public BSConstraintHinge(BulletWorld world, BulletBody obj1, BulletBody obj2,
                 Vector3 pivotInA, Vector3 pivotInB,
                 Vector3 axisInA, Vector3 axisInB,
                 bool useLinearReferenceFrameA, bool disableCollisionsBetweenLinkedBodies)
 {
     m_world = world;
     m_body1 = obj1;
     m_body2 = obj2;
     m_constraint = new BulletConstraint(
                         BulletSimAPI.CreateHingeConstraint2(m_world.ptr, m_body1.ptr, m_body2.ptr,
                             pivotInA, pivotInB,
                             axisInA, axisInB,
                             useLinearReferenceFrameA, disableCollisionsBetweenLinkedBodies));
     m_enabled = true;
 }
 // Create a btGeneric6DofConstraint
 public BSConstraint6Dof(BulletWorld world, BulletBody obj1, BulletBody obj2,
                 Vector3 frame1, Quaternion frame1rot,
                 Vector3 frame2, Quaternion frame2rot,
                 bool useLinearReferenceFrameA, bool disableCollisionsBetweenLinkedBodies)
 {
     m_world = world;
     m_body1 = obj1;
     m_body2 = obj2;
     m_constraint = new BulletConstraint(
                         BulletSimAPI.Create6DofConstraint2(m_world.ptr, m_body1.ptr, m_body2.ptr,
                             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.ptr.ToString(), obj2.ID, obj2.ptr.ToString());
 }
 public BSConstraint6Dof(BulletWorld world, BulletBody obj1, BulletBody obj2,
                 Vector3 joinPoint,
                 bool useLinearReferenceFrameA, bool disableCollisionsBetweenLinkedBodies)
 {
     m_world = 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.ptr.ToString(), obj2.ID, obj2.ptr.ToString());
         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.ptr.ToString(), obj2.ID, obj2.ptr.ToString());
         m_enabled = false;
     }
     else
     {
         m_constraint = new BulletConstraint(
                             BulletSimAPI.Create6DofConstraintToPoint2(m_world.ptr, m_body1.ptr, m_body2.ptr,
                                 joinPoint,
                                 useLinearReferenceFrameA, disableCollisionsBetweenLinkedBodies));
         world.physicsScene.DetailLog("{0},BS6DofConstraint,createMidPoint,wID={1}, csrt={2}, rID={3}, rBody={4}, cID={5}, cBody={6}",
                             BSScene.DetailLogZero, world.worldID, m_constraint.ptr.ToString(),
                             obj1.ID, obj1.ptr.ToString(), obj2.ID, obj2.ptr.ToString());
         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;
         }
     }
 }
 public BSConstraintCollection(BulletWorld world)
 {
     m_world = world;
     m_constraints = new List<BSConstraint>();
 }
Exemple #5
0
    public override void Initialise(IMesher meshmerizer, IConfigSource config)
    {
        mesher = meshmerizer;
        _taintOperations = new List<TaintCallbackEntry>();
        _postTaintOperations = new Dictionary<string, TaintCallbackEntry>();
        _postStepOperations = new List<TaintCallbackEntry>();
        PhysObjects = new Dictionary<uint, BSPhysObject>();
        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<BulletXNA.CollisionDesc>();
        //m_collisionArrayPinnedHandle = GCHandle.Alloc(m_collisionArray, GCHandleType.Pinned);
        m_updateArray = new List<BulletXNA.EntityProperties>();
        //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;
    }
    // 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;
    }
 public bool GetBodyAndShape(bool forceRebuild, BulletWorld sim, BSPhysObject prim)
 {
     return GetBodyAndShape(forceRebuild, sim, prim, null, null);
 }
    // 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;
    }