public void SetUp() { conf = new DefaultCollisionConfiguration(); dispatcher = new CollisionDispatcher(conf); broadphase = new AxisSweep3(new Vector3(-1000, -1000, -1000), new Vector3(1000, 1000, 1000)); world = new DiscreteDynamicsWorld(dispatcher, broadphase, null, conf); // Initialize TriangleIndexVertexArray with float array indexVertexArray = new TriangleIndexVertexArray(TorusMesh.Indices, TorusMesh.Vertices); gImpactMeshShape = new GImpactMeshShape(indexVertexArray); gImpactMeshShape.CalculateLocalInertia(1.0f); gImpactMesh = CreateBody(1.0f, gImpactMeshShape, Vector3.Zero); // Initialize TriangleIndexVertexArray with Vector3 array Vector3[] torusVertices = new Vector3[TorusMesh.Vertices.Length / 3]; for (int i = 0; i < torusVertices.Length; i++) { torusVertices[i] = new Vector3( TorusMesh.Vertices[i * 3], TorusMesh.Vertices[i * 3 + 1], TorusMesh.Vertices[i * 3 + 2]); } indexVertexArray2 = new TriangleIndexVertexArray(TorusMesh.Indices, torusVertices); triangleMeshShape = new BvhTriangleMeshShape(indexVertexArray2, true); // CalculateLocalInertia must fail for static shapes (shapes based on TriangleMeshShape) //triangleMeshShape.CalculateLocalInertia(1.0f); triangleMesh = CreateBody(0.0f, triangleMeshShape, Vector3.Zero); }
public override void Run() { var conf = new DefaultCollisionConfiguration(); var dispatcher = new CollisionDispatcher(conf); var broadphase = new AxisSweep3(new Vector3(-1000, -1000, -1000), new Vector3(1000, 1000, 1000)); world = new DiscreteDynamicsWorld(dispatcher, broadphase, null, conf); var indexVertexArray = new TriangleIndexVertexArray(TorusMesh.Indices, TorusMesh.Vertices); foreach (var indexedMesh in indexVertexArray.IndexedMeshArray) { indexedMesh.ToString(); } AddToDisposeQueue(indexVertexArray); var gImpactMesh = new GImpactMeshShape(indexVertexArray); Vector3 aabbMin, aabbMax; gImpactMesh.GetAabb(Matrix.Identity, out aabbMin, out aabbMax); CreateBody(1.0f, gImpactMesh, Vector3.Zero); AddToDisposeQueue(gImpactMesh); gImpactMesh = null; var triangleMesh = new BvhTriangleMeshShape(indexVertexArray, true); triangleMesh.CalculateLocalInertia(1.0f); triangleMesh.GetAabb(Matrix.Identity, out aabbMin, out aabbMax); CreateBody(1.0f, triangleMesh, Vector3.Zero); AddToDisposeQueue(triangleMesh); triangleMesh = null; indexVertexArray = null; AddToDisposeQueue(conf); AddToDisposeQueue(dispatcher); AddToDisposeQueue(broadphase); AddToDisposeQueue(world); //conf.Dispose(); conf = null; //dispatcher.Dispose(); dispatcher = null; //broadphase.Dispose(); broadphase = null; for (int i = 0; i < 600; i++) { world.StepSimulation(1.0f / 60.0f); } world.Dispose(); world = null; ForceGC(); TestWeakRefs(); ClearRefs(); }
internal AlignedIndexedMeshArray(IntPtr native, TriangleIndexVertexArray triangleIndexVertexArray) { Initialize(native); _triangleIndexVertexArray = triangleIndexVertexArray; int count = btAlignedObjectArray_btIndexedMesh_size(Native); for (int i = 0; i < count; i++) { var mesh = new IndexedMesh(btAlignedObjectArray_btIndexedMesh_at(native, i), this); _backingList.Add(mesh); } }
override protected BulletSharp.CollisionShape createShape () { if (mesh == null) mesh = GetComponent<MeshFilter> ().mesh; // TODO: share data using an own interface float[] vertices = new float[mesh.vertices.Length * 3]; for (int i = 0; i < mesh.vertices.Length; i++) { vertices [i * 3] = mesh.vertices [i].x; vertices [i * 3 + 1] = mesh.vertices [i].y; vertices [i * 3 + 2] = mesh.vertices [i].z; } BulletSharp.TriangleIndexVertexArray bulletMesh = new BulletSharp.TriangleIndexVertexArray (mesh.triangles, vertices); return new BulletSharp.BvhTriangleMeshShape (bulletMesh, useQuantizedAabbCompression); }
override protected BulletSharp.CollisionShape createShape () { if (mesh == null) mesh = GetComponent<MeshFilter> ().mesh; // TODO: share data using an own interface float[] vertices = new float[mesh.vertices.Length * 3]; for (int i = 0; i < mesh.vertices.Length; i++) { vertices [i * 3] = mesh.vertices [i].x; vertices [i * 3 + 1] = mesh.vertices [i].y; vertices [i * 3 + 2] = mesh.vertices [i].z; } BulletSharp.TriangleIndexVertexArray bulletMesh = new BulletSharp.TriangleIndexVertexArray (mesh.triangles, vertices); BulletSharp.GImpactMeshShape impactShape = new BulletSharp.GImpactMeshShape (bulletMesh); impactShape.UpdateBound (); return impactShape; }
public void SetUp() { conf = new DefaultCollisionConfiguration(); dispatcher = new CollisionDispatcher(conf); broadphase = new AxisSweep3(new Vector3(-1000, -1000, -1000), new Vector3(1000, 1000, 1000)); world = new DiscreteDynamicsWorld(dispatcher, broadphase, null, conf); indexVertexArray = new TriangleIndexVertexArray(TorusMesh.Indices, TorusMesh.Vertices); gImpactMeshShape = new GImpactMeshShape(indexVertexArray); triangleMeshShape = new BvhTriangleMeshShape(indexVertexArray, true); triangleMeshShape.CalculateLocalInertia(1.0f); gImpactMesh = CreateBody(1.0f, gImpactMeshShape, Vector3.Zero); triangleMesh = CreateBody(1.0f, triangleMeshShape, Vector3.Zero); }
private void TestTriangleArray(TriangleIndexVertexArray triangleArray) { Assert.AreSame(triangleArray.IndexedMeshArray, triangleArray.IndexedMeshArray); // check caching foreach (var indexedMesh in triangleArray.IndexedMeshArray) { Assert.NotNull(indexedMesh); } var initialMesh = triangleArray.IndexedMeshArray[0]; Assert.AreEqual(PhyScalarType.Int32, initialMesh.IndexType); Assert.AreEqual(PhyScalarType.Single, initialMesh.VertexType); Assert.AreEqual(TorusMesh.Vertices.Length / 3, initialMesh.NumVertices); Assert.AreEqual(TorusMesh.Indices.Length / 3, initialMesh.NumTriangles); Assert.AreEqual(sizeof(float) * 3, initialMesh.VertexStride); Assert.AreEqual(sizeof(int) * 3, initialMesh.TriangleIndexStride); var triangleIndices = initialMesh.TriangleIndices; Assert.AreEqual(TorusMesh.Indices.Length, triangleIndices.Count); for (int i = 0; i < triangleIndices.Count; i++) { Assert.AreEqual(triangleIndices[i], TorusMesh.Indices[i]); } }
public IGImpactMeshShapeImp AddGImpactMeshShape(int[] meshTriangles, float3[] meshVertices) { Vector3[] btMeshVertices = new Vector3[meshVertices.Length]; for (int i = 0; i < meshVertices.Length; i++) { btMeshVertices[i].X = meshVertices[i].x; btMeshVertices[i].Y = meshVertices[i].y; btMeshVertices[i].Z = meshVertices[i].z; } var btTriangleIndexVertexArray = new TriangleIndexVertexArray(meshTriangles, btMeshVertices); var btGimpactMeshShape = new GImpactMeshShape(btTriangleIndexVertexArray); btGimpactMeshShape.UpdateBound(); BtCollisionShapes.Add(btGimpactMeshShape); var retval = new GImpactMeshShapeImp(); retval.BtGImpactMeshShape = btGimpactMeshShape; btGimpactMeshShape.UserObject = retval; return retval; }
protected override void OnInitializePhysics() { // collision configuration contains default setup for memory, collision setup CollisionConf = new DefaultCollisionConfiguration(); Dispatcher = new CollisionDispatcher(CollisionConf); Vector3 worldMin = new Vector3(-1000, -1000, -1000); Vector3 worldMax = new Vector3(1000, 1000, 1000); Broadphase = new AxisSweep3(worldMin, worldMax); Solver = new SequentialImpulseConstraintSolver(); World = new DiscreteDynamicsWorld(Dispatcher, Broadphase, Solver, CollisionConf); World.SolverInfo.SplitImpulse = 1; World.Gravity = new Vector3(0, -10, 0); const int totalVerts = NUM_VERTS_X * NUM_VERTS_Y; const int totalTriangles = 2 * (NUM_VERTS_X - 1) * (NUM_VERTS_Y - 1); indexVertexArrays = new TriangleIndexVertexArray(); IndexedMesh mesh = new IndexedMesh(); mesh.Allocate(totalVerts, totalTriangles, 3 * sizeof(int), Vector3.SizeInBytes, PhyScalarType.Int32, PhyScalarType.Single); using (var indices = mesh.LockIndices()) { for (int i = 0; i < NUM_VERTS_X - 1; i++) { for (int j = 0; j < NUM_VERTS_Y - 1; j++) { indices.Write(j * NUM_VERTS_X + i); indices.Write(j * NUM_VERTS_X + i + 1); indices.Write((j + 1) * NUM_VERTS_X + i + 1); indices.Write(j * NUM_VERTS_X + i); indices.Write((j + 1) * NUM_VERTS_X + i + 1); indices.Write((j + 1) * NUM_VERTS_X + i); } } } indexVertexArrays.AddIndexedMesh(mesh); raycastBar = new RaycastBar(4000.0f, 0.0f); //raycastBar = new RaycastBar(true, 40.0f, -50.0f, 50.0f); CollisionShape colShape = new BoxShape(1); CollisionShapes.Add(colShape); for (int i = 0; i < 10; i++) { //CollisionShape colShape = new CapsuleShape(0.5f,2.0f);//boxShape = new SphereShape(1.0f); Matrix startTransform = Matrix.Translation(2 * i, 10, 1); LocalCreateRigidBody(1.0f, startTransform, colShape); } SetVertexPositions(waveHeight, 0.0f); const bool useQuantizedAabbCompression = true; groundShape = new BvhTriangleMeshShape(indexVertexArrays, useQuantizedAabbCompression); CollisionShapes.Add(groundShape); staticBody = LocalCreateRigidBody(0.0f, Matrix.Identity, groundShape); staticBody.CollisionFlags |= CollisionFlags.StaticObject; staticBody.UserObject = "Ground"; }
void InitGImpactCollision() { // Create Torus Shape indexVertexArrays = new TriangleIndexVertexArray(TorusMesh.Indices, TorusMesh.Vertices); #if BULLET_GIMPACT #if BULLET_GIMPACT_CONVEX_DECOMPOSITION //GImpactConvexDecompositionShape trimesh = // new GImpactConvexDecompositionShape(indexVertexArrays, new Vector3(1), 0.01f); //trimesh.Margin = 0.07f; //trimesh.UpdateBound(); #else GImpactMeshShape trimesh = new GImpactMeshShape(indexVertexArrays); trimesh.LocalScaling = new Vector3(1); #if BULLET_TRIANGLE_COLLISION trimesh.Margin = 0.07f; //????? #else trimesh.Margin = 0; #endif trimesh.UpdateBound(); #endif trimeshShape = trimesh; #else //trimeshShape = new GImpactMeshData(indexVertexArrays); #endif CollisionShapes.Add(trimeshShape); // Create Bunny Shape indexVertexArrays2 = new TriangleIndexVertexArray(BunnyMesh.Indices, BunnyMesh.Vertices); #if BULLET_GIMPACT #if BULLET_GIMPACT_CONVEX_DECOMPOSITION //GImpactConvexDecompositionShape trimesh2 = // new GImpactConvexDecompositionShape(indexVertexArrays, new Vector3(1), 0.01f); //trimesh.Margin = 0.07f; //trimesh.UpdateBound(); //trimeshShape = trimesh2; #else GImpactMeshShape trimesh2 = new GImpactMeshShape(indexVertexArrays2); trimesh2.LocalScaling = new Vector3(1); #if BULLET_TRIANGLE_COLLISION trimesh2.Margin = 0.07f; //????? #else trimesh2.Margin = 0; #endif trimesh2.UpdateBound(); trimeshShape2 = trimesh2; #endif #else //trimeshShape2 = new GImpactMeshData(indexVertexArrays2); #endif CollisionShapes.Add(trimeshShape2); //register GIMPACT algorithm #if BULLET_GIMPACT GImpactCollisionAlgorithm.RegisterAlgorithm(Dispatcher); #else //ConcaveConcaveCollisionAlgorithm.RegisterAlgorithm(Dispatcher); #endif }
protected override void OnInitializePhysics() { CollisionShape groundShape = new BoxShape(50, 3, 50); CollisionShapes.Add(groundShape); CollisionConf = new DefaultCollisionConfiguration(); Dispatcher = new CollisionDispatcher(CollisionConf); Solver = new SequentialImpulseConstraintSolver(); Vector3 worldMin = new Vector3(-10000, -10000, -10000); Vector3 worldMax = new Vector3(10000, 10000, 10000); Broadphase = new AxisSweep3(worldMin, worldMax); //Broadphase = new DbvtBroadphase(); World = new DiscreteDynamicsWorld(Dispatcher, Broadphase, Solver, CollisionConf); int i; Matrix tr; Matrix vehicleTr; //if (UseTrimeshGround) { const float scale = 20.0f; //create a triangle-mesh ground const int NumVertsX = 20; const int NumVertsY = 20; const int totalVerts = NumVertsX * NumVertsY; const int totalTriangles = 2 * (NumVertsX - 1) * (NumVertsY - 1); TriangleIndexVertexArray vertexArray = new TriangleIndexVertexArray(); IndexedMesh mesh = new IndexedMesh(); mesh.Allocate(totalTriangles, totalVerts); mesh.NumTriangles = totalTriangles; mesh.NumVertices = totalVerts; mesh.TriangleIndexStride = 3 * sizeof(int); mesh.VertexStride = Vector3.SizeInBytes; using (var indicesStream = mesh.GetTriangleStream()) { var indices = new BinaryWriter(indicesStream); for (i = 0; i < NumVertsX - 1; i++) { for (int j = 0; j < NumVertsY - 1; j++) { indices.Write(j * NumVertsX + i); indices.Write(j * NumVertsX + i + 1); indices.Write((j + 1) * NumVertsX + i + 1); indices.Write(j * NumVertsX + i); indices.Write((j + 1) * NumVertsX + i + 1); indices.Write((j + 1) * NumVertsX + i); } } indices.Dispose(); } using (var vertexStream = mesh.GetVertexStream()) { var vertices = new BinaryWriter(vertexStream); for (i = 0; i < NumVertsX; i++) { for (int j = 0; j < NumVertsY; j++) { float wl = .2f; float height = 20.0f * (float)(Math.Sin(i * wl) * Math.Cos(j * wl)); vertices.Write((i - NumVertsX * 0.5f) * scale); vertices.Write(height); vertices.Write((j - NumVertsY * 0.5f) * scale); } } vertices.Dispose(); } vertexArray.AddIndexedMesh(mesh); groundShape = new BvhTriangleMeshShape(vertexArray, true); tr = Matrix.Identity; vehicleTr = Matrix.Translation(0, -2, 0); }/* else { // Use HeightfieldTerrainShape int width = 40, length = 40; //int width = 128, length = 128; // Debugging is too slow for this float maxHeight = 10.0f; float heightScale = maxHeight / 256.0f; Vector3 scale = new Vector3(20.0f, maxHeight, 20.0f); //PhyScalarType scalarType = PhyScalarType.PhyUChar; //FileStream file = new FileStream(heightfieldFile, FileMode.Open, FileAccess.Read); // Use float data PhyScalarType scalarType = PhyScalarType.PhyFloat; byte[] terr = new byte[width * length * 4]; MemoryStream file = new MemoryStream(terr); BinaryWriter writer = new BinaryWriter(file); for (i = 0; i < width; i++) for (int j = 0; j < length; j++) writer.Write((float)((maxHeight / 2) + 4 * Math.Sin(j * 0.5f) * Math.Cos(i))); writer.Flush(); file.Position = 0; HeightfieldTerrainShape heightterrainShape = new HeightfieldTerrainShape(width, length, file, heightScale, 0, maxHeight, upIndex, scalarType, false); heightterrainShape.SetUseDiamondSubdivision(true); groundShape = heightterrainShape; groundShape.LocalScaling = new Vector3(scale.X, 1, scale.Z); tr = Matrix.Translation(new Vector3(-scale.X / 2, scale.Y / 2, -scale.Z / 2)); vehicleTr = Matrix.Translation(new Vector3(20, 3, -3)); // Create graphics object file.Position = 0; BinaryReader reader = new BinaryReader(file); int totalTriangles = (width - 1) * (length - 1) * 2; int totalVerts = width * length; game.groundMesh = new Mesh(game.Device, totalTriangles, totalVerts, MeshFlags.SystemMemory | MeshFlags.Use32Bit, VertexFormat.Position | VertexFormat.Normal); SlimDX.DataStream data = game.groundMesh.LockVertexBuffer(LockFlags.None); for (i = 0; i < width; i++) { for (int j = 0; j < length; j++) { float height; if (scalarType == PhyScalarType.PhyFloat) { // heightScale isn't applied internally for float data height = reader.ReadSingle(); } else if (scalarType == PhyScalarType.PhyUChar) { height = file.ReadByte() * heightScale; } else { height = 0.0f; } data.Write((j - length * 0.5f) * scale.X); data.Write(height); data.Write((i - width * 0.5f) * scale.Z); // Normals will be calculated later data.Position += 12; } } game.groundMesh.UnlockVertexBuffer(); file.Close(); data = game.groundMesh.LockIndexBuffer(LockFlags.None); for (i = 0; i < width - 1; i++) { for (int j = 0; j < length - 1; j++) { // Using diamond subdivision if ((j + i) % 2 == 0) { data.Write(j * width + i); data.Write((j + 1) * width + i + 1); data.Write(j * width + i + 1); data.Write(j * width + i); data.Write((j + 1) * width + i); data.Write((j + 1) * width + i + 1); } else { data.Write(j * width + i); data.Write((j + 1) * width + i); data.Write(j * width + i + 1); data.Write(j * width + i + 1); data.Write((j + 1) * width + i); data.Write((j + 1) * width + i + 1); } / * // Not using diamond subdivision data.Write(j * width + i); data.Write((j + 1) * width + i); data.Write(j * width + i + 1); data.Write(j * width + i + 1); data.Write((j + 1) * width + i); data.Write((j + 1) * width + i + 1); * / } } game.groundMesh.UnlockIndexBuffer(); game.groundMesh.ComputeNormals(); }*/ CollisionShapes.Add(groundShape); //create ground object RigidBody ground = LocalCreateRigidBody(0, tr, groundShape); ground.UserObject = "Ground"; CollisionShape chassisShape = new BoxShape(1.0f, 0.5f, 2.0f); CollisionShapes.Add(chassisShape); CompoundShape compound = new CompoundShape(); CollisionShapes.Add(compound); //localTrans effectively shifts the center of mass with respect to the chassis Matrix localTrans = Matrix.Translation(Vector3.UnitY); compound.AddChildShape(localTrans, chassisShape); RigidBody carChassis = LocalCreateRigidBody(800, Matrix.Identity, compound); carChassis.UserObject = "Chassis"; //carChassis.SetDamping(0.2f, 0.2f); //CylinderShapeX wheelShape = new CylinderShapeX(wheelWidth, wheelRadius, wheelRadius); // clientResetScene(); // create vehicle VehicleTuning tuning = new VehicleTuning(); IVehicleRaycaster vehicleRayCaster = new DefaultVehicleRaycaster(World); //vehicle = new RaycastVehicle(tuning, carChassis, vehicleRayCaster); vehicle = new CustomVehicle(tuning, carChassis, vehicleRayCaster); carChassis.ActivationState = ActivationState.DisableDeactivation; World.AddAction(vehicle); const float connectionHeight = 1.2f; bool isFrontWheel = true; // choose coordinate system vehicle.SetCoordinateSystem(rightIndex, upIndex, forwardIndex); BulletSharp.Math.Vector3 connectionPointCS0 = new Vector3(CUBE_HALF_EXTENTS - (0.3f * wheelWidth), connectionHeight, 2 * CUBE_HALF_EXTENTS - wheelRadius); vehicle.AddWheel(connectionPointCS0, wheelDirectionCS0, wheelAxleCS, suspensionRestLength, wheelRadius, tuning, isFrontWheel); connectionPointCS0 = new Vector3(-CUBE_HALF_EXTENTS + (0.3f * wheelWidth), connectionHeight, 2 * CUBE_HALF_EXTENTS - wheelRadius); vehicle.AddWheel(connectionPointCS0, wheelDirectionCS0, wheelAxleCS, suspensionRestLength, wheelRadius, tuning, isFrontWheel); isFrontWheel = false; connectionPointCS0 = new Vector3(-CUBE_HALF_EXTENTS + (0.3f * wheelWidth), connectionHeight, -2 * CUBE_HALF_EXTENTS + wheelRadius); vehicle.AddWheel(connectionPointCS0, wheelDirectionCS0, wheelAxleCS, suspensionRestLength, wheelRadius, tuning, isFrontWheel); connectionPointCS0 = new Vector3(CUBE_HALF_EXTENTS - (0.3f * wheelWidth), connectionHeight, -2 * CUBE_HALF_EXTENTS + wheelRadius); vehicle.AddWheel(connectionPointCS0, wheelDirectionCS0, wheelAxleCS, suspensionRestLength, wheelRadius, tuning, isFrontWheel); for (i = 0; i < vehicle.NumWheels; i++) { WheelInfo wheel = vehicle.GetWheelInfo(i); wheel.SuspensionStiffness = suspensionStiffness; wheel.WheelsDampingRelaxation = suspensionDamping; wheel.WheelsDampingCompression = suspensionCompression; wheel.FrictionSlip = wheelFriction; wheel.RollInfluence = rollInfluence; } vehicle.RigidBody.WorldTransform = vehicleTr; }
public override void Run() { #region Create renderers // Note: the renderers take care of creating their own // device resources and listen for DeviceManager.OnInitialize // Create a axis-grid renderer var axisGrid = ToDispose(new AxisGridRenderer()); axisGrid.Initialize(this); // Create and initialize the mesh renderer var loadedMesh = Common.Mesh.LoadFromFile("PhysicsScene1.cmo"); List <MeshRenderer> meshes = new List <MeshRenderer>(); meshes.AddRange(from mesh in loadedMesh select ToDispose(new MeshRenderer(mesh))); foreach (var m in meshes) { m.Initialize(this); m.World = Matrix.Identity; } // Set the first animation as the current animation and start clock foreach (var m in meshes) { if (m.Mesh.Animations != null && m.Mesh.Animations.Any()) { m.CurrentAnimation = m.Mesh.Animations.First().Value; } m.Clock.Start(); } loadedMesh = Common.Mesh.LoadFromFile("SubdividedPlane.cmo"); var waterMesh = ToDispose(new MeshRenderer(loadedMesh.First())); waterMesh.Initialize(this); loadedMesh = Common.Mesh.LoadFromFile("Bataux.cmo"); List <MeshRenderer> shipMeshes = new List <MeshRenderer>(); shipMeshes.AddRange((from mesh in loadedMesh select ToDispose(new MeshRenderer(mesh)))); foreach (var m in shipMeshes) { m.Initialize(this); m.World = Matrix.Scaling(3) * Matrix.RotationAxis(Vector3.UnitY, -1.57079f); } //var anchor = new SphereRenderer(0.05f); //anchor.Initialize(this); //var anchorWorld = Matrix.Identity; //var sphere = new SphereRenderer(); //sphere.Initialize(this); //var sphereWorld = Matrix.Identity; // Create and initialize a Direct2D FPS text renderer var fps = ToDispose(new Common.FpsRenderer("Calibri", Color.CornflowerBlue, new Point(8, 8), 16)); fps.Initialize(this); // Create and initialize a general purpose Direct2D text renderer // This will display some instructions and the current view and rotation offsets var textRenderer = ToDispose(new Common.TextRenderer("Calibri", Color.CornflowerBlue, new Point(8, 40), 12)); textRenderer.Initialize(this); #endregion #region Initialize physics engine CollisionConfiguration defaultConfig = new DefaultCollisionConfiguration(); ConstraintSolver solver = new SequentialImpulseConstraintSolver(); BulletSharp.Dispatcher dispatcher = new CollisionDispatcher(defaultConfig); BroadphaseInterface broadphase = new DbvtBroadphase(); DynamicsWorld world = null; Action initializePhysics = () => { RemoveAndDispose(ref world); world = ToDispose(new BulletSharp.DiscreteDynamicsWorld(dispatcher, broadphase, solver, defaultConfig)); world.Gravity = new Vector3(0, -10, 0); // For each mesh, create a RigidBody and add to "world" for simulation meshes.ForEach(m => { // We use the name of the mesh to determine the correct body if (String.IsNullOrEmpty(m.Mesh.Name)) { return; } var name = m.Mesh.Name.ToLower(); var extent = m.Mesh.Extent; BulletSharp.CollisionShape shape; #region Create collision shape if (name.Contains("box") || name.Contains("cube")) { // Assumes the box/cube has an axis-aligned neutral orientation shape = new BulletSharp.BoxShape( Math.Abs(extent.Max.Z - extent.Min.Z) / 2.0f, Math.Abs(extent.Max.Y - extent.Min.Y) / 2.0f, Math.Abs(extent.Max.X - extent.Min.X) / 2.0f); } else if (name.Contains("sphere")) { shape = new BulletSharp.SphereShape(extent.Radius); } else // use mesh vertices directly { // for each SubMesh, retrieve the vertex and index buffers // to create a TriangleMeshShape for collision detection. List <Vector3> vertices = new List <Vector3>(); List <int> indices = new List <int>(); int vertexOffset = 0; foreach (var sm in m.Mesh.SubMeshes) { vertexOffset += vertices.Count; indices.AddRange( (from indx in m.Mesh.IndexBuffers[(int)sm.IndexBufferIndex] select vertexOffset + (int)indx)); vertices.AddRange( (from v in m.Mesh .VertexBuffers[(int)sm.VertexBufferIndex] select v.Position - extent.Center)); } // Create the collision shape var iva = new BulletSharp.TriangleIndexVertexArray(indices.ToArray(), vertices.ToArray()); shape = new BulletSharp.BvhTriangleMeshShape(iva, true); } #endregion m.World = Matrix.Identity; // Reset mesh location float mass; Vector3 vec; shape.GetBoundingSphere(out vec, out mass); var body = new BulletSharp.RigidBody( new BulletSharp.RigidBodyConstructionInfo(name.Contains("static") ? 0 : mass, new MeshMotionState(m), shape, shape.CalculateLocalInertia(mass))); if (body.IsStaticObject) { body.Restitution = 1f; body.Friction = 0.4f; } // Add to the simulation world.AddRigidBody(body); }); #if DEBUG world.DebugDrawer = ToDispose(new PhysicsDebugDraw(this.DeviceManager)); world.DebugDrawer.DebugMode = DebugDrawModes.DrawAabb | DebugDrawModes.DrawWireframe; #endif }; initializePhysics(); // Newton's Cradle //var box = new Jitter.Dynamics.RigidBody(new Jitter.Collision.Shapes.BoxShape(7, 1, 2)); //box.Position = new Jitter.LinearMath.JVector(0, 8, 0); //world.AddBody(box); //box.IsStatic = true; //var anchorBody = new Jitter.Dynamics.RigidBody(new Jitter.Collision.Shapes.SphereShape(0.05f)); //anchorBody.Position = new Jitter.LinearMath.JVector(0, 4, 0); //world.AddBody(anchorBody); //anchorBody.IsStatic = true; //for (var bodyCount = -3; bodyCount < 4; bodyCount++) //{ // var testBody = new Jitter.Dynamics.RigidBody(new Jitter.Collision.Shapes.SphereShape(0.501f)); // testBody.Position = new Jitter.LinearMath.JVector(bodyCount, 0, 0); // world.AddBody(testBody); // world.AddConstraint(new Jitter.Dynamics.Constraints.PointPointDistance(box, testBody, // testBody.Position + Jitter.LinearMath.JVector.Up * 8f + Jitter.LinearMath.JVector.Forward * 3f + Jitter.LinearMath.JVector.Down * 0.5f, // testBody.Position) { Softness = 1.0f, BiasFactor = 0.8f }); // world.AddConstraint(new Jitter.Dynamics.Constraints.PointPointDistance(box, testBody, // testBody.Position + Jitter.LinearMath.JVector.Up * 8f + Jitter.LinearMath.JVector.Backward * 3f + Jitter.LinearMath.JVector.Down * 0.5f, // testBody.Position) { Softness = 1.0f, BiasFactor = 0.8f }); // testBody.Material.Restitution = 1.0f; // testBody.Material.StaticFriction = 1.0f; //} #endregion // Initialize the world matrix var worldMatrix = Matrix.Identity; // Set the camera position slightly behind (z) var cameraPosition = new Vector3(0, 1, 10); var cameraTarget = Vector3.Zero; // Looking at the origin 0,0,0 var cameraUp = Vector3.UnitY; // Y+ is Up // Prepare matrices // Create the view matrix from our camera position, look target and up direction var viewMatrix = Matrix.LookAtRH(cameraPosition, cameraTarget, cameraUp); viewMatrix.TranslationVector += new Vector3(0, -0.98f, 0); // Create the projection matrix /* FoV 60degrees = Pi/3 radians */ // Aspect ratio (based on window size), Near clip, Far clip var projectionMatrix = Matrix.PerspectiveFovRH((float)Math.PI / 3f, Width / (float)Height, 0.1f, 100f); // Maintain the correct aspect ratio on resize Window.Resize += (s, e) => { projectionMatrix = Matrix.PerspectiveFovRH((float)Math.PI / 3f, Width / (float)Height, 0.1f, 100f); }; bool debugDraw = false; bool paused = false; var simTime = new System.Diagnostics.Stopwatch(); simTime.Start(); float time = 0.0f; float timeStep = 0.0f; #region Rotation and window event handlers // Create a rotation vector to keep track of the rotation // around each of the axes var rotation = new Vector3(0.0f, 0.0f, 0.0f); // We will call this action to update text // for the text renderer Action updateText = () => { textRenderer.Text = String.Format("Rotation ({0}) (Up/Down Left/Right Wheel+-)\nView ({1}) (A/D, W/S, Shift+Wheel+-)" //+ "\nPress 1,2,3,4,5,6,7,8 to switch shaders" + "\nTime: {2:0.00} (P to toggle, R to reset scene)" + "\nPhysics debug draw: {3} (E to toggle)" + "\nBackspace: toggle between Physics and Waves", rotation, viewMatrix.TranslationVector, simTime.Elapsed.TotalSeconds, debugDraw); }; Dictionary <Keys, bool> keyToggles = new Dictionary <Keys, bool>(); keyToggles[Keys.Z] = false; keyToggles[Keys.F] = false; keyToggles[Keys.Back] = false; // Support keyboard/mouse input to rotate or move camera view var moveFactor = 0.02f; // how much to change on each keypress var shiftKey = false; var ctrlKey = false; var background = Color.White; var showNormals = false; var enableNormalMap = true; Window.KeyDown += (s, e) => { var context = DeviceManager.Direct3DContext; shiftKey = e.Shift; ctrlKey = e.Control; switch (e.KeyCode) { // WASD -> pans view case Keys.A: viewMatrix.TranslationVector += new Vector3(moveFactor * 2, 0f, 0f); break; case Keys.D: viewMatrix.TranslationVector -= new Vector3(moveFactor * 2, 0f, 0f); break; case Keys.S: if (shiftKey) { viewMatrix.TranslationVector += new Vector3(0f, moveFactor * 2, 0f); } else { viewMatrix.TranslationVector -= new Vector3(0f, 0f, 1) * moveFactor * 2; } break; case Keys.W: if (shiftKey) { viewMatrix.TranslationVector -= new Vector3(0f, moveFactor * 2, 0f); } else { viewMatrix.TranslationVector += new Vector3(0f, 0f, 1) * moveFactor * 2; } break; // Up/Down and Left/Right - rotates around X / Y respectively // (Mouse wheel rotates around Z) case Keys.Down: worldMatrix *= Matrix.RotationX(moveFactor); rotation += new Vector3(moveFactor, 0f, 0f); break; case Keys.Up: worldMatrix *= Matrix.RotationX(-moveFactor); rotation -= new Vector3(moveFactor, 0f, 0f); break; case Keys.Left: worldMatrix *= Matrix.RotationY(moveFactor); rotation += new Vector3(0f, moveFactor, 0f); break; case Keys.Right: worldMatrix *= Matrix.RotationY(-moveFactor); rotation -= new Vector3(0f, moveFactor, 0f); break; case Keys.T: fps.Show = !fps.Show; textRenderer.Show = !textRenderer.Show; break; case Keys.B: if (background == Color.White) { background = new Color(30, 30, 34); } else { background = Color.White; } break; case Keys.G: axisGrid.Show = !axisGrid.Show; break; case Keys.P: paused = !paused; if (paused) { simTime.Stop(); } else { simTime.Start(); } // Pause or resume mesh animation meshes.ForEach(m => { if (m.Clock.IsRunning) { m.Clock.Stop(); } else { m.Clock.Start(); } }); updateText(); break; case Keys.X: // To test for correct resource recreation // Simulate device reset or lost. System.Diagnostics.Debug.WriteLine(SharpDX.Diagnostics.ObjectTracker.ReportActiveObjects()); DeviceManager.Initialize(DeviceManager.Dpi); System.Diagnostics.Debug.WriteLine(SharpDX.Diagnostics.ObjectTracker.ReportActiveObjects()); break; case Keys.Z: keyToggles[Keys.Z] = !keyToggles[Keys.Z]; if (keyToggles[Keys.Z]) { context.PixelShader.Set(depthPixelShader); } else { context.PixelShader.Set(pixelShader); } break; case Keys.F: keyToggles[Keys.F] = !keyToggles[Keys.F]; RasterizerStateDescription rasterDesc; if (context.Rasterizer.State != null) { rasterDesc = context.Rasterizer.State.Description; } else { rasterDesc = new RasterizerStateDescription() { CullMode = CullMode.None, FillMode = FillMode.Solid } }; if (keyToggles[Keys.F]) { rasterDesc.FillMode = FillMode.Wireframe; context.Rasterizer.State = ToDispose(new RasterizerState(context.Device, rasterDesc)); } else { rasterDesc.FillMode = FillMode.Solid; context.Rasterizer.State = ToDispose(new RasterizerState(context.Device, rasterDesc)); } break; case Keys.N: if (!shiftKey) { showNormals = !showNormals; } else { enableNormalMap = !enableNormalMap; } break; case Keys.E: debugDraw = !debugDraw; break; case Keys.R: //world = new Jitter.World(new Jitter.Collision.CollisionSystemSAP()); initializePhysics(); if (simTime.IsRunning) { simTime.Restart(); } else { simTime.Reset(); } break; case Keys.D1: context.PixelShader.Set(pixelShader); break; case Keys.D2: context.PixelShader.Set(lambertShader); break; case Keys.D3: context.PixelShader.Set(phongShader); break; case Keys.D4: context.PixelShader.Set(blinnPhongShader); break; case Keys.Back: keyToggles[Keys.Back] = !keyToggles[Keys.Back]; break; } updateText(); }; Window.KeyUp += (s, e) => { // Clear the shift/ctrl keys so they aren't sticky if (e.KeyCode == Keys.ShiftKey) { shiftKey = false; } if (e.KeyCode == Keys.ControlKey) { ctrlKey = false; } }; Window.MouseWheel += (s, e) => { if (shiftKey) { // Zoom in/out viewMatrix.TranslationVector += new Vector3(0f, 0f, (e.Delta / 120f) * moveFactor * 2); } else { // rotate around Z-axis viewMatrix *= Matrix.RotationZ((e.Delta / 120f) * moveFactor); rotation += new Vector3(0f, 0f, (e.Delta / 120f) * moveFactor); } updateText(); }; var lastX = 0; var lastY = 0; Window.MouseDown += (s, e) => { if (e.Button == MouseButtons.Left) { lastX = e.X; lastY = e.Y; } }; Window.MouseMove += (s, e) => { if (e.Button == MouseButtons.Left) { var yRotate = lastX - e.X; var xRotate = lastY - e.Y; lastY = e.Y; lastX = e.X; // Mouse move changes viewMatrix *= Matrix.RotationX(-xRotate * moveFactor); viewMatrix *= Matrix.RotationY(-yRotate * moveFactor); updateText(); } }; // Display instructions with initial values updateText(); #endregion var clock = new System.Diagnostics.Stopwatch(); clock.Start(); #region Render loop // Create and run the render loop RenderLoop.Run(Window, () => { // Update simulation, at 60fps if (!paused) { if ((float)simTime.Elapsed.TotalSeconds < time) { time = 0; timeStep = 0; } timeStep = ((float)simTime.Elapsed.TotalSeconds - time); time = (float)simTime.Elapsed.TotalSeconds; world.StepSimulation(timeStep, 7); // For how to choose the maxSubSteps see: // http://www.bulletphysics.org/mediawiki-1.5.8/index.php/Stepping_The_World } updateText(); // Start of frame: // Retrieve immediate context var context = DeviceManager.Direct3DContext; // Clear depth stencil view context.ClearDepthStencilView(DepthStencilView, DepthStencilClearFlags.Depth | DepthStencilClearFlags.Stencil, 1.0f, 0); // Clear render target view context.ClearRenderTargetView(RenderTargetView, background); // Create viewProjection matrix var viewProjection = Matrix.Multiply(viewMatrix, projectionMatrix); // Extract camera position from view var camPosition = Matrix.Transpose(Matrix.Invert(viewMatrix)).Column4; cameraPosition = new Vector3(camPosition.X, camPosition.Y, camPosition.Z); var perFrame = new ConstantBuffers.PerFrame(); perFrame.Light.Color = new Color(0.8f, 0.8f, 0.8f, 1.0f); var lightDir = Vector3.Transform(new Vector3(1f, -1f, -1f), worldMatrix); perFrame.Light.Direction = new Vector3(lightDir.X, lightDir.Y, lightDir.Z); perFrame.CameraPosition = cameraPosition; perFrame.Time = (float)simTime.Elapsed.TotalSeconds; // Provide simulation time to shader context.UpdateSubresource(ref perFrame, perFrameBuffer); // Render each object var perMaterial = new ConstantBuffers.PerMaterial(); perMaterial.Ambient = new Color4(0.2f); perMaterial.Diffuse = Color.White; perMaterial.Emissive = new Color4(0); perMaterial.Specular = Color.White; perMaterial.SpecularPower = 20f; perMaterial.HasTexture = 0; perMaterial.UVTransform = Matrix.Identity; context.UpdateSubresource(ref perMaterial, perMaterialBuffer); var perObject = new ConstantBuffers.PerObject(); // MESH if (!keyToggles[Keys.Back]) { meshes.ForEach((m) => { perObject.World = m.World * worldMatrix; // Provide the material constant buffer to the mesh renderer perObject.WorldInverseTranspose = Matrix.Transpose(Matrix.Invert(perObject.World)); perObject.WorldViewProjection = perObject.World * viewProjection; perObject.ViewProjection = viewProjection; perObject.Transpose(); context.UpdateSubresource(ref perObject, perObjectBuffer); m.PerMaterialBuffer = perMaterialBuffer; m.PerArmatureBuffer = perArmatureBuffer; m.Render(); if (showNormals) { using (var prevPixelShader = context.PixelShader.Get()) { perMaterial.HasTexture = 0; perMaterial.UVTransform = Matrix.Identity; context.UpdateSubresource(ref perMaterial, perMaterialBuffer); context.PixelShader.Set(pixelShader); context.GeometryShader.Set(debugNormals); m.Render(); context.PixelShader.Set(prevPixelShader); context.GeometryShader.Set(null); } } }); if (debugDraw) { perObject.World = Matrix.Identity; perObject.WorldInverseTranspose = Matrix.Transpose(Matrix.Invert(perObject.World)); perObject.WorldViewProjection = perObject.World * viewProjection; perObject.ViewProjection = viewProjection; perObject.Transpose(); context.UpdateSubresource(ref perObject, perObjectBuffer); (world.DebugDrawer as PhysicsDebugDraw).DrawDebugWorld(world); context.VertexShader.Set(vertexShader); context.PixelShader.Set(pixelShader); context.InputAssembler.InputLayout = vertexLayout; } } else { perObject.World = waterMesh.World * worldMatrix; perObject.WorldInverseTranspose = Matrix.Transpose(Matrix.Invert(perObject.World)); perObject.WorldViewProjection = perObject.World * viewProjection; perObject.ViewProjection = viewProjection; perObject.Transpose(); context.UpdateSubresource(ref perObject, perObjectBuffer); waterMesh.EnableNormalMap = enableNormalMap; waterMesh.PerMaterialBuffer = perMaterialBuffer; waterMesh.PerArmatureBuffer = perArmatureBuffer; context.VertexShader.Set(waterVertexShader); waterMesh.Render(); if (showNormals) { using (var prevPixelShader = context.PixelShader.Get()) { perMaterial.HasTexture = 0; perMaterial.UVTransform = Matrix.Identity; context.UpdateSubresource(ref perMaterial, perMaterialBuffer); context.PixelShader.Set(pixelShader); context.GeometryShader.Set(debugNormals); waterMesh.Render(); context.PixelShader.Set(prevPixelShader); context.GeometryShader.Set(null); } } context.VertexShader.Set(vertexShader); foreach (var m in shipMeshes) { perObject.World = m.World * worldMatrix; perObject.WorldInverseTranspose = Matrix.Transpose(Matrix.Invert(perObject.World)); perObject.WorldViewProjection = perObject.World * viewProjection; perObject.Transpose(); context.UpdateSubresource(ref perObject, perObjectBuffer); // Provide the material constant buffer to the mesh renderer perObject.WorldInverseTranspose = Matrix.Transpose(Matrix.Invert(perObject.World)); perObject.WorldViewProjection = perObject.World * viewProjection; perObject.ViewProjection = viewProjection; perObject.Transpose(); context.UpdateSubresource(ref perObject, perObjectBuffer); m.PerMaterialBuffer = perMaterialBuffer; m.PerArmatureBuffer = perArmatureBuffer; m.Render(); if (showNormals) { using (var prevPixelShader = context.PixelShader.Get()) { perMaterial.HasTexture = 0; perMaterial.UVTransform = Matrix.Identity; context.UpdateSubresource(ref perMaterial, perMaterialBuffer); context.PixelShader.Set(pixelShader); context.GeometryShader.Set(debugNormals); m.Render(); context.PixelShader.Set(prevPixelShader); context.GeometryShader.Set(null); } } } } perMaterial.Ambient = new Color4(0.2f); perMaterial.Diffuse = Color.White; perMaterial.Emissive = new Color4(0); perMaterial.Specular = Color.White; perMaterial.SpecularPower = 20f; perMaterial.UVTransform = Matrix.Identity; context.UpdateSubresource(ref perMaterial, perMaterialBuffer); // AXIS GRID context.HullShader.Set(null); context.DomainShader.Set(null); context.GeometryShader.Set(null); using (var prevPixelShader = context.PixelShader.Get()) using (var prevVertexShader = context.VertexShader.Get()) { context.VertexShader.Set(vertexShader); context.PixelShader.Set(pixelShader); perObject.World = worldMatrix; perObject.WorldInverseTranspose = Matrix.Transpose(Matrix.Invert(perObject.World)); perObject.WorldViewProjection = perObject.World * viewProjection; perObject.ViewProjection = viewProjection; perObject.Transpose(); context.UpdateSubresource(ref perObject, perObjectBuffer); axisGrid.Render(); context.PixelShader.Set(prevPixelShader); context.VertexShader.Set(prevVertexShader); } // Render FPS fps.Render(); // Render instructions + position changes textRenderer.Render(); // Present the frame Present(); }); #endregion }
public BvhTriangleMeshShape GetAccurateCollisionShape(float scale = 1.0f) { //if (CachedBvhTriangleMeshShape != null) return CachedBvhTriangleMeshShape; List<Vector3> vectors = GetOrderedVertices(); var smesh = new TriangleIndexVertexArray(GetOrderedIndices().ToArray(), vectors.ToArray()); CachedBvhTriangleMeshShape = new BvhTriangleMeshShape(smesh, false); //CachedBvhTriangleMeshShape.LocalScaling = new Vector3(scale); return CachedBvhTriangleMeshShape; }
protected override void OnInitialize() { Freelook.SetEyeTarget(eye, target); Graphics.SetFormText("BulletSharp - Concave Raycast Demo"); Graphics.SetInfoText("Move using mouse and WASD+shift\n" + "F3 - Toggle debug\n" + //"F11 - Toggle fullscreen\n" + "Space - Shoot box"); DebugDrawMode = debugMode; const int totalVerts = NUM_VERTS_X * NUM_VERTS_Y; const int totalTriangles = 2 * (NUM_VERTS_X - 1) * (NUM_VERTS_Y - 1); indexVertexArrays = new TriangleIndexVertexArray(); IndexedMesh mesh = new IndexedMesh(); mesh.Allocate(totalVerts, Vector3.SizeInBytes, totalTriangles, 3 * sizeof(int)); DataStream indices = mesh.LockIndices(); for (int i = 0; i < NUM_VERTS_X - 1; i++) { for (int j = 0; j < NUM_VERTS_Y - 1; j++) { indices.Write(j * NUM_VERTS_X + i); indices.Write(j * NUM_VERTS_X + i + 1); indices.Write((j + 1) * NUM_VERTS_X + i + 1); indices.Write(j * NUM_VERTS_X + i); indices.Write((j + 1) * NUM_VERTS_X + i + 1); indices.Write((j + 1) * NUM_VERTS_X + i); } } indices.Dispose(); indexVertexArrays.AddIndexedMesh(mesh); raycastBar = new RaycastBar(4000.0f, 0.0f); //raycastBar = new RaycastBar(true, 40.0f, -50.0f, 50.0f); }
public BvhTriangleMeshShape GetAccurateCollisionShape() { //if (CachedBvhTriangleMeshShape != null) return CachedBvhTriangleMeshShape; List<Vector3> vectors = GetRawVertexList(); var smesh = new TriangleIndexVertexArray(Enumerable.Range(0, Vertices.Count).ToArray(), vectors.Select((a) => a).ToArray()); CachedBvhTriangleMeshShape = new BvhTriangleMeshShape(smesh, false); //CachedBvhTriangleMeshShape.LocalScaling = new Vector3(scale); return CachedBvhTriangleMeshShape; }
protected override void OnInitializePhysics() { // collision configuration contains default setup for memory, collision setup CollisionConf = new DefaultCollisionConfiguration(); Dispatcher = new CollisionDispatcher(CollisionConf); Vector3 worldMin = new Vector3(-1000, -1000, -1000); Vector3 worldMax = new Vector3(1000, 1000, 1000); Broadphase = new AxisSweep3(worldMin, worldMax); Solver = new SequentialImpulseConstraintSolver(); World = new DiscreteDynamicsWorld(Dispatcher, Broadphase, Solver, CollisionConf); World.SolverInfo.SplitImpulse = 1; World.Gravity = new Vector3(0, -10, 0); const int totalVerts = NumVertsX * NumVertsY; const int totalTriangles = 2 * (NumVertsX - 1) * (NumVertsY - 1); indexVertexArrays = new TriangleIndexVertexArray(); IndexedMesh mesh = new IndexedMesh(); mesh.NumTriangles = totalTriangles; mesh.NumVertices = totalVerts; mesh.TriangleIndexStride = 3 * sizeof(int); mesh.VertexStride = Vector3.SizeInBytes; mesh.TriangleIndexBase = Marshal.AllocHGlobal(mesh.TriangleIndexStride * totalTriangles); mesh.VertexBase = Marshal.AllocHGlobal(mesh.VertexStride * totalVerts); var indicesStream = mesh.GetTriangleStream(); using (var indices = new BinaryWriter(indicesStream)) { for (int i = 0; i < NumVertsX - 1; i++) { for (int j = 0; j < NumVertsY - 1; j++) { indices.Write(j*NumVertsX + i); indices.Write(j*NumVertsX + i + 1); indices.Write((j + 1)*NumVertsX + i + 1); indices.Write(j*NumVertsX + i); indices.Write((j + 1)*NumVertsX + i + 1); indices.Write((j + 1)*NumVertsX + i); } } } indexVertexArrays.AddIndexedMesh(mesh); convexcastBatch = new ConvexcastBatch(40.0f, 0.0f, -10.0f, 80.0f); CollisionShape colShape = new BoxShape(1); CollisionShapes.Add(colShape); for (int j = 0; j < NumDynamicBoxesX; j++) { for (int i = 0; i < NumDynamicBoxesY; i++) { //CollisionShape colShape = new CapsuleShape(0.5f,2.0f);//boxShape = new SphereShape(1.0f); Matrix startTransform = Matrix.Translation(5 * (i - NumDynamicBoxesX / 2), 10, 5 * (j - NumDynamicBoxesY / 2)); LocalCreateRigidBody(1.0f, startTransform, colShape); } } SetVertexPositions(WaveHeight, 0.0f); const bool useQuantizedAabbCompression = true; groundShape = new BvhTriangleMeshShape(indexVertexArrays, useQuantizedAabbCompression); CollisionShapes.Add(groundShape); staticBody = LocalCreateRigidBody(0.0f, Matrix.Identity, groundShape); staticBody.CollisionFlags |= CollisionFlags.StaticObject; staticBody.UserObject = "Ground"; }
public TriangleIndexVertexArray CreateTriangleMeshContainer() { TriangleIndexVertexArray tiva = new TriangleIndexVertexArray(); _allocatedTriangleIndexArrays.Add(tiva); return tiva; }
protected override void OnInitialize() { Freelook.SetEyeTarget(eye, target); Graphics.SetFormText("BulletSharp - Concave Convexcast Demo"); Graphics.SetInfoText("Move using mouse and WASD+shift\n" + "F3 - Toggle debug\n" + //"F11 - Toggle fullscreen\n" + "Space - Shoot box"); DebugDrawMode = debugMode; const int totalVerts = NumVertsX * NumVertsY; const int totalTriangles = 2 * (NumVertsX - 1) * (NumVertsY - 1); indexVertexArrays = new TriangleIndexVertexArray(); IndexedMesh mesh = new IndexedMesh(); mesh.NumTriangles = totalTriangles; mesh.NumVertices = totalVerts; mesh.TriangleIndexStride = 3 * sizeof(int); mesh.VertexStride = Vector3.SizeInBytes; mesh.TriangleIndexBase = Marshal.AllocHGlobal(mesh.TriangleIndexStride * totalTriangles); mesh.VertexBase = Marshal.AllocHGlobal(mesh.VertexStride * totalVerts); var indicesStream = mesh.GetTriangleStream(); var indices = new BinaryWriter(indicesStream); for (int i = 0; i < NumVertsX - 1; i++) { for (int j = 0; j < NumVertsY - 1; j++) { indices.Write(j * NumVertsX + i); indices.Write(j * NumVertsX + i + 1); indices.Write((j + 1) * NumVertsX + i + 1); indices.Write(j * NumVertsX + i); indices.Write((j + 1) * NumVertsX + i + 1); indices.Write((j + 1) * NumVertsX + i); } } indices.Dispose(); indexVertexArrays.AddIndexedMesh(mesh); convexcastBatch = new ConvexcastBatch(40.0f, 0.0f, -10.0f, 80.0f); //convexcastBatch = new ConvexcastBatch(true, 40.0f, -50.0f, 50.0f); }
protected override CollisionShape CreateShape() { //ConvexHullShape shape = new ConvexHullShape(this.vertices); //BvhTriangleMeshShape bvh = new BvhTriangleMeshShape( //StridingMeshInterface smi = new StridingMeshInterface(); TriangleIndexVertexArray tiv = new TriangleIndexVertexArray(this.indices, this.vertices); BvhTriangleMeshShape bvh = new BvhTriangleMeshShape(tiv, true, true); //StridingMeshInterface return bvh; }