From 7294eaa2c6e9670476d3b3e86f557e78c22eee33 Mon Sep 17 00:00:00 2001 From: CekisSWG Date: Sun, 29 Dec 2019 01:43:51 -0500 Subject: [PATCH] Beginning of Atmo Flight work --- .../shared/collision/CollisionCallbacks.cpp | 4 +- .../collision/CollisionCallbackManager.cpp | 55 +++++++- .../ProceduralTerrainAppearance.cpp | 17 ++- .../appearance/ProceduralTerrainAppearance.h | 2 + .../SamplerProceduralTerrainAppearance.cpp | 7 + .../SamplerProceduralTerrainAppearance.h | 1 + .../ServerProceduralTerrainAppearance.cpp | 120 +++++++++++++++--- .../ServerProceduralTerrainAppearance.h | 2 + .../shared/appearance/TerrainAppearance.cpp | 7 + .../src/shared/appearance/TerrainAppearance.h | 1 + .../src/shared/object/TerrainObject.cpp | 7 + .../src/shared/object/TerrainObject.h | 1 + 12 files changed, 195 insertions(+), 29 deletions(-) diff --git a/engine/server/library/serverGame/src/shared/collision/CollisionCallbacks.cpp b/engine/server/library/serverGame/src/shared/collision/CollisionCallbacks.cpp index 9bce1404..8c7e6325 100755 --- a/engine/server/library/serverGame/src/shared/collision/CollisionCallbacks.cpp +++ b/engine/server/library/serverGame/src/shared/collision/CollisionCallbacks.cpp @@ -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(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; } diff --git a/engine/shared/library/sharedGame/src/shared/collision/CollisionCallbackManager.cpp b/engine/shared/library/sharedGame/src/shared/collision/CollisionCallbackManager.cpp index 89f58b9a..0d1f138d 100755 --- a/engine/shared/library/sharedGame/src/shared/collision/CollisionCallbackManager.cpp +++ b/engine/shared/library/sharedGame/src/shared/collision/CollisionCallbackManager.cpp @@ -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; + } } } diff --git a/engine/shared/library/sharedTerrain/src/shared/appearance/ProceduralTerrainAppearance.cpp b/engine/shared/library/sharedTerrain/src/shared/appearance/ProceduralTerrainAppearance.cpp index 3ffa961b..1b99f7e8 100755 --- a/engine/shared/library/sharedTerrain/src/shared/appearance/ProceduralTerrainAppearance.cpp +++ b/engine/shared/library/sharedTerrain/src/shared/appearance/ProceduralTerrainAppearance.cpp @@ -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 (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; diff --git a/engine/shared/library/sharedTerrain/src/shared/appearance/ProceduralTerrainAppearance.h b/engine/shared/library/sharedTerrain/src/shared/appearance/ProceduralTerrainAppearance.h index 40de93a1..a7b4b149 100755 --- a/engine/shared/library/sharedTerrain/src/shared/appearance/ProceduralTerrainAppearance.h +++ b/engine/shared/library/sharedTerrain/src/shared/appearance/ProceduralTerrainAppearance.h @@ -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; diff --git a/engine/shared/library/sharedTerrain/src/shared/appearance/SamplerProceduralTerrainAppearance.cpp b/engine/shared/library/sharedTerrain/src/shared/appearance/SamplerProceduralTerrainAppearance.cpp index be65e8a2..b6e804a5 100755 --- a/engine/shared/library/sharedTerrain/src/shared/appearance/SamplerProceduralTerrainAppearance.cpp +++ b/engine/shared/library/sharedTerrain/src/shared/appearance/SamplerProceduralTerrainAppearance.cpp @@ -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 diff --git a/engine/shared/library/sharedTerrain/src/shared/appearance/SamplerProceduralTerrainAppearance.h b/engine/shared/library/sharedTerrain/src/shared/appearance/SamplerProceduralTerrainAppearance.h index a80374e4..314a368f 100755 --- a/engine/shared/library/sharedTerrain/src/shared/appearance/SamplerProceduralTerrainAppearance.h +++ b/engine/shared/library/sharedTerrain/src/shared/appearance/SamplerProceduralTerrainAppearance.h @@ -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; diff --git a/engine/shared/library/sharedTerrain/src/shared/appearance/ServerProceduralTerrainAppearance.cpp b/engine/shared/library/sharedTerrain/src/shared/appearance/ServerProceduralTerrainAppearance.cpp index 938c4f2f..293f3dfc 100755 --- a/engine/shared/library/sharedTerrain/src/shared/appearance/ServerProceduralTerrainAppearance.cpp +++ b/engine/shared/library/sharedTerrain/src/shared/appearance/ServerProceduralTerrainAppearance.cpp @@ -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(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)); diff --git a/engine/shared/library/sharedTerrain/src/shared/appearance/ServerProceduralTerrainAppearance.h b/engine/shared/library/sharedTerrain/src/shared/appearance/ServerProceduralTerrainAppearance.h index 7857ed28..25bb1070 100755 --- a/engine/shared/library/sharedTerrain/src/shared/appearance/ServerProceduralTerrainAppearance.h +++ b/engine/shared/library/sharedTerrain/src/shared/appearance/ServerProceduralTerrainAppearance.h @@ -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: diff --git a/engine/shared/library/sharedTerrain/src/shared/appearance/TerrainAppearance.cpp b/engine/shared/library/sharedTerrain/src/shared/appearance/TerrainAppearance.cpp index adc87c0f..3cc4886b 100755 --- a/engine/shared/library/sharedTerrain/src/shared/appearance/TerrainAppearance.cpp +++ b/engine/shared/library/sharedTerrain/src/shared/appearance/TerrainAppearance.cpp @@ -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; +} //------------------------------------------------------------------- diff --git a/engine/shared/library/sharedTerrain/src/shared/appearance/TerrainAppearance.h b/engine/shared/library/sharedTerrain/src/shared/appearance/TerrainAppearance.h index e90d9558..ffbd24ca 100755 --- a/engine/shared/library/sharedTerrain/src/shared/appearance/TerrainAppearance.h +++ b/engine/shared/library/sharedTerrain/src/shared/appearance/TerrainAppearance.h @@ -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; diff --git a/engine/shared/library/sharedTerrain/src/shared/object/TerrainObject.cpp b/engine/shared/library/sharedTerrain/src/shared/object/TerrainObject.cpp index 5206146a..1414db70 100755 --- a/engine/shared/library/sharedTerrain/src/shared/object/TerrainObject.cpp +++ b/engine/shared/library/sharedTerrain/src/shared/object/TerrainObject.cpp @@ -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)); diff --git a/engine/shared/library/sharedTerrain/src/shared/object/TerrainObject.h b/engine/shared/library/sharedTerrain/src/shared/object/TerrainObject.h index 9ecdde2f..0030503b 100755 --- a/engine/shared/library/sharedTerrain/src/shared/object/TerrainObject.h +++ b/engine/shared/library/sharedTerrain/src/shared/object/TerrainObject.h @@ -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;