FGAIBase::~FGAIBase() {
// Unregister that one at the scenery manager
if (globals->get_scenery()) {
- globals->get_scenery()->unregister_placement_transform(aip.getTransform());
globals->get_scenery()->get_scene_graph()->removeChild(aip.getSceneGraph());
}
invisible = false;
globals->get_scenery()->get_scene_graph()->addChild(aip.getSceneGraph());
- // Register that one at the scenery manager
- globals->get_scenery()->register_placement_transform(aip.getTransform());
fgSetString("/ai/models/model-added", props->getPath());
} else {
// For the flols reuse some computations done above ...
// The position of the eyepoint - at least near that ...
- SGVec3d eyePos(globals->get_current_view()->get_absolute_view_pos());
+ SGVec3d eyePos(globals->get_current_view()->get_view_pos());
// Add the position offset of the AIModel to gain the earth
// centered position
SGVec3d eyeWrtCarrier = eyePos - cartPos;
//cout << "FGAIEntity dtor called..." << endl;
//cout << "Removing model from scene graph..." << endl;
globals->get_scenery()->get_scene_graph()->removeChild(_aip.getSceneGraph());
- // Unregister that one at the scenery manager
- globals->get_scenery()->unregister_placement_transform(_aip.getTransform());
//cout << "Done!" << endl;
}
_aip.init(_model.get());
_aip.setVisible(false);
globals->get_scenery()->get_scene_graph()->addChild(_aip.getSceneGraph());
- // Register that one at the scenery manager
- globals->get_scenery()->register_placement_transform(_aip.getTransform());
}
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();
- }
}
mGroundProperty.pivot = SGVec3d(0, 0, 0);
}
- void setSceneryCenter(const SGVec3d& cntr)
- {
- mLocalToGlobal.makeTranslate(cntr.osg());
- mGlobalToLocal.makeTranslate(-cntr.osg());
- }
-
void updateCullMode(osg::StateSet* stateSet)
{
if (!stateSet)
// Walk the scene graph and extract solid ground triangles and carrier data.
GroundCacheFillVisitor gcfv(this, down, pt, cacheRadius, wireCacheRadius);
- gcfv.setSceneryCenter(globals->get_scenery()->get_center());
globals->get_scenery()->get_scene_graph()->accept(gcfv);
// some stats
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();
- }
}
//
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();
- SGVec3d cntr(vp);
- if (30.0*30.0 < distSqr(cntr, globals->get_scenery()->get_center()))
- globals->get_scenery()->set_center( cntr );
globals->get_tile_mgr()->prep_ssg_nodes( current_view->getSGLocation(),
visibility_meters );
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);
+ SGVec3d viewpos(globals->get_current_view()->get_view_pos());
if (valid && distSqr(viewpos, pt) < r*r) {
// Reuse the cache ...
double lev
if ( idle_state == 0 ) {
idle_state++;
-#ifdef GL_EXT_texture_lod_bias
- // negative values sharpen, positive values blur mipmapped textures
- glTexEnvf( GL_TEXTURE_FILTER_CONTROL_EXT, GL_TEXTURE_LOD_BIAS_EXT, -0.5 ) ;
-#endif
// This seems to be the absolute earliest in the init sequence
// that these calls will return valid info. Too bad it's after
// we've already created and sized our window. :-(
resize( fgGetInt("/sim/startup/xsize"),
fgGetInt("/sim/startup/ysize") );
- SGVec3d center = globals->get_scenery()->get_center();
SGVec3d position = current__view->getViewPosition();
SGQuatd attitude = current__view->getViewOrientation();
- SGVec3d osgPosition = attitude.transform(center - position);
+ SGVec3d osgPosition = attitude.transform(-position);
mCameraView->setPosition(osgPosition.osg());
mCameraView->setAttitude(inverse(attitude).osg());
}
static SGSkyState sstate;
- sstate.view_pos = current__view->get_view_pos();
- sstate.zero_elev = current__view->get_zero_elev();
+ sstate.view_pos = toVec3f(current__view->get_view_pos());
+ sstate.zero_elev = toVec3f(current__view->get_zero_elev());
sstate.view_up = current__view->get_world_up();
sstate.lon = current__view->getLongitude_deg()
* SGD_DEGREES_TO_RADIANS;
mFrameStamp->setCalendarTime(*globals->get_time_params()->getGmt());
mUpdateVisitor->setViewData(current__view->getViewPosition(),
current__view->getViewOrientation());
- mUpdateVisitor->setSceneryCenter(globals->get_scenery()->get_center());
+ mUpdateVisitor->setSceneryCenter(SGVec3d(0, 0, 0));
SGVec3f direction(l->sun_vec()[0], l->sun_vec()[1], l->sun_vec()[2]);
mUpdateVisitor->setLight(direction, l->scene_ambient(),
l->scene_diffuse(), l->scene_specular());
if (!viewport)
return false;
- // good old scenery center
- SGVec3d center = globals->get_scenery()->get_center();
-
// don't know why, but the update has partly happened somehow,
// so update the scenery part of the viewer
FGViewer *current_view = globals->get_current_view();
current_view->set_dirty();
SGVec3d position = current_view->getViewPosition();
SGQuatd attitude = current_view->getViewOrientation();
- SGVec3d osgPosition = attitude.transform(center - position);
+ SGVec3d osgPosition = attitude.transform(-position);
mCameraView->setPosition(osgPosition.osg());
mCameraView->setAttitude(inverse(attitude).osg());
sceneryPick.info.wgs84 = SGVec3d(localPt*(*hi->getMatrix()));
else
sceneryPick.info.wgs84 = SGVec3d(localPt);
- sceneryPick.info.wgs84 += globals->get_scenery()->get_center();
sceneryPick.callback = pickCallback;
pickList.push_back(sceneryPick);
}
_heading_offset_deg = heading_offset_deg;
}
-double *
-FGViewer::get_absolute_view_pos ()
-{
- if (_dirty)
- recalc();
- return _absolute_view_pos.data();
-}
-
// recalc() is done every time one of the setters is called (making the
// cached data "dirty") on the next "get". It calculates all the outputs
// for viewer.
recalcLookAt();
}
- SGVec3d center = globals->get_scenery()->get_center();
- _view_pos = toVec3f(_absolute_view_pos - center);
-
SGGeod geodEyePoint = SGGeod::fromCart(_absolute_view_pos);
geodEyePoint.setElevationM(0);
- _zero_elev = toVec3f(SGVec3d::fromGeod(geodEyePoint) - center);
+ _zero_elev = SGVec3d::fromGeod(geodEyePoint);
SGQuatd hlOr = SGQuatd::fromLonLat(geodEyePoint);
_surface_south = toVec3f(hlOr.backTransform(-SGVec3d::e1()));
// Vectors and positions...
- // Get zero view_pos
- const SGVec3f& get_view_pos() {if ( _dirty ) { recalc(); } return _view_pos; }
- // Get the absolute view position in fgfs coordinates.
- virtual double * get_absolute_view_pos ();
// Get zero elev
- const SGVec3f& get_zero_elev() {if ( _dirty ) { recalc(); } return _zero_elev; }
+ const SGVec3d& get_zero_elev() {if ( _dirty ) { recalc(); } return _zero_elev; }
// Get world up vector
const SGVec3f& get_world_up() {if ( _dirty ) { recalc(); } return _world_up; }
// Get surface east vector
// Get surface south vector
const SGVec3f& get_surface_south() {if ( _dirty ) { recalc(); } return _surface_south; }
+ const SGVec3d& get_view_pos() { if ( _dirty ) { recalc(); } return _absolute_view_pos; }
const SGVec3d& getViewPosition() { if ( _dirty ) { recalc(); } return _absolute_view_pos; }
const SGQuatd& getViewOrientation() { if ( _dirty ) { recalc(); } return mViewOrientation; }
SGQuatd mViewOrientation;
SGVec3d _absolute_view_pos;
- SGVec3f _relative_view_pos;
double _lon_deg;
double _lat_deg;
// Ratio of window width and height; height = width *
// aspect_ratio. This value is automatically calculated based on
// window dimentions.
- double _aspect_ratio;
+ double _aspect_ratio;
// default = 1.0, this value is user configurable and is
// multiplied into the aspect_ratio to get the actual vertical fov
double _aspect_ratio_multiplier;
- // view position in opengl world coordinates (this is the
- // abs_view_pos translated to scenery.center)
- SGVec3f _view_pos;
-
// cartesion coordinates of current lon/lat if at sea level
- // translated to scenery.center
- SGVec3f _zero_elev;
+ SGVec3d _zero_elev;
// surface vector heading south
SGVec3f _surface_south;
FGAircraftModel::~FGAircraftModel ()
{
- // Unregister that one at the scenery manager
- if (_aircraft)
- globals->get_scenery()->unregister_placement_transform(_aircraft->getTransform());
-
delete _aircraft;
// SSG will delete it
globals->get_scenery()->get_aircraft_branch()->removeChild(_selector.get());
// Do not do altitude computations with that model
_selector->setNodeMask(~SG_NODEMASK_TERRAIN_BIT);
globals->get_scenery()->get_aircraft_branch()->addChild(_selector.get());
-
- // Register that one at the scenery manager
- globals->get_scenery()->register_placement_transform(_aircraft->getTransform());
}
void
// Add this model to the global scene graph
globals->get_scenery()->get_scene_graph()->addChild(model->getSceneGraph());
- // Register that one at the scenery manager
- globals->get_scenery()->register_placement_transform(model->getTransform());
-
// Save this instance for updating
add_instance(instance);
FGModelMgr::Instance::~Instance ()
{
- // Unregister that one at the scenery manager
- globals->get_scenery()->unregister_placement_transform(model->getTransform());
-
delete model;
}
};
// Scenery Management system
-FGScenery::FGScenery() :
- center(0, 0, 0)
+FGScenery::FGScenery()
{
SG_LOG( SG_TERRAIN, SG_INFO, "Initializing scenery subsystem" );
}
void FGScenery::unbind() {
}
-void FGScenery::set_center( const SGVec3d& p ) {
- if (center == p)
- return;
- center = p;
- placement_list_type::iterator it = _placement_list.begin();
- while (it != _placement_list.end()) {
- (*it)->setSceneryCenter(center);
- ++it;
- }
-}
-
-void FGScenery::register_placement_transform(SGPlacementTransform *trans) {
- _placement_list.push_back(trans);
- trans->setSceneryCenter(center);
-}
-
-void FGScenery::unregister_placement_transform(SGPlacementTransform *trans) {
- placement_list_type::iterator it = _placement_list.begin();
- while (it != _placement_list.end()) {
- if ((*it) == trans) {
- it = _placement_list.erase(it);
- } else
- ++it;
- }
-}
-
bool
FGScenery::get_elevation_m(double lat, double lon, double max_alt,
double& alt, const SGMaterial** material,
if ( norm1(pos) < 1 )
return false;
- SGVec3d saved_center = center;
- bool replaced_center = false;
- if (exact) {
- if (30*30 < distSqr(pos, center)) {
- set_center( pos );
- replaced_center = true;
- }
- }
-
-
- SGVec3d start = pos + max_altoff*normalize(pos) - center;
- SGVec3d end = - center;
+ SGVec3d start = pos + max_altoff*normalize(pos);
+ SGVec3d end(0, 0, 0);
osgUtil::IntersectVisitor intersectVisitor;
intersectVisitor.setTraversalMask(SG_NODEMASK_TERRAIN_BIT);
= intersectVisitor.getHitList(lineSegment.get())[i];
SGVec3d point;
point.osg() = hit.getWorldIntersectPoint();
- point += center;
SGGeod geod = SGGeod::fromCart(point);
double elevation = geod.getElevationM();
if (alt < elevation) {
}
}
- if (replaced_center)
- set_center( saved_center );
-
return hits;
}
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 ...
- SGVec3d saved_center = center;
- bool replaced_center = false;
- if (exact) {
- if (30*30 < distSqr(pos, center)) {
- set_center( pos );
- replaced_center = true;
- }
- }
-
// Make really sure the direction is normalized, is really cheap compared to
// computation of ground intersection.
- SGVec3d start = pos - center;
+ SGVec3d start = pos;
SGVec3d end = start + 1e5*normalize(dir); // FIXME visibility ???
osgUtil::IntersectVisitor intersectVisitor;
double newdist = length(start - point);
if (newdist < dist) {
dist = newdist;
- nearestHit = point + center;
+ nearestHit = point;
}
}
}
- if (replaced_center)
- set_center( saved_center );
-
return hits;
}
// Define a structure containing global scenery parameters
class FGScenery : public SGSubsystem {
- // center of current scenery chunk
- SGVec3d center;
-
// FIXME this should be a views property
// angle of sun relative to current local horizontal
double sun_angle;
osg::ref_ptr<osg::Group> models_branch;
osg::ref_ptr<osg::Group> aircraft_branch;
- // list of all placement transform, used to move the scenery center on the fly.
- typedef list<osg::ref_ptr<SGPlacementTransform> > placement_list_type;
- placement_list_type _placement_list;
-
public:
FGScenery();
bool get_cart_ground_intersection(const SGVec3d& start, const SGVec3d& dir,
SGVec3d& nearestHit, bool exact = false);
- const SGVec3d& get_center() const { return center; }
- void set_center( const SGVec3d& p );
-
osg::Group *get_scene_graph () const { return scene_graph.get(); }
inline void set_scene_graph (osg::Group * s) { scene_graph = s; }
inline void set_aircraft_branch (osg::Group *t) {
aircraft_branch = t;
}
-
- void register_placement_transform(SGPlacementTransform *trans);
- void unregister_placement_transform(SGPlacementTransform *trans);
};
// bump up the ref count so we can remove this later without
// having ssg try to free the memory.
terrain_branch->addChild( terra_transform.get() );
- globals->get_scenery()->register_placement_transform(terra_transform.get());
SG_LOG( SG_TERRAIN, SG_DEBUG,
"connected a tile into scene graph. terra_transform = "
// bump up the ref count so we can remove this later without
// having ssg try to free the memory.
gnd_lights_branch->addChild( gnd_lights_transform.get() );
- globals->get_scenery()->register_placement_transform(gnd_lights_transform.get());
}
if ( vasi_lights_transform.get() != NULL ) {
// bump up the ref count so we can remove this later without
// having ssg try to free the memory.
vasi_lights_selector->addChild( vasi_lights_transform.get() );
- globals->get_scenery()->register_placement_transform(vasi_lights_transform.get());
vasi_lights_branch->addChild( vasi_lights_selector.get() );
}
// bump up the ref count so we can remove this later without
// having ssg try to free the memory.
rwy_lights_selector->addChild( rwy_lights_transform.get() );
- globals->get_scenery()->register_placement_transform(rwy_lights_transform.get());
rwy_lights_branch->addChild( rwy_lights_selector.get() );
}
// bump up the ref count so we can remove this later without
// having ssg try to free the memory.
taxi_lights_selector->addChild( taxi_lights_transform.get() );
- globals->get_scenery()->register_placement_transform(taxi_lights_transform.get());
taxi_lights_branch->addChild( taxi_lights_selector.get() );
}
SG_LOG( SG_TERRAIN, SG_DEBUG, "removing a fully loaded tile! terra_transform = " << terra_transform.get() );
}
- // Unregister that one at the scenery manager
- globals->get_scenery()->unregister_placement_transform(terra_transform.get());
-
// find the terrain branch parent
int pcount = terra_transform->getNumParents();
if ( pcount > 0 ) {
// find the ground lighting branch
if ( gnd_lights_transform.get() ) {
- // Unregister that one at the scenery manager
- globals->get_scenery()->unregister_placement_transform(gnd_lights_transform.get());
pcount = gnd_lights_transform->getNumParents();
if ( pcount > 0 ) {
// find the first parent (should only be one)
// find the vasi lighting branch
if ( vasi_lights_transform.get() ) {
- // Unregister that one at the scenery manager
- globals->get_scenery()->unregister_placement_transform(vasi_lights_transform.get());
pcount = vasi_lights_transform->getNumParents();
if ( pcount > 0 ) {
// find the first parent (should only be one)
// find the runway lighting branch
if ( rwy_lights_transform.get() ) {
- // Unregister that one at the scenery manager
- globals->get_scenery()->unregister_placement_transform(rwy_lights_transform.get());
pcount = rwy_lights_transform->getNumParents();
if ( pcount > 0 ) {
// find the first parent (should only be one)
// find the taxi lighting branch
if ( taxi_lights_transform.get() ) {
- // Unregister that one at the scenery manager
- globals->get_scenery()->unregister_placement_transform(taxi_lights_transform.get());
pcount = taxi_lights_transform->getNumParents();
if ( pcount > 0 ) {
// find the first parent (should only be one)
<< l->get_sun_angle() );
// calculate vector to sun's position on the earth's surface
- SGVec3d rel_sunpos = globals->get_scenery()->get_center();
- rel_sunpos += l->get_sunpos() - toVec3d(v->get_view_pos());
+ SGVec3d rel_sunpos = l->get_sunpos() - v->get_view_pos();
// vector in cartesian coordinates from current position to the
// postion on the earth's surface the sun is directly over
SGVec3f to_sun = toVec3f(rel_sunpos);
// local plane representing "horizontal".
SGVec3f world_up = v->get_world_up();
- SGVec3f view_pos = v->get_view_pos();
+ SGVec3f view_pos = toVec3f(v->get_view_pos());
// surface direction to go to head towards sun
SGVec3f surface_to_sun;
sgmap_vec_onto_cur_surface_plane( world_up.data(), view_pos.data(),