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 | #include <hash_map> |
---|
20 | #include <maya/MDagPath.h> |
---|
21 | #include "paramList.h" |
---|
22 | #include "mayaExportLayer.h" |
---|
23 | #pragma warning(disable: 4996) |
---|
24 | |
---|
25 | namespace OgreMayaExporter |
---|
26 | { |
---|
27 | //////////////////////////////////////////////////////////////////////////////////////////////////// |
---|
28 | inline float fabs( float fVal ) { return ::fabs( fVal ); } |
---|
29 | //////////////////////////////////////////////////////////////////////////////////////////////////// |
---|
30 | struct SPos |
---|
31 | { |
---|
32 | float x; |
---|
33 | float y; |
---|
34 | float z; |
---|
35 | |
---|
36 | SPos(): x(0), y(0), z(0) {} |
---|
37 | SPos( float _x, float _y, float _z ): x(_x), y(_y), z(_z) {} |
---|
38 | }; |
---|
39 | inline const SPos operator-( const SPos &in ) { return SPos( -in.x, -in.y, -in.z ); } |
---|
40 | inline const SPos operator+( const SPos &in1, const SPos &in2 ) { return SPos( in1.x + in2.x, in1.y + in2.y, in1.z + in2.z ); } |
---|
41 | inline const SPos operator-( const SPos &in1, const SPos &in2 ) { return SPos( in1.x - in2.x, in1.y - in2.y, in1.z - in2.z ); } |
---|
42 | inline float fabs2( const SPos &in ) { return in.x * in.x + in.y * in.y + in.z * in.z; } |
---|
43 | inline float fabs( const SPos &in ) { return float( sqrt( fabs2( in ) ) ); } |
---|
44 | //////////////////////////////////////////////////////////////////////////////////////////////////// |
---|
45 | struct SColor |
---|
46 | { |
---|
47 | union |
---|
48 | { |
---|
49 | struct |
---|
50 | { |
---|
51 | float x, y, z, w; |
---|
52 | }; |
---|
53 | struct |
---|
54 | { |
---|
55 | float r, g, b, a; |
---|
56 | }; |
---|
57 | }; |
---|
58 | |
---|
59 | SColor(): r(0), g(0), b(0), a(0) {} |
---|
60 | SColor( float _r, float _g, float _b, float _a ): r(_r), g(_g), b(_b), a(_a) {} |
---|
61 | }; |
---|
62 | inline const SColor operator-( const SColor &in1) { return SColor( -in1.x, -in1.y, -in1.z, -in1.w ); } |
---|
63 | 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 ); } |
---|
64 | 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 ); } |
---|
65 | inline float fabs2( const SColor &in ) { return in.x * in.x + in.y * in.y + in.z * in.z + in.w * in.w; } |
---|
66 | inline float fabs( const SColor &in ) { return float( sqrt( fabs2( in ) ) ); } |
---|
67 | //////////////////////////////////////////////////////////////////////////////////////////////////// |
---|
68 | struct SScale |
---|
69 | { |
---|
70 | float x; |
---|
71 | float y; |
---|
72 | |
---|
73 | SScale(): x(0), y(0) {} |
---|
74 | SScale( float _x, float _y ): x(_x), y(_y) {} |
---|
75 | }; |
---|
76 | inline const SScale operator+( const SScale &in1, const SScale &in2 ) { return SScale( in1.x + in2.x, in1.y + in2.y ); } |
---|
77 | inline const SScale operator-( const SScale &in1, const SScale &in2 ) { return SScale( in1.x - in2.x, in1.y - in2.y ); } |
---|
78 | inline float fabs2( const SScale &in ) { return in.x * in.x + in.y * in.y; } |
---|
79 | inline float fabs( const SScale &in ) { return float( sqrt( fabs2( in ) ) ); } |
---|
80 | //////////////////////////////////////////////////////////////////////////////////////////////////// |
---|
81 | struct SParticleData |
---|
82 | { |
---|
83 | int nFrame; |
---|
84 | int nSprite; |
---|
85 | SPos pos; |
---|
86 | SColor color; |
---|
87 | SScale scale; |
---|
88 | float fRotation; |
---|
89 | //// |
---|
90 | SParticleData(): nFrame( 0 ), nSprite( 0 ), pos( 0, 0, 0 ), color( 1, 1, 1, 1 ), scale( 1, 1 ), fRotation( 0 ) {} |
---|
91 | }; |
---|
92 | typedef std::vector<SParticleData> CParticlesTrack; |
---|
93 | typedef stdext::hash_map<int, CParticlesTrack> CParticlesData; |
---|
94 | //////////////////////////////////////////////////////////////////////////////////////////////////// |
---|
95 | template <class T> |
---|
96 | inline void Interpolate( const T &v1, const T &v2, float fCoeff, T *pRes ) |
---|
97 | { |
---|
98 | pRes->Interpolate( v1, v2, fCoeff ); |
---|
99 | } |
---|
100 | //////////////////////////////////////////////////////////////////////////////////////////////////// |
---|
101 | inline void Interpolate( const int &v1, const int &v2, float fCoeff, int *pRes ) |
---|
102 | { |
---|
103 | *pRes = v1; |
---|
104 | } |
---|
105 | //////////////////////////////////////////////////////////////////////////////////////////////////// |
---|
106 | inline void Interpolate( const float &v1, const float &v2, float fCoeff, float *pRes ) |
---|
107 | { |
---|
108 | *pRes = ( 1 - fCoeff ) * v1 + fCoeff * v2; |
---|
109 | } |
---|
110 | //////////////////////////////////////////////////////////////////////////////////////////////////// |
---|
111 | inline void Interpolate( const SPos &v1, const SPos &v2, float fCoeff, SPos *pRes ) |
---|
112 | { |
---|
113 | Interpolate( v1.x, v2.x, fCoeff, &pRes->x ); |
---|
114 | Interpolate( v1.y, v2.y, fCoeff, &pRes->y ); |
---|
115 | Interpolate( v1.z, v2.z, fCoeff, &pRes->z ); |
---|
116 | } |
---|
117 | //////////////////////////////////////////////////////////////////////////////////////////////////// |
---|
118 | inline void Interpolate( const SColor &v1, const SColor &v2, float fCoeff, SColor *pRes ) |
---|
119 | { |
---|
120 | Interpolate( v1.r, v2.r, fCoeff, &pRes->r ); |
---|
121 | Interpolate( v1.g, v2.g, fCoeff, &pRes->g ); |
---|
122 | Interpolate( v1.b, v2.b, fCoeff, &pRes->b ); |
---|
123 | Interpolate( v1.a, v2.a, fCoeff, &pRes->a ); |
---|
124 | } |
---|
125 | //////////////////////////////////////////////////////////////////////////////////////////////////// |
---|
126 | inline void Interpolate( const SScale &v1, const SScale &v2, float fCoeff, SScale *pRes ) |
---|
127 | { |
---|
128 | Interpolate( v1.x, v2.x, fCoeff, &pRes->x ); |
---|
129 | Interpolate( v1.y, v2.y, fCoeff, &pRes->y ); |
---|
130 | } |
---|
131 | //////////////////////////////////////////////////////////////////////////////////////////////////// |
---|
132 | template <class T> |
---|
133 | class TKey |
---|
134 | { |
---|
135 | public: |
---|
136 | T value; |
---|
137 | int nTime; |
---|
138 | }; |
---|
139 | //////////////////////////////////////////////////////////////////////////////////////////////////// |
---|
140 | template <class T> |
---|
141 | class TKeyTrack |
---|
142 | { |
---|
143 | public: |
---|
144 | std::vector<TKey<T> > keys; |
---|
145 | |
---|
146 | protected: |
---|
147 | void GetValueBinSearch( float fTime, T *pRes ) const |
---|
148 | { |
---|
149 | int nLeft = 0, nRight = keys.size() - 1; |
---|
150 | int nTime = int( fTime - 0.5f ); |
---|
151 | while( nLeft - nRight > 1 ) |
---|
152 | { |
---|
153 | int nTemp = ( nLeft + nRight ) / 2; |
---|
154 | if ( keys[nTemp].nTime <= nTime ) |
---|
155 | nLeft = nTemp; |
---|
156 | else |
---|
157 | nRight = nTemp; |
---|
158 | } |
---|
159 | //// |
---|
160 | const TKey<T> &end = keys[nRight]; |
---|
161 | const TKey<T> &start = keys[nLeft]; |
---|
162 | float fCoeff = ( fTime - start.nTime ) / ( end.nTime - start.nTime ); |
---|
163 | Interpolate( start.value, end.value, fCoeff, pRes ); |
---|
164 | } |
---|
165 | |
---|
166 | public: |
---|
167 | void GetValue( float fTime, T *pRes ) const |
---|
168 | { |
---|
169 | if ( keys.size() == 1 ) |
---|
170 | *pRes = keys[0].value; |
---|
171 | else |
---|
172 | GetValueBinSearch( fTime, pRes ); |
---|
173 | } |
---|
174 | }; |
---|
175 | //////////////////////////////////////////////////////////////////////////////////////////////////// |
---|
176 | struct SParticle |
---|
177 | { |
---|
178 | int nEndTime; |
---|
179 | int nStartTime; |
---|
180 | TKeyTrack<int> sprite; |
---|
181 | TKeyTrack<SPos> pos; |
---|
182 | TKeyTrack<SColor> color; |
---|
183 | TKeyTrack<SScale> scale; |
---|
184 | TKeyTrack<float> rotation; |
---|
185 | }; |
---|
186 | //////////////////////////////////////////////////////////////////////////////////////////////////// |
---|
187 | // Particles |
---|
188 | //////////////////////////////////////////////////////////////////////////////////////////////////// |
---|
189 | class Particles |
---|
190 | { |
---|
191 | private: |
---|
192 | CParticlesData data; |
---|
193 | //// |
---|
194 | int nFrames; |
---|
195 | std::vector<SParticle> particleTracks; |
---|
196 | |
---|
197 | protected: |
---|
198 | MStatus ExportFrame( MDagPath &dagPath, int nFrame ); |
---|
199 | MStatus FinalizeData( int nMinFrame, int nMaxFrame ); |
---|
200 | |
---|
201 | public: |
---|
202 | Particles(); |
---|
203 | virtual ~Particles(); |
---|
204 | |
---|
205 | MStatus load( MDagPath& dagPath, ParamList& params ); |
---|
206 | MStatus writeToXML( ParamList& params ); |
---|
207 | void clear(); |
---|
208 | }; |
---|
209 | //////////////////////////////////////////////////////////////////////////////////////////////////// |
---|
210 | }; // end of namespace |
---|
211 | //////////////////////////////////////////////////////////////////////////////////////////////////// |
---|
212 | #endif |
---|