Created
April 10, 2017 12:35
XNA-FNA Physics in one file
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#if FNA || XNA | |
using Microsoft.Xna.Framework; | |
using Microsoft.Xna.Framework.Graphics; | |
#endif | |
using System; | |
namespace Android_Invaders | |
{ | |
struct Object | |
{ | |
public float restitution; | |
public Vector2 velocity; | |
public float mass; | |
} | |
struct AABB | |
{ | |
public Vector2 min; | |
public Vector2 max; | |
}; | |
struct Circle | |
{ | |
public float radius; | |
public Vector2 position; | |
}; | |
public class Physics | |
{ | |
public float Gravity; | |
public Physics(float val) | |
{ | |
Gravity = val; | |
} | |
bool AABBvsAABB(AABB a, AABB b) | |
{ | |
// Exit with no intersection if found separated along an axis | |
if (a.max.X < b.min.X || a.min.X > b.max.X) return false; | |
if (a.max.Y < b.min.Y || a.min.Y > b.max.Y) return false; | |
// No separating axis found, therefore there is at least one overlapping axis | |
return true; | |
} | |
float Distance(Vector2 a, Vector2 b) | |
{ | |
return (float)Math.Sqrt(Math.Pow((double)a.X - b.X, 2) + Math.Pow((double)a.Y - b.Y, 2)); | |
} | |
bool CirclevsCircleUnoptimized(Circle a, Circle b) | |
{ | |
float r = a.radius + b.radius; | |
return r < Distance(a.position, b.position); | |
} | |
bool CirclevsCircleOptimized(Circle a, Circle b) | |
{ | |
float r = a.radius + b.radius; | |
r *= r; | |
return (r < (float)Math.Pow((double)(a.position.X + b.position.X), 2) + Math.Pow((double)(a.position.Y + b.position.Y), 2)); | |
} | |
float GetRestitution(Object A, Object B) | |
{ | |
// Given two objects A and B | |
return Math.Min(A.restitution, B.restitution); | |
} | |
void ResolveCollision(ref Object A, ref Object B) | |
{ | |
// Calculate relative velocity | |
Vector2 rv = B.velocity - A.velocity; | |
// Calculate relative velocity in terms of the normal direction | |
float velAlongNormal = Vector2.Dot(rv, Vector2.Normalize(A.velocity)); | |
// Do not resolve if velocities are separating | |
if (velAlongNormal > 0) | |
return; | |
// Calculate restitution | |
float e = Math.Min(A.restitution, B.restitution); | |
// Calculate impulse scalar | |
float j = -(1 + e) * velAlongNormal; | |
j /= 1 / A.mass + 1 / B.mass; | |
// Apply impulse | |
Vector2 impulse = j * Vector2.Normalize(A.velocity); | |
A.velocity -= 1 / A.mass * impulse; | |
B.velocity += 1 / B.mass * impulse; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment