joserpagil commited on
Commit
f0d5f65
·
verified ·
1 Parent(s): ef61a9d

Upload 5 files

Browse files
libs/cannon/cannon-es-debugger.js ADDED
@@ -0,0 +1,300 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { Vec3, Quaternion, Shape } from 'cannon-es';
2
+ import { MeshBasicMaterial, SphereGeometry, BoxGeometry, PlaneGeometry, Mesh, CylinderGeometry, BufferGeometry, Float32BufferAttribute } from 'three';
3
+
4
+ function CannonDebugger(scene, world, _temp) {
5
+ let {
6
+ color = 0x00ff00,
7
+ scale = 1,
8
+ onInit,
9
+ onUpdate
10
+ } = _temp === void 0 ? {} : _temp;
11
+ const _meshes = [];
12
+
13
+ const _material = new MeshBasicMaterial({
14
+ color: color != null ? color : 0x00ff00,
15
+ wireframe: true
16
+ });
17
+
18
+ const _tempVec0 = new Vec3();
19
+
20
+ const _tempVec1 = new Vec3();
21
+
22
+ const _tempVec2 = new Vec3();
23
+
24
+ const _tempQuat0 = new Quaternion();
25
+
26
+ const _sphereGeometry = new SphereGeometry(1);
27
+
28
+ const _boxGeometry = new BoxGeometry(1, 1, 1);
29
+
30
+ const _planeGeometry = new PlaneGeometry(10, 10, 10, 10); // Move the planeGeometry forward a little bit to prevent z-fighting
31
+
32
+
33
+ _planeGeometry.translate(0, 0, 0.0001);
34
+
35
+ function createConvexPolyhedronGeometry(shape) {
36
+ const geometry = new BufferGeometry(); // Add vertices
37
+
38
+ const positions = [];
39
+
40
+ for (let i = 0; i < shape.vertices.length; i++) {
41
+ const vertex = shape.vertices[i];
42
+ positions.push(vertex.x, vertex.y, vertex.z);
43
+ }
44
+
45
+ geometry.setAttribute('position', new Float32BufferAttribute(positions, 3)); // Add faces
46
+
47
+ const indices = [];
48
+
49
+ for (let i = 0; i < shape.faces.length; i++) {
50
+ const face = shape.faces[i];
51
+ const a = face[0];
52
+
53
+ for (let j = 1; j < face.length - 1; j++) {
54
+ const b = face[j];
55
+ const c = face[j + 1];
56
+ indices.push(a, b, c);
57
+ }
58
+ }
59
+
60
+ geometry.setIndex(indices);
61
+ geometry.computeBoundingSphere();
62
+ geometry.computeVertexNormals();
63
+ return geometry;
64
+ }
65
+
66
+ function createTrimeshGeometry(shape) {
67
+ const geometry = new BufferGeometry();
68
+ const positions = [];
69
+ const v0 = _tempVec0;
70
+ const v1 = _tempVec1;
71
+ const v2 = _tempVec2;
72
+
73
+ for (let i = 0; i < shape.indices.length / 3; i++) {
74
+ shape.getTriangleVertices(i, v0, v1, v2);
75
+ positions.push(v0.x, v0.y, v0.z);
76
+ positions.push(v1.x, v1.y, v1.z);
77
+ positions.push(v2.x, v2.y, v2.z);
78
+ }
79
+
80
+ geometry.setAttribute('position', new Float32BufferAttribute(positions, 3));
81
+ geometry.computeBoundingSphere();
82
+ geometry.computeVertexNormals();
83
+ return geometry;
84
+ }
85
+
86
+ function createHeightfieldGeometry(shape) {
87
+ const geometry = new BufferGeometry();
88
+ const s = shape.elementSize || 1; // assumes square heightfield, else i*x, j*y
89
+
90
+ const positions = shape.data.flatMap((row, i) => row.flatMap((z, j) => [i * s, j * s, z]));
91
+ const indices = [];
92
+
93
+ for (let xi = 0; xi < shape.data.length - 1; xi++) {
94
+ for (let yi = 0; yi < shape.data[xi].length - 1; yi++) {
95
+ const stride = shape.data[xi].length;
96
+ const index = xi * stride + yi;
97
+ indices.push(index + 1, index + stride, index + stride + 1);
98
+ indices.push(index + stride, index + 1, index);
99
+ }
100
+ }
101
+
102
+ geometry.setIndex(indices);
103
+ geometry.setAttribute('position', new Float32BufferAttribute(positions, 3));
104
+ geometry.computeBoundingSphere();
105
+ geometry.computeVertexNormals();
106
+ return geometry;
107
+ }
108
+
109
+ function createMesh(shape) {
110
+ let mesh = new Mesh();
111
+ const {
112
+ SPHERE,
113
+ BOX,
114
+ PLANE,
115
+ CYLINDER,
116
+ CONVEXPOLYHEDRON,
117
+ TRIMESH,
118
+ HEIGHTFIELD
119
+ } = Shape.types;
120
+
121
+ switch (shape.type) {
122
+ case SPHERE:
123
+ {
124
+ mesh = new Mesh(_sphereGeometry, _material);
125
+ break;
126
+ }
127
+
128
+ case BOX:
129
+ {
130
+ mesh = new Mesh(_boxGeometry, _material);
131
+ break;
132
+ }
133
+
134
+ case PLANE:
135
+ {
136
+ mesh = new Mesh(_planeGeometry, _material);
137
+ break;
138
+ }
139
+
140
+ case CYLINDER:
141
+ {
142
+ const geometry = new CylinderGeometry(shape.radiusTop, shape.radiusBottom, shape.height, shape.numSegments);
143
+ mesh = new Mesh(geometry, _material);
144
+ shape.geometryId = geometry.id;
145
+ break;
146
+ }
147
+
148
+ case CONVEXPOLYHEDRON:
149
+ {
150
+ const geometry = createConvexPolyhedronGeometry(shape);
151
+ mesh = new Mesh(geometry, _material);
152
+ shape.geometryId = geometry.id;
153
+ break;
154
+ }
155
+
156
+ case TRIMESH:
157
+ {
158
+ const geometry = createTrimeshGeometry(shape);
159
+ mesh = new Mesh(geometry, _material);
160
+ shape.geometryId = geometry.id;
161
+ break;
162
+ }
163
+
164
+ case HEIGHTFIELD:
165
+ {
166
+ const geometry = createHeightfieldGeometry(shape);
167
+ mesh = new Mesh(geometry, _material);
168
+ shape.geometryId = geometry.id;
169
+ break;
170
+ }
171
+ }
172
+
173
+ scene.add(mesh);
174
+ return mesh;
175
+ }
176
+
177
+ function scaleMesh(mesh, shape) {
178
+ const {
179
+ SPHERE,
180
+ BOX,
181
+ PLANE,
182
+ CYLINDER,
183
+ CONVEXPOLYHEDRON,
184
+ TRIMESH,
185
+ HEIGHTFIELD
186
+ } = Shape.types;
187
+
188
+ switch (shape.type) {
189
+ case SPHERE:
190
+ {
191
+ const {
192
+ radius
193
+ } = shape;
194
+ mesh.scale.set(radius * scale, radius * scale, radius * scale);
195
+ break;
196
+ }
197
+
198
+ case BOX:
199
+ {
200
+ mesh.scale.copy(shape.halfExtents);
201
+ mesh.scale.multiplyScalar(2 * scale);
202
+ break;
203
+ }
204
+
205
+ case PLANE:
206
+ {
207
+ break;
208
+ }
209
+
210
+ case CYLINDER:
211
+ {
212
+ mesh.scale.set(1 * scale, 1 * scale, 1 * scale);
213
+ break;
214
+ }
215
+
216
+ case CONVEXPOLYHEDRON:
217
+ {
218
+ mesh.scale.set(1 * scale, 1 * scale, 1 * scale);
219
+ break;
220
+ }
221
+
222
+ case TRIMESH:
223
+ {
224
+ mesh.scale.copy(shape.scale).multiplyScalar(scale);
225
+ break;
226
+ }
227
+
228
+ case HEIGHTFIELD:
229
+ {
230
+ mesh.scale.set(1 * scale, 1 * scale, 1 * scale);
231
+ break;
232
+ }
233
+ }
234
+ }
235
+
236
+ function typeMatch(mesh, shape) {
237
+ if (!mesh) return false;
238
+ const {
239
+ geometry
240
+ } = mesh;
241
+ return geometry instanceof SphereGeometry && shape.type === Shape.types.SPHERE || geometry instanceof BoxGeometry && shape.type === Shape.types.BOX || geometry instanceof PlaneGeometry && shape.type === Shape.types.PLANE || geometry.id === shape.geometryId && shape.type === Shape.types.CYLINDER || geometry.id === shape.geometryId && shape.type === Shape.types.CONVEXPOLYHEDRON || geometry.id === shape.geometryId && shape.type === Shape.types.TRIMESH || geometry.id === shape.geometryId && shape.type === Shape.types.HEIGHTFIELD;
242
+ }
243
+
244
+ function updateMesh(index, shape) {
245
+ let mesh = _meshes[index];
246
+ let didCreateNewMesh = false;
247
+
248
+ if (!typeMatch(mesh, shape)) {
249
+ if (mesh) scene.remove(mesh);
250
+ _meshes[index] = mesh = createMesh(shape);
251
+ didCreateNewMesh = true;
252
+ }
253
+
254
+ scaleMesh(mesh, shape);
255
+ return didCreateNewMesh;
256
+ }
257
+
258
+ function update() {
259
+ const meshes = _meshes;
260
+ const shapeWorldPosition = _tempVec0;
261
+ const shapeWorldQuaternion = _tempQuat0;
262
+ let meshIndex = 0;
263
+
264
+ for (const body of world.bodies) {
265
+ for (let i = 0; i !== body.shapes.length; i++) {
266
+ const shape = body.shapes[i];
267
+ const didCreateNewMesh = updateMesh(meshIndex, shape);
268
+ const mesh = meshes[meshIndex];
269
+
270
+ if (mesh) {
271
+ // Get world position
272
+ body.quaternion.vmult(body.shapeOffsets[i], shapeWorldPosition);
273
+ body.position.vadd(shapeWorldPosition, shapeWorldPosition); // Get world quaternion
274
+
275
+ body.quaternion.mult(body.shapeOrientations[i], shapeWorldQuaternion); // Copy to meshes
276
+
277
+ mesh.position.copy(shapeWorldPosition);
278
+ mesh.quaternion.copy(shapeWorldQuaternion);
279
+ if (didCreateNewMesh && onInit instanceof Function) onInit(body, mesh, shape);
280
+ if (!didCreateNewMesh && onUpdate instanceof Function) onUpdate(body, mesh, shape);
281
+ }
282
+
283
+ meshIndex++;
284
+ }
285
+ }
286
+
287
+ for (let i = meshIndex; i < meshes.length; i++) {
288
+ const mesh = meshes[i];
289
+ if (mesh) scene.remove(mesh);
290
+ }
291
+
292
+ meshes.length = meshIndex;
293
+ }
294
+
295
+ return {
296
+ update
297
+ };
298
+ }
299
+
300
+ export { CannonDebugger as default };
libs/cannon/cannon-es.js ADDED
The diff for this file is too large to render. See raw diff
 
