Integrated Ulrich Hertlien's osg::Sequence node, and osgsequence demo, and

support for osg::Sequence in the pfb loader.
This commit is contained in:
Robert Osfield
2002-08-03 18:11:21 +00:00
parent c253d3558b
commit 6a04fc3dee
19 changed files with 894 additions and 18 deletions

View File

@@ -62,6 +62,8 @@ Randall Hopper <aa8vb@yahoo.com>
Ulrich Hertlein <u.hertlein@bit-side.com>
- support for IBM Mirror Repeat extension in osg::Texture
- support for texture subloading in osg::Texture
- osg::Sequence support.
- improvements to the pfb loader.
- .lwo and .obj plugins.
Axel Volley <volley@acm.org>

View File

@@ -86,6 +86,7 @@ DEMOS_DIRS = \
osgreflect\
osgscribe\
osgstereoimage\
osgsequence\
osgtext\
osgtexture\
osgviews\

View File

@@ -0,0 +1,95 @@
# Microsoft Developer Studio Project File - Name="Demo osgsequence" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Console Application" 0x0103
CFG=Demo osgsequence - Win32 Release
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "osgsequence.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "osgsequence.mak" CFG="Demo osgsequence - Win32 Release"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "Demo osgsequence - Win32 Release" (based on "Win32 (x86) Console Application")
!MESSAGE "Demo osgsequence - Win32 Debug" (based on "Win32 (x86) Console Application")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
RSC=rc.exe
!IF "$(CFG)" == "Demo osgsequence - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD CPP /nologo /MD /W3 /GR /GX /O2 /I "../../../include" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD BASE RSC /l 0x809 /d "NDEBUG"
# ADD RSC /l 0x809 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
# ADD LINK32 /nologo /subsystem:console /pdb:none /machine:I386 /out:"../../../bin/osgsequence.exe" /libpath:"../../../lib"
!ELSEIF "$(CFG)" == "Demo osgsequence - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD CPP /nologo /MDd /W3 /Gm /vd0 /GR /GX /Zi /Od /I "../../../include" /D "_CONSOLE" /D "_MBCS" /D "FL_DLL" /D "WIN32" /D "_DEBUG" /FR /YX /FD /c
# ADD BASE RSC /l 0x809 /d "_DEBUG"
# ADD RSC /l 0x809 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
# ADD LINK32 glut32.lib glu32.lib opengl32.lib /nologo /subsystem:console /debug /machine:I386 /nodefaultlib:"libcmt" /out:"../../../bin/osgsequenced.exe" /pdbtype:sept /libpath:"../../../lib"
# SUBTRACT LINK32 /incremental:no
!ENDIF
# Begin Target
# Name "Demo osgsequence - Win32 Release"
# Name "Demo osgsequence - Win32 Debug"
# Begin Source File
SOURCE=..\..\..\src\Demos\osgsequence\osgsequence.cpp
# End Source File
# End Target
# Begin Group "Resource Files"
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
# End Group
# End Project

View File

@@ -1104,6 +1104,60 @@ Package=<4>
Project: "Demo osgsequence"=.\Demos\osgsequence\osgsequence.dsp - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
Begin Project Dependency
Project_Dep_Name Core osg
End Project Dependency
Begin Project Dependency
Project_Dep_Name Core osgDB
End Project Dependency
Begin Project Dependency
Project_Dep_Name Core osgGA
End Project Dependency
Begin Project Dependency
Project_Dep_Name Core osgGLUT
End Project Dependency
Begin Project Dependency
Project_Dep_Name Core osgUtil
End Project Dependency
}}}
###############################################################################
Project: "Demo osgstereoimage"=.\Demos\osgstereoimage\osgstereoimage.dsp - Package Owner=<4>

View File

@@ -329,6 +329,10 @@ SOURCE=..\..\src\osg\Quat.cpp
# End Source File
# Begin Source File
SOURCE=..\..\src\osg\Sequence.cpp
# End Source File
# Begin Source File
SOURCE=..\..\src\osg\ShadeModel.cpp
# End Source File
# Begin Source File
@@ -677,6 +681,10 @@ SOURCE=..\..\Include\Osg\Referenced
# End Source File
# Begin Source File
SOURCE=..\..\Include\Osg\Sequence
# End Source File
# Begin Source File
SOURCE=..\..\Include\Osg\ShadeModel
# End Source File
# Begin Source File

