mirror of
https://github.com/logsol/chuck.js.git
synced 2026-05-11 10:37:34 +00:00
changed linear interpolation to nearest and added rube ragdoll with testbed in lab
This commit is contained in:
parent
47bb5ef147
commit
86063661db
28 changed files with 31671 additions and 2 deletions
416
lab/rube/js/loadrube.js
Normal file
416
lab/rube/js/loadrube.js
Normal file
|
|
@ -0,0 +1,416 @@
|
|||
|
||||
Object.prototype.hasOwnProperty = function(property) {
|
||||
return typeof(this[property]) !== 'undefined'
|
||||
};
|
||||
|
||||
function loadBodyFromRUBE(bodyJso, world) {
|
||||
//console.log(bodyJso);
|
||||
|
||||
if ( ! bodyJso.hasOwnProperty('type') ) {
|
||||
console.log("Body does not have a 'type' property");
|
||||
return null;
|
||||
}
|
||||
|
||||
var bd = new b2BodyDef();
|
||||
if ( bodyJso.type == 2 )
|
||||
bd.type = b2_dynamicBody;
|
||||
else if ( bodyJso.type == 1 )
|
||||
bd.type = b2_kinematicBody;
|
||||
if ( bodyJso.hasOwnProperty('angle') )
|
||||
bd.angle = bodyJso.angle;
|
||||
if ( bodyJso.hasOwnProperty('angularVelocity') )
|
||||
bd.angularVelocity = bodyJso.angularVelocity;
|
||||
if ( bodyJso.hasOwnProperty('active') )
|
||||
bd.awake = bodyJso.active;
|
||||
if ( bodyJso.hasOwnProperty('fixedRotation') )
|
||||
bd.fixedRotation = bodyJso.fixedRotation;
|
||||
if ( bodyJso.hasOwnProperty('linearVelocity') && bodyJso.linearVelocity instanceof Object )
|
||||
bd.linearVelocity.SetV( bodyJso.linearVelocity );
|
||||
if ( bodyJso.hasOwnProperty('position') && bodyJso.position instanceof Object )
|
||||
bd.position.SetV( bodyJso.position );
|
||||
if ( bodyJso.hasOwnProperty('awake') )
|
||||
bd.awake = bodyJso.awake;
|
||||
else
|
||||
bd.awake = false;
|
||||
var body = world.CreateBody(bd);
|
||||
if ( bodyJso.hasOwnProperty('fixture') ) {
|
||||
for (k = 0; k < bodyJso['fixture'].length; k++) {
|
||||
var fixtureJso = bodyJso['fixture'][k];
|
||||
loadFixtureFromRUBE(body, fixtureJso);
|
||||
}
|
||||
}
|
||||
if ( bodyJso.hasOwnProperty('name') )
|
||||
body.name = bodyJso.name;
|
||||
if ( bodyJso.hasOwnProperty('customProperties') )
|
||||
body.customProperties = bodyJso.customProperties;
|
||||
return body;
|
||||
}
|
||||
|
||||
function loadFixtureFromRUBE(body, fixtureJso) {
|
||||
//console.log(fixtureJso);
|
||||
var fd = new b2FixtureDef();
|
||||
if (fixtureJso.hasOwnProperty('friction'))
|
||||
fd.friction = fixtureJso.friction;
|
||||
if (fixtureJso.hasOwnProperty('density'))
|
||||
fd.density = fixtureJso.density;
|
||||
if (fixtureJso.hasOwnProperty('restitution'))
|
||||
fd.restitution = fixtureJso.restitution;
|
||||
if (fixtureJso.hasOwnProperty('sensor'))
|
||||
fd.isSensor = fixtureJso.sensor;
|
||||
if ( fixtureJso.hasOwnProperty('filter-categoryBits') )
|
||||
fd.filter.categoryBits = fixtureJso['filter-categoryBits'];
|
||||
if ( fixtureJso.hasOwnProperty('filter-maskBits') )
|
||||
fd.filter.maskBits = fixtureJso['filter-maskBits'];
|
||||
if ( fixtureJso.hasOwnProperty('filter-groupIndex') )
|
||||
fd.filter.groupIndex = fixtureJso['filter-groupIndex'];
|
||||
if (fixtureJso.hasOwnProperty('circle')) {
|
||||
fd.shape = new b2CircleShape();
|
||||
fd.shape.m_radius = fixtureJso.circle.radius;
|
||||
if ( fixtureJso.circle.center )
|
||||
fd.shape.m_p.SetV(fixtureJso.circle.center);
|
||||
var fixture = body.CreateFixture(fd);
|
||||
if ( fixtureJso.name )
|
||||
fixture.name = fixtureJso.name;
|
||||
}
|
||||
else if (fixtureJso.hasOwnProperty('polygon')) {
|
||||
fd.shape = new b2PolygonShape();
|
||||
var verts = [];
|
||||
for (v = 0; v < fixtureJso.polygon.vertices.x.length; v++)
|
||||
verts.push( new b2Vec2( fixtureJso.polygon.vertices.x[v], fixtureJso.polygon.vertices.y[v] ) );
|
||||
fd.shape.SetAsArray(verts, verts.length);
|
||||
var fixture = body.CreateFixture(fd);
|
||||
if ( fixture && fixtureJso.name )
|
||||
fixture.name = fixtureJso.name;
|
||||
}
|
||||
else if (fixtureJso.hasOwnProperty('chain')) {
|
||||
fd.shape = new b2PolygonShape();
|
||||
var lastVertex = new b2Vec2();
|
||||
for (v = 0; v < fixtureJso.chain.vertices.x.length; v++) {
|
||||
var thisVertex = new b2Vec2( fixtureJso.chain.vertices.x[v], fixtureJso.chain.vertices.y[v] );
|
||||
if ( v > 0 ) {
|
||||
fd.shape.SetAsEdge( lastVertex, thisVertex );
|
||||
var fixture = body.CreateFixture(fd);
|
||||
if ( fixtureJso.name )
|
||||
fixture.name = fixtureJso.name;
|
||||
}
|
||||
lastVertex = thisVertex;
|
||||
}
|
||||
}
|
||||
else {
|
||||
console.log("Could not find shape type for fixture");
|
||||
}
|
||||
}
|
||||
|
||||
function getVectorValue(val) {
|
||||
if ( val instanceof Object )
|
||||
return val;
|
||||
else
|
||||
return { x:0, y:0 };
|
||||
}
|
||||
|
||||
function loadJointCommonProperties(jd, jointJso, loadedBodies) {
|
||||
jd.bodyA = loadedBodies[jointJso.bodyA];
|
||||
jd.bodyB = loadedBodies[jointJso.bodyB];
|
||||
jd.localAnchorA.SetV( getVectorValue(jointJso.anchorA) );
|
||||
jd.localAnchorB.SetV( getVectorValue(jointJso.anchorB) );
|
||||
if ( jointJso.collideConnected )
|
||||
jd.collideConnected = jointJso.collideConnected;
|
||||
}
|
||||
|
||||
function loadJointFromRUBE(jointJso, world, loadedBodies)
|
||||
{
|
||||
if ( ! jointJso.hasOwnProperty('type') ) {
|
||||
console.log("Joint does not have a 'type' property");
|
||||
return null;
|
||||
}
|
||||
if ( jointJso.bodyA >= loadedBodies.length ) {
|
||||
console.log("Index for bodyA is invalid: " + jointJso.bodyA );
|
||||
return null;
|
||||
}
|
||||
if ( jointJso.bodyB >= loadedBodies.length ) {
|
||||
console.log("Index for bodyB is invalid: " + jointJso.bodyB );
|
||||
return null;
|
||||
}
|
||||
|
||||
var joint = null;
|
||||
if ( jointJso.type == "revolute" ) {
|
||||
var jd = new b2RevoluteJointDef();
|
||||
loadJointCommonProperties(jd, jointJso, loadedBodies);
|
||||
if ( jointJso.hasOwnProperty('refAngle') )
|
||||
jd.referenceAngle = jointJso.refAngle;
|
||||
if ( jointJso.hasOwnProperty('lowerLimit') )
|
||||
jd.lowerAngle = jointJso.lowerLimit;
|
||||
if ( jointJso.hasOwnProperty('upperLimit') )
|
||||
jd.upperAngle = jointJso.upperLimit;
|
||||
if ( jointJso.hasOwnProperty('maxMotorTorque') )
|
||||
jd.maxMotorTorque = jointJso.maxMotorTorque;
|
||||
if ( jointJso.hasOwnProperty('motorSpeed') )
|
||||
jd.motorSpeed = jointJso.motorSpeed;
|
||||
if ( jointJso.hasOwnProperty('enableLimit') )
|
||||
jd.enableLimit = jointJso.enableLimit;
|
||||
if ( jointJso.hasOwnProperty('enableMotor') )
|
||||
jd.enableMotor = jointJso.enableMotor;
|
||||
joint = world.CreateJoint(jd);
|
||||
}
|
||||
else if ( jointJso.type == "distance" || jointJso.type == "rope" ) {
|
||||
if ( jointJso.type == "rope" )
|
||||
console.log("Replacing unsupported rope joint with distance joint!");
|
||||
var jd = new b2DistanceJointDef();
|
||||
loadJointCommonProperties(jd, jointJso, loadedBodies);
|
||||
if ( jointJso.hasOwnProperty('length') )
|
||||
jd.length = jointJso.length;
|
||||
if ( jointJso.hasOwnProperty('dampingRatio') )
|
||||
jd.dampingRatio = jointJso.dampingRatio;
|
||||
if ( jointJso.hasOwnProperty('frequency') )
|
||||
jd.frequencyHz = jointJso.frequency;
|
||||
joint = world.CreateJoint(jd);
|
||||
}
|
||||
else if ( jointJso.type == "prismatic" ) {
|
||||
var jd = new b2PrismaticJointDef();
|
||||
loadJointCommonProperties(jd, jointJso, loadedBodies);
|
||||
if ( jointJso.hasOwnProperty('localAxisA') )
|
||||
jd.localAxisA.SetV( getVectorValue(jointJso.localAxisA) );
|
||||
if ( jointJso.hasOwnProperty('refAngle') )
|
||||
jd.referenceAngle = jointJso.refAngle;
|
||||
if ( jointJso.hasOwnProperty('enableLimit') )
|
||||
jd.enableLimit = jointJso.enableLimit;
|
||||
if ( jointJso.hasOwnProperty('lowerLimit') )
|
||||
jd.lowerTranslation = jointJso.lowerLimit;
|
||||
if ( jointJso.hasOwnProperty('upperLimit') )
|
||||
jd.upperTranslation = jointJso.upperLimit;
|
||||
if ( jointJso.hasOwnProperty('enableMotor') )
|
||||
jd.enableMotor = jointJso.enableMotor;
|
||||
if ( jointJso.hasOwnProperty('maxMotorForce') )
|
||||
jd.maxMotorForce = jointJso.maxMotorForce;
|
||||
if ( jointJso.hasOwnProperty('motorSpeed') )
|
||||
jd.motorSpeed = jointJso.motorSpeed;
|
||||
joint = world.CreateJoint(jd);
|
||||
}
|
||||
else if ( jointJso.type == "wheel" ) {
|
||||
//Make a fake wheel joint using a line joint and a distance joint.
|
||||
//Return the line joint because it has the linear motor controls.
|
||||
//Use ApplyTorque on the bodies to spin the wheel...
|
||||
|
||||
var jd = new b2DistanceJointDef();
|
||||
loadJointCommonProperties(jd, jointJso, loadedBodies);
|
||||
jd.length = 0.0;
|
||||
if ( jointJso.hasOwnProperty('springDampingRatio') )
|
||||
jd.dampingRatio = jointJso.springDampingRatio;
|
||||
if ( jointJso.hasOwnProperty('springFrequency') )
|
||||
jd.frequencyHz = jointJso.springFrequency;
|
||||
world.CreateJoint(jd);
|
||||
|
||||
jd = new b2LineJointDef();
|
||||
loadJointCommonProperties(jd, jointJso, loadedBodies);
|
||||
if ( jointJso.hasOwnProperty('localAxisA') )
|
||||
jd.localAxisA.SetV( getVectorValue(jointJso.localAxisA) );
|
||||
|
||||
joint = world.CreateJoint(jd);
|
||||
}
|
||||
else if ( jointJso.type == "friction" ) {
|
||||
var jd = new b2FrictionJointDef();
|
||||
loadJointCommonProperties(jd, jointJso, loadedBodies);
|
||||
if ( jointJso.hasOwnProperty('maxForce') )
|
||||
jd.maxForce = jointJso.maxForce;
|
||||
if ( jointJso.hasOwnProperty('maxTorque') )
|
||||
jd.maxTorque = jointJso.maxTorque;
|
||||
joint = world.CreateJoint(jd);
|
||||
}
|
||||
else if ( jointJso.type == "weld" ) {
|
||||
var jd = new b2WeldJointDef();
|
||||
loadJointCommonProperties(jd, jointJso, loadedBodies);
|
||||
if ( jointJso.hasOwnProperty('referenceAngle') )
|
||||
jd.referenceAngle = jointJso.referenceAngle;
|
||||
joint = world.CreateJoint(jd);
|
||||
}
|
||||
else {
|
||||
console.log("Unsupported joint type: " + jointJso.type);
|
||||
console.log(jointJso);
|
||||
}
|
||||
if ( joint && jointJso.name )
|
||||
joint.name = jointJso.name;
|
||||
return joint;
|
||||
}
|
||||
|
||||
function makeClone(obj) {
|
||||
var newObj = (obj instanceof Array) ? [] : {};
|
||||
for (var i in obj) {
|
||||
if (obj[i] && typeof obj[i] == "object")
|
||||
newObj[i] = makeClone(obj[i]);
|
||||
else
|
||||
newObj[i] = obj[i];
|
||||
}
|
||||
return newObj;
|
||||
};
|
||||
|
||||
function loadImageFromRUBE(imageJso, world, loadedBodies)
|
||||
{
|
||||
var image = makeClone(imageJso);
|
||||
|
||||
if ( image.hasOwnProperty('body') && image.body >= 0 )
|
||||
image.body = loadedBodies[image.body];//change index to the actual body
|
||||
else
|
||||
image.body = null;
|
||||
|
||||
image.center = new b2Vec2();
|
||||
image.center.SetV( getVectorValue(imageJso.center) );
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//mainly just a convenience for the testbed - uses global 'world' variable
|
||||
function loadSceneFromRUBE(worldJso) {
|
||||
return loadSceneIntoWorld(worldJso, world);
|
||||
}
|
||||
|
||||
//load the scene into an already existing world variable
|
||||
function loadSceneIntoWorld(worldJso, world) {
|
||||
var success = true;
|
||||
|
||||
var loadedBodies = [];
|
||||
if ( worldJso.hasOwnProperty('body') ) {
|
||||
for (var i = 0; i < worldJso.body.length; i++) {
|
||||
var bodyJso = worldJso.body[i];
|
||||
var body = loadBodyFromRUBE(bodyJso, world);
|
||||
if ( body )
|
||||
loadedBodies.push( body );
|
||||
else
|
||||
success = false;
|
||||
}
|
||||
}
|
||||
|
||||
var loadedJoints = [];
|
||||
if ( worldJso.hasOwnProperty('joint') ) {
|
||||
for (var i = 0; i < worldJso.joint.length; i++) {
|
||||
var jointJso = worldJso.joint[i];
|
||||
var joint = loadJointFromRUBE(jointJso, world, loadedBodies);
|
||||
if ( joint )
|
||||
loadedJoints.push( joint );
|
||||
//else
|
||||
// success = false;
|
||||
}
|
||||
}
|
||||
|
||||
var loadedImages = [];
|
||||
if ( worldJso.hasOwnProperty('image') ) {
|
||||
for (var i = 0; i < worldJso.image.length; i++) {
|
||||
var imageJso = worldJso.image[i];
|
||||
var image = loadImageFromRUBE(imageJso, world, loadedBodies);
|
||||
if ( image )
|
||||
loadedImages.push( image );
|
||||
else
|
||||
success = false;
|
||||
}
|
||||
world.images = loadedImages;
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
//create a world variable and return it if loading succeeds
|
||||
function loadWorldFromRUBE(worldJso) {
|
||||
var gravity = new b2Vec2(0,0);
|
||||
if ( worldJso.hasOwnProperty('gravity') && worldJso.gravity instanceof Object )
|
||||
gravity.SetV( worldJso.gravity );
|
||||
var world = new b2World( gravity );
|
||||
if ( ! loadSceneIntoWorld(worldJso, world) )
|
||||
return false;
|
||||
return world;
|
||||
}
|
||||
|
||||
function getNamedBodies(world, name) {
|
||||
var bodies = [];
|
||||
for (b = world.m_bodyList; b; b = b.m_next) {
|
||||
if ( b.name == name )
|
||||
bodies.push(b);
|
||||
}
|
||||
return bodies;
|
||||
}
|
||||
|
||||
function getNamedFixtures(world, name) {
|
||||
var fixtures = [];
|
||||
for (b = world.m_bodyList; b; b = b.m_next) {
|
||||
for (f = b.m_fixtureList; f; f = f.m_next) {
|
||||
if ( f.name == name )
|
||||
fixtures.push(f);
|
||||
}
|
||||
}
|
||||
return fixtures;
|
||||
}
|
||||
|
||||
function getNamedJoints(world, name) {
|
||||
var joints = [];
|
||||
for (j = world.m_jointList; j; j = j.m_next) {
|
||||
if ( j.name == name )
|
||||
joints.push(j);
|
||||
}
|
||||
return joints;
|
||||
}
|
||||
|
||||
function getNamedImages(world, name) {
|
||||
var images = [];
|
||||
for (i = 0; i < world.images.length; i++) {
|
||||
if ( world.images[i].name == name )
|
||||
images.push(world.images[i].name);
|
||||
}
|
||||
return images;
|
||||
}
|
||||
|
||||
//custom properties
|
||||
function getBodiesByCustomProperty(world, propertyType, propertyName, valueToMatch) {
|
||||
var bodies = [];
|
||||
for (b = world.m_bodyList; b; b = b.m_next) {
|
||||
if ( ! b.hasOwnProperty('customProperties') )
|
||||
continue;
|
||||
for (var i = 0; i < b.customProperties.length; i++) {
|
||||
if ( ! b.customProperties[i].hasOwnProperty("name") )
|
||||
continue;
|
||||
if ( ! b.customProperties[i].hasOwnProperty(propertyType) )
|
||||
continue;
|
||||
if ( b.customProperties[i].name == propertyName &&
|
||||
b.customProperties[i][propertyType] == valueToMatch)
|
||||
bodies.push(b);
|
||||
}
|
||||
}
|
||||
return bodies;
|
||||
}
|
||||
|
||||
function hasCustomProperty(item, propertyType, propertyName) {
|
||||
if ( !item.hasOwnProperty('customProperties') )
|
||||
return false;
|
||||
for (var i = 0; i < item.customProperties.length; i++) {
|
||||
if ( ! item.customProperties[i].hasOwnProperty("name") )
|
||||
continue;
|
||||
if ( ! item.customProperties[i].hasOwnProperty(propertyType) )
|
||||
continue;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function getCustomProperty(item, propertyType, propertyName, defaultValue) {
|
||||
if ( !item.hasOwnProperty('customProperties') )
|
||||
return defaultValue;
|
||||
for (var i = 0; i < item.customProperties.length; i++) {
|
||||
if ( ! item.customProperties[i].hasOwnProperty("name") )
|
||||
continue;
|
||||
if ( ! item.customProperties[i].hasOwnProperty(propertyType) )
|
||||
continue;
|
||||
if ( item.customProperties[i].name == propertyName )
|
||||
return item.customProperties[i][propertyType];
|
||||
}
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue