next iteration.

pull/2966/head
Kim Kulling 2020-08-19 22:44:13 +02:00
parent d393f677ce
commit cb631517a7
1 changed files with 150 additions and 206 deletions

View File

@ -642,11 +642,10 @@ void ColladaParser::ReadController(XmlNode &node, Collada::Controller &pControll
pController.mType = Skin; pController.mType = Skin;
pController.mMethod = Normalized; pController.mMethod = Normalized;
for (XmlNode currentNode : node.children()) { for (XmlNode currentNode : node.children()) {
const std::string currentName = currentNode.name(); const std::string &currentName = currentNode.name();
if (currentName == "morph") { if (currentName == "morph") {
pController.mType = Morph; pController.mType = Morph;
int baseIndex = currentNode.attribute("source").as_int(); pController.mMeshId = currentNode.attribute("source").as_string();
pController.mMeshId = currentNode.attribute.begin() + baseIndex + 1;
int methodIndex = currentNode.attribute("method").as_int(); int methodIndex = currentNode.attribute("method").as_int();
if (methodIndex > 0) { if (methodIndex > 0) {
const char *method = currentNode.attribute("method").value(); const char *method = currentNode.attribute("method").value();
@ -655,8 +654,7 @@ void ColladaParser::ReadController(XmlNode &node, Collada::Controller &pControll
} }
} }
} else if (currentName == "skin") { } else if (currentName == "skin") {
int sourceIndex = currentNode.attribute("source").as_int(); pController.mMeshId = currentNode.attribute("source").as_string();
pController.mMeshId = currentNode.attribute.begin() + sourceIndex + 1;
} else if (currentName == "bind_shape_matrix") { } else if (currentName == "bind_shape_matrix") {
const char *content = currentNode.value(); const char *content = currentNode.value();
for (unsigned int a = 0; a < 16; a++) { for (unsigned int a = 0; a < 16; a++) {
@ -675,10 +673,8 @@ void ColladaParser::ReadController(XmlNode &node, Collada::Controller &pControll
for (XmlNode currendChildNode : currentNode.children()) { for (XmlNode currendChildNode : currentNode.children()) {
const std::string currentChildName = currendChildNode.name(); const std::string currentChildName = currendChildNode.name();
if (currentChildName == "input") { if (currentChildName == "input") {
int semanticsIndex = currendChildNode.attribute("semantic").as_int(); const char *semantics = currendChildNode.attribute("semantic").as_string();
int sourceIndex = currendChildNode.attribute("source").as_int(); const char *source = currendChildNode.attribute("source").as_string();
const char *semantics = currendChildNode.attributes.begin() + semanticsIndex;
const char *source = currendChildNode.attributes.begin() + sourceIndex;
if (strcmp(semantics, "MORPH_TARGET") == 0) { if (strcmp(semantics, "MORPH_TARGET") == 0) {
pController.mMorphTarget = source + 1; pController.mMorphTarget = source + 1;
} else if (strcmp(semantics, "MORPH_WEIGHT") == 0) { } else if (strcmp(semantics, "MORPH_WEIGHT") == 0) {
@ -696,14 +692,12 @@ void ColladaParser::ReadControllerJoints(XmlNode &node, Collada::Controller &pCo
for (XmlNode currentNode : node.children()) { for (XmlNode currentNode : node.children()) {
const std::string currentName = currentNode.name(); const std::string currentName = currentNode.name();
if (currentName == "input") { if (currentName == "input") {
int indexSemantic = currentNode.attribute("semantic").as_int(); const char *attrSemantic = currentNode.attribute("semantic").as_string();
const char *attrSemantic = currentNode.attributes.begin() + indexSemantic; const char *attrSource = currentNode.attribute("source").as_string();
int indexSource = currentNode.attribute("source").as_int();
const char *attrSource = currentNode.attributes.begin() + indexSource;
if (attrSource[0] != '#') { if (attrSource[0] != '#') {
ThrowException(format() << "Unsupported URL format in \"" << attrSource << "\" in source attribute of <joints> data <input> element"); ThrowException(format() << "Unsupported URL format in \"" << attrSource << "\" in source attribute of <joints> data <input> element");
} }
attrSource++; ++attrSource;
// parse source URL to corresponding source // parse source URL to corresponding source
if (strcmp(attrSemantic, "JOINT") == 0) { if (strcmp(attrSemantic, "JOINT") == 0) {
pController.mJointNameSource = attrSource; pController.mJointNameSource = attrSource;
@ -720,8 +714,7 @@ void ColladaParser::ReadControllerJoints(XmlNode &node, Collada::Controller &pCo
// Reads the joint weights for the given controller // Reads the joint weights for the given controller
void ColladaParser::ReadControllerWeights(XmlNode &node, Collada::Controller &pController) { void ColladaParser::ReadControllerWeights(XmlNode &node, Collada::Controller &pController) {
// Read vertex count from attributes and resize the array accordingly // Read vertex count from attributes and resize the array accordingly
int indexCount = node.attribute("count").as_int(); int vertexCount = node.attribute("count").as_int();
size_t vertexCount = node.attributes.begin() + indexCount;
pController.mWeightCounts.resize(vertexCount); pController.mWeightCounts.resize(vertexCount);
/*// read vertex count from attributes and resize the array accordingly /*// read vertex count from attributes and resize the array accordingly
@ -734,17 +727,14 @@ void ColladaParser::ReadControllerWeights(XmlNode &node, Collada::Controller &pC
if (currentName == "input") { if (currentName == "input") {
InputChannel channel; InputChannel channel;
int indexSemantic = currentNode.attribute("semantic").as_int(); const char *attrSemantic = currentNode.attribute("semantic").as_string();
const char *attrSemantic = currentNode.attributes.begin() + indexSemantic; const char *attrSource = currentNode.attribute("source").as_string();
int indexSource = currentNode.attribute("source").as_int(); channel.mOffset = currentNode.attribute("offset").as_int();
const char *attrSource = currentNode.attributes.begin() + indexSource;
int indexOffset = currentNode.attribute("offset").as_int();
if (indexOffset >= 0)
channel.mOffset = currentNode.attributes.begin + indexOffset;
// local URLS always start with a '#'. We don't support global URLs // local URLS always start with a '#'. We don't support global URLs
if (attrSource[0] != '#') if (attrSource[0] != '#') {
ThrowException(format() << "Unsupported URL format in \"" << attrSource << "\" in source attribute of <vertex_weights> data <input> element"); ThrowException(format() << "Unsupported URL format in \"" << attrSource << "\" in source attribute of <vertex_weights> data <input> element");
}
channel.mAccessor = attrSource + 1; channel.mAccessor = attrSource + 1;
// parse source URL to corresponding source // parse source URL to corresponding source
@ -799,8 +789,7 @@ void ColladaParser::ReadImageLibrary(XmlNode &node) {
for (XmlNode currentNode : node.children()) { for (XmlNode currentNode : node.children()) {
const std::string name = currentNode.name(); const std::string name = currentNode.name();
if (name == "image") { if (name == "image") {
int attrID = currentNode.attribute("id").as_int(); std::string id = currentNode.attribute("id").as_string();
std::string id = currentNode.attributes.begin() + attrID;
mImageLibrary[id] = Image(); mImageLibrary[id] = Image();
// read on from there // read on from there
@ -837,19 +826,17 @@ void ColladaParser::ReadImage(XmlNode &node, Collada::Image &pImage) {
// make sure we skip over mip and array initializations, which // make sure we skip over mip and array initializations, which
// we don't support, but which could confuse the loader if // we don't support, but which could confuse the loader if
// they're not skipped. // they're not skipped.
int attrib = currentNode.attribute("ref").as_int(); int v = currentNode.attribute("ref").as_int();
int v = currentNode.attributes.begin + attrib; /* if (v y) {
if (attrib != -1 && v > 0) {
ASSIMP_LOG_WARN("Collada: Ignoring texture array index"); ASSIMP_LOG_WARN("Collada: Ignoring texture array index");
continue; continue;
} }*/
attrib = currentNode.attribute("mip_index").as_int(); v = currentNode.attribute("mip_index").as_int();
v = currentNode.attributes.begin + attrib; /*if (attrib != -1 && v > 0) {
if (attrib != -1 && v > 0) {
ASSIMP_LOG_WARN("Collada: Ignoring MIP map layer"); ASSIMP_LOG_WARN("Collada: Ignoring MIP map layer");
continue; continue;
} }*/
// TODO: correctly jump over cube and volume maps? // TODO: correctly jump over cube and volume maps?
} }
@ -866,11 +853,9 @@ void ColladaParser::ReadImage(XmlNode &node, Collada::Image &pImage) {
} }
} else if (hexChild && !pImage.mFileName.length()) { } else if (hexChild && !pImage.mFileName.length()) {
// embedded image. get format // embedded image. get format
const int attrib = hexChild.attribute("format").as_int(); pImage.mEmbeddedFormat = hexChild.attribute("format").as_string();
if (-1 == attrib) { if (pImage.mEmbeddedFormat.empty()) {
ASSIMP_LOG_WARN("Collada: Unknown image file format"); ASSIMP_LOG_WARN("Collada: Unknown image file format");
} else {
pImage.mEmbeddedFormat = hexChild.attributes.begin() + attrib;
} }
const char *data = hexChild.value(); const char *data = hexChild.value();
@ -905,13 +890,8 @@ void ColladaParser::ReadMaterialLibrary(XmlNode &node) {
for (XmlNode currentNode : node.children()) { for (XmlNode currentNode : node.children()) {
const std::string currentName = currentNode.name(); const std::string currentName = currentNode.name();
int attrID = currentNode.attribute("id").as_int(); std::string id = currentNode.attribute("id").as_string();
std::string id = currentNode.attributes.begin() + attrID; std::string name = currentNode.attribute("name").as_string();
std::string name;
int attrName = currentNode.attribute("name").as_int();
if (attrName >= 0) {
name = currentNode.attributes.begin() + attrName;
}
mMaterialLibrary[id] = Material(); mMaterialLibrary[id] = Material();
if (!name.empty()) { if (!name.empty()) {
@ -1108,55 +1088,53 @@ void ColladaParser::ReadEffect(XmlNode &node, Collada::Effect &pEffect) {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Reads an COMMON effect profile // Reads an COMMON effect profile
void ColladaParser::ReadEffectProfileCommon(XmlNode &node, Collada::Effect &pEffect) { void ColladaParser::ReadEffectProfileCommon(XmlNode &node, Collada::Effect &pEffect) {
while (mReader->read()) { for (XmlNode &currentNode : node.children()) {
if (mReader->getNodeType() == irr::io::EXN_ELEMENT) { const std::string &currentName = currentNode.name();
if (IsElement("newparam")) { if (currentName == "newparam") {
// save ID // save ID
int attrSID = GetAttribute("sid"); std::string sid = currentNode.attribute("sid").as_string();
std::string sid = mReader->getAttributeValue(attrSID); //std::string sid = GetAttribute("sid");
//= mReader->getAttributeValue(attrSID);
pEffect.mParams[sid] = EffectParam(); pEffect.mParams[sid] = EffectParam();
ReadEffectParam(pEffect.mParams[sid]); ReadEffectParam(currentNode, pEffect.mParams[sid]);
} else if (IsElement("technique") || IsElement("extra")) { } else if (currentName == "technique" || currentName == "extra" ) {
// just syntactic sugar // just syntactic sugar
} } else if (mFormat == FV_1_4_n && currentName == "image") {
else if (mFormat == FV_1_4_n && IsElement("image")) {
// 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 attrID = GetAttribute("id"); std::string id = currentNode.attribute("id").as_string();
std::string id = mReader->getAttributeValue(attrID);
//int attrID = GetAttribute("id");
//std::string id = mReader->getAttributeValue(attrID);
// create an entry and store it in the library under its ID // create an entry and store it in the library under its ID
mImageLibrary[id] = Image(); mImageLibrary[id] = Image();
// read on from there // read on from there
ReadImage(mImageLibrary[id]); ReadImage(currentNode, mImageLibrary[id]);
} } else if (currentName == "phong")
/* Shading modes */
else if (IsElement("phong"))
pEffect.mShadeType = Shade_Phong; pEffect.mShadeType = Shade_Phong;
else if (IsElement("constant")) else if (currentName == "constant")
pEffect.mShadeType = Shade_Constant; pEffect.mShadeType = Shade_Constant;
else if (IsElement("lambert")) else if (currentName == "lambert")
pEffect.mShadeType = Shade_Lambert; pEffect.mShadeType = Shade_Lambert;
else if (IsElement("blinn")) else if (currentName == "blinn")
pEffect.mShadeType = Shade_Blinn; pEffect.mShadeType = Shade_Blinn;
/* Color + texture properties */ /* Color + texture properties */
else if (IsElement("emission")) else if (currentName == "emission")
ReadEffectColor(pEffect.mEmissive, pEffect.mTexEmissive); ReadEffectColor(currentNode, pEffect.mEmissive, pEffect.mTexEmissive);
else if (IsElement("ambient")) else if (currentName == "ambient")
ReadEffectColor(pEffect.mAmbient, pEffect.mTexAmbient); ReadEffectColor(currentNode, pEffect.mAmbient, pEffect.mTexAmbient);
else if (IsElement("diffuse")) else if (currentName == "diffuse")
ReadEffectColor(pEffect.mDiffuse, pEffect.mTexDiffuse); ReadEffectColor(currentNode, pEffect.mDiffuse, pEffect.mTexDiffuse);
else if (IsElement("specular")) else if (currentName == "specular")
ReadEffectColor(pEffect.mSpecular, pEffect.mTexSpecular); ReadEffectColor(currentNode, pEffect.mSpecular, pEffect.mTexSpecular);
else if (IsElement("reflective")) { else if (currentName == "reflective") {
ReadEffectColor(pEffect.mReflective, pEffect.mTexReflective); ReadEffectColor(currentNode, pEffect.mReflective, pEffect.mTexReflective);
} else if (IsElement("transparent")) { } else if (currentName == "transparent") {
pEffect.mHasTransparency = true; pEffect.mHasTransparency = true;
const char *opaque = currentNode.attribute("opaque").as_string();
const char *opaque = mReader->getAttributeValueSafe("opaque"); //const char *opaque = mReader->getAttributeValueSafe("opaque");
if (::strcmp(opaque, "RGB_ZERO") == 0 || ::strcmp(opaque, "RGB_ONE") == 0) { if (::strcmp(opaque, "RGB_ZERO") == 0 || ::strcmp(opaque, "RGB_ONE") == 0) {
pEffect.mRGBTransparency = true; pEffect.mRGBTransparency = true;
@ -1167,46 +1145,36 @@ void ColladaParser::ReadEffectProfileCommon(XmlNode &node, Collada::Effect &pEff
pEffect.mInvertTransparency = true; pEffect.mInvertTransparency = true;
} }
ReadEffectColor(pEffect.mTransparent, pEffect.mTexTransparent); ReadEffectColor(currentNode, pEffect.mTransparent, pEffect.mTexTransparent);
} else if (IsElement("shininess")) } else if (currentName == "shininess")
ReadEffectFloat(pEffect.mShininess); ReadEffectFloat(currentNode, pEffect.mShininess);
else if (IsElement("reflectivity")) else if (currentName == "reflectivity")
ReadEffectFloat(pEffect.mReflectivity); ReadEffectFloat(currentNode, pEffect.mReflectivity);
/* Single scalar properties */ /* Single scalar properties */
else if (IsElement("transparency")) else if (currentName == "transparency")
ReadEffectFloat(pEffect.mTransparency); ReadEffectFloat(currentNode, pEffect.mTransparency);
else if (IsElement("index_of_refraction")) else if (currentName == "index_of_refraction")
ReadEffectFloat(pEffect.mRefractIndex); ReadEffectFloat(currentNode, pEffect.mRefractIndex);
// GOOGLEEARTH/OKINO extensions // GOOGLEEARTH/OKINO extensions
// ------------------------------------------------------- // -------------------------------------------------------
else if (IsElement("double_sided")) else if (currentName == "double_sided")
pEffect.mDoubleSided = ReadBoolFromTextContent(); pEffect.mDoubleSided = ReadBoolFromTextContent();
// FCOLLADA extensions // FCOLLADA extensions
// ------------------------------------------------------- // -------------------------------------------------------
else if (IsElement("bump")) { else if (currentName == "bump") {
aiColor4D dummy; aiColor4D dummy;
ReadEffectColor(dummy, pEffect.mTexBump); ReadEffectColor(currentNode, dummy, pEffect.mTexBump);
} }
// MAX3D extensions // MAX3D extensions
// ------------------------------------------------------- // -------------------------------------------------------
else if (IsElement("wireframe")) { else if (currentName == "wireframe") {
pEffect.mWireframe = ReadBoolFromTextContent(); pEffect.mWireframe = ReadBoolFromTextContent();
TestClosing("wireframe"); } else if (currentName == "faceted") {
} else if (IsElement("faceted")) {
pEffect.mFaceted = ReadBoolFromTextContent(); pEffect.mFaceted = ReadBoolFromTextContent();
TestClosing("faceted");
} else {
// ignore the rest
SkipElement();
}
} else if (mReader->getNodeType() == irr::io::EXN_ELEMENT_END) {
if (strcmp(mReader->getNodeName(), "profile_COMMON") == 0) {
break;
}
} }
} }
} }
@ -1217,76 +1185,54 @@ void ColladaParser::ReadSamplerProperties(XmlNode &node, Sampler &out) {
if (node.empty()) { if (node.empty()) {
return; return;
} }
for (XmlNode &currentNode : node.children()) {
while (mReader->read()) { const std::string &currentName = currentNode.name();
if (mReader->getNodeType() == irr::io::EXN_ELEMENT) {
// MAYA extensions // MAYA extensions
// ------------------------------------------------------- // -------------------------------------------------------
if (IsElement("wrapU")) { if (currentName == "wrapU") {
out.mWrapU = ReadBoolFromTextContent(); out.mWrapU = ReadBoolFromTextContent();
TestClosing("wrapU"); } else if (currentName == "wrapV") {
} else if (IsElement("wrapV")) {
out.mWrapV = ReadBoolFromTextContent(); out.mWrapV = ReadBoolFromTextContent();
TestClosing("wrapV"); } else if (currentName == "mirrorU") {
} else if (IsElement("mirrorU")) {
out.mMirrorU = ReadBoolFromTextContent(); out.mMirrorU = ReadBoolFromTextContent();
TestClosing("mirrorU"); } else if (currentName == "mirrorV") {
} else if (IsElement("mirrorV")) {
out.mMirrorV = ReadBoolFromTextContent(); out.mMirrorV = ReadBoolFromTextContent();
TestClosing("mirrorV"); } else if (currentName == "repeatU") {
} else if (IsElement("repeatU")) {
out.mTransform.mScaling.x = ReadFloatFromTextContent(); out.mTransform.mScaling.x = ReadFloatFromTextContent();
TestClosing("repeatU"); } else if (currentName == "repeatV") {
} else if (IsElement("repeatV")) {
out.mTransform.mScaling.y = ReadFloatFromTextContent(); out.mTransform.mScaling.y = ReadFloatFromTextContent();
TestClosing("repeatV"); } else if (currentName == "offsetU") {
} else if (IsElement("offsetU")) {
out.mTransform.mTranslation.x = ReadFloatFromTextContent(); out.mTransform.mTranslation.x = ReadFloatFromTextContent();
TestClosing("offsetU"); } else if (currentName == "offsetV") {
} else if (IsElement("offsetV")) {
out.mTransform.mTranslation.y = ReadFloatFromTextContent(); out.mTransform.mTranslation.y = ReadFloatFromTextContent();
TestClosing("offsetV"); } else if (currentName == "rotateUV") {
} else if (IsElement("rotateUV")) {
out.mTransform.mRotation = ReadFloatFromTextContent(); out.mTransform.mRotation = ReadFloatFromTextContent();
TestClosing("rotateUV"); } else if (currentName == "blend_mode") {
} else if (IsElement("blend_mode")) {
const char *sz = GetTextContent(); const char *sz = GetTextContent();
// http://www.feelingsoftware.com/content/view/55/72/lang,en/ // http://www.feelingsoftware.com/content/view/55/72/lang,en/
// NONE, OVER, IN, OUT, ADD, SUBTRACT, MULTIPLY, DIFFERENCE, LIGHTEN, DARKEN, SATURATE, DESATURATE and ILLUMINATE // NONE, OVER, IN, OUT, ADD, SUBTRACT, MULTIPLY, DIFFERENCE, LIGHTEN, DARKEN, SATURATE, DESATURATE and ILLUMINATE
if (0 == ASSIMP_strincmp(sz, "ADD", 3)) if (0 == ASSIMP_strincmp(sz, "ADD", 3))
out.mOp = aiTextureOp_Add; out.mOp = aiTextureOp_Add;
else if (0 == ASSIMP_strincmp(sz, "SUBTRACT", 8)) else if (0 == ASSIMP_strincmp(sz, "SUBTRACT", 8))
out.mOp = aiTextureOp_Subtract; out.mOp = aiTextureOp_Subtract;
else if (0 == ASSIMP_strincmp(sz, "MULTIPLY", 8)) else if (0 == ASSIMP_strincmp(sz, "MULTIPLY", 8))
out.mOp = aiTextureOp_Multiply; out.mOp = aiTextureOp_Multiply;
else { else {
ASSIMP_LOG_WARN("Collada: Unsupported MAYA texture blend mode"); ASSIMP_LOG_WARN("Collada: Unsupported MAYA texture blend mode");
} }
TestClosing("blend_mode");
} }
// OKINO extensions // OKINO extensions
// ------------------------------------------------------- // -------------------------------------------------------
else if (IsElement("weighting")) { else if (currentName == "weighting") {
out.mWeighting = ReadFloatFromTextContent(); out.mWeighting = ReadFloatFromTextContent();
TestClosing("weighting"); } else if (currentName == "mix_with_previous_layer") {
} else if (IsElement("mix_with_previous_layer")) {
out.mMixWithPrevious = ReadFloatFromTextContent(); out.mMixWithPrevious = ReadFloatFromTextContent();
TestClosing("mix_with_previous_layer");
} }
// MAX3D extensions // MAX3D extensions
// ------------------------------------------------------- // -------------------------------------------------------
else if (IsElement("amount")) { else if (currentName == "amount") {
out.mWeighting = ReadFloatFromTextContent(); out.mWeighting = ReadFloatFromTextContent();
TestClosing("amount");
}
} else if (mReader->getNodeType() == irr::io::EXN_ELEMENT_END) {
if (strcmp(mReader->getNodeName(), "technique") == 0)
break;
} }
} }
} }
@ -1297,8 +1243,6 @@ void ColladaParser::ReadEffectColor(XmlNode &node, aiColor4D &pColor, Sampler &p
if (node.empty()) { if (node.empty()) {
return; return;
} }
/*if (mReader->isEmptyElement())
return;*/
// Save current element name // Save current element name
const std::string curElem = mReader->getNodeName(); const std::string curElem = mReader->getNodeName();