В OpenTK несколько сеток не трансформируются при импорте с использованием Assimp.

Я уверен, что в Интернете есть ответ на этот вопрос, но я не могу его найти. Я импортирую сцену из Blender с несколькими сетками в OpenTK. Библиотека, которую я использую для импорта, называется Assimp-net, а формат файла — Collada (.dae).

Я создал космический корабль из нескольких частей, каждая из которых представляет собой сетку. Теперь, когда я импортирую и рисую, геометрия объектов выглядит нормально, а материалы работают так, как ожидалось. Однако различные части не вращаются, не масштабируются и не перемещаются так, как они отображаются в Blender. Что происходит, так это то, что разные части не связаны, и некоторые кажутся больше/меньше, чем должны, в неправильном месте и т. д.

Есть ли параметр, который мне не хватает при экспорте из Blender, или есть какой-то элемент/функция Assimp, который я могу использовать для преобразования сеток перед их визуализацией?

Импорт файла:

string filename = @"C:\Path\ship.dae";
Scene ship;

//Create a new importer
AssimpImporter importer = new AssimpImporter();

//This is how we add a configuration (each config is its own class)
NormalSmoothingAngleConfig config = new NormalSmoothingAngleConfig(66.0f);
importer.SetConfig(config);

//Import the model
ship = importer.ImportFile(filename, PostProcessPreset.TargetRealTimeMaximumQuality);

//End of example
importer.Dispose();

Рисование сеток (весь обработчик событий «RenderFrame» в OpenTK):

// Clear color/depth buffers
    GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);

    // Define world space
    GL.MatrixMode(MatrixMode.Projection);
    GL.LoadIdentity();
    GL.Ortho(-15.0, 15.0, -15.0, 15.0, 15.0, -15.0);

    // Rotate around X and Y axes for better viewing
    rotateX(xrot);
    rotateY(yrot);

    GL.Enable(EnableCap.ColorMaterial);

    var rootnode = wes10.RootNode;
    foreach (Node node in rootnode.Children)
    {
        //for each node, do
        GL.MatrixMode(MatrixMode.Modelview);  //ensure your current matrix is the model matrix.
        GL.PushMatrix();              //save current model matrix so you can undo next transformations;

        var meshIndices = node.MeshIndices;

        if (meshIndices == null)
            continue;
        else
        {
            Matrix4d convertedTransform = new Matrix4d();
            getConvertedMatrix(node.Transform, ref convertedTransform);
            GL.MultMatrix(ref convertedTransform);

            GL.Begin(BeginMode.Triangles);
            foreach (uint i in meshIndices)
            {
                Mesh mesh = wes10.Meshes[i];

                Material mat = wes10.Materials[mesh.MaterialIndex];

                // Material setup                        
                var spec_color = mat.ColorSpecular;
                var amb_color = mat.ColorAmbient;
                var diff_color = mat.ColorDiffuse;


                float[] mat_specular = { spec_color.R, spec_color.G, spec_color.B, spec_color.A };
                float[] mat_ambient = { amb_color.R, amb_color.G, amb_color.B, amb_color.A };
                float[] mat_diffuse = { diff_color.R, diff_color.G, diff_color.B, diff_color.A };

                float[] mat_shininess = { 0.0f };

                GL.Material(MaterialFace.FrontAndBack, MaterialParameter.Specular, mat_specular);
                GL.Material(MaterialFace.FrontAndBack, MaterialParameter.Ambient, mat_ambient);
                GL.Material(MaterialFace.FrontAndBack, MaterialParameter.Diffuse, mat_diffuse);
                GL.Material(MaterialFace.FrontAndBack, MaterialParameter.Shininess, mat_shininess);

                foreach (Face face in mesh.Faces)
                {
                    foreach (uint indice in face.Indices)
                    {
                        var normal = mesh.Normals[indice];
                        var pos = mesh.Vertices[indice];
                        //var tex = mesh.GetTextureCoords(0)[v];
                        //GL.TexCoord2(tex.X, tex.Y);
                        GL.Normal3(normal.X, normal.Y, normal.Z);
                        GL.Vertex3(pos.X, pos.Y, pos.Z);
                    }
                }
            }                            
        }

        GL.PopMatrix();
    }


    GL.End();                    

    game.SwapBuffers();

Обновлено, чтобы использовать предложения.


person AS7K    schedule 28.03.2014    source источник
comment
наверняка существует матрица преобразования модели, определенная для каждой сетки или на более высоком уровне, который вы упускаете.   -  person j-p    schedule 28.03.2014
comment
Между началом и концом не допускаются матричные операции. ваше начало должно стоять прямо перед циклом синтаксического анализа...   -  person j-p    schedule 02.04.2014
comment
Должен признаться, я чувствую себя дураком, вы правы. Обновлен исходный пост - перенесен вызов GL.Begin. Теперь сетки трансформируются — они выглядят тонкими (масштабируются по оси Y), но в остальном не изменяются. Вероятно, проблема с матрицами преобразования. Я постараюсь решить и дам вам знать   -  person AS7K    schedule 03.04.2014
comment
Вызов MultMatrix действительно работает. Мне также пришлось кое-что сделать в Blender: центрировать курсор в центре 3D-мира, выделить каждую сетку и перейти в Transform->Origin to 3D курсор. Это позволит правильно настроить матрицы преобразования для каждой сетки, ЗА ИСКЛЮЧЕНИЕМ сеток, которые были повернуты, что все еще вызывает у меня проблемы. Если разберусь с этим, напишу как.   -  person AS7K    schedule 05.04.2014


Ответы (1)


В c примере есть матрица преобразования на узел...

aiMultiplyMatrix4(trafo,&nd->mTransformation);

Проверь это:

Если вы не знаете, что делать с этой матрицей, проверьте это, чтобы узнать о матрице куча. (Имейте в виду, что современные OpenGL рекомендуют реализовать собственную матрицу преобразования)

Golobaly, вам нужны следующие шаги для рендеринга (подробности читайте в примере c):

//for each node, do
glMatrixMode (GL_MODELVIEW);  //ensure your current matrix is the model matrix. 
glPushMatrix ();              //save current model matrix so you can undo next transformations;
glMultMatrixf(Transformation);//apply your node matrix

//render your node, in your example it's surely a mesh

glPopMatrix ();               //restore model matrix
person j-p    schedule 28.03.2014
comment
Хм, по какой-то причине это не сработало... Я использую функцию GL.MultMatrix() в OpenTK. Матрица, которую я даю, определенно имеет значения, но, похоже, не имеет никакого эффекта. - person AS7K; 31.03.2014