From Geoff Michel, added AC3D .ac and GEO .geo loaders.
This commit is contained in:
@@ -26,8 +26,10 @@ PLUGIN_DIRS = \
|
||||
osgParticle\
|
||||
osgText\
|
||||
rgb\
|
||||
ac3d\
|
||||
lib3ds\
|
||||
flt\
|
||||
geo\
|
||||
iv\
|
||||
obj\
|
||||
lwo\
|
||||
|
||||
@@ -1044,7 +1044,28 @@ Package=<4>
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "osgPlugin flt"=.\osgPlugins\flt\flt.dsp - Package Owner=<4>
|
||||
Project: "osgPlugin geo"=.\osgPlugins\geo\geo.dsp - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
Begin Project Dependency
|
||||
Project_Dep_Name Core osg
|
||||
End Project Dependency
|
||||
Begin Project Dependency
|
||||
Project_Dep_Name Core osgDB
|
||||
End Project Dependency
|
||||
Begin Project Dependency
|
||||
Project_Dep_Name Core osgUtil
|
||||
End Project Dependency
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "osgPlugin ac3d"=.\osgPlugins\ac3d\ac3d.dsp - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
|
||||
109
VisualStudio/osgPlugins/ac3d/ac3d.dsp
Normal file
109
VisualStudio/osgPlugins/ac3d/ac3d.dsp
Normal file
@@ -0,0 +1,109 @@
|
||||
# Microsoft Developer Studio Project File - Name="osgPlugin ac3d" - 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 ac3d - 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 "ac3d.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 "ac3d.mak" CFG="osgPlugin ac3d - Win32 Release"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "osgPlugin ac3d - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
|
||||
!MESSAGE "osgPlugin ac3d - 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 ac3d - 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 /nologo /dll /pdb:none /machine:I386 /nodefaultlib:"LIBC" /out:"../../../bin/osgdb_ac.dll" /libpath:"../../../lib"
|
||||
# SUBTRACT LINK32 /nodefaultlib
|
||||
|
||||
!ELSEIF "$(CFG)" == "osgPlugin ac3d - 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 /nologo /dll /debug /machine:I386 /nodefaultlib:"LIBC" /out:"../../../bin/osgdb_ac.dll" /pdbtype:sept /libpath:"../../../lib"
|
||||
# SUBTRACT LINK32 /nodefaultlib
|
||||
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
|
||||
# Name "osgPlugin ac3d - Win32 Release"
|
||||
# Name "osgPlugin ac3d - 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\ac3d\ac3d.cpp
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Header Files"
|
||||
|
||||
# PROP Default_Filter "h;hpp;hxx;hm;inl"
|
||||
# End Group
|
||||
# Begin Group "Resource Files"
|
||||
|
||||
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
|
||||
# End Group
|
||||
# End Target
|
||||
# End Project
|
||||
125
VisualStudio/osgPlugins/geo/geo.dsp
Normal file
125
VisualStudio/osgPlugins/geo/geo.dsp
Normal file
@@ -0,0 +1,125 @@
|
||||
# Microsoft Developer Studio Project File - Name="osgPlugin geo" - 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 geo - 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 "geo.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 "geo.mak" CFG="osgPlugin geo - Win32 Release"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "osgPlugin geo - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
|
||||
!MESSAGE "osgPlugin geo - 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 geo - 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 /nologo /dll /pdb:none /machine:I386 /nodefaultlib:"LIBC" /out:"../../../bin/osgdb_geo.dll" /libpath:"../../../lib"
|
||||
# SUBTRACT LINK32 /nodefaultlib
|
||||
|
||||
!ELSEIF "$(CFG)" == "osgPlugin geo - 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 /nologo /dll /debug /machine:I386 /nodefaultlib:"LIBC" /out:"../../../bin/osgdb_geod.dll" /pdbtype:sept /libpath:"../../../lib"
|
||||
# SUBTRACT LINK32 /nodefaultlib
|
||||
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
|
||||
# Name "osgPlugin geo - Win32 Release"
|
||||
# Name "osgPlugin geo - 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\geo\ReaderWriterGEO.cpp
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Header Files"
|
||||
|
||||
# PROP Default_Filter "h;hpp;hxx;hm;inl"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\src\osgPlugins\geo\geoFormat.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\src\osgPlugins\geo\geoTypes.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\src\osgPlugins\geo\geoUnits.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\src\osgPlugins\geo\osgGeoStructs.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Resource Files"
|
||||
|
||||
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
|
||||
# End Group
|
||||
# End Target
|
||||
# End Project
|
||||
13
src/osgPlugins/ac3d/Makefile
Normal file
13
src/osgPlugins/ac3d/Makefile
Normal file
@@ -0,0 +1,13 @@
|
||||
TOPDIR = ../../..
|
||||
include $(TOPDIR)/Make/makedefs
|
||||
|
||||
CXXFILES =\
|
||||
ac3d.cpp\
|
||||
|
||||
LIBS += $(OSG_LIBS) $(OTHER_LIBS)
|
||||
|
||||
TARGET_BASENAME = ac
|
||||
include $(TOPDIR)/Make/cygwin_plugin_def
|
||||
PLUGIN = $(PLUGIN_PREFIX)$(TARGET_BASENAME).$(PLUGIN_EXT)
|
||||
|
||||
include $(TOPDIR)/Make/makerules
|
||||
775
src/osgPlugins/ac3d/ac3d.cpp
Normal file
775
src/osgPlugins/ac3d/ac3d.cpp
Normal file
@@ -0,0 +1,775 @@
|
||||
// 30 Oct 2002
|
||||
// AC3D loader for models generated by the AC3D modeller (www.ac3d.org)
|
||||
// part of this source code were supplied by the AC3D project (Andy Colebourne)
|
||||
// eg the basic parsing of an AC3D file.
|
||||
// Conversion from AC3D scenegraph to OSG by GW Michel.
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <malloc.h>
|
||||
#include <math.h>
|
||||
|
||||
#include <osg/CullFace>
|
||||
#include <osg/Geode>
|
||||
#include <osg/Group>
|
||||
#include <osg/Geometry> //Set>
|
||||
#include <osg/Light>
|
||||
#include <osg/LightSource>
|
||||
#include <osg/Material>
|
||||
#include <osg/Texture2D>
|
||||
#include <osg/TexEnv>
|
||||
#include <osg/StateSet>
|
||||
#include <osg/Notify>
|
||||
#include <osg/Texture2D>
|
||||
|
||||
|
||||
#include <osgDB/FileNameUtils>
|
||||
#include <osgDB/Registry>
|
||||
#include <osgDB/ReadFile>
|
||||
#include <osgDB/FileUtils>
|
||||
|
||||
#include <osgUtil/Tesselator>
|
||||
#include <osgUtil/SmoothingVisitor>
|
||||
|
||||
#include "osgac3d.h"
|
||||
|
||||
class ReaderWriterAC : public osgDB::ReaderWriter
|
||||
{
|
||||
public:
|
||||
virtual const char* className() { return "AC3D Database Reader"; }
|
||||
|
||||
virtual bool acceptsExtension(const std::string& extension)
|
||||
{
|
||||
return osgDB::equalCaseInsensitive(extension,"ac");
|
||||
}
|
||||
virtual ReadResult readNode(const std::string& fileName,const osgDB::ReaderWriter::Options*)
|
||||
{
|
||||
osg::Group *grp; // holder for all loaded objects
|
||||
grp=ac_load_ac3d(fileName.c_str());
|
||||
return grp;
|
||||
};
|
||||
private:
|
||||
};
|
||||
|
||||
static int line = 0;
|
||||
static char buff[255];
|
||||
|
||||
|
||||
|
||||
static osg::Material *palette[255];
|
||||
static int num_palette = 0;
|
||||
static int startmatindex = 0;
|
||||
|
||||
|
||||
osg::Material*ac_palette_get_material(int id)
|
||||
{
|
||||
return(palette[id]);
|
||||
}
|
||||
|
||||
|
||||
Boolean read_line(FILE *f)
|
||||
{
|
||||
fgets(buff, 255, f); line++;
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
|
||||
|
||||
int tokc = 0;
|
||||
char *tokv[30];
|
||||
|
||||
Prototype int get_tokens(char *s, int *argc, char *argv[])
|
||||
/** bung '\0' chars at the end of tokens and set up the array (tokv) and count (tokc)
|
||||
like argv argc **/
|
||||
{
|
||||
char *p = s;
|
||||
char *st;
|
||||
char c;
|
||||
//int n;
|
||||
int tc;
|
||||
|
||||
tc = 0;
|
||||
while ((c = *p))
|
||||
{
|
||||
if ((c != ' ') && (c != '\t') && (c != '\n') && ( c != 13))
|
||||
{
|
||||
if (c == '"')
|
||||
{
|
||||
c = *p++;
|
||||
st = p;
|
||||
while ((c = *p) && ((c != '"')&&(c != '\n')&& ( c != 13)) )
|
||||
{
|
||||
if (c == '\\')
|
||||
strcpy(p, p+1);
|
||||
p++;
|
||||
}
|
||||
*p=0;
|
||||
argv[tc++] = st;
|
||||
}
|
||||
else
|
||||
{
|
||||
st = p;
|
||||
while ((c = *p) && ((c != ' ') && (c != '\t') && (c != '\n') && ( c != 13)) )
|
||||
p++;
|
||||
*p=0;
|
||||
argv[tc++] = st;
|
||||
}
|
||||
}
|
||||
p++;
|
||||
}
|
||||
|
||||
*argc = tc;
|
||||
return(tc);
|
||||
}
|
||||
|
||||
|
||||
void initobject(ACObject *ob)
|
||||
{
|
||||
ob->loc[0] = ob->loc[1] = ob->loc[2] = 0.0;
|
||||
ob->name = ob->url = NULL;
|
||||
ob->data = NULL;
|
||||
ob->num_vert = 0;
|
||||
ob->num_surf = 0;
|
||||
ob->texture = NULL;
|
||||
ob->texture_repeat_x = ob->texture_repeat_y = 1.0;
|
||||
ob->texture_offset_x = ob->texture_offset_y = 0.0;
|
||||
ob->kids = NULL;
|
||||
ob->num_kids = 0;
|
||||
ob->matrix[0] = 1;
|
||||
ob->matrix[1] = 0;
|
||||
ob->matrix[2] = 0;
|
||||
ob->matrix[3] = 0;
|
||||
ob->matrix[4] = 1;
|
||||
ob->matrix[5] = 0;
|
||||
ob->matrix[6] = 0;
|
||||
ob->matrix[7] = 0;
|
||||
ob->matrix[8] = 1;
|
||||
}
|
||||
|
||||
|
||||
void init_surface(ACSurface *s)
|
||||
{
|
||||
s->num_vertref = 0;
|
||||
s->flags = 0;
|
||||
s->mat = 0;
|
||||
// s->normal.x = 0.0; s->normal.z = 0.0; s->normal.z = 0.0;
|
||||
}
|
||||
|
||||
|
||||
void osgtri_calc_normal(osg::Vec3 &v1, osg::Vec3 &v2, osg::Vec3 &v3, osg::Vec3 &n)
|
||||
{
|
||||
osg::Vec3 side1=v2-v1;
|
||||
osg::Vec3 side2=v3-v2;
|
||||
n=side1^side2;
|
||||
n.normalize();
|
||||
|
||||
}
|
||||
|
||||
ACSurface *read_surface(FILE *f, ACSurface *s,osg::UShortArray *nusidx,
|
||||
osg::Vec2Array *tcs)
|
||||
{
|
||||
char t[20];
|
||||
init_surface(s);
|
||||
|
||||
while (!feof(f))
|
||||
{
|
||||
read_line(f);
|
||||
sscanf(buff, "%s", t);
|
||||
|
||||
if (streq(t, "SURF"))
|
||||
{
|
||||
int flgs;
|
||||
|
||||
if (get_tokens(buff, &tokc, tokv) != 2)
|
||||
{
|
||||
printf("SURF should be followed by one flags argument\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
flgs = strtol(tokv[1], NULL, 0);
|
||||
s->flags = flgs;
|
||||
}
|
||||
}
|
||||
else
|
||||
if (streq(t, "mat"))
|
||||
{
|
||||
int mindx;
|
||||
|
||||
sscanf(buff, "%s %d", t, &mindx);
|
||||
s->mat = mindx+startmatindex;
|
||||
}
|
||||
else
|
||||
if (streq(t, "refs"))
|
||||
{
|
||||
int num, n;
|
||||
int ind;
|
||||
osg::Vec2 tx;
|
||||
|
||||
sscanf(buff, "%s %d", t, &num);
|
||||
|
||||
s->num_vertref = num;
|
||||
|
||||
for (n = 0; n < num; n++)
|
||||
{
|
||||
fscanf(f, "%d %f %f\n", &ind, &tx[0], &tx[1]); line++;
|
||||
nusidx->push_back(ind);
|
||||
if (tcs) tcs->push_back(tx);
|
||||
}
|
||||
|
||||
return(s);
|
||||
}
|
||||
else
|
||||
printf("ignoring %s\n", t);
|
||||
|
||||
}
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*void ac_object_calc_vertex_normals(ACObject *ob)
|
||||
{
|
||||
int s, v, vr;
|
||||
|
||||
/ ** for each vertex in this object ** /
|
||||
for (v = 0; v < ob->num_vert; v++)
|
||||
{
|
||||
ACNormal n = {0, 0, 0};
|
||||
int found = 0;
|
||||
|
||||
/ ** go through each surface ** /
|
||||
for (s = 0; s < ob->num_surf; s++)
|
||||
{
|
||||
ACSurface *surf = &ob->surfaces[s];
|
||||
|
||||
/ ** check if this vertex is used in this surface ** /
|
||||
/ ** if it is, use it to create an average normal ** /
|
||||
for (vr = 0; vr < surf->num_vertref; vr++)
|
||||
if (surf->vertref[vr] == v)
|
||||
{
|
||||
n.x+=surf->normal.x;
|
||||
n.y+=surf->normal.y;
|
||||
n.z+=surf->normal.z;
|
||||
found++;
|
||||
}
|
||||
}
|
||||
if (found > 0)
|
||||
{
|
||||
n.x /= found;
|
||||
n.y /= found;
|
||||
n.z /= found;
|
||||
}
|
||||
ob->vertices[v].normal = n;
|
||||
}
|
||||
|
||||
|
||||
} */
|
||||
|
||||
|
||||
int string_to_objecttype(char *s)
|
||||
{
|
||||
if (streq("world", s))
|
||||
return(OBJECT_WORLD);
|
||||
if (streq("poly", s))
|
||||
return(OBJECT_NORMAL);
|
||||
if (streq("group", s))
|
||||
return(OBJECT_GROUP);
|
||||
if (streq("light", s))
|
||||
return(OBJECT_LIGHT);
|
||||
return(OBJECT_NORMAL);
|
||||
}
|
||||
|
||||
void
|
||||
protate(osg::Vec3 p, float m[9])
|
||||
{ // p-> m*p, m is 3.3 matrix
|
||||
osg::Vec3 t=p;
|
||||
p[0]=m[0]*t[0]+m[1]*t[1]+m[2]*t[3];
|
||||
p[1]=m[3]*t[0]+m[4]*t[1]+m[5]*t[3];
|
||||
p[2]=m[6]*t[0]+m[7]*t[1]+m[8]*t[3];
|
||||
}
|
||||
|
||||
osg::Group *ac_load_object(FILE *f,const ACObject *parent)
|
||||
{
|
||||
// most of this logic came from Andy Colebourne (developer of the AC3D editor) so it had better be right!
|
||||
char t[20];
|
||||
osg::Group *gp=NULL;
|
||||
osg::Geode *geode=NULL;
|
||||
osg::Vec3Array *normals = NULL; // new osg::Vec3Array; // NULL;
|
||||
|
||||
ACObject ob; // local storage for stuff taken from AC's loader
|
||||
osg::Vec3Array *vertpool = new osg::Vec3Array;
|
||||
|
||||
if (parent) ob.loc=parent->loc; // copy loc
|
||||
while (!feof(f))
|
||||
{
|
||||
read_line(f);
|
||||
|
||||
sscanf(buff, "%s", t);
|
||||
|
||||
if (streq(t, "MATERIAL"))
|
||||
{
|
||||
if (get_tokens(buff, &tokc, tokv) != 22)
|
||||
{
|
||||
printf("expected 21 params after \"MATERIAL\" - line %d\n", line);
|
||||
}
|
||||
else
|
||||
{
|
||||
osg::Material *numat=new osg::Material();
|
||||
osg::Vec4 cdiff((float)atof(tokv[3]), (float)atof(tokv[4]),
|
||||
(float)atof(tokv[5]), 1.0-(float)atof(tokv[21]));
|
||||
numat->setDiffuse(osg::Material::FRONT_AND_BACK,cdiff);
|
||||
osg::Vec4 camb((float)atof(tokv[7]),(float)atof(tokv[8]),
|
||||
(float)atof(tokv[9]),1.0-(float)atof(tokv[21]));
|
||||
numat->setAmbient(osg::Material::FRONT_AND_BACK,camb);
|
||||
osg::Vec4 cspec((float)atof(tokv[15]), (float)atof(tokv[16]),
|
||||
(float)atof(tokv[17]),1.0-(float)atof(tokv[21]));
|
||||
numat->setSpecular(osg::Material::FRONT_AND_BACK,cspec);
|
||||
osg::Vec4 cemm((float)atof(tokv[11]),(float)atof(tokv[12]),(float)atof(tokv[13]),1.0-(float)atof(tokv[21]));
|
||||
numat->setSpecular(osg::Material::FRONT_AND_BACK,cemm);
|
||||
//numat->setTransparency(osg::Material::FRONT_AND_BACK, 1.0-(float)atof(tokv[21]));
|
||||
|
||||
palette[num_palette++] = numat;
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
if (streq(t, "OBJECT"))
|
||||
{
|
||||
char type[20];
|
||||
char str[20];
|
||||
osg::Vec3 loc=ob.loc;
|
||||
if (!gp) gp = new osg::Group();
|
||||
initobject(&ob); // rezero data for object
|
||||
ob.loc=loc;
|
||||
|
||||
sscanf(buff, "%s %s", str, type);
|
||||
|
||||
ob.type = string_to_objecttype(type);
|
||||
}
|
||||
else
|
||||
if (streq(t, "data"))
|
||||
{
|
||||
if (get_tokens(buff, &tokc, tokv) != 2)
|
||||
printf("expected 'data <number>' at line %d\n", line);
|
||||
else
|
||||
{
|
||||
char *str;
|
||||
int len;
|
||||
|
||||
len = atoi(tokv[1]);
|
||||
if (len > 0)
|
||||
{
|
||||
str = (char *)myalloc(len+1);
|
||||
fread(str, len, 1, f);
|
||||
str[len] = 0;
|
||||
fscanf(f, "\n"); line++;
|
||||
ob.data = STRING(str);
|
||||
myfree(str);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
if (streq(t, "name"))
|
||||
{
|
||||
int numtok = get_tokens(buff, &tokc, tokv);
|
||||
if (numtok != 2)
|
||||
{
|
||||
printf("expected quoted name at line %d (got %d tokens)\n", line, numtok);
|
||||
}
|
||||
else
|
||||
if (gp) gp->setName(tokv[1]);
|
||||
}
|
||||
else
|
||||
if (streq(t, "texture"))
|
||||
{
|
||||
if (get_tokens(buff, &tokc, tokv) != 2)
|
||||
printf("expected quoted texture name at line %d\n", line);
|
||||
|
||||
else
|
||||
{
|
||||
osg::Image *ctx= osgDB::readImageFile(tokv[1]);
|
||||
if (ctx) { // image coukd be read
|
||||
ob.texture = new osg::Texture2D;// ac_load_texture(tokv[1]);
|
||||
ob.texture->setImage(ctx);
|
||||
if (ob.texture_repeat_x > 0.1) {
|
||||
ob.texture->setWrap(osg::Texture2D::WRAP_S, osg::Texture2D::REPEAT);
|
||||
} else {
|
||||
ob.texture->setWrap(osg::Texture2D::WRAP_S, osg::Texture2D::CLAMP);
|
||||
}
|
||||
if (ob.texture_repeat_y > 0.1) {
|
||||
ob.texture->setWrap(osg::Texture2D::WRAP_T, osg::Texture2D::REPEAT);
|
||||
} else {
|
||||
ob.texture->setWrap(osg::Texture2D::WRAP_T, osg::Texture2D::CLAMP);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
if (streq(t, "texrep"))
|
||||
{
|
||||
if (get_tokens(buff, &tokc, tokv) != 3)
|
||||
printf("expected 'texrep <float> <float>' at line %d\n", line);
|
||||
else
|
||||
{
|
||||
ob.texture_repeat_x = atof(tokv[1]);
|
||||
ob.texture_repeat_y = atof(tokv[2]);
|
||||
}
|
||||
}
|
||||
else
|
||||
if (streq(t, "texoff"))
|
||||
{
|
||||
if (get_tokens(buff, &tokc, tokv) != 3)
|
||||
printf("expected 'texoff <float> <float>' at line %d\n", line);
|
||||
else
|
||||
{
|
||||
ob.texture_offset_x = atof(tokv[1]);
|
||||
ob.texture_offset_y = atof(tokv[2]);
|
||||
}
|
||||
}
|
||||
else
|
||||
if (streq(t, "rot"))
|
||||
{
|
||||
float r[9];
|
||||
char str2[5];
|
||||
int n;
|
||||
|
||||
sscanf(buff, "%s %f %f %f %f %f %f %f %f %f", str2,
|
||||
&r[0], &r[1], &r[2], &r[3], &r[4], &r[5], &r[6], &r[7], &r[8] );
|
||||
|
||||
for (n = 0; n < 9; n++)
|
||||
ob.matrix[n] = r[n];
|
||||
|
||||
}
|
||||
else
|
||||
if (streq(t, "loc"))
|
||||
{
|
||||
char str[5];
|
||||
osg::Vec3 loc;
|
||||
sscanf(buff, "%s %f %f %f", str, &loc[0], &loc[1], &loc[2]);
|
||||
ob.loc+=loc;
|
||||
}
|
||||
else
|
||||
if (streq(t, "url"))
|
||||
{
|
||||
if (get_tokens(buff, &tokc, tokv) != 2)
|
||||
printf("expected one arg to url at line %d (got %d)\n", line, tokv);
|
||||
else
|
||||
ob.url = STRING(tokv[1]);
|
||||
}
|
||||
else
|
||||
if (streq(t, "numvert"))
|
||||
{
|
||||
int num, n;
|
||||
char str[10];
|
||||
if (ob.type == OBJECT_GROUP || ob.type == OBJECT_WORLD) {
|
||||
} else if (ob.type == OBJECT_NORMAL) {
|
||||
if (geode) {
|
||||
osgUtil::Tesselator tesselator;
|
||||
for(unsigned int i=0;i<geode->getNumDrawables();++i)
|
||||
{
|
||||
osg::Geometry* geom = dynamic_cast<osg::Geometry*>(geode->getDrawable(i));
|
||||
if (geom) tesselator.retesselatePolygons(*geom);
|
||||
}
|
||||
}
|
||||
geode = new osg::Geode();
|
||||
gp->addChild(geode);
|
||||
geode->setName(gp->getName());
|
||||
normals = new osg::Vec3Array;
|
||||
}
|
||||
|
||||
sscanf(buff, "%s %d", str, &num);
|
||||
|
||||
if (num > 0)
|
||||
{
|
||||
ob.num_vert = num;
|
||||
|
||||
for (n = 0; n < num; n++)
|
||||
{
|
||||
osg::Vec3 p;
|
||||
fscanf(f, "%f %f %f\n", &p[0], &p[1], &p[2]); line++;
|
||||
protate(p, ob.matrix);
|
||||
vertpool->push_back(p+ob.loc);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
if (streq(t, "numsurf"))
|
||||
{
|
||||
int num, n;
|
||||
char str[10];
|
||||
// this is not obvious (what is?). Each set of surfaces can have different material on each surface.
|
||||
// so I set up a set of 'bins' for
|
||||
// the primitives (geometry list, geomlist)
|
||||
// the coords array of each geometry (Vec3Array list, vertslist)
|
||||
// the tx coords array for each geometry (Vec2Array list, texslist)
|
||||
// then I add a new geometry to the current Geode for each new material as it is found.
|
||||
|
||||
std::vector<int> ia; // list of materials required- generate one geode per material
|
||||
typedef std::vector<osg::Geometry *> geomlist;
|
||||
geomlist glist;
|
||||
typedef std::vector<osg::Vec3Array *> vertslist;
|
||||
vertslist vlists; // list of vertices for each glist element
|
||||
typedef std::vector<osg::Vec2Array *> texslist;
|
||||
texslist txlists; // list of texture coords for each glist element
|
||||
|
||||
sscanf(buff, "%s %d", str, &num);
|
||||
if (num > 0)
|
||||
{
|
||||
int needSmooth=0; // flat shaded
|
||||
ob.num_surf = num;
|
||||
|
||||
for (n = 0; n < num; n++)
|
||||
{
|
||||
osg::Geometry *geom=NULL; // the surface will be addded to this geometry
|
||||
osg::Vec3Array *vgeom=NULL; // vertices corresponding to geom taken from vertexpool
|
||||
osg::Vec2Array *tgeom=NULL; // texture coords corresponding to geom taken from vertexpool
|
||||
ACSurface asurf;
|
||||
osg::UShortArray *nusidx = new osg::UShortArray; // indices into the vertices
|
||||
osg::Vec2Array *tcs=new osg::Vec2Array; // texture coordinates for this object
|
||||
ACSurface *news = read_surface(f, &asurf, nusidx, tcs);
|
||||
if (news == NULL)
|
||||
{
|
||||
printf("error whilst reading surface at line: %d\n", line);
|
||||
return(NULL);
|
||||
} else {
|
||||
int i=0;
|
||||
for (std::vector<int>::iterator itr= ia.begin(); itr<ia.end(); itr++, i++) {
|
||||
if ((*itr)==asurf.mat) {
|
||||
geom=glist[i];
|
||||
vgeom=vlists[i];
|
||||
tgeom=txlists[i]; // what is current texture array
|
||||
}
|
||||
}
|
||||
if (!geom) { // then we need a new geometry
|
||||
osg::Vec3Array *verts = new osg::Vec3Array;
|
||||
|
||||
osg::Vec2Array *tcrds=new osg::Vec2Array; // texture coordinates for this object
|
||||
vgeom=verts;
|
||||
tgeom=tcrds; // what is current texture array
|
||||
vlists.push_back(verts);
|
||||
txlists.push_back(tcrds);
|
||||
geom=new osg::Geometry();
|
||||
geom->setNormalBinding(osg::Geometry::BIND_PER_PRIMITIVE);
|
||||
geom->setNormalArray(normals);
|
||||
geom->setVertexArray(verts);
|
||||
if (ob.texture) {
|
||||
geom->setTexCoordArray(0,tgeom); // share same set of TexCoords
|
||||
}
|
||||
osg::Material*mat=ac_palette_get_material(asurf.mat);
|
||||
osg::StateSet *dstate = new osg::StateSet;
|
||||
dstate->setMode( GL_LIGHTING, osg::StateAttribute::ON );
|
||||
dstate->setAttribute(mat);
|
||||
const osg::Vec4 cdiff =mat->getDiffuse(osg::Material::FRONT_AND_BACK);
|
||||
if (cdiff[3]<0.99) {
|
||||
dstate->setMode(GL_BLEND,osg::StateAttribute::ON);
|
||||
dstate->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
|
||||
} else {
|
||||
dstate->setMode(GL_BLEND,osg::StateAttribute::OFF);
|
||||
}
|
||||
if (ob.texture) dstate->setTextureMode(0,GL_TEXTURE_2D,osg::StateAttribute::OFF);
|
||||
if (ob.texture) {
|
||||
osg::TexEnv* texenv = new osg::TexEnv;
|
||||
texenv->setMode(osg::TexEnv::MODULATE);
|
||||
dstate->setTextureAttribute(0, texenv );
|
||||
dstate->setTextureAttributeAndModes(0,ob.texture,osg::StateAttribute::ON);
|
||||
}
|
||||
if (asurf.flags & SURFACE_TWOSIDED) dstate->setMode( GL_CULL_FACE, osg::StateAttribute::OFF );
|
||||
else dstate->setMode( GL_CULL_FACE, osg::StateAttribute::ON );
|
||||
|
||||
geom->setStateSet( dstate );
|
||||
glist.push_back(geom);
|
||||
geode->addDrawable(geom);
|
||||
ia.push_back(asurf.mat);
|
||||
}
|
||||
|
||||
osg::Vec3Array* normals = geom->getNormalArray();
|
||||
/** calc surface normal **/
|
||||
if (asurf.num_vertref >= 3) {
|
||||
osg::Vec3 norm;
|
||||
osg::ushort i1=(*nusidx)[0];
|
||||
osg::ushort i2=(*nusidx)[1];
|
||||
osg::ushort i3=(*nusidx)[2];
|
||||
osgtri_calc_normal((*vertpool)[i1],
|
||||
(*vertpool)[i2],
|
||||
(*vertpool)[i3], norm);
|
||||
normals->push_back(norm);
|
||||
}
|
||||
int nstart=(*vgeom).size();
|
||||
for (i=0; i<asurf.num_vertref; i++) {
|
||||
int i1=(*nusidx)[i];
|
||||
(*vgeom).push_back((*vertpool)[i1]);
|
||||
(*tgeom).push_back((*tcs)[i]);
|
||||
}
|
||||
GLenum poltype=osg::Primitive::POLYGON;
|
||||
if (asurf.flags & SURFACE_TYPE_CLOSEDLINE) poltype=osg::Primitive::LINE_LOOP;
|
||||
if (asurf.flags & SURFACE_TYPE_LINE) poltype=osg::Primitive::LINE_STRIP;
|
||||
geom->addPrimitive(new osg::DrawArrays(poltype,nstart,asurf.num_vertref));
|
||||
if (asurf.flags & 0x10) needSmooth++;
|
||||
}
|
||||
}
|
||||
for (geomlist::iterator itr= glist.begin(); itr<glist.end(); itr++) {
|
||||
osgUtil::Tesselator tesselator;
|
||||
if (*itr) tesselator.retesselatePolygons(**itr);
|
||||
if (needSmooth) {
|
||||
osgUtil::SmoothingVisitor smoother;
|
||||
smoother.smooth(**itr);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
if (streq(t, "kids")) /** 'kids' is the last token in an object **/
|
||||
{
|
||||
int num, n;
|
||||
|
||||
sscanf(buff, "%s %d", t, &num);
|
||||
|
||||
if (num != 0)
|
||||
{
|
||||
// ob.kids = (ACObject **)myalloc(num * sizeof(ACObject *) );
|
||||
ob.num_kids = num;
|
||||
|
||||
for (n = 0; n < num; n++)
|
||||
{
|
||||
osg::Group *k = ac_load_object(f,&ob); //, ob);
|
||||
|
||||
if (k == NULL)
|
||||
{
|
||||
printf("error reading expected child object %d of %d at line: %d\n", n+1, num, line);
|
||||
return(gp);
|
||||
}
|
||||
else
|
||||
//ob.kids[n] = k;
|
||||
gp->addChild(k);
|
||||
}
|
||||
|
||||
}
|
||||
if (geode) {
|
||||
osgUtil::Tesselator tesselator;
|
||||
for(unsigned int i=0;i<geode->getNumDrawables();++i)
|
||||
{
|
||||
osg::Geometry* geom = dynamic_cast<osg::Geometry*>(geode->getDrawable(i));
|
||||
if (geom) tesselator.retesselatePolygons(*geom);
|
||||
}
|
||||
}
|
||||
return(gp);
|
||||
}
|
||||
|
||||
}
|
||||
if (geode) {
|
||||
osgUtil::Tesselator tesselator;
|
||||
for(unsigned int i=0;i<geode->getNumDrawables();++i)
|
||||
{
|
||||
osg::Geometry* geom = dynamic_cast<osg::Geometry*>(geode->getDrawable(i));
|
||||
if (geom) tesselator.retesselatePolygons(*geom);
|
||||
}
|
||||
}
|
||||
return(gp);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*void ac_calc_vertex_normals(ACObject *ob)
|
||||
{
|
||||
int n;
|
||||
|
||||
ac_object_calc_vertex_normals(ob);
|
||||
if (ob->num_kids)
|
||||
for (n = 0; n < ob->num_kids; n++)
|
||||
ac_calc_vertex_normals(ob->kids[n]);
|
||||
}*/
|
||||
|
||||
|
||||
osg::Group *ac_load_ac3d(const char *fname)
|
||||
{
|
||||
FILE *f = fopen(fname, "r");
|
||||
|
||||
osg::Group *ret = NULL;
|
||||
|
||||
if (f == NULL)
|
||||
{
|
||||
printf("can't open %s\n", fname);
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
read_line(f);
|
||||
|
||||
if (strncmp(buff, "AC3D", 4))
|
||||
{
|
||||
printf("ac_load_ac '%s' is not a valid AC3D file.", fname);
|
||||
fclose(f);
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
startmatindex = num_palette;
|
||||
|
||||
|
||||
ret = ac_load_object(f,NULL); //, NULL);
|
||||
|
||||
|
||||
fclose(f);
|
||||
|
||||
// ac_calc_vertex_normals(ret);
|
||||
// here I need to calculate nromals for this object
|
||||
|
||||
return(ret);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void ac_dump(ACObject *ob)
|
||||
{ // not yet finished option ot output AC3D file from OSG scene.
|
||||
int n;
|
||||
|
||||
printf("OBJECT name %s\nloc %f %f %f\nnum_vert %d\nnum_surf %d\n",
|
||||
ob->name, ob->loc[0], ob->loc[1], ob->loc[2], ob->num_vert, ob->num_surf);
|
||||
|
||||
|
||||
// for (n=0; n < ob->num_vert; n++)
|
||||
// printf("\tv %f %f %f\n", ob->vertices[n].x, ob->vertices[n].y, ob->vertices[n].z);
|
||||
|
||||
for (n=0; n < ob->num_surf; n++)
|
||||
{
|
||||
//// ACSurface *s = &ob->surfaces[n];
|
||||
// printf("surface %d, %d refs, mat %d\n", n, s->num_vertref, s->mat);
|
||||
}
|
||||
|
||||
/* this structure not used in OSG
|
||||
if (ob->num_kids)
|
||||
for (n = 0; n < ob->num_kids; n++)
|
||||
ac_dump(ob->kids[n]);
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
|
||||
// now register with osg::Registry to instantiate the above
|
||||
// reader/writer.
|
||||
osgDB::RegisterReaderWriterProxy<ReaderWriterAC> g_readerWriter_AC_Proxy;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
81
src/osgPlugins/ac3d/osgac3d.h
Normal file
81
src/osgPlugins/ac3d/osgac3d.h
Normal file
@@ -0,0 +1,81 @@
|
||||
// 30 Oct 2002
|
||||
// AC3D loader for models generated by the AC3D modeller (www.ac3d.org)
|
||||
// part of this source code were supplied by the AC3D project (Andy Colebourne)
|
||||
// eg the basic parsing of an AC3D file, values of constants in this include file..
|
||||
// Conversion from AC3D scenegraph to OSG by GW Michel.
|
||||
// == Opinion: ac3d is a valuable, very easy to use 3D modeller.
|
||||
// use can be picked up in hours rather than weeks.
|
||||
// Other loaders and modellers are available for OSG.
|
||||
|
||||
typedef struct ACSurface_t
|
||||
{
|
||||
int num_vertref;
|
||||
int flags;
|
||||
int mat;
|
||||
} ACSurface;
|
||||
|
||||
typedef struct ACObject_t
|
||||
{
|
||||
osg::Vec3 loc;
|
||||
char *name;
|
||||
char *data;
|
||||
char *url;
|
||||
int num_vert;
|
||||
|
||||
int num_surf;
|
||||
float texture_repeat_x, texture_repeat_y;
|
||||
float texture_offset_x, texture_offset_y;
|
||||
|
||||
int num_kids;
|
||||
struct ACObject_t **kids;
|
||||
float matrix[9];
|
||||
int type;
|
||||
osg::Texture2D *texture;
|
||||
} ACObject;
|
||||
|
||||
#define OBJECT_WORLD 999
|
||||
#define OBJECT_NORMAL 0
|
||||
#define OBJECT_GROUP 1
|
||||
#define OBJECT_LIGHT 2
|
||||
|
||||
|
||||
|
||||
#define SURFACE_SHADED (1<<4)
|
||||
#define SURFACE_TWOSIDED (1<<5)
|
||||
|
||||
#define SURFACE_TYPE_POLYGON (0)
|
||||
#define SURFACE_TYPE_CLOSEDLINE (1)
|
||||
#define SURFACE_TYPE_LINE (2)
|
||||
|
||||
|
||||
|
||||
#define Prototype
|
||||
#define Private static
|
||||
#define Boolean int
|
||||
#define FALSE (0)
|
||||
#define TRUE (!FALSE)
|
||||
#define STRING(s) (char *)(strcpy((char *)myalloc(strlen(s)+1), s))
|
||||
#define streq(a,b) (!strcmp(a,b))
|
||||
#define myalloc malloc
|
||||
#define myfree free
|
||||
|
||||
|
||||
Prototype osg::Group *ac_load_ac3d(const char *filename);
|
||||
Prototype osg::Material *ac_palette_get_material(int index);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
775
src/osgPlugins/ac3d/~ac3d.cpp
Normal file
775
src/osgPlugins/ac3d/~ac3d.cpp
Normal file
@@ -0,0 +1,775 @@
|
||||
// 30 Oct 2002
|
||||
// AC3D loader for models generated by the AC3D modeller (www.ac3d.org)
|
||||
// part of this source code were supplied by the AC3D project (Andy Colebourne)
|
||||
// eg the basic parsing of an AC3D file.
|
||||
// Conversion from AC3D scenegraph to OSG by GW Michel.
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <malloc.h>
|
||||
#include <math.h>
|
||||
|
||||
#include <osg/CullFace>
|
||||
#include <osg/Geode>
|
||||
#include <osg/Group>
|
||||
#include <osg/Geometry> //Set>
|
||||
#include <osg/Light>
|
||||
#include <osg/LightSource>
|
||||
#include <osg/Material>
|
||||
#include <osg/Texture2D>
|
||||
#include <osg/TexEnv>
|
||||
#include <osg/StateSet>
|
||||
#include <osg/Notify>
|
||||
#include <osg/Texture2D>
|
||||
|
||||
|
||||
#include <osgDB/FileNameUtils>
|
||||
#include <osgDB/Registry>
|
||||
#include <osgDB/ReadFile>
|
||||
#include <osgDB/FileUtils>
|
||||
|
||||
#include <osgUtil/Tesselator>
|
||||
#include <osgUtil/SmoothingVisitor>
|
||||
|
||||
#include "osgac3d.h"
|
||||
|
||||
class ReaderWriterAC : public osgDB::ReaderWriter
|
||||
{
|
||||
public:
|
||||
virtual const char* className() { return "AC3D Database Reader"; }
|
||||
|
||||
virtual bool acceptsExtension(const std::string& extension)
|
||||
{
|
||||
return osgDB::equalCaseInsensitive(extension,"ac");
|
||||
}
|
||||
virtual ReadResult readNode(const std::string& fileName,const osgDB::ReaderWriter::Options*)
|
||||
{
|
||||
osg::Group *grp; // holder for all loaded objects
|
||||
grp=ac_load_ac3d(fileName.c_str());
|
||||
return grp;
|
||||
};
|
||||
private:
|
||||
};
|
||||
|
||||
static int line = 0;
|
||||
static char buff[255];
|
||||
|
||||
|
||||
|
||||
static osg::Material *palette[255];
|
||||
static int num_palette = 0;
|
||||
static int startmatindex = 0;
|
||||
|
||||
|
||||
osg::Material*ac_palette_get_material(int id)
|
||||
{
|
||||
return(palette[id]);
|
||||
}
|
||||
|
||||
|
||||
Boolean read_line(FILE *f)
|
||||
{
|
||||
fgets(buff, 255, f); line++;
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
|
||||
|
||||
int tokc = 0;
|
||||
char *tokv[30];
|
||||
|
||||
Prototype int get_tokens(char *s, int *argc, char *argv[])
|
||||
/** bung '\0' chars at the end of tokens and set up the array (tokv) and count (tokc)
|
||||
like argv argc **/
|
||||
{
|
||||
char *p = s;
|
||||
char *st;
|
||||
char c;
|
||||
//int n;
|
||||
int tc;
|
||||
|
||||
tc = 0;
|
||||
while ((c = *p))
|
||||
{
|
||||
if ((c != ' ') && (c != '\t') && (c != '\n') && ( c != 13))
|
||||
{
|
||||
if (c == '"')
|
||||
{
|
||||
c = *p++;
|
||||
st = p;
|
||||
while ((c = *p) && ((c != '"')&&(c != '\n')&& ( c != 13)) )
|
||||
{
|
||||
if (c == '\\')
|
||||
strcpy(p, p+1);
|
||||
p++;
|
||||
}
|
||||
*p=0;
|
||||
argv[tc++] = st;
|
||||
}
|
||||
else
|
||||
{
|
||||
st = p;
|
||||
while ((c = *p) && ((c != ' ') && (c != '\t') && (c != '\n') && ( c != 13)) )
|
||||
p++;
|
||||
*p=0;
|
||||
argv[tc++] = st;
|
||||
}
|
||||
}
|
||||
p++;
|
||||
}
|
||||
|
||||
*argc = tc;
|
||||
return(tc);
|
||||
}
|
||||
|
||||
|
||||
void initobject(ACObject *ob)
|
||||
{
|
||||
ob->loc[0] = ob->loc[1] = ob->loc[2] = 0.0;
|
||||
ob->name = ob->url = NULL;
|
||||
ob->data = NULL;
|
||||
ob->num_vert = 0;
|
||||
ob->num_surf = 0;
|
||||
ob->texture = NULL;
|
||||
ob->texture_repeat_x = ob->texture_repeat_y = 1.0;
|
||||
ob->texture_offset_x = ob->texture_offset_y = 0.0;
|
||||
ob->kids = NULL;
|
||||
ob->num_kids = 0;
|
||||
ob->matrix[0] = 1;
|
||||
ob->matrix[1] = 0;
|
||||
ob->matrix[2] = 0;
|
||||
ob->matrix[3] = 0;
|
||||
ob->matrix[4] = 1;
|
||||
ob->matrix[5] = 0;
|
||||
ob->matrix[6] = 0;
|
||||
ob->matrix[7] = 0;
|
||||
ob->matrix[8] = 1;
|
||||
}
|
||||
|
||||
|
||||
void init_surface(ACSurface *s)
|
||||
{
|
||||
s->num_vertref = 0;
|
||||
s->flags = 0;
|
||||
s->mat = 0;
|
||||
// s->normal.x = 0.0; s->normal.z = 0.0; s->normal.z = 0.0;
|
||||
}
|
||||
|
||||
|
||||
void osgtri_calc_normal(osg::Vec3 &v1, osg::Vec3 &v2, osg::Vec3 &v3, osg::Vec3 &n)
|
||||
{
|
||||
osg::Vec3 side1=v2-v1;
|
||||
osg::Vec3 side2=v3-v2;
|
||||
n=side1^side2;
|
||||
n.normalize();
|
||||
|
||||
}
|
||||
|
||||
ACSurface *read_surface(FILE *f, ACSurface *s,osg::UShortArray *nusidx,
|
||||
osg::Vec2Array *tcs)
|
||||
{
|
||||
char t[20];
|
||||
init_surface(s);
|
||||
|
||||
while (!feof(f))
|
||||
{
|
||||
read_line(f);
|
||||
sscanf(buff, "%s", t);
|
||||
|
||||
if (streq(t, "SURF"))
|
||||
{
|
||||
int flgs;
|
||||
|
||||
if (get_tokens(buff, &tokc, tokv) != 2)
|
||||
{
|
||||
printf("SURF should be followed by one flags argument\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
flgs = strtol(tokv[1], NULL, 0);
|
||||
s->flags = flgs;
|
||||
}
|
||||
}
|
||||
else
|
||||
if (streq(t, "mat"))
|
||||
{
|
||||
int mindx;
|
||||
|
||||
sscanf(buff, "%s %d", t, &mindx);
|
||||
s->mat = mindx+startmatindex;
|
||||
}
|
||||
else
|
||||
if (streq(t, "refs"))
|
||||
{
|
||||
int num, n;
|
||||
int ind;
|
||||
osg::Vec2 tx;
|
||||
|
||||
sscanf(buff, "%s %d", t, &num);
|
||||
|
||||
s->num_vertref = num;
|
||||
|
||||
for (n = 0; n < num; n++)
|
||||
{
|
||||
fscanf(f, "%d %f %f\n", &ind, &tx[0], &tx[1]); line++;
|
||||
nusidx->push_back(ind);
|
||||
if (tcs) tcs->push_back(tx);
|
||||
}
|
||||
|
||||
return(s);
|
||||
}
|
||||
else
|
||||
printf("ignoring %s\n", t);
|
||||
|
||||
}
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*void ac_object_calc_vertex_normals(ACObject *ob)
|
||||
{
|
||||
int s, v, vr;
|
||||
|
||||
/ ** for each vertex in this object ** /
|
||||
for (v = 0; v < ob->num_vert; v++)
|
||||
{
|
||||
ACNormal n = {0, 0, 0};
|
||||
int found = 0;
|
||||
|
||||
/ ** go through each surface ** /
|
||||
for (s = 0; s < ob->num_surf; s++)
|
||||
{
|
||||
ACSurface *surf = &ob->surfaces[s];
|
||||
|
||||
/ ** check if this vertex is used in this surface ** /
|
||||
/ ** if it is, use it to create an average normal ** /
|
||||
for (vr = 0; vr < surf->num_vertref; vr++)
|
||||
if (surf->vertref[vr] == v)
|
||||
{
|
||||
n.x+=surf->normal.x;
|
||||
n.y+=surf->normal.y;
|
||||
n.z+=surf->normal.z;
|
||||
found++;
|
||||
}
|
||||
}
|
||||
if (found > 0)
|
||||
{
|
||||
n.x /= found;
|
||||
n.y /= found;
|
||||
n.z /= found;
|
||||
}
|
||||
ob->vertices[v].normal = n;
|
||||
}
|
||||
|
||||
|
||||
} */
|
||||
|
||||
|
||||
int string_to_objecttype(char *s)
|
||||
{
|
||||
if (streq("world", s))
|
||||
return(OBJECT_WORLD);
|
||||
if (streq("poly", s))
|
||||
return(OBJECT_NORMAL);
|
||||
if (streq("group", s))
|
||||
return(OBJECT_GROUP);
|
||||
if (streq("light", s))
|
||||
return(OBJECT_LIGHT);
|
||||
return(OBJECT_NORMAL);
|
||||
}
|
||||
|
||||
void
|
||||
protate(osg::Vec3 p, float m[9])
|
||||
{ // p-> m*p, m is 3.3 matrix
|
||||
osg::Vec3 t=p;
|
||||
p[0]=m[0]*t[0]+m[1]*t[1]+m[2]*t[3];
|
||||
p[1]=m[3]*t[0]+m[4]*t[1]+m[5]*t[3];
|
||||
p[2]=m[6]*t[0]+m[7]*t[1]+m[8]*t[3];
|
||||
}
|
||||
|
||||
osg::Group *ac_load_object(FILE *f,const ACObject *parent)
|
||||
{
|
||||
// most of this logic came from Andy Colebourne (developer of the AC3D editor) so it had better be right!
|
||||
char t[20];
|
||||
osg::Group *gp=NULL;
|
||||
osg::Geode *geode=NULL;
|
||||
osg::Vec3Array *normals = NULL; // new osg::Vec3Array; // NULL;
|
||||
|
||||
ACObject ob; // local storage for stuff taken from AC's loader
|
||||
osg::Vec3Array *vertpool = new osg::Vec3Array;
|
||||
|
||||
if (parent) ob.loc=parent->loc; // copy loc
|
||||
while (!feof(f))
|
||||
{
|
||||
read_line(f);
|
||||
|
||||
sscanf(buff, "%s", t);
|
||||
|
||||
if (streq(t, "MATERIAL"))
|
||||
{
|
||||
if (get_tokens(buff, &tokc, tokv) != 22)
|
||||
{
|
||||
printf("expected 21 params after \"MATERIAL\" - line %d\n", line);
|
||||
}
|
||||
else
|
||||
{
|
||||
osg::Material *numat=new osg::Material();
|
||||
osg::Vec4 cdiff((float)atof(tokv[3]), (float)atof(tokv[4]),
|
||||
(float)atof(tokv[5]), 1.0-(float)atof(tokv[21]));
|
||||
numat->setDiffuse(osg::Material::FRONT_AND_BACK,cdiff);
|
||||
osg::Vec4 camb((float)atof(tokv[7]),(float)atof(tokv[8]),
|
||||
(float)atof(tokv[9]),1.0-(float)atof(tokv[21]));
|
||||
numat->setAmbient(osg::Material::FRONT_AND_BACK,camb);
|
||||
osg::Vec4 cspec((float)atof(tokv[15]), (float)atof(tokv[16]),
|
||||
(float)atof(tokv[17]),1.0-(float)atof(tokv[21]));
|
||||
numat->setSpecular(osg::Material::FRONT_AND_BACK,cspec);
|
||||
osg::Vec4 cemm((float)atof(tokv[11]),(float)atof(tokv[12]),(float)atof(tokv[13]),1.0-(float)atof(tokv[21]));
|
||||
numat->setSpecular(osg::Material::FRONT_AND_BACK,cemm);
|
||||
//numat->setTransparency(osg::Material::FRONT_AND_BACK, 1.0-(float)atof(tokv[21]));
|
||||
|
||||
palette[num_palette++] = numat;
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
if (streq(t, "OBJECT"))
|
||||
{
|
||||
char type[20];
|
||||
char str[20];
|
||||
osg::Vec3 loc=ob.loc;
|
||||
if (!gp) gp = new osg::Group();
|
||||
initobject(&ob); // rezero data for object
|
||||
ob.loc=loc;
|
||||
|
||||
sscanf(buff, "%s %s", str, type);
|
||||
|
||||
ob.type = string_to_objecttype(type);
|
||||
}
|
||||
else
|
||||
if (streq(t, "data"))
|
||||
{
|
||||
if (get_tokens(buff, &tokc, tokv) != 2)
|
||||
printf("expected 'data <number>' at line %d\n", line);
|
||||
else
|
||||
{
|
||||
char *str;
|
||||
int len;
|
||||
|
||||
len = atoi(tokv[1]);
|
||||
if (len > 0)
|
||||
{
|
||||
str = (char *)myalloc(len+1);
|
||||
fread(str, len, 1, f);
|
||||
str[len] = 0;
|
||||
fscanf(f, "\n"); line++;
|
||||
ob.data = STRING(str);
|
||||
myfree(str);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
if (streq(t, "name"))
|
||||
{
|
||||
int numtok = get_tokens(buff, &tokc, tokv);
|
||||
if (numtok != 2)
|
||||
{
|
||||
printf("expected quoted name at line %d (got %d tokens)\n", line, numtok);
|
||||
}
|
||||
else
|
||||
if (gp) gp->setName(tokv[1]);
|
||||
}
|
||||
else
|
||||
if (streq(t, "texture"))
|
||||
{
|
||||
if (get_tokens(buff, &tokc, tokv) != 2)
|
||||
printf("expected quoted texture name at line %d\n", line);
|
||||
|
||||
else
|
||||
{
|
||||
osg::Image *ctx= osgDB::readImageFile(tokv[1]);
|
||||
if (ctx) { // image coukd be read
|
||||
ob.texture = new osg::Texture2D;// ac_load_texture(tokv[1]);
|
||||
ob.texture->setImage(ctx);
|
||||
if (ob.texture_repeat_x > 0.1) {
|
||||
ob.texture->setWrap(osg::Texture2D::WRAP_S, osg::Texture2D::REPEAT);
|
||||
} else {
|
||||
ob.texture->setWrap(osg::Texture2D::WRAP_S, osg::Texture2D::CLAMP);
|
||||
}
|
||||
if (ob.texture_repeat_y > 0.1) {
|
||||
ob.texture->setWrap(osg::Texture2D::WRAP_T, osg::Texture2D::REPEAT);
|
||||
} else {
|
||||
ob.texture->setWrap(osg::Texture2D::WRAP_T, osg::Texture2D::CLAMP);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
if (streq(t, "texrep"))
|
||||
{
|
||||
if (get_tokens(buff, &tokc, tokv) != 3)
|
||||
printf("expected 'texrep <float> <float>' at line %d\n", line);
|
||||
else
|
||||
{
|
||||
ob.texture_repeat_x = atof(tokv[1]);
|
||||
ob.texture_repeat_y = atof(tokv[2]);
|
||||
}
|
||||
}
|
||||
else
|
||||
if (streq(t, "texoff"))
|
||||
{
|
||||
if (get_tokens(buff, &tokc, tokv) != 3)
|
||||
printf("expected 'texoff <float> <float>' at line %d\n", line);
|
||||
else
|
||||
{
|
||||
ob.texture_offset_x = atof(tokv[1]);
|
||||
ob.texture_offset_y = atof(tokv[2]);
|
||||
}
|
||||
}
|
||||
else
|
||||
if (streq(t, "rot"))
|
||||
{
|
||||
float r[9];
|
||||
char str2[5];
|
||||
int n;
|
||||
|
||||
sscanf(buff, "%s %f %f %f %f %f %f %f %f %f", str2,
|
||||
&r[0], &r[1], &r[2], &r[3], &r[4], &r[5], &r[6], &r[7], &r[8] );
|
||||
|
||||
for (n = 0; n < 9; n++)
|
||||
ob.matrix[n] = r[n];
|
||||
|
||||
}
|
||||
else
|
||||
if (streq(t, "loc"))
|
||||
{
|
||||
char str[5];
|
||||
osg::Vec3 loc;
|
||||
sscanf(buff, "%s %f %f %f", str, &loc[0], &loc[1], &loc[2]);
|
||||
ob.loc+=loc;
|
||||
}
|
||||
else
|
||||
if (streq(t, "url"))
|
||||
{
|
||||
if (get_tokens(buff, &tokc, tokv) != 2)
|
||||
printf("expected one arg to url at line %d (got %d)\n", line, tokv);
|
||||
else
|
||||
ob.url = STRING(tokv[1]);
|
||||
}
|
||||
else
|
||||
if (streq(t, "numvert"))
|
||||
{
|
||||
int num, n;
|
||||
char str[10];
|
||||
if (ob.type == OBJECT_GROUP || ob.type == OBJECT_WORLD) {
|
||||
} else if (ob.type == OBJECT_NORMAL) {
|
||||
if (geode) {
|
||||
osgUtil::Tesselator tesselator;
|
||||
for(unsigned int i=0;i<geode->getNumDrawables();++i)
|
||||
{
|
||||
osg::Geometry* geom = dynamic_cast<osg::Geometry*>(geode->getDrawable(i));
|
||||
if (geom) tesselator.retesselatePolygons(*geom);
|
||||
}
|
||||
}
|
||||
geode = new osg::Geode();
|
||||
gp->addChild(geode);
|
||||
geode->setName(gp->getName());
|
||||
normals = new osg::Vec3Array;
|
||||
}
|
||||
|
||||
sscanf(buff, "%s %d", str, &num);
|
||||
|
||||
if (num > 0)
|
||||
{
|
||||
ob.num_vert = num;
|
||||
|
||||
for (n = 0; n < num; n++)
|
||||
{
|
||||
osg::Vec3 p;
|
||||
fscanf(f, "%f %f %f\n", &p[0], &p[1], &p[2]); line++;
|
||||
protate(p, ob.matrix);
|
||||
vertpool->push_back(p+ob.loc);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
if (streq(t, "numsurf"))
|
||||
{
|
||||
int num, n;
|
||||
char str[10];
|
||||
// this is not obvious (what is?). Each set of surfaces can have different material on each surface.
|
||||
// so I set up a set of 'bins' for
|
||||
// the primitives (geometry list, geomlist)
|
||||
// the coords array of each geometry (Vec3Array list, vertslist)
|
||||
// the tx coords array for each geometry (Vec2Array list, texslist)
|
||||
// then I add a new geometry to the current Geode for each new material as it is found.
|
||||
|
||||
std::vector<int> ia; // list of materials required- generate one geode per material
|
||||
typedef std::vector<osg::Geometry *> geomlist;
|
||||
geomlist glist;
|
||||
typedef std::vector<osg::Vec3Array *> vertslist;
|
||||
vertslist vlists; // list of vertices for each glist element
|
||||
typedef std::vector<osg::Vec2Array *> texslist;
|
||||
texslist txlists; // list of texture coords for each glist element
|
||||
|
||||
sscanf(buff, "%s %d", str, &num);
|
||||
if (num > 0)
|
||||
{
|
||||
int needSmooth=0; // flat shaded
|
||||
ob.num_surf = num;
|
||||
|
||||
for (n = 0; n < num; n++)
|
||||
{
|
||||
osg::Geometry *geom=NULL; // the surface will be addded to this geometry
|
||||
osg::Vec3Array *vgeom=NULL; // vertices corresponding to geom taken from vertexpool
|
||||
osg::Vec2Array *tgeom=NULL; // texture coords corresponding to geom taken from vertexpool
|
||||
ACSurface asurf;
|
||||
osg::UShortArray *nusidx = new osg::UShortArray; // indices into the vertices
|
||||
osg::Vec2Array *tcs=new osg::Vec2Array; // texture coordinates for this object
|
||||
ACSurface *news = read_surface(f, &asurf, nusidx, tcs);
|
||||
if (news == NULL)
|
||||
{
|
||||
printf("error whilst reading surface at line: %d\n", line);
|
||||
return(NULL);
|
||||
} else {
|
||||
int i=0;
|
||||
for (std::vector<int>::iterator itr= ia.begin(); itr<ia.end(); itr++, i++) {
|
||||
if ((*itr)==asurf.mat) {
|
||||
geom=glist[i];
|
||||
vgeom=vlists[i];
|
||||
tgeom=txlists[i]; // what is current texture array
|
||||
}
|
||||
}
|
||||
if (!geom) { // then we need a new geometry
|
||||
osg::Vec3Array *verts = new osg::Vec3Array;
|
||||
|
||||
osg::Vec2Array *tcrds=new osg::Vec2Array; // texture coordinates for this object
|
||||
vgeom=verts;
|
||||
tgeom=tcrds; // what is current texture array
|
||||
vlists.push_back(verts);
|
||||
txlists.push_back(tcrds);
|
||||
geom=new osg::Geometry();
|
||||
geom->setNormalBinding(osg::Geometry::BIND_PER_PRIMITIVE);
|
||||
geom->setNormalArray(normals);
|
||||
geom->setVertexArray(verts);
|
||||
if (ob.texture) {
|
||||
geom->setTexCoordArray(0,tgeom); // share same set of TexCoords
|
||||
}
|
||||
osg::Material*mat=ac_palette_get_material(asurf.mat);
|
||||
osg::StateSet *dstate = new osg::StateSet;
|
||||
dstate->setMode( GL_LIGHTING, osg::StateAttribute::ON );
|
||||
dstate->setAttribute(mat);
|
||||
const osg::Vec4 cdiff =mat->getDiffuse(osg::Material::FRONT_AND_BACK);
|
||||
if (cdiff[3]<0.99) {
|
||||
dstate->setMode(GL_BLEND,osg::StateAttribute::ON);
|
||||
dstate->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
|
||||
} else {
|
||||
dstate->setMode(GL_BLEND,osg::StateAttribute::OFF);
|
||||
}
|
||||
if (ob.texture) dstate->setTextureMode(0,GL_TEXTURE_2D,osg::StateAttribute::OFF);
|
||||
if (ob.texture) {
|
||||
osg::TexEnv* texenv = new osg::TexEnv;
|
||||
texenv->setMode(osg::TexEnv::MODULATE);
|
||||
dstate->setTextureAttribute(0, texenv );
|
||||
dstate->setTextureAttributeAndModes(0,ob.texture,osg::StateAttribute::ON);
|
||||
}
|
||||
if (asurf.flags & SURFACE_TWOSIDED) dstate->setMode( GL_CULL_FACE, osg::StateAttribute::OFF );
|
||||
else dstate->setMode( GL_CULL_FACE, osg::StateAttribute::ON );
|
||||
|
||||
geom->setStateSet( dstate );
|
||||
glist.push_back(geom);
|
||||
geode->addDrawable(geom);
|
||||
ia.push_back(asurf.mat);
|
||||
}
|
||||
|
||||
osg::Vec3Array* normals = geom->getNormalArray();
|
||||
/** calc surface normal **/
|
||||
if (asurf.num_vertref >= 3) {
|
||||
osg::Vec3 norm;
|
||||
osg::ushort i1=(*nusidx)[0];
|
||||
osg::ushort i2=(*nusidx)[1];
|
||||
osg::ushort i3=(*nusidx)[2];
|
||||
osgtri_calc_normal((*vertpool)[i1],
|
||||
(*vertpool)[i2],
|
||||
(*vertpool)[i3], norm);
|
||||
normals->push_back(norm);
|
||||
}
|
||||
int nstart=(*vgeom).size();
|
||||
for (i=0; i<asurf.num_vertref; i++) {
|
||||
int i1=(*nusidx)[i];
|
||||
(*vgeom).push_back((*vertpool)[i1]);
|
||||
(*tgeom).push_back((*tcs)[i]);
|
||||
}
|
||||
GLenum poltype=osg::Primitive::POLYGON;
|
||||
if (asurf.flags & SURFACE_TYPE_CLOSEDLINE) poltype=osg::Primitive::LINE_LOOP;
|
||||
if (asurf.flags & SURFACE_TYPE_LINE) poltype=osg::Primitive::LINE_STRIP;
|
||||
geom->addPrimitive(new osg::DrawArrays(poltype,nstart,asurf.num_vertref));
|
||||
if (asurf.flags & 0x10) needSmooth++;
|
||||
}
|
||||
}
|
||||
for (geomlist::iterator itr= glist.begin(); itr<glist.end(); itr++) {
|
||||
osgUtil::Tesselator tesselator;
|
||||
if (*itr) tesselator.retesselatePolygons(**itr);
|
||||
if (needSmooth) {
|
||||
osgUtil::SmoothingVisitor smoother;
|
||||
smoother.smooth(**itr);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
if (streq(t, "kids")) /** 'kids' is the last token in an object **/
|
||||
{
|
||||
int num, n;
|
||||
|
||||
sscanf(buff, "%s %d", t, &num);
|
||||
|
||||
if (num != 0)
|
||||
{
|
||||
// ob.kids = (ACObject **)myalloc(num * sizeof(ACObject *) );
|
||||
ob.num_kids = num;
|
||||
|
||||
for (n = 0; n < num; n++)
|
||||
{
|
||||
osg::Group *k = ac_load_object(f,&ob); //, ob);
|
||||
|
||||
if (k == NULL)
|
||||
{
|
||||
printf("error reading expected child object %d of %d at line: %d\n", n+1, num, line);
|
||||
return(gp);
|
||||
}
|
||||
else
|
||||
//ob.kids[n] = k;
|
||||
gp->addChild(k);
|
||||
}
|
||||
|
||||
}
|
||||
if (geode) {
|
||||
osgUtil::Tesselator tesselator;
|
||||
for(unsigned int i=0;i<geode->getNumDrawables();++i)
|
||||
{
|
||||
osg::Geometry* geom = dynamic_cast<osg::Geometry*>(geode->getDrawable(i));
|
||||
if (geom) tesselator.retesselatePolygons(*geom);
|
||||
}
|
||||
}
|
||||
return(gp);
|
||||
}
|
||||
|
||||
}
|
||||
if (geode) {
|
||||
osgUtil::Tesselator tesselator;
|
||||
for(unsigned int i=0;i<geode->getNumDrawables();++i)
|
||||
{
|
||||
osg::Geometry* geom = dynamic_cast<osg::Geometry*>(geode->getDrawable(i));
|
||||
if (geom) tesselator.retesselatePolygons(*geom);
|
||||
}
|
||||
}
|
||||
return(gp);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*void ac_calc_vertex_normals(ACObject *ob)
|
||||
{
|
||||
int n;
|
||||
|
||||
ac_object_calc_vertex_normals(ob);
|
||||
if (ob->num_kids)
|
||||
for (n = 0; n < ob->num_kids; n++)
|
||||
ac_calc_vertex_normals(ob->kids[n]);
|
||||
}*/
|
||||
|
||||
|
||||
osg::Group *ac_load_ac3d(const char *fname)
|
||||
{
|
||||
FILE *f = fopen(fname, "r");
|
||||
|
||||
osg::Group *ret = NULL;
|
||||
|
||||
if (f == NULL)
|
||||
{
|
||||
printf("can't open %s\n", fname);
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
read_line(f);
|
||||
|
||||
if (strncmp(buff, "AC3D", 4))
|
||||
{
|
||||
printf("ac_load_ac '%s' is not a valid AC3D file.", fname);
|
||||
fclose(f);
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
startmatindex = num_palette;
|
||||
|
||||
|
||||
ret = ac_load_object(f,NULL); //, NULL);
|
||||
|
||||
|
||||
fclose(f);
|
||||
|
||||
// ac_calc_vertex_normals(ret);
|
||||
// here I need to calculate nromals for this object
|
||||
|
||||
return(ret);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void ac_dump(ACObject *ob)
|
||||
{ // not yet finished option ot output AC3D file from OSG scene.
|
||||
int n;
|
||||
|
||||
printf("OBJECT name %s\nloc %f %f %f\nnum_vert %d\nnum_surf %d\n",
|
||||
ob->name, ob->loc[0], ob->loc[1], ob->loc[2], ob->num_vert, ob->num_surf);
|
||||
|
||||
|
||||
// for (n=0; n < ob->num_vert; n++)
|
||||
// printf("\tv %f %f %f\n", ob->vertices[n].x, ob->vertices[n].y, ob->vertices[n].z);
|
||||
|
||||
for (n=0; n < ob->num_surf; n++)
|
||||
{
|
||||
//// ACSurface *s = &ob->surfaces[n];
|
||||
// printf("surface %d, %d refs, mat %d\n", n, s->num_vertref, s->mat);
|
||||
}
|
||||
|
||||
/* this structure not used in OSG
|
||||
if (ob->num_kids)
|
||||
for (n = 0; n < ob->num_kids; n++)
|
||||
ac_dump(ob->kids[n]);
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
|
||||
// now register with osg::Registry to instantiate the above
|
||||
// reader/writer.
|
||||
osgDB::RegisterReaderWriterProxy<ReaderWriterAC> g_readerWriter_AC_Proxy;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
13
src/osgPlugins/geo/Makefile
Normal file
13
src/osgPlugins/geo/Makefile
Normal file
@@ -0,0 +1,13 @@
|
||||
TOPDIR = ../../..
|
||||
include $(TOPDIR)/Make/makedefs
|
||||
|
||||
CXXFILES =\
|
||||
ReaderWriterGEO.cpp
|
||||
|
||||
LIBS += $(OSG_LIBS) $(OTHER_LIBS)
|
||||
|
||||
TARGET_BASENAME = geo
|
||||
include $(TOPDIR)/Make/cygwin_plugin_def
|
||||
PLUGIN = $(PLUGIN_PREFIX)$(TARGET_BASENAME).$(PLUGIN_EXT)
|
||||
|
||||
include $(TOPDIR)/Make/makerules
|
||||
626
src/osgPlugins/geo/ReaderWriterGEO.cpp
Normal file
626
src/osgPlugins/geo/ReaderWriterGEO.cpp
Normal file
@@ -0,0 +1,626 @@
|
||||
// GEO format (carbon graphics Inc) loader for the OSG real time scene graph
|
||||
// www.carbongraphics.com for more information about the Geo animation+ modeller
|
||||
// 2002
|
||||
|
||||
#include "osg/Image"
|
||||
#include "osg/Group"
|
||||
#include "osg/LOD"
|
||||
#include "osg/Billboard"
|
||||
#include <osg/Sequence>
|
||||
#include <osg/Switch>
|
||||
#include <osg/Geode>
|
||||
#include <osg/Geometry>
|
||||
#include <osg/MatrixTransform>
|
||||
#include <osg/Material>
|
||||
#include <osg/Notify>
|
||||
#include <osg/Texture2D>
|
||||
#include <osg/TexEnv>
|
||||
#include <osg/StateSet>
|
||||
#include <osg/PositionAttitudeTransform>
|
||||
|
||||
|
||||
#include "osgDB/FileNameUtils"
|
||||
#include "osgDB/Registry"
|
||||
#include <osgDB/ReadFile>
|
||||
#include "osgDB/Input"
|
||||
#include "osgDB/Output"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
// specific to GEO
|
||||
#include "geoFormat.h"
|
||||
#include "geoTypes.h"
|
||||
#include "geoUnits.h"
|
||||
#include "osgGeoStructs.h"
|
||||
|
||||
using namespace osg;
|
||||
using namespace osgDB;
|
||||
|
||||
class vertexInfo { // holds vertex information for an entire osg::geometry
|
||||
public:
|
||||
vertexInfo(const float *coord_pool, const float *normal_pool) {
|
||||
norms=new osg::Vec3Array;
|
||||
coords=new osg::Vec3Array;
|
||||
txcoords=new osg::Vec2Array;
|
||||
coordindices=new osg::IntArray;
|
||||
normindices=new osg::IntArray;
|
||||
txindices=new osg::IntArray;
|
||||
cpool=coord_pool; npool=normal_pool;
|
||||
}
|
||||
inline osg::Vec3Array *getNorms() const { return norms;}
|
||||
inline osg::Vec3Array *getCoords() const { return coords;}
|
||||
inline osg::Vec2Array *getTexCoords() const { return txcoords;}
|
||||
inline osg::IntArray *getCoordIndices() const { return coordindices;}
|
||||
inline osg::IntArray *getNormIndices() const { return normindices;}
|
||||
inline osg::IntArray *getTextureIndices() const { return txindices;}
|
||||
void addIndices(georecord *gr)
|
||||
{ // this must only be called with a vertex georecord.
|
||||
if (gr->getType()==DB_DSK_VERTEX) {
|
||||
const geoField *gfd=gr->getField(GEO_DB_VRTX_NORMAL);
|
||||
int nrmindex=gfd ? gfd->getUInt():0;
|
||||
normindices->push_back(nrmindex);
|
||||
norms->push_back(osg::Vec3(npool[3*nrmindex],npool[3*nrmindex+1],npool[3*nrmindex+2]));
|
||||
gfd=gr->getField(GEO_DB_VRTX_COORD);
|
||||
unsigned int idx=gfd ? gfd->getInt():0;
|
||||
coords->push_back(osg::Vec3(cpool[3*idx],cpool[3*idx+1],cpool[3*idx+2]));
|
||||
coordindices->push_back(txcoords->size());
|
||||
txindices->push_back(txcoords->size());
|
||||
float *uvc=NULL;
|
||||
gfd=gr->getField(GEO_DB_VRTX_UV_SET_1);
|
||||
if (gfd) {
|
||||
uvc=(float *)gfd->getstore(0);
|
||||
}
|
||||
|
||||
if (uvc) { // then there are tx coords
|
||||
osg::Vec2 uv(uvc[0], uvc[1]);
|
||||
txcoords->push_back(uv);
|
||||
} else {
|
||||
txcoords->push_back(osg::Vec2(0,0));
|
||||
}
|
||||
}
|
||||
}
|
||||
friend inline std::ostream& operator << (std::ostream& output, const vertexInfo& vf)
|
||||
{
|
||||
const osg::Vec2Array *txa=vf.getTexCoords();
|
||||
osg::IntArray *normindices=vf.getNormIndices();
|
||||
osg::IntArray *txind = vf.getTextureIndices();
|
||||
output << " vertexinfo " << txa->size() << " nrm: " << normindices->size()<<
|
||||
" txinds " << txind->size()<<std::endl;
|
||||
uint i;
|
||||
for (i=0; i< txa->size(); i++) {
|
||||
const osg::Vec2 uvt=(*txa)[i];
|
||||
output << " U " << uvt.x() << " v " << uvt.y() << std::endl;
|
||||
}
|
||||
for (i=0; i<normindices->size(); i++) {
|
||||
output << "Nind " << i << " = " << (*normindices)[i] << std::endl;
|
||||
}
|
||||
return output; // to enable cascading, monkey copy from osg\plane or \quat, Ubyte4, vec2,3,4,...
|
||||
}
|
||||
private:
|
||||
const float *cpool; // passed in from the geo file
|
||||
const float *npool;
|
||||
osg::Vec3Array *norms;
|
||||
osg::Vec3Array *coords;
|
||||
osg::Vec2Array *txcoords;
|
||||
osg::IntArray *coordindices;
|
||||
osg::IntArray *normindices;
|
||||
osg::IntArray *txindices;
|
||||
};
|
||||
|
||||
class ReaderWriterGEO : public ReaderWriter
|
||||
{
|
||||
public:
|
||||
virtual const char* className() { return "GEO Reader/Writer"; }
|
||||
|
||||
virtual bool acceptsExtension(const std::string& extension)
|
||||
{
|
||||
return equalCaseInsensitive(extension,"gem") || equalCaseInsensitive(extension,"geo");
|
||||
}
|
||||
|
||||
virtual ReadResult readObject(const std::string& fileName, const Options* opt) { return readNode(fileName,opt); }
|
||||
|
||||
virtual ReadResult readNode(const std::string& fileName, const Options*)
|
||||
{
|
||||
std::string ext = getFileExtension(fileName);
|
||||
if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED;
|
||||
|
||||
std::ifstream fin(fileName.c_str(), std::ios::binary | std::ios::in );
|
||||
if (fin.is_open() )
|
||||
{ // read the input file.
|
||||
typedef std::vector<osg::Node*> NodeList;
|
||||
NodeList nodeList;
|
||||
geoRecordList recs;
|
||||
osg::Material *mt=new osg::Material;
|
||||
matlist.push_back(mt);
|
||||
|
||||
// load all nodes in file, placing them in a linear list corresponding to the on disk file.
|
||||
while(!fin.eof())
|
||||
{
|
||||
georecord gr;
|
||||
gr.readfile(fin);
|
||||
// osg::notify(osg::WARN) << gr << std::endl;
|
||||
recs.push_back(gr); // add to a list of all records
|
||||
}
|
||||
fin.close();
|
||||
// now sort the reocrds so that any record followed by a PUSh has a child set = next record, etc
|
||||
std::vector<georecord *> sorted=sort(recs); // tree-list of sorted record pointers
|
||||
std::fstream fout("georex.txt", std::ios::out );
|
||||
fout << "Debug file " << std::endl;
|
||||
// output(fout,sorted); // print details of the sorted tree, with records indented.
|
||||
nodeList=makeosg(sorted, fout); // make a list of osg nodes
|
||||
fout.close();
|
||||
|
||||
if (nodeList.empty())
|
||||
{
|
||||
return ReadResult("No data loaded from "+fileName);
|
||||
}
|
||||
else if (nodeList.size()==1)
|
||||
{
|
||||
return nodeList.front();
|
||||
}
|
||||
else
|
||||
{
|
||||
Group* group = osgNew Group;
|
||||
group->setName("import group");
|
||||
for(NodeList::iterator itr=nodeList.begin();
|
||||
itr!=nodeList.end();
|
||||
++itr)
|
||||
{
|
||||
group->addChild(*itr);
|
||||
}
|
||||
return group;
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0L;
|
||||
}
|
||||
}
|
||||
std::vector<georecord *> sort(geoRecordList &recs) { // return a tree-list of sorted record pointers
|
||||
// which mirrors the original .geo file (containers hold push/pop blocks).
|
||||
std::vector<georecord *> sorted;
|
||||
class georecord *curparent=NULL;
|
||||
for (geoRecordList::iterator itr=recs.begin();
|
||||
itr!=recs.end();
|
||||
++itr) {
|
||||
// osg::notify(osg::WARN) << *itr << std::endl;
|
||||
// now parse for push/pops and add to lists
|
||||
if ((*itr).getType()==DB_DSK_COORD_POOL) {
|
||||
const geoField *gfd=itr->getField(GEO_DB_COORD_POOL_VALUES);
|
||||
coord_pool= (gfd) ? (gfd->getVec3Arr()):NULL;
|
||||
} else if ((*itr).getType()==DB_DSK_NORMAL_POOL) {
|
||||
const geoField *gfd=itr->getField(GEO_DB_NORMAL_POOL_VALUES);
|
||||
normal_pool= (gfd) ? (gfd->getVec3Arr()):NULL;
|
||||
}
|
||||
if ((*itr).getType()==DB_DSK_PUSH) {
|
||||
curparent= itr-1;
|
||||
} else if ((*itr).getType()==DB_DSK_POP) {
|
||||
if (curparent) curparent=curparent->getparent();
|
||||
} else {
|
||||
if (curparent) {
|
||||
(*itr).setparent(curparent);
|
||||
curparent->addchild(itr);
|
||||
} else {
|
||||
sorted.push_back(itr);
|
||||
}
|
||||
}
|
||||
}
|
||||
return sorted;
|
||||
}
|
||||
int getprim(const std::vector<georecord *> gr,vertexInfo &vinf)
|
||||
{ // fills vinf with txcoords = texture coordinates, txindex=txindex etc
|
||||
int nv=0;
|
||||
if (gr.size()>0) {
|
||||
for (std::vector<georecord *>::const_iterator itr=gr.begin();
|
||||
itr!=gr.end();
|
||||
++itr) {
|
||||
vinf.addIndices((*itr));
|
||||
nv++;
|
||||
}
|
||||
}
|
||||
return nv;
|
||||
}
|
||||
std::vector<osg::Geometry *>makeGeometry(const std::vector<georecord *> gr, const unsigned int imat)
|
||||
{
|
||||
// txcoords returns with a set of vec2 (UV coords for texturing)
|
||||
std::vector<osg::Geometry *> geom;
|
||||
if (gr.size()>0) {
|
||||
std::vector<int> ia; // list of texture indices found i this geode; sort into new
|
||||
vertexInfo vinf(coord_pool,normal_pool); // holds all types of coords, indices etc
|
||||
int nstart=0; // start of list
|
||||
for (std::vector<georecord *>::const_iterator itr=gr.begin();
|
||||
itr!=gr.end();
|
||||
++itr) {
|
||||
if ((*itr)->getType()==DB_DSK_POLYGON) {
|
||||
int txidx=-1;
|
||||
const geoField *gfd=(*itr)->getField(GEO_DB_POLY_TEX);
|
||||
if (gfd) txidx=gfd->getInt();
|
||||
int igidx=0, igeom=-1;
|
||||
for (IntArray::const_iterator itrint=ia.begin();
|
||||
itrint!=ia.end();
|
||||
++itrint) {
|
||||
if (txidx==(*itrint)) igeom=igidx;
|
||||
igidx++;
|
||||
}
|
||||
if (igeom<0) {
|
||||
osg::Geometry *nug;
|
||||
nug=new osg::Geometry;
|
||||
nug->setNormalBinding(osg::Geometry::BIND_PER_VERTEX);
|
||||
nug->setVertexArray(vinf.getCoords());
|
||||
nug->setNormalArray(vinf.getNorms());
|
||||
StateSet *dstate=new StateSet;
|
||||
if (txidx>=0 && (unsigned int)txidx<txlist.size()) {
|
||||
dstate->setTextureAttribute(0, txenvlist[txidx] );
|
||||
dstate->setTextureAttributeAndModes(0,txlist[txidx],osg::StateAttribute::ON);
|
||||
}
|
||||
if (imat>0 && imat<matlist.size()) dstate->setAttribute(matlist[imat]);
|
||||
else dstate->setAttribute(matlist[0]);
|
||||
nug->setStateSet( dstate );
|
||||
geom.push_back(nug);
|
||||
igeom=ia.size();
|
||||
ia.push_back(txidx); // look up table for which texture corresponds to which geom
|
||||
}
|
||||
int nv=getprim((*itr)->getchildren(),vinf);
|
||||
geom[igeom]->addPrimitive(new osg::DrawArrays(osg::Primitive::POLYGON,nstart,nv));
|
||||
nstart+=nv;
|
||||
}
|
||||
}
|
||||
osg::Vec2Array *txa=vinf.getTexCoords();
|
||||
if (txa->size() > 0 ) {
|
||||
for (std::vector<osg::Geometry *>::iterator itr=geom.begin();
|
||||
itr!=geom.end();
|
||||
++itr) {
|
||||
(*itr)->setTexCoordArray(0, txa);
|
||||
}
|
||||
}
|
||||
// osg::notify(osg::WARN) << vinf;
|
||||
}
|
||||
return geom;
|
||||
}
|
||||
osg::Group *makeGroup(const georecord *gr) { // group or Static transform
|
||||
osg::Group *gp=NULL;
|
||||
const geoField *gfd=gr->getField(GEO_DB_GRP_TRANSFORM);
|
||||
if (gfd) {
|
||||
osg::MatrixTransform *tr=new osg::MatrixTransform;
|
||||
osg::Matrix mx;
|
||||
float * m44=gfd->getMat44Arr();
|
||||
mx.set(m44); // hope uses same convention as OSG else will need to use set(m44[0],m44[1]...)
|
||||
tr->setMatrix(mx);
|
||||
gp=tr;
|
||||
} else {
|
||||
gp=new osg::Group;
|
||||
}
|
||||
gfd=gr->getField(GEO_DB_GRP_NAME);
|
||||
if (gfd) {
|
||||
gp->setName(gfd->getChar());
|
||||
}
|
||||
return gp;
|
||||
}
|
||||
osg::Group * makeSwitch(const georecord *gr) {
|
||||
osg::Switch *sw=new Switch;
|
||||
const geoField *gfd=gr->getField(GEO_DB_SWITCH_CURRENT_MASK);
|
||||
sw->setValue(osg::Switch::ALL_CHILDREN_OFF);
|
||||
if (gfd) {
|
||||
int imask;
|
||||
imask=gfd->getInt();
|
||||
sw->setValue(imask);
|
||||
osg::notify(osg::WARN) << gr << " imask " << imask << std::endl;
|
||||
} else {
|
||||
sw->setValue(0);
|
||||
osg::notify(osg::WARN) << gr << " No mask " << std::endl;
|
||||
}
|
||||
gfd=gr->getField(GEO_DB_SWITCH_NAME);
|
||||
if (gfd) {
|
||||
sw->setName(gfd->getChar());
|
||||
}
|
||||
return sw;
|
||||
}
|
||||
osg::Sequence *makeSequence(const georecord *gr)
|
||||
{
|
||||
Sequence *sq=new Sequence;
|
||||
const geoField *gfd=gr->getField(GEO_DB_SEQUENCE_NAME);
|
||||
if (gfd) {
|
||||
sq->setName(gfd->getChar());
|
||||
}
|
||||
return sq;
|
||||
}
|
||||
osg::LOD *makeLOD(const georecord *gr)
|
||||
{
|
||||
osg::LOD *gp=new LOD;
|
||||
const geoField *gfd=gr->getField(GEO_DB_LOD_IN);
|
||||
float in = gfd ? gfd->getFloat() : 100.0;
|
||||
gfd=gr->getField(GEO_DB_LOD_OUT);
|
||||
float out = gfd ? gfd->getFloat() : 0.0;
|
||||
gp->setRange(0,out,in);
|
||||
gfd=gr->getField(GEO_DB_LOD_NAME);
|
||||
if (gfd) {
|
||||
gp->setName(gfd->getChar());
|
||||
}
|
||||
return gp;
|
||||
}
|
||||
osg::PositionAttitudeTransform *makeHeader(const georecord *gr) {
|
||||
osg::PositionAttitudeTransform *nup=NULL;
|
||||
const geoField *gfd=gr->getField(GEO_DB_HDR_UP_AXIS);
|
||||
if (gfd) {
|
||||
unsigned iup=gfd->getUInt();
|
||||
if (iup==GEO_DB_UP_AXIS_X) {
|
||||
nup=new PositionAttitudeTransform();
|
||||
osg::Quat q;
|
||||
q.set(1,1,0,0);
|
||||
q/=q.length();
|
||||
nup->setAttitude(q);
|
||||
} else if (iup==GEO_DB_UP_AXIS_Y) {
|
||||
nup=new PositionAttitudeTransform();
|
||||
osg::Quat q;
|
||||
q.set(1,0,0,1);
|
||||
q/=q.length();
|
||||
nup->setAttitude(q);
|
||||
}
|
||||
}
|
||||
return nup;
|
||||
}
|
||||
void makeTexture(const georecord *gr) {
|
||||
// scans the fields of this record and puts a new texture & environment into 'pool' stor
|
||||
const geoField *gfd=gr->getField(GEO_DB_TEX_FILE_NAME);
|
||||
const char *name = gfd->getChar();
|
||||
if (name) {
|
||||
Texture2D *tx=new Texture2D;
|
||||
Image *ctx=osgDB::readImageFile(name);
|
||||
if (ctx) {
|
||||
ctx->setFileName(name);
|
||||
tx->setImage(ctx);
|
||||
}
|
||||
gfd=gr->getField(GEO_DB_TEX_WRAPS);
|
||||
osg::Texture2D::WrapMode wm=Texture2D::REPEAT;
|
||||
if (gfd) {
|
||||
unsigned iwrap= gfd->getUInt();
|
||||
wm = (iwrap==GEO_DB_TEX_CLAMP) ? Texture2D::CLAMP : Texture2D::REPEAT;
|
||||
}
|
||||
tx->setWrap(Texture2D::WRAP_S, wm);
|
||||
gfd=gr->getField(GEO_DB_TEX_WRAPT);
|
||||
wm=Texture2D::REPEAT;
|
||||
if (gfd) {
|
||||
unsigned iwrap= gfd->getUInt();
|
||||
wm = (iwrap==GEO_DB_TEX_CLAMP) ? Texture2D::CLAMP : Texture2D::REPEAT;
|
||||
}
|
||||
tx->setWrap(Texture2D::WRAP_T, wm);
|
||||
txlist.push_back(tx);
|
||||
osg::TexEnv* texenv = new osg::TexEnv;
|
||||
osg::TexEnv::Mode md=osg::TexEnv::MODULATE;
|
||||
gfd=gr->getField(GEO_DB_TEX_ENV);
|
||||
texenv->setMode(md);
|
||||
if (gfd) {
|
||||
unsigned imod=gfd->getUInt();
|
||||
switch (imod) {
|
||||
case GEO_DB_TEX_MODULATE:
|
||||
md=osg::TexEnv::MODULATE;
|
||||
break;
|
||||
case GEO_DB_TEX_DECAL:
|
||||
md=osg::TexEnv::DECAL;
|
||||
break;
|
||||
case GEO_DB_TEX_BLEND:
|
||||
md=osg::TexEnv::BLEND;
|
||||
break;
|
||||
}
|
||||
}
|
||||
gfd=gr->getField(GEO_DB_TEX_MINFILTER);
|
||||
osg::Texture::FilterMode filt=osg::Texture::NEAREST_MIPMAP_NEAREST;
|
||||
if (gfd) {
|
||||
unsigned imod=gfd->getUInt();
|
||||
switch (imod) {
|
||||
case GEO_DB_TEX_NEAREST_MIPMAP_NEAREST:
|
||||
filt=osg::Texture::LINEAR_MIPMAP_LINEAR;
|
||||
break;
|
||||
case GEO_DB_TEX_LINEAR_MIPMAP_NEAREST:
|
||||
filt=osg::Texture::LINEAR_MIPMAP_NEAREST;
|
||||
break;
|
||||
case GEO_DB_TEX_NEAREST_MIPMAP_LINEAR:
|
||||
filt=osg::Texture::NEAREST_MIPMAP_LINEAR;
|
||||
break;
|
||||
case GEO_DB_TEX_LINEAR_MIPMAP_LINEAR:
|
||||
filt=osg::Texture::NEAREST_MIPMAP_NEAREST;
|
||||
break;
|
||||
}
|
||||
}
|
||||
tx->setFilter(osg::Texture::MIN_FILTER, filt);
|
||||
gfd=gr->getField(GEO_DB_TEX_MAGFILTER);
|
||||
if (gfd) {
|
||||
unsigned imod=gfd->getUInt();
|
||||
switch (imod) {
|
||||
case GEO_DB_TEX_NEAREST:
|
||||
filt=osg::Texture::LINEAR;
|
||||
break;
|
||||
case GEO_DB_TEX_LINEAR:
|
||||
filt=osg::Texture::NEAREST;
|
||||
break;
|
||||
}
|
||||
}
|
||||
txenvlist.push_back(texenv);
|
||||
}
|
||||
}
|
||||
std::vector<Node *> makeosg(const std::vector<georecord *> gr, std::fstream &fout) {
|
||||
// recursive traversal of records and extract osg::Nodes equivalent
|
||||
Group *geodeholder=NULL;
|
||||
std::vector<Node *> nodelist;
|
||||
if (gr.size()>0) {
|
||||
for (std::vector<georecord *>::const_iterator itr=gr.begin();
|
||||
itr!=gr.end();
|
||||
++itr) {
|
||||
const georecord *gr=*itr;
|
||||
if (gr->getType()== DB_DSK_GEODE) { // geodes can require >1 geometry for example if polygons have different texture indices.
|
||||
if (!geodeholder) {
|
||||
geodeholder=new osg::Group;
|
||||
}
|
||||
Geode *geode=new Geode;
|
||||
const geoField *gfd=gr->getField(GEO_DB_RENDERGROUP_MAT);
|
||||
const unsigned int imat=gfd ? gfd->getInt():0;
|
||||
std::vector<osg::Geometry *>geom=makeGeometry((*itr)->getchildren(),imat);
|
||||
for (std::vector<osg::Geometry *>::iterator itr=geom.begin();
|
||||
itr!=geom.end();
|
||||
++itr)
|
||||
{
|
||||
geode->addDrawable((*itr));
|
||||
}
|
||||
geodeholder->addChild(geode);
|
||||
} else {
|
||||
Group *holder=NULL;
|
||||
const geoField *gfd;
|
||||
switch (gr->getType()) {
|
||||
case DB_DSK_HEADER:
|
||||
holder=makeHeader(gr);
|
||||
|
||||
break;
|
||||
case DB_DSK_MATERIAL: {
|
||||
osg::Material *mt=new osg::Material;
|
||||
gr->setMaterial(mt);
|
||||
matlist.push_back(mt);
|
||||
}
|
||||
break;
|
||||
case DB_DSK_TEXTURE:
|
||||
makeTexture(gr);
|
||||
break;
|
||||
case DB_DSK_GROUP:
|
||||
holder=makeGroup(gr);
|
||||
break;
|
||||
case DB_DSK_BEHAVIOR:
|
||||
holder=new MatrixTransform;
|
||||
gfd=gr->getField(GEO_DB_BEHAVIOR_NAME);
|
||||
if (gfd) {
|
||||
holder->setName(gfd->getChar());
|
||||
}
|
||||
break;
|
||||
case DB_DSK_LOD:
|
||||
holder=makeLOD(gr);
|
||||
break;
|
||||
case DB_DSK_SEQUENCE:
|
||||
holder=makeSequence(gr);
|
||||
break;
|
||||
case DB_DSK_SWITCH:
|
||||
holder=makeSwitch(gr);
|
||||
break;
|
||||
case DB_DSK_CUBE:
|
||||
holder=new Group;
|
||||
gfd=gr->getField(GEO_DB_GRP_NAME);
|
||||
if (gfd) {
|
||||
holder->setName(gfd->getChar());
|
||||
}
|
||||
break;
|
||||
case DB_DSK_SPHERE:
|
||||
holder=new Group;
|
||||
gfd=gr->getField(GEO_DB_GRP_NAME);
|
||||
if (gfd) {
|
||||
holder->setName(gfd->getChar());
|
||||
}
|
||||
break;
|
||||
case DB_DSK_CONE:
|
||||
holder=new Group;
|
||||
gfd=gr->getField(GEO_DB_GRP_NAME);
|
||||
if (gfd) {
|
||||
holder->setName(gfd->getChar());
|
||||
}
|
||||
break;
|
||||
case DB_DSK_CYLINDER:
|
||||
holder=new Group;
|
||||
gfd=gr->getField(GEO_DB_GRP_NAME);
|
||||
if (gfd) {
|
||||
holder->setName(gfd->getChar());
|
||||
}
|
||||
break;
|
||||
case DB_DSK_INSTANCE:
|
||||
holder=new Group;
|
||||
/*gfd=gr->getField(GEO_DB_GRP_NAME);
|
||||
if (gfd) {
|
||||
holder->setName(gfd->getChar());
|
||||
} */
|
||||
break;
|
||||
case DB_DSK_PAGE:
|
||||
holder=new Group;
|
||||
gfd=gr->getField(GEO_DB_PAGE_NAME);
|
||||
if (gfd) {
|
||||
holder->setName(gfd->getChar());
|
||||
}
|
||||
break;
|
||||
case DB_DSK_FLOAT_VAR:
|
||||
case DB_DSK_INT_VAR:
|
||||
case DB_DSK_LONG_VAR:
|
||||
case DB_DSK_DOUBLE_VAR:
|
||||
case DB_DSK_BOOL_VAR:
|
||||
case DB_DSK_FLOAT2_VAR:
|
||||
case DB_DSK_FLOAT3_VAR:
|
||||
case DB_DSK_FLOAT4_VAR:
|
||||
|
||||
case DB_DSK_INTERNAL_VARS:
|
||||
case DB_DSK_LOCAL_VARS:
|
||||
case DB_DSK_EXTERNAL_VARS:
|
||||
fout << "==Unhandled option " << gr->getType() << std::endl;
|
||||
fout << (*gr) << std::endl;
|
||||
break;
|
||||
case DB_DSK_CLAMP_ACTION:
|
||||
case DB_DSK_RANGE_ACTION:
|
||||
case DB_DSK_ROTATE_ACTION:
|
||||
case DB_DSK_TRANSLATE_ACTION:
|
||||
case DB_DSK_SCALE_ACTION:
|
||||
case DB_DSK_ARITHMETIC_ACTION:
|
||||
case DB_DSK_LOGIC_ACTION:
|
||||
case DB_DSK_CONDITIONAL_ACTION:
|
||||
case DB_DSK_LOOPING_ACTION:
|
||||
case DB_DSK_COMPARE_ACTION:
|
||||
case DB_DSK_VISIBILITY_ACTION:
|
||||
case DB_DSK_STRING_CONTENT_ACTION:
|
||||
holder=new Group;
|
||||
fout << "==Poorly handled option " << gr->getType() << std::endl;
|
||||
fout << (*gr) << std::endl;
|
||||
break;
|
||||
default: {
|
||||
osg::Group *gp=new Group;
|
||||
holder=gp;
|
||||
}
|
||||
break;
|
||||
}
|
||||
nodelist.push_back(holder);
|
||||
|
||||
std::vector<Node *> child=makeosg((*itr)->getchildren(),fout);
|
||||
for (std::vector<Node *>::iterator itr=child.begin();
|
||||
itr!=child.end();
|
||||
++itr) {
|
||||
holder->addChild(*itr);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (geodeholder) nodelist.push_back(geodeholder);
|
||||
return nodelist;
|
||||
}
|
||||
void output(std::fstream &fout,std::vector<georecord *> gr)
|
||||
{ // debugging - print the tree of records
|
||||
static int depth=0;
|
||||
depth++;
|
||||
if (gr.size()>0) {
|
||||
for (std::vector<georecord *>::iterator itr=gr.begin();
|
||||
itr!=gr.end();
|
||||
++itr) {
|
||||
// osg::notify(osg::WARN)
|
||||
for (int i=0; i<depth-1; i++) fout << " " ;
|
||||
fout << "Node type " << (*itr)->getType() << " ";
|
||||
fout << (**itr) << std::endl;
|
||||
fout << std::endl;
|
||||
output(fout,(*itr)->getchildren());
|
||||
}
|
||||
}
|
||||
depth--;
|
||||
}
|
||||
private:
|
||||
// std::fstream fout; // debug output
|
||||
static float *coord_pool; // current vertex ooords
|
||||
static float *normal_pool; // current pool of normal vectors
|
||||
std::vector<osg::Texture2D *> txlist; // list of textures for this model
|
||||
std::vector<osg::TexEnv *> txenvlist; // list of texture environments for the textures
|
||||
std::vector<osg::Material *> matlist; // list of materials for current model
|
||||
};
|
||||
|
||||
// now register with Registry to instantiate the above
|
||||
// reader/writer.
|
||||
osgDB::RegisterReaderWriterProxy<ReaderWriterGEO> gReaderWriter_GEO_Proxy;
|
||||
float *ReaderWriterGEO::coord_pool=NULL; // current vertex ooords
|
||||
float *ReaderWriterGEO::normal_pool=NULL; // current vertex ooords
|
||||
1057
src/osgPlugins/geo/geoFormat.h
Normal file
1057
src/osgPlugins/geo/geoFormat.h
Normal file
File diff suppressed because it is too large
Load Diff
377
src/osgPlugins/geo/geoTypes.h
Normal file
377
src/osgPlugins/geo/geoTypes.h
Normal file
@@ -0,0 +1,377 @@
|
||||
/*===========================================================================*\
|
||||
|
||||
NAME: geoTypes.h
|
||||
|
||||
DESCRIPTION: Constants fro Node types etc.
|
||||
|
||||
AUTHOR: Andy Bushnell
|
||||
|
||||
-------------------------------------------------------------------------
|
||||
|
||||
PROPRIETARY RIGHTS NOTICE:
|
||||
|
||||
This software contains proprietary information and trade secrets of Carbon
|
||||
Graphics LLC. No part or all of this software may be reproduced in any form,
|
||||
without the written permission of Carbon Graphics LLC.
|
||||
|
||||
Exception:
|
||||
This Software file can be used by third-party software developers (without
|
||||
using the Geo SDK libraries) for any purpose OTHER THAN loading Geo format
|
||||
files into an application or executable (such as, though not limited to,
|
||||
geometry Modelers & animation systems) which is primarily intended to allow for
|
||||
the CREATION or MODIFICATION of geometric or animation data.
|
||||
|
||||
Specifically,using this software (either all or part thereof) to aid in the
|
||||
creation of a Geo format loader for a run-time system, game engine, toolkit
|
||||
IG (Image Generation) System or any software where the PRIMARY purpose is
|
||||
real-time image playback and interactivity and not Model Creation and/or
|
||||
modification is permitted.
|
||||
|
||||
COPYRIGHT NOTICE:
|
||||
|
||||
Copyright <20> 1998-2001 Carbon Graphics Llc, ALL RIGHTS RESERVED
|
||||
|
||||
\*===========================================================================*/
|
||||
|
||||
|
||||
|
||||
#ifndef _GEO_TYPES_H_
|
||||
#define _GEO_TYPES_H_
|
||||
|
||||
|
||||
|
||||
#ifndef uint
|
||||
#define uint unsigned int
|
||||
#endif
|
||||
|
||||
#ifndef ushort
|
||||
//#define ushort unsigned short
|
||||
#endif
|
||||
|
||||
#ifndef ubyte
|
||||
#define ubyte unsigned char
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* constants to identify the plugin type
|
||||
*/
|
||||
const uint GEO_PLUGIN_TYPE_UNDEFINED = 1;
|
||||
const uint GEO_PLUGIN_TYPE_GEOMETRY_IMPORTER = 2;
|
||||
const uint GEO_PLUGIN_TYPE_GEOMETRY_EXPORTER = 3;
|
||||
const uint GEO_PLUGIN_TYPE_IMAGE_IMPORTER = 4;
|
||||
const uint GEO_PLUGIN_TYPE_TOOL = 5;
|
||||
const uint GEO_PLUGIN_TYPE_BEHAVIOR = 6;
|
||||
const uint GEO_PLUGIN_TYPE_GROUP_NODE_DEF = 7;
|
||||
const uint GEO_PLUGIN_TYPE_LAST = GEO_PLUGIN_TYPE_GROUP_NODE_DEF;
|
||||
|
||||
|
||||
|
||||
|
||||
/** user tool constant - put in favorites menu & toolbar */
|
||||
const uint GEO_TOOL_TYPE_USER = 1;
|
||||
|
||||
/** create tool constant - put in create menu & toolbar */
|
||||
const uint GEO_TOOL_TYPE_CREATE = 2;
|
||||
|
||||
/** modify tool constant - put in modify menu & toolbar */
|
||||
const uint GEO_TOOL_TYPE_MODIFY = 3;
|
||||
|
||||
/** helper point tool constant - put in helpers menu & toolbar */
|
||||
const uint GEO_TOOL_TYPE_HELPER_PT = 4;
|
||||
|
||||
/** appearance tool constant - put in plugins menu & toolbar */
|
||||
const uint GEO_TOOL_TYPE_APPEARANCE = 5;
|
||||
|
||||
/** behavior tool constant - put in plugins menu & toolbar */
|
||||
const uint GEO_TOOL_TYPE_BEHAVIOR = 6;
|
||||
|
||||
/** behavior tool constant - put in plugins menu & toolbar */
|
||||
const uint GEO_TOOL_TYPE_OPTIMIZE = 7;
|
||||
|
||||
/** convenience constant */
|
||||
const uint GEO_TOOL_TYPE_LAST = GEO_TOOL_TYPE_OPTIMIZE;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Node Type identifiers. These tokens encode the Node's inheritance
|
||||
* information within the type
|
||||
*
|
||||
* The GEO Node Type Class Hierarchy is as follows...
|
||||
*
|
||||
* GEO_DB_BASE
|
||||
* GEO_DB_GROUP
|
||||
* GEO_DB_BILLBOARD
|
||||
* GEO_DB_SEQUENCE
|
||||
* GEO_DB_LOD
|
||||
* GEO_DB_SWITCH
|
||||
* GEO_DB_RENDERGROUP
|
||||
* GEO_DB_BASE_GROUP
|
||||
* GEO_DB_EXTERNAL
|
||||
* GEO_DB_INSTANCE
|
||||
* GEO_DB_PAGE
|
||||
* GEO_DB_TRANSFORM (*)
|
||||
* GEO_DB_GEOMETRY
|
||||
* GEO_DB_SURFACE
|
||||
* GEO_DB_COORDINATE_SURFACE
|
||||
* GEO_DB_POLYGON
|
||||
* GEO_DB_LIGHTPT
|
||||
* GEO_DB_MESH (*)
|
||||
* GEO_DB_PARAMETRIC_SURFACE (*)
|
||||
* GEO_DB_QUADRIC (*)
|
||||
* GEO_DB_TEXT
|
||||
* GEO_DB_BASE_SURFACE (*)
|
||||
* GEO_DB_VERTEX
|
||||
* GEO_DB_HEADER
|
||||
*
|
||||
* (*) Not available in Geo Version 1.0
|
||||
*/
|
||||
const uint GEO_DB_BASE = 0x00000003;
|
||||
const uint GEO_DB_GROUP = (0x00000004 | GEO_DB_BASE);
|
||||
const uint GEO_DB_SEQUENCE = (0x00000010 | GEO_DB_GROUP);
|
||||
const uint GEO_DB_LOD = (0x00000020 | GEO_DB_GROUP);
|
||||
const uint GEO_DB_SWITCH = (0x00000040 | GEO_DB_GROUP);
|
||||
const uint GEO_DB_RENDERGROUP = (0x00000080 | GEO_DB_GROUP);
|
||||
const uint GEO_DB_GEOMETRY = (0x00000100 | GEO_DB_BASE);
|
||||
const uint GEO_DB_SURFACE = (0x00000200 | GEO_DB_GEOMETRY);
|
||||
const uint GEO_DB_COORDINATE_SURFACE = (0x00000400 | GEO_DB_SURFACE);
|
||||
const uint GEO_DB_POLYGON = (0x00000800 | GEO_DB_COORDINATE_SURFACE);
|
||||
const uint GEO_DB_MESH = (0x00001000 | GEO_DB_POLYGON);
|
||||
const uint GEO_DB_PARAMETRIC_SURFACE = (0x00002000 | GEO_DB_SURFACE);
|
||||
const uint GEO_DB_QUADRIC = (0x00004000 | GEO_DB_PARAMETRIC_SURFACE);
|
||||
const uint GEO_DB_PAGE = (0x00008000 | GEO_DB_GROUP);
|
||||
const uint GEO_DB_TEXT = (0x00040000 | GEO_DB_SURFACE);
|
||||
const uint GEO_DB_VERTEX = (0x00080000 | GEO_DB_GEOMETRY);
|
||||
const uint GEO_DB_HEADER = (0x00100000 | GEO_DB_BASE);
|
||||
const uint GEO_DB_TRANSFORM = (0x00200000 | GEO_DB_GROUP);
|
||||
const uint GEO_DB_BASE_GROUP = (0x00400000 | GEO_DB_GROUP);
|
||||
const uint GEO_DB_BASE_SURFACE = (0x00800000 | GEO_DB_SURFACE);
|
||||
const uint GEO_DB_EXTERNAL = (0x01000000 | GEO_DB_GROUP);
|
||||
const uint GEO_DB_INSTANCE = (0x04000000 | GEO_DB_GROUP);
|
||||
const uint GEO_DB_LIGHTPT = (0x08000000 | GEO_DB_POLYGON);
|
||||
|
||||
// older version types for Compatability & convenience
|
||||
//
|
||||
const uint GEO_DB_ALL = GEO_DB_BASE;
|
||||
const uint GEO_DB_ALL_GROUP_TYPES = GEO_DB_GROUP;
|
||||
const uint GEO_DB_ALL_SURFACE_TYPES = GEO_DB_SURFACE;
|
||||
const uint GEO_DB_ALL_SHAPE_TYPES = GEO_DB_PARAMETRIC_SURFACE;
|
||||
const uint GEO_DB_ALL_GEOMETRY_TYPES = GEO_DB_GEOMETRY;
|
||||
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/** constants to identify the type of picking to be done */
|
||||
const uint GEO_PICK_GROUP = 0x00000001;
|
||||
const uint GEO_PICK_PRIM = 0x00000002;
|
||||
const uint GEO_PICK_VERTEX = 0x00000004;
|
||||
const uint GEO_PICK_EDGE = 0x00000008; // Future
|
||||
const uint GEO_PICK_GRID = 0x00000010;
|
||||
const uint GEO_PICK_NON_NODE = 0x00000020; // manipulators, user geometry etc.
|
||||
const uint GEO_PICK_EXTERNAL = 0x00000040;
|
||||
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/** constants to identify mouse button usage */
|
||||
const uint GEO_NO_MOUSE = 0x00000000;
|
||||
const uint GEO_LEFT_MOUSE = 0x00000001;
|
||||
const uint GEO_MIDDLE_MOUSE = 0x00000002;
|
||||
const uint GEO_RIGHT_MOUSE = 0x00000004;
|
||||
const uint GEO_LEFT_AND_RIGHT_MOUSE = 0x00000008;
|
||||
const uint GEO_MIDDLE_AND_RIGHT_MOUSE = 0x00000010;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/** Predefined model unit identifier. database model units can be modified
|
||||
* via set/getUnits
|
||||
*/
|
||||
const uint GEO_DB_INCHES = 1;
|
||||
const uint GEO_DB_FEET = 2;
|
||||
const uint GEO_DB_YARDS = 3;
|
||||
const uint GEO_DB_MILES = 4;
|
||||
const uint GEO_DB_CENTIMETERS = 5;
|
||||
const uint GEO_DB_METERS = 6;
|
||||
const uint GEO_DB_KILOMETERS = 7;
|
||||
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/** Constants to define the modeler's intended "up" direction if that
|
||||
* makes any sense
|
||||
*/
|
||||
|
||||
const int GEO_DB_UP_AXIS_X = 1;
|
||||
const int GEO_DB_UP_AXIS_Y = 2; // the default
|
||||
const int GEO_DB_UP_AXIS_Z = 3;
|
||||
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/** Constants to control the drawing effect
|
||||
*
|
||||
* Constants to control the drawing of geometry primitives - usefull if user
|
||||
* wants to call standard draw method in a tool postDraw callback
|
||||
*/
|
||||
const uint GEO_DB_SOLID = 0x00000001;
|
||||
const uint GEO_DB_WIRE = 0x00000002;
|
||||
const uint GEO_DB_OUTLINED = 0x00000008;
|
||||
|
||||
const uint GEO_DB_ZBUFFER = 0x00000100;
|
||||
const uint GEO_DB_BACKFACE = 0x00000400;
|
||||
|
||||
const uint GEO_DB_DRAW_FACE_NORMALS = 0x00001000;
|
||||
const uint GEO_DB_DRAW_VERTEX_NORMALS = 0x00002000;
|
||||
|
||||
const uint GEO_DB_TEXTURE = 0x00010000;
|
||||
const uint GEO_DB_HIGHLIGHT = 0x00020000;
|
||||
const uint GEO_DB_PICKING = 0x00040000;
|
||||
const uint GEO_DB_HIGHLIGHT_DASHED = 0x00080000;
|
||||
|
||||
const uint GEO_DB_ILLUMINATED = 0x01000000;
|
||||
const uint GEO_DB_NORMAL_PER_PRIM = 0x04000000;
|
||||
const uint GEO_DB_NORMAL_PER_VERTEX = 0x08000000;
|
||||
|
||||
const uint GEO_DB_COLOR_PER_GEODE = 0x10000000;
|
||||
const uint GEO_DB_COLOR_PER_PRIM = 0x20000000;
|
||||
const uint GEO_DB_COLOR_PER_VERTEX = 0x40000000;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/** Constants to control the switch Node behavior
|
||||
*
|
||||
* Switch Nodes can either be addative (in which case the
|
||||
* accumulate drawable children) or selective (in which case
|
||||
* the determine which of their children should be drawn).
|
||||
*
|
||||
* Selctive control is not implemented.
|
||||
*/
|
||||
const uint GEO_SWITCH_TYPE_ADDATIVE = 1;
|
||||
const uint GEO_SWITCH_TYPE_SELECTIVE = 2;
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/** Type Tokens for Node & Tool Gui Widgets */
|
||||
const int GUI_FLOAT = 1;
|
||||
const int GUI_INT = 2;
|
||||
const int GUI_STRING = 3;
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/** geoWidget Typedef - Used by Node & Tool Gui Widgets */
|
||||
typedef void geoWidget;
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/** Animated String padding tokens */
|
||||
const int GEO_TEXT_PAD_NONE = 0;
|
||||
const int GEO_TEXT_PAD_WITH_SPACES = 1;
|
||||
const int GEO_TEXT_PAD_WITH_ZEROES = 2;
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Polygon draw style types
|
||||
//
|
||||
const int GEO_POLY_DSTYLE_SOLID = 0;
|
||||
const int GEO_POLY_DSTYLE_OPEN_WIRE = 1;
|
||||
const int GEO_POLY_DSTYLE_CLOSED_WIRE = 2;
|
||||
const int GEO_POLY_DSTYLE_POINTS = 3;
|
||||
const int GEO_POLY_DSTYLE_SOLID_BOTH_SIDES = 4;
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Polygon shade style types
|
||||
//
|
||||
|
||||
const int GEO_POLY_SHADEMODEL_FLAT = 0;
|
||||
const int GEO_POLY_SHADEMODEL_GOURAUD = 1;
|
||||
const int GEO_POLY_SHADEMODEL_LIT = 2;
|
||||
const int GEO_POLY_SHADEMODEL_LIT_GOURAUD = 3;
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Texture Mapping types
|
||||
//
|
||||
|
||||
const int GEO_POLY_PLANAR_MAP = 0;
|
||||
const int GEO_POLY_CYLINDRICAL_MAP = 1;
|
||||
const int GEO_POLY_SPHERICAL_MAP = 2;
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// STring type constants
|
||||
//
|
||||
const int GEO_TEXT_RASTER = 0;
|
||||
const int GEO_TEXT_STROKE = 1;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Justification constants
|
||||
//
|
||||
const int GEO_TEXT_LEFT_JUSTIFY = 0;
|
||||
const int GEO_TEXT_CENTER_JUSTIFY = 1;
|
||||
const int GEO_TEXT_RIGHT_JUSTIFY = 2;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Direction constants
|
||||
//
|
||||
const int GEO_TEXT_LEFT_TO_RIGHT = 0;
|
||||
const int GEO_TEXT_RIGHT_TO_LEFT = 1;
|
||||
const int GEO_TEXT_TOP_TO_BOTTOM = 2;
|
||||
const int GEO_TEXT_BOTTOM_TO_TOP = 3;
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// LightPoint Type constants
|
||||
//
|
||||
const int GEO_DB_LIGHTPT_OMNI_DIRECTIONAL = 0;
|
||||
const int GEO_DB_LIGHTPT_UNI_DIRECTIONAL = 1;
|
||||
const int GEO_DB_LIGHTPT_BI_DIRECTIONAL = 2;
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Texture Record Wrap S & T Modes
|
||||
const unsigned GEO_DB_TEX_CLAMP = 0x00000001;
|
||||
const unsigned GEO_DB_TEX_REPEAT = 0x00000002;
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Texture Record MagFilter
|
||||
const unsigned GEO_DB_TEX_NEAREST = 0x00000001;
|
||||
const unsigned GEO_DB_TEX_LINEAR = 0x00000002;
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Texture Record MinFilter
|
||||
const unsigned GEO_DB_TEX_NEAREST_MIPMAP_NEAREST = 0x00000004;
|
||||
const unsigned GEO_DB_TEX_LINEAR_MIPMAP_NEAREST = 0x00000008;
|
||||
const unsigned GEO_DB_TEX_NEAREST_MIPMAP_LINEAR = 0x00000010;
|
||||
const unsigned GEO_DB_TEX_LINEAR_MIPMAP_LINEAR = 0x00000020;
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Texture Record TexEnv
|
||||
const unsigned GEO_DB_TEX_MODULATE = 0x00000001;
|
||||
const unsigned GEO_DB_TEX_DECAL = 0x00000002;
|
||||
const unsigned GEO_DB_TEX_BLEND = 0x00000004;
|
||||
|
||||
|
||||
|
||||
#endif //_GEO_TYPES_H_
|
||||
|
||||
74
src/osgPlugins/geo/geoUnits.h
Normal file
74
src/osgPlugins/geo/geoUnits.h
Normal file
@@ -0,0 +1,74 @@
|
||||
/*===========================================================================*\
|
||||
|
||||
NAME: geoUnits.h
|
||||
|
||||
DESCRIPTION: Constants to convert coordinate data to/from meters (Geo
|
||||
default)
|
||||
|
||||
AUTHOR: Andy Bushnell
|
||||
|
||||
-------------------------------------------------------------------------
|
||||
|
||||
PROPRIETARY RIGHTS NOTICE:
|
||||
|
||||
This software contains proprietary information and trade secrets of Carbon
|
||||
Graphics LLC. No part or all of this software may be reproduced in any form,
|
||||
without the written permission of Carbon Graphics LLC.
|
||||
|
||||
Exception:
|
||||
This Software file can be used by third-party software developers (without
|
||||
using the Geo SDK libraries) for any purpose OTHER THAN loading Geo format
|
||||
files into an application or executable (such as, though not limited to,
|
||||
geometry Modelers & animation systems) which is primarily intended to allow for
|
||||
the CREATION or MODIFICATION of geometric or animation data.
|
||||
|
||||
Specifically,using this software (either all or part thereof) to aid in the
|
||||
creation of a Geo format loader for a run-time system, game engine, toolkit
|
||||
IG (Image Generation) System or any software where the PRIMARY purpose is
|
||||
real-time image playback and interactivity and not Model Creation and/or
|
||||
modification is permitted.
|
||||
|
||||
COPYRIGHT NOTICE:
|
||||
|
||||
Copyright <20> 1998-2001 Carbon Graphics Llc, ALL RIGHTS RESERVED
|
||||
|
||||
\*===========================================================================*/
|
||||
|
||||
|
||||
|
||||
#ifndef _GEO_UNITS_H_
|
||||
#define _GEO_UNITS_H_
|
||||
|
||||
|
||||
const float KM_TO_METERS = 1000.0f;
|
||||
const float CM_TO_METERS = 0.01f;
|
||||
const float MM_TO_METERS = 0.001f;
|
||||
const float NM_TO_METERS = 1852.0f;
|
||||
const float MILES_TO_METERS = 1609.344f;
|
||||
const float YARDS_TO_METERS = 0.9144f;
|
||||
const float FEET_TO_METERS = 0.3048f;
|
||||
const float INCHES_TO_METERS= 0.0254f;
|
||||
|
||||
const float METERS_TO_KM = 0.001f;
|
||||
const float METERS_TO_CM = 100.0f;
|
||||
const float METERS_TO_MM = 1000.0f;
|
||||
const float METERS_TO_NM = 0.0005399568035f;
|
||||
const float METERS_TO_MILES = 0.0006213711922f;
|
||||
const float METERS_TO_YARDS = 1.093613298f;
|
||||
const float METERS_TO_FEET = 3.280839895f;
|
||||
const float METERS_TO_INCHES= 39.37007874f;
|
||||
|
||||
const float CM_TO_FEET = 0.03280839895f;
|
||||
const float CM_TO_INCHES = 0.3937007874f;
|
||||
const float FEET_TO_YARDS = 0.333333333f;
|
||||
const float FEET_TO_CM = 30.48f;
|
||||
const float FEET_TO_INCHES = 12.0f;
|
||||
const float INCHES_TO_FEET = 0.083333333f;
|
||||
const float INCHES_TO_CM = 2.54f;
|
||||
|
||||
const float MPH_TO_FPS = 1.4667f;
|
||||
const float MPH_TO_MPS = 0.447f;
|
||||
|
||||
|
||||
|
||||
#endif //_GEO_UNITS_H_
|
||||
466
src/osgPlugins/geo/osgGeoStructs.h
Normal file
466
src/osgPlugins/geo/osgGeoStructs.h
Normal file
@@ -0,0 +1,466 @@
|
||||
/*===========================================================================*\
|
||||
|
||||
NAME: osgGeoStructs.h
|
||||
|
||||
DESCRIPTION: OSG data format for reading a Geo file into OSG
|
||||
|
||||
AUTHOR: Geoff Michel
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
|
||||
\ *===========================================================================*/
|
||||
|
||||
|
||||
|
||||
#ifndef _GEO_STRUCTS_H_
|
||||
#define _GEO_STRUCTS_H_
|
||||
|
||||
class geoField { // holds one field of data as read from the disk of a GEO file
|
||||
public:
|
||||
geoField() {
|
||||
tokenId=TypeId=0; numItems=0;storeSize=0;
|
||||
}
|
||||
|
||||
unsigned char *readStorage(std::ifstream &fin, const unsigned sz) {
|
||||
unsigned char *st=new unsigned char[numItems*sz];
|
||||
storeSize=sz;
|
||||
fin.read((char *)st, sz*numItems);
|
||||
return st;
|
||||
}
|
||||
void storageRead(std::ifstream &fin) {
|
||||
switch (TypeId) {
|
||||
case DB_CHAR:
|
||||
storage=readStorage(fin,SIZEOF_CHAR);
|
||||
break;
|
||||
case DB_SHORT:
|
||||
storage=readStorage(fin,SIZEOF_SHORT);
|
||||
break;
|
||||
case DB_INT:
|
||||
storage=readStorage(fin,SIZEOF_INT);
|
||||
break;
|
||||
case DB_FLOAT:
|
||||
storage=readStorage(fin,SIZEOF_FLOAT);
|
||||
break;
|
||||
case DB_LONG:
|
||||
storage=readStorage(fin,SIZEOF_LONG);
|
||||
break;
|
||||
case DB_ULONG:
|
||||
storage=readStorage(fin,SIZEOF_ULONG);
|
||||
break;
|
||||
case DB_DOUBLE:
|
||||
storage=readStorage(fin,SIZEOF_DOUBLE);
|
||||
break;
|
||||
case DB_VEC2F:
|
||||
storage=readStorage(fin,SIZEOF_VEC2F);
|
||||
break;
|
||||
case DB_VEC3F:
|
||||
storage=readStorage(fin,SIZEOF_VEC3F);
|
||||
break;
|
||||
case DB_VEC4F:
|
||||
storage=readStorage(fin,SIZEOF_VEC4F);
|
||||
break;
|
||||
case DB_VEC16F:
|
||||
storage=readStorage(fin,SIZEOF_VEC16F);
|
||||
break;
|
||||
case DB_VEC2I:
|
||||
storage=readStorage(fin,SIZEOF_VEC2I);
|
||||
break;
|
||||
case DB_VEC3I:
|
||||
storage=readStorage(fin,SIZEOF_VEC3I);
|
||||
break;
|
||||
case DB_VEC4I:
|
||||
storage=readStorage(fin,SIZEOF_VEC4I);
|
||||
break;
|
||||
case DB_VEC2D:
|
||||
storage=readStorage(fin,SIZEOF_VEC2D);
|
||||
break;
|
||||
case DB_VEC3D:
|
||||
storage=readStorage(fin,SIZEOF_VEC3D);
|
||||
break;
|
||||
case DB_VEC4D:
|
||||
storage=readStorage(fin,SIZEOF_VEC4D);
|
||||
break;
|
||||
case DB_VEC16D:
|
||||
storage=readStorage(fin,SIZEOF_VEC16D);
|
||||
break;
|
||||
case DB_VRTX_STRUCT:
|
||||
storage=readStorage(fin,SIZEOF_VRTX_STRUCT);
|
||||
break;
|
||||
case DB_UINT:
|
||||
storage=readStorage(fin,SIZEOF_UINT);
|
||||
break;
|
||||
case DB_USHORT:
|
||||
storage=readStorage(fin,SIZEOF_USHORT);
|
||||
break;
|
||||
case DB_UCHAR:
|
||||
storage=readStorage(fin,SIZEOF_UCHAR);
|
||||
break;
|
||||
case DB_EXT_STRUCT:
|
||||
storage=readStorage(fin,SIZEOF_EXT_STRUCT);
|
||||
break;
|
||||
case DB_SHORT_WITH_PADDING:
|
||||
storage=readStorage(fin,SIZEOF_ULONG);
|
||||
break;
|
||||
case DB_CHAR_WITH_PADDING:
|
||||
storage=readStorage(fin,SIZEOF_CHAR_WITH_PADDING);
|
||||
break;
|
||||
case DB_USHORT_WITH_PADDING:
|
||||
storage=readStorage(fin,SIZEOF_USHORT_WITH_PADDING);
|
||||
break;
|
||||
case DB_UCHAR_WITH_PADDING:
|
||||
storage=readStorage(fin,SIZEOF_UCHAR_WITH_PADDING);
|
||||
break;
|
||||
case DB_BOOL_WITH_PADDING:
|
||||
storage=readStorage(fin,SIZEOF_BOOL_WITH_PADDING);
|
||||
break;
|
||||
case DB_EXTENDED_FIELD_STRUCT:
|
||||
storage=readStorage(fin,SIZEOF_EXTENDED_FIELD_STRUCT);
|
||||
break;
|
||||
case DB_VEC4UC:
|
||||
storage=readStorage(fin,SIZEOF_VEC4UC);
|
||||
break;
|
||||
case DB_DISCRETE_MAPPING_STRUCT:
|
||||
storage=readStorage(fin,SIZEOF_DISCRETE_MAPPING_STRUCT);
|
||||
break;
|
||||
case DB_BITFLAGS:
|
||||
storage=readStorage(fin,SIZEOF_BITFLAGS);
|
||||
break;
|
||||
}
|
||||
}
|
||||
void readfile(std::ifstream &fin) {
|
||||
osg::uchar tokid, type;
|
||||
osg::ushort nits;
|
||||
if (!fin.eof()) {
|
||||
fin.read((char *)&tokid,1);fin.read((char *)&type,1);
|
||||
fin.read((char *)&nits,sizeof(unsigned short));
|
||||
if (TypeId == GEO_DB_EXTENDED_FIELD) {
|
||||
fin.read((char *)&tokenId,sizeof(tokenId));fin.read((char *)&TypeId,sizeof(TypeId));
|
||||
fin.read((char *)&numItems,sizeof(unsigned int));
|
||||
} else {
|
||||
tokenId=tokid; TypeId=type;
|
||||
numItems=nits;
|
||||
}
|
||||
storageRead(fin); // allocate & fill the storage
|
||||
}
|
||||
}
|
||||
inline osg::uchar getToken() const { return tokenId;}
|
||||
inline osg::uchar getType() const { return TypeId;}
|
||||
inline unsigned short getNum() const { return numItems;}
|
||||
inline unsigned char *getstore (unsigned int i) const {
|
||||
return storage+i*storeSize;
|
||||
}
|
||||
void uncompress() { // folow the recipe to uncompress
|
||||
if (TypeId==DB_VEC3F) { // already uncompressed
|
||||
} else {
|
||||
float *norms=new float[numItems*SIZEOF_VEC3F]; // uncompressed size
|
||||
for (uint i=0; i<numItems; i++) {
|
||||
switch (TypeId) {
|
||||
case DB_UINT:
|
||||
norms[3*i]=storage[4*i+1]/255.0f;
|
||||
norms[3*i+1]=storage[4*i+2]/255.0f;
|
||||
norms[3*i+2]=storage[4*i+3]/255.0f;
|
||||
if (storage[4*i] & 0x01) norms[3*i] *= -1;
|
||||
if (storage[4*i] & 0x02) norms[3*i+1] *= -1;
|
||||
if (storage[4*i] & 0x04) norms[3*i+2] *= -1;
|
||||
break;
|
||||
case DB_SHORT:
|
||||
norms[3*i]=(storage[6*i]*255+storage[6*i+1])/32767.0f;
|
||||
norms[3*i+1]=(storage[6*i+2]*255+storage[6*i+3])/32767.0f;
|
||||
norms[3*i+2]=(storage[6*i+4]*255+storage[6*i+5])/32767.0f;
|
||||
break;
|
||||
case DB_CHAR:
|
||||
norms[3*i]=storage[3*i]/127.0f;
|
||||
norms[3*i+1]=storage[3*i+1]/127.0f;
|
||||
norms[3*i+2]=storage[3*i+2]/127.0f;
|
||||
break;
|
||||
}
|
||||
}
|
||||
delete [] storage;
|
||||
TypeId=DB_VEC3F;
|
||||
storage=(unsigned char *)norms;
|
||||
}
|
||||
}
|
||||
void warn(const char *type, unsigned tval) const { if (getType() != tval)
|
||||
osg::notify(osg::WARN) << "Wrong type " << type <<" expecting "<< getType() << std::endl;}
|
||||
unsigned int getUInt() const {warn("getUInt",DB_UINT); return *((unsigned int*)storage);} // return int value
|
||||
char *getChar() const {warn("getChar",DB_CHAR); return (char *)storage;} // return chars, eg for name or file name
|
||||
int getInt() const {warn("getInt", DB_INT); return *((int*)storage);} // return int value
|
||||
float getFloat() const {warn("getFloat", DB_FLOAT); return (*(float *)storage); }
|
||||
float *getFloatArr() const {warn("getFloatArr", DB_FLOAT); return ( (float *)storage); }
|
||||
float *getVec3Arr() const {warn("getVec3Arr", DB_VEC3F); return ( (float *)storage); }
|
||||
float *getMat44Arr() const {warn("getMat44Arr", DB_VEC16F); return ( (float *)storage); }
|
||||
double getDouble() const {warn("getDouble", DB_DOUBLE); return (*(double *)storage); }
|
||||
friend inline std::ostream& operator << (std::ostream& output, const geoField& gf)
|
||||
{
|
||||
if (gf.tokenId!=GEO_DB_LAST_FIELD) {
|
||||
output << " Field:token " << (int)gf.tokenId << " type " << (int)gf.TypeId
|
||||
<< " num its " << gf.numItems << " size " << gf.storeSize << std::endl;
|
||||
for (uint i=0; i<gf.numItems; i++) {
|
||||
int j,k;
|
||||
union {
|
||||
unsigned char *uch;
|
||||
char *ch;
|
||||
float *ft;
|
||||
int *in;
|
||||
uint *uin;
|
||||
short *sh;
|
||||
osg::ushort *ush;
|
||||
long *ln;
|
||||
unsigned long *uln;
|
||||
double *dbl;
|
||||
} st;
|
||||
st.uch=gf.storage+i*gf.storeSize;
|
||||
switch (gf.TypeId) {
|
||||
case DB_CHAR:
|
||||
if (st.ch[0]) output << st.ch[0];
|
||||
break;
|
||||
case DB_SHORT:
|
||||
output << st.sh[0] << std::endl;
|
||||
break;
|
||||
case DB_INT:
|
||||
output << st.in[0] << std::endl;
|
||||
break;
|
||||
case DB_FLOAT:
|
||||
output << st.ft[0] << std::endl;
|
||||
break;
|
||||
case DB_LONG:
|
||||
output << st.ln[0] << std::endl;
|
||||
break;
|
||||
case DB_ULONG:
|
||||
output << st.uln[0] << std::endl;
|
||||
break;
|
||||
case DB_DOUBLE:
|
||||
output << st.dbl[0] << std::endl;
|
||||
break;
|
||||
case DB_VEC2F:
|
||||
for (j=0; j<2; j++) output << st.ft[j] << " ";
|
||||
output << std::endl;
|
||||
break;
|
||||
case DB_VEC3F:
|
||||
for (j=0; j<3; j++) output << st.ft[j] << " ";
|
||||
output << std::endl;
|
||||
break;
|
||||
case DB_VEC4F:
|
||||
for (j=0; j<4; j++) output << st.ft[j] << " ";
|
||||
output << std::endl;
|
||||
break;
|
||||
case DB_VEC16F:
|
||||
for (j=0; j<4; j++) {
|
||||
for (k=0; k<4; k++) output << st.ch[j*4+k] << " ";
|
||||
output << std::endl;
|
||||
}
|
||||
break;
|
||||
case DB_VEC2I:
|
||||
for (j=0; j<2; j++) output << st.in[j] << " ";
|
||||
output << std::endl;
|
||||
break;
|
||||
case DB_VEC3I:
|
||||
for ( j=0; j<3; j++) output << st.in[j] << " ";
|
||||
output << std::endl;
|
||||
break;
|
||||
case DB_VEC4I:
|
||||
for ( j=0; j<4; j++) output << st.in[j] << " ";
|
||||
output << std::endl;
|
||||
break;
|
||||
case DB_VEC2D:
|
||||
for ( j=0; j<2; j++) output << st.dbl[j] << " ";
|
||||
output << std::endl;
|
||||
break;
|
||||
case DB_VEC3D:
|
||||
for ( j=0; j<3; j++) output << st.dbl[j] << " ";
|
||||
output << std::endl;
|
||||
break;
|
||||
case DB_VEC4D:
|
||||
for ( j=0; j<4; j++) output << st.dbl[j] << " ";
|
||||
output << std::endl;
|
||||
break;
|
||||
case DB_VEC16D:
|
||||
for (j=0; j<4; j++) {
|
||||
for (k=0; k<4; k++) output << st.dbl[j*4+k] << " ";
|
||||
output << std::endl;
|
||||
}
|
||||
break;
|
||||
case DB_VRTX_STRUCT:
|
||||
output << st.ch[0] << std::endl;
|
||||
break;
|
||||
case DB_UINT:
|
||||
output << st.uin[0] << std::endl;
|
||||
break;
|
||||
case DB_USHORT:
|
||||
output << st.ush[0] << std::endl;
|
||||
break;
|
||||
case DB_UCHAR:
|
||||
output << (int)st.ch[0] << std::endl;
|
||||
break;
|
||||
case DB_EXT_STRUCT:
|
||||
output << st.ch[0] << std::endl;
|
||||
break;
|
||||
case DB_SHORT_WITH_PADDING:
|
||||
output << st.ch[0] << std::endl;
|
||||
break;
|
||||
case DB_CHAR_WITH_PADDING:
|
||||
output << st.ch[0] << std::endl;
|
||||
break;
|
||||
case DB_USHORT_WITH_PADDING:
|
||||
output << st.ch[0] << std::endl;
|
||||
break;
|
||||
case DB_UCHAR_WITH_PADDING:
|
||||
output << (int)st.ch[0] << std::endl;
|
||||
break;
|
||||
case DB_BOOL_WITH_PADDING:
|
||||
output << st.ch[0] << std::endl;
|
||||
break;
|
||||
case DB_EXTENDED_FIELD_STRUCT:
|
||||
output << st.ch[0] << std::endl;
|
||||
break;
|
||||
case DB_VEC4UC:
|
||||
for ( j=0; j<4; j++) output << (int)st.uch[j] << " ";
|
||||
output << std::endl;
|
||||
break;
|
||||
case DB_DISCRETE_MAPPING_STRUCT:
|
||||
output << st.ch[i] << std::endl;
|
||||
break;
|
||||
case DB_BITFLAGS:
|
||||
output << st.ch[i] << std::endl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return output; // to enable cascading, monkey copy from osg\plane or \quat, Ubyte4, vec2,3,4,...
|
||||
}
|
||||
private:
|
||||
osg::ushort tokenId, TypeId; // these are longer than standard field; are extended field length
|
||||
uint numItems;
|
||||
unsigned char *storage; // data relating
|
||||
uint storeSize; // size*numItems in storage
|
||||
};
|
||||
|
||||
class georecord { // holds a single record with a vector of geoFields as read from disk
|
||||
public:
|
||||
typedef std::vector< geoField > geoFieldList;
|
||||
georecord() {id=0; parent=NULL; instance=NULL;}
|
||||
~georecord() {;}
|
||||
inline int getType(void) const {return id;}
|
||||
inline void setparent(georecord *p) { parent=p;}
|
||||
inline class georecord *getparent() { return parent;}
|
||||
inline std::vector<georecord *> getchildren(void) { return children;}
|
||||
void addchild(class georecord *gr) { children.push_back(gr);}
|
||||
void readfile(std::ifstream &fin) {
|
||||
if (!fin.eof()) {
|
||||
fin.read((char *)&id,sizeof(int));
|
||||
if (id==DB_DSK_PUSH) {
|
||||
// there are no fields for a push
|
||||
} else if (id==DB_DSK_POP) {
|
||||
// there are no fields for a pop
|
||||
} else { // get the fields
|
||||
geoField gf;
|
||||
do {
|
||||
gf.readfile(fin);
|
||||
if (id == DB_DSK_NORMAL_POOL && gf.getToken()==GEO_DB_NORMAL_POOL_VALUES) {
|
||||
// uncompress the normals
|
||||
gf.uncompress();
|
||||
}
|
||||
fields.push_back(gf);
|
||||
} while (gf.getToken()!=GEO_DB_LAST_FIELD);
|
||||
}
|
||||
}
|
||||
}
|
||||
friend inline std::ostream& operator << (std::ostream& output, const georecord& gr)
|
||||
{
|
||||
if (gr.id == DB_DSK_PUSH) output << "Push" << std::endl;
|
||||
else if (gr.id == DB_DSK_POP) output << "Pop" << std::endl;
|
||||
else if (gr.id == DB_DSK_HEADER) output << "Header" << std::endl;
|
||||
else if (gr.id == DB_DSK_GROUP) output << "Group" << std::endl;
|
||||
else if (gr.id == DB_DSK_BILLBOARD) output << "Billboard" << std::endl;
|
||||
else if (gr.id == DB_DSK_SEQUENCE) output << "Sequence" << std::endl;
|
||||
else if (gr.id == DB_DSK_LOD) output << "LOD" << std::endl;
|
||||
else if (gr.id == DB_DSK_GEODE) output << "Geode" << std::endl;
|
||||
else if (gr.id == DB_DSK_POLYGON) output << "Polygon" << std::endl;
|
||||
else if (gr.id == DB_DSK_MESH) output << "Mesh" << std::endl;
|
||||
else if (gr.id == DB_DSK_CUBE) output << "Cube" << std::endl;
|
||||
else if (gr.id == DB_DSK_SPHERE) output << "Sphere" << std::endl;
|
||||
else if (gr.id == DB_DSK_CONE) output << "Cone" << std::endl;
|
||||
else if (gr.id == DB_DSK_CYLINDER) output << "Cylinder" << std::endl;
|
||||
else if (gr.id == DB_DSK_VERTEX) output << "Vertex" << std::endl;
|
||||
else if (gr.id == DB_DSK_TEXTURE) output << "Texture" << std::endl;
|
||||
else if (gr.id == DB_DSK_MATERIAL) output << "Material" << std::endl;
|
||||
else if (gr.id == DB_DSK_VIEW) output << "View" << std::endl;
|
||||
else if (gr.id == DB_DSK_EXTENSION_LIST) output << "Extensions" << std::endl;
|
||||
else if (gr.id == DB_DSK_COORD_POOL) output << "Coords" << std::endl;
|
||||
else if (gr.id == DB_DSK_NORMAL_POOL) output << "Normals" << std::endl;
|
||||
else if (gr.id == DB_DSK_SWITCH) output << "Switch" << std::endl;
|
||||
else if (gr.id == DB_DSK_TEXT) output << "Text" << std::endl;
|
||||
else if (gr.id == DB_DSK_BASE_GROUP) output << "Base group" << std::endl;
|
||||
else if (gr.id == DB_DSK_BASE_SURFACE) output << "Base Surface" << std::endl;
|
||||
else if (gr.id == DB_DSK_INSTANCE) output << "Instance" << std::endl;
|
||||
else if (gr.id == DB_DSK_LIGHTPT) output << "Light Point" << std::endl;
|
||||
else if (gr.id == DB_DSK_EXTERNAL) output << "External" << std::endl;
|
||||
else if (gr.id == DB_DSK_PAGE) output << "Page" << std::endl;
|
||||
else if (gr.id == DB_DSK_COLOR_PALETTE) output << "Colour palette" << std::endl;
|
||||
else output << " inp record " << gr.id << std::endl;
|
||||
|
||||
for (geoFieldList::const_iterator itr=gr.fields.begin();
|
||||
itr!=gr.fields.end();
|
||||
++itr)
|
||||
{
|
||||
output << *itr << std::endl;
|
||||
}
|
||||
return output; // to enable cascading, monkey copy from osg\plane or \quat, Ubyte4, vec2,3,4,...
|
||||
}
|
||||
/* const char *getCharField(const int fieldid) const {
|
||||
const geoField *gfd=getField(fieldid);
|
||||
if (gfd) return (char *)gfd->getstore(0);
|
||||
return NULL;
|
||||
} */
|
||||
const geoField *getField(const int fieldid) const { // return field if it exists.
|
||||
for (geoFieldList::const_iterator itr=fields.begin();
|
||||
itr!=fields.end();
|
||||
++itr)
|
||||
{
|
||||
if (itr->getToken()==fieldid) return itr;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
void setMaterial(osg::Material *mt) const {
|
||||
if (id == DB_DSK_MATERIAL) {
|
||||
for (geoFieldList::const_iterator itr=fields.begin();
|
||||
itr!=fields.end();
|
||||
++itr)
|
||||
{
|
||||
float *fval;
|
||||
if (itr->getToken()==GEO_DB_MAT_AMBIENT) {
|
||||
fval= (float *)(*itr).getstore(0);
|
||||
mt->setAmbient(osg::Material::FRONT_AND_BACK, osg::Vec4(fval[0],fval[1],fval[2],fval[3]));
|
||||
}
|
||||
if (itr->getToken()==GEO_DB_MAT_DIFFUSE) {
|
||||
fval= (float *)(*itr).getstore(0);
|
||||
mt->setDiffuse(osg::Material::FRONT_AND_BACK, osg::Vec4(fval[0],fval[1],fval[2],fval[3]));
|
||||
}
|
||||
if (itr->getToken()==GEO_DB_MAT_SPECULAR) {
|
||||
fval= (float *)(*itr).getstore(0);
|
||||
mt->setSpecular(osg::Material::FRONT_AND_BACK, osg::Vec4(fval[0],fval[1],fval[2],fval[3]));
|
||||
}
|
||||
if (itr->getToken()==GEO_DB_MAT_EMISSIVE) {
|
||||
fval= (float *)(*itr).getstore(0);
|
||||
mt->setEmission(osg::Material::FRONT_AND_BACK, osg::Vec4(fval[0],fval[1],fval[2],fval[3]));
|
||||
}
|
||||
if (itr->getToken()==GEO_DB_MAT_SHININESS) {
|
||||
fval= (float *)(*itr).getstore(0);
|
||||
mt->setShininess(osg::Material::FRONT_AND_BACK, fval[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
private:
|
||||
int id;
|
||||
std::vector<geoField> fields; // each geo record has a variable number of fields
|
||||
class georecord *parent; // parent of pushed/popped records
|
||||
class georecord *instance; // this record is an instance of the pointed to record
|
||||
std::vector< georecord *> children; // children of this record
|
||||
};
|
||||
|
||||
|
||||
typedef std::vector< georecord > geoRecordList;
|
||||
|
||||
#endif //_GEO_STRUCTS_H_
|
||||
Reference in New Issue
Block a user