Esempio n. 1
0
        public override void computeMass(MassData massData, float density)
        {
            massData.mass = density*Settings.PI*m_radius*m_radius;
            massData.center.x = m_p.x;
            massData.center.y = m_p.y;

            // inertia about the local origin
            // massData.I = massData.mass * (0.5f * m_radius * m_radius + Vec2.dot(m_p, m_p));
            massData.I = massData.mass*(0.5f*m_radius*m_radius + (m_p.x*m_p.x + m_p.y*m_p.y));
        }
Esempio n. 2
0
 /**
    * Compute the mass properties of this shape using its dimensions and density. The inertia tensor
    * is computed about the local origin.
    *
    * @param massData returns the mass data for this shape.
    * @param density the density in kilograms per meter squared.
    */
 public abstract void computeMass(MassData massData, float density);
Esempio n. 3
0
 /**
    * Get the mass data for this fixture. The mass data is based on the density and the shape. The
    * rotational inertia is about the shape's origin.
    *
    * @return
    */
 public void getMassData(MassData massData)
 {
     m_shape.computeMass(massData, m_density);
 }
Esempio n. 4
0
        /**
           * Set the mass properties to override the mass properties of the fixtures. Note that this changes
           * the center of mass position. Note that creating or destroying fixtures can also alter the mass.
           * This function has no effect if the body isn't dynamic.
           *
           * @param massData the mass properties.
           */
        public void setMassData(MassData massData)
        {
            // TODO_ERIN adjust linear velocity and torque to account for movement of center.
            Debug.Assert(m_world.isLocked() == false);
            if (m_world.isLocked() == true)
            {
                return;
            }

            if (m_type != BodyType.DYNAMIC)
            {
                return;
            }

            m_invMass = 0.0f;
            m_I = 0.0f;
            m_invI = 0.0f;

            m_mass = massData.mass;
            if (m_mass <= 0.0f)
            {
                m_mass = 1f;
            }

            m_invMass = 1.0f/m_mass;

            if (massData.I > 0.0f && (m_flags & BodyFlags.FixedRotation) == 0)
            {
                m_I = massData.I - m_mass*Vec2.dot(massData.center, massData.center);
                Debug.Assert(m_I > 0.0f);
                m_invI = 1.0f/m_I;
            }

            Vec2 oldCenter = m_world.getPool().popVec2();
            // Move center of mass.
            oldCenter.set(m_sweep.c);
            m_sweep.localCenter.set(massData.center);
            // m_sweep.c0 = m_sweep.c = Mul(m_xf, m_sweep.localCenter);
            Transform.mulToOutUnsafe(m_xf, m_sweep.localCenter, ref m_sweep.c0);
            m_sweep.c.set(m_sweep.c0);

            // Update center of mass velocity.
            // m_linearVelocity += Cross(m_angularVelocity, m_sweep.c - oldCenter);
            Vec2 temp = m_world.getPool().popVec2();
            temp.set(m_sweep.c);
            temp.subLocal(oldCenter);
            Vec2.crossToOut(m_angularVelocity, temp, ref temp);
            m_linearVelocity.addLocal(temp);

            m_world.getPool().pushVec2(2);
        }
Esempio n. 5
0
        /**
           * Get the mass data of the body. The rotational inertia is relative to the center of mass.
           *
           * @return a struct containing the mass, inertia and center of the body.
           */
        public void getMassData(MassData data)
        {
            // data.mass = m_mass;
            // data.I = m_I + m_mass * Vec2.dot(m_sweep.localCenter, m_sweep.localCenter);
            // data.center.set(m_sweep.localCenter);

            data.mass = m_mass;
            data.I =
                m_I
                + m_mass
                *(m_sweep.localCenter.x*m_sweep.localCenter.x + m_sweep.localCenter.y
                  *m_sweep.localCenter.y);
            data.center.x = m_sweep.localCenter.x;
            data.center.y = m_sweep.localCenter.y;
        }
