public void UpdateSoftBody(SoftBody softBody, ShapeData shapeData) { // Could just allocate a Vector3 array here at each frame, but reusing shapeData.SoftBodyData is faster. // Probably uses more memory though. softBody.GetVertexNormalData(out shapeData.SoftBodyData); shapeData.SetDynamicVertexBuffer(device, shapeData.SoftBodyData); if (softBody.Faces.Count == 0 && softBody.Tetras.Count == 0) { shapeData.PrimitiveTopology = PrimitiveTopology.LineList; } }
/* Mesh CreateStaticPlaneShape(StaticPlaneShape shape) { // Load shader if (planeShader == null) { Assembly assembly = Assembly.GetExecutingAssembly(); Stream shaderStream = assembly.GetManifestResourceStream("DemoFramework.checker_shader.fx"); planeShader = Effect.FromStream(device, shaderStream, ShaderFlags.None); } Vector3[] vertices = new Vector3[4 * 2]; Mesh mesh = new Mesh(device, 2, 4, MeshFlags.SystemMemory, VertexFormat.Position | VertexFormat.Normal); Vector3 planeOrigin = shape.PlaneNormal * shape.PlaneConstant; Vector3 vec0, vec1; PlaneSpace1(shape.PlaneNormal, out vec0, out vec1); float size = 1000; Vector3[] verts = new Vector3[4] { planeOrigin + vec0*size, planeOrigin - vec0*size, planeOrigin + vec1*size, planeOrigin - vec1*size }; SlimDX.DataStream vertexBuffer = mesh.LockVertexBuffer(LockFlags.Discard); vertexBuffer.Write(verts[0]); vertexBuffer.Position += 12; vertexBuffer.Write(verts[1]); vertexBuffer.Position += 12; vertexBuffer.Write(verts[2]); vertexBuffer.Position += 12; vertexBuffer.Write(verts[3]); vertexBuffer.Position += 12; mesh.UnlockVertexBuffer(); SlimDX.DataStream indexBuffer = mesh.LockIndexBuffer(LockFlags.Discard); indexBuffer.Write((short)1); indexBuffer.Write((short)2); indexBuffer.Write((short)0); indexBuffer.Write((short)1); indexBuffer.Write((short)3); indexBuffer.Write((short)0); mesh.UnlockIndexBuffer(); mesh.ComputeNormals(); complexShapes.Add(shape, mesh); return mesh; } */ ShapeData CreateTriangleMeshShape(StridingMeshInterface meshInterface) { BulletSharp.DataStream vertexStream, indexStream; int numVerts, numFaces; PhyScalarType vertsType, indicesType; int vertexStride, indexStride; meshInterface.GetLockedReadOnlyVertexIndexData(out vertexStream, out numVerts, out vertsType, out vertexStride, out indexStream, out indexStride, out numFaces, out indicesType); ShapeData shapeData = new ShapeData(); shapeData.VertexCount = numVerts; shapeData.IndexCount = numFaces * 3; Vector3[] vertices = new Vector3[shapeData.VertexCount * 2]; int v = 0; int vStrideExtra = vertexStride - Marshal.SizeOf(typeof(Vector3)); while (vertexStream.Position < vertexStream.Length) { Vector3 v0 = vertexStream.Read<Vector3>(); vertexStream.Position += vStrideExtra; Vector3 v1 = vertexStream.Read<Vector3>(); vertexStream.Position += vStrideExtra; Vector3 v2 = vertexStream.Read<Vector3>(); vertexStream.Position += vStrideExtra; Vector3 v01 = v0 - v1; Vector3 v02 = v0 - v2; Vector3 normal = Vector3.Cross(v01, v02); vertices[v++] = v0; vertices[v++] = normal; vertices[v++] = v1; vertices[v++] = normal; vertices[v++] = v2; vertices[v++] = normal; } int i = 0; if (numVerts > 65536) { uint[] indices = new uint[shapeData.IndexCount]; while (indexStream.Position < indexStream.Length) indices[i++] = indexStream.Read<uint>(); shapeData.SetIndexBuffer(device, indices); } else { ushort[] indices = new ushort[shapeData.IndexCount]; while (indexStream.Position < indexStream.Length) indices[i++] = (ushort)indexStream.Read<int>(); shapeData.SetIndexBuffer(device, indices); } shapeData.SetVertexBuffer(device, vertices); return shapeData; }
ShapeData InitShapeData(CollisionShape shape) { ShapeData shapeData; if (shapes.TryGetValue(shape, out shapeData) == false) { switch (shape.ShapeType) { case BroadphaseNativeType.SoftBodyShape: shapeData = new ShapeData(); break; case BroadphaseNativeType.BoxShape: shapeData = CreateBoxShape(shape as BoxShape); break; case BroadphaseNativeType.CapsuleShape: shapeData = CreateCapsule(shape as CapsuleShape); break; case BroadphaseNativeType.CylinderShape: shapeData = CreateCylinderShape(shape as CylinderShape); break; case BroadphaseNativeType.ConvexHullShape: shapeData = CreateConvexHullShape(shape as ConvexHullShape); break; case BroadphaseNativeType.GImpactShape: shapeData = CreateTriangleMeshShape((shape as GImpactMeshShape).MeshInterface); break; case BroadphaseNativeType.SphereShape: shapeData = CreateSphereShape(shape as SphereShape); break; case BroadphaseNativeType.TriangleMeshShape: shapeData = CreateTriangleMeshShape((shape as TriangleMeshShape).MeshInterface); break; default: throw new NotImplementedException(); } // Create an initial instance data buffer for a single instance instanceDataDesc.SizeInBytes = InstanceData.SizeInBytes; shapeData.InstanceDataBuffer = new Buffer(device, instanceDataDesc); shapeData.BufferBindings[1] = new VertexBufferBinding(shapeData.InstanceDataBuffer, instanceDataDesc.SizeInBytes, 0); shapes.Add(shape, shapeData); } return shapeData; }
ShapeData CreateConvexHullShape(ConvexHullShape shape) { ConvexPolyhedron poly = shape.ConvexPolyhedron; if (poly != null) { throw new NotImplementedException(); } ShapeHull hull = new ShapeHull(shape); hull.BuildHull(shape.Margin); int indexCount = hull.NumIndices; UIntArray indices = hull.Indices; Vector3Array points = hull.Vertices; ShapeData shapeData = new ShapeData(); shapeData.VertexCount = indexCount; Vector3[] vertices = new Vector3[indexCount * 2]; int v = 0, i; for (i = 0; i < indexCount; i += 3) { Vector3 v0 = points[(int)indices[i]]; Vector3 v1 = points[(int)indices[i + 1]]; Vector3 v2 = points[(int)indices[i + 2]]; Vector3 v01 = v0 - v1; Vector3 v02 = v0 - v2; Vector3 normal = Vector3.Cross(v01, v02); normal.Normalize(); vertices[v++] = v0; vertices[v++] = normal; vertices[v++] = v1; vertices[v++] = normal; vertices[v++] = v2; vertices[v++] = normal; } shapeData.SetVertexBuffer(device, vertices); return shapeData; }
/* Mesh CreateMultiSphereShape(MultiSphereShape shape) { Mesh mesh = null; int i; for (i = 0; i < shape.SphereCount; i++) { Vector3 position = shape.GetSpherePosition(i); Mesh sphereMesh = Mesh.CreateSphere(device, shape.GetSphereRadius(i), 12, 12); if (i == 0) { Matrix[] transform = new Matrix[] { Matrix.Translation(position) }; mesh = Mesh.Concatenate(device, new Mesh[] { sphereMesh }, MeshFlags.Managed, transform, null); } else { Mesh multiSphereMeshNew; Matrix[] transform = new Matrix[] { Matrix.Identity, Matrix.Translation(position) }; multiSphereMeshNew = Mesh.Concatenate(device, new Mesh[] { mesh, sphereMesh }, MeshFlags.Managed, transform, null); mesh.Dispose(); mesh = multiSphereMeshNew; } sphereMesh.Dispose(); } complexShapes.Add(shape, mesh); return mesh; } */ ShapeData CreateSphereShape(SphereShape shape) { float radius = shape.Radius; int slices = (int)(radius * 10.0f); int stacks = (int)(radius * 10.0f); slices = (slices > 16) ? 16 : (slices < 3) ? 3 : slices; stacks = (stacks > 16) ? 16 : (stacks < 2) ? 2 : stacks; float hAngleStep = (float)Math.PI * 2 / slices; float vAngleStep = (float)Math.PI / stacks; ShapeData shapeData = new ShapeData(); shapeData.VertexCount = 2 + slices * (stacks - 1); shapeData.IndexCount = 6 * slices * (stacks - 1); Vector3[] vertices = new Vector3[shapeData.VertexCount * 2]; ushort[] indices = new ushort[shapeData.IndexCount]; int i = 0, v = 0; // Vertices // Top and bottom vertices[v++] = new Vector3(0, -radius, 0); vertices[v++] = -Vector3.UnitY; vertices[v++] = new Vector3(0, radius, 0); vertices[v++] = Vector3.UnitY; // Stacks int j, k; float angle = 0; float vAngle = -(float)Math.PI / 2; Vector3 vTemp; for (j = 0; j < stacks - 1; j++) { vAngle += vAngleStep; for (k = 0; k < slices; k++) { angle += hAngleStep; vTemp = new Vector3((float)Math.Cos(vAngle) * (float)Math.Sin(angle), (float)Math.Sin(vAngle), (float)Math.Cos(vAngle) * (float)Math.Cos(angle)); vertices[v++] = vTemp * radius; vertices[v++] = Vector3.Normalize(vTemp); } } // Indices // Top cap ushort index = 2; for (k = 0; k < slices; k++) { indices[i++] = index++; indices[i++] = 0; indices[i++] = index; } indices[i - 1] = 2; // Stacks //for (j = 0; j < 1; j++) int sliceDiff = slices * 3; for (j = 0; j < stacks - 2; j++) { for (k = 0; k < slices; k++) { indices[i] = indices[i - sliceDiff + 2]; indices[i + 1] = index++; indices[i + 2] = indices[i - sliceDiff]; i += 3; } for (k = 0; k < slices; k++) { indices[i] = indices[i - sliceDiff + 1]; indices[i + 1] = indices[i - sliceDiff]; indices[i + 2] = indices[i - sliceDiff + 4]; i += 3; } indices[i - 1] = indices[i - sliceDiff]; } // Bottom cap index--; for (k = 0; k < slices; k++) { indices[i++] = index--; indices[i++] = 1; indices[i++] = index; } indices[i - 1] = indices[i - sliceDiff]; shapeData.SetVertexBuffer(device, vertices); shapeData.SetIndexBuffer(device, indices); return shapeData; }
public ShapeData CreateCapsule(CapsuleShape shape) { int up = shape.UpAxis; float radius = shape.Radius; float cylinderHalfHeight = shape.HalfHeight; int slices = (int)(radius * 10.0f); int stacks = (int)(radius * 10.0f); slices = (slices > 16) ? 16 : (slices < 3) ? 3 : slices; stacks = (stacks > 16) ? 16 : (stacks < 3) ? 3 : stacks; float hAngleStep = (float)Math.PI * 2 / slices; float vAngleStep = (float)Math.PI / stacks; ShapeData shapeData = new ShapeData(); shapeData.VertexCount = 2 + slices * (stacks - 1); shapeData.IndexCount = 6 * slices * (stacks - 1); Vector3[] vertices = new Vector3[shapeData.VertexCount * 2]; ushort[] indices = new ushort[shapeData.IndexCount]; int i = 0, v = 0; // Vertices // Top and bottom vertices[v++] = GetVectorByAxis(0, -cylinderHalfHeight - radius, 0, up); vertices[v++] = GetVectorByAxis(-Vector3.UnitY, up); vertices[v++] = GetVectorByAxis(0, cylinderHalfHeight + radius, 0, up); vertices[v++] = GetVectorByAxis(Vector3.UnitY, up); // Stacks int j, k; float angle = 0; float vAngle = -(float)Math.PI / 2; Vector3 vTemp; Vector3 cylinderOffset = GetVectorByAxis(0, -cylinderHalfHeight, 0, up); for (j = 0; j < stacks - 1; j++) { float prevAngle = vAngle; vAngle += vAngleStep; if (vAngle > 0 && prevAngle < 0) { cylinderOffset = GetVectorByAxis(0, cylinderHalfHeight, 0, up); } for (k = 0; k < slices; k++) { angle += hAngleStep; vTemp = GetVectorByAxis((float)Math.Cos(vAngle) * (float)Math.Sin(angle), (float)Math.Sin(vAngle), (float)Math.Cos(vAngle) * (float)Math.Cos(angle), up); vertices[v++] = vTemp * radius + cylinderOffset; vertices[v++] = Vector3.Normalize(vTemp); } } // Indices // Top cap ushort index = 2; for (k = 0; k < slices; k++) { indices[i++] = index++; indices[i++] = 0; indices[i++] = index; } indices[i - 1] = 2; // Stacks int sliceDiff = slices * 3; for (j = 0; j < stacks - 2; j++) { for (k = 0; k < slices; k++) { indices[i] = indices[i - sliceDiff + 2]; indices[i + 1] = index++; indices[i + 2] = indices[i - sliceDiff]; i += 3; } for (k = 0; k < slices; k++) { indices[i] = indices[i - sliceDiff + 1]; indices[i + 1] = indices[i - sliceDiff]; indices[i + 2] = indices[i - sliceDiff + 4]; i += 3; } indices[i - 1] = indices[i - sliceDiff]; } // Bottom cap index--; for (k = 0; k < slices; k++) { indices[i++] = index--; indices[i++] = 1; indices[i++] = index; } indices[i - 1] = indices[i - sliceDiff]; shapeData.SetVertexBuffer(device, vertices); shapeData.SetIndexBuffer(device, indices); return shapeData; }
ShapeData CreateCylinderShape(CylinderShape shape) { int up = shape.UpAxis; float radius = shape.Radius; float halfHeight = shape.HalfExtentsWithoutMargin[up] + shape.Margin; int numSteps = 10; float angleStep = (2 * (float)Math.PI) / numSteps; ShapeData shapeData = new ShapeData(); shapeData.VertexCount = 2 + 6 * numSteps; shapeData.IndexCount = (4 * numSteps + 2) * 3; Vector3[] vertices = new Vector3[shapeData.VertexCount * 2]; ushort[] indices = new ushort[shapeData.IndexCount]; int i = 0, v = 0; ushort index = 0; ushort baseIndex; Vector3 normal; // Draw two sides for (int side = 1; side != -3; side -= 2) { normal = GetVectorByAxis(side * Vector3.UnitY, up); baseIndex = index; vertices[v++] = GetVectorByAxis(new Vector3(0, side * halfHeight, 0), up); vertices[v++] = normal; vertices[v++] = GetVectorByAxis(new Vector3(0, side * halfHeight, radius), up); vertices[v++] = normal; index += 2; for (int j = 1; j < numSteps; j++) { float x = radius * (float)Math.Sin(j * angleStep); float z = radius * (float)Math.Cos(j * angleStep); vertices[v++] = GetVectorByAxis(new Vector3(x, side * halfHeight, z), up); vertices[v++] = normal; indices[i++] = baseIndex; if (side == 1) { indices[i++] = (ushort)(index - 1); indices[i++] = index++; } else { indices[i++] = index; indices[i++] = (ushort)(index - 1); index++; } } indices[i++] = baseIndex; if (side == 1) { indices[i++] = (ushort)(index - 1); indices[i++] = (ushort)(baseIndex + 1); } else { indices[i++] = (ushort)(baseIndex + 1); indices[i++] = (ushort)(index - 1); } } normal = GetVectorByAxis(new Vector3(0, 0, radius), up); normal.Normalize(); baseIndex = index; vertices[v++] = GetVectorByAxis(new Vector3(0, halfHeight, radius), up); vertices[v++] = normal; vertices[v++] = GetVectorByAxis(new Vector3(0, -halfHeight, radius), up); vertices[v++] = normal; index += 2; for (int j = 1; j < numSteps + 1; j++) { float x = radius * (float)Math.Sin(j * angleStep); float z = radius * (float)Math.Cos(j * angleStep); normal = GetVectorByAxis(new Vector3(x, 0, z), up); normal.Normalize(); vertices[v++] = GetVectorByAxis(new Vector3(x, halfHeight, z), up); vertices[v++] = normal; vertices[v++] = GetVectorByAxis(new Vector3(x, -halfHeight, z), up); vertices[v++] = normal; indices[i++] = (ushort)(index - 2); indices[i++] = (ushort)(index - 1); indices[i++] = index; indices[i++] = index; indices[i++] = (ushort)(index - 1); indices[i++] = (ushort)(index + 1); index += 2; } indices[i++] = (ushort)(index - 2); indices[i++] = (ushort)(index - 1); indices[i++] = baseIndex; indices[i++] = baseIndex; indices[i++] = (ushort)(index - 1); indices[i] = (ushort)(baseIndex + 1); shapeData.SetVertexBuffer(device, vertices); shapeData.SetIndexBuffer(device, indices); return shapeData; }
ShapeData CreateBoxShape(BoxShape shape) { Vector3 size = shape.HalfExtentsWithMargin; float x = size.X; float y = size.Y; float z = size.Z; ShapeData shapeData = new ShapeData(); shapeData.VertexCount = 36; Vector3[] vectors = new Vector3[shapeData.VertexCount * 2]; Vector3 normal; int v = 0; // Draw two sides for (int i = 1; i != -3; i -= 2) { normal = new Vector3(i, 0, 0); vectors[v++] = new Vector3(i * x, y, -z); // Position vectors[v++] = normal; vectors[v++] = new Vector3(i * x, -y, -z); vectors[v++] = normal; vectors[v++] = new Vector3(i * x, -y, z); vectors[v++] = normal; vectors[v++] = new Vector3(i * x, y, -z); vectors[v++] = normal; vectors[v++] = new Vector3(i * x, y, z); vectors[v++] = normal; vectors[v++] = new Vector3(i * x, -y, z); vectors[v++] = normal; } for (int i = 1; i != -3; i -= 2) { normal = new Vector3(0, 0, i); vectors[v++] = new Vector3(-x, y, i * z); vectors[v++] = normal; vectors[v++] = new Vector3(-x, -y, i * z); vectors[v++] = normal; vectors[v++] = new Vector3(x, -y, i * z); vectors[v++] = normal; vectors[v++] = new Vector3(-x, y, i * z); vectors[v++] = normal; vectors[v++] = new Vector3(x, y, i * z); vectors[v++] = normal; vectors[v++] = new Vector3(x, -y, i * z); vectors[v++] = normal; } for (int i = 1; i != -3; i -= 2) { normal = new Vector3(0, i, 0); vectors[v++] = new Vector3(-x, i * y, -z); vectors[v++] = normal; vectors[v++] = new Vector3(x, i * y, -z); vectors[v++] = normal; vectors[v++] = new Vector3(-x, i * y, z); vectors[v++] = normal; vectors[v++] = new Vector3(x, i * y, z); vectors[v++] = normal; vectors[v++] = new Vector3(-x, i * y, z); vectors[v++] = normal; vectors[v++] = new Vector3(x, i * y, -z); vectors[v++] = normal; } shapeData.SetVertexBuffer(device, vectors); return shapeData; }
ShapeData CreateBoxShape(BoxShape shape) { Vector3 size = shape.HalfExtentsWithMargin; float x = size.X; float y = size.Y; float z = size.Z; ShapeData shapeData = new ShapeData(); shapeData.VertexCount = 36; Vector3[] vertices = new Vector3[shapeData.VertexCount * 2]; Vector3 normal; int v = 0; for (int j = 0; j < 3; j++) { for (int i = 1; i != -3; i -= 2) { normal = GetVectorByAxis(0, i, 0, j); vertices[v++] = GetVectorByAxis(i, i, i, j) * size; vertices[v++] = normal; vertices[v++] = GetVectorByAxis(1, i, -1, j) * size; vertices[v++] = normal; vertices[v++] = GetVectorByAxis(-1, i, 1, j) * size; vertices[v++] = normal; vertices[v++] = GetVectorByAxis(-i, i, -i, j) * size; vertices[v++] = normal; vertices[v++] = GetVectorByAxis(-1, i, 1, j) * size; vertices[v++] = normal; vertices[v++] = GetVectorByAxis(1, i, -1, j) * size; vertices[v++] = normal; } } shapeData.SetVertexBuffer(device, vertices); return shapeData; }
public void InitInstancedRender() { // Clear instance data foreach (ShapeData s in shapes.Values) { s.InstanceDataList.Clear(); } removeList.Clear(); AlignedCollisionObjectArray objects = demo.PhysicsContext.World.CollisionObjectArray; int i = objects.Count - 1; for (; i >= 0; i--) { CollisionObject colObj = objects[i]; Matrix transform; if (colObj is SoftBody) { transform = Matrix.Identity; } else { ((colObj as RigidBody).MotionState as DefaultMotionState).GetWorldTransform(out transform); } InitInstanceData(colObj, colObj.CollisionShape, ref transform); } foreach (KeyValuePair <CollisionShape, ShapeData> sh in shapes) { ShapeData s = sh.Value; // Is the instance buffer the right size? if (s.InstanceDataBuffer.Description.SizeInBytes != s.InstanceDataList.Count * 68) { // No, recreate it s.InstanceDataBuffer.Dispose(); if (s.InstanceDataList.Count == 0) { if (s.IndexBuffer != null) { s.IndexBuffer.Dispose(); } s.VertexBuffer.Dispose(); removeList.Add(sh.Key); continue; } instanceDataDesc.SizeInBytes = s.InstanceDataList.Count * 68; s.InstanceDataBuffer = new Buffer(device, instanceDataDesc); s.BufferBindings[1] = new VertexBufferBinding(s.InstanceDataBuffer, 68, 0); } // Copy the instance data over to the instance buffer using (var data = s.InstanceDataBuffer.Map(MapMode.WriteDiscard)) { data.WriteRange(s.InstanceDataList.ToArray()); s.InstanceDataBuffer.Unmap(); } } if (removeList.Count != 0) { for (i = removeList.Count - 1; i >= 0; i--) { shapes.Remove(removeList[i]); } } }
public void UpdateSoftBody(SoftBody softBody, ShapeData shapeData) { AlignedFaceArray faces = softBody.Faces; if (faces.Count != 0) { shapeData.VertexCount = faces.Count * 3; Vector3[] vectors = new Vector3[shapeData.VertexCount * 2]; int v = 0; int i; for (i = 0; i < faces.Count; i++) { NodePtrArray nodes = faces[i].N; Node n0 = nodes[0]; Node n1 = nodes[1]; Node n2 = nodes[2]; n0.GetX(out vectors[v]); n0.GetNormal(out vectors[v + 1]); n1.GetX(out vectors[v + 2]); n1.GetNormal(out vectors[v + 3]); n2.GetX(out vectors[v + 4]); n2.GetNormal(out vectors[v + 5]); v += 6; } shapeData.SetDynamicVertexBuffer(device, vectors); } else { AlignedTetraArray tetras = softBody.Tetras; int tetraCount = tetras.Count; if (tetraCount != 0) { shapeData.VertexCount = tetraCount * 12; Vector3[] vectors = new Vector3[tetraCount * 24]; int v = 0; for (int i = 0; i < tetraCount; i++) { NodePtrArray nodes = tetras[i].Nodes; Vector3 v0 = nodes[0].X; Vector3 v1 = nodes[1].X; Vector3 v2 = nodes[2].X; Vector3 v3 = nodes[3].X; Vector3 v10 = v1 - v0; Vector3 v02 = v0 - v2; Vector3 normal = Vector3.Cross(v10, v02); vectors[v] = v0; vectors[v + 1] = normal; vectors[v + 2] = v1; vectors[v + 3] = normal; vectors[v + 4] = v2; vectors[v + 5] = normal; normal = Vector3.Cross(v10, v3 - v0); vectors[v + 6] = v0; vectors[v + 7] = normal; vectors[v + 8] = v1; vectors[v + 9] = normal; vectors[v + 10] = v3; vectors[v + 11] = normal; normal = Vector3.Cross(v2 - v1, v3 - v1); vectors[v + 12] = v1; vectors[v + 13] = normal; vectors[v + 14] = v2; vectors[v + 15] = normal; vectors[v + 16] = v3; vectors[v + 17] = normal; normal = Vector3.Cross(v02, v3 - v2); vectors[v + 18] = v2; vectors[v + 19] = normal; vectors[v + 20] = v0; vectors[v + 21] = normal; vectors[v + 22] = v3; vectors[v + 23] = normal; v += 24; } shapeData.SetDynamicVertexBuffer(device, vectors); } else if (softBody.Links.Count != 0) { AlignedLinkArray links = softBody.Links; int linkCount = links.Count; shapeData.VertexCount = linkCount * 2; Vector3[] vectors = new Vector3[linkCount * 4]; for (int i = 0; i < linkCount; i++) { NodePtrArray nodes = links[i].Nodes; nodes[0].GetX(out vectors[i * 4]); nodes[1].GetX(out vectors[i * 4 + 2]); } shapeData.PrimitiveTopology = PrimitiveTopology.LineList; shapeData.SetDynamicVertexBuffer(device, vectors); } else { throw new NotImplementedException(); } } }
/* * Mesh CreateStaticPlaneShape(StaticPlaneShape shape) * { * // Load shader * if (planeShader == null) * { * Assembly assembly = Assembly.GetExecutingAssembly(); * Stream shaderStream = assembly.GetManifestResourceStream("DemoFramework.checker_shader.fx"); * * planeShader = Effect.FromStream(device, shaderStream, ShaderFlags.None); * } * * * Vector3[] vertices = new Vector3[4 * 2]; * * Mesh mesh = new Mesh(device, 2, 4, MeshFlags.SystemMemory, VertexFormat.Position | VertexFormat.Normal); * * Vector3 planeOrigin = shape.PlaneNormal * shape.PlaneConstant; * Vector3 vec0, vec1; * PlaneSpace1(shape.PlaneNormal, out vec0, out vec1); * float size = 1000; * * Vector3[] verts = new Vector3[4] * { * planeOrigin + vec0*size, * planeOrigin - vec0*size, * planeOrigin + vec1*size, * planeOrigin - vec1*size * }; * * SlimDX.DataStream vertexBuffer = mesh.LockVertexBuffer(LockFlags.Discard); * vertexBuffer.Write(verts[0]); * vertexBuffer.Position += 12; * vertexBuffer.Write(verts[1]); * vertexBuffer.Position += 12; * vertexBuffer.Write(verts[2]); * vertexBuffer.Position += 12; * vertexBuffer.Write(verts[3]); * vertexBuffer.Position += 12; * mesh.UnlockVertexBuffer(); * * SlimDX.DataStream indexBuffer = mesh.LockIndexBuffer(LockFlags.Discard); * indexBuffer.Write((short)1); * indexBuffer.Write((short)2); * indexBuffer.Write((short)0); * indexBuffer.Write((short)1); * indexBuffer.Write((short)3); * indexBuffer.Write((short)0); * mesh.UnlockIndexBuffer(); * * mesh.ComputeNormals(); * * complexShapes.Add(shape, mesh); * * return mesh; * } */ ShapeData CreateTriangleMeshShape(StridingMeshInterface meshInterface) { BulletSharp.DataStream vertexStream, indexStream; int numVerts, numFaces; PhyScalarType vertsType, indicesType; int vertexStride, indexStride; meshInterface.GetLockedReadOnlyVertexIndexData(out vertexStream, out numVerts, out vertsType, out vertexStride, out indexStream, out indexStride, out numFaces, out indicesType); ShapeData shapeData = new ShapeData(); shapeData.VertexCount = numVerts; shapeData.IndexCount = numFaces * 3; Vector3[] vertices = new Vector3[shapeData.VertexCount * 2]; int v = 0; int vStrideExtra = vertexStride - Marshal.SizeOf(typeof(Vector3)); while (vertexStream.Position < vertexStream.Length) { Vector3 v0 = vertexStream.Read <Vector3>(); vertexStream.Position += vStrideExtra; Vector3 v1 = vertexStream.Read <Vector3>(); vertexStream.Position += vStrideExtra; Vector3 v2 = vertexStream.Read <Vector3>(); vertexStream.Position += vStrideExtra; Vector3 v01 = v0 - v1; Vector3 v02 = v0 - v2; Vector3 normal = Vector3.Cross(v01, v02); vertices[v++] = v0; vertices[v++] = normal; vertices[v++] = v1; vertices[v++] = normal; vertices[v++] = v2; vertices[v++] = normal; } int i = 0; if (numVerts > 65536) { uint[] indices = new uint[shapeData.IndexCount]; while (indexStream.Position < indexStream.Length) { indices[i++] = indexStream.Read <uint>(); } shapeData.SetIndexBuffer(device, indices); } else { ushort[] indices = new ushort[shapeData.IndexCount]; while (indexStream.Position < indexStream.Length) { indices[i++] = (ushort)indexStream.Read <int>(); } shapeData.SetIndexBuffer(device, indices); } shapeData.SetVertexBuffer(device, vertices); return(shapeData); }
/* * Mesh CreateMultiSphereShape(MultiSphereShape shape) * { * Mesh mesh = null; * * int i; * for (i = 0; i < shape.SphereCount; i++) * { * Vector3 position = shape.GetSpherePosition(i); * * Mesh sphereMesh = Mesh.CreateSphere(device, shape.GetSphereRadius(i), 12, 12); * if (i == 0) * { * Matrix[] transform = new Matrix[] { Matrix.Translation(position) }; * mesh = Mesh.Concatenate(device, new Mesh[] { sphereMesh }, MeshFlags.Managed, transform, null); * } * else * { * Mesh multiSphereMeshNew; * Matrix[] transform = new Matrix[] { Matrix.Identity, Matrix.Translation(position) }; * multiSphereMeshNew = Mesh.Concatenate(device, new Mesh[] { mesh, sphereMesh }, MeshFlags.Managed, transform, null); * mesh.Dispose(); * mesh = multiSphereMeshNew; * } * sphereMesh.Dispose(); * } * * complexShapes.Add(shape, mesh); * return mesh; * } */ ShapeData CreateSphereShape(SphereShape shape) { float radius = shape.Radius; int slices = (int)(radius * 10.0f); int stacks = (int)(radius * 10.0f); slices = (slices > 16) ? 16 : (slices < 3) ? 3 : slices; stacks = (stacks > 16) ? 16 : (stacks < 2) ? 2 : stacks; float hAngleStep = (float)Math.PI * 2 / slices; float vAngleStep = (float)Math.PI / stacks; ShapeData shapeData = new ShapeData(); shapeData.VertexCount = 2 + slices * (stacks - 1); shapeData.IndexCount = 6 * slices * (stacks - 1); Vector3[] vertices = new Vector3[shapeData.VertexCount * 2]; ushort[] indices = new ushort[shapeData.IndexCount]; int i = 0, v = 0; // Vertices // Top and bottom vertices[v++] = new Vector3(0, -radius, 0); vertices[v++] = -Vector3.UnitY; vertices[v++] = new Vector3(0, radius, 0); vertices[v++] = Vector3.UnitY; // Stacks int j, k; float angle = 0; float vAngle = -(float)Math.PI / 2; Vector3 vTemp; for (j = 0; j < stacks - 1; j++) { vAngle += vAngleStep; for (k = 0; k < slices; k++) { angle += hAngleStep; vTemp = new Vector3((float)Math.Cos(vAngle) * (float)Math.Sin(angle), (float)Math.Sin(vAngle), (float)Math.Cos(vAngle) * (float)Math.Cos(angle)); vertices[v++] = vTemp * radius; vertices[v++] = Vector3.Normalize(vTemp); } } // Indices // Top cap ushort index = 2; for (k = 0; k < slices; k++) { indices[i++] = 0; indices[i++] = index; index++; indices[i++] = index; } indices[i - 1] = 2; // Stacks //for (j = 0; j < 1; j++) int sliceDiff = slices * 3; for (j = 0; j < stacks - 2; j++) { for (k = 0; k < slices; k++) { indices[i++] = indices[i - sliceDiff]; indices[i++] = indices[i - sliceDiff]; indices[i++] = index; index++; } for (k = 0; k < slices; k++) { indices[i++] = indices[i - sliceDiff]; indices[i++] = indices[i - sliceDiff]; indices[i++] = indices[i - sliceDiff + 2]; } indices[i - 1] = indices[i - sliceDiff + 1]; } // Bottom cap index--; for (k = 0; k < slices; k++) { indices[i++] = 1; indices[i++] = index; index--; indices[i++] = index; } indices[i - 1] = indices[i - sliceDiff + 1]; shapeData.SetVertexBuffer(device, vertices); shapeData.SetIndexBuffer(device, indices); return(shapeData); }
ShapeData CreateCylinderShape(CylinderShape shape) { int up = shape.UpAxis; float radius = shape.Radius; float halfHeight = shape.HalfExtentsWithoutMargin[up] + shape.Margin; int numSteps = 10; float angleStep = (2 * (float)Math.PI) / numSteps; ShapeData shapeData = new ShapeData(); shapeData.VertexCount = 2 + 6 * numSteps; shapeData.IndexCount = (4 * numSteps + 2) * 3; Vector3[] vertices = new Vector3[shapeData.VertexCount * 2]; ushort[] indices = new ushort[shapeData.IndexCount]; int i = 0, v = 0; ushort index = 0; ushort baseIndex; Vector3 normal; // Draw two sides for (int side = 1; side != -3; side -= 2) { normal = GetVectorByAxis(side * Vector3.UnitY, up); baseIndex = index; vertices[v++] = GetVectorByAxis(new Vector3(0, side * halfHeight, 0), up); vertices[v++] = normal; vertices[v++] = GetVectorByAxis(new Vector3(0, side * halfHeight, radius), up); vertices[v++] = normal; index += 2; for (int j = 1; j < numSteps; j++) { float x = radius * (float)Math.Sin(j * angleStep); float z = radius * (float)Math.Cos(j * angleStep); vertices[v++] = GetVectorByAxis(new Vector3(x, side * halfHeight, z), up); vertices[v++] = normal; indices[i++] = baseIndex; indices[i++] = (ushort)(index - 1); indices[i++] = index++; } indices[i++] = baseIndex; indices[i++] = (ushort)(index - 1); indices[i++] = (ushort)(baseIndex + 1); } normal = GetVectorByAxis(new Vector3(0, 0, radius), up); normal.Normalize(); baseIndex = index; vertices[v++] = GetVectorByAxis(new Vector3(0, halfHeight, radius), up); vertices[v++] = normal; vertices[v++] = GetVectorByAxis(new Vector3(0, -halfHeight, radius), up); vertices[v++] = normal; index += 2; for (int j = 1; j < numSteps + 1; j++) { float x = radius * (float)Math.Sin(j * angleStep); float z = radius * (float)Math.Cos(j * angleStep); normal = GetVectorByAxis(new Vector3(x, 0, z), up); normal.Normalize(); vertices[v++] = GetVectorByAxis(new Vector3(x, halfHeight, z), up); vertices[v++] = normal; vertices[v++] = GetVectorByAxis(new Vector3(x, -halfHeight, z), up); vertices[v++] = normal; indices[i++] = (ushort)(index - 2); indices[i++] = (ushort)(index - 1); indices[i++] = index; indices[i++] = index; indices[i++] = (ushort)(index - 1); indices[i++] = (ushort)(index + 1); index += 2; } indices[i++] = (ushort)(index - 2); indices[i++] = (ushort)(index - 1); indices[i++] = baseIndex; indices[i++] = baseIndex; indices[i++] = (ushort)(index - 1); indices[i++] = (ushort)(baseIndex + 1); shapeData.SetVertexBuffer(device, vertices); shapeData.SetIndexBuffer(device, indices); return(shapeData); }
ShapeData CreateBoxShape(BoxShape shape) { Vector3 size = shape.HalfExtentsWithMargin; float x = size.X; float y = size.Y; float z = size.Z; ShapeData shapeData = new ShapeData(); shapeData.VertexCount = 36; Vector3[] vectors = new Vector3[shapeData.VertexCount * 2]; Vector3 normal; int v = 0; // Draw two sides for (int i = 1; i != -3; i -= 2) { normal = new Vector3(i, 0, 0); vectors[v++] = new Vector3(i * x, y, -z); // Position vectors[v++] = normal; vectors[v++] = new Vector3(i * x, -y, -z); vectors[v++] = normal; vectors[v++] = new Vector3(i * x, -y, z); vectors[v++] = normal; vectors[v++] = new Vector3(i * x, y, -z); vectors[v++] = normal; vectors[v++] = new Vector3(i * x, y, z); vectors[v++] = normal; vectors[v++] = new Vector3(i * x, -y, z); vectors[v++] = normal; } for (int i = 1; i != -3; i -= 2) { normal = new Vector3(0, 0, i); vectors[v++] = new Vector3(-x, y, i * z); vectors[v++] = normal; vectors[v++] = new Vector3(-x, -y, i * z); vectors[v++] = normal; vectors[v++] = new Vector3(x, -y, i * z); vectors[v++] = normal; vectors[v++] = new Vector3(-x, y, i * z); vectors[v++] = normal; vectors[v++] = new Vector3(x, y, i * z); vectors[v++] = normal; vectors[v++] = new Vector3(x, -y, i * z); vectors[v++] = normal; } for (int i = 1; i != -3; i -= 2) { normal = new Vector3(0, i, 0); vectors[v++] = new Vector3(-x, i * y, -z); vectors[v++] = normal; vectors[v++] = new Vector3(x, i * y, -z); vectors[v++] = normal; vectors[v++] = new Vector3(-x, i * y, z); vectors[v++] = normal; vectors[v++] = new Vector3(x, i * y, z); vectors[v++] = normal; vectors[v++] = new Vector3(-x, i * y, z); vectors[v++] = normal; vectors[v++] = new Vector3(x, i * y, -z); vectors[v++] = normal; } shapeData.SetVertexBuffer(device, vectors); return(shapeData); }