public override void InitializeDemo() { base.InitializeDemo(); SetCameraDistance(SCALING * 50f); //string filename = @"C:\users\man\bullett\xna-largemesh-output.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); m_broadphase = new DbvtBroadphase(); IOverlappingPairCache pairCache = null; //pairCache = new SortedOverlappingPairCache(); //m_broadphase = new SimpleBroadphase(10000, 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); m_profileManager = new BasicProfileManager(); BulletGlobals.g_profileManager = m_profileManager; m_profileIterator = m_profileManager.getIterator(); ///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), 0); LocalCreateRigidBody(0f, IndexedMatrix.Identity, groundShape); //CollisionShape groundShape = BuildLargeMesh(); m_collisionShapes.Add(groundShape); CollisionShape sphereShape = new SphereShape(0.2f); int size = 16;// 5; // 16 for (int i = 0; i < size; ++i) { for (int j = 0; j < size; ++j) { IndexedMatrix m = IndexedMatrix.CreateTranslation(new IndexedVector3(i, 1, j)); RigidBody rb = LocalCreateRigidBody(1f, m, sphereShape); rb.SetActivationState(ActivationState.ISLAND_SLEEPING); } } ClientResetScene(); }
//(PhysicsScene.World.ptr, nativeShapeData) public override BulletShape BuildNativeShape(BulletWorld pWorld, ShapeData pShapeData) { DiscreteDynamicsWorld world = (pWorld as BulletWorldXNA).world; 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 new BulletShapeXNA(shape, pShapeData.Type); }
//////////////////////////////////////////////////////////////////////////////// // // TerrainDemo -- private helper methods // //////////////////////////////////////////////////////////////////////////////// /// called whenever key terrain attribute is changed public override void ClientResetScene() { base.ClientResetScene(); // remove old heightfield m_rawHeightfieldData = null; // reset gravity to point in appropriate direction //m_dynamicsWorld.setGravity(getUpVector(m_upAxis, 0.0f, -s_gravity)); m_dynamicsWorld.SetGravity(ref m_defaultGravity); // get new heightfield of appropriate type m_rawHeightfieldData = GetRawHeightfieldData(m_model, m_type, ref m_minHeight, ref m_maxHeight); Debug.Assert(m_rawHeightfieldData != null , "failed to create raw heightfield"); if (m_terrainRigidBody != null) { m_dynamicsWorld.RemoveCollisionObject(m_terrainRigidBody); m_terrainRigidBody = null; m_terrainShape = null; m_collisionShapes.Remove(m_terrainShape); } bool flipQuadEdges = false; m_terrainShape = new HeightfieldTerrainShape(s_gridSize, s_gridSize, m_rawHeightfieldData, s_gridHeightScale, m_minHeight, m_maxHeight, m_upAxis, m_type, flipQuadEdges); Debug.Assert(m_terrainShape != null, "null heightfield"); // scale the shape IndexedVector3 localScaling = GetUpVector(m_upAxis, s_gridSpacing, 1.0f); m_terrainShape.SetLocalScaling(ref localScaling); // stash this shape away m_collisionShapes.Add(m_terrainShape); // set origin to middle of heightfield IndexedMatrix tr = IndexedMatrix.CreateTranslation(new IndexedVector3(0,-20,0)); // create ground object float mass = 0.0f; m_terrainRigidBody = LocalCreateRigidBody(mass, ref tr, m_terrainShape); CollisionShape sphere = new SphereShape(0.5f); tr = IndexedMatrix.CreateTranslation(new IndexedVector3(0, 0, 0)); LocalCreateRigidBody(1f,ref tr,sphere); }
public virtual void GetAabbNonVirtual(ref IndexedMatrix t, ref IndexedVector3 aabbMin, ref IndexedVector3 aabbMax) { switch (m_shapeType) { case BroadphaseNativeTypes.SPHERE_SHAPE_PROXYTYPE: { SphereShape sphereShape = this as SphereShape; float radius = sphereShape.GetImplicitShapeDimensions().X;// * convexShape->getLocalScaling().getX(); float margin = radius + sphereShape.GetMarginNonVirtual(); IndexedVector3 center = t._origin; IndexedVector3 extent = new IndexedVector3(margin); aabbMin = center - extent; aabbMax = center + extent; } break; case BroadphaseNativeTypes.CYLINDER_SHAPE_PROXYTYPE: /* fall through */ case BroadphaseNativeTypes.BOX_SHAPE_PROXYTYPE: { BoxShape convexShape = this as BoxShape; float margin = convexShape.GetMarginNonVirtual(); IndexedVector3 halfExtents = convexShape.GetImplicitShapeDimensions(); halfExtents += new IndexedVector3(margin); IndexedBasisMatrix abs_b = t._basis.Absolute(); IndexedVector3 center = t._origin; IndexedVector3 extent = new IndexedVector3(abs_b._el0.Dot(ref halfExtents), abs_b._el1.Dot(ref halfExtents), abs_b._el2.Dot(ref halfExtents)); aabbMin = center - extent; aabbMax = center + extent; break; } case BroadphaseNativeTypes.TRIANGLE_SHAPE_PROXYTYPE: { TriangleShape triangleShape = (TriangleShape)this; float margin = triangleShape.GetMarginNonVirtual(); for (int i = 0; i < 3; i++) { IndexedVector3 vec = new IndexedVector3(); vec[i] = 1f; IndexedVector3 sv = LocalGetSupportVertexWithoutMarginNonVirtual(vec * t._basis); IndexedVector3 tmp = t * sv; aabbMax[i] = tmp[i] + margin; vec[i] = -1.0f; tmp = t * (LocalGetSupportVertexWithoutMarginNonVirtual(vec * t._basis)); aabbMin[i] = tmp[i] - margin; } } break; case BroadphaseNativeTypes.CAPSULE_SHAPE_PROXYTYPE: { CapsuleShape capsuleShape = this as CapsuleShape; float r = capsuleShape.GetRadius(); IndexedVector3 halfExtents = new IndexedVector3(r); int m_upAxis = capsuleShape.GetUpAxis(); halfExtents[m_upAxis] = r + capsuleShape.GetHalfHeight(); float nvMargin = capsuleShape.GetMarginNonVirtual(); halfExtents += new IndexedVector3(nvMargin); IndexedBasisMatrix abs_b = t._basis.Absolute(); IndexedVector3 center = t._origin; IndexedVector3 extent = new IndexedVector3(abs_b._el0.Dot(ref halfExtents), abs_b._el1.Dot(ref halfExtents), abs_b._el2.Dot(ref halfExtents)); aabbMin = center - extent; aabbMax = center + extent; } break; case BroadphaseNativeTypes.CONVEX_POINT_CLOUD_SHAPE_PROXYTYPE: case BroadphaseNativeTypes.CONVEX_HULL_SHAPE_PROXYTYPE: { PolyhedralConvexAabbCachingShape convexHullShape = (PolyhedralConvexAabbCachingShape)this; float margin = convexHullShape.GetMarginNonVirtual(); convexHullShape.GetNonvirtualAabb(ref t, out aabbMin, out aabbMax, margin); } break; default: GetAabb(ref t, out aabbMin, out aabbMax); break; } // should never reach here Debug.Assert(false); }
public override float CalculateTimeOfImpact(CollisionObject body0, CollisionObject body1, DispatcherInfo dispatchInfo, ManifoldResult resultOut) { ///Rather then checking ALL pairs, only calculate TOI when motion exceeds threshold ///Linear motion for one of objects needs to exceed m_ccdSquareMotionThreshold ///body0.m_worldTransform, float resultFraction = 1.0f; float squareMot0 = (body0.GetInterpolationWorldTransform()._origin - body0.GetWorldTransform()._origin).LengthSquared(); float squareMot1 = (body1.GetInterpolationWorldTransform()._origin - body1.GetWorldTransform()._origin).LengthSquared(); if (squareMot0 < body0.GetCcdSquareMotionThreshold() && squareMot1 < body1.GetCcdSquareMotionThreshold()) { return(resultFraction); } //An adhoc way of testing the Continuous Collision Detection algorithms //One object is approximated as a sphere, to simplify things //Starting in penetration should report no time of impact //For proper CCD, better accuracy and handling of 'allowed' penetration should be added //also the mainloop of the physics should have a kind of toi queue (something like Brian Mirtich's application of Timewarp for Rigidbodies) /// Convex0 against sphere for Convex1 { ConvexShape convex0 = body0.GetCollisionShape() as ConvexShape; SphereShape sphere1 = BulletGlobals.SphereShapePool.Get(); sphere1.Initialize(body1.GetCcdSweptSphereRadius()); //todo: allow non-zero sphere sizes, for better approximation CastResult result = BulletGlobals.CastResultPool.Get(); VoronoiSimplexSolver voronoiSimplex = BulletGlobals.VoronoiSimplexSolverPool.Get(); //SubsimplexConvexCast ccd0(&sphere,min0,&voronoiSimplex); ///Simplification, one object is simplified as a sphere using (GjkConvexCast ccd1 = BulletGlobals.GjkConvexCastPool.Get()) { ccd1.Initialize(convex0, sphere1, voronoiSimplex); //ContinuousConvexCollision ccd(min0,min1,&voronoiSimplex,0); if (ccd1.CalcTimeOfImpact(body0.GetWorldTransform(), body0.GetInterpolationWorldTransform(), body1.GetWorldTransform(), body1.GetInterpolationWorldTransform(), result)) { //store result.m_fraction in both bodies if (body0.GetHitFraction() > result.m_fraction) { body0.SetHitFraction(result.m_fraction); } if (body1.GetHitFraction() > result.m_fraction) { body1.SetHitFraction(result.m_fraction); } if (resultFraction > result.m_fraction) { resultFraction = result.m_fraction; } } BulletGlobals.VoronoiSimplexSolverPool.Free(voronoiSimplex); BulletGlobals.SphereShapePool.Free(sphere1); result.Cleanup(); } } /// Sphere (for convex0) against Convex1 { ConvexShape convex1 = body1.GetCollisionShape() as ConvexShape; SphereShape sphere0 = BulletGlobals.SphereShapePool.Get(); sphere0.Initialize(body0.GetCcdSweptSphereRadius()); //todo: allow non-zero sphere sizes, for better approximation CastResult result = BulletGlobals.CastResultPool.Get(); VoronoiSimplexSolver voronoiSimplex = BulletGlobals.VoronoiSimplexSolverPool.Get(); //SubsimplexConvexCast ccd0(&sphere,min0,&voronoiSimplex); ///Simplification, one object is simplified as a sphere using (GjkConvexCast ccd1 = BulletGlobals.GjkConvexCastPool.Get()) { ccd1.Initialize(sphere0, convex1, voronoiSimplex); //ContinuousConvexCollision ccd(min0,min1,&voronoiSimplex,0); if (ccd1.CalcTimeOfImpact(body0.GetWorldTransform(), body0.GetInterpolationWorldTransform(), body1.GetWorldTransform(), body1.GetInterpolationWorldTransform(), result)) { //store result.m_fraction in both bodies if (body0.GetHitFraction() > result.m_fraction) { body0.SetHitFraction(result.m_fraction); } if (body1.GetHitFraction() > result.m_fraction) { body1.SetHitFraction(result.m_fraction); } if (resultFraction > result.m_fraction) { resultFraction = result.m_fraction; } } BulletGlobals.VoronoiSimplexSolverPool.Free(voronoiSimplex); BulletGlobals.SphereShapePool.Free(sphere0); result.Cleanup(); } } return(resultFraction); }
//(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; }
public void Initialize(SphereShape sphere, TriangleShape triangle, float contactBreakingThreshold) { m_sphere = sphere; m_triangle = triangle; m_contactBreakingThreshold = contactBreakingThreshold; }
} // for pool public SphereTriangleDetector(SphereShape sphere, TriangleShape triangle, float contactBreakingThreshold) { m_sphere = sphere; m_triangle = triangle; m_contactBreakingThreshold = contactBreakingThreshold; }
public void InitializePhysicsBulletXNA() { #if BULLETXNA CollisionFilterGroups colGroup = CollisionFilterGroups.DefaultFilter; CollisionFilterGroups colMask = CollisionFilterGroups.AllFilter; float sphereMass = 5f; CollisionShape sphereShape = new Bullet.BulletCollision.SphereShape(1); Bullet.LinearMath.IndexedVector3 sphereLocalInertia; sphereShape.CalculateLocalInertia(sphereMass, out sphereLocalInertia); BulletXNAObject ball = new BulletXNAObject(this, "Models/Sphere", sphereMass, new Bullet.DefaultMotionState(Matrix.CreateTranslation(camera.Position + new Vector3(0, 10, -5)), Matrix.Identity), sphereShape, sphereLocalInertia, colGroup, colMask); ball.TranslateAA(camera.Position + new Vector3(0, 10, 0)); ball.TextureMaterials.Add("Textures/core1"); ball.NormalMaterials.Add("Textures/core1Normal"); ball.RigidBody.SetFriction(1); boxs.Add(ball); Components.Add(ball); // create a few dynamic rigidbodies float mass = 1.0f; Bullet.BulletCollision.CollisionShape colShape = new Bullet.BulletCollision.BoxShape(Vector3.One); //CollisionShapes.Add(colShape); Vector3 localInertia = Vector3.Zero; Bullet.LinearMath.IndexedVector3 li = Bullet.LinearMath.IndexedVector3.Zero; colShape.CalculateLocalInertia(mass, out li); localInertia = li; float start_x = StartPosX - ArraySizeX / 2; float start_y = StartPosY; float start_z = StartPosZ - ArraySizeZ / 2; start_z -= 8; Random rnd = new Random(); int k, i, j; for (k = 0; k < ArraySizeY; k++) { for (i = 0; i < ArraySizeX; i++) { for (j = 0; j < ArraySizeZ; j++) { Matrix startTransform = Matrix.CreateTranslation( 2 * i + start_x, 2 * k + start_y, 2 * j + start_z ); // using motionstate is recommended, it provides interpolation capabilities // and only synchronizes 'active' objects BulletXNAObject box = new BulletXNAObject(this, "Models/Box", mass, new Bullet.DefaultMotionState(startTransform, Matrix.Identity), colShape, localInertia, colGroup, colMask); box.TextureMaterials.Add("Textures/BoxColor"); box.NormalMaterials.Add("Textures/BoxNormal"); box.TranslateAA(new Vector3(0, 7, 0)); boxs.Add(box); Components.Add(box); } } } start_x -= 8; for (k = 0; k < 2; k++) { for (i = 0; i < 2; i++) { for (j = 0; j < 2; j++) { Matrix startTransform = Matrix.CreateTranslation( 2 * i + start_x, 2 * k + start_y, 2 * j + start_z ); // using motionstate is recommended, it provides interpolation capabilities // and only synchronizes 'active' objects BulletXNAObject box = new BulletXNAObject(this, "Models/Box", mass, new Bullet.DefaultMotionState(startTransform, Matrix.Identity), colShape, localInertia, colGroup, colMask); box.TextureMaterials.Add("Textures/BoxColor01"); box.NormalMaterials.Add("Textures/BoxNormal01"); box.TranslateAA(new Vector3(0, 7, 0)); boxs.Add(box); Components.Add(box); } } } IsPhysicsEnabled = false; #endif }
public SphereTriangleDetector() { } // for pool public SphereTriangleDetector(SphereShape sphere, TriangleShape triangle, float contactBreakingThreshold) { m_sphere = sphere; m_triangle = triangle; m_contactBreakingThreshold = contactBreakingThreshold; }
private void BuildBoard() { float width = 40; float height = 40; IndexedVector3 boardBackExtents = new IndexedVector3(width,height,2) /2f; IndexedVector3 boardSideExtents = new IndexedVector3(1,height,2) /2f; IndexedVector3 boardBarExtents = new IndexedVector3(width,1,2)/2f; IndexedVector3 pinExtent = new IndexedVector3(0.5f,1f,2f); IndexedVector3 boardCenter = new IndexedVector3(0,0,0); // build frame.objects BoxShape boardBack = new BoxShape(boardBackExtents); BoxShape boardSide = new BoxShape(boardSideExtents); BoxShape boardBar = new BoxShape(boardBarExtents); StaticPlaneShape boardFront = new StaticPlaneShape(new IndexedVector3(0,0,-1),-(boardBackExtents.Z+boardSideExtents.Z)); CollisionShape pinShape = new CapsuleShapeZ(pinExtent.Y,pinExtent.Z); //pinShape = new BoxShape(pinExtent); //pinShape = new SphereShape(pinExtent.Y); m_cameraUp = Vector3.Up; // now RB's Matrix m = Matrix.Identity; IndexedMatrix trans = m; trans._origin = boardCenter; float mass = 0f; //LocalCreateRigidBody(mass,trans,boardBack); //LocalCreateRigidBody(mass, trans, boardFront); IndexedVector3 leftSide = new IndexedVector3(boardCenter.X - boardBackExtents.X + boardSideExtents.X, boardCenter.Y, boardCenter.Z + boardSideExtents.Z); IndexedVector3 rightSide = new IndexedVector3(boardCenter.X + boardBackExtents.X - boardSideExtents.X, boardCenter.Y, boardCenter.Z + boardSideExtents.Z); IndexedVector3 topBar = new IndexedVector3(boardCenter.X, boardCenter.Y + boardBackExtents.Y - boardBarExtents.Y, boardCenter.Z + boardSideExtents.Z); IndexedVector3 bottomBar = new IndexedVector3(boardCenter.X, boardCenter.Y - boardBackExtents.Y + boardBarExtents.Y, boardCenter.Z + boardSideExtents.Z); trans._origin = leftSide; LocalCreateRigidBody(mass, trans, boardSide); trans._origin = rightSide; LocalCreateRigidBody(mass, trans, boardSide); trans._origin = topBar; LocalCreateRigidBody(mass, trans, boardBar); trans._origin = bottomBar; LocalCreateRigidBody(mass, trans, boardBar); // now place the pins? (simple offset grid to start) int numPinsX = 8; int numPinsY = 8; // fixme IndexedVector3 pinTopLeft = new IndexedVector3(-boardBackExtents.X + 4, boardBackExtents.Y - 5, boardCenter.Z + boardSideExtents.Z); IndexedVector3 pinSpacer = new IndexedVector3(pinExtent.Y * 4f, -pinExtent.Y * 4f, 0); float ballRadius = 0.9f; float fudge = 3f; m_dropSphereShape = new SphereShape(ballRadius); m_ballDropSpot = new Vector3(1f, pinTopLeft.Y + 1, boardCenter.Z + boardBackExtents.Z+ballRadius); //new SphereShape(0.95f); m_debugDraw.SetDebugMode(m_debugDraw.GetDebugMode() | DebugDrawModes.DBG_DrawAabb); trans._origin = pinTopLeft; LocalCreateRigidBody(mass, trans, pinShape); for (int i = 0; i < numPinsX; ++i) { for (int j = 0; j < numPinsY; ++j) { IndexedVector3 pos = new IndexedVector3(pinSpacer.X * i, (pinSpacer.Y * j), pinSpacer.Z); // stagger rows. if (j % 2 == 1) { pos.X += pinSpacer.X/2f; } trans._origin = pinTopLeft + pos; LocalCreateRigidBody(mass, trans, pinShape); } } }
public void InitializePhysicsBulletXNA() { #if BULLETXNA CollisionFilterGroups colGroup = CollisionFilterGroups.DefaultFilter; CollisionFilterGroups colMask = CollisionFilterGroups.AllFilter; float sphereMass = 5f; CollisionShape sphereShape = new Bullet.BulletCollision.SphereShape(1); Bullet.LinearMath.IndexedVector3 sphereLocalInertia; sphereShape.CalculateLocalInertia(sphereMass,out sphereLocalInertia); BulletXNAObject ball = new BulletXNAObject(this, "Models/Sphere", sphereMass, new Bullet.DefaultMotionState(Matrix.CreateTranslation(camera.Position + new Vector3(0, 10, -5)), Matrix.Identity),sphereShape , sphereLocalInertia, colGroup, colMask); ball.TranslateAA(camera.Position + new Vector3(0, 10, 0)); ball.TextureMaterials.Add("Textures/core1"); ball.NormalMaterials.Add("Textures/core1Normal"); ball.RigidBody.SetFriction(1); boxs.Add(ball); Components.Add(ball); // create a few dynamic rigidbodies float mass = 1.0f; Bullet.BulletCollision.CollisionShape colShape = new Bullet.BulletCollision.BoxShape(Vector3.One); //CollisionShapes.Add(colShape); Vector3 localInertia = Vector3.Zero; Bullet.LinearMath.IndexedVector3 li = Bullet.LinearMath.IndexedVector3.Zero; colShape.CalculateLocalInertia(mass, out li); localInertia = li; float start_x = StartPosX - ArraySizeX / 2; float start_y = StartPosY; float start_z = StartPosZ - ArraySizeZ / 2; start_z -= 8; Random rnd = new Random(); int k, i, j; for (k = 0; k < ArraySizeY; k++) { for (i = 0; i < ArraySizeX; i++) { for (j = 0; j < ArraySizeZ; j++) { Matrix startTransform = Matrix.CreateTranslation( 2 * i + start_x, 2 * k + start_y, 2 * j + start_z ); // using motionstate is recommended, it provides interpolation capabilities // and only synchronizes 'active' objects BulletXNAObject box = new BulletXNAObject(this, "Models/Box", mass, new Bullet.DefaultMotionState(startTransform, Matrix.Identity), colShape, localInertia, colGroup, colMask); box.TextureMaterials.Add("Textures/BoxColor"); box.NormalMaterials.Add("Textures/BoxNormal"); box.TranslateAA(new Vector3(0, 7, 0)); boxs.Add(box); Components.Add(box); } } } start_x -= 8; for (k = 0; k < 2; k++) { for (i = 0; i < 2; i++) { for (j = 0; j < 2; j++) { Matrix startTransform = Matrix.CreateTranslation( 2 * i + start_x, 2 * k + start_y, 2 * j + start_z ); // using motionstate is recommended, it provides interpolation capabilities // and only synchronizes 'active' objects BulletXNAObject box = new BulletXNAObject(this, "Models/Box", mass, new Bullet.DefaultMotionState(startTransform, Matrix.Identity), colShape, localInertia, colGroup, colMask); box.TextureMaterials.Add("Textures/BoxColor01"); box.NormalMaterials.Add("Textures/BoxNormal01"); box.TranslateAA(new Vector3(0, 7, 0)); boxs.Add(box); Components.Add(box); } } } IsPhysicsEnabled = false; #endif }