@woosh/meep-engine 2.78.1 → 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 +57 -35
- package/build/meep.min.js +1 -1
- package/build/meep.module.js +57 -35
- package/package.json +1 -1
- 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/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/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,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;
|