Initial revision

This commit is contained in:
Don BURNS
2001-01-10 16:32:10 +00:00
parent 7c12eb9361
commit 70208ebc06
461 changed files with 70936 additions and 0 deletions

32
src/osgPlugins/Makefile Normal file
View File

@@ -0,0 +1,32 @@
#!smake
SHELL=/bin/sh
#DIRS = fly flt png
#DIRS = fly flt pic png jpeg tga tiff gif png
DIRS = fly osgtgz tgz zip flt pfb pic png jpeg tga tiff gif png
all :
for f in $(DIRS) ; do cd $$f; make ; cd ..; done
clean :
for f in $(DIRS) ; do cd $$f; make clean; cd ..; done
clobber :
for f in $(DIRS) ; do cd $$f; make clobber; cd ..; done
depend :
for f in $(DIRS) ; do cd $$f; make depend; cd ..; done
to_unix :
for f in $(DIRS) ; do cd $$f; to_unix Makefile Makefile; cd ..; done
for f in $(DIRS) ; do cd $$f; make to_unix; cd ..; done
install :
for f in $(DIRS) ; do cd $$f; make install; cd ..; done
instlinks :
for f in $(DIRS) ; do cd $$f; make instlinks; cd ..; done
instclean :
for f in $(DIRS) ; do cd $$f; make instclean; cd ..; done

View File

@@ -0,0 +1,136 @@
// BoundingVolumeRecords.cpp
#include "flt.h"
#include "Registry.h"
#include "BoundingVolumeRecords.h"
using namespace flt;
////////////////////////////////////////////////////////////////////
//
// BoundingBoxRecord
//
////////////////////////////////////////////////////////////////////
RegisterRecordProxy<BoundingBoxRecord> g_BoundingBoxProxy;
BoundingBoxRecord::BoundingBoxRecord()
{
}
// virtual
BoundingBoxRecord::~BoundingBoxRecord()
{
}
void BoundingBoxRecord::endian()
{
}
////////////////////////////////////////////////////////////////////
//
// BoundingSphereRecord
//
////////////////////////////////////////////////////////////////////
RegisterRecordProxy<BoundingSphereRecord> g_BoundingSphereProxy;
BoundingSphereRecord::BoundingSphereRecord()
{
}
// virtual
BoundingSphereRecord::~BoundingSphereRecord()
{
}
void BoundingSphereRecord::endian()
{
}
////////////////////////////////////////////////////////////////////
//
// BoundingCylinderRecord
//
////////////////////////////////////////////////////////////////////
RegisterRecordProxy<BoundingCylinderRecord> g_BoundingCylinderProxy;
BoundingCylinderRecord::BoundingCylinderRecord()
{
}
// virtual
BoundingCylinderRecord::~BoundingCylinderRecord()
{
}
void BoundingCylinderRecord::endian()
{
}
////////////////////////////////////////////////////////////////////
//
// BoundingVolumeCenterRecord
//
////////////////////////////////////////////////////////////////////
RegisterRecordProxy<BoundingVolumeCenterRecord> g_BoundingVolumeCenterProxy;
BoundingVolumeCenterRecord::BoundingVolumeCenterRecord()
{
}
// virtual
BoundingVolumeCenterRecord::~BoundingVolumeCenterRecord()
{
}
void BoundingVolumeCenterRecord::endian()
{
}
////////////////////////////////////////////////////////////////////
//
// BoundingVolumeOrientationRecord
//
////////////////////////////////////////////////////////////////////
RegisterRecordProxy<BoundingVolumeOrientationRecord> g_BoundingVolumeOrientationProxy;
BoundingVolumeOrientationRecord::BoundingVolumeOrientationRecord()
{
}
// virtual
BoundingVolumeOrientationRecord::~BoundingVolumeOrientationRecord()
{
}
void BoundingVolumeOrientationRecord::endian()
{
}

View File

@@ -0,0 +1,225 @@
// BoundingVolumeRecords.h
#ifndef __FLT_BOUNDING_VOLUME_RECORDS_H
#define __FLT_BOUNDING_VOLUME_RECORDS_H
#include "opcodes.h"
#include "Record.h"
#include "RecordVisitor.h"
namespace flt {
////////////////////////////////////////////////////////////////////
//
// BoundingBoxRecord
//
////////////////////////////////////////////////////////////////////
typedef struct BoundingBoxTag
{
SRecHeader RecHeader;
#if 0
Int 4 Reserved
Double 8 x coordinate of lowest corner
Double 8 y coordinate of lowest corner
Double 8 z coordinate of lowest corner
Double 8 x coordinate of highest corner
Double 8 y coordinate of highest corner
Double 8 z coordinate of highest corner
#endif
} SBoundingBox;
class BoundingBoxRecord : public AncillaryRecord
{
public:
BoundingBoxRecord();
virtual Record* clone() const { return new BoundingBoxRecord(); }
virtual const char* className() const { return "BoundingBoxRecord"; }
virtual int classOpcode() const { return BOUNDING_BOX_OP; }
virtual void accept(RecordVisitor& rv) { rv.apply(*this); }
// virtual void traverse(RecordVisitor& rv);
protected:
virtual ~BoundingBoxRecord();
virtual void endian();
};
////////////////////////////////////////////////////////////////////
//
// BoundingSphereRecord
//
////////////////////////////////////////////////////////////////////
typedef struct BoundingSphereTag
{
SRecHeader RecHeader;
#if 0
Unsigned Int 2 Length of the record
Int 4 Reserved
Double 8 Radius of the sphere
#endif
} SBoundingSphere;
class BoundingSphereRecord : public AncillaryRecord
{
public:
BoundingSphereRecord();
virtual Record* clone() const { return new BoundingSphereRecord(); }
virtual const char* className() const { return "BoundingSphereRecord"; }
virtual int classOpcode() const { return BOUNDING_SPHERE_OP; }
virtual void accept(RecordVisitor& rv) { rv.apply(*this); }
// virtual void traverse(RecordVisitor& rv);
protected:
virtual ~BoundingSphereRecord();
virtual void endian();
};
////////////////////////////////////////////////////////////////////
//
// BoundingCylinderRecord
//
////////////////////////////////////////////////////////////////////
typedef struct BoundingCylinderTag
{
SRecHeader RecHeader;
#if 0
Int 4 Reserved
Double 8 Radius of the cylinder base
Double 8 Height of the cylinder
#endif
} SBoundingCylinder;
class BoundingCylinderRecord : public AncillaryRecord
{
public:
BoundingCylinderRecord();
virtual Record* clone() const { return new BoundingCylinderRecord(); }
virtual const char* className() const { return "BoundingCylinderRecord"; }
virtual int classOpcode() const { return BOUNDING_CYLINDER_OP; }
virtual void accept(RecordVisitor& rv) { rv.apply(*this); }
// virtual void traverse(RecordVisitor& rv);
protected:
virtual ~BoundingCylinderRecord();
virtual void endian();
};
////////////////////////////////////////////////////////////////////
//
// BoundingVolumeCenterRecord
//
////////////////////////////////////////////////////////////////////
typedef struct BoundingVolumeCenterTag
{
SRecHeader RecHeader;
#if 0
Int 4 Reserved
Double 8 x coordinate of center
Double 8 y coordinate of center
Double 8 z coordinate of center
#endif
} SBoundingVolumeCenter;
class BoundingVolumeCenterRecord : public AncillaryRecord
{
public:
BoundingVolumeCenterRecord();
virtual Record* clone() const { return new BoundingVolumeCenterRecord(); }
virtual const char* className() const { return "BoundingVolumeCenterRecord"; }
virtual int classOpcode() const { return BOUNDING_VOLUME_CENTER_OP; }
virtual void accept(RecordVisitor& rv) { rv.apply(*this); }
// virtual void traverse(RecordVisitor& rv);
protected:
virtual ~BoundingVolumeCenterRecord();
virtual void endian();
};
////////////////////////////////////////////////////////////////////
//
// BoundingVolumeOrientationRecord
//
////////////////////////////////////////////////////////////////////
typedef struct BoundingVolumeOrientationTag
{
SRecHeader RecHeader;
#if 0
Int 2 Bounding Volume Orientation Opcode 109
Unsigned Int 2 Length of the record
Int 4 Reserved
Double 8 Yaw angle
Double 8 Pitch angle
Double 8 Roll angle
#endif
} SBoundingVolumeOrientation;
class BoundingVolumeOrientationRecord : public AncillaryRecord
{
public:
BoundingVolumeOrientationRecord();
virtual Record* clone() const { return new BoundingVolumeOrientationRecord(); }
virtual const char* className() const { return "BoundingVolumeOrientationRecord"; }
virtual int classOpcode() const { return BOUNDING_VOLUME_ORIENTATION_OP; }
virtual void accept(RecordVisitor& rv) { rv.apply(*this); }
// virtual void traverse(RecordVisitor& rv);
protected:
virtual ~BoundingVolumeOrientationRecord();
virtual void endian();
};
}; // end namespace flt
#endif

View File

@@ -0,0 +1,55 @@
// ColorPaletteRecord.cpp
#include "flt.h"
#include "Input.h"
#include "Registry.h"
#include "ColorPaletteRecord.h"
using namespace flt;
////////////////////////////////////////////////////////////////////
//
// MaterialPaletteRecord
//
////////////////////////////////////////////////////////////////////
RegisterRecordProxy<ColorPaletteRecord> g_ColorPaletteRecordProxy;
ColorPaletteRecord::ColorPaletteRecord()
{
}
// virtual
ColorPaletteRecord::~ColorPaletteRecord()
{
}
// virtual
void ColorPaletteRecord::endian()
{
SColorPalette* pSColor = (SColorPalette*)getData();
int nOffset = sizeof(SColorPalette);
if (nOffset < getSize())
{
int n = 0;
ENDIAN( pSColor->nNames );
while ((n++ < pSColor->nNames) && (nOffset < getSize()))
{
SColorName* pName = (SColorName*)((char*)getData())+nOffset;
ENDIAN( pName->swSize );
ENDIAN( pName->nIndex );
nOffset += pName->swSize;
};
}
}

View File

@@ -0,0 +1,62 @@
// ColorPaletteRecord.h
#ifndef __FLT_COLOR_PALETTE_RECORD_H
#define __FLT_COLOR_PALETTE_RECORD_H
#include "opcodes.h"
#include "Record.h"
#include "RecordVisitor.h"
namespace flt {
////////////////////////////////////////////////////////////////////
//
// ColorPaletteRecord
//
////////////////////////////////////////////////////////////////////
struct SColorName
{
uint16 swSize; // Length of color name entry
int16 Reserved1;
int16 nIndex; // Color entry index
int16 Reserved2;
char szName[1]; // Color name string (variable length, up to 80 bytes)
};
struct SColorPalette
{
SRecHeader RecHeader;
char szReserved[128]; // Reserved
color32 Colors[1024]; // Color 0 - 1023
int32 nNames;
// Followed by SColorName. SColorName is of valiable length!
};
class ColorPaletteRecord : public AncillaryRecord
{
public:
ColorPaletteRecord();
virtual Record* clone() const { return new ColorPaletteRecord(); }
virtual const char* className() const { return "ColorPaletteRecord"; }
virtual int classOpcode() const { return COLOR_PALETTE_OP; }
virtual void accept(RecordVisitor& rv) { rv.apply(*this); }
// virtual void traverse(RecordVisitor& rv);
SColorPalette* getData() const { return (SColorPalette*)_pData; }
protected:
virtual ~ColorPaletteRecord();
virtual void endian();
};
}; // end namespace flt
#endif // __FLT_COLOR_PALETTE_RECORD_H

View File

@@ -0,0 +1,37 @@
// CommentRecord.cpp
#include "flt.h"
#include "Registry.h"
#include "CommentRecord.h"
using namespace flt;
////////////////////////////////////////////////////////////////////
//
// CommentRecord
//
////////////////////////////////////////////////////////////////////
RegisterRecordProxy<CommentRecord> g_CommentRecordProxy;
CommentRecord::CommentRecord()
{
}
// virtual
CommentRecord::~CommentRecord()
{
}
// virtual
void CommentRecord::endian()
{
}

View File

@@ -0,0 +1,53 @@
// CommentRecord.h
#ifndef __FLT_COMMENT_RECORD_H
#define __FLT_COMMENT_RECORD_H
#include "opcodes.h"
#include "Record.h"
#include "RecordVisitor.h"
namespace flt {
////////////////////////////////////////////////////////////////////
//
// CommentRecord
//
////////////////////////////////////////////////////////////////////
typedef struct CommentTag
{
SRecHeader RecHeader;
// TODO
} SComment;
class CommentRecord : public AncillaryRecord
{
public:
CommentRecord();
virtual Record* clone() const { return new CommentRecord(); }
virtual const char* className() const { return "CommentRecord"; }
virtual int classOpcode() const { return COMMENT_OP; }
virtual void accept(RecordVisitor& rv) { rv.apply(*this); }
// virtual void traverse(RecordVisitor& rv);
protected:
virtual ~CommentRecord();
virtual void endian();
};
}; // end namespace flt
#endif

View File

@@ -0,0 +1,21 @@
// ControlRecord.cpp
#include "Registry.h"
#include "ControlRecord.h"
using namespace flt;
RegisterRecordProxy<PushLevelRecord> g_PushLevelProxy;
RegisterRecordProxy<PopLevelRecord> g_PopLevelProxy;
RegisterRecordProxy<PushSubfaceRecord> g_PushSubfaceProxy;
RegisterRecordProxy<PopSubfaceRecord> g_PopSubfaceProxy;
RegisterRecordProxy<PushExtensionRecord> g_PushExtensionProxy;
RegisterRecordProxy<PopExtensionRecord> g_PopExtensionProxy;

View File

@@ -0,0 +1,125 @@
// ControlRecord.h
#ifndef __FLT_CONTROL_RECORD_H
#define __FLT_CONTROL_RECORD_H
#include "opcodes.h"
#include "Record.h"
#include "RecordVisitor.h"
namespace flt {
////////////////////////////////////////////////////////////////////
//
// PushLevelRecord
//
////////////////////////////////////////////////////////////////////
class PushLevelRecord : public ControlRecord
{
public:
PushLevelRecord() {}
virtual Record* clone() const { return new PushLevelRecord(); }
virtual const char* className() const { return "PushLevelRecord"; }
virtual int classOpcode() const { return PUSH_LEVEL_OP; }
virtual void accept(RecordVisitor& rv) { rv.apply(*this); }
// virtual void traverse(RecordVisitor& rv);
protected:
virtual ~PushLevelRecord() {}
};
class PopLevelRecord : public ControlRecord
{
public:
PopLevelRecord() {}
virtual Record* clone() const { return new PopLevelRecord(); }
virtual const char* className() const { return "PopLevelRecord"; }
virtual int classOpcode() const { return POP_LEVEL_OP; }
virtual void accept(RecordVisitor& rv) { rv.apply(*this); }
// virtual void traverse(RecordVisitor& rv);
protected:
virtual ~PopLevelRecord() {}
};
class PushSubfaceRecord : public ControlRecord
{
public:
PushSubfaceRecord() {}
virtual Record* clone() const { return new PushSubfaceRecord(); }
virtual const char* className() const { return "PushSubfaceRecord"; }
virtual int classOpcode() const { return PUSH_SUBFACE_OP; }
virtual void accept(RecordVisitor& rv) { rv.apply(*this); }
// virtual void traverse(RecordVisitor& rv);
protected:
virtual ~PushSubfaceRecord() {}
};
class PopSubfaceRecord : public ControlRecord
{
public:
PopSubfaceRecord() {}
virtual Record* clone() const { return new PopSubfaceRecord(); }
virtual const char* className() const { return "PopSubfaceRecord"; }
virtual int classOpcode() const { return POP_SUBFACE_OP; }
virtual void accept(RecordVisitor& rv) { rv.apply(*this); }
// virtual void traverse(RecordVisitor& rv);
protected:
virtual ~PopSubfaceRecord() {}
};
class PushExtensionRecord : public ControlRecord
{
public:
PushExtensionRecord() {}
virtual Record* clone() const { return new PushExtensionRecord(); }
virtual const char* className() const { return "PushExtensionRecord"; }
virtual int classOpcode() const { return PUSH_EXTENSION_OP; }
virtual void accept(RecordVisitor& rv) { rv.apply(*this); }
// virtual void traverse(RecordVisitor& rv);
protected:
virtual ~PushExtensionRecord() {}
};
class PopExtensionRecord : public ControlRecord
{
public:
PopExtensionRecord() {}
virtual Record* clone() const { return new PopExtensionRecord(); }
virtual const char* className() const { return "PopExtensionRecord"; }
virtual int classOpcode() const { return POP_EXTENSION_OP; }
virtual void accept(RecordVisitor& rv) { rv.apply(*this); }
// virtual void traverse(RecordVisitor& rv);
protected:
virtual ~PopExtensionRecord() {}
};
}; // end namespace flt
#endif // __FLT_CONTROL_RECORD_H

View File

@@ -0,0 +1,52 @@
// DofRecord.cpp
#include "flt.h"
#include "Registry.h"
#include "DofRecord.h"
using namespace flt;
////////////////////////////////////////////////////////////////////
//
// DofRecord
//
////////////////////////////////////////////////////////////////////
RegisterRecordProxy<DofRecord> g_DofProxy;
DofRecord::DofRecord()
{
}
// virtual
DofRecord::~DofRecord()
{
}
void DofRecord::endian()
{
SDegreeOfFreedom *pSDof = (SDegreeOfFreedom*)getData();
ENDIAN( pSDof->diReserved );
pSDof->OriginLocalDOF.endian();
pSDof->PointOnXaxis.endian();
pSDof->PointInXYplane.endian();
pSDof->dfZ.endian();
pSDof->dfY.endian();
pSDof->dfX.endian();
pSDof->dfPitch.endian();
pSDof->dfRoll.endian();
pSDof->dfYaw.endian();
pSDof->dfZscale.endian();
pSDof->dfYscale.endian();
pSDof->dfXscale.endian();
ENDIAN( pSDof->dwFlags );
}

View File

@@ -0,0 +1,87 @@
// DofRecord.h
#ifndef __FLT_DOF_RECORD_H
#define __FLT_DOF_RECORD_H
#include "opcodes.h"
#include "Record.h"
#include "RecordVisitor.h"
namespace flt {
struct SRange
{
float64 _dfMin; // Minimum value with respect to the local coord system
float64 _dfMax; // Maximum value with respect to the local coordsystem
float64 _dfCurrent; // Current value with respect to the local coord system
float64 _dfIncrement; // Increment
inline float64 minRange() { return _dfMin; }
inline float64 maxRange() { return _dfMax; }
inline float64 current() { return _dfCurrent; }
inline float64 increment() { return _dfIncrement; }
void endian() {
ENDIAN( _dfMin );
ENDIAN( _dfMax );
ENDIAN( _dfCurrent );
ENDIAN( _dfIncrement );
}
};
typedef struct DegreeOfFreedomTag
{
SRecHeader RecHeader;
char szIdent[8]; // 7 char ASCII ID; 0 terminates
int32 diReserved; // Reserved
float64x3 OriginLocalDOF; // Origin (x,y,z) of the DOF's local coordinate system
float64x3 PointOnXaxis; // Point (x,y,z) on the x-axis of the DOF's local coord system
float64x3 PointInXYplane; // Point (x,y,z) in xy plane of the DOF's local coord system
SRange dfZ; // Legal z values with respect to the local coord system
SRange dfY; // Legal y values with respect to the local coord system
SRange dfX; // Legal x values with respect to the local coord system
SRange dfPitch; // Legal pitch values (rotation about the x-axis)
SRange dfRoll; // Legal roll values( rotation about the y-axis)
SRange dfYaw; // Legal yaw values (rotation about the z-axis)
SRange dfZscale; // Legal z scale values (about local origin)
SRange dfYscale; // Legal y scale values about local origin)
SRange dfXscale; // Legal x scale values (about local origin)
uint32 dwFlags; // Flags, bits from left to right (see OF doc)
} SDegreeOfFreedom;
class DofRecord : public PrimNodeRecord
{
public:
DofRecord();
virtual Record* clone() const { return new DofRecord(); }
virtual const char* className() const { return "DofRecord"; }
virtual int classOpcode() const { return DOF_OP; }
virtual int sizeofData() const { return sizeof(SDegreeOfFreedom); }
virtual void accept(RecordVisitor& rv) { rv.apply(*this); }
// virtual void traverse(RecordVisitor& rv);
SDegreeOfFreedom* getData() const { return (SDegreeOfFreedom*)_pData; }
virtual const std::string getName( void ) const { return std::string(getData()->szIdent); }
protected:
virtual ~DofRecord();
virtual void endian();
// virtual bool readLocalData(Input& fr);
// virtual bool writeLocalData(Output& fw);
};
}; // end namespace flt
#endif

View File

@@ -0,0 +1,39 @@
// ExtensionRecord.cpp
#include "flt.h"
#include "Registry.h"
#include "ExtensionRecord.h"
using namespace flt;
////////////////////////////////////////////////////////////////////
//
// ExtensionRecord
//
////////////////////////////////////////////////////////////////////
RegisterRecordProxy<ExtensionRecord> g_ExtensionProxy;
ExtensionRecord::ExtensionRecord()
{
}
// virtual
ExtensionRecord::~ExtensionRecord()
{
}
void ExtensionRecord::endian()
{
SExtension *pExtension = (SExtension*)getData();
// VALID_RECORD(SHeader, pRecHdr)
ENDIAN( pExtension->code );
}

View File

@@ -0,0 +1,59 @@
// ExtensionRecord.h
#ifndef __FLT_EXTENSION_RECORD_H
#define __FLT_EXTENSION_RECORD_H
#include "opcodes.h"
#include "Record.h"
#include "RecordVisitor.h"
namespace flt {
class Input;
};
namespace flt {
////////////////////////////////////////////////////////////////////
//
// ExtensionRecord
//
////////////////////////////////////////////////////////////////////
typedef struct ExtensionTag
{
SRecHeader RecHeader;
char szIdent[8]; // 7 char ASCII ID; 0 terminates
char site[8]; // Site ID - Unique site name
char reserved; // Reserved
char revision; // Revision - site specific
uint16 code; // Record code - site specific
// char n/a; // Extended data - site specific
}SExtension;
class ExtensionRecord : public PrimNodeRecord
{
public:
ExtensionRecord();
virtual Record* clone() const { return new ExtensionRecord(); }
virtual const char* className() const { return "ExtensionRecord"; }
virtual int classOpcode() const { return EXTENSION_OP; }
virtual int sizeofData() const { return sizeof(SExtension); }
virtual void accept(RecordVisitor& rv) { rv.apply(*this); }
// virtual void traverse(RecordVisitor& rv);
protected:
virtual ~ExtensionRecord();
virtual void endian();
};
}; // end namespace flt
#endif

View File

@@ -0,0 +1,52 @@
// ExternalRecord.cpp
#include "flt.h"
#include "Registry.h"
#include "FltFile.h"
#include "ExternalRecord.h"
using namespace flt;
////////////////////////////////////////////////////////////////////
//
// ExternalRecord
//
////////////////////////////////////////////////////////////////////
RegisterRecordProxy<ExternalRecord> g_ExternalProxy;
ExternalRecord::ExternalRecord()
{
_pExternal = NULL;
}
// virtual
ExternalRecord::~ExternalRecord()
{
if (_pExternal)
_pExternal->unref();
}
void ExternalRecord::setExternal(FltFile* pExternal)
{
if (_pExternal)
_pExternal->unref();
_pExternal = pExternal;
_pExternal->ref();
}
void ExternalRecord::endian()
{
SExternalReference *pSExternal = (SExternalReference*)getData();
ENDIAN( pSExternal->diFlags );
}

View File

@@ -0,0 +1,63 @@
// ExternalRecord.h
#ifndef __FLT_EXTERNAL_RECORD_H
#define __FLT_EXTERNAL_RECORD_H
#include "opcodes.h"
#include "Record.h"
#include "RecordVisitor.h"
namespace flt {
struct SExternalReference
{
SRecHeader RecHeader;
char szPath[200]; // 199 char ASCII Path; 0 terminates
uint8 swReserved[4]; // Reserved
int32 diFlags; // Flags (bits from left to right)
// 0 = Color Palette Override
// 1 = Material Palette Override
// 2 = Texture Palette Override
// 3 = Line Palette Override
// 4 = Sound Palette Override
// 5 = Light source Palette Override
// 6-31 Spare
int16 iReserved; // Reserved
};
class ExternalRecord : public PrimNodeRecord
{
public:
ExternalRecord();
virtual Record* clone() const { return new ExternalRecord(); }
virtual const char* className() const { return "ExternalRecord"; }
virtual int classOpcode() const { return EXTERNAL_REFERENCE_OP; }
virtual void accept(RecordVisitor& rv) { rv.apply(*this); }
// virtual void traverse(RecordVisitor& rv);
SExternalReference* getData() const { return (SExternalReference*)_pData; }
void setExternal(FltFile* pExternal);
FltFile* getExternal() { return _pExternal; }
const std::string getFilename( void ) const { return std::string(getData()->szPath); }
protected:
virtual ~ExternalRecord();
// virtual bool readLocalData(Input& fr);
// virtual bool writeLocalData(Output& fw);
virtual void endian();
FltFile* _pExternal;
};
}; // end namespace flt
#endif

View File

@@ -0,0 +1,292 @@
// FaceRecord.cpp
#include "flt.h"
#include "Registry.h"
#include "FaceRecord.h"
#include "Input.h"
using namespace flt;
////////////////////////////////////////////////////////////////////
//
// FaceRecord
//
////////////////////////////////////////////////////////////////////
RegisterRecordProxy<FaceRecord> g_FaceProxy;
FaceRecord::FaceRecord()
{
}
// virtual
FaceRecord::~FaceRecord()
{
}
int FaceRecord::numberOfVertices()
{
for (int n=0; n < getNumChildren(); n++)
{
VertexListRecord* pSVertexList = (VertexListRecord*)getChild(n);
if (pSVertexList && pSVertexList->isOfType(VERTEX_LIST_OP))
return pSVertexList->numberOfVertices();
}
return 0;
}
int FaceRecord::getVertexPoolOffset(int index)
{
for (int n=0; n < getNumChildren(); n++)
{
VertexListRecord* pSVertexList = (VertexListRecord*)getChild(n);
if (pSVertexList && pSVertexList->isOfType(VERTEX_LIST_OP))
return pSVertexList->getVertexPoolOffset(index);
}
return 0;
}
void FaceRecord::endian()
{
SFace *pSFace = (SFace*)getData();
ENDIAN( pSFace->diIRColor );
ENDIAN( pSFace->iObjectRelPriority );
ENDIAN( pSFace->wPrimaryNameIndex );
ENDIAN( pSFace->wSecondaryNameIndex );
ENDIAN( pSFace->iDetailTexturePattern );
ENDIAN( pSFace->iTexturePattern );
ENDIAN( pSFace->iMaterial );
ENDIAN( pSFace->iSurfaceMaterial );
ENDIAN( pSFace->iFeature );
ENDIAN( pSFace->diIRMaterial );
ENDIAN( pSFace->wTransparency );
ENDIAN( pSFace->diFlags );
// ENDIAN( pSFace->PrimaryPackedColor );
// ENDIAN( pSFace->SecondaryPackedColor );
ENDIAN( pSFace->iTextureMapIndex );
ENDIAN( pSFace->dwPrimaryColorIndex );
ENDIAN( pSFace->dwAlternateColorIndex );
}
// virtual
bool FaceRecord::readLocalData(Input& fr)
{
if (!PrimNodeRecord::readLocalData(fr))
return false;
//
// Check for subfaces
//
Record* pRec;
if (!(pRec=fr.readCreateRecord())) return false;
if (pRec->getOpcode() != PUSH_SUBFACE_OP)
return fr.rewindLast();
while ((pRec=fr.readCreateRecord()))
{
if (pRec->getOpcode()==POP_SUBFACE_OP) return true;
if (pRec->isPrimaryNode())
{
addChild(pRec);
if (!((PrimNodeRecord*)pRec)->readLocalData(fr))
return false;
}
}
return (pRec != NULL);
}
////////////////////////////////////////////////////////////////////
//
// VertexListRecord
//
////////////////////////////////////////////////////////////////////
RegisterRecordProxy<VertexListRecord> g_VertexListProxy;
VertexListRecord::VertexListRecord()
{
}
// virtual
VertexListRecord::~VertexListRecord()
{
}
int VertexListRecord::numberOfVertices()
{
return getBodyLength()/4;
}
int VertexListRecord::getVertexPoolOffset(int index)
{
SSingleVertexList *pSVertexList = (SSingleVertexList*)getData();
if ((index >= 0) && (index < numberOfVertices()))
return pSVertexList->diSOffset[index];
return 0;
}
void VertexListRecord::endian()
{
SSingleVertexList *pSVertexList = (SSingleVertexList*)getData();
int nNumberOfVertices = numberOfVertices();
for(int i=0; i < nNumberOfVertices; i++)
{
ENDIAN( pSVertexList->diSOffset[i] );
}
}
// virtual
bool VertexListRecord::readLocalData(Input& fr)
{
// A vertex node is a leaf node in the database and
// therefore cannot have any children.
return true;
}
////////////////////////////////////////////////////////////////////
//
// MorphVertexListRecord
//
////////////////////////////////////////////////////////////////////
RegisterRecordProxy<MorphVertexListRecord> g_MorphVertexListRecordProxy;
MorphVertexListRecord::MorphVertexListRecord()
{
}
// virtual
MorphVertexListRecord::~MorphVertexListRecord()
{
}
int MorphVertexListRecord::numberOfVertices()
{
return getBodyLength()/8;
}
void MorphVertexListRecord::endian()
{
// SMorphVertexList *pSMorpVertexList = (SMorphVertexList*)getData();
}
// virtual
bool MorphVertexListRecord::readLocalData(Input& fr)
{
// A vertex node is a leaf node in the database and
// therefore cannot have any children.
return true;
}
////////////////////////////////////////////////////////////////////
//
// UnknownListRecord
//
////////////////////////////////////////////////////////////////////
//RegisterRecordProxy<UnknownListRecord> g_UnknownListProxy;
UnknownListRecord::UnknownListRecord()
{
}
// virtual
UnknownListRecord::~UnknownListRecord()
{
}
void UnknownListRecord::endian()
{
}
// virtual
bool UnknownListRecord::readLocalData(Input& fr)
{
// A vertex node is a leaf node in the database and
// therefore cannot have any children.
return true;
}
////////////////////////////////////////////////////////////////////
//
// VectorRecord
//
////////////////////////////////////////////////////////////////////
RegisterRecordProxy<VectorRecord> g_VectorProxy;
VectorRecord::VectorRecord()
{
}
// virtual
VectorRecord::~VectorRecord()
{
}
void VectorRecord::endian()
{
SVector *pSVector = (SVector*)getData();
pSVector->Vec.endian();
}

View File

@@ -0,0 +1,288 @@
// FaceRecord.h
#ifndef __FLT_FACE_RECORD_H
#define __FLT_FACE_RECORD_H
#include "opcodes.h"
#include "Record.h"
#include "RecordVisitor.h"
namespace flt {
////////////////////////////////////////////////////////////////////
//
// FaceRecord
//
////////////////////////////////////////////////////////////////////
struct SFace
{
SRecHeader RecHeader;
char szIdent[8]; // 7 char ASCII ID; 0 terminates
int32 diIRColor; // IR Color Code
int16 iObjectRelPriority; // Polygon relative priority
uint8 swDrawFlag; // How to draw the polygon
// = 0 Draw solid backfaced
// = 1 Draw solid no backface
// = 2 Draw wireframe and not closed
// = 3 Draw closed wireframe
// = 4 Surround with wireframe in alternate color
// = 8 Omni-directional light
// = 9 Unidirectional light
// = 10 Bidirectional light
uint8 swTexWhite; // if TRUE, draw textured polygon white (see note 1 below)
uint16 wPrimaryNameIndex; // Color name index
uint16 wSecondaryNameIndex; // Alternate color name index
uint8 swNotUsed; // Not used
uint8 swTemplateTrans; // Set template transparency
// = 0 None
// = 1 Fixed
// = 2 Axis type rotate
// = 4 Point rotate
int16 iDetailTexturePattern; // Detail texture pattern no. -1 if none
int16 iTexturePattern; // Texture pattern no. -1 if none
int16 iMaterial; // Material code [0-63]. -1 if none
int16 iSurfaceMaterial; // Surface material code (for DFAD)
int16 iFeature; // Feature ID (for DFAD)
int32 diIRMaterial; // IR Material codes
uint16 wTransparency; // Transparency
// = 0 opaque
// = 65535 for totally clear
uint8 swInfluenceLODGen; // LOD Generation Control
uint8 swLinestyle; // Linestyle Index
int32 diFlags; // Flags (bits from to right)
// 0 = Terrain
// 1 = No Color
// 2 = No Alt Color
// 3 = Packed color
// 4 = Terrain culture cutout (footprint)
// 5 = Hidden (not drawn)
// 6-31 Spare
uint8 swLightMode; // Lightmode
// = 0 use face color, not illuminated
// = 1 use vertex color, not illuminated
// = 2 use face color and vertex normal
// = 3 use vertex color and vertex normal
uint8 swReserved1[7]; // Reserved
color32 PrimaryPackedColor; // Packed Color Primary (A, B, G, R)
color32 SecondaryPackedColor; // Packed Color Secondary (A, B, G, R)
int16 iTextureMapIndex; // Texture mapping index
int16 iReserved2;
uint32 dwPrimaryColorIndex;
uint32 dwAlternateColorIndex;
int16 iReserved3[2];
};
class FaceRecord : public PrimNodeRecord
{
public:
enum DrawFlag {
SOLID_BACKFACED = 0,
SOLID_NO_BACKFACE = 1,
WIREFRAME_NOT_CLOSED = 2,
WIREFRAME_CLOSED = 3,
SURROUND_ALTERNATE_COLOR = 4,
OMNIDIRECTIONAL_LIGHT = 8,
UNIDIRECTIONAL_LIGHT = 9,
BIDIRECTIONAL_LIGHT = 10
};
enum LightMode {
FACE_COLOR = 0,
VERTEX_COLOR = 1,
FACE_COLOR_LIGHTING = 2,
VERTEX_COLOR_LIGHTING = 3,
};
FaceRecord();
virtual Record* clone() const { return new FaceRecord(); }
virtual const char* className() const { return "FaceRecord"; }
virtual int classOpcode() const { return FACE_OP; }
virtual int sizeofData() const { return sizeof(SFace); }
virtual void accept(RecordVisitor& rv) { rv.apply(*this); }
// virtual void traverse(RecordVisitor& rv);
virtual SFace* getData() const { return (SFace*)_pData; }
virtual const std::string getName( void ) const { return std::string(getData()->szIdent); }
int numberOfVertices();
int getVertexPoolOffset(int index);
protected:
virtual ~FaceRecord();
virtual void endian();
virtual bool readLocalData(Input& fr);
// virtual bool writeLocalData(Output& fw);
};
////////////////////////////////////////////////////////////////////
//
// VertexListRecord
//
////////////////////////////////////////////////////////////////////
typedef struct SingleVertexListTag
{
SRecHeader RecHeader;
int32 diSOffset[1]; // Byte offset to this vertex record in vertex table,
// the actual vertex of the face
} SSingleVertexList;
class VertexListRecord : public PrimNodeRecord
{
public:
VertexListRecord();
virtual Record* clone() const { return new VertexListRecord(); }
virtual const char* className() const { return "VertexListRecord"; }
virtual int classOpcode() const { return VERTEX_LIST_OP; }
virtual int sizeofData() const { return sizeof(SSingleVertexList); }
virtual void accept(RecordVisitor& rv) { rv.apply(*this); }
// virtual void traverse(RecordVisitor& rv);
virtual SSingleVertexList* getData() const { return (SSingleVertexList*)_pData; }
int numberOfVertices();
int getVertexPoolOffset(int index);
protected:
virtual ~VertexListRecord();
virtual bool readLocalData(Input& fr);
// virtual bool writeLocalData(Output& fw);
virtual void endian();
};
////////////////////////////////////////////////////////////////////
//
// MorphVertexListRecord
//
////////////////////////////////////////////////////////////////////
typedef struct MorphVertexListTag
{
SRecHeader RecHeader;
uint32 dwOffset0; // Byte offset into vertex palette of the 0% vertex
uint32 dwOffset100; // Byte offset into vertex palette of the 100% vertex
} SMorphVertexList;
class MorphVertexListRecord : public PrimNodeRecord
{
public:
MorphVertexListRecord();
virtual Record* clone() const { return new MorphVertexListRecord(); }
virtual const char* className() const { return "MorphVertexListRecord"; }
virtual int classOpcode() const { return MORPH_VERTEX_LIST_OP; }
virtual int sizeofData() const { return sizeof(SMorphVertexList); }
virtual void accept(RecordVisitor& rv) { rv.apply(*this); }
// virtual void traverse(RecordVisitor& rv);
virtual SMorphVertexList* getData() const { return (SMorphVertexList*)_pData; }
int numberOfVertices();
protected:
virtual ~MorphVertexListRecord();
virtual bool readLocalData(Input& fr);
// virtual bool writeLocalData(Output& fw);
virtual void endian();
};
////////////////////////////////////////////////////////////////////
//
// UnknownListRecord
//
////////////////////////////////////////////////////////////////////
class UnknownListRecord : public PrimNodeRecord
{
public:
UnknownListRecord();
virtual Record* clone() const { return new UnknownListRecord(); }
virtual const char* className() const { return "UnknownListRecord"; }
virtual int classOpcode() const { return 53; }
// virtual void accept(RecordVisitor& rv) { rv.apply(*this); }
// virtual void traverse(RecordVisitor& rv);
protected:
virtual ~UnknownListRecord();
virtual bool readLocalData(Input& fr);
// virtual bool writeLocalData(Output& fw);
virtual void endian();
};
////////////////////////////////////////////////////////////////////
//
// VectorRecord
//
////////////////////////////////////////////////////////////////////
// A vector record is an ancillary record of the (pre V15.4) face node.
// Its only use is to provide the direction vector for old-style
// unidirectional and bidirectional light point faces.
typedef struct VectorTag
{
SRecHeader RecHeader;
float32x3 Vec;
} SVector;
class VectorRecord : public AncillaryRecord
{
public:
VectorRecord();
virtual Record* clone() const { return new VectorRecord(); }
virtual const char* className() const { return "VectorRecord"; }
virtual int classOpcode() const { return VECTOR_OP; }
virtual int sizeofData() const { return sizeof(SVector); }
virtual void accept(RecordVisitor& rv) { rv.apply(*this); }
// virtual void traverse(RecordVisitor& rv);
virtual SVector* getData() const { return (SVector*)_pData; }
protected:
virtual ~VectorRecord();
virtual void endian();
};
}; // end namespace flt
#endif

