Gizmo engine (tm.gizmonative)
Internal. This is the engine behind tm.gizmo: move, rotate and resize handles drawn with DrawLine / DrawPoly and picked with a ray from the mouse cursor. Call tm.gizmo, not this module. It owns no thread and registers no key: tm.gizmo calls frame() once per game frame while a session runs.
| Call | Description |
|---|---|
start(target, options, hooks) | Starts a session on an entity or a virtual target. hooks provides mode(), relative(), grid() (returns on, step) and suspended(). |
frame() | One frame: read the camera and cursor, pick, drag, draw. The caller has already put the game in cursor mode. |
stop(cancelled) | Ends the session. A cancel restores the starting transform (virtual table or entity matrix). |
release() | Ends a drag in progress (the owner switched mode). |
isDragging() | A handle is being dragged. |
canScale() | The target has a size. |
snapToGround() | Rests a virtual target on the ground below it. |
getTransform() | position, rotation (pitch, roll, yaw), size?. |
Math
- Rotation is pitch / roll / yaw in degrees in the order
GetEntityRotation(entity, 2)uses (yaw, then pitch, then roll). Forward is(-sin yaw, cos yaw, 0)when level, so a positive yaw turns counter clockwise. - The cursor ray is built from the rendered camera position, rotation and field of view. Handles are sized by
distance * tan(fov / 2)so they keep a constant size on screen. - Axis drags use the point on the axis closest to the ray, plane drags intersect the ray with the plane, rotation accumulates the angle swept around the ring (so it can pass 180 degrees) and rotates the grabbed basis about the ring axis from the grab (no drift). The basis is rebuilt orthonormal after every rotation.
- Scale cubes grow the dragged face and keep the opposite face fixed (
Shiftgrows both sides, a sphere always scales evenly, a plane has no forward scale). Sizes are clamped tominSize/maxSizeand snapped tosnap(fineSnapwithCtrl). - Handles are drawn on an overlay plane pulled toward the camera so world geometry never hides them, and the camera's travel since the last frame is carried forward so they do not jitter while the camera moves.
Errors raised by onChange and constrain are logged, never thrown into the frame.