-1

我编写了一个自定义的 OBJ 文件导入器,它运行得相当好,但不够强大,无法支持所有内容。我决定给 AssImp 一个机会。我遵循了一些教程并设置了我的代码以读取我已成功使用自定义导入器加载的 OBJ 立方体模型的顶点、tex 坐标、法线和索引。立方体模型的面没有正确渲染,而是只渲染了立方体的几个三角形。AssImp 处理数据的方式显然与我的解决方案有点不同,因为法线、位置/顶点、tex 坐标和索引与我的自定义解决方案不匹配。我非常感谢您了解我遇到问题的原因,因为我发现的所有教程都与我的方法相匹配。如果错误渲染的立方体的图片会有所帮助,我可以制作屏幕截图。谢谢你。

我的资产导入类:

module graphics.assimp;

import std.stdio, std.container, std.range;
import core, graphics;
import derelict.assimp3.assimp;

class AssImp
{
    this()
    {
        DerelictASSIMP3.load();
    }
    IndexedModel makeIndexedModel(vec3[] verts, vec3[] norms, vec2[] uvs, uint[] indices)
    {
        IndexedModel model;
        model.pos = verts;
        model.normals = norms;
        model.texCoords = uvs;
        model.indices = indices;

        writeln("verts: ", model.pos);
        writeln("normals: ", model.normals);
        writeln("texCoords: ", model.texCoords);
        writeln("indices: ", model.indices);

        return model;
    }
    Mesh loadMesh(const char* fileName)
    {
        const aiScene* scene = aiImportFile(fileName, aiProcessPreset_TargetRealtime_Fast | aiProcess_Triangulate | aiProcess_JoinIdenticalVertices);
        const aiMesh* mesh = scene.mMeshes[0];

        numVerts = mesh.mNumFaces * 3;

        vertArray = new vec3[mesh.mNumFaces];
        normalArray = new vec3[mesh.mNumFaces];
        uvArray = new vec2[mesh.mNumFaces];
        int indexCount;
        for (uint i = 0; i < mesh.mNumFaces; i++)
        {
            const aiFace face = mesh.mFaces[i];
            indexCount += face.mNumIndices;

            for (int j = 0; j < 3; j++)
            {
                aiVector3D uv = mesh.mTextureCoords[0][face.mIndices[j]];
                uvArray[i] = vec2(uv.x, uv.y);

                aiVector3D normal = mesh.mNormals[face.mIndices[j]];
                normalArray[i] = vec3(normal.x, normal.y, normal.z);

                aiVector3D pos = mesh.mVertices[face.mIndices[j]];
                vertArray[i] = vec3(pos.x, pos.y, pos.z);

                indices.insert(face.mIndices[j]);
            }
        }
        return new Mesh(makeIndexedModel(vertArray, normalArray, uvArray, indices.array));      
    }
private:
    vec3 vertArray[];
    vec3 normalArray[];
    vec2 uvArray[];
    auto indices = make!(Array!uint)();
    int numVerts;
}

我的其余代码位于(Mesh Class 在源代码/图形中): https ://github.com/BennetLeff/PhySim

4

1 回答 1

0

我不知道D,所以我只会评论您的assimp使用情况。

如何使用更多的预处理选项:

aiProcess_SortByPType |
aiProcess_RemoveRedundantMaterials |
aiProcess_PreTransformVertices |
aiProcess_GenUVCoords |
aiProcess_OptimizeMeshes |
aiProcess_OptimizeGraph

这可能对.obj文件没有那么有用,但如果您想阅读其他格式,稍后会变得有用。

同样对于一个简单的.obj文件,这可能就足够了:

const aiMesh* mesh = scene.mMeshes[0];

aiNode*但有时它会选择错误的网格,因此您应该使用start fromscene.mRootNode和 to递归迭代scene.mNumChildren

我 100% 确定这mesh.mNumFaces不是顶点数组的大小。你可以看看我的 C++ 代码,相信你会明白其中的逻辑。

aiMesh *ptr = nullptr; // Set to mesh you want to process
QVector<float> outVertices, outUVs, outNormals;
QVector<uint> outIndices;


qDebug() << "Mesh name: " << ptr->mName.C_Str();
const uint n_vertices = ptr->mNumVertices;
qDebug() << "Num vertices: " << n_vertices;


outVertices.resize(n_vertices * 3);
float * data = reinterpret_cast<float*>(ptr->mVertices);
copy_n(data, outVertices.size(), outVertices.data());

outUVs.resize(n_vertices * 2);
for(uint i = 0; i < n_vertices; i++)
{
    aiVector3D & vec = ptr->mTextureCoords[0][i];
    outUVs[i*2] = vec.x;
    outUVs[i*2+1] = vec.y;
}

outNormals.resize(n_vertices * 3);
data = reinterpret_cast<float*>(ptr->mNormals);
copy_n(data, outNormals.size(), outNormals.data());


for(uint i = 0; i < ptr->mNumFaces; i++)
{
    aiFace face = ptr->mFaces[i];
    const uint n_indices = face.mNumIndices;
    const uint current_size = outIndices.size();

    outIndices.resize(current_size + n_indices);
    copy_n(face.mIndices, n_indices, outIndices.data() + current_size);
}

QVectors 这里是 的平面数组,因此当您使用andfloat时,它与您的代码有点不兼容。vec3vec2

于 2015-03-28T06:33:15.427 回答