mirror of
https://github.com/SWG-Source/src.git
synced 2026-01-17 00:04:25 -05:00
Beginning of Atmo Flight work
This commit is contained in:
@@ -72,7 +72,7 @@ void CollisionCallbacks::install()
|
||||
CollisionCallbackManager::registerOnHitFunction(CollisionCallbacksNamespace::onHitDoCollisionWith, miningAsteroidDynamic, asteroid);
|
||||
CollisionCallbackManager::registerOnHitFunction(CollisionCallbacksNamespace::onHitDoCollisionWith, miningAsteroidDynamic, shipStation);
|
||||
|
||||
//CollisionCallbackManager::registerDoCollisionWithTerrainFunction(CollisionCallbacksNamespace::onDoCollisionWithTerrain);
|
||||
CollisionCallbackManager::registerDoCollisionWithTerrainFunction(CollisionCallbacksNamespace::onDoCollisionWithTerrain);
|
||||
|
||||
ExitChain::add(CollisionCallbacksNamespace::remove, "CollisionCallbacks");
|
||||
}
|
||||
@@ -133,7 +133,7 @@ bool CollisionCallbacksNamespace::onDoCollisionWithTerrain(Object * const object
|
||||
{
|
||||
ShipController * const shipController = safe_cast<ShipController *>(shipObject->getController());
|
||||
NOT_NULL(shipController);
|
||||
|
||||
REPORT_LOG(true, ("responding to collision"));
|
||||
shipController->respondToCollision(result.m_deltaToMoveBack_p, result.m_newReflection_p, result.m_normalOfSurface_p);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -131,7 +131,6 @@ void CollisionCallbackManager::registerDoCollisionWithTerrainFunction(DoCollisio
|
||||
bool CollisionCallbackManager::intersectAndReflect(Object * const object, Object * const wasHitByThisObject, Result & result)
|
||||
{
|
||||
// See if we need to ignore this collision
|
||||
|
||||
if (!s_ignoreIntersectList.empty())
|
||||
{
|
||||
NetworkId first(object->getNetworkId());
|
||||
@@ -219,6 +218,7 @@ bool CollisionCallbackManager::intersectAndReflect(Object * const object, Object
|
||||
bool CollisionCallbackManager::intersectAndReflectWithTerrain(Object * const object, Result & result)
|
||||
{
|
||||
CollisionProperty const * collision = object->getCollisionProperty();
|
||||
|
||||
NOT_NULL(collision);
|
||||
|
||||
Capsule queryCapsule_w(collision->getQueryCapsule_w());
|
||||
@@ -232,17 +232,29 @@ bool CollisionCallbackManager::intersectAndReflectWithTerrain(Object * const obj
|
||||
Vector const begin_w(queryCapsule_w.getPointA());
|
||||
Vector const end_w(queryCapsule_w.getPointB() + direction_w * radius);
|
||||
|
||||
DEBUG_REPORT_LOG(ms_debugReport, ("terrain begin = %f %f %f\n", begin_w.x, begin_w.y, begin_w.z));
|
||||
DEBUG_REPORT_LOG(ms_debugReport, ("terrain end = %f %f %f\n", end_w.x, end_w.y, end_w.z));
|
||||
DEBUG_REPORT_LOG(ms_debugReport, ("terrain direction = %f %f %f\n", direction_w.x, direction_w.y, direction_w.z));
|
||||
DEBUG_REPORT_LOG(ms_debugReport, ("terrain length = %f\n", deltaTraveled_w.magnitude()));
|
||||
// DEBUG_REPORT_LOG(ms_debugReport, ("terrain begin = %f %f %f\n", begin_w.x, begin_w.y, begin_w.z));
|
||||
// DEBUG_REPORT_LOG(ms_debugReport, ("terrain end = %f %f %f\n", end_w.x, end_w.y, end_w.z));
|
||||
// DEBUG_REPORT_LOG(ms_debugReport, ("terrain direction = %f %f %f\n", direction_w.x, direction_w.y, direction_w.z));
|
||||
// DEBUG_REPORT_LOG(ms_debugReport, ("terrain length = %f\n", deltaTraveled_w.magnitude()));
|
||||
|
||||
REPORT_LOG(true, ("ship begin = %f %f %f\n", begin_w.x, begin_w.y, begin_w.z));
|
||||
REPORT_LOG(true, ("ship end = %f %f %f\n", end_w.x, end_w.y, end_w.z));
|
||||
REPORT_LOG(true, ("ship direction = %f %f %f\n", direction_w.x, direction_w.y, direction_w.z));
|
||||
REPORT_LOG(true, ("ship length = %f\n", deltaTraveled_w.magnitude()));
|
||||
|
||||
TerrainObject const * const terrainObject = TerrainObject::getConstInstance();
|
||||
if (terrainObject != 0)
|
||||
{
|
||||
REPORT_LOG(true, ("found possible ground collision - checking collision\n"));
|
||||
CollisionInfo info;
|
||||
|
||||
float bh = 0.0f;
|
||||
terrainObject->getHeightForceChunkCreation(Vector(begin_w.x, 0.f, begin_w.z), bh);
|
||||
REPORT_LOG(true,("Terrain Height: begin: %f\n", bh));
|
||||
|
||||
if (terrainObject->collide (begin_w, end_w, info))
|
||||
{
|
||||
REPORT_LOG(true, ("collided with terrain\n"));
|
||||
#ifdef _DEBUG
|
||||
// calculate the parametric time for logging
|
||||
float const actualDistance = begin_w.magnitudeBetween(info.getPoint());
|
||||
@@ -261,7 +273,7 @@ bool CollisionCallbackManager::intersectAndReflectWithTerrain(Object * const obj
|
||||
result.m_pointOfCollision_p = pointOfCollision_w;
|
||||
result.m_normalOfSurface_p = info.getNormal();
|
||||
result.m_deltaToMoveBack_p = pointOfCollision_w - end_w;
|
||||
result.m_newReflection_p = result.m_normalOfSurface_p.reflectIncoming(direction_w);
|
||||
result.m_newReflection_p = info.getNormal().reflectIncoming(direction_w);
|
||||
|
||||
#ifdef _DEBUG
|
||||
DEBUG_REPORT_LOG(ms_debugReport, ("\t\tterrain = %f %f %f\n", result.m_deltaToMoveBack_p.x, result.m_deltaToMoveBack_p.y, result.m_deltaToMoveBack_p.z));
|
||||
@@ -269,6 +281,37 @@ bool CollisionCallbackManager::intersectAndReflectWithTerrain(Object * const obj
|
||||
|
||||
return true;
|
||||
}
|
||||
// Check our terrain elevation and add 5m to it - this will be our "floor" for allowable flight
|
||||
// if below that, then we've "collided" and at the very least, we need to be put somewhere ABOVE
|
||||
// the terrain.
|
||||
else if(bh >= begin_w.y) {
|
||||
// we are below the allowable elevation
|
||||
|
||||
// Create a theoretical intersection point. We need to "fake" this point as the main system
|
||||
// that was originally used is not working properly - suggesting more is at play that was originally expected.
|
||||
// implement this to avoid any unwanted bugs - rework when the bugs are found and fixed.
|
||||
Vector const & intersection = Vector(begin_w.x, bh, begin_w.z);
|
||||
Vector normal;
|
||||
|
||||
// Recreate the necessary geometry in light of NOT having the correct geometry.
|
||||
info.setObject(terrainObject);
|
||||
info.setPoint(terrainObject->rotateTranslate_w2o(intersection));
|
||||
if(terrainObject->getNormalOfPlaneAtPoint(intersection, normal)){
|
||||
info.setNormal(normal);
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
|
||||
REPORT_LOG(true, ("Intersection: %f %f %f\n", info.getPoint().x, info.getPoint().y, info.getPoint().z));
|
||||
|
||||
result.m_pointOfCollision_p = info.getPoint();
|
||||
result.m_normalOfSurface_p = info.getNormal();
|
||||
result.m_deltaToMoveBack_p = info.getPoint() - end_w;
|
||||
result.m_newReflection_p = result.m_normalOfSurface_p.reflectIncoming(direction_w);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -754,7 +754,6 @@ bool ProceduralTerrainAppearance::getHeight (const Vector& position_o, float& he
|
||||
bool ProceduralTerrainAppearance::getHeightForceChunkCreation (const Vector& position_o, float& height) const
|
||||
{
|
||||
const Chunk* chunk = findChunk (position_o, 1);
|
||||
|
||||
if (!chunk)
|
||||
{
|
||||
DEBUG_REPORT_LOG (ms_logGetHeightFailures, ("getHeightForceChunkCreation: chunk for <%1.2f, %1.2f> does not exist, creating\n", position_o.x, position_o.z));
|
||||
@@ -769,6 +768,22 @@ bool ProceduralTerrainAppearance::getHeightForceChunkCreation (const Vector& pos
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
bool ProceduralTerrainAppearance::getNormalOfPlaneAtPoint (const Vector& position_o, Vector& normal) const
|
||||
{
|
||||
const Chunk* chunk = findChunk (position_o, 1);
|
||||
if (!chunk)
|
||||
{
|
||||
DEBUG_REPORT_LOG (ms_logGetHeightFailures, ("getHeightForceChunkCreation: chunk for <%1.2f, %1.2f> does not exist, creating\n", position_o.x, position_o.z));
|
||||
const_cast<ProceduralTerrainAppearance*> (this)->createChunk (position_o, 1);
|
||||
|
||||
chunk = findChunk (position_o, 1);
|
||||
DEBUG_REPORT_LOG (ms_logGetHeightFailures && !chunk, ("getHeightForceChunkCreation: chunk for <%1.2f, %1.2f> STILL does not exist\n", position_o.x, position_o.z));
|
||||
}
|
||||
|
||||
return chunk && chunk->getNormalAtPoint (position_o, &normal);
|
||||
}
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
const ObjectTemplate* ProceduralTerrainAppearance::getSurfaceProperties (const Vector& position_o) const
|
||||
{
|
||||
SurfaceData sd;
|
||||
|
||||
@@ -171,6 +171,7 @@ public:
|
||||
virtual bool collide(Vector const & start_o, Vector const & end_o, CollideParameters const & collideParameters, CollisionInfo & result) const = 0;
|
||||
virtual bool getHeightAt (const Vector& pos, float* height) const = 0;
|
||||
virtual bool getHeightAt (const Vector& pos, float* height, Vector* normal) const = 0;
|
||||
virtual bool getNormalAtPoint (const Vector& pos, Vector* normal) const = 0;
|
||||
|
||||
const BoxExtent& getBoxExtent() const { return m_boxExtent; }
|
||||
|
||||
@@ -271,6 +272,7 @@ public:
|
||||
virtual bool getHeight (const Vector& position_o, float& height) const;
|
||||
virtual bool getHeight (const Vector& position_o, float& height, Vector& normal) const;
|
||||
virtual bool getHeightForceChunkCreation (const Vector& position_o, float& height) const;
|
||||
virtual bool getNormalOfPlaneAtPoint (const Vector& position_o, Vector& normal) const;
|
||||
virtual const ObjectTemplate* getSurfaceProperties (const Vector& position_o) const;
|
||||
virtual bool getWaterHeight (const Vector& position_o, float& height) const;
|
||||
virtual bool getWaterHeight (const Vector& position_o, float& height, TerrainGeneratorWaterType& waterType, bool ignoreNonTransparentWater=false) const;
|
||||
|
||||
@@ -376,6 +376,13 @@ bool SamplerProceduralTerrainAppearance::SamplerChunk::getHeightAt (const Vector
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
bool SamplerProceduralTerrainAppearance::SamplerChunk::getNormalAtPoint (const Vector& pos, Vector* normal) const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
#define ALLOW_BACKFACING_COLLISION 0
|
||||
|
||||
bool SamplerProceduralTerrainAppearance::SamplerChunk::collide (const Vector& start, const Vector& end, CollideParameters const & /*collideParameters*/, CollisionInfo& result) const
|
||||
|
||||
@@ -71,6 +71,7 @@ public:
|
||||
|
||||
virtual bool getHeightAt (const Vector& worldPos, float* height) const;
|
||||
virtual bool getHeightAt (const Vector& worldPos, float* height, Vector* normal) const;
|
||||
virtual bool getNormalAtPoint (const Vector& worldPos, Vector* normal) const;
|
||||
virtual bool collide(Vector const & start_o, Vector const & end_o, CollideParameters const & collideParameters, CollisionInfo & result) const;
|
||||
virtual int getChunkMemorySize () const;
|
||||
|
||||
|
||||
@@ -365,12 +365,89 @@ bool ServerProceduralTerrainAppearance::ServerChunk::getHeightAt (const Vector&
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
bool ServerProceduralTerrainAppearance::ServerChunk::getNormalAtPoint (const Vector& pos, Vector* normal) const
|
||||
{
|
||||
const Vector vmin = m_boxExtent.getMin ();
|
||||
const Vector vmax = m_boxExtent.getMax ();
|
||||
if (pos.x < vmin.x || pos.x > vmax.x || pos.z < vmin.z || pos.z > vmax.z)
|
||||
{
|
||||
DEBUG_WARNING (true, ("called getNormalAtPoint for position not within chunk"));
|
||||
REPORT_LOG(true, ("position not within chunk\n"));
|
||||
return false;
|
||||
}
|
||||
|
||||
int tileX;
|
||||
int tileZ;
|
||||
_findTileXz(pos, tileX, tileZ);
|
||||
if (isExcluded(tileX, tileZ)) {
|
||||
REPORT_LOG(true, ("tile is excluded\n"));
|
||||
return false;
|
||||
}
|
||||
|
||||
//-- find out which tile this intersects
|
||||
const Vector start (pos.x, vmax.y + 0.1f, pos.z);
|
||||
const Vector end (pos.x, vmin.y - 0.1f, pos.z);
|
||||
const Vector dir = end - start;
|
||||
|
||||
//-- collide with the 8 polygons in the tile
|
||||
|
||||
|
||||
int const numberOfTilesPerChunk = m_proceduralTerrainAppearance.getNumberOfTilesPerChunk();
|
||||
int const tileIndex = tileZ * numberOfTilesPerChunk + tileX;
|
||||
const int offset = tileIndex * 8;
|
||||
REPORT_LOG(true, ("Offset: %d\n", offset));
|
||||
|
||||
int k;
|
||||
for (k = offset; k < offset + 8; ++k)
|
||||
{
|
||||
Vector intersection;
|
||||
const Plane& plane = (*m_planeList) [k];
|
||||
Vector planeNormal = plane.getNormal ();
|
||||
|
||||
if(!plane.findIntersection(start, end, intersection)) {
|
||||
REPORT_LOG(true, ("Intersection was not found\n"));
|
||||
return false;
|
||||
}
|
||||
|
||||
REPORT_LOG(true, ("Checking plane %d, dir.dot: %f, intersection: %f, %f, %f\n", k, dir.dot(planeNormal), intersection.x, intersection.y, intersection.z));
|
||||
|
||||
if ((dir.dot (planeNormal) < 0.f) && (plane.findIntersection (start, end, intersection)))
|
||||
{
|
||||
const int i0 = (*ms_indexList) [k * 3 + 0];
|
||||
const int i1 = (*ms_indexList) [k * 3 + 1];
|
||||
const int i2 = (*ms_indexList) [k * 3 + 2];
|
||||
|
||||
const Vector& v0 = (*m_vertexList) [i0];
|
||||
const Vector& v1 = (*m_vertexList) [i1];
|
||||
const Vector& v2 = (*m_vertexList) [i2];
|
||||
REPORT_LOG(true, ("Found good plane: %f, %f, %f : checking vertexes.\n", v0, v1, v2));
|
||||
|
||||
DenormalizedLine2d const line01 (Vector2d (v0.x, v0.z), Vector2d (v1.x, v1.z));
|
||||
DenormalizedLine2d const line12 (Vector2d (v1.x, v1.z), Vector2d (v2.x, v2.z));
|
||||
DenormalizedLine2d const line20 (Vector2d (v2.x, v2.z), Vector2d (v0.x, v0.z));
|
||||
|
||||
if (line01.computeDistanceTo (Vector2d (start.x, start.z)) <= 0 &&
|
||||
line12.computeDistanceTo (Vector2d (start.x, start.z)) <= 0 &&
|
||||
line20.computeDistanceTo (Vector2d (start.x, start.z)) <= 0)
|
||||
{
|
||||
*normal = planeNormal;
|
||||
REPORT_LOG(true, ("Found on this plane: %f, %f, %f\n", v0, v1, v2));
|
||||
return true;
|
||||
}
|
||||
REPORT_LOG(true, ("Not on this plane. Distances: %f, %f, %f\n", line01.computeDistanceTo (Vector2d (start.x, start.z)), line12.computeDistanceTo (Vector2d (start.x, start.z)), line20.computeDistanceTo (Vector2d (start.x, start.z))));
|
||||
}
|
||||
REPORT_LOG(true, ("Not on this intersection.\n"));
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
#define ALLOW_BACKFACING_COLLISION 0
|
||||
|
||||
bool ServerProceduralTerrainAppearance::ServerChunk::collide (const Vector& start, const Vector& end, CollideParameters const & /*collideParameters*/, CollisionInfo& result) const
|
||||
{
|
||||
bool found = false;
|
||||
|
||||
//-- test the line against the extent
|
||||
if (m_boxExtent.testSphereOnly (start, end))
|
||||
{
|
||||
@@ -415,10 +492,9 @@ bool ServerProceduralTerrainAppearance::ServerChunk::collide (const Vector& star
|
||||
|
||||
if ((start.magnitudeBetweenSquared (intersection) < start.magnitudeBetweenSquared (result.getPoint ())) && intersection.inPolygon (v0, v1, v2))
|
||||
{
|
||||
found = true;
|
||||
|
||||
result.setPoint (intersection);
|
||||
result.setNormal (normal);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -426,7 +502,7 @@ bool ServerProceduralTerrainAppearance::ServerChunk::collide (const Vector& star
|
||||
}
|
||||
}
|
||||
|
||||
return found;
|
||||
return false;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
@@ -1146,30 +1222,34 @@ void ServerProceduralTerrainAppearance::addChunk (Chunk* const chunk, const int
|
||||
|
||||
bool ServerProceduralTerrainAppearance::collideChunkList(ChunkList const & chunkList, Vector const & start_o, Vector const & end_o, CollisionInfo& result) const
|
||||
{
|
||||
bool collided = false;
|
||||
|
||||
result.setPoint (end_o);
|
||||
|
||||
//-- fire ray through chunks
|
||||
for (ChunkList::const_iterator iter = chunkList.begin (); iter != chunkList.end (); ++iter)
|
||||
{
|
||||
Chunk const * const chunk = *iter;
|
||||
|
||||
CollisionInfo info;
|
||||
if (chunk->collide (start_o, result.getPoint (), CollideParameters::cms_default, info))
|
||||
{
|
||||
collided = true;
|
||||
result = info;
|
||||
}
|
||||
if(std::size(chunkList) > 0) {
|
||||
for (ChunkList::const_iterator iter = chunkList.begin (); iter != chunkList.end (); ++iter)
|
||||
{
|
||||
if ((*iter)->collide (start_o, end_o, CollideParameters::cms_default, result))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return collided;
|
||||
return false;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
bool ServerProceduralTerrainAppearance::getNormalOfPlaneAtPoint(const Vector& position_o, Vector* normal) const
|
||||
{
|
||||
const ServerChunk* const chunk = safe_cast<ServerChunk const *>(ProceduralTerrainAppearance::findChunk (position_o, 1));
|
||||
|
||||
return chunk->getNormalAtPoint(position_o, normal);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
bool ServerProceduralTerrainAppearance::collide(Vector const & start_o, Vector const & end_o, CollideParameters const & /*collideParameters*/, CollisionInfo & result) const
|
||||
{
|
||||
REPORT_LOG(true, ("Checking collision after rotation - Start Y: %f, End Y: %f\n", start_o.y, end_o.y));
|
||||
ChunkList chunkList;
|
||||
m_sphereTree.findOnSegment (start_o, end_o, chunkList);
|
||||
std::stable_sort(chunkList.begin(), chunkList.end(), CollisionChunkSorter(start_o));
|
||||
|
||||
@@ -71,6 +71,7 @@ public:
|
||||
|
||||
virtual bool getHeightAt (const Vector& worldPos, float* height) const;
|
||||
virtual bool getHeightAt (const Vector& worldPos, float* height, Vector* normal) const;
|
||||
virtual bool getNormalAtPoint (const Vector& worldPos, Vector* normal) const;
|
||||
virtual bool collide(Vector const & start_o, Vector const & end_o, CollideParameters const & collideParameters, CollisionInfo & result) const;
|
||||
virtual int getChunkMemorySize () const;
|
||||
|
||||
@@ -100,6 +101,7 @@ public:
|
||||
virtual int getNumberOfChunks () const;
|
||||
virtual bool hasHighLevelOfDetailTerrain (const Vector& position_o) const;
|
||||
virtual void purgeChunks();
|
||||
virtual bool getNormalOfPlaneAtPoint (const Vector& position_o, Vector* normal) const;
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
@@ -148,6 +148,13 @@ bool TerrainAppearance::getHeightForceChunkCreation (const Vector& /*position_o*
|
||||
{
|
||||
return false;
|
||||
}
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
bool TerrainAppearance::getNormalOfPlaneAtPoint (const Vector& /*position_w*/, Vector& /*normal*/) const
|
||||
{
|
||||
REPORT_LOG(true, ("Not implemented.\n"));
|
||||
return false;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
|
||||
@@ -38,6 +38,7 @@ public:
|
||||
virtual bool getHeight (const Vector& position_o, float& height) const;
|
||||
virtual bool getHeight (const Vector& position_o, float& height, Vector& normal) const;
|
||||
virtual bool getHeightForceChunkCreation (const Vector& position_o, float& height) const;
|
||||
virtual bool getNormalOfPlaneAtPoint (const Vector& position_o, Vector& normal) const;
|
||||
virtual const ObjectTemplate* getSurfaceProperties (const Vector& position_o) const;
|
||||
virtual int getTerrainType (const Vector& position_o) const;
|
||||
virtual bool getWaterHeight (const Vector& position_o, float& height) const;
|
||||
|
||||
@@ -302,6 +302,13 @@ bool TerrainObject::getHeightForceChunkCreation (const Vector& position_w, float
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
bool TerrainObject::getNormalOfPlaneAtPoint (const Vector& position_w, Vector& normal) const
|
||||
{
|
||||
return getCastedAppearance (this)->getNormalOfPlaneAtPoint (rotateTranslate_w2o (position_w), normal);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
const ObjectTemplate* TerrainObject::getSurfaceProperties (const Vector& position_w) const
|
||||
{
|
||||
return getCastedAppearance (this)->getSurfaceProperties (rotateTranslate_w2o (position_w));
|
||||
|
||||
@@ -54,6 +54,7 @@ public:
|
||||
bool getHeight (const Vector& position_w, float& height) const;
|
||||
bool getHeight (const Vector& position_w, float& height, Vector& normal) const;
|
||||
bool getHeightForceChunkCreation (const Vector& position_w, float& height) const;
|
||||
bool getNormalOfPlaneAtPoint (const Vector& position_w, Vector& normal) const;
|
||||
const ObjectTemplate* getSurfaceProperties (const Vector& position_w) const;
|
||||
int getTerrainType (const Vector& position_w) const;
|
||||
bool getWaterHeight (const Vector& position_w, float& height) const;
|
||||
|
||||
Reference in New Issue
Block a user