View File

@@ -0,0 +1,166 @@
// FltFile.cpp
#include <osg/OSG>
#include <osg/Node>
#include <osg/NodeVisitor>
#include <osg/Notify>
#include "FltFile.h"
#include "Record.h"
#include "RecordVisitor.h"
#include "ExternalRecord.h"
#include "flt2osg.h" // ConvertFromFLT
#include "Input.h"
using namespace flt;
FltFile::FltFile(
ColorPool* pColorPool,
TexturePool* pTexturePool,
MaterialPool* pMaterialPool)
{
if (pColorPool)
_pColorPool = pColorPool;
else
_pColorPool = &_colorPool;
if (pTexturePool)
_pTexturePool = pTexturePool;
else
_pTexturePool = &_texturePool;
if (pMaterialPool)
_pMaterialPool = pMaterialPool;
else
_pMaterialPool = &_materialPool;
_pHeaderRecord = NULL;
}
FltFile::~FltFile()
{
}
osg::Object* FltFile::readObject(const std::string& fileName)
{
return readNode(fileName);
}
osg::Node* FltFile::readNode(const std::string& fileName)
{
osg::Node* node = NULL;
Record* pRootRec = readModel(fileName);
if (pRootRec == NULL)
return NULL;
// Convert record tree to osg scene graph
node = convert();
pRootRec->unref(); // delete record tree
return node;
}
osg::Node* FltFile::convert()
{
ConvertFromFLT visit(this);
return visit.convert(getHeaderRecord());
}
// Read flight model (include externals)
Record* FltFile::readModel(const std::string& fileName)
{
Record* pRec = readFile(fileName);
if (pRec == NULL) return NULL;
readExternals(pRec);
return pRec;
}
Record* FltFile::readFile(const std::string& fileName)
{
FileInput fin;
if (!fin.open(fileName)) return NULL;
osg::notify(osg::INFO) << "Loading " << fileName << " ... " << endl;
Record* pRec = fin.readCreateRecord();
_pHeaderRecord = pRec;
if (pRec == NULL)
{
osg::notify(osg::WARN) << "File not found " << fileName << endl;
return NULL;
}
if (pRec->isPrimaryNode()) // Header
pRec->readLocalData(fin); // Read rest of file
fin.close();
return pRec;
}
class ReadExternal : public RecordVisitor
{
public:
ReadExternal(FltFile* fltFile)
{
_fltFile = fltFile;
setTraverseMode(RecordVisitor::TRAVERSE_ALL_CHILDREN);
}
virtual void apply(ExternalRecord& rec)
{
SExternalReference* pSExternal = (SExternalReference*)rec.getData();
osg::notify(osg::INFO) << "External=" << pSExternal->szPath << endl;
ColorPool* pColorPool = NULL;
TexturePool* pTexturePool = NULL;
MaterialPool* pMaterialPool = NULL;
if (pSExternal->diFlags & BIT0)
pColorPool = _fltFile->getColorPool();
if (pSExternal->diFlags & BIT2)
pTexturePool = _fltFile->getTexturePool();
if (pSExternal->diFlags & BIT1)
pMaterialPool = _fltFile->getMaterialPool();
FltFile* flt = new FltFile(pColorPool, pTexturePool, pMaterialPool);
if (flt)
{
flt->readModel(pSExternal->szPath);
rec.setExternal(flt);
}
}
public:
FltFile* _fltFile;
};
void FltFile::readExternals(Record* pRec)
{
if (pRec)
{
ReadExternal visitor(this);
pRec->accept(visitor);
}
}

View File

@@ -0,0 +1,60 @@
// FltFile.h
#ifndef __FLT_FILE_H
#define __FLT_FILE_H
#include <map>
#include <string>
#include <osg/Referenced>
#include "Pool.h"
namespace flt {
class Record;
class FltFile : public osg::Referenced
{
public:
FltFile(
ColorPool* pColorPool = NULL,
TexturePool* pTexturePool = NULL,
MaterialPool* pMaterialPool = NULL);
virtual ~FltFile();
virtual osg::Object* readObject(const std::string& fileName);
virtual osg::Node* readNode(const std::string& fileName);
osg::Node* convert();
Record* getHeaderRecord() { return _pHeaderRecord; }
Record* readModel(const std::string& fileName);
ColorPool* getColorPool() { return _pColorPool; }
TexturePool* getTexturePool() { return _pTexturePool; }
MaterialPool* getMaterialPool() { return _pMaterialPool; }
protected:
Record* readFile(const std::string& fileName);
void readExternals(Record* pRec);
private:
Record* _pHeaderRecord;
ColorPool _colorPool;
TexturePool _texturePool;
MaterialPool _materialPool;
ColorPool* _pColorPool;
TexturePool* _pTexturePool;
MaterialPool* _pMaterialPool;
};
}; // end namespace flt
#endif

View File

@@ -0,0 +1,95 @@
// FltRecords.h
#ifndef __FLT_RECORDS_H
#define __FLT_RECORDS_H
#include "flt.h"
namespace flt {
///////////////////////////////////////////////////////////////
typedef struct MorphingVertexListTag
{
SRecHeader RecHeader;
int32 diAOffset; // Byte offset to the actual vertex record in the vertex table.
int32 diMOffset; // Byte offset to the morph vertex record in the vertex table.
} SMorphingVertexList; // see OF doc
typedef struct ReplicateTag
{
SRecHeader RecHeader;
int16 iNumber; // Number of replications
int16 iSpare; // Spare for fullword alignment
} SReplicate;
/*
typedef struct ReferenceTag // OBSOLETE
{
SRecHeader RecHeader;
int16 iSpare; // Spare
int16 iNumber; // Instance definition number
} SReference;
typedef struct DefinitionTag // OBSOLETE
{
SRecHeader RecHeader;
int16 iSpare; // Spare
int16 iNumber; // Instance definition number
} SDefinition;
*/
/*
typedef struct ColorTableTag
{
SRecHeader RecHeader;
char szReserved[128];// Reserved
color32 Colors[1024]; // Array of brightest RGB of color 0 - 1024
} SColorTable;
// this record is sometimes immediately followed by a: int32 numberOfColorNames
// and then the specified number of ColorNames as described in the structure below
// to check if such a list exist: compare RecHeaderBuff.wLength with sizeof(SColorTable)
typedef struct ColorNameListTag
{
uint16 wEntryLength;
int16 iReserved_1;
int16 iEntryIndex;
int16 iReserved_2;
char *szName; // calc length of string from wEntryLength
} SColorNameList;
*/
/*
typedef struct ComponentTag
{
float32 sfRed; // red component of material
float32 sfGreen; // green component of material
float32 sfBlue; // blue component of material
} SComponent;
*/
}; // end namespace flt
#endif // __FLT_RECORDS_H

View File

@@ -0,0 +1,574 @@
// GeoSetBuilder.cpp
#include "flt.h"
#include "FltFile.h"
#include "Pool.h"
#include "opcodes.h"
#include "VertexPoolRecords.h"
#include "OldVertexRecords.h"
#include "MaterialPaletteRecord.h"
#include "GeoSetBuilder.h"
#include <osg/Object>
#include <osg/LOD>
#include <osg/GeoState>
#include <osg/Transparency>
#include <osg/GeoSet>
#include <osg/GeoState>
#include <osg/Geode>
#include <osg/Material>
#include <osg/Texture>
#include <osg/TexEnv>
#include <osg/Notify>
#include <algorithm>
#include <map>
using namespace flt;
////////////////////////////////////////////////////////////////////
//
// GeoSetBuilder
//
////////////////////////////////////////////////////////////////////
// OpenFlight don't save data in GeoSets. This class tries to find
// existing GeoSets with matching state before creating a new GeoSet.
GeoSetBuilder::GeoSetBuilder(FltFile* pFltFile)
{
_pFltFile = pFltFile;
initPrimData();
}
// virtual
GeoSetBuilder::~GeoSetBuilder()
{
for(GeoSetList::iterator itr=_aGeoSet.begin();
itr!=_aGeoSet.end();
++itr)
{
delete *itr;
}
}
void GeoSetBuilder::initPrimData()
{
_appearance.init();
_aVertex.erase(_aVertex.begin(), _aVertex.end());
}
// Convert flt::TmpGeoSet's to osg::GeoSet's and add to osg::Geode.
// If geode parameter is NULL create new.
// If geode created inside this function and no osg::GeoSet's
// added free geode.
osg::Geode* GeoSetBuilder::createOsgGeoSets(osg::Geode* geode)
{
bool bInternalGeodeAllocation = false;
if (geode == NULL)
{
geode = new osg::Geode;
bInternalGeodeAllocation = true;
}
for(GeoSetList::iterator itr=_aGeoSet.begin();
itr!=_aGeoSet.end();
++itr)
{
osg::GeoSet* gset = (*itr)->createOsgGeoSet();
if (gset)
geode->addGeoSet(gset);
}
if (bInternalGeodeAllocation && (geode->getNumGeosets() == 0))
{
geode->unref();
return NULL;
}
return geode;
}
void GeoSetBuilder::addVertex(Record* vertex)
{
_aVertex.push_back(vertex);
_appearance.setVertexOp(vertex->getOpcode());
}
bool GeoSetBuilder::addPrimitive()
{
int nVertices = _aVertex.size();
if (nVertices == 0) return false;
if (_appearance.getPrimType() == osg::GeoSet::NO_TYPE)
_appearance.setPrimType(findPrimType(nVertices));
TmpGeoSet* gset = findMatchingGeoSet();
if (gset)
{
addTo(gset);
if (_appearance.getMaterial())
{
_appearance.getMaterial()->unref();
_appearance.setMaterial(NULL);
}
}
else
addToNew();
initPrimData();
return true;
}
//////////////////////// protected /////////////////////////////////
TmpGeoSet* GeoSetBuilder::findMatchingGeoSet()
{
for(std::vector<TmpGeoSet*>::iterator itr=_aGeoSet.begin();
itr!=_aGeoSet.end();
++itr)
{
if (_appearance == (*itr)->_appearance)
return *itr;
}
return NULL;
}
void GeoSetBuilder::addTo(TmpGeoSet* gset)
{
int nVertices = _aVertex.size();
gset->addPrimLen(nVertices);
for(std::vector<Record*>::iterator itr=_aVertex.begin();
itr!=_aVertex.end();
++itr)
{
gset->addVertex(*itr);
}
}
void GeoSetBuilder::addToNew()
{
TmpGeoSet* gset = new TmpGeoSet(_pFltFile);
if (gset == NULL) return;
// Transfer data to TmpGeoSet
gset->_appearance = _appearance;
addTo(gset);
_aGeoSet.push_back(gset);
}
PrimitiveType GeoSetBuilder::findPrimType( int nVertices)
{
PrimitiveType primtype = osg::GeoSet::NO_TYPE;
switch (nVertices)
{
case 1:
primtype = osg::GeoSet::POINTS;
break;
case 2:
primtype = osg::GeoSet::LINES;
break;
case 3:
primtype = osg::GeoSet::TRIANGLES;
break;
case 4:
primtype = osg::GeoSet::QUADS;
break;
default:
if (nVertices >= 5) primtype = osg::GeoSet::POLYGON;
break;
}
return primtype;
}
////////////////////////////////////////////////////////////////////
//
// TmpGeoSet
//
////////////////////////////////////////////////////////////////////
// GeoSet with dynamic size. Used by GeoSetBuilder as a temp. buffer.
TmpGeoSet::TmpGeoSet(FltFile* pFltFile)
{
_pFltFile = pFltFile;
}
TmpGeoSet::~TmpGeoSet()
{
}
void TmpGeoSet::addVertex(Record* vertex)
{
_appearance.setVertexOp(vertex->getOpcode());
_aVertex.push_back(vertex);
}
void TmpGeoSet::addPrimLen(int len)
{
_aPrimLen.push_back(len);
}
osg::GeoSet* TmpGeoSet::createOsgGeoSet()
{
int prims = _aPrimLen.size();
int indices = _aVertex.size();
if (prims==0 || indices==0)
return NULL;
osg::GeoSet* gset = new osg::GeoSet;
gset->setNumPrims(prims);
gset->setPrimType(_appearance.getPrimType());
osg::GeoState* gstate = new osg::GeoState;
gset->setGeoState(gstate);
// Material
osg::Material* osgMaterial = _appearance.getMaterial();
if (osgMaterial)
{
gstate->setAttribute(osg::GeoState::MATERIAL, osgMaterial);
}
// Color BIND_OVERALL
if (_appearance.getColorBinding() == osg::GeoSet::BIND_OVERALL)
{
osg::Vec4* color = new osg::Vec4[1];
*color = _appearance.getColor();
gset->setColorBinding(_appearance.getColorBinding());
gset->setColors(color);
}
// Color BIND_PERVERTEX
if (_appearance.getColorBinding() == osg::GeoSet::BIND_PERVERTEX)
{
gset->setColorBinding(_appearance.getColorBinding());
gset->setColors(new osg::Vec4[indices]);
}
// Transparency
if (_appearance.getTransparency())
{
gstate->setMode(osg::GeoState::TRANSPARENCY, osg::GeoState::ON);
gstate->setAttribute(osg::GeoState::TRANSPARENCY, new osg::Transparency);
}
// Cull face
if (_appearance.getCullface())
{
osg::CullFace* cullface = new osg::CullFace;
if (cullface)
{
gstate->setMode(osg::GeoState::FACE_CULL, osg::GeoState::ON);
cullface->setMode(osg::CullFace::BACK);
gstate->setAttribute(osg::GeoState::FACE_CULL, cullface);
}
}
else
{
gstate->setMode(osg::GeoState::FACE_CULL, osg::GeoState::OFF);
}
// Texture
if (_appearance.getTexture())
{
gstate->setMode( osg::GeoState::TEXTURE, osg::GeoState::ON );
gstate->setAttribute( osg::GeoState::TEXTURE, _appearance.getTexture() );
gstate->setAttribute( osg::GeoState::TEXENV, new osg::TexEnv );
}
// Lighting
if (_appearance.getLighting())
gstate->setMode( osg::GeoState::LIGHTING, osg::GeoState::ON );
else
gstate->setMode( osg::GeoState::LIGHTING, osg::GeoState::OFF );
// Subface
if (_appearance.getSubface() > 0)
{
osg::PolygonOffset* polyoffset = new osg::PolygonOffset;
if (polyoffset)
{
int level = _appearance.getSubface();
gstate->setMode(osg::GeoState::POLYGON_OFFSET,osg::GeoState::ON);
polyoffset->setOffset(-1*level, -20*level);
gstate->setAttribute(osg::GeoState::POLYGON_OFFSET, polyoffset);
}
}
// Point
if (_appearance.getPrimType() == osg::GeoSet::POINTS)
{
osg::Point* point = new osg::Point;
if (point)
{
gstate->setMode(osg::GeoState::POINT,osg::GeoState::ON);
point->setSize(8);
point->enableSmooth();
gstate->setAttribute(osg::GeoState::POINT, point);
}
}
// PrimLengths
int nPrimLenSize = 1;
if (_appearance.getPrimType() == osg::GeoSet::POLYGON)
nPrimLenSize = prims;
int *lens = new int[nPrimLenSize];
gset->setPrimLengths( lens );
for (int n=0; n < nPrimLenSize; n++)
lens[n] = _aPrimLen[n];
// Vertices
switch(_appearance.getVertexOp())
{
case VERTEX_C_OP:
gset->setCoords(new osg::Vec3[indices]);
break;
case VERTEX_CN_OP:
gset->setNormalBinding(osg::GeoSet::BIND_PERVERTEX);
gset->setCoords(new osg::Vec3[indices]);
gset->setNormals(new osg::Vec3[indices]);
break;
case VERTEX_CT_OP:
gset->setTextureBinding(osg::GeoSet::BIND_PERVERTEX);
gset->setCoords(new osg::Vec3[indices]);
gset->setTextureCoords(new osg::Vec2[indices]);
break;
case VERTEX_CNT_OP:
gset->setNormalBinding(osg::GeoSet::BIND_PERVERTEX);
gset->setTextureBinding(osg::GeoSet::BIND_PERVERTEX);
gset->setCoords(new osg::Vec3[indices]);
gset->setNormals(new osg::Vec3[indices]);
gset->setTextureCoords(new osg::Vec2[indices]);
break;
case OLD_VERTEX_OP:
gset->setCoords(new osg::Vec3[indices]);
break;
case OLD_VERTEX_COLOR_OP:
gset->setCoords(new osg::Vec3[indices]);
break;
case OLD_VERTEX_COLOR_NORMAL_OP:
gset->setCoords(new osg::Vec3[indices]);
// gset->setNormals(new osg::Vec3[indices]);
break;
}
// Copy vertices
{
int index;
std::vector<Record*>::iterator itr;
for(index=0, itr=_aVertex.begin();
itr!=_aVertex.end();
++index, ++itr)
{
setVertex(gset, index, *itr);
}
}
return gset;
}
///////////////////////// private //////////////////////////////////
void TmpGeoSet::setVertex(osg::GeoSet* gset, int index, Record* vertex)
{
bool bColorBindPerVertex = _appearance.getColorBinding() == osg::GeoSet::BIND_PERVERTEX;
switch(_appearance.getVertexOp())
{
case VERTEX_C_OP:
{
SVertex* pVert = (SVertex*)vertex->getData();
osg::Vec3* coords = gset->getCoords();
coords[index].set(
(float)pVert->Coord.x(),
(float)pVert->Coord.y(),
(float)pVert->Coord.z());
if (bColorBindPerVertex)
{
osg::Vec4* colors = gset->getColors();
if (pVert->swFlags & BIT3)
colors[index] = pVert->PackedColor.get();
else
{
ColorPool* pColorPool = _pFltFile->getColorPool();
if (pColorPool)
colors[index] = pColorPool->getColor(pVert->dwVertexColorIndex);
}
}
}
break;
case VERTEX_CN_OP:
{
SNormalVertex* pVert = (SNormalVertex*)vertex->getData();
osg::Vec3* coords = gset->getCoords();
osg::Vec3* normals = gset->getNormals();
coords[index].set(
(float)pVert->Coord.x(),
(float)pVert->Coord.y(),
(float)pVert->Coord.z());
normals[index].set(
(float)pVert->Normal.x(),
(float)pVert->Normal.y(),
(float)pVert->Normal.z());
if (bColorBindPerVertex)
{
osg::Vec4* colors = gset->getColors();
if (pVert->swFlags & BIT3)
colors[index] = pVert->PackedColor.get();
else
{
ColorPool* pColorPool = _pFltFile->getColorPool();
if (pColorPool)
colors[index] = pColorPool->getColor(pVert->dwVertexColorIndex);
}
}
}
break;
case VERTEX_CNT_OP:
{
SNormalTextureVertex* pVert = (SNormalTextureVertex*)vertex->getData();
osg::Vec3* coords = gset->getCoords();
osg::Vec3* normals = gset->getNormals();
osg::Vec2* texuv = gset->getTCoords();
coords[index].set(
(float)pVert->Coord.x(),
(float)pVert->Coord.y(),
(float)pVert->Coord.z());
normals[index].set(
(float)pVert->Normal.x(),
(float)pVert->Normal.y(),
(float)pVert->Normal.z());
texuv[index].set(
(float)pVert->Texture.x(),
(float)pVert->Texture.y());
if (bColorBindPerVertex)
{
osg::Vec4* colors = gset->getColors();
if (pVert->swFlags & BIT3)
colors[index] = pVert->PackedColor.get();
else
{
ColorPool* pColorPool = _pFltFile->getColorPool();
if (pColorPool)
colors[index] = pColorPool->getColor(pVert->dwVertexColorIndex);
}
}
}
break;
case VERTEX_CT_OP:
{
STextureVertex* pVert = (STextureVertex*)vertex->getData();
osg::Vec3* coords = gset->getCoords();
osg::Vec2* texuv = gset->getTCoords();
coords[index].set(
(float)pVert->Coord.x(),
(float)pVert->Coord.y(),
(float)pVert->Coord.z());
texuv[index].set(
(float)pVert->Texture.x(),
(float)pVert->Texture.y());
if (bColorBindPerVertex)
{
osg::Vec4* colors = gset->getColors();
if (pVert->swFlags & BIT3)
colors[index] = pVert->PackedColor.get();
else
{
ColorPool* pColorPool = _pFltFile->getColorPool();
if (pColorPool)
colors[index] = pColorPool->getColor(pVert->dwVertexColorIndex);
}
}
}
break;
case OLD_VERTEX_OP:
{
SOldVertex* pVert = (SOldVertex*)vertex->getData();
osg::Vec3* coords = gset->getCoords();
coords[index].set(
(float)pVert->v[0],
(float)pVert->v[1],
(float)pVert->v[2]);
}
break;
case OLD_VERTEX_COLOR_OP:
{
SOldVertexColor* pVert = (SOldVertexColor*)vertex->getData();
osg::Vec3* coords = gset->getCoords();
coords[index].set(
(float)pVert->v[0],
(float)pVert->v[1],
(float)pVert->v[2]);
}
break;
case OLD_VERTEX_COLOR_NORMAL_OP:
{
SOldVertexColorNormal* pVert = (SOldVertexColorNormal*)vertex->getData();
osg::Vec3* coords = gset->getCoords();
// osg::Vec3* normals = gset->getNormals();
coords[index].set(
(float)pVert->Coord[0],
(float)pVert->Coord[1],
(float)pVert->Coord[2]);
/*
normals[index].set(
(float)pVert->Normal[0],
(float)pVert->Normal[1],
(float)pVert->Normal[2]);
*/
}
break;
}
}

View File

@@ -0,0 +1,234 @@
// GeoSetBuilder.h
#ifndef __FLT_GEOSETS_H
#define __FLT_GEOSETS_H
#include <map>
#include <vector>
#include <osg/GeoSet>
#include <osg/Vec2>
#include <osg/Vec3>
#include <osg/Vec4>
namespace osg {
class Node;
class LOD;
class GeoSet;
class Geode;
class GeoState;
class Material;
class Texture;
}
namespace flt {
class Record;
class TmpGeoSet;
typedef osg::GeoSet::PrimitiveType PrimitiveType;
typedef std::vector<osg::Vec3> CoordList;
typedef std::vector<osg::Vec3> NormalList;
typedef std::vector<osg::Vec2> TexUVList;
typedef std::vector<osg::Vec4> ColorList;
typedef std::vector<Record*> VertexList;
typedef std::vector<int> PrimLenList;
class Appearance
{
public:
typedef osg::GeoSet::BindingType BindingType;
Appearance() { init(); }
void init()
{
_nVertexOp = 0;
_primtype = osg::GeoSet::NO_TYPE;
_material = NULL;
_texture = NULL;
_color = osg::Vec4(1,1,1,1);
_color_binding = osg::GeoSet::BIND_OFF;
_cullface = false;
_transparency = false;
_lighting = false;
_subface = 0;
}
void setVertexOp(int op) { _nVertexOp = op; }
int getVertexOp() { return _nVertexOp; }
void setPrimType(PrimitiveType pt) { _primtype = pt; }
PrimitiveType getPrimType() { return _primtype; }
void setColor(osg::Vec4 color) { _color = color; }
osg::Vec4& getColor() { return _color; }
void setColorBinding( BindingType binding ) { _color_binding = binding; }
BindingType getColorBinding() { return _color_binding; }
void setMaterial(osg::Material *material) { _material = material; }
osg::Material* getMaterial() { return _material; }
void setTexture(osg::Texture *texture) { _texture = texture; }
osg::Texture* getTexture() { return _texture; }
void setCullface(bool cullface) { _cullface = cullface; }
bool getCullface() { return _cullface; }
void setTransparency(bool transp) { _transparency = transp; }
bool getTransparency() { return _transparency; }
void setLighting(bool light) { _lighting = light; }
bool getLighting() { return _lighting; }
void setSubface(int level) { _subface = level; }
int getSubface() { return _subface; }
bool mat_equal(const void *m) const
{
if (_material && m)
return !memcmp(_material, m, sizeof(osg::Material));
return (!_material && !m);
}
bool col_equal(const BindingType b, const osg::Vec4 c) const
{
if (_color_binding != b)
return false;
if (_color_binding == osg::GeoSet::BIND_OVERALL)
return (_color == c);
return true;
}
/*inline*/ bool operator == (const Appearance& a) const
{
return ((_nVertexOp == a._nVertexOp)
&& (_primtype == a._primtype)
&& mat_equal(a._material)
&& col_equal(a._color_binding, a._color)
&& (_texture == a._texture)
&& (_cullface == a._cullface)
&& (_transparency == a._transparency)
&& (_lighting == a._lighting)
&& (_subface == a._subface));
}
private:
int _nVertexOp;
PrimitiveType _primtype;
osg::Material* _material;
osg::Texture* _texture;
osg::Vec4 _color; // BIND_OVERALL
BindingType _color_binding;
bool _cullface;
bool _transparency;
bool _lighting;
int _subface;
};
////////////////////////////////////////////////////////////////////
//
// GeoSetBuilder
//
////////////////////////////////////////////////////////////////////
class GeoSetBuilder
{
public:
typedef osg::GeoSet::BindingType BindingType;
GeoSetBuilder(FltFile* pFltFile);
virtual ~GeoSetBuilder();
void addVertex(Record* vertex);
void setPrimType(PrimitiveType pt) { _appearance.setPrimType(pt); }
void setColor(osg::Vec4 color) { _appearance.setColor(color); }
void setColorBinding(BindingType binding ) { _appearance.setColorBinding(binding); }
void setMaterial(osg::Material *material) { _appearance.setMaterial(material); }
void setTexture(osg::Texture *texture) { _appearance.setTexture(texture); }
void setCullface(bool cullface) { _appearance.setCullface(cullface); }
void setTransparency(bool transp) { _appearance.setTransparency(transp); }
void setLighting(bool light) { _appearance.setLighting(light); }
void setSubface(int level) { _appearance.setSubface(level); }
PrimitiveType getPrimType() { return _appearance.getPrimType(); }
osg::Vec4& getColor() { return _appearance.getColor(); }
BindingType getColorBinding() { return _appearance.getColorBinding(); }
osg::Material* getMaterial() { return _appearance.getMaterial(); }
osg::Texture* getTexture() { return _appearance.getTexture(); }
bool getCullface() { return _appearance.getCullface(); }
bool getTransparency() { return _appearance.getTransparency(); }
bool getLighting() { return _appearance.getLighting(); }
int getSubface() { return _appearance.getSubface(); }
bool addPrimitive();
osg::Geode* createOsgGeoSets(osg::Geode* geode=NULL);
protected:
void initPrimData();
TmpGeoSet* findMatchingGeoSet();
void addTo(TmpGeoSet* gset);
void addToNew();
PrimitiveType findPrimType( int nVertices);
private:
VertexList _aVertex;
Appearance _appearance;
typedef std::vector<TmpGeoSet*> GeoSetList;
GeoSetList _aGeoSet;
FltFile* _pFltFile;
};
////////////////////////////////////////////////////////////////////
//
// TmpGeoSet
//
////////////////////////////////////////////////////////////////////
class TmpGeoSet
{
public:
TmpGeoSet(FltFile* pFltFile);
virtual ~TmpGeoSet();
void addVertex(Record* vertex);
void addPrimLen(int len);
osg::GeoSet* createOsgGeoSet();
Appearance _appearance;
private:
void setVertex(osg::GeoSet* gset, int index, Record* vertex);
PrimLenList _aPrimLen;
VertexList _aVertex;
FltFile* _pFltFile;
};
} // end of namespace flt
#endif // __FLT_GEOSETS_H

View File

@@ -0,0 +1,44 @@
// GroupRecord.cpp
#include "flt.h"
#include "Registry.h"
#include "GroupRecord.h"
using namespace flt;
////////////////////////////////////////////////////////////////////
//
// GroupRecord
//
////////////////////////////////////////////////////////////////////
RegisterRecordProxy<GroupRecord> g_GroupProxy;
GroupRecord::GroupRecord()
{
}
// virtual
GroupRecord::~GroupRecord()
{
}
void GroupRecord::endian()
{
SGroup *pSGroup = (SGroup*)getData();
ENDIAN( pSGroup->iGroupRelPriority );
ENDIAN( pSGroup->dwFlags );
ENDIAN( pSGroup->iSpecialId_1 );
ENDIAN( pSGroup->iSpecialId_2 );
ENDIAN( pSGroup->iSignificance );
}

View File

@@ -0,0 +1,64 @@
// GroupRecord.h
#ifndef __FLT_GROUP_RECORD_H
#define __FLT_GROUP_RECORD_H
#include "opcodes.h"
#include "Record.h"
#include "RecordVisitor.h"
namespace flt {
struct SGroup
{
SRecHeader RecHeader;
char szIdent[8]; // 7 char ASCII ID; 0 terminates
int16 iGroupRelPriority; // Group relative priority
int16 iSpare; // Spare for fullword alignment
uint32 dwFlags; // Flags (bits, from left to right)
// 0 = Reserved
// 1 = Forward animation
// 2 = Cycling animation
// 3 = Bounding box follows
// 4 = Freeze bounding box
// 5 = Default parent
// 6-31 Spare
int16 iSpecialId_1; // Special effects ID 1 - defined by real time
int16 iSpecialId_2; // Special effects ID 2 - defined by real time
int16 iSignificance; // Significance Flags
uint8 swLayer; // Layer Number
uint8 swReserved[5]; // Reserved
};
class GroupRecord : public PrimNodeRecord
{
public:
GroupRecord();
virtual Record* clone() const { return new GroupRecord(); }
virtual const char* className() const { return "GroupRecord"; }
virtual int classOpcode() const { return GROUP_OP; }
virtual int sizeofData() const { return sizeof(SGroup); }
virtual void accept(RecordVisitor& rv) { rv.apply(*this); }
// virtual void traverse(RecordVisitor& rv);
SGroup* getData() const { return (SGroup*)_pData; }
virtual const std::string getName( void ) const { return std::string(getData()->szIdent); }
int childLODs();
protected:
virtual ~GroupRecord();
virtual void endian();
};
}; // end namespace flt
#endif

View File

@@ -0,0 +1,197 @@
// HeaderRecord.cpp
#include "osg/Group"
#include "flt.h"
#include "Registry.h"
#include "HeaderRecord.h"
#include "Input.h"
using namespace flt;
////////////////////////////////////////////////////////////////////
//
// HeaderRecord
//
////////////////////////////////////////////////////////////////////
RegisterRecordProxy<HeaderRecord> g_HeaderProxy;
HeaderRecord::HeaderRecord()
{
// _pNode = NULL;
}
// virtual
HeaderRecord::~HeaderRecord()
{
}
void HeaderRecord::endian()
{
SHeader *pHeader = (SHeader*)getData();
// VALID_RECORD(SHeader, pRecHdr)
ENDIAN( pHeader->diFormatRevLev );
ENDIAN( pHeader->diDatabaseRevLev );
ENDIAN( pHeader->iNextGroup );
ENDIAN( pHeader->iNextLOD );
ENDIAN( pHeader->iNextObject );
ENDIAN( pHeader->iNextPolygon );
ENDIAN( pHeader->iMultDivUnit );
ENDIAN( pHeader->diFlags );
ENDIAN( pHeader->diProjection );
ENDIAN( pHeader->iNextDegOfFreedom );
ENDIAN( pHeader->iVertexStorage );
ENDIAN( pHeader->diDatabaseSource );
ENDIAN( pHeader->dfSWDatabaseCoordX );
ENDIAN( pHeader->dfSWDatabaseCoordY );
ENDIAN( pHeader->dfDatabaseOffsetX );
ENDIAN( pHeader->dfDatabaseOffsetY );
ENDIAN( pHeader->iNextSound );
ENDIAN( pHeader->iNextPath );
ENDIAN( pHeader->iNextClippingRegion );
ENDIAN( pHeader->iNextText );
ENDIAN( pHeader->iNextBSP );
ENDIAN( pHeader->iNextSwitch );
pHeader->SWCorner.endian();
pHeader->NECorner.endian();
pHeader->Origin.endian();
ENDIAN( pHeader->dfLambertUpperLat );
ENDIAN( pHeader->dfLambertLowerLat );
ENDIAN( pHeader->iNextLightSource );
}
// virtual
void HeaderRecord::decode()
{
// SHeader *pHeader = (SHeader*)getData();
// Add node to scene graph
// _pNode = new osg::Node;
// _pNode->setName(pHeader->szIdent);
}
// virtual
bool HeaderRecord::readLocalData(Input& fr)
{
return PrimNodeRecord::readLocalData(fr);
}
// virtual
int HeaderRecord::decodeAncillary(int op)
{
/*
switch (op)
{
case COLOUR_TABLE_OP:
G_TRACE0( "\tCOLOUR_TABLE_R\n" );
break;
case MATERIAL_PALETTE_OP:
{
fltMaterialPalette rec( _pFltFile );
rec.readRecordBody();
rec.decodeRecord();
}
break;
case LIGHT_SOURCE_PALETTE_R:
G_TRACE0( "\tLIGHT_SOURCE_PALETTE_R\n" );
break;
case VERTEX_PALETTE_R:
{
fltVertexPalette rec( _pFltFile );
rec.readRecordBody();
rec.decodeRecord();
}
break;
case VERTEX_COORD_R:
{
fltVertex rec( _pFltFile );
rec.readRecordBody();
rec.decodeRecord();
}
break;
case VERTEX_NORMAL_COORD_R:
{
fltNormalVertex rec( _pFltFile );
rec.readRecordBody();
rec.decodeRecord();
}
break;
case VERTEX_NORMAL_UV_COORD_R:
{
fltNormalTextureVertex rec( _pFltFile );
rec.readRecordBody();
rec.decodeRecord();
}
break;
case VERTEX_UV_COORD_R:
{
fltTextureVertex rec( _pFltFile );
rec.readRecordBody();
rec.decodeRecord();
}
break;
default:
return FALSE;
} // end-switch
*/
return true;
}
// virtual
int HeaderRecord::decodeLevel( int op )
{
/*
switch (op)
{
case GROUP_OP:
{
fltGroup rec( _pFltFile, (csGroup*)_pContainer );
rec.readRecordBody();
rec.decodeRecord();
}
break;
default:
return FALSE;
}
*/
return true;
}
/*
void HeaderRecord::write()
{
SHeader *pHeader = (SHeader*)getData();
G_TRACE0("Header\n");
G_TRACE1("\tFormatRevisionLevel %ld\n", pHeader->diFormatRevLev);
G_TRACE1("\tDatabaseRevisionLevel %ld\n", pHeader->diDatabaseRevLev);
G_TRACE1("\tDateAndTimeOfLastRev. %s\n", pHeader->szDaTimLastRev);
G_TRACE1("\tProjection %ld\n", pHeader->diProjection);
G_TRACE1("\tDatabase Source %ld\n", pHeader->diDatabaseSource);
G_TRACE1("\tSWCorner,Lat %lf\n", pHeader->SWCorner.dfLat);
G_TRACE1("\tSWCorner,Lon %lf\n", pHeader->SWCorner.dfLon);
G_TRACE1("\tNECorner,Lat %lf\n", pHeader->NECorner.dfLat);
G_TRACE1("\tNECorner,Lon %lf\n", pHeader->NECorner.dfLon);
G_TRACE1("\tOrigin,Lat %lf\n", pHeader->Origin.dfLat);
G_TRACE1("\tOrigin,Lon %lf\n", pHeader->Origin.dfLon);
}
*/

View File

