1
0
Fork 0

Incorporated Norman's optimized line/geometry intersection code.

This commit is contained in:
curt 2002-03-17 00:38:24 +00:00
parent 3bf7269174
commit 8138c82b58
4 changed files with 668 additions and 334 deletions

File diff suppressed because it is too large Load diff

View file

@ -1,3 +1,7 @@
// hitlist.hxx
// Height Over Terrain and Assosciated Routines for FlightGear based Scenery
// Written by Norman Vine, started 2000.
#ifndef _HITLIST_HXX
#define _HITLIST_HXX
@ -11,8 +15,9 @@
#include <plib/ssg.h>
SG_USING_STD(vector);
#define FAST_HITLIST__TEST 1
SG_USING_STD(vector);
class FGHitRec {
@ -44,11 +49,12 @@ private:
ssgEntity *last;
vector < FGHitRec > list;
double test_dist;
public:
FGHitList() { last = NULL; }
void init(void) { list.clear(); }
FGHitList() { last = NULL; test_dist=DBL_MAX; }
void init(void) { list.clear(); test_dist=DBL_MAX; }
void clear(void) { init(); last = NULL; }
void add( ssgEntity *ent, int idx, sgdVec3 point, sgdVec3 normal ) {
list.push_back( FGHitRec( ent,idx,point,normal) );
@ -63,24 +69,47 @@ public:
void Intersect( ssgBranch *branch,
sgdVec3 orig, sgdVec3 dir );
void Intersect( ssgBranch *scene, sgdMat4 m,
sgdVec3 orig, sgdVec3 dir );
void IntersectBranch( ssgBranch *branch, sgdMat4 m,
sgdVec3 orig, sgdVec3 dir);
void IntersectCachedLeaf( sgdMat4 m,
sgdVec3 orig, sgdVec3 dir);
void IntersectCachedLeaf( sgdVec3 orig, sgdVec3 dir);
int IntersectLeaf( ssgLeaf *leaf, sgdMat4 m,
sgdVec3 orig, sgdVec3 dir );
int IntersectPolyOrFanLeaf( ssgLeaf *leaf, sgdMat4 m,
sgdVec3 orig, sgdVec3 dir );
int IntersectTriLeaf( ssgLeaf *leaf, sgdMat4 m,
sgdVec3 orig, sgdVec3 dir );
int IntersectStripLeaf( ssgLeaf *leaf, sgdMat4 m,
sgdVec3 orig, sgdVec3 dir );
int IntersectQuadsLeaf( ssgLeaf *leaf, sgdMat4 m,
sgdVec3 orig, sgdVec3 dir );
};
// 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,
bool fgCurrentElev( sgdVec3 abs_view_pos,
sgdVec3 scenery_center,
ssgTransform *terra_transform,
FGHitList *hit_list,
double *terrain_elev, double *radius, double *normal );
double *terrain_elev,
double *radius,
double *normal );
bool fgCurrentElev( sgdVec3 abs_view_pos,
sgdVec3 scenery_center,
FGHitList *hit_list,
double *terrain_elev,
double *radius,
double *normal );
#endif // _HITLIST_HXX

View file

@ -266,6 +266,12 @@ public:
* graph for this tile.
*/
void disconnect_ssg_nodes();
/**
* return the SSG Transform node for the terrain
*/
inline ssgTransform *get_terra_transform() { return terra_transform; }
};

View file

@ -292,7 +292,8 @@ int FGTileMgr::update( double lon, double lat ) {
// happen in the render thread because model loading can trigger
// texture loading which involves use of the opengl api.
if ( !model_queue.empty() ) {
// load the next tile in the queue
// cout << "loading next model ..." << endl;
// load the next tile in the queue
#ifdef ENABLE_THREADS
FGDeferredModel* dm = model_queue.pop();
#else
@ -311,6 +312,8 @@ int FGTileMgr::update( double lon, double lat ) {
delete dm;
}
// cout << "current elevation (ssg) == " << scenery.get_cur_elev() << endl;
previous_bucket = current_bucket;
last_longitude = longitude;
last_latitude = latitude;
@ -334,6 +337,7 @@ int FGTileMgr::update( double lon, double lat ) {
e->add_ssg_nodes( terrain_branch,
gnd_lights_branch,
rwy_lights_branch );
// cout << "Adding ssg nodes for "
}
sgdVec3 sc;
@ -345,6 +349,7 @@ int FGTileMgr::update( double lon, double lat ) {
#if 0
if ( scenery.center == Point3D(0.0) ) {
// initializing
cout << "initializing scenery current elevation ... " << endl;
sgdVec3 tmp_abs_view_pos;
Point3D geod_pos = Point3D( longitude * SGD_DEGREES_TO_RADIANS,
@ -354,6 +359,7 @@ int FGTileMgr::update( double lon, double lat ) {
scenery.center = tmp;
sgdSetVec3( tmp_abs_view_pos, tmp.x(), tmp.y(), tmp.z() );
// cout << "abs_view_pos = " << tmp_abs_view_pos << endl;
prep_ssg_nodes();
double tmp_elev;
@ -364,8 +370,25 @@ int FGTileMgr::update( double lon, double lat ) {
} else {
scenery.set_cur_elev( 0.0 );
}
// cout << "result = " << scenery.get_cur_elev() << endl;
} else {
#endif
/*
cout << "abs view pos = "
<< globals->get_current_view()->get_abs_view_pos()[0] << ","
<< globals->get_current_view()->get_abs_view_pos()[1] << ","
<< globals->get_current_view()->get_abs_view_pos()[2]
<< " view pos = "
<< globals->get_current_view()->get_view_pos()[0] << ","
<< globals->get_current_view()->get_view_pos()[1] << ","
<< globals->get_current_view()->get_view_pos()[2]
<< endl;
cout << "current_tile = " << current_tile << endl;
cout << "Scenery center = " << sc[0] << "," << sc[1] << "," << sc[2]
<< endl;
*/
// overridden with actual values if a terrain intersection is
// found
double hit_elev = -9999.0;
@ -376,12 +399,17 @@ int FGTileMgr::update( double lon, double lat ) {
if ( fabs(sc[0]) > 1.0 || fabs(sc[1]) > 1.0 || fabs(sc[2]) > 1.0 ) {
// scenery center has been properly defined so any hit
// should be valid (and not just luck)
hit = fgCurrentElev(globals->get_current_view()->get_abs_view_pos(),
sc,
&hit_list,
&hit_elev,
&hit_radius,
hit_normal);
sgdSetVec3( sc,
scenery.get_center()[0],
scenery.get_center()[1],
scenery.get_center()[2] );
hit = fgCurrentElev(globals->get_current_view()->get_abs_view_pos(),
sc,
current_tile->get_terra_transform(),
&hit_list,
&hit_elev,
&hit_radius,
hit_normal);
}
if ( hit ) {
@ -393,6 +421,8 @@ int FGTileMgr::update( double lon, double lat ) {
scenery.set_cur_radius( 0.0 );
scenery.set_cur_normal( hit_normal );
}
// cout << "Current elevation = " << scenery.get_cur_elev() << endl;
#if 0
}
#endif
@ -413,7 +443,8 @@ void FGTileMgr::prep_ssg_nodes() {
tile_cache.reset_traversal();
while ( ! tile_cache.at_end() ) {
if ( (e = tile_cache.get_current()) ) {
// cout << "processing a tile" << endl;
if ( (e = tile_cache.get_current()) ) {
e->prep_ssg_node( scenery.get_center(), vis);
} else {
SG_LOG(SG_INPUT, SG_ALERT, "warning ... empty tile in cache");