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; }
//============================================================================== static ANKI_USE_RESULT Error xmlF32( const XmlElement& el_, const CString& str, F32& out) { Error err = ErrorCode::NONE; XmlElement el; err = el_.getChildElementOptional(str, el); if(err || !el) { return err; } F64 tmp; err = el.getF64(tmp); if(!err) { out = tmp; } return err; }
//============================================================================== 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; }