在XNA 4中为模型创建边界框

时间:2014-01-03 09:24:37

标签: c# xna

我有以下代码,目前正在创建一个边界框

public Wall(Model model, Vector3 position) : base(model){
            this.translation = Matrix.CreateTranslation(position);
            Vector3 from = Vector3.Transform(new Vector3(0f), World);
            Vector3 to = Vector3.Transform(new Vector3(1f), World);
            boundingBox = new BoundingBox(from, to);
        }

然而,我最终得到的盒子与所绘制的模型的位置不同,如下图所示(黄色轮廓是边界框)

enter image description here

如何创建边界框以使其处于正确的位置。

我找到了:

public BoundingBox GetBoundingBoxFromModel(Model model)
        {
            BoundingBox boundingBox = new BoundingBox();


              foreach (ModelMesh mesh in model.Meshes)
              {
                VertexPositionNormalTexture[] vertices =
                  new VertexPositionNormalTexture[mesh.VertexBuffer.SizeInBytes / VertexPositionNormalTexture.SizeInBytes];

                mesh.VertexBuffer.GetData<VertexPositionNormalTexture>(vertices);
                Vector3[] vertexs = new Vector3[vertices.Length];

                for (int index = 0; index < vertexs.Length; index++)
                {
                  vertexs[index] = vertices[index].Position;
                }

                boundingBox = BoundingBox.CreateMerged(boundingBox,
                  BoundingBox.CreateFromPoints(vertexs));
              }

              return boundingBox;
            }

但这不适用于XNA 4

如何为与绘制的模型位于同一位置的模型生成边界框。

修改

我的完整墙类:

namespace MapGameLibrary {
    public class Wall : Entity {
        BoundingBox boundingBox;

        public Wall(Model model, Vector3 position) : base(model){
            this.translation = Matrix.CreateTranslation(position);
            Vector3 from = Vector3.Transform(new Vector3(0f), World);
            Vector3 to = Vector3.Transform(new Vector3(1f), World);
            boundingBox = new BoundingBox(from, to);
        }

        public BoundingBox GetBoundingBox() {
            return boundingBox;
        }

        public override void Draw(bool textured, Matrix view, Matrix proj)
        {
            foreach (ModelMesh mesh in model.Meshes)
            {
                foreach (BasicEffect effect in mesh.Effects)
                {
                    effect.World = World * mesh.ParentBone.Transform;
                    effect.View = view;
                    effect.Projection = proj;
                    effect.EnableDefaultLighting();
                }
                mesh.Draw();
            }
        }

    }
}

并使用以下方式创建墙:

for (int row = 0; row < map.Rows; row++)
            {
                for (int col = 0; col < map.Columns; col++)
                {
                    if (map.Get(row, col) == 'w') walls.Add(new Wall(content.Load<Model>("models/wall"), new Vector3(col, 0, row)));
                }
            }

1 个答案:

答案 0 :(得分:0)

您当前的方法:

用于制作框的转换和数据必须与用于渲染框用于的墙对象的数据和转换完全相同...完全相同。

您使用的数据是min&amp;最大化你的盒子(0和1),与你在墙壁对象的顶点缓冲区(用于渲染的数据)中找到的完全相同?

要制作你的盒子,你正在改造0&amp; 1由一个名为“世界”的矩阵组成。这是渲染墙部分时传递给effect.World属性的完全相同的矩阵吗?在Xna中渲染时,常常有myModel.CopyAbsoluteBoneTransformsTo()这样的行。如果你有这样一条线并使用它的结果进行渲染,那么你也必须使用它的结果来制作一个盒子。


你的第二种方法:好多了。

将顶点缓冲区导入到具有未变换顶点位置的Xna中(未应用骨骼变换)。但在渲染时,您通常会应用骨骼变换(通过CopyAbsoluteBoneTransformsTo()并使用effect.World中的结果)。所以你用它们制作的盒子是一个非变形的盒子。如果你要改造这个盒子的min&amp;最大化由相同的矩阵构成你的效果。世界财产,你会是金色的。