simple-circuit-engine 0.0.10 → 0.0.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +13 -7
- package/CLAUDE.md +16 -103
- package/README.md +8 -5
- package/dist/core/index.d.ts +2 -23
- package/dist/core/index.js +75 -2000
- package/dist/core/setup.d.ts +17 -0
- package/dist/core/simulation/CircuitRunner.d.ts +176 -0
- package/dist/core/simulation/DirtyTracker.d.ts +87 -0
- package/dist/core/simulation/EventQueue.d.ts +68 -0
- package/dist/core/simulation/StateManager.d.ts +100 -0
- package/dist/core/simulation/behaviors/BehaviorRegistry.d.ts +70 -0
- package/dist/core/simulation/behaviors/ComponentBehavior.d.ts +53 -0
- package/dist/core/simulation/behaviors/basic/BatteryBehavior.d.ts +14 -0
- package/dist/core/simulation/behaviors/basic/ClockBehavior.d.ts +24 -0
- package/dist/core/simulation/behaviors/basic/DoubleThrowSwitchBehavior.d.ts +33 -0
- package/dist/core/simulation/behaviors/basic/LightbulbBehavior.d.ts +23 -0
- package/dist/core/simulation/behaviors/basic/RectangleLEDBehavior.d.ts +24 -0
- package/dist/core/simulation/behaviors/basic/RelayBehavior.d.ts +33 -0
- package/dist/core/simulation/behaviors/basic/SmallLEDBehavior.d.ts +24 -0
- package/dist/core/simulation/behaviors/basic/SwitchBehavior.d.ts +33 -0
- package/dist/core/simulation/behaviors/basic/index.d.ts +20 -0
- package/dist/core/simulation/behaviors/gates/InverterBehavior.d.ts +29 -0
- package/dist/core/simulation/behaviors/gates/Nand4GateBehavior.d.ts +18 -0
- package/dist/core/simulation/behaviors/gates/Nand8GateBehavior.d.ts +18 -0
- package/dist/core/simulation/behaviors/gates/NandGateBehavior.d.ts +28 -0
- package/dist/core/simulation/behaviors/gates/Nor4GateBehavior.d.ts +18 -0
- package/dist/core/simulation/behaviors/gates/Nor8GateBehavior.d.ts +18 -0
- package/dist/core/simulation/behaviors/gates/NorGateBehavior.d.ts +22 -0
- package/dist/core/simulation/behaviors/gates/Xor4GateBehavior.d.ts +18 -0
- package/dist/core/simulation/behaviors/gates/Xor8GateBehavior.d.ts +18 -0
- package/dist/core/simulation/behaviors/gates/XorGateBehavior.d.ts +22 -0
- package/dist/core/simulation/behaviors/gates/index.d.ts +34 -0
- package/dist/core/simulation/behaviors/index.d.ts +24 -0
- package/dist/core/simulation/behaviors/types.d.ts +101 -0
- package/dist/core/simulation/index.d.ts +18 -0
- package/dist/core/simulation/states/ComponentState.d.ts +57 -0
- package/dist/core/simulation/states/SimulationState.d.ts +46 -0
- package/dist/core/simulation/states/basic/BatteryState.d.ts +16 -0
- package/dist/core/simulation/states/basic/ClockState.d.ts +16 -0
- package/dist/core/simulation/states/basic/DoubleThrowSwitchState.d.ts +21 -0
- package/dist/core/simulation/states/basic/LightbulbState.d.ts +21 -0
- package/dist/core/simulation/states/basic/RectangleLEDState.d.ts +9 -0
- package/dist/core/simulation/states/basic/RelayState.d.ts +25 -0
- package/dist/core/simulation/states/basic/SmallLEDState.d.ts +21 -0
- package/dist/core/simulation/states/basic/SwitchState.d.ts +25 -0
- package/dist/core/simulation/states/gates/InverterState.d.ts +17 -0
- package/dist/core/simulation/states/gates/Nand4GateState.d.ts +10 -0
- package/dist/core/simulation/states/gates/Nand8GateState.d.ts +10 -0
- package/dist/core/simulation/states/gates/NandGateState.d.ts +16 -0
- package/dist/core/simulation/states/gates/Nor4GateState.d.ts +10 -0
- package/dist/core/simulation/states/gates/Nor8GateState.d.ts +10 -0
- package/dist/core/simulation/states/gates/NorGateState.d.ts +10 -0
- package/dist/core/simulation/states/gates/Xor4GateState.d.ts +10 -0
- package/dist/core/simulation/states/gates/Xor8GateState.d.ts +10 -0
- package/dist/core/simulation/states/gates/XorGateState.d.ts +10 -0
- package/dist/core/simulation/states/gates/index.d.ts +25 -0
- package/dist/core/simulation/states/index.d.ts +26 -0
- package/dist/core/simulation/states/types.d.ts +32 -0
- package/dist/core/simulation/types.d.ts +155 -0
- package/dist/core/topology/Circuit.d.ts +420 -0
- package/dist/core/topology/CircuitMetadata.d.ts +24 -0
- package/dist/core/topology/CircuitOptions.d.ts +14 -0
- package/dist/core/topology/Component.d.ts +152 -0
- package/dist/core/topology/ENode.d.ts +200 -0
- package/dist/core/topology/Wire.d.ts +130 -0
- package/dist/core/topology/delays.d.ts +52 -0
- package/dist/core/topology/index.d.ts +14 -0
- package/dist/core/topology/types.d.ts +175 -0
- package/dist/core/utils/CameraOptions.d.ts +83 -0
- package/dist/core/utils/MemoizeDecorator.d.ts +9 -0
- package/dist/core/utils/Position.d.ts +166 -0
- package/dist/core/utils/Position3D.d.ts +77 -0
- package/dist/core/utils/Rotation.d.ts +82 -0
- package/dist/core/utils/index.d.ts +24 -0
- package/dist/core/utils/types.d.ts +35 -0
- package/dist/core-Bjta9Y7_.js +2707 -0
- package/dist/core-Bjta9Y7_.js.map +1 -0
- package/dist/index.d.ts +13 -6286
- package/dist/index.js +120 -100
- package/dist/scene/CircuitEngine.d.ts +270 -0
- package/dist/scene/index.d.ts +1 -2
- package/dist/scene/index.js +44 -38
- package/dist/scene/setup.d.ts +18 -0
- package/dist/scene/shared/AbstractCircuitController.d.ts +211 -0
- package/dist/scene/shared/BranchingPointVisualFactory.d.ts +70 -0
- package/dist/scene/shared/EventEmitter.d.ts +92 -0
- package/dist/scene/shared/HoverManager.d.ts +151 -0
- package/dist/scene/shared/SelectionManager.d.ts +159 -0
- package/dist/scene/shared/WireVisualManager.d.ts +242 -0
- package/dist/scene/shared/components/ComponentVisualFactory.d.ts +438 -0
- package/dist/scene/shared/components/DefaultVisualFactory.d.ts +51 -0
- package/dist/scene/shared/components/FactoryRegistry.d.ts +84 -0
- package/dist/scene/shared/components/GroupedFactoryRegistry.d.ts +153 -0
- package/dist/scene/shared/components/basic/BatteryVisualFactory.d.ts +13 -0
- package/dist/scene/shared/components/basic/ClockVisualFactory.d.ts +79 -0
- package/dist/scene/shared/components/basic/DoubleThrowSwitchVisualFactory.d.ts +87 -0
- package/dist/scene/shared/components/basic/LabelVisualFactory.d.ts +148 -0
- package/dist/scene/shared/components/basic/LightbulbVisualFactory.d.ts +72 -0
- package/dist/scene/shared/components/basic/RectangleLEDVisualFactory.d.ts +86 -0
- package/dist/scene/shared/components/basic/RelayVisualFactory.d.ts +92 -0
- package/dist/scene/shared/components/basic/SmallLEDVisualFactory.d.ts +86 -0
- package/dist/scene/shared/components/basic/SwitchVisualFactory.d.ts +85 -0
- package/dist/scene/shared/components/gates/InverterVisualFactory.d.ts +104 -0
- package/dist/scene/shared/components/gates/Nand4GateVisualFactory.d.ts +27 -0
- package/dist/scene/shared/components/gates/Nand8GateVisualFactory.d.ts +27 -0
- package/dist/scene/shared/components/gates/NandGateVisualFactory.d.ts +101 -0
- package/dist/scene/shared/components/gates/Nor4GateVisualFactory.d.ts +27 -0
- package/dist/scene/shared/components/gates/Nor8GateVisualFactory.d.ts +27 -0
- package/dist/scene/shared/components/gates/NorGateVisualFactory.d.ts +101 -0
- package/dist/scene/shared/components/gates/Xor4GateVisualFactory.d.ts +29 -0
- package/dist/scene/shared/components/gates/Xor8GateVisualFactory.d.ts +29 -0
- package/dist/scene/shared/components/gates/XorGateVisualFactory.d.ts +103 -0
- package/dist/scene/shared/components/index.d.ts +29 -0
- package/dist/scene/shared/components/types.d.ts +43 -0
- package/dist/scene/shared/types.d.ts +476 -0
- package/dist/scene/shared/utils/CameraUtils.d.ts +23 -0
- package/dist/scene/shared/utils/ColorUtils.d.ts +26 -0
- package/dist/scene/shared/utils/ControlsUtils.d.ts +8 -0
- package/dist/scene/shared/utils/GeometryUtils.d.ts +261 -0
- package/dist/scene/shared/utils/LayerConstants.d.ts +40 -0
- package/dist/scene/shared/utils/LightingUtils.d.ts +31 -0
- package/dist/scene/shared/utils/MaterialUtils.d.ts +73 -0
- package/dist/scene/shared/utils/Options.d.ts +16 -0
- package/dist/scene/simulation/CircuitRunnerController.d.ts +227 -0
- package/dist/scene/static/CircuitController.d.ts +227 -0
- package/dist/scene/static/CircuitWriter.d.ts +146 -0
- package/dist/scene/static/PinTooltipWidget.d.ts +26 -0
- package/dist/scene/static/tools/BuildTool.d.ts +286 -0
- package/dist/scene/static/tools/ComponentPickerWidget.d.ts +82 -0
- package/dist/scene/static/tools/ConfigPanelWidget.d.ts +93 -0
- package/dist/scene/static/tools/MultiSelectTool.d.ts +265 -0
- package/dist/scene-CVsDdySt.js +7357 -0
- package/dist/scene-CVsDdySt.js.map +1 -0
- package/package.json +24 -25
- package/dist/CircuitRunner-DEb7JdNf.js +0 -1809
- package/dist/CircuitRunner-DEb7JdNf.js.map +0 -1
- package/dist/core/index.js.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/scene/index.js.map +0 -1
- package/dist/setup-AB1vFiis.js +0 -9918
- package/dist/setup-AB1vFiis.js.map +0 -1
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
import { Position, Rotation } from '../../../core/index.ts';
|
|
2
|
+
import { ExtrudeGeometry } from 'three';
|
|
3
|
+
/**
|
|
4
|
+
* Geometry Utilities
|
|
5
|
+
* @module scene/shared/utils/GeometryUtils
|
|
6
|
+
*
|
|
7
|
+
* Helper functions for creating Three.js geometries for grid and circuit elements
|
|
8
|
+
*/
|
|
9
|
+
import * as THREE from 'three';
|
|
10
|
+
/**
|
|
11
|
+
* convenience to control standard rotations of meshes on X-Z plan
|
|
12
|
+
*/
|
|
13
|
+
export type Direction2D = 'right' | 'bottom' | 'left' | 'top';
|
|
14
|
+
/**
|
|
15
|
+
* Create a grid helper for the scene
|
|
16
|
+
*
|
|
17
|
+
* @param size - Size of the grid
|
|
18
|
+
* @param divisions - Number of grid divisions
|
|
19
|
+
* @param colorCenterLine - Color for center lines
|
|
20
|
+
* @param colorGrid - Color for grid lines
|
|
21
|
+
* @returns GridHelper object
|
|
22
|
+
*/
|
|
23
|
+
export declare function createGridHelper(size: number, divisions: number, colorCenterLine: number, colorGrid: number): THREE.GridHelper;
|
|
24
|
+
/**
|
|
25
|
+
* optimal number of grid divisions for a given size
|
|
26
|
+
* @param size
|
|
27
|
+
*/
|
|
28
|
+
export declare function computeDivisionsForSize(size: number): number;
|
|
29
|
+
/**
|
|
30
|
+
* Components, branching points and wires intermediate points snap to the nearest integer grid point.
|
|
31
|
+
* @param position
|
|
32
|
+
* @constructor
|
|
33
|
+
*/
|
|
34
|
+
export declare function nearestWorldSnapPosition(position: THREE.Vector3): THREE.Vector3;
|
|
35
|
+
/**
|
|
36
|
+
* Converts a world 3D position to the snapped 2D model grid position.
|
|
37
|
+
* @param position
|
|
38
|
+
* @constructor
|
|
39
|
+
*/
|
|
40
|
+
export declare function worldToGridPosition(position: THREE.Vector3): Position;
|
|
41
|
+
/**
|
|
42
|
+
* Converts a model grid 2D position to the world 3D position.
|
|
43
|
+
* @param position
|
|
44
|
+
* @constructor
|
|
45
|
+
*/
|
|
46
|
+
export declare function gridToWorldPosition(position: Position): THREE.Vector3;
|
|
47
|
+
/**
|
|
48
|
+
* Converts a world 3D rotation to the model grid 2D rotation.
|
|
49
|
+
* @param rotation
|
|
50
|
+
* @constructor
|
|
51
|
+
*/
|
|
52
|
+
export declare function worldToGridRotation(rotation: THREE.Euler): Rotation;
|
|
53
|
+
/**
|
|
54
|
+
* Converts model grid 2D rotation to the world 3D rotation.
|
|
55
|
+
* @param rotation
|
|
56
|
+
* @constructor
|
|
57
|
+
*/
|
|
58
|
+
export declare function gridToWorldRotation(rotation: Rotation): THREE.Euler;
|
|
59
|
+
/**
|
|
60
|
+
* Get the bounding box of a Three.js object in world space
|
|
61
|
+
*
|
|
62
|
+
* @param object - The Three.js object to get bounds for
|
|
63
|
+
* @returns Box3 representing the world-space bounding box
|
|
64
|
+
*/
|
|
65
|
+
export declare function getObjectBoundingBox(object: THREE.Object3D): THREE.Box3;
|
|
66
|
+
/**
|
|
67
|
+
* Project a 3D world position to 2D screen coordinates
|
|
68
|
+
*
|
|
69
|
+
* @param worldPosition - Position in world space
|
|
70
|
+
* @param camera - Camera to use for projection
|
|
71
|
+
* @param width - Viewport width in pixels
|
|
72
|
+
* @param height - Viewport height in pixels
|
|
73
|
+
* @returns Screen coordinates {x, y} where (0,0) is top-left
|
|
74
|
+
*/
|
|
75
|
+
export declare function worldToScreenPosition(worldPosition: THREE.Vector3, camera: THREE.Camera, width: number, height: number): {
|
|
76
|
+
x: number;
|
|
77
|
+
y: number;
|
|
78
|
+
};
|
|
79
|
+
/**
|
|
80
|
+
* Check if a 3D point (projected to screen space) is inside a 2D screen rectangle
|
|
81
|
+
*
|
|
82
|
+
* @param worldPosition - Position in world space
|
|
83
|
+
* @param camera - Camera to use for projection
|
|
84
|
+
* @param width - Viewport width in pixels
|
|
85
|
+
* @param height - Viewport height in pixels
|
|
86
|
+
* @param rect - Screen rectangle with min/max coordinates
|
|
87
|
+
* @returns true if the projected point is inside the rectangle
|
|
88
|
+
*/
|
|
89
|
+
export declare function isPointInScreenRect(worldPosition: THREE.Vector3, camera: THREE.Camera, width: number, height: number, rect: {
|
|
90
|
+
minX: number;
|
|
91
|
+
minY: number;
|
|
92
|
+
maxX: number;
|
|
93
|
+
maxY: number;
|
|
94
|
+
}): boolean;
|
|
95
|
+
/**
|
|
96
|
+
* Check if an object's center point is inside a screen rectangle
|
|
97
|
+
* Used for rectangle selection of components and branching points
|
|
98
|
+
*
|
|
99
|
+
* @param object - The Three.js object to check
|
|
100
|
+
* @param camera - Camera to use for projection
|
|
101
|
+
* @param width - Viewport width in pixels
|
|
102
|
+
* @param height - Viewport height in pixels
|
|
103
|
+
* @param rect - Screen rectangle with min/max coordinates
|
|
104
|
+
* @returns true if object's center is inside the rectangle
|
|
105
|
+
*/
|
|
106
|
+
export declare function isObjectInScreenRect(object: THREE.Object3D, camera: THREE.Camera, width: number, height: number, rect: {
|
|
107
|
+
minX: number;
|
|
108
|
+
minY: number;
|
|
109
|
+
maxX: number;
|
|
110
|
+
maxY: number;
|
|
111
|
+
}): boolean;
|
|
112
|
+
/**
|
|
113
|
+
* Create a ring geometry with given inner/outer radius and depth (y axis)
|
|
114
|
+
* @param innerRadius
|
|
115
|
+
* @param outerRadius
|
|
116
|
+
* @param depth
|
|
117
|
+
* @param steps
|
|
118
|
+
* @constructor
|
|
119
|
+
*/
|
|
120
|
+
export declare function RingGeometry(innerRadius: number, outerRadius: number, depth: number, steps: number): ExtrudeGeometry;
|
|
121
|
+
/**
|
|
122
|
+
* Create an ExtrudeGeometry for the body of an AND gate.
|
|
123
|
+
* Shape is centered at origin: flat side on the left, semicircle on the right,
|
|
124
|
+
* matching the standard logic gate schematic representation.
|
|
125
|
+
* Handles both standard (width > height / 2) and tall (width ≤ height / 2) proportions.
|
|
126
|
+
*
|
|
127
|
+
* Input pins attach on the left flat side (x = -width/2).
|
|
128
|
+
* Output pin attaches at the rightmost point of the arc (x = +width/2).
|
|
129
|
+
*
|
|
130
|
+
* The thickness parameter controls a visual state trick:
|
|
131
|
+
* - LOW state: thin thickness → gate appears as an empty shell
|
|
132
|
+
* - HIGH state: thick thickness → gate appears filled
|
|
133
|
+
* - TRANSITIONING: medium thickness → gate appears half-filled
|
|
134
|
+
*
|
|
135
|
+
* @param width - Total width, from left flat edge to rightmost arc point
|
|
136
|
+
* @param height - Total height; also determines the arc radius (= height / 2)
|
|
137
|
+
* @param thickness - Wall thickness of the gate shell
|
|
138
|
+
* @param depth - Extrusion depth
|
|
139
|
+
* @param steps - Number of extrusion steps
|
|
140
|
+
* @constructor
|
|
141
|
+
*/
|
|
142
|
+
export declare function AndGateGeometry(width: number, height: number, thickness: number, depth: number, steps?: number): ExtrudeGeometry;
|
|
143
|
+
/**
|
|
144
|
+
* Create an ExtrudeGeometry for the inner hole of an AND gate body.
|
|
145
|
+
* Returns null when thickness is large enough that the gate has no hole.
|
|
146
|
+
* Handles both standard (width > height / 2) and tall (width ≤ height / 2) proportions.
|
|
147
|
+
*
|
|
148
|
+
* @param width - Total width, from left flat edge to rightmost arc point
|
|
149
|
+
* @param height - Total height
|
|
150
|
+
* @param thickness - Wall thickness of the gate shell
|
|
151
|
+
* @param depth - Extrusion depth
|
|
152
|
+
* @param steps - Number of extrusion steps
|
|
153
|
+
*/
|
|
154
|
+
export declare function AndGateHoleGeometry(width: number, height: number, thickness: number, depth: number, steps?: number): ExtrudeGeometry | null;
|
|
155
|
+
/**
|
|
156
|
+
* Create an ExtrudeGeometry for the body of an OR gate.
|
|
157
|
+
* Same structure as AndGateGeometry but the left side is a concave arc (curves inward)
|
|
158
|
+
* instead of a flat edge, matching the standard logic gate schematic representation.
|
|
159
|
+
* Handles both standard (width > height / 2) and tall (width ≤ height / 2) proportions.
|
|
160
|
+
*
|
|
161
|
+
* Input pins attach on the left curved side (nominally at x = -width/2).
|
|
162
|
+
* Output pin attaches at the rightmost point of the right arc (x = +width/2).
|
|
163
|
+
*
|
|
164
|
+
* The thickness parameter controls the same visual state trick as AndGateGeometry:
|
|
165
|
+
* - LOW state: thin thickness → gate appears as an empty shell
|
|
166
|
+
* - HIGH state: thick thickness → gate appears filled
|
|
167
|
+
* - TRANSITIONING: medium thickness → gate appears half-filled
|
|
168
|
+
*
|
|
169
|
+
* Back arc geometry: the concave left side bows inward (rightward) by backInset = halfH * 0.4.
|
|
170
|
+
* The arc center sits far to the left; u_b is its x-distance to the back-left corners.
|
|
171
|
+
* The inner hole back arc is concentric with the outer (same center, radius += 0.1), giving a
|
|
172
|
+
* truly constant perpendicular wall thickness of 0.1 along the entire back curve, independent
|
|
173
|
+
* of the thickness parameter.
|
|
174
|
+
*
|
|
175
|
+
* @param width - Total width, from leftmost back curve point to rightmost arc point
|
|
176
|
+
* @param height - Total height; also determines the right arc radius (= height / 2)
|
|
177
|
+
* @param thickness - Wall thickness of the gate shell
|
|
178
|
+
* @param depth - Extrusion depth
|
|
179
|
+
* @param steps - Number of extrusion steps
|
|
180
|
+
* @constructor
|
|
181
|
+
*/
|
|
182
|
+
export declare function OrGateGeometry(width: number, height: number, thickness: number, depth: number, steps?: number): ExtrudeGeometry;
|
|
183
|
+
/**
|
|
184
|
+
* Create an ExtrudeGeometry for the inner hole of an OR gate body.
|
|
185
|
+
* Returns null when thickness is large enough that the gate has no hole.
|
|
186
|
+
* Handles both standard (width > height / 2) and tall (width ≤ height / 2) proportions.
|
|
187
|
+
*
|
|
188
|
+
* @param width - Total width
|
|
189
|
+
* @param height - Total height
|
|
190
|
+
* @param thickness - Wall thickness of the gate shell
|
|
191
|
+
* @param depth - Extrusion depth
|
|
192
|
+
* @param steps - Number of extrusion steps
|
|
193
|
+
*/
|
|
194
|
+
export declare function OrGateHoleGeometry(width: number, height: number, thickness: number, depth: number, steps?: number): ExtrudeGeometry | null;
|
|
195
|
+
/**
|
|
196
|
+
* Create an ExtrudeGeometry for the XOR gate tail — the distinctive extra curved bar
|
|
197
|
+
* placed to the left of an OrGateGeometry body to form the full XOR gate symbol.
|
|
198
|
+
*
|
|
199
|
+
* Back-arc parameters (backInset, u_b, cx_b, r_b, angle_b) are identical to those in
|
|
200
|
+
* OrGateGeometry so this geometry aligns correctly when placed at the same centre.
|
|
201
|
+
*
|
|
202
|
+
* Note: the tail arc's centre is shifted left by tailWidth (radius stays constant = r_b), so
|
|
203
|
+
* the tail always spans the full gate height regardless of tailWidth.
|
|
204
|
+
* For bars to be visible, barsSeparation must be less than orHeight − 2 × thickness.
|
|
205
|
+
*
|
|
206
|
+
* @param orWidth - Width of the paired OR gate body
|
|
207
|
+
* @param orHeight - Height of the paired OR gate body
|
|
208
|
+
* @param tailWidth - How far left the tail arc's corners are from the OR gate's left corners
|
|
209
|
+
* @param thickness - Wall thickness of the arc shell AND height of each bar
|
|
210
|
+
* @param barsSeparation - Vertical gap between the two bars (centred on y = 0)
|
|
211
|
+
* @param depth - Extrusion depth
|
|
212
|
+
* @param steps - Number of extrusion steps
|
|
213
|
+
*/
|
|
214
|
+
export declare function XorGateTailGeometry(orWidth: number, orHeight: number, tailWidth: number, thickness: number, barsSeparation: number, depth: number, steps?: number): ExtrudeGeometry;
|
|
215
|
+
/**
|
|
216
|
+
* Create an ExtrudeGeometry shaped like an L (or mirrored L) with a configurable
|
|
217
|
+
* angle between the two arms.
|
|
218
|
+
*
|
|
219
|
+
* Default orientation (`invert = false`) produces a `|_`-like shape:
|
|
220
|
+
* base arm extends to the right, stem arm extends upward at the given angle.
|
|
221
|
+
* When `invert = true` the shape is mirrored horizontally (`_|`-like):
|
|
222
|
+
* base arm extends to the left, stem arm mirrors accordingly.
|
|
223
|
+
*
|
|
224
|
+
* The `angle` parameter (in degrees) controls the inner angle between the two arms:
|
|
225
|
+
* - 90° → standard right-angle L
|
|
226
|
+
* - 120° → obtuse junction (`\_`-like)
|
|
227
|
+
* - 60° → acute junction
|
|
228
|
+
*
|
|
229
|
+
* Both the inner (concave) and outer (convex) junction corners are rounded
|
|
230
|
+
* equally with `junctionRadius` (similar to CSS border-radius).
|
|
231
|
+
* When 0 both corners are sharp. The arc sweep adapts to the angle: (180° − angle).
|
|
232
|
+
*
|
|
233
|
+
* The geometry is centered on its bounding box.
|
|
234
|
+
*
|
|
235
|
+
* At 90°, `width` and `height` correspond exactly to the bounding box dimensions.
|
|
236
|
+
* At other angles the bounding box changes but the arm lengths remain consistent:
|
|
237
|
+
* base inner arm = width − thickness, stem inner arm = height − thickness.
|
|
238
|
+
*
|
|
239
|
+
* @param width - Base arm length (bounding-box width at 90°)
|
|
240
|
+
* @param height - Stem arm length (bounding-box height at 90°)
|
|
241
|
+
* @param thickness - Arm thickness of the L
|
|
242
|
+
* @param angle - Inner angle between the two arms, in degrees (typically 30–150)
|
|
243
|
+
* @param invert - If true, mirror horizontally
|
|
244
|
+
* @param junctionRadius - Radius of the rounded junction corners, inner and outer (0 = sharp)
|
|
245
|
+
* @param depth - Extrusion depth
|
|
246
|
+
* @param steps - Number of extrusion steps
|
|
247
|
+
*/
|
|
248
|
+
export declare function LGeometry(width: number, height: number, thickness: number, angle: number, invert: boolean, junctionRadius: number, depth: number, steps?: number): ExtrudeGeometry;
|
|
249
|
+
export declare function CyclicTrapezoidGeometry(width: number, tailHeight: number, headHeight: number, thickness: number, depth: number, steps?: number): ExtrudeGeometry;
|
|
250
|
+
/**
|
|
251
|
+
* Create an ExtrudeGeometry for the inner hole of a cyclic trapezoid.
|
|
252
|
+
* Returns null when the geometry should be solid (no hole).
|
|
253
|
+
*
|
|
254
|
+
* @param width - Total width
|
|
255
|
+
* @param tailHeight - Height of the left (tail) side
|
|
256
|
+
* @param headHeight - Height of the right (head) side (0 for triangle)
|
|
257
|
+
* @param thickness - Wall thickness
|
|
258
|
+
* @param depth - Extrusion depth
|
|
259
|
+
* @param steps - Number of extrusion steps
|
|
260
|
+
*/
|
|
261
|
+
export declare function CyclicTrapezoidHoleGeometry(width: number, tailHeight: number, headHeight: number, thickness: number, depth: number, steps?: number): ExtrudeGeometry | null;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Three.js Layer Constants for Hitbox Organization
|
|
3
|
+
* @module scene/shared/utils/LayerConstants
|
|
4
|
+
*
|
|
5
|
+
* Defines layer assignments for priority-based raycasting and rendering.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Three.js layer assignments for hitbox meshes and rendering
|
|
9
|
+
*
|
|
10
|
+
* Layers enable priority-based raycasting by querying layers sequentially.
|
|
11
|
+
* Lower layer numbers = higher priority for hover detection.
|
|
12
|
+
*
|
|
13
|
+
* @remarks
|
|
14
|
+
* - Layer 0 is reserved for default visual rendering
|
|
15
|
+
* - Hitbox layers (1-3) are invisible but raycastable
|
|
16
|
+
* - Camera.layers should include only layer 0 for rendering
|
|
17
|
+
* - Raycaster.layers is set per-query based on priority
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* ```typescript
|
|
21
|
+
* import { HitboxLayers } from './LayerConstants';
|
|
22
|
+
*
|
|
23
|
+
* // Assign hitbox to component layer
|
|
24
|
+
* hitboxMesh.layers.set(HitboxLayers.COMPONENT);
|
|
25
|
+
*
|
|
26
|
+
* // Raycast only enode hitboxes
|
|
27
|
+
* raycaster.layers.set(HitboxLayers.ENODE);
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
export declare const HitboxLayers: {
|
|
31
|
+
/** Default layer for visual rendering (do not use for hitboxes) */
|
|
32
|
+
readonly DEFAULT: 0;
|
|
33
|
+
/** Enode hitboxes - highest hover priority */
|
|
34
|
+
readonly ENODE: 1;
|
|
35
|
+
/** Component hitboxes - medium hover priority */
|
|
36
|
+
readonly COMPONENT: 2;
|
|
37
|
+
/** Wire hitboxes - lowest hover priority */
|
|
38
|
+
readonly WIRE: 3;
|
|
39
|
+
};
|
|
40
|
+
export type HitboxLayerValue = (typeof HitboxLayers)[keyof typeof HitboxLayers];
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lighting Utilities
|
|
3
|
+
* @module scene/shared/utils/LightingUtils
|
|
4
|
+
*
|
|
5
|
+
* Helper functions for setting up scene lighting
|
|
6
|
+
*/
|
|
7
|
+
import * as THREE from 'three';
|
|
8
|
+
/**
|
|
9
|
+
* Create an ambient light with default intensity
|
|
10
|
+
*
|
|
11
|
+
* @param color - Light color (hex)
|
|
12
|
+
* @param intensity - Light intensity (0-1)
|
|
13
|
+
* @returns AmbientLight
|
|
14
|
+
*/
|
|
15
|
+
export declare function createAmbientLight(color?: number, intensity?: number): THREE.AmbientLight;
|
|
16
|
+
/**
|
|
17
|
+
* Create a directional light with default positioning
|
|
18
|
+
*
|
|
19
|
+
* @param color - Light color (hex)
|
|
20
|
+
* @param intensity - Light intensity
|
|
21
|
+
* @param position - Light position
|
|
22
|
+
* @returns DirectionalLight
|
|
23
|
+
*/
|
|
24
|
+
export declare function createDirectionalLight(color?: number, intensity?: number, position?: THREE.Vector3): THREE.DirectionalLight;
|
|
25
|
+
/**
|
|
26
|
+
* Setup standard scene lighting (ambient + directional)
|
|
27
|
+
*
|
|
28
|
+
* @param scene - Scene to add lights to
|
|
29
|
+
* @returns Array of created lights
|
|
30
|
+
*/
|
|
31
|
+
export declare function setupSceneLights(scene: THREE.Scene): THREE.Light[];
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { LineMaterial } from 'three/examples/jsm/lines/LineMaterial.js';
|
|
2
|
+
/**
|
|
3
|
+
* Material Utilities
|
|
4
|
+
* @module scene/shared/utils/MaterialUtils
|
|
5
|
+
*
|
|
6
|
+
* Helper functions for creating and managing Three.js materials
|
|
7
|
+
*/
|
|
8
|
+
import * as THREE from 'three';
|
|
9
|
+
/**
|
|
10
|
+
* Create a standard material with common defaults
|
|
11
|
+
*
|
|
12
|
+
* @param color - Base color (hex)
|
|
13
|
+
* @param options - Additional material options
|
|
14
|
+
* @returns MeshStandardMaterial
|
|
15
|
+
*/
|
|
16
|
+
export declare function createStandardMaterial(color: number, options?: {
|
|
17
|
+
emissive?: number;
|
|
18
|
+
emissiveIntensity?: number;
|
|
19
|
+
metalness?: number;
|
|
20
|
+
roughness?: number;
|
|
21
|
+
transparent?: boolean;
|
|
22
|
+
opacity?: number;
|
|
23
|
+
}): THREE.MeshStandardMaterial;
|
|
24
|
+
/**
|
|
25
|
+
* Create a material for wire lines
|
|
26
|
+
*
|
|
27
|
+
* @param color - Line color (hex)
|
|
28
|
+
* @param linewidth - Line width (note: may not work on all platforms)
|
|
29
|
+
* @returns LineBasicMaterial
|
|
30
|
+
*/
|
|
31
|
+
export declare function createLineMaterial(color?: number, linewidth?: number): THREE.LineBasicMaterial;
|
|
32
|
+
/**
|
|
33
|
+
* Create a LineMaterial for Line2 rendering with consistent line width
|
|
34
|
+
*
|
|
35
|
+
* Note: Resolution must be set after creation using material.resolution.set(width, height)
|
|
36
|
+
*
|
|
37
|
+
* @param color - Line color (hex, default: 0xffffff/white)
|
|
38
|
+
* @param linewidth - Line width in pixels (default: 2)
|
|
39
|
+
* @returns LineMaterial for Line2 objects
|
|
40
|
+
*
|
|
41
|
+
* @example
|
|
42
|
+
* ```typescript
|
|
43
|
+
* const material = createLine2Material(0xffffff, 2);
|
|
44
|
+
* material.resolution.set(window.innerWidth, window.innerHeight);
|
|
45
|
+
* ```
|
|
46
|
+
*/
|
|
47
|
+
export declare function createLine2Material(color?: number, linewidth?: number): LineMaterial;
|
|
48
|
+
/**
|
|
49
|
+
* Update material state for component state changes
|
|
50
|
+
*
|
|
51
|
+
* @param material - Material to update
|
|
52
|
+
* @param state - Component state data
|
|
53
|
+
*/
|
|
54
|
+
export declare function updateMaterialState(material: THREE.MeshStandardMaterial, state: {
|
|
55
|
+
isActive?: boolean;
|
|
56
|
+
isHighlighted?: boolean;
|
|
57
|
+
customColor?: number;
|
|
58
|
+
emissiveIntensity?: number;
|
|
59
|
+
}): void;
|
|
60
|
+
/**
|
|
61
|
+
* Create a semi-transparent preview material
|
|
62
|
+
*
|
|
63
|
+
* @param baseColor - Base color
|
|
64
|
+
* @param opacity - Transparency level (0-1)
|
|
65
|
+
* @returns MeshStandardMaterial configured for preview
|
|
66
|
+
*/
|
|
67
|
+
export declare function createPreviewMaterial(baseColor: number, opacity?: number): THREE.MeshStandardMaterial;
|
|
68
|
+
/**
|
|
69
|
+
* Create an error state material (for validation feedback)
|
|
70
|
+
*
|
|
71
|
+
* @returns MeshStandardMaterial in error state (red tint)
|
|
72
|
+
*/
|
|
73
|
+
export declare function createErrorMaterial(): THREE.MeshStandardMaterial;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { ControllerOptions, EngineOptions, MapControlsOptions } from '../types';
|
|
2
|
+
/**
|
|
3
|
+
* returns default complete mapControlsOptions or an autocompleted partial mapControlOptions
|
|
4
|
+
* @param options
|
|
5
|
+
*/
|
|
6
|
+
export declare function mapControlsOptions(options?: MapControlsOptions | undefined): MapControlsOptions;
|
|
7
|
+
/**
|
|
8
|
+
* returns default complete controllerOptions or an autocompleted partial controllerOptions
|
|
9
|
+
* @param options
|
|
10
|
+
*/
|
|
11
|
+
export declare function controllerOptions(options?: ControllerOptions | undefined): ControllerOptions;
|
|
12
|
+
/**
|
|
13
|
+
* returns default complete engineOptions or and autoCompleted partial engineOptions
|
|
14
|
+
* @param options
|
|
15
|
+
*/
|
|
16
|
+
export declare function engineOptions(options?: EngineOptions | undefined): EngineOptions;
|
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
import { Circuit, BehaviorRegistry } from '../../core/index.ts';
|
|
2
|
+
import { IFactoryRegistry } from '../shared/components/ComponentVisualFactory';
|
|
3
|
+
import { SharedResources, ControllerOptions } from '../shared/types';
|
|
4
|
+
import { AbstractCircuitController } from '../shared/AbstractCircuitController';
|
|
5
|
+
/**
|
|
6
|
+
* Simulation Circuit Runner Controller Implementation
|
|
7
|
+
*
|
|
8
|
+
* Manages Three.js scene for live circuit simulation visualization.
|
|
9
|
+
* Provides smooth interpolation between simulation ticks for 60fps rendering.
|
|
10
|
+
* Animates current flow through wires and component state changes.
|
|
11
|
+
*/
|
|
12
|
+
export declare class CircuitRunnerController extends AbstractCircuitController {
|
|
13
|
+
private _runner;
|
|
14
|
+
private _behaviorRegistry;
|
|
15
|
+
private _animationContext;
|
|
16
|
+
private _autoPlay;
|
|
17
|
+
private _isPlaying;
|
|
18
|
+
private _tickIntervalMs;
|
|
19
|
+
private _simulationLoopId;
|
|
20
|
+
private _clickHandler;
|
|
21
|
+
/**
|
|
22
|
+
* Create a new Simulation Circuit Controller
|
|
23
|
+
*
|
|
24
|
+
* @param factoryRegistry - Component visual factory registry
|
|
25
|
+
* @param behaviorRegistry - Component behavior registry
|
|
26
|
+
* @param sharedResources - Optional shared resources for facade pattern (CircuitEngine)
|
|
27
|
+
* @throws {TypeError} If factoryRegistry is null/undefined
|
|
28
|
+
*/
|
|
29
|
+
constructor(factoryRegistry: IFactoryRegistry, behaviorRegistry: BehaviorRegistry, sharedResources?: SharedResources);
|
|
30
|
+
/**
|
|
31
|
+
* Check if simulation is currently playing (auto-advancing ticks)
|
|
32
|
+
* Returns false if paused or no circuit loaded
|
|
33
|
+
*/
|
|
34
|
+
get isPlaying(): boolean;
|
|
35
|
+
/**
|
|
36
|
+
* Get current tick interval in milliseconds
|
|
37
|
+
* Default is 500ms (2 ticks per second)
|
|
38
|
+
*/
|
|
39
|
+
get tickInterval(): number;
|
|
40
|
+
/**
|
|
41
|
+
* Set tick interval in milliseconds (50-2000ms)
|
|
42
|
+
* If simulation is playing, restarts the interval with new value
|
|
43
|
+
*
|
|
44
|
+
* @param value - Interval in milliseconds, must be between 50-2000ms
|
|
45
|
+
* @throws {RangeError} If value is outside valid range
|
|
46
|
+
*/
|
|
47
|
+
set tickInterval(value: number);
|
|
48
|
+
/**
|
|
49
|
+
* Get current simulation speed in ticks per second.
|
|
50
|
+
* Range: 1-20 TPS
|
|
51
|
+
*/
|
|
52
|
+
get simulationSpeed(): number;
|
|
53
|
+
/**
|
|
54
|
+
* Set simulation speed in ticks per second.
|
|
55
|
+
* Value is clamped to range 1-20 TPS.
|
|
56
|
+
* If simulation is playing, restarts the interval with new value.
|
|
57
|
+
* Emits 'simulationSpeedChanged' event when speed changes.
|
|
58
|
+
*
|
|
59
|
+
* @param tps - Ticks per second (1-20)
|
|
60
|
+
*/
|
|
61
|
+
set simulationSpeed(tps: number);
|
|
62
|
+
/**
|
|
63
|
+
* Minimum allowed simulation speed in ticks per second.
|
|
64
|
+
*/
|
|
65
|
+
get minSimulationSpeed(): number;
|
|
66
|
+
/**
|
|
67
|
+
* Maximum allowed simulation speed in ticks per second.
|
|
68
|
+
*/
|
|
69
|
+
get maxSimulationSpeed(): number;
|
|
70
|
+
/**
|
|
71
|
+
* Compute the number of ticks required for a transition given its duration in milliseconds.
|
|
72
|
+
* Formula: ceil(transitionUserSpanMs × simulationSpeed / 1000), minimum 1.
|
|
73
|
+
*
|
|
74
|
+
* @param transitionUserSpanMs - Transition duration in milliseconds
|
|
75
|
+
* @returns Number of ticks for the transition (minimum 1)
|
|
76
|
+
*/
|
|
77
|
+
computeTickCount(transitionUserSpanMs: number): number;
|
|
78
|
+
/**
|
|
79
|
+
* Get the transition duration from component config for user-driven transitions.
|
|
80
|
+
* @param config - Component config map
|
|
81
|
+
* @returns Transition duration in milliseconds (defaults to TRANSITION_USER_SPAN_MS)
|
|
82
|
+
*/
|
|
83
|
+
private _getTransitionUserSpan;
|
|
84
|
+
/**
|
|
85
|
+
* Get current simulation tick number
|
|
86
|
+
* Returns 0 if no circuit runner is loaded
|
|
87
|
+
*/
|
|
88
|
+
get currentTick(): number;
|
|
89
|
+
/**
|
|
90
|
+
* Specific Initialization logic, performed after AbstractCircuitController initialization
|
|
91
|
+
* @private
|
|
92
|
+
*
|
|
93
|
+
* @param options - Controller options passed to initialize()
|
|
94
|
+
*/
|
|
95
|
+
protected onInitialize(options?: ControllerOptions): void;
|
|
96
|
+
protected emitReady(): void;
|
|
97
|
+
/**
|
|
98
|
+
* specific disposal prepended at the beginning of dispose process
|
|
99
|
+
*/
|
|
100
|
+
protected onDispose(): void;
|
|
101
|
+
onSetActive(active: boolean): void;
|
|
102
|
+
setCircuit(circuit: Circuit | null): void;
|
|
103
|
+
/**
|
|
104
|
+
* specific logic when to render a new set circuit
|
|
105
|
+
* @protected
|
|
106
|
+
*/
|
|
107
|
+
protected onSetCircuit(): void;
|
|
108
|
+
/**
|
|
109
|
+
* Play automatic simulation playback
|
|
110
|
+
* Simulation will advance at the configured tick interval until paused
|
|
111
|
+
*
|
|
112
|
+
* Requires a circuit runner to be loaded via setCircuitRunner()
|
|
113
|
+
* Emits 'simulationPlayed' event on play
|
|
114
|
+
* Emits 'simulationTick' event on each tick
|
|
115
|
+
*/
|
|
116
|
+
play(): void;
|
|
117
|
+
/**
|
|
118
|
+
* Pause automatic simulation playback
|
|
119
|
+
* Safe to call even if already paused or no circuit loaded
|
|
120
|
+
*
|
|
121
|
+
* Emits 'simulationPaused' event
|
|
122
|
+
*/
|
|
123
|
+
pause(): void;
|
|
124
|
+
/**
|
|
125
|
+
* Execute a single simulation tick
|
|
126
|
+
* Simulation remains paused after step, useful for debugging
|
|
127
|
+
*
|
|
128
|
+
* If currently playing, pauses first then steps
|
|
129
|
+
* Requires a circuit runner to be loaded via setCircuitRunner()
|
|
130
|
+
* Emits 'simulationStepped' event with tick result
|
|
131
|
+
*/
|
|
132
|
+
step(): void;
|
|
133
|
+
/**
|
|
134
|
+
* Stop the simulation, reset visual to initial state
|
|
135
|
+
* Simulation remains paused after step, useful for debugging
|
|
136
|
+
*
|
|
137
|
+
* If currently playing, pauses first then steps
|
|
138
|
+
* Requires a circuit runner to be loaded via setCircuitRunner()
|
|
139
|
+
* Emits 'simulationStopped' event with tick result (0)
|
|
140
|
+
*/
|
|
141
|
+
stop(): void;
|
|
142
|
+
/**
|
|
143
|
+
* Execute one simulation tick and update visuals
|
|
144
|
+
* @private
|
|
145
|
+
*/
|
|
146
|
+
private _executeTick;
|
|
147
|
+
/**
|
|
148
|
+
* Update component animations for dirty components
|
|
149
|
+
* @private
|
|
150
|
+
*/
|
|
151
|
+
private _updateDirtyComponents;
|
|
152
|
+
/**
|
|
153
|
+
* Update all active AnimationMixers.
|
|
154
|
+
* Called per frame from the render loop via CircuitEngine.update(delta).
|
|
155
|
+
*
|
|
156
|
+
* @param delta - Time in seconds since last frame
|
|
157
|
+
*/
|
|
158
|
+
updateAnimations(delta: number): void;
|
|
159
|
+
/**
|
|
160
|
+
* Recompute animation timescales when simulation speed changes mid-animation.
|
|
161
|
+
* Updates ticksPerSecond on userData and adjusts active action timeScales.
|
|
162
|
+
*/
|
|
163
|
+
private _updateAnimationTimescales;
|
|
164
|
+
/**
|
|
165
|
+
* Update wire visual state based on electrical state
|
|
166
|
+
* @private
|
|
167
|
+
*/
|
|
168
|
+
private _updateDirtyWires;
|
|
169
|
+
/**
|
|
170
|
+
* Update enode visual state based on electrical state
|
|
171
|
+
* Applies emissive glow to pins and branching points
|
|
172
|
+
* @private
|
|
173
|
+
*/
|
|
174
|
+
private _updateDirtyEnodes;
|
|
175
|
+
/**
|
|
176
|
+
* rollback wires/enodes/components visuals to edition state (no simulation state)
|
|
177
|
+
*/
|
|
178
|
+
_removeSimulationStateVisuals(): void;
|
|
179
|
+
/**
|
|
180
|
+
* Handle click events for component interaction
|
|
181
|
+
* @param event
|
|
182
|
+
* @private
|
|
183
|
+
*/
|
|
184
|
+
private _handleClick;
|
|
185
|
+
/**
|
|
186
|
+
* Handle regular click events : emit user commands to the runner
|
|
187
|
+
* @param clickedElement
|
|
188
|
+
* @private
|
|
189
|
+
*/
|
|
190
|
+
private _handleRegularClick;
|
|
191
|
+
private _handleCtrlClick;
|
|
192
|
+
/**
|
|
193
|
+
* recreate all visuals based on circuit data
|
|
194
|
+
* Should be called on an already cleared scene
|
|
195
|
+
*
|
|
196
|
+
* When using shared resources (CircuitEngine facade), skips visual creation
|
|
197
|
+
* if visuals already exist in the shared maps (created by edit controller).
|
|
198
|
+
* @private
|
|
199
|
+
*/
|
|
200
|
+
private _fullUpdate;
|
|
201
|
+
/**
|
|
202
|
+
* Consider all elements as dirty to update all visual state according to simulation state
|
|
203
|
+
* @private
|
|
204
|
+
*/
|
|
205
|
+
private _visualUpdateFromSimulationState;
|
|
206
|
+
private _createComponentObject3D;
|
|
207
|
+
/**
|
|
208
|
+
* Index component mesh and its pins meshes for interaction (hover, selection)
|
|
209
|
+
* @param componentId
|
|
210
|
+
* @param object3D
|
|
211
|
+
* @private
|
|
212
|
+
*/
|
|
213
|
+
private _indexComponentObject3D;
|
|
214
|
+
/**
|
|
215
|
+
* Create enode (branching point ONLY) visual object and add to scene
|
|
216
|
+
* pin enodes are created and attache to their components by createComponentObject3D()
|
|
217
|
+
*
|
|
218
|
+
* @param enode
|
|
219
|
+
* @private
|
|
220
|
+
*/
|
|
221
|
+
private _createEnodeObject3D;
|
|
222
|
+
private _createWireObject3D;
|
|
223
|
+
private _removeComponentObject3D;
|
|
224
|
+
private _removeEnodeObject3D;
|
|
225
|
+
private _removeWireObject3D;
|
|
226
|
+
protected _removeAllVisuals(): void;
|
|
227
|
+
}
|