Skip to content

Commit 8f91699

Browse files
committed
Update default projection matrices
1 parent 336a139 commit 8f91699

File tree

4 files changed

+23
-21
lines changed

4 files changed

+23
-21
lines changed

src/scenex/model/_nodes/camera.py

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
11
from __future__ import annotations
22

3-
from typing import Literal
3+
from typing import TYPE_CHECKING, Literal
44

55
from pydantic import Field
66

7-
from scenex.model._transform import Transform
7+
from scenex.utils import projections
88

99
from .node import Node
1010

11+
if TYPE_CHECKING:
12+
from scenex.model._transform import Transform
13+
1114
CameraType = Literal["panzoom", "perspective"]
1215
Position2D = tuple[float, float]
1316
Position3D = tuple[float, float, float]
@@ -35,8 +38,8 @@ class Camera(Node):
3538
description="Whether the camera responds to user interaction, "
3639
"such as mouse and keyboard events.",
3740
)
38-
# FIXME: Default should be explained. And z-scale should probably be -1
3941
projection: Transform = Field(
40-
default_factory=Transform,
41-
description="Describes how 3D points are mapped to a 2D canvas",
42+
default_factory=lambda: projections.orthographic(1, 1, 1),
43+
description="Describes how 3D points are mapped to a 2D canvas, "
44+
"default is an orthographic projection of a unit cube, centered at (0, 0, 0)",
4245
)

src/scenex/utils/projections.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
from scenex.model._transform import Transform
88

99

10-
def orthographic(width: float = 2, height: float = 2, depth: float = 2) -> Transform:
10+
def orthographic(width: float = 1, height: float = 1, depth: float = 1) -> Transform:
1111
"""Creates an orthographic projection matrix.
1212
1313
Note that the resulting projection matrix provides no positional offset; this would
@@ -20,15 +20,15 @@ def orthographic(width: float = 2, height: float = 2, depth: float = 2) -> Trans
2020
Parameters
2121
----------
2222
width: float, optional
23-
The width of the camera rectangular prism. Default 2 (mirroring the side length
23+
The width of the camera rectangular prism. Default 1 (mirroring the side length
2424
of a unit cube).
2525
height: float, optional
26-
The height of the camera rectangular prism. Default 2 (mirroring the side length
26+
The height of the camera rectangular prism. Default 1 (mirroring the side length
2727
of a unit cube).
2828
depth: float, optional
2929
The depth of the camera rectangular prism. The near and far clipping planes of
3030
the resulting matrix become (-depth / 2) and (depth / 2) respectively. Default
31-
2, increase (to render things farther away) or decrease (to increase
31+
1, increase (to render things farther away) or decrease (to increase
3232
performance) as needed.
3333
3434
TODO: Is this a good default? May want to consider some large number (1000?)

tests/adaptors/_vispy/test_camera.py

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ def test_transform_with_view(view_camera: tuple[snx.Camera, adaptors.Camera]) ->
5555
[
5656
[5, 0, 0, 0],
5757
[0, 5, 0, 0],
58-
[0, 0, 1, 0],
58+
[0, 0, -1, 0],
5959
[5, 5, 0, 1],
6060
]
6161
)
@@ -69,7 +69,7 @@ def test_transform_with_view(view_camera: tuple[snx.Camera, adaptors.Camera]) ->
6969
[
7070
[5, 0, 0, 0],
7171
[0, 5, 0, 0],
72-
[0, 0, 1, 0],
72+
[0, 0, -1, 0],
7373
[0, 0, 0, 1],
7474
]
7575
)
@@ -82,15 +82,14 @@ def test_projection_with_view(view_camera: tuple[snx.Camera, adaptors.Camera]) -
8282
node = adaptor._vispy_node
8383
assert isinstance(node, BaseCamera)
8484
# Centered at [0, 0], top left [-1, -1], bottom right [1, 1]
85-
identity_tform = Transform()
86-
assert camera.projection == identity_tform
85+
assert camera.projection == Transform().scaled((1, 1, -1))
8786
# Vispy wants to map [-1, -1] to [0, 0]
8887
# Vispy wants to map [1, 1] to [10, 10]
8988
exp_tform_mat = np.asarray(
9089
[
9190
[5, 0, 0, 0],
9291
[0, 5, 0, 0],
93-
[0, 0, 1, 0],
92+
[0, 0, -1, 0],
9493
[5, 5, 0, 1],
9594
]
9695
)

tests/utils/test_projections.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,20 +19,20 @@ def test_orthographic() -> None:
1919
# By default, the return should unproject NDCs to a depth-inverted unit cube
2020
exp_mat = np.asarray(
2121
[
22-
[1, 0, 0, 0],
23-
[0, 1, 0, 0],
24-
[0, 0, -1, 0],
22+
[2, 0, 0, 0],
23+
[0, 2, 0, 0],
24+
[0, 0, -2, 0],
2525
[0, 0, 0, 1],
2626
]
2727
)
2828
act_mat = orthographic()
2929
assert np.array_equal(exp_mat, act_mat)
3030
exp_corners = np.asarray(
3131
[
32-
[-1, -1, 0],
33-
[-1, 1, 0],
34-
[1, -1, 0],
35-
[1, 1, 0],
32+
[-0.5, -0.5, 0],
33+
[-0.5, 0.5, 0],
34+
[0.5, -0.5, 0],
35+
[0.5, 0.5, 0],
3636
]
3737
)
3838
assert np.array_equal(exp_corners, vec_unproject(CORNERS, act_mat))

0 commit comments

Comments
 (0)