// Used when we only change position. public override void MoveAABB(FixVec2 posDiff) { boundingBox.min.x += posDiff.X; boundingBox.min.y += posDiff.Y; boundingBox.max.x += posDiff.X; boundingBox.max.y += posDiff.Y; }
public void initialize() { // Calculate average bounciness/restitution e = FixMath.Min(A.Bounciness, B.Bounciness); // Calculate static & dynamic friction sf = FixMath.Sqrt(A.StaticFriction * A.StaticFriction + B.StaticFriction * B.StaticFriction); df = FixMath.Sqrt(A.DynamicFriction * A.DynamicFriction + B.DynamicFriction * B.DynamicFriction); for (int i = 0; i < contactCount; i++) { //Calculate radii from COM to contact FixVec2 ra = contacts[i] -= A.info.position; FixVec2 rb = contacts[i] -= B.info.position; //? FixVec2 rv = B.info.velocity + FixVec2.Cross(B.info.angularVelocity, rb) - A.info.velocity - FixVec2.Cross(A.info.angularVelocity, ra); // Determine if we should perform a resting collision or not // The idea is if the only thing moving this object is gravity, // then the collision should be performed without any restitution if (rv.GetMagnitudeSquared() < TFPhysics.instance.resting) { e = 0; } } }
public static void Update(Contexts contexts) { var dt = contexts.Configuration().Get <TimeStep>().Value; var g = contexts.Configuration().Get <GlobalForce>().Value; var context = contexts.Get <Game>(); foreach (var entity in context.AllWith <Force, Mass, Velocity>()) { if (entity.Is <Destroyed>()) { continue; } var force = entity.Get <Force>().Value + g; var mass = entity.Get <Mass>().Value; var velocity = entity.Get <Velocity>().Value; var damping = entity.Has <Damping>() ? entity.Get <Damping>().Value : 0; velocity += dt * force / mass; velocity *= Fix.One / (Fix.One + dt * damping); if (entity.Has <MaxVelocity>()) { var maxVelocity = entity.Get <MaxVelocity>(); velocity = FixVec2.ClampMagnitude(velocity, maxVelocity.Value); } entity.Replace(new Velocity(velocity)); entity.Replace(new Force()); } }
// Used when we rotate or vertices are added/removed. public override void RecalcAABB(FixVec2 pos) { boundingBox.min.x = pos.x; boundingBox.max.x = pos.x; boundingBox.min.y = pos.y; boundingBox.max.y = pos.y; for (int i = 0; i < vertices.Count; i++) { FixVec2 v = u.Transposed() * vertices[i]; if (v.x + pos.x < boundingBox.min.x) { boundingBox.min.x = v.x + pos.x; } if (v.y + pos.y < boundingBox.min.y) { boundingBox.min.y = v.y + pos.y; } if (v.x + pos.x > boundingBox.max.x) { boundingBox.max.x = v.x + pos.x; } if (v.y + pos.y > boundingBox.max.y) { boundingBox.max.y = v.y + pos.y; } } }
/// <summary> /// Expand the AABB by increasing its size by amount along each side. /// </summary> /// <param name="amount"></param> public void Expand(Fix amount) { FixVec2 extendAmt = FixVec2.one * amount; min -= extendAmt; max += extendAmt; }
public FixTrans2 Scale(FixVec2 scale) { return(new FixTrans2( M11 * scale.X, M12 * scale.X, M13 * scale.X, M21 * scale.Y, M22 * scale.Y, M23 * scale.Y )); }
public FixTrans2 Translate(FixVec2 delta) { return(new FixTrans2( M11, M12, M13 + delta.X, M21, M22, M23 + delta.Y )); }
private static SteeringVelocity Arrive(Entity <Game> owner, FixVec2 target) { var tolerance = owner.Get <ArrivalTolerance>(); var position = owner.Get <Position>().Value; target.Sub(ref position); var distance = target.Magnitude; if (distance <= tolerance.Distance) { return(SteeringVelocity.Zero); } var maxVelocity = owner.Get <MaxVelocity>().Value; var decelerationDistance = tolerance.DecelerationDistance; if (distance <= decelerationDistance) { maxVelocity *= distance / decelerationDistance; } var velocity = target / distance * maxVelocity; return(new SteeringVelocity(FixVec2.ClampMagnitude(velocity, maxVelocity))); }
// Used when we rotate or vertices are added/removed. public override void RecalcAABB(FixVec2 pos) { boundingBox.min.x = pos.X; boundingBox.max.x = pos.X; boundingBox.min.y = pos.Y; boundingBox.max.y = pos.Y; for (int i = 0; i < vertices.Count; i++) { FixVec2 v = u.Transposed() * (vertices[i] * tdTransform.LocalScale); if (v.X + pos.x < boundingBox.min.X) { boundingBox.min.x = v.X + pos.x; } if (v.Y + pos.y < boundingBox.min.Y) { boundingBox.min.y = v.Y + pos.y; } if (v.X + pos.x > boundingBox.max.X) { boundingBox.max.x = v.X + pos.x; } if (v.Y + pos.y > boundingBox.max.Y) { boundingBox.max.y = v.Y + pos.y; } } }
// Draw the property inside the given rect public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) { FixVec2 te = new FixVec2(); te._x._raw = property.FindPropertyRelative("_x").FindPropertyRelative("_raw").intValue; te._y._raw = property.FindPropertyRelative("_y").FindPropertyRelative("_raw").intValue; val = (Vector2)te; EditorGUI.BeginProperty(position, label, property); // Calculate rects var nameRect = new Rect(position.x, position.y, position.width - 90, position.height); var xRect = new Rect(position.x + 130, position.y, 60, position.height); var yRect = new Rect(position.x + 185, position.y, 60, position.height); // Draw fields - passs GUIContent.none to each so they are drawn without labels //EditorGUI.PropertyField(amountRect, val.x. GUIContent.none); //EditorGUI.PropertyField(unitRect, val.y, GUIContent.none); //EditorGUI.PropertyField(nameRect, property.FindPropertyRelative("name"), GUIContent.none); EditorGUI.LabelField(nameRect, property.name); val.x = EditorGUI.FloatField(xRect, val.x); val.y = EditorGUI.FloatField(yRect, val.y); EditorGUI.EndProperty(); if (GUI.changed) { FixVec2 tem = (FixVec2)val; property.FindPropertyRelative("_x").FindPropertyRelative("_raw").intValue = tem._x._raw; property.FindPropertyRelative("_y").FindPropertyRelative("_raw").intValue = tem._y._raw; } }
public void HandleCollision(Manifold m, TFRigidbody a, TFRigidbody b) { TFCircleCollider A = (TFCircleCollider)a.coll; TFCircleCollider B = (TFCircleCollider)b.coll; //Calculate translational vector, which is normal FixVec2 normal = ((FixVec2)b.Position) - ((FixVec2)a.Position); Fix distSpr = normal.GetMagnitudeSquared(); Fix radius = A.radius + B.radius; //Not in contact if (distSpr >= radius * radius) { m.contactCount = 0; return; } Fix distance = FixMath.Sqrt(distSpr); m.contactCount = 1; if (distance == Fix.zero) { m.penetration = A.radius; m.normal = new FixVec2(1, 0); m.contacts[0] = (FixVec2)a.Position; } else { m.penetration = radius - distance; m.normal = normal / distance; m.contacts[0] = m.normal * A.radius + ((FixVec2)a.Position); } }
public void HandleCollision(Manifold m, TFRigidbody a, TFRigidbody b) { TFEdgeCollider A = (TFEdgeCollider)a.coll; TFCircleCollider B = (TFCircleCollider)b.coll; // No line segments, return out. if (A.vertices.Count < 2) { return; } // Transform circle center to Edge model space FixVec2 circleCenter = A.u.Transposed() * (b.Position - a.Position); // Iterate through all the line segments to find contact point. for (int i = 0; i < A.vertices.Count - 1; i++) { FixVec2 rayDir = (A.vertices[i + 1] - A.vertices[i]); FixVec2 centerRay = (A.vertices[i] - circleCenter); Fix k = rayDir.Dot(rayDir); Fix l = 2 * centerRay.Dot(rayDir); Fix n = centerRay.Dot(centerRay) - (B.radius * B.radius); Fix discriminant = l * l - 4 * k * n; // No intersection. if (discriminant <= Fix.zero) { continue; } discriminant = FixMath.Sqrt(discriminant); Fix t1 = (-l - discriminant) / (2 * k); Fix t2 = (-l + discriminant) / (2 * k); Fix s = FixVec2.Dot(A.normals[i], circleCenter - A.vertices[i]); if (t1 >= Fix.zero && t1 <= Fix.one) { //t1 is the intersection, and it's closer than t2. m.contactCount = 1; m.contacts[0] = (A.u * A.vertices[i] + a.Position) + (t1 * rayDir); m.normal = A.normals[i]; m.penetration = B.radius - s; return; } if (t2 >= Fix.zero && t2 <= Fix.one) { // t1 didn't insection, so we either started inside the circle // or completely past it. m.contactCount = 1; m.contacts[0] = (A.u * A.vertices[i] + a.Position) + (t2 * rayDir); m.normal = A.normals[i]; m.penetration = B.radius - s; return; } } }