@woosh/meep-engine 2.126.65 → 2.126.67
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 +1 -1
- package/src/core/math/spline/spline3_hermite_nearest_point.d.ts +15 -0
- package/src/core/math/spline/spline3_hermite_nearest_point.d.ts.map +1 -0
- package/src/core/math/spline/spline3_hermite_nearest_point.js +126 -0
- package/src/engine/animation/curve/AnimationCurve.d.ts.map +1 -1
- package/src/engine/animation/curve/AnimationCurve.js +4 -1
- package/src/engine/animation/curve/animation_curve_nearest_point.d.ts +13 -0
- package/src/engine/animation/curve/animation_curve_nearest_point.d.ts.map +1 -0
- package/src/engine/animation/curve/animation_curve_nearest_point.js +71 -0
- package/src/engine/animation/curve/animation_curve_subdivide.d.ts.map +1 -1
- package/src/engine/animation/curve/animation_curve_subdivide.js +11 -0
- package/src/engine/graphics/geometry/skining/meshFromSkinnedMesh.d.ts +8 -0
- package/src/engine/graphics/geometry/skining/meshFromSkinnedMesh.d.ts.map +1 -0
- package/src/engine/graphics/geometry/skining/meshFromSkinnedMesh.js +39 -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.126.
|
|
8
|
+
"version": "2.126.67",
|
|
9
9
|
"main": "build/meep.module.js",
|
|
10
10
|
"module": "build/meep.module.js",
|
|
11
11
|
"exports": {
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Finds the parameter 't' of the nearest point on a 1D Hermite spline
|
|
3
|
+
* function graph to a reference point. The curve is defined by (t, p(t)).
|
|
4
|
+
* This version is optimized to avoid allocations.
|
|
5
|
+
*
|
|
6
|
+
* @param {number} ref_t - The 't' coordinate of the reference point.
|
|
7
|
+
* @param {number} ref_p - The 'p' coordinate of the reference point.
|
|
8
|
+
* @param {number} p0 - The start value of the spline (at t=0).
|
|
9
|
+
* @param {number} p1 - The end value of the spline (at t=1).
|
|
10
|
+
* @param {number} m0 - The tangent at the start.
|
|
11
|
+
* @param {number} m1 - The tangent at the end.
|
|
12
|
+
* @returns {number} The parameter 't' of the nearest point. This value is always in [0..1] range
|
|
13
|
+
*/
|
|
14
|
+
export function spline3_hermite_nearest_point(ref_t: number, ref_p: number, p0: number, p1: number, m0: number, m1: number): number;
|
|
15
|
+
//# sourceMappingURL=spline3_hermite_nearest_point.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spline3_hermite_nearest_point.d.ts","sourceRoot":"","sources":["../../../../../src/core/math/spline/spline3_hermite_nearest_point.js"],"names":[],"mappings":"AAyBA;;;;;;;;;;;;GAYG;AACH,qDARW,MAAM,SACN,MAAM,MACN,MAAM,MACN,MAAM,MACN,MAAM,MACN,MAAM,GACJ,MAAM,CAyFlB"}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { spline3_hermite } from "./spline3_hermite.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Helper to evaluate a polynomial given its coefficients.
|
|
5
|
+
* @param {Float32Array} p - Polynomial coefficients [c0, c1, c2, ...]
|
|
6
|
+
* @param {number} t - The value at which to evaluate.
|
|
7
|
+
* @param {number} size
|
|
8
|
+
* @returns {number}
|
|
9
|
+
*/
|
|
10
|
+
function polyval(p, t, size) {
|
|
11
|
+
let result = 0;
|
|
12
|
+
|
|
13
|
+
for (let i = size - 1; i >= 0; i--) {
|
|
14
|
+
result = result * t + p[i];
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
return result;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const quintic_coeffs = new Float32Array(6);
|
|
21
|
+
const quartic_coeffs = new Float32Array(5);
|
|
22
|
+
|
|
23
|
+
const NEWTON_STEPS = 3;
|
|
24
|
+
const START_ROOT_COUNT = 5;
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Finds the parameter 't' of the nearest point on a 1D Hermite spline
|
|
28
|
+
* function graph to a reference point. The curve is defined by (t, p(t)).
|
|
29
|
+
* This version is optimized to avoid allocations.
|
|
30
|
+
*
|
|
31
|
+
* @param {number} ref_t - The 't' coordinate of the reference point.
|
|
32
|
+
* @param {number} ref_p - The 'p' coordinate of the reference point.
|
|
33
|
+
* @param {number} p0 - The start value of the spline (at t=0).
|
|
34
|
+
* @param {number} p1 - The end value of the spline (at t=1).
|
|
35
|
+
* @param {number} m0 - The tangent at the start.
|
|
36
|
+
* @param {number} m1 - The tangent at the end.
|
|
37
|
+
* @returns {number} The parameter 't' of the nearest point. This value is always in [0..1] range
|
|
38
|
+
*/
|
|
39
|
+
export function spline3_hermite_nearest_point(
|
|
40
|
+
ref_t, ref_p,
|
|
41
|
+
p0, p1, m0, m1
|
|
42
|
+
) {
|
|
43
|
+
|
|
44
|
+
// 1. Calculate polynomial coefficients A, B, C for p(t)
|
|
45
|
+
const A = 2 * p0 - 2 * p1 + m0 + m1;
|
|
46
|
+
const B = -3 * p0 + 3 * p1 - 2 * m0 - m1;
|
|
47
|
+
const C = m0;
|
|
48
|
+
const D_minus_Rp = p0 - ref_p;
|
|
49
|
+
|
|
50
|
+
// 2. Form the quintic polynomial f(t) = c5*t^5 + ... + c0
|
|
51
|
+
|
|
52
|
+
quintic_coeffs[0] = (C * D_minus_Rp - ref_t)
|
|
53
|
+
quintic_coeffs[1] = (C * C + 2 * B * D_minus_Rp + 1)
|
|
54
|
+
quintic_coeffs[2] = (3 * B * C + 3 * A * D_minus_Rp)
|
|
55
|
+
quintic_coeffs[3] = (4 * A * C + 2 * B * B)
|
|
56
|
+
quintic_coeffs[4] = (5 * A * B)
|
|
57
|
+
quintic_coeffs[5] = (3 * A * A)
|
|
58
|
+
|
|
59
|
+
// Derivative of the quintic (a quartic) for Newton's method
|
|
60
|
+
|
|
61
|
+
quartic_coeffs[0] = quintic_coeffs[1]
|
|
62
|
+
quartic_coeffs[1] = 2 * quintic_coeffs[2]
|
|
63
|
+
quartic_coeffs[2] = 3 * quintic_coeffs[3]
|
|
64
|
+
quartic_coeffs[3] = 4 * quintic_coeffs[4]
|
|
65
|
+
quartic_coeffs[4] = 5 * quintic_coeffs[5]
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
// 3. Initialize by checking the endpoints t=0 and t=1
|
|
69
|
+
let best_t = 0;
|
|
70
|
+
let dt = 0 - ref_t;
|
|
71
|
+
let dp = p0 - ref_p;
|
|
72
|
+
let min_dist_sq = dt * dt + dp * dp;
|
|
73
|
+
|
|
74
|
+
dt = 1 - ref_t;
|
|
75
|
+
dp = p1 - ref_p;
|
|
76
|
+
const dist_sq_at_1 = dt * dt + dp * dp;
|
|
77
|
+
if (dist_sq_at_1 < min_dist_sq) {
|
|
78
|
+
min_dist_sq = dist_sq_at_1;
|
|
79
|
+
best_t = 1;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// 4. Find roots and check them on the fly
|
|
83
|
+
const tolerance = 1e-7;
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
// Start Newton's method from several points to find multiple roots
|
|
87
|
+
for (let i = 0; i <= START_ROOT_COUNT; i++) {
|
|
88
|
+
let t = i / START_ROOT_COUNT; // Starting guess for the root
|
|
89
|
+
|
|
90
|
+
for (let j = NEWTON_STEPS; j > 0; j--) {
|
|
91
|
+
|
|
92
|
+
const f_t = polyval(quintic_coeffs, t, 6);
|
|
93
|
+
|
|
94
|
+
// derivative of the polynomial we are finding the root of
|
|
95
|
+
const fp_t = polyval(quartic_coeffs, t, 5);
|
|
96
|
+
|
|
97
|
+
if (Math.abs(fp_t) < tolerance) {
|
|
98
|
+
break;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
const t_new = t - f_t / fp_t;
|
|
102
|
+
|
|
103
|
+
if (Math.abs(t_new - t) < tolerance) {
|
|
104
|
+
break;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
t = t_new;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// Check if the found root is valid and yields a better distance
|
|
111
|
+
if (t > 0 && t < 1) {
|
|
112
|
+
// Endpoints already checked
|
|
113
|
+
const p = spline3_hermite(t, p0, p1, m0, m1);
|
|
114
|
+
const current_dt = t - ref_t;
|
|
115
|
+
const current_dp = p - ref_p;
|
|
116
|
+
const dist_sq = current_dt * current_dt + current_dp * current_dp;
|
|
117
|
+
|
|
118
|
+
if (dist_sq < min_dist_sq) {
|
|
119
|
+
min_dist_sq = dist_sq;
|
|
120
|
+
best_t = t;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
return best_t;
|
|
126
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AnimationCurve.d.ts","sourceRoot":"","sources":["../../../../../src/engine/animation/curve/AnimationCurve.js"],"names":[],"mappings":"AAqBA;;;;;;;;;;;;;;;;GAgBG;AACH;IAkXI;;;;OAIG;IACH,kBAHW,QAAQ,EAAE,GACR,cAAc,CAQ1B;IAED;;;;;;;;OAQG;IACH,6BANW,MAAM,eACN,MAAM,YACN,MAAM,aACN,MAAM,GACL,cAAc,CAUzB;IAED;;;;;;OAMG;IACH,4BALW,MAAM,YACN,MAAM,UACN,MAAM,GACL,cAAc,CAOzB;IAED;;;;;;;OAOG;IACH,0BANW,MAAM,eACN,MAAM,YACN,MAAM,aACN,MAAM,GACL,cAAc,
|
|
1
|
+
{"version":3,"file":"AnimationCurve.d.ts","sourceRoot":"","sources":["../../../../../src/engine/animation/curve/AnimationCurve.js"],"names":[],"mappings":"AAqBA;;;;;;;;;;;;;;;;GAgBG;AACH;IAkXI;;;;OAIG;IACH,kBAHW,QAAQ,EAAE,GACR,cAAc,CAQ1B;IAED;;;;;;;;OAQG;IACH,6BANW,MAAM,eACN,MAAM,YACN,MAAM,aACN,MAAM,GACL,cAAc,CAUzB;IAED;;;;;;OAMG;IACH,4BALW,MAAM,YACN,MAAM,UACN,MAAM,GACL,cAAc,CAOzB;IAED;;;;;;;OAOG;IACH,0BANW,MAAM,eACN,MAAM,YACN,MAAM,aACN,MAAM,GACL,cAAc,CAezB;IApbD;;;;;OAKG;IACH,eAFU,QAAQ,EAAE,CAEV;IAEV;;;;;OAKG;IACH,SAHW,QAAQ,GACN,MAAM,CAiClB;IAED;;;OAGG;IACH,cAFW,QAAQ,EAAE,QAUpB;IAED;;;;OAIG;IACH,YAHW,QAAQ,GACN,OAAO,CAYnB;IAED;;OAEG;IACH,cAEC;IAGD;;;OAGG;IACH,WAFY,OAAO,CAIlB;IAED;;;OAGG;IACH,qBAEC;IAED;;;;OAIG;IACH,yBAUC;IAED;;;;OAIG;IACH,uBAUC;IAED;;;;OAIG;IACH,uBAcC;IAED;;;;OAIG;IACH,wBAHW,MAAM,GACJ,MAAM,CA0ClB;IAED;;;;OAIG;IACH,eAHW,MAAM,GACL,MAAM,CAoCjB;IAED;;;;OAIG;IACH,qBAFW,MAAM,QAmChB;IAED;;;;OAIG;IACH,sBAHW,MAAM,UACN,MAAM,QAWhB;IAED,0BAKC;IAGD;;;OAGG;IACH,YAFW,cAAc,QAIxB;IAED;;;OAGG;IACH,SAFY,cAAc,CAQzB;IAED;;;;OAIG;IACH,cAHW,cAAc,GACb,OAAO,CAIlB;IAED;;;OAGG;IACH,QAFY,MAAM,CAIjB;IAED;;MAIC;IAED;;aAeC;IAyEL;;;;OAIG;IACH,2BAFU,OAAO,CAEwB;CARxC;yBAndwB,eAAe"}
|
|
@@ -464,7 +464,10 @@ export class AnimationCurve {
|
|
|
464
464
|
timeStart = 0, valueStart = 0,
|
|
465
465
|
timeEnd = 1, valueEnd = 1
|
|
466
466
|
) {
|
|
467
|
-
const
|
|
467
|
+
const time_delta = timeEnd - timeStart;
|
|
468
|
+
|
|
469
|
+
// tangent needs to be normalized
|
|
470
|
+
const tangent = time_delta === 0 ? 0 : (valueEnd - valueStart) / time_delta;
|
|
468
471
|
|
|
469
472
|
return AnimationCurve.from([
|
|
470
473
|
Keyframe.from(timeStart, valueStart, 0, tangent),
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* NOTE: this operation has O(n) complexity, where n is the number of keys in the curve.
|
|
3
|
+
* @param {AnimationCurve} curve
|
|
4
|
+
* @param {number} ref_time
|
|
5
|
+
* @param {number} ref_value
|
|
6
|
+
* @returns {number} time of the nearest point on the curve
|
|
7
|
+
* @see AnimationCurve
|
|
8
|
+
* @example
|
|
9
|
+
* const nearest_time = animation_curve_nearest_point(curve, 0.5, 10);
|
|
10
|
+
* const nearest_value = curve.evaluate(nearest_time);
|
|
11
|
+
*/
|
|
12
|
+
export function animation_curve_nearest_point(curve: AnimationCurve, ref_time: number, ref_value: number): number;
|
|
13
|
+
//# sourceMappingURL=animation_curve_nearest_point.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"animation_curve_nearest_point.d.ts","sourceRoot":"","sources":["../../../../../src/engine/animation/curve/animation_curve_nearest_point.js"],"names":[],"mappings":"AAMA;;;;;;;;;;GAUG;AACH,+EARW,MAAM,aACN,MAAM,GACJ,MAAM,CA2DlB"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { v2_distance_sqr } from "../../../core/geom/vec2/v2_distance_sqr.js";
|
|
2
|
+
import { inverseLerp } from "../../../core/math/inverseLerp.js";
|
|
3
|
+
import { lerp } from "../../../core/math/lerp.js";
|
|
4
|
+
import { spline3_hermite } from "../../../core/math/spline/spline3_hermite.js";
|
|
5
|
+
import { spline3_hermite_nearest_point } from "../../../core/math/spline/spline3_hermite_nearest_point.js";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* NOTE: this operation has O(n) complexity, where n is the number of keys in the curve.
|
|
9
|
+
* @param {AnimationCurve} curve
|
|
10
|
+
* @param {number} ref_time
|
|
11
|
+
* @param {number} ref_value
|
|
12
|
+
* @returns {number} time of the nearest point on the curve
|
|
13
|
+
* @see AnimationCurve
|
|
14
|
+
* @example
|
|
15
|
+
* const nearest_time = animation_curve_nearest_point(curve, 0.5, 10);
|
|
16
|
+
* const nearest_value = curve.evaluate(nearest_time);
|
|
17
|
+
*/
|
|
18
|
+
export function animation_curve_nearest_point(curve, ref_time, ref_value) {
|
|
19
|
+
|
|
20
|
+
const keys = curve.keys;
|
|
21
|
+
const key_count = keys.length;
|
|
22
|
+
|
|
23
|
+
if (key_count === 0) {
|
|
24
|
+
// special case: empty curve
|
|
25
|
+
return ref_time;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
if (key_count === 1) {
|
|
29
|
+
// special case: single key
|
|
30
|
+
return keys[0].time;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
let nearest_time = keys[0].time;
|
|
34
|
+
let nearest_value = keys[0].value;
|
|
35
|
+
let nearest_distance_sqr = v2_distance_sqr(nearest_time, nearest_value, ref_time, ref_value);
|
|
36
|
+
|
|
37
|
+
for (let i = 0; i <= key_count - 2; i++) {
|
|
38
|
+
const key0 = keys[i];
|
|
39
|
+
const key1 = keys[i + 1];
|
|
40
|
+
|
|
41
|
+
const time_delta = key1.time - key0.time;
|
|
42
|
+
|
|
43
|
+
// Normalize reference time to the segment's [0, 1] space
|
|
44
|
+
const ref_t = inverseLerp(key0.time, key1.time, ref_time);
|
|
45
|
+
|
|
46
|
+
// Scale tangents by the segment duration
|
|
47
|
+
const m0 = key0.outTangent * time_delta;
|
|
48
|
+
const m1 = key1.inTangent * time_delta;
|
|
49
|
+
|
|
50
|
+
const t = spline3_hermite_nearest_point(
|
|
51
|
+
ref_t, ref_value,
|
|
52
|
+
key0.value, key1.value,
|
|
53
|
+
m0, m1
|
|
54
|
+
);
|
|
55
|
+
|
|
56
|
+
// De-normalize the resulting time back to the global timeline
|
|
57
|
+
const curve_time = lerp(key0.time, key1.time, t);
|
|
58
|
+
const curve_value = spline3_hermite(t, key0.value, key1.value, m0, m1);
|
|
59
|
+
|
|
60
|
+
const distance_sqr = v2_distance_sqr(curve_time, curve_value, ref_time, ref_value);
|
|
61
|
+
|
|
62
|
+
if (distance_sqr < nearest_distance_sqr) {
|
|
63
|
+
nearest_time = curve_time;
|
|
64
|
+
nearest_value = curve_value;
|
|
65
|
+
nearest_distance_sqr = distance_sqr;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
return nearest_time;
|
|
71
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"animation_curve_subdivide.d.ts","sourceRoot":"","sources":["../../../../../src/engine/animation/curve/animation_curve_subdivide.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"animation_curve_subdivide.d.ts","sourceRoot":"","sources":["../../../../../src/engine/animation/curve/animation_curve_subdivide.js"],"names":[],"mappings":"AAKA;;;;;;;;;;;;GAYG;AACH,+CAVW,QAAQ,QACR,QAAQ,QACR,QAAQ,KACR,MAAM,GACJ,QAAQ,CAqDpB"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { assert } from "../../../core/assert.js";
|
|
1
2
|
import { lerp } from "../../../core/math/lerp.js";
|
|
2
3
|
import { spline3_hermite } from "../../../core/math/spline/spline3_hermite.js";
|
|
3
4
|
import { spline3_hermite_derivative } from "../../../core/math/spline/spline3_hermite_derivative.js";
|
|
@@ -21,6 +22,16 @@ export function animation_curve_subdivide(
|
|
|
21
22
|
key1,
|
|
22
23
|
t
|
|
23
24
|
) {
|
|
25
|
+
assert.isObject(out, 'out');
|
|
26
|
+
assert.isObject(key0, 'key0');
|
|
27
|
+
assert.isObject(key1, 'key1');
|
|
28
|
+
|
|
29
|
+
assert.equal(out.isKeyframe,true,'out.isKeyframe !== true');
|
|
30
|
+
assert.equal(key0.isKeyframe,true,'key0.isKeyframe !== true');
|
|
31
|
+
assert.equal(key1.isKeyframe,true,'key1.isKeyframe !== true');
|
|
32
|
+
|
|
33
|
+
assert.isNumber(t, 't');
|
|
34
|
+
assert.ok(t >= 0 && t <= 1);
|
|
24
35
|
|
|
25
36
|
const v0 = key0.value;
|
|
26
37
|
const v1 = key1.value;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Rebuild skinned mesh as a regular mesh applying skinning in the process
|
|
3
|
+
* @param {SkinnedMesh} skinned
|
|
4
|
+
* @returns {Mesh}
|
|
5
|
+
*/
|
|
6
|
+
export function meshFromSkinnedMesh(skinned: SkinnedMesh): Mesh;
|
|
7
|
+
import { Mesh } from "three";
|
|
8
|
+
//# sourceMappingURL=meshFromSkinnedMesh.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"meshFromSkinnedMesh.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/graphics/geometry/skining/meshFromSkinnedMesh.js"],"names":[],"mappings":"AAGA;;;;GAIG;AACH,2DAFa,IAAI,CAgChB;qBAtCoB,OAAO"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { Mesh } from "three";
|
|
2
|
+
import { computeSkinnedMeshVertices } from "./computeSkinnedMeshVertices.js";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Rebuild skinned mesh as a regular mesh applying skinning in the process
|
|
6
|
+
* @param {SkinnedMesh} skinned
|
|
7
|
+
* @returns {Mesh}
|
|
8
|
+
*/
|
|
9
|
+
export function meshFromSkinnedMesh(skinned) {
|
|
10
|
+
|
|
11
|
+
const geometry = skinned.geometry;
|
|
12
|
+
|
|
13
|
+
const bakedGeometry = geometry.clone();
|
|
14
|
+
|
|
15
|
+
delete bakedGeometry.attributes.skinIndex;
|
|
16
|
+
delete bakedGeometry.attributes.skinWeight;
|
|
17
|
+
|
|
18
|
+
const positionAttribute = bakedGeometry.getAttribute("position");
|
|
19
|
+
const vertices = positionAttribute.array;
|
|
20
|
+
|
|
21
|
+
computeSkinnedMeshVertices(vertices, skinned);
|
|
22
|
+
|
|
23
|
+
const mesh = new Mesh(bakedGeometry, skinned.material);
|
|
24
|
+
|
|
25
|
+
mesh.position.copy(skinned.position);
|
|
26
|
+
mesh.rotation.copy(skinned.rotation);
|
|
27
|
+
mesh.scale.copy(skinned.scale);
|
|
28
|
+
|
|
29
|
+
//apply transform to each vertex
|
|
30
|
+
skinned.updateMatrix();
|
|
31
|
+
skinned.updateMatrixWorld(true);
|
|
32
|
+
|
|
33
|
+
const m4 = skinned.matrixWorld.clone();
|
|
34
|
+
m4.invert();
|
|
35
|
+
|
|
36
|
+
positionAttribute.applyMatrix4(m4);
|
|
37
|
+
|
|
38
|
+
return mesh;
|
|
39
|
+
}
|