From: frohlich Date: Sun, 11 Jun 2006 13:34:18 +0000 (+0000) Subject: Modified Files: X-Git-Url: https://git.mxchange.org/?a=commitdiff_plain;h=14fe03ba6fd65efdf3283fd692fe6347af722934;p=flightgear.git Modified Files: src/AIModel/AIAircraft.cxx src/ATC/AILocalTraffic.cxx src/FDM/flight.cxx src/FDM/flight.hxx src/FDM/groundcache.cxx src/FDM/groundcache.hxx src/Main/fg_init.cxx src/Main/main.cxx src/Scenery/hitlist.cxx src/Scenery/hitlist.hxx src/Scenery/scenery.cxx src/Scenery/scenery.hxx Make use of the attached SGMaterial reference userdata on scenegraph leafs. Make the SGMaterial pointer available to the ground query routines. --- diff --git a/src/AIModel/AIAircraft.cxx b/src/AIModel/AIAircraft.cxx index fb7edf751..5c560d9bc 100644 --- a/src/AIModel/AIAircraft.cxx +++ b/src/AIModel/AIAircraft.cxx @@ -941,7 +941,7 @@ void FGAIAircraft::getGroundElev(double dt) { // FIXME: make sure the pos.lat/pos.lon values are in degrees ... double alt; - if (globals->get_scenery()->get_elevation_m(pos.lat(), pos.lon(), 20000.0, alt)) + if (globals->get_scenery()->get_elevation_m(pos.lat(), pos.lon(), 20000.0, alt, 0)) tgt_altitude = alt * SG_METER_TO_FEET; //cerr << "Target altitude : " << tgt_altitude << endl; diff --git a/src/ATC/AILocalTraffic.cxx b/src/ATC/AILocalTraffic.cxx index 43d9b9485..15eb6a3d3 100644 --- a/src/ATC/AILocalTraffic.cxx +++ b/src/ATC/AILocalTraffic.cxx @@ -1590,7 +1590,7 @@ void FGAILocalTraffic::DoGroundElev() { // FIXME: make shure the pos.lat/pos.lon values are in degrees ... double alt; - if (globals->get_scenery()->get_elevation_m(lat, lon, 20000.0, alt)) + if (globals->get_scenery()->get_elevation_m(lat, lon, 20000.0, alt, 0)) _aip.getSGLocation()->set_cur_elev_m(alt); } diff --git a/src/FDM/flight.cxx b/src/FDM/flight.cxx index d6e5366c9..fcb71deed 100644 --- a/src/FDM/flight.cxx +++ b/src/FDM/flight.cxx @@ -32,6 +32,7 @@ #include #include #include +#include #include #include @@ -836,16 +837,28 @@ FGInterface::get_cat_ft(double t, const double pt[3], return dist*SG_METER_TO_FEET; } +// Legacy interface just kept because of JSBSim bool FGInterface::get_agl_m(double t, const double pt[3], double contact[3], double normal[3], double vel[3], int *type, double *loadCapacity, double *frictionFactor, double *agl) { - return ground_cache.get_agl(t, pt, 2.0, contact, normal, vel, type, - loadCapacity, frictionFactor, agl); + const SGMaterial* material; + bool ret = ground_cache.get_agl(t, pt, 2.0, contact, normal, vel, type, + &material, agl); + if (material) { + *loadCapacity = material->get_load_resistence(); + *frictionFactor = material->get_friction_factor(); + + } else { + *loadCapacity = DBL_MAX; + *frictionFactor = 1.0; + } + return ret; } +// Legacy interface just kept because of JSBSim bool FGInterface::get_agl_ft(double t, const double pt[3], double contact[3], double normal[3], double vel[3], @@ -855,45 +868,51 @@ FGInterface::get_agl_ft(double t, const double pt[3], // Convert units and do the real work. sgdVec3 pt_m; sgdScaleVec3( pt_m, pt, SG_FEET_TO_METER ); + + const SGMaterial* material; bool ret = ground_cache.get_agl(t, pt_m, 2.0, contact, normal, vel, - type, loadCapacity, frictionFactor, agl); + type, &material, agl); // Convert units back ... sgdScaleVec3( contact, SG_METER_TO_FEET ); sgdScaleVec3( vel, SG_METER_TO_FEET ); *agl *= SG_METER_TO_FEET; - // FIXME: scale the load limit to something in the english unit system. - // Be careful with the DBL_MAX which is returned by default. + + // return material properties if available + if (material) { + // FIXME: convert units?? now pascal to lbf/ft^2 + *loadCapacity = 0.020885434*material->get_load_resistence(); + *frictionFactor = material->get_friction_factor(); + } else { + *loadCapacity = DBL_MAX; + *frictionFactor = 1.0; + } return ret; } bool FGInterface::get_agl_m(double t, const double pt[3], double max_altoff, double contact[3], double normal[3], double vel[3], - int *type, double *loadCapacity, - double *frictionFactor, double *agl) + int *type, const SGMaterial** material, double *agl) { return ground_cache.get_agl(t, pt, max_altoff, contact, normal, vel, type, - loadCapacity, frictionFactor, agl); + material, agl); } bool FGInterface::get_agl_ft(double t, const double pt[3], double max_altoff, double contact[3], double normal[3], double vel[3], - int *type, double *loadCapacity, - double *frictionFactor, double *agl) + int *type, const SGMaterial** material, double *agl) { // Convert units and do the real work. sgdVec3 pt_m; sgdScaleVec3( pt_m, pt, SG_FEET_TO_METER ); bool ret = ground_cache.get_agl(t, pt_m, SG_FEET_TO_METER * max_altoff, contact, normal, vel, - type, loadCapacity, frictionFactor, agl); + type, material, agl); // Convert units back ... sgdScaleVec3( contact, SG_METER_TO_FEET ); sgdScaleVec3( vel, SG_METER_TO_FEET ); *agl *= SG_METER_TO_FEET; - // FIXME: scale the load limit to something in the english unit system. - // Be careful with the DBL_MAX which is returned by default. return ret; } @@ -936,13 +955,13 @@ FGInterface::get_groundlevel_m(double lat, double lon, double alt) } } - double contact[3], normal[3], vel[3], lc, ff, agl; + double contact[3], normal[3], vel[3], agl; int type; // Ignore the return value here, since it just tells us if // the returns stem from the groundcache or from the coarse // computations below the groundcache. The contact point is still something // valid, the normals and the other returns just contain some defaults. - get_agl_m(ref_time, pos, 2.0, contact, normal, vel, &type, &lc, &ff, &agl); + get_agl_m(ref_time, pos, 2.0, contact, normal, vel, &type, 0, &agl); Point3D geodPos = sgCartToGeod(Point3D(contact[0], contact[1], contact[2])); return geodPos.elev(); } diff --git a/src/FDM/flight.hxx b/src/FDM/flight.hxx index f26824d15..09d40bd32 100644 --- a/src/FDM/flight.hxx +++ b/src/FDM/flight.hxx @@ -1090,7 +1090,6 @@ public: enum GroundType { Unknown = 0, //?? Solid, // Whatever we will roll on with infinite load factor. - Forest, // Ground unsuitable for taxiing. Water, // For the beaver ... Catapult, // Carrier cats. Wire // Carrier wires. @@ -1133,14 +1132,17 @@ public: double contact[3], double normal[3], double vel[3], int *type, double *loadCapacity, double *frictionFactor, double *agl); + + // Return the altitude above ground below the wgs84 point pt + // Search for the nearest triangle to pt. + // Return ground properties like the ground type, a pointer to the + // material and finally the altitude above ground. bool get_agl_m(double t, const double pt[3], double max_altoff, double contact[3], double normal[3], double vel[3], - int *type, double *loadCapacity, - double *frictionFactor, double *agl); + int *type, const SGMaterial** material, double *agl); bool get_agl_ft(double t, const double pt[3], double max_altoff, double contact[3], double normal[3], double vel[3], - int *type, double *loadCapacity, - double *frictionFactor, double *agl); + int *type, const SGMaterial** material, double *agl); double get_groundlevel_m(double lat, double lon, double alt); diff --git a/src/FDM/groundcache.cxx b/src/FDM/groundcache.cxx index ac0fa40ac..d4cfb80a9 100644 --- a/src/FDM/groundcache.cxx +++ b/src/FDM/groundcache.cxx @@ -32,6 +32,8 @@ #include #include #include +#include +#include #include
#include @@ -233,32 +235,15 @@ FGGroundCache::extractGroundProperty( ssgLeaf* l ) } else { - // Initialize velocity field. sgdSetVec3( gp.vel, 0.0, 0.0, 0.0 ); sgdSetVec3( gp.rot, 0.0, 0.0, 0.0 ); sgdSetVec3( gp.pivot, 0.0, 0.0, 0.0 ); - } - - // Get the texture name and decide what ground type we have. - ssgState *st = l->getState(); - if (st != NULL && st->isAKindOf(ssgTypeSimpleState())) { - ssgSimpleState *ss = (ssgSimpleState*)st; - SGPath fullPath( ss->getTextureFilename() ? ss->getTextureFilename(): "" ); - string file = fullPath.file(); - SGPath dirPath(fullPath.dir()); - string category = dirPath.file(); - - if (category == "Runway") - gp.type = FGInterface::Solid; - else { - if (file == "asphault.rgb" || file == "airport.rgb") - gp.type = FGInterface::Solid; - else if (file == "water.rgb" || file == "water-lake.rgb") - gp.type = FGInterface::Water; - else if (file == "forest.rgb" || file == "cropwood.rgb") - gp.type = FGInterface::Forest; - } + + // get some material information for use in the gear model + gp.material = globals->get_matlib()->findMaterial(l); + if (gp.material) + gp.type = gp.material->get_solid() ? FGInterface::Solid : FGInterface::Water; } return gp; @@ -322,6 +307,7 @@ FGGroundCache::putSurfaceLeafIntoCache(const sgdSphere *sp, for (int i = 0; i < nt; ++i) { Triangle t; t.sphere.empty(); + t.material = gp.material; short v[3]; l->getTriangle(i, &v[0], &v[1], &v[2]); for (int k = 0; k < 3; ++k) { @@ -395,6 +381,7 @@ FGGroundCache::velocityTransformTriangle(double dt, sgdCopyVec3(dst.rotation_pivot, src.rotation_pivot); dst.type = src.type; + dst.material = src.material; if (dt*sgdLengthSquaredVec3(src.velocity) != 0) { sgdVec3 pivotoff, vel; @@ -621,15 +608,14 @@ FGGroundCache::get_cat(double t, const double dpt[3], bool FGGroundCache::get_agl(double t, const double dpt[3], double max_altoff, double contact[3], double normal[3], double vel[3], - int *type, double *loadCapacity, - double *frictionFactor, double *agl) + int *type, const SGMaterial** material, double *agl) { bool ret = false; *type = FGInterface::Unknown; // *agl = 0.0; - *loadCapacity = DBL_MAX; - *frictionFactor = 1.0; + if (material) + *material = 0; sgdSetVec3( vel, 0.0, 0.0, 0.0 ); sgdSetVec3( contact, 0.0, 0.0, 0.0 ); sgdSetVec3( normal, 0.0, 0.0, 0.0 ); @@ -683,11 +669,11 @@ FGGroundCache::get_agl(double t, const double dpt[3], double max_altoff, sgdAddVec3(vel, triangle.velocity); // Save the ground type. *type = triangle.type; - // FIXME: figure out how to get that sign ... -// *agl = sqrt(sqdist); - *agl = sgdLengthVec3( dpt ) - sgdLengthVec3( contact ); -// *loadCapacity = DBL_MAX; -// *frictionFactor = 1.0; + sgdVec3 dstToContact; + sgdSubVec3(dstToContact, contact, dpt); + *agl = sgdScalarProductVec3(dir, dstToContact); + if (material) + *material = triangle.material; } } } @@ -708,10 +694,10 @@ FGGroundCache::get_agl(double t, const double dpt[3], double max_altoff, // The altitude is the distance of the requested point from the // contact point. - *agl = sgdLengthVec3( dpt ) - sgdLengthVec3( contact ); + sgdVec3 dstToContact; + sgdSubVec3(dstToContact, contact, dpt); + *agl = sgdScalarProductVec3(dir, dstToContact); *type = FGInterface::Unknown; - *loadCapacity = DBL_MAX; - *frictionFactor = 1.0; return ret; } diff --git a/src/FDM/groundcache.hxx b/src/FDM/groundcache.hxx index 0b90c0d8e..e91534a63 100644 --- a/src/FDM/groundcache.hxx +++ b/src/FDM/groundcache.hxx @@ -28,6 +28,8 @@ #include #include +class SGMaterial; + class FGGroundCache { public: FGGroundCache(); @@ -63,8 +65,7 @@ public: // and finally the altitude above ground. bool get_agl(double t, const double pt[3], double max_altoff, double contact[3], double normal[3], double vel[3], - int *type, double *loadCapacity, - double *frictionFactor, double *agl); + int *type, const SGMaterial** material, double *agl); // Return 1 if the hook intersects with a wire. // That test is done by checking if the quad spanned by the points pt* @@ -82,6 +83,7 @@ public: private: struct Triangle { + Triangle() : material(0) {} // The edge vertices. sgdVec3 vertices[3]; // The surface normal. @@ -94,6 +96,8 @@ private: sgdVec3 rotation_pivot; // Ground type int type; + // the simgear material reference, contains friction coeficients ... + const SGMaterial* material; }; struct Catapult { sgdVec3 start; @@ -147,14 +151,13 @@ private: // Helper class to hold some properties of the ground triangle. struct GroundProperty { - GroundProperty() : type(0) {} + GroundProperty() : type(0), material(0) {} int type; int wire_id; sgdVec3 vel; sgdVec3 rot; sgdVec3 pivot; - // not yet implemented ... -// double loadCapacity; + const SGMaterial* material; }; // compute the ground property of this leaf. diff --git a/src/Main/main.cxx b/src/Main/main.cxx index b484917af..f490eb062 100644 --- a/src/Main/main.cxx +++ b/src/Main/main.cxx @@ -561,7 +561,7 @@ static void fgMainLoop( void ) { } else { // Do full intersection test. double lev; - if (globals->get_scenery()->get_elevation_m(lat, lon, alt+2, lev)) + if (globals->get_scenery()->get_elevation_m(lat, lon, alt+2, lev, 0)) view_location->set_cur_elev_m( lev ); else view_location->set_cur_elev_m( -9999.0 ); diff --git a/src/Scenery/hitlist.cxx b/src/Scenery/hitlist.cxx index 264c6f9f8..afeb3bb1b 100644 --- a/src/Scenery/hitlist.cxx +++ b/src/Scenery/hitlist.cxx @@ -700,7 +700,7 @@ bool fgCurrentElev( sgdVec3 abs_view_pos, double max_alt_m, // returned results are in meters bool fgCurrentElev( sgdVec3 abs_view_pos, double max_alt_m, sgdVec3 scenery_center, - ssgTransform *terra_transform, + ssgBranch *branch, FGHitList *hit_list, double *terrain_elev, double *radius, double *normal, int & this_hit ) @@ -719,11 +719,11 @@ bool fgCurrentElev( sgdVec3 abs_view_pos, double max_alt_m, sgMat4 fxform; sgMakeIdentMat4 ( fxform ) ; - ssgGetEntityTransform( terra_transform, fxform ); + ssgGetEntityTransform( branch, fxform ); sgdMat4 xform; sgdSetMat4(xform,fxform); - hit_list->Intersect( terra_transform, xform, orig, dir ); + hit_list->Intersect( branch, xform, orig, dir ); this_hit = -1; int max_hit = -1; diff --git a/src/Scenery/hitlist.hxx b/src/Scenery/hitlist.hxx index 0bb99c074..cec41f967 100644 --- a/src/Scenery/hitlist.hxx +++ b/src/Scenery/hitlist.hxx @@ -89,7 +89,7 @@ public: bool fgCurrentElev( sgdVec3 abs_view_pos, double max_alt_m, sgdVec3 scenery_center, - ssgTransform *terra_transform, + ssgBranch *branch, FGHitList *hit_list, double *terrain_elev, double *radius, diff --git a/src/Scenery/scenery.cxx b/src/Scenery/scenery.cxx index 0bbe2163e..39e21cd37 100644 --- a/src/Scenery/scenery.cxx +++ b/src/Scenery/scenery.cxx @@ -131,33 +131,19 @@ void FGScenery::unregister_placement_transform(ssgPlacementTransform *trans) { bool FGScenery::get_elevation_m(double lat, double lon, double max_alt, - double& alt, bool exact) + double& alt, const SGMaterial** material, + bool exact) { -// std::cout << __PRETTY_FUNCTION__ << " " -// << lat << " " -// << lon << " " -// << max_alt -// << std::endl; sgdVec3 pos; sgGeodToCart(lat*SG_DEGREES_TO_RADIANS, lon*SG_DEGREES_TO_RADIANS, max_alt, pos); - return get_cart_elevation_m(pos, 0, alt, exact); -} - -bool -FGScenery::get_material_m(double lat, double lon, double max_alt, - double& alt, string & material, bool exact) -{ - sgdVec3 pos; - sgGeodToCart(lat*SG_DEGREES_TO_RADIANS, lon*SG_DEGREES_TO_RADIANS, - max_alt, pos); - - return get_cart_material_m(pos, 0, alt, material, exact); + return get_cart_elevation_m(pos, 0, alt, material, exact); } bool FGScenery::get_cart_elevation_m(const sgdVec3& pos, double max_altoff, - double& alt, bool exact) + double& alt, const SGMaterial** material, + bool exact) { Point3D saved_center = center; bool replaced_center = false; @@ -188,78 +174,18 @@ FGScenery::get_cart_elevation_m(const sgdVec3& pos, double max_altoff, // scenery center has been properly defined so any hit should // be valid (and not just luck) hit = fgCurrentElev(ncpos, max_altoff+sgdLengthVec3(pos), - sc, (ssgTransform*)get_scene_graph(), + sc, get_scene_graph(), &hit_list, &alt, &hit_radius, hit_normal, this_hit); - } - if (replaced_center) - set_center( saved_center ); - - return hit; -} - -bool -FGScenery::get_cart_material_m(const sgdVec3& pos, double max_altoff, - double& alt, string& material, bool exact) -{ - Point3D saved_center = center; - bool replaced_center = false; - if (exact) { - Point3D ppos(pos[0], pos[1], pos[2]); - if (30.0*30.0 < ppos.distance3Dsquared(center)) { - set_center( ppos ); - replaced_center = true; - } - } - - material = ""; - - // overridden with actual values if a terrain intersection is - // found - int this_hit; - double hit_radius = 0.0; - sgdVec3 hit_normal = { 0.0, 0.0, 0.0 }; - - bool hit = false; - if ( fabs(pos[0]) > 1.0 || fabs(pos[1]) > 1.0 || fabs(pos[2]) > 1.0 ) { - sgdVec3 sc; - sgdSetVec3(sc, center[0], center[1], center[2]); - - sgdVec3 ncpos; - sgdCopyVec3(ncpos, pos); - - FGHitList hit_list; - - // scenery center has been properly defined so any hit should - // be valid (and not just luck) - hit = fgCurrentElev(ncpos, max_altoff+sgdLengthVec3(pos), - sc, (ssgTransform*)get_scene_graph(), - &hit_list, &alt, &hit_radius, hit_normal, - this_hit ); - - if( hit ) - { - ssgEntity *entity = hit_list.get_entity( this_hit ); - - if( entity != NULL && entity->isAKindOf(ssgTypeLeaf()) ) - { - ssgLeaf *leaf = (ssgLeaf*) hit_list.get_entity( this_hit ); - ssgState *st = leaf->getState(); - - if( st != NULL && st->isAKindOf(ssgTypeSimpleState()) ) - { - ssgSimpleState *ss = (ssgSimpleState *) st; - - if( !globals->get_matlib()->find( ss, material ) ) - { - material = "not-in-matlib"; - } - } - } - } - else - { - material = "no-hit"; + if (material) { + *material = 0; + if (hit) { + ssgEntity *entity = hit_list.get_entity( this_hit ); + if (entity && entity->isAKindOf(ssgTypeLeaf())) { + ssgLeaf* leaf = static_cast(entity); + *material = globals->get_matlib()->findMaterial(leaf); + } + } } } @@ -269,7 +195,6 @@ FGScenery::get_cart_material_m(const sgdVec3& pos, double max_altoff, return hit; } - bool FGScenery::get_cart_ground_intersection(const sgdVec3& pos, const sgdVec3& dir, diff --git a/src/Scenery/scenery.hxx b/src/Scenery/scenery.hxx index 58690188f..84e12f8c3 100644 --- a/src/Scenery/scenery.hxx +++ b/src/Scenery/scenery.hxx @@ -43,6 +43,7 @@ SG_USING_STD(list); class ssgRoot; class ssgBranch; +class SGMaterial; // Define a structure containing global scenery parameters @@ -93,9 +94,8 @@ public: /// value is undefined. /// All values are meant to be in meters or degrees. bool get_elevation_m(double lat, double lon, double max_alt, - double& alt, bool exact = false); - bool get_material_m(double lat, double lon, double max_alt, - double& alt, string & material, bool exact = false); + double& alt, const SGMaterial** material, + bool exact = false); /// Compute the elevation of the scenery beow the cartesian point pos. /// you the returned scenery altitude is not higher than the position @@ -109,9 +109,8 @@ public: /// value is undefined. /// All values are meant to be in meters. bool get_cart_elevation_m(const sgdVec3& pos, double max_altoff, - double& radius, bool exact = false); - bool get_cart_material_m(const sgdVec3& pos, double max_altoff, - double& radius, string& material, bool exact = false); + double& radius, const SGMaterial** material, + bool exact = false); /// Compute the nearest intersection point of the line starting from /// start going in direction dir with the terrain.