【发布时间】:2010-06-20 19:39:01
【问题描述】:
大家好,我一直在 XNA 中从事这个小项目,目标非常基本 我有一个 3D 模型,它会在屏幕上的某个位置弹出,假设对象在它的 y 轴上旋转,
问题是: 取而代之的是模型围绕自己旋转,并且开始围绕它们自己和屏幕中的 0,0,0 点之间的中点旋转,所以看起来中间模型在正常旋转,而其他 2 个在前面提到的方式(包括下面旋转模型的img)。
“一些”更多细节
我的架构是这样的,我有 3 个模型(他们接受 Game、Position、Size @ their ctor)
private void initDradles()
{
m_Dradles[0] = new DradlePositionColor(this, new Vector3(15, 0, 0), 8);
m_Dradles[1] = new DradlePositionColor(this, new Vector3(0, 0, 0), 8);
m_Dradles[2] = new DradlePositionColor(this, new Vector3(-15, 0, 0), 8);
this.Components.Add(m_Dradles[0]);
this.Components.Add(m_Dradles[1]);
this.Components.Add(m_Dradles[2]);
}
这些模型首先以如下图 1 所示的方式出现在屏幕上
它们都共享相同的 BasicEffect 着色器,但具有不同的世界矩阵
模型的基本效果创建和分配
protected override void Initialize()
{
float k_NearPlaneDistance = 0.5f;
float k_FarPlaneDistance = 1000.0f;
float k_ViewAngle = MathHelper.PiOver4;
// we are storing the field-of-view data in a matrix:
m_ProjectionFieldOfView = Matrix.CreatePerspectiveFieldOfView(
k_ViewAngle,
GraphicsDevice.Viewport.AspectRatio,
k_NearPlaneDistance,
k_FarPlaneDistance);
// we want to shoot the center of the world:
Vector3 targetPosition = new Vector3(0, 0, 0);//Vector3.Zero;
// we are standing 100 units in front of our target:
Vector3 pointOfViewPosition = new Vector3(0, 0, 130);
// we are not standing on our head:
Vector3 pointOfViewUpDirection = new Vector3(0, 1, 0);
// we are storing the point-of-view data in a matrix:
m_PointOfView = Matrix.CreateLookAt(
pointOfViewPosition, targetPosition, pointOfViewUpDirection);
base.Initialize();
}
protected override void LoadContent()
{
// we are working with the out-of-the box shader that comes with XNA:
m_BasicEffect = new BasicEffect(this.GraphicsDevice, null);
m_BasicEffect.View = m_PointOfView;
m_BasicEffect.Projection = m_ProjectionFieldOfView;
m_BasicEffect.VertexColorEnabled = true;
// we are working with colored vertices
GraphicsDevice.VertexDeclaration = new VertexDeclaration(
GraphicsDevice, VertexPositionColor.VertexElements);
// we did not use certain clockwise ordering in our vertex buffer
// and we don't want antthing to be culled away..
this.GraphicsDevice.RenderState.CullMode = CullMode.None;
foreach (var dradle in m_Dradles)
{
dradle.BasicEffect = m_BasicEffect;
}
base.LoadContent();
}
在每个模型的更新方法中都有这段代码:
private void BuildWorldMatrix()
{
m_WorldMatrix = Matrix.Identity;
m_WorldMatrix *= Matrix.CreateScale(m_Scales);
m_WorldMatrix *= Matrix.CreateRotationX(m_Rotations.X);
m_WorldMatrix *= Matrix.CreateRotationY(m_Rotations.Y);
m_WorldMatrix *= Matrix.CreateRotationZ(m_Rotations.Z);
m_WorldMatrix *= Matrix.CreateTranslation(m_Position);
///*I*/ Matrix.Identity *
///*S*/ Matrix.CreateScale(m_Scales) *
///*R*/ Matrix.CreateRotationX(m_Rotations.X) *
// Matrix.CreateRotationY(m_Rotations.Y) *
// Matrix.CreateRotationZ(m_Rotations.Z) *
///* No Orbit */
///*T*/ Matrix.CreateTranslation(m_Position);
}
public override void Update(GameTime gameTime)
{
m_Rotations.Y += (float)gameTime.ElapsedGameTime.TotalSeconds;
BuildWorldMatrix();
base.Update(gameTime);
}
以及draw方法中的这段代码
public override void Draw(GameTime gameTime)
{
m_BasicEffect.World = m_WorldMatrix;
m_BasicEffect.Begin();
foreach (EffectPass pass in m_BasicEffect.CurrentTechnique.Passes)
{
pass.Begin();
Render();
pass.End();
}
m_BasicEffect.End();
base.Draw(gameTime);
}
public override void Render()
{
renderVerticesBox(m_BodyVertices);
renderVerticesBox(m_HandleVertices);
Game.GraphicsDevice.DrawUserPrimitives<VertexPositionColor>(
PrimitiveType.TriangleFan, m_PyramidVertices, 0, 4);
}
private void renderVerticesBox(VertexPositionColor[] m_Vertices)
{
Game.GraphicsDevice.DrawUserPrimitives<VertexPositionColor>(
PrimitiveType.TriangleStrip, m_Vertices, 0, 8);
Game.GraphicsDevice.DrawUserPrimitives<VertexPositionColor>(
PrimitiveType.TriangleStrip, m_Vertices, 10, 2);
Game.GraphicsDevice.DrawUserPrimitives<VertexPositionColor>(
PrimitiveType.TriangleStrip, m_Vertices, 14, 2);
}
旋转时的图像 alt text http://www.freeimagehosting.net/uploads/b0aa83d0d6.png
启动时的图像
alt text http://www.freeimagehosting.net/uploads/ee9e5c379c.png
【问题讨论】: