예제 #1
0
        private static ConvexHullShape CreateTaruShape()
        {
            var shape = new ConvexHullShape();

            for (int i = 0; i < Taru.Vertices.Length / 3; i++)
            {
                Vector3 vertex = new Vector3(
                    Taru.Vertices[i * 3],
                    Taru.Vertices[i * 3 + 1],
                    Taru.Vertices[i * 3 + 2]);
                shape.AddPoint(vertex);
            }
            return(shape);
        }
예제 #2
0
        private static CollisionShape loadConvexHull(Mesh mesh, Vector3 scale)
        {
            TriangleMesh trimesh = new TriangleMesh();

            // Shift vertices in so margin is not visible
            Vector3 shift = Vector3.Normalize(scale) - new Vector3(0.04f);

            for (int i = 0; i < mesh.submeshes[0].vertex_data.Length; i += 3)
            {
                int index0 = (int)mesh.submeshes[0].index_data[i];
                int index1 = (int)mesh.submeshes[0].index_data[i + 1];
                int index2 = (int)mesh.submeshes[0].index_data[i + 2];

                Vector3 vertex0 = new Vector3(mesh.submeshes[0].vertex_data[index0].position.X, mesh.submeshes[0].vertex_data[index0].position.Y, mesh.submeshes[0].vertex_data[index0].position.Z) * (scale);
                //vertex0 *= shift;
                Vector3 vertex1 = new Vector3(mesh.submeshes[0].vertex_data[index1].position.X, mesh.submeshes[0].vertex_data[index1].position.Y, mesh.submeshes[0].vertex_data[index1].position.Z) * (scale);
                //vertex1 *= shift;
                Vector3 vertex2 = new Vector3(mesh.submeshes[0].vertex_data[index2].position.X, mesh.submeshes[0].vertex_data[index2].position.Y, mesh.submeshes[0].vertex_data[index2].position.Z) * (scale);
                //vertex2 *= shift;

                trimesh.AddTriangle(vertex0, vertex1, vertex2);
            }
            ConvexShape tmpShape = new ConvexTriangleMeshShape(trimesh);

            ShapeHull hull   = new ShapeHull(tmpShape);
            float     margin = tmpShape.Margin;

            hull.BuildHull(margin);
            tmpShape.UserObject = hull;

            ConvexHullShape convexShape = new ConvexHullShape();

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

            hull.Dispose();
            tmpShape.Dispose();


            return(convexShape);
        }
예제 #3
0
        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 < 20; 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;
            }
        }