View File

@@ -157,6 +157,14 @@ SOURCE=..\..\..\src\osgPlugins\iv\indexedfaceset.h
# End Source File
# Begin Source File
SOURCE=..\..\..\src\osgPlugins\iv\atrvec3list.h
# End Source File
# Begin Source File
SOURCE=..\..\..\src\osgPlugins\iv\indexedtristripset.h
# End Source File
# Begin Source File
SOURCE=..\..\..\src\osgPlugins\iv\ltstr.h
# End Source File
# Begin Source File

View File

@@ -23,6 +23,7 @@ class Switch;
class Impostor;
class EarthSky;
class OccluderNode;
class Sequence;
/** Visitor for type safe operations on osg::Node's.
Based on GOF's Visitor pattern. The NodeVisitor
@@ -177,6 +178,7 @@ class SG_EXPORT NodeVisitor : public Referenced
virtual void apply(Projection& node) { apply((Group&)node); }
virtual void apply(Transform& node) { apply((Group&)node); }
virtual void apply(Switch& node) { apply((Group&)node); }
virtual void apply(Sequence& node) { apply((Switch&)node); }
virtual void apply(LOD& node) { apply((Group&)node); }
virtual void apply(Impostor& node) { apply((LOD&)node); }
virtual void apply(EarthSky& node) { apply((Group&)node); }

95
include/osg/Sequence Normal file
View File

@@ -0,0 +1,95 @@
// -*-c++-*-
//C++ header - Open Scene Graph - Copyright (C) 1998-2002 Robert Osfield
//Distributed under the terms of the GNU Library General Public License (LGPL)
//as published by the Free Software Foundation.
#ifndef OSG_SEQUENCE
#define OSG_SEQUENCE 1
#include <osg/Switch>
namespace osg {
/** Sequence is a Group node which allows automatic, time based
switching between children.
*/
class SG_EXPORT Sequence : public Switch
{
public :
Sequence();
/** Copy constructor using CopyOp to manage deep vs shallow copy.*/
Sequence(const Sequence&, const CopyOp& copyop=CopyOp::SHALLOW_COPY);
META_Node(osg, Sequence);
virtual void traverse(NodeVisitor& nv);
/** Set time in seconds for child */
void setTime(int frame, float t);
/** Get time for child */
const float getTime(int frame) const;
/** Interval modes */
enum LoopMode {
LOOP,
SWING
};
/** Set sequence mode & interval. */
void setInterval(LoopMode mode, int begin, int end);
/** Get sequence mode & interval. */
inline void getInterval(LoopMode& mode, int& begin, int& end) const {
mode = _loopMode;
begin = _begin;
end = _end;
}
/** Set duration: speed-up & number of repeats */
void setDuration(float speed, int nreps = -1);
/** Get duration */
inline void getDuration(float& speed, int& nreps) const {
speed = _speed;
nreps = _nreps;
}
/** Sequence modes */
enum SequenceMode {
START,
STOP,
PAUSE,
RESUME
};
/** Set sequence mode. Start/stop & pause/resume. */
void setMode(SequenceMode mode);
/** Get sequence mode. */
inline SequenceMode getMode() const { return _mode; }
protected :
virtual ~Sequence() {}
float _last;
std::vector<float> _frameTime;
int _step;
LoopMode _loopMode;
int _begin, _end;
float _speed;
int _nreps, _nrepsremain;
SequenceMode _mode;
};
}
#endif

View File

@@ -0,0 +1,15 @@
TOPDIR = ../../..
include $(TOPDIR)/Make/makedefs
CXXFILES =\
osgsequence.cpp\
LIBS += $(OSG_LIBS) $(GLUT_LIB) $(GL_LIBS) $(X_LIBS) $(OTHER_LIBS)
INSTFILES = \
$(CXXFILES)\
Makefile.inst=Makefile
EXEC = osgsequence
include $(TOPDIR)/Make/makerules

View File

@@ -0,0 +1,11 @@
TOPDIR = ../..
include $(TOPDIR)/Make/makedefs
CXXFILES =\
osgtexture.cpp\
LIBS += $(OSG_LIBS) $(GLUT_LIB) $(GL_LIBS) $(X_LIBS) $(OTHER_LIBS)
EXEC = osgtexture
include $(TOPDIR)/Make/makerules