@@ -0,0 +1,126 @@
// HeaderRecord.h
#ifndef __FLT_HEADER_RECORD_H
#define __FLT_HEADER_RECORD_H
#include "opcodes.h"
#include "Record.h"
#include "RecordVisitor.h"
//namespace flt {
//class Node;
//};
namespace flt {
struct SHeader
{
SRecHeader RecHeader;
char szIdent[8]; // ID field (Not curr used)
int32 diFormatRevLev; // Format revision level
int32 diDatabaseRevLev; // Edit rev. level
char szDaTimLastRev[32]; // Date and time last rev.
int16 iNextGroup; // Next group ID number
int16 iNextLOD; // Next LOD ID number
int16 iNextObject; // Next object ID number
int16 iNextPolygon; // Next polygon ID number
int16 iMultDivUnit; // Unit multiplier/divisor, always = 1
uint8 swVertexCoordUnit; // Vertex coordinate units
// 0 = Meters
// 1 = Kilometers
// 4 = Feet
// 5 = Inches
// 8 = Nautical miles
uint8 swTexWhite; // if TRUE set texwhite on new polygons
int32 diFlags; // Flags (bits, from left to right)
// 0 = Save vertex normals
// 1-31 Spare
int32 diNotUsed_1[6]; // Not Used
int32 diProjection; // Projection Type
// 0 = Flat Earth
// 1 = Trapezoidal
// 2 = Round Earth
// 3 = Lambert
// 4 = UTM
// 5 = Geodetic
// 6 = Geocentric
int32 diNotUsed_2[7]; // Not Used
int16 iNextDegOfFreedom; // Next degree of freedom ID number
int16 iVertexStorage; // Vertex Storage Type
// 1 = Double Precision Float
int32 diDatabaseSource; // Database Source
// 100 = OpenFlight
// 200 = DIG I/DIG II
// 300 = Evans and Sutherland CT5A/CT6
// 400 = PSP DIG
// 600 = General Electric CIV/CV / PT2000
// 700 = Evans and Sutherland GDF
float64 dfSWDatabaseCoordX; // Southwest Database Coordinate (x,y)
float64 dfSWDatabaseCoordY;
float64 dfDatabaseOffsetX; // Delta (x,y) to Place Database
float64 dfDatabaseOffsetY;
int16 iNextSound; // Next Sound Bead Id
int16 iNextPath; // Next Path Bead ID
int32 diReserved_1[2]; // Reserved for MultiGen
int16 iNextClippingRegion;// Next Clipping Region Bead ID
int16 iNextText; // Next Text Bead ID
int16 iNextBSP; // Next BSP ID
int16 iNextSwitch; // Next Switch Bead ID
int32 diReserved_2; // Reserved
float64x2 SWCorner; // South West Corner Lat/Lon (NB: dec. degrees)
float64x2 NECorner; // North East Corner Lat/Lon (NB: dec. degrees)
float64x2 Origin; // Origin Lat/Lon (NB: dec. degrees, not radians)
float64 dfLambertUpperLat; // Lambert Upper Latitude
float64 dfLambertLowerLat; // Lambert Lower Latitude
int16 iNextLightSource; // Next Light Source ID Number
int16 iReserved_3; // Reserved
int16 iNextRoad; // Next road bead ID number
int16 iNextCat; // Next CAT bead ID number
int16 iReserved_4[4]; // Reserved
int32 diEllipsoid; // Earth ellipsoid model
// 0 - WGS 1984
// 1 - WGS 1972
// 2 - Bessel
// 3 - Clarke 1866
// 4 - NAD 1927
};
class HeaderRecord : public PrimNodeRecord
{
public:
HeaderRecord();
virtual Record* clone() const { return new HeaderRecord(); }
virtual const char* className() const { return "HeaderRecord"; }
virtual int classOpcode() const { return HEADER_OP; }
virtual int sizeofData() const { return sizeof(SHeader); }
virtual void accept(RecordVisitor& rv) { rv.apply(*this); }
// virtual void traverse(RecordVisitor& rv);
SHeader* getData() const { return (SHeader*)_pData; }
virtual const std::string getName( void ) const { return std::string(getData()->szIdent); }
protected:
virtual ~HeaderRecord();
virtual void endian();
virtual void decode();
virtual bool readLocalData(Input& fr);
// virtual bool writeLocalData(Output& fw);
virtual int decodeAncillary(int op);
virtual int decodeLevel(int op);
private:
// vertex pool
// osg::Node* _pNode;
};
}; // end namespace flt
#endif

View File

@@ -0,0 +1,202 @@
// Input.cpp
#include <string>
#include <malloc.h>
#include <osg/Notify>
#include "Input.h"
#include "Record.h"
#include "Registry.h"
#ifdef __sgi
using std::string;
#endif
#ifdef OSG_USE_IO_DOT_H
#include <iostream.h>
#else
#include <iostream>
using namespace std;
#endif
using namespace flt;
FileInput::FileInput()
{
_init();
}
FileInput::~FileInput()
{
close();
}
void FileInput::_init()
{
_lRecOffset = 0L;
_file = NULL;
_eof = true;
}
size_t FileInput::_read(void *buffer, size_t size)
{
if (_eof) return 0;
size_t nItemsRead = ::fread(buffer, size, 1, _file);
if (nItemsRead != 1)
_eof = true;
return nItemsRead;
}
bool FileInput::eof()
{
return _eof;
}
bool FileInput::open(const std::string& fileName)
{
_file=::fopen( fileName.c_str(), "rb");
if (_file == NULL) return false;
_eof = false;
return true;
}
void FileInput::close()
{
if (_file) ::fclose(_file);
_init();
}
bool FileInput::rewindLast()
{
if (_file == NULL) return false;
return (fseek(_file, _lRecOffset, SEEK_SET) == 0);
}
long FileInput::offset()
{
return _lRecOffset;
}
// read opcode and size
bool FileInput::_readHeader(SRecHeader* pHdr)
{
int nItemsRead;
_lRecOffset = ::ftell( _file ); // Save file position for rewind operation
// Read record header (4 bytes)
nItemsRead = _read(pHdr, sizeof(SRecHeader));
if (nItemsRead != 1)
return false;
if (isLittleEndianMachine())
pHdr->endian();
if ((unsigned)pHdr->length() < sizeof(SRecHeader))
return false;
return true;
}
bool FileInput::_readBody(SRecHeader* pData)
{
// Read record body
int nBodySize = pData->length() - sizeof(SRecHeader);
if (nBodySize > 0)
{
int nItemsRead = _read(pData+1, nBodySize);
if (nItemsRead != 1)
return false;
}
return true;
}
SRecHeader* FileInput::readRecord()
{
SRecHeader hdr;
SRecHeader* pData;
if (!_readHeader(&hdr))
return NULL;
// Allocate buffer for record (including header)
pData = (SRecHeader*)::malloc(hdr.length());
if (pData == NULL)
return NULL;
*pData = hdr;
// Some records contains only the header
if (hdr.length() == sizeof(SRecHeader))
return pData;
if (!_readBody(pData))
return NULL;
return pData;
}
Record* Input::readCreateRecord()
{
SRecHeader* pData = readRecord();
if (pData == NULL) return NULL;
// find matching record prototype class
Record* pProto = Registry::instance()->getRecordProto(pData->opcode());
if (pProto == NULL)
pProto = Registry::instance()->getRecordProto(0);
if (pProto == NULL)
{
// Should not be possible to end up here!
osg::notify(osg::INFO) << "UnknownRecord not in registry!" << endl;
::free(pData);
return NULL;
}
// clone protoype
Record* pRec = pProto->cloneRecord(pData);
if (pRec == NULL)
{
osg::notify(osg::INFO) << "Can't clone record!" << endl;
::free(pData);
return NULL;
}
#if 0
osg::notify(osg::INFO) << "class=" << pRec->className();
osg::notify(osg::INFO) << " op=" << pRec->getOpcode();
osg::notify(osg::INFO) << " name=" << pRec->getName();
osg::notify(osg::INFO) << " offset=" << offset() << endl;
#endif
if (isLittleEndianMachine()) // From Intel with love :-(
pRec->endian();
return pRec;
}

108
src/osgPlugins/flt/Input.h Normal file
View File

@@ -0,0 +1,108 @@
#ifndef __FLT_INPUT_H
#define __FLT_INPUT_H
#include "Record.h"
#include <map>
#include <list>
#include <string>
#include "stdio.h"
namespace osg {
class Object;
class Image;
class Node;
};
namespace flt {
class Record;
class Input
{
public:
Input() {}
virtual SRecHeader* readRecord() = 0;
virtual bool eof() = 0;
virtual bool rewindLast() = 0;
virtual long offset() = 0;
Record* readCreateRecord();
protected:
/** disallow creation of Objects on the stack.*/
virtual ~Input() {}
private:
virtual bool _readHeader(SRecHeader* pHdr) = 0;
virtual bool _readBody(SRecHeader* pData) = 0;
};
/** Class for managing the reading of binary .flt files.*/
class FileInput : public Input
{
public:
FileInput();
virtual ~FileInput();
bool open(const std::string& fileName);
void close();
virtual bool eof();
virtual bool rewindLast();
virtual long offset();
virtual SRecHeader* readRecord();
private:
virtual bool _readHeader(SRecHeader* pHdr);
virtual bool _readBody(SRecHeader* pData);
void _init();
size_t _read(void *buffer, size_t size);
FILE* _file;
bool _eof;
long _lRecOffset;
};
class MemInput : public Input
{
public:
MemInput();
virtual ~MemInput();
bool open(SRecHeader* pHdr);
void close();
virtual bool eof();
virtual bool rewindLast();
virtual long offset();
virtual SRecHeader* readRecord();
private:
virtual bool _readHeader(SRecHeader* pHdr);
virtual bool _readBody(SRecHeader* pData);
void _init();
size_t _read(void *buffer, size_t size);
bool _eof;
long _lRecOffset;
};
}; // end namespace flt
#endif // __FLT_INPUT_H

View File

@@ -0,0 +1,62 @@
// InstanceRecords.cpp
#include "flt.h"
#include "Registry.h"
#include "InstanceRecords.h"
using namespace flt;
////////////////////////////////////////////////////////////////////
//
// InstanceDefinitionRecord
//
////////////////////////////////////////////////////////////////////
RegisterRecordProxy<InstanceDefinitionRecord> g_InstanceDefinitionProxy;
InstanceDefinitionRecord::InstanceDefinitionRecord()
{
}
// virtual
InstanceDefinitionRecord::~InstanceDefinitionRecord()
{
}
void InstanceDefinitionRecord::endian()
{
}
////////////////////////////////////////////////////////////////////
//
// InstanceReferenceRecord
//
////////////////////////////////////////////////////////////////////
RegisterRecordProxy<InstanceReferenceRecord> g_InstanceReferenceProxy;
InstanceReferenceRecord::InstanceReferenceRecord()
{
}
// virtual
InstanceReferenceRecord::~InstanceReferenceRecord()
{
}
void InstanceReferenceRecord::endian()
{
}

View File

@@ -0,0 +1,85 @@
// InstanceRecords.h
#ifndef __FLT_INSTANCE_RECORDS_H
#define __FLT_INSTANCE_RECORDS_H
#include "opcodes.h"
#include "Record.h"
#include "RecordVisitor.h"
namespace flt {
////////////////////////////////////////////////////////////////////
//
// InstanceDefinitionRecord
//
////////////////////////////////////////////////////////////////////
typedef struct InstanceDefinitionTag
{
SRecHeader RecHeader;
}SInstanceDefinition;
class InstanceDefinitionRecord : public PrimNodeRecord
{
public:
InstanceDefinitionRecord();
virtual Record* clone() const { return new InstanceDefinitionRecord(); }
virtual const char* className() const { return "InstanceDefinitionRecord"; }
virtual int classOpcode() const { return INSTANCE_DEFINITION_OP; }
virtual void accept(RecordVisitor& rv) { rv.apply(*this); }
// virtual void traverse(RecordVisitor& rv);
SInstanceDefinition* getData() const { return (SInstanceDefinition*)_pData; }
protected:
virtual ~InstanceDefinitionRecord();
virtual void endian();
};
////////////////////////////////////////////////////////////////////
//
// InstanceReferenceRecord
//
////////////////////////////////////////////////////////////////////
typedef struct InstanceReferenceTag
{
SRecHeader RecHeader;
}SInstanceReference;
class InstanceReferenceRecord : public PrimNodeRecord
{
public:
InstanceReferenceRecord();
virtual Record* clone() const { return new InstanceReferenceRecord(); }
virtual const char* className() const { return "InstanceReferenceRecord"; }
virtual int classOpcode() const { return INSTANCE_REFERENCE_OP; }
virtual void accept(RecordVisitor& rv) { rv.apply(*this); }
// virtual void traverse(RecordVisitor& rv);
SInstanceReference* getData() const { return (SInstanceReference*)_pData; }
protected:
virtual ~InstanceReferenceRecord();
virtual void endian();
};
}; // end namespace flt
#endif

View File

@@ -0,0 +1,73 @@
// LightPointRecord.cpp
#include "flt.h"
#include "Registry.h"
#include "LightPointRecord.h"
using namespace flt;
////////////////////////////////////////////////////////////////////
//
// LightPointRecord
//
////////////////////////////////////////////////////////////////////
RegisterRecordProxy<LightPointRecord> g_LightPointProxy;
LightPointRecord::LightPointRecord()
{
}
// virtual
LightPointRecord::~LightPointRecord()
{
}
void LightPointRecord::endian()
{
SLightPoint *pSLightPoint = (SLightPoint*)getData();
ENDIAN( pSLightPoint->iMaterial );
ENDIAN( pSLightPoint->iFeature );
ENDIAN( pSLightPoint->diMode );
ENDIAN( pSLightPoint->sfIntensityFront );
ENDIAN( pSLightPoint->sfIntensityBack );
ENDIAN( pSLightPoint->sfMinDefocus );
ENDIAN( pSLightPoint->sfMaxDefocus );
ENDIAN( pSLightPoint->diFadeMode );
ENDIAN( pSLightPoint->diFogPunchMode );
ENDIAN( pSLightPoint->diDirectionalMode );
ENDIAN( pSLightPoint->diRangeMode );
ENDIAN( pSLightPoint->sfMinPixelSize );
ENDIAN( pSLightPoint->sfMaxPixelSize );
ENDIAN( pSLightPoint->afActualPixelSize );
ENDIAN( pSLightPoint->sfTranspFalloff );
ENDIAN( pSLightPoint->sfTranspFalloffExponent );
ENDIAN( pSLightPoint->sfTranspFalloffScalar );
ENDIAN( pSLightPoint->sfTranspFalloffClamp );
ENDIAN( pSLightPoint->sfFog );
ENDIAN( pSLightPoint->sfReserved );
ENDIAN( pSLightPoint->sfSize );
ENDIAN( pSLightPoint->diDirection );
ENDIAN( pSLightPoint->sfLobeHoriz );
ENDIAN( pSLightPoint->sfLobeVert );
ENDIAN( pSLightPoint->sfLobeRoll );
ENDIAN( pSLightPoint->sfFalloff );
ENDIAN( pSLightPoint->sfAmbientIntensity );
ENDIAN( pSLightPoint->sfAnimPeriod );
ENDIAN( pSLightPoint->sfAnimPhaseDelay );
ENDIAN( pSLightPoint->sfAnimPeriodEnable );
ENDIAN( pSLightPoint->sfSignificance );
ENDIAN( pSLightPoint->sfDrawOrder );
ENDIAN( pSLightPoint->sfFlags );
pSLightPoint->animRot.endian();
}

View File

@@ -0,0 +1,135 @@
// LightPointRecord.h
#ifndef __FLT_LIGHT_POINT_RECORD_H
#define __FLT_LIGHT_POINT_RECORD_H
#include "opcodes.h"
#include "Record.h"
#include "RecordVisitor.h"
namespace flt {
struct SLightPoint
{
SRecHeader RecHeader;
char szIdent[8]; // 7 char ASCII ID; 0 terminates
int16 iMaterial; // Surface material code (for DFAD)
int16 iFeature; // Feature ID (for DFAD)
color32 dwBackColor; // Back color for all bidirectional points
int32 diMode; // Display mode
// 0 = RASTER
// 1 = CALLIGRAPHIC
// 2 = EITHER
float32 sfIntensityFront; // Intensity - scalar for front colors
float32 sfIntensityBack; // - scalar for back color
float32 sfMinDefocus; // Minimum defocus - limit (0.0 - 1.0) for calligraphic points
float32 sfMaxDefocus; // Maximum defocus - limit (0.0 - 1.0) for calligraphic points
int32 diFadeMode; // Fading mode
// 0 = enable perspective fading calculations
// 1 = disable calculations
int32 diFogPunchMode; // Fog Punch mode
// 0 = enable fog punch through calculations
// 1 = disable calculations
int32 diDirectionalMode; // Directional mode
// 0 = enable directional calculations
// 1 = disable calculations
int32 diRangeMode; // Range mode
// 0 = use depth (Z) buffer calculation
// 1 = use slant range calculation
float32 sfMinPixelSize; // Minimum pixel size
// Minimum diameter of points in pixels
float32 sfMaxPixelSize; // Maximum pixel size
// Maximum diameter of points in pixels
float32 afActualPixelSize; // Actual size
// Actual diameter of points in database coordinates
float32 sfTranspFalloff; // Transparent falloff pixel size
// Diameter in pixels when points become transparent
float32 sfTranspFalloffExponent; // Transparent falloff exponent
// >= 0 - falloff multiplier exponent (1.0 = linear falloff)
float32 sfTranspFalloffScalar; // Transparent falloff scalar
// > 0 - falloff multiplier scale factor
float32 sfTranspFalloffClamp; // Transparent falloff clamp
// Minimum permissible falloff multiplier result
float32 sfFog; // Fog scalar
// >= 0 - adjusts range of points for punch threw effect.
float32 sfReserved;
float32 sfSize; // Size difference threshold
// Point size transition hint to renderer
int32 diDirection; // Directional type
// 0 = OMNIDIRECTIONAL
// 1 = UNIDIRECTIONAL
// 2 = BIDIRECTIONAL
float32 sfLobeHoriz; // Horizontal lobe angle [degrees]
float32 sfLobeVert; // Vertical lobe angle [degrees]
float32 sfLobeRoll; // Rotation of lobe about local Y axis [degrees]
float32 sfFalloff; // Directional falloff exponent
// >= 0 - falloff multiplier exponent
// (1.0 = linear falloff)
float32 sfAmbientIntensity; // Directional ambient intensity
float32 sfAnimPeriod; // Animation period [seconds]
float32 sfAnimPhaseDelay; // Animation phase delay [seconds]
float32 sfAnimPeriodEnable; // Animation enabled period [seconds]
float32 sfSignificance; // Drop out priority for RASCAL lights (0.0 - 1.0)
int32 sfDrawOrder; // Calligraphic draw order
uint32 sfFlags; // Flags (bits, from left to right)
// 0 = reserved
// 1 = No back color
// TRUE = don<6F>t use back color for
// bidirectional points
// FALSE = use back color for
// bidirectional points
// 2 = reserved
// 3 = Calligraphic proximity occulting (Debunching)
// 4 = Reflective, non-emissive point
// 5-7 = Randomize intensity
// 0 = never
// 1 = low
// 2 = medium
// 3 = high
// 8 = Perspective mode
// 9 = Flashing
// 10 = Rotating
// 11 = Rotate Counter Clockwise
// Direction of rotation about local Z axis
// 12 = reserved
// 13-14 = Quality
// 0 = Low
// 1 = Medium
// 2 = High
// 3 = Undefined
// 15 = Visible during day
// 16 = Visible during dusk
// 17 = Visible during night
// 18-31 = Spare
float32x3 animRot; // Axis of rotation for rotating animation
};
class LightPointRecord : public PrimNodeRecord
{
public:
LightPointRecord();
virtual Record* clone() const { return new LightPointRecord(); }
virtual const char* className() const { return "LightPointRecord"; }
virtual int classOpcode() const { return LIGHT_POINT_OP; }
virtual void accept(RecordVisitor& rv) { rv.apply(*this); }
// virtual void traverse(RecordVisitor& rv);
virtual SLightPoint* getData() const { return (SLightPoint*)_pData; }
protected:
virtual ~LightPointRecord();
virtual void endian();
};
}; // end namespace flt
#endif

View File

@@ -0,0 +1,38 @@
// LightSourcePaletteRecord.cpp
#include "flt.h"
#include "Registry.h"
#include "LightSourcePaletteRecord.h"
using namespace flt;
////////////////////////////////////////////////////////////////////
//
// LightSourcePaletteRecord
//
////////////////////////////////////////////////////////////////////
RegisterRecordProxy<LightSourcePaletteRecord> g_LightSourcePaletteProxy;
LightSourcePaletteRecord::LightSourcePaletteRecord()
{
}
// virtual
LightSourcePaletteRecord::~LightSourcePaletteRecord()
{
}
// virtual
void LightSourcePaletteRecord::endian()
{
}

View File

@@ -0,0 +1,66 @@
// LightSourcePaletteRecord.h
#ifndef __FLT_LIGHT_SOURCE_PALETTE_RECORD_H
#define __FLT_LIGHT_SOURCE_PALETTE_RECORD_H
#include "opcodes.h"
#include "Record.h"
#include "RecordVisitor.h"
namespace flt {
typedef struct LightSourcePaletteTag
{
SRecHeader RecHeader;
int32 diIndex; // Palette index
int32 diReserved_1[2];
char szName[20]; // Light source name
int32 diReserved_2;
float32 sfAmbientRGBA[4]; // Alpha comp. currently unused
float32 sfDiffuseRGBA[4]; // Alpha comp. currently unused
float32 sfSpecularRGBA[4]; // Alpha comp. currently unused
int32 diLightType; // 0 = INFINITE
// 1 = LOCAL
// 2 = SPOT
int32 diReserved_3[10];
float32 sfDropoff; // Spot exponential dropoff term
float32 sfCutoff; // Spot cutoff angle (radians)
float32 sfYaw;
float32 sfPitch;
float32 sfConstantAttuenation;
float32 sfLinearAttuenation;
float32 sfQuadraticAttuenation;
int32 diModelingLight; // TRUE/FALSE
int32 diSpare[19];
} SLightSourcePalette;
class LightSourcePaletteRecord : public AncillaryRecord
{
public:
LightSourcePaletteRecord();
virtual Record* clone() const { return new LightSourcePaletteRecord(); }
virtual const char* className() const { return "LightSourcePaletteRecord"; }
virtual int classOpcode() const { return LIGHT_SOURCE_PALETTE_OP; }
virtual void accept(RecordVisitor& rv) { rv.apply(*this); }
// virtual void traverse(RecordVisitor& rv);
protected:
virtual ~LightSourcePaletteRecord();
virtual void endian();
};
}; // end namespace flt
#endif

View File

@@ -0,0 +1,47 @@
// LightSourceRecord.cpp
#include "flt.h"
#include "Registry.h"
#include "LightSourceRecord.h"
using namespace flt;
////////////////////////////////////////////////////////////////////
//
// LightSourceRecord
//
////////////////////////////////////////////////////////////////////
RegisterRecordProxy<LightSourceRecord> g_LightSourceRecordProxy;
LightSourceRecord::LightSourceRecord()
{
}
// virtual
LightSourceRecord::~LightSourceRecord()
{
}
// virtual
void LightSourceRecord::endian()
{
SLightSource *pSLightSource = (SLightSource*)getData();
ENDIAN( pSLightSource->diReserved_1 );
ENDIAN( pSLightSource->diIndex );
ENDIAN( pSLightSource->diReserved_2 );
ENDIAN( pSLightSource->dwFlags );
ENDIAN( pSLightSource->diReserved_3 );
pSLightSource->Coord.endian();
ENDIAN( pSLightSource->sfYaw );
ENDIAN( pSLightSource->sfPitch );
}

View File

@@ -0,0 +1,68 @@
// LightSourceRecord.h
#ifndef __FLT_LIGHT_SOURCE_RECORD_H
#define __FLT_LIGHT_SOURCE_RECORD_H
#include "opcodes.h"
#include "Record.h"
#include "RecordVisitor.h"
namespace flt {
////////////////////////////////////////////////////////////////////
//
// LightSourceRecord
//
////////////////////////////////////////////////////////////////////
typedef struct LightSourceTag
{
SRecHeader RecHeader;
char szIdent[8]; // 7 char ASCII ID; 0 terminates
int32 diReserved_1;
int32 diIndex; //index into lightpalette
int32 diReserved_2;
uint32 dwFlags; //bits from left to right
//0=enabled
//1=global
//2=reserve
//3=export
//4=reserved
//5-31 spare
int32 diReserved_3;
float64x3 Coord; // x,y,z coordinate
float32 sfYaw;
float32 sfPitch;
} SLightSource;
class LightSourceRecord : public PrimNodeRecord
{
public:
LightSourceRecord();
virtual Record* clone() const { return new LightSourceRecord(); }
virtual const char* className() const { return "LightSourceRecord"; }
virtual int classOpcode() const { return LIGHT_SOURCE_OP; }
virtual void accept(RecordVisitor& rv) { rv.apply(*this); }
// virtual void traverse(RecordVisitor& rv);
protected:
virtual ~LightSourceRecord();
virtual void endian();
};
}; // end namespace flt
#endif

View File

@@ -0,0 +1,78 @@
// LodRecord.cpp
#include "flt.h"
#include "Registry.h"
#include "LodRecord.h"
using namespace flt;
////////////////////////////////////////////////////////////////////
//
// LodRecord
//
////////////////////////////////////////////////////////////////////
RegisterRecordProxy<LodRecord> g_LodProxy;
LodRecord::LodRecord()
{
}
// virtual
LodRecord::~LodRecord()
{
}
void LodRecord::endian()
{
SLevelOfDetail *pSLod = (SLevelOfDetail*)getData();
ENDIAN( pSLod->dfSwitchInDist );
ENDIAN( pSLod->dfSwitchOutDist );
ENDIAN( pSLod->iSpecialId_1 );
ENDIAN( pSLod->iSpecialId_2 );
ENDIAN( pSLod->diFlags );
pSLod->Center.endian();
ENDIAN( pSLod->dfTransitionRange );
}
////////////////////////////////////////////////////////////////////
//
// OldLodRecord
//
////////////////////////////////////////////////////////////////////
RegisterRecordProxy<OldLodRecord> g_OldLodProxy;
OldLodRecord::OldLodRecord()
{
}
// virtual
OldLodRecord::~OldLodRecord()
{
}
void OldLodRecord::endian()
{
SOldLOD *pSLod = (SOldLOD*)getData();
ENDIAN( pSLod->dfSwitchInDist );
ENDIAN( pSLod->dfSwitchOutDist );
ENDIAN( pSLod->iSpecialId_1 );
ENDIAN( pSLod->iSpecialId_2 );
ENDIAN( pSLod->diFlags );
pSLod->Center.endian();
ENDIAN( pSLod->dfTransitionRange );
}

View File

@@ -0,0 +1,115 @@
// LodRecord.h
#ifndef __FLT_LOD_RECORD_H
#define __FLT_LOD_RECORD_H
#include "opcodes.h"
#include "Record.h"
#include "RecordVisitor.h"
namespace flt {
////////////////////////////////////////////////////////////////////
//
// LodRecord
//
////////////////////////////////////////////////////////////////////
typedef struct LevelOfDetailTag
{
SRecHeader RecHeader;
char szIdent[8]; // 7 char ASCII ID; 0 terminates
int32 iSpare; // Spare
float64 dfSwitchInDist; // Switch in distance
float64 dfSwitchOutDist;// Switch out distance
int16 iSpecialId_1; // Special effects ID 1 - defined by real time
int16 iSpecialId_2; // Special effects ID 2 - defined by real time
int32 diFlags; // Flags (bits, from left to right)
// 0 = Use previous slant range
// 1 = SPT flag: 0 if replacement LOD, 1 for additive LOD
// 2 = Freeze center (don't recalculate)
// 3-31 Spare
float64x3 Center; // Center coordinate (x,y,z) of LOD block
float64 dfTransitionRange; // Transition Range for Morphing
} SLevelOfDetail;
class LodRecord : public PrimNodeRecord
{
public:
LodRecord();
virtual Record* clone() const { return new LodRecord(); }
virtual const char* className() const { return "LodRecord"; }
virtual int classOpcode() const { return LOD_OP; }
virtual int sizeofData() const { return sizeof(SLevelOfDetail); }
virtual void accept(RecordVisitor& rv) { rv.apply(*this); }
// virtual void traverse(RecordVisitor& rv);
SLevelOfDetail* getData() const { return (SLevelOfDetail*)_pData; }
virtual const std::string getName( void ) const { return std::string(getData()->szIdent); }
protected:
virtual ~LodRecord();
virtual void endian();
};
////////////////////////////////////////////////////////////////////
//
// OldLodRecord
//
////////////////////////////////////////////////////////////////////
typedef struct OldLodTag
{
SRecHeader RecHeader;
char szIdent[8]; // 7 char ASCII ID; 0 terminates
int32 iSpare; // Spare
float64 dfSwitchInDist; // Switch in distance
float64 dfSwitchOutDist;// Switch out distance
int16 iSpecialId_1; // Special effects ID 1 - defined by real time
int16 iSpecialId_2; // Special effects ID 2 - defined by real time
int32 diFlags; // Flags (bits, from left to right)
// 0 = Use previous slant range
// 1 = SPT flag: 0 if replacement LOD, 1 for additive LOD
// 2 = Freeze center (don't recalculate)
// 3-31 Spare
float64x3 Center; // Center coordinate (x,y,z) of LOD block
float64 dfTransitionRange; // Transition Range for Morphing
} SOldLOD;
class OldLodRecord : public PrimNodeRecord
{
public:
OldLodRecord();
virtual Record* clone() const { return new OldLodRecord(); }
virtual const char* className() const { return "OldLodRecord"; }
virtual int classOpcode() const { return OLD_LOD_OP; }
virtual int sizeofData() const { return sizeof(SOldLOD); }
virtual void accept(RecordVisitor& rv) { rv.apply(*this); }
// virtual void traverse(RecordVisitor& rv);
SOldLOD* getData() const { return (SOldLOD*)_pData; }
// virtual const std::string getName( void ) const { return std::string(getData()->szIdent); }
protected:
virtual ~OldLodRecord();
virtual void endian();
};
}; // end namespace flt
#endif

View File

@@ -0,0 +1,37 @@
// LongIDRecord.cpp
#include "flt.h"
#include "Registry.h"
#include "LongIDRecord.h"
using namespace flt;
////////////////////////////////////////////////////////////////////
//
// MaterialPaletteRecord
//
////////////////////////////////////////////////////////////////////
RegisterRecordProxy<LongIDRecord> g_LongIDProxy;
LongIDRecord::LongIDRecord()
{
}
// virtual
LongIDRecord::~LongIDRecord()
{
}
// virtual
void LongIDRecord::endian()
{
}

View File

@@ -0,0 +1,46 @@
// LongIDRecord.h
#ifndef __FLT_LONG_ID_RECORD_H
#define __FLT_LONG_ID_RECORD_H
#include "opcodes.h"
#include "Record.h"
#include "RecordVisitor.h"
namespace flt {
struct SLongID
{
SRecHeader RecHeader;
char szIdent[1]; // (Length - 4) ASCII ID of node
};
class LongIDRecord : public AncillaryRecord
{
public:
LongIDRecord();
virtual Record* clone() const { return new LongIDRecord(); }
virtual const char* className() const { return "LongIDRecord"; }
virtual int classOpcode() const { return LONG_ID_OP; }
virtual void accept(RecordVisitor& rv) { rv.apply(*this); }
// virtual void traverse(RecordVisitor& rv);
protected:
virtual ~LongIDRecord();
virtual void endian();
};
}; // end namespace flt
#endif

View File

View File

@@ -0,0 +1,51 @@
#!smake
include ../../../Make/makedefs
C++FILES = \
BoundingVolumeRecords.cpp\
LongIDRecord.cpp\
ColorPaletteRecord.cpp\
MaterialPaletteRecord.cpp\
CommentRecord.cpp\
ObjectRecord.cpp\
ControlRecord.cpp\
OldVertexRecords.cpp\
DofRecord.cpp\
ExtensionRecord.cpp\
ExternalRecord.cpp\
Record.cpp\
FaceRecord.cpp\
FltFile.cpp\
RecordVisitor.cpp\
GeoSetBuilder.cpp\
Registry.cpp\
GroupRecord.cpp\
SwitchRecord.cpp\
HeaderRecord.cpp\
TexturePaletteRecord.cpp\
Input.cpp\
TransformationRecords.cpp\
InstanceRecords.cpp\
UnknownRecord.cpp\
LightPointRecord.cpp\
VertexPoolRecords.cpp\
LightSourcePaletteRecord.cpp\
flt.cpp\
LightSourceRecord.cpp\
flt2osg.cpp\
LodRecord.cpp\
Pool.cpp\
TextureMappingPaletteRecord.cpp\
ReaderWriterFLT.cpp\
# PointLight.cpp\
C++FLAGS += -I../../../include
LIB = ../../../lib/osgPlugins/osgdb_flt.so
TARGET_LOADER_FILES = osgPlugins/osgdb_flt.so
include ../../../Make/makerules

View File

@@ -0,0 +1,49 @@
// MaterialPaletteRecord.cpp
#include "flt.h"
#include "Registry.h"
#include "MaterialPaletteRecord.h"
using namespace flt;
////////////////////////////////////////////////////////////////////
//
// MaterialPaletteRecord
//
////////////////////////////////////////////////////////////////////
RegisterRecordProxy<MaterialPaletteRecord> g_MaterialPaletteProxy;
MaterialPaletteRecord::MaterialPaletteRecord()
{
}
// virtual
MaterialPaletteRecord::~MaterialPaletteRecord()
{
}
// virtual
void MaterialPaletteRecord::endian()
{
SMaterial *pSMaterial = (SMaterial*)getData();
ENDIAN( pSMaterial->diIndex );
ENDIAN( pSMaterial->diFlags );
pSMaterial->Ambient.endian();
pSMaterial->Diffuse.endian();
pSMaterial->Specular.endian();
pSMaterial->Emissive.endian();
ENDIAN( pSMaterial->sfShininess );
ENDIAN( pSMaterial->sfAlpha );
}

View File

@@ -0,0 +1,60 @@
// MaterialPaletteRecord.h
#ifndef __FLT_MATERIAL_PALETTE_RECORD_H
#define __FLT_MATERIAL_PALETTE_RECORD_H
#include "opcodes.h"
#include "Record.h"
#include "RecordVisitor.h"
namespace flt {
struct SMaterial
{
SRecHeader RecHeader;
int32 diIndex;
char szName[12];
uint32 diFlags; // bit 0 Materials used
// bit 1-31 Spare
float32x3 Ambient; // Ambient component of material
float32x3 Diffuse; // Diffuse component of material
float32x3 Specular; // Specular component of material
float32x3 Emissive; // Emissive component of material
float32 sfShininess; // Shininess. [0.0-128.0]
float32 sfAlpha; // Alpha. [0.0-1.0], where 1.0 is opaque
int32 diSpare;
};
class MaterialPaletteRecord : public AncillaryRecord
{
public:
MaterialPaletteRecord();
virtual Record* clone() const { return new MaterialPaletteRecord(); }
virtual const char* className() const { return "MaterialPaletteRecord"; }
virtual int classOpcode() const { return MATERIAL_PALETTE_OP; }
virtual int sizeofData() const { return sizeof(SMaterial); }
virtual void accept(RecordVisitor& rv) { rv.apply(*this); }
// virtual void traverse(RecordVisitor& rv);
protected:
virtual ~MaterialPaletteRecord();
virtual void endian();
// virtual void decode();
// virtual bool readLocalData(Input& fr);
// virtual bool writeLocalData(Output& fw);
};
}; // end namespace flt
#endif

View File

@@ -0,0 +1,42 @@
// ObjectRecord.cpp
#include "flt.h"
#include "Registry.h"
#include "ObjectRecord.h"
using namespace flt;
////////////////////////////////////////////////////////////////////
//
// ObjectRecord
//
////////////////////////////////////////////////////////////////////
RegisterRecordProxy<ObjectRecord> g_ObjectProxy;
ObjectRecord::ObjectRecord()
{
}
// virtual
ObjectRecord::~ObjectRecord()
{
}
void ObjectRecord::endian()
{
SObject *pSObject = (SObject*)getData();
ENDIAN( pSObject->dwFlags );
ENDIAN( pSObject->iObjectRelPriority );
ENDIAN( pSObject->wTransparency );
ENDIAN( pSObject->iSpecialId_1 );
ENDIAN( pSObject->iSpecialId_2 );
ENDIAN( pSObject->iSignificance );
}

View File

@@ -0,0 +1,66 @@
// ObjectRecord.h
#ifndef __FLT_OBJECT_RECORD_H
#define __FLT_OBJECT_RECORD_H
#include "opcodes.h"
#include "Record.h"
#include "RecordVisitor.h"
namespace flt {
typedef struct ObjectTag
{
SRecHeader RecHeader;
char szIdent[8]; // 7 char ASCII ID; 0 terminates
uint32 dwFlags; // Flags (bits from to right)
// 0 = Don't display in daylight
// 1 = Don't display at dusk
// 2 = Don't display at night
// 3 = Don't illuminate
// 4 = Flat shaded
// 5 = Group's shadow object
// 6-31 Spare
int16 iObjectRelPriority; // Object relative priority
uint16 wTransparency; // Transparency factor
// = 0 opaque
// = 65535 for totally clear
int16 iSpecialId_1; // Special effects ID 1 - defined by real time
int16 iSpecialId_2; // Special effects ID 2 - defined by real time
int16 iSignificance; // Significance
int16 iSpare; // Spare
} SObject;
class ObjectRecord : public PrimNodeRecord
{
public:
ObjectRecord();
virtual Record* clone() const { return new ObjectRecord(); }
virtual const char* className() const { return "ObjectRecord"; }
virtual int classOpcode() const { return OBJECT_OP; }
virtual void accept(RecordVisitor& rv) { rv.apply(*this); }
// virtual void traverse(RecordVisitor& rv);
SObject* getData() const { return (SObject*)_pData; }
virtual const std::string getName( void ) const { return std::string(getData()->szIdent); }
protected:
virtual ~ObjectRecord();
virtual void endian();
// virtual bool readLocalData(Input& fr);
// virtual bool writeLocalData(Output& fw);
};
}; // end namespace flt
#endif

