abstract-3d 0.6.1 → 0.6.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/lib/abstract-3d.d.ts +4 -0
- package/lib/abstract-3d.d.ts.map +1 -1
- package/lib/abstract-3d.js +10 -8
- package/lib/abstract-3d.js.map +1 -1
- package/lib/index.js +1 -0
- package/lib/index.js.map +1 -1
- package/lib/renderers/dxf/color.d.ts +3 -1
- package/lib/renderers/dxf/color.d.ts.map +1 -1
- package/lib/renderers/dxf/color.js +299 -1
- package/lib/renderers/dxf/color.js.map +1 -1
- package/lib/renderers/dxf/dxf-encoding.d.ts +12 -4
- package/lib/renderers/dxf/dxf-encoding.d.ts.map +1 -1
- package/lib/renderers/dxf/dxf-encoding.js +18323 -223
- package/lib/renderers/dxf/dxf-encoding.js.map +1 -1
- package/lib/renderers/dxf/dxf-geometries/dxf-box.d.ts +3 -1
- package/lib/renderers/dxf/dxf-geometries/dxf-box.d.ts.map +1 -1
- package/lib/renderers/dxf/dxf-geometries/dxf-box.js +7 -7
- package/lib/renderers/dxf/dxf-geometries/dxf-box.js.map +1 -1
- package/lib/renderers/dxf/dxf-geometries/dxf-cone.d.ts +3 -1
- package/lib/renderers/dxf/dxf-geometries/dxf-cone.d.ts.map +1 -1
- package/lib/renderers/dxf/dxf-geometries/dxf-cone.js +2 -2
- package/lib/renderers/dxf/dxf-geometries/dxf-cone.js.map +1 -1
- package/lib/renderers/dxf/dxf-geometries/dxf-cylinder.d.ts +3 -1
- package/lib/renderers/dxf/dxf-geometries/dxf-cylinder.d.ts.map +1 -1
- package/lib/renderers/dxf/dxf-geometries/dxf-cylinder.js +3 -3
- package/lib/renderers/dxf/dxf-geometries/dxf-cylinder.js.map +1 -1
- package/lib/renderers/dxf/dxf-geometries/dxf-plane.d.ts +3 -1
- package/lib/renderers/dxf/dxf-geometries/dxf-plane.d.ts.map +1 -1
- package/lib/renderers/dxf/dxf-geometries/dxf-plane.js +2 -2
- package/lib/renderers/dxf/dxf-geometries/dxf-plane.js.map +1 -1
- package/lib/renderers/dxf/dxf-geometries/dxf-polygon.d.ts +3 -1
- package/lib/renderers/dxf/dxf-geometries/dxf-polygon.d.ts.map +1 -1
- package/lib/renderers/dxf/dxf-geometries/dxf-polygon.js +5 -5
- package/lib/renderers/dxf/dxf-geometries/dxf-polygon.js.map +1 -1
- package/lib/renderers/dxf/dxf-geometries/dxf-shape.d.ts +3 -1
- package/lib/renderers/dxf/dxf-geometries/dxf-shape.d.ts.map +1 -1
- package/lib/renderers/dxf/dxf-geometries/dxf-shape.js +5 -5
- package/lib/renderers/dxf/dxf-geometries/dxf-shape.js.map +1 -1
- package/lib/renderers/dxf/dxf.d.ts.map +1 -1
- package/lib/renderers/dxf/dxf.js +22 -14
- package/lib/renderers/dxf/dxf.js.map +1 -1
- package/lib/renderers/react/react-camera.d.ts.map +1 -1
- package/lib/renderers/react/react-camera.js +24 -24
- package/lib/renderers/react/react-camera.js.map +1 -1
- package/lib/renderers/react/react-hotspot.js +1 -1
- package/lib/renderers/react/react-hotspot.js.map +1 -1
- package/lib/renderers/react/react-material.d.ts +2 -1
- package/lib/renderers/react/react-material.d.ts.map +1 -1
- package/lib/renderers/react/react-material.js +10 -3
- package/lib/renderers/react/react-material.js.map +1 -1
- package/lib/renderers/react/react-scene.d.ts.map +1 -1
- package/lib/renderers/react/react-scene.js +1 -2
- package/lib/renderers/react/react-scene.js.map +1 -1
- package/lib/renderers/step/step-encoding.d.ts.map +1 -1
- package/lib/renderers/step/step.d.ts.map +1 -1
- package/lib/renderers/stl/stl-encoding.d.ts.map +1 -1
- package/lib/renderers/stl/stl.d.ts.map +1 -1
- package/lib/renderers/svg/svg-encoding.d.ts.map +1 -1
- package/lib/renderers/svg/svg-encoding.js +13 -4
- package/lib/renderers/svg/svg-encoding.js.map +1 -1
- package/lib/renderers/svg/svg-geometries/shared.d.ts.map +1 -1
- package/lib/renderers/svg/svg.d.ts +1 -1
- package/lib/renderers/svg/svg.d.ts.map +1 -1
- package/lib/renderers/svg/svg.js +4 -2
- package/lib/renderers/svg/svg.js.map +1 -1
- package/package.json +6 -6
- package/src/abstract-3d.ts +18 -9
- package/src/index.ts +1 -0
- package/src/renderers/dxf/color.ts +304 -1
- package/src/renderers/dxf/dxf-encoding.ts +18331 -226
- package/src/renderers/dxf/dxf-geometries/dxf-box.ts +7 -7
- package/src/renderers/dxf/dxf-geometries/dxf-cone.ts +2 -2
- package/src/renderers/dxf/dxf-geometries/dxf-cylinder.ts +3 -3
- package/src/renderers/dxf/dxf-geometries/dxf-plane.ts +3 -2
- package/src/renderers/dxf/dxf-geometries/dxf-polygon.ts +5 -5
- package/src/renderers/dxf/dxf-geometries/dxf-shape.ts +5 -5
- package/src/renderers/dxf/dxf.ts +23 -15
- package/src/renderers/react/react-camera.tsx +28 -28
- package/src/renderers/react/react-hotspot.tsx +1 -1
- package/src/renderers/react/react-material.tsx +12 -2
- package/src/renderers/react/react-scene.tsx +1 -3
- package/src/renderers/svg/svg-encoding.ts +14 -12
- package/src/renderers/svg/svg.ts +7 -2
|
@@ -2,7 +2,7 @@ import { Box, Material, Vec3, vec3TransRot, vec3RotCombine, vec3Zero, vec3Scale,
|
|
|
2
2
|
import { color } from "../color.js";
|
|
3
3
|
import { dxf3DFACE } from "../dxf-encoding.js";
|
|
4
4
|
|
|
5
|
-
export function dxfBox(b: Box, m: Material, parentPos: Vec3, parentRot: Vec3): string {
|
|
5
|
+
export function dxfBox(b: Box, m: Material, parentPos: Vec3, parentRot: Vec3, handleRef: {handle: number}): string {
|
|
6
6
|
const pos = vec3TransRot(b.pos, parentPos, parentRot);
|
|
7
7
|
const rot = vec3RotCombine(parentRot, b.rot ?? vec3Zero);
|
|
8
8
|
const half = vec3Scale(b.size, 0.5);
|
|
@@ -18,11 +18,11 @@ export function dxfBox(b: Box, m: Material, parentPos: Vec3, parentRot: Vec3): s
|
|
|
18
18
|
const v8 = vec3tr3(-half.x, half.y, -half.z);
|
|
19
19
|
const mat = color(m.normal);
|
|
20
20
|
return (
|
|
21
|
-
dxf3DFACE(v1, v2, v3, v4, mat) + // front
|
|
22
|
-
dxf3DFACE(v5, v6, v7, v8, mat) + // Back
|
|
23
|
-
dxf3DFACE(v5, v1, v4, v8, mat) + // Left
|
|
24
|
-
dxf3DFACE(v6, v2, v3, v7, mat) + // Right
|
|
25
|
-
dxf3DFACE(v8, v7, v3, v4, mat) + // Top
|
|
26
|
-
dxf3DFACE(v5, v6, v2, v1, mat) // Bottom
|
|
21
|
+
dxf3DFACE(v1, v2, v3, v4, mat, handleRef) + // front
|
|
22
|
+
dxf3DFACE(v5, v6, v7, v8, mat, handleRef) + // Back
|
|
23
|
+
dxf3DFACE(v5, v1, v4, v8, mat, handleRef) + // Left
|
|
24
|
+
dxf3DFACE(v6, v2, v3, v7, mat, handleRef) + // Right
|
|
25
|
+
dxf3DFACE(v8, v7, v3, v4, mat, handleRef) + // Top
|
|
26
|
+
dxf3DFACE(v5, v6, v2, v1, mat, handleRef) // Bottom
|
|
27
27
|
);
|
|
28
28
|
}
|
|
@@ -2,7 +2,7 @@ import { Cone, Material, Vec3, vec3TransRot, vec3RotCombine, vec3Zero, vec3 } fr
|
|
|
2
2
|
import { color } from "../color.js";
|
|
3
3
|
import { dxf3DFACE } from "../dxf-encoding.js";
|
|
4
4
|
|
|
5
|
-
export function dxfCone(c: Cone, m: Material, sides: number, parentPos: Vec3, parentRot: Vec3): string {
|
|
5
|
+
export function dxfCone(c: Cone, m: Material, sides: number, parentPos: Vec3, parentRot: Vec3, handleRef: {handle: number}): string {
|
|
6
6
|
let dxfString = "";
|
|
7
7
|
const pos = vec3TransRot(c.pos, parentPos, parentRot);
|
|
8
8
|
const rot = vec3RotCombine(parentRot, c.rot ?? vec3Zero);
|
|
@@ -22,7 +22,7 @@ export function dxfCone(c: Cone, m: Material, sides: number, parentPos: Vec3, pa
|
|
|
22
22
|
|
|
23
23
|
if (i !== 0) {
|
|
24
24
|
const prevBot = botVec3Array[i - 1]!;
|
|
25
|
-
dxfString += dxf3DFACE(botPos, prevBot, currBot, currBot, mat) + dxf3DFACE(currBot, prevBot, topPos, topPos, mat);
|
|
25
|
+
dxfString += dxf3DFACE(botPos, prevBot, currBot, currBot, mat, handleRef) + dxf3DFACE(currBot, prevBot, topPos, topPos, mat, handleRef);
|
|
26
26
|
}
|
|
27
27
|
currentAngle += angleStep;
|
|
28
28
|
}
|
|
@@ -2,7 +2,7 @@ import { Cylinder, Material, Vec3, vec3TransRot, vec3RotCombine, vec3Zero, vec3
|
|
|
2
2
|
import { color } from "../color.js";
|
|
3
3
|
import { dxf3DFACE } from "../dxf-encoding.js";
|
|
4
4
|
|
|
5
|
-
export function dxfCylinder(c: Cylinder, m: Material, sides: number, parentPos: Vec3, parentRot: Vec3): string {
|
|
5
|
+
export function dxfCylinder(c: Cylinder, m: Material, sides: number, parentPos: Vec3, parentRot: Vec3, handleRef: {handle: number}): string {
|
|
6
6
|
let dxfString = "";
|
|
7
7
|
const pos = vec3TransRot(c.pos, parentPos, parentRot);
|
|
8
8
|
const rot = vec3RotCombine(parentRot, c.rot ?? vec3Zero);
|
|
@@ -30,9 +30,9 @@ export function dxfCylinder(c: Cylinder, m: Material, sides: number, parentPos:
|
|
|
30
30
|
const prevTop = topVec3Array[i - 1]!;
|
|
31
31
|
if (!c.open) {
|
|
32
32
|
dxfString +=
|
|
33
|
-
dxf3DFACE(botPos, prevBot, currBot, currBot, mat) + dxf3DFACE(topPos, prevTop, currTop, currTop, mat);
|
|
33
|
+
dxf3DFACE(botPos, prevBot, currBot, currBot, mat, handleRef) + dxf3DFACE(topPos, prevTop, currTop, currTop, mat, handleRef);
|
|
34
34
|
}
|
|
35
|
-
dxfString += dxf3DFACE(currBot, prevBot, prevTop, currTop, mat);
|
|
35
|
+
dxfString += dxf3DFACE(currBot, prevBot, prevTop, currTop, mat, handleRef);
|
|
36
36
|
}
|
|
37
37
|
currentAngle += angleStep;
|
|
38
38
|
}
|
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
import { color } from "../color.js";
|
|
12
12
|
import { dxf3DFACE } from "../dxf-encoding.js";
|
|
13
13
|
|
|
14
|
-
export function dxfPlane(p: Plane, m: Material, parentPos: Vec3, parentRot: Vec3): string {
|
|
14
|
+
export function dxfPlane(p: Plane, m: Material, parentPos: Vec3, parentRot: Vec3, handleRef: {handle: number}): string {
|
|
15
15
|
const half = vec2Scale(p.size, 0.5);
|
|
16
16
|
const pos = vec3TransRot(p.pos, parentPos, parentRot);
|
|
17
17
|
const rot = vec3RotCombine(parentRot, p.rot ?? vec3Zero);
|
|
@@ -21,6 +21,7 @@ export function dxfPlane(p: Plane, m: Material, parentPos: Vec3, parentRot: Vec3
|
|
|
21
21
|
vec3tr(half.x, -half.y),
|
|
22
22
|
vec3tr(half.x, half.y),
|
|
23
23
|
vec3tr(-half.x, half.y),
|
|
24
|
-
color(m.normal)
|
|
24
|
+
color(m.normal),
|
|
25
|
+
handleRef
|
|
25
26
|
);
|
|
26
27
|
}
|
|
@@ -4,7 +4,7 @@ import { dxf3DFACE } from "../dxf-encoding.js";
|
|
|
4
4
|
|
|
5
5
|
const chunkSize = 4;
|
|
6
6
|
|
|
7
|
-
export function dxfPolygon(p: Polygon, m: Material, parentPos: Vec3, parentRot: Vec3): string {
|
|
7
|
+
export function dxfPolygon(p: Polygon, m: Material, parentPos: Vec3, parentRot: Vec3, handleRef: {handle: number}): string {
|
|
8
8
|
let polygonString = "";
|
|
9
9
|
const pos = vec3TransRot(p.pos, parentPos, parentRot);
|
|
10
10
|
const rot = vec3RotCombine(parentRot, p.rot ?? vec3Zero);
|
|
@@ -12,7 +12,7 @@ export function dxfPolygon(p: Polygon, m: Material, parentPos: Vec3, parentRot:
|
|
|
12
12
|
let i = 0;
|
|
13
13
|
if (points.length >= chunkSize) {
|
|
14
14
|
for (i; i < points.length; i += chunkSize) {
|
|
15
|
-
polygonString += dxf3DFACE(points[i]!, points[i + 1]!, points[i + 2]!, points[i + 3]!, color(m.normal));
|
|
15
|
+
polygonString += dxf3DFACE(points[i]!, points[i + 1]!, points[i + 2]!, points[i + 3]!, color(m.normal), handleRef);
|
|
16
16
|
}
|
|
17
17
|
}
|
|
18
18
|
|
|
@@ -20,13 +20,13 @@ export function dxfPolygon(p: Polygon, m: Material, parentPos: Vec3, parentRot:
|
|
|
20
20
|
const lastArrayLength = points.length - i;
|
|
21
21
|
switch (lastArrayLength) {
|
|
22
22
|
case 1:
|
|
23
|
-
polygonString += dxf3DFACE(points[i - 2]!, points[i - 1]!, points[i]!, points[i]!, color(m.normal));
|
|
23
|
+
polygonString += dxf3DFACE(points[i - 2]!, points[i - 1]!, points[i]!, points[i]!, color(m.normal), handleRef);
|
|
24
24
|
break;
|
|
25
25
|
case 2:
|
|
26
|
-
polygonString += dxf3DFACE(points[i - 1]!, points[i]!, points[i + 1]!, points[i + 1]!, color(m.normal));
|
|
26
|
+
polygonString += dxf3DFACE(points[i - 1]!, points[i]!, points[i + 1]!, points[i + 1]!, color(m.normal), handleRef);
|
|
27
27
|
break;
|
|
28
28
|
case 3:
|
|
29
|
-
polygonString += dxf3DFACE(points[i]!, points[i + 1]!, points[i + 2]!, points[i + 2]!, color(m.normal));
|
|
29
|
+
polygonString += dxf3DFACE(points[i]!, points[i + 1]!, points[i + 2]!, points[i + 2]!, color(m.normal), handleRef);
|
|
30
30
|
break;
|
|
31
31
|
default:
|
|
32
32
|
break;
|
|
@@ -4,7 +4,7 @@ import { dxf3DFACE } from "../dxf-encoding.js";
|
|
|
4
4
|
|
|
5
5
|
const chunkSize = 4;
|
|
6
6
|
|
|
7
|
-
export function dxfPolygon(s: Shape, m: Material, parentPos: Vec3, parentRot: Vec3): string {
|
|
7
|
+
export function dxfPolygon(s: Shape, m: Material, parentPos: Vec3, parentRot: Vec3, handleRef: {handle: number}): string {
|
|
8
8
|
let polygonString = "";
|
|
9
9
|
const pos = vec3TransRot(s.pos, parentPos, parentRot);
|
|
10
10
|
const rot = vec3RotCombine(parentRot, s.rot ?? vec3Zero);
|
|
@@ -13,7 +13,7 @@ export function dxfPolygon(s: Shape, m: Material, parentPos: Vec3, parentRot: Ve
|
|
|
13
13
|
let i = 0;
|
|
14
14
|
if (points.length >= chunkSize) {
|
|
15
15
|
for (i; i < points.length; i += chunkSize) {
|
|
16
|
-
polygonString += dxf3DFACE(points[i]!, points[i + 1]!, points[i + 2]!, points[i + 3]!, mat);
|
|
16
|
+
polygonString += dxf3DFACE(points[i]!, points[i + 1]!, points[i + 2]!, points[i + 3]!, mat, handleRef);
|
|
17
17
|
}
|
|
18
18
|
}
|
|
19
19
|
|
|
@@ -21,13 +21,13 @@ export function dxfPolygon(s: Shape, m: Material, parentPos: Vec3, parentRot: Ve
|
|
|
21
21
|
const lastArrayLength = points.length - i;
|
|
22
22
|
switch (lastArrayLength) {
|
|
23
23
|
case 1:
|
|
24
|
-
polygonString += dxf3DFACE(points[i - 2]!, points[i - 1]!, points[i]!, points[i]!, mat);
|
|
24
|
+
polygonString += dxf3DFACE(points[i - 2]!, points[i - 1]!, points[i]!, points[i]!, mat, handleRef);
|
|
25
25
|
break;
|
|
26
26
|
case 2:
|
|
27
|
-
polygonString += dxf3DFACE(points[i - 1]!, points[i]!, points[i + 1]!, points[i + 1]!, mat);
|
|
27
|
+
polygonString += dxf3DFACE(points[i - 1]!, points[i]!, points[i + 1]!, points[i + 1]!, mat, handleRef);
|
|
28
28
|
break;
|
|
29
29
|
case 3:
|
|
30
|
-
polygonString += dxf3DFACE(points[i]!, points[i + 1]!, points[i + 2]!, points[i + 2]!, mat);
|
|
30
|
+
polygonString += dxf3DFACE(points[i]!, points[i + 1]!, points[i + 2]!, points[i + 2]!, mat, handleRef);
|
|
31
31
|
break;
|
|
32
32
|
default:
|
|
33
33
|
break;
|
package/src/renderers/dxf/dxf.ts
CHANGED
|
@@ -11,28 +11,36 @@ export const toDxf = (scene: Scene, view: View): string => {
|
|
|
11
11
|
const unitRot = vec3RotCombine(rotationForCameraPos(view), scene.rotation_deprecated ?? vec3Zero);
|
|
12
12
|
const rotatedCenter = vec3Rot(scene.center_deprecated ?? vec3Zero, vec3Zero, scene.rotation_deprecated ?? vec3Zero);
|
|
13
13
|
const [size, center] = sizeCenterForCameraPos(scene.size_deprecated, rotatedCenter, vec3Zero, 1);
|
|
14
|
-
|
|
14
|
+
const id = "D171D";
|
|
15
|
+
const handleRef = {handle: 0x1000}; //make sure we start with a value higher than any other handle id's used in the header
|
|
16
|
+
return dxfHeader(size, center, id) + scene.groups.reduce((a, c) => a + dxfGroup(c, center, unitRot, handleRef), "") + dxfFooter(id);
|
|
15
17
|
};
|
|
16
18
|
|
|
17
|
-
function dxfGroup(g: Group, parentPos: Vec3, parentRot: Vec3): string {
|
|
19
|
+
function dxfGroup(g: Group, parentPos: Vec3, parentRot: Vec3, handleRef: {handle: number}): string {
|
|
18
20
|
const pos = vec3TransRot(g.pos, parentPos, parentRot);
|
|
19
21
|
const rot = vec3RotCombine(parentRot, g.rot ?? vec3Zero);
|
|
20
22
|
return (
|
|
21
23
|
(g.meshes?.reduce((a, c) => {
|
|
22
24
|
switch (c.geometry.type) {
|
|
23
|
-
case "Plane":
|
|
24
|
-
return a + dxfPlane(c.geometry, c.material, pos, rot);
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
case "
|
|
30
|
-
return a +
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
25
|
+
case "Plane": {
|
|
26
|
+
return a + dxfPlane(c.geometry, c.material, pos, rot, handleRef);
|
|
27
|
+
}
|
|
28
|
+
case "Box": {
|
|
29
|
+
return a + dxfBox(c.geometry, c.material, pos, rot, handleRef);
|
|
30
|
+
}
|
|
31
|
+
case "Cylinder": {
|
|
32
|
+
return a + dxfCylinder(c.geometry, c.material, 18, pos, rot, handleRef);
|
|
33
|
+
}
|
|
34
|
+
case "Cone": {
|
|
35
|
+
return a + dxfCone(c.geometry, c.material, 18, pos, rot, handleRef);
|
|
36
|
+
}
|
|
37
|
+
case "Polygon": {
|
|
38
|
+
return a + dxfPolygon(c.geometry, c.material, pos, rot, handleRef);
|
|
39
|
+
}
|
|
40
|
+
default: {
|
|
34
41
|
return a;
|
|
42
|
+
}
|
|
35
43
|
}
|
|
36
|
-
}, "") ?? "") + g.groups?.reduce((a, c) => a + dxfGroup(c, pos, rot), "")
|
|
44
|
+
}, "") ?? "") + g.groups?.reduce((a, c) => a + dxfGroup(c, pos, rot, handleRef), "")
|
|
37
45
|
);
|
|
38
|
-
}
|
|
46
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
2
|
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
3
|
-
import React, { useEffect, useRef, useState } from "react";
|
|
3
|
+
import React, { useEffect, useLayoutEffect, useRef, useState } from "react";
|
|
4
4
|
import {
|
|
5
5
|
GizmoHelperProps,
|
|
6
6
|
PerspectiveCamera,
|
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
GizmoViewcube,
|
|
12
12
|
GizmoViewport,
|
|
13
13
|
} from "@react-three/drei";
|
|
14
|
-
import { ThreeEvent,
|
|
14
|
+
import { ThreeEvent, useThree } from "@react-three/fiber";
|
|
15
15
|
import { exhaustiveCheck } from "ts-exhaustive-check";
|
|
16
16
|
import { Vector3 } from "three/src/math/Vector3.js";
|
|
17
17
|
import { View, Scene, Vec3, vec3 } from "../../abstract-3d.js";
|
|
@@ -31,20 +31,6 @@ export type ControlsHelper = (Viewcube | Viewport) & { readonly props: Pick<Gizm
|
|
|
31
31
|
type Viewcube = { readonly type: "Viewcube"; readonly viewcubeProps: GenericProps };
|
|
32
32
|
type Viewport = { readonly type: "Viewport"; readonly viewportProps: GizmoViewportProps };
|
|
33
33
|
|
|
34
|
-
const ControlsWrapper = (
|
|
35
|
-
props: OrbitControlsProps & { readonly setControls: (r: React.MutableRefObject<any>) => void }
|
|
36
|
-
): React.JSX.Element => {
|
|
37
|
-
const ref = useRef<any>(undefined!);
|
|
38
|
-
|
|
39
|
-
useEffect(() => {
|
|
40
|
-
if (!ref.current) {
|
|
41
|
-
return;
|
|
42
|
-
}
|
|
43
|
-
props.setControls(ref.current);
|
|
44
|
-
}, [ref.current]);
|
|
45
|
-
return <OrbitControls {...props} makeDefault ref={ref} />;
|
|
46
|
-
};
|
|
47
|
-
|
|
48
34
|
export function ReactCamera({
|
|
49
35
|
useAnimations,
|
|
50
36
|
camera,
|
|
@@ -65,7 +51,7 @@ export function ReactCamera({
|
|
|
65
51
|
const orthographicRef = useRef<any | undefined>(undefined);
|
|
66
52
|
const viewPortAspect = useThree(({ viewport: { aspect } }) => aspect);
|
|
67
53
|
|
|
68
|
-
|
|
54
|
+
useLayoutEffect(() => {
|
|
69
55
|
const [posX, posY, posZ, size, sceneAspect] = (() => {
|
|
70
56
|
switch (view) {
|
|
71
57
|
case "front":
|
|
@@ -136,17 +122,17 @@ export function ReactCamera({
|
|
|
136
122
|
// prevScene.current = scene;
|
|
137
123
|
// }, [scene]);
|
|
138
124
|
|
|
139
|
-
useFrame(() => {
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
});
|
|
125
|
+
// useFrame(() => {
|
|
126
|
+
// if (useAnimations && camera && prevScene.current !== scene) {
|
|
127
|
+
// const [, , z] = cameraDist(scene);
|
|
128
|
+
// vector3.set(camera.position.x, camera.position.y, z);
|
|
129
|
+
// camera.position.lerp(vector3, 0.12);
|
|
130
|
+
// ref.current.enabled = false;
|
|
131
|
+
// invalidate();
|
|
132
|
+
// } else {
|
|
133
|
+
// ref.current.enabled = true;
|
|
134
|
+
// }
|
|
135
|
+
// });
|
|
150
136
|
return (
|
|
151
137
|
<>
|
|
152
138
|
<PerspectiveCamera
|
|
@@ -198,6 +184,20 @@ export function ReactCamera({
|
|
|
198
184
|
);
|
|
199
185
|
}
|
|
200
186
|
|
|
187
|
+
const ControlsWrapper = (
|
|
188
|
+
props: OrbitControlsProps & { readonly setControls: (r: React.MutableRefObject<any>) => void }
|
|
189
|
+
): React.JSX.Element => {
|
|
190
|
+
const ref = useRef<any>(undefined!);
|
|
191
|
+
|
|
192
|
+
useLayoutEffect(() => {
|
|
193
|
+
if (!ref.current) {
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
196
|
+
props.setControls(ref.current);
|
|
197
|
+
}, [ref.current]);
|
|
198
|
+
return <OrbitControls {...props} makeDefault ref={ref} />;
|
|
199
|
+
};
|
|
200
|
+
|
|
201
201
|
type GizmoViewportProps = React.JSX.IntrinsicElements["group"] & {
|
|
202
202
|
readonly axisColors?: readonly [string, string, string];
|
|
203
203
|
readonly axisScale?: readonly [number, number, number];
|
|
@@ -100,7 +100,7 @@ export function ReactHotSpot({
|
|
|
100
100
|
})}
|
|
101
101
|
>
|
|
102
102
|
<ReactMesh mesh={h.mesh}>
|
|
103
|
-
<ReactMaterial id={h.id} isText={false} material={h.mesh.material} hoveredId={hoveredId} />
|
|
103
|
+
<ReactMaterial id={h.id} isText={false} isHotSpot={true} material={h.mesh.material} hoveredId={hoveredId} />
|
|
104
104
|
</ReactMesh>
|
|
105
105
|
</group>
|
|
106
106
|
{hotSpotTexts && text && (
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React from "react";
|
|
1
|
+
import React, { useEffect } from "react";
|
|
2
2
|
import { suspend } from "suspend-react";
|
|
3
3
|
import { Color, DoubleSide, MaterialParameters, SRGBColorSpace, Texture, TextureLoader } from "three";
|
|
4
4
|
import { Material } from "../../abstract-3d.js";
|
|
@@ -18,6 +18,7 @@ export function ReactMaterial({
|
|
|
18
18
|
materialStateImages,
|
|
19
19
|
state,
|
|
20
20
|
isText,
|
|
21
|
+
isHotSpot,
|
|
21
22
|
}: {
|
|
22
23
|
readonly material: Material;
|
|
23
24
|
readonly id?: string;
|
|
@@ -27,6 +28,7 @@ export function ReactMaterial({
|
|
|
27
28
|
readonly materialStateImages?: Record<string, string>;
|
|
28
29
|
readonly state?: MaterialState | undefined;
|
|
29
30
|
readonly isText: boolean;
|
|
31
|
+
readonly isHotSpot?: boolean;
|
|
30
32
|
}): React.JSX.Element {
|
|
31
33
|
const mat =
|
|
32
34
|
!state || material.image?.type === "UrlImage"
|
|
@@ -70,7 +72,7 @@ export function ReactMaterial({
|
|
|
70
72
|
roughness={mat.roughness}
|
|
71
73
|
metalness={mat.metalness}
|
|
72
74
|
side={DoubleSide}
|
|
73
|
-
{...(opacity < 1 || disabled
|
|
75
|
+
{...((opacity < 1 || disabled) && !isHotSpot
|
|
74
76
|
? { transparent: true, opacity: disabled ? opacity * decreasedOpacity : opacity }
|
|
75
77
|
: materialDefaults)}
|
|
76
78
|
/>
|
|
@@ -101,6 +103,14 @@ function TextureMaterial({
|
|
|
101
103
|
[url]
|
|
102
104
|
) as Texture | null;
|
|
103
105
|
|
|
106
|
+
useEffect(() => {
|
|
107
|
+
return () => {
|
|
108
|
+
if (texture) {
|
|
109
|
+
texture.dispose();
|
|
110
|
+
}
|
|
111
|
+
};
|
|
112
|
+
}, [texture]);
|
|
113
|
+
|
|
104
114
|
return (
|
|
105
115
|
<meshBasicMaterial
|
|
106
116
|
color={color}
|
|
@@ -5,8 +5,6 @@ import { ReactDimensions } from "./react-dimension.js";
|
|
|
5
5
|
import { ReactGroup } from "./react-group.js";
|
|
6
6
|
import { MaterialState } from "./react-material.js";
|
|
7
7
|
|
|
8
|
-
// dummy 2
|
|
9
|
-
|
|
10
8
|
export function ReactScene({
|
|
11
9
|
scene,
|
|
12
10
|
selectedId,
|
|
@@ -66,7 +64,7 @@ export function ReactScene({
|
|
|
66
64
|
const id = createGroupId ? createGroupId(g) : "";
|
|
67
65
|
return (
|
|
68
66
|
<ReactGroup
|
|
69
|
-
key={createGroupKey ? createGroupKey(g,
|
|
67
|
+
key={createGroupKey ? createGroupKey(g, 0, g.data, id) : i}
|
|
70
68
|
g={g}
|
|
71
69
|
selectedId={selectedId}
|
|
72
70
|
hotSpotsActive={activeHotSpots !== undefined}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import { Vec2, vec2Add, vec2Scale } from "../../abstract-3d.js";
|
|
1
|
+
import { vec2, Vec2, vec2Add, vec2Scale } from "../../abstract-3d.js";
|
|
2
2
|
|
|
3
|
-
export const svg = (width: number, height: number, children: string): string =>
|
|
4
|
-
`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 ${width.toFixed(0)} ${height.toFixed(
|
|
3
|
+
export const svg = (width: number, height: number, children: string): string => {
|
|
4
|
+
return `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 ${width.toFixed(0)} ${height.toFixed(
|
|
5
5
|
0
|
|
6
6
|
)}" width="${width.toFixed(0)}px" height="${height.toFixed(0)}px">${children} </svg>`;
|
|
7
|
+
};
|
|
7
8
|
|
|
8
9
|
export const svgLine = (p1: Vec2, p2: Vec2, stroke: string, strokeWidth: number): string =>
|
|
9
10
|
`<line x1="${p1.x.toFixed(0)}" y1="${p1.y.toFixed(0)}" x2="${p2.x.toFixed(0)}" y2="${p2.y.toFixed(
|
|
@@ -30,16 +31,17 @@ export type EmbededImage =
|
|
|
30
31
|
| { readonly type: "svg"; readonly svg: string };
|
|
31
32
|
|
|
32
33
|
export const svgImage = (p: Vec2, size: Vec2, rot: number, data: EmbededImage): string => {
|
|
34
|
+
const rad = rot * (Math.PI / 180);
|
|
35
|
+
const cos = Math.abs(Math.cos(rad));
|
|
36
|
+
const sin = Math.abs(Math.sin(rad));
|
|
37
|
+
const newSize = vec2(size.x * cos + size.y * sin, size.x * sin + size.y * cos);
|
|
33
38
|
const half = vec2Scale(size, 0.5);
|
|
39
|
+
const originalCenter = vec2(size.x / 2, size.y / 2);
|
|
40
|
+
const rotatedCenter = vec2(newSize.x / 2, newSize.y / 2);
|
|
41
|
+
const rotatatedTranslationDelta = vec2(originalCenter.x - rotatedCenter.x, originalCenter.y - rotatedCenter.y);
|
|
34
42
|
return data.type === "url"
|
|
35
|
-
|
|
36
|
-
p,
|
|
37
|
-
half
|
|
38
|
-
)} width="${size.x.toFixed(0)}" height="${size.y.toFixed(0)}" href="${data.url}" />`
|
|
39
|
-
: `<svg width="${size.x.toFixed(0)}" height="${size.y.toFixed(0)}" transform="${translate(
|
|
40
|
-
vec2Add(p, half)
|
|
41
|
-
)} ${rotate(rot)} ${translate(vec2Scale(half, -1))}">${data.svg}</svg>
|
|
42
|
-
|
|
43
|
+
? `<image x="${p.x.toFixed(0)}" y="${p.y.toFixed(0)}" transform="${rotate(rot)}" ${transformOrigin(p, half)} width="${size.x.toFixed(0)}" height="${size.y.toFixed(0)}" href="${data.url}" />`
|
|
44
|
+
: `<svg width="${newSize.x.toFixed(0)}" height="${newSize.y.toFixed(0)}" transform="${translate(p)} ${rotateAtPos(rot, half)} ${translate(rotatatedTranslationDelta)}">${data.svg}</svg>
|
|
43
45
|
`;
|
|
44
46
|
};
|
|
45
47
|
|
|
@@ -47,5 +49,5 @@ const transformOrigin = (p: Vec2, half: Vec2): string =>
|
|
|
47
49
|
`transform-origin="${(p.x + half.x).toFixed(0)}px ${(p.y + half.y).toFixed(0)}px"`;
|
|
48
50
|
|
|
49
51
|
const rotate = (rot: number): string => `rotate(${rot.toFixed(0)})`;
|
|
50
|
-
|
|
52
|
+
const rotateAtPos = (rot: number, p: Vec2): string => `rotate(${rot.toFixed(0)}, ${p.x.toFixed(0)}, ${p.y.toFixed(0)})`;
|
|
51
53
|
const translate = (p: Vec2): string => `translate(${p.x.toFixed(0)}, ${p.y.toFixed(0)})`;
|
package/src/renderers/svg/svg.ts
CHANGED
|
@@ -26,6 +26,8 @@ import { cone } from "./svg-geometries/svg-cone.js";
|
|
|
26
26
|
import { rotationForCameraPos, sizeCenterForCameraPos } from "../shared.js";
|
|
27
27
|
import { EmbededImage, svg } from "./svg-encoding.js";
|
|
28
28
|
|
|
29
|
+
// dummy
|
|
30
|
+
|
|
29
31
|
export function toSvg(
|
|
30
32
|
scene: Scene,
|
|
31
33
|
view: View,
|
|
@@ -35,7 +37,8 @@ export function toSvg(
|
|
|
35
37
|
grayScale?: boolean,
|
|
36
38
|
onlyStrokeFill: string = "rgba(255,255,255,0)",
|
|
37
39
|
font: string = "",
|
|
38
|
-
buffers?: Record<string, string
|
|
40
|
+
buffers?: Record<string, string>,
|
|
41
|
+
rotation?: number
|
|
39
42
|
): { readonly image: string; readonly width: number; readonly height: number } {
|
|
40
43
|
const factor = scale
|
|
41
44
|
? scale.size /
|
|
@@ -47,7 +50,9 @@ export function toSvg(
|
|
|
47
50
|
? scene.size_deprecated.z
|
|
48
51
|
: scene.size_deprecated.y)
|
|
49
52
|
: 1;
|
|
50
|
-
const
|
|
53
|
+
const baseRot = vec3RotCombine(rotationForCameraPos(view), scene.rotation_deprecated ?? vec3Zero);
|
|
54
|
+
const unitRot = rotation ? vec3RotCombine(vec3(0, 0, (rotation * Math.PI) / 180), baseRot) : baseRot;
|
|
55
|
+
|
|
51
56
|
const unitPos = vec3Rot(scene.center_deprecated ?? vec3Zero, vec3Zero, scene.rotation_deprecated ?? vec3Zero);
|
|
52
57
|
const [size, center] = sizeCenterForCameraPos(scene.size_deprecated, unitPos, unitRot, factor);
|
|
53
58
|
const unitHalfSize = vec3Scale(size, 0.5);
|