Skip to content

Instantly share code, notes, and snippets.

@msmshazan
Created April 10, 2017 12:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save msmshazan/d9be6d6c693a43fb861ec73d7f4493bc to your computer and use it in GitHub Desktop.
Save msmshazan/d9be6d6c693a43fb861ec73d7f4493bc to your computer and use it in GitHub Desktop.
XNA-FNA Physics in one file
#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