Incorporated Norman's optimized line/geometry intersection code.
This commit is contained in:
parent
3bf7269174
commit
8138c82b58
4 changed files with 668 additions and 334 deletions
File diff suppressed because it is too large
Load diff
|
@ -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
|
#ifndef _HITLIST_HXX
|
||||||
#define _HITLIST_HXX
|
#define _HITLIST_HXX
|
||||||
|
|
||||||
|
@ -11,8 +15,9 @@
|
||||||
|
|
||||||
#include <plib/ssg.h>
|
#include <plib/ssg.h>
|
||||||
|
|
||||||
SG_USING_STD(vector);
|
#define FAST_HITLIST__TEST 1
|
||||||
|
|
||||||
|
SG_USING_STD(vector);
|
||||||
|
|
||||||
class FGHitRec {
|
class FGHitRec {
|
||||||
|
|
||||||
|
@ -44,11 +49,12 @@ private:
|
||||||
|
|
||||||
ssgEntity *last;
|
ssgEntity *last;
|
||||||
vector < FGHitRec > list;
|
vector < FGHitRec > list;
|
||||||
|
double test_dist;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
FGHitList() { last = NULL; }
|
FGHitList() { last = NULL; test_dist=DBL_MAX; }
|
||||||
void init(void) { list.clear(); }
|
void init(void) { list.clear(); test_dist=DBL_MAX; }
|
||||||
void clear(void) { init(); last = NULL; }
|
void clear(void) { init(); last = NULL; }
|
||||||
void add( ssgEntity *ent, int idx, sgdVec3 point, sgdVec3 normal ) {
|
void add( ssgEntity *ent, int idx, sgdVec3 point, sgdVec3 normal ) {
|
||||||
list.push_back( FGHitRec( ent,idx,point,normal) );
|
list.push_back( FGHitRec( ent,idx,point,normal) );
|
||||||
|
@ -63,24 +69,47 @@ public:
|
||||||
|
|
||||||
void Intersect( ssgBranch *branch,
|
void Intersect( ssgBranch *branch,
|
||||||
sgdVec3 orig, sgdVec3 dir );
|
sgdVec3 orig, sgdVec3 dir );
|
||||||
|
void Intersect( ssgBranch *scene, sgdMat4 m,
|
||||||
|
sgdVec3 orig, sgdVec3 dir );
|
||||||
|
|
||||||
void IntersectBranch( ssgBranch *branch, sgdMat4 m,
|
void IntersectBranch( ssgBranch *branch, sgdMat4 m,
|
||||||
sgdVec3 orig, sgdVec3 dir);
|
sgdVec3 orig, sgdVec3 dir);
|
||||||
|
|
||||||
void IntersectCachedLeaf( sgdMat4 m,
|
void IntersectCachedLeaf( sgdVec3 orig, sgdVec3 dir);
|
||||||
sgdVec3 orig, sgdVec3 dir);
|
|
||||||
|
|
||||||
int IntersectLeaf( ssgLeaf *leaf, sgdMat4 m,
|
int IntersectLeaf( ssgLeaf *leaf, sgdMat4 m,
|
||||||
sgdVec3 orig, sgdVec3 dir );
|
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
|
// Associated function, assuming a wgs84 world with 0,0,0 at the
|
||||||
// center, find the current terrain intersection elevation for the
|
// center, find the current terrain intersection elevation for the
|
||||||
// point specified.
|
// 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,
|
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
|
#endif // _HITLIST_HXX
|
||||||
|
|
|
@ -266,6 +266,12 @@ public:
|
||||||
* graph for this tile.
|
* graph for this tile.
|
||||||
*/
|
*/
|
||||||
void disconnect_ssg_nodes();
|
void disconnect_ssg_nodes();
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* return the SSG Transform node for the terrain
|
||||||
|
*/
|
||||||
|
inline ssgTransform *get_terra_transform() { return terra_transform; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -292,7 +292,8 @@ int FGTileMgr::update( double lon, double lat ) {
|
||||||
// happen in the render thread because model loading can trigger
|
// happen in the render thread because model loading can trigger
|
||||||
// texture loading which involves use of the opengl api.
|
// texture loading which involves use of the opengl api.
|
||||||
if ( !model_queue.empty() ) {
|
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
|
#ifdef ENABLE_THREADS
|
||||||
FGDeferredModel* dm = model_queue.pop();
|
FGDeferredModel* dm = model_queue.pop();
|
||||||
#else
|
#else
|
||||||
|
@ -311,6 +312,8 @@ int FGTileMgr::update( double lon, double lat ) {
|
||||||
delete dm;
|
delete dm;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// cout << "current elevation (ssg) == " << scenery.get_cur_elev() << endl;
|
||||||
|
|
||||||
previous_bucket = current_bucket;
|
previous_bucket = current_bucket;
|
||||||
last_longitude = longitude;
|
last_longitude = longitude;
|
||||||
last_latitude = latitude;
|
last_latitude = latitude;
|
||||||
|
@ -334,6 +337,7 @@ int FGTileMgr::update( double lon, double lat ) {
|
||||||
e->add_ssg_nodes( terrain_branch,
|
e->add_ssg_nodes( terrain_branch,
|
||||||
gnd_lights_branch,
|
gnd_lights_branch,
|
||||||
rwy_lights_branch );
|
rwy_lights_branch );
|
||||||
|
// cout << "Adding ssg nodes for "
|
||||||
}
|
}
|
||||||
|
|
||||||
sgdVec3 sc;
|
sgdVec3 sc;
|
||||||
|
@ -345,6 +349,7 @@ int FGTileMgr::update( double lon, double lat ) {
|
||||||
#if 0
|
#if 0
|
||||||
if ( scenery.center == Point3D(0.0) ) {
|
if ( scenery.center == Point3D(0.0) ) {
|
||||||
// initializing
|
// initializing
|
||||||
|
cout << "initializing scenery current elevation ... " << endl;
|
||||||
sgdVec3 tmp_abs_view_pos;
|
sgdVec3 tmp_abs_view_pos;
|
||||||
|
|
||||||
Point3D geod_pos = Point3D( longitude * SGD_DEGREES_TO_RADIANS,
|
Point3D geod_pos = Point3D( longitude * SGD_DEGREES_TO_RADIANS,
|
||||||
|
@ -354,6 +359,7 @@ int FGTileMgr::update( double lon, double lat ) {
|
||||||
scenery.center = tmp;
|
scenery.center = tmp;
|
||||||
sgdSetVec3( tmp_abs_view_pos, tmp.x(), tmp.y(), tmp.z() );
|
sgdSetVec3( tmp_abs_view_pos, tmp.x(), tmp.y(), tmp.z() );
|
||||||
|
|
||||||
|
// cout << "abs_view_pos = " << tmp_abs_view_pos << endl;
|
||||||
prep_ssg_nodes();
|
prep_ssg_nodes();
|
||||||
|
|
||||||
double tmp_elev;
|
double tmp_elev;
|
||||||
|
@ -364,8 +370,25 @@ int FGTileMgr::update( double lon, double lat ) {
|
||||||
} else {
|
} else {
|
||||||
scenery.set_cur_elev( 0.0 );
|
scenery.set_cur_elev( 0.0 );
|
||||||
}
|
}
|
||||||
|
// cout << "result = " << scenery.get_cur_elev() << endl;
|
||||||
} else {
|
} else {
|
||||||
#endif
|
#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
|
// overridden with actual values if a terrain intersection is
|
||||||
// found
|
// found
|
||||||
double hit_elev = -9999.0;
|
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 ) {
|
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
|
// scenery center has been properly defined so any hit
|
||||||
// should be valid (and not just luck)
|
// should be valid (and not just luck)
|
||||||
hit = fgCurrentElev(globals->get_current_view()->get_abs_view_pos(),
|
sgdSetVec3( sc,
|
||||||
sc,
|
scenery.get_center()[0],
|
||||||
&hit_list,
|
scenery.get_center()[1],
|
||||||
&hit_elev,
|
scenery.get_center()[2] );
|
||||||
&hit_radius,
|
hit = fgCurrentElev(globals->get_current_view()->get_abs_view_pos(),
|
||||||
hit_normal);
|
sc,
|
||||||
|
current_tile->get_terra_transform(),
|
||||||
|
&hit_list,
|
||||||
|
&hit_elev,
|
||||||
|
&hit_radius,
|
||||||
|
hit_normal);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( hit ) {
|
if ( hit ) {
|
||||||
|
@ -393,6 +421,8 @@ int FGTileMgr::update( double lon, double lat ) {
|
||||||
scenery.set_cur_radius( 0.0 );
|
scenery.set_cur_radius( 0.0 );
|
||||||
scenery.set_cur_normal( hit_normal );
|
scenery.set_cur_normal( hit_normal );
|
||||||
}
|
}
|
||||||
|
// cout << "Current elevation = " << scenery.get_cur_elev() << endl;
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -413,7 +443,8 @@ void FGTileMgr::prep_ssg_nodes() {
|
||||||
tile_cache.reset_traversal();
|
tile_cache.reset_traversal();
|
||||||
|
|
||||||
while ( ! tile_cache.at_end() ) {
|
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);
|
e->prep_ssg_node( scenery.get_center(), vis);
|
||||||
} else {
|
} else {
|
||||||
SG_LOG(SG_INPUT, SG_ALERT, "warning ... empty tile in cache");
|
SG_LOG(SG_INPUT, SG_ALERT, "warning ... empty tile in cache");
|
||||||
|
|
Loading…
Add table
Reference in a new issue