View File

@@ -0,0 +1,194 @@
// -*-c++-*-
#include <osg/Group>
#include <osg/Sequence>
#include <osg/Transform>
#include <osgDB/ReadFile>
#include <osgGA/TrackballManipulator>
#include <osgGLUT/Viewer>
#include <osgGLUT/glut>
//
// A simple demo demonstrating usage of osg::Sequence.
//
// simple event handler to start/stop sequences
class MyEventHandler : public osgGA::GUIEventHandler {
public:
/// Constructor.
MyEventHandler(std::vector<osg::Sequence*>* seq) : GUIEventHandler() {
_seq = seq;
}
/// Handle events.
virtual bool handle(const osgGA::GUIEventAdapter& ea,
osgGA::GUIActionAdapter&) {
bool handled = false;
if (ea.getEventType() == osgGA::GUIEventAdapter::KEYBOARD) {
const char keys[] = "!@#$%^&*()";
for (unsigned int i = 0; i < (sizeof(keys) / sizeof(keys[0])); i++) {
if (i < _seq->size() && ea.getKey() == keys[i]) {
// toggle sequence
osg::Sequence* seq = (*_seq)[i];
osg::Sequence::SequenceMode mode = seq->getMode();
switch (mode) {
case osg::Sequence::START:
seq->setMode(osg::Sequence::PAUSE);
break;
case osg::Sequence::STOP:
seq->setMode(osg::Sequence::START);
break;
case osg::Sequence::PAUSE:
seq->setMode(osg::Sequence::RESUME);
break;
default:
break;
}
cerr << "Toggled sequence " << i << endl;
handled = true;
}
}
}
return handled;
}
/// accept visits.
virtual void accept(osgGA::GUIEventHandlerVisitor&) { }
private:
std::vector<osg::Sequence*>* _seq;
};
void write_usage(std::ostream& out, const std::string& name)
{
out << std::endl;
out <<"usage:"<< std::endl;
out <<" "<<name<<" [options] infile1 [infile2 ...]"<< std::endl;
out << std::endl;
out <<"options:"<< std::endl;
out <<" -l libraryName - load plugin of name libraryName"<< std::endl;
out <<" i.e. -l osgdb_pfb"<< std::endl;
out <<" Useful for loading reader/writers which can load"<< std::endl;
out <<" other file formats in addition to its extension."<< std::endl;
out <<" -e extensionName - load reader/wrter plugin for file extension"<< std::endl;
out <<" i.e. -e pfb"<< std::endl;
out <<" Useful short hand for specifying full library name as"<< std::endl;
out <<" done with -l above, as it automatically expands to"<< std::endl;
out <<" the full library name appropriate for each platform."<< std::endl;
out<<std::endl;
}
osg::Sequence* generateSeq(osg::Sequence::LoopMode mode,
float speed, int nreps,
std::vector<osg::Node*>& model)
{
osg::Sequence* seqNode = osgNew osg::Sequence;
// add children, show each child for 1.0 seconds
for (unsigned int i = 0; i < model.size(); i++) {
seqNode->addChild(model[i]);
seqNode->setTime(i, 1.0f);
}
// interval
seqNode->setInterval(mode, 0, -1);
// speed-up factor and number of repeats for entire sequence
seqNode->setDuration(speed, nreps);
// stopped
seqNode->setMode(osg::Sequence::STOP);
return seqNode;
}
int main( int argc, char **argv )
{
// initialize the GLUT
glutInit( &argc, argv );
if (argc < 2)
{
write_usage(osg::notify(osg::NOTICE), argv[0]);
return 0;
}
// create commandline args
std::vector<std::string> commandLine;
for (int i = 1; i < argc; i++)
commandLine.push_back(argv[i]);
// initialize the viewer
osgGLUT::Viewer viewer;
viewer.setWindowTitle(argv[0]);
// configure the viewer from the commandline arguments, and eat any
// parameters that have been matched.
viewer.readCommandLine(commandLine);
// assumes any remaining parameters are models
std::vector<osg::Node*> model;
for (unsigned int i = 0; i < commandLine.size(); i++) {
cerr << "Loading " << commandLine[i] << endl;
osg::Node* node = osgDB::readNodeFile(commandLine[i]);
if (node)
model.push_back(node);
}
if (model.empty()) {
write_usage(osg::notify(osg::NOTICE),argv[0]);
return -1;
}
// root
osg::Group* rootNode = osgNew osg::Group;
// create sequences
std::vector<osg::Sequence*> seq;
const osg::Sequence::LoopMode mode[] = { osg::Sequence::LOOP,
osg::Sequence::SWING,
osg::Sequence::LOOP };
const float speed[] = { 0.5f, 1.0f, 1.5f };
const int nreps[] = { -1, 5, 1 };
float x = 0.0f;
for (unsigned int i = 0; i < (sizeof(speed) / sizeof(speed[0])); i++) {
osg::Sequence* seqNode = generateSeq(mode[i], speed[i], nreps[i],
model);
if (!seqNode)
continue;
seq.push_back(seqNode);
// position sequence
osg::Matrix matrix;
matrix.makeTranslate(x, 0.0, 0.0);
osg::Transform* xform = osgNew osg::Transform;
xform->setMatrix(matrix);
xform->addChild(seqNode);
rootNode->addChild(xform);
x += seqNode->getBound()._radius * 1.5f;
}
// add model to viewer.
viewer.addViewport(rootNode);
// register additional event handler
viewer.setEventHandler(osgNew MyEventHandler(&seq), 0);
// register trackball, flight and drive.
viewer.registerCameraManipulator(new osgGA::TrackballManipulator);
viewer.open();
viewer.run();
return 0;
}

