1
0
Fork 0

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.
This commit is contained in:
frohlich 2006-06-11 13:34:18 +00:00
parent e48967cb1d
commit 14fe03ba6f
11 changed files with 96 additions and 162 deletions

View file

@ -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;

View file

@ -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);
}

View file

@ -32,6 +32,7 @@
#include <simgear/debug/logstream.hxx>
#include <simgear/math/sg_geodesy.hxx>
#include <simgear/scene/model/placement.hxx>
#include <simgear/scene/material/mat.hxx>
#include <simgear/timing/timestamp.hxx>
#include <Scenery/scenery.hxx>
@ -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();
}

View file

@ -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);

View file

@ -32,6 +32,8 @@
#include <simgear/constants.h>
#include <simgear/debug/logstream.hxx>
#include <simgear/math/sg_geodesy.hxx>
#include <simgear/scene/material/mat.hxx>
#include <simgear/scene/material/matlib.hxx>
#include <Main/globals.hxx>
#include <Scenery/scenery.hxx>
@ -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;
}

View file

@ -28,6 +28,8 @@
#include <simgear/compiler.h>
#include <simgear/constants.h>
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.

View file

@ -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 );

View file

@ -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;

View file

@ -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,

View file

@ -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)
{
// 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)
double& alt, const SGMaterial** 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<ssgLeaf*>(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,

View file

@ -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.