Moved present3D from own repository into core OSG.
This commit is contained in:
parent
ff93371cbd
commit
6399de2897
@ -32,6 +32,9 @@ IF(DYNAMIC_OPENSCENEGRAPH)
|
||||
ADD_SUBDIRECTORY(osgconv)
|
||||
ADD_SUBDIRECTORY(osgfilecache)
|
||||
ADD_SUBDIRECTORY(osgversion)
|
||||
IF(LIBXML2_FOUND)
|
||||
ADD_SUBDIRECTORY(present3D)
|
||||
ENDIF()
|
||||
ELSE()
|
||||
# need to define this on win32 or linker cries about _declspecs
|
||||
ADD_DEFINITIONS(-DOSG_LIBRARY_STATIC)
|
||||
|
235
applications/present3D/AnimationMaterial.cpp
Normal file
235
applications/present3D/AnimationMaterial.cpp
Normal file
@ -0,0 +1,235 @@
|
||||
/* -*-c++-*- Present3D - Copyright (C) 1999-2006 Robert Osfield
|
||||
*
|
||||
* This software is open source and may be redistributed and/or modified under
|
||||
* the terms of the GNU General Public License (GPL) version 2.0.
|
||||
* The full license is in LICENSE.txt file included with this distribution,.
|
||||
*
|
||||
* This software is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* include LICENSE.txt for more details.
|
||||
*/
|
||||
|
||||
#include "AnimationMaterial.h"
|
||||
#include <osg/MatrixTransform>
|
||||
#include <osg/PositionAttitudeTransform>
|
||||
#include <osg/Notify>
|
||||
#include <osg/io_utils>
|
||||
|
||||
using namespace ss3d;
|
||||
|
||||
void AnimationMaterial::insert(double time,osg::Material* material)
|
||||
{
|
||||
_timeControlPointMap[time] = material;
|
||||
}
|
||||
|
||||
bool AnimationMaterial::getMaterial(double time,osg::Material& material) const
|
||||
{
|
||||
if (_timeControlPointMap.empty()) return false;
|
||||
|
||||
switch(_loopMode)
|
||||
{
|
||||
case(SWING):
|
||||
{
|
||||
double modulated_time = (time - getFirstTime())/(getPeriod()*2.0);
|
||||
double fraction_part = modulated_time - floor(modulated_time);
|
||||
if (fraction_part>0.5) fraction_part = 1.0-fraction_part;
|
||||
|
||||
time = getFirstTime()+(fraction_part*2.0) * getPeriod();
|
||||
break;
|
||||
}
|
||||
case(LOOP):
|
||||
{
|
||||
double modulated_time = (time - getFirstTime())/getPeriod();
|
||||
double fraction_part = modulated_time - floor(modulated_time);
|
||||
time = getFirstTime()+fraction_part * getPeriod();
|
||||
break;
|
||||
}
|
||||
case(NO_LOOPING):
|
||||
// no need to modulate the time.
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
|
||||
TimeControlPointMap::const_iterator second = _timeControlPointMap.lower_bound(time);
|
||||
if (second==_timeControlPointMap.begin())
|
||||
{
|
||||
material = *(second->second);
|
||||
}
|
||||
else if (second!=_timeControlPointMap.end())
|
||||
{
|
||||
TimeControlPointMap::const_iterator first = second;
|
||||
--first;
|
||||
|
||||
// we have both a lower bound and the next item.
|
||||
|
||||
// deta_time = second.time - first.time
|
||||
double delta_time = second->first - first->first;
|
||||
|
||||
if (delta_time==0.0)
|
||||
material = *(first->second);
|
||||
else
|
||||
{
|
||||
interpolate(material,(time - first->first)/delta_time, *first->second, *second->second);
|
||||
}
|
||||
}
|
||||
else // (second==_timeControlPointMap.end())
|
||||
{
|
||||
material = *(_timeControlPointMap.rbegin()->second);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
T interp(float r, const T& lhs, const T& rhs)
|
||||
{
|
||||
return lhs*(1.0f-r)+rhs*r;
|
||||
}
|
||||
|
||||
|
||||
void AnimationMaterial::interpolate(osg::Material& material, float r, const osg::Material& lhs,const osg::Material& rhs) const
|
||||
{
|
||||
material.setColorMode(lhs.getColorMode());
|
||||
|
||||
material.setAmbient(osg::Material::FRONT_AND_BACK,interp(r, lhs.getAmbient(osg::Material::FRONT),rhs.getAmbient(osg::Material::FRONT)));
|
||||
if (!material.getAmbientFrontAndBack())
|
||||
material.setAmbient(osg::Material::BACK,interp(r, lhs.getAmbient(osg::Material::BACK),rhs.getAmbient(osg::Material::BACK)));
|
||||
|
||||
material.setDiffuse(osg::Material::FRONT_AND_BACK,interp(r, lhs.getDiffuse(osg::Material::FRONT),rhs.getDiffuse(osg::Material::FRONT)));
|
||||
if (!material.getDiffuseFrontAndBack())
|
||||
material.setDiffuse(osg::Material::BACK,interp(r, lhs.getDiffuse(osg::Material::BACK),rhs.getDiffuse(osg::Material::BACK)));
|
||||
|
||||
material.setSpecular(osg::Material::FRONT_AND_BACK,interp(r, lhs.getSpecular(osg::Material::FRONT),rhs.getSpecular(osg::Material::FRONT)));
|
||||
if (!material.getSpecularFrontAndBack())
|
||||
material.setSpecular(osg::Material::BACK,interp(r, lhs.getSpecular(osg::Material::BACK),rhs.getSpecular(osg::Material::BACK)));
|
||||
|
||||
material.setEmission(osg::Material::FRONT_AND_BACK,interp(r, lhs.getEmission(osg::Material::FRONT),rhs.getEmission(osg::Material::FRONT)));
|
||||
if (!material.getEmissionFrontAndBack())
|
||||
material.setEmission(osg::Material::BACK,interp(r, lhs.getEmission(osg::Material::BACK),rhs.getEmission(osg::Material::BACK)));
|
||||
|
||||
material.setShininess(osg::Material::FRONT_AND_BACK,interp(r, lhs.getShininess(osg::Material::FRONT),rhs.getShininess(osg::Material::FRONT)));
|
||||
if (!material.getShininessFrontAndBack())
|
||||
material.setShininess(osg::Material::BACK,interp(r, lhs.getShininess(osg::Material::BACK),rhs.getShininess(osg::Material::BACK)));
|
||||
}
|
||||
|
||||
void AnimationMaterial::read(std::istream& in)
|
||||
{
|
||||
while (!in.eof())
|
||||
{
|
||||
double time;
|
||||
osg::Vec4 color;
|
||||
in >> time >> color[0] >> color[1] >> color[2] >> color[3];
|
||||
if(!in.eof())
|
||||
{
|
||||
osg::Material* material = new osg::Material;
|
||||
material->setAmbient(osg::Material::FRONT_AND_BACK,color);
|
||||
material->setDiffuse(osg::Material::FRONT_AND_BACK,color);
|
||||
insert(time,material);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AnimationMaterial::write(std::ostream& fout) const
|
||||
{
|
||||
const TimeControlPointMap& tcpm = getTimeControlPointMap();
|
||||
for(TimeControlPointMap::const_iterator tcpmitr=tcpm.begin();
|
||||
tcpmitr!=tcpm.end();
|
||||
++tcpmitr)
|
||||
{
|
||||
fout<<tcpmitr->first<<" "<<tcpmitr->second->getDiffuse(osg::Material::FRONT)<<std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
bool AnimationMaterial::requiresBlending() const
|
||||
{
|
||||
const TimeControlPointMap& tcpm = getTimeControlPointMap();
|
||||
for(TimeControlPointMap::const_iterator tcpmitr=tcpm.begin();
|
||||
tcpmitr!=tcpm.end();
|
||||
++tcpmitr)
|
||||
{
|
||||
if ((tcpmitr->second->getDiffuse(osg::Material::FRONT))[3]!=1.0f) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void AnimationMaterialCallback::operator()(osg::Node* node, osg::NodeVisitor* nv)
|
||||
{
|
||||
if (_animationMaterial.valid() &&
|
||||
nv->getVisitorType()==osg::NodeVisitor::UPDATE_VISITOR &&
|
||||
nv->getFrameStamp())
|
||||
{
|
||||
double time = nv->getFrameStamp()->getReferenceTime();
|
||||
_latestTime = time;
|
||||
|
||||
if (!_pause)
|
||||
{
|
||||
// Only update _firstTime the first time, when its value is still DBL_MAX
|
||||
if (_firstTime==DBL_MAX)
|
||||
{
|
||||
osg::notify(osg::INFO)<<"AnimationMaterialCallback::operator() resetting _firstTime to "<<time<<std::endl;
|
||||
_firstTime = time;
|
||||
}
|
||||
update(*node);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// must call any nested node callbacks and continue subgraph traversal.
|
||||
NodeCallback::traverse(node,nv);
|
||||
}
|
||||
|
||||
double AnimationMaterialCallback::getAnimationTime() const
|
||||
{
|
||||
if (_firstTime==DBL_MAX) return 0.0f;
|
||||
else return ((_latestTime-_firstTime)-_timeOffset)*_timeMultiplier;
|
||||
}
|
||||
|
||||
void AnimationMaterialCallback::update(osg::Node& node)
|
||||
{
|
||||
osg::StateSet* stateset = node.getOrCreateStateSet();
|
||||
osg::Material* material =
|
||||
dynamic_cast<osg::Material*>(stateset->getAttribute(osg::StateAttribute::MATERIAL));
|
||||
|
||||
if (!material)
|
||||
{
|
||||
material = new osg::Material;
|
||||
stateset->setAttribute(material,osg::StateAttribute::OVERRIDE);
|
||||
}
|
||||
|
||||
_animationMaterial->getMaterial(getAnimationTime(),*material);
|
||||
}
|
||||
|
||||
|
||||
void AnimationMaterialCallback::reset()
|
||||
{
|
||||
#if 1
|
||||
_firstTime = DBL_MAX;
|
||||
_pauseTime = DBL_MAX;
|
||||
#else
|
||||
_firstTime = _latestTime;
|
||||
_pauseTime = _latestTime;
|
||||
#endif
|
||||
}
|
||||
|
||||
void AnimationMaterialCallback::setPause(bool pause)
|
||||
{
|
||||
if (_pause==pause)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_pause = pause;
|
||||
|
||||
if (_firstTime==DBL_MAX) return;
|
||||
|
||||
if (_pause)
|
||||
{
|
||||
_pauseTime = _latestTime;
|
||||
}
|
||||
else
|
||||
{
|
||||
_firstTime += (_latestTime-_pauseTime);
|
||||
}
|
||||
}
|
170
applications/present3D/AnimationMaterial.h
Normal file
170
applications/present3D/AnimationMaterial.h
Normal file
@ -0,0 +1,170 @@
|
||||
/* -*-c++-*- Present3D - Copyright (C) 1999-2006 Robert Osfield
|
||||
*
|
||||
* This software is open source and may be redistributed and/or modified under
|
||||
* the terms of the GNU General Public License (GPL) version 2.0.
|
||||
* The full license is in LICENSE.txt file included with this distribution,.
|
||||
*
|
||||
* This software is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* include LICENSE.txt for more details.
|
||||
*/
|
||||
|
||||
#ifndef OSG_ANIMATIONMATERIAL
|
||||
#define OSG_ANIMATIONMATERIAL 1
|
||||
|
||||
#include <osg/Material>
|
||||
#include <osg/NodeCallback>
|
||||
|
||||
#include <map>
|
||||
#include <float.h>
|
||||
|
||||
namespace ss3d {
|
||||
|
||||
/** AnimationMaterial for specify the time varying transformation pathway to use when update camera and model objects.
|
||||
* Subclassed from Transform::ComputeTransformCallback allows AnimationMaterial to
|
||||
* be attached directly to Transform nodes to move subgraphs around the scene.
|
||||
*/
|
||||
class AnimationMaterial : public virtual osg::Object
|
||||
{
|
||||
public:
|
||||
|
||||
AnimationMaterial():_loopMode(LOOP) {}
|
||||
|
||||
AnimationMaterial(const AnimationMaterial& ap, const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY):
|
||||
Object(ap,copyop),
|
||||
_timeControlPointMap(ap._timeControlPointMap),
|
||||
_loopMode(ap._loopMode) {}
|
||||
|
||||
META_Object(osg,AnimationMaterial);
|
||||
|
||||
|
||||
/** get the transformation matrix for a point in time.*/
|
||||
bool getMaterial(double time,osg::Material& material) const;
|
||||
|
||||
void insert(double time,osg::Material* material);
|
||||
|
||||
double getFirstTime() const { if (!_timeControlPointMap.empty()) return _timeControlPointMap.begin()->first; else return 0.0;}
|
||||
double getLastTime() const { if (!_timeControlPointMap.empty()) return _timeControlPointMap.rbegin()->first; else return 0.0;}
|
||||
double getPeriod() const { return getLastTime()-getFirstTime();}
|
||||
|
||||
enum LoopMode
|
||||
{
|
||||
SWING,
|
||||
LOOP,
|
||||
NO_LOOPING
|
||||
};
|
||||
|
||||
void setLoopMode(LoopMode lm) { _loopMode = lm; }
|
||||
|
||||
LoopMode getLoopMode() const { return _loopMode; }
|
||||
|
||||
|
||||
typedef std::map<double, osg::ref_ptr<osg::Material> > TimeControlPointMap;
|
||||
|
||||
TimeControlPointMap& getTimeControlPointMap() { return _timeControlPointMap; }
|
||||
|
||||
const TimeControlPointMap& getTimeControlPointMap() const { return _timeControlPointMap; }
|
||||
|
||||
/** read the anumation path from a flat ascii file stream.*/
|
||||
void read(std::istream& in);
|
||||
|
||||
/** write the anumation path to a flat ascii file stream.*/
|
||||
void write(std::ostream& out) const;
|
||||
|
||||
bool requiresBlending() const;
|
||||
|
||||
protected:
|
||||
|
||||
virtual ~AnimationMaterial() {}
|
||||
|
||||
void interpolate(osg::Material& material, float r, const osg::Material& lhs,const osg::Material& rhs) const;
|
||||
|
||||
TimeControlPointMap _timeControlPointMap;
|
||||
LoopMode _loopMode;
|
||||
|
||||
};
|
||||
|
||||
|
||||
class AnimationMaterialCallback : public osg::NodeCallback
|
||||
{
|
||||
public:
|
||||
|
||||
AnimationMaterialCallback():
|
||||
_timeOffset(0.0),
|
||||
_timeMultiplier(1.0),
|
||||
_firstTime(DBL_MAX),
|
||||
_latestTime(0.0),
|
||||
_pause(false),
|
||||
_pauseTime(0.0) {}
|
||||
|
||||
|
||||
AnimationMaterialCallback(const AnimationMaterialCallback& apc,const osg::CopyOp& copyop):
|
||||
osg::NodeCallback(apc,copyop),
|
||||
_animationMaterial(apc._animationMaterial),
|
||||
_useInverseMatrix(apc._useInverseMatrix),
|
||||
_timeOffset(apc._timeOffset),
|
||||
_timeMultiplier(apc._timeMultiplier),
|
||||
_firstTime(apc._firstTime),
|
||||
_latestTime(apc._latestTime),
|
||||
_pause(apc._pause),
|
||||
_pauseTime(apc._pauseTime) {}
|
||||
|
||||
|
||||
META_Object(osg,AnimationMaterialCallback);
|
||||
|
||||
AnimationMaterialCallback(AnimationMaterial* ap,double timeOffset=0.0f,double timeMultiplier=1.0f):
|
||||
_animationMaterial(ap),
|
||||
_useInverseMatrix(false),
|
||||
_timeOffset(timeOffset),
|
||||
_timeMultiplier(timeMultiplier),
|
||||
_firstTime(DBL_MAX),
|
||||
_latestTime(0.0),
|
||||
_pause(false),
|
||||
_pauseTime(0.0) {}
|
||||
|
||||
void setAnimationMaterial(AnimationMaterial* path) { _animationMaterial = path; }
|
||||
|
||||
AnimationMaterial* getAnimationMaterial() { return _animationMaterial.get(); }
|
||||
|
||||
const AnimationMaterial* getAnimationMaterial() const { return _animationMaterial.get(); }
|
||||
|
||||
void setTimeOffset(double offset) { _timeOffset = offset; }
|
||||
double getTimeOffset() const { return _timeOffset; }
|
||||
|
||||
void setTimeMultiplier(double multiplier) { _timeMultiplier = multiplier; }
|
||||
double getTimeMultiplier() const { return _timeMultiplier; }
|
||||
|
||||
void reset();
|
||||
|
||||
void setPause(bool pause);
|
||||
|
||||
/** get the animation time that is used to specify the position along the AnimationMaterial.
|
||||
* Animation time is computed from the formula ((_latestTime-_firstTime)-_timeOffset)*_timeMultiplier.*/
|
||||
double getAnimationTime() const;
|
||||
|
||||
/** implements the callback*/
|
||||
virtual void operator()(osg::Node* node, osg::NodeVisitor* nv);
|
||||
|
||||
void update(osg::Node& node);
|
||||
|
||||
public:
|
||||
|
||||
osg::ref_ptr<AnimationMaterial> _animationMaterial;
|
||||
bool _useInverseMatrix;
|
||||
double _timeOffset;
|
||||
double _timeMultiplier;
|
||||
double _firstTime;
|
||||
double _latestTime;
|
||||
bool _pause;
|
||||
double _pauseTime;
|
||||
|
||||
protected:
|
||||
|
||||
~AnimationMaterialCallback(){}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
59
applications/present3D/CMakeLists.txt
Normal file
59
applications/present3D/CMakeLists.txt
Normal file
@ -0,0 +1,59 @@
|
||||
INCLUDE_DIRECTORIES(${LIBXML2_INCLUDE_DIR} )
|
||||
SET(TARGET_EXTERNAL_LIBRARIES ${LIBXML2_LIBRARIES})
|
||||
|
||||
SET(TARGET_SRC
|
||||
AnimationMaterial.h
|
||||
Cluster.h
|
||||
CompileSlideCallback.h
|
||||
ExportHTML.h
|
||||
PickEventHandler.h
|
||||
PointsEventHandler.h
|
||||
ReadShowFile.h
|
||||
ShowEventHandler.h
|
||||
SlideEventHandler.h
|
||||
SlideShowConstructor.h
|
||||
)
|
||||
|
||||
SET(TARGET_H
|
||||
AnimationMaterial.cpp
|
||||
Cluster.cpp
|
||||
CompileSlideCallback.cpp
|
||||
ExportHTML.cpp
|
||||
PickEventHandler.cpp
|
||||
PointsEventHandler.cpp
|
||||
present3D.cpp
|
||||
ReaderWriterXML.cpp
|
||||
ReadShowFile.cpp
|
||||
ShowEventHandler.cpp
|
||||
SlideEventHandler.cpp
|
||||
SlideShowConstructor.cpp
|
||||
)
|
||||
|
||||
IF (SDL_FOUND)
|
||||
|
||||
OPTION(BUILD_WITH_SDL "Set to ON to build with SDL for joystick support." OFF)
|
||||
|
||||
IF (BUILD_WITH_SDL)
|
||||
|
||||
SET(TARGET_ADDED_LIBRARIES ${TARGET_ADDED_LIBRARIES} ${SDL_LIBRARY})
|
||||
SET(EXTERNAL_INCLUDE_DIRS ${EXTERNAL_INCLUDE_DIRS} ${SDL_INCLUDE_DIR})
|
||||
|
||||
SET(TARGET_SRC
|
||||
${TARGET_SRC}
|
||||
SDLIntegration.cpp
|
||||
)
|
||||
|
||||
SET(TARGET_H
|
||||
${TARGET_H}
|
||||
SDLIntegration.h
|
||||
)
|
||||
|
||||
ADD_DEFINITIONS(-DUSE_SDL)
|
||||
|
||||
ENDIF(BUILD_WITH_SDL)
|
||||
|
||||
ENDIF(SDL_FOUND)
|
||||
|
||||
SET(TARGET_ADDED_LIBRARIES osgVolume osgFX)
|
||||
|
||||
SETUP_APPLICATION(present3D)
|
523
applications/present3D/Cluster.cpp
Normal file
523
applications/present3D/Cluster.cpp
Normal file
@ -0,0 +1,523 @@
|
||||
/* -*-c++-*- Present3D - Copyright (C) 1999-2006 Robert Osfield
|
||||
*
|
||||
* This software is open source and may be redistributed and/or modified under
|
||||
* the terms of the GNU General Public License (GPL) version 2.0.
|
||||
* The full license is in LICENSE.txt file included with this distribution,.
|
||||
*
|
||||
* This software is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* include LICENSE.txt for more details.
|
||||
*/
|
||||
|
||||
#include "Cluster.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#if !defined (WIN32) || defined(__CYGWIN__)
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/uio.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netdb.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <sys/time.h>
|
||||
#include <net/if.h>
|
||||
#include <netdb.h>
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#if defined(__linux)
|
||||
#include <unistd.h>
|
||||
#include <linux/sockios.h>
|
||||
#elif defined(__FreeBSD__)
|
||||
#include <unistd.h>
|
||||
#include <sys/sockio.h>
|
||||
#elif defined(__sgi)
|
||||
#include <unistd.h>
|
||||
#include <net/soioctl.h>
|
||||
#elif defined(__CYGWIN__)
|
||||
#include <unistd.h>
|
||||
#elif defined(__sun)
|
||||
#include <unistd.h>
|
||||
#include <sys/sockio.h>
|
||||
#elif defined (__APPLE__)
|
||||
#include <unistd.h>
|
||||
#include <sys/sockio.h>
|
||||
#elif defined (WIN32)
|
||||
#include <winsock.h>
|
||||
#include <stdio.h>
|
||||
#elif defined (__hpux__)
|
||||
#include <unistd.h>
|
||||
#else
|
||||
#error Teach me how to build on this system
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
#if defined (WIN32) && !defined(__CYGWIN__)
|
||||
#include <winsock.h>
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#include <sys/uio.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netdb.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
#include <string.h>
|
||||
|
||||
#include <osg/io_utils>
|
||||
#include <iostream>
|
||||
|
||||
const unsigned int CameraPacket::MAX_NUM_EVENTS = 10;
|
||||
const unsigned int CameraPacket::SWAP_BYTES_COMPARE = 0x12345678;
|
||||
|
||||
void DataConverter::write(const osg::FrameStamp& fs)
|
||||
{
|
||||
osg::notify(osg::NOTICE)<<"writeFramestamp = "<<fs.getFrameNumber()<<" "<<fs.getReferenceTime()<<std::endl;
|
||||
|
||||
writeUInt(fs.getFrameNumber());
|
||||
writeDouble(fs.getReferenceTime());
|
||||
}
|
||||
|
||||
void DataConverter::read(osg::FrameStamp& fs)
|
||||
{
|
||||
fs.setFrameNumber(readUInt());
|
||||
fs.setReferenceTime(readDouble());
|
||||
|
||||
osg::notify(osg::NOTICE)<<"readFramestamp = "<<fs.getFrameNumber()<<" "<<fs.getReferenceTime()<<std::endl;
|
||||
}
|
||||
|
||||
void DataConverter::write(const osg::Matrix& matrix)
|
||||
{
|
||||
writeDouble(matrix(0,0));
|
||||
writeDouble(matrix(0,1));
|
||||
writeDouble(matrix(0,2));
|
||||
writeDouble(matrix(0,3));
|
||||
|
||||
writeDouble(matrix(1,0));
|
||||
writeDouble(matrix(1,1));
|
||||
writeDouble(matrix(1,2));
|
||||
writeDouble(matrix(1,3));
|
||||
|
||||
writeDouble(matrix(2,0));
|
||||
writeDouble(matrix(2,1));
|
||||
writeDouble(matrix(2,2));
|
||||
writeDouble(matrix(2,3));
|
||||
|
||||
writeDouble(matrix(3,0));
|
||||
writeDouble(matrix(3,1));
|
||||
writeDouble(matrix(3,2));
|
||||
writeDouble(matrix(3,3));
|
||||
|
||||
osg::notify(osg::NOTICE)<<"writeMatrix = "<<matrix<<std::endl;
|
||||
|
||||
}
|
||||
|
||||
void DataConverter::read(osg::Matrix& matrix)
|
||||
{
|
||||
matrix(0,0) = readDouble();
|
||||
matrix(0,1) = readDouble();
|
||||
matrix(0,2) = readDouble();
|
||||
matrix(0,3) = readDouble();
|
||||
|
||||
matrix(1,0) = readDouble();
|
||||
matrix(1,1) = readDouble();
|
||||
matrix(1,2) = readDouble();
|
||||
matrix(1,3) = readDouble();
|
||||
|
||||
matrix(2,0) = readDouble();
|
||||
matrix(2,1) = readDouble();
|
||||
matrix(2,2) = readDouble();
|
||||
matrix(2,3) = readDouble();
|
||||
|
||||
matrix(3,0) = readDouble();
|
||||
matrix(3,1) = readDouble();
|
||||
matrix(3,2) = readDouble();
|
||||
matrix(3,3) = readDouble();
|
||||
|
||||
osg::notify(osg::NOTICE)<<"readMatrix = "<<matrix<<std::endl;
|
||||
|
||||
}
|
||||
|
||||
void DataConverter::write(const osgGA::GUIEventAdapter& event)
|
||||
{
|
||||
writeUInt(event.getEventType());
|
||||
writeUInt(event.getKey());
|
||||
writeUInt(event.getButton());
|
||||
writeInt(event.getWindowX());
|
||||
writeInt(event.getWindowY());
|
||||
writeUInt(event.getWindowWidth());
|
||||
writeUInt(event.getWindowHeight());
|
||||
writeFloat(event.getXmin());
|
||||
writeFloat(event.getYmin());
|
||||
writeFloat(event.getXmax());
|
||||
writeFloat(event.getYmax());
|
||||
writeFloat(event.getX());
|
||||
writeFloat(event.getY());
|
||||
writeUInt(event.getButtonMask());
|
||||
writeUInt(event.getModKeyMask());
|
||||
writeDouble(event.getTime());
|
||||
}
|
||||
|
||||
void DataConverter::read(osgGA::GUIEventAdapter& event)
|
||||
{
|
||||
event.setEventType((osgGA::GUIEventAdapter::EventType)readUInt());
|
||||
event.setKey(readUInt());
|
||||
event.setButton(readUInt());
|
||||
int x = readInt();
|
||||
int y = readInt();
|
||||
int width = readUInt();
|
||||
int height = readUInt();
|
||||
event.setWindowRectangle(x,y,width,height);
|
||||
float xmin = readFloat();
|
||||
float ymin = readFloat();
|
||||
float xmax = readFloat();
|
||||
float ymax = readFloat();
|
||||
event.setInputRange(xmin,ymin,xmax,ymax);
|
||||
event.setX(readFloat());
|
||||
event.setY(readFloat());
|
||||
event.setButtonMask(readUInt());
|
||||
event.setModKeyMask(readUInt());
|
||||
event.setTime(readDouble());
|
||||
}
|
||||
|
||||
void DataConverter::write(CameraPacket& cameraPacket)
|
||||
{
|
||||
writeUInt(cameraPacket._byte_order);
|
||||
|
||||
writeUInt(cameraPacket._masterKilled);
|
||||
|
||||
write(cameraPacket._matrix);
|
||||
write(cameraPacket._frameStamp);
|
||||
|
||||
writeUInt(cameraPacket._events.size());
|
||||
for(osgGA::EventQueue::Events::iterator itr = cameraPacket._events.begin();
|
||||
itr != cameraPacket._events.end();
|
||||
++itr)
|
||||
{
|
||||
write(*(*itr));
|
||||
}
|
||||
}
|
||||
|
||||
void DataConverter::read(CameraPacket& cameraPacket)
|
||||
{
|
||||
cameraPacket._byte_order = readUInt();
|
||||
if (cameraPacket._byte_order != CameraPacket::SWAP_BYTES_COMPARE)
|
||||
{
|
||||
_swapBytes = !_swapBytes;
|
||||
}
|
||||
|
||||
cameraPacket._masterKilled = readUInt();
|
||||
|
||||
read(cameraPacket._matrix);
|
||||
read(cameraPacket._frameStamp);
|
||||
|
||||
cameraPacket._events.clear();
|
||||
unsigned int numEvents = readUInt();
|
||||
for(unsigned int i=0;i<numEvents;++i)
|
||||
{
|
||||
osgGA::GUIEventAdapter* event = new osgGA::GUIEventAdapter;
|
||||
read(*(event));
|
||||
cameraPacket._events.push_back(event);
|
||||
}
|
||||
}
|
||||
|
||||
void CameraPacket::readEventQueue(osgViewer::Viewer& viewer)
|
||||
{
|
||||
_events.clear();
|
||||
|
||||
viewer.getEventQueue()->copyEvents(_events);
|
||||
|
||||
osg::notify(osg::INFO)<<"written events = "<<_events.size()<<std::endl;
|
||||
}
|
||||
|
||||
void CameraPacket::writeEventQueue(osgViewer::Viewer& viewer)
|
||||
{
|
||||
osg::notify(osg::INFO)<<"recieved events = "<<_events.size()<<std::endl;
|
||||
|
||||
// copy the events to osgProducer style events.
|
||||
viewer.getEventQueue()->appendEvents(_events);
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Reciever
|
||||
//
|
||||
Receiver::Receiver( void )
|
||||
{
|
||||
_port = 0;
|
||||
_initialized = false;
|
||||
_buffer = 0L;
|
||||
}
|
||||
|
||||
Receiver::~Receiver( void )
|
||||
{
|
||||
#if defined (WIN32) && !defined(__CYGWIN__)
|
||||
closesocket( _so);
|
||||
#else
|
||||
close( _so );
|
||||
#endif
|
||||
}
|
||||
|
||||
bool Receiver::init( void )
|
||||
{
|
||||
#if defined(WIN32) && !defined(__CYGWIN__)
|
||||
WORD version = MAKEWORD(1,1);
|
||||
WSADATA wsaData;
|
||||
// First, we start up Winsock
|
||||
WSAStartup(version, &wsaData);
|
||||
#endif
|
||||
|
||||
if( _port == 0 )
|
||||
{
|
||||
fprintf( stderr, "Receiver::init() - port not defined\n" );
|
||||
return false;
|
||||
}
|
||||
|
||||
if( (_so = socket( AF_INET, SOCK_DGRAM, 0 )) < 0 )
|
||||
{
|
||||
perror( "Socket" );
|
||||
return false;
|
||||
}
|
||||
#if defined (WIN32) && !defined(__CYGWIN__)
|
||||
// const BOOL on = TRUE;
|
||||
// setsockopt( _so, SOL_SOCKET, SO_REUSEADDR, (const char*) &on, sizeof(int));
|
||||
#else
|
||||
int on = 1;
|
||||
setsockopt( _so, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
|
||||
#endif
|
||||
|
||||
// struct sockaddr_in saddr;
|
||||
saddr.sin_family = AF_INET;
|
||||
saddr.sin_port = htons( _port );
|
||||
#if defined (WIN32) && !defined(__CYGWIN__)
|
||||
saddr.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
#else
|
||||
saddr.sin_addr.s_addr = 0;
|
||||
#endif
|
||||
|
||||
if( bind( _so, (struct sockaddr *)&saddr, sizeof( saddr )) < 0 )
|
||||
{
|
||||
perror( "bind" );
|
||||
return false;
|
||||
}
|
||||
|
||||
_initialized = true;
|
||||
return _initialized;
|
||||
}
|
||||
|
||||
|
||||
void Receiver::setPort( const short port )
|
||||
{
|
||||
_port = port;
|
||||
}
|
||||
|
||||
void Receiver::setBuffer( void *buffer, const unsigned int size )
|
||||
{
|
||||
_buffer = buffer;
|
||||
_buffer_size = size;
|
||||
}
|
||||
|
||||
void Receiver::sync( void )
|
||||
{
|
||||
if(!_initialized) init();
|
||||
|
||||
if( _buffer == 0L )
|
||||
{
|
||||
fprintf( stderr, "Receiver::sync() - No buffer\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
#if defined(__linux) || defined(__FreeBSD__) || defined( __APPLE__ )
|
||||
socklen_t
|
||||
#else
|
||||
int
|
||||
#endif
|
||||
size = sizeof( struct sockaddr_in );
|
||||
|
||||
fd_set fdset;
|
||||
FD_ZERO( &fdset );
|
||||
FD_SET( _so, &fdset );
|
||||
|
||||
struct timeval tv;
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = 0;
|
||||
|
||||
#if defined (WIN32) && !defined(__CYGWIN__)
|
||||
// saddr.sin_port = htons( _port );
|
||||
recvfrom( _so, (char *)_buffer, _buffer_size, 0, (sockaddr*)&saddr, &size );
|
||||
// recvfrom(sock_Receive, szMessage, 256, 0, (sockaddr*)&addr_Cli, &clilen)
|
||||
int err = WSAGetLastError ();
|
||||
int *dum = (int*) _buffer;
|
||||
|
||||
while( select( _so+1, &fdset, 0L, 0L, &tv ) )
|
||||
{
|
||||
if( FD_ISSET( _so, &fdset ) )
|
||||
{
|
||||
recvfrom( _so, (char *)_buffer, _buffer_size, 0, (sockaddr*)&saddr, &size );
|
||||
}
|
||||
}
|
||||
#else
|
||||
recvfrom( _so, (caddr_t)_buffer, _buffer_size, 0, 0, &size );
|
||||
while( select( _so+1, &fdset, 0L, 0L, &tv ) )
|
||||
{
|
||||
if( FD_ISSET( _so, &fdset ) )
|
||||
{
|
||||
recvfrom( _so, (caddr_t)_buffer, _buffer_size, 0, 0, &size );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Broadcaster
|
||||
//
|
||||
Broadcaster::Broadcaster( void )
|
||||
{
|
||||
_port = 0;
|
||||
_initialized = false;
|
||||
_buffer = 0L;
|
||||
_address = 0;
|
||||
}
|
||||
|
||||
Broadcaster::~Broadcaster( void )
|
||||
{
|
||||
#if defined (WIN32) && !defined(__CYGWIN__)
|
||||
closesocket( _so);
|
||||
#else
|
||||
close( _so );
|
||||
#endif
|
||||
}
|
||||
|
||||
bool Broadcaster::init( void )
|
||||
{
|
||||
#if defined (WIN32) && !defined(__CYGWIN__)
|
||||
WORD version = MAKEWORD(1,1);
|
||||
WSADATA wsaData;
|
||||
// First, we start up Winsock
|
||||
WSAStartup(version, &wsaData);
|
||||
#endif
|
||||
|
||||
if( _port == 0 )
|
||||
{
|
||||
fprintf( stderr, "Broadcaster::init() - port not defined\n" );
|
||||
return false;
|
||||
}
|
||||
|
||||
if( (_so = socket( AF_INET, SOCK_DGRAM, 0 )) < 0 )
|
||||
{
|
||||
perror( "Socket" );
|
||||
return false;
|
||||
}
|
||||
#if defined (WIN32) && !defined(__CYGWIN__)
|
||||
const BOOL on = TRUE;
|
||||
#else
|
||||
int on = 1;
|
||||
#endif
|
||||
|
||||
#if defined (WIN32) && !defined(__CYGWIN__)
|
||||
setsockopt( _so, SOL_SOCKET, SO_REUSEADDR, (const char *) &on, sizeof(int));
|
||||
#else
|
||||
setsockopt( _so, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
|
||||
#endif
|
||||
|
||||
saddr.sin_family = AF_INET;
|
||||
saddr.sin_port = htons( _port );
|
||||
if( _address == 0 )
|
||||
{
|
||||
#if defined (WIN32) && !defined(__CYGWIN__)
|
||||
setsockopt( _so, SOL_SOCKET, SO_BROADCAST, (const char *) &on, sizeof(int));
|
||||
#else
|
||||
setsockopt( _so, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on));
|
||||
#endif
|
||||
|
||||
#if !defined (WIN32) || defined(__CYGWIN__)
|
||||
struct ifreq ifr;
|
||||
#endif
|
||||
#if defined (__linux) || defined(__CYGWIN__)
|
||||
strcpy( ifr.ifr_name, "eth0" );
|
||||
#elif defined(__sun)
|
||||
strcpy( ifr.ifr_name, "hme0" );
|
||||
#elif !defined (WIN32)
|
||||
strcpy( ifr.ifr_name, "ef0" );
|
||||
#endif
|
||||
#if defined (WIN32) // get the server address
|
||||
saddr.sin_addr.s_addr = htonl(INADDR_BROADCAST);
|
||||
}
|
||||
#else
|
||||
if( (ioctl( _so, SIOCGIFBRDADDR, &ifr)) < 0 )
|
||||
{
|
||||
perror( "Broadcaster::init() Cannot get Broadcast Address" );
|
||||
return false;
|
||||
}
|
||||
saddr.sin_addr.s_addr = (((sockaddr_in *)&ifr.ifr_broadaddr)->sin_addr.s_addr);
|
||||
}
|
||||
else
|
||||
{
|
||||
saddr.sin_addr.s_addr = _address;
|
||||
}
|
||||
#endif
|
||||
#define _VERBOSE 1
|
||||
#ifdef _VERBOSE
|
||||
unsigned char *ptr = (unsigned char *)&saddr.sin_addr.s_addr;
|
||||
printf( "Broadcast address : %u.%u.%u.%u\n", ptr[0], ptr[1], ptr[2], ptr[3] );
|
||||
#endif
|
||||
|
||||
_initialized = true;
|
||||
return _initialized;
|
||||
}
|
||||
|
||||
void Broadcaster::setHost( const char *hostname )
|
||||
{
|
||||
struct hostent *h;
|
||||
if( (h = gethostbyname( hostname )) == 0L )
|
||||
{
|
||||
fprintf( stderr, "Broadcaster::setHost() - Cannot resolv an address for \"%s\".\n", hostname );
|
||||
_address = 0;
|
||||
}
|
||||
else
|
||||
_address = *(( unsigned long *)h->h_addr);
|
||||
}
|
||||
|
||||
void Broadcaster::setPort( const short port )
|
||||
{
|
||||
_port = port;
|
||||
}
|
||||
|
||||
void Broadcaster::setBuffer( void *buffer, const unsigned int size )
|
||||
{
|
||||
_buffer = buffer;
|
||||
_buffer_size = size;
|
||||
}
|
||||
|
||||
void Broadcaster::sync( void )
|
||||
{
|
||||
if(!_initialized) init();
|
||||
|
||||
if( _buffer == 0L )
|
||||
{
|
||||
fprintf( stderr, "Broadcaster::sync() - No buffer\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
#if defined (WIN32) && !defined(__CYGWIN__)
|
||||
unsigned int size = sizeof( SOCKADDR_IN );
|
||||
sendto( _so, (const char *)_buffer, _buffer_size, 0, (struct sockaddr *)&saddr, size );
|
||||
int err = WSAGetLastError ();
|
||||
int *dum = (int*) _buffer;
|
||||
#else
|
||||
unsigned int size = sizeof( struct sockaddr_in );
|
||||
sendto( _so, (const void *)_buffer, _buffer_size, 0, (struct sockaddr *)&saddr, size );
|
||||
#endif
|
||||
|
||||
}
|
334
applications/present3D/Cluster.h
Normal file
334
applications/present3D/Cluster.h
Normal file
@ -0,0 +1,334 @@
|
||||
/* -*-c++-*- Present3D - Copyright (C) 1999-2006 Robert Osfield
|
||||
*
|
||||
* This software is open source and may be redistributed and/or modified under
|
||||
* the terms of the GNU General Public License (GPL) version 2.0.
|
||||
* The full license is in LICENSE.txt file included with this distribution,.
|
||||
*
|
||||
* This software is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* include LICENSE.txt for more details.
|
||||
*/
|
||||
|
||||
#ifndef CLUSTER_H
|
||||
#define CLUSTER_H
|
||||
|
||||
#include <osg/Matrix>
|
||||
#include <osg/FrameStamp>
|
||||
|
||||
#include <osgViewer/Viewer>
|
||||
|
||||
#if !defined(WIN32) || defined(__CYGWIN__)
|
||||
#include <netinet/in.h>
|
||||
#else
|
||||
#include "winsock.h"
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Receiver.h
|
||||
//
|
||||
// Class definition for the recipient of a broadcasted message
|
||||
//
|
||||
class Receiver
|
||||
{
|
||||
public :
|
||||
|
||||
Receiver();
|
||||
~Receiver();
|
||||
|
||||
// setBuffer defines the buffer into which the broadcasted
|
||||
// message will be received.
|
||||
void setBuffer( void *buffer, const unsigned int size );
|
||||
|
||||
// Define what port to listen and bind to
|
||||
void setPort( const short port );
|
||||
|
||||
// Sync does a blocking wait to recieve next message
|
||||
void sync( void );
|
||||
|
||||
private :
|
||||
bool init( void );
|
||||
|
||||
private :
|
||||
#if defined (WIN32) && !defined(__CYGWIN__)
|
||||
SOCKET _so;
|
||||
SOCKADDR_IN saddr;
|
||||
#else
|
||||
int _so;
|
||||
struct sockaddr_in saddr;
|
||||
#endif
|
||||
bool _initialized;
|
||||
short _port;
|
||||
void *_buffer;
|
||||
unsigned int _buffer_size;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Broadcaster.h
|
||||
//
|
||||
// Class definition for broadcasting a buffer to a LAN
|
||||
//
|
||||
class Broadcaster
|
||||
{
|
||||
public :
|
||||
|
||||
Broadcaster( void );
|
||||
~Broadcaster( void );
|
||||
|
||||
// Set the broadcast port
|
||||
void setPort( const short port );
|
||||
|
||||
// Set the buffer to be broadcast
|
||||
void setBuffer( void *buffer, const unsigned int buffer_size );
|
||||
|
||||
// Set a recipient host. If this is used, the Broadcaster
|
||||
// no longer broadcasts, but rather directs UDP packets at
|
||||
// host.
|
||||
void setHost( const char *hostname );
|
||||
|
||||
// Sync broadcasts the buffer
|
||||
void sync( void );
|
||||
|
||||
private :
|
||||
bool init( void );
|
||||
|
||||
private :
|
||||
#if defined(WIN32) && !defined(__CYGWIN__)
|
||||
SOCKET _so;
|
||||
#else
|
||||
int _so;
|
||||
#endif
|
||||
bool _initialized;
|
||||
short _port;
|
||||
void *_buffer;
|
||||
unsigned int _buffer_size;
|
||||
#if defined(WIN32) && !defined(__CYGWIN__)
|
||||
SOCKADDR_IN saddr;
|
||||
#else
|
||||
struct sockaddr_in saddr;
|
||||
#endif
|
||||
unsigned long _address;
|
||||
};
|
||||
|
||||
class CameraPacket {
|
||||
public:
|
||||
|
||||
static const unsigned int MAX_NUM_EVENTS;
|
||||
static const unsigned int SWAP_BYTES_COMPARE;
|
||||
|
||||
CameraPacket():_masterKilled(false)
|
||||
{
|
||||
_byte_order = SWAP_BYTES_COMPARE;
|
||||
}
|
||||
|
||||
void setPacket(const osg::Matrix& matrix,const osg::FrameStamp* frameStamp)
|
||||
{
|
||||
_matrix = matrix;
|
||||
if (frameStamp)
|
||||
{
|
||||
_frameStamp = *frameStamp;
|
||||
}
|
||||
}
|
||||
|
||||
void getModelView(osg::Matrix& matrix,float angle_offset=0.0f)
|
||||
{
|
||||
|
||||
matrix = _matrix * osg::Matrix::rotate(osg::DegreesToRadians(angle_offset),0.0f,1.0f,0.0f);
|
||||
}
|
||||
|
||||
void readEventQueue(osgViewer::Viewer& viewer);
|
||||
|
||||
void writeEventQueue(osgViewer::Viewer& viewer);
|
||||
|
||||
void setMasterKilled(const bool flag) { _masterKilled = flag; }
|
||||
const bool getMasterKilled() const { return _masterKilled; }
|
||||
|
||||
unsigned int _byte_order;
|
||||
bool _masterKilled;
|
||||
osg::Matrix _matrix;
|
||||
|
||||
// note don't use a ref_ptr as used elsewhere for FrameStamp
|
||||
// since we don't want to copy the pointer - but the memory.
|
||||
// FrameStamp doesn't have a private destructor to allow
|
||||
// us to do this, even though its a reference counted object.
|
||||
osg::FrameStamp _frameStamp;
|
||||
|
||||
osgGA::EventQueue::Events _events;
|
||||
|
||||
};
|
||||
|
||||
class DataConverter
|
||||
{
|
||||
public:
|
||||
|
||||
DataConverter(unsigned int numBytes):
|
||||
_startPtr(0),
|
||||
_endPtr(0),
|
||||
_swapBytes(false),
|
||||
_currentPtr(0)
|
||||
{
|
||||
_currentPtr = _startPtr = new char[numBytes];
|
||||
_endPtr = _startPtr+numBytes;
|
||||
_numBytes = numBytes;
|
||||
}
|
||||
|
||||
char* _startPtr;
|
||||
char* _endPtr;
|
||||
unsigned int _numBytes;
|
||||
bool _swapBytes;
|
||||
|
||||
char* _currentPtr;
|
||||
|
||||
void reset()
|
||||
{
|
||||
_currentPtr = _startPtr;
|
||||
}
|
||||
|
||||
inline void write1(char* ptr)
|
||||
{
|
||||
if (_currentPtr+1>=_endPtr) return;
|
||||
|
||||
*(_currentPtr++) = *(ptr);
|
||||
}
|
||||
|
||||
inline void read1(char* ptr)
|
||||
{
|
||||
if (_currentPtr+1>=_endPtr) return;
|
||||
|
||||
*(ptr) = *(_currentPtr++);
|
||||
}
|
||||
|
||||
inline void write2(char* ptr)
|
||||
{
|
||||
if (_currentPtr+2>=_endPtr) return;
|
||||
|
||||
*(_currentPtr++) = *(ptr++);
|
||||
*(_currentPtr++) = *(ptr);
|
||||
}
|
||||
|
||||
inline void read2(char* ptr)
|
||||
{
|
||||
if (_currentPtr+2>=_endPtr) return;
|
||||
|
||||
if (_swapBytes)
|
||||
{
|
||||
*(ptr+1) = *(_currentPtr++);
|
||||
*(ptr) = *(_currentPtr++);
|
||||
}
|
||||
else
|
||||
{
|
||||
*(ptr++) = *(_currentPtr++);
|
||||
*(ptr) = *(_currentPtr++);
|
||||
}
|
||||
}
|
||||
|
||||
inline void write4(char* ptr)
|
||||
{
|
||||
if (_currentPtr+4>=_endPtr) return;
|
||||
|
||||
*(_currentPtr++) = *(ptr++);
|
||||
*(_currentPtr++) = *(ptr++);
|
||||
*(_currentPtr++) = *(ptr++);
|
||||
*(_currentPtr++) = *(ptr);
|
||||
}
|
||||
|
||||
inline void read4(char* ptr)
|
||||
{
|
||||
if (_currentPtr+4>=_endPtr) return;
|
||||
|
||||
if (_swapBytes)
|
||||
{
|
||||
*(ptr+3) = *(_currentPtr++);
|
||||
*(ptr+2) = *(_currentPtr++);
|
||||
*(ptr+1) = *(_currentPtr++);
|
||||
*(ptr) = *(_currentPtr++);
|
||||
}
|
||||
else
|
||||
{
|
||||
*(ptr++) = *(_currentPtr++);
|
||||
*(ptr++) = *(_currentPtr++);
|
||||
*(ptr++) = *(_currentPtr++);
|
||||
*(ptr) = *(_currentPtr++);
|
||||
}
|
||||
}
|
||||
|
||||
inline void write8(char* ptr)
|
||||
{
|
||||
if (_currentPtr+8>=_endPtr) return;
|
||||
|
||||
*(_currentPtr++) = *(ptr++);
|
||||
*(_currentPtr++) = *(ptr++);
|
||||
*(_currentPtr++) = *(ptr++);
|
||||
*(_currentPtr++) = *(ptr++);
|
||||
|
||||
*(_currentPtr++) = *(ptr++);
|
||||
*(_currentPtr++) = *(ptr++);
|
||||
*(_currentPtr++) = *(ptr++);
|
||||
*(_currentPtr++) = *(ptr);
|
||||
}
|
||||
|
||||
inline void read8(char* ptr)
|
||||
{
|
||||
char* endPtr = _currentPtr+8;
|
||||
if (endPtr>=_endPtr) return;
|
||||
|
||||
if (_swapBytes)
|
||||
{
|
||||
*(ptr+7) = *(_currentPtr++);
|
||||
*(ptr+6) = *(_currentPtr++);
|
||||
*(ptr+5) = *(_currentPtr++);
|
||||
*(ptr+4) = *(_currentPtr++);
|
||||
|
||||
*(ptr+3) = *(_currentPtr++);
|
||||
*(ptr+2) = *(_currentPtr++);
|
||||
*(ptr+1) = *(_currentPtr++);
|
||||
*(ptr) = *(_currentPtr++);
|
||||
}
|
||||
else
|
||||
{
|
||||
*(ptr++) = *(_currentPtr++);
|
||||
*(ptr++) = *(_currentPtr++);
|
||||
*(ptr++) = *(_currentPtr++);
|
||||
*(ptr++) = *(_currentPtr++);
|
||||
|
||||
*(ptr++) = *(_currentPtr++);
|
||||
*(ptr++) = *(_currentPtr++);
|
||||
*(ptr++) = *(_currentPtr++);
|
||||
*(ptr) = *(_currentPtr++);
|
||||
}
|
||||
}
|
||||
|
||||
inline void writeChar(char c) { write1(&c); }
|
||||
inline void writeUChar(unsigned char c) { write1((char*)&c); }
|
||||
inline void writeShort(short c) { write2((char*)&c); }
|
||||
inline void writeUShort(unsigned short c) { write2((char*)&c); }
|
||||
inline void writeInt(int c) { write4((char*)&c); }
|
||||
inline void writeUInt(unsigned int c) { write4((char*)&c); }
|
||||
inline void writeFloat(float c) { write4((char*)&c); }
|
||||
inline void writeDouble(double c) { write8((char*)&c); }
|
||||
|
||||
inline char readChar() { char c; read1(&c); return c; }
|
||||
inline unsigned char readUChar() { unsigned char c; read1((char*)&c); return c; }
|
||||
inline short readShort() { short c; read2((char*)&c); return c; }
|
||||
inline unsigned short readUShort() { unsigned short c; read2((char*)&c); return c; }
|
||||
inline int readInt() { int c; read4((char*)&c); return c; }
|
||||
inline unsigned int readUInt() { unsigned int c; read4((char*)&c); return c; }
|
||||
inline float readFloat() { float c; read4((char*)&c); return c; }
|
||||
inline double readDouble() { double c; read8((char*)&c); return c; }
|
||||
|
||||
void write(const osg::FrameStamp& fs);
|
||||
void read(osg::FrameStamp& fs);
|
||||
|
||||
void write(const osg::Matrix& matrix);
|
||||
void read(osg::Matrix& matrix);
|
||||
|
||||
void write(const osgGA::GUIEventAdapter& event);
|
||||
void read(osgGA::GUIEventAdapter& event);
|
||||
|
||||
void write(CameraPacket& cameraPacket);
|
||||
void read(CameraPacket& cameraPacket);
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif
|
48
applications/present3D/CompileSlideCallback.cpp
Normal file
48
applications/present3D/CompileSlideCallback.cpp
Normal file
@ -0,0 +1,48 @@
|
||||
/* -*-c++-*- Present3D - Copyright (C) 1999-2006 Robert Osfield
|
||||
*
|
||||
* This software is open source and may be redistributed and/or modified under
|
||||
* the terms of the GNU General Public License (GPL) version 2.0.
|
||||
* The full license is in LICENSE.txt file included with this distribution,.
|
||||
*
|
||||
* This software is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* include LICENSE.txt for more details.
|
||||
*/
|
||||
|
||||
#include "CompileSlideCallback.h"
|
||||
|
||||
#include <osgUtil/GLObjectsVisitor>
|
||||
|
||||
using namespace ss3d;
|
||||
|
||||
void CompileSlideCallback::operator()(const osg::Camera & camera) const
|
||||
{
|
||||
osg::GraphicsContext* context = const_cast<osg::GraphicsContext*>(camera.getGraphicsContext());
|
||||
if (!context) return;
|
||||
|
||||
osg::State* state = context->getState();
|
||||
if (!state) return;
|
||||
|
||||
const osg::FrameStamp* fs = state->getFrameStamp();
|
||||
if (!fs) return;
|
||||
|
||||
if (_needCompile)
|
||||
{
|
||||
_frameNumber = fs->getFrameNumber();
|
||||
_needCompile = false;
|
||||
}
|
||||
|
||||
if (_frameNumber!=fs->getFrameNumber()) return;
|
||||
|
||||
osgUtil::GLObjectsVisitor globjVisitor(osgUtil::GLObjectsVisitor::COMPILE_DISPLAY_LISTS|
|
||||
osgUtil::GLObjectsVisitor::COMPILE_STATE_ATTRIBUTES);
|
||||
|
||||
globjVisitor.setTraversalMode(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN);
|
||||
|
||||
globjVisitor.setNodeMaskOverride(0xffffffff);
|
||||
|
||||
globjVisitor.setState(state);
|
||||
|
||||
_sceneToCompile->accept(globjVisitor);
|
||||
}
|
44
applications/present3D/CompileSlideCallback.h
Normal file
44
applications/present3D/CompileSlideCallback.h
Normal file
@ -0,0 +1,44 @@
|
||||
/* -*-c++-*- Present3D - Copyright (C) 1999-2006 Robert Osfield
|
||||
*
|
||||
* This software is open source and may be redistributed and/or modified under
|
||||
* the terms of the GNU General Public License (GPL) version 2.0.
|
||||
* The full license is in LICENSE.txt file included with this distribution,.
|
||||
*
|
||||
* This software is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* include LICENSE.txt for more details.
|
||||
*/
|
||||
|
||||
#ifndef OSG_COMPILESLIDECALLBACK
|
||||
#define OSG_COMPILESLIDECALLBACK 1
|
||||
|
||||
#include <osgViewer/Viewer>
|
||||
|
||||
namespace ss3d {
|
||||
|
||||
class CompileSlideCallback : public osg::Camera::DrawCallback
|
||||
{
|
||||
public:
|
||||
|
||||
CompileSlideCallback():
|
||||
_needCompile(false),
|
||||
_frameNumber(0) {}
|
||||
|
||||
virtual void operator()(const osg::Camera& camera) const;
|
||||
|
||||
void needCompile(osg::Node* node) { _needCompile=true; _sceneToCompile = node; }
|
||||
|
||||
protected:
|
||||
|
||||
virtual ~CompileSlideCallback() {}
|
||||
|
||||
mutable bool _needCompile;
|
||||
mutable int _frameNumber;
|
||||
osg::ref_ptr<osg::Node> _sceneToCompile;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
188
applications/present3D/ExportHTML.cpp
Normal file
188
applications/present3D/ExportHTML.cpp
Normal file
@ -0,0 +1,188 @@
|
||||
/* -*-c++-*- Present3D - Copyright (C) 1999-2006 Robert Osfield
|
||||
*
|
||||
* This software is open source and may be redistributed and/or modified under
|
||||
* the terms of the GNU General Public License (GPL) version 2.0.
|
||||
* The full license is in LICENSE.txt file included with this distribution,.
|
||||
*
|
||||
* This software is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* include LICENSE.txt for more details.
|
||||
*/
|
||||
|
||||
#include "ExportHTML.h"
|
||||
#include <osgDB/FileNameUtils>
|
||||
#include <osgDB/WriteFile>
|
||||
#include <sstream>
|
||||
#include <iostream>
|
||||
|
||||
template<typename A, typename B, typename C>
|
||||
std::string createString(const A& a, const B& b, const C& c)
|
||||
{
|
||||
std::ostringstream hos;
|
||||
hos << a << b << c;
|
||||
return hos.str();
|
||||
}
|
||||
|
||||
template<typename A, typename B, typename C, typename D>
|
||||
std::string createString(const A& a, const B& b, const C& c, const D& d)
|
||||
{
|
||||
std::ostringstream hos;
|
||||
hos << a << b << c << d;
|
||||
return hos.str();
|
||||
}
|
||||
|
||||
class SnapImageDrawCallback : public osg::Camera::DrawCallback
|
||||
{
|
||||
public:
|
||||
|
||||
SnapImageDrawCallback():
|
||||
_snapImageOnNextFrame(false)
|
||||
{
|
||||
}
|
||||
|
||||
void setFileName(const std::string& filename) { _filename = filename; }
|
||||
const std::string& getFileName() const { return _filename; }
|
||||
|
||||
void setSnapImageOnNextFrame(bool flag) { _snapImageOnNextFrame = flag; }
|
||||
bool getSnapImageOnNextFrame() const { return _snapImageOnNextFrame; }
|
||||
|
||||
virtual void operator () (const osg::Camera& camera) const
|
||||
{
|
||||
if (!_snapImageOnNextFrame) return;
|
||||
|
||||
int x = static_cast<int>(camera.getViewport()->x());
|
||||
int y = static_cast<int>(camera.getViewport()->y());
|
||||
unsigned int width = static_cast<unsigned int>(camera.getViewport()->width());
|
||||
unsigned int height = static_cast<unsigned int>(camera.getViewport()->height());
|
||||
|
||||
osg::ref_ptr<osg::Image> image = new osg::Image;
|
||||
image->readPixels(x,y,width,height,
|
||||
GL_RGB,GL_UNSIGNED_BYTE);
|
||||
|
||||
if (osgDB::writeImageFile(*image,_filename))
|
||||
{
|
||||
osg::notify(osg::NOTICE) << "Saved screen image to `"<<_filename<<"`"<< std::endl;
|
||||
}
|
||||
|
||||
_snapImageOnNextFrame = false;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
std::string _filename;
|
||||
mutable bool _snapImageOnNextFrame;
|
||||
|
||||
|
||||
};
|
||||
|
||||
std::string ExportHTML::createFileName(const std::string& basename, unsigned int page, const std::string& ext)
|
||||
{
|
||||
if (page==0) return basename+ext;
|
||||
else return createString(basename,'_', page, ext);
|
||||
}
|
||||
|
||||
bool ExportHTML::write(SlideEventHandler* seh, osgViewer::Viewer& viewer, const std::string& filename)
|
||||
{
|
||||
std::string image_basename;
|
||||
std::string image_ext;
|
||||
std::string html_basename;
|
||||
std::string html_ext;
|
||||
|
||||
std::string ext = osgDB::getFileExtension(filename);
|
||||
if (ext=="html" || ext=="htm")
|
||||
{
|
||||
image_basename = osgDB::getNameLessExtension(filename);
|
||||
image_ext = ".jpg";
|
||||
html_basename = osgDB::getNameLessExtension(filename);
|
||||
html_ext = std::string(".")+ext;
|
||||
}
|
||||
else
|
||||
{
|
||||
image_basename = osgDB::getNameLessExtension(filename);
|
||||
image_ext = ".jpg";
|
||||
}
|
||||
|
||||
std::cout<<"Writing slides to "<<image_basename<<"_[slidenumber]"<<image_ext<<std::endl;
|
||||
|
||||
osg::ref_ptr<SnapImageDrawCallback> sidc = new SnapImageDrawCallback;
|
||||
|
||||
osgViewer::Viewer::Cameras cameras;
|
||||
viewer.getCameras(cameras);
|
||||
|
||||
for(osgViewer::Viewer::Cameras::iterator itr = cameras.begin();
|
||||
itr != cameras.end();
|
||||
++itr)
|
||||
{
|
||||
(*itr)->setPostDrawCallback(sidc.get());
|
||||
}
|
||||
|
||||
std::string home_file = createFileName(html_basename, 0, html_ext);
|
||||
|
||||
unsigned int i;
|
||||
for(i=0; i<seh->getNumSlides(); ++i)
|
||||
{
|
||||
std::ostringstream os;
|
||||
os << image_basename <<"_"<<i<<image_ext;
|
||||
|
||||
sidc->setFileName(os.str());
|
||||
sidc->setSnapImageOnNextFrame(true);
|
||||
|
||||
if (!html_basename.empty())
|
||||
{
|
||||
std::string htmlFileName = createFileName(html_basename, i, html_ext);
|
||||
|
||||
std::ofstream fout(htmlFileName.c_str());
|
||||
if (fout)
|
||||
{
|
||||
std::string previous_file = i>0 ? createFileName(html_basename,i-1,html_ext) : "";
|
||||
std::string next_file = i<seh->getNumSlides()-1 ? createFileName(html_basename,i+1,html_ext) : "";
|
||||
|
||||
std::cout<<"Writing html slides "<<htmlFileName<<std::endl;
|
||||
|
||||
fout<<"<html>"<<std::endl;
|
||||
fout<<"<table width=\"100%\">"<<std::endl;
|
||||
fout<<"<tr>"<<std::endl;
|
||||
if (!previous_file.empty())
|
||||
{
|
||||
fout<<"<td align=\"left\" width=\"33%\"><a href=\""<<osgDB::getSimpleFileName(previous_file)<<"\"> Previous </a></td>"<<std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
fout<<"<td align=\"left\" width=\"33%\"></td>"<<std::endl;
|
||||
}
|
||||
if (i != 0)
|
||||
{
|
||||
fout<<"<td align=\"center\" width=\"33%\"><a href=\""<<osgDB::getSimpleFileName(home_file)<<"\"> Home </a></td>"<<std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
fout<<"<td align=\"center\" width=\"33%\"></td>"<<std::endl;
|
||||
}
|
||||
if (!next_file.empty())
|
||||
{
|
||||
fout<<"<td align=\"right\" width=\"33%\"><a href=\""<<osgDB::getSimpleFileName(next_file)<<"\"> Next </a></td>"<<std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
fout<<"<td align=\"right\" width=\"33%\"></td>"<<std::endl;
|
||||
}
|
||||
fout<<"</tr>"<<std::endl;
|
||||
fout<<"</table>"<<std::endl;
|
||||
fout<<"<img src=\""<<osgDB::getSimpleFileName(os.str())<<"\">"<<std::endl;
|
||||
fout<<"</html>"<<std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout<<"Could not open '"<<filename<<"' for writing."<<std::endl;
|
||||
}
|
||||
}
|
||||
// wait for all cull and draw threads to complete.
|
||||
|
||||
seh->selectSlide(i, SlideEventHandler::LAST_POSITION);
|
||||
|
||||
// fire off the cull and draw traversals of the scene.
|
||||
viewer.frame();
|
||||
}
|
||||
return true;
|
||||
}
|
27
applications/present3D/ExportHTML.h
Normal file
27
applications/present3D/ExportHTML.h
Normal file
@ -0,0 +1,27 @@
|
||||
/* -*-c++-*- Present3D - Copyright (C) 1999-2006 Robert Osfield
|
||||
*
|
||||
* This software is open source and may be redistributed and/or modified under
|
||||
* the terms of the GNU General Public License (GPL) version 2.0.
|
||||
* The full license is in LICENSE.txt file included with this distribution,.
|
||||
*
|
||||
* This software is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* include LICENSE.txt for more details.
|
||||
*/
|
||||
|
||||
#ifndef EXPORTHTML_H
|
||||
#define EXPORTHTML_H 1
|
||||
|
||||
#include "SlideEventHandler.h"
|
||||
#include <osgViewer/Viewer>
|
||||
|
||||
class ExportHTML
|
||||
{
|
||||
public:
|
||||
static bool write(SlideEventHandler* seh, osgViewer::Viewer& viewer, const std::string& filename);
|
||||
|
||||
static std::string createFileName(const std::string& basename, unsigned int page, const std::string& ext);
|
||||
};
|
||||
|
||||
#endif
|
209
applications/present3D/PickEventHandler.cpp
Normal file
209
applications/present3D/PickEventHandler.cpp
Normal file
@ -0,0 +1,209 @@
|
||||
/* -*-c++-*- Present3D - Copyright (C) 1999-2006 Robert Osfield
|
||||
*
|
||||
* This software is open source and may be redistributed and/or modified under
|
||||
* the terms of the GNU General Public License (GPL) version 2.0.
|
||||
* The full license is in LICENSE.txt file included with this distribution,.
|
||||
*
|
||||
* This software is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* include LICENSE.txt for more details.
|
||||
*/
|
||||
|
||||
#include "PickEventHandler.h"
|
||||
#include "SlideEventHandler.h"
|
||||
|
||||
#include <osgViewer/Viewer>
|
||||
#include <osg/Notify>
|
||||
#include <osgDB/FileUtils>
|
||||
|
||||
PickEventHandler::PickEventHandler(SlideShowConstructor::Operation operation,bool relativeJump, int slideNum, int layerNum):
|
||||
_operation(operation),
|
||||
_relativeJump(relativeJump),
|
||||
_slideNum(slideNum),
|
||||
_layerNum(layerNum)
|
||||
{
|
||||
}
|
||||
|
||||
PickEventHandler::PickEventHandler(const std::string& str, SlideShowConstructor::Operation operation,bool relativeJump, int slideNum, int layerNum):
|
||||
_command(str),
|
||||
_operation(operation),
|
||||
_relativeJump(relativeJump),
|
||||
_slideNum(slideNum),
|
||||
_layerNum(layerNum)
|
||||
{
|
||||
}
|
||||
|
||||
PickEventHandler::PickEventHandler(const SlideShowConstructor::KeyPosition& keyPos,bool relativeJump, int slideNum, int layerNum):
|
||||
_keyPos(keyPos),
|
||||
_operation(SlideShowConstructor::EVENT),
|
||||
_relativeJump(relativeJump),
|
||||
_slideNum(slideNum),
|
||||
_layerNum(layerNum)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
bool PickEventHandler::handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter& aa, osg::Object*, osg::NodeVisitor* nv)
|
||||
{
|
||||
switch(ea.getEventType())
|
||||
{
|
||||
case(osgGA::GUIEventAdapter::MOVE):
|
||||
case(osgGA::GUIEventAdapter::PUSH):
|
||||
case(osgGA::GUIEventAdapter::RELEASE):
|
||||
{
|
||||
osgViewer::Viewer* viewer = dynamic_cast<osgViewer::Viewer*>(&aa);
|
||||
osgUtil::LineSegmentIntersector::Intersections intersections;
|
||||
if (viewer->computeIntersections(ea.getX(),ea.getY(), nv->getNodePath(), intersections))
|
||||
{
|
||||
for(osgUtil::LineSegmentIntersector::Intersections::iterator hitr=intersections.begin();
|
||||
hitr!=intersections.end();
|
||||
++hitr)
|
||||
{
|
||||
if (ea.getEventType()==osgGA::GUIEventAdapter::MOVE)
|
||||
{
|
||||
osg::notify(osg::INFO)<<"Tooltip..."<<std::endl;
|
||||
}
|
||||
else if (ea.getEventType()==osgGA::GUIEventAdapter::RELEASE)
|
||||
{
|
||||
doOperation();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case(osgGA::GUIEventAdapter::KEYDOWN):
|
||||
{
|
||||
//osg::notify(osg::NOTICE)<<"PickEventHandler KEYDOWN "<<(char)ea.getKey()<<std::endl;
|
||||
//if (object) osg::notify(osg::NOTICE)<<" "<<object->className()<<std::endl;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void PickEventHandler::accept(osgGA::GUIEventHandlerVisitor& v)
|
||||
{
|
||||
v.visit(*this);
|
||||
}
|
||||
|
||||
void PickEventHandler::getUsage(osg::ApplicationUsage& /*usage*/) const
|
||||
{
|
||||
}
|
||||
|
||||
void PickEventHandler::setRelativeJump(int slideNum, int layerNum)
|
||||
{
|
||||
_relativeJump = true;
|
||||
_slideNum = slideNum;
|
||||
_layerNum = layerNum;
|
||||
}
|
||||
|
||||
void PickEventHandler::setAbsoluteJump(int slideNum, int layerNum)
|
||||
{
|
||||
_relativeJump = false;
|
||||
_slideNum = slideNum;
|
||||
_layerNum = layerNum;
|
||||
}
|
||||
|
||||
|
||||
void PickEventHandler::doOperation()
|
||||
{
|
||||
switch(_operation)
|
||||
{
|
||||
case(SlideShowConstructor::RUN):
|
||||
{
|
||||
osg::notify(osg::NOTICE)<<"Run "<<_command<<std::endl;
|
||||
|
||||
|
||||
osgDB::FilePathList& paths = osgDB::getDataFilePathList();
|
||||
#if 0
|
||||
if (!paths.empty())
|
||||
{
|
||||
#ifdef _WIN32
|
||||
std::string delimintor(";");
|
||||
#else
|
||||
std::string delimintor(":");
|
||||
#endif
|
||||
std::string filepath("OSG_FILE_PATH=");
|
||||
|
||||
bool needDeliminator = false;
|
||||
for(osgDB::FilePathList::iterator itr = paths.begin();
|
||||
itr != paths.end();
|
||||
++itr)
|
||||
{
|
||||
if (needDeliminator) filepath += delimintor;
|
||||
filepath += *itr;
|
||||
needDeliminator = true;
|
||||
}
|
||||
putenv( (char*) filepath.c_str());
|
||||
|
||||
std::string binpath("PATH=");
|
||||
char* path = getenv("PATH");
|
||||
if (path) binpath += path;
|
||||
|
||||
needDeliminator = true;
|
||||
for(osgDB::FilePathList::iterator itr = paths.begin();
|
||||
itr != paths.end();
|
||||
++itr)
|
||||
{
|
||||
if (needDeliminator) binpath += delimintor;
|
||||
binpath += *itr;
|
||||
needDeliminator = true;
|
||||
}
|
||||
putenv( (char*) binpath.c_str());
|
||||
|
||||
}
|
||||
#endif
|
||||
int result = system(_command.c_str());
|
||||
|
||||
osg::notify(osg::INFO)<<"system("<<_command<<") result "<<result<<std::endl;
|
||||
|
||||
break;
|
||||
}
|
||||
case(SlideShowConstructor::LOAD):
|
||||
{
|
||||
osg::notify(osg::NOTICE)<<"Load "<<_command<<std::endl;
|
||||
break;
|
||||
}
|
||||
case(SlideShowConstructor::EVENT):
|
||||
{
|
||||
osg::notify(osg::INFO)<<"Event "<<_keyPos._key<<" "<<_keyPos._x<<" "<<_keyPos._y<<std::endl;
|
||||
if (SlideEventHandler::instance()) SlideEventHandler::instance()->dispatchEvent(_keyPos);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (requiresJump())
|
||||
{
|
||||
osg::notify(osg::NOTICE)<<"Requires jump "<<_relativeJump<<", "<<_slideNum<<", "<<_layerNum<<std::endl;
|
||||
|
||||
if (_relativeJump)
|
||||
{
|
||||
int previousSlide = SlideEventHandler::instance()->getActiveSlide();
|
||||
int previousLayer = SlideEventHandler::instance()->getActiveLayer();
|
||||
int newSlide = previousSlide + _slideNum;
|
||||
int newLayer = previousLayer + _layerNum;
|
||||
if (newLayer<0)
|
||||
{
|
||||
newLayer = 0;
|
||||
}
|
||||
|
||||
osg::notify(osg::NOTICE)<<" jump to "<<newSlide<<", "<<newLayer<<std::endl;
|
||||
|
||||
SlideEventHandler::instance()->selectSlide(newSlide, newLayer);
|
||||
}
|
||||
else
|
||||
{
|
||||
SlideEventHandler::instance()->selectSlide(_slideNum,_layerNum);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
osg::notify(osg::NOTICE)<<"No jump required."<<std::endl;
|
||||
}
|
||||
}
|
||||
|
66
applications/present3D/PickEventHandler.h
Normal file
66
applications/present3D/PickEventHandler.h
Normal file
@ -0,0 +1,66 @@
|
||||
/* -*-c++-*- Present3D - Copyright (C) 1999-2006 Robert Osfield
|
||||
*
|
||||
* This software is open source and may be redistributed and/or modified under
|
||||
* the terms of the GNU General Public License (GPL) version 2.0.
|
||||
* The full license is in LICENSE.txt file included with this distribution,.
|
||||
*
|
||||
* This software is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* include LICENSE.txt for more details.
|
||||
*/
|
||||
|
||||
#ifndef PICKEVENTHANDLER
|
||||
#define PICKEVENTHANDLER 1
|
||||
|
||||
#include <osg/StateSet>
|
||||
#include <osg/Point>
|
||||
|
||||
#include <osgGA/GUIEventHandler>
|
||||
|
||||
#include "SlideShowConstructor.h"
|
||||
|
||||
class PickEventHandler : public osgGA::GUIEventHandler
|
||||
{
|
||||
public:
|
||||
|
||||
PickEventHandler(SlideShowConstructor::Operation operation, bool relativeJump=true, int slideNum=0, int layerNum=0);
|
||||
PickEventHandler(const std::string& str, SlideShowConstructor::Operation operation, bool relativeJump=true, int slideNum=0, int layerNum=0);
|
||||
PickEventHandler(const SlideShowConstructor::KeyPosition& keyPos, bool relativeJump=true, int slideNum=0, int layerNum=0);
|
||||
|
||||
void setOperation(SlideShowConstructor::Operation operation) { _operation = operation; }
|
||||
SlideShowConstructor::Operation getOperation() const { return _operation; }
|
||||
|
||||
void setCommand(const std::string& str) { _command = str; }
|
||||
const std::string& getCommand() const { return _command; }
|
||||
|
||||
void setKeyPosition(const SlideShowConstructor::KeyPosition& keyPos) { _keyPos = keyPos; }
|
||||
const SlideShowConstructor::KeyPosition& getKeyPosition() const { return _keyPos; }
|
||||
|
||||
void setRelativeJump(int slideDelta, int layerDelta);
|
||||
void setAbsoluteJump(int slideNum, int layerNum);
|
||||
|
||||
bool getRelativeJump() const { return _relativeJump; }
|
||||
int getSlideNum() const { return _slideNum; }
|
||||
int getLayerNum() const { return _layerNum; }
|
||||
|
||||
bool requiresJump() const { return _relativeJump ? (_slideNum!=0 || _layerNum!=0) : true; }
|
||||
|
||||
virtual bool handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter& aa, osg::Object* object, osg::NodeVisitor* nv);
|
||||
|
||||
virtual void accept(osgGA::GUIEventHandlerVisitor& v);
|
||||
|
||||
virtual void getUsage(osg::ApplicationUsage& usage) const;
|
||||
|
||||
void doOperation();
|
||||
|
||||
std::string _command;
|
||||
SlideShowConstructor::KeyPosition _keyPos;
|
||||
SlideShowConstructor::Operation _operation;
|
||||
|
||||
bool _relativeJump;
|
||||
int _slideNum;
|
||||
int _layerNum;
|
||||
};
|
||||
|
||||
#endif
|
101
applications/present3D/PointsEventHandler.cpp
Normal file
101
applications/present3D/PointsEventHandler.cpp
Normal file
@ -0,0 +1,101 @@
|
||||
/* -*-c++-*- Present3D - Copyright (C) 1999-2006 Robert Osfield
|
||||
*
|
||||
* This software is open source and may be redistributed and/or modified under
|
||||
* the terms of the GNU General Public License (GPL) version 2.0.
|
||||
* The full license is in LICENSE.txt file included with this distribution,.
|
||||
*
|
||||
* This software is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* include LICENSE.txt for more details.
|
||||
*/
|
||||
|
||||
#include "PointsEventHandler.h"
|
||||
|
||||
#include <osg/Notify>
|
||||
|
||||
PointsEventHandler::PointsEventHandler()
|
||||
{
|
||||
_point = new osg::Point;
|
||||
//_point->setDistanceAttenuation(osg::Vec3(0.0,0.0000,0.05f));
|
||||
}
|
||||
|
||||
bool PointsEventHandler::handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter&)
|
||||
{
|
||||
switch(ea.getEventType())
|
||||
{
|
||||
case(osgGA::GUIEventAdapter::KEYDOWN):
|
||||
{
|
||||
if (ea.getKey()=='+' || ea.getKey()==osgGA::GUIEventAdapter::KEY_KP_Add)
|
||||
{
|
||||
changePointSize(1.0f);
|
||||
return true;
|
||||
}
|
||||
else if (ea.getKey()=='-' || ea.getKey()==osgGA::GUIEventAdapter::KEY_KP_Subtract)
|
||||
{
|
||||
changePointSize(-1.0f);
|
||||
return true;
|
||||
}
|
||||
else if (ea.getKey()=='<')
|
||||
{
|
||||
changePointAttenuation(1.1f);
|
||||
return true;
|
||||
}
|
||||
else if (ea.getKey()=='>')
|
||||
{
|
||||
changePointAttenuation(1.0f/1.1f);
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void PointsEventHandler::accept(osgGA::GUIEventHandlerVisitor& v)
|
||||
{
|
||||
v.visit(*this);
|
||||
}
|
||||
|
||||
void PointsEventHandler::getUsage(osg::ApplicationUsage& usage) const
|
||||
{
|
||||
usage.addKeyboardMouseBinding("+","Increase point size");
|
||||
usage.addKeyboardMouseBinding("-","Reduce point size");
|
||||
usage.addKeyboardMouseBinding(">","Increase point size");
|
||||
usage.addKeyboardMouseBinding("<","Reduce point size");
|
||||
}
|
||||
|
||||
float PointsEventHandler::getPointSize() const
|
||||
{
|
||||
return _point->getSize();
|
||||
}
|
||||
|
||||
void PointsEventHandler::setPointSize(float psize)
|
||||
{
|
||||
if (psize>0.0)
|
||||
{
|
||||
_point->setSize(psize);
|
||||
_stateset->setAttribute(_point.get());
|
||||
}
|
||||
else
|
||||
{
|
||||
_stateset->setAttribute(_point.get(),osg::StateAttribute::INHERIT);
|
||||
}
|
||||
osg::notify(osg::INFO)<<"Point size "<<psize<<std::endl;
|
||||
}
|
||||
|
||||
void PointsEventHandler::changePointSize(float delta)
|
||||
{
|
||||
setPointSize(getPointSize()+delta);
|
||||
}
|
||||
|
||||
void PointsEventHandler::changePointAttenuation(float scale)
|
||||
{
|
||||
if (_point.valid())
|
||||
{
|
||||
_point->setDistanceAttenuation(_point->getDistanceAttenuation()*scale);
|
||||
if (_stateset.valid()) _stateset->setAttribute(_point.get());
|
||||
}
|
||||
}
|
51
applications/present3D/PointsEventHandler.h
Normal file
51
applications/present3D/PointsEventHandler.h
Normal file
@ -0,0 +1,51 @@
|
||||
/* -*-c++-*- Present3D - Copyright (C) 1999-2006 Robert Osfield
|
||||
*
|
||||
* This software is open source and may be redistributed and/or modified under
|
||||
* the terms of the GNU General Public License (GPL) version 2.0.
|
||||
* The full license is in LICENSE.txt file included with this distribution,.
|
||||
*
|
||||
* This software is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* include LICENSE.txt for more details.
|
||||
*/
|
||||
|
||||
#ifndef POINTSEVENTHANDLER
|
||||
#define POINTSEVENTHANDLER 1
|
||||
|
||||
#include <osg/StateSet>
|
||||
#include <osg/Point>
|
||||
|
||||
#include <osgGA/GUIEventHandler>
|
||||
|
||||
class PointsEventHandler : public osgGA::GUIEventHandler
|
||||
{
|
||||
public:
|
||||
PointsEventHandler();
|
||||
|
||||
virtual bool handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter&);
|
||||
|
||||
virtual void accept(osgGA::GUIEventHandlerVisitor& v);
|
||||
|
||||
void getUsage(osg::ApplicationUsage& usage) const;
|
||||
|
||||
void setStateSet(osg::StateSet* stateset) { _stateset=stateset; }
|
||||
|
||||
osg::StateSet* getStateSet() { return _stateset.get(); }
|
||||
|
||||
const osg::StateSet* getStateSet() const { return _stateset.get(); }
|
||||
|
||||
void setPointSize(float psize);
|
||||
|
||||
float getPointSize() const;
|
||||
|
||||
void changePointSize(float delta);
|
||||
|
||||
void changePointAttenuation(float scale);
|
||||
|
||||
osg::ref_ptr<osg::StateSet> _stateset;
|
||||
osg::ref_ptr<osg::Point> _point;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
279
applications/present3D/ReadShowFile.cpp
Normal file
279
applications/present3D/ReadShowFile.cpp
Normal file
@ -0,0 +1,279 @@
|
||||
/* -*-c++-*- Present3D - Copyright (C) 1999-2006 Robert Osfield
|
||||
*
|
||||
* This software is open source and may be redistributed and/or modified under
|
||||
* the terms of the GNU General Public License (GPL) version 2.0.
|
||||
* The full license is in LICENSE.txt file included with this distribution,.
|
||||
*
|
||||
* This software is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* include LICENSE.txt for more details.
|
||||
*/
|
||||
|
||||
#include "ReadShowFile.h"
|
||||
#include "ShowEventHandler.h"
|
||||
|
||||
#include <osg/ImageStream>
|
||||
#include <osg/Shape>
|
||||
#include <osg/ShapeDrawable>
|
||||
#include <osg/Switch>
|
||||
|
||||
#include <osgDB/ReadFile>
|
||||
#include <osgDB/FileNameUtils>
|
||||
#include <osgDB/FileUtils>
|
||||
|
||||
#include <osgVolume/VolumeTile>
|
||||
|
||||
#include <libxml/xmlmemory.h>
|
||||
#include <libxml/parser.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
class AddVolumeEditingCallbackVisitor : public osg::NodeVisitor
|
||||
{
|
||||
public:
|
||||
AddVolumeEditingCallbackVisitor():
|
||||
osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN) {}
|
||||
|
||||
void apply(osg::Group& group)
|
||||
{
|
||||
osgVolume::VolumeTile* volumeTile = dynamic_cast<osgVolume::VolumeTile*>(&group);
|
||||
if (volumeTile)
|
||||
{
|
||||
volumeTile->addEventCallback(new osgVolume::PropertyAdjustmentCallback());
|
||||
}
|
||||
else
|
||||
{
|
||||
traverse(group);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
bool p3d::getFileNames(osg::ArgumentParser& arguments, FileNameList& xmlFiles, FileNameList& normalFiles)
|
||||
{
|
||||
// note currently doesn't delete the loaded file entries from the command line yet...
|
||||
for(int pos=1;pos<arguments.argc();++pos)
|
||||
{
|
||||
if (!arguments.isOption(pos))
|
||||
{
|
||||
std::string ext = osgDB::getFileExtension(arguments[pos]);
|
||||
if (osgDB::equalCaseInsensitive(ext,"xml") || osgDB::equalCaseInsensitive(ext,"p3d"))
|
||||
{
|
||||
xmlFiles.push_back(arguments[pos]);
|
||||
}
|
||||
else
|
||||
{
|
||||
normalFiles.push_back(arguments[pos]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return (!xmlFiles.empty() || !normalFiles.empty());
|
||||
}
|
||||
|
||||
bool p3d::readEnvVars(osg::ArgumentParser& arguments)
|
||||
{
|
||||
bool readVars = false;
|
||||
|
||||
for(unsigned int i=1; i<arguments.argc(); ++i)
|
||||
{
|
||||
if (!arguments.isOption(i))
|
||||
{
|
||||
std::string ext = osgDB::getLowerCaseFileExtension(arguments[i]);
|
||||
if (ext=="xml" || ext=="p3d")
|
||||
{
|
||||
std::string file = osgDB::findDataFile(arguments[i]);
|
||||
if (!file.empty())
|
||||
{
|
||||
std::string path = osgDB::getFilePath(file);
|
||||
if (!path.empty())
|
||||
{
|
||||
osgDB::getDataFilePathList().push_front(path);
|
||||
}
|
||||
|
||||
if (p3d::readEnvVars(file)) readVars = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return readVars;
|
||||
}
|
||||
|
||||
bool p3d::readEnvVars(const std::string& fileName)
|
||||
{
|
||||
std::string ext = osgDB::getFileExtension(fileName);
|
||||
if (!osgDB::equalCaseInsensitive(ext,"xml") &&
|
||||
!osgDB::equalCaseInsensitive(ext,"p3d")) return false;
|
||||
|
||||
|
||||
xmlDocPtr doc;
|
||||
xmlNodePtr cur;
|
||||
|
||||
doc = xmlParseFile(fileName.c_str());
|
||||
|
||||
if (doc == NULL )
|
||||
{
|
||||
fprintf(stderr,"Document not parsed successfully. \n");
|
||||
return false;
|
||||
}
|
||||
|
||||
cur = xmlDocGetRootElement(doc);
|
||||
|
||||
if (cur == NULL)
|
||||
{
|
||||
fprintf(stderr,"empty document\n");
|
||||
xmlFreeDoc(doc);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (xmlStrcmp(cur->name, (const xmlChar *) "presentation"))
|
||||
{
|
||||
fprintf(stderr,"document of the wrong type, root node != presentation");
|
||||
xmlFreeDoc(doc);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool readVars = false;
|
||||
|
||||
xmlChar *key;
|
||||
cur = cur->xmlChildrenNode;
|
||||
while (cur != NULL) {
|
||||
|
||||
if ((!xmlStrcmp(cur->name, (const xmlChar *)"env")))
|
||||
{
|
||||
key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
|
||||
if (key)
|
||||
{
|
||||
char* str = strdup((char*)key);
|
||||
osg::notify(osg::INFO)<<"putenv("<<str<<")"<<std::endl;
|
||||
putenv(str);
|
||||
readVars = true;
|
||||
}
|
||||
xmlFree(key);
|
||||
}
|
||||
cur = cur->next;
|
||||
}
|
||||
|
||||
#ifndef __APPLE__
|
||||
|
||||
xmlFreeDoc(doc);
|
||||
|
||||
#endif
|
||||
|
||||
return readVars;
|
||||
}
|
||||
|
||||
osg::Node* p3d::readHoldingSlide(const std::string& filename)
|
||||
{
|
||||
std::string ext = osgDB::getFileExtension(filename);
|
||||
if (!osgDB::equalCaseInsensitive(ext,"xml") &&
|
||||
!osgDB::equalCaseInsensitive(ext,"p3d")) return 0;
|
||||
|
||||
osg::ref_ptr<osgDB::ReaderWriter::Options> options = new osgDB::ReaderWriter::Options;
|
||||
options->setObjectCacheHint(osgDB::ReaderWriter::Options::CACHE_NONE);
|
||||
options->setOptionString("holding_slide");
|
||||
|
||||
osgDB::ReaderWriter::ReadResult readResult = osgDB::Registry::instance()->readNode(filename, options.get());
|
||||
if (readResult.validNode()) return readResult.takeNode();
|
||||
else return 0;
|
||||
}
|
||||
|
||||
osg::Node* p3d::readPresentation(const std::string& filename,const osgDB::ReaderWriter::Options* options)
|
||||
{
|
||||
std::string ext = osgDB::getFileExtension(filename);
|
||||
if (!osgDB::equalCaseInsensitive(ext,"xml") &&
|
||||
!osgDB::equalCaseInsensitive(ext,"p3d")) return 0;
|
||||
return osgDB::readNodeFile(filename, options);
|
||||
}
|
||||
|
||||
osg::Node* p3d::readShowFiles(osg::ArgumentParser& arguments,const osgDB::ReaderWriter::Options* options)
|
||||
{
|
||||
|
||||
typedef std::vector< osg::ref_ptr<osg::Node> > NodeList;
|
||||
NodeList nodeList;
|
||||
|
||||
std::string filename;
|
||||
while (arguments.read("--image",filename))
|
||||
{
|
||||
osg::ref_ptr<osg::Image> image = readImageFile(filename.c_str(), options);
|
||||
if (image.valid()) nodeList.push_back(osg::createGeodeForImage(image.get()));
|
||||
}
|
||||
|
||||
while (arguments.read("--movie",filename))
|
||||
{
|
||||
osg::ref_ptr<osg::Image> image = readImageFile(filename.c_str(), options);
|
||||
osg::ref_ptr<osg::ImageStream> imageStream = dynamic_cast<osg::ImageStream*>(image.get());
|
||||
if (image.valid())
|
||||
{
|
||||
imageStream->play();
|
||||
nodeList.push_back(osg::createGeodeForImage(imageStream.get()));
|
||||
}
|
||||
}
|
||||
|
||||
while (arguments.read("--dem",filename))
|
||||
{
|
||||
osg::HeightField* hf = readHeightFieldFile(filename.c_str(), options);
|
||||
if (hf)
|
||||
{
|
||||
osg::Geode* geode = new osg::Geode;
|
||||
geode->addDrawable(new osg::ShapeDrawable(hf));
|
||||
nodeList.push_back(geode);
|
||||
}
|
||||
}
|
||||
|
||||
// note currently doesn't delete the loaded file entries from the command line yet...
|
||||
for(int pos=1;pos<arguments.argc();++pos)
|
||||
{
|
||||
if (!arguments.isOption(pos))
|
||||
{
|
||||
// not an option so assume string is a filename.
|
||||
osg::Node *node = osgDB::readNodeFile( arguments[pos], options);
|
||||
|
||||
if(node)
|
||||
{
|
||||
if (node->getName().empty()) node->setName( arguments[pos] );
|
||||
nodeList.push_back(node);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (nodeList.empty())
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
osg::ref_ptr<osg::Node> root;
|
||||
|
||||
if (nodeList.size()==1)
|
||||
{
|
||||
root = nodeList.front().get();
|
||||
}
|
||||
else // size >1
|
||||
{
|
||||
|
||||
osg::Switch* sw = new osg::Switch;
|
||||
for(NodeList::iterator itr=nodeList.begin();
|
||||
itr!=nodeList.end();
|
||||
++itr)
|
||||
{
|
||||
sw->addChild((*itr).get());
|
||||
}
|
||||
sw->setSingleChildOn(0);
|
||||
|
||||
sw->setEventCallback(new p3d::ShowEventHandler());
|
||||
|
||||
root = sw;
|
||||
}
|
||||
|
||||
if (root.valid())
|
||||
{
|
||||
osg::notify(osg::INFO)<<"Got node now adding callback"<<std::endl;
|
||||
|
||||
AddVolumeEditingCallbackVisitor avecv;
|
||||
root->accept(avecv);
|
||||
}
|
||||
|
||||
return root.release();
|
||||
}
|
37
applications/present3D/ReadShowFile.h
Normal file
37
applications/present3D/ReadShowFile.h
Normal file
@ -0,0 +1,37 @@
|
||||
/* -*-c++-*- Present3D - Copyright (C) 1999-2006 Robert Osfield
|
||||
*
|
||||
* This software is open source and may be redistributed and/or modified under
|
||||
* the terms of the GNU General Public License (GPL) version 2.0.
|
||||
* The full license is in LICENSE.txt file included with this distribution,.
|
||||
*
|
||||
* This software is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* include LICENSE.txt for more details.
|
||||
*/
|
||||
|
||||
#ifndef P3D_READFILE
|
||||
#define P3D_READFILE 1
|
||||
|
||||
#include <osg/ArgumentParser>
|
||||
#include <osgDB/ReaderWriter>
|
||||
|
||||
namespace p3d {
|
||||
|
||||
typedef std::vector<std::string> FileNameList;
|
||||
|
||||
bool getFileNames(osg::ArgumentParser& arguments, FileNameList& xmlFiles, FileNameList& normalFiles);
|
||||
|
||||
bool readEnvVars(osg::ArgumentParser& arguments);
|
||||
|
||||
bool readEnvVars(const std::string& filename);
|
||||
|
||||
osg::Node* readHoldingSlide(const std::string& filename);
|
||||
|
||||
osg::Node* readPresentation(const std::string& filename,const osgDB::ReaderWriter::Options* options);
|
||||
|
||||
osg::Node* readShowFiles(osg::ArgumentParser& arguments,const osgDB::ReaderWriter::Options* options);
|
||||
|
||||
}
|
||||
|
||||
#endif
|
1716
applications/present3D/ReaderWriterXML.cpp
Normal file
1716
applications/present3D/ReaderWriterXML.cpp
Normal file
File diff suppressed because it is too large
Load Diff
181
applications/present3D/SDLIntegration.cpp
Normal file
181
applications/present3D/SDLIntegration.cpp
Normal file
@ -0,0 +1,181 @@
|
||||
/* -*-c++-*- Present3D - Copyright (C) 1999-2006 Robert Osfield
|
||||
*
|
||||
* This software is open source and may be redistributed and/or modified under
|
||||
* the terms of the GNU General Public License (GPL) version 2.0.
|
||||
* The full license is in LICENSE.txt file included with this distribution,.
|
||||
*
|
||||
* This software is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* include LICENSE.txt for more details.
|
||||
*/
|
||||
|
||||
#include <osgViewer/Viewer>
|
||||
|
||||
#include "SDLIntegration.h"
|
||||
|
||||
#include <SDL.h>
|
||||
#include <SDL_events.h>
|
||||
#include <SDL_joystick.h>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
SDLIntegration::SDLIntegration()
|
||||
{
|
||||
_verbose = false;
|
||||
|
||||
// init SDL
|
||||
if ( SDL_Init(SDL_INIT_JOYSTICK) < 0 )
|
||||
{
|
||||
fprintf(stderr, "Unable to init SDL: %s\n", SDL_GetError());
|
||||
exit(1);
|
||||
}
|
||||
atexit(SDL_Quit);
|
||||
|
||||
int numJoysticks = SDL_NumJoysticks();
|
||||
|
||||
if (_verbose)
|
||||
{
|
||||
std::cout<<"number of joysticks "<<numJoysticks<<std::endl;
|
||||
for(int i=0; i<numJoysticks; ++i)
|
||||
{
|
||||
std::cout<<"Joystick name '"<<SDL_JoystickName(i)<<"'"<<std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
_joystick = numJoysticks>0 ? SDL_JoystickOpen(0) : 0;
|
||||
|
||||
_numAxes = _joystick ? SDL_JoystickNumAxes(_joystick) : 0;
|
||||
_numBalls = _joystick ? SDL_JoystickNumBalls(_joystick) : 0;
|
||||
_numHats = _joystick ? SDL_JoystickNumHats(_joystick) : 0;
|
||||
_numButtons = _joystick ? SDL_JoystickNumButtons(_joystick) : 0;
|
||||
|
||||
if (_verbose)
|
||||
{
|
||||
std::cout<<"numAxes = "<<_numAxes<<std::endl;
|
||||
std::cout<<"numBalls = "<<_numBalls<<std::endl;
|
||||
std::cout<<"numHats = "<<_numHats<<std::endl;
|
||||
std::cout<<"numButtons = "<<_numButtons<<std::endl;
|
||||
}
|
||||
|
||||
addMouseButtonMapping(4, 1); // left
|
||||
addMouseButtonMapping(5, 3); // right
|
||||
addMouseButtonMapping(6, 2); // middle
|
||||
|
||||
addKeyMapping(10, ' '); // R2
|
||||
|
||||
addKeyMapping(0, '1'); // 1
|
||||
addKeyMapping(1, '2'); // 2
|
||||
addKeyMapping(2, '3'); // 3
|
||||
addKeyMapping(4, '4'); // 4
|
||||
|
||||
addKeyMapping(7, ' '); // home
|
||||
|
||||
addKeyMapping(8, osgGA::GUIEventAdapter::KEY_Page_Up); // Start
|
||||
addKeyMapping(9, osgGA::GUIEventAdapter::KEY_Page_Down); // Start
|
||||
addKeyMapping(10, osgGA::GUIEventAdapter::KEY_Home); // Start
|
||||
|
||||
|
||||
capture(_axisValues, _buttonValues);
|
||||
}
|
||||
|
||||
SDLIntegration::~SDLIntegration()
|
||||
{
|
||||
}
|
||||
|
||||
void SDLIntegration::capture(ValueList& axisValues, ValueList& buttonValues) const
|
||||
{
|
||||
if (_joystick)
|
||||
{
|
||||
SDL_JoystickUpdate();
|
||||
|
||||
axisValues.resize(_numAxes);
|
||||
for(int ai=0; ai<_numAxes; ++ai)
|
||||
{
|
||||
axisValues[ai] = SDL_JoystickGetAxis(_joystick, ai);
|
||||
}
|
||||
|
||||
buttonValues.resize(_numButtons);
|
||||
for(int bi=0; bi<_numButtons; ++bi)
|
||||
{
|
||||
buttonValues[bi] = SDL_JoystickGetButton(_joystick, bi);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SDLIntegration::update(osgViewer::Viewer& viewer)
|
||||
{
|
||||
if (_joystick)
|
||||
{
|
||||
|
||||
ValueList newAxisValues;
|
||||
ValueList newButtonValues;
|
||||
|
||||
capture(newAxisValues, newButtonValues);
|
||||
|
||||
unsigned int mouseXaxis = 0;
|
||||
unsigned int mouseYaxis = 1;
|
||||
|
||||
float prev_mx = (float)_axisValues[mouseXaxis]/32767.0f;
|
||||
float prev_my = -(float)_axisValues[mouseYaxis]/32767.0f;
|
||||
|
||||
float mx = (float)newAxisValues[mouseXaxis]/32767.0f;
|
||||
float my = -(float)newAxisValues[mouseYaxis]/32767.0f;
|
||||
|
||||
|
||||
osgGA::EventQueue* eq = viewer.getEventQueue();
|
||||
double time = eq ? eq->getTime() : 0.0;
|
||||
osgGA::GUIEventAdapter* previous_event = eq->getCurrentEventState();
|
||||
float projected_mx = previous_event->getXmin() + (mx+1.0)*0.5*(previous_event->getXmax()-previous_event->getXmin());
|
||||
float projected_my = previous_event->getYmin() + (my+1.0)*0.5*(previous_event->getYmax()-previous_event->getYmin());
|
||||
|
||||
if (mx!=prev_mx || my!=prev_my)
|
||||
{
|
||||
eq->mouseMotion(projected_mx, projected_my, time);
|
||||
}
|
||||
|
||||
|
||||
if (_verbose)
|
||||
{
|
||||
for(int ai=0; ai<_numAxes; ++ai)
|
||||
{
|
||||
if (newAxisValues[ai]!=_axisValues[ai])
|
||||
{
|
||||
std::cout<<"axis "<<ai<<" moved to "<<newAxisValues[ai]<<std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(int bi=0; bi<_numButtons; ++bi)
|
||||
{
|
||||
if (newButtonValues[bi]!=_buttonValues[bi])
|
||||
{
|
||||
if (_verbose)
|
||||
{
|
||||
std::cout<<"button "<<bi<<" changed to "<<newButtonValues[bi]<<std::endl;
|
||||
}
|
||||
|
||||
int key = getKeyMapping(bi);
|
||||
int mouseButton = getMouseButtonMapping(bi);
|
||||
|
||||
if (mouseButton>0)
|
||||
{
|
||||
if (newButtonValues[bi]==0) eq->mouseButtonRelease(projected_mx,projected_my,mouseButton,time);
|
||||
else eq->mouseButtonPress(projected_mx,projected_my,mouseButton,time);
|
||||
}
|
||||
else if (key>0)
|
||||
{
|
||||
|
||||
if (newButtonValues[bi]==0) eq->keyRelease(key,time);
|
||||
else eq->keyPress(key,time);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_axisValues.swap(newAxisValues);
|
||||
_buttonValues.swap(newButtonValues);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
76
applications/present3D/SDLIntegration.h
Normal file
76
applications/present3D/SDLIntegration.h
Normal file
@ -0,0 +1,76 @@
|
||||
/* -*-c++-*- Present3D - Copyright (C) 1999-2006 Robert Osfield
|
||||
*
|
||||
* This software is open source and may be redistributed and/or modified under
|
||||
* the terms of the GNU General Public License (GPL) version 2.0.
|
||||
* The full license is in LICENSE.txt file included with this distribution,.
|
||||
*
|
||||
* This software is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* include LICENSE.txt for more details.
|
||||
*/
|
||||
|
||||
#ifndef SDLINTEGRATION
|
||||
#define SDLINTEGRATION
|
||||
|
||||
#include <SDL.h>
|
||||
#include <SDL_events.h>
|
||||
#include <SDL_joystick.h>
|
||||
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
class SDLIntegration
|
||||
{
|
||||
public:
|
||||
|
||||
SDLIntegration();
|
||||
~SDLIntegration();
|
||||
|
||||
typedef std::vector<int> ValueList;
|
||||
typedef std::map<int, int> ButtonMap;
|
||||
|
||||
void update(osgViewer::Viewer& viewer);
|
||||
|
||||
void addMouseButtonMapping(int joystickButton, int mouseButton)
|
||||
{
|
||||
_mouseButtonMap[joystickButton] = mouseButton;
|
||||
}
|
||||
|
||||
int getMouseButtonMapping(int joystickButton)
|
||||
{
|
||||
ButtonMap::const_iterator itr = _mouseButtonMap.find(joystickButton);
|
||||
if (itr != _mouseButtonMap.end()) return itr->second;
|
||||
else return -1;
|
||||
}
|
||||
|
||||
void addKeyMapping(int joystickButton, int key)
|
||||
{
|
||||
_keyMap[joystickButton] = key;
|
||||
}
|
||||
|
||||
int getKeyMapping(int joystickButton)
|
||||
{
|
||||
ButtonMap::const_iterator itr = _keyMap.find(joystickButton);
|
||||
if (itr != _keyMap.end()) return itr->second;
|
||||
else return -1;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
void capture(ValueList& axisValues, ValueList& buttonValues) const;
|
||||
|
||||
SDL_Joystick* _joystick;
|
||||
int _numAxes;
|
||||
int _numBalls;
|
||||
int _numHats;
|
||||
int _numButtons;
|
||||
bool _verbose;
|
||||
|
||||
ValueList _axisValues;
|
||||
ValueList _buttonValues;
|
||||
ButtonMap _mouseButtonMap;
|
||||
ButtonMap _keyMap;
|
||||
};
|
||||
|
||||
#endif
|
64
applications/present3D/ShowEventHandler.cpp
Normal file
64
applications/present3D/ShowEventHandler.cpp
Normal file
@ -0,0 +1,64 @@
|
||||
/* -*-c++-*- Present3D - Copyright (C) 1999-2006 Robert Osfield
|
||||
*
|
||||
* This software is open source and may be redistributed and/or modified under
|
||||
* the terms of the GNU General Public License (GPL) version 2.0.
|
||||
* The full license is in LICENSE.txt file included with this distribution,.
|
||||
*
|
||||
* This software is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* include LICENSE.txt for more details.
|
||||
*/
|
||||
|
||||
#include "ShowEventHandler.h"
|
||||
|
||||
#include <osgViewer/Viewer>
|
||||
#include <osg/Notify>
|
||||
|
||||
using namespace p3d;
|
||||
|
||||
ShowEventHandler::ShowEventHandler()
|
||||
{
|
||||
}
|
||||
|
||||
bool ShowEventHandler::handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter& /*aa*/, osg::Object* object, osg::NodeVisitor* /*nv*/)
|
||||
{
|
||||
switch(ea.getEventType())
|
||||
{
|
||||
case(osgGA::GUIEventAdapter::KEYUP):
|
||||
{
|
||||
osg::notify(osg::INFO)<<"ShowEventHandler KEYUP "<<(int)ea.getKey()<<std::endl;
|
||||
if (ea.getKey()>=osgGA::GUIEventAdapter::KEY_F1 &&
|
||||
ea.getKey()<=osgGA::GUIEventAdapter::KEY_F8)
|
||||
{
|
||||
unsigned int child = ea.getKey()-osgGA::GUIEventAdapter::KEY_F1;
|
||||
osg::notify(osg::INFO)<<" Select "<<child<<std::endl;
|
||||
osg::Switch* showSwitch = dynamic_cast<osg::Switch*>(object);
|
||||
if (showSwitch)
|
||||
{
|
||||
if (child<showSwitch->getNumChildren())
|
||||
{
|
||||
osg::notify(osg::INFO)<<" Switched "<<child<<std::endl;
|
||||
showSwitch->setSingleChildOn(child);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void ShowEventHandler::accept(osgGA::GUIEventHandlerVisitor& v)
|
||||
{
|
||||
v.visit(*this);
|
||||
}
|
||||
|
||||
void ShowEventHandler::getUsage(osg::ApplicationUsage& /*usage*/) const
|
||||
{
|
||||
}
|
||||
|
40
applications/present3D/ShowEventHandler.h
Normal file
40
applications/present3D/ShowEventHandler.h
Normal file
@ -0,0 +1,40 @@
|
||||
/* -*-c++-*- Present3D - Copyright (C) 1999-2006 Robert Osfield
|
||||
*
|
||||
* This software is open source and may be redistributed and/or modified under
|
||||
* the terms of the GNU General Public License (GPL) version 2.0.
|
||||
* The full license is in LICENSE.txt file included with this distribution,.
|
||||
*
|
||||
* This software is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* include LICENSE.txt for more details.
|
||||
*/
|
||||
|
||||
#ifndef SHOWEVENTHANDLER
|
||||
#define SHOWEVENTHANDLER 1
|
||||
|
||||
#include <osg/StateSet>
|
||||
#include <osg/Point>
|
||||
|
||||
#include <osgGA/GUIEventHandler>
|
||||
|
||||
namespace p3d
|
||||
{
|
||||
|
||||
class ShowEventHandler : public osgGA::GUIEventHandler
|
||||
{
|
||||
public:
|
||||
|
||||
ShowEventHandler();
|
||||
|
||||
virtual bool handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter& aa, osg::Object* object, osg::NodeVisitor* nv);
|
||||
|
||||
virtual void accept(osgGA::GUIEventHandlerVisitor& v);
|
||||
|
||||
virtual void getUsage(osg::ApplicationUsage& usage) const;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
1294
applications/present3D/SlideEventHandler.cpp
Normal file
1294
applications/present3D/SlideEventHandler.cpp
Normal file
File diff suppressed because it is too large
Load Diff
215
applications/present3D/SlideEventHandler.h
Normal file
215
applications/present3D/SlideEventHandler.h
Normal file
@ -0,0 +1,215 @@
|
||||
/* -*-c++-*- Present3D - Copyright (C) 1999-2006 Robert Osfield
|
||||
*
|
||||
* This software is open source and may be redistributed and/or modified under
|
||||
* the terms of the GNU General Public License (GPL) version 2.0.
|
||||
* The full license is in LICENSE.txt file included with this distribution,.
|
||||
*
|
||||
* This software is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* include LICENSE.txt for more details.
|
||||
*/
|
||||
|
||||
#ifndef SLIDEEVENTHANDLER
|
||||
#define SLIDEEVENTHANDLER 1
|
||||
|
||||
#include <osg/Switch>
|
||||
#include <osg/Timer>
|
||||
|
||||
#include <osgGA/GUIEventHandler>
|
||||
#include <osgViewer/Viewer>
|
||||
|
||||
#include "CompileSlideCallback.h"
|
||||
#include "SlideShowConstructor.h"
|
||||
|
||||
|
||||
struct dereference_less
|
||||
{
|
||||
template<class T, class U>
|
||||
inline bool operator() (const T& lhs,const U& rhs) const
|
||||
{
|
||||
return *lhs < *rhs;
|
||||
}
|
||||
};
|
||||
|
||||
struct ObjectOperator : public osg::Referenced
|
||||
{
|
||||
inline bool operator < (const ObjectOperator& rhs) const { return ptr() < rhs.ptr(); }
|
||||
|
||||
virtual void* ptr() const = 0;
|
||||
|
||||
virtual void enter() = 0;
|
||||
virtual void maintain() = 0;
|
||||
virtual void leave() = 0;
|
||||
virtual void setPause(bool pause) = 0;
|
||||
virtual void reset() = 0;
|
||||
|
||||
virtual ~ObjectOperator() {}
|
||||
};
|
||||
|
||||
class ActiveOperators
|
||||
{
|
||||
public:
|
||||
ActiveOperators();
|
||||
~ActiveOperators();
|
||||
|
||||
void collect(osg::Node* incommingNode, osg::NodeVisitor::TraversalMode tm = osg::NodeVisitor::TRAVERSE_ACTIVE_CHILDREN);
|
||||
|
||||
void process();
|
||||
|
||||
void setPause(bool pause);
|
||||
bool getPause() const { return _pause; }
|
||||
|
||||
void reset();
|
||||
|
||||
typedef std::set< osg::ref_ptr<ObjectOperator>, dereference_less > OperatorList;
|
||||
|
||||
protected:
|
||||
|
||||
void processOutgoing();
|
||||
void processIncomming();
|
||||
void processMaintained();
|
||||
|
||||
bool _pause;
|
||||
|
||||
OperatorList _previous;
|
||||
OperatorList _current;
|
||||
|
||||
OperatorList _outgoing;
|
||||
OperatorList _incomming;
|
||||
OperatorList _maintained;
|
||||
|
||||
};
|
||||
|
||||
class SlideEventHandler : public osgGA::GUIEventHandler
|
||||
{
|
||||
public:
|
||||
|
||||
SlideEventHandler(osgViewer::Viewer* viewer=0);
|
||||
|
||||
static SlideEventHandler* instance();
|
||||
|
||||
META_Object(osgslideshowApp,SlideEventHandler);
|
||||
|
||||
void set(osg::Node* model);
|
||||
|
||||
virtual void accept(osgGA::GUIEventHandlerVisitor& v) { v.visit(*this); }
|
||||
|
||||
virtual bool handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter&);
|
||||
|
||||
virtual void getUsage(osg::ApplicationUsage& usage) const;
|
||||
|
||||
osgViewer::Viewer* getViewer() { return _viewer.get(); }
|
||||
|
||||
enum WhichPosition
|
||||
{
|
||||
FIRST_POSITION = 0,
|
||||
LAST_POSITION = 0xffffffff,
|
||||
};
|
||||
|
||||
void compileSlide(unsigned int slideNum);
|
||||
void releaseSlide(unsigned int slideNum);
|
||||
|
||||
unsigned int getNumSlides();
|
||||
|
||||
unsigned int getActiveSlide() const { return _activeSlide; }
|
||||
unsigned int getActiveLayer() const { return _activeLayer; }
|
||||
|
||||
bool selectSlide(unsigned int slideNum,unsigned int layerNum=FIRST_POSITION);
|
||||
bool selectLayer(unsigned int layerNum);
|
||||
|
||||
bool nextLayerOrSlide();
|
||||
bool previousLayerOrSlide();
|
||||
|
||||
bool nextSlide();
|
||||
bool previousSlide();
|
||||
|
||||
bool nextLayer();
|
||||
bool previousLayer();
|
||||
|
||||
bool home();
|
||||
|
||||
void setAutoSteppingActive(bool flag = true) { _autoSteppingActive = flag; }
|
||||
bool getAutoSteppingActive() const { return _autoSteppingActive; }
|
||||
|
||||
void setTimeDelayBetweenSlides(double dt) { _timePerSlide = dt; }
|
||||
double getTimeDelayBetweenSlides() const { return _timePerSlide; }
|
||||
|
||||
double getDuration(const osg::Node* node) const;
|
||||
|
||||
double getCurrentTimeDelayBetweenSlides() const;
|
||||
|
||||
void setReleaseAndCompileOnEachNewSlide(bool flag) { _releaseAndCompileOnEachNewSlide = flag; }
|
||||
bool getReleaseAndCompileOnEachNewSlide() const { return _releaseAndCompileOnEachNewSlide; }
|
||||
|
||||
void setTimeDelayOnNewSlideWithMovies(float t) { _timeDelayOnNewSlideWithMovies = t; }
|
||||
float getTimeDelayOnNewSlideWithMovies() const { return _timeDelayOnNewSlideWithMovies; }
|
||||
|
||||
void setLoopPresentation(bool loop) { _loopPresentation = loop; }
|
||||
bool getLoopPresentation() const { return _loopPresentation; }
|
||||
|
||||
void dispatchEvent(const SlideShowConstructor::KeyPosition& keyPosition);
|
||||
|
||||
enum ObjectMask
|
||||
{
|
||||
MOVIE = 1<<0,
|
||||
OBJECTS = 1<<1,
|
||||
ALL_OBJECTS = MOVIE | OBJECTS
|
||||
};
|
||||
|
||||
protected:
|
||||
|
||||
~SlideEventHandler() {}
|
||||
SlideEventHandler(const SlideEventHandler&,const osg::CopyOp&) {}
|
||||
|
||||
bool home(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter& aa);
|
||||
|
||||
void updateAlpha(bool, bool, float x, float y);
|
||||
void updateLight(float x, float y);
|
||||
|
||||
|
||||
osg::observer_ptr<osgViewer::Viewer> _viewer;
|
||||
|
||||
osg::ref_ptr<osg::Switch> _showSwitch;
|
||||
unsigned int _activePresentation;
|
||||
|
||||
osg::ref_ptr<osg::Switch> _presentationSwitch;
|
||||
unsigned int _activeSlide;
|
||||
|
||||
osg::ref_ptr<osg::Switch> _slideSwitch;
|
||||
unsigned int _activeLayer;
|
||||
|
||||
bool _firstTraversal;
|
||||
double _previousTime;
|
||||
double _timePerSlide;
|
||||
bool _autoSteppingActive;
|
||||
bool _loopPresentation;
|
||||
bool _pause;
|
||||
bool _hold;
|
||||
|
||||
bool _updateLightActive;
|
||||
bool _updateOpacityActive;
|
||||
float _previousX, _previousY;
|
||||
|
||||
bool _cursorOn;
|
||||
|
||||
bool _releaseAndCompileOnEachNewSlide;
|
||||
|
||||
bool _firstSlideOrLayerChange;
|
||||
osg::Timer_t _tickAtFirstSlideOrLayerChange;
|
||||
osg::Timer_t _tickAtLastSlideOrLayerChange;
|
||||
|
||||
float _timeDelayOnNewSlideWithMovies;
|
||||
|
||||
double _minimumTimeBetweenKeyPresses;
|
||||
double _timeLastKeyPresses;
|
||||
|
||||
ActiveOperators _activeOperators;
|
||||
|
||||
osg::ref_ptr<ss3d::CompileSlideCallback> _compileSlideCallback;
|
||||
|
||||
void updateOperators();
|
||||
|
||||
};
|
||||
|
||||
#endif
|
1873
applications/present3D/SlideShowConstructor.cpp
Normal file
1873
applications/present3D/SlideShowConstructor.cpp
Normal file
File diff suppressed because it is too large
Load Diff
518
applications/present3D/SlideShowConstructor.h
Normal file
518
applications/present3D/SlideShowConstructor.h
Normal file
@ -0,0 +1,518 @@
|
||||
/* -*-c++-*- Present3D - Copyright (C) 1999-2006 Robert Osfield
|
||||
*
|
||||
* This software is open source and may be redistributed and/or modified under
|
||||
* the terms of the GNU General Public License (GPL) version 2.0.
|
||||
* The full license is in LICENSE.txt file included with this distribution,.
|
||||
*
|
||||
* This software is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* include LICENSE.txt for more details.
|
||||
*/
|
||||
|
||||
#ifndef SLIDESHOWCONSTRUCTOR
|
||||
#define SLIDESHOWCONSTRUCTOR
|
||||
|
||||
#include <osg/Vec3>
|
||||
#include <osg/Vec4>
|
||||
#include <osg/Group>
|
||||
#include <osg/ClearNode>
|
||||
#include <osg/Switch>
|
||||
#include <osg/AnimationPath>
|
||||
#include <osg/ImageStream>
|
||||
#include <osgText/Text>
|
||||
#include <osgGA/GUIEventAdapter>
|
||||
|
||||
#include <osgDB/FileUtils>
|
||||
|
||||
#include "AnimationMaterial.h"
|
||||
|
||||
class SlideShowConstructor
|
||||
{
|
||||
public:
|
||||
|
||||
|
||||
enum CoordinateFrame { SLIDE, MODEL };
|
||||
|
||||
struct HomePosition : public virtual osg::Referenced
|
||||
{
|
||||
HomePosition() {}
|
||||
|
||||
HomePosition(const osg::Vec3& in_eye, const osg::Vec3& in_center, const osg::Vec3& in_up):
|
||||
eye(in_eye),
|
||||
center(in_center),
|
||||
up(in_up) {}
|
||||
|
||||
osg::Vec3 eye;
|
||||
osg::Vec3 center;
|
||||
osg::Vec3 up;
|
||||
};
|
||||
|
||||
struct KeyPosition
|
||||
{
|
||||
KeyPosition(unsigned int key=0, float x=FLT_MAX, float y=FLT_MAX):
|
||||
_key((osgGA::GUIEventAdapter::KeySymbol)key),
|
||||
_x(x),
|
||||
_y(y) {}
|
||||
|
||||
|
||||
void set(unsigned int key=0, float x=FLT_MAX, float y=FLT_MAX)
|
||||
{
|
||||
_key = (osgGA::GUIEventAdapter::KeySymbol)key;
|
||||
_x = x;
|
||||
_y = y;
|
||||
}
|
||||
|
||||
osgGA::GUIEventAdapter::KeySymbol _key;
|
||||
float _x;
|
||||
float _y;
|
||||
};
|
||||
|
||||
struct LayerCallback : public virtual osg::Referenced
|
||||
{
|
||||
virtual void operator() (osg::Node* node) const = 0;
|
||||
};
|
||||
|
||||
struct LayerAttributes : public virtual osg::Referenced
|
||||
{
|
||||
LayerAttributes():_duration(0),_relativeJump(true),_slideNum(0),_layerNum(0) {}
|
||||
LayerAttributes(double in_duration):_duration(in_duration),_relativeJump(true),_slideNum(0),_layerNum(0) {}
|
||||
|
||||
void setDuration(double duration) { _duration = duration; }
|
||||
double getDuration() const { return _duration; }
|
||||
|
||||
typedef std::vector<KeyPosition> Keys;
|
||||
typedef std::vector<std::string> RunStrings;
|
||||
|
||||
void setKeys(const Keys& keys) { _keys = keys; }
|
||||
const Keys& getKeys() const { return _keys; }
|
||||
|
||||
void addKey(const KeyPosition& kp) { _keys.push_back(kp); }
|
||||
|
||||
void setRunStrings(const RunStrings& runStrings) { _runStrings = runStrings; }
|
||||
const RunStrings& getRunStrings() const { return _runStrings; }
|
||||
|
||||
void addRunString(const std::string& runString) { _runStrings.push_back(runString); }
|
||||
|
||||
void setJump(bool relativeJump, int slideNum, int layerNum)
|
||||
{
|
||||
_relativeJump = relativeJump;
|
||||
_slideNum = slideNum;
|
||||
_layerNum = layerNum;
|
||||
}
|
||||
|
||||
bool getRelativeJump() const { return _relativeJump; }
|
||||
int getSlideNum() const { return _slideNum; }
|
||||
int getLayerNum() const { return _layerNum; }
|
||||
|
||||
bool requiresJump() const { return _relativeJump ? (_slideNum!=0 || _layerNum!=0) : true; }
|
||||
|
||||
double _duration;
|
||||
Keys _keys;
|
||||
RunStrings _runStrings;
|
||||
|
||||
bool _relativeJump;
|
||||
int _slideNum;
|
||||
int _layerNum;
|
||||
|
||||
void addEnterCallback(LayerCallback* lc) { _enterLayerCallbacks.push_back(lc); }
|
||||
void addLeaveCallback(LayerCallback* lc) { _leaveLayerCallbacks.push_back(lc); }
|
||||
|
||||
void callEnterCallbacks(osg::Node* node);
|
||||
void callLeaveCallbacks(osg::Node* node);
|
||||
|
||||
typedef std::list< osg::ref_ptr<LayerCallback> > LayerCallbacks;
|
||||
LayerCallbacks _enterLayerCallbacks;
|
||||
LayerCallbacks _leaveLayerCallbacks;
|
||||
};
|
||||
|
||||
|
||||
LayerAttributes* getOrCreateLayerAttributes(osg::Node* node);
|
||||
|
||||
void setDuration(osg::Node* node,double duration)
|
||||
{
|
||||
getOrCreateLayerAttributes(node)->setDuration(duration);
|
||||
}
|
||||
|
||||
void addKey(osg::Node* node,const KeyPosition& kp)
|
||||
{
|
||||
getOrCreateLayerAttributes(node)->addKey(kp);
|
||||
}
|
||||
|
||||
void addRunString(osg::Node* node, const std::string& runString)
|
||||
{
|
||||
getOrCreateLayerAttributes(node)->addRunString(runString);
|
||||
}
|
||||
|
||||
void setJump(osg::Node* node, bool relativeJump, int slideNum, int layerNum)
|
||||
{
|
||||
getOrCreateLayerAttributes(node)->setJump(relativeJump, slideNum, layerNum);
|
||||
}
|
||||
|
||||
void addPresentationKey(const KeyPosition& kp)
|
||||
{
|
||||
if (!_presentationSwitch) createPresentation();
|
||||
if (_presentationSwitch.valid()) addKey( _presentationSwitch.get(), kp);
|
||||
}
|
||||
|
||||
void addPresentationRunString(const std::string& runString)
|
||||
{
|
||||
if (!_presentationSwitch) createPresentation();
|
||||
if (_presentationSwitch.valid()) addRunString( _presentationSwitch.get(),runString);
|
||||
}
|
||||
|
||||
void addSlideKey(const KeyPosition& kp)
|
||||
{
|
||||
if (!_slide) addSlide();
|
||||
if (_slide.valid()) addKey(_slide.get(),kp);
|
||||
}
|
||||
|
||||
void addSlideRunString(const std::string& runString)
|
||||
{
|
||||
if (!_slide) addSlide();
|
||||
if (_slide.valid()) addRunString(_slide.get(),runString);
|
||||
}
|
||||
|
||||
void setSlideJump(bool relativeJump, int switchNum, int layerNum)
|
||||
{
|
||||
if (!_slide) addSlide();
|
||||
if (_slide.valid()) setJump(_slide.get(),relativeJump, switchNum, layerNum);
|
||||
}
|
||||
|
||||
void addLayerKey(const KeyPosition& kp)
|
||||
{
|
||||
if (!_currentLayer) addLayer();
|
||||
if (_currentLayer.valid()) addKey(_currentLayer.get(),kp);
|
||||
}
|
||||
|
||||
void addLayerRunString(const std::string& runString)
|
||||
{
|
||||
if (!_currentLayer) addLayer();
|
||||
if (_currentLayer.valid()) addRunString(_currentLayer.get(),runString);
|
||||
}
|
||||
|
||||
|
||||
void setLayerJump(bool relativeJump, int switchNum, int layerNum)
|
||||
{
|
||||
if (!_currentLayer) addLayer();
|
||||
if (_currentLayer.valid()) setJump(_currentLayer.get(),relativeJump, switchNum, layerNum);
|
||||
}
|
||||
|
||||
struct FilePathData : public virtual osg::Referenced
|
||||
{
|
||||
FilePathData(const osgDB::FilePathList& fpl):filePathList(fpl) {}
|
||||
|
||||
osgDB::FilePathList filePathList;
|
||||
};
|
||||
|
||||
|
||||
struct PositionData
|
||||
{
|
||||
PositionData():
|
||||
frame(SlideShowConstructor::SLIDE),
|
||||
position(0.0f,1.0f,0.0f),
|
||||
//position(0.5f,0.5f,0.0f),
|
||||
scale(1.0f,1.0f,1.0f),
|
||||
rotate(0.0f,0.0f,0.0f,1.0f),
|
||||
rotation(0.0f,0.0f,1.0f,0.0f),
|
||||
absolute_path(false),
|
||||
inverse_path(false),
|
||||
path_time_offset(0.0),
|
||||
path_time_multiplier(1.0f),
|
||||
path_loop_mode(osg::AnimationPath::NO_LOOPING),
|
||||
animation_material_time_offset(0.0),
|
||||
animation_material_time_multiplier(1.0),
|
||||
animation_material_loop_mode(ss3d::AnimationMaterial::NO_LOOPING) {}
|
||||
|
||||
bool requiresPosition() const
|
||||
{
|
||||
return (position[0]!=0.0f || position[1]!=1.0f || position[2]!=1.0f);
|
||||
}
|
||||
|
||||
bool requiresScale() const
|
||||
{
|
||||
return (scale[0]!=1.0f || scale[1]!=1.0f || scale[2]!=1.0f);
|
||||
}
|
||||
|
||||
bool requiresRotate() const
|
||||
{
|
||||
return rotate[0]!=0.0f;
|
||||
}
|
||||
|
||||
bool requiresAnimation() const
|
||||
{
|
||||
return (rotation[0]!=0.0f || !path.empty());
|
||||
}
|
||||
|
||||
bool requiresMaterialAnimation() const
|
||||
{
|
||||
return !animation_material_filename.empty() || !fade.empty();
|
||||
}
|
||||
|
||||
CoordinateFrame frame;
|
||||
osg::Vec3 position;
|
||||
osg::Vec3 scale;
|
||||
osg::Vec4 rotate;
|
||||
osg::Vec4 rotation;
|
||||
std::string animation_name;
|
||||
bool absolute_path;
|
||||
bool inverse_path;
|
||||
double path_time_offset;
|
||||
double path_time_multiplier;
|
||||
osg::AnimationPath::LoopMode path_loop_mode;
|
||||
std::string path;
|
||||
double animation_material_time_offset;
|
||||
double animation_material_time_multiplier;
|
||||
ss3d::AnimationMaterial::LoopMode animation_material_loop_mode;
|
||||
std::string animation_material_filename;
|
||||
std::string fade;
|
||||
};
|
||||
|
||||
struct ModelData
|
||||
{
|
||||
ModelData():
|
||||
effect("") {}
|
||||
|
||||
std::string effect;
|
||||
};
|
||||
|
||||
struct ImageData
|
||||
{
|
||||
ImageData():
|
||||
width(1.0f),
|
||||
height(1.0f),
|
||||
region(0.0f,0.0f,1.0f,1.0f),
|
||||
region_in_pixel_coords(false),
|
||||
texcoord_rotate(0.0f),
|
||||
loopingMode(osg::ImageStream::NO_LOOPING),
|
||||
page(-1),
|
||||
backgroundColor(1.0f,1.0f,1.0f,1.0f) {}
|
||||
|
||||
float width;
|
||||
float height;
|
||||
osg::Vec4 region;
|
||||
bool region_in_pixel_coords;
|
||||
float texcoord_rotate;
|
||||
osg::ImageStream::LoopingMode loopingMode;
|
||||
int page;
|
||||
osg::Vec4 backgroundColor;
|
||||
};
|
||||
|
||||
struct FontData
|
||||
{
|
||||
FontData():
|
||||
font("fonts/arial.ttf"),
|
||||
layout(osgText::Text::LEFT_TO_RIGHT),
|
||||
alignment(osgText::Text::LEFT_BASE_LINE),
|
||||
axisAlignment(osgText::Text::XZ_PLANE),
|
||||
characterSize(0.04f),
|
||||
maximumHeight(1.0f),
|
||||
maximumWidth(1.0f),
|
||||
color(1.0f,1.0f,1.0f,1.0f) {}
|
||||
|
||||
std::string font;
|
||||
osgText::Text::Layout layout;
|
||||
osgText::Text::AlignmentType alignment;
|
||||
osgText::Text::AxisAlignment axisAlignment;
|
||||
float characterSize;
|
||||
float maximumHeight;
|
||||
float maximumWidth;
|
||||
osg::Vec4 color;
|
||||
};
|
||||
|
||||
/// Operations related to click to run/load/key events.
|
||||
enum Operation
|
||||
{
|
||||
RUN,
|
||||
LOAD,
|
||||
EVENT,
|
||||
JUMP
|
||||
};
|
||||
|
||||
SlideShowConstructor();
|
||||
|
||||
void createPresentation();
|
||||
|
||||
void setBackgroundColor(const osg::Vec4& color, bool updateClearNode);
|
||||
const osg::Vec4& getBackgroundColor() const { return _backgroundColor; }
|
||||
|
||||
void setTextColor(const osg::Vec4& color);
|
||||
const osg::Vec4& getTextColor() const { return _textFontDataDefault.color; }
|
||||
|
||||
void setPresentationName(const std::string& name);
|
||||
|
||||
void setPresentationAspectRatio(float aspectRatio);
|
||||
|
||||
void setPresentationAspectRatio(const std::string& str);
|
||||
|
||||
void setPresentationDuration(double duration);
|
||||
|
||||
|
||||
void addSlide();
|
||||
|
||||
void selectSlide(int slideNum);
|
||||
|
||||
|
||||
void setSlideTitle(const std::string& name, PositionData& positionData, FontData& fontData)
|
||||
{
|
||||
_titlePositionData = positionData;
|
||||
_titleFontData = fontData;
|
||||
_slideTitle = name;
|
||||
}
|
||||
|
||||
void setSlideBackground(const std::string& name) { _slideBackgroundImageFileName = name; }
|
||||
|
||||
void setSlideDuration(double duration);
|
||||
|
||||
|
||||
void addLayer(bool inheritPreviousLayers=true, bool defineAsBaseLayer=false);
|
||||
|
||||
void selectLayer(int layerNum);
|
||||
|
||||
void setLayerDuration(double duration);
|
||||
|
||||
|
||||
// title settings
|
||||
FontData& getTitleFontData() { return _titleFontData; }
|
||||
FontData& getTitleFontDataDefault() { return _titleFontDataDefault; }
|
||||
|
||||
PositionData& getTitlePositionData() { return _titlePositionData; }
|
||||
PositionData& getTitlePositionDataDefault() { return _titlePositionDataDefault; }
|
||||
|
||||
// text settings
|
||||
FontData& getTextFontData() { return _textFontData; }
|
||||
FontData& getTextFontDataDefault() { return _textFontDataDefault; }
|
||||
|
||||
PositionData& getTextPositionData() { return _textPositionData; }
|
||||
PositionData& getTextPositionDataDefault() { return _textPositionDataDefault; }
|
||||
|
||||
void translateTextCursor(const osg::Vec3& delta) { _textPositionData.position += delta; }
|
||||
|
||||
// image settings
|
||||
PositionData& getImagePositionData() { return _imagePositionData; }
|
||||
PositionData& getImagePositionDataDefault() { return _imagePositionDataDefault; }
|
||||
|
||||
// model settings
|
||||
PositionData& getModelPositionData() { return _modelPositionData; }
|
||||
PositionData& getModelPositionDataDefault() { return _modelPositionDataDefault; }
|
||||
|
||||
|
||||
void layerClickToDoOperation(Operation operation, bool relativeJump=true, int slideNum=0, int layerNum=0);
|
||||
void layerClickToDoOperation(const std::string& command, Operation operation, bool relativeJump=true, int slideNum=0, int layerNum=0);
|
||||
void layerClickEventOperation(const SlideShowConstructor::KeyPosition& keyPos, bool relativeJump=true, int slideNum=0, int layerNum=0);
|
||||
|
||||
void addBullet(const std::string& bullet, PositionData& positionData, FontData& fontData);
|
||||
|
||||
void addParagraph(const std::string& paragraph, PositionData& positionData, FontData& fontData);
|
||||
|
||||
void addImage(const std::string& filename,const PositionData& positionData, const ImageData& imageData);
|
||||
|
||||
void addStereoImagePair(const std::string& filenameLeft, const ImageData& imageDataLeft, const std::string& filenameRight,const ImageData& imageDataRight, const PositionData& positionData);
|
||||
|
||||
void addVNC(const std::string& filename,const PositionData& positionData, const ImageData& imageData);
|
||||
void addBrowser(const std::string& filename,const PositionData& positionData, const ImageData& imageData);
|
||||
void addPDF(const std::string& filename,const PositionData& positionData, const ImageData& imageData);
|
||||
osg::Image* addInteractiveImage(const std::string& filename,const PositionData& positionData, const ImageData& imageData);
|
||||
|
||||
void addModel(osg::Node* subgraph, const PositionData& positionData, const ModelData& modelData);
|
||||
|
||||
void addModel(const std::string& filename, const PositionData& positionData, const ModelData& modelData);
|
||||
|
||||
void addVolume(const std::string& filename, const PositionData& positionData);
|
||||
|
||||
osg::Group* takePresentation() { return _root.release(); }
|
||||
|
||||
osg::Group* getPresentation() { return _root.get(); }
|
||||
|
||||
osg::Switch* getPresentationSwitch() { return _presentationSwitch.get(); }
|
||||
|
||||
osg::Switch* getCurrentSlide() { return _slide.get(); }
|
||||
|
||||
osg::Group* getCurrentLayer() { return _currentLayer.get(); }
|
||||
|
||||
void setLoopPresentation(bool loop) { _loopPresentation = loop; }
|
||||
bool getLoopPresentation() const { return _loopPresentation; }
|
||||
|
||||
void setAutoSteppingActive(bool flag = true) { _autoSteppingActive = flag; }
|
||||
bool getAutoSteppingActive() const { return _autoSteppingActive; }
|
||||
|
||||
protected:
|
||||
|
||||
void findImageStreamsAndAddCallbacks(osg::Node* node);
|
||||
|
||||
osg::Geometry* createTexturedQuadGeometry(const osg::Vec3& pos, const osg::Vec4& rotation, float width,float height, osg::Image* image, bool& usedTextureRectangle);
|
||||
|
||||
osg::Vec3 computePositionInModelCoords(const PositionData& positionData) const;
|
||||
void updatePositionFromInModelCoords(const osg::Vec3& vertex, PositionData& positionData) const;
|
||||
|
||||
osg::Vec3 convertSlideToModel(const osg::Vec3& position) const;
|
||||
osg::Vec3 convertModelToSlide(const osg::Vec3& position) const;
|
||||
|
||||
osg::AnimationPath* readPivotPath(const std::string& filename) const;
|
||||
osg::AnimationPath* readRotationPath(const std::string& filename) const;
|
||||
|
||||
osg::AnimationPathCallback* getAnimationPathCallback(const PositionData& positionData);
|
||||
|
||||
osg::Node* attachMaterialAnimation(osg::Node* model, const PositionData& positionData);
|
||||
bool attachTexMat(osg::StateSet* stateset, const ImageData& imageData, float s, float t, bool textureRectangle);
|
||||
|
||||
osg::StateSet* createTransformStateSet()
|
||||
{
|
||||
osg::StateSet* stateset = new osg::StateSet;
|
||||
stateset->setMode(GL_NORMALIZE,osg::StateAttribute::ON);
|
||||
return stateset;
|
||||
}
|
||||
|
||||
osg::Vec3 _slideOrigin;
|
||||
osg::Vec3 _eyeOrigin;
|
||||
float _slideWidth;
|
||||
float _slideHeight;
|
||||
float _slideDistance;
|
||||
|
||||
// title settings
|
||||
FontData _titleFontData;
|
||||
FontData _titleFontDataDefault;
|
||||
|
||||
PositionData _titlePositionData;
|
||||
PositionData _titlePositionDataDefault;
|
||||
|
||||
// text settings
|
||||
FontData _textFontData;
|
||||
FontData _textFontDataDefault;
|
||||
|
||||
PositionData _textPositionData;
|
||||
PositionData _textPositionDataDefault;
|
||||
|
||||
// image settings
|
||||
PositionData _imagePositionData;
|
||||
PositionData _imagePositionDataDefault;
|
||||
|
||||
// model settings
|
||||
PositionData _modelPositionData;
|
||||
PositionData _modelPositionDataDefault;
|
||||
|
||||
|
||||
bool _loopPresentation;
|
||||
bool _autoSteppingActive;
|
||||
osg::Vec4 _backgroundColor;
|
||||
std::string _presentationName;
|
||||
double _presentationDuration;
|
||||
|
||||
osg::ref_ptr<osg::Group> _root;
|
||||
osg::ref_ptr<osg::Switch> _presentationSwitch;
|
||||
|
||||
osg::ref_ptr<osg::ClearNode> _slideClearNode;
|
||||
osg::ref_ptr<osg::Switch> _slide;
|
||||
std::string _slideTitle;
|
||||
std::string _slideBackgroundImageFileName;
|
||||
|
||||
osg::ref_ptr<osg::Group> _previousLayer;
|
||||
osg::ref_ptr<osg::Group> _currentLayer;
|
||||
|
||||
osg::ref_ptr<FilePathData> _filePathData;
|
||||
|
||||
std::string findFileAndRecordPath(const std::string& filename);
|
||||
|
||||
};
|
||||
|
||||
#endif
|
689
applications/present3D/present3D.cpp
Normal file
689
applications/present3D/present3D.cpp
Normal file
@ -0,0 +1,689 @@
|
||||
/* -*-c++-*- Present3D - Copyright (C) 1999-2006 Robert Osfield
|
||||
*
|
||||
* This software is open source and may be redistributed and/or modified under
|
||||
* the terms of the GNU General Public License (GPL) version 2.0.
|
||||
* The full license is in LICENSE.txt file included with this distribution,.
|
||||
*
|
||||
* This software is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* include LICENSE.txt for more details.
|
||||
*/
|
||||
|
||||
#include <osg/Geometry>
|
||||
#include <osg/CameraNode>
|
||||
#include <osg/Texture2D>
|
||||
#include <osg/Notify>
|
||||
|
||||
|
||||
#include <osgDB/ReadFile>
|
||||
#include <osgDB/WriteFile>
|
||||
#include <osgDB/FileNameUtils>
|
||||
#include <osgUtil/Optimizer>
|
||||
#include <osgUtil/SceneView>
|
||||
|
||||
#include <osgViewer/Viewer>
|
||||
#include <osgViewer/ViewerEventHandlers>
|
||||
|
||||
#include <OpenThreads/Thread>
|
||||
|
||||
#include <osgGA/TrackballManipulator>
|
||||
#include <osgGA/FlightManipulator>
|
||||
#include <osgGA/DriveManipulator>
|
||||
#include <osgGA/KeySwitchMatrixManipulator>
|
||||
#include <osgGA/AnimationPathManipulator>
|
||||
#include <osgGA/TerrainManipulator>
|
||||
#include <osgGA/AnimationPathManipulator>
|
||||
#include <osgGA/StateSetManipulator>
|
||||
|
||||
#include "ReadShowFile.h"
|
||||
#include "SlideEventHandler.h"
|
||||
#include "PointsEventHandler.h"
|
||||
#include "SlideShowConstructor.h"
|
||||
#include "Cluster.h"
|
||||
#include "ExportHTML.h"
|
||||
|
||||
|
||||
#include <sstream>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#ifdef USE_SDL
|
||||
#include "SDLIntegration.h"
|
||||
#endif
|
||||
|
||||
static const char* s_version = "1.3";
|
||||
|
||||
void setViewer(osgViewer::Viewer& viewer, float width, float height, float distance)
|
||||
{
|
||||
double vfov = osg::RadiansToDegrees(atan2(height/2.0f,distance)*2.0);
|
||||
double hfov = osg::RadiansToDegrees(atan2(width/2.0f,distance)*2.0);
|
||||
|
||||
viewer.getCamera()->setProjectionMatrixAsPerspective( vfov, width/height, 0.1, 1000.0);
|
||||
}
|
||||
|
||||
class FollowMouseCallback: public osgGA::GUIEventHandler
|
||||
{
|
||||
public:
|
||||
|
||||
virtual bool handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter&, osg::Object* object, osg::NodeVisitor*)
|
||||
{
|
||||
switch(ea.getEventType())
|
||||
{
|
||||
case(osgGA::GUIEventAdapter::MOVE):
|
||||
case(osgGA::GUIEventAdapter::DRAG):
|
||||
{
|
||||
osg::CameraNode* camera = dynamic_cast<osg::CameraNode*>(object);
|
||||
if (camera)
|
||||
{
|
||||
camera->setViewMatrix(osg::Matrixd::translate(ea.getX(),ea.getY(),0.0));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case(osgGA::GUIEventAdapter::KEYDOWN):
|
||||
{
|
||||
if (ea.getKey()=='c')
|
||||
{
|
||||
osg::CameraNode* camera = dynamic_cast<osg::CameraNode*>(object);
|
||||
if (camera)
|
||||
{
|
||||
for(unsigned int i=0; i< camera->getNumChildren(); ++i)
|
||||
{
|
||||
osg::Node* node = camera->getChild(i);
|
||||
node->setNodeMask(
|
||||
node->getNodeMask()!=0 ?
|
||||
0 :
|
||||
0xffffff);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual void accept(osgGA::GUIEventHandlerVisitor& v)
|
||||
{
|
||||
v.visit(*this);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
osg::Node* createCursorSubgraph(const std::string& filename, float size)
|
||||
{
|
||||
osg::Geode* geode = new osg::Geode;
|
||||
|
||||
osg::Geometry* geom = osg::createTexturedQuadGeometry(osg::Vec3(-size*0.5f,-size*0.5f,0.0f),osg::Vec3(size,0.0f,0.0f),osg::Vec3(0.0f,size,0.0f));
|
||||
|
||||
osg::Image* image = osgDB::readImageFile(osgDB::findDataFile(filename));
|
||||
if (image)
|
||||
{
|
||||
osg::StateSet* stateset = geom->getOrCreateStateSet();
|
||||
stateset->setTextureAttributeAndModes(0, new osg::Texture2D(image),osg::StateAttribute::ON);
|
||||
stateset->setMode(GL_BLEND,osg::StateAttribute::ON);
|
||||
stateset->setRenderBinDetails(1000, "DepthSortedBin");
|
||||
}
|
||||
|
||||
geode->addDrawable(geom);
|
||||
|
||||
osg::CameraNode* camera = new osg::CameraNode;
|
||||
|
||||
// set the projection matrix
|
||||
camera->setProjectionMatrix(osg::Matrix::ortho2D(-1,1,-1,1));
|
||||
|
||||
// set the view matrix
|
||||
camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
|
||||
camera->setViewMatrix(osg::Matrix::identity());
|
||||
|
||||
// only clear the depth buffer
|
||||
camera->setClearMask(GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
// draw subgraph after main camera view.
|
||||
camera->setRenderOrder(osg::CameraNode::NESTED_RENDER);
|
||||
|
||||
camera->addChild(geode);
|
||||
|
||||
camera->setEventCallback(new FollowMouseCallback());
|
||||
|
||||
return camera;
|
||||
|
||||
}
|
||||
|
||||
|
||||
enum P3DApplicationType
|
||||
{
|
||||
VIEWER,
|
||||
MASTER,
|
||||
SLAVE,
|
||||
};
|
||||
|
||||
|
||||
|
||||
int main( int argc, char **argv )
|
||||
{
|
||||
// use an ArgumentParser object to manage the program arguments.
|
||||
osg::ArgumentParser arguments(&argc,argv);
|
||||
|
||||
// set up the usage document, in case we need to print out how to use this program.
|
||||
arguments.getApplicationUsage()->setApplicationName(arguments.getApplicationName());
|
||||
arguments.getApplicationUsage()->setDescription(arguments.getApplicationName()+" is the application for presenting 3D interactive slide shows.");
|
||||
arguments.getApplicationUsage()->setCommandLineUsage(arguments.getApplicationName()+" [options] filename ...");
|
||||
arguments.getApplicationUsage()->addCommandLineOption("-h or --help","Display this information");
|
||||
arguments.getApplicationUsage()->addCommandLineOption("-a","Turn auto stepping on by default");
|
||||
arguments.getApplicationUsage()->addCommandLineOption("-d <float>","Time duration in seconds between layers/slides");
|
||||
arguments.getApplicationUsage()->addCommandLineOption("-s <float> <float> <float>","width, height, distance and of the screen away from the viewer");
|
||||
arguments.getApplicationUsage()->addCommandLineOption("--viewer","Start Present3D as the viewer version.");
|
||||
arguments.getApplicationUsage()->addCommandLineOption("--authoring","Start Presen3D as the authoring version, license required.");
|
||||
arguments.getApplicationUsage()->addCommandLineOption("--master","Start Present3D as the master version, license required.");
|
||||
arguments.getApplicationUsage()->addCommandLineOption("--slave","Start Present3D as the slave version, license required.");
|
||||
arguments.getApplicationUsage()->addCommandLineOption("--publishing","Start Present3D as the publishing version, license required.");
|
||||
arguments.getApplicationUsage()->addCommandLineOption("--timeDelayOnNewSlideWithMovies","Set the time delay on new slide with movies, done to allow movie threads to get in sync with rendering thread.");
|
||||
arguments.getApplicationUsage()->addCommandLineOption("--targetFrameRate","Set the target frame rate, defaults to 80Hz.");
|
||||
arguments.getApplicationUsage()->addCommandLineOption("--version","Report the Present3D version.");
|
||||
arguments.getApplicationUsage()->addCommandLineOption("--print <filename>","Print out slides to a series of image files.");
|
||||
arguments.getApplicationUsage()->addCommandLineOption("--html <filename>","Print out slides to a series of html & image files.");
|
||||
arguments.getApplicationUsage()->addCommandLineOption("--loop","Switch on looping of presentation.");
|
||||
arguments.getApplicationUsage()->addCommandLineOption("--devices","Print the Video input capability via QuickTime and exit.");
|
||||
|
||||
// if user requests devices video capability.
|
||||
if (arguments.read("-devices") || arguments.read("--devices"))
|
||||
{
|
||||
// Force load QuickTime plugin, probe video capability, exit
|
||||
osgDB::readImageFile("devices.live");
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
// read any env vars from presentations before we create viewer to make sure the viewer
|
||||
// utilises these env vars
|
||||
if (p3d::readEnvVars(arguments))
|
||||
{
|
||||
osg::DisplaySettings::instance()->readEnvironmentalVariables();
|
||||
}
|
||||
|
||||
|
||||
#ifdef USE_SDL
|
||||
SDLIntegration sdlIntegration;
|
||||
|
||||
osg::notify(osg::INFO)<<"USE_SDL"<<std::endl;
|
||||
#endif
|
||||
|
||||
bool doSetViewer = true;
|
||||
std::string configurationFile;
|
||||
|
||||
// check env vars for configuration file
|
||||
const char* str = getenv("PRESENT3D_CONFIG_FILE");
|
||||
if (!str) str = getenv("OSG_CONFIG_FILE");
|
||||
if (str) configurationFile = str;
|
||||
|
||||
// check command line parameters for configuration file.
|
||||
while (arguments.read("-c",configurationFile)) {}
|
||||
|
||||
osg::Vec4 clearColor(0.0f,0.0f,0.0f,0.0f);
|
||||
|
||||
while (arguments.read("--clear-color",clearColor[0],clearColor[1],clearColor[2],clearColor[3])) {}
|
||||
|
||||
// construct the viewer.
|
||||
osgViewer::Viewer viewer(arguments);
|
||||
|
||||
// set clear colour to black by default.
|
||||
viewer.getCamera()->setClearColor(clearColor);
|
||||
|
||||
if (!configurationFile.empty())
|
||||
{
|
||||
viewer.readConfiguration(configurationFile);
|
||||
doSetViewer = false;
|
||||
}
|
||||
|
||||
// set up stereo masks
|
||||
viewer.getCamera()->setCullMask(0xffffffff);
|
||||
viewer.getCamera()->setCullMaskLeft(0x00000001);
|
||||
viewer.getCamera()->setCullMaskRight(0x00000002);
|
||||
|
||||
// set up the camera manipulators.
|
||||
{
|
||||
osg::ref_ptr<osgGA::KeySwitchMatrixManipulator> keyswitchManipulator = new osgGA::KeySwitchMatrixManipulator;
|
||||
|
||||
keyswitchManipulator->addMatrixManipulator( '1', "Trackball", new osgGA::TrackballManipulator() );
|
||||
keyswitchManipulator->addMatrixManipulator( '2', "Flight", new osgGA::FlightManipulator() );
|
||||
keyswitchManipulator->addMatrixManipulator( '3', "Drive", new osgGA::DriveManipulator() );
|
||||
keyswitchManipulator->addMatrixManipulator( '4', "Terrain", new osgGA::TerrainManipulator() );
|
||||
|
||||
std::string pathfile;
|
||||
char keyForAnimationPath = '5';
|
||||
while (arguments.read("-p",pathfile))
|
||||
{
|
||||
osgGA::AnimationPathManipulator* apm = new osgGA::AnimationPathManipulator(pathfile);
|
||||
if (apm || !apm->valid())
|
||||
{
|
||||
unsigned int num = keyswitchManipulator->getNumMatrixManipulators();
|
||||
keyswitchManipulator->addMatrixManipulator( keyForAnimationPath, "Path", apm );
|
||||
keyswitchManipulator->selectMatrixManipulator(num);
|
||||
++keyForAnimationPath;
|
||||
}
|
||||
}
|
||||
|
||||
viewer.setCameraManipulator( keyswitchManipulator.get() );
|
||||
}
|
||||
|
||||
// add the state manipulator
|
||||
viewer.addEventHandler( new osgGA::StateSetManipulator(viewer.getCamera()->getOrCreateStateSet()) );
|
||||
|
||||
// add the state manipulator
|
||||
viewer.addEventHandler( new osgViewer::StatsHandler() );
|
||||
|
||||
viewer.addEventHandler( new osgViewer::WindowSizeHandler() );
|
||||
|
||||
// neeed to address.
|
||||
// viewer.getScene()->getUpdateVisitor()->setTraversalMode(osg::NodeVisitor::TRAVERSE_ACTIVE_CHILDREN);
|
||||
|
||||
|
||||
const char* p3dCursor = getenv("P3D_CURSOR");
|
||||
std::string cursorFileName( p3dCursor ? p3dCursor : "");
|
||||
while (arguments.read("--cursor",cursorFileName)) {}
|
||||
|
||||
|
||||
while (arguments.read("--set-viewer")) { doSetViewer = true; }
|
||||
|
||||
while (arguments.read("--no-set-viewer")) { doSetViewer = false; }
|
||||
|
||||
|
||||
// cluster related entries.
|
||||
int socketNumber=8100;
|
||||
while (arguments.read("-n",socketNumber)) {}
|
||||
|
||||
float camera_fov=-1.0f;
|
||||
while (arguments.read("-f",camera_fov)) {}
|
||||
|
||||
float camera_offset=45.0f;
|
||||
while (arguments.read("-o",camera_offset)) {}
|
||||
|
||||
|
||||
std::string exportName;
|
||||
while (arguments.read("--print",exportName)) {}
|
||||
|
||||
while (arguments.read("--html",exportName)) {}
|
||||
|
||||
// read any time delay argument.
|
||||
float timeDelayBetweenSlides = 1.0f;
|
||||
while (arguments.read("-d",timeDelayBetweenSlides)) {}
|
||||
|
||||
bool autoSteppingActive = false;
|
||||
while (arguments.read("-a")) autoSteppingActive = true;
|
||||
|
||||
bool loopPresentation = false;
|
||||
while (arguments.read("--loop")) loopPresentation = true;
|
||||
|
||||
// register the slide event handler - which moves the presentation from slide to slide, layer to layer.
|
||||
SlideEventHandler* seh = new SlideEventHandler(&viewer);
|
||||
viewer.addEventHandler(seh);
|
||||
|
||||
seh->setAutoSteppingActive(autoSteppingActive);
|
||||
seh->setTimeDelayBetweenSlides(timeDelayBetweenSlides);
|
||||
seh->setLoopPresentation(loopPresentation);
|
||||
|
||||
double targetFrameRate = 80.0;
|
||||
while (arguments.read("--targetFrameRate",targetFrameRate)) {}
|
||||
|
||||
|
||||
// set the time delay
|
||||
float timeDelayOnNewSlideWithMovies = 0.4f;
|
||||
while (arguments.read("--timeDelayOnNewSlideWithMovies",timeDelayOnNewSlideWithMovies)) {}
|
||||
seh->setTimeDelayOnNewSlideWithMovies(timeDelayOnNewSlideWithMovies);
|
||||
|
||||
// set up optimizer options
|
||||
unsigned int optimizer_options = osgUtil::Optimizer::DEFAULT_OPTIMIZATIONS;
|
||||
bool relase_and_compile = false;
|
||||
while (arguments.read("--release-and-compile"))
|
||||
{
|
||||
relase_and_compile = true;
|
||||
}
|
||||
seh->setReleaseAndCompileOnEachNewSlide(relase_and_compile);
|
||||
if (relase_and_compile)
|
||||
{
|
||||
// make sure that imagery stays around after being applied to textures.
|
||||
viewer.getDatabasePager()->setUnrefImageDataAfterApplyPolicy(true,false);
|
||||
// optimizer_options &= ~osgUtil::Optimizer::OPTIMIZE_TEXTURE_SETTINGS;
|
||||
// viewer.setRealizeSceneViewOptions(viewer.getRealizeSceneViewOptions() & ~osgUtil::SceneView::COMPILE_GLOBJECTS_AT_INIT);
|
||||
}
|
||||
//
|
||||
// osgDB::Registry::instance()->getOrCreateDatabasePager()->setUnrefImageDataAfterApplyPolicy(true,false);
|
||||
// optimizer_options &= ~osgUtil::Optimizer::OPTIMIZE_TEXTURE_SETTINGS;
|
||||
// osg::Texture::getTextureObjectManager()->setExpiryDelay(0.0f);
|
||||
// osgDB::Registry::instance()->getOrCreateDatabasePager()->setExpiryDelay(1.0f);
|
||||
|
||||
// register the handler for modifying the point size
|
||||
PointsEventHandler* peh = new PointsEventHandler;
|
||||
viewer.addEventHandler(peh);
|
||||
|
||||
// osg::DisplaySettings::instance()->setSplitStereoAutoAjustAspectRatio(false);
|
||||
|
||||
float width = osg::DisplaySettings::instance()->getScreenWidth();
|
||||
float height = osg::DisplaySettings::instance()->getScreenHeight();
|
||||
float distance = osg::DisplaySettings::instance()->getScreenDistance();
|
||||
bool sizesSpecified = false;
|
||||
while (arguments.read("-s", width, height, distance))
|
||||
{
|
||||
sizesSpecified = true;
|
||||
|
||||
osg::DisplaySettings::instance()->setScreenDistance(distance);
|
||||
osg::DisplaySettings::instance()->setScreenHeight(height);
|
||||
osg::DisplaySettings::instance()->setScreenWidth(width);
|
||||
}
|
||||
|
||||
// get details on keyboard and mouse bindings used by the viewer.
|
||||
viewer.getUsage(*arguments.getApplicationUsage());
|
||||
|
||||
// if user request help write it out to cout.
|
||||
if (arguments.read("-h") || arguments.read("--help"))
|
||||
{
|
||||
arguments.getApplicationUsage()->write(osg::notify(osg::NOTICE));
|
||||
return 1;
|
||||
}
|
||||
|
||||
P3DApplicationType P3DApplicationType = VIEWER;
|
||||
|
||||
str = getenv("PRESENT3D_TYPE");
|
||||
if (str)
|
||||
{
|
||||
if (strcmp(str,"viewer")==0) P3DApplicationType = VIEWER;
|
||||
else if (strcmp(str,"master")==0) P3DApplicationType = MASTER;
|
||||
else if (strcmp(str,"slave")==0) P3DApplicationType = SLAVE;
|
||||
}
|
||||
|
||||
while (arguments.read("--viewer")) { P3DApplicationType = VIEWER; }
|
||||
while (arguments.read("--master")) { P3DApplicationType = MASTER; }
|
||||
while (arguments.read("--slave")) { P3DApplicationType = SLAVE; }
|
||||
|
||||
while (arguments.read("--version"))
|
||||
{
|
||||
std::string appTypeName = "invalid";
|
||||
switch(P3DApplicationType)
|
||||
{
|
||||
case(VIEWER): appTypeName = "viewer"; break;
|
||||
case(MASTER): appTypeName = "master"; break;
|
||||
case(SLAVE): appTypeName = "slave"; break;
|
||||
}
|
||||
|
||||
osg::notify(osg::NOTICE)<<std::endl;
|
||||
osg::notify(osg::NOTICE)<<"Present3D "<<appTypeName<<" version : "<<s_version<<std::endl;
|
||||
osg::notify(osg::NOTICE)<<std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// any option left unread are converted into errors to write out later.
|
||||
//arguments.reportRemainingOptionsAsUnrecognized();
|
||||
|
||||
// report any errors if they have occured when parsing the program aguments.
|
||||
if (arguments.errors())
|
||||
{
|
||||
arguments.writeErrorMessages(osg::notify(osg::INFO));
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
// read files name from arguments.
|
||||
p3d::FileNameList xmlFiles, normalFiles;
|
||||
if (!p3d::getFileNames(arguments, xmlFiles, normalFiles))
|
||||
{
|
||||
osg::notify(osg::NOTICE)<<std::endl;
|
||||
osg::notify(osg::NOTICE)<<"No file specified, please specify and file to load."<<std::endl;
|
||||
osg::notify(osg::NOTICE)<<std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool viewerInitialized = false;
|
||||
if (!xmlFiles.empty())
|
||||
{
|
||||
osg::ref_ptr<osg::Node> holdingModel = p3d::readHoldingSlide(xmlFiles.front());
|
||||
|
||||
if (holdingModel.valid())
|
||||
{
|
||||
viewer.setSceneData(holdingModel.get());
|
||||
|
||||
if (!viewerInitialized)
|
||||
{
|
||||
// pass the global stateset to the point event handler so that it can
|
||||
// alter the point size of all points in the scene.
|
||||
peh->setStateSet(viewer.getCamera()->getOrCreateStateSet());
|
||||
|
||||
// create the windows and run the threads.
|
||||
viewer.realize();
|
||||
|
||||
if (doSetViewer) setViewer(viewer, width, height, distance);
|
||||
|
||||
viewerInitialized = true;
|
||||
}
|
||||
|
||||
seh->home();
|
||||
|
||||
// render a frame
|
||||
viewer.frame();
|
||||
}
|
||||
}
|
||||
|
||||
osg::Timer timer;
|
||||
osg::Timer_t start_tick = timer.tick();
|
||||
|
||||
|
||||
osg::ref_ptr<osgDB::ReaderWriter::Options> cacheAllOption = new osgDB::ReaderWriter::Options;
|
||||
cacheAllOption->setObjectCacheHint(osgDB::ReaderWriter::Options::CACHE_ALL);
|
||||
|
||||
osgDB::Registry::instance()->setOptions(cacheAllOption.get());
|
||||
|
||||
// read the scene from the list of file specified commandline args.
|
||||
osg::ref_ptr<osg::Node> loadedModel = p3d::readShowFiles(arguments,cacheAllOption.get()); // osgDB::readNodeFiles(arguments, cacheAllOption.get());
|
||||
|
||||
|
||||
osgDB::Registry::instance()->setOptions( 0 );
|
||||
|
||||
|
||||
// if no model has been successfully loaded report failure.
|
||||
if (!loadedModel)
|
||||
{
|
||||
osg::notify(osg::INFO) << arguments.getApplicationName() <<": No data loaded" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
osg::Timer_t end_tick = timer.tick();
|
||||
|
||||
osg::notify(osg::INFO) << "Time to load = "<<timer.delta_s(start_tick,end_tick)<<std::endl;
|
||||
|
||||
|
||||
if (loadedModel->getNumDescriptions()>0)
|
||||
{
|
||||
for(unsigned int i=0; i<loadedModel->getNumDescriptions(); ++i)
|
||||
{
|
||||
const std::string& desc = loadedModel->getDescription(i);
|
||||
if (desc=="loop")
|
||||
{
|
||||
osg::notify(osg::NOTICE)<<"Enabling looping"<<std::endl;
|
||||
seh->setLoopPresentation(true);
|
||||
}
|
||||
else if (desc=="auto")
|
||||
{
|
||||
osg::notify(osg::NOTICE)<<"Enabling auto run"<<std::endl;
|
||||
seh->setAutoSteppingActive(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#if 1
|
||||
// add back in enabling of the GL_ALPHA_TEST to get around the core OSG no longer setting it by default for opaque bins.
|
||||
// the alpha test is required for the volume rendering alpha clipping to work.
|
||||
loadedModel->getOrCreateStateSet()->setMode(GL_ALPHA_TEST, osg::StateAttribute::ON);
|
||||
#endif
|
||||
|
||||
|
||||
// optimize the scene graph, remove rendundent nodes and state etc.
|
||||
osgUtil::Optimizer optimizer;
|
||||
optimizer.optimize(loadedModel.get(), optimizer_options);
|
||||
|
||||
if (!cursorFileName.empty())
|
||||
{
|
||||
osg::ref_ptr<osg::Group> group = new osg::Group;
|
||||
group->addChild(loadedModel.get());
|
||||
group->addChild(createCursorSubgraph(cursorFileName, 0.05f));
|
||||
|
||||
loadedModel = group.get();
|
||||
}
|
||||
|
||||
// set the scene to render
|
||||
viewer.setSceneData(loadedModel.get());
|
||||
|
||||
if (!viewerInitialized)
|
||||
{
|
||||
// pass the global stateset to the point event handler so that it can
|
||||
// alter the point size of all points in the scene.
|
||||
peh->setStateSet(viewer.getCamera()->getOrCreateStateSet());
|
||||
|
||||
// create the windows and run the threads.
|
||||
viewer.realize();
|
||||
|
||||
if (doSetViewer) setViewer(viewer, width, height, distance);
|
||||
|
||||
viewerInitialized = true;
|
||||
}
|
||||
|
||||
if (!cursorFileName.empty())
|
||||
{
|
||||
// switch off the cursor
|
||||
osgViewer::Viewer::Windows windows;
|
||||
viewer.getWindows(windows);
|
||||
for(osgViewer::Viewer::Windows::iterator itr = windows.begin();
|
||||
itr != windows.end();
|
||||
++itr)
|
||||
{
|
||||
(*itr)->useCursor(false);
|
||||
}
|
||||
}
|
||||
|
||||
// pass the model to the slide event handler so it knows which to manipulate.
|
||||
seh->set(loadedModel.get());
|
||||
|
||||
seh->home();
|
||||
|
||||
// osgDB::writeNodeFile(*loadedModel,"saved.osg");
|
||||
|
||||
osg::Timer_t startOfFrameTick = osg::Timer::instance()->tick();
|
||||
double targetFrameTime = 1.0/targetFrameRate;
|
||||
|
||||
if (exportName.empty())
|
||||
{
|
||||
// objects for managing the broadcasting and recieving of camera packets.
|
||||
CameraPacket cp;
|
||||
Broadcaster bc;
|
||||
Receiver rc;
|
||||
bc.setPort(static_cast<short int>(socketNumber));
|
||||
rc.setPort(static_cast<short int>(socketNumber));
|
||||
|
||||
bool masterKilled = false;
|
||||
DataConverter scratchPad(1024);
|
||||
|
||||
while( !viewer.done() && !masterKilled)
|
||||
{
|
||||
// wait for all cull and draw threads to complete.
|
||||
viewer.advance();
|
||||
|
||||
osg::Timer_t currentTick = osg::Timer::instance()->tick();
|
||||
double deltaTime = osg::Timer::instance()->delta_s(startOfFrameTick, currentTick);
|
||||
|
||||
|
||||
if (deltaTime<targetFrameTime)
|
||||
{
|
||||
OpenThreads::Thread::microSleep(static_cast<unsigned int>((targetFrameTime-deltaTime)*1000000.0));
|
||||
}
|
||||
|
||||
startOfFrameTick = osg::Timer::instance()->tick();
|
||||
|
||||
#if 0
|
||||
if (kmcb)
|
||||
{
|
||||
double time = kmcb->getTime();
|
||||
viewer.getFrameStamp()->setReferenceTime(time);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef USE_SDL
|
||||
sdlIntegration.update(viewer);
|
||||
#endif
|
||||
|
||||
if (P3DApplicationType==MASTER)
|
||||
{
|
||||
// take camera zero as the guide.
|
||||
osg::Matrix modelview(viewer.getCamera()->getViewMatrix());
|
||||
|
||||
cp.setPacket(modelview,viewer.getFrameStamp());
|
||||
|
||||
// cp.readEventQueue(viewer);
|
||||
|
||||
scratchPad.reset();
|
||||
scratchPad.write(cp);
|
||||
|
||||
scratchPad.reset();
|
||||
scratchPad.read(cp);
|
||||
|
||||
bc.setBuffer(scratchPad._startPtr, scratchPad._numBytes);
|
||||
|
||||
std::cout << "bc.sync()"<<scratchPad._numBytes<<std::endl;
|
||||
|
||||
bc.sync();
|
||||
}
|
||||
else if (P3DApplicationType==SLAVE)
|
||||
{
|
||||
rc.setBuffer(scratchPad._startPtr, scratchPad._numBytes);
|
||||
|
||||
rc.sync();
|
||||
|
||||
scratchPad.reset();
|
||||
scratchPad.read(cp);
|
||||
|
||||
// cp.writeEventQueue(viewer);
|
||||
|
||||
if (cp.getMasterKilled())
|
||||
{
|
||||
std::cout << "Received master killed."<<std::endl;
|
||||
// break out of while (!done) loop since we've now want to shut down.
|
||||
masterKilled = true;
|
||||
}
|
||||
}
|
||||
|
||||
// update the scene by traversing it with the the update visitor which will
|
||||
// call all node update callbacks and animations.
|
||||
viewer.eventTraversal();
|
||||
|
||||
// update the scene by traversing it with the the update visitor which will
|
||||
// call all node update callbacks and animations.
|
||||
viewer.updateTraversal();
|
||||
|
||||
if (P3DApplicationType==SLAVE)
|
||||
{
|
||||
osg::Matrix modelview;
|
||||
cp.getModelView(modelview,camera_offset);
|
||||
|
||||
viewer.getCamera()->setViewMatrix(modelview);
|
||||
}
|
||||
|
||||
// fire off the cull and draw traversals of the scene.
|
||||
if(!masterKilled)
|
||||
viewer.renderingTraversals();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ExportHTML::write(seh, viewer, exportName);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user