@woosh/meep-engine 2.78.0 → 2.79.0
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/build/meep.cjs +87 -63
- package/build/meep.min.js +1 -1
- package/build/meep.module.js +87 -63
- package/package.json +1 -1
- package/src/core/{graph → geom/3d/topology}/build_face_graph_from_mesh.js +5 -5
- package/src/core/geom/Quaternion.js +1 -1
- package/src/core/geom/vec3/v3_angle_between.js +15 -4
- package/src/core/geom/vec3/{v3_computeOffsetVector.js → v3_displace_in_direction.js} +11 -2
- package/src/core/graph/Edge.js +10 -22
- package/src/core/graph/Edge.spec.js +35 -0
- package/src/core/graph/MultiNode.js +6 -7
- package/src/core/graph/v2/Graph.js +20 -8
- package/src/core/graph/v2/NodeContainer.js +1 -0
- package/src/engine/ecs/ik/OneBoneSurfaceAlignmentSolver.js +2 -2
- package/src/engine/ecs/ik/TwoBoneInverseKinematicsSolver.js +2 -2
- package/src/engine/ecs/transform-attachment/TransformAttachment.js +2 -1
- package/src/engine/ecs/transform-attachment/TransformAttachmentSystem.js +45 -33
- package/src/core/graph/EdgeDirection.js +0 -11
- package/src/core/primitives/strings/prefixTree/PrefixTree.js +0 -225
- package/src/core/primitives/strings/prefixTree/PrefixTree.spec.js +0 -39
- package/src/core/primitives/strings/prefixTree/PrefixTreeLeaf.js +0 -25
- package/src/core/primitives/strings/prefixTree/PrefixTreeNode.js +0 -16
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { assert } from "../../../core/assert.js";
|
|
2
2
|
import { SurfacePoint3 } from "../../../core/geom/3d/SurfacePoint3.js";
|
|
3
3
|
import Quaternion from "../../../core/geom/Quaternion.js";
|
|
4
|
-
import {
|
|
4
|
+
import { v3_displace_in_direction } from "../../../core/geom/vec3/v3_displace_in_direction.js";
|
|
5
5
|
import { v3_dot } from "../../../core/geom/vec3/v3_dot.js";
|
|
6
6
|
import { v3_length } from "../../../core/geom/vec3/v3_length.js";
|
|
7
7
|
import Vector3 from "../../../core/geom/Vector3.js";
|
|
@@ -255,7 +255,7 @@ export class TwoBoneInverseKinematicsSolver extends IKSolver {
|
|
|
255
255
|
|
|
256
256
|
const targetOffsetDistance = constraint.offset * limbLength;
|
|
257
257
|
|
|
258
|
-
|
|
258
|
+
v3_displace_in_direction(
|
|
259
259
|
targetPosition,
|
|
260
260
|
targetOffsetDistance,
|
|
261
261
|
contactPosition.x, contactPosition.y, contactPosition.z,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Transform } from "../transform/Transform.js";
|
|
2
1
|
import { assert } from "../../../core/assert.js";
|
|
2
|
+
import { Transform } from "../transform/Transform.js";
|
|
3
3
|
|
|
4
4
|
export const TransformAttachmentFlags = {
|
|
5
5
|
/**
|
|
@@ -15,6 +15,7 @@ export class TransformAttachment {
|
|
|
15
15
|
|
|
16
16
|
/**
|
|
17
17
|
* transform relative to the attachment target
|
|
18
|
+
* Think of it as "local transform"
|
|
18
19
|
* @type {Transform}
|
|
19
20
|
*/
|
|
20
21
|
transform = new Transform();
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
import { min2 } from "../../../core/math/min2.js";
|
|
2
|
+
import { ResourceAccessKind } from "../../../core/model/ResourceAccessKind.js";
|
|
3
|
+
import { ResourceAccessSpecification } from "../../../core/model/ResourceAccessSpecification.js";
|
|
1
4
|
import { System } from "../System.js";
|
|
2
|
-
import { TransformAttachment, TransformAttachmentFlags } from "./TransformAttachment.js";
|
|
3
5
|
import { Transform } from "../transform/Transform.js";
|
|
4
|
-
import {
|
|
6
|
+
import { TransformAttachment, TransformAttachmentFlags } from "./TransformAttachment.js";
|
|
5
7
|
|
|
6
8
|
/**
|
|
7
9
|
* @readonly
|
|
@@ -47,7 +49,10 @@ class UpdateContext {
|
|
|
47
49
|
}
|
|
48
50
|
|
|
49
51
|
update() {
|
|
50
|
-
this.transform.multiplyTransforms(
|
|
52
|
+
this.transform.multiplyTransforms(
|
|
53
|
+
this.parent_transform,
|
|
54
|
+
this.attachment.transform
|
|
55
|
+
);
|
|
51
56
|
}
|
|
52
57
|
|
|
53
58
|
/**
|
|
@@ -70,51 +75,51 @@ class UpdateContext {
|
|
|
70
75
|
link() {
|
|
71
76
|
const t_parent = this.parent_transform;
|
|
72
77
|
|
|
73
|
-
t_parent.
|
|
74
|
-
t_parent.rotation.onChanged.add(this.update, this);
|
|
75
|
-
t_parent.scale.onChanged.add(this.update, this);
|
|
78
|
+
t_parent.subscribe(this.update, this);
|
|
76
79
|
|
|
77
80
|
const t_attachment = this.attachment.transform;
|
|
78
|
-
|
|
79
|
-
t_attachment.
|
|
80
|
-
t_attachment.scale.onChanged.add(this.update,this);
|
|
81
|
+
|
|
82
|
+
t_attachment.subscribe(this.update, this);
|
|
81
83
|
}
|
|
82
84
|
|
|
83
85
|
unlink() {
|
|
84
86
|
const transform = this.parent_transform;
|
|
85
87
|
|
|
86
|
-
transform.
|
|
87
|
-
transform.rotation.onChanged.remove(this.update, this);
|
|
88
|
-
transform.scale.onChanged.remove(this.update, this);
|
|
88
|
+
transform.unsubscribe(this.update, this);
|
|
89
89
|
|
|
90
90
|
const t_attachment = this.attachment.transform;
|
|
91
|
-
|
|
92
|
-
t_attachment.
|
|
93
|
-
t_attachment.scale.onChanged.remove(this.update,this);
|
|
91
|
+
|
|
92
|
+
t_attachment.unsubscribe(this.update, this);
|
|
94
93
|
}
|
|
95
94
|
}
|
|
96
95
|
|
|
97
96
|
export class TransformAttachmentSystem extends System {
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
*
|
|
100
|
+
* @type {UpdateContext[]}
|
|
101
|
+
* @private
|
|
102
|
+
*/
|
|
103
|
+
__contexts = [];
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
*
|
|
107
|
+
* @type {UpdateContext[]}
|
|
108
|
+
* @private
|
|
109
|
+
*/
|
|
110
|
+
__queue = [];
|
|
111
|
+
__queue_size = 0;
|
|
112
|
+
__queue_cursor = 0;
|
|
113
|
+
|
|
98
114
|
constructor() {
|
|
99
115
|
super();
|
|
100
116
|
|
|
101
117
|
this.dependencies = [TransformAttachment, Transform];
|
|
102
118
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
*/
|
|
108
|
-
this.__contexts = [];
|
|
109
|
-
|
|
110
|
-
/**
|
|
111
|
-
*
|
|
112
|
-
* @type {UpdateContext[]}
|
|
113
|
-
* @private
|
|
114
|
-
*/
|
|
115
|
-
this.__queue = [];
|
|
116
|
-
this.__queue_size = 0;
|
|
117
|
-
this.__queue_cursor = 0;
|
|
119
|
+
this.components_used = [
|
|
120
|
+
ResourceAccessSpecification.from(TransformAttachment, ResourceAccessKind.Read),
|
|
121
|
+
ResourceAccessSpecification.from(Transform, ResourceAccessKind.Read | ResourceAccessKind.Write),
|
|
122
|
+
];
|
|
118
123
|
}
|
|
119
124
|
|
|
120
125
|
/**
|
|
@@ -142,6 +147,12 @@ export class TransformAttachmentSystem extends System {
|
|
|
142
147
|
this.__queue[this.__queue_size++] = ctx;
|
|
143
148
|
}
|
|
144
149
|
|
|
150
|
+
/**
|
|
151
|
+
*
|
|
152
|
+
* @param {number} entity
|
|
153
|
+
* @returns {boolean}
|
|
154
|
+
* @private
|
|
155
|
+
*/
|
|
145
156
|
__dequeue_entity(entity) {
|
|
146
157
|
for (let i = 0; i < this.__queue_size; i++) {
|
|
147
158
|
const ctx = this.__queue[i];
|
|
@@ -170,9 +181,7 @@ export class TransformAttachmentSystem extends System {
|
|
|
170
181
|
ctx.entity = entity;
|
|
171
182
|
|
|
172
183
|
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
ctx.ecd = ecd;
|
|
184
|
+
ctx.ecd = this.entityManager.dataset;
|
|
176
185
|
|
|
177
186
|
if (ctx.bind_parent()) {
|
|
178
187
|
this.__finalize_link(ctx);
|
|
@@ -207,12 +216,14 @@ export class TransformAttachmentSystem extends System {
|
|
|
207
216
|
|
|
208
217
|
update(timeDelta) {
|
|
209
218
|
const step_count = min2(this.__queue_size, QUEUE_ITERATION_COUNT);
|
|
219
|
+
|
|
210
220
|
for (let i = 0; i < step_count; i++) {
|
|
211
221
|
const index = this.__queue_cursor % this.__queue_size;
|
|
212
222
|
|
|
213
223
|
const ctx = this.__queue[index];
|
|
214
224
|
|
|
215
225
|
if (ctx.bind_parent()) {
|
|
226
|
+
// parent obtained
|
|
216
227
|
this.__finalize_link(ctx);
|
|
217
228
|
|
|
218
229
|
this.__queue.splice(index, 1);
|
|
@@ -222,5 +233,6 @@ export class TransformAttachmentSystem extends System {
|
|
|
222
233
|
this.__queue_cursor++;
|
|
223
234
|
}
|
|
224
235
|
}
|
|
236
|
+
|
|
225
237
|
}
|
|
226
238
|
}
|
|
@@ -1,225 +0,0 @@
|
|
|
1
|
-
import { PrefixTreeLeaf } from "./PrefixTreeLeaf.js";
|
|
2
|
-
import { PrefixTreeNode } from "./PrefixTreeNode.js";
|
|
3
|
-
|
|
4
|
-
export class PrefixTree extends PrefixTreeNode {
|
|
5
|
-
constructor() {
|
|
6
|
-
super();
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
*
|
|
10
|
-
* @type {string}
|
|
11
|
-
*/
|
|
12
|
-
this.character = "";
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
*
|
|
16
|
-
* @type {PrefixTreeNode[]}
|
|
17
|
-
*/
|
|
18
|
-
this.children = [];
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
*
|
|
23
|
-
* @param {PrefixTreeNode} node
|
|
24
|
-
*/
|
|
25
|
-
addChild(node) {
|
|
26
|
-
node.depth = this.depth + 1;
|
|
27
|
-
node.parent = this;
|
|
28
|
-
|
|
29
|
-
this.children.push(node);
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
*
|
|
34
|
-
* @param {string} character
|
|
35
|
-
* @return {PrefixTree|undefined}
|
|
36
|
-
*/
|
|
37
|
-
findChildByCharacter(character) {
|
|
38
|
-
const n = this.children.length;
|
|
39
|
-
|
|
40
|
-
for (let i = 0; i < n; i++) {
|
|
41
|
-
const child = this.children[i];
|
|
42
|
-
|
|
43
|
-
if (!child.isPrefixTree) {
|
|
44
|
-
continue;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
if (child.character === character) {
|
|
48
|
-
return child;
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
/**
|
|
54
|
-
*
|
|
55
|
-
* @param {string} word
|
|
56
|
-
* @returns {PrefixTreeLeaf|undefined}
|
|
57
|
-
*/
|
|
58
|
-
findLeafByWord(word) {
|
|
59
|
-
|
|
60
|
-
const n = this.children.length;
|
|
61
|
-
|
|
62
|
-
for (let i = 0; i < n; i++) {
|
|
63
|
-
const child = this.children[i];
|
|
64
|
-
|
|
65
|
-
if (!child.isPrefixTreeLeaf) {
|
|
66
|
-
continue;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
if (child.word === word) {
|
|
70
|
-
return child;
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
/**
|
|
76
|
-
*
|
|
77
|
-
* @param {string[]} result
|
|
78
|
-
*/
|
|
79
|
-
collectValues(result) {
|
|
80
|
-
const children = this.children;
|
|
81
|
-
const n = children.length;
|
|
82
|
-
|
|
83
|
-
for (let i = 0; i < n; i++) {
|
|
84
|
-
const node = children[i];
|
|
85
|
-
|
|
86
|
-
if (node.isPrefixTree) {
|
|
87
|
-
node.collectValue(result);
|
|
88
|
-
} else {
|
|
89
|
-
const values = node.values;
|
|
90
|
-
const valueCount = values.length;
|
|
91
|
-
|
|
92
|
-
for (let j = 0; j < valueCount; j++) {
|
|
93
|
-
const value = values[j];
|
|
94
|
-
|
|
95
|
-
result.push(value);
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
/**
|
|
102
|
-
*
|
|
103
|
-
* @param {string[]} result
|
|
104
|
-
* @param {string} prefix
|
|
105
|
-
*/
|
|
106
|
-
findValuesByPrefix(result, prefix) {
|
|
107
|
-
const l = prefix.length;
|
|
108
|
-
|
|
109
|
-
let n = this;
|
|
110
|
-
|
|
111
|
-
for (let i = 0; i < l; i++) {
|
|
112
|
-
|
|
113
|
-
const character = prefix.charAt(i);
|
|
114
|
-
n = n.findChildByCharacter(character)
|
|
115
|
-
|
|
116
|
-
if (n === undefined) {
|
|
117
|
-
return;
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
/**
|
|
125
|
-
*
|
|
126
|
-
* @param {string} text
|
|
127
|
-
* @param {RegExp} splitExpression
|
|
128
|
-
* @param {boolean} stripSpecial
|
|
129
|
-
* @param {boolean} stripPunctuation
|
|
130
|
-
* @param {boolean} forceLowerCase
|
|
131
|
-
* @param {*} value
|
|
132
|
-
*/
|
|
133
|
-
insertText({ text, splitExpression = /\s/, stripSpecial = true, stripPunctuation = true, forceLowerCase = true, value }) {
|
|
134
|
-
const strings = text.split(splitExpression);
|
|
135
|
-
|
|
136
|
-
const words = [];
|
|
137
|
-
|
|
138
|
-
const n = strings.length;
|
|
139
|
-
|
|
140
|
-
let i;
|
|
141
|
-
|
|
142
|
-
for (i = 0; i < n; i++) {
|
|
143
|
-
const input = strings[i];
|
|
144
|
-
|
|
145
|
-
let output = input;
|
|
146
|
-
|
|
147
|
-
if (stripSpecial) {
|
|
148
|
-
output = output.replace(/[\n\t\r]/g, '');
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
if (stripPunctuation) {
|
|
152
|
-
output = output.replace(/[\,\.\!\?\-\+\[\]\(\)\=\"\']/g, '');
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
if (forceLowerCase) {
|
|
156
|
-
output = output.toLocaleLowerCase();
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
if (output.length === 0) {
|
|
160
|
-
continue;
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
if (words.indexOf(output) !== -1) {
|
|
164
|
-
//skip, already recorded
|
|
165
|
-
continue;
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
words.push(output);
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
const wordCount = words.length;
|
|
172
|
-
|
|
173
|
-
for (i = 0; i < wordCount; i++) {
|
|
174
|
-
|
|
175
|
-
const word = words[i];
|
|
176
|
-
|
|
177
|
-
this.insertWord(word, value);
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
/**
|
|
182
|
-
*
|
|
183
|
-
* @param {string} word
|
|
184
|
-
* @param {*} value
|
|
185
|
-
*/
|
|
186
|
-
insertWord(word, value) {
|
|
187
|
-
const n = word.length;
|
|
188
|
-
|
|
189
|
-
if (n <= this.depth) {
|
|
190
|
-
//last letter
|
|
191
|
-
let leaf = this.findLeafByWord(word);
|
|
192
|
-
|
|
193
|
-
if (leaf === undefined) {
|
|
194
|
-
leaf = new PrefixTreeLeaf();
|
|
195
|
-
|
|
196
|
-
leaf.word = word;
|
|
197
|
-
|
|
198
|
-
this.addChild(leaf);
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
leaf.values.push(value);
|
|
202
|
-
|
|
203
|
-
} else {
|
|
204
|
-
|
|
205
|
-
const char = word.charAt(this.depth);
|
|
206
|
-
|
|
207
|
-
let child = this.findChildByCharacter(char);
|
|
208
|
-
|
|
209
|
-
if (child === undefined) {
|
|
210
|
-
child = new PrefixTree();
|
|
211
|
-
child.character = char;
|
|
212
|
-
|
|
213
|
-
this.addChild(child);
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
child.insertWord(word, value);
|
|
217
|
-
}
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
/**
|
|
222
|
-
* @readonly
|
|
223
|
-
* @type {boolean}
|
|
224
|
-
*/
|
|
225
|
-
PrefixTree.prototype.isPrefixTree = true;
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import { PrefixTree } from "./PrefixTree.js";
|
|
2
|
-
|
|
3
|
-
test('inset one letter', () => {
|
|
4
|
-
const t = new PrefixTree();
|
|
5
|
-
|
|
6
|
-
t.insertWord('a');
|
|
7
|
-
|
|
8
|
-
const child = t.findChildByCharacter('a');
|
|
9
|
-
|
|
10
|
-
expect(child.character).toBe('a');
|
|
11
|
-
expect(child.children[0].word).toBe('a');
|
|
12
|
-
expect(child.children[0].values.length).toBe(1);
|
|
13
|
-
});
|
|
14
|
-
|
|
15
|
-
test('insert one letter twice', () => {
|
|
16
|
-
|
|
17
|
-
const t = new PrefixTree();
|
|
18
|
-
|
|
19
|
-
t.insertWord('a');
|
|
20
|
-
t.insertWord('a');
|
|
21
|
-
|
|
22
|
-
const child = t.findChildByCharacter('a');
|
|
23
|
-
|
|
24
|
-
expect(child.character).toBe('a');
|
|
25
|
-
expect(child.children[0].word).toBe('a');
|
|
26
|
-
expect(child.children[0].values.length).toBe(2);
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
test('complex', () => {
|
|
31
|
-
|
|
32
|
-
const t = new PrefixTree();
|
|
33
|
-
|
|
34
|
-
"cat sat on a mat. Horse smoked a camel. Bear snored, slithered and slobbered".split(/\s/).forEach(word => {
|
|
35
|
-
t.insertWord(word);
|
|
36
|
-
});
|
|
37
|
-
|
|
38
|
-
console.log("");
|
|
39
|
-
});
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import { PrefixTreeNode } from "./PrefixTreeNode.js";
|
|
2
|
-
|
|
3
|
-
export class PrefixTreeLeaf extends PrefixTreeNode {
|
|
4
|
-
constructor() {
|
|
5
|
-
super();
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Values associated with the word
|
|
9
|
-
* @type {Array}
|
|
10
|
-
*/
|
|
11
|
-
this.values = [];
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Actual word
|
|
15
|
-
* @type {string}
|
|
16
|
-
*/
|
|
17
|
-
this.word = "";
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* @readonly
|
|
23
|
-
* @type {boolean}
|
|
24
|
-
*/
|
|
25
|
-
PrefixTreeLeaf.prototype.isPrefixTreeLeaf = true;
|