View File

@@ -0,0 +1,138 @@
// OldVertexRecords.cpp
#include "flt.h"
#include "Registry.h"
#include "OldVertexRecords.h"
using namespace flt;
////////////////////////////////////////////////////////////////////
//
// OldVertexRecord
//
////////////////////////////////////////////////////////////////////
RegisterRecordProxy<OldVertexRecord> g_OldVertexProxy;
OldVertexRecord::OldVertexRecord()
{
}
// virtual
OldVertexRecord::~OldVertexRecord()
{
}
// virtual
void OldVertexRecord::endian()
{
SOldVertex *pVertex = (SOldVertex*)getData();
ENDIAN( pVertex->v[0] );
ENDIAN( pVertex->v[1] );
ENDIAN( pVertex->v[2] );
}
/*
ostream& operator << (ostream& output, const OldVertexRecord& rec)
{
output << rec.className() << " "
<< rec.getData()->swFlags << " "
<< rec.getData()->Coord;
return output; // to enable cascading
}
*/
////////////////////////////////////////////////////////////////////
//
// OldVertexColorRecord
//
////////////////////////////////////////////////////////////////////
RegisterRecordProxy<OldVertexColorRecord> g_OldVertexColorProxy;
OldVertexColorRecord::OldVertexColorRecord()
{
}
// virtual
OldVertexColorRecord::~OldVertexColorRecord()
{
}
// virtual
void OldVertexColorRecord::endian()
{
SOldVertexColor *pVertex = (SOldVertexColor*)getData();
ENDIAN( pVertex->v[0] );
ENDIAN( pVertex->v[1] );
ENDIAN( pVertex->v[2] );
}
/*
ostream& operator << (ostream& output, const OldVertexColorRecord& rec)
{
output << rec.className() << " "
<< rec.getData()->swFlags << " "
<< rec.getData()->Coord;
return output; // to enable cascading
}
*/
////////////////////////////////////////////////////////////////////
//
// OldVertexColorNormalRecord
//
////////////////////////////////////////////////////////////////////
RegisterRecordProxy<OldVertexColorNormalRecord> g_OldVertexColorNormalProxy;
OldVertexColorNormalRecord::OldVertexColorNormalRecord()
{
}
// virtual
OldVertexColorNormalRecord::~OldVertexColorNormalRecord()
{
}
// virtual
void OldVertexColorNormalRecord::endian()
{
SOldVertexColorNormal *pVertex = (SOldVertexColorNormal*)getData();
ENDIAN( pVertex->Coord[0] );
ENDIAN( pVertex->Coord[1] );
ENDIAN( pVertex->Coord[2] );
ENDIAN( pVertex->swColor );
ENDIAN( pVertex->swFlags );
// ENDIAN( pVertex->Normal[0] );
// ENDIAN( pVertex->Normal[1] );
// ENDIAN( pVertex->Normal[2] );
}
/*
ostream& operator << (ostream& output, const OldVertexColorNormalRecord& rec)
{
output << rec.className() << " "
<< rec.getData()->swFlags << " "
<< rec.getData()->Coord;
return output; // to enable cascading
}
*/

View File

@@ -0,0 +1,137 @@
// OldVertexRecords.h
#ifndef __FLT_OLD_VERTEX_RECORDS_H
#define __FLT_OLD_VERTEX_RECORDS_H
#include <map>
#include "opcodes.h"
#include "Record.h"
#include "RecordVisitor.h"
#ifdef OSG_USE_IO_DOT_H
#include <iostream.h>
#else
#include <iostream>
using namespace std;
#endif
namespace flt {
////////////////////////////////////////////////////////////////////
//
// OldVertexRecord
//
////////////////////////////////////////////////////////////////////
typedef struct OldVertexTag
{
SRecHeader RecHeader;
int32 v[3];
} SOldVertex;
class OldVertexRecord : public PrimNodeRecord
{
public:
OldVertexRecord();
virtual Record* clone() const { return new OldVertexRecord(); }
virtual const char* className() const { return "OldVertexRecord"; }
virtual int classOpcode() const { return OLD_VERTEX_OP; }
virtual int sizeofData() const { return sizeof(SOldVertex); }
virtual void accept(RecordVisitor& rv) { rv.apply(*this); }
// virtual void traverse(RecordVisitor& rv);
virtual SOldVertex* getData() const { return (SOldVertex*)_pData; }
// friend ostream& operator << (ostream& output, const OldVertexRecord& rec);
protected:
virtual ~OldVertexRecord();
virtual void endian();
};
////////////////////////////////////////////////////////////////////
//
// OldVertexColorRecord
//
////////////////////////////////////////////////////////////////////
typedef struct OldVertexColorTag
{
SRecHeader RecHeader;
int32 v[3];
/*
float64_t x;
float64_t y;
float64_t z;
uint16_t color_name_index;
uint16_t flags;
uint32_t packed_color;
uint32_t color_index;
*/
} SOldVertexColor;
class OldVertexColorRecord : public PrimNodeRecord
{
public:
OldVertexColorRecord();
virtual Record* clone() const { return new OldVertexColorRecord(); }
virtual const char* className() const { return "OldVertexColorRecord"; }
virtual int classOpcode() const { return OLD_VERTEX_COLOR_OP; }
virtual int sizeofData() const { return sizeof(SOldVertexColor); }
virtual void accept(RecordVisitor& rv) { rv.apply(*this); }
// virtual void traverse(RecordVisitor& rv);
virtual SOldVertexColor* getData() const { return (SOldVertexColor*)_pData; }
// friend ostream& operator << (ostream& output, const OldVertexColorRecord& rec);
protected:
virtual ~OldVertexColorRecord();
virtual void endian();
};
////////////////////////////////////////////////////////////////////
//
// OldVertexColorNormalRecord
//
////////////////////////////////////////////////////////////////////
typedef struct OldVertexColorNormalTag
{
SRecHeader RecHeader;
int32 Coord[3];
uint16 swColor; // Color Name Index
uint16 swFlags; // Flags (bits, from left to right)
int16 Normal[3];
} SOldVertexColorNormal;
class OldVertexColorNormalRecord : public PrimNodeRecord
{
public:
OldVertexColorNormalRecord();
virtual Record* clone() const { return new OldVertexColorNormalRecord(); }
virtual const char* className() const { return "OldVertexColorNormalRecord"; }
virtual int classOpcode() const { return OLD_VERTEX_COLOR_NORMAL_OP; }
virtual int sizeofData() const { return sizeof(SOldVertexColorNormal); }
virtual void accept(RecordVisitor& rv) { rv.apply(*this); }
// virtual void traverse(RecordVisitor& rv);
virtual SOldVertexColorNormal* getData() const { return (SOldVertexColorNormal*)_pData; }
// friend ostream& operator << (ostream& output, const OldVertexColorNormalRecord& rec);
protected:
virtual ~OldVertexColorNormalRecord();
virtual void endian();
};
}; // end namespace flt
#endif // __FLT_VERTEX_POOL_RECORDS_H

150
src/osgPlugins/flt/Pool.cpp Normal file
View File

@@ -0,0 +1,150 @@
// Pool.cpp
#include <osg/Vec4>
#include <osg/Texture>
#include "Pool.h"
using namespace flt;
ColorPool::ColorPool()
{
}
// virtual
ColorPool::~ColorPool()
{
eraseAll();
}
osg::Vec4 ColorPool::getColor(int nColorIndex)
{
osg::Vec4 col(1,1,1,1);
if (nColorIndex >= 0)
{
int index = nColorIndex / 128;
float intensity = (nColorIndex % 128) / 128.0f;
ColorName* cn = getColorName(index);
if (cn)
col = cn->getColor();
col[0] *= intensity;
col[1] *= intensity;
col[2] *= intensity;
}
return col;
}
void ColorPool::regisiterColor(int nIndex, const osg::Vec4& color)
{
if (nIndex >= 0)
{
ColorName* colorname = new ColorName;
colorname->setColor(color);
_colorNameMap[nIndex] = colorname;
}
}
ColorPool::ColorName* ColorPool::getColorName(int nIndex)
{
ColorNameMap::iterator itr = _colorNameMap.find(nIndex);
if (itr != _colorNameMap.end())
return (*itr).second;
return NULL;
}
void ColorPool::eraseAll()
{
for(ColorNameMap::iterator itr=_colorNameMap.begin();
itr!=_colorNameMap.end();
++itr)
{
ColorName* colorname = (*itr).second;
if (colorname)
delete colorname;
}
_colorNameMap.erase(_colorNameMap.begin(), _colorNameMap.end());
}
////////////////////////////////////////////////////////////////////
TexturePool::TexturePool()
{
}
// virtual
TexturePool::~TexturePool()
{
eraseAll();
}
osg::Texture* TexturePool::getTexture(int nIndex)
{
TexturePaletteMap::iterator fitr = _textureMap.find(nIndex);
if (fitr != _textureMap.end())
return (*fitr).second;
else
return NULL;
}
void TexturePool::regisiterTexture(int nIndex, osg::Texture* osgTexture)
{
_textureMap[nIndex] = osgTexture;
}
void TexturePool::eraseAll()
{
_textureMap.erase(_textureMap.begin(), _textureMap.end());
}
////////////////////////////////////////////////////////////////////
MaterialPool::MaterialPool()
{
}
// virtual
MaterialPool::~MaterialPool()
{
eraseAll();
}
SMaterial* MaterialPool::getMaterial(int nIndex)
{
MaterialMap::iterator fitr = _MaterialMap.find(nIndex);
if (fitr != _MaterialMap.end())
return (*fitr).second;
return NULL;
}
void MaterialPool::regisiterMaterial(int nIndex, SMaterial* material)
{
_MaterialMap[nIndex] = material;
}
void MaterialPool::eraseAll()
{
_MaterialMap.erase(_MaterialMap.begin(), _MaterialMap.end());
}

93
src/osgPlugins/flt/Pool.h Normal file
View File

@@ -0,0 +1,93 @@
// Pool.cpp
#ifndef __FLT_POOL_H
#define __FLT_POOL_H
#include <string>
#include <algorithm>
#include <map>
//#include <vector>
#include <osg/Vec4>
#include <osg/Texture>
namespace flt {
struct SMaterial;
class ColorPool
{
public:
ColorPool();
virtual ~ColorPool();
osg::Vec4 getColor(int nColorIndex);
void regisiterColor(int nIndex, const osg::Vec4& color);
private:
class ColorName
{
public:
void setName( const std::string& name ) { _name = name; }
const std::string& getName( void ) { return _name; }
void setColor(const osg::Vec4& color ) { _color = color; }
osg::Vec4& getColor() { return _color; }
private:
osg::Vec4 _color;
std::string _name;
};
void eraseAll();
ColorName* getColorName(int nIndex);
typedef std::map<int,ColorName*>ColorNameMap;
ColorNameMap _colorNameMap;
};
class TexturePool
{
public:
TexturePool();
virtual ~TexturePool();
osg::Texture* getTexture(int nIndex);
void regisiterTexture(int nIndex, osg::Texture* osgTexture);
private:
void eraseAll();
typedef std::map<int,osg::Texture*> TexturePaletteMap;
TexturePaletteMap _textureMap;
};
class MaterialPool
{
public:
MaterialPool();
virtual ~MaterialPool();
SMaterial* getMaterial(int nIndex);
void regisiterMaterial(int nIndex, SMaterial* material);
private:
void eraseAll();
typedef std::map<int,SMaterial*> MaterialMap;
MaterialMap _MaterialMap;
};
}; // end namespace flt
#endif

View File

@@ -0,0 +1,41 @@
// ReaderWriterFLT.cpp
#ifdef WIN32
#pragma warning( disable : 4786 )
#endif
#include "ReaderWriterFLT.h"
#include "FltFile.h"
#include <osg/Registry>
#include <osg/Object>
#include <osg/Node>
using namespace flt;
osg::Object* ReaderWriterFLT::readObject(const std::string& fileName)
{
FltFile read;
return read.readObject(fileName);
}
osg::Node* ReaderWriterFLT::readNode(const std::string& fileName)
{
FltFile read;
return read.readNode(fileName);
}
// now register with Registry to instantiate the above
// reader/writer.
osg::RegisterReaderWriterProxy<ReaderWriterFLT> g_fltReaderWriterProxy;

View File

@@ -0,0 +1,66 @@
//
// OpenFlight<68> loader for Open Scene Graph
//
// Copyright (C) 2000 Brede Johansen
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would be
// appreciated but is not required.
// 2. Altered source versions must be plainly marked as such, and must not be
// misrepresented as being the original software.
// 3. This notice may not be removed or altered from any source distribution.
//
// The Open Scene Graph (OSG) is a cross platform C++/OpenGL library for
// real-time rendering of large 3D photo-realistic models.
// The OSG homepage is http://www.openscenegraph.org/
//
// MultiGen, OpenFlight, and Flight Format are registered trademarks of MultiGen Inc.
//
#ifndef __FLT_READER_WRITER_FLT_H
#define __FLT_READER_WRITER_FLT_H
#include <string>
#include <osg/Registry>
#include <osg/Object>
#include <osg/Node>
#include "export.h"
namespace flt {
class FLT_EXPORT ReaderWriterFLT : public osg::ReaderWriter
{
public:
virtual const char* className() { return "FLT Reader/Writer"; }
virtual bool acceptsExtension(const std::string& extension) { return extension=="flt"; }
virtual bool writeObject(osg::Object& obj,const std::string& fileName) { return false; }
virtual bool writeNode(osg::Node& node,const std::string& fileName) { return false; }
virtual osg::Object* readObject(const std::string& fileName);
virtual osg::Node* readNode(const std::string& fileName);
};
}; // end namespace flt
#endif // __FLT_CONTROL_RECORD_H

View File

@@ -0,0 +1,338 @@
// Record.cpp
#include <algorithm>
#include <stdio.h>
#include <malloc.h>
#include <osg/Notify>
#include "export.h"
#include "flt.h"
#include "Registry.h"
#include "Record.h"
#include "FltRecords.h"
#include "UnknownRecord.h"
#include "opcodes.h"
#include "Input.h"
#include "RecordVisitor.h"
#ifdef OSG_USE_IO_DOT_H
#include <iostream.h>
#else
#include <iostream>
using namespace std;
#endif
using namespace flt;
////////////////////////////////////////////////////////////////////
//
// Record
//
////////////////////////////////////////////////////////////////////
Record::Record()
{
_pData = NULL;
_pParent = NULL;
}
Record::~Record()
{
if (_pData) ::free(_pData);
}
Record* Record::cloneRecord(SRecHeader* pData)
{
Record* pRec = clone();
if (pRec->sizeofData() > pData->length())
pData = (SRecHeader*)::realloc(pData, pRec->sizeofData());
pRec->_pData = (SRecHeader*)pData;
return pRec;
}
void Record::accept(RecordVisitor& rv)
{
rv.apply(*this);
}
/*
void Record::ascend(RecordVisitor& rv)
{
std::for_each(_parents.begin(),_parents.end(),RecordAcceptOp(rv));
}
*/
ostream& operator << (ostream& output, const Record& rec)
{
output << rec.className()
<< " op=" << rec.getOpcode()
<< " size=" << rec.getSize();
return output; // to enable cascading
}
////////////////////////////////////////////////////////////////////
//
// PrimNodeRecord
//
////////////////////////////////////////////////////////////////////
PrimNodeRecord::PrimNodeRecord()
{
}
// virtual
PrimNodeRecord::~PrimNodeRecord()
{
removeAllChildren();
}
// virtual
void PrimNodeRecord::accept(RecordVisitor& rv)
{
rv.apply(*this);
}
// virtual
void PrimNodeRecord::traverse(RecordVisitor& rv)
{
for(ChildList::iterator itr=_children.begin();
itr!=_children.end();
++itr)
{
(*itr)->accept(rv);
}
}
void PrimNodeRecord::addChild( Record *child )
{
if (child==NULL) return;
ChildList::iterator itr = std::find(_children.begin(),_children.end(),child);
if (itr==_children.end())
{
// add child to group.
_children.push_back(child);
// register as parent of child.
#if 0
// child->_parents.push_back(this);
#else
child->_pParent = this;
#endif
}
}
void PrimNodeRecord::removeChild( Record *child )
{
if (child==NULL) return;
ChildList::iterator itr = std::find(_children.begin(),_children.end(),child);
if (itr!=_children.end())
{
_children.erase(itr);
// ParentList::iterator pitr = std::find(child->_parents.begin(),child->_parents.end(),child);
// if (pitr!=child->_parents.end()) child->_parents.erase(pitr);
}
}
void PrimNodeRecord::removeAllChildren()
{
_children.erase(_children.begin(),_children.end());
}
bool PrimNodeRecord::readExtensions(Input& fr)
{
Record* pRec;
while ((pRec=readNextRecord(fr)))
{
if (pRec->isOfType(POP_EXTENSION_OP)) return true;
// ignore extensions for now
}
return false;
}
bool PrimNodeRecord::readLevel(Input& fr)
{
Record* pRec;
while ((pRec=readNextRecord(fr)))
{
if (pRec->isOfType(POP_LEVEL_OP)) return true;
if (!pRec->isPrimaryNode())
{
osg::notify(osg::WARN) << "Non primary record found as child. op=";
osg::notify(osg::WARN) << pRec->getOpcode() << endl;
return false;
}
addChild(pRec);
if (!((PrimNodeRecord*)pRec)->readLocalData(fr))
return false;
}
return false;
}
Record* PrimNodeRecord::readNextRecord(Input& fr)
{
Record* pRec;
while ((pRec=fr.readCreateRecord()))
{
switch (pRec->getOpcode())
{
case PUSH_EXTENSION_OP:
readExtensions(fr);
break;
case PUSH_LEVEL_OP:
readLevel(fr);
break;
default:
return pRec;
}
}
return pRec;
}
// virtual
bool PrimNodeRecord::readLocalData(Input& fr)
{
Record* pRec;
while ((pRec=readNextRecord(fr)))
{
// if (pRec->isOfType(PUSH_LEVEL_OP))
// return true;
if (!pRec->isAncillaryRecord())
return fr.rewindLast();
addChild(pRec);
}
return false;
}
/*
// virtual
bool PrimNodeRecord::readLocalData(Input& fr)
{
Record* pRec;
int until_op = 0;
//
// read ancillary records
//
while (pRec=fr.readCreateRecord())
{
// read extension records
if (pRec->isOfType(PUSH_EXTENSION_OP))
{
while (pRec=fr.readCreateRecord())
{
if (pRec->isOfType(POP_EXTENSION_OP))
{
pRec=fr.readCreateRecord();
break;
}
};
}
if (!pRec->isAncillaryRecord())
break;
addChild(pRec);
};
// if (pRec == NULL) return false;
if (pRec == NULL) return false;
if (pRec->getOpcode() != PUSH_LEVEL_OP)
{
// if (pRec->isPrimaryNode())
return fr.rewindLast();
// osg::notify(osg::INFO) << "Missing PUSH_LEVEL_OP" << endl;
// return false;
}
//
// read primary node records
//
while (pRec=fr.readCreateRecord())
{
if (pRec->getOpcode() == POP_LEVEL_OP) return true;
if (pRec->isPrimaryNode())
{
addChild(pRec);
if (!((PrimNodeRecord*)pRec)->readLocalData(fr))
return false;
}
}
if (pRec == NULL)
return false;
return true;
}
*/
////////////////////////////////////////////////////////////////////
//
// ControlRecord
//
////////////////////////////////////////////////////////////////////
// virtual
void ControlRecord::accept(RecordVisitor& rv)
{
rv.apply(*this);
}
////////////////////////////////////////////////////////////////////
//
// AncillaryRecord
//
////////////////////////////////////////////////////////////////////
// virtual
void AncillaryRecord::accept(RecordVisitor& rv)
{
rv.apply(*this);
}

239
src/osgPlugins/flt/Record.h Normal file
View File

@@ -0,0 +1,239 @@
#ifndef __FLT_RECORD_H
#define __FLT_RECORD_H
#include <string>
#include <vector>
#include <osg/Referenced>
#include "FltRecords.h"
#ifdef OSG_USE_IO_DOT_H
#include <iostream.h>
#else
#include <iostream>
using namespace std;
#endif
namespace flt {
class Record;
class Input;
class RecordVisitor;
class FltFile;
class PrimNodeRecord;
class FaceRecord;
////////////////////////////////////////////////////////////////////
//
// Record
//
////////////////////////////////////////////////////////////////////
class Record : public osg::Referenced
{
public:
Record();
virtual Record* clone() const = 0;
Record* cloneRecord(SRecHeader* pData);
virtual const char* className() const { return "Record"; } //const = 0;
virtual int classOpcode() const { return 0; } //const = 0;
virtual int sizeofData() const { return 0; } //const = 0;
virtual void accept(RecordVisitor& rv);
virtual void traverse(RecordVisitor&) {}
virtual const std::string getName( void ) const { return std::string("?"); }
virtual bool isPrimaryNode() const { return false; }
virtual bool isControlRecord() const { return false; }
virtual bool isAncillaryRecord() const { return false; }
virtual void endian(){}
int getRecordType() const;
SRecHeader* getData() const;
void* getBody() const;
int getOpcode() const;
int getSize() const;
int getHeaderLength() const;
int getBodyLength() const;
bool isOfType(int op) const;
Record* getParent() const { return _pParent; }
friend ostream& operator << (ostream& output, const Record& rec);
protected:
/** disallow creation of Records on the stack.*/
virtual ~Record();
/** Template Method local read and write methods */
virtual bool readLocalData(Input& /*fr*/) { return false; }
// virtual bool writeLocalData(Output& fw) { return false; }
SRecHeader* _pData;
Record* _pParent;
friend FltFile;
friend PrimNodeRecord;
private:
/** disallow copy */
Record& operator = (const Record&) { return *this;}
Record(const Record&) : osg::Referenced() {}
};
inline
SRecHeader* Record::getData() const
{
return _pData;
}
inline
void* Record::getBody() const
{
return (_pData) ? _pData+1 : NULL;
}
inline
int Record::getOpcode() const
{
return (_pData) ? _pData->opcode() : 0;
}
inline
int Record::getSize() const
{
return (_pData) ? _pData->length() : 0;
}
inline
int Record::getHeaderLength() const
{
return sizeof(SRecHeader);
}
inline
int Record::getBodyLength() const
{
return getSize() - getHeaderLength();
}
inline
bool Record::isOfType(int op) const
{
return (op == getOpcode());
}
////////////////////////////////////////////////////////////////////
//
// PrimNodeRecord
//
////////////////////////////////////////////////////////////////////
class PrimNodeRecord : public Record
{
public:
PrimNodeRecord();
virtual bool isPrimaryNode() const { return true; }
virtual void accept(RecordVisitor& rv);
virtual void traverse(RecordVisitor& rv);
void addChild( Record* child );
void removeChild( Record* child );
void removeAllChildren();
int getNumChildren( void ) { return _children.size(); }
Record* getChild( int i ) { return _children[i].get(); }
protected:
/** disallow creation of PrimNodeRecords on the stack.*/
virtual ~PrimNodeRecord();
virtual bool readLocalData(Input& fr);
private:
bool readExtensions(Input& fr);
bool readLevel(Input& fr);
Record* readNextRecord(Input& fr);
typedef std::vector<osg::ref_ptr<Record> > ChildList;
ChildList _children;
friend FaceRecord;
};
////////////////////////////////////////////////////////////////////
//
// ControlRecord
//
////////////////////////////////////////////////////////////////////
class ControlRecord : public Record
{
public:
// ControlRecord();
virtual bool isControlRecord() const { return true; }
virtual void accept(RecordVisitor& rv);
// virtual void traverse(RecordVisitor& rv);
protected:
/** disallow creation of ControlRecord on the stack.*/
// virtual ~ControlRecord();
virtual bool readLocalData(Input& /*fr*/) { return true; }
};
////////////////////////////////////////////////////////////////////
//
// AncillaryRecord
//
////////////////////////////////////////////////////////////////////
class AncillaryRecord : public Record
{
public:
// AncillaryRecord();
virtual bool isAncillaryRecord() const { return true; }
virtual void accept(RecordVisitor& rv);
// virtual void traverse(RecordVisitor& rv);
protected:
/** disallow creation of AncillaryRecord on the stack.*/
// virtual ~AncillaryRecord();
virtual bool readLocalData(Input& /*fr*/) { return true; }
};
////////////////////////////////////////////////////////////////////
}; // end namespace flt
#endif // __FLT_RECORD_H

View File

@@ -0,0 +1,42 @@
// RecordVisitor.cpp
#include "RecordVisitor.h"
#include <stdlib.h>
using namespace flt;
RecordVisitor::RecordVisitor(TraversalMode tm)
{
_traverseVisitor = NULL;
_traverseMode = tm;
}
RecordVisitor::~RecordVisitor()
{
// if (_traverseVisitor) detach from _traverseVisitor;
}
void RecordVisitor::setTraverseMode(TraversalMode mode)
{
if (_traverseMode==mode) return;
if (mode==TRAVERSE_VISITOR)
{
if (_traverseVisitor==NULL) _traverseMode = TRAVERSE_NONE;
else _traverseMode = TRAVERSE_VISITOR;
}
else
{
if (_traverseVisitor) _traverseVisitor=NULL;
_traverseMode = mode;
}
}
void RecordVisitor::setTraverseVisitor(RecordVisitor* rv)
{
if (_traverseVisitor==rv) return;
// if (_traverseVisitor) detach from _traverseVisitor;
_traverseVisitor = rv;
if (_traverseVisitor) _traverseMode = TRAVERSE_VISITOR;
else _traverseMode = TRAVERSE_NONE;
// attach to _traverseVisitor;
}

View File

@@ -0,0 +1,161 @@
// RecordVisitor.h
#ifndef __FLT_RECORD_VISITOR_H
#define __FLT_RECORD_VISITOR_H
#include "Record.h"
namespace flt {
// Palette records
class ColorPaletteRecord;
class MaterialPaletteRecord;
class LightSourcePaletteRecord;
class TexturePaletteRecord;
class VertexPaletteRecord;
class VertexRecord;
class NormalVertexRecord;
class TextureVertexRecord;
class NormalTextureVertexRecord;
// Primary records
class HeaderRecord;
class GroupRecord;
class LodRecord;
class OldLodRecord;
class DofRecord;
class ObjectRecord;
class FaceRecord;
class VertexListRecord;
class MorphVertexListRecord;
class LightSourceRecord;
class LightPointRecord;
class SwitchRecord;
class ExtensionRecord;
class ExternalRecord;
// Ancillary records
class CommentRecord;
class LongIDRecord;
class VectorRecord;
// Transformation records (ancillary)
class MatrixRecord;
class RotatAboutEdgeRecord;
class TranslateRecord;
class ScaleRecord;
class RotatAboutPointRecord;
class RotatScaleToPointRecord;
class PutTransformRecord;
class GeneralMatrixRecord;
/** Visitor for type safe operations on flt::Record's.
Based on GOF's Visitor pattern.*/
class RecordVisitor
{
public:
enum TraversalMode {
TRAVERSE_NONE,
// TRAVERSE_PARENTS,
TRAVERSE_ALL_CHILDREN,
TRAVERSE_ACTIVE_CHILDREN,
TRAVERSE_VISITOR
};
RecordVisitor(TraversalMode tm=TRAVERSE_NONE);
virtual ~RecordVisitor();
/** Set the traversal mode for Node::traverse() to use when
deciding which children of a node to traverse. If a
NodeVisitor has been attached via setTraverseVisitor()
and the new mode is not TRAVERSE_VISITOR then the attached
visitor is detached. Default mode is TRAVERSE_NONE.*/
void setTraverseMode(TraversalMode mode);
/** Get the traversal mode.*/
TraversalMode getTraverseMode() { return _traverseMode; }
/** Set a visitor to handle traversal.
Overides the traverse mode setting it to TRAVERSE_VISITOR.*/
void setTraverseVisitor(RecordVisitor* rv);
/** Get the traverse visitor, returns NULL if none is attached.*/
RecordVisitor* getTraverseVisitor() { return _traverseVisitor; }
/** Inline method for passing handling traversal of a nodes.
If you intend to use the visitor for actively traversing
the scene graph then make sure the accept() methods call
this method unless they handle traversal directly.*/
void traverse(Record& rec)
{
if (_traverseVisitor) rec.accept(*_traverseVisitor);
// else if (_traverseMode==TRAVERSE_PARENTS) rec.ascend(*this);
else if (_traverseMode!=TRAVERSE_NONE) rec.traverse(*this);
}
virtual void apply(Record& rec) { traverse(rec);}
virtual void apply(PrimNodeRecord& rec) { apply((Record&)rec);}
// Palette records
virtual void apply(ColorPaletteRecord& rec) { apply((Record&)rec); }
virtual void apply(MaterialPaletteRecord& rec) { apply((Record&)rec); }
virtual void apply(LightSourcePaletteRecord& rec) { apply((Record&)rec); }
virtual void apply(TexturePaletteRecord& rec) { apply((Record&)rec); }
virtual void apply(VertexPaletteRecord& rec) { apply((Record&)rec); }
virtual void apply(VertexRecord& rec) { apply((Record&)rec); }
virtual void apply(NormalVertexRecord& rec) { apply((Record&)rec); }
virtual void apply(TextureVertexRecord& rec) { apply((Record&)rec); }
virtual void apply(NormalTextureVertexRecord& rec) { apply((Record&)rec); }
// Primary records
virtual void apply(HeaderRecord& rec) { apply((PrimNodeRecord&)rec); }
virtual void apply(GroupRecord& rec) { apply((PrimNodeRecord&)rec); }
virtual void apply(LodRecord& rec) { apply((PrimNodeRecord&)rec); }
virtual void apply(OldLodRecord& rec) { apply((PrimNodeRecord&)rec); }
virtual void apply(DofRecord& rec) { apply((PrimNodeRecord&)rec); }
virtual void apply(ObjectRecord& rec) { apply((PrimNodeRecord&)rec); }
virtual void apply(FaceRecord& rec) { apply((PrimNodeRecord&)rec); }
virtual void apply(VertexListRecord& rec) { apply((PrimNodeRecord&)rec); }
virtual void apply(MorphVertexListRecord& rec) { apply((PrimNodeRecord&)rec); }
virtual void apply(LightSourceRecord& rec) { apply((PrimNodeRecord&)rec); }
virtual void apply(LightPointRecord& rec) { apply((PrimNodeRecord&)rec); }
virtual void apply(SwitchRecord& rec) { apply((PrimNodeRecord&)rec); }
virtual void apply(ExtensionRecord& rec) { apply((PrimNodeRecord&)rec); }
virtual void apply(ExternalRecord& rec) { apply((PrimNodeRecord&)rec); }
// Ancillary records
virtual void apply(CommentRecord& rec) { apply((Record&)rec); }
virtual void apply(LongIDRecord& rec) { apply((Record&)rec); }
virtual void apply(VectorRecord& rec) { apply((Record&)rec); }
// Transformation records (ancillary)
virtual void apply(MatrixRecord& rec) { apply((Record&)rec); }
virtual void apply(RotatAboutEdgeRecord& rec) { apply((Record&)rec); }
virtual void apply(TranslateRecord& rec) { apply((Record&)rec); }
virtual void apply(ScaleRecord& rec) { apply((Record&)rec); }
virtual void apply(RotatAboutPointRecord& rec) { apply((Record&)rec); }
virtual void apply(RotatScaleToPointRecord& rec) { apply((Record&)rec); }
virtual void apply(PutTransformRecord& rec) { apply((Record&)rec); }
virtual void apply(GeneralMatrixRecord& rec) { apply((Record&)rec); }
protected:
RecordVisitor* _traverseVisitor;
TraversalMode _traverseMode;
};
/** Convinience functor for assisting visiting of arrays of flt::Records's.*/
struct RecordAcceptOp
{
RecordVisitor& _rv;
RecordAcceptOp(RecordVisitor& rv):_rv(rv) {}
void operator () (Record* rec) { rec->accept(_rv); }
};
};
#endif

View File

@@ -0,0 +1,108 @@
#include "osg/Node"
#include "osg/Group"
#include "osg/Output"
#include <osg/Notify>
#include <algorithm>
#include <set>
#include "Record.h"
#include "Input.h"
#include "Registry.h"
#ifdef OSG_USE_IO_DOT_H
//#include <ostream.h>
#else
#include <iostream>
using namespace std;
#endif
#include <stdio.h>
using namespace flt;
// definition of the Registry
Registry::Registry()
{
osg::notify(osg::INFO) << "Constructing flt record flt::Registry\n";
}
Registry::~Registry()
{
osg::notify(osg::INFO) << "Destructing flt flt::Registry"<< endl;
// note, do not need to unrefence records as the combination of
// std::vector and ref_ptr will do it automatical on destruction.
}
Registry* Registry::instance()
{
static Registry s_nodeFactory;
return &s_nodeFactory;
}
void Registry::addPrototype(Record* rec)
{
if (rec==0L) return;
osg::notify(osg::INFO) << "flt::Registry::addPrototype("<< rec->className()<<")\n";
RecordProtoList::iterator pitr = std::find(_recordProtoList.begin(),_recordProtoList.end(),rec);
if (pitr==_recordProtoList.end())
{
_recordProtoList.push_back(rec);
}
else
{
osg::notify(osg::INFO) << " failed - flt::Registry::addPrototype() - prototype already exists"<<")\n";
}
rec->ref();
}
void Registry::removePrototype(Record* rec)
{
if (rec==0L) return;
osg::notify(osg::INFO) << "flt::Registry::removePrototype("<<rec->className()<<")\n";
RecordProtoList::iterator pitr = std::find(_recordProtoList.begin(),_recordProtoList.end(),rec);
if (pitr!=_recordProtoList.end())
{
_recordProtoList.erase(pitr);
}
}
Registry::RecordProtoList::iterator Registry::getRecordProtoItr(const int opcode)
{
for(RecordProtoList::iterator itr=_recordProtoList.begin();
itr!=_recordProtoList.end();
++itr)
{
if ((*itr)->classOpcode() == opcode)
return itr;
}
return _recordProtoList.end();
}
Record* Registry::getRecordProto(const int opcode)
{
RecordProtoList::iterator itr = getRecordProtoItr(opcode);
if (itr==_recordProtoList.end())
return NULL;
return itr->get();
}

View File

@@ -0,0 +1,94 @@
#ifndef __FLT_REGISTRY_H
#define __FLT_REGISTRY_H
#include <vector>
#include <string>
#include "osg/Referenced"
namespace osg {
class Node;
};
namespace flt {
// forward declare referenced classes to help avoid mutiple includes
class Record;
class Input;
/**
Registry is a singleton factory which stores
the Objects types available at runtime for loading,
and any Object reader or writers which are linked in
at runtime for reading non-native file formats.
The RegisterObjectProxy defined in Object.h can be
used to automatically register at runtime a Object
with the Registry.
The RegisterReaderWriterProxy defined in ReaderWriter.h can
be used to automatically register at runtime a reader/writer
with the Registry.
*/
class Registry
{
public:
~Registry();
static Registry* instance();
void addPrototype(Record* rec);
void removePrototype(Record* rec);
Record* getRecordProto(const int opcode);
// bool apply(Record& rec);
// Record* readRecord(Input& fr);
// osg::Node* readNode(Input& fr);
private:
typedef std::vector<osg::ref_ptr<Record> > RecordProtoList;
/** constructor is private, as its a singleton, preventing
construction other than via the instance() method and
therefore ensuring only one copy is ever constructed*/
Registry();
RecordProtoList::iterator getRecordProtoItr(const int opcode);
RecordProtoList _recordProtoList;
};
/** Proxy class for automatic registration of reader/writers with the
Registry.*/
template<class T>
class RegisterRecordProxy
{
public:
RegisterRecordProxy()
{
_obj = new T;
_obj->ref();
Registry::instance()->addPrototype(_obj);
}
~RegisterRecordProxy()
{
//commented out to prevent seg fault under Linux
//due to the registry being previously destructed.
//Registry::instance()->removePrototype(_obj);
_obj->unref();
}
protected:
T* _obj;
};
}; // end namespace flt
#endif // __FLT_REGISTRY_H

View File

@@ -0,0 +1,42 @@
// SwitchRecord.cpp
#include "flt.h"
#include "Registry.h"
#include "SwitchRecord.h"
using namespace flt;
////////////////////////////////////////////////////////////////////
//
// SwitchRecord
//
////////////////////////////////////////////////////////////////////
RegisterRecordProxy<SwitchRecord> g_SwitchProxy;
SwitchRecord::SwitchRecord()
{
}
// virtual
SwitchRecord::~SwitchRecord()
{
}
void SwitchRecord::endian()
{
SSwitch *pSSwitch = (SSwitch*)getData();
ENDIAN( pSSwitch->dwCurrentMask );
ENDIAN( pSSwitch->diWordsInMask );
ENDIAN( pSSwitch->diMasks );
}

View File