Esempio n. 6
0
        public override void computeMass(MassData massData, float density)
        {
            // Polygon mass, centroid, and inertia.
            // Let rho be the polygon density in mass per unit area.
            // Then:
            // mass = rho * int(dA)
            // centroid.x = (1/mass) * rho * int(x * dA)
            // centroid.y = (1/mass) * rho * int(y * dA)
            // I = rho * int((x*x + y*y) * dA)
            //
            // We can compute these integrals by summing all the integrals
            // for each triangle of the polygon. To evaluate the integral
            // for a single triangle, we make a change of variables to
            // the (u,v) coordinates of the triangle:
            // x = x0 + e1x * u + e2x * v
            // y = y0 + e1y * u + e2y * v
            // where 0 <= u && 0 <= v && u + v <= 1.
            //
            // We integrate u from [0,1-v] and then v from [0,1].
            // We also need to use the Jacobian of the transformation:
            // D = cross(e1, e2)
            //
            // Simplification: triangle centroid = (1/3) * (p1 + p2 + p3)
            //
            // The rest of the derivation is handled by computer algebra.

            Debug.Assert(m_count >= 3);

            Vec2 center = pool1;
            center.setZero();
            float area = 0.0f;
            float I = 0.0f;

            // pRef is the reference point for forming triangles.
            // It's location doesn't change the result (except for rounding error).
            Vec2 s = pool2;
            s.setZero();
            // This code would put the reference point inside the polygon.
            for (int i = 0; i < m_count; ++i)
            {
                s.addLocal(m_vertices[i]);
            }
            s.mulLocal(1.0f/m_count);

            float k_inv3 = 1.0f/3.0f;

            Vec2 e1 = pool3;
            Vec2 e2 = pool4;

            for (int i = 0; i < m_count; ++i)
            {
                // Triangle vertices.
                e1.set(m_vertices[i]);
                e1.subLocal(s);
                e2.set(s);
                e2.negateLocal();
                e2.addLocal(i + 1 < m_count ? m_vertices[i + 1] : m_vertices[0]);

                float D = Vec2.cross(e1, e2);

                float triangleArea = 0.5f*D;
                area += triangleArea;

                // Area weighted centroid
                center.x += triangleArea*k_inv3*(e1.x + e2.x);
                center.y += triangleArea*k_inv3*(e1.y + e2.y);

                float ex1 = e1.x, ey1 = e1.y;
                float ex2 = e2.x, ey2 = e2.y;

                float intx2 = ex1*ex1 + ex2*ex1 + ex2*ex2;
                float inty2 = ey1*ey1 + ey2*ey1 + ey2*ey2;

                I += (0.25f*k_inv3*D)*(intx2 + inty2);
            }

            // Total mass
            massData.mass = density*area;

            // Center of mass
            Debug.Assert(area > Settings.EPSILON);
            center.mulLocal(1.0f/area);
            massData.center.set(center);
            massData.center.addLocal(s);

            // Inertia tensor relative to the local origin (point s)
            massData.I = I*density;

            // Shift to center of mass then to original body origin.
            massData.I += massData.mass*(Vec2.dot(massData.center, massData.center));
        }
Esempio n. 7
0
 public override void computeMass(MassData massData, float density)
 {
     massData.mass = 0.0f;
     massData.center.set(m_vertex1);
     massData.center.addLocal(m_vertex2);
     massData.center.mulLocal(0.5f);
     massData.I = 0.0f;
 }
Esempio n. 8
0
 public override void computeMass(MassData massData, float density)
 {
     massData.mass = 0.0f;
     massData.center.setZero();
     massData.I = 0.0f;
 }
Esempio n. 9
0
 /**
  * Copies from the given mass data
  *
  * @param md
  *            mass data to copy from
  */
 public MassData(MassData md)
 {
     mass = md.mass;
     I = md.I;
     center = md.center.clone();
 }
Esempio n. 10
0
 public void set(MassData md)
 {
     mass = md.mass;
     I = md.I;
     center.set(md.center);
 }