Skip to content

Commit a273ce1

Browse files
authored
Physics engine optimizations (#1997)
* Optimize kinematic body handling * Faster body to entity syncing and vice versa * Refactor linear/angularVelocity properties. * Moved deprecated constants to backwards-compatibility.js * Only update an entity's transform is the body is active * Add minimal function for updating kinematic bodies * Create specific update functions for dynamic and kinematic bodies * Only activate the body when necessary * No longer determine body type arrays every frame * Update comment about component arrays * Add JSDoc for new internal functions * Cache for loop lengths * Temp vars for arrays * Don't iterate all collision components on every update * Fix static bodies. Various tidy ups. * Simplify body creation * grey -> gray (US spelling) * Delete unused property on pc.RigidBodyComponent * Remove constraint code which is currently unused * set -> force * Unify trigger and body creation * Only update transforms of active dynamic bodies * it's -> its * Fix lint errors * Use standard deprecation warning format * Fixed function signature for _checkForCollisions * Predicate deprecation warning on DEBUG * Fix type in deprecation warning * Move syncBodyToEntity to backwards compatibility file * Reorder functions * Unify body creation and destruction code * Simplify vector creation * Fix trigger body creation * Move all update related to physics to the rigidbody component system
1 parent 56733b6 commit a273ce1

File tree

8 files changed

+318
-338
lines changed

8 files changed

+318
-338
lines changed

examples/physics/falling-shapes.html

Lines changed: 17 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -60,22 +60,17 @@
6060
}
6161

6262
// create a few materials for our objects
63-
var white = createMaterial(new pc.Color(1, 1, 1));
64-
var red = createMaterial(new pc.Color(1, 0, 0));
65-
var green = createMaterial(new pc.Color(0, 1, 0));
66-
var blue = createMaterial(new pc.Color(0, 0, 1));
67-
var yellow = createMaterial(new pc.Color(1, 1, 0));
63+
var red = createMaterial(new pc.Color(1, 0.3, 0.3));
64+
var gray = createMaterial(new pc.Color(0.7, 0.7, 0.7));
6865

6966
// *********** Create our floor *******************
7067

7168
var floor = new pc.Entity();
7269
floor.addComponent("model", {
73-
type: "box"
70+
type: "box",
71+
material: gray
7472
});
7573

76-
// make the floor white
77-
floor.model.material = white;
78-
7974
// scale it
8075
floor.setLocalScale(10, 1, 10);
8176

@@ -137,7 +132,8 @@
137132
var boxTemplate = new pc.Entity();
138133
boxTemplate.addComponent("model", {
139134
type: "box",
140-
castShadows: true
135+
castShadows: true,
136+
material: gray
141137
});
142138

143139
// ...a rigidbody component of type 'dynamic' so that it is simulated
@@ -154,16 +150,14 @@
154150
halfExtents: new pc.Vec3(0.5, 0.5, 0.5)
155151
});
156152

157-
// make the box red
158-
boxTemplate.model.material = red;
159-
160153
// Create other shapes too for variety...
161154

162155
// A sphere...
163156
var sphereTemplate = new pc.Entity();
164157
sphereTemplate.addComponent("model", {
165158
type: "sphere",
166-
castShadows: true
159+
castShadows: true,
160+
material: gray
167161
});
168162

169163
sphereTemplate.addComponent("rigidbody", {
@@ -177,15 +171,12 @@
177171
radius: 0.5
178172
});
179173

180-
181-
// make the sphere green
182-
sphereTemplate.model.material = green;
183-
184174
// A capsule...
185175
var capsuleTemplate = new pc.Entity();
186176
capsuleTemplate.addComponent("model", {
187177
type: "capsule",
188-
castShadows: true
178+
castShadows: true,
179+
material: gray
189180
});
190181

191182
capsuleTemplate.addComponent("rigidbody", {
@@ -200,15 +191,12 @@
200191
height: 2
201192
});
202193

203-
204-
// make the capsule blue
205-
capsuleTemplate.model.material = blue;
206-
207194
// A cylinder...
208195
var cylinderTemplate = new pc.Entity();
209196
cylinderTemplate.addComponent("model", {
210197
type: "cylinder",
211-
castShadows: true
198+
castShadows: true,
199+
material: gray
212200
});
213201

214202
cylinderTemplate.addComponent("rigidbody", {
@@ -223,10 +211,6 @@
223211
height: 1
224212
});
225213

226-
227-
// make the cylinder yellow
228-
cylinderTemplate.model.material = yellow;
229-
230214
// add all the templates to an array so that
231215
// we can randomly spawn them
232216
var templates = [boxTemplate, sphereTemplate, capsuleTemplate, cylinderTemplate];
@@ -263,6 +247,11 @@
263247
clone.rigidbody.teleport(pc.math.random(-1, 1), 10, pc.math.random(-1, 1));
264248
}
265249
}
250+
251+
// Show active bodies in red and frozen bodies in gray
252+
app.root.findComponents('rigidbody').forEach(function (body) {
253+
body.entity.model.material = body.isActive() ? red : gray;
254+
});
266255
});
267256
}
268257
</script>

