Пример #1
0
		public static void SolveClusters(AlignedSoftBodyArray bodies)
		{
			btSoftBody_solveClusters(bodies._native);
		}
Пример #2
0
        // Create a sequence of flag objects and add them to the world.
        void CreateFlag(int width, int height, out AlignedSoftBodyArray flags)
        {
            flags = new AlignedSoftBodyArray();

            // First create a triangle mesh to represent a flag

            // Allocate a simple mesh consisting of a vertex array and a triangle index array
            IndexedMesh mesh = new IndexedMesh();
            mesh.NumVertices = width * height;
            mesh.NumTriangles = 2 * (width - 1) * (height - 1);

            Vector3Array vertexArray = new Vector3Array(mesh.NumVertices);
            mesh.Vertices = vertexArray;
            mesh.VertexStride = Vector3.SizeInBytes;

            IntArray triangleVertexIndexArray = new IntArray(3 * mesh.NumTriangles);
            mesh.TriangleIndices = triangleVertexIndexArray;
            mesh.TriangleIndexStride = sizeof(int) * 3;

            // Generate normalised object space vertex coordinates for a rectangular flag

            Matrix defaultScale = Matrix.Scaling(5, 20, 1);
            for (int y = 0; y < height; ++y)
            {
                float yCoordinate = y * 2.0f / (float)height - 1.0f;
                for (int x = 0; x < width; ++x)
                {
                    float xCoordinate = x * 2.0f / (float)width - 1.0f;

                    Vector3 vertex = new Vector3(xCoordinate, yCoordinate, 0.0f);
                    vertexArray[y * width + x] = Vector3.TransformCoordinate(vertex, defaultScale);
                }
            }

            // Generate vertex indices for triangles
            for (int y = 0; y < (height - 1); ++y)
            {
                for (int x = 0; x < (width - 1); ++x)
                {
                    // Triangle 0
                    // Top left of square on mesh
                    {
                        int vertex0 = y * width + x;
                        int vertex1 = vertex0 + 1;
                        int vertex2 = vertex0 + width;
                        int triangleIndex = 2 * (y * (width - 1) + x);
                        triangleVertexIndexArray[(mesh.TriangleIndexStride * triangleIndex) / sizeof(int)] = vertex0;
                        triangleVertexIndexArray[(mesh.TriangleIndexStride * triangleIndex + 1) / sizeof(int) + 1] = vertex1;
                        triangleVertexIndexArray[(mesh.TriangleIndexStride * triangleIndex + 2) / sizeof(int) + 2] = vertex2;
                    }

                    // Triangle 1
                    // Bottom right of square on mesh
                    {
                        int vertex0 = y * width + x + 1;
                        int vertex1 = vertex0 + width;
                        int vertex2 = vertex1 - 1;
                        int triangleIndex = 2 * y * (width - 1) + 2 * x + 1;
                        triangleVertexIndexArray[(mesh.TriangleIndexStride * triangleIndex) / sizeof(int)] = vertex0;
                        triangleVertexIndexArray[(mesh.TriangleIndexStride * triangleIndex) / sizeof(int) + 1] = vertex1;
                        triangleVertexIndexArray[(mesh.TriangleIndexStride * triangleIndex) / sizeof(int) + 2] = vertex2;
                    }
                }
            }

            Matrix defaultRotateAndScale = Matrix.RotationX(0.5f);

            // Construct the sequence flags applying a slightly different translation to each one to arrange them
            // appropriately in the scene.
            for (int i = 0; i < numFlags; ++i)
            {
                float zTranslate = flagSpacing * (i - numFlags / 2);

                Vector3 defaultTranslate = new Vector3(0, 20, zTranslate);
                Matrix transform = defaultRotateAndScale * Matrix.Translation(defaultTranslate);

                SoftBody softBody = CreateFromIndexedMesh(vertexArray, triangleVertexIndexArray, true);

                for (int j = 0; j < mesh.NumVertices; ++j)
                {
                    softBody.SetMass(j, 10.0f / mesh.NumVertices);
                }
                softBody.SetMass((height - 1) * width, 0);
                softBody.SetMass((height - 1) * width + width - 1, 0);
                softBody.SetMass((height - 1) * width + width / 2, 0);
                softBody.Cfg.Collisions = FCollisions.CLSS | FCollisions.CLRS;

                softBody.Cfg.LF = 0.0005f;
                softBody.Cfg.VCF = 0.001f;
                softBody.Cfg.DP = 0.0f;
                softBody.Cfg.DG = 0.0f;

                flags.Add(softBody);

                softBody.Transform(transform);

                SoftWorld.AddSoftBody(softBody);
            }

            //delete [] vertexArray;
            //delete [] triangleVertexIndexArray;
        }
