/* * 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 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); }
/* * 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); }
/* 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++] = 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; }
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; }
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; }