@@ -0,0 +1,53 @@
// SwitchRecord.h
#ifndef __FLT_SWITCH_RECORD_H
#define __FLT_SWITCH_RECORD_H
#include "opcodes.h"
#include "Record.h"
#include "RecordVisitor.h"
namespace flt {
struct SSwitch
{
SRecHeader RecHeader;
char szIdent[8]; // // 7 char ASCII ID; 0 terminates
uint8 reserved[4]; // Reserved
uint32 dwCurrentMask; // Current mask
int32 diWordsInMask; // Number of 32 bit words required for each mask
// (number of children / 32 + number of children modulo 32)
int32 diMasks; // Number of masks
// ??? Mask[1]; // Variable Mask words
// (length = number of words per mask * number of masks * 4 bytes)
};
class SwitchRecord : public PrimNodeRecord
{
public:
SwitchRecord();
virtual Record* clone() const { return new SwitchRecord(); }
virtual const char* className() const { return "SwitchRecord"; }
virtual int classOpcode() const { return SWITCH_OP; }
virtual int sizeofData() const { return sizeof(SSwitch); }
virtual void accept(RecordVisitor& rv) { rv.apply(*this); }
// virtual void traverse(RecordVisitor& rv);
SSwitch* getData() const { return (SSwitch*)_pData; }
protected:
virtual ~SwitchRecord();
virtual void endian();
};
}; // end namespace flt
#endif

View File

@@ -0,0 +1,55 @@
// TextureMappingPaletteRecord.cpp
#include "flt.h"
#include "Registry.h"
#include "TextureMappingPaletteRecord.h"
using namespace flt;
////////////////////////////////////////////////////////////////////
//
// TextureMappingPaletteRecord
//
////////////////////////////////////////////////////////////////////
RegisterRecordProxy<TextureMappingPaletteRecord> g_TextureMappingPaletteProxy;
TextureMappingPaletteRecord::TextureMappingPaletteRecord()
{
}
// virtual
TextureMappingPaletteRecord::~TextureMappingPaletteRecord()
{
}
// virtual
void TextureMappingPaletteRecord::endian()
{
STextureMapping *pSMapping = (STextureMapping*)getData();
if (pSMapping)
{
ENDIAN( pSMapping->diIndex );
ENDIAN( pSMapping->diType );
ENDIAN( pSMapping->diWarpFlag );
for(int i=0;i<4;++i)
{
for(int j=0;j<4;++j)
{
ENDIAN( pSMapping->dfMat[i][j] );
}
}
}
}

View File

@@ -0,0 +1,195 @@
// TextureMappingPaletteRecord.h
#ifndef __FLT_TEXTURE_MAPPING_PALETTE_RECORD_H
#define __FLT_TEXTURE_MAPPING_PALETTE_RECORD_H
#include "opcodes.h"
#include "Record.h"
#include "RecordVisitor.h"
namespace flt {
struct STextureMapping
{
SRecHeader RecHeader;
float32 reserved; // Reserved
int32 diIndex; // Texture mapping index
char szName[20]; // Texture mapping name
int32 diType; // Texture mapping type
// 0 = None
// 1 = Put
// 2 = 4 Point Put
// 3 = Reserved
// 4 = Spherical Project
// 5 = Radial Project
// 6 = Reserved
int32 diWarpFlag; // Warped flag; if TRUE, 8 point warp applied
float64 dfMat[4][4]; // Transformation matrix (valid only for Types 1 & 2)
// Variable Variable; // Parameters (see below for parameters for each mapping type)
#if 0
// Parameters for Put Texture Mapping (Type 1)
uint32 dwState; // State of Put Texture tool
// 0 = Start state - no points entered
// 1 = One point entered
// 2 = Two points entered
// 3 = Three points entered
int32 active; // Active geometry point
// 1 = Origin point
// 2 = Alignment point
// 3 = Shear point
float64x3 lower_left; // lower-left corner of bounding box
float64x3 upper_right; // upper-right corner of bounding box
int32 sizeFlags[3]; // Use real world size flags for each of the three put points
float64x3 dfTxtOrigin; // Texture origin point
float64x3 dfTxtAlignment; // Texture alignment point
float64x3 dfTxtShear; // Texture shear point
float64x3 dfGeoOrigin; // Geometry origin point
float64x3 dfGeoAlignmentM // Geometry alignment point
float64x3 dfGeoShear; // Geometry shear point
int32 TxtActive; // Active texture point
// 1 = Origin point
// 2 = Alignment point
// 3 = Shear point
int32 Reserved; // should always be set to 1
// Variable Variable; // Parameters (see parameters below for each mapping type)
//Parameters for 4 Point Put Texture Mapping (Type 2)
int32 state; // State of Put Texture tool
// 0 = Start state - no points entered
// 1 = One point entered
// 2 = Two points entered
// 3 = Three points entered
// 4 = Four points entered
int32 active; // Active geometry point
// 1 = Origin point
// 2 = Alignment point
// 3 = Shear point
// 4 = Perspective point
float64x3 lower_left; // lower-left corner of bounding box
float64x3 upper_right; // upper-right corner of bounding box
int32 sizeFlags[4]; // Use real world size flags for each of the four put points
float64x3 dfTxtOrigin; // Texture origin point
float64x3 dfTxtAlignment; // Texture alignment point
float64x3 dfTxtShear; // Texture shear point
float64x3 dfTxtPerspective; // Texture perspective point
float64x3 dfGeoOrigin; // Geometry origin point
float64x3 dfGeoAlignment; // Geometry alignment point
float64x3 dfGeoShear; // Geometry shear point
float64x3 dfGeoPerspective; // Geometry perspective point
int32 TxtActive; // Active texture point
// 1 = Origin point
// 2 = Alignment point
// 3 = Shear point
// 4 = Perspective point
int32 Reserved; // should always be set to 1
float32 sfScale; // Depth scale factor
float64 dfMat[4][4]; // Transformation matrix for the 4 point projection plane
// Parameters for Spherical Project Mapping (Type 4)
float32 sfScale; // Scale
float64x3 Center; // Center of the projection sphere
float32 sfScale; // Scale / (maximum dimension of the mapped geometry
// bounding box)
float32 sfMaxDimension; // Maximum dimension of the mapped geometry
// bounding box
// Parameters for Radial Project Mapping (Type 5)
int32 active // Active geometry point
// 1 = End point 1 of cylinder center line
// 2 = End point 2 of cylinder center line
int32 reserved; // Reserved
float32 sfRadialScale; // Radial scale
float32 sfLengthScale; // Scale along length of cylinder
float64 dfMat[4][4]; // Trackplane to XY plane transformation matrix
float64x3 endpoint1; // End point 1 of cylinder center line
float64x3 endpoint2; // End point 2 of cylinder center line
// Parameters for Warped Mapping (Warped Flag Set)
int32 active; // Active geometry point
// 0 = First warp FROM point
// 1 = Second warp FROM point
// 2 =Third warp FROM point
// 3 = Fourth warp FROM point
// 4 = Fifth warp FROM point
// 5 = Sixth warp FROM point
// 6 = Seventh warp FROM point
// 7 = Eighth warp FROM point
// 8 = First warp TO point
// 9 = Second warp TO point
// 10 = Third warp TO point
// 11 = Fourth warp TO point
// 12 = Fifth warp TO point
// 13 = Sixth warp TO point
// 14 = Seventh warp TO point
// 15 = Eighth warp TO point
int32 warpState; // Warp tool state
// 0 = Start state - no points entered
// 1 = One FROM point entered
// 2 = Two FROM point entered
// 3 = Three FROM point entered
// 4 = Four FROM point entered
// 5 = Five FROM point entered
// 6 = Six FROM point entered
// 7 = Seven FROM point entered
// 8 = All FROM point entered
float64 dfMat[4][4]; // Trackplane to XY plane transformation matrix
/*
Double 16*2 x, y of the first FROM point transformed to the XY plane by the above matrix
Double 16*2 x, y of the second FROM point transformed to the XY plane by the above matrix
Double 16*2 x, y of the third FROM point transformed to the XY plane by the above matrix
Double 16*2 x, y of the fourth FROM point transformed to the XY plane by the above matrix
Double 16*2 x, y of the fifth FROM point transformed to the XY plane by the above matrix
Double 16*2 x, y of the sixth FROM point transformed to the XY plane by the above matrix
Double 16*2 x, y of the seventh FROM point transformed to the XY plane by the above matrix
Double 16*2 x, y of the eighth FROM point transformed to the XY plane by the above matrix
Double 16*2 x, y of the first TO point transformed to the XY plane by the above matrix
Double 16*2 x, y of the second TO point transformed to the XY plane by the above matrix
Double 16*2 x, y of the third TO point transformed to the XY plane by the above matrix
Double 16*2 x, y of the fourth TO point transformed to the XY plane by the above matrix
Double 16*2 x, y of the fifth TO point transformed to the XY plane by the above matrix
Double 16*2 x, y of the sixth TO point transformed to the XY plane by the above matrix
Double 16*2 x, y of the seventh TO point transformed to the XY plane by the above matrix
Double 16*2 x, y of the eighth TO point transformed to the XY plane by the above matrix
*/
#endif
};
class TextureMappingPaletteRecord : public AncillaryRecord
{
public:
TextureMappingPaletteRecord();
virtual Record* clone() const { return new TextureMappingPaletteRecord(); }
virtual const char* className() const { return "TextureMappingPaletteRecord"; }
virtual int classOpcode() const { return TEXTURE_MAPPING_PALETTE_OP; }
virtual int sizeofData() const { return sizeof(STextureMapping); }
virtual void accept(RecordVisitor& rv) { rv.apply(*this); }
// virtual void traverse(RecordVisitor& rv);
protected:
virtual ~TextureMappingPaletteRecord();
virtual void endian();
// virtual bool readLocalData(Input& fr);
// virtual bool writeLocalData(Output& fw);
};
}; // end namespace flt
#endif

View File

@@ -0,0 +1,44 @@
// TexturePaletteRecord.cpp
#include "flt.h"
#include "Registry.h"
#include "TexturePaletteRecord.h"
using namespace flt;
////////////////////////////////////////////////////////////////////
//
// TexturePaletteRecord
//
////////////////////////////////////////////////////////////////////
RegisterRecordProxy<TexturePaletteRecord> g_TexturePaletteProxy;
TexturePaletteRecord::TexturePaletteRecord()
{
}
// virtual
TexturePaletteRecord::~TexturePaletteRecord()
{
}
// virtual
void TexturePaletteRecord::endian()
{
STexturePalette *pSTexture = (STexturePalette*)getData();
ENDIAN( pSTexture->diIndex );
ENDIAN( pSTexture->diX );
ENDIAN( pSTexture->diY );
}

View File

@@ -0,0 +1,50 @@
// TexturePaletteRecord.h
#ifndef __FLT_TEXTURE_PALETTE_RECORD_H
#define __FLT_TEXTURE_PALETTE_RECORD_H
#include "opcodes.h"
#include "Record.h"
#include "RecordVisitor.h"
namespace flt {
typedef struct TexturePaletteTag
{
SRecHeader RecHeader;
char szFilename[200]; // Filename of texture pattern
int32 diIndex; // Pattern index
int32 diX; // x location in texture palette
int32 diY; // y location in texture palette
} STexturePalette;
class TexturePaletteRecord : public AncillaryRecord
{
public:
TexturePaletteRecord();
virtual Record* clone() const { return new TexturePaletteRecord(); }
virtual const char* className() const { return "TexturePaletteRecord"; }
virtual int classOpcode() const { return TEXTURE_PALETTE_OP; }
virtual int sizeofData() const { return sizeof(STexturePalette); }
virtual void accept(RecordVisitor& rv) { rv.apply(*this); }
// virtual void traverse(RecordVisitor& rv);
protected:
virtual ~TexturePaletteRecord();
virtual void endian();
};
}; // end namespace flt
#endif

View File

@@ -0,0 +1,253 @@
// TransformationRecords.cpp
#include "flt.h"
#include "Registry.h"
#include "TransformationRecords.h"
using namespace flt;
////////////////////////////////////////////////////////////////////
//
// MatrixRecord
//
////////////////////////////////////////////////////////////////////
RegisterRecordProxy<MatrixRecord> g_MatrixProxy;
MatrixRecord::MatrixRecord()
{
}
// virtual
MatrixRecord::~MatrixRecord()
{
}
// virtual
void MatrixRecord::endian()
{
SMatrix* pSMatrix = (SMatrix*)getData();
if (pSMatrix)
{
for(int i=0;i<4;++i)
{
for(int j=0;j<4;++j)
{
ENDIAN( pSMatrix->sfMat[i][j] );
}
}
}
}
////////////////////////////////////////////////////////////////////
//
// RotatAboutEdgeRecord
//
////////////////////////////////////////////////////////////////////
RegisterRecordProxy<RotatAboutEdgeRecord> g_RotatAboutEdgeProxy;
RotatAboutEdgeRecord::RotatAboutEdgeRecord()
{
}
// virtual
RotatAboutEdgeRecord::~RotatAboutEdgeRecord()
{
}
// virtual
void RotatAboutEdgeRecord::endian()
{
}
////////////////////////////////////////////////////////////////////
//
// TranslateRecord
//
////////////////////////////////////////////////////////////////////
RegisterRecordProxy<TranslateRecord> g_TranslateProxy;
TranslateRecord::TranslateRecord()
{
}
// virtual
TranslateRecord::~TranslateRecord()
{
}
// virtual
void TranslateRecord::endian()
{
}
////////////////////////////////////////////////////////////////////
//
// ScaleRecord
//
////////////////////////////////////////////////////////////////////
RegisterRecordProxy<ScaleRecord> g_ScaleProxy;
ScaleRecord::ScaleRecord()
{
}
// virtual
ScaleRecord::~ScaleRecord()
{
}
// virtual
void ScaleRecord::endian()
{
}
////////////////////////////////////////////////////////////////////
//
// RotatAboutPointRecord
//
////////////////////////////////////////////////////////////////////
RegisterRecordProxy<RotatAboutPointRecord> g_RotatAboutPointProxy;
RotatAboutPointRecord::RotatAboutPointRecord()
{
}
// virtual
RotatAboutPointRecord::~RotatAboutPointRecord()
{
}
// virtual
void RotatAboutPointRecord::endian()
{
}
////////////////////////////////////////////////////////////////////
//
// RotatScaleToPointRecord
//
////////////////////////////////////////////////////////////////////
RegisterRecordProxy<RotatScaleToPointRecord> g_RotatScaleToPointProxy;
RotatScaleToPointRecord::RotatScaleToPointRecord()
{
}
// virtual
RotatScaleToPointRecord::~RotatScaleToPointRecord()
{
}
// virtual
void RotatScaleToPointRecord::endian()
{
}
////////////////////////////////////////////////////////////////////
//
// PutTransformRecord
//
////////////////////////////////////////////////////////////////////
RegisterRecordProxy<PutTransformRecord> g_PutTransformProxy;
PutTransformRecord::PutTransformRecord()
{
}
// virtual
PutTransformRecord::~PutTransformRecord()
{
}
// virtual
void PutTransformRecord::endian()
{
SPutTransform *pSPutTransform = (SPutTransform*)getData();
ENDIAN( pSPutTransform->tmp1 );
pSPutTransform->FromOrigin.endian();
pSPutTransform->FromAlign.endian();
pSPutTransform->FromTrack.endian();
pSPutTransform->ToOrigin.endian();
pSPutTransform->ToAlign.endian();
pSPutTransform->ToTrack.endian();
}
////////////////////////////////////////////////////////////////////
//
// GeneralMatrixRecord
//
////////////////////////////////////////////////////////////////////
RegisterRecordProxy<GeneralMatrixRecord> g_GeneralMatrixProxy;
GeneralMatrixRecord::GeneralMatrixRecord()
{
}
// virtual
GeneralMatrixRecord::~GeneralMatrixRecord()
{
}
// virtual
void GeneralMatrixRecord::endian()
{
SGeneralMatrix* pSMatrix = (SGeneralMatrix*)getData();
if (pSMatrix)
{
for(int i=0;i<4;++i)
{
for(int j=0;j<4;++j)
{
ENDIAN( pSMatrix->sfMat[i][j] );
}
}
}
}

View File

@@ -0,0 +1,301 @@
// TransformationRecords.h
#ifndef __FLT_TRANSFORMATION_RECORDS_H
#define __FLT_TRANSFORMATION_RECORDS_H
#include "opcodes.h"
#include "Record.h"
#include "RecordVisitor.h"
namespace flt {
////////////////////////////////////////////////////////////////////
//
// MatrixRecord
//
////////////////////////////////////////////////////////////////////
typedef struct MatrixTag
{
SRecHeader RecHeader;
float32 sfMat[4][4]; // 4x4 Single Precision Matrix
} SMatrix; // row major order
class MatrixRecord : public AncillaryRecord
{
public:
MatrixRecord();
virtual Record* clone() const { return new MatrixRecord(); }
virtual const char* className() const { return "MatrixRecord"; }
virtual int classOpcode() const { return MATRIX_OP; }
virtual int sizeofData() const { return sizeof(SMatrix); }
virtual void accept(RecordVisitor& rv) { rv.apply(*this); }
// virtual void traverse(RecordVisitor& rv);
virtual SMatrix* getData() const { return (SMatrix*)_pData; }
protected:
virtual ~MatrixRecord();
virtual void endian();
};
////////////////////////////////////////////////////////////////////
//
// RotatAboutEdgeRecord
//
////////////////////////////////////////////////////////////////////
typedef struct RotatAboutEdgeTag
{
SRecHeader RecHeader;
int32 diReserved;
float64x3 Point1; // first point on edge
float64x3 Point2; // second point on edge
float32 sfAngle; // Angle by which to rotate
} SRotatAboutEdge;
class RotatAboutEdgeRecord : public AncillaryRecord
{
public:
RotatAboutEdgeRecord();
virtual Record* clone() const { return new RotatAboutEdgeRecord(); }
virtual const char* className() const { return "RotatAboutEdgeRecord"; }
virtual int classOpcode() const { return ROTATE_ABOUT_EDGE_OP; }
virtual int sizeofData() const { return sizeof(SRotatAboutEdge); }
virtual void accept(RecordVisitor& rv) { rv.apply(*this); }
// virtual void traverse(RecordVisitor& rv);
virtual SRotatAboutEdge* getData() const { return (SRotatAboutEdge*)_pData; }
protected:
virtual ~RotatAboutEdgeRecord();
virtual void endian();
};
////////////////////////////////////////////////////////////////////
//
// TranslateRecord
//
////////////////////////////////////////////////////////////////////
typedef struct TranslateTag
{
SRecHeader RecHeader;
int32 diReserved;
float64x3 From; // reference FROM point
float64x3 Delta; // Delta to translate node by
} STranslate;
class TranslateRecord : public AncillaryRecord
{
public:
TranslateRecord();
virtual Record* clone() const { return new TranslateRecord(); }
virtual const char* className() const { return "TranslateRecord"; }
virtual int classOpcode() const { return TRANSLATE_OP; }
virtual int sizeofData() const { return sizeof(STranslate); }
virtual void accept(RecordVisitor& rv) { rv.apply(*this); }
// virtual void traverse(RecordVisitor& rv);
virtual STranslate* getData() const { return (STranslate*)_pData; }
protected:
virtual ~TranslateRecord();
virtual void endian();
};
////////////////////////////////////////////////////////////////////
//
// ScaleRecord
//
////////////////////////////////////////////////////////////////////
typedef struct ScaleTag
{
SRecHeader RecHeader;
int32 Reserved;
float64x3 center;
float32x3 scale;
} SScale;
class ScaleRecord : public AncillaryRecord
{
public:
ScaleRecord();
virtual Record* clone() const { return new ScaleRecord(); }
virtual const char* className() const { return "ScaleRecord"; }
virtual int classOpcode() const { return SCALE_OP; }
virtual int sizeofData() const { return sizeof(SScale); }
virtual void accept(RecordVisitor& rv) { rv.apply(*this); }
// virtual void traverse(RecordVisitor& rv);
// virtual SGroup* getData() const { return (SGroup*)_pData; }
protected:
virtual ~ScaleRecord();
virtual void endian();
};
////////////////////////////////////////////////////////////////////
//
// RotatAboutPointRecord
//
////////////////////////////////////////////////////////////////////
typedef struct RotatAboutPointTag
{
SRecHeader RecHeader;
// TODO
} SRotatAboutPoint;
class RotatAboutPointRecord : public AncillaryRecord
{
public:
RotatAboutPointRecord();
virtual Record* clone() const { return new RotatAboutPointRecord(); }
virtual const char* className() const { return "RotatAboutPointRecord"; }
virtual int classOpcode() const { return ROTATE_ABOUT_POINT_OP; }
virtual int sizeofData() const { return sizeof(SRotatAboutPoint); }
virtual void accept(RecordVisitor& rv) { rv.apply(*this); }
// virtual void traverse(RecordVisitor& rv);
// virtual SGroup* getData() const { return (SGroup*)_pData; }
protected:
virtual ~RotatAboutPointRecord();
virtual void endian();
};
////////////////////////////////////////////////////////////////////
//
// RotatScaleToPointRecord
//
////////////////////////////////////////////////////////////////////
typedef struct RotatScaleToPointTag
{
SRecHeader RecHeader;
// TODO
} SRotatScaleToPoint;
class RotatScaleToPointRecord : public AncillaryRecord
{
public:
RotatScaleToPointRecord();
virtual Record* clone() const { return new RotatScaleToPointRecord(); }
virtual const char* className() const { return "RotatScaleToPointRecord"; }
virtual int classOpcode() const { return ROTATE_SCALE_TO_POINT_OP; }
virtual int sizeofData() const { return sizeof(SRotatScaleToPoint); }
virtual void accept(RecordVisitor& rv) { rv.apply(*this); }
// virtual void traverse(RecordVisitor& rv);
// virtual SGroup* getData() const { return (SGroup*)_pData; }
protected:
virtual ~RotatScaleToPointRecord();
virtual void endian();
};
////////////////////////////////////////////////////////////////////
//
// PutTransformRecord
//
////////////////////////////////////////////////////////////////////
typedef struct PutTransformTag //follows normally a matrix record to
{ //make up the transformation
SRecHeader RecHeader;
int32 tmp1; //mismatch with spec!
float64x3 FromOrigin;
float64x3 FromAlign;
float64x3 FromTrack;
float64x3 ToOrigin; //mismatch !!
float64x3 ToAlign;
float64x3 ToTrack;
} SPutTransform;
class PutTransformRecord : public AncillaryRecord
{
public:
PutTransformRecord();
virtual Record* clone() const { return new PutTransformRecord(); }
virtual const char* className() const { return "PutTransformRecord"; }
virtual int classOpcode() const { return PUT_TRANSFORM_OP; }
virtual int sizeofData() const { return sizeof(SPutTransform); }
virtual void accept(RecordVisitor& rv) { rv.apply(*this); }
// virtual void traverse(RecordVisitor& rv);
virtual SPutTransform* getData() const { return (SPutTransform*)_pData; }
protected:
virtual ~PutTransformRecord();
virtual void endian();
};
////////////////////////////////////////////////////////////////////
//
// GeneralMatrixRecord
//
////////////////////////////////////////////////////////////////////
typedef struct GeneralMatrixTag
{
SRecHeader RecHeader;
float32 sfMat[4][4]; // 4x4 Single Precision Matrix
} SGeneralMatrix; // row major order
class GeneralMatrixRecord : public AncillaryRecord
{
public:
GeneralMatrixRecord();
virtual Record* clone() const { return new GeneralMatrixRecord(); }
virtual const char* className() const { return "GeneralMatrixRecord"; }
virtual int classOpcode() const { return GENERAL_MATRIX_OP; }
virtual int sizeofData() const { return sizeof(SGeneralMatrix); }
virtual void accept(RecordVisitor& rv) { rv.apply(*this); }
// virtual void traverse(RecordVisitor& rv);
// virtual SGroup* getData() const { return (SGroup*)_pData; }
protected:
virtual ~GeneralMatrixRecord();
virtual void endian();
};
}; // end namespace flt
#endif // __FLT_TRANSFORMATION_RECORDS_H

View File

@@ -0,0 +1,27 @@
// UnknownRecord.cpp
#include "flt.h"
#include "Registry.h"
#include "UnknownRecord.h"
using namespace flt;
////////////////////////////////////////////////////////////////////
//
// UnknownRecord
//
////////////////////////////////////////////////////////////////////
RegisterRecordProxy<UnknownRecord> g_UnknownProxy;
UnknownRecord::UnknownRecord()
{
}
// virtual
UnknownRecord::~UnknownRecord()
{
}

View File

@@ -0,0 +1,37 @@
// UnknownRecord.h
#ifndef __FLT_UNKNOWN_RECORD_H
#define __FLT_UNKNOWN_RECORD_H
#include "opcodes.h"
#include "Record.h"
#include "RecordVisitor.h"
namespace flt {
////////////////////////////////////////////////////////////////////
class UnknownRecord : public AncillaryRecord
{
public:
UnknownRecord();
virtual ~UnknownRecord();
virtual Record* clone() const { return new UnknownRecord(); }
virtual const char* className() const { return "UnknownRecord"; }
virtual int classOpcode() const { return 0; }
virtual void accept(RecordVisitor& rv) { rv.apply(*this); }
// virtual void traverse(RecordVisitor& rv);
protected:
};
}; // end namespace flt
#endif

View File

@@ -0,0 +1,220 @@
// VertexPoolRecords.cpp
#include "flt.h"
#include "Registry.h"
#include "VertexPoolRecords.h"
using namespace flt;
////////////////////////////////////////////////////////////////////
//
// VertexPaletteRecord
//
////////////////////////////////////////////////////////////////////
RegisterRecordProxy<VertexPaletteRecord> g_VertexPaletteProxy;
VertexPaletteRecord::VertexPaletteRecord()
{
}
// virtual
VertexPaletteRecord::~VertexPaletteRecord()
{
}
// virtual
void VertexPaletteRecord::endian()
{
SVertexTableHeader *pVertexTableHeader = (SVertexTableHeader*)getData();
ENDIAN( pVertexTableHeader->diVertexTableLength );
}
ostream& operator << (ostream& output, const VertexPaletteRecord& rec)
{
output << rec.className();
return output; // to enable cascading
}
////////////////////////////////////////////////////////////////////
//
// VertexRecord
//
////////////////////////////////////////////////////////////////////
RegisterRecordProxy<VertexRecord> g_VertexProxy;
VertexRecord::VertexRecord()
{
}
// virtual
VertexRecord::~VertexRecord()
{
}
// virtual
void VertexRecord::endian()
{
SVertex *pVertex = (SVertex*)getData();
ENDIAN( pVertex->swColor );
ENDIAN( pVertex->swFlags );
pVertex->Coord.endian();
ENDIAN( pVertex->dwVertexColorIndex );
}
ostream& operator << (ostream& output, const VertexRecord& rec)
{
output << rec.className() << " "
<< rec.getData()->swFlags << " "
<< rec.getData()->Coord;
return output; // to enable cascading
}
////////////////////////////////////////////////////////////////////
//
// NormalVertexRecord
//
////////////////////////////////////////////////////////////////////
RegisterRecordProxy<NormalVertexRecord> g_NormalVertexProxy;
NormalVertexRecord::NormalVertexRecord()
{
}
// virtual
NormalVertexRecord::~NormalVertexRecord()
{
}
// virtual
void NormalVertexRecord::endian()
{
SNormalVertex *pVertex = (SNormalVertex*)getData();
ENDIAN( pVertex->swColor );
ENDIAN( pVertex->swFlags );
pVertex->Coord.endian();
pVertex->Normal.endian();
// ENDIAN( pVertex->PackedColor );
ENDIAN( pVertex->dwVertexColorIndex );
}
ostream& operator << (ostream& output, const NormalVertexRecord& rec)
{
output << rec.className() << " "
<< rec.getData()->swFlags << " "
<< rec.getData()->Coord;
return output; // to enable cascading
}
////////////////////////////////////////////////////////////////////
//
// TextureVertexRecord
//
////////////////////////////////////////////////////////////////////
RegisterRecordProxy<TextureVertexRecord> g_TextureVertexProxy;
TextureVertexRecord::TextureVertexRecord()
{
}
// virtual
TextureVertexRecord::~TextureVertexRecord()
{
}
// virtual
void TextureVertexRecord::endian()
{
STextureVertex *pVertex = (STextureVertex*)getData();
ENDIAN( pVertex->swColor );
ENDIAN( pVertex->swFlags );
pVertex->Coord.endian();
pVertex->Texture.endian();
// ENDIAN( pVertex->PackedColor );
ENDIAN( pVertex->dwVertexColorIndex );
}
ostream& operator << (ostream& output, const TextureVertexRecord& rec)
{
output << rec.className() << " "
<< rec.getData()->swFlags << " "
<< rec.getData()->Coord;
return output; // to enable cascading
}
////////////////////////////////////////////////////////////////////
//
// NormalTextureVertexRecord
//
////////////////////////////////////////////////////////////////////
RegisterRecordProxy<NormalTextureVertexRecord> g_NormalTextureVertexProxy;
NormalTextureVertexRecord::NormalTextureVertexRecord()
{
}
// virtual
NormalTextureVertexRecord::~NormalTextureVertexRecord()
{
}
// virtual
void NormalTextureVertexRecord::endian()
{
SNormalTextureVertex *pVertex = (SNormalTextureVertex*)getData();
ENDIAN( pVertex->swColor );
ENDIAN( pVertex->swFlags );
pVertex->Coord.endian();
pVertex->Normal.endian();
pVertex->Texture.endian();
// ENDIAN( pVertex->PackedColor );
ENDIAN( pVertex->dwVertexColorIndex );
}
ostream& operator << (ostream& output, const NormalTextureVertexRecord& rec)
{
output << rec.className() << " "
<< rec.getData()->swFlags << " "
<< rec.getData()->Coord;
return output; // to enable cascading
}

View File

@@ -0,0 +1,230 @@
// VertexPoolRecords.h
#ifndef __FLT_VERTEX_POOL_RECORDS_H
#define __FLT_VERTEX_POOL_RECORDS_H
#include <map>
#include "opcodes.h"
#include "Record.h"
#include "RecordVisitor.h"
#ifdef OSG_USE_IO_DOT_H
#include <iostream.h>
#else
#include <iostream>
using namespace std;
#endif
namespace flt {
////////////////////////////////////////////////////////////////////
//
// VertexPaletteRecord
//
////////////////////////////////////////////////////////////////////
typedef struct VertexTableHeaderTag //Vertex Palette Header record
{
SRecHeader RecHeader;
int32 diVertexTableLength; //Length of this record plus pool
} SVertexTableHeader;
class VertexPaletteRecord : public AncillaryRecord
{
public:
VertexPaletteRecord();
virtual Record* clone() const { return new VertexPaletteRecord(); }
virtual const char* className() const { return "VertexPaletteRecord"; }
virtual int classOpcode() const { return VERTEX_PALETTE_OP; }
virtual int sizeofData() const { return sizeof(SVertexTableHeader); }
virtual void accept(RecordVisitor& rv) { rv.apply(*this); }
// virtual void traverse(RecordVisitor& rv);
friend ostream& operator << (ostream& output, const VertexPaletteRecord& rec);
protected:
virtual ~VertexPaletteRecord();
virtual void endian();
};
////////////////////////////////////////////////////////////////////
//
// VertexRecord
//
////////////////////////////////////////////////////////////////////
typedef struct VertexTag // Vertex with Color Record Format
{
SRecHeader RecHeader;
uint16 swColor; // Color Name Index
uint16 swFlags; // Flags (bits, from left to right)
// 0 = Start Hard Edge
// 1 = Normal frozen
// 2 = no Vertex Color
// 3 = Packed Color
// 4-15 Spare
float64x3 Coord; // x,y,z coordinate
color32 PackedColor; // Packed color (A, B, G, R)
uint32 dwVertexColorIndex;
} SVertex;
class VertexRecord : public AncillaryRecord
{
public:
VertexRecord();
virtual Record* clone() const { return new VertexRecord(); }
virtual const char* className() const { return "VertexRecord"; }
virtual int classOpcode() const { return VERTEX_C_OP; }
virtual int sizeofData() const { return sizeof(SVertex); }
virtual void accept(RecordVisitor& rv) { rv.apply(*this); }
// virtual void traverse(RecordVisitor& rv);
virtual SVertex* getData() const { return (SVertex*)_pData; }
friend ostream& operator << (ostream& output, const VertexRecord& rec);
protected:
virtual ~VertexRecord();
virtual void endian();
};
////////////////////////////////////////////////////////////////////
//
// NormalVertexRecord
//
////////////////////////////////////////////////////////////////////
typedef struct NormalVertexTag // Vertex with Normal Record Format
{
SRecHeader RecHeader;
uint16 swColor; // Color Name Index
uint16 swFlags; // Flags (bits, from left to right)
// 0 = Start Hard Edge
// 1 = Normal frozen
// 2 = no Vertex Color
// 3 = Packed Color
// 4-15 Spare
float64x3 Coord; // x,y,z coordinate
float32x3 Normal; // Vertex normal
color32 PackedColor; // Packed color (A, B, G, R)
uint32 dwVertexColorIndex;
} SNormalVertex;
class NormalVertexRecord : public AncillaryRecord
{
public:
NormalVertexRecord();
virtual Record* clone() const { return new NormalVertexRecord(); }
virtual const char* className() const { return "NormalVertexRecord"; }
virtual int classOpcode() const { return VERTEX_CN_OP; }
virtual int sizeofData() const { return sizeof(SNormalVertex); }
virtual void accept(RecordVisitor& rv) { rv.apply(*this); }
// virtual void traverse(RecordVisitor& rv);
virtual SNormalVertex* getData() const { return (SNormalVertex*)_pData; }
friend ostream& operator << (ostream& output, const NormalVertexRecord& rec);
protected:
virtual ~NormalVertexRecord();
virtual void endian();
};
////////////////////////////////////////////////////////////////////
//
// TextureVertexRecord
//
////////////////////////////////////////////////////////////////////
typedef struct TextureVertexTag // Vertex with Texture Record Format
{
SRecHeader RecHeader;
uint16 swColor; // Color Name Index
uint16 swFlags; // Flags (bits, from left to right)
// 0 = Start Hard Edge
// 1 = Normal frozen
// 2 = no Vertex Color
// 3 = Packed Color
// 4-15 Spare
float64x3 Coord; // x,y,z coordinate
float32x2 Texture; // Texture (u,v)
color32 PackedColor; // Packed color (A, B, G, R)
uint32 dwVertexColorIndex;
} STextureVertex;
class TextureVertexRecord : public AncillaryRecord
{
public:
TextureVertexRecord();
virtual Record* clone() const { return new TextureVertexRecord(); }
virtual const char* className() const { return "TextureVertexRecord"; }
virtual int classOpcode() const { return VERTEX_CT_OP; }
virtual int sizeofData() const { return sizeof(STextureVertex); }
virtual void accept(RecordVisitor& rv) { rv.apply(*this); }
// virtual void traverse(RecordVisitor& rv);
virtual STextureVertex* getData() const { return (STextureVertex*)_pData; }
friend ostream& operator << (ostream& output, const TextureVertexRecord& rec);
protected:
virtual ~TextureVertexRecord();
virtual void endian();
};
////////////////////////////////////////////////////////////////////
//
// NormalTextureVertexRecord
//
////////////////////////////////////////////////////////////////////
typedef struct NormalTextureVertexTag //Vertex with Normal and Texture Format
{
SRecHeader RecHeader;
uint16 swColor; // Color Name Index
uint16 swFlags; // Flags (bits, from left to right)
// 0 = Start Hard Edge
// 1 = Normal frozen
// 2 = no Vertex Color
// 3 = Packed Color
// 4-15 Spare
float64x3 Coord; // x,y,z coordinate
float32x3 Normal; // Vertex normal
float32x2 Texture; // Texture (u,v)
color32 PackedColor; // Packed color (A, B, G, R)
uint32 dwVertexColorIndex;
} SNormalTextureVertex;
class NormalTextureVertexRecord : public AncillaryRecord
{
public:
NormalTextureVertexRecord();
virtual Record* clone() const { return new NormalTextureVertexRecord(); }
virtual const char* className() const { return "NormalTextureVertexRecord"; }
virtual int classOpcode() const { return VERTEX_CNT_OP; }
virtual int sizeofData() const { return sizeof(SNormalTextureVertex); }
virtual void accept(RecordVisitor& rv) { rv.apply(*this); }
// virtual void traverse(RecordVisitor& rv);
virtual SNormalTextureVertex* getData() const { return (SNormalTextureVertex*)_pData; }
friend ostream& operator << (ostream& output, const NormalTextureVertexRecord& rec);
protected:
virtual ~NormalTextureVertexRecord();
virtual void endian();
};
}; // end namespace flt
#endif // __FLT_VERTEX_POOL_RECORDS_H

View File

@@ -0,0 +1,22 @@
#ifndef __FLT_EXPORT_H
#define __FLT_EXPORT_H
#define FLT_DLL
#ifdef WIN32
#pragma warning( disable : 4251 )
#pragma warning( disable : 4275 )
#pragma warning( disable : 4786 )
#endif
#if defined(FLT_DLL) && defined(_MSC_VER)
# ifdef FLT_LIBRARY
# define FLT_EXPORT __declspec(dllexport)
# else
# define FLT_EXPORT __declspec(dllimport)
# endif /* FLT_LIBRARY */
#else
# define FLT_EXPORT
#endif /* FLT_DLL && _MSC_VER */
#endif

