From Jan Peciva, "I am sending improved version of Inventor plugin. Attaching just

modified files, while GroupSoLOD.h and .cpp was deleted. Please, delete
it from repository, it is not used any longer and I doubt if it is
probably not used for anything meaningful for a while. In the new code,
there is no GroupSoLOD. Please, delete it.

I am using new plugin version for about 1.5 month so I consider it
stable by myself.

List of changes:
- rewritten Inventor state stack
- shaders support
- light attenuation support
- support for reading from stream (readNode(std::istream& fin, options))
- improved grouping node handling (SoSeparator, SoGroup,...)
- fixed transformation bug when two SoShapes/Drawables with different transformations are placed bellow one grouping node
- introduced preprocessing to handle more advanced usage schemes of SoLOD and SoSwitch nodes
- unused code clean up
- improved notify messages
- animation callbacks fixes
- FindInventor.cmake improved finding routines, support for Coin3 and Coin4"
This commit is contained in:
Robert Osfield
2010-01-31 12:55:29 +00:00
parent 874296cbb3
commit b2270e7f38
11 changed files with 1435 additions and 639 deletions

View File

@@ -3,7 +3,6 @@ INCLUDE(OsgMacroUtils)
SET(TARGET_SRC
ConvertToInventor.cpp
ConvertFromInventor.cpp
GroupSoLOD.cpp
PendulumCallback.cpp
ReaderWriterIV.cpp
ShuttleCallback.cpp
@@ -11,7 +10,6 @@ SET(TARGET_SRC
SET(TARGET_HDRS
ConvertToInventor.h
ConvertFromInventor.h
GroupSoLOD.h
PendulumCallback.h
ReaderWriterIV.h
ShuttleCallback.h
@@ -21,6 +19,6 @@ ADD_DEFINITIONS(-DCOIN_DLL)
INCLUDE_DIRECTORIES(${INVENTOR_INCLUDE_DIR})
SET(TARGET_LIBRARIES_VARS INVENTOR_LIBRARY)
SET(TARGET_ADDED_LIBRARIES ${INVENTOR_LIBRARY})
SETUP_PLUGIN(iv iv)

File diff suppressed because it is too large Load Diff

View File

@@ -10,6 +10,7 @@
#include <Inventor/SbLinear.h>
#include <vector>
#include <stack>
#include <assert.h>
class ConvertFromInventor
{
@@ -17,42 +18,53 @@ class ConvertFromInventor
ConvertFromInventor();
~ConvertFromInventor();
/// Conversts from IV to OSG scene graph
osg::Node* convert(SoNode* rootIVNode);
/**
* Preprocessing restructure the scene for the convertor
* to be able to convert some peculiar scene constructions.
* Resulting scene is geometrically equivalent to the source
* scene. The preprocessing is related to grouping nodes only
* (SoSeparator, SoGroup, SoLOD, SoSwitch,...) and their
* treatment with traversal state.
*/
void preprocess(SoNode *root);
private:
// Callback functions for converting inventor scene graph to osg
// Callback functions for converting inventor scene graph to osg
// scene graph
static SoCallbackAction::Response preNode(void* data,
SoCallbackAction* action, const SoNode* node);
static SoCallbackAction::Response postNode(void* data,
SoCallbackAction* action, const SoNode* node);
static SoCallbackAction::Response preTransformSeparator(void* data,
SoCallbackAction* action, const SoNode* node);
static SoCallbackAction::Response postTransformSeparator(void* data,
SoCallbackAction* action, const SoNode* node);
static SoCallbackAction::Response preLOD(void* data,
SoCallbackAction* action, const SoNode* node);
static SoCallbackAction::Response postLOD(void* data,
SoCallbackAction* action, const SoNode* node);
static SoCallbackAction::Response preShape(void* data,
SoCallbackAction* action, const SoNode* node);
static SoCallbackAction::Response postShape(void* data,
SoCallbackAction* action, const SoNode* node);
static SoCallbackAction::Response preGroup(void* data,
static SoCallbackAction::Response postTexture(void* data,
SoCallbackAction* action, const SoNode* node);
static SoCallbackAction::Response postGroup(void* data,
static SoCallbackAction::Response preLight(void* data,
SoCallbackAction* action, const SoNode* node);
static SoCallbackAction::Response preTexture(void* data,
static SoCallbackAction::Response preEnvironment(void* data,
SoCallbackAction* action, const SoNode* node);
static SoCallbackAction::Response preLight(void* data,
static SoCallbackAction::Response preShaderProgram(void* data,
SoCallbackAction* action, const SoNode* node);
static SoCallbackAction::Response preRotor(void* data,
static SoCallbackAction::Response preRotor(void* data,
SoCallbackAction* action, const SoNode* node);
static SoCallbackAction::Response prePendulum(void* data,
static SoCallbackAction::Response prePendulum(void* data,
SoCallbackAction* action, const SoNode* node);
static SoCallbackAction::Response preShuttle(void* data,
SoCallbackAction* action, const SoNode* node);
static SoCallbackAction::Response postLOD(void* data,
SoCallbackAction* action, const SoNode* node);
///Callback for VRMLImageTexture
///\param data The pointer to ConvertFromInventor object
///\param action The action handling class
///\param node The current VRMLImageTexture node
static SoCallbackAction::Response preVRMLImageTexture(void* data,
SoCallbackAction* action, const SoNode* node);
static SoCallbackAction::Response preVRMLAppearance(void* data,
SoCallbackAction* action, const SoNode* node);
static SoCallbackAction::Response postVRMLAppearance(void* data,
static SoCallbackAction::Response preShuttle(void* data,
SoCallbackAction* action, const SoNode* node);
static SoCallbackAction::Response preInfo(void* data,
SoCallbackAction* action, const SoNode* node);
@@ -67,18 +79,23 @@ class ConvertFromInventor
static void addPointCB(void* data, SoCallbackAction* action,
const SoPrimitiveVertex *v0);
static SoCallbackAction::Response restructure(void* data,
SoCallbackAction* action, const SoNode* node);
static SoCallbackAction::Response restructurePreNode(void* data,
SoCallbackAction* action, const SoNode* node);
static SoCallbackAction::Response restructurePostNode(void* data,
SoCallbackAction* action, const SoNode* node);
private:
SbString transformInfoName;
SbName appearanceName;
bool inAppearanceWithNoTexture;
void addMatrixTransform(const std::string& name, SbVec3f axis, float angle, SbVec3f center, SbVec3f trans, SbVec3f scale);
void addVertex(SoCallbackAction* action, const SoPrimitiveVertex* v,
void addVertex(SoCallbackAction* action, const SoPrimitiveVertex* v,
int index);
osg::ref_ptr<osg::StateSet> getStateSet(SoCallbackAction* action);
osg::Texture2D* convertIVTexToOSGTex(const SoNode* soNode,
osg::Texture2D* convertIVTexToOSGTex(const SoNode* soNode,
SoCallbackAction* action);
void transformLight(SoCallbackAction* action, const SbVec3f& vec,
@@ -99,7 +116,7 @@ class ConvertFromInventor
std::vector<osg::Vec4> colors;
std::vector<osg::Vec2> textureCoords;
// Num of primitive and primitive type
// Num of primitive and primitive type
int numPrimitives;
osg::PrimitiveSet::Mode primitiveType;
@@ -107,24 +124,104 @@ class ConvertFromInventor
enum VertexOrder { CLOCKWISE, COUNTER_CLOCKWISE };
VertexOrder vertexOrder;
// Stack of group nodes (used to build the scene graph)
std::stack<osg::Group* > groupStack;
// Stack of texture nodes (used for attaching the right texture to the
// geosets). Supported types are SoTexture2 and SoVRMLImageTexture for now.
std::stack<const SoNode*> soTexStack;
// Mapping from SoTexture2 and SoVRMLImageTexture to already converted
// osg::Texture2D - avoids duplication of same texture objects
std::map<const SoNode*, osg::Texture2D*> ivToOsgTexMap;
// Stack to maintain the list of lights at each level of the
// scenegraph
typedef std::vector<osg::Light *> LightList;
std::stack<LightList> lightStack;
osg::ref_ptr<osg::MatrixTransform> _root;///<The root node;
osg::ref_ptr<osg::Group> lightGroup;
/**
* IvStateItem aids lack of some state retrieval methods
* of SoCallbackAction. State is maintained in stack
* manner separately from Open Inventor.
*/
class IvStateItem {
public:
// Pop flags and node caused the push
enum Flags {
DEFAULT_FLAGS = 0,
MULTI_POP = 1,
KEEP_CHILDREN_ORDER = 2,
APPEND_AT_PUSH = 4,
UPDATE_STATE = 8,
UPDATE_STATE_EXCEPT_TRANSFORM = 0x10 // this has the same
// effect as UPDATE_STATE at the present time
};
int flags;
const SoNode *pushInitiator;
// Tracking of model transformation
SbMatrix inheritedTransformation;
SbMatrix lastUsedTransformation;
// Active texture node (used for attaching the right texture to the
// geosets). Supported types are SoTexture2 and SoVRMLImageTexture for now.
// No multitexturing yet.
const SoNode* inheritedTexture;
const SoNode* currentTexture;
// List of active lights
std::vector<osg::ref_ptr<osg::Light> > inheritedLights;
std::vector<osg::ref_ptr<osg::Light> > currentLights;
// Active OpenGL glProgram and associated shaders
osg::ref_ptr<osg::Program> inheritedGLProgram;
osg::ref_ptr<osg::Program> currentGLProgram;
// Ambient light (of SoEnvironment)
SbColor inheritedAmbientLight;
SbColor currentAmbientLight;
// Generated OSG graph
osg::ref_ptr<osg::Group> osgStateRoot;
// Extra variables
const SoNode *keepChildrenOrderParent;
IvStateItem(const SoNode *initiator, osg::Group *root = NULL) :
flags(IvStateItem::DEFAULT_FLAGS),
pushInitiator(initiator),
inheritedTransformation(SbMatrix::identity()),
lastUsedTransformation(SbMatrix::identity()),
inheritedTexture(NULL),
currentTexture(NULL),
inheritedLights(),
currentLights(),
inheritedGLProgram(NULL),
currentGLProgram(NULL),
inheritedAmbientLight(SbColor(0.2f,0.2f,0.2f)),
currentAmbientLight(SbColor(0.2f,0.2f,0.2f)),
osgStateRoot(root ? root : new osg::Group) {}
IvStateItem(const IvStateItem& i, const SoCallbackAction *action,
const SoNode *initiator, const int f,
osg::Group *root) :
flags(f),
pushInitiator(initiator),
inheritedTransformation(action->getModelMatrix()),
lastUsedTransformation(action->getModelMatrix()),
inheritedTexture(i.currentTexture),
currentTexture(i.currentTexture),
inheritedLights(i.currentLights),
currentLights(i.currentLights),
inheritedGLProgram(i.currentGLProgram),
currentGLProgram(i.currentGLProgram),
inheritedAmbientLight(i.inheritedAmbientLight),
currentAmbientLight(i.currentAmbientLight),
osgStateRoot(root) {}
};
/// State stack for Inventor scene traversal
std::stack<IvStateItem> ivStateStack;
void ivPushState(const SoCallbackAction *action,
const SoNode *initiator, const int flags = IvStateItem::DEFAULT_FLAGS,
osg::Group *root = new osg::Group);
void ivPopState(const SoCallbackAction *action, const SoNode *initator);
void appendNode(osg::Node *n, const SoCallbackAction *action);
};
#endif

View File

@@ -236,7 +236,7 @@ void osgArray2ivMField_template(const osg::Array *array, fieldClass &field, int
int z;
for (i=0, z=0; i<num; i++)
if (z == numItemsUntilMinusOne) {
a[i] = -1;
a[i] = ivType(-1);
z = 0;
} else {
a[i] = ivType(*ptr);
@@ -1920,7 +1920,7 @@ void ConvertToInventor::apply(osg::Billboard& node)
// Rotate billboard correctly (OSG->IV conversion)
// Note: use SoTransform instead of SoRotation because SoRotation is not supported by VRML1.
SoTransform *transform = new SoTransform;
transform->rotation = SbRotation(SbVec3f(1.f,0.f,0.f), -M_PI_2);
transform->rotation = SbRotation(SbVec3f(1.f,0.f,0.f), float(-M_PI_2));
SoSeparator *separator = new SoSeparator;
separator->addChild(translation);
@@ -2047,3 +2047,4 @@ void ConvertToInventor::apply(osg::LOD& node)
popInventorState();
}

View File

@@ -1,28 +0,0 @@
#include <Inventor/nodes/SoGroup.h>
#include <Inventor/actions/SoCallbackAction.h>
#include "GroupSoLOD.h"
SO_NODE_SOURCE(GroupSoLOD)
void GroupSoLOD::initClass()
{
classTypeId = SoType::overrideType(SoLOD::getClassTypeId(),
createInstance);
parentFieldData = SoLOD::getFieldDataPtr();
}
GroupSoLOD::GroupSoLOD()
{
SO_NODE_CONSTRUCTOR(GroupSoLOD);
}
GroupSoLOD::~GroupSoLOD()
{
}
void GroupSoLOD::callback(SoCallbackAction *action)
{
SoGroup::doAction(action);
}

View File

@@ -1,22 +0,0 @@
#ifndef _GROUPSOLOD_H_
#define _GROUPSOLOD_H_
#include <Inventor/nodes/SoLOD.h>
#include <Inventor/nodes/SoSubNode.h>
class GroupSoLOD : public SoLOD
{
SO_NODE_HEADER(GroupSoLOD);
public:
GroupSoLOD();
static void initClass();
protected:
virtual void callback(SoCallbackAction *action);
private:
virtual ~GroupSoLOD();
};
#endif

View File

@@ -2,7 +2,7 @@
#include "PendulumCallback.h"
PendulumCallback::PendulumCallback(const osg::Vec3& axis,
PendulumCallback::PendulumCallback(const osg::Vec3& axis,
float startAngle, float endAngle,
float frequency)
{
@@ -10,7 +10,7 @@ PendulumCallback::PendulumCallback(const osg::Vec3& axis,
_startAngle = startAngle;
_endAngle = endAngle;
_frequency = frequency;
_previousTraversalNumber = -1;
_previousTime = -1.0;
_angle = 0.0;
@@ -26,24 +26,26 @@ void PendulumCallback::operator() (osg::Node* node, osg::NodeVisitor* nv)
return;
const osg::FrameStamp* fs = nv->getFrameStamp();
if (!fs)
return;
if (!fs)
return;
// ensure that we do not operate on this node more than
// once during this traversal. This is an issue since node
// can be shared between multiple parents.
if (nv->getTraversalNumber()!=_previousTraversalNumber)
{
double currentTime = fs->getSimulationTime();
if (_previousTime == -1.)
_previousTime = currentTime;
_angle += (currentTime - _previousTime) * 2 * osg::PI * _frequency;
double frac = 0.5 + 0.5 * sin(_angle);
double rotAngle = _endAngle - _startAngle - osg::PI
double frac = 0.5 - 0.5 * cos(_angle);
double rotAngle = //_endAngle - _startAngle - osg::PI
+ (1.0 - frac) * _startAngle + frac * _endAngle;
// update the specified transform
transform->setMatrix(osg::Matrix::rotate(rotAngle, _axis));
_previousTraversalNumber = nv->getTraversalNumber();
_previousTime = currentTime;
}
@@ -52,3 +54,4 @@ void PendulumCallback::operator() (osg::Node* node, osg::NodeVisitor* nv)
traverse(node,nv);
}

View File

@@ -17,7 +17,7 @@
The plugin requires one of Inventor libraries:
- Coin - GPL, support of VRML 2.0
(http://www.coin3d.org)
(http://www.coin3d.org)
- SGI Inventor - LGPL
(http://oss.sgi.com/projects/inventor/)
- TGS Inventor - commercial
@@ -26,9 +26,10 @@ The plugin requires one of Inventor libraries:
Contributors:
Sean Spicer - Vivek (c) Magic-Earth - Original author of the plugin
Sean Spicer - Vivek (c) Magic-Earth - Original author of the Inventor reader
Gerrick Bivins
PCJohn - Jan Peciva, Cadwork (c)
PCJohn - Jan Peciva, Cadwork (c) - author of Inventor writer, number of
contributions and improvements to the reader
Minor fixes:
Ruben

View File

@@ -1,5 +1,3 @@
#include "ReaderWriterIV.h"
// OSG headers
#include <osg/Notify>
#include <osgDB/FileUtils>
@@ -12,52 +10,132 @@
#include <Inventor/nodes/SoSeparator.h>
#include <Inventor/actions/SoWriteAction.h>
#include <Inventor/actions/SoCallbackAction.h>
#ifdef __COIN__
#include <Inventor/VRMLnodes/SoVRMLImageTexture.h>
# include <Inventor/VRMLnodes/SoVRMLImageTexture.h>
#endif
#include "ReaderWriterIV.h"
#include "ConvertFromInventor.h"
#include "GroupSoLOD.h"
#include "ConvertToInventor.h"
// forward declarations of static functions
static void addSearchPaths(const osgDB::FilePathList *searchPaths);
static void removeSearchPaths(const osgDB::FilePathList *searchPaths);
// Register with Registry to instantiate the inventor reader.
REGISTER_OSGPLUGIN(Inventor, ReaderWriterIV)
/**
* Constructor.
* Initializes the ReaderWriterIV.
*/
ReaderWriterIV::ReaderWriterIV()
{
// Set supported extensions and options
supportsExtension("iv","Inventor format");
supportsExtension("wrl","VRML world file");
// Initialize Inventor
initInventor();
}
// Read file and convert to OSG
osgDB::ReaderWriter::ReadResult
ReaderWriterIV::readNode(const std::string& file,
const osgDB::ReaderWriter::Options* options) const
/**
* Initializes Open Inventor.
*/
void ReaderWriterIV::initInventor() const
{
std::string ext = osgDB::getLowerCaseFileExtension(file);
if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED;
std::string fileName = osgDB::findDataFile( file, options );
if (fileName.empty()) return ReadResult::FILE_NOT_FOUND;
osg::notify(osg::INFO) << "osgDB::ReaderWriterIV::readNode() Reading file "
<< fileName.data() << std::endl;
// Initialize Inventor
SoDB::init();
SoNodeKit::init();
SoInteraction::init();
// Initial GroupSoLOD node
GroupSoLOD::initClass();
#ifdef __COIN__
// Disable delayed loading of VRML textures
SoVRMLImageTexture::setDelayFetchURL(FALSE);
#endif
}
/**
* Read from SoInput and convert to OSG.
* This is a method used by readNode(string,options) and readNode(istream,options).
*/
osgDB::ReaderWriter::ReadResult
ReaderWriterIV::readNodeFromSoInput(SoInput &input,
std::string &fileName, const osgDB::ReaderWriter::Options *options) const
{
// Parse options and add search paths to SoInput
const osgDB::FilePathList *searchPaths = options ? &options->getDatabasePathList() : NULL;
if (options)
addSearchPaths(searchPaths);
// Create the inventor scenegraph by reading from SoInput
SoSeparator* rootIVNode = SoDB::readAll(&input);
// Remove recently appened search paths
if (options)
removeSearchPaths(searchPaths);
// Close the file
input.closeFile();
// Perform conversion
ReadResult result;
if (rootIVNode)
{
rootIVNode->ref();
// Convert the inventor scenegraph to an osg scenegraph
ConvertFromInventor convertIV;
convertIV.preprocess(rootIVNode);
result = convertIV.convert(rootIVNode);
rootIVNode->unref();
} else
result = ReadResult::FILE_NOT_HANDLED;
// Notify
if (result.success()) {
if (fileName.length())
osg::notify(osg::NOTICE) << "osgDB::ReaderWriterIV::readNode() "
<< "File " << fileName.data()
<< " loaded successfully." << std::endl;
else
osg::notify(osg::NOTICE) << "osgDB::ReaderWriterIV::readNode() "
<< "Stream loaded successfully." << std::endl;
} else {
if (fileName.length())
osg::notify(osg::WARN) << "osgDB::ReaderWriterIV::readNode() "
<< "Failed to load file " << fileName.data()
<< "." << std::endl;
else
osg::notify(osg::WARN) << "osgDB::ReaderWriterIV::readNode() "
<< "Failed to load stream." << std::endl;
}
return result;
}
// Read file and convert to OSG
osgDB::ReaderWriter::ReadResult
ReaderWriterIV::readNode(const std::string& file,
const osgDB::ReaderWriter::Options* options) const
{
// Accept extension
std::string ext = osgDB::getLowerCaseFileExtension(file);
if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED;
// Find file
std::string fileName = osgDB::findDataFile( file, options );
if (fileName.empty()) return ReadResult::FILE_NOT_FOUND;
// Notify
osg::notify(osg::NOTICE) << "osgDB::ReaderWriterIV::readNode() Reading file "
<< fileName.data() << std::endl;
osg::notify(osg::INFO) << "osgDB::ReaderWriterIV::readNode() Inventor version: "
<< SoDB::getVersion() << std::endl;
// Open the file
SoInput input;
@@ -68,23 +146,59 @@ ReaderWriterIV::readNode(const std::string& file,
return ReadResult::ERROR_IN_READING_FILE;
}
// Create the inventor scenegraph from the file
SoSeparator* rootIVNode = SoDB::readAll(&input);
// Perform reading from SoInput
return readNodeFromSoInput(input, fileName, options);
}
// Close the file
input.closeFile();
if (rootIVNode)
{
rootIVNode->ref();
// Convert the inventor scenegraph to an osg scenegraph and return it
ConvertFromInventor convertIV;
ReadResult result = convertIV.convert(rootIVNode);
rootIVNode->unref();
return result;
osgDB::ReaderWriter::ReadResult
ReaderWriterIV::readNode(std::istream& fin,
const osgDB::ReaderWriter::Options* options) const
{
// Notify
osg::notify(osg::NOTICE) << "osgDB::ReaderWriterIV::readNode() "
"Reading from stream." << std::endl;
osg::notify(osg::INFO) << "osgDB::ReaderWriterIV::readNode() "
"Inventor version: " << SoDB::getVersion() << std::endl;
// Open the file
SoInput input;
// Assign istream to SoInput
// note: It seems there is no straightforward way to do that.
// SoInput accepts only FILE by setFilePointer or memory buffer
// by setBuffer. The FILE is dangerous on Windows, since it forces
// the plugin and Inventor DLL to use the same runtime library
// (otherwise there are app crashes).
// The memory buffer seems much better option here, even although
// there will not be a real streaming. However, the model data
// are usually much smaller than textures, so we should not worry
// about it and think how to stream textures instead.
// Get the data to the buffer
size_t bufSize = 126*1024; // let's make it something bellow 128KB
char *buf = (char*)malloc(bufSize);
size_t dataSize = 0;
while (!fin.eof() && fin.good()) {
fin.read(buf+dataSize, bufSize-dataSize);
dataSize += fin.gcount();
if (bufSize == dataSize) {
bufSize *= 2;
buf = (char*)realloc(buf, bufSize);
}
}
input.setBuffer(buf, dataSize);
osg::notify(osg::INFO) << "osgDB::ReaderWriterIV::readNode() "
"Stream size: " << dataSize << std::endl;
return ReadResult::FILE_NOT_HANDLED;
// Perform reading from SoInput
osgDB::ReaderWriter::ReadResult r;
std::string fileName("");
r = readNodeFromSoInput(input, fileName, options);
// clean up and return
free(buf);
return r;
}
@@ -97,11 +211,8 @@ ReaderWriterIV::writeNode(const osg::Node& node, const std::string& fileName,
if (!acceptsExtension(ext)) return WriteResult::FILE_NOT_HANDLED;
bool useVRML1 = !isInventorExtension(osgDB::getFileExtension(fileName));
osg::notify(osg::INFO) << "osgDB::ReaderWriterIV::writeNode() Writing file "
<< fileName.data() << std::endl;
// Initialize Inventor
SoInteraction::init();
osg::notify(osg::NOTICE) << "osgDB::ReaderWriterIV::writeNode() Writing file "
<< fileName.data() << std::endl;
// Convert OSG graph to Inventor graph
ConvertToInventor osg2iv;
@@ -130,3 +241,18 @@ ReaderWriterIV::writeNode(const osg::Node& node, const std::string& fileName,
return WriteResult::FILE_SAVED;
}
static void addSearchPaths(const osgDB::FilePathList *searchPaths)
{
for (int i=searchPaths->size()-1; i>=0; i--)
SoInput::addDirectoryFirst(searchPaths->operator[](i).c_str());
}
static void removeSearchPaths(const osgDB::FilePathList *searchPaths)
{
for (int i=0, c=searchPaths->size(); i<c; i++)
SoInput::addDirectoryFirst(searchPaths->operator[](i).c_str());
}

View File

@@ -8,22 +8,31 @@ class ReaderWriterIV : public osgDB::ReaderWriter
{
public:
ReaderWriterIV();
virtual const char* className() const
{
return "Inventor reader/writer";
{
return "Inventor reader/writer";
}
bool isInventorExtension(const std::string& extension) const
{
return osgDB::equalCaseInsensitive(extension, "iv") ? true : false;
}
virtual ReadResult readNode(const std::string& filename,
const osgDB::ReaderWriter::Options *) const;
virtual ReadResult readNode(const std::string& filename,
const osgDB::ReaderWriter::Options*) const;
virtual ReadResult readNode(std::istream& fin,
const osgDB::ReaderWriter::Options* = NULL) const;
virtual WriteResult writeNode(const osg::Node& node, const std::string& filename,
const osgDB::ReaderWriter::Options* options = NULL) const;
protected:
void initInventor() const;
ReadResult readNodeFromSoInput(class SoInput&,
std::string &fileName, const osgDB::ReaderWriter::Options*) const;
};
#endif

View File

@@ -2,14 +2,14 @@
#include "ShuttleCallback.h"
ShuttleCallback::ShuttleCallback(const osg::Vec3& startPos,
ShuttleCallback::ShuttleCallback(const osg::Vec3& startPos,
const osg::Vec3& endPos,
float frequency)
{
_startPos = startPos;
_endPos = endPos;
_frequency = frequency;
_previousTraversalNumber = -1;
_previousTime = -1.0;
_angle = 0.0;
@@ -25,24 +25,26 @@ void ShuttleCallback::operator() (osg::Node* node, osg::NodeVisitor* nv)
return;
const osg::FrameStamp* fs = nv->getFrameStamp();
if (!fs)
return;
if (!fs)
return;
// ensure that we do not operate on this node more than
// once during this traversal. This is an issue since node
// can be shared between multiple parents.
if (nv->getTraversalNumber()!=_previousTraversalNumber)
{
double currentTime = fs->getSimulationTime();
if (_previousTime == -1.)
_previousTime = currentTime;
_angle += (currentTime - _previousTime) * 2 * osg::PI * _frequency;
double frac = 0.5 + 0.5 * sin(_angle);
double frac = 0.5 - 0.5 * cos(_angle);
osg::Vec3 position = _startPos * (1.0 - frac) + _endPos * frac;
// update the specified transform
transform->setMatrix(osg::Matrix::translate(position));
_previousTraversalNumber = nv->getTraversalNumber();
_previousTime = currentTime;
}
@@ -51,3 +53,4 @@ void ShuttleCallback::operator() (osg::Node* node, osg::NodeVisitor* nv)
traverse(node,nv);
}