abstract-3d 0.1.2
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/CHANGELOG.md +7 -0
- package/LICENSE +21 -0
- package/README.md +7 -0
- package/lib/abstract-3d.d.ts +317 -0
- package/lib/abstract-3d.d.ts.map +1 -0
- package/lib/abstract-3d.js +333 -0
- package/lib/abstract-3d.js.map +1 -0
- package/lib/index.d.ts +3 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +19 -0
- package/lib/index.js.map +1 -0
- package/lib/renderers/dxf/dxf-encoding.d.ts +7 -0
- package/lib/renderers/dxf/dxf-encoding.d.ts.map +1 -0
- package/lib/renderers/dxf/dxf-encoding.js +343 -0
- package/lib/renderers/dxf/dxf-encoding.js.map +1 -0
- package/lib/renderers/dxf/dxf-geometries/dxf-box.d.ts +3 -0
- package/lib/renderers/dxf/dxf-geometries/dxf-box.d.ts.map +1 -0
- package/lib/renderers/dxf/dxf-geometries/dxf-box.js +52 -0
- package/lib/renderers/dxf/dxf-geometries/dxf-box.js.map +1 -0
- package/lib/renderers/dxf/dxf-geometries/dxf-cone.d.ts +3 -0
- package/lib/renderers/dxf/dxf-geometries/dxf-cone.d.ts.map +1 -0
- package/lib/renderers/dxf/dxf-geometries/dxf-cone.js +54 -0
- package/lib/renderers/dxf/dxf-geometries/dxf-cone.js.map +1 -0
- package/lib/renderers/dxf/dxf-geometries/dxf-cylinder.d.ts +3 -0
- package/lib/renderers/dxf/dxf-geometries/dxf-cylinder.d.ts.map +1 -0
- package/lib/renderers/dxf/dxf-geometries/dxf-cylinder.js +62 -0
- package/lib/renderers/dxf/dxf-geometries/dxf-cylinder.js.map +1 -0
- package/lib/renderers/dxf/dxf-geometries/dxf-plane.d.ts +3 -0
- package/lib/renderers/dxf/dxf-geometries/dxf-plane.d.ts.map +1 -0
- package/lib/renderers/dxf/dxf-geometries/dxf-plane.js +38 -0
- package/lib/renderers/dxf/dxf-geometries/dxf-plane.js.map +1 -0
- package/lib/renderers/dxf/dxf-geometries/dxf-polygon.d.ts +3 -0
- package/lib/renderers/dxf/dxf-geometries/dxf-polygon.d.ts.map +1 -0
- package/lib/renderers/dxf/dxf-geometries/dxf-polygon.js +61 -0
- package/lib/renderers/dxf/dxf-geometries/dxf-polygon.js.map +1 -0
- package/lib/renderers/dxf/dxf-geometries/dxf-shape.d.ts +3 -0
- package/lib/renderers/dxf/dxf-geometries/dxf-shape.d.ts.map +1 -0
- package/lib/renderers/dxf/dxf-geometries/dxf-shape.js +61 -0
- package/lib/renderers/dxf/dxf-geometries/dxf-shape.js.map +1 -0
- package/lib/renderers/dxf/dxf.d.ts +3 -0
- package/lib/renderers/dxf/dxf.d.ts.map +1 -0
- package/lib/renderers/dxf/dxf.js +64 -0
- package/lib/renderers/dxf/dxf.js.map +1 -0
- package/lib/renderers/dxf/index.d.ts +2 -0
- package/lib/renderers/dxf/index.d.ts.map +1 -0
- package/lib/renderers/dxf/index.js +18 -0
- package/lib/renderers/dxf/index.js.map +1 -0
- package/lib/renderers/index.d.ts +5 -0
- package/lib/renderers/index.d.ts.map +1 -0
- package/lib/renderers/index.js +21 -0
- package/lib/renderers/index.js.map +1 -0
- package/lib/renderers/react/index.d.ts +6 -0
- package/lib/renderers/react/index.d.ts.map +1 -0
- package/lib/renderers/react/index.js +21 -0
- package/lib/renderers/react/index.js.map +1 -0
- package/lib/renderers/react/react-camera.d.ts +60 -0
- package/lib/renderers/react/react-camera.d.ts.map +1 -0
- package/lib/renderers/react/react-camera.js +132 -0
- package/lib/renderers/react/react-camera.js.map +1 -0
- package/lib/renderers/react/react-dimension.d.ts +12 -0
- package/lib/renderers/react/react-dimension.d.ts.map +1 -0
- package/lib/renderers/react/react-dimension.js +39 -0
- package/lib/renderers/react/react-dimension.js.map +1 -0
- package/lib/renderers/react/react-group.d.ts +18 -0
- package/lib/renderers/react/react-group.d.ts.map +1 -0
- package/lib/renderers/react/react-group.js +62 -0
- package/lib/renderers/react/react-group.js.map +1 -0
- package/lib/renderers/react/react-hotspot.d.ts +30 -0
- package/lib/renderers/react/react-hotspot.d.ts.map +1 -0
- package/lib/renderers/react/react-hotspot.js +71 -0
- package/lib/renderers/react/react-hotspot.js.map +1 -0
- package/lib/renderers/react/react-material.d.ts +13 -0
- package/lib/renderers/react/react-material.d.ts.map +1 -0
- package/lib/renderers/react/react-material.js +85 -0
- package/lib/renderers/react/react-material.js.map +1 -0
- package/lib/renderers/react/react-mesh.d.ts +10 -0
- package/lib/renderers/react/react-mesh.d.ts.map +1 -0
- package/lib/renderers/react/react-mesh.js +238 -0
- package/lib/renderers/react/react-mesh.js.map +1 -0
- package/lib/renderers/react/react-scene.d.ts +20 -0
- package/lib/renderers/react/react-scene.d.ts.map +1 -0
- package/lib/renderers/react/react-scene.js +44 -0
- package/lib/renderers/react/react-scene.js.map +1 -0
- package/lib/renderers/react/react.d.ts +30 -0
- package/lib/renderers/react/react.d.ts.map +1 -0
- package/lib/renderers/react/react.js +48 -0
- package/lib/renderers/react/react.js.map +1 -0
- package/lib/renderers/shared.d.ts +6 -0
- package/lib/renderers/shared.d.ts.map +1 -0
- package/lib/renderers/shared.js +93 -0
- package/lib/renderers/shared.js.map +1 -0
- package/lib/renderers/stl/index.d.ts +2 -0
- package/lib/renderers/stl/index.d.ts.map +1 -0
- package/lib/renderers/stl/index.js +18 -0
- package/lib/renderers/stl/index.js.map +1 -0
- package/lib/renderers/stl/stl-encoding.d.ts +4 -0
- package/lib/renderers/stl/stl-encoding.d.ts.map +1 -0
- package/lib/renderers/stl/stl-encoding.js +26 -0
- package/lib/renderers/stl/stl-encoding.js.map +1 -0
- package/lib/renderers/stl/stl-geometries/stl-box.d.ts +3 -0
- package/lib/renderers/stl/stl-geometries/stl-box.d.ts.map +1 -0
- package/lib/renderers/stl/stl-geometries/stl-box.js +57 -0
- package/lib/renderers/stl/stl-geometries/stl-box.js.map +1 -0
- package/lib/renderers/stl/stl-geometries/stl-cone.d.ts +3 -0
- package/lib/renderers/stl/stl-geometries/stl-cone.d.ts.map +1 -0
- package/lib/renderers/stl/stl-geometries/stl-cone.js +54 -0
- package/lib/renderers/stl/stl-geometries/stl-cone.js.map +1 -0
- package/lib/renderers/stl/stl-geometries/stl-cylinder.d.ts +3 -0
- package/lib/renderers/stl/stl-geometries/stl-cylinder.d.ts.map +1 -0
- package/lib/renderers/stl/stl-geometries/stl-cylinder.js +62 -0
- package/lib/renderers/stl/stl-geometries/stl-cylinder.js.map +1 -0
- package/lib/renderers/stl/stl-geometries/stl-plane.d.ts +3 -0
- package/lib/renderers/stl/stl-geometries/stl-plane.d.ts.map +1 -0
- package/lib/renderers/stl/stl-geometries/stl-plane.js +44 -0
- package/lib/renderers/stl/stl-geometries/stl-plane.js.map +1 -0
- package/lib/renderers/stl/stl-geometries/stl-polygon.d.ts +3 -0
- package/lib/renderers/stl/stl-geometries/stl-polygon.d.ts.map +1 -0
- package/lib/renderers/stl/stl-geometries/stl-polygon.js +59 -0
- package/lib/renderers/stl/stl-geometries/stl-polygon.js.map +1 -0
- package/lib/renderers/stl/stl-geometries/stl-shape.d.ts +3 -0
- package/lib/renderers/stl/stl-geometries/stl-shape.d.ts.map +1 -0
- package/lib/renderers/stl/stl-geometries/stl-shape.js +59 -0
- package/lib/renderers/stl/stl-geometries/stl-shape.js.map +1 -0
- package/lib/renderers/stl/stl.d.ts +3 -0
- package/lib/renderers/stl/stl.d.ts.map +1 -0
- package/lib/renderers/stl/stl.js +57 -0
- package/lib/renderers/stl/stl.js.map +1 -0
- package/lib/renderers/svg/index.d.ts +3 -0
- package/lib/renderers/svg/index.d.ts.map +1 -0
- package/lib/renderers/svg/index.js +18 -0
- package/lib/renderers/svg/index.js.map +1 -0
- package/lib/renderers/svg/svg-encoding.d.ts +14 -0
- package/lib/renderers/svg/svg-encoding.d.ts.map +1 -0
- package/lib/renderers/svg/svg-encoding.js +27 -0
- package/lib/renderers/svg/svg-encoding.js.map +1 -0
- package/lib/renderers/svg/svg-geometries/shared.d.ts +12 -0
- package/lib/renderers/svg/svg-geometries/shared.d.ts.map +1 -0
- package/lib/renderers/svg/svg-geometries/shared.js +12 -0
- package/lib/renderers/svg/svg-geometries/shared.js.map +1 -0
- package/lib/renderers/svg/svg-geometries/svg-box.d.ts +4 -0
- package/lib/renderers/svg/svg-geometries/svg-box.d.ts.map +1 -0
- package/lib/renderers/svg/svg-geometries/svg-box.js +70 -0
- package/lib/renderers/svg/svg-geometries/svg-box.js.map +1 -0
- package/lib/renderers/svg/svg-geometries/svg-cone.d.ts +4 -0
- package/lib/renderers/svg/svg-geometries/svg-cone.d.ts.map +1 -0
- package/lib/renderers/svg/svg-geometries/svg-cone.js +64 -0
- package/lib/renderers/svg/svg-geometries/svg-cone.js.map +1 -0
- package/lib/renderers/svg/svg-geometries/svg-cylinder.d.ts +4 -0
- package/lib/renderers/svg/svg-geometries/svg-cylinder.d.ts.map +1 -0
- package/lib/renderers/svg/svg-geometries/svg-cylinder.js +69 -0
- package/lib/renderers/svg/svg-geometries/svg-cylinder.js.map +1 -0
- package/lib/renderers/svg/svg-geometries/svg-line.d.ts +4 -0
- package/lib/renderers/svg/svg-geometries/svg-line.d.ts.map +1 -0
- package/lib/renderers/svg/svg-geometries/svg-line.js +39 -0
- package/lib/renderers/svg/svg-geometries/svg-line.js.map +1 -0
- package/lib/renderers/svg/svg-geometries/svg-plane.d.ts +5 -0
- package/lib/renderers/svg/svg-geometries/svg-plane.d.ts.map +1 -0
- package/lib/renderers/svg/svg-geometries/svg-plane.js +57 -0
- package/lib/renderers/svg/svg-geometries/svg-plane.js.map +1 -0
- package/lib/renderers/svg/svg-geometries/svg-polygon.d.ts +4 -0
- package/lib/renderers/svg/svg-geometries/svg-polygon.d.ts.map +1 -0
- package/lib/renderers/svg/svg-geometries/svg-polygon.js +20 -0
- package/lib/renderers/svg/svg-geometries/svg-polygon.js.map +1 -0
- package/lib/renderers/svg/svg-geometries/svg-shape.d.ts +4 -0
- package/lib/renderers/svg/svg-geometries/svg-shape.d.ts.map +1 -0
- package/lib/renderers/svg/svg-geometries/svg-shape.js +20 -0
- package/lib/renderers/svg/svg-geometries/svg-shape.js.map +1 -0
- package/lib/renderers/svg/svg-geometries/svg-text.d.ts +4 -0
- package/lib/renderers/svg/svg-geometries/svg-text.d.ts.map +1 -0
- package/lib/renderers/svg/svg-geometries/svg-text.js +46 -0
- package/lib/renderers/svg/svg-geometries/svg-text.js.map +1 -0
- package/lib/renderers/svg/svg.d.ts +10 -0
- package/lib/renderers/svg/svg.d.ts.map +1 -0
- package/lib/renderers/svg/svg.js +98 -0
- package/lib/renderers/svg/svg.js.map +1 -0
- package/package.json +31 -0
- package/src/abstract-3d.ts +578 -0
- package/src/index.ts +2 -0
- package/src/renderers/dxf/dxf-encoding.ts +348 -0
- package/src/renderers/dxf/dxf-geometries/dxf-box.ts +27 -0
- package/src/renderers/dxf/dxf-geometries/dxf-cone.ts +31 -0
- package/src/renderers/dxf/dxf-geometries/dxf-cylinder.ts +45 -0
- package/src/renderers/dxf/dxf-geometries/dxf-plane.ts +16 -0
- package/src/renderers/dxf/dxf-geometries/dxf-polygon.ts +36 -0
- package/src/renderers/dxf/dxf-geometries/dxf-shape.ts +36 -0
- package/src/renderers/dxf/dxf.ts +38 -0
- package/src/renderers/dxf/index.ts +1 -0
- package/src/renderers/index.ts +4 -0
- package/src/renderers/react/index.ts +5 -0
- package/src/renderers/react/react-camera.tsx +208 -0
- package/src/renderers/react/react-dimension.tsx +76 -0
- package/src/renderers/react/react-group.tsx +133 -0
- package/src/renderers/react/react-hotspot.tsx +116 -0
- package/src/renderers/react/react-material.tsx +159 -0
- package/src/renderers/react/react-mesh.tsx +380 -0
- package/src/renderers/react/react-scene.tsx +137 -0
- package/src/renderers/react/react.tsx +118 -0
- package/src/renderers/shared.ts +111 -0
- package/src/renderers/stl/index.ts +1 -0
- package/src/renderers/stl/stl-encoding.ts +22 -0
- package/src/renderers/stl/stl-geometries/stl-box.ts +33 -0
- package/src/renderers/stl/stl-geometries/stl-cone.ts +37 -0
- package/src/renderers/stl/stl-geometries/stl-cylinder.ts +45 -0
- package/src/renderers/stl/stl-geometries/stl-plane.ts +16 -0
- package/src/renderers/stl/stl-geometries/stl-polygon.ts +35 -0
- package/src/renderers/stl/stl-geometries/stl-shape.ts +35 -0
- package/src/renderers/stl/stl.ts +33 -0
- package/src/renderers/svg/index.ts +2 -0
- package/src/renderers/svg/svg-encoding.ts +46 -0
- package/src/renderers/svg/svg-geometries/shared.ts +10 -0
- package/src/renderers/svg/svg-geometries/svg-box.ts +61 -0
- package/src/renderers/svg/svg-geometries/svg-cone.ts +52 -0
- package/src/renderers/svg/svg-geometries/svg-cylinder.ts +58 -0
- package/src/renderers/svg/svg-geometries/svg-line.ts +20 -0
- package/src/renderers/svg/svg-geometries/svg-plane.ts +44 -0
- package/src/renderers/svg/svg-geometries/svg-polygon.ts +25 -0
- package/src/renderers/svg/svg-geometries/svg-shape.ts +25 -0
- package/src/renderers/svg/svg-geometries/svg-text.ts +28 -0
- package/src/renderers/svg/svg.ts +201 -0
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
|
+
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
3
|
+
import React, { useEffect, useRef, useState } from "react";
|
|
4
|
+
// import { OrbitControls, OrbitControlsProps } from "@react-three/drei/core/OrbitControls";
|
|
5
|
+
// import { GizmoHelper, GizmoHelperProps } from "@react-three/drei/core/GizmoHelper";
|
|
6
|
+
// import { GizmoViewcube } from "@react-three/drei/core/GizmoViewcube";
|
|
7
|
+
// import { OrthographicCamera } from "@react-three/drei/core/OrthographicCamera";
|
|
8
|
+
// import { PerspectiveCamera } from "@react-three/drei/core/PerspectiveCamera";
|
|
9
|
+
// import { GizmoViewport } from "@react-three/drei/core/GizmoViewport";
|
|
10
|
+
import {
|
|
11
|
+
GizmoHelperProps,
|
|
12
|
+
PerspectiveCamera,
|
|
13
|
+
OrthographicCamera,
|
|
14
|
+
OrbitControlsProps,
|
|
15
|
+
OrbitControls,
|
|
16
|
+
GizmoHelper,
|
|
17
|
+
GizmoViewcube,
|
|
18
|
+
GizmoViewport,
|
|
19
|
+
} from "@react-three/drei";
|
|
20
|
+
import { Vector3 } from "three";
|
|
21
|
+
import { ThreeEvent, useFrame, useThree } from "@react-three/fiber";
|
|
22
|
+
import { exhaustiveCheck } from "ts-exhaustive-check";
|
|
23
|
+
import { View, Scene, Vec3, vec3 } from "../../abstract-3d";
|
|
24
|
+
|
|
25
|
+
export type Camera = A3dPerspectiveCamera | A3dOrthographicCamera;
|
|
26
|
+
export type CameraType = Camera["type"];
|
|
27
|
+
|
|
28
|
+
export type A3dPerspectiveCamera = {
|
|
29
|
+
readonly type: "Perspective";
|
|
30
|
+
readonly near?: number;
|
|
31
|
+
readonly far?: number;
|
|
32
|
+
readonly fov?: number;
|
|
33
|
+
};
|
|
34
|
+
export type A3dOrthographicCamera = { readonly type: "Orthographic"; readonly near?: number; readonly far?: number };
|
|
35
|
+
|
|
36
|
+
export type ControlsHelper = (Viewcube | Viewport) & { readonly props: Pick<GizmoHelperProps, "alignment" | "margin"> };
|
|
37
|
+
type Viewcube = { readonly type: "Viewcube"; readonly viewcubeProps: GenericProps };
|
|
38
|
+
type Viewport = { readonly type: "Viewport"; readonly viewportProps: GizmoViewportProps };
|
|
39
|
+
|
|
40
|
+
const ControlsWrapper = (
|
|
41
|
+
props: OrbitControlsProps & { readonly setControls: (r: React.MutableRefObject<any>) => void }
|
|
42
|
+
): JSX.Element => {
|
|
43
|
+
const ref = useRef<any>();
|
|
44
|
+
|
|
45
|
+
useEffect(() => {
|
|
46
|
+
if (!ref.current) {
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
props.setControls(ref.current);
|
|
50
|
+
}, [ref.current]);
|
|
51
|
+
return <OrbitControls {...props} makeDefault ref={ref} />;
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
export function ReactCamera({
|
|
55
|
+
useAnimations,
|
|
56
|
+
camera,
|
|
57
|
+
view,
|
|
58
|
+
scene,
|
|
59
|
+
controlsHelper,
|
|
60
|
+
orbitContolsProps,
|
|
61
|
+
}: {
|
|
62
|
+
readonly useAnimations: boolean;
|
|
63
|
+
readonly camera: Camera;
|
|
64
|
+
readonly view: View;
|
|
65
|
+
readonly scene: Scene;
|
|
66
|
+
readonly controlsHelper?: ControlsHelper;
|
|
67
|
+
readonly orbitContolsProps?: OrbitControlsProps;
|
|
68
|
+
}): JSX.Element {
|
|
69
|
+
const [controls, setControls] = useState<any | null>(null);
|
|
70
|
+
const perspectiveRef = useRef<any | undefined>(undefined);
|
|
71
|
+
const orthographicRef = useRef<any | undefined>(undefined);
|
|
72
|
+
const viewPortAspect = useThree(({ viewport: { aspect } }) => aspect);
|
|
73
|
+
|
|
74
|
+
useEffect(() => {
|
|
75
|
+
const [posX, posY, posZ, size, sceneAspect] = (() => {
|
|
76
|
+
switch (view) {
|
|
77
|
+
case "front":
|
|
78
|
+
return [0, 0, 1, scene.size, scene.size.x / scene.size.y];
|
|
79
|
+
case "back":
|
|
80
|
+
return [0, 0, -1, scene.size, scene.size.x / scene.size.y];
|
|
81
|
+
case "top":
|
|
82
|
+
return [0, 1, 0, vec3(scene.size.x, scene.size.z, scene.size.y), scene.size.x / scene.size.z];
|
|
83
|
+
case "bottom":
|
|
84
|
+
return [0, -1, 0, vec3(scene.size.x, scene.size.z, scene.size.y), scene.size.x / scene.size.z];
|
|
85
|
+
case "right":
|
|
86
|
+
return [1, 0, 0, vec3(scene.size.z, scene.size.y, scene.size.x), scene.size.z / scene.size.y];
|
|
87
|
+
case "left":
|
|
88
|
+
return [-1, 0, 0, vec3(scene.size.z, scene.size.y, scene.size.x), scene.size.z / scene.size.y];
|
|
89
|
+
default:
|
|
90
|
+
return exhaustiveCheck(view);
|
|
91
|
+
}
|
|
92
|
+
})();
|
|
93
|
+
|
|
94
|
+
const dist = cameraDist(size, camera.type === "Perspective" ? camera.fov ?? 45 : 45);
|
|
95
|
+
|
|
96
|
+
if (camera.type === "Orthographic" && orthographicRef.current) {
|
|
97
|
+
const [left, right, top, bottom] =
|
|
98
|
+
sceneAspect > viewPortAspect
|
|
99
|
+
? [-size.x / 2, size.x / 2, size.x / 2 / viewPortAspect, -size.x / 2 / viewPortAspect]
|
|
100
|
+
: [(-viewPortAspect * size.y) / 2, (viewPortAspect * size.y) / 2, size.y / 2, -size.y / 2];
|
|
101
|
+
orthographicRef.current.position.setX(posX * dist);
|
|
102
|
+
orthographicRef.current.position.setY(posY * dist);
|
|
103
|
+
orthographicRef.current.position.setZ(posZ * dist);
|
|
104
|
+
orthographicRef.current.left = left;
|
|
105
|
+
orthographicRef.current.right = right;
|
|
106
|
+
orthographicRef.current.bottom = bottom;
|
|
107
|
+
orthographicRef.current.top = top;
|
|
108
|
+
orthographicRef.current.updateProjectionMatrix();
|
|
109
|
+
} else if (camera.type === "Perspective" && perspectiveRef.current) {
|
|
110
|
+
perspectiveRef.current.position.setX(posX * dist);
|
|
111
|
+
perspectiveRef.current.position.setY(posY * dist);
|
|
112
|
+
perspectiveRef.current.position.setZ(posZ * dist);
|
|
113
|
+
perspectiveRef.current.updateProjectionMatrix();
|
|
114
|
+
}
|
|
115
|
+
}, [camera, viewPortAspect]);
|
|
116
|
+
// const prevScene = React.useRef(scene)
|
|
117
|
+
// useEffect(() => {
|
|
118
|
+
// prevScene.current = scene;
|
|
119
|
+
// }, [scene]);
|
|
120
|
+
|
|
121
|
+
useFrame(() => {
|
|
122
|
+
// if (useAnimations && camera && prevScene.current !== scene) {
|
|
123
|
+
// const [, , z] = cameraDist(scene);
|
|
124
|
+
// vector3.set(camera.position.x, camera.position.y, z);
|
|
125
|
+
// camera.position.lerp(vector3, 0.12);
|
|
126
|
+
// ref.current.enabled = false;
|
|
127
|
+
// invalidate();
|
|
128
|
+
// } else {
|
|
129
|
+
// ref.current.enabled = true;
|
|
130
|
+
// }
|
|
131
|
+
});
|
|
132
|
+
return (
|
|
133
|
+
<>
|
|
134
|
+
<PerspectiveCamera
|
|
135
|
+
ref={perspectiveRef}
|
|
136
|
+
near={camera.near}
|
|
137
|
+
far={camera.far}
|
|
138
|
+
fov={camera.type === "Perspective" ? camera.fov : 75}
|
|
139
|
+
aspect={viewPortAspect}
|
|
140
|
+
manual={true}
|
|
141
|
+
makeDefault={camera.type === "Perspective"}
|
|
142
|
+
/>
|
|
143
|
+
<OrthographicCamera
|
|
144
|
+
ref={orthographicRef}
|
|
145
|
+
up={[0, 1, 0]}
|
|
146
|
+
near={camera.near}
|
|
147
|
+
far={camera.far}
|
|
148
|
+
manual={true}
|
|
149
|
+
makeDefault={camera.type === "Orthographic"}
|
|
150
|
+
/>
|
|
151
|
+
<ControlsWrapper {...orbitContolsProps} setControls={(c) => setControls(c.current)} />
|
|
152
|
+
{(() => {
|
|
153
|
+
switch (controlsHelper?.type) {
|
|
154
|
+
case "Viewcube":
|
|
155
|
+
return (
|
|
156
|
+
<GizmoHelper
|
|
157
|
+
{...controlsHelper.props}
|
|
158
|
+
onTarget={() => controls?.target as Vector3}
|
|
159
|
+
onUpdate={() => controls?.update?.()}
|
|
160
|
+
>
|
|
161
|
+
<GizmoViewcube {...(controlsHelper.viewcubeProps as any)} />
|
|
162
|
+
</GizmoHelper>
|
|
163
|
+
);
|
|
164
|
+
case "Viewport":
|
|
165
|
+
return (
|
|
166
|
+
<GizmoHelper
|
|
167
|
+
{...controlsHelper.props}
|
|
168
|
+
onTarget={() => controls?.target as Vector3}
|
|
169
|
+
onUpdate={() => controls?.update?.()}
|
|
170
|
+
>
|
|
171
|
+
<GizmoViewport {...(controlsHelper.viewportProps as any)} />
|
|
172
|
+
</GizmoHelper>
|
|
173
|
+
);
|
|
174
|
+
case undefined:
|
|
175
|
+
default:
|
|
176
|
+
return <></>;
|
|
177
|
+
}
|
|
178
|
+
})()}
|
|
179
|
+
</>
|
|
180
|
+
);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
type GizmoViewportProps = JSX.IntrinsicElements["group"] & {
|
|
184
|
+
readonly axisColors?: readonly [string, string, string];
|
|
185
|
+
readonly axisScale?: readonly [number, number, number];
|
|
186
|
+
readonly labels?: readonly [string, string, string];
|
|
187
|
+
readonly axisHeadScale?: number;
|
|
188
|
+
readonly labelColor?: string;
|
|
189
|
+
readonly hideNegativeAxes?: boolean;
|
|
190
|
+
readonly hideAxisHeads?: boolean;
|
|
191
|
+
readonly disabled?: boolean;
|
|
192
|
+
readonly font?: string;
|
|
193
|
+
readonly onClick?: (e: ThreeEvent<MouseEvent>) => null;
|
|
194
|
+
};
|
|
195
|
+
|
|
196
|
+
type GenericProps = {
|
|
197
|
+
readonly font?: string;
|
|
198
|
+
readonly opacity?: number;
|
|
199
|
+
readonly color?: string;
|
|
200
|
+
readonly hoverColor?: string;
|
|
201
|
+
readonly textColor?: string;
|
|
202
|
+
readonly strokeColor?: string;
|
|
203
|
+
readonly onClick?: (e: ThreeEvent<MouseEvent>) => null;
|
|
204
|
+
readonly faces?: ReadonlyArray<string>;
|
|
205
|
+
};
|
|
206
|
+
|
|
207
|
+
export const cameraDist = (size: Vec3, fov: number): number =>
|
|
208
|
+
size.z * 0.5 + (size.x > size.y ? size.x : size.y) / (1 / 2 / Math.tan((Math.PI * fov) / 180 / 2));
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { useFrame } from "@react-three/fiber";
|
|
2
|
+
import React from "react";
|
|
3
|
+
import { Group } from "three";
|
|
4
|
+
import * as A3d from "../../abstract-3d";
|
|
5
|
+
import { ReactMaterial } from "./react-material";
|
|
6
|
+
import { ReactMesh } from "./react-mesh";
|
|
7
|
+
|
|
8
|
+
export const ReactDimensions = React.memo(
|
|
9
|
+
({
|
|
10
|
+
dimensions,
|
|
11
|
+
showDimensions,
|
|
12
|
+
}: {
|
|
13
|
+
readonly dimensions: A3d.Dimensions | undefined;
|
|
14
|
+
readonly showDimensions: boolean;
|
|
15
|
+
}): JSX.Element => {
|
|
16
|
+
const dimensionMaterial = React.useMemo(
|
|
17
|
+
() => (dimensions?.material ? <ReactMaterial material={dimensions?.material} /> : <></>),
|
|
18
|
+
[]
|
|
19
|
+
);
|
|
20
|
+
return (
|
|
21
|
+
<>
|
|
22
|
+
{dimensions?.dimensions.map((dimension, i) => (
|
|
23
|
+
<ReactDimension key={i} d={dimension} visible={showDimensions}>
|
|
24
|
+
{dimensionMaterial}
|
|
25
|
+
</ReactDimension>
|
|
26
|
+
))}
|
|
27
|
+
</>
|
|
28
|
+
);
|
|
29
|
+
}
|
|
30
|
+
);
|
|
31
|
+
|
|
32
|
+
export function ReactDimension({
|
|
33
|
+
d,
|
|
34
|
+
visible,
|
|
35
|
+
children,
|
|
36
|
+
}: {
|
|
37
|
+
readonly d: A3d.Dimension;
|
|
38
|
+
readonly visible: boolean;
|
|
39
|
+
readonly children: JSX.Element;
|
|
40
|
+
}): JSX.Element {
|
|
41
|
+
const ref = React.useRef<Group>(undefined!);
|
|
42
|
+
useFrame(({ camera }) => {
|
|
43
|
+
ref.current.visible =
|
|
44
|
+
visible &&
|
|
45
|
+
((): boolean => {
|
|
46
|
+
const cameraPositions = {
|
|
47
|
+
[camera.position.x >= 0 ? "right" : "left"]: true,
|
|
48
|
+
[camera.position.y >= 0 ? "top" : "bottom"]: true,
|
|
49
|
+
[camera.position.z >= 0 ? "front" : "back"]: true,
|
|
50
|
+
};
|
|
51
|
+
if (d.views.every((cp) => cameraPositions[cp])) {
|
|
52
|
+
ref.current.position.set(d.pos.x, d.pos.y, d.pos.z);
|
|
53
|
+
ref.current.rotation.set(d.rot.x, d.rot.y, d.rot.z);
|
|
54
|
+
return true;
|
|
55
|
+
}
|
|
56
|
+
return false;
|
|
57
|
+
})();
|
|
58
|
+
});
|
|
59
|
+
return (
|
|
60
|
+
<group ref={ref}>
|
|
61
|
+
<DimensionMeshes meshes={d.meshes}>{children}</DimensionMeshes>
|
|
62
|
+
</group>
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const DimensionMeshes = React.memo(
|
|
67
|
+
({ meshes, children }: { readonly meshes: ReadonlyArray<A3d.Mesh>; readonly children: JSX.Element }): JSX.Element => (
|
|
68
|
+
<>
|
|
69
|
+
{meshes.map((m, i) => (
|
|
70
|
+
<ReactMesh key={i} mesh={m}>
|
|
71
|
+
{children}
|
|
72
|
+
</ReactMesh>
|
|
73
|
+
))}
|
|
74
|
+
</>
|
|
75
|
+
)
|
|
76
|
+
);
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { Group } from "three";
|
|
3
|
+
import { useFrame } from "@react-three/fiber";
|
|
4
|
+
import * as A3d from "../../abstract-3d";
|
|
5
|
+
import { MaterialState, ReactMaterial } from "./react-material";
|
|
6
|
+
import { ReactMesh } from "./react-mesh";
|
|
7
|
+
|
|
8
|
+
export function ReactGroup({
|
|
9
|
+
g,
|
|
10
|
+
materialStateImages,
|
|
11
|
+
hoveredId,
|
|
12
|
+
hoveredIdExternal,
|
|
13
|
+
selectedId,
|
|
14
|
+
hotSpotsActive,
|
|
15
|
+
activeComponents,
|
|
16
|
+
id,
|
|
17
|
+
rootData,
|
|
18
|
+
onClickGroup,
|
|
19
|
+
onContextMenuGroup,
|
|
20
|
+
setHoveredId,
|
|
21
|
+
createGroupKey,
|
|
22
|
+
}: {
|
|
23
|
+
readonly g: A3d.Group;
|
|
24
|
+
readonly materialStateImages?: Record<string, string>;
|
|
25
|
+
readonly hoveredId: string | undefined;
|
|
26
|
+
readonly hoveredIdExternal: string | undefined;
|
|
27
|
+
readonly selectedId: string | undefined;
|
|
28
|
+
readonly hotSpotsActive: boolean;
|
|
29
|
+
readonly activeComponents: Record<string, MaterialState> | undefined;
|
|
30
|
+
readonly id: string | undefined;
|
|
31
|
+
readonly rootData: Record<string, string> | undefined;
|
|
32
|
+
readonly onClickGroup?: (
|
|
33
|
+
id: string | undefined,
|
|
34
|
+
rootData: Record<string, string> | undefined,
|
|
35
|
+
data: Record<string, string> | undefined
|
|
36
|
+
) => void;
|
|
37
|
+
readonly onContextMenuGroup?: (
|
|
38
|
+
id: string,
|
|
39
|
+
rootData: Record<string, string> | undefined,
|
|
40
|
+
data: Record<string, string> | undefined,
|
|
41
|
+
left: number,
|
|
42
|
+
top: number
|
|
43
|
+
) => void;
|
|
44
|
+
readonly setHoveredId: (id: string | undefined) => void;
|
|
45
|
+
readonly createGroupKey?: (
|
|
46
|
+
g: A3d.Group,
|
|
47
|
+
idx: number,
|
|
48
|
+
rootData: Record<string, string> | undefined,
|
|
49
|
+
id: string
|
|
50
|
+
) => string;
|
|
51
|
+
}): JSX.Element {
|
|
52
|
+
const ref = React.useRef<Group>(undefined!);
|
|
53
|
+
useFrame(({ invalidate }, delta) => {
|
|
54
|
+
if (g.animation) {
|
|
55
|
+
invalidate();
|
|
56
|
+
ref.current.rotation.x += (g.animation.transform.rot.x / g.animation.duration) * 1000 * delta;
|
|
57
|
+
ref.current.rotation.y += (g.animation.transform.rot.y / g.animation.duration) * 1000 * delta;
|
|
58
|
+
ref.current.rotation.z += (g.animation.transform.rot.z / g.animation.duration) * 1000 * delta;
|
|
59
|
+
} else {
|
|
60
|
+
ref.current.rotation.x = g.rot?.x ?? 0;
|
|
61
|
+
ref.current.rotation.y = g.rot?.y ?? 0;
|
|
62
|
+
ref.current.rotation.z = g.rot?.z ?? 0;
|
|
63
|
+
ref.current.position.x = g.pos.x;
|
|
64
|
+
ref.current.position.y = g.pos.y;
|
|
65
|
+
ref.current.position.z = g.pos.z;
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
const materialState = activeComponents?.[id ?? ""];
|
|
69
|
+
const disabled = hotSpotsActive && materialState !== "Accept";
|
|
70
|
+
return (
|
|
71
|
+
<group
|
|
72
|
+
rotation={[g.rot?.x ?? 0, g.rot?.y ?? 0, g.rot?.z ?? 0]}
|
|
73
|
+
position={[g.pos.x, g.pos.y, g.pos.z]}
|
|
74
|
+
ref={ref}
|
|
75
|
+
{...(id &&
|
|
76
|
+
!disabled && {
|
|
77
|
+
onClick: (e) => {
|
|
78
|
+
if (onClickGroup) {
|
|
79
|
+
e.stopPropagation();
|
|
80
|
+
onClickGroup(id, rootData, g.data);
|
|
81
|
+
}
|
|
82
|
+
},
|
|
83
|
+
onPointerOver: (e) => {
|
|
84
|
+
e.stopPropagation();
|
|
85
|
+
document.body.style.cursor = "pointer";
|
|
86
|
+
setHoveredId(id);
|
|
87
|
+
},
|
|
88
|
+
onPointerOut: (_e) => {
|
|
89
|
+
document.body.style.cursor = "auto";
|
|
90
|
+
setHoveredId(undefined);
|
|
91
|
+
},
|
|
92
|
+
onContextMenu: (e) => {
|
|
93
|
+
if (onContextMenuGroup) {
|
|
94
|
+
e.stopPropagation();
|
|
95
|
+
onContextMenuGroup(id, rootData, g.data, e.nativeEvent.x, e.nativeEvent.y);
|
|
96
|
+
}
|
|
97
|
+
},
|
|
98
|
+
})}
|
|
99
|
+
>
|
|
100
|
+
{g.groups?.map((g, i) => (
|
|
101
|
+
<ReactGroup
|
|
102
|
+
key={createGroupKey ? createGroupKey(g, i, rootData, id ?? "") : i}
|
|
103
|
+
g={g}
|
|
104
|
+
selectedId={selectedId}
|
|
105
|
+
hotSpotsActive={hotSpotsActive}
|
|
106
|
+
activeComponents={activeComponents}
|
|
107
|
+
materialStateImages={materialStateImages}
|
|
108
|
+
hoveredId={hoveredId}
|
|
109
|
+
hoveredIdExternal={hoveredIdExternal}
|
|
110
|
+
onClickGroup={onClickGroup}
|
|
111
|
+
onContextMenuGroup={onContextMenuGroup}
|
|
112
|
+
setHoveredId={setHoveredId}
|
|
113
|
+
id={id}
|
|
114
|
+
rootData={rootData}
|
|
115
|
+
createGroupKey={createGroupKey}
|
|
116
|
+
/>
|
|
117
|
+
))}
|
|
118
|
+
{g.meshes?.map((m, i) => (
|
|
119
|
+
<ReactMesh key={`mesh_${i}`} mesh={m}>
|
|
120
|
+
<ReactMaterial
|
|
121
|
+
material={m.material}
|
|
122
|
+
id={id}
|
|
123
|
+
selectedId={selectedId}
|
|
124
|
+
hoveredId={hoveredId || hoveredIdExternal}
|
|
125
|
+
materialStateImages={materialStateImages}
|
|
126
|
+
disabled={disabled}
|
|
127
|
+
state={materialState}
|
|
128
|
+
/>
|
|
129
|
+
</ReactMesh>
|
|
130
|
+
))}
|
|
131
|
+
</group>
|
|
132
|
+
);
|
|
133
|
+
}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
// import { Html } from "@react-three/drei/web/Html";
|
|
3
|
+
import { Html } from "@react-three/drei";
|
|
4
|
+
import * as A3d from "../../abstract-3d";
|
|
5
|
+
import { ReactMesh } from "./react-mesh";
|
|
6
|
+
import { ReactMaterial } from "./react-material";
|
|
7
|
+
|
|
8
|
+
export interface HotSpotInfo {
|
|
9
|
+
readonly replaceId: string;
|
|
10
|
+
readonly replaceFromId: string;
|
|
11
|
+
readonly replaceOutlet: string;
|
|
12
|
+
readonly replaceToId: string;
|
|
13
|
+
readonly replaceInlet: string;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export const ReactHotSpots = React.memo(
|
|
17
|
+
({
|
|
18
|
+
hotSpots,
|
|
19
|
+
showHotSpotTexts,
|
|
20
|
+
hotSpotTexts,
|
|
21
|
+
hotSpotZAdjPos,
|
|
22
|
+
activeHotSpots,
|
|
23
|
+
hoveredId,
|
|
24
|
+
onClickHotSpot,
|
|
25
|
+
setHoveredId,
|
|
26
|
+
}: {
|
|
27
|
+
readonly hotSpots?: ReadonlyArray<A3d.HotSpot>;
|
|
28
|
+
readonly showHotSpotTexts: boolean;
|
|
29
|
+
readonly hotSpotZAdjPos: number;
|
|
30
|
+
readonly hotSpotTexts?: Record<string, string>;
|
|
31
|
+
readonly activeHotSpots: Record<string, HotSpotInfo> | undefined;
|
|
32
|
+
readonly hoveredId: string | undefined;
|
|
33
|
+
readonly onClickHotSpot?: (hotSpot: HotSpotInfo) => void;
|
|
34
|
+
readonly setHoveredId: (id: string | undefined) => void;
|
|
35
|
+
}): JSX.Element => {
|
|
36
|
+
return (
|
|
37
|
+
<>
|
|
38
|
+
{hotSpots?.map((h) => (
|
|
39
|
+
<ReactHotSpot
|
|
40
|
+
key={h.id}
|
|
41
|
+
h={h}
|
|
42
|
+
hotSpotZAdjPos={hotSpotZAdjPos}
|
|
43
|
+
activeHotSpots={activeHotSpots}
|
|
44
|
+
hotSpotTexts={hotSpotTexts}
|
|
45
|
+
hoveredId={hoveredId}
|
|
46
|
+
onClickHotSpot={onClickHotSpot}
|
|
47
|
+
setHoveredId={setHoveredId}
|
|
48
|
+
showHotSpotTexts={showHotSpotTexts}
|
|
49
|
+
/>
|
|
50
|
+
))}
|
|
51
|
+
</>
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
);
|
|
55
|
+
|
|
56
|
+
export function ReactHotSpot({
|
|
57
|
+
h,
|
|
58
|
+
hotSpotZAdjPos,
|
|
59
|
+
showHotSpotTexts,
|
|
60
|
+
hotSpotTexts,
|
|
61
|
+
activeHotSpots,
|
|
62
|
+
hoveredId,
|
|
63
|
+
onClickHotSpot,
|
|
64
|
+
setHoveredId,
|
|
65
|
+
}: {
|
|
66
|
+
readonly h: A3d.HotSpot;
|
|
67
|
+
readonly hotSpotZAdjPos: number;
|
|
68
|
+
readonly showHotSpotTexts: boolean;
|
|
69
|
+
readonly hotSpotTexts?: Record<string, string>;
|
|
70
|
+
readonly activeHotSpots: Record<string, HotSpotInfo> | undefined;
|
|
71
|
+
readonly hoveredId: string | undefined;
|
|
72
|
+
readonly onClickHotSpot?: (hotSpot: HotSpotInfo) => void;
|
|
73
|
+
readonly setHoveredId: (id: string | undefined) => void;
|
|
74
|
+
}): JSX.Element {
|
|
75
|
+
const hotSpot = activeHotSpots ? activeHotSpots[h.id] : undefined;
|
|
76
|
+
const hsPos = h.mesh.geometry.type === "Box" ? h.mesh.geometry.pos : A3d.vec3Zero;
|
|
77
|
+
const text = hotSpotTexts?.[h.id];
|
|
78
|
+
return (
|
|
79
|
+
<>
|
|
80
|
+
<group
|
|
81
|
+
visible={hotSpot !== undefined}
|
|
82
|
+
{...(hotSpot && {
|
|
83
|
+
onClick: (e) => {
|
|
84
|
+
if (onClickHotSpot) {
|
|
85
|
+
e.stopPropagation();
|
|
86
|
+
onClickHotSpot(hotSpot);
|
|
87
|
+
}
|
|
88
|
+
},
|
|
89
|
+
onPointerOver: (e) => {
|
|
90
|
+
e.stopPropagation();
|
|
91
|
+
document.body.style.cursor = "pointer";
|
|
92
|
+
setHoveredId(h.id);
|
|
93
|
+
},
|
|
94
|
+
onPointerOut: (_e) => {
|
|
95
|
+
document.body.style.cursor = "auto";
|
|
96
|
+
setHoveredId(undefined);
|
|
97
|
+
},
|
|
98
|
+
onContextMenu: (e) => {
|
|
99
|
+
e.stopPropagation();
|
|
100
|
+
},
|
|
101
|
+
})}
|
|
102
|
+
>
|
|
103
|
+
<ReactMesh mesh={h.mesh}>
|
|
104
|
+
<ReactMaterial id={h.id} material={h.mesh.material} hoveredId={hoveredId} />
|
|
105
|
+
</ReactMesh>
|
|
106
|
+
</group>
|
|
107
|
+
{hotSpotTexts && text && (
|
|
108
|
+
<Html position={[hsPos.x, hsPos.y, hotSpotZAdjPos]} center>
|
|
109
|
+
<div className={`air-states-container ${showHotSpotTexts ? "" : "air-states-container-hidden"}`}>
|
|
110
|
+
<span className="air-states-text">{text}</span>
|
|
111
|
+
</div>
|
|
112
|
+
</Html>
|
|
113
|
+
)}
|
|
114
|
+
</>
|
|
115
|
+
);
|
|
116
|
+
}
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { Color, DoubleSide, MaterialParameters, SRGBColorSpace, Texture, TextureLoader } from "three";
|
|
3
|
+
import { suspend } from "suspend-react";
|
|
4
|
+
import * as A3d from "../../abstract-3d";
|
|
5
|
+
|
|
6
|
+
const decreasedOpacity = 0.2;
|
|
7
|
+
|
|
8
|
+
export type MaterialState = "Accept" | "Error" | "Warning";
|
|
9
|
+
export const ERROR_IMG_KEY = "error";
|
|
10
|
+
|
|
11
|
+
export function ReactMaterial({
|
|
12
|
+
material,
|
|
13
|
+
id = "",
|
|
14
|
+
selectedId,
|
|
15
|
+
hoveredId,
|
|
16
|
+
disabled,
|
|
17
|
+
materialStateImages,
|
|
18
|
+
state,
|
|
19
|
+
}: {
|
|
20
|
+
readonly material: A3d.Material;
|
|
21
|
+
readonly id?: string;
|
|
22
|
+
readonly hoveredId?: string | undefined;
|
|
23
|
+
readonly selectedId?: string | undefined;
|
|
24
|
+
readonly disabled?: boolean;
|
|
25
|
+
readonly materialStateImages?: Record<string, string>;
|
|
26
|
+
readonly state?: MaterialState | undefined;
|
|
27
|
+
}): JSX.Element {
|
|
28
|
+
const mat =
|
|
29
|
+
!state || material.image?.type === "UrlImage"
|
|
30
|
+
? material
|
|
31
|
+
: state === "Accept"
|
|
32
|
+
? acceptMaterial
|
|
33
|
+
: state === "Error"
|
|
34
|
+
? errorMaterial
|
|
35
|
+
: warningMaterial;
|
|
36
|
+
const color = selectedId === id ? mat.selected : hoveredId === id ? mat.hover : mat.normal;
|
|
37
|
+
const opacity = material.opacity !== undefined ? material.opacity : materialDefaults.opacity!;
|
|
38
|
+
if (material.image?.type === "UrlImage") {
|
|
39
|
+
return (
|
|
40
|
+
<TextureMaterial
|
|
41
|
+
url={state === "Error" ? materialStateImages?.[ERROR_IMG_KEY] ?? material.image.url : material.image.url}
|
|
42
|
+
color={color}
|
|
43
|
+
material={mat}
|
|
44
|
+
/>
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
switch (mat.type) {
|
|
49
|
+
case "Basic":
|
|
50
|
+
return (
|
|
51
|
+
<meshBasicMaterial
|
|
52
|
+
color={color}
|
|
53
|
+
side={DoubleSide}
|
|
54
|
+
transparent
|
|
55
|
+
{...(opacity < 1 ? { opacity } : materialDefaults)}
|
|
56
|
+
/>
|
|
57
|
+
);
|
|
58
|
+
case "Phong":
|
|
59
|
+
return (
|
|
60
|
+
<meshPhongMaterial
|
|
61
|
+
color={color}
|
|
62
|
+
shininess={(mat.shininess ?? 70) * 2}
|
|
63
|
+
side={DoubleSide}
|
|
64
|
+
{...(opacity < 1 || disabled
|
|
65
|
+
? { transparent: true, opacity: disabled ? opacity * decreasedOpacity : opacity }
|
|
66
|
+
: materialDefaults)}
|
|
67
|
+
/>
|
|
68
|
+
);
|
|
69
|
+
// return (
|
|
70
|
+
// <meshStandardMaterial
|
|
71
|
+
// color={color}
|
|
72
|
+
// roughness={0.45}
|
|
73
|
+
// metalness={0.55}
|
|
74
|
+
// side={DoubleSide}
|
|
75
|
+
// {...(mat.opacity < 1 || disabled
|
|
76
|
+
// ? { transparent: true, opacity: disabled ? mat.opacity * decreasedOpacity : mat.opacity }
|
|
77
|
+
// : materialDefaults)}
|
|
78
|
+
// />
|
|
79
|
+
// );
|
|
80
|
+
case "Lambert":
|
|
81
|
+
default:
|
|
82
|
+
return (
|
|
83
|
+
<meshLambertMaterial
|
|
84
|
+
color={color}
|
|
85
|
+
side={DoubleSide}
|
|
86
|
+
{...(opacity < 1 || disabled
|
|
87
|
+
? { transparent: true, opacity: disabled ? opacity * decreasedOpacity : opacity }
|
|
88
|
+
: materialDefaults)}
|
|
89
|
+
/>
|
|
90
|
+
);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
function TextureMaterial({
|
|
95
|
+
url,
|
|
96
|
+
color,
|
|
97
|
+
material,
|
|
98
|
+
}: {
|
|
99
|
+
readonly url: string;
|
|
100
|
+
readonly color: string | Color | undefined;
|
|
101
|
+
readonly material: A3d.Material;
|
|
102
|
+
}): JSX.Element {
|
|
103
|
+
const texture = suspend(
|
|
104
|
+
new Promise((res) =>
|
|
105
|
+
textureLoader.load(
|
|
106
|
+
url,
|
|
107
|
+
(data) => {
|
|
108
|
+
data.colorSpace = SRGBColorSpace;
|
|
109
|
+
res(data);
|
|
110
|
+
},
|
|
111
|
+
undefined,
|
|
112
|
+
() => res(null)
|
|
113
|
+
)
|
|
114
|
+
),
|
|
115
|
+
[url]
|
|
116
|
+
) as Texture | null;
|
|
117
|
+
|
|
118
|
+
return (
|
|
119
|
+
<meshBasicMaterial
|
|
120
|
+
color={color}
|
|
121
|
+
side={DoubleSide}
|
|
122
|
+
alphaTest={0.8}
|
|
123
|
+
map={texture}
|
|
124
|
+
{...(material.opacity !== undefined && material.opacity < 1 ? { opacity: material.opacity } : materialDefaults)}
|
|
125
|
+
transparent
|
|
126
|
+
/>
|
|
127
|
+
);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
const textureLoader = new TextureLoader();
|
|
131
|
+
|
|
132
|
+
const materialDefaults: MaterialParameters = { transparent: false, opacity: 1.0, depthWrite: true, depthTest: true };
|
|
133
|
+
|
|
134
|
+
const acceptMaterial: A3d.Material = {
|
|
135
|
+
type: "Phong",
|
|
136
|
+
normal: "rgb(0,148,91)",
|
|
137
|
+
hover: "rgb(1,88,55)",
|
|
138
|
+
selected: "rgb(1,88,55)",
|
|
139
|
+
opacity: 1.0,
|
|
140
|
+
shininess: 50,
|
|
141
|
+
};
|
|
142
|
+
|
|
143
|
+
const errorMaterial: A3d.Material = {
|
|
144
|
+
type: "Phong",
|
|
145
|
+
normal: "#b82f3a",
|
|
146
|
+
hover: "#991c31",
|
|
147
|
+
selected: "#991c31",
|
|
148
|
+
opacity: 1.0,
|
|
149
|
+
shininess: 50,
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
const warningMaterial: A3d.Material = {
|
|
153
|
+
type: "Phong",
|
|
154
|
+
normal: "rgb(240, 197, 48)",
|
|
155
|
+
hover: "rgb(221, 181, 38)",
|
|
156
|
+
selected: "rgb(182, 147, 20)",
|
|
157
|
+
opacity: 1.0,
|
|
158
|
+
shininess: 50,
|
|
159
|
+
};
|