Example #1
0
 public RigidBody_c(Body_c b, Shape cg, HullMaker hull, float radius, Microsoft.Xna.Framework.Graphics.Color c)
 {
     maxRadius    = radius;
     body         = b;
     collideModel = cg;
     renderModel  = hull;
     id           = idcounter;
     colour       = c;
     idcounter++;
 }
Example #2
0
    void ComputeMassProperties(Body_c body, HullMaker model, float density)
    {
        MyVector3 diag    = new MyVector3(Vector3.Zero);
        MyVector3 offDiag = new MyVector3(Vector3.Zero);
        Vector3   weightedCenterOfMass = Vector3.Zero;
        float     volume = 0;
        float     mass   = 0;

        // Iterate through the faces
        for (int faceIndex = 0; faceIndex < model.surfaceTriList.Count; faceIndex++)
        {
            HullMaker.ClipTri face = model.surfaceTriList[faceIndex];

            // Iterate through the tris in the face
            for (int triIndex = 0; triIndex < 3; triIndex++)
            {
                MyVector3 v0 = new MyVector3(face.n1);
                MyVector3 v1 = new MyVector3(face.n2);
                MyVector3 v2 = new MyVector3(face.n3);

                float det = Det(v0.V3(), v1.V3(), v2.V3());

                // Volume
                float tetVolume = det / 6.0f;
                volume += tetVolume;

                // Mass
                float tetMass = tetVolume * density;
                mass += tetMass;

                // Center of Mass
                Vector3 tetCenterOfMass = ((v0 + v1 + v2) / 4.0f).V3();                 // Note: includes origin (0, 0, 0) as fourth vertex
                weightedCenterOfMass += tetMass * tetCenterOfMass;

                // Inertia Tensor
                for (int i = 0; i < 3; i++)
                {
                    int j = (i + 1) % 3;
                    int k = (i + 2) % 3;

                    diag[i] += det * (v0[i] * v1[i] + v1[i] * v2[i] + v2[i] * v0[i] + v0[i] * v0[i] + v1[i] * v1[i] + v2[i] * v2[i]) / 60.0f;

                    offDiag[i] += det * (
                        v0[j] * v1[k] + v1[j] * v2[k] + v2[j] * v0[k] +
                        v0[j] * v2[k] + v1[j] * v0[k] + v2[j] * v1[k] +
                        2 * v0[j] * v0[k] + 2 * v1[j] * v1[k] + 2 * v2[j] * v2[k]) / 120.0f;
                }
            }
        }


        Debug_c.Assert(mass > 0);
        if (mass == 0.0f)
        {
            mass = 5.0f;
        }

        Vector3 centerOfMass = weightedCenterOfMass / mass;

        diag    *= density;
        offDiag *= density;

        MyMatrix I = new MyMatrix(Matrix.Identity);

        I[0, 0] = diag[1] + diag[2];
        I[1, 1] = diag[2] + diag[0];
        I[2, 2] = diag[0] + diag[1];
        I[1, 2] = I[2, 1] = -offDiag[0];
        I[0, 2] = I[2, 0] = -offDiag[1];
        I[0, 1] = I[1, 0] = -offDiag[2];

        ///
        // Move inertia tensor to be relative to center of mass (rather than origin)

        // Translate intertia to center of mass
        float x = centerOfMass.X;
        float y = centerOfMass.Y;
        float z = centerOfMass.Z;

        //Debug_c.Assert(Math.Abs(x)>0);
        //Debug_c.Assert(Math.Abs(y)>0);
        //Debug_c.Assert(Math.Abs(z)>0);
        //if (x==0.0f) x = 1.0f;
        //if (y==0.0f) y = 1.0f;
        //if (z==0.0f) z = 1.0f;

        I[0, 0] -= mass * (y * y + z * z);
        I[0, 1] -= mass * (-x * y);
        I[0, 2] -= mass * (-x * z);
        I[1, 1] -= mass * (x * x + z * z);
        I[1, 2] -= mass * (-y * z);
        I[2, 2] -= mass * (x * x + y * y);

        // Symmetry
        I[1, 0] = I[0, 1];
        I[2, 0] = I[0, 2];
        I[2, 1] = I[1, 2];

        float check = 0.0f;

        for (int r = 0; r < 3; r++)
        {
            for (int c = 0; c < 3; c++)
            {
                check += I[r, c];
            }
        }
        Debug_c.Assert(Math.Abs(check) > 0.0f);
        if (check == 0.0f)
        {
            I = new MyMatrix(Matrix.Identity);
        }

        body.com        = centerOfMass;
        body.inv_m      = 1.0f / mass;
        body.inv_m_back = body.inv_m;
        body.I          = I.Get();
        GeneralInverse4x4(out body.inv_I, ref I);
        //body.inv_I = Matrix.Invert( I.Get() );

        Debug_c.Valid(body.com);
        Debug_c.Valid(body.inv_m);
        Debug_c.Valid(body.inv_I);
        Debug_c.Valid(body.I);

        Matrix test = Matrix.Identity;

        test = Matrix.Invert(I.Get());
    }
