一个模型与另一个模型重叠,应该是相反的
本文关键字:模型 另一个 一个 重叠 | 更新日期: 2023-09-27 18:08:29
我目前正在尝试开发一款3D乒乓球游戏。我的问题是,当绘制表和球拍,表是目前重叠的球拍,这应该是另一种方式。有人能帮忙吗?
下面是部分代码:
Model table;
Model racket;
Vector3 modelPosition = new Vector3(0,100,150);
Vector3 modelPosition_table = new Vector3(0,40,0);
// Set the position of the camera in world space, for our view matrix.
Vector3 cameraPosition_racket = new Vector3(0.0f, 1000.0f, 10.0f);
Vector3 cameraPosition_table = new Vector3(0.0f, 150.0f, 250.0f);
void Draw_Racket()
{
// Copy any parent transforms.
Matrix[] transforms_racket = new Matrix[racket.Bones.Count];
racket.CopyAbsoluteBoneTransformsTo(transforms_racket);
// Draw the model. A model can have multiple meshes, so loop.
foreach (ModelMesh mesh in racket.Meshes)
{
// This is where the mesh orientation is set, as well
// as our camera and projection.
foreach (BasicEffect effect in mesh.Effects)
{
effect.EnableDefaultLighting();
effect.World = transforms_racket[mesh.ParentBone.Index] * Matrix.CreateRotationY(modelRotation) * Matrix.CreateTranslation(modelPosition);
effect.View = Matrix.CreateLookAt(cameraPosition_racket, Vector3.Up, Vector3.Up);
effect.Projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.ToRadians(45.0f), aspectRatio, 1.0f, 10000.0f);
}
// Draw the mesh, using the effects set above.
mesh.Draw();
}
}
void Draw_Table()
{
// Copy any parent transforms.
Matrix[] transforms_table = new Matrix[table.Bones.Count];
table.CopyAbsoluteBoneTransformsTo(transforms_table);
// Draw the model. A model can have multiple meshes, so loop.
foreach (ModelMesh mesh in table.Meshes)
{
// This is where the mesh orientation is set, as well
// as our camera and projection.
foreach (BasicEffect effect in mesh.Effects)
{
effect.EnableDefaultLighting();
effect.World = transforms_table[mesh.ParentBone.Index] * Matrix.CreateTranslation(modelPosition_table);
effect.View = Matrix.CreateLookAt(cameraPosition_table, Vector3.Down, Vector3.Up);
effect.Projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.ToRadians(45.0f), aspectRatio, 1.0f, 1000.0f);
}
// Draw the mesh, using the effects set above.
mesh.Draw();
}
}
protected override void Draw(GameTime gameTime)
{
graphics.GraphicsDevice.Clear(Color.CornflowerBlue);
Draw_Table();
Draw_Racket();
base.Draw(gameTime);
}
如果你需要更多的代码,请告诉我。提前感谢:)
编辑……
@Pablo Ariel..我现在明白了,意识到,而不是试图改变相机,我可以在x轴上旋转球拍,并设法得到我想要的,但现在一个问题是球拍有点大..这里是新的代码..
// Set the 3D model to draw.
Model table;
Model racket;
// The aspect ratio determines how to scale 3d to 2d projection.
float aspectRatio;
// Set the position of the model in world space, and set the rotation.
Vector3 modelPosition = new Vector3(0,250,-25);
Vector3 modelPosition_table = new Vector3(0,40,500);
float modelRotation = (MathHelper.Pi*3)/2;
Vector3 cameraPosition;
Vector3 cameraTarget;
Matrix mWorld;
Matrix mWorld1;
Matrix mView;
Matrix mView1;
Matrix mProjection;
protected override void Initialize()
{
// TODO: Add your initialization logic here
graphics.PreferredBackBufferWidth = 1000;
graphics.PreferredBackBufferHeight = 500;
graphics.IsFullScreen = false;
graphics.ApplyChanges();
Window.Title = "Table Tennis 3D";
mProjection = Matrix.CreatePerspectiveFieldOfView(MathHelper.ToRadians(45.0f), 1.0f, 1.0f, 10000.0f);
cameraPosition = modelPosition;
cameraTarget = modelPosition_table;
modelPosition_table.Z += 40;
mView = Matrix.CreateLookAt(cameraPosition, cameraTarget, Vector3.Up);
cameraPosition.Z -= 300;
modelPosition.Y -= 100;
mView1 = Matrix.CreateLookAt(cameraPosition, cameraTarget, Vector3.Up);
base.Initialize();
}
protected override void Draw(GameTime gameTime)
{
graphics.GraphicsDevice.Clear(Color.CornflowerBlue);
mWorld = Matrix.CreateRotationY(modelRotation) * Matrix.CreateRotationX(modelRotation) * Matrix.CreateTranslation(modelPosition);
mWorld1 = Matrix.CreateTranslation(modelPosition_table);
Draw_Table();
Draw_Racket();
base.Draw(gameTime);
}
void Draw_Table()
{
// Copy any parent transforms.
Matrix[] transforms_table = new Matrix[table.Bones.Count];
table.CopyAbsoluteBoneTransformsTo(transforms_table);
// Draw the model. A model can have multiple meshes, so loop.
foreach (ModelMesh mesh in table.Meshes)
{
// This is where the mesh orientation is set, as well
// as our camera and projection.
foreach (BasicEffect effect in mesh.Effects)
{
effect.EnableDefaultLighting();
effect.World = transforms_table[mesh.ParentBone.Index] * mWorld1;
effect.View = mView;
effect.Projection = mProjection;
}
// Draw the mesh, using the effects set above.
mesh.Draw();
}
}
void Draw_Racket()
{
Matrix[] transforms_racket = new Matrix[racket.Bones.Count];
racket.CopyAbsoluteBoneTransformsTo(transforms_racket);
// Draw the model. A model can have multiple meshes, so loop.
foreach (ModelMesh mesh in racket.Meshes)
{
// This is where the mesh orientation is set, as well
// as our camera and projection.
foreach (BasicEffect effect in mesh.Effects)
{
effect.EnableDefaultLighting();
effect.World = transforms_racket[mesh.ParentBone.Index] * mWorld;
effect.View = mView1;
effect.Projection = mProjection;
}
// Draw the mesh, using the effects set above.
mesh.Draw();
}
}
我应该为球拍做一个新的投影,这样我就可以把它的大小变成一半吗?我试过改变它的z位置,但没有运气:/…再次感谢:)ps..这里有一个截图..http://i1099.photobucket.com/albums/g395/krt_ricci/3.png
编辑……我将球拍的世界矩阵与matrix . createscale (0.5f, 0.5f, 0.5f)相乘,这样球拍就按比例缩小了一半:)
我认为这是错误的:
Matrix.CreateLookAt(cameraPosition_racket, Vector3.Up, Vector3.Up);
应该是:
Matrix.CreateLookAt(cameraPosition, cameraTarget, Vector3.Up);
我的建议是,你不应该使用像1000.0f这样的大数字作为位置,除非这是你的游戏架构所需要的,但使用较小的比例会更好,因为浮点数不精确。
如果你把相机放在球拍所在的地方,那么你的相机可能会在球拍内部,你将无法看到它(因为背面剔除,你无法从球拍内部看到人脸)
除此之外,我无法从这个代码中找出什么可能是错误的,但是错误的视图矩阵可能会以一种扰乱深度缓冲区的方式反转你的z值。
这很复杂,因为我不明白相机向量应该是什么,你应该为相机使用3个向量:camerposition, cameraTarget和cameraUp,然后它会更清楚你想要相机指向哪里,如果你改变相机值你不必修改矩阵创建,但只需分配另一个向量。
编辑:看,有些地方你必须修改
首先,计算每个骨骼的视图和投影矩阵(场景中的每个网格都是相同的)是非常糟糕的,因为生成矩阵真的很慢特别是在c# 中,所以你应该设法这样做:effect.View = mView;
和投影矩阵相同。
这就是你出错的原因,因为生成矩阵的次数太多了,你构建了2个不同的投影矩阵:
你可以在DrawRacket():
effect.Projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.ToRadians(45.0f), aspectRatio, 1.0f, 10000.0f);
and
effect.Projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.ToRadians(45.0f), aspectRatio, 1.0f, 1000.0f);
你将表网格映射到1到1000,球拍映射到1到10k,然后所有的坐标都会因为一个0而混乱,当你需要为每个对象使用相同的投影矩阵时,所以你应该将其存储为全局变量或c#中处理的其他变量(成员变量或类似的东西)
编辑2:
当然你必须用同一个相机拍摄两个物体!!如果你不这样做,那么每个对象将被绘制,好像相机是在不同的地方!
这是你的固定代码:
Model table;
Model racket;
Vector3 modelPosition = new Vector3(0,100,150);
Vector3 modelPosition_table = new Vector3(0,40,0);
// Set the position of the camera in world space, for our view matrix.
Vector3 cameraPosition_racket = new Vector3(0.0f, 1000.0f, 10.0f);
Vector3 cameraPosition_table = new Vector3(0.0f, 150.0f, 250.0f);
Vector3 cameraPosition = cameraPosition_racket;
Vector3 cameraTarget = new Vector3(0.0f, 0.0f, 0.0f);
Matrix mView = Matrix.CreateLookAt(cameraPosition, cameraTarget, Vector3.Up);
Matrix mProjection = Matrix.CreatePerspectiveFieldOfView(MathHelper.ToRadians(45.0f), aspectRatio, 1.0f, 10000.0f);
void Draw_Racket()
{
// Copy any parent transforms.
Matrix[] transforms_racket = new Matrix[racket.Bones.Count];
racket.CopyAbsoluteBoneTransformsTo(transforms_racket);
// Draw the model. A model can have multiple meshes, so loop.
foreach (ModelMesh mesh in racket.Meshes)
{
// This is where the mesh orientation is set, as well
// as our camera and projection.
foreach (BasicEffect effect in mesh.Effects)
{
effect.EnableDefaultLighting();
effect.World = transforms_racket[mesh.ParentBone.Index] * Matrix.CreateRotationY(modelRotation) * Matrix.CreateTranslation(modelPosition);
effect.View = mView;
effect.Projection = mProjection;
}
// Draw the mesh, using the effects set above.
mesh.Draw();
}
}
void Draw_Table()
{
// Copy any parent transforms.
Matrix[] transforms_table = new Matrix[table.Bones.Count];
table.CopyAbsoluteBoneTransformsTo(transforms_table);
// Draw the model. A model can have multiple meshes, so loop.
foreach (ModelMesh mesh in table.Meshes)
{
// This is where the mesh orientation is set, as well
// as our camera and projection.
foreach (BasicEffect effect in mesh.Effects)
{
effect.EnableDefaultLighting();
effect.World = transforms_table[mesh.ParentBone.Index] * Matrix.CreateTranslation(modelPosition_table);
effect.View = mView;
effect.Projection = mProjection;
}
// Draw the mesh, using the effects set above.
mesh.Draw();
}
}
protected override void Draw(GameTime gameTime)
{
graphics.GraphicsDevice.Clear(Color.CornflowerBlue);
Draw_Table();
Draw_Racket();
base.Draw(gameTime);
}
UPDATE: try this:
Vector3 modelPosition_racket = new Vector3(0,100,100); // former modelPosition
Vector3 modelPosition_table = new Vector3(0,40,500);
// Set the position of the camera in world space, for our view matrix.
Vector3 cameraPosition = modelPosition_racket;
Vector3 cameraPosition.z -= 300;
Vector3 cameraTarget = modelPosition_table;
UPDATE:你必须理解的是,为了正确地显示图像,你正在使用modelPosition将每个对象从其本地坐标空间转换为全局/世界坐标空间(每个模型都有自己的modelPosition)。所有的物体共享相同的坐标空间和相同的投影变换。在全局/世界坐标空间中,您还可以指定摄像机位置,然后根据摄像机的世界变换值构建矩阵。如果你想在世界空间中移动一个对象,你必须修改modelPosition..这并不是我"相信"的方式,这就是3d的工作原理。如果你修改其他值来改变对象的位置,比如投影或视图矩阵,那么这对你没有任何好处,因为它不是那样工作的,你所有的数学都会混乱,你将无法正常工作。