一个模型与另一个模型重叠,应该是相反的

本文关键字:模型 另一个 一个 重叠 | 更新日期: 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的工作原理。如果你修改其他值来改变对象的位置,比如投影或视图矩阵,那么这对你没有任何好处,因为它不是那样工作的,你所有的数学都会混乱,你将无法正常工作。