如何在XNA中为模型的每个实例存储Matrix的状态?

时间:2013-07-25 18:06:50

标签: c# xna

我有下一个代码部分工作,绘制模型, 我正在创建它的几个实例,并将模型的每个实例渲染到不同的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);
        }




    }
}

1 个答案:

答案 0 :(得分:0)

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

mesheffect.World = worldtransform;

并在更新时设置该值:worldtransform = worldTransforms[0];

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

您可以通过执行以下操作来解决此问题:

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

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

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; }
}

并在该课程中存储其他信息。它可以处理更新/绘图信息并对World变换执行操作。

了解'XNA实例化',但其中一些可能超出您的需要