// NeL - MMORPG Framework // Copyright (C) 2010 Winch Gate Property Limited // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as // published by the Free Software Foundation, either version 3 of the // License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Affero General Public License for more details. // // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . #include "stdpacs.h" #include "nel/pacs/move_primitive.h" #include "nel/pacs/collision_desc.h" #include "nel/pacs/move_element.h" #include "nel/misc/hierarchical_timer.h" using namespace NLMISC; H_AUTO_DECL ( NLPACS_Get_Global_Position ) H_AUTO_DECL ( NLPACS_Set_Global_Position ) H_AUTO_DECL ( NLPACS_Set_UGlobal_Position ) H_AUTO_DECL ( NLPACS_Move ) #define NLPACS_HAUTO_GET_GLOBAL_POSITION H_AUTO_USE ( NLPACS_Get_Global_Position ) #define NLPACS_HAUTO_SET_GLOBAL_POSITION H_AUTO_USE ( NLPACS_Set_Global_Position ) #define NLPACS_HAUTO_SET_UGLOBAL_POSITION H_AUTO_USE ( NLPACS_Set_UGlobal_Position ) #define NLPACS_HAUTO_MOVE H_AUTO_USE ( NLPACS_Move ) namespace NLPACS { // *************************************************************************** CMovePrimitive::CMovePrimitive (CMoveContainer* container, uint8 firstWorldImage, uint8 numWorldImage) { _FirstWorldImage=firstWorldImage; _NumWorldImage=numWorldImage; _CollisionMask=0xffffffff; _OcclusionMask=0xffffffff; _Attenuation=1; _Container=container; _StaticFlags=0; _RootOTInfo=NULL; _LastTestTime=0xffffffff; // Ptr table alloc _WorldImages=_Container->allocateWorldImagesPtrs (numWorldImage); // Alloc world images for (uint j=0; jallocateWorldImage (); } // *************************************************************************** CMovePrimitive::~CMovePrimitive () { // Alloc world images for (uint j=0; j<(uint)_NumWorldImage; j++) { _WorldImages[j]->deleteIt (*_Container, (uint8)(_FirstWorldImage+j)); _Container->freeWorldImage (_WorldImages[j]); } // Ptr table alloc _Container->freeWorldImagesPtrs (_WorldImages); } // *************************************************************************** void CMovePrimitive::removeCollisionOTInfo (CCollisionOTInfo *toRemove) { // Should be ok CCollisionOTInfo *previousElement=NULL; CCollisionOTInfo *element=_RootOTInfo; nlassert (element); // Look for it while (element) { // Good one ? if (element==toRemove) { // If previous element, just link if (previousElement) previousElement->primitiveLink (this, element->getNext (this)); else _RootOTInfo=element->getNext (this); // End break; } // Look for next previousElement=element; element=element->getNext (this); } // Should be found nlassert (element); } // *************************************************************************** void CMovePrimitive::removeCollisionOTInfo () { // For each element in the list CCollisionOTInfo *element=_RootOTInfo; while (element) { // Unlink from ot element->unlink (); // Remove collision ot info from other primitive CMovePrimitive *other=element->getOtherPrimitive (this); if (other) { // Remove it in the other element other->removeCollisionOTInfo (element); } // Next element element=element->getNext (this); } // Relink element because we keep it _RootOTInfo=NULL; } // *************************************************************************** void CMovePrimitive::checkSortedList () { // Check sorted list for ecah world image for (uint i=0; i<(uint)_NumWorldImage; i++) _WorldImages[i]->checkSortedList (uint8(i+_FirstWorldImage)); } // *************************************************************************** bool CMovePrimitive::isTriggered (CMovePrimitive& second, bool enter, bool exit) { // Generate a trigger ? // Is the two are not triggers ? if ( ( (_StaticFlags&TriggerMask) == NotATrigger ) && ( (second._StaticFlags&TriggerMask) == NotATrigger ) ) return false; // Is one of them is an enter trigger ? if ( enter && ( (_StaticFlags&EnterTrigger) || (second._StaticFlags&EnterTrigger) ) ) return true; // Is one of them is an exit trigger ? if ( exit && ( (_StaticFlags&ExitTrigger) || (second._StaticFlags&ExitTrigger) ) ) return true; // Is one of them is a trigger ? if ( (_StaticFlags&OverlapTrigger) || (second._StaticFlags&OverlapTrigger) ) return true; return false; } // *************************************************************************** void CMovePrimitive::insertInWorldImage (uint8 worldImage) { // Check it is a collisionable primitive nlassert (!isNonCollisionable()); // Check ad get the primitive world image CPrimitiveWorldImage *wI=getWorldImage (worldImage); // Set as inserted wI->setInWorldImageFlag (true); // Flag to update this wI _Container->changed (this, worldImage); } // *************************************************************************** void CMovePrimitive::removeFromWorldImage (uint8 worldImage) { // Check it is a collisionable primitive nlassert (!isNonCollisionable()); // Check ad get the primitive world image CPrimitiveWorldImage *wI=getWorldImage (worldImage); // Remove from cells wI->deleteIt (*_Container, worldImage); // Set as non inserted wI->setInWorldImageFlag (false); } // *************************************************************************** void CMovePrimitive::setAbsorbtion (float attenuation) { _Attenuation=attenuation; } // *************************************************************************** void CMovePrimitive::setOrientation (double rot, uint8 worldImage) { if (isNonCollisionable()) getWorldImage (0)->setOrientation (rot, _Container, this, worldImage); else getWorldImage (worldImage)->setOrientation (rot, _Container, this, worldImage); } // *************************************************************************** void CMovePrimitive::setGlobalPosition (const UGlobalPosition& pos, uint8 worldImage) { NLPACS_HAUTO_SET_GLOBAL_POSITION if (isNonCollisionable()) getWorldImage (0)->setGlobalPosition (pos, *_Container, *this, worldImage); else getWorldImage (worldImage)->setGlobalPosition (pos, *_Container, *this, worldImage); } // *************************************************************************** void CMovePrimitive::setGlobalPosition (const NLMISC::CVectorD& pos, uint8 worldImage, UGlobalPosition::TType /* type */) { NLPACS_HAUTO_SET_UGLOBAL_POSITION if (isNonCollisionable()) getWorldImage (0)->setGlobalPosition (pos, *_Container, *this, worldImage, (_StaticFlags & DontSnapToGroundFlag) != 0); else getWorldImage (worldImage)->setGlobalPosition (pos, *_Container, *this, worldImage, (_StaticFlags & DontSnapToGroundFlag) != 0); } // *************************************************************************** void CMovePrimitive::move (const NLMISC::CVectorD& speed, uint8 worldImage) { NLPACS_HAUTO_MOVE if (isNonCollisionable()) getWorldImage (0)->move (speed, *_Container, *this, worldImage); else getWorldImage (worldImage)->move (speed, *_Container, *this, worldImage); } // *************************************************************************** NLMISC::CVectorD CMovePrimitive::getFinalPosition (uint8 worldImage) const { if (isNonCollisionable()) return getWorldImage (0)->getFinalPosition (); else return getWorldImage (worldImage)->getFinalPosition (); } // *************************************************************************** const NLMISC::CVectorD& CMovePrimitive::getSpeed (uint8 worldImage) const { if (isNonCollisionable()) return getWorldImage (0)->getSpeed (); else return getWorldImage (worldImage)->getSpeed (); } // *************************************************************************** CMovePrimitive::TType CMovePrimitive::getPrimitiveType () const { return getPrimitiveTypeInternal (); } // *************************************************************************** CMovePrimitive::TReaction CMovePrimitive::getReactionType () const { return getReactionTypeInternal (); } // *************************************************************************** CMovePrimitive::TTrigger CMovePrimitive::getTriggerType () const { return getTriggerTypeInternal (); } // *************************************************************************** CMovePrimitive::TCollisionMask CMovePrimitive::getCollisionMask () const { return getCollisionMaskInternal (); } // *************************************************************************** CMovePrimitive::TCollisionMask CMovePrimitive::getOcclusionMask () const { return getOcclusionMaskInternal (); } // *************************************************************************** bool CMovePrimitive::getObstacle () const { return isObstacle (); } // *************************************************************************** float CMovePrimitive::getAbsorbtion () const { return _Attenuation; } // *************************************************************************** void CMovePrimitive::getSize (float& width, float& depth) const { width=getLength(0); depth=getLength(1); } // *************************************************************************** float CMovePrimitive::getHeight () const { return getHeightInternal (); } // *************************************************************************** float CMovePrimitive::getRadius () const { return getRadiusInternal (); } // *************************************************************************** double CMovePrimitive::getOrientation (uint8 worldImage) const { if (isNonCollisionable()) return getWorldImage (0)->getOrientation (); else return getWorldImage (worldImage)->getOrientation (); } // *************************************************************************** void CMovePrimitive::getGlobalPosition (UGlobalPosition& pos, uint8 worldImage) const { NLPACS_HAUTO_GET_GLOBAL_POSITION if (isNonCollisionable()) pos=getWorldImage (0)->getGlobalPosition(); else pos=getWorldImage (worldImage)->getGlobalPosition(); } // *************************************************************************** uint8 CMovePrimitive::getFirstWorldImageV () const { return getFirstWorldImage (); } // *************************************************************************** uint8 CMovePrimitive::getNumWorldImageV () const { return getNumWorldImageV (); } // *************************************************************************** bool CMovePrimitive::isInCollision (CMovePrimitive *primitive) { // Should be ok CCollisionOTInfo *element=_RootOTInfo; // Look for it while (element) { // Dynamic collision ? if (!element->isCollisionAgainstStatic()) { // Cast const CCollisionOTDynamicInfo *dynInfo=static_cast (element); // Check if the primitive is used if ((dynInfo->getFirstPrimitive()== primitive)||(dynInfo->getSecondPrimitive()== primitive)) return true; } // Look for next element=element->getNext (this); } return false; } } // NLPACS