libs/cannon/cannon-es.min.js ADDED
The diff for this file is too large to render. See raw diff
 
libs/mixamo/loadMixamoAnimation.js ADDED
@@ -0,0 +1,95 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import * as THREE from 'three';
2
+ import { FBXLoader } from 'three/addons/loaders/FBXLoader.js';
3
+ import { mixamoVRMRigMap } from './mixamoVRMRigMap.js';
4
+
5
+ /**
6
+ * Load Mixamo animation, convert for three-vrm use, and return it.
7
+ *
8
+ * @param {string} url A url of mixamo animation data
9
+ * @param {VRM} vrm A target VRM
10
+ * @returns {Promise<THREE.AnimationClip>} The converted AnimationClip
11
+ */
12
+ export function loadMixamoAnimation( url, vrm ) {
13
+
14
+ const loader = new FBXLoader(); // A loader which loads FBX
15
+ return loader.loadAsync( url ).then( ( asset ) => {
16
+
17
+ const clip = THREE.AnimationClip.findByName( asset.animations, 'mixamo.com' ); // extract the AnimationClip
18
+
19
+ const tracks = []; // KeyframeTracks compatible with VRM will be added here
20
+
21
+ const restRotationInverse = new THREE.Quaternion();
22
+ const parentRestWorldRotation = new THREE.Quaternion();
23
+ const _quatA = new THREE.Quaternion();
24
+ const _vec3 = new THREE.Vector3();
25
+
26
+ // Adjust with reference to hips height.
27
+ const motionHipsHeight = asset.getObjectByName( 'mixamorigHips' ).position.y;
28
+ const vrmHipsHeight = vrm.humanoid.normalizedRestPose.hips.position[ 1 ];
29
+ const hipsPositionScale = vrmHipsHeight / motionHipsHeight;
30
+
31
+ clip.tracks.forEach( ( track ) => {
32
+
33
+ // Convert each tracks for VRM use, and push to `tracks`
34
+ const trackSplitted = track.name.split( '.' );
35
+ const mixamoRigName = trackSplitted[ 0 ];
36
+ const vrmBoneName = mixamoVRMRigMap[ mixamoRigName ];
37
+ const vrmNodeName = vrm.humanoid?.getNormalizedBoneNode( vrmBoneName )?.name;
38
+ const mixamoRigNode = asset.getObjectByName( mixamoRigName );
39
+
40
+ if ( vrmNodeName != null ) {
41
+
42
+ const propertyName = trackSplitted[ 1 ];
43
+
44
+ // Store rotations of rest-pose.
45
+ mixamoRigNode.getWorldQuaternion( restRotationInverse ).invert();
46
+ mixamoRigNode.parent.getWorldQuaternion( parentRestWorldRotation );
47
+
48
+ if ( track instanceof THREE.QuaternionKeyframeTrack ) {
49
+
50
+ // Retarget rotation of mixamoRig to NormalizedBone.
51
+ for ( let i = 0; i < track.values.length; i += 4 ) {
52
+
53
+ const flatQuaternion = track.values.slice( i, i + 4 );
54
+
55
+ _quatA.fromArray( flatQuaternion );
56
+
57
+ // 親のレスト時ワールド回転 * トラックの回転 * レスト時ワールド回転の逆
58
+ _quatA
59
+ .premultiply( parentRestWorldRotation )
60
+ .multiply( restRotationInverse );
61
+
62
+ _quatA.toArray( flatQuaternion );
63
+
64
+ flatQuaternion.forEach( ( v, index ) => {
65
+
66
+ track.values[ index + i ] = v;
67
+
68
+ } );
69
+
70
+ }
71
+
72
+ tracks.push(
73
+ new THREE.QuaternionKeyframeTrack(
74
+ `${vrmNodeName}.${propertyName}`,
75
+ track.times,
76
+ track.values.map( ( v, i ) => ( vrm.meta?.metaVersion === '0' && i % 2 === 0 ? - v : v ) ),
77
+ ),
78
+ );
79
+
80
+ } else if ( track instanceof THREE.VectorKeyframeTrack ) {
81
+
82
+ const value = track.values.map( ( v, i ) => ( vrm.meta?.metaVersion === '0' && i % 3 !== 1 ? - v : v ) * hipsPositionScale );
83
+ tracks.push( new THREE.VectorKeyframeTrack( `${vrmNodeName}.${propertyName}`, track.times, value ) );
84
+
85
+ }
86
+
87
+ }
88
+
89
+ } );
90
+
91
+ return new THREE.AnimationClip( 'vrmAnimation', clip.duration, tracks );
92
+
93
+ } );
94
+
95
+ }
libs/mixamo/mixamoVRMRigMap.js ADDED
@@ -0,0 +1,57 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * A map from Mixamo rig name to VRM Humanoid bone name
3
+ */
4
+ export const mixamoVRMRigMap = {
5
+ mixamorigHips: 'hips',
6
+ mixamorigSpine: 'spine',
7
+ mixamorigSpine1: 'chest',
8
+ mixamorigSpine2: 'upperChest',
9
+ mixamorigNeck: 'neck',
10
+ mixamorigHead: 'head',
11
+ mixamorigLeftShoulder: 'leftShoulder',
12
+ mixamorigLeftArm: 'leftUpperArm',
13
+ mixamorigLeftForeArm: 'leftLowerArm',
14
+ mixamorigLeftHand: 'leftHand',
15
+ mixamorigLeftHandThumb1: 'leftThumbMetacarpal',
16
+ mixamorigLeftHandThumb2: 'leftThumbProximal',
17
+ mixamorigLeftHandThumb3: 'leftThumbDistal',
18
+ mixamorigLeftHandIndex1: 'leftIndexProximal',
19
+ mixamorigLeftHandIndex2: 'leftIndexIntermediate',
20
+ mixamorigLeftHandIndex3: 'leftIndexDistal',
21
+ mixamorigLeftHandMiddle1: 'leftMiddleProximal',
22
+ mixamorigLeftHandMiddle2: 'leftMiddleIntermediate',
23
+ mixamorigLeftHandMiddle3: 'leftMiddleDistal',
24
+ mixamorigLeftHandRing1: 'leftRingProximal',
25
+ mixamorigLeftHandRing2: 'leftRingIntermediate',
26
+ mixamorigLeftHandRing3: 'leftRingDistal',
27
+ mixamorigLeftHandPinky1: 'leftLittleProximal',
28
+ mixamorigLeftHandPinky2: 'leftLittleIntermediate',
29
+ mixamorigLeftHandPinky3: 'leftLittleDistal',
30
+ mixamorigRightShoulder: 'rightShoulder',
31
+ mixamorigRightArm: 'rightUpperArm',
32
+ mixamorigRightForeArm: 'rightLowerArm',
33
+ mixamorigRightHand: 'rightHand',
34
+ mixamorigRightHandPinky1: 'rightLittleProximal',
35
+ mixamorigRightHandPinky2: 'rightLittleIntermediate',
36
+ mixamorigRightHandPinky3: 'rightLittleDistal',
37
+ mixamorigRightHandRing1: 'rightRingProximal',
38
+ mixamorigRightHandRing2: 'rightRingIntermediate',
39
+ mixamorigRightHandRing3: 'rightRingDistal',
40
+ mixamorigRightHandMiddle1: 'rightMiddleProximal',
41
+ mixamorigRightHandMiddle2: 'rightMiddleIntermediate',
42
+ mixamorigRightHandMiddle3: 'rightMiddleDistal',
43
+ mixamorigRightHandIndex1: 'rightIndexProximal',
44
+ mixamorigRightHandIndex2: 'rightIndexIntermediate',
45
+ mixamorigRightHandIndex3: 'rightIndexDistal',
46
+ mixamorigRightHandThumb1: 'rightThumbMetacarpal',
47
+ mixamorigRightHandThumb2: 'rightThumbProximal',
48
+ mixamorigRightHandThumb3: 'rightThumbDistal',
49
+ mixamorigLeftUpLeg: 'leftUpperLeg',
50
+ mixamorigLeftLeg: 'leftLowerLeg',
51
+ mixamorigLeftFoot: 'leftFoot',
52
+ mixamorigLeftToeBase: 'leftToes',
53
+ mixamorigRightUpLeg: 'rightUpperLeg',
54
+ mixamorigRightLeg: 'rightLowerLeg',
55
+ mixamorigRightFoot: 'rightFoot',
56
+ mixamorigRightToeBase: 'rightToes',
57
+ };