root/OpenSceneGraph/trunk/applications/present3D/ReaderWriterPaths.cpp @ 10207

Revision 10207, 8.7 kB (checked in by robert, 5 years ago)

Integrated support for relative paths, and http hosted presentations

Line 
1/* -*-c++-*- Present3D - Copyright (C) 1999-2006 Robert Osfield
2 *
3 * This software is open source and may be redistributed and/or modified under 
4 * the terms of the GNU General Public License (GPL) version 2.0.
5 * The full license is in LICENSE.txt file included with this distribution,.
6 *
7 * This software is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10 * include LICENSE.txt for more details.
11*/
12
13#include <osg/Notify>
14#include <osg/io_utils>
15
16#include <osgDB/ReaderWriter>
17#include <osgDB/FileNameUtils>
18#include <osgDB/FileUtils>
19#include <osgDB/Registry>
20
21#include <osgWidget/PdfReader>
22
23#include "SlideShowConstructor.h"
24#include "AnimationMaterial.h"
25
26#include <stdio.h>
27#include <string.h>
28#include <stdlib.h>
29
30#include <osgDB/XmlParser>
31
32#include <sstream>
33#include <iostream>
34
35
36/**
37 * OpenSceneGraph plugin wrapper/converter.
38 */
39class ReaderWriterPaths : public osgDB::ReaderWriter
40{
41public:
42    ReaderWriterPaths()
43    {
44        supportsExtension("material","Material animation Ascii file format");
45        supportsExtension("path","Animation path Ascii file format");
46        supportsExtension("pivot_path","Animation pivot path Ascii file format");
47        supportsExtension("rotation_path","Animation rotation path Ascii file format");
48    }
49   
50    virtual const char* className() const
51    {
52        return "Path Reader/Writer";
53    }
54
55    virtual bool acceptsExtension(const std::string& extension) const
56    {
57        return osgDB::equalCaseInsensitive(extension,"material") ||
58               osgDB::equalCaseInsensitive(extension,"path") ||
59               osgDB::equalCaseInsensitive(extension,"pivot_path") ||
60               osgDB::equalCaseInsensitive(extension,"rotation_path");
61    }
62
63    virtual osgDB::ReaderWriter::ReadResult readObject(const std::string& fileName, const osgDB::Options* options) const;
64
65    virtual osgDB::ReaderWriter::ReadResult readObject(std::istream& fin, const osgDB::Options* options) const;
66
67    virtual osgDB::ReaderWriter::ReadResult read_material(std::istream& fin, const osgDB::Options* options) const;
68    virtual osgDB::ReaderWriter::ReadResult read_path(std::istream& fin, const osgDB::Options* options) const;
69    virtual osgDB::ReaderWriter::ReadResult read_pivot_path(std::istream& fin, const osgDB::Options* options) const;
70    virtual osgDB::ReaderWriter::ReadResult read_rotation_path(std::istream& fin, const osgDB::Options* options) const;
71};
72
73// Register with Registry to instantiate the above reader/writer.
74osgDB::RegisterReaderWriterProxy<ReaderWriterPaths> g_readerWriter_PathsL_Proxy;
75
76osgDB::ReaderWriter::ReadResult ReaderWriterPaths::readObject(const std::string& file, const osgDB::Options* options) const
77{
78
79
80    std::string ext = osgDB::getLowerCaseFileExtension(file);
81    if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED;
82
83    osg::notify(osg::INFO)<<"ReaderWriterPaths::readObject("<<file<<")"<<std::endl;
84
85    std::string fileName = osgDB::findDataFile( file, options );
86    if (fileName.empty()) return ReadResult::FILE_NOT_FOUND;
87
88    osg::notify(osg::INFO)<<"  Found path file :"<<fileName<<std::endl;
89
90    // code for setting up the database path so that internally referenced file are searched for on relative paths.
91    osg::ref_ptr<osgDB::ReaderWriter::Options> local_opt = options ? static_cast<osgDB::ReaderWriter::Options*>(options->clone(osg::CopyOp::SHALLOW_COPY)) : new Options;
92    local_opt->setPluginStringData("filename",fileName);
93
94    std::ifstream input(fileName.c_str());
95
96    return readObject(input, local_opt);
97}
98
99osgDB::ReaderWriter::ReadResult ReaderWriterPaths::readObject(std::istream& fin, const osgDB::Options* options) const
100{
101    osg::notify(osg::INFO)<<"ReaderWriterPaths::readObject(std::istream& fin"<<std::endl;
102
103    if (!options) return ReadResult::FILE_NOT_HANDLED;
104    if (!fin) return ReadResult::ERROR_IN_READING_FILE;
105
106
107    std::string filename = options->getPluginStringData("filename");
108
109    std::string ext = osgDB::getLowerCaseFileExtension(filename);
110
111    osg::notify(osg::INFO)<<"   filename found in options: "<<filename<<"  extension="<<ext<<std::endl;
112
113
114    if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED;
115
116
117    if      (ext=="path") return read_path(fin, options);
118    else if (ext=="material") return read_material(fin, options);
119    else if (ext=="pivot_path") return read_pivot_path(fin, options);
120    else if (ext=="rotation_path") return read_rotation_path(fin, options);
121
122    return ReadResult::FILE_NOT_HANDLED;
123}
124
125osgDB::ReaderWriter::ReadResult ReaderWriterPaths::read_material(std::istream& fin, const osgDB::Options* options) const
126{
127    osg::ref_ptr<ss3d::AnimationMaterial> animationMaterial = new ss3d::AnimationMaterial;
128    animationMaterial->read(fin);
129
130    return animationMaterial.get();
131}
132
133osgDB::ReaderWriter::ReadResult ReaderWriterPaths::read_path(std::istream& fin, const osgDB::Options* options) const
134{
135    osg::ref_ptr<osg::AnimationPath> animation = new osg::AnimationPath;
136    animation->read(fin);
137    return animation.get();
138}
139
140osgDB::ReaderWriter::ReadResult ReaderWriterPaths::read_pivot_path(std::istream& fin, const osgDB::Options* options) const
141{
142    osg::ref_ptr<osg::AnimationPath> animation = new osg::AnimationPath;
143
144    while (!fin.eof())
145    {
146        double time;
147        osg::Vec3 pivot;
148        osg::Vec3 position;
149        float scale;
150        osg::Quat rotation;
151        fin >> time >> pivot.x() >> pivot.y() >> pivot.z() >> position.x() >> position.y() >> position.z() >> rotation.x() >> rotation.y() >> rotation.z() >> rotation.w() >> scale;
152        if(!fin.eof())
153        {
154            osg::Matrix SR = osg::Matrix::scale(scale,scale,scale)*
155                                osg::Matrixf::rotate(rotation);
156
157            osg::Matrix invSR;
158            invSR.invert(SR);
159
160            position += (invSR*pivot)*SR;
161
162            animation->insert(time,osg::AnimationPath::ControlPoint(position,rotation,osg::Vec3(scale,scale,scale)));
163        }
164    }
165
166    return animation.get();
167}
168
169struct RotationPathData
170{
171    RotationPathData():
172        time(0.0),
173        scale(1.0f),
174        azim(0.0f),
175        elevation(0.0f) {}
176
177    double time;
178    osg::Vec3 pivot;
179    osg::Vec3 position;
180    float scale;
181    float azim;
182    float elevation;
183
184    void addToPath(osg::AnimationPath* animation) const
185    {
186        osg::Quat Rx, Rz, rotation;
187
188        Rx.makeRotate(osg::DegreesToRadians(elevation),1.0f,0.0f,0.0f);
189        Rz.makeRotate(osg::DegreesToRadians(azim),0.0f,0.0f,1.0f);
190        rotation = Rz * Rx; // note, I believe this is the wrong way round, but I had to put it in this order to fix the Quat properly.
191
192        osg::Matrix SR = osg::Matrix::scale(scale,scale,scale)*
193                         osg::Matrixf::rotate(rotation);
194
195        osg::Matrix invSR;
196        invSR.invert(SR);
197
198        osg::Vec3 local_position = position + (invSR*pivot)*SR;
199
200        animation->insert(time,osg::AnimationPath::ControlPoint(local_position,rotation,osg::Vec3(scale,scale,scale)));
201    }
202
203};
204
205osgDB::ReaderWriter::ReadResult ReaderWriterPaths::read_rotation_path(std::istream& fin, const osgDB::Options* options) const
206{
207    osg::ref_ptr<osg::AnimationPath> animation = new osg::AnimationPath;
208
209    RotationPathData prevValue;
210    bool first = true;
211    while (!fin.eof())
212    {
213        RotationPathData currValue;
214        fin >> currValue.time >> currValue.pivot.x() >> currValue.pivot.y() >> currValue.pivot.z() >> currValue.position.x() >> currValue.position.y() >> currValue.position.z() >> currValue.azim >> currValue.elevation >> currValue.scale;
215
216        if(!fin.eof())
217        {
218
219            if (!first)
220            {
221
222                unsigned int num = 20;
223                float dr = 1.0f/(float)num;
224                float r=dr;
225                for(unsigned int i=0;
226                    i<num;
227                    ++i, r+=dr)
228                {
229                    RotationPathData localValue;
230                    localValue.time = currValue.time *r + prevValue.time * (1.0f-r);
231                    localValue.pivot = currValue.pivot *r + prevValue.pivot * (1.0f-r);
232                    localValue.position = currValue.position *r + prevValue.position * (1.0f-r);
233                    localValue.scale = currValue.scale *r + prevValue.scale * (1.0f-r);
234                    localValue.azim = currValue.azim *r + prevValue.azim * (1.0f-r);
235                    localValue.elevation = currValue.elevation *r + prevValue.elevation * (1.0f-r);
236
237                    localValue.addToPath(animation);
238                }
239            }
240            else
241            {
242                currValue.addToPath(animation);
243            }
244            prevValue = currValue;
245            first = false;
246        }
247
248    }
249    osg::notify(osg::NOTICE)<<"finished"<<std::endl;
250
251    return animation.get();
252}
Note: See TracBrowser for help on using the browser.