mirror of
https://github.com/liabru/matter-js.git
synced 2024-11-23 09:26:51 -05:00
fixed constraint torque calculation
This commit is contained in:
parent
b6e597378e
commit
a8d1950148
1 changed files with 15 additions and 49 deletions
|
@ -24,6 +24,7 @@ var Common = require('../core/Common');
|
||||||
var _zeroVector = { x: 0, y: 0 };
|
var _zeroVector = { x: 0, y: 0 };
|
||||||
|
|
||||||
Constraint._warming = 0.4;
|
Constraint._warming = 0.4;
|
||||||
|
Constraint._torqueDampen = 0.8;
|
||||||
Constraint._minLength = 0.000001;
|
Constraint._minLength = 0.000001;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -120,6 +121,9 @@ var Common = require('../core/Common');
|
||||||
pointA = constraint.pointA,
|
pointA = constraint.pointA,
|
||||||
pointB = constraint.pointB;
|
pointB = constraint.pointB;
|
||||||
|
|
||||||
|
if (!bodyA && !bodyB)
|
||||||
|
return;
|
||||||
|
|
||||||
// update reference angle
|
// update reference angle
|
||||||
if (bodyA && !bodyA.isStatic) {
|
if (bodyA && !bodyA.isStatic) {
|
||||||
Vector.rotate(pointA, bodyA.angle - constraint.angleA, pointA);
|
Vector.rotate(pointA, bodyA.angle - constraint.angleA, pointA);
|
||||||
|
@ -141,58 +145,24 @@ var Common = require('../core/Common');
|
||||||
if (!pointAWorld || !pointBWorld)
|
if (!pointAWorld || !pointBWorld)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var velocityPointA = _zeroVector,
|
|
||||||
velocityPointB = _zeroVector;
|
|
||||||
|
|
||||||
if (bodyA && !bodyA.isStatic) {
|
|
||||||
// update velocity
|
|
||||||
bodyA.velocity.x = bodyA.position.x - bodyA.positionPrev.x;
|
|
||||||
bodyA.velocity.y = bodyA.position.y - bodyA.positionPrev.y;
|
|
||||||
bodyA.angularVelocity = bodyA.angle - bodyA.anglePrev;
|
|
||||||
|
|
||||||
// find point velocity and body mass
|
|
||||||
velocityPointA = Vector.add(bodyA.velocity, Vector.mult(Vector.perp(pointA), bodyA.angularVelocity));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bodyB && !bodyB.isStatic) {
|
|
||||||
// update velocity
|
|
||||||
bodyB.velocity.x = bodyB.position.x - bodyB.positionPrev.x;
|
|
||||||
bodyB.velocity.y = bodyB.position.y - bodyB.positionPrev.y;
|
|
||||||
bodyB.angularVelocity = bodyB.angle - bodyB.anglePrev;
|
|
||||||
|
|
||||||
// find point velocity and body mass
|
|
||||||
velocityPointB = Vector.add(bodyB.velocity, Vector.mult(Vector.perp(pointB), bodyB.angularVelocity));
|
|
||||||
}
|
|
||||||
|
|
||||||
var delta = Vector.sub(pointAWorld, pointBWorld),
|
var delta = Vector.sub(pointAWorld, pointBWorld),
|
||||||
currentLength = Vector.magnitude(delta);
|
currentLength = Vector.magnitude(delta);
|
||||||
|
|
||||||
// prevent singularity
|
// prevent singularity
|
||||||
if (currentLength === 0) {
|
if (currentLength < Constraint._minLength) {
|
||||||
currentLength = Constraint._minLength;
|
currentLength = Constraint._minLength;
|
||||||
delta.x = Constraint._minLength;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// solve distance constraint with Gauss-Siedel method
|
// solve distance constraint with Gauss-Siedel method
|
||||||
var difference = (currentLength - constraint.length) / currentLength,
|
var difference = (currentLength - constraint.length) / currentLength,
|
||||||
normal = Vector.div(delta, currentLength),
|
stiffness = constraint.stiffness < 1 ? constraint.stiffness * timeScale : constraint.stiffness,
|
||||||
force = Vector.mult(delta, difference * constraint.stiffness * timeScale * timeScale),
|
force = Vector.mult(delta, difference * stiffness),
|
||||||
relativeVelocity = Vector.sub(velocityPointB, velocityPointA),
|
|
||||||
massTotal = (bodyA ? bodyA.inverseMass : 0) + (bodyB ? bodyB.inverseMass : 0),
|
massTotal = (bodyA ? bodyA.inverseMass : 0) + (bodyB ? bodyB.inverseMass : 0),
|
||||||
inertiaTotal = (bodyA ? bodyA.inverseInertia : 0) + (bodyB ? bodyB.inverseInertia : 0),
|
inertiaTotal = (bodyA ? bodyA.inverseInertia : 0) + (bodyB ? bodyB.inverseInertia : 0),
|
||||||
resistanceTotal = massTotal + inertiaTotal,
|
resistanceTotal = massTotal + inertiaTotal,
|
||||||
normalImpulse = Vector.dot(normal, relativeVelocity) / resistanceTotal,
|
|
||||||
normalVelocity,
|
|
||||||
torque,
|
torque,
|
||||||
share;
|
share;
|
||||||
|
|
||||||
if (normalImpulse < 0 && constraint.angularStiffness < 1) {
|
|
||||||
normalVelocity = {
|
|
||||||
x: normal.x * normalImpulse,
|
|
||||||
y: normal.y * normalImpulse
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bodyA && !bodyA.isStatic) {
|
if (bodyA && !bodyA.isStatic) {
|
||||||
share = bodyA.inverseMass / massTotal;
|
share = bodyA.inverseMass / massTotal;
|
||||||
|
|
||||||
|
@ -204,12 +174,10 @@ var Common = require('../core/Common');
|
||||||
bodyA.position.x -= force.x * share;
|
bodyA.position.x -= force.x * share;
|
||||||
bodyA.position.y -= force.y * share;
|
bodyA.position.y -= force.y * share;
|
||||||
|
|
||||||
if (normalVelocity) {
|
// apply torque
|
||||||
share = (bodyA.inverseInertia + bodyA.inverseMass) / resistanceTotal;
|
torque = (Vector.cross(pointA, force) / resistanceTotal) * Constraint._torqueDampen * bodyA.inverseInertia;
|
||||||
torque = Vector.cross(pointA, normalVelocity) * share * bodyA.inverseInertia * constraint.stiffness * (1 - constraint.angularStiffness);
|
bodyA.constraintImpulse.angle -= torque;
|
||||||
bodyA.constraintImpulse.angle += torque;
|
bodyA.angle -= torque;
|
||||||
bodyA.angle += torque;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bodyB && !bodyB.isStatic) {
|
if (bodyB && !bodyB.isStatic) {
|
||||||
|
@ -223,12 +191,10 @@ var Common = require('../core/Common');
|
||||||
bodyB.position.x += force.x * share;
|
bodyB.position.x += force.x * share;
|
||||||
bodyB.position.y += force.y * share;
|
bodyB.position.y += force.y * share;
|
||||||
|
|
||||||
if (normalVelocity) {
|
// apply torque
|
||||||
share = (bodyB.inverseInertia + bodyB.inverseMass) / resistanceTotal;
|
torque = (Vector.cross(pointB, force) / resistanceTotal) * Constraint._torqueDampen * bodyB.inverseInertia;
|
||||||
torque = Vector.cross(pointB, normalVelocity) * share * bodyB.inverseInertia * constraint.stiffness * (1 - constraint.angularStiffness);
|
bodyB.constraintImpulse.angle += torque;
|
||||||
bodyB.constraintImpulse.angle -= torque;
|
bodyB.angle += torque;
|
||||||
bodyB.angle -= torque;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue