28 using System.Collections.Generic;
31 using OMV = OpenMetaverse;
33 namespace OpenSim.Region.PhysicsModule.BulletS
72 member.PhysScene.DetailLog(
"{0},BSLinkInfoConstraint.creation", member.LocalID);
79 constraintType = ConstraintType.BS_FIXED_CONSTRAINT_TYPE;
80 linearLimitLow = OMV.Vector3.Zero;
81 linearLimitHigh = OMV.Vector3.Zero;
82 angularLimitLow = OMV.Vector3.Zero;
83 angularLimitHigh = OMV.Vector3.Zero;
84 useFrameOffset = BSParam.LinkConstraintUseFrameOffset;
85 enableTransMotor = BSParam.LinkConstraintEnableTransMotor;
86 transMotorMaxVel = BSParam.LinkConstraintTransMotorMaxVel;
87 transMotorMaxForce = BSParam.LinkConstraintTransMotorMaxForce;
88 cfm = BSParam.LinkConstraintCFM;
89 erp = BSParam.LinkConstraintERP;
90 solverIterations = BSParam.LinkConstraintSolverIterations;
91 frameInAloc = OMV.Vector3.Zero;
92 frameInArot = OMV.Quaternion.Identity;
93 frameInBloc = OMV.Vector3.Zero;
94 frameInBrot = OMV.Quaternion.Identity;
95 useLinearReferenceFrameA =
true;
96 springAxisEnable =
new bool[6];
97 springDamping =
new float[6];
98 springStiffness =
new float[6];
99 for (
int ii = 0; ii < springAxisEnable.Length; ii++)
101 springAxisEnable[ii] =
false;
102 springDamping[ii] = BSAPITemplate.SPRING_NOT_SPECIFIED;
103 springStiffness[ii] = BSAPITemplate.SPRING_NOT_SPECIFIED;
105 springLinearEquilibriumPoint = OMV.Vector3.Zero;
106 springAngularEquilibriumPoint = OMV.Vector3.Zero;
107 member.PhysScene.DetailLog(
"{0},BSLinkInfoConstraint.ResetLink", member.LocalID);
113 member.PhysScene.DetailLog(
"{0},BSLinkInfoConstraint.SetLinkParameters,type={1}", member.LocalID, constraintType);
114 switch (constraintType)
116 case ConstraintType.BS_FIXED_CONSTRAINT_TYPE:
117 case ConstraintType.D6_CONSTRAINT_TYPE:
119 if (constrain6dof != null)
123 constrain6dof.SetLinearLimits(linearLimitLow, linearLimitHigh);
124 constrain6dof.SetAngularLimits(angularLimitLow, angularLimitHigh);
127 constrain6dof.UseFrameOffset(useFrameOffset);
128 constrain6dof.TranslationalLimitMotor(enableTransMotor, transMotorMaxVel, transMotorMaxForce);
129 constrain6dof.SetCFMAndERP(cfm, erp);
130 if (solverIterations != 0f)
132 constrain6dof.SetSolverIterations(solverIterations);
136 case ConstraintType.D6_SPRING_CONSTRAINT_TYPE:
138 if (constrainSpring != null)
141 constrainSpring.SetLinearLimits(linearLimitLow, linearLimitHigh);
142 constrainSpring.SetAngularLimits(angularLimitLow, angularLimitHigh);
145 constrainSpring.UseFrameOffset(useFrameOffset);
146 constrainSpring.TranslationalLimitMotor(enableTransMotor, transMotorMaxVel, transMotorMaxForce);
147 constrainSpring.SetCFMAndERP(cfm, erp);
148 if (solverIterations != 0f)
150 constrainSpring.SetSolverIterations(solverIterations);
152 for (
int ii = 0; ii < springAxisEnable.Length; ii++)
154 constrainSpring.SetAxisEnable(ii, springAxisEnable[ii]);
156 constrainSpring.SetDamping(ii, springDamping[ii]);
158 constrainSpring.SetStiffness(ii, springStiffness[ii]);
160 constrainSpring.CalculateTransforms();
162 if (springLinearEquilibriumPoint !=
OMV.Vector3.Zero)
163 constrainSpring.SetEquilibriumPoint(springLinearEquilibriumPoint, springAngularEquilibriumPoint);
165 constrainSpring.SetEquilibriumPoint(BSAPITemplate.SPRING_NOT_SPECIFIED, BSAPITemplate.SPRING_NOT_SPECIFIED);
189 LinksetImpl = LinksetImplementation.Constraint;
192 private static string LogHeader =
"[BULLETSIM LINKSET CONSTRAINT]";
200 ScheduleRebuild(requestor);
201 base.Refresh(requestor);
207 DetailLog(
"{0},BSLinksetConstraint.ScheduleRebuild,,rebuilding={1},hasChildren={2},actuallyScheduling={3}",
208 requestor.
LocalID, Rebuilding, HasAnyChildren, (!Rebuilding && HasAnyChildren));
215 if (!RebuildScheduled)
217 if (!Rebuilding && HasAnyChildren)
219 RebuildScheduled =
true;
221 m_physicsScene.PostTaintObject(
"BSLinksetContraints.Refresh", requestor.LocalID, delegate()
227 PhysicallyUnlinkAChildFromRoot(LinksetRoot, requestor);
229 RecomputeLinksetConstraints();
231 RebuildScheduled =
false;
247 DetailLog(
"{0},BSLinksetConstraints.MakeDynamic,call,IsRoot={1}", child.
LocalID, IsRoot(child));
251 Refresh(LinksetRoot);
265 DetailLog(
"{0},BSLinksetConstraint.MakeStatic,call,IsRoot={1}", child.
LocalID, IsRoot(child));
266 child.ClearDisplacement();
270 Refresh(LinksetRoot);
290 DetailLog(
"{0},BSLinksetConstraint.RemoveDependencies,removeChildrenForRoot,rID={1},rBody={2}",
291 child.
LocalID, LinksetRoot.LocalID, LinksetRoot.PhysBody.AddrString);
293 lock (m_linksetActivityLock)
296 ret = PhysicallyUnlinkAllChildrenFromRoot(LinksetRoot);
298 Refresh(LinksetRoot);
309 if (!HasChild(child))
313 DetailLog(
"{0},BSLinksetConstraints.AddChildToLinkset,call,child={1}", LinksetRoot.LocalID, child.LocalID);
316 Refresh(LinksetRoot);
325 if (m_children.Remove(child))
330 DetailLog(
"{0},BSLinksetConstraints.RemoveChildFromLinkset,call,rID={1},rBody={2},cID={3},cBody={4}",
335 m_physicsScene.TaintedObject(inTaintTime, childx.LocalID,
"BSLinksetConstraints.RemoveChildFromLinkset", delegate()
337 PhysicallyUnlinkAChildFromRoot(rootx, childx);
340 Refresh(LinksetRoot);
359 private BSConstraint BuildConstraint(BSPrimLinkable rootPrim, BSLinkInfo li)
361 BSLinkInfoConstraint linkInfo = li as BSLinkInfoConstraint;
362 if (linkInfo == null)
366 li.member.ZeroMotion(
true);
368 BSConstraint constrain = null;
370 switch (linkInfo.constraintType)
372 case ConstraintType.BS_FIXED_CONSTRAINT_TYPE:
373 case ConstraintType.D6_CONSTRAINT_TYPE:
376 OMV.Vector3 childRelativePosition = linkInfo.member.Position - rootPrim.Position;
379 OMV.Vector3 midPoint = rootPrim.Position + (childRelativePosition / 2);
381 DetailLog(
"{0},BSLinksetConstraint.BuildConstraint,6Dof,rBody={1},cBody={2},rLoc={3},cLoc={4},midLoc={5}",
382 rootPrim.LocalID, rootPrim.PhysBody, linkInfo.member.PhysBody,
383 rootPrim.Position, linkInfo.member.Position, midPoint);
388 constrain =
new BSConstraint6Dof(
389 m_physicsScene.World, rootPrim.PhysBody, linkInfo.member.PhysBody, midPoint,
true,
true );
418 case ConstraintType.D6_SPRING_CONSTRAINT_TYPE:
419 constrain =
new BSConstraintSpring(m_physicsScene.World, rootPrim.PhysBody, linkInfo.member.PhysBody,
420 linkInfo.frameInAloc, linkInfo.frameInArot, linkInfo.frameInBloc, linkInfo.frameInBrot,
421 linkInfo.useLinearReferenceFrameA,
423 DetailLog(
"{0},BSLinksetConstraint.BuildConstraint,spring,root={1},rBody={2},child={3},cBody={4},rLoc={5},cLoc={6}",
425 rootPrim.LocalID, rootPrim.PhysBody.AddrString,
426 linkInfo.member.LocalID, linkInfo.member.PhysBody.AddrString,
427 rootPrim.Position, linkInfo.member.Position);
434 linkInfo.SetLinkParameters(constrain);
436 m_physicsScene.Constraints.AddConstraint(constrain);
445 private bool PhysicallyUnlinkAChildFromRoot(BSPrimLinkable rootPrim, BSPrimLinkable childPrim)
448 DetailLog(
"{0},BSLinksetConstraint.PhysicallyUnlinkAChildFromRoot,taint,root={1},rBody={2},child={3},cBody={4}",
450 rootPrim.LocalID, rootPrim.PhysBody.AddrString,
451 childPrim.LocalID, childPrim.PhysBody.AddrString);
454 if (rootPrim == childPrim || childPrim == LinksetRoot)
456 PhysicallyUnlinkAllChildrenFromRoot(LinksetRoot);
462 if (m_physicsScene.Constraints.RemoveAndDestroyConstraint(rootPrim.PhysBody, childPrim.PhysBody))
465 m_physicsScene.PE.PushUpdate(childPrim.PhysBody);
476 private bool PhysicallyUnlinkAllChildrenFromRoot(BSPrimLinkable rootPrim)
478 DetailLog(
"{0},BSLinksetConstraint.PhysicallyUnlinkAllChildren,taint", rootPrim.LocalID);
480 return m_physicsScene.Constraints.RemoveAndDestroyConstraint(rootPrim.PhysBody);
488 private void RecomputeLinksetConstraints()
490 float linksetMass = LinksetMass;
491 LinksetRoot.UpdatePhysicalMassProperties(linksetMass,
true);
493 DetailLog(
"{0},BSLinksetConstraint.RecomputeLinksetConstraints,set,rBody={1},linksetMass={2}",
494 LinksetRoot.LocalID, LinksetRoot.PhysBody.AddrString, linksetMass);
501 if (!LinksetRoot.IsPhysicallyActive || !HasAnyChildren)
503 DetailLog(
"{0},BSLinksetConstraint.RecomputeLinksetCompound,notPhysicalOrNoChildren", LinksetRoot.LocalID);
507 ForEachLinkInfo((li) =>
512 li.member.UpdatePhysicalMassProperties(linksetMass,
true);
514 BSConstraint constrain;
515 if (!m_physicsScene.Constraints.TryGetConstraint(LinksetRoot.PhysBody, li.member.PhysBody, out constrain))
518 constrain = BuildConstraint(LinksetRoot, li);
520 li.SetLinkParameters(constrain);
521 constrain.RecomputeConstraintVariables(linksetMass);
534 public override object Extension(
string pFunct, params
object[] pParams)
540 case ExtendedPhysics.PhysFunctChangeLinkType:
541 if (pParams.Length > 2)
543 int requestedType = (int)pParams[2];
544 DetailLog(
"{0},BSLinksetConstraint.ChangeLinkType,requestedType={1}", LinksetRoot.LocalID, requestedType);
555 DetailLog(
"{0},BSLinksetConstraint.ChangeLinkType,rootID={1},childID={2},type={3}",
556 LinksetRoot.LocalID, LinksetRoot.LocalID, child.
LocalID, requestedType);
557 m_physicsScene.TaintedObject(child.LocalID,
"BSLinksetConstraint.PhysFunctChangeLinkType", delegate()
560 RemoveDependencies(child);
563 if (TryGetLinkInfo(child, out linkInfo))
565 BSLinkInfoConstraint linkInfoC = linkInfo as BSLinkInfoConstraint;
566 if (linkInfoC != null)
570 DetailLog(
"{0},BSLinksetConstraint.ChangeLinkType,link={1},type={2}",
571 linkInfo.member.LocalID, linkInfo.member.LocalID, linkInfoC.
constraintType);
575 DetailLog(
"{0},BSLinksetConstraint.ChangeLinkType,linkInfoNotConstraint,childID={1}", LinksetRoot.LocalID, child.
LocalID);
580 DetailLog(
"{0},BSLinksetConstraint.ChangeLinkType,noLinkInfoForChild,childID={1}", LinksetRoot.LocalID, child.
LocalID);
588 DetailLog(
"{0},BSLinksetConstraint.SetLinkType,childNotBSPrimLinkable", LinksetRoot.LocalID);
593 DetailLog(
"{0},BSLinksetConstraint.SetLinkType,illegalRequestedType,reqested={1},spring={2}",
594 LinksetRoot.LocalID, requestedType, ((
int)
ConstraintType.D6_SPRING_CONSTRAINT_TYPE));
599 case ExtendedPhysics.PhysFunctGetLinkType:
600 if (pParams.Length > 0)
606 if (TryGetLinkInfo(child, out linkInfo))
608 BSLinkInfoConstraint linkInfoC = linkInfo as BSLinkInfoConstraint;
609 if (linkInfoC != null)
611 ret = (object)(
int)linkInfoC.constraintType;
612 DetailLog(
"{0},BSLinksetConstraint.GetLinkType,link={1},type={2}",
613 linkInfo.member.LocalID, linkInfo.member.LocalID, linkInfoC.
constraintType);
621 case ExtendedPhysics.PhysFunctChangeLinkParams:
623 if (pParams.Length > 2)
627 if (TryGetLinkInfo(child, out baseLinkInfo))
629 BSLinkInfoConstraint linkInfo = baseLinkInfo as BSLinkInfoConstraint;
630 if (linkInfo != null)
635 OMV.Vector3 valueVector;
636 OMV.Vector3 valueVector2;
637 OMV.Quaternion valueQuaternion;
638 int axisLow, axisHigh;
641 while (opIndex < pParams.Length)
647 thisOp = (int)pParams[opIndex];
648 DetailLog(
"{0},BSLinksetConstraint.ChangeLinkParams2,op={1},val={2}",
649 linkInfo.member.LocalID, thisOp, pParams[opIndex + 1]);
652 case ExtendedPhysics.PHYS_PARAM_LINK_TYPE:
653 valueInt = (int)pParams[opIndex + 1];
662 linkInfo.constraintType = valueType;
666 case ExtendedPhysics.PHYS_PARAM_FRAMEINA_LOC:
667 errMsg =
"PHYS_PARAM_FRAMEINA_LOC takes one parameter of type vector";
668 valueVector = (OMV.Vector3)pParams[opIndex + 1];
669 linkInfo.frameInAloc = valueVector;
672 case ExtendedPhysics.PHYS_PARAM_FRAMEINA_ROT:
673 errMsg =
"PHYS_PARAM_FRAMEINA_ROT takes one parameter of type rotation";
674 valueQuaternion = (OMV.Quaternion)pParams[opIndex + 1];
675 linkInfo.frameInArot = valueQuaternion;
678 case ExtendedPhysics.PHYS_PARAM_FRAMEINB_LOC:
679 errMsg =
"PHYS_PARAM_FRAMEINB_LOC takes one parameter of type vector";
680 valueVector = (OMV.Vector3)pParams[opIndex + 1];
681 linkInfo.frameInBloc = valueVector;
684 case ExtendedPhysics.PHYS_PARAM_FRAMEINB_ROT:
685 errMsg =
"PHYS_PARAM_FRAMEINB_ROT takes one parameter of type rotation";
686 valueQuaternion = (OMV.Quaternion)pParams[opIndex + 1];
687 linkInfo.frameInBrot = valueQuaternion;
690 case ExtendedPhysics.PHYS_PARAM_LINEAR_LIMIT_LOW:
691 errMsg =
"PHYS_PARAM_LINEAR_LIMIT_LOW takes one parameter of type vector";
692 valueVector = (OMV.Vector3)pParams[opIndex + 1];
693 linkInfo.linearLimitLow = valueVector;
696 case ExtendedPhysics.PHYS_PARAM_LINEAR_LIMIT_HIGH:
697 errMsg =
"PHYS_PARAM_LINEAR_LIMIT_HIGH takes one parameter of type vector";
698 valueVector = (OMV.Vector3)pParams[opIndex + 1];
699 linkInfo.linearLimitHigh = valueVector;
702 case ExtendedPhysics.PHYS_PARAM_ANGULAR_LIMIT_LOW:
703 errMsg =
"PHYS_PARAM_ANGULAR_LIMIT_LOW takes one parameter of type vector";
704 valueVector = (OMV.Vector3)pParams[opIndex + 1];
705 linkInfo.angularLimitLow = valueVector;
708 case ExtendedPhysics.PHYS_PARAM_ANGULAR_LIMIT_HIGH:
709 errMsg =
"PHYS_PARAM_ANGULAR_LIMIT_HIGH takes one parameter of type vector";
710 valueVector = (OMV.Vector3)pParams[opIndex + 1];
711 linkInfo.angularLimitHigh = valueVector;
714 case ExtendedPhysics.PHYS_PARAM_USE_FRAME_OFFSET:
715 errMsg =
"PHYS_PARAM_USE_FRAME_OFFSET takes one parameter of type integer (bool)";
716 valueBool = ((int)pParams[opIndex + 1]) != 0;
717 linkInfo.useFrameOffset = valueBool;
720 case ExtendedPhysics.PHYS_PARAM_ENABLE_TRANSMOTOR:
721 errMsg =
"PHYS_PARAM_ENABLE_TRANSMOTOR takes one parameter of type integer (bool)";
722 valueBool = ((int)pParams[opIndex + 1]) != 0;
723 linkInfo.enableTransMotor = valueBool;
726 case ExtendedPhysics.PHYS_PARAM_TRANSMOTOR_MAXVEL:
727 errMsg =
"PHYS_PARAM_TRANSMOTOR_MAXVEL takes one parameter of type float";
728 valueFloat = (float)pParams[opIndex + 1];
729 linkInfo.transMotorMaxVel = valueFloat;
732 case ExtendedPhysics.PHYS_PARAM_TRANSMOTOR_MAXFORCE:
733 errMsg =
"PHYS_PARAM_TRANSMOTOR_MAXFORCE takes one parameter of type float";
734 valueFloat = (float)pParams[opIndex + 1];
735 linkInfo.transMotorMaxForce = valueFloat;
738 case ExtendedPhysics.PHYS_PARAM_CFM:
739 errMsg =
"PHYS_PARAM_CFM takes one parameter of type float";
740 valueFloat = (float)pParams[opIndex + 1];
741 linkInfo.cfm = valueFloat;
744 case ExtendedPhysics.PHYS_PARAM_ERP:
745 errMsg =
"PHYS_PARAM_ERP takes one parameter of type float";
746 valueFloat = (float)pParams[opIndex + 1];
747 linkInfo.erp = valueFloat;
750 case ExtendedPhysics.PHYS_PARAM_SOLVER_ITERATIONS:
751 errMsg =
"PHYS_PARAM_SOLVER_ITERATIONS takes one parameter of type float";
752 valueFloat = (float)pParams[opIndex + 1];
753 linkInfo.solverIterations = valueFloat;
756 case ExtendedPhysics.PHYS_PARAM_SPRING_AXIS_ENABLE:
757 errMsg =
"PHYS_PARAM_SPRING_AXIS_ENABLE takes two parameters of types integer and integer (bool)";
758 valueInt = (int)pParams[opIndex + 1];
759 valueBool = ((int)pParams[opIndex + 2]) != 0;
760 GetAxisRange(valueInt, out axisLow, out axisHigh);
761 for (
int ii = axisLow; ii <= axisHigh; ii++)
766 errMsg =
"PHYS_PARAM_SPRING_DAMPING takes two parameters of types integer and float";
767 valueInt = (
int)pParams[opIndex + 1];
768 valueFloat = (float)pParams[opIndex + 2];
769 GetAxisRange(valueInt, out axisLow, out axisHigh);
770 for (
int ii = axisLow; ii <= axisHigh; ii++)
775 errMsg =
"PHYS_PARAM_SPRING_STIFFNESS takes two parameters of types integer and float";
776 valueInt = (
int)pParams[opIndex + 1];
777 valueFloat = (float)pParams[opIndex + 2];
778 GetAxisRange(valueInt, out axisLow, out axisHigh);
779 for (
int ii = axisLow; ii <= axisHigh; ii++)
784 errMsg =
"PHYS_PARAM_SPRING_EQUILIBRIUM_POINT takes two parameters of type vector";
785 valueVector = (
OMV.Vector3)pParams[opIndex + 1];
786 valueVector2 = (OMV.Vector3)pParams[opIndex + 2];
787 linkInfo.springLinearEquilibriumPoint = valueVector;
788 linkInfo.springAngularEquilibriumPoint = valueVector2;
791 case ExtendedPhysics.PHYS_PARAM_USE_LINEAR_FRAMEA:
792 errMsg =
"PHYS_PARAM_USE_LINEAR_FRAMEA takes one parameter of type integer (bool)";
793 valueBool = ((int)pParams[opIndex + 1]) != 0;
794 linkInfo.useLinearReferenceFrameA = valueBool;
801 catch (InvalidCastException e)
803 m_physicsScene.Logger.WarnFormat(
"{0} value of wrong type in physSetLinksetParams: {1}, err={2}",
804 LogHeader, errMsg, e);
808 m_physicsScene.Logger.WarnFormat(
"{0} bad parameters in physSetLinksetParams: {1}", LogHeader, e);
818 ret = base.Extension(pFunct, pParams);
827 private void GetAxisRange(
int rangeSpec, out
int low, out
int high)
831 case ExtendedPhysics.PHYS_AXIS_LINEAR_ALL:
835 case ExtendedPhysics.PHYS_AXIS_ANGULAR_ALL:
839 case ExtendedPhysics.PHYS_AXIS_ALL:
844 low = high = rangeSpec;
849 #endregion // Extension
const int SPRING_NOT_SPECIFIED
const int PHYS_PARAM_SPRING_EQUILIBRIUM_POINT
override void AddChildToLinkset(BSPrimLinkable child)
override object Extension(string pFunct, params object[] pParams)
override void SetLinkParameters(BSConstraint constrain)
const int PHYS_PARAM_SPRING_STIFFNESS
bool useLinearReferenceFrameA
OMV.Vector3 springAngularEquilibriumPoint
OMV.Quaternion frameInArot
BSLinkInfoConstraint(BSPrimLinkable pMember)
OMV.Vector3 angularLimitLow
const int PHYS_PARAM_SPRING_DAMPING
override void RemoveChildFromLinkset(BSPrimLinkable child, bool inTaintTime)
virtual string AddrString
ConstraintType constraintType
OMV.Quaternion frameInBrot
OMV.Vector3 springLinearEquilibriumPoint
OMV.Vector3 angularLimitHigh
override bool MakeStatic(BSPrimLinkable child)
OMV.Vector3 linearLimitHigh
override bool ShouldUpdateChildProperties()
override bool RemoveDependencies(BSPrimLinkable child)
BSLinksetConstraints(BSScene scene, BSPrimLinkable parent)
OMV.Vector3 linearLimitLow
override void UpdateProperties(UpdatedProperties whichUpdated, BSPrimLinkable pObj)
override void Refresh(BSPrimLinkable requestor)
override void ResetLink()
override bool MakeDynamic(BSPrimLinkable child)