View File

@@ -62,6 +62,7 @@ CXXFILES =\
Primitive.cpp\
Projection.cpp\
Quat.cpp\
Sequence.cpp\
ShadeModel.cpp\
ShadowVolumeOccluder.cpp\
State.cpp\
@@ -77,7 +78,7 @@ CXXFILES =\
Transform.cpp\
Version.cpp\
Viewport.cpp\
DEF += -DSG_LIBRARY
LIBS += $(GL_LIBS) $(OTHER_LIBS)

172
src/osg/Sequence.cpp Normal file
View File

@@ -0,0 +1,172 @@
// -*-c++-*-
#include <osg/Sequence>
#include <osgUtil/AppVisitor>
using namespace osg;
/**
* Sequence constructor.
*/
Sequence::Sequence() :
Switch(),
_last(-1.0f),
_step(1)
{
_frameTime.clear();
setInterval(LOOP, 0, -1);
setMode(STOP);
setNumChildrenRequiringAppTraversal(1);
}
Sequence::Sequence(const Sequence& seq, const CopyOp& copyop) :
Switch(seq, copyop),
_last(seq._last),
_frameTime(seq._frameTime),
_step(seq._step)
{
setInterval(seq._loopMode, seq._begin, seq._end);
setDuration(seq._speed, seq._nreps);
setMode(seq._mode);
setNumChildrenRequiringAppTraversal(1);
}
void Sequence::setTime(int frame, float t)
{
int sz = _frameTime.size();
//cerr << "sz=" << sz << " frame=" << frame << endl;
if (frame < sz)
_frameTime[frame] = t;
else
for (int i = sz; i < (frame+1); i++) {
_frameTime.push_back(t);
}
}
const float Sequence::getTime(int frame) const
{
if (frame >= 0 && frame < (int) _frameTime.size())
return _frameTime[frame];
else
return -1.0f;
}
void Sequence::setInterval(LoopMode mode, int begin, int end)
{
_loopMode = mode;
_begin = begin;
_end = end;
// switch to beginning of interval
unsigned int nch = getNumChildren();
begin = (_begin < 0 ? nch + _begin : _begin);
end = (_end < 0 ? nch + _end : _end);
setValue(begin);
_step = (begin < end ? 1 : -1);
}
void Sequence::setDuration(float speed, int nreps)
{
_speed = (speed <= 0.0f ? 0.0f : speed);
_nreps = (nreps < 0 ? -1 : nreps);
_nrepsremain = _nreps;
}
void Sequence::setMode(SequenceMode mode)
{
switch (mode) {
case START:
// restarts sequence in 'traverse'
setValue(ALL_CHILDREN_OFF);
_mode = mode;
break;
case STOP:
_mode = mode;
break;
case PAUSE:
if (_mode == START)
_mode = PAUSE;
break;
case RESUME:
if (_mode == PAUSE)
_mode = START;
break;
}
}
void Sequence::traverse(NodeVisitor& nv)
{
osgUtil::AppVisitor* app = dynamic_cast<osgUtil::AppVisitor*>(&nv);
if (app && _mode == START && _nrepsremain) {
double t = nv.getFrameStamp()->getReferenceTime();
if (_last == -1.0)
_last = t;
// first and last frame of interval
unsigned int nch = getNumChildren();
int begin = (_begin < 0 ? nch + _begin : _begin);
int end = (_end < 0 ? nch + _end : _end);
int sw = getValue();
if (sw == ALL_CHILDREN_OFF || sw == ALL_CHILDREN_ON) {
sw = begin;
_step = (begin < end ? 1 : -1);
}
// default timeout for unset values
if (sw >= (int) _frameTime.size()) {
setTime(sw, 1.0f);
}
// frame time-out?
float dur = _frameTime[sw] * _speed;
if ((t - _last) > dur) {
sw += _step;
// check interval
int ibegin = (begin < end ? begin : end);
int iend = (end > begin ? end : begin);
//cerr << this << " interval " << ibegin << "," << iend << endl;
if (sw < ibegin || sw > iend) {
// stop at last frame
if (sw < ibegin)
sw = ibegin;
else
sw = iend;
// repeat counter
if (_nrepsremain > 0)
_nrepsremain--;
if (_nrepsremain == 0) {
// stop
setMode(STOP);
}
else {
// wrap around
switch (_loopMode) {
case LOOP:
//cerr << this << " loop" << endl;
sw = begin;
break;
case SWING:
//cerr << this << " swing" << endl;
_step = -_step;
break;
}
}
}
_last = t;
}
//cerr << this << " child=" << sw << endl;
setValue(sw);
}
Switch::traverse(nv);
}

