From 4b23576df1d428fc90c9a653d3dde063e32682e5 Mon Sep 17 00:00:00 2001 From: curt Date: Wed, 11 Jul 2001 15:51:21 +0000 Subject: [PATCH] Shuffled around and restructured the terrain elevation interesection code to make it usable by the threaded tile loader for placing objects at ground level at load time. --- src/Scenery/hitlist.cxx | 83 +++++++++++++++++++++++++++++++++++++++++ src/Scenery/hitlist.hxx | 9 +++++ src/Scenery/tilemgr.cxx | 83 ++++------------------------------------- src/Scenery/tilemgr.hxx | 5 --- 4 files changed, 100 insertions(+), 80 deletions(-) diff --git a/src/Scenery/hitlist.cxx b/src/Scenery/hitlist.cxx index 027b4b15b..b5abb7805 100644 --- a/src/Scenery/hitlist.cxx +++ b/src/Scenery/hitlist.cxx @@ -14,11 +14,19 @@ #include #include +#include +#include +#include #include +#include
+ #include "hitlist.hxx" +extern ssgBranch *terrain; + + // check to see if the intersection point is // actually inside this face static bool sgdPointInTriangle( sgdVec3 point, sgdVec3 tri[3] ) @@ -304,3 +312,78 @@ void FGHitList::IntersectCachedLeaf( sgdMat4 m, } } } + + +static void CurrentNormalInLocalPlane(sgVec3 dst, sgVec3 src) { + sgVec3 tmp; + sgSetVec3(tmp, src[0], src[1], src[2] ); + sgMat4 TMP; + sgTransposeNegateMat4 ( TMP, globals->get_current_view()->get_UP() ) ; + sgXformVec3(tmp, tmp, TMP); + sgSetVec3(dst, tmp[2], tmp[1], tmp[0] ); +} + + +// a temporary hack until we get everything rewritten with sgdVec3 +static inline Point3D operator + (const Point3D& a, const sgdVec3 b) +{ + return Point3D(a.x()+b[0], a.y()+b[1], a.z()+b[2]); +} + + +// Determine scenery altitude via ssg. Normally this just happens +// when we render the scene, but we'd also like to be able to do this +// explicitely. lat & lon are in radians. view_pos in current world +// coordinate translated near (0,0,0) (in meters.) Returns result in +// meters. +bool fgCurrentElev( sgdVec3 abs_view_pos, sgdVec3 scenery_center, + FGHitList *hit_list, + double *terrain_elev, double *radius, double *normal) +{ + sgdVec3 view_pos; + sgdSubVec3( view_pos, abs_view_pos, scenery_center ); + + sgdVec3 orig, dir; + sgdCopyVec3(orig, view_pos ); + sgdCopyVec3(dir, abs_view_pos ); + + hit_list->Intersect( terrain, orig, dir ); + + int this_hit=0; + Point3D geoc; + double result = -9999; + Point3D sc(scenery_center[0], scenery_center[1], scenery_center[2]) ; + + int hitcount = hit_list->num_hits(); + for ( int i = 0; i < hitcount; ++i ) { + geoc = sgCartToPolar3d( sc + hit_list->get_point(i) ); + double lat_geod, alt, sea_level_r; + sgGeocToGeod(geoc.lat(), geoc.radius(), &lat_geod, + &alt, &sea_level_r); + if ( alt > result && alt < 10000 ) { + result = alt; + this_hit = i; + } + } + + if ( result > -9000 ) { + *terrain_elev = result; + *radius = geoc.radius(); + sgVec3 tmp; + sgSetVec3(tmp, hit_list->get_normal(this_hit)); + // cout << "cur_normal: " << tmp[0] << " " << tmp[1] << " " + // << tmp[2] << endl; + /* ssgState *IntersectedLeafState = + ((ssgLeaf*)hit_list->get_entity(this_hit))->getState(); */ + CurrentNormalInLocalPlane(tmp, tmp); + sgdSetVec3( normal, tmp ); + // cout << "NED: " << tmp[0] << " " << tmp[1] << " " << tmp[2] << endl; + return true; + } else { + SG_LOG( SG_TERRAIN, SG_INFO, "no terrain intersection" ); + *terrain_elev = 0.0; + float *up = globals->get_current_view()->get_world_up(); + sgdSetVec3(normal, up[0], up[1], up[2]); + return false; + } +} diff --git a/src/Scenery/hitlist.hxx b/src/Scenery/hitlist.hxx index 0fa5d7465..709b23a20 100644 --- a/src/Scenery/hitlist.hxx +++ b/src/Scenery/hitlist.hxx @@ -93,4 +93,13 @@ inline void FGHitList::Intersect( ssgBranch *scene, } } + +// Associated function, assuming a wgs84 world with 0,0,0 at the +// center, find the current terrain intersection elevation for the +// point specified. +bool fgCurrentElev( sgdVec3 abs_view_pos, sgdVec3 scenery_center, + FGHitList *hit_list, + double *terrain_elev, double *radius, double *normal ); + + #endif // _HITLIST_HXX diff --git a/src/Scenery/tilemgr.cxx b/src/Scenery/tilemgr.cxx index 399336849..d162a00e4 100644 --- a/src/Scenery/tilemgr.cxx +++ b/src/Scenery/tilemgr.cxx @@ -63,12 +63,6 @@ extern ssgBranch *ground; FGTileMgr global_tile_mgr; -// a temporary hack until we get everything rewritten with sgdVec3 -static inline Point3D operator + (const Point3D& a, const sgdVec3 b) -{ - return Point3D(a.x()+b[0], a.y()+b[1], a.z()+b[2]); -} - #ifdef ENABLE_THREADS SGLockedQueue FGTileMgr::attach_queue; SGLockedQueue FGTileMgr::model_queue; @@ -153,72 +147,6 @@ void FGTileMgr::sched_tile( const SGBucket& b ) { } -static void CurrentNormalInLocalPlane(sgVec3 dst, sgVec3 src) { - sgVec3 tmp; - sgSetVec3(tmp, src[0], src[1], src[2] ); - sgMat4 TMP; - sgTransposeNegateMat4 ( TMP, globals->get_current_view()->get_UP() ) ; - sgXformVec3(tmp, tmp, TMP); - sgSetVec3(dst, tmp[2], tmp[1], tmp[0] ); -} - - -// Determine scenery altitude via ssg. Normally this just happens -// when we render the scene, but we'd also like to be able to do this -// explicitely. lat & lon are in radians. view_pos in current world -// coordinate translated near (0,0,0) (in meters.) Returns result in -// meters. -bool FGTileMgr::current_elev_ssg( sgdVec3 abs_view_pos, double *terrain_elev ) { - sgdVec3 view_pos; - sgdVec3 sc; - sgdSetVec3( sc, scenery.center.x(), scenery.center.y(), scenery.center.z()); - sgdSubVec3( view_pos, abs_view_pos, sc ); - - sgdVec3 orig, dir; - sgdCopyVec3(orig, view_pos ); - sgdCopyVec3(dir, abs_view_pos ); - - hit_list.Intersect( terrain, orig, dir ); - - int this_hit=0; - Point3D geoc; - double result = -9999; - - int hitcount = hit_list.num_hits(); - for ( int i = 0; i < hitcount; ++i ) { - geoc = sgCartToPolar3d( scenery.center + hit_list.get_point(i) ); - double lat_geod, alt, sea_level_r; - sgGeocToGeod(geoc.lat(), geoc.radius(), &lat_geod, - &alt, &sea_level_r); - if ( alt > result && alt < 10000 ) { - result = alt; - this_hit = i; - } - } - - if ( result > -9000 ) { - *terrain_elev = result; - scenery.cur_radius = geoc.radius(); - sgVec3 tmp; - sgSetVec3(tmp, hit_list.get_normal(this_hit)); - // cout << "cur_normal: " << tmp[0] << " " << tmp[1] << " " - // << tmp[2] << endl; - /* ssgState *IntersectedLeafState = - ((ssgLeaf*)hit_list.get_entity(this_hit))->getState(); */ - CurrentNormalInLocalPlane(tmp, tmp); - sgdSetVec3( scenery.cur_normal, tmp ); - // cout << "NED: " << tmp[0] << " " << tmp[1] << " " << tmp[2] << endl; - return true; - } else { - SG_LOG( SG_TERRAIN, SG_INFO, "no terrain intersection" ); - *terrain_elev = 0.0; - float *up = globals->get_current_view()->get_world_up(); - sgdSetVec3(scenery.cur_normal, up[0], up[1], up[2]); - return false; - } -} - - // schedule a needed buckets for loading void FGTileMgr::schedule_needed() { #ifndef FG_OLD_WEATHER @@ -401,6 +329,8 @@ int FGTileMgr::update( double lon, double lat ) { } } counter_hack = (counter_hack + 1) % 5; + sgdVec3 sc; + sgdSetVec3( sc, scenery.center[0], scenery.center[1], scenery.center[2] ); if ( scenery.center == Point3D(0.0) ) { // initializing @@ -419,7 +349,9 @@ int FGTileMgr::update( double lon, double lat ) { prep_ssg_nodes(); sgSetVec3( tmp_view_pos, 0.0, 0.0, 0.0 ); double tmp_elev; - if ( current_elev_ssg(tmp_abs_view_pos, &tmp_elev) ) { + if ( fgCurrentElev(tmp_abs_view_pos, sc, &hit_list, + &tmp_elev, &scenery.cur_radius, scenery.cur_normal) ) + { scenery.cur_elev = tmp_elev; } else { scenery.cur_elev = 0.0; @@ -429,8 +361,9 @@ int FGTileMgr::update( double lon, double lat ) { // cout << "abs view pos = " << current_view.abs_view_pos // << " view pos = " << current_view.view_pos << endl; double tmp_elev; - if ( current_elev_ssg(globals->get_current_view()->get_abs_view_pos(), - &tmp_elev) ) + if ( fgCurrentElev(globals->get_current_view()->get_abs_view_pos(), + sc, &hit_list, + &tmp_elev, &scenery.cur_radius, scenery.cur_normal) ) { scenery.cur_elev = tmp_elev; } else { diff --git a/src/Scenery/tilemgr.hxx b/src/Scenery/tilemgr.hxx index a6cfeb5b7..fe9c6fd2f 100644 --- a/src/Scenery/tilemgr.hxx +++ b/src/Scenery/tilemgr.hxx @@ -81,10 +81,6 @@ private: // see comment at prep_ssg_nodes() void prep_ssg_node( int idx ); - // int hitcount; - // sgdVec3 hit_pts [ MAX_HITS ] ; - - // ssgEntity *last_hit; FGHitList hit_list; SGBucket previous_bucket; @@ -177,7 +173,6 @@ public: const sgdVec3 p, const sgdVec3 dir, FGHitList *list ); - bool current_elev_ssg( sgdVec3 abs_view_pos, double *terrain_elev ); // Prepare the ssg nodes ... for each tile, set it's proper // transform and update it's range selector based on current -- 2.39.5