in world.solve
b2World.prototype.Solve = function (step) {
var b;
for (var controller = this.m_controllerList; controller; controller = controller.m_next) {
controller.Step(step);
}
var island = this.m_island;
island.Initialize(this.m_bodyCount, this.m_contactCount, this.m_jointCount, null, this.m_contactManager.m_contactListener, this.m_contactSolver);
then in island.initialize
b2Island.prototype.Initialize = function (bodyCapacity, contactCapacity, jointCapacity, allocator, listener, contactSolver) {
if (bodyCapacity === undefined) bodyCapacity = 0;
if (contactCapacity === undefined) contactCapacity = 0;
if (jointCapacity === undefined) jointCapacity = 0;
var i = 0;
this.m_bodyCapacity = bodyCapacity;
this.m_contactCapacity = contactCapacity;
this.m_jointCapacity = jointCapacity;
this.m_bodyCount = 0;
this.m_contactCount = 0;
this.m_jointCount = 0;
this.m_allocator = allocator;
this.m_listener = listener;
this.m_contactSolver = contactSolver;
for (i = this.m_bodies.length;
i < bodyCapacity; i++)
this.m_bodies[i] = null;
for (i = this.m_contacts.length;
i < contactCapacity; i++)
this.m_contacts[i] = null;
for (i = this.m_joints.length;
i < jointCapacity; i++)
this.m_joints[i] = null;
}
and in island.solve
b2Island.prototype.Solve = function (step, gravity, allowSleep) {
var i = 0;
var j = 0;
var b;
var joint;
for (i = 0;
i < this.m_bodyCount; ++i) {
b = this.m_bodies[i];
if (b.GetType() != b2Body.b2_dynamicBody) continue;
b.m_linearVelocity.x += step.dt * (gravity.x + b.m_invMass * b.m_force.x);
b.m_linearVelocity.y += step.dt * (gravity.y + b.m_invMass * b.m_force.y);
b.m_angularVelocity += step.dt * b.m_invI * b.m_torque;
b.m_linearVelocity.Multiply(b2Math.Clamp(1.0 - step.dt * b.m_linearDamping, 0.0, 1.0));
b.m_angularVelocity *= b2Math.Clamp(1.0 - step.dt * b.m_angularDamping, 0.0, 1.0);
}
this.m_contactSolver.Initialize(step, this.m_contacts, this.m_contactCount, this.m_allocator);
in contact factory
b2ContactFactory.prototype.b2ContactFactory = function (allocator) { this.m_allocator = allocator; this.InitializeRegisters(); }
and it is actually used when a contact constraint is created.
b2ContactFactory.prototype.Create = function (fixtureA, fixtureB) {
var type1 = parseInt(fixtureA.GetType());
var type2 = parseInt(fixtureB.GetType());
var reg = this.m_registers[type1][type2];
var c;
if (reg.pool) {
c = reg.pool;
reg.pool = c.m_next;
reg.poolCount--;
c.Reset(fixtureA, fixtureB);
return c;
}
var createFcn = reg.createFcn;
if (createFcn != null) {
if (reg.primary) {
c = createFcn(this.m_allocator);
c.Reset(fixtureA, fixtureB);
return c;
}
else {
c = createFcn(this.m_allocator);
c.Reset(fixtureB, fixtureA);
return c;
}
}
else {
return null;
}
}
which is in turn used by the relevant contact creation function <<<--- note allocator is passed as parameter, but is not used?
b2CircleContact.Create = function (allocator) {
return new b2CircleContact();
}
which is defined like below
Box2D.inherit(b2CircleContact, Box2D.Dynamics.Contacts.b2Contact);
b2CircleContact.prototype.__super = Box2D.Dynamics.Contacts.b2Contact.prototype;
b2CircleContact.b2CircleContact = function () {
Box2D.Dynamics.Contacts.b2Contact.b2Contact.apply(this, arguments);
};
inheriting property of b3Contact
b2Contact.b2Contact = function () {
this.m_nodeA = new b2ContactEdge();
this.m_nodeB = new b2ContactEdge();
this.m_manifold = new b2Manifold();
this.m_oldManifold = new b2Manifold();
};
and referred to when the contact constraint is solved
b2ContactSolver.prototype.Initialize = function (step, contacts, contactCount, allocator) {
if (contactCount === undefined) contactCount = 0;
var contact;
this.m_step.Set(step);
this.m_allocator = allocator;
var i = 0;
var tVec;
var tMat;
this.m_constraintCount = contactCount;
while (this.m_constraints.length < this.m_constraintCount) {
this.m_constraints[this.m_constraints.length] = new b2ContactConstraint();
}
for (i = 0;
i < contactCount; ++i) {
contact = contacts[i];
var fixtureA = contact.m_fixtureA;
var fixtureB = contact.m_fixtureB;
var shapeA = fixtureA.m_shape;
var shapeB = fixtureB.m_shape;
var radiusA = shapeA.m_radius;
var radiusB = shapeB.m_radius;
var bodyA = fixtureA.m_body;
var bodyB = fixtureB.m_body;
var manifold = contact.GetManifold();
var friction = b2Settings.b2MixFriction(fixtureA.GetFriction(), fixtureB.GetFriction());
var restitution = b2Settings.b2MixRestitution(fixtureA.GetRestitution(), fixtureB.GetRestitution());
var vAX = bodyA.m_linearVelocity.x;
var vAY = bodyA.m_linearVelocity.y;
var vBX = bodyB.m_linearVelocity.x;
var vBY = bodyB.m_linearVelocity.y;
var wA = bodyA.m_angularVelocity;
var wB = bodyB.m_angularVelocity;
b2Settings.b2Assert(manifold.m_pointCount > 0);
b2ContactSolver.s_worldManifold.Initialize(manifold, bodyA.m_xf, radiusA, bodyB.m_xf, radiusB);
var normalX = b2ContactSolver.s_worldManifold.m_normal.x;
var normalY = b2ContactSolver.s_worldManifold.m_normal.y;
var cc = this.m_constraints[i];
cc.bodyA = bodyA;
cc.bodyB = bodyB;
cc.manifold = manifold;
cc.normal.x = normalX;
cc.normal.y = normalY;
cc.pointCount = manifold.m_pointCount;
cc.friction = friction;
cc.restitution = restitution;
cc.localPlaneNormal.x = manifold.m_localPlaneNormal.x;
cc.localPlaneNormal.y = manifold.m_localPlaneNormal.y;
cc.localPoint.x = manifold.m_localPoint.x;
cc.localPoint.y = manifold.m_localPoint.y;
cc.radius = radiusA + radiusB;
cc.type = manifold.m_type;
for (var k = 0; k < cc.pointCount; ++k) {
var cp = manifold.m_points[k];
var ccp = cc.points[k];
ccp.normalImpulse = cp.m_normalImpulse;
ccp.tangentImpulse = cp.m_tangentImpulse;
ccp.localPoint.SetV(cp.m_localPoint);
var rAX = ccp.rA.x = b2ContactSolver.s_worldManifold.m_points[k].x - bodyA.m_sweep.c.x;
var rAY = ccp.rA.y = b2ContactSolver.s_worldManifold.m_points[k].y - bodyA.m_sweep.c.y;
var rBX = ccp.rB.x = b2ContactSolver.s_worldManifold.m_points[k].x - bodyB.m_sweep.c.x;
var rBY = ccp.rB.y = b2ContactSolver.s_worldManifold.m_points[k].y - bodyB.m_sweep.c.y;
var rnA = rAX * normalY - rAY * normalX;
var rnB = rBX * normalY - rBY * normalX;
rnA *= rnA;
rnB *= rnB;
var kNormal = bodyA.m_invMass + bodyB.m_invMass + bodyA.m_invI * rnA + bodyB.m_invI * rnB;
ccp.normalMass = 1.0 / kNormal;
var kEqualized = bodyA.m_mass * bodyA.m_invMass + bodyB.m_mass * bodyB.m_invMass;
kEqualized += bodyA.m_mass * bodyA.m_invI * rnA + bodyB.m_mass * bodyB.m_invI * rnB;
ccp.equalizedMass = 1.0 / kEqualized;
var tangentX = normalY;
var tangentY = (-normalX);
var rtA = rAX * tangentY - rAY * tangentX;
var rtB = rBX * tangentY - rBY * tangentX;
rtA *= rtA;
rtB *= rtB;
var kTangent = bodyA.m_invMass + bodyB.m_invMass + bodyA.m_invI * rtA + bodyB.m_invI * rtB;
ccp.tangentMass = 1.0 / kTangent;
ccp.velocityBias = 0.0;
var tX = vBX + ((-wB * rBY)) - vAX - ((-wA * rAY));
var tY = vBY + (wB * rBX) - vAY - (wA * rAX);
var vRel = cc.normal.x * tX + cc.normal.y * tY;
if (vRel < (-b2Settings.b2_velocityThreshold)) {
ccp.velocityBias += (-cc.restitution * vRel);
}
}
if (cc.pointCount == 2) {
var ccp1 = cc.points[0];
var ccp2 = cc.points[1];
var invMassA = bodyA.m_invMass;
var invIA = bodyA.m_invI;
var invMassB = bodyB.m_invMass;
var invIB = bodyB.m_invI;
var rn1A = ccp1.rA.x * normalY - ccp1.rA.y * normalX;
var rn1B = ccp1.rB.x * normalY - ccp1.rB.y * normalX;
var rn2A = ccp2.rA.x * normalY - ccp2.rA.y * normalX;
var rn2B = ccp2.rB.x * normalY - ccp2.rB.y * normalX;
var k11 = invMassA + invMassB + invIA * rn1A * rn1A + invIB * rn1B * rn1B;
var k22 = invMassA + invMassB + invIA * rn2A * rn2A + invIB * rn2B * rn2B;
var k12 = invMassA + invMassB + invIA * rn1A * rn2A + invIB * rn1B * rn2B;
var k_maxConditionNumber = 100.0;
if (k11 * k11 < k_maxConditionNumber * (k11 * k22 - k12 * k12)) {
cc.K.col1.Set(k11, k12);
cc.K.col2.Set(k12, k22);
cc.K.GetInverse(cc.normalMass);
}
else {
cc.pointCount = 1;
}
}
}
}
the contact factory is created by the contact manager when instantiated.
b2ContactManager.prototype.b2ContactManager = function () {
this.m_world = null;
this.m_contactCount = 0;
this.m_contactFilter = b2ContactFilter.b2_defaultFilter;
this.m_contactListener = b2ContactListener.b2_defaultListener;
this.m_contactFactory = new b2ContactFactory(this.m_allocator);
this.m_broadPhase = new b2DynamicTreeBroadPhase();
}
in summary, property m_allocator is defined by:
contact factory
b2ContactFactory.prototype.b2ContactFactory = function (allocator) {
this.m_allocator = allocator;
this.InitializeRegisters();
}
2. contact solver
b2ContactSolver.prototype.Initialize = function (step, contacts, contactCount, allocator) {
if (contactCount === undefined) contactCount = 0;
var contact;
this.m_step.Set(step);
this.m_allocator = allocator;
3. island
b2Island.prototype.Initialize = function (bodyCapacity, contactCapacity, jointCapacity, allocator, listener, contactSolver) { if (bodyCapacity === undefined) bodyCapacity = 0; if (contactCapacity === undefined) contactCapacity = 0; if (jointCapacity === undefined) jointCapacity = 0; var i = 0; this.m_bodyCapacity = bodyCapacity; this.m_contactCapacity = contactCapacity; this.m_jointCapacity = jointCapacity; this.m_bodyCount = 0; this.m_contactCount = 0; this.m_jointCount = 0; this.m_allocator = allocator;
as far as I can see, not used by any other class
Σχόλια