Example #3
0
    RigidBody_c CreateRigidBody(Shape collideModel, Quaternion q, Vector3 x, float inv_m)
    {
        //RenderPolytope	renderModel	 = rb.renderModel;
        HullMaker renderModel = new HullMaker(collideModel, -1);

        //if (!renderModel)
        //{
        //	renderModel = CreateRenderModel(collideModel);
        //}

        Body_c body = new Body_c();

        body.q      = q;
        body.x      = x;
        body.inv_I  = Matrix.Identity;
        body.inv_I *= inv_m / 25.0f;
        //body.inv_I.M33 = 1;
        body.inv_I.M44 = 1;
        body.inv_m     = inv_m;

        if (inv_m == 0.0f)
        {
            body.m = 0.0f;
        }

        if (inv_m > 0.0f)
        {
            HelperRigidBody_c.ComputeMassProperties(body, renderModel, 1.0f);
        }

        float radiusNegX = Math.Abs(collideModel.GetSupportPoint(new Vector3(-1, 0, 0)).X);
        float radiusPosX = Math.Abs(collideModel.GetSupportPoint(new Vector3(1, 0, 0)).X);
        float radiusNegY = Math.Abs(collideModel.GetSupportPoint(new Vector3(0, -1, 0)).Y);
        float radiusPosY = Math.Abs(collideModel.GetSupportPoint(new Vector3(0, 1, 0)).Y);
        float radiusNegZ = Math.Abs(collideModel.GetSupportPoint(new Vector3(0, 0, -1)).Z);
        float radiusPosZ = Math.Abs(collideModel.GetSupportPoint(new Vector3(0, 0, 1)).Z);

        Vector3 maxRadiusVector = new Vector3
                                  (
            Math.Max(radiusNegX, radiusPosX),
            Math.Max(radiusNegY, radiusPosY),
            Math.Max(radiusNegZ, radiusPosZ)
                                  );

        float maxRadius = maxRadiusVector.Length();

        Microsoft.Xna.Framework.Graphics.Color[] randColour = { Microsoft.Xna.Framework.Graphics.Color.Red,
                                                                Microsoft.Xna.Framework.Graphics.Color.Green,
                                                                Microsoft.Xna.Framework.Graphics.Color.PaleGoldenrod,
                                                                Microsoft.Xna.Framework.Graphics.Color.OliveDrab,
                                                                Microsoft.Xna.Framework.Graphics.Color.OrangeRed,
                                                                Microsoft.Xna.Framework.Graphics.Color.Wheat,
                                                                Microsoft.Xna.Framework.Graphics.Color.YellowGreen };

        randColourIndx++;
        if (randColourIndx > (randColour.Count() - 1))
        {
            randColourIndx = 0;
        }

        body.inv_m_back = body.inv_m;

        return(new RigidBody_c(body, collideModel, renderModel, maxRadius, randColour[randColourIndx]));
    }