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>(); }
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; }