public override void ComputeMass(MassData massData, float density) { massData.Mass = 0.0f; massData.Center.SetZero(); massData.I = 0.0f; }
public virtual void set_Renamed(MassData md) { mass = md.mass; I = md.I; center.set_Renamed(md.center); }
/// <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(); }
/// <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);
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)); }
/// <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); }
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; }
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)); }
/// <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); }
public override void computeMass(MassData massData, float density) { massData.mass = 0.0f; massData.center.setZero(); massData.I = 0.0f; }
/// <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); }
/// <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(); }
public void Set(MassData md) { Mass = md.Mass; I = md.I; Center.Set(md.Center); }
/// <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; }
/// <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); }
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; }
/// <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; }
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)); }