2.8 branch: Latest Inventor plugin. Revisions from trunk included in this commit: 11032 and 11034.
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