1 
2 #include <osgParticle/Particle>
3 #include <osgParticle/Interpolator>
4 #include <osgParticle/range>
5 
6 #include <iostream>
7 #include <string>
8 
9 #include <osg/Vec3>
10 #include <osg/Vec4>
11 #include <osg/Notify>
12 
13 #include <osgDB/Input>
14 #include <osgDB/Output>
15 
read_particle(osgDB::Input & fr,osgParticle::Particle & P)16 bool  read_particle(osgDB::Input &fr, osgParticle::Particle &P)
17 {
18     if (fr[0].matchString("{")) {
19         ++fr;
20         int entry = fr[0].getNoNestedBrackets();
21         bool itAdvanced = true;
22         while (!fr.eof() && fr[0].getNoNestedBrackets() >= entry && itAdvanced) {
23             itAdvanced = false;
24             if (fr[0].matchWord("shape")) {
25                 const char *ptstr = fr[1].getStr();
26                 if (ptstr) {
27                     if (std::string(ptstr) == "QUAD") {
28                         P.setShape(osgParticle::Particle::QUAD);
29                     } else if (std::string(ptstr) == "HEXAGON") {
30                         P.setShape(osgParticle::Particle::HEXAGON);
31                     } else if (std::string(ptstr) == "POINT") {
32                         P.setShape(osgParticle::Particle::POINT);
33                     } else if (std::string(ptstr) == "QUAD_TRIANGLESTRIP") {
34                         P.setShape(osgParticle::Particle::QUAD_TRIANGLESTRIP);
35                     } else if (std::string(ptstr) == "LINE") {
36                         P.setShape(osgParticle::Particle::LINE);
37                     } else if (std::string(ptstr) == "USER") {
38                         P.setShape(osgParticle::Particle::USER);
39                     } else {
40                         osg::notify(osg::WARN) << "Particle reader warning: invalid shape: " << ptstr << std::endl;
41                     }
42                     fr += 2;
43                     itAdvanced = true;
44                 }
45             }
46             if (fr[0].matchWord("lifeTime")) {
47                 float lt;
48                 if (fr[1].getFloat(lt)) {
49                     P.setLifeTime(lt);
50                     fr += 2;
51                     itAdvanced = true;
52                 }
53             }
54             if (fr[0].matchWord("sizeRange")) {
55                 osgParticle::rangef r;
56                 if (fr[1].getFloat(r.minimum) && fr[2].getFloat(r.maximum)) {
57                     P.setSizeRange(r);
58                     fr += 3;
59                     itAdvanced = true;
60                 }
61             }
62             if (fr[0].matchWord("alphaRange")) {
63                 osgParticle::rangef r;
64                 if (fr[1].getFloat(r.minimum) && fr[2].getFloat(r.maximum)) {
65                     P.setAlphaRange(r);
66                     fr += 3;
67                     itAdvanced = true;
68                 }
69             }
70             if (fr[0].matchWord("colorRange")) {
71                 osgParticle::rangev4 r;
72                 if (fr[1].getFloat(r.minimum.x()) && fr[2].getFloat(r.minimum.y()) && fr[3].getFloat(r.minimum.z()) && fr[4].getFloat(r.minimum.w()) &&
73                     fr[5].getFloat(r.maximum.x()) && fr[6].getFloat(r.maximum.y()) && fr[7].getFloat(r.maximum.z()) && fr[8].getFloat(r.maximum.w())) {
74                     P.setColorRange(r);
75                     fr += 9;
76                     itAdvanced = true;
77                 }
78             }
79             if (fr[0].matchWord("position")) {
80                 osg::Vec3 v;
81                 if (fr[1].getFloat(v.x()) && fr[2].getFloat(v.y()) && fr[3].getFloat(v.z())) {
82                     P.setPosition(v);
83                     fr += 4;
84                     itAdvanced = true;
85                 }
86             }
87             if (fr[0].matchWord("velocity")) {
88                 osg::Vec3 v;
89                 if (fr[1].getFloat(v.x()) && fr[2].getFloat(v.y()) && fr[3].getFloat(v.z())) {
90                     P.setVelocity(v);
91                     fr += 4;
92                     itAdvanced = true;
93                 }
94             }
95             if (fr[0].matchWord("angle")) {
96                 osg::Vec3 v;
97                 if (fr[1].getFloat(v.x()) && fr[2].getFloat(v.y()) && fr[3].getFloat(v.z())) {
98                     P.setAngle(v);
99                     fr += 4;
100                     itAdvanced = true;
101                 }
102             }
103             if (fr[0].matchWord("angularVelocity")) {
104                 osg::Vec3 v;
105                 if (fr[1].getFloat(v.x()) && fr[2].getFloat(v.y()) && fr[3].getFloat(v.z())) {
106                     P.setAngularVelocity(v);
107                     fr += 4;
108                     itAdvanced = true;
109                 }
110             }
111             if (fr[0].matchWord("radius")) {
112                 float f;
113                 if (fr[1].getFloat(f)) {
114                     P.setRadius(f);
115                     fr += 2;
116                     itAdvanced = true;
117                 }
118             }
119 
120             if (fr[0].matchWord("mass")) {
121                 float f;
122                 if (fr[1].getFloat(f)) {
123                     P.setMass(f);
124                     fr += 2;
125                     itAdvanced = true;
126                 }
127             }
128 
129             if (fr[0].matchWord("textureTile")) {
130                 int sTile,tTile,numTiles;
131                 if (fr[1].getInt(sTile) && fr[2].getInt(tTile) && fr[3].getInt(numTiles)) {
132                     P.setTextureTile(sTile,tTile,numTiles);
133                     fr += 4;
134                     itAdvanced = true;
135                 }
136             }
137 
138 
139             // interpolators
140 
141             if (fr[0].matchWord("sizeInterpolator") && fr[1].matchString("{")) {
142                 fr += 2;
143                 itAdvanced = true;
144                 osgParticle::Interpolator *ip = dynamic_cast<osgParticle::Interpolator *>(fr.readObject());
145                 if (ip) {
146                     P.setSizeInterpolator(ip);
147                 }
148                 ++fr;
149             }
150             if (fr[0].matchWord("alphaInterpolator") && fr[1].matchString("{")) {
151                 fr += 2;
152                 itAdvanced = true;
153                 osgParticle::Interpolator *ip = dynamic_cast<osgParticle::Interpolator *>(fr.readObject());
154                 if (ip) {
155                     P.setAlphaInterpolator(ip);
156                 }
157                 ++fr;
158             }
159             if (fr[0].matchWord("colorInterpolator") && fr[1].matchString("{")) {
160                 fr += 2;
161                 itAdvanced = true;
162                 osgParticle::Interpolator *ip = dynamic_cast<osgParticle::Interpolator *>(fr.readObject());
163                 if (ip) {
164                     P.setColorInterpolator(ip);
165                 }
166                 ++fr;
167             }
168         }
169         return true;
170     }
171     return false;
172 }
173 
write_particle(const osgParticle::Particle & P,osgDB::Output & fw)174 void  write_particle(const osgParticle::Particle &P, osgDB::Output &fw)
175 {
176     fw << "{" << std::endl;
177     fw.moveIn();
178 
179     fw.indent() << "shape ";
180     switch (P.getShape())
181     {
182     case osgParticle::Particle::POINT: fw << "POINT" << std::endl; break;
183     case osgParticle::Particle::HEXAGON: fw << "HEXAGON" << std::endl; break;
184     case osgParticle::Particle::QUAD_TRIANGLESTRIP: fw << "QUAD_TRIANGLESTRIP" << std::endl; break;
185     case osgParticle::Particle::QUAD: fw << "QUAD" << std::endl; break;
186     case osgParticle::Particle::LINE: fw << "LINE" << std::endl; break;
187     case osgParticle::Particle::USER:
188     default: fw << "USER" << std::endl; break;
189     }
190 
191     fw.indent() << "lifeTime " << P.getLifeTime() << std::endl;
192 
193     osgParticle::rangef rf = P.getSizeRange();
194     fw.indent() << "sizeRange " << rf.minimum << " " << rf.maximum << std::endl;
195 
196     rf = P.getAlphaRange();
197     fw.indent() << "alphaRange " << rf.minimum << " " << rf.maximum << std::endl;
198 
199     osgParticle::rangev4 rv4 = P.getColorRange();
200     fw.indent() << "colorRange ";
201     fw << rv4.minimum.x() << " " << rv4.minimum.y() << " " << rv4.minimum.z() << " " << rv4.minimum.w() << " ";
202     fw << rv4.maximum.x() << " " << rv4.maximum.y() << " " << rv4.maximum.z() << " " << rv4.maximum.w() << std::endl;
203 
204     osg::Vec3 v = P.getPosition();
205     fw.indent() << "position ";
206     fw << v.x() << " " << v.y() << " " << v.z() << std::endl;
207 
208     v = P.getVelocity();
209     fw.indent() << "velocity ";
210     fw << v.x() << " " << v.y() << " " << v.z() << std::endl;
211 
212     v = P.getAngle();
213     fw.indent() << "angle ";
214     fw << v.x() << " " << v.y() << " " << v.z() << std::endl;
215 
216     v = P.getAngularVelocity();
217     fw.indent() << "angularVelocity ";
218     fw << v.x() << " " << v.y() << " " << v.z() << std::endl;
219 
220     fw.indent() << "radius " << P.getRadius() << std::endl;
221     fw.indent() << "mass " << P.getMass() << std::endl;
222     fw.indent() << "textureTile " << P.getTileS() << " " << P.getTileT() << " " << P.getNumTiles() << std::endl;
223 
224     // interpolators
225 
226     fw.indent() << "sizeInterpolator {" << std::endl;
227     fw.moveIn();
228     fw.writeObject(*P.getSizeInterpolator());
229     fw.moveOut();
230     fw.indent() << "}" << std::endl;
231 
232     fw.indent() << "alphaInterpolator {" << std::endl;
233     fw.moveIn();
234     fw.writeObject(*P.getAlphaInterpolator());
235     fw.moveOut();
236     fw.indent() << "}" << std::endl;
237 
238     fw.indent() << "colorInterpolator {" << std::endl;
239     fw.moveIn();
240     fw.writeObject(*P.getColorInterpolator());
241     fw.moveOut();
242     fw.indent() << "}" << std::endl;
243 
244     fw.moveOut();
245     fw.indent() << "}" << std::endl;
246 }
247