();
- LinksetMass = parent.RawMass;
- Rebuilding = false;
- }
-
- // Link to a linkset where the child knows the parent.
- // Parent changing should not happen so do some sanity checking.
- // We return the parent's linkset so the child can track its membership.
- // Called at runtime.
- public BSLinkset AddMeToLinkset(BSPhysObject child)
- {
- lock (m_linksetActivityLock)
- {
- // Don't add the root to its own linkset
- if (!IsRoot(child))
- AddChildToLinkset(child);
- LinksetMass = ComputeLinksetMass();
- }
- return this;
- }
-
- // Remove a child from a linkset.
- // Returns a new linkset for the child which is a linkset of one (just the
- // orphened child).
- // Called at runtime.
- public BSLinkset RemoveMeFromLinkset(BSPhysObject child)
- {
- lock (m_linksetActivityLock)
- {
- if (IsRoot(child))
- {
- // Cannot remove the root from a linkset.
- return this;
- }
- RemoveChildFromLinkset(child);
- LinksetMass = ComputeLinksetMass();
- }
-
- // The child is down to a linkset of just itself
- return BSLinkset.Factory(PhysicsScene, child);
- }
-
- // Return 'true' if the passed object is the root object of this linkset
- public bool IsRoot(BSPhysObject requestor)
- {
- return (requestor.LocalID == LinksetRoot.LocalID);
- }
-
- public int NumberOfChildren { get { return m_children.Count; } }
-
- // Return 'true' if this linkset has any children (more than the root member)
- public bool HasAnyChildren { get { return (m_children.Count > 0); } }
-
- // Return 'true' if this child is in this linkset
- public bool HasChild(BSPhysObject child)
- {
- bool ret = false;
- lock (m_linksetActivityLock)
- {
- ret = m_children.Contains(child);
- /* Safer version but the above should work
- foreach (BSPhysObject bp in m_children)
- {
- if (child.LocalID == bp.LocalID)
- {
- ret = true;
- break;
- }
- }
- */
- }
- return ret;
- }
-
- // Perform an action on each member of the linkset including root prim.
- // Depends on the action on whether this should be done at taint time.
- public delegate bool ForEachMemberAction(BSPhysObject obj);
- public virtual bool ForEachMember(ForEachMemberAction action)
- {
- bool ret = false;
- lock (m_linksetActivityLock)
- {
- action(LinksetRoot);
- foreach (BSPhysObject po in m_children)
- {
- if (action(po))
- break;
- }
- }
- return ret;
- }
-
- // I am the root of a linkset and a new child is being added
- // Called while LinkActivity is locked.
- protected abstract void AddChildToLinkset(BSPhysObject child);
-
- // I am the root of a linkset and one of my children is being removed.
- // Safe to call even if the child is not really in my linkset.
- protected abstract void RemoveChildFromLinkset(BSPhysObject child);
-
- // When physical properties are changed the linkset needs to recalculate
- // its internal properties.
- // May be called at runtime or taint-time.
- public virtual void Refresh(BSPhysObject requestor)
- {
- LinksetMass = ComputeLinksetMass();
- }
-
- // Flag denoting the linkset is in the process of being rebuilt.
- // Used to know not the schedule a rebuild in the middle of a rebuild.
- protected bool Rebuilding { get; set; }
-
- // The object is going dynamic (physical). Do any setup necessary
- // for a dynamic linkset.
- // Only the state of the passed object can be modified. The rest of the linkset
- // has not yet been fully constructed.
- // Return 'true' if any properties updated on the passed object.
- // Called at taint-time!
- public abstract bool MakeDynamic(BSPhysObject child);
-
- // The object is going static (non-physical). Do any setup necessary
- // for a static linkset.
- // Return 'true' if any properties updated on the passed object.
- // Called at taint-time!
- public abstract bool MakeStatic(BSPhysObject child);
-
- // Called when a parameter update comes from the physics engine for any object
- // of the linkset is received.
- // Passed flag is update came from physics engine (true) or the user (false).
- // Called at taint-time!!
- public abstract void UpdateProperties(BSPhysObject physObject, bool physicalUpdate);
-
- // Routine used when rebuilding the body of the root of the linkset
- // Destroy all the constraints have have been made to root.
- // This is called when the root body is changing.
- // Returns 'true' of something was actually removed and would need restoring
- // Called at taint-time!!
- public abstract bool RemoveBodyDependencies(BSPrim child);
-
- // Companion to RemoveBodyDependencies(). If RemoveBodyDependencies() returns 'true',
- // this routine will restore the removed constraints.
- // Called at taint-time!!
- public abstract void RestoreBodyDependencies(BSPrim child);
-
- // ================================================================
- protected virtual float ComputeLinksetMass()
- {
- float mass = LinksetRoot.RawMass;
- if (HasAnyChildren)
- {
- lock (m_linksetActivityLock)
- {
- foreach (BSPhysObject bp in m_children)
- {
- mass += bp.RawMass;
- }
- }
- }
- return mass;
- }
-
- protected virtual OMV.Vector3 ComputeLinksetCenterOfMass()
- {
- OMV.Vector3 com;
- lock (m_linksetActivityLock)
- {
- com = LinksetRoot.Position * LinksetRoot.RawMass;
- float totalMass = LinksetRoot.RawMass;
-
- foreach (BSPhysObject bp in m_children)
- {
- com += bp.Position * bp.RawMass;
- totalMass += bp.RawMass;
- }
- if (totalMass != 0f)
- com /= totalMass;
- }
-
- return com;
- }
-
- protected virtual OMV.Vector3 ComputeLinksetGeometricCenter()
- {
- OMV.Vector3 com;
- lock (m_linksetActivityLock)
- {
- com = LinksetRoot.Position;
-
- foreach (BSPhysObject bp in m_children)
- {
- com += bp.Position * bp.RawMass;
- }
- com /= (m_children.Count + 1);
- }
-
- return com;
- }
-
- // Invoke the detailed logger and output something if it's enabled.
- protected void DetailLog(string msg, params Object[] args)
- {
- if (PhysicsScene.PhysicsLogging.Enabled)
- PhysicsScene.DetailLog(msg, args);
- }
-
-}
-}
diff --git a/OpenSim/Region/Physics/BulletSNPlugin/BSLinksetCompound.cs b/OpenSim/Region/Physics/BulletSNPlugin/BSLinksetCompound.cs
deleted file mode 100644
index 9a977e6ad2..0000000000
--- a/OpenSim/Region/Physics/BulletSNPlugin/BSLinksetCompound.cs
+++ /dev/null
@@ -1,397 +0,0 @@
-/*
- * Copyright (c) Contributors, http://opensimulator.org/
- * See CONTRIBUTORS.TXT for a full list of copyright holders.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyrightD
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * * Neither the name of the OpenSimulator Project nor the
- * names of its contributors may be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-using System;
-using System.Collections.Generic;
-using System.Text;
-
-using OpenSim.Framework;
-
-using OMV = OpenMetaverse;
-
-namespace OpenSim.Region.Physics.BulletSNPlugin
-{
-
-// When a child is linked, the relationship position of the child to the parent
-// is remembered so the child's world position can be recomputed when it is
-// removed from the linkset.
-sealed class BSLinksetCompoundInfo : BSLinksetInfo
-{
- public OMV.Vector3 OffsetPos;
- public OMV.Quaternion OffsetRot;
- public BSLinksetCompoundInfo(OMV.Vector3 p, OMV.Quaternion r)
- {
- OffsetPos = p;
- OffsetRot = r;
- }
- public override void Clear()
- {
- OffsetPos = OMV.Vector3.Zero;
- OffsetRot = OMV.Quaternion.Identity;
- }
- public override string ToString()
- {
- StringBuilder buff = new StringBuilder();
- buff.Append("");
- return buff.ToString();
- }
-};
-
-public sealed class BSLinksetCompound : BSLinkset
-{
- private static string LogHeader = "[BULLETSIM LINKSET COMPOUND]";
-
- public BSLinksetCompound(BSScene scene, BSPhysObject parent) : base(scene, parent)
- {
- }
-
- // For compound implimented linksets, if there are children, use compound shape for the root.
- public override BSPhysicsShapeType PreferredPhysicalShape(BSPhysObject requestor)
- {
- // Returning 'unknown' means we don't have a preference.
- BSPhysicsShapeType ret = BSPhysicsShapeType.SHAPE_UNKNOWN;
- if (IsRoot(requestor) && HasAnyChildren)
- {
- ret = BSPhysicsShapeType.SHAPE_COMPOUND;
- }
- // DetailLog("{0},BSLinksetCompound.PreferredPhysicalShape,call,shape={1}", LinksetRoot.LocalID, ret);
- return ret;
- }
-
- // When physical properties are changed the linkset needs to recalculate
- // its internal properties.
- public override void Refresh(BSPhysObject requestor)
- {
- base.Refresh(requestor);
-
- // Something changed so do the rebuilding thing
- // ScheduleRebuild();
- }
-
- // Schedule a refresh to happen after all the other taint processing.
- private void ScheduleRebuild(BSPhysObject requestor)
- {
- DetailLog("{0},BSLinksetCompound.ScheduleRebuild,,rebuilding={1}",
- requestor.LocalID, Rebuilding);
- // When rebuilding, it is possible to set properties that would normally require a rebuild.
- // If already rebuilding, don't request another rebuild.
- if (!Rebuilding)
- {
- PhysicsScene.PostTaintObject("BSLinksetCompound.ScheduleRebuild", LinksetRoot.LocalID, delegate()
- {
- if (HasAnyChildren)
- RecomputeLinksetCompound();
- });
- }
- }
-
- // The object is going dynamic (physical). Do any setup necessary
- // for a dynamic linkset.
- // Only the state of the passed object can be modified. The rest of the linkset
- // has not yet been fully constructed.
- // Return 'true' if any properties updated on the passed object.
- // Called at taint-time!
- public override bool MakeDynamic(BSPhysObject child)
- {
- bool ret = false;
- DetailLog("{0},BSLinksetCompound.MakeDynamic,call,IsRoot={1}", child.LocalID, IsRoot(child));
- if (IsRoot(child))
- {
- // The root is going dynamic. Make sure mass is properly set.
- ScheduleRebuild(LinksetRoot);
- }
- else
- {
- // The origional prims are removed from the world as the shape of the root compound
- // shape takes over.
- BulletSimAPI.AddToCollisionFlags2(child.PhysBody.ptr, CollisionFlags.CF_NO_CONTACT_RESPONSE);
- BulletSimAPI.ForceActivationState2(child.PhysBody.ptr, ActivationState.DISABLE_SIMULATION);
- // We don't want collisions from the old linkset children.
- BulletSimAPI.RemoveFromCollisionFlags2(child.PhysBody.ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS);
-
- child.PhysBody.collisionType = CollisionType.LinksetChild;
-
- ret = true;
- }
- return ret;
- }
-
- // The object is going static (non-physical). Do any setup necessary for a static linkset.
- // Return 'true' if any properties updated on the passed object.
- // This doesn't normally happen -- OpenSim removes the objects from the physical
- // world if it is a static linkset.
- // Called at taint-time!
- public override bool MakeStatic(BSPhysObject child)
- {
- bool ret = false;
- DetailLog("{0},BSLinksetCompound.MakeStatic,call,IsRoot={1}", child.LocalID, IsRoot(child));
- if (IsRoot(child))
- {
- ScheduleRebuild(LinksetRoot);
- }
- else
- {
- // The non-physical children can come back to life.
- BulletSimAPI.RemoveFromCollisionFlags2(child.PhysBody.ptr, CollisionFlags.CF_NO_CONTACT_RESPONSE);
-
- child.PhysBody.collisionType = CollisionType.LinksetChild;
-
- // Don't force activation so setting of DISABLE_SIMULATION can stay if used.
- BulletSimAPI.Activate2(child.PhysBody.ptr, false);
- ret = true;
- }
- return ret;
- }
-
- public override void UpdateProperties(BSPhysObject updated, bool physicalUpdate)
- {
- // The user moving a child around requires the rebuilding of the linkset compound shape
- // One problem is this happens when a border is crossed -- the simulator implementation
- // is to store the position into the group which causes the move of the object
- // but it also means all the child positions get updated.
- // What would cause an unnecessary rebuild so we make sure the linkset is in a
- // region before bothering to do a rebuild.
- if (!IsRoot(updated)
- && !physicalUpdate
- && PhysicsScene.TerrainManager.IsWithinKnownTerrain(LinksetRoot.RawPosition))
- {
- updated.LinksetInfo = null;
- ScheduleRebuild(updated);
- }
- }
-
- // Routine called when rebuilding the body of some member of the linkset.
- // Since we don't keep in world relationships, do nothing unless it's a child changing.
- // Returns 'true' of something was actually removed and would need restoring
- // Called at taint-time!!
- public override bool RemoveBodyDependencies(BSPrim child)
- {
- bool ret = false;
-
- DetailLog("{0},BSLinksetCompound.RemoveBodyDependencies,refreshIfChild,rID={1},rBody={2},isRoot={3}",
- child.LocalID, LinksetRoot.LocalID, LinksetRoot.PhysBody.ptr.ToString(), IsRoot(child));
-
- if (!IsRoot(child))
- {
- // Because it is a convenient time, recompute child world position and rotation based on
- // its position in the linkset.
- RecomputeChildWorldPosition(child, true);
- }
-
- // Cannot schedule a refresh/rebuild here because this routine is called when
- // the linkset is being rebuilt.
- // InternalRefresh(LinksetRoot);
-
- return ret;
- }
-
- // Companion to RemoveBodyDependencies(). If RemoveBodyDependencies() returns 'true',
- // this routine will restore the removed constraints.
- // Called at taint-time!!
- public override void RestoreBodyDependencies(BSPrim child)
- {
- }
-
- // When the linkset is built, the child shape is added to the compound shape relative to the
- // root shape. The linkset then moves around but this does not move the actual child
- // prim. The child prim's location must be recomputed based on the location of the root shape.
- private void RecomputeChildWorldPosition(BSPhysObject child, bool inTaintTime)
- {
- BSLinksetCompoundInfo lci = child.LinksetInfo as BSLinksetCompoundInfo;
- if (lci != null)
- {
- if (inTaintTime)
- {
- OMV.Vector3 oldPos = child.RawPosition;
- child.ForcePosition = LinksetRoot.RawPosition + lci.OffsetPos;
- child.ForceOrientation = LinksetRoot.RawOrientation * lci.OffsetRot;
- DetailLog("{0},BSLinksetCompound.RecomputeChildWorldPosition,oldPos={1},lci={2},newPos={3}",
- child.LocalID, oldPos, lci, child.RawPosition);
- }
- else
- {
- // TaintedObject is not used here so the raw position is set now and not at taint-time.
- child.Position = LinksetRoot.RawPosition + lci.OffsetPos;
- child.Orientation = LinksetRoot.RawOrientation * lci.OffsetRot;
- }
- }
- else
- {
- // This happens when children have been added to the linkset but the linkset
- // has not been constructed yet. So like, at taint time, adding children to a linkset
- // and then changing properties of the children (makePhysical, for instance)
- // but the post-print action of actually rebuilding the linkset has not yet happened.
- // PhysicsScene.Logger.WarnFormat("{0} Restoring linkset child position failed because of no relative position computed. ID={1}",
- // LogHeader, child.LocalID);
- DetailLog("{0},BSLinksetCompound.recomputeChildWorldPosition,noRelativePositonInfo", child.LocalID);
- }
- }
-
- // ================================================================
-
- // Add a new child to the linkset.
- // Called while LinkActivity is locked.
- protected override void AddChildToLinkset(BSPhysObject child)
- {
- if (!HasChild(child))
- {
- m_children.Add(child);
-
- DetailLog("{0},BSLinksetCompound.AddChildToLinkset,call,child={1}", LinksetRoot.LocalID, child.LocalID);
-
- // Rebuild the compound shape with the new child shape included
- ScheduleRebuild(child);
- }
- return;
- }
-
- // Remove the specified child from the linkset.
- // Safe to call even if the child is not really in the linkset.
- protected override void RemoveChildFromLinkset(BSPhysObject child)
- {
- if (m_children.Remove(child))
- {
- DetailLog("{0},BSLinksetCompound.RemoveChildFromLinkset,call,rID={1},rBody={2},cID={3},cBody={4}",
- child.LocalID,
- LinksetRoot.LocalID, LinksetRoot.PhysBody.ptr.ToString(),
- child.LocalID, child.PhysBody.ptr.ToString());
-
- // Cause the child's body to be rebuilt and thus restored to normal operation
- RecomputeChildWorldPosition(child, false);
- child.ForceBodyShapeRebuild(false);
-
- if (!HasAnyChildren)
- {
- // The linkset is now empty. The root needs rebuilding.
- LinksetRoot.ForceBodyShapeRebuild(false);
- }
- else
- {
- // Rebuild the compound shape with the child removed
- ScheduleRebuild(child);
- }
- }
- return;
- }
-
- // Called before the simulation step to make sure the compound based linkset
- // is all initialized.
- // Constraint linksets are rebuilt every time.
- // Note that this works for rebuilding just the root after a linkset is taken apart.
- // Called at taint time!!
- private void RecomputeLinksetCompound()
- {
- try
- {
- // Suppress rebuilding while rebuilding
- Rebuilding = true;
-
- // Cause the root shape to be rebuilt as a compound object with just the root in it
- LinksetRoot.ForceBodyShapeRebuild(true);
-
- DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,start,rBody={1},rShape={2},numChildren={3}",
- LinksetRoot.LocalID, LinksetRoot.PhysBody, LinksetRoot.PhysShape, NumberOfChildren);
-
- // Add a shape for each of the other children in the linkset
- ForEachMember(delegate(BSPhysObject cPrim)
- {
- if (!IsRoot(cPrim))
- {
- // Compute the displacement of the child from the root of the linkset.
- // This info is saved in the child prim so the relationship does not
- // change over time and the new child position can be computed
- // when the linkset is being disassembled (the linkset may have moved).
- BSLinksetCompoundInfo lci = cPrim.LinksetInfo as BSLinksetCompoundInfo;
- if (lci == null)
- {
- // Each child position and rotation is given relative to the root.
- OMV.Quaternion invRootOrientation = OMV.Quaternion.Inverse(LinksetRoot.RawOrientation);
- OMV.Vector3 displacementPos = (cPrim.RawPosition - LinksetRoot.RawPosition) * invRootOrientation;
- OMV.Quaternion displacementRot = cPrim.RawOrientation * invRootOrientation;
-
- // Save relative position for recomputing child's world position after moving linkset.
- lci = new BSLinksetCompoundInfo(displacementPos, displacementRot);
- cPrim.LinksetInfo = lci;
- DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,creatingRelPos,lci={1}", cPrim.LocalID, lci);
- }
-
- DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,addMemberToShape,mID={1},mShape={2},dispPos={3},dispRot={4}",
- LinksetRoot.LocalID, cPrim.LocalID, cPrim.PhysShape, lci.OffsetPos, lci.OffsetRot);
-
- if (cPrim.PhysShape.isNativeShape)
- {
- // A native shape is turning into a hull collision shape because native
- // shapes are not shared so we have to hullify it so it will be tracked
- // and freed at the correct time. This also solves the scaling problem
- // (native shapes scaled but hull/meshes are assumed to not be).
- // TODO: decide of the native shape can just be used in the compound shape.
- // Use call to CreateGeomNonSpecial().
- BulletShape saveShape = cPrim.PhysShape;
- cPrim.PhysShape.Clear(); // Don't let the create free the child's shape
- // PhysicsScene.Shapes.CreateGeomNonSpecial(true, cPrim, null);
- PhysicsScene.Shapes.CreateGeomMeshOrHull(cPrim, null);
- BulletShape newShape = cPrim.PhysShape;
- cPrim.PhysShape = saveShape;
- BulletSimAPI.AddChildShapeToCompoundShape2(LinksetRoot.PhysShape.ptr, newShape.ptr, lci.OffsetPos, lci.OffsetRot);
- }
- else
- {
- // For the shared shapes (meshes and hulls), just use the shape in the child.
- // The reference count added here will be decremented when the compound shape
- // is destroyed in BSShapeCollection (the child shapes are looped over and dereferenced).
- if (PhysicsScene.Shapes.ReferenceShape(cPrim.PhysShape))
- {
- PhysicsScene.Logger.ErrorFormat("{0} Rebuilt sharable shape when building linkset! Region={1}, primID={2}, shape={3}",
- LogHeader, PhysicsScene.RegionName, cPrim.LocalID, cPrim.PhysShape);
- }
- BulletSimAPI.AddChildShapeToCompoundShape2(LinksetRoot.PhysShape.ptr, cPrim.PhysShape.ptr, lci.OffsetPos, lci.OffsetRot);
- }
- }
- return false; // 'false' says to move onto the next child in the list
- });
-
- // With all of the linkset packed into the root prim, it has the mass of everyone.
- LinksetMass = LinksetMass;
- LinksetRoot.UpdatePhysicalMassProperties(LinksetMass, true);
- }
- finally
- {
- Rebuilding = false;
- }
-
- BulletSimAPI.RecalculateCompoundShapeLocalAabb2(LinksetRoot.PhysShape.ptr);
-
- // DEBUG: see of inter-linkset collisions are causing problems for constraint linksets.
- // BulletSimAPI.SetCollisionFilterMask2(LinksetRoot.BSBody.ptr,
- // (uint)CollisionFilterGroups.LinksetFilter, (uint)CollisionFilterGroups.LinksetMask);
-
- }
-}
-}
\ No newline at end of file
diff --git a/OpenSim/Region/Physics/BulletSNPlugin/BSLinksetConstraints.cs b/OpenSim/Region/Physics/BulletSNPlugin/BSLinksetConstraints.cs
deleted file mode 100644
index 46ff99f98d..0000000000
--- a/OpenSim/Region/Physics/BulletSNPlugin/BSLinksetConstraints.cs
+++ /dev/null
@@ -1,316 +0,0 @@
-/*
- * Copyright (c) Contributors, http://opensimulator.org/
- * See CONTRIBUTORS.TXT for a full list of copyright holders.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyrightD
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * * Neither the name of the OpenSimulator Project nor the
- * names of its contributors may be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-using System;
-using System.Collections.Generic;
-using System.Text;
-
-using OMV = OpenMetaverse;
-
-namespace OpenSim.Region.Physics.BulletSNPlugin
-{
-public sealed class BSLinksetConstraints : BSLinkset
-{
- // private static string LogHeader = "[BULLETSIM LINKSET CONSTRAINTS]";
-
- public BSLinksetConstraints(BSScene scene, BSPhysObject parent) : base(scene, parent)
- {
- }
-
- // When physical properties are changed the linkset needs to recalculate
- // its internal properties.
- // This is queued in the 'post taint' queue so the
- // refresh will happen once after all the other taints are applied.
- public override void Refresh(BSPhysObject requestor)
- {
- base.Refresh(requestor);
-
- // Queue to happen after all the other taint processing
- PhysicsScene.PostTaintObject("BSLinksetContraints.Refresh", requestor.LocalID, delegate()
- {
- if (HasAnyChildren && IsRoot(requestor))
- RecomputeLinksetConstraints();
- });
- }
-
- // The object is going dynamic (physical). Do any setup necessary
- // for a dynamic linkset.
- // Only the state of the passed object can be modified. The rest of the linkset
- // has not yet been fully constructed.
- // Return 'true' if any properties updated on the passed object.
- // Called at taint-time!
- public override bool MakeDynamic(BSPhysObject child)
- {
- // What is done for each object in BSPrim is what we want.
- return false;
- }
-
- // The object is going static (non-physical). Do any setup necessary for a static linkset.
- // Return 'true' if any properties updated on the passed object.
- // This doesn't normally happen -- OpenSim removes the objects from the physical
- // world if it is a static linkset.
- // Called at taint-time!
- public override bool MakeStatic(BSPhysObject child)
- {
- // What is done for each object in BSPrim is what we want.
- return false;
- }
-
- // Called at taint-time!!
- public override void UpdateProperties(BSPhysObject updated, bool inTaintTime)
- {
- // Nothing to do for constraints on property updates
- }
-
- // Routine called when rebuilding the body of some member of the linkset.
- // Destroy all the constraints have have been made to root and set
- // up to rebuild the constraints before the next simulation step.
- // Returns 'true' of something was actually removed and would need restoring
- // Called at taint-time!!
- public override bool RemoveBodyDependencies(BSPrim child)
- {
- bool ret = false;
-
- DetailLog("{0},BSLinksetConstraint.RemoveBodyDependencies,removeChildrenForRoot,rID={1},rBody={2}",
- child.LocalID, LinksetRoot.LocalID, LinksetRoot.PhysBody.ptr.ToString());
-
- lock (m_linksetActivityLock)
- {
- // Just undo all the constraints for this linkset. Rebuild at the end of the step.
- ret = PhysicallyUnlinkAllChildrenFromRoot(LinksetRoot);
- // Cause the constraints, et al to be rebuilt before the next simulation step.
- Refresh(LinksetRoot);
- }
- return ret;
- }
-
- // Companion to RemoveBodyDependencies(). If RemoveBodyDependencies() returns 'true',
- // this routine will restore the removed constraints.
- // Called at taint-time!!
- public override void RestoreBodyDependencies(BSPrim child)
- {
- // The Refresh operation queued by RemoveBodyDependencies() will build any missing constraints.
- }
-
- // ================================================================
-
- // Add a new child to the linkset.
- // Called while LinkActivity is locked.
- protected override void AddChildToLinkset(BSPhysObject child)
- {
- if (!HasChild(child))
- {
- m_children.Add(child);
-
- DetailLog("{0},BSLinksetConstraints.AddChildToLinkset,call,child={1}", LinksetRoot.LocalID, child.LocalID);
-
- // Cause constraints and assorted properties to be recomputed before the next simulation step.
- Refresh(LinksetRoot);
- }
- return;
- }
-
- // Remove the specified child from the linkset.
- // Safe to call even if the child is not really in my linkset.
- protected override void RemoveChildFromLinkset(BSPhysObject child)
- {
- if (m_children.Remove(child))
- {
- BSPhysObject rootx = LinksetRoot; // capture the root and body as of now
- BSPhysObject childx = child;
-
- DetailLog("{0},BSLinksetConstraints.RemoveChildFromLinkset,call,rID={1},rBody={2},cID={3},cBody={4}",
- childx.LocalID,
- rootx.LocalID, rootx.PhysBody.ptr.ToString(),
- childx.LocalID, childx.PhysBody.ptr.ToString());
-
- PhysicsScene.TaintedObject("BSLinksetConstraints.RemoveChildFromLinkset", delegate()
- {
- PhysicallyUnlinkAChildFromRoot(rootx, childx);
- });
- // See that the linkset parameters are recomputed at the end of the taint time.
- Refresh(LinksetRoot);
- }
- else
- {
- // Non-fatal occurance.
- // PhysicsScene.Logger.ErrorFormat("{0}: Asked to remove child from linkset that was not in linkset", LogHeader);
- }
- return;
- }
-
- // Create a constraint between me (root of linkset) and the passed prim (the child).
- // Called at taint time!
- private void PhysicallyLinkAChildToRoot(BSPhysObject rootPrim, BSPhysObject childPrim)
- {
- // Don't build the constraint when asked. Put it off until just before the simulation step.
- Refresh(rootPrim);
- }
-
- private BSConstraint BuildConstraint(BSPhysObject rootPrim, BSPhysObject 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.ptr.ToString(),
- childPrim.LocalID, childPrim.PhysBody.ptr.ToString(),
- 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.BoolNumeric(BSParam.LinkConstraintUseFrameOffset));
- constrain.TranslationalLimitMotor(BSParam.BoolNumeric(BSParam.LinkConstraintEnableTransMotor),
- BSParam.LinkConstraintTransMotorMaxVel,
- BSParam.LinkConstraintTransMotorMaxForce);
- constrain.SetCFMAndERP(BSParam.LinkConstraintCFM, BSParam.LinkConstraintERP);
- if (BSParam.LinkConstraintSolverIterations != 0f)
- {
- constrain.SetSolverIterations(BSParam.LinkConstraintSolverIterations);
- }
- return constrain;
- }
-
- // Remove linkage between the linkset root and a particular child
- // The root and child bodies are passed in because we need to remove the constraint between
- // the bodies that were present at unlink time.
- // Called at taint time!
- private bool PhysicallyUnlinkAChildFromRoot(BSPhysObject rootPrim, BSPhysObject childPrim)
- {
- bool ret = false;
- DetailLog("{0},BSLinksetConstraint.PhysicallyUnlinkAChildFromRoot,taint,root={1},rBody={2},child={3},cBody={4}",
- rootPrim.LocalID,
- rootPrim.LocalID, rootPrim.PhysBody.ptr.ToString(),
- childPrim.LocalID, childPrim.PhysBody.ptr.ToString());
-
- // Find the constraint for this link and get rid of it from the overall collection and from my list
- if (PhysicsScene.Constraints.RemoveAndDestroyConstraint(rootPrim.PhysBody, childPrim.PhysBody))
- {
- // Make the child refresh its location
- BulletSimAPI.PushUpdate2(childPrim.PhysBody.ptr);
- ret = true;
- }
-
- return ret;
- }
-
- // Remove linkage between myself and any possible children I might have.
- // Returns 'true' of any constraints were destroyed.
- // Called at taint time!
- private bool PhysicallyUnlinkAllChildrenFromRoot(BSPhysObject rootPrim)
- {
- DetailLog("{0},BSLinksetConstraint.PhysicallyUnlinkAllChildren,taint", rootPrim.LocalID);
-
- return PhysicsScene.Constraints.RemoveAndDestroyConstraint(rootPrim.PhysBody);
- }
-
- // Call each of the constraints that make up this linkset and recompute the
- // various transforms and variables. Create constraints of not created yet.
- // Called before the simulation step to make sure the constraint based linkset
- // is all initialized.
- // Called at taint time!!
- private void RecomputeLinksetConstraints()
- {
- float linksetMass = LinksetMass;
- LinksetRoot.UpdatePhysicalMassProperties(linksetMass, true);
-
- // DEBUG: see of inter-linkset collisions are causing problems
- // BulletSimAPI.SetCollisionFilterMask2(LinksetRoot.BSBody.ptr,
- // (uint)CollisionFilterGroups.LinksetFilter, (uint)CollisionFilterGroups.LinksetMask);
- DetailLog("{0},BSLinksetConstraint.RecomputeLinksetConstraints,set,rBody={1},linksetMass={2}",
- LinksetRoot.LocalID, LinksetRoot.PhysBody.ptr.ToString(), linksetMass);
-
- foreach (BSPhysObject child in m_children)
- {
- // A child in the linkset physically shows the mass of the whole linkset.
- // This allows Bullet to apply enough force on the child to move the whole linkset.
- // (Also do the mass stuff before recomputing the constraint so mass is not zero.)
- child.UpdatePhysicalMassProperties(linksetMass, true);
-
- BSConstraint constrain;
- if (!PhysicsScene.Constraints.TryGetConstraint(LinksetRoot.PhysBody, child.PhysBody, out constrain))
- {
- // If constraint doesn't exist yet, create it.
- constrain = BuildConstraint(LinksetRoot, child);
- }
- constrain.RecomputeConstraintVariables(linksetMass);
-
- // DEBUG: see of inter-linkset collisions are causing problems
- // BulletSimAPI.SetCollisionFilterMask2(child.BSBody.ptr,
- // (uint)CollisionFilterGroups.LinksetFilter, (uint)CollisionFilterGroups.LinksetMask);
-
- // BulletSimAPI.DumpConstraint2(PhysicsScene.World.ptr, constrain.Constraint.ptr); // DEBUG DEBUG
- }
-
- }
-}
-}
diff --git a/OpenSim/Region/Physics/BulletSNPlugin/BSMaterials.cs b/OpenSim/Region/Physics/BulletSNPlugin/BSMaterials.cs
deleted file mode 100644
index d7941b6f1a..0000000000
--- a/OpenSim/Region/Physics/BulletSNPlugin/BSMaterials.cs
+++ /dev/null
@@ -1,200 +0,0 @@
-/*
- * Copyright (c) Contributors, http://opensimulator.org/
- * See CONTRIBUTORS.TXT for a full list of copyright holders.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyrightD
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * * Neither the name of the OpenSimulator Project nor the
- * names of its contributors may be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-using System;
-using System.Collections.Generic;
-using System.Text;
-using System.Reflection;
-using Nini.Config;
-
-namespace OpenSim.Region.Physics.BulletSNPlugin
-{
-
-public struct MaterialAttributes
-{
- // Material type values that correspond with definitions for LSL
- public enum Material : int
- {
- Stone = 0,
- Metal,
- Glass,
- Wood,
- Flesh,
- Plastic,
- Rubber,
- Light,
- // Hereafter are BulletSim additions
- Avatar,
- NumberOfTypes // the count of types in the enum.
- }
-
- // Names must be in the order of the above enum.
- // These names must coorespond to the lower case field names in the MaterialAttributes
- // structure as reflection is used to select the field to put the value in.
- public static readonly string[] MaterialAttribs = { "Density", "Friction", "Restitution"};
-
- public MaterialAttributes(string t, float d, float f, float r)
- {
- type = t;
- density = d;
- friction = f;
- restitution = r;
- }
- public string type;
- public float density;
- public float friction;
- public float restitution;
-}
-
-public static class BSMaterials
-{
- // Attributes for each material type
- private static readonly MaterialAttributes[] Attributes;
-
- // Map of material name to material type code
- public static readonly Dictionary MaterialMap;
-
- static BSMaterials()
- {
- // Attribute sets for both the non-physical and physical instances of materials.
- Attributes = new MaterialAttributes[(int)MaterialAttributes.Material.NumberOfTypes * 2];
-
- // Map of name to type code.
- MaterialMap = new Dictionary();
- MaterialMap.Add("Stone", MaterialAttributes.Material.Stone);
- MaterialMap.Add("Metal", MaterialAttributes.Material.Metal);
- MaterialMap.Add("Glass", MaterialAttributes.Material.Glass);
- MaterialMap.Add("Wood", MaterialAttributes.Material.Wood);
- MaterialMap.Add("Flesh", MaterialAttributes.Material.Flesh);
- MaterialMap.Add("Plastic", MaterialAttributes.Material.Plastic);
- MaterialMap.Add("Rubber", MaterialAttributes.Material.Rubber);
- MaterialMap.Add("Light", MaterialAttributes.Material.Light);
- MaterialMap.Add("Avatar", MaterialAttributes.Material.Avatar);
- }
-
- // This is where all the default material attributes are defined.
- public static void InitializeFromDefaults(ConfigurationParameters parms)
- {
- // Values from http://wiki.secondlife.com/wiki/PRIM_MATERIAL
- float dDensity = parms.defaultDensity;
- float dFriction = parms.defaultFriction;
- float dRestitution = parms.defaultRestitution;
- Attributes[(int)MaterialAttributes.Material.Stone] =
- new MaterialAttributes("stone",dDensity, 0.8f, 0.4f);
- Attributes[(int)MaterialAttributes.Material.Metal] =
- new MaterialAttributes("metal",dDensity, 0.3f, 0.4f);
- Attributes[(int)MaterialAttributes.Material.Glass] =
- new MaterialAttributes("glass",dDensity, 0.2f, 0.7f);
- Attributes[(int)MaterialAttributes.Material.Wood] =
- new MaterialAttributes("wood",dDensity, 0.6f, 0.5f);
- Attributes[(int)MaterialAttributes.Material.Flesh] =
- new MaterialAttributes("flesh",dDensity, 0.9f, 0.3f);
- Attributes[(int)MaterialAttributes.Material.Plastic] =
- new MaterialAttributes("plastic",dDensity, 0.4f, 0.7f);
- Attributes[(int)MaterialAttributes.Material.Rubber] =
- new MaterialAttributes("rubber",dDensity, 0.9f, 0.9f);
- Attributes[(int)MaterialAttributes.Material.Light] =
- new MaterialAttributes("light",dDensity, dFriction, dRestitution);
- Attributes[(int)MaterialAttributes.Material.Avatar] =
- new MaterialAttributes("avatar",3.5f, 0.2f, 0f);
-
- Attributes[(int)MaterialAttributes.Material.Stone + (int)MaterialAttributes.Material.NumberOfTypes] =
- new MaterialAttributes("stonePhysical",dDensity, 0.8f, 0.4f);
- Attributes[(int)MaterialAttributes.Material.Metal + (int)MaterialAttributes.Material.NumberOfTypes] =
- new MaterialAttributes("metalPhysical",dDensity, 0.3f, 0.4f);
- Attributes[(int)MaterialAttributes.Material.Glass + (int)MaterialAttributes.Material.NumberOfTypes] =
- new MaterialAttributes("glassPhysical",dDensity, 0.2f, 0.7f);
- Attributes[(int)MaterialAttributes.Material.Wood + (int)MaterialAttributes.Material.NumberOfTypes] =
- new MaterialAttributes("woodPhysical",dDensity, 0.6f, 0.5f);
- Attributes[(int)MaterialAttributes.Material.Flesh + (int)MaterialAttributes.Material.NumberOfTypes] =
- new MaterialAttributes("fleshPhysical",dDensity, 0.9f, 0.3f);
- Attributes[(int)MaterialAttributes.Material.Plastic + (int)MaterialAttributes.Material.NumberOfTypes] =
- new MaterialAttributes("plasticPhysical",dDensity, 0.4f, 0.7f);
- Attributes[(int)MaterialAttributes.Material.Rubber + (int)MaterialAttributes.Material.NumberOfTypes] =
- new MaterialAttributes("rubberPhysical",dDensity, 0.9f, 0.9f);
- Attributes[(int)MaterialAttributes.Material.Light + (int)MaterialAttributes.Material.NumberOfTypes] =
- new MaterialAttributes("lightPhysical",dDensity, dFriction, dRestitution);
- Attributes[(int)MaterialAttributes.Material.Avatar + (int)MaterialAttributes.Material.NumberOfTypes] =
- new MaterialAttributes("avatarPhysical",3.5f, 0.2f, 0f);
- }
-
- // Under the [BulletSim] section, one can change the individual material
- // attribute values. The format of the configuration parameter is:
- // ["Physical"] = floatValue
- // For instance:
- // [BulletSim]
- // StoneFriction = 0.2
- // FleshRestitutionPhysical = 0.8
- // Materials can have different parameters for their static and
- // physical instantiations. When setting the non-physical value,
- // both values are changed. Setting the physical value only changes
- // the physical value.
- public static void InitializefromParameters(IConfig pConfig)
- {
- foreach (KeyValuePair kvp in MaterialMap)
- {
- string matName = kvp.Key;
- foreach (string attribName in MaterialAttributes.MaterialAttribs)
- {
- string paramName = matName + attribName;
- if (pConfig.Contains(paramName))
- {
- float paramValue = pConfig.GetFloat(paramName);
- SetAttributeValue((int)kvp.Value, attribName, paramValue);
- // set the physical value also
- SetAttributeValue((int)kvp.Value + (int)MaterialAttributes.Material.NumberOfTypes, attribName, paramValue);
- }
- paramName += "Physical";
- if (pConfig.Contains(paramName))
- {
- float paramValue = pConfig.GetFloat(paramName);
- SetAttributeValue((int)kvp.Value + (int)MaterialAttributes.Material.NumberOfTypes, attribName, paramValue);
- }
- }
- }
- }
-
- // Use reflection to set the value in the attribute structure.
- private static void SetAttributeValue(int matType, string attribName, float val)
- {
- MaterialAttributes thisAttrib = Attributes[matType];
- FieldInfo fieldInfo = thisAttrib.GetType().GetField(attribName.ToLower());
- if (fieldInfo != null)
- {
- fieldInfo.SetValue(thisAttrib, val);
- Attributes[matType] = thisAttrib;
- }
- }
-
- // Given a material type, return a structure of attributes.
- public static MaterialAttributes GetAttributes(MaterialAttributes.Material type, bool isPhysical)
- {
- int ind = (int)type;
- if (isPhysical) ind += (int)MaterialAttributes.Material.NumberOfTypes;
- return Attributes[ind];
- }
-}
-}
diff --git a/OpenSim/Region/Physics/BulletSNPlugin/BSMotors.cs b/OpenSim/Region/Physics/BulletSNPlugin/BSMotors.cs
deleted file mode 100644
index 7abc9b2b78..0000000000
--- a/OpenSim/Region/Physics/BulletSNPlugin/BSMotors.cs
+++ /dev/null
@@ -1,347 +0,0 @@
-/*
- * Copyright (c) Contributors, http://opensimulator.org/
- * See CONTRIBUTORS.TXT for a full list of copyright holders.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * * Neither the name of the OpenSimulator Project nor the
- * names of its contributors may be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-using System;
-using System.Collections.Generic;
-using System.Text;
-using OpenMetaverse;
-using OpenSim.Framework;
-
-namespace OpenSim.Region.Physics.BulletSNPlugin
-{
-public abstract class BSMotor
-{
- // Timescales and other things can be turned off by setting them to 'infinite'.
- public const float Infinite = 12345.6f;
- public readonly static Vector3 InfiniteVector = new Vector3(BSMotor.Infinite, BSMotor.Infinite, BSMotor.Infinite);
-
- public BSMotor(string useName)
- {
- UseName = useName;
- PhysicsScene = null;
- Enabled = true;
- }
- public virtual bool Enabled { get; set; }
- public virtual void Reset() { }
- public virtual void Zero() { }
- public virtual void GenerateTestOutput(float timeStep) { }
-
- // A name passed at motor creation for easily identifyable debugging messages.
- public string UseName { get; private set; }
-
- // Used only for outputting debug information. Might not be set so check for null.
- public BSScene PhysicsScene { get; set; }
- protected void MDetailLog(string msg, params Object[] parms)
- {
- if (PhysicsScene != null)
- {
- if (PhysicsScene.VehicleLoggingEnabled)
- {
- PhysicsScene.DetailLog(msg, parms);
- }
- }
- }
-}
-
-// Motor which moves CurrentValue to TargetValue over TimeScale seconds.
-// The TargetValue decays in TargetValueDecayTimeScale and
-// the CurrentValue will be held back by FrictionTimeScale.
-// This motor will "zero itself" over time in that the targetValue will
-// decay to zero and the currentValue will follow it to that zero.
-// The overall effect is for the returned correction value to go from large
-// values (the total difference between current and target minus friction)
-// to small and eventually zero values.
-// TimeScale and TargetDelayTimeScale may be 'infinite' which means no decay.
-
-// For instance, if something is moving at speed X and the desired speed is Y,
-// CurrentValue is X and TargetValue is Y. As the motor is stepped, new
-// values of CurrentValue are returned that approach the TargetValue.
-// The feature of decaying TargetValue is so vehicles will eventually
-// come to a stop rather than run forever. This can be disabled by
-// setting TargetValueDecayTimescale to 'infinite'.
-// The change from CurrentValue to TargetValue is linear over TimeScale seconds.
-public class BSVMotor : BSMotor
-{
- // public Vector3 FrameOfReference { get; set; }
- // public Vector3 Offset { get; set; }
-
- public virtual float TimeScale { get; set; }
- public virtual float TargetValueDecayTimeScale { get; set; }
- public virtual Vector3 FrictionTimescale { get; set; }
- public virtual float Efficiency { get; set; }
-
- public virtual float ErrorZeroThreshold { get; set; }
-
- public virtual Vector3 TargetValue { get; protected set; }
- public virtual Vector3 CurrentValue { get; protected set; }
- public virtual Vector3 LastError { get; protected set; }
-
- public virtual bool ErrorIsZero
- { get {
- return (LastError == Vector3.Zero || LastError.LengthSquared() <= ErrorZeroThreshold);
- }
- }
-
- public BSVMotor(string useName)
- : base(useName)
- {
- TimeScale = TargetValueDecayTimeScale = BSMotor.Infinite;
- Efficiency = 1f;
- FrictionTimescale = BSMotor.InfiniteVector;
- CurrentValue = TargetValue = Vector3.Zero;
- ErrorZeroThreshold = 0.001f;
- }
- public BSVMotor(string useName, float timeScale, float decayTimeScale, Vector3 frictionTimeScale, float efficiency)
- : this(useName)
- {
- TimeScale = timeScale;
- TargetValueDecayTimeScale = decayTimeScale;
- FrictionTimescale = frictionTimeScale;
- Efficiency = efficiency;
- CurrentValue = TargetValue = Vector3.Zero;
- }
- public void SetCurrent(Vector3 current)
- {
- CurrentValue = current;
- }
- public void SetTarget(Vector3 target)
- {
- TargetValue = target;
- }
- public override void Zero()
- {
- base.Zero();
- CurrentValue = TargetValue = Vector3.Zero;
- }
-
- // Compute the next step and return the new current value
- public virtual Vector3 Step(float timeStep)
- {
- if (!Enabled) return TargetValue;
-
- Vector3 origTarget = TargetValue; // DEBUG
- Vector3 origCurrVal = CurrentValue; // DEBUG
-
- Vector3 correction = Vector3.Zero;
- Vector3 error = TargetValue - CurrentValue;
- if (!error.ApproxEquals(Vector3.Zero, ErrorZeroThreshold))
- {
- correction = Step(timeStep, error);
-
- CurrentValue += correction;
-
- // The desired value reduces to zero which also reduces the difference with current.
- // If the decay time is infinite, don't decay at all.
- float decayFactor = 0f;
- if (TargetValueDecayTimeScale != BSMotor.Infinite)
- {
- decayFactor = (1.0f / TargetValueDecayTimeScale) * timeStep;
- TargetValue *= (1f - decayFactor);
- }
-
- // The amount we can correct the error is reduced by the friction
- Vector3 frictionFactor = Vector3.Zero;
- if (FrictionTimescale != BSMotor.InfiniteVector)
- {
- // frictionFactor = (Vector3.One / FrictionTimescale) * timeStep;
- // Individual friction components can be 'infinite' so compute each separately.
- frictionFactor.X = (FrictionTimescale.X == BSMotor.Infinite) ? 0f : (1f / FrictionTimescale.X);
- frictionFactor.Y = (FrictionTimescale.Y == BSMotor.Infinite) ? 0f : (1f / FrictionTimescale.Y);
- frictionFactor.Z = (FrictionTimescale.Z == BSMotor.Infinite) ? 0f : (1f / FrictionTimescale.Z);
- frictionFactor *= timeStep;
- CurrentValue *= (Vector3.One - frictionFactor);
- }
-
- MDetailLog("{0}, BSVMotor.Step,nonZero,{1},origCurr={2},origTarget={3},timeStep={4},err={5},corr={6}",
- BSScene.DetailLogZero, UseName, origCurrVal, origTarget,
- timeStep, error, correction);
- MDetailLog("{0}, BSVMotor.Step,nonZero,{1},tgtDecayTS={2},decayFact={3},frictTS={4},frictFact={5},tgt={6},curr={7}",
- BSScene.DetailLogZero, UseName,
- TargetValueDecayTimeScale, decayFactor, FrictionTimescale, frictionFactor,
- TargetValue, CurrentValue);
- }
- else
- {
- // Difference between what we have and target is small. Motor is done.
- CurrentValue = TargetValue;
- MDetailLog("{0}, BSVMotor.Step,zero,{1},origTgt={2},origCurr={3},ret={4}",
- BSScene.DetailLogZero, UseName, origCurrVal, origTarget, CurrentValue);
- }
-
- return CurrentValue;
- }
- public virtual Vector3 Step(float timeStep, Vector3 error)
- {
- if (!Enabled) return Vector3.Zero;
-
- LastError = error;
- Vector3 returnCorrection = Vector3.Zero;
- if (!error.ApproxEquals(Vector3.Zero, ErrorZeroThreshold))
- {
- // correction = error / secondsItShouldTakeToCorrect
- Vector3 correctionAmount;
- if (TimeScale == 0f || TimeScale == BSMotor.Infinite)
- correctionAmount = error * timeStep;
- else
- correctionAmount = error / TimeScale * timeStep;
-
- returnCorrection = correctionAmount;
- MDetailLog("{0}, BSVMotor.Step,nonZero,{1},timeStep={2},timeScale={3},err={4},corr={5}",
- BSScene.DetailLogZero, UseName, timeStep, TimeScale, error, correctionAmount);
- }
- return returnCorrection;
- }
-
- // The user sets all the parameters and calls this which outputs values until error is zero.
- public override void GenerateTestOutput(float timeStep)
- {
- // maximum number of outputs to generate.
- int maxOutput = 50;
- MDetailLog("{0},BSVMotor.Test,{1},===================================== BEGIN Test Output", BSScene.DetailLogZero, UseName);
- MDetailLog("{0},BSVMotor.Test,{1},timeScale={2},targDlyTS={3},frictTS={4},eff={5},curr={6},tgt={7}",
- BSScene.DetailLogZero, UseName,
- TimeScale, TargetValueDecayTimeScale, FrictionTimescale, Efficiency,
- CurrentValue, TargetValue);
-
- LastError = BSMotor.InfiniteVector;
- while (maxOutput-- > 0 && !LastError.ApproxEquals(Vector3.Zero, ErrorZeroThreshold))
- {
- Vector3 lastStep = Step(timeStep);
- MDetailLog("{0},BSVMotor.Test,{1},cur={2},tgt={3},lastError={4},lastStep={5}",
- BSScene.DetailLogZero, UseName, CurrentValue, TargetValue, LastError, lastStep);
- }
- MDetailLog("{0},BSVMotor.Test,{1},===================================== END Test Output", BSScene.DetailLogZero, UseName);
-
-
- }
-
- public override string ToString()
- {
- return String.Format("<{0},curr={1},targ={2},decayTS={3},frictTS={4}>",
- UseName, CurrentValue, TargetValue, TargetValueDecayTimeScale, FrictionTimescale);
- }
-}
-
-public class BSFMotor : BSMotor
-{
- public float TimeScale { get; set; }
- public float DecayTimeScale { get; set; }
- public float Friction { get; set; }
- public float Efficiency { get; set; }
-
- public float Target { get; private set; }
- public float CurrentValue { get; private set; }
-
- public BSFMotor(string useName, float timeScale, float decayTimescale, float friction, float efficiency)
- : base(useName)
- {
- }
- public void SetCurrent(float target)
- {
- }
- public void SetTarget(float target)
- {
- }
- public virtual float Step(float timeStep)
- {
- return 0f;
- }
-}
-
-// Proportional, Integral, Derivitive Motor
-// Good description at http://www.answers.com/topic/pid-controller . Includes processes for choosing p, i and d factors.
-public class BSPIDVMotor : BSVMotor
-{
- // Larger makes more overshoot, smaller means converge quicker. Range of 0.1 to 10.
- public Vector3 proportionFactor { get; set; }
- public Vector3 integralFactor { get; set; }
- public Vector3 derivFactor { get; set; }
-
- // Arbritrary factor range.
- // EfficiencyHigh means move quickly to the correct number. EfficiencyLow means might over correct.
- public float EfficiencyHigh = 0.4f;
- public float EfficiencyLow = 4.0f;
-
- // Running integration of the error
- Vector3 RunningIntegration { get; set; }
-
- public BSPIDVMotor(string useName)
- : base(useName)
- {
- proportionFactor = new Vector3(1.00f, 1.00f, 1.00f);
- integralFactor = new Vector3(1.00f, 1.00f, 1.00f);
- derivFactor = new Vector3(1.00f, 1.00f, 1.00f);
- RunningIntegration = Vector3.Zero;
- LastError = Vector3.Zero;
- }
-
- public override void Zero()
- {
- base.Zero();
- }
-
- public override float Efficiency
- {
- get { return base.Efficiency; }
- set
- {
- base.Efficiency = Util.Clamp(value, 0f, 1f);
- // Compute factors based on efficiency.
- // If efficiency is high (1f), use a factor value that moves the error value to zero with little overshoot.
- // If efficiency is low (0f), use a factor value that overcorrects.
- // TODO: might want to vary contribution of different factor depending on efficiency.
- float factor = ((1f - this.Efficiency) * EfficiencyHigh + EfficiencyLow) / 3f;
- // float factor = (1f - this.Efficiency) * EfficiencyHigh + EfficiencyLow;
- proportionFactor = new Vector3(factor, factor, factor);
- integralFactor = new Vector3(factor, factor, factor);
- derivFactor = new Vector3(factor, factor, factor);
- }
- }
-
- // Ignore Current and Target Values and just advance the PID computation on this error.
- public override Vector3 Step(float timeStep, Vector3 error)
- {
- if (!Enabled) return Vector3.Zero;
-
- // Add up the error so we can integrate over the accumulated errors
- RunningIntegration += error * timeStep;
-
- // A simple derivitive is the rate of change from the last error.
- Vector3 derivFactor = (error - LastError) * timeStep;
- LastError = error;
-
- // Correction = -(proportionOfPresentError + accumulationOfPastError + rateOfChangeOfError)
- Vector3 ret = -(
- error * proportionFactor
- + RunningIntegration * integralFactor
- + derivFactor * derivFactor
- );
-
- return ret;
- }
-}
-}
diff --git a/OpenSim/Region/Physics/BulletSNPlugin/BSParam.cs b/OpenSim/Region/Physics/BulletSNPlugin/BSParam.cs
deleted file mode 100644
index 5e93a0335a..0000000000
--- a/OpenSim/Region/Physics/BulletSNPlugin/BSParam.cs
+++ /dev/null
@@ -1,559 +0,0 @@
-/*
- * Copyright (c) Contributors, http://opensimulator.org/
- * See CONTRIBUTORS.TXT for a full list of copyright holders.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyrightD
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * * Neither the name of the OpenSimulator Project nor the
- * names of its contributors may be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-using System;
-using System.Collections.Generic;
-using System.Text;
-
-using OpenSim.Region.Physics.Manager;
-
-using OpenMetaverse;
-using Nini.Config;
-
-namespace OpenSim.Region.Physics.BulletSNPlugin
-{
-public static class BSParam
-{
- // Level of Detail values kept as float because that's what the Meshmerizer wants
- public static float MeshLOD { get; private set; }
- public static float MeshMegaPrimLOD { get; private set; }
- public static float MeshMegaPrimThreshold { get; private set; }
- public static float SculptLOD { get; private set; }
-
- public static float MinimumObjectMass { get; private set; }
- public static float MaximumObjectMass { get; private set; }
-
- public static float LinearDamping { get; private set; }
- public static float AngularDamping { get; private set; }
- public static float DeactivationTime { get; private set; }
- public static float LinearSleepingThreshold { get; private set; }
- public static float AngularSleepingThreshold { get; private set; }
- public static float CcdMotionThreshold { get; private set; }
- public static float CcdSweptSphereRadius { get; private set; }
- public static float ContactProcessingThreshold { get; private set; }
-
- public static bool ShouldMeshSculptedPrim { get; private set; } // cause scuplted prims to get meshed
- public static bool ShouldForceSimplePrimMeshing { get; private set; } // if a cube or sphere, let Bullet do internal shapes
- public static bool ShouldUseHullsForPhysicalObjects { get; private set; } // 'true' if should create hulls for physical objects
-
- public static float TerrainImplementation { get; private set; }
- public static float TerrainFriction { get; private set; }
- public static float TerrainHitFraction { get; private set; }
- public static float TerrainRestitution { get; private set; }
- public static float TerrainCollisionMargin { get; private set; }
-
- // Avatar parameters
- public static float AvatarFriction { get; private set; }
- public static float AvatarStandingFriction { get; private set; }
- public static float AvatarDensity { get; private set; }
- public static float AvatarRestitution { get; private set; }
- public static float AvatarCapsuleWidth { get; private set; }
- public static float AvatarCapsuleDepth { get; private set; }
- public static float AvatarCapsuleHeight { get; private set; }
- public static float AvatarContactProcessingThreshold { get; private set; }
-
- public static float VehicleAngularDamping { get; private set; }
-
- public static float LinksetImplementation { get; private set; }
- public static float LinkConstraintUseFrameOffset { get; private set; }
- public static float LinkConstraintEnableTransMotor { get; private set; }
- public static float LinkConstraintTransMotorMaxVel { get; private set; }
- public static float LinkConstraintTransMotorMaxForce { get; private set; }
- public static float LinkConstraintERP { get; private set; }
- public static float LinkConstraintCFM { get; private set; }
- public static float LinkConstraintSolverIterations { get; private set; }
-
- public static float PID_D { get; private set; } // derivative
- public static float PID_P { get; private set; } // proportional
-
- public delegate void ParamUser(BSScene scene, IConfig conf, string paramName, float val);
- public delegate float ParamGet(BSScene scene);
- public delegate void ParamSet(BSScene scene, string paramName, uint localID, float val);
- public delegate void SetOnObject(BSScene scene, BSPhysObject obj, float val);
-
- public struct ParameterDefn
- {
- public string name; // string name of the parameter
- public string desc; // a short description of what the parameter means
- public float defaultValue; // default value if not specified anywhere else
- public ParamUser userParam; // get the value from the configuration file
- public ParamGet getter; // return the current value stored for this parameter
- public ParamSet setter; // set the current value for this parameter
- public SetOnObject onObject; // set the value on an object in the physical domain
- public ParameterDefn(string n, string d, float v, ParamUser u, ParamGet g, ParamSet s)
- {
- name = n;
- desc = d;
- defaultValue = v;
- userParam = u;
- getter = g;
- setter = s;
- onObject = null;
- }
- public ParameterDefn(string n, string d, float v, ParamUser u, ParamGet g, ParamSet s, SetOnObject o)
- {
- name = n;
- desc = d;
- defaultValue = v;
- userParam = u;
- getter = g;
- setter = s;
- onObject = o;
- }
- }
-
- // List of all of the externally visible parameters.
- // For each parameter, this table maps a text name to getter and setters.
- // To add a new externally referencable/settable parameter, add the paramter storage
- // location somewhere in the program and make an entry in this table with the
- // getters and setters.
- // It is easiest to find an existing definition and copy it.
- // Parameter values are floats. Booleans are converted to a floating value.
- //
- // A ParameterDefn() takes the following parameters:
- // -- the text name of the parameter. This is used for console input and ini file.
- // -- a short text description of the parameter. This shows up in the console listing.
- // -- a default value (float)
- // -- a delegate for fetching the parameter from the ini file.
- // Should handle fetching the right type from the ini file and converting it.
- // -- a delegate for getting the value as a float
- // -- a delegate for setting the value from a float
- // -- an optional delegate to update the value in the world. Most often used to
- // push the new value to an in-world object.
- //
- // The single letter parameters for the delegates are:
- // s = BSScene
- // o = BSPhysObject
- // p = string parameter name
- // l = localID of referenced object
- // v = value (float)
- // cf = parameter configuration class (for fetching values from ini file)
- private static ParameterDefn[] ParameterDefinitions =
- {
- new ParameterDefn("MeshSculptedPrim", "Whether to create meshes for sculpties",
- ConfigurationParameters.numericTrue,
- (s,cf,p,v) => { ShouldMeshSculptedPrim = cf.GetBoolean(p, BSParam.BoolNumeric(v)); },
- (s) => { return BSParam.NumericBool(ShouldMeshSculptedPrim); },
- (s,p,l,v) => { ShouldMeshSculptedPrim = BSParam.BoolNumeric(v); } ),
- new ParameterDefn("ForceSimplePrimMeshing", "If true, only use primitive meshes for objects",
- ConfigurationParameters.numericFalse,
- (s,cf,p,v) => { ShouldForceSimplePrimMeshing = cf.GetBoolean(p, BSParam.BoolNumeric(v)); },
- (s) => { return BSParam.NumericBool(ShouldForceSimplePrimMeshing); },
- (s,p,l,v) => { ShouldForceSimplePrimMeshing = BSParam.BoolNumeric(v); } ),
- new ParameterDefn("UseHullsForPhysicalObjects", "If true, create hulls for physical objects",
- ConfigurationParameters.numericTrue,
- (s,cf,p,v) => { ShouldUseHullsForPhysicalObjects = cf.GetBoolean(p, BSParam.BoolNumeric(v)); },
- (s) => { return BSParam.NumericBool(ShouldUseHullsForPhysicalObjects); },
- (s,p,l,v) => { ShouldUseHullsForPhysicalObjects = BSParam.BoolNumeric(v); } ),
-
- new ParameterDefn("MeshLevelOfDetail", "Level of detail to render meshes (32, 16, 8 or 4. 32=most detailed)",
- 8f,
- (s,cf,p,v) => { MeshLOD = (float)cf.GetInt(p, (int)v); },
- (s) => { return MeshLOD; },
- (s,p,l,v) => { MeshLOD = v; } ),
- new ParameterDefn("MeshLevelOfDetailMegaPrim", "Level of detail to render meshes larger than threshold meters",
- 16f,
- (s,cf,p,v) => { MeshMegaPrimLOD = (float)cf.GetInt(p, (int)v); },
- (s) => { return MeshMegaPrimLOD; },
- (s,p,l,v) => { MeshMegaPrimLOD = v; } ),
- new ParameterDefn("MeshLevelOfDetailMegaPrimThreshold", "Size (in meters) of a mesh before using MeshMegaPrimLOD",
- 10f,
- (s,cf,p,v) => { MeshMegaPrimThreshold = (float)cf.GetInt(p, (int)v); },
- (s) => { return MeshMegaPrimThreshold; },
- (s,p,l,v) => { MeshMegaPrimThreshold = v; } ),
- new ParameterDefn("SculptLevelOfDetail", "Level of detail to render sculpties (32, 16, 8 or 4. 32=most detailed)",
- 32f,
- (s,cf,p,v) => { SculptLOD = (float)cf.GetInt(p, (int)v); },
- (s) => { return SculptLOD; },
- (s,p,l,v) => { SculptLOD = v; } ),
-
- new ParameterDefn("MaxSubStep", "In simulation step, maximum number of substeps",
- 10f,
- (s,cf,p,v) => { s.m_maxSubSteps = cf.GetInt(p, (int)v); },
- (s) => { return (float)s.m_maxSubSteps; },
- (s,p,l,v) => { s.m_maxSubSteps = (int)v; } ),
- new ParameterDefn("FixedTimeStep", "In simulation step, seconds of one substep (1/60)",
- 1f / 60f,
- (s,cf,p,v) => { s.m_fixedTimeStep = cf.GetFloat(p, v); },
- (s) => { return (float)s.m_fixedTimeStep; },
- (s,p,l,v) => { s.m_fixedTimeStep = v; } ),
- new ParameterDefn("MaxCollisionsPerFrame", "Max collisions returned at end of each frame",
- 2048f,
- (s,cf,p,v) => { s.m_maxCollisionsPerFrame = cf.GetInt(p, (int)v); },
- (s) => { return (float)s.m_maxCollisionsPerFrame; },
- (s,p,l,v) => { s.m_maxCollisionsPerFrame = (int)v; } ),
- new ParameterDefn("MaxUpdatesPerFrame", "Max updates returned at end of each frame",
- 8000f,
- (s,cf,p,v) => { s.m_maxUpdatesPerFrame = cf.GetInt(p, (int)v); },
- (s) => { return (float)s.m_maxUpdatesPerFrame; },
- (s,p,l,v) => { s.m_maxUpdatesPerFrame = (int)v; } ),
- new ParameterDefn("MaxTaintsToProcessPerStep", "Number of update taints to process before each simulation step",
- 500f,
- (s,cf,p,v) => { s.m_taintsToProcessPerStep = cf.GetInt(p, (int)v); },
- (s) => { return (float)s.m_taintsToProcessPerStep; },
- (s,p,l,v) => { s.m_taintsToProcessPerStep = (int)v; } ),
- new ParameterDefn("MinObjectMass", "Minimum object mass (0.0001)",
- 0.0001f,
- (s,cf,p,v) => { MinimumObjectMass = cf.GetFloat(p, v); },
- (s) => { return (float)MinimumObjectMass; },
- (s,p,l,v) => { MinimumObjectMass = v; } ),
- new ParameterDefn("MaxObjectMass", "Maximum object mass (10000.01)",
- 10000.01f,
- (s,cf,p,v) => { MaximumObjectMass = cf.GetFloat(p, v); },
- (s) => { return (float)MaximumObjectMass; },
- (s,p,l,v) => { MaximumObjectMass = v; } ),
-
- new ParameterDefn("PID_D", "Derivitive factor for motion smoothing",
- 2200f,
- (s,cf,p,v) => { PID_D = cf.GetFloat(p, v); },
- (s) => { return (float)PID_D; },
- (s,p,l,v) => { PID_D = v; } ),
- new ParameterDefn("PID_P", "Parameteric factor for motion smoothing",
- 900f,
- (s,cf,p,v) => { PID_P = cf.GetFloat(p, v); },
- (s) => { return (float)PID_P; },
- (s,p,l,v) => { PID_P = v; } ),
-
- new ParameterDefn("DefaultFriction", "Friction factor used on new objects",
- 0.2f,
- (s,cf,p,v) => { s.UnmanagedParams[0].defaultFriction = cf.GetFloat(p, v); },
- (s) => { return s.UnmanagedParams[0].defaultFriction; },
- (s,p,l,v) => { s.UnmanagedParams[0].defaultFriction = v; } ),
- new ParameterDefn("DefaultDensity", "Density for new objects" ,
- 10.000006836f, // Aluminum g/cm3
- (s,cf,p,v) => { s.UnmanagedParams[0].defaultDensity = cf.GetFloat(p, v); },
- (s) => { return s.UnmanagedParams[0].defaultDensity; },
- (s,p,l,v) => { s.UnmanagedParams[0].defaultDensity = v; } ),
- new ParameterDefn("DefaultRestitution", "Bouncyness of an object" ,
- 0f,
- (s,cf,p,v) => { s.UnmanagedParams[0].defaultRestitution = cf.GetFloat(p, v); },
- (s) => { return s.UnmanagedParams[0].defaultRestitution; },
- (s,p,l,v) => { s.UnmanagedParams[0].defaultRestitution = v; } ),
- new ParameterDefn("CollisionMargin", "Margin around objects before collisions are calculated (must be zero!)",
- 0.04f,
- (s,cf,p,v) => { s.UnmanagedParams[0].collisionMargin = cf.GetFloat(p, v); },
- (s) => { return s.UnmanagedParams[0].collisionMargin; },
- (s,p,l,v) => { s.UnmanagedParams[0].collisionMargin = v; } ),
- new ParameterDefn("Gravity", "Vertical force of gravity (negative means down)",
- -9.80665f,
- (s,cf,p,v) => { s.UnmanagedParams[0].gravity = cf.GetFloat(p, v); },
- (s) => { return s.UnmanagedParams[0].gravity; },
- (s,p,l,v) => { s.UpdateParameterObject((x)=>{s.UnmanagedParams[0].gravity=x;}, p, PhysParameterEntry.APPLY_TO_NONE, v); },
- (s,o,v) => { BulletSimAPI.SetGravity2(s.World.ptr, new Vector3(0f,0f,v)); } ),
-
-
- new ParameterDefn("LinearDamping", "Factor to damp linear movement per second (0.0 - 1.0)",
- 0f,
- (s,cf,p,v) => { LinearDamping = cf.GetFloat(p, v); },
- (s) => { return LinearDamping; },
- (s,p,l,v) => { s.UpdateParameterObject((x)=>{LinearDamping=x;}, p, l, v); },
- (s,o,v) => { BulletSimAPI.SetDamping2(o.PhysBody.ptr, v, AngularDamping); } ),
- new ParameterDefn("AngularDamping", "Factor to damp angular movement per second (0.0 - 1.0)",
- 0f,
- (s,cf,p,v) => { AngularDamping = cf.GetFloat(p, v); },
- (s) => { return AngularDamping; },
- (s,p,l,v) => { s.UpdateParameterObject((x)=>{AngularDamping=x;}, p, l, v); },
- (s,o,v) => { BulletSimAPI.SetDamping2(o.PhysBody.ptr, LinearDamping, v); } ),
- new ParameterDefn("DeactivationTime", "Seconds before considering an object potentially static",
- 0.2f,
- (s,cf,p,v) => { DeactivationTime = cf.GetFloat(p, v); },
- (s) => { return DeactivationTime; },
- (s,p,l,v) => { s.UpdateParameterObject((x)=>{DeactivationTime=x;}, p, l, v); },
- (s,o,v) => { BulletSimAPI.SetDeactivationTime2(o.PhysBody.ptr, v); } ),
- new ParameterDefn("LinearSleepingThreshold", "Seconds to measure linear movement before considering static",
- 0.8f,
- (s,cf,p,v) => { LinearSleepingThreshold = cf.GetFloat(p, v); },
- (s) => { return LinearSleepingThreshold; },
- (s,p,l,v) => { s.UpdateParameterObject((x)=>{LinearSleepingThreshold=x;}, p, l, v); },
- (s,o,v) => { BulletSimAPI.SetSleepingThresholds2(o.PhysBody.ptr, v, v); } ),
- new ParameterDefn("AngularSleepingThreshold", "Seconds to measure angular movement before considering static",
- 1.0f,
- (s,cf,p,v) => { AngularSleepingThreshold = cf.GetFloat(p, v); },
- (s) => { return AngularSleepingThreshold; },
- (s,p,l,v) => { s.UpdateParameterObject((x)=>{AngularSleepingThreshold=x;}, p, l, v); },
- (s,o,v) => { BulletSimAPI.SetSleepingThresholds2(o.PhysBody.ptr, v, v); } ),
- new ParameterDefn("CcdMotionThreshold", "Continuious collision detection threshold (0 means no CCD)" ,
- 0f, // set to zero to disable
- (s,cf,p,v) => { CcdMotionThreshold = cf.GetFloat(p, v); },
- (s) => { return CcdMotionThreshold; },
- (s,p,l,v) => { s.UpdateParameterObject((x)=>{CcdMotionThreshold=x;}, p, l, v); },
- (s,o,v) => { BulletSimAPI.SetCcdMotionThreshold2(o.PhysBody.ptr, v); } ),
- new ParameterDefn("CcdSweptSphereRadius", "Continuious collision detection test radius" ,
- 0f,
- (s,cf,p,v) => { CcdSweptSphereRadius = cf.GetFloat(p, v); },
- (s) => { return CcdSweptSphereRadius; },
- (s,p,l,v) => { s.UpdateParameterObject((x)=>{CcdSweptSphereRadius=x;}, p, l, v); },
- (s,o,v) => { BulletSimAPI.SetCcdSweptSphereRadius2(o.PhysBody.ptr, v); } ),
- new ParameterDefn("ContactProcessingThreshold", "Distance between contacts before doing collision check" ,
- 0.1f,
- (s,cf,p,v) => { ContactProcessingThreshold = cf.GetFloat(p, v); },
- (s) => { return ContactProcessingThreshold; },
- (s,p,l,v) => { s.UpdateParameterObject((x)=>{ContactProcessingThreshold=x;}, p, l, v); },
- (s,o,v) => { BulletSimAPI.SetContactProcessingThreshold2(o.PhysBody.ptr, v); } ),
-
- new ParameterDefn("TerrainImplementation", "Type of shape to use for terrain (0=heightmap, 1=mesh)",
- (float)BSTerrainPhys.TerrainImplementation.Heightmap,
- (s,cf,p,v) => { TerrainImplementation = cf.GetFloat(p,v); },
- (s) => { return TerrainImplementation; },
- (s,p,l,v) => { TerrainImplementation = v; } ),
- new ParameterDefn("TerrainFriction", "Factor to reduce movement against terrain surface" ,
- 0.3f,
- (s,cf,p,v) => { TerrainFriction = cf.GetFloat(p, v); },
- (s) => { return TerrainFriction; },
- (s,p,l,v) => { TerrainFriction = v; /* TODO: set on real terrain */} ),
- new ParameterDefn("TerrainHitFraction", "Distance to measure hit collisions" ,
- 0.8f,
- (s,cf,p,v) => { TerrainHitFraction = cf.GetFloat(p, v); },
- (s) => { return TerrainHitFraction; },
- (s,p,l,v) => { TerrainHitFraction = v; /* TODO: set on real terrain */ } ),
- new ParameterDefn("TerrainRestitution", "Bouncyness" ,
- 0f,
- (s,cf,p,v) => { TerrainRestitution = cf.GetFloat(p, v); },
- (s) => { return TerrainRestitution; },
- (s,p,l,v) => { TerrainRestitution = v; /* TODO: set on real terrain */ } ),
- new ParameterDefn("TerrainCollisionMargin", "Margin where collision checking starts" ,
- 0.04f,
- (s,cf,p,v) => { TerrainCollisionMargin = cf.GetFloat(p, v); },
- (s) => { return TerrainCollisionMargin; },
- (s,p,l,v) => { TerrainCollisionMargin = v; /* TODO: set on real terrain */ } ),
-
- new ParameterDefn("AvatarFriction", "Factor to reduce movement against an avatar. Changed on avatar recreation.",
- 0.2f,
- (s,cf,p,v) => { AvatarFriction = cf.GetFloat(p, v); },
- (s) => { return AvatarFriction; },
- (s,p,l,v) => { s.UpdateParameterObject((x)=>{AvatarFriction=x;}, p, l, v); } ),
- new ParameterDefn("AvatarStandingFriction", "Avatar friction when standing. Changed on avatar recreation.",
- 10.0f,
- (s,cf,p,v) => { AvatarStandingFriction = cf.GetFloat(p, v); },
- (s) => { return AvatarStandingFriction; },
- (s,p,l,v) => { AvatarStandingFriction = v; } ),
- new ParameterDefn("AvatarDensity", "Density of an avatar. Changed on avatar recreation.",
- 3.5f,
- (s,cf,p,v) => { AvatarDensity = cf.GetFloat(p, v); },
- (s) => { return AvatarDensity; },
- (s,p,l,v) => { s.UpdateParameterObject((x)=>{AvatarDensity=x;}, p, l, v); } ),
- new ParameterDefn("AvatarRestitution", "Bouncyness. Changed on avatar recreation.",
- 0f,
- (s,cf,p,v) => { AvatarRestitution = cf.GetFloat(p, v); },
- (s) => { return AvatarRestitution; },
- (s,p,l,v) => { s.UpdateParameterObject((x)=>{AvatarRestitution=x;}, p, l, v); } ),
- new ParameterDefn("AvatarCapsuleWidth", "The distance between the sides of the avatar capsule",
- 0.6f,
- (s,cf,p,v) => { AvatarCapsuleWidth = cf.GetFloat(p, v); },
- (s) => { return AvatarCapsuleWidth; },
- (s,p,l,v) => { s.UpdateParameterObject((x)=>{AvatarCapsuleWidth=x;}, p, l, v); } ),
- new ParameterDefn("AvatarCapsuleDepth", "The distance between the front and back of the avatar capsule",
- 0.45f,
- (s,cf,p,v) => { AvatarCapsuleDepth = cf.GetFloat(p, v); },
- (s) => { return AvatarCapsuleDepth; },
- (s,p,l,v) => { s.UpdateParameterObject((x)=>{AvatarCapsuleDepth=x;}, p, l, v); } ),
- new ParameterDefn("AvatarCapsuleHeight", "Default height of space around avatar",
- 1.5f,
- (s,cf,p,v) => { AvatarCapsuleHeight = cf.GetFloat(p, v); },
- (s) => { return AvatarCapsuleHeight; },
- (s,p,l,v) => { s.UpdateParameterObject((x)=>{AvatarCapsuleHeight=x;}, p, l, v); } ),
- new ParameterDefn("AvatarContactProcessingThreshold", "Distance from capsule to check for collisions",
- 0.1f,
- (s,cf,p,v) => { AvatarContactProcessingThreshold = cf.GetFloat(p, v); },
- (s) => { return AvatarContactProcessingThreshold; },
- (s,p,l,v) => { s.UpdateParameterObject((x)=>{AvatarContactProcessingThreshold=x;}, p, l, v); } ),
-
- new ParameterDefn("VehicleAngularDamping", "Factor to damp vehicle angular movement per second (0.0 - 1.0)",
- 0.95f,
- (s,cf,p,v) => { VehicleAngularDamping = cf.GetFloat(p, v); },
- (s) => { return VehicleAngularDamping; },
- (s,p,l,v) => { VehicleAngularDamping = v; } ),
-
- new ParameterDefn("MaxPersistantManifoldPoolSize", "Number of manifolds pooled (0 means default of 4096)",
- 0f,
- (s,cf,p,v) => { s.UnmanagedParams[0].maxPersistantManifoldPoolSize = cf.GetFloat(p, v); },
- (s) => { return s.UnmanagedParams[0].maxPersistantManifoldPoolSize; },
- (s,p,l,v) => { s.UnmanagedParams[0].maxPersistantManifoldPoolSize = v; } ),
- new ParameterDefn("MaxCollisionAlgorithmPoolSize", "Number of collisions pooled (0 means default of 4096)",
- 0f,
- (s,cf,p,v) => { s.UnmanagedParams[0].maxCollisionAlgorithmPoolSize = cf.GetFloat(p, v); },
- (s) => { return s.UnmanagedParams[0].maxCollisionAlgorithmPoolSize; },
- (s,p,l,v) => { s.UnmanagedParams[0].maxCollisionAlgorithmPoolSize = v; } ),
- new ParameterDefn("ShouldDisableContactPoolDynamicAllocation", "Enable to allow large changes in object count",
- ConfigurationParameters.numericFalse,
- (s,cf,p,v) => { s.UnmanagedParams[0].shouldDisableContactPoolDynamicAllocation = BSParam.NumericBool(cf.GetBoolean(p, BSParam.BoolNumeric(v))); },
- (s) => { return s.UnmanagedParams[0].shouldDisableContactPoolDynamicAllocation; },
- (s,p,l,v) => { s.UnmanagedParams[0].shouldDisableContactPoolDynamicAllocation = v; } ),
- new ParameterDefn("ShouldForceUpdateAllAabbs", "Enable to recomputer AABBs every simulator step",
- ConfigurationParameters.numericFalse,
- (s,cf,p,v) => { s.UnmanagedParams[0].shouldForceUpdateAllAabbs = BSParam.NumericBool(cf.GetBoolean(p, BSParam.BoolNumeric(v))); },
- (s) => { return s.UnmanagedParams[0].shouldForceUpdateAllAabbs; },
- (s,p,l,v) => { s.UnmanagedParams[0].shouldForceUpdateAllAabbs = v; } ),
- new ParameterDefn("ShouldRandomizeSolverOrder", "Enable for slightly better stacking interaction",
- ConfigurationParameters.numericTrue,
- (s,cf,p,v) => { s.UnmanagedParams[0].shouldRandomizeSolverOrder = BSParam.NumericBool(cf.GetBoolean(p, BSParam.BoolNumeric(v))); },
- (s) => { return s.UnmanagedParams[0].shouldRandomizeSolverOrder; },
- (s,p,l,v) => { s.UnmanagedParams[0].shouldRandomizeSolverOrder = v; } ),
- new ParameterDefn("ShouldSplitSimulationIslands", "Enable splitting active object scanning islands",
- ConfigurationParameters.numericTrue,
- (s,cf,p,v) => { s.UnmanagedParams[0].shouldSplitSimulationIslands = BSParam.NumericBool(cf.GetBoolean(p, BSParam.BoolNumeric(v))); },
- (s) => { return s.UnmanagedParams[0].shouldSplitSimulationIslands; },
- (s,p,l,v) => { s.UnmanagedParams[0].shouldSplitSimulationIslands = v; } ),
- new ParameterDefn("ShouldEnableFrictionCaching", "Enable friction computation caching",
- ConfigurationParameters.numericFalse,
- (s,cf,p,v) => { s.UnmanagedParams[0].shouldEnableFrictionCaching = BSParam.NumericBool(cf.GetBoolean(p, BSParam.BoolNumeric(v))); },
- (s) => { return s.UnmanagedParams[0].shouldEnableFrictionCaching; },
- (s,p,l,v) => { s.UnmanagedParams[0].shouldEnableFrictionCaching = v; } ),
- new ParameterDefn("NumberOfSolverIterations", "Number of internal iterations (0 means default)",
- 0f, // zero says use Bullet default
- (s,cf,p,v) => { s.UnmanagedParams[0].numberOfSolverIterations = cf.GetFloat(p, v); },
- (s) => { return s.UnmanagedParams[0].numberOfSolverIterations; },
- (s,p,l,v) => { s.UnmanagedParams[0].numberOfSolverIterations = v; } ),
-
- new ParameterDefn("LinksetImplementation", "Type of linkset implementation (0=Constraint, 1=Compound, 2=Manual)",
- (float)BSLinkset.LinksetImplementation.Compound,
- (s,cf,p,v) => { LinksetImplementation = cf.GetFloat(p,v); },
- (s) => { return LinksetImplementation; },
- (s,p,l,v) => { LinksetImplementation = v; } ),
- new ParameterDefn("LinkConstraintUseFrameOffset", "For linksets built with constraints, enable frame offsetFor linksets built with constraints, enable frame offset.",
- ConfigurationParameters.numericFalse,
- (s,cf,p,v) => { LinkConstraintUseFrameOffset = BSParam.NumericBool(cf.GetBoolean(p, BSParam.BoolNumeric(v))); },
- (s) => { return LinkConstraintUseFrameOffset; },
- (s,p,l,v) => { LinkConstraintUseFrameOffset = v; } ),
- new ParameterDefn("LinkConstraintEnableTransMotor", "Whether to enable translational motor on linkset constraints",
- ConfigurationParameters.numericTrue,
- (s,cf,p,v) => { LinkConstraintEnableTransMotor = BSParam.NumericBool(cf.GetBoolean(p, BSParam.BoolNumeric(v))); },
- (s) => { return LinkConstraintEnableTransMotor; },
- (s,p,l,v) => { LinkConstraintEnableTransMotor = v; } ),
- new ParameterDefn("LinkConstraintTransMotorMaxVel", "Maximum velocity to be applied by translational motor in linkset constraints",
- 5.0f,
- (s,cf,p,v) => { LinkConstraintTransMotorMaxVel = cf.GetFloat(p, v); },
- (s) => { return LinkConstraintTransMotorMaxVel; },
- (s,p,l,v) => { LinkConstraintTransMotorMaxVel = v; } ),
- new ParameterDefn("LinkConstraintTransMotorMaxForce", "Maximum force to be applied by translational motor in linkset constraints",
- 0.1f,
- (s,cf,p,v) => { LinkConstraintTransMotorMaxForce = cf.GetFloat(p, v); },
- (s) => { return LinkConstraintTransMotorMaxForce; },
- (s,p,l,v) => { LinkConstraintTransMotorMaxForce = v; } ),
- new ParameterDefn("LinkConstraintCFM", "Amount constraint can be violated. 0=no violation, 1=infinite. Default=0.1",
- 0.1f,
- (s,cf,p,v) => { LinkConstraintCFM = cf.GetFloat(p, v); },
- (s) => { return LinkConstraintCFM; },
- (s,p,l,v) => { LinkConstraintCFM = v; } ),
- new ParameterDefn("LinkConstraintERP", "Amount constraint is corrected each tick. 0=none, 1=all. Default = 0.2",
- 0.1f,
- (s,cf,p,v) => { LinkConstraintERP = cf.GetFloat(p, v); },
- (s) => { return LinkConstraintERP; },
- (s,p,l,v) => { LinkConstraintERP = v; } ),
- new ParameterDefn("LinkConstraintSolverIterations", "Number of solver iterations when computing constraint. (0 = Bullet default)",
- 40,
- (s,cf,p,v) => { LinkConstraintSolverIterations = cf.GetFloat(p, v); },
- (s) => { return LinkConstraintSolverIterations; },
- (s,p,l,v) => { LinkConstraintSolverIterations = v; } ),
-
- new ParameterDefn("LogPhysicsStatisticsFrames", "Frames between outputting detailed phys stats. (0 is off)",
- 0f,
- (s,cf,p,v) => { s.UnmanagedParams[0].physicsLoggingFrames = cf.GetInt(p, (int)v); },
- (s) => { return (float)s.UnmanagedParams[0].physicsLoggingFrames; },
- (s,p,l,v) => { s.UnmanagedParams[0].physicsLoggingFrames = (int)v; } ),
- };
-
- // Convert a boolean to our numeric true and false values
- public static float NumericBool(bool b)
- {
- return (b ? ConfigurationParameters.numericTrue : ConfigurationParameters.numericFalse);
- }
-
- // Convert numeric true and false values to a boolean
- public static bool BoolNumeric(float b)
- {
- return (b == ConfigurationParameters.numericTrue ? true : false);
- }
-
- // Search through the parameter definitions and return the matching
- // ParameterDefn structure.
- // Case does not matter as names are compared after converting to lower case.
- // Returns 'false' if the parameter is not found.
- internal static bool TryGetParameter(string paramName, out ParameterDefn defn)
- {
- bool ret = false;
- ParameterDefn foundDefn = new ParameterDefn();
- string pName = paramName.ToLower();
-
- foreach (ParameterDefn parm in ParameterDefinitions)
- {
- if (pName == parm.name.ToLower())
- {
- foundDefn = parm;
- ret = true;
- break;
- }
- }
- defn = foundDefn;
- return ret;
- }
-
- // Pass through the settable parameters and set the default values
- internal static void SetParameterDefaultValues(BSScene physicsScene)
- {
- foreach (ParameterDefn parm in ParameterDefinitions)
- {
- parm.setter(physicsScene, parm.name, PhysParameterEntry.APPLY_TO_NONE, parm.defaultValue);
- }
- }
-
- // Get user set values out of the ini file.
- internal static void SetParameterConfigurationValues(BSScene physicsScene, IConfig cfg)
- {
- foreach (ParameterDefn parm in ParameterDefinitions)
- {
- parm.userParam(physicsScene, cfg, parm.name, parm.defaultValue);
- }
- }
-
- internal static PhysParameterEntry[] SettableParameters = new PhysParameterEntry[1];
-
- // This creates an array in the correct format for returning the list of
- // parameters. This is used by the 'list' option of the 'physics' command.
- internal static void BuildParameterTable()
- {
- if (SettableParameters.Length < ParameterDefinitions.Length)
- {
- List entries = new List();
- for (int ii = 0; ii < ParameterDefinitions.Length; ii++)
- {
- ParameterDefn pd = ParameterDefinitions[ii];
- entries.Add(new PhysParameterEntry(pd.name, pd.desc));
- }
-
- // make the list in alphabetical order for estetic reasons
- entries.Sort(delegate(PhysParameterEntry ppe1, PhysParameterEntry ppe2)
- {
- return ppe1.name.CompareTo(ppe2.name);
- });
-
- SettableParameters = entries.ToArray();
- }
- }
-
-
-}
-}
diff --git a/OpenSim/Region/Physics/BulletSNPlugin/BSPhysObject.cs b/OpenSim/Region/Physics/BulletSNPlugin/BSPhysObject.cs
deleted file mode 100644
index 689da7f962..0000000000
--- a/OpenSim/Region/Physics/BulletSNPlugin/BSPhysObject.cs
+++ /dev/null
@@ -1,346 +0,0 @@
-/*
- * Copyright (c) Contributors, http://opensimulator.org/
- * See CONTRIBUTORS.TXT for a full list of copyright holders.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyrightD
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * * Neither the name of the OpenSimulator Project nor the
- * names of its contributors may be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-using System;
-using System.Collections.Generic;
-using System.Text;
-
-using OMV = OpenMetaverse;
-using OpenSim.Framework;
-using OpenSim.Region.Physics.Manager;
-
-namespace OpenSim.Region.Physics.BulletSNPlugin
-{
-/*
- * Class to wrap all objects.
- * The rest of BulletSim doesn't need to keep checking for avatars or prims
- * unless the difference is significant.
- *
- * Variables in the physicsl objects are in three forms:
- * VariableName: used by the simulator and performs taint operations, etc
- * RawVariableName: direct reference to the BulletSim storage for the variable value
- * ForceVariableName: direct reference (store and fetch) to the value in the physics engine.
- * The last two (and certainly the last one) should be referenced only in taint-time.
- */
-
-/*
- * As of 20121221, the following are the call sequences (going down) for different script physical functions:
- * llApplyImpulse llApplyRotImpulse llSetTorque llSetForce
- * SOP.ApplyImpulse SOP.ApplyAngularImpulse SOP.SetAngularImpulse SOP.SetForce
- * SOG.ApplyImpulse SOG.ApplyAngularImpulse SOG.SetAngularImpulse
- * PA.AddForce PA.AddAngularForce PA.Torque = v PA.Force = v
- * BS.ApplyCentralForce BS.ApplyTorque
- */
-
-public abstract class BSPhysObject : PhysicsActor
-{
- protected BSPhysObject()
- {
- }
- protected BSPhysObject(BSScene parentScene, uint localID, string name, string typeName)
- {
- PhysicsScene = parentScene;
- LocalID = localID;
- PhysObjectName = name;
- TypeName = typeName;
-
- Linkset = BSLinkset.Factory(PhysicsScene, this);
- LastAssetBuildFailed = false;
-
- // Default material type
- Material = MaterialAttributes.Material.Wood;
-
- CollisionCollection = new CollisionEventUpdate();
- SubscribedEventsMs = 0;
- CollidingStep = 0;
- CollidingGroundStep = 0;
- }
-
- // Tell the object to clean up.
- public virtual void Destroy()
- {
- UnRegisterAllPreStepActions();
- }
-
- public BSScene PhysicsScene { get; protected set; }
- // public override uint LocalID { get; set; } // Use the LocalID definition in PhysicsActor
- public string PhysObjectName { get; protected set; }
- public string TypeName { get; protected set; }
-
- public BSLinkset Linkset { get; set; }
- public BSLinksetInfo LinksetInfo { get; set; }
-
- // Return the object mass without calculating it or having side effects
- public abstract float RawMass { get; }
- // Set the raw mass but also update physical mass properties (inertia, ...)
- // 'inWorld' true if the object has already been added to the dynamic world.
- public abstract void UpdatePhysicalMassProperties(float mass, bool inWorld);
-
- // The last value calculated for the prim's inertia
- public OMV.Vector3 Inertia { get; set; }
-
- // Reference to the physical body (btCollisionObject) of this object
- public BulletBody PhysBody;
- // Reference to the physical shape (btCollisionShape) of this object
- public BulletShape PhysShape;
-
- // 'true' if the mesh's underlying asset failed to build.
- // This will keep us from looping after the first time the build failed.
- public bool LastAssetBuildFailed { get; set; }
-
- // The objects base shape information. Null if not a prim type shape.
- public PrimitiveBaseShape BaseShape { get; protected set; }
- // Some types of objects have preferred physical representations.
- // Returns SHAPE_UNKNOWN if there is no preference.
- public virtual BSPhysicsShapeType PreferredPhysicalShape
- {
- get { return BSPhysicsShapeType.SHAPE_UNKNOWN; }
- }
-
- // When the physical properties are updated, an EntityProperty holds the update values.
- // Keep the current and last EntityProperties to enable computation of differences
- // between the current update and the previous values.
- public EntityProperties CurrentEntityProperties { get; set; }
- public EntityProperties LastEntityProperties { get; set; }
-
- public virtual OMV.Vector3 Scale { get; set; }
- public abstract bool IsSolid { get; }
- public abstract bool IsStatic { get; }
-
- // Materialness
- public MaterialAttributes.Material Material { get; private set; }
- public override void SetMaterial(int material)
- {
- Material = (MaterialAttributes.Material)material;
- }
-
- // Stop all physical motion.
- public abstract void ZeroMotion(bool inTaintTime);
- public abstract void ZeroAngularMotion(bool inTaintTime);
-
- // Step the vehicle simulation for this object. A NOOP if the vehicle was not configured.
- public virtual void StepVehicle(float timeStep) { }
-
- // Update the physical location and motion of the object. Called with data from Bullet.
- public abstract void UpdateProperties(EntityProperties entprop);
-
- public abstract OMV.Vector3 RawPosition { get; set; }
- public abstract OMV.Vector3 ForcePosition { get; set; }
-
- public abstract OMV.Quaternion RawOrientation { get; set; }
- public abstract OMV.Quaternion ForceOrientation { get; set; }
-
- // The system is telling us the velocity it wants to move at.
- // protected OMV.Vector3 m_targetVelocity; // use the definition in PhysicsActor
- public override OMV.Vector3 TargetVelocity
- {
- get { return m_targetVelocity; }
- set
- {
- m_targetVelocity = value;
- Velocity = value;
- }
- }
- public abstract OMV.Vector3 ForceVelocity { get; set; }
-
- public abstract OMV.Vector3 ForceRotationalVelocity { get; set; }
-
- public abstract float ForceBuoyancy { get; set; }
-
- public virtual bool ForceBodyShapeRebuild(bool inTaintTime) { return false; }
-
- #region Collisions
-
- // Requested number of milliseconds between collision events. Zero means disabled.
- protected int SubscribedEventsMs { get; set; }
- // Given subscription, the time that a collision may be passed up
- protected int NextCollisionOkTime { get; set; }
- // The simulation step that last had a collision
- protected long CollidingStep { get; set; }
- // The simulation step that last had a collision with the ground
- protected long CollidingGroundStep { get; set; }
- // The collision flags we think are set in Bullet
- protected CollisionFlags CurrentCollisionFlags { get; set; }
-
- // The collisions that have been collected this tick
- protected CollisionEventUpdate CollisionCollection;
-
- // The simulation step is telling this object about a collision.
- // Return 'true' if a collision was processed and should be sent up.
- // Called at taint time from within the Step() function
- public virtual bool Collide(uint collidingWith, BSPhysObject collidee,
- OMV.Vector3 contactPoint, OMV.Vector3 contactNormal, float pentrationDepth)
- {
- bool ret = false;
-
- // The following lines make IsColliding() and IsCollidingGround() work
- CollidingStep = PhysicsScene.SimulationStep;
- if (collidingWith <= PhysicsScene.TerrainManager.HighestTerrainID)
- {
- CollidingGroundStep = PhysicsScene.SimulationStep;
- }
-
- // prims in the same linkset cannot collide with each other
- if (collidee != null && (this.Linkset.LinksetID == collidee.Linkset.LinksetID))
- {
- return ret;
- }
-
- // if someone has subscribed for collision events....
- if (SubscribedEvents()) {
- CollisionCollection.AddCollider(collidingWith, new ContactPoint(contactPoint, contactNormal, pentrationDepth));
- DetailLog("{0},{1}.Collison.AddCollider,call,with={2},point={3},normal={4},depth={5}",
- LocalID, TypeName, collidingWith, contactPoint, contactNormal, pentrationDepth);
-
- ret = true;
- }
- return ret;
- }
-
- // Send the collected collisions into the simulator.
- // Called at taint time from within the Step() function thus no locking problems
- // with CollisionCollection and ObjectsWithNoMoreCollisions.
- // Return 'true' if there were some actual collisions passed up
- public virtual bool SendCollisions()
- {
- bool ret = true;
- // If the 'no collision' call, force it to happen right now so quick collision_end
- bool force = (CollisionCollection.Count == 0);
-
- // throttle the collisions to the number of milliseconds specified in the subscription
- if (force || (PhysicsScene.SimulationNowTime >= NextCollisionOkTime))
- {
- NextCollisionOkTime = PhysicsScene.SimulationNowTime + SubscribedEventsMs;
-
- // We are called if we previously had collisions. If there are no collisions
- // this time, send up one last empty event so OpenSim can sense collision end.
- if (CollisionCollection.Count == 0)
- {
- // If I have no collisions this time, remove me from the list of objects with collisions.
- ret = false;
- }
-
- // DetailLog("{0},{1}.SendCollisionUpdate,call,numCollisions={2}", LocalID, TypeName, CollisionCollection.Count);
- base.SendCollisionUpdate(CollisionCollection);
-
- // The CollisionCollection instance is passed around in the simulator.
- // Make sure we don't have a handle to that one and that a new one is used for next time.
- // This fixes an interesting 'gotcha'. If we call CollisionCollection.Clear() here,
- // a race condition is created for the other users of this instance.
- CollisionCollection = new CollisionEventUpdate();
- }
- return ret;
- }
-
- // Subscribe for collision events.
- // Parameter is the millisecond rate the caller wishes collision events to occur.
- public override void SubscribeEvents(int ms) {
- // DetailLog("{0},{1}.SubscribeEvents,subscribing,ms={2}", LocalID, TypeName, ms);
- SubscribedEventsMs = ms;
- if (ms > 0)
- {
- // make sure first collision happens
- NextCollisionOkTime = Util.EnvironmentTickCountSubtract(SubscribedEventsMs);
-
- PhysicsScene.TaintedObject(TypeName+".SubscribeEvents", delegate()
- {
- if (PhysBody.HasPhysicalBody)
- CurrentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(PhysBody.ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS);
- });
- }
- else
- {
- // Subscribing for zero or less is the same as unsubscribing
- UnSubscribeEvents();
- }
- }
- public override void UnSubscribeEvents() {
- // DetailLog("{0},{1}.UnSubscribeEvents,unsubscribing", LocalID, TypeName);
- SubscribedEventsMs = 0;
- PhysicsScene.TaintedObject(TypeName+".UnSubscribeEvents", delegate()
- {
- // Make sure there is a body there because sometimes destruction happens in an un-ideal order.
- if (PhysBody.HasPhysicalBody)
- CurrentCollisionFlags = BulletSimAPI.RemoveFromCollisionFlags2(PhysBody.ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS);
- });
- }
- // Return 'true' if the simulator wants collision events
- public override bool SubscribedEvents() {
- return (SubscribedEventsMs > 0);
- }
-
- #endregion // Collisions
-
- #region Per Simulation Step actions
- // There are some actions that must be performed for a physical object before each simulation step.
- // These actions are optional so, rather than scanning all the physical objects and asking them
- // if they have anything to do, a physical object registers for an event call before the step is performed.
- // This bookkeeping makes it easy to add, remove and clean up after all these registrations.
- private Dictionary RegisteredActions = new Dictionary();
- protected void RegisterPreStepAction(string op, uint id, BSScene.PreStepAction actn)
- {
- string identifier = op + "-" + id.ToString();
- RegisteredActions[identifier] = actn;
- PhysicsScene.BeforeStep += actn;
- DetailLog("{0},BSPhysObject.RegisterPreStepAction,id={1}", LocalID, identifier);
- }
-
- // Unregister a pre step action. Safe to call if the action has not been registered.
- protected void UnRegisterPreStepAction(string op, uint id)
- {
- string identifier = op + "-" + id.ToString();
- bool removed = false;
- if (RegisteredActions.ContainsKey(identifier))
- {
- PhysicsScene.BeforeStep -= RegisteredActions[identifier];
- RegisteredActions.Remove(identifier);
- removed = true;
- }
- DetailLog("{0},BSPhysObject.UnRegisterPreStepAction,id={1},removed={2}", LocalID, identifier, removed);
- }
-
- protected void UnRegisterAllPreStepActions()
- {
- foreach (KeyValuePair kvp in RegisteredActions)
- {
- PhysicsScene.BeforeStep -= kvp.Value;
- }
- RegisteredActions.Clear();
- DetailLog("{0},BSPhysObject.UnRegisterAllPreStepActions,", LocalID);
- }
-
-
- #endregion // Per Simulation Step actions
-
- // High performance detailed logging routine used by the physical objects.
- protected void DetailLog(string msg, params Object[] args)
- {
- if (PhysicsScene.PhysicsLogging.Enabled)
- PhysicsScene.DetailLog(msg, args);
- }
-
-}
-}
diff --git a/OpenSim/Region/Physics/BulletSNPlugin/BSPlugin.cs b/OpenSim/Region/Physics/BulletSNPlugin/BSPlugin.cs
deleted file mode 100644
index 75963ee5e5..0000000000
--- a/OpenSim/Region/Physics/BulletSNPlugin/BSPlugin.cs
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright (c) Contributors, http://opensimulator.org/
- * See CONTRIBUTORS.TXT for a full list of copyright holders.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyrightD
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * * Neither the name of the OpenSimulator Project nor the
- * names of its contributors may be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-using System;
-using System.Collections.Generic;
-using OpenSim.Framework;
-using OpenSim.Region.Physics.Manager;
-using OpenMetaverse;
-
-namespace OpenSim.Region.Physics.BulletSNPlugin
-{
- ///
- /// Entry for a port of Bullet (http://bulletphysics.org/) to OpenSim.
- /// This module interfaces to an unmanaged C++ library which makes the
- /// actual calls into the Bullet physics engine.
- /// The unmanaged library is found in opensim-libs::trunk/unmanaged/BulletSim/.
- /// The unmanaged library is compiled and linked statically with Bullet
- /// to create BulletSim.dll and libBulletSim.so (for both 32 and 64 bit).
- ///
-public class BSPlugin : IPhysicsPlugin
-{
- //private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
-
- private BSScene _mScene;
-
- public BSPlugin()
- {
- }
-
- public bool Init()
- {
- return true;
- }
-
- public PhysicsScene GetScene(String sceneIdentifier)
- {
- if (_mScene == null)
- {
-
- // If not Windows, loading is performed by the
- // Mono loader as specified in
- // "bin/Physics/OpenSim.Region.Physics.BulletSNPlugin.dll.config".
-
- _mScene = new BSScene(sceneIdentifier);
- }
- return (_mScene);
- }
-
- public string GetName()
- {
- return ("BulletSimN");
- }
-
- public void Dispose()
- {
- }
-}
-}
diff --git a/OpenSim/Region/Physics/BulletSNPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSNPlugin/BSPrim.cs
deleted file mode 100644
index aadb5b2925..0000000000
--- a/OpenSim/Region/Physics/BulletSNPlugin/BSPrim.cs
+++ /dev/null
@@ -1,1494 +0,0 @@
-/*
- * Copyright (c) Contributors, http://opensimulator.org/
- * See CONTRIBUTORS.TXT for a full list of copyright holders.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyrightD
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * * Neither the name of the OpenSimulator Project nor the
- * names of its contributors may be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-using System;
-using System.Reflection;
-using System.Collections.Generic;
-using System.Xml;
-using log4net;
-using OMV = OpenMetaverse;
-using OpenSim.Framework;
-using OpenSim.Region.Physics.Manager;
-using OpenSim.Region.Physics.ConvexDecompositionDotNet;
-
-namespace OpenSim.Region.Physics.BulletSNPlugin
-{
-
- [Serializable]
-public sealed class BSPrim : BSPhysObject
-{
- private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
- private static readonly string LogHeader = "[BULLETS PRIM]";
-
- // _size is what the user passed. Scale is what we pass to the physics engine with the mesh.
- private OMV.Vector3 _size; // the multiplier for each mesh dimension as passed by the user
-
- private bool _grabbed;
- private bool _isSelected;
- private bool _isVolumeDetect;
- private OMV.Vector3 _position;
- private float _mass; // the mass of this object
- private float _density;
- private OMV.Vector3 _force;
- private OMV.Vector3 _velocity;
- private OMV.Vector3 _torque;
- private float _collisionScore;
- private OMV.Vector3 _acceleration;
- private OMV.Quaternion _orientation;
- private int _physicsActorType;
- private bool _isPhysical;
- private bool _flying;
- private float _friction;
- private float _restitution;
- private bool _setAlwaysRun;
- private bool _throttleUpdates;
- private bool _isColliding;
- private bool _collidingGround;
- private bool _collidingObj;
- private bool _floatOnWater;
- private OMV.Vector3 _rotationalVelocity;
- private bool _kinematic;
- private float _buoyancy;
-
- private BSDynamics _vehicle;
-
- private OMV.Vector3 _PIDTarget;
- private bool _usePID;
- private float _PIDTau;
- private bool _useHoverPID;
- private float _PIDHoverHeight;
- private PIDHoverType _PIDHoverType;
- private float _PIDHoverTao;
-
- public BSPrim(uint localID, String primName, BSScene parent_scene, OMV.Vector3 pos, OMV.Vector3 size,
- OMV.Quaternion rotation, PrimitiveBaseShape pbs, bool pisPhysical)
- : base(parent_scene, localID, primName, "BSPrim")
- {
- // m_log.DebugFormat("{0}: BSPrim creation of {1}, id={2}", LogHeader, primName, localID);
- _physicsActorType = (int)ActorTypes.Prim;
- _position = pos;
- _size = size;
- Scale = size; // prims are the size the user wants them to be (different for BSCharactes).
- _orientation = rotation;
- _buoyancy = 1f;
- _velocity = OMV.Vector3.Zero;
- _rotationalVelocity = OMV.Vector3.Zero;
- BaseShape = pbs;
- _isPhysical = pisPhysical;
- _isVolumeDetect = false;
-
- // Someday set default attributes based on the material but, for now, we don't know the prim material yet.
- // MaterialAttributes primMat = BSMaterials.GetAttributes(Material, pisPhysical);
- _density = PhysicsScene.Params.defaultDensity;
- _friction = PhysicsScene.Params.defaultFriction;
- _restitution = PhysicsScene.Params.defaultRestitution;
-
- _vehicle = new BSDynamics(PhysicsScene, this); // add vehicleness
-
- _mass = CalculateMass();
-
- Linkset.Refresh(this);
-
- DetailLog("{0},BSPrim.constructor,call", LocalID);
- // do the actual object creation at taint time
- PhysicsScene.TaintedObject("BSPrim.create", delegate()
- {
- CreateGeomAndObject(true);
-
- CurrentCollisionFlags = BulletSimAPI.GetCollisionFlags2(PhysBody.ptr);
- });
- }
-
- // called when this prim is being destroyed and we should free all the resources
- public override void Destroy()
- {
- // m_log.DebugFormat("{0}: Destroy, id={1}", LogHeader, LocalID);
- base.Destroy();
-
- // Undo any links between me and any other object
- BSPhysObject parentBefore = Linkset.LinksetRoot;
- int childrenBefore = Linkset.NumberOfChildren;
-
- Linkset = Linkset.RemoveMeFromLinkset(this);
-
- DetailLog("{0},BSPrim.Destroy,call,parentBefore={1},childrenBefore={2},parentAfter={3},childrenAfter={4}",
- LocalID, parentBefore.LocalID, childrenBefore, Linkset.LinksetRoot.LocalID, Linkset.NumberOfChildren);
-
- // Undo any vehicle properties
- this.VehicleType = (int)Vehicle.TYPE_NONE;
-
- PhysicsScene.TaintedObject("BSPrim.destroy", delegate()
- {
- DetailLog("{0},BSPrim.Destroy,taint,", LocalID);
- // If there are physical body and shape, release my use of same.
- PhysicsScene.Shapes.DereferenceBody(PhysBody, true, null);
- PhysBody.Clear();
- PhysicsScene.Shapes.DereferenceShape(PhysShape, true, null);
- PhysShape.Clear();
- });
- }
-
- // No one uses this property.
- public override bool Stopped {
- get { return false; }
- }
- public override OMV.Vector3 Size {
- get { return _size; }
- set {
- // We presume the scale and size are the same. If scale must be changed for
- // the physical shape, that is done when the geometry is built.
- _size = value;
- Scale = _size;
- ForceBodyShapeRebuild(false);
- }
- }
-
- public override PrimitiveBaseShape Shape {
- set {
- BaseShape = value;
- ForceBodyShapeRebuild(false);
- }
- }
- // Whatever the linkset wants is what I want.
- public override BSPhysicsShapeType PreferredPhysicalShape
- { get { return Linkset.PreferredPhysicalShape(this); } }
-
- public override bool ForceBodyShapeRebuild(bool inTaintTime)
- {
- LastAssetBuildFailed = false;
- PhysicsScene.TaintedObject(inTaintTime, "BSPrim.ForceBodyShapeRebuild", delegate()
- {
- _mass = CalculateMass(); // changing the shape changes the mass
- CreateGeomAndObject(true);
- });
- return true;
- }
- public override bool Grabbed {
- set { _grabbed = value;
- }
- }
- public override bool Selected {
- set
- {
- if (value != _isSelected)
- {
- _isSelected = value;
- PhysicsScene.TaintedObject("BSPrim.setSelected", delegate()
- {
- DetailLog("{0},BSPrim.selected,taint,selected={1}", LocalID, _isSelected);
- SetObjectDynamic(false);
- });
- }
- }
- }
- public override void CrossingFailure() { return; }
-
- // link me to the specified parent
- public override void link(PhysicsActor obj) {
- BSPrim parent = obj as BSPrim;
- if (parent != null)
- {
- BSPhysObject parentBefore = Linkset.LinksetRoot;
- int childrenBefore = Linkset.NumberOfChildren;
-
- Linkset = parent.Linkset.AddMeToLinkset(this);
-
- DetailLog("{0},BSPrim.link,call,parentBefore={1}, childrenBefore=={2}, parentAfter={3}, childrenAfter={4}",
- LocalID, parentBefore.LocalID, childrenBefore, Linkset.LinksetRoot.LocalID, Linkset.NumberOfChildren);
- }
- return;
- }
-
- // delink me from my linkset
- public override void delink() {
- // TODO: decide if this parent checking needs to happen at taint time
- // Race condition here: if link() and delink() in same simulation tick, the delink will not happen
-
- BSPhysObject parentBefore = Linkset.LinksetRoot;
- int childrenBefore = Linkset.NumberOfChildren;
-
- Linkset = Linkset.RemoveMeFromLinkset(this);
-
- DetailLog("{0},BSPrim.delink,parentBefore={1},childrenBefore={2},parentAfter={3},childrenAfter={4}, ",
- LocalID, parentBefore.LocalID, childrenBefore, Linkset.LinksetRoot.LocalID, Linkset.NumberOfChildren);
- return;
- }
-
- // Set motion values to zero.
- // Do it to the properties so the values get set in the physics engine.
- // Push the setting of the values to the viewer.
- // Called at taint time!
- public override void ZeroMotion(bool inTaintTime)
- {
- _velocity = OMV.Vector3.Zero;
- _acceleration = OMV.Vector3.Zero;
- _rotationalVelocity = OMV.Vector3.Zero;
-
- // Zero some other properties in the physics engine
- PhysicsScene.TaintedObject(inTaintTime, "BSPrim.ZeroMotion", delegate()
- {
- if (PhysBody.HasPhysicalBody)
- BulletSimAPI.ClearAllForces2(PhysBody.ptr);
- });
- }
- public override void ZeroAngularMotion(bool inTaintTime)
- {
- _rotationalVelocity = OMV.Vector3.Zero;
- // Zero some other properties in the physics engine
- PhysicsScene.TaintedObject(inTaintTime, "BSPrim.ZeroMotion", delegate()
- {
- // DetailLog("{0},BSPrim.ZeroAngularMotion,call,rotVel={1}", LocalID, _rotationalVelocity);
- if (PhysBody.HasPhysicalBody)
- {
- BulletSimAPI.SetInterpolationAngularVelocity2(PhysBody.ptr, _rotationalVelocity);
- BulletSimAPI.SetAngularVelocity2(PhysBody.ptr, _rotationalVelocity);
- }
- });
- }
-
- public override void LockAngularMotion(OMV.Vector3 axis)
- {
- DetailLog("{0},BSPrim.LockAngularMotion,call,axis={1}", LocalID, axis);
- return;
- }
-
- public override OMV.Vector3 RawPosition
- {
- get { return _position; }
- set { _position = value; }
- }
- public override OMV.Vector3 Position {
- get {
- /* NOTE: this refetch is not necessary. The simulator knows about linkset children
- * and does not fetch this position info for children. Thus this is commented out.
- // child prims move around based on their parent. Need to get the latest location
- if (!Linkset.IsRoot(this))
- _position = Linkset.PositionGet(this);
- */
-
- // don't do the GetObjectPosition for root elements because this function is called a zillion times.
- // _position = BulletSimAPI.GetObjectPosition2(PhysicsScene.World.ptr, BSBody.ptr);
- return _position;
- }
- set {
- // If the position must be forced into the physics engine, use ForcePosition.
- // All positions are given in world positions.
- if (_position == value)
- {
- DetailLog("{0},BSPrim.setPosition,taint,positionNotChanging,pos={1},orient={2}", LocalID, _position, _orientation);
- return;
- }
- _position = value;
- PositionSanityCheck(false);
-
- // A linkset might need to know if a component information changed.
- Linkset.UpdateProperties(this, false);
-
- PhysicsScene.TaintedObject("BSPrim.setPosition", delegate()
- {
- DetailLog("{0},BSPrim.SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation);
- ForcePosition = _position;
- });
- }
- }
- public override OMV.Vector3 ForcePosition {
- get {
- _position = BulletSimAPI.GetPosition2(PhysBody.ptr);
- return _position;
- }
- set {
- _position = value;
- if (PhysBody.HasPhysicalBody)
- {
- BulletSimAPI.SetTranslation2(PhysBody.ptr, _position, _orientation);
- ActivateIfPhysical(false);
- }
- }
- }
-
- // Check that the current position is sane and, if not, modify the position to make it so.
- // Check for being below terrain and being out of bounds.
- // Returns 'true' of the position was made sane by some action.
- private bool PositionSanityCheck(bool inTaintTime)
- {
- bool ret = false;
-
- if (!PhysicsScene.TerrainManager.IsWithinKnownTerrain(_position))
- {
- // The physical object is out of the known/simulated area.
- // Upper levels of code will handle the transition to other areas so, for
- // the time, we just ignore the position.
- return ret;
- }
-
- float terrainHeight = PhysicsScene.TerrainManager.GetTerrainHeightAtXYZ(_position);
- OMV.Vector3 upForce = OMV.Vector3.Zero;
- if (RawPosition.Z < terrainHeight)
- {
- DetailLog("{0},BSPrim.PositionAdjustUnderGround,call,pos={1},terrain={2}", LocalID, _position, terrainHeight);
- float targetHeight = terrainHeight + (Size.Z / 2f);
- // Upforce proportional to the distance away from the terrain. Correct the error in 1 sec.
- upForce.Z = (terrainHeight - RawPosition.Z) * 1f;
- ret = true;
- }
-
- if ((CurrentCollisionFlags & CollisionFlags.BS_FLOATS_ON_WATER) != 0)
- {
- float waterHeight = PhysicsScene.TerrainManager.GetWaterLevelAtXYZ(_position);
- // TODO: a floating motor so object will bob in the water
- if (Math.Abs(RawPosition.Z - waterHeight) > 0.1f)
- {
- // Upforce proportional to the distance away from the water. Correct the error in 1 sec.
- upForce.Z = (waterHeight - RawPosition.Z) * 1f;
- ret = true;
- }
- }
-
- // The above code computes a force to apply to correct any out-of-bounds problems. Apply same.
- // TODO: This should be intergrated with a geneal physics action mechanism.
- // TODO: This should be moderated with PID'ness.
- if (ret)
- {
- // Apply upforce and overcome gravity.
- OMV.Vector3 correctionForce = upForce - PhysicsScene.DefaultGravity;
- DetailLog("{0},BSPrim.PositionSanityCheck,applyForce,pos={1},upForce={2},correctionForce={3}", LocalID, _position, upForce, correctionForce);
- AddForce(correctionForce, false, inTaintTime);
- }
- return ret;
- }
-
- // Return the effective mass of the object.
- // The definition of this call is to return the mass of the prim.
- // If the simulator cares about the mass of the linkset, it will sum it itself.
- public override float Mass
- {
- get
- {
- return _mass;
- }
- }
-
- // used when we only want this prim's mass and not the linkset thing
- public override float RawMass {
- get { return _mass; }
- }
- // Set the physical mass to the passed mass.
- // Note that this does not change _mass!
- public override void UpdatePhysicalMassProperties(float physMass, bool inWorld)
- {
- if (PhysBody.HasPhysicalBody)
- {
- if (IsStatic)
- {
- Inertia = OMV.Vector3.Zero;
- BulletSimAPI.SetMassProps2(PhysBody.ptr, 0f, Inertia);
- BulletSimAPI.UpdateInertiaTensor2(PhysBody.ptr);
- }
- else
- {
- if (inWorld)
- {
- // Changing interesting properties doesn't change proxy and collision cache
- // information. The Bullet solution is to re-add the object to the world
- // after parameters are changed.
- BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.ptr, PhysBody.ptr);
- }
-
- Inertia = BulletSimAPI.CalculateLocalInertia2(PhysShape.ptr, physMass);
- BulletSimAPI.SetMassProps2(PhysBody.ptr, physMass, Inertia);
- BulletSimAPI.UpdateInertiaTensor2(PhysBody.ptr);
-
- // center of mass is at the zero of the object
- // DEBUG DEBUG BulletSimAPI.SetCenterOfMassByPosRot2(PhysBody.ptr, ForcePosition, ForceOrientation);
- DetailLog("{0},BSPrim.UpdateMassProperties,mass={1},localInertia={2},inWorld={3}", LocalID, physMass, Inertia, inWorld);
-
- if (inWorld)
- {
- BulletSimAPI.AddObjectToWorld2(PhysicsScene.World.ptr, PhysBody.ptr,_position,_orientation);
- }
-
- // Must set gravity after it has been added to the world because, for unknown reasons,
- // adding the object resets the object's gravity to world gravity
- OMV.Vector3 grav = PhysicsScene.DefaultGravity * (1f - Buoyancy);
- BulletSimAPI.SetGravity2(PhysBody.ptr, grav);
-
- }
- }
- }
-
- // Is this used?
- public override OMV.Vector3 CenterOfMass
- {
- get { return Linkset.CenterOfMass; }
- }
-
- // Is this used?
- public override OMV.Vector3 GeometricCenter
- {
- get { return Linkset.GeometricCenter; }
- }
-
- public override OMV.Vector3 Force {
- get { return _force; }
- set {
- _force = value;
- if (_force != OMV.Vector3.Zero)
- {
- // If the force is non-zero, it must be reapplied each tick because
- // Bullet clears the forces applied last frame.
- RegisterPreStepAction("BSPrim.setForce", LocalID,
- delegate(float timeStep)
- {
- DetailLog("{0},BSPrim.setForce,preStep,force={1}", LocalID, _force);
- if (PhysBody.HasPhysicalBody)
- {
- BulletSimAPI.ApplyCentralForce2(PhysBody.ptr, _force);
- ActivateIfPhysical(false);
- }
- }
- );
- }
- else
- {
- UnRegisterPreStepAction("BSPrim.setForce", LocalID);
- }
- }
- }
-
- public override int VehicleType {
- get {
- return (int)_vehicle.Type; // if we are a vehicle, return that type
- }
- set {
- Vehicle type = (Vehicle)value;
-
- PhysicsScene.TaintedObject("setVehicleType", delegate()
- {
- // Done at taint time so we're sure the physics engine is not using the variables
- // Vehicle code changes the parameters for this vehicle type.
- _vehicle.ProcessTypeChange(type);
- ActivateIfPhysical(false);
-
- // If an active vehicle, register the vehicle code to be called before each step
- if (_vehicle.Type == Vehicle.TYPE_NONE)
- UnRegisterPreStepAction("BSPrim.Vehicle", LocalID);
- else
- RegisterPreStepAction("BSPrim.Vehicle", LocalID, _vehicle.Step);
- });
- }
- }
- public override void VehicleFloatParam(int param, float value)
- {
- PhysicsScene.TaintedObject("BSPrim.VehicleFloatParam", delegate()
- {
- _vehicle.ProcessFloatVehicleParam((Vehicle)param, value);
- ActivateIfPhysical(false);
- });
- }
- public override void VehicleVectorParam(int param, OMV.Vector3 value)
- {
- PhysicsScene.TaintedObject("BSPrim.VehicleVectorParam", delegate()
- {
- _vehicle.ProcessVectorVehicleParam((Vehicle)param, value);
- ActivateIfPhysical(false);
- });
- }
- public override void VehicleRotationParam(int param, OMV.Quaternion rotation)
- {
- PhysicsScene.TaintedObject("BSPrim.VehicleRotationParam", delegate()
- {
- _vehicle.ProcessRotationVehicleParam((Vehicle)param, rotation);
- ActivateIfPhysical(false);
- });
- }
- public override void VehicleFlags(int param, bool remove)
- {
- PhysicsScene.TaintedObject("BSPrim.VehicleFlags", delegate()
- {
- _vehicle.ProcessVehicleFlags(param, remove);
- });
- }
-
- // Allows the detection of collisions with inherently non-physical prims. see llVolumeDetect for more
- public override void SetVolumeDetect(int param) {
- bool newValue = (param != 0);
- if (_isVolumeDetect != newValue)
- {
- _isVolumeDetect = newValue;
- PhysicsScene.TaintedObject("BSPrim.SetVolumeDetect", delegate()
- {
- // DetailLog("{0},setVolumeDetect,taint,volDetect={1}", LocalID, _isVolumeDetect);
- SetObjectDynamic(true);
- });
- }
- return;
- }
- public override OMV.Vector3 Velocity {
- get { return _velocity; }
- set {
- _velocity = value;
- PhysicsScene.TaintedObject("BSPrim.setVelocity", delegate()
- {
- // DetailLog("{0},BSPrim.SetVelocity,taint,vel={1}", LocalID, _velocity);
- ForceVelocity = _velocity;
- });
- }
- }
- public override OMV.Vector3 ForceVelocity {
- get { return _velocity; }
- set {
- PhysicsScene.AssertInTaintTime("BSPrim.ForceVelocity");
-
- _velocity = value;
- if (PhysBody.HasPhysicalBody)
- {
- BulletSimAPI.SetLinearVelocity2(PhysBody.ptr, _velocity);
- ActivateIfPhysical(false);
- }
- }
- }
- public override OMV.Vector3 Torque {
- get { return _torque; }
- set {
- _torque = value;
- if (_torque != OMV.Vector3.Zero)
- {
- // If the torque is non-zero, it must be reapplied each tick because
- // Bullet clears the forces applied last frame.
- RegisterPreStepAction("BSPrim.setTorque", LocalID,
- delegate(float timeStep)
- {
- if (PhysBody.HasPhysicalBody)
- AddAngularForce(_torque, false, true);
- }
- );
- }
- else
- {
- UnRegisterPreStepAction("BSPrim.setTorque", LocalID);
- }
- // DetailLog("{0},BSPrim.SetTorque,call,torque={1}", LocalID, _torque);
- }
- }
- public override float CollisionScore {
- get { return _collisionScore; }
- set { _collisionScore = value;
- }
- }
- public override OMV.Vector3 Acceleration {
- get { return _acceleration; }
- set { _acceleration = value; }
- }
- public override OMV.Quaternion RawOrientation
- {
- get { return _orientation; }
- set { _orientation = value; }
- }
- public override OMV.Quaternion Orientation {
- get {
- /* NOTE: this refetch is not necessary. The simulator knows about linkset children
- * and does not fetch this position info for children. Thus this is commented out.
- // Children move around because tied to parent. Get a fresh value.
- if (!Linkset.IsRoot(this))
- {
- _orientation = Linkset.OrientationGet(this);
- }
- */
- return _orientation;
- }
- set {
- if (_orientation == value)
- return;
- _orientation = value;
-
- // A linkset might need to know if a component information changed.
- Linkset.UpdateProperties(this, false);
-
- PhysicsScene.TaintedObject("BSPrim.setOrientation", delegate()
- {
- if (PhysBody.HasPhysicalBody)
- {
- // _position = BulletSimAPI.GetObjectPosition2(PhysicsScene.World.ptr, BSBody.ptr);
- // DetailLog("{0},BSPrim.setOrientation,taint,pos={1},orient={2}", LocalID, _position, _orientation);
- BulletSimAPI.SetTranslation2(PhysBody.ptr, _position, _orientation);
- }
- });
- }
- }
- // Go directly to Bullet to get/set the value.
- public override OMV.Quaternion ForceOrientation
- {
- get
- {
- _orientation = BulletSimAPI.GetOrientation2(PhysBody.ptr);
- return _orientation;
- }
- set
- {
- _orientation = value;
- BulletSimAPI.SetTranslation2(PhysBody.ptr, _position, _orientation);
- }
- }
- public override int PhysicsActorType {
- get { return _physicsActorType; }
- set { _physicsActorType = value; }
- }
- public override bool IsPhysical {
- get { return _isPhysical; }
- set {
- if (_isPhysical != value)
- {
- _isPhysical = value;
- PhysicsScene.TaintedObject("BSPrim.setIsPhysical", delegate()
- {
- // DetailLog("{0},setIsPhysical,taint,isPhys={1}", LocalID, _isPhysical);
- SetObjectDynamic(true);
- // whether phys-to-static or static-to-phys, the object is not moving.
- ZeroMotion(true);
- });
- }
- }
- }
-
- // An object is static (does not move) if selected or not physical
- public override bool IsStatic
- {
- get { return _isSelected || !IsPhysical; }
- }
-
- // An object is solid if it's not phantom and if it's not doing VolumeDetect
- public override bool IsSolid
- {
- get { return !IsPhantom && !_isVolumeDetect; }
- }
-
- // Make gravity work if the object is physical and not selected
- // Called at taint-time!!
- private void SetObjectDynamic(bool forceRebuild)
- {
- // Recreate the physical object if necessary
- CreateGeomAndObject(forceRebuild);
- }
-
- // Convert the simulator's physical properties into settings on BulletSim objects.
- // There are four flags we're interested in:
- // IsStatic: Object does not move, otherwise the object has mass and moves
- // isSolid: other objects bounce off of this object
- // isVolumeDetect: other objects pass through but can generate collisions
- // collisionEvents: whether this object returns collision events
- private void UpdatePhysicalParameters()
- {
- // DetailLog("{0},BSPrim.UpdatePhysicalParameters,entry,body={1},shape={2}", LocalID, BSBody, BSShape);
-
- // Mangling all the physical properties requires the object not be in the physical world.
- // This is a NOOP if the object is not in the world (BulletSim and Bullet ignore objects not found).
- BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.ptr, PhysBody.ptr);
-
- // Set up the object physicalness (does gravity and collisions move this object)
- MakeDynamic(IsStatic);
-
- // Update vehicle specific parameters (after MakeDynamic() so can change physical parameters)
- _vehicle.Refresh();
-
- // Arrange for collision events if the simulator wants them
- EnableCollisions(SubscribedEvents());
-
- // Make solid or not (do things bounce off or pass through this object).
- MakeSolid(IsSolid);
-
- BulletSimAPI.AddObjectToWorld2(PhysicsScene.World.ptr, PhysBody.ptr, _position, _orientation);
-
- // Rebuild its shape
- BulletSimAPI.UpdateSingleAabb2(PhysicsScene.World.ptr, PhysBody.ptr);
-
- // Collision filter can be set only when the object is in the world
- PhysBody.ApplyCollisionMask();
-
- // Recompute any linkset parameters.
- // When going from non-physical to physical, this re-enables the constraints that
- // had been automatically disabled when the mass was set to zero.
- // For compound based linksets, this enables and disables interactions of the children.
- Linkset.Refresh(this);
-
- DetailLog("{0},BSPrim.UpdatePhysicalParameters,taintExit,static={1},solid={2},mass={3},collide={4},cf={5:X},body={6},shape={7}",
- LocalID, IsStatic, IsSolid, Mass, SubscribedEvents(), CurrentCollisionFlags, PhysBody, PhysShape);
- }
-
- // "Making dynamic" means changing to and from static.
- // When static, gravity does not effect the object and it is fixed in space.
- // When dynamic, the object can fall and be pushed by others.
- // This is independent of its 'solidness' which controls what passes through
- // this object and what interacts with it.
- private void MakeDynamic(bool makeStatic)
- {
- if (makeStatic)
- {
- // Become a Bullet 'static' object type
- CurrentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(PhysBody.ptr, CollisionFlags.CF_STATIC_OBJECT);
- // Stop all movement
- ZeroMotion(true);
-
- // Set various physical properties so other object interact properly
- MaterialAttributes matAttrib = BSMaterials.GetAttributes(Material, false);
- BulletSimAPI.SetFriction2(PhysBody.ptr, matAttrib.friction);
- BulletSimAPI.SetRestitution2(PhysBody.ptr, matAttrib.restitution);
-
- // Mass is zero which disables a bunch of physics stuff in Bullet
- UpdatePhysicalMassProperties(0f, false);
- // Set collision detection parameters
- if (BSParam.CcdMotionThreshold > 0f)
- {
- BulletSimAPI.SetCcdMotionThreshold2(PhysBody.ptr, BSParam.CcdMotionThreshold);
- BulletSimAPI.SetCcdSweptSphereRadius2(PhysBody.ptr, BSParam.CcdSweptSphereRadius);
- }
-
- // The activation state is 'disabled' so Bullet will not try to act on it.
- // BulletSimAPI.ForceActivationState2(PhysBody.ptr, ActivationState.DISABLE_SIMULATION);
- // Start it out sleeping and physical actions could wake it up.
- BulletSimAPI.ForceActivationState2(PhysBody.ptr, ActivationState.ISLAND_SLEEPING);
-
- // This collides like a static object
- PhysBody.collisionType = CollisionType.Static;
-
- // There can be special things needed for implementing linksets
- Linkset.MakeStatic(this);
- }
- else
- {
- // Not a Bullet static object
- CurrentCollisionFlags = BulletSimAPI.RemoveFromCollisionFlags2(PhysBody.ptr, CollisionFlags.CF_STATIC_OBJECT);
-
- // Set various physical properties so other object interact properly
- MaterialAttributes matAttrib = BSMaterials.GetAttributes(Material, true);
- BulletSimAPI.SetFriction2(PhysBody.ptr, matAttrib.friction);
- BulletSimAPI.SetRestitution2(PhysBody.ptr, matAttrib.restitution);
-
- // per http://www.bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=3382
- // Since this can be called multiple times, only zero forces when becoming physical
- // BulletSimAPI.ClearAllForces2(BSBody.ptr);
-
- // For good measure, make sure the transform is set through to the motion state
- BulletSimAPI.SetTranslation2(PhysBody.ptr, _position, _orientation);
-
- // Center of mass is at the center of the object
- // DEBUG DEBUG BulletSimAPI.SetCenterOfMassByPosRot2(Linkset.LinksetRoot.PhysBody.ptr, _position, _orientation);
-
- // A dynamic object has mass
- UpdatePhysicalMassProperties(RawMass, false);
-
- // Set collision detection parameters
- if (BSParam.CcdMotionThreshold > 0f)
- {
- BulletSimAPI.SetCcdMotionThreshold2(PhysBody.ptr, BSParam.CcdMotionThreshold);
- BulletSimAPI.SetCcdSweptSphereRadius2(PhysBody.ptr, BSParam.CcdSweptSphereRadius);
- }
-
- // Various values for simulation limits
- BulletSimAPI.SetDamping2(PhysBody.ptr, BSParam.LinearDamping, BSParam.AngularDamping);
- BulletSimAPI.SetDeactivationTime2(PhysBody.ptr, BSParam.DeactivationTime);
- BulletSimAPI.SetSleepingThresholds2(PhysBody.ptr, BSParam.LinearSleepingThreshold, BSParam.AngularSleepingThreshold);
- BulletSimAPI.SetContactProcessingThreshold2(PhysBody.ptr, BSParam.ContactProcessingThreshold);
-
- // This collides like an object.
- PhysBody.collisionType = CollisionType.Dynamic;
-
- // Force activation of the object so Bullet will act on it.
- // Must do the ForceActivationState2() to overcome the DISABLE_SIMULATION from static objects.
- BulletSimAPI.ForceActivationState2(PhysBody.ptr, ActivationState.ACTIVE_TAG);
-
- // There might be special things needed for implementing linksets.
- Linkset.MakeDynamic(this);
- }
- }
-
- // "Making solid" means that other object will not pass through this object.
- // To make transparent, we create a Bullet ghost object.
- // Note: This expects to be called from the UpdatePhysicalParameters() routine as
- // the functions after this one set up the state of a possibly newly created collision body.
- private void MakeSolid(bool makeSolid)
- {
- CollisionObjectTypes bodyType = (CollisionObjectTypes)BulletSimAPI.GetBodyType2(PhysBody.ptr);
- if (makeSolid)
- {
- // Verify the previous code created the correct shape for this type of thing.
- if ((bodyType & CollisionObjectTypes.CO_RIGID_BODY) == 0)
- {
- m_log.ErrorFormat("{0} MakeSolid: physical body of wrong type for solidity. id={1}, type={2}", LogHeader, LocalID, bodyType);
- }
- CurrentCollisionFlags = BulletSimAPI.RemoveFromCollisionFlags2(PhysBody.ptr, CollisionFlags.CF_NO_CONTACT_RESPONSE);
- }
- else
- {
- if ((bodyType & CollisionObjectTypes.CO_GHOST_OBJECT) == 0)
- {
- m_log.ErrorFormat("{0} MakeSolid: physical body of wrong type for non-solidness. id={1}, type={2}", LogHeader, LocalID, bodyType);
- }
- CurrentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(PhysBody.ptr, CollisionFlags.CF_NO_CONTACT_RESPONSE);
-
- // Change collision info from a static object to a ghosty collision object
- PhysBody.collisionType = CollisionType.VolumeDetect;
- }
- }
-
- // Enable physical actions. Bullet will keep sleeping non-moving physical objects so
- // they need waking up when parameters are changed.
- // Called in taint-time!!
- private void ActivateIfPhysical(bool forceIt)
- {
- if (IsPhysical && PhysBody.HasPhysicalBody)
- BulletSimAPI.Activate2(PhysBody.ptr, forceIt);
- }
-
- // Turn on or off the flag controlling whether collision events are returned to the simulator.
- private void EnableCollisions(bool wantsCollisionEvents)
- {
- if (wantsCollisionEvents)
- {
- CurrentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(PhysBody.ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS);
- }
- else
- {
- CurrentCollisionFlags = BulletSimAPI.RemoveFromCollisionFlags2(PhysBody.ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS);
- }
- }
-
- // prims don't fly
- public override bool Flying {
- get { return _flying; }
- set {
- _flying = value;
- }
- }
- public override bool SetAlwaysRun {
- get { return _setAlwaysRun; }
- set { _setAlwaysRun = value; }
- }
- public override bool ThrottleUpdates {
- get { return _throttleUpdates; }
- set { _throttleUpdates = value; }
- }
- public override bool IsColliding {
- get { return (CollidingStep == PhysicsScene.SimulationStep); }
- set { _isColliding = value; }
- }
- public override bool CollidingGround {
- get { return (CollidingGroundStep == PhysicsScene.SimulationStep); }
- set { _collidingGround = value; }
- }
- public override bool CollidingObj {
- get { return _collidingObj; }
- set { _collidingObj = value; }
- }
- public bool IsPhantom {
- get {
- // SceneObjectPart removes phantom objects from the physics scene
- // so, although we could implement touching and such, we never
- // are invoked as a phantom object
- return false;
- }
- }
- public override bool FloatOnWater {
- set {
- _floatOnWater = value;
- PhysicsScene.TaintedObject("BSPrim.setFloatOnWater", delegate()
- {
- if (_floatOnWater)
- CurrentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(PhysBody.ptr, CollisionFlags.BS_FLOATS_ON_WATER);
- else
- CurrentCollisionFlags = BulletSimAPI.RemoveFromCollisionFlags2(PhysBody.ptr, CollisionFlags.BS_FLOATS_ON_WATER);
- });
- }
- }
- public override OMV.Vector3 RotationalVelocity {
- get {
- return _rotationalVelocity;
- }
- set {
- _rotationalVelocity = value;
- // m_log.DebugFormat("{0}: RotationalVelocity={1}", LogHeader, _rotationalVelocity);
- PhysicsScene.TaintedObject("BSPrim.setRotationalVelocity", delegate()
- {
- DetailLog("{0},BSPrim.SetRotationalVel,taint,rotvel={1}", LocalID, _rotationalVelocity);
- ForceRotationalVelocity = _rotationalVelocity;
- });
- }
- }
- public override OMV.Vector3 ForceRotationalVelocity {
- get {
- return _rotationalVelocity;
- }
- set {
- _rotationalVelocity = value;
- if (PhysBody.HasPhysicalBody)
- {
- BulletSimAPI.SetAngularVelocity2(PhysBody.ptr, _rotationalVelocity);
- ActivateIfPhysical(false);
- }
- }
- }
- public override bool Kinematic {
- get { return _kinematic; }
- set { _kinematic = value;
- // m_log.DebugFormat("{0}: Kinematic={1}", LogHeader, _kinematic);
- }
- }
- public override float Buoyancy {
- get { return _buoyancy; }
- set {
- _buoyancy = value;
- PhysicsScene.TaintedObject("BSPrim.setBuoyancy", delegate()
- {
- ForceBuoyancy = _buoyancy;
- });
- }
- }
- public override float ForceBuoyancy {
- get { return _buoyancy; }
- set {
- _buoyancy = value;
- // DetailLog("{0},BSPrim.setForceBuoyancy,taint,buoy={1}", LocalID, _buoyancy);
- // Force the recalculation of the various inertia,etc variables in the object
- UpdatePhysicalMassProperties(_mass, true);
- ActivateIfPhysical(false);
- }
- }
-
- // Used for MoveTo
- public override OMV.Vector3 PIDTarget {
- set { _PIDTarget = value; }
- }
- public override bool PIDActive {
- set { _usePID = value; }
- }
- public override float PIDTau {
- set { _PIDTau = value; }
- }
-
- // Used for llSetHoverHeight and maybe vehicle height
- // Hover Height will override MoveTo target's Z
- public override bool PIDHoverActive {
- set { _useHoverPID = value; }
- }
- public override float PIDHoverHeight {
- set { _PIDHoverHeight = value; }
- }
- public override PIDHoverType PIDHoverType {
- set { _PIDHoverType = value; }
- }
- public override float PIDHoverTau {
- set { _PIDHoverTao = value; }
- }
-
- // For RotLookAt
- public override OMV.Quaternion APIDTarget { set { return; } }
- public override bool APIDActive { set { return; } }
- public override float APIDStrength { set { return; } }
- public override float APIDDamping { set { return; } }
-
- public override void AddForce(OMV.Vector3 force, bool pushforce) {
- // Since this force is being applied in only one step, make this a force per second.
- OMV.Vector3 addForce = force / PhysicsScene.LastTimeStep;
- AddForce(addForce, pushforce, false);
- }
- // Applying a force just adds this to the total force on the object.
- // This added force will only last the next simulation tick.
- public void AddForce(OMV.Vector3 force, bool pushforce, bool inTaintTime) {
- // for an object, doesn't matter if force is a pushforce or not
- if (force.IsFinite())
- {
- float magnitude = force.Length();
- if (magnitude > 20000f)
- {
- // Force has a limit
- force = force / magnitude * 20000f;
- }
-
- OMV.Vector3 addForce = force;
- DetailLog("{0},BSPrim.addForce,call,force={1}", LocalID, addForce);
-
- PhysicsScene.TaintedObject(inTaintTime, "BSPrim.AddForce", delegate()
- {
- // Bullet adds this central force to the total force for this tick
- DetailLog("{0},BSPrim.addForce,taint,force={1}", LocalID, addForce);
- if (PhysBody.HasPhysicalBody)
- {
- BulletSimAPI.ApplyCentralForce2(PhysBody.ptr, addForce);
- ActivateIfPhysical(false);
- }
- });
- }
- else
- {
- m_log.WarnFormat("{0}: Got a NaN force applied to a prim. LocalID={1}", LogHeader, LocalID);
- return;
- }
- }
-
- public override void AddAngularForce(OMV.Vector3 force, bool pushforce) {
- AddAngularForce(force, pushforce, false);
- }
- public void AddAngularForce(OMV.Vector3 force, bool pushforce, bool inTaintTime)
- {
- if (force.IsFinite())
- {
- OMV.Vector3 angForce = force;
- PhysicsScene.TaintedObject(inTaintTime, "BSPrim.AddAngularForce", delegate()
- {
- if (PhysBody.HasPhysicalBody)
- {
- BulletSimAPI.ApplyTorque2(PhysBody.ptr, angForce);
- ActivateIfPhysical(false);
- }
- });
- }
- else
- {
- m_log.WarnFormat("{0}: Got a NaN force applied to a prim. LocalID={1}", LogHeader, LocalID);
- return;
- }
- }
-
- // A torque impulse.
- // ApplyTorqueImpulse adds torque directly to the angularVelocity.
- // AddAngularForce accumulates the force and applied it to the angular velocity all at once.
- // Computed as: angularVelocity += impulse * inertia;
- public void ApplyTorqueImpulse(OMV.Vector3 impulse, bool inTaintTime)
- {
- OMV.Vector3 applyImpulse = impulse;
- PhysicsScene.TaintedObject(inTaintTime, "BSPrim.ApplyTorqueImpulse", delegate()
- {
- if (PhysBody.HasPhysicalBody)
- {
- BulletSimAPI.ApplyTorqueImpulse2(PhysBody.ptr, applyImpulse);
- ActivateIfPhysical(false);
- }
- });
- }
-
- public override void SetMomentum(OMV.Vector3 momentum) {
- // DetailLog("{0},BSPrim.SetMomentum,call,mom={1}", LocalID, momentum);
- }
- #region Mass Calculation
-
- private float CalculateMass()
- {
- float volume = _size.X * _size.Y * _size.Z; // default
- float tmp;
-
- float returnMass = 0;
- float hollowAmount = (float)BaseShape.ProfileHollow * 2.0e-5f;
- float hollowVolume = hollowAmount * hollowAmount;
-
- switch (BaseShape.ProfileShape)
- {
- case ProfileShape.Square:
- // default box
-
- if (BaseShape.PathCurve == (byte)Extrusion.Straight)
- {
- if (hollowAmount > 0.0)
- {
- switch (BaseShape.HollowShape)
- {
- case HollowShape.Square:
- case HollowShape.Same:
- break;
-
- case HollowShape.Circle:
-
- hollowVolume *= 0.78539816339f;
- break;
-
- case HollowShape.Triangle:
-
- hollowVolume *= (0.5f * .5f);
- break;
-
- default:
- hollowVolume = 0;
- break;
- }
- volume *= (1.0f - hollowVolume);
- }
- }
-
- else if (BaseShape.PathCurve == (byte)Extrusion.Curve1)
- {
- //a tube
-
- volume *= 0.78539816339e-2f * (float)(200 - BaseShape.PathScaleX);
- tmp= 1.0f -2.0e-2f * (float)(200 - BaseShape.PathScaleY);
- volume -= volume*tmp*tmp;
-
- if (hollowAmount > 0.0)
- {
- hollowVolume *= hollowAmount;
-
- switch (BaseShape.HollowShape)
- {
- case HollowShape.Square:
- case HollowShape.Same:
- break;
-
- case HollowShape.Circle:
- hollowVolume *= 0.78539816339f;;
- break;
-
- case HollowShape.Triangle:
- hollowVolume *= 0.5f * 0.5f;
- break;
- default:
- hollowVolume = 0;
- break;
- }
- volume *= (1.0f - hollowVolume);
- }
- }
-
- break;
-
- case ProfileShape.Circle:
-
- if (BaseShape.PathCurve == (byte)Extrusion.Straight)
- {
- volume *= 0.78539816339f; // elipse base
-
- if (hollowAmount > 0.0)
- {
- switch (BaseShape.HollowShape)
- {
- case HollowShape.Same:
- case HollowShape.Circle:
- break;
-
- case HollowShape.Square:
- hollowVolume *= 0.5f * 2.5984480504799f;
- break;
-
- case HollowShape.Triangle:
- hollowVolume *= .5f * 1.27323954473516f;
- break;
-
- default:
- hollowVolume = 0;
- break;
- }
- volume *= (1.0f - hollowVolume);
- }
- }
-
- else if (BaseShape.PathCurve == (byte)Extrusion.Curve1)
- {
- volume *= 0.61685027506808491367715568749226e-2f * (float)(200 - BaseShape.PathScaleX);
- tmp = 1.0f - .02f * (float)(200 - BaseShape.PathScaleY);
- volume *= (1.0f - tmp * tmp);
-
- if (hollowAmount > 0.0)
- {
-
- // calculate the hollow volume by it's shape compared to the prim shape
- hollowVolume *= hollowAmount;
-
- switch (BaseShape.HollowShape)
- {
- case HollowShape.Same:
- case HollowShape.Circle:
- break;
-
- case HollowShape.Square:
- hollowVolume *= 0.5f * 2.5984480504799f;
- break;
-
- case HollowShape.Triangle:
- hollowVolume *= .5f * 1.27323954473516f;
- break;
-
- default:
- hollowVolume = 0;
- break;
- }
- volume *= (1.0f - hollowVolume);
- }
- }
- break;
-
- case ProfileShape.HalfCircle:
- if (BaseShape.PathCurve == (byte)Extrusion.Curve1)
- {
- volume *= 0.52359877559829887307710723054658f;
- }
- break;
-
- case ProfileShape.EquilateralTriangle:
-
- if (BaseShape.PathCurve == (byte)Extrusion.Straight)
- {
- volume *= 0.32475953f;
-
- if (hollowAmount > 0.0)
- {
-
- // calculate the hollow volume by it's shape compared to the prim shape
- switch (BaseShape.HollowShape)
- {
- case HollowShape.Same:
- case HollowShape.Triangle:
- hollowVolume *= .25f;
- break;
-
- case HollowShape.Square:
- hollowVolume *= 0.499849f * 3.07920140172638f;
- break;
-
- case HollowShape.Circle:
- // Hollow shape is a perfect cyllinder in respect to the cube's scale
- // Cyllinder hollow volume calculation
-
- hollowVolume *= 0.1963495f * 3.07920140172638f;
- break;
-
- default:
- hollowVolume = 0;
- break;
- }
- volume *= (1.0f - hollowVolume);
- }
- }
- else if (BaseShape.PathCurve == (byte)Extrusion.Curve1)
- {
- volume *= 0.32475953f;
- volume *= 0.01f * (float)(200 - BaseShape.PathScaleX);
- tmp = 1.0f - .02f * (float)(200 - BaseShape.PathScaleY);
- volume *= (1.0f - tmp * tmp);
-
- if (hollowAmount > 0.0)
- {
-
- hollowVolume *= hollowAmount;
-
- switch (BaseShape.HollowShape)
- {
- case HollowShape.Same:
- case HollowShape.Triangle:
- hollowVolume *= .25f;
- break;
-
- case HollowShape.Square:
- hollowVolume *= 0.499849f * 3.07920140172638f;
- break;
-
- case HollowShape.Circle:
-
- hollowVolume *= 0.1963495f * 3.07920140172638f;
- break;
-
- default:
- hollowVolume = 0;
- break;
- }
- volume *= (1.0f - hollowVolume);
- }
- }
- break;
-
- default:
- break;
- }
-
-
-
- float taperX1;
- float taperY1;
- float taperX;
- float taperY;
- float pathBegin;
- float pathEnd;
- float profileBegin;
- float profileEnd;
-
- if (BaseShape.PathCurve == (byte)Extrusion.Straight || BaseShape.PathCurve == (byte)Extrusion.Flexible)
- {
- taperX1 = BaseShape.PathScaleX * 0.01f;
- if (taperX1 > 1.0f)
- taperX1 = 2.0f - taperX1;
- taperX = 1.0f - taperX1;
-
- taperY1 = BaseShape.PathScaleY * 0.01f;
- if (taperY1 > 1.0f)
- taperY1 = 2.0f - taperY1;
- taperY = 1.0f - taperY1;
- }
- else
- {
- taperX = BaseShape.PathTaperX * 0.01f;
- if (taperX < 0.0f)
- taperX = -taperX;
- taperX1 = 1.0f - taperX;
-
- taperY = BaseShape.PathTaperY * 0.01f;
- if (taperY < 0.0f)
- taperY = -taperY;
- taperY1 = 1.0f - taperY;
-
- }
-
-
- volume *= (taperX1 * taperY1 + 0.5f * (taperX1 * taperY + taperX * taperY1) + 0.3333333333f * taperX * taperY);
-
- pathBegin = (float)BaseShape.PathBegin * 2.0e-5f;
- pathEnd = 1.0f - (float)BaseShape.PathEnd * 2.0e-5f;
- volume *= (pathEnd - pathBegin);
-
- // this is crude aproximation
- profileBegin = (float)BaseShape.ProfileBegin * 2.0e-5f;
- profileEnd = 1.0f - (float)BaseShape.ProfileEnd * 2.0e-5f;
- volume *= (profileEnd - profileBegin);
-
- returnMass = _density * volume;
-
- /* Comment out code that computes the mass of the linkset. That is done in the Linkset class.
- if (IsRootOfLinkset)
- {
- foreach (BSPrim prim in _childrenPrims)
- {
- returnMass += prim.CalculateMass();
- }
- }
- */
-
- returnMass = Util.Clamp(returnMass, BSParam.MinimumObjectMass, BSParam.MaximumObjectMass);
-
- return returnMass;
- }// end CalculateMass
- #endregion Mass Calculation
-
- // Rebuild the geometry and object.
- // This is called when the shape changes so we need to recreate the mesh/hull.
- // Called at taint-time!!!
- public void CreateGeomAndObject(bool forceRebuild)
- {
- // If this prim is part of a linkset, we must remove and restore the physical
- // links if the body is rebuilt.
- bool needToRestoreLinkset = false;
- bool needToRestoreVehicle = false;
-
- // Create the correct physical representation for this type of object.
- // Updates PhysBody and PhysShape with the new information.
- // Ignore 'forceRebuild'. This routine makes the right choices and changes of necessary.
- PhysicsScene.Shapes.GetBodyAndShape(false, PhysicsScene.World, this, null, delegate(BulletBody dBody)
- {
- // Called if the current prim body is about to be destroyed.
- // Remove all the physical dependencies on the old body.
- // (Maybe someday make the changing of BSShape an event to be subscribed to by BSLinkset, ...)
- needToRestoreLinkset = Linkset.RemoveBodyDependencies(this);
- needToRestoreVehicle = _vehicle.RemoveBodyDependencies(this);
- });
-
- if (needToRestoreLinkset)
- {
- // If physical body dependencies were removed, restore them
- Linkset.RestoreBodyDependencies(this);
- }
- if (needToRestoreVehicle)
- {
- // If physical body dependencies were removed, restore them
- _vehicle.RestoreBodyDependencies(this);
- }
-
- // Make sure the properties are set on the new object
- UpdatePhysicalParameters();
- return;
- }
-
- // The physics engine says that properties have updated. Update same and inform
- // the world that things have changed.
- // TODO: do we really need to check for changed? Maybe just copy values and call RequestPhysicsterseUpdate()
- enum UpdatedProperties {
- Position = 1 << 0,
- Rotation = 1 << 1,
- Velocity = 1 << 2,
- Acceleration = 1 << 3,
- RotationalVel = 1 << 4
- }
-
- const float ROTATION_TOLERANCE = 0.01f;
- const float VELOCITY_TOLERANCE = 0.001f;
- const float POSITION_TOLERANCE = 0.05f;
- const float ACCELERATION_TOLERANCE = 0.01f;
- const float ROTATIONAL_VELOCITY_TOLERANCE = 0.01f;
-
- public override void UpdateProperties(EntityProperties entprop)
- {
- // Updates only for individual prims and for the root object of a linkset.
- if (Linkset.IsRoot(this))
- {
- // A temporary kludge to suppress the rotational effects introduced on vehicles by Bullet
- // TODO: handle physics introduced by Bullet with computed vehicle physics.
- if (_vehicle.IsActive)
- {
- entprop.RotationalVelocity = OMV.Vector3.Zero;
- }
-
- // Assign directly to the local variables so the normal set action does not happen
- _position = entprop.Position;
- _orientation = entprop.Rotation;
- _velocity = entprop.Velocity;
- _acceleration = entprop.Acceleration;
- _rotationalVelocity = entprop.RotationalVelocity;
-
- // The sanity check can change the velocity and/or position.
- if (IsPhysical && PositionSanityCheck(true))
- {
- entprop.Position = _position;
- entprop.Velocity = _velocity;
- }
-
- OMV.Vector3 direction = OMV.Vector3.UnitX * _orientation; // DEBUG DEBUG DEBUG
- DetailLog("{0},BSPrim.UpdateProperties,call,pos={1},orient={2},dir={3},vel={4},rotVel={5}",
- LocalID, _position, _orientation, direction, _velocity, _rotationalVelocity);
-
- // remember the current and last set values
- LastEntityProperties = CurrentEntityProperties;
- CurrentEntityProperties = entprop;
-
- base.RequestPhysicsterseUpdate();
- }
- /*
- else
- {
- // For debugging, report the movement of children
- DetailLog("{0},BSPrim.UpdateProperties,child,pos={1},orient={2},vel={3},accel={4},rotVel={5}",
- LocalID, entprop.Position, entprop.Rotation, entprop.Velocity,
- entprop.Acceleration, entprop.RotationalVelocity);
- }
- */
-
- // The linkset implimentation might want to know about this.
- Linkset.UpdateProperties(this, true);
- }
-}
-}
diff --git a/OpenSim/Region/Physics/BulletSNPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSNPlugin/BSScene.cs
deleted file mode 100644
index 1a7c34b4ff..0000000000
--- a/OpenSim/Region/Physics/BulletSNPlugin/BSScene.cs
+++ /dev/null
@@ -1,957 +0,0 @@
-/*
- * Copyright (c) Contributors, http://opensimulator.org/
- * See CONTRIBUTORS.TXT for a full list of copyright holders.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyrightD
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * * Neither the name of the OpenSimulator Project nor the
- * names of its contributors may be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-using System;
-using System.Collections.Generic;
-using System.Runtime.InteropServices;
-using System.Text;
-using System.Threading;
-using OpenSim.Framework;
-using OpenSim.Region.Framework;
-using OpenSim.Region.CoreModules;
-using Logging = OpenSim.Region.CoreModules.Framework.Statistics.Logging;
-using OpenSim.Region.Physics.Manager;
-using Nini.Config;
-using log4net;
-using OpenMetaverse;
-
-// TODOs for BulletSim (for BSScene, BSPrim, BSCharacter and BulletSim)
-// Based on material, set density and friction
-// More efficient memory usage when passing hull information from BSPrim to BulletSim
-// Do attachments need to be handled separately? Need collision events. Do not collide with VolumeDetect
-// Implement LockAngularMotion
-// Add PID movement operations. What does ScenePresence.MoveToTarget do?
-// Check terrain size. 128 or 127?
-// Raycast
-//
-namespace OpenSim.Region.Physics.BulletSNPlugin
-{
-public sealed class BSScene : PhysicsScene, IPhysicsParameters
-{
- private static readonly ILog m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
- private static readonly string LogHeader = "[BULLETS SCENE]";
-
- // The name of the region we're working for.
- public string RegionName { get; private set; }
-
- public string BulletSimVersion = "?";
-
- public Dictionary PhysObjects;
- public BSShapeCollection Shapes;
-
- // Keeping track of the objects with collisions so we can report begin and end of a collision
- public HashSet ObjectsWithCollisions = new HashSet();
- public HashSet ObjectsWithNoMoreCollisions = new HashSet();
- // Keep track of all the avatars so we can send them a collision event
- // every tick so OpenSim will update its animation.
- private HashSet m_avatars = new HashSet();
-
- // let my minuions use my logger
- public ILog Logger { get { return m_log; } }
-
- public IMesher mesher;
- public uint WorldID { get; private set; }
- public BulletWorld World { get; private set; }
-
- // All the constraints that have been allocated in this instance.
- public BSConstraintCollection Constraints { get; private set; }
-
- // Simulation parameters
- internal int m_maxSubSteps;
- internal float m_fixedTimeStep;
- internal long m_simulationStep = 0;
- public long SimulationStep { get { return m_simulationStep; } }
- internal int m_taintsToProcessPerStep;
- internal float LastTimeStep { get; private set; }
-
- // Physical objects can register for prestep or poststep events
- public delegate void PreStepAction(float timeStep);
- public delegate void PostStepAction(float timeStep);
- public event PreStepAction BeforeStep;
- public event PreStepAction AfterStep;
-
- // A value of the time now so all the collision and update routines do not have to get their own
- // Set to 'now' just before all the prims and actors are called for collisions and updates
- public int SimulationNowTime { get; private set; }
-
- // True if initialized and ready to do simulation steps
- private bool m_initialized = false;
-
- // Flag which is true when processing taints.
- // Not guaranteed to be correct all the time (don't depend on this) but good for debugging.
- public bool InTaintTime { get; private set; }
-
- // Pinned memory used to pass step information between managed and unmanaged
- internal int m_maxCollisionsPerFrame;
- private List m_collisionArray;
- //private GCHandle m_collisionArrayPinnedHandle;
-
- internal int m_maxUpdatesPerFrame;
- private List m_updateArray;
- //private GCHandle m_updateArrayPinnedHandle;
-
-
- public const uint TERRAIN_ID = 0; // OpenSim senses terrain with a localID of zero
- public const uint GROUNDPLANE_ID = 1;
- public const uint CHILDTERRAIN_ID = 2; // Terrain allocated based on our mega-prim childre start here
-
- public float SimpleWaterLevel { get; set; }
- public BSTerrainManager TerrainManager { get; private set; }
-
- public ConfigurationParameters Params
- {
- get { return UnmanagedParams[0]; }
- }
- public Vector3 DefaultGravity
- {
- get { return new Vector3(0f, 0f, Params.gravity); }
- }
- // Just the Z value of the gravity
- public float DefaultGravityZ
- {
- get { return Params.gravity; }
- }
-
- // When functions in the unmanaged code must be called, it is only
- // done at a known time just before the simulation step. The taint
- // system saves all these function calls and executes them in
- // order before the simulation.
- public delegate void TaintCallback();
- private struct TaintCallbackEntry
- {
- public String ident;
- public TaintCallback callback;
- public TaintCallbackEntry(string i, TaintCallback c)
- {
- ident = i;
- callback = c;
- }
- }
- private Object _taintLock = new Object(); // lock for using the next object
- private List _taintOperations;
- private Dictionary _postTaintOperations;
- private List _postStepOperations;
-
- // A pointer to an instance if this structure is passed to the C++ code
- // Used to pass basic configuration values to the unmanaged code.
- internal ConfigurationParameters[] UnmanagedParams;
- //GCHandle m_paramsHandle;
-
- // Handle to the callback used by the unmanaged code to call into the managed code.
- // Used for debug logging.
- // Need to store the handle in a persistant variable so it won't be freed.
- private BulletSimAPI.DebugLogCallback m_DebugLogCallbackHandle;
-
- // Sometimes you just have to log everything.
- public Logging.LogWriter PhysicsLogging;
- private bool m_physicsLoggingEnabled;
- private string m_physicsLoggingDir;
- private string m_physicsLoggingPrefix;
- private int m_physicsLoggingFileMinutes;
- private bool m_physicsLoggingDoFlush;
- // 'true' of the vehicle code is to log lots of details
- public bool VehicleLoggingEnabled { get; private set; }
- public bool VehiclePhysicalLoggingEnabled { get; private set; }
-
- #region Construction and Initialization
- public BSScene(string identifier)
- {
- m_initialized = false;
- // we are passed the name of the region we're working for.
- RegionName = identifier;
- }
-
- public override void Initialise(IMesher meshmerizer, IConfigSource config)
- {
- mesher = meshmerizer;
- _taintOperations = new List();
- _postTaintOperations = new Dictionary();
- _postStepOperations = new List();
- PhysObjects = new Dictionary();
- Shapes = new BSShapeCollection(this);
-
- // Allocate pinned memory to pass parameters.
- UnmanagedParams = new ConfigurationParameters[1];
- //m_paramsHandle = GCHandle.Alloc(UnmanagedParams, GCHandleType.Pinned);
-
- // Set default values for physics parameters plus any overrides from the ini file
- GetInitialParameterValues(config);
-
- // allocate more pinned memory close to the above in an attempt to get the memory all together
- m_collisionArray = new List();
- //m_collisionArrayPinnedHandle = GCHandle.Alloc(m_collisionArray, GCHandleType.Pinned);
- m_updateArray = new List();
- //m_updateArrayPinnedHandle = GCHandle.Alloc(m_updateArray, GCHandleType.Pinned);
-
- // Enable very detailed logging.
- // By creating an empty logger when not logging, the log message invocation code
- // can be left in and every call doesn't have to check for null.
- if (m_physicsLoggingEnabled)
- {
- PhysicsLogging = new Logging.LogWriter(m_physicsLoggingDir, m_physicsLoggingPrefix, m_physicsLoggingFileMinutes);
- PhysicsLogging.ErrorLogger = m_log; // for DEBUG. Let's the logger output error messages.
- }
- else
- {
- PhysicsLogging = new Logging.LogWriter();
- }
-
- // If Debug logging level, enable logging from the unmanaged code
- m_DebugLogCallbackHandle = null;
- if (m_log.IsDebugEnabled || PhysicsLogging.Enabled)
- {
- m_log.DebugFormat("{0}: Initialize: Setting debug callback for unmanaged code", LogHeader);
- if (PhysicsLogging.Enabled)
- // The handle is saved in a variable to make sure it doesn't get freed after this call
- m_DebugLogCallbackHandle = new BulletSimAPI.DebugLogCallback(BulletLoggerPhysLog);
- else
- m_DebugLogCallbackHandle = new BulletSimAPI.DebugLogCallback(BulletLogger);
- }
-
- // Get the version of the DLL
- // TODO: this doesn't work yet. Something wrong with marshaling the returned string.
- // BulletSimVersion = BulletSimAPI.GetVersion();
- // m_log.WarnFormat("{0}: BulletSim.dll version='{1}'", LogHeader, BulletSimVersion);
-
- // The bounding box for the simulated world. The origin is 0,0,0 unless we're
- // a child in a mega-region.
- // Bullet actually doesn't care about the extents of the simulated
- // area. It tracks active objects no matter where they are.
- Vector3 worldExtent = new Vector3(Constants.RegionSize, Constants.RegionSize, Constants.RegionHeight);
-
- // m_log.DebugFormat("{0}: Initialize: Calling BulletSimAPI.Initialize.", LogHeader);
-
- World = new BulletWorld(0, this, BulletSimAPI.Initialize2(worldExtent, UnmanagedParams,
- m_maxCollisionsPerFrame, ref m_collisionArray,
- m_maxUpdatesPerFrame,ref m_updateArray,
- m_DebugLogCallbackHandle));
-
- Constraints = new BSConstraintCollection(World);
-
- TerrainManager = new BSTerrainManager(this);
- TerrainManager.CreateInitialGroundPlaneAndTerrain();
-
- m_log.WarnFormat("{0} Linksets implemented with {1}", LogHeader, (BSLinkset.LinksetImplementation)BSParam.LinksetImplementation);
-
- InTaintTime = false;
- m_initialized = true;
- }
-
- // All default parameter values are set here. There should be no values set in the
- // variable definitions.
- private void GetInitialParameterValues(IConfigSource config)
- {
- ConfigurationParameters parms = new ConfigurationParameters();
- UnmanagedParams[0] = parms;
-
- BSParam.SetParameterDefaultValues(this);
-
- if (config != null)
- {
- // If there are specifications in the ini file, use those values
- IConfig pConfig = config.Configs["BulletSim"];
- if (pConfig != null)
- {
- BSParam.SetParameterConfigurationValues(this, pConfig);
-
- // Very detailed logging for physics debugging
- m_physicsLoggingEnabled = pConfig.GetBoolean("PhysicsLoggingEnabled", false);
- m_physicsLoggingDir = pConfig.GetString("PhysicsLoggingDir", ".");
- m_physicsLoggingPrefix = pConfig.GetString("PhysicsLoggingPrefix", "physics-%REGIONNAME%-");
- m_physicsLoggingFileMinutes = pConfig.GetInt("PhysicsLoggingFileMinutes", 5);
- m_physicsLoggingDoFlush = pConfig.GetBoolean("PhysicsLoggingDoFlush", false);
- // Very detailed logging for vehicle debugging
- VehicleLoggingEnabled = pConfig.GetBoolean("VehicleLoggingEnabled", false);
- VehiclePhysicalLoggingEnabled = pConfig.GetBoolean("VehiclePhysicalLoggingEnabled", false);
-
- // Do any replacements in the parameters
- m_physicsLoggingPrefix = m_physicsLoggingPrefix.Replace("%REGIONNAME%", RegionName);
- }
-
- // The material characteristics.
- BSMaterials.InitializeFromDefaults(Params);
- if (pConfig != null)
- {
- // Let the user add new and interesting material property values.
- BSMaterials.InitializefromParameters(pConfig);
- }
- }
- }
-
- // A helper function that handles a true/false parameter and returns the proper float number encoding
- float ParamBoolean(IConfig config, string parmName, float deflt)
- {
- float ret = deflt;
- if (config.Contains(parmName))
- {
- ret = ConfigurationParameters.numericFalse;
- if (config.GetBoolean(parmName, false))
- {
- ret = ConfigurationParameters.numericTrue;
- }
- }
- return ret;
- }
-
- // Called directly from unmanaged code so don't do much
- private void BulletLogger(string msg)
- {
- m_log.Debug("[BULLETS UNMANAGED]:" + msg);
- }
-
- // Called directly from unmanaged code so don't do much
- private void BulletLoggerPhysLog(string msg)
- {
- DetailLog("[BULLETS UNMANAGED]:" + msg);
- }
-
- public override void Dispose()
- {
- // m_log.DebugFormat("{0}: Dispose()", LogHeader);
-
- // make sure no stepping happens while we're deleting stuff
- m_initialized = false;
-
- foreach (KeyValuePair kvp in PhysObjects)
- {
- kvp.Value.Destroy();
- }
- PhysObjects.Clear();
-
- // Now that the prims are all cleaned up, there should be no constraints left
- if (Constraints != null)
- {
- Constraints.Dispose();
- Constraints = null;
- }
-
- if (Shapes != null)
- {
- Shapes.Dispose();
- Shapes = null;
- }
-
- if (TerrainManager != null)
- {
- TerrainManager.ReleaseGroundPlaneAndTerrain();
- TerrainManager.Dispose();
- TerrainManager = null;
- }
-
- // Anything left in the unmanaged code should be cleaned out
- BulletSimAPI.Shutdown2(World.ptr);
-
- // Not logging any more
- PhysicsLogging.Close();
- }
- #endregion // Construction and Initialization
-
- #region Prim and Avatar addition and removal
-
- public override PhysicsActor AddAvatar(string avName, Vector3 position, Vector3 size, bool isFlying)
- {
- m_log.ErrorFormat("{0}: CALL TO AddAvatar in BSScene. NOT IMPLEMENTED", LogHeader);
- return null;
- }
-
- public override PhysicsActor AddAvatar(uint localID, string avName, Vector3 position, Vector3 size, bool isFlying)
- {
- // m_log.DebugFormat("{0}: AddAvatar: {1}", LogHeader, avName);
-
- if (!m_initialized) return null;
-
- BSCharacter actor = new BSCharacter(localID, avName, this, position, size, isFlying);
- lock (PhysObjects) PhysObjects.Add(localID, actor);
-
- // TODO: Remove kludge someday.
- // We must generate a collision for avatars whether they collide or not.
- // This is required by OpenSim to update avatar animations, etc.
- lock (m_avatars) m_avatars.Add(actor);
-
- return actor;
- }
-
- public override void RemoveAvatar(PhysicsActor actor)
- {
- // m_log.DebugFormat("{0}: RemoveAvatar", LogHeader);
-
- if (!m_initialized) return;
-
- BSCharacter bsactor = actor as BSCharacter;
- if (bsactor != null)
- {
- try
- {
- lock (PhysObjects) PhysObjects.Remove(actor.LocalID);
- // Remove kludge someday
- lock (m_avatars) m_avatars.Remove(bsactor);
- }
- catch (Exception e)
- {
- m_log.WarnFormat("{0}: Attempt to remove avatar that is not in physics scene: {1}", LogHeader, e);
- }
- bsactor.Destroy();
- // bsactor.dispose();
- }
- }
-
- public override void RemovePrim(PhysicsActor prim)
- {
- if (!m_initialized) return;
-
- BSPrim bsprim = prim as BSPrim;
- if (bsprim != null)
- {
- DetailLog("{0},RemovePrim,call", bsprim.LocalID);
- // m_log.DebugFormat("{0}: RemovePrim. id={1}/{2}", LogHeader, bsprim.Name, bsprim.LocalID);
- try
- {
- lock (PhysObjects) PhysObjects.Remove(bsprim.LocalID);
- }
- catch (Exception e)
- {
- m_log.ErrorFormat("{0}: Attempt to remove prim that is not in physics scene: {1}", LogHeader, e);
- }
- bsprim.Destroy();
- // bsprim.dispose();
- }
- else
- {
- m_log.ErrorFormat("{0}: Attempt to remove prim that is not a BSPrim type.", LogHeader);
- }
- }
-
- public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, Vector3 position,
- Vector3 size, Quaternion rotation, bool isPhysical, uint localID)
- {
- // m_log.DebugFormat("{0}: AddPrimShape2: {1}", LogHeader, primName);
-
- if (!m_initialized) return null;
-
- DetailLog("{0},AddPrimShape,call", localID);
-
- BSPrim prim = new BSPrim(localID, primName, this, position, size, rotation, pbs, isPhysical);
- lock (PhysObjects) PhysObjects.Add(localID, prim);
- return prim;
- }
-
- // This is a call from the simulator saying that some physical property has been updated.
- // The BulletSim driver senses the changing of relevant properties so this taint
- // information call is not needed.
- public override void AddPhysicsActorTaint(PhysicsActor prim) { }
-
- #endregion // Prim and Avatar addition and removal
-
- #region Simulation
- // Simulate one timestep
- public override float Simulate(float timeStep)
- {
- // prevent simulation until we've been initialized
- if (!m_initialized) return 5.0f;
-
- LastTimeStep = timeStep;
-
- int updatedEntityCount = 0;
- //Object updatedEntitiesPtr;
- int collidersCount = 0;
- //Object collidersPtr;
-
- int beforeTime = 0;
- int simTime = 0;
-
- // update the prim states while we know the physics engine is not busy
- int numTaints = _taintOperations.Count;
-
- InTaintTime = true; // Only used for debugging so locking is not necessary.
-
- ProcessTaints();
-
- // Some of the physical objects requre individual, pre-step calls
- TriggerPreStepEvent(timeStep);
-
- // the prestep actions might have added taints
- ProcessTaints();
-
- InTaintTime = false; // Only used for debugging so locking is not necessary.
-
- // The following causes the unmanaged code to output ALL the values found in ALL the objects in the world.
- // Only enable this in a limited test world with few objects.
- // BulletSimAPI.DumpAllInfo2(World.ptr); // DEBUG DEBUG DEBUG
-
- // step the physical world one interval
- m_simulationStep++;
- int numSubSteps = 0;
-
- try
- {
- if (PhysicsLogging.Enabled) beforeTime = Util.EnvironmentTickCount();
-
- numSubSteps = BulletSimAPI.PhysicsStep2(World.ptr, timeStep, m_maxSubSteps, m_fixedTimeStep,
- out updatedEntityCount, out m_updateArray, out collidersCount, out m_collisionArray);
-
- if (PhysicsLogging.Enabled) simTime = Util.EnvironmentTickCountSubtract(beforeTime);
- DetailLog("{0},Simulate,call, frame={1}, nTaints={2}, simTime={3}, substeps={4}, updates={5}, colliders={6}, objWColl={7}",
- DetailLogZero, m_simulationStep, numTaints, simTime, numSubSteps,
- updatedEntityCount, collidersCount, ObjectsWithCollisions.Count);
- }
- catch (Exception e)
- {
- m_log.WarnFormat("{0},PhysicsStep Exception: nTaints={1}, substeps={2}, updates={3}, colliders={4}, e={5}",
- LogHeader, numTaints, numSubSteps, updatedEntityCount, collidersCount, e);
- DetailLog("{0},PhysicsStepException,call, nTaints={1}, substeps={2}, updates={3}, colliders={4}",
- DetailLogZero, numTaints, numSubSteps, updatedEntityCount, collidersCount);
- updatedEntityCount = 0;
- collidersCount = 0;
- }
-
- // Don't have to use the pointers passed back since we know it is the same pinned memory we passed in.
-
- // Get a value for 'now' so all the collision and update routines don't have to get their own.
- SimulationNowTime = Util.EnvironmentTickCount();
-
- // If there were collisions, process them by sending the event to the prim.
- // Collisions must be processed before updates.
- if (collidersCount > 0)
- {
- for (int ii = 0; ii < collidersCount; ii++)
- {
- uint cA = m_collisionArray[ii].aID;
- uint cB = m_collisionArray[ii].bID;
- Vector3 point = new Vector3(m_collisionArray[ii].point.X, m_collisionArray[ii].point.Y,
- m_collisionArray[ii].point.Z);
- Vector3 normal = new Vector3(m_collisionArray[ii].normal.X, m_collisionArray[ii].normal.Y,
- m_collisionArray[ii].normal.Z);
- SendCollision(cA, cB, point, normal, 0.01f);
- SendCollision(cB, cA, point, -normal, 0.01f);
- }
- }
-
- // The above SendCollision's batch up the collisions on the objects.
- // Now push the collisions into the simulator.
- if (ObjectsWithCollisions.Count > 0)
- {
- foreach (BSPhysObject bsp in ObjectsWithCollisions)
- if (!bsp.SendCollisions())
- {
- // If the object is done colliding, see that it's removed from the colliding list
- ObjectsWithNoMoreCollisions.Add(bsp);
- }
- }
-
- // This is a kludge to get avatar movement updates.
- // The simulator expects collisions for avatars even if there are have been no collisions.
- // The event updates avatar animations and stuff.
- // If you fix avatar animation updates, remove this overhead and let normal collision processing happen.
- foreach (BSPhysObject bsp in m_avatars)
- if (!ObjectsWithCollisions.Contains(bsp)) // don't call avatars twice
- bsp.SendCollisions();
-
- // Objects that are done colliding are removed from the ObjectsWithCollisions list.
- // Not done above because it is inside an iteration of ObjectWithCollisions.
- // This complex collision processing is required to create an empty collision
- // event call after all collisions have happened on an object. This enables
- // the simulator to generate the 'collision end' event.
- if (ObjectsWithNoMoreCollisions.Count > 0)
- {
- foreach (BSPhysObject po in ObjectsWithNoMoreCollisions)
- ObjectsWithCollisions.Remove(po);
- ObjectsWithNoMoreCollisions.Clear();
- }
- // Done with collisions.
-
- // If any of the objects had updated properties, tell the object it has been changed by the physics engine
- if (updatedEntityCount > 0)
- {
- for (int ii = 0; ii < updatedEntityCount; ii++)
- {
-
- BulletXNA.EntityProperties entprop = m_updateArray[ii];
- BSPhysObject pobj;
- if (PhysObjects.TryGetValue(entprop.ID, out pobj))
- {
- EntityProperties prop = new EntityProperties()
- {
- Acceleration = new Vector3(entprop.Acceleration.X, entprop.Acceleration.Y, entprop.Acceleration.Z),
- ID = entprop.ID,
- Position = new Vector3(entprop.Position.X,entprop.Position.Y,entprop.Position.Z),
- Rotation = new Quaternion(entprop.Rotation.X,entprop.Rotation.Y,entprop.Rotation.Z,entprop.Rotation.W),
- RotationalVelocity = new Vector3(entprop.AngularVelocity.X,entprop.AngularVelocity.Y,entprop.AngularVelocity.Z),
- Velocity = new Vector3(entprop.Velocity.X,entprop.Velocity.Y,entprop.Velocity.Z)
- };
- //m_log.Debug(pobj.Name + ":" + prop.ToString() + "\n");
- pobj.UpdateProperties(prop);
- }
- }
- }
-
- TriggerPostStepEvent(timeStep);
-
- // The following causes the unmanaged code to output ALL the values found in ALL the objects in the world.
- // Only enable this in a limited test world with few objects.
- // BulletSimAPI.DumpAllInfo2(World.ptr); // DEBUG DEBUG DEBUG
-
- // The physics engine returns the number of milliseconds it simulated this call.
- // These are summed and normalized to one second and divided by 1000 to give the reported physics FPS.
- // Multiply by 55 to give a nominal frame rate of 55.
- return (float)numSubSteps * m_fixedTimeStep * 1000f * 55f;
- }
-
- // Something has collided
- private void SendCollision(uint localID, uint collidingWith, Vector3 collidePoint, Vector3 collideNormal, float penetration)
- {
- if (localID <= TerrainManager.HighestTerrainID)
- {
- return; // don't send collisions to the terrain
- }
-
- BSPhysObject collider;
- if (!PhysObjects.TryGetValue(localID, out collider))
- {
- // If the object that is colliding cannot be found, just ignore the collision.
- DetailLog("{0},BSScene.SendCollision,colliderNotInObjectList,id={1},with={2}", DetailLogZero, localID, collidingWith);
- return;
- }
-
- // The terrain is not in the physical object list so 'collidee' can be null when Collide() is called.
- BSPhysObject collidee = null;
- PhysObjects.TryGetValue(collidingWith, out collidee);
-
- // DetailLog("{0},BSScene.SendCollision,collide,id={1},with={2}", DetailLogZero, localID, collidingWith);
-
- if (collider.Collide(collidingWith, collidee, collidePoint, collideNormal, penetration))
- {
- // If a collision was posted, remember to send it to the simulator
- ObjectsWithCollisions.Add(collider);
- }
-
- return;
- }
-
- #endregion // Simulation
-
- public override void GetResults() { }
-
- #region Terrain
-
- public override void SetTerrain(float[] heightMap) {
- TerrainManager.SetTerrain(heightMap);
- }
-
- public override void SetWaterLevel(float baseheight)
- {
- SimpleWaterLevel = baseheight;
- }
-
- public override void DeleteTerrain()
- {
- // m_log.DebugFormat("{0}: DeleteTerrain()", LogHeader);
- }
-
- // Although no one seems to check this, I do support combining.
- public override bool SupportsCombining()
- {
- return TerrainManager.SupportsCombining();
- }
- // This call says I am a child to region zero in a mega-region. 'pScene' is that
- // of region zero, 'offset' is my offset from regions zero's origin, and
- // 'extents' is the largest XY that is handled in my region.
- public override void Combine(PhysicsScene pScene, Vector3 offset, Vector3 extents)
- {
- TerrainManager.Combine(pScene, offset, extents);
- }
-
- // Unhook all the combining that I know about.
- public override void UnCombine(PhysicsScene pScene)
- {
- TerrainManager.UnCombine(pScene);
- }
-
- #endregion // Terrain
-
- public override Dictionary GetTopColliders()
- {
- return new Dictionary();
- }
-
- public override bool IsThreaded { get { return false; } }
-
- #region Taints
- // The simulation execution order is:
- // Simulate()
- // DoOneTimeTaints
- // TriggerPreStepEvent
- // DoOneTimeTaints
- // Step()
- // ProcessAndForwardCollisions
- // ProcessAndForwardPropertyUpdates
- // TriggerPostStepEvent
-
- // Calls to the PhysicsActors can't directly call into the physics engine
- // because it might be busy. We delay changes to a known time.
- // We rely on C#'s closure to save and restore the context for the delegate.
- public void TaintedObject(String ident, TaintCallback callback)
- {
- if (!m_initialized) return;
-
- lock (_taintLock)
- {
- _taintOperations.Add(new TaintCallbackEntry(ident, callback));
- }
-
- return;
- }
-
- // Sometimes a potentially tainted operation can be used in and out of taint time.
- // This routine executes the command immediately if in taint-time otherwise it is queued.
- public void TaintedObject(bool inTaintTime, string ident, TaintCallback callback)
- {
- if (inTaintTime)
- callback();
- else
- TaintedObject(ident, callback);
- }
-
- private void TriggerPreStepEvent(float timeStep)
- {
- PreStepAction actions = BeforeStep;
- if (actions != null)
- actions(timeStep);
-
- }
-
- private void TriggerPostStepEvent(float timeStep)
- {
- PreStepAction actions = AfterStep;
- if (actions != null)
- actions(timeStep);
-
- }
-
- // When someone tries to change a property on a BSPrim or BSCharacter, the object queues
- // a callback into itself to do the actual property change. That callback is called
- // here just before the physics engine is called to step the simulation.
- public void ProcessTaints()
- {
- ProcessRegularTaints();
- ProcessPostTaintTaints();
- }
-
- private void ProcessRegularTaints()
- {
- if (_taintOperations.Count > 0) // save allocating new list if there is nothing to process
- {
- // swizzle a new list into the list location so we can process what's there
- List oldList;
- lock (_taintLock)
- {
- oldList = _taintOperations;
- _taintOperations = new List();
- }
-
- foreach (TaintCallbackEntry tcbe in oldList)
- {
- try
- {
- DetailLog("{0},BSScene.ProcessTaints,doTaint,id={1}", DetailLogZero, tcbe.ident); // DEBUG DEBUG DEBUG
- tcbe.callback();
- }
- catch (Exception e)
- {
- m_log.ErrorFormat("{0}: ProcessTaints: {1}: Exception: {2}", LogHeader, tcbe.ident, e);
- }
- }
- oldList.Clear();
- }
- }
-
- // Schedule an update to happen after all the regular taints are processed.
- // Note that new requests for the same operation ("ident") for the same object ("ID")
- // will replace any previous operation by the same object.
- public void PostTaintObject(String ident, uint ID, TaintCallback callback)
- {
- string uniqueIdent = ident + "-" + ID.ToString();
- lock (_taintLock)
- {
- _postTaintOperations[uniqueIdent] = new TaintCallbackEntry(uniqueIdent, callback);
- }
-
- return;
- }
-
- // Taints that happen after the normal taint processing but before the simulation step.
- private void ProcessPostTaintTaints()
- {
- if (_postTaintOperations.Count > 0)
- {
- Dictionary oldList;
- lock (_taintLock)
- {
- oldList = _postTaintOperations;
- _postTaintOperations = new Dictionary();
- }
-
- foreach (KeyValuePair kvp in oldList)
- {
- try
- {
- DetailLog("{0},BSScene.ProcessPostTaintTaints,doTaint,id={1}", DetailLogZero, kvp.Key); // DEBUG DEBUG DEBUG
- kvp.Value.callback();
- }
- catch (Exception e)
- {
- m_log.ErrorFormat("{0}: ProcessPostTaintTaints: {1}: Exception: {2}", LogHeader, kvp.Key, e);
- }
- }
- oldList.Clear();
- }
- }
-
- // Only used for debugging. Does not change state of anything so locking is not necessary.
- public bool AssertInTaintTime(string whereFrom)
- {
- if (!InTaintTime)
- {
- DetailLog("{0},BSScene.AssertInTaintTime,NOT IN TAINT TIME,Region={1},Where={2}", DetailLogZero, RegionName, whereFrom);
- m_log.ErrorFormat("{0} NOT IN TAINT TIME!! Region={1}, Where={2}", LogHeader, RegionName, whereFrom);
- Util.PrintCallStack(DetailLog);
- }
- return InTaintTime;
- }
-
- #endregion // Taints
-
- #region INI and command line parameter processing
-
- #region IPhysicsParameters
- // Get the list of parameters this physics engine supports
- public PhysParameterEntry[] GetParameterList()
- {
- BSParam.BuildParameterTable();
- return BSParam.SettableParameters;
- }
-
- // Set parameter on a specific or all instances.
- // Return 'false' if not able to set the parameter.
- // Setting the value in the m_params block will change the value the physics engine
- // will use the next time since it's pinned and shared memory.
- // Some of the values require calling into the physics engine to get the new
- // value activated ('terrainFriction' for instance).
- public bool SetPhysicsParameter(string parm, float val, uint localID)
- {
- bool ret = false;
- BSParam.ParameterDefn theParam;
- if (BSParam.TryGetParameter(parm, out theParam))
- {
- theParam.setter(this, parm, localID, val);
- ret = true;
- }
- return ret;
- }
-
- // update all the localIDs specified
- // If the local ID is APPLY_TO_NONE, just change the default value
- // If the localID is APPLY_TO_ALL change the default value and apply the new value to all the lIDs
- // If the localID is a specific object, apply the parameter change to only that object
- internal delegate void AssignVal(float x);
- internal void UpdateParameterObject(AssignVal setDefault, string parm, uint localID, float val)
- {
- List objectIDs = new List();
- switch (localID)
- {
- case PhysParameterEntry.APPLY_TO_NONE:
- setDefault(val); // setting only the default value
- // This will cause a call into the physical world if some operation is specified (SetOnObject).
- objectIDs.Add(TERRAIN_ID);
- TaintedUpdateParameter(parm, objectIDs, val);
- break;
- case PhysParameterEntry.APPLY_TO_ALL:
- setDefault(val); // setting ALL also sets the default value
- lock (PhysObjects) objectIDs = new List(PhysObjects.Keys);
- TaintedUpdateParameter(parm, objectIDs, val);
- break;
- default:
- // setting only one localID
- objectIDs.Add(localID);
- TaintedUpdateParameter(parm, objectIDs, val);
- break;
- }
- }
-
- // schedule the actual updating of the paramter to when the phys engine is not busy
- private void TaintedUpdateParameter(string parm, List lIDs, float val)
- {
- float xval = val;
- List xlIDs = lIDs;
- string xparm = parm;
- TaintedObject("BSScene.UpdateParameterSet", delegate() {
- BSParam.ParameterDefn thisParam;
- if (BSParam.TryGetParameter(xparm, out thisParam))
- {
- if (thisParam.onObject != null)
- {
- foreach (uint lID in xlIDs)
- {
- BSPhysObject theObject = null;
- PhysObjects.TryGetValue(lID, out theObject);
- thisParam.onObject(this, theObject, xval);
- }
- }
- }
- });
- }
-
- // Get parameter.
- // Return 'false' if not able to get the parameter.
- public bool GetPhysicsParameter(string parm, out float value)
- {
- float val = 0f;
- bool ret = false;
- BSParam.ParameterDefn theParam;
- if (BSParam.TryGetParameter(parm, out theParam))
- {
- val = theParam.getter(this);
- ret = true;
- }
- value = val;
- return ret;
- }
-
- #endregion IPhysicsParameters
-
- #endregion Runtime settable parameters
-
- // Invoke the detailed logger and output something if it's enabled.
- public void DetailLog(string msg, params Object[] args)
- {
- PhysicsLogging.Write(msg, args);
- // Add the Flush() if debugging crashes. Gets all the messages written out.
- if (m_physicsLoggingDoFlush) PhysicsLogging.Flush();
- }
- // Used to fill in the LocalID when there isn't one. It's the correct number of characters.
- public const string DetailLogZero = "0000000000";
-
-}
-}
diff --git a/OpenSim/Region/Physics/BulletSNPlugin/BSShapeCollection.cs b/OpenSim/Region/Physics/BulletSNPlugin/BSShapeCollection.cs
deleted file mode 100644
index 47fb76870e..0000000000
--- a/OpenSim/Region/Physics/BulletSNPlugin/BSShapeCollection.cs
+++ /dev/null
@@ -1,1015 +0,0 @@
-/*
- * Copyright (c) Contributors, http://opensimulator.org/
- * See CONTRIBUTORS.TXT for a full list of copyright holders.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyrightD
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * * Neither the name of the OpenSimulator Project nor the
- * names of its contributors may be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-using System;
-using System.Collections.Generic;
-using System.Text;
-using OMV = OpenMetaverse;
-using OpenSim.Framework;
-using OpenSim.Region.Physics.Manager;
-using OpenSim.Region.Physics.ConvexDecompositionDotNet;
-
-namespace OpenSim.Region.Physics.BulletSNPlugin
-{
-public sealed class BSShapeCollection : IDisposable
-{
- private static string LogHeader = "[BULLETSIM SHAPE COLLECTION]";
-
- private BSScene PhysicsScene { get; set; }
-
- private Object m_collectionActivityLock = new Object();
-
- // Description of a Mesh
- private struct MeshDesc
- {
- public Object ptr;
- public int referenceCount;
- public DateTime lastReferenced;
- public UInt64 shapeKey;
- }
-
- // Description of a hull.
- // Meshes and hulls have the same shape hash key but we only need hulls for efficient collision calculations.
- private struct HullDesc
- {
- public Object ptr;
- public int referenceCount;
- public DateTime lastReferenced;
- public UInt64 shapeKey;
- }
-
- // The sharable set of meshes and hulls. Indexed by their shape hash.
- private Dictionary Meshes = new Dictionary();
- private Dictionary Hulls = new Dictionary();
-
- private bool DDetail = false;
-
- public BSShapeCollection(BSScene physScene)
- {
- PhysicsScene = physScene;
- // Set the next to 'true' for very detailed shape update detailed logging (detailed details?)
- // While detailed debugging is still active, this is better than commenting out all the
- // DetailLog statements. When debugging slows down, this and the protected logging
- // statements can be commented/removed.
- DDetail = true;
- }
-
- public void Dispose()
- {
- // TODO!!!!!!!!!
- }
-
- // Callbacks called just before either the body or shape is destroyed.
- // Mostly used for changing bodies out from under Linksets.
- // Useful for other cases where parameters need saving.
- // Passing 'null' says no callback.
- public delegate void ShapeDestructionCallback(BulletShape shape);
- public delegate void BodyDestructionCallback(BulletBody body);
-
- // Called to update/change the body and shape for an object.
- // First checks the shape and updates that if necessary then makes
- // sure the body is of the right type.
- // Return 'true' if either the body or the shape changed.
- // 'shapeCallback' and 'bodyCallback' are, if non-null, functions called just before
- // the current shape or body is destroyed. This allows the caller to remove any
- // higher level dependencies on the shape or body. Mostly used for LinkSets to
- // remove the physical constraints before the body is destroyed.
- // Called at taint-time!!
- public bool GetBodyAndShape(bool forceRebuild, BulletWorld sim, BSPhysObject prim,
- ShapeDestructionCallback shapeCallback, BodyDestructionCallback bodyCallback)
- {
- PhysicsScene.AssertInTaintTime("BSShapeCollection.GetBodyAndShape");
-
- bool ret = false;
-
- // This lock could probably be pushed down lower but building shouldn't take long
- lock (m_collectionActivityLock)
- {
- // Do we have the correct geometry for this type of object?
- // Updates prim.BSShape with information/pointers to shape.
- // Returns 'true' of BSShape is changed to a new shape.
- bool newGeom = CreateGeom(forceRebuild, prim, shapeCallback);
- // If we had to select a new shape geometry for the object,
- // rebuild the body around it.
- // Updates prim.BSBody with information/pointers to requested body
- // Returns 'true' if BSBody was changed.
- bool newBody = CreateBody((newGeom || forceRebuild), prim, PhysicsScene.World,
- prim.PhysShape, bodyCallback);
- ret = newGeom || newBody;
- }
- DetailLog("{0},BSShapeCollection.GetBodyAndShape,taintExit,force={1},ret={2},body={3},shape={4}",
- prim.LocalID, forceRebuild, ret, prim.PhysBody, prim.PhysShape);
-
- return ret;
- }
-
- public bool GetBodyAndShape(bool forceRebuild, BulletWorld sim, BSPhysObject prim)
- {
- return GetBodyAndShape(forceRebuild, sim, prim, null, null);
- }
-
- // Track another user of a body.
- // We presume the caller has allocated the body.
- // Bodies only have one user so the body is just put into the world if not already there.
- public void ReferenceBody(BulletBody body, bool inTaintTime)
- {
- lock (m_collectionActivityLock)
- {
- if (DDetail) DetailLog("{0},BSShapeCollection.ReferenceBody,newBody,body={1}", body.ID, body);
- PhysicsScene.TaintedObject(inTaintTime, "BSShapeCollection.ReferenceBody", delegate()
- {
- if (!BulletSimAPI.IsInWorld2(PhysicsScene.World.ptr, body.ptr))
- {
- BulletSimAPI.AddObjectToWorld2(PhysicsScene.World.ptr, body.ptr);
- if (DDetail) DetailLog("{0},BSShapeCollection.ReferenceBody,addedToWorld,ref={1}", body.ID, body);
- }
- });
- }
- }
-
- // Release the usage of a body.
- // Called when releasing use of a BSBody. BSShape is handled separately.
- public void DereferenceBody(BulletBody body, bool inTaintTime, BodyDestructionCallback bodyCallback )
- {
- if (!body.HasPhysicalBody)
- return;
-
- lock (m_collectionActivityLock)
- {
- PhysicsScene.TaintedObject(inTaintTime, "BSShapeCollection.DereferenceBody", delegate()
- {
- if (DDetail) DetailLog("{0},BSShapeCollection.DereferenceBody,DestroyingBody,body={1},inTaintTime={2}",
- body.ID, body, inTaintTime);
- // If the caller needs to know the old body is going away, pass the event up.
- if (bodyCallback != null) bodyCallback(body);
-
- if (BulletSimAPI.IsInWorld2(PhysicsScene.World.ptr, body.ptr))
- {
- BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.ptr, body.ptr);
- if (DDetail) DetailLog("{0},BSShapeCollection.DereferenceBody,removingFromWorld. Body={1}", body.ID, body);
- }
-
- // Zero any reference to the shape so it is not freed when the body is deleted.
- BulletSimAPI.SetCollisionShape2(PhysicsScene.World.ptr, body.ptr, null);
- BulletSimAPI.DestroyObject2(PhysicsScene.World.ptr, body.ptr);
- });
- }
- }
-
- // Track the datastructures and use count for a shape.
- // When creating a hull, this is called first to reference the mesh
- // and then again to reference the hull.
- // Meshes and hulls for the same shape have the same hash key.
- // NOTE that native shapes are not added to the mesh list or removed.
- // Returns 'true' if this is the initial reference to the shape. Otherwise reused.
- public bool ReferenceShape(BulletShape shape)
- {
- bool ret = false;
- switch (shape.type)
- {
- case BSPhysicsShapeType.SHAPE_MESH:
- MeshDesc meshDesc;
- if (Meshes.TryGetValue(shape.shapeKey, out meshDesc))
- {
- // There is an existing instance of this mesh.
- meshDesc.referenceCount++;
- if (DDetail) DetailLog("{0},BSShapeCollection.ReferenceShape,existingMesh,key={1},cnt={2}",
- BSScene.DetailLogZero, shape.shapeKey.ToString("X"), meshDesc.referenceCount);
- }
- else
- {
- // This is a new reference to a mesh
- meshDesc.ptr = shape.ptr;
- meshDesc.shapeKey = shape.shapeKey;
- // We keep a reference to the underlying IMesh data so a hull can be built
- meshDesc.referenceCount = 1;
- if (DDetail) DetailLog("{0},BSShapeCollection.ReferenceShape,newMesh,key={1},cnt={2}",
- BSScene.DetailLogZero, shape.shapeKey.ToString("X"), meshDesc.referenceCount);
- ret = true;
- }
- meshDesc.lastReferenced = System.DateTime.Now;
- Meshes[shape.shapeKey] = meshDesc;
- break;
- case BSPhysicsShapeType.SHAPE_HULL:
- HullDesc hullDesc;
- if (Hulls.TryGetValue(shape.shapeKey, out hullDesc))
- {
- // There is an existing instance of this hull.
- hullDesc.referenceCount++;
- if (DDetail) DetailLog("{0},BSShapeCollection.ReferenceShape,existingHull,key={1},cnt={2}",
- BSScene.DetailLogZero, shape.shapeKey.ToString("X"), hullDesc.referenceCount);
- }
- else
- {
- // This is a new reference to a hull
- hullDesc.ptr = shape.ptr;
- hullDesc.shapeKey = shape.shapeKey;
- hullDesc.referenceCount = 1;
- if (DDetail) DetailLog("{0},BSShapeCollection.ReferenceShape,newHull,key={1},cnt={2}",
- BSScene.DetailLogZero, shape.shapeKey.ToString("X"), hullDesc.referenceCount);
- ret = true;
-
- }
- hullDesc.lastReferenced = System.DateTime.Now;
- Hulls[shape.shapeKey] = hullDesc;
- break;
- case BSPhysicsShapeType.SHAPE_UNKNOWN:
- break;
- default:
- // Native shapes are not tracked and they don't go into any list
- break;
- }
- return ret;
- }
-
- // Release the usage of a shape.
- public void DereferenceShape(BulletShape shape, bool inTaintTime, ShapeDestructionCallback shapeCallback)
- {
- if (!shape.HasPhysicalShape)
- return;
-
- PhysicsScene.TaintedObject(inTaintTime, "BSShapeCollection.DereferenceShape", delegate()
- {
- if (shape.HasPhysicalShape)
- {
- if (shape.isNativeShape)
- {
- // Native shapes are not tracked and are released immediately
- if (DDetail) DetailLog("{0},BSShapeCollection.DereferenceShape,deleteNativeShape,ptr={1},taintTime={2}",
- BSScene.DetailLogZero, shape.ptr.ToString(), inTaintTime);
- if (shapeCallback != null) shapeCallback(shape);
- BulletSimAPI.DeleteCollisionShape2(PhysicsScene.World.ptr, shape.ptr);
- }
- else
- {
- switch (shape.type)
- {
- case BSPhysicsShapeType.SHAPE_HULL:
- DereferenceHull(shape, shapeCallback);
- break;
- case BSPhysicsShapeType.SHAPE_MESH:
- DereferenceMesh(shape, shapeCallback);
- break;
- case BSPhysicsShapeType.SHAPE_COMPOUND:
- DereferenceCompound(shape, shapeCallback);
- break;
- case BSPhysicsShapeType.SHAPE_UNKNOWN:
- break;
- default:
- break;
- }
- }
- }
- });
- }
-
- // Count down the reference count for a mesh shape
- // Called at taint-time.
- private void DereferenceMesh(BulletShape shape, ShapeDestructionCallback shapeCallback)
- {
- MeshDesc meshDesc;
- if (Meshes.TryGetValue(shape.shapeKey, out meshDesc))
- {
- meshDesc.referenceCount--;
- // TODO: release the Bullet storage
- if (shapeCallback != null) shapeCallback(shape);
- meshDesc.lastReferenced = System.DateTime.Now;
- Meshes[shape.shapeKey] = meshDesc;
- if (DDetail) DetailLog("{0},BSShapeCollection.DereferenceMesh,shape={1},refCnt={2}",
- BSScene.DetailLogZero, shape, meshDesc.referenceCount);
-
- }
- }
-
- // Count down the reference count for a hull shape
- // Called at taint-time.
- private void DereferenceHull(BulletShape shape, ShapeDestructionCallback shapeCallback)
- {
- HullDesc hullDesc;
- if (Hulls.TryGetValue(shape.shapeKey, out hullDesc))
- {
- hullDesc.referenceCount--;
- // TODO: release the Bullet storage (aging old entries?)
-
- // Tell upper layers that, if they have dependencies on this shape, this link is going away
- if (shapeCallback != null) shapeCallback(shape);
-
- hullDesc.lastReferenced = System.DateTime.Now;
- Hulls[shape.shapeKey] = hullDesc;
- if (DDetail) DetailLog("{0},BSShapeCollection.DereferenceHull,shape={1},refCnt={2}",
- BSScene.DetailLogZero, shape, hullDesc.referenceCount);
- }
- }
-
- // Remove a reference to a compound shape.
- // Taking a compound shape apart is a little tricky because if you just delete the
- // physical shape, it will free all the underlying children. We can't do that because
- // they could be shared. So, this removes each of the children from the compound and
- // dereferences them separately before destroying the compound collision object itself.
- // Called at taint-time.
- private void DereferenceCompound(BulletShape shape, ShapeDestructionCallback shapeCallback)
- {
- if (!BulletSimAPI.IsCompound2(shape.ptr))
- {
- // Failed the sanity check!!
- PhysicsScene.Logger.ErrorFormat("{0} Attempt to free a compound shape that is not compound!! type={1}, ptr={2}",
- LogHeader, shape.type, shape.ptr.ToString());
- if (DDetail) DetailLog("{0},BSShapeCollection.DereferenceCompound,notACompoundShape,type={1},ptr={2}",
- BSScene.DetailLogZero, shape.type, shape.ptr.ToString());
- return;
- }
-
- int numChildren = BulletSimAPI.GetNumberOfCompoundChildren2(shape.ptr);
- if (DDetail) DetailLog("{0},BSShapeCollection.DereferenceCompound,shape={1},children={2}", BSScene.DetailLogZero, shape, numChildren);
-
- for (int ii = numChildren - 1; ii >= 0; ii--)
- {
- Object childShape = BulletSimAPI.RemoveChildShapeFromCompoundShapeIndex2(shape.ptr, ii);
- DereferenceAnonCollisionShape(childShape);
- }
- BulletSimAPI.DeleteCollisionShape2(PhysicsScene.World.ptr, shape.ptr);
- }
-
- // Sometimes we have a pointer to a collision shape but don't know what type it is.
- // Figure out type and call the correct dereference routine.
- // Called at taint-time.
- private void DereferenceAnonCollisionShape(Object cShape)
- {
- MeshDesc meshDesc;
- HullDesc hullDesc;
-
- BulletShape shapeInfo = new BulletShape(cShape);
- if (TryGetMeshByPtr(cShape, out meshDesc))
- {
- shapeInfo.type = BSPhysicsShapeType.SHAPE_MESH;
- shapeInfo.shapeKey = meshDesc.shapeKey;
- }
- else
- {
- if (TryGetHullByPtr(cShape, out hullDesc))
- {
- shapeInfo.type = BSPhysicsShapeType.SHAPE_HULL;
- shapeInfo.shapeKey = hullDesc.shapeKey;
- }
- else
- {
- if (BulletSimAPI.IsCompound2(cShape))
- {
- shapeInfo.type = BSPhysicsShapeType.SHAPE_COMPOUND;
- }
- else
- {
- if (BulletSimAPI.IsNativeShape2(cShape))
- {
- shapeInfo.isNativeShape = true;
- shapeInfo.type = BSPhysicsShapeType.SHAPE_BOX; // (technically, type doesn't matter)
- }
- }
- }
- }
-
- if (DDetail) DetailLog("{0},BSShapeCollection.DereferenceAnonCollisionShape,shape={1}", BSScene.DetailLogZero, shapeInfo);
-
- if (shapeInfo.type != BSPhysicsShapeType.SHAPE_UNKNOWN)
- {
- DereferenceShape(shapeInfo, true, null);
- }
- else
- {
- PhysicsScene.Logger.ErrorFormat("{0} Could not decypher shape type. Region={1}, addr={2}",
- LogHeader, PhysicsScene.RegionName, cShape.ToString());
- }
- }
-
- // Create the geometry information in Bullet for later use.
- // The objects needs a hull if it's physical otherwise a mesh is enough.
- // if 'forceRebuild' is true, the geometry is unconditionally rebuilt. For meshes and hulls,
- // shared geometries will be used. If the parameters of the existing shape are the same
- // as this request, the shape is not rebuilt.
- // Info in prim.BSShape is updated to the new shape.
- // Returns 'true' if the geometry was rebuilt.
- // Called at taint-time!
- private bool CreateGeom(bool forceRebuild, BSPhysObject prim, ShapeDestructionCallback shapeCallback)
- {
- bool ret = false;
- bool haveShape = false;
-
- if (!haveShape && prim.PreferredPhysicalShape == BSPhysicsShapeType.SHAPE_CAPSULE)
- {
- // an avatar capsule is close to a native shape (it is not shared)
- GetReferenceToNativeShape(prim, BSPhysicsShapeType.SHAPE_CAPSULE,
- FixedShapeKey.KEY_CAPSULE, shapeCallback);
- if (DDetail) DetailLog("{0},BSShapeCollection.CreateGeom,avatarCapsule,shape={1}", prim.LocalID, prim.PhysShape);
- ret = true;
- haveShape = true;
- }
-
- // Compound shapes are handled special as they are rebuilt from scratch.
- // This isn't too great a hardship since most of the child shapes will have already been created.
- if (!haveShape && prim.PreferredPhysicalShape == BSPhysicsShapeType.SHAPE_COMPOUND)
- {
- ret = GetReferenceToCompoundShape(prim, shapeCallback);
- if (DDetail) DetailLog("{0},BSShapeCollection.CreateGeom,compoundShape,shape={1}", prim.LocalID, prim.PhysShape);
- haveShape = true;
- }
-
- if (!haveShape)
- {
- ret = CreateGeomNonSpecial(forceRebuild, prim, shapeCallback);
- }
-
- return ret;
- }
-
- // Create a mesh/hull shape or a native shape if 'nativeShapePossible' is 'true'.
- public bool CreateGeomNonSpecial(bool forceRebuild, BSPhysObject prim, ShapeDestructionCallback shapeCallback)
- {
- bool ret = false;
- bool haveShape = false;
- bool nativeShapePossible = true;
- PrimitiveBaseShape pbs = prim.BaseShape;
-
- // If the prim attributes are simple, this could be a simple Bullet native shape
- if (!haveShape
- && pbs != null
- && nativeShapePossible
- && ((pbs.SculptEntry && !BSParam.ShouldMeshSculptedPrim)
- || (pbs.ProfileBegin == 0 && pbs.ProfileEnd == 0
- && pbs.ProfileHollow == 0
- && pbs.PathTwist == 0 && pbs.PathTwistBegin == 0
- && pbs.PathBegin == 0 && pbs.PathEnd == 0
- && pbs.PathTaperX == 0 && pbs.PathTaperY == 0
- && pbs.PathScaleX == 100 && pbs.PathScaleY == 100
- && pbs.PathShearX == 0 && pbs.PathShearY == 0) ) )
- {
- // Get the scale of any existing shape so we can see if the new shape is same native type and same size.
- OMV.Vector3 scaleOfExistingShape = OMV.Vector3.Zero;
- if (prim.PhysShape.HasPhysicalShape)
- scaleOfExistingShape = BulletSimAPI.GetLocalScaling2(prim.PhysShape.ptr);
-
- if (DDetail) DetailLog("{0},BSShapeCollection.CreateGeom,maybeNative,force={1},primScale={2},primSize={3},primShape={4}",
- prim.LocalID, forceRebuild, prim.Scale, prim.Size, prim.PhysShape.type);
-
- // It doesn't look like Bullet scales spheres so make sure the scales are all equal
- if ((pbs.ProfileShape == ProfileShape.HalfCircle && pbs.PathCurve == (byte)Extrusion.Curve1)
- && pbs.Scale.X == pbs.Scale.Y && pbs.Scale.Y == pbs.Scale.Z)
- {
- haveShape = true;
- if (forceRebuild
- || prim.Scale != scaleOfExistingShape
- || prim.PhysShape.type != BSPhysicsShapeType.SHAPE_SPHERE
- )
- {
- ret = GetReferenceToNativeShape(prim, BSPhysicsShapeType.SHAPE_SPHERE,
- FixedShapeKey.KEY_SPHERE, shapeCallback);
- if (DDetail) DetailLog("{0},BSShapeCollection.CreateGeom,sphere,force={1},shape={2}",
- prim.LocalID, forceRebuild, prim.PhysShape);
- }
- }
- if (!haveShape && pbs.ProfileShape == ProfileShape.Square && pbs.PathCurve == (byte)Extrusion.Straight)
- {
- haveShape = true;
- if (forceRebuild
- || prim.Scale != scaleOfExistingShape
- || prim.PhysShape.type != BSPhysicsShapeType.SHAPE_BOX
- )
- {
- ret = GetReferenceToNativeShape( prim, BSPhysicsShapeType.SHAPE_BOX,
- FixedShapeKey.KEY_BOX, shapeCallback);
- if (DDetail) DetailLog("{0},BSShapeCollection.CreateGeom,box,force={1},shape={2}",
- prim.LocalID, forceRebuild, prim.PhysShape);
- }
- }
- }
-
- // If a simple shape is not happening, create a mesh and possibly a hull.
- if (!haveShape && pbs != null)
- {
- ret = CreateGeomMeshOrHull(prim, shapeCallback);
- }
-
- return ret;
- }
-
- public bool CreateGeomMeshOrHull(BSPhysObject prim, ShapeDestructionCallback shapeCallback)
- {
-
- bool ret = false;
- // Note that if it's a native shape, the check for physical/non-physical is not
- // made. Native shapes work in either case.
- if (prim.IsPhysical && BSParam.ShouldUseHullsForPhysicalObjects)
- {
- // Update prim.BSShape to reference a hull of this shape.
- ret = GetReferenceToHull(prim,shapeCallback);
- if (DDetail) DetailLog("{0},BSShapeCollection.CreateGeom,hull,shape={1},key={2}",
- prim.LocalID, prim.PhysShape, prim.PhysShape.shapeKey.ToString("X"));
- }
- else
- {
- ret = GetReferenceToMesh(prim, shapeCallback);
- if (DDetail) DetailLog("{0},BSShapeCollection.CreateGeom,mesh,shape={1},key={2}",
- prim.LocalID, prim.PhysShape, prim.PhysShape.shapeKey.ToString("X"));
- }
- return ret;
- }
-
- // Creates a native shape and assignes it to prim.BSShape.
- // "Native" shapes are never shared. they are created here and destroyed in DereferenceShape().
- private bool GetReferenceToNativeShape(BSPhysObject prim,
- BSPhysicsShapeType shapeType, FixedShapeKey shapeKey,
- ShapeDestructionCallback shapeCallback)
- {
- // release any previous shape
- DereferenceShape(prim.PhysShape, true, shapeCallback);
-
- BulletShape newShape = BuildPhysicalNativeShape(prim, shapeType, shapeKey);
-
- // Don't need to do a 'ReferenceShape()' here because native shapes are not shared.
- if (DDetail) DetailLog("{0},BSShapeCollection.AddNativeShapeToPrim,create,newshape={1},scale={2}",
- prim.LocalID, newShape, prim.Scale);
-
- // native shapes are scaled by Bullet
- prim.PhysShape = newShape;
- return true;
- }
-
- private BulletShape BuildPhysicalNativeShape(BSPhysObject prim, BSPhysicsShapeType shapeType,
- FixedShapeKey shapeKey)
- {
- BulletShape newShape;
- // Need to make sure the passed shape information is for the native type.
- ShapeData nativeShapeData = new ShapeData();
- nativeShapeData.Type = shapeType;
- nativeShapeData.ID = prim.LocalID;
- nativeShapeData.Scale = prim.Scale;
- nativeShapeData.Size = prim.Scale; // unneeded, I think.
- nativeShapeData.MeshKey = (ulong)shapeKey;
- nativeShapeData.HullKey = (ulong)shapeKey;
-
- if (shapeType == BSPhysicsShapeType.SHAPE_CAPSULE)
- {
- // The proper scale has been calculated in the prim.
- newShape = new BulletShape(
- BulletSimAPI.BuildCapsuleShape2(PhysicsScene.World.ptr, 1f, 1f, prim.Scale)
- , shapeType);
- if (DDetail) DetailLog("{0},BSShapeCollection.BuiletPhysicalNativeShape,capsule,scale={1}", prim.LocalID, prim.Scale);
- }
- else
- {
- // Native shapes are scaled in Bullet so set the scaling to the size
- newShape = new BulletShape(BulletSimAPI.BuildNativeShape2(PhysicsScene.World.ptr, nativeShapeData), shapeType);
- }
- if (!newShape.HasPhysicalShape)
- {
- PhysicsScene.Logger.ErrorFormat("{0} BuildPhysicalNativeShape failed. ID={1}, shape={2}",
- LogHeader, prim.LocalID, shapeType);
- }
- newShape.shapeKey = (System.UInt64)shapeKey;
- newShape.isNativeShape = true;
-
- return newShape;
- }
-
- // Builds a mesh shape in the physical world and updates prim.BSShape.
- // Dereferences previous shape in BSShape and adds a reference for this new shape.
- // Returns 'true' of a mesh was actually built. Otherwise .
- // Called at taint-time!
- private bool GetReferenceToMesh(BSPhysObject prim, ShapeDestructionCallback shapeCallback)
- {
- BulletShape newShape = new BulletShape();
-
- float lod;
- System.UInt64 newMeshKey = ComputeShapeKey(prim.Size, prim.BaseShape, out lod);
-
- // if this new shape is the same as last time, don't recreate the mesh
- if (newMeshKey == prim.PhysShape.shapeKey && prim.PhysShape.type == BSPhysicsShapeType.SHAPE_MESH)
- return false;
-
- if (DDetail) DetailLog("{0},BSShapeCollection.GetReferenceToMesh,create,oldKey={1},newKey={2}",
- prim.LocalID, prim.PhysShape.shapeKey.ToString("X"), newMeshKey.ToString("X"));
-
- // Since we're recreating new, get rid of the reference to the previous shape
- DereferenceShape(prim.PhysShape, true, shapeCallback);
-
- newShape = CreatePhysicalMesh(prim.PhysObjectName, newMeshKey, prim.BaseShape, prim.Size, lod);
- // Take evasive action if the mesh was not constructed.
- newShape = VerifyMeshCreated(newShape, prim);
-
- ReferenceShape(newShape);
-
- prim.PhysShape = newShape;
-
- return true; // 'true' means a new shape has been added to this prim
- }
-
- private BulletShape CreatePhysicalMesh(string objName, System.UInt64 newMeshKey, PrimitiveBaseShape pbs, OMV.Vector3 size, float lod)
- {
- IMesh meshData = null;
- Object meshPtr = null;
- MeshDesc meshDesc;
- if (Meshes.TryGetValue(newMeshKey, out meshDesc))
- {
- // If the mesh has already been built just use it.
- meshPtr = meshDesc.ptr;
- }
- else
- {
- meshData = PhysicsScene.mesher.CreateMesh(objName, pbs, size, lod, true, false);
-
- if (meshData != null)
- {
- int[] indices = meshData.getIndexListAsInt();
- List vertices = meshData.getVertexList();
-
- float[] verticesAsFloats = new float[vertices.Count * 3];
- int vi = 0;
- foreach (OMV.Vector3 vv in vertices)
- {
- verticesAsFloats[vi++] = vv.X;
- verticesAsFloats[vi++] = vv.Y;
- verticesAsFloats[vi++] = vv.Z;
- }
-
- // m_log.DebugFormat("{0}: BSShapeCollection.CreatePhysicalMesh: calling CreateMesh. lid={1}, key={2}, indices={3}, vertices={4}",
- // LogHeader, prim.LocalID, newMeshKey, indices.Length, vertices.Count);
-
- meshPtr = BulletSimAPI.CreateMeshShape2(PhysicsScene.World.ptr,
- indices.GetLength(0), indices, vertices.Count, verticesAsFloats);
- }
- }
- BulletShape newShape = new BulletShape(meshPtr, BSPhysicsShapeType.SHAPE_MESH);
- newShape.shapeKey = newMeshKey;
-
- return newShape;
- }
-
- // See that hull shape exists in the physical world and update prim.BSShape.
- // We could be creating the hull because scale changed or whatever.
- private bool GetReferenceToHull(BSPhysObject prim, ShapeDestructionCallback shapeCallback)
- {
- BulletShape newShape;
-
- float lod;
- System.UInt64 newHullKey = ComputeShapeKey(prim.Size, prim.BaseShape, out lod);
-
- // if the hull hasn't changed, don't rebuild it
- if (newHullKey == prim.PhysShape.shapeKey && prim.PhysShape.type == BSPhysicsShapeType.SHAPE_HULL)
- return false;
-
- if (DDetail) DetailLog("{0},BSShapeCollection.GetReferenceToHull,create,oldKey={1},newKey={2}",
- prim.LocalID, prim.PhysShape.shapeKey.ToString("X"), newHullKey.ToString("X"));
-
- // Remove usage of the previous shape.
- DereferenceShape(prim.PhysShape, true, shapeCallback);
-
- newShape = CreatePhysicalHull(prim.PhysObjectName, newHullKey, prim.BaseShape, prim.Size, lod);
- newShape = VerifyMeshCreated(newShape, prim);
-
- ReferenceShape(newShape);
-
- prim.PhysShape = newShape;
- return true; // 'true' means a new shape has been added to this prim
- }
-
- List m_hulls;
- private BulletShape CreatePhysicalHull(string objName, System.UInt64 newHullKey, PrimitiveBaseShape pbs, OMV.Vector3 size, float lod)
- {
-
- Object hullPtr = null;
- HullDesc hullDesc;
- if (Hulls.TryGetValue(newHullKey, out hullDesc))
- {
- // If the hull shape already is created, just use it.
- hullPtr = hullDesc.ptr;
- }
- else
- {
- // Build a new hull in the physical world
- // Pass true for physicalness as this creates some sort of bounding box which we don't need
- IMesh meshData = PhysicsScene.mesher.CreateMesh(objName, pbs, size, lod, true, false);
- if (meshData != null)
- {
-
- int[] indices = meshData.getIndexListAsInt();
- List vertices = meshData.getVertexList();
-
- //format conversion from IMesh format to DecompDesc format
- List convIndices = new List();
- List convVertices = new List();
- for (int ii = 0; ii < indices.GetLength(0); ii++)
- {
- convIndices.Add(indices[ii]);
- }
- foreach (OMV.Vector3 vv in vertices)
- {
- convVertices.Add(new float3(vv.X, vv.Y, vv.Z));
- }
-
- // setup and do convex hull conversion
- m_hulls = new List();
- DecompDesc dcomp = new DecompDesc();
- dcomp.mIndices = convIndices;
- dcomp.mVertices = convVertices;
- ConvexBuilder convexBuilder = new ConvexBuilder(HullReturn);
- // create the hull into the _hulls variable
- convexBuilder.process(dcomp);
-
- // Convert the vertices and indices for passing to unmanaged.
- // The hull information is passed as a large floating point array.
- // The format is:
- // convHulls[0] = number of hulls
- // convHulls[1] = number of vertices in first hull
- // convHulls[2] = hull centroid X coordinate
- // convHulls[3] = hull centroid Y coordinate
- // convHulls[4] = hull centroid Z coordinate
- // convHulls[5] = first hull vertex X
- // convHulls[6] = first hull vertex Y
- // convHulls[7] = first hull vertex Z
- // convHulls[8] = second hull vertex X
- // ...
- // convHulls[n] = number of vertices in second hull
- // convHulls[n+1] = second hull centroid X coordinate
- // ...
- //
- // TODO: is is very inefficient. Someday change the convex hull generator to return
- // data structures that do not need to be converted in order to pass to Bullet.
- // And maybe put the values directly into pinned memory rather than marshaling.
- int hullCount = m_hulls.Count;
- int totalVertices = 1; // include one for the count of the hulls
- foreach (ConvexResult cr in m_hulls)
- {
- totalVertices += 4; // add four for the vertex count and centroid
- totalVertices += cr.HullIndices.Count * 3; // we pass just triangles
- }
- float[] convHulls = new float[totalVertices];
-
- convHulls[0] = (float)hullCount;
- int jj = 1;
- foreach (ConvexResult cr in m_hulls)
- {
- // copy vertices for index access
- float3[] verts = new float3[cr.HullVertices.Count];
- int kk = 0;
- foreach (float3 ff in cr.HullVertices)
- {
- verts[kk++] = ff;
- }
-
- // add to the array one hull's worth of data
- convHulls[jj++] = cr.HullIndices.Count;
- convHulls[jj++] = 0f; // centroid x,y,z
- convHulls[jj++] = 0f;
- convHulls[jj++] = 0f;
- foreach (int ind in cr.HullIndices)
- {
- convHulls[jj++] = verts[ind].x;
- convHulls[jj++] = verts[ind].y;
- convHulls[jj++] = verts[ind].z;
- }
- }
- // create the hull data structure in Bullet
- hullPtr = BulletSimAPI.CreateHullShape2(PhysicsScene.World.ptr, hullCount, convHulls);
- }
- }
-
- BulletShape newShape = new BulletShape(hullPtr, BSPhysicsShapeType.SHAPE_HULL);
- newShape.shapeKey = newHullKey;
-
- return newShape;
- }
-
- // Callback from convex hull creater with a newly created hull.
- // Just add it to our collection of hulls for this shape.
- private void HullReturn(ConvexResult result)
- {
- m_hulls.Add(result);
- return;
- }
-
- // Compound shapes are always built from scratch.
- // This shouldn't be to bad since most of the parts will be meshes that had been built previously.
- private bool GetReferenceToCompoundShape(BSPhysObject prim, ShapeDestructionCallback shapeCallback)
- {
- // Remove reference to the old shape
- // Don't need to do this as the shape is freed when the new root shape is created below.
- // DereferenceShape(prim.PhysShape, true, shapeCallback);
-
- BulletShape cShape = new BulletShape(
- BulletSimAPI.CreateCompoundShape2(PhysicsScene.World.ptr, false), BSPhysicsShapeType.SHAPE_COMPOUND);
-
- // Create the shape for the root prim and add it to the compound shape. Cannot be a native shape.
- CreateGeomMeshOrHull(prim, shapeCallback);
- BulletSimAPI.AddChildShapeToCompoundShape2(cShape.ptr, prim.PhysShape.ptr, OMV.Vector3.Zero, OMV.Quaternion.Identity);
- if (DDetail) DetailLog("{0},BSShapeCollection.GetReferenceToCompoundShape,addRootPrim,compShape={1},rootShape={2}",
- prim.LocalID, cShape, prim.PhysShape);
-
- prim.PhysShape = cShape;
-
- return true;
- }
-
- // Create a hash of all the shape parameters to be used as a key
- // for this particular shape.
- private System.UInt64 ComputeShapeKey(OMV.Vector3 size, PrimitiveBaseShape pbs, out float retLod)
- {
- // level of detail based on size and type of the object
- float lod = BSParam.MeshLOD;
- if (pbs.SculptEntry)
- lod = BSParam.SculptLOD;
-
- // Mega prims usually get more detail because one can interact with shape approximations at this size.
- float maxAxis = Math.Max(size.X, Math.Max(size.Y, size.Z));
- if (maxAxis > BSParam.MeshMegaPrimThreshold)
- lod = BSParam.MeshMegaPrimLOD;
-
- retLod = lod;
- return pbs.GetMeshKey(size, lod);
- }
- // For those who don't want the LOD
- private System.UInt64 ComputeShapeKey(OMV.Vector3 size, PrimitiveBaseShape pbs)
- {
- float lod;
- return ComputeShapeKey(size, pbs, out lod);
- }
-
- // The creation of a mesh or hull can fail if an underlying asset is not available.
- // There are two cases: 1) the asset is not in the cache and it needs to be fetched;
- // and 2) the asset cannot be converted (like failed decompression of JPEG2000s).
- // The first case causes the asset to be fetched. The second case requires
- // us to not loop forever.
- // Called after creating a physical mesh or hull. If the physical shape was created,
- // just return.
- private BulletShape VerifyMeshCreated(BulletShape newShape, BSPhysObject prim)
- {
- // If the shape was successfully created, nothing more to do
- if (newShape.HasPhysicalShape)
- return newShape;
-
- // If this mesh has an underlying asset and we have not failed getting it before, fetch the asset
- if (prim.BaseShape.SculptEntry && !prim.LastAssetBuildFailed && prim.BaseShape.SculptTexture != OMV.UUID.Zero)
- {
- prim.LastAssetBuildFailed = true;
- BSPhysObject xprim = prim;
- DetailLog("{0},BSShapeCollection.VerifyMeshCreated,fetchAsset,lID={1},lastFailed={2}",
- LogHeader, prim.LocalID, prim.LastAssetBuildFailed);
- Util.FireAndForget(delegate
- {
- RequestAssetDelegate assetProvider = PhysicsScene.RequestAssetMethod;
- if (assetProvider != null)
- {
- BSPhysObject yprim = xprim; // probably not necessary, but, just in case.
- assetProvider(yprim.BaseShape.SculptTexture, delegate(AssetBase asset)
- {
- if (!yprim.BaseShape.SculptEntry)
- return;
- if (yprim.BaseShape.SculptTexture.ToString() != asset.ID)
- return;
-
- yprim.BaseShape.SculptData = asset.Data;
- // This will cause the prim to see that the filler shape is not the right
- // one and try again to build the object.
- // No race condition with the normal shape setting since the rebuild is at taint time.
- yprim.ForceBodyShapeRebuild(false);
-
- });
- }
- });
- }
- else
- {
- if (prim.LastAssetBuildFailed)
- {
- PhysicsScene.Logger.ErrorFormat("{0} Mesh failed to fetch asset. lID={1}, texture={2}",
- LogHeader, prim.LocalID, prim.BaseShape.SculptTexture);
- }
- }
-
- // While we figure out the real problem, stick a simple native shape on the object.
- BulletShape fillinShape =
- BuildPhysicalNativeShape(prim, BSPhysicsShapeType.SHAPE_BOX, FixedShapeKey.KEY_BOX);
-
- return fillinShape;
- }
-
- // Create a body object in Bullet.
- // Updates prim.BSBody with the information about the new body if one is created.
- // Returns 'true' if an object was actually created.
- // Called at taint-time.
- private bool CreateBody(bool forceRebuild, BSPhysObject prim, BulletWorld sim, BulletShape shape,
- BodyDestructionCallback bodyCallback)
- {
- bool ret = false;
-
- // the mesh, hull or native shape must have already been created in Bullet
- bool mustRebuild = !prim.PhysBody.HasPhysicalBody;
-
- // If there is an existing body, verify it's of an acceptable type.
- // If not a solid object, body is a GhostObject. Otherwise a RigidBody.
- if (!mustRebuild)
- {
- CollisionObjectTypes bodyType = (CollisionObjectTypes)BulletSimAPI.GetBodyType2(prim.PhysBody.ptr);
- if (prim.IsSolid && bodyType != CollisionObjectTypes.CO_RIGID_BODY
- || !prim.IsSolid && bodyType != CollisionObjectTypes.CO_GHOST_OBJECT)
- {
- // If the collisionObject is not the correct type for solidness, rebuild what's there
- mustRebuild = true;
- }
- }
-
- if (mustRebuild || forceRebuild)
- {
- // Free any old body
- DereferenceBody(prim.PhysBody, true, bodyCallback);
-
- BulletBody aBody;
- Object bodyPtr = null;
- if (prim.IsSolid)
- {
- bodyPtr = BulletSimAPI.CreateBodyFromShape2(sim.ptr, shape.ptr,
- prim.LocalID, prim.RawPosition, prim.RawOrientation);
- if (DDetail) DetailLog("{0},BSShapeCollection.CreateBody,mesh,ptr={1}", prim.LocalID, bodyPtr.ToString());
- }
- else
- {
- bodyPtr = BulletSimAPI.CreateGhostFromShape2(sim.ptr, shape.ptr,
- prim.LocalID, prim.RawPosition, prim.RawOrientation);
- if (DDetail) DetailLog("{0},BSShapeCollection.CreateBody,ghost,ptr={1}", prim.LocalID, bodyPtr.ToString());
- }
- aBody = new BulletBody(prim.LocalID, bodyPtr);
-
- ReferenceBody(aBody, true);
-
- prim.PhysBody = aBody;
-
- ret = true;
- }
-
- return ret;
- }
-
- private bool TryGetMeshByPtr(Object addr, out MeshDesc outDesc)
- {
- bool ret = false;
- MeshDesc foundDesc = new MeshDesc();
- foreach (MeshDesc md in Meshes.Values)
- {
- if (md.ptr == addr)
- {
- foundDesc = md;
- ret = true;
- break;
- }
-
- }
- outDesc = foundDesc;
- return ret;
- }
-
- private bool TryGetHullByPtr(Object addr, out HullDesc outDesc)
- {
- bool ret = false;
- HullDesc foundDesc = new HullDesc();
- foreach (HullDesc hd in Hulls.Values)
- {
- if (hd.ptr == addr)
- {
- foundDesc = hd;
- ret = true;
- break;
- }
-
- }
- outDesc = foundDesc;
- return ret;
- }
-
- private void DetailLog(string msg, params Object[] args)
- {
- if (PhysicsScene.PhysicsLogging.Enabled)
- PhysicsScene.DetailLog(msg, args);
- }
-}
-}
diff --git a/OpenSim/Region/Physics/BulletSNPlugin/BSShapes.cs b/OpenSim/Region/Physics/BulletSNPlugin/BSShapes.cs
deleted file mode 100644
index 8ff027535c..0000000000
--- a/OpenSim/Region/Physics/BulletSNPlugin/BSShapes.cs
+++ /dev/null
@@ -1,208 +0,0 @@
-/*
- * Copyright (c) Contributors, http://opensimulator.org/
- * See CONTRIBUTORS.TXT for a full list of copyright holders.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyrightD
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * * Neither the name of the OpenSimulator Project nor the
- * names of its contributors may be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-
-namespace OpenSim.Region.Physics.BulletSNPlugin
-{
-public abstract class BSShape
-{
- public Object ptr { get; set; }
- public BSPhysicsShapeType type { get; set; }
- public System.UInt64 key { get; set; }
- public int referenceCount { get; set; }
- public DateTime lastReferenced { get; set; }
-
- public BSShape()
- {
- ptr = null;
- type = BSPhysicsShapeType.SHAPE_UNKNOWN;
- key = 0;
- referenceCount = 0;
- lastReferenced = DateTime.Now;
- }
-
- // Get a reference to a physical shape. Create if it doesn't exist
- public static BSShape GetShapeReference(BSScene physicsScene, bool forceRebuild, BSPhysObject prim)
- {
- BSShape ret = null;
-
- if (prim.PreferredPhysicalShape == BSPhysicsShapeType.SHAPE_CAPSULE)
- {
- // an avatar capsule is close to a native shape (it is not shared)
- ret = BSShapeNative.GetReference(physicsScene, prim, BSPhysicsShapeType.SHAPE_CAPSULE,
- FixedShapeKey.KEY_CAPSULE);
- physicsScene.DetailLog("{0},BSShape.GetShapeReference,avatarCapsule,shape={1}", prim.LocalID, ret);
- }
-
- // Compound shapes are handled special as they are rebuilt from scratch.
- // This isn't too great a hardship since most of the child shapes will already been created.
- if (ret == null && prim.PreferredPhysicalShape == BSPhysicsShapeType.SHAPE_COMPOUND)
- {
- // Getting a reference to a compound shape gets you the compound shape with the root prim shape added
- ret = BSShapeCompound.GetReference(prim);
- physicsScene.DetailLog("{0},BSShapeCollection.CreateGeom,compoundShape,shape={1}", prim.LocalID, ret);
- }
-
- if (ret == null)
- ret = GetShapeReferenceNonSpecial(physicsScene, forceRebuild, prim);
-
- return ret;
- }
- public static BSShape GetShapeReferenceNonSpecial(BSScene physicsScene, bool forceRebuild, BSPhysObject prim)
- {
- return null;
- }
- public static BSShape GetShapeReferenceNonNative(BSScene physicsScene, bool forceRebuild, BSPhysObject prim)
- {
- return null;
- }
-
- // Release the use of a physical shape.
- public abstract void Dereference(BSScene physicsScene);
-
- // All shapes have a static call to get a reference to the physical shape
- // protected abstract static BSShape GetReference();
-
- public override string ToString()
- {
- StringBuilder buff = new StringBuilder();
- buff.Append("");
- return buff.ToString();
- }
-}
-
-public class BSShapeNull : BSShape
-{
- public BSShapeNull() : base()
- {
- }
- public static BSShape GetReference() { return new BSShapeNull(); }
- public override void Dereference(BSScene physicsScene) { /* The magic of garbage collection will make this go away */ }
-}
-
-public class BSShapeNative : BSShape
-{
- private static string LogHeader = "[BULLETSIM SHAPE NATIVE]";
- public BSShapeNative() : base()
- {
- }
- public static BSShape GetReference(BSScene physicsScene, BSPhysObject prim,
- BSPhysicsShapeType shapeType, FixedShapeKey shapeKey)
- {
- // Native shapes are not shared and are always built anew.
- return new BSShapeNative(physicsScene, prim, shapeType, shapeKey);
- }
-
- private BSShapeNative(BSScene physicsScene, BSPhysObject prim,
- BSPhysicsShapeType shapeType, FixedShapeKey shapeKey)
- {
- ShapeData nativeShapeData = new ShapeData();
- nativeShapeData.Type = shapeType;
- nativeShapeData.ID = prim.LocalID;
- nativeShapeData.Scale = prim.Scale;
- nativeShapeData.Size = prim.Scale;
- nativeShapeData.MeshKey = (ulong)shapeKey;
- nativeShapeData.HullKey = (ulong)shapeKey;
-
-
- if (shapeType == BSPhysicsShapeType.SHAPE_CAPSULE)
- {
- ptr = BulletSimAPI.BuildCapsuleShape2(physicsScene.World.ptr, 1f, 1f, prim.Scale);
- physicsScene.DetailLog("{0},BSShapeCollection.BuiletPhysicalNativeShape,capsule,scale={1}", prim.LocalID, prim.Scale);
- }
- else
- {
- ptr = BulletSimAPI.BuildNativeShape2(physicsScene.World.ptr, nativeShapeData);
- }
- if (ptr == null)
- {
- physicsScene.Logger.ErrorFormat("{0} BuildPhysicalNativeShape failed. ID={1}, shape={2}",
- LogHeader, prim.LocalID, shapeType);
- }
- type = shapeType;
- key = (UInt64)shapeKey;
- }
- // Make this reference to the physical shape go away since native shapes are not shared.
- public override void Dereference(BSScene physicsScene)
- {
- // Native shapes are not tracked and are released immediately
- physicsScene.DetailLog("{0},BSShapeCollection.DereferenceShape,deleteNativeShape,shape={1}", BSScene.DetailLogZero, this);
- BulletSimAPI.DeleteCollisionShape2(physicsScene.World.ptr, ptr);
- ptr = null;
- // Garbage collection will free up this instance.
- }
-}
-
-public class BSShapeMesh : BSShape
-{
- private static string LogHeader = "[BULLETSIM SHAPE MESH]";
- private static Dictionary Meshes = new Dictionary();
-
- public BSShapeMesh() : base()
- {
- }
- public static BSShape GetReference() { return new BSShapeNull(); }
- public override void Dereference(BSScene physicsScene) { }
-}
-
-public class BSShapeHull : BSShape
-{
- private static string LogHeader = "[BULLETSIM SHAPE HULL]";
- private static Dictionary Hulls = new Dictionary();
-
- public BSShapeHull() : base()
- {
- }
- public static BSShape GetReference() { return new BSShapeNull(); }
- public override void Dereference(BSScene physicsScene) { }
-}
-
-public class BSShapeCompound : BSShape
-{
- private static string LogHeader = "[BULLETSIM SHAPE COMPOUND]";
- public BSShapeCompound() : base()
- {
- }
- public static BSShape GetReference(BSPhysObject prim)
- {
- return new BSShapeNull();
- }
- public override void Dereference(BSScene physicsScene) { }
-}
-}
diff --git a/OpenSim/Region/Physics/BulletSNPlugin/BSTerrainHeightmap.cs b/OpenSim/Region/Physics/BulletSNPlugin/BSTerrainHeightmap.cs
deleted file mode 100644
index ba17059da0..0000000000
--- a/OpenSim/Region/Physics/BulletSNPlugin/BSTerrainHeightmap.cs
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * Copyright (c) Contributors, http://opensimulator.org/
- * See CONTRIBUTORS.TXT for a full list of copyright holders.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyrightD
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * * Neither the name of the OpenSimulator Project nor the
- * names of its contributors may be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-using System;
-using System.Collections.Generic;
-using System.Text;
-
-using OpenSim.Framework;
-using OpenSim.Region.Framework;
-using OpenSim.Region.CoreModules;
-using OpenSim.Region.Physics.Manager;
-
-using Nini.Config;
-using log4net;
-
-using OpenMetaverse;
-
-namespace OpenSim.Region.Physics.BulletSNPlugin
-{
-public sealed class BSTerrainHeightmap : BSTerrainPhys
-{
- static string LogHeader = "[BULLETSIM TERRAIN HEIGHTMAP]";
-
- BulletHeightMapInfo m_mapInfo = null;
-
- // Constructor to build a default, flat heightmap terrain.
- public BSTerrainHeightmap(BSScene physicsScene, Vector3 regionBase, uint id, Vector3 regionSize)
- : base(physicsScene, regionBase, id)
- {
- Vector3 minTerrainCoords = new Vector3(0f, 0f, BSTerrainManager.HEIGHT_INITIALIZATION - BSTerrainManager.HEIGHT_EQUAL_FUDGE);
- Vector3 maxTerrainCoords = new Vector3(regionSize.X, regionSize.Y, BSTerrainManager.HEIGHT_INITIALIZATION);
- int totalHeights = (int)maxTerrainCoords.X * (int)maxTerrainCoords.Y;
- float[] initialMap = new float[totalHeights];
- for (int ii = 0; ii < totalHeights; ii++)
- {
- initialMap[ii] = BSTerrainManager.HEIGHT_INITIALIZATION;
- }
- m_mapInfo = new BulletHeightMapInfo(id, initialMap, null);
- m_mapInfo.minCoords = minTerrainCoords;
- m_mapInfo.maxCoords = maxTerrainCoords;
- m_mapInfo.terrainRegionBase = TerrainBase;
- // Don't have to free any previous since we just got here.
- BuildHeightmapTerrain();
- }
-
- // This minCoords and maxCoords passed in give the size of the terrain (min and max Z
- // are the high and low points of the heightmap).
- public BSTerrainHeightmap(BSScene physicsScene, Vector3 regionBase, uint id, float[] initialMap,
- Vector3 minCoords, Vector3 maxCoords)
- : base(physicsScene, regionBase, id)
- {
- m_mapInfo = new BulletHeightMapInfo(id, initialMap, null);
- m_mapInfo.minCoords = minCoords;
- m_mapInfo.maxCoords = maxCoords;
- m_mapInfo.minZ = minCoords.Z;
- m_mapInfo.maxZ = maxCoords.Z;
- m_mapInfo.terrainRegionBase = TerrainBase;
-
- // Don't have to free any previous since we just got here.
- BuildHeightmapTerrain();
- }
-
- public override void Dispose()
- {
- ReleaseHeightMapTerrain();
- }
-
- // Using the information in m_mapInfo, create the physical representation of the heightmap.
- private void BuildHeightmapTerrain()
- {
- m_mapInfo.Ptr = BulletSimAPI.CreateHeightMapInfo2(PhysicsScene.World.ptr, m_mapInfo.ID,
- m_mapInfo.minCoords, m_mapInfo.maxCoords,
- m_mapInfo.heightMap, BSParam.TerrainCollisionMargin);
-
- // Create the terrain shape from the mapInfo
- m_mapInfo.terrainShape = new BulletShape(BulletSimAPI.CreateTerrainShape2(m_mapInfo.Ptr),
- BSPhysicsShapeType.SHAPE_TERRAIN);
-
- // The terrain object initial position is at the center of the object
- Vector3 centerPos;
- centerPos.X = m_mapInfo.minCoords.X + (m_mapInfo.sizeX / 2f);
- centerPos.Y = m_mapInfo.minCoords.Y + (m_mapInfo.sizeY / 2f);
- centerPos.Z = m_mapInfo.minZ + ((m_mapInfo.maxZ - m_mapInfo.minZ) / 2f - 0.5f);
-
- m_mapInfo.terrainBody = new BulletBody(m_mapInfo.ID,
- BulletSimAPI.CreateBodyWithDefaultMotionState2(m_mapInfo.terrainShape.ptr,
- m_mapInfo.ID, centerPos, Quaternion.Identity));
-
- // Set current terrain attributes
- BulletSimAPI.SetFriction2(m_mapInfo.terrainBody.ptr, BSParam.TerrainFriction);
- BulletSimAPI.SetHitFraction2(m_mapInfo.terrainBody.ptr, BSParam.TerrainHitFraction);
- BulletSimAPI.SetRestitution2(m_mapInfo.terrainBody.ptr, BSParam.TerrainRestitution);
- BulletSimAPI.SetCollisionFlags2(m_mapInfo.terrainBody.ptr, CollisionFlags.CF_STATIC_OBJECT);
-
- // Return the new terrain to the world of physical objects
- BulletSimAPI.AddObjectToWorld2(PhysicsScene.World.ptr, m_mapInfo.terrainBody.ptr, centerPos, Quaternion.Identity);
-
- // redo its bounding box now that it is in the world
- BulletSimAPI.UpdateSingleAabb2(PhysicsScene.World.ptr, m_mapInfo.terrainBody.ptr);
-
- m_mapInfo.terrainBody.collisionType = CollisionType.Terrain;
- m_mapInfo.terrainBody.ApplyCollisionMask();
-
- // Make it so the terrain will not move or be considered for movement.
- BulletSimAPI.ForceActivationState2(m_mapInfo.terrainBody.ptr, ActivationState.DISABLE_SIMULATION);
-
- return;
- }
-
- // If there is information in m_mapInfo pointing to physical structures, release same.
- private void ReleaseHeightMapTerrain()
- {
- if (m_mapInfo != null)
- {
- if (m_mapInfo.terrainBody.HasPhysicalBody)
- {
- BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.ptr, m_mapInfo.terrainBody.ptr);
- // Frees both the body and the shape.
- BulletSimAPI.DestroyObject2(PhysicsScene.World.ptr, m_mapInfo.terrainBody.ptr);
- BulletSimAPI.ReleaseHeightMapInfo2(m_mapInfo.Ptr);
- }
- }
- m_mapInfo = null;
- }
-
- // The passed position is relative to the base of the region.
- public override float GetTerrainHeightAtXYZ(Vector3 pos)
- {
- float ret = BSTerrainManager.HEIGHT_GETHEIGHT_RET;
-
- int mapIndex = (int)pos.Y * (int)m_mapInfo.sizeY + (int)pos.X;
- try
- {
- ret = m_mapInfo.heightMap[mapIndex];
- }
- catch
- {
- // Sometimes they give us wonky values of X and Y. Give a warning and return something.
- PhysicsScene.Logger.WarnFormat("{0} Bad request for terrain height. terrainBase={1}, pos={2}",
- LogHeader, m_mapInfo.terrainRegionBase, pos);
- ret = BSTerrainManager.HEIGHT_GETHEIGHT_RET;
- }
- return ret;
- }
-
- // The passed position is relative to the base of the region.
- public override float GetWaterLevelAtXYZ(Vector3 pos)
- {
- return PhysicsScene.SimpleWaterLevel;
- }
-}
-}
diff --git a/OpenSim/Region/Physics/BulletSNPlugin/BSTerrainManager.cs b/OpenSim/Region/Physics/BulletSNPlugin/BSTerrainManager.cs
deleted file mode 100644
index 66d62f0afb..0000000000
--- a/OpenSim/Region/Physics/BulletSNPlugin/BSTerrainManager.cs
+++ /dev/null
@@ -1,461 +0,0 @@
-/*
- * Copyright (c) Contributors, http://opensimulator.org/
- * See CONTRIBUTORS.TXT for a full list of copyright holders.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyrightD
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * * Neither the name of the OpenSimulator Project nor the
- * names of its contributors may be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-using System;
-using System.Collections.Generic;
-using System.Text;
-
-using OpenSim.Framework;
-using OpenSim.Region.Framework;
-using OpenSim.Region.CoreModules;
-using OpenSim.Region.Physics.Manager;
-
-using Nini.Config;
-using log4net;
-
-using OpenMetaverse;
-
-namespace OpenSim.Region.Physics.BulletSNPlugin
-{
-
-// The physical implementation of the terrain is wrapped in this class.
-public abstract class BSTerrainPhys : IDisposable
-{
- public enum TerrainImplementation
- {
- Heightmap = 0,
- Mesh = 1
- }
-
- public BSScene PhysicsScene { get; private set; }
- // Base of the region in world coordinates. Coordinates inside the region are relative to this.
- public Vector3 TerrainBase { get; private set; }
- public uint ID { get; private set; }
-
- public BSTerrainPhys(BSScene physicsScene, Vector3 regionBase, uint id)
- {
- PhysicsScene = physicsScene;
- TerrainBase = regionBase;
- ID = id;
- }
- public abstract void Dispose();
- public abstract float GetTerrainHeightAtXYZ(Vector3 pos);
- public abstract float GetWaterLevelAtXYZ(Vector3 pos);
-}
-
-// ==========================================================================================
-public sealed class BSTerrainManager : IDisposable
-{
- static string LogHeader = "[BULLETSIM TERRAIN MANAGER]";
-
- // These height values are fractional so the odd values will be
- // noticable when debugging.
- public const float HEIGHT_INITIALIZATION = 24.987f;
- public const float HEIGHT_INITIAL_LASTHEIGHT = 24.876f;
- public const float HEIGHT_GETHEIGHT_RET = 24.765f;
- public const float WATER_HEIGHT_GETHEIGHT_RET = 19.998f;
-
- // If the min and max height are equal, we reduce the min by this
- // amount to make sure that a bounding box is built for the terrain.
- public const float HEIGHT_EQUAL_FUDGE = 0.2f;
-
- // Until the whole simulator is changed to pass us the region size, we rely on constants.
- public Vector3 DefaultRegionSize = new Vector3(Constants.RegionSize, Constants.RegionSize, Constants.RegionHeight);
-
- // The scene that I am part of
- private BSScene PhysicsScene { get; set; }
-
- // The ground plane created to keep thing from falling to infinity.
- private BulletBody m_groundPlane;
-
- // If doing mega-regions, if we're region zero we will be managing multiple
- // region terrains since region zero does the physics for the whole mega-region.
- private Dictionary m_terrains;
-
- // Flags used to know when to recalculate the height.
- private bool m_terrainModified = false;
-
- // If we are doing mega-regions, terrains are added from TERRAIN_ID to m_terrainCount.
- // This is incremented before assigning to new region so it is the last ID allocated.
- private uint m_terrainCount = BSScene.CHILDTERRAIN_ID - 1;
- public uint HighestTerrainID { get {return m_terrainCount; } }
-
- // If doing mega-regions, this holds our offset from region zero of
- // the mega-regions. "parentScene" points to the PhysicsScene of region zero.
- private Vector3 m_worldOffset;
- // If the parent region (region 0), this is the extent of the combined regions
- // relative to the origin of region zero
- private Vector3 m_worldMax;
- private PhysicsScene MegaRegionParentPhysicsScene { get; set; }
-
- public BSTerrainManager(BSScene physicsScene)
- {
- PhysicsScene = physicsScene;
- m_terrains = new Dictionary();
-
- // Assume one region of default size
- m_worldOffset = Vector3.Zero;
- m_worldMax = new Vector3(DefaultRegionSize);
- MegaRegionParentPhysicsScene = null;
- }
-
- public void Dispose()
- {
- ReleaseGroundPlaneAndTerrain();
- }
-
- // Create the initial instance of terrain and the underlying ground plane.
- // This is called from the initialization routine so we presume it is
- // safe to call Bullet in real time. We hope no one is moving prims around yet.
- public void CreateInitialGroundPlaneAndTerrain()
- {
- // The ground plane is here to catch things that are trying to drop to negative infinity
- BulletShape groundPlaneShape = new BulletShape(
- BulletSimAPI.CreateGroundPlaneShape2(BSScene.GROUNDPLANE_ID, 1f,
- BSParam.TerrainCollisionMargin),
- BSPhysicsShapeType.SHAPE_GROUNDPLANE);
- m_groundPlane = new BulletBody(BSScene.GROUNDPLANE_ID,
- BulletSimAPI.CreateBodyWithDefaultMotionState2(groundPlaneShape.ptr, BSScene.GROUNDPLANE_ID,
- Vector3.Zero, Quaternion.Identity));
- BulletSimAPI.AddObjectToWorld2(PhysicsScene.World.ptr, m_groundPlane.ptr, Vector3.Zero, Quaternion.Identity);
- BulletSimAPI.UpdateSingleAabb2(PhysicsScene.World.ptr, m_groundPlane.ptr);
- // Ground plane does not move
- BulletSimAPI.ForceActivationState2(m_groundPlane.ptr, ActivationState.DISABLE_SIMULATION);
- // Everything collides with the ground plane.
- m_groundPlane.collisionType = CollisionType.Groundplane;
- m_groundPlane.ApplyCollisionMask();
-
- // Build an initial terrain and put it in the world. This quickly gets replaced by the real region terrain.
- BSTerrainPhys initialTerrain = new BSTerrainHeightmap(PhysicsScene, Vector3.Zero, BSScene.TERRAIN_ID, DefaultRegionSize);
- m_terrains.Add(Vector3.Zero, initialTerrain);
- }
-
- // Release all the terrain structures we might have allocated
- public void ReleaseGroundPlaneAndTerrain()
- {
- if (m_groundPlane.HasPhysicalBody)
- {
- if (BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.ptr, m_groundPlane.ptr))
- {
- BulletSimAPI.DestroyObject2(PhysicsScene.World.ptr, m_groundPlane.ptr);
- }
- m_groundPlane.Clear();
- }
-
- ReleaseTerrain();
- }
-
- // Release all the terrain we have allocated
- public void ReleaseTerrain()
- {
- lock (m_terrains)
- {
- foreach (KeyValuePair kvp in m_terrains)
- {
- kvp.Value.Dispose();
- }
- m_terrains.Clear();
- }
- }
-
- // The simulator wants to set a new heightmap for the terrain.
- public void SetTerrain(float[] heightMap) {
- float[] localHeightMap = heightMap;
- // If there are multiple requests for changes to the same terrain between ticks,
- // only do that last one.
- PhysicsScene.PostTaintObject("TerrainManager.SetTerrain-"+ m_worldOffset.ToString(), 0, delegate()
- {
- if (m_worldOffset != Vector3.Zero && MegaRegionParentPhysicsScene != null)
- {
- // If a child of a mega-region, we shouldn't have any terrain allocated for us
- ReleaseGroundPlaneAndTerrain();
- // If doing the mega-prim stuff and we are the child of the zero region,
- // the terrain is added to our parent
- if (MegaRegionParentPhysicsScene is BSScene)
- {
- DetailLog("{0},SetTerrain.ToParent,offset={1},worldMax={2}",
- BSScene.DetailLogZero, m_worldOffset, m_worldMax);
- ((BSScene)MegaRegionParentPhysicsScene).TerrainManager.UpdateTerrain(
- BSScene.CHILDTERRAIN_ID, localHeightMap,
- m_worldOffset, m_worldOffset + DefaultRegionSize, true);
- }
- }
- else
- {
- // If not doing the mega-prim thing, just change the terrain
- DetailLog("{0},SetTerrain.Existing", BSScene.DetailLogZero);
-
- UpdateTerrain(BSScene.TERRAIN_ID, localHeightMap,
- m_worldOffset, m_worldOffset + DefaultRegionSize, true);
- }
- });
- }
-
- // If called with no mapInfo for the terrain, this will create a new mapInfo and terrain
- // based on the passed information. The 'id' should be either the terrain id or
- // BSScene.CHILDTERRAIN_ID. If the latter, a new child terrain ID will be allocated and used.
- // The latter feature is for creating child terrains for mega-regions.
- // If called with a mapInfo in m_heightMaps and there is an existing terrain body, a new
- // terrain shape is created and added to the body.
- // This call is most often used to update the heightMap and parameters of the terrain.
- // (The above does suggest that some simplification/refactoring is in order.)
- // Called during taint-time.
- private void UpdateTerrain(uint id, float[] heightMap,
- Vector3 minCoords, Vector3 maxCoords, bool inTaintTime)
- {
- DetailLog("{0},BSTerrainManager.UpdateTerrain,call,minC={1},maxC={2},inTaintTime={3}",
- BSScene.DetailLogZero, minCoords, maxCoords, inTaintTime);
-
- // Find high and low points of passed heightmap.
- // The min and max passed in is usually the area objects can be in (maximum
- // object height, for instance). The terrain wants the bounding box for the
- // terrain so replace passed min and max Z with the actual terrain min/max Z.
- float minZ = float.MaxValue;
- float maxZ = float.MinValue;
- foreach (float height in heightMap)
- {
- if (height < minZ) minZ = height;
- if (height > maxZ) maxZ = height;
- }
- if (minZ == maxZ)
- {
- // If min and max are the same, reduce min a little bit so a good bounding box is created.
- minZ -= BSTerrainManager.HEIGHT_EQUAL_FUDGE;
- }
- minCoords.Z = minZ;
- maxCoords.Z = maxZ;
-
- Vector3 terrainRegionBase = new Vector3(minCoords.X, minCoords.Y, 0f);
-
- lock (m_terrains)
- {
- BSTerrainPhys terrainPhys;
- if (m_terrains.TryGetValue(terrainRegionBase, out terrainPhys))
- {
- // There is already a terrain in this spot. Free the old and build the new.
- DetailLog("{0},UpdateTerrain:UpdateExisting,call,id={1},base={2},minC={3},maxC={4}",
- BSScene.DetailLogZero, id, terrainRegionBase, minCoords, minCoords);
-
- // Remove old terrain from the collection
- m_terrains.Remove(terrainRegionBase);
- // Release any physical memory it may be using.
- terrainPhys.Dispose();
-
- if (MegaRegionParentPhysicsScene == null)
- {
- BSTerrainPhys newTerrainPhys = BuildPhysicalTerrain(terrainRegionBase, id, heightMap, minCoords, maxCoords);
- m_terrains.Add(terrainRegionBase, newTerrainPhys);
-
- m_terrainModified = true;
- }
- else
- {
- // It's possible that Combine() was called after this code was queued.
- // If we are a child of combined regions, we don't create any terrain for us.
- DetailLog("{0},BSTerrainManager.UpdateTerrain:AmACombineChild,taint", BSScene.DetailLogZero);
-
- // Get rid of any terrain that may have been allocated for us.
- ReleaseGroundPlaneAndTerrain();
-
- // I hate doing this, but just bail
- return;
- }
- }
- else
- {
- // We don't know about this terrain so either we are creating a new terrain or
- // our mega-prim child is giving us a new terrain to add to the phys world
-
- // if this is a child terrain, calculate a unique terrain id
- uint newTerrainID = id;
- if (newTerrainID >= BSScene.CHILDTERRAIN_ID)
- newTerrainID = ++m_terrainCount;
-
- DetailLog("{0},UpdateTerrain:NewTerrain,taint,newID={1},minCoord={2},maxCoord={3}",
- BSScene.DetailLogZero, newTerrainID, minCoords, minCoords);
- BSTerrainPhys newTerrainPhys = BuildPhysicalTerrain(terrainRegionBase, id, heightMap, minCoords, maxCoords);
- m_terrains.Add(terrainRegionBase, newTerrainPhys);
-
- m_terrainModified = true;
- }
- }
- }
-
- // TODO: redo terrain implementation selection to allow other base types than heightMap.
- private BSTerrainPhys BuildPhysicalTerrain(Vector3 terrainRegionBase, uint id, float[] heightMap, Vector3 minCoords, Vector3 maxCoords)
- {
- PhysicsScene.Logger.DebugFormat("{0} Terrain for {1}/{2} created with {3}",
- LogHeader, PhysicsScene.RegionName, terrainRegionBase,
- (BSTerrainPhys.TerrainImplementation)BSParam.TerrainImplementation);
- BSTerrainPhys newTerrainPhys = null;
- switch ((int)BSParam.TerrainImplementation)
- {
- case (int)BSTerrainPhys.TerrainImplementation.Heightmap:
- newTerrainPhys = new BSTerrainHeightmap(PhysicsScene, terrainRegionBase, id,
- heightMap, minCoords, maxCoords);
- break;
- case (int)BSTerrainPhys.TerrainImplementation.Mesh:
- newTerrainPhys = new BSTerrainMesh(PhysicsScene, terrainRegionBase, id,
- heightMap, minCoords, maxCoords);
- break;
- default:
- PhysicsScene.Logger.ErrorFormat("{0} Bad terrain implementation specified. Type={1}/{2},Region={3}/{4}",
- LogHeader,
- (int)BSParam.TerrainImplementation,
- BSParam.TerrainImplementation,
- PhysicsScene.RegionName, terrainRegionBase);
- break;
- }
- return newTerrainPhys;
- }
-
- // Return 'true' of this position is somewhere in known physical terrain space
- public bool IsWithinKnownTerrain(Vector3 pos)
- {
- Vector3 terrainBaseXYZ;
- BSTerrainPhys physTerrain;
- return GetTerrainPhysicalAtXYZ(pos, out physTerrain, out terrainBaseXYZ);
- }
-
- // Given an X and Y, find the height of the terrain.
- // Since we could be handling multiple terrains for a mega-region,
- // the base of the region is calcuated assuming all regions are
- // the same size and that is the default.
- // Once the heightMapInfo is found, we have all the information to
- // compute the offset into the array.
- private float lastHeightTX = 999999f;
- private float lastHeightTY = 999999f;
- private float lastHeight = HEIGHT_INITIAL_LASTHEIGHT;
- public float GetTerrainHeightAtXYZ(Vector3 pos)
- {
- float tX = pos.X;
- float tY = pos.Y;
- // You'd be surprized at the number of times this routine is called
- // with the same parameters as last time.
- if (!m_terrainModified && (lastHeightTX == tX) && (lastHeightTY == tY))
- return lastHeight;
- m_terrainModified = false;
-
- lastHeightTX = tX;
- lastHeightTY = tY;
- float ret = HEIGHT_GETHEIGHT_RET;
-
- Vector3 terrainBaseXYZ;
- BSTerrainPhys physTerrain;
- if (GetTerrainPhysicalAtXYZ(pos, out physTerrain, out terrainBaseXYZ))
- {
- ret = physTerrain.GetTerrainHeightAtXYZ(pos - terrainBaseXYZ);
- }
- else
- {
- PhysicsScene.Logger.ErrorFormat("{0} GetTerrainHeightAtXY: terrain not found: region={1}, x={2}, y={3}",
- LogHeader, PhysicsScene.RegionName, tX, tY);
- DetailLog("{0},BSTerrainManager.GetTerrainHeightAtXYZ,terrainNotFound,pos={1},base={2}",
- BSScene.DetailLogZero, pos, terrainBaseXYZ);
- }
-
- lastHeight = ret;
- return ret;
- }
-
- public float GetWaterLevelAtXYZ(Vector3 pos)
- {
- float ret = WATER_HEIGHT_GETHEIGHT_RET;
-
- Vector3 terrainBaseXYZ;
- BSTerrainPhys physTerrain;
- if (GetTerrainPhysicalAtXYZ(pos, out physTerrain, out terrainBaseXYZ))
- {
- ret = physTerrain.GetWaterLevelAtXYZ(pos);
- }
- else
- {
- PhysicsScene.Logger.ErrorFormat("{0} GetWaterHeightAtXY: terrain not found: pos={1}, terrainBase={2}, height={3}",
- LogHeader, PhysicsScene.RegionName, pos, terrainBaseXYZ, ret);
- }
- return ret;
- }
-
- // Given an address, return 'true' of there is a description of that terrain and output
- // the descriptor class and the 'base' fo the addresses therein.
- private bool GetTerrainPhysicalAtXYZ(Vector3 pos, out BSTerrainPhys outPhysTerrain, out Vector3 outTerrainBase)
- {
- int offsetX = ((int)(pos.X / (int)DefaultRegionSize.X)) * (int)DefaultRegionSize.X;
- int offsetY = ((int)(pos.Y / (int)DefaultRegionSize.Y)) * (int)DefaultRegionSize.Y;
- Vector3 terrainBaseXYZ = new Vector3(offsetX, offsetY, 0f);
-
- BSTerrainPhys physTerrain = null;
- lock (m_terrains)
- {
- m_terrains.TryGetValue(terrainBaseXYZ, out physTerrain);
- }
- outTerrainBase = terrainBaseXYZ;
- outPhysTerrain = physTerrain;
- return (physTerrain != null);
- }
-
- // Although no one seems to check this, I do support combining.
- public bool SupportsCombining()
- {
- return true;
- }
-
- // This routine is called two ways:
- // One with 'offset' and 'pScene' zero and null but 'extents' giving the maximum
- // extent of the combined regions. This is to inform the parent of the size
- // of the combined regions.
- // and one with 'offset' as the offset of the child region to the base region,
- // 'pScene' pointing to the parent and 'extents' of zero. This informs the
- // child of its relative base and new parent.
- public void Combine(PhysicsScene pScene, Vector3 offset, Vector3 extents)
- {
- m_worldOffset = offset;
- m_worldMax = extents;
- MegaRegionParentPhysicsScene = pScene;
- if (pScene != null)
- {
- // We are a child.
- // We want m_worldMax to be the highest coordinate of our piece of terrain.
- m_worldMax = offset + DefaultRegionSize;
- }
- DetailLog("{0},BSTerrainManager.Combine,offset={1},extents={2},wOffset={3},wMax={4}",
- BSScene.DetailLogZero, offset, extents, m_worldOffset, m_worldMax);
- }
-
- // Unhook all the combining that I know about.
- public void UnCombine(PhysicsScene pScene)
- {
- // Just like ODE, we don't do anything yet.
- DetailLog("{0},BSTerrainManager.UnCombine", BSScene.DetailLogZero);
- }
-
-
- private void DetailLog(string msg, params Object[] args)
- {
- PhysicsScene.PhysicsLogging.Write(msg, args);
- }
-}
-}
diff --git a/OpenSim/Region/Physics/BulletSNPlugin/BSTerrainMesh.cs b/OpenSim/Region/Physics/BulletSNPlugin/BSTerrainMesh.cs
deleted file mode 100644
index 6083dd451a..0000000000
--- a/OpenSim/Region/Physics/BulletSNPlugin/BSTerrainMesh.cs
+++ /dev/null
@@ -1,267 +0,0 @@
-/*
- * Copyright (c) Contributors, http://opensimulator.org/
- * See CONTRIBUTORS.TXT for a full list of copyright holders.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyrightD
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * * Neither the name of the OpenSimulator Project nor the
- * names of its contributors may be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-using System;
-using System.Collections.Generic;
-using System.Text;
-
-using OpenSim.Framework;
-using OpenSim.Region.Framework;
-using OpenSim.Region.CoreModules;
-using OpenSim.Region.Physics.Manager;
-
-using Nini.Config;
-using log4net;
-
-using OpenMetaverse;
-
-namespace OpenSim.Region.Physics.BulletSNPlugin
-{
-public sealed class BSTerrainMesh : BSTerrainPhys
-{
- static string LogHeader = "[BULLETSIM TERRAIN MESH]";
-
- private float[] m_savedHeightMap;
- int m_sizeX;
- int m_sizeY;
-
- BulletShape m_terrainShape;
- BulletBody m_terrainBody;
-
- public BSTerrainMesh(BSScene physicsScene, Vector3 regionBase, uint id, Vector3 regionSize)
- : base(physicsScene, regionBase, id)
- {
- }
-
- public BSTerrainMesh(BSScene physicsScene, Vector3 regionBase, uint id /* parameters for making mesh */)
- : base(physicsScene, regionBase, id)
- {
- }
-
- // Create terrain mesh from a heightmap.
- public BSTerrainMesh(BSScene physicsScene, Vector3 regionBase, uint id, float[] initialMap,
- Vector3 minCoords, Vector3 maxCoords)
- : base(physicsScene, regionBase, id)
- {
- int indicesCount;
- int[] indices;
- int verticesCount;
- float[] vertices;
-
- m_savedHeightMap = initialMap;
-
- m_sizeX = (int)(maxCoords.X - minCoords.X);
- m_sizeY = (int)(maxCoords.Y - minCoords.Y);
-
- if (!BSTerrainMesh.ConvertHeightmapToMesh(PhysicsScene, initialMap,
- m_sizeX, m_sizeY,
- (float)m_sizeX, (float)m_sizeY,
- Vector3.Zero, 1.0f,
- out indicesCount, out indices, out verticesCount, out vertices))
- {
- // DISASTER!!
- PhysicsScene.DetailLog("{0},BSTerrainMesh.create,failedConversionOfHeightmap", ID);
- PhysicsScene.Logger.ErrorFormat("{0} Failed conversion of heightmap to mesh! base={1}", LogHeader, TerrainBase);
- // Something is very messed up and a crash is in our future.
- return;
- }
- PhysicsScene.DetailLog("{0},BSTerrainMesh.create,meshed,indices={1},indSz={2},vertices={3},vertSz={4}",
- ID, indicesCount, indices.Length, verticesCount, vertices.Length);
-
- m_terrainShape = new BulletShape(BulletSimAPI.CreateMeshShape2(PhysicsScene.World.ptr,
- indicesCount, indices, verticesCount, vertices),
- BSPhysicsShapeType.SHAPE_MESH);
- if (!m_terrainShape.HasPhysicalShape)
- {
- // DISASTER!!
- PhysicsScene.DetailLog("{0},BSTerrainMesh.create,failedCreationOfShape", ID);
- physicsScene.Logger.ErrorFormat("{0} Failed creation of terrain mesh! base={1}", LogHeader, TerrainBase);
- // Something is very messed up and a crash is in our future.
- return;
- }
-
- Vector3 pos = regionBase;
- Quaternion rot = Quaternion.Identity;
-
- m_terrainBody = new BulletBody(id, BulletSimAPI.CreateBodyWithDefaultMotionState2( m_terrainShape.ptr, ID, pos, rot));
- if (!m_terrainBody.HasPhysicalBody)
- {
- // DISASTER!!
- physicsScene.Logger.ErrorFormat("{0} Failed creation of terrain body! base={1}", LogHeader, TerrainBase);
- // Something is very messed up and a crash is in our future.
- return;
- }
-
- // Set current terrain attributes
- BulletSimAPI.SetFriction2(m_terrainBody.ptr, BSParam.TerrainFriction);
- BulletSimAPI.SetHitFraction2(m_terrainBody.ptr, BSParam.TerrainHitFraction);
- BulletSimAPI.SetRestitution2(m_terrainBody.ptr, BSParam.TerrainRestitution);
- BulletSimAPI.SetCollisionFlags2(m_terrainBody.ptr, CollisionFlags.CF_STATIC_OBJECT);
-
- // Static objects are not very massive.
- BulletSimAPI.SetMassProps2(m_terrainBody.ptr, 0f, Vector3.Zero);
-
- // Put the new terrain to the world of physical objects
- BulletSimAPI.AddObjectToWorld2(PhysicsScene.World.ptr, m_terrainBody.ptr, pos, rot);
-
- // Redo its bounding box now that it is in the world
- BulletSimAPI.UpdateSingleAabb2(PhysicsScene.World.ptr, m_terrainBody.ptr);
-
- m_terrainBody.collisionType = CollisionType.Terrain;
- m_terrainBody.ApplyCollisionMask();
-
- // Make it so the terrain will not move or be considered for movement.
- BulletSimAPI.ForceActivationState2(m_terrainBody.ptr, ActivationState.DISABLE_SIMULATION);
- }
-
- public override void Dispose()
- {
- if (m_terrainBody.HasPhysicalBody)
- {
- BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.ptr, m_terrainBody.ptr);
- // Frees both the body and the shape.
- BulletSimAPI.DestroyObject2(PhysicsScene.World.ptr, m_terrainBody.ptr);
- }
- }
-
- public override float GetTerrainHeightAtXYZ(Vector3 pos)
- {
- // For the moment use the saved heightmap to get the terrain height.
- // TODO: raycast downward to find the true terrain below the position.
- float ret = BSTerrainManager.HEIGHT_GETHEIGHT_RET;
-
- int mapIndex = (int)pos.Y * m_sizeY + (int)pos.X;
- try
- {
- ret = m_savedHeightMap[mapIndex];
- }
- catch
- {
- // Sometimes they give us wonky values of X and Y. Give a warning and return something.
- PhysicsScene.Logger.WarnFormat("{0} Bad request for terrain height. terrainBase={1}, pos={2}",
- LogHeader, TerrainBase, pos);
- ret = BSTerrainManager.HEIGHT_GETHEIGHT_RET;
- }
- return ret;
- }
-
- // The passed position is relative to the base of the region.
- public override float GetWaterLevelAtXYZ(Vector3 pos)
- {
- return PhysicsScene.SimpleWaterLevel;
- }
-
- // Convert the passed heightmap to mesh information suitable for CreateMeshShape2().
- // Return 'true' if successfully created.
- public static bool ConvertHeightmapToMesh(
- BSScene physicsScene,
- float[] heightMap, int sizeX, int sizeY, // parameters of incoming heightmap
- float extentX, float extentY, // zero based range for output vertices
- Vector3 extentBase, // base to be added to all vertices
- float magnification, // number of vertices to create between heightMap coords
- out int indicesCountO, out int[] indicesO,
- out int verticesCountO, out float[] verticesO)
- {
- bool ret = false;
-
- int indicesCount = 0;
- int verticesCount = 0;
- int[] indices = new int[0];
- float[] vertices = new float[0];
-
- // Simple mesh creation which assumes magnification == 1.
- // TODO: do a more general solution that scales, adds new vertices and smoothes the result.
-
- // Create an array of vertices that is sizeX+1 by sizeY+1 (note the loop
- // from zero to <= sizeX). The triangle indices are then generated as two triangles
- // per heightmap point. There are sizeX by sizeY of these squares. The extra row and
- // column of vertices are used to complete the triangles of the last row and column
- // of the heightmap.
- try
- {
- // One vertice per heightmap value plus the vertices off the top and bottom edge.
- int totalVertices = (sizeX + 1) * (sizeY + 1);
- vertices = new float[totalVertices * 3];
- int totalIndices = sizeX * sizeY * 6;
- indices = new int[totalIndices];
-
- float magX = (float)sizeX / extentX;
- float magY = (float)sizeY / extentY;
- physicsScene.DetailLog("{0},BSTerrainMesh.ConvertHeightMapToMesh,totVert={1},totInd={2},extentBase={3},magX={4},magY={5}",
- BSScene.DetailLogZero, totalVertices, totalIndices, extentBase, magX, magY);
- float minHeight = float.MaxValue;
- // Note that sizeX+1 vertices are created since there is land between this and the next region.
- for (int yy = 0; yy <= sizeY; yy++)
- {
- for (int xx = 0; xx <= sizeX; xx++) // Hint: the "<=" means we go around sizeX + 1 times
- {
- int offset = yy * sizeX + xx;
- // Extend the height with the height from the last row or column
- if (yy == sizeY) offset -= sizeX;
- if (xx == sizeX) offset -= 1;
- float height = heightMap[offset];
- minHeight = Math.Min(minHeight, height);
- vertices[verticesCount + 0] = (float)xx * magX + extentBase.X;
- vertices[verticesCount + 1] = (float)yy * magY + extentBase.Y;
- vertices[verticesCount + 2] = height + extentBase.Z;
- verticesCount += 3;
- }
- }
- verticesCount = verticesCount / 3;
-
- for (int yy = 0; yy < sizeY; yy++)
- {
- for (int xx = 0; xx < sizeX; xx++)
- {
- int offset = yy * (sizeX + 1) + xx;
- // Each vertices is presumed to be the upper left corner of a box of two triangles
- indices[indicesCount + 0] = offset;
- indices[indicesCount + 1] = offset + 1;
- indices[indicesCount + 2] = offset + sizeX + 1; // accounting for the extra column
- indices[indicesCount + 3] = offset + 1;
- indices[indicesCount + 4] = offset + sizeX + 2;
- indices[indicesCount + 5] = offset + sizeX + 1;
- indicesCount += 6;
- }
- }
-
- ret = true;
- }
- catch (Exception e)
- {
- physicsScene.Logger.ErrorFormat("{0} Failed conversion of heightmap to mesh. For={1}/{2}, e={3}",
- LogHeader, physicsScene.RegionName, extentBase, e);
- }
-
- indicesCountO = indicesCount;
- indicesO = indices;
- verticesCountO = verticesCount;
- verticesO = vertices;
-
- return ret;
- }
-}
-}
diff --git a/OpenSim/Region/Physics/BulletSNPlugin/BulletSimAPI.cs b/OpenSim/Region/Physics/BulletSNPlugin/BulletSimAPI.cs
deleted file mode 100644
index 93643c9f50..0000000000
--- a/OpenSim/Region/Physics/BulletSNPlugin/BulletSimAPI.cs
+++ /dev/null
@@ -1,1603 +0,0 @@
-/*
- * Copyright (c) Contributors, http://opensimulator.org/
- * See CONTRIBUTORS.TXT for a full list of copyright holders.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyrightD
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * * Neither the name of the OpenSimulator Project nor the
- * names of its contributors may be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Runtime.InteropServices;
-using System.Security;
-using System.Text;
-using BulletXNA;
-using OpenMetaverse;
-using BulletXNA.LinearMath;
-using BulletXNA.BulletCollision;
-using BulletXNA.BulletDynamics;
-using BulletXNA.BulletCollision.CollisionDispatch;
-using OpenSim.Framework;
-
-namespace OpenSim.Region.Physics.BulletSNPlugin {
-
-// Classes to allow some type checking for the API
-// These hold pointers to allocated objects in the unmanaged space.
-
-
-
- // Constraint type values as defined by Bullet
-public enum ConstraintType : int
-{
- POINT2POINT_CONSTRAINT_TYPE = 3,
- HINGE_CONSTRAINT_TYPE,
- CONETWIST_CONSTRAINT_TYPE,
- D6_CONSTRAINT_TYPE,
- SLIDER_CONSTRAINT_TYPE,
- CONTACT_CONSTRAINT_TYPE,
- D6_SPRING_CONSTRAINT_TYPE,
- MAX_CONSTRAINT_TYPE
-}
-
-// ===============================================================================
-[StructLayout(LayoutKind.Sequential)]
-public struct ConvexHull
-{
- Vector3 Offset;
- int VertexCount;
- Vector3[] Vertices;
-}
-public enum BSPhysicsShapeType
-{
- SHAPE_UNKNOWN = 0,
- SHAPE_CAPSULE = 1,
- SHAPE_BOX = 2,
- SHAPE_CONE = 3,
- SHAPE_CYLINDER = 4,
- SHAPE_SPHERE = 5,
- SHAPE_MESH = 6,
- SHAPE_HULL = 7,
- // following defined by BulletSim
- SHAPE_GROUNDPLANE = 20,
- SHAPE_TERRAIN = 21,
- SHAPE_COMPOUND = 22,
- SHAPE_HEIGHTMAP = 23,
-};
-
-// The native shapes have predefined shape hash keys
-public enum FixedShapeKey : ulong
-{
- KEY_NONE = 0,
- KEY_BOX = 1,
- KEY_SPHERE = 2,
- KEY_CONE = 3,
- KEY_CYLINDER = 4,
- KEY_CAPSULE = 5,
-}
-
-[StructLayout(LayoutKind.Sequential)]
-public struct ShapeData
-{
- public uint ID;
- public BSPhysicsShapeType Type;
- public Vector3 Position;
- public Quaternion Rotation;
- public Vector3 Velocity;
- public Vector3 Scale;
- public float Mass;
- public float Buoyancy;
- public System.UInt64 HullKey;
- public System.UInt64 MeshKey;
- public float Friction;
- public float Restitution;
- public float Collidable; // true of things bump into this
- public float Static; // true if a static object. Otherwise gravity, etc.
- public float Solid; // true if object cannot be passed through
- public Vector3 Size;
-
- // note that bools are passed as floats since bool size changes by language and architecture
- public const float numericTrue = 1f;
- public const float numericFalse = 0f;
-}
-[StructLayout(LayoutKind.Sequential)]
-public struct SweepHit
-{
- public uint ID;
- public float Fraction;
- public Vector3 Normal;
- public Vector3 Point;
-}
-[StructLayout(LayoutKind.Sequential)]
-public struct RaycastHit
-{
- public uint ID;
- public float Fraction;
- public Vector3 Normal;
-}
-[StructLayout(LayoutKind.Sequential)]
-public struct CollisionDesc
-{
- public uint aID;
- public uint bID;
- public Vector3 point;
- public Vector3 normal;
-}
-[StructLayout(LayoutKind.Sequential)]
-public struct EntityProperties
-{
- public uint ID;
- public Vector3 Position;
- public Quaternion Rotation;
- public Vector3 Velocity;
- public Vector3 Acceleration;
- public Vector3 RotationalVelocity;
- public override string ToString()
- {
- return string.Format("ID:{0}, Pos:<{1:F},{2:F},{3:F}>, Rot:<{4:F},{5:F},{6:F},{7:F}>, LVel:<{8:F},{9:F},{10:F}>, AVel:<{11:F},{12:F},{13:F}>",
- ID.ToString(),
- Position.X,Position.Y,Position.Z,
- Rotation.X,Rotation.Y,Rotation.Z,Rotation.W,
- Velocity.X,Velocity.Y,Velocity.Z,
- RotationalVelocity.X,RotationalVelocity.Y,RotationalVelocity.Z
- );
- }
-}
-
-// Format of this structure must match the definition in the C++ code
-// NOTE: adding the X causes compile breaks if used. These are unused symbols
-// that can be removed from both here and the unmanaged definition of this structure.
-[StructLayout(LayoutKind.Sequential)]
-public struct ConfigurationParameters
-{
- public float defaultFriction;
- public float defaultDensity;
- public float defaultRestitution;
- public float collisionMargin;
- public float gravity;
-
- public float XlinearDamping;
- public float XangularDamping;
- public float XdeactivationTime;
- public float XlinearSleepingThreshold;
- public float XangularSleepingThreshold;
- public float XccdMotionThreshold;
- public float XccdSweptSphereRadius;
- public float XcontactProcessingThreshold;
-
- public float XterrainImplementation;
- public float XterrainFriction;
- public float XterrainHitFraction;
- public float XterrainRestitution;
- public float XterrainCollisionMargin;
-
- public float XavatarFriction;
- public float XavatarStandingFriction;
- public float XavatarDensity;
- public float XavatarRestitution;
- public float XavatarCapsuleWidth;
- public float XavatarCapsuleDepth;
- public float XavatarCapsuleHeight;
- public float XavatarContactProcessingThreshold;
-
- public float XvehicleAngularDamping;
-
- public float maxPersistantManifoldPoolSize;
- public float maxCollisionAlgorithmPoolSize;
- public float shouldDisableContactPoolDynamicAllocation;
- public float shouldForceUpdateAllAabbs;
- public float shouldRandomizeSolverOrder;
- public float shouldSplitSimulationIslands;
- public float shouldEnableFrictionCaching;
- public float numberOfSolverIterations;
-
- public float XlinksetImplementation;
- public float XlinkConstraintUseFrameOffset;
- public float XlinkConstraintEnableTransMotor;
- public float XlinkConstraintTransMotorMaxVel;
- public float XlinkConstraintTransMotorMaxForce;
- public float XlinkConstraintERP;
- public float XlinkConstraintCFM;
- public float XlinkConstraintSolverIterations;
-
- public float physicsLoggingFrames;
-
- public const float numericTrue = 1f;
- public const float numericFalse = 0f;
-}
-
-
-// The states a bullet collision object can have
-
-public enum ActivationState : uint
-{
- UNDEFINED = 0,
- ACTIVE_TAG = 1,
- ISLAND_SLEEPING = 2,
- WANTS_DEACTIVATION = 3,
- DISABLE_DEACTIVATION = 4,
- DISABLE_SIMULATION = 5,
-}
-
-public enum CollisionObjectTypes : int
-{
- CO_COLLISION_OBJECT = 1 << 0,
- CO_RIGID_BODY = 1 << 1,
- CO_GHOST_OBJECT = 1 << 2,
- CO_SOFT_BODY = 1 << 3,
- CO_HF_FLUID = 1 << 4,
- CO_USER_TYPE = 1 << 5,
-}
-
-// Values used by Bullet and BulletSim to control object properties.
-// Bullet's "CollisionFlags" has more to do with operations on the
-// object (if collisions happen, if gravity effects it, ...).
- [Flags]
-public enum CollisionFlags : uint
-{
- CF_STATIC_OBJECT = 1 << 0,
- CF_KINEMATIC_OBJECT = 1 << 1,
- CF_NO_CONTACT_RESPONSE = 1 << 2,
- CF_CUSTOM_MATERIAL_CALLBACK = 1 << 3,
- CF_CHARACTER_OBJECT = 1 << 4,
- CF_DISABLE_VISUALIZE_OBJECT = 1 << 5,
- CF_DISABLE_SPU_COLLISION_PROCESS = 1 << 6,
- // Following used by BulletSim to control collisions and updates
- BS_SUBSCRIBE_COLLISION_EVENTS = 1 << 10,
- BS_FLOATS_ON_WATER = 1 << 11,
- BS_VEHICLE_COLLISIONS = 1 << 12,
- BS_NONE = 0,
- BS_ALL = 0xFFFFFFFF,
-
- // These are the collision flags switched depending on physical state.
- // The other flags are used for other things and should not be fooled with.
- BS_ACTIVE = CF_STATIC_OBJECT
- | CF_KINEMATIC_OBJECT
- | CF_NO_CONTACT_RESPONSE
-};
-
-// Values for collisions groups and masks
-public enum CollisionFilterGroups : uint
-{
- // Don't use the bit definitions!! Define the use in a
- // filter/mask definition below. This way collision interactions
- // are more easily debugged.
- BNoneGroup = 0,
- BDefaultGroup = 1 << 0,
- BStaticGroup = 1 << 1,
- BKinematicGroup = 1 << 2,
- BDebrisGroup = 1 << 3,
- BSensorTrigger = 1 << 4,
- BCharacterGroup = 1 << 5,
- BAllGroup = 0xFFFFFFFF,
- // Filter groups defined by BulletSim
- BGroundPlaneGroup = 1 << 10,
- BTerrainGroup = 1 << 11,
- BRaycastGroup = 1 << 12,
- BSolidGroup = 1 << 13,
- // BLinksetGroup = xx // a linkset proper is either static or dynamic
- BLinksetChildGroup = 1 << 14,
- // The collsion filters and masked are defined in one place -- don't want them scattered
- AvatarGroup = BCharacterGroup,
- AvatarMask = BAllGroup,
- ObjectGroup = BSolidGroup,
- ObjectMask = BAllGroup,
- StaticObjectGroup = BStaticGroup,
- StaticObjectMask = AvatarGroup | ObjectGroup, // static things don't interact with much
- LinksetGroup = BLinksetChildGroup,
- LinksetMask = BAllGroup & ~BLinksetChildGroup, // linkset objects don't collide with each other
- VolumeDetectGroup = BSensorTrigger,
- VolumeDetectMask = ~BSensorTrigger,
- TerrainGroup = BTerrainGroup,
- TerrainMask = BAllGroup & ~BStaticGroup, // static objects on the ground don't collide
- GroundPlaneGroup = BGroundPlaneGroup,
- GroundPlaneMask = BAllGroup
-
-};
-
-// CFM controls the 'hardness' of the constraint. 0=fixed, 0..1=violatable. Default=0
-// ERP controls amount of correction per tick. Usable range=0.1..0.8. Default=0.2.
-public enum ConstraintParams : int
-{
- BT_CONSTRAINT_ERP = 1, // this one is not used in Bullet as of 20120730
- BT_CONSTRAINT_STOP_ERP,
- BT_CONSTRAINT_CFM,
- BT_CONSTRAINT_STOP_CFM,
-};
-public enum ConstraintParamAxis : int
-{
- AXIS_LINEAR_X = 0,
- AXIS_LINEAR_Y,
- AXIS_LINEAR_Z,
- AXIS_ANGULAR_X,
- AXIS_ANGULAR_Y,
- AXIS_ANGULAR_Z,
- AXIS_LINEAR_ALL = 20, // these last three added by BulletSim so we don't have to do zillions of calls
- AXIS_ANGULAR_ALL,
- AXIS_ALL
-};
-
-// ===============================================================================
-static class BulletSimAPI {
- private static int m_collisionsThisFrame;
- public delegate void DebugLogCallback(string msg);
- ///
- ///
- ///
- ///
- ///
- internal static bool RemoveObjectFromWorld2(object pWorld, object pBody)
- {
- DiscreteDynamicsWorld world = pWorld as DiscreteDynamicsWorld;
- RigidBody body = pBody as RigidBody;
- world.RemoveRigidBody(body);
- return true;
- }
-
- internal static void SetRestitution2(object pBody, float pRestitution)
- {
- RigidBody body = pBody as RigidBody;
- body.SetRestitution(pRestitution);
- }
-
- internal static void SetMargin2(object pShape, float pMargin)
- {
- CollisionShape shape = pShape as CollisionShape;
- shape.SetMargin(pMargin);
- }
-
- internal static void SetLocalScaling2(object pShape, Vector3 pScale)
- {
- CollisionShape shape = pShape as CollisionShape;
- IndexedVector3 vec = new IndexedVector3(pScale.X, pScale.Y, pScale.Z);
- shape.SetLocalScaling(ref vec);
-
- }
-
- internal static void SetContactProcessingThreshold2(object pBody, float contactprocessingthreshold)
- {
- RigidBody body = pBody as RigidBody;
- body.SetContactProcessingThreshold(contactprocessingthreshold);
- }
-
- internal static void SetCcdMotionThreshold2(object pBody, float pccdMotionThreashold)
- {
- RigidBody body = pBody as RigidBody;
- body.SetCcdMotionThreshold(pccdMotionThreashold);
- }
-
- internal static void SetCcdSweptSphereRadius2(object pBody, float pCcdSweptSphereRadius)
- {
- RigidBody body = pBody as RigidBody;
- body.SetCcdSweptSphereRadius(pCcdSweptSphereRadius);
- }
-
- internal static void SetAngularFactorV2(object pBody, Vector3 pAngularFactor)
- {
- RigidBody body = pBody as RigidBody;
- body.SetAngularFactor(new IndexedVector3(pAngularFactor.X, pAngularFactor.Y, pAngularFactor.Z));
- }
-
- internal static CollisionFlags AddToCollisionFlags2(object pBody, CollisionFlags pcollisionFlags)
- {
- CollisionObject body = pBody as CollisionObject;
- CollisionFlags existingcollisionFlags = (CollisionFlags)(uint)body.GetCollisionFlags();
- existingcollisionFlags |= pcollisionFlags;
- body.SetCollisionFlags((BulletXNA.BulletCollision.CollisionFlags)(uint)existingcollisionFlags);
- return (CollisionFlags) (uint) existingcollisionFlags;
- }
-
- internal static void AddObjectToWorld2(object pWorld, object pBody)
- {
- RigidBody body = pBody as RigidBody;
- DiscreteDynamicsWorld world = pWorld as DiscreteDynamicsWorld;
- //if (!(body.GetCollisionShape().GetShapeType() == BroadphaseNativeTypes.STATIC_PLANE_PROXYTYPE && body.GetCollisionShape().GetShapeType() == BroadphaseNativeTypes.TERRAIN_SHAPE_PROXYTYPE))
-
- world.AddRigidBody(body);
-
- //if (body.GetBroadphaseHandle() != null)
- // world.UpdateSingleAabb(body);
- }
-
- internal static void AddObjectToWorld2(object pWorld, object pBody, Vector3 _position, Quaternion _orientation)
- {
- RigidBody body = pBody as RigidBody;
- DiscreteDynamicsWorld world = pWorld as DiscreteDynamicsWorld;
- //if (!(body.GetCollisionShape().GetShapeType() == BroadphaseNativeTypes.STATIC_PLANE_PROXYTYPE && body.GetCollisionShape().GetShapeType() == BroadphaseNativeTypes.TERRAIN_SHAPE_PROXYTYPE))
-
- world.AddRigidBody(body);
- IndexedVector3 vposition = new IndexedVector3(_position.X, _position.Y, _position.Z);
- IndexedQuaternion vquaternion = new IndexedQuaternion(_orientation.X, _orientation.Y, _orientation.Z,
- _orientation.W);
- IndexedMatrix mat = IndexedMatrix.CreateFromQuaternion(vquaternion);
- mat._origin = vposition;
- body.SetWorldTransform(mat);
- //if (body.GetBroadphaseHandle() != null)
- // world.UpdateSingleAabb(body);
- }
-
- internal static void ForceActivationState2(object pBody, ActivationState pActivationState)
- {
- CollisionObject body = pBody as CollisionObject;
- body.ForceActivationState((BulletXNA.BulletCollision.ActivationState)(uint)pActivationState);
- }
-
- internal static void UpdateSingleAabb2(object pWorld, object pBody)
- {
- CollisionObject body = pBody as CollisionObject;
- DiscreteDynamicsWorld world = pWorld as DiscreteDynamicsWorld;
- world.UpdateSingleAabb(body);
- }
-
- internal static bool SetCollisionGroupMask2(object pBody, uint pGroup, uint pMask)
- {
- RigidBody body = pBody as RigidBody;
- body.GetBroadphaseHandle().m_collisionFilterGroup = (BulletXNA.BulletCollision.CollisionFilterGroups) pGroup;
- body.GetBroadphaseHandle().m_collisionFilterGroup = (BulletXNA.BulletCollision.CollisionFilterGroups) pGroup;
- if ((uint) body.GetBroadphaseHandle().m_collisionFilterGroup == 0)
- return false;
- return true;
- }
-
- internal static void ClearAllForces2(object pBody)
- {
- CollisionObject body = pBody as CollisionObject;
- IndexedVector3 zeroVector = new IndexedVector3(0, 0, 0);
- body.SetInterpolationLinearVelocity(ref zeroVector);
- body.SetInterpolationAngularVelocity(ref zeroVector);
- IndexedMatrix bodytransform = body.GetWorldTransform();
-
- body.SetInterpolationWorldTransform(ref bodytransform);
-
- if (body is RigidBody)
- {
- RigidBody rigidbody = body as RigidBody;
- rigidbody.SetLinearVelocity(zeroVector);
- rigidbody.SetAngularVelocity(zeroVector);
- rigidbody.ClearForces();
- }
- }
-
- internal static void SetInterpolationAngularVelocity2(object pBody, Vector3 pVector3)
- {
- RigidBody body = pBody as RigidBody;
- IndexedVector3 vec = new IndexedVector3(pVector3.X, pVector3.Y, pVector3.Z);
- body.SetInterpolationAngularVelocity(ref vec);
- }
-
- internal static void SetAngularVelocity2(object pBody, Vector3 pVector3)
- {
- RigidBody body = pBody as RigidBody;
- IndexedVector3 vec = new IndexedVector3(pVector3.X, pVector3.Y, pVector3.Z);
- body.SetAngularVelocity(ref vec);
- }
-
- internal static void ClearForces2(object pBody)
- {
- RigidBody body = pBody as RigidBody;
- body.ClearForces();
- }
-
- internal static void SetTranslation2(object pBody, Vector3 _position, Quaternion _orientation)
- {
- RigidBody body = pBody as RigidBody;
- IndexedVector3 vposition = new IndexedVector3(_position.X, _position.Y, _position.Z);
- IndexedQuaternion vquaternion = new IndexedQuaternion(_orientation.X, _orientation.Y, _orientation.Z,
- _orientation.W);
- IndexedMatrix mat = IndexedMatrix.CreateFromQuaternion(vquaternion);
- mat._origin = vposition;
- body.SetWorldTransform(mat);
-
- }
-
- internal static Vector3 GetPosition2(object pBody)
- {
- RigidBody body = pBody as RigidBody;
- IndexedVector3 pos = body.GetInterpolationWorldTransform()._origin;
- return new Vector3(pos.X, pos.Y, pos.Z);
- }
-
- internal static Vector3 CalculateLocalInertia2(object pShape, float pphysMass)
- {
- CollisionShape shape = pShape as CollisionShape;
- IndexedVector3 inertia = IndexedVector3.Zero;
- shape.CalculateLocalInertia(pphysMass, out inertia);
- return new Vector3(inertia.X, inertia.Y, inertia.Z);
- }
-
- internal static void SetMassProps2(object pBody, float pphysMass, Vector3 plocalInertia)
- {
- RigidBody body = pBody as RigidBody;
- IndexedVector3 inertia = new IndexedVector3(plocalInertia.X, plocalInertia.Y, plocalInertia.Z);
- body.SetMassProps(pphysMass, inertia);
- }
-
-
- internal static void SetObjectForce2(object pBody, Vector3 _force)
- {
- RigidBody body = pBody as RigidBody;
- IndexedVector3 force = new IndexedVector3(_force.X, _force.Y, _force.Z);
- body.SetTotalForce(ref force);
- }
-
- internal static void SetFriction2(object pBody, float _currentFriction)
- {
- RigidBody body = pBody as RigidBody;
- body.SetFriction(_currentFriction);
- }
-
- internal static void SetLinearVelocity2(object pBody, Vector3 _velocity)
- {
- RigidBody body = pBody as RigidBody;
- IndexedVector3 velocity = new IndexedVector3(_velocity.X, _velocity.Y, _velocity.Z);
- body.SetLinearVelocity(velocity);
- }
-
- internal static void Activate2(object pBody, bool pforceactivation)
- {
- RigidBody body = pBody as RigidBody;
- body.Activate(pforceactivation);
-
- }
-
- internal static Quaternion GetOrientation2(object pBody)
- {
- RigidBody body = pBody as RigidBody;
- IndexedQuaternion mat = body.GetInterpolationWorldTransform().GetRotation();
- return new Quaternion(mat.X, mat.Y, mat.Z, mat.W);
- }
-
- internal static CollisionFlags RemoveFromCollisionFlags2(object pBody, CollisionFlags pcollisionFlags)
- {
- RigidBody body = pBody as RigidBody;
- CollisionFlags existingcollisionFlags = (CollisionFlags)(uint)body.GetCollisionFlags();
- existingcollisionFlags &= ~pcollisionFlags;
- body.SetCollisionFlags((BulletXNA.BulletCollision.CollisionFlags)(uint)existingcollisionFlags);
- return (CollisionFlags)(uint)existingcollisionFlags;
- }
-
- internal static void SetGravity2(object pBody, Vector3 pGravity)
- {
- RigidBody body = pBody as RigidBody;
- IndexedVector3 gravity = new IndexedVector3(pGravity.X, pGravity.Y, pGravity.Z);
- body.SetGravity(gravity);
- }
-
- internal static bool DestroyConstraint2(object pBody, object pConstraint)
- {
- RigidBody body = pBody as RigidBody;
- TypedConstraint constraint = pConstraint as TypedConstraint;
- body.RemoveConstraintRef(constraint);
- return true;
- }
-
- internal static bool SetLinearLimits2(object pConstraint, Vector3 low, Vector3 high)
- {
- Generic6DofConstraint constraint = pConstraint as Generic6DofConstraint;
- IndexedVector3 lowlimit = new IndexedVector3(low.X, low.Y, low.Z);
- IndexedVector3 highlimit = new IndexedVector3(high.X, high.Y, high.Z);
- constraint.SetLinearLowerLimit(lowlimit);
- constraint.SetLinearUpperLimit(highlimit);
- return true;
- }
-
- internal static bool SetAngularLimits2(object pConstraint, Vector3 low, Vector3 high)
- {
- Generic6DofConstraint constraint = pConstraint as Generic6DofConstraint;
- IndexedVector3 lowlimit = new IndexedVector3(low.X, low.Y, low.Z);
- IndexedVector3 highlimit = new IndexedVector3(high.X, high.Y, high.Z);
- constraint.SetAngularLowerLimit(lowlimit);
- constraint.SetAngularUpperLimit(highlimit);
- return true;
- }
-
- internal static void SetConstraintNumSolverIterations2(object pConstraint, float cnt)
- {
- Generic6DofConstraint constraint = pConstraint as Generic6DofConstraint;
- constraint.SetOverrideNumSolverIterations((int)cnt);
- }
-
- internal static void CalculateTransforms2(object pConstraint)
- {
- Generic6DofConstraint constraint = pConstraint as Generic6DofConstraint;
- constraint.CalculateTransforms();
- }
-
- internal static void SetConstraintEnable2(object pConstraint, float p_2)
- {
- Generic6DofConstraint constraint = pConstraint as Generic6DofConstraint;
- constraint.SetEnabled((p_2 == 0) ? false : true);
- }
-
-
- //BulletSimAPI.Create6DofConstraint2(m_world.ptr, m_body1.ptr, m_body2.ptr,frame1, frame1rot,frame2, frame2rot,useLinearReferenceFrameA, disableCollisionsBetweenLinkedBodies));
- internal static object Create6DofConstraint2(object pWorld, object pBody1, object pBody2, Vector3 pframe1, Quaternion pframe1rot, Vector3 pframe2, Quaternion pframe2rot, bool puseLinearReferenceFrameA, bool pdisableCollisionsBetweenLinkedBodies)
-
- {
- DiscreteDynamicsWorld world = pWorld as DiscreteDynamicsWorld;
- RigidBody body1 = pBody1 as RigidBody;
- RigidBody body2 = pBody2 as RigidBody;
- IndexedVector3 frame1v = new IndexedVector3(pframe1.X, pframe1.Y, pframe1.Z);
- IndexedQuaternion frame1rot = new IndexedQuaternion(pframe1rot.X, pframe1rot.Y, pframe1rot.Z, pframe1rot.W);
- IndexedMatrix frame1 = IndexedMatrix.CreateFromQuaternion(frame1rot);
- frame1._origin = frame1v;
-
- IndexedVector3 frame2v = new IndexedVector3(pframe2.X, pframe2.Y, pframe2.Z);
- IndexedQuaternion frame2rot = new IndexedQuaternion(pframe2rot.X, pframe2rot.Y, pframe2rot.Z, pframe2rot.W);
- IndexedMatrix frame2 = IndexedMatrix.CreateFromQuaternion(frame2rot);
- frame2._origin = frame1v;
-
- Generic6DofConstraint consttr = new Generic6DofConstraint(body1, body2, ref frame1, ref frame2,
- puseLinearReferenceFrameA);
- consttr.CalculateTransforms();
- world.AddConstraint(consttr,pdisableCollisionsBetweenLinkedBodies);
-
- return consttr;
- }
-
-
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- internal static object Create6DofConstraintToPoint2(object pWorld, object pBody1, object pBody2, Vector3 pjoinPoint, bool puseLinearReferenceFrameA, bool pdisableCollisionsBetweenLinkedBodies)
- {
- DiscreteDynamicsWorld world = pWorld as DiscreteDynamicsWorld;
- RigidBody body1 = pBody1 as RigidBody;
- RigidBody body2 = pBody2 as RigidBody;
- IndexedMatrix frame1 = new IndexedMatrix(IndexedBasisMatrix.Identity, new IndexedVector3(0, 0, 0));
- IndexedMatrix frame2 = new IndexedMatrix(IndexedBasisMatrix.Identity, new IndexedVector3(0, 0, 0));
-
- IndexedVector3 joinPoint = new IndexedVector3(pjoinPoint.X, pjoinPoint.Y, pjoinPoint.Z);
- IndexedMatrix mat = IndexedMatrix.Identity;
- mat._origin = new IndexedVector3(pjoinPoint.X, pjoinPoint.Y, pjoinPoint.Z);
- frame1._origin = body1.GetWorldTransform().Inverse()*joinPoint;
- frame2._origin = body2.GetWorldTransform().Inverse()*joinPoint;
-
- Generic6DofConstraint consttr = new Generic6DofConstraint(body1, body2, ref frame1, ref frame2, puseLinearReferenceFrameA);
- consttr.CalculateTransforms();
- world.AddConstraint(consttr, pdisableCollisionsBetweenLinkedBodies);
-
- return consttr;
- }
- //SetFrames2(m_constraint.ptr, frameA, frameArot, frameB, frameBrot);
- internal static void SetFrames2(object pConstraint, Vector3 pframe1, Quaternion pframe1rot, Vector3 pframe2, Quaternion pframe2rot)
- {
- Generic6DofConstraint constraint = pConstraint as Generic6DofConstraint;
- IndexedVector3 frame1v = new IndexedVector3(pframe1.X, pframe1.Y, pframe1.Z);
- IndexedQuaternion frame1rot = new IndexedQuaternion(pframe1rot.X, pframe1rot.Y, pframe1rot.Z, pframe1rot.W);
- IndexedMatrix frame1 = IndexedMatrix.CreateFromQuaternion(frame1rot);
- frame1._origin = frame1v;
-
- IndexedVector3 frame2v = new IndexedVector3(pframe2.X, pframe2.Y, pframe2.Z);
- IndexedQuaternion frame2rot = new IndexedQuaternion(pframe2rot.X, pframe2rot.Y, pframe2rot.Z, pframe2rot.W);
- IndexedMatrix frame2 = IndexedMatrix.CreateFromQuaternion(frame2rot);
- frame2._origin = frame1v;
- constraint.SetFrames(ref frame1, ref frame2);
- }
-
-
-
-
- internal static bool IsInWorld2(object pWorld, object pShapeObj)
- {
- DiscreteDynamicsWorld world = pWorld as DiscreteDynamicsWorld;
- CollisionObject shape = pShapeObj as CollisionObject;
- return world.IsInWorld(shape);
- }
-
- internal static void SetInterpolationLinearVelocity2(object pBody, Vector3 VehicleVelocity)
- {
- RigidBody body = pBody as RigidBody;
- IndexedVector3 velocity = new IndexedVector3(VehicleVelocity.X, VehicleVelocity.Y, VehicleVelocity.Z);
- body.SetInterpolationLinearVelocity(ref velocity);
- }
-
- internal static bool UseFrameOffset2(object pConstraint, float onOff)
- {
- Generic6DofConstraint constraint = pConstraint as Generic6DofConstraint;
- constraint.SetUseFrameOffset((onOff == 0) ? false : true);
- return true;
- }
- //SetBreakingImpulseThreshold2(m_constraint.ptr, threshold);
- internal static bool SetBreakingImpulseThreshold2(object pConstraint, float threshold)
- {
- Generic6DofConstraint constraint = pConstraint as Generic6DofConstraint;
- constraint.SetBreakingImpulseThreshold(threshold);
- return true;
- }
- //BulletSimAPI.SetAngularDamping2(Prim.PhysBody.ptr, angularDamping);
- internal static void SetAngularDamping2(object pBody, float angularDamping)
- {
- RigidBody body = pBody as RigidBody;
- float lineardamping = body.GetLinearDamping();
- body.SetDamping(lineardamping, angularDamping);
-
- }
-
- internal static void UpdateInertiaTensor2(object pBody)
- {
- RigidBody body = pBody as RigidBody;
- body.UpdateInertiaTensor();
- }
-
- internal static void RecalculateCompoundShapeLocalAabb2( object pCompoundShape)
- {
-
- CompoundShape shape = pCompoundShape as CompoundShape;
- shape.RecalculateLocalAabb();
- }
-
- //BulletSimAPI.GetCollisionFlags2(PhysBody.ptr)
- internal static CollisionFlags GetCollisionFlags2(object pBody)
- {
- RigidBody body = pBody as RigidBody;
- uint flags = (uint)body.GetCollisionFlags();
- return (CollisionFlags) flags;
- }
-
- internal static void SetDamping2(object pBody, float pLinear, float pAngular)
- {
- RigidBody body = pBody as RigidBody;
- body.SetDamping(pLinear, pAngular);
- }
- //PhysBody.ptr, PhysicsScene.Params.deactivationTime);
- internal static void SetDeactivationTime2(object pBody, float pDeactivationTime)
- {
- RigidBody body = pBody as RigidBody;
- body.SetDeactivationTime(pDeactivationTime);
- }
- //SetSleepingThresholds2(PhysBody.ptr, PhysicsScene.Params.linearSleepingThreshold, PhysicsScene.Params.angularSleepingThreshold);
- internal static void SetSleepingThresholds2(object pBody, float plinearSleepingThreshold, float pangularSleepingThreshold)
- {
- RigidBody body = pBody as RigidBody;
- body.SetSleepingThresholds(plinearSleepingThreshold, pangularSleepingThreshold);
- }
-
- internal static CollisionObjectTypes GetBodyType2(object pBody)
- {
- RigidBody body = pBody as RigidBody;
- return (CollisionObjectTypes)(int) body.GetInternalType();
- }
-
- //BulletSimAPI.ApplyCentralForce2(PhysBody.ptr, fSum);
- internal static void ApplyCentralForce2(object pBody, Vector3 pfSum)
- {
- RigidBody body = pBody as RigidBody;
- IndexedVector3 fSum = new IndexedVector3(pfSum.X, pfSum.Y, pfSum.Z);
- body.ApplyCentralForce(ref fSum);
- }
- internal static void ApplyCentralImpulse2(object pBody, Vector3 pfSum)
- {
- RigidBody body = pBody as RigidBody;
- IndexedVector3 fSum = new IndexedVector3(pfSum.X, pfSum.Y, pfSum.Z);
- body.ApplyCentralImpulse(ref fSum);
- }
- internal static void ApplyTorque2(object pBody, Vector3 pfSum)
- {
- RigidBody body = pBody as RigidBody;
- IndexedVector3 fSum = new IndexedVector3(pfSum.X, pfSum.Y, pfSum.Z);
- body.ApplyTorque(ref fSum);
- }
- internal static void ApplyTorqueImpulse2(object pBody, Vector3 pfSum)
- {
- RigidBody body = pBody as RigidBody;
- IndexedVector3 fSum = new IndexedVector3(pfSum.X, pfSum.Y, pfSum.Z);
- body.ApplyTorqueImpulse(ref fSum);
- }
-
- internal static void DumpRigidBody2(object p, object p_2)
- {
- //TODO:
- }
-
- internal static void DumpCollisionShape2(object p, object p_2)
- {
- //TODO:
- }
-
- internal static void DestroyObject2(object p, object p_2)
- {
- //TODO:
- }
-
- internal static void Shutdown2(object pWorld)
- {
- DiscreteDynamicsWorld world = pWorld as DiscreteDynamicsWorld;
- world.Cleanup();
- }
-
- internal static void DeleteCollisionShape2(object p, object p_2)
- {
- //TODO:
- }
- //(sim.ptr, shape.ptr, prim.LocalID, prim.RawPosition, prim.RawOrientation);
-
- internal static object CreateBodyFromShape2(object pWorld, object pShape, uint pLocalID, Vector3 pRawPosition, Quaternion pRawOrientation)
- {
- CollisionWorld world = pWorld as CollisionWorld;
- IndexedMatrix mat =
- IndexedMatrix.CreateFromQuaternion(new IndexedQuaternion(pRawOrientation.X, pRawOrientation.Y,
- pRawOrientation.Z, pRawOrientation.W));
- mat._origin = new IndexedVector3(pRawPosition.X, pRawPosition.Y, pRawPosition.Z);
- CollisionShape shape = pShape as CollisionShape;
- //UpdateSingleAabb2(world, shape);
- // TODO: Feed Update array into null
- RigidBody body = new RigidBody(0,new SimMotionState(world,pLocalID,mat,null),shape,IndexedVector3.Zero);
-
- body.SetUserPointer(pLocalID);
- return body;
- }
-
-
- internal static object CreateBodyWithDefaultMotionState2( object pShape, uint pLocalID, Vector3 pRawPosition, Quaternion pRawOrientation)
- {
-
- IndexedMatrix mat =
- IndexedMatrix.CreateFromQuaternion(new IndexedQuaternion(pRawOrientation.X, pRawOrientation.Y,
- pRawOrientation.Z, pRawOrientation.W));
- mat._origin = new IndexedVector3(pRawPosition.X, pRawPosition.Y, pRawPosition.Z);
-
- CollisionShape shape = pShape as CollisionShape;
-
- // TODO: Feed Update array into null
- RigidBody body = new RigidBody(0, new DefaultMotionState( mat, IndexedMatrix.Identity), shape, IndexedVector3.Zero);
- body.SetWorldTransform(mat);
- body.SetUserPointer(pLocalID);
- return body;
- }
- //(m_mapInfo.terrainBody.ptr, CollisionFlags.CF_STATIC_OBJECT);
- internal static void SetCollisionFlags2(object pBody, CollisionFlags collisionFlags)
- {
- RigidBody body = pBody as RigidBody;
- body.SetCollisionFlags((BulletXNA.BulletCollision.CollisionFlags) (uint) collisionFlags);
- }
- //(m_mapInfo.terrainBody.ptr, PhysicsScene.Params.terrainHitFraction);
- internal static void SetHitFraction2(object pBody, float pHitFraction)
- {
- RigidBody body = pBody as RigidBody;
- body.SetHitFraction(pHitFraction);
- }
- //BuildCapsuleShape2(physicsScene.World.ptr, 1f, 1f, prim.Scale);
- internal static object BuildCapsuleShape2(object pWorld, float pRadius, float pHeight, Vector3 pScale)
- {
- DiscreteDynamicsWorld world = pWorld as DiscreteDynamicsWorld;
- IndexedVector3 scale = new IndexedVector3(pScale.X, pScale.Y, pScale.Z);
- CapsuleShapeZ capsuleShapeZ = new CapsuleShapeZ(pRadius, pHeight);
- capsuleShapeZ.SetMargin(world.WorldSettings.Params.collisionMargin);
- capsuleShapeZ.SetLocalScaling(ref scale);
-
- return capsuleShapeZ;
- }
-
- public static object Initialize2(Vector3 worldExtent, ConfigurationParameters[] o, int mMaxCollisionsPerFrame, ref List collisionArray, int mMaxUpdatesPerFrame, ref List updateArray, object mDebugLogCallbackHandle)
- {
- CollisionWorld.WorldData.ParamData p = new CollisionWorld.WorldData.ParamData();
-
- p.angularDamping = o[0].XangularDamping;
- p.defaultFriction = o[0].defaultFriction;
- p.defaultFriction = o[0].defaultFriction;
- p.defaultDensity = o[0].defaultDensity;
- p.defaultRestitution = o[0].defaultRestitution;
- p.collisionMargin = o[0].collisionMargin;
- p.gravity = o[0].gravity;
-
- p.linearDamping = o[0].XlinearDamping;
- p.angularDamping = o[0].XangularDamping;
- p.deactivationTime = o[0].XdeactivationTime;
- p.linearSleepingThreshold = o[0].XlinearSleepingThreshold;
- p.angularSleepingThreshold = o[0].XangularSleepingThreshold;
- p.ccdMotionThreshold = o[0].XccdMotionThreshold;
- p.ccdSweptSphereRadius = o[0].XccdSweptSphereRadius;
- p.contactProcessingThreshold = o[0].XcontactProcessingThreshold;
-
- p.terrainImplementation = o[0].XterrainImplementation;
- p.terrainFriction = o[0].XterrainFriction;
-
- p.terrainHitFraction = o[0].XterrainHitFraction;
- p.terrainRestitution = o[0].XterrainRestitution;
- p.terrainCollisionMargin = o[0].XterrainCollisionMargin;
-
- p.avatarFriction = o[0].XavatarFriction;
- p.avatarStandingFriction = o[0].XavatarStandingFriction;
- p.avatarDensity = o[0].XavatarDensity;
- p.avatarRestitution = o[0].XavatarRestitution;
- p.avatarCapsuleWidth = o[0].XavatarCapsuleWidth;
- p.avatarCapsuleDepth = o[0].XavatarCapsuleDepth;
- p.avatarCapsuleHeight = o[0].XavatarCapsuleHeight;
- p.avatarContactProcessingThreshold = o[0].XavatarContactProcessingThreshold;
-
- p.vehicleAngularDamping = o[0].XvehicleAngularDamping;
-
- p.maxPersistantManifoldPoolSize = o[0].maxPersistantManifoldPoolSize;
- p.maxCollisionAlgorithmPoolSize = o[0].maxCollisionAlgorithmPoolSize;
- p.shouldDisableContactPoolDynamicAllocation = o[0].shouldDisableContactPoolDynamicAllocation;
- p.shouldForceUpdateAllAabbs = o[0].shouldForceUpdateAllAabbs;
- p.shouldRandomizeSolverOrder = o[0].shouldRandomizeSolverOrder;
- p.shouldSplitSimulationIslands = o[0].shouldSplitSimulationIslands;
- p.shouldEnableFrictionCaching = o[0].shouldEnableFrictionCaching;
- p.numberOfSolverIterations = o[0].numberOfSolverIterations;
-
- p.linksetImplementation = o[0].XlinksetImplementation;
- p.linkConstraintUseFrameOffset = o[0].XlinkConstraintUseFrameOffset;
- p.linkConstraintEnableTransMotor = o[0].XlinkConstraintEnableTransMotor;
- p.linkConstraintTransMotorMaxVel = o[0].XlinkConstraintTransMotorMaxVel;
- p.linkConstraintTransMotorMaxForce = o[0].XlinkConstraintTransMotorMaxForce;
- p.linkConstraintERP = o[0].XlinkConstraintERP;
- p.linkConstraintCFM = o[0].XlinkConstraintCFM;
- p.linkConstraintSolverIterations = o[0].XlinkConstraintSolverIterations;
- p.physicsLoggingFrames = o[0].physicsLoggingFrames;
- DefaultCollisionConstructionInfo ccci = new DefaultCollisionConstructionInfo();
-
- DefaultCollisionConfiguration cci = new DefaultCollisionConfiguration();
- CollisionDispatcher m_dispatcher = new CollisionDispatcher(cci);
-
-
- if (p.maxPersistantManifoldPoolSize > 0)
- cci.m_persistentManifoldPoolSize = (int)p.maxPersistantManifoldPoolSize;
- if (p.shouldDisableContactPoolDynamicAllocation !=0)
- m_dispatcher.SetDispatcherFlags(DispatcherFlags.CD_DISABLE_CONTACTPOOL_DYNAMIC_ALLOCATION);
- //if (p.maxCollisionAlgorithmPoolSize >0 )
-
- DbvtBroadphase m_broadphase = new DbvtBroadphase();
- //IndexedVector3 aabbMin = new IndexedVector3(0, 0, 0);
- //IndexedVector3 aabbMax = new IndexedVector3(256, 256, 256);
-
- //AxisSweep3Internal m_broadphase2 = new AxisSweep3Internal(ref aabbMin, ref aabbMax, Convert.ToInt32(0xfffe), 0xffff, ushort.MaxValue/2, null, true);
- m_broadphase.GetOverlappingPairCache().SetInternalGhostPairCallback(new GhostPairCallback());
-
- SequentialImpulseConstraintSolver m_solver = new SequentialImpulseConstraintSolver();
-
- DiscreteDynamicsWorld world = new DiscreteDynamicsWorld(m_dispatcher, m_broadphase, m_solver, cci);
- world.UpdatedObjects = updateArray;
- world.UpdatedCollisions = collisionArray;
- world.WorldSettings.Params = p;
- world.SetForceUpdateAllAabbs(p.shouldForceUpdateAllAabbs != 0);
- world.GetSolverInfo().m_solverMode = SolverMode.SOLVER_USE_WARMSTARTING | SolverMode.SOLVER_SIMD;
- if (p.shouldRandomizeSolverOrder != 0)
- world.GetSolverInfo().m_solverMode |= SolverMode.SOLVER_RANDMIZE_ORDER;
-
- world.GetSimulationIslandManager().SetSplitIslands(p.shouldSplitSimulationIslands != 0);
- //world.GetDispatchInfo().m_enableSatConvex Not implemented in C# port
-
- if (p.shouldEnableFrictionCaching != 0)
- world.GetSolverInfo().m_solverMode |= SolverMode.SOLVER_ENABLE_FRICTION_DIRECTION_CACHING;
-
- if (p.numberOfSolverIterations > 0)
- world.GetSolverInfo().m_numIterations = (int) p.numberOfSolverIterations;
-
-
- world.GetSolverInfo().m_damping = world.WorldSettings.Params.linearDamping;
- world.GetSolverInfo().m_restitution = world.WorldSettings.Params.defaultRestitution;
- world.GetSolverInfo().m_globalCfm = 0.0f;
- world.GetSolverInfo().m_tau = 0.6f;
- world.GetSolverInfo().m_friction = 0.3f;
- world.GetSolverInfo().m_maxErrorReduction = 20f;
- world.GetSolverInfo().m_numIterations = 10;
- world.GetSolverInfo().m_erp = 0.2f;
- world.GetSolverInfo().m_erp2 = 0.1f;
- world.GetSolverInfo().m_sor = 1.0f;
- world.GetSolverInfo().m_splitImpulse = false;
- world.GetSolverInfo().m_splitImpulsePenetrationThreshold = -0.02f;
- world.GetSolverInfo().m_linearSlop = 0.0f;
- world.GetSolverInfo().m_warmstartingFactor = 0.85f;
- world.GetSolverInfo().m_restingContactRestitutionThreshold = 2;
- world.SetForceUpdateAllAabbs(true);
-
-
- world.SetGravity(new IndexedVector3(0,0,p.gravity));
-
- return world;
- }
- //m_constraint.ptr, ConstraintParams.BT_CONSTRAINT_STOP_CFM, cfm, ConstraintParamAxis.AXIS_ALL
- internal static bool SetConstraintParam2(object pConstraint, ConstraintParams paramIndex, float paramvalue, ConstraintParamAxis axis)
- {
- Generic6DofConstraint constrain = pConstraint as Generic6DofConstraint;
- if (axis == ConstraintParamAxis.AXIS_LINEAR_ALL || axis == ConstraintParamAxis.AXIS_ALL)
- {
- constrain.SetParam((BulletXNA.BulletDynamics.ConstraintParams) (int) paramIndex, paramvalue, 0);
- constrain.SetParam((BulletXNA.BulletDynamics.ConstraintParams) (int) paramIndex, paramvalue, 1);
- constrain.SetParam((BulletXNA.BulletDynamics.ConstraintParams) (int) paramIndex, paramvalue, 2);
- }
- if (axis == ConstraintParamAxis.AXIS_ANGULAR_ALL || axis == ConstraintParamAxis.AXIS_ALL)
- {
- constrain.SetParam((BulletXNA.BulletDynamics.ConstraintParams)(int)paramIndex, paramvalue, 3);
- constrain.SetParam((BulletXNA.BulletDynamics.ConstraintParams)(int)paramIndex, paramvalue, 4);
- constrain.SetParam((BulletXNA.BulletDynamics.ConstraintParams)(int)paramIndex, paramvalue, 5);
- }
- if (axis == ConstraintParamAxis.AXIS_LINEAR_ALL)
- {
- constrain.SetParam((BulletXNA.BulletDynamics.ConstraintParams)(int)paramIndex, paramvalue, (int)axis);
- }
- return true;
- }
-
- internal static bool PushUpdate2(object pCollisionObject)
- {
- bool ret = false;
- RigidBody rb = pCollisionObject as RigidBody;
- if (rb != null)
- {
- SimMotionState sms = rb.GetMotionState() as SimMotionState;
- if (sms != null)
- {
- IndexedMatrix wt = IndexedMatrix.Identity;
- sms.GetWorldTransform(out wt);
- sms.SetWorldTransform(ref wt, true);
- ret = true;
- }
- }
- return ret;
-
- }
-
- internal static bool IsCompound2(object pShape)
- {
- CollisionShape shape = pShape as CollisionShape;
- return shape.IsCompound();
- }
- internal static bool IsPloyhedral2(object pShape)
- {
- CollisionShape shape = pShape as CollisionShape;
- return shape.IsPolyhedral();
- }
- internal static bool IsConvex2d2(object pShape)
- {
- CollisionShape shape = pShape as CollisionShape;
- return shape.IsConvex2d();
- }
- internal static bool IsConvex2(object pShape)
- {
- CollisionShape shape = pShape as CollisionShape;
- return shape.IsConvex();
- }
- internal static bool IsNonMoving2(object pShape)
- {
- CollisionShape shape = pShape as CollisionShape;
- return shape.IsNonMoving();
- }
- internal static bool IsConcave2(object pShape)
- {
- CollisionShape shape = pShape as CollisionShape;
- return shape.IsConcave();
- }
- internal static bool IsInfinite2(object pShape)
- {
- CollisionShape shape = pShape as CollisionShape;
- return shape.IsInfinite();
- }
- internal static bool IsNativeShape2(object pShape)
- {
- CollisionShape shape = pShape as CollisionShape;
- bool ret;
- switch (shape.GetShapeType())
- {
- case BroadphaseNativeTypes.BOX_SHAPE_PROXYTYPE:
- case BroadphaseNativeTypes.CONE_SHAPE_PROXYTYPE:
- case BroadphaseNativeTypes.SPHERE_SHAPE_PROXYTYPE:
- case BroadphaseNativeTypes.CYLINDER_SHAPE_PROXYTYPE:
- ret = true;
- break;
- default:
- ret = false;
- break;
- }
- return ret;
- }
- //sim.ptr, shape.ptr,prim.LocalID, prim.RawPosition, prim.RawOrientation
- internal static object CreateGhostFromShape2(object pWorld, object pShape, uint pLocalID, Vector3 pRawPosition, Quaternion pRawOrientation)
- {
- IndexedMatrix bodyTransform = new IndexedMatrix();
- bodyTransform._origin = new IndexedVector3(pRawPosition.X, pRawPosition.Y, pRawPosition.Z);
- bodyTransform.SetRotation(new IndexedQuaternion(pRawOrientation.X,pRawOrientation.Y,pRawOrientation.Z,pRawOrientation.W));
- GhostObject gObj = new PairCachingGhostObject();
- gObj.SetWorldTransform(bodyTransform);
- CollisionShape shape = pShape as CollisionShape;
- gObj.SetCollisionShape(shape);
- gObj.SetUserPointer(pLocalID);
- // TODO: Add to Special CollisionObjects!
- return gObj;
- }
-
- public static void SetCollisionShape2(object pWorld, object pObj, object pShape)
- {
- var world = pWorld as DiscreteDynamicsWorld;
- var obj = pObj as CollisionObject;
- var shape = pShape as CollisionShape;
- obj.SetCollisionShape(shape);
-
- }
- //(PhysicsScene.World.ptr, nativeShapeData)
- internal static object BuildNativeShape2(object pWorld, ShapeData pShapeData)
- {
- var world = pWorld as DiscreteDynamicsWorld;
- CollisionShape shape = null;
- switch (pShapeData.Type)
- {
- case BSPhysicsShapeType.SHAPE_BOX:
- shape = new BoxShape(new IndexedVector3(0.5f,0.5f,0.5f));
- break;
- case BSPhysicsShapeType.SHAPE_CONE:
- shape = new ConeShapeZ(0.5f, 1.0f);
- break;
- case BSPhysicsShapeType.SHAPE_CYLINDER:
- shape = new CylinderShapeZ(new IndexedVector3(0.5f, 0.5f, 0.5f));
- break;
- case BSPhysicsShapeType.SHAPE_SPHERE:
- shape = new SphereShape(0.5f);
- break;
-
- }
- if (shape != null)
- {
- IndexedVector3 scaling = new IndexedVector3(pShapeData.Scale.X, pShapeData.Scale.Y, pShapeData.Scale.Z);
- shape.SetMargin(world.WorldSettings.Params.collisionMargin);
- shape.SetLocalScaling(ref scaling);
-
- }
- return shape;
- }
- //PhysicsScene.World.ptr, false
- internal static object CreateCompoundShape2(object pWorld, bool enableDynamicAabbTree)
- {
- return new CompoundShape(enableDynamicAabbTree);
- }
-
- internal static int GetNumberOfCompoundChildren2(object pCompoundShape)
- {
- var compoundshape = pCompoundShape as CompoundShape;
- return compoundshape.GetNumChildShapes();
- }
- //LinksetRoot.PhysShape.ptr, newShape.ptr, displacementPos, displacementRot
- internal static void AddChildShapeToCompoundShape2(object pCShape, object paddShape, Vector3 displacementPos, Quaternion displacementRot)
- {
- IndexedMatrix relativeTransform = new IndexedMatrix();
- var compoundshape = pCShape as CompoundShape;
- var addshape = paddShape as CollisionShape;
-
- relativeTransform._origin = new IndexedVector3(displacementPos.X, displacementPos.Y, displacementPos.Z);
- relativeTransform.SetRotation(new IndexedQuaternion(displacementRot.X,displacementRot.Y,displacementRot.Z,displacementRot.W));
- compoundshape.AddChildShape(ref relativeTransform, addshape);
-
- }
-
- internal static object RemoveChildShapeFromCompoundShapeIndex2(object pCShape, int pii)
- {
- var compoundshape = pCShape as CompoundShape;
- CollisionShape ret = null;
- ret = compoundshape.GetChildShape(pii);
- compoundshape.RemoveChildShapeByIndex(pii);
- return ret;
- }
-
- internal static object CreateGroundPlaneShape2(uint pLocalId, float pheight, float pcollisionMargin)
- {
- StaticPlaneShape m_planeshape = new StaticPlaneShape(new IndexedVector3(0,0,1),(int)pheight );
- m_planeshape.SetMargin(pcollisionMargin);
- m_planeshape.SetUserPointer(pLocalId);
- return m_planeshape;
- }
-
- internal static object CreateHingeConstraint2(object pWorld, object pBody1, object ppBody2, Vector3 ppivotInA, Vector3 ppivotInB, Vector3 paxisInA, Vector3 paxisInB, bool puseLinearReferenceFrameA, bool pdisableCollisionsBetweenLinkedBodies)
- {
- HingeConstraint constrain = null;
- var rb1 = pBody1 as RigidBody;
- var rb2 = ppBody2 as RigidBody;
- if (rb1 != null && rb2 != null)
- {
- IndexedVector3 pivotInA = new IndexedVector3(ppivotInA.X, ppivotInA.Y, ppivotInA.Z);
- IndexedVector3 pivotInB = new IndexedVector3(ppivotInB.X, ppivotInB.Y, ppivotInB.Z);
- IndexedVector3 axisInA = new IndexedVector3(paxisInA.X, paxisInA.Y, paxisInA.Z);
- IndexedVector3 axisInB = new IndexedVector3(paxisInB.X, paxisInB.Y, paxisInB.Z);
- var world = pWorld as DiscreteDynamicsWorld;
- world.AddConstraint(constrain, pdisableCollisionsBetweenLinkedBodies);
- }
- return constrain;
- }
-
- internal static bool ReleaseHeightMapInfo2(object pMapInfo)
- {
- if (pMapInfo != null)
- {
- BulletHeightMapInfo mapinfo = pMapInfo as BulletHeightMapInfo;
- if (mapinfo.heightMap != null)
- mapinfo.heightMap = null;
-
-
- }
- return true;
- }
-
- internal static object CreateHullShape2(object pWorld, int pHullCount, float[] pConvHulls)
- {
- CompoundShape compoundshape = new CompoundShape(false);
- var world = pWorld as DiscreteDynamicsWorld;
-
-
- compoundshape.SetMargin(world.WorldSettings.Params.collisionMargin);
- int ii = 1;
-
- for (int i = 0; i < pHullCount; i++)
- {
- int vertexCount = (int) pConvHulls[ii];
-
- IndexedVector3 centroid = new IndexedVector3(pConvHulls[ii + 1], pConvHulls[ii + 2], pConvHulls[ii + 3]);
- IndexedMatrix childTrans = IndexedMatrix.Identity;
- childTrans._origin = centroid;
-
- List virts = new List();
- int ender = ((ii + 4) + (vertexCount*3));
- for (int iii = ii + 4; iii < ender; iii+=3)
- {
-
- virts.Add(new IndexedVector3(pConvHulls[iii], pConvHulls[iii + 1], pConvHulls[iii +2]));
- }
- ConvexHullShape convexShape = new ConvexHullShape(virts, vertexCount);
- convexShape.SetMargin(world.WorldSettings.Params.collisionMargin);
- compoundshape.AddChildShape(ref childTrans, convexShape);
- ii += (vertexCount*3 + 4);
- }
-
-
- return compoundshape;
- }
-
- internal static object CreateMeshShape2(object pWorld, int pIndicesCount, int[] indices, int pVerticesCount, float[] verticesAsFloats)
- {
- //DumpRaw(indices,verticesAsFloats,pIndicesCount,pVerticesCount);
-
- for (int iter = 0; iter < pVerticesCount; iter++)
- {
- if (verticesAsFloats[iter] > 0 && verticesAsFloats[iter] < 0.0001) verticesAsFloats[iter] = 0;
- if (verticesAsFloats[iter] < 0 && verticesAsFloats[iter] > -0.0001) verticesAsFloats[iter] = 0;
- }
-
- ObjectArray indicesarr = new ObjectArray(indices);
- ObjectArray vertices = new ObjectArray(verticesAsFloats);
- DumpRaw(indicesarr,vertices,pIndicesCount,pVerticesCount);
- var world = pWorld as DiscreteDynamicsWorld;
- IndexedMesh mesh = new IndexedMesh();
- mesh.m_indexType = PHY_ScalarType.PHY_INTEGER;
- mesh.m_numTriangles = pIndicesCount/3;
- mesh.m_numVertices = pVerticesCount;
- mesh.m_triangleIndexBase = indicesarr;
- mesh.m_vertexBase = vertices;
- mesh.m_vertexStride = 3;
- mesh.m_vertexType = PHY_ScalarType.PHY_FLOAT;
- mesh.m_triangleIndexStride = 3;
-
- TriangleIndexVertexArray tribuilder = new TriangleIndexVertexArray();
- tribuilder.AddIndexedMesh(mesh, PHY_ScalarType.PHY_INTEGER);
- BvhTriangleMeshShape meshShape = new BvhTriangleMeshShape(tribuilder, true,true);
- meshShape.SetMargin(world.WorldSettings.Params.collisionMargin);
- // world.UpdateSingleAabb(meshShape);
- return meshShape;
-
- }
- public static void DumpRaw(ObjectArrayindices, ObjectArray vertices, int pIndicesCount,int pVerticesCount )
- {
-
- String fileName = "objTest3.raw";
- String completePath = System.IO.Path.Combine(Util.configDir(), fileName);
- StreamWriter sw = new StreamWriter(completePath);
- IndexedMesh mesh = new IndexedMesh();
-
- mesh.m_indexType = PHY_ScalarType.PHY_INTEGER;
- mesh.m_numTriangles = pIndicesCount / 3;
- mesh.m_numVertices = pVerticesCount;
- mesh.m_triangleIndexBase = indices;
- mesh.m_vertexBase = vertices;
- mesh.m_vertexStride = 3;
- mesh.m_vertexType = PHY_ScalarType.PHY_FLOAT;
- mesh.m_triangleIndexStride = 3;
-
- TriangleIndexVertexArray tribuilder = new TriangleIndexVertexArray();
- tribuilder.AddIndexedMesh(mesh, PHY_ScalarType.PHY_INTEGER);
-
-
-
- for (int i = 0; i < pVerticesCount; i++)
- {
-
- string s = vertices[indices[i * 3]].ToString("0.0000");
- s += " " + vertices[indices[i * 3 + 1]].ToString("0.0000");
- s += " " + vertices[indices[i * 3 + 2]].ToString("0.0000");
-
- sw.Write(s + "\n");
- }
-
- sw.Close();
- }
- public static void DumpRaw(int[] indices, float[] vertices, int pIndicesCount, int pVerticesCount)
- {
-
- String fileName = "objTest6.raw";
- String completePath = System.IO.Path.Combine(Util.configDir(), fileName);
- StreamWriter sw = new StreamWriter(completePath);
- IndexedMesh mesh = new IndexedMesh();
-
- mesh.m_indexType = PHY_ScalarType.PHY_INTEGER;
- mesh.m_numTriangles = pIndicesCount / 3;
- mesh.m_numVertices = pVerticesCount;
- mesh.m_triangleIndexBase = indices;
- mesh.m_vertexBase = vertices;
- mesh.m_vertexStride = 3;
- mesh.m_vertexType = PHY_ScalarType.PHY_FLOAT;
- mesh.m_triangleIndexStride = 3;
-
- TriangleIndexVertexArray tribuilder = new TriangleIndexVertexArray();
- tribuilder.AddIndexedMesh(mesh, PHY_ScalarType.PHY_INTEGER);
-
-
- sw.WriteLine("Indices");
- sw.WriteLine(string.Format("int[] indices = new int[{0}];",pIndicesCount));
- for (int iter = 0; iter < indices.Length; iter++)
- {
- sw.WriteLine(string.Format("indices[{0}]={1};",iter,indices[iter]));
- }
- sw.WriteLine("VerticesFloats");
- sw.WriteLine(string.Format("float[] vertices = new float[{0}];", pVerticesCount));
- for (int iter = 0; iter < vertices.Length; iter++)
- {
- sw.WriteLine(string.Format("Vertices[{0}]={1};", iter, vertices[iter].ToString("0.0000")));
- }
-
- // for (int i = 0; i < pVerticesCount; i++)
- // {
- //
- // string s = vertices[indices[i * 3]].ToString("0.0000");
- // s += " " + vertices[indices[i * 3 + 1]].ToString("0.0000");
- // s += " " + vertices[indices[i * 3 + 2]].ToString("0.0000");
- //
- // sw.Write(s + "\n");
- //}
-
- sw.Close();
- }
- //PhysicsScene.World.ptr, m_mapInfo.ID, m_mapInfo.minCoords, m_mapInfo.maxCoords, m_mapInfo.heightMap, PhysicsScene.Params.terrainCollisionMargin
- internal static object CreateHeightMapInfo2(object pWorld, uint pId, Vector3 pminCoords, Vector3 pmaxCoords, float[] pheightMap, float pCollisionMargin)
- {
- BulletHeightMapInfo mapInfo = new BulletHeightMapInfo(pId, pheightMap, null);
- mapInfo.heightMap = null;
- mapInfo.minCoords = pminCoords;
- mapInfo.maxCoords = pmaxCoords;
- mapInfo.sizeX = (int) (pmaxCoords.X - pminCoords.X);
- mapInfo.sizeY = (int) (pmaxCoords.Y - pminCoords.Y);
- mapInfo.ID = pId;
- mapInfo.minZ = pminCoords.Z;
- mapInfo.maxZ = pmaxCoords.Z;
- mapInfo.collisionMargin = pCollisionMargin;
- if (mapInfo.minZ == mapInfo.maxZ)
- mapInfo.minZ -= 0.2f;
- mapInfo.heightMap = pheightMap;
-
- return mapInfo;
-
- }
-
- internal static object CreateTerrainShape2(object pMapInfo)
- {
- BulletHeightMapInfo mapinfo = pMapInfo as BulletHeightMapInfo;
- const int upAxis = 2;
- const float scaleFactor = 1.0f;
- HeightfieldTerrainShape terrainShape = new HeightfieldTerrainShape((int)mapinfo.sizeX, (int)mapinfo.sizeY,
- mapinfo.heightMap, scaleFactor,
- mapinfo.minZ, mapinfo.maxZ, upAxis,
- false);
- terrainShape.SetMargin(mapinfo.collisionMargin + 0.5f);
- terrainShape.SetUseDiamondSubdivision(true);
- terrainShape.SetUserPointer(mapinfo.ID);
- return terrainShape;
- }
-
- internal static bool TranslationalLimitMotor2(object pConstraint, float ponOff, float targetVelocity, float maxMotorForce)
- {
- TypedConstraint tconstrain = pConstraint as TypedConstraint;
- bool onOff = ponOff != 0;
- bool ret = false;
-
- switch (tconstrain.GetConstraintType())
- {
- case TypedConstraintType.D6_CONSTRAINT_TYPE:
- Generic6DofConstraint constrain = pConstraint as Generic6DofConstraint;
- constrain.GetTranslationalLimitMotor().m_enableMotor[0] = onOff;
- constrain.GetTranslationalLimitMotor().m_targetVelocity[0] = targetVelocity;
- constrain.GetTranslationalLimitMotor().m_maxMotorForce[0] = maxMotorForce;
- ret = true;
- break;
- }
-
-
- return ret;
-
- }
-
- internal static int PhysicsStep2(object pWorld, float timeStep, int m_maxSubSteps, float m_fixedTimeStep, out int updatedEntityCount, out List updatedEntities, out int collidersCount, out Listcolliders)
- {
- int epic = PhysicsStepint2(pWorld, timeStep, m_maxSubSteps, m_fixedTimeStep, out updatedEntityCount, out updatedEntities,
- out collidersCount, out colliders);
- return epic;
- }
-
- private static int PhysicsStepint2(object pWorld,float timeStep, int m_maxSubSteps, float m_fixedTimeStep, out int updatedEntityCount, out List updatedEntities, out int collidersCount, out List colliders)
- {
- int numSimSteps = 0;
-
-
- //if (updatedEntities is null)
- // updatedEntities = new List();
-
- //if (colliders is null)
- // colliders = new List();
-
-
- if (pWorld is DiscreteDynamicsWorld)
- {
- DiscreteDynamicsWorld world = pWorld as DiscreteDynamicsWorld;
-
- numSimSteps = world.StepSimulation(timeStep, m_maxSubSteps, m_fixedTimeStep);
- int updates = 0;
-
- updatedEntityCount = world.UpdatedObjects.Count;
- updatedEntities = new List(world.UpdatedObjects);
- updatedEntityCount = updatedEntities.Count;
- world.UpdatedObjects.Clear();
-
-
- collidersCount = world.UpdatedCollisions.Count;
- colliders = new List(world.UpdatedCollisions);
-
- world.UpdatedCollisions.Clear();
- m_collisionsThisFrame = 0;
- int numManifolds = world.GetDispatcher().GetNumManifolds();
- for (int j = 0; j < numManifolds; j++)
- {
- PersistentManifold contactManifold = world.GetDispatcher().GetManifoldByIndexInternal(j);
- int numContacts = contactManifold.GetNumContacts();
- if (numContacts == 0)
- continue;
-
- CollisionObject objA = contactManifold.GetBody0() as CollisionObject;
- CollisionObject objB = contactManifold.GetBody1() as CollisionObject;
-
- ManifoldPoint manifoldPoint = contactManifold.GetContactPoint(0);
- IndexedVector3 contactPoint = manifoldPoint.GetPositionWorldOnB();
- IndexedVector3 contactNormal = -manifoldPoint.m_normalWorldOnB; // make relative to A
-
- RecordCollision(world, objA, objB, contactPoint, contactNormal);
- m_collisionsThisFrame ++;
- if (m_collisionsThisFrame >= 9999999)
- break;
-
-
- }
-
-
- }
- else
- {
- //if (updatedEntities is null)
- updatedEntities = new List();
- updatedEntityCount = 0;
- //if (colliders is null)
- colliders = new List();
- collidersCount = 0;
- }
- return numSimSteps;
- }
-
- private static void RecordCollision(CollisionWorld world,CollisionObject objA, CollisionObject objB, IndexedVector3 contact, IndexedVector3 norm)
- {
-
- IndexedVector3 contactNormal = norm;
- if ((objA.GetCollisionFlags() & BulletXNA.BulletCollision.CollisionFlags.BS_WANTS_COLLISIONS) == 0 &&
- (objB.GetCollisionFlags() & BulletXNA.BulletCollision.CollisionFlags.BS_WANTS_COLLISIONS) == 0)
- {
- return;
- }
- uint idA = (uint)objA.GetUserPointer();
- uint idB = (uint)objB.GetUserPointer();
- if (idA > idB)
- {
- uint temp = idA;
- idA = idB;
- idB = temp;
- contactNormal = -contactNormal;
- }
-
- ulong collisionID = ((ulong) idA << 32) | idB;
-
- BulletXNA.CollisionDesc cDesc = new BulletXNA.CollisionDesc()
- {
- aID = idA,
- bID = idB,
- point = contact,
- normal = contactNormal
- };
- world.UpdatedCollisions.Add(cDesc);
- m_collisionsThisFrame++;
-
-
- }
- private static EntityProperties GetDebugProperties(object pWorld, object pBody)
- {
- EntityProperties ent = new EntityProperties();
- DiscreteDynamicsWorld world = pWorld as DiscreteDynamicsWorld;
- RigidBody body = pBody as RigidBody;
- IndexedMatrix transform = body.GetWorldTransform();
- IndexedVector3 LinearVelocity = body.GetInterpolationLinearVelocity();
- IndexedVector3 AngularVelocity = body.GetInterpolationAngularVelocity();
- IndexedQuaternion rotation = transform.GetRotation();
- ent.Acceleration = Vector3.Zero;
- ent.ID = (uint)body.GetUserPointer();
- ent.Position = new Vector3(transform._origin.X,transform._origin.Y,transform._origin.Z);
- ent.Rotation = new Quaternion(rotation.X,rotation.Y,rotation.Z,rotation.W);
- ent.Velocity = new Vector3(LinearVelocity.X, LinearVelocity.Y, LinearVelocity.Z);
- ent.RotationalVelocity = new Vector3(AngularVelocity.X, AngularVelocity.Y, AngularVelocity.Z);
- return ent;
-
-
- }
-
-
- internal static Vector3 GetLocalScaling2(object pBody)
- {
- CollisionShape shape = pBody as CollisionShape;
- IndexedVector3 scale = shape.GetLocalScaling();
- return new Vector3(scale.X,scale.Y,scale.Z);
- }
-
- internal static bool RayCastGround(object pWorld, Vector3 _RayOrigin, float pRayHeight, object NotMe)
- {
- DynamicsWorld world = pWorld as DynamicsWorld;
- if (world != null)
- {
- if (NotMe is CollisionObject || NotMe is RigidBody)
- {
- CollisionObject AvoidBody = NotMe as CollisionObject;
-
- IndexedVector3 rOrigin = new IndexedVector3(_RayOrigin.X, _RayOrigin.Y, _RayOrigin.Z);
- IndexedVector3 rEnd = new IndexedVector3(_RayOrigin.X, _RayOrigin.Y, _RayOrigin.Z - pRayHeight);
- using (
- ClosestNotMeRayResultCallback rayCallback = new ClosestNotMeRayResultCallback(rOrigin,
- rEnd, AvoidBody)
- )
- {
- world.RayTest(ref rOrigin, ref rEnd, rayCallback);
- if (rayCallback.HasHit())
- {
- IndexedVector3 hitLocation = rayCallback.m_hitPointWorld;
-
- }
- return rayCallback.HasHit();
- }
- }
- }
- return false;
- }
-}
-}
diff --git a/OpenSim/Region/Physics/BulletSNPlugin/BulletSimData.cs b/OpenSim/Region/Physics/BulletSNPlugin/BulletSimData.cs
deleted file mode 100644
index f509dc4092..0000000000
--- a/OpenSim/Region/Physics/BulletSNPlugin/BulletSimData.cs
+++ /dev/null
@@ -1,280 +0,0 @@
-/*
- * Copyright (c) Contributors, http://opensimulator.org/
- * See CONTRIBUTORS.TXT for a full list of copyright holders.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyrightD
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * * Neither the name of the OpenSimulator Project nor the
- * names of its contributors may be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-using System;
-using System.Collections.Generic;
-using System.Text;
-using OMV = OpenMetaverse;
-
-namespace OpenSim.Region.Physics.BulletSNPlugin
-{
-// Classes to allow some type checking for the API
-// These hold pointers to allocated objects in the unmanaged space.
-
-// The physics engine controller class created at initialization
-public struct BulletWorld
-{
- public BulletWorld(uint worldId, BSScene bss, object xx)
- {
- ptr = xx;
- worldID = worldId;
- physicsScene = bss;
- }
- public object ptr;
- public uint worldID;
- // The scene is only in here so very low level routines have a handle to print debug/error messages
- public BSScene physicsScene;
-}
-
-// An allocated Bullet btRigidBody
-public struct BulletBody
-{
- public BulletBody(uint id) : this(id, null)
- {
- }
- public BulletBody(uint id, object xx)
- {
- ID = id;
- ptr = xx;
- collisionType = CollisionType.Static;
- }
- public object ptr;
- public uint ID;
- public CollisionType collisionType;
-
- public void Clear()
- {
- ptr = null;
- }
- public bool HasPhysicalBody { get { return ptr != null; } }
-
- // Apply the specificed collision mask into the physical world
- public void ApplyCollisionMask()
- {
- // Should assert the body has been added to the physical world.
- // (The collision masks are stored in the collision proxy cache which only exists for
- // a collision body that is in the world.)
- BulletSimAPI.SetCollisionGroupMask2(ptr,
- BulletSimData.CollisionTypeMasks[collisionType].group,
- BulletSimData.CollisionTypeMasks[collisionType].mask);
- }
-
- public override string ToString()
- {
- StringBuilder buff = new StringBuilder();
- buff.Append("");
- return buff.ToString();
- }
-}
-
-public struct BulletShape
-{
- public BulletShape(object xx) : this(xx, BSPhysicsShapeType.SHAPE_UNKNOWN)
- {
- }
- public BulletShape(object xx, BSPhysicsShapeType typ)
- {
- ptr = xx;
- type = typ;
- shapeKey = (System.UInt64)FixedShapeKey.KEY_NONE;
- isNativeShape = false;
- }
- public object ptr;
- public BSPhysicsShapeType type;
- public System.UInt64 shapeKey;
- public bool isNativeShape;
-
- public void Clear()
- {
- ptr = null;
- }
- public bool HasPhysicalShape { get { return ptr != null; } }
-
- public override string ToString()
- {
- StringBuilder buff = new StringBuilder();
- buff.Append("");
- return buff.ToString();
- }
-}
-
-// An allocated Bullet btConstraint
-public struct BulletConstraint
-{
- public BulletConstraint(object xx)
- {
- ptr = xx;
- }
- public object ptr;
-
- public void Clear()
- {
- ptr = null;
- }
- public bool HasPhysicalConstraint { get { return ptr != null; } }
-}
-
-// An allocated HeightMapThing which holds various heightmap info.
-// Made a class rather than a struct so there would be only one
-// instance of this and C# will pass around pointers rather
-// than making copies.
-public class BulletHeightMapInfo
-{
- public BulletHeightMapInfo(uint id, float[] hm, object xx) {
- ID = id;
- Ptr = xx;
- heightMap = hm;
- terrainRegionBase = OMV.Vector3.Zero;
- minCoords = new OMV.Vector3(100f, 100f, 25f);
- maxCoords = new OMV.Vector3(101f, 101f, 26f);
- minZ = maxZ = 0f;
- sizeX = sizeY = 256f;
- }
- public uint ID;
- public object Ptr;
- public float[] heightMap;
- public OMV.Vector3 terrainRegionBase;
- public OMV.Vector3 minCoords;
- public OMV.Vector3 maxCoords;
- public float sizeX, sizeY;
- public float minZ, maxZ;
- public BulletShape terrainShape;
- public BulletBody terrainBody;
-
- public float collisionMargin { get; set; }
-}
-
-// The general class of collsion object.
-public enum CollisionType
-{
- Avatar,
- Groundplane,
- Terrain,
- Static,
- Dynamic,
- VolumeDetect,
- // Linkset, // A linkset should be either Static or Dynamic
- LinksetChild,
- Unknown
-};
-
-// Hold specification of group and mask collision flags for a CollisionType
-public struct CollisionTypeFilterGroup
-{
- public CollisionTypeFilterGroup(CollisionType t, uint g, uint m)
- {
- type = t;
- group = g;
- mask = m;
- }
- public CollisionType type;
- public uint group;
- public uint mask;
-};
-
- /* NOTE: old definitions kept for reference. Delete when things are working.
- // The collsion filters and masked are defined in one place -- don't want them scattered
- AvatarGroup = BCharacterGroup,
- AvatarMask = BAllGroup,
- ObjectGroup = BSolidGroup,
- ObjectMask = BAllGroup,
- StaticObjectGroup = BStaticGroup,
- StaticObjectMask = AvatarGroup | ObjectGroup, // static things don't interact with much
- LinksetGroup = BLinksetGroup,
- LinksetMask = BAllGroup,
- LinksetChildGroup = BLinksetChildGroup,
- LinksetChildMask = BNoneGroup, // Linkset children disappear from the world
- VolumeDetectGroup = BSensorTrigger,
- VolumeDetectMask = ~BSensorTrigger,
- TerrainGroup = BTerrainGroup,
- TerrainMask = BAllGroup & ~BStaticGroup, // static objects on the ground don't collide
- GroundPlaneGroup = BGroundPlaneGroup,
- GroundPlaneMask = BAllGroup
- */
-
-public static class BulletSimData
-{
-
-// Map of collisionTypes to flags for collision groups and masks.
-// As mentioned above, don't use the CollisionFilterGroups definitions directly in the code
-// but, instead, use references to this dictionary. Finding and debugging
-// collision flag problems will be made easier.
-public static Dictionary CollisionTypeMasks
- = new Dictionary()
-{
- { CollisionType.Avatar,
- new CollisionTypeFilterGroup(CollisionType.Avatar,
- (uint)CollisionFilterGroups.BCharacterGroup,
- (uint)CollisionFilterGroups.BAllGroup)
- },
- { CollisionType.Groundplane,
- new CollisionTypeFilterGroup(CollisionType.Groundplane,
- (uint)CollisionFilterGroups.BGroundPlaneGroup,
- (uint)CollisionFilterGroups.BAllGroup)
- },
- { CollisionType.Terrain,
- new CollisionTypeFilterGroup(CollisionType.Terrain,
- (uint)CollisionFilterGroups.BTerrainGroup,
- (uint)(CollisionFilterGroups.BAllGroup & ~CollisionFilterGroups.BStaticGroup))
- },
- { CollisionType.Static,
- new CollisionTypeFilterGroup(CollisionType.Static,
- (uint)CollisionFilterGroups.BStaticGroup,
- (uint)(CollisionFilterGroups.BCharacterGroup | CollisionFilterGroups.BSolidGroup))
- },
- { CollisionType.Dynamic,
- new CollisionTypeFilterGroup(CollisionType.Dynamic,
- (uint)CollisionFilterGroups.BSolidGroup,
- (uint)(CollisionFilterGroups.BAllGroup))
- },
- { CollisionType.VolumeDetect,
- new CollisionTypeFilterGroup(CollisionType.VolumeDetect,
- (uint)CollisionFilterGroups.BSensorTrigger,
- (uint)(~CollisionFilterGroups.BSensorTrigger))
- },
- { CollisionType.LinksetChild,
- new CollisionTypeFilterGroup(CollisionType.LinksetChild,
- (uint)CollisionFilterGroups.BTerrainGroup,
- (uint)(CollisionFilterGroups.BNoneGroup))
- },
-};
-
-}
-}
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs b/OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs
index b6ff52bf5b..49b17305df 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs
@@ -129,7 +129,12 @@ private sealed class BulletConstraintXNA : BulletConstraint
get { return "XNAConstraint"; }
}
}
+ internal int m_maxCollisions;
+ internal CollisionDesc[] m_collisionArray;
+ internal int m_maxUpdatesPerFrame;
+ internal EntityProperties[] m_updateArray;
+
private static int m_collisionsThisFrame;
private BSScene PhysicsScene { get; set; }
@@ -148,92 +153,98 @@ private sealed class BulletConstraintXNA : BulletConstraint
///
public override bool RemoveObjectFromWorld(BulletWorld pWorld, BulletBody pBody)
{
- DiscreteDynamicsWorld world = ((BulletWorldXNA)pWorld).world;
+ DiscreteDynamicsWorld world = (pWorld as BulletWorldXNA).world;
RigidBody body = ((BulletBodyXNA)pBody).rigidBody;
world.RemoveRigidBody(body);
return true;
}
- public override bool AddConstraintToWorld(BulletWorld world, BulletConstraint constrain, bool disableCollisionsBetweenLinkedObjects)
+ public override bool AddConstraintToWorld(BulletWorld pWorld, BulletConstraint pConstraint, bool pDisableCollisionsBetweenLinkedObjects)
{
- /* TODO */
- return false;
+ DiscreteDynamicsWorld world = (pWorld as BulletWorldXNA).world;
+ TypedConstraint constraint = (pConstraint as BulletConstraintXNA).constrain;
+ world.AddConstraint(constraint, pDisableCollisionsBetweenLinkedObjects);
+
+ return true;
+
}
- public override bool RemoveConstraintFromWorld(BulletWorld world, BulletConstraint constrain)
+ public override bool RemoveConstraintFromWorld(BulletWorld pWorld, BulletConstraint pConstraint)
{
- /* TODO */
- return false;
+ DiscreteDynamicsWorld world = (pWorld as BulletWorldXNA).world;
+ TypedConstraint constraint = (pConstraint as BulletConstraintXNA).constrain;
+ world.RemoveConstraint(constraint);
+ return true;
}
- public override void SetRestitution(BulletBody pBody, float pRestitution)
+ public override void SetRestitution(BulletBody pCollisionObject, float pRestitution)
{
- RigidBody body = ((BulletBodyXNA)pBody).rigidBody;
- body.SetRestitution(pRestitution);
+ CollisionObject collisionObject = (pCollisionObject as BulletBodyXNA).rigidBody;
+ collisionObject.SetRestitution(pRestitution);
}
public override int GetShapeType(BulletShape pShape)
{
- CollisionShape shape = ((BulletShapeXNA)pShape).shape;
+ CollisionShape shape = (pShape as BulletShapeXNA).shape;
return (int)shape.GetShapeType();
}
public override void SetMargin(BulletShape pShape, float pMargin)
{
- CollisionShape shape = ((BulletShapeXNA)pShape).shape;
+ CollisionShape shape = (pShape as BulletShapeXNA).shape;
shape.SetMargin(pMargin);
}
public override float GetMargin(BulletShape pShape)
{
- CollisionShape shape = ((BulletShapeXNA)pShape).shape;
+ CollisionShape shape = (pShape as BulletShapeXNA).shape;
return shape.GetMargin();
}
public override void SetLocalScaling(BulletShape pShape, Vector3 pScale)
{
- CollisionShape shape = ((BulletShapeXNA)pShape).shape;
+ CollisionShape shape = (pShape as BulletShapeXNA).shape;
IndexedVector3 vec = new IndexedVector3(pScale.X, pScale.Y, pScale.Z);
shape.SetLocalScaling(ref vec);
}
- public override void SetContactProcessingThreshold(BulletBody pBody, float contactprocessingthreshold)
+ public override void SetContactProcessingThreshold(BulletBody pCollisionObject, float contactprocessingthreshold)
{
- RigidBody body = ((BulletBodyXNA)pBody).rigidBody;
- body.SetContactProcessingThreshold(contactprocessingthreshold);
+ CollisionObject collisionObject = (pCollisionObject as BulletBodyXNA).rigidBody;
+ collisionObject.SetContactProcessingThreshold(contactprocessingthreshold);
}
- public override void SetCcdMotionThreshold(BulletBody pBody, float pccdMotionThreashold)
+ public override void SetCcdMotionThreshold(BulletBody pCollisionObject, float pccdMotionThreashold)
{
- RigidBody body = ((BulletBodyXNA)pBody).rigidBody;
- body.SetCcdMotionThreshold(pccdMotionThreashold);
+ CollisionObject collisionObject = (pCollisionObject as BulletBodyXNA).rigidBody;
+ collisionObject.SetCcdMotionThreshold(pccdMotionThreashold);
}
- public override void SetCcdSweptSphereRadius(BulletBody pBody, float pCcdSweptSphereRadius)
+ public override void SetCcdSweptSphereRadius(BulletBody pCollisionObject, float pCcdSweptSphereRadius)
{
- RigidBody body = ((BulletBodyXNA)pBody).rigidBody;
- body.SetCcdSweptSphereRadius(pCcdSweptSphereRadius);
+ CollisionObject collisionObject = (pCollisionObject as BulletBodyXNA).rigidBody;
+ collisionObject.SetCcdSweptSphereRadius(pCcdSweptSphereRadius);
}
public override void SetAngularFactorV(BulletBody pBody, Vector3 pAngularFactor)
{
- RigidBody body = ((BulletBodyXNA)pBody).rigidBody;
+ RigidBody body = (pBody as BulletBodyXNA).rigidBody;
body.SetAngularFactor(new IndexedVector3(pAngularFactor.X, pAngularFactor.Y, pAngularFactor.Z));
}
- public override CollisionFlags AddToCollisionFlags(BulletBody pBody, CollisionFlags pcollisionFlags)
+ public override CollisionFlags AddToCollisionFlags(BulletBody pCollisionObject, CollisionFlags pcollisionFlags)
{
- CollisionObject body = ((BulletBodyXNA)pBody).body;
- CollisionFlags existingcollisionFlags = (CollisionFlags)(uint)body.GetCollisionFlags();
+ CollisionObject collisionObject = (pCollisionObject as BulletBodyXNA).body;
+ CollisionFlags existingcollisionFlags = (CollisionFlags)(uint)collisionObject.GetCollisionFlags();
existingcollisionFlags |= pcollisionFlags;
- body.SetCollisionFlags((BulletXNA.BulletCollision.CollisionFlags)(uint)existingcollisionFlags);
+ collisionObject.SetCollisionFlags((BulletXNA.BulletCollision.CollisionFlags)(uint)existingcollisionFlags);
return (CollisionFlags) (uint) existingcollisionFlags;
}
public override bool AddObjectToWorld(BulletWorld pWorld, BulletBody pBody)
{
- DiscreteDynamicsWorld world = ((BulletWorldXNA)pWorld).world;
- CollisionObject cbody = ((BulletBodyXNA)pBody).body;
+ DiscreteDynamicsWorld world = (pWorld as BulletWorldXNA).world;
+ CollisionObject cbody = (pBody as BulletBodyXNA).body;
RigidBody rbody = cbody as RigidBody;
// Bullet resets several variables when an object is added to the world. In particular,
@@ -259,99 +270,110 @@ private sealed class BulletConstraintXNA : BulletConstraint
return true;
}
- public override void ForceActivationState(BulletBody pBody, ActivationState pActivationState)
+ public override void ForceActivationState(BulletBody pCollisionObject, ActivationState pActivationState)
{
- CollisionObject body = ((BulletBodyXNA)pBody).body;
- body.ForceActivationState((BulletXNA.BulletCollision.ActivationState)(uint)pActivationState);
+ CollisionObject collisionObject = (pCollisionObject as BulletBodyXNA).body;
+ collisionObject.ForceActivationState((BulletXNA.BulletCollision.ActivationState)(uint)pActivationState);
}
- public override void UpdateSingleAabb(BulletWorld pWorld, BulletBody pBody)
+ public override void UpdateSingleAabb(BulletWorld pWorld, BulletBody pCollisionObject)
{
- DiscreteDynamicsWorld world = ((BulletWorldXNA)pWorld).world;
- CollisionObject body = ((BulletBodyXNA)pBody).body;
- world.UpdateSingleAabb(body);
+ DiscreteDynamicsWorld world = (pWorld as BulletWorldXNA).world;
+ CollisionObject collisionObject = (pCollisionObject as BulletBodyXNA).body;
+ world.UpdateSingleAabb(collisionObject);
}
- public override void UpdateAabbs(BulletWorld world) { /* TODO */ }
- public override bool GetForceUpdateAllAabbs(BulletWorld world) { /* TODO */ return false; }
- public override void SetForceUpdateAllAabbs(BulletWorld world, bool force) { /* TODO */ }
-
- public override bool SetCollisionGroupMask(BulletBody pBody, uint pGroup, uint pMask)
+ public override void UpdateAabbs(BulletWorld pWorld) {
+ DiscreteDynamicsWorld world = (pWorld as BulletWorldXNA).world;
+ world.UpdateAabbs();
+ }
+ public override bool GetForceUpdateAllAabbs(BulletWorld pWorld) {
+ DiscreteDynamicsWorld world = (pWorld as BulletWorldXNA).world;
+ return world.GetForceUpdateAllAabbs();
+
+ }
+ public override void SetForceUpdateAllAabbs(BulletWorld pWorld, bool pForce)
{
- RigidBody body = ((BulletBodyXNA)pBody).rigidBody;
- body.GetBroadphaseHandle().m_collisionFilterGroup = (BulletXNA.BulletCollision.CollisionFilterGroups) pGroup;
- body.GetBroadphaseHandle().m_collisionFilterGroup = (BulletXNA.BulletCollision.CollisionFilterGroups) pGroup;
- if ((uint) body.GetBroadphaseHandle().m_collisionFilterGroup == 0)
+ DiscreteDynamicsWorld world = (pWorld as BulletWorldXNA).world;
+ world.SetForceUpdateAllAabbs(pForce);
+ }
+
+ public override bool SetCollisionGroupMask(BulletBody pCollisionObject, uint pGroup, uint pMask)
+ {
+ CollisionObject collisionObject = (pCollisionObject as BulletBodyXNA).rigidBody;
+ collisionObject.GetBroadphaseHandle().m_collisionFilterGroup = (BulletXNA.BulletCollision.CollisionFilterGroups) pGroup;
+ collisionObject.GetBroadphaseHandle().m_collisionFilterGroup = (BulletXNA.BulletCollision.CollisionFilterGroups) pGroup;
+ if ((uint) collisionObject.GetBroadphaseHandle().m_collisionFilterGroup == 0)
return false;
return true;
}
- public override void ClearAllForces(BulletBody pBody)
+ public override void ClearAllForces(BulletBody pCollisionObject)
{
- CollisionObject body = ((BulletBodyXNA)pBody).body;
+ CollisionObject collisionObject = (pCollisionObject as BulletBodyXNA).body;
IndexedVector3 zeroVector = new IndexedVector3(0, 0, 0);
- body.SetInterpolationLinearVelocity(ref zeroVector);
- body.SetInterpolationAngularVelocity(ref zeroVector);
- IndexedMatrix bodytransform = body.GetWorldTransform();
+ collisionObject.SetInterpolationLinearVelocity(ref zeroVector);
+ collisionObject.SetInterpolationAngularVelocity(ref zeroVector);
+ IndexedMatrix bodytransform = collisionObject.GetWorldTransform();
- body.SetInterpolationWorldTransform(ref bodytransform);
+ collisionObject.SetInterpolationWorldTransform(ref bodytransform);
- if (body is RigidBody)
+ if (collisionObject is RigidBody)
{
- RigidBody rigidbody = body as RigidBody;
+ RigidBody rigidbody = collisionObject as RigidBody;
rigidbody.SetLinearVelocity(zeroVector);
rigidbody.SetAngularVelocity(zeroVector);
rigidbody.ClearForces();
}
}
- public override void SetInterpolationAngularVelocity(BulletBody pBody, Vector3 pVector3)
+ public override void SetInterpolationAngularVelocity(BulletBody pCollisionObject, Vector3 pVector3)
{
- RigidBody body = ((BulletBodyXNA)pBody).rigidBody;
+ CollisionObject collisionObject = (pCollisionObject as BulletBodyXNA).rigidBody;
IndexedVector3 vec = new IndexedVector3(pVector3.X, pVector3.Y, pVector3.Z);
- body.SetInterpolationAngularVelocity(ref vec);
+ collisionObject.SetInterpolationAngularVelocity(ref vec);
}
public override void SetAngularVelocity(BulletBody pBody, Vector3 pVector3)
{
- RigidBody body = ((BulletBodyXNA)pBody).rigidBody;
+ RigidBody body = (pBody as BulletBodyXNA).rigidBody;
IndexedVector3 vec = new IndexedVector3(pVector3.X, pVector3.Y, pVector3.Z);
body.SetAngularVelocity(ref vec);
}
public override Vector3 GetTotalForce(BulletBody pBody)
{
- RigidBody body = ((BulletBodyXNA)pBody).rigidBody;
+ RigidBody body = (pBody as BulletBodyXNA).rigidBody;
IndexedVector3 iv3 = body.GetTotalForce();
return new Vector3(iv3.X, iv3.Y, iv3.Z);
}
public override Vector3 GetTotalTorque(BulletBody pBody)
{
- RigidBody body = ((BulletBodyXNA)pBody).rigidBody;
+ RigidBody body = (pBody as BulletBodyXNA).rigidBody;
IndexedVector3 iv3 = body.GetTotalTorque();
return new Vector3(iv3.X, iv3.Y, iv3.Z);
}
public override Vector3 GetInvInertiaDiagLocal(BulletBody pBody)
{
- RigidBody body = ((BulletBodyXNA)pBody).rigidBody;
+ RigidBody body = (pBody as BulletBodyXNA).rigidBody;
IndexedVector3 iv3 = body.GetInvInertiaDiagLocal();
return new Vector3(iv3.X, iv3.Y, iv3.Z);
}
public override void SetInvInertiaDiagLocal(BulletBody pBody, Vector3 inert)
{
- RigidBody body = ((BulletBodyXNA)pBody).rigidBody;
+ RigidBody body = (pBody as BulletBodyXNA).rigidBody;
IndexedVector3 iv3 = new IndexedVector3(inert.X, inert.Y, inert.Z);
body.SetInvInertiaDiagLocal(ref iv3);
}
public override void ApplyForce(BulletBody pBody, Vector3 force, Vector3 pos)
{
- RigidBody body = ((BulletBodyXNA)pBody).rigidBody;
+ RigidBody body = (pBody as BulletBodyXNA).rigidBody;
IndexedVector3 forceiv3 = new IndexedVector3(force.X, force.Y, force.Z);
IndexedVector3 posiv3 = new IndexedVector3(pos.X, pos.Y, pos.Z);
body.ApplyForce(ref forceiv3, ref posiv3);
}
public override void ApplyImpulse(BulletBody pBody, Vector3 imp, Vector3 pos)
{
- RigidBody body = ((BulletBodyXNA)pBody).rigidBody;
+ RigidBody body = (pBody as BulletBodyXNA).rigidBody;
IndexedVector3 impiv3 = new IndexedVector3(imp.X, imp.Y, imp.Z);
IndexedVector3 posiv3 = new IndexedVector3(pos.X, pos.Y, pos.Z);
body.ApplyImpulse(ref impiv3, ref posiv3);
@@ -359,32 +381,32 @@ private sealed class BulletConstraintXNA : BulletConstraint
public override void ClearForces(BulletBody pBody)
{
- RigidBody body = ((BulletBodyXNA)pBody).rigidBody;
+ RigidBody body = (pBody as BulletBodyXNA).rigidBody;
body.ClearForces();
}
- public override void SetTranslation(BulletBody pBody, Vector3 _position, Quaternion _orientation)
+ public override void SetTranslation(BulletBody pCollisionObject, Vector3 _position, Quaternion _orientation)
{
- RigidBody body = ((BulletBodyXNA)pBody).rigidBody;
+ CollisionObject collisionObject = (pCollisionObject as BulletBodyXNA).rigidBody;
IndexedVector3 vposition = new IndexedVector3(_position.X, _position.Y, _position.Z);
IndexedQuaternion vquaternion = new IndexedQuaternion(_orientation.X, _orientation.Y, _orientation.Z,
_orientation.W);
IndexedMatrix mat = IndexedMatrix.CreateFromQuaternion(vquaternion);
mat._origin = vposition;
- body.SetWorldTransform(mat);
+ collisionObject.SetWorldTransform(mat);
}
- public override Vector3 GetPosition(BulletBody pBody)
+ public override Vector3 GetPosition(BulletBody pCollisionObject)
{
- RigidBody body = ((BulletBodyXNA)pBody).rigidBody;
- IndexedVector3 pos = body.GetInterpolationWorldTransform()._origin;
+ CollisionObject collisionObject = (pCollisionObject as BulletBodyXNA).rigidBody;
+ IndexedVector3 pos = collisionObject.GetInterpolationWorldTransform()._origin;
return new Vector3(pos.X, pos.Y, pos.Z);
}
public override Vector3 CalculateLocalInertia(BulletShape pShape, float pphysMass)
{
- CollisionShape shape = ((BulletShapeXNA)pShape).shape;
+ CollisionShape shape = (pShape as BulletShapeXNA).shape;
IndexedVector3 inertia = IndexedVector3.Zero;
shape.CalculateLocalInertia(pphysMass, out inertia);
return new Vector3(inertia.X, inertia.Y, inertia.Z);
@@ -392,7 +414,7 @@ private sealed class BulletConstraintXNA : BulletConstraint
public override void SetMassProps(BulletBody pBody, float pphysMass, Vector3 plocalInertia)
{
- RigidBody body = ((BulletBodyXNA)pBody).rigidBody;
+ RigidBody body = (pBody as BulletBodyXNA).rigidBody;
IndexedVector3 inertia = new IndexedVector3(plocalInertia.X, plocalInertia.Y, plocalInertia.Z);
body.SetMassProps(pphysMass, inertia);
}
@@ -400,73 +422,90 @@ private sealed class BulletConstraintXNA : BulletConstraint
public override void SetObjectForce(BulletBody pBody, Vector3 _force)
{
- RigidBody body = ((BulletBodyXNA)pBody).rigidBody;
+ RigidBody body = (pBody as BulletBodyXNA).rigidBody;
IndexedVector3 force = new IndexedVector3(_force.X, _force.Y, _force.Z);
body.SetTotalForce(ref force);
}
- public override void SetFriction(BulletBody pBody, float _currentFriction)
+ public override void SetFriction(BulletBody pCollisionObject, float _currentFriction)
{
- RigidBody body = ((BulletBodyXNA)pBody).rigidBody;
- body.SetFriction(_currentFriction);
+ CollisionObject collisionObject = (pCollisionObject as BulletBodyXNA).rigidBody;
+ collisionObject.SetFriction(_currentFriction);
}
public override void SetLinearVelocity(BulletBody pBody, Vector3 _velocity)
{
- RigidBody body = ((BulletBodyXNA)pBody).rigidBody;
+ RigidBody body = (pBody as BulletBodyXNA).rigidBody;
IndexedVector3 velocity = new IndexedVector3(_velocity.X, _velocity.Y, _velocity.Z);
body.SetLinearVelocity(velocity);
}
- public override void Activate(BulletBody pBody, bool pforceactivation)
+ public override void Activate(BulletBody pCollisionObject, bool pforceactivation)
{
- RigidBody body = ((BulletBodyXNA)pBody).rigidBody;
- body.Activate(pforceactivation);
+ CollisionObject collisionObject = (pCollisionObject as BulletBodyXNA).rigidBody;
+ collisionObject.Activate(pforceactivation);
}
- public override Quaternion GetOrientation(BulletBody pBody)
+ public override Quaternion GetOrientation(BulletBody pCollisionObject)
{
- RigidBody body = ((BulletBodyXNA)pBody).rigidBody;
- IndexedQuaternion mat = body.GetInterpolationWorldTransform().GetRotation();
+ CollisionObject collisionObject = (pCollisionObject as BulletBodyXNA).rigidBody;
+ IndexedQuaternion mat = collisionObject.GetInterpolationWorldTransform().GetRotation();
return new Quaternion(mat.X, mat.Y, mat.Z, mat.W);
}
- public override CollisionFlags RemoveFromCollisionFlags(BulletBody pBody, CollisionFlags pcollisionFlags)
+ public override CollisionFlags RemoveFromCollisionFlags(BulletBody pCollisionObject, CollisionFlags pcollisionFlags)
{
- RigidBody body = ((BulletBodyXNA)pBody).rigidBody;
- CollisionFlags existingcollisionFlags = (CollisionFlags)(uint)body.GetCollisionFlags();
+ CollisionObject collisionObject = (pCollisionObject as BulletBodyXNA).rigidBody;
+ CollisionFlags existingcollisionFlags = (CollisionFlags)(uint)collisionObject.GetCollisionFlags();
existingcollisionFlags &= ~pcollisionFlags;
- body.SetCollisionFlags((BulletXNA.BulletCollision.CollisionFlags)(uint)existingcollisionFlags);
+ collisionObject.SetCollisionFlags((BulletXNA.BulletCollision.CollisionFlags)(uint)existingcollisionFlags);
return (CollisionFlags)(uint)existingcollisionFlags;
}
- public override float GetCcdMotionThreshold(BulletBody obj) { /* TODO */ return 0f; }
+ public override float GetCcdMotionThreshold(BulletBody pCollisionObject)
+ {
+ CollisionObject collisionObject = (pCollisionObject as BulletBodyXNA).rigidBody;
+ return collisionObject.GetCcdSquareMotionThreshold();
+ }
- public override float GetCcdSweptSphereRadius(BulletBody obj) { /* TODO */ return 0f; }
+ public override float GetCcdSweptSphereRadius(BulletBody pCollisionObject)
+ {
+ CollisionObject collisionObject = (pCollisionObject as BulletBodyXNA).rigidBody;
+ return collisionObject.GetCcdSweptSphereRadius();
+
+ }
- public override IntPtr GetUserPointer(BulletBody obj) { /* TODO */ return IntPtr.Zero; }
+ public override IntPtr GetUserPointer(BulletBody pCollisionObject)
+ {
+ CollisionObject shape = (pCollisionObject as BulletBodyXNA).body;
+ return (IntPtr)shape.GetUserPointer();
+ }
- public override void SetUserPointer(BulletBody obj, IntPtr val) { /* TODO */ }
+ public override void SetUserPointer(BulletBody pCollisionObject, IntPtr val)
+ {
+ CollisionObject shape = (pCollisionObject as BulletBodyXNA).body;
+ shape.SetUserPointer(val);
+ }
public override void SetGravity(BulletBody pBody, Vector3 pGravity)
{
- RigidBody body = ((BulletBodyXNA)pBody).rigidBody;
+ RigidBody body = (pBody as BulletBodyXNA).rigidBody;
IndexedVector3 gravity = new IndexedVector3(pGravity.X, pGravity.Y, pGravity.Z);
body.SetGravity(gravity);
}
public override bool DestroyConstraint(BulletWorld pWorld, BulletConstraint pConstraint)
{
- DiscreteDynamicsWorld world = ((BulletWorldXNA)pWorld).world;
- TypedConstraint constraint = ((BulletConstraintXNA)pConstraint).constrain;
+ DiscreteDynamicsWorld world = (pWorld as BulletWorldXNA).world;
+ TypedConstraint constraint = (pConstraint as BulletConstraintXNA).constrain;
world.RemoveConstraint(constraint);
return true;
}
public override bool SetLinearLimits(BulletConstraint pConstraint, Vector3 low, Vector3 high)
{
- Generic6DofConstraint constraint = ((BulletConstraintXNA)pConstraint).constrain as Generic6DofConstraint;
+ Generic6DofConstraint constraint = (pConstraint as BulletConstraintXNA).constrain as Generic6DofConstraint;
IndexedVector3 lowlimit = new IndexedVector3(low.X, low.Y, low.Z);
IndexedVector3 highlimit = new IndexedVector3(high.X, high.Y, high.Z);
constraint.SetLinearLowerLimit(lowlimit);
@@ -476,7 +515,7 @@ private sealed class BulletConstraintXNA : BulletConstraint
public override bool SetAngularLimits(BulletConstraint pConstraint, Vector3 low, Vector3 high)
{
- Generic6DofConstraint constraint = ((BulletConstraintXNA)pConstraint).constrain as Generic6DofConstraint;
+ Generic6DofConstraint constraint = (pConstraint as BulletConstraintXNA).constrain as Generic6DofConstraint;
IndexedVector3 lowlimit = new IndexedVector3(low.X, low.Y, low.Z);
IndexedVector3 highlimit = new IndexedVector3(high.X, high.Y, high.Z);
constraint.SetAngularLowerLimit(lowlimit);
@@ -486,20 +525,20 @@ private sealed class BulletConstraintXNA : BulletConstraint
public override void SetConstraintNumSolverIterations(BulletConstraint pConstraint, float cnt)
{
- Generic6DofConstraint constraint = ((BulletConstraintXNA)pConstraint).constrain as Generic6DofConstraint;
+ Generic6DofConstraint constraint = (pConstraint as BulletConstraintXNA).constrain as Generic6DofConstraint;
constraint.SetOverrideNumSolverIterations((int)cnt);
}
public override bool CalculateTransforms(BulletConstraint pConstraint)
{
- Generic6DofConstraint constraint = ((BulletConstraintXNA)pConstraint).constrain as Generic6DofConstraint;
+ Generic6DofConstraint constraint = (pConstraint as BulletConstraintXNA).constrain as Generic6DofConstraint;
constraint.CalculateTransforms();
return true;
}
public override void SetConstraintEnable(BulletConstraint pConstraint, float p_2)
{
- Generic6DofConstraint constraint = ((BulletConstraintXNA)pConstraint).constrain as Generic6DofConstraint;
+ Generic6DofConstraint constraint = (pConstraint as BulletConstraintXNA).constrain as Generic6DofConstraint;
constraint.SetEnabled((p_2 == 0) ? false : true);
}
@@ -508,9 +547,9 @@ private sealed class BulletConstraintXNA : BulletConstraint
public override BulletConstraint Create6DofConstraint(BulletWorld pWorld, BulletBody pBody1, BulletBody pBody2, Vector3 pframe1, Quaternion pframe1rot, Vector3 pframe2, Quaternion pframe2rot, bool puseLinearReferenceFrameA, bool pdisableCollisionsBetweenLinkedBodies)
{
- DiscreteDynamicsWorld world = ((BulletWorldXNA)pWorld).world;
- RigidBody body1 = ((BulletBodyXNA)pBody1).rigidBody;
- RigidBody body2 = ((BulletBodyXNA)pBody2).rigidBody;
+ DiscreteDynamicsWorld world = (pWorld as BulletWorldXNA).world;
+ RigidBody body1 = (pBody1 as BulletBodyXNA).rigidBody;
+ RigidBody body2 = (pBody2 as BulletBodyXNA).rigidBody;
IndexedVector3 frame1v = new IndexedVector3(pframe1.X, pframe1.Y, pframe1.Z);
IndexedQuaternion frame1rot = new IndexedQuaternion(pframe1rot.X, pframe1rot.Y, pframe1rot.Z, pframe1rot.W);
IndexedMatrix frame1 = IndexedMatrix.CreateFromQuaternion(frame1rot);
@@ -542,9 +581,9 @@ private sealed class BulletConstraintXNA : BulletConstraint
///
public override BulletConstraint Create6DofConstraintToPoint(BulletWorld pWorld, BulletBody pBody1, BulletBody pBody2, Vector3 pjoinPoint, bool puseLinearReferenceFrameA, bool pdisableCollisionsBetweenLinkedBodies)
{
- DiscreteDynamicsWorld world = ((BulletWorldXNA)pWorld).world;
- RigidBody body1 = ((BulletBodyXNA)pBody1).rigidBody;
- RigidBody body2 = ((BulletBodyXNA)pBody2).rigidBody;
+ DiscreteDynamicsWorld world = (pWorld as BulletWorldXNA).world;
+ RigidBody body1 = (pBody1 as BulletBodyXNA).rigidBody;
+ RigidBody body2 = (pBody2 as BulletBodyXNA).rigidBody;
IndexedMatrix frame1 = new IndexedMatrix(IndexedBasisMatrix.Identity, new IndexedVector3(0, 0, 0));
IndexedMatrix frame2 = new IndexedMatrix(IndexedBasisMatrix.Identity, new IndexedVector3(0, 0, 0));
@@ -563,7 +602,7 @@ private sealed class BulletConstraintXNA : BulletConstraint
//SetFrames(m_constraint.ptr, frameA, frameArot, frameB, frameBrot);
public override bool SetFrames(BulletConstraint pConstraint, Vector3 pframe1, Quaternion pframe1rot, Vector3 pframe2, Quaternion pframe2rot)
{
- Generic6DofConstraint constraint = ((BulletConstraintXNA)pConstraint).constrain as Generic6DofConstraint;
+ Generic6DofConstraint constraint = (pConstraint as BulletConstraintXNA).constrain as Generic6DofConstraint;
IndexedVector3 frame1v = new IndexedVector3(pframe1.X, pframe1.Y, pframe1.Z);
IndexedQuaternion frame1rot = new IndexedQuaternion(pframe1rot.X, pframe1rot.Y, pframe1rot.Z, pframe1rot.W);
IndexedMatrix frame1 = IndexedMatrix.CreateFromQuaternion(frame1rot);
@@ -579,109 +618,110 @@ private sealed class BulletConstraintXNA : BulletConstraint
public override Vector3 GetLinearVelocity(BulletBody pBody)
{
- RigidBody body = ((BulletBodyXNA)pBody).rigidBody;
+ RigidBody body = (pBody as BulletBodyXNA).rigidBody;
IndexedVector3 iv3 = body.GetLinearVelocity();
return new Vector3(iv3.X, iv3.Y, iv3.Z);
}
public override Vector3 GetAngularVelocity(BulletBody pBody)
{
- RigidBody body = ((BulletBodyXNA)pBody).rigidBody;
+ RigidBody body = (pBody as BulletBodyXNA).rigidBody;
IndexedVector3 iv3 = body.GetAngularVelocity();
return new Vector3(iv3.X, iv3.Y, iv3.Z);
}
public override Vector3 GetVelocityInLocalPoint(BulletBody pBody, Vector3 pos)
{
- RigidBody body = ((BulletBodyXNA)pBody).rigidBody;
+ RigidBody body = (pBody as BulletBodyXNA).rigidBody;
IndexedVector3 posiv3 = new IndexedVector3(pos.X, pos.Y, pos.Z);
IndexedVector3 iv3 = body.GetVelocityInLocalPoint(ref posiv3);
return new Vector3(iv3.X, iv3.Y, iv3.Z);
}
- public override void Translate(BulletBody pBody, Vector3 trans)
+ public override void Translate(BulletBody pCollisionObject, Vector3 trans)
{
- RigidBody body = ((BulletBodyXNA)pBody).rigidBody;
+ CollisionObject collisionObject = (pCollisionObject as BulletBodyXNA).rigidBody;
+ collisionObject.Translate(new IndexedVector3(trans.X,trans.Y,trans.Z));
}
public override void UpdateDeactivation(BulletBody pBody, float timeStep)
{
- RigidBody body = ((BulletBodyXNA)pBody).rigidBody;
+ RigidBody body = (pBody as BulletBodyXNA).rigidBody;
body.UpdateDeactivation(timeStep);
}
public override bool WantsSleeping(BulletBody pBody)
{
- RigidBody body = ((BulletBodyXNA)pBody).rigidBody;
+ RigidBody body = (pBody as BulletBodyXNA).rigidBody;
return body.WantsSleeping();
}
public override void SetAngularFactor(BulletBody pBody, float factor)
{
- RigidBody body = ((BulletBodyXNA)pBody).rigidBody;
+ RigidBody body = (pBody as BulletBodyXNA).rigidBody;
body.SetAngularFactor(factor);
}
public override Vector3 GetAngularFactor(BulletBody pBody)
{
- RigidBody body = ((BulletBodyXNA)pBody).rigidBody;
+ RigidBody body = (pBody as BulletBodyXNA).rigidBody;
IndexedVector3 iv3 = body.GetAngularFactor();
return new Vector3(iv3.X, iv3.Y, iv3.Z);
}
- public override bool IsInWorld(BulletWorld pWorld, BulletBody pBody)
+ public override bool IsInWorld(BulletWorld pWorld, BulletBody pCollisionObject)
{
- DiscreteDynamicsWorld world = ((BulletWorldXNA)pWorld).world;
- CollisionObject body = ((BulletBodyXNA)pBody).body;
- return world.IsInWorld(body);
+ DiscreteDynamicsWorld world = (pWorld as BulletWorldXNA).world;
+ CollisionObject collisionObject = (pCollisionObject as BulletBodyXNA).body;
+ return world.IsInWorld(collisionObject);
}
- public override void AddConstraintRef(BulletBody pBody, BulletConstraint pConstrain)
+ public override void AddConstraintRef(BulletBody pBody, BulletConstraint pConstraint)
{
- RigidBody body = ((BulletBodyXNA)pBody).rigidBody;
- TypedConstraint constrain = ((BulletConstraintXNA)pConstrain).constrain;
+ RigidBody body = (pBody as BulletBodyXNA).rigidBody;
+ TypedConstraint constrain = (pConstraint as BulletConstraintXNA).constrain;
body.AddConstraintRef(constrain);
}
- public override void RemoveConstraintRef(BulletBody pBody, BulletConstraint pConstrain)
+ public override void RemoveConstraintRef(BulletBody pBody, BulletConstraint pConstraint)
{
- RigidBody body = ((BulletBodyXNA)pBody).rigidBody;
- TypedConstraint constrain = ((BulletConstraintXNA)pConstrain).constrain;
+ RigidBody body = (pBody as BulletBodyXNA).rigidBody;
+ TypedConstraint constrain = (pConstraint as BulletConstraintXNA).constrain;
body.RemoveConstraintRef(constrain);
}
public override BulletConstraint GetConstraintRef(BulletBody pBody, int index)
{
- RigidBody body = ((BulletBodyXNA)pBody).rigidBody;
+ RigidBody body = (pBody as BulletBodyXNA).rigidBody;
return new BulletConstraintXNA(body.GetConstraintRef(index));
}
public override int GetNumConstraintRefs(BulletBody pBody)
{
- RigidBody body = ((BulletBodyXNA)pBody).rigidBody;
+ RigidBody body = (pBody as BulletBodyXNA).rigidBody;
return body.GetNumConstraintRefs();
}
- public override void SetInterpolationLinearVelocity(BulletBody pBody, Vector3 VehicleVelocity)
+ public override void SetInterpolationLinearVelocity(BulletBody pCollisionObject, Vector3 VehicleVelocity)
{
- RigidBody body = ((BulletBodyXNA)pBody).rigidBody;
+ CollisionObject collisionObject = (pCollisionObject as BulletBodyXNA).rigidBody;
IndexedVector3 velocity = new IndexedVector3(VehicleVelocity.X, VehicleVelocity.Y, VehicleVelocity.Z);
- body.SetInterpolationLinearVelocity(ref velocity);
+ collisionObject.SetInterpolationLinearVelocity(ref velocity);
}
public override bool UseFrameOffset(BulletConstraint pConstraint, float onOff)
{
- Generic6DofConstraint constraint = ((BulletConstraintXNA)pConstraint).constrain as Generic6DofConstraint;
+ Generic6DofConstraint constraint = (pConstraint as BulletConstraintXNA).constrain as Generic6DofConstraint;
constraint.SetUseFrameOffset((onOff == 0) ? false : true);
return true;
}
//SetBreakingImpulseThreshold(m_constraint.ptr, threshold);
public override bool SetBreakingImpulseThreshold(BulletConstraint pConstraint, float threshold)
{
- Generic6DofConstraint constraint = ((BulletConstraintXNA)pConstraint).constrain as Generic6DofConstraint;
+ Generic6DofConstraint constraint = (pConstraint as BulletConstraintXNA).constrain as Generic6DofConstraint;
constraint.SetBreakingImpulseThreshold(threshold);
return true;
}
//BulletSimAPI.SetAngularDamping(Prim.PhysBody.ptr, angularDamping);
public override void SetAngularDamping(BulletBody pBody, float angularDamping)
{
- RigidBody body = ((BulletBodyXNA)pBody).rigidBody;
+ RigidBody body = (pBody as BulletBodyXNA).rigidBody;
float lineardamping = body.GetLinearDamping();
body.SetDamping(lineardamping, angularDamping);
@@ -689,111 +729,183 @@ private sealed class BulletConstraintXNA : BulletConstraint
public override void UpdateInertiaTensor(BulletBody pBody)
{
- RigidBody body = ((BulletBodyXNA)pBody).rigidBody;
+ RigidBody body = (pBody as BulletBodyXNA).rigidBody;
body.UpdateInertiaTensor();
}
public override void RecalculateCompoundShapeLocalAabb(BulletShape pCompoundShape)
{
- CompoundShape shape = ((BulletShapeXNA)pCompoundShape).shape as CompoundShape;
+ CompoundShape shape = (pCompoundShape as BulletShapeXNA).shape as CompoundShape;
shape.RecalculateLocalAabb();
}
//BulletSimAPI.GetCollisionFlags(PhysBody.ptr)
- public override CollisionFlags GetCollisionFlags(BulletBody pBody)
+ public override CollisionFlags GetCollisionFlags(BulletBody pCollisionObject)
{
- RigidBody body = ((BulletBodyXNA)pBody).rigidBody;
- uint flags = (uint)body.GetCollisionFlags();
+ CollisionObject collisionObject = (pCollisionObject as BulletBodyXNA).rigidBody;
+ uint flags = (uint)collisionObject.GetCollisionFlags();
return (CollisionFlags) flags;
}
public override void SetDamping(BulletBody pBody, float pLinear, float pAngular)
{
- RigidBody body = ((BulletBodyXNA)pBody).rigidBody;
+ RigidBody body = (pBody as BulletBodyXNA).rigidBody;
body.SetDamping(pLinear, pAngular);
}
//PhysBody.ptr, PhysicsScene.Params.deactivationTime);
- public override void SetDeactivationTime(BulletBody pBody, float pDeactivationTime)
+ public override void SetDeactivationTime(BulletBody pCollisionObject, float pDeactivationTime)
{
- RigidBody body = ((BulletBodyXNA)pBody).rigidBody;
- body.SetDeactivationTime(pDeactivationTime);
+ CollisionObject collisionObject = (pCollisionObject as BulletBodyXNA).rigidBody;
+ collisionObject.SetDeactivationTime(pDeactivationTime);
}
//SetSleepingThresholds(PhysBody.ptr, PhysicsScene.Params.linearSleepingThreshold, PhysicsScene.Params.angularSleepingThreshold);
public override void SetSleepingThresholds(BulletBody pBody, float plinearSleepingThreshold, float pangularSleepingThreshold)
{
- RigidBody body = ((BulletBodyXNA)pBody).rigidBody;
+ RigidBody body = (pBody as BulletBodyXNA).rigidBody;
body.SetSleepingThresholds(plinearSleepingThreshold, pangularSleepingThreshold);
}
- public override CollisionObjectTypes GetBodyType(BulletBody pBody)
+ public override CollisionObjectTypes GetBodyType(BulletBody pCollisionObject)
{
- RigidBody body = ((BulletBodyXNA)pBody).rigidBody;
- return (CollisionObjectTypes)(int) body.GetInternalType();
+ CollisionObject collisionObject = (pCollisionObject as BulletBodyXNA).rigidBody;
+ return (CollisionObjectTypes)(int) collisionObject.GetInternalType();
}
- public override void ApplyGravity(BulletBody obj) { /* TODO */ }
+ public override void ApplyGravity(BulletBody pBody)
+ {
- public override Vector3 GetGravity(BulletBody obj) { /* TODO */ return Vector3.Zero; }
+ RigidBody body = (pBody as BulletBodyXNA).rigidBody;
+ body.ApplyGravity();
+ }
- public override void SetLinearDamping(BulletBody obj, float lin_damping) { /* TODO */ }
+ public override Vector3 GetGravity(BulletBody pBody)
+ {
+ RigidBody body = (pBody as BulletBodyXNA).rigidBody;
+ IndexedVector3 gravity = body.GetGravity();
+ return new Vector3(gravity.X, gravity.Y, gravity.Z);
+ }
- public override float GetLinearDamping(BulletBody obj) { /* TODO */ return 0f; }
+ public override void SetLinearDamping(BulletBody pBody, float lin_damping)
+ {
+ RigidBody body = (pBody as BulletBodyXNA).rigidBody;
+ float angularDamping = body.GetAngularDamping();
+ body.SetDamping(lin_damping, angularDamping);
+ }
- public override float GetAngularDamping(BulletBody obj) { /* TODO */ return 0f; }
+ public override float GetLinearDamping(BulletBody pBody)
+ {
+ RigidBody body = (pBody as BulletBodyXNA).rigidBody;
+ return body.GetLinearDamping();
+ }
- public override float GetLinearSleepingThreshold(BulletBody obj) { /* TODO */ return 0f; }
+ public override float GetAngularDamping(BulletBody pBody)
+ {
+ RigidBody body = (pBody as BulletBodyXNA).rigidBody;
+ return body.GetAngularDamping();
+ }
- public override void ApplyDamping(BulletBody obj, float timeStep) { /* TODO */ }
+ public override float GetLinearSleepingThreshold(BulletBody pBody)
+ {
+ RigidBody body = (pBody as BulletBodyXNA).rigidBody;
+ return body.GetLinearSleepingThreshold();
+ }
- public override Vector3 GetLinearFactor(BulletBody obj) { /* TODO */ return Vector3.Zero; }
+ public override void ApplyDamping(BulletBody pBody, float timeStep)
+ {
+ RigidBody body = (pBody as BulletBodyXNA).rigidBody;
+ body.ApplyDamping(timeStep);
+ }
- public override void SetLinearFactor(BulletBody obj, Vector3 factor) { /* TODO */ }
+ public override Vector3 GetLinearFactor(BulletBody pBody)
+ {
+ RigidBody body = (pBody as BulletBodyXNA).rigidBody;
+ IndexedVector3 linearFactor = body.GetLinearFactor();
+ return new Vector3(linearFactor.X, linearFactor.Y, linearFactor.Z);
+ }
- public override void SetCenterOfMassByPosRot(BulletBody obj, Vector3 pos, Quaternion rot) { /* TODO */ }
+ public override void SetLinearFactor(BulletBody pBody, Vector3 factor)
+ {
+ RigidBody body = (pBody as BulletBodyXNA).rigidBody;
+ body.SetLinearFactor(new IndexedVector3(factor.X, factor.Y, factor.Z));
+ }
+
+ public override void SetCenterOfMassByPosRot(BulletBody pBody, Vector3 pos, Quaternion rot)
+ {
+ RigidBody body = (pBody as BulletBodyXNA).rigidBody;
+ IndexedQuaternion quat = new IndexedQuaternion(rot.X, rot.Y, rot.Z,rot.W);
+ IndexedMatrix mat = IndexedMatrix.CreateFromQuaternion(quat);
+ mat._origin = new IndexedVector3(pos.X, pos.Y, pos.Z);
+ body.SetCenterOfMassTransform( ref mat);
+ /* TODO: double check this */
+ }
//BulletSimAPI.ApplyCentralForce(PhysBody.ptr, fSum);
public override void ApplyCentralForce(BulletBody pBody, Vector3 pfSum)
{
- RigidBody body = ((BulletBodyXNA)pBody).rigidBody;
+ RigidBody body = (pBody as BulletBodyXNA).rigidBody;
IndexedVector3 fSum = new IndexedVector3(pfSum.X, pfSum.Y, pfSum.Z);
body.ApplyCentralForce(ref fSum);
}
public override void ApplyCentralImpulse(BulletBody pBody, Vector3 pfSum)
{
- RigidBody body = ((BulletBodyXNA)pBody).rigidBody;
+ RigidBody body = (pBody as BulletBodyXNA).rigidBody;
IndexedVector3 fSum = new IndexedVector3(pfSum.X, pfSum.Y, pfSum.Z);
body.ApplyCentralImpulse(ref fSum);
}
public override void ApplyTorque(BulletBody pBody, Vector3 pfSum)
{
- RigidBody body = ((BulletBodyXNA)pBody).rigidBody;
+ RigidBody body = (pBody as BulletBodyXNA).rigidBody;
IndexedVector3 fSum = new IndexedVector3(pfSum.X, pfSum.Y, pfSum.Z);
body.ApplyTorque(ref fSum);
}
public override void ApplyTorqueImpulse(BulletBody pBody, Vector3 pfSum)
{
- RigidBody body = ((BulletBodyXNA)pBody).rigidBody;
+ RigidBody body = (pBody as BulletBodyXNA).rigidBody;
IndexedVector3 fSum = new IndexedVector3(pfSum.X, pfSum.Y, pfSum.Z);
body.ApplyTorqueImpulse(ref fSum);
}
- public override void DestroyObject(BulletWorld p, BulletBody p_2)
+ public override void DestroyObject(BulletWorld pWorld, BulletBody pBody)
{
- //TODO:
+ DiscreteDynamicsWorld world = (pWorld as BulletWorldXNA).world;
+ CollisionObject co = (pBody as BulletBodyXNA).rigidBody;
+ RigidBody bo = co as RigidBody;
+ if (bo == null)
+ {
+
+ if (world.IsInWorld(co))
+ {
+ world.RemoveCollisionObject(co);
+ }
+ }
+ else
+ {
+
+ if (world.IsInWorld(bo))
+ {
+ world.RemoveRigidBody(bo);
+ }
+ }
+
}
public override void Shutdown(BulletWorld pWorld)
{
- DiscreteDynamicsWorld world = ((BulletWorldXNA)pWorld).world;
+ DiscreteDynamicsWorld world = (pWorld as BulletWorldXNA).world;
world.Cleanup();
}
- public override BulletShape DuplicateCollisionShape(BulletWorld sim, BulletShape srcShape, uint id)
+ public override BulletShape DuplicateCollisionShape(BulletWorld pWorld, BulletShape pShape, uint id)
{
- return null;
+ CollisionShape shape1 = (pShape as BulletShapeXNA).shape;
+
+ // TODO: Turn this from a reference copy to a Value Copy.
+ BulletShapeXNA shape2 = new BulletShapeXNA(shape1, BSPhysicsShapeType.SHAPE_UNKNOWN);
+
+ return shape2;
}
- public override bool DeleteCollisionShape(BulletWorld p, BulletShape p_2)
+ public override bool DeleteCollisionShape(BulletWorld pWorld, BulletShape pShape)
{
//TODO:
return false;
@@ -802,17 +914,40 @@ private sealed class BulletConstraintXNA : BulletConstraint
public override BulletBody CreateBodyFromShape(BulletWorld pWorld, BulletShape pShape, uint pLocalID, Vector3 pRawPosition, Quaternion pRawOrientation)
{
- CollisionWorld world = ((BulletWorldXNA)pWorld).world;
+ CollisionWorld world = (pWorld as BulletWorldXNA).world;
IndexedMatrix mat =
IndexedMatrix.CreateFromQuaternion(new IndexedQuaternion(pRawOrientation.X, pRawOrientation.Y,
pRawOrientation.Z, pRawOrientation.W));
mat._origin = new IndexedVector3(pRawPosition.X, pRawPosition.Y, pRawPosition.Z);
- CollisionShape shape = ((BulletShapeXNA)pShape).shape;
+ CollisionShape shape = (pShape as BulletShapeXNA).shape;
//UpdateSingleAabb(world, shape);
// TODO: Feed Update array into null
- RigidBody body = new RigidBody(0,new SimMotionState(world,pLocalID,mat,null),shape,IndexedVector3.Zero);
-
+ SimMotionState motionState = new SimMotionState(world, pLocalID, mat, null);
+ RigidBody body = new RigidBody(0,motionState,shape,IndexedVector3.Zero);
+ RigidBodyConstructionInfo constructionInfo = new RigidBodyConstructionInfo(0, new SimMotionState(world, pLocalID, mat, null),shape,IndexedVector3.Zero)
+ {
+ m_mass = 0
+ };
+ /*
+ m_mass = mass;
+ m_motionState =motionState;
+ m_collisionShape = collisionShape;
+ m_localInertia = localInertia;
+ m_linearDamping = 0f;
+ m_angularDamping = 0f;
+ m_friction = 0.5f;
+ m_restitution = 0f;
+ m_linearSleepingThreshold = 0.8f;
+ m_angularSleepingThreshold = 1f;
+ m_additionalDamping = false;
+ m_additionalDampingFactor = 0.005f;
+ m_additionalLinearDampingThresholdSqr = 0.01f;
+ m_additionalAngularDampingThresholdSqr = 0.01f;
+ m_additionalAngularDampingFactor = 0.01f;
+ m_startWorldTransform = IndexedMatrix.Identity;
+ */
body.SetUserPointer(pLocalID);
+
return new BulletBodyXNA(pLocalID, body);
}
@@ -825,7 +960,7 @@ private sealed class BulletConstraintXNA : BulletConstraint
pRawOrientation.Z, pRawOrientation.W));
mat._origin = new IndexedVector3(pRawPosition.X, pRawPosition.Y, pRawPosition.Z);
- CollisionShape shape = ((BulletShapeXNA)pShape).shape;
+ CollisionShape shape = (pShape as BulletShapeXNA).shape;
// TODO: Feed Update array into null
RigidBody body = new RigidBody(0, new DefaultMotionState( mat, IndexedMatrix.Identity), shape, IndexedVector3.Zero);
@@ -834,21 +969,43 @@ private sealed class BulletConstraintXNA : BulletConstraint
return new BulletBodyXNA(pLocalID, body);
}
//(m_mapInfo.terrainBody.ptr, CollisionFlags.CF_STATIC_OBJECT);
- public override CollisionFlags SetCollisionFlags(BulletBody pBody, CollisionFlags collisionFlags)
+ public override CollisionFlags SetCollisionFlags(BulletBody pCollisionObject, CollisionFlags collisionFlags)
{
- RigidBody body = ((BulletBodyXNA)pBody).rigidBody;
- body.SetCollisionFlags((BulletXNA.BulletCollision.CollisionFlags) (uint) collisionFlags);
- return (CollisionFlags)body.GetCollisionFlags();
+ CollisionObject collisionObject = (pCollisionObject as BulletBodyXNA).rigidBody;
+ collisionObject.SetCollisionFlags((BulletXNA.BulletCollision.CollisionFlags) (uint) collisionFlags);
+ return (CollisionFlags)collisionObject.GetCollisionFlags();
}
- public override Vector3 GetAnisotripicFriction(BulletConstraint pconstrain) { /* TODO */ return Vector3.Zero; }
+ public override Vector3 GetAnisotripicFriction(BulletConstraint pconstrain)
+ {
+
+ /* TODO */
+ return Vector3.Zero;
+ }
public override Vector3 SetAnisotripicFriction(BulletConstraint pconstrain, Vector3 frict) { /* TODO */ return Vector3.Zero; }
public override bool HasAnisotripicFriction(BulletConstraint pconstrain) { /* TODO */ return false; }
public override float GetContactProcessingThreshold(BulletBody pBody) { /* TODO */ return 0f; }
- public override bool IsStaticObject(BulletBody pBody) { /* TODO */ return false; }
- public override bool IsKinematicObject(BulletBody pBody) { /* TODO */ return false; }
- public override bool IsStaticOrKinematicObject(BulletBody pBody) { /* TODO */ return false; }
- public override bool HasContactResponse(BulletBody pBody) { /* TODO */ return false; }
+ public override bool IsStaticObject(BulletBody pCollisionObject)
+ {
+ CollisionObject collisionObject = (pCollisionObject as BulletBodyXNA).rigidBody;
+ return collisionObject.IsStaticObject();
+
+ }
+ public override bool IsKinematicObject(BulletBody pCollisionObject)
+ {
+ CollisionObject collisionObject = (pCollisionObject as BulletBodyXNA).rigidBody;
+ return collisionObject.IsKinematicObject();
+ }
+ public override bool IsStaticOrKinematicObject(BulletBody pCollisionObject)
+ {
+ CollisionObject collisionObject = (pCollisionObject as BulletBodyXNA).rigidBody;
+ return collisionObject.IsStaticOrKinematicObject();
+ }
+ public override bool HasContactResponse(BulletBody pCollisionObject)
+ {
+ CollisionObject collisionObject = (pCollisionObject as BulletBodyXNA).rigidBody;
+ return collisionObject.HasContactResponse();
+ }
public override int GetActivationState(BulletBody pBody) { /* TODO */ return 0; }
public override void SetActivationState(BulletBody pBody, int state) { /* TODO */ }
public override float GetDeactivationTime(BulletBody pBody) { /* TODO */ return 0f; }
@@ -859,15 +1016,15 @@ private sealed class BulletConstraintXNA : BulletConstraint
public override float GetHitFraction(BulletBody pBody) { /* TODO */ return 0f; }
//(m_mapInfo.terrainBody.ptr, PhysicsScene.Params.terrainHitFraction);
- public override void SetHitFraction(BulletBody pBody, float pHitFraction)
+ public override void SetHitFraction(BulletBody pCollisionObject, float pHitFraction)
{
- RigidBody body = ((BulletBodyXNA)pBody).rigidBody;
- body.SetHitFraction(pHitFraction);
+ CollisionObject collisionObject = (pCollisionObject as BulletBodyXNA).rigidBody;
+ collisionObject.SetHitFraction(pHitFraction);
}
//BuildCapsuleShape(physicsScene.World.ptr, 1f, 1f, prim.Scale);
public override BulletShape BuildCapsuleShape(BulletWorld pWorld, float pRadius, float pHeight, Vector3 pScale)
{
- DiscreteDynamicsWorld world = ((BulletWorldXNA)pWorld).world;
+ DiscreteDynamicsWorld world = (pWorld as BulletWorldXNA).world;
IndexedVector3 scale = new IndexedVector3(pScale.X, pScale.Y, pScale.Z);
CapsuleShapeZ capsuleShapeZ = new CapsuleShapeZ(pRadius, pHeight);
capsuleShapeZ.SetMargin(world.WorldSettings.Params.collisionMargin);
@@ -881,14 +1038,24 @@ private sealed class BulletConstraintXNA : BulletConstraint
int maxUpdates, ref EntityProperties[] updateArray
)
{
+
+ m_updateArray = updateArray;
+ m_collisionArray = collisionArray;
/* TODO */
- return new BulletWorldXNA(1, null, null);
+ ConfigurationParameters[] configparms = new ConfigurationParameters[1];
+ configparms[0] = parms;
+ Vector3 worldExtent = new Vector3(Constants.RegionSize, Constants.RegionSize, Constants.RegionHeight);
+ m_maxCollisions = maxCollisions;
+ m_maxUpdatesPerFrame = maxUpdates;
+
+
+ return new BulletWorldXNA(1, PhysicsScene, BSAPIXNA.Initialize2(worldExtent, configparms, maxCollisions, ref collisionArray, maxUpdates, ref updateArray, null));
}
- private static object Initialize2(Vector3 worldExtent,
+ private static DiscreteDynamicsWorld Initialize2(Vector3 worldExtent,
ConfigurationParameters[] o,
- int mMaxCollisionsPerFrame, ref List collisionArray,
- int mMaxUpdatesPerFrame, ref List updateArray,
+ int mMaxCollisionsPerFrame, ref CollisionDesc[] collisionArray,
+ int mMaxUpdatesPerFrame, ref EntityProperties[] updateArray,
object mDebugLogCallbackHandle)
{
CollisionWorld.WorldData.ParamData p = new CollisionWorld.WorldData.ParamData();
@@ -968,8 +1135,13 @@ private sealed class BulletConstraintXNA : BulletConstraint
SequentialImpulseConstraintSolver m_solver = new SequentialImpulseConstraintSolver();
DiscreteDynamicsWorld world = new DiscreteDynamicsWorld(m_dispatcher, m_broadphase, m_solver, cci);
- world.UpdatedObjects = updateArray;
- world.UpdatedCollisions = collisionArray;
+
+
+ world.UpdatedObjects = BSAPIXNA.GetBulletXNAEntityStruct(BSAPIXNA.BulletSimEntityStructToByteArray(updateArray, updateArray.Length));
+ world.UpdatedCollisions = BSAPIXNA.GetBulletXNACollisionStruct(BSAPIXNA.BulletSimCollisionStructToByteArray(collisionArray, collisionArray.Length));
+ world.LastCollisionDesc = 0;
+ world.LastEntityProperty = 0;
+
world.WorldSettings.Params = p;
world.SetForceUpdateAllAabbs(p.shouldForceUpdateAllAabbs != 0);
world.GetSolverInfo().m_solverMode = SolverMode.SOLVER_USE_WARMSTARTING | SolverMode.SOLVER_SIMD;
@@ -1003,7 +1175,7 @@ private sealed class BulletConstraintXNA : BulletConstraint
world.GetSolverInfo().m_restingContactRestitutionThreshold = 2;
world.SetForceUpdateAllAabbs(true);
-
+ //BSParam.TerrainImplementation = 0;
world.SetGravity(new IndexedVector3(0,0,p.gravity));
return world;
@@ -1011,7 +1183,7 @@ private sealed class BulletConstraintXNA : BulletConstraint
//m_constraint.ptr, ConstraintParams.BT_CONSTRAINT_STOP_CFM, cfm, ConstraintParamAxis.AXIS_ALL
public override bool SetConstraintParam(BulletConstraint pConstraint, ConstraintParams paramIndex, float paramvalue, ConstraintParamAxis axis)
{
- Generic6DofConstraint constrain = ((BulletConstraintXNA)pConstraint).constrain as Generic6DofConstraint;
+ Generic6DofConstraint constrain = (pConstraint as BulletConstraintXNA).constrain as Generic6DofConstraint;
if (axis == ConstraintParamAxis.AXIS_LINEAR_ALL || axis == ConstraintParamAxis.AXIS_ALL)
{
constrain.SetParam((BulletXNA.BulletDynamics.ConstraintParams) (int) paramIndex, paramvalue, 0);
@@ -1034,7 +1206,8 @@ private sealed class BulletConstraintXNA : BulletConstraint
public override bool PushUpdate(BulletBody pCollisionObject)
{
bool ret = false;
- RigidBody rb = ((BulletBodyXNA)pCollisionObject).rigidBody;
+ CollisionObject collisionObject = (pCollisionObject as BulletBodyXNA).rigidBody;
+ RigidBody rb = collisionObject as RigidBody;
if (rb != null)
{
SimMotionState sms = rb.GetMotionState() as SimMotionState;
@@ -1052,57 +1225,57 @@ private sealed class BulletConstraintXNA : BulletConstraint
public override float GetAngularMotionDisc(BulletShape pShape)
{
- CollisionShape shape = ((BulletShapeXNA)pShape).shape;
+ CollisionShape shape = (pShape as BulletShapeXNA).shape;
return shape.GetAngularMotionDisc();
}
public override float GetContactBreakingThreshold(BulletShape pShape, float defaultFactor)
{
- CollisionShape shape = ((BulletShapeXNA)pShape).shape;
+ CollisionShape shape = (pShape as BulletShapeXNA).shape;
return shape.GetContactBreakingThreshold(defaultFactor);
}
public override bool IsCompound(BulletShape pShape)
{
- CollisionShape shape = ((BulletShapeXNA)pShape).shape;
+ CollisionShape shape = (pShape as BulletShapeXNA).shape;
return shape.IsCompound();
}
public override bool IsSoftBody(BulletShape pShape)
{
- CollisionShape shape = ((BulletShapeXNA)pShape).shape;
+ CollisionShape shape = (pShape as BulletShapeXNA).shape;
return shape.IsSoftBody();
}
public override bool IsPolyhedral(BulletShape pShape)
{
- CollisionShape shape = ((BulletShapeXNA)pShape).shape;
+ CollisionShape shape = (pShape as BulletShapeXNA).shape;
return shape.IsPolyhedral();
}
public override bool IsConvex2d(BulletShape pShape)
{
- CollisionShape shape = ((BulletShapeXNA)pShape).shape;
+ CollisionShape shape = (pShape as BulletShapeXNA).shape;
return shape.IsConvex2d();
}
public override bool IsConvex(BulletShape pShape)
{
- CollisionShape shape = ((BulletShapeXNA)pShape).shape;
+ CollisionShape shape = (pShape as BulletShapeXNA).shape;
return shape.IsConvex();
}
public override bool IsNonMoving(BulletShape pShape)
{
- CollisionShape shape = ((BulletShapeXNA)pShape).shape;
+ CollisionShape shape = (pShape as BulletShapeXNA).shape;
return shape.IsNonMoving();
}
public override bool IsConcave(BulletShape pShape)
{
- CollisionShape shape = ((BulletShapeXNA)pShape).shape;
+ CollisionShape shape = (pShape as BulletShapeXNA).shape;
return shape.IsConcave();
}
public override bool IsInfinite(BulletShape pShape)
{
- CollisionShape shape = ((BulletShapeXNA)pShape).shape;
+ CollisionShape shape = (pShape as BulletShapeXNA).shape;
return shape.IsInfinite();
}
public override bool IsNativeShape(BulletShape pShape)
{
- CollisionShape shape = ((BulletShapeXNA)pShape).shape;
+ CollisionShape shape = (pShape as BulletShapeXNA).shape;
bool ret;
switch (shape.GetShapeType())
{
@@ -1119,38 +1292,53 @@ private sealed class BulletConstraintXNA : BulletConstraint
return ret;
}
- public override void SetShapeCollisionMargin(BulletShape shape, float margin) { /* TODO */ }
+ public override void SetShapeCollisionMargin(BulletShape pShape, float pMargin)
+ {
+ CollisionShape shape = (pShape as BulletShapeXNA).shape;
+ shape.SetMargin(pMargin);
+ }
//sim.ptr, shape.ptr,prim.LocalID, prim.RawPosition, prim.RawOrientation
public override BulletBody CreateGhostFromShape(BulletWorld pWorld, BulletShape pShape, uint pLocalID, Vector3 pRawPosition, Quaternion pRawOrientation)
{
- DiscreteDynamicsWorld world = ((BulletWorldXNA)pWorld).world;
+ DiscreteDynamicsWorld world = (pWorld as BulletWorldXNA).world;
IndexedMatrix bodyTransform = new IndexedMatrix();
bodyTransform._origin = new IndexedVector3(pRawPosition.X, pRawPosition.Y, pRawPosition.Z);
bodyTransform.SetRotation(new IndexedQuaternion(pRawOrientation.X,pRawOrientation.Y,pRawOrientation.Z,pRawOrientation.W));
GhostObject gObj = new PairCachingGhostObject();
gObj.SetWorldTransform(bodyTransform);
- CollisionShape shape = ((BulletShapeXNA)pShape).shape;
+ CollisionShape shape = (pShape as BulletShapeXNA).shape;
gObj.SetCollisionShape(shape);
gObj.SetUserPointer(pLocalID);
// TODO: Add to Special CollisionObjects!
return new BulletBodyXNA(pLocalID, gObj);
}
- public override void SetCollisionShape(BulletWorld pWorld, BulletBody pObj, BulletShape pShape)
+ public override void SetCollisionShape(BulletWorld pWorld, BulletBody pCollisionObject, BulletShape pShape)
{
- DiscreteDynamicsWorld world = ((BulletWorldXNA)pWorld).world;
- CollisionObject obj = ((BulletBodyXNA)pObj).body;
- CollisionShape shape = ((BulletShapeXNA)pShape).shape;
- obj.SetCollisionShape(shape);
-
+ DiscreteDynamicsWorld world = (pWorld as BulletWorldXNA).world;
+ CollisionObject collisionObject = (pCollisionObject as BulletBodyXNA).body;
+ if (pShape == null)
+ {
+ collisionObject.SetCollisionShape(new EmptyShape());
+ }
+ else
+ {
+ CollisionShape shape = (pShape as BulletShapeXNA).shape;
+ collisionObject.SetCollisionShape(shape);
+ }
+ }
+ public override BulletShape GetCollisionShape(BulletBody pCollisionObject)
+ {
+ CollisionObject collisionObject = (pCollisionObject as BulletBodyXNA).rigidBody;
+ CollisionShape shape = collisionObject.GetCollisionShape();
+ return new BulletShapeXNA(shape,BSPhysicsShapeType.SHAPE_UNKNOWN);
}
- public override BulletShape GetCollisionShape(BulletBody obj) { /* TODO */ return null; }
//(PhysicsScene.World.ptr, nativeShapeData)
public override BulletShape BuildNativeShape(BulletWorld pWorld, ShapeData pShapeData)
{
- DiscreteDynamicsWorld world = ((BulletWorldXNA)pWorld).world;
+ DiscreteDynamicsWorld world = (pWorld as BulletWorldXNA).world;
CollisionShape shape = null;
switch (pShapeData.Type)
{
@@ -1185,15 +1373,15 @@ private sealed class BulletConstraintXNA : BulletConstraint
public override int GetNumberOfCompoundChildren(BulletShape pCompoundShape)
{
- CompoundShape compoundshape = ((BulletShapeXNA)pCompoundShape).shape as CompoundShape;
+ CompoundShape compoundshape = (pCompoundShape as BulletShapeXNA).shape as CompoundShape;
return compoundshape.GetNumChildShapes();
}
//LinksetRoot.PhysShape.ptr, newShape.ptr, displacementPos, displacementRot
public override void AddChildShapeToCompoundShape(BulletShape pCShape, BulletShape paddShape, Vector3 displacementPos, Quaternion displacementRot)
{
IndexedMatrix relativeTransform = new IndexedMatrix();
- CompoundShape compoundshape = ((BulletShapeXNA)pCShape).shape as CompoundShape;
- CollisionShape addshape = ((BulletShapeXNA)paddShape).shape;
+ CompoundShape compoundshape = (pCShape as BulletShapeXNA).shape as CompoundShape;
+ CollisionShape addshape = (paddShape as BulletShapeXNA).shape;
relativeTransform._origin = new IndexedVector3(displacementPos.X, displacementPos.Y, displacementPos.Z);
relativeTransform.SetRotation(new IndexedQuaternion(displacementRot.X,displacementRot.Y,displacementRot.Z,displacementRot.W));
@@ -1203,7 +1391,7 @@ private sealed class BulletConstraintXNA : BulletConstraint
public override BulletShape RemoveChildShapeFromCompoundShapeIndex(BulletShape pCShape, int pii)
{
- CompoundShape compoundshape = ((BulletShapeXNA)pCShape).shape as CompoundShape;
+ CompoundShape compoundshape = (pCShape as BulletShapeXNA).shape as CompoundShape;
CollisionShape ret = null;
ret = compoundshape.GetChildShape(pii);
compoundshape.RemoveChildShapeByIndex(pii);
@@ -1222,12 +1410,12 @@ private sealed class BulletConstraintXNA : BulletConstraint
return new BulletShapeXNA(m_planeshape, BSPhysicsShapeType.SHAPE_GROUNDPLANE);
}
- public override BulletConstraint CreateHingeConstraint(BulletWorld pWorld, BulletBody pBody1, BulletBody ppBody2, Vector3 ppivotInA, Vector3 ppivotInB, Vector3 paxisInA, Vector3 paxisInB, bool puseLinearReferenceFrameA, bool pdisableCollisionsBetweenLinkedBodies)
+ public override BulletConstraint CreateHingeConstraint(BulletWorld pWorld, BulletBody pBody1, BulletBody pBody2, Vector3 ppivotInA, Vector3 ppivotInB, Vector3 paxisInA, Vector3 paxisInB, bool puseLinearReferenceFrameA, bool pdisableCollisionsBetweenLinkedBodies)
{
HingeConstraint constrain = null;
- DiscreteDynamicsWorld world = ((BulletWorldXNA)pWorld).world;
- RigidBody rb1 = ((BulletBodyXNA)pBody1).rigidBody;
- RigidBody rb2 = ((BulletBodyXNA)ppBody2).rigidBody;
+ DiscreteDynamicsWorld world = (pWorld as BulletWorldXNA).world;
+ RigidBody rb1 = (pBody1 as BulletBodyXNA).rigidBody;
+ RigidBody rb2 = (pBody2 as BulletBodyXNA).rigidBody;
if (rb1 != null && rb2 != null)
{
IndexedVector3 pivotInA = new IndexedVector3(ppivotInA.X, ppivotInA.Y, ppivotInA.Z);
@@ -1241,7 +1429,7 @@ private sealed class BulletConstraintXNA : BulletConstraint
public override BulletShape CreateHullShape(BulletWorld pWorld, int pHullCount, float[] pConvHulls)
{
- DiscreteDynamicsWorld world = ((BulletWorldXNA)pWorld).world;
+ DiscreteDynamicsWorld world = (pWorld as BulletWorldXNA).world;
CompoundShape compoundshape = new CompoundShape(false);
compoundshape.SetMargin(world.WorldSettings.Params.collisionMargin);
@@ -1271,7 +1459,11 @@ private sealed class BulletConstraintXNA : BulletConstraint
return new BulletShapeXNA(compoundshape, BSPhysicsShapeType.SHAPE_HULL);
}
- public override BulletShape BuildHullShapeFromMesh(BulletWorld world, BulletShape meshShape) { /* TODO */ return null; }
+ public override BulletShape BuildHullShapeFromMesh(BulletWorld world, BulletShape meshShape)
+ {
+ /* TODO */ return null;
+
+ }
public override BulletShape CreateMeshShape(BulletWorld pWorld, int pIndicesCount, int[] indices, int pVerticesCount, float[] verticesAsFloats)
{
@@ -1286,7 +1478,7 @@ private sealed class BulletConstraintXNA : BulletConstraint
ObjectArray indicesarr = new ObjectArray(indices);
ObjectArray vertices = new ObjectArray(verticesAsFloats);
DumpRaw(indicesarr,vertices,pIndicesCount,pVerticesCount);
- DiscreteDynamicsWorld world = ((BulletWorldXNA)pWorld).world;
+ DiscreteDynamicsWorld world = (pWorld as BulletWorldXNA).world;
IndexedMesh mesh = new IndexedMesh();
mesh.m_indexType = PHY_ScalarType.PHY_INTEGER;
mesh.m_numTriangles = pIndicesCount/3;
@@ -1402,7 +1594,7 @@ private sealed class BulletConstraintXNA : BulletConstraint
public override bool TranslationalLimitMotor(BulletConstraint pConstraint, float ponOff, float targetVelocity, float maxMotorForce)
{
- TypedConstraint tconstrain = ((BulletConstraintXNA)pConstraint).constrain;
+ TypedConstraint tconstrain = (pConstraint as BulletConstraintXNA).constrain;
bool onOff = ponOff != 0;
bool ret = false;
@@ -1428,47 +1620,45 @@ private sealed class BulletConstraintXNA : BulletConstraint
/* TODO */
updatedEntityCount = 0;
collidersCount = 0;
- return 1;
+
+
+ int ret = PhysicsStep2(world,timeStep,maxSubSteps,fixedTimeStep,out updatedEntityCount,out world.physicsScene.m_updateArray, out collidersCount, out world.physicsScene.m_collisionArray);
+
+ return ret;
}
private int PhysicsStep2(BulletWorld pWorld, float timeStep, int m_maxSubSteps, float m_fixedTimeStep,
- out int updatedEntityCount, out List updatedEntities,
- out int collidersCount, out Listcolliders)
+ out int updatedEntityCount, out EntityProperties[] updatedEntities,
+ out int collidersCount, out CollisionDesc[] colliders)
{
int epic = PhysicsStepint(pWorld, timeStep, m_maxSubSteps, m_fixedTimeStep, out updatedEntityCount, out updatedEntities,
- out collidersCount, out colliders);
+ out collidersCount, out colliders, m_maxCollisions, m_maxUpdatesPerFrame);
return epic;
}
- private static int PhysicsStepint(BulletWorld pWorld,float timeStep, int m_maxSubSteps, float m_fixedTimeStep, out int updatedEntityCount, out List updatedEntities, out int collidersCount, out List colliders)
+ private static int PhysicsStepint(BulletWorld pWorld,float timeStep, int m_maxSubSteps, float m_fixedTimeStep, out int updatedEntityCount,
+ out EntityProperties[] updatedEntities, out int collidersCount, out CollisionDesc[] colliders, int maxCollisions, int maxUpdates)
{
int numSimSteps = 0;
-
- //if (updatedEntities is null)
- // updatedEntities = new List();
-
- //if (colliders is null)
- // colliders = new List();
+ updatedEntityCount = 0;
+ collidersCount = 0;
if (pWorld is BulletWorldXNA)
{
- DiscreteDynamicsWorld world = ((BulletWorldXNA)pWorld).world;
+ DiscreteDynamicsWorld world = (pWorld as BulletWorldXNA).world;
+ world.LastCollisionDesc = 0;
+ world.LastEntityProperty = 0;
+ world.UpdatedObjects = new BulletXNA.EntityProperties[maxUpdates];
+ world.UpdatedCollisions = new BulletXNA.CollisionDesc[maxCollisions];
numSimSteps = world.StepSimulation(timeStep, m_maxSubSteps, m_fixedTimeStep);
int updates = 0;
- updatedEntityCount = world.UpdatedObjects.Count;
- updatedEntities = new List(world.UpdatedObjects);
- updatedEntityCount = updatedEntities.Count;
- world.UpdatedObjects.Clear();
+
- collidersCount = world.UpdatedCollisions.Count;
- colliders = new List(world.UpdatedCollisions);
-
- world.UpdatedCollisions.Clear();
m_collisionsThisFrame = 0;
int numManifolds = world.GetDispatcher().GetNumManifolds();
for (int j = 0; j < numManifolds; j++)
@@ -1493,16 +1683,31 @@ private sealed class BulletConstraintXNA : BulletConstraint
}
+ updatedEntityCount = world.LastEntityProperty;
+ updatedEntities = GetBulletSimEntityStruct(BulletXNAEntityStructToByteArray(world.UpdatedObjects, world.LastEntityProperty));
+
+
+
+
+ collidersCount = world.LastCollisionDesc;
+ colliders =
+ GetBulletSimCollisionStruct(BulletXNACollisionStructToByteArray(world.UpdatedCollisions, world.LastCollisionDesc));//new List(world.UpdatedCollisions);
}
else
{
//if (updatedEntities is null)
- updatedEntities = new List();
- updatedEntityCount = 0;
+ //updatedEntities = new List();
+ //updatedEntityCount = 0;
//if (colliders is null)
- colliders = new List();
- collidersCount = 0;
+ //colliders = new List();
+ //collidersCount = 0;
+
+ updatedEntities = new EntityProperties[0];
+
+
+ colliders = new CollisionDesc[0];
+
}
return numSimSteps;
}
@@ -1535,22 +1740,23 @@ private sealed class BulletConstraintXNA : BulletConstraint
point = contact,
normal = contactNormal
};
- world.UpdatedCollisions.Add(cDesc);
+ if (world.LastCollisionDesc < world.UpdatedCollisions.Length)
+ world.UpdatedCollisions[world.LastCollisionDesc++] = (cDesc);
m_collisionsThisFrame++;
}
- private static EntityProperties GetDebugProperties(BulletWorld pWorld, BulletBody pBody)
+ private static EntityProperties GetDebugProperties(BulletWorld pWorld, BulletBody pCollisionObject)
{
EntityProperties ent = new EntityProperties();
- DiscreteDynamicsWorld world = ((BulletWorldXNA)pWorld).world;
- RigidBody body = ((BulletBodyXNA)pBody).rigidBody;
- IndexedMatrix transform = body.GetWorldTransform();
- IndexedVector3 LinearVelocity = body.GetInterpolationLinearVelocity();
- IndexedVector3 AngularVelocity = body.GetInterpolationAngularVelocity();
+ DiscreteDynamicsWorld world = (pWorld as BulletWorldXNA).world;
+ CollisionObject collisionObject = (pCollisionObject as BulletBodyXNA).rigidBody;
+ IndexedMatrix transform = collisionObject.GetWorldTransform();
+ IndexedVector3 LinearVelocity = collisionObject.GetInterpolationLinearVelocity();
+ IndexedVector3 AngularVelocity = collisionObject.GetInterpolationAngularVelocity();
IndexedQuaternion rotation = transform.GetRotation();
ent.Acceleration = Vector3.Zero;
- ent.ID = (uint)body.GetUserPointer();
+ ent.ID = (uint)collisionObject.GetUserPointer();
ent.Position = new Vector3(transform._origin.X,transform._origin.Y,transform._origin.Z);
ent.Rotation = new Quaternion(rotation.X,rotation.Y,rotation.Z,rotation.W);
ent.Velocity = new Vector3(LinearVelocity.X, LinearVelocity.Y, LinearVelocity.Z);
@@ -1562,19 +1768,19 @@ private sealed class BulletConstraintXNA : BulletConstraint
public override Vector3 GetLocalScaling(BulletShape pShape)
{
- CollisionShape shape = ((BulletShapeXNA)pShape).shape;
+ CollisionShape shape = (pShape as BulletShapeXNA).shape;
IndexedVector3 scale = shape.GetLocalScaling();
return new Vector3(scale.X,scale.Y,scale.Z);
}
public bool RayCastGround(BulletWorld pWorld, Vector3 _RayOrigin, float pRayHeight, BulletBody NotMe)
{
- DiscreteDynamicsWorld world = ((BulletWorldXNA)pWorld).world;
+ DiscreteDynamicsWorld world = (pWorld as BulletWorldXNA).world;
if (world != null)
{
if (NotMe is BulletBodyXNA && NotMe.HasPhysicalBody)
{
- CollisionObject AvoidBody = ((BulletBodyXNA)NotMe).body;
+ CollisionObject AvoidBody = (NotMe as BulletBodyXNA).body;
IndexedVector3 rOrigin = new IndexedVector3(_RayOrigin.X, _RayOrigin.Y, _RayOrigin.Z);
IndexedVector3 rEnd = new IndexedVector3(_RayOrigin.X, _RayOrigin.Y, _RayOrigin.Z - pRayHeight);
@@ -1594,5 +1800,160 @@ private sealed class BulletConstraintXNA : BulletConstraint
}
return false;
}
+
+ public static unsafe BulletXNA.CollisionDesc[] GetBulletXNACollisionStruct(byte[] buffer)
+ {
+ int count = buffer.Length/sizeof (BulletXNA.CollisionDesc);
+ BulletXNA.CollisionDesc[] result = new BulletXNA.CollisionDesc[count];
+ BulletXNA.CollisionDesc* ptr;
+ fixed (byte* localBytes = new byte[buffer.Length])
+ {
+ for (int i = 0; i < buffer.Length; i++)
+ {
+ localBytes[i] = buffer[i];
+ }
+ for (int i=0;i count ? count : CollisionDescArray.Length;
+ byte[] byteArray = new byte[sizeof(CollisionDesc) * arrayLength];
+ fixed (CollisionDesc* floatPointer = CollisionDescArray)
+ {
+ fixed (byte* bytePointer = byteArray)
+ {
+ CollisionDesc* read = floatPointer;
+ CollisionDesc* write = (CollisionDesc*)bytePointer;
+ for (int i = 0; i < arrayLength; i++)
+ {
+ *write++ = *read++;
+ }
+ }
+ }
+ return byteArray;
+ }
+ public static unsafe byte[] BulletXNACollisionStructToByteArray(BulletXNA.CollisionDesc[] CollisionDescArray, int count)
+ {
+ int arrayLength = CollisionDescArray.Length > count ? count : CollisionDescArray.Length;
+ byte[] byteArray = new byte[sizeof(BulletXNA.CollisionDesc) * arrayLength];
+ fixed (BulletXNA.CollisionDesc* floatPointer = CollisionDescArray)
+ {
+ fixed (byte* bytePointer = byteArray)
+ {
+ BulletXNA.CollisionDesc* read = floatPointer;
+ BulletXNA.CollisionDesc* write = (BulletXNA.CollisionDesc*)bytePointer;
+ for (int i = 0; i < arrayLength; i++)
+ {
+ *write++ = *read++;
+ }
+ }
+ }
+ return byteArray;
+ }
+ public static unsafe BulletXNA.EntityProperties[] GetBulletXNAEntityStruct(byte[] buffer)
+ {
+ int count = buffer.Length / sizeof(BulletXNA.EntityProperties);
+ BulletXNA.EntityProperties[] result = new BulletXNA.EntityProperties[count];
+ BulletXNA.EntityProperties* ptr;
+ fixed (byte* localBytes = new byte[buffer.Length])
+ {
+ for (int i = 0; i < buffer.Length; i++)
+ {
+ localBytes[i] = buffer[i];
+ }
+ for (int i = 0; i < count; i++)
+ {
+ ptr = (BulletXNA.EntityProperties*)(localBytes + sizeof(BulletXNA.EntityProperties) * i);
+ result[i] = new BulletXNA.EntityProperties();
+ result[i] = *ptr;
+ }
+ }
+ return result;
+ }
+
+ public static unsafe EntityProperties[] GetBulletSimEntityStruct(byte[] buffer)
+ {
+ int count = buffer.Length / sizeof(EntityProperties);
+ EntityProperties[] result = new EntityProperties[count];
+ EntityProperties* ptr;
+ fixed (byte* localBytes = new byte[buffer.Length])
+ {
+ for (int i = 0; i < buffer.Length; i++)
+ {
+ localBytes[i] = buffer[i];
+ }
+ for (int i = 0; i < count; i++)
+ {
+ ptr = (EntityProperties*)(localBytes + sizeof(EntityProperties) * i);
+ result[i] = new EntityProperties();
+ result[i] = *ptr;
+ }
+ }
+ return result;
+ }
+ public static unsafe byte[] BulletSimEntityStructToByteArray(EntityProperties[] CollisionDescArray, int count)
+ {
+ int arrayLength = CollisionDescArray.Length > count ? count : CollisionDescArray.Length;
+ byte[] byteArray = new byte[sizeof(EntityProperties) * arrayLength];
+ fixed (EntityProperties* floatPointer = CollisionDescArray)
+ {
+ fixed (byte* bytePointer = byteArray)
+ {
+ EntityProperties* read = floatPointer;
+ EntityProperties* write = (EntityProperties*)bytePointer;
+ for (int i = 0; i < arrayLength; i++)
+ {
+ *write++ = *read++;
+ }
+ }
+ }
+ return byteArray;
+ }
+ public static unsafe byte[] BulletXNAEntityStructToByteArray(BulletXNA.EntityProperties[] CollisionDescArray, int count)
+ {
+ int arrayLength = CollisionDescArray.Length > count ? count : CollisionDescArray.Length;
+ byte[] byteArray = new byte[sizeof(BulletXNA.EntityProperties) * arrayLength];
+ fixed (BulletXNA.EntityProperties* floatPointer = CollisionDescArray)
+ {
+ fixed (byte* bytePointer = byteArray)
+ {
+ BulletXNA.EntityProperties* read = floatPointer;
+ BulletXNA.EntityProperties* write = (BulletXNA.EntityProperties*)bytePointer;
+ for (int i = 0; i < arrayLength; i++)
+ {
+ *write++ = *read++;
+ }
+ }
+ }
+ return byteArray;
+ }
}
}
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
index 6d5e23f7d9..76032541ef 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
@@ -56,6 +56,7 @@ public sealed class BSCharacter : BSPhysObject
private int _physicsActorType;
private bool _isPhysical;
private bool _flying;
+ private bool _wasWalking; // 'true' if the avatar was walking/moving last frame
private bool _setAlwaysRun;
private bool _throttleUpdates;
private bool _floatOnWater;
@@ -83,6 +84,7 @@ public sealed class BSCharacter : BSPhysObject
_position = pos;
_flying = isFlying;
+ _wasWalking = true; // causes first step to initialize standing
_orientation = OMV.Quaternion.Identity;
_velocity = OMV.Vector3.Zero;
_buoyancy = ComputeBuoyancyFromFlying(isFlying);
@@ -198,25 +200,68 @@ public sealed class BSCharacter : BSPhysObject
// TODO: Decide if the step parameters should be changed depending on the avatar's
// state (flying, colliding, ...). There is code in ODE to do this.
- OMV.Vector3 stepVelocity = _velocityMotor.Step(timeStep);
+ // COMMENTARY: when the user is making the avatar walk, except for falling, the velocity
+ // specified for the avatar is the one that should be used. For falling, if the avatar
+ // is not flying and is not colliding then it is presumed to be falling and the Z
+ // component is not fooled with (thus allowing gravity to do its thing).
+ // When the avatar is standing, though, the user has specified a velocity of zero and
+ // the avatar should be standing. But if the avatar is pushed by something in the world
+ // (raising elevator platform, moving vehicle, ...) the avatar should be allowed to
+ // move. Thus, the velocity cannot be forced to zero. The problem is that small velocity
+ // errors can creap in and the avatar will slowly float off in some direction.
+ // So, the problem is that, when an avatar is standing, we cannot tell creaping error
+ // from real pushing.OMV.Vector3.Zero;
+ // The code below keeps setting the velocity to zero hoping the world will keep pushing.
- // If falling, we keep the world's downward vector no matter what the other axis specify.
- if (!Flying && !IsColliding)
+ _velocityMotor.Step(timeStep);
+
+ // If we're not supposed to be moving, make sure things are zero.
+ if (_velocityMotor.ErrorIsZero() && _velocityMotor.TargetValue == OMV.Vector3.Zero && IsColliding)
{
- stepVelocity.Z = _velocity.Z;
- // DetailLog("{0},BSCharacter.MoveMotor,taint,overrideStepZWithWorldZ,stepVel={1}", LocalID, stepVelocity);
+ // The avatar shouldn't be moving
+ _velocityMotor.Zero();
+ ZeroMotion(true /* inTaintTime */);
+
+ // Standing has more friction on the ground
+ if (_currentFriction != BSParam.AvatarStandingFriction)
+ {
+ _currentFriction = BSParam.AvatarStandingFriction;
+ PhysicsScene.PE.SetFriction(PhysBody, _currentFriction);
+ }
+ DetailLog("{0},BSCharacter.MoveMotor,taint,stopping,target={1}", LocalID, _velocityMotor.TargetValue);
+
+ _wasWalking = false;
}
+ else
+ {
+ OMV.Vector3 stepVelocity = _velocityMotor.CurrentValue;
- // 'stepVelocity' is now the speed we'd like the avatar to move in. Turn that into an instantanous force.
- OMV.Vector3 moveForce = (stepVelocity - _velocity) * Mass;
+ if (_currentFriction != BSParam.AvatarFriction)
+ {
+ // Probably starting up walking. Set friction to moving friction.
+ _currentFriction = BSParam.AvatarFriction;
+ PhysicsScene.PE.SetFriction(PhysBody, _currentFriction);
+ }
- // Should we check for move force being small and forcing velocity to zero?
+ // If falling, we keep the world's downward vector no matter what the other axis specify.
+ if (!Flying && !IsColliding)
+ {
+ stepVelocity.Z = _velocity.Z;
+ // DetailLog("{0},BSCharacter.MoveMotor,taint,overrideStepZWithWorldZ,stepVel={1}", LocalID, stepVelocity);
+ }
- // Add special movement force to allow avatars to walk up stepped surfaces.
- moveForce += WalkUpStairs();
+ // 'stepVelocity' is now the speed we'd like the avatar to move in. Turn that into an instantanous force.
+ OMV.Vector3 moveForce = (stepVelocity - _velocity) * Mass;
- // DetailLog("{0},BSCharacter.MoveMotor,move,stepVel={1},vel={2},mass={3},moveForce={4}", LocalID, stepVelocity, _velocity, Mass, moveForce);
- PhysicsScene.PE.ApplyCentralImpulse(PhysBody, moveForce);
+ // Should we check for move force being small and forcing velocity to zero?
+
+ // Add special movement force to allow avatars to walk up stepped surfaces.
+ moveForce += WalkUpStairs();
+
+ DetailLog("{0},BSCharacter.MoveMotor,move,stepVel={1},vel={2},mass={3},moveForce={4}", LocalID, stepVelocity, _velocity, Mass, moveForce);
+ PhysicsScene.PE.ApplyCentralImpulse(PhysBody, moveForce);
+ _wasWalking = true;
+ }
});
}
@@ -559,27 +604,6 @@ public sealed class BSCharacter : BSPhysObject
PhysicsScene.AssertInTaintTime("BSCharacter.ForceVelocity");
_velocity = value;
- // Depending on whether the avatar is moving or not, change the friction
- // to keep the avatar from slipping around
- if (_velocity.Length() == 0)
- {
- if (_currentFriction != BSParam.AvatarStandingFriction)
- {
- _currentFriction = BSParam.AvatarStandingFriction;
- if (PhysBody.HasPhysicalBody)
- PhysicsScene.PE.SetFriction(PhysBody, _currentFriction);
- }
- }
- else
- {
- if (_currentFriction != BSParam.AvatarFriction)
- {
- _currentFriction = BSParam.AvatarFriction;
- if (PhysBody.HasPhysicalBody)
- PhysicsScene.PE.SetFriction(PhysBody, _currentFriction);
- }
- }
-
PhysicsScene.PE.SetLinearVelocity(PhysBody, _velocity);
PhysicsScene.PE.Activate(PhysBody, true);
}
@@ -853,7 +877,14 @@ public sealed class BSCharacter : BSPhysObject
{
_position = entprop.Position;
_orientation = entprop.Rotation;
- _velocity = entprop.Velocity;
+
+ // Smooth velocity. OpenSimulator is VERY sensitive to changes in velocity of the avatar
+ // and will send agent updates to the clients if velocity changes by more than
+ // 0.001m/s. Bullet introduces a lot of jitter in the velocity which causes many
+ // extra updates.
+ if (!entprop.Velocity.ApproxEquals(_velocity, 0.1f))
+ _velocity = entprop.Velocity;
+
_acceleration = entprop.Acceleration;
_rotationalVelocity = entprop.RotationalVelocity;
@@ -868,7 +899,7 @@ public sealed class BSCharacter : BSPhysObject
CurrentEntityProperties = entprop;
// Tell the linkset about value changes
- Linkset.UpdateProperties(this, true);
+ Linkset.UpdateProperties(UpdatedProperties.EntPropUpdates, this);
// Avatars don't report their changes the usual way. Changes are checked for in the heartbeat loop.
// base.RequestPhysicsterseUpdate();
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs
index f2c7cec0b3..dbe44de5f4 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs
@@ -231,6 +231,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
break;
case Vehicle.ANGULAR_MOTOR_DIRECTION:
m_angularMotorDirection = new Vector3(pValue, pValue, pValue);
+ m_angularMotor.Zero();
m_angularMotor.SetTarget(m_angularMotorDirection);
break;
case Vehicle.LINEAR_FRICTION_TIMESCALE:
@@ -264,6 +265,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
pValue.Y = ClampInRange(-12.56f, pValue.Y, 12.56f);
pValue.Z = ClampInRange(-12.56f, pValue.Z, 12.56f);
m_angularMotorDirection = new Vector3(pValue.X, pValue.Y, pValue.Z);
+ m_angularMotor.Zero();
m_angularMotor.SetTarget(m_angularMotorDirection);
break;
case Vehicle.LINEAR_FRICTION_TIMESCALE:
@@ -720,10 +722,12 @@ namespace OpenSim.Region.Physics.BulletSPlugin
// Since the computation of terrain height can be a little involved, this routine
// is used to fetch the height only once for each vehicle simulation step.
+ Vector3 lastRememberedHeightPos;
private float GetTerrainHeight(Vector3 pos)
{
- if ((m_knownHas & m_knownChangedTerrainHeight) == 0)
+ if ((m_knownHas & m_knownChangedTerrainHeight) == 0 || pos != lastRememberedHeightPos)
{
+ lastRememberedHeightPos = pos;
m_knownTerrainHeight = Prim.PhysicsScene.TerrainManager.GetTerrainHeightAtXYZ(pos);
m_knownHas |= m_knownChangedTerrainHeight;
}
@@ -943,10 +947,10 @@ namespace OpenSim.Region.Physics.BulletSPlugin
// ==================================================================
// Clamp high or low velocities
float newVelocityLengthSq = VehicleVelocity.LengthSquared();
- if (newVelocityLengthSq > 1000f)
+ if (newVelocityLengthSq > BSParam.VehicleMaxLinearVelocity)
{
VehicleVelocity /= VehicleVelocity.Length();
- VehicleVelocity *= 1000f;
+ VehicleVelocity *= BSParam.VehicleMaxLinearVelocity;
}
else if (newVelocityLengthSq < 0.001f)
VehicleVelocity = Vector3.Zero;
@@ -957,39 +961,25 @@ namespace OpenSim.Region.Physics.BulletSPlugin
public void ComputeLinearVelocity(float pTimestep)
{
- Vector3 linearMotorStep = m_linearMotor.Step(pTimestep);
+ // Step the motor from the current value. Get the correction needed this step.
+ Vector3 currentVel = VehicleVelocity * Quaternion.Inverse(VehicleOrientation);
+ Vector3 linearMotorCorrection = m_linearMotor.Step(pTimestep, currentVel);
- // The movement computed in the linear motor is relative to the vehicle
- // coordinates. Rotate the movement to world coordinates.
- Vector3 linearMotorVelocity = linearMotorStep * VehicleOrientation;
+ // Motor is vehicle coordinates. Rotate it to world coordinates
+ Vector3 linearMotorVelocity = linearMotorCorrection * VehicleOrientation;
- // If we're a ground vehicle, don't loose any Z action (like gravity acceleration).
- float mixFactor = 1f; // 1 means use all linear motor Z value, 0 means use all existing Z
+ // If we're a ground vehicle, don't add any upward Z movement
if ((m_flags & VehicleFlag.LIMIT_MOTOR_UP) != 0)
{
- if (!Prim.IsColliding)
- {
- // If a ground vehicle and not on the ground, I want gravity effect
- mixFactor = 0.2f;
- }
+ if (linearMotorVelocity.Z > 0f)
+ linearMotorVelocity.Z = 0f;
}
- else
- {
- // I'm not a ground vehicle but don't totally loose the effect of the environment
- mixFactor = 0.8f;
- }
- linearMotorVelocity.Z = mixFactor * linearMotorVelocity.Z + (1f - mixFactor) * VehicleVelocity.Z;
- // What we want to contribute to the vehicle's existing velocity
- Vector3 linearMotorForce = linearMotorVelocity - VehicleVelocity;
+ // Add this correction to the velocity to make it faster/slower.
+ VehicleVelocity += linearMotorVelocity;
- // Act against the inertia of the vehicle
- linearMotorForce *= m_vehicleMass;
-
- VehicleAddForceImpulse(linearMotorForce * pTimestep);
-
- VDetailLog("{0}, MoveLinear,velocity,vehVel={1},step={2},stepVel={3},mix={4},force={5}",
- Prim.LocalID, VehicleVelocity, linearMotorStep, linearMotorVelocity, mixFactor, linearMotorForce);
+ VDetailLog("{0}, MoveLinear,velocity,vehVel={1},correction={2},force={3}",
+ Prim.LocalID, VehicleVelocity, linearMotorCorrection, linearMotorVelocity);
}
public void ComputeLinearTerrainHeightCorrection(float pTimestep)
@@ -1202,62 +1192,27 @@ namespace OpenSim.Region.Physics.BulletSPlugin
// set directly on the vehicle.
private void MoveAngular(float pTimestep)
{
- // The user wants this many radians per second angular change?
- Vector3 angularMotorContribution = m_angularMotor.Step(pTimestep);
+ // VehicleRotationalVelocity = Vector3.Zero;
+
+ ComputeAngularTurning(pTimestep);
+
+ ComputeAngularVerticalAttraction();
+
+ ComputeAngularDeflection();
+
+ ComputeAngularBanking();
// ==================================================================
- // From http://wiki.secondlife.com/wiki/LlSetVehicleFlags :
- // This flag prevents linear deflection parallel to world z-axis. This is useful
- // for preventing ground vehicles with large linear deflection, like bumper cars,
- // from climbing their linear deflection into the sky.
- // That is, NO_DEFLECTION_UP says angular motion should not add any pitch or roll movement
- // TODO: This is here because this is where ODE put it but documentation says it
- // is a linear effect. Where should this check go?
- if ((m_flags & (VehicleFlag.NO_DEFLECTION_UP)) != 0)
- {
- angularMotorContribution.X = 0f;
- angularMotorContribution.Y = 0f;
- VDetailLog("{0}, MoveAngular,noDeflectionUp,angularMotorContrib={1}", Prim.LocalID, angularMotorContribution);
- }
-
- Vector3 verticalAttractionContribution = ComputeAngularVerticalAttraction();
-
- Vector3 deflectionContribution = ComputeAngularDeflection();
-
- Vector3 bankingContribution = ComputeAngularBanking();
-
- // ==================================================================
- m_lastVertAttractor = verticalAttractionContribution;
-
- m_lastAngularVelocity = angularMotorContribution
- + verticalAttractionContribution
- + deflectionContribution
- + bankingContribution;
-
- // Add of the above computation are made relative to vehicle coordinates.
- // Convert to world coordinates.
- m_lastAngularVelocity *= VehicleOrientation;
-
- // ==================================================================
- // Apply the correction velocity.
- // TODO: Should this be applied as an angular force (torque)?
- if (!m_lastAngularVelocity.ApproxEquals(Vector3.Zero, 0.01f))
- {
- VehicleRotationalVelocity = m_lastAngularVelocity;
-
- VDetailLog("{0}, MoveAngular,done,nonZero,angMotorContrib={1},vertAttrContrib={2},bankContrib={3},deflectContrib={4},totalContrib={5}",
- Prim.LocalID,
- angularMotorContribution, verticalAttractionContribution,
- bankingContribution, deflectionContribution,
- m_lastAngularVelocity
- );
- }
- else
+ if (VehicleRotationalVelocity.ApproxEquals(Vector3.Zero, 0.01f))
{
// The vehicle is not adding anything angular wise.
VehicleRotationalVelocity = Vector3.Zero;
VDetailLog("{0}, MoveAngular,done,zero", Prim.LocalID);
}
+ else
+ {
+ VDetailLog("{0}, MoveAngular,done,nonZero,angVel={1}", Prim.LocalID, VehicleRotationalVelocity);
+ }
// ==================================================================
//Offset section
@@ -1291,6 +1246,31 @@ namespace OpenSim.Region.Physics.BulletSPlugin
}
}
+
+ private void ComputeAngularTurning(float pTimestep)
+ {
+ // The user wants this many radians per second angular change?
+ Vector3 currentAngular = VehicleRotationalVelocity * Quaternion.Inverse(VehicleOrientation);
+ Vector3 angularMotorContribution = m_angularMotor.Step(pTimestep, currentAngular);
+
+ // ==================================================================
+ // From http://wiki.secondlife.com/wiki/LlSetVehicleFlags :
+ // This flag prevents linear deflection parallel to world z-axis. This is useful
+ // for preventing ground vehicles with large linear deflection, like bumper cars,
+ // from climbing their linear deflection into the sky.
+ // That is, NO_DEFLECTION_UP says angular motion should not add any pitch or roll movement
+ // TODO: This is here because this is where ODE put it but documentation says it
+ // is a linear effect. Where should this check go?
+ if ((m_flags & (VehicleFlag.NO_DEFLECTION_UP)) != 0)
+ {
+ angularMotorContribution.X = 0f;
+ angularMotorContribution.Y = 0f;
+ }
+
+ VehicleRotationalVelocity += angularMotorContribution * VehicleOrientation;
+ VDetailLog("{0}, MoveAngular,angularTurning,angularMotorContrib={1}", Prim.LocalID, angularMotorContribution);
+ }
+
// From http://wiki.secondlife.com/wiki/Linden_Vehicle_Tutorial:
// Some vehicles, like boats, should always keep their up-side up. This can be done by
// enabling the "vertical attractor" behavior that springs the vehicle's local z-axis to
@@ -1299,13 +1279,13 @@ namespace OpenSim.Region.Physics.BulletSPlugin
// and then set the VEHICLE_VERTICAL_ATTRACTION_EFFICIENCY to control the damping. An
// efficiency of 0.0 will cause the spring to wobble around its equilibrium, while an
// efficiency of 1.0 will cause the spring to reach its equilibrium with exponential decay.
- public Vector3 ComputeAngularVerticalAttraction()
+ public void ComputeAngularVerticalAttraction()
{
- Vector3 ret = Vector3.Zero;
-
// If vertical attaction timescale is reasonable
if (enableAngularVerticalAttraction && m_verticalAttractionTimescale < m_verticalAttractionCutoff)
{
+ Vector3 vertContribution = Vector3.Zero;
+
// Take a vector pointing up and convert it from world to vehicle relative coords.
Vector3 verticalError = Vector3.UnitZ * VehicleOrientation;
@@ -1319,37 +1299,36 @@ namespace OpenSim.Region.Physics.BulletSPlugin
// Y error means needed rotation around X axis and visa versa.
// Since the error goes from zero to one, the asin is the corresponding angle.
- ret.X = (float)Math.Asin(verticalError.Y);
+ vertContribution.X = (float)Math.Asin(verticalError.Y);
// (Tilt forward (positive X) needs to tilt back (rotate negative) around Y axis.)
- ret.Y = -(float)Math.Asin(verticalError.X);
+ vertContribution.Y = -(float)Math.Asin(verticalError.X);
// If verticalError.Z is negative, the vehicle is upside down. Add additional push.
if (verticalError.Z < 0f)
{
- ret.X += PIOverFour;
- ret.Y += PIOverFour;
+ vertContribution.X += PIOverFour;
+ // vertContribution.Y -= PIOverFour;
}
- // 'ret' is now the necessary velocity to correct tilt in one second.
+ // 'vertContrbution' is now the necessary angular correction to correct tilt in one second.
// Correction happens over a number of seconds.
- Vector3 unscaledContrib = ret;
- ret /= m_verticalAttractionTimescale;
+ Vector3 unscaledContrib = vertContribution; // DEBUG DEBUG
+ vertContribution /= m_verticalAttractionTimescale;
+
+ VehicleRotationalVelocity += vertContribution * VehicleOrientation;
VDetailLog("{0}, MoveAngular,verticalAttraction,,verticalError={1},unscaled={2},eff={3},ts={4},vertAttr={5}",
- Prim.LocalID, verticalError, unscaledContrib, m_verticalAttractionEfficiency, m_verticalAttractionTimescale, ret);
+ Prim.LocalID, verticalError, unscaledContrib, m_verticalAttractionEfficiency, m_verticalAttractionTimescale, vertContribution);
}
- return ret;
}
- // Return the angular correction to correct the direction the vehicle is pointing to be
+ // Angular correction to correct the direction the vehicle is pointing to be
// the direction is should want to be pointing.
// The vehicle is moving in some direction and correct its orientation to it is pointing
// in that direction.
// TODO: implement reference frame.
- public Vector3 ComputeAngularDeflection()
+ public void ComputeAngularDeflection()
{
- Vector3 ret = Vector3.Zero;
-
// Since angularMotorUp and angularDeflection are computed independently, they will calculate
// approximately the same X or Y correction. When added together (when contributions are combined)
// this creates an over-correction and then wabbling as the target is overshot.
@@ -1357,6 +1336,8 @@ namespace OpenSim.Region.Physics.BulletSPlugin
if (enableAngularDeflection && m_angularDeflectionEfficiency != 0 && VehicleForwardSpeed > 0.2)
{
+ Vector3 deflectContribution = Vector3.Zero;
+
// The direction the vehicle is moving
Vector3 movingDirection = VehicleVelocity;
movingDirection.Normalize();
@@ -1382,18 +1363,19 @@ namespace OpenSim.Region.Physics.BulletSPlugin
// ret = m_angularDeflectionCorrectionMotor(1f, deflectionError);
// Scale the correction by recovery timescale and efficiency
- ret = (-deflectionError) * m_angularDeflectionEfficiency;
- ret /= m_angularDeflectionTimescale;
+ deflectContribution = (-deflectionError) * m_angularDeflectionEfficiency;
+ deflectContribution /= m_angularDeflectionTimescale;
+
+ VehicleRotationalVelocity += deflectContribution * VehicleOrientation;
VDetailLog("{0}, MoveAngular,Deflection,movingDir={1},pointingDir={2},deflectError={3},ret={4}",
- Prim.LocalID, movingDirection, pointingDirection, deflectionError, ret);
+ Prim.LocalID, movingDirection, pointingDirection, deflectionError, deflectContribution);
VDetailLog("{0}, MoveAngular,Deflection,fwdSpd={1},defEff={2},defTS={3}",
Prim.LocalID, VehicleForwardSpeed, m_angularDeflectionEfficiency, m_angularDeflectionTimescale);
}
- return ret;
}
- // Return an angular change to rotate the vehicle around the Z axis when the vehicle
+ // Angular change to rotate the vehicle around the Z axis when the vehicle
// is tipped around the X axis.
// From http://wiki.secondlife.com/wiki/Linden_Vehicle_Tutorial:
// The vertical attractor feature must be enabled in order for the banking behavior to
@@ -1424,12 +1406,12 @@ namespace OpenSim.Region.Physics.BulletSPlugin
// world z-axis is determined by the VEHICLE_BANKING_TIMESCALE. So if you want the vehicle to
// bank quickly then give it a banking timescale of about a second or less, otherwise you can
// make a sluggish vehicle by giving it a timescale of several seconds.
- public Vector3 ComputeAngularBanking()
+ public void ComputeAngularBanking()
{
- Vector3 ret = Vector3.Zero;
-
if (enableAngularBanking && m_bankingEfficiency != 0 && m_verticalAttractionTimescale < m_verticalAttractionCutoff)
{
+ Vector3 bankingContribution = Vector3.Zero;
+
// Rotate a UnitZ vector (pointing up) to how the vehicle is oriented.
// As the vehicle rolls to the right or left, the Y value will increase from
// zero (straight up) to 1 or -1 (full tilt right or left)
@@ -1446,15 +1428,16 @@ namespace OpenSim.Region.Physics.BulletSPlugin
mixedYawAngle = ClampInRange(-20f, mixedYawAngle, 20f);
// Build the force vector to change rotation from what it is to what it should be
- ret.Z = -mixedYawAngle;
+ bankingContribution.Z = -mixedYawAngle;
// Don't do it all at once.
- ret /= m_bankingTimescale;
+ bankingContribution /= m_bankingTimescale;
+
+ VehicleRotationalVelocity += bankingContribution * VehicleOrientation;
VDetailLog("{0}, MoveAngular,Banking,rollComp={1},speed={2},rollComp={3},yAng={4},mYAng={5},ret={6}",
- Prim.LocalID, rollComponents, VehicleForwardSpeed, rollComponents, yawAngle, mixedYawAngle, ret);
+ Prim.LocalID, rollComponents, VehicleForwardSpeed, rollComponents, yawAngle, mixedYawAngle, bankingContribution);
}
- return ret;
}
// This is from previous instantiations of XXXDynamics.cs.
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs
index cbd160fb81..580ea4e689 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs
@@ -252,7 +252,7 @@ public abstract class BSLinkset
// of the linkset is received.
// Passed flag is update came from physics engine (true) or the user (false).
// Called at taint-time!!
- public abstract void UpdateProperties(BSPhysObject physObject, bool physicalUpdate);
+ public abstract void UpdateProperties(UpdatedProperties whichUpdated, BSPhysObject physObject);
// Routine used when rebuilding the body of the root of the linkset
// Destroy all the constraints have have been made to root.
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs
index 8c9a7745f0..27d8ad0ef9 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs
@@ -51,6 +51,21 @@ sealed class BSLinksetCompoundInfo : BSLinksetInfo
OffsetFromCenterOfMass = p;
OffsetRot = r;
}
+ // 'centerDisplacement' is the distance from the root the the center-of-mass (Bullet 'zero' of the shape)
+ public BSLinksetCompoundInfo(int indx, BSPhysObject root, BSPhysObject child, OMV.Vector3 centerDisplacement)
+ {
+ // Each child position and rotation is given relative to the center-of-mass.
+ OMV.Quaternion invRootOrientation = OMV.Quaternion.Inverse(root.RawOrientation);
+ OMV.Vector3 displacementFromRoot = (child.RawPosition - root.RawPosition) * invRootOrientation;
+ OMV.Vector3 displacementFromCOM = displacementFromRoot - centerDisplacement;
+ OMV.Quaternion displacementRot = child.RawOrientation * invRootOrientation;
+
+ // Save relative position for recomputing child's world position after moving linkset.
+ Index = indx;
+ OffsetFromRoot = displacementFromRoot;
+ OffsetFromCenterOfMass = displacementFromCOM;
+ OffsetRot = displacementRot;
+ }
public override void Clear()
{
Index = 0;
@@ -182,24 +197,71 @@ public sealed class BSLinksetCompound : BSLinkset
// 'physicalUpdate' is true if these changes came directly from the physics engine. Don't need to rebuild then.
// Called at taint-time.
- public override void UpdateProperties(BSPhysObject updated, bool physicalUpdate)
+ public override void UpdateProperties(UpdatedProperties whichUpdated, BSPhysObject updated)
{
// The user moving a child around requires the rebuilding of the linkset compound shape
// One problem is this happens when a border is crossed -- the simulator implementation
- // is to store the position into the group which causes the move of the object
+ // stores the position into the group which causes the move of the object
// but it also means all the child positions get updated.
// What would cause an unnecessary rebuild so we make sure the linkset is in a
// region before bothering to do a rebuild.
- if (!IsRoot(updated)
- && !physicalUpdate
- && PhysicsScene.TerrainManager.IsWithinKnownTerrain(LinksetRoot.RawPosition))
+ if (!IsRoot(updated) && PhysicsScene.TerrainManager.IsWithinKnownTerrain(LinksetRoot.RawPosition))
{
- // TODO: replace this with are calculation of the child prim's orientation and pos.
- // TODO: for the moment, don't rebuild the compound shape.
- // This is often just the car turning its wheels. When we can just reorient the one
- // member shape of the compound shape, the overhead of rebuilding won't be a problem.
- // updated.LinksetInfo = null;
- // ScheduleRebuild(updated);
+ // If a child of the linkset is updating only the position or rotation, that can be done
+ // without rebuilding the linkset.
+ // If a handle for the child can be fetch, we update the child here. If a rebuild was
+ // scheduled by someone else, the rebuild will just replace this setting.
+
+ bool updatedChild = false;
+ // Anything other than updating position or orientation usually means a physical update
+ // and that is caused by us updating the object.
+ if ((whichUpdated & ~(UpdatedProperties.Position | UpdatedProperties.Orientation)) == 0)
+ {
+ // Gather the child info. It might not be there if the linkset is in transition.
+ BSLinksetCompoundInfo lsi = updated.LinksetInfo as BSLinksetCompoundInfo;
+ if (LinksetRoot.PhysShape.HasPhysicalShape && lsi != null)
+ {
+ if (PhysicsScene.PE.IsCompound(LinksetRoot.PhysShape))
+ {
+ BulletShape linksetChildShape = PhysicsScene.PE.GetChildShapeFromCompoundShapeIndex(LinksetRoot.PhysShape, lsi.Index);
+ if (linksetChildShape.HasPhysicalShape)
+ {
+ // Compute the offset from the center-of-gravity
+ BSLinksetCompoundInfo newLsi = new BSLinksetCompoundInfo(lsi.Index, LinksetRoot, updated, LinksetRoot.PositionDisplacement);
+ PhysicsScene.PE.UpdateChildTransform(LinksetRoot.PhysShape, lsi.Index,
+ newLsi.OffsetFromCenterOfMass,
+ newLsi.OffsetRot,
+ true /* shouldRecalculateLocalAabb */);
+ DetailLog("{0},BSLinksetCompound.UpdateProperties,changeChildPosRot,whichUpdated={1}newLsi={2}",
+ updated.LocalID, whichUpdated, newLsi);
+ updated.LinksetInfo = newLsi;
+ updatedChild = true;
+ }
+ else // DEBUG DEBUG
+ { // DEBUG DEBUG
+ DetailLog("{0},BSLinksetCompound.UpdateProperties,couldNotUpdateChild,noChildShape,shape={1}",
+ updated.LocalID, linksetChildShape);
+ } // DEBUG DEBUG
+ }
+ else // DEBUG DEBUG
+ { // DEBUG DEBUG
+ DetailLog("{0},BSLinksetCompound.UpdateProperties,couldNotUpdateChild,notCompound", updated.LocalID);
+ } // DEBUG DEBUG
+ }
+ else // DEBUG DEBUG
+ { // DEBUG DEBUG
+ DetailLog("{0},BSLinksetCompound.UpdateProperties,couldNotUpdateChild,rootPhysShape={1},lsi={2}",
+ updated.LocalID, LinksetRoot.PhysShape, lsi == null ? "NULL" : lsi.ToString());
+ } // DEBUG DEBUG
+ if (!updatedChild)
+ {
+ // If couldn't do the individual child, the linkset needs a rebuild to incorporate the new child info.
+ DetailLog("{0},BSLinksetCompound.UpdateProperties,couldNotUpdateChild.schedulingRebuild,whichUpdated={1}",
+ updated.LocalID, whichUpdated);
+ updated.LinksetInfo = null; // setting to 'null' causes relative position to be recomputed.
+ ScheduleRebuild(updated);
+ }
+ }
}
}
@@ -372,15 +434,7 @@ public sealed class BSLinksetCompound : BSLinkset
BSLinksetCompoundInfo lci = cPrim.LinksetInfo as BSLinksetCompoundInfo;
if (lci == null)
{
- // Each child position and rotation is given relative to the center-of-mass.
- OMV.Quaternion invRootOrientation = OMV.Quaternion.Inverse(LinksetRoot.RawOrientation);
- OMV.Vector3 displacementFromRoot = (cPrim.RawPosition - LinksetRoot.RawPosition) * invRootOrientation;
- OMV.Vector3 displacementFromCOM = displacementFromRoot - centerDisplacement;
- OMV.Quaternion displacementRot = cPrim.RawOrientation * invRootOrientation;
-
- // Save relative position for recomputing child's world position after moving linkset.
- lci = new BSLinksetCompoundInfo(memberIndex, displacementFromCOM, displacementRot);
- lci.OffsetFromRoot = displacementFromRoot;
+ lci = new BSLinksetCompoundInfo(memberIndex, LinksetRoot, cPrim, centerDisplacement);
cPrim.LinksetInfo = lci;
DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,creatingRelPos,lci={1}", cPrim.LocalID, lci);
}
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs
index d0b2a567a4..89f186c206 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs
@@ -83,7 +83,7 @@ public sealed class BSLinksetConstraints : BSLinkset
}
// Called at taint-time!!
- public override void UpdateProperties(BSPhysObject updated, bool inTaintTime)
+ public override void UpdateProperties(UpdatedProperties whichUpdated, BSPhysObject pObj)
{
// Nothing to do for constraints on property updates
}
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs b/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs
index 6d0db2e4e4..9501e2d4fe 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs
@@ -138,7 +138,8 @@ public class BSVMotor : BSMotor
CurrentValue = TargetValue = Vector3.Zero;
}
- // Compute the next step and return the new current value
+ // Compute the next step and return the new current value.
+ // Returns the correction needed to move 'current' to 'target'.
public virtual Vector3 Step(float timeStep)
{
if (!Enabled) return TargetValue;
@@ -148,9 +149,10 @@ public class BSVMotor : BSMotor
Vector3 correction = Vector3.Zero;
Vector3 error = TargetValue - CurrentValue;
+ LastError = error;
if (!ErrorIsZero(error))
{
- correction = Step(timeStep, error);
+ correction = StepError(timeStep, error);
CurrentValue += correction;
@@ -187,20 +189,31 @@ public class BSVMotor : BSMotor
else
{
// Difference between what we have and target is small. Motor is done.
+ if (TargetValue.ApproxEquals(Vector3.Zero, ErrorZeroThreshold))
+ {
+ // The target can step down to nearly zero but not get there. If close to zero
+ // it is really zero.
+ TargetValue = Vector3.Zero;
+ }
CurrentValue = TargetValue;
- MDetailLog("{0}, BSVMotor.Step,zero,{1},origTgt={2},origCurr={3},ret={4}",
- BSScene.DetailLogZero, UseName, origCurrVal, origTarget, CurrentValue);
+ MDetailLog("{0}, BSVMotor.Step,zero,{1},origTgt={2},origCurr={3},currTgt={4},currCurr={5}",
+ BSScene.DetailLogZero, UseName, origCurrVal, origTarget, TargetValue, CurrentValue);
}
- return CurrentValue;
+ return correction;
}
- public virtual Vector3 Step(float timeStep, Vector3 error)
+ // version of step that sets the current value before doing the step
+ public virtual Vector3 Step(float timeStep, Vector3 current)
+ {
+ CurrentValue = current;
+ return Step(timeStep);
+ }
+ public virtual Vector3 StepError(float timeStep, Vector3 error)
{
if (!Enabled) return Vector3.Zero;
- LastError = error;
Vector3 returnCorrection = Vector3.Zero;
- if (!ErrorIsZero())
+ if (!ErrorIsZero(error))
{
// correction = error / secondsItShouldTakeToCorrect
Vector3 correctionAmount;
@@ -302,9 +315,10 @@ public class BSFMotor : BSMotor
float correction = 0f;
float error = TargetValue - CurrentValue;
+ LastError = error;
if (!ErrorIsZero(error))
{
- correction = Step(timeStep, error);
+ correction = StepError(timeStep, error);
CurrentValue += correction;
@@ -339,6 +353,12 @@ public class BSFMotor : BSMotor
else
{
// Difference between what we have and target is small. Motor is done.
+ if (Util.InRange(TargetValue, -ErrorZeroThreshold, ErrorZeroThreshold))
+ {
+ // The target can step down to nearly zero but not get there. If close to zero
+ // it is really zero.
+ TargetValue = 0f;
+ }
CurrentValue = TargetValue;
MDetailLog("{0}, BSFMotor.Step,zero,{1},origTgt={2},origCurr={3},ret={4}",
BSScene.DetailLogZero, UseName, origCurrVal, origTarget, CurrentValue);
@@ -347,13 +367,12 @@ public class BSFMotor : BSMotor
return CurrentValue;
}
- public virtual float Step(float timeStep, float error)
+ public virtual float StepError(float timeStep, float error)
{
if (!Enabled) return 0f;
- LastError = error;
float returnCorrection = 0f;
- if (!ErrorIsZero())
+ if (!ErrorIsZero(error))
{
// correction = error / secondsItShouldTakeToCorrect
float correctionAmount;
@@ -440,8 +459,8 @@ public class BSPIDVMotor : BSVMotor
}
}
- // Ignore Current and Target Values and just advance the PID computation on this error.
- public override Vector3 Step(float timeStep, Vector3 error)
+ // Advance the PID computation on this error.
+ public override Vector3 StepError(float timeStep, Vector3 error)
{
if (!Enabled) return Vector3.Zero;
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs
index 3e80aa4101..da7438a4ae 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs
@@ -45,6 +45,9 @@ public static class BSParam
public static float MinimumObjectMass { get; private set; }
public static float MaximumObjectMass { get; private set; }
+ public static float MaxLinearVelocity { get; private set; }
+ public static float MaxAngularVelocity { get; private set; }
+ public static float MaxAddForceMagnitude { get; private set; }
public static float LinearDamping { get; private set; }
public static float AngularDamping { get; private set; }
@@ -79,6 +82,8 @@ public static class BSParam
public static float AvatarStepApproachFactor { get; private set; }
public static float AvatarStepForceFactor { get; private set; }
+ public static float VehicleMaxLinearVelocity { get; private set; }
+ public static float VehicleMaxAngularVelocity { get; private set; }
public static float VehicleAngularDamping { get; private set; }
public static float VehicleDebuggingEnabled { get; private set; }
@@ -103,7 +108,6 @@ public static class BSParam
public const float MaxDensity = 22587f;
public const float MinRestitution = 0f;
public const float MaxRestitution = 1f;
- public const float MaxAddForceMagnitude = 20f;
// ===========================================================================
public delegate void ParamUser(BSScene scene, IConfig conf, string paramName, float val);
@@ -232,11 +236,7 @@ public static class BSParam
(s,cf,p,v) => { s.m_maxUpdatesPerFrame = cf.GetInt(p, (int)v); },
(s) => { return (float)s.m_maxUpdatesPerFrame; },
(s,p,l,v) => { s.m_maxUpdatesPerFrame = (int)v; } ),
- new ParameterDefn("MaxTaintsToProcessPerStep", "Number of update taints to process before each simulation step",
- 500f,
- (s,cf,p,v) => { s.m_taintsToProcessPerStep = cf.GetInt(p, (int)v); },
- (s) => { return (float)s.m_taintsToProcessPerStep; },
- (s,p,l,v) => { s.m_taintsToProcessPerStep = (int)v; } ),
+
new ParameterDefn("MinObjectMass", "Minimum object mass (0.0001)",
0.0001f,
(s,cf,p,v) => { MinimumObjectMass = cf.GetFloat(p, v); },
@@ -247,6 +247,22 @@ public static class BSParam
(s,cf,p,v) => { MaximumObjectMass = cf.GetFloat(p, v); },
(s) => { return (float)MaximumObjectMass; },
(s,p,l,v) => { MaximumObjectMass = v; } ),
+ new ParameterDefn("MaxLinearVelocity", "Maximum velocity magnitude that can be assigned to an object",
+ 1000.0f,
+ (s,cf,p,v) => { MaxLinearVelocity = cf.GetFloat(p, v); },
+ (s) => { return (float)MaxLinearVelocity; },
+ (s,p,l,v) => { MaxLinearVelocity = v; } ),
+ new ParameterDefn("MaxAngularVelocity", "Maximum rotational velocity magnitude that can be assigned to an object",
+ 1000.0f,
+ (s,cf,p,v) => { MaxAngularVelocity = cf.GetFloat(p, v); },
+ (s) => { return (float)MaxAngularVelocity; },
+ (s,p,l,v) => { MaxAngularVelocity = v; } ),
+ // LL documentation says thie number should be 20f for llApplyImpulse and 200f for llRezObject
+ new ParameterDefn("MaxAddForceMagnitude", "Maximum force that can be applied by llApplyImpulse (SL says 20f)",
+ 20000.0f,
+ (s,cf,p,v) => { MaxAddForceMagnitude = cf.GetFloat(p, v); },
+ (s) => { return (float)MaxAddForceMagnitude; },
+ (s,p,l,v) => { MaxAddForceMagnitude = v; } ),
new ParameterDefn("PID_D", "Derivitive factor for motion smoothing",
2200f,
@@ -423,8 +439,18 @@ public static class BSParam
(s) => { return AvatarStepForceFactor; },
(s,p,l,v) => { AvatarStepForceFactor = v; } ),
+ new ParameterDefn("VehicleMaxLinearVelocity", "Maximum velocity magnitude that can be assigned to a vehicle",
+ 1000.0f,
+ (s,cf,p,v) => { VehicleMaxLinearVelocity = cf.GetFloat(p, v); },
+ (s) => { return (float)VehicleMaxLinearVelocity; },
+ (s,p,l,v) => { VehicleMaxLinearVelocity = v; } ),
+ new ParameterDefn("VehicleMaxAngularVelocity", "Maximum rotational velocity magnitude that can be assigned to a vehicle",
+ 12.0f,
+ (s,cf,p,v) => { VehicleMaxAngularVelocity = cf.GetFloat(p, v); },
+ (s) => { return (float)VehicleMaxAngularVelocity; },
+ (s,p,l,v) => { VehicleMaxAngularVelocity = v; } ),
new ParameterDefn("VehicleAngularDamping", "Factor to damp vehicle angular movement per second (0.0 - 1.0)",
- 0.95f,
+ 0.0f,
(s,cf,p,v) => { VehicleAngularDamping = cf.GetFloat(p, v); },
(s) => { return VehicleAngularDamping; },
(s,p,l,v) => { VehicleAngularDamping = v; } ),
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs
index bac0427274..027c786ce7 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs
@@ -55,6 +55,16 @@ namespace OpenSim.Region.Physics.BulletSPlugin
* BS.ApplyCentralForce BS.ApplyTorque
*/
+// Flags used to denote which properties updates when making UpdateProperties calls to linksets, etc.
+public enum UpdatedProperties : uint
+{
+ Position = 1 << 0,
+ Orientation = 1 << 1,
+ Velocity = 1 << 2,
+ Acceleration = 1 << 3,
+ RotationalVelocity = 1 << 4,
+ EntPropUpdates = Position | Orientation | Velocity | Acceleration | RotationalVelocity,
+}
public abstract class BSPhysObject : PhysicsActor
{
protected BSPhysObject()
@@ -141,7 +151,7 @@ public abstract class BSPhysObject : PhysicsActor
// It can be confusing for an actor to know if it should move or update an object
// depeneding on the setting of 'selected', 'physical, ...
- // This flag is the true test -- if true, the object is being acted on in the physical world
+ // This flag is the true test -- if true, the object is being acted on in the physical world
public abstract bool IsPhysicallyActive { get; }
// Materialness
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
index 7aa2d92ca6..e6b8507337 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
@@ -311,13 +311,14 @@ public sealed class BSPrim : BSPhysObject
_position = value;
PositionSanityCheck(false);
- // A linkset might need to know if a component information changed.
- Linkset.UpdateProperties(this, false);
-
PhysicsScene.TaintedObject("BSPrim.setPosition", delegate()
{
DetailLog("{0},BSPrim.SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation);
ForcePosition = _position;
+
+ // A linkset might need to know if a component information changed.
+ Linkset.UpdateProperties(UpdatedProperties.Position, this);
+
});
}
}
@@ -502,6 +503,12 @@ public sealed class BSPrim : BSPhysObject
RegisterPreStepAction("BSPrim.setForce", LocalID,
delegate(float timeStep)
{
+ if (!IsPhysicallyActive)
+ {
+ UnRegisterPreStepAction("BSPrim.setForce", LocalID);
+ return;
+ }
+
DetailLog("{0},BSPrim.setForce,preStep,force={1}", LocalID, _force);
if (PhysBody.HasPhysicalBody)
{
@@ -627,6 +634,12 @@ public sealed class BSPrim : BSPhysObject
RegisterPreStepAction("BSPrim.setTorque", LocalID,
delegate(float timeStep)
{
+ if (!IsPhysicallyActive)
+ {
+ UnRegisterPreStepAction("BSPrim.setTorque", LocalID);
+ return;
+ }
+
if (PhysBody.HasPhysicalBody)
AddAngularForce(_torque, false, true);
}
@@ -670,12 +683,13 @@ public sealed class BSPrim : BSPhysObject
return;
_orientation = value;
- // A linkset might need to know if a component information changed.
- Linkset.UpdateProperties(this, false);
-
PhysicsScene.TaintedObject("BSPrim.setOrientation", delegate()
{
ForceOrientation = _orientation;
+
+ // A linkset might need to know if a component information changed.
+ Linkset.UpdateProperties(UpdatedProperties.Orientation, this);
+
});
}
}
@@ -977,10 +991,10 @@ public sealed class BSPrim : BSPhysObject
}
set {
_rotationalVelocity = value;
+ Util.ClampV(_rotationalVelocity, BSParam.MaxAngularVelocity);
// m_log.DebugFormat("{0}: RotationalVelocity={1}", LogHeader, _rotationalVelocity);
PhysicsScene.TaintedObject("BSPrim.setRotationalVelocity", delegate()
{
- DetailLog("{0},BSPrim.SetRotationalVel,taint,rotvel={1}", LocalID, _rotationalVelocity);
ForceRotationalVelocity = _rotationalVelocity;
});
}
@@ -993,7 +1007,9 @@ public sealed class BSPrim : BSPhysObject
_rotationalVelocity = value;
if (PhysBody.HasPhysicalBody)
{
+ DetailLog("{0},BSPrim.ForceRotationalVel,taint,rotvel={1}", LocalID, _rotationalVelocity);
PhysicsScene.PE.SetAngularVelocity(PhysBody, _rotationalVelocity);
+ // PhysicsScene.PE.SetInterpolationAngularVelocity(PhysBody, _rotationalVelocity);
ActivateIfPhysical(false);
}
}
@@ -1061,10 +1077,16 @@ public sealed class BSPrim : BSPhysObject
RegisterPreStepAction("BSPrim.PIDTarget", LocalID, delegate(float timeStep)
{
+ if (!IsPhysicallyActive)
+ {
+ UnRegisterPreStepAction("BSPrim.PIDTarget", LocalID);
+ return;
+ }
+
OMV.Vector3 origPosition = RawPosition; // DEBUG DEBUG (for printout below)
// 'movePosition' is where we'd like the prim to be at this moment.
- OMV.Vector3 movePosition = _targetMotor.Step(timeStep);
+ OMV.Vector3 movePosition = RawPosition + _targetMotor.Step(timeStep);
// If we are very close to our target, turn off the movement motor.
if (_targetMotor.ErrorIsZero())
@@ -1108,6 +1130,9 @@ public sealed class BSPrim : BSPhysObject
RegisterPreStepAction("BSPrim.Hover", LocalID, delegate(float timeStep)
{
+ if (!IsPhysicallyActive)
+ return;
+
_hoverMotor.SetCurrent(RawPosition.Z);
_hoverMotor.SetTarget(ComputeCurrentPIDHoverHeight());
float targetHeight = _hoverMotor.Step(timeStep);
@@ -1172,10 +1197,14 @@ public sealed class BSPrim : BSPhysObject
public override float APIDDamping { set { return; } }
public override void AddForce(OMV.Vector3 force, bool pushforce) {
+ // Per documentation, max force is limited.
+ OMV.Vector3 addForce = Util.ClampV(force, BSParam.MaxAddForceMagnitude);
+
// Since this force is being applied in only one step, make this a force per second.
- OMV.Vector3 addForce = force / PhysicsScene.LastTimeStep;
- AddForce(addForce, pushforce, false);
+ addForce /= PhysicsScene.LastTimeStep;
+ AddForce(addForce, pushforce, false /* inTaintTime */);
}
+
// Applying a force just adds this to the total force on the object.
// This added force will only last the next simulation tick.
public void AddForce(OMV.Vector3 force, bool pushforce, bool inTaintTime) {
@@ -1184,9 +1213,9 @@ public sealed class BSPrim : BSPhysObject
{
if (force.IsFinite())
{
- OMV.Vector3 addForce = Util.ClampV(force, BSParam.MaxAddForceMagnitude);
// DetailLog("{0},BSPrim.addForce,call,force={1}", LocalID, addForce);
+ OMV.Vector3 addForce = force;
PhysicsScene.TaintedObject(inTaintTime, "BSPrim.AddForce", delegate()
{
// Bullet adds this central force to the total force for this tick
@@ -1621,7 +1650,7 @@ public sealed class BSPrim : BSPhysObject
// TODO: handle physics introduced by Bullet with computed vehicle physics.
if (_vehicle.IsActive)
{
- entprop.RotationalVelocity = OMV.Vector3.Zero;
+ // entprop.RotationalVelocity = OMV.Vector3.Zero;
}
// Assign directly to the local variables so the normal set actions do not happen
@@ -1660,7 +1689,7 @@ public sealed class BSPrim : BSPhysObject
*/
// The linkset implimentation might want to know about this.
- Linkset.UpdateProperties(this, true);
+ Linkset.UpdateProperties(UpdatedProperties.EntPropUpdates, this);
}
}
}
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
index e0b4992e0d..8075b73b05 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
@@ -81,7 +81,6 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
internal long m_simulationStep = 0;
internal float NominalFrameRate { get; set; }
public long SimulationStep { get { return m_simulationStep; } }
- internal int m_taintsToProcessPerStep;
internal float LastTimeStep { get; private set; }
// Physical objects can register for prestep or poststep events
@@ -847,8 +846,6 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
#endregion // Taints
- #region INI and command line parameter processing
-
#region IPhysicsParameters
// Get the list of parameters this physics engine supports
public PhysParameterEntry[] GetParameterList()
@@ -945,8 +942,6 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
#endregion IPhysicsParameters
- #endregion Runtime settable parameters
-
// Invoke the detailed logger and output something if it's enabled.
public void DetailLog(string msg, params Object[] args)
{
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt
index 9bfec19e0e..41bab2601d 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt
+++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt
@@ -1,23 +1,20 @@
CURRENT PRIORITIES
=================================================
-Mantis 6040 script http://opensimulator.org/mantis/view.php?id=6040
- Msg Kayaker on OSGrid when working
+Child movement in linkset (don't rebuild linkset)
+Vehicle angular vertical attraction
+vehicle angular banking
+Center-of-gravity
+Vehicle angular deflection
+ Preferred orientation angular correction fix
+when should angular and linear motor targets be zeroed? when selected?
+ Need a vehicle.clear()? Or an 'else' in prestep if not physical.
Teravus llMoveToTarget script debug
Mixing of hover, buoyancy/gravity, moveToTarget, into one force
-Boats floating at proper level
Nebadon vehicles turning funny in arena
limitMotorUp calibration (more down?)
llRotLookAt
llLookAt
-Vehicle angular vertical attraction
-Vehicle angular deflection
- Preferred orientation angular correction fix
-vehicle angular banking
Avatars walking up stairs (HALF DONE)
- Radius of the capsule affects ability to climb edges.
-Vehicle movement on terrain smoothness
-When is force introduced by SetForce removed? The prestep action could go forever.
-Boats float low in the water (DONE)
Avatar movement
flying into a wall doesn't stop avatar who keeps appearing to move through the obstacle (DONE)
walking up stairs is not calibrated correctly (stairs out of Kepler cabin)
@@ -73,8 +70,12 @@ Incorporate inter-relationship of angular corrections. For instance, angularDefl
GENERAL TODO LIST:
=================================================
+llMoveToTarget objects are not effected by gravity until target is removed.
Implement llSetPhysicalMaterial.
+ extend it with Center-of-mass, rolling friction, density
Implement llSetForceAndTorque.
+Change BSPrim.moveToTarget to used forces rather than changing position
+ Changing position allows one to move through walls
Implement an avatar mesh shape. The Bullet capsule is way too limited.
Consider just hand creating a vertex/index array in a new BSShapeAvatar.
Verify/fix phantom, volume-detect objects do not fall to infinity. Should stop at terrain.
@@ -310,4 +311,12 @@ Remove HeightmapInfo from terrain specification (DONE)
Since C++ code does not need terrain height, this structure et al are not needed.
Surfboard go wonky when turning (DONE)
Angular motor direction is global coordinates rather than local coordinates?
- (Resolution: made angular motor direction correct coordinate system)
\ No newline at end of file
+ (Resolution: made angular motor direction correct coordinate system)
+Mantis 6040 script http://opensimulator.org/mantis/view.php?id=6040 (DONE)
+ Msg Kayaker on OSGrid when working
+ (Resolution: LINEAR_DIRECTION is in vehicle coords. Test script does the
+ same in SL as in OS/BulletSim)
+Boats float low in the water (DONE)
+Boats floating at proper level (DONE)
+When is force introduced by SetForce removed? The prestep action could go forever. (DONE)
+ (Resolution: setForce registers a prestep action which keeps applying the force)
\ No newline at end of file
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index d47fd6b5ac..507c3997f5 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -3364,7 +3364,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
if (animID == UUID.Zero)
presence.Animator.RemoveAnimation(anim);
else
- presence.Animator.RemoveAnimation(animID);
+ presence.Animator.RemoveAnimation(animID, true);
}
}
}
@@ -4923,7 +4923,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
public LSL_Vector llGetCenterOfMass()
{
m_host.AddScriptLPS(1);
- Vector3 center = m_host.GetGeometricCenter();
+ Vector3 center = m_host.GetCenterOfMass();
return new LSL_Vector(center.X,center.Y,center.Z);
}
@@ -5793,13 +5793,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
if (parcelOwned && land.LandData.OwnerID == id ||
parcel && land.LandData.GlobalID == id)
{
- result.Add(ssp.UUID.ToString());
+ result.Add(new LSL_Key(ssp.UUID.ToString()));
}
}
}
else
{
- result.Add(ssp.UUID.ToString());
+ result.Add(new LSL_Key(ssp.UUID.ToString()));
}
}
// Maximum of 100 results
@@ -10590,6 +10590,35 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
case ScriptBaseClass.OBJECT_PHYSICS_COST:
ret.Add(new LSL_Float(0));
break;
+ case ScriptBaseClass.OBJECT_CHARACTER_TIME: // Pathfinding
+ ret.Add(new LSL_Float(0));
+ break;
+ case ScriptBaseClass.OBJECT_ROOT:
+ SceneObjectPart p = av.ParentPart;
+ if (p != null)
+ {
+ ret.Add(new LSL_String(p.ParentGroup.RootPart.UUID.ToString()));
+ }
+ else
+ {
+ ret.Add(new LSL_String(id));
+ }
+ break;
+ case ScriptBaseClass.OBJECT_ATTACHED_POINT:
+ ret.Add(new LSL_Integer(0));
+ break;
+ case ScriptBaseClass.OBJECT_PATHFINDING_TYPE: // Pathfinding
+ ret.Add(new LSL_Integer(ScriptBaseClass.OPT_AVATAR));
+ break;
+ case ScriptBaseClass.OBJECT_PHYSICS:
+ ret.Add(new LSL_Integer(0));
+ break;
+ case ScriptBaseClass.OBJECT_PHANTOM:
+ ret.Add(new LSL_Integer(0));
+ break;
+ case ScriptBaseClass.OBJECT_TEMP_ON_REZ:
+ ret.Add(new LSL_Integer(0));
+ break;
default:
// Invalid or unhandled constant.
ret.Add(new LSL_Integer(ScriptBaseClass.OBJECT_UNKNOWN_DETAIL));
@@ -10685,6 +10714,52 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
// The value returned in SL for normal prims looks like the prim count
ret.Add(new LSL_Float(0));
break;
+ case ScriptBaseClass.OBJECT_CHARACTER_TIME: // Pathfinding
+ ret.Add(new LSL_Float(0));
+ break;
+ case ScriptBaseClass.OBJECT_ROOT:
+ ret.Add(new LSL_String(obj.ParentGroup.RootPart.UUID.ToString()));
+ break;
+ case ScriptBaseClass.OBJECT_ATTACHED_POINT:
+ ret.Add(new LSL_Integer(obj.ParentGroup.AttachmentPoint));
+ break;
+ case ScriptBaseClass.OBJECT_PATHFINDING_TYPE:
+ byte pcode = obj.Shape.PCode;
+ if (obj.ParentGroup.AttachmentPoint != 0
+ || pcode == (byte)PCode.Grass
+ || pcode == (byte)PCode.Tree
+ || pcode == (byte)PCode.NewTree)
+ {
+ ret.Add(new LSL_Integer(ScriptBaseClass.OPT_OTHER));
+ }
+ else
+ {
+ ret.Add(new LSL_Integer(ScriptBaseClass.OPT_LEGACY_LINKSET));
+ }
+ break;
+ case ScriptBaseClass.OBJECT_PHYSICS:
+ if (obj.ParentGroup.AttachmentPoint != 0)
+ {
+ ret.Add(new LSL_Integer(0)); // Always false if attached
+ }
+ else
+ {
+ ret.Add(new LSL_Integer(obj.ParentGroup.UsesPhysics ? 1 : 0));
+ }
+ break;
+ case ScriptBaseClass.OBJECT_PHANTOM:
+ if (obj.ParentGroup.AttachmentPoint != 0)
+ {
+ ret.Add(new LSL_Integer(0)); // Always false if attached
+ }
+ else
+ {
+ ret.Add(new LSL_Integer(obj.ParentGroup.IsPhantom ? 1 : 0));
+ }
+ break;
+ case ScriptBaseClass.OBJECT_TEMP_ON_REZ:
+ ret.Add(new LSL_Integer(obj.ParentGroup.IsTemporary ? 1 : 0));
+ break;
default:
// Invalid or unhandled constant.
ret.Add(new LSL_Integer(ScriptBaseClass.OBJECT_UNKNOWN_DETAIL));
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
index 25635ff767..5c0ff1c6c4 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
@@ -986,7 +986,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
if (animID == UUID.Zero)
target.Animator.RemoveAnimation(animation);
else
- target.Animator.RemoveAnimation(animID);
+ target.Animator.RemoveAnimation(animID, true);
}
}
}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
index 880841b5d9..9bf1a64cf9 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
@@ -556,6 +556,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
public const int OBJECT_SERVER_COST = 14;
public const int OBJECT_STREAMING_COST = 15;
public const int OBJECT_PHYSICS_COST = 16;
+ public const int OBJECT_CHARACTER_TIME = 17;
+ public const int OBJECT_ROOT = 18;
+ public const int OBJECT_ATTACHED_POINT = 19;
+ public const int OBJECT_PATHFINDING_TYPE = 20;
+ public const int OBJECT_PHYSICS = 21;
+ public const int OBJECT_PHANTOM = 22;
+ public const int OBJECT_TEMP_ON_REZ = 23;
+
+ // Pathfinding types
+ public const int OPT_OTHER = -1;
+ public const int OPT_LEGACY_LINKSET = 0;
+ public const int OPT_AVATAR = 1;
+ public const int OPT_CHARACTER = 2;
+ public const int OPT_WALKABLE = 3;
+ public const int OPT_STATIC_OBSTACLE = 4;
+ public const int OPT_MATERIAL_VOLUME = 5;
+ public const int OPT_EXCLUSION_VOLUME = 6;
// for llGetAgentList
public const int AGENT_LIST_PARCEL = 1;
diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
index a17a0188bb..72646f6ccb 100644
--- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
+++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
@@ -1486,7 +1486,8 @@ namespace OpenSim.Region.ScriptEngine.XEngine
m_MaxScriptQueue = maxScriptQueue;
STPStartInfo startInfo = new STPStartInfo();
- startInfo.IdleTimeout = idleTimeout*1000; // convert to seconds as stated in .ini
+ startInfo.ThreadPoolName = "XEngine";
+ startInfo.IdleTimeout = idleTimeout * 1000; // convert to seconds as stated in .ini
startInfo.MaxWorkerThreads = maxThreads;
startInfo.MinWorkerThreads = minThreads;
startInfo.ThreadPriority = threadPriority;;
@@ -1494,7 +1495,6 @@ namespace OpenSim.Region.ScriptEngine.XEngine
startInfo.StartSuspended = true;
m_ThreadPool = new SmartThreadPool(startInfo);
- m_ThreadPool.Name = "XEngine";
}
//
diff --git a/TESTING.txt b/TESTING.txt
index a7346ff34b..e7ab0882a8 100644
--- a/TESTING.txt
+++ b/TESTING.txt
@@ -1,4 +1,4 @@
-===== The Quick Guide to OpenSim Unit Testing ===
+= The Quick Guide to OpenSim Unit Testing =
== Running Tests ==
@@ -27,7 +27,7 @@ must list it in both ".nant/local.include"
for it to be accessible to Linux users and to the continuous
integration system.
-==TESTING ON WINDOWS==
+== TESTING ON WINDOWS ==
To use nunit testing on opensim code, you have a variety of methods. The
easiast methods involve using IDE capabilities to test code. Using
@@ -58,14 +58,14 @@ Nunit console allows you to execute the nunit tests of assemblies via console.
Its output will show test failures and successes and a summary of what
happened. This is very useful for a quick overview and/or automated testing.
-Windows
+=== Windows ===
Windows version of nunit-console is by default .Net 2.0 if you downloaded the
.Net 2.0 version of Nunit. Be sure to setup your PATH environment variable.
-Linux & OSX
+=== Linux & OSX ===
On these operating systems you will have to use the command "nunit-console2"
-Example
+=== Example ===
nunit-console2 OpenSim.Framework.Tests.dll (on linux)
nunit-console OpenSim.Framework.Tests.dll (on windows)
diff --git a/ThirdParty/SmartThreadPool/STPStartInfo.cs b/ThirdParty/SmartThreadPool/STPStartInfo.cs
index d1815639db..fa9ceb4bb5 100644
--- a/ThirdParty/SmartThreadPool/STPStartInfo.cs
+++ b/ThirdParty/SmartThreadPool/STPStartInfo.cs
@@ -32,6 +32,11 @@ namespace Amib.Threading
///