diff --git a/Extras/XNAPhysics/Physics.sln b/Extras/XNAPhysics/Physics.sln new file mode 100644 index 000000000..078fda410 --- /dev/null +++ b/Extras/XNAPhysics/Physics.sln @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual C# Express 2005 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Physics", "Physics\Physics.csproj", "{4AA0A1F5-0F11-4D86-9D43-85A12835572F}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {4AA0A1F5-0F11-4D86-9D43-85A12835572F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4AA0A1F5-0F11-4D86-9D43-85A12835572F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4AA0A1F5-0F11-4D86-9D43-85A12835572F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4AA0A1F5-0F11-4D86-9D43-85A12835572F}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/Extras/XNAPhysics/Physics/BoundingBox.cs b/Extras/XNAPhysics/Physics/BoundingBox.cs new file mode 100644 index 000000000..d2ba9343a --- /dev/null +++ b/Extras/XNAPhysics/Physics/BoundingBox.cs @@ -0,0 +1,143 @@ +using System; +using System.Collections.Generic; +using System.Text; +using Microsoft.Xna.Framework.Graphics; +using Microsoft.Xna.Framework; + +namespace Physics +{ + /// + /// This bounding volume is represented by a box. + /// + public class BoundingBox : BoundingVolume + { + #region Constructor: BoundingBox(float width, float height, float depth, Color color, GraphicsDevice device) + + /// + /// Creates a new bounding box. + /// + /// The width of the box. + /// The height of the box. + /// The depth of the box. + /// The color of the box. + /// The rendering device. + public BoundingBox(float width, float height, float depth, Color color, GraphicsDevice device) + : base(color, device) + { + #region Vertex Buffer + + // Define the vertices + VertexPositionColor[] tempVertices = new VertexPositionColor[8]; + float halfWidth = width / 2f; + float halfHeight = height / 2f; + float halfDepth = depth / 2f; + + // Define the 8 corners. + tempVertices[0] = new VertexPositionColor(new Vector3(-halfWidth, -halfHeight, halfDepth), Color.White); + tempVertices[1] = new VertexPositionColor(new Vector3(-halfWidth, -halfHeight, -halfDepth), Color.White); + tempVertices[2] = new VertexPositionColor(new Vector3(halfWidth, -halfHeight, -halfDepth), Color.White); + tempVertices[3] = new VertexPositionColor(new Vector3(halfWidth, -halfHeight, halfDepth), Color.White); + tempVertices[4] = new VertexPositionColor(new Vector3(-halfWidth, halfHeight, halfDepth), Color.White); + tempVertices[5] = new VertexPositionColor(new Vector3(-halfWidth, halfHeight, -halfDepth), Color.White); + tempVertices[6] = new VertexPositionColor(new Vector3(halfWidth, halfHeight, -halfDepth), Color.White); + tempVertices[7] = new VertexPositionColor(new Vector3(halfWidth, halfHeight, halfDepth), Color.White); + + // Initialize the vertex buffer. + this.vertexbuffer = new VertexBuffer(device, typeof(VertexPositionColor), 8, ResourceUsage.None, ResourcePool.Default); + + // Set the vertices. + this.vertexbuffer.SetData(tempVertices); + + // Set other info. + this.numberOfPrimitive = 12; + this.numberOfVertices = 8; + + #endregion + + #region Index Buffer + + // Define the index buffer. + int[] tempIndices = new int[12 * 3]; + + // Front face. + tempIndices[0] = 0; + tempIndices[1] = 4; + tempIndices[2] = 7; + tempIndices[3] = 0; + tempIndices[4] = 7; + tempIndices[5] = 3; + + // Back face. + tempIndices[6] = 2; + tempIndices[7] = 6; + tempIndices[8] = 5; + tempIndices[9] = 2; + tempIndices[10] = 5; + tempIndices[11] = 1; + + // Left face. + tempIndices[12] = 1; + tempIndices[13] = 5; + tempIndices[14] = 4; + tempIndices[15] = 1; + tempIndices[16] = 4; + tempIndices[17] = 0; + + // Right face. + tempIndices[18] = 4; + tempIndices[19] = 7; + tempIndices[20] = 6; + tempIndices[21] = 4; + tempIndices[22] = 6; + tempIndices[23] = 3; + + // Up face. + tempIndices[24] = 4; + tempIndices[25] = 5; + tempIndices[26] = 6; + tempIndices[27] = 4; + tempIndices[28] = 6; + tempIndices[29] = 7; + + // Down face. + tempIndices[30] = 0; + tempIndices[31] = 2; + tempIndices[32] = 1; + tempIndices[33] = 0; + tempIndices[34] = 3; + tempIndices[35] = 2; + + // Initialize the index buffer. + this.indexBuffer = new IndexBuffer(device, typeof(int), 12 * 3, ResourceUsage.None, ResourcePool.Default); + + // Set the data. + this.indexBuffer.SetData(tempIndices); + + #endregion + } + + #endregion + + + #region Method: Intersects(BoundingVolume volume) + + /// + /// It checks whether this bounding box intersects with the given bounding volume. + /// + /// The volume to check with. + /// True if the bounding volumes intersect, false otherwise. + public override bool Intersects(BoundingVolume volume) + { + // Check with other bounding volumes. + if (volume is BoundingBox) + { + // Intersection code here. + } + + // By default. + return false; + } + + #endregion + } +} diff --git a/Extras/XNAPhysics/Physics/BoundingVolume.cs b/Extras/XNAPhysics/Physics/BoundingVolume.cs new file mode 100644 index 000000000..37bb14fa9 --- /dev/null +++ b/Extras/XNAPhysics/Physics/BoundingVolume.cs @@ -0,0 +1,166 @@ +using System; +using System.Collections.Generic; +using System.Text; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; + +namespace Physics +{ + /// + /// An abstract class for a bounding volume. + /// A bounding volume has a transformation matrix that determines the orientation of the volume. + /// Futhermore it has an intersect funtion that checks whether this bounding volume intersects with an other bounding volume. + /// There is also a draw method by which the bounding volume is drawn. + /// + public abstract class BoundingVolume + { + #region Field: graphicsDevice + + /// + /// The graphicsDevice of this volume. + /// + protected GraphicsDevice graphicsDevice; + + #endregion + + #region Field: vertexBuffer + + /// + /// The vertex buffer of this volume. + /// + protected VertexBuffer vertexbuffer; + + #endregion + + #region Field: indexBuffer + + /// + /// The index buffer of this volume. + /// + protected IndexBuffer indexBuffer; + + #endregion + + #region Field: numberOfPrimitives + + /// + /// The number of primitives of this volume. + /// + protected int numberOfPrimitive; + + #endregion + + #region Field: numberOfVertices + + /// + /// The number of vertices of this volume. + /// + protected int numberOfVertices; + + #endregion + + + #region Property: TransformationMatrix + + /// + /// The transformation matrix of this bounding volume. + /// + protected Matrix transformationMatrix; + + /// + /// The transformation matrix of this bounding volume. + /// + public Matrix TransformationMatrix + { + get + { + return this.transformationMatrix; + } + } + + #endregion + + #region Property: Color + + /// + /// The color of this bounding volume. + /// + private Color color; + + /// + /// The color of this bounding volume. + /// + public Color Color + { + get + { + return color; + } + set + { + color = value; + } + } + + #endregion + + + #region Constructor: BoundingVolume(Color color, GraphicsDevice graphicsDevice) + + /// + /// Create a new bounding volume. + /// + /// The color of this volume. + /// The device used to render. + public BoundingVolume(Color color, GraphicsDevice graphicsDevice) + { + this.color = color; + this.transformationMatrix = Matrix.Identity; + this.graphicsDevice = graphicsDevice; + } + + #endregion + + + #region Method: Intersects(BoundingVolume volume) + + /// + /// This method must be implemented. + /// It checks whether this bounding volume intersects with the given bounding volume. + /// + /// The volume to check with. + /// True if the bounding volumes intersect, false otherwise. + public abstract bool Intersects(BoundingVolume volume); + + #endregion + + #region Method: Draw() + + /// + /// Draw this bounding volume to the screen. + /// + public void Draw() + { + this.graphicsDevice.RenderState.CullMode = CullMode.None; + this.graphicsDevice.Indices = this.indexBuffer; + this.graphicsDevice.VertexDeclaration = new VertexDeclaration(graphicsDevice, VertexPositionColor.VertexElements); + this.graphicsDevice.Vertices[0].SetSource(this.vertexbuffer, 0, VertexPositionColor.SizeInBytes); + this.graphicsDevice.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, this.numberOfVertices, 0, this.numberOfPrimitive); + } + + #endregion + + #region Method: TranslateWorld(Vector3 translation) + + /// + /// Translate this bounding volume relative to the world axis. + /// + /// The translation to make. + public void TranslateWorld(Vector3 translation) + { + this.transformationMatrix *= Matrix.CreateTranslation(translation); + } + + #endregion + } +} diff --git a/Extras/XNAPhysics/Physics/Game1.Designer.cs b/Extras/XNAPhysics/Physics/Game1.Designer.cs new file mode 100644 index 000000000..188a5631c --- /dev/null +++ b/Extras/XNAPhysics/Physics/Game1.Designer.cs @@ -0,0 +1,21 @@ +using System; + +namespace Physics +{ + partial class Game1 + { + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.graphics = new Microsoft.Xna.Framework.Components.GraphicsComponent(); + + this.GameComponents.Add(this.graphics); + + } + + private Microsoft.Xna.Framework.Components.GraphicsComponent graphics; + } +} diff --git a/Extras/XNAPhysics/Physics/Game1.cs b/Extras/XNAPhysics/Physics/Game1.cs new file mode 100644 index 000000000..aa49ab51f --- /dev/null +++ b/Extras/XNAPhysics/Physics/Game1.cs @@ -0,0 +1,216 @@ +using System; +using System.Collections.Generic; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Audio; +using Microsoft.Xna.Framework.Components; +using Microsoft.Xna.Framework.Graphics; +using Microsoft.Xna.Framework.Input; +using Microsoft.Xna.Framework.Storage; + +namespace Physics +{ + /// + /// This is the main type for your game + /// + partial class Game1 : Microsoft.Xna.Framework.Game + { + #region Field: viewTransformation + + /// + /// The used view transformation. + /// + private Matrix viewTransformation; + + #endregion + + #region Field: projectionTransformation + + /// + /// The used projection transformation. + /// + private Matrix projectionTransformation; + + #endregion + + #region Field: effect + + /// + /// The used effect. + /// + private Effect effect; + + #endregion + + #region Field: transform + + /// + /// The used transform effect parameter. + /// + private EffectParameter transform; + + #endregion + + #region Field: color + + /// + /// The used color effect parameter. + /// + private EffectParameter color; + + #endregion + + #region Field: volumes + + /// + /// The list of bounding volumes. + /// + private List volumes; + + #endregion + + + #region Constructor: Game1() + + /// + /// Create a new game. + /// + public Game1() + { + InitializeComponent(); + + float aspectRatio = 640.0f / 480.0f; + float fov = MathHelper.PiOver4; + + // Initialize the matrices. + this.viewTransformation = Matrix.CreateLookAt(new Vector3(0, 0, 150), new Vector3(0, 0, 0), new Vector3(0, 1, 0)); + this.projectionTransformation = Matrix.CreatePerspectiveFieldOfView(fov, aspectRatio, 1, 600); + + // Initialize the shader. + CompiledEffect cEffect = Effect.CompileEffectFromFile("color.fx", null, null, CompilerOptions.None, TargetPlatform.Windows); + this.effect = new Effect(this.graphics.GraphicsDevice, cEffect.GetShaderCode(), CompilerOptions.None, null); + + // Get the parameters. + EffectParameterCollection coll = this.effect.Parameters; + this.transform = coll.GetParameterBySemantic("WorldViewProjection"); + this.color = coll.GetParameterBySemantic("Color"); + + // Create and add volumes. + this.volumes = new List(); + this.AddBoundingVolumes(); + } + + #endregion + + + #region Method: AddBoundingVolumes() + + /// + /// Add bounding volumes to the world. + /// + private void AddBoundingVolumes() + { + // ---------- + // + // Add bounding volumes here. + // + // ---------- + + // Box 1 + BoundingBox box1 = new BoundingBox(5, 5, 5, Color.Green, this.graphics.GraphicsDevice); + box1.TranslateWorld(new Vector3(10, 0, 0)); + this.volumes.Add(box1); + + // Box 2 + this.volumes.Add(new BoundingBox(10, 10, 10, Color.LightSkyBlue, this.graphics.GraphicsDevice)); + } + + #endregion + + #region Method: Update() + + /// + /// Update components of this physics application. + /// + protected override void Update() + { + // The time since Update was called last + float elapsed = (float)ElapsedTime.TotalSeconds; + + this.ProcessUserInput(); + + // Let the GameComponents update + UpdateComponents(); + } + + #endregion + + #region Method: ProcessUserInput() + + /// + /// Process input from the user. + /// + private void ProcessUserInput() + { + KeyboardState state = Keyboard.GetState(); + + // Move left and right. + if (state.IsKeyDown(Keys.D)) this.volumes[0].TranslateWorld(new Vector3(0.1f, 0, 0)); + if (state.IsKeyDown(Keys.A)) this.volumes[0].TranslateWorld(new Vector3(-0.1f, 0, 0)); + + // Check for collisions here somewhere. + } + + #endregion + + #region Method: Draw() + + /// + /// Draw the content of the physics application. + /// + protected override void Draw() + { + // Make sure we have a valid device + if (!graphics.EnsureDevice()) + return; + + graphics.GraphicsDevice.Clear(ClearOptions.DepthBuffer | ClearOptions.Target, Color.Blue, 1, 0); + graphics.GraphicsDevice.BeginScene(); + + + // Render all the bounding volumes. + foreach (BoundingVolume currentVolume in this.volumes) + { + // Set the color. + this.color.SetValue((currentVolume.Color.ToVector4())); + + // Set the transformation. + this.transform.SetValue(currentVolume.TransformationMatrix * this.viewTransformation * this.projectionTransformation); + + // Start the effect. + this.effect.Begin(EffectStateOptions.Default); + + foreach (EffectPass pass in effect.CurrentTechnique.Passes) + { + pass.Begin(); + + // Draw the volume. + currentVolume.Draw(); + + pass.End(); + } + + + // End the effect. + this.effect.End(); + } + + // Let the GameComponents draw + DrawComponents(); + + graphics.GraphicsDevice.EndScene(); + graphics.GraphicsDevice.Present(); + } + + #endregion + } +} \ No newline at end of file diff --git a/Extras/XNAPhysics/Physics/Physics.csproj b/Extras/XNAPhysics/Physics/Physics.csproj new file mode 100644 index 000000000..334e3b6ad --- /dev/null +++ b/Extras/XNAPhysics/Physics/Physics.csproj @@ -0,0 +1,66 @@ + + + {4AA0A1F5-0F11-4D86-9D43-85A12835572F} + {9F340DF3-2AED-4330-AC16-78AC2D9B4738};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + Debug + AnyCPU + WinExe + Properties + Physics + Physics + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + true + false + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + true + false + + + + true + + + true + + + + + + + + + + + + Game1.cs + + + + + Component + + + + + \ No newline at end of file diff --git a/Extras/XNAPhysics/Physics/Program.cs b/Extras/XNAPhysics/Physics/Program.cs new file mode 100644 index 000000000..3211e603b --- /dev/null +++ b/Extras/XNAPhysics/Physics/Program.cs @@ -0,0 +1,19 @@ +using System; + +namespace Physics +{ + static class Program + { + /// + /// The main entry point for the application. + /// + static void Main(string[] args) + { + using (Game1 game = new Game1()) + { + game.Run(); + } + } + } +} + diff --git a/Extras/XNAPhysics/Physics/Properties/AssemblyInfo.cs b/Extras/XNAPhysics/Physics/Properties/AssemblyInfo.cs new file mode 100644 index 000000000..703162276 --- /dev/null +++ b/Extras/XNAPhysics/Physics/Properties/AssemblyInfo.cs @@ -0,0 +1,32 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("Physics")] +[assembly: AssemblyProduct("Physics")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyCopyright("Copyright © 2006")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("04d7cdfe-26b9-4243-b855-7071a96076fd")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Extras/XNAPhysics/Physics/bin/Debug/color.fx b/Extras/XNAPhysics/Physics/bin/Debug/color.fx new file mode 100644 index 000000000..f99024950 --- /dev/null +++ b/Extras/XNAPhysics/Physics/bin/Debug/color.fx @@ -0,0 +1,42 @@ + //--------------------------------------------------------------// + // Constant(s) + //--------------------------------------------------------------// + + float4 color : Color; + + float4x4 transform : WorldViewProjection; + + //--------------------------------------------------------------// + // Vertex shader(s) + //--------------------------------------------------------------// + + void FinalVS( inout float4 Position : POSITION0) + { + // Calculate the output position. + //float4 tempPos = mul( Position, world ); + Position = mul( Position, transform); + } + + //--------------------------------------------------------------// + // Pixel shader(s) + //--------------------------------------------------------------// + + void FinalPS( out float4 Color : COLOR0 ) + { + // Set the output color. + Color = color; + } + + + //--------------------------------------------------------------// + // Technique(s) + //--------------------------------------------------------------// + + technique Final + { + pass Pass_0 + { + VertexShader = compile vs_1_1 FinalVS(); + PixelShader = compile ps_2_0 FinalPS(); + } + } diff --git a/Extras/XNAPhysics/Physics/bin/Release/color.fx b/Extras/XNAPhysics/Physics/bin/Release/color.fx new file mode 100644 index 000000000..f99024950 --- /dev/null +++ b/Extras/XNAPhysics/Physics/bin/Release/color.fx @@ -0,0 +1,42 @@ + //--------------------------------------------------------------// + // Constant(s) + //--------------------------------------------------------------// + + float4 color : Color; + + float4x4 transform : WorldViewProjection; + + //--------------------------------------------------------------// + // Vertex shader(s) + //--------------------------------------------------------------// + + void FinalVS( inout float4 Position : POSITION0) + { + // Calculate the output position. + //float4 tempPos = mul( Position, world ); + Position = mul( Position, transform); + } + + //--------------------------------------------------------------// + // Pixel shader(s) + //--------------------------------------------------------------// + + void FinalPS( out float4 Color : COLOR0 ) + { + // Set the output color. + Color = color; + } + + + //--------------------------------------------------------------// + // Technique(s) + //--------------------------------------------------------------// + + technique Final + { + pass Pass_0 + { + VertexShader = compile vs_1_1 FinalVS(); + PixelShader = compile ps_2_0 FinalPS(); + } + }