Merge branch 'main/rendor-staging' into fixes
[ryzomcore.git] / nel / src / 3d / ps_plane_basis_maker.cpp
blob05df5821b05ecec3c2e2e8ad98f06deaf8d98867
1 // NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
2 // Copyright (C) 2010 Winch Gate Property Limited
3 //
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU Affero General Public License as
6 // published by the Free Software Foundation, either version 3 of the
7 // License, or (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU Affero General Public License for more details.
14 // You should have received a copy of the GNU Affero General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
17 #include "std3d.h"
20 #include "nel/3d/ps_plane_basis_maker.h"
21 #include "nel/3d/ps_register_plane_basis_attribs.h"
23 #ifdef DEBUG_NEW
24 #define new DEBUG_NEW
25 #endif
27 namespace NL3D
31 CPlaneBasis CPSPlaneBasisGradient::DefaultPlaneBasisTab[] = { CPlaneBasis(NLMISC::CVector::I), CPlaneBasis(NLMISC::CVector::J) };
33 /////////////////////////////////////////////
34 // CPSPlaneBasisFollowSpeed implementation //
35 /////////////////////////////////////////////
37 ///============================================================================
38 CPlaneBasis CPSPlaneBasisFollowSpeed::get(CPSLocated *loc, uint32 index)
40 return (CPlaneBasis(loc->getSpeed()[index]));
42 CPlaneBasis CPSPlaneBasisFollowSpeed::get(const CPSEmitterInfo &infos)
44 return (CPlaneBasis(infos.Speed));
47 ///============================================================================
48 void *CPSPlaneBasisFollowSpeed::make(CPSLocated *loc,
49 uint32 startIndex,
50 void *tab, uint32 stride,
51 uint32 numAttrib,
52 bool enableNoCopy /* = false*/,
53 uint32 srcStep /*= (1 << 16)*/,
54 bool forceClampEntry /* = false */
55 ) const
57 nlassert(numAttrib);
58 if (srcStep == (1 << 16))
60 TPSAttribVector::const_iterator speedIt = loc->getSpeed().begin() + startIndex
61 , endSpeedIt = loc->getSpeed().begin() + startIndex + numAttrib;
62 uint8 *ptDat = (uint8 *) tab;
63 switch(_ProjectionPlane)
65 case NoProjection:
68 *(CPlaneBasis *) ptDat = CPlaneBasis(*speedIt);
69 ++ speedIt;
70 ptDat += stride;
72 while (speedIt != endSpeedIt);
73 break;
74 case XY:
77 float norm = sqrtf(speedIt->x * speedIt->x + speedIt->y * speedIt->y);
78 float invNorm = (norm != 0.f) ? 1.f / norm : 0.f;
79 CPlaneBasis &pb = *(CPlaneBasis *) ptDat;
80 pb.X.set(invNorm * speedIt->x, invNorm * speedIt->y, 0.f);
81 pb.Y.set(- pb.X.y, pb.X.x, 0.f);
82 ++ speedIt;
83 ptDat += stride;
85 while (speedIt != endSpeedIt);
86 break;
87 case XZ:
90 float norm = sqrtf(speedIt->x * speedIt->x + speedIt->z * speedIt->z);
91 float invNorm = (norm != 0.f) ? 1.f / norm : 0.f;
92 CPlaneBasis &pb = *(CPlaneBasis *) ptDat;
93 pb.X.set(invNorm * speedIt->x, 0.f, invNorm * speedIt->z);
94 pb.Y.set(- pb.X.z, 0.f, pb.X.x);
95 ++ speedIt;
96 ptDat += stride;
98 while (speedIt != endSpeedIt);
99 break;
100 case YZ:
103 float norm = sqrtf(speedIt->y * speedIt->y + speedIt->z * speedIt->z);
104 float invNorm = (norm != 0.f) ? 1.f / norm : 0.f;
105 CPlaneBasis &pb = *(CPlaneBasis *) ptDat;
106 pb.X.set(0.f, invNorm * speedIt->y, invNorm * speedIt->z);
107 pb.Y.set(0.f, - pb.X.z, pb.X.y);
108 ++ speedIt;
109 ptDat += stride;
111 while (speedIt != endSpeedIt);
112 break;
113 default:
114 nlstop; // unknow projection mode
115 break;
117 return tab;
119 else
121 uint32 fpIndex = startIndex * srcStep;
122 const TPSAttribVector::const_iterator speedIt = loc->getSpeed().begin();
123 uint8 *ptDat = (uint8 *) tab;
124 switch(_ProjectionPlane)
126 case NoProjection:
127 while (numAttrib --)
129 *(CPlaneBasis *) ptDat = CPlaneBasis(*(speedIt + (fpIndex >> 16)));
130 ptDat += stride;
131 fpIndex += srcStep;
133 break;
134 case XY:
135 while (numAttrib --)
137 const CVector *speedVect = &(*(speedIt + (fpIndex >> 16)));
138 float norm = sqrtf(speedVect->x * speedVect->x + speedVect->y * speedVect->y);
139 float invNorm = (norm != 0.f) ? 1.f / norm : 0.f;
140 CPlaneBasis &pb = *(CPlaneBasis *) ptDat;
141 pb.X.set(invNorm * speedVect->x, invNorm * speedVect->y, 0.f);
142 pb.Y.set(- pb.X.y, pb.X.x, 0.f);
143 ptDat += stride;
144 fpIndex += srcStep;
146 break;
147 case XZ:
148 while (numAttrib --)
150 const CVector *speedVect = &(*(speedIt + (fpIndex >> 16)));
151 float norm = sqrtf(speedVect->x * speedVect->x + speedVect->z * speedVect->z);
152 float invNorm = (norm != 0.f) ? 1.f / norm : 0.f;
153 CPlaneBasis &pb = *(CPlaneBasis *) ptDat;
154 pb.X.set(invNorm * speedVect->x, 0.f, invNorm * speedVect->z);
155 pb.Y.set(- pb.X.z, 0.f, pb.X.x);
156 ptDat += stride;
157 fpIndex += srcStep;
159 break;
160 case YZ:
161 while (numAttrib --)
163 const CVector *speedVect = &(*(speedIt + (fpIndex >> 16)));
164 float norm = sqrtf(speedVect->y * speedVect->y + speedVect->z * speedVect->z);
165 float invNorm = (norm != 0.f) ? 1.f / norm : 0.f;
166 CPlaneBasis &pb = *(CPlaneBasis *) ptDat;
167 pb.X.set(0.f, invNorm * speedVect->y, invNorm * speedVect->z);
168 pb.Y.set(0.f, - pb.X.z, pb.X.y);
169 ptDat += stride;
170 fpIndex += srcStep;
172 break;
173 default:
174 nlstop; // unknow projection mode
175 break;
177 return tab;
181 ///============================================================================
182 void CPSPlaneBasisFollowSpeed::make4(CPSLocated *loc,
183 uint32 startIndex,
184 void *tab,
185 uint32 stride,
186 uint32 numAttrib,
187 uint32 srcStep /*= (1 << 16)*/
188 ) const
190 nlassert(numAttrib);
191 if (srcStep == (1 << 16))
193 TPSAttribVector::const_iterator speedIt = loc->getSpeed().begin() + startIndex
194 , endSpeedIt = loc->getSpeed().begin() + startIndex + numAttrib;
195 uint8 *ptDat = (uint8 *) tab;
198 *(CPlaneBasis *) ptDat = CPlaneBasis(*speedIt);
199 *(CPlaneBasis *) (ptDat + stride) = *(CPlaneBasis *) ptDat;
200 ptDat += stride;
201 *(CPlaneBasis *) (ptDat + stride) = *(CPlaneBasis *) ptDat;
202 ptDat += stride;
203 *(CPlaneBasis *) (ptDat + stride) = *(CPlaneBasis *) ptDat;
204 ptDat += stride << 1;
205 ++ speedIt;
207 while (speedIt != endSpeedIt);
209 else
211 uint32 fpIndex = startIndex * srcStep;
212 const TPSAttribVector::const_iterator speedIt = loc->getSpeed().begin();
213 uint8 *ptDat = (uint8 *) tab;
214 while (numAttrib --)
216 *(CPlaneBasis *) ptDat = CPlaneBasis(*(speedIt + (fpIndex >> 16)));
217 *(CPlaneBasis *) (ptDat + stride) = *(CPlaneBasis *) ptDat;
218 ptDat += stride;
219 *(CPlaneBasis *) (ptDat + stride) = *(CPlaneBasis *) ptDat;
220 ptDat += stride;
221 *(CPlaneBasis *) (ptDat + stride) = *(CPlaneBasis *) ptDat;
222 ptDat += stride << 1;
223 fpIndex += srcStep;
228 ///============================================================================
229 void CPSPlaneBasisFollowSpeed::makeN(CPSLocated *loc,
230 uint32 startIndex,
231 void *tab,
232 uint32 stride,
233 uint32 numAttrib,
234 uint32 nbReplicate,
235 uint32 srcStep /*= (1 << 16) */
236 ) const
238 nlassert(numAttrib);
239 if (srcStep == (1 << 16))
241 nlassert(nbReplicate > 1);
242 TPSAttribVector::const_iterator speedIt = loc->getSpeed().begin() + startIndex
243 , endSpeedIt = loc->getSpeed().begin() + startIndex + numAttrib;
244 uint8 *ptDat = (uint8 *) tab;
245 uint k;
248 *(CPlaneBasis *) ptDat = CPlaneBasis(*speedIt);
250 k = nbReplicate - 1;
254 *(CPlaneBasis *) (ptDat + stride) = *(CPlaneBasis *) ptDat;
255 ptDat += stride;
257 while (--k);
258 ptDat += stride;
260 ++ speedIt;
262 while (speedIt != endSpeedIt);
264 else
266 uint32 fpIndex = startIndex * srcStep;
267 nlassert(nbReplicate > 1);
268 const TPSAttribVector::const_iterator speedIt = loc->getSpeed().begin();
269 uint8 *ptDat = (uint8 *) tab;
270 uint k;
271 while (numAttrib --)
273 *(CPlaneBasis *) ptDat = CPlaneBasis(*(speedIt + (fpIndex >> 16)));
275 k = nbReplicate - 1;
279 *(CPlaneBasis *) (ptDat + stride) = *(CPlaneBasis *) ptDat;
280 ptDat += stride;
282 while (--k);
283 ptDat += stride;
285 fpIndex += srcStep;
291 /////////////////////////////////////////////
292 // CSpinnerFunctor implementation //
293 /////////////////////////////////////////////
296 ///============================================================================
297 CSpinnerFunctor::CSpinnerFunctor() : _NbSamples(0), _Axis(NLMISC::CVector::K)
301 ///============================================================================
302 void CSpinnerFunctor::setAxis(const NLMISC::CVector &axis)
304 _Axis = axis;
305 updateSamples();
308 ///============================================================================
309 void CSpinnerFunctor::setNumSamples(uint32 nbSamples)
311 nlassert(nbSamples > 0);
312 _NbSamples = nbSamples;
313 updateSamples();
316 ///============================================================================
317 uint32 CSpinnerFunctor::getNumSamples(void) const
319 return _NbSamples;
322 ///============================================================================
323 void CSpinnerFunctor::serial(NLMISC::IStream &f)
325 f.serialVersion(1);
326 f.serial(_Axis, _NbSamples);
327 if (f.isReading()) updateSamples();
330 ///============================================================================
331 void CSpinnerFunctor::updateSamples(void)
333 if (_NbSamples == 0) return;
334 // compute step between each angle
335 const float angInc = (float) (2.f * NLMISC::Pi / _NbSamples);
336 _PBTab.resize(_NbSamples + 1);
337 NLMISC::CMatrix mat;
338 CPSUtil::buildSchmidtBasis(_Axis, mat);
339 NLMISC::CVector I = mat.getI();
340 NLMISC::CVector J = mat.getJ();
341 // compute basis for rotation
342 for (uint32 k = 0; k < _NbSamples; ++k)
344 float ca = cosf(k * angInc);
345 float sa = sinf(k * angInc);
346 _PBTab[k].X.set(ca * I.x + sa * J.x,
347 ca * I.y + sa * J.y,
348 ca * I.z + sa * J.z);
350 _PBTab[k].Y.set(- sa * I.x + ca * J.x,
351 - sa * I.y + ca * J.y,
352 - sa * I.z + ca * J.z);
356 ///============================================================================
357 void PSRegisterPlaneBasisAttribs()
359 NLMISC_REGISTER_CLASS(CPSPlaneBasisBlender);
360 NLMISC_REGISTER_CLASS(CPSPlaneBasisGradient);
361 NLMISC_REGISTER_CLASS(CPSPlaneBasisMemory);
362 NLMISC_REGISTER_CLASS(CPSPlaneBasisBinOp);
363 NLMISC_REGISTER_CLASS(CPSPlaneBasisFollowSpeed);
364 NLMISC_REGISTER_CLASS(CPSBasisSpinner);
367 } // NL3D