XNA physics testbed, just 2 cubes for now, move with a/d keys

This commit is contained in:
ejcoumans
2006-09-19 19:03:41 +00:00
parent 7faf84d784
commit 1d539aa662
10 changed files with 767 additions and 0 deletions

View File

@@ -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

View File

@@ -0,0 +1,143 @@
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;
namespace Physics
{
/// <summary>
/// This bounding volume is represented by a box.
/// </summary>
public class BoundingBox : BoundingVolume
{
#region Constructor: BoundingBox(float width, float height, float depth, Color color, GraphicsDevice device)
/// <summary>
/// Creates a new bounding box.
/// </summary>
/// <param name="width">The width of the box.</param>
/// <param name="height">The height of the box.</param>
/// <param name="depth">The depth of the box.</param>
/// <param name="color">The color of the box.</param>
/// <param name="device">The rendering device.</param>
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<VertexPositionColor>(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<int>(tempIndices);
#endregion
}
#endregion
#region Method: Intersects(BoundingVolume volume)
/// <summary>
/// It checks whether this bounding box intersects with the given bounding volume.
/// </summary>
/// <param name="volume">The volume to check with.</param>
/// <returns>True if the bounding volumes intersect, false otherwise.</returns>
public override bool Intersects(BoundingVolume volume)
{
// Check with other bounding volumes.
if (volume is BoundingBox)
{
// Intersection code here.
}
// By default.
return false;
}
#endregion
}
}

View File

@@ -0,0 +1,166 @@
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
namespace Physics
{
/// <summary>
/// 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.
/// </summary>
public abstract class BoundingVolume
{
#region Field: graphicsDevice
/// <summary>
/// The graphicsDevice of this volume.
/// </summary>
protected GraphicsDevice graphicsDevice;
#endregion
#region Field: vertexBuffer
/// <summary>
/// The vertex buffer of this volume.
/// </summary>
protected VertexBuffer vertexbuffer;
#endregion
#region Field: indexBuffer
/// <summary>
/// The index buffer of this volume.
/// </summary>
protected IndexBuffer indexBuffer;
#endregion
#region Field: numberOfPrimitives
/// <summary>
/// The number of primitives of this volume.
/// </summary>
protected int numberOfPrimitive;
#endregion
#region Field: numberOfVertices
/// <summary>
/// The number of vertices of this volume.
/// </summary>
protected int numberOfVertices;
#endregion
#region Property: TransformationMatrix
/// <summary>
/// The transformation matrix of this bounding volume.
/// </summary>
protected Matrix transformationMatrix;
/// <summary>
/// The transformation matrix of this bounding volume.
/// </summary>
public Matrix TransformationMatrix
{
get
{
return this.transformationMatrix;
}
}
#endregion
#region Property: Color
/// <summary>
/// The color of this bounding volume.
/// </summary>
private Color color;
/// <summary>
/// The color of this bounding volume.
/// </summary>
public Color Color
{
get
{
return color;
}
set
{
color = value;
}
}
#endregion
#region Constructor: BoundingVolume(Color color, GraphicsDevice graphicsDevice)
/// <summary>
/// Create a new bounding volume.
/// </summary>
/// <param name="color">The color of this volume.</param>
/// <param name="graphicsDevice">The device used to render.</param>
public BoundingVolume(Color color, GraphicsDevice graphicsDevice)
{
this.color = color;
this.transformationMatrix = Matrix.Identity;
this.graphicsDevice = graphicsDevice;
}
#endregion
#region Method: Intersects(BoundingVolume volume)
/// <summary>
/// This method must be implemented.
/// It checks whether this bounding volume intersects with the given bounding volume.
/// </summary>
/// <param name="volume">The volume to check with.</param>
/// <returns>True if the bounding volumes intersect, false otherwise.</returns>
public abstract bool Intersects(BoundingVolume volume);
#endregion
#region Method: Draw()
/// <summary>
/// Draw this bounding volume to the screen.
/// </summary>
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)
/// <summary>
/// Translate this bounding volume relative to the world axis.
/// </summary>
/// <param name="translation">The translation to make.</param>
public void TranslateWorld(Vector3 translation)
{
this.transformationMatrix *= Matrix.CreateTranslation(translation);
}
#endregion
}
}

