Skip to content

Commit f426ee7

Browse files
authored
Build API doc for all Camera types and functions (#2112)
* Refactor camera data type doc so it doesn't break Sphinx * Expose all Camera types in doc * Add modules to update_quick_index.py * Add generated file to doc/api_docs/arcade.rst toctree * Fix syntax + add cross-refs in perspective.py * Fix build error due to syntax issue in alignment * Add cross-refs * General touch-ups for style and phrasing
1 parent 58bde7e commit f426ee7

File tree

4 files changed

+102
-50
lines changed

4 files changed

+102
-50
lines changed

arcade/camera/data_types.py

+45-27
Original file line numberDiff line numberDiff line change
@@ -41,14 +41,6 @@ class CameraData:
4141
"""Stores position, orientation, and zoom for a camera.
4242
4343
This is like where a camera is placed in 3D space.
44-
45-
Attributes:
46-
position: A 3D vector which describes where the camera is located.
47-
up: A 3D vector which describes which direction is up (+y).
48-
forward: a 3D vector which describes which direction is forwards (+z).
49-
zoom: A scaler that records the zoom of the camera. While this most often affects the projection matrix
50-
it allows camera controllers access to the zoom functionality
51-
without interacting with the projection data.
5244
"""
5345

5446
__slots__ = ("position", "up", "forward", "zoom")
@@ -59,9 +51,15 @@ def __init__(self,
5951
forward: Point3 = (0.0, 0.0, -1.0),
6052
zoom: float = 1.0):
6153

62-
# View matrix data
54+
#: A 3D vector which describes where the camera is located.
6355
self.position: Tuple[float, float, float] = position
56+
#: A 3D vector which describes which direction is up (+y).
6457
self.up: Tuple[float, float, float] = up
58+
#: A scalar which describes which direction the camera is pointing.
59+
#:
60+
#: While this affects the projection matrix, it also allows camera
61+
#: controllers to access zoom functionality without interacting with
62+
#: projection data.
6563
self.forward: Tuple[float, float, float] = forward
6664

6765
# Zoom
@@ -104,15 +102,6 @@ class OrthographicProjectionData:
104102
This is by default a Left-handed system. with the X axis going from left to right, The Y axis going from
105103
bottom to top, and the Z axis going from towards the screen to away from the screen. This can be made
106104
right-handed by making the near value greater than the far value.
107-
108-
Attributes:
109-
left: The left most value, which gets mapped to x = -1.0 (anything below this value is not visible).
110-
right: The right most value, which gets mapped to x = 1.0 (anything above this value is not visible).
111-
bottom: The bottom most value, which gets mapped to y = -1.0 (anything below this value is not visible).
112-
top: The top most value, which gets mapped to y = 1.0 (anything above this value is not visible).
113-
near: The 'closest' value, which gets mapped to z = -1.0 (anything below this value is not visible).
114-
far: The 'furthest' value, Which gets mapped to z = 1.0 (anything above this value is not visible).
115-
viewport: The pixel bounds which will be drawn onto. (left, bottom, width, height)
116105
"""
117106

118107
__slots__ = ("rect", "near", "far")
@@ -129,11 +118,23 @@ def __init__(
129118

130119
# Data for generating Orthographic Projection matrix
131120
self.rect: Rect = LRBT(left, right, bottom, top)
121+
#: The 'closest' visible position along the forward direction.
122+
#:
123+
#: It will get mapped to z = -1.0. Anything closer than this value
124+
#: is not visible.
132125
self.near: float = near
126+
#: The 'farthest' visible position along the forward direction.
127+
#:
128+
#: It will get mapped to z = 1.0. Anything father than this value
129+
#: is not visible.
133130
self.far: float = far
134131

135132
@property
136133
def left(self) -> float:
134+
""""The left-side cutoff value, which gets mapped to x = -1.0.
135+
136+
Anything to the left of this value is not visible.
137+
"""
137138
return self.rect.left
138139

139140
@left.setter
@@ -153,6 +154,10 @@ def left(self, new_left: AsFloat):
153154

154155
@property
155156
def right(self) -> float:
157+
""""The right-side cutoff value, which gets mapped to x = 1.0.
158+
159+
Anything to the left of this value is not visible.
160+
"""
156161
return self.rect.right
157162

158163
@right.setter
@@ -172,6 +177,10 @@ def right(self, new_right: AsFloat):
172177

173178
@property
174179
def bottom(self) -> float:
180+
""""The bottom-side cutoff value, which gets mapped to -y = 1.0.
181+
182+
Anything to the left of this value is not visible.
183+
"""
175184
return self.rect.bottom
176185

177186
@bottom.setter
@@ -191,6 +200,10 @@ def bottom(self, new_bottom: AsFloat):
191200

192201
@property
193202
def top(self) -> float:
203+
""""The top-side cutoff value, which gets mapped to y = 1.0.
204+
205+
Anything to the left of this value is not visible.
206+
"""
194207
return self.rect.top
195208

196209
@top.setter
@@ -239,14 +252,7 @@ def orthographic_from_rect(rect: Rect, near: float, far: float) -> OrthographicP
239252

240253
class PerspectiveProjectionData:
241254
"""Describes a perspective projection.
242-
243-
Attributes:
244-
aspect: The aspect ratio of the screen (width over height).
245-
fov: The field of view in degrees. With the aspect ratio defines
246-
the size of the projection at any given depth.
247-
near: The 'closest' value, which gets mapped to z = -1.0 (anything below this value is not visible).
248-
far: The 'furthest' value, Which gets mapped to z = 1.0 (anything above this value is not visible).
249-
viewport: The pixel bounds which will be drawn onto. (left, bottom, width, height)
255+
)
250256
"""
251257
__slots__ = ("aspect", "fov", "near", "far")
252258

@@ -255,10 +261,22 @@ def __init__(self,
255261
fov: float,
256262
near: float,
257263
far: float):
258-
# Data for generating Perspective Projection matrix
264+
#: The aspect ratio of the screen (width over height).
259265
self.aspect: float = aspect
266+
#: The field of view in degrees.
267+
#:
268+
#: Together with the aspect ratio, it defines the size of the
269+
#: perspective projection for any given depth.
260270
self.fov: float = fov
271+
#: The 'closest' visible position along the forward direction.
272+
#:
273+
#: It will get mapped to z = -1.0. Anything closer than this value
274+
#: is not visible.
261275
self.near: float = near
276+
#: The 'farthest' visible position along the forward direction.
277+
#:
278+
#: It will get mapped to z = 1.0. Anything father than this value
279+
#: is not visible.
262280
self.far: float = far
263281

264282
def __str__(self):

arcade/camera/perspective.py

+45-23
Original file line numberDiff line numberDiff line change
@@ -73,27 +73,34 @@ def __init__(self, *,
7373

7474
@property
7575
def view(self) -> CameraData:
76-
"""
76+
"""Get the internal :py:class:`~arcade.camera.data_types.CameraData`.
77+
78+
This is a read-only property.
7779
The CameraData. Is a read only property.
7880
"""
7981
return self._view
8082

