Mesh CreateTriangleMeshShape(TriangleMeshShape shape) { StridingMeshInterface meshInterface = shape.MeshInterface; BulletSharp.DataStream verts, indices; int numVerts, numFaces; PhyScalarType vertsType, indicesType; int vertexStride, indexStride; meshInterface.GetLockedReadOnlyVertexIndexData(out verts, out numVerts, out vertsType, out vertexStride, out indices, out indexStride, out numFaces, out indicesType); bool index32 = numVerts > 65536; Mesh mesh = new Mesh(device, numFaces, numVerts, MeshFlags.SystemMemory | (index32 ? MeshFlags.Use32Bit : 0), VertexFormat.Position | VertexFormat.Normal); SlimDX.DataStream data = mesh.LockVertexBuffer(LockFlags.None); while (verts.Position < verts.Length) { Vector3 v = verts.Read <Vector3>(); data.Write(v); verts.Position += vertexStride - 12; // Normals will be calculated later data.Position += 12; } mesh.UnlockVertexBuffer(); data = mesh.LockIndexBuffer(LockFlags.None); while (indices.Position < indices.Length) { int index = indices.Read <int>(); if (index32) { data.Write(index); } else { data.Write((short)index); } } mesh.UnlockVertexBuffer(); mesh.ComputeNormals(); shapes.Add(shape, mesh); return(mesh); }
static Vector3[] CreateTriangleMesh(StridingMeshInterface meshInterface) { var indexStream = meshInterface.GetIndexStream(); var vertexStream = meshInterface.GetVertexStream(); var indexReader = new BinaryReader(indexStream); var vertexReader = new BinaryReader(vertexStream); int numVertices = (int)indexStream.Length / 4; const int vertexStride = 12; Vector3[] vertices = new Vector3[numVertices * 2]; int v = 0; while (indexStream.Position < indexStream.Length) { uint i = indexReader.ReadUInt32(); vertexStream.Position = vertexStride * i; Vector3 v0 = new Vector3(vertexReader.ReadSingle(), vertexReader.ReadSingle(), vertexReader.ReadSingle()); i = indexReader.ReadUInt32(); vertexStream.Position = vertexStride * i; Vector3 v1 = new Vector3(vertexReader.ReadSingle(), vertexReader.ReadSingle(), vertexReader.ReadSingle()); i = indexReader.ReadUInt32(); vertexStream.Position = vertexStride * i; Vector3 v2 = new Vector3(vertexReader.ReadSingle(), vertexReader.ReadSingle(), vertexReader.ReadSingle()); 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; } indexStream.Dispose(); vertexStream.Dispose(); return(vertices); }
static Vector3[] CreateTriangleMesh(TriangleMeshShape shape) { StridingMeshInterface meshInterface = shape.MeshInterface; BulletSharp.DataStream vertexBuffer, indexBuffer; int numVerts, numFaces; PhyScalarType vertsType, indicesType; int vertexStride, indexStride; meshInterface.GetLockedReadOnlyVertexIndexData(out vertexBuffer, out numVerts, out vertsType, out vertexStride, out indexBuffer, out indexStride, out numFaces, out indicesType); Vector3[] vertices = new Vector3[numFaces * 3 * 2]; // Need to un-index the vertex buffer to make the normals right. int v = 0; while (indexBuffer.Position < indexBuffer.Length) { uint i = indexBuffer.Read <uint>(); vertexBuffer.Position = vertexStride * i; Vector3 v0 = vertexBuffer.Read <Vector3>(); i = indexBuffer.Read <uint>(); vertexBuffer.Position = vertexStride * i; Vector3 v1 = vertexBuffer.Read <Vector3>(); i = indexBuffer.Read <uint>(); vertexBuffer.Position = vertexStride * i; Vector3 v2 = vertexBuffer.Read <Vector3>(); 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; } return(vertices); }
/// <summary> /// Turns a BXDA mesh into a CompoundShape centered around the origin /// </summary> /// <param name="mesh"></param> /// <returns></returns> private static CompoundShape GetShape(BXDAMesh mesh) { CompoundShape shape = new CompoundShape(); Vector3[] meshVertices = mesh.AllColliderVertices().ToArray(); for (int i = 0; i < mesh.colliders.Count; i++) { BXDAMesh.BXDASubMesh sub = mesh.colliders[i]; Vector3[] vertices = sub.GetVertexData(); StridingMeshInterface sMesh = MeshUtilities.CenteredBulletShapeFromSubMesh(sub); //Add the shape at a location relative to the compound shape such that the compound shape is centered at (0, 0) but child shapes are properly placed shape.AddChildShape(Matrix4.CreateTranslation(MeshUtilities.MeshCenterRelative(sub, mesh)), new ConvexTriangleMeshShape(sMesh)); Console.WriteLine("Successfully created and added sub shape"); } return(shape); }
public static void CreateTriangleMeshShape(StridingMeshInterface meshInterface, Mesh m) { // StridingMeshInterface can only be TriangleIndexVertexArray var meshes = (meshInterface as TriangleIndexVertexArray).IndexedMeshArray; int numTriangles = 0; foreach (var mesh in meshes) { numTriangles += mesh.NumTriangles; } int numVertices = numTriangles * 3; UnityEngine.Vector3[] vertices = new UnityEngine.Vector3[numVertices * 2]; int v = 0; List <int> triangles = new List <int>(); for (int part = 0; part < meshInterface.NumSubParts; part++) { var mesh = meshes[part]; var indexStream = mesh.GetTriangleStream(); var vertexStream = mesh.GetVertexStream(); var indexReader = new BinaryReader(indexStream); var vertexReader = new BinaryReader(vertexStream); int vertexStride = mesh.VertexStride; int triangleStrideDelta = mesh.TriangleIndexStride - 3 * sizeof(int); while (indexStream.Position < indexStream.Length) { uint i = indexReader.ReadUInt32(); vertexStream.Position = vertexStride * i; float f1 = vertexReader.ReadSingle(); float f2 = vertexReader.ReadSingle(); float f3 = vertexReader.ReadSingle(); UnityEngine.Vector3 v0 = new UnityEngine.Vector3(f1, f2, f3); i = indexReader.ReadUInt32(); vertexStream.Position = vertexStride * i; f1 = vertexReader.ReadSingle(); f2 = vertexReader.ReadSingle(); f3 = vertexReader.ReadSingle(); UnityEngine.Vector3 v1 = new UnityEngine.Vector3(f1, f2, f3); i = indexReader.ReadUInt32(); vertexStream.Position = vertexStride * i; f1 = vertexReader.ReadSingle(); f2 = vertexReader.ReadSingle(); f3 = vertexReader.ReadSingle(); UnityEngine.Vector3 v2 = new UnityEngine.Vector3(f1, f2, f3); UnityEngine.Vector3 v01 = v0 - v1; UnityEngine.Vector3 v02 = v0 - v2; UnityEngine.Vector3 normal = UnityEngine.Vector3.Cross(v01, v02); normal.Normalize(); triangles.Add(v); triangles.Add(v + 1); triangles.Add(v + 2); vertices[v++] = v0; vertices[v++] = v1; vertices[v++] = v2; indexStream.Position += triangleStrideDelta; } indexStream.Dispose(); vertexStream.Dispose(); } m.Clear(); m.vertices = vertices; m.triangles = triangles.ToArray(); m.RecalculateBounds(); m.RecalculateNormals(); }
public btBvhTriangleMeshShape_handlemesh(StridingMeshInterface meshInterface) : base(meshInterface, true, true) { minterface = meshInterface; }
/* * 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); }
///////////////////////////////////////////////////////// ///////////////////////////////////////////////////////// public static void GenerateInternalEdgeInfo(BvhTriangleMeshShape trimeshShape, TriangleInfoMap triangleInfoMap) { //the user pointer shouldn't already be used for other purposes, we intend to store connectivity info there! if (trimeshShape.GetTriangleInfoMap() != null) { return; } trimeshShape.SetTriangleInfoMap(triangleInfoMap); StridingMeshInterface meshInterface = trimeshShape.GetMeshInterface(); IndexedVector3 meshScaling = meshInterface.GetScaling(); for (int partId = 0; partId < meshInterface.GetNumSubParts(); partId++) { object vertexbase = null; int numverts = 0; PHY_ScalarType type = PHY_ScalarType.PHY_INTEGER; int stride = 0; object indexbase = null; int indexstride = 0; int numfaces = 0; PHY_ScalarType indicestype = PHY_ScalarType.PHY_INTEGER; //PHY_ScalarType indexType=0; IndexedVector3[] triangleVerts = new IndexedVector3[3]; meshInterface.GetLockedReadOnlyVertexIndexBase(out vertexbase, out numverts, out type, out stride, out indexbase, out indexstride, out numfaces, out indicestype, partId); IndexedVector3 aabbMin, aabbMax; switch (indicestype) { case PHY_ScalarType.PHY_INTEGER: { int[] indexList = ((ObjectArray <int>)indexbase).GetRawArray(); if (vertexbase is ObjectArray <IndexedVector3> ) { IndexedVector3[] vertexList = (vertexbase as ObjectArray <IndexedVector3>).GetRawArray(); int indexCounter = 0; for (int triangleIndex = 0; triangleIndex < numfaces; triangleIndex++) { int index1 = indexList[triangleIndex]; int index2 = indexList[triangleIndex + 1]; int index3 = indexList[triangleIndex + 2]; triangleVerts[0] = new IndexedVector3(vertexList[index1]) * meshScaling; triangleVerts[1] = new IndexedVector3(vertexList[index2]) * meshScaling; triangleVerts[2] = new IndexedVector3(vertexList[index3]) * meshScaling; ProcessResult(triangleVerts, out aabbMin, out aabbMax, trimeshShape, partId, triangleIndex, triangleInfoMap); } } #if XNA else if (vertexbase is ObjectArray <Microsoft.Xna.Framework.Vector3> ) { Microsoft.Xna.Framework.Vector3[] vertexList = (vertexbase as ObjectArray <Microsoft.Xna.Framework.Vector3>).GetRawArray(); int indexCounter = 0; for (int triangleIndex = 0; triangleIndex < numfaces; triangleIndex++) { int index1 = indexList[triangleIndex]; int index2 = indexList[triangleIndex + 1]; int index3 = indexList[triangleIndex + 2]; triangleVerts[0] = new IndexedVector3(vertexList[index1]) * meshScaling; triangleVerts[1] = new IndexedVector3(vertexList[index2]) * meshScaling; triangleVerts[2] = new IndexedVector3(vertexList[index3]) * meshScaling; ProcessResult(triangleVerts, out aabbMin, out aabbMax, trimeshShape, partId, triangleIndex, triangleInfoMap); } } #endif else if (vertexbase is ObjectArray <float> ) { float[] vertexList = (vertexbase as ObjectArray <float>).GetRawArray(); for (int triangleIndex = 0; triangleIndex < numfaces; triangleIndex++) { triangleVerts[0] = new IndexedVector3(vertexList[indexList[triangleIndex]], vertexList[indexList[triangleIndex] + 1], vertexList[indexList[triangleIndex] + 2]) * meshScaling; triangleVerts[1] = new IndexedVector3(vertexList[indexList[triangleIndex + 1]], vertexList[indexList[triangleIndex + 1] + 1], vertexList[indexList[triangleIndex + 1] + 2]) * meshScaling; triangleVerts[2] = new IndexedVector3(vertexList[indexList[triangleIndex + 2]], vertexList[indexList[triangleIndex + 2] + 1], vertexList[indexList[triangleIndex + 2] + 2]) * meshScaling; ProcessResult(triangleVerts, out aabbMin, out aabbMax, trimeshShape, partId, triangleIndex, triangleInfoMap); } } break; } default: { Debug.Assert(indicestype == PHY_ScalarType.PHY_INTEGER); break; } } } }
private void CreateMesh(string filePath) { Bodies = new List <RigidBody>(); VisualMeshes = new List <Mesh>(); BXDAMesh mesh = new BXDAMesh(); mesh.ReadFromFile(filePath); foreach (FieldNode node in NodeGroup.EnumerateAllLeafFieldNodes()) { if (!GetPropertySets().ContainsKey(node.PropertySetID)) { return; } PropertySet current = GetPropertySets()[node.PropertySetID]; CollisionShape subShape = null; switch (current.Collider.CollisionType) { case PropertySet.PropertySetCollider.PropertySetCollisionType.BOX: { //Create a box shape //This is a mess, though I was told that this is how it works Vector3[] vertices = MeshUtilities.DataToVector(mesh.meshes[node.SubMeshID].verts); StridingMeshInterface temp = MeshUtilities.BulletShapeFromSubMesh(mesh.meshes[node.SubMeshID]); Vector3 min, max; temp.CalculateAabbBruteForce(out min, out max); PropertySet.BoxCollider colliderInfo = (PropertySet.BoxCollider)current.Collider; subShape = new BoxShape((max - min) * colliderInfo.Scale.Convert() * 0.5f); if (debug) { Console.WriteLine("Created Box"); } break; } case PropertySet.PropertySetCollider.PropertySetCollisionType.SPHERE: { //Create a sphere shape PropertySet.SphereCollider colliderInfo = (PropertySet.SphereCollider)current.Collider; subShape = new SphereShape(colliderInfo.Scale); if (debug) { Console.WriteLine("Created Sphere"); } break; } case PropertySet.PropertySetCollider.PropertySetCollisionType.MESH: { //Create a mesh shape if (node.CollisionMeshID == -1) { break; } PropertySet.MeshCollider colliderInfo = (PropertySet.MeshCollider)current.Collider; Vector3[] vertices = MeshUtilities.DataToVector(mesh.colliders[node.CollisionMeshID].verts); if (colliderInfo.Convex) { subShape = new ConvexHullShape(vertices); if (debug) { Console.WriteLine("Created Convex Mesh"); } } else { StridingMeshInterface sMesh = MeshUtilities.BulletShapeFromSubMesh(mesh.colliders[node.CollisionMeshID]); subShape = new ConvexTriangleMeshShape(sMesh, true); //still not really concave if (debug) { Console.WriteLine("Created Concave Mesh"); } } break; } } if (null == subShape) { return; } //set sub shape local position/rotation and add it to the compound shape Vector3 Translation = node.Position.Convert(); Quaternion rotation = node.Rotation.Convert(); DefaultMotionState motion = new DefaultMotionState(Matrix4.CreateFromQuaternion(rotation) * Matrix4.CreateTranslation(Translation)); motion.CenterOfMassOffset = Matrix4.CreateTranslation(mesh.physics.centerOfMass.Convert()); RigidBodyConstructionInfo info = new RigidBodyConstructionInfo(current.Mass, motion, subShape, subShape.CalculateLocalInertia(current.Mass)); info.Friction = current.Friction; Bodies.Add(new RigidBody(info)); VisualMeshes.Add(new Mesh(mesh.meshes[node.SubMeshID], Translation)); if (debug) { Console.WriteLine("Created " + node.PropertySetID); } } }
private static Vector3[] CreateTriangleMesh(StridingMeshInterface meshInterface) { // StridingMeshInterface can only be TriangleIndexVertexArray var meshes = (meshInterface as TriangleIndexVertexArray).IndexedMeshArray; int numTriangles = 0; foreach (var mesh in meshes) { numTriangles += mesh.NumTriangles; } int numVertices = numTriangles * 3; Vector3[] vertices = new Vector3[numVertices * 2]; int v = 0; for (int part = 0; part < meshInterface.NumSubParts; part++) { var mesh = meshes[part]; var indexStream = mesh.GetTriangleStream(); var vertexStream = mesh.GetVertexStream(); var indexReader = new BinaryReader(indexStream); var vertexReader = new BinaryReader(vertexStream); int vertexStride = mesh.VertexStride; int triangleStrideDelta = mesh.TriangleIndexStride - 3 * sizeof(int); PhyScalarType vertexType = mesh.VertexType; while (indexStream.Position < indexStream.Length) { uint i = indexReader.ReadUInt32(); vertexStream.Position = vertexStride * i; float f1 = ReadFloat(vertexReader, vertexType); float f2 = ReadFloat(vertexReader, vertexType); float f3 = ReadFloat(vertexReader, vertexType); Vector3 v0 = new Vector3(f1, f2, f3); i = indexReader.ReadUInt32(); vertexStream.Position = vertexStride * i; f1 = vertexReader.ReadSingle(); f2 = vertexReader.ReadSingle(); f3 = vertexReader.ReadSingle(); Vector3 v1 = new Vector3(f1, f2, f3); i = indexReader.ReadUInt32(); vertexStream.Position = vertexStride * i; f1 = ReadFloat(vertexReader, vertexType); f2 = ReadFloat(vertexReader, vertexType); f3 = ReadFloat(vertexReader, vertexType); Vector3 v2 = new Vector3(f1, f2, f3); Vector3 v01 = v0 - v1; Vector3 v02 = v0 - v2; Vector3 normal = Vector3.Cross(v01, v02); normal.Normalize(); var scaling = meshInterface.Scaling; vertices[v++] = v0 * scaling; vertices[v++] = normal * scaling; vertices[v++] = v1 * scaling; vertices[v++] = normal * scaling; vertices[v++] = v2 * scaling; vertices[v++] = normal * scaling; indexStream.Position += triangleStrideDelta; } indexStream.Dispose(); vertexStream.Dispose(); } return(vertices); }