-1

私はカスタム OBJ ファイル インポーターを作成しましたが、これはかなりうまく機能しましたが、すべてをサポートできるほど堅牢ではありませんでした。AssImpを試してみることにしました。いくつかのチュートリアルに従い、カスタム インポーターでの読み込みに成功した OBJ キューブ モデルの頂点、tex 座標、法線、およびインデックスを読み取るようにコードを設定しました。立方体モデルの面が適切にレンダリングされず、立方体のいくつかのトライがレンダリングされるだけです。法線、位置/頂点、tex 座標、およびインデックスがカスタム ソリューションと一致しないため、AsImp がデータを処理する方法は明らかに私のソリューションとは少し異なります。私が見つけたすべてのチュートリアルが私のアプローチと一致しているため、問題が発生している理由についての洞察をいただければ幸いです。不完全なレンダリングされた立方体の写真が役立つ場合は、スクリーンショットをアップする作業を行うことができます。ありがとうございました。

私のアセットインポートクラス:

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;
}

私のコードの残りの部分は次の場所にあります (メッシュ クラスは source/graphics にあります): 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*fromscene.mRootNodeと toを使用して再帰的に反復する必要がありますscene.mNumChildren

mesh.mNumFaces頂点配列のサイズではないことは 100% 確信しています。私の 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);
}

QVectorここの s は のフラット配列であるため、 およびfloatを使用する場合、コードとは少し互換性がありません。vec3vec2

于 2015-03-28T06:33:15.427 に答える