[Index page]
[Download source code]
Dream come true XNA (10)-Collision Detection of 3D Models
Author: webabcd
Introduction
XNA: Collision Detection of 3D models. Collision Detection Using the Bounding Sphere Algorithm
Example
Demonstrate 3D model collision detection. The "up/down/left" key controls the rotation of the 3D model, and the "LeftShift" and "LeftControl" keys control the movement of the 3D model before and after (press the keyboard S key to load this Demo)
3D/Collision/RotationDirection. cs
Namespace XNA. component. _ 3D. collision {// <summary> // rotation direction // </summary> public enum RotationDirection {Up, Down, Left, Right }}
3D/Collision/TranslationDirection. cs
Namespace XNA. Component. _ 3D. Collision {// <summary> // displacement direction // </summary> public enum TranslationDirection {Forward, Backward }}
3D/Collision/MyCamera. cs
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; namespace XNA. component. _ 3D. collision {// <summary> // custom Camera class // </summary> public class MyCamera: Microsoft. xna. framework. gameComponent {// View Matrix, used to set the camera position and direction public Matrix View {get; protected set;} // Projection Matrix, used to project a 3D object to a 2D screen. public Matrix Projection {get; protected set;} public MyCamera (Game game, Vector3 pos, Vector3 target, Vector3 up): base (game) {/** Matrix CreateLookAt (Vector3 cameraPosition, Vector3 cameraTarget, Vector3 cameraUpVector) -instantiate the View Matrix * Vector3 cameraPosition-camera position coordinate * Vector3 cameraTarget-orientation vector of the camera lens * Vector3 cameraUpVector-vector above the top of the camera body */View = Matrix. createLookAt (pos, target, up);/** CreatePerspectiveFieldOfView (float fieldOfView, float aspectRatio, float nearPlaneDistance, float farPlaneDistance) -instantiate the angle radian of the projection matrix * float fieldOfView-Y axis, which is generally the aspect ratio of the 1/4 PI * float aspectRatio-visible area, generally, the width of the game window is divided by the height of the game window * float nearPlaneDistance-when the object is too close to the camera, it cannot be seen * float farPlaneDistance-when the object is too far away from the camera, it cannot be seen */Projection = matrix. createPerspectiveFieldOfView (MathHelper. piOver4, // 1/4 PI (there are many useful functions in MathHelper) (float) Game. window. clientBounds. width/(float) Game. window. clientBounds. height, 1, 3000);} public override void Initialize () {base. initialize ();} public override void Update (GameTime gameTime) {base. update (gameTime );}}}
3D/Collision/MyModel. cs
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; namespace XNA. component. _ 3D. collision {// <summary> // custom 3D model class /// </summ Ary> public class MyModel {// Model-represents a 3D Model. Texture2D private Model _ model is used to represent 2D objects. // The rotating Matrix private Matrix _ rotation = Matrix. identity; // displacement Matrix private Matrix _ translation = Matrix. identity; // initial Matrix private Matrix _ world = Matrix. identity; public MyModel (Model model, Matrix world) {_ model = model; _ world = world ;} /// <summary> /// Draw a 3D Model /// </summary> public void Draw (MyCamera camera) {/** a Model object contains multiple ModelMesh objects, each ModelMesh object contains the texture, color, and other information of the mesh */foreach (ModelMesh in _ model. meshes) {/** A ModelMesh object contains multiple Effect */foreach (BasicEffect effect in mesh) used to draw ModelMesh. effects) {// use the default light source effect. enabledefalightlighting (); effect. projection = camera. projection; effect. view = camera. view; effect. world = GetWorld ();} // draw the ModelMesh mesh. draw () ;}/// <summary> /// calculate the rotation matrix based on the direction (up and down) /// </summary> public void Rotate (RotationDirection direction) {switch (direction) {case RotationDirection. up: _ rotation * = Matrix. createRotationX (-MathHelper. pi/180); // radians that rotate around the X axis break; case RotationDirection. down: _ rotation * = Matrix. createRotationX (MathHelper. pi/180); break; case RotationDirection. left: _ rotation * = Matrix. createRotationY (-MathHelper. pi/180); // radians that rotate around the Y axis break; case RotationDirection. right: _ rotation * = Matrix. createRotationY (MathHelper. pi/180); break ;}/// <summary> // calculate the displacement matrix (forward or backward) /// </summary> public void Move (TranslationDirection direction) {switch (direction) {case TranslationDirection. forward: _ translation * = Matrix. createTranslation (_ rotation. backward); break; case TranslationDirection. backward: _ translation * = Matrix. createTranslation (_ rotation. forward); break ;}/// <summary> // obtain the world Matrix, that is, multiply the initial Matrix by the rotation Matrix /// </summary> public Matrix GetWorld () {return _ world * _ rotation * _ translation ;} /// <summary >/// return the Model object of the custom 3D Model /// </summary> public model GetModel () {return _ Model ;} /// <summary> /// check whether another Model has collided with this Model. /// </summary> /// <param name = "model2"> another 3D Model model </param> /// <param name = "world2"> world matrix of another 3D Model </param> /// <returns> </returns> public bool CheckCollision (Model model2, matrix world2) {foreach (ModelMesh mesh in _ model. meshes) {foreach (ModelMesh mesh2 in model2.Meshes) {// each ModelMesh object has a BoundingSphere attribute if (mesh. boundingSphere. transform (GetWorld ()). intersects (mesh2.BoundingSphere. transform (world2) return true ;}} return false ;}}}
3D/Collision/Demo. cs
/** Demonstration in this example: Collision Detection of 3D models, through the Bounding Sphere algorithm (XNA has built this algorithm) * "Up and down" key to control the rotation of 3D models, the "LeftShift" and "LeftControl" keys control the movement of the 3D model before and after */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; namespace XNA. component. _ 3D. collision {public class Demo: Microsoft. xna. framework. drawableGameComponent {private MyCamera _ camera; // computer-controlled model private MyModel _ modelSystem; // user-controlled model private MyModel _ modelUser; // whether a collision has occurred bool _ collided = false; public Demo (Game game): base (game) {} public override void Initialize () {// Add the camera component _ camera = new MyCamera (Game, new Vector3 (0, 0, 50), Vector3.Zero, Vector3.Up); Game. components. add (_ camera); base. initialize ();} protected override void LoadContent () {_ modelSystem = new MyModel (Game. content. load <Model> (@ "3DModel \ Spaceship"), Matrix. identity * Matrix. createTranslation (0, 0,-200); _ modelUser = new MyModel (Game. content. load <Model> (@ "3DModel \ Spaceship"), Matrix. identity * Matrix. createTranslation (0,-10, 0); base. loadContent ();} public override void Update (GameTime gameTime) {// determine whether two 3D models have collided with each other _ collided = _ modelUser. checkCollision (_ modelSystem. getModel (), _ modelSystem. getWorld (); if (_ collided) return; KeyboardState keyboardState = Keyboard. getState (); // rotate the 3D model if (keyboardState. isKeyDown (Keys. up) _ modelUser. rotate (RotationDirection. up); else if (keyboardState. isKeyDown (Keys. down) _ modelUser. rotate (RotationDirection. down); else if (keyboardState. isKeyDown (Keys. left) _ modelUser. rotate (RotationDirection. left); else if (keyboardState. isKeyDown (Keys. right) _ modelUser. rotate (RotationDirection. right); // move the 3D model based on the user's buttons: LeftShift-move forward; LeftControl-move backward if (keyboardState. isKeyDown (Keys. leftShift) _ modelUser. move (TranslationDirection. forward); else if (keyboardState. isKeyDown (Keys. leftControl) _ modelUser. move (TranslationDirection. backward); base. update (gameTime);} public override void Draw (GameTime gameTime) {if (_ collided) Game. graphicsDevice. clear (Color. indianRed); else Game. graphicsDevice. clear (Color. cornflowerBlue); // draw a 3D model _ modelSystem. draw (_ camera); _ modelUser. draw (_ camera); base. update (gameTime );}}}
OK
[Download source code]