>我写了一个自定义的OBJ文件导入器,效果很好但是不够强大,无法支持所有内容。我已经决定了给AssImp一个机会。我遵循了一些教程并进行了设置我在顶点、tex 坐标、法线和索引中读取的代码我已成功加载我的 OBJ 立方体模型自定义导入器。立方体模型的面无法正确渲染,而是只渲染立方体的几个 tri。屁股屁股的方式处理数据显然与我的解决方案略有不同因为法线、位置/顶点、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;
}
我的其余代码位于(网格类在源代码/图形中):https://github.com/BennetLeff/PhySim
D
所以我只会评论你的assimp
用法。
使用更多的预处理选项怎么样:
aiProcess_SortByPType |
aiProcess_RemoveRedundantMaterials |
aiProcess_PreTransformVertices |
aiProcess_GenUVCoords |
aiProcess_OptimizeMeshes |
aiProcess_OptimizeGraph
这对于.obj
文件可能没有那么有用,但如果您想读取其他格式,则会在以后使用。
同样对于简单的.obj
文件,这可能就足够了:
const aiMesh* mesh = scene.mMeshes[0];
但有时它会选择错误的网格,因此您应该使用从 scene.mRootNode
开始到 scene.mNumChildren
的aiNode*
递归迭代。
我 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);
}
QVector
这里的是 float
的平面数组,所以当你使用 vec3
和 vec2
时,它与你的代码有点不兼容。