diff --git a/Make/makedirdefs b/Make/makedirdefs
index 6c601810c..2756ea14c 100644
--- a/Make/makedirdefs
+++ b/Make/makedirdefs
@@ -128,6 +128,7 @@ EXAMPLE_DIRS = \
osgautotransform\
osgbillboard\
osgbluemarble\
+ osgdem\
osgcallback\
osgcameragroup\
osgclip\
diff --git a/doc/stereo.html b/doc/stereo.html
index 78d977bce..993932335 100644
--- a/doc/stereo.html
+++ b/doc/stereo.html
@@ -1,306 +1,228 @@
-
+
-
-
- Native stereo support
+
+
+ Native stereo support
-
-
+
+
-
-
-Native Support for Stereo
-The OSG has support for anaglyphic stereo (i.e. red/green or red/cyan glasses),
-quad buffered stereo (i.e. active stereo using shutter glasses, or passive
-stereo using polarized projectors & glasses) and horizontal and vertical
-split window stereo implementations. Almost all OSG applications have the
-potential for stereo support simply by setting the relevant environmental
-variables, or via command line arguments. Little or no code changes will
-be required, the support is handled transparently inside osgUtil::SceneView's
-handling of rendering. It is a simple as:
-
osgviewer --stereo cow.osg
-If the user is planning to use head tracked stereo, or a cave then it
-is currently recommend to set it up via a VR toolkit such as VRjuggler,
-in this case refer to the VR toolkits handling of stereo, and keep all
-the OSG's stereo specific environment variables (below) set to OFF, or
-set the values to off within own your own applications.
-
+
Native Support for Stereo
+The OSG has support for anaglyphic stereo (i.e. red/green or red/cyan
+glasses), quad buffered stereo (i.e. active stereo using shutter
+glasses, or passive stereo using polarized projectors & glasses)
+and horizontal and vertical split window stereo implementations. Almost
+all OSG applications have the potential for stereo support simply by
+setting the relevant environmental variables, or via command line
+arguments. Little or no code changes will be required, the support is
+handled transparently inside osgUtil::SceneView's handling of
+rendering. It is a simple as:
+ osgviewer --stereo cow.osg
+If the user is planning to use head tracked stereo, or a cave then
+it is currently recommend to set it up via a VR toolkit such as
+VRjuggler, in this case refer to the VR toolkits handling of stereo,
+and keep all the OSG's stereo specific environment variables (below)
+set to OFF, or set the values to off within own your own applications.
+
-
-The environmental variables of interest:
-
+ The environmental variables of interest:
-
-| OSG_STEREO |
-
-ON |
-
-Turn stereo on |
-
-
-
- |
-
-OFF |
-
-Turn stereo off (default). |
-
-
-
-| OSG_STEREO_MODE |
-
-ANAGLYPHIC |
-
-Use anaglyphic stereo when in stereo (default). |
-
-
-
- |
-
-QUAD_BUFFER |
-
-Use quad buffered stereo when in stereo. |
-
-
-
- |
-
-HORIZONTAL_SPLIT |
-
-Use horizontal split stereo mode when in stereo |
-
-
-
- |
-
-VERTICAL_SPLIT |
-
-Use vertical split stereo mode when in stereo |
-
-
-
-| OSG_SCREEN_DISTANCE |
-
-0.50 |
-
-Set the distance the viewer is from screen in metres (default shown) |
-
-
-
-| OSG_SCREEN_HEIGHT |
-
-0.26 |
-
-Set the height if image on the screen in metres (default shown) |
-
-
-
-| OSG_EYE_SEPARATION |
-
-0.06 |
-
-Set the eye separation - interoccular distance (default shown.) |
-
-
-
-| OSG_SPLIT_STEREO_HORIZONTAL_SEPARATION |
-
-42 |
-
-Set the number of pixels between the left and right viewports (default
-shown). |
-
-
-
-| OSG_SPLIT_STEREO_HORIZONTAL_EYE_MAPPING |
-
-LEFT_EYE_LEFT_VIEWPORT |
-
-Set the left eye to render to left viewport, right eye to right viewport
-(default). |
-
-
-
- |
-
-LEFT_EYE_RIGHT_VIEWPORT |
-
-Set the left eye to render to right viewport, right eye to left viewport. |
-
-
-
-| OSG_SPLIT_STEREO_VERTICAL_SEPARATION |
-
-42 |
-
-Set the number of pixels between the top and bottom viewports (default
-shown). |
-
-
-
-| OSG_SPLIT_STEREO_VERTICAL_EYE_MAPPING |
-
-LEFT_EYE_TOP_VIEWPORT |
-
-Set the left eye to render to top viewport, right eye to bottom viewport
-(default). |
-
-
-
- |
-
-LEFT_EYE_BOTTOM_VIEWPORT |
-
-Set the left eye to render to bottom viewport, right eye to top viewport. |
-
+
+
+ | OSG_STEREO |
+ ON |
+ Turn stereo on |
+
+
+
+ |
+ OFF |
+ Turn stereo off (default). |
+
+
+ | OSG_STEREO_MODE |
+ ANAGLYPHIC |
+ Use anaglyphic stereo when in stereo (default). |
+
+
+
+ |
+ QUAD_BUFFER |
+ Use quad buffered stereo when in stereo. |
+
+
+
+ |
+ HORIZONTAL_SPLIT |
+ Use horizontal split stereo mode when in stereo |
+
+
+
+ |
+ VERTICAL_SPLIT |
+ Use vertical split stereo mode when in stereo |
+
+
+ | OSG_SCREEN_DISTANCE |
+ 0.50 |
+ Set the distance the viewer is from screen in metres (default
+shown) |
+
+
+ | OSG_SCREEN_HEIGHT |
+ 0.26 |
+ Set the height if image on the screen in metres (default
+shown) |
+
+
+ | OSG_EYE_SEPARATION |
+ 0.06 |
+ Set the eye separation - interoccular distance (default
+shown.) |
+
+
+ | OSG_SPLIT_STEREO_HORIZONTAL_SEPARATION |
+ 42 |
+ Set the number of pixels between the left and right viewports
+(default shown). |
+
+
+ | OSG_SPLIT_STEREO_HORIZONTAL_EYE_MAPPING |
+ LEFT_EYE_LEFT_VIEWPORT |
+ Set the left eye to render to left viewport, right eye to
+right viewport (default). |
+
+
+
+ |
+ LEFT_EYE_RIGHT_VIEWPORT |
+ Set the left eye to render to right viewport, right eye to
+left viewport. |
+
+
+ | OSG_SPLIT_STEREO_VERTICAL_SEPARATION |
+ 42 |
+ Set the number of pixels between the top and bottom viewports
+(default shown). |
+
+
+ | OSG_SPLIT_STEREO_VERTICAL_EYE_MAPPING |
+ LEFT_EYE_TOP_VIEWPORT |
+ Set the left eye to render to top viewport, right eye to
+bottom viewport (default). |
+
+
+
+ |
+ LEFT_EYE_BOTTOM_VIEWPORT |
+ Set the left eye to render to bottom viewport, right eye to
+top viewport. |
+
+
-
-
-Command line arguments can be used to override these settings:
-
+ Command line arguments can be used to override these settings:
-
-| -stereo |
-
- |
-
-Switch on stereo. |
-
-
-
-| -stereo |
-
-ON |
-
-Switch on stereo. |
-
-
-
- |
-
-OFF |
-
-Switch off stereo. |
-
-
-
- |
-
-ANAGLYPHIC |
-
-Switch on ANAGLYPHIC stereo. |
-
-
-
- |
-
-QUAD_BUFFER |
-
-Switch on QUAD_BUFFER stereo. |
-
-
-
- |
-
-VERTICAL_SPLIT |
-
-Switch on VERTICAL_SPLIT stereo. |
-
-
-
- |
-
-HORIZONTAL_SPLIT |
-
-Switch on VERTICAL_SPLIT stereo. |
-
+
+
+ | -stereo |
+
+ |
+ Switch on stereo. |
+
+
+ | -stereo |
+ ON |
+ Switch on stereo. |
+
+
+
+ |
+ OFF |
+ Switch off stereo. |
+
+
+
+ |
+ ANAGLYPHIC |
+ Switch on ANAGLYPHIC stereo. |
+
+
+
+ |
+ QUAD_BUFFER |
+ Switch on QUAD_BUFFER stereo. |
+
+
+
+ |
+ VERTICAL_SPLIT |
+ Switch on VERTICAL_SPLIT stereo. |
+
+
+
+ |
+ HORIZONTAL_SPLIT |
+ Switch on VERTICAL_SPLIT stereo. |
+
+
-
-
-Examples:
-To invoke stereo from the comandline:
-
osgviewer -stereo cow.osg
-To invoke quad buffered stereo from the commandline:
-
osgviewer -stereo QUAD_BUFFER cow.osg
-
To force all apps to start up in quad buffered stereo (if system supports
-it)
-
export OSG_STEREO=ON
-
export OSG_STEREO_MODE=QUAD_BUFFER
-
osgviewer cow.osg
+
Examples:
+To invoke stereo from the comandline:
+ osgviewer -stereo cow.osg
+To invoke quad buffered stereo from the commandline:
+ osgviewer -stereo QUAD_BUFFER cow.osg
+To force all apps to start up in quad buffered stereo (if system
+supports it)
+ export OSG_STEREO=ON
+ export OSG_STEREO_MODE=QUAD_BUFFER
+ osgviewer cow.osg
To set quad buffered stereo to the default, but use the commandline
-to switch stereo on:
-
export OSG_STEREO=OFF
-
export OSG_STEREO_MODE=QUAD_BUFFER
-
osgviewer -stereo cow.osg
-
+to switch stereo on:
+ export OSG_STEREO=OFF
+ export OSG_STEREO_MODE=QUAD_BUFFER
+ osgviewer -stereo cow.osg
+
-
-Size matters:
+ Size matters:
For appropriate depth perception the stereo code creates separate left
and eye views, both the frustum and modelview are shifted to account for
the separate eye views. To achieve the right amount of adjustment
the OSG requires the users eye separation, the distance from the eyes to
-the screen and the height of the screen. The OSG will use the defaults
-of 0.05m,0.5m and 0.26m respectively which are assumed to be reasonable
-defaults for most users workstation configurations, note the OSG_SCREEN_HEIGHT
-is the image height rather than total size of your monitor/display surface.
-For the best stereo effects please measure these values and set them up
-via the environmental variables. Once set the views you get should
-give improved depth perception. A good way of measuring how well
-you are configured for your display is to fly away from objects (using
-the FlightManipulator for instance, but not the TrackballManipulator, see
+the screen and the height of the screen. The OSG will use the
+defaults of 0.05m,0.5m and 0.26m respectively which are assumed to be
+reasonable defaults for most users workstation configurations, note the
+OSG_SCREEN_HEIGHT is the image height rather than total size of your
+monitor/display surface. For the best stereo effects please
+measure these values and set them up via the environmental
+variables. Once set the views you get should give improved depth
+perception. A good way of measuring how well you are configured
+for your display is to fly away from objects (using the
+FlightManipulator for instance, but not the TrackballManipulator, see
below) so that they go of toward infinity. As they move away the offset
between the two images should tend towards your eye separation, if you
-achieve this then the object will be perceived as at infinity.
+achieve this then the object will be perceived as at infinity.
-
-
-Camera Manipulator Modes:
-There are three osgUtil::CameraManipulator's which come with osgUtil, which
-operate as a Trackball, Drive and Flight modes of interaction (see osgviewer.html
-for how to invoke them in the scene graph viewer). The osgUtil::Trackball
-Manipulator automatically scales the fusion distance to that which will
-fusion on center point of rotation - this will appear at the middle of
-the monitor at the monitors depth. Whereas, the osgUtil::DriveManipualtor,
-osgUtil::FlightManipulator scale the fusion distance to the distance the
-viewer is from the screen, the results in a perception that the virtual
-world is scaled to physical world, this is clearly better for simulators
-and alike. You can control the fusion of the image in these two modes via
-the osg::Camera::setFusionDistanceMode(FusionDistanceMode mode) where mode
-can be osg::Camera::PROPORTIONAL_TO_LOOK_DISTANCE (used by Trackball) or
-osg::Camera::PROPORTIONAL_TO_SCREEN_DISTANCE (used by Drive and Flight),
-and osg::Camera::setFusionDistanceRatio(float). See include/osg/Camera
-for further details, and the camera manipulators for implementation details.
-The fusion distance ratio defaults to 1.0 but can be biased to move objects
-out or into screen, they will also appear to get smaller and larger respectively.
-The camera manipulators allow the user to alter this value at runtime via
-the '+' and '-' keys.
diff --git a/examples/osgbluemarble/osgbluemarble.cpp b/examples/osgbluemarble/osgbluemarble.cpp
index 7616d47f3..4cfe88c2b 100644
--- a/examples/osgbluemarble/osgbluemarble.cpp
+++ b/examples/osgbluemarble/osgbluemarble.cpp
@@ -69,10 +69,14 @@ osg::Node* createTile(const std::string& filename, bool leftHemisphere, double x
options->_destinationImageWindowMode = osgDB::ImageOptions::PIXEL_WINDOW;
options->_destinationPixelWindow.set(0,0,256,256);
+ osgDB::ImageOptions::TexCoordRange* texCoordRange = 0;
+
osgDB::Registry::instance()->setOptions(options.get());
osg::Image* image = osgDB::readImageFile(filename.c_str());
if (image)
{
+ texCoordRange = dynamic_cast(image->getUserData());
+
osg::Texture2D* texture = new osg::Texture2D;
texture->setImage(image);
texture->setWrap(osg::Texture::WRAP_S,osg::Texture::CLAMP);
@@ -82,16 +86,18 @@ osg::Node* createTile(const std::string& filename, bool leftHemisphere, double x
texture->setMaxAnisotropy(8);
stateset->setTextureAttributeAndModes(0,texture,osg::StateAttribute::ON);
- texture->setInternalFormatMode(osg::Texture::USE_S3TC_DXT3_COMPRESSION);
-
- osg::ref_ptr state = new osg::State;
- texture->apply(*state);
-
- image->readImageFromCurrentTexture();
-
- texture->setInternalFormatMode(osg::Texture::USE_IMAGE_DATA_FORMAT);
-
- std::cout<<"glGetError()=="<setInternalFormatMode(osg::Texture::USE_S3TC_DXT3_COMPRESSION);
+
+ osg::ref_ptr state = new osg::State;
+ texture->apply(*state);
+
+ image->readImageFromCurrentTexture();
+
+ texture->setInternalFormatMode(osg::Texture::USE_IMAGE_DATA_FORMAT);
+ }
}
@@ -114,9 +120,24 @@ osg::Node* createTile(const std::string& filename, bool leftHemisphere, double x
color[0].set(255,255,255,255);
+
+ osg::Vec2 tex_orig(0.0f,0.0f);
+
float rowTexDelta = 1.0f/(float)(numRows-1);
float columnTexDelta = 1.0f/(float)(numColumns-1);
+ if (texCoordRange)
+ {
+ tex_orig.set(texCoordRange->_x,texCoordRange->_y);
+ rowTexDelta = texCoordRange->_h/(float)(numRows-1);
+ columnTexDelta = texCoordRange->_w/(float)(numColumns-1);
+
+ std::cout<<"setting tex values to use texCoordRange"<setApplicationName(arguments.getApplicationName());
arguments.getApplicationUsage()->setDescription(arguments.getApplicationName()+" is the standard OpenSceneGraph example which loads and visualises 3d models.");
arguments.getApplicationUsage()->setCommandLineUsage(arguments.getApplicationName()+" [options] filename ...");
+ arguments.getApplicationUsage()->addCommandLineOption("-i ","Specify the input file to process");
+ arguments.getApplicationUsage()->addCommandLineOption("-o ","Specify the output master file to generate");
+ arguments.getApplicationUsage()->addCommandLineOption("-l ","Specify the number of PagedLOD levels to generate");
arguments.getApplicationUsage()->addCommandLineOption("-h or --help","Display this information");
+ std::string inputFile;
+ while (arguments.read("-i",inputFile)) {}
+
+ std::string basename("output.ive");
+ while (arguments.read("-o",basename)) {}
+
+ float numLevels;
+ while (arguments.read("-l",numLevels)) {}
// if user request help write it out to cout.
if (arguments.read("-h") || arguments.read("--help"))
@@ -365,7 +399,6 @@ int main( int argc, char **argv )
std::string left_hemisphere("land_shallow_topo_west.tif");
std::string right_hemisphere("land_shallow_topo_east.tif");
- std::string basename("BlueMarble/bluemarble.ive");
// create a graphics context to allow us to use OpenGL to compress textures.
GraphicsContext gfx;
diff --git a/examples/osgdem/GNUmakefile b/examples/osgdem/GNUmakefile
new file mode 100644
index 000000000..a6ae3e106
--- /dev/null
+++ b/examples/osgdem/GNUmakefile
@@ -0,0 +1,18 @@
+TOPDIR = ../..
+include $(TOPDIR)/Make/makedefs
+
+CXXFILES =\
+ osgdem.cpp\
+
+LIBS += -losgProducer -lProducer -losgFX -losgText -losgGA -losgDB -losgUtil -losg $(GL_LIBS) $(X_LIBS) $(OTHER_LIBS)
+
+INSTFILES = \
+ $(CXXFILES)\
+ GNUmakefile.inst=GNUmakefile
+
+EXEC = osgdem
+
+INC += $(X_INC)
+
+include $(TOPDIR)/Make/makerules
+
diff --git a/examples/osgdem/GNUmakefile.inst b/examples/osgdem/GNUmakefile.inst
new file mode 100644
index 000000000..d27395804
--- /dev/null
+++ b/examples/osgdem/GNUmakefile.inst
@@ -0,0 +1,13 @@
+TOPDIR = ../..
+include $(TOPDIR)/Make/makedefs
+
+CXXFILES =\
+ osgdem.cpp\
+
+LIBS += -losgProducer -lProducer -losgDB -losgText -losgUtil -losg $(GL_LIBS) $(X_LIBS) $(OTHER_LIBS)
+
+EXEC = osgdem
+
+INC += $(X_INC)
+
+include $(TOPDIR)/Make/makerules
diff --git a/examples/osgdem/osgdem.cpp b/examples/osgdem/osgdem.cpp
new file mode 100644
index 000000000..bee5453cb
--- /dev/null
+++ b/examples/osgdem/osgdem.cpp
@@ -0,0 +1,883 @@
+/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2003 Robert Osfield
+ *
+ * This application is open source and may be redistributed and/or modified
+ * freely and without restriction, both in commericial and non commericial applications,
+ * as long as this copyright notice is maintained.
+ *
+ * This application is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+*/
+
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+
+#include
+
+#include
+
+
+float VERTICAL_SIZE = 0.0005;
+
+class GraphicsContext {
+ public:
+ GraphicsContext()
+ {
+ rs = new Producer::RenderSurface;
+ rs->setWindowRectangle(0,0,1,1);
+ rs->useBorder(false);
+ rs->useConfigEventThread(false);
+ rs->realize();
+ std::cout<<"Realized window"< rs;
+};
+
+osg::Image* createNormalMap(osg::HeightField* grid)
+{
+ osg::Image* image = new osg::Image;
+ image->allocateImage(grid->getNumColumns(),grid->getNumRows(),1,GL_RGB,GL_BYTE);
+
+ char* ptr = (char*) image->data();
+ for(unsigned int r=0;rgetNumRows();++r)
+ {
+ for(unsigned int c=0;cgetNumColumns();++c)
+ {
+ osg::Vec3 normal = grid->getNormal(c,r);
+ (*ptr++) = (char)((normal.x()+1.0)*0.5*255);
+ (*ptr++) = (char)((normal.y()+1.0)*0.5*255);
+ (*ptr++) = (char)((normal.z()+1.0)*0.5*255);
+ }
+ }
+
+ return image;
+
+}
+
+
+template< typename T>
+osg::HeightField* _createHeightField(osg::Image* image, float zScale)
+{
+ unsigned char* ptr = image->data();
+ unsigned int rowSizeInBytes = image->getRowSizeInBytes();
+ unsigned int pixelSizeInBits = image->getPixelSizeInBits();
+ unsigned int pixelSizeInBytes = pixelSizeInBits/8;
+
+ unsigned int numColumns = image->s();
+ unsigned int numRows = image->t();
+
+ osg::HeightField* grid = new osg::HeightField;
+ grid->allocateGrid(numColumns,numRows);
+
+ for(unsigned int r=0;rsetHeight(c,r,zScale*(float)(*((T*)ptr_in_row)));
+ ptr_in_row += pixelSizeInBytes;
+ }
+ ptr += rowSizeInBytes;
+ }
+
+ return grid;
+}
+
+osg::HeightField* createHeightField(osg::Image* image, const osg::Vec3& origin, const osg::Vec3& size)
+{
+ osg::HeightField* grid = new osg::HeightField;
+ switch(image->getDataType())
+ {
+ case(GL_UNSIGNED_BYTE): grid = _createHeightField(image,size.z()); break;
+ case(GL_BYTE): grid = _createHeightField(image,size.z()); break;
+ case(GL_UNSIGNED_SHORT): grid = _createHeightField(image,size.z()); break;
+ case(GL_SHORT): grid = _createHeightField(image,size.z()); break;
+ case(GL_UNSIGNED_INT): grid = _createHeightField(image,size.z()); break;
+ case(GL_INT): grid = _createHeightField(image,size.z()); break;
+ case(GL_FLOAT): grid = _createHeightField(image,size.z()); break;
+ }
+ grid->setOrigin(origin);
+ grid->setXInterval(size.x()/(float)(image->s()-1));
+ grid->setYInterval(size.y()/(float)(image->s()-1));
+
+ return grid;
+
+}
+
+osg::Node* createTile(osg::HeightField* grid,
+ unsigned int columnBegin, unsigned int columnEnd,
+ unsigned int rowBegin, unsigned int rowEnd,
+ float xTexCoordBegin, float xTexCoordEnd,
+ float yTexCoordBegin, float yTexCoordEnd,
+ unsigned int targetNumPolygonsPerTile)
+{
+
+
+ int numPolys = (columnEnd-columnBegin)*(rowEnd-rowBegin)*2;
+ int numColumns, numRows;
+ bool oneToOneMapping = numPolys<=targetNumPolygonsPerTile;
+ if (oneToOneMapping)
+ {
+ numColumns = (columnEnd-columnBegin)+1;
+ numRows = (rowEnd-rowBegin)+1;
+ }
+ else
+ {
+ numColumns = (int)sqrtf((float)targetNumPolygonsPerTile/2.0) + 1;
+ numRows = targetNumPolygonsPerTile/(2*(numColumns)-1) + 1;
+ }
+
+ bool createSkirt = true;
+
+
+ int numVerticesInBody = numColumns*numRows;
+ int numVerticesInSkirt = createSkirt ? numColumns*2 + numRows*2 - 4 : 0;
+ int numVertices = numVerticesInBody+numVerticesInSkirt;
+
+ osg::Vec3 skirtVector(0.0f,0.0f,-0.003f);
+
+
+ osg::Geometry* geometry = new osg::Geometry;
+
+ osg::Vec3Array& v = *(new osg::Vec3Array(numVertices));
+ osg::Vec2Array& t = *(new osg::Vec2Array(numVertices));
+ osg::UByte4Array& color = *(new osg::UByte4Array(1));
+
+ color[0].set(255,255,255,255);
+
+
+ int vi=0;
+ int r,c;
+ if (!oneToOneMapping)
+ {
+ for(r=0;rgetOrigin()+osg::Vec3(grid->getXInterval()*(float)col,
+ grid->getYInterval()*(float)row,
+ grid->getHeight(col,row));
+ t[vi].x() = xTexCoordBegin + (xTexCoordEnd-xTexCoordBegin)*(float)(col-columnBegin)/(float)(columnEnd-columnBegin);
+ t[vi].y() = yTexCoordBegin + (yTexCoordEnd-yTexCoordBegin)*(float)(row-rowBegin)/(float)(rowEnd-rowBegin);
+
+ ++vi;
+ }
+ }
+ }
+ else
+ {
+ for(r=rowBegin;r<=rowEnd;++r)
+ {
+ for(c=columnBegin;c<=columnEnd;++c)
+ {
+ v[vi] = grid->getOrigin()+osg::Vec3(grid->getXInterval()*c,
+ grid->getYInterval()*r,
+ grid->getHeight(c,r));
+ t[vi].x() = xTexCoordBegin + (xTexCoordEnd-xTexCoordBegin)*(float)(c-columnBegin)/(float)(columnEnd-columnBegin);
+ t[vi].y() = yTexCoordBegin + (yTexCoordEnd-yTexCoordBegin)*(float)(r-rowBegin)/(float)(rowEnd-rowBegin);
+
+ ++vi;
+ }
+ }
+ }
+
+
+
+ geometry->setVertexArray(&v);
+ geometry->setColorArray(&color);
+ geometry->setColorBinding(osg::Geometry::BIND_OVERALL);
+ geometry->setTexCoordArray(0,&t);
+ geometry->setTexCoordArray(1,&t);
+
+ bool pickOutDiagonals = true;
+ if (pickOutDiagonals)
+ {
+ osg::DrawElementsUShort& drawElements = *(new osg::DrawElementsUShort(GL_TRIANGLES,2*3*(numColumns-1)*(numRows-1)));
+ geometry->addPrimitiveSet(&drawElements);
+ int ei=0;
+ for(r=0;raddPrimitiveSet(&drawElements);
+ int ei=0;
+ for(c=0;c0)
+ {
+ osg::DrawElementsUShort& skirtDrawElements = *(new osg::DrawElementsUShort(GL_QUAD_STRIP,2*numVerticesInSkirt+2));
+ geometry->addPrimitiveSet(&skirtDrawElements);
+ int ei=0;
+ int firstSkirtVertexIndex = vi;
+ // create bottom skirt vertices
+ r=0;
+ for(c=0;c0;--c)
+ {
+ skirtDrawElements[ei++] = (r)*numColumns+c;
+ skirtDrawElements[ei++] = vi;
+ v[vi] = v[(r)*numColumns+c]+skirtVector;
+ t[vi++] = t[(r)*numColumns+c];
+ }
+ // create left skirt vertices
+ c=0;
+ for(r=numRows-1;r>0;--r)
+ {
+ skirtDrawElements[ei++] = (r)*numColumns+c;
+ skirtDrawElements[ei++] = vi;
+ v[vi] = v[(r)*numColumns+c]+skirtVector;
+ t[vi++] = t[(r)*numColumns+c];
+ }
+ skirtDrawElements[ei++] = 0;
+ skirtDrawElements[ei++] = firstSkirtVertexIndex;
+ }
+
+
+
+
+ osgUtil::TriStripVisitor tsv;
+ tsv.stripify(*geometry);
+//
+// osgUtil::SmoothingVisitor sv;
+// sv.smooth(*geometry);
+
+ osg::Vec4Array& tsgTangentArray = *(new osg::Vec4Array(1));
+ osg::Vec4Array& tsgBinormalArray = *(new osg::Vec4Array(1));
+ osg::Vec4Array& tsgNormalArray = *(new osg::Vec4Array(1));
+ tsgTangentArray[0].set(1.0f,0.0f,0.0f,0.0f);
+ tsgBinormalArray[0].set(0.0f,1.0f,0.0f,0.0f);
+ tsgNormalArray[0].set(0.0f,0.0f,1.0f,0.0f);
+ geometry->setVertexAttribData(6, osg::Geometry::ArrayData(&tsgTangentArray, osg::Geometry::BIND_OVERALL,GL_FALSE));
+ geometry->setVertexAttribData(7, osg::Geometry::ArrayData(&tsgBinormalArray, osg::Geometry::BIND_OVERALL,GL_FALSE));
+ geometry->setVertexAttribData(15, osg::Geometry::ArrayData(&tsgNormalArray, osg::Geometry::BIND_OVERALL,GL_FALSE));
+
+ //geometry->setUseVertexBufferObjects(true);
+
+ geometry->setUseDisplayList(false);
+ geometry->setUseVertexBufferObjects(false);
+
+ osg::Geode* geode = new osg::Geode;
+ geode->addDrawable(geometry);
+
+ return geode;
+
+}
+
+
+osg::Node* createQuadTree(osg::HeightField* grid,
+ unsigned int columnBegin, unsigned int columnEnd,
+ unsigned int rowBegin, unsigned int rowEnd,
+ float xTexCoordBegin, float xTexCoordEnd,
+ float yTexCoordBegin, float yTexCoordEnd,
+ unsigned int targetNumPolygonsPerTile)
+{
+ unsigned int numPolys = (columnEnd-columnBegin)*(rowEnd-rowBegin)*2;
+
+
+ std::cout << "createQuadTree "<getBound().radius()*4.0f;
+ float max_visible_distance = 1e7;
+
+ unsigned int columnCenter = (columnBegin + columnEnd)/2;
+ unsigned int rowCenter = (rowBegin + rowEnd)/2;
+ float xTexCoordCenter = xTexCoordBegin+
+ (xTexCoordEnd-xTexCoordBegin)*((float)(columnCenter-columnBegin)/(float)(columnEnd-columnBegin));
+ float yTexCoordCenter = yTexCoordBegin+
+ (yTexCoordEnd-yTexCoordBegin)*((float)(rowCenter-rowBegin)/(float)(rowEnd-rowBegin));
+
+ osg::Group* group = new osg::Group;
+ group->addChild(createQuadTree(grid,
+ columnBegin, columnCenter,
+ rowBegin, rowCenter,
+ xTexCoordBegin, xTexCoordCenter,
+ yTexCoordBegin, yTexCoordCenter,
+ targetNumPolygonsPerTile));
+
+ group->addChild(createQuadTree(grid,
+ columnCenter, columnEnd,
+ rowBegin, rowCenter,
+ xTexCoordCenter, xTexCoordEnd,
+ yTexCoordBegin, yTexCoordCenter,
+ targetNumPolygonsPerTile));
+
+ group->addChild(createQuadTree(grid,
+ columnCenter, columnEnd,
+ rowCenter, rowEnd,
+ xTexCoordCenter, xTexCoordEnd,
+ yTexCoordCenter, yTexCoordEnd,
+ targetNumPolygonsPerTile));
+
+ group->addChild(createQuadTree(grid,
+ columnBegin, columnCenter,
+ rowCenter, rowEnd,
+ xTexCoordBegin, xTexCoordCenter,
+ yTexCoordCenter, yTexCoordEnd,
+ targetNumPolygonsPerTile));
+
+ osg::LOD* lod = new osg::LOD;
+ lod->addChild(tile,cut_off_distance,max_visible_distance);
+ lod->addChild(group,0.0f,cut_off_distance);
+
+ return lod;
+
+ }
+}
+
+
+template< typename T>
+void populate_z(osg::Image* image, const osg::Vec3& zAxis,osg::Vec3Array& v)
+{
+ unsigned char* ptr = image->data();
+ unsigned int rowSizeInBytes = image->getRowSizeInBytes();
+ unsigned int pixelSizeInBits = image->getPixelSizeInBits();
+ unsigned int pixelSizeInBytes = pixelSizeInBits/8;
+
+ unsigned int numColumns = image->s();
+ unsigned int numRows = image->t();
+ for(unsigned int r=0,vi=0;r(image->getUserData());
+
+ unsigned int numColumns = image->s();
+ unsigned int numRows = image->t();
+ unsigned int r;
+ unsigned int c;
+
+ osg::Geode* geode = new osg::Geode;
+
+ bool useGeometry = true;
+ if (useGeometry)
+ {
+
+ osg::Geometry* geometry = new osg::Geometry;
+
+ osg::Vec3Array& v = *(new osg::Vec3Array(numColumns*numRows));
+ //osg::Vec3Array& n = *(new osg::Vec3Array(numColumns*numRows));
+ osg::Vec2Array& t = *(new osg::Vec2Array(numColumns*numRows));
+ osg::UByte4Array& color = *(new osg::UByte4Array(1));
+
+ color[0].set(255,255,255,255);
+
+
+#if 0
+ osg::Vec2 tex_orig(0.0f,0.0f);
+
+ float rowTexDelta = 1.0f/(float)(numRows-1);
+ float columnTexDelta = 1.0f/(float)(numColumns-1);
+#else
+
+ osg::Vec2 tex_orig(origin.x(),origin.y());
+
+ float columnTexDelta = xAxis.length()/(float)(numColumns-1);
+ float rowTexDelta = yAxis.length()/(float)(numRows-1);
+#endif
+
+ if (texCoordRange)
+ {
+// tex_orig.set(texCoordRange->_x,texCoordRange->_y);
+// rowTexDelta = texCoordRange->_h/(float)(numRows-1);
+// columnTexDelta = texCoordRange->_w/(float)(numColumns-1);
+
+ std::cout<<"setting tex values to use texCoordRange"<getDataType())
+ {
+ case(GL_UNSIGNED_BYTE): populate_z(image,zAxis,v); break;
+ case(GL_BYTE): populate_z(image,zAxis,v); break;
+ case(GL_UNSIGNED_SHORT): populate_z(image,zAxis,v); break;
+ case(GL_SHORT): populate_z(image,zAxis,v); break;
+ case(GL_UNSIGNED_INT): populate_z(image,zAxis,v); break;
+ case(GL_INT): populate_z(image,zAxis,v); break;
+ case(GL_FLOAT): populate_z(image,zAxis,v); break;
+ }
+
+ geometry->setVertexArray(&v);
+ //geometry->setNormalArray(&n);
+ //geometry->setNormalBinding(osg::Geometry::BIND_PER_VERTEX);
+ geometry->setColorArray(&color);
+ geometry->setColorBinding(osg::Geometry::BIND_OVERALL);
+ geometry->setTexCoordArray(0,&t);
+ geometry->setTexCoordArray(1,&t);
+
+
+ for(r=0;raddPrimitiveSet(&drawElements);
+ int ei=0;
+ for(c=0;csetVertexAttribData(6, osg::Geometry::ArrayData(&tsgTangentArray, osg::Geometry::BIND_OVERALL,GL_FALSE));
+ geometry->setVertexAttribData(7, osg::Geometry::ArrayData(&tsgBinormalArray, osg::Geometry::BIND_OVERALL,GL_FALSE));
+ geometry->setVertexAttribData(15, osg::Geometry::ArrayData(&tsgNormalArray, osg::Geometry::BIND_OVERALL,GL_FALSE));
+
+ //geometry->setUseVertexBufferObjects(true);
+
+ geometry->setUseDisplayList(false);
+ geometry->setUseVertexBufferObjects(false);
+
+ geode->addDrawable(geometry);
+ }
+ else
+ {
+
+ osg::HeightField* grid = createHeightField(image,origin,osg::Vec3(xAxis.length(),yAxis.length(),zAxis.length()));
+
+ geode->addDrawable(new osg::ShapeDrawable(grid));
+ }
+
+ return geode;
+}
+
+osg::Node* computeGeometry(osg::Image* image, const osg::Vec3& origin, const osg::Vec3& size)
+{
+ return computeGeometry(image,origin,osg::Vec3(size.x(),0.0f,0.0f),osg::Vec3(0.0f,size.y(),0.0f),osg::Vec3(0.0f,0.0f,size.z()));
+}
+
+osg::Node* createTile(const std::string& filename, double x, double y, double w,double h)
+{
+
+ osg::ref_ptr options = new osgDB::ImageOptions;
+ options->_sourceImageWindowMode = osgDB::ImageOptions::RATIO_WINDOW;
+ options->_sourceRatioWindow.set(x,1-(y+h),w,h);
+
+ options->_destinationImageWindowMode = osgDB::ImageOptions::PIXEL_WINDOW;
+ options->_destinationPixelWindow.set(0,0,20,20);
+
+ osgDB::Registry::instance()->setOptions(options.get());
+ osg::Image* image = osgDB::readImageFile(filename.c_str());
+ if (image)
+ {
+
+ return computeGeometry(image,osg::Vec3(x,y,0.0),osg::Vec3(w,h,VERTICAL_SIZE));
+
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+osg::Node* createTileAndRecurse(const std::string& filename, const std::string& basename, const std::string& extension, unsigned int noTilesX, unsigned int noTilesY, double x, double y, double w,double h, unsigned int numLevelsLeft)
+{
+
+ osg::Group* group = new osg::Group;
+
+ double dx = w / (double) noTilesX;
+ double dy = h / (double) noTilesY;
+
+
+ if (numLevelsLeft>0)
+ {
+
+ float cut_off_distance = 4.0f*dy;
+ float max_visible_distance = 1e7;
+
+ // create current layer, and write to disk.
+ unsigned int numTiles = 0;
+ double lx = x;
+ for(unsigned i=0;i node = createTileAndRecurse(filename,lbasename,extension,2,2,lx,ly,dx,dy,numLevelsLeft-1);
+ osgDB::writeNodeFile(*node, lbasename+extension);
+ }
+
+ // create PagedLOD for tile.
+ osg::PagedLOD* pagedlod = new osg::PagedLOD;
+ osg::Node* tile = createTile(filename,lx,ly,dx,dy);
+ pagedlod->addChild(tile, cut_off_distance,max_visible_distance);
+ pagedlod->setRange(1,0.0f,cut_off_distance);
+ pagedlod->setFileName(1,lbasename+extension);
+ pagedlod->setCenter(tile->getBound().center());
+
+ group->addChild(pagedlod);
+
+ // increment number of tiles.
+ ++numTiles;
+ }
+
+ }
+
+ }
+ else
+ {
+ double lx = x;
+ for(unsigned i=0;iaddChild(createTile(filename,lx,ly,dx,dy));
+ }
+ }
+ }
+
+
+ return group;
+
+}
+
+bool createWorld(const std::string& inputFile, const std::string& baseName, unsigned int numLevels)
+{
+
+ osgDB::ReaderWriter* readerWriter = osgDB::Registry::instance()->getReaderWriterForExtension("gdal");
+ if (!readerWriter)
+ {
+ std::cout<<"Error: GDAL plugin not available, cannot preceed with database creation"< scene;
+
+ // = createTileAndRecurse(inputFile, base, /*extension*/".ive", 2,2, 0.0, 0.0, 1.0, 1.0, numLevels);
+
+ // generate normal map
+ osg::Image* normalMap = 0;
+ {
+ osg::ref_ptr options = new osgDB::ImageOptions;
+ options->_sourceImageWindowMode = osgDB::ImageOptions::RATIO_WINDOW;
+ options->_sourceRatioWindow.set(0,0,1,1);
+
+ options->_destinationImageWindowMode = osgDB::ImageOptions::PIXEL_WINDOW;
+ options->_destinationPixelWindow.set(0,0,512,512);
+
+ osgDB::Registry::instance()->setOptions(options.get());
+ osg::Image* image = osgDB::readImageFile(inputFile.c_str());
+ if (image)
+ {
+ osg::HeightField* grid = createHeightField(image,osg::Vec3(0.0f,0.0f,0.0f),osg::Vec3(1.0,1.0,VERTICAL_SIZE));
+ normalMap = createNormalMap(grid);
+ normalMap->setFileName("normalmap.rgb");
+ osgDB::writeImageFile(*normalMap,"normalmap.rgb");
+
+
+ scene = createQuadTree(grid,
+ 0, grid->getNumColumns()-1,
+ 0, grid->getNumRows()-1,
+ 0.0f, 1.0f,
+ 0.0f, 1.0f,
+ 2000);
+
+ }
+
+
+ }
+
+ // generate diffuse map
+ osg::Image* diffuseMap = 0;
+// {
+// osg::ref_ptr options = new osgDB::ImageOptions;
+// options->_sourceImageWindowMode = osgDB::ImageOptions::RATIO_WINDOW;
+// options->_sourceRatioWindow.set(0,0,1,1);
+//
+// options->_destinationImageWindowMode = osgDB::ImageOptions::PIXEL_WINDOW;
+// options->_destinationPixelWindow.set(0,0,2048,2048);
+//
+// osgDB::Registry::instance()->setOptions(options.get());
+// diffuseMap = osgDB::readImageFile(inputFile.c_str());
+// if (diffuseMap)
+// {
+// diffuseMap->setFileName("diffuse.rgb");
+// osgDB::writeImageFile(*diffuseMap,"diffuse.rgb");
+// }
+//
+// }
+
+ diffuseMap = osgDB::readImageFile("LlanoTex.jpg");
+
+
+ osg::Texture2D* diffuseMapTexture = new osg::Texture2D(diffuseMap);
+ osg::Texture2D* normalMapTexture = new osg::Texture2D(normalMap);
+
+ // create osgFX::BumpingMapping
+ osg::ref_ptr bumpMap = new osgFX::BumpMapping;
+ bumpMap->setLightNumber(0);
+ bumpMap->setNormalMapTextureUnit(0);
+ bumpMap->setDiffuseTextureUnit(1);
+ bumpMap->setOverrideDiffuseTexture(diffuseMapTexture);
+ bumpMap->setOverrideNormalMapTexture(normalMapTexture);
+
+ bumpMap->addChild(scene.get());
+
+#ifdef USE_PREPARE
+ bumpMap->prepareChildren();
+#endif
+
+ osg::ref_ptr group = new osg::Group;
+
+
+ group->addChild(bumpMap.get());
+
+ osg::StateSet* stateset = group->getOrCreateStateSet();
+ stateset->setMode(GL_CULL_FACE,osg::StateAttribute::ON);
+
+ osgDB::writeNodeFile(*group, baseName);
+
+ }
+ else
+ {
+
+ osg::ref_ptr group = new osg::Group;
+ group->addChild(createTileAndRecurse(inputFile, base, extension, 2,2, 0.0, 0.0, 1.0, 1.0, numLevels));
+
+ osg::StateSet* stateset = group->getOrCreateStateSet();
+ stateset->setMode(GL_CULL_FACE,osg::StateAttribute::ON);
+
+ osgDB::writeNodeFile(*group, baseName);
+
+ }
+
+ osg::Timer_t end_tick = timer.tick();
+ std::cout << "Time to create world "<setApplicationName(arguments.getApplicationName());
+ arguments.getApplicationUsage()->setDescription(arguments.getApplicationName()+" is the standard OpenSceneGraph example which loads and visualises 3d models.");
+ arguments.getApplicationUsage()->setCommandLineUsage(arguments.getApplicationName()+" [options] filename ...");
+ arguments.getApplicationUsage()->addCommandLineOption("-i ","Specify the input file to process");
+ arguments.getApplicationUsage()->addCommandLineOption("-o ","Specify the output master file to generate");
+ arguments.getApplicationUsage()->addCommandLineOption("-l ","Specify the number of PagedLOD levels to generate");
+ arguments.getApplicationUsage()->addCommandLineOption("-h or --help","Display this information");
+
+ std::string inputFile;
+ while (arguments.read("-i",inputFile)) {}
+
+ std::string basename("output.ive");
+ while (arguments.read("-o",basename)) {}
+
+ float numLevels;
+ while (arguments.read("-l",numLevels)) {}
+
+ while (arguments.read("-v",VERTICAL_SIZE)) {}
+
+ // if user request help write it out to cout.
+ if (arguments.read("-h") || arguments.read("--help"))
+ {
+ arguments.getApplicationUsage()->write(std::cout);
+ return 1;
+ }
+
+ // any option left unread are converted into errors to write out later.
+ arguments.reportRemainingOptionsAsUnrecognized();
+
+ // report any errors if they have occured when parsing the program aguments.
+ if (arguments.errors())
+ {
+ arguments.writeErrorMessages(std::cout);
+ return 1;
+ }
+
+// if (arguments.argc()<=1)
+// {
+// arguments.getApplicationUsage()->write(std::cout,osg::ApplicationUsage::COMMAND_LINE_OPTION);
+// return 1;
+// }
+
+
+
+ // create a graphics context to allow us to use OpenGL to compress textures.
+ GraphicsContext gfx;
+
+ createWorld(inputFile,basename,(unsigned int)numLevels);
+
+ return 0;
+}
+
diff --git a/examples/osgforest/osgforest.cpp b/examples/osgforest/osgforest.cpp
index 2369d5869..79ed5c199 100644
--- a/examples/osgforest/osgforest.cpp
+++ b/examples/osgforest/osgforest.cpp
@@ -384,7 +384,7 @@ osg::Geode* ForestTechniqueManager::createTerrain(const osg::Vec3& origin, const
if (createGrid)
{
- osg::Grid* grid = new osg::Grid;
+ osg::HeightField* grid = new osg::HeightField;
grid->allocateGrid(numColumns,numRows);
grid->setOrigin(origin);
grid->setXInterval(size.x()/(float)(numColumns-1));
diff --git a/examples/osgshadowtexture/osgshadowtexture.cpp b/examples/osgshadowtexture/osgshadowtexture.cpp
index 567fc3db6..929f82434 100644
--- a/examples/osgshadowtexture/osgshadowtexture.cpp
+++ b/examples/osgshadowtexture/osgshadowtexture.cpp
@@ -68,7 +68,7 @@ osg::Node* createBase(const osg::Vec3& center,float radius)
geode->setStateSet( stateset );
- osg::Grid* grid = new osg::Grid;
+ osg::HeightField* grid = new osg::HeightField;
grid->allocateGrid(38,39);
grid->setOrigin(center+osg::Vec3(-radius,-radius,0.0f));
grid->setXInterval(radius*2.0f/(float)(38-1));
diff --git a/examples/osgshape/osgshape.cpp b/examples/osgshape/osgshape.cpp
index 6412fdaf7..e9c03086a 100644
--- a/examples/osgshape/osgshape.cpp
+++ b/examples/osgshape/osgshape.cpp
@@ -42,7 +42,7 @@ osg::Geode* createShapes()
geode->addDrawable(new osg::ShapeDrawable(new osg::Cone(osg::Vec3(4.0f,0.0f,0.0f),radius,height),hints));
geode->addDrawable(new osg::ShapeDrawable(new osg::Cylinder(osg::Vec3(6.0f,0.0f,0.0f),radius,height),hints));
- osg::Grid* grid = new osg::Grid;
+ osg::HeightField* grid = new osg::HeightField;
grid->allocateGrid(38,39);
grid->setXInterval(0.28f);
grid->setYInterval(0.28f);
diff --git a/include/osg/Shape b/include/osg/Shape
index bdf53f661..3001255af 100644
--- a/include/osg/Shape
+++ b/include/osg/Shape
@@ -418,21 +418,25 @@ class SG_EXPORT HeightField : public Shape
{
public:
- HeightField() {}
-
- HeightField(const HeightField& mesh,const CopyOp& copyop=CopyOp::SHALLOW_COPY):
- Shape(mesh,copyop),
+ HeightField():
_columns(0),
_rows(0),
_origin(0.0f,0.0f,0.0f),
_dx(1.0f),
_dy(1.0f) {}
+
+ HeightField(const HeightField& mesh,const CopyOp& copyop=CopyOp::SHALLOW_COPY):
+ Shape(mesh,copyop),
+ _columns(mesh._columns),
+ _rows(mesh._rows),
+ _origin(mesh._origin),
+ _dx(mesh._dx),
+ _dy(mesh._dy),
+ _heights(mesh._heights) {}
- virtual bool isSameKindAs(const Object* obj) const { return dynamic_cast(obj)!=NULL; }
- virtual const char* libraryName() const { return "osg"; }
- virtual const char* className() const { return "HeightField"; }
- virtual void accept(osg::ShapeVisitor& sv) { sv.apply(*this); }
- virtual void accept(osg::ConstShapeVisitor& csv) const { csv.apply(*this); }
+ META_Shape(osg, HeightField)
+
+ void allocateGrid(unsigned int numColumns,unsigned int numRows);
inline unsigned int getNumColumns() const { return _columns; }
inline unsigned int getNumRows() const { return _rows; }
@@ -446,9 +450,23 @@ class SG_EXPORT HeightField : public Shape
inline void setYInterval(float dy) { _dy = dy; }
inline float getYInterval() const { return _dy; }
- virtual float getHeight(unsigned int c,unsigned int r) const = 0;
-
- virtual Vec3 getNormal(unsigned int c,unsigned int r) const;
+
+ inline void setHeight(unsigned int c,unsigned int r,float value)
+ {
+ _heights[c+r*_columns] = value;
+ }
+
+ inline float& getHeight(unsigned int c,unsigned int r)
+ {
+ return _heights[c+r*_columns];
+ }
+
+ inline float getHeight(unsigned int c,unsigned int r) const
+ {
+ return _heights[c+r*_columns];
+ }
+
+ Vec3 getNormal(unsigned int c,unsigned int r) const;
inline void setRotation(const Quat& quat) { _rotation = quat; }
inline const Quat& getRotation() const { return _rotation; }
@@ -467,39 +485,11 @@ class SG_EXPORT HeightField : public Shape
Quat _rotation;
-};
-
-class SG_EXPORT Grid : public HeightField
-{
- public:
-
- Grid();
-
- Grid(const Grid& mesh,const CopyOp& copyop=CopyOp::SHALLOW_COPY);
-
- META_Shape(osg,Grid);
-
- void allocateGrid(unsigned int numColumns,unsigned int numRows);
-
- void setHeight(unsigned int c,unsigned int r,float value)
- {
- _heights[c+r*_columns] = value;
- }
-
- virtual float getHeight(unsigned int c,unsigned int r) const
- {
- return _heights[c+r*_columns];
- }
-
- protected:
-
- ~Grid();
-
typedef std::vector HeightList;
HeightList _heights;
-
};
+
class CompositeShape : public Shape
{
public:
diff --git a/include/osgDB/ImageOptions b/include/osgDB/ImageOptions
index 72e277763..d9a7fe3e4 100644
--- a/include/osgDB/ImageOptions
+++ b/include/osgDB/ImageOptions
@@ -86,24 +86,43 @@ class OSGDB_EXPORT ImageOptions : public osgDB::ReaderWriter::Options
CUBIC
};
+ /** Used as UserData attached to generated osg::Image's*/
+ struct TexCoordRange : public osg::Referenced
+ {
+ TexCoordRange():
+ _x(0.0),
+ _y(0.0),
+ _w(1.0),
+ _h(1.0) {}
+
+ void set(double x,double y, double w, double h)
+ {
+ _x = x;
+ _y = y;
+ _w = w;
+ _h = h;
+ }
+
+ double _x,_y,_w,_h;
+ };
+
+
// source
ImageSamplingMode _sourceImageSamplingMode;
ImageWindowMode _sourceImageWindowMode;
RatioWindow _sourceRatioWindow;
PixelWindow _sourcePixelWindow;
-
-
// destination
osg::ref_ptr _destinationImage;
-
+
ImageWindowMode _destinationImageWindowMode;
RatioWindow _destinationRatioWindow;
PixelWindow _destinationPixelWindow;
-
+
GLenum _destinationDataType;
GLenum _destinationPixelFormat;
-
+
void init();
};
diff --git a/include/osgGA/AnimationPathManipulator b/include/osgGA/AnimationPathManipulator
index 8c6686c64..7e5ee724d 100644
--- a/include/osgGA/AnimationPathManipulator
+++ b/include/osgGA/AnimationPathManipulator
@@ -21,7 +21,7 @@
namespace osgGA{
//
-// The AnimationPathManipulator is a Camera Manipulator that reads an
+// The AnimationPathManipulator is a Matrix Manipulator that reads an
// animation path from a file and plays it back. The file is expected
// to be ascii and a succession of lines with 8 floating point values
// per line. The succession of values are:
diff --git a/src/osg/Shape.cpp b/src/osg/Shape.cpp
index fe93d4d65..c47afe1a2 100644
--- a/src/osg/Shape.cpp
+++ b/src/osg/Shape.cpp
@@ -15,6 +15,16 @@
using namespace osg;
+void HeightField::allocateGrid(unsigned int numColumns,unsigned int numRows)
+{
+ if (_columns!=numColumns || _rows!=numRows)
+ {
+ _heights.resize(numColumns*numRows);
+ }
+ _columns=numColumns;
+ _rows=numRows;
+}
+
Vec3 HeightField::getNormal(unsigned int c,unsigned int r) const
{
// four point normal generation.
@@ -53,27 +63,4 @@ Vec3 HeightField::getNormal(unsigned int c,unsigned int r) const
return normal;
}
-Grid::Grid()
-{
-}
-
-Grid::Grid(const Grid& mesh,const CopyOp& copyop):
- HeightField(mesh,copyop)
-{
- _heights = mesh._heights;
-}
-
-Grid::~Grid()
-{
-}
-
-void Grid::allocateGrid(unsigned int numColumns,unsigned int numRows)
-{
- if (_columns!=numColumns || _rows!=numRows)
- {
- _heights.resize(numColumns*numRows);
- }
- _columns=numColumns;
- _rows=numRows;
-}
diff --git a/src/osgPlugins/gdal/ReaderWriterGDAL.cpp b/src/osgPlugins/gdal/ReaderWriterGDAL.cpp
index 71201cc87..93009e6f6 100644
--- a/src/osgPlugins/gdal/ReaderWriterGDAL.cpp
+++ b/src/osgPlugins/gdal/ReaderWriterGDAL.cpp
@@ -42,18 +42,35 @@ class ReaderWriterGDAL : public osgDB::ReaderWriter
int destHeight = osg::minimum(dataHeight,1024);
+ osgDB::ImageOptions::TexCoordRange* texCoordRange = 0;
+
const osgDB::ImageOptions* imageOptions = dynamic_cast(options);
if (imageOptions)
{
std::cout<<"Got ImageOptions"<_sourceImageWindowMode)
{
case(osgDB::ImageOptions::RATIO_WINDOW):
- windowX = osg::maximum((int)(floor((double)dataWidth * imageOptions->_sourceRatioWindow.windowX)),0);
- windowY = osg::maximum((int)(floor((double)dataHeight * imageOptions->_sourceRatioWindow.windowY)),0);
- windowWidth = osg::minimum((int)(ceil((double)dataWidth * (imageOptions->_sourceRatioWindow.windowX + imageOptions->_sourceRatioWindow.windowWidth))),dataWidth)-windowX;
- windowHeight = osg::minimum((int)(ceil((double)dataHeight * (imageOptions->_sourceRatioWindow.windowY + imageOptions->_sourceRatioWindow.windowHeight))),dataHeight)-windowY;
+ {
+ double desiredX = (double)dataWidth * imageOptions->_sourceRatioWindow.windowX;
+ double desiredY = (double)dataHeight * imageOptions->_sourceRatioWindow.windowY;
+ double desiredWidth = (double)dataWidth * imageOptions->_sourceRatioWindow.windowWidth;
+ double desiredHeight = (double)dataHeight * imageOptions->_sourceRatioWindow.windowHeight;
+
+ windowX = osg::maximum((int)(floor(desiredX))-margin,0);
+ windowY = osg::maximum((int)(floor(desiredY))-margin,0);
+ windowWidth = osg::minimum((int)(ceil(desiredX + desiredWidth))+margin,dataWidth)-windowX;
+ windowHeight = osg::minimum((int)(ceil(desiredY + desiredHeight))+margin,dataHeight)-windowY;
+
+ texCoordRange = new osgDB::ImageOptions::TexCoordRange;
+ texCoordRange->set((desiredX-(double)windowX)/(double)windowWidth,
+ ((double)(windowY+windowHeight) -(desiredY+desiredHeight))/(double)windowHeight,
+ (desiredWidth)/(double)windowWidth,
+ (desiredHeight)/(double)windowHeight);
+ std::cout<<"tex coord range "<_x<<" "<_y<<" "<_w<<" "<_h<_sourcePixelWindow.windowX;
@@ -145,6 +162,7 @@ class ReaderWriterGDAL : public osgDB::ReaderWriter
else if (band->GetColorInterpretation()==GCI_GreenBand) bandGreen = band;
else if (band->GetColorInterpretation()==GCI_BlueBand) bandBlue = band;
else if (band->GetColorInterpretation()==GCI_AlphaBand) bandAlpha = band;
+ else bandGray = band;
// int gotMin,gotMax;
// double minmax[2];
@@ -281,7 +299,9 @@ class ReaderWriterGDAL : public osgDB::ReaderWriter
dataType,
(unsigned char *)imageData,
osg::Image::USE_NEW_DELETE);
-
+
+ if (texCoordRange) image->setUserData(texCoordRange);
+
image->flipVertical();
return image;
diff --git a/src/osgPlugins/osg/Drawable.cpp b/src/osgPlugins/osg/Drawable.cpp
index 6f1a46205..69631c8ca 100644
--- a/src/osgPlugins/osg/Drawable.cpp
+++ b/src/osgPlugins/osg/Drawable.cpp
@@ -73,6 +73,21 @@ bool Drawable_readLocalData(Object& obj, Input& fr)
}
}
+ if (fr[0].matchWord("useVertexBufferObjects"))
+ {
+ if (fr[1].matchWord("TRUE"))
+ {
+ drawable.setUseVertexBufferObjects(true);
+ fr+=2;
+ iteratorAdvanced = true;
+ }
+ else if (fr[1].matchWord("FALSE"))
+ {
+ drawable.setUseVertexBufferObjects(false);
+ fr+=2;
+ iteratorAdvanced = true;
+ }
+ }
return iteratorAdvanced;
}
@@ -103,6 +118,9 @@ bool Drawable_writeLocalData(const Object& obj, Output& fw)
if (drawable.getUseDisplayList()) fw << "TRUE" << std::endl;
else fw << "FALSE" << std::endl;
+ fw.indent()<<"useVertexBufferObjects ";
+ if (drawable.getUseVertexBufferObjects()) fw << "TRUE" << std::endl;
+ else fw << "FALSE" << std::endl;
return true;
}
diff --git a/src/osgPlugins/osg/Shape.cpp b/src/osgPlugins/osg/Shape.cpp
index a5f21b5f0..b03ca8360 100644
--- a/src/osgPlugins/osg/Shape.cpp
+++ b/src/osgPlugins/osg/Shape.cpp
@@ -305,14 +305,25 @@ bool HeightField_writeLocalData(const Object& obj, Output& fw);
//register the read and write functions with the osgDB::Registry.
RegisterDotOsgWrapperProxy g_HeightFieldFuncProxy
(
- 0,
+ new osg::HeightField,
"HeightField",
- "Object HieghtField",
+ "Object HeightField",
&HeightField_readLocalData,
&HeightField_writeLocalData,
DotOsgWrapper::READ_AND_WRITE
);
+//register the read and write functions with the osgDB::Registry.
+RegisterDotOsgWrapperProxy g_GridFuncProxy
+(
+ new osg::HeightField,
+ "Grid",
+ "Object HeightField",
+ 0,
+ 0,
+ DotOsgWrapper::READ_AND_WRITE
+);
+
bool HeightField_readLocalData(Object& obj, Input& fr)
{
bool iteratorAdvanced = false;
@@ -359,49 +370,12 @@ bool HeightField_readLocalData(Object& obj, Input& fr)
iteratorAdvanced = true;
}
- return iteratorAdvanced;
-}
-
-bool HeightField_writeLocalData(const Object& obj, Output& fw)
-{
- const HeightField& heightfield = static_cast(obj);
-
- fw.indent()<<"Origin "<(obj);
-
if (fr.matchSequence("NumColumnsAndRows %i %i"))
{
int numcolumns,numrows;
fr[1].getInt(numcolumns);
fr[2].getInt(numrows);
- grid.allocateGrid(numcolumns,numrows);
+ heightfield.allocateGrid(numcolumns,numrows);
fr+=3;
iteratorAdvanced = true;
}
@@ -421,9 +395,9 @@ bool Grid_readLocalData(Object& obj, Input& fr)
{
if (fr.readSequence(height))
{
- grid.setHeight(column,row,height);
+ heightfield.setHeight(column,row,height);
++column;
- if (column>=grid.getNumColumns())
+ if (column>=heightfield.getNumColumns())
{
column = 0;
++row;
@@ -440,25 +414,29 @@ bool Grid_readLocalData(Object& obj, Input& fr)
}
-
return iteratorAdvanced;
}
-bool Grid_writeLocalData(const Object& obj, Output& fw)
+bool HeightField_writeLocalData(const Object& obj, Output& fw)
{
- const Grid& grid = static_cast(obj);
+ const HeightField& heightfield = static_cast(obj);
- fw.indent()<<"NumColumnsAndRows "<