одна модель перекрывает другую, должна быть наоборот - PullRequest
1 голос
/ 11 сентября 2011

В настоящее время я пытаюсь разработать игру для настольного тенниса в 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);
    }

Если вам понадобится больше кода, просто дайте мне знать.Заранее спасибо:)

РЕДАКТИРОВАТЬ ...

@ Пабло Ариэль .. да, теперь я понял и понял, что вместо попытки заменить камеру, я мог бы повернуть ракетку на хоси, и мне удалось получить то, что я хочу, но теперь одна проблема в том, что ракетка немного большая ... здесь новый код ..

    // 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..here снимок экрана .. http://i1099.photobucket.com/albums/g395/krt_ricci/3.png

РЕДАКТИРОВАТЬ ... Я умножил свою мировую матрицу для ракетки с Matrix.CreateScale (0,5f, 0,5f, 0,5f), чтобы ракетка была уменьшена вдвое:)

1 Ответ

0 голосов
/ 11 сентября 2011

Я считаю, что это неправильно:

Matrix.CreateLookAt(cameraPosition_racket, Vector3.Up, Vector3.Up);

должно быть:

Matrix.CreateLookAt(cameraPosition, cameraTarget, Vector3.Up);

Рекомендация, которую я хотел бы сделать, заключается в том, что вы не должны использовать такие большие числа, как 1000.0f, в качестве позиций, если, конечно, это не требуется для вашей игровой архитектуры, но использование меньшего масштаба лучше из-за неточности поплавка.

Если вы поместите камеру там, где находится ракетка, тогда ваша камера может оказаться внутри ракетки, и вы не сможете ее увидеть (из-за отбраковки задней поверхности вы не можете видеть лица внутри ракетки)

Кроме этого, я не могу понять из этого кода, что может быть неправильным, но неправильная матрица представления может инвертировать ваши значения z таким образом, что испортит буфер глубины.

Это сложно, потому что я не понимаю, какими должны быть векторы камеры, вы должны использовать 3 вектора для камеры: cameraPosition, cameraTarget и cameraUp, тогда будет яснее, куда вы хотите, чтобы камера указывала, и если вы измените Значения камеры: вам не нужно изменять создание матрицы, а просто назначить другой вектор.

РЕДАКТИРОВАТЬ: Смотри, есть некоторые вещи, которые вы должны изменить

Прежде всего, вычисление матрицы вида и проекции (которые одинаковы для КАЖДОГО меша в сцене) для каждой кости очень плохое, потому что создание матрицы REAALLLLYYY SLOW ОСОБЕННО В C # , поэтому вам следует Удастся просто сделать это: effect.View = mView; и то же самое с матрицей проекции.

Это причина вашей ошибки, потому что, генерируя матрицу столько раз, вы строите 2 разные матрицы проекций:

вы делаете это в DrawRacket ():

effect.Projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.ToRadians(45.0f), aspectRatio, 1.0f, 10000.0f);

и в DrawTable ():

effect.Projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.ToRadians(45.0f), aspectRatio, 1.0f, 1000.0f);

Вы отображаете сетку таблицы на 1 - 1000, а ракетку - на 1 - 10 тыс. Тогда все координаты портятся из-за одного нуля, когда вам нужно использовать одну и ту же матрицу проекции для каждого объекта, поэтому вам следует сохранить это как глобальная переменная или как она обрабатывается в 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);
}

ОБНОВЛЕНИЕ: попробуйте это:

 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;

ОБНОВЛЕНИЕ: То, что вы должны понять, это то, что вы должны правильно показать изображение, то, что вы делаете с modelPosition, переводит каждый объект из его локального координатного пространства в глобальное / мировое координатное пространство (каждая модель имеет свое собственное modelPosition). Там все объекты имеют одинаковое координатное пространство и одинаковое проекционное преобразование. В глобальном / мировом координатном пространстве вы также указываете положение камеры, а затем строите матрицу из значений мирового преобразования камеры. Если вы хотите переместить объект в мировое пространство, вы должны изменить modelPosition .. это не то, что я просто "верю", это то, как работает 3d. Если вы измените другие значения, чтобы изменить положение объекта, например, проекцию или матрицу вида, то это не принесет вам пользы, потому что это не сработает, все ваши вычисления будут испорчены, и вы выиграете не сможет нормально работать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...