public override void ComputeMass(out MassData massData) { massData = default(MassData); massData.Mass = this._density * Settings.Pi * this._radius * this._radius; massData.Center = this._localPosition; massData.I = massData.Mass * (0.5f * this._radius * this._radius + Vec2.Dot(this._localPosition, this._localPosition)); }
public override void ComputeMass(out MassData massData, float density) { massData = new MassData(); massData.Mass = density * Mathf.PI * _radius * _radius; massData.Center = _position; // inertia about the local origin massData.I = massData.Mass * (0.5f * _radius * _radius + Vector2.Dot(_position, _position)); }
public override void ComputeMass(out MassData massData, float density) { massData = new MassData(); massData.Mass = density * Settings.PI * _radius * _radius; massData.Center = _p; // inertia about the local origin massData.I = massData.Mass * (0.5f * _radius * _radius + Vec2.Dot(_p, _p)); }
public BodyDef() { this.MassData = default(MassData); this.MassData.Center.SetZero(); this.MassData.Mass = 0f; this.MassData.I = 0f; this.UserData = null; this.Position = default(Vec2); this.Position.Set(0f, 0f); this.Angle = 0f; this.LinearDamping = 0f; this.AngularDamping = 0f; this.AllowSleep = true; this.IsSleeping = false; this.FixedRotation = false; this.IsBullet = false; }
/// <summary> /// This constructor sets the body definition default values. /// </summary> public BodyDef() { MassData = new MassData(); MassData.Center.SetZero(); MassData.Mass = 0.0f; MassData.I = 0.0f; UserData = null; Position = new Vec2(); Position.Set(0.0f, 0.0f); Angle = 0.0f; LinearDamping = 0.0f; AngularDamping = 0.0f; AllowSleep = true; IsSleeping = false; FixedRotation = false; IsBullet = false; }
/// <summary> /// This constructor sets the body definition default values. /// </summary> public BodyDef(byte init) { MassData = new MassData(); MassData.Center = Vector2.zero; MassData.Mass = 0.0f; MassData.I = 0.0f; UserData = null; Position = Vector2.zero; Angle = 0.0f; LinearVelocity = Vector2.zero; AngularVelocity = 0.0f; LinearDamping = 0.0f; AngularDamping = 0.0f; AllowSleep = true; IsSleeping = false; FixedRotation = false; IsBullet = false; }
/// <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 abstract void ComputeMass(out MassData massData, float density);
public override void ComputeMass(out MassData massData, float density) { massData.Mass = 0.0f; massData.Center = _v1; massData.I = 0.0f; }
/// <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); }
/// 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(out MassData data) { data = new MassData(); data.Mass = _mass; data.I = _I; Vec2 center = Vec2.Zero; for (Fixture f = _fixtureList; f != null; f = f._next) { MassData massData = f.GetMassData(); _mass += massData.Mass; center += massData.Mass * massData.Center; _I += massData.I; } // Compute center of mass. if (_mass > 0.0f) { _invMass = 1.0f / _mass; center *= _invMass; } if (_I > 0.0f && (_flags & BodyFlags.FixedRotation) == 0) { // Center the inertia about the center of mass. _I -= _mass * Vec2.Dot(center, center); Box2DXDebug.Assert(_I > 0.0f); _invI = 1.0f / _I; } else { _I = 0.0f; _invI = 0.0f; } // Move center of mass. Vec2 oldCenter = _sweep.C; _sweep.LocalCenter = center; _sweep.C0 = _sweep.C = Math.Mul(_xf, _sweep.LocalCenter); // Update center of mass velocity. _linearVelocity += Vec2.Cross(_angularVelocity, _sweep.C - oldCenter); BodyType oldType = _type; if (_invMass == 0.0f && _invI == 0.0f) { _type = BodyType.Static; _angularVelocity = 0.0f; _linearVelocity.SetZero(); } else { _type = BodyType.Dynamic; } // If the body type changed, we need to flag contacts for filtering. if (oldType != _type) { for (ContactEdge ce = _contactList; ce != null; ce = ce.Next) { ce.Contact.FlagForFiltering(); } } }
public override void ComputeMass(out MassData massData) { Box2DXDebug.Assert(this._vertexCount >= 3); Vec2 vec = default(Vec2); vec.Set(0f, 0f); float num = 0f; float num2 = 0f; Vec2 vec2 = new Vec2(0f, 0f); float num3 = 0.333333343f; for (int i = 0; i < this._vertexCount; i++) { Vec2 vec3 = vec2; Vec2 vec4 = this._vertices[i]; Vec2 vec5 = (i + 1 < this._vertexCount) ? this._vertices[i + 1] : this._vertices[0]; Vec2 a = vec4 - vec3; Vec2 b = vec5 - vec3; float num4 = Vec2.Cross(a, b); float num5 = 0.5f * num4; num += num5; vec += num5 * num3 * (vec3 + vec4 + vec5); float x = vec3.X; float y = vec3.Y; float x2 = a.X; float y2 = a.Y; float x3 = b.X; float y3 = b.Y; float num6 = num3 * (0.25f * (x2 * x2 + x3 * x2 + x3 * x3) + (x * x2 + x * x3)) + 0.5f * x * x; float num7 = num3 * (0.25f * (y2 * y2 + y3 * y2 + y3 * y3) + (y * y2 + y * y3)) + 0.5f * y * y; num2 += num4 * (num6 + num7); } massData.Mass = this._density * num; Box2DXDebug.Assert(num > Settings.FLT_EPSILON); vec *= 1f / num; massData.Center = vec; massData.I = this._density * num2; }
// TODO_ERIN adjust linear velocity and torque to account for movement of center. /// <summary> /// Set the mass properties. Note that this changes the center of mass position. /// If you are not sure how to compute mass properties, use SetMassFromShapes. /// The inertia tensor is assumed to be relative to the center of mass. /// @param massData the mass properties. /// </summary> /// <param name="massData"></param> public void SetMass(MassData massData) { Box2DXDebug.Assert(_world._lock == false); if (_world._lock == true) { return; } _invMass = 0.0f; _I = 0.0f; _invI = 0.0f; _mass = massData.Mass; if (_mass > 0.0f) { _invMass = 1.0f / _mass; } if ((_flags & BodyFlags.FixedRotation) == 0) { _I = massData.I; } if (_I > 0.0f) { _invI = 1.0f /_I; } // Move center of mass. _sweep.LocalCenter = massData.Center; _sweep.C0 = _sweep.C = Common.Math.Mul(_xf, _sweep.LocalCenter); // Update the sweep radii of all child shapes. for (Shape s = _shapeList; s != null; s = s._next) { s.UpdateSweepRadius(_sweep.LocalCenter); } BodyType oldType = _type; if (_invMass == 0.0f && _invI == 0.0f) { _type = BodyType.Static; } else { _type = BodyType.Dynamic; } // If the body type changed, we need to refilter the broad-phase proxies. if (oldType != _type) { for (Shape s = _shapeList; s!=null; s = s._next) { s.RefilterProxy(_world._broadPhase, _xf); } } }
public override void Keyboard(Keys key) { switch (key) { case Keys.S: { MassData data = new MassData(); data.Center.SetZero(); data.I = 0.0f; data.Mass = 0.0f; _middle.SetMassData(data); } break; } }
public override void ComputeMass(out MassData massData, float density) { massData.Mass = 0.0f; massData.Center = _v1; massData.I = 0.0f; }
public override void ComputeMass(out MassData massData) { massData = new MassData(); massData.Mass = _density * Settings.Pi * _radius * _radius; massData.Center = _localPosition; // inertia about the local origin massData.I = massData.Mass * (0.5f * _radius * _radius + Vec2.Dot(_localPosition, _localPosition)); }
/// <summary> /// Get the mass data of the body. /// </summary> /// <returns>A struct containing the mass, inertia and center of the body.</returns> public MassData GetMassData() { MassData massData = new MassData(); massData.Mass = _mass; massData.I = _I; massData.Center = GetWorldCenter(); return massData; }
public abstract void ComputeMass(out MassData massData);
// TODO_ERIN adjust linear velocity and torque to account for movement of center. /// <summary> /// Set the mass properties. Note that this changes the center of mass position. /// If you are not sure how to compute mass properties, use SetMassFromShapes. /// The inertia tensor is assumed to be relative to the center of mass. /// </summary> /// <param name="massData">The mass properties.</param> public void SetMass(MassData massData) { Box2DXDebug.Assert(_world._lock == false); if (_world._lock == true) { return; } _invMass = 0.0f; _I = 0.0f; _invI = 0.0f; _mass = massData.Mass; if (_mass > 0.0f) { _invMass = 1.0f / _mass; } _I = massData.I; if (_I > 0.0f && (_flags & BodyFlags.FixedRotation) == 0) { _invI = 1.0f / _I; } // Move center of mass. _sweep.LocalCenter = massData.Center; _sweep.C0 = _sweep.C = Common.Math.Mul(_xf, _sweep.LocalCenter); BodyType oldType = _type; if (_invMass == 0.0f && _invI == 0.0f) { _type = BodyType.Static; } else { _type = BodyType.Dynamic; } // If the body type changed, we need to refilter the broad-phase proxies. if (oldType != _type) { for (Fixture f = _fixtureList; f != null; f = f.Next) { f.RefilterProxy(_world._broadPhase, _xf); } } }
/// Set the mass properties to override the mass properties of the fixtures. /// Note that this changes the center of mass position. You can make the body /// static by using zero mass. /// Note that creating or destroying fixtures can also alter the mass. /// @warning The supplied rotational inertia is assumed to be relative to the center of mass. /// @param massData the mass properties. // TODO ERIN adjust linear velocity and torque to account for movement of center. public void SetMassData(MassData massData) { Box2DXDebug.Assert(_world.IsLocked() == false); if (_world.IsLocked() == true) { return; } _invMass = 0.0f; _I = 0.0f; _invI = 0.0f; _mass = massData.Mass; if (_mass > 0.0f) { _invMass = 1.0f / _mass; } if (massData.I > 0.0f && (_flags & BodyFlags.FixedRotation) == 0) { _I = massData.I - _mass * Vec2.Dot(massData.Center, massData.Center); _invI = 1.0f / _I; } // Move center of mass. Vec2 oldCenter = _sweep.C; _sweep.LocalCenter = massData.Center; _sweep.C0 = _sweep.C = Math.Mul(_xf, _sweep.LocalCenter); // Update center of mass velocity. _linearVelocity += Vec2.Cross(_angularVelocity, _sweep.C - oldCenter); BodyType oldType = _type; if (_invMass == 0.0f && _invI == 0.0f) { _type = BodyType.Static; } else { _type = BodyType.Dynamic; } // If the body type changed, we need to flag contacts for filtering. if (oldType != _type) { for (ContactEdge ce = _contactList; ce != null; ce = ce.Next) { ce.Contact.FlagForFiltering(); } } }
/// <summary> /// Apply properties in text box to currently selected object. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void b_ApplyProperties_Click(object sender, EventArgs e) { // apply these new settings if (currentlySelectedObject != null && AreObjPropertiesValid()) { float newScale = float.Parse(tb_Scale.Text); currentlySelectedObject.Width = (currentlySelectedObject.Width / currentlySelectedObject.scale) * newScale; if ((currentlySelectedObject is InstasteelCircleObject || (currentlySelectedObject is CircleObject && !(currentlySelectedObject is PaintedObject)))) { currentlySelectedObject.Height = currentlySelectedObject.Width; float radius = (float)currentlySelectedObject.Width / (2 * CASSWorld.SCALE); // circle objects only currentlySelectedObject.RemoveFromWorld(); CircleDef shape = new CircleDef(); shape.Radius = radius; // HACK HACK HACK - this won't work for objects that have more than one shape! shape.Density = currentlySelectedObject.shapes[0].Density; shape.Friction = currentlySelectedObject.shapes[0].Friction; shape.Restitution = currentlySelectedObject.shapes[0].Restitution; currentlySelectedObject.shapes.Clear(); // get rid of the old, unscaled shape currentlySelectedObject.shapes.Add(shape); // add the new one currentlySelectedObject.AddToWorld(); } else if (currentlySelectedObject.TextureFilename == "Art\\Objects\\BoxObjects\\bottomTexture2273") { float halfWidth = (float)currentlySelectedObject.Width / (2 * CASSWorld.SCALE); float halfHeight = (float)currentlySelectedObject.Height / (2 * CASSWorld.SCALE); // box object only... currentlySelectedObject.RemoveFromWorld(); // Create the collision shape PolygonDef shape = new PolygonDef(); shape.SetAsBox(halfWidth, halfHeight); // HACK HACK HACK - this won't work for objects that have more than one shape! shape.Density = currentlySelectedObject.shapes[0].Density; shape.Friction = currentlySelectedObject.shapes[0].Friction; shape.Restitution = currentlySelectedObject.shapes[0].Restitution; currentlySelectedObject.shapes.Clear(); // get rid of the old, unscaled shape currentlySelectedObject.shapes.Add(shape); // add the new one currentlySelectedObject.AddToWorld(); } else if (currentlySelectedObject is InstasteelObject || !(currentlySelectedObject is PaintedObject)) { currentlySelectedObject.Height = (currentlySelectedObject.Height / currentlySelectedObject.scale) * newScale; // Determine dimensions float halfWidth = (float)currentlySelectedObject.Width / (2 * CASSWorld.SCALE); float halfHeight = (float)currentlySelectedObject.Height / (2 * CASSWorld.SCALE); // box object only... currentlySelectedObject.RemoveFromWorld(); // Create the collision shape PolygonDef shape = new PolygonDef(); shape.SetAsBox(halfWidth, halfHeight); // HACK HACK HACK - this won't work for objects that have more than one shape! shape.Density = currentlySelectedObject.shapes[0].Density; shape.Friction = currentlySelectedObject.shapes[0].Friction; shape.Restitution = currentlySelectedObject.shapes[0].Restitution; currentlySelectedObject.shapes.Clear(); // get rid of the old, unscaled shape currentlySelectedObject.shapes.Add(shape); // add the new one currentlySelectedObject.AddToWorld(); } if ((bool)cBox_StaticObject.Checked) { MassData mass = new MassData(); mass.Mass = 0f; currentlySelectedObject.Body.SetMass(mass); } else if (currentlySelectedObject.Body.GetMass()==0) { MassData mass = new MassData(); mass.Mass = 1f; currentlySelectedObject.Body.SetMass(mass); currentlySelectedObject.Body.GetShapeList().Density = 1f; currentlySelectedObject.Body.SetMassFromShapes(); } float newRotation = float.Parse(tb_Rotation.Text); currentlySelectedObject.Angle = MathHelper.ToRadians(newRotation); currentlySelectedObject.scale = newScale; float newbound1 = float.Parse(tb_bound1.Text); float newbound2 = float.Parse(tb_bound2.Text); if (currentlySelectedObject is MovingObject) { MovingObject temp = (MovingObject)currentlySelectedObject; temp.bound1 = temp.Position.Y - newbound1; temp.bound2 = temp.Position.Y + newbound2; Console.WriteLine(temp.bound1 + " " + temp.bound2); currentlySelectedObject = temp; } else if (currentlySelectedObject is HorizontalMovingObject) { HorizontalMovingObject temp = (HorizontalMovingObject)currentlySelectedObject; temp.bound1 = temp.Position.X - newbound1; temp.bound2 = temp.Position.X + newbound2; currentlySelectedObject = temp; } } pb_Level.Refresh(); }
public override void ComputeMass(out MassData massData) { // 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. Box2DXDebug.Assert(_vertexCount >= 3); Vec2 center = new Vec2(); center.Set(0.0f, 0.0f); 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 pRef = new Vec2(0.0f, 0.0f); #if O // This code would put the reference point inside the polygon. for (int i = 0; i < _vertexCount; ++i) { pRef += _vertices[i]; } pRef *= 1.0f / count; #endif float k_inv3 = 1.0f / 3.0f; for (int i = 0; i < _vertexCount; ++i) { // Triangle vertices. Vec2 p1 = pRef; Vec2 p2 = _vertices[i]; Vec2 p3 = i + 1 < _vertexCount ? _vertices[i + 1] : _vertices[0]; Vec2 e1 = p2 - p1; Vec2 e2 = p3 - p1; float D = Vec2.Cross(e1, e2); float triangleArea = 0.5f * D; area += triangleArea; // Area weighted centroid center += triangleArea * k_inv3 * (p1 + p2 + p3); float px = p1.X, py = p1.Y; float ex1 = e1.X, ey1 = e1.Y; float ex2 = e2.X, ey2 = e2.Y; float intx2 = k_inv3 * (0.25f * (ex1 * ex1 + ex2 * ex1 + ex2 * ex2) + (px * ex1 + px * ex2)) + 0.5f * px * px; 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 massData.Mass = _density * area; // Center of mass Box2DXDebug.Assert(area > Common.Settings.FLT_EPSILON); center *= 1.0f / area; massData.Center = center; // Inertia tensor relative to the local origin. massData.I = _density * I; }
public void SetMass(MassData massData) { Box2DXDebug.Assert(!this._world._lock); if (!this._world._lock) { this._invMass = 0f; this._I = 0f; this._invI = 0f; this._mass = massData.Mass; if (this._mass > 0f) { this._invMass = 1f / this._mass; } if ((this._flags & Body.BodyFlags.FixedRotation) == (Body.BodyFlags)0) { this._I = massData.I; } if (this._I > 0f) { this._invI = 1f / this._I; } this._sweep.LocalCenter = massData.Center; this._sweep.C0 = (this._sweep.C = Box2DX.Common.Math.Mul(this._xf, this._sweep.LocalCenter)); for (Shape shape = this._shapeList; shape != null; shape = shape._next) { shape.UpdateSweepRadius(this._sweep.LocalCenter); } Body.BodyType type = this._type; if (this._invMass == 0f && this._invI == 0f) { this._type = Body.BodyType.Static; } else { this._type = Body.BodyType.Dynamic; } if (type != this._type) { for (Shape shape = this._shapeList; shape != null; shape = shape._next) { shape.RefilterProxy(this._world._broadPhase, this._xf); } } } }