//---------------------------------------------------------------------------------------------- public virtual void RenderScenePassMultiWorld(int pass, GameTime gameTime, DiscreteDynamicsWorld world) { IndexedMatrix m = IndexedMatrix.Identity; IndexedBasisMatrix rot = IndexedBasisMatrix.Identity; int numObjects = world.GetNumCollisionObjects(); IndexedVector3 wireColor = new IndexedVector3(1, 0, 0); for (int i = 0; i < numObjects; i++) { CollisionObject colObj = world.GetCollisionObjectArray()[i]; RigidBody body = RigidBody.Upcast(colObj); if (body != null && body.GetMotionState() != null) { DefaultMotionState myMotionState = (DefaultMotionState)body.GetMotionState(); //myMotionState.m_graphicsWorldTrans.getOpenGLMatrix(m); m = myMotionState.m_graphicsWorldTrans; rot = myMotionState.m_graphicsWorldTrans._basis; } else { //colObj.getWorldTransform().getOpenGLMatrix(m); m = colObj.GetWorldTransform(); rot = colObj.GetWorldTransform()._basis; } wireColor = new IndexedVector3(1.0f, 1.0f, 0.5f); //wants deactivation if ((i & 1) != 0) { wireColor = new IndexedVector3(0f, 0f, 1f); } ///color differently for active, sleeping, wantsdeactivation states if (colObj.GetActivationState() == ActivationState.ACTIVE_TAG) //active { if ((i & 1) != 0) { wireColor += new IndexedVector3(1f, 0f, 0f); } else { wireColor += new IndexedVector3(.5f, 0f, 0f); } } if (colObj.GetActivationState() == ActivationState.ISLAND_SLEEPING) //ISLAND_SLEEPING { if ((i & 1) != 0) { wireColor += new IndexedVector3(0f, 1f, 0f); } else { wireColor += new IndexedVector3(0f, 05f, 0f); } } IndexedVector3 min, max; world.GetBroadphase().GetBroadphaseAabb(out min, out max); min -= MathUtil.MAX_VECTOR; max += MathUtil.MAX_VECTOR; // printf("aabbMin=(%f,%f,%f)\n",aabbMin.getX(),aabbMin.getY(),aabbMin.getZ()); // printf("aabbMax=(%f,%f,%f)\n",aabbMax.getX(),aabbMax.getY(),aabbMax.getZ()); // m_dynamicsWorld.getDebugDrawer().drawAabb(aabbMin,aabbMax,btVector3(1,1,1)); switch (pass) { case 0: { m_shapeDrawer.DrawXNA(ref m, colObj.GetCollisionShape(), ref wireColor, m_debugDraw.GetDebugMode(), ref min, ref max, ref m_lookAt, ref m_perspective); break; } case 1: { IndexedVector3 shadow = rot * m_lightDirection; m_shapeDrawer.DrawShadow(ref m, ref shadow, colObj.GetCollisionShape(), ref min, ref max); break; } case 2: { IndexedVector3 adjustedWireColor = wireColor * 0.3f; m_shapeDrawer.DrawXNA(ref m, colObj.GetCollisionShape(), ref adjustedWireColor, 0, ref min, ref max, ref m_lookAt, ref m_perspective); break; } } } }
//---------------------------------------------------------------------------------------------- protected virtual void RenderScenePassMultiWorld(int pass, GameTime gameTime,DiscreteDynamicsWorld world) { IndexedMatrix m = IndexedMatrix.Identity; IndexedBasisMatrix rot = IndexedBasisMatrix.Identity; int numObjects = world.GetNumCollisionObjects(); IndexedVector3 wireColor = new IndexedVector3(1, 0, 0); for (int i = 0; i < numObjects; i++) { CollisionObject colObj = world.GetCollisionObjectArray()[i]; RigidBody body = RigidBody.Upcast(colObj); if (body != null && body.GetMotionState() != null) { DefaultMotionState myMotionState = (DefaultMotionState)body.GetMotionState(); //myMotionState.m_graphicsWorldTrans.getOpenGLMatrix(m); m = myMotionState.m_graphicsWorldTrans; rot = myMotionState.m_graphicsWorldTrans._basis; } else { //colObj.getWorldTransform().getOpenGLMatrix(m); m = colObj.GetWorldTransform(); rot = colObj.GetWorldTransform()._basis; } wireColor = new IndexedVector3(1.0f, 1.0f, 0.5f); //wants deactivation if ((i & 1) != 0) wireColor = new IndexedVector3(0f, 0f, 1f); ///color differently for active, sleeping, wantsdeactivation states if (colObj.GetActivationState() == ActivationState.ACTIVE_TAG) //active { if ((i & 1) != 0) { wireColor += new IndexedVector3(1f, 0f, 0f); } else { wireColor += new IndexedVector3(.5f, 0f, 0f); } } if (colObj.GetActivationState() == ActivationState.ISLAND_SLEEPING) //ISLAND_SLEEPING { if ((i & 1) != 0) { wireColor += new IndexedVector3(0f, 1f, 0f); } else { wireColor += new IndexedVector3(0f, 05f, 0f); } } IndexedVector3 min, max; world.GetBroadphase().GetBroadphaseAabb(out min, out max); min -= MathUtil.MAX_VECTOR; max += MathUtil.MAX_VECTOR; // printf("aabbMin=(%f,%f,%f)\n",aabbMin.getX(),aabbMin.getY(),aabbMin.getZ()); // printf("aabbMax=(%f,%f,%f)\n",aabbMax.getX(),aabbMax.getY(),aabbMax.getZ()); // m_dynamicsWorld.getDebugDrawer().drawAabb(aabbMin,aabbMax,btVector3(1,1,1)); switch (pass) { case 0: { m_shapeDrawer.DrawXNA(ref m, colObj.GetCollisionShape(), ref wireColor, m_debugDraw.GetDebugMode(), ref min, ref max, ref m_lookAt, ref m_perspective); break; } case 1: { IndexedVector3 shadow = rot * m_lightDirection; m_shapeDrawer.DrawShadow(ref m, ref shadow, colObj.GetCollisionShape(), ref min, ref max); break; } case 2: { IndexedVector3 adjustedWireColor = wireColor * 0.3f; m_shapeDrawer.DrawXNA(ref m, colObj.GetCollisionShape(), ref adjustedWireColor, 0, ref min, ref max, ref m_lookAt, ref m_perspective); break; } } } }
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(); }
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(); }