MiltonJSONSceneLoader.h

Go to the documentation of this file.
00001 /**<!-------------------------------------------------------------------->
00002    @class  MiltonJSONSceneLoader
00003    @author Travis Fischer (fisch0920@gmail.com)
00004    @author Matthew Jacobs (jacobs.mh@gmail.com)
00005    @date   Fall 2008
00006    
00007    @brief
00008       Scene loader for Milton JSON scene format
00009    <!-------------------------------------------------------------------->**/
00010 
00011 #ifndef MILTON_JSON_SCENE_LOADER_H_
00012 #define MILTON_JSON_SCENE_LOADER_H_
00013 
00014 #include <loaders/SceneLoader.h>
00015 #include <loaders/SceneGraph.h>
00016 #include <dynamic/DynamicPlugin.h>
00017 
00018 #include <materials/Material.h>
00019 #include <shapes/ShapeSet.h>
00020 
00021 #include <third-party/tinyjson/tinyjson.hpp>
00022 #include <typeinfo>
00023 
00024 struct JSONParseData;
00025 struct JSONVisitor;
00026 class  MiltonJSONSceneLoader;
00027 class  KernelFilter;
00028 
00029 DECLARE_STL_TYPEDEF2(std::map<std::string, SceneNode*>,    InstancedNodeMap);
00030 
00031 DECLARE_STL_TYPEDEF2(std::map<std::string, std::string>, KeyValueIDMap);
00032 
00033 DECLARE_STL_TYPEDEF2(std::map<std::string, unsigned>, ParseResultsMap);
00034    
00035 DECLARE_STL_TYPEDEF(json::grammar<char>::array,        JSONArray);
00036 DECLARE_STL_TYPEDEF(json::grammar<char>::object,       JSONObject);
00037 DECLARE_STL_TYPEDEF(std::string,                       JSONString);
00038 typedef             json::grammar<char>::variant       JSONVariant;
00039 
00040 typedef bool (MiltonJSONSceneLoader::*ParseFunction) 
00041    (const JSONVariant &, JSONParseData &) const;
00042 
00043 struct JSONParseData : public ParseData {
00044    ShapeSet        *primitives;
00045    MaterialList     materials;
00046    
00047    Material        *activeMaterial;
00048    Material        *background;
00049    
00050    // temporary during parsing (stack of SceneNodes)
00051    SceneGraph       sceneGraph;
00052    
00053    InstancedNodeMap instancedNodes;
00054    unsigned         instance;
00055    
00056    JSONParseData(const ParseData &copy)
00057       : ParseData(copy), primitives(NULL), activeMaterial(NULL), 
00058         background(NULL), instance(0)
00059    { }
00060    
00061    /// clears the SceneGraph and frees its resources
00062    virtual void reset() {
00063       ParseData::reset();
00064       
00065       instancedNodes.clear();
00066       safeDelete(primitives);
00067       materials.clear();
00068       
00069       activeMaterial = NULL;
00070       background     = NULL;
00071       instance       = 0;
00072       
00073       sceneGraph.reset();
00074    }
00075 };
00076 
00077 struct JSONVisitorValue {
00078    ParseFunction function;
00079    bool          required;
00080    
00081    inline JSONVisitorValue(const ParseFunction &function_ = NULL, 
00082                            const bool required_ = false)
00083       : function(function_), required(required_)
00084    { }
00085 };
00086 
00087 /*struct JSONVisitorConstraint {
00088    const std::string &key;
00089    bool               required;
00090    
00091    inline JSONVisitorConstraint(const std::string &key_, 
00092                                 const bool required_ = false)
00093       : key(key_), required(required_)
00094    { }
00095 };*/
00096 
00097 struct JSONVisitor {
00098    DECLARE_STL_TYPEDEF2(std::map<std::string, JSONVisitorValue>, FunctionMap);
00099    
00100    FunctionMap functionMap;
00101    
00102    JSONVisitor(ParseFunction nullFunction, 
00103                ParseFunction boolFunction, 
00104                ParseFunction intFunction, 
00105                ParseFunction real_tFunction, 
00106                ParseFunction stringFunction, 
00107                ParseFunction arrayFunction, 
00108                ParseFunction objectFunction)
00109    {
00110 #define ADD_VARIANT(v, type) \
00111    if (v##Function)          \
00112       functionMap[std::string(typeid(type).name())] = JSONVisitorValue(v##Function, true);
00113       
00114       ADD_VARIANT(null,   void);
00115       ADD_VARIANT(bool,   bool);
00116       ADD_VARIANT(int,    int);
00117       ADD_VARIANT(real_t, real_t);
00118       ADD_VARIANT(string, JSONString);
00119       ADD_VARIANT(array,  JSONArray);
00120       ADD_VARIANT(object, JSONObject);
00121       
00122 #undef ADD_VARIANT
00123    }
00124    
00125    inline JSONVisitor()
00126    { }
00127    
00128    inline JSONVisitorValue &operator[](const std::type_info &type) {
00129       return (*this)[type.name()];
00130    }
00131    
00132    inline JSONVisitorValue &operator[](const std::string &key) {
00133       return functionMap[key];
00134    }
00135    
00136    // perform the functions defined by this JSONVisitor on the given variant, 
00137    // depending on its type
00138    bool visit(const MiltonJSONSceneLoader *loader, const JSONVariant &v, 
00139               JSONParseData &data);
00140    
00141    // iterate through each key, value (string : variant) pair in the given 
00142    // JSONObject, invoking the action specified by this JSONVisitor on each 
00143    // sub-variant
00144    bool visit(const MiltonJSONSceneLoader *loader, JSONObject const &obj, 
00145               JSONParseData &data, ParseResultsMap *results = NULL, 
00146               bool allowRepeats = false, bool atLeastOne = false, 
00147               // strict determines whether or not an error occurs if an 
00148               // unknown key is encountered
00149               bool strict = true);
00150 };
00151 
00152 class MiltonJSONSceneLoader : public SceneLoader {
00153    public:
00154       ///@name Constructors
00155       //@{-----------------------------------------------------------------
00156       
00157       inline MiltonJSONSceneLoader()
00158          : SceneLoader()
00159       { }
00160       
00161       virtual ~MiltonJSONSceneLoader()
00162       { }
00163       
00164       //@}-----------------------------------------------------------------
00165       ///@name Main usage interface
00166       //@{-----------------------------------------------------------------
00167       
00168       /**
00169        * @brief
00170        *    Attempts to parse the given file, storing the results in outData
00171        * 
00172        * @returns whether or not parsing was successful
00173        */
00174       virtual bool parse(const std::string &fileName, ParseData &outData);
00175       
00176       //@}-----------------------------------------------------------------
00177       
00178    protected:
00179       virtual bool _parse(const std::string &input,   ParseData &outData) const;
00180       
00181       /**
00182        * @brief
00183        *    Called after successful parsing of 'scenefile' element
00184        * 
00185        * Initializes defaults for the camera, output, and renderer of they 
00186        * weren't specified and ensures all references are in place between 
00187        * them
00188        */
00189       virtual bool _finalizeData(JSONParseData &data) const;
00190       
00191    private:
00192 #define ADD_PARSE_METHOD(name) \
00193    bool _parse_##name(const JSONVariant &v, JSONParseData &data) const;
00194       
00195       ADD_PARSE_METHOD(root);
00196       ADD_PARSE_METHOD(scenefile);
00197       
00198       ADD_PARSE_METHOD(version);
00199       
00200       ADD_PARSE_METHOD(renderer);
00201       ADD_PARSE_METHOD(camera);
00202       ADD_PARSE_METHOD(output);
00203       
00204       ADD_PARSE_METHOD(scene);
00205       
00206       ADD_PARSE_METHOD(transform);
00207       ADD_PARSE_METHOD(shape);
00208       ADD_PARSE_METHOD(material);
00209       
00210       ADD_PARSE_METHOD(background);
00211       
00212       ADD_PARSE_METHOD(bsdf);
00213       ADD_PARSE_METHOD(emitter);
00214       ADD_PARSE_METHOD(medium);
00215       
00216       ADD_PARSE_METHOD(translate);
00217       ADD_PARSE_METHOD(rotate);
00218       ADD_PARSE_METHOD(scale);
00219       ADD_PARSE_METHOD(arbitraryTransform);
00220       
00221       ADD_PARSE_METHOD(blob);
00222       ADD_PARSE_METHOD(cube);
00223       ADD_PARSE_METHOD(cone);
00224       ADD_PARSE_METHOD(cylinder);
00225       ADD_PARSE_METHOD(plane);
00226       ADD_PARSE_METHOD(point);
00227       ADD_PARSE_METHOD(mesh);
00228       ADD_PARSE_METHOD(shapeSet);
00229       ADD_PARSE_METHOD(sphere);
00230       ADD_PARSE_METHOD(triangle);
00231       
00232       ADD_PARSE_METHOD(spatialAccel);
00233       
00234       ADD_PARSE_METHOD(metaObjects);
00235       ADD_PARSE_METHOD(meta);
00236       ADD_PARSE_METHOD(ball);
00237       
00238       ADD_PARSE_METHOD(dummy);
00239       
00240       // helper utilities
00241       bool _parse_properties(const KeyValueIDMap &constraints,
00242                              JSONObject const &obj, 
00243                              PropertyMap &outMap, 
00244                              JSONParseData &data) const;
00245       
00246       bool _parse_emitter_helper(const JSONVariant &v, JSONParseData &data, 
00247                                  bool background) const;
00248       
00249       //bool _parse_filter(const JSONVariant &v, KernelFilter *outFilter, 
00250       //                   JSONParseData &data) const;
00251       
00252       void _add_node(JSONVisitor &outVisitor) const;
00253       void _add_shapes(JSONVisitor &outVisitor) const;
00254       
00255       bool _parse_real_t(const JSONVariant &v, real_t &outVal) const;
00256       bool _parse_real_t_array(const JSONVariant &v, real_t *outArray, 
00257                                unsigned expectedLength, 
00258                                JSONParseData &data) const;
00259       
00260       inline bool _is_valid_clampedSpectralSampleSet(const real_t s) const {
00261          return (s >= 0 && s <= 1);
00262       }
00263       
00264       template<typename T, unsigned E>
00265       T *_parse_dynamic_plugin(JSONObject const &obj, JSONParseData &data) const;
00266 };
00267 
00268 #endif // MILTON_JSON_SCENE_LOADER_H_
00269 

Generated on 28 Feb 2009 for Milton by doxygen 1.5.6