/// \file AMFImporter_Material.cpp /// \brief Parsing data from material nodes. /// \date 2016 /// \author smal.root@gmail.com #ifndef ASSIMP_BUILD_NO_AMF_IMPORTER #include "AMFImporter.hpp" #include "AMFImporter_Macro.hpp" namespace Assimp { // , and . // > // // A color definition. // Multi elements - No. // Parent element - , , , , . // // "profile" can be one of "sRGB", "AdobeRGB", "Wide-Gamut-RGB", "CIERGB", "CIELAB", or "CIEXYZ". // Children elements: // , , , // Multi elements - No. // Red, Greed, Blue and Alpha (transparency) component of a color in sRGB space, values ranging from 0 to 1. The // values can be specified as constants, or as a formula depending on the coordinates. void AMFImporter::ParseNode_Color() { std::string profile; CAMFImporter_NodeElement* ne; // Read attributes for node . MACRO_ATTRREAD_LOOPBEG; MACRO_ATTRREAD_CHECK_RET("profile", profile, mReader->getAttributeValue); MACRO_ATTRREAD_LOOPEND; // create new color object. ne = new CAMFImporter_NodeElement_Color(mNodeElement_Cur); CAMFImporter_NodeElement_Color& als = *((CAMFImporter_NodeElement_Color*)ne);// alias for convenience als.Profile = profile; // Check for child nodes if(!mReader->isEmptyElement()) { bool read_flag[4] = { false, false, false, false }; ParseHelper_Node_Enter(ne); MACRO_NODECHECK_LOOPBEGIN("color"); MACRO_NODECHECK_READCOMP_F("r", read_flag[0], als.Color.r); MACRO_NODECHECK_READCOMP_F("g", read_flag[1], als.Color.g); MACRO_NODECHECK_READCOMP_F("b", read_flag[2], als.Color.b); MACRO_NODECHECK_READCOMP_F("a", read_flag[3], als.Color.a); MACRO_NODECHECK_LOOPEND("color"); ParseHelper_Node_Exit(); // check that all components was defined if(!(read_flag[0] && read_flag[1] && read_flag[2])) throw DeadlyImportError("Not all color components are defined."); // check if is absent. Then manualy add "a == 1". if(!read_flag[3]) als.Color.a = 1; }// if(!mReader->isEmptyElement()) else { mNodeElement_Cur->Child.push_back(ne);// Add element to child list of current element }// if(!mReader->isEmptyElement()) else als.Composed = false; mNodeElement_List.push_back(ne);// and to node element list because its a new object in graph. } // // // An available material. // Multi elements - Yes. // Parent element - . void AMFImporter::ParseNode_Material() { std::string id; CAMFImporter_NodeElement* ne; // Read attributes for node . MACRO_ATTRREAD_LOOPBEG; MACRO_ATTRREAD_CHECK_RET("id", id, mReader->getAttributeValue); MACRO_ATTRREAD_LOOPEND; // create new object. ne = new CAMFImporter_NodeElement_Material(mNodeElement_Cur); // and assign read data ((CAMFImporter_NodeElement_Material*)ne)->ID = id; // Check for child nodes if(!mReader->isEmptyElement()) { bool col_read = false; ParseHelper_Node_Enter(ne); MACRO_NODECHECK_LOOPBEGIN("material"); if(XML_CheckNode_NameEqual("color")) { // Check if data already defined. if(col_read) Throw_MoreThanOnceDefined("color", "Only one color can be defined for ."); // read data and set flag about it ParseNode_Color(); col_read = true; continue; } if(XML_CheckNode_NameEqual("metadata")) { ParseNode_Metadata(); continue; } MACRO_NODECHECK_LOOPEND("material"); ParseHelper_Node_Exit(); }// if(!mReader->isEmptyElement()) else { mNodeElement_Cur->Child.push_back(ne);// Add element to child list of current element }// if(!mReader->isEmptyElement()) else mNodeElement_List.push_back(ne);// and to node element list because its a new object in graph. } // // // Specifies an texture data to be used as a map. Lists a sequence of Base64 values specifying values for pixels from left to right then top to bottom, // then layer by layer. // Multi elements - Yes. // Parent element - . void AMFImporter::ParseNode_Texture() { std::string id; uint32_t width = 0; uint32_t height = 0; uint32_t depth = 1; std::string type; bool tiled = false; std::string enc64_data; CAMFImporter_NodeElement* ne; // Read attributes for node . MACRO_ATTRREAD_LOOPBEG; MACRO_ATTRREAD_CHECK_RET("id", id, mReader->getAttributeValue); MACRO_ATTRREAD_CHECK_RET("width", width, XML_ReadNode_GetAttrVal_AsU32); MACRO_ATTRREAD_CHECK_RET("height", height, XML_ReadNode_GetAttrVal_AsU32); MACRO_ATTRREAD_CHECK_RET("depth", depth, XML_ReadNode_GetAttrVal_AsU32); MACRO_ATTRREAD_CHECK_RET("type", type, mReader->getAttributeValue); MACRO_ATTRREAD_CHECK_RET("tiled", tiled, XML_ReadNode_GetAttrVal_AsBool); MACRO_ATTRREAD_LOOPEND; // create new texture object. ne = new CAMFImporter_NodeElement_Texture(mNodeElement_Cur); CAMFImporter_NodeElement_Texture& als = *((CAMFImporter_NodeElement_Texture*)ne);// alias for convenience // Check for child nodes if(!mReader->isEmptyElement()) XML_ReadNode_GetVal_AsString(enc64_data); // check that all components was defined if(id.empty()) throw DeadlyImportError("ID for texture must be defined."); if(width < 1) Throw_IncorrectAttrValue("width"); if(height < 1) Throw_IncorrectAttrValue("height"); if(depth < 1) Throw_IncorrectAttrValue("depth"); if(type != "grayscale") Throw_IncorrectAttrValue("type"); if(enc64_data.empty()) throw DeadlyImportError("Texture data not defined."); // copy data als.ID = id; als.Width = width; als.Height = height; als.Depth = depth; als.Tiled = tiled; ParseHelper_Decode_Base64(enc64_data, als.Data); // check data size if((width * height * depth) != als.Data.size()) throw DeadlyImportError("Texture has incorrect data size."); mNodeElement_Cur->Child.push_back(ne);// Add element to child list of current element mNodeElement_List.push_back(ne);// and to node element list because its a new object in graph. } // // , old name: // Specifies texture coordinates for triangle. // Multi elements - No. // Parent element - . // Children elements: // , , , , , . Old name: , , , , , . // Multi elements - No. // Texture coordinates for every vertex of triangle. void AMFImporter::ParseNode_TexMap(const bool pUseOldName) { std::string rtexid, gtexid, btexid, atexid; CAMFImporter_NodeElement* ne; // Read attributes for node . MACRO_ATTRREAD_LOOPBEG; MACRO_ATTRREAD_CHECK_RET("rtexid", rtexid, mReader->getAttributeValue); MACRO_ATTRREAD_CHECK_RET("gtexid", gtexid, mReader->getAttributeValue); MACRO_ATTRREAD_CHECK_RET("btexid", btexid, mReader->getAttributeValue); MACRO_ATTRREAD_CHECK_RET("atexid", atexid, mReader->getAttributeValue); MACRO_ATTRREAD_LOOPEND; // create new texture coordinates object. ne = new CAMFImporter_NodeElement_TexMap(mNodeElement_Cur); CAMFImporter_NodeElement_TexMap& als = *((CAMFImporter_NodeElement_TexMap*)ne);// alias for convenience // check data if(rtexid.empty() && gtexid.empty() && btexid.empty()) throw DeadlyImportError("ParseNode_TexMap. At least one texture ID must be defined."); // Check for children nodes XML_CheckNode_MustHaveChildren(); // read children nodes bool read_flag[6] = { false, false, false, false, false, false }; ParseHelper_Node_Enter(ne); if(!pUseOldName) { MACRO_NODECHECK_LOOPBEGIN("texmap"); MACRO_NODECHECK_READCOMP_F("utex1", read_flag[0], als.TextureCoordinate[0].x); MACRO_NODECHECK_READCOMP_F("utex2", read_flag[1], als.TextureCoordinate[1].x); MACRO_NODECHECK_READCOMP_F("utex3", read_flag[2], als.TextureCoordinate[2].x); MACRO_NODECHECK_READCOMP_F("vtex1", read_flag[3], als.TextureCoordinate[0].y); MACRO_NODECHECK_READCOMP_F("vtex2", read_flag[4], als.TextureCoordinate[1].y); MACRO_NODECHECK_READCOMP_F("vtex3", read_flag[5], als.TextureCoordinate[2].y); MACRO_NODECHECK_LOOPEND("texmap"); } else { MACRO_NODECHECK_LOOPBEGIN("map"); MACRO_NODECHECK_READCOMP_F("u1", read_flag[0], als.TextureCoordinate[0].x); MACRO_NODECHECK_READCOMP_F("u2", read_flag[1], als.TextureCoordinate[1].x); MACRO_NODECHECK_READCOMP_F("u3", read_flag[2], als.TextureCoordinate[2].x); MACRO_NODECHECK_READCOMP_F("v1", read_flag[3], als.TextureCoordinate[0].y); MACRO_NODECHECK_READCOMP_F("v2", read_flag[4], als.TextureCoordinate[1].y); MACRO_NODECHECK_READCOMP_F("v3", read_flag[5], als.TextureCoordinate[2].y); MACRO_NODECHECK_LOOPEND("map"); }// if(!pUseOldName) else ParseHelper_Node_Exit(); // check that all components was defined if(!(read_flag[0] && read_flag[1] && read_flag[2] && read_flag[3] && read_flag[4] && read_flag[5])) throw DeadlyImportError("Not all texture coordinates are defined."); // copy attributes data als.TextureID_R = rtexid; als.TextureID_G = gtexid; als.TextureID_B = btexid; als.TextureID_A = atexid; mNodeElement_List.push_back(ne);// add to node element list because its a new object in graph. } }// namespace Assimp #endif // !ASSIMP_BUILD_NO_AMF_IMPORTER