View File

@@ -0,0 +1,45 @@
// flt.cpp
#include "flt.h"
using namespace flt;
////////////////////////////////////////////////////////////////////
int flt::isLittleEndianMachine()
{
int a = 1;
return (int)(*(char*)&a);
}
void flt::endian2(void* pSrc, int nSrc, void* pDst, int nDst)
{
if (nSrc == 2)
{
short tmp1;
tmp1 = *(short *)pSrc;
tmp1 = (tmp1 << 8) | ((tmp1 >> 8) & 0xff);
*(short *)pDst = tmp1;
}
else if (nSrc == 4)
{
long tmp1;
tmp1 = *(long *)pSrc;
tmp1 = (tmp1 << 24) | ((tmp1 << 8) & 0xff0000) | ((tmp1 >> 8) & 0xff00) | ((tmp1 >> 24) & 0xff);
*(long *)pDst = tmp1;
}
else if (nSrc == 8)
{
long tmp1, tmp2;
tmp1 = *(long *)pSrc;
tmp2 = *(1 + (long *)pSrc);
tmp1 = (tmp1 << 24) | ((tmp1 << 8) & 0xff0000) | ((tmp1 >> 8) & 0xff00) | ((tmp1 >> 24) & 0xff);
tmp2 = (tmp2 << 24) | ((tmp2 << 8) & 0xff0000) | ((tmp2 >> 8) & 0xff00) | ((tmp2 >> 24) & 0xff);
*(long *)pDst = tmp2;
*(1 + (long *)pDst) = tmp1;
}
}

175
src/osgPlugins/flt/flt.h Normal file
View File

@@ -0,0 +1,175 @@
#ifndef __FLT_H
#define __FLT_H
#include <osg/Vec4>
#ifdef OSG_USE_IO_DOT_H
#include <iostream.h>
#else
#include <iostream>
using namespace std;
#endif
namespace flt {
#define ENDIAN2(SRC, DST) endian2((void*)&(SRC), sizeof(SRC), (void*)&(DST), sizeof(DST))
#define ENDIAN(A) ENDIAN2((A), (A))
#define BIT0 0x0001
#define BIT1 0x0002
#define BIT2 0x0004
#define BIT3 0x0008
#define BIT4 0x0010
#define BIT5 0x0020
#define BIT6 0x0040
#define BIT7 0x0080
#define BIT8 0x0100
#define BIT9 0x0200
#define BIT10 0x0400
#define BIT11 0x0800
#define BIT12 0x1000
#define BIT13 0x2000
#define BIT14 0x4000
#define BIT15 0x8000
////////////////////////////////////////////////////////////////////
typedef signed char int8;
typedef unsigned char uint8;
typedef signed short int16;
typedef unsigned short uint16;
typedef signed long int32;
typedef unsigned long uint32;
typedef float float32;
typedef double float64;
////////////////////////////////////////////////////////////////////
extern int isLittleEndianMachine();
extern void endian2( void* pSrc, int nSrc, void* pDst, int nDst );
struct float32x2
{
float32 _v[2];
inline float32 x() { return _v[0]; }
inline float32 y() { return _v[1]; }
inline float32 operator [] (int i) { return _v[i]; }
void endian() {
ENDIAN( _v[0] );
ENDIAN( _v[1] );
}
friend inline ostream& operator << (ostream& output, const float32x2& f)
{
output << f._v[0] << " "
<< f._v[1];
return output; // to enable cascading
}
};
struct float32x3
{
float32 _v[3];
inline float32 x() { return _v[0]; }
inline float32 y() { return _v[1]; }
inline float32 z() { return _v[2]; }
inline float32 operator [] (int i) { return _v[i]; }
void endian() {
ENDIAN( _v[0] );
ENDIAN( _v[1] );
ENDIAN( _v[2] );
}
friend inline ostream& operator << (ostream& output, const float32x3& f)
{
output << f._v[0] << " "
<< f._v[1] << " "
<< f._v[2];
return output; // to enable cascading
}
};
struct float64x2
{
float64 _v[2];
inline float64 x() { return _v[0]; }
inline float64 y() { return _v[1]; }
inline float64 operator [] (int i) { return _v[i]; }
void endian() {
ENDIAN( _v[0] );
ENDIAN( _v[1] );
}
friend inline ostream& operator << (ostream& output, const float64x2& f)
{
output << f._v[0] << " "
<< f._v[1];
return output; // to enable cascading
}
};
struct float64x3
{
float64 _v[3];
inline float64 x() { return _v[0]; }
inline float64 y() { return _v[1]; }
inline float64 z() { return _v[2]; }
inline float64 operator [] (int i) { return _v[i]; }
void endian() {
ENDIAN( _v[0] );
ENDIAN( _v[1] );
ENDIAN( _v[2] );
}
friend inline ostream& operator << (ostream& output, const float64x3& f)
{
output << f._v[0] << " "
<< f._v[1] << " "
<< f._v[2];
return output; // to enable cascading
}
};
struct color32
{
uint8 _alpha;
uint8 _blue;
uint8 _green;
uint8 _red;
inline float red() { return (float)_red/255; }
inline float green() { return (float)_green/255; }
inline float blue() { return (float)_blue/255; }
inline float alpha() { return (float)_alpha/255; }
inline osg::Vec4 get()
{ return osg::Vec4( red(), green(), blue(), alpha()); }
};
struct SRecHeader
{
uint16 _wOpcode; // identifies record type
uint16 _wLength; // total length of record
inline int opcode() { return (int)_wOpcode; }
inline int length() { return (int)_wLength; }
void endian() {
ENDIAN( _wOpcode );
ENDIAN( _wLength );
}
};
}; // end namespace flt
#endif

View File

@@ -0,0 +1,738 @@
// flt2osg.cpp
#include <string.h>
#include "osg/GL"
#include <osg/Scene>
#include <osg/Group>
#include <osg/DCS>
#include <osg/LOD>
#include <osg/DCS>
#include <osg/Switch>
#include <osg/Sequence>
#include <osg/Geode>
#include <osg/GeoSet>
#include <osg/GeoState>
#include <osg/Material>
#include <osg/PolygonOffset>
#include <osg/Vec3>
#include <osg/Vec4>
#include <osg/Billboard>
#include <osg/Texture>
#include <osg/Image>
#include <osg/FileNameUtils>
#include <osg/Registry>
#include <osg/Notify>
#include <osg/FileNameUtils>
#include "opcodes.h"
#include "flt.h"
#include "flt2osg.h"
#include "FltFile.h"
#include "Record.h"
#include "HeaderRecord.h"
#include "ColorPaletteRecord.h"
#include "MaterialPaletteRecord.h"
#include "TexturePaletteRecord.h"
#include "VertexPoolRecords.h"
#include "GroupRecord.h"
#include "LodRecord.h"
#include "DofRecord.h"
#include "SwitchRecord.h"
#include "ObjectRecord.h"
#include "FaceRecord.h"
#include "TransformationRecords.h"
#include "ExternalRecord.h"
#include "LightPointRecord.h"
#include "Input.h"
#include "GeoSetBuilder.h"
#include "LongIDRecord.h"
using namespace flt;
ConvertFromFLT::ConvertFromFLT(FltFile* pFltFile)
{
_pFltFile = pFltFile;
_diOpenFlightVersion = 0;
_diCurrentOffset = 0;
_wObjTransparency = 0;
_nSubfaceLevel = 0;
}
ConvertFromFLT::~ConvertFromFLT()
{
}
osg::Node* ConvertFromFLT::convert(Record* rec)
{
if (rec==NULL) return NULL;
return visitNode(NULL, rec);
}
////////////////////////////////////////////////////////////////////
Record* ConvertFromFLT::getVertexFromPool(int nOffset)
{
VertexPaletteOffsetMap::iterator fitr = _VertexPaletteOffsetMap.find(nOffset);
if (fitr != _VertexPaletteOffsetMap.end())
{
return (*fitr).second;
}
else return NULL;
}
void ConvertFromFLT::regisiterVertex(int nOffset, Record* pRec)
{
_VertexPaletteOffsetMap[nOffset] = pRec;
}
////////////////////////////////////////////////////////////////////
osg::Node* ConvertFromFLT::visitNode(osg::Group* osgParent, Record* rec)
{
if (rec==NULL) return NULL;
if (rec->isOfType(HEADER_OP)) return visitHeader(osgParent, (HeaderRecord*)rec);
else if (rec->isOfType(COLOR_PALETTE_OP)) return visitColorPalette(osgParent, (ColorPaletteRecord*)rec);
else if (rec->isOfType(MATERIAL_PALETTE_OP)) return visitMaterialPalette(osgParent, (MaterialPaletteRecord*)rec);
else if (rec->isOfType(TEXTURE_PALETTE_OP)) return visitTexturePalette(osgParent, (TexturePaletteRecord*)rec);
else if (rec->isOfType(VERTEX_PALETTE_OP)) return visitVertexPalette(osgParent, (VertexPaletteRecord*)rec);
else if (rec->isOfType(VERTEX_C_OP)) return visitVertex(osgParent, (VertexRecord*)rec);
else if (rec->isOfType(VERTEX_CN_OP)) return visitNormalVertex(osgParent, (NormalVertexRecord*)rec);
else if (rec->isOfType(VERTEX_CNT_OP)) return visitNormalTextureVertex(osgParent, (NormalTextureVertexRecord*)rec);
else if (rec->isOfType(VERTEX_CT_OP)) return visitTextureVertex(osgParent, (TextureVertexRecord*)rec);
else if (rec->isOfType(GROUP_OP)) return visitGroup(osgParent, (GroupRecord*)rec);
else if (rec->isOfType(LOD_OP)) return visitLOD(osgParent, (LodRecord*)rec);
else if (rec->isOfType(OLD_LOD_OP)) return visitOldLOD(osgParent, (OldLodRecord*)rec);
else if (rec->isOfType(DOF_OP)) return visitDOF(osgParent, (DofRecord*)rec);
else if (rec->isOfType(SWITCH_OP)) return visitSwitch(osgParent, (SwitchRecord*)rec);
else if (rec->isOfType(OBJECT_OP)) return visitObject(osgParent, (ObjectRecord*)rec);
else if (rec->isOfType(EXTERNAL_REFERENCE_OP)) return visitExternal(osgParent, (ExternalRecord*)rec);
else if (rec->isOfType(MATRIX_OP)) return visitMatrix(osgParent, (MatrixRecord*)rec);
else if (rec->isOfType(LONG_ID_OP)) return visitLongID(osgParent, (LongIDRecord*)rec);
return NULL;
}
osg::Node* ConvertFromFLT::visitAncillary(osg::Group* osgParent, PrimNodeRecord* rec)
{
osg::Node* node = NULL;
// Visit
for(int i=0; i < rec->getNumChildren(); i++)
{
Record* child = rec->getChild(i);
if (child && child->isAncillaryRecord())
{
node = visitNode(osgParent, child);
if (node) osgParent = (osg::Group*)node;
}
}
return osgParent;
}
osg::Node* ConvertFromFLT::visitPrimaryNode(osg::Group* osgParent, PrimNodeRecord* rec)
{
osg::Node* node = NULL;
GeoSetBuilder geoSetBuilder(_pFltFile);
// Visit
for(int i=0; i < rec->getNumChildren(); i++)
{
Record* child = rec->getChild(i);
if (child && child->isPrimaryNode())
{
if (child->isOfType(FACE_OP))
visitFace(&geoSetBuilder, (FaceRecord*)child);
else if (child->isOfType(LIGHT_POINT_OP))
visitLightPoint(&geoSetBuilder, (LightPointRecord*)child);
else
node = visitNode(osgParent, child);
}
}
osg::Geode* geode = geoSetBuilder.createOsgGeoSets();
if (osgParent && geode)
osgParent->addChild( geode );
return node;
}
osg::Node* ConvertFromFLT::visitLongID(osg::Group* osgParent, LongIDRecord* rec)
{
SLongID *pSLongID = (SLongID*)rec->getData();
osgParent->setName(pSLongID->szIdent);
return NULL;
}
osg::Node* ConvertFromFLT::visitHeader(osg::Group* osgParent, HeaderRecord* rec)
{
SHeader *pSHeader = (SHeader*)rec->getData();
osg::Group* group = new osg::Group;
_diOpenFlightVersion = pSHeader->diFormatRevLev;
osg::notify(osg::INFO) << "Version " << _diOpenFlightVersion << endl;
if (group)
{
visitAncillary(osgParent, rec);
visitPrimaryNode(group, (PrimNodeRecord*)rec);
group->setName(pSHeader->szIdent);
if (osgParent) osgParent->addChild(group);
}
return (osg::Node*)group;
}
osg::Node* ConvertFromFLT::visitColorPalette(osg::Group* osgParent, ColorPaletteRecord* rec)
{
SColorPalette* pCol = (SColorPalette*)rec->getData();
ColorPool* pColorPool = _pFltFile->getColorPool();
if (pCol && pColorPool)
{
for (int n=0; n<1024; n++)
pColorPool->regisiterColor(n, pCol->Colors[n].get());
}
return NULL;
}
osg::Node* ConvertFromFLT::visitMaterialPalette(osg::Group* osgParent, MaterialPaletteRecord* rec)
{
SMaterial* pSMaterial = (SMaterial*)rec->getData();
MaterialPool* pMaterialPool = _pFltFile->getMaterialPool();
if (pSMaterial && pMaterialPool /* && (pMaterial->diFlags & BIT0) */)
pMaterialPool->regisiterMaterial((int)pSMaterial->diIndex, pSMaterial);
return NULL;
}
osg::Node* ConvertFromFLT::visitTexturePalette(osg::Group* osgParent, TexturePaletteRecord* rec)
{
STexturePalette* pTexture = (STexturePalette*)rec->getData();
if (pTexture)
{
osg::notify(osg::INFO) << "Texture" << pTexture->diIndex << " = " << pTexture->szFilename << endl;
osg::ref_ptr<osg::Image> image = osg::Registry::instance()->readImage(pTexture->szFilename);
if (image.valid())
{
osg::Texture *osgTexture = new osg::Texture;
TexturePool* pTexturePool = _pFltFile->getTexturePool();
if (osgTexture && pTexturePool)
{
osgTexture->setWrap( osg::Texture::WRAP_S, osg::Texture::REPEAT );
osgTexture->setWrap( osg::Texture::WRAP_T, osg::Texture::REPEAT );
osgTexture->setImage(image.get());
pTexturePool->regisiterTexture((int)pTexture->diIndex, osgTexture);
}
}
}
return NULL;
}
osg::Node* ConvertFromFLT::visitVertexPalette(osg::Group* osgParent, VertexPaletteRecord* rec)
{
_diCurrentOffset = rec->getSize();
return NULL;
}
osg::Node* ConvertFromFLT::visitVertex(osg::Group* osgParent, VertexRecord* rec)
{
regisiterVertex(_diCurrentOffset, rec);
_diCurrentOffset += rec->getSize();
return NULL;
}
osg::Node* ConvertFromFLT::visitNormalVertex(osg::Group* osgParent, NormalVertexRecord* rec)
{
regisiterVertex(_diCurrentOffset, rec);
_diCurrentOffset += rec->getSize();
return NULL;
}
osg::Node* ConvertFromFLT::visitTextureVertex(osg::Group* osgParent, TextureVertexRecord* rec)
{
regisiterVertex(_diCurrentOffset, rec);
_diCurrentOffset += rec->getSize();
return NULL;
}
osg::Node* ConvertFromFLT::visitNormalTextureVertex(osg::Group* osgParent, NormalTextureVertexRecord* rec)
{
regisiterVertex(_diCurrentOffset, rec);
_diCurrentOffset += rec->getSize();
return NULL;
}
osg::Node* ConvertFromFLT::visitGroup(osg::Group* osgParent, GroupRecord* rec)
{
osg::Group* group = new osg::Group;
if (group)
{
osg::Node* node = visitAncillary(osgParent, rec);
if (node) osgParent = (osg::Group*)node;
visitPrimaryNode(group, (PrimNodeRecord*)rec);
group->setName(rec->getData()->szIdent);
osgParent->addChild( group );
}
return (osg::Node*)group;
}
osg::Node* ConvertFromFLT::visitLOD(osg::Group* osgParent, LodRecord* rec)
{
SLevelOfDetail* pSLOD = rec->getData();
osg::LOD* lod = new osg::LOD;
osg::Group* group = new osg::Group;
if (lod && group)
{
osg::Node* node = visitAncillary(osgParent, rec);
if (node) osgParent = (osg::Group*)node;
visitPrimaryNode(group, (PrimNodeRecord*)rec);
float64x3* pCenter = &pSLOD->Center;
lod->addChild(group);
lod->setCenter(osg::Vec3(pCenter->x(), pCenter->y(), pCenter->z()));
lod->setRange(0, pSLOD->dfSwitchOutDist);
lod->setRange(1, pSLOD->dfSwitchInDist);
lod->setName(pSLOD->szIdent);
osgParent->addChild( lod );
}
return (osg::Node*)lod;
}
osg::Node* ConvertFromFLT::visitOldLOD(osg::Group* osgParent, OldLodRecord* rec)
{
osg::Group* group = new osg::Group;
if (group)
{
osg::Node* node = visitAncillary(osgParent, rec);
if (node) osgParent = (osg::Group*)node;
visitPrimaryNode(group, (PrimNodeRecord*)rec);
group->setName(rec->getData()->szIdent);
osgParent->addChild( group );
}
return (osg::Node*)group;
}
// TODO: DOF node implemented as Group.
osg::Node* ConvertFromFLT::visitDOF(osg::Group* osgParent, DofRecord* rec)
{
osg::Group* group = new osg::Group;
if (group)
{
osg::Node* node = visitAncillary(osgParent, rec);
if (node) osgParent = (osg::Group*)node;
visitPrimaryNode(group, (PrimNodeRecord*)rec);
group->setName(rec->getData()->szIdent);
osgParent->addChild( group );
}
return (osg::Node*)group;
}
osg::Node* ConvertFromFLT::visitSwitch(osg::Group* osgParent, SwitchRecord* rec)
{
osg::Switch* switc = new osg::Switch;
if (switc)
{
osg::Node* node = visitAncillary(osgParent, rec);
if (node) osgParent = (osg::Group*)node;
visitPrimaryNode(switc, (PrimNodeRecord*)rec);
switc->setName(rec->getData()->szIdent);
switc->setVal(rec->getData()->dwCurrentMask);
osgParent->addChild( switc );
/*
TODO:
mask_bit = 1 << (child_num % 32)
mask_word = mask_words [mask_num * num_words + child_num / 32]
child_selected = mask_word & mask_bit
*/
}
return (osg::Node*)switc;
}
osg::Node* ConvertFromFLT::visitObject(osg::Group* osgParent, ObjectRecord* rec)
{
osg::Group* group = new osg::Group;
if (group)
{
osg::Node* node = visitAncillary(osgParent, rec);
if (node) osgParent = (osg::Group*)node;
unsigned short wPrevTransparency = _wObjTransparency;
_wObjTransparency = rec->getData()->wTransparency;
visitPrimaryNode(group, (PrimNodeRecord*)rec);
_wObjTransparency = wPrevTransparency;
group->setName(rec->getData()->szIdent);
osgParent->addChild( group );
}
return (osg::Node*)group;
}
void ConvertFromFLT::visitFace(GeoSetBuilder* pBuilder, FaceRecord* rec)
{
SFace *pSFace = (SFace*)rec->getData();
osg::Vec4 color(1,1,1,1);
// Cull face & wireframe
int drawMode = pSFace->swDrawFlag & (BIT0 | BIT1);
switch(drawMode)
{
case FaceRecord::SOLID_BACKFACED:
pBuilder->setCullface(true);
break;
case FaceRecord::SOLID_NO_BACKFACE:
pBuilder->setCullface(false);
break;
case FaceRecord::WIREFRAME_NOT_CLOSED:
pBuilder->setPrimType(osg::GeoSet::LINE_STRIP);
break;
case FaceRecord::WIREFRAME_CLOSED:
pBuilder->setPrimType(osg::GeoSet::LINE_LOOP);
break;
}
/*
TODO:
int directionalLight = pSFace->swDrawFlag & (BIT3 | BIT4);
switch(directionalLight)
{
case FaceRecord::OMNIDIRECTIONAL_LIGHT:
break;
case FaceRecord::UNIDIRECTIONAL_LIGHT:
break;
case FaceRecord::BIDIRECTIONAL_LIGHT:
break;
}
*/
// Lighting
switch(pSFace->swLightMode)
{
case FaceRecord::FACE_COLOR:
case FaceRecord::VERTEX_COLOR:
pBuilder->setLighting(false);
break;
case FaceRecord::FACE_COLOR_LIGHTING:
case FaceRecord::VERTEX_COLOR_LIGHTING:
pBuilder->setLighting(true);
break;
}
// Color
switch(pSFace->swLightMode)
{
case FaceRecord::FACE_COLOR:
case FaceRecord::FACE_COLOR_LIGHTING:
case FaceRecord::VERTEX_COLOR:
case FaceRecord::VERTEX_COLOR_LIGHTING:
if (!(pSFace->diFlags & BIT1)) // face color bit
{
float alpha;
if (pSFace->diFlags & BIT3) // Packed color bit
color = pSFace->PrimaryPackedColor.get();
else
{
ColorPool* pColorPool = _pFltFile->getColorPool();
if (pColorPool)
color = pColorPool->getColor(pSFace->dwPrimaryColorIndex);
}
alpha = 1.0f - (float)pSFace->wTransparency / 65535.0f;
color[3] = alpha;
if (alpha < 1.0f)
pBuilder->setTransparency(true);
pBuilder->setColorBinding(osg::GeoSet::BIND_OVERALL);
pBuilder->setColor(color);
}
break;
}
// Material
MaterialPool* pMaterialPool = _pFltFile->getMaterialPool();
if (pMaterialPool)
{
SMaterial* pSMaterial = pMaterialPool->getMaterial((int)pSFace->iMaterial);
if (pSMaterial)
{
osg::Material* osgMaterial = new osg::Material;
osg::Vec4 ambient;
osg::Vec4 diffuse;
osg::Vec4 specular;
osg::Vec4 emissiv;
float alpha;
alpha = pSMaterial->sfAlpha * (1.0f - (
((float)pSFace->wTransparency / 65535.0f) * ((float)_wObjTransparency / 65535.0f) ));
ambient[0] = pSMaterial->Ambient[0] * color[0];
ambient[1] = pSMaterial->Ambient[1] * color[1];
ambient[2] = pSMaterial->Ambient[2] * color[2];
ambient[3] = alpha;
diffuse[0] = pSMaterial->Diffuse[0] * color[0];
diffuse[1] = pSMaterial->Diffuse[1] * color[1];
diffuse[2] = pSMaterial->Diffuse[2] * color[2];
diffuse[3] = alpha;
specular[0] = pSMaterial->Specular[0];
specular[1] = pSMaterial->Specular[1];
specular[2] = pSMaterial->Specular[2];
specular[3] = alpha;
emissiv[0] = pSMaterial->Emissive[0];
emissiv[1] = pSMaterial->Emissive[1];
emissiv[2] = pSMaterial->Emissive[2];
emissiv[3] = alpha;
osgMaterial->setAmbient(osg::Material::FACE_FRONT_AND_BACK, ambient);
osgMaterial->setDiffuse(osg::Material::FACE_FRONT_AND_BACK, diffuse);
osgMaterial->setSpecular(osg::Material::FACE_FRONT_AND_BACK, specular);
osgMaterial->setEmission(osg::Material::FACE_FRONT_AND_BACK, emissiv);
osgMaterial->setShininess(osg::Material::FACE_FRONT_AND_BACK, pSMaterial->sfShininess/128.0f);
osgMaterial->setColorMode(osg::Material::OFF);
if (alpha < 1.0f)
pBuilder->setTransparency(true);
pBuilder->setMaterial(osgMaterial);
}
}
// Subface
if (rec->getParent()->isOfType(FACE_OP))
{
pBuilder->setSubface(_nSubfaceLevel);
}
// Texture
TexturePool* pTexturePool = _pFltFile->getTexturePool();
if (pTexturePool)
{
osg::Texture* osgTexture = pTexturePool->getTexture((int)pSFace->iTexturePattern);
if (osgTexture)
{
osg::Image* image = osgTexture->getImage();
if (image)
{
switch (image->pixelFormat())
{
case GL_LUMINANCE_ALPHA:
case GL_RGBA:
pBuilder->setTransparency(true);
break;
}
}
pBuilder->setTexture(osgTexture);
}
}
// Visit vertices
for(int i=0; i < rec->getNumChildren(); i++)
{
Record* child = rec->getChild(i);
if (child)
{
int op = child->getOpcode();
switch (op)
{
case VERTEX_LIST_OP:
visitVertexList(pBuilder, (VertexListRecord*)child);
break;
case OLD_VERTEX_OP:
case OLD_VERTEX_COLOR_OP:
case OLD_VERTEX_COLOR_NORMAL_OP:
pBuilder->addVertex(child);
break;
}
}
}
// Add primitive to GeoSet and prepare for next.
pBuilder->addPrimitive();
// Look for sufbfaces
_nSubfaceLevel++;
for(i=0; i < rec->getNumChildren(); i++)
{
Record* child = rec->getChild(i);
if (child && child->isOfType(FACE_OP))
visitFace(pBuilder, (FaceRecord*)child);
}
_nSubfaceLevel--;
}
void ConvertFromFLT::visitVertexList(GeoSetBuilder* pBuilder, VertexListRecord* rec)
{
int vertices = rec->numberOfVertices();
// Add vertices to GeoSetBuilder
if (pBuilder->getPrimType() == osg::GeoSet::POINTS)
{
for (int i=0; i < vertices; i++)
{
Record* vertex = getVertexFromPool(rec->getVertexPoolOffset(i));
if (vertex)
{
pBuilder->setPrimType(osg::GeoSet::POINTS);
pBuilder->setColorBinding(osg::GeoSet::BIND_PERVERTEX);
pBuilder->addVertex(vertex);
pBuilder->addPrimitive();
}
}
}
else
{
for (int i=0; i < vertices; i++)
{
Record* vertex = getVertexFromPool(rec->getVertexPoolOffset(i));
if (vertex)
pBuilder->addVertex(vertex);
}
}
}
osg::Node* ConvertFromFLT::visitMatrix(osg::Group* osgParent, MatrixRecord* rec)
{
SMatrix* pSMatrix = (SMatrix*)rec->getData();
osg::DCS* dcs = new osg::DCS;
if (dcs)
{
osg::Matrix m;
for(int i=0;i<4;++i)
{
for(int j=0;j<4;++j)
{
m._mat[i][j] = pSMatrix->sfMat[i][j];
}
}
dcs->setMatrix(m);
osgParent->addChild(dcs);
return (osg::Node*)dcs;
}
return NULL;
}
osg::Node* ConvertFromFLT::visitExternal(osg::Group* osgParent, ExternalRecord* rec)
{
SExternalReference *pSExternal = (SExternalReference*)rec->getData();
if (osgParent)
{
osg::Node* node = visitAncillary(osgParent, rec);
if (node) osgParent = (osg::Group*)node;
FltFile* pFile = rec->getExternal();
if (pFile)
{
node = pFile->convert();
if (node)
{
osgParent->addChild(node);
return node;
}
}
}
return NULL;
}
void ConvertFromFLT::visitLightPoint(GeoSetBuilder* pBuilder, LightPointRecord* rec)
{
SLightPoint *pSLightPoint = (SLightPoint*)rec->getData();
// Visit vertices
for(int i=0; i < rec->getNumChildren(); i++)
{
Record* child = rec->getChild(i);
if (child)
{
int op = child->getOpcode();
switch (op)
{
case VERTEX_LIST_OP:
pBuilder->setPrimType(osg::GeoSet::POINTS);
visitVertexList(pBuilder, (VertexListRecord*)child);
break;
case OLD_VERTEX_OP:
case OLD_VERTEX_COLOR_OP:
case OLD_VERTEX_COLOR_NORMAL_OP:
pBuilder->setColorBinding(osg::GeoSet::BIND_PERVERTEX);
pBuilder->addVertex(child);
pBuilder->addPrimitive();
break;
}
}
}
}

View File

@@ -0,0 +1,116 @@
// flt2osg.h
#ifndef __FLT_2_OSG_H
#define __FLT_2_OSG_H
#include <map>
#include <vector>
#include <string>
#include <osg/Vec4>
#include "Record.h"
namespace osg {
class Object;
class Group;
class LOD;
class Geode;
class GeoSet;
class Material;
class Texture;
class Vec4;
};
namespace flt {
class Record;
class HeaderRecord;
class ColorPaletteRecord;
class MaterialPaletteRecord;
class TexturePaletteRecord;
class VertexPaletteRecord;
class VertexRecord;
class NormalVertexRecord;
class TextureVertexRecord;
class NormalTextureVertexRecord;
class GroupRecord;
class LodRecord;
class OldLodRecord;
class DofRecord;
class SwitchRecord;
class ObjectRecord;
class FaceRecord;
class MatrixRecord;
class ExternalRecord;
class LightPointRecord;
class VertexListRecord;
class LongIDRecord;
class GeoSetBuilder;
class FltFile;
struct SMaterial;
class ConvertFromFLT
{
public:
ConvertFromFLT(FltFile* pFltFile);
virtual ~ConvertFromFLT();
osg::Node* convert(Record* rec);
osg::Node* visitNode(osg::Group* osgParent,Record* rec);
osg::Node* visitAncillary(osg::Group* osgParent, PrimNodeRecord* rec);
osg::Node* visitPrimaryNode(osg::Group* osgParent, PrimNodeRecord* rec);
osg::Node* visitLongID(osg::Group* osgParent, LongIDRecord* rec);
osg::Node* visitHeader(osg::Group* osgParent, HeaderRecord* rec);
osg::Node* visitColorPalette(osg::Group* osgParent, ColorPaletteRecord* rec);
osg::Node* visitMaterialPalette(osg::Group* osgParent, MaterialPaletteRecord* rec);
osg::Node* visitTexturePalette(osg::Group* osgParent, TexturePaletteRecord* rec);
osg::Node* visitVertexPalette(osg::Group* osgParent, VertexPaletteRecord* rec);
osg::Node* visitVertex(osg::Group* osgParent, VertexRecord* rec);
osg::Node* visitNormalVertex(osg::Group* osgParent, NormalVertexRecord* rec);
osg::Node* visitTextureVertex(osg::Group* osgParent, TextureVertexRecord* rec);
osg::Node* visitNormalTextureVertex(osg::Group* osgParent, NormalTextureVertexRecord* rec);
osg::Node* visitGroup(osg::Group* osgParent, GroupRecord* rec);
osg::Node* visitLOD(osg::Group* osgParent, LodRecord* rec);
osg::Node* visitOldLOD(osg::Group* osgParent, OldLodRecord* rec);
osg::Node* visitDOF(osg::Group* osgParent, DofRecord* rec);
osg::Node* visitSwitch(osg::Group* osgParent, SwitchRecord* rec);
osg::Node* visitObject(osg::Group* osgParent, ObjectRecord* rec);
osg::Node* visitMatrix(osg::Group* osgParent, MatrixRecord* rec);
osg::Node* visitExternal(osg::Group* osgParent, ExternalRecord* rec);
void visitFace(GeoSetBuilder* pParent, FaceRecord* rec);
void visitLightPoint(GeoSetBuilder* pBuilder, LightPointRecord* rec);
void visitVertexList(GeoSetBuilder* pParent, VertexListRecord* rec);
private:
Record* getVertexFromPool(int nOffset);
void regisiterVertex(int nOffset, Record* pRec);
typedef std::map<int,Record*> VertexPaletteOffsetMap;
VertexPaletteOffsetMap _VertexPaletteOffsetMap;
FltFile* _pFltFile;
int _diOpenFlightVersion;
int _diCurrentOffset;
unsigned short _wObjTransparency;
int _nSubfaceLevel;
};
}; // end namespace flt
#endif // __FLT_2_OSG_H

View File

@@ -0,0 +1,28 @@
//
// OpenFlight<68> loader for Open Scene Graph
//
// Copyright (C) 2000 Brede Johansen
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would be
// appreciated but is not required.
// 2. Altered source versions must be plainly marked as such, and must not be
// misrepresented as being the original software.
// 3. This notice may not be removed or altered from any source distribution.
//
// The Open Scene Graph (OSG) is a cross platform C++/OpenGL library for
// real-time rendering of large 3D photo-realistic models.
// The OSG homepage is http://www.openscenegraph.org/
//
// MultiGen, OpenFlight, and Flight Format are registered trademarks of MultiGen Inc.
//

View File

@@ -0,0 +1,70 @@
// Opcode.h
#ifndef __FLT_OPCODE_H
#define __FLT_OPCODE_H
#define OF_VERSION 1520 //OpenFlight version
#define UNKNOWN_OP 0
#define HEADER_OP 1
#define GROUP_OP 2
#define OLD_LOD_OP 3
#define OBJECT_OP 4
#define FACE_OP 5
#define OLD_VERTEX_OP 7
#define OLD_VERTEX_COLOR_OP 8
#define OLD_VERTEX_COLOR_NORMAL_OP 9
#define PUSH_LEVEL_OP 10
#define POP_LEVEL_OP 11
#define DOF_OP 14
#define PUSH_SUBFACE_OP 19
#define POP_SUBFACE_OP 20
#define PUSH_EXTENSION_OP 21
#define POP_EXTENSION_OP 22
#define COMMENT_OP 31
#define COLOR_PALETTE_OP 32
#define LONG_ID_OP 33
// Opcodes 40 to 48 are obsolete
#define MATRIX_OP 49
#define VECTOR_OP 50
#define REPLICATE_OP 60
#define INSTANCE_REFERENCE_OP 61
#define INSTANCE_DEFINITION_OP 62
#define EXTERNAL_REFERENCE_OP 63
#define TEXTURE_PALETTE_OP 64
#define VERTEX_PALETTE_OP 67
#define VERTEX_C_OP 68
#define VERTEX_CN_OP 69
#define VERTEX_CNT_OP 70
#define VERTEX_CT_OP 71
#define VERTEX_LIST_OP 72
#define LOD_OP 73
#define BOUNDING_BOX_OP 74
#define ROTATE_ABOUT_EDGE_OP 76
#define TRANSLATE_OP 78
#define SCALE_OP 79
#define ROTATE_ABOUT_POINT_OP 80
#define ROTATE_SCALE_TO_POINT_OP 81
#define PUT_TRANSFORM_OP 82
#define ROAD_ZONE_OP 88
#define MORPH_VERTEX_LIST_OP 89
#define GENERAL_MATRIX_OP 94
#define SWITCH_OP 96
#define EXTENSION_OP 100
#define LIGHT_SOURCE_OP 101
#define LIGHT_SOURCE_PALETTE_OP 102
#define BOUNDING_SPHERE_OP 105
#define BOUNDING_CYLINDER_OP 106
#define BOUNDING_VOLUME_CENTER_OP 108
#define BOUNDING_VOLUME_ORIENTATION_OP 109
#define LIGHT_POINT_OP 111
#define TEXTURE_MAPPING_PALETTE_OP 112
#define MATERIAL_PALETTE_OP 113
#define CAT_OP 115
#define CAT_DATA_OP 116
#endif // __FLT_OPCODE_H

View File

View File

@@ -0,0 +1,26 @@
#!smake
include ../../../Make/makedefs
C++FILES = \
hat.cpp\
vector.cpp\
matrix.cpp\
fly.cpp\
terrain.cpp\
tank.cpp\
sky.cpp\
base.cpp\
trees.cpp\
LIB = ../../../lib/osgPlugins/osgdb_fly.so
TARGET_LOADER_FILES = osgPlugins/osgdb_fly.so
C++FLAGS += -I../../../include
LDFLAGS += -L../../../lib
include ../../../Make/makerules

View File

@@ -0,0 +1,97 @@
#include <math.h>
#include <osg/OSG>
#include <osg/Geode>
#include <osg/GeoSet>
#include <osg/Texture>
#include <osg/GeoState>
#include <osg/Registry>
using namespace osg;
Node *makeBase( void )
{
int i, c;
float theta;
float ir, ori;
ir = 6.0;
ori = 20.0;
Vec3 *coords = new Vec3[38];
Vec2 *tcoords = new Vec2[38];
Vec4 *colors = new Vec4[1];
int *lengths = new int[1];
colors[0][0] = colors[0][1] = colors[0][2] = colors[0][3] = 1;
c = 0;
for( i = 0; i <= 18; i++ )
{
theta = (float)i * 20.0 * M_PI/180.0;
coords[c][0] = ir * cosf( theta );
coords[c][1] = ir * sinf( theta );
coords[c][2] = 0.0;
tcoords[c][0] = coords[c][0]/36.;
tcoords[c][1] = coords[c][1]/36.;
c++;
coords[c][0] = ori * cosf( theta );
coords[c][1] = ori * sinf( theta );
coords[c][2] = 0.0f;
tcoords[c][0] = coords[c][0]/36.;
tcoords[c][1] = coords[c][1]/36.;
c++;
}
*lengths = 38;
GeoSet *gset = new GeoSet;
gset->setCoords( coords );
gset->setTextureCoords( tcoords );
gset->setTextureBinding( GeoSet::BIND_PERVERTEX );
gset->setColors( colors );
gset->setColorBinding( GeoSet::BIND_OVERALL );
gset->setPrimType( GeoSet::TRIANGLE_STRIP );
gset->setNumPrims( 1 );
gset->setPrimLengths( lengths );
Texture *tex = new Texture;
tex->setImage(Registry::instance()->readImage("water.rgb"));
tex->setWrap( Texture::WRAP_S, Texture::REPEAT );
tex->setWrap( Texture::WRAP_T, Texture::REPEAT );
GeoState *gstate = new GeoState;
gstate->setMode( GeoState::TEXTURE, GeoState::ON );
gstate->setMode( GeoState::LIGHTING, GeoState::OFF );
gstate->setAttribute( GeoState::TEXTURE, tex );
gstate->setAttribute( GeoState::TEXENV, new TexEnv );
/*
pfFog *fog = new pfFog;
fog->setFogType( PFFOG_PIX_EXP2 );
fog->setColor( 0.1, 0.2, 0.2 );
fog->setRange( 16.0, 22.0 );
gstate->setMode( PFSTATE_ENFOG, PF_ON );
gstate->setAttr( PFSTATE_FOG, fog );
*/
gset->setGeoState( gstate );
Geode *geode = new Geode;
geode->addGeoSet( gset );
return geode;
}

