Monday, June 7, 2010

The Camera Class

This is the Camera Class you will need for the Demo


Note that the full visual studio project can be downloaded from source forge
https://sourceforge.net/projects/aphysicsengine/


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;
using PhysicsEngine;

namespace WindowsGame1
{
public class Camera
{

public Vector3 cameraPosition, cameraTarget, cameraUpVector;
public float fieldOfView, aspectRatio, nearPlaneDistance, farPlaneDistance;

public Camera(Vector3 cameraPosition, Vector3 cameraTarget, Vector3 cameraUpVector, float fieldOfView, float aspectRatio, float nearPlaneDistance, float farPlaneDistance)
{
this.cameraPosition = cameraPosition;
this.cameraTarget = cameraTarget;
this.cameraUpVector = cameraUpVector;
this.fieldOfView = fieldOfView;
this.aspectRatio = aspectRatio;
this.nearPlaneDistance = nearPlaneDistance;
this.farPlaneDistance = farPlaneDistance;
}

public Matrix View
{
get
{
return Matrix.CreateLookAt(cameraPosition, cameraTarget, cameraUpVector);
}
}

public Matrix Projection
{
get
{
return Matrix.CreatePerspectiveFieldOfView
(
fieldOfView,
aspectRatio,
nearPlaneDistance,
farPlaneDistance
);
}
}

public void Draw(DefaultEntity entity, Model model)
{
Matrix[] boneTransforms = new Matrix[model.Bones.Count];
Matrix rotation = entity.Rotation;
Matrix position = Matrix.CreateTranslation(entity.Position);
model.Root.Transform = Matrix.Identity * rotation * position;
model.CopyAbsoluteBoneTransformsTo(boneTransforms);

foreach (ModelMesh mesh in model.Meshes)
{
foreach (BasicEffect effect in mesh.Effects)
{
effect.EnableDefaultLighting();
effect.World = boneTransforms[mesh.ParentBone.Index];
effect.View = this.View;
effect.Projection = this.Projection;
}
mesh.Draw();
}
}
}
}

Sunday, June 6, 2010

Using the Engine - The main points to know

You will need visual studio with XNA installed

link to the dynamic code library "physics engine.dll"

once you have done this you can import the physics engine

using PhysicsEngine;

To create a new environment

PhysicsEngine.Environment world = new PhysicsEngine.Environment();

Loading the hull

System.IO.StreamReader streamReader = new System.IO.StreamReader("..//..//..//Content//Hulls//box.hull"); 
ConvexSegment segment = CommonFunctions.LoadConvexHull(streamReader);
Matrix rotation = Matrix.CreateFromYawPitchRoll(0, 0, 0);
ConvexHull hull = new ConvexHull(segment, Vector3.Zero, rotation);
ConvexHull[] hulls = new ConvexHull[] { hull };
wholeHull = new Hull(hulls);


Creating new world entities
firstBox = new DefaultEntity (Vector3.Zero, Vector3.Up, 1.0f, 2.0f, wholeHull, new ElasticCollision(1), parameters, 0 ); 
Vector3 orientation = Vector3.One; 
orientation.Normalize(); 
secondBox = new DefaultEntity (new Vector3(0.5f, 2, 0), orientation, 1.0f, 2.0f, wholeHull, new ElasticCollision(1), parameters, 0);

Adding the entities to the environment

world.Add(firstBox); world.Add(secondBox);

Update the physics engine (nothing will move if this is not called while the game runs)
world.Update((float)gameTime.ElapsedGameTime.TotalSeconds);


The full code is below




using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;
using PhysicsEngine;

