Merge pull request #1507 from rasmusgo/find-space-on-spaceship

Find space on spaceship
fix-squashed-planets
Tomasz Kapuściński 2022-07-09 16:38:58 +02:00 committed by GitHub
commit 3fd9815138
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 47 additions and 51 deletions

View File

@ -4101,66 +4101,55 @@ float SearchNearestObject(CObjectManager* objMan, Math::Vector center, CObject*
}
return min;
}
bool BlockedByObject(CObjectManager* objMan, Math::Vector center, float space, CObject* exclu)
{
for (CObject* obj : objMan->GetAllObjects())
{
if (!obj->GetDetectable()) continue; // inactive?
if (IsObjectBeingTransported(obj)) continue;
if (obj == exclu) continue;
for (const auto &crashSphere : obj->GetAllCrashSpheres())
{
const Math::Vector oPos = crashSphere.sphere.pos;
const float oRadius = crashSphere.sphere.radius;
const float minDist = oRadius + space;
if (Math::DistanceSquared(center, oPos) < minDist * minDist)
return true;
}
}
return false;
}
}
//! Calculates a free space
bool CRobotMain::FreeSpace(Math::Vector &center, float minRadius, float maxRadius,
float space, CObject *exclu)
{
if (minRadius < maxRadius) // from internal to external?
for (float radius = minRadius; radius <= maxRadius; radius += space)
{
for (float radius = minRadius; radius <= maxRadius; radius += space)
float ia = space/radius;
for (float angle = 0.0f; angle < Math::PI*2.0f; angle += ia)
{
float ia = space/radius;
for (float angle = 0.0f; angle < Math::PI*2.0f; angle += ia)
Math::Point p;
p.x = center.x+radius;
p.y = center.z;
p = Math::RotatePoint(Math::Point(center.x, center.z), angle, p);
Math::Vector pos;
pos.x = p.x;
pos.z = p.y;
pos.y = 0.0f;
m_terrain->AdjustToFloor(pos, true);
if (!BlockedByObject(m_objMan.get(), pos, space, exclu))
{
Math::Point p;
p.x = center.x+radius;
p.y = center.z;
p = Math::RotatePoint(Math::Point(center.x, center.z), angle, p);
Math::Vector pos;
pos.x = p.x;
pos.z = p.y;
pos.y = 0.0f;
m_terrain->AdjustToFloor(pos, true);
float dist = SearchNearestObject(m_objMan.get(), pos, exclu);
if (dist >= space)
float flat = m_terrain->GetFlatZoneRadius(pos, space);
if (flat >= space)
{
float flat = m_terrain->GetFlatZoneRadius(pos, dist/2.0f);
if (flat >= dist/2.0f)
{
center = pos;
return true;
}
}
}
}
}
else // from external to internal?
{
for (float radius=maxRadius; radius >= minRadius; radius -= space)
{
float ia = space/radius;
for (float angle=0.0f ; angle<Math::PI*2.0f ; angle+=ia )
{
Math::Point p;
p.x = center.x+radius;
p.y = center.z;
p = Math::RotatePoint(Math::Point(center.x, center.z), angle, p);
Math::Vector pos;
pos.x = p.x;
pos.z = p.y;
pos.y = 0.0f;
m_terrain->AdjustToFloor(pos, true);
float dist = SearchNearestObject(m_objMan.get(), pos, exclu);
if (dist >= space)
{
float flat = m_terrain->GetFlatZoneRadius(pos, dist/2.0f);
if (flat >= dist/2.0f)
{
center = pos;
return true;
}
center = pos;
return true;
}
}
}

View File

@ -273,6 +273,14 @@ inline float Distance(const Math::Vector &a, const Math::Vector &b)
(a.z-b.z)*(a.z-b.z) );
}
//! Returns the squared distance between the ends of two vectors
inline float DistanceSquared(const Math::Vector &a, const Math::Vector &b)
{
return (a.x-b.x)*(a.x-b.x) +
(a.y-b.y)*(a.y-b.y) +
(a.z-b.z)*(a.z-b.z);
}
//! Clamps the vector \a vec to range between \a min and \a max
inline Vector Clamp(const Vector &vec, const Vector &min, const Vector &max)
{
@ -285,4 +293,3 @@ inline Vector Clamp(const Vector &vec, const Vector &min, const Vector &max)
} // namespace Math