|
|
@ -52,6 +52,34 @@ using namespace NL3D;
|
|
|
|
|
|
|
|
|
|
|
|
// TODO: Skinned - reverse transform by skeleton root bone to align?
|
|
|
|
// TODO: Skinned - reverse transform by skeleton root bone to align?
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*inline CMatrix convMatrix(const aiMatrix4x4 &tf)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
CMatrix m;
|
|
|
|
|
|
|
|
for (int i = 0; i < 16; ++i)
|
|
|
|
|
|
|
|
m.set(&tf.a1);
|
|
|
|
|
|
|
|
return m;
|
|
|
|
|
|
|
|
}*/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
inline CVector convVector(const aiVector3D &av)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
return CVector(av.x, av.y, av.z); // COORDINATE CONVERSION
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
inline CRGBA convColor(const aiColor4D &ac)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
return CRGBA(ac.r * 255.99f, ac.g * 255.99f, ac.b * 255.99f, ac.a * 255.99f);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
inline CUVW convUvw(const aiVector3D &av)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
return CUVW(av.x, -av.y, av.z); // UH OH COORDINATE CONVERSION ?! ONLY FOR TEXTURES !!
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
inline CQuat convQuat(const aiQuaternion &aq)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
return CQuat(aq.x, aq.y, aq.z, aq.w);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void assimpBuildBaseMesh(CMeshBase::CMeshBaseBuild &buildBaseMesh, CMeshUtilsContext &context, CNodeContext &nodeContext)
|
|
|
|
void assimpBuildBaseMesh(CMeshBase::CMeshBaseBuild &buildBaseMesh, CMeshUtilsContext &context, CNodeContext &nodeContext)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
const aiNode *node = nodeContext.InternalNode;
|
|
|
|
const aiNode *node = nodeContext.InternalNode;
|
|
|
@ -77,21 +105,24 @@ void assimpBuildBaseMesh(CMeshBase::CMeshBaseBuild &buildBaseMesh, CMeshUtilsCon
|
|
|
|
buildBaseMesh.Materials[mi] = *context.SceneMeta.Materials[amname.C_Str()];
|
|
|
|
buildBaseMesh.Materials[mi] = *context.SceneMeta.Materials[amname.C_Str()];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
inline CVector convVector(const aiVector3D &av)
|
|
|
|
// Positioning
|
|
|
|
{
|
|
|
|
const aiMatrix4x4 &root = context.InternalScene->mRootNode->mTransformation;
|
|
|
|
return CVector(-av.x, av.z, av.y); // COORDINATE CONVERSION
|
|
|
|
const aiMatrix4x4 &tf = nodeContext.InternalNode->mTransformation; // COORDINATE CONVERSION HERE INSTEAD OF PER VERTEX ??
|
|
|
|
}
|
|
|
|
aiVector3D scaling;
|
|
|
|
|
|
|
|
aiQuaternion rotation;
|
|
|
|
inline CRGBA convColor(const aiColor4D &ac)
|
|
|
|
aiVector3D position;
|
|
|
|
{
|
|
|
|
tf.Decompose(scaling, rotation, position);
|
|
|
|
return CRGBA(ac.r * 255.99f, ac.g * 255.99f, ac.b * 255.99f, ac.a * 255.99f);
|
|
|
|
buildBaseMesh.DefaultScale = convVector(scaling);
|
|
|
|
}
|
|
|
|
buildBaseMesh.DefaultRotQuat = convQuat(rotation);
|
|
|
|
|
|
|
|
buildBaseMesh.DefaultRotEuler = CVector(0, 0, 0);
|
|
|
|
inline CUVW convUvw(const aiVector3D &av)
|
|
|
|
buildBaseMesh.DefaultPivot = CVector(0, 0, 0);
|
|
|
|
{
|
|
|
|
buildBaseMesh.DefaultPos = convVector(position);
|
|
|
|
return CUVW(av.x, av.y, av.z); // UH OH COORDINATE CONVERSION ?!
|
|
|
|
|
|
|
|
|
|
|
|
// Meta
|
|
|
|
|
|
|
|
// dst.CollisionMeshGeneration = src.CollisionMeshGeneration;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// TODO: Morph
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool assimpBuildMesh(CMesh::CMeshBuild &buildMesh, CMeshBase::CMeshBaseBuild &buildBaseMesh, CMeshUtilsContext &context, CNodeContext &nodeContext)
|
|
|
|
bool assimpBuildMesh(CMesh::CMeshBuild &buildMesh, CMeshBase::CMeshBaseBuild &buildBaseMesh, CMeshUtilsContext &context, CNodeContext &nodeContext)
|
|
|
@ -139,7 +170,7 @@ bool assimpBuildMesh(CMesh::CMeshBuild &buildMesh, CMeshBase::CMeshBaseBuild &bu
|
|
|
|
|
|
|
|
|
|
|
|
// Meshes in assimp are separated per material, so we need to re-merge them for the mesh build process
|
|
|
|
// Meshes in assimp are separated per material, so we need to re-merge them for the mesh build process
|
|
|
|
// This process also deduplicates vertices
|
|
|
|
// This process also deduplicates vertices
|
|
|
|
bool cleanupMesh = false;
|
|
|
|
bool cleanupMesh = true;
|
|
|
|
sint32 numVertices = 0;
|
|
|
|
sint32 numVertices = 0;
|
|
|
|
for (unsigned int mi = 0; mi < node->mNumMeshes; ++mi)
|
|
|
|
for (unsigned int mi = 0; mi < node->mNumMeshes; ++mi)
|
|
|
|
numVertices += context.InternalScene->mMeshes[node->mMeshes[mi]]->mNumVertices;
|
|
|
|
numVertices += context.InternalScene->mMeshes[node->mMeshes[mi]]->mNumVertices;
|
|
|
@ -208,7 +239,7 @@ bool assimpBuildMesh(CMesh::CMeshBuild &buildMesh, CMeshBase::CMeshBaseBuild &bu
|
|
|
|
numUVChannels = CVertexBuffer::MaxStage;
|
|
|
|
numUVChannels = CVertexBuffer::MaxStage;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for (unsigned int ui = 0; ui < numUVChannels; ++ui)
|
|
|
|
for (unsigned int ui = 0; ui < numUVChannels; ++ui)
|
|
|
|
buildMesh.VertexFlags |= (CVertexBuffer::TexCoord0 << ui); // TODO: Coord UV tex stage rerouting
|
|
|
|
buildMesh.VertexFlags |= (CVertexBuffer::TexCoord0Flag << ui); // TODO: Coord UV tex stage rerouting
|
|
|
|
|
|
|
|
|
|
|
|
// TODO: Channels do in fact differ between submeshes, so we need to correctly recount and reroute the materials properly
|
|
|
|
// TODO: Channels do in fact differ between submeshes, so we need to correctly recount and reroute the materials properly
|
|
|
|
if (numColorChannels != refNumColorChannels)
|
|
|
|
if (numColorChannels != refNumColorChannels)
|
|
|
@ -227,6 +258,13 @@ bool assimpBuildMesh(CMesh::CMeshBuild &buildMesh, CMeshBase::CMeshBaseBuild &bu
|
|
|
|
"(%s) Face %i on mesh %i has %i faces", node->mName.C_Str(), fi, mi, af.mNumIndices);
|
|
|
|
"(%s) Face %i on mesh %i has %i faces", node->mName.C_Str(), fi, mi, af.mNumIndices);
|
|
|
|
continue; // return false; Keep going, just drop the face for better user experience
|
|
|
|
continue; // return false; Keep going, just drop the face for better user experience
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (cleanupMesh)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
if (vertexRemapping[mi][af.mIndices[0]] == vertexRemapping[mi][af.mIndices[1]]
|
|
|
|
|
|
|
|
|| vertexRemapping[mi][af.mIndices[1]] == vertexRemapping[mi][af.mIndices[2]]
|
|
|
|
|
|
|
|
|| vertexRemapping[mi][af.mIndices[2]] == vertexRemapping[mi][af.mIndices[0]])
|
|
|
|
|
|
|
|
continue; // Not a triangle
|
|
|
|
|
|
|
|
}
|
|
|
|
CMesh::CFace &face = buildMesh.Faces[numFaces];
|
|
|
|
CMesh::CFace &face = buildMesh.Faces[numFaces];
|
|
|
|
face.MaterialId = mi;
|
|
|
|
face.MaterialId = mi;
|
|
|
|
face.SmoothGroup = 0; // No smoothing groups (bitfield)
|
|
|
|
face.SmoothGroup = 0; // No smoothing groups (bitfield)
|
|
|
@ -279,7 +317,12 @@ bool assimpBuildMesh(CMesh::CMeshBuild &buildMesh, CMeshBase::CMeshBaseBuild &bu
|
|
|
|
++numFaces;
|
|
|
|
++numFaces;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (numFaces != buildMesh.Faces.size())
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
tlmessage(context.ToolLogger, context.Settings.SourceFilePath.c_str(),
|
|
|
|
|
|
|
|
"Removed %u degenerate faces in shape '%s'", (uint32)(buildMesh.Faces.size() - numFaces), node->mName.C_Str());
|
|
|
|
buildMesh.Faces.resize(numFaces);
|
|
|
|
buildMesh.Faces.resize(numFaces);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// clear for MRM info
|
|
|
|
// clear for MRM info
|
|
|
|
buildMesh.Interfaces.clear();
|
|
|
|
buildMesh.Interfaces.clear();
|
|
|
|