1 /****************************************************************
2  Thanks to Bandures for the particle exporter
3  ****************************************************************/
4 
5 /*********************************************************************************
6 *                                                                                *
7 *   This program is free software; you can redistribute it and/or modify         *
8 *   it under the terms of the GNU Lesser General Public License as published by  *
9 *   the Free Software Foundation; either version 2 of the License, or            *
10 *   (at your option) any later version.                                          *
11 *                                                                                *
12 **********************************************************************************/
13 
14 #ifndef _PARTICLES_H
15 #define _PARTICLES_H
16 
17 #include <math.h>
18 #include <vector>
19 #ifdef MAC_PLUGIN
20 #include <ext/hash_map>
21 #else
22 #include <hash_map>
23 #endif
24 #include <maya/MDagPath.h>
25 #include "paramList.h"
26 #include "mayaExportLayer.h"
27 #pragma warning(disable: 4996)
28 
29 namespace OgreMayaExporter
30 {
31 ////////////////////////////////////////////////////////////////////////////////////////////////////
fabs(float fVal)32 inline float fabs( float fVal ) { return ::fabs( fVal ); }
33 ////////////////////////////////////////////////////////////////////////////////////////////////////
34 struct SPos
35 {
36     float x;
37     float y;
38     float z;
39 
SPosSPos40     SPos(): x(0), y(0), z(0) {}
SPosSPos41     SPos( float _x, float _y, float _z ): x(_x), y(_y), z(_z) {}
42 };
43 inline const SPos operator-( const SPos &in ) { return SPos( -in.x, -in.y, -in.z ); }
44 inline const SPos operator+( const SPos &in1, const SPos &in2 ) { return SPos( in1.x + in2.x, in1.y + in2.y, in1.z + in2.z ); }
45 inline const SPos operator-( const SPos &in1, const SPos &in2 ) { return SPos( in1.x - in2.x, in1.y - in2.y, in1.z - in2.z ); }
fabs2(const SPos & in)46 inline float fabs2( const SPos &in ) { return in.x * in.x + in.y * in.y + in.z * in.z; }
fabs(const SPos & in)47 inline float fabs( const SPos &in ) { return float( sqrt( fabs2( in ) ) ); }
48 ////////////////////////////////////////////////////////////////////////////////////////////////////
49 struct SColor
50 {
51     union
52     {
53         struct
54         {
55             float x, y, z, w;
56         };
57         struct
58         {
59             float r, g, b, a;
60         };
61     };
62 
SColorSColor63     SColor(): r(0), g(0), b(0), a(0) {}
SColorSColor64     SColor( float _r, float _g, float _b, float _a ): r(_r), g(_g), b(_b), a(_a) {}
65 };
66 inline const SColor operator-( const SColor &in1) { return SColor( -in1.x, -in1.y, -in1.z, -in1.w ); }
67 inline const SColor operator+( const SColor &in1, const SColor &in2 ) { return SColor( in1.x + in2.x, in1.y + in2.y, in1.z + in2.z, in1.w + in2.w ); }
68 inline const SColor operator-( const SColor &in1, const SColor &in2 ) { return SColor( in1.x - in2.x, in1.y - in2.y, in1.z - in2.z, in1.w - in2.w ); }
fabs2(const SColor & in)69 inline float fabs2( const SColor &in ) { return in.x * in.x + in.y * in.y + in.z * in.z + in.w * in.w; }
fabs(const SColor & in)70 inline float fabs( const SColor &in ) { return float( sqrt( fabs2( in ) ) ); }
71 ////////////////////////////////////////////////////////////////////////////////////////////////////
72 struct SScale
73 {
74     float x;
75     float y;
76 
SScaleSScale77     SScale(): x(0), y(0) {}
SScaleSScale78     SScale( float _x, float _y ): x(_x), y(_y) {}
79 };
80 inline const SScale operator+( const SScale &in1, const SScale &in2 ) { return SScale( in1.x + in2.x, in1.y + in2.y ); }
81 inline const SScale operator-( const SScale &in1, const SScale &in2 ) { return SScale( in1.x - in2.x, in1.y - in2.y ); }
fabs2(const SScale & in)82 inline float fabs2( const SScale &in ) { return in.x * in.x + in.y * in.y; }
fabs(const SScale & in)83 inline float fabs( const SScale &in ) { return float( sqrt( fabs2( in ) ) ); }
84 ////////////////////////////////////////////////////////////////////////////////////////////////////
85 struct SParticleData
86 {
87     int nFrame;
88     int nSprite;
89     SPos pos;
90     SColor color;
91     SScale scale;
92     float fRotation;
93     ////
SParticleDataSParticleData94     SParticleData(): nFrame( 0 ), nSprite( 0 ), pos( 0, 0, 0 ), color( 1, 1, 1, 1 ), scale( 1, 1 ), fRotation( 0 ) {}
95 };
96 typedef std::vector<SParticleData> CParticlesTrack;
97 #ifdef MAC_PLUGIN
98 typedef __gnu_cxx::hash_map<int, CParticlesTrack> CParticlesData;
99 #else
100 typedef stdext::hash_map<int, CParticlesTrack> CParticlesData;
101 #endif
102 ////////////////////////////////////////////////////////////////////////////////////////////////////
103 template <class T>
Interpolate(const T & v1,const T & v2,float fCoeff,T * pRes)104 inline void Interpolate( const T &v1, const T &v2, float fCoeff, T *pRes )
105 {
106     pRes->Interpolate( v1, v2, fCoeff );
107 }
108 ////////////////////////////////////////////////////////////////////////////////////////////////////
Interpolate(const int & v1,const int & v2,float fCoeff,int * pRes)109 inline void Interpolate( const int &v1, const int &v2, float fCoeff, int *pRes )
110 {
111     *pRes = v1;
112 }
113 ////////////////////////////////////////////////////////////////////////////////////////////////////
Interpolate(const float & v1,const float & v2,float fCoeff,float * pRes)114 inline void Interpolate( const float &v1, const float &v2, float fCoeff, float *pRes )
115 {
116     *pRes = ( 1 - fCoeff ) * v1 + fCoeff * v2;
117 }
118 ////////////////////////////////////////////////////////////////////////////////////////////////////
Interpolate(const SPos & v1,const SPos & v2,float fCoeff,SPos * pRes)119 inline void Interpolate( const SPos &v1, const SPos &v2, float fCoeff, SPos *pRes )
120 {
121     Interpolate( v1.x, v2.x, fCoeff, &pRes->x );
122     Interpolate( v1.y, v2.y, fCoeff, &pRes->y );
123     Interpolate( v1.z, v2.z, fCoeff, &pRes->z );
124 }
125 ////////////////////////////////////////////////////////////////////////////////////////////////////
Interpolate(const SColor & v1,const SColor & v2,float fCoeff,SColor * pRes)126 inline void Interpolate( const SColor &v1, const SColor &v2, float fCoeff, SColor *pRes )
127 {
128     Interpolate( v1.r, v2.r, fCoeff, &pRes->r );
129     Interpolate( v1.g, v2.g, fCoeff, &pRes->g );
130     Interpolate( v1.b, v2.b, fCoeff, &pRes->b );
131     Interpolate( v1.a, v2.a, fCoeff, &pRes->a );
132 }
133 ////////////////////////////////////////////////////////////////////////////////////////////////////
Interpolate(const SScale & v1,const SScale & v2,float fCoeff,SScale * pRes)134 inline void Interpolate( const SScale &v1, const SScale &v2, float fCoeff, SScale *pRes )
135 {
136     Interpolate( v1.x, v2.x, fCoeff, &pRes->x );
137     Interpolate( v1.y, v2.y, fCoeff, &pRes->y );
138 }
139 ////////////////////////////////////////////////////////////////////////////////////////////////////
140 template <class T>
141 class TKey
142 {
143 public:
144     T value;
145     int nTime;
146 };
147 ////////////////////////////////////////////////////////////////////////////////////////////////////
148 template <class T>
149 class TKeyTrack
150 {
151 public:
152     std::vector<TKey<T> > keys;
153 
154 protected:
GetValueBinSearch(float fTime,T * pRes)155     void GetValueBinSearch( float fTime, T *pRes ) const
156     {
157         int nLeft = 0, nRight = keys.size() - 1;
158         int nTime = int( fTime - 0.5f );
159         while( nLeft - nRight > 1 )
160         {
161             int nTemp = ( nLeft + nRight ) / 2;
162             if ( keys[nTemp].nTime <= nTime )
163                 nLeft = nTemp;
164             else
165                 nRight = nTemp;
166         }
167         ////
168         const TKey<T> &end = keys[nRight];
169         const TKey<T> &start = keys[nLeft];
170         float fCoeff = ( fTime - start.nTime ) / ( end.nTime - start.nTime );
171         Interpolate( start.value, end.value, fCoeff, pRes );
172     }
173 
174 public:
GetValue(float fTime,T * pRes)175     void GetValue( float fTime, T *pRes ) const
176     {
177         if ( keys.size() == 1 )
178             *pRes = keys[0].value;
179         else
180             GetValueBinSearch( fTime, pRes );
181     }
182 };
183 ////////////////////////////////////////////////////////////////////////////////////////////////////
184 struct SParticle
185 {
186     int nEndTime;
187     int nStartTime;
188     TKeyTrack<int> sprite;
189     TKeyTrack<SPos> pos;
190     TKeyTrack<SColor> color;
191     TKeyTrack<SScale> scale;
192     TKeyTrack<float> rotation;
193 };
194 ////////////////////////////////////////////////////////////////////////////////////////////////////
195 // Particles
196 ////////////////////////////////////////////////////////////////////////////////////////////////////
197 class Particles
198 {
199 private:
200     CParticlesData data;
201     ////
202     int nFrames;
203     std::vector<SParticle> particleTracks;
204 
205 protected:
206     MStatus ExportFrame( MDagPath &dagPath, int nFrame );
207     MStatus FinalizeData( int nMinFrame, int nMaxFrame );
208 
209 public:
210     Particles();
211     virtual ~Particles();
212 
213     MStatus load( MDagPath& dagPath, ParamList& params );
214     MStatus writeToXML( ParamList& params );
215     void clear();
216 };
217 ////////////////////////////////////////////////////////////////////////////////////////////////////
218 }; // end of namespace
219 ////////////////////////////////////////////////////////////////////////////////////////////////////
220 #endif