MCPcopy Create free account
hub / github.com/Robbyant/lingbot-map / OrbitCamera

Class OrbitCamera

demo_render/interactive_viewer/camera.py:30–155  ·  view source on GitHub ↗

Interactive orbit camera with WASD FPS-style movement.

Source from the content-addressed store, hash-verified

28
29
30class OrbitCamera:
31 """Interactive orbit camera with WASD FPS-style movement."""
32
33 def __init__(
34 self,
35 eye: np.ndarray,
36 look_at: np.ndarray,
37 up: np.ndarray = None,
38 fov_deg: float = 60.0,
39 ):
40 self.eye = np.asarray(eye, dtype=np.float32).copy()
41 self.look_at = np.asarray(look_at, dtype=np.float32).copy()
42 self.up = np.asarray(
43 up if up is not None else [0, -1, 0], dtype=np.float32
44 ).copy()
45 self.fov_deg = fov_deg
46
47 # ----- Derived vectors -----
48
49 @property
50 def forward(self) -> np.ndarray:
51 return _normalize(self.look_at - self.eye)
52
53 @property
54 def right(self) -> np.ndarray:
55 return _normalize(np.cross(self.up, self.forward))
56
57 @property
58 def camera_up(self) -> np.ndarray:
59 """Actual up vector (orthogonal to forward and right)."""
60 return _normalize(np.cross(self.right, self.forward))
61
62 @property
63 def distance(self) -> float:
64 return float(np.linalg.norm(self.look_at - self.eye))
65
66 # ----- Mouse interactions -----
67
68 def orbit(self, dx: float, dy: float, sensitivity: float = 0.005):
69 """Rotate around look_at point. dx = horizontal, dy = vertical."""
70 offset = self.eye - self.look_at
71
72 # Horizontal rotation (around world up)
73 angle_h = -dx * sensitivity
74 cos_h, sin_h = np.cos(angle_h), np.sin(angle_h)
75 up = _normalize(self.up)
76 # Rodrigues rotation around up axis
77 offset = (
78 offset * cos_h
79 + np.cross(up, offset) * sin_h
80 + up * np.dot(up, offset) * (1 - cos_h)
81 )
82
83 # Vertical rotation (around right axis)
84 angle_v = -dy * sensitivity
85 right = _normalize(np.cross(up, _normalize(offset)))
86 cos_v, sin_v = np.cos(angle_v), np.sin(angle_v)
87 offset = (

Callers 4

load_sceneFunction · 0.90
ws_handlerFunction · 0.90
copyMethod · 0.85
interpolateMethod · 0.85

Calls

no outgoing calls

Tested by

no test coverage detected