2.8 branch: Latest Inventor plugin. Revisions from trunk included in this commit: 11032 and 11034.

This commit is contained in:
Paul MARTZ
2010-03-15 20:06:25 +00:00
parent 9f45b89722
commit cb3868872e
11 changed files with 1424 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);
}