Clean up scenery center handling. It is set now less often.
This commit is contained in:
parent
75f0dcbb1d
commit
cdb725528d
14 changed files with 118 additions and 166 deletions
|
@ -50,7 +50,7 @@
|
|||
#include <deque> // STL double ended queue
|
||||
#include STL_FSTREAM
|
||||
|
||||
#include <simgear/math/fastmath.hxx> // float_to_int()
|
||||
#include <simgear/math/SGMath.hxx>
|
||||
#include <simgear/constants.h>
|
||||
|
||||
#include <Include/fg_typedefs.h>
|
||||
|
@ -69,6 +69,7 @@ SG_USING_STD(deque);
|
|||
SG_USING_STD(vector);
|
||||
SG_USING_NAMESPACE(std);
|
||||
|
||||
#define float_to_int(v) SGMiscf::roundToInt(v)
|
||||
|
||||
// some of Norman's crazy optimizations. :-)
|
||||
|
||||
|
|
|
@ -181,13 +181,6 @@ bool runway_instr::get_active_runway(FGRunway& runway)
|
|||
|
||||
void runway_instr::get_rwy_points(sgdVec3 *points3d)
|
||||
{
|
||||
static Point3D center = globals->get_scenery()->get_center();
|
||||
|
||||
//Get the current tile center
|
||||
Point3D currentCenter = globals->get_scenery()->get_center();
|
||||
Point3D tileCenter = currentCenter;
|
||||
if (center != currentCenter) //if changing tiles
|
||||
tileCenter = center; //use last center
|
||||
double alt = current_aircraft.fdm_state->get_Runway_altitude() * SG_FEET_TO_METER;
|
||||
double length = (runway._length / 2.0) * SG_FEET_TO_METER;
|
||||
double width = (runway._width / 2.0) * SG_FEET_TO_METER;
|
||||
|
@ -211,12 +204,13 @@ void runway_instr::get_rwy_points(sgdVec3 *points3d)
|
|||
geo_direct_wgs_84(alt, frontLat, frontLon, runway._heading + 90, width, &tempLat, &tempLon, &az);
|
||||
sgGeodToCart(tempLat * SG_DEGREES_TO_RADIANS, tempLon * SG_DEGREES_TO_RADIANS, alt, points3d[3]);
|
||||
|
||||
//Get the current tile center
|
||||
SGVec3d tileCenter = globals->get_scenery()->get_center();
|
||||
for (int i = 0; i < 6; i++) {
|
||||
points3d[i][0] -= tileCenter.x();
|
||||
points3d[i][1] -= tileCenter.y();
|
||||
points3d[i][2] -= tileCenter.z();
|
||||
}
|
||||
center = currentCenter;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -481,10 +481,10 @@ FGGroundCache::prepare_ground_cache(double ref_time, const double pt[3],
|
|||
cache_ref_time = ref_time;
|
||||
|
||||
// Decide where we put the scenery center.
|
||||
Point3D old_cntr = globals->get_scenery()->get_center();
|
||||
Point3D cntr(pt[0], pt[1], pt[2]);
|
||||
SGVec3d old_cntr = globals->get_scenery()->get_center();
|
||||
SGVec3d cntr(pt[0], pt[1], pt[2]);
|
||||
// Only move the cache center if it is unacceptable far away.
|
||||
if (40*40 < old_cntr.distance3Dsquared(cntr))
|
||||
if (40*40 < distSqr(old_cntr, cntr))
|
||||
globals->get_scenery()->set_center(cntr);
|
||||
else
|
||||
cntr = old_cntr;
|
||||
|
|
|
@ -356,17 +356,17 @@ FGInput::doMouseClick (int b, int updown, int x, int y)
|
|||
// terrain intersection point corresponding to the mouse click
|
||||
// and be happy.
|
||||
FGScenery* scenery = globals->get_scenery();
|
||||
sgdVec3 start, dir, hit;
|
||||
if (!b && updown == MOUSE_BUTTON_DOWN && FGRenderer::getPickInfo(start, dir, x, y)
|
||||
SGVec3d start, dir, hit;
|
||||
if (!b && updown == MOUSE_BUTTON_DOWN
|
||||
&& FGRenderer::getPickInfo(start, dir, x, y)
|
||||
&& scenery->get_cart_ground_intersection(start, dir, hit)) {
|
||||
|
||||
Point3D geod = sgCartToGeod(Point3D(hit[0], hit[1], hit[2]));
|
||||
|
||||
SGGeod geod = SGGeod::fromCart(hit);
|
||||
SGPropertyNode *c = fgGetNode("/sim/input/click", true);
|
||||
c->setDoubleValue("longitude-deg", geod.lon() * SGD_RADIANS_TO_DEGREES);
|
||||
c->setDoubleValue("latitude-deg", geod.lat() * SGD_RADIANS_TO_DEGREES);
|
||||
c->setDoubleValue("elevation-m", geod.elev());
|
||||
c->setDoubleValue("elevation-ft", geod.elev() * SG_METER_TO_FEET);
|
||||
c->setDoubleValue("longitude-deg", geod.getLongitudeDeg());
|
||||
c->setDoubleValue("latitude-deg", geod.getLatitudeDeg());
|
||||
c->setDoubleValue("elevation-m", geod.getElevationM());
|
||||
c->setDoubleValue("elevation-ft", geod.getElevationFt());
|
||||
|
||||
fgSetBool("/sim/signals/click", 1);
|
||||
}
|
||||
|
|
|
@ -173,14 +173,6 @@ bool HUD::Runway::get_active_runway(FGRunway& runway)
|
|||
|
||||
void HUD::Runway::get_rwy_points(sgdVec3 *_points3d)
|
||||
{
|
||||
static Point3D center = globals->get_scenery()->get_center();
|
||||
|
||||
//Get the current tile center
|
||||
Point3D currentCenter = globals->get_scenery()->get_center();
|
||||
Point3D tileCenter = currentCenter;
|
||||
if (center != currentCenter) //if changing tiles
|
||||
tileCenter = center; //use last center
|
||||
|
||||
double alt = current_aircraft.fdm_state->get_Runway_altitude() * SG_FEET_TO_METER;
|
||||
double length = (_runway._length / 2.0) * SG_FEET_TO_METER;
|
||||
double width = (_runway._width / 2.0) * SG_FEET_TO_METER;
|
||||
|
@ -204,12 +196,13 @@ void HUD::Runway::get_rwy_points(sgdVec3 *_points3d)
|
|||
geo_direct_wgs_84(alt, frontLat, frontLon, _runway._heading + 90, width, &tempLat, &tempLon, &az);
|
||||
sgGeodToCart(tempLat * SG_DEGREES_TO_RADIANS, tempLon * SG_DEGREES_TO_RADIANS, alt, _points3d[3]);
|
||||
|
||||
//Get the current tile center
|
||||
SGVec3d tileCenter = globals->get_scenery()->get_center();
|
||||
for (int i = 0; i < 6; i++) {
|
||||
_points3d[i][0] -= tileCenter.x();
|
||||
_points3d[i][1] -= tileCenter.y();
|
||||
_points3d[i][2] -= tileCenter.z();
|
||||
}
|
||||
center = currentCenter;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -206,13 +206,7 @@ FGMarkerBeacon::update(double dt)
|
|||
static bool check_beacon_range( const SGGeod& pos,
|
||||
FGNavRecord *b )
|
||||
{
|
||||
SGVec3d aircraft = SGVec3d::fromGeod(pos);
|
||||
SGVec3d station = b->get_cart();
|
||||
// cout << " aircraft = " << aircraft << " station = " << station
|
||||
// << endl;
|
||||
|
||||
SGVec3d tmp = station - aircraft;
|
||||
double d = dot(tmp, tmp);
|
||||
double d = distSqr(b->get_cart(), SGVec3d::fromGeod(pos));
|
||||
// cout << " distance = " << d << " ("
|
||||
// << FG_ILS_DEFAULT_RANGE * SG_NM_TO_METER
|
||||
// * FG_ILS_DEFAULT_RANGE * SG_NM_TO_METER
|
||||
|
|
|
@ -514,44 +514,23 @@ static void fgMainLoop( void ) {
|
|||
double visibility_meters = fgGetDouble("/environment/visibility-m");
|
||||
FGViewer *current_view = globals->get_current_view();
|
||||
|
||||
// Let the scenery center follow the current view position with
|
||||
// 30m increments.
|
||||
//
|
||||
// Having the scenery center near the view position will eliminate
|
||||
// jitter of objects which are placed very near the view position
|
||||
// and haveing it's center near that view position.
|
||||
// So the 3d insruments of the aircraft will not jitter with this.
|
||||
//
|
||||
// Following the view position exactly would introduce jitter of
|
||||
// the scenery tiles (they would be from their center up to 10000m
|
||||
// to the view and this will introduce roundoff too). By stepping
|
||||
// at 30m incements the roundoff error of the scenery tiles is
|
||||
// still present, but we will make exactly the same roundoff error
|
||||
// at each frame until the center is switched to a new
|
||||
// position. This roundoff is still visible but you will most
|
||||
// propably not notice.
|
||||
double *vp = globals->get_current_view()->get_absolute_view_pos();
|
||||
Point3D cntr(vp[0], vp[1], vp[2]);
|
||||
if (30.0*30.0 < cntr.distance3Dsquared(globals->get_scenery()->get_center())) {
|
||||
globals->get_scenery()->set_next_center( cntr );
|
||||
}
|
||||
|
||||
globals->get_tile_mgr()->prep_ssg_nodes( current_view->getSGLocation(),
|
||||
visibility_meters );
|
||||
// update tile manager for view...
|
||||
SGLocation *view_location = globals->get_current_view()->getSGLocation();
|
||||
globals->get_tile_mgr()->update( view_location, visibility_meters );
|
||||
globals->get_scenery()->set_center( cntr );
|
||||
{
|
||||
double lon = view_location->getLongitude_deg();
|
||||
double lat = view_location->getLatitude_deg();
|
||||
double alt = view_location->getAltitudeASL_ft() * SG_FEET_TO_METER;
|
||||
|
||||
// check if we can reuse the groundcache for that purpose.
|
||||
double ref_time, pt[3], r;
|
||||
bool valid = cur_fdm_state->is_valid_m(&ref_time, pt, &r);
|
||||
if (valid &&
|
||||
cntr.distance3Dsquared(Point3D(pt[0], pt[1], pt[2])) < r*r) {
|
||||
double ref_time, r;
|
||||
SGVec3d pt;
|
||||
bool valid = cur_fdm_state->is_valid_m(&ref_time, pt.sg(), &r);
|
||||
double *vp = globals->get_current_view()->get_absolute_view_pos();
|
||||
SGVec3d viewpos(vp);
|
||||
if (valid && distSqr(viewpos, pt) < r*r) {
|
||||
// Reuse the cache ...
|
||||
double lev
|
||||
= cur_fdm_state->get_groundlevel_m(lat*SGD_DEGREES_TO_RADIANS,
|
||||
|
|
|
@ -232,6 +232,27 @@ FGRenderer::update( bool refresh_camera_settings ) {
|
|||
return;
|
||||
}
|
||||
|
||||
// Let the scenery center follow the current view position with
|
||||
// 30m increments.
|
||||
//
|
||||
// Having the scenery center near the view position will eliminate
|
||||
// jitter of objects which are placed very near the view position
|
||||
// and haveing it's center near that view position.
|
||||
// So the 3d insruments of the aircraft will not jitter with this.
|
||||
//
|
||||
// Following the view position exactly would introduce jitter of
|
||||
// the scenery tiles (they would be from their center up to 10000m
|
||||
// to the view and this will introduce roundoff too). By stepping
|
||||
// at 30m incements the roundoff error of the scenery tiles is
|
||||
// still present, but we will make exactly the same roundoff error
|
||||
// at each frame until the center is switched to a new
|
||||
// position. This roundoff is still visible but you will most
|
||||
// propably not notice.
|
||||
double *vp = globals->get_current_view()->get_absolute_view_pos();
|
||||
SGVec3d cntr(vp);
|
||||
if (30.0*30.0 < distSqr(cntr, globals->get_scenery()->get_center()))
|
||||
globals->get_scenery()->set_center( cntr );
|
||||
|
||||
bool draw_otw = fgGetBool("/sim/rendering/draw-otw");
|
||||
bool skyblend = fgGetBool("/sim/rendering/skyblend");
|
||||
bool use_point_sprites = fgGetBool("/sim/rendering/point-sprites");
|
||||
|
@ -305,10 +326,6 @@ FGRenderer::update( bool refresh_camera_settings ) {
|
|||
// now work without seg faulting the system.
|
||||
|
||||
FGViewer *current__view = globals->get_current_view();
|
||||
|
||||
// calculate our current position in cartesian space
|
||||
Point3D cntr = globals->get_scenery()->get_next_center();
|
||||
globals->get_scenery()->set_center(cntr);
|
||||
// Force update of center dependent values ...
|
||||
current__view->set_dirty();
|
||||
|
||||
|
@ -934,7 +951,8 @@ void FGRenderer::setNearFar( float n, float f ) {
|
|||
fgHackFrustum();
|
||||
}
|
||||
|
||||
bool FGRenderer::getPickInfo( sgdVec3 pt, sgdVec3 dir, unsigned x, unsigned y )
|
||||
bool FGRenderer::getPickInfo( SGVec3d& pt, SGVec3d& dir,
|
||||
unsigned x, unsigned y )
|
||||
{
|
||||
// Get the matrices involved in the transform from global to screen
|
||||
// coordinates.
|
||||
|
@ -970,11 +988,11 @@ bool FGRenderer::getPickInfo( sgdVec3 pt, sgdVec3 dir, unsigned x, unsigned y )
|
|||
FGViewer* view = globals->get_current_view();
|
||||
sgVec4 fDir;
|
||||
sgSubVec3(fDir, worldPt, view->get_view_pos());
|
||||
sgdSetVec3(dir, fDir);
|
||||
sgdNormalizeVec3(dir);
|
||||
sgdSetVec3(dir.sg(), fDir);
|
||||
sgdNormalizeVec3(dir.sg());
|
||||
|
||||
// Copy the start point
|
||||
sgdCopyVec3(pt, view->get_absolute_view_pos());
|
||||
sgdCopyVec3(pt.sg(), view->get_absolute_view_pos());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -50,7 +50,7 @@ public:
|
|||
* The inputs are expected to be the x and y coordinates of the
|
||||
* screen point relative to the window.
|
||||
*/
|
||||
static bool getPickInfo( sgdVec3 p, sgdVec3 d, unsigned x, unsigned y );
|
||||
static bool getPickInfo( SGVec3d& p, SGVec3d& d, unsigned x, unsigned y );
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -576,9 +576,7 @@ FGViewer::recalc ()
|
|||
void
|
||||
FGViewer::recalcLookFrom ()
|
||||
{
|
||||
|
||||
sgVec3 right, forward;
|
||||
// sgVec3 eye_pos;
|
||||
sgVec3 position_offset; // eye position offsets (xyz)
|
||||
|
||||
// LOOKFROM mode...
|
||||
|
@ -642,7 +640,6 @@ FGViewer::recalcLookFrom ()
|
|||
void
|
||||
FGViewer::recalcLookAt ()
|
||||
{
|
||||
|
||||
sgVec3 right, forward;
|
||||
sgVec3 eye_pos, at_pos;
|
||||
sgVec3 position_offset; // eye position offsets (xyz)
|
||||
|
@ -663,7 +660,7 @@ FGViewer::recalcLookAt ()
|
|||
_target_roll_deg, _target_pitch_deg, _target_heading_deg );
|
||||
}
|
||||
// calculate the "at" target object positon relative to eye or view's tile center...
|
||||
Point3D center = globals->get_scenery()->get_next_center();
|
||||
SGVec3d center = globals->get_scenery()->get_center();
|
||||
sgdVec3 dVec3;
|
||||
sgdSetVec3(dVec3, center[0], center[1], center[2]);
|
||||
sgdSubVec3(dVec3, _target_location->get_absolute_view_pos(), dVec3 );
|
||||
|
@ -679,7 +676,7 @@ FGViewer::recalcLookAt ()
|
|||
_roll_deg, _pitch_deg, _heading_deg );
|
||||
}
|
||||
// save the eye positon...
|
||||
sgCopyVec3(eye_pos, _location->get_view_pos(center));
|
||||
sgCopyVec3(eye_pos, _location->get_view_pos(center));
|
||||
|
||||
// copy data from location class to local items...
|
||||
copyLocationData();
|
||||
|
@ -730,7 +727,7 @@ FGViewer::recalcLookAt ()
|
|||
void
|
||||
FGViewer::copyLocationData()
|
||||
{
|
||||
Point3D center = globals->get_scenery()->get_center();
|
||||
SGVec3d center = globals->get_scenery()->get_center();
|
||||
// Get our friendly vectors from the eye location...
|
||||
sgdCopyVec3(_absolute_view_pos, _location->get_absolute_view_pos());
|
||||
sgCopyVec3(_relative_view_pos, _location->get_view_pos(center));
|
||||
|
|
|
@ -41,10 +41,10 @@
|
|||
|
||||
|
||||
// Scenery Management system
|
||||
FGScenery::FGScenery() {
|
||||
FGScenery::FGScenery() :
|
||||
center(0, 0, 0)
|
||||
{
|
||||
SG_LOG( SG_TERRAIN, SG_INFO, "Initializing scenery subsystem" );
|
||||
|
||||
center = Point3D(0.0);
|
||||
}
|
||||
|
||||
|
||||
|
@ -101,22 +101,20 @@ void FGScenery::bind() {
|
|||
void FGScenery::unbind() {
|
||||
}
|
||||
|
||||
void FGScenery::set_center( const Point3D& p ) {
|
||||
void FGScenery::set_center( const SGVec3d& p ) {
|
||||
if (center == p)
|
||||
return;
|
||||
center = p;
|
||||
sgdVec3 c;
|
||||
sgdSetVec3(c, p.x(), p.y(), p.z());
|
||||
placement_list_type::iterator it = _placement_list.begin();
|
||||
while (it != _placement_list.end()) {
|
||||
(*it)->setSceneryCenter(c);
|
||||
(*it)->setSceneryCenter(center.sg());
|
||||
++it;
|
||||
}
|
||||
}
|
||||
|
||||
void FGScenery::register_placement_transform(ssgPlacementTransform *trans) {
|
||||
_placement_list.push_back(trans);
|
||||
sgdVec3 c;
|
||||
sgdSetVec3(c, center.x(), center.y(), center.z());
|
||||
trans->setSceneryCenter(c);
|
||||
trans->setSceneryCenter(center.sg());
|
||||
}
|
||||
|
||||
void FGScenery::unregister_placement_transform(ssgPlacementTransform *trans) {
|
||||
|
@ -134,23 +132,24 @@ FGScenery::get_elevation_m(double lat, double lon, double max_alt,
|
|||
double& alt, const SGMaterial** material,
|
||||
bool exact)
|
||||
{
|
||||
sgdVec3 pos;
|
||||
sgGeodToCart(lat*SG_DEGREES_TO_RADIANS, lon*SG_DEGREES_TO_RADIANS,
|
||||
max_alt, pos);
|
||||
SGGeod geod = SGGeod::fromDegM(lon, lat, max_alt);
|
||||
SGVec3d pos = SGVec3d::fromGeod(geod);
|
||||
return get_cart_elevation_m(pos, 0, alt, material, exact);
|
||||
}
|
||||
|
||||
bool
|
||||
FGScenery::get_cart_elevation_m(const sgdVec3& pos, double max_altoff,
|
||||
FGScenery::get_cart_elevation_m(const SGVec3d& pos, double max_altoff,
|
||||
double& alt, const SGMaterial** material,
|
||||
bool exact)
|
||||
{
|
||||
Point3D saved_center = center;
|
||||
if ( norm1(pos) < 1 )
|
||||
return false;
|
||||
|
||||
SGVec3d 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 );
|
||||
if (30*30 < distSqr(pos, center)) {
|
||||
set_center( pos );
|
||||
replaced_center = true;
|
||||
}
|
||||
}
|
||||
|
@ -159,32 +158,25 @@ FGScenery::get_cart_elevation_m(const sgdVec3& pos, double max_altoff,
|
|||
// found
|
||||
int this_hit;
|
||||
double hit_radius = 0.0;
|
||||
sgdVec3 hit_normal = { 0.0, 0.0, 0.0 };
|
||||
SGVec3d hit_normal(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, get_scene_graph(),
|
||||
&hit_list, &alt, &hit_radius, hit_normal, this_hit);
|
||||
SGVec3d sc = center;
|
||||
SGVec3d ncpos = pos;
|
||||
|
||||
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);
|
||||
}
|
||||
FGHitList hit_list;
|
||||
// scenery center has been properly defined so any hit should
|
||||
// be valid (and not just luck)
|
||||
bool hit = fgCurrentElev(ncpos.sg(), max_altoff+length(pos), sc.sg(),
|
||||
get_scene_graph(), &hit_list, &alt,
|
||||
&hit_radius, hit_normal.sg(), this_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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -196,23 +188,21 @@ FGScenery::get_cart_elevation_m(const sgdVec3& pos, double max_altoff,
|
|||
}
|
||||
|
||||
bool
|
||||
FGScenery::get_cart_ground_intersection(const sgdVec3& pos,
|
||||
const sgdVec3& dir,
|
||||
sgdVec3& nearestHit, bool exact)
|
||||
FGScenery::get_cart_ground_intersection(const SGVec3d& pos, const SGVec3d& dir,
|
||||
SGVec3d& nearestHit, bool exact)
|
||||
{
|
||||
// We assume that starting positions in the center of the earth are invalid
|
||||
if ( fabs(pos[0]) < 1.0 && fabs(pos[1]) < 1.0 && fabs(pos[2]) < 1.0 )
|
||||
if ( norm1(pos) < 1 )
|
||||
return false;
|
||||
|
||||
// Well that 'exactness' is somehow problematic, but makes at least sure
|
||||
// that we don't compute that with a cenery center at the other side of
|
||||
// the world ...
|
||||
Point3D saved_center = center;
|
||||
SGVec3d 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 );
|
||||
if (30*30 < distSqr(pos, center)) {
|
||||
set_center( pos );
|
||||
replaced_center = true;
|
||||
}
|
||||
}
|
||||
|
@ -222,39 +212,32 @@ FGScenery::get_cart_ground_intersection(const sgdVec3& pos,
|
|||
|
||||
// Make really sure the direction is normalized, is really cheap compared to
|
||||
// computation of ground intersection.
|
||||
sgdVec3 normalizedDir;
|
||||
sgdCopyVec3(normalizedDir, dir);
|
||||
sgdNormaliseVec3(normalizedDir);
|
||||
|
||||
sgdVec3 sceneryCenter;
|
||||
sgdSetVec3(sceneryCenter, center[0], center[1], center[2]);
|
||||
sgdVec3 relativePos;
|
||||
sgdSubVec3(relativePos, pos, sceneryCenter);
|
||||
SGVec3d normalizedDir = normalize(dir);
|
||||
SGVec3d relativePos = pos - center;
|
||||
|
||||
// At the moment only intersection with the terrain?
|
||||
FGHitList hit_list;
|
||||
hit_list.Intersect(globals->get_scenery()->get_terrain_branch(),
|
||||
relativePos, normalizedDir);
|
||||
relativePos.sg(), normalizedDir.sg());
|
||||
|
||||
double dist = DBL_MAX;
|
||||
int hitcount = hit_list.num_hits();
|
||||
for (int i = 0; i < hitcount; ++i) {
|
||||
// Check for the nearest hit
|
||||
sgdVec3 diff;
|
||||
sgdSubVec3(diff, hit_list.get_point(i), relativePos);
|
||||
SGVec3d diff = SGVec3d(hit_list.get_point(i)) - relativePos;
|
||||
|
||||
// We only want hits in front of us ...
|
||||
if (sgdScalarProductVec3(normalizedDir, diff) < 0)
|
||||
if (dot(normalizedDir, diff) < 0)
|
||||
continue;
|
||||
|
||||
// find the nearest hit
|
||||
double nDist = sgdScalarProductVec3(diff, diff);
|
||||
double nDist = dot(diff, diff);
|
||||
if (dist < nDist)
|
||||
continue;
|
||||
|
||||
// Store the hit point
|
||||
dist = nDist;
|
||||
sgdAddVec3(nearestHit, hit_list.get_point(i), sceneryCenter);
|
||||
nearestHit = SGVec3d(hit_list.get_point(i)) + center;
|
||||
result = true;
|
||||
}
|
||||
|
||||
|
|
|
@ -49,10 +49,7 @@ class SGMaterial;
|
|||
// Define a structure containing global scenery parameters
|
||||
class FGScenery : public SGSubsystem {
|
||||
// center of current scenery chunk
|
||||
Point3D center;
|
||||
|
||||
// next center of current scenery chunk
|
||||
Point3D next_center;
|
||||
SGVec3d center;
|
||||
|
||||
// FIXME this should be a views property
|
||||
// angle of sun relative to current local horizontal
|
||||
|
@ -108,7 +105,7 @@ public:
|
|||
/// lat/lon pair. If there is no scenery for that point, the altitude
|
||||
/// value is undefined.
|
||||
/// All values are meant to be in meters.
|
||||
bool get_cart_elevation_m(const sgdVec3& pos, double max_altoff,
|
||||
bool get_cart_elevation_m(const SGVec3d& pos, double max_altoff,
|
||||
double& radius, const SGMaterial** material,
|
||||
bool exact = false);
|
||||
|
||||
|
@ -117,14 +114,11 @@ public:
|
|||
/// The input and output values should be in cartesian coordinates in the
|
||||
/// usual earth centered wgs84 coordiante system. Units are meters.
|
||||
/// On success, true is returned.
|
||||
bool get_cart_ground_intersection(const sgdVec3& start, const sgdVec3& dir,
|
||||
sgdVec3& nearestHit, bool exact = false);
|
||||
bool get_cart_ground_intersection(const SGVec3d& start, const SGVec3d& dir,
|
||||
SGVec3d& nearestHit, bool exact = false);
|
||||
|
||||
inline const Point3D& get_center() const { return center; }
|
||||
void set_center( const Point3D& p );
|
||||
|
||||
inline const Point3D& get_next_center() const { return next_center; }
|
||||
inline void set_next_center( const Point3D& p ) { next_center = p; }
|
||||
const SGVec3d& get_center() const { return center; }
|
||||
void set_center( const SGVec3d& p );
|
||||
|
||||
inline ssgRoot *get_scene_graph () const { return scene_graph; }
|
||||
inline void set_scene_graph (ssgRoot * s) { scene_graph = s; }
|
||||
|
|
|
@ -70,7 +70,7 @@ private:
|
|||
double _moon_lon, _moon_gc_lat;
|
||||
|
||||
// in cartesian coordiantes
|
||||
Point3D _sunpos, _moonpos;
|
||||
SGVec3d _sunpos, _moonpos;
|
||||
|
||||
// (in view coordinates)
|
||||
sgVec4 _sun_vec, _moon_vec;
|
||||
|
@ -149,8 +149,8 @@ public:
|
|||
inline double get_sun_gc_lat () const { return _sun_gc_lat; }
|
||||
inline void set_sun_gc_lat (double l) { _sun_gc_lat = l; }
|
||||
|
||||
inline const Point3D& get_sunpos () const { return _sunpos; }
|
||||
inline void set_sunpos (const Point3D& p) { _sunpos = p; }
|
||||
inline const SGVec3d& get_sunpos () const { return _sunpos; }
|
||||
inline void set_sunpos (const SGVec3d& p) { _sunpos = p; }
|
||||
|
||||
inline float *sun_vec () const { return (float *)_sun_vec; }
|
||||
inline float *sun_vec_inv () const { return (float *)_sun_vec_inv; }
|
||||
|
@ -170,8 +170,8 @@ public:
|
|||
inline double get_moon_gc_lat () const { return _moon_gc_lat; }
|
||||
inline void set_moon_gc_lat (double l) { _moon_gc_lat = l; }
|
||||
|
||||
inline const Point3D& get_moonpos () const { return _moonpos; }
|
||||
inline void set_moonpos (const Point3D& p) { _moonpos = p; }
|
||||
inline const SGVec3d& get_moonpos () const { return _moonpos; }
|
||||
inline void set_moonpos (const SGVec3d& p) { _moonpos = p; }
|
||||
|
||||
inline float *moon_vec () const { return (float *)_moon_vec; }
|
||||
inline float *moon_vec_inv () const { return (float *)_moon_vec_inv; }
|
||||
|
|
|
@ -69,7 +69,6 @@ void fgUpdateLocalTime() {
|
|||
// update the cur_time_params structure with the current sun position
|
||||
void fgUpdateSunPos( void ) {
|
||||
sgVec3 nup, nsun;
|
||||
Point3D rel_sunpos;
|
||||
double dot, east_dot;
|
||||
double sun_gd_lat, sl_radius;
|
||||
|
||||
|
@ -94,8 +93,9 @@ void fgUpdateSunPos( void ) {
|
|||
sgGeodToGeoc(sun_gd_lat, 0.0, &sl_radius, &sun_l);
|
||||
l->set_sun_gc_lat(sun_l);
|
||||
|
||||
Point3D p = Point3D( l->get_sun_lon(), l->get_sun_gc_lat(), sl_radius );
|
||||
l->set_sunpos( sgPolarToCart3d(p) );
|
||||
SGGeoc geocSun = SGGeoc::fromRadM( l->get_sun_lon(), l->get_sun_gc_lat(),
|
||||
sl_radius );
|
||||
l->set_sunpos( SGVec3d::fromGeoc(geocSun) );
|
||||
|
||||
SG_LOG( SG_EVENT, SG_DEBUG, " t->cur_time = " << t->get_cur_time() );
|
||||
SG_LOG( SG_EVENT, SG_DEBUG,
|
||||
|
@ -130,10 +130,9 @@ void fgUpdateSunPos( void ) {
|
|||
<< l->get_sun_angle() );
|
||||
|
||||
// calculate vector to sun's position on the earth's surface
|
||||
Point3D vp( v->get_view_pos()[0],
|
||||
v->get_view_pos()[1],
|
||||
v->get_view_pos()[2] );
|
||||
rel_sunpos = l->get_sunpos() - (vp + globals->get_scenery()->get_center());
|
||||
SGVec3d rel_sunpos = globals->get_scenery()->get_center();
|
||||
SGVec3f vp( v->get_view_pos() );
|
||||
rel_sunpos += l->get_sunpos() - toVec3d(vp);
|
||||
sgSetVec3( to_sun, rel_sunpos.x(), rel_sunpos.y(), rel_sunpos.z() );
|
||||
// printf( "Vector to sun = %.2f %.2f %.2f\n",
|
||||
// v->to_sun[0], v->to_sun[1], v->to_sun[2]);
|
||||
|
|
Loading…
Add table
Reference in a new issue