My thoughts are to use a script similar to this one:
var HingeConstraint = pc.createScript('hingeConstraint');
HingeConstraint.attributes.add('partA', { type: 'entity', title: 'Part A' });
HingeConstraint.attributes.add('partB', { type: 'entity', title: 'Part B' });
HingeConstraint.attributes.add('limits', { type: 'vec2', title: 'Joint Limits (degrees)' });
HingeConstraint.attributes.add('partOrientationOffsetA', { type: 'vec3', title: 'Part A Orientation Offset (degrees)' });
HingeConstraint.attributes.add('partOrientationOffsetB', { type: 'vec3', title: 'Part B Orientation Offset (degrees)' });
HingeConstraint.attributes.add('disableCollision', { type: 'boolean', default: false, title: 'Disable Collision' });
HingeConstraint.attributes.add('debugDraw', { type: 'boolean', default: false, title: 'Debug Draw' });
HingeConstraint.prototype.initialize = function() {
this.createJoint();
this.white = new pc.Color(1, 1, 1, 1);
this.temp = new pc.Vec3();
this.on('attr:limits', function (value, prev) {
this.joint.setLimit(value.x * pc.math.DEG_TO_RAD, value.y * pc.math.DEG_TO_RAD, 0.9, 0.3, 1);
});
};
HingeConstraint.prototype.draw = function () {
this.app.renderLine(this.partA.getPosition(), this.entity.getPosition(), this.white);
this.app.renderLine(this.partB.getPosition(), this.entity.getPosition(), this.white);
};
HingeConstraint.prototype.update = function (dt) {
if (this.debugDraw) {
this.draw();
}
};
HingeConstraint.prototype.createJoint = function() {
var rbA = this.partA.rigidbody.body;
var rbB = this.partB.rigidbody.body;
// Work out offset to the parts
var offsetA = new pc.Vec3();
var matrixA = this.partA.getWorldTransform().clone();
matrixA.invert();
matrixA.transformPoint(this.entity.getPosition(), offsetA);
var offsetB = new pc.Vec3();
var matrixB = this.partB.getWorldTransform().clone();
console.log("Matrix: " + matrixB);
console.log("World Transform: " + this.partB.worldTransform);
matrixB.invert();
console.log("Inversse Matrix: " + matrixB);
matrixB.transformPoint(this.entity.getPosition(), offsetB);
var localA = new Ammo.btTransform();
var localB = new Ammo.btTransform();
localA.setIdentity();
localB.setIdentity();
var orientA = this.partOrientationOffsetA;
var orientB = this.partOrientationOffsetB;
localA.getBasis().setEulerZYX(orientA.x * pc.math.DEG_TO_RAD, orientA.y * pc.math.DEG_TO_RAD, orientA.z * pc.math.DEG_TO_RAD);
localA.setOrigin(new Ammo.btVector3(offsetA.x, offsetA.y, offsetA.z));
localB.getBasis().setEulerZYX(orientB.x * pc.math.DEG_TO_RAD, orientB.y * pc.math.DEG_TO_RAD, orientB.z * pc.math.DEG_TO_RAD);
localB.setOrigin(new Ammo.btVector3(offsetB.x, offsetB.y, offsetB.z));
this.joint = new Ammo.btHingeConstraint(rbA, rbB, localA, localB);
this.joint.setLimit(this.limits.x * pc.math.DEG_TO_RAD, this.limits.y * pc.math.DEG_TO_RAD, 0.9, 0.3, 1);
// Add joint to simulation
this.app.systems.rigidbody.dynamicsWorld.addConstraint(this.joint, this.disableCollision);
};
To create something like the spokes on a bicycle wheel between several individual rigidbodies in my scene. They would need to stay at the position they are in, but rotate around a centralized point. I know this script can create that centralized point, but after playing around with it I get the feeling the rigidbodies will not move as a single entity with this setup. I have tried using a single model with several child rigidbodies, but they don’t interact with the other object I want them to when done this way. Compounding them together seems to be the only option.