137
src/osgPlugins/fly/fly.cpp Normal file
View File

@@ -0,0 +1,137 @@
#include <stdio.h>
#include <string.h>
#include <osg/OSG>
#include <osg/Geode>
#include <osg/Group>
#include <osg/Registry>
#include <osg/Notify>
using namespace osg;
extern Node *makeTerrain( void );
extern Node *makeTrees( void );
extern Node *makeTank( void );
extern Node *makeWindsocks( void );
extern Node *makeGliders( void );
extern Node *makeGlider( void );
extern Node *makeSky( void );
extern Node *makeBase( void );
extern Node *makeClouds( void );
extern "C" {
Node* LoadFile_fly( const char *file );
void InitConverter_fly( void );
}
static struct _nodes {
char *name;
Node *(*fptr)(void);
}nodes[] = {
{ "terrain", makeTerrain },
{ "tank", makeTank },
{ "sky", makeSky },
{ "base", makeBase },
{ "trees", makeTrees },
// { "gliders", makeGliders },
// { "clouds", makeClouds },
{ 0L, 0L }
};
void InitConverter_fly( void )
{
}
Node* LoadFile_fly( const char *file )
{
char buff[256];
osg::notify(osg::INFO)<< "sgLoadFile_fly( "<<file<< ")\n";
FILE *fp;
if( (fp = fopen( file, "r" )) == (FILE *)0L )
{
osg::notify(osg::WARN)<< "Unable to open file \""<<file<<"\"\n";
return 0L;
}
Group *grp = new Group;
while( !feof( fp ) )
{
_nodes *nptr;
fgets( buff, sizeof( buff ), fp );
if( buff[0] == '#' )
continue;
for( nptr = nodes; nptr->name; nptr ++ )
{
if( !strncmp( buff, nptr->name, strlen( nptr->name ) ))
{
Node *node = nptr->fptr();
node->setName( nptr->name );
grp->addChild( node );
break;
}
}
}
fclose( fp );
return grp;
}
class sgReaderWriterFLY : public ReaderWriter {
public:
virtual const char* className() { return "Default FLY Database Reader/Writer"; }
virtual bool acceptsExtension(const std::string& extension) { return extension=="fly"; }
virtual Node* readNode(const std::string& fileName)
{
char buff[256];
osg::notify(osg::INFO)<< "sgReaderWriterFLY::readNode( "<<fileName.c_str()<<" )\n";
FILE *fp;
if( (fp = fopen( fileName.c_str(), "r" )) == (FILE *)0L )
{
osg::notify(osg::WARN)<< "Unable to open file \""<<fileName.c_str()<<"\"\n";
return 0L;
}
Group *grp = new Group;
while( !feof( fp ) )
{
_nodes *nptr;
fgets( buff, sizeof( buff ), fp );
if( buff[0] == '#' )
continue;
for( nptr = nodes; nptr->name; nptr ++ )
{
if( !strncmp( buff, nptr->name, strlen( nptr->name ) ))
{
Node *node = nptr->fptr();
node->setName( nptr->name );
grp->addChild( node );
break;
}
}
}
fclose( fp );
return grp;
}
virtual bool writeNode(Node& obj,const std::string& fileName) {
return false;
}
};
// now register with sgRegistry to instantiate the above
// reader/writer.
RegisterReaderWriterProxy<sgReaderWriterFLY> g_readerWriter_FLY_Proxy;

149
src/osgPlugins/fly/hat.cpp Normal file
View File

@@ -0,0 +1,149 @@
#ifdef WIN32
#include <Windows.h>
#pragma warning( disable : 4244 )
#endif
#include <GL/gl.h>
#include <math.h>
#include <stdio.h>
#include "terrain_data.h"
#include "hat.h"
static int inited = 0;
static float dbcenter[3];
static float dbradius;
static void getDatabaseCenterRadius( float dbcenter[3], float *dbradius )
{
int i;
double n=0.0;
double center[3] = { 0.0f, 0.0f, 0.0f };
float cnt;
cnt = 39 * 38;
for( i = 0; i < cnt; i++ )
{
center[0] += (double)vertex[i][0];
center[1] += (double)vertex[i][1];
center[2] += (double)vertex[i][2];
n = n + 1.0;
}
center[0] /= n;
center[1] /= n;
center[2] /= n;
float r = 0.0;
// for( i = 0; i < sizeof( vertex ) / (sizeof( float[3] )); i++ )
for( i = 0; i < cnt; i++ )
{
double d = sqrt(
(((double)vertex[i][0] - center[0]) * ((double)vertex[i][0] - center[0])) +
(((double)vertex[i][1] - center[1]) * ((double)vertex[i][1] - center[1])) +
(((double)vertex[i][2] - center[2]) * ((double)vertex[i][2] - center[2])) );
if( d > (double)r ) r = (float)d;
}
*dbradius = r;
dbcenter[0] = (float)center[0];
dbcenter[1] = (float)center[1];
dbcenter[2] = (float)center[2];
int index = 19 * 39 + 19;
dbcenter[0] = vertex[index][0] - 0.15;
dbcenter[1] = vertex[index][1];
dbcenter[2] = vertex[index][2] + 0.35;
}
static void init( void )
{
getDatabaseCenterRadius( dbcenter, &dbradius );
inited = 1;
}
static void getNormal( float *v1, float *v2, float *v3, float *n )
{
float V1[4], V2[4];
float f;
int i;
/* Two vectors v2->v1 and v2->v3 */
for( i = 0; i < 3; i++ )
{
V1[i] = v1[i] - v2[i];
V2[i] = v3[i] - v2[i];
}
/* Cross product between V1 and V2 */
n[0] = (V1[1] * V2[2]) - (V1[2] * V2[1]);
n[1] = -((V1[0] * V2[2]) - ( V1[2] * V2[0] ));
n[2] = (V1[0] * V2[1] ) - (V1[1] * V2[0] );
/* Normalize */
f = sqrtf( ( n[0] * n[0] ) + ( n[1] * n[1] ) + ( n[2] * n[2] ) );
n[0] /= f;
n[1] /= f;
n[2] /= f;
}
float Hat( float x, float y, float z )
{
int m, n;
int i, j;
float tri[3][3];
float norm[3];
float d, pz;
if( inited == 0 ) init();
// m = columns
// n = rows
m = (sizeof( vertex ) /(sizeof( float[3])))/39;
n = 39;
i = 0;
while( i < ((m-1)*39) && x > (vertex[i+n][0] - dbcenter[0]) )
i += n;
j = 0;
while( j < n-1 && y > (vertex[i+j+1][1] - dbcenter[1]) )
j++;
tri[0][0] = vertex[i+0+j+0][0] - dbcenter[0];
tri[0][1] = vertex[i+0+j+0][1] - dbcenter[1];
//tri[0][2] = vertex[i+0+j+0][2] - dbcenter[2];
tri[0][2] = vertex[i+0+j+0][2];
tri[1][0] = vertex[i+n+j+0][0] - dbcenter[0];
tri[1][1] = vertex[i+n+j+0][1] - dbcenter[1];
//tri[1][2] = vertex[i+n+j+0][2] - dbcenter[2];
tri[1][2] = vertex[i+n+j+0][2];
tri[2][0] = vertex[i+0+j+1][0] - dbcenter[0];
tri[2][1] = vertex[i+0+j+1][1] - dbcenter[1];
//tri[2][2] = vertex[i+0+j+1][2] - dbcenter[2];
tri[2][2] = vertex[i+0+j+1][2];
getNormal( tri[0], tri[1], tri[2], norm );
d = (tri[0][0] * norm[0]) +
(tri[0][1] * norm[1]) +
(tri[0][2] * norm[2]);
d *= -1;
pz = (-(norm[0] * x) - (norm[1] * y) - d)/norm[2];
return z - pz;
}

4
src/osgPlugins/fly/hat.h Normal file
View File

@@ -0,0 +1,4 @@
#ifndef __HAT_H
#define __HAT_H
extern float Hat( float x, float y, float z );
#endif

View File

@@ -0,0 +1,113 @@
#include <string.h>
#include <math.h>
#include "matrix.h"
#include <osg/Types>
static float ID[4][4] = {
{ 1.0, 0.0, 0.0, 0.0 },
{ 0.0, 1.0, 0.0, 0.0 },
{ 0.0, 0.0, 1.0, 0.0 },
{ 0.0, 0.0, 0.0, 1.0 },
};
static float M[2][4][4];
static int mi = 0;
static float R[4][4];
static float T[4][4];
static float S[4][4];
static void preMultiply( float m[4][4] )
{
int i, j, k;
int mo;
mo = 1 - mi;
for( i = 0; i < 4; i++ )
{
for( j = 0; j < 4; j++ )
{
M[mo][i][j] = 0.0;
for( k = 0; k < 4; k++ )
M[mo][i][j] += m[i][k] * M[mi][k][j];
}
}
mi = mo;
}
void m_LoadID( void )
{
memcpy( M[mi], ID, sizeof( float ) * 16 );
}
void m_Rotate( float a, char axis )
{
float theta;
theta = a * M_PI/180.0;
memcpy( R, ID, sizeof( float) * 16 );
switch( axis )
{
case 'x' :
R[1][1] = cosf( theta );
R[1][2] = -sinf( theta );
R[2][1] = sinf( theta );
R[2][2] = cosf( theta );
break;
case 'y' :
R[0][0] = cosf( theta );
R[0][2] = -sinf( theta );
R[2][0] = sinf( theta );
R[2][2] = cosf( theta );
break;
case 'z' :
R[0][0] = cosf( theta );
R[0][1] = -sinf( theta );
R[1][0] = sinf( theta );
R[1][1] = cosf( theta );
break;
}
preMultiply( R );
}
void m_Translate( float x, float y, float z )
{
memcpy( T, ID, sizeof( float) * 16 );
T[3][0] = x;
T[3][1] = y;
T[3][2] = z;
preMultiply( T );
}
void m_Scale( float x, float y, float z )
{
memcpy( S, ID, sizeof( float ) * 16 );
S[0][0] = x;
S[1][1] = y;
S[2][2] = z;
preMultiply( S );
}
void m_MultV( float v[4], float r[4] )
{
int i, j;
for( i = 0; i < 4; i++ )
{
r[i] = 0.0;
for( j = 0; j < 4; j++ )
r[i] += v[j] * M[mi][j][i];
}
}

View File

@@ -0,0 +1,15 @@
#ifndef __MATRIX_H
#define __MATRIX_H
extern void m_LoadID( void );
extern void m_Rotate( float, char );
extern void m_Translate( float, float, float );
extern void m_Scale( float, float, float );
extern void m_MultV( float [4], float [4] );
#endif

View File

@@ -0,0 +1,261 @@
#include <stdlib.h>
#include <osg/OSG>
#include <osg/Billboard>
#include <osg/Group>
#include <osg/Geode>
#include <osg/GeoSet>
#include <osg/Texture>
#include <osg/Registry>
#include "hat.h"
#ifdef WIN32
#pragma warning( disable : 4244 )
#pragma warning( disable : 4305 )
#endif
using namespace osg;
#define sqr(x) ((x)*(x))
extern void getDatabaseCenterRadius( float dbcenter[3], float *dbradius );
static float dbcenter[3], dbradius;
static struct _tree{
int n;
float x, y, z;
float w, h;
}trees[] = {
{ 0, -0.4769, -0.8972, -0.4011, 0.2000, 0.1200 },
{ 1, -0.2543, -0.9117, -0.3873, 0.2000, 0.1200 },
{ 2, -0.0424, -0.8538, -0.3728, 0.2000, 0.1200 },
{ 3, 0.1590, -0.8827, -0.3594, 0.2000, 0.1200 },
{ 4, -0.4981, -1.0853, -0.4016, 0.3500, 0.1200 },
{ 5, -0.5405, -1.2590, -0.4050, 0.2000, 0.1200 },
{ 6, -0.5723, -1.5339, -0.4152, 0.2000, 0.1200 },
{ 7, -0.6252, -1.8667, -0.4280, 0.2000, 0.1200 },
{ 8, -0.5617, -2.1851, -0.4309, 0.2000, 0.1200 },
{ 9, -0.5087, -2.4166, -0.4215, 0.2000, 0.1200 },
{ 10, -0.4345, -2.3443, -0.4214, 0.2000, 0.1200 },
{ 11, -3.0308, -1.5484, -0.4876, 0.2000, 0.1200 },
{ 12, -3.0202, -1.6497, -0.4963, 0.2000, 0.1200 },
{ 13, -2.9355, -1.8378, -0.4969, 0.2000, 0.1200 },
{ 14, -0.6040, -2.0259, -0.4300, 0.2000, 0.1200 },
{ 15, -0.5442, -1.3442, -0.4080, 0.1000, 0.1200 },
{ 16, -0.5639, -1.6885, -0.4201, 0.1000, 0.1200 },
{ 17, 0.9246, 3.4835, 0.5898, 0.2500, 0.1000 },
{ 18, 0.0787, 3.8687, 0.3329, 0.2500, 0.1200 },
{ 19, 0.2885, 3.7130, 0.4047, 0.2500, 0.1200 },
{ 20, 0.2033, 3.6228, 0.3704, 0.2500, 0.1200 },
{ 21, -0.2098, 3.9015, 0.2327, 0.2500, 0.1200 },
{ 22, -0.3738, 3.7376, 0.1722, 0.2500, 0.1200 },
{ 23, -0.2557, 3.6064, 0.1989, 0.2500, 0.1200 },
{ 24, 0.0590, 3.7294, 0.3210, 0.2500, 0.1200 },
{ 25, -0.4721, 3.8851, 0.1525, 0.2500, 0.1200 },
{ 26, 0.9639, 3.2048, 0.5868, 0.1200, 0.0800 },
{ 27, 0.7082, -1.0409, -0.3221, 0.1000, 0.1000 },
{ 28, -0.2426, -2.3442, -0.4150, 0.1000, 0.1380 },
{ 29, -0.1770, -2.4179, -0.4095, 0.1000, 0.1580 },
{ 30, -0.0852, -2.5327, -0.4056, 0.1000, 0.1130 },
{ 31, -0.0131, -2.6065, -0.4031, 0.1000, 0.1150 },
{ 32, 0.0787, -2.6638, -0.4012, 0.1000, 0.1510 },
{ 33, 0.1049, -2.7622, -0.3964, 0.1000, 0.1270 },
{ 34, 0.1770, -2.8687, -0.3953, 0.1000, 0.1100 },
{ 35, 0.3213, -2.9507, -0.3974, 0.1000, 0.1190 },
{ 36, 0.4065, -3.0163, -0.4014, 0.1000, 0.1120 },
{ 37, 0.3738, -3.1802, -0.4025, 0.1000, 0.1860 },
{ 38, 0.5508, -3.2048, -0.3966, 0.1000, 0.1490 },
{ 39, 0.5836, -3.3031, -0.3900, 0.1000, 0.1670 },
{ 40, -0.3082, -2.7212, -0.3933, 0.1000, 0.1840 },
{ 41, -0.1967, -2.6474, -0.4017, 0.1000, 0.1600 },
{ 42, -0.1180, -2.7458, -0.3980, 0.1000, 0.1250 },
{ 43, -0.3344, -2.8359, -0.3964, 0.1000, 0.1430 },
{ 44, -0.2492, -2.8933, -0.3838, 0.1000, 0.1890 },
{ 45, -0.1246, -3.0491, -0.3768, 0.1000, 0.1830 },
{ 46, 0.0000, -3.0818, -0.3696, 0.1000, 0.1370 },
{ 47, -0.2295, -3.0409, -0.3706, 0.1000, 0.1660 },
{ 48, -1.3245, 2.6638, 0.0733, 0.0500, 0.0500 },
{ 49, 2.2425, -1.5491, -0.2821, 0.2300, 0.1200 },
{ 50, 0.2164, -2.1311, -0.4000, 0.1000, 0.0690 },
{ 51, 0.2885, -2.2130, -0.4000, 0.1000, 0.0790 },
{ 52, 0.3606, -2.2786, -0.4000, 0.1000, 0.0565 },
{ 53, 0.4328, -2.3442, -0.4000, 0.1000, 0.0575 },
{ 54, 0.5246, -2.4343, -0.4086, 0.1000, 0.0755 },
{ 55, 0.6360, -2.5245, -0.4079, 0.1000, 0.0635 },
{ 56, 0.7541, -2.4261, -0.4007, 0.1000, 0.0550 },
{ 57, 0.7934, -2.2786, -0.3944, 0.1000, 0.0595 },
{ 58, 1.0295, -2.2868, -0.3837, 0.1000, 0.0560 },
{ 59, 0.8459, -2.6474, -0.4051, 0.1000, 0.0930 },
{ 60, 1.0426, -2.6884, -0.4001, 0.1000, 0.0745 },
{ 61, 1.1475, -2.7458, -0.3883, 0.1000, 0.0835 },
{ 62, -0.1967, -1.4180, -0.3988, 0.1000, 0.0920 },
{ 63, -0.0131, -1.2704, -0.3856, 0.1000, 0.0690 },
{ 64, 0.2098, -1.2049, -0.3664, 0.1000, 0.0790 },
{ 65, 0.3410, -1.3196, -0.3652, 0.1000, 0.0565 },
{ 66, 0.5705, -1.2704, -0.3467, 0.1000, 0.0575 },
{ 67, 0.6360, -1.4344, -0.3532, 0.1000, 0.0755 },
{ 68, 0.9246, -1.4180, -0.3329, 0.1000, 0.0635 },
{ 69, 1.0623, -1.3360, -0.3183, 0.1000, 0.0550 },
{ 70, 1.2393, -1.3934, -0.3103, 0.1000, 0.0595 },
{ 71, 1.3639, -1.4753, -0.3079, 0.1000, 0.0560 },
{ 72, 1.4819, -1.5983, -0.3210, 0.1000, 0.0930 },
{ 73, 1.7835, -1.5819, -0.3065, 0.1000, 0.0745 },
{ 74, 1.9343, -2.1065, -0.3307, 0.1000, 0.0835 },
{ 75, 2.1245, -2.3196, -0.3314, 0.1000, 0.0920 },
{ 76, 2.2556, -2.3032, -0.3230, 0.1000, 0.0800 },
{ 77, 2.4196, -2.3688, -0.3165, 0.1000, 0.0625 },
{ 78, 1.7835, -2.5327, -0.3543, 0.1000, 0.0715 },
{ 79, 1.7180, -2.8933, -0.3742, 0.1000, 0.0945 },
{ 80, 1.9343, -3.0409, -0.3727, 0.1000, 0.0915 },
{ 81, 2.4524, -3.4671, -0.3900, 0.1000, 0.0685 },
{ 82, 2.4786, -2.8851, -0.3538, 0.1000, 0.0830 },
{ 83, 2.3343, -2.6228, -0.3420, 0.1000, 0.0830 },
{ 84, 2.8130, -2.0737, -0.2706, 0.1000, 0.0890 },
{ 85, 2.6360, -1.8278, -0.2661, 0.1000, 0.0975 },
{ 86, 2.3958, -1.7130, -0.2774, 0.2000, 0.1555 },
{ 87, 2.2688, -1.2868, -0.2646, 0.1000, 0.0835 },
{ 88, 2.4196, -1.1147, -0.2486, 0.1000, 0.0770 },
{ 89, 2.7802, -2.3933, -0.3017, 0.1000, 0.0655 },
{ 90, 3.0163, -2.4179, -0.2905, 0.1000, 0.0725 },
{ 91, 2.9310, -2.2540, -0.2798, 0.1000, 0.0910 },
{ 92, 2.6622, -2.0983, -0.2823, 0.1000, 0.0680 },
{ 93, 2.3147, -1.9753, -0.2973, 0.1000, 0.0620 },
{ 94, 2.1573, -1.8770, -0.3013, 0.1000, 0.0525 },
{ 95, 2.0196, -1.7868, -0.3044, 0.1000, 0.0970 },
{ 96, 2.7802, -3.3031, -0.3900, 0.1000, 0.0510 },
{ 97, 2.8589, -3.1720, -0.3900, 0.1000, 0.0755 },
{ 98, 3.0163, -2.8114, -0.3383, 0.1000, 0.0835 },
{ 99, 3.5081, -2.4179, -0.2558, 0.1000, 0.0770 },
{ 100, 3.5277, -2.3196, -0.2366, 0.1000, 0.0765 },
{ 101, 3.6654, -2.5819, -0.2566, 0.1000, 0.0805 },
{ 102, 3.7179, -2.7622, -0.2706, 0.1000, 0.0980 },
{ 103, 3.7769, -2.4671, -0.2339, 0.1000, 0.0640 },
{ 104, 3.3441, -2.4671, -0.2693, 0.1000, 0.0940 },
{ -1, 0, 0, 0, 0, 0 },
};
static GeoSet *makeTree( _tree *tree, GeoState *gstate )
{
float vv[][3] = {
{ -tree->w/2.0, 0.0, 0.0 },
{ tree->w/2.0, 0.0, 0.0 },
{ tree->w/2.0, 0.0, 2 * tree->h },
{ -tree->w/2.0, 0.0, 2 * tree->h },
};
Vec3 *v = new Vec3[4];
Vec2 *t = new Vec2[4];
Vec4 *l = new Vec4[1];
int i;
l[0][0] = l[0][1] = l[0][2] = l[0][3] = 1;
for( i = 0; i < 4; i++ )
{
v[i][0] = vv[i][0];
v[i][1] = vv[i][1];
v[i][2] = vv[i][2];
}
t[0][0] = 0.0; t[0][1] = 0.0;
t[1][0] = 1.0; t[1][1] = 0.0;
t[2][0] = 1.0; t[2][1] = 1.0;
t[3][0] = 0.0; t[3][1] = 1.0;
GeoSet *gset = new GeoSet;
gset->setCoords( v );
gset->setTextureCoords( t );
gset->setTextureBinding( GeoSet::BIND_PERVERTEX );
gset->setColors( l );
gset->setColorBinding( GeoSet::BIND_OVERALL );
gset->setPrimType( GeoSet::QUADS );
gset->setNumPrims( 1 );
gset->setGeoState( gstate );
return gset;
}
static float ttx, tty;
static int ct( const void *a, const void *b )
{
_tree *ta = (_tree *)a;
_tree *tb = (_tree *)b;
float da = sqrtf( sqr(ta->x - ttx) + sqr(ta->y - tty) );
float db = sqrtf( sqr(tb->x - ttx) + sqr(tb->y - tty) );
if( da < db )
return -1;
else
return 1;
}
Node *makeTrees( void )
{
Group *group = new Group;
int i;
getDatabaseCenterRadius( dbcenter, &dbradius );
struct _tree *t;
Texture *tex = new Texture;
tex->setImage(Registry::instance()->readImage("tree0.rgba"));
GeoState *gstate = new GeoState;
gstate->setMode( GeoState::TRANSPARENCY, GeoState::ON );
gstate->setAttribute( GeoState::TRANSPARENCY, new Transparency );
gstate->setMode( GeoState::TEXTURE, GeoState::ON );
gstate->setAttribute( GeoState::TEXTURE, tex );
gstate->setAttribute( GeoState::TEXENV, new TexEnv );
gstate->setMode( GeoState::LIGHTING, GeoState::OFF );
int tt[] = { 15, 30, 45, 58, 72, 75, 93, 96, 105, -1 };
int *ttp = tt;
i = 0;
while( i < 105 )
{
ttx = trees[i].x;
tty = trees[i].y;
qsort( &trees[i], 105 - i, sizeof( _tree ), ct );
i += *ttp;
ttp++;
}
t = trees;
i = 0;
ttp = tt;
while( *ttp != -1 )
{
Billboard *bb = new Billboard;
//int starti = i;
for( ; i < (*ttp); i++ )
{
t->x -= 0.3f;
float h = Hat(t->x, t->y, t->z );
Vec3 pos( t->x, t->y, t->z-h );
GeoSet *gset = makeTree( t, gstate );
bb->addGeoSet( gset, pos );
t++;
}
group->addChild( bb );
ttp++;
}
return group;
}

109
src/osgPlugins/fly/sky.cpp Normal file
View File

@@ -0,0 +1,109 @@
#include <math.h>
#include <osg/OSG>
#include <osg/Geode>
#include <osg/GeoSet>
#include <osg/Texture>
#include <osg/GeoState>
#include <osg/Registry>
#ifdef WIN32
#pragma warning( disable : 4244 )
#pragma warning( disable : 4305 )
#endif
using namespace osg;
Node *makeSky( void )
{
int i, j;
float lev[] = { -5, -1.0, 1.0, 15.0, 30.0, 60.0, 90.0 };
float cc[][4] = {
{ 0.0, 0.0, 0.15 },
{ 0.0, 0.0, 0.15 },
{ 0.4, 0.4, 0.7 },
{ 0.2, 0.2, 0.6 },
{ 0.1, 0.1, 0.6 },
{ 0.1, 0.1, 0.6 },
{ 0.1, 0.1, 0.6 },
};
float x, y, z;
float alpha, theta;
float radius = 20.0f;
int nlev = sizeof( lev )/sizeof(float);
Vec3 *coords = new Vec3[19*nlev];
Vec4 *colors = new Vec4[19*nlev];
Vec2 *tcoords = new Vec2[19*nlev];
osg::ushort *idx = new osg::ushort[38* nlev];
int *lengths = new int[nlev];
int ci, ii;
ii = ci = 0;
for( i = 0; i < nlev; i++ )
{
for( j = 0; j <= 18; j++ )
{
alpha = lev[i] * M_PI/180.0;
theta = (float)(j*20) * M_PI/180.0;
x = radius * cosf( alpha ) * cosf( theta );
y = radius * cosf( alpha ) * -sinf( theta );
z = radius * sinf( alpha );
coords[ci][0] = x;
coords[ci][1] = y;
coords[ci][2] = z;
colors[ci][0] = cc[i][0];
colors[ci][1] = cc[i][1];
colors[ci][2] = cc[i][2];
colors[ci][3] = 1.0;
tcoords[ci][0] = (float)j/18.0;
tcoords[ci][0] = (float)i/(float)(nlev-1);
ci++;
idx[ii++] = ((i+1)*19+j);
idx[ii++] = ((i+0)*19+j);
}
lengths[i] = 38;
}
GeoSet *gset = new GeoSet;
gset->setCoords( coords, idx );
gset->setTextureCoords( tcoords, idx );
gset->setTextureBinding( GeoSet::BIND_PERVERTEX );
gset->setColors( colors, idx );
gset->setColorBinding( GeoSet::BIND_PERVERTEX );
gset->setPrimType( GeoSet::TRIANGLE_STRIP );
gset->setNumPrims( nlev - 1 );
gset->setPrimLengths( lengths );
Texture *tex = new Texture;
tex->setImage(Registry::instance()->readImage( "white.rgb"));
GeoState *gstate = new GeoState;
// gstate->setMode( GeoState::TEXTURE, GeoState::ON );
gstate->setMode( GeoState::TEXTURE, GeoState::OFF);
gstate->setAttribute( GeoState::TEXTURE, tex );
gstate->setAttribute( GeoState::TEXENV, new TexEnv );
gstate->setMode( GeoState::LIGHTING, GeoState::OFF );
gstate->setMode( GeoState::FACE_CULL, GeoState::ON );
gset->setGeoState( gstate );
Geode *geode = new Geode;
geode->addGeoSet( gset );
geode->setName( "Sky" );
return geode;
}

193
src/osgPlugins/fly/tank.cpp Normal file
View File

@@ -0,0 +1,193 @@
#include <math.h>
#include <osg/GL>
#include <osg/OSG>
#include <osg/Group>
#include <osg/Geode>
#include <osg/GeoSet>
#include <osg/Texture>
#include <osg/GeoState>
#include <osg/DCS>
#include <osg/Registry>
#ifdef WIN32
#pragma warning( disable : 4244 )
#pragma warning( disable : 4305 )
#endif
using namespace osg;
extern void getDatabaseCenterRadius( float dbcenter[3], float *dbradius );
static float radius = 2.0;
static float dbcenter[3], dbradius;
static void conv( const Vec3& a, const Matrix& mat, Vec3& b )
{
int i;
Vec3 t;
for( i = 0; i < 3; i++ )
{
t[i] = (a[0] * mat._mat[0][i]) +
(a[1] * mat._mat[1][i]) +
(a[2] * mat._mat[2][i]) +
mat._mat[3][i];
}
b[0] = t[0];
b[1] = t[1];
b[2] = t[2];
}
Node *makeTank( void )
{
Geode *geode1 = new Geode;
getDatabaseCenterRadius( dbcenter, &dbradius );
ref_ptr<Matrix> mat = new Matrix(
0.05, 0, 0, 0,
0, 0.05, 0, 0,
0, 0, 0.05, 0,
1.5999 - 0.3,
3.1474,
dbcenter[2] + 0.6542 - 0.09,
1
);
Vec3 *vc = new Vec3[42];
Vec2 *tc = new Vec2[42];
int *lens = new int[1];
int i, c;
c = 0;
for( i = 0; i <= 360; i += 18 )
{
float x, y, z;
float s, t;
float theta = (float)i * M_PI/180.0;
s = (float)i/90.0;
t = 1.0;
x = radius * cosf( theta );
y = radius * sinf( theta );
z = 1.0;
vc[c][0] = x;
vc[c][1] = y;
vc[c][2] = z;
tc[c][0] = s;
tc[c][1] = t;
c++;
t = 0.0;
z = 0.0;
vc[c][0] = x;
vc[c][1] = y;
vc[c][2] = z;
tc[c][0] = s;
tc[c][1] = t;
c++;
}
*lens = 42;
for( i = 0; i < c; i++ )
conv( vc[i], *mat, vc[i] );
GeoSet *gset = new GeoSet;
gset->setCoords( vc );
gset->setTextureCoords( tc );
gset->setTextureBinding( GeoSet::BIND_PERVERTEX );
gset->setPrimType( GeoSet::TRIANGLE_STRIP );
gset->setNumPrims( 1 );
gset->setPrimLengths( lens );
Texture *tex = new Texture;
tex->setWrap( Texture::WRAP_S, Texture::REPEAT );
tex->setWrap( Texture::WRAP_T, Texture::REPEAT );
tex->setImage(Registry::instance()->readImage( "tank.rgb"));
GeoState *gstate = new GeoState;
gstate->setMode( GeoState::TEXTURE, GeoState::ON );
gstate->setAttribute( GeoState::TEXTURE, tex );
gstate->setAttribute( GeoState::TEXENV, new TexEnv );
gset->setGeoState( gstate );
geode1->addGeoSet( gset );
lens = new int[1];
*lens = 22;
vc = new Vec3[22];
tc = new Vec2[22];
c = 0;
vc[c][0] = 0;
vc[c][1] = 0;
vc[c][2] = 1;
c++;
for( i = 0; i <= 360; i += 18 )
{
float x, y, z;
float s, t;
float theta = (float)i * M_PI/180.0;
// s = (float)i/360.0;
// t = 1.0;
s = cosf( theta );
t = sinf( theta );
x = radius * cosf( theta );
y = radius * sinf( theta );
z = 1.0;
vc[c][0] = x;
vc[c][1] = y;
vc[c][2] = z;
tc[c][0] = s;
tc[c][1] = t;
c++;
}
for( i = 0; i < c; i++ )
conv( vc[i], *mat, vc[i] );
gset = new GeoSet;
gset->setCoords( vc );
gset->setTextureCoords( tc );
gset->setPrimType(GeoSet::TRIANGLE_FAN);
gset->setNumPrims( 1 );
gset->setPrimLengths( lens );
gset->setGeoState( gstate );
Geode *geode2 = new Geode;
geode2->addGeoSet( gset );
//DCS *dcs = new DCS(mat);
//dcs->addChild( geode2 );
Group *grp = new Group;
grp->addChild( geode1 );
grp->addChild( geode2 );
geode1->setName( "Geode 1" );
geode2->setName( "Geode 2" );
return grp;
}

View File

