diff --git a/nel/include/nel/pacs/move_container.h b/nel/include/nel/pacs/move_container.h index 5193e8386..f368dd5e9 100644 --- a/nel/include/nel/pacs/move_container.h +++ b/nel/include/nel/pacs/move_container.h @@ -244,7 +244,7 @@ private: CCollisionOTStaticInfo *staticColInfo); // Add a trigger in the trigger array - void newTrigger (CMovePrimitive* first, CMovePrimitive* second, const CCollisionDesc& desc, uint triggerType); + bool newTrigger (CMovePrimitive* first, CMovePrimitive* second, const CCollisionDesc& desc, uint triggerType); // Clear modified primitive list void clearModifiedList (uint8 worldImage); diff --git a/nel/include/nel/pacs/move_primitive.h b/nel/include/nel/pacs/move_primitive.h index aa153c076..d77517a7d 100644 --- a/nel/include/nel/pacs/move_primitive.h +++ b/nel/include/nel/pacs/move_primitive.h @@ -251,6 +251,27 @@ public: _Height=height; } + void setZOffset(float offset) + { + _ZOffset = offset; + } + + float getZOffset() + { + return _ZOffset; + } + + bool haveZOffset() + { + return _HaveZOffset; + } + + void enableZOffset(bool enabled) + { + _HaveZOffset = enabled; + } + + /** * Set the cylinder size. Only for cylinder. * @@ -466,6 +487,10 @@ private: // Iteration count sint32 _IterationCount; + + float _ZOffset; + bool _HaveZOffset; + }; } // NLPACS diff --git a/nel/include/nel/pacs/u_move_primitive.h b/nel/include/nel/pacs/u_move_primitive.h index 5a021daa8..e067c3e6b 100644 --- a/nel/include/nel/pacs/u_move_primitive.h +++ b/nel/include/nel/pacs/u_move_primitive.h @@ -114,6 +114,12 @@ public: * This is an overlap trigger. This trigger is actived each time the object overlap the trigger. */ OverlapTrigger=0x400, + + /** + * This is an stairs trigger. This trigger is actived each time the object overlap the trigger and change Z position. + */ + OverlapStairsTrigger=0x800, + }; /** @@ -274,6 +280,14 @@ public: */ virtual float getHeight () const =0; + virtual void setZOffset(float offset) =0; + + virtual float getZOffset() =0; + + virtual bool haveZOffset() =0; + + virtual void enableZOffset(bool enabled) =0; + /** * Set the cylinder size. Only for cylinder. * diff --git a/nel/src/pacs/move_container.cpp b/nel/src/pacs/move_container.cpp index 35b7ddcd6..424f7d8b9 100644 --- a/nel/src/pacs/move_container.cpp +++ b/nel/src/pacs/move_container.cpp @@ -918,8 +918,10 @@ bool CMoveContainer::evalPrimAgainstPrimCollision (double beginTime, CMovePrimit || (otherPrimitive->getTriggerType()&UMovePrimitive::EnterTrigger)); bool exit = (beginTime<=lastTime) && (lastTime<_DeltaTime) && ((primitive->getTriggerType()&UMovePrimitive::ExitTrigger) || (otherPrimitive->getTriggerType()&UMovePrimitive::ExitTrigger)); - bool overlap = (firstTime<=beginTime) && (lastTime>_DeltaTime) && ((primitive->getTriggerType()&UMovePrimitive::OverlapTrigger) - || (otherPrimitive->getTriggerType()&UMovePrimitive::OverlapTrigger)); + bool overlap = ((firstTime<=beginTime) && (lastTime>_DeltaTime) && ((primitive->getTriggerType()&UMovePrimitive::OverlapTrigger) + || (otherPrimitive->getTriggerType()&UMovePrimitive::OverlapTrigger)) || + (firstTime<=beginTime) && (lastTime>_DeltaTime) && ((primitive->getTriggerType()&UMovePrimitive::OverlapStairsTrigger) + || (otherPrimitive->getTriggerType()&UMovePrimitive::OverlapStairsTrigger))); bool contact = ( beginTime<((firstTime+lastTime)/2) ) && (firstTime<=_DeltaTime); bool collision = contact && (primitive->isObstacle() && otherPrimitive->isObstacle ()); @@ -1211,7 +1213,7 @@ void CMoveContainer::newCollision (CMovePrimitive* first, const CCollisionSurfac // *************************************************************************** -void CMoveContainer::newTrigger (CMovePrimitive* first, CMovePrimitive* second, const CCollisionDesc& desc, uint triggerType) +bool CMoveContainer::newTrigger (CMovePrimitive* first, CMovePrimitive* second, const CCollisionDesc& desc, uint triggerType) { // Element index uint index=(uint)_Triggers.size(); @@ -1224,6 +1226,14 @@ void CMoveContainer::newTrigger (CMovePrimitive* first, CMovePrimitive* second, _Triggers[index].Object1=second->UserData; _Triggers[index].CollisionDesc=desc; _Triggers[index].CollisionType = uint8(triggerType); + + + if (second->_StaticFlags&UMovePrimitive::OverlapStairsTrigger) { + nlinfo("Col Stairs height %f", second->getHeight()); + return true; + } + + return false; } // *************************************************************************** @@ -1659,8 +1669,18 @@ void CMoveContainer::reaction (const CCollisionOTInfo& first) newTrigger (dynInfo->getFirstPrimitive (), dynInfo->getSecondPrimitive (), dynInfo->getCollisionDesc (), UTriggerInfo::In); if (dynInfo->isExit()) newTrigger (dynInfo->getFirstPrimitive (), dynInfo->getSecondPrimitive (), dynInfo->getCollisionDesc (), UTriggerInfo::Out); - if (dynInfo->isInside()) - newTrigger (dynInfo->getFirstPrimitive (), dynInfo->getSecondPrimitive (), dynInfo->getCollisionDesc (), UTriggerInfo::Inside); + if (dynInfo->isInside()) { + if (newTrigger (dynInfo->getFirstPrimitive (), dynInfo->getSecondPrimitive (), dynInfo->getCollisionDesc (), UTriggerInfo::Inside)) + { + dynInfo->getFirstPrimitive()->enableZOffset(true); + CVectorD first_pos = dynInfo->getFirstPrimitive()->getFinalPosition(dynInfo->getFirstWorldImage()); + CVectorD second_pos = dynInfo->getSecondPrimitive()->getFinalPosition(dynInfo->getSecondWorldImage()); + nlinfo("P = %f, C = %f, H = %f, D = %f", first_pos.z, second_pos.z, dynInfo->getSecondPrimitive()->getHeight(), second_pos.z-first_pos.z); + dynInfo->getFirstPrimitive()->setZOffset(second_pos.z+dynInfo->getSecondPrimitive()->getHeight()-1.0f); + } + } + if (dynInfo->isExit()) + newTrigger (dynInfo->getFirstPrimitive (), dynInfo->getSecondPrimitive (), dynInfo->getCollisionDesc (), UTriggerInfo::Out); } } } diff --git a/nel/src/pacs/move_primitive.cpp b/nel/src/pacs/move_primitive.cpp index 039fa0c7b..261d7bbf8 100644 --- a/nel/src/pacs/move_primitive.cpp +++ b/nel/src/pacs/move_primitive.cpp @@ -49,6 +49,8 @@ CMovePrimitive::CMovePrimitive (CMoveContainer* container, uint8 firstWorldImage _StaticFlags=0; _RootOTInfo=NULL; _LastTestTime=0xffffffff; + _ZOffset = 0; + _HaveZOffset = false; // Ptr table alloc _WorldImages=_Container->allocateWorldImagesPtrs (numWorldImage); @@ -149,6 +151,11 @@ bool CMovePrimitive::isTriggered (CMovePrimitive& second, bool enter, bool exit) { // Generate a trigger ? + + // Is one of them is a stairs trigger ? + if ( second._StaticFlags&OverlapStairsTrigger ) + return true; + // Is the two are not triggers ? if ( ( (_StaticFlags&TriggerMask) == NotATrigger ) && ( (second._StaticFlags&TriggerMask) == NotATrigger ) ) return false; diff --git a/ryzom/client/src/entities.cpp b/ryzom/client/src/entities.cpp index 6a64ea449..a17a49e4f 100644 --- a/ryzom/client/src/entities.cpp +++ b/ryzom/client/src/entities.cpp @@ -461,7 +461,7 @@ void CEntityManager::initialize(uint nbMaxEntity) NLGUI::CDBManager::getInstance()->getDB()->addObserver(&TeamUIDObserver, textId ); _GroupMemberUidDB[i] = NLGUI::CDBManager::getInstance()->getDbProp(text, false); nlassert(_GroupMemberUidDB[i]); - + text = toString(TEAM_DB_PATH ":%d:NAME", i); textId = ICDBNode::CTextId(text); NLGUI::CDBManager::getInstance()->getDB()->addObserver(&TeamPresentObserver, textId ); @@ -477,13 +477,13 @@ void CEntityManager::initialize(uint nbMaxEntity) NLGUI::CDBManager::getInstance()->getDB()->addObserver(&AnimalUIDObserver, textId); _BeastUidDB[i] = NLGUI::CDBManager::getInstance()->getDbProp(text, false); nlassert(_BeastUidDB[i]); - + text = toString("SERVER:PACK_ANIMAL:BEAST%d:STATUS", i); textId = ICDBNode::CTextId(text); NLGUI::CDBManager::getInstance()->getDB()->addObserver(&AnimalStatusObserver, textId); _BeastStatusDB[i] = NLGUI::CDBManager::getInstance()->getDbProp(text, false); nlassert(_BeastStatusDB[i]); - + text = toString("SERVER:PACK_ANIMAL:BEAST%d:TYPE", i); _BeastTypeDB[i] = NLGUI::CDBManager::getInstance()->getDbProp(text, false); nlassert(_BeastTypeDB[i]); @@ -550,7 +550,7 @@ CShapeInstanceReference CEntityManager::createInstance(const string& shape, cons primitive = PACS->addCollisionablePrimitive(dynamicWI, 1); primitive->setDontSnapToGround(false); } - + // Put instance in last deleted position if found if (_LastRemovedInstance != -1) { @@ -562,7 +562,7 @@ CShapeInstanceReference CEntityManager::createInstance(const string& shape, cons _ShapeInstances[idx].BboxActive = !text.empty() || !url.empty(); _ShapeInstances[idx].Deleted = false; _ShapeInstances[idx].InIGZone = inIgZone > 0; - + _LastRemovedInstance = _ShapeInstances[idx].LastDeleted; _ShapeInstances[idx].LastDeleted = -1; TIGZoneShapes::iterator it = _IgZoneShapes.find(inIgZone); @@ -613,7 +613,7 @@ bool CEntityManager::deleteInstance(uint32 idx) UMovePrimitive *primitive = _ShapeInstances[idx].Primitive; if (primitive) PACS->removePrimitive(primitive); - + if (!_ShapeInstances[idx].Deleted) { _ShapeInstances[idx].Primitive = NULL; @@ -649,7 +649,7 @@ CVector CEntityManager::getInstancePos(uint32 idx) UInstance instance = _ShapeInstances[idx].Instance; if(instance.empty()) return CVector(0,0,0); - + return instance.getPos(); } @@ -657,17 +657,17 @@ bool CEntityManager::setInstancePos(uint32 idx, CVector pos) { if (!Scene || idx >= _ShapeInstances.size() || _ShapeInstances[idx].Deleted) return false; - + UInstance instance = _ShapeInstances[idx].Instance; if(instance.empty()) return false; - + UMovePrimitive *primitive = _ShapeInstances[idx].Primitive; if (primitive) { primitive->setGlobalPosition(_ShapeInstances[idx].PrimRelativePos + pos, dynamicWI); } - + instance.setPos(pos); return true; } @@ -676,11 +676,11 @@ CVector CEntityManager::getInstanceRot(uint32 idx) { if (!Scene || idx >= _ShapeInstances.size() || _ShapeInstances[idx].Deleted) return CVector(0,0,0); - + UInstance instance = _ShapeInstances[idx].Instance; if(instance.empty()) return CVector(0,0,0); - + return instance.getRotEuler(); } @@ -688,13 +688,13 @@ bool CEntityManager::setInstanceRot(uint32 idx, CVector rot) { if (!Scene || idx >= _ShapeInstances.size() || _ShapeInstances[idx].Deleted) return false; - + UInstance instance = _ShapeInstances[idx].Instance; if(instance.empty()) return false; - + instance.setRotEuler(rot); - + return true; } @@ -706,7 +706,7 @@ CVector CEntityManager::getInstanceScale(uint32 idx) UInstance instance = _ShapeInstances[idx].Instance; if(instance.empty()) return CVector(0,0,0); - + return instance.getScale(); } @@ -714,7 +714,7 @@ CVector CEntityManager::getInstanceColPos(uint32 idx) { if (!Scene || idx >= _ShapeInstances.size() || _ShapeInstances[idx].Deleted) return CVector(0,0,0); - + return _ShapeInstances[idx].PrimRelativePos; } @@ -726,11 +726,11 @@ CVector CEntityManager::getInstanceColScale(uint32 idx) UMovePrimitive *primitive = _ShapeInstances[idx].Primitive; if (!primitive) return CVector(0,0,0); - + float width, depth; primitive->getSize(width, depth); float height = primitive->getHeight(); - + return CVector(width, depth, height); } @@ -738,11 +738,11 @@ double CEntityManager::getInstanceColOrient(uint32 idx) { if (!Scene || idx >= _ShapeInstances.size() || _ShapeInstances[idx].Deleted) return 0.f; - + UMovePrimitive *primitive = _ShapeInstances[idx].Primitive; if (!primitive) return 0.f; - + return primitive->getOrientation(dynamicWI); } @@ -754,21 +754,21 @@ CVector CEntityManager::getInstanceBBoxMin(uint32 idx) UInstance instance = _ShapeInstances[idx].Instance; if (instance.empty()) return CVector(0,0,0); - + NLMISC::CAABBox bbox; _ShapeInstances[idx].Instance.getShapeAABBox(bbox); - + CVector bbox_min; - + if (bbox.getCenter() == CVector::Null) bbox_min = CVector(-0.5f, -0.5f, -0.5f); else bbox_min = bbox.getMin(); - + bbox_min.x *= _ShapeInstances[idx].Instance.getScale().x; bbox_min.y *= _ShapeInstances[idx].Instance.getScale().y; bbox_min.z *= _ShapeInstances[idx].Instance.getScale().z; - + return bbox_min+_ShapeInstances[idx].Instance.getPos(); } @@ -780,28 +780,28 @@ CVector CEntityManager::getInstanceBBoxMax(uint32 idx) UInstance instance = _ShapeInstances[idx].Instance; if(instance.empty()) return CVector(0,0,0); - + NLMISC::CAABBox bbox; _ShapeInstances[idx].Instance.getShapeAABBox(bbox); - + CVector bbox_max; - + if (bbox.getCenter() == CVector::Null) bbox_max = CVector(-0.5f, -0.5f, -0.5f); else bbox_max = bbox.getMax(); - + bbox_max.x *= _ShapeInstances[idx].Instance.getScale().x; bbox_max.y *= _ShapeInstances[idx].Instance.getScale().y; bbox_max.z *= _ShapeInstances[idx].Instance.getScale().z; - + return bbox_max+_ShapeInstances[idx].Instance.getPos(); } bool CEntityManager::removeInstances() { if (!Scene) return false; - + for(uint i=0; i<_ShapeInstances.size(); ++i) { if (!_ShapeInstances[i].InIGZone) @@ -814,13 +814,13 @@ bool CEntityManager::setupInstance(uint32 idx, const vector &keys, const { if (!Scene || idx >= _ShapeInstances.size() || _ShapeInstances[idx].Deleted) return false; - + UInstance instance = _ShapeInstances[idx].Instance; if(instance.empty()) return false; - + UMovePrimitive *primitive = _ShapeInstances[idx].Primitive; - + for (uint32 i=0; i < keys.size(); i++) { string param = keys[i]; @@ -891,7 +891,7 @@ bool CEntityManager::setupInstance(uint32 idx, const vector &keys, const { float v; CVector pos = getInstancePos(idx); - + if (getRelativeFloatFromString(values[i], v)) { updateVector(param, pos, v, true); @@ -904,10 +904,10 @@ bool CEntityManager::setupInstance(uint32 idx, const vector &keys, const } else if (param == "rot x" || param == "rot y" || param == "rot z") { - + float v; CVector rot = getInstanceRot(idx); - + if (getRelativeFloatFromString(values[i], v)) { updateVector(param, rot, v, true); @@ -922,7 +922,7 @@ bool CEntityManager::setupInstance(uint32 idx, const vector &keys, const { float v; CVector scale = instance.getScale(); - + if (getRelativeFloatFromString(values[i], v)) { updateVector(param, scale, v, true); @@ -933,17 +933,17 @@ bool CEntityManager::setupInstance(uint32 idx, const vector &keys, const } instance.setScale(scale); } - + // Primitive colissions setups - + if (!primitive) continue; - + if (param == "col size x" || param == "col size y" || param == "col size z") { float width, depth; primitive->getSize(width, depth); float height = primitive->getHeight(); - + CVector size = CVector(width, depth, height); float v; if (getRelativeFloatFromString(values[i], v)) @@ -961,7 +961,7 @@ bool CEntityManager::setupInstance(uint32 idx, const vector &keys, const { CVector pos = instance.getPos(); float v; - + if (getRelativeFloatFromString(values[i], v)) { updateVector(param, _ShapeInstances[idx].PrimRelativePos, v, false); @@ -981,10 +981,10 @@ bool CEntityManager::setupInstance(uint32 idx, const vector &keys, const { double orient = primitive->getOrientation(dynamicWI); double v = 0.f; - + if (values[i].empty()) continue; - + if (values[i][0] == '+') { fromString(values[i].substr(1), v); @@ -995,7 +995,7 @@ bool CEntityManager::setupInstance(uint32 idx, const vector &keys, const fromString(values[i], v); orient = v; } - + primitive->setOrientation(orient, dynamicWI); } else if (param == "col mask player") @@ -1024,9 +1024,23 @@ bool CEntityManager::setupInstance(uint32 idx, const vector &keys, const fromString(values[i], active); primitive->setObstacle(active); } - else if (param == "col obstacle") + else if (param == "col stairs") { - + bool active; + fromString(values[i], active); + primitive->setObstacle(active); + if (active) + { + primitive->setReactionType(UMovePrimitive::DoNothing); + primitive->setTriggerType(UMovePrimitive::OverlapStairsTrigger); + primitive->setGlobalPosition(instance.getPos()+CVector(0, 0, 0.5f), dynamicWI); + } + else + { + primitive->setReactionType(UMovePrimitive::Slide); + primitive->setTriggerType(UMovePrimitive::NotATrigger); + primitive->setGlobalPosition(instance.getPos(), dynamicWI); + } } } @@ -1039,7 +1053,7 @@ CShapeInstanceReference CEntityManager::getShapeInstanceUnderPos(float x, float CShapeInstanceReference selectedInstance(UInstance(), string(""), string("")); _LastInstanceUnderPos= NULL; idx = -1; - + // If not initialised, return if (_ShapeInstances.empty()) return selectedInstance; diff --git a/ryzom/client/src/entity_cl.cpp b/ryzom/client/src/entity_cl.cpp index 9b7ca340e..c523449a1 100644 --- a/ryzom/client/src/entity_cl.cpp +++ b/ryzom/client/src/entity_cl.cpp @@ -1478,6 +1478,7 @@ void CEntityCL::pacsMove(const CVectorD &vect) if ((fabs (deltaPos.x) > 0.05) || (fabs (deltaPos.y) > 0.05)) { _HasMoved = true; + _Primitive->enableZOffset(false); _Primitive->move (deltaPos, dynamicWI); } } @@ -1657,7 +1658,7 @@ void CEntityCL::snapToGround() { if ( isUser() || isPlayer() || isNPC()) { - + float waterOffset = ClientCfg.WaterOffset; switch(people()) { @@ -1713,6 +1714,12 @@ void CEntityCL::snapToGround() pos().z = vect.z; } + if (_Primitive->haveZOffset()) { + //CVectorD prim_pos = _Primitive->getFinalPosition(dynamicWI); + pos().z = _Primitive->getZOffset(); + } + + // Set the box position. posBox(pos()); }// snapToGround // @@ -2294,7 +2301,7 @@ void CEntityCL::onStringAvailable(uint /* stringId */, const std::string &value) { womanTitle = ( c->getGender() == GSGENDER::female ); } - + string replacement = STRING_MANAGER::CStringManagerClient::getTitleLocalizedName(_TitleRaw, womanTitle); // Sometimes translation contains another title @@ -2792,7 +2799,7 @@ void CEntityCL::setOpacityMin(uint32 value) bool CEntityCL::mustShowInsceneInterface( bool enabledInSheet ) const { return ( - (enabledInSheet /*&& !CNPCIconCache::getInstance().getNPCIcon(this).getTextureMain().empty()*/) && + (enabledInSheet /*&& !CNPCIconCache::getInstance().getNPCIcon(this).getTextureMain().empty()*/) && (_InSceneInterfaceEnabled) && ( ClientCfg.Names || isUser () || @@ -3137,7 +3144,7 @@ void CEntityCL::updateVisiblePostPos(const NLMISC::TTime &/* currentTimeInMs */, if (skeleton()) _StateFX.setClusterSystem(skeleton()->getClusterSystem()); } - + if (!_SelectionFX.empty() || !_MouseOverFX.empty()) { // Build a matrix for the fx diff --git a/ryzom/client/src/main_loop.cpp b/ryzom/client/src/main_loop.cpp index 492d54623..bb9a29d4d 100644 --- a/ryzom/client/src/main_loop.cpp +++ b/ryzom/client/src/main_loop.cpp @@ -1421,7 +1421,7 @@ bool mainLoop() MainCam.setTransformMode(UTransformable::RotQuat); CVector cameraMoves = UserEntity->getCameraMoves(); - + currViewPos.z += cameraMoves.z; MainCam.setPos(currViewPos); MainCam.setRotQuat(View.currentViewQuat()); @@ -1435,7 +1435,7 @@ bool mainLoop() } UserEntity->setCameraMoves(CVector(0, 0, 0)); - + if (StereoHMD) { CMatrix camMatrix; @@ -2982,15 +2982,41 @@ CVector PacsBox[PacsBoxPointCount] = CVector( 0.5f, 0.5f, 0), CVector( -0.5f, 0.5f, 0), CVector( -0.5f, 0.5f, 0), CVector( -0.5f, -0.5f, 0), + CVector( -0.5f, -0.5f, 0), CVector( -0.5f, -0.5f, 1), + CVector( 0.5f, -0.5f, 0), CVector( 0.5f, -0.5f, 1), + CVector( 0.5f, 0.5f, 0), CVector( 0.5f, 0.5f, 1), + CVector( -0.5f, 0.5f, 0), CVector( -0.5f, 0.5f, 1), + CVector( -0.5f, -0.5f, 1), CVector( 0.5f, -0.5f, 1), CVector( 0.5f, -0.5f, 1), CVector( 0.5f, 0.5f, 1), CVector( 0.5f, 0.5f, 1), CVector( -0.5f, 0.5f, 1), CVector( -0.5f, 0.5f, 1), CVector( -0.5f, -0.5f, 1), +}; + +const uint PacsStairPointCount = 32; + +CVector PacsStair[PacsStairPointCount] = +{ + CVector( -0.5f, -0.5f, 0), CVector( 0.5f, -0.5f, 0), + CVector( 0.5f, -0.5f, 0), CVector( 0.5f, 0.5f, 0), + CVector( 0.5f, 0.5f, 0), CVector( -0.5f, 0.5f, 0), + CVector( -0.5f, 0.5f, 0), CVector( -0.5f, -0.5f, 0), CVector( -0.5f, -0.5f, 0), CVector( -0.5f, -0.5f, 1), CVector( 0.5f, -0.5f, 0), CVector( 0.5f, -0.5f, 1), CVector( 0.5f, 0.5f, 0), CVector( 0.5f, 0.5f, 1), CVector( -0.5f, 0.5f, 0), CVector( -0.5f, 0.5f, 1), + + CVector( -0.5f, -0.5f, 1), CVector( 0.5f, -0.5f, 1), + CVector( 0.5f, -0.5f, 1), CVector( 0.5f, 0.5f, 1), + CVector( 0.5f, 0.5f, 1), CVector( -0.5f, 0.5f, 1), + CVector( -0.5f, 0.5f, 1), CVector( -0.5f, -0.5f, 1), + + CVector( -0.5f, -0.5f, 1), CVector( 0.5f, 0.5f, 1), + CVector( -0.5f, 0.5f, 1), CVector( 0.5f, -0.5f, 1), + CVector( -0.5f, 0, 1), CVector( 0.5f, 0, 1), + CVector( 0, - 0.5f, 1), CVector( 0, 0.5f, 1), + }; const uint PacsCylPointCount = 48; @@ -3044,6 +3070,7 @@ void displayPACSPrimitive() // Distance CVector position = prim->getFinalPosition(wI); + bool isStairs = false; if ((position-UserEntity->pos()).sqrnorm() < (200*200)) { // Choose a color @@ -3051,8 +3078,14 @@ void displayPACSPrimitive() if (prim->isCollisionable()) { // Static collision - if (prim->getReactionType() == UMovePrimitive::DoNothing) + if (prim->getTriggerType() == UMovePrimitive::OverlapStairsTrigger) { + line.Color0 = CRGBA::Blue; + isStairs = true; + position.z -= 1.0f; + } + else if (prim->getReactionType() == UMovePrimitive::DoNothing) + { line.Color0 = CRGBA::Red; } else @@ -3082,8 +3115,16 @@ void displayPACSPrimitive() // Draw the primitive if (prim->getPrimitiveType() == UMovePrimitive::_2DOrientedBox) { - lines = PacsBox; - linecount = PacsBoxPointCount/2; + if (isStairs) + { + lines = PacsStair; + linecount = PacsStairPointCount/2; + } + else + { + lines = PacsBox; + linecount = PacsBoxPointCount/2; + } float width; float depth; prim->getSize (width, depth);