1 // NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
2 // Copyright (C) 2010 Winch Gate Property Limited
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.
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/>.
20 #include "nel/3d/ps_plane_basis_maker.h"
21 #include "nel/3d/ps_register_plane_basis_attribs.h"
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
,
50 void *tab
, uint32 stride
,
52 bool enableNoCopy
/* = false*/,
53 uint32 srcStep
/*= (1 << 16)*/,
54 bool forceClampEntry
/* = false */
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
)
68 *(CPlaneBasis
*) ptDat
= CPlaneBasis(*speedIt
);
72 while (speedIt
!= endSpeedIt
);
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
);
85 while (speedIt
!= endSpeedIt
);
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
);
98 while (speedIt
!= endSpeedIt
);
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
);
111 while (speedIt
!= endSpeedIt
);
114 nlstop
; // unknow projection mode
121 uint32 fpIndex
= startIndex
* srcStep
;
122 const TPSAttribVector::const_iterator speedIt
= loc
->getSpeed().begin();
123 uint8
*ptDat
= (uint8
*) tab
;
124 switch(_ProjectionPlane
)
129 *(CPlaneBasis
*) ptDat
= CPlaneBasis(*(speedIt
+ (fpIndex
>> 16)));
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
);
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
);
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
);
174 nlstop
; // unknow projection mode
181 ///============================================================================
182 void CPSPlaneBasisFollowSpeed::make4(CPSLocated
*loc
,
187 uint32 srcStep
/*= (1 << 16)*/
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
;
201 *(CPlaneBasis
*) (ptDat
+ stride
) = *(CPlaneBasis
*) ptDat
;
203 *(CPlaneBasis
*) (ptDat
+ stride
) = *(CPlaneBasis
*) ptDat
;
204 ptDat
+= stride
<< 1;
207 while (speedIt
!= endSpeedIt
);
211 uint32 fpIndex
= startIndex
* srcStep
;
212 const TPSAttribVector::const_iterator speedIt
= loc
->getSpeed().begin();
213 uint8
*ptDat
= (uint8
*) tab
;
216 *(CPlaneBasis
*) ptDat
= CPlaneBasis(*(speedIt
+ (fpIndex
>> 16)));
217 *(CPlaneBasis
*) (ptDat
+ stride
) = *(CPlaneBasis
*) ptDat
;
219 *(CPlaneBasis
*) (ptDat
+ stride
) = *(CPlaneBasis
*) ptDat
;
221 *(CPlaneBasis
*) (ptDat
+ stride
) = *(CPlaneBasis
*) ptDat
;
222 ptDat
+= stride
<< 1;
228 ///============================================================================
229 void CPSPlaneBasisFollowSpeed::makeN(CPSLocated
*loc
,
235 uint32 srcStep
/*= (1 << 16) */
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
;
248 *(CPlaneBasis
*) ptDat
= CPlaneBasis(*speedIt
);
254 *(CPlaneBasis
*) (ptDat
+ stride
) = *(CPlaneBasis
*) ptDat
;
262 while (speedIt
!= endSpeedIt
);
266 uint32 fpIndex
= startIndex
* srcStep
;
267 nlassert(nbReplicate
> 1);
268 const TPSAttribVector::const_iterator speedIt
= loc
->getSpeed().begin();
269 uint8
*ptDat
= (uint8
*) tab
;
273 *(CPlaneBasis
*) ptDat
= CPlaneBasis(*(speedIt
+ (fpIndex
>> 16)));
279 *(CPlaneBasis
*) (ptDat
+ stride
) = *(CPlaneBasis
*) ptDat
;
291 /////////////////////////////////////////////
292 // CSpinnerFunctor implementation //
293 /////////////////////////////////////////////
296 ///============================================================================
297 CSpinnerFunctor::CSpinnerFunctor() : _NbSamples(0), _Axis(NLMISC::CVector::K
)
301 ///============================================================================
302 void CSpinnerFunctor::setAxis(const NLMISC::CVector
&axis
)
308 ///============================================================================
309 void CSpinnerFunctor::setNumSamples(uint32 nbSamples
)
311 nlassert(nbSamples
> 0);
312 _NbSamples
= nbSamples
;
316 ///============================================================================
317 uint32
CSpinnerFunctor::getNumSamples(void) const
322 ///============================================================================
323 void CSpinnerFunctor::serial(NLMISC::IStream
&f
)
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);
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
,
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
);