8183
@property
8284
def projection(self) -> PerspectiveProjectionData:
83-
"""
84-
The OrthographicProjectionData. Is a read only property.
85+
"""Get the :py:class:`~arcade.camera.data_types.PerspectiveProjectionData`.
86+
87+
This is a read-only property.
8588
"""
8689
return self._projection
8790

8891
def generate_projection_matrix(self) -> Mat4:
89-
"""
90-
alias of arcade.camera.get_perspective_matrix method
92+
"""Generates a projection matrix.
93+
94+
This is an alias of
95+
:py:class:`arcade.camera.get_perspective_matrix`.
9196
"""
9297
return generate_perspective_matrix(self._projection, self._view.zoom)
9398

9499
def generate_view_matrix(self) -> Mat4:
95-
"""
96-
alias of arcade.camera.get_view_matrix method
100+
"""Generates a view matrix.
101+
102+
This is an alias of=
103+
:py:class:`arcade.camera.get_view_matrix`.
97104
"""
98105
return generate_view_matrix(self._view)
99106

@@ -123,10 +130,15 @@ def activate(self) -> Generator[Self, None, None]:
123130
previous_projector.use()
124131

125132
def use(self) -> None:
126-
"""
127-
Sets the active camera to this object.
128-
Then generates the view and projection matrices.
129-
Finally, the gl context viewport is set, as well as the projection and view matrices.
133+
"""Set the active camera to this object and apply other config.
134+
135+
This includes the following steps:
136+
137+
#. Set the window's current camera to this one
138+
#. Generate appropriate view and projection matrices
139+
#. Set the GL context's viewport and scissorbox values
140+
#. Apply the relevant matrices to Arcade's
141+
:py:class:`~arcade.Window` object
130142
"""
131143

