abstract-3d 3.1.1 → 4.0.0-beta.0
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/README.md +21 -1
- package/lib/renderers/dxf/dxf-encoding/dxf-build.d.ts.map +1 -1
- package/lib/renderers/dxf/dxf-encoding/dxf-build.js +1 -2
- package/lib/renderers/dxf/dxf-encoding/dxf-build.js.map +1 -1
- package/lib/renderers/ifc/ifc.test.d.ts +2 -0
- package/lib/renderers/ifc/ifc.test.d.ts.map +1 -0
- package/lib/renderers/ifc/ifc.test.js +380 -0
- package/lib/renderers/ifc/ifc.test.js.map +1 -0
- package/lib/renderers/index.d.ts +1 -0
- package/lib/renderers/index.d.ts.map +1 -1
- package/lib/renderers/index.js +1 -0
- package/lib/renderers/index.js.map +1 -1
- package/lib/renderers/react/index.d.ts +2 -5
- package/lib/renderers/react/index.d.ts.map +1 -1
- package/lib/renderers/react/index.js +1 -2
- package/lib/renderers/react/index.js.map +1 -1
- package/lib/renderers/react/react.d.ts +16 -42
- package/lib/renderers/react/react.d.ts.map +1 -1
- package/lib/renderers/react/react.js +49 -32
- package/lib/renderers/react/react.js.map +1 -1
- package/lib/renderers/three/appearance/appearance.d.ts +41 -0
- package/lib/renderers/three/appearance/appearance.d.ts.map +1 -0
- package/lib/renderers/three/appearance/appearance.js +89 -0
- package/lib/renderers/three/appearance/appearance.js.map +1 -0
- package/lib/renderers/three/appearance/appearance.test.d.ts +2 -0
- package/lib/renderers/three/appearance/appearance.test.d.ts.map +1 -0
- package/lib/renderers/three/appearance/appearance.test.js +97 -0
- package/lib/renderers/three/appearance/appearance.test.js.map +1 -0
- package/lib/renderers/three/appearance.d.ts +41 -0
- package/lib/renderers/three/appearance.d.ts.map +1 -0
- package/lib/renderers/three/appearance.js +100 -0
- package/lib/renderers/three/appearance.js.map +1 -0
- package/lib/renderers/three/build/build.d.ts +51 -0
- package/lib/renderers/three/build/build.d.ts.map +1 -0
- package/lib/renderers/three/build/build.js +174 -0
- package/lib/renderers/three/build/build.js.map +1 -0
- package/lib/renderers/three/build/build.test.d.ts +2 -0
- package/lib/renderers/three/build/build.test.d.ts.map +1 -0
- package/lib/renderers/three/build/build.test.js +120 -0
- package/lib/renderers/three/build/build.test.js.map +1 -0
- package/lib/renderers/three/build/materials.d.ts +12 -0
- package/lib/renderers/three/build/materials.d.ts.map +1 -0
- package/lib/renderers/three/build/materials.js +55 -0
- package/lib/renderers/three/build/materials.js.map +1 -0
- package/lib/renderers/three/build/parts.d.ts +65 -0
- package/lib/renderers/three/build/parts.d.ts.map +1 -0
- package/lib/renderers/three/build/parts.js +203 -0
- package/lib/renderers/three/build/parts.js.map +1 -0
- package/lib/renderers/three/build.d.ts +50 -0
- package/lib/renderers/three/build.d.ts.map +1 -0
- package/lib/renderers/three/build.js +210 -0
- package/lib/renderers/three/build.js.map +1 -0
- package/lib/renderers/three/camera/camera.d.ts +40 -0
- package/lib/renderers/three/camera/camera.d.ts.map +1 -0
- package/lib/renderers/three/camera/camera.js +51 -0
- package/lib/renderers/three/camera/camera.js.map +1 -0
- package/lib/renderers/three/camera/camera.test.d.ts +2 -0
- package/lib/renderers/three/camera/camera.test.d.ts.map +1 -0
- package/lib/renderers/three/camera/camera.test.js +46 -0
- package/lib/renderers/three/camera/camera.test.js.map +1 -0
- package/lib/renderers/three/camera/controls.d.ts +24 -0
- package/lib/renderers/three/camera/controls.d.ts.map +1 -0
- package/lib/renderers/three/camera/controls.js +39 -0
- package/lib/renderers/three/camera/controls.js.map +1 -0
- package/lib/renderers/three/camera/gizmo.d.ts +44 -0
- package/lib/renderers/three/camera/gizmo.d.ts.map +1 -0
- package/lib/renderers/three/camera/gizmo.js +42 -0
- package/lib/renderers/three/camera/gizmo.js.map +1 -0
- package/lib/renderers/three/camera.d.ts +63 -0
- package/lib/renderers/three/camera.d.ts.map +1 -0
- package/lib/renderers/three/camera.js +85 -0
- package/lib/renderers/three/camera.js.map +1 -0
- package/lib/renderers/three/compile/compile.d.ts +59 -0
- package/lib/renderers/three/compile/compile.d.ts.map +1 -0
- package/lib/renderers/three/compile/compile.js +88 -0
- package/lib/renderers/three/compile/compile.js.map +1 -0
- package/lib/renderers/three/compile/compile.test.d.ts +2 -0
- package/lib/renderers/three/compile/compile.test.d.ts.map +1 -0
- package/lib/renderers/three/compile/compile.test.js +93 -0
- package/lib/renderers/three/compile/compile.test.js.map +1 -0
- package/lib/renderers/three/compile.d.ts +58 -0
- package/lib/renderers/three/compile.d.ts.map +1 -0
- package/lib/renderers/three/compile.js +89 -0
- package/lib/renderers/three/compile.js.map +1 -0
- package/lib/renderers/three/controls.d.ts +27 -0
- package/lib/renderers/three/controls.d.ts.map +1 -0
- package/lib/renderers/three/controls.js +115 -0
- package/lib/renderers/three/controls.js.map +1 -0
- package/lib/renderers/three/geometry/geometry.d.ts +21 -0
- package/lib/renderers/three/geometry/geometry.d.ts.map +1 -0
- package/lib/renderers/three/geometry/geometry.js +132 -0
- package/lib/renderers/three/geometry/geometry.js.map +1 -0
- package/lib/renderers/three/geometry/geometry.test.d.ts +2 -0
- package/lib/renderers/three/geometry/geometry.test.d.ts.map +1 -0
- package/lib/renderers/three/geometry/geometry.test.js +80 -0
- package/lib/renderers/three/geometry/geometry.test.js.map +1 -0
- package/lib/renderers/three/geometry.d.ts +20 -0
- package/lib/renderers/three/geometry.d.ts.map +1 -0
- package/lib/renderers/three/geometry.js +164 -0
- package/lib/renderers/three/geometry.js.map +1 -0
- package/lib/renderers/three/gizmo.d.ts +49 -0
- package/lib/renderers/three/gizmo.d.ts.map +1 -0
- package/lib/renderers/three/gizmo.js +172 -0
- package/lib/renderers/three/gizmo.js.map +1 -0
- package/lib/renderers/three/index.d.ts +16 -0
- package/lib/renderers/three/index.d.ts.map +1 -0
- package/lib/renderers/three/index.js +6 -0
- package/lib/renderers/three/index.js.map +1 -0
- package/lib/renderers/three/input.d.ts +25 -0
- package/lib/renderers/three/input.d.ts.map +1 -0
- package/lib/renderers/three/input.js +71 -0
- package/lib/renderers/three/input.js.map +1 -0
- package/lib/renderers/three/lines.d.ts +16 -0
- package/lib/renderers/three/lines.d.ts.map +1 -0
- package/lib/renderers/three/lines.js +63 -0
- package/lib/renderers/three/lines.js.map +1 -0
- package/lib/renderers/three/materials.d.ts +15 -0
- package/lib/renderers/three/materials.d.ts.map +1 -0
- package/lib/renderers/three/materials.js +70 -0
- package/lib/renderers/three/materials.js.map +1 -0
- package/lib/renderers/three/options.d.ts +68 -0
- package/lib/renderers/three/options.d.ts.map +1 -0
- package/lib/renderers/three/options.js +64 -0
- package/lib/renderers/three/options.js.map +1 -0
- package/lib/renderers/three/overlays.d.ts +25 -0
- package/lib/renderers/three/overlays.d.ts.map +1 -0
- package/lib/renderers/three/overlays.js +57 -0
- package/lib/renderers/three/overlays.js.map +1 -0
- package/lib/renderers/three/quality/quality.d.ts +37 -0
- package/lib/renderers/three/quality/quality.d.ts.map +1 -0
- package/lib/renderers/three/quality/quality.js +64 -0
- package/lib/renderers/three/quality/quality.js.map +1 -0
- package/lib/renderers/three/quality/quality.test.d.ts +2 -0
- package/lib/renderers/three/quality/quality.test.d.ts.map +1 -0
- package/lib/renderers/three/quality/quality.test.js +23 -0
- package/lib/renderers/three/quality/quality.test.js.map +1 -0
- package/lib/renderers/three/quality.d.ts +24 -0
- package/lib/renderers/three/quality.d.ts.map +1 -0
- package/lib/renderers/three/quality.js +67 -0
- package/lib/renderers/three/quality.js.map +1 -0
- package/lib/renderers/three/text/text.d.ts +55 -0
- package/lib/renderers/three/text/text.d.ts.map +1 -0
- package/lib/renderers/three/text/text.js +90 -0
- package/lib/renderers/three/text/text.js.map +1 -0
- package/lib/renderers/three/text/text.test.d.ts +2 -0
- package/lib/renderers/three/text/text.test.d.ts.map +1 -0
- package/lib/renderers/three/text/text.test.js +70 -0
- package/lib/renderers/three/text/text.test.js.map +1 -0
- package/lib/renderers/three/text.d.ts +53 -0
- package/lib/renderers/three/text.d.ts.map +1 -0
- package/lib/renderers/three/text.js +151 -0
- package/lib/renderers/three/text.js.map +1 -0
- package/lib/renderers/three/viewer/options.d.ts +71 -0
- package/lib/renderers/three/viewer/options.d.ts.map +1 -0
- package/lib/renderers/three/viewer/options.js +31 -0
- package/lib/renderers/three/viewer/options.js.map +1 -0
- package/lib/renderers/three/viewer/options.test.d.ts +2 -0
- package/lib/renderers/three/viewer/options.test.d.ts.map +1 -0
- package/lib/renderers/three/viewer/options.test.js +38 -0
- package/lib/renderers/three/viewer/options.test.js.map +1 -0
- package/lib/renderers/three/viewer/overlays.d.ts +31 -0
- package/lib/renderers/three/viewer/overlays.d.ts.map +1 -0
- package/lib/renderers/three/viewer/overlays.js +43 -0
- package/lib/renderers/three/viewer/overlays.js.map +1 -0
- package/lib/renderers/three/viewer/viewer.d.ts +90 -0
- package/lib/renderers/three/viewer/viewer.d.ts.map +1 -0
- package/lib/renderers/three/viewer/viewer.js +432 -0
- package/lib/renderers/three/viewer/viewer.js.map +1 -0
- package/lib/renderers/three/viewer.d.ts +38 -0
- package/lib/renderers/three/viewer.d.ts.map +1 -0
- package/lib/renderers/three/viewer.js +435 -0
- package/lib/renderers/three/viewer.js.map +1 -0
- package/package.json +26 -9
- package/src/abstract-3d.ts +1 -1
- package/src/custom_typings/n8ao.d.ts +11 -0
- package/src/renderers/dxf/dxf-encoding/dxf-build.ts +1 -2
- package/src/renderers/index.ts +1 -0
- package/src/renderers/react/index.ts +2 -5
- package/src/renderers/react/react.tsx +96 -181
- package/src/renderers/three/appearance/appearance.test.ts +116 -0
- package/src/renderers/three/appearance/appearance.ts +132 -0
- package/src/renderers/three/build/build.test.ts +141 -0
- package/src/renderers/three/build/build.ts +270 -0
- package/src/renderers/three/build/materials.ts +85 -0
- package/src/renderers/three/build/parts.ts +277 -0
- package/src/renderers/three/camera/camera.test.ts +53 -0
- package/src/renderers/three/camera/camera.ts +82 -0
- package/src/renderers/three/camera/controls.ts +65 -0
- package/src/renderers/three/camera/gizmo.ts +93 -0
- package/src/renderers/three/compile/compile.test.ts +113 -0
- package/src/renderers/three/compile/compile.ts +151 -0
- package/src/renderers/three/geometry/geometry.test.ts +95 -0
- package/src/renderers/three/geometry/geometry.ts +179 -0
- package/src/renderers/three/index.ts +15 -0
- package/src/renderers/three/quality/quality.test.ts +30 -0
- package/src/renderers/three/quality/quality.ts +95 -0
- package/src/renderers/three/text/text.test.ts +79 -0
- package/src/renderers/three/text/text.ts +128 -0
- package/src/renderers/three/viewer/options.ts +98 -0
- package/src/renderers/three/viewer/overlays.ts +71 -0
- package/src/renderers/three/viewer/viewer.ts +540 -0
- package/lib/renderers/dxf/color.d.ts +0 -7
- package/lib/renderers/dxf/color.d.ts.map +0 -1
- package/lib/renderers/dxf/color.js +0 -311
- package/lib/renderers/dxf/color.js.map +0 -1
- package/lib/renderers/dxf/dxf-encoding.d.ts +0 -17
- package/lib/renderers/dxf/dxf-encoding.d.ts.map +0 -1
- package/lib/renderers/dxf/dxf-encoding.js +0 -18467
- package/lib/renderers/dxf/dxf-encoding.js.map +0 -1
- package/lib/renderers/react/react-hotspot.d.ts +0 -27
- package/lib/renderers/react/react-hotspot.d.ts.map +0 -1
- package/lib/renderers/react/react-hotspot.js +0 -37
- package/lib/renderers/react/react-hotspot.js.map +0 -1
- package/lib/renderers/shared.d.ts +0 -30
- package/lib/renderers/shared.d.ts.map +0 -1
- package/lib/renderers/shared.js +0 -164
- package/lib/renderers/shared.js.map +0 -1
- package/src/custom_typings/react-three-fiber.d.ts +0 -9
- package/src/custom_typings/react-three-postprocessing.d.ts +0 -1
- package/src/renderers/react/react-camera.tsx +0 -391
- package/src/renderers/react/react-dimension.tsx +0 -122
- package/src/renderers/react/react-group.test.ts +0 -56
- package/src/renderers/react/react-group.tsx +0 -202
- package/src/renderers/react/react-image-material.tsx +0 -139
- package/src/renderers/react/react-material.tsx +0 -91
- package/src/renderers/react/react-mesh.tsx +0 -512
- package/src/renderers/react/react-relation.tsx +0 -86
- package/src/renderers/react/react-scene.tsx +0 -111
- package/src/renderers/react/react-types.ts +0 -9
|
@@ -1,512 +0,0 @@
|
|
|
1
|
-
import { Text, Line } from "@react-three/drei";
|
|
2
|
-
import { extend, useThree } from "@react-three/fiber";
|
|
3
|
-
import React, { useMemo } from "react";
|
|
4
|
-
import {
|
|
5
|
-
BoxGeometry,
|
|
6
|
-
BufferAttribute,
|
|
7
|
-
BufferGeometry,
|
|
8
|
-
CatmullRomCurve3,
|
|
9
|
-
Color,
|
|
10
|
-
ConeGeometry,
|
|
11
|
-
CylinderGeometry,
|
|
12
|
-
Euler,
|
|
13
|
-
ExtrudeGeometry,
|
|
14
|
-
Float32BufferAttribute,
|
|
15
|
-
FrontSide,
|
|
16
|
-
Path,
|
|
17
|
-
PlaneGeometry,
|
|
18
|
-
Quaternion,
|
|
19
|
-
Shape,
|
|
20
|
-
SphereGeometry,
|
|
21
|
-
TubeGeometry,
|
|
22
|
-
Vector2,
|
|
23
|
-
Vector3,
|
|
24
|
-
} from "three";
|
|
25
|
-
import type { Mesh, Box, Plane, Shape as Shape_1, Cylinder, Polygon as A3dPolygon, Tube as A3dTube } from "../../abstract-3d.js";
|
|
26
|
-
import { vec2Scale, isZero } from "../../abstract-3d.js";
|
|
27
|
-
import { addHoles, CircleCurve, CYLINDER_SEGMENTS, cylinderCutPositions, nonZeroHoles } from "../shared/three-geometry.js";
|
|
28
|
-
import { planeGeometry } from "./react-image-material.js";
|
|
29
|
-
|
|
30
|
-
extend({
|
|
31
|
-
SphereGeometry,
|
|
32
|
-
PlaneGeometry,
|
|
33
|
-
ConeGeometry,
|
|
34
|
-
Quaternion,
|
|
35
|
-
Vector3,
|
|
36
|
-
Euler,
|
|
37
|
-
BoxGeometry,
|
|
38
|
-
Path,
|
|
39
|
-
Shape,
|
|
40
|
-
TubeGeometry,
|
|
41
|
-
CatmullRomCurve3,
|
|
42
|
-
BufferAttribute,
|
|
43
|
-
ExtrudeGeometry,
|
|
44
|
-
CylinderGeometry,
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
const boxGeometry = new BoxGeometry();
|
|
48
|
-
const cylinderGeometries = new Map<string, BufferGeometry>();
|
|
49
|
-
const coneGeometry = new ConeGeometry(1, 1, 16, 1);
|
|
50
|
-
const sphereGeometry = new SphereGeometry(1, 12, 12);
|
|
51
|
-
export const euler = new Euler();
|
|
52
|
-
export const vector3 = new Vector3();
|
|
53
|
-
export const quaternion = new Quaternion();
|
|
54
|
-
|
|
55
|
-
export function ReactMesh({ mesh, children }: { readonly mesh: Mesh; readonly children?: React.JSX.Element }): React.JSX.Element {
|
|
56
|
-
const culledLineGeometry = useMemo(() => {
|
|
57
|
-
const g = new BufferGeometry();
|
|
58
|
-
|
|
59
|
-
g.setAttribute("position", new Float32BufferAttribute([0, -1, 0, 0, 1, 0, 1, -1, 0, 1, 1, 0], 3));
|
|
60
|
-
|
|
61
|
-
g.setIndex([0, 2, 1, 2, 3, 1]);
|
|
62
|
-
|
|
63
|
-
return g;
|
|
64
|
-
}, []);
|
|
65
|
-
const { camera, size } = useThree();
|
|
66
|
-
|
|
67
|
-
switch (mesh.geometry.type) {
|
|
68
|
-
case "Box": {
|
|
69
|
-
const { pos, size, rot, holes } = mesh.geometry;
|
|
70
|
-
return nonZeroHoles(holes).length === 0 ? (
|
|
71
|
-
<mesh
|
|
72
|
-
geometry={boxGeometry}
|
|
73
|
-
scale={[size.x, size.y, size.z]}
|
|
74
|
-
position={[pos.x, pos.y, pos.z]}
|
|
75
|
-
rotation={[rot?.x ?? 0, rot?.y ?? 0, rot?.z ?? 0]}
|
|
76
|
-
castShadow
|
|
77
|
-
receiveShadow
|
|
78
|
-
>
|
|
79
|
-
{children}
|
|
80
|
-
</mesh>
|
|
81
|
-
) : (
|
|
82
|
-
<ExcrudeBoxPlane geo={mesh.geometry} sizeZ={size.z}>
|
|
83
|
-
{children}
|
|
84
|
-
</ExcrudeBoxPlane>
|
|
85
|
-
);
|
|
86
|
-
}
|
|
87
|
-
case "Cone": {
|
|
88
|
-
const { pos, radius, rot, length } = mesh.geometry;
|
|
89
|
-
return (
|
|
90
|
-
<mesh
|
|
91
|
-
geometry={coneGeometry}
|
|
92
|
-
scale={[radius, length, radius]}
|
|
93
|
-
position={[pos.x, pos.y, pos.z]}
|
|
94
|
-
rotation={[rot?.x ?? 0, rot?.y ?? 0, rot?.z ?? 0]}
|
|
95
|
-
castShadow
|
|
96
|
-
receiveShadow
|
|
97
|
-
>
|
|
98
|
-
{children}
|
|
99
|
-
</mesh>
|
|
100
|
-
);
|
|
101
|
-
}
|
|
102
|
-
case "Cylinder": {
|
|
103
|
-
const { pos, radius, radiusEnd = radius, rot, length, holes, open, angleStart = 0, angleLength = Math.PI * 2 } = mesh.geometry;
|
|
104
|
-
const isWhole = isZero(Math.PI * 2 - angleLength);
|
|
105
|
-
// Holes are extruded along the length, which can't taper
|
|
106
|
-
if (isWhole && radiusEnd === radius && nonZeroHoles(holes).length > 0) {
|
|
107
|
-
return <ExcrudeCylinder cyl={mesh.geometry}>{children}</ExcrudeCylinder>;
|
|
108
|
-
}
|
|
109
|
-
// Unit geometry scaled by the largest radius, so only the radius ratio needs its own geometry
|
|
110
|
-
const maxRadius = Math.max(radius, radiusEnd);
|
|
111
|
-
const unitTop = radiusEnd / (maxRadius || 1);
|
|
112
|
-
const unitBottom = radius / (maxRadius || 1);
|
|
113
|
-
const transform = {
|
|
114
|
-
scale: [maxRadius, length, maxRadius],
|
|
115
|
-
position: [pos.x, pos.y, pos.z],
|
|
116
|
-
rotation: [rot?.x ?? 0, rot?.y ?? 0, rot?.z ?? 0],
|
|
117
|
-
} as const;
|
|
118
|
-
return isWhole ? (
|
|
119
|
-
<mesh geometry={getCylinderGeometry(unitTop, unitBottom, open ?? false, 0, Math.PI * 2)} {...transform} castShadow receiveShadow>
|
|
120
|
-
{children}
|
|
121
|
-
</mesh>
|
|
122
|
-
) : (
|
|
123
|
-
<mesh {...transform}>
|
|
124
|
-
<mesh geometry={getCylinderGeometry(unitTop, unitBottom, false, angleStart, angleLength)} castShadow receiveShadow>
|
|
125
|
-
{children}
|
|
126
|
-
</mesh>
|
|
127
|
-
<mesh geometry={getCylinderCutGeometry(unitTop, unitBottom, angleStart, angleLength)} castShadow receiveShadow>
|
|
128
|
-
{children}
|
|
129
|
-
</mesh>
|
|
130
|
-
</mesh>
|
|
131
|
-
);
|
|
132
|
-
}
|
|
133
|
-
case "Image":
|
|
134
|
-
return (
|
|
135
|
-
<React.Suspense fallback={null}>
|
|
136
|
-
<mesh
|
|
137
|
-
geometry={planeGeometry}
|
|
138
|
-
scale={[mesh.geometry.size.x, mesh.geometry.size.y, 1]}
|
|
139
|
-
position={[mesh.geometry.pos.x, mesh.geometry.pos.y, mesh.geometry.pos.z]}
|
|
140
|
-
rotation={[mesh.geometry.rot?.x ?? 0, mesh.geometry.rot?.y ?? 0, mesh.geometry.rot?.z ?? 0]}
|
|
141
|
-
castShadow
|
|
142
|
-
receiveShadow
|
|
143
|
-
>
|
|
144
|
-
{children}
|
|
145
|
-
</mesh>
|
|
146
|
-
</React.Suspense>
|
|
147
|
-
);
|
|
148
|
-
case "Plane": {
|
|
149
|
-
const { pos, size, rot, holes } = mesh.geometry;
|
|
150
|
-
return nonZeroHoles(holes).length === 0 ? (
|
|
151
|
-
<mesh
|
|
152
|
-
geometry={planeGeometry}
|
|
153
|
-
scale={[size.x, size.y, 1]}
|
|
154
|
-
position={[pos.x, pos.y, pos.z]}
|
|
155
|
-
rotation={[rot?.x ?? 0, rot?.y ?? 0, rot?.z ?? 0]}
|
|
156
|
-
castShadow
|
|
157
|
-
receiveShadow
|
|
158
|
-
>
|
|
159
|
-
{children}
|
|
160
|
-
</mesh>
|
|
161
|
-
) : (
|
|
162
|
-
<ExcrudeBoxPlane geo={mesh.geometry} sizeZ={0}>
|
|
163
|
-
{children}
|
|
164
|
-
</ExcrudeBoxPlane>
|
|
165
|
-
);
|
|
166
|
-
}
|
|
167
|
-
case "Sphere": {
|
|
168
|
-
const { pos, radius } = mesh.geometry;
|
|
169
|
-
return (
|
|
170
|
-
<mesh geometry={sphereGeometry} scale={radius} position={[pos.x, pos.y, pos.z]} castShadow receiveShadow>
|
|
171
|
-
{children}
|
|
172
|
-
</mesh>
|
|
173
|
-
);
|
|
174
|
-
}
|
|
175
|
-
case "Shape":
|
|
176
|
-
return <ExcrudeShape s={mesh.geometry}>{children}</ExcrudeShape>;
|
|
177
|
-
case "Text": {
|
|
178
|
-
const { pos, rot, text, fontSize } = mesh.geometry;
|
|
179
|
-
return (
|
|
180
|
-
<React.Suspense fallback={null}>
|
|
181
|
-
<Text
|
|
182
|
-
position={[pos.x, pos.y, pos.z]}
|
|
183
|
-
rotation={[rot?.x ?? 0, rot?.y ?? 0, rot?.z ?? 0]}
|
|
184
|
-
fontSize={fontSize}
|
|
185
|
-
textAlign="center"
|
|
186
|
-
letterSpacing={0.001}
|
|
187
|
-
lineHeight={1.5}
|
|
188
|
-
// outlineColor="rgb(255,255,255)"
|
|
189
|
-
// depthOffset={10}
|
|
190
|
-
// outlineWidth={3}
|
|
191
|
-
// outlineOpacity={1}
|
|
192
|
-
>
|
|
193
|
-
{children}
|
|
194
|
-
{text}
|
|
195
|
-
</Text>
|
|
196
|
-
</React.Suspense>
|
|
197
|
-
);
|
|
198
|
-
}
|
|
199
|
-
case "Line": {
|
|
200
|
-
const { start, end, thickness } = mesh.geometry;
|
|
201
|
-
return (
|
|
202
|
-
<Line
|
|
203
|
-
points={[
|
|
204
|
-
[start.x, start.y, start.z],
|
|
205
|
-
[end.x, end.y, end.z],
|
|
206
|
-
]}
|
|
207
|
-
lineWidth={thickness}
|
|
208
|
-
color={mesh.material.normal}
|
|
209
|
-
>
|
|
210
|
-
{children}
|
|
211
|
-
</Line>
|
|
212
|
-
);
|
|
213
|
-
}
|
|
214
|
-
case "CulledLine": {
|
|
215
|
-
const { start, end, normal, thickness } = mesh.geometry;
|
|
216
|
-
const color = mesh.material.normal;
|
|
217
|
-
|
|
218
|
-
return (
|
|
219
|
-
<mesh geometry={culledLineGeometry} frustumCulled={false}>
|
|
220
|
-
<shaderMaterial
|
|
221
|
-
side={FrontSide}
|
|
222
|
-
uniforms={{
|
|
223
|
-
lineStart: { value: new Vector3(start.x, start.y, start.z) },
|
|
224
|
-
lineEnd: { value: new Vector3(end.x, end.y, end.z) },
|
|
225
|
-
lineNormal: { value: new Vector3(normal.x, normal.y, normal.z) },
|
|
226
|
-
thickness: { value: thickness },
|
|
227
|
-
viewport: { value: new Vector2(size.width, size.height) },
|
|
228
|
-
nearPlane: { value: camera.near },
|
|
229
|
-
color: { value: new Color(color) },
|
|
230
|
-
}}
|
|
231
|
-
vertexShader={culledLineVertexShader}
|
|
232
|
-
fragmentShader={culledLineFragmentShader}
|
|
233
|
-
/>
|
|
234
|
-
</mesh>
|
|
235
|
-
);
|
|
236
|
-
}
|
|
237
|
-
case "Polygon":
|
|
238
|
-
return <Polygon polygon={mesh.geometry}>{children}</Polygon>;
|
|
239
|
-
case "Tube":
|
|
240
|
-
return <Tube tube={mesh.geometry}>{children}</Tube>;
|
|
241
|
-
default:
|
|
242
|
-
return <group />;
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
function ExcrudeBoxPlane({
|
|
247
|
-
geo,
|
|
248
|
-
sizeZ,
|
|
249
|
-
children,
|
|
250
|
-
}: {
|
|
251
|
-
readonly geo: Box | Plane;
|
|
252
|
-
readonly sizeZ: number;
|
|
253
|
-
readonly children?: React.JSX.Element;
|
|
254
|
-
}): React.JSX.Element {
|
|
255
|
-
const half = vec2Scale(geo.size, 0.5);
|
|
256
|
-
|
|
257
|
-
const excrudeGeometry = React.useMemo(() => {
|
|
258
|
-
const shape = new Shape();
|
|
259
|
-
shape.moveTo(-half.x, -half.y).lineTo(-half.x, half.y).lineTo(half.x, half.y).lineTo(half.x, -half.y).closePath();
|
|
260
|
-
addHoles(geo.holes, shape);
|
|
261
|
-
return new ExtrudeGeometry(shape, { depth: sizeZ, bevelEnabled: false });
|
|
262
|
-
}, [geo, half.x, half.y, sizeZ]);
|
|
263
|
-
|
|
264
|
-
return (
|
|
265
|
-
// Doesn't seem to adjust for excrude z size directly???
|
|
266
|
-
<mesh rotation={[geo.rot?.x ?? 0, geo.rot?.y ?? 0, geo.rot?.z ?? 0]} position={[geo.pos.x, geo.pos.y, geo.pos.z]}>
|
|
267
|
-
<mesh geometry={excrudeGeometry} position-z={-sizeZ / 2} castShadow receiveShadow>
|
|
268
|
-
{children}
|
|
269
|
-
</mesh>
|
|
270
|
-
</mesh>
|
|
271
|
-
);
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
function ExcrudeShape({ s, children }: { readonly s: Shape_1; readonly children?: React.JSX.Element }): React.JSX.Element {
|
|
275
|
-
const excrudeGeometry = React.useMemo(() => {
|
|
276
|
-
const shape = new Shape();
|
|
277
|
-
if (s.points.length > 0) {
|
|
278
|
-
const p = s.points[0]!;
|
|
279
|
-
shape.moveTo(p.x, p.y);
|
|
280
|
-
}
|
|
281
|
-
for (let i = 1; i < s.points.length; i++) {
|
|
282
|
-
const p = s.points[i]!;
|
|
283
|
-
shape.lineTo(p.x, p.y);
|
|
284
|
-
}
|
|
285
|
-
shape.closePath();
|
|
286
|
-
addHoles(s.holes, shape);
|
|
287
|
-
return new ExtrudeGeometry(shape, { depth: s.thickness, bevelEnabled: false });
|
|
288
|
-
}, [s]);
|
|
289
|
-
|
|
290
|
-
// Doesn't seem to adjust for excrude z size directly???
|
|
291
|
-
return (
|
|
292
|
-
<mesh rotation={[s.rot?.x ?? 0, s.rot?.y ?? 0, s.rot?.z ?? 0]} position={[s.pos.x, s.pos.y, s.pos.z]}>
|
|
293
|
-
<mesh geometry={excrudeGeometry} position-z={-s.thickness / 2} castShadow receiveShadow>
|
|
294
|
-
{children}
|
|
295
|
-
</mesh>
|
|
296
|
-
</mesh>
|
|
297
|
-
);
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
function cachedCylinderGeometry(key: string, create: () => BufferGeometry): BufferGeometry {
|
|
301
|
-
const cached = cylinderGeometries.get(key);
|
|
302
|
-
if (cached) {
|
|
303
|
-
return cached;
|
|
304
|
-
}
|
|
305
|
-
const geometry = create();
|
|
306
|
-
cylinderGeometries.set(key, geometry);
|
|
307
|
-
return geometry;
|
|
308
|
-
}
|
|
309
|
-
|
|
310
|
-
function getCylinderGeometry(top: number, bottom: number, open: boolean, angleStart: number, angleLength: number): BufferGeometry {
|
|
311
|
-
return cachedCylinderGeometry(
|
|
312
|
-
`cyl_${top}_${bottom}_${open}_${angleStart}_${angleLength}`,
|
|
313
|
-
() => new CylinderGeometry(top, bottom, 1, CYLINDER_SEGMENTS, 1, open, angleStart, angleLength)
|
|
314
|
-
);
|
|
315
|
-
}
|
|
316
|
-
|
|
317
|
-
/** The two walls closing an angled cylinder, from the axis out to the rim at angleStart and angleEnd */
|
|
318
|
-
function getCylinderCutGeometry(top: number, bottom: number, angleStart: number, angleLength: number): BufferGeometry {
|
|
319
|
-
return cachedCylinderGeometry(`cut_${top}_${bottom}_${angleStart}_${angleLength}`, () => {
|
|
320
|
-
const g = new BufferGeometry();
|
|
321
|
-
g.setAttribute("position", new Float32BufferAttribute(cylinderCutPositions(top, bottom, 1, angleStart, angleLength), 3));
|
|
322
|
-
g.computeVertexNormals();
|
|
323
|
-
return g;
|
|
324
|
-
});
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
function ExcrudeCylinder({ cyl, children }: { readonly cyl: Cylinder; readonly children?: React.JSX.Element }): React.JSX.Element {
|
|
328
|
-
const excrudeGeometry = React.useMemo(() => {
|
|
329
|
-
const shape = new Shape();
|
|
330
|
-
shape.moveTo(0, cyl.radius).absellipse(0, 0, cyl.radius, cyl.radius, 0, Math.PI * 2, true);
|
|
331
|
-
addHoles(cyl.holes, shape);
|
|
332
|
-
return new ExtrudeGeometry(shape, { depth: cyl.length, bevelEnabled: false });
|
|
333
|
-
}, [cyl]);
|
|
334
|
-
|
|
335
|
-
return (
|
|
336
|
-
// Doesn't seem to adjust for excrude z size directly???
|
|
337
|
-
<mesh rotation={[cyl.rot?.x ?? 0, cyl.rot?.y ?? 0, cyl.rot?.z ?? 0]} position={[cyl.pos.x, cyl.pos.y, cyl.pos.z]}>
|
|
338
|
-
<mesh geometry={excrudeGeometry} rotation-x={Math.PI / 2} position-y={cyl.length / 2} castShadow receiveShadow>
|
|
339
|
-
{children}
|
|
340
|
-
</mesh>
|
|
341
|
-
</mesh>
|
|
342
|
-
);
|
|
343
|
-
}
|
|
344
|
-
|
|
345
|
-
function Polygon({ polygon, children }: { readonly polygon: A3dPolygon; readonly children?: React.JSX.Element }): React.JSX.Element {
|
|
346
|
-
const vertices = React.useMemo(() => {
|
|
347
|
-
if (polygon.points.length === 4) {
|
|
348
|
-
const [v0, v1, v2, v3] = polygon.points;
|
|
349
|
-
return new Float32Array([
|
|
350
|
-
v0!.x,
|
|
351
|
-
v0!.y,
|
|
352
|
-
v0!.z,
|
|
353
|
-
v1!.x,
|
|
354
|
-
v1!.y,
|
|
355
|
-
v1!.z,
|
|
356
|
-
v2!.x,
|
|
357
|
-
v2!.y,
|
|
358
|
-
v2!.z,
|
|
359
|
-
v2!.x,
|
|
360
|
-
v2!.y,
|
|
361
|
-
v2!.z,
|
|
362
|
-
v3!.x,
|
|
363
|
-
v3!.y,
|
|
364
|
-
v3!.z,
|
|
365
|
-
v0!.x,
|
|
366
|
-
v0!.y,
|
|
367
|
-
v0!.z,
|
|
368
|
-
]);
|
|
369
|
-
}
|
|
370
|
-
|
|
371
|
-
const flattenedPoints: Array<number> = [];
|
|
372
|
-
for (const point of polygon.points) {
|
|
373
|
-
flattenedPoints.push(point.x, point.y, point.z);
|
|
374
|
-
}
|
|
375
|
-
const vertexCount = Math.floor(flattenedPoints.length / 3) * 3;
|
|
376
|
-
const vertices = new Float32Array(vertexCount);
|
|
377
|
-
for (let i = 0; i < vertexCount; i++) {
|
|
378
|
-
vertices[i] = flattenedPoints[i] ?? 0.0;
|
|
379
|
-
}
|
|
380
|
-
return vertices;
|
|
381
|
-
}, [polygon]);
|
|
382
|
-
|
|
383
|
-
return (
|
|
384
|
-
<mesh
|
|
385
|
-
rotation={[polygon.rot?.x ?? 0, polygon.rot?.y ?? 0, polygon.rot?.z ?? 0]}
|
|
386
|
-
position={[polygon.pos.x, polygon.pos.y, polygon.pos.z]}
|
|
387
|
-
castShadow
|
|
388
|
-
receiveShadow
|
|
389
|
-
>
|
|
390
|
-
<bufferGeometry key={vertices.join("")} attach="geometry" onUpdate={(self) => self.computeVertexNormals()}>
|
|
391
|
-
<bufferAttribute attach="attributes-position" needsUpdate={true} args={fakeArgs} array={vertices} count={vertices.length / 3} itemSize={3} />
|
|
392
|
-
</bufferGeometry>
|
|
393
|
-
{children}
|
|
394
|
-
</mesh>
|
|
395
|
-
);
|
|
396
|
-
}
|
|
397
|
-
|
|
398
|
-
const fakeArgs = [] as unknown as ConstructorParameters<typeof BufferAttribute>;
|
|
399
|
-
|
|
400
|
-
function Tube({ tube, children }: { readonly tube: A3dTube; readonly children?: React.JSX.Element }): React.JSX.Element {
|
|
401
|
-
const tubeGeometry = React.useMemo(() => {
|
|
402
|
-
return new TubeGeometry(
|
|
403
|
-
tube.curve.type === "SplineCurve"
|
|
404
|
-
? new CatmullRomCurve3(tube.curve.points.map((p) => new Vector3(p.x, p.y, p.z)))
|
|
405
|
-
: new CircleCurve(tube.curve),
|
|
406
|
-
9,
|
|
407
|
-
tube.radius,
|
|
408
|
-
9,
|
|
409
|
-
false
|
|
410
|
-
);
|
|
411
|
-
}, [tube]);
|
|
412
|
-
|
|
413
|
-
return (
|
|
414
|
-
<mesh
|
|
415
|
-
rotation={[tube.rot?.x ?? 0, tube.rot?.y ?? 0, tube.rot?.z ?? 0]}
|
|
416
|
-
position={[tube.pos.x, tube.pos.y, tube.pos.z]}
|
|
417
|
-
geometry={tubeGeometry}
|
|
418
|
-
castShadow
|
|
419
|
-
receiveShadow
|
|
420
|
-
>
|
|
421
|
-
{children}
|
|
422
|
-
</mesh>
|
|
423
|
-
);
|
|
424
|
-
}
|
|
425
|
-
|
|
426
|
-
const culledLineVertexShader = `
|
|
427
|
-
uniform vec3 lineStart;
|
|
428
|
-
uniform vec3 lineEnd;
|
|
429
|
-
uniform vec3 lineNormal;
|
|
430
|
-
|
|
431
|
-
uniform float thickness;
|
|
432
|
-
uniform float nearPlane;
|
|
433
|
-
uniform vec2 viewport;
|
|
434
|
-
|
|
435
|
-
void main() {
|
|
436
|
-
vec3 a = (modelViewMatrix * vec4(lineStart, 1.0)).xyz;
|
|
437
|
-
vec3 b = (modelViewMatrix * vec4(lineEnd, 1.0)).xyz;
|
|
438
|
-
|
|
439
|
-
vec3 n = normalize(mat3(modelViewMatrix) * lineNormal);
|
|
440
|
-
|
|
441
|
-
// camera is at (0,0,0) in view space.
|
|
442
|
-
vec3 mid = (a + b) * 0.5;
|
|
443
|
-
vec3 toCamera = normalize(-mid);
|
|
444
|
-
|
|
445
|
-
bool frontFacing = dot(n, toCamera) > 0.0;
|
|
446
|
-
|
|
447
|
-
if(!frontFacing) {
|
|
448
|
-
// collapse all 4 vertices to one point.
|
|
449
|
-
gl_Position = vec4(0.0);
|
|
450
|
-
return;
|
|
451
|
-
}
|
|
452
|
-
|
|
453
|
-
// ---- near-plane clipping ----
|
|
454
|
-
|
|
455
|
-
float nearZ = -nearPlane;
|
|
456
|
-
|
|
457
|
-
bool aBehind = a.z > nearZ;
|
|
458
|
-
bool bBehind = b.z > nearZ;
|
|
459
|
-
|
|
460
|
-
if(aBehind && bBehind) {
|
|
461
|
-
gl_Position = vec4(0.0);
|
|
462
|
-
return;
|
|
463
|
-
}
|
|
464
|
-
|
|
465
|
-
if(aBehind) {
|
|
466
|
-
float t = (nearZ - a.z) / (b.z - a.z);
|
|
467
|
-
a = mix(a, b, t);
|
|
468
|
-
}
|
|
469
|
-
|
|
470
|
-
if(bBehind) {
|
|
471
|
-
float t = (nearZ - b.z) / (a.z - b.z);
|
|
472
|
-
b = mix(b, a, t);
|
|
473
|
-
}
|
|
474
|
-
|
|
475
|
-
vec4 ca = projectionMatrix * vec4(a, 1.0);
|
|
476
|
-
vec4 cb = projectionMatrix * vec4(b, 1.0);
|
|
477
|
-
|
|
478
|
-
vec2 aNdc = ca.xy / ca.w;
|
|
479
|
-
vec2 bNdc = cb.xy / cb.w;
|
|
480
|
-
|
|
481
|
-
vec2 aPx = aNdc * viewport * 0.5;
|
|
482
|
-
vec2 bPx = bNdc * viewport * 0.5;
|
|
483
|
-
|
|
484
|
-
vec2 delta = bPx - aPx;
|
|
485
|
-
float len = length(delta);
|
|
486
|
-
|
|
487
|
-
if(len < 0.0001) {
|
|
488
|
-
gl_Position = vec4(0.0);
|
|
489
|
-
return;
|
|
490
|
-
}
|
|
491
|
-
|
|
492
|
-
vec2 dir = delta / len;
|
|
493
|
-
vec2 perp = vec2(-dir.y, dir.x);
|
|
494
|
-
|
|
495
|
-
float endpoint = position.x;
|
|
496
|
-
float side = position.y;
|
|
497
|
-
|
|
498
|
-
vec4 clip = mix(ca, cb, endpoint);
|
|
499
|
-
|
|
500
|
-
vec2 offsetNdc = perp * side * (thickness * 0.5) * (2.0 / viewport);
|
|
501
|
-
clip.xy += offsetNdc * clip.w;
|
|
502
|
-
gl_Position = clip;
|
|
503
|
-
}
|
|
504
|
-
`;
|
|
505
|
-
|
|
506
|
-
const culledLineFragmentShader = `
|
|
507
|
-
uniform vec3 color;
|
|
508
|
-
|
|
509
|
-
void main() {
|
|
510
|
-
gl_FragColor = vec4(color, 1.0);
|
|
511
|
-
}
|
|
512
|
-
`;
|
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
import type { ThreeEvent } from "@react-three/fiber";
|
|
2
|
-
import React from "react";
|
|
3
|
-
import type { Group, Relation } from "../../abstract-3d.js";
|
|
4
|
-
import { vec3Scale } from "../../abstract-3d.js";
|
|
5
|
-
import { ReactMaterial } from "./react-material.js";
|
|
6
|
-
import { ReactMesh } from "./react-mesh.js";
|
|
7
|
-
|
|
8
|
-
const outlineMat = { normal: "rgb(0, 0, 0)", opacity: 1.0 };
|
|
9
|
-
|
|
10
|
-
/** The shape of each active relation, e.g. where a component can be inserted on an air relation, clickable and darker when hovered */
|
|
11
|
-
export const ReactRelations = React.memo(
|
|
12
|
-
({
|
|
13
|
-
relations,
|
|
14
|
-
activeRelations,
|
|
15
|
-
onClickRelation,
|
|
16
|
-
}: {
|
|
17
|
-
readonly relations: ReadonlyArray<Relation> | undefined;
|
|
18
|
-
readonly activeRelations: ReadonlyArray<string> | undefined;
|
|
19
|
-
readonly onClickRelation?: (relation: Relation, e: ThreeEvent<MouseEvent>) => void;
|
|
20
|
-
}): React.JSX.Element => (
|
|
21
|
-
<>
|
|
22
|
-
{relations
|
|
23
|
-
?.filter((r) => activeRelations?.includes(r.id))
|
|
24
|
-
.map((r) => (
|
|
25
|
-
<ReactRelation key={r.id} relation={r} onClickRelation={onClickRelation} />
|
|
26
|
-
))}
|
|
27
|
-
</>
|
|
28
|
-
)
|
|
29
|
-
);
|
|
30
|
-
|
|
31
|
-
function ReactRelation({
|
|
32
|
-
relation,
|
|
33
|
-
onClickRelation,
|
|
34
|
-
}: {
|
|
35
|
-
readonly relation: Relation;
|
|
36
|
-
readonly onClickRelation?: (relation: Relation, e: ThreeEvent<MouseEvent>) => void;
|
|
37
|
-
}): React.JSX.Element {
|
|
38
|
-
const [hovered, setHovered] = React.useState<boolean>(false);
|
|
39
|
-
return (
|
|
40
|
-
<group
|
|
41
|
-
onClick={(e) => {
|
|
42
|
-
if (onClickRelation) {
|
|
43
|
-
e.stopPropagation();
|
|
44
|
-
onClickRelation(relation, e);
|
|
45
|
-
}
|
|
46
|
-
}}
|
|
47
|
-
onPointerOver={(e) => {
|
|
48
|
-
e.stopPropagation();
|
|
49
|
-
document.body.style.cursor = "pointer";
|
|
50
|
-
setHovered(true);
|
|
51
|
-
}}
|
|
52
|
-
onPointerOut={() => {
|
|
53
|
-
document.body.style.cursor = "auto";
|
|
54
|
-
setHovered(false);
|
|
55
|
-
}}
|
|
56
|
-
onContextMenu={(e) => e.stopPropagation()}
|
|
57
|
-
>
|
|
58
|
-
{relation.groups?.map((g, i) => (
|
|
59
|
-
<ReactRelationGroup key={i} g={g} hovered={hovered} />
|
|
60
|
-
))}
|
|
61
|
-
</group>
|
|
62
|
-
);
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
/** A group of a relation's shape, unlit, with a black outline around its boxes */
|
|
66
|
-
function ReactRelationGroup({ g, hovered }: { readonly g: Group; readonly hovered: boolean }): React.JSX.Element {
|
|
67
|
-
return (
|
|
68
|
-
<group position={[g.pos.x, g.pos.y, g.pos.z]} rotation={[g.rot?.x ?? 0, g.rot?.y ?? 0, g.rot?.z ?? 0]}>
|
|
69
|
-
{g.meshes?.map((m, i) => (
|
|
70
|
-
<React.Fragment key={i}>
|
|
71
|
-
<ReactMesh mesh={m}>
|
|
72
|
-
<ReactMaterial isText={false} isRelation={true} material={m.material} hovered={hovered} />
|
|
73
|
-
</ReactMesh>
|
|
74
|
-
{m.geometry.type === "Box" && (
|
|
75
|
-
<ReactMesh mesh={{ ...m, geometry: { ...m.geometry, size: vec3Scale(m.geometry.size, 1.0125) } }}>
|
|
76
|
-
<ReactMaterial isText={false} isRelation={true} drawBackOnly={true} material={outlineMat} hovered={hovered} />
|
|
77
|
-
</ReactMesh>
|
|
78
|
-
)}
|
|
79
|
-
</React.Fragment>
|
|
80
|
-
))}
|
|
81
|
-
{g.groups?.map((c, i) => (
|
|
82
|
-
<ReactRelationGroup key={i} g={c} hovered={hovered} />
|
|
83
|
-
))}
|
|
84
|
-
</group>
|
|
85
|
-
);
|
|
86
|
-
}
|
|
@@ -1,111 +0,0 @@
|
|
|
1
|
-
import { Html } from "@react-three/drei";
|
|
2
|
-
import type { ThreeEvent } from "@react-three/fiber";
|
|
3
|
-
import React from "react";
|
|
4
|
-
import type { Scene, Group, Relation } from "../../abstract-3d.js";
|
|
5
|
-
import { ReactDimensions } from "./react-dimension.js";
|
|
6
|
-
import { ReactGroup } from "./react-group.js";
|
|
7
|
-
import type { MaterialState } from "./react-material.js";
|
|
8
|
-
import { ReactRelations } from "./react-relation.js";
|
|
9
|
-
import type { ReactPopover } from "./react-types.js";
|
|
10
|
-
|
|
11
|
-
export type SceneMouseEvent = ThreeEvent<MouseEvent>;
|
|
12
|
-
|
|
13
|
-
export function ReactScene({
|
|
14
|
-
scene,
|
|
15
|
-
selectedIds,
|
|
16
|
-
hoveredIdsExternal,
|
|
17
|
-
activeRelations,
|
|
18
|
-
activeComponents,
|
|
19
|
-
showDimensions,
|
|
20
|
-
useAlphaTest,
|
|
21
|
-
materialStateImages,
|
|
22
|
-
reactPopovers,
|
|
23
|
-
onClickGroup,
|
|
24
|
-
onHoverGroup,
|
|
25
|
-
onContextMenuGroup,
|
|
26
|
-
getTooltips,
|
|
27
|
-
onClickRelation,
|
|
28
|
-
createGroupKey,
|
|
29
|
-
createGroupId,
|
|
30
|
-
}: {
|
|
31
|
-
readonly scene: Scene;
|
|
32
|
-
readonly selectedIds: Record<string, boolean> | undefined;
|
|
33
|
-
readonly hoveredIdsExternal: ReadonlyArray<string> | undefined;
|
|
34
|
-
readonly activeRelations: ReadonlyArray<string> | undefined;
|
|
35
|
-
readonly activeComponents: Record<string, MaterialState> | undefined;
|
|
36
|
-
readonly showDimensions: boolean;
|
|
37
|
-
readonly useAlphaTest?: boolean;
|
|
38
|
-
readonly materialStateImages?: Record<string, string>;
|
|
39
|
-
readonly reactPopovers?: ReadonlyArray<ReactPopover>;
|
|
40
|
-
readonly onClickGroup?: (
|
|
41
|
-
id: string | undefined,
|
|
42
|
-
rootData: Record<string, string> | undefined,
|
|
43
|
-
data: Record<string, string> | undefined,
|
|
44
|
-
e: SceneMouseEvent
|
|
45
|
-
) => void;
|
|
46
|
-
readonly onHoverGroup?: (
|
|
47
|
-
id: string | undefined,
|
|
48
|
-
rootData: Record<string, string> | undefined,
|
|
49
|
-
data: Record<string, string> | undefined,
|
|
50
|
-
e: SceneMouseEvent
|
|
51
|
-
) => void;
|
|
52
|
-
readonly onContextMenuGroup?: (
|
|
53
|
-
id: string,
|
|
54
|
-
rootData: Record<string, string> | undefined,
|
|
55
|
-
data: Record<string, string> | undefined,
|
|
56
|
-
left: number,
|
|
57
|
-
top: number,
|
|
58
|
-
e: SceneMouseEvent
|
|
59
|
-
) => void;
|
|
60
|
-
readonly getTooltips?: (id: string) => ReadonlyArray<ReactPopover>;
|
|
61
|
-
readonly onClickRelation?: (relation: Relation, e: SceneMouseEvent) => void;
|
|
62
|
-
readonly createGroupKey?: (g: Group, idx: number, rootData: Record<string, string> | undefined, id: string) => string;
|
|
63
|
-
readonly createGroupId?: (g: Group) => string;
|
|
64
|
-
}): React.JSX.Element {
|
|
65
|
-
return (
|
|
66
|
-
<group
|
|
67
|
-
rotation={[scene.rotation_deprecated?.x ?? 0, scene.rotation_deprecated?.y ?? 0, scene.rotation_deprecated?.z ?? 0]}
|
|
68
|
-
position={[-(scene.center_deprecated?.x ?? 0), -(scene.center_deprecated?.y ?? 0), -(scene.center_deprecated?.z ?? 0)]}
|
|
69
|
-
>
|
|
70
|
-
{scene.groups.map((g, i) => {
|
|
71
|
-
const id = createGroupId ? createGroupId(g) : "";
|
|
72
|
-
return (
|
|
73
|
-
<ReactGroup
|
|
74
|
-
key={createGroupKey ? createGroupKey(g, 0, g.data, id) : i}
|
|
75
|
-
g={g}
|
|
76
|
-
selectedIds={selectedIds}
|
|
77
|
-
relationsActive={activeRelations !== undefined}
|
|
78
|
-
activeComponents={activeComponents}
|
|
79
|
-
materialStateImages={materialStateImages}
|
|
80
|
-
hoveredIdsExternal={hoveredIdsExternal}
|
|
81
|
-
onClickGroup={onClickGroup}
|
|
82
|
-
onHoverGroup={onHoverGroup}
|
|
83
|
-
onContextMenuGroup={onContextMenuGroup}
|
|
84
|
-
getTooltips={getTooltips}
|
|
85
|
-
createGroupKey={createGroupKey}
|
|
86
|
-
id={id}
|
|
87
|
-
useAlphaTest={useAlphaTest}
|
|
88
|
-
rootData={g.data}
|
|
89
|
-
/>
|
|
90
|
-
);
|
|
91
|
-
})}
|
|
92
|
-
<ReactDimensions
|
|
93
|
-
dimensions={scene.dimensions_deprecated}
|
|
94
|
-
showDimensions={showDimensions}
|
|
95
|
-
sceneRotation={scene.rotation_deprecated}
|
|
96
|
-
sceneCenter={scene.center_deprecated}
|
|
97
|
-
selectedIds={selectedIds}
|
|
98
|
-
relationsActive={activeRelations !== undefined}
|
|
99
|
-
onClickGroup={onClickGroup}
|
|
100
|
-
onHoverGroup={onHoverGroup}
|
|
101
|
-
onContextMenuGroup={onContextMenuGroup}
|
|
102
|
-
/>
|
|
103
|
-
<ReactRelations relations={scene.relations} activeRelations={activeRelations} onClickRelation={onClickRelation} />
|
|
104
|
-
{reactPopovers?.map((p) => (
|
|
105
|
-
<Html key={p.id} position={[p.pos.x, p.pos.y, p.pos.z]} center pointerEvents="none" style={{ pointerEvents: "none" }}>
|
|
106
|
-
{p.content}
|
|
107
|
-
</Html>
|
|
108
|
-
))}
|
|
109
|
-
</group>
|
|
110
|
-
);
|
|
111
|
-
}
|