public void ConvertBsp(BspLoader bspLoader, float scaling) { Vector3 playerStart = new Vector3(0, 0, 100); if (bspLoader.FindVectorByName("info_player_start", ref playerStart) == false) { bspLoader.FindVectorByName("info_player_deathmatch", ref playerStart); } playerStart[2] += 20.0f * scaling; //start a bit higher foreach (BspLeaf leaf in bspLoader.Leaves) { bool isValidBrush = false; for (int b = 0; b < leaf.NumLeafBrushes; b++) { AlignedVector3Array planeEquations = new AlignedVector3Array(); int brushID = bspLoader.LeafBrushes[leaf.FirstLeafBrush + b]; BspBrush brush = bspLoader.Brushes[brushID]; if (brush.ShaderNum != -1) { if ((bspLoader.Shaders[brush.ShaderNum].ContentFlags & ContentFlags.Solid) == ContentFlags.Solid) { brush.ShaderNum = -1; for (int p = 0; p < brush.NumSides; p++) { int sideid = brush.FirstSide + p; BspBrushSide brushside = bspLoader.BrushSides[sideid]; int planeid = brushside.PlaneNum; BspPlane plane = bspLoader.Planes[planeid]; Vector4 planeEq = new Vector4(plane.Normal, scaling * -plane.Distance); planeEquations.Add(planeEq); isValidBrush = true; } if (isValidBrush) { AlignedVector3Array vertices; GeometryUtil.GetVerticesFromPlaneEquations(planeEquations, out vertices); bool isEntity = false; Vector3 entityTarget = Vector3.Zero; AddConvexVerticesCollider(vertices, isEntity, entityTarget); } } } } } foreach (BspEntity entity in bspLoader.Entities) { if (entity.ClassName == "trigger_push") { } } }
public void ConvertBsp(BspLoader bspLoader, float scaling) { Vector3 playerStart = new Vector3(0, 0, 100); if (bspLoader.FindVectorByName("info_player_start", ref playerStart) == false) { bspLoader.FindVectorByName("info_player_deathmatch", ref playerStart); } playerStart[2] += 20.0f * scaling; //start a bit higher foreach (BspLeaf leaf in bspLoader.Leaves) { bool isValidBrush = false; for (int b = 0; b < leaf.NumLeafBrushes; b++) { AlignedVector3Array planeEquations = new AlignedVector3Array(); int brushID = bspLoader.LeafBrushes[leaf.FirstLeafBrush + b]; BspBrush brush = bspLoader.Brushes[brushID]; if (brush.ShaderNum != -1) { if ((bspLoader.Shaders[brush.ShaderNum].ContentFlags & ContentFlags.Solid) == ContentFlags.Solid) { brush.ShaderNum = -1; for (int p = 0; p < brush.NumSides; p++) { int sideid = brush.FirstSide + p; BspBrushSide brushside = bspLoader.BrushSides[sideid]; int planeid = brushside.PlaneNum; BspPlane plane = bspLoader.Planes[planeid]; Vector4 planeEq = new Vector4(plane.Normal, scaling*-plane.Distance); planeEquations.Add(planeEq); isValidBrush = true; } if (isValidBrush) { AlignedVector3Array vertices = new AlignedVector3Array(); GeometryUtil.GetVerticesFromPlaneEquations(planeEquations, vertices); bool isEntity = false; Vector3 entityTarget = Vector3.Zero; AddConvexVerticesCollider(vertices, isEntity, entityTarget); } } } } } foreach (BspEntity entity in bspLoader.Entities) { if (entity.ClassName == "trigger_push") { } } }
public override void ConvexDecompResult(ConvexResult result) { TriangleMesh trimesh = new TriangleMesh(); demo.trimeshes.Add(trimesh); Vector3 localScaling = new Vector3(6.0f, 6.0f, 6.0f); if (output == null) { return; } output.WriteLine("## Hull Piece {0} with {1} vertices and {2} triangles.", mHullCount, result.mHullVertices.Length, result.mHullIndices.Length / 3); output.WriteLine("usemtl Material{0}", mBaseCount); output.WriteLine("o Object{0}", mBaseCount); foreach (Vector3 p in result.mHullVertices) { output.WriteLine(string.Format(floatFormat, "v {0:F9} {1:F9} {2:F9}", p.X, p.Y, p.Z)); } //calc centroid, to shift vertices around center of mass demo.centroid = Vector3.Zero; AlignedVector3Array vertices = new AlignedVector3Array(); if (true) { foreach (Vector3 vertex in result.mHullVertices) { demo.centroid += vertex * localScaling; } } demo.centroid /= (float)result.mHullVertices.Length; if (true) { foreach (Vector3 vertex in result.mHullVertices) { vertices.Add(vertex * localScaling - demo.centroid); } } if (true) { int[] src = result.mHullIndices; for (int i = 0; i < src.Length; i += 3) { int index0 = src[i]; int index1 = src[i + 1]; int index2 = src[i + 2]; Vector3 vertex0 = result.mHullVertices[index0] * localScaling - demo.centroid; Vector3 vertex1 = result.mHullVertices[index1] * localScaling - demo.centroid; Vector3 vertex2 = result.mHullVertices[index2] * localScaling - demo.centroid; trimesh.AddTriangle(vertex0, vertex1, vertex2); index0 += mBaseCount; index1 += mBaseCount; index2 += mBaseCount; output.WriteLine("f {0} {1} {2}", index0 + 1, index1 + 1, index2 + 1); } } //this is a tools issue: due to collision margin, convex objects overlap, compensate for it here: //#define SHRINK_OBJECT_INWARDS 1 #if SHRINK_OBJECT_INWARDS float collisionMargin = 0.01f; btAlignedObjectArray <btVector3> planeEquations; btGeometryUtil::getPlaneEquationsFromVertices(vertices, planeEquations); btAlignedObjectArray <btVector3> shiftedPlaneEquations; for (int p = 0; p < planeEquations.size(); p++) { btVector3 plane = planeEquations[p]; plane[3] += collisionMargin; shiftedPlaneEquations.push_back(plane); } btAlignedObjectArray <btVector3> shiftedVertices; btGeometryUtil::getVerticesFromPlaneEquations(shiftedPlaneEquations, shiftedVertices); btConvexHullShape *convexShape = new btConvexHullShape(&(shiftedVertices[0].getX()), shiftedVertices.size()); #else //SHRINK_OBJECT_INWARDS ConvexHullShape convexShape = new ConvexHullShape(vertices); #endif if (demo.sEnableSAT) { convexShape.InitializePolyhedralFeatures(); } convexShape.Margin = 0.01f; convexShapes.Add(convexShape); convexCentroids.Add(demo.centroid); demo.CollisionShapes.Add(convexShape); mBaseCount += result.mHullVertices.Length; // advance the 'base index' counter. }
public override void ConvexDecompResult(ConvexResult result) { TriangleMesh trimesh = new TriangleMesh(); demo.trimeshes.Add(trimesh); Vector3 localScaling = new Vector3(6.0f, 6.0f, 6.0f); if (output == null) return; output.WriteLine("## Hull Piece {0} with {1} vertices and {2} triangles.", mHullCount, result.mHullVertices.Length, result.mHullIndices.Length / 3); output.WriteLine("usemtl Material{0}", mBaseCount); output.WriteLine("o Object{0}", mBaseCount); foreach (Vector3 p in result.mHullVertices) { output.WriteLine(string.Format(floatFormat, "v {0:F9} {1:F9} {2:F9}", p.X, p.Y, p.Z)); } //calc centroid, to shift vertices around center of mass demo.centroid = Vector3.Zero; AlignedVector3Array vertices = new AlignedVector3Array(); if (true) { foreach (Vector3 vertex in result.mHullVertices) { demo.centroid += vertex * localScaling; } } demo.centroid /= (float)result.mHullVertices.Length; if (true) { foreach (Vector3 vertex in result.mHullVertices) { vertices.Add(vertex * localScaling - demo.centroid); } } if (true) { int[] src = result.mHullIndices; for (int i = 0; i < src.Length; i += 3) { int index0 = src[i]; int index1 = src[i + 1]; int index2 = src[i + 2]; Vector3 vertex0 = result.mHullVertices[index0] * localScaling - demo.centroid; Vector3 vertex1 = result.mHullVertices[index1] * localScaling - demo.centroid; Vector3 vertex2 = result.mHullVertices[index2] * localScaling - demo.centroid; trimesh.AddTriangle(vertex0, vertex1, vertex2); index0 += mBaseCount; index1 += mBaseCount; index2 += mBaseCount; output.WriteLine("f {0} {1} {2}", index0 + 1, index1 + 1, index2 + 1); } } //this is a tools issue: due to collision margin, convex objects overlap, compensate for it here: //#define SHRINK_OBJECT_INWARDS 1 #if SHRINK_OBJECT_INWARDS float collisionMargin = 0.01f; btAlignedObjectArray<btVector3> planeEquations; btGeometryUtil::getPlaneEquationsFromVertices(vertices,planeEquations); btAlignedObjectArray<btVector3> shiftedPlaneEquations; for (int p=0;p<planeEquations.size();p++) { btVector3 plane = planeEquations[p]; plane[3] += collisionMargin; shiftedPlaneEquations.push_back(plane); } btAlignedObjectArray<btVector3> shiftedVertices; btGeometryUtil::getVerticesFromPlaneEquations(shiftedPlaneEquations,shiftedVertices); btConvexHullShape* convexShape = new btConvexHullShape(&(shiftedVertices[0].getX()),shiftedVertices.size()); #else //SHRINK_OBJECT_INWARDS ConvexHullShape convexShape = new ConvexHullShape(vertices); #endif if (demo.sEnableSAT) { convexShape.InitializePolyhedralFeatures(); } convexShape.Margin = 0.01f; convexShapes.Add(convexShape); convexCentroids.Add(demo.centroid); demo.CollisionShapes.Add(convexShape); mBaseCount += result.mHullVertices.Length; // advance the 'base index' counter. }
/// <summary> /// Generates a convex hull collision mesh from the given original mesh. /// </summary> /// <param name="original"></param> /// <returns></returns> public static Mesh GenerateCollisionMesh(Mesh original, Vector3 offset = default(Vector3), float margin = 0f) { if (margin > 0f) { ConvexHullShape tempShape = new ConvexHullShape(Array.ConvertAll(original.vertices, x => x.ToBullet()), original.vertices.Length); tempShape.Margin = 0f; ShapeHull shapeHull = new ShapeHull(tempShape); bool b = shapeHull.BuildHull(0f); AlignedVector3Array initialVertices = new AlignedVector3Array(); for (int i = 0; i < shapeHull.NumVertices; i++) { initialVertices.Add(shapeHull.Vertices[i]); } List <BulletSharp.Math.Vector4> planeEquations = GeometryUtilEx.GetPlaneEquationsFromVertices(initialVertices); List <BulletSharp.Math.Vector4> shiftedPlaneEquations = new List <BulletSharp.Math.Vector4>(); for (int i = 0; i < planeEquations.Count; i++) { BulletSharp.Math.Vector4 plane = planeEquations[i]; plane.W += margin; shiftedPlaneEquations.Add(plane); } List <BulletSharp.Math.Vector3> shiftedVertices = GeometryUtilEx.GetVerticesFromPlaneEquations(shiftedPlaneEquations); Vector3[] finalVertices = new Vector3[shiftedVertices.Count]; Mesh collisionMesh = new Mesh(); for (int i = 0; i < finalVertices.Length; i++) { finalVertices[i] = shiftedVertices[i].ToUnity() - offset; } collisionMesh.vertices = finalVertices; collisionMesh.RecalculateBounds(); return(collisionMesh); } else { ConvexHullShape tempShape = new ConvexHullShape(Array.ConvertAll(original.vertices, x => x.ToBullet()), original.vertices.Length); tempShape.Margin = 0f; ShapeHull shapeHull = new ShapeHull(tempShape); bool b = shapeHull.BuildHull(0f); Mesh collisionMesh = new Mesh(); Vector3[] vertices = new Vector3[shapeHull.NumVertices]; for (int i = 0; i < vertices.Length; i++) { vertices[i] = shapeHull.Vertices[i].ToUnity() - offset; } int[] triangles = new int[shapeHull.NumIndices]; for (int i = 0; i < triangles.Length; i++) { triangles[i] = (int)shapeHull.Indices[i]; } collisionMesh.vertices = vertices; collisionMesh.triangles = triangles; collisionMesh.RecalculateNormals(); collisionMesh.RecalculateBounds(); return(collisionMesh); } }