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 "nel/pacs/move_primitive.h"
20 #include "nel/pacs/collision_desc.h"
21 #include "nel/pacs/move_element.h"
22 #include "nel/misc/hierarchical_timer.h"
24 using namespace NLMISC
;
26 H_AUTO_DECL ( NLPACS_Get_Global_Position
)
27 H_AUTO_DECL ( NLPACS_Set_Global_Position
)
28 H_AUTO_DECL ( NLPACS_Set_UGlobal_Position
)
29 H_AUTO_DECL ( NLPACS_Move
)
30 #define NLPACS_HAUTO_GET_GLOBAL_POSITION H_AUTO_USE ( NLPACS_Get_Global_Position )
31 #define NLPACS_HAUTO_SET_GLOBAL_POSITION H_AUTO_USE ( NLPACS_Set_Global_Position )
32 #define NLPACS_HAUTO_SET_UGLOBAL_POSITION H_AUTO_USE ( NLPACS_Set_UGlobal_Position )
33 #define NLPACS_HAUTO_MOVE H_AUTO_USE ( NLPACS_Move )
38 // ***************************************************************************
40 CMovePrimitive::CMovePrimitive (CMoveContainer
* container
, uint8 firstWorldImage
, uint8 numWorldImage
)
42 _FirstWorldImage
=firstWorldImage
;
43 _NumWorldImage
=numWorldImage
;
45 _CollisionMask
=0xffffffff;
46 _OcclusionMask
=0xffffffff;
51 _LastTestTime
=0xffffffff;
54 _WorldImages
=_Container
->allocateWorldImagesPtrs (numWorldImage
);
57 for (uint j
=0; j
<numWorldImage
; j
++)
58 _WorldImages
[j
]=_Container
->allocateWorldImage ();
61 // ***************************************************************************
63 CMovePrimitive::~CMovePrimitive ()
66 for (uint j
=0; j
<(uint
)_NumWorldImage
; j
++)
68 _WorldImages
[j
]->deleteIt (*_Container
, (uint8
)(_FirstWorldImage
+j
));
69 _Container
->freeWorldImage (_WorldImages
[j
]);
73 _Container
->freeWorldImagesPtrs (_WorldImages
);
76 // ***************************************************************************
78 void CMovePrimitive::removeCollisionOTInfo (CCollisionOTInfo
*toRemove
)
81 CCollisionOTInfo
*previousElement
=NULL
;
82 CCollisionOTInfo
*element
=_RootOTInfo
;
89 if (element
==toRemove
)
91 // If previous element, just link
93 previousElement
->primitiveLink (this, element
->getNext (this));
95 _RootOTInfo
=element
->getNext (this);
102 previousElement
=element
;
103 element
=element
->getNext (this);
110 // ***************************************************************************
112 void CMovePrimitive::removeCollisionOTInfo ()
114 // For each element in the list
115 CCollisionOTInfo
*element
=_RootOTInfo
;
121 // Remove collision ot info from other primitive
122 CMovePrimitive
*other
=element
->getOtherPrimitive (this);
125 // Remove it in the other element
126 other
->removeCollisionOTInfo (element
);
130 element
=element
->getNext (this);
133 // Relink element because we keep it
137 // ***************************************************************************
139 void CMovePrimitive::checkSortedList ()
141 // Check sorted list for ecah world image
142 for (uint i
=0; i
<(uint
)_NumWorldImage
; i
++)
143 _WorldImages
[i
]->checkSortedList (uint8(i
+_FirstWorldImage
));
146 // ***************************************************************************
148 bool CMovePrimitive::isTriggered (CMovePrimitive
& second
, bool enter
, bool exit
)
150 // Generate a trigger ?
152 // Is the two are not triggers ?
153 if ( ( (_StaticFlags
&TriggerMask
) == NotATrigger
) && ( (second
._StaticFlags
&TriggerMask
) == NotATrigger
) )
156 // Is one of them is an enter trigger ?
157 if ( enter
&& ( (_StaticFlags
&EnterTrigger
) || (second
._StaticFlags
&EnterTrigger
) ) )
160 // Is one of them is an exit trigger ?
161 if ( exit
&& ( (_StaticFlags
&ExitTrigger
) || (second
._StaticFlags
&ExitTrigger
) ) )
164 // Is one of them is a trigger ?
165 if ( (_StaticFlags
&OverlapTrigger
) || (second
._StaticFlags
&OverlapTrigger
) )
171 // ***************************************************************************
173 void CMovePrimitive::insertInWorldImage (uint8 worldImage
)
175 // Check it is a collisionable primitive
176 nlassert (!isNonCollisionable());
178 // Check ad get the primitive world image
179 CPrimitiveWorldImage
*wI
=getWorldImage (worldImage
);
182 wI
->setInWorldImageFlag (true);
184 // Flag to update this wI
185 _Container
->changed (this, worldImage
);
188 // ***************************************************************************
190 void CMovePrimitive::removeFromWorldImage (uint8 worldImage
)
192 // Check it is a collisionable primitive
193 nlassert (!isNonCollisionable());
195 // Check ad get the primitive world image
196 CPrimitiveWorldImage
*wI
=getWorldImage (worldImage
);
199 wI
->deleteIt (*_Container
, worldImage
);
201 // Set as non inserted
202 wI
->setInWorldImageFlag (false);
205 // ***************************************************************************
207 void CMovePrimitive::setAbsorbtion (float attenuation
)
209 _Attenuation
=attenuation
;
212 // ***************************************************************************
214 void CMovePrimitive::setOrientation (double rot
, uint8 worldImage
)
216 if (isNonCollisionable())
217 getWorldImage (0)->setOrientation (rot
, _Container
, this, worldImage
);
219 getWorldImage (worldImage
)->setOrientation (rot
, _Container
, this, worldImage
);
222 // ***************************************************************************
224 void CMovePrimitive::setGlobalPosition (const UGlobalPosition
& pos
, uint8 worldImage
)
226 NLPACS_HAUTO_SET_GLOBAL_POSITION
228 if (isNonCollisionable())
229 getWorldImage (0)->setGlobalPosition (pos
, *_Container
, *this, worldImage
);
231 getWorldImage (worldImage
)->setGlobalPosition (pos
, *_Container
, *this, worldImage
);
234 // ***************************************************************************
236 void CMovePrimitive::setGlobalPosition (const NLMISC::CVectorD
& pos
, uint8 worldImage
, UGlobalPosition::TType
/* type */)
238 NLPACS_HAUTO_SET_UGLOBAL_POSITION
240 if (isNonCollisionable())
241 getWorldImage (0)->setGlobalPosition (pos
, *_Container
, *this, worldImage
, (_StaticFlags
& DontSnapToGroundFlag
) != 0);
243 getWorldImage (worldImage
)->setGlobalPosition (pos
, *_Container
, *this, worldImage
, (_StaticFlags
& DontSnapToGroundFlag
) != 0);
246 // ***************************************************************************
248 void CMovePrimitive::move (const NLMISC::CVectorD
& speed
, uint8 worldImage
)
252 if (isNonCollisionable())
253 getWorldImage (0)->move (speed
, *_Container
, *this, worldImage
);
255 getWorldImage (worldImage
)->move (speed
, *_Container
, *this, worldImage
);
258 // ***************************************************************************
260 NLMISC::CVectorD
CMovePrimitive::getFinalPosition (uint8 worldImage
) const
262 if (isNonCollisionable())
263 return getWorldImage (0)->getFinalPosition ();
265 return getWorldImage (worldImage
)->getFinalPosition ();
268 // ***************************************************************************
270 const NLMISC::CVectorD
& CMovePrimitive::getSpeed (uint8 worldImage
) const
272 if (isNonCollisionable())
273 return getWorldImage (0)->getSpeed ();
275 return getWorldImage (worldImage
)->getSpeed ();
278 // ***************************************************************************
280 CMovePrimitive::TType
CMovePrimitive::getPrimitiveType () const
282 return getPrimitiveTypeInternal ();
285 // ***************************************************************************
287 CMovePrimitive::TReaction
CMovePrimitive::getReactionType () const
289 return getReactionTypeInternal ();
292 // ***************************************************************************
294 CMovePrimitive::TTrigger
CMovePrimitive::getTriggerType () const
296 return getTriggerTypeInternal ();
299 // ***************************************************************************
301 CMovePrimitive::TCollisionMask
CMovePrimitive::getCollisionMask () const
303 return getCollisionMaskInternal ();
306 // ***************************************************************************
308 CMovePrimitive::TCollisionMask
CMovePrimitive::getOcclusionMask () const
310 return getOcclusionMaskInternal ();
313 // ***************************************************************************
315 bool CMovePrimitive::getObstacle () const
317 return isObstacle ();
320 // ***************************************************************************
322 float CMovePrimitive::getAbsorbtion () const
327 // ***************************************************************************
329 void CMovePrimitive::getSize (float& width
, float& depth
) const
335 // ***************************************************************************
337 float CMovePrimitive::getHeight () const
339 return getHeightInternal ();
342 // ***************************************************************************
344 float CMovePrimitive::getRadius () const
346 return getRadiusInternal ();
349 // ***************************************************************************
351 double CMovePrimitive::getOrientation (uint8 worldImage
) const
353 if (isNonCollisionable())
354 return getWorldImage (0)->getOrientation ();
356 return getWorldImage (worldImage
)->getOrientation ();
359 // ***************************************************************************
361 void CMovePrimitive::getGlobalPosition (UGlobalPosition
& pos
, uint8 worldImage
) const
363 NLPACS_HAUTO_GET_GLOBAL_POSITION
365 if (isNonCollisionable())
366 pos
=getWorldImage (0)->getGlobalPosition();
368 pos
=getWorldImage (worldImage
)->getGlobalPosition();
371 // ***************************************************************************
373 uint8
CMovePrimitive::getFirstWorldImageV () const
375 return getFirstWorldImage ();
378 // ***************************************************************************
380 uint8
CMovePrimitive::getNumWorldImageV () const
382 return getNumWorldImage ();
385 // ***************************************************************************
387 bool CMovePrimitive::isInCollision (CMovePrimitive
*primitive
)
390 CCollisionOTInfo
*element
=_RootOTInfo
;
395 // Dynamic collision ?
396 if (!element
->isCollisionAgainstStatic())
399 const CCollisionOTDynamicInfo
*dynInfo
=static_cast<const CCollisionOTDynamicInfo
*> (element
);
401 // Check if the primitive is used
402 if ((dynInfo
->getFirstPrimitive()== primitive
)||(dynInfo
->getSecondPrimitive()== primitive
))
407 element
=element
->getNext (this);