Changeset 7838

Show
Ignore:
Timestamp:
01/28/08 16:41:42
Author:
robert
Message:

Added projectorMatrix parameter support to *SphericalDisplay? setup functions and .view, this allows one
to flip, rotate, or turn up side the position of the projector. Note, projector at base of display is the default.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • OpenSceneGraph/trunk/include/osgViewer/View

    r7681 r7838  
    162162 
    163163        /** Convenience method for spherical display using 6 slave cameras rendering the 6 sides of a cube map, and 7th camera doing distortion correction to present on a spherical display.*/ 
    164         void setUpViewFor3DSphericalDisplay(double radius=1.0, double collar=0.45, unsigned int screenNum=0, osg::Image* intensityMap=0); 
     164        void setUpViewFor3DSphericalDisplay(double radius=1.0, double collar=0.45, unsigned int screenNum=0, osg::Image* intensityMap=0, const osg::Matrixd& projectorMatrix = osg::Matrixd()); 
    165165 
    166166        /** Convenience method for spherical display by rendering main scene to as panoramic 2:1 texture and then doing distortion correction to present onto a spherical display.*/ 
    167         void setUpViewForPanoramicSphericalDisplay(double radius=1.0, double collar=0.45, unsigned int screenNum=0, osg::Image* intensityMap=0); 
     167        void setUpViewForPanoramicSphericalDisplay(double radius=1.0, double collar=0.45, unsigned int screenNum=0, osg::Image* intensityMap=0, const osg::Matrixd& projectorMatrix = osg::Matrixd()); 
    168168 
    169169         
  • OpenSceneGraph/trunk/src/osgPlugins/osgViewer/View.cpp

    r7648 r7838  
    2121    View_writeLocalData 
    2222); 
     23 
     24 
     25static bool readMatrix(osg::Matrix& matrix, osgDB::Input& fr, const char* keyword) 
     26{ 
     27    bool iteratorAdvanced = false; 
     28     
     29    if (fr[0].matchWord(keyword) && fr[1].isOpenBracket()) 
     30    { 
     31        int entry = fr[0].getNoNestedBrackets(); 
     32 
     33        fr += 2; 
     34 
     35        int row=0; 
     36        int col=0; 
     37        double v; 
     38        while (!fr.eof() && fr[0].getNoNestedBrackets()>entry) 
     39        { 
     40            if (fr[0].getFloat(v)) 
     41            { 
     42                matrix(row,col)=v; 
     43                ++col; 
     44                if (col>=4) 
     45                { 
     46                    col = 0; 
     47                    ++row; 
     48                } 
     49                ++fr; 
     50            } 
     51            else fr.advanceOverCurrentFieldOrBlock(); 
     52        } 
     53        iteratorAdvanced = true; 
     54    }         
     55         
     56    return iteratorAdvanced; 
     57} 
     58 
     59 
     60static bool writeMatrix(const osg::Matrix& matrix, osgDB::Output& fw, const char* keyword) 
     61{ 
     62    fw.indent() << keyword <<" {" << std::endl; 
     63    fw.moveIn(); 
     64    fw.indent() << matrix(0,0) << " " << matrix(0,1) << " " << matrix(0,2) << " " << matrix(0,3) << std::endl; 
     65    fw.indent() << matrix(1,0) << " " << matrix(1,1) << " " << matrix(1,2) << " " << matrix(1,3) << std::endl; 
     66    fw.indent() << matrix(2,0) << " " << matrix(2,1) << " " << matrix(2,2) << " " << matrix(2,3) << std::endl; 
     67    fw.indent() << matrix(3,0) << " " << matrix(3,1) << " " << matrix(3,2) << " " << matrix(3,3) << std::endl; 
     68    fw.moveOut(); 
     69    fw.indent() << "}"<< std::endl; 
     70    return true; 
     71} 
    2372 
    2473osg::Image* readIntensityImage(osgDB::Input& fr, bool& itrAdvanced) 
     
    108157        unsigned int screenNum = 0; 
    109158        unsigned int intensityFormat = 8; 
     159        osg::Matrix matrix;  
    110160        std::string filename; 
    111161        osg::ref_ptr<osg::Image> intensityMap; 
     
    123173            if (fr.matchSequence("intensityMap {")) intensityMap = readIntensityImage(fr,local_itrAdvanced); 
    124174            if (fr.read("intensityFormat",intensityFormat)) local_itrAdvanced = true; 
     175            if (readMatrix(matrix,fr,"projectorMatrix")) local_itrAdvanced = true; 
    125176             
    126177            if (!local_itrAdvanced) ++fr; 
     
    145196 
    146197 
    147         if (matchedFirst) view.setUpViewFor3DSphericalDisplay(radius, collar, screenNum, intensityMap.get()); 
    148         else view.setUpViewForPanoramicSphericalDisplay(radius, collar, screenNum, intensityMap.get()); 
     198        if (matchedFirst) view.setUpViewFor3DSphericalDisplay(radius, collar, screenNum, intensityMap.get(), matrix); 
     199        else view.setUpViewForPanoramicSphericalDisplay(radius, collar, screenNum, intensityMap.get(), matrix); 
    149200    } 
    150201 
  • OpenSceneGraph/trunk/src/osgViewer/View.cpp

    r7681 r7838  
    704704} 
    705705 
    706 static osg::Geometry* create3DSphericalDisplayDistortionMesh(const osg::Vec3& origin, const osg::Vec3& widthVector, const osg::Vec3& heightVector, double sphere_radius, double collar_radius,osg::Image* intensityMap
     706static osg::Geometry* create3DSphericalDisplayDistortionMesh(const osg::Vec3& origin, const osg::Vec3& widthVector, const osg::Vec3& heightVector, double sphere_radius, double collar_radius,osg::Image* intensityMap, const osg::Matrix& projectorMatrix
    707707{ 
    708708    osg::Vec3d center(0.0,0.0,0.0); 
     
    748748    osg::Vec3 cursor = bottom; 
    749749    int i,j; 
    750      
    751      
     750 
    752751    if (centerProjection) 
    753752    { 
     
    773772 
    774773                vertices->push_back(cursor); 
    775                 texcoords0->push_back(texcoord); 
     774                texcoords0->push_back(texcoord * projectorMatrix); 
    776775 
    777776                osg::Vec2 texcoord1(theta/(2.0*osg::PI), 1.0f - phi/osg::PI_2); 
     
    817816 
    818817                vertices->push_back(cursor); 
    819                 texcoords0->push_back(texcoord); 
     818                texcoords0->push_back(texcoord * projectorMatrix); 
    820819 
    821820                osg::Vec2 texcoord1(theta/(2.0*osg::PI), 1.0f - phi/osg::PI_2); 
     
    859858} 
    860859 
    861 void View::setUpViewFor3DSphericalDisplay(double radius, double collar, unsigned int screenNum, osg::Image* intensityMap
     860void View::setUpViewFor3DSphericalDisplay(double radius, double collar, unsigned int screenNum, osg::Image* intensityMap, const osg::Matrixd& projectorMatrix
    862861{ 
    863862    osg::notify(osg::INFO)<<"View::setUpViewFor3DSphericalDisplay(rad="<<radius<<", cllr="<<collar<<", sn="<<screenNum<<", im="<<intensityMap<<")"<<std::endl; 
     
    868867        return; 
    869868    } 
    870  
    871869 
    872870    osg::GraphicsContext::ScreenIdentifier si; 
     
    10481046    { 
    10491047        osg::Geode* geode = new osg::Geode(); 
    1050         geode->addDrawable(create3DSphericalDisplayDistortionMesh(osg::Vec3(0.0f,0.0f,0.0f), osg::Vec3(width,0.0f,0.0f), osg::Vec3(0.0f,height,0.0f), radius, collar, applyIntensityMapAsColours ? intensityMap : 0)); 
     1048        geode->addDrawable(create3DSphericalDisplayDistortionMesh(osg::Vec3(0.0f,0.0f,0.0f), osg::Vec3(width,0.0f,0.0f), osg::Vec3(0.0f,height,0.0f), radius, collar, applyIntensityMapAsColours ? intensityMap : 0, projectorMatrix)); 
    10511049 
    10521050        // new we need to add the texture to the mesh, we do so by creating a  
     
    10641062        camera->setGraphicsContext(gc.get()); 
    10651063        camera->setClearMask(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT ); 
    1066         camera->setClearColor( osg::Vec4(0.1,0.1,1.0,1.0) ); 
     1064        camera->setClearColor( osg::Vec4(0.0,0.0,0.0,1.0) ); 
    10671065        camera->setViewport(new osg::Viewport(0, 0, width, height)); 
    10681066        GLenum buffer = traits->doubleBuffer ? GL_BACK : GL_FRONT; 
     
    10711069        camera->setReferenceFrame(osg::Camera::ABSOLUTE_RF); 
    10721070        camera->setAllowEventFocus(false); 
    1073         //camera->setInheritanceMask(camera->getInheritanceMask() & ~osg::CullSettings::CLEAR_COLOR & ~osg::CullSettings::COMPUTE_NEAR_FAR_MODE); 
     1071        camera->setInheritanceMask(camera->getInheritanceMask() & ~osg::CullSettings::CLEAR_COLOR & ~osg::CullSettings::COMPUTE_NEAR_FAR_MODE); 
    10741072        //camera->setComputeNearFarMode(osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR); 
    10751073         
     
    10941092} 
    10951093 
    1096 static osg::Geometry* createParoramicSphericalDisplayDistortionMesh(const osg::Vec3& origin, const osg::Vec3& widthVector, const osg::Vec3& heightVector, double sphere_radius, double collar_radius, osg::Image* intensityMap
     1094static osg::Geometry* createParoramicSphericalDisplayDistortionMesh(const osg::Vec3& origin, const osg::Vec3& widthVector, const osg::Vec3& heightVector, double sphere_radius, double collar_radius, osg::Image* intensityMap, const osg::Matrix& projectorMatrix
    10971095{ 
    10981096    osg::Vec3d center(0.0,0.0,0.0); 
     
    11101108    osg::notify(osg::INFO)<<"createParoramicSphericalDisplayDistortionMesh : Projector position = "<<projector<<std::endl; 
    11111109    osg::notify(osg::INFO)<<"createParoramicSphericalDisplayDistortionMesh : distance = "<<distance<<std::endl; 
    1112  
    11131110 
    11141111    // create the quad to visualize. 
     
    11381135    osg::Vec3 top = origin + yAxis*height; 
    11391136 
    1140     osg::Vec3d screenCenter = origin + widthVector*0.5f + heightVector*0.5f; 
     1137    osg::Vec3 screenCenter = origin + widthVector*0.5f + heightVector*0.5f; 
    11411138    float screenRadius = heightVector.length() * 0.5f; 
    11421139 
    11431140    double rotation = 0.0; 
    11441141 
    1145     osg::Vec3 cursor = bottom; 
    1146     int i,j; 
    1147      
    1148     int midSteps = noSteps/2; 
    1149      
    1150     for(i=0;i<midSteps;++i) 
     1142    geometry->getOrCreateStateSet()->setMode(GL_CULL_FACE, osg::StateAttribute::OFF | osg::StateAttribute::PROTECTED); 
     1143 
     1144    for(int i=0;i<noSteps;++i) 
    11511145    { 
    11521146        osg::Vec3 cursor = bottom+dy*(float)i; 
    1153         for(j=0;j<midSteps;++j) 
    1154         { 
    1155             osg::Vec2 delta(cursor.x() - screenCenter.x(), cursor.y() - screenCenter.y()); 
    1156             double theta = atan2(delta.x(), -delta.y()); 
    1157             theta += 2*osg::PI; 
    1158  
    1159             double phi = osg::PI_2 * delta.length() / screenRadius; 
    1160             if (phi > osg::PI_2) phi = osg::PI_2; 
    1161  
    1162             double f = distance * sin(phi); 
    1163             double e = distance * cos(phi) + sqrt( sphere_radius*sphere_radius - f*f); 
    1164             double l = e * cos(phi); 
    1165             double h = e * sin(phi); 
    1166             double gamma = atan2(h, l-distance); 
    1167  
    1168             osg::Vec2 texcoord(theta/(2.0*osg::PI), 1.0-gamma/osg::PI); 
    1169  
    1170             // osg::notify(osg::NOTICE)<<"cursor = "<<cursor<< " theta = "<<theta<< "phi="<<phi<<" gamma = "<<gamma<<" texcoord="<<texcoord<<std::endl; 
    1171  
     1147        for(int j=0;j<noSteps;++j) 
     1148        { 
     1149            osg::Vec2 texcoord(double(i)/double(noSteps-1), double(j)/double(noSteps-1)); 
     1150            double theta = texcoord.x() * 2.0 * osg::PI; 
     1151            double phi = (1.0-texcoord.y()) * osg::PI; 
     1152             
     1153            if (texcoord_flip) texcoord.y() = 1.0f - texcoord.y(); 
     1154 
     1155            osg::Vec3 pos(sin(phi)*sin(theta), sin(phi)*cos(theta), cos(phi)); 
     1156            pos = pos*projectorMatrix; 
     1157             
     1158            double alpha = atan2(pos.x(), pos.y()); 
     1159            if (alpha<0.0) alpha += 2.0*osg::PI; 
     1160             
     1161            double beta = atan2(sqrt(pos.x()*pos.x() + pos.y()*pos.y()), pos.z()); 
     1162            if (beta<0.0) beta += 2.0*osg::PI; 
     1163 
     1164            double gamma = atan2(sqrt(pos.x()*pos.x() + pos.y()*pos.y()), pos.z()+distance); 
     1165            if (gamma<0.0) gamma += 2.0*osg::PI; 
     1166             
     1167             
     1168            osg::Vec3 v = screenCenter + osg::Vec3(sin(alpha)*gamma*2.0/osg::PI, -cos(alpha)*gamma*2.0/osg::PI, 0.0f)*screenRadius; 
     1169              
    11721170            if (flip) 
    1173                 vertices->push_back(osg::Vec3(cursor.x(), top.y()-(cursor.y()-origin.y()),cursor.z())); 
     1171                vertices->push_back(osg::Vec3(v.x(), top.y()-(v.y()-origin.y()),v.z())); 
    11741172            else 
    1175                 vertices->push_back(cursor); 
    1176              
    1177             texcoords0->push_back( texcoord_flip ? osg::Vec2(texcoord.x(), 1.0f - texcoord.y()) : texcoord); 
    1178          
    1179             osg::Vec2 texcoord1(theta/(2.0*osg::PI), 1.0f - phi/osg::PI_2); 
     1173                vertices->push_back(v); 
     1174 
     1175            texcoords0->push_back( texcoord ); 
     1176         
     1177            osg::Vec2 texcoord1(alpha/(2.0*osg::PI), 1.0f - beta/osg::PI); 
    11801178            if (intensityMap) 
    1181             {             
     1179            { 
    11821180                colors->push_back(intensityMap->getColor(texcoord1)); 
    11831181            } 
     
    11881186            } 
    11891187 
    1190             if (j+1<midSteps) cursor += dx; 
    1191         } 
    1192  
    1193         for(;j<noSteps;++j) 
    1194         { 
    1195             osg::Vec2 delta(cursor.x() - screenCenter.x(), cursor.y() - screenCenter.y()); 
    1196             double theta = atan2(delta.x(), -delta.y()); 
    1197             double phi = osg::PI_2 * delta.length() / screenRadius; 
    1198             if (phi > osg::PI_2) phi = osg::PI_2; 
    1199  
    1200             double f = distance * sin(phi); 
    1201             double e = distance * cos(phi) + sqrt( sphere_radius*sphere_radius - f*f); 
    1202             double l = e * cos(phi); 
    1203             double h = e * sin(phi); 
    1204             double gamma = atan2(h, l-distance); 
    1205  
    1206             osg::Vec2 texcoord(theta/(2.0*osg::PI), 1.0-gamma/osg::PI); 
    1207  
    1208             // osg::notify(osg::NOTICE)<<"cursor = "<<cursor<< " theta = "<<theta<< "phi="<<phi<<" gamma = "<<gamma<<" texcoord="<<texcoord<<std::endl; 
    1209  
    1210             if (flip) 
    1211                 vertices->push_back(osg::Vec3(cursor.x(), top.y()-(cursor.y()-origin.y()),cursor.z())); 
    1212             else 
    1213                 vertices->push_back(cursor); 
    1214  
    1215             texcoords0->push_back( texcoord_flip ? osg::Vec2(texcoord.x(), 1.0f - texcoord.y()) : texcoord); 
    1216  
    1217             osg::Vec2 texcoord1(theta/(2.0*osg::PI), 1.0f - phi/osg::PI_2); 
    1218             if (intensityMap) 
    1219             {             
    1220                 colors->push_back(intensityMap->getColor(texcoord1)); 
    1221             } 
    1222             else 
    1223             { 
    1224                 colors->push_back(osg::Vec4(1.0f,1.0f,1.0f,1.0f)); 
    1225                 if (texcoords1) texcoords1->push_back( texcoord1 ); 
    1226             } 
    1227  
    1228             cursor += dx; 
    1229         } 
    1230         // osg::notify(osg::NOTICE)<<std::endl; 
    1231     } 
    1232      
    1233     for(;i<noSteps;++i) 
    1234     { 
    1235         osg::Vec3 cursor = bottom+dy*(float)i; 
    1236         for(j=0;j<noSteps;++j) 
    1237         { 
    1238             osg::Vec2 delta(cursor.x() - screenCenter.x(), cursor.y() - screenCenter.y()); 
    1239             double theta = atan2(delta.x(), -delta.y()); 
    1240             if (theta<0.0) theta += 2*osg::PI; 
    1241             double phi = osg::PI_2 * delta.length() / screenRadius; 
    1242             if (phi > osg::PI_2) phi = osg::PI_2; 
    1243  
    1244             double f = distance * sin(phi); 
    1245             double e = distance * cos(phi) + sqrt( sphere_radius*sphere_radius - f*f); 
    1246             double l = e * cos(phi); 
    1247             double h = e * sin(phi); 
    1248             double gamma = atan2(h, l-distance); 
    1249  
    1250             osg::Vec2 texcoord(theta/(2.0*osg::PI), 1.0-gamma/osg::PI); 
    1251  
    1252             // osg::notify(osg::NOTICE)<<"cursor = "<<cursor<< " theta = "<<theta<< "phi="<<phi<<" gamma = "<<gamma<<" texcoord="<<texcoord<<std::endl; 
    1253  
    1254             if (flip) 
    1255                 vertices->push_back(osg::Vec3(cursor.x(), top.y()-(cursor.y()-origin.y()),cursor.z())); 
    1256             else 
    1257                 vertices->push_back(cursor); 
    1258  
    1259             texcoords0->push_back( texcoord_flip ? osg::Vec2(texcoord.x(), 1.0f - texcoord.y()) : texcoord); 
    1260  
    1261             osg::Vec2 texcoord1(theta/(2.0*osg::PI), 1.0f - phi/osg::PI_2); 
    1262             if (intensityMap) 
    1263             {             
    1264                 colors->push_back(intensityMap->getColor(texcoord1)); 
    1265             } 
    1266             else 
    1267             { 
    1268                 colors->push_back(osg::Vec4(1.0f,1.0f,1.0f,1.0f)); 
    1269                 if (texcoords1) texcoords1->push_back( texcoord1 ); 
    1270             } 
    1271  
    1272             cursor += dx; 
    1273         } 
    1274  
    1275         // osg::notify(osg::NOTICE)<<std::endl; 
    1276     } 
     1188 
     1189        } 
     1190    } 
     1191 
    12771192 
    12781193    // pass the created vertex array to the points geometry object. 
     
    12851200    if (texcoords1) geometry->setTexCoordArray(1,texcoords1); 
    12861201 
    1287     for(i=0;i<noSteps-1;++i) 
    1288     { 
    1289         osg::DrawElementsUShort* elements = new osg::DrawElementsUShort(osg::PrimitiveSet::QUAD_STRIP); 
    1290         for(j=0;j<noSteps;++j) 
    1291         { 
    1292             elements->push_back(j+(i+1)*noSteps); 
    1293             elements->push_back(j+(i)*noSteps); 
    1294         } 
    1295         geometry->addPrimitiveSet(elements); 
    1296     } 
    1297      
     1202    osg::DrawElementsUShort* elements = new osg::DrawElementsUShort(osg::PrimitiveSet::TRIANGLES); 
     1203    geometry->addPrimitiveSet(elements); 
     1204 
     1205    for(int i=0;i<noSteps-1;++i) 
     1206    { 
     1207        for(int j=0;j<noSteps-1;++j) 
     1208        { 
     1209            int i1 = j+(i+1)*noSteps; 
     1210            int i2 = j+(i)*noSteps; 
     1211            int i3 = j+1+(i)*noSteps; 
     1212            int i4 = j+1+(i+1)*noSteps; 
     1213             
     1214            osg::Vec3& v1 = (*vertices)[i1]; 
     1215            osg::Vec3& v2 = (*vertices)[i2]; 
     1216            osg::Vec3& v3 = (*vertices)[i3]; 
     1217            osg::Vec3& v4 = (*vertices)[i4]; 
     1218 
     1219            if ((v1-screenCenter).length()>screenRadius) continue; 
     1220            if ((v2-screenCenter).length()>screenRadius) continue; 
     1221            if ((v3-screenCenter).length()>screenRadius) continue; 
     1222            if ((v4-screenCenter).length()>screenRadius) continue; 
     1223             
     1224            elements->push_back(i1); 
     1225            elements->push_back(i2); 
     1226            elements->push_back(i3); 
     1227             
     1228            elements->push_back(i1); 
     1229            elements->push_back(i3); 
     1230            elements->push_back(i4); 
     1231        } 
     1232    } 
     1233    
    12981234    return geometry; 
    12991235} 
    13001236 
    1301 void View::setUpViewForPanoramicSphericalDisplay(double radius, double collar, unsigned int screenNum, osg::Image* intensityMap
     1237void View::setUpViewForPanoramicSphericalDisplay(double radius, double collar, unsigned int screenNum, osg::Image* intensityMap, const osg::Matrixd& projectorMatrix
    13021238{ 
    13031239    osg::notify(osg::INFO)<<"View::setUpViewForPanoramicSphericalDisplay(rad="<<radius<<", cllr="<<collar<<", sn="<<screenNum<<", im="<<intensityMap<<")"<<std::endl; 
     
    13871323    { 
    13881324        osg::Geode* geode = new osg::Geode(); 
    1389         geode->addDrawable(createParoramicSphericalDisplayDistortionMesh(osg::Vec3(0.0f,0.0f,0.0f), osg::Vec3(width,0.0f,0.0f), osg::Vec3(0.0f,height,0.0f), radius, collar, applyIntensityMapAsColours ? intensityMap : 0)); 
     1325        geode->addDrawable(createParoramicSphericalDisplayDistortionMesh(osg::Vec3(0.0f,0.0f,0.0f), osg::Vec3(width,0.0f,0.0f), osg::Vec3(0.0f,height,0.0f), radius, collar, applyIntensityMapAsColours ? intensityMap : 0, projectorMatrix)); 
    13901326 
    13911327        // new we need to add the texture to the mesh, we do so by creating a  
     
    14071343        camera->setGraphicsContext(gc.get()); 
    14081344        camera->setClearMask(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT ); 
    1409         camera->setClearColor( osg::Vec4(0.1,0.1,1.0,1.0) ); 
     1345        camera->setClearColor( osg::Vec4(0.0,0.0,0.0,1.0) ); 
    14101346        camera->setViewport(new osg::Viewport(0, 0, width, height)); 
    14111347        GLenum buffer = traits->doubleBuffer ? GL_BACK : GL_FRONT; 
     
    14141350        camera->setReferenceFrame(osg::Camera::ABSOLUTE_RF); 
    14151351        camera->setAllowEventFocus(false); 
    1416         //camera->setInheritanceMask(camera->getInheritanceMask() & ~osg::CullSettings::CLEAR_COLOR & ~osg::CullSettings::COMPUTE_NEAR_FAR_MODE); 
     1352        camera->setInheritanceMask(camera->getInheritanceMask() & ~osg::CullSettings::CLEAR_COLOR & ~osg::CullSettings::COMPUTE_NEAR_FAR_MODE); 
    14171353        //camera->setComputeNearFarMode(osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR); 
    14181354