如何在XNA中存储模型的每个实例的矩阵状态

本文关键字:实例 状态 模型 XNA 存储 | 更新日期: 2023-09-27 18:25:01

我的下一个代码正在部分工作,以绘制模型,我正在创建它的几个实例,并将模型的每个实例渲染到不同的rendertarget。我的问题是如何存储每个实例的矩阵?因为当我想旋转一个时,似乎是引用了矩阵,当旋转时,它得到了更新的矩阵
谢谢问候

    using System;
    using System.Collections.Generic;
    using System.Text;
    using Microsoft.Xna.Framework;
    using Microsoft.Xna.Framework.Content;
    using Microsoft.Xna.Framework.Graphics;
    using gamacherclone.Sources.Model;
namespace gamacherclone
{
    public class Case360 : DrawableComponent 
    {
        private Model _model ;//= new Model();
        Matrix[] _boneTransforms,world;
        public int coverflowposition = 0;
        public bool rotate = false;
        Matrix view,  proj,worldtransform,tempbones;
        public Matrix[] boneTransforms;
        public Matrix[] originalBoneTransforms;
        Matrix[] worldTransforms;
        float i = 0;
        public DashBoard dash;
        Cover cover;

        public Case360(Game game, Cover _cover)
            : base(game)
        {
            this.dash = (DashBoard)game;
            this.cover = _cover;
        }
        protected override void LoadContent(){
            this._model = this.dash.Content.Load<Model>(@"Models'case360");
            this.initialize();  
         }
        public void initialize() {
            this._boneTransforms = new Matrix[this._model.Bones.Count];
            this.originalBoneTransforms = new Matrix[this._model.Bones.Count];
            this.worldTransforms = new Matrix[this._model.Bones.Count];
            this._model.CopyAbsoluteBoneTransformsTo(_boneTransforms);
            this._model.CopyAbsoluteBoneTransformsTo(originalBoneTransforms);
        }

        public override void Update(GameTime gameTime)
        {
            // Calculate the new position of the forks.
            float time = (float)gameTime.TotalGameTime.TotalSeconds;
           if (this.rotate) {
                worldtransform = worldTransforms[0];
                UpdateWorldTransforms(time);
            }

            base.Update(gameTime);
        }
        public void UpdateWorldTransforms(float time)
        {
            worldTransforms[0] = _boneTransforms[0] * Matrix.CreateRotationY(time * 2f);
        }

        public override void Draw(GameTime gameTime)
        {
            this._model.CopyAbsoluteBoneTransformsTo(_boneTransforms);
             base.GraphicsDevice.SetRenderTarget(cover.caseRender);
             base.GraphicsDevice.Clear(Color.Transparent);
             base.GraphicsDevice.BlendState = BlendState.AlphaBlend;
             //GraphicsDevice.RasterizerState = RasterizerState.CullCounterClockwise;
             base.GraphicsDevice.DepthStencilState = DepthStencilState.Default;
             view = Matrix.CreateLookAt(new Vector3(1, 10, 10), new Vector3(0, 7, -10), Vector3.Up);
             proj = Matrix.CreatePerspectiveFieldOfView(MathHelper.ToRadians(45f),
                                        GraphicsDevice.Viewport.Width / GraphicsDevice.Viewport.Height,
                                        1f, 1000.0f);

            // Draw the model.
            foreach (ModelMesh mesh in this._model.Meshes)
            {
               foreach (BasicEffect mesheffect in mesh.Effects)
                {
                    mesheffect.Parameters["Texture"].SetValue(this.cover.coverImage);
                    mesheffect.EnableDefaultLighting();
                    mesheffect.View = view;
                    mesheffect.Projection = proj;
                    mesheffect.World = worldtransform;
                }
                mesh.Draw();
            }
            base.GraphicsDevice.SetRenderTarget(null);
            base.GraphicsDevice.SetRenderTarget(dash.renderTarget2D);
            base.Draw(gameTime);
        }


    }
}

如何在XNA中存储模型的每个实例的矩阵状态

根据我所知,您正在使用下一行的变量worldtransform

mesheffect.World = worldtransform;

并将该值设置为Update:worldtransform = worldTransforms[0];

您遇到的问题是,Matrix是一个结构,将通过值(而不是引用)传递。因此,当您将数组矩阵worldTransforms[0]分配给变量worldtransform时,您正在创建一个全新的实例。

你可以通过以下操作来解决这个问题:

UpdateWorldTransforms(time);
worldtransform = worldTransforms[0];

OR通过引用传递矩阵,并直接修改变量

public void UpdateWorldTransforms(float time, ref Matrix worldMatrix)
{
    worldMatrix = _boneTransforms[0] * Matrix.CreateRotationY(time * 2f);
}

更新

至于存储多个实例,您可以使用这样的模型:

public class WorldObject
{
    public Matrix World { get; set; }
    public Model GameModel { get; set; }
}

并将附加信息存储在该类中。它可以处理更新/绘制信息,并对"世界"变换执行操作。

查看"XNA实例化",但其中一些可能超出的需要

  • 实例化模型
  • 硬件实例化
  • 蒙皮模型实例