mirror of
https://github.com/mangosfour/server.git
synced 2025-12-15 01:37:00 +00:00
[10175] Fix incorrectly blocked line of sight in certain locations.
I really should know by now that floats are not infinitely precise...
This commit is contained in:
parent
695f0f1655
commit
00751347e5
4 changed files with 30 additions and 23 deletions
|
|
@ -1,4 +1,4 @@
|
||||||
#ifndef __REVISION_NR_H__
|
#ifndef __REVISION_NR_H__
|
||||||
#define __REVISION_NR_H__
|
#define __REVISION_NR_H__
|
||||||
#define REVISION_NR "10174"
|
#define REVISION_NR "10175"
|
||||||
#endif // __REVISION_NR_H__
|
#endif // __REVISION_NR_H__
|
||||||
|
|
|
||||||
|
|
@ -34,13 +34,18 @@ namespace VMAP
|
||||||
class MapRayCallback
|
class MapRayCallback
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
MapRayCallback(ModelInstance *val): prims(val) {}
|
MapRayCallback(ModelInstance *val): prims(val), hit(false) {}
|
||||||
ModelInstance *prims;
|
|
||||||
bool operator()(const G3D::Ray& ray, uint32 entry, float& distance, bool pStopAtFirstHit=true)
|
bool operator()(const G3D::Ray& ray, uint32 entry, float& distance, bool pStopAtFirstHit=true)
|
||||||
{
|
{
|
||||||
return prims[entry].intersectRay(ray, distance, pStopAtFirstHit);
|
bool result = prims[entry].intersectRay(ray, distance, pStopAtFirstHit);
|
||||||
//std::cout << "trying to intersect '" << entity->name << "'\n";
|
if (result)
|
||||||
|
hit = true;
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
bool didHit(){ return hit; }
|
||||||
|
protected:
|
||||||
|
ModelInstance *prims;
|
||||||
|
bool hit;
|
||||||
};
|
};
|
||||||
|
|
||||||
class AreaInfoCallback
|
class AreaInfoCallback
|
||||||
|
|
@ -131,21 +136,23 @@ namespace VMAP
|
||||||
|
|
||||||
//=========================================================
|
//=========================================================
|
||||||
/**
|
/**
|
||||||
return dist to hit or inf() if no hit
|
If intersection is found within pMaxDist, sets pMaxDist to intersection distance and returns true.
|
||||||
|
Else, pMaxDist is not modified and returns false;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
float StaticMapTree::getIntersectionTime(const G3D::Ray& pRay, float pMaxDist, bool pStopAtFirstHit) const
|
bool StaticMapTree::getIntersectionTime(const G3D::Ray& pRay, float &pMaxDist, bool pStopAtFirstHit) const
|
||||||
{
|
{
|
||||||
float distance = pMaxDist;
|
float distance = pMaxDist;
|
||||||
MapRayCallback intersectionCallBack(iTreeValues);
|
MapRayCallback intersectionCallBack(iTreeValues);
|
||||||
iTree.intersectRay(pRay, intersectionCallBack, distance, pStopAtFirstHit);
|
iTree.intersectRay(pRay, intersectionCallBack, distance, pStopAtFirstHit);
|
||||||
return distance;
|
if (intersectionCallBack.didHit())
|
||||||
|
pMaxDist = distance;
|
||||||
|
return intersectionCallBack.didHit();
|
||||||
}
|
}
|
||||||
//=========================================================
|
//=========================================================
|
||||||
|
|
||||||
bool StaticMapTree::isInLineOfSight(const Vector3& pos1, const Vector3& pos2) const
|
bool StaticMapTree::isInLineOfSight(const Vector3& pos1, const Vector3& pos2) const
|
||||||
{
|
{
|
||||||
bool result = true;
|
|
||||||
float maxDist = (pos2 - pos1).magnitude();
|
float maxDist = (pos2 - pos1).magnitude();
|
||||||
// valid map coords should *never ever* produce float overflow, but this would produce NaNs too:
|
// valid map coords should *never ever* produce float overflow, but this would produce NaNs too:
|
||||||
ASSERT(maxDist < std::numeric_limits<float>::max());
|
ASSERT(maxDist < std::numeric_limits<float>::max());
|
||||||
|
|
@ -154,12 +161,10 @@ namespace VMAP
|
||||||
return true;
|
return true;
|
||||||
// direction with length of 1
|
// direction with length of 1
|
||||||
G3D::Ray ray = G3D::Ray::fromOriginAndDirection(pos1, (pos2 - pos1)/maxDist);
|
G3D::Ray ray = G3D::Ray::fromOriginAndDirection(pos1, (pos2 - pos1)/maxDist);
|
||||||
float resultDist = getIntersectionTime(ray, maxDist, true);
|
if (getIntersectionTime(ray, maxDist, true))
|
||||||
if (resultDist < maxDist)
|
return false;
|
||||||
{
|
|
||||||
result = false;
|
return true;
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
//=========================================================
|
//=========================================================
|
||||||
/**
|
/**
|
||||||
|
|
@ -181,8 +186,8 @@ namespace VMAP
|
||||||
}
|
}
|
||||||
Vector3 dir = (pPos2 - pPos1)/maxDist; // direction with length of 1
|
Vector3 dir = (pPos2 - pPos1)/maxDist; // direction with length of 1
|
||||||
G3D::Ray ray(pPos1, dir);
|
G3D::Ray ray(pPos1, dir);
|
||||||
float dist = getIntersectionTime(ray, maxDist, false);
|
float dist = maxDist;
|
||||||
if (dist < maxDist)
|
if (getIntersectionTime(ray, dist, false))
|
||||||
{
|
{
|
||||||
pResultHitPos = pPos1 + dir * dist;
|
pResultHitPos = pPos1 + dir * dist;
|
||||||
if (pModifyDist < 0)
|
if (pModifyDist < 0)
|
||||||
|
|
@ -218,10 +223,9 @@ namespace VMAP
|
||||||
Vector3 dir = Vector3(0,0,-1);
|
Vector3 dir = Vector3(0,0,-1);
|
||||||
G3D::Ray ray(pPos, dir); // direction with length of 1
|
G3D::Ray ray(pPos, dir); // direction with length of 1
|
||||||
float maxDist = VMapDefinitions::getMaxCanFallDistance();
|
float maxDist = VMapDefinitions::getMaxCanFallDistance();
|
||||||
float dist = getIntersectionTime(ray, maxDist, false);
|
if (getIntersectionTime(ray, maxDist, false))
|
||||||
if (dist < maxDist)
|
|
||||||
{
|
{
|
||||||
height = pPos.z - dist;
|
height = pPos.z - maxDist;
|
||||||
}
|
}
|
||||||
return(height);
|
return(height);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -57,7 +57,7 @@ namespace VMAP
|
||||||
std::string iBasePath;
|
std::string iBasePath;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
float getIntersectionTime(const G3D::Ray& pRay, float pMaxDist, bool pStopAtFirstHit) const;
|
bool getIntersectionTime(const G3D::Ray& pRay, float &pMaxDist, bool pStopAtFirstHit) const;
|
||||||
//bool containsLoadedMapTile(unsigned int pTileIdent) const { return(iLoadedMapTiles.containsKey(pTileIdent)); }
|
//bool containsLoadedMapTile(unsigned int pTileIdent) const { return(iLoadedMapTiles.containsKey(pTileIdent)); }
|
||||||
public:
|
public:
|
||||||
static std::string getTileFileName(uint32 mapID, uint32 tileX, uint32 tileY);
|
static std::string getTileFileName(uint32 mapID, uint32 tileX, uint32 tileY);
|
||||||
|
|
|
||||||
|
|
@ -54,8 +54,11 @@ namespace VMAP
|
||||||
Ray modRay(p, iInvRot * pRay.direction());
|
Ray modRay(p, iInvRot * pRay.direction());
|
||||||
float distance = pMaxDist * iInvScale;
|
float distance = pMaxDist * iInvScale;
|
||||||
bool hit = iModel->IntersectRay(modRay, distance, pStopAtFirstHit);
|
bool hit = iModel->IntersectRay(modRay, distance, pStopAtFirstHit);
|
||||||
distance *= iScale;
|
if(hit)
|
||||||
pMaxDist = distance;
|
{
|
||||||
|
distance *= iScale;
|
||||||
|
pMaxDist = distance;
|
||||||
|
}
|
||||||
return hit;
|
return hit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue