// Given a constraint, apply the current constraint parameters to same. public void SetConstraintParameters(BSConstraint constrain) { switch (constraintType) { case ConstraintType.D6_CONSTRAINT_TYPE: BSConstraint6Dof constrain6dof = constrain as BSConstraint6Dof; if (constrain6dof != null) { // zero linear and angular limits makes the objects unable to move in relation to each other constrain6dof.SetLinearLimits(linearLimitLow, linearLimitHigh); constrain6dof.SetAngularLimits(angularLimitLow, angularLimitHigh); // tweek the constraint to increase stability constrain6dof.UseFrameOffset(useFrameOffset); constrain6dof.TranslationalLimitMotor(enableTransMotor, transMotorMaxVel, transMotorMaxForce); constrain6dof.SetCFMAndERP(cfm, erp); if (solverIterations != 0f) { constrain6dof.SetSolverIterations(solverIterations); } } break; default: break; } }
private BSConstraint BuildConstraint(BSPrimLinkable rootPrim, BSPrimLinkable childPrim) { // Zero motion for children so they don't interpolate childPrim.ZeroMotion(true); // Relative position normalized to the root prim // Essentually a vector pointing from center of rootPrim to center of childPrim OMV.Vector3 childRelativePosition = childPrim.Position - rootPrim.Position; // real world coordinate of midpoint between the two objects OMV.Vector3 midPoint = rootPrim.Position + (childRelativePosition / 2); DetailLog("{0},BSLinksetConstraint.BuildConstraint,taint,root={1},rBody={2},child={3},cBody={4},rLoc={5},cLoc={6},midLoc={7}", rootPrim.LocalID, rootPrim.LocalID, rootPrim.PhysBody.AddrString, childPrim.LocalID, childPrim.PhysBody.AddrString, rootPrim.Position, childPrim.Position, midPoint); // create a constraint that allows no freedom of movement between the two objects // http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=4818 BSConstraint6Dof constrain = new BSConstraint6Dof( PhysicsScene.World, rootPrim.PhysBody, childPrim.PhysBody, midPoint, true, true); // PhysicsScene.World, childPrim.BSBody, rootPrim.BSBody, midPoint, true, true ); /* NOTE: below is an attempt to build constraint with full frame computation, etc. * Using the midpoint is easier since it lets the Bullet code manipulate the transforms * of the objects. * Code left for future programmers. * // ================================================================================== * // relative position normalized to the root prim * OMV.Quaternion invThisOrientation = OMV.Quaternion.Inverse(rootPrim.Orientation); * OMV.Vector3 childRelativePosition = (childPrim.Position - rootPrim.Position) * invThisOrientation; * * // relative rotation of the child to the parent * OMV.Quaternion childRelativeRotation = invThisOrientation * childPrim.Orientation; * OMV.Quaternion inverseChildRelativeRotation = OMV.Quaternion.Inverse(childRelativeRotation); * * DetailLog("{0},BSLinksetConstraint.PhysicallyLinkAChildToRoot,taint,root={1},child={2}", rootPrim.LocalID, rootPrim.LocalID, childPrim.LocalID); * BS6DofConstraint constrain = new BS6DofConstraint( * PhysicsScene.World, rootPrim.Body, childPrim.Body, * OMV.Vector3.Zero, * OMV.Quaternion.Inverse(rootPrim.Orientation), * OMV.Vector3.Zero, * OMV.Quaternion.Inverse(childPrim.Orientation), * true, * true * ); * // ================================================================================== */ PhysicsScene.Constraints.AddConstraint(constrain); // zero linear and angular limits makes the objects unable to move in relation to each other constrain.SetLinearLimits(OMV.Vector3.Zero, OMV.Vector3.Zero); constrain.SetAngularLimits(OMV.Vector3.Zero, OMV.Vector3.Zero); // tweek the constraint to increase stability constrain.UseFrameOffset(BSParam.LinkConstraintUseFrameOffset); constrain.TranslationalLimitMotor(BSParam.LinkConstraintEnableTransMotor, BSParam.LinkConstraintTransMotorMaxVel, BSParam.LinkConstraintTransMotorMaxForce); constrain.SetCFMAndERP(BSParam.LinkConstraintCFM, BSParam.LinkConstraintERP); if (BSParam.LinkConstraintSolverIterations != 0f) { constrain.SetSolverIterations(BSParam.LinkConstraintSolverIterations); } return(constrain); }
private BSConstraint BuildConstraint(BSPrimLinkable rootPrim, BSPrimLinkable childPrim) { // Zero motion for children so they don't interpolate childPrim.ZeroMotion(true); // Relative position normalized to the root prim // Essentually a vector pointing from center of rootPrim to center of childPrim OMV.Vector3 childRelativePosition = childPrim.Position - rootPrim.Position; // real world coordinate of midpoint between the two objects OMV.Vector3 midPoint = rootPrim.Position + (childRelativePosition / 2); DetailLog("{0},BSLinksetConstraint.BuildConstraint,taint,root={1},rBody={2},child={3},cBody={4},rLoc={5},cLoc={6},midLoc={7}", rootPrim.LocalID, rootPrim.LocalID, rootPrim.PhysBody.AddrString, childPrim.LocalID, childPrim.PhysBody.AddrString, rootPrim.Position, childPrim.Position, midPoint); // create a constraint that allows no freedom of movement between the two objects // http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=4818 BSConstraint6Dof constrain = new BSConstraint6Dof( PhysicsScene.World, rootPrim.PhysBody, childPrim.PhysBody, midPoint, true, true ); // PhysicsScene.World, childPrim.BSBody, rootPrim.BSBody, midPoint, true, true ); /* NOTE: below is an attempt to build constraint with full frame computation, etc. * Using the midpoint is easier since it lets the Bullet code manipulate the transforms * of the objects. * Code left for future programmers. // ================================================================================== // relative position normalized to the root prim OMV.Quaternion invThisOrientation = OMV.Quaternion.Inverse(rootPrim.Orientation); OMV.Vector3 childRelativePosition = (childPrim.Position - rootPrim.Position) * invThisOrientation; // relative rotation of the child to the parent OMV.Quaternion childRelativeRotation = invThisOrientation * childPrim.Orientation; OMV.Quaternion inverseChildRelativeRotation = OMV.Quaternion.Inverse(childRelativeRotation); DetailLog("{0},BSLinksetConstraint.PhysicallyLinkAChildToRoot,taint,root={1},child={2}", rootPrim.LocalID, rootPrim.LocalID, childPrim.LocalID); BS6DofConstraint constrain = new BS6DofConstraint( PhysicsScene.World, rootPrim.Body, childPrim.Body, OMV.Vector3.Zero, OMV.Quaternion.Inverse(rootPrim.Orientation), OMV.Vector3.Zero, OMV.Quaternion.Inverse(childPrim.Orientation), true, true ); // ================================================================================== */ PhysicsScene.Constraints.AddConstraint(constrain); // zero linear and angular limits makes the objects unable to move in relation to each other constrain.SetLinearLimits(OMV.Vector3.Zero, OMV.Vector3.Zero); constrain.SetAngularLimits(OMV.Vector3.Zero, OMV.Vector3.Zero); // tweek the constraint to increase stability constrain.UseFrameOffset(BSParam.LinkConstraintUseFrameOffset); constrain.TranslationalLimitMotor(BSParam.LinkConstraintEnableTransMotor, BSParam.LinkConstraintTransMotorMaxVel, BSParam.LinkConstraintTransMotorMaxForce); constrain.SetCFMAndERP(BSParam.LinkConstraintCFM, BSParam.LinkConstraintERP); if (BSParam.LinkConstraintSolverIterations != 0f) { constrain.SetSolverIterations(BSParam.LinkConstraintSolverIterations); } return constrain; }
// Given a constraint, apply the current constraint parameters to same. public override void SetLinkParameters(BSConstraint constrain) { member.PhysScene.DetailLog("{0},BSLinkInfoConstraint.SetLinkParameters,type={1}", member.LocalID, constraintType); switch (constraintType) { case ConstraintType.FIXED_CONSTRAINT_TYPE: case ConstraintType.D6_CONSTRAINT_TYPE: BSConstraint6Dof constrain6dof = constrain as BSConstraint6Dof; if (constrain6dof != null) { // NOTE: D6_SPRING_CONSTRAINT_TYPE should be updated if you change any of this code. // zero linear and angular limits makes the objects unable to move in relation to each other constrain6dof.SetLinearLimits(linearLimitLow, linearLimitHigh); constrain6dof.SetAngularLimits(angularLimitLow, angularLimitHigh); // tweek the constraint to increase stability constrain6dof.UseFrameOffset(useFrameOffset); constrain6dof.TranslationalLimitMotor(enableTransMotor, transMotorMaxVel, transMotorMaxForce); constrain6dof.SetCFMAndERP(cfm, erp); if (solverIterations != 0f) { constrain6dof.SetSolverIterations(solverIterations); } } break; case ConstraintType.D6_SPRING_CONSTRAINT_TYPE: BSConstraintSpring constrainSpring = constrain as BSConstraintSpring; if (constrainSpring != null) { // zero linear and angular limits makes the objects unable to move in relation to each other constrainSpring.SetLinearLimits(linearLimitLow, linearLimitHigh); constrainSpring.SetAngularLimits(angularLimitLow, angularLimitHigh); // tweek the constraint to increase stability constrainSpring.UseFrameOffset(useFrameOffset); constrainSpring.TranslationalLimitMotor(enableTransMotor, transMotorMaxVel, transMotorMaxForce); constrainSpring.SetCFMAndERP(cfm, erp); if (solverIterations != 0f) { constrainSpring.SetSolverIterations(solverIterations); } for (int ii = 0; ii < springAxisEnable.Length; ii++) { constrainSpring.SetAxisEnable(ii, springAxisEnable[ii]); if (springDamping[ii] != BSAPITemplate.SPRING_NOT_SPECIFIED) { constrainSpring.SetDamping(ii, springDamping[ii]); } if (springStiffness[ii] != BSAPITemplate.SPRING_NOT_SPECIFIED) { constrainSpring.SetStiffness(ii, springStiffness[ii]); } } constrainSpring.CalculateTransforms(); if (springLinearEquilibriumPoint != OMV.Vector3.Zero) { constrainSpring.SetEquilibriumPoint(springLinearEquilibriumPoint, springAngularEquilibriumPoint); } else { constrainSpring.SetEquilibriumPoint(BSAPITemplate.SPRING_NOT_SPECIFIED, BSAPITemplate.SPRING_NOT_SPECIFIED); } } break; default: break; } }