Documentation is work in progress and not completeEditor
3D System

ThreeDEngine

The engine is the central coordinator. It creates all Three.js infrastructure and delegates domain-specific work to SceneManager and GizmoController.

Renderer Creation

this.renderer = new THREE.WebGLRenderer({
  antialias: true,
  alpha: true,
  preserveDrawingBuffer: true,
});
OptionValueReason
antialiastrueSmooth edges on geometry
alphatrueTransparent background so the canvas artboard shows through
preserveDrawingBuffertrueRequired for toDataURL() and screenshot capture

Renderer Configuration

SettingValuePurpose
setPixelRatioMath.min(window.devicePixelRatio, 2)Caps at 2x. Higher ratios quadruple pixel count with diminishing visual return.
shadowMap.enabledtrueEnables shadow casting
shadowMap.typeTHREE.PCFSoftShadowMapPercentage-Closer Filtering with bilinear filtering, producing smooth penumbras
toneMappingTHREE.ACESFilmicToneMappingACES filmic curve maps HDR to LDR with natural highlight rolloff
toneMappingExposure1.0Neutral exposure
setClearColor0x000000, 0Fully transparent clear so the background shows through

Camera and Orbit Controls

ParameterValuePurpose
FOV50Moderate field of view. Avoids fisheye distortion while keeping natural perspective.
Near plane0.1Close enough that small objects aren't clipped
Far plane1000Far enough for large imported models
Position(4, 3, 4)A diagonal giving an isometric-like initial view

OrbitControls are created with damping enabled and a damping factor of 0.1, targeting the origin. Damping creates smooth deceleration when the user releases the mouse; the change event marks the scene dirty.

Lighting

Three lights are added to every scene:

LightTypeIntensityPositionShadow
AmbientAmbientLight0.4N/ANo
DirectionalDirectionalLight1.0(5, 10, 5)Yes (2048x2048 shadow map)
PointPointLight0.3(-3, 5, -3)No

All three are white. The directional light is the primary source; its shadow camera uses orthographic bounds of -10 to 10 on all axes, with a near plane of 0.1 and a far plane of 50.

Grid Helper

A 20-unit grid with 40 divisions is created at 0.4 opacity but is hidden by default and never added to the scene. It exists as a reference that can be retrieved via getGridHelper() and toggled externally if needed.

Key Public Methods

MethodDescription
markDirty()Forces a re-render on the next frame
onSelect(cb)Registers a callback for object selection events
onTransformEnd(cb)Registers a callback for when a gizmo drag ends
selectObject(id)Selects an object by ID and attaches the gizmo, or deselects if null
addPrimitive(type, material?, geometry?)Creates a new primitive mesh and adds it to the scene
importModelFromFile(file)Loads a 3D model file, normalizes it and adds it to the scene
removeObject(id)Removes an object and disposes its resources
setGizmoMode(mode)Switches the gizmo between translate, rotate and scale
updateTransform(id, pos?, rot?, scale?)Updates an object's position, rotation or scale
updateMaterial(id, config)Replaces an object's material
updateGeometry(id, config)Replaces an object's geometry (primitives only)
updateEnvironment(config)Updates lighting and background color
getSelectedObject()Returns the config of the selected object
getAllObjects()Returns configs for all objects in the scene
getCameraPosition() / getCameraTarget()Returns the current camera position or orbit target
setCameraPosition(pos, target)Sets camera position and orbit target
resize(width, height)Resizes the renderer and updates camera aspect
setOrbitEnabled(enabled)Enables or disables orbit controls
pauseLoop() / resumeLoop()Stops or restarts the render loop
dispose()Full teardown

Dispose Sequence

dispose(): void {
  this.disposed = true;
  cancelAnimationFrame(this.animFrameId);
  this.renderer.domElement.removeEventListener('pointerdown', this.handlePointerDown);
  this.gizmo.dispose();
  this.sceneManager.dispose();
  this.orbit.dispose();
  this.renderer.dispose();
  if (this.renderer.domElement.parentElement) {
    this.renderer.domElement.parentElement.removeChild(this.renderer.domElement);
  }
}
The order matters. The gizmo is detached before the scene manager disposes all meshes, then orbit and renderer are disposed, and the canvas DOM element is removed last.