/// <summary> /// Generate the current bounding box of a model. /// </summary> public static BoundingBox GenerateBoundingBox(this Model model) { Vector3 min = new Vector3(float.MaxValue); Vector3 max = new Vector3(float.MinValue); Matrix[] bonesAbsolute = new Matrix[model.Bones.Count]; // MEMORYCHURN model.CopyAbsoluteBoneTransformsTo(bonesAbsolute); foreach (ModelMesh mesh in model.Meshes) { Matrix boneAbsolute = bonesAbsolute[mesh.ParentBone.Index]; foreach (ModelMeshPart part in mesh.MeshParts) { int stride = part.VertexStride; int vertexCount = part.NumVertices; byte[] vertexData = new byte[stride * vertexCount]; // MEMORYCHURN mesh.VertexBuffer.GetData(vertexData); for (int index = 0; index < vertexData.Length; index += stride) { float x = BitConverter.ToSingle(vertexData, index); float y = BitConverter.ToSingle(vertexData, index + 4); float z = BitConverter.ToSingle(vertexData, index + 8); Vector3 vertex = new Vector3(x, y, z); Vector3 vertexWorld = Vector3.Transform(vertex, boneAbsolute); if (vertexWorld.X < min.X) min.X = vertexWorld.X; if (vertexWorld.X > max.X) max.X = vertexWorld.X; if (vertexWorld.Y < min.Y) min.Y = vertexWorld.Y; if (vertexWorld.Y > max.Y) max.Y = vertexWorld.Y; if (vertexWorld.Z < min.Z) min.Z = vertexWorld.Z; if (vertexWorld.Z > max.Z) max.Z = vertexWorld.Z; } } } return new BoundingBox(min, max); }
/// <summary> /// Model 全体を包む BoundingBox を取得します。 /// </summary> /// <param name="model">Model。</param> /// <param name="result">Model 全体を包む BoundingBox。</param> public static void GetBoundingBox(this Model model, out BoundingBox result) { var boneTransforms = new Matrix[model.Bones.Count]; model.CopyAbsoluteBoneTransformsTo(boneTransforms); var points = new List<Vector3>(); foreach (var mesh in model.Meshes) { foreach (var part in mesh.MeshParts) { var vertexBuffer = part.VertexBuffer; var data = new float[vertexBuffer.VertexCount * vertexBuffer.VertexDeclaration.VertexStride / sizeof(float)]; vertexBuffer.GetData<float>(data); var boneTransform = boneTransforms[mesh.ParentBone.Index]; var increment = vertexBuffer.VertexDeclaration.VertexStride / sizeof(float); for (int i = 0; i < data.Length; i += increment) { Vector3 point; point.X = data[i]; point.Y = data[i + 1]; point.Z = data[i + 2]; point = Vector3.Transform(point, boneTransform); points.Add(point); } } } result = BoundingBox.CreateFromPoints(points); }
public static BoundingSphere ComputeBoundingSphere( this Model that ) { var result = new BoundingSphere(Vector3.Zero, 0); var modelTransforms = new Matrix[that.Bones.Count]; that.CopyAbsoluteBoneTransformsTo(modelTransforms); foreach (ModelMesh mesh in that.Meshes) { BoundingSphere transformed = mesh.BoundingSphere.Transform( modelTransforms[mesh.ParentBone.Index]); result = result.MergeWith(transformed); } return result; }
public static BoundingSphere GetBoundingSphere(this Model model, Matrix[] transformations) { var result = new BoundingSphere(); if (transformations.IsNull()) { transformations = new Matrix[model.Bones.Count]; model.CopyAbsoluteBoneTransformsTo(transformations); } foreach (var mesh in model.Meshes) { var additional = mesh.BoundingSphere.Transform(transformations[mesh.ParentBone.Index]); BoundingSphere.CreateMerged(ref result, ref additional, out result); } return result; }
public static Matrix[] GetAboluteBoneTransforms( this Model model ) { Matrix[] bones = new Matrix[ model.Bones.Count ]; model.CopyAbsoluteBoneTransformsTo( bones ); return bones; }