Пример #3
0
        protected override void OnHandleInput()
        {
            base.OnHandleInput();

            if (Input.MousePressed == MouseButtons.Right)
            {
                results.Fraction = 1;
                if (pickConstraint == null)
                {
                    Vector3 rayFrom = Freelook.Eye;
                    Vector3 rayTo   = GetRayTo(Input.MousePoint, Freelook.Eye, Freelook.Target, FieldOfView);
                    Vector3 rayDir  = (rayTo - rayFrom);
                    rayDir.Normalize();
                    AlignedSoftBodyArray sbs = ((SoftRigidDynamicsWorld)PhysicsContext.World).SoftBodyArray;
                    for (int ib = 0; ib < sbs.Count; ++ib)
                    {
                        SoftBody psb = sbs[ib];
                        SRayCast res = new SRayCast();
                        if (psb.RayTest(rayFrom, rayTo, res))
                        {
                            results = res;
                        }
                    }
                    if (results.Fraction < 1)
                    {
                        impact       = rayFrom + (rayTo - rayFrom) * results.Fraction;
                        drag         = !(PhysicsContext as Physics).cutting;
                        lastMousePos = Input.MousePoint;
                        node         = null;
                        switch (results.Feature)
                        {
                        case EFeature.Tetra:
                        {
                            Tetra tet = results.Body.Tetras[results.Index];
                            node = tet.Nodes[0];
                            for (int i = 1; i < 4; ++i)
                            {
                                if ((node.X - impact).LengthSquared() >
                                    (tet.Nodes[i].X - impact).LengthSquared())
                                {
                                    node = tet.Nodes[i];
                                }
                            }
                            break;
                        }

                        case EFeature.Face:
                        {
                            Face f = results.Body.Faces[results.Index];
                            node = f.N[0];
                            for (int i = 1; i < 3; ++i)
                            {
                                if ((node.X - impact).LengthSquared() >
                                    (f.N[i].X - impact).LengthSquared())
                                {
                                    node = f.N[i];
                                }
                            }
                        }
                        break;
                        }
                        if (node != null)
                        {
                            goal = node.X;
                        }
                        //return;
                    }
                }
            }
            else if (Input.MouseReleased == MouseButtons.Right)
            {
                if ((!drag) && (PhysicsContext as Physics).cutting && (results.Fraction < 1))
                {
                    ImplicitSphere isphere = new ImplicitSphere(impact, 1);
                    results.Body.Refine(isphere, 0.0001f, true);
                }
                results.Fraction = 1;
                drag             = false;
            }

            // Mouse movement
            if (Input.MouseDown == MouseButtons.Right)
            {
                if (node != null && (results.Fraction < 1))
                {
                    if (!drag)
                    {
                        int x = Input.MousePoint.X - lastMousePos.X;
                        int y = Input.MousePoint.Y - lastMousePos.Y;
                        if ((x * x) + (y * y) > 6)
                        {
                            drag = true;
                        }
                    }
                    if (drag)
                    {
                        lastMousePos = Input.MousePoint;
                    }
                }
            }

            (PhysicsContext as Physics).HandleInput(Input, FrameDelta);
        }
