public bool OnCollision(gxtGeom geomA, gxtGeom geomB, gxtCollisionResult collisionResult) { float scalar = 35.0f; gxtDebugDrawer.Singleton.AddLine(geomA.Position, geomA.Position + collisionResult.Normal * scalar, Color.Orange, 0.0f); gxtDebugDrawer.Singleton.AddLine(geomB.Position, geomB.Position + collisionResult.Normal * scalar, Color.Orange, 0.0f); return true; }
private void InitGeoms() { geomA = new gxtGeom(); geomA.CollisionEnabled = true; geomA.CollidesWithGroups = gxtCollisionGroup.ALL; geomA.CollisionGroups = gxtCollisionGroup.ALL; geomA.CollisionResponseEnabled = true; geomA.RigidBody = null; geomA.Tag = null; gxtPolygon worldPolyA = gxtGeometry.CreateCirclePolygon(100, 9); geomA.Polygon = worldPolyA; geomA.SetPosition(new Vector2(150, -200)); geomA.OnCollision += OnCollision; geomB = new gxtGeom(); geomB.CollisionEnabled = true; geomB.CollidesWithGroups = gxtCollisionGroup.ALL; geomB.CollisionGroups = gxtCollisionGroup.ALL; geomB.CollisionResponseEnabled = true; geomB.RigidBody = null; geomB.Tag = null; gxtPolygon worldPolyB = gxtGeometry.CreateRectanglePolygon(800, 50); geomB.Polygon = worldPolyB; geomB.SetPosition(new Vector2(0, 200)); world.AddGeom(geomA); world.AddGeom(geomB); }
public bool OnCollision(gxtGeom ga, gxtGeom gb, gxtCollisionResult collisionResult) { if (ga == geomF) { } //gxtLog.WriteLineV(gxtVerbosityLevel.WARNING, "Collision between {0} and {1}", geomA.Id, geomB.Id); return true; /* float scalar = 35.0f; gxtDebugDrawer.Singleton.AddLine(geomA.Position, geomA.Position + collisionResult.Normal * scalar, Color.Orange, 0.0f); gxtDebugDrawer.Singleton.AddLine(geomB.Position, geomB.Position + collisionResult.Normal * scalar, Color.Orange, 0.0f); gxtDebugDrawer.Singleton.AddString(geomA.Id.ToString(), geomA.Position, Color.White, 0.0f); gxtDebugDrawer.Singleton.AddString(geomB.Id.ToString(), geomB.Position, Color.White, 0.0f); */ }
public void Remove(gxtGeom geom) { float minX = geom.AABB.Min.X; int low = 0, high = colliderList.Count - 1; int mid; do { mid = low + ((high - low) / 2); if (geom == colliderList[mid].geom) { colliderList.RemoveAt(mid); return; } if (minX > colliderList[mid].min.X) mid = low + 1; else high = mid - 1; } while (low < high); gxtLog.WriteLineV(VerbosityLevel.WARNING, "Geom Was Not Found"); }
public void Add(gxtGeom geom) { // make associated sap box gxtSAPBox addBox = new gxtSAPBox(geom); addBox.Update(); int size = colliderList.Count; // if empty or greater than the rest of the collection add to end if (colliderList.Count == 0 || addBox.min.X >= colliderList[size - 1].min.X) colliderList.Add(addBox); // if less than rest of collection insert in front else if (addBox.min.X < colliderList[0].min.X) colliderList.Insert(0, addBox); else { int idx = 1; while (addBox.min.X > colliderList[idx].min.X) { idx++; } colliderList.Insert(idx, addBox); } }
/// <summary> /// Returns one geom intersected by the pt which will collide with the given collision group /// In cases where multiple geoms are intersected by the point, the geom is chosen whose centroid /// is closest to the passed in point /// </summary> /// <param name="pt">Pt</param> /// <param name="hitGeom">Intersected Geom</param> /// <param name="collisionGroup">Collision Group</param> /// <returns>Returns true if a geom is intersected by the point</returns> public bool PointCast(Vector2 pt, out gxtGeom hitGeom, gxtCollisionGroup collisionGroup = gxtCollisionGroup.ALL) { hitGeom = null; List<gxtGeom> geoms; if (PointCastAll(pt, out geoms, collisionGroup)) { float minDist = float.MaxValue; float tmpDist; for (int i = 0; i < geoms.Count; i++) { // should really be by the world centroid instead tmpDist = (pt - geoms[i].GetWorldCentroid()).LengthSquared(); if (tmpDist < minDist) { hitGeom = geoms[i]; minDist = tmpDist; } } return true; } return false; }
private void InitGeoms() { geoms = new List<gxtGeom>(); playerGeom = new gxtGeom(); playerGeom.CollisionEnabled = true; playerGeom.CollidesWithGroups = gxtCollisionGroup.ALL; playerGeom.CollisionGroups = gxtCollisionGroup.ALL; playerGeom.CollisionResponseEnabled = true; playerGeom.RigidBody = null; playerGeom.Tag = null; gxtPolygon worldPolyA = gxtGeometry.CreateCirclePolygon(100, 9); playerGeom.Polygon = worldPolyA; playerGeom.SetPosition(new Vector2(150, -200)); playerGeom.OnCollision += OnCollision; gxtGeom floorGeom = new gxtGeom(); floorGeom.CollisionEnabled = true; floorGeom.CollidesWithGroups = gxtCollisionGroup.ALL; floorGeom.CollisionGroups = gxtCollisionGroup.ALL; floorGeom.CollisionResponseEnabled = true; floorGeom.RigidBody = null; floorGeom.Tag = null; gxtPolygon floorPoly = gxtGeometry.CreateRectanglePolygon(750, 30); floorGeom.Polygon = floorPoly; floorGeom.SetPosition(new Vector2(0, 200)); floorGeom.OnCollision += OnCollision; floorGeom.Material = new gxtPhysicsMaterial(0.7f, 0.5f); world.AddGeom(playerGeom); world.AddGeom(floorGeom); geoms.Add(floorGeom); }
/// <summary> /// Determines if an object with the given collision group can collide with the geom /// </summary> /// <param name="collisionGroup">Collision Group</param> /// <param name="geom">Geom</param> /// <returns>If object and geom can collide</returns> public bool CanCollide(gxtCollisionGroup collisionGroup, gxtGeom geom) { if (!geom.CollisionEnabled) return false; if ((collisionGroup & geom.CollisionGroups) == gxtCollisionGroup.NONE) return false; return true; }
public void RemoveGeom(gxtGeom geom) { gxtDebug.SlowAssert(!geom_remove_list.Contains(geom)); if (!geom_remove_list.Contains(geom)) geom_remove_list.Add(geom); }
private void InitGeoms() { gxtPhysicsMaterial material = new gxtPhysicsMaterial(0.7f, 0.2f); gxtPhysicsMaterial fMaterial = new gxtPhysicsMaterial(0.3f, 0.01f); gxtPhysicsMaterial cMaterial = new gxtPhysicsMaterial(0.01f, 0.5f); gxtPhysicsMaterial dMaterial = new gxtPhysicsMaterial(0.25f, 0.55f); geomA = new gxtGeom(); geomA.CollisionEnabled = true; geomA.CollidesWithGroups = gxtCollisionGroup.ALL; geomA.CollisionGroups = gxtCollisionGroup.ALL; geomA.CollisionResponseEnabled = true; geomA.RigidBody = null; geomA.Tag = null; //gxtPolygon worldPolyA = gxtGeometry.CreateRectanglePolygon(5.5f, 4.15f); //gxtPolygon worldPolyA = gxtGeometry.CreateRectanglePolygon(5.35f, 3.0f); gxtPolygon worldPolyA = gxtGeometry.CreateCirclePolygon(2.65f, 5); geomA.Polygon = worldPolyA; geomA.SetPosition(new Vector2(0, 0)); //geomA.OnCollision += OnCollision; geomA.OnSeperation += OnSeperation; geomA.Material = material; world.PhysicsWorld.Gravity = new Vector2(0.0f, 9.8f); // A and B will be attached to the came rigid body geomB = new gxtGeom(); geomB.CollisionEnabled = true; geomB.CollidesWithGroups = gxtCollisionGroup.ALL; geomB.CollisionGroups = gxtCollisionGroup.ALL; geomB.CollisionResponseEnabled = true; geomB.RigidBody = null; geomB.Tag = null; //gxtPolygon worldPolyB = gxtGeometry.CreateRectanglePolygon(2.35f, 3.3f); gxtPolygon worldPolyB = gxtGeometry.CreateRectanglePolygon(2.35f, 5); geomB.SetupFromLocalPolygon(worldPolyB, new Vector2(0.0f, -4.0f), 0.0f); geomB.SetPosition(new Vector2(0, 0)); geomB.Material = material; geomC = new gxtGeom(); geomC.CollisionEnabled = true; geomC.CollidesWithGroups = gxtCollisionGroup.ALL; geomC.CollisionGroups = gxtCollisionGroup.ALL; geomC.CollisionResponseEnabled = true; geomC.RigidBody = null; geomC.OnCollision += OnOneWayPlatformCollision; geomC.Tag = null; gxtPolygon worldPolyC = gxtGeometry.CreateRectanglePolygon(7.5f, 1.35f); geomC.Polygon = worldPolyC; geomC.SetPosition(new Vector2(4.5f, 5.25f)); geomC.Material = cMaterial; geomD = new gxtGeom(); geomD.CollisionEnabled = true; geomD.CollidesWithGroups = gxtCollisionGroup.ALL; geomD.CollisionGroups = gxtCollisionGroup.ALL; geomD.CollisionResponseEnabled = true; geomD.RigidBody = null; geomD.Tag = null; gxtPolygon worldPolyD = gxtGeometry.CreateRectanglePolygon(3.0f, 3.0f); geomD.Polygon = worldPolyD; geomD.Material = dMaterial; //geomD.SetPosition(new Vector2(400, 0)); /* geomE = new gxtGeom(); geomE.CollisionEnabled = true; geomE.CollidesWithGroups = gxtCollisionGroup.ALL; geomE.CollisionGroups = gxtCollisionGroup.ALL; geomE.CollisionResponseEnabled = true; geomE.RigidBody = null; geomE.Tag = null; gxtPolygon worldPolyE; Vector2[] tri = new Vector2[3]; tri[0] = new Vector2(-400, -300); tri[1] = new Vector2(400, -75); tri[2] = new Vector2(400, -300); worldPolyE = new gxtPolygon(tri); geomE.Polygon = worldPolyE; geomE.SetPosition(new Vector2(0, 0)); */ geomF = new gxtGeom(); geomF.CollisionEnabled = true; geomF.CollidesWithGroups = gxtCollisionGroup.ALL; geomF.CollisionGroups = gxtCollisionGroup.ALL; geomF.CollisionResponseEnabled = true; geomF.RigidBody = null; geomF.Tag = null; //geomF.Polygon = gxtGeometry.CreateCirclePolygon(2.0f, 12); geomF.Polygon = gxtGeometry.CreateRectanglePolygon(3.0f, 4.5f); //geomF.Polygon = gxtGeometry.CreateRectanglePolygon(4.35f, 4); geomF.SetPosition(new Vector2(-5.5f, -3.15f)); geomF.OnCollision += OnCollision; geomF.Material = fMaterial; floorG = new gxtGeom(); floorG.CollisionEnabled = true; floorG.CollidesWithGroups = gxtCollisionGroup.ALL; floorG.CollisionGroups = gxtCollisionGroup.ALL; floorG.CollisionResponseEnabled = true; floorG.RigidBody = null; floorG.Tag = null; floorG.Polygon = gxtGeometry.CreateRectanglePolygon(30, 2.5f); floorG.SetPosition(new Vector2(0.0f, 10.25f)); floorG.Material = material; world.AddGeom(geomA); world.AddGeom(floorG); //world.AddGeom(geomB); world.AddGeom(geomC); world.AddGeom(geomD); /* world.AddGeom(geomE); */ world.AddGeom(geomF); }
public void OnSeperation(gxtGeom playerGeom, gxtGeom otherGeom) { incrementSeperationTime = true; //collidingWithWalkableGeom = false; }
private static bool CheckOneRigidOneFixedResponse(ref gxtGeom geomA, ref gxtGeom geomB, ref gxtCollisionResult collisionResult, float dt) { if (geomA.RigidBody.MotionType == gxtRigidyBodyMotion.FIXED && geomB.RigidBody.MotionType == gxtRigidyBodyMotion.DYNAMIC) { Vector2 prevForce = geomB.RigidBody.Mass * geomB.RigidBody.PrevAcceleration; Vector2 reflectedForce = gxtMath.GetReflection(prevForce, collisionResult.Normal); // used to arbitrarily be * 0.5 Vector2 reflectedVelocity = gxtMath.GetReflection(geomB.RigidBody.Velocity, collisionResult.Normal) * combinedFrictionCoefficient; geomB.RigidBody.ClearAllKinematics(); // eventually add at point //geomB.RigidBody.AddForceAtPoint(reflectedForce, collisionResult.ContactPointB); geomB.RigidBody.Velocity = reflectedVelocity; geomB.RigidBody.Translate(collisionResult.Normal * collisionResult.Depth); geomB.RigidBody.Update(dt); geomB.Update(); return true; } else if (geomB.RigidBody.MotionType == gxtRigidyBodyMotion.FIXED && geomA.RigidBody.MotionType == gxtRigidyBodyMotion.DYNAMIC) { // worthless, it is cleared by this point Vector2 prevForce = geomA.RigidBody.Mass * geomA.RigidBody.PrevAcceleration; Vector2 reflectedForce = gxtMath.GetReflection(prevForce, collisionResult.Normal); Vector2 reflectedVelocity = gxtMath.GetReflection(geomA.RigidBody.Velocity, collisionResult.Normal) * combinedFrictionCoefficient; geomA.RigidBody.ClearAllKinematics(); // eventually add at point //geomA.RigidBody.AddForceAtPoint(reflectedVelocity, collisionResult.ContactPointA); geomA.RigidBody.Velocity = reflectedVelocity; geomA.RigidBody.Translate(collisionResult.Normal * -collisionResult.Depth); geomA.RigidBody.Update(dt); geomA.Update(); return true; } return false; }
/// <summary> /// Geoms perform no response /// </summary> /// <param name="geomA"></param> /// <param name="geomB"></param> /// <param name="collisionResult"></param> /// <returns></returns> private static bool CheckGeomResponse(ref gxtGeom geomA, ref gxtGeom geomB, ref gxtCollisionResult collisionResult) { if (geomA.HasAttachedBody() || geomB.HasAttachedBody()) return false; return true; /* if (!geomA.CollisionResponseEnabled) { if (!geomB.CollisionResponseEnabled) { return true; } else { geomB.Translate(collisionResult.Normal * -collisionResult.Depth); return true; } } else if (!geomB.CollisionResponseEnabled) { geomA.Translate(collisionResult.Normal * -collisionResult.Depth); return true; } else { // either could be translated here, thinking of doing half for each geomA.Translate(collisionResult.Normal * -collisionResult.Depth); return true; } */ }
public static bool CheckRigidResponse(ref gxtGeom geomA, ref gxtGeom geomB, ref gxtCollisionResult collisionResult, float dt) { if (!geomA.HasAttachedBody() && !geomB.HasAttachedBody()) return false; if (geomA.RigidBody.MotionType == gxtRigidyBodyMotion.FIXED && geomB.RigidBody.MotionType == gxtRigidyBodyMotion.FIXED) return true; if (!geomA.CollisionResponseEnabled && !geomB.CollisionResponseEnabled) return true; /* Begin Pre Step */ Vector2 crA = collisionResult.ContactPointA - geomA.RigidBody.Position; Vector2 crB = collisionResult.ContactPointB - geomB.RigidBody.Position; float crnA = Vector2.Dot(crA, collisionResult.Normal); float crnB = Vector2.Dot(crB, collisionResult.Normal); float invMassSum = geomA.RigidBody.InverseMass + geomB.RigidBody.InverseMass; float cra2 = crA.LengthSquared(); float crb2 = crB.LengthSquared(); float fNorm = invMassSum + geomA.RigidBody.InverseInertia * (cra2 - crnA * crnA) + geomB.RigidBody.InverseInertia * (crb2 - crnB * crnB); float massNormal = 1.0f / fNorm; float f1 = 1.0f; Vector2 tangent = gxtMath.Cross2D(collisionResult.Normal, f1); float rt1 = Vector2.Dot(crA, tangent); float rt2 = Vector2.Dot(crB, tangent); float ktangent = invMassSum; ktangent += geomA.RigidBody.InverseInertia * (cra2 - rt1 * rt1) + geomB.RigidBody.InverseInertia * (crb2 - rt2 * rt2); float massTangent = 1.0f / ktangent; Vector2 worldVelocityA = geomA.RigidBody.GetVelocityAtWorldOffset(collisionResult.ContactPointA); Vector2 worldVelocityB = geomB.RigidBody.GetVelocityAtWorldOffset(collisionResult.ContactPointB); Vector2 dv = worldVelocityB - worldVelocityA; float dvn = Vector2.Dot(dv, collisionResult.Normal); float bounceVelocity = dvn * combinedRestitutionCoefficient; float normalImpulse = 0.0f; float tangentImpulse = 0.0f; Vector2 ja = collisionResult.Normal * normalImpulse; Vector2 jb = tangent * tangentImpulse; Vector2 impulse = ja + jb; geomB.RigidBody.ApplyImpulse(impulse, crB); impulse = -impulse; geomA.RigidBody.ApplyImpulse(impulse, crA); /* End Pre Step */ /* Begin Post Step */ // 1st update contact point position for both bodies // cra - bodyA.pos // crb - bodyB.pos // get velocity from contact point // get difference between velocities at contact point // get difference along normals float tmpNormalImpulse = massNormal * -(dvn + bounceVelocity); normalImpulse = gxtMath.Max(tmpNormalImpulse + normalImpulse, 0.0f); float dni = normalImpulse - tmpNormalImpulse; Vector2 impulse2 = collisionResult.Normal * tmpNormalImpulse; geomB.RigidBody.ApplyImpulse(impulse2, collisionResult.ContactPointB); impulse2 = -impulse2; geomA.RigidBody.ApplyImpulse(impulse2, collisionResult.ContactPointA); // 0s are old normal impulse bias float normalVelocityBias = Vector2.Dot(dv, collisionResult.Normal); float normalImpulseBias = massNormal * (-normalVelocityBias + 0.0f); normalImpulseBias = gxtMath.Max(normalImpulseBias + 0.0f, 0.0f); Vector2 impulseBias = collisionResult.Normal * normalImpulseBias; geomB.RigidBody.ApplyImpulse(impulseBias, collisionResult.ContactPointB); impulseBias = -impulseBias; geomA.RigidBody.ApplyImpulse(impulseBias, collisionResult.ContactPointA); normalImpulseBias = massNormal * (-normalVelocityBias + 0.0f); normalImpulseBias = gxtMath.Max(normalImpulseBias, 0.0f); Vector2 biasedImpulse = collisionResult.Normal * normalImpulseBias; geomB.RigidBody.ApplyImpulse(biasedImpulse, collisionResult.ContactPointB); biasedImpulse = -biasedImpulse; geomA.RigidBody.ApplyImpulse(biasedImpulse, collisionResult.ContactPointA); float maxTangentImpulse = combinedFrictionCoefficient * normalImpulse; f1 = 1.0f; Vector2 normCrossF = gxtMath.Cross2D(collisionResult.Normal, f1); float dvDotTangent = Vector2.Dot(dv, tangent); tangentImpulse = massTangent * (-dvDotTangent); tangentImpulse = gxtMath.Clamp(tangentImpulse, -maxTangentImpulse, maxTangentImpulse); Vector2 frictionImpulse = tangent * tangentImpulse; geomB.RigidBody.ApplyImpulse(frictionImpulse, collisionResult.ContactPointB); frictionImpulse = -frictionImpulse; geomA.RigidBody.ApplyImpulse(frictionImpulse, collisionResult.ContactPointA); /* End Post Step */ /* geomA.RigidBody.Update(dt); geomB.RigidBody.Update(dt); geomA.Update(); geomB.Update(); */ //gxtLog.WriteLineV(VerbosityLevel.INFORMATIONAL, "in collide"); /* Vector2 relativeVelocity = geomA.RigidBody.Velocity - geomB.RigidBody.Velocity; // relative velocity along normal if (!gxtMath.Equals(relativeVelocity, Vector2.Zero, float.Epsilon)) { float rvn = Vector2.Dot(relativeVelocity, collisionResult.Normal); if (!gxtMath.Equals(rvn, 0.0f, float.Epsilon)) { float f = -(1.0f + combinedRestitutionCoefficient) * rvn; //float nn = Vector2.Dot(collisionResult.Normal, collisionResult.Normal); float invMassSum = geomA.RigidBody.InverseMass + geomB.RigidBody.InverseMass; float denom = Vector2.Dot(collisionResult.Normal, collisionResult.Normal * invMassSum); float invja = 1.0f / (geomA.RigidBody.AngularAcceleration * geomA.RigidBody.Mass); float invjb = 1.0f / (geomB.RigidBody.AngularAcceleration * geomB.RigidBody.Mass); float ja = invja * gxtMath.Cross2D(collisionResult.Normal, collisionResult.ContactPointA); //ja *= gxtMath.Cross2D(collisionResult.ContactPointA, collisionResult.Normal); //ja = gxtMath.Cross2D(); float jb = invjb * gxtMath.Cross2D(collisionResult.Normal, collisionResult.ContactPointB); //jb *= gxtMath.Cross2D(collisionResult.ContactPointB, collisionResult.Normal); //float impulseDotN = collisionResult.Normal * (ja + jb); //denom *= (ja * jb); float fcopy = f; f /= denom; float foma = f / geomA.RigidBody.Mass; float fomb = f / geomB.RigidBody.Mass; Vector2 rigidAFinalVelocity = geomA.RigidBody.Velocity + collisionResult.Normal * foma; Vector2 rigidBFinalVelocity = geomB.RigidBody.Velocity - collisionResult.Normal * fomb; geomA.RigidBody.SetVelocity(rigidAFinalVelocity); geomB.RigidBody.SetVelocity(rigidBFinalVelocity); float angularMomentumA = geomA.RigidBody.AngularVelocity * geomA.RigidBody.Mass; float angularMomentumB = geomB.RigidBody.AngularVelocity * geomB.RigidBody.Mass; Vector2 fn = f * collisionResult.Normal; float finalAngularA = angularMomentumA + gxtMath.Cross2D(collisionResult.ContactPointA, fn); geomA.RigidBody.SetAngularVelocity(finalAngularA * geomA.RigidBody.InverseMass); float finalAngularB = angularMomentumB - gxtMath.Cross2D(collisionResult.ContactPointB, fn); geomB.RigidBody.SetAngularVelocity(finalAngularB * geomB.RigidBody.InverseMass); //geomA.RigidBody.Set //geomA.RigidBody.ApplyImpulse(rigidAFinalVelocity, collisionResult.ContactPointA); //geomB.RigidBody.ApplyImpulse(rigidBFinalVelocity, collisionResult.ContactPointB); } else { } } geomA.RigidBody.Translate(collisionResult.Normal * -collisionResult.Depth); geomB.RigidBody.Translate(collisionResult.Normal * collisionResult.Depth); // translate it out?? geomB.RigidBody.Update(dt); geomA.RigidBody.Update(dt); */ return true; }
public static void Solve(gxtGeom geomA, gxtGeom geomB, gxtCollisionResult collisionResult, float dt) { // no intersection means there's nothing to solve gxtDebug.Assert(collisionResult.Intersection); if (geomA.HasAttachedBody() && geomB.HasAttachedBody()) { combinedFrictionCoefficient = GetCombinedFriction(geomA.RigidBody, geomB.RigidBody); combinedRestitutionCoefficient = GetCombinedRestitution(geomA.RigidBody, geomB.RigidBody); } // early return for trigger geoms if (CheckGeomResponse(ref geomA, ref geomB, ref collisionResult)) return; // earlier exit for one fixed, one rigid if (CheckOneRigidOneFixedResponse(ref geomA, ref geomB, ref collisionResult, dt)) return; if (CheckRigidResponse(ref geomA, ref geomB, ref collisionResult, dt)) return; }
/// <summary> /// /// </summary> /// <param name="sphere"></param> /// <param name="hitGeom"></param> /// <param name="collisionGroupName"></param> /// <returns></returns> public bool SphereCast(gxtSphere sphere, out gxtGeom hitGeom, string collisionGroupName) { gxtDebug.Assert(collisionGroupsMap.ContainsKey(collisionGroupName), "Named Collision Group: {0} Does Not Exist In Physics World"); gxtCollisionGroup cgroup = collisionGroupsMap[collisionGroupName]; return SphereCast(sphere, out hitGeom, cgroup); }
/// <summary> /// /// </summary> /// <param name="sphere"></param> /// <param name="hitGeom"></param> /// <param name="collisionGroup"></param> /// <returns></returns> public bool SphereCast(gxtSphere sphere, out gxtGeom hitGeom, gxtCollisionGroup collisionGroup = gxtCollisionGroup.ALL) { hitGeom = null; List<gxtGeom> geoms; if (SphereCastAll(sphere, out geoms, collisionGroup)) { float minDist = float.MaxValue; float tmpDist; for (int i = 0; i < geoms.Count; i++) { tmpDist = (sphere.Position - geoms[i].GetWorldCentroid()).LengthSquared(); if (tmpDist < minDist) { hitGeom = geoms[i]; minDist = tmpDist; } } return true; } return false; }
public void Initialize(Vector2 initPos, float speed = 3.0f, float maxSpeed = 500.0f) { hashedString = new gxtHashedString("player_actor"); this.position = initPos; this.rotation = 0.0f; // if we were to take a rotation be sure to use gxtMath.WrapAngle(initRot) MoveSpeed = speed; MaxSpeed = maxSpeed; this.clipMode = asgClipMode.NORMAL; // in physics world units // setup body playerBody = new gxtRigidBody(); playerBody.Mass = 2.0f; playerBody.CanSleep = false; // should NEVER go to sleep playerBody.Awake = true; playerBody.FixedRotation = true; playerBody.IgnoreGravity = false; playerBody.Position = position; playerBody.Rotation = rotation; world.AddRigidBody(playerBody); // setup geom //playerPolygon = gxtGeometry.CreateRectanglePolygon(2, 3.5f); playerPolygon = gxtGeometry.CreateRoundedRectanglePolygon(2.0f, 3.5f, 0.45f, 0.05f); //playerPolygon = gxtGeometry.CreateEllipsePolygon(1.0f, 1.75f, 20); //playerPolygon = gxtGeometry.CreateCapsulePolygon(3.0f, 1.0f, 8); //playerPolygon = gxtGeometry.CreateCirclePolygon(3.0f, 3); playerGeom = new gxtGeom(playerPolygon, position, rotation); playerGeom.Tag = this; playerGeom.CollidesWithGroups = world.PhysicsWorld.GetCollisionGroup("traversable_world_geometry"); playerGeom.CollisionGroups = world.PhysicsWorld.GetCollisionGroup("player"); playerGeom.RigidBody = playerBody; playerGeom.OnCollision += OnCollision; playerGeom.OnSeperation += OnSeperation; world.PhysicsWorld.AddGeom(playerGeom); // setup scene node // for now we'll just use a line loop but programming it // this way makes it easy to swap out for something like a skeleton // or a texture later down the road scenePoly = gxtPolygon.Copy(playerPolygon); scenePoly.Scale(gxtPhysicsWorld.PHYSICS_SCALE); //playerEntity = new gxtLineLoop(scenePoly.v); // setup drawable //playerDrawable = new gxtDrawable(playerEntity, Color.Yellow, true, 0.1f); playerSceneNode = new gxtSceneNode(); playerSceneNode.Position = playerBody.Position; //playerSceneNode.AttachDrawable(playerDrawable); //world.AddSceneNode(playerSceneNode); // setup raycatsing logic rayCastTimer = new gxtStopWatch(true); world.AddProcess(rayCastTimer); raycasts = new List<gxtRayHit>(); clipMode = asgClipMode.NORMAL; this.halfHeight = playerGeom.LocalAABB.Height * 0.5f; }
public bool OnCollision(gxtGeom playerGeom, gxtGeom otherGeom, gxtCollisionResult collisionResult) { incrementSeperationTime = false; //collidingWithWalkableGeom = true; return true; }
public void AddGeom(gxtGeom geom) { physicsWorld.AddGeom(geom); }
public gxtSAPBox(gxtGeom geom) { this.geom = geom; }
public void RemoveGeom(gxtGeom geom) { physicsWorld.RemoveGeom(geom); }
private bool OnOneWayPlatformCollision(gxtGeom ga, gxtGeom gb, gxtCollisionResult cr) { float tolerance = 0.5f; if (ga == geomC) { //gxtLog.WriteLineV(gxtVerbosityLevel.INFORMATIONAL, "here"); float dot = Vector2.Dot(cr.Normal, Vector2.UnitY); if (dot >= tolerance) { //if (gb.HasAttachedBody() && Vector2.Dot(gb.RigidBody.PrevAcceleration, Vector2.UnitY) <= 0.0f) return false; } else { gxtRayHit rayHit; gxtRay downRay = new gxtRay(); downRay.Origin = gb.GetWorldCentroid() - new Vector2(0.0f, geomF.LocalAABB.Height * 0.45f); downRay.Direction = Vector2.UnitY; float halfHeight = geomF.LocalAABB.Height * 0.65f; if (world.PhysicsWorld.RayCast(downRay, out rayHit, gxtCollisionGroup.ALL, halfHeight)) { gxtRay adjRay = new gxtRay(downRay.Origin * gxtPhysicsWorld.PHYSICS_SCALE, downRay.Direction); gxtDebugDrawer.Singleton.AddRay(adjRay, rayHit.Distance * gxtPhysicsWorld.PHYSICS_SCALE, Color.Green, 0.0f, TimeSpan.FromSeconds(5.0)); return false; } else { //return false; gxtRay adjRay = new gxtRay(downRay.Origin * gxtPhysicsWorld.PHYSICS_SCALE, downRay.Direction); gxtDebugDrawer.Singleton.AddRay(adjRay, halfHeight * gxtPhysicsWorld.PHYSICS_SCALE, Color.Green, 0.0f, TimeSpan.FromSeconds(5.0)); //return false; } } //else if (gb.HasAttachedBody() && Vector2.Dot(gb.RigidBody.PrevAcceleration, Vector2.UnitY)) } else { gxtDebug.Assert(false, "You didn't set up the swap properly"); } /* else if (gb == geomC) { float dot = Vector2.Dot(cr.Normal, new Vector2(0.0f, -1.0f)); if (dot >= tolerance) { if (gb.HasAttachedBody() && Vector2.Dot(gb.RigidBody.PrevAcceleration, new Vector2(0.0f, -1.0f)) >= 0.0f) return false; } } */ return true; }
private gxtGeom CreatePlatformGeom(gxtPolygon polygon, Vector2 position) { gxtGeom platGeom = new gxtGeom(polygon, true); gxtRigidBody platBody = new gxtRigidBody(); platBody.MotionType = gxtRigidyBodyMotion.FIXED; platBody.CanSleep = false; platBody.Awake = true; platGeom.RigidBody = platBody; gxtPhysicsMaterial mat = new gxtPhysicsMaterial(0.6f, 0.3f); platGeom.CollisionGroups = world.PhysicsWorld.GetCollisionGroup("traversable_world_geometry"); platGeom.CollidesWithGroups = world.PhysicsWorld.GetCollisionGroup("player"); platGeom.Material = mat; platGeom.SetPosition(new Vector2(0.0f, 8.5f)); world.AddGeom(platGeom); return platGeom; }
public bool OnCollision(gxtGeom geomA, gxtGeom geomB, gxtCollisionResult collisionResult) { return true; }
/// <summary> /// Returns one geom intersected by the pt which will collide with the given collision group /// In cases where multiple geoms are intersected by the point, the geom is chosen whose centroid /// is closest to the point /// </summary> /// <param name="pt">Pt</param> /// <param name="hitGeom">Intersected Geom</param> /// <param name="collisionGroupName">Collision Group</param> /// <returns>Returns true if a geom is intersected by the point</returns> public bool PointCast(Vector2 pt, out gxtGeom hitGeom, string collisionGroupName) { gxtDebug.Assert(collisionGroupsMap.ContainsKey(collisionGroupName), "Named Collision Group: {0} Does Not Exist In Physics World"); gxtCollisionGroup cgroup = collisionGroupsMap[collisionGroupName]; return PointCast(pt, out hitGeom, cgroup); }
public void OnSeperation(gxtGeom geomA, gxtGeom geomB) { //gxtLog.WriteLineV(gxtVerbosityLevel.INFORMATIONAL, "Seperation between {0} and {1}", geomA.Id, geomB.Id); }
private void CreateGeom(Vector2 min, Vector2 max, float density) { gxtGeom g = new gxtGeom(); g.CollidesWithGroups = gxtCollisionGroup.ALL; g.CollisionEnabled = true; g.CollisionGroups = gxtCollisionGroup.ALL; g.CollisionResponseEnabled = true; g.Polygon = gxtGeometry.CreateRectanglePolygon(max.X - min.X, max.Y - min.Y); g.Material = new gxtPhysicsMaterial(0.85f, 0.45f); gxtRigidBody b = new gxtRigidBody(); b.IgnoreGravity = false; b.Mass = density * g.Polygon.GetArea(); gxtLog.WriteLineV(gxtVerbosityLevel.INFORMATIONAL, "mass: {0}", b.Mass); b.Inertia = gxtRigidBody.GetInertiaForRectangle(max.X - min.X, max.Y - min.Y, b.Mass); b.MotionType = gxtRigidyBodyMotion.DYNAMIC; //b.Material = new gxtPhysicsMaterial(0.85f, 0.45f); b.Position = ((min + max) * 0.5f); b.Damping = 0.9995f; g.RigidBody = b; geoms.Add(g); bodies.Add(b); world.AddGeom(g); world.AddRigidBody(b); }
public override void Initialize(bool setupDebugDrawing = true) { base.Initialize(); world = new gxtWorld(); world.Initialize(true, "ASG Prototype"); gxtDisplayManager.Singleton.WindowTitle = "ASG Prototype"; if (setupDebugDrawing) { if (gxtDebugDrawer.SingletonIsInitialized) { debugDrawId = gxtDebugDrawer.Singleton.GetNewId(); gxtDebugDrawer.Singleton.AddSceneGraph(debugDrawId, world.SceneGraph); gxtDebugDrawer.Singleton.DebugFont = gxtResourceManager.Singleton.Load<Microsoft.Xna.Framework.Graphics.SpriteFont>("Fonts\\debug_font"); } else { gxtLog.WriteLineV(gxtVerbosityLevel.WARNING, "Cannot Set Up Debug Drawing For The Gameplay Screen Because the Debug Drawer Has Not Been Initialized"); } } gxtLog.WriteLineV(gxtVerbosityLevel.SUCCESS, "Initialized GXT World \"{0}\"", world.Name); gxtLog.WriteLineV(gxtVerbosityLevel.INFORMATIONAL, "Populating world..."); world.PhysicsWorld.AddCollisionGroupName("player", gxtCollisionGroup.GROUP1); world.PhysicsWorld.AddCollisionGroupName("traversable_world_geometry", gxtCollisionGroup.GROUP2); // setup player asgPlayerActor player = new asgPlayerActor(world); player.Initialize(Vector2.Zero, 6.5f); world.AddActor(player); // player controller asgPlayerController playerController = new asgPlayerController(); playerController.Initialize(player); world.AddController(playerController); // camera controller asgCameraController cameraController = new asgCameraController(world.Camera); cameraController.Initialize(asgCameraMode.AUTONOMOUS, player, 1.0f, new Vector2(0.0f, -3.5f)); world.AddController(cameraController); // geoms (platforms and walls) gxtPolygon platformPolygon = gxtGeometry.CreateRectanglePolygon(15.0f, 2.0f); CreatePlatformGeom(platformPolygon, new Vector2(0.0f, 8.5f)); // dynamic box gxtRigidBody boxBody = new gxtRigidBody(); boxBody.Mass = 1.0f; boxBody.CanSleep = false; boxBody.Awake = true; gxtPolygon box = gxtGeometry.CreateRectanglePolygon(1.5f, 1.5f); gxtGeom boxGeom = new gxtGeom(box, true); boxGeom.RigidBody = boxBody; boxBody.Inertia = gxtRigidBody.GetInertiaForRectangle(1.5f, 1.5f, boxBody.Mass); boxBody.Position = new Vector2(-3.5f, -3.5f); world.AddGeom(boxGeom); world.AddRigidBody(boxBody); gxtLog.WriteLineV(gxtVerbosityLevel.INFORMATIONAL, "Done populating world..."); }
/// <summary> /// Checks if it is possible for two geoms to collide given their settings /// Optional AABB test is available /// </summary> /// <param name="geomA">Geom A</param> /// <param name="geomB">Geom B</param> /// <param name="testAABB">Optional AABB test</param> /// <returns>If the two geoms can collide</returns> public bool CanCollide(gxtGeom geomA, gxtGeom geomB, bool testAABB = false) { if (!geomA.CollisionEnabled || !geomB.CollisionEnabled) return false; if ((geomA.CollisionGroups & geomB.CollidesWithGroups) == gxtCollisionGroup.NONE || (geomA.CollidesWithGroups & geomB.CollisionGroups) == gxtCollisionGroup.NONE) return false; if (testAABB) if (!gxtAABB.Intersects(geomA.AABB, geomB.AABB)) return false; return true; }