///btRigidBody constructor for backwards compatibility. ///To specify friction (etc) during rigid body construction, please use the other constructor (using btRigidBodyConstructionInfo) public RigidBody(float mass, IMotionState motionState, CollisionShape collisionShape, IndexedVector3 localInertia) { RigidBodyConstructionInfo cinfo = new RigidBodyConstructionInfo(mass, motionState, collisionShape, localInertia); motionState.SetRigidBody(this); SetupRigidBody(cinfo); }
///setupRigidBody is only used internally by the constructor protected void SetupRigidBody(RigidBodyConstructionInfo constructionInfo) { m_internalType = CollisionObjectTypes.CO_RIGID_BODY; m_linearVelocity = IndexedVector3.Zero; m_angularVelocity = IndexedVector3.Zero; m_angularFactor = IndexedVector3.One; m_linearFactor = IndexedVector3.One; m_gravity = IndexedVector3.Zero; m_gravity_acceleration = IndexedVector3.Zero; m_totalForce = IndexedVector3.Zero; m_totalTorque = IndexedVector3.Zero; SetDamping(constructionInfo.m_linearDamping, constructionInfo.m_angularDamping); m_linearSleepingThreshold = constructionInfo.m_linearSleepingThreshold; m_angularSleepingThreshold = constructionInfo.m_angularSleepingThreshold; m_optionalMotionState = constructionInfo.m_motionState; m_contactSolverType = 0; m_frictionSolverType = 0; m_additionalDamping = constructionInfo.m_additionalDamping; m_additionalDampingFactor = constructionInfo.m_additionalDampingFactor; m_additionalLinearDampingThresholdSqr = constructionInfo.m_additionalLinearDampingThresholdSqr; m_additionalAngularDampingThresholdSqr = constructionInfo.m_additionalAngularDampingThresholdSqr; m_additionalAngularDampingFactor = constructionInfo.m_additionalAngularDampingFactor; if (m_optionalMotionState != null) { m_optionalMotionState.GetWorldTransform(out m_worldTransform); } else { SetWorldTransform(ref constructionInfo.m_startWorldTransform); } m_interpolationWorldTransform = m_worldTransform; m_interpolationLinearVelocity = IndexedVector3.Zero; m_interpolationAngularVelocity = IndexedVector3.Zero; //moved to btCollisionObject m_friction = constructionInfo.m_friction; m_restitution = constructionInfo.m_restitution; SetCollisionShape(constructionInfo.m_collisionShape); m_debugBodyId = uniqueId++; SetMassProps(constructionInfo.m_mass, constructionInfo.m_localInertia); UpdateInertiaTensor(); m_rigidbodyFlags = RigidBodyFlags.BT_NONE; m_constraintRefs = new List <TypedConstraint>(); m_deltaLinearVelocity = IndexedVector3.Zero; m_deltaAngularVelocity = IndexedVector3.Zero; m_invMass = m_inverseMass * m_linearFactor; m_pushVelocity = IndexedVector3.Zero; m_turnVelocity = IndexedVector3.Zero; }
//(sim.ptr, shape.ptr, prim.LocalID, prim.RawPosition, prim.RawOrientation); public override BulletBody CreateBodyFromShape(BulletWorld pWorld, BulletShape pShape, uint pLocalID, Vector3 pRawPosition, Quaternion pRawOrientation) { 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 = (pShape as BulletShapeXNA).shape; //UpdateSingleAabb(world, shape); // TODO: Feed Update array into null SimMotionState motionState = new SimMotionState(this, pLocalID, mat, null); RigidBody body = new RigidBody(0,motionState,shape,IndexedVector3.Zero); RigidBodyConstructionInfo constructionInfo = new RigidBodyConstructionInfo(0, motionState, 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); }
public void BuildCollisionData(Color[] map, int width, int height, Vector3 bottomLeft) { Vector2 dim = Vector2.One; Vector3 scale = new Vector3(dim, 1); BoxShape collisionBoxShape = new BoxShape(new IndexedVector3(0.5f)); for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { int currentIndex = x + y * width; if (map[currentIndex] == Color.White) { float yOffset = -dim.Y;//0f;// -(dim.Y / 2f); Vector3 position = new Vector3(x - bottomLeft.X, (bottomLeft.Y - y) + yOffset, bottomLeft.Z); m_waterLocations.Add(position); } if (map[currentIndex] == Color.White) { // check the 4 ordinals , if we're surrounded by other solid blocks // then we don't need a block here. bool upSet = false; bool downSet = false; bool leftSet = false; bool rightSet = false; if (x >= 1 && x < width - 1) { if (map[currentIndex - 1] == Color.White) { leftSet = true; } if (map[currentIndex + 1] == Color.White) { rightSet = true; } } if (y >= 1 && y < height - 1) { if (map[currentIndex - height] == Color.White) { upSet = true; } if (map[currentIndex + height] == Color.White) { downSet = true; } } // if we're not surrounded by blocks then add in. if (!(upSet && downSet && leftSet && rightSet)) { Object rigifdBody; float yOffset = -dim.Y;//0f;// -(dim.Y / 2f); Vector3 position = new Vector3(x - bottomLeft.X, (bottomLeft.Y - y) + yOffset, bottomLeft.Z); RigidBodyConstructionInfo constructionInfo = new BulletXNA.BulletDynamics.RigidBodyConstructionInfo(0f, null, (BulletXNA.BulletCollision.CollisionShape)collisionBoxShape); RigidBody rigidBody = new BulletXNA.BulletDynamics.RigidBody(constructionInfo); Matrix bsm = Matrix.CreateTranslation(position); rigidBody.SetWorldTransform(bsm); // FIXME MAN - setup some collision flags on these bodies... BulletXNA.BulletCollision.CollisionFilterGroups flags = (BulletXNA.BulletCollision.CollisionFilterGroups)(1 << 8); BulletXNA.BulletCollision.CollisionFilterGroups mask = (BulletXNA.BulletCollision.CollisionFilterGroups)(1 << 9); //rigidBody.CollisionFlags |= (BulletSharp.CollisionFlags)CollisionObjectType.Ground; m_dynamicsWorld.AddRigidBody(rigidBody, flags, mask); } } // Build water ghost objects. foreach (Vector3 pos in m_waterLocations) { GhostObject ghostObject = new GhostObject(); ghostObject.SetCollisionShape((BulletXNA.BulletCollision.CollisionShape)collisionBoxShape); CollisionFilterGroups flags = (CollisionFilterGroups)(1 << 10); CollisionFilterGroups mask = (CollisionFilterGroups)(1 << 9); ghostObject.SetCollisionFlags(CollisionFlags.CF_NO_CONTACT_RESPONSE | CollisionFlags.CF_STATIC_OBJECT); // We can choose to make it "solid" if we want... ghostObject.SetWorldTransform(BulletXNA.LinearMath.IndexedMatrix.CreateTranslation(pos)); m_dynamicsWorld.AddCollisionObject(ghostObject, flags, mask); break; } } } }
///btRigidBody constructor using construction info public RigidBody(RigidBodyConstructionInfo constructionInfo) { SetupRigidBody(constructionInfo); }
public override void InitializeDemo() { //maxiterations = 10; SetCameraDistance(SCALING * 50f); //string filename = @"E:\users\man\bullet\xna-basic-output-1.txt"; //FileStream filestream = File.Open(filename, FileMode.Create, FileAccess.Write, FileShare.Read); //BulletGlobals.g_streamWriter = new StreamWriter(filestream); ///collision configuration contains default setup for memory, collision setup m_collisionConfiguration = new DefaultCollisionConfiguration(); ///use the default collision dispatcher. For parallel processing you can use a diffent dispatcher (see Extras/BulletMultiThreaded) m_dispatcher = new CollisionDispatcher(m_collisionConfiguration); IndexedVector3 worldMin = new IndexedVector3(-1000, -1000, -1000); IndexedVector3 worldMax = -worldMin; m_broadphase = new AxisSweep3Internal(ref worldMin, ref worldMax, 0xfffe, 0xffff, 16384, null, false); //m_broadphase = new DbvtBroadphase(); IOverlappingPairCache pairCache = null; //pairCache = new SortedOverlappingPairCache(); //m_broadphase = new SimpleBroadphase(1000, pairCache); ///the default constraint solver. For parallel processing you can use a different solver (see Extras/BulletMultiThreaded) SequentialImpulseConstraintSolver sol = new SequentialImpulseConstraintSolver(); m_constraintSolver = sol; m_dynamicsWorld = new DiscreteDynamicsWorld(m_dispatcher, m_broadphase, m_constraintSolver, m_collisionConfiguration); IndexedVector3 gravity = new IndexedVector3(0, -10, 0); m_dynamicsWorld.SetGravity(ref gravity); ///create a few basic rigid bodies IndexedVector3 halfExtents = new IndexedVector3(50, 50, 50); //IndexedVector3 halfExtents = new IndexedVector3(10, 10, 10); CollisionShape groundShape = new BoxShape(ref halfExtents); //CollisionShape groundShape = new StaticPlaneShape(new IndexedVector3(0,1,0), 50); m_collisionShapes.Add(groundShape); IndexedMatrix groundTransform = IndexedMatrix.CreateTranslation(new IndexedVector3(0, -50, 0)); //IndexedMatrix groundTransform = IndexedMatrix.CreateTranslation(new IndexedVector3(0,-10,0)); float mass = 0f; LocalCreateRigidBody(mass, ref groundTransform, groundShape); { //create a few dynamic rigidbodies CollisionShape colShape = new BoxShape(new IndexedVector3(SCALING, SCALING, SCALING)); //CollisionShape colShape = BuildCorner(); //btCollisionShape* colShape = new btSphereShape(btScalar(1.)); //CollisionShape colShape = new CylinderShape(new IndexedVector3(1f, 1, 1f)); m_collisionShapes.Add(colShape); /// Create Dynamic Objects IndexedMatrix startTransform = IndexedMatrix.Identity; mass = 1f; //rigidbody is dynamic if and only if mass is non zero, otherwise static bool isDynamic = mass != 0f; IndexedVector3 localInertia = IndexedVector3.Zero; if (isDynamic) { colShape.CalculateLocalInertia(mass, out localInertia); } float start_x = START_POS_X - ARRAY_SIZE_X/2; float start_y = START_POS_Y; float start_z = START_POS_Z - ARRAY_SIZE_Z/2; for (int k=0;k<ARRAY_SIZE_Y;k++) { for (int i=0;i<ARRAY_SIZE_X;i++) { for(int j = 0;j<ARRAY_SIZE_Z;j++) { startTransform._origin = (new IndexedVector3(2.0f * i + start_x, 20 + 2.0f * k + start_y, 2.0f * j + start_z) * SCALING); //using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects DefaultMotionState myMotionState = new DefaultMotionState(startTransform, IndexedMatrix.Identity); RigidBodyConstructionInfo rbInfo = new RigidBodyConstructionInfo(mass, myMotionState, colShape, localInertia); RigidBody body = new RigidBody(rbInfo); //body->setContactProcessingThreshold(colShape->getContactBreakingThreshold()); //body.SetActivationState(ActivationState.ISLAND_SLEEPING); m_dynamicsWorld.AddRigidBody(body); //body.SetActivationState(ActivationState.ISLAND_SLEEPING); body.SetUserPointer(String.Format("Box X{0} Y{1} Z{2}", k, i, j)); } } } } //ClientResetScene(); }
protected override void Initialize() { base.Initialize(); SetCameraDistance(50.0f); ///collision configuration contains default setup for memory, collision setup m_collisionConfiguration = new DefaultCollisionConfiguration(); //m_collisionConfiguration.setConvexConvexMultipointIterations(); ///use the default collision dispatcher. For parallel processing you can use a diffent dispatcher (see Extras/BulletMultiThreaded) m_dispatcher = new CollisionDispatcher(m_collisionConfiguration); m_broadphase = new DbvtBroadphase(); ///the default constraint solver. For parallel processing you can use a different solver (see Extras/BulletMultiThreaded) m_constraintSolver = new SequentialImpulseConstraintSolver(); m_dynamicsWorld = new DiscreteDynamicsWorld(m_dispatcher, m_broadphase, m_constraintSolver, m_collisionConfiguration); IndexedVector3 gravity = new IndexedVector3(0, -10, 0); m_dynamicsWorld.SetGravity(ref gravity); // NEW => btGhostPairCallback ================================= m_ghostPairCallback = new GhostPairCallback(); m_dynamicsWorld.GetBroadphase().GetOverlappingPairCache().SetInternalGhostPairCallback(m_ghostPairCallback); // Needed once to enable ghost objects inside Bullet // NEW => btGhostObject ======================================= m_ghostObject = new GhostObject(); CollisionShape shape = new BoxShape(new IndexedVector3(5f)); // As far as I know only the world aabb of the shape will be used (i.e. a box always parallel to the x,y,z axis of variable size) m_collisionShapes.Add(shape); m_ghostObject.SetCollisionShape(shape); m_ghostObject.SetCollisionFlags(CollisionFlags.CF_NO_CONTACT_RESPONSE); // We can choose to make it "solid" if we want... m_dynamicsWorld.AddCollisionObject(m_ghostObject, CollisionFilterGroups.SensorTrigger, CollisionFilterGroups.AllFilter & ~CollisionFilterGroups.SensorTrigger); //m_ghostObject.setWorldTransform(btTransform(btQuaternion::getIdentity(),btVector3(0,5,-15))); IndexedMatrix im = IndexedMatrix.CreateFromQuaternion(quatDeg45Y); im._origin = new IndexedVector3(0, 5, -15); m_ghostObject.SetWorldTransform(im); // NEW => btPairCachingGhostObject ============================ m_pairCachingGhostObject = new PairCachingGhostObject(); shape = new ConeShape(7.0f, 14.0f); m_collisionShapes.Add(shape); m_pairCachingGhostObject.SetCollisionShape(shape); m_pairCachingGhostObject.SetCollisionFlags(CollisionFlags.CF_NO_CONTACT_RESPONSE); // We can choose to make it "solid" if we want... m_dynamicsWorld.AddCollisionObject(m_pairCachingGhostObject, CollisionFilterGroups.SensorTrigger, CollisionFilterGroups.AllFilter & ~CollisionFilterGroups.SensorTrigger); //m_pairCachingGhostObject.setWorldTransform(btTransform(btQuaternion::getIdentity(),btVector3(0,5,15))); im._origin = new IndexedVector3(0, 7, 15); m_pairCachingGhostObject.SetWorldTransform(im); //============================================================= ///create a few basic rigid bodies CollisionShape groundShape = new BoxShape(new IndexedVector3(50)); m_collisionShapes.Add(groundShape); IndexedMatrix groundTransform = IndexedMatrix.Identity; groundTransform._origin = new IndexedVector3(0, -50, 0); float mass = 0.0f; LocalCreateRigidBody(mass, groundTransform, groundShape); // spawn some cubes (code pasted from appBasicDemo...) if(true) { //create a few dynamic rigidbodies CollisionShape colShape = new BoxShape(new IndexedVector3(SCALING, SCALING, SCALING)); //btCollisionShape* colShape = new btSphereShape(btScalar(1.)); //CollisionShape colShape = new CylinderShape(new IndexedVector3(1f, 1, 1f)); m_collisionShapes.Add(colShape); /// Create Dynamic Objects IndexedMatrix startTransform = IndexedMatrix.Identity; mass = 1f; //rigidbody is dynamic if and only if mass is non zero, otherwise static bool isDynamic = mass != 0f; IndexedVector3 localInertia = IndexedVector3.Zero; if (isDynamic) { colShape.CalculateLocalInertia(mass, out localInertia); } float start_x = START_POS_X - ARRAY_SIZE_X / 2; float start_y = START_POS_Y; float start_z = START_POS_Z - ARRAY_SIZE_Z / 2; for (int k = 0; k < ARRAY_SIZE_Y; k++) { for (int i = 0; i < ARRAY_SIZE_X; i++) { for (int j = 0; j < ARRAY_SIZE_Z; j++) { startTransform._origin = (new IndexedVector3(2.0f * i + start_x, 20 + 2.0f * k + start_y, 2.0f * j + start_z) * SCALING); //using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects DefaultMotionState myMotionState = new DefaultMotionState(startTransform, IndexedMatrix.Identity); RigidBodyConstructionInfo rbInfo = new RigidBodyConstructionInfo(mass, myMotionState, colShape, localInertia); RigidBody body = new RigidBody(rbInfo); //body.setContactProcessingThreshold(colShape.getContactBreakingThreshold()); body.SetActivationState(ActivationState.ISLAND_SLEEPING); m_dynamicsWorld.AddRigidBody(body); body.SetActivationState(ActivationState.ISLAND_SLEEPING); body.SetUserPointer(String.Format("Box X{0} Y{1} Z{2}", k, i, j)); } } } } ClientResetScene(); }
public virtual void LoadHeightField(float[,] heights, float heightRange, uint vertsX, uint vertsZ, Vector3 loc, int metersPerSample) { //if (worldLoaded == false || metersPerSample > 2) // return; loc = loc / scaleFactor; //heightRange = heightRange * 1000; //loc.X += heightFieldOffset; //loc.z += heightFieldOffset; // these axes are out by about 1m? if (heightFields.ContainsKey(loc)) { int oldMetersPerSample = heightFields[loc]; if (oldMetersPerSample == metersPerSample) { return; // no need to update } else { // we need to delete the old one to rebuild this one foreach (CollisionObject a in m_dynamicsWorld.GetCollisionObjectArray()) { if (a.GetCollisionShape() != null && a.GetCollisionShape().GetShapeType() == BroadphaseNativeTypes.TERRAIN_SHAPE_PROXYTYPE) { string terrainName = (string)a.GetUserPointer(); if (terrainName == "TestHeightField_" + loc) { a.Cleanup(); heightFields.Remove(loc); System.Console.WriteLine("Removed heightmap at position '{0}' with metersPerSample: '{1}' and old: '{2}'", loc, metersPerSample, oldMetersPerSample); break; } } } } } byte[] terr = new byte[vertsX * vertsZ * 4]; MemoryStream file = new MemoryStream(terr); BinaryWriter writer = new BinaryWriter(file); for (int i = 0; i < vertsX; i++) { for (int j = 0; j < vertsZ; j++) { writer.Write((float)((heightRange / 2) + 4 * Math.Sin(j * 0.5f) * Math.Cos(i))); //writer.Write(0f); } } writer.Flush(); file.Position = 0; float heightScale = heightRange / 32767f / scaleFactor; int upAxis = 1; CollisionShape terrainShape = new HeightfieldTerrainShape((int)vertsX, (int)vertsZ, terr, heightScale, 0, heightRange, upAxis, PHY_ScalarType.PHY_FLOAT, true); IndexedMatrix worldTransform = IndexedMatrix.CreateTranslation(loc); DefaultMotionState objectMotionState = new DefaultMotionState(worldTransform, IndexedMatrix.Identity); //terrainShape = new StaticPlaneShape(Vector3.Up, 0f); //IndexedVector3 halfExtents = new IndexedVector3(50, 50, 50); //terrainShape = new BoxShape(ref halfExtents); RigidBodyConstructionInfo rbInfo = new RigidBodyConstructionInfo(0, objectMotionState, terrainShape); RigidBody terrain = new RigidBody(rbInfo); //IndexedMatrix groundTransform = IndexedMatrix.CreateTranslation(new IndexedVector3(0, -50, 0)); IndexedMatrix groundTransform = IndexedMatrix.CreateTranslation(new IndexedVector3(0, -5, 0)); LocalCreateRigidBody(0f, groundTransform, terrainShape); terrain.SetUserPointer("TestHeightField_" + loc.ToString()); //terrain.SetCollisionFlags(CollisionFlags.CF_KINEMATIC_OBJECT); ////m_dynamicsWorld.AddCollisionObject(terrain, CollisionFilterGroups.DefaultFilter, CollisionFilterGroups.AllFilter); //m_dynamicsWorld.AddCollisionObject(terrain); System.Console.WriteLine("Added heightmap at position: '{0}' with metersPerSample: '{1}'", loc, metersPerSample); heightFields.Add(loc, metersPerSample); }
///btRigidBody constructor for backwards compatibility. ///To specify friction (etc) during rigid body construction, please use the other constructor (using btRigidBodyConstructionInfo) public RigidBody(float mass, IMotionState motionState, CollisionShape collisionShape, IndexedVector3 localInertia) { RigidBodyConstructionInfo cinfo = new RigidBodyConstructionInfo(mass,motionState,collisionShape,localInertia); SetupRigidBody(cinfo); }
///setupRigidBody is only used internally by the constructor protected void SetupRigidBody(RigidBodyConstructionInfo constructionInfo) { m_internalType=CollisionObjectTypes.CO_RIGID_BODY; m_linearVelocity = IndexedVector3.Zero; m_angularVelocity = IndexedVector3.Zero; m_angularFactor = IndexedVector3.One; m_linearFactor = IndexedVector3.One; m_gravity = IndexedVector3.Zero; m_gravity_acceleration = IndexedVector3.Zero; m_totalForce = IndexedVector3.Zero; m_totalTorque = IndexedVector3.Zero; SetDamping(constructionInfo.m_linearDamping, constructionInfo.m_angularDamping); m_linearSleepingThreshold = constructionInfo.m_linearSleepingThreshold; m_angularSleepingThreshold = constructionInfo.m_angularSleepingThreshold; m_optionalMotionState = constructionInfo.m_motionState; m_contactSolverType = 0; m_frictionSolverType = 0; m_additionalDamping = constructionInfo.m_additionalDamping; m_additionalDampingFactor = constructionInfo.m_additionalDampingFactor; m_additionalLinearDampingThresholdSqr = constructionInfo.m_additionalLinearDampingThresholdSqr; m_additionalAngularDampingThresholdSqr = constructionInfo.m_additionalAngularDampingThresholdSqr; m_additionalAngularDampingFactor = constructionInfo.m_additionalAngularDampingFactor; if (m_optionalMotionState != null) { m_optionalMotionState.GetWorldTransform(out m_worldTransform); } else { SetWorldTransform(ref constructionInfo.m_startWorldTransform); } m_interpolationWorldTransform = m_worldTransform; m_interpolationLinearVelocity = IndexedVector3.Zero; m_interpolationAngularVelocity = IndexedVector3.Zero; //moved to btCollisionObject m_friction = constructionInfo.m_friction; m_restitution = constructionInfo.m_restitution; SetCollisionShape( constructionInfo.m_collisionShape ); m_debugBodyId = uniqueId++; SetMassProps(constructionInfo.m_mass, constructionInfo.m_localInertia); UpdateInertiaTensor(); m_rigidbodyFlags = RigidBodyFlags.BT_NONE; m_constraintRefs = new List<TypedConstraint>(); m_deltaLinearVelocity = IndexedVector3.Zero; m_deltaAngularVelocity = IndexedVector3.Zero; m_invMass = m_inverseMass * m_linearFactor; m_pushVelocity = IndexedVector3.Zero; m_turnVelocity = IndexedVector3.Zero; }
//---------------------------------------------------------------------------------------------- public RigidBody LocalCreateRigidBodyMultiWorld(float mass, ref IndexedMatrix startTransform, CollisionShape shape, DiscreteDynamicsWorld world) { Debug.Assert((shape == null || shape.GetShapeType() != BroadphaseNativeTypes.INVALID_SHAPE_PROXYTYPE)); //rigidbody is dynamic if and only if mass is non zero, otherwise static bool isDynamic = !MathUtil.CompareFloat(mass, 0f); IndexedVector3 localInertia = IndexedVector3.Zero; if (isDynamic) { shape.CalculateLocalInertia(mass, out localInertia); } //using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects //#define USE_MOTIONSTATE 1 //#ifdef USE_MOTIONSTATE DefaultMotionState myMotionState = new DefaultMotionState(startTransform, IndexedMatrix.Identity); RigidBodyConstructionInfo cInfo = new RigidBodyConstructionInfo(mass, myMotionState, shape, localInertia); RigidBody body = new RigidBody(cInfo); if (BulletGlobals.g_streamWriter != null && true) { BulletGlobals.g_streamWriter.WriteLine("localCreateRigidBody [{0}] startTransform", body.m_debugBodyId); MathUtil.PrintMatrix(BulletGlobals.g_streamWriter, startTransform); BulletGlobals.g_streamWriter.WriteLine(""); } world.AddRigidBody(body); return body; }
public void BuildCollisionData(Color[] map, int width, int height, Vector3 bottomLeft) { Vector2 dim = Vector2.One; Vector3 scale = new Vector3(dim, 1); BoxShape collisionBoxShape = new BoxShape(new IndexedVector3(0.5f)); for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { int currentIndex = x + y * width; if (map[currentIndex] == Color.White) { float yOffset = -dim.Y;//0f;// -(dim.Y / 2f); Vector3 position = new Vector3(x - bottomLeft.X, (bottomLeft.Y - y) + yOffset, bottomLeft.Z); m_waterLocations.Add(position); } if (map[currentIndex] == Color.White) { // check the 4 ordinals , if we're surrounded by other solid blocks // then we don't need a block here. bool upSet = false; bool downSet = false; bool leftSet = false; bool rightSet = false; if (x >= 1 && x < width - 1) { if (map[currentIndex - 1] == Color.White) { leftSet = true; } if (map[currentIndex + 1] == Color.White) { rightSet = true; } } if (y >= 1 && y < height - 1) { if (map[currentIndex - height] == Color.White) { upSet = true; } if (map[currentIndex + height] == Color.White) { downSet = true; } } // if we're not surrounded by blocks then add in. if (!(upSet && downSet && leftSet && rightSet)) { Object rigifdBody; float yOffset = -dim.Y;//0f;// -(dim.Y / 2f); Vector3 position = new Vector3(x - bottomLeft.X, (bottomLeft.Y - y) + yOffset, bottomLeft.Z); RigidBodyConstructionInfo constructionInfo = new BulletXNA.BulletDynamics.RigidBodyConstructionInfo(0f, null, (BulletXNA.BulletCollision.CollisionShape)collisionBoxShape); RigidBody rigidBody = new BulletXNA.BulletDynamics.RigidBody(constructionInfo); Matrix bsm = Matrix.CreateTranslation(position); rigidBody.SetWorldTransform(bsm); // FIXME MAN - setup some collision flags on these bodies... BulletXNA.BulletCollision.CollisionFilterGroups flags = (BulletXNA.BulletCollision.CollisionFilterGroups)(1 << 8); BulletXNA.BulletCollision.CollisionFilterGroups mask = (BulletXNA.BulletCollision.CollisionFilterGroups)(1 << 9); //rigidBody.CollisionFlags |= (BulletSharp.CollisionFlags)CollisionObjectType.Ground; m_dynamicsWorld.AddRigidBody(rigidBody, flags, mask); } } // Build water ghost objects. foreach (Vector3 pos in m_waterLocations) { GhostObject ghostObject = new GhostObject(); ghostObject.SetCollisionShape((BulletXNA.BulletCollision.CollisionShape)collisionBoxShape); CollisionFilterGroups flags = (CollisionFilterGroups)(1 << 10); CollisionFilterGroups mask = (CollisionFilterGroups)(1<<9); ghostObject.SetCollisionFlags(CollisionFlags.CF_NO_CONTACT_RESPONSE | CollisionFlags.CF_STATIC_OBJECT); // We can choose to make it "solid" if we want... ghostObject.SetWorldTransform(BulletXNA.LinearMath.IndexedMatrix.CreateTranslation(pos)); m_dynamicsWorld.AddCollisionObject(ghostObject, flags, mask); break; } } } }