Beispiel #1
0
 public unsafe static void AddPoint(this ConvexHullShape obj, ref OpenTK.Vector3 point, bool recalculateLocalAabb)
 {
     fixed(OpenTK.Vector3 *pointPtr = &point)
     {
         obj.AddPoint(ref *(BulletSharp.Math.Vector3 *)pointPtr, recalculateLocalAabb);
     }
 }
Beispiel #2
0
 public unsafe static void AddPoint(this ConvexHullShape obj, ref OpenTK.Vector3 point)
 {
     fixed(OpenTK.Vector3 *pointPtr = &point)
     {
         obj.AddPoint(ref *(BulletSharp.Math.Vector3 *)pointPtr);
     }
 }
        protected override void OnInitializePhysics()
        {
            ManifoldPoint.ContactAdded += MyContactCallback;

            SetupEmptyDynamicsWorld();

            WavefrontObj wo = new WavefrontObj();
            int tcount = wo.LoadObj("data/file.obj");
            if (tcount > 0)
            {
                TriangleMesh trimesh = new TriangleMesh();
                trimeshes.Add(trimesh);

                Vector3 localScaling = new Vector3(6, 6, 6);
                List<int> indices = wo.Indices;
                List<Vector3> vertices = wo.Vertices;

                int i;
                for (i = 0; i < tcount; i++)
                {
                    int index0 = indices[i * 3];
                    int index1 = indices[i * 3 + 1];
                    int index2 = indices[i * 3 + 2];

                    Vector3 vertex0 = vertices[index0] * localScaling;
                    Vector3 vertex1 = vertices[index1] * localScaling;
                    Vector3 vertex2 = vertices[index2] * localScaling;

                    trimesh.AddTriangle(vertex0, vertex1, vertex2);
                }

                ConvexShape tmpConvexShape = new ConvexTriangleMeshShape(trimesh);

                //create a hull approximation
                ShapeHull hull = new ShapeHull(tmpConvexShape);
                float margin = tmpConvexShape.Margin;
                hull.BuildHull(margin);
                tmpConvexShape.UserObject = hull;

                ConvexHullShape convexShape = new ConvexHullShape();
                foreach (Vector3 v in hull.Vertices)
                {
                    convexShape.AddPoint(v);
                }

                if (sEnableSAT)
                {
                    convexShape.InitializePolyhedralFeatures();
                }
                tmpConvexShape.Dispose();
                //hull.Dispose();

                CollisionShapes.Add(convexShape);

                float mass = 1.0f;

                LocalCreateRigidBody(mass, Matrix.Translation(0, 2, 14), convexShape);

                const bool useQuantization = true;
                CollisionShape concaveShape = new BvhTriangleMeshShape(trimesh, useQuantization);
                LocalCreateRigidBody(0, Matrix.Translation(convexDecompositionObjectOffset), concaveShape);

                CollisionShapes.Add(concaveShape);

                // Bullet Convex Decomposition

                FileStream outputFile = new FileStream("file_convex.obj", FileMode.Create, FileAccess.Write);
                StreamWriter writer = new StreamWriter(outputFile);

                DecompDesc desc = new DecompDesc
                {
                    mVertices = wo.Vertices.ToArray(),
                    mTcount = tcount,
                    mIndices = wo.Indices.ToArray(),
                    mDepth = 5,
                    mCpercent = 5,
                    mPpercent = 15,
                    mMaxVertices = 16,
                    mSkinWidth = 0.0f
                };

                MyConvexDecomposition convexDecomposition = new MyConvexDecomposition(writer, this);
                desc.mCallback = convexDecomposition;

                // HACD

                Hacd myHACD = new Hacd();
                myHACD.SetPoints(wo.Vertices);
                myHACD.SetTriangles(wo.Indices);
                myHACD.CompacityWeight = 0.1;
                myHACD.VolumeWeight = 0.0;

                // HACD parameters
                // Recommended parameters: 2 100 0 0 0 0
                int nClusters = 2;
                const double concavity = 100;
                //bool invert = false;
                const bool addExtraDistPoints = false;
                const bool addNeighboursDistPoints = false;
                const bool addFacesPoints = false;

                myHACD.NClusters = nClusters;                     // minimum number of clusters
                myHACD.VerticesPerConvexHull = 100;               // max of 100 vertices per convex-hull
                myHACD.Concavity = concavity;                     // maximum concavity
                myHACD.AddExtraDistPoints = addExtraDistPoints;
                myHACD.AddNeighboursDistPoints = addNeighboursDistPoints;
                myHACD.AddFacesPoints = addFacesPoints;

                myHACD.Compute();
                nClusters = myHACD.NClusters;

                myHACD.Save("output.wrl", false);

                if (true)
                {
                    CompoundShape compound = new CompoundShape();
                    CollisionShapes.Add(compound);

                    Matrix trans = Matrix.Identity;

                    for (int c = 0; c < nClusters; c++)
                    {
                        //generate convex result
                        Vector3[] points;
                        int[] triangles;
                        myHACD.GetCH(c, out points, out triangles);

                        ConvexResult r = new ConvexResult(points, triangles);
                        convexDecomposition.ConvexDecompResult(r);
                    }

                    for (i = 0; i < convexDecomposition.convexShapes.Count; i++)
                    {
                        Vector3 centroid = convexDecomposition.convexCentroids[i];
                        trans = Matrix.Translation(centroid);
                        ConvexHullShape convexShape2 = convexDecomposition.convexShapes[i] as ConvexHullShape;
                        compound.AddChildShape(trans, convexShape2);

                        RigidBody body = LocalCreateRigidBody(1.0f, trans, convexShape2);
                    }

            #if true
                    mass = 10.0f;
                    trans = Matrix.Translation(-convexDecompositionObjectOffset);
                    RigidBody body2 = LocalCreateRigidBody(mass, trans, compound);
                    body2.CollisionFlags |= CollisionFlags.CustomMaterialCallback;

                    convexDecompositionObjectOffset.Z = 6;
                    trans = Matrix.Translation(-convexDecompositionObjectOffset);
                    body2 = LocalCreateRigidBody(mass, trans, compound);
                    body2.CollisionFlags |= CollisionFlags.CustomMaterialCallback;

                    convexDecompositionObjectOffset.Z = -6;
                    trans = Matrix.Translation(-convexDecompositionObjectOffset);
                    body2 = LocalCreateRigidBody(mass, trans, compound);
                    body2.CollisionFlags |= CollisionFlags.CustomMaterialCallback;
            #endif
                }

                writer.Dispose();
                outputFile.Dispose();
            }
        }
        protected override void OnInitializePhysics()
        {
            // collision configuration contains default setup for memory, collision setup
            DefaultCollisionConstructionInfo cci = new DefaultCollisionConstructionInfo();
            cci.DefaultMaxPersistentManifoldPoolSize = 32768;
            CollisionConf = new DefaultCollisionConfiguration(cci);

            Dispatcher = new CollisionDispatcher(CollisionConf);
            Dispatcher.DispatcherFlags = DispatcherFlags.DisableContactPoolDynamicAllocation;

            // the maximum size of the collision world. Make sure objects stay within these boundaries
            // Don't make the world AABB size too large, it will harm simulation quality and performance
            Vector3 worldAabbMin = new Vector3(-1000, -1000, -1000);
            Vector3 worldAabbMax = new Vector3(1000, 1000, 1000);

            HashedOverlappingPairCache pairCache = new HashedOverlappingPairCache();
            Broadphase = new AxisSweep3(worldAabbMin, worldAabbMax, 3500, pairCache);
            //Broadphase = new DbvtBroadphase();

            Solver = new SequentialImpulseConstraintSolver();

            World = new DiscreteDynamicsWorld(Dispatcher, Broadphase, Solver, CollisionConf);
            World.Gravity = new Vector3(0, -10, 0);
            World.SolverInfo.SolverMode |= SolverModes.EnableFrictionDirectionCaching;
            World.SolverInfo.NumIterations = 5;

            if (benchmark < 5)
            {
                // create the ground
                CollisionShape groundShape = new BoxShape(250, 50, 250);
                CollisionShapes.Add(groundShape);
                CollisionObject ground = base.LocalCreateRigidBody(0, Matrix.Translation(0, -50, 0), groundShape);
                ground.UserObject = "Ground";
            }

            float cubeSize = 1.0f;
            float spacing = cubeSize;
            float mass = 1.0f;
            int size = 8;
            Vector3 pos = new Vector3(0.0f, cubeSize * 2, 0.0f);
            float offset = -size * (cubeSize * 2.0f + spacing) * 0.5f;

            switch (benchmark)
            {
                case 1:
                    // 3000

                    BoxShape blockShape = new BoxShape(cubeSize - collisionRadius);
                    mass = 2.0f;

                    for (int k = 0; k < 47; k++)
                    {
                        for (int j = 0; j < size; j++)
                        {
                            pos[2] = offset + (float)j * (cubeSize * 2.0f + spacing);
                            for (int i = 0; i < size; i++)
                            {
                                pos[0] = offset + (float)i * (cubeSize * 2.0f + spacing);
                                RigidBody cmbody = LocalCreateRigidBody(mass, Matrix.Translation(pos), blockShape);
                            }
                        }
                        offset -= 0.05f * spacing * (size - 1);
                        // spacing *= 1.01f;
                        pos[1] += (cubeSize * 2.0f + spacing);
                    }
                    break;

                case 2:
                    CreatePyramid(new Vector3(-20, 0, 0), 12, new Vector3(cubeSize));
                    CreateWall(new Vector3(-2.0f, 0.0f, 0.0f), 12, new Vector3(cubeSize));
                    CreateWall(new Vector3(4.0f, 0.0f, 0.0f), 12, new Vector3(cubeSize));
                    CreateWall(new Vector3(10.0f, 0.0f, 0.0f), 12, new Vector3(cubeSize));
                    CreateTowerCircle(new Vector3(25.0f, 0.0f, 0.0f), 8, 24, new Vector3(cubeSize));
                    break;

                case 3:
                    // TODO: Ragdolls
                    break;

                case 4:
                    cubeSize = 1.5f;

                    ConvexHullShape convexHullShape = new ConvexHullShape();

                    float scaling = 1;

                    convexHullShape.LocalScaling = new Vector3(scaling);

                    for (int i = 0; i < Taru.Vtx.Length / 3; i++)
                    {
                        Vector3 vtx = new Vector3(Taru.Vtx[i * 3], Taru.Vtx[i * 3 + 1], Taru.Vtx[i * 3 + 2]);
                        convexHullShape.AddPoint(vtx * (1.0f / scaling));
                    }

                    //this will enable polyhedral contact clipping, better quality, slightly slower
                    convexHullShape.InitializePolyhedralFeatures();

                    for (int k = 0; k < 15; k++)
                    {
                        for (int j = 0; j < size; j++)
                        {
                            pos[2] = offset + (float)j * (cubeSize * 2.0f + spacing);
                            for (int i = 0; i < size; i++)
                            {
                                pos[0] = offset + (float)i * (cubeSize * 2.0f + spacing);
                                LocalCreateRigidBody(mass, Matrix.Translation(pos), convexHullShape);
                            }
                        }
                        offset -= 0.05f * spacing * (size - 1);
                        spacing *= 1.01f;
                        pos[1] += (cubeSize * 2.0f + spacing);
                    }
                    break;

                case 5:
                    Vector3 boxSize = new Vector3(1.5f);
                    float boxMass = 1.0f;
                    float sphereRadius = 1.5f;
                    float sphereMass = 1.0f;
                    float capsuleHalf = 2.0f;
                    float capsuleRadius = 1.0f;
                    float capsuleMass = 1.0f;

                    size = 10;
                    int height = 10;

                    cubeSize = boxSize[0];
                    spacing = 2.0f;
                    pos = new Vector3(0.0f, 20.0f, 0.0f);
                    offset = -size * (cubeSize * 2.0f + spacing) * 0.5f;

                    int numBodies = 0;

                    Random random = new Random();

                    for (int k = 0; k < height; k++)
                    {
                        for (int j = 0; j < size; j++)
                        {
                            pos[2] = offset + (float)j * (cubeSize * 2.0f + spacing);
                            for (int i = 0; i < size; i++)
                            {
                                pos[0] = offset + (float)i * (cubeSize * 2.0f + spacing);
                                Vector3 bpos = new Vector3(0, 25, 0) + new Vector3(5.0f * pos.X, pos.Y, 5.0f * pos.Z);
                                int idx = random.Next(10);
                                Matrix trans = Matrix.Translation(bpos);

                                switch (idx)
                                {
                                    case 0:
                                    case 1:
                                    case 2:
                                        {
                                            float r = 0.5f * (idx + 1);
                                            BoxShape boxShape = new BoxShape(boxSize * r);
                                            LocalCreateRigidBody(boxMass * r, trans, boxShape);
                                        }
                                        break;

                                    case 3:
                                    case 4:
                                    case 5:
                                        {
                                            float r = 0.5f * (idx - 3 + 1);
                                            SphereShape sphereShape = new SphereShape(sphereRadius * r);
                                            LocalCreateRigidBody(sphereMass * r, trans, sphereShape);
                                        }
                                        break;

                                    case 6:
                                    case 7:
                                    case 8:
                                        {
                                            float r = 0.5f * (idx - 6 + 1);
                                            CapsuleShape capsuleShape = new CapsuleShape(capsuleRadius * r, capsuleHalf * r);
                                            LocalCreateRigidBody(capsuleMass * r, trans, capsuleShape);
                                        }
                                        break;
                                }

                                numBodies++;
                            }
                        }
                        offset -= 0.05f * spacing * (size - 1);
                        spacing *= 1.1f;
                        pos[1] += (cubeSize * 2.0f + spacing);
                    }

                    //CreateLargeMeshBody();

                    break;

                case 6:
                    boxSize = new Vector3(1.5f, 1.5f, 1.5f);

                    convexHullShape = new ConvexHullShape();

                    for (int i = 0; i < Taru.Vtx.Length / 3; i++)
                    {
                        Vector3 vtx = new Vector3(Taru.Vtx[i * 3], Taru.Vtx[i * 3 + 1], Taru.Vtx[i * 3 + 2]);
                        convexHullShape.AddPoint(vtx);
                    }

                    size = 10;
                    height = 10;

                    cubeSize = boxSize[0];
                    spacing = 2.0f;
                    pos = new Vector3(0.0f, 20.0f, 0.0f);
                    offset = -size * (cubeSize * 2.0f + spacing) * 0.5f;

                    for (int k = 0; k < height; k++)
                    {
                        for (int j = 0; j < size; j++)
                        {
                            pos[2] = offset + (float)j * (cubeSize * 2.0f + spacing);
                            for (int i = 0; i < size; i++)
                            {
                                pos[0] = offset + (float)i * (cubeSize * 2.0f + spacing);
                                Vector3 bpos = new Vector3(0, 25, 0) + new Vector3(5.0f * pos.X, pos.Y, 5.0f * pos.Z);

                                LocalCreateRigidBody(mass, Matrix.Translation(bpos), convexHullShape);
                            }
                        }
                        offset -= 0.05f * spacing * (size - 1);
                        spacing *= 1.1f;
                        pos[1] += (cubeSize * 2.0f + spacing);
                    }

                    //CreateLargeMeshBody();

                    break;

                case 7:
                    // TODO
                    //CreateTest6();
                    //InitRays();
                    break;
            }
        }