bool CubeFaceLocator::convertLocalToModel( const osg::Vec3d& local, osg::Vec3d& world ) const { #if ((OPENSCENEGRAPH_MAJOR_VERSION <= 2) && (OPENSCENEGRAPH_MINOR_VERSION < 8)) // OSG 2.7 bug workaround: bug fix in Locator submitted by GW const_cast<CubeFaceLocator*>(this)->_inverse.invert( _transform ); #endif if ( _coordinateSystemType == GEOCENTRIC ) { //Convert the NDC coordinate into face space osg::Vec3d faceCoord = local * _transform; double lat_deg, lon_deg; CubeUtils::faceCoordsToLatLon( faceCoord.x(), faceCoord.y(), _face, lat_deg, lon_deg ); //OE_NOTICE << "LatLon=" << latLon << std::endl; // convert to geocentric: _ellipsoidModel->convertLatLongHeightToXYZ( osg::DegreesToRadians( lat_deg ), osg::DegreesToRadians( lon_deg ), local.z(), world.x(), world.y(), world.z() ); return true; } return true; }
HUDHoverScaler::HUDHoverScaler(osgviz::Object* obj, const osg::Vec3d &size, const osg::Vec3d &scale, Type type, osg::Vec3d anchor_offset, HUD* hud):obj(obj),anchor_offset(anchor_offset),scale(scale),size(size),type(type),hud(hud){ scaled = false; initial_scale = obj->getScale(); if (scale.x() == 0 || scale.y() == 0 || scale.z() == 0){ printf("%s scale cannot be 0\n",__PRETTY_FUNCTION__); } }
bool MapInfo::geocentricPointToMapPoint( const osg::Vec3d& input, osg::Vec3d& output ) const { const SpatialReference* mapSRS = _profile->getSRS(); if ( !mapSRS->isGeographic() ) return false; mapSRS->getEllipsoid()->convertXYZToLatLongHeight( input.x(), input.y(), input.z(), output.y(), output.x(), output.z() ); output.y() = osg::RadiansToDegrees(output.y()); output.x() = osg::RadiansToDegrees(output.x()); return true; }
static bool getRelativeWorld(double x, double y, double relativeHeight, MapNode* mapNode, osg::Vec3d& world ) { GeoPoint mapPoint(mapNode->getMapSRS(), x, y); osg::Vec3d pos; mapNode->getMap()->toWorldPoint(mapPoint, pos); osg::Vec3d up(0,0,1); const osg::EllipsoidModel* em = mapNode->getMap()->getProfile()->getSRS()->getEllipsoid(); if (em) { up = em->computeLocalUpVector( world.x(), world.y(), world.z()); } up.normalize(); double segOffset = 50000; osg::Vec3d start = pos + (up * segOffset); osg::Vec3d end = pos - (up * segOffset); osgUtil::LineSegmentIntersector* i = new osgUtil::LineSegmentIntersector( start, end ); osgUtil::IntersectionVisitor iv; iv.setIntersector( i ); mapNode->getTerrainEngine()->accept( iv ); osgUtil::LineSegmentIntersector::Intersections& results = i->getIntersections(); if ( !results.empty() ) { const osgUtil::LineSegmentIntersector::Intersection& result = *results.begin(); world = result.getWorldIntersectPoint(); world += up * relativeHeight; return true; } return false; }
// z0 is the point that lies on the plane A parallel to the near plane through e // and on the near plane of the C frustum (the plane z = bZmax) and on the line x = e.x osg::Vec3d LispSM::getZ0_ls (const osg::Matrix &lightSpace, const osg::Vec3d &e, const double &b_lsZmax, const osg::Vec3d &eyeDir) const { // to calculate the parallel plane to the near plane through e we // calculate the plane A with the three points osg::Plane A(eyeDir, e); // to transform plane A into lightSpace A.transform(lightSpace); // transform to light space const osg::Vec3d e_ls = e * lightSpace; // z_0 has the x coordinate of e, the z coord of B_lsZmax // and the y coord of the plane A and plane (z==B_lsZmax) intersection #if 1 osg::Vec3d v = osg::Vec3d(e_ls.x(), 0, b_lsZmax); // x & z are given. We compute y from equations: // A.distance( x,y,z ) == 0 // A.distance( x,y,z ) == A.distance( x,0,z ) + A.normal.y * y // hence A.distance( x,0,z ) == -A.normal.y * y v.y() = -A.distance(v) / A.getNormal().y(); #else // get the parameters of A from the plane equation n dot d = 0 const double d = A.asVec4()[3]; const osg::Vec3d n = A.getNormal(); osg::Vec3d v(e_ls.x(), (-d - n.z() * b_lsZmax - n.x() * e_ls.x()) / n.y(), b_lsZmax); #endif return v; }
bool SpatialReference::createLocalToWorld(const osg::Vec3d& xyz, osg::Matrixd& out_local2world ) const { if ( (isProjected() || _is_plate_carre) && !isCube() ) { osg::Vec3d world; if ( !transformToWorld( xyz, world ) ) return false; out_local2world = osg::Matrix::translate(world); } else if ( isECEF() ) { //out_local2world = ECEF::createLocalToWorld(xyz); _ellipsoid->computeLocalToWorldTransformFromXYZ(xyz.x(), xyz.y(), xyz.z(), out_local2world); } else { // convert MSL to HAE if necessary: osg::Vec3d geodetic; if ( !transform(xyz, getGeodeticSRS(), geodetic) ) return false; // then to ECEF: osg::Vec3d ecef; if ( !transform(geodetic, getGeodeticSRS()->getECEF(), ecef) ) return false; //out_local2world = ECEF::createLocalToWorld(ecef); _ellipsoid->computeLocalToWorldTransformFromXYZ(ecef.x(), ecef.y(), ecef.z(), out_local2world); } return true; }
osg::Vec3d spherical_to_cartesian (osg::Vec3d & spher, double scale) { osg::Vec3d rads(spher.x (), spher.y () * DEGS_TO_RADS, spher.z () * DEGS_TO_RADS); return spherical_to_cartesian_radians(rads, scale); }
void ScreenBase::computeDefaultViewProj(osg::Vec3d eyePos, osg::Matrix & view, osg::Matrix & proj) { //translate screen to origin osg::Matrix screenTrans; screenTrans.makeTranslate(-_myInfo->xyz); //rotate screen to xz osg::Matrix screenRot; screenRot.makeRotate(-_myInfo->h * M_PI / 180.0,osg::Vec3(0,0,1), -_myInfo->p * M_PI / 180.0,osg::Vec3(1,0,0), -_myInfo->r * M_PI / 180.0,osg::Vec3(0,1,0)); eyePos = eyePos * screenTrans * screenRot; //make frustum float top, bottom, left, right; float screenDist = -eyePos.y(); top = _near * (_myInfo->height / 2.0 - eyePos.z()) / screenDist; bottom = _near * (-_myInfo->height / 2.0 - eyePos.z()) / screenDist; right = _near * (_myInfo->width / 2.0 - eyePos.x()) / screenDist; left = _near * (-_myInfo->width / 2.0 - eyePos.x()) / screenDist; proj.makeFrustum(left,right,bottom,top,_near,_far); // move camera to origin osg::Matrix cameraTrans; cameraTrans.makeTranslate(-eyePos); //make view view = screenTrans * screenRot * cameraTrans * osg::Matrix::lookAt(osg::Vec3(0,0,0),osg::Vec3(0,1,0), osg::Vec3(0,0,1)); }
osg::Vec3d ConfigManager::getVec3d(std::string attributeX, std::string attributeY, std::string attributeZ, std::string path, osg::Vec3d def, bool * found) { bool hasEntry = false; bool isFound; osg::Vec3d result; result.x() = getDouble(attributeX,path,def.x(),&isFound); if(isFound) { hasEntry = true; } result.y() = getDouble(attributeY,path,def.y(),&isFound); if(isFound) { hasEntry = true; } result.z() = getDouble(attributeZ,path,def.z(),&isFound); if(isFound) { hasEntry = true; } if(found) { *found = hasEntry; } return result; }
void GlobePlugin::setSelectedCoordinates( osg::Vec3d coords ) { mSelectedLon = coords.x(); mSelectedLat = coords.y(); mSelectedElevation = coords.z(); QgsPoint coord = QgsPoint( mSelectedLon, mSelectedLat ); emit newCoordinatesSelected( coord ); }
bool SpatialReference::transformToECEF(const osg::Vec3d& input, osg::Vec3d& output ) const { double lat = input.y(), lon = input.x(), alt = input.z(); // first convert to lat/long if necessary: if ( !isGeographic() ) transform( input.x(), input.y(), input.z(), getGeographicSRS(), lon, lat, alt ); // then convert to ECEF. //double z = input.z(); getGeographicSRS()->getEllipsoid()->convertLatLongHeightToXYZ( osg::DegreesToRadians( lat ), osg::DegreesToRadians( lon ), alt, output.x(), output.y(), output.z() ); return true; }
bool MarkerSymbolizer::pointInPolygon(const osg::Vec3d& point, osg::Vec3dArray* pointList) { if (!pointList) return false; bool result = false; const osg::Vec3dArray& polygon = *pointList; for( unsigned int i=0, j=polygon.size()-1; i<polygon.size(); j = i++ ) { if ((((polygon[i].y() <= point.y()) && (point.y() < polygon[j].y())) || ((polygon[j].y() <= point.y()) && (point.y() < polygon[i].y()))) && (point.x() < (polygon[j].x()-polygon[i].x()) * (point.y()-polygon[i].y())/(polygon[j].y()-polygon[i].y())+polygon[i].x())) { result = !result; } } return result; }
bool MapInfo::toMapPoint( const osg::Vec3d& input, const SpatialReference* inputSRS, osg::Vec3d& output ) const { if ( !inputSRS ) return false; const SpatialReference* mapSRS = _profile->getSRS(); if ( inputSRS->isEquivalentTo( mapSRS ) ) { output = input; return true; } return inputSRS->transform( input.x(), input.y(), mapSRS, output.x(), output.y() ); }
osg::Vec3d LineAnalysis::getWorldCoord(osg::Vec3d pos) { osg::Vec3d world; m_pMap3D->getSRS()->getEllipsoid()->convertLatLongHeightToXYZ( osg::DegreesToRadians(pos.y()), osg::DegreesToRadians(pos.x()), pos.z(), world.x(), world.y(), world.z()); return world; }
void TessellateOperator::tessellateGeo( const osg::Vec3d& p0, const osg::Vec3d& p1, unsigned parts, GeoInterpolation interp, Vec3dVector& out ) { double step = 1.0/double(parts); double zdelta = p1.z() - p0.z(); out.push_back( p0 ); for( unsigned i=1; i<parts; ++i ) { double t = step*double(i); osg::Vec3d p; if ( interp == GEOINTERP_GREAT_CIRCLE ) { double lat, lon; GeoMath::interpolate( osg::DegreesToRadians(p0.y()), osg::DegreesToRadians(p0.x()), osg::DegreesToRadians(p1.y()), osg::DegreesToRadians(p1.x()), t, lat, lon ); p.set( osg::RadiansToDegrees(lon), osg::RadiansToDegrees(lat), p0.z() + t*zdelta ); } else // GEOINTERP_RHUMB_LINE { double lat1 = osg::DegreesToRadians(p0.y()), lon1 = osg::DegreesToRadians(p0.x()); double lat2 = osg::DegreesToRadians(p1.y()), lon2 = osg::DegreesToRadians(p1.x()); double totalDistance = GeoMath::rhumbDistance( lat1, lon1, lat2, lon2 ); double bearing = GeoMath::rhumbBearing( lat1, lon1, lat2, lon2 ); double interpDistance = t * totalDistance; double lat3, lon3; GeoMath::rhumbDestination(lat1, lon1, bearing, interpDistance, lat3, lon3); p.set( osg::RadiansToDegrees(lon3), osg::RadiansToDegrees(lat3), p0.z() + t*zdelta ); } out.push_back(p); } }
bool CubeFaceLocator::convertModelToLocal(const osg::Vec3d& world, osg::Vec3d& local) const { #if ((OPENSCENEGRAPH_MAJOR_VERSION <= 2) && (OPENSCENEGRAPH_MINOR_VERSION < 8)) // OSG 2.7 bug workaround: bug fix in Locator submitted by GW const_cast<CubeFaceLocator*>(this)->_inverse.invert( _transform ); #endif switch(_coordinateSystemType) { case(GEOCENTRIC): { double longitude, latitude, height; _ellipsoidModel->convertXYZToLatLongHeight(world.x(), world.y(), world.z(), latitude, longitude, height ); int face=-1; double x, y; double lat_deg = osg::RadiansToDegrees(latitude); double lon_deg = osg::RadiansToDegrees(longitude); bool success = CubeUtils::latLonToFaceCoords( lat_deg, lon_deg, x, y, face, _face ); if (!success) { OE_WARN << LC << "Couldn't convert to face coords " << std::endl; return false; } if (face != _face) { OE_WARN << LC << "Face should be " << _face << " but is " << face << ", lat = " << lat_deg << ", lon = " << lon_deg << std::endl; } local = osg::Vec3d( x, y, height ) * _inverse; return true; } case(GEOGRAPHIC): case(PROJECTED): // Neither of these is supported for this locator.. { local = world * _inverse; return true; } } return false; }
osg::Vec3d RadarMap::getLonLat(const osg::Vec3d& worldPos) { osg::Vec3d vecPos = osg::Vec3d(); if (m_pOSGViewer) { m_pOSGViewer->getSRS()->getEllipsoid()->convertXYZToLatLongHeight( worldPos.x(), worldPos.y(), worldPos.z(), vecPos.y(), vecPos.x(), vecPos.z()); vecPos.x() = osg::RadiansToDegrees(vecPos.x()); vecPos.y() = osg::RadiansToDegrees(vecPos.y()); } return vecPos; }
void CameraFlight::navigate(osg::Matrix destMat, osg::Vec3 destVec) { osg::Matrix objMat = SceneManager::instance()->getObjectTransform()->getMatrix(); switch(_flightMode) { case INSTANT:{ cout<<"USING INSTANT"<<endl; SceneManager::instance()->setObjectMatrix(destMat); break; } case SATELLITE: cout<<"USING SATELLITE"<<endl; t = 0.0; total = 0.0; objMat.decompose(trans2, rot2, scale2, so2); a = (maxHeight - trans2[1])/25.0; map->getProfile()->getSRS()->getEllipsoid()->convertLatLongHeightToXYZ( destVec.x(),destVec.y(),destVec.z(),toVec.x(),toVec.y(),toVec.z()); fromVec = origPlanetPoint; fromVec.normalize(); toVec.normalize(); origAngle = acos((fromVec * toVec)/((fromVec.length() * toVec.length()))); origAngle = RadiansToDegrees(origAngle); angle = origAngle; if(origAngle <= 10) { maxHeight = 6.5e+9; } else { maxHeight = 2.0e+10; } flagRot = true; break; case AIRPLANE: cout<<"USING AIRPLANE"<<endl; break; default: cout<<"PICK THE ALGORYTHM!!!!"<<endl; break; } }
void LOSCreationDialog::setLOSPoint(LOSPoint point, const osg::Vec3d& value, bool updateUi) { _updatingUi = !updateUi; switch(point) { case P2P_START: _ui.p1LatBox->setValue(value.y()); _ui.p1LonBox->setValue(value.x()); _p1BaseAlt = value.z(); if (!isAltitudeRelative(point)) _ui.p1AltBox->setValue(value.z()); break; case P2P_END: _ui.p2LatBox->setValue(value.y()); _ui.p2LonBox->setValue(value.x()); _p2BaseAlt = value.z(); if (!isAltitudeRelative(point)) _ui.p2AltBox->setValue(value.z()); break; case RADIAL_CENTER: _ui.radLatBox->setValue(value.y()); _ui.radLonBox->setValue(value.x()); _radBaseAlt = value.z(); if (!isAltitudeRelative(point)) _ui.radAltBox->setValue(value.z()); break; } _updatingUi = false; }
osg::Quat FaceTransform::computeQuat(osg::Vec3d direction) { direction.normalize(); double zAngle = atan2(direction.y(), direction.x()); osg::Quat zRot(zAngle, osg::Vec3d(0,0,1)); osg::Vec3d yAxis = zRot * osg::Vec3d(0,1,0); double zLength = (direction - osg::Vec3d(0,0,direction.z())).length(); double yAngle = - atan2(direction.z(), zLength) + osg::PI/2; osg::Quat yRot(yAngle, yAxis); return zRot * yRot; }
void SpatialReference::createLocal2World(const osg::Vec3d& xyz, osg::Matrixd& out_local2world ) const { if ( isProjected() ) { out_local2world = osg::Matrix::translate(xyz); } else { getEllipsoid()->computeLocalToWorldTransformFromLatLongHeight( osg::DegreesToRadians(xyz.y()), osg::DegreesToRadians(xyz.x()), xyz.z(), out_local2world); } }
double LispSM::calcNoptGeneral(const osg::Matrix lightSpace, const osg::BoundingBox &B_ls) const { const osg::Matrix &eyeView = getViewMatrix(); const osg::Matrix invLightSpace = osg::Matrix::inverse(lightSpace); const osg::Vec3d z0_ls = getZ0_ls(lightSpace, _E, B_ls.zMax(), getEyeDir()); const osg::Vec3d z1_ls = osg::Vec3d(z0_ls.x(), z0_ls.y(), B_ls.zMin()); // to world const osg::Vec4d z0_ws = osg::Vec4d(z0_ls, 1) * invLightSpace; const osg::Vec4d z1_ws = osg::Vec4d(z1_ls, 1) * invLightSpace; // to eye const osg::Vec4d z0_cs = z0_ws * eyeView; const osg::Vec4d z1_cs = z1_ws * eyeView; double z0 = -z0_cs.z() / z0_cs.w(); double z1 = -z1_cs.z() / z1_cs.w(); if (z1 / z0 <= 1.0) { // solve camera pos singularity in light space problem brutally: // if extreme points of B projected to Light space extend beyond // camera frustum simply use B extents in camera frustum // Its not optimal selection but ceratainly better than negative N osg::BoundingBox bb = _hull.computeBoundingBox(eyeView); z0 = -bb.zMax(); if (z0 <= 0) z0 = 0.1; z1 = -bb.zMin(); if (z1 <= z0) z1 = z0 + 0.1; } const double d = osg::absolute(B_ls.zMax() - B_ls.zMin()); double N = d / (sqrt(z1 / z0) - 1.0); #if PRINT_COMPUTED_N_OPT std::cout << " N=" << std::setw(8) << N << " n=" << std::setw(8) << z0 << " f=" << std::setw(8) << z1 << "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b" << std::flush; #endif return N; }
osg::Vec3d spherical_to_cartesian_radians (osg::Vec3d & spher, double scale) { double r = spher.x (); double lambda = spher.y (); double phi = spher.z (); double sphi = sin (phi); double cphi = cos (phi); double slambda = sin (lambda); double clambda = cos (lambda); double x = scale * r * cphi * clambda; double y = scale * r * cphi * slambda; double z = scale * r * sphi; return osg::Vec3d(x, y, z); }
osg::Vec3d OrthoNode::adjustOcclusionCullingPoint( const osg::Vec3d& world ) { // Adjust the height by a little bit "up", we can't have the occlusion point sitting right on the ground if ( getMapNode() ) { const osg::EllipsoidModel* em = getMapNode()->getMapSRS()->getEllipsoid(); osg::Vec3d up = em ? em->computeLocalUpVector( world.x(), world.y(), world.z() ) : osg::Vec3d(0,0,1); osg::Vec3d adjust = up * 0.1; return world + adjust; } else { return world; } }
void SpatialReference::createWorld2Local(const osg::Vec3d& xyz, osg::Matrixd& out_world2local ) const { if ( isProjected() ) { out_world2local = osg::Matrix::translate(-xyz); } else { osg::Matrix local2world; getEllipsoid()->computeLocalToWorldTransformFromLatLongHeight( osg::DegreesToRadians(xyz.y()), osg::DegreesToRadians(xyz.x()), xyz.z(), local2world); out_world2local = osg::Matrix::inverse(local2world); } }
// this is the algorithm discussed in the article osg::Matrix LispSM::getLispSmMtx(const osg::Matrix &lightSpace) const { const osg::BoundingBox B_ls = _hull.computeBoundingBox(lightSpace); const double n = getN(lightSpace, B_ls); // get the coordinates of the near camera point in light space const osg::Vec3d e_ls = _E * lightSpace; // c start has the x and y coordinate of e, the z coord of B.min() const osg::Vec3d Cstart_lp(e_ls.x(), e_ls.y(), B_ls.zMax()); if (n >= OSG_INFINITY) { // if n is inf. than we should do uniform shadow mapping return osg::Matrix::identity(); } // calc C the projection center // new projection center C, n behind the near plane of P // we work along a negative axis so we transform +n*<the positive axis> == -n*<neg axis> const osg::Vec3d C(Cstart_lp + osg::Vec3d(0, 0, 1) * n); // construct a translation that moves to the projection center const osg::Matrix projectionCenter = osg::Matrix::translate(-C); // calc d the perspective transform depth or light space y extents const double d = osg::absolute(B_ls.zMax() - B_ls.zMin()); // the lispsm perspective transformation // here done with a standard frustum call that maps P onto the unit cube with // corner points [-1,-1,-1] and [1,1,1]. // in directX you can use the same mapping and do a mapping to the directX post-perspective cube // with corner points [-1,-1,0] and [1,1,1] as the final step after all the shadow mapping. osg::Matrix P = osg::Matrix::frustum(-1.0, 1.0, -1.0, 1.0, n, n + d); // invert the transform from right handed into left handed coordinate system for the ndc // done by the openGL style frustumGL call // so we stay in a right handed system P = P * osg::Matrix::scale(1.0, 1.0, -1.0); // return the lispsm frustum with the projection center return projectionCenter * P; }
bool SpatialReference::transformToECEF(const osg::Vec3d& input, osg::Vec3d& output ) const { osg::Vec3d geo(input); // first convert to lat/long/hae: if ( !isGeodetic() ) { if ( !transform(input, getGeodeticSRS(), geo) ) return false; } // then convert to ECEF. getEllipsoid()->convertLatLongHeightToXYZ( osg::DegreesToRadians( geo.y() ), osg::DegreesToRadians( geo.x() ), geo.z(), output.x(), output.y(), output.z() ); return true; }
bool SpatialReference::transformFromECEF(const osg::Vec3d& ecef, osg::Vec3d& output, double* out_haeZ ) const { // transform to lat/long/hae (geodetic): osg::Vec3d geodetic; getEllipsoid()->convertXYZToLatLongHeight( ecef.x(), ecef.y(), ecef.z(), geodetic.y(), geodetic.x(), geodetic.z() ); geodetic.y() = osg::RadiansToDegrees(geodetic.y()); geodetic.x() = osg::RadiansToDegrees(geodetic.x()); // if our SRS is geographic, save the HAE now: if ( out_haeZ ) *out_haeZ = geodetic.z(); return getGeodeticSRS()->transform(geodetic, this, output); }
bool Locator::computeLocalBounds(Locator& source, osg::Vec3d& bottomLeft, osg::Vec3d& topRight) const { typedef std::list<osg::Vec3d> Corners; Corners corners; osg::Vec3d cornerNDC; if (Locator::convertLocalCoordBetween(source, osg::Vec3d(0.0,0.0,0.0), *this, cornerNDC)) { corners.push_back(cornerNDC); } if (Locator::convertLocalCoordBetween(source, osg::Vec3d(1.0,0.0,0.0), *this, cornerNDC)) { corners.push_back(cornerNDC); } if (Locator::convertLocalCoordBetween(source, osg::Vec3d(0.0,1.0,0.0), *this, cornerNDC)) { corners.push_back(cornerNDC); } if (Locator::convertLocalCoordBetween(source, osg::Vec3d(1.0,1.0,0.0), *this, cornerNDC)) { corners.push_back(cornerNDC); } if (corners.empty()) return false; Corners::iterator itr = corners.begin(); bottomLeft.x() = topRight.x() = itr->x(); bottomLeft.y() = topRight.y() = itr->y(); ++itr; for(; itr != corners.end(); ++itr) { bottomLeft.x() = osg::minimum( bottomLeft.x(), itr->x()); bottomLeft.y() = osg::minimum( bottomLeft.y(), itr->y()); topRight.x() = osg::maximum( topRight.x(), itr->x()); topRight.y() = osg::maximum( topRight.y(), itr->y()); } return true; }
MeshNode GeodeticManifold::createNode( const osg::Vec3d& manCoord ) const { MeshNode node; node._manifoldCoord = manCoord; node._geodeticCoord.set( osg::DegreesToRadians(manCoord.x()), osg::DegreesToRadians(manCoord.y()), manCoord.z() ); osg::Vec3d temp; _ellipsoid->convertLatLongHeightToXYZ( node._geodeticCoord.y(), node._geodeticCoord.x(), node._geodeticCoord.z(), temp.x(), temp.y(), temp.z() ); node._vertex = temp; node._normal = _ellipsoid->computeLocalUpVector( temp.x(), temp.y(), temp.z() ); return node; }