parameter in osg::Image. To support this Image::setData(..) now has a new optional rowLength parameter which defaults to 0, which provides the original behaviour, Image::setRowLength(int) and int Image::getRowLength() are also provided. With the introduction of RowLength support in osg::Image it is now possible to create a sub image where the t size of the image are smaller than the row length, useful for when you have a large image on the CPU and which to use a small portion of it on the GPU. However, when these sub images are created the data within the image is no longer contiguous so data access can no longer assume that all the data is in one block. The new method Image::isDataContiguous() enables the user to check whether the data is contiguous, and if not one can either access the data row by row using Image::data(column,row,image) accessor, or use the new Image::DataIterator for stepping through each block on memory assocatied with the image. To support the possibility of non contiguous osg::Image usage of image objects has had to be updated to check DataContiguous and handle the case or use access via the DataIerator or by row by row. To achieve this a relatively large number of files has had to be modified, in particular the texture classes and image plugins that doing writing.
123 lines
3.8 KiB
C++
123 lines
3.8 KiB
C++
#include <osg/ComputeBoundsVisitor>
|
|
#include <osg/io_utils>
|
|
#include <osg/Notify>
|
|
#include <osgDB/FileUtils>
|
|
#include <osgDB/FileNameUtils>
|
|
#include "ReaderWriterPOV.h"
|
|
#include "POVWriterNodeVisitor.h"
|
|
|
|
using namespace std;
|
|
using namespace osg;
|
|
|
|
|
|
// Register with Registry to instantiate the Povray writer.
|
|
REGISTER_OSGPLUGIN( Povray, ReaderWriterPOV )
|
|
|
|
|
|
/**
|
|
* Constructor.
|
|
* Initializes the ReaderWriterPOV.
|
|
*/
|
|
ReaderWriterPOV::ReaderWriterPOV()
|
|
{
|
|
// Set supported extensions and options
|
|
supportsExtension( "pov", "POV-Ray format" );
|
|
}
|
|
|
|
|
|
static osgDB::ReaderWriter::WriteResult
|
|
writeNodeImplementation( const Node& node, ostream& fout,
|
|
const osgDB::ReaderWriter::Options* options )
|
|
{
|
|
// get camera on the top of scene graph
|
|
const Camera *camera = dynamic_cast< const Camera* >( &node );
|
|
|
|
Vec3d eye, center, up, right;
|
|
double fovy, aspectRatio, tmp;
|
|
if( camera ) {
|
|
|
|
// view matrix
|
|
camera->getViewMatrixAsLookAt( eye, center, up );
|
|
up = Vec3d( 0.,0.,1. );
|
|
right = Vec3d( 1.,0.,0. );
|
|
//up.normalize();
|
|
//right = (center-eye) ^ up;
|
|
//right.normalize();
|
|
|
|
// projection matrix
|
|
camera->getProjectionMatrixAsPerspective( fovy, aspectRatio, tmp, tmp );
|
|
right *= aspectRatio;
|
|
|
|
} else {
|
|
|
|
// get POV-Ray camera setup from scene bounding sphere
|
|
// constructed from bounding box
|
|
// (bounding box computes model center more precisely than bounding sphere)
|
|
ComputeBoundsVisitor cbVisitor;
|
|
const_cast< Node& >( node ).accept( cbVisitor );
|
|
BoundingBox &bb = cbVisitor.getBoundingBox();
|
|
BoundingSphere bs( bb );
|
|
|
|
// set
|
|
eye = bs.center() + Vec3( 0., -3.0 * bs.radius(), 0. );
|
|
center = bs.center();
|
|
up = Vec3d( 0.,1.,0. );
|
|
right = Vec3d( 4./3.,0.,0. );
|
|
|
|
}
|
|
|
|
// camera
|
|
fout << "camera { // following POV-Ray, x is right, y is up, and z is to the scene" << endl
|
|
<< " location <" << eye[0] << ", " << eye[2] << ", " << eye[1] << ">" << endl
|
|
<< " up <" << up[0] << ", " << up[2] << ", " << up[1] << ">" << endl
|
|
<< " right <" << right[0] << ", " << right[2] << ", " << right[1] << ">" << endl
|
|
<< " look_at <" << center[0] << ", " << center[2] << ", " << center[1] << ">" << endl
|
|
<< "}" << endl
|
|
<< endl;
|
|
|
|
POVWriterNodeVisitor povWriter( fout, node.getBound() );
|
|
if( camera )
|
|
|
|
for( int i=0, c=camera->getNumChildren(); i<c; i++ )
|
|
const_cast< Camera* >( camera )->getChild( i )->accept( povWriter );
|
|
|
|
else
|
|
|
|
const_cast< Node* >( &node )->accept( povWriter );
|
|
|
|
notify( NOTICE ) << "ReaderWriterPOV::writeNode() Done. ("
|
|
<< povWriter.getNumProducedTriangles()
|
|
<< " triangles written)" << endl;
|
|
|
|
return osgDB::ReaderWriter::WriteResult::FILE_SAVED;
|
|
}
|
|
|
|
|
|
osgDB::ReaderWriter::WriteResult
|
|
ReaderWriterPOV::writeNode( const Node& node, const string& fileName,
|
|
const osgDB::ReaderWriter::Options* options ) const
|
|
{
|
|
// accept extension
|
|
string ext = osgDB::getLowerCaseFileExtension( fileName );
|
|
if( !acceptsExtension( ext ) ) return WriteResult::FILE_NOT_HANDLED;
|
|
|
|
notify( NOTICE ) << "ReaderWriterPOV::writeNode() Writing file " << fileName << endl;
|
|
|
|
osgDB::ofstream fout( fileName.c_str(), ios::out | ios::trunc );
|
|
if( !fout )
|
|
return WriteResult::ERROR_IN_WRITING_FILE;
|
|
else
|
|
return writeNodeImplementation( node, fout, options );
|
|
}
|
|
|
|
|
|
osgDB::ReaderWriter::WriteResult
|
|
ReaderWriterPOV::writeNode( const Node& node, ostream& fout,
|
|
const osgDB::ReaderWriter::Options* options ) const
|
|
{
|
|
notify( osg::NOTICE ) << "ReaderWriterPOV::writeNode() Writing to "
|
|
<< "stream" << endl;
|
|
|
|
return writeNodeImplementation( node, fout, options );
|
|
}
|