View File

@@ -207,6 +207,11 @@ void Texture::dirtyTextureObject()
void Texture::apply(State& state) const
{
// Texture* texture = const_cast<Texture*>(this);
// texture->_min_filter = LINEAR_MIPMAP_LINEAR;
// texture->_mag_filter = ANISOTROPIC;
// get the contextID (user defined ID of 0 upwards) for the
// current OpenGL context.
const uint contextID = state.getContextID();

View File

@@ -108,7 +108,12 @@ DynamicLibrary::PROC_ADDRESS DynamicLibrary::getProcAddress(const std::string& p
return NULL;
}
#else // other unix
return dlsym( _handle, procName.c_str() );
void* sym = dlsym( _handle, procName.c_str() );
if (!sym) {
notify(WARN) << "DynamicLibrary::failed looking up " << procName << std::endl;
notify(WARN) << "DynamicLibrary::error " << dlerror() << std::endl;
}
return sym;
#endif
return NULL;
}

View File

@@ -39,6 +39,7 @@ CXXFILES =\
ReaderWriterOSG.cpp\
ShadeModel.cpp\
StateSet.cpp\
Sequence.cpp\
Stencil.cpp\
Switch.cpp\
TexEnv.cpp\

View File

@@ -0,0 +1,157 @@
#include "osg/Sequence"
#include "osgDB/Registry"
#include "osgDB/Input"
#include "osgDB/Output"
using namespace osg;
using namespace osgDB;
// forward declare functions to use later.
bool Sequence_readLocalData(Object& obj, Input& fr);
bool Sequence_writeLocalData(const Object& obj, Output& fw);
// register the read and write functions with the osgDB::Registry.
RegisterDotOsgWrapperProxy g_SequenceProxy
(
osgNew osg::Sequence,
"Sequence",
"Object Node Group Switch Sequence",
&Sequence_readLocalData,
&Sequence_writeLocalData
);
static bool Sequence_matchLoopMode(const char* str,
Sequence::LoopMode& mode)
{
if (strcmp(str, "LOOP") == 0)
mode = Sequence::LOOP;
else if (strcmp(str, "SWING") == 0)
mode = Sequence::SWING;
else
return false;
return true;
}
static const char* Sequence_getLoopMode(Sequence::LoopMode mode)
{
switch (mode) {
case Sequence::SWING:
return "SWING";
case Sequence::LOOP:
default:
return "LOOP";
}
}
// only storing 'START' and 'STOP' since 'PAUSE' doesn't make sense to me
static bool Sequence_matchSeqMode(const char* str,
Sequence::SequenceMode& mode)
{
if (strcmp(str, "START") == 0)
mode = Sequence::START;
else if (strcmp(str, "STOP") == 0)
mode = Sequence::STOP;
else
return false;
return true;
}
static const char* Sequence_getSeqMode(Sequence::SequenceMode mode)
{
switch (mode) {
case Sequence::START:
return "START";
default:
return "STOP";
}
}
bool Sequence_readLocalData(Object& obj, Input& fr)
{
bool iteratorAdvanced = false;
Sequence& sw = static_cast<Sequence&>(obj);
if (fr.matchSequence("frameTime {")) {
int entry = fr[0].getNoNestedBrackets();
fr += 2;
int i = 0;
while (!fr.eof() && fr[0].getNoNestedBrackets() > entry) {
float t;
if (fr[0].getFloat(t)) {
sw.setTime(i, t);
++fr;
i++;
}
}
iteratorAdvanced = true;
++fr;
}
else if (fr.matchSequence("interval")) {
Sequence::LoopMode mode;
int begin, end;
if (Sequence_matchLoopMode(fr[1].getStr(), mode) &&
fr[2].getInt(begin) && fr[3].getInt(end)) {
sw.setInterval(mode, begin, end);
iteratorAdvanced = true;
fr += 4;
}
}
else if (fr.matchSequence("duration")) {
if (fr[1].isFloat() && fr[2].isInt()) {
float speed;
int nreps;
fr[1].getFloat(speed);
fr[2].getInt(nreps);
sw.setDuration(speed, nreps);
iteratorAdvanced = true;
fr += 3;
}
}
else if (fr.matchSequence("mode")) {
Sequence::SequenceMode mode;
if (Sequence_matchSeqMode(fr[1].getStr(), mode)) {
sw.setMode(mode);
iteratorAdvanced = true;
fr += 2;
}
}
return iteratorAdvanced;
}
bool Sequence_writeLocalData(const Object& obj, Output& fw)
{
const Sequence& sw = static_cast<const Sequence&>(obj);
// frame times
fw.indent() << "frameTime {" << std::endl;
fw.moveIn();
for (unsigned int i = 0; i < sw.getNumChildren(); i++) {
fw.indent() << sw.getTime(i) << std::endl;
}
fw.moveOut();
fw.indent() << "}" << std::endl;
// loop mode & interval
Sequence::LoopMode mode;
int begin, end;
sw.getInterval(mode, begin, end);
fw.indent() << "interval " << Sequence_getLoopMode(mode) << " " << begin << " " << end << std::endl;
// duration
float speed;
int nreps;
sw.getDuration(speed, nreps);
fw.indent() << "duration " << speed << " " << nreps << std::endl;
// sequence mode
fw.indent() << "mode " << Sequence_getSeqMode(sw.getMode()) << std::endl;
return true;
}

