XNA - 3D模型的碰撞檢測 - Part 2…
例如:
if (bulletBoundingSphere.Intersects(planeBoundingSphere))
{
//plane's been hit. cue smoke, flames, snakes in a panic, singing nuns, whatever...
}
…
這裡範例展示要如何取得Model的BoundingSphere…
//Load the model using my game's instance of a ContentManager.
Model myModel = MyGame.ContentManager.Load("ContentMeshesMyModel");
foreach (ModelMesh mesh in myModel.Meshes)
{
//Do stuff with mesh.BoundingSphere
}
…
接著來看看這些程式碼,它們可以在MyGame.cs裡面找到…
private void AnalyseModel()
{
// Take a copy of the Model's BoneTransforms (transforms to be applied to each part of the model)
GetBoneTransforms();
// Build BoundingParts for Collision Detection
BuildBoundingParts();
}
private void GetBoneTransforms()
{
_modelBoneTransforms = new Matrix[_model.Bones.Count];
_model.CopyAbsoluteBoneTransformsTo(_modelBoneTransforms);
}
…
是的,這一切聽起來令人興奮,所以來看看著個好東西。這些程式碼在MyGame.cs約頂部的地方,你可以看到以下有趣的程式碼…
//Blob mesh
private string[] _modelBoundingPartNames = new string[]
{
"Fuselage",
"Wing",
"Tail"
};
private Color[] _modelBoundingPartColours = new Color[]
{
Color.Blue,
Color.Red,
Color.GreenYellow
};
private Vector4[][] _modelBoundingPartSubdivisions = new Vector4[][]
{
//Fuselage
new Vector4[] { new Vector4(0.50f, 0.10f, 0.46f, 0.20f),
new Vector4(0.50f, 0.30f, 0.46f, 0.27f),
new Vector4(0.50f, 0.60f, 0.48f, 0.26f)
},
//Wing
new Vector4[] { new Vector4(0.07f, 0.51f, 0.50f, 0.20f),
new Vector4(0.30f, 0.515f, 0.50f, 0.25f),
new Vector4(0.50f, 0.515f, 0.50f, 0.27f),
new Vector4(0.70f, 0.515f, 0.50f, 0.25f),
new Vector4(0.93f, 0.51f, 0.50f, 0.20f)
},
//Tail
new Vector4[] { new Vector4(0.25f, 0.52f, 0.45f, 0.40f),
new Vector4(0.50f, 0.56f, 0.53f, 0.55f),
new Vector4(0.75f, 0.52f, 0.45f, 0.40f)
}
};
…
接下來看BuildBoundingParts()方法會做些甚麼事情!
///
/// Builds a collection of BoundingParts for each ModelMesh in the Model.
/// Each BoundingPart will contain one or many BoundingSphere as defined in the _modelBoundingPartSubdivisions array.
///
private void BuildBoundingParts()
{
_modelBoundingParts = new BoundingPartList();
BoundingPart boundingPart;
int meshIndex = 0;
foreach (ModelMesh mesh in _model.Meshes)
{
BoundingSphere[] pieces = new BoundingSphere[_modelBoundingPartSubdivisions[meshIndex].Length];
int pieceIndex = 0;
//Create, Scale and Position new BoundingSphere's according to the defined subdivisions for this part of the model.
foreach (Vector4 subdivision in _modelBoundingPartSubdivisions[meshIndex])
{
//Determine the new BoundingSphere's Radius
float radius = subdivision.W * mesh.BoundingSphere.Radius;
//Determine the new BoundingSphere's Center by interpolating.
//The subdivision's X, Y, Z represent percentages in each axis. They will used across the full diameter of XNA's "default" BoundingSphere.
float x = MathHelper.Lerp(mesh.BoundingSphere.Center.X - mesh.BoundingSphere.Radius, mesh.BoundingSphere.Center.X + mesh.BoundingSphere.Radius, subdivision.X);
float y = MathHelper.Lerp(mesh.BoundingSphere.Center.Y - mesh.BoundingSphere.Radius, mesh.BoundingSphere.Center.Y + mesh.BoundingSphere.Radius, subdivision.Y);
float z = MathHelper.Lerp(mesh.BoundingSphere.Center.Z - mesh.BoundingSphere.Radius, mesh.BoundingSphere.Center.Z + mesh.BoundingSphere.Radius, subdivision.Z);
Vector3 centre = new Vector3(x, y, z);
pieces[pieceIndex] = new BoundingSphere(centre, radius);
pieceIndex++;
}
boundingPart = new BoundingPart(mesh.BoundingSphere, pieces, _modelBoneTransforms[mesh.ParentBone.Index], _modelBoundingPartNames[meshIndex], _modelBoundingPartColours[meshIndex]);
_modelBoundingParts.Add(boundingPart);
meshIndex++;
}
}