- fbx: support ByPolygon mapping for materials, refactor code to read material indices.
parent
e821988c64
commit
3f10314656
|
@ -262,7 +262,7 @@ void ReadVectorDataArray(std::vector<aiVector2D>& out, const Element& el)
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// read an array of ints
|
// read an array of ints
|
||||||
void ReadIntDataArray(std::vector<int>& out, const Element& el)
|
void ReadVectorDataArray(std::vector<int>& out, const Element& el)
|
||||||
{
|
{
|
||||||
out.clear();
|
out.clear();
|
||||||
const TokenList& tok = el.Tokens();
|
const TokenList& tok = el.Tokens();
|
||||||
|
@ -279,6 +279,30 @@ void ReadIntDataArray(std::vector<int>& out, const Element& el)
|
||||||
out.push_back(ival);
|
out.push_back(ival);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
// read an array of uints
|
||||||
|
void ReadVectorDataArray(std::vector<unsigned int>& out, const Element& el)
|
||||||
|
{
|
||||||
|
out.clear();
|
||||||
|
const TokenList& tok = el.Tokens();
|
||||||
|
const size_t dim = ParseTokenAsDim(*tok[0]);
|
||||||
|
|
||||||
|
// see notes in ReadVectorDataArray()
|
||||||
|
out.reserve(dim);
|
||||||
|
|
||||||
|
const Scope& scope = GetRequiredScope(el);
|
||||||
|
const Element& a = GetRequiredElement(scope,"a",&el);
|
||||||
|
|
||||||
|
for (TokenList::const_iterator it = a.Tokens().begin(), end = a.Tokens().end(); it != end; ) {
|
||||||
|
const int ival = ParseTokenAsInt(**it++);
|
||||||
|
if(ival < 0) {
|
||||||
|
DOMError("encountered negative integer index");
|
||||||
|
}
|
||||||
|
out.push_back(static_cast<unsigned int>(ival));
|
||||||
|
}
|
||||||
|
}
|
||||||
} // end anon.
|
} // end anon.
|
||||||
|
|
||||||
|
|
||||||
|
@ -387,7 +411,7 @@ MeshGeometry::MeshGeometry(const Element& element, const std::string& name)
|
||||||
ReadVectorDataArray(tempVerts,Vertices);
|
ReadVectorDataArray(tempVerts,Vertices);
|
||||||
|
|
||||||
std::vector<int> tempFaces;
|
std::vector<int> tempFaces;
|
||||||
ReadIntDataArray(tempFaces,PolygonVertexIndex);
|
ReadVectorDataArray(tempFaces,PolygonVertexIndex);
|
||||||
|
|
||||||
vertices.reserve(tempFaces.size());
|
vertices.reserve(tempFaces.size());
|
||||||
faces.reserve(tempFaces.size() / 3);
|
faces.reserve(tempFaces.size() / 3);
|
||||||
|
@ -515,32 +539,34 @@ void MeshGeometry::ReadVertexData(const std::string& type, int index, const Scop
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReadVertexDataUV(uvs[index],source,MappingInformationType,ReferenceInformationType);
|
ReadVertexDataUV(uvs[index],source,
|
||||||
|
MappingInformationType,
|
||||||
|
ReferenceInformationType
|
||||||
|
);
|
||||||
}
|
}
|
||||||
else if (type == "LayerElementMaterial") {
|
else if (type == "LayerElementMaterial") {
|
||||||
|
ReadVertexDataMaterials(materials,source,
|
||||||
materials.resize(vertices.size());
|
MappingInformationType,
|
||||||
|
ReferenceInformationType
|
||||||
std::vector<int> tempMaterials;
|
);
|
||||||
ReadIntDataArray(tempMaterials,GetRequiredElement(source,"Materials"));
|
|
||||||
|
|
||||||
if (MappingInformationType == "AllSame") {
|
|
||||||
// easy - same material for all faces
|
|
||||||
materials.assign(vertices.size(),tempMaterials[0]);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
FBXImporter::LogError(Formatter::format("ignoring material assignments, unrecognized access type: ")
|
|
||||||
<< MappingInformationType << "," << ReferenceInformationType);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (type == "LayerElementNormal") {
|
else if (type == "LayerElementNormal") {
|
||||||
ReadVertexDataNormals(normals,source,MappingInformationType,ReferenceInformationType);
|
ReadVertexDataNormals(normals,source,
|
||||||
|
MappingInformationType,
|
||||||
|
ReferenceInformationType
|
||||||
|
);
|
||||||
}
|
}
|
||||||
else if (type == "LayerElementTangent") {
|
else if (type == "LayerElementTangent") {
|
||||||
ReadVertexDataTangents(tangents,source,MappingInformationType,ReferenceInformationType);
|
ReadVertexDataTangents(tangents,source,
|
||||||
|
MappingInformationType,
|
||||||
|
ReferenceInformationType
|
||||||
|
);
|
||||||
}
|
}
|
||||||
else if (type == "LayerElementBinormal") {
|
else if (type == "LayerElementBinormal") {
|
||||||
ReadVertexDataBinormals(binormals,source,MappingInformationType,ReferenceInformationType);
|
ReadVertexDataBinormals(binormals,source,
|
||||||
|
MappingInformationType,
|
||||||
|
ReferenceInformationType
|
||||||
|
);
|
||||||
}
|
}
|
||||||
else if (type == "LayerElementColor") {
|
else if (type == "LayerElementColor") {
|
||||||
if(index >= AI_MAX_NUMBER_OF_COLOR_SETS) {
|
if(index >= AI_MAX_NUMBER_OF_COLOR_SETS) {
|
||||||
|
@ -549,7 +575,10 @@ void MeshGeometry::ReadVertexData(const std::string& type, int index, const Scop
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReadVertexDataColors(colors[index],source,MappingInformationType,ReferenceInformationType);
|
ReadVertexDataColors(colors[index],source,
|
||||||
|
MappingInformationType,
|
||||||
|
ReferenceInformationType
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -588,7 +617,7 @@ void ResolveVertexDataArray(std::vector<T>& data_out, const Scope& source,
|
||||||
data_out.resize(vertex_count);
|
data_out.resize(vertex_count);
|
||||||
|
|
||||||
std::vector<int> uvIndices;
|
std::vector<int> uvIndices;
|
||||||
ReadIntDataArray(uvIndices,GetRequiredElement(source,indexDataElementName));
|
ReadVectorDataArray(uvIndices,GetRequiredElement(source,indexDataElementName));
|
||||||
|
|
||||||
for (size_t i = 0, e = uvIndices.size(); i < e; ++i) {
|
for (size_t i = 0, e = uvIndices.size(); i < e; ++i) {
|
||||||
|
|
||||||
|
@ -603,7 +632,9 @@ void ResolveVertexDataArray(std::vector<T>& data_out, const Scope& source,
|
||||||
}
|
}
|
||||||
else if (MappingInformationType == "ByPolygonVertex" && ReferenceInformationType == "Direct") {
|
else if (MappingInformationType == "ByPolygonVertex" && ReferenceInformationType == "Direct") {
|
||||||
if (tempUV.size() != vertex_count) {
|
if (tempUV.size() != vertex_count) {
|
||||||
FBXImporter::LogError("length of input data unexpected for ByPolygonVertex mapping");
|
FBXImporter::LogError(Formatter::format("length of input data unexpected for ByPolygon mapping: ")
|
||||||
|
<< tempUV.size() << ", expected " << vertex_count
|
||||||
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -613,7 +644,7 @@ void ResolveVertexDataArray(std::vector<T>& data_out, const Scope& source,
|
||||||
data_out.resize(vertex_count);
|
data_out.resize(vertex_count);
|
||||||
|
|
||||||
std::vector<int> uvIndices;
|
std::vector<int> uvIndices;
|
||||||
ReadIntDataArray(uvIndices,GetRequiredElement(source,indexDataElementName));
|
ReadVectorDataArray(uvIndices,GetRequiredElement(source,indexDataElementName));
|
||||||
|
|
||||||
if (uvIndices.size() != vertex_count) {
|
if (uvIndices.size() != vertex_count) {
|
||||||
FBXImporter::LogError("length of input data unexpected for ByPolygonVertex mapping");
|
FBXImporter::LogError("length of input data unexpected for ByPolygonVertex mapping");
|
||||||
|
@ -630,7 +661,7 @@ void ResolveVertexDataArray(std::vector<T>& data_out, const Scope& source,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
FBXImporter::LogError(Formatter::format("ignoring vertex data channel, unrecognized access type: ")
|
FBXImporter::LogError(Formatter::format("ignoring vertex data channel, access type not implemented: ")
|
||||||
<< MappingInformationType << "," << ReferenceInformationType);
|
<< MappingInformationType << "," << ReferenceInformationType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -709,6 +740,48 @@ void MeshGeometry::ReadVertexDataBinormals(std::vector<aiVector3D>& binormals_ou
|
||||||
mappings);
|
mappings);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
void MeshGeometry::ReadVertexDataMaterials(std::vector<unsigned int>& materials_out, const Scope& source,
|
||||||
|
const std::string& MappingInformationType,
|
||||||
|
const std::string& ReferenceInformationType)
|
||||||
|
{
|
||||||
|
const size_t face_count = faces.size();
|
||||||
|
ai_assert(face_count);
|
||||||
|
|
||||||
|
// materials are handled separately. First of all, they are assigned per-face
|
||||||
|
// and not per polyvert. Secondly, ReferenceInformationType=IndexToDirect
|
||||||
|
// has a slightly different meaning for materials.
|
||||||
|
ReadVectorDataArray(materials_out,GetRequiredElement(source,"Materials"));
|
||||||
|
|
||||||
|
if (MappingInformationType == "AllSame") {
|
||||||
|
// easy - same material for all faces
|
||||||
|
if (materials_out.empty()) {
|
||||||
|
FBXImporter::LogError(Formatter::format("expected material index, ignoring"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (materials_out.size() > 1) {
|
||||||
|
FBXImporter::LogWarn(Formatter::format("expected only a single material index, ignoring all except the first one"));
|
||||||
|
materials_out.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
materials.assign(vertices.size(),materials_out[0]);
|
||||||
|
}
|
||||||
|
else if (MappingInformationType == "ByPolygon" && ReferenceInformationType == "IndexToDirect") {
|
||||||
|
materials.resize(face_count);
|
||||||
|
|
||||||
|
if(materials_out.size() != face_count) {
|
||||||
|
FBXImporter::LogError(Formatter::format("length of input data unexpected for ByPolygon mapping: ")
|
||||||
|
<< materials_out.size() << ", expected " << face_count
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
FBXImporter::LogError(Formatter::format("ignoring material assignments, access type not implemented: ")
|
||||||
|
<< MappingInformationType << "," << ReferenceInformationType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
Document::Document(const Parser& parser)
|
Document::Document(const Parser& parser)
|
||||||
|
|
|
@ -198,6 +198,10 @@ private:
|
||||||
const std::string& MappingInformationType,
|
const std::string& MappingInformationType,
|
||||||
const std::string& ReferenceInformationType);
|
const std::string& ReferenceInformationType);
|
||||||
|
|
||||||
|
void ReadVertexDataMaterials(std::vector<unsigned int>& materials_out, const Scope& source,
|
||||||
|
const std::string& MappingInformationType,
|
||||||
|
const std::string& ReferenceInformationType);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
// cached data arrays
|
// cached data arrays
|
||||||
|
|
Loading…
Reference in New Issue