Пример #1
0
 public static MassData CircleMassInertiaCenter(CircleCollider2D collider, float density, Vector2 center)
 {
     //PORTED FROM BOX2D
     float r = collider.radius * collider.transform.lossyScale.x;
     float m = density * Mathf.PI * r * r;
     center = (Vector2)collider.transform.TransformPoint(collider.center) - center;
     float I = m * (0.5f * r * r + center.sqrMagnitude);
     MassData data = new MassData();
     data.inertia = I;
     data.mass = m;
     data.center = center;
     return data;
 }
Пример #2
0
    public static MassData PolygonMassInertiaCenter(Vector2[] points, float density)
    {
        //PORTED FROM BOX2D
        Vector2 center = Vector2.zero;
        float area = 0f;
        float I = 0f;

        // pRef is the reference point for forming triangles.
        // It's location doesn't change the result (except for rounding error).
        Vector2 p1 = Vector2.zero;

        float k_inv3 = 1f / 3f;

        for (int i = 0; i < points.Length; ++i)
        {
            // Triangle vertices.
            //b2Vec2 p1 = pRef;
            //
            //b2Vec2 p2 = m_vertices[i];
            Vector2 p2 = points[i];
            //b2Vec2 p3 = i + 1 < m_vertexCount ? m_vertices[i+1] : m_vertices[0];
            Vector2 p3 = i + 1 < points.Length ? points[i + 1] : points[0];

            //b2Vec2 e1 = p2 - p1;
            Vector2 e1 = p2 - p1;
            //b2Vec2 e2 = p3 - p1;
            Vector2 e2 = p3 - p1;

            //float32 D = b2Cross(e1, e2);
            float D = e1.x * e2.y - e1.y * e2.x;

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

            // Area weighted centroid
            //center += triangleArea * k_inv3 * (p1 + p2 + p3);
            center += triangleArea * k_inv3 * (p1 + p2 + p3);

            //float32 px = p1.x, py = p1.y;
            float px = p1.x;
            float py = p1.y;
            //float32 ex1 = e1.x, ey1 = e1.y;
            float ex1 = e1.x;
            float ey1 = e1.y;
            //float32 ex2 = e2.x, ey2 = e2.y;
            float ex2 = e2.x;
            float ey2 = e2.y;

            //MAGICS
            //float32 intx2 = k_inv3 * (0.25f * (ex1*ex1 + ex2*ex1 + ex2*ex2) + (px*ex1 + px*ex2)) + 0.5f*px*px;
            float intx2 = k_inv3 * (0.25f * (ex1 * ex1 + ex2 * ex1 + ex2 * ex2) + (px * ex1 + px*ex2)) + 0.5f * px * px;
            //float32 inty2 = k_inv3 * (0.25f * (ey1*ey1 + ey2*ey1 + ey2*ey2) + (py*ey1 + py*ey2)) + 0.5f*py*py;
            float inty2 = k_inv3 * (0.25f * (ey1 * ey1 + ey2 * ey1 + ey2 * ey2) + (py * ey1 + py * ey2)) + 0.5f * py * py;

            I += D * (intx2 + inty2);
        }

        // Total mass
        float m = density * area;

        // Center of mass
        //b2Settings.b2Assert(area > Number.MIN_VALUE);
        //center *= 1.0f / area;
        center *= 1f / area;

        // Inertia tensor relative to the local origin.
        I = density * I;

        MassData data = new MassData();
        data.inertia = I;
        data.mass = m;
        data.center = center;

        return data;
    }
Пример #3
0
 public void RecalculateMass()
 {
     try
     {
         _mass = Body.ComputeMass(OnlyFixtures);
     }
     catch
     {
         _mass = new MassData(0, Vec2.Empty, 0);
     }
 }
Пример #4
0
 void _fixtures_ObjectsRemoved(object sender, EventArgs e)
 {
     _mass = Body.ComputeMass(OnlyFixtures);
 }
Пример #5
0
 public static extern void b2body_setmassdata(IntPtr body, out MassData data);
Пример #6
0
        public BodyNode(WorldObject world, BodyDefSerialized x)
            : base(x.Name, 3)
        {
            Body = x.Body;
            Name = x.Name;

            for (int i = 0; i < x.FixtureIDs.Count; ++i)
            {
                var fixture = world.Fixtures[x.FixtureIDs[i]];
                _fixtures.Add(fixture);
            }

            _mass = Body.ComputeMass(OnlyFixtures);

            _fixtures.ObjectsAdded += new EventHandler(_fixtures_ObjectsAdded);
            _fixtures.ObjectsRemoved += new EventHandler(_fixtures_ObjectsRemoved);
        }
