Changeset 10536

Show
Ignore:
Timestamp:
08/20/09 16:19:10 (5 years ago)
Author:
robert
Message:

From Ronald van Maarseveen and Robert Osfield, changed compute of up vector and localToWorld transform so that it takes in to account the geographic latitude.

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • OpenSceneGraph/trunk/include/osg/CoordinateSystemNode

    r10502 r10536  
    6161        inline void computeLocalToWorldTransformFromXYZ(double X, double Y, double Z, osg::Matrixd& localToWorld) const; 
    6262 
     63        inline void computeCoordinateFrame(double latitude, double longitude, osg::Matrixd& localToWorld) const; 
     64 
    6365        inline osg::Vec3d computeLocalUpVector(double X, double Y, double Z) const; 
    6466 
     
    190192    double X, Y, Z; 
    191193    convertLatLongHeightToXYZ(latitude,longitude,height,X,Y,Z); 
    192     computeLocalToWorldTransformFromXYZ(X,Y,Z,localToWorld); 
     194 
     195    localToWorld.makeTranslate(X,Y,Z); 
     196    computeCoordinateFrame(latitude, longitude, localToWorld); 
    193197} 
    194198 
    195199inline void EllipsoidModel::computeLocalToWorldTransformFromXYZ(double X, double Y, double Z, osg::Matrixd& localToWorld) const 
    196200{ 
     201    double  latitude, longitude, height; 
     202    convertXYZToLatLongHeight(X,Y,Z,latitude,longitude,height); 
     203 
    197204    localToWorld.makeTranslate(X,Y,Z); 
    198  
    199  
    200     // normalize X,Y,Z 
    201     double inverse_length = 1.0/sqrt(X*X + Y*Y + Z*Z); 
    202      
    203     X *= inverse_length; 
    204     Y *= inverse_length; 
    205     Z *= inverse_length; 
    206  
    207     double length_XY = sqrt(X*X + Y*Y); 
    208     double inverse_length_XY = 1.0/length_XY; 
    209  
    210     // Vx = |(-Y,X,0)| 
    211     localToWorld(0,0) = -Y*inverse_length_XY; 
    212     localToWorld(0,1) = X*inverse_length_XY; 
    213     localToWorld(0,2) = 0.0; 
    214  
    215     // Vy = /(-Z*X/(sqrt(X*X+Y*Y), -Z*Y/(sqrt(X*X+Y*Y),sqrt(X*X+Y*Y))|  
    216     double Vy_x = -Z*X*inverse_length_XY; 
    217     double Vy_y = -Z*Y*inverse_length_XY; 
    218     double Vy_z = length_XY; 
    219     inverse_length = 1.0/sqrt(Vy_x*Vy_x + Vy_y*Vy_y + Vy_z*Vy_z);             
    220     localToWorld(1,0) = Vy_x*inverse_length; 
    221     localToWorld(1,1) = Vy_y*inverse_length; 
    222     localToWorld(1,2) = Vy_z*inverse_length; 
    223  
    224     // Vz = (X,Y,Z) 
    225     localToWorld(2,0) = X; 
    226     localToWorld(2,1) = Y; 
    227     localToWorld(2,2) = Z; 
     205    computeCoordinateFrame(latitude, longitude, localToWorld); 
     206} 
     207 
     208inline void EllipsoidModel::computeCoordinateFrame(double latitude, double longitude, osg::Matrixd& localToWorld) const 
     209{ 
     210    // Compute up vector 
     211    osg::Vec3d    up      ( cos(longitude)*cos(latitude), sin(longitude)*cos(latitude), sin(latitude)); 
     212 
     213    // Compute east vector 
     214    osg::Vec3d    east    (-sin(longitude), cos(longitude), 0); 
     215 
     216    // Compute north vector = outer product up x east 
     217    osg::Vec3d    north   = up ^ east; 
     218 
     219    // set matrix 
     220    localToWorld(0,0) = east[0]; 
     221    localToWorld(0,1) = east[1]; 
     222    localToWorld(0,2) = east[2]; 
     223 
     224    localToWorld(1,0) = north[0]; 
     225    localToWorld(1,1) = north[1]; 
     226    localToWorld(1,2) = north[2]; 
     227 
     228    localToWorld(2,0) = up[0]; 
     229    localToWorld(2,1) = up[1]; 
     230    localToWorld(2,2) = up[2]; 
    228231} 
    229232 
    230233inline osg::Vec3d EllipsoidModel::computeLocalUpVector(double X, double Y, double Z) const 
    231234{ 
    232     osg::Vec3d normal(X,Y,Z); 
    233     normal.normalize(); 
    234     return normal; 
     235    // Note latitude is angle between normal to ellipsoid surface and XY-plane 
     236    double  latitude; 
     237    double  longitude; 
     238    double  altitude; 
     239    convertXYZToLatLongHeight(X,Y,Z,latitude,longitude,altitude); 
     240 
     241    // Compute up vector 
     242    return osg::Vec3d(  cos(longitude) * cos(latitude), 
     243                        sin(longitude) * cos(latitude), 
     244                                         sin(latitude)); 
    235245} 
    236246