@@ -0,0 +1,137 @@
// #include <math.h>
#include <osg/OSG>
#include <osg/Geode>
#include <osg/GeoSet>
#include <osg/Texture>
#include <osg/GeoState>
#include <osg/Registry>
#include "terrain_data.h"
using namespace osg;
void getDatabaseCenterRadius( float dbcenter[3], float *dbradius )
{
int i;
double n=0.0;
double center[3] = { 0.0f, 0.0f, 0.0f };
float cnt;
cnt = 39 * 38;
for( i = 0; i < cnt; i++ )
{
center[0] += (double)vertex[i][0];
center[1] += (double)vertex[i][1];
center[2] += (double)vertex[i][2];
n = n + 1.0;
}
center[0] /= n;
center[1] /= n;
center[2] /= n;
float r = 0.0;
// for( i = 0; i < sizeof( vertex ) / (sizeof( float[3] )); i++ )
for( i = 0; i < cnt; i++ )
{
double d = sqrt(
(((double)vertex[i][0] - center[0]) * ((double)vertex[i][0] - center[0])) +
(((double)vertex[i][1] - center[1]) * ((double)vertex[i][1] - center[1])) +
(((double)vertex[i][2] - center[2]) * ((double)vertex[i][2] - center[2])) );
if( d > (double)r ) r = (float)d;
}
*dbradius = r;
dbcenter[0] = (float)center[0];
dbcenter[1] = (float)center[1];
dbcenter[2] = (float)center[2];
int index = 19 * 39 + 19;
dbcenter[0] = vertex[index][0] - 0.15;
dbcenter[1] = vertex[index][1];
dbcenter[2] = vertex[index][2] + 0.35;
}
Node *makeTerrain( void )
{
int m, n;
int i, j, c;
float dbcenter[3];
float dbradius;
getDatabaseCenterRadius( dbcenter, &dbradius );
m = (sizeof( vertex ) /(sizeof( float[3])))/39;
n = 39;
Vec3 *v = new Vec3[m*n];
Vec2 *t = new Vec2[m*n];
Vec4 *col = new Vec4[1];
osg::ushort *cidx = new osg::ushort;
osg::ushort *idx = new osg::ushort[m*n*2];
int *lens = new int[m];
col[0][0] = col[0][1] = col[0][2] = col[0][3] = 1;
*cidx = 0;
for( i = 0; i < m * n; i++ )
{
v[i][0] = vertex[i][0] - dbcenter[0];
v[i][1] = vertex[i][1] - dbcenter[1];
v[i][2] = vertex[i][2];
t[i][0] = texcoord[i][0] + 0.025;
t[i][1] = texcoord[i][1];
}
c = 0;
for( i = 0; i < m-2; i++ )
{
for( j = 0; j < n; j++ )
{
idx[c++] = (i+0)*n+j;
idx[c++] = (i+1)*n+j;
}
lens[i] = 39*2;
}
GeoSet *gset = new GeoSet;
gset->setCoords( v, idx );
gset->setTextureCoords( t, idx );
gset->setTextureBinding( GeoSet::BIND_PERVERTEX );
gset->setColors( col, cidx );
gset->setColorBinding( GeoSet::BIND_OVERALL );
gset->setPrimType( GeoSet::TRIANGLE_STRIP );
gset->setNumPrims( m-2 );
gset->setPrimLengths( lens );
Texture *tex = new Texture;
tex->setImage(Registry::instance()->readImage("lz.rgb"));
GeoState *gstate = new GeoState;
gstate->setMode( GeoState::TEXTURE, GeoState::ON );
gstate->setMode( GeoState::LIGHTING, GeoState::OFF );
gstate->setAttribute( GeoState::TEXTURE, tex );
gstate->setAttribute( GeoState::TEXENV, new TexEnv );
gstate->check();
gset->setGeoState( gstate );
Geode *geode = new Geode;
geode->addGeoSet( gset );
gset->check();
return geode;
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,265 @@
#include <stdlib.h>
#include <osg/OSG>
#include <osg/Billboard>
#include <osg/Group>
#include <osg/Geode>
#include <osg/GeoSet>
#include <osg/Texture>
#include <osg/Registry>
#include "hat.h"
#ifdef WIN32
#pragma warning( disable : 4244 )
#pragma warning( disable : 4305 )
#endif
using namespace osg;
#define sqr(x) ((x)*(x))
extern void getDatabaseCenterRadius( float dbcenter[3], float *dbradius );
static float dbcenter[3], dbradius;
static struct _tree{
int n;
float x, y, z;
float w, h;
}trees[] = {
{ 0, -0.4769, -0.8972, -0.4011, 0.2000, 0.1200 },
{ 1, -0.2543, -0.9117, -0.3873, 0.2000, 0.1200 },
{ 2, -0.0424, -0.8538, -0.3728, 0.2000, 0.1200 },
{ 3, 0.1590, -0.8827, -0.3594, 0.2000, 0.1200 },
{ 4, -0.4981, -1.0853, -0.4016, 0.3500, 0.1200 },
{ 5, -0.5405, -1.2590, -0.4050, 0.2000, 0.1200 },
{ 6, -0.5723, -1.5339, -0.4152, 0.2000, 0.1200 },
{ 7, -0.6252, -1.8667, -0.4280, 0.2000, 0.1200 },
{ 8, -0.5617, -2.1851, -0.4309, 0.2000, 0.1200 },
{ 9, -0.5087, -2.4166, -0.4215, 0.2000, 0.1200 },
{ 10, -0.4345, -2.3443, -0.4214, 0.2000, 0.1200 },
{ 11, -3.0308, -1.5484, -0.4876, 0.2000, 0.1200 },
{ 12, -3.0202, -1.6497, -0.4963, 0.2000, 0.1200 },
{ 13, -2.9355, -1.8378, -0.4969, 0.2000, 0.1200 },
{ 14, -0.6040, -2.0259, -0.4300, 0.2000, 0.1200 },
{ 15, -0.5442, -1.3442, -0.4080, 0.1000, 0.1200 },
{ 16, -0.5639, -1.6885, -0.4201, 0.1000, 0.1200 },
{ 17, 0.9246, 3.4835, 0.5898, 0.2500, 0.1000 },
{ 18, 0.0787, 3.8687, 0.3329, 0.2500, 0.1200 },
{ 19, 0.2885, 3.7130, 0.4047, 0.2500, 0.1200 },
{ 20, 0.2033, 3.6228, 0.3704, 0.2500, 0.1200 },
{ 21, -0.2098, 3.9015, 0.2327, 0.2500, 0.1200 },
{ 22, -0.3738, 3.7376, 0.1722, 0.2500, 0.1200 },
{ 23, -0.2557, 3.6064, 0.1989, 0.2500, 0.1200 },
{ 24, 0.0590, 3.7294, 0.3210, 0.2500, 0.1200 },
{ 25, -0.4721, 3.8851, 0.1525, 0.2500, 0.1200 },
{ 26, 0.9639, 3.2048, 0.5868, 0.1200, 0.0800 },
{ 27, 0.7082, -1.0409, -0.3221, 0.1000, 0.1000 },
{ 28, -0.2426, -2.3442, -0.4150, 0.1000, 0.1380 },
{ 29, -0.1770, -2.4179, -0.4095, 0.1000, 0.1580 },
{ 30, -0.0852, -2.5327, -0.4056, 0.1000, 0.1130 },
{ 31, -0.0131, -2.6065, -0.4031, 0.1000, 0.1150 },
{ 32, 0.0787, -2.6638, -0.4012, 0.1000, 0.1510 },
{ 33, 0.1049, -2.7622, -0.3964, 0.1000, 0.1270 },
{ 34, 0.1770, -2.8687, -0.3953, 0.1000, 0.1100 },
{ 35, 0.3213, -2.9507, -0.3974, 0.1000, 0.1190 },
{ 36, 0.4065, -3.0163, -0.4014, 0.1000, 0.1120 },
{ 37, 0.3738, -3.1802, -0.4025, 0.1000, 0.1860 },
{ 38, 0.5508, -3.2048, -0.3966, 0.1000, 0.1490 },
{ 39, 0.5836, -3.3031, -0.3900, 0.1000, 0.1670 },
{ 40, -0.3082, -2.7212, -0.3933, 0.1000, 0.1840 },
{ 41, -0.1967, -2.6474, -0.4017, 0.1000, 0.1600 },
{ 42, -0.1180, -2.7458, -0.3980, 0.1000, 0.1250 },
{ 43, -0.3344, -2.8359, -0.3964, 0.1000, 0.1430 },
{ 44, -0.2492, -2.8933, -0.3838, 0.1000, 0.1890 },
{ 45, -0.1246, -3.0491, -0.3768, 0.1000, 0.1830 },
{ 46, 0.0000, -3.0818, -0.3696, 0.1000, 0.1370 },
{ 47, -0.2295, -3.0409, -0.3706, 0.1000, 0.1660 },
{ 48, -1.3245, 2.6638, 0.0733, 0.0500, 0.0500 },
{ 49, 2.2425, -1.5491, -0.2821, 0.2300, 0.1200 },
{ 50, 0.2164, -2.1311, -0.4000, 0.1000, 0.0690 },
{ 51, 0.2885, -2.2130, -0.4000, 0.1000, 0.0790 },
{ 52, 0.3606, -2.2786, -0.4000, 0.1000, 0.0565 },
{ 53, 0.4328, -2.3442, -0.4000, 0.1000, 0.0575 },
{ 54, 0.5246, -2.4343, -0.4086, 0.1000, 0.0755 },
{ 55, 0.6360, -2.5245, -0.4079, 0.1000, 0.0635 },
{ 56, 0.7541, -2.4261, -0.4007, 0.1000, 0.0550 },
{ 57, 0.7934, -2.2786, -0.3944, 0.1000, 0.0595 },
{ 58, 1.0295, -2.2868, -0.3837, 0.1000, 0.0560 },
{ 59, 0.8459, -2.6474, -0.4051, 0.1000, 0.0930 },
{ 60, 1.0426, -2.6884, -0.4001, 0.1000, 0.0745 },
{ 61, 1.1475, -2.7458, -0.3883, 0.1000, 0.0835 },
{ 62, -0.1967, -1.4180, -0.3988, 0.1000, 0.0920 },
{ 63, -0.0131, -1.2704, -0.3856, 0.1000, 0.0690 },
{ 64, 0.2098, -1.2049, -0.3664, 0.1000, 0.0790 },
{ 65, 0.3410, -1.3196, -0.3652, 0.1000, 0.0565 },
{ 66, 0.5705, -1.2704, -0.3467, 0.1000, 0.0575 },
{ 67, 0.6360, -1.4344, -0.3532, 0.1000, 0.0755 },
{ 68, 0.9246, -1.4180, -0.3329, 0.1000, 0.0635 },
{ 69, 1.0623, -1.3360, -0.3183, 0.1000, 0.0550 },
{ 70, 1.2393, -1.3934, -0.3103, 0.1000, 0.0595 },
{ 71, 1.3639, -1.4753, -0.3079, 0.1000, 0.0560 },
{ 72, 1.4819, -1.5983, -0.3210, 0.1000, 0.0930 },
{ 73, 1.7835, -1.5819, -0.3065, 0.1000, 0.0745 },
{ 74, 1.9343, -2.1065, -0.3307, 0.1000, 0.0835 },
{ 75, 2.1245, -2.3196, -0.3314, 0.1000, 0.0920 },
{ 76, 2.2556, -2.3032, -0.3230, 0.1000, 0.0800 },
{ 77, 2.4196, -2.3688, -0.3165, 0.1000, 0.0625 },
{ 78, 1.7835, -2.5327, -0.3543, 0.1000, 0.0715 },
{ 79, 1.7180, -2.8933, -0.3742, 0.1000, 0.0945 },
{ 80, 1.9343, -3.0409, -0.3727, 0.1000, 0.0915 },
{ 81, 2.4524, -3.4671, -0.3900, 0.1000, 0.0685 },
{ 82, 2.4786, -2.8851, -0.3538, 0.1000, 0.0830 },
{ 83, 2.3343, -2.6228, -0.3420, 0.1000, 0.0830 },
{ 84, 2.8130, -2.0737, -0.2706, 0.1000, 0.0890 },
{ 85, 2.6360, -1.8278, -0.2661, 0.1000, 0.0975 },
{ 86, 2.3958, -1.7130, -0.2774, 0.2000, 0.1555 },
{ 87, 2.2688, -1.2868, -0.2646, 0.1000, 0.0835 },
{ 88, 2.4196, -1.1147, -0.2486, 0.1000, 0.0770 },
{ 89, 2.7802, -2.3933, -0.3017, 0.1000, 0.0655 },
{ 90, 3.0163, -2.4179, -0.2905, 0.1000, 0.0725 },
{ 91, 2.9310, -2.2540, -0.2798, 0.1000, 0.0910 },
{ 92, 2.6622, -2.0983, -0.2823, 0.1000, 0.0680 },
{ 93, 2.3147, -1.9753, -0.2973, 0.1000, 0.0620 },
{ 94, 2.1573, -1.8770, -0.3013, 0.1000, 0.0525 },
{ 95, 2.0196, -1.7868, -0.3044, 0.1000, 0.0970 },
{ 96, 2.7802, -3.3031, -0.3900, 0.1000, 0.0510 },
{ 97, 2.8589, -3.1720, -0.3900, 0.1000, 0.0755 },
{ 98, 3.0163, -2.8114, -0.3383, 0.1000, 0.0835 },
{ 99, 3.5081, -2.4179, -0.2558, 0.1000, 0.0770 },
{ 100, 3.5277, -2.3196, -0.2366, 0.1000, 0.0765 },
{ 101, 3.6654, -2.5819, -0.2566, 0.1000, 0.0805 },
{ 102, 3.7179, -2.7622, -0.2706, 0.1000, 0.0980 },
{ 103, 3.7769, -2.4671, -0.2339, 0.1000, 0.0640 },
{ 104, 3.3441, -2.4671, -0.2693, 0.1000, 0.0940 },
{ -1, 0, 0, 0, 0, 0 },
};
static GeoSet *makeTree( _tree *tree, GeoState *gstate )
{
float vv[][3] = {
{ -tree->w/2.0, 0.0, 0.0 },
{ tree->w/2.0, 0.0, 0.0 },
{ tree->w/2.0, 0.0, 2 * tree->h },
{ -tree->w/2.0, 0.0, 2 * tree->h },
};
Vec3 *v = new Vec3[4];
Vec2 *t = new Vec2[4];
Vec4 *l = new Vec4[1];
int i;
l[0][0] = l[0][1] = l[0][2] = l[0][3] = 1;
for( i = 0; i < 4; i++ )
{
v[i][0] = vv[i][0];
v[i][1] = vv[i][1];
v[i][2] = vv[i][2];
}
t[0][0] = 0.0; t[0][1] = 0.0;
t[1][0] = 1.0; t[1][1] = 0.0;
t[2][0] = 1.0; t[2][1] = 1.0;
t[3][0] = 0.0; t[3][1] = 1.0;
GeoSet *gset = new GeoSet;
gset->setCoords( v );
gset->setTextureCoords( t );
gset->setTextureBinding( GeoSet::BIND_PERVERTEX );
gset->setColors( l );
gset->setColorBinding( GeoSet::BIND_OVERALL );
gset->setPrimType( GeoSet::QUADS );
gset->setNumPrims( 1 );
gset->setGeoState( gstate );
return gset;
}
static float ttx, tty;
static int ct( const void *a, const void *b )
{
_tree *ta = (_tree *)a;
_tree *tb = (_tree *)b;
float da = sqrtf( sqr(ta->x - ttx) + sqr(ta->y - tty) );
float db = sqrtf( sqr(tb->x - ttx) + sqr(tb->y - tty) );
if( da < db )
return -1;
else
return 1;
}
Node *makeTrees( void )
{
Group *group = new Group;
int i;
getDatabaseCenterRadius( dbcenter, &dbradius );
struct _tree *t;
Texture *tex = new Texture;
tex->setImage(Registry::instance()->readImage("tree0.rgba"));
GeoState *gstate = new GeoState;
gstate->setMode( GeoState::TEXTURE, GeoState::ON );
gstate->setAttribute( GeoState::TEXTURE, tex );
gstate->setAttribute( GeoState::TEXENV, new TexEnv );
AlphaFunc* alphaFunc = new AlphaFunc;
alphaFunc->setFunction(AlphaFunc::GEQUAL,0.1f);
gstate->setMode( GeoState::ALPHAFUNC, GeoState::ON );
gstate->setAttribute( GeoState::ALPHAFUNC, alphaFunc );
gstate->setMode( GeoState::LIGHTING, GeoState::OFF );
int tt[] = { 15, 30, 45, 58, 72, 75, 93, 96, 105, -1 };
int *ttp = tt;
i = 0;
while( i < 105 )
{
ttx = trees[i].x;
tty = trees[i].y;
qsort( &trees[i], 105 - i, sizeof( _tree ), ct );
i += *ttp;
ttp++;
}
t = trees;
i = 0;
ttp = tt;
while( *ttp != -1 )
{
Billboard *bb = new Billboard;
//int starti = i;
for( ; i < (*ttp); i++ )
{
t->x -= 0.3f;
float h = Hat(t->x, t->y, t->z );
Vec3 pos( t->x, t->y, t->z-h );
GeoSet *gset = makeTree( t, gstate );
bb->addGeoSet( gset, pos );
t++;
}
group->addChild( bb );
ttp++;
}
return group;
}

View File

@@ -0,0 +1,138 @@
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <string.h>
#include "vector.h"
#ifdef WIN32
#pragma warning( disable : 4244 )
#pragma warning( disable : 4305 )
#endif
#define SET_VEC( v, a, b, c ) v->x = (a); v->y = (b); v->z = (c)
Vector NewVector( void )
{
Vector temp;
temp = (Vector)calloc( 1, sizeof( struct _vector ) );
SET_VEC( temp, 0., 0., 0. );
return temp;
}
void DeleteVector( Vector v )
{
SET_VEC( v, 0., 0., 0. );
free( v );
}
void VectorSet( Vector v, float a, float b, float c )
{
SET_VEC( v, a, b, c );
}
void VectorGet( Vector v, float *a, float *b, float *c )
{
*a = v->x;
*b = v->y;
*c = v->z;
}
float VectorDotProduct( Vector p, Vector q )
{
return (p->x * p->x) + (p->y * p->y) + (p->z * p->z);
}
void VectorNormalize( Vector v )
{
float f;
f = sqrt( (v->x*v->x)+(v->y*v->y)+(v->z*v->z));
if( f == 0.0 )
v->x = v->y = v->z = 0.0;
else
{
v->x /= f;
v->y /= f;
v->z /= f;
}
}
void VectorCrossProduct(Vector v1, Vector v2, Vector prod)
{
struct _vector p; /* in case prod == v1 or v2 */
p.x = v1->y*v2->z - v2->y*v1->z;
p.y = v1->z*v2->x - v2->z*v1->x;
p.z = v1->x*v2->y - v2->x*v1->y;
prod->x = p.x; prod->y = p.y; prod->z = p.z;
}
void VectorAdd( Vector v1, Vector v2, Vector sum )
{
sum->x = v1->x + v2->x;
sum->y = v1->y + v2->y;
sum->z = v1->z + v2->z;
}
void VectorDiff( Vector v1, Vector v2, Vector diff )
{
diff->x = v1->x - v2->x;
diff->y = v1->y - v2->y;
diff->z = v1->z - v2->z;
}
float VectorAngle( Vector v1, Vector v2 )
{
float d;
float f1, f2;
d = ((v1->x*v2->x) + (v1->y*v2->y) + (v1->z*v2->z));
f1 = sqrt( (v1->x*v1->x) + (v1->y *v1->y) + (v1->z*v1->z) );
f2 = sqrt( (v2->x*v2->x) + (v2->y *v2->y) + (v2->z*v2->z) );
if( f1*f2 == 0.0 ) return 0.0;
return acos( d/(f1*f2) );
}
char * VectorToA( Vector v, char *ptr, int size )
{
char buff[512];
sprintf( buff, "%12.4f %12.4f %12.4f", v->x, v->y, v->z );
strncpy( ptr, buff, size );
return ptr;
}
float VectorMagnitude( Vector v )
{
return sqrt( (v->x*v->x) + (v->y *v->y) + (v->z*v->z) );
}
void VectorMagnify( Vector v, float magnitude, Vector res )
{
float x;
float d;
x = magnitude;
d = sqrt( (v->x*v->x) + (v->y*v->y) + (v->z*v->z) );
if( d == 0.0 )
{
res->x = res->y = res->z = 0.0;
}
else
{
res->x = x * v->x/d;
res->y = x * v->y/d;
res->z = x * v->z/d;
}
}

View File

@@ -0,0 +1,27 @@
#ifndef __VECTOR_H
#define __VECTOR_H
struct _vector {
float x, y, z;
};
typedef struct _vector *Vector;
typedef struct _vector sgvector;
extern Vector NewVector( void );
extern void DeleteVector( Vector v );
extern void VectorSet( Vector v, float a, float b, float c );
extern void VectorGet( Vector v, float *a, float *b, float *c );
extern float VectorDotProduct( Vector p, Vector q );
extern void VectorCrossProduct(Vector v1, Vector v2, Vector prod);
extern void VectorAdd( Vector v1, Vector v2, Vector diff );
extern void VectorDiff( Vector v1, Vector v2, Vector diff );
extern void VectorNormalize( Vector v );
extern float VectorAngle( Vector v1, Vector v2 );
extern char * VectorToA( Vector v, char *cptr, int size );
extern float VectorMagnitude( Vector v );
extern void VectorMagnify( Vector v, float magnitude, Vector res );
#endif

View File

View File

@@ -0,0 +1,19 @@
#!smake
include ../../../Make/makedefs
C++FILES = \
ReaderWriterGIF.cpp\
LIB = ../../../lib/osgPlugins/osgdb_gif.so
TARGET_LOADER_FILES = osgPlugins/osgdb_gif.so
LIBS = -lungif
C++FLAGS += -I. -I../../../include
LDFLAGS += -L../../../lib
include ../../../Make/makerules

View File

@@ -0,0 +1,348 @@
#include <osg/Image>
#include <osg/Image>
#include <osg/Input>
#include <osg/Output>
#include <osg/Notify>
#include <osg/Registry>
#include <osg/Geode>
#include <osg/GL>
/****************************************************************************
*
* Follows is code extracted from the simage library. Original Authors:
*
* Systems in Motion,
* <URL:http://www.sim.no>
*
* Peder Blekken <pederb@sim.no>
* Morten Eriksen <mortene@sim.no>
* Marius Bugge Monsen <mariusbu@sim.no>
*
* The original COPYING notice
*
* All files in this library are public domain, except simage_rgb.cpp which is
* Copyright (c) Mark J Kilgard <mjk@nvidia.com>. I will contact Mark
* very soon to hear if this source also can become public domain.
*
* Please send patches for bugs and new features to: <pederb@sim.no>.
*
* Peder Blekken
*
*
* Ported into the OSG as a plugin, Robert Osfield Decemeber 2000.
* Note, reference above to license of simage_rgb is not relevent to the OSG
* as the OSG does not use it. Also for patches, bugs and new features
* please send them direct to the OSG dev team rather than address above.
*
**********************************************************************/
/*!
GIF loader, using libungif
Based, in part, on source code found in libungif, gif2rgb.c
*/
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
extern "C" {
#include <gif_lib.h>
};
#define ERR_NO_ERROR 0
#define ERR_OPEN 1
#define ERR_READ 2
#define ERR_MEM 3
#define MY_GIF_DEBUG 1
static int giferror = ERR_NO_ERROR;
int
simage_gif_error(char * buffer, int buflen)
{
switch (giferror) {
case ERR_OPEN:
strncpy(buffer, "GIF loader: Error opening file", buflen);
break;
case ERR_READ:
strncpy(buffer, "GIF loader: Error reading file", buflen);
break;
case ERR_MEM:
strncpy(buffer, "GIF loader: Out of memory error", buflen);
break;
}
return giferror;
}
int
simage_gif_identify(const char *filename,
const unsigned char *header,
int headerlen)
{
static unsigned char gifcmp[] = {'G', 'I', 'F'};
if (headerlen < 3) return 0;
if (memcmp((const void*)header,
(const void*)gifcmp, 3) == 0) return 1;
return 0;
}
static void
decode_row(GifFileType * giffile,
unsigned char * buffer,
unsigned char * rowdata,
int x, int y, int len,
int transparent)
{
GifColorType * cmentry;
ColorMapObject * colormap;
int colormapsize;
unsigned char col;
unsigned char * ptr;
y = giffile->SHeight - (y+1);
ptr = buffer + (giffile->SWidth * y + x) * 4;
colormap = (giffile->Image.ColorMap
? giffile->Image.ColorMap
: giffile->SColorMap);
colormapsize = colormap ? colormap->ColorCount : 255;
while (len--) {
col = *rowdata++;
if (col >= colormapsize) col = 0; /* just in case */
cmentry = colormap ? &colormap->Colors[col] : NULL;
if (cmentry) {
*ptr++ = cmentry->Red;
*ptr++ = cmentry->Green;
*ptr++ = cmentry->Blue;
}
else {
*ptr++ = col;
*ptr++ = col;
*ptr++ = col;
}
*ptr++ = (col == transparent ? 0x00 : 0xff);
}
}
unsigned char *
simage_gif_load(const char *filename,
int *width_ret,
int *height_ret,
int *numComponents_ret)
{
int i, j, n, row, col, width, height, extcode;
unsigned char * rowdata;
unsigned char * buffer, * ptr;
unsigned char bg;
int transparent;
GifRecordType recordtype;
GifByteType * extension;
GifFileType * giffile;
GifColorType * bgcol;
/* The way an interlaced image should be read - offsets and jumps */
int interlacedoffset[] = { 0, 4, 2, 1 };
int interlacedjumps[] = { 8, 8, 4, 2 };
giffile = DGifOpenFileName(filename);
if (!giffile) {
giferror = ERR_OPEN;
return NULL;
}
transparent = -1; /* no transparent color by default */
n = giffile->SHeight * giffile->SWidth;
buffer = (unsigned char *)malloc(n * 4);
if (!buffer) {
giferror = ERR_MEM;
return NULL;
}
rowdata = (unsigned char *)malloc(giffile->SWidth);
if (!rowdata) {
giferror = ERR_MEM;
free(buffer);
return NULL;
}
bg = giffile->SBackGroundColor;
if (giffile->SColorMap && bg < giffile->SColorMap->ColorCount) {
bgcol = &giffile->SColorMap->Colors[bg];
}
else bgcol = NULL;
ptr = buffer;
for (i = 0; i < n; i++) {
if (bgcol) {
*ptr++ = bgcol->Red;
*ptr++ = bgcol->Green;
*ptr++ = bgcol->Blue;
*ptr++ = 0xff;
}
else {
*ptr++ = 0x00;
*ptr++ = 0x00;
*ptr++ = 0x00;
*ptr++ = 0xff;
}
}
/* Scan the content of the GIF file and load the image(s) in: */
do {
if (DGifGetRecordType(giffile, &recordtype) == GIF_ERROR) {
giferror = ERR_READ;
free(buffer);
free(rowdata);
return NULL;
}
switch (recordtype) {
case IMAGE_DESC_RECORD_TYPE:
if (DGifGetImageDesc(giffile) == GIF_ERROR) {
giferror = ERR_READ;
free(buffer);
free(rowdata);
return NULL;
}
row = giffile->Image.Top; /* subimage position in composite image */
col = giffile->Image.Left;
width = giffile->Image.Width;
height = giffile->Image.Height;
if (giffile->Image.Left + giffile->Image.Width > giffile->SWidth ||
giffile->Image.Top + giffile->Image.Height > giffile->SHeight) {
/* image is not confined to screen dimension */
giferror = ERR_READ;
free(buffer);
free(rowdata);
return NULL;
}
if (giffile->Image.Interlace) {
fprintf(stderr,"interlace\n");
/* Need to perform 4 passes on the images: */
for (i = 0; i < 4; i++) {
for (j = row + interlacedoffset[i]; j < row + height;
j += interlacedjumps[i]) {
if (DGifGetLine(giffile, rowdata, width) == GIF_ERROR) {
giferror = ERR_READ;
free(buffer);
free(rowdata);
return NULL;
}
else decode_row(giffile, buffer, rowdata, col, j, width, transparent);
}
}
}
else {
for (i = 0; i < height; i++, row++) {
if (DGifGetLine(giffile, rowdata, width) == GIF_ERROR) {
giferror = ERR_READ;
free(buffer);
free(rowdata);
return NULL;
}
else decode_row(giffile, buffer, rowdata, col, row, width, transparent);
}
}
break;
case EXTENSION_RECORD_TYPE:
/* Skip any extension blocks in file: */
if (DGifGetExtension(giffile, &extcode, &extension) == GIF_ERROR) {
giferror = ERR_READ;
free(buffer);
free(rowdata);
return NULL;
}
/* transparent test from the gimp gif-plugin. Open Source rulez! */
else if (extcode == 0xf9) {
if (extension[0] >= 4 && extension[1] & 0x1) transparent = extension[4];
else transparent = -1;
}
while (extension != NULL) {
if (DGifGetExtensionNext(giffile, &extension) == GIF_ERROR) {
giferror = ERR_READ;
free(buffer);
free(rowdata);
return NULL;
}
}
break;
case TERMINATE_RECORD_TYPE:
break;
default: /* Should be trapped by DGifGetRecordType. */
break;
}
}
while (recordtype != TERMINATE_RECORD_TYPE);
free(rowdata);
*width_ret = giffile->SWidth;
*height_ret = giffile->SHeight;
*numComponents_ret = 4;
DGifCloseFile(giffile);
return buffer;
}
class ReaderWriterGIF : public osg::ReaderWriter
{
public:
virtual const char* className() { return "GIF Image Reader"; }
virtual bool acceptsExtension(const std::string& extension) { return extension=="gif"; }
virtual osg::Node* readNode(const std::string& fileName)
{
osg::Image* image = readImage(fileName);
if (image)
{
osg::Geode* geode = osg::createGeodeForImage(image);
if (geode==NULL) image->unref();
return geode;
}
else
{
return NULL;
}
}
virtual osg::Image* readImage(const std::string& fileName)
{
unsigned char *imageData = NULL;
int width_ret;
int height_ret;
int numComponents_ret;
imageData = simage_gif_load(fileName.c_str(),&width_ret,&height_ret,&numComponents_ret);
if (imageData==NULL) return NULL;
int s = width_ret;
int t = height_ret;
int r = 1;
int internalFormat = numComponents_ret;
unsigned int pixelFormat =
numComponents_ret == 1 ? GL_LUMINANCE :
numComponents_ret == 2 ? GL_LUMINANCE_ALPHA :
numComponents_ret == 3 ? GL_RGB :
numComponents_ret == 4 ? GL_RGBA : (GLenum)-1;
unsigned int dataType = GL_UNSIGNED_BYTE;
osg::Image* pOsgImage = new osg::Image;
pOsgImage->setFileName(fileName.c_str());
pOsgImage->setImage(s,t,r,
internalFormat,
pixelFormat,
dataType,
imageData);
return pOsgImage;
}
};
// now register with Registry to instantiate the above
// reader/writer.
osg::RegisterReaderWriterProxy<ReaderWriterGIF> g_readerWriter_GIF_Proxy;

View File

View File

@@ -0,0 +1,18 @@
#!smake
include ../../../Make/makedefs
C++FILES = \
ReaderWriterJPEG.cpp\
LIB = ../../../lib/osgPlugins/osgdb_jpg.so
TARGET_LOADER_FILES = osgPlugins/osgdb_jpg.so
LIBS = -ljpeg
C++FLAGS += -I. -I../../../include
LDFLAGS += -L../../../lib
include ../../../Make/makerules

View File

@@ -0,0 +1,354 @@
#include <osg/Image>
#include <osg/Image>
#include <osg/Input>
#include <osg/Output>
#include <osg/Notify>
#include <osg/Registry>
#include <osg/Geode>
#include <osg/GL>
/****************************************************************************
*
* Follows is code extracted from the simage library. Original Authors:
*
* Systems in Motion,
* <URL:http://www.sim.no>
*
* Peder Blekken <pederb@sim.no>
* Morten Eriksen <mortene@sim.no>
* Marius Bugge Monsen <mariusbu@sim.no>
*
* The original COPYING notice
*
* All files in this library are public domain, except simage_rgb.cpp which is
* Copyright (c) Mark J Kilgard <mjk@nvidia.com>. I will contact Mark
* very soon to hear if this source also can become public domain.
*
* Please send patches for bugs and new features to: <pederb@sim.no>.
*
* Peder Blekken
*
*
* Ported into the OSG as a plugin, Robert Osfield Decemeber 2000.
* Note, reference above to license of simage_rgb is not relevent to the OSG
* as the OSG does not use it. Also for patches, bugs and new features
* please send them direct to the OSG dev team rather than address above.
*
**********************************************************************/
/*
* Based on example code found in the libjpeg archive
*
*/
#include <stdio.h>
extern "C" {
#include <jpeglib.h>
};
#include <setjmp.h>
#include <string.h>
#include <assert.h>
#include <stdlib.h>
#define ERR_NO_ERROR 0
#define ERR_OPEN 1
#define ERR_MEM 2
#define ERR_JPEGLIB 3
static int jpegerror = ERR_NO_ERROR;
int
simage_jpeg_error(char * buffer, int buflen)
{
switch (jpegerror) {
case ERR_OPEN:
strncpy(buffer, "JPEG loader: Error opening file", buflen);
break;
case ERR_MEM:
strncpy(buffer, "JPEG loader: Out of memory error", buflen);
break;
case ERR_JPEGLIB:
strncpy(buffer, "JPEG loader: Illegal jpeg file", buflen);
break;
}
return jpegerror;
}
struct my_error_mgr {
struct jpeg_error_mgr pub; /* "public" fields */
jmp_buf setjmp_buffer; /* for return to caller */
};
typedef struct my_error_mgr * my_error_ptr;
static void
my_error_exit (j_common_ptr cinfo)
{
/* cinfo->err really points to a my_error_mgr struct, so coerce pointer */
my_error_ptr myerr = (my_error_ptr) cinfo->err;
/* Always display the message. */
/* We could postpone this until after returning, if we chose. */
/*(*cinfo->err->output_message) (cinfo);*/
/* FIXME: get error messahe from jpeglib */
/* Return control to the setjmp point */
longjmp(myerr->setjmp_buffer, 1);
}
int
simage_jpeg_identify(const char * ptr,
const unsigned char *header,
int headerlen)
{
static unsigned char jpgcmp[] = {'J', 'F', 'I', 'F' };
if (headerlen < 4) return 0;
if (memcmp((const void*)&header[6],
(const void*)jpgcmp, 4) == 0) return 1;
return 0;
}
static unsigned char*
copyScanline(unsigned char *currPtr, unsigned char *from, int cnt)
{
memcpy((void*)currPtr, (void*)from, cnt);
currPtr -= cnt;
return currPtr;
}
unsigned char *
simage_jpeg_load(const char *filename,
int *width_ret,
int *height_ret,
int *numComponents_ret)
{
int width;
int height;
unsigned char *currPtr;
int format;
unsigned char *buffer;
/* This struct contains the JPEG decompression parameters and pointers to
* working space (which is allocated as needed by the JPEG library).
*/
struct jpeg_decompress_struct cinfo;
/* We use our private extension JPEG error handler.
* Note that this struct must live as long as the main JPEG parameter
* struct, to avoid dangling-pointer problems.
*/
struct my_error_mgr jerr;
/* More stuff */
FILE * infile; /* source file */
JSAMPARRAY rowbuffer; /* Output row buffer */
int row_stride; /* physical row width in output buffer */
jpegerror = ERR_NO_ERROR;
/* In this example we want to open the input file before doing anything else,
* so that the setjmp() error recovery below can assume the file is open.
* VERY IMPORTANT: use "b" option to fopen() if you are on a machine that
* requires it in order to read binary files.
*/
if ((infile = fopen(filename, "rb")) == NULL) {
jpegerror = ERR_OPEN;
return NULL;
}
/* Step 1: allocate and initialize JPEG decompression object */
buffer = NULL;
/* We set up the normal JPEG error routines, then override error_exit. */
cinfo.err = jpeg_std_error(&jerr.pub);
jerr.pub.error_exit = my_error_exit;
/* Establish the setjmp return context for my_error_exit to use. */
if (setjmp(jerr.setjmp_buffer)) {
/* If we get here, the JPEG code has signaled an error.
* We need to clean up the JPEG object, close the input file, and return.
*/
jpegerror = ERR_JPEGLIB;
jpeg_destroy_decompress(&cinfo);
fclose(infile);
if (buffer) free(buffer);
return NULL;
}
/* Now we can initialize the JPEG decompression object. */
jpeg_create_decompress(&cinfo);
/* Step 2: specify data source (eg, a file) */
jpeg_stdio_src(&cinfo, infile);
/* Step 3: read file parameters with jpeg_read_header() */
(void) jpeg_read_header(&cinfo, TRUE);
/* We can ignore the return value from jpeg_read_header since
* (a) suspension is not possible with the stdio data source, and
* (b) we passed TRUE to reject a tables-only JPEG file as an error.
* See libjpeg.doc for more info.
*/
/* Step 4: set parameters for decompression */
/* In this example, we don't need to change any of the defaults set by
* jpeg_read_header(), so we do nothing here.
*/
/* Step 5: Start decompressor */
if (cinfo.jpeg_color_space == JCS_GRAYSCALE) {
format = 1;
cinfo.out_color_space = JCS_GRAYSCALE;
}
else { /* use rgb */
format = 3;
cinfo.out_color_space = JCS_RGB;
}
(void) jpeg_start_decompress(&cinfo);
/* We can ignore the return value since suspension is not possible
* with the stdio data source.
*/
/* We may need to do some setup of our own at this point before reading
* the data. After jpeg_start_decompress() we have the correct scaled
* output image dimensions available, as well as the output colormap
* if we asked for color quantization.
* In this example, we need to make an output work buffer of the right size.
*/
/* JSAMPLEs per row in output buffer */
row_stride = cinfo.output_width * cinfo.output_components;
/* Make a one-row-high sample array that will go away when done with image */
rowbuffer = (*cinfo.mem->alloc_sarray)
((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1);
width = cinfo.output_width;
height = cinfo.output_height;
buffer = currPtr = (unsigned char*)
malloc(width*height*cinfo.output_components);
/* Step 6: while (scan lines remain to be read) */
/* jpeg_read_scanlines(...); */
/* Here we use the library's state variable cinfo.output_scanline as the
* loop counter, so that we don't have to keep track ourselves.
*/
/* flip image upside down */
if (buffer) {
currPtr = buffer + row_stride * (cinfo.output_height-1);
while (cinfo.output_scanline < cinfo.output_height) {
/* jpeg_read_scanlines expects an array of pointers to scanlines.
* Here the array is only one element long, but you could ask for
* more than one scanline at a time if that's more convenient.
*/
(void) jpeg_read_scanlines(&cinfo, rowbuffer, 1);
/* Assume put_scanline_someplace wants a pointer and sample count. */
currPtr = copyScanline(currPtr, rowbuffer[0], row_stride);
}
}
/* Step 7: Finish decompression */
(void) jpeg_finish_decompress(&cinfo);
/* We can ignore the return value since suspension is not possible
* with the stdio data source.
*/
/* Step 8: Release JPEG decompression object */
/* This is an important step since it will release a good deal of memory. */
jpeg_destroy_decompress(&cinfo);
/* After finish_decompress, we can close the input file.
* Here we postpone it until after no more JPEG errors are possible,
* so as to simplify the setjmp error logic above. (Actually, I don't
* think that jpeg_destroy can do an error exit, but why assume anything...)
*/
fclose(infile);
/* At this point you may want to check to see whether any corrupt-data
* warnings occurred (test whether jerr.pub.num_warnings is nonzero).
*/
/* And we're done! */
if (buffer) {
*width_ret = width;
*height_ret = height;
*numComponents_ret = format;
}
else {
jpegerror = ERR_MEM;
}
return buffer;
}
class ReaderWriterJPEG : public osg::ReaderWriter
{
public:
virtual const char* className() { return "JPEG Image Reader"; }
virtual bool acceptsExtension(const std::string& extension) { return extension=="jpeg"; }
virtual osg::Node* readNode(const std::string& fileName)
{
osg::Image* image = readImage(fileName);
if (image)
{
osg::Geode* geode = osg::createGeodeForImage(image);
if (geode==NULL) image->unref();
return geode;
}
else
{
return NULL;
}
}
virtual osg::Image* readImage(const std::string& fileName)
{
unsigned char *imageData = NULL;
int width_ret;
int height_ret;
int numComponents_ret;
imageData = simage_jpeg_load(fileName.c_str(),&width_ret,&height_ret,&numComponents_ret);
if (imageData==NULL) return NULL;
int s = width_ret;
int t = height_ret;
int r = 1;
int internalFormat = numComponents_ret;
unsigned int pixelFormat =
numComponents_ret == 1 ? GL_LUMINANCE :
numComponents_ret == 2 ? GL_LUMINANCE_ALPHA :
numComponents_ret == 3 ? GL_RGB :
numComponents_ret == 4 ? GL_RGBA : (GLenum)-1;
unsigned int dataType = GL_UNSIGNED_BYTE;
osg::Image* pOsgImage = new osg::Image;
pOsgImage->setFileName(fileName.c_str());
pOsgImage->setImage(s,t,r,
internalFormat,
pixelFormat,
dataType,
imageData);
return pOsgImage;
}
};
// now register with Registry to instantiate the above
// reader/writer.
osg::RegisterReaderWriterProxy<ReaderWriterJPEG> g_readerWriter_JPEG_Proxy;

View File

Some files were not shown because too many files have changed in this diff Show More