Skip to content

Instantly share code, notes, and snippets.

/ModelBox.cs Secret

Created October 7, 2016 04:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save anonymous/a9794066767e5149b0f5cabaaffb6bb8 to your computer and use it in GitHub Desktop.
Save anonymous/a9794066767e5149b0f5cabaaffb6bb8 to your computer and use it in GitHub Desktop.
using System;
using BEPUphysics.Entities.Prefabs;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
namespace Engine
{
public class ModelBox
{
private Box box;
private BasicEffect effect;
private short[] bBoxIndices;
// Properties
public Box Box
{
get { return box; }
set { box = value; }
}
public ModelBox(Model model, Vector3 position)
{
// Set up model data
box = BuildBoundingBox(model, position);
// New shader
effect = new BasicEffect(Globals.GraphicDevice);
// (Draw) Initialize an array of indices for the box. 12 lines require 24 indices
bBoxIndices = new short[] {
0, 1, 1, 2, 2, 3, 3, 0, // Front edges
4, 5, 5, 6, 6, 7, 7, 4, // Back edges
0, 4, 1, 5, 2, 6, 3, 7 // Side edges connecting front and back
};
}
private Box BuildBoundingBox(Model model, Vector3 position)
{
// Initialize minimum and maximum corners of the bounding box to max and min values
Vector3 min = new Vector3(float.MaxValue, float.MaxValue, float.MaxValue);
Vector3 max = new Vector3(float.MinValue, float.MinValue, float.MinValue);
// For each mesh of the model
foreach (ModelMesh mesh in model.Meshes)
{
foreach (ModelMeshPart meshPart in mesh.MeshParts)
{
// Vertex buffer parameters
int vertexStride = meshPart.VertexBuffer.VertexDeclaration.VertexStride;
int vertexBufferSize = meshPart.NumVertices * vertexStride;
// Get vertex data as float
float[] vertexData = new float[vertexBufferSize / sizeof(float)];
meshPart.VertexBuffer.GetData<float>(vertexData);
// Iterate through vertices (possibly) growing bounding box, all calculations are done in world space
for (int i = 0; i < vertexBufferSize / sizeof(float); i += vertexStride / sizeof(float))
{
Vector3 transformedPosition = Vector3.Transform(new Vector3(vertexData[i], vertexData[i + 1], vertexData[i + 2]), Matrix.Identity);
min = Vector3.Min(min, transformedPosition);
max = Vector3.Max(max, transformedPosition);
}
}
}
// Create and return bounding box
return new Box(ConvertTo.BEPUVector3(position), Math.Abs(max.X - min.X), Math.Abs(max.Y - min.Y), Math.Abs(max.Z - min.Z));
}
public void Update(Model model, Vector3 position)
{
box = BuildBoundingBox(model, position);
}
public void Draw(Matrix View, Matrix Projection)
{
// Use inside a drawing loop
BEPUutilities.Vector3[] corners = box.CollisionInformation.BoundingBox.GetCorners();
VertexPositionColor[] primitiveList = new VertexPositionColor[corners.Length];
// Assign the 8 box vertices
for (int i = 0; i < corners.Length; i++)
{
primitiveList[i] = new VertexPositionColor(ConvertTo.XNAVector3(corners[i]), Color.White);
}
effect.View = View;
effect.World = Matrix.Identity;
effect.Projection = Projection;
effect.TextureEnabled = false;
// Draw the box with a LineList
foreach (EffectPass pass in effect.CurrentTechnique.Passes)
{
pass.Apply();
Globals.GraphicDevice.DrawUserIndexedPrimitives(PrimitiveType.LineList, primitiveList, 0, 8, bBoxIndices, 0, 12);
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment