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; }
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; }
public void RecalculateMass() { try { _mass = Body.ComputeMass(OnlyFixtures); } catch { _mass = new MassData(0, Vec2.Empty, 0); } }
void _fixtures_ObjectsRemoved(object sender, EventArgs e) { _mass = Body.ComputeMass(OnlyFixtures); }
public static extern void b2body_setmassdata(IntPtr body, out MassData data);
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); }
/// <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); }
/// <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); }
/// <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); }
void _fixtures_ObjectsAdded(object sender, EventArgs e) { _mass = Body.ComputeMass(OnlyFixtures); }
public (KVector2, float) UpdateForce(MassData massData, PhysicMateriel materiel, State state, float h) { _force = _gravity * massData.Mass; return(_force, 0f); }