This holds the mass data computed for a shape.
Ejemplo n.º 1
0
 public override void ComputeMass(MassData massData, float density)
 {
     massData.Mass = 0.0f;
     massData.Center.SetZero();
     massData.I = 0.0f;
 }
Ejemplo n.º 2
0
 public virtual void set_Renamed(MassData md)
 {
     mass = md.mass;
     I = md.I;
     center.set_Renamed(md.center);
 }
Ejemplo n.º 3
0
 /// <summary>
 /// Copies from the given mass data
 /// </summary>
 /// <param name="md">mass data to copy from</param>
 public MassData(MassData md)
 {
     mass = md.mass;
     I = md.I;
     center = md.center.Clone();
 }
Ejemplo n.º 4
0
 /// <summary>
 /// Compute the mass properties of this shape using its dimensions and density. The inertia tensor
 /// is computed about the local origin.
 /// </summary>
 /// <param name="massData">returns the mass data for this shape.</param>
 /// <param name="density">the density in kilograms per meter squared.</param>
 public abstract void computeMass(MassData massData, float density);
Ejemplo n.º 5
0
        public override void computeMass(MassData massData, float density)
        {
            massData.mass = density * Settings.PI * m_radius * m_radius;
            massData.center.set_Renamed(m_p);

            // inertia about the local origin
            massData.I = massData.mass * (0.5f * m_radius * m_radius + Vec2.dot(m_p, m_p));
        }
Ejemplo n.º 6
0
        /// <summary>
        /// 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.
        /// </summary>
        /// <param name="massData">the mass properties.</param>
        public void SetMassData(MassData massData)
        {
            // TODO_ERIN adjust linear velocity and torque to account for movement of center.
            Debug.Assert(World.Locked == false);
            if (World.Locked)
            {
                return;
            }

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

            InvMass = 0.0f;
            I = 0.0f;
            InvI = 0.0f;

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

            InvMass = 1.0f / Mass;

            if (massData.I > 0.0f && (Flags & TypeFlags.FixedRotation) == 0)
            {
                I = massData.I - Mass * Vec2.Dot(massData.Center, massData.Center);
                Debug.Assert(I > 0.0f);
                InvI = 1.0f / I;
            }

            Vec2 oldCenter = World.Pool.PopVec2();
            // Move center of mass.
            oldCenter.Set(Sweep.C);
            Sweep.LocalCenter.Set(massData.Center);
            // m_sweep.c0 = m_sweep.c = Mul(m_xf, m_sweep.localCenter);
            Transform.MulToOutUnsafe(Xf, Sweep.LocalCenter, Sweep.C0);
            Sweep.C.Set(Sweep.C0);

            // Update center of mass velocity.
            // m_linearVelocity += Cross(m_angularVelocity, m_sweep.c - oldCenter);
            Vec2 temp = World.Pool.PopVec2();
            temp.Set(Sweep.C).SubLocal(oldCenter);
            Vec2.CrossToOut(m_angularVelocity, temp, temp);
            m_linearVelocity.AddLocal(temp);

            World.Pool.PushVec2(2);
        }
Ejemplo n.º 7
0
 public override void ComputeMass(MassData massData, float density)
 {
     massData.Mass = 0.0f;
     massData.Center.Set(Vertex1).AddLocal(Vertex2).MulLocal(0.5f);
     massData.I = 0.0f;
 }
Ejemplo n.º 8
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(VertexCount >= 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 < VertexCount; ++i)
            {
                s.AddLocal(Vertices[i]);
            }
            s.MulLocal(1.0f / VertexCount);

            const float k_inv3 = 1.0f / 3.0f;

            Vec2 e1 = pool3;
            Vec2 e2 = pool4;

            for (int i = 0; i < VertexCount; ++i)
            {
                // Triangle vertices.
                e1.Set(Vertices[i]).SubLocal(s);
                e2.Set(s).NegateLocal().AddLocal(i + 1 < VertexCount ? Vertices[i + 1] : 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;
                float ey1 = e1.Y;
                float ex2 = e2.X;
                float 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).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));
        }
Ejemplo n.º 9
0
 /// <summary>
 /// 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.
 /// </summary>
 /// <returns></returns>
 public void GetMassData(MassData massData)
 {
     Shape.ComputeMass(massData, m_density);
 }
Ejemplo n.º 10
0
 public override void computeMass(MassData massData, float density)
 {
     massData.mass = 0.0f;
     massData.center.setZero();
     massData.I = 0.0f;
 }
Ejemplo n.º 11
0
 /// <summary>
 /// 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.
 /// </summary>
 /// <returns></returns>
 public virtual void getMassData(MassData massData)
 {
     m_shape.computeMass(massData, m_density);
 }
Ejemplo n.º 12
0
 /// <summary>
 /// Copies from the given mass data
 /// </summary>
 /// <param name="md">mass data to copy from</param>
 public MassData(MassData md)
 {
     Mass = md.Mass;
     I = md.I;
     Center = md.Center.Clone();
 }
Ejemplo n.º 13
0
 public void Set(MassData md)
 {
     Mass = md.Mass;
     I = md.I;
     Center.Set(md.Center);
 }
Ejemplo n.º 14
0
        /// <summary>
        /// Get the mass data of the body. The rotational inertia is relative to the center of mass.
        /// </summary>
        /// <returns>a struct containing the mass, inertia and center of the body.</returns>
        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 = Mass;
            data.I = I + Mass * (Sweep.LocalCenter.X * Sweep.LocalCenter.X + Sweep.LocalCenter.Y * Sweep.LocalCenter.Y);
            data.Center.X = Sweep.LocalCenter.X;
            data.Center.Y = Sweep.LocalCenter.Y;
        }
Ejemplo n.º 15
0
        /// <summary>
        /// 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.
        /// </summary>
        /// <param name="massData">the mass properties.</param>
        public void setMassData(MassData massData)
        {
            // TODO_ERIN adjust linear velocity and torque to account for movement of center.
            Debug.Assert(m_world.Locked == false);
            if (m_world.Locked == 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 & e_fixedRotationFlag) == 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.Pool.popVec2();
            // Move center of mass.
            oldCenter.set_Renamed(m_sweep.c);
            m_sweep.localCenter.set_Renamed(massData.center);
            // m_sweep.c0 = m_sweep.c = Mul(m_xf, m_sweep.localCenter);
            Transform.mulToOutUnsafe(m_xf, m_sweep.localCenter, m_sweep.c0);
            m_sweep.c.set_Renamed(m_sweep.c0);

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

            m_world.Pool.pushVec2(2);
        }
Ejemplo n.º 16
0
 public override void computeMass(MassData massData, float density)
 {
     massData.mass = 0.0f;
     massData.center.set_Renamed(m_vertex1).addLocal(m_vertex2).mulLocal(0.5f);
     massData.I = 0.0f;
 }
Ejemplo n.º 17
0
        /// <summary>
        /// Get the mass data of the body. The rotational inertia is relative to the center of mass.
        /// </summary>
        /// <returns>a struct containing the mass, inertia and center of the body.</returns>
        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;
        }
Ejemplo n.º 18
0
        public override void ComputeMass(MassData massData, float density)
        {
            massData.Mass = density * Settings.PI * Radius * Radius;
            massData.Center.Set(P);

            // inertia about the local origin
            massData.I = massData.Mass * (0.5f * Radius * Radius + Vec2.Dot(P, P));
        }