예제 #5
0
        public override void InitializeDemo()
        {
            SetCameraDistance(50);
            int totalTriangles = 2 * (NUM_VERTS_X - 1) * (NUM_VERTS_Y - 1);

            int vertStride  = 1;
            int indexStride = 3;

            BulletGlobals.gContactAddedCallback = new CustomMaterialCombinerCallback();


            gVertices = new ObjectArray <IndexedVector3>(totalVerts);
            gIndices  = new ObjectArray <int>(totalTriangles * 3);

            SetVertexPositions(waveheight, 0.0f);

            gVertices.GetRawArray()[1].Y = 0.1f;


            int index = 0;
            int i, j;

            for (i = 0; i < NUM_VERTS_X - 1; i++)
            {
                for (j = 0; j < NUM_VERTS_Y - 1; j++)
                {
#if SWAP_WINDING
#if SHIFT_INDICES
                    gIndices[index++] = j * NUM_VERTS_X + i;
                    gIndices[index++] = (j + 1) * NUM_VERTS_X + i + 1;
                    gIndices[index++] = j * NUM_VERTS_X + i + 1;

                    gIndices[index++] = j * NUM_VERTS_X + i;
                    gIndices[index++] = (j + 1) * NUM_VERTS_X + i;
                    gIndices[index++] = (j + 1) * NUM_VERTS_X + i + 1;
#else
                    gIndices[index++] = (j + 1) * NUM_VERTS_X + i + 1;
                    gIndices[index++] = j * NUM_VERTS_X + i + 1;
                    gIndices[index++] = j * NUM_VERTS_X + i;

                    gIndices[index++] = (j + 1) * NUM_VERTS_X + i;
                    gIndices[index++] = (j + 1) * NUM_VERTS_X + i + 1;
                    gIndices[index++] = j * NUM_VERTS_X + i;
#endif //SHIFT_INDICES
#else //SWAP_WINDING
#if SHIFT_INDICES
                    gIndices[index++] = (j + 1) * NUM_VERTS_X + i + 1;
                    gIndices[index++] = j * NUM_VERTS_X + i;
                    gIndices[index++] = j * NUM_VERTS_X + i + 1;

#if TEST_INCONSISTENT_WINDING
                    gIndices[index++] = j * NUM_VERTS_X + i;
                    gIndices[index++] = (j + 1) * NUM_VERTS_X + i;
                    gIndices[index++] = (j + 1) * NUM_VERTS_X + i + 1;
#else //TEST_INCONSISTENT_WINDING
                    gIndices[index++] = (j + 1) * NUM_VERTS_X + i;
                    gIndices[index++] = j * NUM_VERTS_X + i;
                    gIndices[index++] = (j + 1) * NUM_VERTS_X + i + 1;
#endif //TEST_INCONSISTENT_WINDING
#else //SHIFT_INDICES
                    gIndices[index++] = j * NUM_VERTS_X + i;
                    gIndices[index++] = j * NUM_VERTS_X + i + 1;
                    gIndices[index++] = (j + 1) * NUM_VERTS_X + i + 1;

                    gIndices[index++] = j * NUM_VERTS_X + i;
                    gIndices[index++] = (j + 1) * NUM_VERTS_X + i + 1;
                    gIndices[index++] = (j + 1) * NUM_VERTS_X + i;
#endif //SHIFT_INDICES
#endif //SWAP_WINDING
                }
            }

            m_indexVertexArrays = new TriangleIndexVertexArray(totalTriangles,
                                                               gIndices,
                                                               indexStride,
                                                               totalVerts, gVertices, vertStride);

            bool useQuantizedAabbCompression = true;

            IndexedVector3 aabbMin           = new IndexedVector3(-1000, -1000, -1000);
            IndexedVector3 aabbMax = new IndexedVector3(1000, 1000, 1000);

            trimeshShape = new BvhTriangleMeshShape(m_indexVertexArrays, useQuantizedAabbCompression, ref aabbMin, ref aabbMax, true);

            CollisionShape groundShape = trimeshShape;

            TriangleInfoMap triangleInfoMap = new TriangleInfoMap();

            InternalEdgeUtility.GenerateInternalEdgeInfo(trimeshShape, triangleInfoMap);


            m_collisionConfiguration = new DefaultCollisionConfiguration();


            m_dispatcher = new CollisionDispatcher(m_collisionConfiguration);



            m_broadphase       = new DbvtBroadphase();
            m_constraintSolver = new SequentialImpulseConstraintSolver();
            m_dynamicsWorld    = new DiscreteDynamicsWorld(m_dispatcher, m_broadphase, m_constraintSolver, m_collisionConfiguration);
            m_dynamicsWorld.SetDebugDrawer(m_debugDraw);

            IndexedVector3 gravity = new IndexedVector3(0, -10, 0);
            m_dynamicsWorld.SetGravity(ref gravity);


            float         mass               = 0.0f;
            IndexedMatrix startTransform     = IndexedMatrix.CreateTranslation(new IndexedVector3(0, -2, 0));

            ConvexHullShape colShape = new ConvexHullShape(new List <IndexedVector3>(), 0);
            for (int k = 0; k < DemoMeshes.TaruVtxCount; k++)
            {
                IndexedVector3 vtx = DemoMeshes.TaruVtx[k];
                colShape.AddPoint(ref vtx);
            }
            //this will enable polyhedral contact clipping, better quality, slightly slower
            //colShape.InitializePolyhedralFeatures();

            //the polyhedral contact clipping can use either GJK or SAT test to find the separating axis
            m_dynamicsWorld.GetDispatchInfo().m_enableSatConvex = false;


            {
                //for (int i2 = 0; i2 < 1; i2++)
                //{
                //    startTransform._origin = new IndexedVector3(-10.0f + i2 * 3.0f, 2.2f + i2 * 0.1f, -1.3f);
                //    RigidBody body = LocalCreateRigidBody(10, startTransform, colShape);
                //    body.SetActivationState(ActivationState.DISABLE_DEACTIVATION);
                //    body.SetLinearVelocity(new IndexedVector3(0, 0, -1));
                //    //body->setContactProcessingThreshold(0.f);
                //}
            }
            {
                BoxShape colShape2 = new BoxShape(new IndexedVector3(1, 1, 1));
                //colShape.InitializePolyhedralFeatures();
                m_collisionShapes.Add(colShape2);
                startTransform._origin = new IndexedVector3(-16.0f + i * 3.0f, 1.0f + i * 0.1f, -1.3f);
                RigidBody body = LocalCreateRigidBody(10, startTransform, colShape2);
                body.SetActivationState(ActivationState.DISABLE_DEACTIVATION);
                body.SetLinearVelocity(new IndexedVector3(0, 0, -1));
            }

            startTransform = IndexedMatrix.Identity;

            staticBody = LocalCreateRigidBody(mass, startTransform, groundShape);
            //staticBody->setContactProcessingThreshold(-0.031f);
            staticBody.SetCollisionFlags(staticBody.GetCollisionFlags() | CollisionFlags.CF_KINEMATIC_OBJECT);    //STATIC_OBJECT);

            //enable custom material callback
            staticBody.SetCollisionFlags(staticBody.GetCollisionFlags() | CollisionFlags.CF_CUSTOM_MATERIAL_CALLBACK);
            m_debugDraw.SetDebugMode(DebugDrawModes.DBG_DrawText | DebugDrawModes.DBG_NoHelpText | DebugDrawModes.DBG_DrawWireframe | DebugDrawModes.DBG_DrawContactPoints);



            //base.InitializeDemo();
            //ClientResetScene();
        }
예제 #6
0
        /// <summary>
        /// Adds the point.
        /// </summary>
        /// <param name="point">The point.</param>
        public void AddPoint(float3 point)
        {
            var btPoint = Translator.Float3ToBtVector3(point);

            BtConvexHullShape.AddPoint(btPoint, true);
        }