FBX File import now re-orders vertices and batches all materials together to reduce draw calls
--HG-- extra : convert_revision : svn%3A7752d6cf-9f14-4ad2-affc-04f1e67b81a5/trunk%4020
This commit is contained in:
@@ -279,7 +279,8 @@ void LoadMesh(std::vector<KRResource *> &resources, KFbxGeometryConverter *pGeom
|
|||||||
int uv_count = pMesh->GetElementUVCount();
|
int uv_count = pMesh->GetElementUVCount();
|
||||||
int normal_count = pMesh->GetElementNormalCount();
|
int normal_count = pMesh->GetElementNormalCount();
|
||||||
int tangent_count = pMesh->GetElementTangentCount();
|
int tangent_count = pMesh->GetElementTangentCount();
|
||||||
int material_count = pMesh->GetElementMaterialCount();
|
int elementmaterial_count = pMesh->GetElementMaterialCount();
|
||||||
|
int material_count = pNode->GetMaterialCount();
|
||||||
|
|
||||||
|
|
||||||
printf(" Polygon Count: %i (before triangulation: %i)\n", polygon_count, pSourceMesh->GetPolygonCount());
|
printf(" Polygon Count: %i (before triangulation: %i)\n", polygon_count, pSourceMesh->GetPolygonCount());
|
||||||
@@ -293,185 +294,170 @@ void LoadMesh(std::vector<KRResource *> &resources, KFbxGeometryConverter *pGeom
|
|||||||
std::vector<int> submesh_starts;
|
std::vector<int> submesh_starts;
|
||||||
std::vector<std::string> material_names;
|
std::vector<std::string> material_names;
|
||||||
|
|
||||||
|
|
||||||
int source_vertex_id = 0;
|
|
||||||
int dest_vertex_id = 0;
|
int dest_vertex_id = 0;
|
||||||
KFbxGeometryElementMaterial* pMaterial = NULL;
|
|
||||||
int iMaterial = -1;
|
|
||||||
int mat_vertex_count = 0;
|
|
||||||
int mat_vertex_start = 0;
|
|
||||||
|
|
||||||
for(int iPolygon = 0; iPolygon < polygon_count; iPolygon++) {
|
for(int iMaterial=0; iMaterial < material_count; iMaterial++) {
|
||||||
int lPolygonSize = pMesh->GetPolygonSize(iPolygon);
|
int source_vertex_id = 0;
|
||||||
if(lPolygonSize != 3) {
|
int mat_vertex_count = 0;
|
||||||
source_vertex_id += lPolygonSize;
|
int mat_vertex_start = dest_vertex_id;
|
||||||
printf(" Warning - Poly with %i vertices found. Expecting only triangles.", lPolygonSize);
|
for(int iPolygon = 0; iPolygon < polygon_count; iPolygon++) {
|
||||||
} else {
|
int lPolygonSize = pMesh->GetPolygonSize(iPolygon);
|
||||||
// ----====---- Read SubMesh / Material Mapping ----====----
|
if(lPolygonSize != 3) {
|
||||||
int iPrevMat = iMaterial;
|
source_vertex_id += lPolygonSize;
|
||||||
KFbxGeometryElementMaterial *pPrevMat = pMaterial;
|
printf(" Warning - Poly with %i vertices found. Expecting only triangles.", lPolygonSize);
|
||||||
iMaterial = -1;
|
} else {
|
||||||
pMaterial = NULL;
|
// ----====---- Read SubMesh / Material Mapping ----====----
|
||||||
for (int l = 0; l < material_count; l++)
|
int iNewMaterial = -1;
|
||||||
{
|
for (int l = 0; l < elementmaterial_count; l++)
|
||||||
KFbxGeometryElementMaterial* leMat = pMesh->GetElementMaterial(l);
|
{
|
||||||
if(leMat) {
|
KFbxGeometryElementMaterial* leMat = pMesh->GetElementMaterial(l);
|
||||||
if (leMat->GetReferenceMode() == KFbxGeometryElement::eINDEX || leMat->GetReferenceMode() == KFbxGeometryElement::eINDEX_TO_DIRECT) {
|
if(leMat) {
|
||||||
int new_id = leMat->GetIndexArray().GetAt(iPolygon);
|
if (leMat->GetReferenceMode() == KFbxGeometryElement::eINDEX || leMat->GetReferenceMode() == KFbxGeometryElement::eINDEX_TO_DIRECT) {
|
||||||
if(new_id >= 0) {
|
int new_id = leMat->GetIndexArray().GetAt(iPolygon);
|
||||||
iMaterial = new_id;
|
if(new_id >= 0) {
|
||||||
pMaterial = leMat;
|
iNewMaterial = new_id;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if(iMaterial != iPrevMat) {
|
|
||||||
if(pPrevMat && mat_vertex_count) {
|
|
||||||
submesh_starts.push_back(mat_vertex_start);
|
|
||||||
submesh_lengths.push_back(mat_vertex_count);
|
|
||||||
material_names.push_back(pNode->GetMaterial(iMaterial)->GetName());
|
|
||||||
printf(" Material \"%s\" from %i to %i\n", pNode->GetMaterial(iMaterial)->GetName(), mat_vertex_start, mat_vertex_count + mat_vertex_start - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
mat_vertex_count = 0;
|
if(iMaterial == iNewMaterial) {
|
||||||
mat_vertex_start = dest_vertex_id;
|
// ----====---- Read Vertex-level Attributes ----====----
|
||||||
}
|
for(int iVertex=0; iVertex<3; iVertex++) {
|
||||||
|
// ----====---- Read Vertex Position ----====----
|
||||||
|
int lControlPointIndex = pMesh->GetPolygonVertex(iPolygon, iVertex);
|
||||||
|
KFbxVector4 v = control_points[lControlPointIndex];
|
||||||
// ----====---- Read Vertex-level Attributes ----====----
|
vertices.push_back(KRVector3(v[0], v[1], v[2]));
|
||||||
for(int iVertex=0; iVertex<3; iVertex++) {
|
|
||||||
// ----====---- Read Vertex Position ----====----
|
|
||||||
int lControlPointIndex = pMesh->GetPolygonVertex(iPolygon, iVertex);
|
// ----====---- Read UVs ----====----
|
||||||
KFbxVector4 v = control_points[lControlPointIndex];
|
for (int l = 0; l < uv_count; ++l)
|
||||||
vertices.push_back(KRVector3(v[0], v[1], v[2]));
|
|
||||||
|
|
||||||
|
|
||||||
// ----====---- Read UVs ----====----
|
|
||||||
for (int l = 0; l < uv_count; ++l)
|
|
||||||
{
|
|
||||||
KFbxVector2 uv;
|
|
||||||
KFbxGeometryElementUV* leUV = pMesh->GetElementUV(l);
|
|
||||||
|
|
||||||
switch (leUV->GetMappingMode()) {
|
|
||||||
case KFbxGeometryElement::eBY_CONTROL_POINT:
|
|
||||||
switch (leUV->GetReferenceMode()) {
|
|
||||||
case KFbxGeometryElement::eDIRECT:
|
|
||||||
uv = leUV->GetDirectArray().GetAt(lControlPointIndex);
|
|
||||||
break;
|
|
||||||
case KFbxGeometryElement::eINDEX_TO_DIRECT:
|
|
||||||
{
|
|
||||||
int id = leUV->GetIndexArray().GetAt(lControlPointIndex);
|
|
||||||
uv = leUV->GetDirectArray().GetAt(id);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break; // other reference modes not shown here!
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case KFbxGeometryElement::eBY_POLYGON_VERTEX:
|
|
||||||
{
|
{
|
||||||
int lTextureUVIndex = pMesh->GetTextureUVIndex(iPolygon, iVertex);
|
KFbxVector2 uv;
|
||||||
switch (leUV->GetReferenceMode())
|
KFbxGeometryElementUV* leUV = pMesh->GetElementUV(l);
|
||||||
{
|
|
||||||
case KFbxGeometryElement::eDIRECT:
|
switch (leUV->GetMappingMode()) {
|
||||||
case KFbxGeometryElement::eINDEX_TO_DIRECT:
|
case KFbxGeometryElement::eBY_CONTROL_POINT:
|
||||||
{
|
switch (leUV->GetReferenceMode()) {
|
||||||
uv = leUV->GetDirectArray().GetAt(lTextureUVIndex);
|
case KFbxGeometryElement::eDIRECT:
|
||||||
|
uv = leUV->GetDirectArray().GetAt(lControlPointIndex);
|
||||||
|
break;
|
||||||
|
case KFbxGeometryElement::eINDEX_TO_DIRECT:
|
||||||
|
{
|
||||||
|
int id = leUV->GetIndexArray().GetAt(lControlPointIndex);
|
||||||
|
uv = leUV->GetDirectArray().GetAt(id);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break; // other reference modes not shown here!
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
|
||||||
break; // other reference modes not shown here!
|
case KFbxGeometryElement::eBY_POLYGON_VERTEX:
|
||||||
|
{
|
||||||
|
int lTextureUVIndex = pMesh->GetTextureUVIndex(iPolygon, iVertex);
|
||||||
|
switch (leUV->GetReferenceMode())
|
||||||
|
{
|
||||||
|
case KFbxGeometryElement::eDIRECT:
|
||||||
|
case KFbxGeometryElement::eINDEX_TO_DIRECT:
|
||||||
|
{
|
||||||
|
uv = leUV->GetDirectArray().GetAt(lTextureUVIndex);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break; // other reference modes not shown here!
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case KFbxGeometryElement::eBY_POLYGON: // doesn't make much sense for UVs
|
||||||
|
case KFbxGeometryElement::eALL_SAME: // doesn't make much sense for UVs
|
||||||
|
case KFbxGeometryElement::eNONE: // doesn't make much sense for UVs
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case KFbxGeometryElement::eBY_POLYGON: // doesn't make much sense for UVs
|
if(l == 0) {
|
||||||
case KFbxGeometryElement::eALL_SAME: // doesn't make much sense for UVs
|
uva.push_back(KRVector2(uv[0], uv[1]));
|
||||||
case KFbxGeometryElement::eNONE: // doesn't make much sense for UVs
|
} else if(l == 1) {
|
||||||
break;
|
uvb.push_back(KRVector2(uv[0], uv[1]));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if(l == 0) {
|
|
||||||
uva.push_back(KRVector2(uv[0], uv[1]));
|
// ----====---- Read Normals ----====----
|
||||||
} else if(l == 1) {
|
for(int l = 0; l < normal_count; ++l)
|
||||||
uvb.push_back(KRVector2(uv[0], uv[1]));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ----====---- Read Normals ----====----
|
|
||||||
for(int l = 0; l < normal_count; ++l)
|
|
||||||
{
|
|
||||||
KFbxVector4 new_normal;
|
|
||||||
KFbxGeometryElementNormal* leNormal = pMesh->GetElementNormal(l);
|
|
||||||
|
|
||||||
if(leNormal->GetMappingMode() == KFbxGeometryElement::eBY_POLYGON_VERTEX) {
|
|
||||||
switch (leNormal->GetReferenceMode())
|
|
||||||
{
|
{
|
||||||
case KFbxGeometryElement::eDIRECT:
|
KFbxVector4 new_normal;
|
||||||
new_normal = leNormal->GetDirectArray().GetAt(source_vertex_id);
|
KFbxGeometryElementNormal* leNormal = pMesh->GetElementNormal(l);
|
||||||
break;
|
|
||||||
case KFbxGeometryElement::eINDEX_TO_DIRECT:
|
if(leNormal->GetMappingMode() == KFbxGeometryElement::eBY_POLYGON_VERTEX) {
|
||||||
{
|
switch (leNormal->GetReferenceMode())
|
||||||
int id = leNormal->GetIndexArray().GetAt(source_vertex_id);
|
{
|
||||||
new_normal = leNormal->GetDirectArray().GetAt(id);
|
case KFbxGeometryElement::eDIRECT:
|
||||||
|
new_normal = leNormal->GetDirectArray().GetAt(source_vertex_id);
|
||||||
|
break;
|
||||||
|
case KFbxGeometryElement::eINDEX_TO_DIRECT:
|
||||||
|
{
|
||||||
|
int id = leNormal->GetIndexArray().GetAt(source_vertex_id);
|
||||||
|
new_normal = leNormal->GetDirectArray().GetAt(id);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break; // other reference modes not shown here!
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
if(l == 0) {
|
||||||
default:
|
normals.push_back(KRVector3(new_normal[0], new_normal[1], new_normal[2]));
|
||||||
break; // other reference modes not shown here!
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(l == 0) {
|
|
||||||
normals.push_back(KRVector3(new_normal[0], new_normal[1], new_normal[2]));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// ----====---- Read Tangents ----====----
|
|
||||||
for(int l = 0; l < tangent_count; ++l)
|
|
||||||
{
|
|
||||||
KFbxVector4 new_tangent;
|
|
||||||
KFbxGeometryElementTangent* leTangent = pMesh->GetElementTangent(l);
|
|
||||||
|
|
||||||
if(leTangent->GetMappingMode() == KFbxGeometryElement::eBY_POLYGON_VERTEX) {
|
|
||||||
switch (leTangent->GetReferenceMode()) {
|
|
||||||
case KFbxGeometryElement::eDIRECT:
|
|
||||||
new_tangent = leTangent->GetDirectArray().GetAt(source_vertex_id);
|
|
||||||
break;
|
|
||||||
case KFbxGeometryElement::eINDEX_TO_DIRECT:
|
|
||||||
{
|
|
||||||
int id = leTangent->GetIndexArray().GetAt(source_vertex_id);
|
|
||||||
new_tangent = leTangent->GetDirectArray().GetAt(id);
|
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break; // other reference modes not shown here!
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if(l == 0) {
|
// ----====---- Read Tangents ----====----
|
||||||
tangents.push_back(KRVector3(new_tangent[0], new_tangent[1], new_tangent[2]));
|
for(int l = 0; l < tangent_count; ++l)
|
||||||
}
|
{
|
||||||
|
KFbxVector4 new_tangent;
|
||||||
}
|
KFbxGeometryElementTangent* leTangent = pMesh->GetElementTangent(l);
|
||||||
|
|
||||||
|
if(leTangent->GetMappingMode() == KFbxGeometryElement::eBY_POLYGON_VERTEX) {
|
||||||
|
switch (leTangent->GetReferenceMode()) {
|
||||||
|
case KFbxGeometryElement::eDIRECT:
|
||||||
|
new_tangent = leTangent->GetDirectArray().GetAt(source_vertex_id);
|
||||||
|
break;
|
||||||
|
case KFbxGeometryElement::eINDEX_TO_DIRECT:
|
||||||
|
{
|
||||||
|
int id = leTangent->GetIndexArray().GetAt(source_vertex_id);
|
||||||
|
new_tangent = leTangent->GetDirectArray().GetAt(id);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break; // other reference modes not shown here!
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(l == 0) {
|
||||||
|
tangents.push_back(KRVector3(new_tangent[0], new_tangent[1], new_tangent[2]));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
source_vertex_id++;
|
source_vertex_id++;
|
||||||
dest_vertex_id++;
|
dest_vertex_id++;
|
||||||
mat_vertex_count++;
|
mat_vertex_count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ----====---- Output last material / submesh details ----====----
|
||||||
|
if(mat_vertex_count) {
|
||||||
|
submesh_starts.push_back(mat_vertex_start);
|
||||||
|
submesh_lengths.push_back(mat_vertex_count);
|
||||||
|
material_names.push_back(pNode->GetMaterial(iMaterial)->GetName());
|
||||||
|
printf(" %s: %i - %i\n", pNode->GetMaterial(iMaterial)->GetName(), mat_vertex_start, mat_vertex_count + mat_vertex_start - 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----====---- Complete last material / submesh ----====----
|
|
||||||
if(iMaterial >= 0 && mat_vertex_count) {
|
|
||||||
submesh_starts.push_back(mat_vertex_start);
|
|
||||||
submesh_lengths.push_back(mat_vertex_count);
|
|
||||||
material_names.push_back(pNode->GetMaterial(iMaterial)->GetName());
|
|
||||||
printf(" Material \"%s\" from %i to %i\n", pNode->GetMaterial(iMaterial)->GetName(), mat_vertex_start, mat_vertex_count + mat_vertex_start - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// ----====---- Generate Output Mesh Object ----====----
|
// ----====---- Generate Output Mesh Object ----====----
|
||||||
|
|||||||
Reference in New Issue
Block a user