Skip to content

Commit

Permalink
fixed: kinematic-body physics lagged a frame behind, allowing you to …
Browse files Browse the repository at this point in the history
…walk through some bodies

Current position and velocity was synced to the physics object AFTER physics sim had been ran, allowing you to walk through some surfaces (particularly spheres and cylinders)
This now uses the new update mechanism to ensure physics bodies are synced before physics interactions are handled
  • Loading branch information
ProPuke authored and donmccurdy committed Nov 25, 2017
1 parent 7717e9d commit ba54a80
Showing 1 changed file with 18 additions and 10 deletions.
28 changes: 18 additions & 10 deletions src/misc/kinematic-body.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ module.exports = AFRAME.registerComponent('kinematic-body', {

init: function () {
this.system = this.el.sceneEl.systems.physics;
this.system.addBehavior(this, this.system.Phase.SIMULATE);
this.system.addComponent(this);

const el = this.el,
data = this.data,
Expand All @@ -64,12 +64,12 @@ module.exports = AFRAME.registerComponent('kinematic-body', {

remove: function () {
this.system.removeBody(this.body);
this.system.removeBehavior(this, this.system.Phase.SIMULATE);
this.system.removeComponent(this);
delete this.el.body;
},

/*******************************************************************
* Tick
* Update
*/

/**
Expand All @@ -82,7 +82,14 @@ module.exports = AFRAME.registerComponent('kinematic-body', {
* If in contact with two ground surfaces (e.g. ground + ramp), choose
* the one that collides with current velocity, if any.
*/
step: (function () {
updateBefore: function (t, dt) {
if (!dt) return;

this.body.velocity.copy(this.el.getAttribute('velocity'));
this.body.position.copy(this.el.getAttribute('position'));
},

updateAfter: (function () {
var velocity = new THREE.Vector3(),
normalizedVelocity = new THREE.Vector3(),
currentSurfaceNormal = new THREE.Vector3(),
Expand All @@ -95,16 +102,16 @@ module.exports = AFRAME.registerComponent('kinematic-body', {
data = this.data,
didCollide = false,
height, groundHeight = -Infinity,
groundBody;
groundBody,
contacts = this.system.getContacts();

dt = Math.min(dt, this.system.data.maxInterval * 1000);

groundNormal.set(0, 0, 0);
velocity.copy(this.el.getAttribute('velocity'));
body.velocity.copy(velocity);
body.position.copy(this.el.getAttribute('position'));

for (var i = 0, contact; (contact = this.system.world.contacts[i]); i++) {
for (var i = 0, contact; contact = contacts[i]; i++) {
// 1. Find any collisions involving this element. Get the contact
// normal, and make sure it's oriented _out_ of the other object and
// enabled (body.collisionReponse is true for both bodies)
Expand Down Expand Up @@ -152,7 +159,7 @@ module.exports = AFRAME.registerComponent('kinematic-body', {
} else {
// 5. If not in contact with anything horizontal, apply world gravity.
// TODO - Why is the 4x scalar necessary.
velocity.add(this.system.world.gravity.scale(dt * 4.0 / 1000));
velocity.add(this.system.driver.world.gravity.scale(dt * 4.0 / 1000));
}

// 6. If the ground surface has a velocity, apply it directly to current
Expand All @@ -164,11 +171,12 @@ module.exports = AFRAME.registerComponent('kinematic-body', {
y: body.position.y + groundVelocity.y * dt / 1000,
z: body.position.z + groundVelocity.z * dt / 1000
});
this.el.setAttribute('position', body.position);
}

body.velocity.copy(velocity);
this.el.setAttribute('velocity', velocity);

this.el.setAttribute('velocity', body.velocity);
this.el.setAttribute('position', body.position);
};
}()),

Expand Down

0 comments on commit ba54a80

Please sign in to comment.