28 using System.Collections.Generic;
31 using OpenSim.Framework;
33 using OMV = OpenMetaverse;
35 namespace OpenSim.
Region.PhysicsModule.BulletS
40 #pragma warning disable 414
41 private static string LogHeader =
"[BULLETSIM LINKSET COMPOUND]";
42 #pragma warning restore 414
47 LinksetImpl = LinksetImplementation.Compound;
54 if (LinksetRoot.PhysBody.HasPhysicalBody)
55 m_physicsScene.PE.SetFriction(LinksetRoot.PhysBody, friction);
59 if (LinksetRoot.PhysBody.HasPhysicalBody)
60 m_physicsScene.PE.SetRestitution(LinksetRoot.PhysBody, restitution);
64 if (LinksetRoot.PhysBody.HasPhysicalBody)
65 m_physicsScene.PE.SetGravity(LinksetRoot.PhysBody, gravity);
69 OMV.Vector3 inertia = m_physicsScene.PE.CalculateLocalInertia(LinksetRoot.PhysShape.physShapeInfo, linksetMass);
70 LinksetRoot.Inertia = inertia * inertiaFactor;
71 m_physicsScene.PE.SetMassProps(LinksetRoot.PhysBody, linksetMass, LinksetRoot.Inertia);
72 m_physicsScene.PE.UpdateInertiaTensor(LinksetRoot.PhysBody);
76 if (LinksetRoot.PhysBody.HasPhysicalBody)
77 m_physicsScene.PE.SetCollisionFlags(LinksetRoot.PhysBody, collFlags);
81 if (LinksetRoot.PhysBody.HasPhysicalBody)
82 m_physicsScene.PE.AddToCollisionFlags(LinksetRoot.PhysBody, collFlags);
86 if (LinksetRoot.PhysBody.HasPhysicalBody)
87 m_physicsScene.PE.RemoveFromCollisionFlags(LinksetRoot.PhysBody, collFlags);
96 ScheduleRebuild(requestor);
97 base.Refresh(requestor);
106 lock (m_linksetActivityLock)
108 if (!RebuildScheduled && !Rebuilding && HasAnyChildren)
110 InternalScheduleRebuild(requestor);
116 private void InternalScheduleRebuild(BSPrimLinkable requestor)
118 DetailLog(
"{0},BSLinksetCompound.InternalScheduleRebuild,,rebuilding={1},hasChildren={2}",
119 requestor.LocalID, Rebuilding, HasAnyChildren);
120 RebuildScheduled =
true;
121 m_physicsScene.PostTaintObject(
"BSLinksetCompound.ScheduleRebuild", LinksetRoot.LocalID, delegate()
125 if (this.AllPartsComplete)
127 RecomputeLinksetCompound();
131 DetailLog(
"{0},BSLinksetCompound.InternalScheduleRebuild,,rescheduling because not all children complete",
133 InternalScheduleRebuild(requestor);
136 RebuildScheduled =
false;
148 DetailLog(
"{0},BSLinksetCompound.MakeDynamic,call,IsRoot={1}", child.
LocalID, IsRoot(child));
152 Refresh(LinksetRoot);
164 DetailLog(
"{0},BSLinksetCompound.MakeStatic,call,IsRoot={1}", child.
LocalID, IsRoot(child));
165 child.ClearDisplacement();
169 Refresh(LinksetRoot);
178 if (!LinksetRoot.IsPhysicallyActive)
181 DetailLog(
"{0},BSLinksetCompound.UpdateProperties,notPhysical", LinksetRoot.LocalID);
191 if (!IsRoot(updated) && m_physicsScene.TerrainManager.IsWithinKnownTerrain(LinksetRoot.RawPosition))
198 bool updatedChild =
false;
204 if (!RebuildScheduled
205 && !LinksetRoot.IsIncomplete
206 && LinksetRoot.PhysShape.HasPhysicalShape
207 && m_physicsScene.PE.IsCompound(LinksetRoot.PhysShape.physShapeInfo))
214 int numLinksetChildren = m_physicsScene.PE.GetNumberOfCompoundChildren(LinksetRoot.PhysShape.physShapeInfo);
217 BulletShape linksetChildShape = m_physicsScene.PE.GetChildShapeFromCompoundShapeIndex(LinksetRoot.PhysShape.physShapeInfo, updated.LinksetChildIndex);
221 m_physicsScene.PE.UpdateChildTransform(LinksetRoot.PhysShape.physShapeInfo, updated.LinksetChildIndex,
222 updated.RawPosition - LinksetRoot.RawPosition,
223 updated.RawOrientation * OMV.Quaternion.Inverse(LinksetRoot.RawOrientation),
226 DetailLog(
"{0},BSLinksetCompound.UpdateProperties,changeChildPosRot,whichUpdated={1},pos={2},rot={3}",
231 DetailLog(
"{0},BSLinksetCompound.UpdateProperties,couldNotUpdateChild,noChildShape,shape={1}",
232 updated.
LocalID, linksetChildShape);
238 DetailLog(
"{0},BSLinksetCompound.UpdateProperties,couldNotUpdateChild,childNotInCompoundShape,numChildren={1},index={2}",
244 DetailLog(
"{0},BSLinksetCompound.UpdateProperties,couldNotUpdateChild,noBodyOrNotCompound", updated.
LocalID);
253 DetailLog(
"{0},BSLinksetCompound.UpdateProperties,couldNotUpdateChild.schedulingRebuild,whichUpdated={1}",
254 updated.
LocalID, whichUpdated);
270 DetailLog(
"{0},BSLinksetCompound.RemoveDependencies,refreshIfChild,rID={1},rBody={2},isRoot={3}",
271 child.
LocalID, LinksetRoot.LocalID, LinksetRoot.PhysBody, IsRoot(child));
284 if (!HasChild(child))
288 DetailLog(
"{0},BSLinksetCompound.AddChildToLinkset,call,child={1}", LinksetRoot.LocalID, child.LocalID);
300 child.ClearDisplacement();
302 if (m_children.Remove(child))
304 DetailLog(
"{0},BSLinksetCompound.RemoveChildFromLinkset,call,rID={1},rBody={2},cID={3},cBody={4}",
306 LinksetRoot.LocalID, LinksetRoot.PhysBody.AddrString,
310 child.ForceBodyShapeRebuild(inTaintTime);
315 LinksetRoot.ForceBodyShapeRebuild(inTaintTime);
320 Refresh(LinksetRoot);
331 private bool UseBulletSimRootOffsetHack =
false;
332 private void RecomputeLinksetCompound()
344 LinksetRoot.ForceBodyShapeRebuild(
true);
347 if (!LinksetRoot.IsPhysicallyActive || !HasAnyChildren)
349 DetailLog(
"{0},BSLinksetCompound.RecomputeLinksetCompound,notPhysicalOrNoChildren", LinksetRoot.LocalID);
354 BSShape linksetShape = BSShapeCompound.GetReference(m_physicsScene);
358 OMV.Vector3 centerOfMassW = ComputeLinksetCenterOfMass();
360 OMV.Quaternion invRootOrientation = OMV.Quaternion.Normalize(OMV.Quaternion.Inverse(LinksetRoot.RawOrientation));
361 OMV.Vector3 origRootPosition = LinksetRoot.RawPosition;
364 OMV.Vector3 centerDisplacementV = (centerOfMassW - LinksetRoot.RawPosition) * invRootOrientation;
365 if (UseBulletSimRootOffsetHack || !BSParam.LinksetOffsetCenterOfMass)
368 centerDisplacementV = OMV.Vector3.Zero;
369 LinksetRoot.ClearDisplacement();
374 centerDisplacementV = LinksetRoot.SetEffectiveCenterOfMassDisplacement(centerDisplacementV);
377 DetailLog(
"{0},BSLinksetCompound.RecomputeLinksetCompound,COM,rootPos={1},com={2},comDisp={3}",
378 LinksetRoot.LocalID, origRootPosition, centerOfMassW, centerDisplacementV);
382 ForEachMember((cPrim) =>
387 cPrim.LinksetChildIndex = 0;
391 cPrim.LinksetChildIndex = memberIndex;
396 BSShape childShape = cPrim.PhysShape.GetReference(m_physicsScene, cPrim);
399 OMV.Vector3 offsetPos = (cPrim.RawPosition - origRootPosition) * invRootOrientation - centerDisplacementV;
400 OMV.Quaternion offsetRot = OMV.Quaternion.Normalize(cPrim.RawOrientation) * invRootOrientation;
403 if (childShape.physShapeInfo.HasPhysicalShape)
405 m_physicsScene.PE.AddChildShapeToCompoundShape(linksetShape.physShapeInfo, childShape.physShapeInfo, offsetPos, offsetRot);
406 DetailLog(
"{0},BSLinksetCompound.RecomputeLinksetCompound,addChild,indx={1},cShape={2},offPos={3},offRot={4}",
407 LinksetRoot.LocalID, cPrim.LinksetChildIndex, childShape, offsetPos, offsetRot);
412 m_physicsScene.PE.AddToCollisionFlags(cPrim.PhysBody, CollisionFlags.CF_NO_CONTACT_RESPONSE);
413 m_physicsScene.PE.ForceActivationState(cPrim.PhysBody, ActivationState.DISABLE_SIMULATION);
415 m_physicsScene.PE.RemoveFromCollisionFlags(cPrim.PhysBody, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS);
416 cPrim.PhysBody.collisionType = CollisionType.LinksetChild;
427 InternalScheduleRebuild(LinksetRoot);
428 DetailLog(
"{0},BSLinksetCompound.RecomputeLinksetCompound,addChildWithNoShape,indx={1},cShape={2},offPos={3},offRot={4}",
429 LinksetRoot.LocalID, cPrim.LinksetChildIndex, childShape, offsetPos, offsetRot);
432 m_physicsScene.Logger.WarnFormat(
"{0} Linkset rebuild warning. If this happens more than one or two times, please report in Mantis 7191", LogHeader);
433 m_physicsScene.Logger.WarnFormat(
"{0} pName={1}, childIdx={2}, shape={3}",
434 LogHeader, LinksetRoot.Name, cPrim.LinksetChildIndex, childShape);
446 LinksetRoot.PhysShape.Dereference(m_physicsScene);
447 LinksetRoot.PhysShape = linksetShape;
448 m_physicsScene.PE.RemoveObjectFromWorld(m_physicsScene.World, LinksetRoot.PhysBody);
449 m_physicsScene.PE.SetCollisionShape(m_physicsScene.World, LinksetRoot.PhysBody, linksetShape.physShapeInfo);
450 m_physicsScene.PE.AddObjectToWorld(m_physicsScene.World, LinksetRoot.PhysBody);
451 DetailLog(
"{0},BSLinksetCompound.RecomputeLinksetCompound,addBody,body={1},shape={2}",
452 LinksetRoot.LocalID, LinksetRoot.PhysBody, linksetShape);
455 LinksetMass = ComputeLinksetMass();
456 LinksetRoot.UpdatePhysicalMassProperties(LinksetMass,
true);
458 if (UseBulletSimRootOffsetHack)
465 m_physicsScene.PE.AddToCollisionFlags(LinksetRoot.PhysBody, CollisionFlags.BS_RETURN_ROOT_COMPOUND_SHAPE);
474 m_physicsScene.PE.RecalculateCompoundShapeLocalAabb(LinksetRoot.PhysShape.physShapeInfo);
override void SetPhysicalGravity(OMV.Vector3 gravity)
override void Refresh(BSPrimLinkable requestor)
override bool MakeStatic(BSPrimLinkable child)
override void SetPhysicalCollisionFlags(CollisionFlags collFlags)
override bool RemoveDependencies(BSPrimLinkable child)
override void AddChildToLinkset(BSPrimLinkable child)
virtual OMV.Quaternion RawOrientation
virtual bool HasPhysicalShape
override void SetPhysicalRestitution(float restitution)
override void RemoveFromPhysicalCollisionFlags(CollisionFlags collFlags)
override bool MakeDynamic(BSPrimLinkable child)
override void AddToPhysicalCollisionFlags(CollisionFlags collFlags)
BSLinksetCompound(BSScene scene, BSPrimLinkable parent)
override void SetPhysicalFriction(float friction)
override void UpdateProperties(UpdatedProperties whichUpdated, BSPrimLinkable updated)
virtual string AddrString
override void ComputeAndSetLocalInertia(OMV.Vector3 inertiaFactor, float linksetMass)
override void RemoveChildFromLinkset(BSPrimLinkable child, bool inTaintTime)
virtual OMV.Vector3 RawPosition