94
96
void FGScenery::bind() {
95
fgTie("/environment/ground-elevation-m", this,
96
&FGScenery::get_cur_elev, &FGScenery::set_cur_elev);
100
100
void FGScenery::unbind() {
101
fgUntie("/environment/ground-elevation-m");
103
void FGScenery::set_center( const Point3D& p ) {
106
sgdSetVec3(c, p.x(), p.y(), p.z());
107
placement_list_type::iterator it = _placement_list.begin();
108
while (it != _placement_list.end()) {
109
(*it)->setSceneryCenter(c);
114
void FGScenery::register_placement_transform(ssgPlacementTransform *trans) {
116
_placement_list.push_back(trans);
118
sgdSetVec3(c, center.x(), center.y(), center.z());
119
trans->setSceneryCenter(c);
122
void FGScenery::unregister_placement_transform(ssgPlacementTransform *trans) {
123
placement_list_type::iterator it = _placement_list.begin();
124
while (it != _placement_list.end()) {
125
if ((*it) == trans) {
126
it = _placement_list.erase(it);
127
ssgDeRefDelete(trans);
134
FGScenery::get_elevation_m(double lat, double lon, double max_alt,
135
double& alt, bool exact)
137
// std::cout << __PRETTY_FUNCTION__ << " "
143
sgGeodToCart(lat*SG_DEGREES_TO_RADIANS, lon*SG_DEGREES_TO_RADIANS,
145
return get_cart_elevation_m(pos, 0, alt, exact);
149
FGScenery::get_cart_elevation_m(const sgdVec3& pos, double max_altoff,
150
double& alt, bool exact)
152
Point3D saved_center = center;
153
bool replaced_center = false;
155
Point3D ppos(pos[0], pos[1], pos[2]);
156
if (30.0*30.0 < ppos.distance3Dsquared(center)) {
158
replaced_center = false;
162
// overridden with actual values if a terrain intersection is
164
double hit_radius = 0.0;
165
sgdVec3 hit_normal = { 0.0, 0.0, 0.0 };
168
if ( fabs(pos[0]) > 1.0 || fabs(pos[1]) > 1.0 || fabs(pos[2]) > 1.0 ) {
170
sgdSetVec3(sc, center[0], center[1], center[2]);
173
sgdCopyVec3(ncpos, pos);
177
// scenery center has been properly defined so any hit should
178
// be valid (and not just luck)
179
hit = fgCurrentElev(ncpos, max_altoff+sgdLengthVec3(pos),
180
sc, (ssgTransform*)get_scene_graph(),
181
&hit_list, &alt, &hit_radius, hit_normal);
185
set_center( saved_center );
192
FGScenery::get_cart_ground_intersection(const sgdVec3& pos,
194
sgdVec3& nearestHit, bool exact)
196
// We assume that starting positions in the center of the earth are invalid
197
if ( fabs(pos[0]) < 1.0 && fabs(pos[1]) < 1.0 && fabs(pos[2]) < 1.0 )
200
// Well that 'exactness' is somehow problematic, but makes at least sure
201
// that we don't compute that with a cenery center at the other side of
203
Point3D saved_center = center;
204
bool replaced_center = false;
206
Point3D ppos(pos[0], pos[1], pos[2]);
207
if (30.0*30.0 < ppos.distance3Dsquared(center)) {
209
replaced_center = true;
213
// Not yet found any hit ...
216
// Make really sure the direction is normalized, is really cheap compared to
217
// computation of ground intersection.
218
sgdVec3 normalizedDir;
219
sgdCopyVec3(normalizedDir, dir);
220
sgdNormaliseVec3(normalizedDir);
222
sgdVec3 sceneryCenter;
223
sgdSetVec3(sceneryCenter, center[0], center[1], center[2]);
225
sgdSubVec3(relativePos, pos, sceneryCenter);
227
// At the moment only intersection with the terrain?
229
hit_list.Intersect(globals->get_scenery()->get_terrain_branch(),
230
relativePos, normalizedDir);
232
double dist = DBL_MAX;
233
int hitcount = hit_list.num_hits();
234
for (int i = 0; i < hitcount; ++i) {
235
// Check for the nearest hit
237
sgdSubVec3(diff, hit_list.get_point(i), relativePos);
239
// We only want hits in front of us ...
240
if (sgdScalarProductVec3(normalizedDir, diff) < 0)
243
// find the nearest hit
244
double nDist = sgdScalarProductVec3(diff, diff);
248
// Store the hit point
250
sgdAddVec3(nearestHit, hit_list.get_point(i), sceneryCenter);
255
set_center( saved_center );