root/OpenSceneGraph/trunk/src/osgPlugins/lws/SceneLoader.cpp @ 13041

Revision 13041, 11.2 kB (checked in by robert, 2 years ago)

Ran script to remove trailing spaces and tabs

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1/*******************************************************
2      Lightwave Scene Loader for OSG
3
4  Copyright (C) 2004 Marco Jez <marco.jez@poste.it>
5  OpenSceneGraph is (C) 2004 Robert Osfield
6********************************************************/
7
8#include "SceneLoader.h"
9
10#include <osg/Notify>
11#include <osg/PositionAttitudeTransform>
12#include <osg/AnimationPath>
13#include <osg/io_utils>
14
15#include <osgDB/FileUtils>
16#include <osgDB/FileNameUtils>
17#include <osgDB/fstream>
18#include <osgDB/ReadFile>
19#include <osgDB/WriteFile>
20
21#include <sstream>
22
23using namespace lwosg;
24
25namespace
26{
27
28    int str_to_int(const std::string &s)
29    {
30        std::istringstream iss(s);
31        int n;
32        iss >> n;
33        return n;
34    }
35
36    int hex_to_int(const std::string &s)
37    {
38        std::istringstream iss(s);
39        int n;
40        iss >> std::hex >> n;
41        return n;
42    }
43
44    osg::Quat rotate_ypr(const osg::Vec3 &ypr, const osg::Vec3 pivot_rot = osg::Vec3(0, 0, 0))
45    {
46        osg::Quat Q1(ypr.z(), osg::Vec3(0, -1, 0));
47        osg::Quat Q2(ypr.y(), osg::Vec3(-1, 0, 0));
48        osg::Quat Q3(ypr.x(), osg::Vec3(0, 0, -1));
49        osg::Quat Q4(pivot_rot.z(), osg::Vec3(0, -1, 0));
50        osg::Quat Q5(pivot_rot.y(), osg::Vec3(-1, 0, 0));
51        osg::Quat Q6(pivot_rot.x(), osg::Vec3(0, 0, -1));
52        return Q1 * Q2 * Q3 * Q4 * Q5 * Q6;
53    }
54
55    void trim(std::string& str)
56    {
57        // trim any trailing control characters.
58        //std::cout<<"trim string "<<str<<std::endl;
59        while (!str.empty() && str[str.size()-1]<32)
60        {
61            // removing control character
62            //std::cout<<"    removing control character "<<(int)str[str.size()-1]<<std::endl;
63            str.erase(str.size()-1);
64        }
65
66    }
67
68}
69
70
71SceneLoader::SceneLoader()
72:    capture_obj_motion_(false),
73    capture_cam_motion_(false)
74{
75}
76
77SceneLoader::SceneLoader(const Options &options)
78:    capture_obj_motion_(false),
79    capture_cam_motion_(false),
80    options_(options)
81{
82}
83
84osg::Group *SceneLoader::load(const std::string &filename, const osgDB::ReaderWriter::Options *options, bool search)
85{
86    std::string fname;
87
88    if (search) {
89        fname = osgDB::findDataFile(filename, options);
90        if (fname.empty()) return 0;
91    } else {
92        fname = filename;
93    }
94
95    osgDB::ifstream ifs(fname.c_str());
96    if (!ifs.is_open()) return 0;
97
98    clear();
99
100    std::string identifier;
101    while (ifs >> identifier) {
102        if (identifier == "{") {
103            ifs >> identifier;
104            std::ws(ifs);
105            std::vector<std::string> data;
106            std::string data_line;
107            while (std::getline(ifs, data_line)) {
108                trim(data_line);
109                if (data_line == "}") {
110                    std::ws(ifs);
111                    break;
112                }
113                data.push_back(data_line);
114                std::ws(ifs);
115            }
116            if (!data.empty()) {
117                if (!parse_block(identifier, data)) {
118                    return 0;
119                }
120            }
121        } else {
122            std::string data;
123            std::getline(ifs, data);
124            trim(data);
125            std::istringstream iss(data);
126            std::ws(iss);
127            std::getline(iss, data);
128            trim(data);
129            if (!parse_block(identifier, data)) {
130                return 0;
131            }
132        }
133    }
134
135    // build camera animations
136    for (Scene_camera_list::iterator ci=scene_cameras_.begin(); ci!=scene_cameras_.end(); ++ci) {
137        if (!ci->motion.keys.empty()) {
138            osg::ref_ptr<osg::AnimationPath> ap = new osg::AnimationPath;
139            for (Motion_envelope::Key_map::const_iterator j=ci->motion.keys.begin(); j!=ci->motion.keys.end(); ++j) {
140                osg::Vec3 pos(options_.csf->fix_point(j->second.position));
141                //const osg::Vec3 &ypr = j->second.ypr;
142                osg::AnimationPath::ControlPoint cp(pos, osg::Quat(osg::PI_2, osg::Vec3(1, 0, 0)) * rotate_ypr(j->second.ypr), j->second.scale);
143                OSG_NOTICE<<"scale = "<<j->second.scale<<std::endl;
144                ap->insert(j->first, cp);
145            }
146            camera_animations_.push_back(ap.get());
147        }
148    }
149
150    // build objects and object animations
151    typedef std::map<int, osg::ref_ptr<osg::PositionAttitudeTransform> > PAT_map;
152    PAT_map pats;
153    int j = 0;
154    for (Scene_object_list::iterator i=scene_objects_.begin(); i!=scene_objects_.end(); ++i, ++j) {
155        osg::ref_ptr<osg::PositionAttitudeTransform> pat = pats[j];
156        if (!pat.valid()) {
157            pat = new osg::PositionAttitudeTransform;
158            pats[j] = pat;
159        }
160
161        pat->setName(i->name);
162        pat->addChild(i->layer_node.get());
163        pat->setPivotPoint(options_.csf->fix_point(i->pivot));
164
165        // still
166        if (!i->motion.keys.empty()) {
167            pat->setPosition(options_.csf->fix_point(i->motion.keys.begin()->second.position));
168            pat->setAttitude(rotate_ypr(i->motion.keys.begin()->second.ypr, i->pivot_rot));
169        }
170
171        // animation
172        if (i->motion.keys.size() > 1) {
173            osg::ref_ptr<osg::AnimationPath> ap = new osg::AnimationPath;
174            for (Motion_envelope::Key_map::const_iterator j=i->motion.keys.begin(); j!=i->motion.keys.end(); ++j) {
175                osg::Vec3 pos(options_.csf->fix_point(j->second.position));
176                osg::AnimationPath::ControlPoint cp(pos, rotate_ypr(j->second.ypr, i->pivot_rot), j->second.scale);
177                ap->insert(j->first, cp);
178            }
179            osg::ref_ptr<osg::AnimationPathCallback> apc = new osg::AnimationPathCallback(ap.get());
180            apc->setPivotPoint(options_.csf->fix_point(i->pivot));
181            pat->setUpdateCallback(apc.get());
182        }
183
184        if (i->parent == -1) {
185            root_->addChild(pat.get());
186        } else {
187            if (i->parent < static_cast<int>(scene_objects_.size())) {
188                osg::ref_ptr<osg::PositionAttitudeTransform> parent = pats[i->parent];
189                if (!parent.valid()) {
190                    parent = new osg::PositionAttitudeTransform;
191                    pats[i->parent] = parent;
192                }
193                parent->addChild(pat.get());
194            } else {
195                OSG_WARN << "Warning: lwosg::SceneLoader: invalid parent" << std::endl;
196            }
197        }
198    }
199
200    return root_.get();
201}
202
203bool SceneLoader::parse_block(const std::string &name, const std::string &data)
204{
205    std::istringstream iss(data);
206
207    if (name == "AddCamera") {
208        scene_cameras_.push_back(Scene_camera());
209    }
210
211    if (name == "AddNullObject") {
212        osg::ref_ptr<osg::Group> nullobjnode = new osg::Group;
213        nullobjnode->setName(data);
214        objects_[data] = nullobjnode;
215        Scene_object so;
216        so.layer_node = nullobjnode.get();
217        scene_objects_.push_back(so);
218    }
219
220    if (name == "LoadObjectLayer") {
221        unsigned layer;
222        iss >> layer;
223        std::ws(iss);
224        std::string filename;
225        std::getline(iss, filename);
226
227        // trim any trailing control characters.
228        trim(filename);
229
230        if (!filename.empty())
231        {
232
233
234            osg::ref_ptr<osg::Group> objnode;
235
236            Object_map::const_iterator i = objects_.find(filename);
237
238            if (i == objects_.end()) {
239
240                OSG_NOTICE << "Loading object \"" << filename << "\"" << std::endl;
241
242                objnode = dynamic_cast<osg::Group *>(osgDB::readNodeFile(filename));
243                if (!objnode.valid()) return false;
244
245                objects_[filename] = objnode;
246
247            } else {
248                objnode = i->second;
249            }
250
251            if (layer > objnode->getNumChildren()) {
252                OSG_WARN << "Warning: lwosg::SceneLoader: layer " << layer << " does not exist in object " << filename << std::endl;
253                return 0;
254            }
255
256            Scene_object so;
257            std::ostringstream oss;
258            oss << filename << "." << layer;
259            so.name = oss.str();
260            so.layer_node = objnode->getChild(layer-1);
261            if (so.layer_node.valid()) {
262                scene_objects_.push_back(so);
263            }
264        }
265    }
266
267    if (name == "PivotPosition") {
268        if (!scene_objects_.empty()) {
269            osg::Vec3 pivot;
270            iss >> pivot.x() >> pivot.y() >> pivot.z();
271            scene_objects_.back().pivot = pivot;
272        }
273    }
274
275    if (name == "PivotRotation") {
276        if (!scene_objects_.empty()) {
277            osg::Vec3 pivot;
278            iss >> pivot.x() >> pivot.y() >> pivot.z();
279            scene_objects_.back().pivot_rot = pivot * (osg::PI / 180.0f);
280        }
281    }
282
283    if (name == "ParentItem") {
284        if (!scene_objects_.empty()) {
285            std::string id;
286            iss >> id;
287            if (id.length() == 8) {
288                if (id[0] == '1') {
289                    id.erase(0, 1);
290                    scene_objects_.back().parent = hex_to_int(id);
291                }
292            } else {
293                scene_objects_.back().parent = str_to_int(id);
294            }
295        }
296    }
297
298    if (name == "NumChannels") {
299        iss >> channel_count_;
300    }
301
302    if (name == "Channel") {
303        iss >> current_channel_;
304    }
305
306    if (name == "ObjectMotion") {
307        capture_obj_motion_ = true;
308    }
309
310    if (name == "CameraMotion") {
311        capture_cam_motion_ = true;
312    }
313
314    return true;
315}
316
317bool SceneLoader::parse_block(const std::string &name, const std::vector<std::string> &data)
318{
319    if (name == "Envelope") {
320        if (((capture_obj_motion_ && !scene_objects_.empty()) ||
321            (capture_cam_motion_ && !scene_cameras_.empty())) &&
322            (data.size() >= 2)) {
323
324            Motion_envelope::Key_map &keys = capture_obj_motion_ ? scene_objects_.back().motion.keys : scene_cameras_.back().motion.keys;
325
326            if (current_channel_ >= (channel_count_ - 1)) {
327                capture_obj_motion_ = false;
328                capture_cam_motion_ = false;
329            }
330
331            for (unsigned i=1; i<data.size(); ++i) {
332                std::istringstream iss(data[i]);
333                std::string key_id;
334                iss >> key_id;
335                if (key_id == "Key") {
336                    float value;
337                    double time;
338                    if (iss >> value >> time) {
339                        switch (current_channel_) {
340                            case 0: keys[time].position.x() = value; break;
341                            case 1: keys[time].position.y() = value; break;
342                            case 2: keys[time].position.z() = value; break;
343                            case 3: keys[time].ypr.x() = value; break;
344                            case 4: keys[time].ypr.y() = value; break;
345                            case 5: keys[time].ypr.z() = value; break;
346                            case 6: keys[time].scale.x() = value; break;
347                            case 7: keys[time].scale.y() = value; break;
348                            case 8: keys[time].scale.z() = value; break;
349                            default: ;
350                        }
351                    }
352                }
353            }
354        }
355    }
356    return true;
357}
358
359void SceneLoader::clear()
360{
361    root_ = new osg::Group;
362    objects_.clear();
363    scene_objects_.clear();
364    scene_cameras_.clear();
365    camera_animations_.clear();
366    channel_count_ = 0;
367    current_channel_ = 0;
368}
Note: See TracBrowser for help on using the browser.