Skip to content

Sroberge/1 0#87

Open
vim-sroberge wants to merge 179 commits intomainfrom
sroberge/1_0
Open

Sroberge/1 0#87
vim-sroberge wants to merge 179 commits intomainfrom
sroberge/1_0

Conversation

@vim-sroberge
Copy link
Collaborator

@vim-sroberge vim-sroberge commented Feb 24, 2026

This branch is a major architectural overhaul preparing vim-web for the 1.0 release. It covers five broad areas: a new public API surface, a complete outline rendering rewrite, a GPU picking system, geometry loading performance, and a thorough dead code purge.


Public API & Exports

  • ViewerApi abstraction: Both WebGL and Ultra viewers now expose a unified ViewerApi handle (WebglViewerApi / UltraViewerApi) through VIM.React.Webgl.createViewer() and VIM.React.Ultra.createViewer(). Direct class access is no longer needed for any common use case.
  • Interface-driven: Core types are now backed by I-prefixed interfaces (IVim, ICamera, ISelectable, IMarker, IMaterials, etc.). Concrete classes are @internal.
  • Tighter barrel files: Internal modules are no longer leaked through re-exports. The public surface is intentionally narrow.
  • Unique class names: Renamed internal classes for cleaner API bundles and better TypeScript declaration output.
  • viewer.core.settings removed: Settings are consumed at construction time only — exposing them as a field was misleading. Removed from IWebglViewer.
  • Material API cleanup: IMaterials now only exposes user-facing properties (ghostOpacity, ghostColor, outlineOpacity, outlineThickness, outlineColor, clippingPlanes). Internal system materials are hidden behind a system getter.
  • Element3D interface: IElement3D exposes only BIM-facing properties; mesh internals are hidden.
  • Input API: Inputs organized under viewer.core.inputs with typed PointerMode enum, configurable key handlers, and clean mouse/touch callbacks. Removed spacebar bindings.
  • Camera API: Fluent snap() / lerp(duration) API for instant vs animated camera moves. Unified frame(), orbit(), orbitTowards(), zoomTo(). Removed lookAt parameter. Rotation axes clarified (x = horizontal/yaw, y = vertical/pitch).
  • Framing renamed: viewer.react.cameraviewer.framing for clarity.
  • Signal interfaces: onXxx event properties typed as read-only signal interfaces, not mutable dispatchers.
  • Ultra API tightened: Ultra viewer API aligned with WebGL — matching fields (container, isolation, sectionBox, etc.), control bar customization via hook param, no leaked RPC internals.

GPU Picking (WebGL)

Replaced CPU raycasting as the primary picking method with a GPU-based approach:

  • Float32 render target stores packed element ID (vimIndex << 24 | elementIndex), depth, and surface normals per fragment.
  • packPickingId() / unpackPickingId() utilities pre-pack IDs at mesh build time — zero overhead per frame.
  • Markers support GPU picking (packedId attribute with MARKER_VIM_INDEX sentinel).
  • GpuPicker reads a 1×1 region on click, resolves vim + element in one readback.
  • CPU raycaster (raycaster.ts) retained as fallback.

Outline Rendering Rewrite

The outline effect was completely rewritten from depth-based to mask-based silhouette detection:

Pipeline: Scene (MSAA) → Selection Mask → Outline Edge Detect → Merge → Screen

  • Mask-based: Selected objects render with a flat white maskMaterial to a dedicated render target. Edge detection runs on the mask, not the depth buffer — eliminates depth precision artifacts at long range.
  • scene.background fix: Background color was leaking into the mask buffer and breaking edge detection. Background is now nulled during the outline composer render and restored after.
  • Configurable thickness: New thickness uniform (range 1–5) controls how many Chebyshev ring levels are sampled per fragment. Higher values = thicker outlines at a proportional sampling cost.
  • Full grid (Chebyshev ring) sampling: Replaced 8-point star sampling with a full NxN grid ring. Eliminates diagonal artifacts from the star pattern.
  • Opacity and color: outlineOpacity (0–1) and outlineColor exposed on IMaterials. Both live on the merge pass for clean separation.
  • Dead properties removed: camera, depthBuffer, color, precision and associated uniforms removed from OutlineMaterial. OutlinePass no longer receives or wires a camera.

