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,105 +1088,93 @@ 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");
pEffect.mParams[sid] = EffectParam(); //= mReader->getAttributeValue(attrSID);
ReadEffectParam(pEffect.mParams[sid]); pEffect.mParams[sid] = EffectParam();
} else if (IsElement("technique") || IsElement("extra")) { ReadEffectParam(currentNode, pEffect.mParams[sid]);
// just syntactic sugar } else if (currentName == "technique" || currentName == "extra" ) {
// just syntactic sugar
} else if (mFormat == FV_1_4_n && currentName == "image") {
// read ID. Another entry which is "optional" by design but obligatory in reality
std::string id = currentNode.attribute("id").as_string();
//int attrID = GetAttribute("id");
//std::string id = mReader->getAttributeValue(attrID);
// create an entry and store it in the library under its ID
mImageLibrary[id] = Image();
// read on from there
ReadImage(currentNode, mImageLibrary[id]);
} else if (currentName == "phong")
pEffect.mShadeType = Shade_Phong;
else if (currentName == "constant")
pEffect.mShadeType = Shade_Constant;
else if (currentName == "lambert")
pEffect.mShadeType = Shade_Lambert;
else if (currentName == "blinn")
pEffect.mShadeType = Shade_Blinn;
/* Color + texture properties */
else if (currentName == "emission")
ReadEffectColor(currentNode, pEffect.mEmissive, pEffect.mTexEmissive);
else if (currentName == "ambient")
ReadEffectColor(currentNode, pEffect.mAmbient, pEffect.mTexAmbient);
else if (currentName == "diffuse")
ReadEffectColor(currentNode, pEffect.mDiffuse, pEffect.mTexDiffuse);
else if (currentName == "specular")
ReadEffectColor(currentNode, pEffect.mSpecular, pEffect.mTexSpecular);
else if (currentName == "reflective") {
ReadEffectColor(currentNode, pEffect.mReflective, pEffect.mTexReflective);
} else if (currentName == "transparent") {
pEffect.mHasTransparency = true;
const char *opaque = currentNode.attribute("opaque").as_string();
//const char *opaque = mReader->getAttributeValueSafe("opaque");
if (::strcmp(opaque, "RGB_ZERO") == 0 || ::strcmp(opaque, "RGB_ONE") == 0) {
pEffect.mRGBTransparency = true;
} }
else if (mFormat == FV_1_4_n && IsElement("image")) { // In RGB_ZERO mode, the transparency is interpreted in reverse, go figure...
// read ID. Another entry which is "optional" by design but obligatory in reality if (::strcmp(opaque, "RGB_ZERO") == 0 || ::strcmp(opaque, "A_ZERO") == 0) {
int attrID = GetAttribute("id"); pEffect.mInvertTransparency = true;
std::string id = mReader->getAttributeValue(attrID);
// create an entry and store it in the library under its ID
mImageLibrary[id] = Image();
// read on from there
ReadImage(mImageLibrary[id]);
} }
/* Shading modes */ ReadEffectColor(currentNode, pEffect.mTransparent, pEffect.mTexTransparent);
else if (IsElement("phong")) } else if (currentName == "shininess")
pEffect.mShadeType = Shade_Phong; ReadEffectFloat(currentNode, pEffect.mShininess);
else if (IsElement("constant")) else if (currentName == "reflectivity")
pEffect.mShadeType = Shade_Constant; ReadEffectFloat(currentNode, pEffect.mReflectivity);
else if (IsElement("lambert"))
pEffect.mShadeType = Shade_Lambert;
else if (IsElement("blinn"))
pEffect.mShadeType = Shade_Blinn;
/* Color + texture properties */ /* Single scalar properties */
else if (IsElement("emission")) else if (currentName == "transparency")
ReadEffectColor(pEffect.mEmissive, pEffect.mTexEmissive); ReadEffectFloat(currentNode, pEffect.mTransparency);
else if (IsElement("ambient")) else if (currentName == "index_of_refraction")
ReadEffectColor(pEffect.mAmbient, pEffect.mTexAmbient); ReadEffectFloat(currentNode, pEffect.mRefractIndex);
else if (IsElement("diffuse"))
ReadEffectColor(pEffect.mDiffuse, pEffect.mTexDiffuse);
else if (IsElement("specular"))
ReadEffectColor(pEffect.mSpecular, pEffect.mTexSpecular);
else if (IsElement("reflective")) {
ReadEffectColor(pEffect.mReflective, pEffect.mTexReflective);
} else if (IsElement("transparent")) {
pEffect.mHasTransparency = true;
const char *opaque = mReader->getAttributeValueSafe("opaque"); // GOOGLEEARTH/OKINO extensions
// -------------------------------------------------------
else if (currentName == "double_sided")
pEffect.mDoubleSided = ReadBoolFromTextContent();
if (::strcmp(opaque, "RGB_ZERO") == 0 || ::strcmp(opaque, "RGB_ONE") == 0) { // FCOLLADA extensions
pEffect.mRGBTransparency = true; // -------------------------------------------------------
} else if (currentName == "bump") {
aiColor4D dummy;
ReadEffectColor(currentNode, dummy, pEffect.mTexBump);
}
// In RGB_ZERO mode, the transparency is interpreted in reverse, go figure... // MAX3D extensions
if (::strcmp(opaque, "RGB_ZERO") == 0 || ::strcmp(opaque, "A_ZERO") == 0) { // -------------------------------------------------------
pEffect.mInvertTransparency = true; else if (currentName == "wireframe") {
} pEffect.mWireframe = ReadBoolFromTextContent();
} else if (currentName == "faceted") {
ReadEffectColor(pEffect.mTransparent, pEffect.mTexTransparent); pEffect.mFaceted = ReadBoolFromTextContent();
} else if (IsElement("shininess"))
ReadEffectFloat(pEffect.mShininess);
else if (IsElement("reflectivity"))
ReadEffectFloat(pEffect.mReflectivity);
/* Single scalar properties */
else if (IsElement("transparency"))
ReadEffectFloat(pEffect.mTransparency);
else if (IsElement("index_of_refraction"))
ReadEffectFloat(pEffect.mRefractIndex);
// GOOGLEEARTH/OKINO extensions
// -------------------------------------------------------
else if (IsElement("double_sided"))
pEffect.mDoubleSided = ReadBoolFromTextContent();
// FCOLLADA extensions
// -------------------------------------------------------
else if (IsElement("bump")) {
aiColor4D dummy;
ReadEffectColor(dummy, pEffect.mTexBump);
}
// MAX3D extensions
// -------------------------------------------------------
else if (IsElement("wireframe")) {
pEffect.mWireframe = ReadBoolFromTextContent();
TestClosing("wireframe");
} else if (IsElement("faceted")) {
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()) {
const std::string &currentName = currentNode.name();
// MAYA extensions
// -------------------------------------------------------
if (currentName == "wrapU") {
out.mWrapU = ReadBoolFromTextContent();
} else if (currentName == "wrapV") {
out.mWrapV = ReadBoolFromTextContent();
} else if (currentName == "mirrorU") {
out.mMirrorU = ReadBoolFromTextContent();
} else if (currentName == "mirrorV") {
out.mMirrorV = ReadBoolFromTextContent();
} else if (currentName == "repeatU") {
out.mTransform.mScaling.x = ReadFloatFromTextContent();
} else if (currentName == "repeatV") {
out.mTransform.mScaling.y = ReadFloatFromTextContent();
} else if (currentName == "offsetU") {
out.mTransform.mTranslation.x = ReadFloatFromTextContent();
} else if (currentName == "offsetV") {
out.mTransform.mTranslation.y = ReadFloatFromTextContent();
} else if (currentName == "rotateUV") {
out.mTransform.mRotation = ReadFloatFromTextContent();
} else if (currentName == "blend_mode") {
while (mReader->read()) { const char *sz = GetTextContent();
if (mReader->getNodeType() == irr::io::EXN_ELEMENT) { // http://www.feelingsoftware.com/content/view/55/72/lang,en/
// NONE, OVER, IN, OUT, ADD, SUBTRACT, MULTIPLY, DIFFERENCE, LIGHTEN, DARKEN, SATURATE, DESATURATE and ILLUMINATE
// MAYA extensions if (0 == ASSIMP_strincmp(sz, "ADD", 3))
// ------------------------------------------------------- out.mOp = aiTextureOp_Add;
if (IsElement("wrapU")) { else if (0 == ASSIMP_strincmp(sz, "SUBTRACT", 8))
out.mWrapU = ReadBoolFromTextContent(); out.mOp = aiTextureOp_Subtract;
TestClosing("wrapU"); else if (0 == ASSIMP_strincmp(sz, "MULTIPLY", 8))
} else if (IsElement("wrapV")) { out.mOp = aiTextureOp_Multiply;
out.mWrapV = ReadBoolFromTextContent(); else {
TestClosing("wrapV"); ASSIMP_LOG_WARN("Collada: Unsupported MAYA texture blend mode");
} else if (IsElement("mirrorU")) {
out.mMirrorU = ReadBoolFromTextContent();
TestClosing("mirrorU");
} else if (IsElement("mirrorV")) {
out.mMirrorV = ReadBoolFromTextContent();
TestClosing("mirrorV");
} else if (IsElement("repeatU")) {
out.mTransform.mScaling.x = ReadFloatFromTextContent();
TestClosing("repeatU");
} else if (IsElement("repeatV")) {
out.mTransform.mScaling.y = ReadFloatFromTextContent();
TestClosing("repeatV");
} else if (IsElement("offsetU")) {
out.mTransform.mTranslation.x = ReadFloatFromTextContent();
TestClosing("offsetU");
} else if (IsElement("offsetV")) {
out.mTransform.mTranslation.y = ReadFloatFromTextContent();
TestClosing("offsetV");
} else if (IsElement("rotateUV")) {
out.mTransform.mRotation = ReadFloatFromTextContent();
TestClosing("rotateUV");
} else if (IsElement("blend_mode")) {
const char *sz = GetTextContent();
// http://www.feelingsoftware.com/content/view/55/72/lang,en/
// NONE, OVER, IN, OUT, ADD, SUBTRACT, MULTIPLY, DIFFERENCE, LIGHTEN, DARKEN, SATURATE, DESATURATE and ILLUMINATE
if (0 == ASSIMP_strincmp(sz, "ADD", 3))
out.mOp = aiTextureOp_Add;
else if (0 == ASSIMP_strincmp(sz, "SUBTRACT", 8))
out.mOp = aiTextureOp_Subtract;
else if (0 == ASSIMP_strincmp(sz, "MULTIPLY", 8))
out.mOp = aiTextureOp_Multiply;
else {
ASSIMP_LOG_WARN("Collada: Unsupported MAYA texture blend mode");
}
TestClosing("blend_mode");
} }
// OKINO extensions }
// ------------------------------------------------------- // OKINO extensions
else if (IsElement("weighting")) { // -------------------------------------------------------
out.mWeighting = ReadFloatFromTextContent(); else if (currentName == "weighting") {
TestClosing("weighting"); out.mWeighting = ReadFloatFromTextContent();
} else if (IsElement("mix_with_previous_layer")) { } else if (currentName == "mix_with_previous_layer") {
out.mMixWithPrevious = ReadFloatFromTextContent(); out.mMixWithPrevious = ReadFloatFromTextContent();
TestClosing("mix_with_previous_layer"); }
} // MAX3D extensions
// MAX3D extensions // -------------------------------------------------------
// ------------------------------------------------------- else if (currentName == "amount") {
else if (IsElement("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();