@woosh/meep-engine 2.133.2 → 2.133.5
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/package.json +2 -2
- package/src/core/binary/BitSet.d.ts +6 -0
- package/src/core/binary/BitSet.d.ts.map +1 -1
- package/src/core/binary/BitSet.js +38 -1
- package/src/core/binary/operations/bitCount.d.ts.map +1 -1
- package/src/core/binary/operations/bitCount.js +11 -6
- package/src/core/geom/2d/quad-tree/QuadTreeNode.d.ts +5 -0
- package/src/core/geom/2d/quad-tree/QuadTreeNode.d.ts.map +1 -1
- package/src/core/geom/2d/quad-tree/QuadTreeNode.js +82 -3
- package/src/core/geom/3d/aabb/AABB3.d.ts +7 -1
- package/src/core/geom/3d/aabb/AABB3.d.ts.map +1 -1
- package/src/core/geom/3d/aabb/AABB3.js +14 -1
- package/src/engine/ecs/terrain/ecs/Terrain.d.ts.map +1 -1
- package/src/engine/ecs/terrain/ecs/Terrain.js +6 -1
- package/src/engine/ecs/terrain/ecs/layers/TerrainLayer.d.ts.map +1 -1
- package/src/engine/ecs/terrain/ecs/layers/TerrainLayer.js +10 -9
- package/src/engine/ecs/terrain/ecs/layers/TerrainLayers.d.ts.map +1 -1
- package/src/engine/ecs/terrain/ecs/layers/TerrainLayers.js +14 -11
- package/src/engine/graphics/ecs/water/WaterSystem.d.ts.map +1 -1
- package/src/engine/graphics/ecs/water/WaterSystem.js +3 -0
- package/src/engine/graphics/material/SplatMaterial.d.ts.map +1 -1
- package/src/engine/graphics/material/SplatMaterial.js +2 -4
- package/src/engine/graphics/shaders/TerrainShader.js +4 -11
- package/src/engine/physics/gjk/gjk.d.ts +16 -0
- package/src/engine/physics/gjk/gjk.d.ts.map +1 -0
- package/src/engine/physics/gjk/gjk.js +378 -0
package/package.json
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
"description": "Pure JavaScript game engine. Fully featured and production ready.",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"author": "Alexander Goldring",
|
|
8
|
-
"version": "2.133.
|
|
8
|
+
"version": "2.133.5",
|
|
9
9
|
"main": "build/meep.module.js",
|
|
10
10
|
"module": "build/meep.module.js",
|
|
11
11
|
"exports": {
|
|
@@ -89,6 +89,6 @@
|
|
|
89
89
|
"typescript"
|
|
90
90
|
],
|
|
91
91
|
"engines": {
|
|
92
|
-
"node": ">=
|
|
92
|
+
"node": ">=24"
|
|
93
93
|
}
|
|
94
94
|
}
|
|
@@ -183,6 +183,12 @@ export class BitSet {
|
|
|
183
183
|
* Sets all the bits in this BitSet to false.
|
|
184
184
|
*/
|
|
185
185
|
reset(): void;
|
|
186
|
+
/**
|
|
187
|
+
* Number of set bits in this BitSet.
|
|
188
|
+
* Also known as "Hamming weight" or "population count".
|
|
189
|
+
* @returns {number}
|
|
190
|
+
*/
|
|
191
|
+
cardinality(): number;
|
|
186
192
|
/**
|
|
187
193
|
* Copy contents of another bit set into this one
|
|
188
194
|
* @param {BitSet} other
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BitSet.d.ts","sourceRoot":"","sources":["../../../../src/core/binary/BitSet.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"BitSet.d.ts","sourceRoot":"","sources":["../../../../src/core/binary/BitSet.js"],"names":[],"mappings":"AAiCA;;;;;;;;;;;;;;GAcG;AACH;IAslBI;;;;OAIG;IACH,oBAHW,MAAM,GACJ,MAAM,CAQlB;IA/lBD;;;OAGG;IACH,+BAFW,MAAM,EAgChB;IA3BG;;;;OAIG;IACH,iBAAiB;IAEjB;;;;;OAKG;IACH,mBAA4C;IAE5C;;;;OAIG;IACH,sBAA0D;IAE1D;;;OAGG;IACH,gBAFU,MAAM,CAE2B;IAG/C;;;;OAIG;IACH,iBAFa,IAAI,CAIhB;IAED;;;OAGG;IACH,mBAFW,MAAM,QAOhB;IACD;;;;;;OAMG;IACH,uBAJW,MAAM,GAEJ,IAAI,CAUhB;IAED;;;;OAIG;IACH,QAFa,MAAM,CAIlB;IAED;;;;OAIG;IACH,YAFa,MAAM,CAIlB;IAED;;;;OAIG;IACH,iBAsBC;IAED;;;OAGG;IACH,uBAMC;IAED;;;;;OAKG;IACH,oBAyBC;IAED;;;;OAIG;IACH,2BAHW,MAAM,GACJ,MAAM,CAuClB;IAED;;;;OAIG;IACH,uBAHW,MAAM,GACJ,MAAM,CAuDlB;IAED;;;;OAIG;IACH,yBAHW,MAAM,GACJ,MAAM,CAkDlB;IAED;;;;;OAKG;IACH,eAJW,MAAM,SACN,OAAO,GACL,IAAI,CAmChB;IAED;;;OAGG;IACH,iBAFW,MAAM,QAIhB;IAED;;;;OAIG;IACH,sBAHW,MAAM,aACN,MAAM,QAWhB;IAED;;;;OAIG;IACH,wBAHW,MAAM,aACN,MAAM,QAShB;IAED;;;;OAIG;IACH,qBAFa,OAAO,CAkBnB;IAED;;;;OAIG;IACH,iBAHW,MAAM,GACJ,OAAO,CAUnB;IAED;;;;OAIG;IACH,mBAHW,MAAM,GACJ,OAAO,CAUnB;IAED;;;;;OAKG;IACH,sBAJW,MAAM,eACN,MAAM,aACN,MAAM,QAShB;IAED;;;;;OAKG;IACH,qBAJW,MAAM,eACN,MAAM,aACN,MAAM,QAShB;IAED;;;;;OAKG;IACH,gBAJW,MAAM,eACN,MAAM,aACN,MAAM,QAQhB;IAED;;OAEG;IACH,cAgBC;IAED;;;;OAIG;IACH,eAFa,MAAM,CA+BlB;IAED;;;OAGG;IACH,YAFW,MAAM,QAoChB;CAcJ"}
|
|
@@ -3,6 +3,7 @@ import { max3 } from "../math/max3.js";
|
|
|
3
3
|
import { min2 } from "../math/min2.js";
|
|
4
4
|
import { align_32 } from "./align_32.js";
|
|
5
5
|
import { lsb_32 } from "./lsb_32.js";
|
|
6
|
+
import { bitCount } from "./operations/bitCount.js";
|
|
6
7
|
|
|
7
8
|
/**
|
|
8
9
|
* Used for overallocating space when bit set needs to grow
|
|
@@ -567,6 +568,42 @@ export class BitSet {
|
|
|
567
568
|
this.__length = 0;
|
|
568
569
|
}
|
|
569
570
|
|
|
571
|
+
/**
|
|
572
|
+
* Number of set bits in this BitSet.
|
|
573
|
+
* Also known as "Hamming weight" or "population count".
|
|
574
|
+
* @returns {number}
|
|
575
|
+
*/
|
|
576
|
+
cardinality(){
|
|
577
|
+
const length = this.__length;
|
|
578
|
+
|
|
579
|
+
if (length === 0) {
|
|
580
|
+
return 0;
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
const data = this.__data_uint32;
|
|
584
|
+
let count = 0;
|
|
585
|
+
|
|
586
|
+
// Number of fully utilized 32-bit words
|
|
587
|
+
const full_words = length >> 5;
|
|
588
|
+
|
|
589
|
+
// Count bits in all complete words
|
|
590
|
+
for (let i = 0; i < full_words; i++) {
|
|
591
|
+
count += bitCount(data[i]);
|
|
592
|
+
}
|
|
593
|
+
|
|
594
|
+
// Handle any remaining bits in the partial last word
|
|
595
|
+
const remainder_bits = length & 31;
|
|
596
|
+
|
|
597
|
+
if (remainder_bits > 0) {
|
|
598
|
+
// Create a mask to ignore any bits beyond __length
|
|
599
|
+
// e.g., if remainder is 3, mask is (1<<3)-1 = 7 (0b111)
|
|
600
|
+
const mask = (1 << remainder_bits) - 1;
|
|
601
|
+
count += bitCount(data[full_words] & mask);
|
|
602
|
+
}
|
|
603
|
+
|
|
604
|
+
return count;
|
|
605
|
+
}
|
|
606
|
+
|
|
570
607
|
/**
|
|
571
608
|
* Copy contents of another bit set into this one
|
|
572
609
|
* @param {BitSet} other
|
|
@@ -619,4 +656,4 @@ export class BitSet {
|
|
|
619
656
|
|
|
620
657
|
return r;
|
|
621
658
|
}
|
|
622
|
-
}
|
|
659
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bitCount.d.ts","sourceRoot":"","sources":["../../../../../src/core/binary/operations/bitCount.js"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,4BAHW,MAAM,GACJ,MAAM,
|
|
1
|
+
{"version":3,"file":"bitCount.d.ts","sourceRoot":"","sources":["../../../../../src/core/binary/operations/bitCount.js"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,4BAHW,MAAM,GACJ,MAAM,CAkBlB"}
|
|
@@ -7,11 +7,16 @@ export function bitCount(v) {
|
|
|
7
7
|
// see https://stackoverflow.com/a/109025/3973586
|
|
8
8
|
// see https://graphics.stanford.edu/%7Eseander/bithacks.html#CountBitsSetParallel
|
|
9
9
|
|
|
10
|
-
let i = v|0;
|
|
11
10
|
|
|
12
|
-
|
|
13
|
-
i =
|
|
14
|
-
|
|
15
|
-
i
|
|
16
|
-
|
|
11
|
+
// Force to a 32-bit unsigned integer
|
|
12
|
+
let i = v >>> 0;
|
|
13
|
+
|
|
14
|
+
i = i - ((i >>> 1) & 0x55555555); // Add pairs of bits
|
|
15
|
+
i = (i & 0x33333333) + ((i >>> 2) & 0x33333333); // Quads
|
|
16
|
+
i = (i + (i >>> 4)) & 0x0F0F0F0F; // Groups of 8
|
|
17
|
+
|
|
18
|
+
// horizontal sum of bytes
|
|
19
|
+
// return just that top byte (after truncating to 32-bit even when int is wider than uint32_t)
|
|
20
|
+
// Math.imul perfectly simulates C's 32-bit integer multiplication overflow
|
|
21
|
+
return (Math.imul(i, 0x01010101) >>> 24);
|
|
17
22
|
}
|
|
@@ -40,6 +40,11 @@ export class QuadTreeNode<D> extends AABB2 {
|
|
|
40
40
|
* @type {QuadTreeDatum<D>[]}
|
|
41
41
|
*/
|
|
42
42
|
data: QuadTreeDatum<D>[];
|
|
43
|
+
/**
|
|
44
|
+
* Internal method. Assesses whether splitting this node would be beneficial.
|
|
45
|
+
* @returns {boolean}
|
|
46
|
+
*/
|
|
47
|
+
isSplitMeaningful(): boolean;
|
|
43
48
|
balance(): 0 | 1 | 2;
|
|
44
49
|
balanceBubbleUp(): void;
|
|
45
50
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"QuadTreeNode.d.ts","sourceRoot":"","sources":["../../../../../../src/core/geom/2d/quad-tree/QuadTreeNode.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"QuadTreeNode.d.ts","sourceRoot":"","sources":["../../../../../../src/core/geom/2d/quad-tree/QuadTreeNode.js"],"names":[],"mappings":"AAqBA;;;GAGG;AACH;IApBK,4DACE;IAAA,cAAqB;IAoBxB;;;OAGG;IACH,SAFU,oBAAa,IAAI,CAEZ;IACf;;;OAGG;IACH,UAFU,oBAAa,IAAI,CAEX;IAChB;;;OAGG;IACH,YAFU,oBAAa,IAAI,CAET;IAClB;;;OAGG;IACH,aAFU,oBAAa,IAAI,CAER;IAEnB;;;OAGG;IACH,YAFU,oBAAa,IAAI,CAET;IAElB;;;OAGG;IACH,eAFU,MAAM,CAEE;IAGlB;;;OAGG;IACH,MAFU,cAAc,CAAC,CAAC,EAAE,CAElB;IAEV;;;OAGG;IACH,qBAFa,OAAO,CAmEnB;IAED,qBAcC;IAED,wBAYC;IAED;;;;;;OAMG;IACH,WALW,MAAM,MACN,MAAM,MACN,MAAM,MACN,MAAM,QAkBhB;IAED;;;;;;;;OAQG;IACH,oBANW,MAAM,MACN,MAAM,MACN,MAAM,MACN,MAAM,sBAWhB;IAED;;;OAGG;IACH,6CAuEC;IAED;;;OAGG;IACH,iBAaC;IAED;;;OAGG;IACH,WAFY,OAAO,CAIlB;IAED,cA8BC;IAED;;OAEG;IACH,mBAKC;IAED;;;OAGG;IACH,8CAiBC;IAED;;OAEG;IACH,qBA2DC;IAED,cASC;IAED,cAQC;IAED;;OAEG;IACH,mBAFW,CAAC,EAAE,QAUb;IAED;;;;OAIG;IACH,6BAHoB,cAAc,CAAC,CAAC,+BAgBnC;IAED;;;;OAIG;IACH,iCAHoB,aAAa,CAAC,CAAC,KAAE,OAAO,uBAiB3C;IAED;;;;;;OAMG;IACH,uCALW,MAAM,cAAc,CAAC,CAAC,CAAC,KACvB,MAAM,KACN,MAAM,GACJ,MAAM,CAIlB;IAED;;;;;;;;OAQG;IACH,2CAPW,MAAM,cAAc,CAAC,CAAC,CAAC,MACvB,MAAM,MACN,MAAM,MACN,MAAM,MACN,MAAM,GACJ,MAAM,CAIlB;IAED;;;;;;;;;OASG;IACH,mCAPW,MAAM,MACN,MAAM,MACN,MAAM,MACN,MAAM,kBACG,cAAc,CAAC,CAAC,+BA2CnC;IAIL;;;OAGG;IACH,yBAFU,OAAO,CAEoB;CANpC;kBAhlBiB,wBAAwB;8BAGZ,oBAAoB"}
|
|
@@ -7,7 +7,16 @@ import { qt_collect_by_point } from "./qt_collect_by_point.js";
|
|
|
7
7
|
import { QuadTreeDatum } from "./QuadTreeDatum.js";
|
|
8
8
|
|
|
9
9
|
|
|
10
|
+
/**
|
|
11
|
+
* Must have at least this many items before splitting makes sense.
|
|
12
|
+
* @type {number}
|
|
13
|
+
*/
|
|
10
14
|
const THRESHOLD_SPLIT = 16;
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Must have at least this many items before merging makes sense.
|
|
18
|
+
* @type {number}
|
|
19
|
+
*/
|
|
11
20
|
const THRESHOLD_MERGE = 8;
|
|
12
21
|
|
|
13
22
|
/**
|
|
@@ -55,11 +64,81 @@ export class QuadTreeNode extends AABB2 {
|
|
|
55
64
|
*/
|
|
56
65
|
data = [];
|
|
57
66
|
|
|
67
|
+
/**
|
|
68
|
+
* Internal method. Assesses whether splitting this node would be beneficial.
|
|
69
|
+
* @returns {boolean}
|
|
70
|
+
*/
|
|
71
|
+
isSplitMeaningful() {
|
|
72
|
+
|
|
73
|
+
const data = this.data;
|
|
74
|
+
const data_size = data.length;
|
|
75
|
+
|
|
76
|
+
if (data_size < THRESHOLD_SPLIT) {
|
|
77
|
+
return false;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const x0 = this.x0;
|
|
81
|
+
const x1 = this.x1;
|
|
82
|
+
const y0 = this.y0;
|
|
83
|
+
const y1 = this.y1;
|
|
84
|
+
|
|
85
|
+
if (x0 === x1 && y0 === y1) {
|
|
86
|
+
// zero area, splitting will do nothing useful
|
|
87
|
+
return false;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
const xm = (x0 + x1) * 0.5;
|
|
91
|
+
const ym = (y0 + y1) * 0.5;
|
|
92
|
+
|
|
93
|
+
// simulate split and count how many items are in each quadrant
|
|
94
|
+
let count_tl = 0;
|
|
95
|
+
let count_tr = 0;
|
|
96
|
+
let count_bl = 0;
|
|
97
|
+
let count_br = 0;
|
|
98
|
+
for (let i = 0; i < data_size; i++) {
|
|
99
|
+
const datum = data[i];
|
|
100
|
+
|
|
101
|
+
if (datum.y1 < ym) {
|
|
102
|
+
//top
|
|
103
|
+
if (datum.x1 < xm) {
|
|
104
|
+
//left
|
|
105
|
+
count_tl++;
|
|
106
|
+
} else if (datum.x0 >= xm) {
|
|
107
|
+
//right
|
|
108
|
+
count_tr++;
|
|
109
|
+
}
|
|
110
|
+
} else if (datum.y0 >= ym) {
|
|
111
|
+
//top
|
|
112
|
+
if (datum.x1 < xm) {
|
|
113
|
+
//left
|
|
114
|
+
count_bl++;
|
|
115
|
+
} else if (datum.x0 >= xm) {
|
|
116
|
+
//right
|
|
117
|
+
count_br++;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
const refined_sum = count_tl + count_tr + count_bl + count_br;
|
|
123
|
+
|
|
124
|
+
if (refined_sum === 0) {
|
|
125
|
+
return false;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
const refined_max = Math.max(count_tl, count_tr, count_bl, count_br);
|
|
129
|
+
|
|
130
|
+
if (refined_max === data_size) {
|
|
131
|
+
// all children would go quadrant, this is pointless recursion
|
|
132
|
+
return false;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
return true;
|
|
136
|
+
}
|
|
137
|
+
|
|
58
138
|
balance() {
|
|
59
|
-
const dataLength = this.data.length;
|
|
60
139
|
const is_split = this.isSplit();
|
|
61
140
|
|
|
62
|
-
if (
|
|
141
|
+
if (!is_split && this.isSplitMeaningful()) {
|
|
63
142
|
this.split();
|
|
64
143
|
|
|
65
144
|
return 1;
|
|
@@ -166,7 +245,7 @@ export class QuadTreeNode extends AABB2 {
|
|
|
166
245
|
} else {
|
|
167
246
|
|
|
168
247
|
if (!this.isSplit()) {
|
|
169
|
-
if (this.treeDataCount >= THRESHOLD_SPLIT) {
|
|
248
|
+
if (this.treeDataCount >= THRESHOLD_SPLIT && this.isSplitMeaningful()) {
|
|
170
249
|
//node is too large and should be split
|
|
171
250
|
this.split();
|
|
172
251
|
} else {
|
|
@@ -215,10 +215,16 @@ export class AABB3 {
|
|
|
215
215
|
* @returns {boolean}
|
|
216
216
|
*/
|
|
217
217
|
_expandToFitPoint(x: number, y: number, z: number): boolean;
|
|
218
|
+
/**
|
|
219
|
+
*
|
|
220
|
+
* @param {AABB3} other
|
|
221
|
+
*/
|
|
222
|
+
union(other: AABB3): void;
|
|
218
223
|
/**
|
|
219
224
|
*
|
|
220
225
|
* @param {AABB3} box
|
|
221
226
|
* @returns {boolean}
|
|
227
|
+
* @deprecated use {@link AABB3#union} instead
|
|
222
228
|
*/
|
|
223
229
|
expandToFit(box: AABB3): boolean;
|
|
224
230
|
/**
|
|
@@ -323,7 +329,7 @@ export class AABB3 {
|
|
|
323
329
|
intersectRay(oX: any, oY: any, oZ: any, dX: any, dY: any, dZ: any): boolean;
|
|
324
330
|
intersectSegment(startX: any, startY: any, startZ: any, endX: any, endY: any, endZ: any): boolean;
|
|
325
331
|
/**
|
|
326
|
-
*
|
|
332
|
+
* @deprecated use {@link AABB3#_containsBox} instead
|
|
327
333
|
* @param {THREE.Box} box
|
|
328
334
|
* @returns {boolean}
|
|
329
335
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AABB3.d.ts","sourceRoot":"","sources":["../../../../../../src/core/geom/3d/aabb/AABB3.js"],"names":[],"mappings":"AAeA;;;;GAIG;AACH;IACI;;;;;;;;;OASG;IACH,iBARW,MAAM,OACN,MAAM,OACN,MAAM,OACN,MAAM,OACN,MAAM,OACN,MAAM,EAYhB;IAgED;;;OAGG;IACH,mBAEC;IAxDD;;;OAGG;IACH,gBAEC;IAoDD;;;OAGG;IACH,mBAEC;IAvDD;;;OAGG;IACH,gBAEC;IAmDD;;;OAGG;IACH,mBAEC;IAvDD;;;OAGG;IACH,gBAEC;IAmDD;;;OAGG;IACH,mBAEC;IAtDD;;;OAGG;IACH,gBAEC;IAkDD;;;OAGG;IACH,mBAEC;IAtDD;;;OAGG;IACH,gBAEC;IAkDD;;;OAGG;IACH,mBAEC;IAtDD;;;OAGG;IACH,gBAEC;IAOG,IA4GU,MAAM,CA5GL;IAQX,IAyGU,MAAM,CAzGL;IAQX,IAsGU,MAAM,CAtGL;IAQX,IAmGU,MAAM,CAnGL;IAQX,IAgGU,MAAM,CAhGL;IAQX,IA6FU,MAAM,CA7FL;IAGf;;;;;;;OAOG;IACH,8BANW,MAAM,KACN,MAAM,KACN,MAAM,aACN,MAAM,GACJ,OAAO,CAMnB;IAED;;;OAGG;IACH,sBAFa,MAAM,CAIlB;IAED;;;OAGG;IACH,kBAFa,MAAM,CAIlB;IAED;;;OAGG;IACH,iBAFa,MAAM,CAIlB;IAED;;;OAGG;IACH,YAFW,KAAK,QAIf;IAED;;;;;;;;OAQG;IACH,wFAsCC;IAED;;;;OAIG;IACH,cAHW,KAAK,GACH,OAAO,CAQnB;IAED;;;;;;;;;OASG;IACH,iFAFa,OAAO,CASnB;IAED;;OAEG;IACH,QAFa,MAAM,CAIlB;IAED;;;;;;;;OAQG;IACH,iGA6BC;IAED,oCAEC;IAED,0BAEC;IAED;;;;;OAKG;IACH,cAJW,MAAM,KACN,MAAM,KACN,MAAM,QAOhB;IAED;;;;;;;OAOG;IACH,oBANW,MAAM,KACN,MAAM,KACN,MAAM,GACJ,MAAM,CASlB;IAED;;;;OAIG;IACH,mBAHW,KAAK,GACH,MAAM,CAIlB;IAED;;;;;;;;;;OAUG;IACH,mBARW,MAAM,MACN,MAAM,MACN,MAAM,MACN,MAAM,MACN,MAAM,MACN,MAAM,GACJ,MAAM,CAclB;IAED;;;;;OAKG;IACH,wBAJW,KAAK,GACH,MAAM,CAKlB;IAED;;;;;;;;;;;OAWG;IACH,sBATW,MAAM,MACN,MAAM,MACN,MAAM,MACN,MAAM,MACN,MAAM,MACN,MAAM,GACJ,MAAM,CAuClB;IAED;;;;;;OAMG;IACH,qBALW,MAAM,KACN,MAAM,KACN,MAAM,GACJ,OAAO,CA6BnB;IAED
|
|
1
|
+
{"version":3,"file":"AABB3.d.ts","sourceRoot":"","sources":["../../../../../../src/core/geom/3d/aabb/AABB3.js"],"names":[],"mappings":"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"}
|
|
@@ -491,10 +491,19 @@ export class AABB3 {
|
|
|
491
491
|
return expanded;
|
|
492
492
|
}
|
|
493
493
|
|
|
494
|
+
/**
|
|
495
|
+
*
|
|
496
|
+
* @param {AABB3} other
|
|
497
|
+
*/
|
|
498
|
+
union(other) {
|
|
499
|
+
this._expandToFit(other.x0, other.y0, other.z0, other.x1, other.y1, other.z1);
|
|
500
|
+
}
|
|
501
|
+
|
|
494
502
|
/**
|
|
495
503
|
*
|
|
496
504
|
* @param {AABB3} box
|
|
497
505
|
* @returns {boolean}
|
|
506
|
+
* @deprecated use {@link AABB3#union} instead
|
|
498
507
|
*/
|
|
499
508
|
expandToFit(box) {
|
|
500
509
|
return this._expandToFit(box.x0, box.y0, box.z0, box.x1, box.y1, box.z1);
|
|
@@ -710,7 +719,7 @@ export class AABB3 {
|
|
|
710
719
|
}
|
|
711
720
|
|
|
712
721
|
/**
|
|
713
|
-
*
|
|
722
|
+
* @deprecated use {@link AABB3#_containsBox} instead
|
|
714
723
|
* @param {THREE.Box} box
|
|
715
724
|
* @returns {boolean}
|
|
716
725
|
*/
|
|
@@ -961,6 +970,10 @@ export class AABB3 {
|
|
|
961
970
|
* @param {number} extra
|
|
962
971
|
*/
|
|
963
972
|
grow(extra) {
|
|
973
|
+
assert.isNumber(extra, 'extra');
|
|
974
|
+
assert.notNaN(extra, 'extra');
|
|
975
|
+
assert.isFinite(extra, 'extra');
|
|
976
|
+
|
|
964
977
|
this.x0 -= extra;
|
|
965
978
|
this.y0 -= extra;
|
|
966
979
|
this.z0 -= extra;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Terrain.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/ecs/terrain/ecs/Terrain.js"],"names":[],"mappings":";AA4CA;IACI;;;OAGG;IACH,aAFU,MAAM,CAEC;IAEjB;;;OAGG;IACH,cAAU;IAEV;;;OAGG;IACH,WAFU,MAAM,CAEF;IAEd;;;OAGG;IACH,eAFU,sBAAsB,CAEa;IAE7C;;;OAGG;IACH,mBAFU,MAAM,CAE6B;IAE7C;;;;OAIG;IACH,YAFU,MAAM,CAED;IAEf;;;OAGG;IACH,eAFU,OAAO,CAEQ;IACzB;;;OAGG;IACH,SAFU,cAAc,CAEO;IAC/B;;;OAGG;IACH,gBAFU,YAAY,CAEK;IAE3B;;;OAGG;IACH,iBAFU,aAAa,CAEM;IAE7B;;;OAGG;IACH,oCAAyC;IAEzC;;;OAGG;IACH,cAFU,SAAS,CAEG;IAIlB;;;OAGG;IACH,QAFU,MAAM,CAEU;IAG1B;;;OAGG;IACH,aAFU,MAAM,CAEI;IAGpB;;;OAGG;IACH,eAFU,SAAS,CAE4B;IAE/C;;;OAGG;IACH,eAFU,WAAW,CAE4G;IAejI;;OAEG;IACH,yBAAqC;IAErC;;;OAGG;IACH,eAFU,OAAO,CAEQ;IAEzB;;;;OAIG;IACH,2BAAuC;IAGvC;;;OAGG;IACH,SAFU,cAAc,CAEoB;IAE5C;;;;OAIG;IACH,gBAGE;IAMF;;;;OAIG;IACH,uBAA0B;IAE1B;;;OAGG;IACH,oBAAuB;IAEvB;;;;OAIG;IACH,6BAAgC;IAKpC;;;;OAIG;IACH,cAHW,MAAM,GAAC,YAAY,GACjB,IAAI,CAIhB;IAED;;;;OAIG;IACH,gBAHW,MAAM,GAAC,YAAY,GACjB,IAAI,CAIhB;IAED;;;;OAIG;IACH,gBAHW,MAAM,GAAC,YAAY,SACnB,OAAO,QAQjB;IAED;;;;OAIG;IACH,cAHW,MAAM,GAAC,YAAY,GACjB,OAAO,CAInB;IAED;;;OAGG;IACH,qCA0BC;IAED;;OAEG;IACH,eAyBC;IAED,gBAIC;IAED,mBAmBC;IAED,iCA4BC;IAED,6BAEC;IAED;;;;;;OAMG;IACH,gBANW,MAAM,KACN,MAAM,6EAiBhB;IAED;;;;;;;;;;OAUG;IACH,yBATW,aAAa,WACb,MAAM,WACN,MAAM,WACN,MAAM,cACN,MAAM,cACN,MAAM,cACN,MAAM,GACJ,OAAO,CAQnB;IAED;;;;;;OAMG;IACH,kCALW,aAAa,KACb,MAAM,KACN,MAAM,GACL,OAAO,CAIlB;IAED;;;;;OAKG;IACH,gCAJW,cAAe,qDAmDzB;IAED;;;;;;OAMG;IACH,wBALW,MAAO,OAAO,CAAC,UACf,SAAS,qDAkBnB;IAED;;;;;OAKG;IACH,sBAJW,MAAM,KACN,MAAM,yBAiBhB;IAED;;;;OAIG;IACH,wCAFW,OAAO,QASjB;IAED;;;OAGG;IACH,gCAsBC;IAED,
|
|
1
|
+
{"version":3,"file":"Terrain.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/ecs/terrain/ecs/Terrain.js"],"names":[],"mappings":"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"}
|
|
@@ -586,7 +586,12 @@ class Terrain {
|
|
|
586
586
|
|
|
587
587
|
uniforms.splatWeightMap.value = this.splat.weightTexture;
|
|
588
588
|
|
|
589
|
-
|
|
589
|
+
// Update layer count as a compile-time define (AMD GLSL 300 ES requires constant loop bounds)
|
|
590
|
+
const layerCount = this.layers.count();
|
|
591
|
+
if (m.defines.SPLAT_LAYER_COUNT !== layerCount) {
|
|
592
|
+
m.defines.SPLAT_LAYER_COUNT = layerCount;
|
|
593
|
+
m.needsUpdate = true;
|
|
594
|
+
}
|
|
590
595
|
|
|
591
596
|
uniforms.materialScalesMap.value = this.layers.scalesTexture;
|
|
592
597
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TerrainLayer.d.ts","sourceRoot":"","sources":["../../../../../../../src/engine/ecs/terrain/ecs/layers/TerrainLayer.js"],"names":[],"mappings":"AA2BA;IA+CI;;;;;OAKG;IACH,iBAJW,MAAM,SACN,MAAM,UACN,MAAM,gBAShB;IAED;;;;OAIG;IACH,oDAFa,YAAY,CAQxB;IAvED;;;OAGG;IACH,0BAAuB;IAEvB;;;OAGG;IACH,SAFU,SAAS,CAEgB;IAEnC;;;OAGG;IACH,MAFU,OAAO,CAEQ;IAEzB;;;OAGG;IACH,WAAW;IAEX;;;OAGG;IACH,WAFU,MAAM,CAES;IAGzB;;;;;;;MAMC;IAED;;;;aAIC;IA8BD;;;;OAIG;IACH,
|
|
1
|
+
{"version":3,"file":"TerrainLayer.d.ts","sourceRoot":"","sources":["../../../../../../../src/engine/ecs/terrain/ecs/layers/TerrainLayer.js"],"names":[],"mappings":"AA2BA;IA+CI;;;;;OAKG;IACH,iBAJW,MAAM,SACN,MAAM,UACN,MAAM,gBAShB;IAED;;;;OAIG;IACH,oDAFa,YAAY,CAQxB;IAvED;;;OAGG;IACH,0BAAuB;IAEvB;;;OAGG;IACH,SAFU,SAAS,CAEgB;IAEnC;;;OAGG;IACH,MAFU,OAAO,CAEQ;IAEzB;;;OAGG;IACH,WAAW;IAEX;;;OAGG;IACH,WAFU,MAAM,CAES;IAGzB;;;;;;;MAMC;IAED;;;;aAIC;IA8BD;;;;OAIG;IACH,0DAyDC;IAGL;;;OAGG;IACH,yBAFU,OAAO,CAEoB;CANpC;0BA/JyB,mDAAmD;oBAJzD,qCAAqC;mBADtC,6CAA6C"}
|
|
@@ -5,7 +5,7 @@ import { computeStringHash } from "../../../../../core/primitives/strings/comput
|
|
|
5
5
|
import { string_compute_byte_size } from "../../../../../core/primitives/strings/string_compute_byte_size.js";
|
|
6
6
|
import { GameAssetType } from "../../../../asset/GameAssetType.js";
|
|
7
7
|
import { Sampler2D } from "../../../../graphics/texture/sampler/Sampler2D.js";
|
|
8
|
-
import {
|
|
8
|
+
import { sampler2d_ensure_uint8_RGBA } from "../../../../graphics/texture/sampler/sampler2d_ensure_uint8_RGBA.js";
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
11
|
*
|
|
@@ -37,7 +37,7 @@ export class TerrainLayer {
|
|
|
37
37
|
*
|
|
38
38
|
* @type {Sampler2D}
|
|
39
39
|
*/
|
|
40
|
-
diffuse = Sampler2D.uint8(
|
|
40
|
+
diffuse = Sampler2D.uint8(4, 1, 1);
|
|
41
41
|
|
|
42
42
|
/**
|
|
43
43
|
*
|
|
@@ -135,21 +135,22 @@ export class TerrainLayer {
|
|
|
135
135
|
.then(assert => {
|
|
136
136
|
const image = assert.create();
|
|
137
137
|
|
|
138
|
+
const source_data = image.data;
|
|
138
139
|
const source_item_size = image.itemSize;
|
|
139
140
|
|
|
140
|
-
|
|
141
|
+
// RGBA (4 channels) for AMD GPU compatibility
|
|
142
|
+
const destination_item_size = 4;
|
|
143
|
+
|
|
144
|
+
const source = new Sampler2D(source_data, source_item_size, image.width, image.height);
|
|
141
145
|
|
|
142
|
-
//
|
|
143
|
-
const
|
|
146
|
+
// Convert to uint8 RGBA, handling any source format
|
|
147
|
+
const rgba = sampler2d_ensure_uint8_RGBA(source);
|
|
144
148
|
|
|
145
149
|
if (this.diffuse === null || this.diffuse.width !== image.width || this.diffuse.height !== image.height) {
|
|
146
|
-
// loaded image does not match the side of the layer
|
|
147
150
|
this.diffuse = Sampler2D.uint8(destination_item_size, image.width, image.height);
|
|
148
151
|
}
|
|
149
152
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
sampler2d_transfer_data(source, this.diffuse);
|
|
153
|
+
this.diffuse.data.set(rgba.data);
|
|
153
154
|
|
|
154
155
|
this.onChanged.send0();
|
|
155
156
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TerrainLayers.d.ts","sourceRoot":"","sources":["../../../../../../../src/engine/ecs/terrain/ecs/layers/TerrainLayers.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"TerrainLayers.d.ts","sourceRoot":"","sources":["../../../../../../../src/engine/ecs/terrain/ecs/layers/TerrainLayers.js"],"names":[],"mappings":"AA8EA;IAGQ;;;OAGG;IACH,QAFU,KAAK,YAAY,CAAC,CAEJ;IAExB;;;OAGG;IACH,YAFU,OAAO,CAEoD;IAMrE;;;OAGG;IACH,SAFU,kBAAkB,CAE8B;IAiB1D,2BAAsF;IAc1F;;;;;;MAKC;IAED;;;aAGC;IAED;;;;OAIG;IACH,gCAHW,MAAM,iBACN,MAAM,QAuChB;IAED;;;;OAIG;IACH,0DAyBC;IAED,sCAIC;IAED;;;;OAIG;IACH,WAHW,MAAM,GACL,YAAY,CAIvB;IAED;;;;OAIG;IACH,8DAFa,MAAM,CAqBlB;IAED;;;;OAIG;IACH,kCAHW,MAAM,GACJ,MAAM,CAMlB;IAED;;;OAGG;IACH,SAFY,MAAM,CAIjB;IAED;;;;OAIG;IACH,gBAHW,YAAY,GACV,MAAM,CAWlB;IAED;;;;OAIG;IACH,mBAHW,YAAY,GACX,OAAO,CAIlB;IAED;;;;;;OAMG;IACH,0CAgCC;IAED;;;OAGG;IACH,iCAFW,MAAM,QAgChB;IAED,gBAGC;IAED,cAEC;IAGD,qBAsCC;CACJ;iBA9ZgB,6CAA6C;6BAQjC,mBAAmB;oBAP5B,qCAAqC;mCALlD,OAAO;4BAAP,OAAO"}
|
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
LinearMipMapLinearFilter,
|
|
9
9
|
NearestFilter,
|
|
10
10
|
RepeatWrapping,
|
|
11
|
+
RGBAFormat,
|
|
11
12
|
RGFormat,
|
|
12
13
|
UnsignedByteType
|
|
13
14
|
} from "three";
|
|
@@ -19,9 +20,9 @@ import Vector2 from "../../../../../core/geom/Vector2.js";
|
|
|
19
20
|
import { invokeObjectEquals } from "../../../../../core/model/object/invokeObjectEquals.js";
|
|
20
21
|
import { invokeObjectHash } from "../../../../../core/model/object/invokeObjectHash.js";
|
|
21
22
|
import { computeStringHash } from "../../../../../core/primitives/strings/computeStringHash.js";
|
|
22
|
-
import { GL_RGBFormat } from "../../../../graphics/texture/GL_RGBFormat.js";
|
|
23
23
|
import { sampler2d_scale } from "../../../../graphics/texture/sampler/resize/sampler2d_scale.js";
|
|
24
24
|
import { Sampler2D } from "../../../../graphics/texture/sampler/Sampler2D.js";
|
|
25
|
+
import { sampler2d_ensure_uint8_RGBA } from "../../../../graphics/texture/sampler/sampler2d_ensure_uint8_RGBA.js";
|
|
25
26
|
import { TerrainLayer } from "./TerrainLayer.js";
|
|
26
27
|
|
|
27
28
|
class ScaledTextureKey {
|
|
@@ -91,7 +92,7 @@ export class TerrainLayers {
|
|
|
91
92
|
this.resolution = new Vector2(DEFAULT_RESOLUTION, DEFAULT_RESOLUTION);
|
|
92
93
|
|
|
93
94
|
|
|
94
|
-
const layer_data = new Uint8Array(
|
|
95
|
+
const layer_data = new Uint8Array(4);
|
|
95
96
|
layer_data.fill(255); //pre-fill with white
|
|
96
97
|
|
|
97
98
|
/**
|
|
@@ -99,7 +100,7 @@ export class TerrainLayers {
|
|
|
99
100
|
* @type {DataTexture2DArray}
|
|
100
101
|
*/
|
|
101
102
|
this.texture = new DataTexture2DArray(layer_data, 1, 1, 1);
|
|
102
|
-
this.texture.format =
|
|
103
|
+
this.texture.format = RGBAFormat;
|
|
103
104
|
this.texture.type = UnsignedByteType;
|
|
104
105
|
|
|
105
106
|
this.texture.wrapS = RepeatWrapping;
|
|
@@ -112,7 +113,7 @@ export class TerrainLayers {
|
|
|
112
113
|
|
|
113
114
|
this.texture.generateMipmaps = true;
|
|
114
115
|
this.texture.encoding = LinearEncoding;
|
|
115
|
-
this.texture.internalFormat = '
|
|
116
|
+
this.texture.internalFormat = 'RGBA8';
|
|
116
117
|
this.texture.needsUpdate = true;
|
|
117
118
|
|
|
118
119
|
this.scalesTexture = new DataTexture(new Float32Array(64), 32, 1, RGFormat, FloatType);
|
|
@@ -312,7 +313,7 @@ export class TerrainLayers {
|
|
|
312
313
|
__obtain_layer_data_at_resolution(layer, resolution) {
|
|
313
314
|
const layerSampler = layer.diffuse;
|
|
314
315
|
|
|
315
|
-
assert.equal(layerSampler.itemSize,
|
|
316
|
+
assert.equal(layerSampler.itemSize, 4, 'layer sampler must have 4 channels');
|
|
316
317
|
|
|
317
318
|
const resolution_x = resolution.x;
|
|
318
319
|
const resolution_y = resolution.y;
|
|
@@ -330,14 +331,16 @@ export class TerrainLayers {
|
|
|
330
331
|
return existing;
|
|
331
332
|
}
|
|
332
333
|
|
|
333
|
-
const scaledLayerSampler = Sampler2D.uint8(
|
|
334
|
+
const scaledLayerSampler = Sampler2D.uint8(4, resolution_x, resolution_y);
|
|
334
335
|
|
|
335
336
|
sampler2d_scale(layerSampler, scaledLayerSampler);
|
|
336
337
|
|
|
337
|
-
//
|
|
338
|
-
|
|
338
|
+
// Ensure result is uint8 RGBA
|
|
339
|
+
const rgba = sampler2d_ensure_uint8_RGBA(scaledLayerSampler);
|
|
339
340
|
|
|
340
|
-
|
|
341
|
+
scaled_texture_cache.put(key, rgba);
|
|
342
|
+
|
|
343
|
+
return rgba;
|
|
341
344
|
}
|
|
342
345
|
}
|
|
343
346
|
|
|
@@ -359,7 +362,7 @@ export class TerrainLayers {
|
|
|
359
362
|
|
|
360
363
|
const resolution = this.resolution;
|
|
361
364
|
|
|
362
|
-
const single_layer_byte_size = resolution.x * resolution.y *
|
|
365
|
+
const single_layer_byte_size = resolution.x * resolution.y * 4;
|
|
363
366
|
|
|
364
367
|
if (arrayData.length < single_layer_byte_size * index) {
|
|
365
368
|
throw new Error('Texture data is too small, make sure you rebuild texture data before attempting to write');
|
|
@@ -411,7 +414,7 @@ export class TerrainLayers {
|
|
|
411
414
|
texture.dispose();
|
|
412
415
|
|
|
413
416
|
//build an array to hold texture array
|
|
414
|
-
const arrayData = new Uint8Array(size_x * size_y *
|
|
417
|
+
const arrayData = new Uint8Array(size_x * size_y * 4 * layerCount);
|
|
415
418
|
arrayData.fill(255); // fill with white
|
|
416
419
|
|
|
417
420
|
if (image.width === size_x && image.height === size_y) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WaterSystem.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/graphics/ecs/water/WaterSystem.js"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"WaterSystem.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/graphics/ecs/water/WaterSystem.js"],"names":[],"mappings":";AAYA;IAyBI;;;;OAIG;IACH,sCAYC;IAzCD,+BAAuB;IAEvB;;;OAGG;IACH,cAFU,GAAG,CAEG;IAGhB,cAAY;IAEZ;;;OAGG;IACH,aAFU,KAAK,EAAE,CAEA;IAEjB;;;;OAIG;IACH,qBAAiB;IAWb,+BAA8B;IAE9B;;;OAGG;IACH,aAFU,cAAY,IAAI,CAEH;IAK3B,4CAMC;IAED,2CA4DC;IAED;;;;OAIG;IACH,gBAHW,KAAK,UACL,MAAM,QAsDhB;IAED;;;;OAIG;IACH,kBAHW,KAAK,UACL,MAAM,QAgBhB;IAED,2BAgCC;IAED;;;;;OAKG;IACH,0BAUC;IAED,6BAcC;CACJ;;;;uBA/QsB,wBAAwB;kBAM7B,YAAY;oBAPV,mCAAmC"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { BackSide, PlaneBufferGeometry } from 'three';
|
|
2
|
+
import { assert } from "../../../../core/assert.js";
|
|
2
3
|
import { BVH } from "../../../../core/bvh2/bvh3/BVH.js";
|
|
3
4
|
import { System } from '../../../ecs/System.js';
|
|
4
5
|
import { obtainTerrain } from "../../../ecs/terrain/util/obtainTerrain.js";
|
|
@@ -76,6 +77,8 @@ class WaterSystem extends System {
|
|
|
76
77
|
(destination, offset, entity, ecd) => {
|
|
77
78
|
const component = ecd.getComponent(entity, Water);
|
|
78
79
|
|
|
80
|
+
assert.defined(component, 'component');
|
|
81
|
+
|
|
79
82
|
const mesh = component.__threeObject;
|
|
80
83
|
|
|
81
84
|
if (mesh === null) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SplatMaterial.d.ts","sourceRoot":"","sources":["../../../../../src/engine/graphics/material/SplatMaterial.js"],"names":[],"mappings":"AAgBA;;;;;;;;GAQG;AACH,oFAPW,OAAO,GAIN,cAAc,
|
|
1
|
+
{"version":3,"file":"SplatMaterial.d.ts","sourceRoot":"","sources":["../../../../../src/engine/graphics/material/SplatMaterial.js"],"names":[],"mappings":"AAgBA;;;;;;;;GAQG;AACH,oFAPW,OAAO,GAIN,cAAc,CAgIzB;;IAtID;;;;;;;;OAQG;IACH,kEAPW,OAAO,EAoIjB;;wBA1IM,OAAO;+BAAP,OAAO"}
|
|
@@ -47,10 +47,7 @@ export function SplatMaterial(
|
|
|
47
47
|
type: "t",
|
|
48
48
|
value: null
|
|
49
49
|
},
|
|
50
|
-
|
|
51
|
-
type: "f",
|
|
52
|
-
value: 4
|
|
53
|
-
},
|
|
50
|
+
|
|
54
51
|
"splatResolution": {
|
|
55
52
|
type: 'v2',
|
|
56
53
|
value: new Vector2(1, 1)
|
|
@@ -115,6 +112,7 @@ export function SplatMaterial(
|
|
|
115
112
|
transparent: false,
|
|
116
113
|
lights: true,
|
|
117
114
|
defines: {
|
|
115
|
+
SPLAT_LAYER_COUNT: 4,
|
|
118
116
|
SHADOWMAP_CLOUDS: false,
|
|
119
117
|
DIFFUSE_GRAIN: false
|
|
120
118
|
},
|
|
@@ -95,7 +95,7 @@ function fragment() {
|
|
|
95
95
|
precision highp sampler2DArray;
|
|
96
96
|
|
|
97
97
|
uniform sampler2DArray splatWeightMap;
|
|
98
|
-
|
|
98
|
+
// SPLAT_LAYER_COUNT is injected as a #define from the material defines
|
|
99
99
|
|
|
100
100
|
uniform vec2 splatResolution;
|
|
101
101
|
|
|
@@ -240,14 +240,7 @@ function fragment() {
|
|
|
240
240
|
return hsv2rgb(hsv);
|
|
241
241
|
}
|
|
242
242
|
|
|
243
|
-
|
|
244
|
-
vec3 yiq = rgb2yiq*color;
|
|
245
|
-
|
|
246
|
-
yiq.x *= p;
|
|
247
|
-
yiq.x = pow(yiq.x,factor);
|
|
248
|
-
|
|
249
|
-
return yiq2rgb * yiq;
|
|
250
|
-
}
|
|
243
|
+
|
|
251
244
|
|
|
252
245
|
vec4 computeGridOverlayTexel(const in vec2 grid_uv, const in vec2 grid_resolution){
|
|
253
246
|
vec2 grid_texel = vGridPosition + 0.5;
|
|
@@ -276,7 +269,7 @@ function fragment() {
|
|
|
276
269
|
float weightSum = 0.0;
|
|
277
270
|
vec4 colorSum = vec4(0.0);
|
|
278
271
|
|
|
279
|
-
for( int i = 0; i <
|
|
272
|
+
for( int i = 0; i < SPLAT_LAYER_COUNT; i++){
|
|
280
273
|
|
|
281
274
|
vec2 scale = texelFetch(materialScalesMap, ivec2(i, 0), 0 ).xy;
|
|
282
275
|
|
|
@@ -290,7 +283,7 @@ function fragment() {
|
|
|
290
283
|
colorSum += diffuseData*weight;
|
|
291
284
|
}
|
|
292
285
|
|
|
293
|
-
return colorSum / weightSum;
|
|
286
|
+
return weightSum > 0.0 ? colorSum / weightSum : vec4(0.0);
|
|
294
287
|
}
|
|
295
288
|
|
|
296
289
|
${ShaderChunks.clouds_pars_fragment}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GJK intersection test for two convex shapes.
|
|
3
|
+
*
|
|
4
|
+
* Determines whether two convex shapes overlap by iteratively building a simplex
|
|
5
|
+
* in the Minkowski difference space. If the origin is enclosed by the simplex,
|
|
6
|
+
* the shapes intersect.
|
|
7
|
+
*
|
|
8
|
+
* Adapted from https://github.com/kevinmoran/GJK/blob/master/GJK.h
|
|
9
|
+
*
|
|
10
|
+
* @param {number[]|Float32Array} simplex Working buffer for simplex vertices (4 vec3s). Must have length >= 12.
|
|
11
|
+
* @param {AbstractShape3D} shape_a
|
|
12
|
+
* @param {AbstractShape3D} shape_b
|
|
13
|
+
* @returns {boolean} true if the shapes intersect
|
|
14
|
+
*/
|
|
15
|
+
export function gjk(simplex: number[] | Float32Array, shape_a: AbstractShape3D, shape_b: AbstractShape3D): boolean;
|
|
16
|
+
//# sourceMappingURL=gjk.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gjk.d.ts","sourceRoot":"","sources":["../../../../../src/engine/physics/gjk/gjk.js"],"names":[],"mappings":"AAmDA;;;;;;;;;;;;;GAaG;AACH,6BALW,MAAM,EAAE,GAAC,YAAY,uDAGnB,OAAO,CAkGnB"}
|
|
@@ -0,0 +1,378 @@
|
|
|
1
|
+
import { v3_dot } from "../../../core/geom/vec3/v3_dot.js";
|
|
2
|
+
import { v3_length } from "../../../core/geom/vec3/v3_length.js";
|
|
3
|
+
|
|
4
|
+
const GJK_MAX_ITERATIONS = 64;
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Module-level scratch buffers to avoid per-call allocations.
|
|
8
|
+
*/
|
|
9
|
+
const scratch_support_a = new Float32Array(3);
|
|
10
|
+
const scratch_support_b = new Float32Array(3);
|
|
11
|
+
const scratch_dir = new Float32Array(3);
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Compute the Minkowski difference support point for two shapes.
|
|
15
|
+
* support(A-B, d) = support(A, d) - support(B, -d)
|
|
16
|
+
*
|
|
17
|
+
* The direction is normalized before being passed to the shape support
|
|
18
|
+
* functions, since {@link AbstractShape3D#support} assumes a unit vector.
|
|
19
|
+
*
|
|
20
|
+
* @param {number[]|Float32Array} result
|
|
21
|
+
* @param {number} result_offset
|
|
22
|
+
* @param {AbstractShape3D} shape_a
|
|
23
|
+
* @param {AbstractShape3D} shape_b
|
|
24
|
+
* @param {number} dir_x
|
|
25
|
+
* @param {number} dir_y
|
|
26
|
+
* @param {number} dir_z
|
|
27
|
+
*/
|
|
28
|
+
function minkowski_support(
|
|
29
|
+
result, result_offset,
|
|
30
|
+
shape_a,
|
|
31
|
+
shape_b,
|
|
32
|
+
dir_x, dir_y, dir_z
|
|
33
|
+
) {
|
|
34
|
+
// Normalize direction — support() contract requires a unit vector
|
|
35
|
+
const len = v3_length(dir_x, dir_y, dir_z);
|
|
36
|
+
|
|
37
|
+
if (len > 0) {
|
|
38
|
+
const inv = 1 / len;
|
|
39
|
+
dir_x *= inv;
|
|
40
|
+
dir_y *= inv;
|
|
41
|
+
dir_z *= inv;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
shape_a.support(scratch_support_a, 0, dir_x, dir_y, dir_z);
|
|
45
|
+
shape_b.support(scratch_support_b, 0, -dir_x, -dir_y, -dir_z);
|
|
46
|
+
|
|
47
|
+
result[result_offset] = scratch_support_a[0] - scratch_support_b[0];
|
|
48
|
+
result[result_offset + 1] = scratch_support_a[1] - scratch_support_b[1];
|
|
49
|
+
result[result_offset + 2] = scratch_support_a[2] - scratch_support_b[2];
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* GJK intersection test for two convex shapes.
|
|
54
|
+
*
|
|
55
|
+
* Determines whether two convex shapes overlap by iteratively building a simplex
|
|
56
|
+
* in the Minkowski difference space. If the origin is enclosed by the simplex,
|
|
57
|
+
* the shapes intersect.
|
|
58
|
+
*
|
|
59
|
+
* Adapted from https://github.com/kevinmoran/GJK/blob/master/GJK.h
|
|
60
|
+
*
|
|
61
|
+
* @param {number[]|Float32Array} simplex Working buffer for simplex vertices (4 vec3s). Must have length >= 12.
|
|
62
|
+
* @param {AbstractShape3D} shape_a
|
|
63
|
+
* @param {AbstractShape3D} shape_b
|
|
64
|
+
* @returns {boolean} true if the shapes intersect
|
|
65
|
+
*/
|
|
66
|
+
export function gjk(simplex, shape_a, shape_b) {
|
|
67
|
+
|
|
68
|
+
const dir = scratch_dir;
|
|
69
|
+
|
|
70
|
+
// Initial search direction — arbitrary, (1,0,0)
|
|
71
|
+
|
|
72
|
+
// Get initial support point (simplex point C)
|
|
73
|
+
minkowski_support(
|
|
74
|
+
simplex, 6,
|
|
75
|
+
shape_a, shape_b,
|
|
76
|
+
1, 0, 0
|
|
77
|
+
);
|
|
78
|
+
|
|
79
|
+
// Search toward the origin from C
|
|
80
|
+
dir[0] = -simplex[6];
|
|
81
|
+
dir[1] = -simplex[7];
|
|
82
|
+
dir[2] = -simplex[8];
|
|
83
|
+
|
|
84
|
+
if (dir[0] === 0 && dir[1] === 0 && dir[2] === 0) {
|
|
85
|
+
// Origin is exactly on the first support point — intersection
|
|
86
|
+
return true;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// Get second support point (simplex point B)
|
|
90
|
+
minkowski_support(simplex, 3, shape_a, shape_b, dir[0], dir[1], dir[2]);
|
|
91
|
+
|
|
92
|
+
// B didn't pass the origin — no intersection possible
|
|
93
|
+
if (v3_dot(simplex[3], simplex[4], simplex[5], dir[0], dir[1], dir[2]) < 0) {
|
|
94
|
+
return false;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// Line case: compute direction perpendicular to line segment BC toward origin
|
|
98
|
+
// CB = C - B
|
|
99
|
+
const cb_x = simplex[6] - simplex[3];
|
|
100
|
+
const cb_y = simplex[7] - simplex[4];
|
|
101
|
+
const cb_z = simplex[8] - simplex[5];
|
|
102
|
+
|
|
103
|
+
// BO = -B (origin - B)
|
|
104
|
+
const bo_x = -simplex[3];
|
|
105
|
+
const bo_y = -simplex[4];
|
|
106
|
+
const bo_z = -simplex[5];
|
|
107
|
+
|
|
108
|
+
// dir = CB × BO × CB (triple cross product)
|
|
109
|
+
triple_cross_product(dir, cb_x, cb_y, cb_z, bo_x, bo_y, bo_z);
|
|
110
|
+
|
|
111
|
+
// Handle degenerate case where origin is on the line segment
|
|
112
|
+
if (dir[0] === 0 && dir[1] === 0 && dir[2] === 0) {
|
|
113
|
+
// Origin is on the line segment — pick any perpendicular direction
|
|
114
|
+
// Use the cross product of CB with an arbitrary axis
|
|
115
|
+
// CB × (1,0,0)
|
|
116
|
+
dir[0] = cb_y;
|
|
117
|
+
dir[1] = -cb_x;
|
|
118
|
+
dir[2] = 0;
|
|
119
|
+
|
|
120
|
+
if (dir[0] === 0 && dir[1] === 0 && dir[2] === 0) {
|
|
121
|
+
// CB is parallel to (1,0,0), use (0,1,0)
|
|
122
|
+
dir[0] = -cb_z;
|
|
123
|
+
dir[1] = 0;
|
|
124
|
+
dir[2] = cb_x;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
let simplex_size = 2; // we have B and C
|
|
129
|
+
|
|
130
|
+
for (let iterations = 0; iterations < GJK_MAX_ITERATIONS; iterations++) {
|
|
131
|
+
// Get new support point A
|
|
132
|
+
minkowski_support(simplex, 0, shape_a, shape_b, dir[0], dir[1], dir[2]);
|
|
133
|
+
|
|
134
|
+
const a_x = simplex[0];
|
|
135
|
+
const a_y = simplex[1];
|
|
136
|
+
const a_z = simplex[2];
|
|
137
|
+
|
|
138
|
+
// Check if A passed the origin
|
|
139
|
+
if (v3_dot(a_x, a_y, a_z, dir[0], dir[1], dir[2]) < 0) {
|
|
140
|
+
return false; // no intersection
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
simplex_size++;
|
|
144
|
+
|
|
145
|
+
if (simplex_size === 3) {
|
|
146
|
+
// Triangle case
|
|
147
|
+
update_simplex_triangle(dir, simplex);
|
|
148
|
+
} else {
|
|
149
|
+
// Tetrahedron case
|
|
150
|
+
if (update_simplex_tetrahedron(dir, simplex)) {
|
|
151
|
+
// Origin is inside the tetrahedron — intersection!
|
|
152
|
+
return true;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// The simplex was reduced to a triangle, so keep size at 3
|
|
156
|
+
simplex_size = 3;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// Did not converge — assume no intersection
|
|
161
|
+
return false;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Compute the triple cross product: (a × b) × a
|
|
166
|
+
*
|
|
167
|
+
* @param {number[]|Float32Array} result output vec3
|
|
168
|
+
* @param {number} ax
|
|
169
|
+
* @param {number} ay
|
|
170
|
+
* @param {number} az
|
|
171
|
+
* @param {number} bx
|
|
172
|
+
* @param {number} by
|
|
173
|
+
* @param {number} bz
|
|
174
|
+
*/
|
|
175
|
+
function triple_cross_product(result, ax, ay, az, bx, by, bz) {
|
|
176
|
+
// First: t = a × b
|
|
177
|
+
const tx = ay * bz - az * by;
|
|
178
|
+
const ty = az * bx - ax * bz;
|
|
179
|
+
const tz = ax * by - ay * bx;
|
|
180
|
+
|
|
181
|
+
// Then: t × a
|
|
182
|
+
result[0] = ty * az - tz * ay;
|
|
183
|
+
result[1] = tz * ax - tx * az;
|
|
184
|
+
result[2] = tx * ay - ty * ax;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* Update simplex for the triangle case (3 points: A, B, C).
|
|
189
|
+
*
|
|
190
|
+
* Determines the Voronoi region of the origin relative to triangle ABC
|
|
191
|
+
* and updates the search direction accordingly.
|
|
192
|
+
*
|
|
193
|
+
* simplex layout: [A(0-2), B(3-5), C(6-8)]
|
|
194
|
+
*
|
|
195
|
+
* @param {number[]|Float32Array} search_dir output: next search direction
|
|
196
|
+
* @param {Float32Array} simplex
|
|
197
|
+
*/
|
|
198
|
+
function update_simplex_triangle(search_dir, simplex) {
|
|
199
|
+
const a_x = simplex[0], a_y = simplex[1], a_z = simplex[2];
|
|
200
|
+
const b_x = simplex[3], b_y = simplex[4], b_z = simplex[5];
|
|
201
|
+
const c_x = simplex[6], c_y = simplex[7], c_z = simplex[8];
|
|
202
|
+
|
|
203
|
+
// AB = B - A
|
|
204
|
+
const ab_x = b_x - a_x;
|
|
205
|
+
const ab_y = b_y - a_y;
|
|
206
|
+
const ab_z = b_z - a_z;
|
|
207
|
+
|
|
208
|
+
// AC = C - A
|
|
209
|
+
const ac_x = c_x - a_x;
|
|
210
|
+
const ac_y = c_y - a_y;
|
|
211
|
+
const ac_z = c_z - a_z;
|
|
212
|
+
|
|
213
|
+
// AO = -A (origin - A)
|
|
214
|
+
const ao_x = -a_x;
|
|
215
|
+
const ao_y = -a_y;
|
|
216
|
+
const ao_z = -a_z;
|
|
217
|
+
|
|
218
|
+
// Normal of triangle ABC
|
|
219
|
+
const abc_x = ab_y * ac_z - ab_z * ac_y;
|
|
220
|
+
const abc_y = ab_z * ac_x - ab_x * ac_z;
|
|
221
|
+
const abc_z = ab_x * ac_y - ab_y * ac_x;
|
|
222
|
+
|
|
223
|
+
// Test edge AC
|
|
224
|
+
// ABC × AC
|
|
225
|
+
const abc_cross_ac_x = abc_y * ac_z - abc_z * ac_y;
|
|
226
|
+
const abc_cross_ac_y = abc_z * ac_x - abc_x * ac_z;
|
|
227
|
+
const abc_cross_ac_z = abc_x * ac_y - abc_y * ac_x;
|
|
228
|
+
|
|
229
|
+
if (v3_dot(abc_cross_ac_x, abc_cross_ac_y, abc_cross_ac_z, ao_x, ao_y, ao_z) > 0) {
|
|
230
|
+
// Origin is on the AC side
|
|
231
|
+
// Reduce simplex to line AC (A stays as A, C moves to B position)
|
|
232
|
+
simplex[3] = c_x;
|
|
233
|
+
simplex[4] = c_y;
|
|
234
|
+
simplex[5] = c_z;
|
|
235
|
+
|
|
236
|
+
// New direction: AC × AO × AC
|
|
237
|
+
triple_cross_product(search_dir, ac_x, ac_y, ac_z, ao_x, ao_y, ao_z);
|
|
238
|
+
return;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
// Test edge AB
|
|
242
|
+
// AB × ABC
|
|
243
|
+
const ab_cross_abc_x = ab_y * abc_z - ab_z * abc_y;
|
|
244
|
+
const ab_cross_abc_y = ab_z * abc_x - ab_x * abc_z;
|
|
245
|
+
const ab_cross_abc_z = ab_x * abc_y - ab_y * abc_x;
|
|
246
|
+
|
|
247
|
+
if (v3_dot(ab_cross_abc_x, ab_cross_abc_y, ab_cross_abc_z, ao_x, ao_y, ao_z) > 0) {
|
|
248
|
+
// Origin is on the AB side
|
|
249
|
+
// Keep simplex as line AB (C slot is cleared by not using it)
|
|
250
|
+
simplex[6] = simplex[3];
|
|
251
|
+
simplex[7] = simplex[4];
|
|
252
|
+
simplex[8] = simplex[5];
|
|
253
|
+
|
|
254
|
+
// New direction: AB × AO × AB
|
|
255
|
+
triple_cross_product(search_dir, ab_x, ab_y, ab_z, ao_x, ao_y, ao_z);
|
|
256
|
+
return;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
// Origin is above or below the triangle
|
|
260
|
+
if (v3_dot(abc_x, abc_y, abc_z, ao_x, ao_y, ao_z) > 0) {
|
|
261
|
+
// Origin is above — search in normal direction
|
|
262
|
+
// Simplex stays as A, B, C
|
|
263
|
+
search_dir[0] = abc_x;
|
|
264
|
+
search_dir[1] = abc_y;
|
|
265
|
+
search_dir[2] = abc_z;
|
|
266
|
+
} else {
|
|
267
|
+
// Origin is below — swap B and C, search in -normal
|
|
268
|
+
const tmp_x = simplex[3], tmp_y = simplex[4], tmp_z = simplex[5];
|
|
269
|
+
simplex[3] = simplex[6];
|
|
270
|
+
simplex[4] = simplex[7];
|
|
271
|
+
simplex[5] = simplex[8];
|
|
272
|
+
simplex[6] = tmp_x;
|
|
273
|
+
simplex[7] = tmp_y;
|
|
274
|
+
simplex[8] = tmp_z;
|
|
275
|
+
|
|
276
|
+
search_dir[0] = -abc_x;
|
|
277
|
+
search_dir[1] = -abc_y;
|
|
278
|
+
search_dir[2] = -abc_z;
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
/**
|
|
283
|
+
* Update simplex for the tetrahedron case (4 points: A, B, C, D).
|
|
284
|
+
*
|
|
285
|
+
* Tests which face of the tetrahedron is closest to the origin and
|
|
286
|
+
* reduces the simplex accordingly. Returns true if the origin is
|
|
287
|
+
* inside the tetrahedron.
|
|
288
|
+
*
|
|
289
|
+
* simplex layout: [A(0-2), B(3-5), C(6-8), D(9-11)]
|
|
290
|
+
*
|
|
291
|
+
* @param {number[]|Float32Array} search_dir output: next search direction (only written when returning false)
|
|
292
|
+
* @param {Float32Array} simplex
|
|
293
|
+
* @returns {boolean} true if origin is inside the tetrahedron
|
|
294
|
+
*/
|
|
295
|
+
function update_simplex_tetrahedron(search_dir, simplex) {
|
|
296
|
+
const a_x = simplex[0], a_y = simplex[1], a_z = simplex[2];
|
|
297
|
+
const b_x = simplex[3], b_y = simplex[4], b_z = simplex[5];
|
|
298
|
+
const c_x = simplex[6], c_y = simplex[7], c_z = simplex[8];
|
|
299
|
+
const d_x = simplex[9], d_y = simplex[10], d_z = simplex[11];
|
|
300
|
+
|
|
301
|
+
// AB, AC, AD vectors
|
|
302
|
+
const ab_x = b_x - a_x, ab_y = b_y - a_y, ab_z = b_z - a_z;
|
|
303
|
+
const ac_x = c_x - a_x, ac_y = c_y - a_y, ac_z = c_z - a_z;
|
|
304
|
+
const ad_x = d_x - a_x, ad_y = d_y - a_y, ad_z = d_z - a_z;
|
|
305
|
+
|
|
306
|
+
// AO = origin - A = -A
|
|
307
|
+
const ao_x = -a_x, ao_y = -a_y, ao_z = -a_z;
|
|
308
|
+
|
|
309
|
+
// Face normals (outward-facing from A's perspective)
|
|
310
|
+
// ABC normal
|
|
311
|
+
const abc_x = ab_y * ac_z - ab_z * ac_y;
|
|
312
|
+
const abc_y = ab_z * ac_x - ab_x * ac_z;
|
|
313
|
+
const abc_z = ab_x * ac_y - ab_y * ac_x;
|
|
314
|
+
|
|
315
|
+
// ACD normal
|
|
316
|
+
const acd_x = ac_y * ad_z - ac_z * ad_y;
|
|
317
|
+
const acd_y = ac_z * ad_x - ac_x * ad_z;
|
|
318
|
+
const acd_z = ac_x * ad_y - ac_y * ad_x;
|
|
319
|
+
|
|
320
|
+
// ADB normal
|
|
321
|
+
const adb_x = ad_y * ab_z - ad_z * ab_y;
|
|
322
|
+
const adb_y = ad_z * ab_x - ad_x * ab_z;
|
|
323
|
+
const adb_z = ad_x * ab_y - ad_y * ab_x;
|
|
324
|
+
|
|
325
|
+
// Test each face to see if the origin is on the outside
|
|
326
|
+
|
|
327
|
+
// Check face ABC (opposite to D)
|
|
328
|
+
const abc_test = v3_dot(abc_x, abc_y, abc_z, ao_x, ao_y, ao_z);
|
|
329
|
+
// Make sure normal points away from D
|
|
330
|
+
const abc_d_side = v3_dot(abc_x, abc_y, abc_z, ad_x, ad_y, ad_z);
|
|
331
|
+
|
|
332
|
+
if (abc_test * abc_d_side < 0) {
|
|
333
|
+
// Origin is on the opposite side of ABC from D
|
|
334
|
+
// Reduce to triangle ABC: D is dropped
|
|
335
|
+
// simplex = [A, B, C] — A(0), B(3), C(6) already in place
|
|
336
|
+
update_simplex_triangle(search_dir, simplex);
|
|
337
|
+
return false;
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
// Check face ACD (opposite to B)
|
|
341
|
+
const acd_test = v3_dot(acd_x, acd_y, acd_z, ao_x, ao_y, ao_z);
|
|
342
|
+
const acd_b_side = v3_dot(acd_x, acd_y, acd_z, ab_x, ab_y, ab_z);
|
|
343
|
+
|
|
344
|
+
if (acd_test * acd_b_side < 0) {
|
|
345
|
+
// Origin is outside face ACD
|
|
346
|
+
// Reduce to triangle ACD: replace B with D
|
|
347
|
+
simplex[3] = c_x;
|
|
348
|
+
simplex[4] = c_y;
|
|
349
|
+
simplex[5] = c_z;
|
|
350
|
+
simplex[6] = d_x;
|
|
351
|
+
simplex[7] = d_y;
|
|
352
|
+
simplex[8] = d_z;
|
|
353
|
+
|
|
354
|
+
update_simplex_triangle(search_dir, simplex);
|
|
355
|
+
return false;
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
// Check face ADB (opposite to C)
|
|
359
|
+
const adb_test = v3_dot(adb_x, adb_y, adb_z, ao_x, ao_y, ao_z);
|
|
360
|
+
const adb_c_side = v3_dot(adb_x, adb_y, adb_z, ac_x, ac_y, ac_z);
|
|
361
|
+
|
|
362
|
+
if (adb_test * adb_c_side < 0) {
|
|
363
|
+
// Origin is outside face ADB
|
|
364
|
+
// Reduce to triangle ADB: replace C with B, B with D
|
|
365
|
+
simplex[6] = b_x;
|
|
366
|
+
simplex[7] = b_y;
|
|
367
|
+
simplex[8] = b_z;
|
|
368
|
+
simplex[3] = d_x;
|
|
369
|
+
simplex[4] = d_y;
|
|
370
|
+
simplex[5] = d_z;
|
|
371
|
+
|
|
372
|
+
update_simplex_triangle(search_dir, simplex);
|
|
373
|
+
return false;
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
// Origin is inside the tetrahedron
|
|
377
|
+
return true;
|
|
378
|
+
}
|