/******************************************************************************/ /*! \file Physics.cs \author Kevin Carey Physics related objects and functionality Copyright © 2007 DigiPen(USA) Corporation. All rights reserved. */ /******************************************************************************/ using Microsoft.Xna.Framework; using System.Collections.Generic; using System; namespace Shooting_Range { // Circle class // Represents a circle. Kind of surprised this isnt a default class in XNA class Circle { // Constructors public Circle() { Center = Vector2.Zero; Radius = 0.0f; } public Circle(Vector2 center, float radius) { Center = center; Radius = radius; } // PointCollision function // Returns true is a point is within a circle (presumably on the same plane) public bool PointCollision(Vector2 point) { // Get the distance squared between the point and the center float distance = ((point.X - Center.X) * (point.X - Center.X)) + ((point.Y - Center.Y) * (point.Y - Center.Y)); // If the distance is less than the circle's redius squared if (distance < (Radius * Radius)) { // The point is within the circle, return true return true; } // Else, return false return false; } // Center of the circle public Vector2 Center; // Radius of the circle public float Radius; } // CirclePlane class // Represents collision information for a circle on a plane class CirclePlane { // Constructors public CirclePlane() { m_Plane = new Plane(); m_Circle = new Circle(); } public CirclePlane(Plane plane, Circle circle) { m_Plane = plane; m_Circle = circle; } // Plane get and set public Plane plane { get { return m_Plane; } set { m_Plane = value; } } // Circle get and set public Circle circle { get { return m_Circle; } set { m_Circle = value; } } // The plane which the object is on private Plane m_Plane; // The circle on said plane representing the collision private Circle m_Circle; } // Physics class // Represents the physics of an object class Physics : ICloneable { // Constructors public Physics() { m_VelocityDirection = Vector3.Zero; m_Gravity = 0.0f; m_CollisionData = new List(); } public Physics(Vector3 velocityDirection) { m_VelocityDirection = velocityDirection; m_Gravity = 0.0f; m_CollisionData = new List(); } public Physics(Vector3 velocityDirection, float gravity) { m_VelocityDirection = velocityDirection; m_Gravity = gravity; m_CollisionData = new List(); } // ICloneable Clone function. I think that being forced to cast from the object type is a pain public object Clone() { Physics clone = new Physics(m_VelocityDirection, m_Gravity); for (int i = 0; i < m_CollisionData.Count; ++i) { clone.AddCollisionData(new CirclePlane( new Plane(m_CollisionData[i].plane.Normal, m_CollisionData[i].plane.D), new Circle(m_CollisionData[i].circle.Center, m_CollisionData[i].circle.Radius))); } return clone; } // So I fixed it with this function public Physics ClonePhysics() { return (Physics)Clone(); } // Velocity get and set public Vector3 VelocityDirection { get { return m_VelocityDirection; } set { m_VelocityDirection = value; } } // X component of the velocity get and set public float VelocityDirectionX { get { return m_VelocityDirection.X; } set { m_VelocityDirection.X = value; } } // Y component of the velocity get and set public float VelocityDirectionY { get { return m_VelocityDirection.Y; } set { m_VelocityDirection.Y = value; } } // Z component of the velocity get and set public float VelocityDirectionZ { get { return m_VelocityDirection.Z; } set { m_VelocityDirection.Z = value; } } // Gravity get and set public float Gravity { get { return m_Gravity; } set { m_Gravity = value; } } // Collision Data get and set public List CollisionData { get { return m_CollisionData; } set { m_CollisionData = value; } } // AddCollisionData function public void AddCollisionData(CirclePlane circlePlane) { // Add the CirclePlane to the list m_CollisionData.Add(circlePlane); } // CheckRaycollision function // Returns the point of collision if one exists, and null if there is no collision public Vector3? CheckRayCollision(Ray ray) { // For each CirclePlane collision data for (int i = 0; i < m_CollisionData.Count; ++i) { // Get the CirclePlane CirclePlane circlePlane = m_CollisionData[i]; // Get the float intersection of the given ray with the plane float? rayCollision = ray.Intersects(circlePlane.plane); // If there is a collision if (rayCollision != null && rayCollision.GetValueOrDefault() <= 1.0f) { // Get the Vector3 intersection of the given ray with the plane Vector3 planeCollision = ray.Position + (ray.Direction * rayCollision.GetValueOrDefault()); // If the point of collision in the plane is within the circle if (circlePlane.circle.PointCollision(new Vector2(planeCollision.X, planeCollision.Y))) { // Return the point of collision return planeCollision; } } } // If no collision has been found, return null return null; } // Direction in which the object moves // Do not normalize private Vector3 m_VelocityDirection; // Gravity factor private float m_Gravity; // Collision data private List m_CollisionData; } }