source: GTP/trunk/App/Demos/Illum/Ogre/src/Common/src/SceneSerializer.cpp @ 2163

Revision 2163, 6.0 KB checked in by szirmay, 17 years ago (diff)
Line 
1#include "SceneSerializer.h"
2
3void logParseError(const String& error, const SceneScriptContext& context)
4{   
5        LogManager::getSingleton().logMessage(
6                    "Error at line " + StringConverter::toString(context.lineNo) +
7                    " of " + context.filename + ": " + error);       
8}
9
10bool parseMeshFileName(String& params, SceneScriptContext& context)
11{
12        if(params == "")
13                logParseError("Error reading mesh filename!", context);
14
15        StringUtil::trim(params);
16        context.meshFiles[context.meshName] = params;
17
18        return false;
19}
20
21bool parseMeshName(String& params, SceneScriptContext& context)
22{
23        if(params == "")
24                logParseError("No mesh name given!", context);
25
26        //create the Entity with the given mesh, attach to a scene node
27        StringUtil::trim(params);
28        String meshfilename = context.meshFiles[params];
29        context.entity = context.sceneManager->createEntity(context.entityName, meshfilename);
30        SceneNode* root = context.sceneManager->getRootSceneNode();
31        context.sceneNode = root->createChildSceneNode(context.entityName);
32        context.sceneNode->attachObject(context.entity);
33
34    return false;
35}
36
37bool parseTransform(String& params, SceneScriptContext& context)
38{
39        Matrix4 transformMatrix = StringConverter::parseMatrix4(params);
40        context.sceneNode->setOrientation(transformMatrix.extractQuaternion());
41       
42        Vector4 x(1,0,0,0);
43        x = transformMatrix * x;
44        Vector4 y(0,1,0,0);
45        y = transformMatrix * y;
46        Vector4 z(0,0,1,0);
47        z = transformMatrix * z;
48        context.sceneNode->scale((Vector3(x.x,x.y,x.z)).length(),
49                                                                (Vector3(y.x,y.y,y.z)).length(),
50                                                                (Vector3(z.x,z.y,z.z)).length());
51        context.sceneNode->translate(transformMatrix.getTrans());
52       
53        return false;
54}
55
56bool parseMesh(String& params, SceneScriptContext& context)
57{
58        if(params == "")
59                logParseError("No mesh name given!", context);
60       
61        StringUtil::trim(params);
62        context.meshName = params;
63        context.section = SSS_MESH;
64        return true;
65}
66
67bool parseEntity(String& params, SceneScriptContext& context)
68{
69        if(params == "")
70                logParseError("No entity name given!", context);
71       
72        StringUtil::trim(params);
73        context.entityName = params;
74        context.section = SSS_ENTITY;
75        return true;
76}
77
78SceneSerializer::SceneSerializer(SceneManager* sm)
79{
80        mScriptContext.sceneManager = sm;
81        mScriptContext.section = SSS_NONE;
82
83        mRootAttribParsers.insert(AttribParserList::value_type("mesh", (SCENE_ATTRIBUTE_PARSER)parseMesh));
84        mRootAttribParsers.insert(AttribParserList::value_type("entity", (SCENE_ATTRIBUTE_PARSER)parseEntity));
85       
86        mMeshAttribParsers.insert(AttribParserList::value_type("ogrefile", (SCENE_ATTRIBUTE_PARSER)parseMeshFileName));
87
88        mEntityAttribParsers.insert(AttribParserList::value_type("mesh", (SCENE_ATTRIBUTE_PARSER)parseMeshName));
89        mEntityAttribParsers.insert(AttribParserList::value_type("transformation", (SCENE_ATTRIBUTE_PARSER)parseTransform));
90
91}
92
93 void SceneSerializer::parseScript(DataStreamPtr& stream, const String& groupName)
94 {
95    //String line;
96    bool nextIsOpenBrace = false;
97
98    mScriptContext.section = SSS_NONE;       
99    mScriptContext.lineNo = 0;         
100    mScriptContext.filename = stream->getName();
101       
102        char buffer[500];
103        //String summ = stream->getAsString();
104
105    while(!stream->eof())
106    {
107
108                stream->readLine(buffer, 500);
109                               
110        String line = buffer;
111                StringUtil::trim(line,true, true);
112               
113        mScriptContext.lineNo++;
114       
115        // DEBUG LINE
116        // LogManager::getSingleton().logMessage("About to attempt line(#" +
117        //    StringConverter::toString(mScriptContext.lineNo) + "): " + line);
118
119        // Ignore comments & blanks
120        if (!(line.length() == 0 || line.substr(0,2) == "//"))
121        {
122            if (nextIsOpenBrace)
123            {
124                // NB, parser will have changed context already
125                if (line != "{")
126                {
127                    logParseError("Expecting '{' but got " +
128                        line + " instead.", mScriptContext);
129                }
130                nextIsOpenBrace = false;
131            }
132            else
133            {
134                nextIsOpenBrace = parseScriptLine(line);
135            }
136
137        }
138    }
139
140    // Check all braces were closed
141    if (mScriptContext.section != SSS_NONE)
142    {
143        logParseError("Unexpected end of file.", mScriptContext);
144    }   
145
146  }
147
148 bool SceneSerializer::parseScriptLine(String& line)
149{
150    switch(mScriptContext.section)
151    {
152                case SSS_NONE:
153                        if (line == "}")
154                        {
155                                logParseError("Unexpected terminating brace.", mScriptContext);
156                                return false;
157                        }
158                        else
159                        {
160                                // find & invoke a parser
161                                return invokeParser(line, mRootAttribParsers);
162                        }
163                        break;
164                case SSS_MESH:
165                        if (line == "}")
166                        {
167                                mScriptContext.section = SSS_NONE;
168                                mScriptContext.meshName = "";
169                                return false;
170                        }
171                        else
172                        {
173                                // find & invoke a parser
174                                return invokeParser(line, mMeshAttribParsers);
175                        }
176                        break;
177                case SSS_ENTITY:
178                        if (line == "}")
179                        {
180                                // End of technique
181                                mScriptContext.section = SSS_NONE;
182                                mScriptContext.entity = 0;
183                                mScriptContext.entityName = "";
184                                mScriptContext.sceneNode = 0;
185                                return false;
186                        }
187                        else
188                        {
189                                // find & invoke a parser
190                                return invokeParser(line, mEntityAttribParsers);
191                        }
192                        break;
193        }
194}
195
196bool SceneSerializer::invokeParser(String& line, AttribParserList& parsers)
197{
198    // First, split line on first divisor only
199    StringVector splitCmd(StringUtil::split(line, " \t", 1));
200
201    // Find attribute parser
202    AttribParserList::iterator iparser = parsers.find(splitCmd[0]);
203    if (iparser == parsers.end())
204    {
205        // BAD command. BAD!
206        logParseError("Unrecognised command: " + splitCmd[0], mScriptContext);
207        return false;
208    }
209    else
210    {
211        String cmd;
212        if(splitCmd.size() >= 2)
213            cmd = splitCmd[1];
214        // Use parser, make sure we have 2 params before using splitCmd[1]
215        return iparser->second( cmd, mScriptContext );
216    }
217}
Note: See TracBrowser for help on using the repository browser.