⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rubysceneimporter.cpp

📁 rcssserver3d Robocup 3D比赛官方指定平台
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/* -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil -*-   this file is part of rcssserver3D   Fri May 9 2003   Copyright (C) 2002,2003 Koblenz University   Copyright (C) 2003 RoboCup Soccer Server 3D Maintenance Group   $Id: rubysceneimporter.cpp,v 1.27 2008/05/12 09:39:14 rollmark Exp $   This program is free software; you can redistribute it and/or modify   it under the terms of the GNU General Public License as published by   the Free Software Foundation; version 2 of the License.   This program is distributed in the hope that it will be useful,   but WITHOUT ANY WARRANTY; without even the implied warranty of   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the   GNU General Public License for more details.   You should have received a copy of the GNU General Public License   along with this program; if not, write to the Free Software   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.*/#include "rubysceneimporter.h"#include <zeitgeist/logserver/logserver.h>#include <zeitgeist/fileserver/fileserver.h>#include <zeitgeist/scriptserver/scriptserver.h>#include <oxygen/sceneserver/transform.h>#include <oxygen/sceneserver/scenedict.h>#include <boost/scoped_array.hpp>#include <sstream>using namespace zeitgeist;using namespace oxygen;using namespace boost;using namespace std;/**    (RubySceneGraph <version major> <version minor>)    (    (template varName1 varName2 ...)    (define varName value)    (node <NodeName>        method param param ...        method param ...        (node <NodeName>            method param param ...            method param ...            )            (node <NodeName>            method param param ...            method param ...            )        method param param ...        method param ...        )*/#define S_NODE     "node"#define S_SELECT   "select"#define S_PWD      "pwd"#define S_TEMPLATE "template"#define S_DEFINE   "define"#define S_ATTACH   "attach"#define S_SWITCH   "switch"#define S_DELTASCENE "RubyDeltaScene"#define S_SCENEGRAPH "RubySceneGraph"#define S_SETLOCALTRANSFORM "setLocalTransform"#define S_SETSCALE "setScale"#define S_SETMATERIAL "setMaterial"#define S_BASENODE "BaseNode"#define S_SINGLEMATNODE "SingleMatNode"#define S_TRANSFORM "Transform";#define S_FROMSTRING "<from string>"RubySceneImporter::RubySceneImporter() : SceneImporter(){    mVersionMajor = 0;    mVersionMinor = 0;    mDeltaScene = false;    mAutoUnlink = false;    mUpdateSceneDict = false;    InitTranslationTable();}RubySceneImporter::~RubySceneImporter(){}void RubySceneImporter::SetUnlinkOnCompleteScenes(bool unlink){    mAutoUnlink = unlink;}voidRubySceneImporter::InitTranslationTable(){    mTranslationTable.clear();    mTranslationTable["nd"]    = S_NODE;    mTranslationTable["sel"]   = S_SELECT;    mTranslationTable["pwd"]   = S_PWD;    mTranslationTable["templ"] = S_TEMPLATE;    mTranslationTable["def"]   = S_DEFINE;    mTranslationTable["att"]   = S_ATTACH;    mTranslationTable["RDS"]   = S_DELTASCENE;    mTranslationTable["RSG"]   = S_SCENEGRAPH;    mTranslationTable["SLT"]   = S_SETLOCALTRANSFORM;    mTranslationTable["sSc"]   = S_SETSCALE;    mTranslationTable["sMat"]  = S_SETMATERIAL;    mTranslationTable["BN"]    = S_BASENODE;    mTranslationTable["SMN"]   = S_SINGLEMATNODE;    mTranslationTable["TRF"]   = S_TRANSFORM;}string RubySceneImporter::Lookup(const std::string& key){    return ((mTranslationTable.find(key) != mTranslationTable.end()) ?            mTranslationTable[key] : key);//     if (mTranslationTable.find(key) != mTranslationTable.end())//     {//         return mTranslationTable[key];//     } else {//         GetLog()->Debug() << "DEBUG: " << key << " not in TranslationTable\n";//         return key;//     }}voidRubySceneImporter::EnableSceneDictionary(bool enable){    mUpdateSceneDict = enable;}bool RubySceneImporter::ImportScene(const std::string& fileName,                                    shared_ptr<BaseNode> root,                                    shared_ptr<ParameterList> parameter){    // try to open the file    shared_ptr<salt::RFile> file = GetFile()->OpenResource(fileName);    if (file.get() == 0)        {            GetLog()->Error() << "(RubySceneImporter) ERROR: cannot open file '"                              << fileName << "'\n";            return false;        }    std::string oldFileName = mFileName;    mFileName = fileName;    // read entire file into a temporary buffer    scoped_array<char> buffer(new char[file->Size() + 1]);    file->Read(buffer.get(), file->Size());    buffer[file->Size()] = 0;    bool ok = ParseScene(buffer.get(), file->Size(), root, parameter);    mFileName = oldFileName;    return ok;}bool RubySceneImporter::ParseScene(const std::string& scene,                                   shared_ptr<BaseNode> root,                                   shared_ptr<ParameterList> parameter){    mFileName = S_FROMSTRING;    return ParseScene(scene.c_str(),static_cast<int>(scene.size()),root,parameter);}bool RubySceneImporter::ParseScene(const char* scene, int size,                                   boost::shared_ptr<oxygen::BaseNode> root,                                   boost::shared_ptr<zeitgeist::ParameterList> parameter){    // parse s-expressions    pcont_t* pcont = init_continuation(const_cast<char*>(scene));    sexp_t* sexp = iparse_sexp(const_cast<char*>(scene),size,pcont);    // read scene magic and version    if (        (sexp == 0) ||        (! ReadHeader(sexp)) ||        (mVersionMajor != 0) ||        (mVersionMinor != 1)        )        {            destroy_sexp(sexp);            destroy_continuation(pcont);            return false;        }    // advance to next sexpression- the scene graph    PushParameter(parameter);    destroy_sexp(sexp);    sexp = iparse_sexp(const_cast<char*>(scene),size,pcont);    if (sexp == 0)    {        GetLog()->Error()            << "(RubySceneImporter) ERROR: failed to parse S-Expressions. "            << "Last read line was " << pcont->line << "\n";        root->UnlinkChildren();        return false;    }    if (        (! mDeltaScene) &&        (mAutoUnlink)        )        {            root->UnlinkChildren();        }    bool ok = mDeltaScene ?        ReadDeltaGraph(sexp,root) :        ReadGraph(sexp,root);    destroy_sexp(sexp);    destroy_continuation(pcont);    InvokeMethods();    PopParameter();    return ok;}void RubySceneImporter::PushParameter(shared_ptr<ParameterList> parameter){    mParameterStack.push_back(ParamEnv(parameter));}void RubySceneImporter::PopParameter(){    if (mParameterStack.empty())        {            GetLog()->Debug()                << "(RubySceneImporter) ERROR: PopParameter "                << "called on empty stack\n";            return;        }    mParameterStack.pop_back();}RubySceneImporter::ParamEnv& RubySceneImporter::GetParamEnv(){    if (mParameterStack.empty())        {            GetLog()->Debug()                << "(RubySceneImporter) ERROR: GetParamEnv "                << "called on empty stack\n";            static ParamEnv nullEnv;            return nullEnv;        }    return mParameterStack.back();}bool RubySceneImporter::ReadHeader(sexp_t* sexp){    // (RubySceneGraph <int majorVersion> <int minorVersion>)    if (        (sexp == 0) ||        (sexp->ty != SEXP_LIST) ||        (sexp->list == 0)        )        {            return false;        }    sexp = sexp->list;    if (sexp->ty != SEXP_VALUE)        {            return false;        }    string val = Lookup(string(sexp->val));    mDeltaScene = false;    if (val == S_DELTASCENE)        {            mDeltaScene = true;        }  else if (val != S_SCENEGRAPH)            {                return false;            }    // try to advance to version number    sexp = sexp->next;    if (        (sexp == 0) ||        (sexp->ty != SEXP_VALUE)        )        {            return false;        }    string mastr(sexp->val);    int major = atoi(mastr.c_str());    if (major < 0)        {            return false;        }    sexp = sexp->next;    if (        (sexp == 0) ||        (sexp->ty != SEXP_VALUE)        )        {            return false;        }    string mistr(sexp->val);    int minor = atoi(mistr.c_str());    if (minor < 0)        {            return false;        }    mVersionMajor = major;    mVersionMinor = minor;    return true;}shared_ptr<Object> RubySceneImporter::CreateInstance(const string& className){    static const string prefixes[] =        {            "",            "oxygen/",            "kerosin/"        };    const int n = sizeof(prefixes)/sizeof(string);    for (int i=0;i<n;++i)        {            string name = prefixes[i] + className;            if (GetCore()->ExistsClass(name))                {                    return GetCore()->New(name);                }        }    return shared_ptr<Object>();}shared_ptr<BaseNode>RubySceneImporter::CreateNode(sexp_t* sexp){    if (sexp == 0)    {        return shared_ptr<BaseNode>();    }    string className(Lookup(sexp->val));    // create a class instance    shared_ptr<Object> obj = CreateInstance(className);    if (obj.get() == 0)    {        GetLog()->Error()            << "(RubySceneImporter) ERROR: in file '" << mFileName            << "': unknown class '"            << className << "'\n";        return shared_ptr<BaseNode>();    }    shared_ptr<BaseNode> node = shared_dynamic_cast<BaseNode>(obj);    if (node.get() == 0)    {        GetLog()->Error()            << "(RubySceneImporter) ERROR: in file '" << mFileName            << className << "': is not derived from BaseNode'\n";        return shared_ptr<BaseNode>();    }    if (        (mUpdateSceneDict) &&        (mSceneDict != 0)        )    {        mSceneDict->Insert            (node, SceneDict::FileRef(mFileName,sexp->line));    }    return node;}bool RubySceneImporter::ReplaceVariable(string& param){    // replace a template parameter    const ParamEnv& env = GetParamEnv();    param.erase(param.begin(),param.begin()+1);    TParameterMap::const_iterator iter = env.parameterMap.find(param);    if (iter == env.parameterMap.end())        {            GetLog()->Error()                << "(RubySceneImporter) ERROR: in file '"                << mFileName                << "': unknown parameter '"                << param << "'\n";            return false;        }    int idx = (*iter).second;    if (        (idx < 0) ||        (idx >= env.parameter->GetSize())        )        {            GetLog()->Error()                << "(RubySceneImporter) ERROR: in file '"                << mFileName                << "': parameter value '"                << param << "' not supplied\n";            return false;        }    string value;    ParameterList::TVector::const_iterator pIter = (*env.parameter)[idx];    if (! env.parameter->AdvanceValue(pIter,value))        {            GetLog()->Error()                << "(RubySceneImporter) ERROR: in file '"                << mFileName                << "': failed to read parameter value '"                << param << "'\n";            return false;        }    param = value;    return true;}bool RubySceneImporter::EvalParameter(sexp_t* sexp, string& value){    const boost::shared_ptr<ScriptServer>&  script = GetScript();    if (script.get() == 0)        {            GetLog()->Error()                << "(RubySceneImporter) ERROR: in file '"                << mFileName                << "': cannot get ScriptServer to eval expression\n";            return false;        }    if (sexp->ty != SEXP_VALUE)        {            return false;        }    string pred = Lookup(sexp->val);    //Simply For String Link By Feng Xue    //Begin    {        if (pred == "join")        {            stringstream ss;            sexp = sexp->next;            while (sexp != 0)            {                string atom;                if (sexp->ty == SEXP_VALUE)                {                    atom = sexp->val; //todo: use TranslationTable here?                    if ((atom[0] == '$') &&                        (! ReplaceVariable(atom)))                    {                        return false;                    }                }                 else                {                    if (! EvalParameter(sexp->list, atom))                    {                        return false;                    }                }                ss << atom;                sexp = sexp->next;            }            value = ss.str();            return true;        }    }    //End    // if (pred == "switch")    // {    //     return ParseSwitch(sexp->next, value);    // }    if (pred != "eval")        {            GetLog()->Error()                << "(RubySceneImporter) ERROR: in file '"                << mFileName                << "': unknown expression type '" << pred << "' in parameter list\n";            return false;        }    string expr;    sexp = sexp->next;    while (sexp != 0)        {            string atom;            if (sexp->ty == SEXP_VALUE)                {                    atom = sexp->val; //todo: use TranslationTable here?                    if (                        (atom[0] == '$') &&                        (! ReplaceVariable(atom))                        )                        {                            return false;                        }                } else                {                    if (! EvalParameter(sexp->list, atom))                        {                            return false;                        }                }            expr = expr + atom;            expr = expr + " ";            sexp = sexp->next;        }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -