@pascal-app/viewer 1.0.6 → 1.0.7
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/dist/components/viewer/daylight-atmosphere.d.ts +9 -0
- package/dist/components/viewer/daylight-atmosphere.d.ts.map +1 -0
- package/dist/components/viewer/daylight-atmosphere.js +315 -0
- package/dist/components/viewer/drone-controller.d.ts +15 -0
- package/dist/components/viewer/drone-controller.d.ts.map +1 -0
- package/dist/components/viewer/drone-controller.js +194 -0
- package/dist/components/viewer/glb-interactive.d.ts +4 -18
- package/dist/components/viewer/glb-interactive.d.ts.map +1 -1
- package/dist/components/viewer/glb-interactive.js +32 -268
- package/dist/components/viewer/glb-scene-motion.d.ts +8 -0
- package/dist/components/viewer/glb-scene-motion.d.ts.map +1 -0
- package/dist/components/viewer/glb-scene-motion.js +57 -0
- package/dist/components/viewer/glb-scene.d.ts +3 -1
- package/dist/components/viewer/glb-scene.d.ts.map +1 -1
- package/dist/components/viewer/glb-scene.js +289 -49
- package/dist/components/viewer/glb-selection-callout.d.ts +17 -0
- package/dist/components/viewer/glb-selection-callout.d.ts.map +1 -0
- package/dist/components/viewer/glb-selection-callout.js +54 -0
- package/dist/components/viewer/glb-walkthrough-controller.d.ts.map +1 -1
- package/dist/components/viewer/glb-walkthrough-controller.js +6 -3
- package/dist/components/viewer/index.d.ts +5 -0
- package/dist/components/viewer/index.d.ts.map +1 -1
- package/dist/components/viewer/index.js +30 -6
- package/dist/components/viewer/lights.d.ts.map +1 -1
- package/dist/components/viewer/lights.js +192 -5
- package/dist/components/viewer/post-processing.d.ts.map +1 -1
- package/dist/components/viewer/post-processing.js +150 -94
- package/dist/components/viewer/scene-environment.js +4 -5
- package/dist/components/viewer/selection-callout.d.ts +51 -0
- package/dist/components/viewer/selection-callout.d.ts.map +1 -0
- package/dist/components/viewer/selection-callout.js +197 -0
- package/dist/components/viewer/use-daylight-rooms.d.ts +13 -0
- package/dist/components/viewer/use-daylight-rooms.d.ts.map +1 -0
- package/dist/components/viewer/use-daylight-rooms.js +236 -0
- package/dist/components/viewer/viewer-camera.d.ts.map +1 -1
- package/dist/components/viewer/viewer-camera.js +12 -1
- package/dist/index.d.ts +21 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +23 -7
- package/dist/lib/daylight/ground.d.ts +21 -0
- package/dist/lib/daylight/ground.d.ts.map +1 -0
- package/dist/lib/daylight/ground.js +53 -0
- package/dist/lib/daylight/location.d.ts +32 -0
- package/dist/lib/daylight/location.d.ts.map +1 -0
- package/dist/lib/daylight/location.js +74 -0
- package/dist/lib/daylight/look.d.ts +33 -0
- package/dist/lib/daylight/look.d.ts.map +1 -0
- package/dist/lib/daylight/look.js +13 -0
- package/dist/lib/daylight/material-hooks.d.ts +2 -0
- package/dist/lib/daylight/material-hooks.d.ts.map +1 -0
- package/dist/lib/daylight/material-hooks.js +150 -0
- package/dist/lib/daylight/room-context.d.ts +12 -0
- package/dist/lib/daylight/room-context.d.ts.map +1 -0
- package/dist/lib/daylight/room-context.js +53 -0
- package/dist/lib/daylight/room-scene.d.ts +54 -0
- package/dist/lib/daylight/room-scene.d.ts.map +1 -0
- package/dist/lib/daylight/room-scene.js +356 -0
- package/dist/lib/daylight/rooms.d.ts +262 -0
- package/dist/lib/daylight/rooms.d.ts.map +1 -0
- package/dist/lib/daylight/rooms.js +1223 -0
- package/dist/lib/daylight/runtime.d.ts +33 -0
- package/dist/lib/daylight/runtime.d.ts.map +1 -0
- package/dist/lib/daylight/runtime.js +42 -0
- package/dist/lib/daylight/sky.d.ts +26 -0
- package/dist/lib/daylight/sky.d.ts.map +1 -0
- package/dist/lib/daylight/sky.js +217 -0
- package/dist/lib/daylight/solar.d.ts +46 -0
- package/dist/lib/daylight/solar.d.ts.map +1 -0
- package/dist/lib/daylight/solar.js +156 -0
- package/dist/lib/device-tier.d.ts +29 -0
- package/dist/lib/device-tier.d.ts.map +1 -0
- package/dist/lib/device-tier.js +71 -0
- package/dist/lib/dispose-object3d.d.ts.map +1 -1
- package/dist/lib/dispose-object3d.js +4 -2
- package/dist/lib/drone-flight.d.ts +44 -0
- package/dist/lib/drone-flight.d.ts.map +1 -0
- package/dist/lib/drone-flight.js +121 -0
- package/dist/lib/editor-highlight.d.ts +16 -0
- package/dist/lib/editor-highlight.d.ts.map +1 -0
- package/dist/lib/editor-highlight.js +33 -0
- package/dist/lib/foundation-materials.d.ts.map +1 -1
- package/dist/lib/foundation-materials.js +2 -4
- package/dist/lib/glb-merge.d.ts +23 -0
- package/dist/lib/glb-merge.d.ts.map +1 -0
- package/dist/lib/glb-merge.js +184 -0
- package/dist/lib/hardware-geometry.d.ts +21 -0
- package/dist/lib/hardware-geometry.d.ts.map +1 -0
- package/dist/lib/hardware-geometry.js +283 -0
- package/dist/lib/layer-pass.d.ts +2 -0
- package/dist/lib/layer-pass.d.ts.map +1 -1
- package/dist/lib/layer-pass.js +20 -0
- package/dist/lib/materials.d.ts.map +1 -1
- package/dist/lib/materials.js +50 -23
- package/dist/lib/merged-outline-node.d.ts.map +1 -1
- package/dist/lib/merged-outline-node.js +7 -1
- package/dist/lib/occlusion-culler.d.ts +34 -0
- package/dist/lib/occlusion-culler.d.ts.map +1 -0
- package/dist/lib/occlusion-culler.js +698 -0
- package/dist/lib/post-processing-resources.d.ts +4 -0
- package/dist/lib/post-processing-resources.d.ts.map +1 -1
- package/dist/lib/post-processing-resources.js +5 -0
- package/dist/lib/readback-rows.d.ts +14 -0
- package/dist/lib/readback-rows.d.ts.map +1 -0
- package/dist/lib/readback-rows.js +31 -0
- package/dist/lib/reveal-pose.d.ts.map +1 -1
- package/dist/lib/reveal-pose.js +3 -0
- package/dist/lib/scene-matrices.d.ts +12 -0
- package/dist/lib/scene-matrices.d.ts.map +1 -0
- package/dist/lib/scene-matrices.js +287 -0
- package/dist/lib/scene-pass-mrt.d.ts +5 -2
- package/dist/lib/scene-pass-mrt.d.ts.map +1 -1
- package/dist/lib/scene-pass-mrt.js +7 -2
- package/dist/lib/scene-themes.d.ts +0 -2
- package/dist/lib/scene-themes.d.ts.map +1 -1
- package/dist/lib/scene-themes.js +0 -2
- package/dist/lib/scene-visibility.d.ts +2 -0
- package/dist/lib/scene-visibility.d.ts.map +1 -1
- package/dist/lib/scene-visibility.js +12 -3
- package/dist/lib/site-surfaces.d.ts +1 -8
- package/dist/lib/site-surfaces.d.ts.map +1 -1
- package/dist/lib/site-surfaces.js +0 -19
- package/dist/lib/snapshot-pipeline.d.ts.map +1 -1
- package/dist/lib/snapshot-pipeline.js +24 -40
- package/dist/lib/texture-reference.d.ts.map +1 -1
- package/dist/lib/texture-reference.js +10 -8
- package/dist/lib/underground-ambiance.d.ts +0 -2
- package/dist/lib/underground-ambiance.d.ts.map +1 -1
- package/dist/lib/underground-ambiance.js +0 -2
- package/dist/store/use-item-light-pool.d.ts +3 -6
- package/dist/store/use-item-light-pool.d.ts.map +1 -1
- package/dist/store/use-item-light-pool.js +12 -0
- package/dist/store/use-viewer.d.ts +72 -15
- package/dist/store/use-viewer.d.ts.map +1 -1
- package/dist/store/use-viewer.js +103 -18
- package/dist/systems/ceiling/ceiling-system.d.ts +5 -0
- package/dist/systems/ceiling/ceiling-system.d.ts.map +1 -1
- package/dist/systems/ceiling/ceiling-system.js +11 -1
- package/dist/systems/door/door-system.d.ts.map +1 -1
- package/dist/systems/door/door-system.js +501 -145
- package/dist/systems/door/leaf-profile.d.ts +11 -0
- package/dist/systems/door/leaf-profile.d.ts.map +1 -0
- package/dist/systems/door/leaf-profile.js +140 -0
- package/dist/systems/interactive/callout-actions.d.ts +72 -0
- package/dist/systems/interactive/callout-actions.d.ts.map +1 -0
- package/dist/systems/interactive/callout-actions.js +212 -0
- package/dist/systems/interactive/interactive-system.d.ts +5 -1
- package/dist/systems/interactive/interactive-system.d.ts.map +1 -1
- package/dist/systems/interactive/interactive-system.js +44 -121
- package/dist/systems/interactive/opening-settled.d.ts +16 -0
- package/dist/systems/interactive/opening-settled.d.ts.map +1 -0
- package/dist/systems/interactive/opening-settled.js +53 -0
- package/dist/systems/item-light/item-light-system.d.ts.map +1 -1
- package/dist/systems/item-light/item-light-system.js +22 -214
- package/dist/systems/item-light/pooled-lights.d.ts +70 -0
- package/dist/systems/item-light/pooled-lights.d.ts.map +1 -0
- package/dist/systems/item-light/pooled-lights.js +449 -0
- package/dist/systems/level/level-system.d.ts.map +1 -1
- package/dist/systems/level/level-system.js +19 -1
- package/dist/systems/roof/roof-material-slots.d.ts +14 -0
- package/dist/systems/roof/roof-material-slots.d.ts.map +1 -0
- package/dist/systems/roof/roof-material-slots.js +13 -0
- package/dist/systems/roof/roof-materials.d.ts +25 -2
- package/dist/systems/roof/roof-materials.d.ts.map +1 -1
- package/dist/systems/roof/roof-materials.js +85 -26
- package/dist/systems/roof/roof-system.d.ts +34 -1
- package/dist/systems/roof/roof-system.d.ts.map +1 -1
- package/dist/systems/roof/roof-system.js +477 -105
- package/dist/systems/wall/opening-casing-geometry.d.ts +14 -0
- package/dist/systems/wall/opening-casing-geometry.d.ts.map +1 -0
- package/dist/systems/wall/opening-casing-geometry.js +102 -0
- package/dist/systems/wall/opening-cutout-geometry.d.ts +9 -0
- package/dist/systems/wall/opening-cutout-geometry.d.ts.map +1 -1
- package/dist/systems/wall/opening-cutout-geometry.js +7 -3
- package/dist/systems/wall/wall-materials.d.ts.map +1 -1
- package/dist/systems/wall/wall-materials.js +28 -35
- package/dist/systems/wall/wall-system.d.ts.map +1 -1
- package/dist/systems/wall/wall-system.js +34 -19
- package/dist/systems/wall/wall-t-junctions.d.ts +15 -0
- package/dist/systems/wall/wall-t-junctions.d.ts.map +1 -0
- package/dist/systems/wall/wall-t-junctions.js +149 -0
- package/dist/systems/window/window-animation-system.d.ts +3 -12
- package/dist/systems/window/window-animation-system.d.ts.map +1 -1
- package/dist/systems/window/window-animation-system.js +37 -122
- package/dist/systems/window/window-pose.d.ts +31 -0
- package/dist/systems/window/window-pose.d.ts.map +1 -0
- package/dist/systems/window/window-pose.js +152 -0
- package/dist/systems/window/window-roller-shutter.d.ts +8 -0
- package/dist/systems/window/window-roller-shutter.d.ts.map +1 -0
- package/dist/systems/window/window-roller-shutter.js +64 -0
- package/dist/systems/window/window-system.d.ts +2 -11
- package/dist/systems/window/window-system.d.ts.map +1 -1
- package/dist/systems/window/window-system.js +470 -303
- package/package.json +6 -6
- package/dist/systems/interactive/control-widget.d.ts +0 -10
- package/dist/systems/interactive/control-widget.d.ts.map +0 -1
- package/dist/systems/interactive/control-widget.js +0 -35
- package/dist/systems/interactive/procedural-controls.d.ts +0 -13
- package/dist/systems/interactive/procedural-controls.d.ts.map +0 -1
- package/dist/systems/interactive/procedural-controls.js +0 -17
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { type Object3D, type Quaternion, Vector3 } from 'three';
|
|
2
|
+
/** Cruise speed, metres per second. */
|
|
3
|
+
export declare const DRONE_SPEED = 7;
|
|
4
|
+
export declare const DRONE_RUN_MULTIPLIER = 3;
|
|
5
|
+
/** Alt: a slower flight and a finer look, for framing. */
|
|
6
|
+
export declare const DRONE_SLOW_MULTIPLIER = 0.2;
|
|
7
|
+
/** Exponential approach rate toward the wanted velocity (1/s), not a linear acceleration. */
|
|
8
|
+
export declare const DRONE_SMOOTHING = 12;
|
|
9
|
+
/** Radians of turn per pixel of pointer-locked mouse movement. */
|
|
10
|
+
export declare const FIRST_PERSON_LOOK_SENSITIVITY = 0.002;
|
|
11
|
+
export type DroneLook = {
|
|
12
|
+
yaw: number;
|
|
13
|
+
pitch: number;
|
|
14
|
+
};
|
|
15
|
+
export type DroneInput = {
|
|
16
|
+
forward: boolean;
|
|
17
|
+
backward: boolean;
|
|
18
|
+
leftward: boolean;
|
|
19
|
+
rightward: boolean;
|
|
20
|
+
up: boolean;
|
|
21
|
+
down: boolean;
|
|
22
|
+
boost: boolean;
|
|
23
|
+
slow: boolean;
|
|
24
|
+
};
|
|
25
|
+
/** The drone control a `KeyboardEvent.code` drives, if any. */
|
|
26
|
+
export declare function droneInputForKey(code: string): keyof DroneInput | null;
|
|
27
|
+
export declare function createDroneInput(): DroneInput;
|
|
28
|
+
/**
|
|
29
|
+
* Writes the controls the held keys drive into `out`. Reading from the set of
|
|
30
|
+
* held codes (rather than toggling a flag per key) keeps a control held while
|
|
31
|
+
* either of its keys is — releasing E does not cancel a held Space.
|
|
32
|
+
*/
|
|
33
|
+
export declare function readDroneInput(heldCodes: ReadonlySet<string>, out: DroneInput): DroneInput;
|
|
34
|
+
/** Picks up the look angles from wherever the camera currently points. */
|
|
35
|
+
export declare function seedDroneLook(look: DroneLook, quaternion: Quaternion): void;
|
|
36
|
+
/** Turns a first-person look by a pointer-locked mouse movement; pitch stops short of straight up/down. */
|
|
37
|
+
export declare function turnFirstPersonLook(look: DroneLook, movementX: number, movementY: number, sensitivityScale?: number): void;
|
|
38
|
+
/**
|
|
39
|
+
* Advances the drone one frame: orients the camera from the look angles, eases
|
|
40
|
+
* `velocity` toward the wanted one (WASD along the view axes, pitch included;
|
|
41
|
+
* up/down along world Y) and moves the camera by it.
|
|
42
|
+
*/
|
|
43
|
+
export declare function stepDroneFlight(camera: Object3D, look: DroneLook, input: DroneInput, velocity: Vector3, delta: number): void;
|
|
44
|
+
//# sourceMappingURL=drone-flight.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"drone-flight.d.ts","sourceRoot":"","sources":["../../src/lib/drone-flight.ts"],"names":[],"mappings":"AAAA,OAAO,EAAS,KAAK,QAAQ,EAAE,KAAK,UAAU,EAAE,OAAO,EAAE,MAAM,OAAO,CAAA;AAKtE,uCAAuC;AACvC,eAAO,MAAM,WAAW,IAAI,CAAA;AAC5B,eAAO,MAAM,oBAAoB,IAAI,CAAA;AACrC,0DAA0D;AAC1D,eAAO,MAAM,qBAAqB,MAAM,CAAA;AACxC,6FAA6F;AAC7F,eAAO,MAAM,eAAe,KAAK,CAAA;AACjC,kEAAkE;AAClE,eAAO,MAAM,6BAA6B,QAAQ,CAAA;AAMlD,MAAM,MAAM,SAAS,GAAG;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAA;AAEtD,MAAM,MAAM,UAAU,GAAG;IACvB,OAAO,EAAE,OAAO,CAAA;IAChB,QAAQ,EAAE,OAAO,CAAA;IACjB,QAAQ,EAAE,OAAO,CAAA;IACjB,SAAS,EAAE,OAAO,CAAA;IAClB,EAAE,EAAE,OAAO,CAAA;IACX,IAAI,EAAE,OAAO,CAAA;IACb,KAAK,EAAE,OAAO,CAAA;IACd,IAAI,EAAE,OAAO,CAAA;CACd,CAAA;AAsBD,+DAA+D;AAC/D,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,UAAU,GAAG,IAAI,CAEtE;AAED,wBAAgB,gBAAgB,IAAI,UAAU,CAW7C;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,SAAS,EAAE,WAAW,CAAC,MAAM,CAAC,EAAE,GAAG,EAAE,UAAU,GAAG,UAAU,CAc1F;AAID,0EAA0E;AAC1E,wBAAgB,aAAa,CAAC,IAAI,EAAE,SAAS,EAAE,UAAU,EAAE,UAAU,QAIpE;AAED,2GAA2G;AAC3G,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,SAAS,EACf,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,gBAAgB,SAAI,QAKrB;AAOD;;;;GAIG;AACH,wBAAgB,eAAe,CAC7B,MAAM,EAAE,QAAQ,EAChB,IAAI,EAAE,SAAS,EACf,KAAK,EAAE,UAAU,EACjB,QAAQ,EAAE,OAAO,EACjB,KAAK,EAAE,MAAM,QA2Bd"}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import { Euler, Vector3 } from 'three';
|
|
2
|
+
// The drone camera: a free flight with no gravity, floor or collision, shared by
|
|
3
|
+
// the viewer's `DroneController` and the editor's first-person capture camera.
|
|
4
|
+
/** Cruise speed, metres per second. */
|
|
5
|
+
export const DRONE_SPEED = 7;
|
|
6
|
+
export const DRONE_RUN_MULTIPLIER = 3;
|
|
7
|
+
/** Alt: a slower flight and a finer look, for framing. */
|
|
8
|
+
export const DRONE_SLOW_MULTIPLIER = 0.2;
|
|
9
|
+
/** Exponential approach rate toward the wanted velocity (1/s), not a linear acceleration. */
|
|
10
|
+
export const DRONE_SMOOTHING = 12;
|
|
11
|
+
/** Radians of turn per pixel of pointer-locked mouse movement. */
|
|
12
|
+
export const FIRST_PERSON_LOOK_SENSITIVITY = 0.002;
|
|
13
|
+
const PITCH_LIMIT = Math.PI / 2 - 0.05;
|
|
14
|
+
// A long frame (tab switch, GC pause) must not teleport the camera.
|
|
15
|
+
const MAX_STEP = 0.1;
|
|
16
|
+
const DRONE_KEY_BINDINGS = {
|
|
17
|
+
KeyW: 'forward',
|
|
18
|
+
ArrowUp: 'forward',
|
|
19
|
+
KeyS: 'backward',
|
|
20
|
+
ArrowDown: 'backward',
|
|
21
|
+
KeyA: 'leftward',
|
|
22
|
+
ArrowLeft: 'leftward',
|
|
23
|
+
KeyD: 'rightward',
|
|
24
|
+
ArrowRight: 'rightward',
|
|
25
|
+
Space: 'up',
|
|
26
|
+
KeyE: 'up',
|
|
27
|
+
KeyQ: 'down',
|
|
28
|
+
ControlLeft: 'down',
|
|
29
|
+
ControlRight: 'down',
|
|
30
|
+
ShiftLeft: 'boost',
|
|
31
|
+
ShiftRight: 'boost',
|
|
32
|
+
AltLeft: 'slow',
|
|
33
|
+
AltRight: 'slow',
|
|
34
|
+
};
|
|
35
|
+
/** The drone control a `KeyboardEvent.code` drives, if any. */
|
|
36
|
+
export function droneInputForKey(code) {
|
|
37
|
+
return DRONE_KEY_BINDINGS[code] ?? null;
|
|
38
|
+
}
|
|
39
|
+
export function createDroneInput() {
|
|
40
|
+
return {
|
|
41
|
+
forward: false,
|
|
42
|
+
backward: false,
|
|
43
|
+
leftward: false,
|
|
44
|
+
rightward: false,
|
|
45
|
+
up: false,
|
|
46
|
+
down: false,
|
|
47
|
+
boost: false,
|
|
48
|
+
slow: false,
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Writes the controls the held keys drive into `out`. Reading from the set of
|
|
53
|
+
* held codes (rather than toggling a flag per key) keeps a control held while
|
|
54
|
+
* either of its keys is — releasing E does not cancel a held Space.
|
|
55
|
+
*/
|
|
56
|
+
export function readDroneInput(heldCodes, out) {
|
|
57
|
+
out.forward = false;
|
|
58
|
+
out.backward = false;
|
|
59
|
+
out.leftward = false;
|
|
60
|
+
out.rightward = false;
|
|
61
|
+
out.up = false;
|
|
62
|
+
out.down = false;
|
|
63
|
+
out.boost = false;
|
|
64
|
+
out.slow = false;
|
|
65
|
+
for (const code of heldCodes) {
|
|
66
|
+
const control = DRONE_KEY_BINDINGS[code];
|
|
67
|
+
if (control)
|
|
68
|
+
out[control] = true;
|
|
69
|
+
}
|
|
70
|
+
return out;
|
|
71
|
+
}
|
|
72
|
+
const lookEuler = new Euler(0, 0, 0, 'YXZ');
|
|
73
|
+
/** Picks up the look angles from wherever the camera currently points. */
|
|
74
|
+
export function seedDroneLook(look, quaternion) {
|
|
75
|
+
lookEuler.setFromQuaternion(quaternion, 'YXZ');
|
|
76
|
+
look.yaw = lookEuler.y;
|
|
77
|
+
look.pitch = lookEuler.x;
|
|
78
|
+
}
|
|
79
|
+
/** Turns a first-person look by a pointer-locked mouse movement; pitch stops short of straight up/down. */
|
|
80
|
+
export function turnFirstPersonLook(look, movementX, movementY, sensitivityScale = 1) {
|
|
81
|
+
const sensitivity = FIRST_PERSON_LOOK_SENSITIVITY * sensitivityScale;
|
|
82
|
+
look.yaw -= movementX * sensitivity;
|
|
83
|
+
look.pitch = Math.max(-PITCH_LIMIT, Math.min(PITCH_LIMIT, look.pitch - movementY * sensitivity));
|
|
84
|
+
}
|
|
85
|
+
const flightEuler = new Euler(0, 0, 0, 'YXZ');
|
|
86
|
+
const flightForward = new Vector3();
|
|
87
|
+
const flightRight = new Vector3();
|
|
88
|
+
const flightDesired = new Vector3();
|
|
89
|
+
/**
|
|
90
|
+
* Advances the drone one frame: orients the camera from the look angles, eases
|
|
91
|
+
* `velocity` toward the wanted one (WASD along the view axes, pitch included;
|
|
92
|
+
* up/down along world Y) and moves the camera by it.
|
|
93
|
+
*/
|
|
94
|
+
export function stepDroneFlight(camera, look, input, velocity, delta) {
|
|
95
|
+
const step = Math.min(delta, MAX_STEP);
|
|
96
|
+
flightEuler.set(look.pitch, look.yaw, 0, 'YXZ');
|
|
97
|
+
camera.quaternion.setFromEuler(flightEuler);
|
|
98
|
+
flightForward.set(0, 0, -1).applyEuler(flightEuler);
|
|
99
|
+
flightRight.set(1, 0, 0).applyEuler(flightEuler);
|
|
100
|
+
flightDesired.set(0, 0, 0);
|
|
101
|
+
if (input.forward)
|
|
102
|
+
flightDesired.add(flightForward);
|
|
103
|
+
if (input.backward)
|
|
104
|
+
flightDesired.sub(flightForward);
|
|
105
|
+
if (input.rightward)
|
|
106
|
+
flightDesired.add(flightRight);
|
|
107
|
+
if (input.leftward)
|
|
108
|
+
flightDesired.sub(flightRight);
|
|
109
|
+
if (input.up)
|
|
110
|
+
flightDesired.y += 1;
|
|
111
|
+
if (input.down)
|
|
112
|
+
flightDesired.y -= 1;
|
|
113
|
+
if (flightDesired.lengthSq() > 0) {
|
|
114
|
+
flightDesired
|
|
115
|
+
.normalize()
|
|
116
|
+
.multiplyScalar(DRONE_SPEED * (input.slow ? DRONE_SLOW_MULTIPLIER : input.boost ? DRONE_RUN_MULTIPLIER : 1));
|
|
117
|
+
}
|
|
118
|
+
velocity.lerp(flightDesired, 1 - Math.exp(-step * DRONE_SMOOTHING));
|
|
119
|
+
camera.position.addScaledVector(velocity, step);
|
|
120
|
+
camera.updateMatrixWorld(true);
|
|
121
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Color, type Material } from 'three';
|
|
2
|
+
/**
|
|
3
|
+
* Marks an editor highlight material (selection, hover, delete): a clone of the object's own
|
|
4
|
+
* material with a soft emissive tint, so it reads as marked. The daylight look must not treat
|
|
5
|
+
* that tint as a glowing surface (no night boost, no exposure lift, no bloom): the object stays
|
|
6
|
+
* readable under it at any time of day.
|
|
7
|
+
*/
|
|
8
|
+
export declare function markHighlight<T extends Material>(material: T): T;
|
|
9
|
+
export declare function isHighlight(material: Material | null | undefined): boolean;
|
|
10
|
+
/**
|
|
11
|
+
* Adds a highlight tint to `material`'s emission: its own glow (a lamp's shade) as it was, plus
|
|
12
|
+
* `color` × `amount`. The intensity is folded into the colour (and set to 1): a material's default
|
|
13
|
+
* intensity is 1, so raising it to the tint's would have run the tint at full strength.
|
|
14
|
+
*/
|
|
15
|
+
export declare function tintEmissive(material: Material, color: Color, amount: number): void;
|
|
16
|
+
//# sourceMappingURL=editor-highlight.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"editor-highlight.d.ts","sourceRoot":"","sources":["../../src/lib/editor-highlight.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,KAAK,QAAQ,EAAE,MAAM,OAAO,CAAA;AAE5C;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,CAAC,SAAS,QAAQ,EAAE,QAAQ,EAAE,CAAC,GAAG,CAAC,CAOhE;AAED,wBAAgB,WAAW,CAAC,QAAQ,EAAE,QAAQ,GAAG,IAAI,GAAG,SAAS,GAAG,OAAO,CAE1E;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAQnF"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { Color } from 'three';
|
|
2
|
+
/**
|
|
3
|
+
* Marks an editor highlight material (selection, hover, delete): a clone of the object's own
|
|
4
|
+
* material with a soft emissive tint, so it reads as marked. The daylight look must not treat
|
|
5
|
+
* that tint as a glowing surface (no night boost, no exposure lift, no bloom): the object stays
|
|
6
|
+
* readable under it at any time of day.
|
|
7
|
+
*/
|
|
8
|
+
export function markHighlight(material) {
|
|
9
|
+
material.userData.editorHighlight = true;
|
|
10
|
+
// three shares a compiled program between materials of the same shape (userData aside): a
|
|
11
|
+
// highlight must get its own, or it renders with its source's and the daylight hooks miss it.
|
|
12
|
+
const key = material.customProgramCacheKey.bind(material);
|
|
13
|
+
material.customProgramCacheKey = () => `${key()}|editor-highlight`;
|
|
14
|
+
return material;
|
|
15
|
+
}
|
|
16
|
+
export function isHighlight(material) {
|
|
17
|
+
return material?.userData.editorHighlight === true;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Adds a highlight tint to `material`'s emission: its own glow (a lamp's shade) as it was, plus
|
|
21
|
+
* `color` × `amount`. The intensity is folded into the colour (and set to 1): a material's default
|
|
22
|
+
* intensity is 1, so raising it to the tint's would have run the tint at full strength.
|
|
23
|
+
*/
|
|
24
|
+
export function tintEmissive(material, color, amount) {
|
|
25
|
+
const m = material;
|
|
26
|
+
if (!(m.emissive instanceof Color))
|
|
27
|
+
return;
|
|
28
|
+
m.emissive = m.emissive
|
|
29
|
+
.clone()
|
|
30
|
+
.multiplyScalar(m.emissiveIntensity ?? 1)
|
|
31
|
+
.add(color.clone().multiplyScalar(amount));
|
|
32
|
+
m.emissiveIntensity = 1;
|
|
33
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"foundation-materials.d.ts","sourceRoot":"","sources":["../../src/lib/foundation-materials.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAE,uBAAuB,EAAE,MAAM,cAAc,CAAA;
|
|
1
|
+
{"version":3,"file":"foundation-materials.d.ts","sourceRoot":"","sources":["../../src/lib/foundation-materials.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAE,uBAAuB,EAAE,MAAM,cAAc,CAAA;AAgBtD,mGAAmG;AACnG,eAAO,MAAM,gBAAgB;aAC3B,GAAG;aACH,QAAQ;CACA,CAAA;AAUV,MAAM,MAAM,OAAO,GAAG;IACpB,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,MAAM,CAAA;IACd,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAA;IACvC,MAAM,EAAE,MAAM,CAAA;CACf,CAAA;AAED,eAAO,MAAM,aAAa,EAAE,OAM3B,CAAA;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAC7B,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,OAAO,EAChE,KAAK,GAAE,GAA0C,2BAkBlD;AAED,wBAAgB,gBAAgB,4BAO/B"}
|
|
@@ -2,10 +2,8 @@ import { FrontSide } from 'three';
|
|
|
2
2
|
import { attribute, color, float, floor, fract, mix, mod, mx_noise_float, normalLocal, positionWorld, smoothstep, step, vec3, } from 'three/tsl';
|
|
3
3
|
import { MeshLambertNodeMaterial } from 'three/webgpu';
|
|
4
4
|
/**
|
|
5
|
-
* How bare structure looks: courses of block, and cast concrete.
|
|
6
|
-
*
|
|
7
|
-
* over a masonry or concrete core shows the same on its exterior face (`wall-materials.ts`), so a
|
|
8
|
-
* basement's walls above grade read as the foundation under them.
|
|
5
|
+
* How bare structure looks: courses of block, and cast concrete. A wall whose assembly has no
|
|
6
|
+
* cladding over a masonry or concrete core shows it on its exterior face (`wall-materials.ts`).
|
|
9
7
|
*/
|
|
10
8
|
const INCH = 0.0254;
|
|
11
9
|
/** A nominal 8 × 8 × 16 in block: the course is 8 in with its joint, a block 16 in long. */
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import * as THREE from 'three';
|
|
2
|
+
export type GlbMergeOptions = {
|
|
3
|
+
/** pascalIds whose meshes must stay individual (lit lamps, animated fixtures). */
|
|
4
|
+
keepIds: ReadonlySet<string>;
|
|
5
|
+
/** Nodes driven by animation tracks (their subtrees move). */
|
|
6
|
+
animated: ReadonlySet<THREE.Object3D>;
|
|
7
|
+
};
|
|
8
|
+
export type GlbBatch = THREE.Mesh & {
|
|
9
|
+
userData: {
|
|
10
|
+
glbBatch: true;
|
|
11
|
+
role?: string;
|
|
12
|
+
bakedMaterial: THREE.Material;
|
|
13
|
+
};
|
|
14
|
+
};
|
|
15
|
+
export type GlbMerge = {
|
|
16
|
+
batches: GlbBatch[];
|
|
17
|
+
merged: number;
|
|
18
|
+
/** Changes when any merged original is shown or hidden on its own (the merge is then stale). */
|
|
19
|
+
visibilitySignature(): number;
|
|
20
|
+
dispose(): void;
|
|
21
|
+
};
|
|
22
|
+
export declare function mergeBakedStatic(root: THREE.Object3D, roleOf: (kind: string | undefined) => string | undefined, options: GlbMergeOptions): GlbMerge;
|
|
23
|
+
//# sourceMappingURL=glb-merge.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"glb-merge.d.ts","sourceRoot":"","sources":["../../src/lib/glb-merge.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AA0B9B,MAAM,MAAM,eAAe,GAAG;IAC5B,kFAAkF;IAClF,OAAO,EAAE,WAAW,CAAC,MAAM,CAAC,CAAA;IAC5B,8DAA8D;IAC9D,QAAQ,EAAE,WAAW,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAA;CACtC,CAAA;AAED,MAAM,MAAM,QAAQ,GAAG,KAAK,CAAC,IAAI,GAAG;IAClC,QAAQ,EAAE;QAAE,QAAQ,EAAE,IAAI,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,KAAK,CAAC,QAAQ,CAAA;KAAE,CAAA;CAC3E,CAAA;AAED,MAAM,MAAM,QAAQ,GAAG;IACrB,OAAO,EAAE,QAAQ,EAAE,CAAA;IACnB,MAAM,EAAE,MAAM,CAAA;IACd,gGAAgG;IAChG,mBAAmB,IAAI,MAAM,CAAA;IAC7B,OAAO,IAAI,IAAI,CAAA;CAChB,CAAA;AAQD,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,KAAK,CAAC,QAAQ,EACpB,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,KAAK,MAAM,GAAG,SAAS,EACxD,OAAO,EAAE,eAAe,GACvB,QAAQ,CA6IV"}
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
import * as THREE from 'three';
|
|
2
|
+
import { mergeGeometries } from 'three/addons/utils/BufferGeometryUtils.js';
|
|
3
|
+
import { hideFromScene, showInScene } from './scene-visibility';
|
|
4
|
+
const KEPT_KINDS = new Set(['ceiling', 'roof', 'roof-segment', 'site', 'zone', 'spawn', 'level']);
|
|
5
|
+
const ATTRIBUTES = ['position', 'normal', 'uv', 'uv1', 'color'];
|
|
6
|
+
/** Cell size (m) batches are split by, so frustum culling still drops what's behind the eye. */
|
|
7
|
+
const CELL = 24;
|
|
8
|
+
const NO_RAYCAST = () => { };
|
|
9
|
+
export function mergeBakedStatic(root, roleOf, options) {
|
|
10
|
+
root.updateWorldMatrix(true, true);
|
|
11
|
+
const groups = new Map();
|
|
12
|
+
const center = new THREE.Vector3();
|
|
13
|
+
root.traverse((object) => {
|
|
14
|
+
const mesh = object;
|
|
15
|
+
if (!mesh.isMesh || mesh.userData.glbBatch)
|
|
16
|
+
return;
|
|
17
|
+
if (mesh.isSkinnedMesh || mesh.isInstancedMesh)
|
|
18
|
+
return;
|
|
19
|
+
const material = (mesh.userData.__bakedMaterial ??
|
|
20
|
+
mesh.material);
|
|
21
|
+
if (Array.isArray(material) || !material)
|
|
22
|
+
return;
|
|
23
|
+
const glass = material.transparent || material.userData.isGlass || mesh.userData.slotId === 'glass';
|
|
24
|
+
if (mesh.geometry.morphAttributes.position)
|
|
25
|
+
return;
|
|
26
|
+
const geometry = mesh.geometry;
|
|
27
|
+
if (!geometry.getAttribute('position') || !geometry.getAttribute('normal'))
|
|
28
|
+
return;
|
|
29
|
+
// Walk up once: the level, the nearest moving pivot (a sash, a door leaf: its parts merge
|
|
30
|
+
// under it and swing with it), the owner's kind, and anything that disqualifies.
|
|
31
|
+
let level = null;
|
|
32
|
+
let pivot = null;
|
|
33
|
+
let ownerKind;
|
|
34
|
+
let inGlassSlot = false;
|
|
35
|
+
for (let x = mesh; x; x = x.parent) {
|
|
36
|
+
if (!x.visible)
|
|
37
|
+
return;
|
|
38
|
+
const extras = x.userData;
|
|
39
|
+
if (!pivot && x !== mesh && (options.animated.has(x) || extras.proceduralMotion))
|
|
40
|
+
pivot = x;
|
|
41
|
+
if (extras.slotId === 'glass')
|
|
42
|
+
inGlassSlot = true;
|
|
43
|
+
if (extras.pascalId) {
|
|
44
|
+
if (options.keepIds.has(extras.pascalId))
|
|
45
|
+
return;
|
|
46
|
+
if (ownerKind === undefined && extras.kind !== 'level')
|
|
47
|
+
ownerKind = extras.kind ?? '';
|
|
48
|
+
}
|
|
49
|
+
const kind = extras.kind;
|
|
50
|
+
if (kind === 'level') {
|
|
51
|
+
level = x;
|
|
52
|
+
break;
|
|
53
|
+
}
|
|
54
|
+
if (kind && (KEPT_KINDS.has(kind) || kind.includes(':')))
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
if (!level || options.animated.has(mesh))
|
|
58
|
+
return;
|
|
59
|
+
// Glass sorts per mesh: merge it only within one moving part (one sash's panes together).
|
|
60
|
+
if ((glass || inGlassSlot) && !pivot)
|
|
61
|
+
return;
|
|
62
|
+
const anchor = pivot ?? level;
|
|
63
|
+
const role = roleOf(ownerKind);
|
|
64
|
+
const signature = ATTRIBUTES.filter((name) => geometry.getAttribute(name)).join(',');
|
|
65
|
+
if (!geometry.boundingBox)
|
|
66
|
+
geometry.computeBoundingBox();
|
|
67
|
+
geometry.boundingBox.getCenter(center).applyMatrix4(mesh.matrixWorld);
|
|
68
|
+
const cell = pivot ? '' : `${Math.floor(center.x / CELL)},${Math.floor(center.z / CELL)}`;
|
|
69
|
+
const key = [
|
|
70
|
+
anchor.uuid,
|
|
71
|
+
cell,
|
|
72
|
+
material.uuid,
|
|
73
|
+
role ?? '',
|
|
74
|
+
signature,
|
|
75
|
+
mesh.castShadow,
|
|
76
|
+
mesh.receiveShadow,
|
|
77
|
+
].join('|');
|
|
78
|
+
let group = groups.get(key);
|
|
79
|
+
if (!group) {
|
|
80
|
+
group = { anchor, material, role, meshes: [] };
|
|
81
|
+
groups.set(key, group);
|
|
82
|
+
}
|
|
83
|
+
group.meshes.push(mesh);
|
|
84
|
+
});
|
|
85
|
+
const batches = [];
|
|
86
|
+
const originals = [];
|
|
87
|
+
const toAnchor = new THREE.Matrix4();
|
|
88
|
+
const local = new THREE.Matrix4();
|
|
89
|
+
for (const group of groups.values()) {
|
|
90
|
+
if (group.meshes.length < 2)
|
|
91
|
+
continue;
|
|
92
|
+
toAnchor.copy(group.anchor.matrixWorld).invert();
|
|
93
|
+
const names = ATTRIBUTES.filter((name) => group.meshes[0].geometry.getAttribute(name));
|
|
94
|
+
const parts = [];
|
|
95
|
+
for (const mesh of group.meshes) {
|
|
96
|
+
const source = mesh.geometry;
|
|
97
|
+
const part = new THREE.BufferGeometry();
|
|
98
|
+
for (const name of names)
|
|
99
|
+
part.setAttribute(name, toFloat(source.getAttribute(name)));
|
|
100
|
+
const count = part.getAttribute('position').count;
|
|
101
|
+
part.setIndex(source.index
|
|
102
|
+
? Array.from(source.index.array)
|
|
103
|
+
: Array.from({ length: count }, (_, i) => i));
|
|
104
|
+
local.multiplyMatrices(toAnchor, mesh.matrixWorld);
|
|
105
|
+
part.applyMatrix4(local);
|
|
106
|
+
if (local.determinant() < 0)
|
|
107
|
+
flipWinding(part); // mirrored transforms flip winding
|
|
108
|
+
parts.push(part);
|
|
109
|
+
}
|
|
110
|
+
const geometry = mergeGeometries(parts, false);
|
|
111
|
+
for (const part of parts)
|
|
112
|
+
part.dispose();
|
|
113
|
+
if (!geometry)
|
|
114
|
+
continue;
|
|
115
|
+
geometry.computeBoundingBox();
|
|
116
|
+
geometry.computeBoundingSphere();
|
|
117
|
+
const batch = new THREE.Mesh(geometry, group.material);
|
|
118
|
+
batch.name = `glb-batch:${group.material.name || group.material.type}`;
|
|
119
|
+
batch.castShadow = group.meshes[0].castShadow;
|
|
120
|
+
batch.receiveShadow = group.meshes[0].receiveShadow;
|
|
121
|
+
batch.userData = { glbBatch: true, role: group.role, bakedMaterial: group.material };
|
|
122
|
+
batch.raycast = NO_RAYCAST;
|
|
123
|
+
group.anchor.add(batch);
|
|
124
|
+
batches.push(batch);
|
|
125
|
+
for (const mesh of group.meshes) {
|
|
126
|
+
hideFromScene(mesh, 'batched');
|
|
127
|
+
originals.push(mesh);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
return {
|
|
131
|
+
batches,
|
|
132
|
+
merged: originals.length,
|
|
133
|
+
visibilitySignature() {
|
|
134
|
+
let h = 0;
|
|
135
|
+
for (let i = 0; i < originals.length; i++) {
|
|
136
|
+
const mesh = originals[i];
|
|
137
|
+
// Its own visibility up to the level: level-wide hiding is the batch's parent's job.
|
|
138
|
+
let shown = true;
|
|
139
|
+
for (let x = mesh; x && shown; x = x.parent) {
|
|
140
|
+
if (x.userData.kind === 'level')
|
|
141
|
+
break;
|
|
142
|
+
shown = x.visible;
|
|
143
|
+
}
|
|
144
|
+
if (shown)
|
|
145
|
+
h += (i % 97) + 1;
|
|
146
|
+
}
|
|
147
|
+
return h;
|
|
148
|
+
},
|
|
149
|
+
dispose() {
|
|
150
|
+
for (const batch of batches) {
|
|
151
|
+
batch.removeFromParent();
|
|
152
|
+
batch.geometry.dispose();
|
|
153
|
+
}
|
|
154
|
+
for (const mesh of originals)
|
|
155
|
+
showInScene(mesh, 'batched');
|
|
156
|
+
batches.length = 0;
|
|
157
|
+
originals.length = 0;
|
|
158
|
+
},
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
function toFloat(attribute) {
|
|
162
|
+
const count = attribute.count;
|
|
163
|
+
const size = attribute.itemSize;
|
|
164
|
+
const out = new Float32Array(count * size);
|
|
165
|
+
for (let i = 0; i < count; i++) {
|
|
166
|
+
out[i * size] = attribute.getX(i);
|
|
167
|
+
if (size > 1)
|
|
168
|
+
out[i * size + 1] = attribute.getY(i);
|
|
169
|
+
if (size > 2)
|
|
170
|
+
out[i * size + 2] = attribute.getZ(i);
|
|
171
|
+
if (size > 3)
|
|
172
|
+
out[i * size + 3] = attribute.getW(i);
|
|
173
|
+
}
|
|
174
|
+
return new THREE.BufferAttribute(out, size);
|
|
175
|
+
}
|
|
176
|
+
function flipWinding(geometry) {
|
|
177
|
+
const index = geometry.index.array;
|
|
178
|
+
for (let i = 0; i < index.length; i += 3) {
|
|
179
|
+
const t = index[i + 1];
|
|
180
|
+
index[i + 1] = index[i + 2];
|
|
181
|
+
index[i + 2] = t;
|
|
182
|
+
}
|
|
183
|
+
geometry.index.needsUpdate = true;
|
|
184
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { type BufferGeometry } from 'three';
|
|
2
|
+
export declare function leverOnRose(): BufferGeometry<import("three").NormalBufferAttributes, import("three").BufferGeometryEventMap>;
|
|
3
|
+
export declare function leverOnRoseCurved(): BufferGeometry<import("three").NormalBufferAttributes, import("three").BufferGeometryEventMap>;
|
|
4
|
+
export declare function leverOnPlate(): BufferGeometry<import("three").NormalBufferAttributes, import("three").BufferGeometryEventMap>;
|
|
5
|
+
/** Origin at the mounting face; a 56 mm ball on a 20 mm neck and 56 mm rose. */
|
|
6
|
+
export declare function knobOnRose(): BufferGeometry<import("three").NormalBufferAttributes, import("three").BufferGeometryEventMap>;
|
|
7
|
+
/** Origin at the face; a 40 × 120 mm open cup with a 3 mm rim, recessed 12 mm. */
|
|
8
|
+
export declare function flushPull(): BufferGeometry<import("three").NormalBufferAttributes, import("three").BufferGeometryEventMap>;
|
|
9
|
+
/** Odd knuckles and plate on the leaf edge (+X), extending into the rebate (-Z). */
|
|
10
|
+
export declare function hingeLeafPart(diameter?: number, height?: number): BufferGeometry<import("three").NormalBufferAttributes, import("three").BufferGeometryEventMap>;
|
|
11
|
+
/** Even knuckles and plate on the jamb face (-X), extending into the rebate (-Z). */
|
|
12
|
+
export declare function hingeJambPart(diameter?: number, height?: number): BufferGeometry<import("three").NormalBufferAttributes, import("three").BufferGeometryEventMap>;
|
|
13
|
+
/** Origin on the mounting face; bar along Y, projecting along +Z. */
|
|
14
|
+
export declare function pullBar(doorScale?: boolean): BufferGeometry<import("three").NormalBufferAttributes, import("three").BufferGeometryEventMap>;
|
|
15
|
+
export declare function roundedBox(w: number, h: number, d: number, r?: number): BufferGeometry<import("three").NormalBufferAttributes, import("three").BufferGeometryEventMap>;
|
|
16
|
+
/** A capped round bar along Y. */
|
|
17
|
+
export declare function tube(radius: number, length: number): BufferGeometry<import("three").NormalBufferAttributes, import("three").BufferGeometryEventMap>;
|
|
18
|
+
export declare function sphere(radius: number): BufferGeometry<import("three").NormalBufferAttributes, import("three").BufferGeometryEventMap>;
|
|
19
|
+
/** A wheel with its axle along Z. */
|
|
20
|
+
export declare function roller(radius: number, width: number): BufferGeometry<import("three").NormalBufferAttributes, import("three").BufferGeometryEventMap>;
|
|
21
|
+
//# sourceMappingURL=hardware-geometry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hardware-geometry.d.ts","sourceRoot":"","sources":["../../src/lib/hardware-geometry.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,cAAc,EASpB,MAAM,OAAO,CAAA;AAgKd,wBAAgB,WAAW,mGAE1B;AAED,wBAAgB,iBAAiB,mGAEhC;AAED,wBAAgB,YAAY,mGAE3B;AAED,gFAAgF;AAChF,wBAAgB,UAAU,mGAazB;AAED,kFAAkF;AAClF,wBAAgB,SAAS,mGAiBxB;AAsCD,oFAAoF;AACpF,wBAAgB,aAAa,CAAC,QAAQ,SAAQ,EAAE,MAAM,SAAQ,kGAE7D;AAED,qFAAqF;AACrF,wBAAgB,aAAa,CAAC,QAAQ,SAAQ,EAAE,MAAM,SAAQ,kGAE7D;AAED,qEAAqE;AACrE,wBAAgB,OAAO,CAAC,SAAS,UAAQ,kGA0BxC;AAmBD,wBAAgB,UAAU,CACxB,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,EACT,CAAC,SAAuC,kGAOzC;AAED,kCAAkC;AAClC,wBAAgB,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,kGAElD;AAED,wBAAgB,MAAM,CAAC,MAAM,EAAE,MAAM,kGAMpC;AAED,qCAAqC;AACrC,wBAAgB,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,kGAInD"}
|