@babylonjs/core 6.46.1 → 6.47.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/Engines/thinEngine.js +2 -2
- package/Engines/thinEngine.js.map +1 -1
- package/Physics/physicsPointProximityQuery.d.ts +1 -1
- package/Physics/physicsPointProximityQuery.js.map +1 -1
- package/Physics/v2/ragdoll.d.ts +16 -5
- package/Physics/v2/ragdoll.js +91 -42
- package/Physics/v2/ragdoll.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"physicsPointProximityQuery.js","sourceRoot":"","sources":["../../../../dev/core/src/Physics/physicsPointProximityQuery.ts"],"names":[],"mappings":"","sourcesContent":["import type { Vector3 } from \"../Maths/math.vector\";\r\nimport type { IRaycastQuery } from \"./physicsRaycastResult\";\r\nimport type { PhysicsBody } from \"./v2\";\r\n\r\n/**\r\n * Interface for point proximity query.\r\n */\r\nexport interface IPhysicsPointProximityQuery {\r\n /**\r\n * The position of the query\r\n */\r\n position: Vector3;\r\n /**\r\n * Maximum distance to check for collisions. Can be set to 0 to check for overlaps.\r\n */\r\n maxDistance: number;\r\n /**\r\n * Collision filter for the query.\r\n */\r\n collisionFilter: IRaycastQuery;\r\n /**\r\n * Should trigger collisions be considered in the query?\r\n */\r\n shouldHitTriggers: boolean;\r\n /**\r\n * Should the query ignore the body that is passed in?\r\n */\r\n ignoreBody?: PhysicsBody;\r\n}\r\n"]}
|
|
1
|
+
{"version":3,"file":"physicsPointProximityQuery.js","sourceRoot":"","sources":["../../../../dev/core/src/Physics/physicsPointProximityQuery.ts"],"names":[],"mappings":"","sourcesContent":["import type { Vector3 } from \"../Maths/math.vector\";\r\nimport type { IRaycastQuery } from \"./physicsRaycastResult\";\r\nimport type { PhysicsBody } from \"./v2/physicsBody\";\r\n\r\n/**\r\n * Interface for point proximity query.\r\n */\r\nexport interface IPhysicsPointProximityQuery {\r\n /**\r\n * The position of the query\r\n */\r\n position: Vector3;\r\n /**\r\n * Maximum distance to check for collisions. Can be set to 0 to check for overlaps.\r\n */\r\n maxDistance: number;\r\n /**\r\n * Collision filter for the query.\r\n */\r\n collisionFilter: IRaycastQuery;\r\n /**\r\n * Should trigger collisions be considered in the query?\r\n */\r\n shouldHitTriggers: boolean;\r\n /**\r\n * Should the query ignore the body that is passed in?\r\n */\r\n ignoreBody?: PhysicsBody;\r\n}\r\n"]}
|
package/Physics/v2/ragdoll.d.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import type { Skeleton } from "../../Bones/skeleton";
|
|
2
2
|
import { Vector3 } from "../../Maths/math.vector";
|
|
3
|
+
import { PhysicsAggregate } from "./physicsAggregate";
|
|
3
4
|
import type { Mesh } from "../../Meshes/mesh";
|
|
5
|
+
import { TransformNode } from "../../Meshes/transformNode";
|
|
4
6
|
/**
|
|
5
7
|
* Ragdoll bone properties
|
|
6
8
|
* @experimental
|
|
@@ -54,11 +56,13 @@ export declare class RagdollBoneProperties {
|
|
|
54
56
|
export declare class Ragdoll {
|
|
55
57
|
private _skeleton;
|
|
56
58
|
private _scene;
|
|
57
|
-
private
|
|
59
|
+
private _rootTransformNode;
|
|
58
60
|
private _config;
|
|
59
61
|
private _boxConfigs;
|
|
62
|
+
private _joints;
|
|
60
63
|
private _bones;
|
|
61
64
|
private _initialRotation;
|
|
65
|
+
private _initialRotation2;
|
|
62
66
|
private _boneNames;
|
|
63
67
|
private _transforms;
|
|
64
68
|
private _aggregates;
|
|
@@ -75,18 +79,25 @@ export declare class Ragdoll {
|
|
|
75
79
|
private _defaultJoint;
|
|
76
80
|
private _defaultJointMin;
|
|
77
81
|
private _defaultJointMax;
|
|
78
|
-
private _boneOffsetAxis;
|
|
79
82
|
/**
|
|
80
83
|
* Construct a new Ragdoll object. Once ready, it can be made dynamic by calling `Ragdoll` method
|
|
81
84
|
* @param skeleton The skeleton containing bones to be physicalized
|
|
82
|
-
* @param
|
|
85
|
+
* @param rootTransformNode The mesh or its transform used by the skeleton
|
|
83
86
|
* @param config an array of `RagdollBoneProperties` corresponding to bones and their properties used to instanciate physics bodies
|
|
84
87
|
*/
|
|
85
|
-
constructor(skeleton: Skeleton,
|
|
88
|
+
constructor(skeleton: Skeleton, rootTransformNode: Mesh | TransformNode, config: RagdollBoneProperties[]);
|
|
89
|
+
/**
|
|
90
|
+
* Returns the aggregate corresponding to the ragdoll bone index
|
|
91
|
+
* @param index ragdoll bone aggregate index
|
|
92
|
+
* @returns the aggregate for the bone index for the root aggregate if index is invalid
|
|
93
|
+
*/
|
|
94
|
+
getAggregate(index: number): PhysicsAggregate;
|
|
86
95
|
private _createColliders;
|
|
87
96
|
private _initJoints;
|
|
97
|
+
private _syncBonesToPhysics;
|
|
98
|
+
private _setBoneOrientationToBody;
|
|
88
99
|
private _syncBonesAndBoxes;
|
|
89
|
-
private
|
|
100
|
+
private _setBodyOrientationToBone;
|
|
90
101
|
private _defineRootBone;
|
|
91
102
|
private _findNearestParent;
|
|
92
103
|
private _init;
|
package/Physics/v2/ragdoll.js
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import { Vector3, Matrix, TmpVectors } from "../../Maths/math.vector.js";
|
|
2
|
-
import { Quaternion } from "../../Maths/math.vector.js";
|
|
1
|
+
import { Vector3, Matrix, TmpVectors, Quaternion } from "../../Maths/math.vector.js";
|
|
3
2
|
import { PhysicsAggregate } from "./physicsAggregate.js";
|
|
4
|
-
import {
|
|
3
|
+
import { PhysicsConstraint } from "./physicsConstraint.js";
|
|
5
4
|
import { Axis, Space } from "../../Maths/math.axis.js";
|
|
6
|
-
import { PhysicsShapeType, PhysicsConstraintType } from "./IPhysicsEnginePlugin.js";
|
|
5
|
+
import { PhysicsShapeType, PhysicsConstraintType, PhysicsMotionType } from "./IPhysicsEnginePlugin.js";
|
|
7
6
|
import { Logger } from "../../Misc/logger.js";
|
|
8
7
|
import { TransformNode } from "../../Meshes/transformNode.js";
|
|
9
8
|
/**
|
|
@@ -20,13 +19,16 @@ export class Ragdoll {
|
|
|
20
19
|
/**
|
|
21
20
|
* Construct a new Ragdoll object. Once ready, it can be made dynamic by calling `Ragdoll` method
|
|
22
21
|
* @param skeleton The skeleton containing bones to be physicalized
|
|
23
|
-
* @param
|
|
22
|
+
* @param rootTransformNode The mesh or its transform used by the skeleton
|
|
24
23
|
* @param config an array of `RagdollBoneProperties` corresponding to bones and their properties used to instanciate physics bodies
|
|
25
24
|
*/
|
|
26
|
-
constructor(skeleton,
|
|
25
|
+
constructor(skeleton, rootTransformNode, config) {
|
|
27
26
|
this._boxConfigs = new Array();
|
|
27
|
+
this._joints = new Array();
|
|
28
28
|
this._bones = new Array();
|
|
29
29
|
this._initialRotation = new Array();
|
|
30
|
+
// without mesh transform, to figure out later
|
|
31
|
+
this._initialRotation2 = new Array();
|
|
30
32
|
this._boneNames = [];
|
|
31
33
|
this._transforms = new Array();
|
|
32
34
|
this._aggregates = new Array();
|
|
@@ -44,15 +46,28 @@ export class Ragdoll {
|
|
|
44
46
|
this._defaultJointMax = 90;
|
|
45
47
|
this._skeleton = skeleton;
|
|
46
48
|
this._scene = skeleton.getScene();
|
|
47
|
-
this.
|
|
49
|
+
this._rootTransformNode = rootTransformNode;
|
|
48
50
|
this._config = config; // initial, user defined box configs. May have several box configs jammed into 1 index.
|
|
49
51
|
this._boxConfigs = []; // final box configs. Every element is a separate box config (this.config may have several configs jammed into 1 index).
|
|
50
52
|
this._putBoxesInBoneCenter = false;
|
|
51
53
|
this._defaultJoint = PhysicsConstraintType.HINGE;
|
|
52
|
-
this.
|
|
54
|
+
this._init();
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Returns the aggregate corresponding to the ragdoll bone index
|
|
58
|
+
* @param index ragdoll bone aggregate index
|
|
59
|
+
* @returns the aggregate for the bone index for the root aggregate if index is invalid
|
|
60
|
+
*/
|
|
61
|
+
getAggregate(index) {
|
|
62
|
+
if (index < 0 || index >= this._aggregates.length) {
|
|
63
|
+
return this._aggregates[this._rootBoneIndex];
|
|
64
|
+
}
|
|
65
|
+
return this._aggregates[index];
|
|
53
66
|
}
|
|
54
67
|
_createColliders() {
|
|
55
|
-
this.
|
|
68
|
+
this._rootTransformNode.computeWorldMatrix();
|
|
69
|
+
this._skeleton.computeAbsoluteMatrices(true);
|
|
70
|
+
this._skeleton.prepare(true);
|
|
56
71
|
const config = this._config;
|
|
57
72
|
for (let i = 0; i < config.length; i++) {
|
|
58
73
|
const boneNames = config[i].bone !== undefined ? [config[i].bone] : config[i].bones;
|
|
@@ -90,10 +105,10 @@ export class Ragdoll {
|
|
|
90
105
|
}
|
|
91
106
|
currentRagdollBoneProperties.boxOffset = boxOffset;
|
|
92
107
|
// Offset axis.
|
|
93
|
-
const boneOffsetAxis = config[i].boneOffsetAxis !== undefined ? config[i].boneOffsetAxis :
|
|
94
|
-
const boneDir = currentBone.getDirection(boneOffsetAxis, this.
|
|
108
|
+
const boneOffsetAxis = config[i].boneOffsetAxis !== undefined ? config[i].boneOffsetAxis : Axis.Y;
|
|
109
|
+
const boneDir = currentBone.getDirection(boneOffsetAxis, this._rootTransformNode);
|
|
95
110
|
currentRagdollBoneProperties.boneOffsetAxis = boneOffsetAxis;
|
|
96
|
-
transform.position = currentBone.getAbsolutePosition(this.
|
|
111
|
+
transform.position = currentBone.getAbsolutePosition(this._rootTransformNode).add(boneDir.scale(boxOffset));
|
|
97
112
|
const mass = config[i].mass !== undefined ? config[i].mass : this._mass;
|
|
98
113
|
const restitution = config[i].restitution !== undefined ? config[i].restitution : this._restitution;
|
|
99
114
|
const aggregate = new PhysicsAggregate(transform, PhysicsShapeType.BOX, {
|
|
@@ -104,17 +119,19 @@ export class Ragdoll {
|
|
|
104
119
|
}, this._scene);
|
|
105
120
|
aggregate.body.setCollisionCallbackEnabled(true);
|
|
106
121
|
aggregate.body.disablePreStep = false;
|
|
122
|
+
aggregate.body.setMotionType(PhysicsMotionType.ANIMATED);
|
|
107
123
|
this._aggregates.push(aggregate);
|
|
108
124
|
this._bones.push(currentBone);
|
|
109
125
|
this._boneNames.push(currentBone.name);
|
|
110
126
|
this._transforms.push(transform);
|
|
111
127
|
this._boxConfigs.push(currentRagdollBoneProperties);
|
|
112
|
-
this._initialRotation.push(currentBone.getRotationQuaternion(Space.WORLD));
|
|
128
|
+
this._initialRotation.push(currentBone.getRotationQuaternion(Space.WORLD, this._rootTransformNode));
|
|
129
|
+
this._initialRotation2.push(currentBone.getRotationQuaternion(Space.WORLD));
|
|
113
130
|
}
|
|
114
131
|
}
|
|
115
132
|
}
|
|
116
133
|
_initJoints() {
|
|
117
|
-
this.
|
|
134
|
+
this._rootTransformNode.computeWorldMatrix();
|
|
118
135
|
for (let i = 0; i < this._bones.length; i++) {
|
|
119
136
|
// The root bone has no joints.
|
|
120
137
|
if (i == this._rootBoneIndex)
|
|
@@ -125,48 +142,76 @@ export class Ragdoll {
|
|
|
125
142
|
return;
|
|
126
143
|
}
|
|
127
144
|
const boneParentIndex = this._boneNames.indexOf(nearestParent.name);
|
|
128
|
-
let distanceFromParentBoxToBone = this._bones[i].getAbsolutePosition(this.
|
|
145
|
+
let distanceFromParentBoxToBone = this._bones[i].getAbsolutePosition(this._rootTransformNode).subtract(this._transforms[boneParentIndex].position);
|
|
129
146
|
const wmat = this._transforms[boneParentIndex].computeWorldMatrix();
|
|
130
147
|
const invertedWorldMat = Matrix.Invert(wmat);
|
|
131
|
-
distanceFromParentBoxToBone = Vector3.TransformCoordinates(this._bones[i].getAbsolutePosition(this.
|
|
132
|
-
const boneAbsPos = this._bones[i].getAbsolutePosition(this.
|
|
148
|
+
distanceFromParentBoxToBone = Vector3.TransformCoordinates(this._bones[i].getAbsolutePosition(this._rootTransformNode), invertedWorldMat);
|
|
149
|
+
const boneAbsPos = this._bones[i].getAbsolutePosition(this._rootTransformNode);
|
|
133
150
|
const boxAbsPos = this._transforms[i].position.clone();
|
|
134
151
|
const myConnectedPivot = boneAbsPos.subtract(boxAbsPos);
|
|
135
|
-
const joint = new
|
|
152
|
+
const joint = new PhysicsConstraint(PhysicsConstraintType.BALL_AND_SOCKET, {
|
|
153
|
+
pivotA: distanceFromParentBoxToBone,
|
|
154
|
+
pivotB: myConnectedPivot,
|
|
155
|
+
axisA: this._boxConfigs[i].rotationAxis,
|
|
156
|
+
axisB: this._boxConfigs[i].rotationAxis,
|
|
157
|
+
collision: false,
|
|
158
|
+
}, this._scene);
|
|
136
159
|
this._aggregates[boneParentIndex].body.addConstraint(this._aggregates[i].body, joint);
|
|
160
|
+
joint.isEnabled = false;
|
|
161
|
+
this._joints.push(joint);
|
|
137
162
|
}
|
|
138
163
|
}
|
|
164
|
+
// set physics body orientation/position from bones
|
|
165
|
+
_syncBonesToPhysics() {
|
|
166
|
+
const rootMatrix = this._rootTransformNode.getWorldMatrix();
|
|
167
|
+
for (let i = 0; i < this._bones.length; i++) {
|
|
168
|
+
// position
|
|
169
|
+
const transform = this._aggregates[i].transformNode;
|
|
170
|
+
const rootPos = this._bones[i].getAbsolutePosition();
|
|
171
|
+
Vector3.TransformCoordinatesToRef(rootPos, rootMatrix, transform.position);
|
|
172
|
+
// added offset
|
|
173
|
+
this._bones[i].getDirectionToRef(this._boxConfigs[i].boneOffsetAxis, this._rootTransformNode, TmpVectors.Vector3[0]);
|
|
174
|
+
TmpVectors.Vector3[0].scaleInPlace(this._boxConfigs[i].boxOffset ?? 0);
|
|
175
|
+
transform.position.addInPlace(TmpVectors.Vector3[0]);
|
|
176
|
+
this._setBoneOrientationToBody(i);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
_setBoneOrientationToBody(boneIndex) {
|
|
180
|
+
const transform = this._aggregates[boneIndex].transformNode;
|
|
181
|
+
const bone = this._bones[boneIndex];
|
|
182
|
+
this._initialRotation[boneIndex].conjugateToRef(TmpVectors.Quaternion[0]);
|
|
183
|
+
bone.getRotationQuaternionToRef(Space.WORLD, this._rootTransformNode, TmpVectors.Quaternion[1]);
|
|
184
|
+
TmpVectors.Quaternion[1].multiplyToRef(TmpVectors.Quaternion[0], transform.rotationQuaternion);
|
|
185
|
+
transform.rotationQuaternion.normalize();
|
|
186
|
+
}
|
|
139
187
|
_syncBonesAndBoxes() {
|
|
140
188
|
if (this.pauseSync) {
|
|
141
189
|
return;
|
|
142
190
|
}
|
|
143
191
|
if (this._ragdollMode) {
|
|
144
|
-
this.
|
|
145
|
-
TmpVectors.Vector3[0].scaleInPlace(this._boxConfigs[this._rootBoneIndex].boxOffset);
|
|
146
|
-
this._bones[this._rootBoneIndex].getAbsolutePositionToRef(this._mesh, TmpVectors.Vector3[1]);
|
|
147
|
-
TmpVectors.Vector3[1].addInPlace(TmpVectors.Vector3[0]);
|
|
148
|
-
this._bones[this._rootBoneIndex].setAbsolutePosition(this._transforms[this._rootBoneIndex].position, this._mesh);
|
|
149
|
-
this._addImpostorRotationToBone(this._rootBoneIndex);
|
|
192
|
+
this._setBodyOrientationToBone(this._rootBoneIndex);
|
|
150
193
|
const rootPos = this._aggregates[this._rootBoneIndex].body.transformNode.position;
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
this.
|
|
194
|
+
this._rootTransformNode.getWorldMatrix().invertToRef(TmpVectors.Matrix[0]);
|
|
195
|
+
Vector3.TransformCoordinatesToRef(rootPos, TmpVectors.Matrix[0], TmpVectors.Vector3[0]);
|
|
196
|
+
this._bones[this._rootBoneIndex].setAbsolutePosition(TmpVectors.Vector3[0]);
|
|
154
197
|
for (let i = 0; i < this._bones.length; i++) {
|
|
155
198
|
if (i == this._rootBoneIndex)
|
|
156
199
|
continue;
|
|
157
|
-
this.
|
|
200
|
+
this._setBodyOrientationToBone(i);
|
|
158
201
|
}
|
|
159
202
|
}
|
|
203
|
+
else {
|
|
204
|
+
this._syncBonesToPhysics();
|
|
205
|
+
}
|
|
160
206
|
}
|
|
161
|
-
|
|
162
|
-
const qmesh = this.
|
|
163
|
-
|
|
207
|
+
_setBodyOrientationToBone(boneIndex) {
|
|
208
|
+
const qmesh = this._rootTransformNode.rotationQuaternion ??
|
|
209
|
+
Quaternion.FromEulerAngles(this._rootTransformNode.rotation.x, this._rootTransformNode.rotation.y, this._rootTransformNode.rotation.z);
|
|
210
|
+
const qbind = this._initialRotation2[boneIndex];
|
|
164
211
|
const qphys = this._aggregates[boneIndex].body?.transformNode?.rotationQuaternion;
|
|
165
|
-
// TmpVectors.Quaternion[1] = mesh.rotation * this._initialRotation[boneIndex]
|
|
166
|
-
// TmpVectors.Quaternion[0] = body.rotation * TmpVectors.Quaternion[1]
|
|
167
212
|
qmesh.multiplyToRef(qbind, TmpVectors.Quaternion[1]);
|
|
168
213
|
qphys.multiplyToRef(TmpVectors.Quaternion[1], TmpVectors.Quaternion[0]);
|
|
169
|
-
this._bones[boneIndex].setRotationQuaternion(TmpVectors.Quaternion[0], Space.WORLD, this.
|
|
214
|
+
this._bones[boneIndex].setRotationQuaternion(TmpVectors.Quaternion[0], Space.WORLD, this._rootTransformNode);
|
|
170
215
|
}
|
|
171
216
|
// Return true if root bone is valid/exists in this.bonesNames. false otherwise.
|
|
172
217
|
_defineRootBone() {
|
|
@@ -194,12 +239,8 @@ export class Ragdoll {
|
|
|
194
239
|
return nearestParent;
|
|
195
240
|
}
|
|
196
241
|
_init() {
|
|
197
|
-
// detach bones with link transform to let physics have control
|
|
198
|
-
this._skeleton.bones.forEach((bone) => {
|
|
199
|
-
bone.linkTransformNode(null);
|
|
200
|
-
});
|
|
201
242
|
this._createColliders();
|
|
202
|
-
// If this.defineRootBone() returns
|
|
243
|
+
// If this.defineRootBone() returns ... there is not root bone.
|
|
203
244
|
if (!this._defineRootBone()) {
|
|
204
245
|
return;
|
|
205
246
|
}
|
|
@@ -207,14 +248,22 @@ export class Ragdoll {
|
|
|
207
248
|
this._scene.registerBeforeRender(() => {
|
|
208
249
|
this._syncBonesAndBoxes();
|
|
209
250
|
});
|
|
251
|
+
this._syncBonesToPhysics();
|
|
210
252
|
}
|
|
211
253
|
/**
|
|
212
254
|
* Enable ragdoll mode. Create physics objects and make them dynamic.
|
|
213
255
|
*/
|
|
214
256
|
ragdoll() {
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
257
|
+
this._ragdollMode = true;
|
|
258
|
+
// detach bones with link transform to let physics have control
|
|
259
|
+
this._skeleton.bones.forEach((bone) => {
|
|
260
|
+
bone.linkTransformNode(null);
|
|
261
|
+
});
|
|
262
|
+
for (let i = 0; i < this._joints.length; i++) {
|
|
263
|
+
this._joints[i].isEnabled = true;
|
|
264
|
+
}
|
|
265
|
+
for (let i = 0; i < this._aggregates.length; i++) {
|
|
266
|
+
this._aggregates[i].body.setMotionType(PhysicsMotionType.DYNAMIC);
|
|
218
267
|
}
|
|
219
268
|
}
|
|
220
269
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ragdoll.js","sourceRoot":"","sources":["../../../../../dev/core/src/Physics/v2/ragdoll.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Skeleton } from \"../../Bones/skeleton\";\r\nimport { Vector3, Matrix, TmpVectors } from \"../../Maths/math.vector\";\r\nimport { Quaternion } from \"../../Maths/math.vector\";\r\nimport type { Scene } from \"../../scene\";\r\nimport { PhysicsAggregate } from \"./physicsAggregate\";\r\nimport { BallAndSocketConstraint } from \"./physicsConstraint\";\r\nimport type { Mesh } from \"../../Meshes/mesh\";\r\nimport { Axis, Space } from \"core/Maths/math.axis\";\r\nimport { PhysicsShapeType, PhysicsConstraintType } from \"./IPhysicsEnginePlugin\";\r\nimport type { Nullable } from \"../../types\";\r\nimport type { Bone } from \"../../Bones/bone\";\r\nimport { Logger } from \"../../Misc/logger\";\r\nimport { TransformNode } from \"../../Meshes/transformNode\";\r\n\r\n/**\r\n * Ragdoll bone properties\r\n * @experimental\r\n */\r\nexport class RagdollBoneProperties {\r\n /**\r\n * Width of the box shape\r\n */\r\n width?: number;\r\n /**\r\n * depth of the box shape\r\n */\r\n depth?: number;\r\n /**\r\n * height of the box shape\r\n */\r\n height?: number;\r\n /**\r\n * size that will be used of width, depth and height of the shape box\r\n */\r\n size?: number;\r\n /**\r\n * Type of Physics Constraint used between bones\r\n */\r\n joint?: number | undefined;\r\n /**\r\n * Main rotation axis used by the constraint, in local space\r\n */\r\n rotationAxis?: Vector3;\r\n /**\r\n * Minimum rotation angle value\r\n */\r\n min?: number;\r\n /**\r\n * Maximum rotation angle value\r\n */\r\n max?: number;\r\n /**\r\n * Offset along local axis\r\n */\r\n boxOffset?: number;\r\n /**\r\n * Axis that need an offset\r\n */\r\n boneOffsetAxis?: Vector3;\r\n}\r\n\r\n/**\r\n * Ragdoll for Physics V2\r\n * @experimental\r\n */\r\nexport class Ragdoll {\r\n private _skeleton: Skeleton;\r\n private _scene: Scene;\r\n private _mesh: Mesh;\r\n private _config: any;\r\n private _boxConfigs: Array<RagdollBoneProperties> = new Array<RagdollBoneProperties>();\r\n\r\n private _bones: Array<Bone> = new Array<Bone>();\r\n private _initialRotation: Array<Quaternion> = new Array<Quaternion>();\r\n private _boneNames: string[] = [];\r\n private _transforms: Array<TransformNode> = new Array<TransformNode>();\r\n private _aggregates: Array<PhysicsAggregate> = new Array<PhysicsAggregate>();\r\n private _ragdollMode: boolean = false;\r\n private _rootBoneName: string = \"\";\r\n private _rootBoneIndex: number = -1;\r\n private _mass: number = 10;\r\n private _restitution: number = 0;\r\n\r\n /**\r\n * Pause synchronization between physics and bone position/orientation\r\n */\r\n public pauseSync: boolean = false;\r\n\r\n private _putBoxesInBoneCenter: boolean;\r\n private _defaultJoint: number = PhysicsConstraintType.HINGE;\r\n private _defaultJointMin: number = -90;\r\n private _defaultJointMax: number = 90;\r\n\r\n private _boneOffsetAxis: Vector3;\r\n\r\n /**\r\n * Construct a new Ragdoll object. Once ready, it can be made dynamic by calling `Ragdoll` method\r\n * @param skeleton The skeleton containing bones to be physicalized\r\n * @param mesh The mesh used by the skeleton\r\n * @param config an array of `RagdollBoneProperties` corresponding to bones and their properties used to instanciate physics bodies\r\n */\r\n constructor(skeleton: Skeleton, mesh: Mesh, config: RagdollBoneProperties[]) {\r\n this._skeleton = skeleton;\r\n this._scene = skeleton.getScene();\r\n this._mesh = mesh;\r\n this._config = config; // initial, user defined box configs. May have several box configs jammed into 1 index.\r\n this._boxConfigs = []; // final box configs. Every element is a separate box config (this.config may have several configs jammed into 1 index).\r\n this._putBoxesInBoneCenter = false;\r\n this._defaultJoint = PhysicsConstraintType.HINGE;\r\n this._boneOffsetAxis = Axis.Y;\r\n }\r\n\r\n private _createColliders(): void {\r\n this._mesh.computeWorldMatrix();\r\n\r\n const config = this._config;\r\n for (let i = 0; i < config.length; i++) {\r\n const boneNames = config[i].bone !== undefined ? [config[i].bone] : config[i].bones;\r\n\r\n for (let ii = 0; ii < boneNames.length; ii++) {\r\n const currentBone = this._skeleton.bones[this._skeleton.getBoneIndexByName(boneNames[ii])];\r\n if (currentBone == undefined) {\r\n return;\r\n }\r\n\r\n // First define the box dimensions, so we can then use them when calling CreateBox().\r\n const currentRagdollBoneProperties: RagdollBoneProperties = {\r\n width: this._config[i].width,\r\n depth: this._config[i].depth,\r\n height: this._config[i].height,\r\n size: this._config[i].size,\r\n };\r\n\r\n currentRagdollBoneProperties.width = currentRagdollBoneProperties.width ?? currentRagdollBoneProperties.size;\r\n currentRagdollBoneProperties.depth = currentRagdollBoneProperties.depth ?? currentRagdollBoneProperties.size;\r\n currentRagdollBoneProperties.height = currentRagdollBoneProperties.height ?? currentRagdollBoneProperties.size;\r\n const transform = new TransformNode(boneNames[ii] + \"_transform\", this._scene);\r\n\r\n // Define the rest of the box properties.\r\n currentRagdollBoneProperties.joint = config[i].joint !== undefined ? config[i].joint : this._defaultJoint;\r\n currentRagdollBoneProperties.rotationAxis = config[i].rotationAxis !== undefined ? config[i].rotationAxis : Axis.X;\r\n currentRagdollBoneProperties.min = config[i].min !== undefined ? config[i].min : this._defaultJointMin;\r\n currentRagdollBoneProperties.max = config[i].max !== undefined ? config[i].max : this._defaultJointMax;\r\n\r\n // Offset value.\r\n let boxOffset = 0;\r\n if ((config[i].putBoxInBoneCenter !== undefined && config[i].putBoxInBoneCenter) || this._putBoxesInBoneCenter) {\r\n if (currentBone.length === undefined) {\r\n Logger.Log(\"The length property is not defined for bone \" + currentBone.name);\r\n }\r\n boxOffset = currentBone.length / 2;\r\n } else if (config[i].boxOffset !== undefined) {\r\n boxOffset = config[i].boxOffset;\r\n }\r\n currentRagdollBoneProperties.boxOffset = boxOffset;\r\n\r\n // Offset axis.\r\n const boneOffsetAxis = config[i].boneOffsetAxis !== undefined ? config[i].boneOffsetAxis : this._boneOffsetAxis;\r\n const boneDir = currentBone.getDirection(boneOffsetAxis, this._mesh);\r\n currentRagdollBoneProperties.boneOffsetAxis = boneOffsetAxis;\r\n\r\n transform.position = currentBone.getAbsolutePosition(this._mesh).add(boneDir.scale(boxOffset));\r\n\r\n const mass = config[i].mass !== undefined ? config[i].mass : this._mass;\r\n const restitution = config[i].restitution !== undefined ? config[i].restitution : this._restitution;\r\n const aggregate = new PhysicsAggregate(\r\n transform,\r\n PhysicsShapeType.BOX,\r\n {\r\n mass: mass,\r\n restitution: restitution,\r\n friction: 0.6,\r\n extents: new Vector3(currentRagdollBoneProperties.width, currentRagdollBoneProperties.height, currentRagdollBoneProperties.depth),\r\n },\r\n this._scene\r\n );\r\n aggregate.body.setCollisionCallbackEnabled(true);\r\n aggregate.body.disablePreStep = false;\r\n this._aggregates.push(aggregate);\r\n this._bones.push(currentBone);\r\n this._boneNames.push(currentBone.name);\r\n this._transforms.push(transform);\r\n this._boxConfigs.push(currentRagdollBoneProperties);\r\n this._initialRotation.push(currentBone.getRotationQuaternion(Space.WORLD));\r\n }\r\n }\r\n }\r\n\r\n private _initJoints(): void {\r\n this._mesh.computeWorldMatrix();\r\n for (let i = 0; i < this._bones.length; i++) {\r\n // The root bone has no joints.\r\n if (i == this._rootBoneIndex) continue;\r\n\r\n const nearestParent = this._findNearestParent(i);\r\n\r\n if (nearestParent == null) {\r\n Logger.Warn(\"Couldn't find a nearest parent bone in the configs for bone called \" + this._boneNames[i]);\r\n return;\r\n }\r\n\r\n const boneParentIndex = this._boneNames.indexOf(nearestParent.name);\r\n\r\n let distanceFromParentBoxToBone = this._bones[i].getAbsolutePosition(this._mesh).subtract(this._transforms[boneParentIndex].position);\r\n\r\n const wmat = this._transforms[boneParentIndex].computeWorldMatrix();\r\n const invertedWorldMat = Matrix.Invert(wmat);\r\n distanceFromParentBoxToBone = Vector3.TransformCoordinates(this._bones[i].getAbsolutePosition(this._mesh), invertedWorldMat);\r\n\r\n const boneAbsPos = this._bones[i].getAbsolutePosition(this._mesh);\r\n const boxAbsPos = this._transforms[i].position.clone();\r\n const myConnectedPivot = boneAbsPos.subtract(boxAbsPos);\r\n\r\n const joint = new BallAndSocketConstraint(\r\n distanceFromParentBoxToBone,\r\n myConnectedPivot,\r\n this._boxConfigs[i].rotationAxis!,\r\n this._boxConfigs[i].rotationAxis!,\r\n this._scene\r\n );\r\n this._aggregates[boneParentIndex].body.addConstraint(this._aggregates[i].body, joint);\r\n }\r\n }\r\n\r\n private _syncBonesAndBoxes(): void {\r\n if (this.pauseSync) {\r\n return;\r\n }\r\n\r\n if (this._ragdollMode) {\r\n this._bones[this._rootBoneIndex].getDirectionToRef(this._boxConfigs[this._rootBoneIndex].boneOffsetAxis!, this._mesh, TmpVectors.Vector3[0]);\r\n TmpVectors.Vector3[0].scaleInPlace(this._boxConfigs[this._rootBoneIndex].boxOffset!);\r\n this._bones[this._rootBoneIndex].getAbsolutePositionToRef(this._mesh, TmpVectors.Vector3[1]);\r\n TmpVectors.Vector3[1].addInPlace(TmpVectors.Vector3[0]);\r\n\r\n this._bones[this._rootBoneIndex].setAbsolutePosition(this._transforms[this._rootBoneIndex].position, this._mesh);\r\n this._addImpostorRotationToBone(this._rootBoneIndex);\r\n\r\n const rootPos = this._aggregates[this._rootBoneIndex].body.transformNode.position;\r\n\r\n // Move the mesh, to guarantee alignment between root bone and impostor box position\r\n TmpVectors.Vector3[1].subtractToRef(rootPos, TmpVectors.Vector3[0]);\r\n this._mesh.position.subtractToRef(TmpVectors.Vector3[0], this._mesh.position);\r\n\r\n for (let i = 0; i < this._bones.length; i++) {\r\n if (i == this._rootBoneIndex) continue;\r\n this._addImpostorRotationToBone(i);\r\n }\r\n }\r\n }\r\n\r\n private _addImpostorRotationToBone(boneIndex: number): void {\r\n const qmesh = this._mesh.rotationQuaternion ?? Quaternion.FromEulerAngles(this._mesh.rotation.x, this._mesh.rotation.y, this._mesh.rotation.z);\r\n const qbind = this._initialRotation[boneIndex];\r\n const qphys = this._aggregates[boneIndex].body?.transformNode?.rotationQuaternion!;\r\n\r\n // TmpVectors.Quaternion[1] = mesh.rotation * this._initialRotation[boneIndex]\r\n // TmpVectors.Quaternion[0] = body.rotation * TmpVectors.Quaternion[1]\r\n qmesh.multiplyToRef(qbind, TmpVectors.Quaternion[1]);\r\n qphys.multiplyToRef(TmpVectors.Quaternion[1], TmpVectors.Quaternion[0]);\r\n\r\n this._bones[boneIndex].setRotationQuaternion(TmpVectors.Quaternion[0], Space.WORLD, this._mesh);\r\n }\r\n\r\n // Return true if root bone is valid/exists in this.bonesNames. false otherwise.\r\n private _defineRootBone(): boolean {\r\n const skeletonRoots = this._skeleton.getChildren();\r\n if (skeletonRoots.length != 1) {\r\n Logger.Log(\"Ragdoll creation failed: there can only be one root in the skeleton.\");\r\n return false;\r\n }\r\n\r\n this._rootBoneName = skeletonRoots[0].name;\r\n this._rootBoneIndex = this._boneNames.indexOf(this._rootBoneName);\r\n if (this._rootBoneIndex == -1) {\r\n Logger.Log(\"Ragdoll creation failed: the array boneNames doesn't have the root bone. The root bone is \" + this._skeleton.getChildren());\r\n return false;\r\n }\r\n\r\n return true;\r\n }\r\n\r\n private _findNearestParent(boneIndex: number): any {\r\n let nearestParent: Nullable<Bone> | undefined = this._bones[boneIndex].getParent();\r\n do {\r\n if (nearestParent != null && this._boneNames.includes(nearestParent.name)) {\r\n break;\r\n }\r\n\r\n nearestParent = nearestParent?.getParent();\r\n } while (nearestParent != null);\r\n\r\n return nearestParent;\r\n }\r\n\r\n private _init() {\r\n // detach bones with link transform to let physics have control\r\n this._skeleton.bones.forEach((bone) => {\r\n bone.linkTransformNode(null);\r\n });\r\n\r\n this._createColliders();\r\n\r\n // If this.defineRootBone() returns false... there is not root bone.\r\n if (!this._defineRootBone()) {\r\n return;\r\n }\r\n\r\n this._initJoints();\r\n this._scene.registerBeforeRender(() => {\r\n this._syncBonesAndBoxes();\r\n });\r\n }\r\n\r\n /**\r\n * Enable ragdoll mode. Create physics objects and make them dynamic.\r\n */\r\n public ragdoll(): void {\r\n if (!this._ragdollMode) {\r\n this._ragdollMode = true;\r\n this._init();\r\n }\r\n }\r\n\r\n /**\r\n * Dispose resources and remove physics objects\r\n */\r\n dispose(): void {\r\n this._aggregates.forEach((aggregate: PhysicsAggregate) => {\r\n aggregate.dispose();\r\n });\r\n }\r\n}\r\n"]}
|
|
1
|
+
{"version":3,"file":"ragdoll.js","sourceRoot":"","sources":["../../../../../dev/core/src/Physics/v2/ragdoll.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Skeleton } from \"../../Bones/skeleton\";\r\nimport { Vector3, Matrix, TmpVectors, Quaternion } from \"../../Maths/math.vector\";\r\nimport type { Scene } from \"../../scene\";\r\nimport { PhysicsAggregate } from \"./physicsAggregate\";\r\nimport { PhysicsConstraint } from \"./physicsConstraint\";\r\nimport type { Mesh } from \"../../Meshes/mesh\";\r\nimport { Axis, Space } from \"core/Maths/math.axis\";\r\nimport { PhysicsShapeType, PhysicsConstraintType, PhysicsMotionType } from \"./IPhysicsEnginePlugin\";\r\nimport type { Nullable } from \"../../types\";\r\nimport type { Bone } from \"../../Bones/bone\";\r\nimport { Logger } from \"../../Misc/logger\";\r\nimport { TransformNode } from \"../../Meshes/transformNode\";\r\n\r\n/**\r\n * Ragdoll bone properties\r\n * @experimental\r\n */\r\nexport class RagdollBoneProperties {\r\n /**\r\n * Width of the box shape\r\n */\r\n width?: number;\r\n /**\r\n * depth of the box shape\r\n */\r\n depth?: number;\r\n /**\r\n * height of the box shape\r\n */\r\n height?: number;\r\n /**\r\n * size that will be used of width, depth and height of the shape box\r\n */\r\n size?: number;\r\n /**\r\n * Type of Physics Constraint used between bones\r\n */\r\n joint?: number | undefined;\r\n /**\r\n * Main rotation axis used by the constraint, in local space\r\n */\r\n rotationAxis?: Vector3;\r\n /**\r\n * Minimum rotation angle value\r\n */\r\n min?: number;\r\n /**\r\n * Maximum rotation angle value\r\n */\r\n max?: number;\r\n /**\r\n * Offset along local axis\r\n */\r\n boxOffset?: number;\r\n /**\r\n * Axis that need an offset\r\n */\r\n boneOffsetAxis?: Vector3;\r\n}\r\n\r\n/**\r\n * Ragdoll for Physics V2\r\n * @experimental\r\n */\r\nexport class Ragdoll {\r\n private _skeleton: Skeleton;\r\n private _scene: Scene;\r\n private _rootTransformNode: Mesh | TransformNode;\r\n private _config: any;\r\n private _boxConfigs: Array<RagdollBoneProperties> = new Array<RagdollBoneProperties>();\r\n private _joints: Array<PhysicsConstraint> = new Array<PhysicsConstraint>();\r\n private _bones: Array<Bone> = new Array<Bone>();\r\n private _initialRotation: Array<Quaternion> = new Array<Quaternion>();\r\n // without mesh transform, to figure out later\r\n private _initialRotation2: Array<Quaternion> = new Array<Quaternion>();\r\n private _boneNames: string[] = [];\r\n private _transforms: Array<TransformNode> = new Array<TransformNode>();\r\n private _aggregates: Array<PhysicsAggregate> = new Array<PhysicsAggregate>();\r\n private _ragdollMode: boolean = false;\r\n private _rootBoneName: string = \"\";\r\n private _rootBoneIndex: number = -1;\r\n private _mass: number = 10;\r\n private _restitution: number = 0;\r\n\r\n /**\r\n * Pause synchronization between physics and bone position/orientation\r\n */\r\n public pauseSync: boolean = false;\r\n\r\n private _putBoxesInBoneCenter: boolean;\r\n private _defaultJoint: number = PhysicsConstraintType.HINGE;\r\n private _defaultJointMin: number = -90;\r\n private _defaultJointMax: number = 90;\r\n\r\n /**\r\n * Construct a new Ragdoll object. Once ready, it can be made dynamic by calling `Ragdoll` method\r\n * @param skeleton The skeleton containing bones to be physicalized\r\n * @param rootTransformNode The mesh or its transform used by the skeleton\r\n * @param config an array of `RagdollBoneProperties` corresponding to bones and their properties used to instanciate physics bodies\r\n */\r\n constructor(skeleton: Skeleton, rootTransformNode: Mesh | TransformNode, config: RagdollBoneProperties[]) {\r\n this._skeleton = skeleton;\r\n this._scene = skeleton.getScene();\r\n this._rootTransformNode = rootTransformNode;\r\n this._config = config; // initial, user defined box configs. May have several box configs jammed into 1 index.\r\n this._boxConfigs = []; // final box configs. Every element is a separate box config (this.config may have several configs jammed into 1 index).\r\n this._putBoxesInBoneCenter = false;\r\n this._defaultJoint = PhysicsConstraintType.HINGE;\r\n\r\n this._init();\r\n }\r\n\r\n /**\r\n * Returns the aggregate corresponding to the ragdoll bone index\r\n * @param index ragdoll bone aggregate index\r\n * @returns the aggregate for the bone index for the root aggregate if index is invalid\r\n */\r\n public getAggregate(index: number): PhysicsAggregate {\r\n if (index < 0 || index >= this._aggregates.length) {\r\n return this._aggregates[this._rootBoneIndex];\r\n }\r\n return this._aggregates[index];\r\n }\r\n\r\n private _createColliders(): void {\r\n this._rootTransformNode.computeWorldMatrix();\r\n this._skeleton.computeAbsoluteMatrices(true);\r\n this._skeleton.prepare(true);\r\n\r\n const config = this._config;\r\n for (let i = 0; i < config.length; i++) {\r\n const boneNames = config[i].bone !== undefined ? [config[i].bone] : config[i].bones;\r\n\r\n for (let ii = 0; ii < boneNames.length; ii++) {\r\n const currentBone = this._skeleton.bones[this._skeleton.getBoneIndexByName(boneNames[ii])];\r\n if (currentBone == undefined) {\r\n return;\r\n }\r\n\r\n // First define the box dimensions, so we can then use them when calling CreateBox().\r\n const currentRagdollBoneProperties: RagdollBoneProperties = {\r\n width: this._config[i].width,\r\n depth: this._config[i].depth,\r\n height: this._config[i].height,\r\n size: this._config[i].size,\r\n };\r\n\r\n currentRagdollBoneProperties.width = currentRagdollBoneProperties.width ?? currentRagdollBoneProperties.size;\r\n currentRagdollBoneProperties.depth = currentRagdollBoneProperties.depth ?? currentRagdollBoneProperties.size;\r\n currentRagdollBoneProperties.height = currentRagdollBoneProperties.height ?? currentRagdollBoneProperties.size;\r\n const transform = new TransformNode(boneNames[ii] + \"_transform\", this._scene);\r\n\r\n // Define the rest of the box properties.\r\n currentRagdollBoneProperties.joint = config[i].joint !== undefined ? config[i].joint : this._defaultJoint;\r\n currentRagdollBoneProperties.rotationAxis = config[i].rotationAxis !== undefined ? config[i].rotationAxis : Axis.X;\r\n currentRagdollBoneProperties.min = config[i].min !== undefined ? config[i].min : this._defaultJointMin;\r\n currentRagdollBoneProperties.max = config[i].max !== undefined ? config[i].max : this._defaultJointMax;\r\n\r\n // Offset value.\r\n let boxOffset = 0;\r\n if ((config[i].putBoxInBoneCenter !== undefined && config[i].putBoxInBoneCenter) || this._putBoxesInBoneCenter) {\r\n if (currentBone.length === undefined) {\r\n Logger.Log(\"The length property is not defined for bone \" + currentBone.name);\r\n }\r\n boxOffset = currentBone.length / 2;\r\n } else if (config[i].boxOffset !== undefined) {\r\n boxOffset = config[i].boxOffset;\r\n }\r\n currentRagdollBoneProperties.boxOffset = boxOffset;\r\n\r\n // Offset axis.\r\n const boneOffsetAxis = config[i].boneOffsetAxis !== undefined ? config[i].boneOffsetAxis : Axis.Y;\r\n const boneDir = currentBone.getDirection(boneOffsetAxis, this._rootTransformNode);\r\n currentRagdollBoneProperties.boneOffsetAxis = boneOffsetAxis;\r\n\r\n transform.position = currentBone.getAbsolutePosition(this._rootTransformNode).add(boneDir.scale(boxOffset));\r\n\r\n const mass = config[i].mass !== undefined ? config[i].mass : this._mass;\r\n const restitution = config[i].restitution !== undefined ? config[i].restitution : this._restitution;\r\n const aggregate = new PhysicsAggregate(\r\n transform,\r\n PhysicsShapeType.BOX,\r\n {\r\n mass: mass,\r\n restitution: restitution,\r\n friction: 0.6,\r\n extents: new Vector3(currentRagdollBoneProperties.width, currentRagdollBoneProperties.height, currentRagdollBoneProperties.depth),\r\n },\r\n this._scene\r\n );\r\n aggregate.body.setCollisionCallbackEnabled(true);\r\n aggregate.body.disablePreStep = false;\r\n aggregate.body.setMotionType(PhysicsMotionType.ANIMATED);\r\n this._aggregates.push(aggregate);\r\n this._bones.push(currentBone);\r\n this._boneNames.push(currentBone.name);\r\n this._transforms.push(transform);\r\n this._boxConfigs.push(currentRagdollBoneProperties);\r\n this._initialRotation.push(currentBone.getRotationQuaternion(Space.WORLD, this._rootTransformNode));\r\n this._initialRotation2.push(currentBone.getRotationQuaternion(Space.WORLD));\r\n }\r\n }\r\n }\r\n\r\n private _initJoints(): void {\r\n this._rootTransformNode.computeWorldMatrix();\r\n for (let i = 0; i < this._bones.length; i++) {\r\n // The root bone has no joints.\r\n if (i == this._rootBoneIndex) continue;\r\n\r\n const nearestParent = this._findNearestParent(i);\r\n\r\n if (nearestParent == null) {\r\n Logger.Warn(\"Couldn't find a nearest parent bone in the configs for bone called \" + this._boneNames[i]);\r\n return;\r\n }\r\n\r\n const boneParentIndex = this._boneNames.indexOf(nearestParent.name);\r\n\r\n let distanceFromParentBoxToBone = this._bones[i].getAbsolutePosition(this._rootTransformNode).subtract(this._transforms[boneParentIndex].position);\r\n\r\n const wmat = this._transforms[boneParentIndex].computeWorldMatrix();\r\n const invertedWorldMat = Matrix.Invert(wmat);\r\n distanceFromParentBoxToBone = Vector3.TransformCoordinates(this._bones[i].getAbsolutePosition(this._rootTransformNode), invertedWorldMat);\r\n\r\n const boneAbsPos = this._bones[i].getAbsolutePosition(this._rootTransformNode);\r\n const boxAbsPos = this._transforms[i].position.clone();\r\n const myConnectedPivot = boneAbsPos.subtract(boxAbsPos);\r\n\r\n const joint = new PhysicsConstraint(\r\n PhysicsConstraintType.BALL_AND_SOCKET,\r\n {\r\n pivotA: distanceFromParentBoxToBone,\r\n pivotB: myConnectedPivot,\r\n axisA: this._boxConfigs[i].rotationAxis!,\r\n axisB: this._boxConfigs[i].rotationAxis!,\r\n collision: false,\r\n },\r\n this._scene\r\n );\r\n\r\n this._aggregates[boneParentIndex].body.addConstraint(this._aggregates[i].body, joint);\r\n joint.isEnabled = false;\r\n this._joints.push(joint);\r\n }\r\n }\r\n\r\n // set physics body orientation/position from bones\r\n private _syncBonesToPhysics(): void {\r\n const rootMatrix = this._rootTransformNode.getWorldMatrix();\r\n for (let i = 0; i < this._bones.length; i++) {\r\n // position\r\n const transform = this._aggregates[i].transformNode;\r\n const rootPos = this._bones[i].getAbsolutePosition();\r\n Vector3.TransformCoordinatesToRef(rootPos, rootMatrix, transform.position);\r\n\r\n // added offset\r\n this._bones[i].getDirectionToRef(this._boxConfigs[i].boneOffsetAxis!, this._rootTransformNode, TmpVectors.Vector3[0]);\r\n TmpVectors.Vector3[0].scaleInPlace(this._boxConfigs[i].boxOffset ?? 0);\r\n transform.position.addInPlace(TmpVectors.Vector3[0]);\r\n\r\n this._setBoneOrientationToBody(i);\r\n }\r\n }\r\n\r\n private _setBoneOrientationToBody(boneIndex: number): void {\r\n const transform = this._aggregates[boneIndex].transformNode;\r\n const bone = this._bones[boneIndex];\r\n this._initialRotation[boneIndex].conjugateToRef(TmpVectors.Quaternion[0]);\r\n bone.getRotationQuaternionToRef(Space.WORLD, this._rootTransformNode, TmpVectors.Quaternion[1]);\r\n TmpVectors.Quaternion[1].multiplyToRef(TmpVectors.Quaternion[0], transform.rotationQuaternion!);\r\n transform.rotationQuaternion!.normalize();\r\n }\r\n\r\n private _syncBonesAndBoxes(): void {\r\n if (this.pauseSync) {\r\n return;\r\n }\r\n\r\n if (this._ragdollMode) {\r\n this._setBodyOrientationToBone(this._rootBoneIndex);\r\n\r\n const rootPos = this._aggregates[this._rootBoneIndex].body.transformNode.position;\r\n this._rootTransformNode.getWorldMatrix().invertToRef(TmpVectors.Matrix[0]);\r\n\r\n Vector3.TransformCoordinatesToRef(rootPos, TmpVectors.Matrix[0], TmpVectors.Vector3[0]);\r\n this._bones[this._rootBoneIndex].setAbsolutePosition(TmpVectors.Vector3[0]);\r\n\r\n for (let i = 0; i < this._bones.length; i++) {\r\n if (i == this._rootBoneIndex) continue;\r\n this._setBodyOrientationToBone(i);\r\n }\r\n } else {\r\n this._syncBonesToPhysics();\r\n }\r\n }\r\n\r\n private _setBodyOrientationToBone(boneIndex: number): void {\r\n const qmesh =\r\n this._rootTransformNode.rotationQuaternion ??\r\n Quaternion.FromEulerAngles(this._rootTransformNode.rotation.x, this._rootTransformNode.rotation.y, this._rootTransformNode.rotation.z);\r\n const qbind = this._initialRotation2[boneIndex];\r\n const qphys = this._aggregates[boneIndex].body?.transformNode?.rotationQuaternion!;\r\n\r\n qmesh.multiplyToRef(qbind, TmpVectors.Quaternion[1]);\r\n qphys.multiplyToRef(TmpVectors.Quaternion[1], TmpVectors.Quaternion[0]);\r\n\r\n this._bones[boneIndex].setRotationQuaternion(TmpVectors.Quaternion[0], Space.WORLD, this._rootTransformNode);\r\n }\r\n\r\n // Return true if root bone is valid/exists in this.bonesNames. false otherwise.\r\n private _defineRootBone(): boolean {\r\n const skeletonRoots = this._skeleton.getChildren();\r\n if (skeletonRoots.length != 1) {\r\n Logger.Log(\"Ragdoll creation failed: there can only be one root in the skeleton.\");\r\n return false;\r\n }\r\n\r\n this._rootBoneName = skeletonRoots[0].name;\r\n this._rootBoneIndex = this._boneNames.indexOf(this._rootBoneName);\r\n if (this._rootBoneIndex == -1) {\r\n Logger.Log(\"Ragdoll creation failed: the array boneNames doesn't have the root bone. The root bone is \" + this._skeleton.getChildren());\r\n return false;\r\n }\r\n\r\n return true;\r\n }\r\n\r\n private _findNearestParent(boneIndex: number): any {\r\n let nearestParent: Nullable<Bone> | undefined = this._bones[boneIndex].getParent();\r\n do {\r\n if (nearestParent != null && this._boneNames.includes(nearestParent.name)) {\r\n break;\r\n }\r\n\r\n nearestParent = nearestParent?.getParent();\r\n } while (nearestParent != null);\r\n\r\n return nearestParent;\r\n }\r\n\r\n private _init() {\r\n this._createColliders();\r\n\r\n // If this.defineRootBone() returns ... there is not root bone.\r\n if (!this._defineRootBone()) {\r\n return;\r\n }\r\n\r\n this._initJoints();\r\n this._scene.registerBeforeRender(() => {\r\n this._syncBonesAndBoxes();\r\n });\r\n this._syncBonesToPhysics();\r\n }\r\n\r\n /**\r\n * Enable ragdoll mode. Create physics objects and make them dynamic.\r\n */\r\n public ragdoll(): void {\r\n this._ragdollMode = true;\r\n // detach bones with link transform to let physics have control\r\n this._skeleton.bones.forEach((bone) => {\r\n bone.linkTransformNode(null);\r\n });\r\n for (let i = 0; i < this._joints.length; i++) {\r\n this._joints[i].isEnabled = true;\r\n }\r\n for (let i = 0; i < this._aggregates.length; i++) {\r\n this._aggregates[i].body.setMotionType(PhysicsMotionType.DYNAMIC);\r\n }\r\n }\r\n\r\n /**\r\n * Dispose resources and remove physics objects\r\n */\r\n dispose(): void {\r\n this._aggregates.forEach((aggregate: PhysicsAggregate) => {\r\n aggregate.dispose();\r\n });\r\n }\r\n}\r\n"]}
|