@woosh/meep-engine 2.33.25 → 2.33.26
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/core/geom/3d/shape/AbstractShape3D.js +28 -1
- package/core/geom/3d/shape/TransformedShape3D.js +65 -10
- package/core/geom/3d/shape/TransformedShape3D.spec.js +33 -0
- package/core/geom/3d/shape/{CompositeShape.js → UnionShape3D.js} +27 -12
- package/core/geom/3d/shape/UnitCubeShape3D.js +77 -0
- package/core/geom/3d/shape/UnitCubeShape3D.spec.js +42 -0
- package/core/geom/3d/shape/UnitSphereShape3D.js +32 -1
- package/core/geom/3d/shape/util/compute_signed_distance_gradient_by_sampling.js +48 -0
- package/core/geom/3d/shape/util/shape_to_visual_entity.js +3 -3
- package/engine/graphics/ecs/highlight/plugin/OutlineRenderPlugin.js +2 -2
- package/engine/graphics/particles/particular/engine/utils/volume/prototypeParticleVolume.js +7 -7
- package/engine/graphics/shadows/ShadowMapRenderer.js +8 -2
- package/package.json +1 -1
|
@@ -1,5 +1,31 @@
|
|
|
1
1
|
export class AbstractShape3D {
|
|
2
|
-
|
|
2
|
+
/**
|
|
3
|
+
* Signed distance to boundary of the shape from the given point
|
|
4
|
+
* @param {number[]} point
|
|
5
|
+
* @returns {number}
|
|
6
|
+
*/
|
|
7
|
+
signed_distance_at_point(point) {
|
|
8
|
+
throw new Error('Not Implemented');
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Samples both distances as well as the gradient
|
|
13
|
+
* @param {number[]} result resulting gradient is written here
|
|
14
|
+
* @param {number[]} point sampling point
|
|
15
|
+
* @returns {number}
|
|
16
|
+
*/
|
|
17
|
+
signed_distance_gradient_at_point(result, point) {
|
|
18
|
+
throw new Error('Not Implemented');
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
*
|
|
23
|
+
* @param {number[]} result where the resulting point is stored
|
|
24
|
+
* @param {number[]} reference reference point from which to go
|
|
25
|
+
* @returns {void}
|
|
26
|
+
*/
|
|
27
|
+
nearest_point_on_surface(result, reference) {
|
|
28
|
+
throw new Error('Not Implemented');
|
|
3
29
|
}
|
|
4
30
|
|
|
5
31
|
/**
|
|
@@ -7,6 +33,7 @@ export class AbstractShape3D {
|
|
|
7
33
|
* @param {number[]} result
|
|
8
34
|
* @param {number} result_offset
|
|
9
35
|
* @param {function} random
|
|
36
|
+
* @returns {void}
|
|
10
37
|
*/
|
|
11
38
|
sample_random_point_in_volume(result, result_offset, random) {
|
|
12
39
|
throw new Error('Not Implemented');
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { mat4, vec3 } from "gl-matrix";
|
|
2
2
|
import { AbstractShape3D } from "./AbstractShape3D.js";
|
|
3
|
+
import { sign } from "../../../math/sign.js";
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
6
|
*
|
|
6
7
|
* @type {number[]|Float32Array|vec3}
|
|
7
8
|
*/
|
|
8
|
-
const
|
|
9
|
+
const scratch_v3_0 = [];
|
|
9
10
|
|
|
10
11
|
export class TransformedShape3D extends AbstractShape3D {
|
|
11
12
|
constructor() {
|
|
@@ -98,29 +99,83 @@ export class TransformedShape3D extends AbstractShape3D {
|
|
|
98
99
|
}
|
|
99
100
|
|
|
100
101
|
get volume() {
|
|
101
|
-
mat4.getScaling(
|
|
102
|
+
mat4.getScaling(scratch_v3_0, this.__matrix);
|
|
102
103
|
|
|
103
|
-
const scale_modifier =
|
|
104
|
+
const scale_modifier = scratch_v3_0[0] * scratch_v3_0[1] * scratch_v3_0[2];
|
|
104
105
|
|
|
105
106
|
return this.__subject.volume * scale_modifier;
|
|
106
107
|
}
|
|
107
108
|
|
|
109
|
+
signed_distance_gradient_at_point(result, point) {
|
|
110
|
+
// transform point to subject's local space
|
|
111
|
+
vec3.transformMat4(scratch_v3_0, point, this.__inverse_matrix);
|
|
112
|
+
|
|
113
|
+
const subject = this.__subject;
|
|
114
|
+
|
|
115
|
+
// sample gradient at the point
|
|
116
|
+
const distance = subject.signed_distance_gradient_at_point(scratch_v3_0, scratch_v3_0);
|
|
117
|
+
|
|
118
|
+
const m = this.__matrix;
|
|
119
|
+
|
|
120
|
+
const m11 = m[0];
|
|
121
|
+
const m12 = m[1];
|
|
122
|
+
const m13 = m[2];
|
|
123
|
+
|
|
124
|
+
const m21 = m[4];
|
|
125
|
+
const m22 = m[5];
|
|
126
|
+
const m23 = m[6];
|
|
127
|
+
|
|
128
|
+
const m31 = m[8];
|
|
129
|
+
const m32 = m[9];
|
|
130
|
+
const m33 = m[10];
|
|
131
|
+
|
|
132
|
+
const scale_x = Math.hypot(m11, m12, m13);
|
|
133
|
+
const scale_y = Math.hypot(m21, m22, m23);
|
|
134
|
+
const scale_z = Math.hypot(m31, m32, m33);
|
|
135
|
+
|
|
136
|
+
const scaled_gx = scratch_v3_0[0] * scale_x;
|
|
137
|
+
const scaled_gy = scratch_v3_0[1] * scale_y;
|
|
138
|
+
const scaled_gz = scratch_v3_0[2] * scale_z;
|
|
139
|
+
|
|
140
|
+
// normalize gradient
|
|
141
|
+
const gd = distance / Math.hypot(scratch_v3_0[0], scratch_v3_0[1], scratch_v3_0[2]);
|
|
142
|
+
|
|
143
|
+
const scaled_dx = scaled_gx * gd ;
|
|
144
|
+
const scaled_dy = scaled_gy * gd ;
|
|
145
|
+
const scaled_dz = scaled_gz * gd ;
|
|
146
|
+
|
|
147
|
+
// determine sign
|
|
148
|
+
const result_sign = sign(distance);
|
|
149
|
+
|
|
150
|
+
const scaled_distance = result_sign * Math.sqrt(scaled_dx * scaled_dx + scaled_dy * scaled_dy + scaled_dz * scaled_dz);
|
|
151
|
+
|
|
152
|
+
result[0] = scaled_gx;
|
|
153
|
+
result[1] = scaled_gy;
|
|
154
|
+
result[2] = scaled_gz;
|
|
155
|
+
|
|
156
|
+
return scaled_distance;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
signed_distance_at_point(point) {
|
|
160
|
+
return this.signed_distance_gradient_at_point(scratch_v3_0, point);
|
|
161
|
+
}
|
|
162
|
+
|
|
108
163
|
contains_point(point) {
|
|
109
164
|
// transform point to subject's local space
|
|
110
|
-
vec3.transformMat4(
|
|
165
|
+
vec3.transformMat4(scratch_v3_0, point, this.__inverse_matrix);
|
|
111
166
|
|
|
112
|
-
return this.__subject.contains_point(
|
|
167
|
+
return this.__subject.contains_point(scratch_v3_0);
|
|
113
168
|
}
|
|
114
169
|
|
|
115
170
|
sample_random_point_in_volume(result, result_offset, random) {
|
|
116
|
-
this.__subject.sample_random_point_in_volume(
|
|
171
|
+
this.__subject.sample_random_point_in_volume(scratch_v3_0, 0, random);
|
|
117
172
|
|
|
118
173
|
// apply transform
|
|
119
|
-
vec3.transformMat4(
|
|
174
|
+
vec3.transformMat4(scratch_v3_0, scratch_v3_0, this.__matrix);
|
|
120
175
|
|
|
121
176
|
// write out
|
|
122
|
-
result[0] =
|
|
123
|
-
result[1] =
|
|
124
|
-
result[2] =
|
|
177
|
+
result[0] = scratch_v3_0[0];
|
|
178
|
+
result[1] = scratch_v3_0[1];
|
|
179
|
+
result[2] = scratch_v3_0[2];
|
|
125
180
|
}
|
|
126
181
|
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { UnitCubeShape3D } from "./UnitCubeShape3D.js";
|
|
2
|
+
import { TransformedShape3D } from "./TransformedShape3D.js";
|
|
3
|
+
|
|
4
|
+
test('signed distance identity transform', () => {
|
|
5
|
+
|
|
6
|
+
const s = TransformedShape3D.from_translation_scale(new UnitCubeShape3D(), [0, 0, 0], [1, 1, 1]);
|
|
7
|
+
|
|
8
|
+
expect(s.signed_distance_at_point([0, 0, 0])).toBeCloseTo(-0.5);
|
|
9
|
+
|
|
10
|
+
expect(s.signed_distance_at_point([1, 0, 0])).toBeCloseTo(0.5);
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
test('signed distance translation', () => {
|
|
14
|
+
|
|
15
|
+
const s = TransformedShape3D.from_translation_scale(new UnitCubeShape3D(), [1, 0, 0], [1, 1, 1]);
|
|
16
|
+
|
|
17
|
+
expect(s.signed_distance_at_point([0, 0, 0])).toBeCloseTo(0.5);
|
|
18
|
+
|
|
19
|
+
expect(s.signed_distance_at_point([-1, 0, 0])).toBeCloseTo(1.5);
|
|
20
|
+
|
|
21
|
+
expect(s.signed_distance_at_point([1, 0, 0])).toBeCloseTo(-0.5);
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
test('signed distance scale', () => {
|
|
25
|
+
|
|
26
|
+
const s = TransformedShape3D.from_translation_scale(new UnitCubeShape3D(), [0, 0, 0], [2, 2, 2]);
|
|
27
|
+
|
|
28
|
+
expect(s.signed_distance_at_point([0, 0, 0])).toBeCloseTo(-1);
|
|
29
|
+
|
|
30
|
+
expect(s.signed_distance_at_point([1, 0, 0])).toBeCloseTo(0);
|
|
31
|
+
|
|
32
|
+
expect(s.signed_distance_at_point([2, 0, 0])).toBeCloseTo(1);
|
|
33
|
+
});
|
|
@@ -2,6 +2,8 @@ import { AbstractShape3D } from "./AbstractShape3D.js";
|
|
|
2
2
|
import { seededRandom } from "../../../math/random/seededRandom.js";
|
|
3
3
|
import { binarySearchHighIndex } from "../../../collection/array/binarySearchHighIndex.js";
|
|
4
4
|
import { compareNumbers } from "../../../primitives/numbers/compareNumbers.js";
|
|
5
|
+
import { min2 } from "../../../math/min2.js";
|
|
6
|
+
import { compute_signed_distance_gradient_by_sampling } from "./util/compute_signed_distance_gradient_by_sampling.js";
|
|
5
7
|
|
|
6
8
|
/**
|
|
7
9
|
* To avoid severe performance overhead, we limit number of possible rejections
|
|
@@ -18,16 +20,7 @@ const VOLUME_OVERLAP_ESTIMATION_SUB_TAPS = 4;
|
|
|
18
20
|
|
|
19
21
|
const scratch_array = [];
|
|
20
22
|
|
|
21
|
-
|
|
22
|
-
*
|
|
23
|
-
* @param {AbstractShape3D} shape
|
|
24
|
-
* @return {number}
|
|
25
|
-
*/
|
|
26
|
-
function getVolume(shape) {
|
|
27
|
-
return shape.volume;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
export class CompositeShape3D extends AbstractShape3D {
|
|
23
|
+
export class UnionShape3D extends AbstractShape3D {
|
|
31
24
|
constructor() {
|
|
32
25
|
super();
|
|
33
26
|
|
|
@@ -50,6 +43,10 @@ export class CompositeShape3D extends AbstractShape3D {
|
|
|
50
43
|
this.__child_volumes = [];
|
|
51
44
|
}
|
|
52
45
|
|
|
46
|
+
/**
|
|
47
|
+
*
|
|
48
|
+
* @private
|
|
49
|
+
*/
|
|
53
50
|
__compute_volume_variables() {
|
|
54
51
|
this.__volume_sum = 0;
|
|
55
52
|
|
|
@@ -123,7 +120,7 @@ export class CompositeShape3D extends AbstractShape3D {
|
|
|
123
120
|
}
|
|
124
121
|
|
|
125
122
|
static from(children) {
|
|
126
|
-
const r = new
|
|
123
|
+
const r = new UnionShape3D();
|
|
127
124
|
|
|
128
125
|
r.children = children;
|
|
129
126
|
|
|
@@ -169,6 +166,25 @@ export class CompositeShape3D extends AbstractShape3D {
|
|
|
169
166
|
return r;
|
|
170
167
|
}
|
|
171
168
|
|
|
169
|
+
signed_distance_gradient_at_point(result, point) {
|
|
170
|
+
return compute_signed_distance_gradient_by_sampling(result, this, point);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
signed_distance_at_point(point) {
|
|
174
|
+
let r = Infinity;
|
|
175
|
+
|
|
176
|
+
const children = this.children;
|
|
177
|
+
const child_count = children.length;
|
|
178
|
+
|
|
179
|
+
for (let i = 0; i < child_count; i++) {
|
|
180
|
+
const child = children[i];
|
|
181
|
+
|
|
182
|
+
r = min2(child.signed_distance_at_point(point), r);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
return r;
|
|
186
|
+
}
|
|
187
|
+
|
|
172
188
|
contains_point(point) {
|
|
173
189
|
const children = this.children;
|
|
174
190
|
const n = children.length;
|
|
@@ -183,7 +199,6 @@ export class CompositeShape3D extends AbstractShape3D {
|
|
|
183
199
|
return false;
|
|
184
200
|
}
|
|
185
201
|
|
|
186
|
-
|
|
187
202
|
sample_random_point_in_volume(result, result_offset, random) {
|
|
188
203
|
const children = this.children;
|
|
189
204
|
const child_count = children.length;
|
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
import { AbstractShape3D } from "./AbstractShape3D.js";
|
|
2
2
|
import { randomPointInBox } from "../../random/randomPointInBox.js";
|
|
3
|
+
import { v3_length } from "../../v3_length.js";
|
|
4
|
+
import { max2 } from "../../../math/max2.js";
|
|
5
|
+
import { max3 } from "../../../math/max3.js";
|
|
6
|
+
import { min2 } from "../../../math/min2.js";
|
|
7
|
+
import { clamp } from "../../../math/clamp.js";
|
|
8
|
+
import { compute_signed_distance_gradient_by_sampling } from "./util/compute_signed_distance_gradient_by_sampling.js";
|
|
3
9
|
|
|
4
10
|
export class UnitCubeShape3D extends AbstractShape3D {
|
|
5
11
|
|
|
@@ -7,6 +13,77 @@ export class UnitCubeShape3D extends AbstractShape3D {
|
|
|
7
13
|
return 1;
|
|
8
14
|
}
|
|
9
15
|
|
|
16
|
+
nearest_point_on_surface(result, reference) {
|
|
17
|
+
const r_x = reference[0];
|
|
18
|
+
const r_y = reference[1];
|
|
19
|
+
const r_z = reference[2];
|
|
20
|
+
|
|
21
|
+
// figure out closest face to the reference point
|
|
22
|
+
const ar_x = Math.abs(r_x);
|
|
23
|
+
const ar_y = Math.abs(r_y);
|
|
24
|
+
const ar_z = Math.abs(r_z);
|
|
25
|
+
|
|
26
|
+
if (ar_x > ar_y && ar_x > ar_z) {
|
|
27
|
+
// X is smallest, project onto X axis
|
|
28
|
+
if (r_x <= 0) {
|
|
29
|
+
result[0] = -0.5;
|
|
30
|
+
} else {
|
|
31
|
+
result[0] = 0.5;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
result[1] = clamp(r_y, -0.5, 0.5);
|
|
35
|
+
result[2] = clamp(r_z, -0.5, 0.5);
|
|
36
|
+
} else if (ar_y > ar_x && ar_y > ar_z) {
|
|
37
|
+
// Y is smallest, project onto X axis
|
|
38
|
+
if (r_y <= 0) {
|
|
39
|
+
result[1] = -0.5;
|
|
40
|
+
} else {
|
|
41
|
+
result[1] = 0.5;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
result[0] = clamp(r_x, -0.5, 0.5);
|
|
45
|
+
result[2] = clamp(r_z, -0.5, 0.5);
|
|
46
|
+
} else {
|
|
47
|
+
// project onto Z axis
|
|
48
|
+
|
|
49
|
+
if (r_z <= 0) {
|
|
50
|
+
result[2] = -0.5;
|
|
51
|
+
} else {
|
|
52
|
+
result[2] = 0.5;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
result[0] = clamp(r_x, -0.5, 0.5);
|
|
56
|
+
result[1] = clamp(r_y, -0.5, 0.5);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
signed_distance_gradient_at_point(result, point) {
|
|
61
|
+
return compute_signed_distance_gradient_by_sampling(result,this, point);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
signed_distance_at_point(point) {
|
|
65
|
+
/*
|
|
66
|
+
based on https://www.iquilezles.org/www/articles/distfunctions/distfunctions.htm
|
|
67
|
+
original shader code:
|
|
68
|
+
------------
|
|
69
|
+
float sdBox( vec3 p, vec3 b )
|
|
70
|
+
{
|
|
71
|
+
vec3 q = abs(p) - b;
|
|
72
|
+
return length(max(q,0.0)) + min(max(q.x,max(q.y,q.z)),0.0);
|
|
73
|
+
}
|
|
74
|
+
------------
|
|
75
|
+
*/
|
|
76
|
+
const q_x = Math.abs(point[0]) - 0.5;
|
|
77
|
+
const q_y = Math.abs(point[1]) - 0.5;
|
|
78
|
+
const q_z = Math.abs(point[2]) - 0.5;
|
|
79
|
+
|
|
80
|
+
return v3_length(
|
|
81
|
+
max2(q_x, 0),
|
|
82
|
+
max2(q_y, 0),
|
|
83
|
+
max2(q_z, 0)
|
|
84
|
+
) + min2(max3(q_x, q_y, q_z), 0);
|
|
85
|
+
}
|
|
86
|
+
|
|
10
87
|
contains_point(point) {
|
|
11
88
|
const x = point[0];
|
|
12
89
|
const y = point[1];
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { UnitCubeShape3D } from "./UnitCubeShape3D.js";
|
|
2
|
+
|
|
3
|
+
test('signed distance', () => {
|
|
4
|
+
const s = new UnitCubeShape3D();
|
|
5
|
+
|
|
6
|
+
expect(s.signed_distance_at_point([0, 0, 0])).toBeCloseTo(-0.5);
|
|
7
|
+
|
|
8
|
+
expect(s.signed_distance_at_point([0.5, 0, 0])).toBeCloseTo(0);
|
|
9
|
+
expect(s.signed_distance_at_point([0, 0.5, 0])).toBeCloseTo(0);
|
|
10
|
+
expect(s.signed_distance_at_point([0, 0, 0.5])).toBeCloseTo(0);
|
|
11
|
+
|
|
12
|
+
expect(s.signed_distance_at_point([-0.5, 0, 0])).toBeCloseTo(0);
|
|
13
|
+
expect(s.signed_distance_at_point([0, -0.5, 0])).toBeCloseTo(0);
|
|
14
|
+
expect(s.signed_distance_at_point([0, 0, -0.5])).toBeCloseTo(0);
|
|
15
|
+
|
|
16
|
+
expect(s.signed_distance_at_point([0.5, 0.5, 0])).toBeCloseTo(0);
|
|
17
|
+
expect(s.signed_distance_at_point([0, 0.5, 0.5])).toBeCloseTo(0);
|
|
18
|
+
expect(s.signed_distance_at_point([0.5, 0, 0.5])).toBeCloseTo(0);
|
|
19
|
+
|
|
20
|
+
expect(s.signed_distance_at_point([-0.5, 0.5, 0])).toBeCloseTo(0);
|
|
21
|
+
expect(s.signed_distance_at_point([0.5, -0.5, 0])).toBeCloseTo(0);
|
|
22
|
+
expect(s.signed_distance_at_point([-0.5, -0.5, 0])).toBeCloseTo(0);
|
|
23
|
+
|
|
24
|
+
expect(s.signed_distance_at_point([0, -0.5, 0.5])).toBeCloseTo(0);
|
|
25
|
+
expect(s.signed_distance_at_point([0, 0.5, -0.5])).toBeCloseTo(0);
|
|
26
|
+
expect(s.signed_distance_at_point([0, -0.5, -0.5])).toBeCloseTo(0);
|
|
27
|
+
|
|
28
|
+
expect(s.signed_distance_at_point([-0.5, 0, 0.5])).toBeCloseTo(0);
|
|
29
|
+
expect(s.signed_distance_at_point([0.5, 0, -0.5])).toBeCloseTo(0);
|
|
30
|
+
expect(s.signed_distance_at_point([-0.5, 0, -0.5])).toBeCloseTo(0);
|
|
31
|
+
|
|
32
|
+
expect(s.signed_distance_at_point([0.5, 0.5, 0.5])).toBeCloseTo(0);
|
|
33
|
+
expect(s.signed_distance_at_point([-0.5, 0.5, 0.5])).toBeCloseTo(0);
|
|
34
|
+
expect(s.signed_distance_at_point([0.5, -0.5, 0.5])).toBeCloseTo(0);
|
|
35
|
+
expect(s.signed_distance_at_point([0.5, 0.5, -0.5])).toBeCloseTo(0);
|
|
36
|
+
expect(s.signed_distance_at_point([-0.5, -0.5, 0.5])).toBeCloseTo(0);
|
|
37
|
+
expect(s.signed_distance_at_point([0.5, -0.5, -0.5])).toBeCloseTo(0);
|
|
38
|
+
expect(s.signed_distance_at_point([-0.5, 0.5, -0.5])).toBeCloseTo(0);
|
|
39
|
+
expect(s.signed_distance_at_point([-0.5, -0.5, -0.5])).toBeCloseTo(0);
|
|
40
|
+
|
|
41
|
+
expect(s.signed_distance_at_point([1, 0, 0])).toBeCloseTo(0.5);
|
|
42
|
+
});
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
import { AbstractShape3D } from "./AbstractShape3D.js";
|
|
2
2
|
import { randomPointInSphere } from "../../random/randomPointInSphere.js";
|
|
3
|
+
import { v3_length } from "../../v3_length.js";
|
|
4
|
+
import { compute_signed_distance_gradient_by_sampling } from "./util/compute_signed_distance_gradient_by_sampling.js";
|
|
3
5
|
|
|
6
|
+
/**
|
|
7
|
+
* Sphere with diameter of 1 (radius = 0.5)
|
|
8
|
+
*/
|
|
4
9
|
export class UnitSphereShape3D extends AbstractShape3D {
|
|
5
10
|
get volume() {
|
|
6
11
|
return 0.523598776;
|
|
@@ -10,12 +15,38 @@ export class UnitSphereShape3D extends AbstractShape3D {
|
|
|
10
15
|
return 3.14159265;
|
|
11
16
|
}
|
|
12
17
|
|
|
18
|
+
nearest_point_on_surface(result, reference) {
|
|
19
|
+
|
|
20
|
+
const r_x = reference[0];
|
|
21
|
+
const r_y = reference[1];
|
|
22
|
+
const r_z = reference[2];
|
|
23
|
+
|
|
24
|
+
// normalize vector to 0.5 radius
|
|
25
|
+
const d = 0.5 / Math.hypot(r_x, r_y, r_z);
|
|
26
|
+
|
|
27
|
+
result[0] = r_x * d;
|
|
28
|
+
result[1] = r_y * d;
|
|
29
|
+
result[2] = r_z * d;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
signed_distance_gradient_at_point(result, point) {
|
|
33
|
+
return compute_signed_distance_gradient_by_sampling(result,this, point);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
signed_distance_at_point(point) {
|
|
37
|
+
return v3_length(
|
|
38
|
+
point[0],
|
|
39
|
+
point[1],
|
|
40
|
+
point[2]
|
|
41
|
+
) - 0.5;
|
|
42
|
+
}
|
|
43
|
+
|
|
13
44
|
contains_point(point) {
|
|
14
45
|
const x = point[0];
|
|
15
46
|
const y = point[1];
|
|
16
47
|
const z = point[2];
|
|
17
48
|
|
|
18
|
-
return (x * x + y * y + z * z) <
|
|
49
|
+
return (x * x + y * y + z * z) < 0.25;
|
|
19
50
|
}
|
|
20
51
|
|
|
21
52
|
sample_random_point_in_volume(result, result_offset, random) {
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
const scratch_v = [];
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
*
|
|
5
|
+
* @param {number[]} result
|
|
6
|
+
* @param {AbstractShape3D} shape
|
|
7
|
+
* @param {number[]} point
|
|
8
|
+
* @returns {number}
|
|
9
|
+
*/
|
|
10
|
+
export function compute_signed_distance_gradient_by_sampling(result, shape, point) {
|
|
11
|
+
const v0 = shape.signed_distance_at_point(point);
|
|
12
|
+
|
|
13
|
+
scratch_v[0] = point[0] + 1e-5;
|
|
14
|
+
scratch_v[1] = point[1];
|
|
15
|
+
scratch_v[2] = point[2];
|
|
16
|
+
|
|
17
|
+
const vx = shape.signed_distance_at_point(scratch_v);
|
|
18
|
+
|
|
19
|
+
scratch_v[0] = point[0];
|
|
20
|
+
scratch_v[1] = point[1] + 1e-5;
|
|
21
|
+
scratch_v[2] = point[2];
|
|
22
|
+
|
|
23
|
+
const vy = shape.signed_distance_at_point(point);
|
|
24
|
+
|
|
25
|
+
scratch_v[0] = point[0];
|
|
26
|
+
scratch_v[1] = point[1];
|
|
27
|
+
scratch_v[2] = point[2] + 1e-5;
|
|
28
|
+
|
|
29
|
+
const vz = shape.signed_distance_at_point(point);
|
|
30
|
+
|
|
31
|
+
// convert absolute sample values to relative
|
|
32
|
+
const rx = vx - v0;
|
|
33
|
+
const ry = vy - v0;
|
|
34
|
+
const rz = vz - v0;
|
|
35
|
+
|
|
36
|
+
// normalize by sampling distance
|
|
37
|
+
const d = 1e-5 / 1.73205080757;
|
|
38
|
+
|
|
39
|
+
const nx = rx * d;
|
|
40
|
+
const ny = ry * d;
|
|
41
|
+
const nz = rz * d;
|
|
42
|
+
|
|
43
|
+
result[0] = nx;
|
|
44
|
+
result[1] = ny;
|
|
45
|
+
result[2] = nz;
|
|
46
|
+
|
|
47
|
+
return v0;
|
|
48
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { UnionShape3D } from "../UnionShape3D.js";
|
|
2
2
|
import { UnitCubeShape3D } from "../UnitCubeShape3D.js";
|
|
3
3
|
import { UnitSphereShape3D } from "../UnitSphereShape3D.js";
|
|
4
4
|
import { TransformedShape3D } from "../TransformedShape3D.js";
|
|
@@ -30,7 +30,7 @@ export const SHAPE_VISUAL_ENTITY_TAG = 'util/vis/Shape3D';
|
|
|
30
30
|
|
|
31
31
|
/**
|
|
32
32
|
*
|
|
33
|
-
* @param {
|
|
33
|
+
* @param {UnionShape3D} shape
|
|
34
34
|
* @param {EntityComponentDataset} ecd
|
|
35
35
|
* @returns {EntityBuilder}
|
|
36
36
|
*/
|
|
@@ -145,7 +145,7 @@ function transformed_shape_to_entity(shape, ecd) {
|
|
|
145
145
|
* @returns {EntityBuilder}
|
|
146
146
|
*/
|
|
147
147
|
export function shape_to_visual_entity(shape, ecd) {
|
|
148
|
-
if (shape instanceof
|
|
148
|
+
if (shape instanceof UnionShape3D) {
|
|
149
149
|
return composite_shape_to_entity(shape, ecd);
|
|
150
150
|
} else if (shape instanceof UnitCubeShape3D) {
|
|
151
151
|
return cube_shape_to_entity(shape, ecd);
|
|
@@ -147,7 +147,7 @@ export class OutlineRenderPlugin extends EnginePlugin {
|
|
|
147
147
|
this.__compositing_layer.name = "Silhouette Outline";
|
|
148
148
|
this.__compositing_layer.stage = CompositingStages.POST_TRANSPARENT;
|
|
149
149
|
|
|
150
|
-
|
|
150
|
+
graphics.on.preRender.add(this.__render, this);
|
|
151
151
|
|
|
152
152
|
|
|
153
153
|
// set rendering resolution
|
|
@@ -160,7 +160,7 @@ export class OutlineRenderPlugin extends EnginePlugin {
|
|
|
160
160
|
|
|
161
161
|
const graphics = this.engine.graphics;
|
|
162
162
|
|
|
163
|
-
|
|
163
|
+
graphics.on.preRender.remove(this.__render, this);
|
|
164
164
|
|
|
165
165
|
graphics.viewport.size.onChanged.remove(this.__set_viewport_size, this);
|
|
166
166
|
|
|
@@ -63,7 +63,7 @@ import {
|
|
|
63
63
|
import { seededRandom } from "../../../../../../../core/math/random/seededRandom.js";
|
|
64
64
|
import { TransformedShape3D } from "../../../../../../../core/geom/3d/shape/TransformedShape3D.js";
|
|
65
65
|
import { mat4 } from "gl-matrix";
|
|
66
|
-
import {
|
|
66
|
+
import { UnionShape3D } from "../../../../../../../core/geom/3d/shape/UnionShape3D.js";
|
|
67
67
|
import { ShadedGeometry } from "../../../../../ecs/mesh-v2/ShadedGeometry.js";
|
|
68
68
|
import { DrawMode } from "../../../../../ecs/mesh-v2/DrawMode.js";
|
|
69
69
|
import { makeHelperBoxGeometry } from "../../../../../../../editor/process/symbolic/makeHelperBoxGeometry.js";
|
|
@@ -313,7 +313,7 @@ async function sample_scene_0(engine) {
|
|
|
313
313
|
await make_demo_volume({
|
|
314
314
|
ecd: ecd,
|
|
315
315
|
lut: heatmap_lut_0,
|
|
316
|
-
shape:
|
|
316
|
+
shape: UnionShape3D.from([
|
|
317
317
|
TransformedShape3D.from_m4(new UnitCubeShape3D(), mat_from_aabb3(new AABB3(67.73, 0, 89, 115.84, 3, 118.34))),
|
|
318
318
|
TransformedShape3D.from_m4(new UnitCubeShape3D(), mat_from_aabb3(new AABB3(98, 0, 76.5, 109.5, 3, 89)))
|
|
319
319
|
]),
|
|
@@ -325,7 +325,7 @@ async function sample_scene_0(engine) {
|
|
|
325
325
|
await make_demo_volume({
|
|
326
326
|
ecd: ecd,
|
|
327
327
|
lut: heatmap_lut_0,
|
|
328
|
-
shape:
|
|
328
|
+
shape: UnionShape3D.from([
|
|
329
329
|
TransformedShape3D.from_m4(new UnitCubeShape3D(), [14.980091485108495, 0, 0, 0, 0, 2.812495250139616, 0, 0, 0, 0, 7.469446746375293, 0, 54.83080514238756, 1.568241402881399, 92.51937192481576, 1]),
|
|
330
330
|
TransformedShape3D.from_m4(new UnitCubeShape3D(), [6.644515553810907, 0, 0, 0, 0, 2.812495250139616, 0, 0, 0, 0, 5.507507223409315, 0, 46.95032009188344, 1.568241402881399, 95.54148649329517, 1]),
|
|
331
331
|
TransformedShape3D.from_m4(new UnitCubeShape3D(), [23.762890107594952, 0, 0, 0, 0, 2.812495250139616, 0, 0, 0, 0, 34.57956316503163, 0, 55.436098243647756, 1.568241402881399, 113.46988143189215, 1])
|
|
@@ -349,7 +349,7 @@ async function sample_scene_0(engine) {
|
|
|
349
349
|
await make_demo_volume({
|
|
350
350
|
ecd: ecd,
|
|
351
351
|
lut: heatmap_lut_pink_to_blue,
|
|
352
|
-
shape:
|
|
352
|
+
shape: UnionShape3D.from([
|
|
353
353
|
TransformedShape3D.from_m4(new UnitCubeShape3D(), [15.218520811592711, 0, 0, 0, 0, 3.058639690434693, 0, 0, 0, 0, 5.828701399328644, 0, 89.53848861962253, 2.0721850959505907, 73.05504876489894, 1]),
|
|
354
354
|
TransformedShape3D.from_m4(new UnitCubeShape3D(), [18.10977091153633, 0, 0, 0, 0, 3.058639690434693, 0, 0, 0, 0, 2.5862076050328002, 0, 88.03260126722904, 2.0721850959505907, 69.0797462656922, 1])
|
|
355
355
|
]),
|
|
@@ -363,7 +363,7 @@ async function sample_scene_0(engine) {
|
|
|
363
363
|
await make_demo_volume({
|
|
364
364
|
ecd: ecd,
|
|
365
365
|
lut: heatmap_lut_3,
|
|
366
|
-
shape:
|
|
366
|
+
shape: UnionShape3D.from([
|
|
367
367
|
TransformedShape3D.from_m4(new UnitCubeShape3D(), [20.977896627021547, 0, 0, 0, 0, 2.956899734575006, 0, 0, 0, 0, 36.201589869571954, 0, 99.2120028317975, 1.5919924971428276, 49.21655402009093, 1]),
|
|
368
368
|
TransformedShape3D.from_m4(new UnitCubeShape3D(), [24.455615450514458, 0, 0, 0, 0, 2.956899734575006, 0, 0, 0, 0, 28.081536987027807, 0, 80.11618755300161, 1.5919924971428276, 45.13808745329574, 1]),
|
|
369
369
|
TransformedShape3D.from_m4(new UnitCubeShape3D(), [5.562874425497998, 0, 0, 0, 0, 2.956899734575006, 0, 0, 0, 0, 2.654155224548708, 0, 70.80986716000054, 1.5919924971428276, 59.679876796143446, 1])
|
|
@@ -378,7 +378,7 @@ async function sample_scene_0(engine) {
|
|
|
378
378
|
await make_demo_volume({
|
|
379
379
|
ecd: ecd,
|
|
380
380
|
lut: heatmap_lut_orange_to_red,
|
|
381
|
-
shape:
|
|
381
|
+
shape: UnionShape3D.from([
|
|
382
382
|
TransformedShape3D.from_m4(new UnitCubeShape3D(), [-3.8971594611231577, -1.9562533614625899, -0.5725042419276598, 0, -8.346390838999248, 16.986127440019352, -1.226109479938015, 0, 0.12112312197093604, 0, -0.8245111322851176, 0, 55.83305788880312, 9.579537179233043, 83.59013920067233, 1]),
|
|
383
383
|
TransformedShape3D.from_m4(new UnitSphereShape3D(), [10.237283879346698, 0, 0, 0, 0, 10.237283879346698, 0, 0, 0, 0, 10.237283879346698, 0, 51.783732965076716, 18.028888481196716, 82.91084586075068, 1])
|
|
384
384
|
]),
|
|
@@ -555,7 +555,7 @@ async function sample_scene_nam(engine) {
|
|
|
555
555
|
await make_demo_volume({
|
|
556
556
|
ecd: ecd,
|
|
557
557
|
lut: heatmap_lut_pink_to_blue,
|
|
558
|
-
shape:
|
|
558
|
+
shape: UnionShape3D.from([
|
|
559
559
|
TransformedShape3D.from_m4(new UnitCubeShape3D(), [5.985827128973811, 0, 0, 0, 0, 2.435269776236539, 0, 0, 0, 0, 4.669621139110231, 0, 11.08356834576874, 1.2643565739307023, 2.4360416869081885, 1]),
|
|
560
560
|
TransformedShape3D.from_m4(new UnitCubeShape3D(), [8.413758403821523, 0, 0, 0, 0, 2.3166487265965343, 0, 0, 0, 0, 7.775469675813772, 0, 4.313201108449287, 1.4169994923726943, 4.011630095541064, 1]),
|
|
561
561
|
TransformedShape3D.from_m4(new UnitCubeShape3D(), [8.413758403821523, 0, 0, 0, 0, 2.3166487265965343, 0, 0, 0, 0, 2.925065210015915, 0, 12.417224289491141, 1.4169994923726943, 6.432483110925785, 1])
|
|
@@ -173,13 +173,19 @@ export class ShadowMapRenderer {
|
|
|
173
173
|
|
|
174
174
|
if (shadow.map === null) {
|
|
175
175
|
|
|
176
|
-
const pars = {
|
|
176
|
+
const pars = {
|
|
177
|
+
format: RGBAFormat,
|
|
178
|
+
scissorTest: false,
|
|
179
|
+
stencilBuffer: false
|
|
180
|
+
};
|
|
177
181
|
|
|
178
182
|
if (!shadow.isPointLightShadow && renderer.shadowMap.type === VSMShadowMap) {
|
|
179
183
|
pars.minFilter = LinearFilter;
|
|
180
184
|
pars.magFilter = LinearFilter;
|
|
181
185
|
|
|
182
|
-
shadow.mapPass = new WebGLRenderTarget(_shadowMapSize.x, _shadowMapSize.y,
|
|
186
|
+
shadow.mapPass = new WebGLRenderTarget(_shadowMapSize.x, _shadowMapSize.y, Object.assign({
|
|
187
|
+
depthBuffer: false
|
|
188
|
+
}, pars));
|
|
183
189
|
|
|
184
190
|
} else {
|
|
185
191
|
pars.minFilter = NearestFilter;
|
package/package.json
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"productName": "Meep",
|
|
5
5
|
"description": "production-ready JavaScript game engine based on Entity Component System Architecture",
|
|
6
6
|
"author": "Alexander Goldring",
|
|
7
|
-
"version": "2.33.
|
|
7
|
+
"version": "2.33.26",
|
|
8
8
|
"dependencies": {
|
|
9
9
|
"fast-levenshtein": "2.0.6",
|
|
10
10
|
"opentype.js": "1.3.3",
|