namespace WindowsGame1
{
/// <summary>
/// This is the main type for your game
/// </summary>
public class Game1 : Microsoft.Xna.Framework.Game
{
Camera camera;

GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;

PhysicsEngine.Environment world = new PhysicsEngine.Environment();

Model boxModel;
Hull wholeHull;
PhysicsEngine.DefaultEntity firstBox;
PhysicsEngine.DefaultEntity secondBox;
PhysicsParameters parameters = new PhysicsParameters();



public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
}

/// <summary>
/// Allows the game to perform any initialization it needs to before starting to run.
/// This is where it can query for any required services and load any non-graphic
/// related content. Calling base.Initialize will enumerate through any components
/// and initialize them as well.
/// </summary>
protected override void Initialize()
{
this.camera = new Camera
(
new Vector3(1, 1, 20),
new Vector3(0, 1, 0),
Vector3.Up,
MathHelper.PiOver4,
(float)graphics.GraphicsDevice.Viewport.Width / (float)graphics.GraphicsDevice.Viewport.Height,
1f,
1000
);
parameters.Gravity = Vector3.Zero;
parameters.WindSpeed = Vector3.Zero;
base.Initialize();
}

/// <summary>
/// LoadContent will be called once per game and is the place to load
/// all of your content.
/// </summary>
protected override void LoadContent()
{
// Create a new SpriteBatch, which can be used to draw textures.
spriteBatch = new SpriteBatch(GraphicsDevice);

boxModel = Content.Load<Model>("Models\\box");

System.IO.StreamReader streamReader = new System.IO.StreamReader("..//..//..//Content//Hulls//box.hull");
ConvexSegment segment = CommonFunctions.LoadConvexHull(streamReader);

Matrix rotation = Matrix.CreateFromYawPitchRoll(0, 0, 0);

ConvexHull hull = new ConvexHull(segment, Vector3.Zero, rotation);

ConvexHull[] hulls = new ConvexHull[] { hull };

wholeHull = new Hull(hulls);

firstBox = new DefaultEntity
(
Vector3.Zero,
Vector3.Up,
1.0f,
2.0f,
wholeHull,
new ElasticCollision(1),
parameters,
0
);
Vector3 orientation = Vector3.One;
orientation.Normalize();
secondBox = new DefaultEntity
(
new Vector3(0.5f, 2, 0),
orientation,
1.0f,
2.0f,
wholeHull,
new ElasticCollision(1),
parameters,
0
);


world.Add(firstBox);
world.Add(secondBox);
}

/// <summary>
/// UnloadContent will be called once per game and is the place to unload
/// all content.
/// </summary>
protected override void UnloadContent()
{
// TODO: Unload any non ContentManager content here
}

/// <summary>
/// Allows the game to run logic such as updating the world,
/// checking for collisions, gathering input, and playing audio.
/// </summary>
/// <param name="gameTime">Provides a snapshot of timing values.</param>
protected override void Update(GameTime gameTime)
{
if (Keyboard.GetState().IsKeyDown(Keys.Escape))
this.Exit();

if (Keyboard.GetState().IsKeyDown(Keys.Enter))
{
Vector3 v = (secondBox.Position - firstBox.Position);
v.Normalize();
firstBox.Velocity = 2 * v;
}

if (Keyboard.GetState().IsKeyDown(Keys.PageUp))
{
Vector3 shift = camera.cameraUpVector;
camera.cameraPosition += shift;
camera.cameraTarget += shift;
}

if (Keyboard.GetState().IsKeyDown(Keys.PageDown))
{
Vector3 shift = -1 * camera.cameraUpVector;
camera.cameraPosition += shift;
camera.cameraTarget += shift;
}

if (Keyboard.GetState().IsKeyDown(Keys.D))
{
Vector3 to = camera.cameraTarget - camera.cameraPosition;
to.Normalize();
Vector3 shift = Vector3.Cross(to, camera.cameraUpVector);
camera.cameraPosition += shift;
camera.cameraTarget += shift;
}

if (Keyboard.GetState().IsKeyDown(Keys.A))
{
Vector3 to = camera.cameraTarget - camera.cameraPosition;
to.Normalize();
Vector3 shift = Vector3.Cross(camera.cameraUpVector, to);
camera.cameraPosition += shift;
camera.cameraTarget += shift;
}

//boom
if (Keyboard.GetState().IsKeyDown(Keys.W))
{
Vector3 shift = camera.cameraTarget - camera.cameraPosition;
shift.Normalize();
camera.cameraPosition += shift;
camera.cameraTarget += shift;
}

if (Keyboard.GetState().IsKeyDown(Keys.S))
{
Vector3 shift = camera.cameraPosition - camera.cameraTarget;
shift.Normalize();
camera.cameraPosition += shift;
camera.cameraTarget += shift;
}

//Rotate
if (Keyboard.GetState().IsKeyDown(Keys.Left))
{
Vector3 toVector = camera.cameraTarget - camera.cameraPosition;
Matrix rotate = Matrix.CreateFromAxisAngle(camera.cameraUpVector, 3.141592653589f / 500);
Quaternion q = Quaternion.CreateFromRotationMatrix(rotate);
Vector3 newTo = Vector3.Transform(toVector, q);
camera.cameraTarget = camera.cameraPosition + newTo;
}

if (Keyboard.GetState().IsKeyDown(Keys.Right))
{
Vector3 toVector = camera.cameraTarget - camera.cameraPosition;
Matrix rotate = Matrix.CreateFromAxisAngle(camera.cameraUpVector * -1, 3.141592653589f / 500);
Quaternion q = Quaternion.CreateFromRotationMatrix(rotate);
Vector3 newTo = Vector3.Transform(toVector, q);
camera.cameraTarget = camera.cameraPosition + newTo;
}

//Roll
if (Keyboard.GetState().IsKeyDown(Keys.RightShift))
{
Vector3 toVector = camera.cameraTarget - camera.cameraPosition;
Matrix rotate = Matrix.CreateFromAxisAngle(toVector, 3.141592653589f / 10000);
Quaternion q = Quaternion.CreateFromRotationMatrix(rotate);
Vector3 newUp = Vector3.Transform(camera.cameraUpVector, q);
camera.cameraUpVector = newUp;
}

if (Keyboard.GetState().IsKeyDown(Keys.LeftShift))
{
Vector3 toVector = camera.cameraTarget - camera.cameraPosition;
Matrix rotate = Matrix.CreateFromAxisAngle(toVector * -1, 3.141592653589f / 10000);
Quaternion q = Quaternion.CreateFromRotationMatrix(rotate);
Vector3 newUp = Vector3.Transform(camera.cameraUpVector, q);
camera.cameraUpVector = newUp;
}

//pitch
if (Keyboard.GetState().IsKeyDown(Keys.Up))
{
Vector3 toVector = camera.cameraTarget - camera.cameraPosition;
Vector3 right = Vector3.Cross(toVector, camera.cameraUpVector);
right.Normalize();
Matrix rotate = Matrix.CreateFromAxisAngle(right, 3.141592653589f / 500);
Quaternion q = Quaternion.CreateFromRotationMatrix(rotate);

Vector3 newUp = Vector3.Transform(camera.cameraUpVector, q);
Vector3 newTo = Vector3.Transform(toVector, q);

camera.cameraUpVector = newUp;
camera.cameraTarget = camera.cameraPosition + newTo;
}

//pitch
if (Keyboard.GetState().IsKeyDown(Keys.Down))
{
Vector3 toVector = camera.cameraTarget - camera.cameraPosition;
Vector3 left = Vector3.Cross(camera.cameraUpVector, toVector);
left.Normalize();
Matrix rotate = Matrix.CreateFromAxisAngle(left, 3.141592653589f / 500);
Quaternion q = Quaternion.CreateFromRotationMatrix(rotate);

Vector3 newUp = Vector3.Transform(camera.cameraUpVector, q);
Vector3 newTo = Vector3.Transform(toVector, q);

camera.cameraUpVector = newUp;
camera.cameraTarget = camera.cameraPosition + newTo;
}

world.Update((float)gameTime.ElapsedGameTime.TotalSeconds);

base.Update(gameTime);
}

/// <summary>
/// This is called when the game should draw itself.
/// </summary>
/// <param name="gameTime">Provides a snapshot of timing values.</param>
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);

camera.Draw(firstBox, boxModel);
camera.Draw(secondBox, boxModel);

base.Draw(gameTime);
}
}
}







Introduction to the APE Physics Engine

Language: C#

Requires XNA

Suitable for XBox and PC Games

Features:

- Collision Detection for convex hulls
- Elastic collision handling
- Customizable collision handling/forces/laws of physics