Error CollisionResource::load(const ResourceFilename& filename) { XmlElement el; XmlDocument doc; ANKI_CHECK(openFileParseXml(filename, doc)); XmlElement collEl; ANKI_CHECK(doc.getChildElement("collisionShape", collEl)); ANKI_CHECK(collEl.getChildElement("type", el)); CString type; ANKI_CHECK(el.getText(type)); XmlElement valEl; ANKI_CHECK(collEl.getChildElement("value", valEl)); PhysicsWorld& physics = getManager().getPhysicsWorld(); PhysicsCollisionShapeInitInfo csInit; if(type == "sphere") { F64 tmp; ANKI_CHECK(valEl.getF64(tmp)); m_physicsShape = physics.newInstance<PhysicsSphere>(csInit, tmp); } else if(type == "box") { Vec3 extend; ANKI_CHECK(valEl.getVec3(extend)); m_physicsShape = physics.newInstance<PhysicsBox>(csInit, extend); } else if(type == "staticMesh") { CString meshfname; ANKI_CHECK(valEl.getText(meshfname)); MeshLoader loader(&getManager()); ANKI_CHECK(loader.load(meshfname)); m_physicsShape = physics.newInstance<PhysicsTriangleSoup>(csInit, reinterpret_cast<const Vec3*>(loader.getVertexData()), loader.getVertexSize(), reinterpret_cast<const U16*>(loader.getIndexData()), loader.getHeader().m_totalIndicesCount); } else { ANKI_LOGE("Incorrect collision type"); return ErrorCode::USER_DATA; } return ErrorCode::NONE; }
//------------------------------------------------------------------------------ void StupidWindow::loadKeyMappings() { int i; OscMappingManager *oscManager = mainPanel->getOscMappingManager(); MidiMappingManager *midiManager = mainPanel->getMidiMappingManager(); File mappingsFile = JuceHelperStuff::getAppDataFolder().getChildFile("AppMappings.xml"); if(mappingsFile.existsAsFile()) { ScopedPointer<XmlElement> rootXml(XmlDocument::parse(mappingsFile)); if(rootXml) { XmlElement *keyMappings = rootXml->getChildByName("KEYMAPPINGS"); XmlElement *midiMappings = rootXml->getChildByName("MidiMappings"); XmlElement *oscMappings = rootXml->getChildByName("OscMappings"); if(keyMappings) commandManager.getKeyMappings()->restoreFromXml(*keyMappings); if(midiMappings) { for(i=0;i<midiMappings->getNumChildElements();++i) { XmlElement *tempEl = midiMappings->getChildElement(i); if(tempEl->hasTagName("MidiAppMapping")) { MidiAppMapping *newMapping = new MidiAppMapping(midiManager, tempEl); midiManager->registerAppMapping(newMapping); } } } if(oscMappings) { for(i=0;i<oscMappings->getNumChildElements();++i) { XmlElement *tempEl = oscMappings->getChildElement(i); if(tempEl->hasTagName("OscAppMapping")) { OscAppMapping *newMapping = new OscAppMapping(oscManager, tempEl); oscManager->registerAppMapping(newMapping); } } } } } }
Error Skeleton::load(const ResourceFilename& filename) { XmlDocument doc; ANKI_CHECK(openFileParseXml(filename, doc)); XmlElement rootEl; ANKI_CHECK(doc.getChildElement("skeleton", rootEl)); XmlElement bonesEl; ANKI_CHECK(rootEl.getChildElement("bones", bonesEl)); // count the bones count XmlElement boneEl; U32 bonesCount = 0; ANKI_CHECK(bonesEl.getChildElement("bone", boneEl)); ANKI_CHECK(boneEl.getSiblingElementsCount(bonesCount)); ++bonesCount; m_bones.create(getAllocator(), bonesCount); // Load every bone bonesCount = 0; do { Bone& bone = m_bones[bonesCount++]; // <name> XmlElement nameEl; ANKI_CHECK(boneEl.getChildElement("name", nameEl)); CString tmp; ANKI_CHECK(nameEl.getText(tmp)); bone.m_name.create(getAllocator(), tmp); // <transform> XmlElement trfEl; ANKI_CHECK(boneEl.getChildElement("transform", trfEl)); ANKI_CHECK(trfEl.getMat4(bone.m_transform)); // Advance ANKI_CHECK(boneEl.getNextSiblingElement("bone", boneEl)); } while(boneEl); return ErrorCode::NONE; }
//============================================================================== void Skeleton::load(const CString& filename, ResourceInitializer& init) { XmlDocument doc; doc.loadFile(filename, init.m_tempAlloc); XmlElement rootEl = doc.getChildElement("skeleton"); XmlElement bonesEl = rootEl.getChildElement("bones"); // count the bones count U bonesCount = 0; XmlElement boneEl = bonesEl.getChildElement("bone"); do { ++bonesCount; boneEl = boneEl.getNextSiblingElement("bone"); } while(boneEl); // Alloc the vector m_bones = std::move(ResourceVector<Bone>(init.m_alloc)); m_bones.resize(bonesCount, Bone(init.m_alloc)); // Load every bone boneEl = bonesEl.getChildElement("bone"); bonesCount = 0; do { Bone& bone = m_bones[bonesCount++]; // <name> XmlElement nameEl = boneEl.getChildElement("name"); bone.m_name = nameEl.getText(); // <transform> XmlElement trfEl = boneEl.getChildElement("transform"); bone.m_transform = trfEl.getMat4(); // Advance boneEl = boneEl.getNextSiblingElement("bone"); } while(boneEl); }
//============================================================================== void MaterialProgramCreator::parseProgramsTag(const XmlElement& el) { // // First gather all the inputs // XmlElement programEl = el.getChildElement("program"_cstr); do { parseInputsTag(programEl); programEl = programEl.getNextSiblingElement("program"_cstr); } while(programEl); // Sort them by name to decrease the change of creating unique shaders std::sort(m_inputs.begin(), m_inputs.end(), InputSortFunctor()); // // Then parse the includes, operations and other parts of the program // programEl = el.getChildElement("program"_cstr); do { parseProgramTag(programEl); programEl = programEl.getNextSiblingElement("program"_cstr); } while(programEl); // // Sanity checks // // Check that all input is referenced for(Input& in : m_inputs) { if(in.m_shaderDefinedMask != in.m_shaderReferencedMask) { throw ANKI_EXCEPTION("Variable not referenced or not defined %s", &in.m_name[0]); } } }
bool pspSpatConfig::loadXml(File xmlFile){ XmlDocument myDocument (xmlFile); XmlElement* mainElement = myDocument.getDocumentElement(); if(!mainElement->hasTagName("SpatConfig")){ AlertWindow::showMessageBoxAsync (AlertWindow::WarningIcon, "xml file doesn't contain room config data", "", "OK"); //delete mainElement; return false; } else{ if(XmlElement* myConfig = mainElement->getChildElement(0)){ getAttributesFromElement(myConfig); } } delete mainElement; return true; }
//============================================================================== Error Material::parseMaterialTag(const XmlElement& materialEl, ResourceInitializer& rinit) { Error err = ErrorCode::NONE; XmlElement el; // levelsOfDetail // XmlElement lodEl; ANKI_CHECK(materialEl.getChildElementOptional("levelsOfDetail", lodEl)); if(lodEl) { I64 tmp; ANKI_CHECK(lodEl.getI64(tmp)); m_lodsCount = (tmp < 1) ? 1 : tmp; } else { m_lodsCount = 1; } // shadow // XmlElement shadowEl; ANKI_CHECK(materialEl.getChildElementOptional("shadow", shadowEl)); if(shadowEl) { I64 tmp; ANKI_CHECK(shadowEl.getI64(tmp)); m_shadow = tmp; } // blendFunctions // XmlElement blendFunctionsEl; ANKI_CHECK( materialEl.getChildElementOptional("blendFunctions", blendFunctionsEl)); if(blendFunctionsEl) { CString cstr; // sFactor ANKI_CHECK(blendFunctionsEl.getChildElement("sFactor", el)); ANKI_CHECK(el.getText(cstr)); m_blendingSfactor = blendToEnum(cstr); if(m_blendingSfactor == 0) { return ErrorCode::USER_DATA; } // dFactor ANKI_CHECK(blendFunctionsEl.getChildElement("dFactor", el)); ANKI_CHECK(el.getText(cstr)); m_blendingDfactor = blendToEnum(cstr); if(m_blendingDfactor == 0) { return ErrorCode::USER_DATA; } } else { m_passesCount = 2; } // depthTesting // XmlElement depthTestingEl; ANKI_CHECK( materialEl.getChildElementOptional("depthTesting", depthTestingEl)); if(depthTestingEl) { I64 tmp; ANKI_CHECK(depthTestingEl.getI64(tmp)); m_depthTesting = tmp; } // wireframe // XmlElement wireframeEl; ANKI_CHECK(materialEl.getChildElementOptional("wireframe", wireframeEl)); if(wireframeEl) { I64 tmp; ANKI_CHECK(wireframeEl.getI64(tmp)); m_wireframe = tmp; } // shaderProgram // ANKI_CHECK(materialEl.getChildElement("programs", el)); MaterialProgramCreator loader(rinit.m_tempAlloc); ANKI_CHECK(loader.parseProgramsTag(el)); m_tessellation = loader.hasTessellation(); U tessCount = m_tessellation ? 2 : 1; // Alloc program vector ANKI_CHECK(m_progs.create(rinit.m_alloc, countShaders(ShaderType::VERTEX) + countShaders(ShaderType::TESSELLATION_CONTROL) + countShaders(ShaderType::TESSELLATION_EVALUATION) + countShaders(ShaderType::GEOMETRY) + countShaders(ShaderType::FRAGMENT))); // Aloc progam descriptors m_pplines.resize(m_passesCount * m_lodsCount * tessCount); m_hash = 0; for(ShaderType shader = ShaderType::VERTEX; shader <= ShaderType::FRAGMENT; ++shader) { Bool isTessellationShader = shader == ShaderType::TESSELLATION_CONTROL || shader == ShaderType::TESSELLATION_EVALUATION; if(!m_tessellation && isTessellationShader) { // Skip tessellation if not enabled continue; } if(shader == ShaderType::GEOMETRY) { // Skip geometry for now continue; } for(U level = 0; level < m_lodsCount; ++level) { if(level > 0 && isTessellationShader) { continue; } for(U pid = 0; pid < m_passesCount; ++pid) { for(U tess = 0; tess < tessCount; ++tess) { if(tess == 0 && isTessellationShader) { continue; } if(tess > 0 && shader == ShaderType::FRAGMENT) { continue; } TempResourceString src; TempResourceString::ScopeDestroyer srcd( &src, rinit.m_tempAlloc); ANKI_CHECK(src.sprintf( rinit.m_tempAlloc, "%s\n" "#define LOD %u\n" "#define PASS %u\n" "#define TESSELLATION %u\n" "%s\n", &rinit.m_resources._getShadersPrependedSource()[0], level, pid, tess, &loader.getProgramSource(shader)[0])); TempResourceString filename; TempResourceString::ScopeDestroyer filenamed( &filename, rinit.m_tempAlloc); ANKI_CHECK(createProgramSourceToCache(src, filename)); RenderingKey key((Pass)pid, level, tess); ProgramResourcePointer& progr = getProgram(key, shader); ANKI_CHECK( progr.load(filename.toCString(), &rinit.m_resources)); // Update the hash m_hash ^= computeHash(&src[0], src.getLength()); } } } } ANKI_CHECK(populateVariables(loader)); // Get uniform block size ANKI_ASSERT(m_progs.getSize() > 0); m_shaderBlockSize = loader.getUniformBlockSize(); return err; }
//============================================================================== Error ParticleEmitterResource::load(const CString& filename) { U32 tmp; XmlDocument doc; ANKI_CHECK(doc.loadFile(filename, getTempAllocator())); XmlElement rel; // Root element ANKI_CHECK(doc.getChildElement("particleEmitter", rel)); // XML load // ANKI_CHECK(xmlF32(rel, "life", m_particle.m_life)); ANKI_CHECK(xmlF32(rel, "lifeDeviation", m_particle.m_lifeDeviation)); ANKI_CHECK(xmlF32(rel, "mass", m_particle.m_mass)); ANKI_CHECK(xmlF32(rel, "massDeviation", m_particle.m_massDeviation)); ANKI_CHECK(xmlF32(rel, "size", m_particle.m_size)); ANKI_CHECK(xmlF32(rel, "sizeDeviation", m_particle.m_sizeDeviation)); ANKI_CHECK(xmlF32(rel, "sizeAnimation", m_particle.m_sizeAnimation)); ANKI_CHECK(xmlF32(rel, "alpha", m_particle.m_alpha)); ANKI_CHECK(xmlF32(rel, "alphaDeviation", m_particle.m_alphaDeviation)); tmp = m_particle.m_alphaAnimation; ANKI_CHECK(xmlU32(rel, "alphaAnimationEnabled", tmp)); m_particle.m_alphaAnimation = tmp; ANKI_CHECK(xmlVec3(rel, "forceDirection", m_particle.m_forceDirection)); ANKI_CHECK(xmlVec3(rel, "forceDirectionDeviation", m_particle.m_forceDirectionDeviation)); ANKI_CHECK(xmlF32(rel, "forceMagnitude", m_particle.m_forceMagnitude)); ANKI_CHECK(xmlF32(rel, "forceMagnitudeDeviation", m_particle.m_forceMagnitudeDeviation)); ANKI_CHECK(xmlVec3(rel, "gravity", m_particle.m_gravity)); ANKI_CHECK(xmlVec3(rel, "gravityDeviation", m_particle.m_gravityDeviation)); ANKI_CHECK(xmlVec3(rel, "startingPosition", m_particle.m_startingPos)); ANKI_CHECK(xmlVec3(rel, "startingPositionDeviation", m_particle.m_startingPosDeviation)); ANKI_CHECK(xmlU32(rel, "maxNumberOfParticles", m_maxNumOfParticles)); ANKI_CHECK(xmlF32(rel, "emissionPeriod", m_emissionPeriod)); ANKI_CHECK(xmlU32(rel, "particlesPerEmittion", m_particlesPerEmittion)); tmp = m_usePhysicsEngine; ANKI_CHECK(xmlU32(rel, "usePhysicsEngine", tmp)); m_usePhysicsEngine = tmp; XmlElement el; CString cstr; ANKI_CHECK(rel.getChildElement("material", el)); ANKI_CHECK(el.getText(cstr)); ANKI_CHECK(m_material.load(cstr, &getManager())); // sanity checks // static const char* ERROR = "Particle emmiter: " "Incorrect or missing value %s"; if(m_particle.m_life <= 0.0) { ANKI_LOGE(ERROR, "life"); return ErrorCode::USER_DATA; } if(m_particle.m_life - m_particle.m_lifeDeviation <= 0.0) { ANKI_LOGE(ERROR, "lifeDeviation"); return ErrorCode::USER_DATA; } if(m_particle.m_size <= 0.0) { ANKI_LOGE(ERROR, "size"); return ErrorCode::USER_DATA; } if(m_maxNumOfParticles < 1) { ANKI_LOGE(ERROR, "maxNumOfParticles"); return ErrorCode::USER_DATA; } if(m_emissionPeriod <= 0.0) { ANKI_LOGE(ERROR, "emissionPeriod"); return ErrorCode::USER_DATA; } if(m_particlesPerEmittion < 1) { ANKI_LOGE(ERROR, "particlesPerEmission"); return ErrorCode::USER_DATA; } // Calc some stuff // updateFlags(); return ErrorCode::NONE; }
//============================================================================== void MaterialProgramCreator::parseOperationTag( const XmlElement& operationTag, GLenum glshader, GLbitfield glshaderbit, MPString& out) { static const char OUT[] = {"out"}; // <id></id> I id = operationTag.getChildElement("id").getInt(); // <returnType></returnType> XmlElement retTypeEl = operationTag.getChildElement("returnType"); MPString retType(retTypeEl.getText(), m_alloc); MPString operationOut(m_alloc); if(retType != "void") { MPString tmp(MPString::toString(id, m_alloc)); operationOut = ANKI_STRL(OUT) + tmp; } // <function>functionName</function> MPString funcName( operationTag.getChildElement("function").getText(), m_alloc); // <arguments></arguments> XmlElement argsEl = operationTag.getChildElementOptional("arguments"); MPStringList argsList(m_alloc); if(argsEl) { // Get all arguments XmlElement argEl = argsEl.getChildElement("argument"); do { MPString arg(argEl.getText(), m_alloc); // Search for all the inputs and mark the appropriate Input* input = nullptr; for(Input& in : m_inputs) { // Check that the first part of the string is equal to the // variable and the following char is '[' if(in.m_name == arg) { input = ∈ in.m_shaderReferencedMask = glshaderbit; break; } } // The argument should be an input variable or an outXX if(!(input != nullptr || std::strncmp(&arg[0], OUT, sizeof(OUT) - 1) == 0)) { throw ANKI_EXCEPTION("Incorrect argument: %s", &arg[0]); } // Add to a list and do something special if instanced if(input && input->m_instanced) { if(glshader == GL_VERTEX_SHADER) { argsList.push_back(ANKI_STRL(argEl.getText()) + "[gl_InstanceID]"); m_instanceIdMask |= glshaderbit; } else if(glshader == GL_TESS_CONTROL_SHADER) { argsList.push_back(ANKI_STRL(argEl.getText()) + "[vInstanceId[0]]"); m_instanceIdMask |= glshaderbit; } else if(glshader == GL_TESS_EVALUATION_SHADER) { argsList.push_back(ANKI_STRL(argEl.getText()) + "[commonPatch.instanceId]"); m_instanceIdMask |= glshaderbit; } else if(glshader == GL_FRAGMENT_SHADER) { argsList.push_back(ANKI_STRL(argEl.getText()) + "[vInstanceId]"); m_instanceIdMask |= glshaderbit; } else { throw ANKI_EXCEPTION( "Cannot access the instance ID in all shaders"); } } else { argsList.push_back(MPString(argEl.getText(), m_alloc)); } // Advance argEl = argEl.getNextSiblingElement("argument"); } while(argEl); } // Now write everything MPString lines(m_alloc); lines.reserve(256); lines += "#if defined(" + funcName + "_DEFINED)"; // Write the defines for the operationOuts for(const MPString& arg : argsList) { if(arg.find(OUT) == 0) { lines += " && defined(" + arg + "_DEFINED)"; } } lines += "\n"; if(retType != "void") { lines += "#\tdefine " + operationOut + "_DEFINED\n\t" + retTypeEl.getText() + " " + operationOut + " = "; } else { lines += "\t"; } // write the blah = func(args...) lines += funcName + "("; lines += argsList.join(", "); lines += ");\n"; lines += "#endif"; // Done out = std::move(lines); }
//============================================================================== void MaterialProgramCreator::parseInputsTag(const XmlElement& programEl) { XmlElement inputsEl = programEl.getChildElementOptional("inputs"); if(!inputsEl) { return; } // Get shader type GLbitfield glshaderbit; GLenum glshader; U shaderidx; getShaderInfo( programEl.getChildElement("type").getText(), glshader, glshaderbit, shaderidx); XmlElement inputEl = inputsEl.getChildElement("input"); do { Input inpvar(m_alloc); // <name> inpvar.m_name = inputEl.getChildElement("name").getText(); // <type> inpvar.m_type = inputEl.getChildElement("type").getText(); // <value> XmlElement valueEl = inputEl.getChildElement("value"); if(valueEl.getText()) { inpvar.m_value = MPStringList::splitString( valueEl.getText(), ' ', m_alloc); } // <const> XmlElement constEl = inputEl.getChildElementOptional("const"); inpvar.m_constant = (constEl) ? constEl.getInt() : false; // <arraySize> XmlElement arrSizeEl = inputEl.getChildElementOptional("arraySize"); inpvar.m_arraySize = (arrSizeEl) ? arrSizeEl.getInt() : 0; // <instanced> if(inpvar.m_arraySize == 0) { XmlElement instancedEl = inputEl.getChildElementOptional("instanced"); inpvar.m_instanced = (instancedEl) ? instancedEl.getInt() : 0; // If one input var is instanced notify the whole program that // it's instanced if(inpvar.m_instanced) { m_instanced = true; } } // Now you have the info to check if duplicate Input* duplicateInp = nullptr; for(Input& in : m_inputs) { if(in.m_name == inpvar.m_name) { duplicateInp = ∈ break; } } if(duplicateInp != nullptr) { // Duplicate. Make sure it's the same as the other shader Bool same = duplicateInp->m_type == inpvar.m_type || duplicateInp->m_value == inpvar.m_value || duplicateInp->m_constant == inpvar.m_constant || duplicateInp->m_arraySize == inpvar.m_arraySize || duplicateInp->m_instanced == inpvar.m_instanced; if(!same) { throw ANKI_EXCEPTION("Variable defined differently between " "shaders: %s", &inpvar.m_name[0]); } duplicateInp->m_shaderDefinedMask |= glshaderbit; goto advance; } if(inpvar.m_constant == false) { // Handle NON-consts inpvar.m_line = inpvar.m_type + " " + inpvar.m_name; if(inpvar.m_arraySize > 1) { MPString tmp(MPString::toString(inpvar.m_arraySize, m_alloc)); inpvar.m_line += "[" + tmp + "U]"; } if(inpvar.m_instanced) { MPString tmp( MPString::toString(ANKI_GL_MAX_INSTANCES, m_alloc)); inpvar.m_line += "[" + tmp + "U]"; } inpvar.m_line += ";"; // Can put it block if(inpvar.m_type == "sampler2D" || inpvar.m_type == "samplerCube") { MPString tmp( MPString::toString(m_texBinding++, m_alloc)); inpvar.m_line = ANKI_STRL("layout(binding = ") + tmp + ") uniform " + inpvar.m_line; inpvar.m_inBlock = false; } else { inpvar.m_inBlock = true; m_uniformBlock.push_back(inpvar.m_line); m_uniformBlockReferencedMask |= glshaderbit; } } else { // Handle consts if(inpvar.m_value.size() == 0) { throw ANKI_EXCEPTION("Empty value and const is illogical"); } if(inpvar.m_arraySize > 0) { throw ANKI_EXCEPTION("Const arrays currently cannot " "be handled"); } inpvar.m_inBlock = false; inpvar.m_line = ANKI_STRL("const ") + inpvar.m_type + " " + inpvar.m_name + " = " + inpvar.m_type + "(" + inpvar.m_value.join(", ") + ");"; } inpvar.m_shaderDefinedMask = glshaderbit; m_inputs.push_back(inpvar); advance: // Advance inputEl = inputEl.getNextSiblingElement("input"); } while(inputEl); }
//============================================================================== void MaterialProgramCreator::parseProgramTag( const XmlElement& programEl) { // <type> CString type = programEl.getChildElement("type"_cstr).getText(); GLbitfield glshaderbit; GLenum glshader; U shaderidx; getShaderInfo(type, glshader, glshaderbit, shaderidx); m_source[shaderidx] = MPStringList(m_alloc); auto& lines = m_source[shaderidx]; lines.push_back(ANKI_STRL("#pragma anki type "_cstr) + type); if(glshader == GL_TESS_CONTROL_SHADER || glshader == GL_TESS_EVALUATION_SHADER) { m_tessellation = true; } // <includes></includes> XmlElement includesEl = programEl.getChildElement("includes"_cstr); XmlElement includeEl = includesEl.getChildElement("include"_cstr); do { MPString fname(includeEl.getText(), m_alloc); lines.push_back( ANKI_STRL("#pragma anki include \""_cstr) + fname + "\""_cstr); includeEl = includeEl.getNextSiblingElement("include"_cstr); } while(includeEl); // Inputs // Block if(m_uniformBlock.size() > 0 && (m_uniformBlockReferencedMask | glshaderbit)) { // TODO Make block SSB when driver bug is fixed lines.push_back(ANKI_STRL( "\nlayout(binding = 0, std140) uniform bDefaultBlock\n{"_cstr)); lines.insert( lines.end(), m_uniformBlock.begin(), m_uniformBlock.end()); lines.push_back(ANKI_STRL("};")); } // Other variables for(Input& in : m_inputs) { if(!in.m_inBlock && (in.m_shaderDefinedMask | glshaderbit)) { lines.push_back(in.m_line); } } // <operations></operations> lines.push_back(ANKI_STRL("\nvoid main()\n{")); XmlElement opsEl = programEl.getChildElement("operations"); XmlElement opEl = opsEl.getChildElement("operation"); do { MPString out(m_alloc); parseOperationTag(opEl, glshader, glshaderbit, out); lines.push_back(out); // Advance opEl = opEl.getNextSiblingElement("operation"); } while(opEl); lines.push_back(ANKI_STRL("}\n")); }
//============================================================================== Error Animation::load(const ResourceFilename& filename) { XmlElement el; I64 tmp; F64 ftmp; m_startTime = MAX_F32; F32 maxTime = MIN_F32; // Document XmlDocument doc; ANKI_CHECK(openFileParseXml(filename, doc)); XmlElement rootel; ANKI_CHECK(doc.getChildElement("animation", rootel)); // Count the number of identity keys. If all of the keys are identities // drop a vector U identPosCount = 0; U identRotCount = 0; U identScaleCount = 0; // <repeat> XmlElement repel; ANKI_CHECK(rootel.getChildElementOptional("repeat", repel)); if(repel) { ANKI_CHECK(repel.getI64(tmp)); m_repeat = tmp; } else { m_repeat = false; } // <channels> XmlElement channelsEl; ANKI_CHECK(rootel.getChildElement("channels", channelsEl)); XmlElement chEl; ANKI_CHECK(channelsEl.getChildElement("channel", chEl)); U32 channelCount = 0; ANKI_CHECK(chEl.getSiblingElementsCount(channelCount)); if(channelCount == 0) { ANKI_LOGE("Didn't found any channels"); return ErrorCode::USER_DATA; } m_channels.create(getAllocator(), channelCount); // For all channels channelCount = 0; do { AnimationChannel& ch = m_channels[channelCount]; // <name> ANKI_CHECK(chEl.getChildElement("name", el)); CString strtmp; ANKI_CHECK(el.getText(strtmp)); ch.m_name.create(getAllocator(), strtmp); XmlElement keysEl, keyEl; // <positionKeys> ANKI_CHECK(chEl.getChildElementOptional("positionKeys", keysEl)); if(keysEl) { ANKI_CHECK(keysEl.getChildElement("key", keyEl)); U32 count = 0; ANKI_CHECK(keyEl.getSiblingElementsCount(count)); ch.m_positions.create(getAllocator(), count); count = 0; do { Key<Vec3>& key = ch.m_positions[count++]; // <time> ANKI_CHECK(keyEl.getChildElement("time", el)); ANKI_CHECK(el.getF64(ftmp)); key.m_time = ftmp; m_startTime = std::min(m_startTime, key.m_time); maxTime = std::max(maxTime, key.m_time); // <value> ANKI_CHECK(keyEl.getChildElement("value", el)); ANKI_CHECK(el.getVec3(key.m_value)); // Check ident if(key.m_value == Vec3(0.0)) { ++identPosCount; } // Move to next ANKI_CHECK(keyEl.getNextSiblingElement("key", keyEl)); } while(keyEl); } // <rotationKeys> ANKI_CHECK(chEl.getChildElement("rotationKeys", keysEl)); if(keysEl) { ANKI_CHECK(keysEl.getChildElement("key", keyEl)); U32 count = 0; ANKI_CHECK(keysEl.getSiblingElementsCount(count)); ch.m_rotations.create(getAllocator(), count); count = 0; do { Key<Quat>& key = ch.m_rotations[count++]; // <time> ANKI_CHECK(keyEl.getChildElement("time", el)); ANKI_CHECK(el.getF64(ftmp)); key.m_time = ftmp; m_startTime = std::min(m_startTime, key.m_time); maxTime = std::max(maxTime, key.m_time); // <value> Vec4 tmp2; ANKI_CHECK(keyEl.getChildElement("value", el)); ANKI_CHECK(el.getVec4(tmp2)); key.m_value = Quat(tmp2); // Check ident if(key.m_value == Quat::getIdentity()) { ++identRotCount; } // Move to next ANKI_CHECK(keyEl.getNextSiblingElement("key", keyEl)); } while(keyEl); } // <scalingKeys> ANKI_CHECK(chEl.getChildElementOptional("scalingKeys", keysEl)); if(keysEl) { ANKI_CHECK(keysEl.getChildElement("key", keyEl)); U32 count = 0; ANKI_CHECK(keyEl.getSiblingElementsCount(count)); ch.m_scales.create(getAllocator(), count); count = 0; do { Key<F32>& key = ch.m_scales[count++]; // <time> ANKI_CHECK(keyEl.getChildElement("time", el)); ANKI_CHECK(el.getF64(ftmp)); key.m_time = ftmp; m_startTime = std::min(m_startTime, key.m_time); maxTime = std::max(maxTime, key.m_time); // <value> ANKI_CHECK(keyEl.getChildElement("value", el)); ANKI_CHECK(el.getF64(ftmp)); key.m_value = ftmp; // Check ident if(isZero(key.m_value - 1.0)) { ++identScaleCount; } // Move to next ANKI_CHECK(keyEl.getNextSiblingElement("key", keyEl)); } while(keyEl); } // Remove identity vectors if(identPosCount == ch.m_positions.getSize()) { ch.m_positions.destroy(getAllocator()); } if(identRotCount == ch.m_rotations.getSize()) { ch.m_rotations.destroy(getAllocator()); } if(identScaleCount == ch.m_scales.getSize()) { ch.m_scales.destroy(getAllocator()); } // Move to next channel ++channelCount; ANKI_CHECK(chEl.getNextSiblingElement("channel", chEl)); } while(chEl); m_duration = maxTime - m_startTime; return ErrorCode::NONE; }
void toXml (XmlElement & node) { node.addChildElement (new XmlElement ("Media")); node.getChildElement (node.getNumChildElements()-1)->setAttribute ("path", filePath); node.getChildElement (node.getNumChildElements()-1)->setAttribute ("duration", duration); }
//============================================================================== void Material::parseMaterialTag(const XmlElement& materialEl, ResourceInitializer& rinit) { // levelsOfDetail // XmlElement lodEl = materialEl.getChildElementOptional("levelsOfDetail"); if(lodEl) { I tmp = lodEl.getInt(); m_lodsCount = (tmp < 1) ? 1 : tmp; } else { m_lodsCount = 1; } // shadow // XmlElement shadowEl = materialEl.getChildElementOptional("shadow"); if(shadowEl) { m_shadow = shadowEl.getInt(); } // blendFunctions // XmlElement blendFunctionsEl = materialEl.getChildElementOptional("blendFunctions"); if(blendFunctionsEl) { // sFactor m_blendingSfactor = blendToEnum( blendFunctionsEl.getChildElement("sFactor").getText()); // dFactor m_blendingDfactor = blendToEnum( blendFunctionsEl.getChildElement("dFactor").getText()); } else { m_passesCount = 2; } // depthTesting // XmlElement depthTestingEl = materialEl.getChildElementOptional("depthTesting"); if(depthTestingEl) { m_depthTesting = depthTestingEl.getInt(); } // wireframe // XmlElement wireframeEl = materialEl.getChildElementOptional("wireframe"); if(wireframeEl) { m_wireframe = wireframeEl.getInt(); } // shaderProgram // MaterialProgramCreator mspc( materialEl.getChildElement("programs"), rinit.m_tempAlloc); m_tessellation = mspc.hasTessellation(); U tessCount = m_tessellation ? 2 : 1; // Alloc program vector U progCount = 0; progCount += m_passesCount * m_lodsCount * tessCount; if(m_tessellation) { progCount += m_passesCount * m_lodsCount * 2; } progCount += m_passesCount * m_lodsCount; m_progs.resize(progCount); // Aloc progam descriptors m_pplines.resize(m_passesCount * m_lodsCount * tessCount); m_hash = 0; for(U shader = 0; shader < 5; shader++) { if(!m_tessellation && (shader == 1 || shader == 2)) { continue; } if(shader == 3) { continue; } for(U level = 0; level < m_lodsCount; ++level) { for(U pid = 0; pid < m_passesCount; ++pid) { for(U tess = 0; tess < tessCount; ++tess) { TempResourceString src(rinit.m_tempAlloc); src.sprintf("#define LOD %u\n" "#define PASS %u\n" "#define TESSELLATION %u\n", level, pid, tess); TempResourceString filename = createProgramSourceToChache(src); RenderingKey key((Pass)pid, level, tess); ProgramResourcePointer& progr = getProgram(key, shader); progr.load(filename.toCString(), &rinit.m_resources); // Update the hash m_hash ^= computeHash(&src[0], src.getLength()); } } } } populateVariables(mspc); // Get uniform block size ANKI_ASSERT(m_progs.size() > 0); m_shaderBlockSize = m_progs[0]->getGlProgram().findBlock("bDefaultBlock").getSize(); }