Пример #4
0
        // Create a sequence of flag objects and add them to the world.
        void CreateFlag(int width, int height, out AlignedSoftBodyArray flags)
        {
            flags = new AlignedSoftBodyArray();

            // First create a triangle mesh to represent a flag

            // Allocate a simple mesh consisting of a vertex array and a triangle index array
            IndexedMesh mesh = new IndexedMesh();

            mesh.NumVertices  = width * height;
            mesh.NumTriangles = 2 * (width - 1) * (height - 1);

            Vector3Array vertexArray = new Vector3Array(mesh.NumVertices);

            mesh.Vertices     = vertexArray;
            mesh.VertexStride = Vector3.SizeInBytes;

            IntArray triangleVertexIndexArray = new IntArray(3 * mesh.NumTriangles);

            mesh.TriangleIndices     = triangleVertexIndexArray;
            mesh.TriangleIndexStride = sizeof(int) * 3;


            // Generate normalised object space vertex coordinates for a rectangular flag

            Matrix defaultScale = Matrix.Scaling(5, 20, 1);

            for (int y = 0; y < height; ++y)
            {
                float yCoordinate = y * 2.0f / (float)height - 1.0f;
                for (int x = 0; x < width; ++x)
                {
                    float xCoordinate = x * 2.0f / (float)width - 1.0f;

                    Vector3 vertex = new Vector3(xCoordinate, yCoordinate, 0.0f);
                    vertexArray[y * width + x] = Vector3.TransformCoordinate(vertex, defaultScale);
                }
            }

            // Generate vertex indices for triangles
            for (int y = 0; y < (height - 1); ++y)
            {
                for (int x = 0; x < (width - 1); ++x)
                {
                    // Triangle 0
                    // Top left of square on mesh
                    {
                        int vertex0       = y * width + x;
                        int vertex1       = vertex0 + 1;
                        int vertex2       = vertex0 + width;
                        int triangleIndex = 2 * (y * (width - 1) + x);
                        triangleVertexIndexArray[(mesh.TriangleIndexStride * triangleIndex) / sizeof(int)]         = vertex0;
                        triangleVertexIndexArray[(mesh.TriangleIndexStride * triangleIndex + 1) / sizeof(int) + 1] = vertex1;
                        triangleVertexIndexArray[(mesh.TriangleIndexStride * triangleIndex + 2) / sizeof(int) + 2] = vertex2;
                    }

                    // Triangle 1
                    // Bottom right of square on mesh
                    {
                        int vertex0       = y * width + x + 1;
                        int vertex1       = vertex0 + width;
                        int vertex2       = vertex1 - 1;
                        int triangleIndex = 2 * y * (width - 1) + 2 * x + 1;
                        triangleVertexIndexArray[(mesh.TriangleIndexStride * triangleIndex) / sizeof(int)]     = vertex0;
                        triangleVertexIndexArray[(mesh.TriangleIndexStride * triangleIndex) / sizeof(int) + 1] = vertex1;
                        triangleVertexIndexArray[(mesh.TriangleIndexStride * triangleIndex) / sizeof(int) + 2] = vertex2;
                    }
                }
            }


            Matrix defaultRotateAndScale = Matrix.RotationX(0.5f);

            // Construct the sequence flags applying a slightly different translation to each one to arrange them
            // appropriately in the scene.
            for (int i = 0; i < numFlags; ++i)
            {
                float zTranslate = flagSpacing * (i - numFlags / 2);

                Vector3 defaultTranslate = new Vector3(0, 20, zTranslate);
                Matrix  transform        = defaultRotateAndScale * Matrix.Translation(defaultTranslate);


                SoftBody softBody = CreateFromIndexedMesh(vertexArray, triangleVertexIndexArray, true);


                for (int j = 0; j < mesh.NumVertices; ++j)
                {
                    softBody.SetMass(j, 10.0f / mesh.NumVertices);
                }
                softBody.SetMass((height - 1) * width, 0);
                softBody.SetMass((height - 1) * width + width - 1, 0);
                softBody.SetMass((height - 1) * width + width / 2, 0);
                softBody.Cfg.Collisions = FCollisions.CLSS | FCollisions.CLRS;

                softBody.Cfg.LF  = 0.0005f;
                softBody.Cfg.VCF = 0.001f;
                softBody.Cfg.DP  = 0.0f;
                softBody.Cfg.DG  = 0.0f;


                flags.Add(softBody);

                softBody.Transform(transform);

                SoftWorld.AddSoftBody(softBody);
            }

            //delete [] vertexArray;
            //delete [] triangleVertexIndexArray;
        }