132144
self._window.current_camera = self
@@ -140,8 +152,19 @@ def use(self) -> None:
140152
self._window.view = _view
141153

142154
def project(self, world_coordinate: Point) -> Vec2:
143-
"""
144-
Take a Vec2 or Vec3 of coordinates and return the related screen coordinate
155+
"""Convert world coordinates to pixel screen coordinates.
156+
157+
If a 2D :py:class:`Vec2` is provided instead of a 3D
158+
:py:class:`Vec3`, then one will be calculated to the best of the
159+
method's ability.
160+
161+
Args:
162+
world_coordinate:
163+
A :py:class:`Vec2` or :py:class:`Vec3` as world
164+
coordinates.
165+
166+
Returns:
167+
A 2D screen pixel coordinate.
145168
"""
146169
x, y, *z = world_coordinate
147170
z = (0.5 * self.viewport.height / tan(
@@ -158,20 +181,19 @@ def project(self, world_coordinate: Point) -> Vec2:
158181

159182
return pos
160183

184+
# TODO: update args
161185
def unproject(self, screen_coordinate: Point) -> Vec3:
162-
"""
163-
Take in a pixel coordinate from within
164-
the range of the window size and returns
165-
the world space coordinates.
186+
"""Convert a pixel coordinate into world space.
166187
167-
Essentially reverses the effects of the projector.
188+
This reverses the effects of :py:meth:`.project`.
168189
169-
# TODO: UPDATE
170190
Args:
171-
screen_coordinate: A 2D position in pixels from the bottom left of the screen.
172-
This should ALWAYS be in the range of 0.0 - screen size.
173-
Returns:
174-
A 3D vector in world space.
191+
screen_coordinate:
192+
A 2D position in pixels from the bottom left of the screen.
193+
This should ALWAYS be in the range of 0.0 - screen size.
194+
195+
Returns: A 3D vector in world space.
196+
175197
"""
176198
x, y, *z = screen_coordinate
177199
z = (0.5 * self.viewport.height / tan(

doc/api_docs/arcade.rst

+1
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ for the Python Arcade library. See also:
3333
api/joysticks
3434
api/window
3535
api/sound
36+
api/advanced_cameras
3637
api/path_finding
3738
api/isometric
3839
api/earclip

util/update_quick_index.py

+11
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,17 @@
258258
"arcade.gui.experimental.password_input",
259259
"arcade.gui.experimental.scroll_area"
260260
]
261+
},
262+
"advanced_cameras.rst": {
263+
"title": "Advanced Camera Features",
264+
"use_declarations_in": [
265+
"arcade.camera.data_types",
266+
"arcade.camera.projection_functions",
267+
"arcade.camera.orthographic",
268+
"arcade.camera.perspective",
269+
"arcade.camera.default",
270+
"arcade.camera.static"
271+
]
261272
}
262273
}
263274

0 commit comments

Comments
 (0)