Universal::Node& Node::addChild(){ NodeID id = nextNodeID(); std::shared_ptr<Universal::Node> newChild = std::make_shared<Universal::Node>(id,parent); local_addChild(newChild); Universal.populateNewChild(newChild); return *newChild.get(); }
// Set properties for material nodes void OBJBaker::setMaterialNodeProperties(FBXNode& materialNode, QString material, FBXGeometry& geometry) { auto materialID = nextNodeID(); _materialIDs.push_back(materialID); materialNode.properties = { materialID, material, MESH }; FBXMaterial currentMaterial = geometry.materials[material]; // Setting the hierarchy: Material -> Properties70 -> P -> Properties FBXNode properties70Node; properties70Node.name = PROPERTIES70_NODE_NAME; // Set diffuseColor FBXNode pNodeDiffuseColor; { pNodeDiffuseColor.name = P_NODE_NAME; pNodeDiffuseColor.properties.append({ "DiffuseColor", "Color", "", "A", currentMaterial.diffuseColor[0], currentMaterial.diffuseColor[1], currentMaterial.diffuseColor[2] }); } properties70Node.children.append(pNodeDiffuseColor); // Set specularColor FBXNode pNodeSpecularColor; { pNodeSpecularColor.name = P_NODE_NAME; pNodeSpecularColor.properties.append({ "SpecularColor", "Color", "", "A", currentMaterial.specularColor[0], currentMaterial.specularColor[1], currentMaterial.specularColor[2] }); } properties70Node.children.append(pNodeSpecularColor); // Set Shininess FBXNode pNodeShininess; { pNodeShininess.name = P_NODE_NAME; pNodeShininess.properties.append({ "Shininess", "Number", "", "A", currentMaterial.shininess }); } properties70Node.children.append(pNodeShininess); // Set Opacity FBXNode pNodeOpacity; { pNodeOpacity.name = P_NODE_NAME; pNodeOpacity.properties.append({ "Opacity", "Number", "", "A", currentMaterial.opacity }); } properties70Node.children.append(pNodeOpacity); materialNode.children.append(properties70Node); }
NodeID Node::move(Universal::Node &newParent){ Thread::ID t_id = Execution::TaskManager::getCurrentThreadID(); newParent.access(t_id).addChild(parent->access().getChildOwnership(ID)); parent->access(t_id).removeChild(ID); parent = &newParent; if(ID<parent->access(t_id).ID)ID = nextNodeID(); Universal.populateMove(newParent,t_id); Universal.populateNewID(ID,t_id); return ID; }
void OBJBaker::createFBXNodeTree(FBXNode& rootNode, FBXGeometry& geometry) { // Generating FBX Header Node FBXNode headerNode; headerNode.name = FBX_HEADER_EXTENSION; // Generating global settings node // Required for Unit Scale Factor FBXNode globalSettingsNode; globalSettingsNode.name = GLOBAL_SETTINGS_NODE_NAME; // Setting the tree hierarchy: GlobalSettings -> Properties70 -> P -> Properties FBXNode properties70Node; properties70Node.name = PROPERTIES70_NODE_NAME; FBXNode pNode; { pNode.name = P_NODE_NAME; pNode.properties.append({ "UnitScaleFactor", "double", "Number", "", UNIT_SCALE_FACTOR }); } properties70Node.children = { pNode }; globalSettingsNode.children = { properties70Node }; // Generating Object node FBXNode objectNode; objectNode.name = OBJECTS_NODE_NAME; // Generating Object node's child - Geometry node FBXNode geometryNode; geometryNode.name = GEOMETRY_NODE_NAME; NodeID geometryID; { geometryID = nextNodeID(); geometryNode.properties = { geometryID, GEOMETRY_NODE_NAME, MESH }; } // Compress the mesh information and store in dracoNode bool hasDeformers = false; // No concept of deformers for an OBJ FBXNode dracoNode; compressMesh(geometry.meshes[0], hasDeformers, dracoNode); geometryNode.children.append(dracoNode); // Generating Object node's child - Model node FBXNode modelNode; modelNode.name = MODEL_NODE_NAME; NodeID modelID; { modelID = nextNodeID(); modelNode.properties = { modelID, MODEL_NODE_NAME, MESH }; } objectNode.children = { geometryNode, modelNode }; // Generating Objects node's child - Material node auto& meshParts = geometry.meshes[0].parts; for (auto& meshPart : meshParts) { FBXNode materialNode; materialNode.name = MATERIAL_NODE_NAME; if (geometry.materials.size() == 1) { // case when no material information is provided, OBJReader considers it as a single default material for (auto& materialID : geometry.materials.keys()) { setMaterialNodeProperties(materialNode, materialID, geometry); } } else { setMaterialNodeProperties(materialNode, meshPart.materialID, geometry); } objectNode.children.append(materialNode); } // Generating Texture Node // iterate through mesh parts and process the associated textures auto size = meshParts.size(); for (int i = 0; i < size; i++) { QString material = meshParts[i].materialID; FBXMaterial currentMaterial = geometry.materials[material]; if (!currentMaterial.albedoTexture.filename.isEmpty() || !currentMaterial.specularTexture.filename.isEmpty()) { auto textureID = nextNodeID(); _mapTextureMaterial.emplace_back(textureID, i); FBXNode textureNode; { textureNode.name = TEXTURE_NODE_NAME; textureNode.properties = { textureID, "texture" + QString::number(textureID) }; } // Texture node child - TextureName node FBXNode textureNameNode; { textureNameNode.name = TEXTURENAME_NODE_NAME; QByteArray propertyString = (!currentMaterial.albedoTexture.filename.isEmpty()) ? "Kd" : "Ka"; textureNameNode.properties = { propertyString }; } // Texture node child - Relative Filename node FBXNode relativeFilenameNode; { relativeFilenameNode.name = RELATIVEFILENAME_NODE_NAME; } QByteArray textureFileName = (!currentMaterial.albedoTexture.filename.isEmpty()) ? currentMaterial.albedoTexture.filename : currentMaterial.specularTexture.filename; auto textureType = (!currentMaterial.albedoTexture.filename.isEmpty()) ? image::TextureUsage::Type::ALBEDO_TEXTURE : image::TextureUsage::Type::SPECULAR_TEXTURE; // Compress the texture using ModelBaker::compressTexture() and store compressed file's name in the node auto textureFile = compressTexture(textureFileName, textureType); if (textureFile.isNull()) { // Baking failed return handleError("Failed to compress texture: " + textureFileName); return; } relativeFilenameNode.properties = { textureFile }; textureNode.children = { textureNameNode, relativeFilenameNode }; objectNode.children.append(textureNode); } } // Generating Connections node FBXNode connectionsNode; connectionsNode.name = CONNECTIONS_NODE_NAME; // connect Geometry to Model FBXNode cNode; cNode.name = C_NODE_NAME; cNode.properties = { CONNECTIONS_NODE_PROPERTY, geometryID, modelID }; connectionsNode.children = { cNode }; // connect all materials to model for (auto& materialID : _materialIDs) { FBXNode cNode; cNode.name = C_NODE_NAME; cNode.properties = { CONNECTIONS_NODE_PROPERTY, materialID, modelID }; connectionsNode.children.append(cNode); } // Connect textures to materials for (const auto& texMat : _mapTextureMaterial) { FBXNode cAmbientNode; cAmbientNode.name = C_NODE_NAME; cAmbientNode.properties = { CONNECTIONS_NODE_PROPERTY_1, texMat.first, _materialIDs[texMat.second], "AmbientFactor" }; connectionsNode.children.append(cAmbientNode); FBXNode cDiffuseNode; cDiffuseNode.name = C_NODE_NAME; cDiffuseNode.properties = { CONNECTIONS_NODE_PROPERTY_1, texMat.first, _materialIDs[texMat.second], "DiffuseColor" }; connectionsNode.children.append(cDiffuseNode); } // Make all generated nodes children of rootNode rootNode.children = { globalSettingsNode, objectNode, connectionsNode }; }