Added stairs collisions

feature/colissions-stairs
Nuno 3 years ago
parent 2304445c39
commit 8ea4ff53cb

@ -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);

@ -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

@ -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.
*

@ -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);
}
}
}

@ -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;

@ -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<string> &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<string> &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<string> &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<string> &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<string> &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<string> &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<string> &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<string> &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<string> &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;

@ -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

@ -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);

Loading…
Cancel
Save