abstract-3d 2.7.2 → 2.7.4
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 +4 -0
- package/lib/abstract-3d.d.ts +15 -1
- package/lib/abstract-3d.d.ts.map +1 -1
- package/lib/abstract-3d.js +22 -8
- package/lib/abstract-3d.js.map +1 -1
- package/lib/renderers/dxf/dxf.d.ts.map +1 -1
- package/lib/renderers/dxf/dxf.js +0 -10
- package/lib/renderers/dxf/dxf.js.map +1 -1
- package/lib/renderers/react/react-dimension.d.ts +2 -2
- package/lib/renderers/react/react-dimension.d.ts.map +1 -1
- package/lib/renderers/react/react-dimension.js +5 -20
- package/lib/renderers/react/react-dimension.js.map +1 -1
- package/lib/renderers/react/react-mesh.d.ts.map +1 -1
- package/lib/renderers/react/react-mesh.js +117 -3
- package/lib/renderers/react/react-mesh.js.map +1 -1
- package/lib/renderers/svg/svg-encoding.d.ts.map +1 -1
- package/lib/renderers/svg/svg-encoding.js +2 -1
- package/lib/renderers/svg/svg-encoding.js.map +1 -1
- package/lib/renderers/svg/svg-geometries/svg-line.d.ts +2 -2
- package/lib/renderers/svg/svg-geometries/svg-line.d.ts.map +1 -1
- package/lib/renderers/svg/svg-geometries/svg-line.js.map +1 -1
- package/lib/renderers/svg/svg.js +1 -0
- package/lib/renderers/svg/svg.js.map +1 -1
- package/package.json +2 -2
- package/src/abstract-3d.ts +38 -10
- package/src/renderers/dxf/dxf.ts +0 -10
- package/src/renderers/react/react-dimension.tsx +10 -24
- package/src/renderers/react/react-mesh.tsx +141 -2
- package/src/renderers/svg/svg-encoding.ts +2 -1
- package/src/renderers/svg/svg-geometries/svg-line.ts +2 -2
- package/src/renderers/svg/svg.ts +1 -0
|
@@ -1,21 +1,26 @@
|
|
|
1
|
-
import React from "react";
|
|
2
|
-
import { extend } from "@react-three/fiber";
|
|
1
|
+
import React, { useMemo } from "react";
|
|
2
|
+
import { extend, useThree } from "@react-three/fiber";
|
|
3
3
|
import { Text, Line } from "@react-three/drei";
|
|
4
4
|
import {
|
|
5
5
|
BoxGeometry,
|
|
6
6
|
BufferAttribute,
|
|
7
|
+
BufferGeometry,
|
|
7
8
|
CatmullRomCurve3,
|
|
9
|
+
Color,
|
|
8
10
|
ConeGeometry,
|
|
9
11
|
Curve,
|
|
10
12
|
CylinderGeometry,
|
|
11
13
|
Euler,
|
|
12
14
|
ExtrudeGeometry,
|
|
15
|
+
Float32BufferAttribute,
|
|
16
|
+
FrontSide,
|
|
13
17
|
Path,
|
|
14
18
|
PlaneGeometry,
|
|
15
19
|
Quaternion,
|
|
16
20
|
Shape,
|
|
17
21
|
SphereGeometry,
|
|
18
22
|
TubeGeometry,
|
|
23
|
+
Vector2,
|
|
19
24
|
Vector3,
|
|
20
25
|
} from "three";
|
|
21
26
|
import {
|
|
@@ -78,6 +83,31 @@ export function ReactMesh({
|
|
|
78
83
|
readonly mesh: Mesh;
|
|
79
84
|
readonly children?: React.JSX.Element;
|
|
80
85
|
}): React.JSX.Element {
|
|
86
|
+
const culledLineGeometry = useMemo(() => {
|
|
87
|
+
const g = new BufferGeometry();
|
|
88
|
+
|
|
89
|
+
g.setAttribute(
|
|
90
|
+
"position",
|
|
91
|
+
new Float32BufferAttribute(
|
|
92
|
+
[
|
|
93
|
+
0, -1, 0,
|
|
94
|
+
0, 1, 0,
|
|
95
|
+
1, -1, 0,
|
|
96
|
+
1, 1, 0,
|
|
97
|
+
],
|
|
98
|
+
3
|
|
99
|
+
)
|
|
100
|
+
);
|
|
101
|
+
|
|
102
|
+
g.setIndex([
|
|
103
|
+
0, 2, 1,
|
|
104
|
+
2, 3, 1,
|
|
105
|
+
]);
|
|
106
|
+
|
|
107
|
+
return g;
|
|
108
|
+
}, []);
|
|
109
|
+
const { camera, size } = useThree();
|
|
110
|
+
|
|
81
111
|
switch (mesh.geometry.type) {
|
|
82
112
|
case "Box": {
|
|
83
113
|
const { pos, size, rot, holes } = mesh.geometry;
|
|
@@ -268,6 +298,27 @@ export function ReactMesh({
|
|
|
268
298
|
</Line>
|
|
269
299
|
);
|
|
270
300
|
}
|
|
301
|
+
case "CulledLine": {
|
|
302
|
+
const { start, end, normal, thickness } = mesh.geometry;
|
|
303
|
+
const color = mesh.material.normal;
|
|
304
|
+
|
|
305
|
+
return <mesh geometry={culledLineGeometry} frustumCulled={false}>
|
|
306
|
+
<shaderMaterial
|
|
307
|
+
side={FrontSide}
|
|
308
|
+
uniforms={{
|
|
309
|
+
lineStart: { value: new Vector3(start.x, start.y, start.z) },
|
|
310
|
+
lineEnd: { value: new Vector3(end.x, end.y, end.z) },
|
|
311
|
+
lineNormal: { value: new Vector3(normal.x, normal.y, normal.z) },
|
|
312
|
+
thickness: { value: thickness },
|
|
313
|
+
viewport: { value: new Vector2(size.width, size.height) },
|
|
314
|
+
nearPlane: { value: camera.near },
|
|
315
|
+
color: { value: new Color(color) },
|
|
316
|
+
}}
|
|
317
|
+
vertexShader={culledLineVertexShader}
|
|
318
|
+
fragmentShader={culledLineFragmentShader}
|
|
319
|
+
/>
|
|
320
|
+
</mesh>;
|
|
321
|
+
}
|
|
271
322
|
case "Polygon":
|
|
272
323
|
return <Polygon polygon={mesh.geometry}>{children}</Polygon>;
|
|
273
324
|
case "Tube":
|
|
@@ -517,3 +568,91 @@ class CircleCurve extends Curve<Vector3> {
|
|
|
517
568
|
);
|
|
518
569
|
}
|
|
519
570
|
}
|
|
571
|
+
|
|
572
|
+
const culledLineVertexShader = `
|
|
573
|
+
uniform vec3 lineStart;
|
|
574
|
+
uniform vec3 lineEnd;
|
|
575
|
+
uniform vec3 lineNormal;
|
|
576
|
+
|
|
577
|
+
uniform float thickness;
|
|
578
|
+
uniform float nearPlane;
|
|
579
|
+
uniform vec2 viewport;
|
|
580
|
+
|
|
581
|
+
void main() {
|
|
582
|
+
vec3 a = (modelViewMatrix * vec4(lineStart, 1.0)).xyz;
|
|
583
|
+
vec3 b = (modelViewMatrix * vec4(lineEnd, 1.0)).xyz;
|
|
584
|
+
|
|
585
|
+
vec3 n = normalize(mat3(modelViewMatrix) * lineNormal);
|
|
586
|
+
|
|
587
|
+
// camera is at (0,0,0) in view space.
|
|
588
|
+
vec3 mid = (a + b) * 0.5;
|
|
589
|
+
vec3 toCamera = normalize(-mid);
|
|
590
|
+
|
|
591
|
+
bool frontFacing = dot(n, toCamera) > 0.0;
|
|
592
|
+
|
|
593
|
+
if(!frontFacing) {
|
|
594
|
+
// collapse all 4 vertices to one point.
|
|
595
|
+
gl_Position = vec4(0.0);
|
|
596
|
+
return;
|
|
597
|
+
}
|
|
598
|
+
|
|
599
|
+
// ---- near-plane clipping ----
|
|
600
|
+
|
|
601
|
+
float nearZ = -nearPlane;
|
|
602
|
+
|
|
603
|
+
bool aBehind = a.z > nearZ;
|
|
604
|
+
bool bBehind = b.z > nearZ;
|
|
605
|
+
|
|
606
|
+
if(aBehind && bBehind) {
|
|
607
|
+
gl_Position = vec4(0.0);
|
|
608
|
+
return;
|
|
609
|
+
}
|
|
610
|
+
|
|
611
|
+
if(aBehind) {
|
|
612
|
+
float t = (nearZ - a.z) / (b.z - a.z);
|
|
613
|
+
a = mix(a, b, t);
|
|
614
|
+
}
|
|
615
|
+
|
|
616
|
+
if(bBehind) {
|
|
617
|
+
float t = (nearZ - b.z) / (a.z - b.z);
|
|
618
|
+
b = mix(b, a, t);
|
|
619
|
+
}
|
|
620
|
+
|
|
621
|
+
vec4 ca = projectionMatrix * vec4(a, 1.0);
|
|
622
|
+
vec4 cb = projectionMatrix * vec4(b, 1.0);
|
|
623
|
+
|
|
624
|
+
vec2 aNdc = ca.xy / ca.w;
|
|
625
|
+
vec2 bNdc = cb.xy / cb.w;
|
|
626
|
+
|
|
627
|
+
vec2 aPx = aNdc * viewport * 0.5;
|
|
628
|
+
vec2 bPx = bNdc * viewport * 0.5;
|
|
629
|
+
|
|
630
|
+
vec2 delta = bPx - aPx;
|
|
631
|
+
float len = length(delta);
|
|
632
|
+
|
|
633
|
+
if(len < 0.0001) {
|
|
634
|
+
gl_Position = vec4(0.0);
|
|
635
|
+
return;
|
|
636
|
+
}
|
|
637
|
+
|
|
638
|
+
vec2 dir = delta / len;
|
|
639
|
+
vec2 perp = vec2(-dir.y, dir.x);
|
|
640
|
+
|
|
641
|
+
float endpoint = position.x;
|
|
642
|
+
float side = position.y;
|
|
643
|
+
|
|
644
|
+
vec4 clip = mix(ca, cb, endpoint);
|
|
645
|
+
|
|
646
|
+
vec2 offsetNdc = perp * side * (thickness * 0.5) * (2.0 / viewport);
|
|
647
|
+
clip.xy += offsetNdc * clip.w;
|
|
648
|
+
gl_Position = clip;
|
|
649
|
+
}
|
|
650
|
+
`;
|
|
651
|
+
|
|
652
|
+
const culledLineFragmentShader = `
|
|
653
|
+
uniform vec3 color;
|
|
654
|
+
|
|
655
|
+
void main() {
|
|
656
|
+
gl_FragColor = vec4(color, 1.0);
|
|
657
|
+
}
|
|
658
|
+
`;
|
|
@@ -168,7 +168,7 @@ function svgMaskHoles(rot: Vec3, size: Vec2, holes: ReadonlyArray<Hole>): string
|
|
|
168
168
|
);
|
|
169
169
|
break;
|
|
170
170
|
}
|
|
171
|
-
case "SquareHole":
|
|
171
|
+
case "SquareHole": {
|
|
172
172
|
const holeSizeRotated = vec3Rot(vec3(hole.size.x, hole.size.y, 0), vec3Zero, rot);
|
|
173
173
|
const holeSize = vec2(Math.abs(holeSizeRotated.x), Math.abs(holeSizeRotated.y));
|
|
174
174
|
const halfSize = vec2Scale(holeSize, 0.5);
|
|
@@ -178,6 +178,7 @@ function svgMaskHoles(rot: Vec3, size: Vec2, holes: ReadonlyArray<Hole>): string
|
|
|
178
178
|
}" height="${holeSize.y / size.y}" fill="black" />`
|
|
179
179
|
);
|
|
180
180
|
break;
|
|
181
|
+
}
|
|
181
182
|
default:
|
|
182
183
|
break;
|
|
183
184
|
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { Line, Vec2, Vec3, vec3TransRot, vec3ZMean } from "../../../abstract-3d.js";
|
|
1
|
+
import { CulledLine, Line, Vec2, Vec3, vec3TransRot, vec3ZMean } from "../../../abstract-3d.js";
|
|
2
2
|
import { SvgOptions, zElem, zOrderElement } from "./shared.js";
|
|
3
3
|
import { svgLine } from "../svg-encoding.js";
|
|
4
4
|
import { rgbGrayScale } from "../../../utils.js";
|
|
5
5
|
|
|
6
6
|
export function line(
|
|
7
|
-
l: Line,
|
|
7
|
+
l: Line | CulledLine,
|
|
8
8
|
point: (x: number, y: number) => Vec2,
|
|
9
9
|
fill: string,
|
|
10
10
|
opts: SvgOptions,
|
package/src/renderers/svg/svg.ts
CHANGED
|
@@ -165,6 +165,7 @@ function svgMesh(
|
|
|
165
165
|
return cylinder(mesh.geometry, point, material, opts, parentPos, parentRot);
|
|
166
166
|
case "Cone":
|
|
167
167
|
return cone(mesh.geometry, point, material, opts, parentPos, parentRot);
|
|
168
|
+
case "CulledLine":
|
|
168
169
|
case "Line":
|
|
169
170
|
return line(mesh.geometry, point, material.normal, opts, parentPos, parentRot);
|
|
170
171
|
case "Polygon":
|