View File

@@ -0,0 +1,21 @@
using System;
namespace Physics
{
partial class Game1
{
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.graphics = new Microsoft.Xna.Framework.Components.GraphicsComponent();
this.GameComponents.Add(this.graphics);
}
private Microsoft.Xna.Framework.Components.GraphicsComponent graphics;
}
}

View File

@@ -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
{
/// <summary>
/// This is the main type for your game
/// </summary>
partial class Game1 : Microsoft.Xna.Framework.Game
{
#region Field: viewTransformation
/// <summary>
/// The used view transformation.
/// </summary>
private Matrix viewTransformation;
#endregion
#region Field: projectionTransformation
/// <summary>
/// The used projection transformation.
/// </summary>
private Matrix projectionTransformation;
#endregion
#region Field: effect
/// <summary>
/// The used effect.
/// </summary>
private Effect effect;
#endregion
#region Field: transform
/// <summary>
/// The used transform effect parameter.
/// </summary>
private EffectParameter transform;
#endregion
#region Field: color
/// <summary>
/// The used color effect parameter.
/// </summary>
private EffectParameter color;
#endregion
#region Field: volumes
/// <summary>
/// The list of bounding volumes.
/// </summary>
private List<BoundingVolume> volumes;
#endregion
#region Constructor: Game1()
/// <summary>
/// Create a new game.
/// </summary>
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<BoundingVolume>();
this.AddBoundingVolumes();
}
#endregion
#region Method: AddBoundingVolumes()
/// <summary>
/// Add bounding volumes to the world.
/// </summary>
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()
/// <summary>
/// Update components of this physics application.
/// </summary>
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()
/// <summary>
/// Process input from the user.
/// </summary>
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()
/// <summary>
/// Draw the content of the physics application.
/// </summary>
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
}
}

View File

@@ -0,0 +1,66 @@
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ProjectGuid>{4AA0A1F5-0F11-4D86-9D43-85A12835572F}</ProjectGuid>
<ProjectTypeGuids>{9F340DF3-2AED-4330-AC16-78AC2D9B4738};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<OutputType>WinExe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Physics</RootNamespace>
<AssemblyName>Physics</AssemblyName>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<NoStdLib>true</NoStdLib>
<UseVSHostingProcess>false</UseVSHostingProcess>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<NoStdLib>true</NoStdLib>
<UseVSHostingProcess>false</UseVSHostingProcess>
</PropertyGroup>
<ItemGroup>
<Reference Include="Microsoft.Xna.Framework, Version=1.0.0.0, Culture=neutral, PublicKeyToken=f48fa5f25d27e8ff, processorArchitecture=x86">
<SpecificVersion>true</SpecificVersion>
</Reference>
<Reference Include="Microsoft.Xna.Framework.Game, Version=1.0.0.0, Culture=neutral, PublicKeyToken=f48fa5f25d27e8ff, processorArchitecture=MSIL">
<SpecificVersion>true</SpecificVersion>
</Reference>
<Reference Include="mscorlib" />
<Reference Include="System" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="BoundingBox.cs" />
<Compile Include="BoundingVolume.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Game1.Designer.cs">
<DependentUpon>Game1.cs</DependentUpon>
</Compile>
<Compile Include="Program.cs">
</Compile>
<Compile Include="Game1.cs">
<SubType>Component</SubType>
</Compile>
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View File

@@ -0,0 +1,19 @@
using System;
namespace Physics
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
static void Main(string[] args)
{
using (Game1 game = new Game1())
{
game.Run();
}
}
}
}

View File

@@ -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")]

View File

@@ -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();
}
}

View File

@@ -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();
}
}