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/>.
19 #include "ps_initial_pos.h"
21 #include "nel/3d/particle_system.h"
22 #include "nel/3d/ps_located.h"
23 #include "nel/3d/ps_edit.h"
24 #include "nel/3d/ps_emitter.h"
27 // CPSInitialPos implementation //
28 ///////////////////////////////////
29 //******************************************************************************************************
30 void CPSInitialPos::reset()
32 _InitInfoVect
.clear();
33 _RotScaleInfoVect
.clear();
34 _InitialSizeVect
.clear();
37 //******************************************************************************************************
38 void CPSInitialPos::copySystemInitialPos(NL3D::CParticleSystem
*ps
)
42 uint32 nbLocated
= ps
->getNbProcess();
45 for(uint32 k
= 0; k
< nbLocated
; ++k
)
48 NL3D::CPSLocated
*loc
= dynamic_cast<NL3D::CPSLocated
*>(ps
->getProcess(k
));
52 _InitialSizeVect
.push_back(std::make_pair(loc
, loc
->getSize()) );
53 for (uint32 l
= 0; l
< loc
->getSize(); ++l
)
56 CInitPSInstanceInfo ii
;
59 ii
.Pos
= loc
->getPos()[l
];
60 ii
.Speed
= loc
->getSpeed()[l
];
61 _InitInfoVect
.push_back(ii
);
63 for (uint32 m
= 0; m
< loc
->getNbBoundObjects(); ++m
)
66 if (dynamic_cast<NL3D::IPSMover
*>(loc
->getBoundObject(m
)))
70 rsi
.LB
= loc
->getBoundObject(m
);
72 rsi
.Psm
= dynamic_cast<NL3D::IPSMover
*>(loc
->getBoundObject(m
));
73 rsi
.Scale
= rsi
.Psm
->getScale(l
);
74 rsi
.Rot
= rsi
.Psm
->getMatrix(l
);
75 _RotScaleInfoVect
.push_back(rsi
);
84 // PRIVATE : a predicate used in CPSInitialPos::removeLocated
85 struct CRemoveLocatedPred
87 NL3D::CPSLocated
*Loc
;
90 // private : predicate to remove located from a CPSInitialPos::TInitialLocatedSizeVect vector
91 struct CRemoveLocatedFromLocatedSizePred
: public CRemoveLocatedPred
93 bool operator()(const std::pair
<NL3D::CPSLocated
*, uint32
> &value
) { return Loc
== value
.first
; }
96 // private : predicate to remove located from a PSInitialPos::CInitPSInstanceInfo vector
97 struct CRemoveLocatedFromInitPSInstanceInfoVectPred
: public CRemoveLocatedPred
99 bool operator()(const CPSInitialPos::CInitPSInstanceInfo
&value
) { return value
.Loc
== Loc
; }
102 // private : predicate to remove located from a PSInitialPos::CRotScaleInfo vector
103 struct CRemoveLocatedFromRotScaleInfoVectPred
: public CRemoveLocatedPred
105 bool operator()(const CPSInitialPos::CRotScaleInfo
&value
) { return value
.Loc
== Loc
; }
108 // private : predicate to remove located bindable pointers in a TRotScaleInfoVect vect
109 struct CRemoveLocatedBindableFromRotScaleInfoVectPred
111 // the located bindable taht has been removed
112 NL3D::CPSLocatedBindable
*LB
;
113 bool operator()(const CPSInitialPos::CRotScaleInfo
&value
) { return value
.LB
== LB
; }
116 //******************************************************************************************************
117 void CPSInitialPos::removeLocated(NL3D::CPSLocated
*loc
)
119 // in each container, we delete every element that has a pointer over lthe located loc
120 // , by using the dedicated predicate.
122 CRemoveLocatedFromLocatedSizePred p
;
124 _InitialSizeVect
.erase(std::remove_if(_InitialSizeVect
.begin(), _InitialSizeVect
.end(), p
)
125 , _InitialSizeVect
.end() );
127 CRemoveLocatedFromInitPSInstanceInfoVectPred p2
;
129 _InitInfoVect
.erase(std::remove_if(_InitInfoVect
.begin(), _InitInfoVect
.end(), p2
)
130 , _InitInfoVect
.end());
132 CRemoveLocatedFromRotScaleInfoVectPred p3
;
134 _RotScaleInfoVect
.erase(std::remove_if(_RotScaleInfoVect
.begin(), _RotScaleInfoVect
.end(), p3
)
135 , _RotScaleInfoVect
.end());
139 //******************************************************************************************************
140 void CPSInitialPos::removeLocatedBindable(NL3D::CPSLocatedBindable
*lb
)
142 CRemoveLocatedBindableFromRotScaleInfoVectPred p
;
144 _RotScaleInfoVect
.erase(std::remove_if(_RotScaleInfoVect
.begin(), _RotScaleInfoVect
.end(), p
), _RotScaleInfoVect
.end() );
147 //******************************************************************************************************
148 // reinitialize the system with its initial instances positions
149 void CPSInitialPos::restoreSystem()
151 nlassert(_PS
); // no system has been memorized yet
153 // delete all the instance of the system
154 NL3D::CPSEmitter::setBypassEmitOnDeath(true);
155 for (uint k
= 0; k
< _PS
->getNbProcess(); ++k
)
157 NL3D::CPSLocated
*loc
= dynamic_cast<NL3D::CPSLocated
*>(_PS
->getProcess(k
));
160 while (loc
->getSize())
162 loc
->deleteElement(0);
165 nlassert(loc
->getSize() == 0);
168 // recreate the initial number of instances
169 for (TInitialLocatedSizeVect ::iterator itSize
= _InitialSizeVect
.begin(); itSize
!= _InitialSizeVect
.end(); ++itSize
)
171 // nlassert(itSize->first->getSize() == 0)
172 for (uint l
= 0; l
< itSize
->second
; ++l
)
174 itSize
->first
->newElement(NLMISC::CVector::Null
, NLMISC::CVector::Null
, NULL
, 0, itSize
->first
->getMatrixMode(), 0.f
);
177 uint realSize
= itSize
->first
->getSize();
178 uint size
= itSize
->second
;
181 NL3D::CPSEmitter::setBypassEmitOnDeath(false);
182 for (TInitInfoVect::iterator it
= _InitInfoVect
.begin(); it
!= _InitInfoVect
.end(); ++it
)
184 if (it
->Index
< it
->Loc
->getSize())
186 it
->Loc
->getPos()[it
->Index
] = it
->Pos
;
187 it
->Loc
->getSpeed()[it
->Index
] = it
->Speed
;
188 // If the particle has parametric infos attach, restore them too
189 if (it
->Loc
->isParametricMotionEnabled())
191 it
->Loc
->getParametricInfos()[it
->Index
].Pos
= it
->Pos
;
192 it
->Loc
->getParametricInfos()[it
->Index
].Speed
= it
->Speed
;
193 it
->Loc
->getParametricInfos()[it
->Index
].Date
= 0.f
;
197 for (TRotScaleInfoVect::iterator it2
= _RotScaleInfoVect
.begin(); it2
!= _RotScaleInfoVect
.end(); ++it2
)
199 if (it2
->Index
< it2
->Loc
->getSize())
201 it2
->Psm
->setMatrix(it2
->Index
, it2
->Rot
);
202 if (it2
->Psm
->supportNonUniformScaling())
204 it2
->Psm
->setScale(it2
->Index
, it2
->Scale
);
206 else if (it2
->Psm
->supportUniformScaling())
208 it2
->Psm
->setScale(it2
->Index
, it2
->Scale
.x
);