Пример #7
0
        /// <summary>
        /// This resets the mass properties to the sum of the mass properties of the fixtures.
        /// This normally does not need to be called unless you called SetMassData to override
        /// the mass and you later want to reset the mass.
        /// </summary>
        public void ResetMassData()
        {
            // Compute mass data from shapes. Each shape has its own density.
            this._mass             = 0.0f;
            this.InvMass           = 0.0f;
            this._inertia          = 0.0f;
            this.InvI              = 0.0f;
            this.Sweep.LocalCenter = Vector2.Zero;

            // Kinematic bodies have zero mass.
            if (this.BodyType == BodyType.Kinematic)
            {
                this.Sweep.C0 = this.Sweep.C = this.Xf.Position;
                return;
            }

            Debug.Assert(this.BodyType == BodyType.Dynamic || this.BodyType == BodyType.Static);

            // Accumulate mass over all fixtures.
            Vector2 center = Vector2.Zero;

            if (this.FixtureList != null)
            {
                foreach (Fixture f in this.FixtureList)
                {
                    if (f.Shape._density == 0)
                    {
                        continue;
                    }

                    MassData massData = f.Shape.MassData;
                    this._mass    += massData.Mass;
                    center        += massData.Mass * massData.Centroid;
                    this._inertia += massData.Inertia;
                }
            }

            //Static bodies only have mass, they don't have other properties. A little hacky tho...
            if (this.BodyType == BodyType.Static)
            {
                this.Sweep.C0 = this.Sweep.C = this.Xf.Position;
                return;
            }

            // Compute center of mass.
            if (this._mass > 0.0f)
            {
                this.InvMass = 1.0f / this._mass;
                center      *= this.InvMass;
            }
            else
            {
                // Force all dynamic bodies to have a positive mass.
                this._mass   = 1.0f;
                this.InvMass = 1.0f;
            }

            if (this._inertia > 0.0f && (this.Flags & BodyFlags.FixedRotation) == 0)
            {
                // Center the inertia about the center of mass.
                this._inertia -= this._mass * Vector2.Dot(center, center);

                Debug.Assert(this._inertia > 0.0f);
                this.InvI = 1.0f / this._inertia;
            }
            else
            {
                this._inertia = 0.0f;
                this.InvI     = 0.0f;
            }

            // Move center of mass.
            Vector2 oldCenter = this.Sweep.C;

            this.Sweep.LocalCenter = center;
            this.Sweep.C0          = this.Sweep.C = MathUtils.Multiply(ref this.Xf, ref this.Sweep.LocalCenter);

            // Update center of mass velocity.
            Vector2 a = this.Sweep.C - oldCenter;

            this.LinearVelocityInternal += new Vector2(-this.AngularVelocityInternal * a.Y, this.AngularVelocityInternal * a.X);
        }
Пример #8
0
 /// <summary>
 /// Compute the mass properties of this shape using its dimensions and density.
 /// The inertia tensor is computed about the local origin, not the centroid.
 /// </summary>
 /// <param name="massData">Returns the mass data for this shape.</param>
 public void ComputeMass(out MassData massData)
 {
     _shape.ComputeMass(out massData, Density);
 }
Пример #9
0
        /// <summary>
        /// This resets the mass properties to the sum of the mass properties of the fixtures.
        /// This normally does not need to be called unless you called SetMassData to override
        /// the mass and you later want to reset the mass.
        /// </summary>
        public void ResetMassData()
        {
            // Compute mass data from shapes. Each shape has its own density.
            _mass              = 0.0f;
            _invMass           = 0.0f;
            _inertia           = 0.0f;
            _invI              = 0.0f;
            _sweep.LocalCenter = Vector2.Zero;

            // Kinematic bodies have zero mass.
            if (BodyType == BodyType.Kinematic)
            {
                _sweep.C0 = _xf.p;
                _sweep.C  = _xf.p;
                _sweep.A0 = _sweep.A;
                return;
            }

            Debug.Assert(BodyType == BodyType.Dynamic || BodyType == BodyType.Static);

            // Accumulate mass over all fixtures.
            Vector2 localCenter = Vector2.Zero;

            foreach (Fixture f in FixtureList)
            {
                if (f.Shape._density == 0)
                {
                    continue;
                }

                MassData massData = f.Shape.MassData;
                _mass       += massData.Mass;
                localCenter += massData.Mass * massData.Centroid;
                _inertia    += massData.Inertia;
            }

            //Static bodies only have mass, they don't have other properties. A little hacky tho...
            if (BodyType == BodyType.Static)
            {
                _sweep.C0 = _sweep.C = _xf.p;
                return;
            }

            // Compute center of mass.
            if (_mass > 0.0f)
            {
                _invMass     = 1.0f / _mass;
                localCenter *= _invMass;
            }
            else
            {
                // Force all dynamic bodies to have a positive mass.
                _mass    = 1.0f;
                _invMass = 1.0f;
            }

            if (_inertia > 0.0f && !_fixedRotation)
            {
                // Center the inertia about the center of mass.
                _inertia -= _mass * Vector2.Dot(localCenter, localCenter);

                Debug.Assert(_inertia > 0.0f);
                _invI = 1.0f / _inertia;
            }
            else
            {
                _inertia = 0.0f;
                _invI    = 0.0f;
            }

            // Move center of mass.
            Vector2 oldCenter = _sweep.C;

            _sweep.LocalCenter = localCenter;
            _sweep.C0          = _sweep.C = MathUtils.Mul(ref _xf, ref _sweep.LocalCenter);

            // Update center of mass velocity.
            Vector2 a = _sweep.C - oldCenter;

            _linearVelocity += new Vector2(-_angularVelocity * a.Y, _angularVelocity * a.X);
        }
Пример #10
0
 void _fixtures_ObjectsAdded(object sender, EventArgs e)
 {
     _mass = Body.ComputeMass(OnlyFixtures);
 }
Пример #11
0
 public (KVector2, float) UpdateForce(MassData massData, PhysicMateriel materiel, State state, float h)
 {
     _force = _gravity * massData.Mass;
     return(_force, 0f);
 }