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:
@@ -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
@@ -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
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -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);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user