public TriangleMesh(bool use32bitIndices,bool use4componentVertices) { m_use32bitIndices = use32bitIndices; m_use4componentVertices = use4componentVertices; IndexedMesh meshIndex = new IndexedMesh(); m_indexedMeshes.Add(meshIndex); if (m_use32bitIndices) { m_indexedMeshes[0].m_numTriangles = m_32bitIndices.Count/3; m_indexedMeshes[0].m_indexType = PHY_ScalarType.PHY_INTEGER; m_indexedMeshes[0].m_triangleIndexStride = 3; } else { m_indexedMeshes[0].m_numTriangles = m_16bitIndices.Count/3; m_indexedMeshes[0].m_triangleIndexBase = null; m_indexedMeshes[0].m_indexType = PHY_ScalarType.PHY_SHORT; m_indexedMeshes[0].m_triangleIndexStride = 3; } if (m_use4componentVertices) { m_indexedMeshes[0].m_numVertices = m_4componentVertices.Count; m_indexedMeshes[0].m_vertexStride = 1; } else { m_indexedMeshes[0].m_numVertices = m_3componentVertices.Count/3; m_indexedMeshes[0].m_vertexStride = 3; } }
//just to be backwards compatible public TriangleIndexVertexArray(int numTriangles,ObjectArray<int> triangleIndexBase,int triangleIndexStride,int numVertices,ObjectArray<Vector3> vertexBase,int vertexStride) { IndexedMesh indexedMesh = new IndexedMesh(); indexedMesh.m_numTriangles = numTriangles; indexedMesh.m_triangleIndexBase = triangleIndexBase; indexedMesh.m_triangleIndexStride = triangleIndexStride; indexedMesh.m_numVertices = numVertices; indexedMesh.m_vertexBase = vertexBase; indexedMesh.m_vertexStride = vertexStride; AddIndexedMesh(indexedMesh,PHY_ScalarType.PHY_INTEGER); }
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"); IsDebugDrawEnabled = false; 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); }
private void CreateGround() { const int totalVerts = NumVertsX * NumVertsY; const int totalTriangles = 2 * (NumVertsX - 1) * (NumVertsY - 1); const int triangleIndexStride = 3 * sizeof(int); const int vertexStride = Vector3.SizeInBytes; var mesh = new IndexedMesh(); mesh.Allocate(totalTriangles, totalVerts, triangleIndexStride, vertexStride); var indicesStream = mesh.GetTriangleStream(); using (var indices = new BinaryWriter(indicesStream)) { for (int x = 0; x < NumVertsX - 1; x++) { for (int y = 0; y < NumVertsY - 1; y++) { int row1Index = x * NumVertsX + y; int row2Index = row1Index + NumVertsX; indices.Write(row1Index); indices.Write(row1Index + 1); indices.Write(row2Index + 1); indices.Write(row1Index); indices.Write(row2Index + 1); indices.Write(row2Index); } } } indexVertexArrays = new TriangleIndexVertexArray(); indexVertexArrays.AddIndexedMesh(mesh); 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"; }
private void EvaluateNormals(IndexedMesh indexedMesh) { foreach (var bufferAndPrimitives in indexedMesh.GroupPrimitives()) { var bufferView = bufferAndPrimitives.BufferView; var existingNormals = bufferView.GetStream(StreamKey.Normal); if (existingNormals != null) { continue; } var positions = bufferView.GetStreamReader <Vector3>(StreamKey.Position); var normals = new ArrayMeshStream <Vector3>(positions.Count, StreamConverterFactory.Default); foreach (var primitive in bufferAndPrimitives) { primitive.SetIndexStream(StreamKey.Normal, primitive.GetIndexReader(StreamKey.Position).ToList()); } { foreach (var face in indexedMesh.Primitives.SelectMany(_ => _.GetFaces(StreamKey.Position))) { var a = positions[face.Item1]; var b = positions[face.Item2]; var c = positions[face.Item3]; var n = Vector3.Cross(b - a, c - a); normals[face.Item1] += n; normals[face.Item2] += n; normals[face.Item3] += n; } for (var index = 0; index < normals.Count; index++) { var normal = normals[index]; if (normal != Vector3.Zero) { normals[index] = Vector3.Normalize(normal); } } bufferView.SetStream(StreamKey.Normal, normals); } foreach (var primitive in bufferAndPrimitives) { primitive.SetIndexStream(StreamKey.Normal, primitive.GetIndexReader(StreamKey.Position).ToList()); } } }
private void CreateGround() { const int totalVerts = NumVertsX * NumVertsY; const int totalTriangles = 2 * (NumVertsX - 1) * (NumVertsY - 1); const int triangleIndexStride = 3 * sizeof(int); indexVertexArrays = new TriangleIndexVertexArray(); var mesh = new IndexedMesh(); mesh.Allocate(totalTriangles, totalVerts, triangleIndexStride, Vector3.SizeInBytes, PhyScalarType.Int32, PhyScalarType.Single); DataStream indices = mesh.LockIndices(); for (int x = 0; x < NumVertsX - 1; x++) { for (int y = 0; y < NumVertsY - 1; y++) { int row1Index = x * NumVertsX + y; int row2Index = row1Index + NumVertsX; indices.Write(row1Index); indices.Write(row1Index + 1); indices.Write(row2Index + 1); indices.Write(row1Index); indices.Write(row2Index + 1); indices.Write(row2Index); } } indices.Dispose(); indexVertexArrays = new TriangleIndexVertexArray(); indexVertexArrays.AddIndexedMesh(mesh); SetVertexPositions(WaveHeight, 0.0f); const bool useQuantizedAabbCompression = true; groundShape = new BvhTriangleMeshShape(indexVertexArrays, useQuantizedAabbCompression); staticBody = LocalCreateRigidBody(0.0f, Matrix.Identity, groundShape); staticBody.CollisionFlags |= CollisionFlags.StaticObject; staticBody.UserObject = "Ground"; }
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); }
private IEnumerable <IMesh> PaintSeparateStreamMesh(IndexedMesh mesh) { foreach (var bufferAndPrimitives in mesh.GroupPrimitives()) { var bufferView = bufferAndPrimitives.BufferView; if (bufferView.GetStream(StreamKey.Color) != null) { continue; } var streamConverterFactory = bufferView.GetStream(StreamKey.Position).ConverterFactory; bufferView.SetStream(StreamKey.Color, new ArrayMeshStream <Vector4>(new[] { _color }, streamConverterFactory)); foreach (var primitiveAndIndex in bufferAndPrimitives.Primitives) { var submesh = primitiveAndIndex.Primitive; var positionIndices = submesh.GetIndexReader(StreamKey.Position); var indices = new int[positionIndices.Count]; submesh.SetIndexStream(StreamKey.Color, indices); } } yield return(mesh); }
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(); 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); 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"; }
public void AddIndexedMesh(IndexedMesh mesh, PHY_ScalarType indexType) { m_indexedMeshes.Add(mesh); m_indexedMeshes[m_indexedMeshes.Count-1].m_indexType = indexType; }
public void AddIndexedMesh(IndexedMesh indexedMesh) { _indexedMeshes.Add(indexedMesh); }
public TriangleIndexVertexArray(int numTriangleIndices, int[] triangleIndexBase, int triangleIndexStride, int numVertices, Vector3[] vertexBase, int vertexStride) { IndexedMesh mesh = new IndexedMesh(); mesh.TriangleCount = numTriangleIndices; mesh.TriangleIndexBase = triangleIndexBase; mesh.TriangleIndexStride = triangleIndexStride; mesh.VertexBase = vertexBase; mesh.VertexCount = numVertices; mesh.VertexStride = vertexStride; AddIndexedMesh(mesh); }
// Create a sequence of flag objects and add them to the world. void CreateFlag(int width, int height, out AlignedSoftBodyArray flags) { flags = new AlignedSoftBodyArray(); // First create a triangle mesh to represent a flag // Allocate a simple mesh consisting of a vertex array and a triangle index array IndexedMesh mesh = new IndexedMesh(); mesh.NumVertices = width * height; mesh.NumTriangles = 2 * (width - 1) * (height - 1); Vector3Array vertexArray = new Vector3Array(mesh.NumVertices); mesh.Vertices = vertexArray; mesh.VertexStride = Vector3.SizeInBytes; IntArray triangleVertexIndexArray = new IntArray(3 * mesh.NumTriangles); mesh.TriangleIndices = triangleVertexIndexArray; mesh.TriangleIndexStride = sizeof(int) * 3; // Generate normalised object space vertex coordinates for a rectangular flag Matrix defaultScale = Matrix.Scaling(5, 20, 1); for (int y = 0; y < height; ++y) { float yCoordinate = y * 2.0f / (float)height - 1.0f; for (int x = 0; x < width; ++x) { float xCoordinate = x * 2.0f / (float)width - 1.0f; Vector3 vertex = new Vector3(xCoordinate, yCoordinate, 0.0f); vertexArray[y * width + x] = Vector3.TransformCoordinate(vertex, defaultScale); } } // Generate vertex indices for triangles for (int y = 0; y < (height - 1); ++y) { for (int x = 0; x < (width - 1); ++x) { // Triangle 0 // Top left of square on mesh { int vertex0 = y * width + x; int vertex1 = vertex0 + 1; int vertex2 = vertex0 + width; int triangleIndex = 2 * (y * (width - 1) + x); triangleVertexIndexArray[(mesh.TriangleIndexStride * triangleIndex) / sizeof(int)] = vertex0; triangleVertexIndexArray[(mesh.TriangleIndexStride * triangleIndex + 1) / sizeof(int) + 1] = vertex1; triangleVertexIndexArray[(mesh.TriangleIndexStride * triangleIndex + 2) / sizeof(int) + 2] = vertex2; } // Triangle 1 // Bottom right of square on mesh { int vertex0 = y * width + x + 1; int vertex1 = vertex0 + width; int vertex2 = vertex1 - 1; int triangleIndex = 2 * y * (width - 1) + 2 * x + 1; triangleVertexIndexArray[(mesh.TriangleIndexStride * triangleIndex) / sizeof(int)] = vertex0; triangleVertexIndexArray[(mesh.TriangleIndexStride * triangleIndex) / sizeof(int) + 1] = vertex1; triangleVertexIndexArray[(mesh.TriangleIndexStride * triangleIndex) / sizeof(int) + 2] = vertex2; } } } Matrix defaultRotateAndScale = Matrix.RotationX(0.5f); // Construct the sequence flags applying a slightly different translation to each one to arrange them // appropriately in the scene. for (int i = 0; i < numFlags; ++i) { float zTranslate = flagSpacing * (i - numFlags / 2); Vector3 defaultTranslate = new Vector3(0, 20, zTranslate); Matrix transform = defaultRotateAndScale * Matrix.Translation(defaultTranslate); SoftBody softBody = CreateFromIndexedMesh(vertexArray, triangleVertexIndexArray, true); for (int j = 0; j < mesh.NumVertices; ++j) { softBody.SetMass(j, 10.0f / mesh.NumVertices); } softBody.SetMass((height - 1) * width, 0); softBody.SetMass((height - 1) * width + width - 1, 0); softBody.SetMass((height - 1) * width + width / 2, 0); softBody.Cfg.Collisions = FCollisions.CLSS | FCollisions.CLRS; softBody.Cfg.LF = 0.0005f; softBody.Cfg.VCF = 0.001f; softBody.Cfg.DP = 0.0f; softBody.Cfg.DG = 0.0f; flags.Add(softBody); softBody.Transform(transform); SoftWorld.AddSoftBody(softBody); } //delete [] vertexArray; //delete [] triangleVertexIndexArray; }
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); RigidBody ground = LocalCreateRigidBody(0, tr, groundShape); ground.UserObject = "Ground"; CreateVehicle(vehicleTr); }
private void CreateTrimeshGround() { 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); _groundVertexArray = new TriangleIndexVertexArray(); _groundMesh = new IndexedMesh(); _groundMesh.Allocate(totalTriangles, totalVerts); _groundMesh.NumTriangles = totalTriangles; _groundMesh.NumVertices = totalVerts; _groundMesh.TriangleIndexStride = 3 * sizeof(int); _groundMesh.VertexStride = Vector3.SizeInBytes; using (var indicesStream = _groundMesh.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(); } using (var vertexStream = _groundMesh.GetVertexStream()) { var vertices = new BinaryWriter(vertexStream); for (int i = 0; i < NumVertsX; i++) { for (int j = 0; j < NumVertsY; j++) { const float waveLength = .2f; float height = (float)(Math.Sin(i * waveLength) * Math.Cos(j * waveLength)); vertices.Write(i - NumVertsX * 0.5f); vertices.Write(height); vertices.Write(j - NumVertsY * 0.5f); } } vertices.Dispose(); } _groundVertexArray.AddIndexedMesh(_groundMesh); var groundShape = new BvhTriangleMeshShape(_groundVertexArray, true); var groundScaled = new ScaledBvhTriangleMeshShape(groundShape, new Vector3(scale)); RigidBody ground = PhysicsHelper.CreateStaticBody(Matrix.Identity, groundScaled, World); ground.UserObject = "Ground"; Matrix vehicleTransform = Matrix.Translation(0, -2, 0); CreateVehicle(vehicleTransform); }
public Physics(VehicleDemo game) { 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 int vertStride = Vector3.SizeInBytes; int indexStride = 3 * sizeof(int); const int NUM_VERTS_X = 20; const int NUM_VERTS_Y = 20; const int totalVerts = NUM_VERTS_X * NUM_VERTS_Y; const int totalTriangles = 2 * (NUM_VERTS_X - 1) * (NUM_VERTS_Y - 1); TriangleIndexVertexArray vertexArray = new TriangleIndexVertexArray(); IndexedMesh mesh = new IndexedMesh(); mesh.Allocate(totalVerts, vertStride, totalTriangles, indexStride, PhyScalarType.Int32, PhyScalarType.Single); BulletSharp.DataStream data = mesh.LockVerts(); for (i = 0; i < NUM_VERTS_X; i++) { for (int j = 0; j < NUM_VERTS_Y; j++) { float wl = .2f; float height = 20.0f * (float)(Math.Sin(i * wl) * Math.Cos(j * wl)); data.Write((i - NUM_VERTS_X * 0.5f) * scale); data.Write(height); data.Write((j - NUM_VERTS_Y * 0.5f) * scale); } } int index = 0; IntArray idata = mesh.TriangleIndices; for (i = 0; i < NUM_VERTS_X - 1; i++) { for (int j = 0; j < NUM_VERTS_Y - 1; j++) { idata[index++] = j * NUM_VERTS_X + i; idata[index++] = j * NUM_VERTS_X + i + 1; idata[index++] = (j + 1) * NUM_VERTS_X + i + 1; idata[index++] = j * NUM_VERTS_X + i; idata[index++] = (j + 1) * NUM_VERTS_X + i + 1; idata[index++] = (j + 1) * NUM_VERTS_X + i; } } 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.Single; 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.Single) { // heightScale isn't applied internally for float data height = reader.ReadSingle(); } else if (scalarType == PhyScalarType.Byte) { 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 RaycastVehicle.VehicleTuning tuning = new RaycastVehicle.VehicleTuning(); IVehicleRaycaster vehicleRayCaster = new DefaultVehicleRaycaster(World); vehicle = new RaycastVehicle(tuning, carChassis, vehicleRayCaster); carChassis.ActivationState = ActivationState.DisableDeactivation; World.AddAction(vehicle); float connectionHeight = 1.2f; bool isFrontWheel = true; // choose coordinate system vehicle.SetCoordinateSystem(rightIndex, upIndex, forwardIndex); Vector3 connectionPointCS0 = new Vector3(CUBE_HALF_EXTENTS - (0.3f * wheelWidth), connectionHeight, 2 * CUBE_HALF_EXTENTS - wheelRadius); WheelInfo a = 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; }
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.Allocate(totalTriangles, totalVerts, 3 * sizeof(int), Vector3.SizeInBytes, PhyScalarType.Int32, PhyScalarType.Single); DataStream indices = mesh.LockIndices(); 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); 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"; }