Appearance
Hits_3D
3D hit testing for Smart Objects — corners, edges, faces.
Location
src/lib/ts/managers/Hits_3D.ts
Purpose
Screen-space hit testing for 3D canvas objects. Separate from DOM-based Hits.ts which handles svelte components.
Design Decision
Separate from DOM Hits — Option C from our analysis. Mouse can only be in canvas OR in DOM, never both. No coordination needed — just routing. Events_3D handles canvas, existing Events handles document.
Hit Types (T_Hit_3D)
Order encodes precedence (lower = higher priority):
corner— vertex hit (8px radius)edge— line segment hit (5px radius)face— polygon hit (front-facing only)none
Structure
typescript
class Hits_3D {
// Registration
register(so: Smart_Object)
unregister(so: Smart_Object)
// Projection cache (updated by Render each frame)
update_projected(scene_id: string, projected: Projected[])
get_projected(scene_id: string): Projected[] | undefined
// Hit testing
test(point: Point): Hit_3D_Result | null
// Hover state
w_hover: Writable<Hit_3D_Result | null>
hover: Hit_3D_Result | null
set_hover(result: Hit_3D_Result | null)
// Selection state
w_selection: Writable<Hit_3D_Result | null>
selection: Hit_3D_Result | null
set_selection(result: Hit_3D_Result | null)
}Hit_3D_Result
typescript
interface Hit_3D_Result {
so: Smart_Object;
type: T_Hit_3D;
index: number; // which corner/edge/face
}Face Detection
Faces use CCW winding when viewed from outside. Hit test:
is_front_facing()— 2D cross product < 0 means front-facing in screen coordspoint_in_polygon()— ray casting algorithm
Selection Behavior
- Click sets selection to current hit (only if something was hit)
- Selection persists until another element is clicked
- Rendered as blue dots; hover rendered as red dots on top
Face Flip on Rotation
When a face is selected and the object rotates, the selected face may flip away from the camera. update_projected() detects this and auto-switches to the opposite face:
- Check if selected face is still front-facing
- If not, try opposite face (index XOR 1: 0↔1, 2↔3, 4↔5)
- If opposite is front-facing, switch selection to it
This assumes faces are paired (front/back, left/right, top/bottom).
Data Flow
Setup.tscreates SOs, registers withhits_3dRender.tsprojects vertices, callshits_3d.update_projected()Events_3D.tson mousemove callshits_3d.test(),hits_3d.set_hover()Events_3D.tson mousedown callshits_3d.set_selection()if hitRender.tsreadshits_3d.selectionandhits_3d.hover, draws highlights
Related
runtime/Smart_Object.ts— entities being testedsignals/Events_3D.ts— mouse event handlingrender/Render.ts— projection + highlight renderingtypes/Enumerations.ts—T_Hit_3Denum