Material System Cleanup

  • StandardMaterial removed: _opaque / _transparent StandardMaterial fields deleted from Materials. VIM meshes have always used ModelMaterial (custom GLSL3 shader) — StandardMaterial was never in the rendering path.
  • Dead settings removed:
    • skybox, skylight, sunlights — defined, parsed, never consumed
    • useFastMaterials, materials.standard.color — toggle with no effect
    • materials.section.strokeWidth/Falloff/Color — only applied to StandardMaterial shader, which was unused
  • modelColor, sectionStroke* removed from IMaterials — dead wiring to removed materials.
  • MaterialSettings now contains only ghost and outline.
  • MaterialSet: New value type { opaque, transparent, hidden } for per-mesh material assignment. applyMaterial() helper is the single place that calls MaterialSet.get().

Geometry Loading & Performance

  • Color palette texture: Per-element colors stored in a shared 128×128 DataTexture (25³ = 15,625 quantized colors). ModelMaterial reads colors via texelFetch — no per-vertex color upload on color changes.
  • texelFetch / WebGL2: Replaced texture2D with texelFetch in shaders for direct texel access.
  • G3dSubset and offsets: Introduced G3dSubset as a filtered view of G3d instances. G3dMeshOffsets pre-computes vertex/index counts per mesh for buffer allocation.
  • InsertableGeometry chunking: Merged mesh geometry split at 16M indices to stay within buffer limits.
  • InstancedMeshFactory: Instanced meshes (>5 instances) built with per-instance packedId and ignore attributes pre-packed at build time.
  • Faster element mapping, bounding boxes, and array lookups: Hot paths replaced with typed array maps.
  • Removed vimx: Legacy vimx loading code removed.
  • No empty meshes: Meshes with zero instances are no longer created.

Camera & Controls

  • Orbit target on select: Orbit target snaps to selected element center.
  • Zoom resets orbit target: Scroll-to-zoom updates the orbit target to the cursor hit point.
  • Floating target fix: Orbit target no longer drifts after camera reset.
  • Touch: Pinch and pan gestures both fire correctly. Faster scroll.
  • lockMovement / lockRotation: Per-axis movement and rotation locks on ViewerSettings.camera.
  • Delta time: Fixed camera animation delta time calculation.

Ultra Viewer Updates

  • Color overrides: Ultra viewer supports element.color = new RGBA32(...) overrides, aligned with WebGL API.
  • nodeStatestate: Renamed for clarity. element.state = VisibilityState.GHOSTED (enum: VISIBLE, HIDDEN, GHOSTED, HIGHLIGHTED).
  • Remove overrides: Ultra viewer supports removing overrides, matching WebGL.
  • Error messages: Improved error/status display. Errors not minimized by default.
  • Ultra 6.0.0 RPC: Updated RPC client to match Ultra 6 protocol.

Gizmos

  • Marker GPU picking: Markers register packedId attribute for GPU picker hit detection.
  • Orbit gizmo: Camera gizmo rebuilt to match Ultra's visual style. Uses sphere coordinates.
  • Section box / axes cleanup: Gizmo classes tightened, internals hidden behind IGizmo* interfaces.

Developer Experience

  • CLAUDE.md: Comprehensive architecture documentation. Covers loading pipeline, rendering pipeline, GPU picker, mesh type hierarchy, React patterns, and camera API.
  • INPUT.md: Dedicated input system documentation.
  • @internal tags: System-only classes and methods marked throughout.
  • TypeDoc comments: Cleaned up and expanded across public API.

Breaking Changes

  • viewer.core.settings removed from IWebglViewer
  • StandardMaterial, modelColor, sectionStroke* removed from IMaterials
  • MaterialSettings.useFastMaterials, .standard, .section removed
  • skybox, skylight, sunlights removed from ViewerSettings
  • viewer.react.camera renamed to viewer.framing
  • nodeState renamed to state (Ultra); use VisibilityState enum
  • Input key binding API changed — register via inputs.keyboard.registerKeyDown()
  • Camera lookAt parameter removed — use orbitTowards() or set(position, target)

vim-sroberge and others added 12 commits February 24, 2026 15:08
Added outline opacity
StandardMaterial (_opaque/_transparent) was never used for rendering —
all VIM meshes use ModelMaterial. Removed the fields, modelColor,
sectionStroke*, useFastMaterials, standard, and section settings
that were wired exclusively to them.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant