var Hinge6dof = pc.createScript('hinge6dof');
Hinge6dof.attributes.add('slot', {
type: 'entity'
});
Hinge6dof.attributes.add('base', {
type: 'entity'
});
Hinge6dof.attributes.add('linearLowerLimits', {
title: 'Linear Lower Limits',
description: 'Linear limits of the constraint.',
type: 'vec3',
default: [-1, -1, -1]
});
Hinge6dof.attributes.add('linearUpperLimits', {
title: 'Linear Upper Limits',
description: 'Linear limits of the constraint.',
type: 'vec3',
default: [1, 1, 1]
});
Hinge6dof.attributes.add('angularLowerLimits', {
title: 'Angula Lower Limits',
description: 'Angular limits of the constraint.',
type: 'vec3',
default: [-1, -1, -1]
});
Hinge6dof.attributes.add('angularUpperLimits', {
title: 'Angular Upper Limits',
description: 'Angular limits of the constraint.',
type: 'vec3',
default: [1, 1, 1]
});
Hinge6dof.attributes.add('breakingThreshold', {
title: 'Break Threshold',
description: 'Maximum breaking impulse threshold required to break the constraint.',
type: 'number',
default: 1e+30
});
Hinge6dof.attributes.add('enableCollision', {
title: 'Enable Collision',
description: 'Enable collision between linked rigid bodies.',
type: 'boolean',
default: true
});
Hinge6dof.prototype.initialize = function () {
this.WorkSpaceBVH = pc.WorkSpace.script.workSpaceBvh;
this.constraint = null;
this.entity.hasOptions = true;
this.maxMotorImpulse = this.initMaxMotorImpulse;
this.softness = this.initsoftness;
this.biasFactor = this.initbiasFactor;
this.relaxationFactor = this.initrelaxationFactor;
this.breakingThreshold = this.initbreakingThreshold;
this.entityA = null;
this.entityB = null;
this.app.on('Hinge:FindConnections', this.findConnections, this);
this.app.on('Hinge:Deactivate', this.onDeactivate, this);
this.app.on('Hinge:SetBreakingThreshold', this.setBreakingThreshold, this);
this.entity.on('destroy', () => {
this.app.off('Hinge:FindConnections', this.findConnections, this);
this.app.off('Hinge:Deactivate', this.onDeactivate, this);
this.destroyConstraint();
}, this);
};
Hinge6dof.prototype.findConnections = function () {
var baseConnection = this.scanSlot(this.base);
var slotConnection = this.scanSlot(this.slot);
if (baseConnection.length !== 0 && slotConnection.length !== 0) {
if (baseConnection[0]._guid !== slotConnection[0]._guid) {
var entityA = baseConnection[0];
var entityB = slotConnection[0];
this.connectBodies(entityA, entityB);
this.activate();
this.enabledScanners(false);
}
}
};
Hinge6dof.prototype.onDeactivate = function () {
if (this.constraint) {
this.destroyConstraint();
}
this.enabledScanners(true);
}
Hinge6dof.prototype.setBreakingThreshold = function (breakingThreshold) {
this.breakingThreshold = breakingThreshold;
}
Hinge6dof.prototype.connectBodies = function (rigidBodyA, rigidBodyB) {
rigidBodyA.addChildAndSaveTransform(this.entity);
this.entityA = rigidBodyA;
this.entityB = rigidBodyB;
var bodyA = rigidBodyA.rigidbody.body;
var bodyB = rigidBodyB.rigidbody.body;
var pivotA = this.entity.getPosition().clone().sub(rigidBodyA.getPosition());
var pivotB = this.entity.getPosition().clone().sub(rigidBodyB.getPosition());
this.createConstraint(bodyA, bodyB, pivotA, pivotB, this.entity.forward.normalize(), this.entity.forward.normalize());
}
Hinge6dof.prototype.createConstraint = function (bodyA, bodyB, pcPivotA, pcPivotB, pcAxisA, pcAxisB) {
if (this.constraint) {
this.destroyConstraint();
}
var v1 = new pc.Vec3();
var v2 = new pc.Vec3();
var q = new pc.Quat();
var m = new pc.Mat4();
var pivotA = new Ammo.btVector3(pcPivotA.x, pcPivotA.y, pcPivotA.z);
Utils.getOrthogonalVectors(pcAxisA, v1, v2);
m.set([
v1.x, v1.y, v1.z, 0,
v2.x, v2.y, v2.z, 0,
pcAxisA.x, pcAxisA.y, pcAxisA.z, 0,
0, 0, 0, 1
]);
q.setFromMat4(m);
var quatA = new Ammo.btQuaternion(q.x, q.y, q.z, q.w);
var frameA = new Ammo.btTransform(quatA, pivotA);
var pivotB = new Ammo.btVector3(pcPivotB.x, pcPivotB.y, pcPivotB.z);
Utils.getOrthogonalVectors(pcAxisB, v1, v2);
m.set([
v1.x, v1.y, v1.z, 0,
v2.x, v2.y, v2.z, 0,
pcAxisB.x, pcAxisB.y, pcAxisB.z, 0,
0, 0, 0, 1
]);
q.setFromMat4(m);
var quatB = new Ammo.btQuaternion(q.x, q.y, q.z, q.w);
var frameB = new Ammo.btTransform(quatB, pivotB);
this.constraint = new Ammo.btGeneric6DofConstraint(bodyA, bodyB, frameA, frameB, false);
//Linear
var lowerLil = new Ammo.btVector3(this.linearLowerLimits.x, this.linearLowerLimits.y, this.linearLowerLimits.z);
var upperLil = new Ammo.btVector3(this.linearUpperLimits.x, this.linearUpperLimits.y, this.linearUpperLimits.z);
this.constraint.setLinearLowerLimit(lowerLil);
this.constraint.setLinearUpperLimit(upperLil);
//Angular
var lowerAng = new Ammo.btVector3(this.angularLowerLimits.x, this.angularLowerLimits.y, this.angularLowerLimits.z);
var upperAng = new Ammo.btVector3(this.angularUpperLimits.x, this.angularUpperLimits.y, this.angularUpperLimits.z);
this.constraint.setAngularLowerLimit(lowerAng);
this.constraint.setAngularUpperLimit(upperAng);
this.constraint.setBreakingImpulseThreshold(this.breakingThreshold);
console.log(this.linearLowerLimits, this.linearUpperLimits);
console.log(this.angularLowerLimits, this.angularUpperLimits);
Ammo.destroy(lowerLil);
Ammo.destroy(upperLil);
Ammo.destroy(lowerAng);
Ammo.destroy(upperAng);
Ammo.destroy(frameA);
Ammo.destroy(quatA);
Ammo.destroy(pivotA);
Ammo.destroy(frameB);
Ammo.destroy(quatB);
Ammo.destroy(pivotB);
var dynamicsWorld = this.app.systems.rigidbody.dynamicsWorld;
dynamicsWorld.addConstraint(this.constraint, !this.enableCollision);
};
Hinge6dof.prototype.activate = function () {
this.entityA.rigidbody.activate();
this.entityB.rigidbody.activate();
};
Hinge6dof.prototype.destroyConstraint = function () {
if (this.constraint) {
var dynamicsWorld = this.app.systems.rigidbody.dynamicsWorld;
dynamicsWorld.removeConstraint(this.constraint);
Ammo.destroy(this.constraint);
this.constraint = null;
}
};
Hinge6dof.prototype.enabledScanners = function (state) {
var scanners = this.entity.findByTag('Scanner');
scanners.forEach((s) => {
s.enabled = state;
});
}
Hinge6dof.prototype.scanSlot = function (slot) {
var scanners = slot.findByTag('Scanner');
var connectedSet = new Set();
for (var s = 0; s < scanners.length; s++) {
var scanner = scanners[s];
var aabb = scanner.render.meshInstances[0].aabb;
// Create AABB region
var region = createAABB(aabb.center, aabb.halfExtents);
// Query the BVH for nearby entities, filtering directly
var nEntities = this.WorkSpaceBVH.query('AABB', region, (nEntity) => { return nEntity._guid !== this.entity._guid });
// Add parent entities to the connected set
for (var i = 0; i < nEntities.length; i++) {
connectedSet.add(nEntities[i].parent);
}
}
// Convert the set to an array for final output if needed
var connected = Array.from(connectedSet);
return connected;
};
Hinge6dof.prototype.update = function (dt) {
};
What I’m doing wrong ? it just fell off from joint I set All upper and lower limits to vec3(0, 0, 0)
it working fine if I use normal Hinge Constraint