public ConvexDecompositionDemoSimulation(bool enableSat) { _enableSat = enableSat; CollisionConfiguration = new DefaultCollisionConfiguration(); Dispatcher = new CollisionDispatcher(CollisionConfiguration); Broadphase = new AxisSweep3(new Vector3(-10000, -10000, -10000), new Vector3(10000, 10000, 10000)); World = new DiscreteDynamicsWorld(Dispatcher, Broadphase, null, CollisionConfiguration); CreateGround(); ManifoldPoint.ContactAdded += MyContactCallback; //CompoundCollisionAlgorithm.CompoundChildShapePairCallback = MyCompoundChildShapeCallback; string path = Path.Combine("data", "file.obj"); var wavefrontModel = WavefrontObj.Load(path); if (wavefrontModel.Indices.Count == 0) { return; } var localScaling = new Vector3(6, 6, 6); _triangleMesh = CreateTriangleMesh(wavefrontModel.Indices, wavefrontModel.Vertices, localScaling); // Convex hull approximation ConvexHullShape convexShape = CreateHullApproximation(_triangleMesh); float mass = 1.0f; PhysicsHelper.CreateBody(mass, Matrix.Translation(0, 2, 14), convexShape, World); // Non-moving body var objectOffset = new Vector3(10, 0, 0); const bool useQuantization = true; var concaveShape = new BvhTriangleMeshShape(_triangleMesh, useQuantization); PhysicsHelper.CreateStaticBody(Matrix.Translation(objectOffset), concaveShape, World); Hacd hacd = ComputeHacd(wavefrontModel); hacd.Save("output.wrl", false); var compoundShape = CreateCompoundShape(hacd, localScaling); mass = 10.0f; objectOffset = new Vector3(-10, 0, -6); var body2 = PhysicsHelper.CreateBody(mass, Matrix.Translation(objectOffset), compoundShape, World); body2.CollisionFlags |= CollisionFlags.CustomMaterialCallback; objectOffset.Z += 6; body2 = PhysicsHelper.CreateBody(mass, Matrix.Translation(objectOffset), compoundShape, World); body2.CollisionFlags |= CollisionFlags.CustomMaterialCallback; objectOffset.Z += 6; body2 = PhysicsHelper.CreateBody(mass, Matrix.Translation(objectOffset), compoundShape, World); body2.CollisionFlags |= CollisionFlags.CustomMaterialCallback; }
protected override void OnInitializePhysics() { ManifoldPoint.ContactAdded += MyContactCallback; SetupEmptyDynamicsWorld(); //CompoundCollisionAlgorithm.CompoundChildShapePairCallback = MyCompoundChildShapeCallback; string path = Path.Combine("data", "file.obj"); var wavefrontModel = WavefrontObj.Load(path); if (wavefrontModel.Indices.Count == 0) { return; } var localScaling = new Vector3(6, 6, 6); _triangleMesh = CreateTriangleMesh(wavefrontModel.Indices, wavefrontModel.Vertices, localScaling); // Convex hull approximation ConvexHullShape convexShape = CreateHullApproximation(_triangleMesh); float mass = 1.0f; LocalCreateRigidBody(mass, Matrix.Translation(0, 2, 14), convexShape); // Non-moving body var objectOffset = new Vector3(10, 0, 0); const bool useQuantization = true; var concaveShape = new BvhTriangleMeshShape(_triangleMesh, useQuantization); LocalCreateRigidBody(0, Matrix.Translation(objectOffset), concaveShape); Hacd hacd = ComputeHacd(wavefrontModel); hacd.Save("output.wrl", false); var compoundShape = CreateCompoundShape(hacd, localScaling); mass = 10.0f; objectOffset = new Vector3(-10, 0, -6); var body2 = LocalCreateRigidBody(mass, Matrix.Translation(objectOffset), compoundShape); body2.CollisionFlags |= CollisionFlags.CustomMaterialCallback; objectOffset.Z += 6; body2 = LocalCreateRigidBody(mass, Matrix.Translation(objectOffset), compoundShape); body2.CollisionFlags |= CollisionFlags.CustomMaterialCallback; objectOffset.Z += 6; body2 = LocalCreateRigidBody(mass, Matrix.Translation(objectOffset), compoundShape); body2.CollisionFlags |= CollisionFlags.CustomMaterialCallback; }
protected override void OnInitializePhysics() { ManifoldPoint.ContactAdded += MyContactCallback; SetupEmptyDynamicsWorld(); CreateGround(); //CompoundCollisionAlgorithm.CompoundChildShapePairCallback = MyCompoundChildShapeCallback; var wo = WavefrontObj.Load("data/file.obj"); if (wo.Indices.Count == 0) { return; } var localScaling = new Vector3(6, 6, 6); triangleMesh = CreateTriangleMesh(wo.Indices, wo.Vertices, localScaling); // Convex hull approximation ConvexHullShape convexShape = CreateHullApproximation(triangleMesh); CollisionShapes.Add(convexShape); float mass = 1.0f; LocalCreateRigidBody(mass, Matrix.Translation(0, 2, 14), convexShape); // Non-moving body Vector3 convexDecompositionObjectOffset = new Vector3(10, 0, 0); const bool useQuantization = true; var concaveShape = new BvhTriangleMeshShape(triangleMesh, useQuantization); CollisionShapes.Add(concaveShape); LocalCreateRigidBody(0, Matrix.Translation(convexDecompositionObjectOffset), concaveShape); var hacd = new Hacd() { VerticesPerConvexHull = 100, CompacityWeight = 0.1, VolumeWeight = 0, // Recommended HACD parameters NClusters = 2, Concavity = 100, AddExtraDistPoints = false, AddFacesPoints = false, AddNeighboursDistPoints = false }; hacd.SetPoints(wo.Vertices); hacd.SetTriangles(wo.Indices); hacd.Compute(); hacd.Save("output.wrl", false); // Generate convex result var outputFile = new FileStream("file_convex.obj", FileMode.Create, FileAccess.Write); var writer = new StreamWriter(outputFile); var convexDecomposition = new ConvexDecomposition(writer) { LocalScaling = localScaling }; for (int c = 0; c < hacd.NClusters; c++) { int nVertices = hacd.GetNPointsCH(c); int trianglesLen = hacd.GetNTrianglesCH(c) * 3; double[] points = new double[nVertices * 3]; long[] triangles = new long[trianglesLen]; hacd.GetCH(c, points, triangles); if (trianglesLen == 0) { continue; } Vector3[] verticesArray = new Vector3[nVertices]; int vi3 = 0; for (int vi = 0; vi < nVertices; vi++) { verticesArray[vi] = new Vector3( (float)points[vi3], (float)points[vi3 + 1], (float)points[vi3 + 2]); vi3 += 3; } int[] trianglesInt = new int[trianglesLen]; for (int ti = 0; ti < trianglesLen; ti++) { trianglesInt[ti] = (int)triangles[ti]; } convexDecomposition.Result(verticesArray, trianglesInt); } writer.Dispose(); outputFile.Dispose(); // Combine convex shapes into a compound shape var compound = new CompoundShape(); for (int i = 0; i < convexDecomposition.convexShapes.Count; i++) { Vector3 centroid = convexDecomposition.convexCentroids[i]; var convexShape2 = convexDecomposition.convexShapes[i]; Matrix trans = Matrix.Translation(centroid); if (enableSat) { convexShape2.InitializePolyhedralFeatures(); } CollisionShapes.Add(convexShape2); compound.AddChildShape(trans, convexShape2); LocalCreateRigidBody(1.0f, trans, convexShape2); } CollisionShapes.Add(compound); #if true mass = 10.0f; var body2 = LocalCreateRigidBody(mass, Matrix.Translation(-convexDecompositionObjectOffset), compound); body2.CollisionFlags |= CollisionFlags.CustomMaterialCallback; convexDecompositionObjectOffset.Z = 6; body2 = LocalCreateRigidBody(mass, Matrix.Translation(-convexDecompositionObjectOffset), compound); body2.CollisionFlags |= CollisionFlags.CustomMaterialCallback; convexDecompositionObjectOffset.Z = -6; body2 = LocalCreateRigidBody(mass, Matrix.Translation(-convexDecompositionObjectOffset), compound); body2.CollisionFlags |= CollisionFlags.CustomMaterialCallback; #endif }