public BSConstraintConeTwist(BulletWorld world, BulletBody obj1, BulletBody obj2,
                 Vector3 frameInAloc, Quaternion frameInArot,
                 Vector3 frameInBloc, Quaternion frameInBrot,
                 bool disableCollisionsBetweenLinkedBodies)
     : base(world)
 {
     m_body1 = obj1;
     m_body2 = obj2;
     m_constraint = PhysicsScene.PE.CreateConeTwistConstraint(world, obj1, obj2,
                             frameInAloc, frameInArot, frameInBloc, frameInBrot,
                             disableCollisionsBetweenLinkedBodies);
     m_enabled = true;
 }
 public BSConstraintHinge(BulletWorld world, BulletBody obj1, BulletBody obj2,
     Vector3 pivotInA, Vector3 pivotInB,
     Vector3 axisInA, Vector3 axisInB,
     bool useLinearReferenceFrameA, bool disableCollisionsBetweenLinkedBodies)
     : base(world)
 {
     m_body1 = obj1;
     m_body2 = obj2;
     m_constraint = PhysicsScene.PE.CreateHingeConstraint(world, obj1, obj2,
         pivotInA, pivotInB, axisInA, axisInB,
         useLinearReferenceFrameA, disableCollisionsBetweenLinkedBodies);
     m_enabled = true;
 }
    public BSConstraintSpring(BulletWorld world, BulletBody obj1, BulletBody obj2,
                    Vector3 frame1Loc, Quaternion frame1Rot,
                    Vector3 frame2Loc, Quaternion frame2Rot,
                    bool useLinearReferenceFrameA, bool disableCollisionsBetweenLinkedBodies)
        :base(world, obj1, obj2)
    {
        m_constraint = PhysicsScene.PE.Create6DofSpringConstraint(world, obj1, obj2,
                                frame1Loc, frame1Rot, frame2Loc, frame2Rot,
                                useLinearReferenceFrameA, disableCollisionsBetweenLinkedBodies);
        m_enabled = true;

        PhysicsScene.DetailLog("{0},BSConstraintSpring,create,wID={1}, rID={2}, rBody={3}, cID={4}, cBody={5}",
                            obj1.ID, world.worldID, obj1.ID, obj1.AddrString, obj2.ID, obj2.AddrString);
        PhysicsScene.DetailLog("{0},BSConstraintSpring,create,  f1Loc={1},f1Rot={2},f2Loc={3},f2Rot={4},usefA={5},disCol={6}",
                    m_body1.ID, frame1Loc, frame1Rot, frame2Loc, frame2Rot, useLinearReferenceFrameA, disableCollisionsBetweenLinkedBodies);
    }
 // Create a btGeneric6DofConstraint
 public BSConstraint6Dof(BulletWorld world, BulletBody obj1, BulletBody obj2,
     Vector3 frame1, Quaternion frame1rot,
     Vector3 frame2, Quaternion frame2rot,
     bool useLinearReferenceFrameA, bool disableCollisionsBetweenLinkedBodies)
     : base(world)
 {
     m_body1 = obj1;
     m_body2 = obj2;
     m_constraint = PhysicsScene.PE.Create6DofConstraint(m_world, m_body1, m_body2,
         frame1, frame1rot,
         frame2, frame2rot,
         useLinearReferenceFrameA, disableCollisionsBetweenLinkedBodies);
     m_enabled = true;
     world.physicsScene.DetailLog(
         "{0},BS6DofConstraint,createFrame,wID={1}, rID={2}, rBody={3}, cID={4}, cBody={5}",
         BSScene.DetailLogZero, world.worldID,
         obj1.ID, obj1.AddrString, obj2.ID, obj2.AddrString);
 }
 // 6 Dof constraint based on a midpoint between the two constrained bodies
 public BSConstraint6Dof(BulletWorld world, BulletBody obj1, BulletBody obj2,
     Vector3 joinPoint,
     bool useLinearReferenceFrameA, bool disableCollisionsBetweenLinkedBodies)
     : base(world)
 {
     m_body1 = obj1;
     m_body2 = obj2;
     if (!obj1.HasPhysicalBody || !obj2.HasPhysicalBody)
     {
         world.physicsScene.DetailLog(
             "{0},BS6DOFConstraint,badBodyPtr,wID={1}, rID={2}, rBody={3}, cID={4}, cBody={5}",
             BSScene.DetailLogZero, world.worldID,
             obj1.ID, obj1.AddrString, obj2.ID, obj2.AddrString);
         world.physicsScene.Logger.ErrorFormat(
             "{0} Attempt to build 6DOF constraint with missing bodies: wID={1}, rID={2}, rBody={3}, cID={4}, cBody={5}",
             LogHeader, world.worldID, obj1.ID, obj1.AddrString, obj2.ID, obj2.AddrString);
         m_enabled = false;
     }
     else
     {
         m_constraint = PhysicsScene.PE.Create6DofConstraintToPoint(m_world, m_body1, m_body2,
             joinPoint,
             useLinearReferenceFrameA, disableCollisionsBetweenLinkedBodies);
         PhysicsScene.DetailLog(
             "{0},BS6DofConstraint,createMidPoint,wID={1}, csrt={2}, rID={3}, rBody={4}, cID={5}, cBody={6}",
             BSScene.DetailLogZero, world.worldID, m_constraint.AddrString,
             obj1.ID, obj1.AddrString, obj2.ID, obj2.AddrString);
         if (!m_constraint.HasPhysicalConstraint)
         {
             world.physicsScene.Logger.ErrorFormat(
                 "{0} Failed creation of 6Dof constraint. rootID={1}, childID={2}",
                 LogHeader, obj1.ID, obj2.ID);
             m_enabled = false;
         }
         else
         {
             m_enabled = true;
         }
     }
 }
        // Get the constraint between two bodies. There can be only one.
        // Return 'true' if a constraint was found.
        public bool TryGetConstraint(BulletBody body1, BulletBody body2, out BSConstraint returnConstraint)
        {
            bool found = false;
            BSConstraint foundConstraint = null;

            uint lookingID1 = body1.ID;
            uint lookingID2 = body2.ID;
            lock (m_constraints)
            {
                foreach (BSConstraint constrain in m_constraints)
                {
                    if ((constrain.Body1.ID == lookingID1 && constrain.Body2.ID == lookingID2)
                        || (constrain.Body1.ID == lookingID2 && constrain.Body2.ID == lookingID1))
                    {
                        foundConstraint = constrain;
                        found = true;
                        break;
                    }
                }
            }
            returnConstraint = foundConstraint;
            return found;
        }
        protected BSPhysObject(BSScene parentScene, uint localID, string name, string typeName)
        {
            PhysicsScene = parentScene;
            LocalID = localID;
            PhysObjectName = name;
            Name = name; // PhysicsActor also has the name of the object. Someday consolidate.
            TypeName = typeName;

            // Oddity if object is destroyed and recreated very quickly it could still have the old body.
            if (!PhysBody.HasPhysicalBody)
                PhysBody = new BulletBody(localID);

            // The collection of things that push me around
            PhysicalActors = new BSActorCollection(PhysicsScene);

            // Initialize variables kept in base.
            GravityMultiplier = 1.0f;
            Gravity = new OMV.Vector3(0f, 0f, BSParam.Gravity);

            PrimAssetState = PrimAssetCondition.Unknown;

            // Default material type. Also sets Friction, Restitution and Density.
            SetMaterial((int)MaterialAttributes.Material.Wood);

            CollisionCollection = new CollisionEventUpdate();
            CollisionsLastTick = CollisionCollection;
            SubscribedEventsMs = 0;
            CollidingStep = 0;
            TrueCollidingStep = 0;
            CollisionAccumulation = 0;
            ColliderIsMoving = false;
            CollisionScore = 0;

            // All axis free.
            LockedLinearAxis = LockedAxisFree;
            LockedAngularAxis = LockedAxisFree;
        }
 // Apply impulse to the object. Same as "ApplycentralForce" but force scaled by object's mass.
 public abstract void ApplyCentralImpulse(BulletBody obj, Vector3 imp);
 public abstract void ApplyTorque(BulletBody obj, Vector3 torque);
 public abstract Vector3 GetInvInertiaDiagLocal(BulletBody obj);
        // 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()
        {
            DetailLog("{0},BSTerrainManager.CreateInitialGroundPlaneAndTerrain,region={1}", BSScene.DetailLogZero,
                PhysicsScene.RegionName);
            // The ground plane is here to catch things that are trying to drop to negative infinity
            BulletShape groundPlaneShape = PhysicsScene.PE.CreateGroundPlaneShape(BSScene.GROUNDPLANE_ID, 1f,
                BSParam.TerrainCollisionMargin);
            Vector3 groundPlaneAltitude = new Vector3(0f, 0f, BSParam.TerrainGroundPlane);
            m_groundPlane = PhysicsScene.PE.CreateBodyWithDefaultMotionState(groundPlaneShape,
                BSScene.GROUNDPLANE_ID, groundPlaneAltitude, Quaternion.Identity);

            PhysicsScene.PE.AddObjectToWorld(PhysicsScene.World, m_groundPlane);
            PhysicsScene.PE.UpdateSingleAabb(PhysicsScene.World, m_groundPlane);
            // Ground plane does not move
            PhysicsScene.PE.ForceActivationState(m_groundPlane, ActivationState.DISABLE_SIMULATION);
            // Everything collides with the ground plane.
            m_groundPlane.collisionType = CollisionType.Groundplane;
            m_groundPlane.ApplyCollisionMask(PhysicsScene);

            m_terrain = new BSTerrainHeightmap(PhysicsScene, Vector3.Zero, BSScene.TERRAIN_ID, m_worldMax);
        }
 // =====================================================================================
 // Debugging
 public virtual void DumpRigidBody(BulletWorld sim, BulletBody collisionObject)
 {
 }
 public abstract void RemoveConstraintRef(BulletBody obj, BulletConstraint constrain);
 public abstract void SetAngularFactorV(BulletBody obj, Vector3 factor);
 public abstract void SetLinearVelocity(BulletBody obj, Vector3 val);
 public abstract Vector3 GetAngularVelocity(BulletBody obj);
 public abstract Vector3 GetLinearVelocity(BulletBody obj);
 public abstract void UpdateInertiaTensor(BulletBody obj);
 public abstract void ClearAllForces(BulletBody obj);
 // Apply impulse at the point given. For is scaled by object's mass and effects both linear and angular forces.
 public abstract void ApplyImpulse(BulletBody obj, Vector3 imp, Vector3 pos);
 // Apply impulse to the object's torque. Force is scaled by object's mass.
 public abstract void ApplyTorqueImpulse(BulletBody obj, Vector3 imp);
 public abstract void Translate(BulletBody obj, Vector3 trans);
 public abstract bool WantsSleeping(BulletBody obj);
 public abstract void SetAngularVelocity(BulletBody obj, Vector3 angularVelocity);
 public abstract bool IsInWorld(BulletWorld world, BulletBody obj);
 public abstract Vector3 GetVelocityInLocalPoint(BulletBody obj, Vector3 pos);
 public abstract int GetNumConstraintRefs(BulletBody obj);
 public abstract void Translate(BulletBody obj, Vector3 trans);
 // Remove all constraints that reference the passed body.
 // Return 'true' if any constraints were destroyed.
 public bool RemoveAndDestroyConstraint(BulletBody body1)
 {
     List<BSConstraint> toRemove = new List<BSConstraint>();
     uint lookingID = body1.ID;
     lock (m_constraints)
     {
         foreach (BSConstraint constrain in m_constraints)
         {
             if (constrain.Body1.ID == lookingID || constrain.Body2.ID == lookingID)
             {
                 toRemove.Add(constrain);
             }
         }
         foreach (BSConstraint constrain in toRemove)
         {
             m_constraints.Remove(constrain);
             constrain.Dispose();
         }
     }
     return (toRemove.Count > 0);
 }
 public abstract void UpdateDeactivation(BulletBody obj, float timeStep);
 public abstract void SetSleepingThresholds(BulletBody obj, float lin_threshold, float ang_threshold);
 public abstract void UpdateInertiaTensor(BulletBody obj);
 public abstract Vector3 GetAngularVelocity(BulletBody obj);
 public abstract void SetAngularVelocity(BulletBody obj, Vector3 angularVelocity);
 public abstract bool WantsSleeping(BulletBody obj);
 // Apply force at the given point. Will add torque to the object.
 public abstract void ApplyForce(BulletBody obj, Vector3 force, Vector3 pos);
 public abstract Vector3 GetLinearVelocity(BulletBody obj);
 public abstract void SetAngularFactor(BulletBody obj, float factor);
 public abstract void SetLinearVelocity(BulletBody obj, Vector3 val);
 public abstract void SetAngularFactorV(BulletBody obj, Vector3 factor);
 public abstract Vector3 GetVelocityInLocalPoint(BulletBody obj, Vector3 pos);
 public abstract Vector3 GetAngularFactor(BulletBody obj);
 public abstract void UpdateDeactivation(BulletBody obj, float timeStep);
 public abstract bool IsInWorld(BulletWorld world, BulletBody obj);
 public abstract void SetAngularFactor(BulletBody obj, float factor);
 public abstract void AddConstraintRef(BulletBody obj, BulletConstraint constrain);
 public abstract Vector3 GetAngularFactor(BulletBody obj);
 public abstract void RemoveConstraintRef(BulletBody obj, BulletConstraint constrain);
 public abstract void AddConstraintRef(BulletBody obj, BulletConstraint constrain);
 public abstract BulletConstraint GetConstraintRef(BulletBody obj, int index);
 public abstract BulletConstraint GetConstraintRef(BulletBody obj, int index);
 public abstract int GetNumConstraintRefs(BulletBody obj);
 public abstract bool SetCollisionGroupMask(BulletBody body, UInt32 filter, UInt32 mask);
 public abstract bool SetCollisionGroupMask(BulletBody body, UInt32 filter, UInt32 mask);
        // Remove any constraint between the passed bodies.
        // Presumed there is only one such constraint possible.
        // Return 'true' if a constraint was found and destroyed.
        public bool RemoveAndDestroyConstraint(BulletBody body1, BulletBody body2)
        {
            bool ret = false;
            lock (m_constraints)
            {
                BSConstraint constrain;
                if (this.TryGetConstraint(body1, body2, out constrain))
                {
                    // remove the constraint from our collection
                    ret = RemoveAndDestroyConstraint(constrain);
                }
            }

            return ret;
        }
 // =====================================================================================
 // Debugging
 public virtual void DumpRigidBody(BulletWorld sim, BulletBody collisionObject)
 {
 }
 public abstract Vector3 GetTotalTorque(BulletBody obj);
 public BSConstraint6Dof(BulletWorld world, BulletBody obj1, BulletBody obj2) : base(world)
 {
     m_body1   = obj1;
     m_body2   = obj2;
     m_enabled = false;
 }
        // 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);

            bool meshCreationSuccess = false;
            if (BSParam.TerrainMeshMagnification == 1)
            {
                // If a magnification of one, use the old routine that is tried and true.
                meshCreationSuccess = BSTerrainMesh.ConvertHeightmapToMesh(PhysicsScene,
                    initialMap, m_sizeX, m_sizeY, // input size
                    Vector3.Zero, // base for mesh
                    out indicesCount, out indices, out verticesCount, out vertices);
            }
            else
            {
                // Other magnifications use the newer routine
                meshCreationSuccess = BSTerrainMesh.ConvertHeightmapToMesh2(PhysicsScene,
                    initialMap, m_sizeX, m_sizeY, // input size
                    BSParam.TerrainMeshMagnification,
                    physicsScene.TerrainManager.WorldMax,
                    Vector3.Zero, // base for mesh
                    out indicesCount, out indices, out verticesCount, out vertices);
            }
            if (!meshCreationSuccess)
            {
                // DISASTER!!
                PhysicsScene.DetailLog("{0},BSTerrainMesh.create,failedConversionOfHeightmap,id={1}",
                    BSScene.DetailLogZero, 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,meshid,id={1},indices={2},indSz={3},vertices={4},vertSz={5}",
                BSScene.DetailLogZero, ID, indicesCount, indices.Length, verticesCount, vertices.Length);

            m_terrainShape = PhysicsScene.PE.CreateMeshShape(PhysicsScene.World, indicesCount, indices, verticesCount,
                vertices);

            if (!m_terrainShape.HasPhysicalShape)
            {
                // DISASTER!!
                PhysicsScene.DetailLog("{0},BSTerrainMesh.create,failedCreationOfShape,id={1}", BSScene.DetailLogZero,
                    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 = PhysicsScene.PE.CreateBodyWithDefaultMotionState(m_terrainShape, 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;
            }

            physicsScene.PE.SetShapeCollisionMargin(m_terrainShape, BSParam.TerrainCollisionMargin);

            // Set current terrain attributes
            PhysicsScene.PE.SetFriction(m_terrainBody, BSParam.TerrainFriction);
            PhysicsScene.PE.SetHitFraction(m_terrainBody, BSParam.TerrainHitFraction);
            PhysicsScene.PE.SetRestitution(m_terrainBody, BSParam.TerrainRestitution);
            PhysicsScene.PE.SetContactProcessingThreshold(m_terrainBody, BSParam.TerrainContactProcessingThreshold);
            PhysicsScene.PE.SetCollisionFlags(m_terrainBody, CollisionFlags.CF_STATIC_OBJECT);

            // Static objects are not very massive.
            PhysicsScene.PE.SetMassProps(m_terrainBody, 0.1f, Vector3.Zero);

            // Put the new terrain to the world of physical objects
            PhysicsScene.PE.AddObjectToWorld(PhysicsScene.World, m_terrainBody);

            // Redo its bounding box now that it is in the world
            PhysicsScene.PE.UpdateSingleAabb(PhysicsScene.World, m_terrainBody);

            m_terrainBody.collisionType = CollisionType.Terrain;
            m_terrainBody.ApplyCollisionMask(PhysicsScene);

            if (BSParam.UseSingleSidedMeshes)
            {
                PhysicsScene.DetailLog("{0},BSTerrainMesh.settingCustomMaterial,id={1}", BSScene.DetailLogZero, id);
                PhysicsScene.PE.AddToCollisionFlags(m_terrainBody, CollisionFlags.CF_CUSTOM_MATERIAL_CALLBACK);
            }

            // Make it so the terrain will not move or be considered for movement.
            PhysicsScene.PE.ForceActivationState(m_terrainBody, ActivationState.DISABLE_SIMULATION);
        }
 public abstract void SetInvInertiaDiagLocal(BulletBody obj, Vector3 inert);