Merge branch 'fixes' into main/rendor-staging
[ryzomcore.git] / nel / src / pacs / move_primitive.cpp
blob039fa0c7b88e281ade748b375225f43a7f04d484
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 "stdpacs.h"
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 )
35 namespace NLPACS
38 // ***************************************************************************
40 CMovePrimitive::CMovePrimitive (CMoveContainer* container, uint8 firstWorldImage, uint8 numWorldImage)
42 _FirstWorldImage=firstWorldImage;
43 _NumWorldImage=numWorldImage;
45 _CollisionMask=0xffffffff;
46 _OcclusionMask=0xffffffff;
47 _Attenuation=1;
48 _Container=container;
49 _StaticFlags=0;
50 _RootOTInfo=NULL;
51 _LastTestTime=0xffffffff;
53 // Ptr table alloc
54 _WorldImages=_Container->allocateWorldImagesPtrs (numWorldImage);
56 // Alloc world images
57 for (uint j=0; j<numWorldImage; j++)
58 _WorldImages[j]=_Container->allocateWorldImage ();
61 // ***************************************************************************
63 CMovePrimitive::~CMovePrimitive ()
65 // Alloc world images
66 for (uint j=0; j<(uint)_NumWorldImage; j++)
68 _WorldImages[j]->deleteIt (*_Container, (uint8)(_FirstWorldImage+j));
69 _Container->freeWorldImage (_WorldImages[j]);
72 // Ptr table alloc
73 _Container->freeWorldImagesPtrs (_WorldImages);
76 // ***************************************************************************
78 void CMovePrimitive::removeCollisionOTInfo (CCollisionOTInfo *toRemove)
80 // Should be ok
81 CCollisionOTInfo *previousElement=NULL;
82 CCollisionOTInfo *element=_RootOTInfo;
83 nlassert (element);
85 // Look for it
86 while (element)
88 // Good one ?
89 if (element==toRemove)
91 // If previous element, just link
92 if (previousElement)
93 previousElement->primitiveLink (this, element->getNext (this));
94 else
95 _RootOTInfo=element->getNext (this);
97 // End
98 break;
101 // Look for next
102 previousElement=element;
103 element=element->getNext (this);
106 // Should be found
107 nlassert (element);
110 // ***************************************************************************
112 void CMovePrimitive::removeCollisionOTInfo ()
114 // For each element in the list
115 CCollisionOTInfo *element=_RootOTInfo;
116 while (element)
118 // Unlink from ot
119 element->unlink ();
121 // Remove collision ot info from other primitive
122 CMovePrimitive *other=element->getOtherPrimitive (this);
123 if (other)
125 // Remove it in the other element
126 other->removeCollisionOTInfo (element);
129 // Next element
130 element=element->getNext (this);
133 // Relink element because we keep it
134 _RootOTInfo=NULL;
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 ) )
154 return false;
156 // Is one of them is an enter trigger ?
157 if ( enter && ( (_StaticFlags&EnterTrigger) || (second._StaticFlags&EnterTrigger) ) )
158 return true;
160 // Is one of them is an exit trigger ?
161 if ( exit && ( (_StaticFlags&ExitTrigger) || (second._StaticFlags&ExitTrigger) ) )
162 return true;
164 // Is one of them is a trigger ?
165 if ( (_StaticFlags&OverlapTrigger) || (second._StaticFlags&OverlapTrigger) )
166 return true;
168 return false;
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);
181 // Set as inserted
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);
198 // Remove from cells
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);
218 else
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);
230 else
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);
242 else
243 getWorldImage (worldImage)->setGlobalPosition (pos, *_Container, *this, worldImage, (_StaticFlags & DontSnapToGroundFlag) != 0);
246 // ***************************************************************************
248 void CMovePrimitive::move (const NLMISC::CVectorD& speed, uint8 worldImage)
250 NLPACS_HAUTO_MOVE
252 if (isNonCollisionable())
253 getWorldImage (0)->move (speed, *_Container, *this, worldImage);
254 else
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 ();
264 else
265 return getWorldImage (worldImage)->getFinalPosition ();
268 // ***************************************************************************
270 const NLMISC::CVectorD& CMovePrimitive::getSpeed (uint8 worldImage) const
272 if (isNonCollisionable())
273 return getWorldImage (0)->getSpeed ();
274 else
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
324 return _Attenuation;
327 // ***************************************************************************
329 void CMovePrimitive::getSize (float& width, float& depth) const
331 width=getLength(0);
332 depth=getLength(1);
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 ();
355 else
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();
367 else
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)
389 // Should be ok
390 CCollisionOTInfo *element=_RootOTInfo;
392 // Look for it
393 while (element)
395 // Dynamic collision ?
396 if (!element->isCollisionAgainstStatic())
398 // Cast
399 const CCollisionOTDynamicInfo *dynInfo=static_cast<const CCollisionOTDynamicInfo*> (element);
401 // Check if the primitive is used
402 if ((dynInfo->getFirstPrimitive()== primitive)||(dynInfo->getSecondPrimitive()== primitive))
403 return true;
406 // Look for next
407 element=element->getNext (this);
410 return false;
413 } // NLPACS