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