From Marco Jez, new Light Wave Scene loader
This commit is contained in:
@@ -35,6 +35,7 @@ PLUGIN_DIRS = \
|
||||
lib3ds\
|
||||
logo\
|
||||
lwo\
|
||||
lws\
|
||||
md2\
|
||||
obj\
|
||||
osgParticle\
|
||||
|
||||
@@ -1977,6 +1977,33 @@ Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
Begin Project Dependency
|
||||
Project_Dep_Name Core osg
|
||||
End Project Dependency
|
||||
Begin Project Dependency
|
||||
Project_Dep_Name Core osgDB
|
||||
End Project Dependency
|
||||
Begin Project Dependency
|
||||
Project_Dep_Name Core osgUtil
|
||||
End Project Dependency
|
||||
Begin Project Dependency
|
||||
Project_Dep_Name Core osgFX
|
||||
End Project Dependency
|
||||
Begin Project Dependency
|
||||
Project_Dep_Name Core osgGL2
|
||||
End Project Dependency
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "osgPlugin lws"=.\osgPlugins\lws\lws.dsp - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
Begin Project Dependency
|
||||
|
||||
121
VisualStudio/osgPlugins/lws/lws.dsp
Normal file
121
VisualStudio/osgPlugins/lws/lws.dsp
Normal file
@@ -0,0 +1,121 @@
|
||||
# Microsoft Developer Studio Project File - Name="osgPlugin lws" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
|
||||
|
||||
CFG=osgPlugin lws - Win32 Release
|
||||
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
|
||||
!MESSAGE use the Export Makefile command and run
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "lws.mak".
|
||||
!MESSAGE
|
||||
!MESSAGE You can specify a configuration when running NMAKE
|
||||
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "lws.mak" CFG="osgPlugin lws - Win32 Release"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "osgPlugin lws - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
|
||||
!MESSAGE "osgPlugin lws - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
|
||||
!MESSAGE
|
||||
|
||||
# Begin Project
|
||||
# PROP AllowPerConfigDependencies 0
|
||||
# PROP Scc_ProjName ""
|
||||
# PROP Scc_LocalPath ""
|
||||
CPP=cl.exe
|
||||
MTL=midl.exe
|
||||
RSC=rc.exe
|
||||
|
||||
!IF "$(CFG)" == "osgPlugin lws - Win32 Release"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 0
|
||||
# PROP BASE Output_Dir "Release"
|
||||
# PROP BASE Intermediate_Dir "Release"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 0
|
||||
# PROP Output_Dir "../../../lib"
|
||||
# PROP Intermediate_Dir "Release"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /YX /FD /c
|
||||
# ADD CPP /nologo /MD /W3 /GR /GX /O2 /I "../../../include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /YX /FD /c
|
||||
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x809 /d "NDEBUG"
|
||||
# ADD RSC /l 0x809 /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
|
||||
# ADD LINK32 glu32.lib /nologo /dll /pdb:none /machine:I386 /nodefaultlib:"LIBC" /out:"../../../bin/osgdb_lws.dll" /libpath:"../../../lib"
|
||||
# SUBTRACT LINK32 /nodefaultlib
|
||||
|
||||
!ELSEIF "$(CFG)" == "osgPlugin lws - Win32 Debug"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 1
|
||||
# PROP BASE Output_Dir "Debug"
|
||||
# PROP BASE Intermediate_Dir "Debug"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 1
|
||||
# PROP Output_Dir "../../../lib"
|
||||
# PROP Intermediate_Dir "Debug"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /MDd /W3 /Gm /vmg /vd0 /GR /GX /Zi /Od /I "../../../include" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "WIN32" /D "_DEBUG" /YX /FD /GZ /c
|
||||
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x809 /d "_DEBUG"
|
||||
# ADD RSC /l 0x809 /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
|
||||
# ADD LINK32 glu32.lib /nologo /dll /debug /machine:I386 /nodefaultlib:"LIBC" /out:"../../../bin/osgdb_lwsd.dll" /pdbtype:sept /libpath:"../../../lib"
|
||||
# SUBTRACT LINK32 /pdb:none
|
||||
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
|
||||
# Name "osgPlugin lws - Win32 Release"
|
||||
# Name "osgPlugin lws - Win32 Debug"
|
||||
# Begin Group "Source Files"
|
||||
|
||||
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\src\osgPlugins\lws\SceneLoader.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\src\osgPlugins\lws\ReaderWriterLWS.cpp
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Header Files"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Src\osgPlugins\lws\SceneLoader.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# End Target
|
||||
# Begin Group "Header Files No. 1"
|
||||
|
||||
# PROP Default_Filter "h;hpp;hxx;hm;inl"
|
||||
# End Group
|
||||
# Begin Group "Resource Files"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# End Group
|
||||
# End Project
|
||||
@@ -19,7 +19,7 @@ CXXFILES =\
|
||||
|
||||
INC += -I$(THISDIR)
|
||||
|
||||
LIBS += $(OSG_LIBS) $(OTHER_LIBS) $(GL_LIBS)
|
||||
LIBS += -losgFX -losgGL2 $(OSG_LIBS) $(OTHER_LIBS) $(GL_LIBS)
|
||||
|
||||
TARGET_BASENAME = lwo
|
||||
include $(TOPDIR)/Make/cygwin_plugin_def
|
||||
|
||||
17
src/osgPlugins/lws/GNUmakefile
Normal file
17
src/osgPlugins/lws/GNUmakefile
Normal file
@@ -0,0 +1,17 @@
|
||||
TOPDIR = ../../..
|
||||
include $(TOPDIR)/Make/makedefs
|
||||
|
||||
CXXFILES =\
|
||||
SceneLoader.cpp\
|
||||
ReaderWriterLWS.cpp\
|
||||
|
||||
|
||||
INC += -I$(THISDIR)
|
||||
|
||||
LIBS += $(OSG_LIBS) $(OTHER_LIBS)
|
||||
|
||||
TARGET_BASENAME = lws
|
||||
include $(TOPDIR)/Make/cygwin_plugin_def
|
||||
PLUGIN = $(PLUGIN_PREFIX)$(TARGET_BASENAME).$(PLUGIN_EXT)
|
||||
|
||||
include $(TOPDIR)/Make/makerules
|
||||
78
src/osgPlugins/lws/ReaderWriterLWS.cpp
Normal file
78
src/osgPlugins/lws/ReaderWriterLWS.cpp
Normal file
@@ -0,0 +1,78 @@
|
||||
/*******************************************************
|
||||
Lightwave Scene Loader for OSG
|
||||
|
||||
Copyright (C) 2004 Marco Jez <marco.jez@poste.it>
|
||||
OpenSceneGraph is (C) 2004 Robert Osfield
|
||||
********************************************************/
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning( disable : 4786 )
|
||||
#endif
|
||||
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
|
||||
#include <osgDB/Registry>
|
||||
#include <osgDB/ReadFile>
|
||||
#include <osgDB/FileNameUtils>
|
||||
#include <osgDB/FileUtils>
|
||||
|
||||
#include "SceneLoader.h"
|
||||
|
||||
|
||||
class ReaderWriterLWS : public osgDB::ReaderWriter
|
||||
{
|
||||
public:
|
||||
ReaderWriterLWS() {}
|
||||
|
||||
virtual const char* className() { return "ReaderWriterLWS"; }
|
||||
|
||||
virtual bool acceptsExtension(const std::string &extension) {
|
||||
return osgDB::equalCaseInsensitive(extension, "lws");
|
||||
}
|
||||
|
||||
virtual ReadResult readNode(const std::string &file, const osgDB::ReaderWriter::Options *options)
|
||||
{
|
||||
std::string ext = osgDB::getLowerCaseFileExtension(file);
|
||||
if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED;
|
||||
|
||||
std::string fileName = osgDB::findDataFile(file);
|
||||
if (fileName.empty()) return ReadResult::FILE_NOT_FOUND;
|
||||
|
||||
lwosg::SceneLoader::Options conv_options = parse_options(options);
|
||||
|
||||
lwosg::SceneLoader scene_loader(conv_options);
|
||||
osg::ref_ptr<osg::Node> node = scene_loader.load(fileName);
|
||||
if (node.valid()) {
|
||||
return node.take();
|
||||
}
|
||||
|
||||
return ReadResult::FILE_NOT_HANDLED;
|
||||
}
|
||||
|
||||
lwosg::SceneLoader::Options parse_options(const Options *options) const;
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
lwosg::SceneLoader::Options ReaderWriterLWS::parse_options(const Options *options) const
|
||||
{
|
||||
lwosg::SceneLoader::Options conv_options;
|
||||
|
||||
if (options) {
|
||||
std::istringstream iss(options->getOptionString());
|
||||
std::string opt;
|
||||
while (iss >> opt) {
|
||||
// no options yet!
|
||||
}
|
||||
}
|
||||
|
||||
return conv_options;
|
||||
}
|
||||
|
||||
|
||||
// register with Registry to instantiate the above reader/writer.
|
||||
osgDB::RegisterReaderWriterProxy<ReaderWriterLWS> g_lwsReaderWriterProxy;
|
||||
361
src/osgPlugins/lws/SceneLoader.cpp
Normal file
361
src/osgPlugins/lws/SceneLoader.cpp
Normal file
@@ -0,0 +1,361 @@
|
||||
/*******************************************************
|
||||
Lightwave Scene Loader for OSG
|
||||
|
||||
Copyright (C) 2004 Marco Jez <marco.jez@poste.it>
|
||||
OpenSceneGraph is (C) 2004 Robert Osfield
|
||||
********************************************************/
|
||||
|
||||
#include "SceneLoader.h"
|
||||
|
||||
#include <osg/Notify>
|
||||
#include <osg/PositionAttitudeTransform>
|
||||
#include <osg/AnimationPath>
|
||||
|
||||
#include <osgDB/FileUtils>
|
||||
#include <osgDB/FileNameUtils>
|
||||
#include <osgDB/ReadFile>
|
||||
#include <osgDB/WriteFile>
|
||||
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
|
||||
using namespace lwosg;
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
int str_to_int(const std::string &s)
|
||||
{
|
||||
std::istringstream iss(s);
|
||||
int n;
|
||||
iss >> n;
|
||||
return n;
|
||||
}
|
||||
|
||||
int hex_to_int(const std::string &s)
|
||||
{
|
||||
std::istringstream iss(s);
|
||||
int n;
|
||||
iss >> std::hex >> n;
|
||||
return n;
|
||||
}
|
||||
|
||||
osg::Quat rotate_ypr(const osg::Vec3 &ypr, const osg::Vec3 pivot_rot = osg::Vec3(0, 0, 0))
|
||||
{
|
||||
osg::Quat Q1(ypr.z(), osg::Vec3(0, -1, 0));
|
||||
osg::Quat Q2(ypr.y(), osg::Vec3(-1, 0, 0));
|
||||
osg::Quat Q3(ypr.x(), osg::Vec3(0, 0, -1));
|
||||
osg::Quat Q4(pivot_rot.z(), osg::Vec3(0, -1, 0));
|
||||
osg::Quat Q5(pivot_rot.y(), osg::Vec3(-1, 0, 0));
|
||||
osg::Quat Q6(pivot_rot.x(), osg::Vec3(0, 0, -1));
|
||||
return Q1 * Q2 * Q3 * Q4 * Q5 * Q6;
|
||||
}
|
||||
|
||||
void trim(std::string& str)
|
||||
{
|
||||
// trim any trailing control characters.
|
||||
//std::cout<<"trim string "<<str<<std::endl;
|
||||
while (!str.empty() && str[str.size()-1]<32)
|
||||
{
|
||||
// removing control character
|
||||
//std::cout<<" removing control character "<<(int)str[str.size()-1]<<std::endl;
|
||||
str.erase(str.size()-1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
SceneLoader::SceneLoader()
|
||||
: capture_obj_motion_(false),
|
||||
capture_cam_motion_(false)
|
||||
{
|
||||
}
|
||||
|
||||
SceneLoader::SceneLoader(const Options &options)
|
||||
: capture_obj_motion_(false),
|
||||
capture_cam_motion_(false),
|
||||
options_(options)
|
||||
{
|
||||
}
|
||||
|
||||
osg::Group *SceneLoader::load(const std::string &filename, bool search)
|
||||
{
|
||||
std::string fname;
|
||||
|
||||
if (search) {
|
||||
fname = osgDB::findDataFile(filename);
|
||||
if (fname.empty()) return 0;
|
||||
} else {
|
||||
fname = filename;
|
||||
}
|
||||
|
||||
std::ifstream ifs(fname.c_str());
|
||||
if (!ifs.is_open()) return 0;
|
||||
|
||||
clear();
|
||||
|
||||
std::string identifier;
|
||||
while (ifs >> identifier) {
|
||||
if (identifier == "{") {
|
||||
ifs >> identifier;
|
||||
std::ws(ifs);
|
||||
std::vector<std::string> data;
|
||||
std::string data_line;
|
||||
while (std::getline(ifs, data_line)) {
|
||||
trim(data_line);
|
||||
if (data_line == "}") {
|
||||
std::ws(ifs);
|
||||
break;
|
||||
}
|
||||
data.push_back(data_line);
|
||||
std::ws(ifs);
|
||||
}
|
||||
if (!data.empty()) {
|
||||
if (!parse_block(identifier, data)) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
std::string data;
|
||||
std::getline(ifs, data);
|
||||
trim(data);
|
||||
std::istringstream iss(data);
|
||||
std::ws(iss);
|
||||
std::getline(iss, data);
|
||||
trim(data);
|
||||
if (!parse_block(identifier, data)) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// build camera animations
|
||||
for (Scene_camera_list::iterator ci=scene_cameras_.begin(); ci!=scene_cameras_.end(); ++ci) {
|
||||
if (!ci->motion.keys.empty()) {
|
||||
osg::ref_ptr<osg::AnimationPath> ap = new osg::AnimationPath;
|
||||
for (Motion_envelope::Key_map::const_iterator j=ci->motion.keys.begin(); j!=ci->motion.keys.end(); ++j) {
|
||||
osg::Vec3 pos(options_.csf->fix_point(j->second.position));
|
||||
//const osg::Vec3 &ypr = j->second.ypr;
|
||||
osg::AnimationPath::ControlPoint cp(pos, osg::Quat(osg::PI_2, osg::Vec3(1, 0, 0)) * rotate_ypr(j->second.ypr), j->second.scale);
|
||||
ap->insert(j->first, cp);
|
||||
}
|
||||
camera_animations_.push_back(ap.get());
|
||||
}
|
||||
}
|
||||
|
||||
// build objects and object animations
|
||||
typedef std::map<int, osg::ref_ptr<osg::PositionAttitudeTransform> > PAT_map;
|
||||
PAT_map pats;
|
||||
int j = 0;
|
||||
for (Scene_object_list::iterator i=scene_objects_.begin(); i!=scene_objects_.end(); ++i, ++j) {
|
||||
osg::ref_ptr<osg::PositionAttitudeTransform> pat = pats[j];
|
||||
if (!pat.valid()) {
|
||||
pat = new osg::PositionAttitudeTransform;
|
||||
pats[j] = pat;
|
||||
}
|
||||
|
||||
pat->addChild(i->layer_node.get());
|
||||
pat->setPivotPoint(options_.csf->fix_point(i->pivot));
|
||||
|
||||
// still
|
||||
if (!i->motion.keys.empty()) {
|
||||
pat->setPosition(options_.csf->fix_point(i->motion.keys.begin()->second.position));
|
||||
pat->setAttitude(rotate_ypr(i->motion.keys.begin()->second.ypr, i->pivot_rot));
|
||||
}
|
||||
|
||||
// animation
|
||||
if (i->motion.keys.size() > 1) {
|
||||
osg::ref_ptr<osg::AnimationPath> ap = new osg::AnimationPath;
|
||||
for (Motion_envelope::Key_map::const_iterator j=i->motion.keys.begin(); j!=i->motion.keys.end(); ++j) {
|
||||
osg::Vec3 pos(options_.csf->fix_point(j->second.position));
|
||||
osg::AnimationPath::ControlPoint cp(pos, rotate_ypr(j->second.ypr, i->pivot_rot), j->second.scale);
|
||||
ap->insert(j->first, cp);
|
||||
}
|
||||
osg::ref_ptr<osg::AnimationPathCallback> apc = new osg::AnimationPathCallback(ap.get());
|
||||
pat->setUpdateCallback(apc.get());
|
||||
}
|
||||
|
||||
if (i->parent == -1) {
|
||||
root_->addChild(pat.get());
|
||||
} else {
|
||||
if (i->parent < static_cast<int>(scene_objects_.size())) {
|
||||
osg::ref_ptr<osg::PositionAttitudeTransform> parent = pats[i->parent];
|
||||
if (!parent.valid()) {
|
||||
parent = new osg::PositionAttitudeTransform;
|
||||
pats[i->parent] = parent;
|
||||
}
|
||||
parent->addChild(pat.get());
|
||||
} else {
|
||||
osg::notify(osg::WARN) << "Warning: lwosg::SceneLoader: invalid parent" << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return root_.get();
|
||||
}
|
||||
|
||||
bool SceneLoader::parse_block(const std::string &name, const std::string &data)
|
||||
{
|
||||
std::istringstream iss(data);
|
||||
|
||||
if (name == "AddCamera") {
|
||||
scene_cameras_.push_back(Scene_camera());
|
||||
}
|
||||
|
||||
if (name == "AddNullObject") {
|
||||
osg::ref_ptr<osg::Group> nullobjnode = new osg::Group;
|
||||
nullobjnode->setName(data);
|
||||
objects_[data] = nullobjnode;
|
||||
Scene_object so;
|
||||
so.layer_node = nullobjnode.get();
|
||||
scene_objects_.push_back(so);
|
||||
}
|
||||
|
||||
if (name == "LoadObjectLayer") {
|
||||
unsigned layer;
|
||||
iss >> layer;
|
||||
std::ws(iss);
|
||||
std::string filename;
|
||||
std::getline(iss, filename);
|
||||
|
||||
// trim any trailing control characters.
|
||||
trim(filename);
|
||||
|
||||
if (!filename.empty())
|
||||
{
|
||||
|
||||
|
||||
osg::ref_ptr<osg::Group> objnode;
|
||||
|
||||
Object_map::const_iterator i = objects_.find(filename);
|
||||
|
||||
if (i == objects_.end()) {
|
||||
|
||||
osg::notify(osg::NOTICE) << "Loading object \"" << filename << "\"" << std::endl;
|
||||
|
||||
objnode = dynamic_cast<osg::Group *>(osgDB::readNodeFile(filename));
|
||||
if (!objnode.valid()) return false;
|
||||
|
||||
objects_[filename] = objnode;
|
||||
|
||||
} else {
|
||||
objnode = i->second;
|
||||
}
|
||||
|
||||
if (layer > objnode->getNumChildren()) {
|
||||
osg::notify(osg::WARN) << "Warning: lwosg::SceneLoader: layer " << layer << " does not exist in object " << filename << std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
Scene_object so;
|
||||
so.layer_node = objnode->getChild(layer-1);
|
||||
if (so.layer_node.valid()) {
|
||||
scene_objects_.push_back(so);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (name == "PivotPosition") {
|
||||
if (!scene_objects_.empty()) {
|
||||
osg::Vec3 pivot;
|
||||
iss >> pivot.x() >> pivot.y() >> pivot.z();
|
||||
scene_objects_.back().pivot = pivot;
|
||||
}
|
||||
}
|
||||
|
||||
if (name == "PivotRotation") {
|
||||
if (!scene_objects_.empty()) {
|
||||
osg::Vec3 pivot;
|
||||
iss >> pivot.x() >> pivot.y() >> pivot.z();
|
||||
scene_objects_.back().pivot_rot = pivot * (osg::PI / 180.0f);
|
||||
}
|
||||
}
|
||||
|
||||
if (name == "ParentItem") {
|
||||
if (!scene_objects_.empty()) {
|
||||
std::string id;
|
||||
iss >> id;
|
||||
if (id.length() == 8) {
|
||||
if (id[0] == '1') {
|
||||
id.erase(0, 1);
|
||||
scene_objects_.back().parent = hex_to_int(id);
|
||||
}
|
||||
} else {
|
||||
scene_objects_.back().parent = str_to_int(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (name == "NumChannels") {
|
||||
iss >> channel_count_;
|
||||
}
|
||||
|
||||
if (name == "Channel") {
|
||||
iss >> current_channel_;
|
||||
}
|
||||
|
||||
if (name == "ObjectMotion") {
|
||||
capture_obj_motion_ = true;
|
||||
}
|
||||
|
||||
if (name == "CameraMotion") {
|
||||
capture_cam_motion_ = true;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SceneLoader::parse_block(const std::string &name, const std::vector<std::string> &data)
|
||||
{
|
||||
if (name == "Envelope") {
|
||||
if (((capture_obj_motion_ && !scene_objects_.empty()) ||
|
||||
(capture_cam_motion_ && !scene_cameras_.empty())) &&
|
||||
(data.size() >= 2)) {
|
||||
|
||||
Motion_envelope::Key_map &keys = capture_obj_motion_ ? scene_objects_.back().motion.keys : scene_cameras_.back().motion.keys;
|
||||
|
||||
if (current_channel_ >= (channel_count_ - 1)) {
|
||||
capture_obj_motion_ = false;
|
||||
capture_cam_motion_ = false;
|
||||
}
|
||||
|
||||
for (unsigned i=1; i<data.size(); ++i) {
|
||||
std::istringstream iss(data[i]);
|
||||
std::string key_id;
|
||||
iss >> key_id;
|
||||
if (key_id == "Key") {
|
||||
float value;
|
||||
double time;
|
||||
if (iss >> value >> time) {
|
||||
switch (current_channel_) {
|
||||
case 0: keys[time].position.x() = value; break;
|
||||
case 1: keys[time].position.y() = value; break;
|
||||
case 2: keys[time].position.z() = value; break;
|
||||
case 3: keys[time].ypr.x() = value; break;
|
||||
case 4: keys[time].ypr.y() = value; break;
|
||||
case 5: keys[time].ypr.z() = value; break;
|
||||
case 6: keys[time].scale.x() = value; break;
|
||||
case 7: keys[time].scale.y() = value; break;
|
||||
case 8: keys[time].scale.z() = value; break;
|
||||
default: ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void SceneLoader::clear()
|
||||
{
|
||||
root_ = new osg::Group;
|
||||
objects_.clear();
|
||||
scene_objects_.clear();
|
||||
scene_cameras_.clear();
|
||||
camera_animations_.clear();
|
||||
channel_count_ = 0;
|
||||
current_channel_ = 0;
|
||||
}
|
||||
150
src/osgPlugins/lws/SceneLoader.h
Normal file
150
src/osgPlugins/lws/SceneLoader.h
Normal file
@@ -0,0 +1,150 @@
|
||||
/*******************************************************
|
||||
Lightwave Scene Loader for OSG
|
||||
|
||||
Copyright (C) 2004 Marco Jez <marco.jez@poste.it>
|
||||
OpenSceneGraph is (C) 2004 Robert Osfield
|
||||
********************************************************/
|
||||
|
||||
#ifndef LWOSG_SCENELOADER_
|
||||
#define LWOSG_SCENELOADER_
|
||||
|
||||
#include <osg/Group>
|
||||
#include <osg/Vec3>
|
||||
#include <osg/AnimationPath>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
namespace lwosg
|
||||
{
|
||||
|
||||
class CoordinateSystemFixer: public osg::Referenced {
|
||||
public:
|
||||
virtual osg::Vec3 fix_point(const osg::Vec3 &P) const = 0;
|
||||
virtual osg::Vec4 fix_point(const osg::Vec4 &P) const = 0;
|
||||
virtual osg::Vec3 fix_vector(const osg::Vec3 &V) const = 0;
|
||||
virtual osg::Vec4 fix_vector(const osg::Vec4 &V) const = 0;
|
||||
virtual inline bool invert_winding() const { return false; }
|
||||
|
||||
protected:
|
||||
virtual ~CoordinateSystemFixer() {}
|
||||
CoordinateSystemFixer &operator=(const CoordinateSystemFixer &) { return *this; }
|
||||
};
|
||||
|
||||
class LwoCoordFixer: public CoordinateSystemFixer {
|
||||
public:
|
||||
inline osg::Vec3 fix_point(const osg::Vec3 &P) const;
|
||||
inline osg::Vec4 fix_point(const osg::Vec4 &P) const;
|
||||
inline osg::Vec3 fix_vector(const osg::Vec3 &V) const;
|
||||
inline osg::Vec4 fix_vector(const osg::Vec4 &V) const;
|
||||
inline bool invert_winding() const { return true; }
|
||||
|
||||
protected:
|
||||
virtual ~LwoCoordFixer() {}
|
||||
LwoCoordFixer &operator=(const LwoCoordFixer &) { return *this; }
|
||||
};
|
||||
|
||||
|
||||
class SceneLoader {
|
||||
public:
|
||||
struct Options {
|
||||
osg::ref_ptr<CoordinateSystemFixer> csf;
|
||||
Options(): csf(new LwoCoordFixer) {}
|
||||
};
|
||||
|
||||
typedef std::vector<osg::ref_ptr<osg::AnimationPath> > Animation_list;
|
||||
|
||||
SceneLoader();
|
||||
SceneLoader(const Options &options);
|
||||
|
||||
osg::Group *load(const std::string &filename, bool search = false);
|
||||
|
||||
inline osg::Group *get_root() { return root_.get(); }
|
||||
inline const osg::Group *get_root() const { return root_.get(); }
|
||||
|
||||
inline const Options &get_options() const { return options_; }
|
||||
inline Options &get_options() { return options_; }
|
||||
inline void set_options(const Options &options) { options_ = options; }
|
||||
|
||||
inline const Animation_list &get_camera_animations() const { return camera_animations_; }
|
||||
inline Animation_list &get_camera_animations() { return camera_animations_; }
|
||||
|
||||
protected:
|
||||
bool parse_block(const std::string &name, const std::string &data);
|
||||
bool parse_block(const std::string &name, const std::vector<std::string> &data);
|
||||
void clear();
|
||||
|
||||
private:
|
||||
typedef std::map<std::string, osg::ref_ptr<osg::Group> > Object_map;
|
||||
Object_map objects_;
|
||||
|
||||
Animation_list camera_animations_;
|
||||
|
||||
struct Motion_envelope {
|
||||
struct Key {
|
||||
osg::Vec3 position;
|
||||
osg::Vec3 ypr;
|
||||
osg::Vec3 scale;
|
||||
Key(): scale(1, 1, 1) {}
|
||||
};
|
||||
typedef std::map<double, Key> Key_map;
|
||||
Key_map keys;
|
||||
};
|
||||
|
||||
struct Scene_object {
|
||||
osg::ref_ptr<osg::Node> layer_node;
|
||||
int parent;
|
||||
osg::Vec3 pivot;
|
||||
osg::Vec3 pivot_rot;
|
||||
Motion_envelope motion;
|
||||
|
||||
Scene_object(): parent(-1) {}
|
||||
};
|
||||
|
||||
struct Scene_camera {
|
||||
Motion_envelope motion;
|
||||
};
|
||||
|
||||
typedef std::vector<Scene_object> Scene_object_list;
|
||||
Scene_object_list scene_objects_;
|
||||
|
||||
typedef std::vector<Scene_camera> Scene_camera_list;
|
||||
Scene_camera_list scene_cameras_;
|
||||
|
||||
osg::ref_ptr<osg::Group> root_;
|
||||
|
||||
int current_channel_;
|
||||
int channel_count_;
|
||||
|
||||
bool capture_obj_motion_;
|
||||
bool capture_cam_motion_;
|
||||
|
||||
Options options_;
|
||||
};
|
||||
|
||||
// INLINE METHODS
|
||||
|
||||
inline osg::Vec3 LwoCoordFixer::fix_point(const osg::Vec3 &P) const
|
||||
{
|
||||
return osg::Vec3(P.x(), P.z(), P.y());
|
||||
}
|
||||
|
||||
inline osg::Vec4 LwoCoordFixer::fix_point(const osg::Vec4 &P) const
|
||||
{
|
||||
return osg::Vec4(fix_point(osg::Vec3(P.x(), P.y(), P.z())), P.w());
|
||||
}
|
||||
|
||||
inline osg::Vec3 LwoCoordFixer::fix_vector(const osg::Vec3 &V) const
|
||||
{
|
||||
return fix_point(V);
|
||||
}
|
||||
|
||||
inline osg::Vec4 LwoCoordFixer::fix_vector(const osg::Vec4 &V) const
|
||||
{
|
||||
return fix_point(V);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user