如何在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);
}
}
}
根据我所知,您正在使用下一行的变量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实例化",但其中一些可能超出的需要
- 实例化模型
- 硬件实例化
- 蒙皮模型实例