@@ -235,11 +235,11 @@
|
|
235
235
|
// if (!this._activeState) return;
|
236
236
|
const dt = this.animator.context.time.deltaTime;
|
237
237
|
if (this.animator.applyRootMotion) {
|
238
|
-
this.rootMotionHandler?.onBeforeUpdate();
|
238
|
+
this.rootMotionHandler?.onBeforeUpdate(weight);
|
239
239
|
}
|
240
240
|
this._mixer.update(dt);
|
241
241
|
if (this.animator.applyRootMotion) {
|
242
|
-
this.rootMotionHandler?.onAfterUpdate();
|
242
|
+
this.rootMotionHandler?.onAfterUpdate(weight);
|
243
243
|
}
|
244
244
|
}
|
245
245
|
|
@@ -881,14 +881,14 @@
|
|
881
881
|
|
882
882
|
// private lastPos: Vector3 = new Vector3();
|
883
883
|
|
884
|
-
onBeforeUpdate() {
|
884
|
+
onBeforeUpdate(_weight: number) {
|
885
885
|
this.positionChange.set(0, 0, 0);
|
886
886
|
this.rotationChange.set(0, 0, 0, 1);
|
887
887
|
}
|
888
888
|
|
889
|
-
onAfterUpdate(): boolean {
|
889
|
+
onAfterUpdate(weight: number): boolean {
|
890
890
|
if (!this.action) return false;
|
891
|
-
|
891
|
+
weight *= this.action.getEffectiveWeight();
|
892
892
|
if (weight <= 0) return false;
|
893
893
|
this.positionChange.multiplyScalar(weight);
|
894
894
|
this.rotationChange.slerp(RootMotionAction.identityQuaternion, 1 - weight);
|
@@ -937,19 +937,22 @@
|
|
937
937
|
|
938
938
|
}
|
939
939
|
|
940
|
-
onBeforeUpdate() {
|
940
|
+
onBeforeUpdate(weight: number) {
|
941
941
|
// capture the position of the object
|
942
942
|
this.basePosition.copy(this.root.position);
|
943
943
|
this.baseQuaternion.copy(this.root.quaternion);
|
944
944
|
|
945
945
|
for (const hand of this.handler)
|
946
|
-
hand.onBeforeUpdate();
|
946
|
+
hand.onBeforeUpdate(weight);
|
947
947
|
}
|
948
948
|
|
949
949
|
private summedPosition: Vector3 = new Vector3();
|
950
950
|
private summedRotation: Quaternion = new Quaternion();
|
951
951
|
|
952
|
-
onAfterUpdate() {
|
952
|
+
onAfterUpdate(weight: number) {
|
953
|
+
if (weight <= 0) return;
|
954
|
+
// TODO: blend weight properly with root motion (when using timeline blending with animator)
|
955
|
+
|
953
956
|
// apply the accumulated changes
|
954
957
|
this.root.position.copy(this.basePosition);
|
955
958
|
this.root.quaternion.copy(this.baseQuaternion);
|
@@ -957,7 +960,7 @@
|
|
957
960
|
this.summedPosition.set(0, 0, 0);
|
958
961
|
this.summedRotation.set(0, 0, 0, 1);
|
959
962
|
for (const entry of this.handler) {
|
960
|
-
if (entry.onAfterUpdate()) {
|
963
|
+
if (entry.onAfterUpdate(weight)) {
|
961
964
|
this.summedPosition.add(entry.positionChange);
|
962
965
|
this.summedRotation.multiply(entry.rotationChange);
|
963
966
|
}
|
@@ -229,9 +229,12 @@
|
|
229
229
|
this._hasCreatedWorld = true;
|
230
230
|
if (RAPIER === undefined) {
|
231
231
|
if (debugPhysics) console.log("Import Rapier");
|
232
|
-
|
232
|
+
const _rapier = await import("@dimforge/rapier3d-compat");
|
233
233
|
if (debugPhysics) console.log("Init Rapier");
|
234
|
-
await
|
234
|
+
await _rapier.init();
|
235
|
+
// only assign after all loads are done to avoid a race condition
|
236
|
+
// where RAPIER is already set and then used while actually still waiting for initialization.
|
237
|
+
RAPIER = _rapier;
|
235
238
|
}
|
236
239
|
if (debugPhysics) console.log("Physics engine initialized, creating world...");
|
237
240
|
this._world = new World(this._gravity);
|
@@ -668,7 +671,7 @@
|
|
668
671
|
// otherwise rapier will compute the mass properties based on the collider shape and density
|
669
672
|
// https://rapier.rs/docs/user_guides/javascript/rigid_bodies#mass-properties
|
670
673
|
if (useExplicitMassProperties) {
|
671
|
-
|
674
|
+
desc.setDensity(0);
|
672
675
|
}
|
673
676
|
|
674
677
|
const col = this.world.createCollider(desc, rigidBody);
|
@@ -696,7 +699,7 @@
|
|
696
699
|
|
697
700
|
const rb = collider.attachedRigidbody;
|
698
701
|
rigidBody = rb[$bodyKey];
|
699
|
-
useExplicitMassProperties =
|
702
|
+
useExplicitMassProperties = rb.autoMass === false;
|
700
703
|
if (!rigidBody) {
|
701
704
|
const kinematic = rb.isKinematic && !debugColliderPlacement;
|
702
705
|
if (debugPhysics)
|
@@ -744,6 +747,30 @@
|
|
744
747
|
rigidbody.setAngularDamping(rb.angularDrag);
|
745
748
|
rigidbody.setGravityScale(rb.useGravity ? rb.gravityScale : 0, true);
|
746
749
|
|
750
|
+
// https://rapier.rs/docs/user_guides/javascript/rigid_bodies#dominance
|
751
|
+
if (rb.dominanceGroup <= 127 && rb.dominanceGroup >= -127)
|
752
|
+
rigidbody.setDominanceGroup(Math.floor(rb.dominanceGroup))
|
753
|
+
else rigidbody.setDominanceGroup(0);
|
754
|
+
|
755
|
+
if (rb.autoMass) {
|
756
|
+
rigidbody.setAdditionalMass(0, false);
|
757
|
+
for (let i = 0; i < rigidbody.numColliders(); i++) {
|
758
|
+
const col = rigidbody.collider(i);
|
759
|
+
col.setDensity(1);
|
760
|
+
}
|
761
|
+
rigidbody.recomputeMassPropertiesFromColliders();
|
762
|
+
console.log(rigidbody.mass())
|
763
|
+
}
|
764
|
+
else {
|
765
|
+
rigidbody.setAdditionalMass(rb.mass, false);
|
766
|
+
for (let i = 0; i < rigidbody.numColliders(); i++) {
|
767
|
+
const col = rigidbody.collider(i);
|
768
|
+
col.setDensity(0);
|
769
|
+
}
|
770
|
+
rigidbody.recomputeMassPropertiesFromColliders();
|
771
|
+
console.log(rigidbody.mass())
|
772
|
+
}
|
773
|
+
|
747
774
|
// https://rapier.rs/docs/user_guides/javascript/rigid_bodies#mass-properties
|
748
775
|
// rigidbody.setAdditionalMass(rb.mass, true);
|
749
776
|
// for (let i = 0; i < rigidbody.numColliders(); i++) {
|
@@ -247,11 +247,15 @@
|
|
247
247
|
export declare interface IRigidbody extends IComponent {
|
248
248
|
constraints: RigidbodyConstraints;
|
249
249
|
isKinematic: boolean;
|
250
|
+
/** When true the mass will automatically calculated by attached colliders */
|
251
|
+
autoMass: boolean;
|
250
252
|
mass: number;
|
251
253
|
drag: number;
|
252
254
|
angularDrag: number;
|
253
255
|
useGravity: boolean;
|
254
256
|
gravityScale: number;
|
257
|
+
dominanceGroup: number;
|
258
|
+
|
255
259
|
collisionDetectionMode: CollisionDetectionMode;
|
256
260
|
|
257
261
|
lockPositionX: boolean;
|
@@ -97,8 +97,8 @@
|
|
97
97
|
if (!res) {
|
98
98
|
const rc = GameObject.addNewComponent(this.context.scene, ObjectRaycaster);
|
99
99
|
this.raycaster.push(rc);
|
100
|
-
if (isDevEnvironment())
|
101
|
-
console.warn("Added an ObjectRaycaster to the scene because no raycaster was found"
|
100
|
+
if (isDevEnvironment() || debug)
|
101
|
+
console.warn("Added an ObjectRaycaster to the scene because no raycaster was found");
|
102
102
|
}
|
103
103
|
}
|
104
104
|
}
|
@@ -133,9 +133,26 @@
|
|
133
133
|
|
134
134
|
export class Rigidbody extends Behaviour implements IRigidbody {
|
135
135
|
|
136
|
+
/** When true the mass will be automatically calculated by the attached colliders */
|
136
137
|
@validate()
|
138
|
+
autoMass: boolean = true;
|
139
|
+
|
137
140
|
@serializable()
|
138
|
-
mass: number
|
141
|
+
set mass(value: number) {
|
142
|
+
if (value === this._mass) return;
|
143
|
+
this._mass = value;
|
144
|
+
this._propertiesChanged = true;
|
145
|
+
// When setting the mass manually we disable autoMass
|
146
|
+
if (this.__didAwake) {
|
147
|
+
this.autoMass = false;
|
148
|
+
}
|
149
|
+
}
|
150
|
+
get mass() {
|
151
|
+
if (this.autoMass)
|
152
|
+
return this.context.physics.engine?.getBody(this)?.mass() ?? -1;
|
153
|
+
return this._mass;
|
154
|
+
}
|
155
|
+
private _mass: number = 0;
|
139
156
|
|
140
157
|
@validate()
|
141
158
|
@serializable()
|
@@ -219,8 +236,15 @@
|
|
219
236
|
get gravityScale() {
|
220
237
|
return this._gravityScale;
|
221
238
|
}
|
239
|
+
@validate()
|
222
240
|
private _gravityScale: number = 1;
|
223
241
|
|
242
|
+
/** Rigidbodies with higher dominance will be immune to forces originating from contacts with rigidbodies of lower dominance.
|
243
|
+
* Read more here: https://rapier.rs/docs/user_guides/javascript/rigid_bodies#dominance
|
244
|
+
*/
|
245
|
+
@validate()
|
246
|
+
dominanceGroup : number = 0;
|
247
|
+
|
224
248
|
private static tempPosition: THREE.Vector3 = new THREE.Vector3();
|
225
249
|
private _propertiesChanged: boolean = false;
|
226
250
|
private _currentVelocity: THREE.Vector3 = new THREE.Vector3();
|