#include "SceneSerializer.h" #include "OgreIlluminationManager.h" void logParseError(const String& error, const SceneScriptContext& context) { LogManager::getSingleton().logMessage( "Error at line " + StringConverter::toString(context.lineNo) + " of " + context.filename + ": " + error); } bool parseMeshFileName(String& params, SceneScriptContext& context) { if(params == "") logParseError("Error reading mesh filename!", context); StringUtil::trim(params); context.meshFiles[context.meshName] = params; return false; } bool parseMeshName(String& params, SceneScriptContext& context) { if(params == "") logParseError("No mesh name given!", context); //create the Entity with the given mesh, attach to a scene node StringUtil::trim(params); String meshfilename = context.meshFiles[params]; context.meshName = params; context.entity = context.sceneManager->createEntity(context.entityName, meshfilename); SceneNode* root = context.sceneManager->getRootSceneNode(); context.sceneNode = root->createChildSceneNode(context.entityName); context.sceneNode->attachObject(context.entity); return false; } bool parseClusters(String& params, SceneScriptContext& context) { if(params == "") logParseError("No clusters given!", context); //create the Entity with the given mesh, attach to a scene node std::vector parameters = StringUtil::split(params); String subentityname = context.entityName + "_SE_" + parameters[0]; PathMapClusters clasters; clasters.count = parameters.size() - 2; clasters.clusters = new unsigned int[clasters.count]; for(int i = 2; i < parameters.size(); i++) clasters.clusters[i-2] = StringConverter::parseUnsignedInt(parameters.at(i)); clasters.pathMapTextureFilename = context.pathMapTextureName + "_" + parameters[0]+ ".hdr"; clasters.pathMapResolution = context.pathMapResolutions[context.meshName]; OgreIlluminationManager::getSingleton().addPathMapClusters(subentityname, clasters); return false; } bool parseTransform(String& params, SceneScriptContext& context) { Matrix4 transformMatrix = StringConverter::parseMatrix4(params); context.sceneNode->setOrientation(transformMatrix.extractQuaternion()); Vector4 x(1,0,0,0); x = transformMatrix * x; Vector4 y(0,1,0,0); y = transformMatrix * y; Vector4 z(0,0,1,0); z = transformMatrix * z; context.sceneNode->scale((Vector3(x.x,x.y,x.z)).length(), (Vector3(y.x,y.y,y.z)).length(), (Vector3(z.x,z.y,z.z)).length()); context.sceneNode->translate(transformMatrix.getTrans()); return false; } bool parseMesh(String& params, SceneScriptContext& context) { if(params == "") logParseError("No mesh name given!", context); StringUtil::trim(params); context.meshName = params; context.section = SSS_MESH; return true; } bool parseEntity(String& params, SceneScriptContext& context) { if(params == "") logParseError("No entity name given!", context); StringUtil::trim(params); context.entityName = params; context.section = SSS_ENTITY; return true; } bool parsePMRes(String& params, SceneScriptContext& context) { context.pathMapResolutions[context.meshName] = StringConverter::parseUnsignedInt(params); return false; } bool parsePRMMapName(String& params, SceneScriptContext& context) { context.pathMapTextureName = params; return false; } SceneSerializer::SceneSerializer(SceneManager* sm) { mScriptContext.sceneManager = sm; mScriptContext.section = SSS_NONE; mRootAttribParsers.insert(AttribParserList::value_type("mesh", (SCENE_ATTRIBUTE_PARSER)parseMesh)); mRootAttribParsers.insert(AttribParserList::value_type("entity", (SCENE_ATTRIBUTE_PARSER)parseEntity)); mMeshAttribParsers.insert(AttribParserList::value_type("ogrefile", (SCENE_ATTRIBUTE_PARSER)parseMeshFileName)); mMeshAttribParsers.insert(AttribParserList::value_type("pathmapresolution", (SCENE_ATTRIBUTE_PARSER)parsePMRes)); mEntityAttribParsers.insert(AttribParserList::value_type("mesh", (SCENE_ATTRIBUTE_PARSER)parseMeshName)); mEntityAttribParsers.insert(AttribParserList::value_type("transformation", (SCENE_ATTRIBUTE_PARSER)parseTransform)); mEntityAttribParsers.insert(AttribParserList::value_type("subentity", (SCENE_ATTRIBUTE_PARSER)parseClusters)); mEntityAttribParsers.insert(AttribParserList::value_type("pathmapfile", (SCENE_ATTRIBUTE_PARSER)parsePRMMapName)); } void SceneSerializer::parseEntryPoints(String filename) { DataStreamPtr stream; stream = ResourceGroupManager::getSingleton().openResource(filename); char buffer[500]; stream->readLine(buffer, 500); String line = buffer; std::vector tokens = StringUtil::split(line); unsigned int entryPointCnt = StringConverter::parseUnsignedInt(tokens[1]); for(int i= 0; i < entryPointCnt; i++) { stream->readLine(buffer, 500); line = buffer; tokens = StringUtil::split(line); PathMapEntryPoint ep; ep.position = Vector3(StringConverter::parseReal(tokens[1]), StringConverter::parseReal(tokens[2]), StringConverter::parseReal(tokens[3])); stream->readLine(buffer, 500); line = buffer; tokens = StringUtil::split(line); ep.normal = Vector3(StringConverter::parseReal(tokens[1]), StringConverter::parseReal(tokens[2]), StringConverter::parseReal(tokens[3])); OgreIlluminationManager::getSingleton().addPathMapEntryPoint(ep); stream->readLine(buffer, 500); } stream->readLine(buffer, 500); line = buffer; tokens = StringUtil::split(line); unsigned int clusterCnt = StringConverter::parseUnsignedInt(tokens[1]); for(int i= 0; i < clusterCnt; i++) { stream->readLine(buffer, 500); unsigned int clusterlength = StringConverter::parseUnsignedInt(buffer); OgreIlluminationManager::getSingleton().addPathMapClusterLength(clusterlength); } } void SceneSerializer::parseScript(DataStreamPtr& stream, const String& groupName) { //String line; bool nextIsOpenBrace = false; mScriptContext.section = SSS_NONE; mScriptContext.lineNo = 0; mScriptContext.filename = stream->getName(); char buffer[500]; //String summ = stream->getAsString(); while(!stream->eof()) { stream->readLine(buffer, 500); String line = buffer; StringUtil::trim(line,true, true); mScriptContext.lineNo++; // DEBUG LINE // LogManager::getSingleton().logMessage("About to attempt line(#" + // StringConverter::toString(mScriptContext.lineNo) + "): " + line); // Ignore comments & blanks if (!(line.length() == 0 || line.substr(0,2) == "//")) { if (nextIsOpenBrace) { // NB, parser will have changed context already if (line != "{") { logParseError("Expecting '{' but got " + line + " instead.", mScriptContext); } nextIsOpenBrace = false; } else { nextIsOpenBrace = parseScriptLine(line); } } } // Check all braces were closed if (mScriptContext.section != SSS_NONE) { logParseError("Unexpected end of file.", mScriptContext); } } bool SceneSerializer::parseScriptLine(String& line) { switch(mScriptContext.section) { case SSS_NONE: if (line == "}") { logParseError("Unexpected terminating brace.", mScriptContext); return false; } else { // find & invoke a parser return invokeParser(line, mRootAttribParsers); } break; case SSS_MESH: if (line == "}") { mScriptContext.section = SSS_NONE; mScriptContext.meshName = ""; return false; } else { // find & invoke a parser return invokeParser(line, mMeshAttribParsers); } break; case SSS_ENTITY: if (line == "}") { // End of technique mScriptContext.section = SSS_NONE; mScriptContext.entity = 0; mScriptContext.entityName = ""; mScriptContext.sceneNode = 0; return false; } else { // find & invoke a parser return invokeParser(line, mEntityAttribParsers); } break; } } bool SceneSerializer::invokeParser(String& line, AttribParserList& parsers) { // First, split line on first divisor only StringVector splitCmd(StringUtil::split(line, " \t", 1)); // Find attribute parser AttribParserList::iterator iparser = parsers.find(splitCmd[0]); if (iparser == parsers.end()) { // BAD command. BAD! logParseError("Unrecognised command: " + splitCmd[0], mScriptContext); return false; } else { String cmd; if(splitCmd.size() >= 2) cmd = splitCmd[1]; // Use parser, make sure we have 2 params before using splitCmd[1] return iparser->second( cmd, mScriptContext ); } }