next collada-iteration
parent
7adfe1f2d8
commit
904f17f29f
|
@ -1023,7 +1023,6 @@ void ColladaParser::ReadLight(XmlNode &node, Collada::Light &pLight) {
|
||||||
pLight.mOuterAngle = ReadFloatFromTextContent();
|
pLight.mOuterAngle = ReadFloatFromTextContent();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
@ -1262,152 +1261,68 @@ void ColladaParser::ReadEffectColor(XmlNode &node, aiColor4D &pColor, Sampler &p
|
||||||
SkipSpacesAndLineEnd(&content);
|
SkipSpacesAndLineEnd(&content);
|
||||||
} else if (currentName == "texture") {
|
} else if (currentName == "texture") {
|
||||||
// get name of source texture/sampler
|
// get name of source texture/sampler
|
||||||
int attrTex = GetAttribute("texture");
|
XmlParser::getStdStrAttribute(currentNode, "texture", pSampler.mName);
|
||||||
pSampler.mName = mReader->getAttributeValue(attrTex);
|
|
||||||
|
|
||||||
// get name of UV source channel. Specification demands it to be there, but some exporters
|
// get name of UV source channel. Specification demands it to be there, but some exporters
|
||||||
// don't write it. It will be the default UV channel in case it's missing.
|
// don't write it. It will be the default UV channel in case it's missing.
|
||||||
attrTex = TestAttribute("texcoord");
|
XmlParser::getStdStrAttribute(currentNode, "texcoord", pSampler.mUVChannel);
|
||||||
if (attrTex >= 0)
|
|
||||||
pSampler.mUVChannel = mReader->getAttributeValue(attrTex);
|
|
||||||
//SkipElement();
|
|
||||||
|
|
||||||
// as we've read texture, the color needs to be 1,1,1,1
|
// as we've read texture, the color needs to be 1,1,1,1
|
||||||
pColor = aiColor4D(1.f, 1.f, 1.f, 1.f);
|
pColor = aiColor4D(1.f, 1.f, 1.f, 1.f);
|
||||||
} else if (currentName == "technique") {
|
} else if (currentName == "technique") {
|
||||||
const int _profile = GetAttribute("profile");
|
std::string profile;
|
||||||
const char *profile = mReader->getAttributeValue(_profile);
|
XmlParser::getStdStrAttribute(currentNode, "profile", profile);
|
||||||
|
//const int _profile = GetAttribute("profile");
|
||||||
|
//const char *profile = mReader->getAttributeValue(_profile);
|
||||||
|
|
||||||
// Some extensions are quite useful ... ReadSamplerProperties processes
|
// Some extensions are quite useful ... ReadSamplerProperties processes
|
||||||
// several extensions in MAYA, OKINO and MAX3D profiles.
|
// several extensions in MAYA, OKINO and MAX3D profiles.
|
||||||
if (!::strcmp(profile, "MAYA") || !::strcmp(profile, "MAX3D") || !::strcmp(profile, "OKINO")) {
|
if (!::strcmp(profile.c_str(), "MAYA") || !::strcmp(profile.c_str(), "MAX3D") || !::strcmp(profile.c_str(), "OKINO")) {
|
||||||
// get more information on this sampler
|
// get more information on this sampler
|
||||||
ReadSamplerProperties(pSampler);
|
ReadSamplerProperties(currentNode, pSampler);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save current element name
|
|
||||||
const std::string curElem = mReader->getNodeName();
|
|
||||||
|
|
||||||
while (mReader->read()) {
|
|
||||||
if (mReader->getNodeType() == irr::io::EXN_ELEMENT) {
|
|
||||||
if (IsElement("color")) {
|
|
||||||
// text content contains 4 floats
|
|
||||||
const char *content = GetTextContent();
|
|
||||||
|
|
||||||
content = fast_atoreal_move<ai_real>(content, (ai_real &)pColor.r);
|
|
||||||
SkipSpacesAndLineEnd(&content);
|
|
||||||
|
|
||||||
content = fast_atoreal_move<ai_real>(content, (ai_real &)pColor.g);
|
|
||||||
SkipSpacesAndLineEnd(&content);
|
|
||||||
|
|
||||||
content = fast_atoreal_move<ai_real>(content, (ai_real &)pColor.b);
|
|
||||||
SkipSpacesAndLineEnd(&content);
|
|
||||||
|
|
||||||
content = fast_atoreal_move<ai_real>(content, (ai_real &)pColor.a);
|
|
||||||
SkipSpacesAndLineEnd(&content);
|
|
||||||
TestClosing("color");
|
|
||||||
} else if (IsElement("texture")) {
|
|
||||||
// get name of source texture/sampler
|
|
||||||
int attrTex = GetAttribute("texture");
|
|
||||||
pSampler.mName = mReader->getAttributeValue(attrTex);
|
|
||||||
|
|
||||||
// get name of UV source channel. Specification demands it to be there, but some exporters
|
|
||||||
// don't write it. It will be the default UV channel in case it's missing.
|
|
||||||
attrTex = TestAttribute("texcoord");
|
|
||||||
if (attrTex >= 0)
|
|
||||||
pSampler.mUVChannel = mReader->getAttributeValue(attrTex);
|
|
||||||
//SkipElement();
|
|
||||||
|
|
||||||
// as we've read texture, the color needs to be 1,1,1,1
|
|
||||||
pColor = aiColor4D(1.f, 1.f, 1.f, 1.f);
|
|
||||||
} else if (IsElement("technique")) {
|
|
||||||
const int _profile = GetAttribute("profile");
|
|
||||||
const char *profile = mReader->getAttributeValue(_profile);
|
|
||||||
|
|
||||||
// Some extensions are quite useful ... ReadSamplerProperties processes
|
|
||||||
// several extensions in MAYA, OKINO and MAX3D profiles.
|
|
||||||
if (!::strcmp(profile, "MAYA") || !::strcmp(profile, "MAX3D") || !::strcmp(profile, "OKINO")) {
|
|
||||||
// get more information on this sampler
|
|
||||||
ReadSamplerProperties(pSampler);
|
|
||||||
} else
|
|
||||||
SkipElement();
|
|
||||||
} else if (!IsElement("extra")) {
|
|
||||||
// ignore the rest
|
|
||||||
SkipElement();
|
|
||||||
}
|
|
||||||
} else if (mReader->getNodeType() == irr::io::EXN_ELEMENT_END) {
|
|
||||||
if (mReader->getNodeName() == curElem)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Reads an effect entry containing a float
|
// Reads an effect entry containing a float
|
||||||
void ColladaParser::ReadEffectFloat(XmlNode &node, ai_real &pFloat) {
|
void ColladaParser::ReadEffectFloat(XmlNode &node, ai_real &pFloat) {
|
||||||
while (mReader->read()) {
|
pFloat = 0.f;
|
||||||
if (mReader->getNodeType() == irr::io::EXN_ELEMENT) {
|
if (node.name() == "float") {
|
||||||
if (IsElement("float")) {
|
XmlParser::getFloatAttribute(node, "float", pFloat);
|
||||||
// text content contains a single floats
|
|
||||||
const char *content = GetTextContent();
|
|
||||||
content = fast_atoreal_move<ai_real>(content, pFloat);
|
|
||||||
SkipSpacesAndLineEnd(&content);
|
|
||||||
|
|
||||||
TestClosing("float");
|
|
||||||
} else {
|
|
||||||
// ignore the rest
|
|
||||||
SkipElement();
|
|
||||||
}
|
|
||||||
} else if (mReader->getNodeType() == irr::io::EXN_ELEMENT_END) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Reads an effect parameter specification of any kind
|
// Reads an effect parameter specification of any kind
|
||||||
void ColladaParser::ReadEffectParam(XmlNode &node, Collada::EffectParam &pParam) {
|
void ColladaParser::ReadEffectParam(XmlNode &node, Collada::EffectParam &pParam) {
|
||||||
while (mReader->read()) {
|
if (node.empty()) {
|
||||||
if (mReader->getNodeType() == irr::io::EXN_ELEMENT) {
|
return;
|
||||||
if (IsElement("surface")) {
|
}
|
||||||
|
|
||||||
|
for (XmlNode ¤tNode : node.children()) {
|
||||||
|
const std::string ¤tName = currentNode.name();
|
||||||
|
if (currentName == "surface") {
|
||||||
// image ID given inside <init_from> tags
|
// image ID given inside <init_from> tags
|
||||||
TestOpening("init_from");
|
const char *content = currentNode.value();
|
||||||
const char *content = GetTextContent();
|
|
||||||
pParam.mType = Param_Surface;
|
pParam.mType = Param_Surface;
|
||||||
pParam.mReference = content;
|
pParam.mReference = content;
|
||||||
TestClosing("init_from");
|
|
||||||
|
|
||||||
// don't care for remaining stuff
|
// don't care for remaining stuff
|
||||||
SkipElement("surface");
|
} else if (currentName == "sampler2D" && (FV_1_4_n == mFormat || FV_1_3_n == mFormat)) {
|
||||||
} else if (IsElement("sampler2D") && (FV_1_4_n == mFormat || FV_1_3_n == mFormat)) {
|
|
||||||
// surface ID is given inside <source> tags
|
// surface ID is given inside <source> tags
|
||||||
TestOpening("source");
|
const char *content = currentNode.value();
|
||||||
const char *content = GetTextContent();
|
|
||||||
pParam.mType = Param_Sampler;
|
pParam.mType = Param_Sampler;
|
||||||
pParam.mReference = content;
|
pParam.mReference = content;
|
||||||
TestClosing("source");
|
} else if (currentName == "sampler2D") {
|
||||||
|
|
||||||
// don't care for remaining stuff
|
|
||||||
SkipElement("sampler2D");
|
|
||||||
} else if (IsElement("sampler2D")) {
|
|
||||||
// surface ID is given inside <instance_image> tags
|
// surface ID is given inside <instance_image> tags
|
||||||
TestOpening("instance_image");
|
std::string url;
|
||||||
int attrURL = GetAttribute("url");
|
XmlParser::getStdStrAttribute(currentNode, "url", url);
|
||||||
const char *url = mReader->getAttributeValue(attrURL);
|
|
||||||
if (url[0] != '#')
|
if (url[0] != '#')
|
||||||
ThrowException("Unsupported URL format in instance_image");
|
ThrowException("Unsupported URL format in instance_image");
|
||||||
url++;
|
|
||||||
pParam.mType = Param_Sampler;
|
pParam.mType = Param_Sampler;
|
||||||
pParam.mReference = url;
|
pParam.mReference = url.c_str() + 1;
|
||||||
SkipElement("sampler2D");
|
|
||||||
} else {
|
|
||||||
// ignore unknown element
|
|
||||||
SkipElement();
|
|
||||||
}
|
|
||||||
} else if (mReader->getNodeType() == irr::io::EXN_ELEMENT_END) {
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1418,44 +1333,25 @@ void ColladaParser::ReadGeometryLibrary(XmlNode &node) {
|
||||||
if (node.empty()) {
|
if (node.empty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/*if (mReader->isEmptyElement())
|
for (XmlNode ¤tNode : node.children()) {
|
||||||
return;*/
|
const std::string ¤tName = currentNode.name();
|
||||||
|
if (currentName == "geometry") {
|
||||||
while (mReader->read()) {
|
|
||||||
if (mReader->getNodeType() == irr::io::EXN_ELEMENT) {
|
|
||||||
if (IsElement("geometry")) {
|
|
||||||
// read ID. Another entry which is "optional" by design but obligatory in reality
|
// read ID. Another entry which is "optional" by design but obligatory in reality
|
||||||
int indexID = GetAttribute("id");
|
|
||||||
std::string id = mReader->getAttributeValue(indexID);
|
|
||||||
|
|
||||||
|
std::string id;
|
||||||
|
XmlParser::getStdStrAttribute(currentNode, "id", id);
|
||||||
// create a mesh and store it in the library under its (resolved) ID
|
// create a mesh and store it in the library under its (resolved) ID
|
||||||
// Skip and warn if ID is not unique
|
// Skip and warn if ID is not unique
|
||||||
if (mMeshLibrary.find(id) == mMeshLibrary.cend()) {
|
if (mMeshLibrary.find(id) == mMeshLibrary.cend()) {
|
||||||
std::unique_ptr<Mesh> mesh(new Mesh(id));
|
std::unique_ptr<Mesh> mesh(new Mesh(id));
|
||||||
|
|
||||||
// read the mesh name if it exists
|
XmlParser::getStdStrAttribute(currentNode, "name", mesh->mName);
|
||||||
const int nameIndex = TestAttribute("name");
|
|
||||||
if (nameIndex != -1) {
|
|
||||||
mesh->mName = mReader->getAttributeValue(nameIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
// read on from there
|
// read on from there
|
||||||
ReadGeometry(*mesh);
|
ReadGeometry(currentNode, *mesh);
|
||||||
// Read successfully, add to library
|
// Read successfully, add to library
|
||||||
mMeshLibrary.insert({ id, mesh.release() });
|
mMeshLibrary.insert({ id, mesh.release() });
|
||||||
} else {
|
|
||||||
ASSIMP_LOG_ERROR_F("Collada: Skipped duplicate geometry id: \"", id, "\"");
|
|
||||||
SkipElement();
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
// ignore the rest
|
|
||||||
SkipElement();
|
|
||||||
}
|
|
||||||
} else if (mReader->getNodeType() == irr::io::EXN_ELEMENT_END) {
|
|
||||||
if (strcmp(mReader->getNodeName(), "library_geometries") != 0)
|
|
||||||
ThrowException("Expected end of <library_geometries> element.");
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1466,23 +1362,10 @@ void ColladaParser::ReadGeometry(XmlNode &node, Collada::Mesh &pMesh) {
|
||||||
if (node.empty()) {
|
if (node.empty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/*if (mReader->isEmptyElement())
|
for (XmlNode ¤tNode : node.children()) {
|
||||||
return;*/
|
const std::string ¤tName = currentNode.name();
|
||||||
|
if (currentName == "mesh") {
|
||||||
while (mReader->read()) {
|
ReadMesh(currentNode, pMesh);
|
||||||
if (mReader->getNodeType() == irr::io::EXN_ELEMENT) {
|
|
||||||
if (IsElement("mesh")) {
|
|
||||||
// read on from there
|
|
||||||
ReadMesh(pMesh);
|
|
||||||
} else {
|
|
||||||
// ignore the rest
|
|
||||||
SkipElement();
|
|
||||||
}
|
|
||||||
} else if (mReader->getNodeType() == irr::io::EXN_ELEMENT_END) {
|
|
||||||
if (strcmp(mReader->getNodeName(), "geometry") != 0)
|
|
||||||
ThrowException("Expected end of <geometry> element.");
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1493,34 +1376,15 @@ void ColladaParser::ReadMesh(XmlNode &node, Mesh &pMesh) {
|
||||||
if (node.empty()) {
|
if (node.empty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/*if (mReader->isEmptyElement())
|
|
||||||
return;*/
|
|
||||||
|
|
||||||
while (mReader->read()) {
|
for (XmlNode ¤tNode : node.children()) {
|
||||||
if (mReader->getNodeType() == irr::io::EXN_ELEMENT) {
|
const std::string ¤tName = currentNode.name();
|
||||||
if (IsElement("source")) {
|
if (currentName == "source") {
|
||||||
// we have professionals dealing with this
|
ReadSource(currentNode);
|
||||||
ReadSource();
|
} else if (currentName == "vertices") {
|
||||||
} else if (IsElement("vertices")) {
|
ReadVertexData(currentNode, pMesh);
|
||||||
// read per-vertex mesh data
|
} else if (currentName == "triangles" || currentName == "lines" || currentName == "linestrips" || currentName == "polygons" || currentName == "polylist" || currentName == "trifans" || currentName == "tristrips") {
|
||||||
ReadVertexData(pMesh);
|
ReadIndexData(currentNode, pMesh);
|
||||||
} else if (IsElement("triangles") || IsElement("lines") || IsElement("linestrips") || IsElement("polygons") || IsElement("polylist") || IsElement("trifans") || IsElement("tristrips")) {
|
|
||||||
// read per-index mesh data and faces setup
|
|
||||||
ReadIndexData(pMesh);
|
|
||||||
} else {
|
|
||||||
// ignore the restf
|
|
||||||
SkipElement();
|
|
||||||
}
|
|
||||||
} else if (mReader->getNodeType() == irr::io::EXN_ELEMENT_END) {
|
|
||||||
if (strcmp(mReader->getNodeName(), "technique_common") == 0) {
|
|
||||||
// end of another meaningless element - read over it
|
|
||||||
} else if (strcmp(mReader->getNodeName(), "mesh") == 0) {
|
|
||||||
// end of <mesh> element - we're done here
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
// everything else should be punished
|
|
||||||
ThrowException("Expected end of <mesh> element.");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1528,31 +1392,20 @@ void ColladaParser::ReadMesh(XmlNode &node, Mesh &pMesh) {
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Reads a source element
|
// Reads a source element
|
||||||
void ColladaParser::ReadSource(XmlNode &node) {
|
void ColladaParser::ReadSource(XmlNode &node) {
|
||||||
int indexID = GetAttribute("id");
|
if (node.empty()) {
|
||||||
std::string sourceID = mReader->getAttributeValue(indexID);
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
while (mReader->read()) {
|
std::string sourceID;
|
||||||
if (mReader->getNodeType() == irr::io::EXN_ELEMENT) {
|
XmlParser::getStdStrAttribute(node, "id", sourceID);
|
||||||
if (IsElement("float_array") || IsElement("IDREF_array") || IsElement("Name_array")) {
|
for (XmlNode ¤tNode : node.children()) {
|
||||||
ReadDataArray();
|
const std::string ¤tName = currentNode.name();
|
||||||
} else if (IsElement("technique_common")) {
|
if (currentName == "float_array" || currentName == "IDREF_array" || currentName == "Name_array") {
|
||||||
|
ReadDataArray(currentNode);
|
||||||
|
} else if (currentName == "technique_common") {
|
||||||
// I don't care for your profiles
|
// I don't care for your profiles
|
||||||
} else if (IsElement("accessor")) {
|
} else if (currentName == "accessor") {
|
||||||
ReadAccessor(sourceID);
|
ReadAccessor(currentNode, sourceID);
|
||||||
} else {
|
|
||||||
// ignore the rest
|
|
||||||
SkipElement();
|
|
||||||
}
|
|
||||||
} else if (mReader->getNodeType() == irr::io::EXN_ELEMENT_END) {
|
|
||||||
if (strcmp(mReader->getNodeName(), "source") == 0) {
|
|
||||||
// end of <source> - we're done
|
|
||||||
break;
|
|
||||||
} else if (strcmp(mReader->getNodeName(), "technique_common") == 0) {
|
|
||||||
// end of another meaningless element - read over it
|
|
||||||
} else {
|
|
||||||
// everything else should be punished
|
|
||||||
ThrowException("Expected end of <source> element.");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1560,16 +1413,16 @@ void ColladaParser::ReadSource(XmlNode &node) {
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Reads a data array holding a number of floats, and stores it in the global library
|
// Reads a data array holding a number of floats, and stores it in the global library
|
||||||
void ColladaParser::ReadDataArray(XmlNode &node) {
|
void ColladaParser::ReadDataArray(XmlNode &node) {
|
||||||
std::string elmName = mReader->getNodeName();
|
std::string name = node.name();
|
||||||
bool isStringArray = (elmName == "IDREF_array" || elmName == "Name_array");
|
bool isStringArray = (name == "IDREF_array" || name == "Name_array");
|
||||||
bool isEmptyElement = mReader->isEmptyElement();
|
bool isEmptyElement = node.empty();
|
||||||
|
|
||||||
// read attributes
|
// read attributes
|
||||||
int indexID = GetAttribute("id");
|
std::string id;
|
||||||
std::string id = mReader->getAttributeValue(indexID);
|
XmlParser::getStdStrAttribute(node, "id", id);
|
||||||
int indexCount = GetAttribute("count");
|
int count;
|
||||||
unsigned int count = (unsigned int)mReader->getAttributeValueAsInt(indexCount);
|
XmlParser::getIntAttribute(node, "count", count);
|
||||||
const char *content = TestTextContent();
|
const char *content = node.value();
|
||||||
|
|
||||||
// read values and store inside an array in the data library
|
// read values and store inside an array in the data library
|
||||||
mDataLibrary[id] = Data();
|
mDataLibrary[id] = Data();
|
||||||
|
@ -1609,49 +1462,45 @@ void ColladaParser::ReadDataArray(XmlNode &node) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// test for closing tag
|
|
||||||
if (!isEmptyElement)
|
|
||||||
TestClosing(elmName.c_str());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Reads an accessor and stores it in the global library
|
// Reads an accessor and stores it in the global library
|
||||||
void ColladaParser::ReadAccessor(XmlNode &node, const std::string &pID) {
|
void ColladaParser::ReadAccessor(XmlNode &node, const std::string &pID) {
|
||||||
// read accessor attributes
|
// read accessor attributes
|
||||||
int attrSource = GetAttribute("source");
|
std::string source;
|
||||||
const char *source = mReader->getAttributeValue(attrSource);
|
XmlParser::getStdStrAttribute(node, "source", source);
|
||||||
if (source[0] != '#')
|
if (source[0] != '#')
|
||||||
ThrowException(format() << "Unknown reference format in url \"" << source << "\" in source attribute of <accessor> element.");
|
ThrowException(format() << "Unknown reference format in url \"" << source << "\" in source attribute of <accessor> element.");
|
||||||
int attrCount = GetAttribute("count");
|
int count;
|
||||||
unsigned int count = (unsigned int)mReader->getAttributeValueAsInt(attrCount);
|
XmlParser::getIntAttribute(node, "count", count);
|
||||||
int attrOffset = TestAttribute("offset");
|
|
||||||
unsigned int offset = 0;
|
|
||||||
if (attrOffset > -1)
|
|
||||||
offset = (unsigned int)mReader->getAttributeValueAsInt(attrOffset);
|
|
||||||
int attrStride = TestAttribute("stride");
|
|
||||||
unsigned int stride = 1;
|
|
||||||
if (attrStride > -1)
|
|
||||||
stride = (unsigned int)mReader->getAttributeValueAsInt(attrStride);
|
|
||||||
|
|
||||||
|
unsigned int offset = 0;
|
||||||
|
if (XmlParser::hasAttribute(node, "offset")) {
|
||||||
|
XmlParser::getUIntAttribute(node, "offset", offset);
|
||||||
|
}
|
||||||
|
unsigned int stride = 1;
|
||||||
|
if (XmlParser::hasAttribute(node, "stride")) {
|
||||||
|
XmlParser::getUIntAttribute(node, "stride", stride);
|
||||||
|
}
|
||||||
// store in the library under the given ID
|
// store in the library under the given ID
|
||||||
mAccessorLibrary[pID] = Accessor();
|
mAccessorLibrary[pID] = Accessor();
|
||||||
Accessor &acc = mAccessorLibrary[pID];
|
Accessor &acc = mAccessorLibrary[pID];
|
||||||
acc.mCount = count;
|
acc.mCount = count;
|
||||||
acc.mOffset = offset;
|
acc.mOffset = offset;
|
||||||
acc.mStride = stride;
|
acc.mStride = stride;
|
||||||
acc.mSource = source + 1; // ignore the leading '#'
|
acc.mSource = source.c_str() + 1; // ignore the leading '#'
|
||||||
acc.mSize = 0; // gets incremented with every param
|
acc.mSize = 0; // gets incremented with every param
|
||||||
|
|
||||||
// and read the components
|
for (XmlNode ¤tNode : node.children()) {
|
||||||
while (mReader->read()) {
|
const std::string ¤tName = currentNode.name();
|
||||||
if (mReader->getNodeType() == irr::io::EXN_ELEMENT) {
|
if (currentName == "param") {
|
||||||
if (IsElement("param")) {
|
|
||||||
// read data param
|
// read data param
|
||||||
int attrName = TestAttribute("name");
|
//int attrName = TestAttribute("name");
|
||||||
std::string name;
|
std::string name;
|
||||||
if (attrName > -1) {
|
if (XmlParser::hasAttribute(currentNode, "name")) {
|
||||||
name = mReader->getAttributeValue(attrName);
|
XmlParser::getStdStrAttribute(currentNode, "name", name);
|
||||||
|
//name = mReader->getAttributeValue(attrName);
|
||||||
|
|
||||||
// analyse for common type components and store it's sub-offset in the corresponding field
|
// analyse for common type components and store it's sub-offset in the corresponding field
|
||||||
|
|
||||||
|
@ -1691,14 +1540,13 @@ void ColladaParser::ReadAccessor(XmlNode &node, const std::string &pID) {
|
||||||
//else
|
//else
|
||||||
// DefaultLogger::get()->warn( format() << "Unknown accessor parameter \"" << name << "\". Ignoring data channel." );
|
// DefaultLogger::get()->warn( format() << "Unknown accessor parameter \"" << name << "\". Ignoring data channel." );
|
||||||
}
|
}
|
||||||
|
if (XmlParser::hasAttribute(currentNode, "type")) {
|
||||||
// read data type
|
// read data type
|
||||||
int attrType = TestAttribute("type");
|
|
||||||
if (attrType > -1) {
|
|
||||||
// for the moment we only distinguish between a 4x4 matrix and anything else.
|
|
||||||
// TODO: (thom) I don't have a spec here at work. Check if there are other multi-value types
|
// TODO: (thom) I don't have a spec here at work. Check if there are other multi-value types
|
||||||
// which should be tested for here.
|
// which should be tested for here.
|
||||||
std::string type = mReader->getAttributeValue(attrType);
|
std::string type;
|
||||||
|
|
||||||
|
XmlParser::getStdStrAttribute(currentNode, "type", type);
|
||||||
if (type == "float4x4")
|
if (type == "float4x4")
|
||||||
acc.mSize += 16;
|
acc.mSize += 16;
|
||||||
else
|
else
|
||||||
|
@ -1706,16 +1554,6 @@ void ColladaParser::ReadAccessor(XmlNode &node, const std::string &pID) {
|
||||||
}
|
}
|
||||||
|
|
||||||
acc.mParams.push_back(name);
|
acc.mParams.push_back(name);
|
||||||
|
|
||||||
// skip remaining stuff of this element, if any
|
|
||||||
SkipElement();
|
|
||||||
} else {
|
|
||||||
ThrowException(format() << "Unexpected sub element <" << mReader->getNodeName() << "> in tag <accessor>");
|
|
||||||
}
|
|
||||||
} else if (mReader->getNodeType() == irr::io::EXN_ELEMENT_END) {
|
|
||||||
if (strcmp(mReader->getNodeName(), "accessor") != 0)
|
|
||||||
ThrowException("Expected end of <accessor> element.");
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1724,23 +1562,14 @@ void ColladaParser::ReadAccessor(XmlNode &node, const std::string &pID) {
|
||||||
// Reads input declarations of per-vertex mesh data into the given mesh
|
// Reads input declarations of per-vertex mesh data into the given mesh
|
||||||
void ColladaParser::ReadVertexData(XmlNode &node, Mesh &pMesh) {
|
void ColladaParser::ReadVertexData(XmlNode &node, Mesh &pMesh) {
|
||||||
// extract the ID of the <vertices> element. Not that we care, but to catch strange referencing schemes we should warn about
|
// extract the ID of the <vertices> element. Not that we care, but to catch strange referencing schemes we should warn about
|
||||||
int attrID = GetAttribute("id");
|
XmlParser::getStdStrAttribute(node, "id", pMesh.mVertexID);
|
||||||
pMesh.mVertexID = mReader->getAttributeValue(attrID);
|
for (XmlNode ¤tNode : node.children()) {
|
||||||
|
const std::string ¤tName = currentNode.name();
|
||||||
// a number of <input> elements
|
if (currentName == "input" ) {
|
||||||
while (mReader->read()) {
|
ReadInputChannel(currentNode, pMesh.mPerVertexData);
|
||||||
if (mReader->getNodeType() == irr::io::EXN_ELEMENT) {
|
|
||||||
if (IsElement("input")) {
|
|
||||||
ReadInputChannel(pMesh.mPerVertexData);
|
|
||||||
} else {
|
} else {
|
||||||
ThrowException(format() << "Unexpected sub element <" << mReader->getNodeName() << "> in tag <vertices>");
|
ThrowException(format() << "Unexpected sub element <" << mReader->getNodeName() << "> in tag <vertices>");
|
||||||
}
|
}
|
||||||
} else if (mReader->getNodeType() == irr::io::EXN_ELEMENT_END) {
|
|
||||||
if (strcmp(mReader->getNodeName(), "vertices") != 0)
|
|
||||||
ThrowException("Expected end of <vertices> element.");
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1750,46 +1579,50 @@ void ColladaParser::ReadIndexData(XmlNode &node, Mesh &pMesh) {
|
||||||
std::vector<size_t> vcount;
|
std::vector<size_t> vcount;
|
||||||
std::vector<InputChannel> perIndexData;
|
std::vector<InputChannel> perIndexData;
|
||||||
|
|
||||||
|
XmlParser::getIntAttribute(node, "count", (int) numPrimitives);
|
||||||
// read primitive count from the attribute
|
// read primitive count from the attribute
|
||||||
int attrCount = GetAttribute("count");
|
//int attrCount = GetAttribute("count");
|
||||||
size_t numPrimitives = (size_t)mReader->getAttributeValueAsInt(attrCount);
|
//size_t numPrimitives = (size_t)mReader->getAttributeValueAsInt(attrCount);
|
||||||
// some mesh types (e.g. tristrips) don't specify primitive count upfront,
|
// some mesh types (e.g. tristrips) don't specify primitive count upfront,
|
||||||
// so we need to sum up the actual number of primitives while we read the <p>-tags
|
// so we need to sum up the actual number of primitives while we read the <p>-tags
|
||||||
size_t actualPrimitives = 0;
|
size_t actualPrimitives = 0;
|
||||||
|
|
||||||
// material subgroup
|
|
||||||
int attrMaterial = TestAttribute("material");
|
|
||||||
SubMesh subgroup;
|
SubMesh subgroup;
|
||||||
if (attrMaterial > -1)
|
if (XmlParser::hasAttribute("material")) {
|
||||||
subgroup.mMaterial = mReader->getAttributeValue(attrMaterial);
|
XmlParser::getStdStrAttribute(node, "material", subgroup.mMaterial);
|
||||||
|
}
|
||||||
|
// material subgroup
|
||||||
|
// int attrMaterial = TestAttribute("material");
|
||||||
|
|
||||||
|
//if (attrMaterial > -1)
|
||||||
|
// subgroup.mMaterial = mReader->getAttributeValue(attrMaterial);
|
||||||
|
|
||||||
// distinguish between polys and triangles
|
// distinguish between polys and triangles
|
||||||
std::string elementName = mReader->getNodeName();
|
std::string elementName = node.name();
|
||||||
PrimitiveType primType = Prim_Invalid;
|
PrimitiveType primType = Prim_Invalid;
|
||||||
if (IsElement("lines"))
|
if (elementName == "lines")
|
||||||
primType = Prim_Lines;
|
primType = Prim_Lines;
|
||||||
else if (IsElement("linestrips"))
|
else if (elementName == "linestrips")
|
||||||
primType = Prim_LineStrip;
|
primType = Prim_LineStrip;
|
||||||
else if (IsElement("polygons"))
|
else if (elementName == "polygons")
|
||||||
primType = Prim_Polygon;
|
primType = Prim_Polygon;
|
||||||
else if (IsElement("polylist"))
|
else if (elementName == "polylist")
|
||||||
primType = Prim_Polylist;
|
primType = Prim_Polylist;
|
||||||
else if (IsElement("triangles"))
|
else if (elementName == "triangles")
|
||||||
primType = Prim_Triangles;
|
primType = Prim_Triangles;
|
||||||
else if (IsElement("trifans"))
|
else if (elementName == "trifans")
|
||||||
primType = Prim_TriFans;
|
primType = Prim_TriFans;
|
||||||
else if (IsElement("tristrips"))
|
else if (elementName == "tristrips")
|
||||||
primType = Prim_TriStrips;
|
primType = Prim_TriStrips;
|
||||||
|
|
||||||
ai_assert(primType != Prim_Invalid);
|
ai_assert(primType != Prim_Invalid);
|
||||||
|
|
||||||
// also a number of <input> elements, but in addition a <p> primitive collection and probably index counts for all primitives
|
// also a number of <input> elements, but in addition a <p> primitive collection and probably index counts for all primitives
|
||||||
while (mReader->read()) {
|
for (XmlNode ¤tNode : node.children()) {
|
||||||
if (mReader->getNodeType() == irr::io::EXN_ELEMENT) {
|
const std::string ¤tName = currentNode.name();
|
||||||
if (IsElement("input")) {
|
if (currentName == "input") {
|
||||||
ReadInputChannel(perIndexData);
|
ReadInputChannel(currentNode, perIndexData);
|
||||||
} else if (IsElement("vcount")) {
|
} else if (currentName == "vcount") {
|
||||||
if (!mReader->isEmptyElement()) {
|
if (!currentNode.empty()) {
|
||||||
if (numPrimitives) // It is possible to define a mesh without any primitives
|
if (numPrimitives) // It is possible to define a mesh without any primitives
|
||||||
{
|
{
|
||||||
// case <polylist> - specifies the number of indices for each polygon
|
// case <polylist> - specifies the number of indices for each polygon
|
||||||
|
@ -1804,27 +1637,19 @@ void ColladaParser::ReadIndexData(XmlNode &node, Mesh &pMesh) {
|
||||||
SkipSpacesAndLineEnd(&content);
|
SkipSpacesAndLineEnd(&content);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TestClosing("vcount");
|
|
||||||
}
|
}
|
||||||
} else if (IsElement("p")) {
|
} else if (currentName == "p") {
|
||||||
if (!mReader->isEmptyElement()) {
|
if (!currentNode.empty()) {
|
||||||
// now here the actual fun starts - these are the indices to construct the mesh data from
|
// now here the actual fun starts - these are the indices to construct the mesh data from
|
||||||
actualPrimitives += ReadPrimitives(pMesh, perIndexData, numPrimitives, vcount, primType);
|
actualPrimitives += ReadPrimitives(currentNode, pMesh, perIndexData, numPrimitives, vcount, primType);
|
||||||
}
|
}
|
||||||
} else if (IsElement("extra")) {
|
} else if (currentName == "extra") {
|
||||||
SkipElement("extra");
|
// skip
|
||||||
} else if (IsElement("ph")) {
|
} else if (currentName == "ph") {
|
||||||
SkipElement("ph");
|
// skip
|
||||||
} else {
|
} else {
|
||||||
ThrowException(format() << "Unexpected sub element <" << mReader->getNodeName() << "> in tag <" << elementName << ">");
|
ThrowException(format() << "Unexpected sub element <" << mReader->getNodeName() << "> in tag <" << elementName << ">");
|
||||||
}
|
}
|
||||||
} else if (mReader->getNodeType() == irr::io::EXN_ELEMENT_END) {
|
|
||||||
if (mReader->getNodeName() != elementName)
|
|
||||||
ThrowException(format() << "Expected end of <" << elementName << "> element.");
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef ASSIMP_BUILD_DEBUG
|
#ifdef ASSIMP_BUILD_DEBUG
|
||||||
|
@ -1845,21 +1670,28 @@ void ColladaParser::ReadInputChannel(XmlNode &node, std::vector<InputChannel> &p
|
||||||
InputChannel channel;
|
InputChannel channel;
|
||||||
|
|
||||||
// read semantic
|
// read semantic
|
||||||
int attrSemantic = GetAttribute("semantic");
|
std::string semantic;
|
||||||
std::string semantic = mReader->getAttributeValue(attrSemantic);
|
XmlParser::getStdStrAttribute(node, "semantic", semantic);
|
||||||
|
//int attrSemantic = GetAttribute("semantic");
|
||||||
|
//std::string semantic = mReader->getAttributeValue(attrSemantic);
|
||||||
channel.mType = GetTypeForSemantic(semantic);
|
channel.mType = GetTypeForSemantic(semantic);
|
||||||
|
|
||||||
// read source
|
// read source
|
||||||
int attrSource = GetAttribute("source");
|
std::string source;
|
||||||
const char *source = mReader->getAttributeValue(attrSource);
|
XmlParser::getStdStrAttribute(node, "source", source);
|
||||||
|
//int attrSource = GetAttribute("source");
|
||||||
|
//const char *source = mReader->getAttributeValue(attrSource);
|
||||||
if (source[0] != '#')
|
if (source[0] != '#')
|
||||||
ThrowException(format() << "Unknown reference format in url \"" << source << "\" in source attribute of <input> element.");
|
ThrowException(format() << "Unknown reference format in url \"" << source << "\" in source attribute of <input> element.");
|
||||||
channel.mAccessor = source + 1; // skipping the leading #, hopefully the remaining text is the accessor ID only
|
channel.mAccessor = source.c_str() + 1; // skipping the leading #, hopefully the remaining text is the accessor ID only
|
||||||
|
|
||||||
// read index offset, if per-index <input>
|
// read index offset, if per-index <input>
|
||||||
int attrOffset = TestAttribute("offset");
|
if (XmlParser::hasAttribute("offset")) {
|
||||||
if (attrOffset > -1)
|
XmlParser::getStdStrAttribute(node, "offset", channel.mOffset);
|
||||||
channel.mOffset = mReader->getAttributeValueAsInt(attrOffset);
|
}
|
||||||
|
//int attrOffset = TestAttribute("offset");
|
||||||
|
//if (attrOffset > -1)
|
||||||
|
// channel.mOffset = mReader->getAttributeValueAsInt(attrOffset);
|
||||||
|
|
||||||
// read set if texture coordinates
|
// read set if texture coordinates
|
||||||
if (channel.mType == IT_Texcoord || channel.mType == IT_Color) {
|
if (channel.mType == IT_Texcoord || channel.mType == IT_Color) {
|
||||||
|
|
|
@ -158,6 +158,16 @@ public:
|
||||||
return !attr.empty();
|
return !attr.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline bool getUIntAttribute(XmlNode &xmlNode, const char *name, unsigned int &val) {
|
||||||
|
pugi::xml_attribute attr = xmlNode.attribute(name);
|
||||||
|
if (attr.empty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
val = attr.as_uint();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static inline bool getIntAttribute(XmlNode &xmlNode, const char *name, int &val ) {
|
static inline bool getIntAttribute(XmlNode &xmlNode, const char *name, int &val ) {
|
||||||
pugi::xml_attribute attr = xmlNode.attribute(name);
|
pugi::xml_attribute attr = xmlNode.attribute(name);
|
||||||
if (attr.empty()) {
|
if (attr.empty()) {
|
||||||
|
@ -168,6 +178,17 @@ public:
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline bool getFloatAttribute( XmlNode &xmlNode, const char *name, float &val ) {
|
||||||
|
pugi::xml_attribute attr = xmlNode.attribute(name);
|
||||||
|
if (attr.empty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
val = attr.as_float();
|
||||||
|
return true;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
static inline bool getStdStrAttribute(XmlNode &xmlNode, const char *name, std::string &val) {
|
static inline bool getStdStrAttribute(XmlNode &xmlNode, const char *name, std::string &val) {
|
||||||
pugi::xml_attribute attr = xmlNode.attribute(name);
|
pugi::xml_attribute attr = xmlNode.attribute(name);
|
||||||
if (attr.empty()) {
|
if (attr.empty()) {
|
||||||
|
|
Loading…
Reference in New Issue