src/backwards-compatibility.js

Lines changed: 45 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,29 @@ Object.assign(pc, function () {
1616
};
1717
}());
1818

19+
// Alias old 'enum' names
20+
Object.assign(pc, {
21+
ELEMENTTYPE_INT8: pc.TYPE_INT8,
22+
ELEMENTTYPE_UINT8: pc.TYPE_UINT8,
23+
ELEMENTTYPE_INT16: pc.TYPE_INT16,
24+
ELEMENTTYPE_UINT16: pc.TYPE_UINT16,
25+
ELEMENTTYPE_INT32: pc.TYPE_INT32,
26+
ELEMENTTYPE_UINT32: pc.TYPE_UINT32,
27+
ELEMENTTYPE_FLOAT32: pc.TYPE_FLOAT32,
28+
29+
RIGIDBODY_TYPE_STATIC: pc.BODYTYPE_STATIC,
30+
RIGIDBODY_TYPE_DYNAMIC: pc.BODYTYPE_DYNAMIC,
31+
RIGIDBODY_TYPE_KINEMATIC: pc.BODYTYPE_KINEMATIC,
32+
RIGIDBODY_CF_STATIC_OBJECT: pc.BODYFLAG_STATIC_OBJECT,
33+
RIGIDBODY_CF_KINEMATIC_OBJECT: pc.BODYFLAG_KINEMATIC_OBJECT,
34+
RIGIDBODY_CF_NORESPONSE_OBJECT: pc.BODYFLAG_NORESPONSE_OBJECT,
35+
RIGIDBODY_ACTIVE_TAG: pc.BODYSTATE_ACTIVE_TAG,
36+
RIGIDBODY_ISLAND_SLEEPING: pc.BODYSTATE_ISLAND_SLEEPING,
37+
RIGIDBODY_WANTS_DEACTIVATION: pc.BODYSTATE_WANTS_DEACTIVATION,
38+
RIGIDBODY_DISABLE_DEACTIVATION: pc.BODYSTATE_DISABLE_DEACTIVATION,
39+
RIGIDBODY_DISABLE_SIMULATION: pc.BODYSTATE_DISABLE_SIMULATION
40+
});
41+
1942
// Continue to support the old engine namespaces
2043
pc.anim = {
2144
Animation: pc.Animation,
@@ -188,14 +211,6 @@ pc.PhongMaterial = pc.StandardMaterial;
188211

189212
pc.BoundingSphere.prototype.intersectRay = pc.BoundingSphere.prototype.intersectsRay;
190213

191-
pc.ELEMENTTYPE_INT8 = pc.TYPE_INT8;
192-
pc.ELEMENTTYPE_UINT8 = pc.TYPE_UINT8;
193-
pc.ELEMENTTYPE_INT16 = pc.TYPE_INT16;
194-
pc.ELEMENTTYPE_UINT16 = pc.TYPE_UINT16;
195-
pc.ELEMENTTYPE_INT32 = pc.TYPE_INT32;
196-
pc.ELEMENTTYPE_UINT32 = pc.TYPE_UINT32;
197-
pc.ELEMENTTYPE_FLOAT32 = pc.TYPE_FLOAT32;
198-
199214
Object.defineProperty(pc.shaderChunks, "transformSkinnedVS", {
200215
get: function () {
201216
return "#define SKIN\n" + pc.shaderChunks.transformVS;
@@ -484,6 +499,28 @@ pc.Material.prototype.setShader = function (shader) {
484499
this.shader = shader;
485500
};
486501

502+
Object.defineProperty(pc.RigidBodyComponent.prototype, "bodyType", {
503+
get: function () {
504+
// #ifdef DEBUG
505+
console.warn('DEPRECATED: pc.RigidBodyComponent#bodyType is deprecated. Use pc.RigidBodyComponent#type instead.');
506+
// #endif
507+
return this.type;
508+
},
509+
set: function (type) {
510+
// #ifdef DEBUG
511+
console.warn('DEPRECATED: pc.RigidBodyComponent#bodyType is deprecated. Use pc.RigidBodyComponent#type instead.');
512+
// #endif
513+
this.type = type;
514+
}
515+
});
516+
517+
pc.RigidBodyComponent.prototype.syncBodyToEntity = function () {
518+
// #ifdef DEBUG
519+
console.warn('pc.RigidBodyComponent#syncBodyToEntity is not public API and should not be used.');
520+
// #endif
521+
this._updateDynamic();
522+
};
523+
487524
pc.RigidBodyComponentSystem.prototype.setGravity = function () {
488525
// #ifdef DEBUG
489526
console.warn('DEPRECATED: pc.RigidBodyComponentSystem#setGravity is deprecated. Use pc.RigidBodyComponentSystem#gravity instead.');

src/framework/application.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1514,7 +1514,6 @@ Object.assign(pc, function () {
15141514
onLibrariesLoaded: function () {
15151515
this._librariesLoaded = true;
15161516
this.systems.rigidbody.onLibraryLoaded();
1517-
this.systems.collision.onLibraryLoaded();
15181517
},
15191518

15201519
/**

src/framework/components/collision/component.js

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,31 @@ Object.assign(pc, function () {
231231
}
232232
},
233233

234+
_updateCompound: function () {
235+
var entity = this.entity;
236+
if (entity._dirtyWorld) {
237+
var dirty = entity._dirtyLocal;
238+
var parent = entity;
239+
while (parent && !dirty) {
240+
if (parent.collision && parent.collision === this._compoundParent)
241+
break;
242+
243+
if (parent._dirtyLocal)
244+
dirty = true;
245+
246+
parent = parent.parent;
247+
}
248+
249+
if (dirty) {
250+
entity.forEach(this.system.implementations.compound._updateEachDescendantTransform, entity);
251+
252+
var bodyComponent = this._compoundParent.entity.rigidbody;
253+
if (bodyComponent)
254+
bodyComponent.activate();
255+
}
256+
}
257+
},
258+
234259
onEnable: function () {
235260
if (this.data.type === 'mesh' && this.data.asset && this.data.initialized) {
236261
var asset = this.system.app.assets.get(this.data.asset);

src/framework/components/collision/system.js

Lines changed: 2 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ Object.assign(pc, function () {
129129

130130
updateTransform: function (component, position, rotation, scale) {
131131
if (component.entity.trigger) {
132-
component.entity.trigger.syncEntityToBody();
132+
component.entity.trigger.updateTransform();
133133
}
134134
},
135135

@@ -404,8 +404,7 @@ Object.assign(pc, function () {
404404

405405
var entityTransform = entity.getWorldTransform();
406406
var scale = entityTransform.getScale();
407-
var vec = new Ammo.btVector3();
408-
vec.setValue(scale.x, scale.y, scale.z);
407+
var vec = new Ammo.btVector3(scale.x, scale.y, scale.z);
409408
shape.setLocalScaling(vec);
410409
Ammo.destroy(vec);
411410

@@ -587,24 +586,13 @@ Object.assign(pc, function () {
587586

588587
this.on('beforeremove', this.onBeforeRemove, this);
589588
this.on('remove', this.onRemove, this);
590-
591-
pc.ComponentSystem.bind('update', this.onUpdate, this);
592589
};
593590
CollisionComponentSystem.prototype = Object.create(pc.ComponentSystem.prototype);
594591
CollisionComponentSystem.prototype.constructor = CollisionComponentSystem;
595592

596593
pc.Component._buildAccessors(pc.CollisionComponent.prototype, _schema);
597594

598595
Object.assign(CollisionComponentSystem.prototype, {
599-
onLibraryLoaded: function () {
600-
if (typeof Ammo !== 'undefined') {
601-
//
602-
} else {
603-
// Unbind the update function if we haven't loaded Ammo by now
604-
pc.ComponentSystem.unbind('update', this.onUpdate, this);
605-
}
606-
},
607-
608596
initializeComponentData: function (component, _data, properties) {
609597
properties = ['type', 'halfExtents', 'radius', 'axis', 'height', 'shape', 'model', 'asset', 'enabled'];
610598

@@ -704,43 +692,6 @@ Object.assign(pc, function () {
704692
this.implementations[data.type].remove(entity, data);
705693
},
706694

707-
onUpdate: function (dt) {
708-
var id, entity, data;
709-
var components = this.store;
710-
711-
for (id in components) {
712-
entity = components[id].entity;
713-
data = components[id].data;
714-
715-
if (data.enabled && entity.enabled) {
716-
if (! entity.rigidbody) {
717-
if (entity.collision._compoundParent && entity._dirtyWorld) {
718-
var dirty = entity._dirtyLocal;
719-
var parent = entity;
720-
while (parent && ! dirty) {
721-
if (parent.collision && parent.collision == entity.collision._compoundParent)
722-
break;
723-
724-
if (parent._dirtyLocal)
725-
dirty = true;
726-
727-
parent = parent.parent;
728-
}
729-
730-
if (dirty) {
731-
entity.forEach(this.implementations.compound._updateEachDescendantTransform, entity);
732-
733-
if (entity.collision._compoundParent.entity.rigidbody)
734-
entity.collision._compoundParent.entity.rigidbody.activate();
735-
}
736-
} else if (entity.trigger) {
737-
entity.trigger.syncEntityToBody();
738-
}
739-
}
740-
}
741-
}
742-
},
743-
744695
updateCompoundChildTransform: function (entity) {
745696
// TODO
746697
// use updateChildTransform once it is exposed in ammo.js

0 commit comments

Comments
 (0)