View File

@@ -16,6 +16,7 @@
#include <osg/Material>
#include <osg/Notify>
#include <osg/Geometry>
#include <osg/Sequence>
#include <osgDB/FileNameUtils>
#include <osgDB/Registry>
@@ -254,23 +255,25 @@ osg::Node* ConvertFromPerformer::visitSwitch(osg::Group* osgParent,pfSwitch* swi
}
osg::Node* ConvertFromPerformer::visitSequence(osg::Group* osgParent,pfSequence* sequence)
osg::Node* ConvertFromPerformer::visitSequence(osg::Group* osgParent,
pfSequence* sequence)
{
osg::notify(osg::WARN)<<"Warning : cannot convert pfSequence as no osg::Sequence exists, using osg::Switch instead."<<std::endl;
//osg::notify(osg::WARN)<<"Warning : cannot convert pfSequence as no osg::Sequence exists, using osg::Switch instead."<<std::endl;
osg::Switch* osgSequence = dynamic_cast<osg::Switch*>(getOsgObject(sequence));
osg::Sequence* osgSequence = dynamic_cast<osg::Sequence*>(getOsgObject(sequence));
if (osgSequence)
{
if (osgParent) osgParent->addChild(osgSequence);
return osgSequence;
}
osgSequence = new osg::Switch;
osgSequence = new osg::Sequence;
if (osgParent) osgParent->addChild(osgSequence);
registerPfObjectForOsgObject(sequence,osgSequence);
#if 0
if (sequence->getNumChildren()>0)
{
// set switch to first child as a 'hack' to prevent all
@@ -279,11 +282,44 @@ osg::Node* ConvertFromPerformer::visitSequence(osg::Group* osgParent,pfSequence*
// be removed.
osgSequence->setValue(0);
}
#endif
// add children
for(int i=0;i<sequence->getNumChildren();++i)
{
osgSequence->setTime(i, sequence->getTime(i));
visitNode(osgSequence,sequence->getChild(i));
}
// interval
int mode, begin, end;
sequence->getInterval(&mode, &begin, &end);
osg::Sequence::LoopMode loopMode = osg::Sequence::LOOP;
if (mode == PFSEQ_SWING)
loopMode = osg::Sequence::SWING;
osgSequence->setInterval(loopMode, begin, end);
// duration
float speed;
int repeat;
sequence->getDuration(&speed, &repeat);
osgSequence->setDuration(speed, repeat);
// mode
mode = sequence->getMode();
osg::Sequence::SequenceMode seqMode = osg::Sequence::START;
switch (mode) {
case PFSEQ_STOP:
seqMode = osg::Sequence::STOP;
break;
case PFSEQ_PAUSE:
seqMode = osg::Sequence::PAUSE;
break;
}
osgSequence->setMode(seqMode);
return (osg::Node*)osgSequence;
}
@@ -483,6 +519,7 @@ osg::Drawable* ConvertFromPerformer::visitGeoSet(osg::Geode* osgGeode,pfGeoSet*
// and then convert back to a osg::Geometry afterwards.
//osg::ref_ptr<osg::GeoSet> osgGeoSet = new osg::GeoSet;
osg::GeoSet* osgGeoSet = new osg::GeoSet;
osgGeoSet->ref();
int i;
@@ -714,7 +751,7 @@ osg::Drawable* ConvertFromPerformer::visitGeoSet(osg::Geode* osgGeode,pfGeoSet*
osgGeode->addDrawable(osgDrawable);
registerPfObjectForOsgObject(geoset,osgDrawable);
}
osgGeoSet->unref();
return osgDrawable;
}
@@ -1191,7 +1228,7 @@ osg::Texture* ConvertFromPerformer::visitTexture(osg::StateSet* osgStateSet,pfTe
unsigned int dataType = GL_UNSIGNED_BYTE;
// copy image data
int size = s * t * comp;
int size = s * t * r * comp;
unsigned char* data = (unsigned char*) malloc(size);
memcpy(data, imageData, size);

View File

@@ -102,6 +102,7 @@ class ReaderWriterPFB : public osgDB::ReaderWriter
initPerformer();
pfTexture* tex = new pfTexture;
tex->ref();
if (tex->loadFile(fileName.c_str()))
{
int s=0;
@@ -116,23 +117,34 @@ class ReaderWriterPFB : public osgDB::ReaderWriter
unsigned int pixelFormat =
comp == 1 ? GL_LUMINANCE :
comp == 2 ? GL_LUMINANCE_ALPHA :
comp == 3 ? GL_RGB :
comp == 4 ? GL_RGBA : (GLenum)-1;
comp == 2 ? GL_LUMINANCE_ALPHA :
comp == 3 ? GL_RGB :
comp == 4 ? GL_RGBA : (GLenum)-1;
unsigned int dataType = GL_UNSIGNED_BYTE;
// copy image data
int size = s * t * r * comp;
unsigned char* data = (unsigned char*) malloc(size);
memcpy(data, imageData, size);
osg::Image* image = new osg::Image;
image->setFileName(fileName.c_str());
image->setImage(s,t,r,
internalFormat,
pixelFormat,
dataType,
(unsigned char*)imageData);
internalFormat,
pixelFormat,
dataType,
data);
// free texture & image data
tex->unrefDelete();
return image;
}
// free texture & image data
tex->unrefDelete();
return ReadResult::FILE_NOT_HANDLED;
}
@@ -146,12 +158,13 @@ class ReaderWriterPFB : public osgDB::ReaderWriter
initPerformer();
pfNode* root = pfdLoadFile(fileName.c_str());
if (root)
{
root->ref();
ConvertFromPerformer converter;
return converter.convert(root);
osg::Node* node = converter.convert(root);
root->unrefDelete();
return node;
}
else
{