aboutsummaryrefslogtreecommitdiff
path: root/tool_src
diff options
context:
space:
mode:
authorFelix Morgner <felix.morgner@gmail.com>2026-08-24 11:16:07 +0200
committerFelix Morgner <felix.morgner@gmail.com>2026-08-24 11:16:07 +0200
commitc068f22329d5cc722622a2183bbb22eef2093df7 (patch)
tree12d56c1aede67988a55e241364606bfbb4dba933 /tool_src
downloadopenparsec-main.tar.xz
openparsec-main.zip
initial importHEADmain
Diffstat (limited to 'tool_src')
-rw-r--r--tool_src/BspLib/AodFormat.cpp39
-rw-r--r--tool_src/BspLib/AodFormat.h59
-rw-r--r--tool_src/BspLib/AodInput.cpp183
-rw-r--r--tool_src/BspLib/AodInput.h42
-rw-r--r--tool_src/BspLib/AodOutput.cpp106
-rw-r--r--tool_src/BspLib/AodOutput.h41
-rw-r--r--tool_src/BspLib/BRep.cpp1514
-rw-r--r--tool_src/BspLib/BRep.h93
-rw-r--r--tool_src/BspLib/BSPNode.cpp401
-rw-r--r--tool_src/BspLib/BSPNode.h132
-rw-r--r--tool_src/BspLib/BSPTree.cpp121
-rw-r--r--tool_src/BspLib/BSPTree.h182
-rw-r--r--tool_src/BspLib/BoundingBox.cpp223
-rw-r--r--tool_src/BspLib/BoundingBox.h72
-rw-r--r--tool_src/BspLib/BspFormat.cpp71
-rw-r--r--tool_src/BspLib/BspFormat.h77
-rw-r--r--tool_src/BspLib/BspInput.cpp406
-rw-r--r--tool_src/BspLib/BspInput.h48
-rwxr-xr-xtool_src/BspLib/BspLib.vcproj1055
-rwxr-xr-xtool_src/BspLib/BspLib.vcxproj385
-rwxr-xr-xtool_src/BspLib/BspLib.vcxproj.filters272
-rwxr-xr-xtool_src/BspLib/BspLib.vcxproj.user4
-rw-r--r--tool_src/BspLib/BspLibDefs.h163
-rw-r--r--tool_src/BspLib/BspObject.cpp641
-rw-r--r--tool_src/BspLib/BspObject.h258
-rw-r--r--tool_src/BspLib/BspObjectList.cpp197
-rw-r--r--tool_src/BspLib/BspObjectList.h151
-rw-r--r--tool_src/BspLib/BspOutput.cpp108
-rw-r--r--tool_src/BspLib/BspOutput.h41
-rw-r--r--tool_src/BspLib/BspTool.cpp68
-rw-r--r--tool_src/BspLib/BspTool.h34
-rw-r--r--tool_src/BspLib/COPYING482
-rw-r--r--tool_src/BspLib/Chunk.h280
-rw-r--r--tool_src/BspLib/EpsAreas.cpp28
-rw-r--r--tool_src/BspLib/Face.cpp352
-rw-r--r--tool_src/BspLib/Face.h223
-rw-r--r--tool_src/BspLib/IOData3D.cpp45
-rw-r--r--tool_src/BspLib/IOData3D.h76
-rw-r--r--tool_src/BspLib/InputData3D.cpp175
-rw-r--r--tool_src/BspLib/InputData3D.h83
-rw-r--r--tool_src/BspLib/LineSeg.cpp71
-rw-r--r--tool_src/BspLib/LineSeg2.h46
-rw-r--r--tool_src/BspLib/LineSeg3.h46
-rw-r--r--tool_src/BspLib/Makefile62
-rw-r--r--tool_src/BspLib/Mapping.cpp63
-rw-r--r--tool_src/BspLib/Mapping.h89
-rw-r--r--tool_src/BspLib/Material.h57
-rw-r--r--tool_src/BspLib/ObjectAodFormat.cpp200
-rw-r--r--tool_src/BspLib/ObjectAodFormat.h52
-rw-r--r--tool_src/BspLib/ObjectBSPNode.cpp170
-rw-r--r--tool_src/BspLib/ObjectBSPNode.h70
-rw-r--r--tool_src/BspLib/ObjectBSPTree.h97
-rw-r--r--tool_src/BspLib/ObjectBinFormat.cpp758
-rw-r--r--tool_src/BspLib/ObjectBinFormat.h55
-rw-r--r--tool_src/BspLib/ObjectBspFormat.cpp213
-rw-r--r--tool_src/BspLib/ObjectBspFormat.h53
-rw-r--r--tool_src/BspLib/OutputData3D.cpp105
-rw-r--r--tool_src/BspLib/OutputData3D.h44
-rw-r--r--tool_src/BspLib/Plane.h146
-rw-r--r--tool_src/BspLib/Polygon.cpp1042
-rw-r--r--tool_src/BspLib/Polygon.h280
-rw-r--r--tool_src/BspLib/PolygonList.cpp213
-rw-r--r--tool_src/BspLib/PolygonList.h153
-rw-r--r--tool_src/BspLib/SingleFormat.cpp158
-rw-r--r--tool_src/BspLib/SingleFormat.h119
-rw-r--r--tool_src/BspLib/SingleInput.cpp699
-rw-r--r--tool_src/BspLib/SingleInput.h83
-rw-r--r--tool_src/BspLib/SingleOutput.cpp125
-rw-r--r--tool_src/BspLib/SingleOutput.h44
-rw-r--r--tool_src/BspLib/SystemIO.cpp314
-rw-r--r--tool_src/BspLib/SystemIO.h172
-rw-r--r--tool_src/BspLib/Texture.cpp77
-rw-r--r--tool_src/BspLib/Texture.h58
-rw-r--r--tool_src/BspLib/Transform2.cpp282
-rw-r--r--tool_src/BspLib/Transform2.h111
-rw-r--r--tool_src/BspLib/Transform3.cpp312
-rw-r--r--tool_src/BspLib/Transform3.h106
-rw-r--r--tool_src/BspLib/TriMapping.cpp26
-rw-r--r--tool_src/BspLib/TriMapping.h43
-rw-r--r--tool_src/BspLib/Vector.h100
-rw-r--r--tool_src/BspLib/Vector2.h113
-rw-r--r--tool_src/BspLib/Vector3.h134
-rw-r--r--tool_src/BspLib/Vertex.cpp47
-rw-r--r--tool_src/BspLib/Vertex.h206
-rw-r--r--tool_src/BspLib/Vertex2.h76
-rw-r--r--tool_src/BspLib/Vertex3.h72
-rw-r--r--tool_src/BspLib/VertexChunk.cpp237
-rw-r--r--tool_src/BspLib/VertexChunk.h129
-rw-r--r--tool_src/BspLib/VrmlFile.cpp133
-rw-r--r--tool_src/BspLib/VrmlFile.h48
-rw-r--r--tool_src/QvLib/Makefile90
-rw-r--r--tool_src/QvLib/QvBasic.h46
-rw-r--r--tool_src/QvLib/QvChildList.cpp10
-rw-r--r--tool_src/QvLib/QvChildList.h13
-rw-r--r--tool_src/QvLib/QvCone.cpp27
-rw-r--r--tool_src/QvLib/QvCone.h26
-rw-r--r--tool_src/QvLib/QvCoordinate3.cpp17
-rw-r--r--tool_src/QvLib/QvCoordinate3.h16
-rw-r--r--tool_src/QvLib/QvCube.cpp21
-rw-r--r--tool_src/QvLib/QvCube.h18
-rw-r--r--tool_src/QvLib/QvCylinder.cpp28
-rw-r--r--tool_src/QvLib/QvCylinder.h27
-rw-r--r--tool_src/QvLib/QvDB.h18
-rw-r--r--tool_src/QvLib/QvDb.cpp29
-rw-r--r--tool_src/QvLib/QvDebugError.cpp16
-rw-r--r--tool_src/QvLib/QvDebugError.h9
-rw-r--r--tool_src/QvLib/QvDict.cpp98
-rw-r--r--tool_src/QvLib/QvDict.h33
-rw-r--r--tool_src/QvLib/QvDirectionalLight.cpp25
-rw-r--r--tool_src/QvLib/QvDirectionalLight.h22
-rw-r--r--tool_src/QvLib/QvElement.cpp38
-rw-r--r--tool_src/QvLib/QvElement.h62
-rw-r--r--tool_src/QvLib/QvField.cpp175
-rw-r--r--tool_src/QvLib/QvField.h72
-rw-r--r--tool_src/QvLib/QvFieldData.cpp266
-rw-r--r--tool_src/QvLib/QvFieldData.h46
-rw-r--r--tool_src/QvLib/QvFields.h23
-rw-r--r--tool_src/QvLib/QvGroup.cpp81
-rw-r--r--tool_src/QvLib/QvGroup.h19
-rw-r--r--tool_src/QvLib/QvIndexedFaceSet.cpp23
-rw-r--r--tool_src/QvLib/QvIndexedFaceSet.h21
-rw-r--r--tool_src/QvLib/QvIndexedLineSet.cpp23
-rw-r--r--tool_src/QvLib/QvIndexedLineSet.h21
-rw-r--r--tool_src/QvLib/QvInfo.cpp17
-rw-r--r--tool_src/QvLib/QvInfo.h16
-rw-r--r--tool_src/QvLib/QvInput.cpp568
-rw-r--r--tool_src/QvLib/QvInput.h65
-rw-r--r--tool_src/QvLib/QvLevelOfDetail.cpp17
-rw-r--r--tool_src/QvLib/QvLevelOfDetail.h16
-rwxr-xr-xtool_src/QvLib/QvLib.vcproj1765
-rwxr-xr-xtool_src/QvLib/QvLib.vcxproj597
-rw-r--r--tool_src/QvLib/QvLists.cpp5
-rw-r--r--tool_src/QvLib/QvLists.h17
-rw-r--r--tool_src/QvLib/QvMFColor.cpp13
-rw-r--r--tool_src/QvLib/QvMFColor.h12
-rw-r--r--tool_src/QvLib/QvMFFloat.cpp9
-rw-r--r--tool_src/QvLib/QvMFFloat.h12
-rw-r--r--tool_src/QvLib/QvMFLong.cpp9
-rw-r--r--tool_src/QvLib/QvMFLong.h12
-rw-r--r--tool_src/QvLib/QvMFVec2f.cpp12
-rw-r--r--tool_src/QvLib/QvMFVec2f.h12
-rw-r--r--tool_src/QvLib/QvMFVec3f.cpp13
-rw-r--r--tool_src/QvLib/QvMFVec3f.h12
-rw-r--r--tool_src/QvLib/QvMaterial.cpp27
-rw-r--r--tool_src/QvLib/QvMaterial.h22
-rw-r--r--tool_src/QvLib/QvMaterialBinding.cpp31
-rw-r--r--tool_src/QvLib/QvMaterialBinding.h28
-rw-r--r--tool_src/QvLib/QvMatrixTransform.cpp20
-rw-r--r--tool_src/QvLib/QvMatrixTransform.h16
-rw-r--r--tool_src/QvLib/QvName.cpp126
-rw-r--r--tool_src/QvLib/QvNode.cpp381
-rw-r--r--tool_src/QvLib/QvNode.h57
-rw-r--r--tool_src/QvLib/QvNodes.h39
-rw-r--r--tool_src/QvLib/QvNormal.cpp19
-rw-r--r--tool_src/QvLib/QvNormal.h16
-rw-r--r--tool_src/QvLib/QvNormalBinding.cpp29
-rw-r--r--tool_src/QvLib/QvNormalBinding.h28
-rw-r--r--tool_src/QvLib/QvOrthographicCamera.cpp28
-rw-r--r--tool_src/QvLib/QvOrthographicCamera.h22
-rw-r--r--tool_src/QvLib/QvPList.cpp64
-rw-r--r--tool_src/QvLib/QvPList.h29
-rw-r--r--tool_src/QvLib/QvPerspectiveCamera.cpp30
-rw-r--r--tool_src/QvLib/QvPerspectiveCamera.h23
-rw-r--r--tool_src/QvLib/QvPointLight.cpp25
-rw-r--r--tool_src/QvLib/QvPointLight.h22
-rw-r--r--tool_src/QvLib/QvPointSet.cpp19
-rw-r--r--tool_src/QvLib/QvPointSet.h19
-rw-r--r--tool_src/QvLib/QvReadError.cpp19
-rw-r--r--tool_src/QvLib/QvReadError.h11
-rw-r--r--tool_src/QvLib/QvRotation.cpp20
-rw-r--r--tool_src/QvLib/QvRotation.h16
-rw-r--r--tool_src/QvLib/QvSFBitMask.cpp84
-rw-r--r--tool_src/QvLib/QvSFBitMask.h12
-rw-r--r--tool_src/QvLib/QvSFBool.cpp37
-rw-r--r--tool_src/QvLib/QvSFBool.h12
-rw-r--r--tool_src/QvLib/QvSFColor.cpp11
-rw-r--r--tool_src/QvLib/QvSFColor.h12
-rw-r--r--tool_src/QvLib/QvSFEnum.cpp58
-rw-r--r--tool_src/QvLib/QvSFEnum.h38
-rw-r--r--tool_src/QvLib/QvSFFloat.cpp9
-rw-r--r--tool_src/QvLib/QvSFFloat.h12
-rw-r--r--tool_src/QvLib/QvSFImage.cpp39
-rw-r--r--tool_src/QvLib/QvSFImage.h14
-rw-r--r--tool_src/QvLib/QvSFLong.cpp9
-rw-r--r--tool_src/QvLib/QvSFLong.h12
-rw-r--r--tool_src/QvLib/QvSFMatrix.cpp16
-rw-r--r--tool_src/QvLib/QvSFMatrix.h12
-rw-r--r--tool_src/QvLib/QvSFRotation.cpp12
-rw-r--r--tool_src/QvLib/QvSFRotation.h13
-rw-r--r--tool_src/QvLib/QvSFString.cpp9
-rw-r--r--tool_src/QvLib/QvSFString.h12
-rw-r--r--tool_src/QvLib/QvSFVec2f.cpp10
-rw-r--r--tool_src/QvLib/QvSFVec2f.h12
-rw-r--r--tool_src/QvLib/QvSFVec3f.cpp11
-rw-r--r--tool_src/QvLib/QvSFVec3f.h12
-rw-r--r--tool_src/QvLib/QvScale.cpp17
-rw-r--r--tool_src/QvLib/QvScale.h16
-rw-r--r--tool_src/QvLib/QvSeparator.cpp23
-rw-r--r--tool_src/QvLib/QvSeparator.h24
-rw-r--r--tool_src/QvLib/QvShapeHints.cpp37
-rw-r--r--tool_src/QvLib/QvShapeHints.h36
-rw-r--r--tool_src/QvLib/QvSphere.cpp17
-rw-r--r--tool_src/QvLib/QvSphere.h17
-rw-r--r--tool_src/QvLib/QvSpotLight.h29
-rw-r--r--tool_src/QvLib/QvSpotlight.cpp35
-rw-r--r--tool_src/QvLib/QvState.cpp128
-rw-r--r--tool_src/QvLib/QvState.h64
-rw-r--r--tool_src/QvLib/QvString.cpp106
-rw-r--r--tool_src/QvLib/QvString.h101
-rw-r--r--tool_src/QvLib/QvSubField.h72
-rw-r--r--tool_src/QvLib/QvSubNode.h41
-rw-r--r--tool_src/QvLib/QvSwitch.cpp17
-rw-r--r--tool_src/QvLib/QvSwitch.h19
-rw-r--r--tool_src/QvLib/QvTexture2.cpp55
-rw-r--r--tool_src/QvLib/QvTexture2.h29
-rw-r--r--tool_src/QvLib/QvTexture2Transform.cpp23
-rw-r--r--tool_src/QvLib/QvTexture2Transform.h20
-rw-r--r--tool_src/QvLib/QvTextureCoordinate2.cpp17
-rw-r--r--tool_src/QvLib/QvTextureCoordinate2.h16
-rw-r--r--tool_src/QvLib/QvTransform.cpp31
-rw-r--r--tool_src/QvLib/QvTransform.h21
-rw-r--r--tool_src/QvLib/QvTransformSeparator.cpp13
-rw-r--r--tool_src/QvLib/QvTransformSeparator.h13
-rw-r--r--tool_src/QvLib/QvTranslation.cpp17
-rw-r--r--tool_src/QvLib/QvTranslation.h16
-rw-r--r--tool_src/QvLib/QvTraverse.cpp317
-rw-r--r--tool_src/QvLib/QvTraverse.p15927
-rw-r--r--tool_src/QvLib/QvUnknownNode.cpp26
-rw-r--r--tool_src/QvLib/QvUnknownNode.h18
-rw-r--r--tool_src/QvLib/QvWWWAnchor.cpp24
-rw-r--r--tool_src/QvLib/QvWWWAnchor.h24
-rw-r--r--tool_src/QvLib/QvWWWInline.cpp24
-rw-r--r--tool_src/QvLib/QvWWWInline.h20
-rw-r--r--tool_src/QvLib/QvWWWInline.p9602
-rw-r--r--tool_src/makeodt/COPYING482
-rw-r--r--tool_src/makeodt/Makefile18
-rw-r--r--tool_src/makeodt/getopt.cpp620
-rw-r--r--tool_src/makeodt/getopt.h78
-rwxr-xr-xtool_src/makeodt/makeodtbin0 -> 2023262 bytes
-rw-r--r--tool_src/makeodt/makeodt.cpp633
-rw-r--r--tool_src/makeodt/makeodt.h40
-rwxr-xr-xtool_src/makeodt/makeodt.sln54
-rwxr-xr-xtool_src/makeodt/makeodt.vcproj195
-rwxr-xr-xtool_src/makeodt/makeodt.vcxproj159
-rwxr-xr-xtool_src/makeodt/meshconv.exebin0 -> 361472 bytes
-rwxr-xr-xtool_src/makeodt/planet1.wrl396
-rwxr-xr-xtool_src/makeodt/test_ship526
-rwxr-xr-xtool_src/makeodt/test_ship2.vrml52
-rwxr-xr-xtool_src/makeodt/test_ship2.vrml~52
-rwxr-xr-xtool_src/makeodt/test_ship~649
-rwxr-xr-xtool_src/redhat_install_build_deps32.sh25
251 files changed, 54393 insertions, 0 deletions
diff --git a/tool_src/BspLib/AodFormat.cpp b/tool_src/BspLib/AodFormat.cpp
new file mode 100644
index 0000000..8ee949c
--- /dev/null
+++ b/tool_src/BspLib/AodFormat.cpp
@@ -0,0 +1,39 @@
+//-----------------------------------------------------------------------------
+// BSPLIB MODULE: AodFormat.cpp
+//
+// Copyright (c) 1997 by Markus Hadwiger
+// All Rights Reserved.
+//-----------------------------------------------------------------------------
+
+// bsplib header files
+#include "AodFormat.h"
+
+
+BSPLIB_NAMESPACE_BEGIN
+
+
+// get index to section id specified as string (this function is static!) -----
+//
+int AodFormat::GetSectionId( char *section_name )
+{
+ return SingleFormat::GetSectionId( section_name );
+}
+
+
+// get name of section specified via id (this function is static!) ------------
+//
+const char *AodFormat::GetSectionName( int section_id )
+{
+ return SingleFormat::GetSectionName( section_id );
+}
+
+
+// AodFormat specific static variables ----------------------------------------
+//
+const char AodFormat::_aodsig_str[] = "#AOD";
+const char AodFormat::AOD_FILE_EXTENSION[] = ".aod";
+
+
+BSPLIB_NAMESPACE_END
+
+//-----------------------------------------------------------------------------
diff --git a/tool_src/BspLib/AodFormat.h b/tool_src/BspLib/AodFormat.h
new file mode 100644
index 0000000..64a216c
--- /dev/null
+++ b/tool_src/BspLib/AodFormat.h
@@ -0,0 +1,59 @@
+//-----------------------------------------------------------------------------
+// BSPLIB HEADER: AodFormat.h
+//
+// Copyright (c) 1997 by Markus Hadwiger
+// All Rights Reserved.
+//-----------------------------------------------------------------------------
+
+#ifndef _AODFORMAT_H_
+#define _AODFORMAT_H_
+
+// bsplib header files
+#include "BspLibDefs.h"
+#include "SingleFormat.h"
+
+
+BSPLIB_NAMESPACE_BEGIN
+
+
+// class containing aod format specifics --------------------------------------
+//
+class AodFormat : public virtual SingleFormat {
+
+protected:
+
+ // section enumeration
+ enum {
+ _num_aod_sections = _num_single_sections
+ };
+
+//protected:
+public:
+ AodFormat() { }
+ ~AodFormat() { }
+
+ AodFormat( const AodFormat& copyobj ) : SingleFormat( copyobj ) { }
+ AodFormat& operator =( const AodFormat& copyobj );
+
+protected:
+ static int GetSectionId( char *section_name );
+ static const char* GetSectionName( int section_id );
+
+protected:
+ static const char _aodsig_str[];
+ static const char AOD_FILE_EXTENSION[];
+};
+
+// assignment operator --------------------------------------------------------
+inline AodFormat& AodFormat::operator =( const AodFormat& copyobj )
+{
+ *(SingleFormat *)this = copyobj;
+ return *this;
+}
+
+
+BSPLIB_NAMESPACE_END
+
+
+#endif // _AODFORMAT_H_
+
diff --git a/tool_src/BspLib/AodInput.cpp b/tool_src/BspLib/AodInput.cpp
new file mode 100644
index 0000000..1224a9e
--- /dev/null
+++ b/tool_src/BspLib/AodInput.cpp
@@ -0,0 +1,183 @@
+//-----------------------------------------------------------------------------
+// BSPLIB MODULE: AodInput.cpp
+//
+// Copyright (c) 1996-1997 by Markus Hadwiger
+// All Rights Reserved.
+//-----------------------------------------------------------------------------
+
+// bsplib header files
+#include "AodInput.h"
+#include "BspObject.h"
+#include "BspTool.h"
+
+
+BSPLIB_NAMESPACE_BEGIN
+
+
+// file is read and parsed immediately after construction of an object --------
+//
+AodInput::AodInput( BspObjectList objectlist, const char *filename ) :
+ SingleInput( objectlist, filename )
+{
+ ParseObjectData();
+}
+
+
+// destructor destroys only class members and the base classes ----------------
+//
+AodInput::~AodInput()
+{
+}
+
+
+// assignment copies only the AodFormat part of the object --------------------
+//
+AodInput& AodInput::operator =( const AodInput& copyobj )
+{
+ *(AodFormat *)this = copyobj;
+ return *this;
+}
+
+
+// print error message if error in object data-file ---------------------------
+//
+void AodInput::ParseError( int section )
+{
+ //NOTE:
+ // GetSectionName() is overloaded and not virtual, therefore
+ // SingleInput's ParseError() cannot be used!
+ sprintf( line, "%sin section %s (line %d)", parser_err_str,
+ GetSectionName( section ), m_parser_lineno );
+ ErrorMessage( line );
+ HandleCriticalError();
+}
+
+
+// parse object data-file -----------------------------------------------------
+//
+int AodInput::ParseObjectData()
+{
+ int faceprop_itemsread = 0;
+ int facenorm_itemsread = 0;
+
+ InfoMessage( "Processing input data file (format='AOD V1.1') ..." );
+
+ // parse sections and read data -------------------------------
+ m_section = _nil;
+ while ( m_input.ReadLine( line, TEXTLINE_MAX ) != NULL ) {
+
+ if ( ( m_parser_lineno++ & PARSER_DOT_SIZE ) == 0 )
+ printf( "." ), fflush( stdout );
+
+ if ( ( m_scanptr = strtok( line, "/, \t\n\r" ) ) == NULL )
+ continue;
+ else if ( *m_scanptr == ';' )
+ continue;
+ else if ( strnicmp( m_scanptr, "<end", 4 ) == 0 )
+ break;
+ else if ( *m_scanptr == '#' ) {
+ if ( strncmp( m_scanptr, _aodsig_str, strlen( _aodsig_str ) ) == 0 ) {
+ m_section = _comment;
+ } else if ( ( m_section = GetSectionId( m_scanptr ) ) == _nil ) {
+ {
+ StrScratch error;
+ sprintf( error, "%s[Undefined section-name]: %s (line %d)",
+ parser_err_str, m_scanptr, m_parser_lineno );
+ ErrorMessage( error );
+ }
+ HandleCriticalError();
+ }
+ } else {
+ switch ( m_section ) {
+
+ // list of vertices ------------------------------------
+ case _vertices :
+ ReadVertex();
+ break;
+
+ // vertexnums of faces ---------------------------------
+ case _faces :
+ ReadFace( TRUE );
+ break;
+
+ // normals for face's planes ---------------------------
+ case _facenormals :
+
+ //NOTE:
+ // face normals are currently ignored in the aod
+ // file, since they are too inaccurate for later
+ // BSP compilation purposes. if no normals are read
+ // in, they will be calculated later on anyway.
+
+ //ReadFaceNormal( facenorm_itemsread );
+ break;
+
+ // properties of faces ---------------------------------
+ case _faceproperties :
+ ReadFaceProperties( faceprop_itemsread );
+ break;
+
+ // texture->face correspondences ----------------------
+ case _correspondences :
+ ReadCorrespondences();
+ break;
+
+ // texturing data -----------------------------------
+ case _textures :
+ ReadTextures();
+ break;
+
+ // location of the object ---------------------------
+ case _worldlocation :
+ ReadWorldLocation();
+ break;
+
+ // location of camera -------------------------------
+ case _camera :
+ ReadCameraLocation();
+ break;
+
+ // filename of palette file -------------------------
+ case _palette :
+ ReadPaletteFilename();
+ break;
+
+ // scalefactors for object --------------------------
+ case _scalefactors :
+ ReadScaleFactors();
+ break;
+
+ // exchange command for axes ------------------------
+ case _xchange :
+ ReadXChangeCommand();
+ break;
+
+ // set new object origin ----------------------------
+ case _setorigin :
+ ReadOrigin();
+ break;
+
+ }
+ }
+ }
+
+ // do post processing after parsing
+ ApplyOriginTranslation();
+ FilterAxesDirSwitch();
+ FilterScaleFactors();
+ FilterAxesExchange();
+ EnforceMaximumExtents();
+ m_baseobject->CheckParsedData();
+
+ InfoMessage( "\nObject data ok.\n" );
+
+ // do colorindex to rgb conversion
+ ConvertColIndxs();
+
+ return ( m_inputok = TRUE );
+}
+
+
+BSPLIB_NAMESPACE_END
+
+//-----------------------------------------------------------------------------
diff --git a/tool_src/BspLib/AodInput.h b/tool_src/BspLib/AodInput.h
new file mode 100644
index 0000000..e04b13f
--- /dev/null
+++ b/tool_src/BspLib/AodInput.h
@@ -0,0 +1,42 @@
+//-----------------------------------------------------------------------------
+// BSPLIB HEADER: AodInput.h
+//
+// Copyright (c) 1996-1997 by Markus Hadwiger
+// All Rights Reserved.
+//-----------------------------------------------------------------------------
+
+#ifndef _AODINPUT_H_
+#define _AODINPUT_H_
+
+// bsplib header files
+#include "BspLibDefs.h"
+#include "AodFormat.h"
+#include "SingleInput.h"
+
+
+BSPLIB_NAMESPACE_BEGIN
+
+
+// file input class for aod format files --------------------------------------
+//
+class AodInput : public AodFormat, public SingleInput {
+
+public:
+ AodInput( BspObjectList objectlist, const char *filename );
+ ~AodInput();
+
+ AodInput& operator =( const AodInput& copyobj );
+
+public:
+ int ParseObjectData();
+
+protected:
+ void ParseError( int section );
+};
+
+
+BSPLIB_NAMESPACE_END
+
+
+#endif // _AODINPUT_H_
+
diff --git a/tool_src/BspLib/AodOutput.cpp b/tool_src/BspLib/AodOutput.cpp
new file mode 100644
index 0000000..316cf9a
--- /dev/null
+++ b/tool_src/BspLib/AodOutput.cpp
@@ -0,0 +1,106 @@
+//-----------------------------------------------------------------------------
+// BSPLIB MODULE: AodOutput.cpp
+//
+// Copyright (c) 1996-1997 by Markus Hadwiger
+// All Rights Reserved.
+//-----------------------------------------------------------------------------
+
+// bsplib header files
+#include "AodOutput.h"
+#include "BspObject.h"
+#include "BspTool.h"
+#include "ObjectAodFormat.h"
+
+
+BSPLIB_NAMESPACE_BEGIN
+
+
+// construct AodOutput object -------------------------------------------------
+//
+AodOutput::AodOutput( BspObjectList objectlist, const char *filename ) :
+ SingleOutput( objectlist, BspTool::ChangeExtension( filename, AOD_FILE_EXTENSION ) )
+{
+}
+
+
+// construct AodOutput object using an InputData3D object ---------------------
+//
+AodOutput::AodOutput( const InputData3D& inputdata ) :
+ SingleOutput( inputdata.getObjectList(),
+ BspTool::ChangeExtension( inputdata.getFileName(), AOD_FILE_EXTENSION ) )
+{
+ // get pointer to "real" input object
+ InputData3D *inputobj = inputdata.getRealObject();
+
+ // try to isolate the AodFormat part of the input object
+ AodFormat *aodformat = dynamic_cast<AodFormat*>(inputobj);
+
+ // copy over if cast succeeded
+ if ( aodformat != NULL ) {
+
+ *(AodFormat *)this = *aodformat;
+
+ } else {
+
+ // try to isolate the SingleFormat part of the input object
+ SingleFormat *singleformat = dynamic_cast<SingleFormat*>(inputobj);
+
+ // copy over if cast succeeded
+ if ( singleformat != NULL )
+ *(SingleFormat *)this = *singleformat;
+ }
+}
+
+
+// write outputfile before destruction ----------------------------------------
+//
+AodOutput::~AodOutput()
+{
+ if ( m_output.Status() == SYSTEM_IO_OK )
+ WriteOutputFile();
+}
+
+
+// assignment copies only the AodFormat part of the object --------------------
+//
+AodOutput& AodOutput::operator =( const AodOutput& copyobj )
+{
+ *(AodFormat *)this = copyobj;
+ return *this;
+}
+
+
+// write '.aod' file for this object ------------------------------------------
+//
+int AodOutput::WriteOutputFile()
+{
+ sprintf( line, "Writing ascii object data to \"%s\"...\n", (const char *) m_filename );
+ InfoMessage( line );
+
+ sprintf( line, "%s\n\n", AOD_SIGNATURE_1_1 );
+ m_output.WriteLine( line );
+
+ // write bsplib banner to file and init output data
+ SingleOutput::InitOutput();
+
+ // create 3-D object knowing about '.aod' format
+ ObjectAodFormat obj( *m_baseobject, *this );
+
+ // write attribute lists
+ obj.WriteVertexList( m_output );
+ obj.WriteFaceList( m_output );
+ obj.WriteNormals( m_output );
+ obj.WriteFaceProperties( m_output );
+ obj.WriteMappingList( m_output );
+ obj.WriteTextureList( m_output );
+
+ // write common part
+ SingleOutput::WriteOutputFile();
+
+ return m_output.Status();
+}
+
+
+BSPLIB_NAMESPACE_END
+
+//-----------------------------------------------------------------------------
diff --git a/tool_src/BspLib/AodOutput.h b/tool_src/BspLib/AodOutput.h
new file mode 100644
index 0000000..88a2f0e
--- /dev/null
+++ b/tool_src/BspLib/AodOutput.h
@@ -0,0 +1,41 @@
+//-----------------------------------------------------------------------------
+// BSPLIB HEADER: AodOutput.h
+//
+// Copyright (c) 1996-1997 by Markus Hadwiger
+// All Rights Reserved.
+//-----------------------------------------------------------------------------
+
+#ifndef _AODOUTPUT_H_
+#define _AODOUTPUT_H_
+
+// bsplib header files
+#include "BspLibDefs.h"
+#include "AodFormat.h"
+#include "SingleOutput.h"
+#include "InputData3D.h"
+
+
+BSPLIB_NAMESPACE_BEGIN
+
+
+// file output class for aod format files -------------------------------------
+//
+class AodOutput : public AodFormat, public SingleOutput {
+
+public:
+ AodOutput( BspObjectList objectlist, const char *filename );
+ AodOutput( const InputData3D& inputdata );
+ ~AodOutput();
+
+ AodOutput& operator =( const AodOutput& copyobj );
+
+public:
+ int WriteOutputFile();
+};
+
+
+BSPLIB_NAMESPACE_END
+
+
+#endif // _AODOUTPUT_H_
+
diff --git a/tool_src/BspLib/BRep.cpp b/tool_src/BspLib/BRep.cpp
new file mode 100644
index 0000000..1b4a49a
--- /dev/null
+++ b/tool_src/BspLib/BRep.cpp
@@ -0,0 +1,1514 @@
+//-----------------------------------------------------------------------------
+// BSPLIB MODULE: BRep.cpp
+//
+// Copyright (c) 1997-1998 by Markus Hadwiger
+// All Rights Reserved.
+//-----------------------------------------------------------------------------
+
+// bsplib headers
+#include "BRep.h"
+
+// qvlib headers
+#include <QvCoordinate3.h>
+#include <QvMaterial.h>
+#include <QvMaterialBinding.h>
+#include <QvMatrixTransform.h>
+#include <QvNormal.h>
+#include <QvNormalBinding.h>
+#include <QvRotation.h>
+#include <QvScale.h>
+#include <QvShapeHints.h>
+#include <QvTexture2.h>
+#include <QvTextureCoordinate2.h>
+#include <QvTexture2Transform.h>
+#include <QvTranslation.h>
+#include <QvTransform.h>
+
+#ifdef USE_JPEG_LIBRARY
+#include <jpeglib.h>
+#endif
+
+BSPLIB_NAMESPACE_BEGIN
+
+
+struct tga_header_s {
+
+ byte IDLength;
+ byte CMapType;
+ byte ImgType;
+ byte CMapStartLo;
+ byte CMapStartHi;
+ byte CMapLengthLo;
+ byte CMapLengthHi;
+ byte CMapDepth;
+ byte XOffSetLo;
+ byte XOffSetHi;
+ byte YOffSetLo;
+ byte YOffSetHi;
+ byte WidthLo;
+ byte WidthHi;
+ byte HeightLo;
+ byte HeightHi;
+ byte PixelDepth;
+ byte ImageDescriptor;
+};
+
+
+// constructor for b-rep object -----------------------------------------------
+//
+BRep::BRep( QvState *state )
+{
+ // save pointer to state
+ m_state = state;
+
+ // create new object and insert into list
+ m_baseobject = m_state->vrmlfile_base->getObjectList().CreateNewObject();
+}
+
+
+// fetch pointer to Coordinate3 array and length ------------------------------
+//
+float *BRep::FetchCoordinate3State( int &num )
+{
+ num = 0;
+ float *coarray = NULL;
+ QvElement *elt = m_state->getTopElement( QvState::Coordinate3Index );
+
+ if ( elt != NULL ) {
+ QvCoordinate3 *c3 = (QvCoordinate3 *) elt->data;
+ num = c3->point.num;
+ coarray = c3->point.values;
+ }
+
+ return coarray;
+}
+
+
+// fetch pointer to texture coordinates array and length ----------------------
+//
+float *BRep::FetchTextureCoordinate2State( int &num )
+{
+ num = 0;
+ float *coarray = NULL;
+ QvElement *elt = m_state->getTopElement( QvState::TextureCoordinate2Index );
+
+ if ( elt != NULL ) {
+ QvTextureCoordinate2 *tc = (QvTextureCoordinate2 *) elt->data;
+ num = tc->point.num;
+ coarray = tc->point.values;
+ }
+
+ return coarray;
+}
+
+
+// fetch pointer to normals array and length ----------------------------------
+//
+float *BRep::FetchNormalState( int &num )
+{
+ num = 0;
+ float *coarray = NULL;
+ QvElement *elt = m_state->getTopElement( QvState::NormalIndex );
+
+ if ( elt != NULL ) {
+ QvNormal *nml = (QvNormal *) elt->data;
+ num = nml->vector.num;
+ coarray = nml->vector.values;
+ }
+
+ return coarray;
+}
+
+
+// accumulate current transformation stack and init Transform3 object ---------
+//
+void BRep::FetchTransformationState( Transform3& trafo )
+{
+ trafo.LoadIdentity();
+
+ QvElement *trafoelt = NULL;
+ trafoelt = m_state->getTopElement( QvState::TransformationIndex );
+ for ( ; trafoelt; trafoelt = trafoelt->next ) {
+
+ if ( trafoelt->type == QvElement::Translation ) {
+ QvTranslation *tnode = (QvTranslation *) trafoelt->data;
+ trafo.Translate( tnode->translation.value[ 0 ],
+ tnode->translation.value[ 1 ],
+ tnode->translation.value[ 2 ] );
+ } else if ( trafoelt->type == QvElement::Rotation ) {
+ QvRotation *tnode = (QvRotation *) trafoelt->data;
+ trafo.Rotate( tnode->rotation.angle,
+ tnode->rotation.axis[ 0 ],
+ tnode->rotation.axis[ 1 ],
+ tnode->rotation.axis[ 2 ] );
+ } else if ( trafoelt->type == QvElement::Scale ) {
+ QvScale *tnode = (QvScale *) trafoelt->data;
+ trafo.Scale( tnode->scaleFactor.value[ 0 ],
+ tnode->scaleFactor.value[ 1 ],
+ tnode->scaleFactor.value[ 2 ] );
+ } else if ( trafoelt->type == QvElement::Transform ) {
+ QvTransform *tnode = (QvTransform *) trafoelt->data;
+ trafo.Translate( -tnode->center.value[ 0 ],
+ -tnode->center.value[ 1 ],
+ -tnode->center.value[ 2 ] );
+ trafo.Rotate( -tnode->scaleOrientation.angle,
+ tnode->scaleOrientation.axis[ 0 ],
+ tnode->scaleOrientation.axis[ 1 ],
+ tnode->scaleOrientation.axis[ 2 ] );
+ trafo.Scale( tnode->scaleFactor.value[ 0 ],
+ tnode->scaleFactor.value[ 1 ],
+ tnode->scaleFactor.value[ 2 ] );
+ trafo.Rotate( tnode->scaleOrientation.angle,
+ tnode->scaleOrientation.axis[ 0 ],
+ tnode->scaleOrientation.axis[ 1 ],
+ tnode->scaleOrientation.axis[ 2 ] );
+ trafo.Rotate( tnode->rotation.angle,
+ tnode->rotation.axis[ 0 ],
+ tnode->rotation.axis[ 1 ],
+ tnode->rotation.axis[ 2 ] );
+ trafo.Translate( tnode->center.value[ 0 ],
+ tnode->center.value[ 1 ],
+ tnode->center.value[ 2 ] );
+ trafo.Translate( tnode->translation.value[ 0 ],
+ tnode->translation.value[ 1 ],
+ tnode->translation.value[ 2 ] );
+ } else if ( trafoelt->type == QvElement::MatrixTransform ) {
+ QvMatrixTransform *tnode = (QvMatrixTransform *) trafoelt->data;
+ Transform3 tmat( (const float(*)[4]) tnode->matrix.value );
+ trafo.Concat( tmat );
+ }
+ }
+}
+
+
+// accumulate current texture transformation stack into Transform2 object -----
+//
+void BRep::FetchTextureTransformationState( Transform2& trafo )
+{
+ trafo.LoadIdentity();
+
+ QvElement *trafoelt = m_state->getTopElement( QvState::Texture2TransformationIndex );
+ for ( ; trafoelt; trafoelt = trafoelt->next ) {
+
+ if ( trafoelt->type == QvElement::Unknown /*Transform*/ ) {
+
+ //NOTE:
+ // well, yes. QvLib really uses QvElement::Unknown as type
+ // for texture transformations!!
+
+ QvTexture2Transform *tnode = (QvTexture2Transform *) trafoelt->data;
+ trafo.Translate( -tnode->center.value[ 0 ],
+ -tnode->center.value[ 1 ] );
+ trafo.Scale( tnode->scaleFactor.value[ 0 ],
+ tnode->scaleFactor.value[ 1 ] );
+ trafo.Rotate( tnode->rotation.value );
+ trafo.Translate( tnode->center.value[ 0 ],
+ tnode->center.value[ 1 ] );
+ trafo.Translate( tnode->translation.value[ 0 ],
+ tnode->translation.value[ 1 ] );
+ }
+ }
+}
+
+
+// check current texture state; create new texture if necessary ---------------
+//
+Texture *BRep::CheckTexture2State()
+{
+ QvElement *elt = m_state->getTopElement( QvState::Texture2Index );
+
+ if ( elt == NULL )
+ return NULL;
+
+ // fetch texture node
+ QvTexture2 *tex = (QvTexture2 *) elt->data;
+ const char *texfilename = tex->filename.value.getString();
+
+ if ( ( texfilename == NULL ) || ( *texfilename == 0 ) )
+ return NULL;
+
+ // check if texture already exists
+ TextureChunk& texlist = m_baseobject->getTextureList();
+ for ( int i = 0; i < texlist.getNumElements(); i++ ) {
+ if ( strcmp( texlist[ i ].getFile(), texfilename ) == 0 )
+ return &texlist[ i ];
+ }
+
+ // default texture width and height are 1, yielding texture
+ // coordinates between 0.0 and 1.0 when multiplied by vrml
+ // texture coordinates later on.
+ int width = 1;
+ int height = 1;
+
+ // try to open texture file if it is in 3df format to read actual width and height
+ int namelen = strlen( texfilename );
+ if ( ( namelen > 4 ) && ( strcmp( texfilename + namelen - 4, ".3df" ) == 0 ) ) {
+
+ // open 3df file
+ FILE *fp = fopen( texfilename, "rb" );
+ if ( fp != NULL ) {
+
+ // header fields
+ char version[ 7 ];
+ char formatspec[ 11 ];
+ int lodsmall;
+ int lodlarge;
+ int aspectw;
+ int aspecth;
+
+ // scan out header
+ if ( fscanf( fp, "3df v%6s %10s lod range: %i %i aspect ratio: %i %i",
+ version, formatspec, &lodsmall, &lodlarge, &aspectw, &aspecth ) == 6 ) {
+
+ fclose( fp );
+
+ version[ 6 ] = 0;
+ formatspec[ 10 ] = 0;
+
+ // determine geometry
+ int aindx = ( aspectw << 4 ) | aspecth;
+ switch ( aindx ) {
+
+ case 0x81 :
+ width = lodlarge;
+ height = lodlarge / 8;
+ break;
+
+ case 0x41 :
+ width = lodlarge;
+ height = lodlarge / 4;
+ break;
+
+ case 0x21 :
+ width = lodlarge;
+ height = lodlarge / 2;
+ break;
+
+ case 0x11 :
+ width = lodlarge;
+ height = lodlarge;
+ break;
+
+ case 0x12 :
+ width = lodlarge / 2;
+ height = lodlarge;
+ break;
+
+ case 0x14 :
+ width = lodlarge / 4;
+ height = lodlarge;
+ break;
+
+ case 0x18 :
+ width = lodlarge / 8;
+ height = lodlarge;
+ break;
+
+ default :
+ break;
+ }
+ }
+ }
+
+ } else if ( ( namelen > 4 ) && ( strcmp( texfilename + namelen - 4, ".tga" ) == 0 ) ) {
+
+ // try to get width/height from .tga header
+
+ FILE *fp = fopen( texfilename, "rb" );
+ if ( fp != NULL ) {
+
+ tga_header_s header;
+
+ // read header
+ if ( fread( &header, 1, sizeof( tga_header_s ), fp ) == sizeof( tga_header_s ) ) {
+
+ width = ( header.WidthHi << 8 ) | header.WidthLo;
+ height = ( header.HeightHi << 8 ) | header.HeightLo;
+ }
+
+ fclose( fp );
+ }
+
+ } else if ( ( namelen > 4 ) && ( strcmp( texfilename + namelen - 4, ".jpg" ) == 0 ) ) {
+
+#ifdef USE_JPEG_LIBRARY
+
+ struct jpeg_decompress_struct cinfo;
+ struct jpeg_error_mgr jerr;
+
+ FILE *fp = fopen( texfilename, "rb" );
+ if ( fp != NULL ) {
+
+ // specify error handler
+ cinfo.err = jpeg_std_error( &jerr );
+
+ // init decompressor
+ jpeg_create_decompress( &cinfo );
+
+ // specify the source for the compressed data
+ jpeg_stdio_src( &cinfo, fp );
+
+ // read jpeg header
+ jpeg_read_header( &cinfo, TRUE );
+
+ // de-init decompressor
+ jpeg_destroy_decompress( &cinfo );
+
+ fclose( fp );
+
+ width = cinfo.image_width;
+ height = cinfo.image_height;
+ }
+#else
+
+ fflush( stdout );
+ fprintf( stderr, "\nJPEG files are not supported by this version of makeodt.\n" );
+ fprintf( stderr, "If you need JPEG support, you can enable -DUSE_JPEG_LIBRARY\n" );
+ fprintf( stderr, "in the BspLib Makefile and recompile BspLib and makeodt.\n" );
+ fprintf( stderr, "This will require a working version of libjpeg 6.x\n" );
+ fprintf( stderr, "to be installed on your system.\n\n" );
+
+ exit( EXIT_FAILURE );
+#endif
+
+ }
+
+ Texture temptex( width, height );
+ temptex.setName( texfilename );
+ temptex.setFile( texfilename );
+ texlist.AddElement( temptex );
+
+ return &texlist[ texlist.getNumElements() - 1 ];
+}
+
+
+// retrieve material corresponding to specified index -------------------------
+//
+int BRep::FetchMaterialState( Material& mat, int indx )
+{
+ QvElement *elt = m_state->getTopElement( QvState::MaterialIndex );
+
+ if ( elt == NULL )
+ return 0;
+
+ // fetch material node
+ QvMaterial *m = (QvMaterial *) elt->data;
+
+ // determine period for binding
+ int ambnum = m->ambientColor.num;
+ int difnum = m->diffuseColor.num;
+ int spcnum = m->specularColor.num;
+ int eminum = m->emissiveColor.num;
+ int shinum = m->shininess.num;
+ int tranum = m->transparency.num;
+ int period = ambnum;
+ if ( difnum > period ) period = difnum;
+ if ( spcnum > period ) period = spcnum;
+ if ( eminum > period ) period = eminum;
+ if ( shinum > period ) period = shinum;
+ if ( tranum > period ) period = tranum;
+
+ ColorRGBA col;
+ col.A = 255;
+
+ int modindx = indx % period;
+ int readindx = ( modindx < ambnum ) ? modindx : ambnum - 1;
+ col.R = (byte)( m->ambientColor.values[ readindx * 3 + 0 ] * 255 );
+ col.G = (byte)( m->ambientColor.values[ readindx * 3 + 1 ] * 255 );
+ col.B = (byte)( m->ambientColor.values[ readindx * 3 + 2 ] * 255 );
+ mat.setAmbientColor( col );
+
+ readindx = ( modindx < difnum ) ? modindx : difnum - 1;
+ col.R = (byte)( m->diffuseColor.values[ readindx * 3 + 0 ] * 255 );
+ col.G = (byte)( m->diffuseColor.values[ readindx * 3 + 1 ] * 255 );
+ col.B = (byte)( m->diffuseColor.values[ readindx * 3 + 2 ] * 255 );
+ mat.setDiffuseColor( col );
+
+ readindx = ( modindx < spcnum ) ? modindx : spcnum - 1;
+ col.R = (byte)( m->specularColor.values[ readindx * 3 + 0 ] * 255 );
+ col.G = (byte)( m->specularColor.values[ readindx * 3 + 1 ] * 255 );
+ col.B = (byte)( m->specularColor.values[ readindx * 3 + 2 ] * 255 );
+ mat.setSpecularColor( col );
+
+ readindx = ( modindx < eminum ) ? modindx : eminum - 1;
+ col.R = (byte)( m->emissiveColor.values[ readindx * 3 + 0 ] * 255 );
+ col.G = (byte)( m->emissiveColor.values[ readindx * 3 + 1 ] * 255 );
+ col.B = (byte)( m->emissiveColor.values[ readindx * 3 + 2 ] * 255 );
+ mat.setEmissiveColor( col );
+
+ readindx = ( modindx < shinum ) ? modindx : shinum - 1;
+ mat.setShininess( m->shininess.values[ readindx ] );
+
+ readindx = ( modindx < tranum ) ? modindx : tranum - 1;
+ mat.setTransparency( m->transparency.values[ readindx ] );
+
+ return 1;
+}
+
+
+// fetch material binding -----------------------------------------------------
+//
+void BRep::FetchMaterialBindingState( int& binding )
+{
+ binding = QvMaterialBinding::DEFAULT;
+ QvElement *elt = m_state->getTopElement( QvState::MaterialBindingIndex );
+ if ( elt != NULL ) {
+ QvMaterialBinding *mb = (QvMaterialBinding *) elt->data;
+ binding = mb->value.value;
+ }
+}
+
+
+// fetch normal binding -------------------------------------------------------
+//
+void BRep::FetchNormalBindingState( int& binding )
+{
+ binding = QvMaterialBinding::DEFAULT;
+ QvElement *elt = m_state->getTopElement( QvState::NormalBindingIndex );
+ if ( elt != NULL ) {
+ QvNormalBinding *mb = (QvNormalBinding *) elt->data;
+ binding = mb->value.value;
+ }
+}
+
+
+// fetch shape hints information into static members --------------------------
+//
+void BRep::FetchShapeHintsState()
+{
+ QvElement *elt = m_state->getTopElement( QvState::ShapeHintsIndex );
+ if ( elt != NULL ) {
+ QvShapeHints *sh = (QvShapeHints *) elt->data;
+ shapehint_vertexOrdering = sh->vertexOrdering.value;
+ shapehint_shapeType = sh->shapeType.value;
+ shapehint_faceType = sh->faceType.value;
+ shapehint_creaseAngle = sh->creaseAngle.value;
+ }
+}
+
+
+// do b-rep construction post-processing --------------------------------------
+//
+void BRep::PostProcessObject()
+{
+ VertexChunk& vtxlist = m_baseobject->getVertexList();
+
+ int numvtxs = vtxlist.getNumElements();
+ if ( numvtxs > 0 ) {
+
+ // apply transformation matrix
+ // otherwise bounding box will not be correct!
+ m_baseobject->ApplyTransformation();
+
+ // determine object bounding box
+ Vertex3 minvertex;
+ Vertex3 maxvertex;
+ m_baseobject->CalcBoundingBox( minvertex, maxvertex );
+
+ // prepend bounding box to list of scene object bounding boxes
+ m_state->vrmlfile_base->m_bboxlist = new BoundingBox( minvertex, maxvertex, m_state->vrmlfile_base->m_bboxlist );
+
+ // set actual vertex correspondences (needs to be done after transformation!)
+ FaceChunk& facelist = m_baseobject->getFaceList();
+ for ( int i = 0; i < facelist.getNumElements(); i++ ) {
+ if ( facelist[ i ].FaceTexMapped() ) {
+ // retrieve fake vertex containing corresponding vertex indexes
+ Vertex2 fake;
+ fake = facelist[ i ].MapXY( 0 );
+ // use vertex indexes to store actual correspondence coordinates
+ facelist[ i ].MapXY( 0 ).InitFromVertex3( vtxlist[ (int) fake.getX() ] );
+ facelist[ i ].MapXY( 1 ).InitFromVertex3( vtxlist[ (int) fake.getY() ] );
+ facelist[ i ].MapXY( 2 ).InitFromVertex3( vtxlist[ (int) fake.getW() ] );
+ }
+ }
+ }
+
+ m_baseobject->CheckParsedData();
+}
+
+
+// construct b-rep from vrml sphere primitive ---------------------------------
+//
+void BRep::BuildFromSpherePrimitive( const QvSphere& node )
+{
+ // base object
+ VertexChunk& vtxlist = m_baseobject->getVertexList();
+ FaceChunk& facelist = m_baseobject->getFaceList();
+ PolygonList& polylist = m_baseobject->getPolygonList();
+
+ // set possible transformation as object's local transformation
+ Transform3 trafo;
+ FetchTransformationState( trafo );
+ m_baseobject->setObjectTransformation( trafo );
+
+ int slices4 = tessellation_slices;
+
+ double radius = node.radius.value;
+
+ double phi = 0.0;
+ double phiinc = 1.570796327 / (double) slices4; // PI/2
+
+ // create circumference vertices
+ Vector3 basevec( radius, 0.0, 0.0 );
+ Vector3 scancircle( basevec );
+ int i = 0;
+ for ( i = 0; i < slices4; i++ ) {
+ vtxlist.AddVertex( scancircle );
+ phi += phiinc;
+ double cosphi = cos( phi );
+ double sinphi = sin( phi );
+ double nextx = cosphi * basevec.getX() + sinphi * basevec.getZ();
+ double nextz = sinphi * basevec.getX() + cosphi * basevec.getZ();
+ scancircle.setX( nextx );
+ scancircle.setZ( -nextz );
+ }
+ for ( i = 0; i < slices4; i++ ) {
+ Vertex3 nv;
+ nv.setX( vtxlist[ i ].getZ() );
+ nv.setY( vtxlist[ i ].getY() );
+ nv.setZ( -vtxlist[ i ].getX() );
+ vtxlist.AddVertex( nv );
+ }
+ for ( i = 0; i < slices4; i++ ) {
+ Vertex3 nv;
+ nv.setX( -vtxlist[ i ].getX() );
+ nv.setY( vtxlist[ i ].getY() );
+ nv.setZ( -vtxlist[ i ].getZ() );
+ vtxlist.AddVertex( nv );
+ }
+ for ( i = 0; i < slices4; i++ ) {
+ Vertex3 nv;
+ nv.setX( -vtxlist[ i ].getZ() );
+ nv.setY( vtxlist[ i ].getY() );
+ nv.setZ( vtxlist[ i ].getX() );
+ vtxlist.AddVertex( nv );
+ }
+
+ // create northern hemisphere
+ basevec = Vector3( radius, 0.0, 0.0 );
+ phi = 0.0;
+ for ( i = 1; i < slices4; i++ ) {
+ phi += phiinc;
+ double cosphi = cos( phi );
+ double sinphi = sin( phi );
+ double nextx = cosphi * basevec.getX() - sinphi * basevec.getY();
+ double nexty = sinphi * basevec.getX() + cosphi * basevec.getY();
+ double rfac = nextx / radius;
+ for ( int j = 0; j < slices4 * 4; j++ ) {
+ Vertex3 nv;
+ nv.setX( vtxlist[ j ].getX() * rfac );
+ nv.setY( nexty );
+ nv.setZ( vtxlist[ j ].getZ() * rfac );
+ vtxlist.AddVertex( nv );
+ }
+ }
+
+ // create southern hemisphere
+ basevec = Vector3( radius, 0.0, 0.0 );
+ phi = 0.0;
+ for ( i = 1; i < slices4; i++ ) {
+ phi += phiinc;
+ double cosphi = cos( phi );
+ double sinphi = sin( phi );
+ double nextx = cosphi * basevec.getX() - sinphi * basevec.getY();
+ double nexty = sinphi * basevec.getX() + cosphi * basevec.getY();
+ double rfac = nextx / radius;
+ for ( int j = 0; j < slices4 * 4; j++ ) {
+ Vertex3 nv;
+ nv.setX( vtxlist[ j ].getX() * rfac );
+ nv.setY( -nexty );
+ nv.setZ( vtxlist[ j ].getZ() * rfac );
+ vtxlist.AddVertex( nv );
+ }
+ }
+
+ // create pole vertices
+ int p1indx = vtxlist.AddVertex( Vertex3( 0.0, radius, 0.0 ) );
+ int p2indx = vtxlist.AddVertex( Vertex3( 0.0, -radius, 0.0 ) );
+
+ // create polygons for side
+ int faceid = 0;
+ int j = 0;
+ for ( j = 0; j < slices4 - 1; j++ ) {
+ for ( i = 0; i < slices4 * 4 - 1; i++ ) {
+ // create side polygon
+ Polygon *sidepoly = polylist.NewPolygon();
+ sidepoly->setFaceId( faceid++ );
+ sidepoly->AppendNewVIndx( i + j * slices4 * 4 );
+ sidepoly->AppendNewVIndx( i + ( j + 1 ) * slices4 * 4 );
+ sidepoly->AppendNewVIndx( i + ( j + 1 ) * slices4 * 4 + 1 );
+ sidepoly = polylist.NewPolygon();
+ sidepoly->setFaceId( faceid++ );
+ sidepoly->AppendNewVIndx( i + ( j + 1 ) * slices4 * 4 + 1 );
+ sidepoly->AppendNewVIndx( i + j * slices4 * 4 + 1 );
+ sidepoly->AppendNewVIndx( i + j * slices4 * 4 );
+ }
+
+ // create last side polygon
+ Polygon *sidepoly = polylist.NewPolygon();
+ sidepoly->setFaceId( faceid++ );
+ sidepoly->AppendNewVIndx( slices4 * 4 - 1 + j * slices4 * 4 );
+ sidepoly->AppendNewVIndx( slices4 * 4 - 1 + ( j + 1 ) * slices4 * 4 );
+ sidepoly->AppendNewVIndx( ( j + 1 ) * slices4 * 4 );
+ sidepoly = polylist.NewPolygon();
+ sidepoly->setFaceId( faceid++ );
+ sidepoly->AppendNewVIndx( ( j + 1 ) * slices4 * 4 );
+ sidepoly->AppendNewVIndx( j * slices4 * 4 );
+ sidepoly->AppendNewVIndx( slices4 * 4 - 1 + j * slices4 * 4 );
+ }
+
+ for ( i = 0; i < slices4 * 4 - 1; i++ ) {
+ // create side polygon
+ Polygon *sidepoly = polylist.NewPolygon();
+ sidepoly->setFaceId( faceid++ );
+ sidepoly->AppendNewVIndx( i );
+ sidepoly->AppendNewVIndx( i + 1 );
+ sidepoly->AppendNewVIndx( i + slices4 * slices4 * 4 + 1 );
+ sidepoly = polylist.NewPolygon();
+ sidepoly->setFaceId( faceid++ );
+ sidepoly->AppendNewVIndx( i + slices4 * slices4 * 4 + 1 );
+ sidepoly->AppendNewVIndx( i + slices4 * slices4 * 4 );
+ sidepoly->AppendNewVIndx( i );
+ }
+
+ // create last side polygon
+ Polygon *sidepoly = polylist.NewPolygon();
+ sidepoly->setFaceId( faceid++ );
+ sidepoly->AppendNewVIndx( slices4 * 4 - 1 );
+ sidepoly->AppendNewVIndx( 0 );
+ sidepoly->AppendNewVIndx( slices4 * slices4 * 4 );
+ sidepoly = polylist.NewPolygon();
+ sidepoly->setFaceId( faceid++ );
+ sidepoly->AppendNewVIndx( slices4 * slices4 * 4 );
+ sidepoly->AppendNewVIndx( slices4 * 4 - 1 + slices4 * slices4 * 4 );
+ sidepoly->AppendNewVIndx( slices4 * 4 - 1 );
+
+
+ for ( j = slices4; j < 2 * slices4 - 2; j++ ) {
+ for ( i = 0; i < slices4 * 4 - 1; i++ ) {
+ // create side polygon
+ Polygon *sidepoly = polylist.NewPolygon();
+ sidepoly->setFaceId( faceid++ );
+ sidepoly->AppendNewVIndx( i + j * slices4 * 4 );
+ sidepoly->AppendNewVIndx( i + j * slices4 * 4 + 1 );
+ sidepoly->AppendNewVIndx( i + ( j + 1 ) * slices4 * 4 + 1 );
+ sidepoly = polylist.NewPolygon();
+ sidepoly->setFaceId( faceid++ );
+ sidepoly->AppendNewVIndx( i + ( j + 1 ) * slices4 * 4 + 1 );
+ sidepoly->AppendNewVIndx( i + ( j + 1 ) * slices4 * 4 );
+ sidepoly->AppendNewVIndx( i + j * slices4 * 4 );
+ }
+
+ // create last side polygon
+ Polygon *sidepoly = polylist.NewPolygon();
+ sidepoly->setFaceId( faceid++ );
+ sidepoly->AppendNewVIndx( slices4 * 4 - 1 + j * slices4 * 4 );
+ sidepoly->AppendNewVIndx( j * slices4 * 4 );
+ sidepoly->AppendNewVIndx( ( j + 1 ) * slices4 * 4 );
+ sidepoly = polylist.NewPolygon();
+ sidepoly->setFaceId( faceid++ );
+ sidepoly->AppendNewVIndx( ( j + 1 ) * slices4 * 4 );
+ sidepoly->AppendNewVIndx( slices4 * 4 - 1 + ( j + 1 ) * slices4 * 4 );
+ sidepoly->AppendNewVIndx( slices4 * 4 - 1 + j * slices4 * 4 );
+ }
+
+ // create polygons for poles
+ for ( i = 0; i < slices4 * 4 - 1; i++ ) {
+ Polygon *sidepoly = polylist.NewPolygon();
+ sidepoly->setFaceId( faceid++ );
+ sidepoly->AppendNewVIndx( i + ( slices4 - 1 ) * slices4 * 4 + 1 );
+ sidepoly->AppendNewVIndx( i + ( slices4 - 1 ) * slices4 * 4 );
+ sidepoly->AppendNewVIndx( p1indx );
+ }
+ {
+ Polygon *sidepoly = polylist.NewPolygon();
+ sidepoly->setFaceId( faceid++ );
+ sidepoly->AppendNewVIndx( ( slices4 - 1 ) * slices4 * 4 );
+ sidepoly->AppendNewVIndx( slices4 * 4 - 1 + ( slices4 - 1 ) * slices4 * 4 );
+ sidepoly->AppendNewVIndx( p1indx );
+ }
+ for ( i = 0; i < slices4 * 4 - 1; i++ ) {
+ Polygon *sidepoly = polylist.NewPolygon();
+ sidepoly->setFaceId( faceid++ );
+ sidepoly->AppendNewVIndx( i + ( 2 * slices4 - 2 ) * slices4 * 4 );
+ sidepoly->AppendNewVIndx( i + ( 2 * slices4 - 2 ) * slices4 * 4 + 1 );
+ sidepoly->AppendNewVIndx( p2indx );
+ }
+ {
+ Polygon *sidepoly = polylist.NewPolygon();
+ sidepoly->setFaceId( faceid++ );
+ sidepoly->AppendNewVIndx( slices4 * 4 - 1 + ( 2 * slices4 - 2 ) * slices4 * 4 );
+ sidepoly->AppendNewVIndx( ( 2 * slices4 - 2 ) * slices4 * 4 );
+ sidepoly->AppendNewVIndx( p2indx );
+ }
+
+ // the sphere primitive ignores the current material binding!
+ // therefore fetch only the first material
+ Material mat;
+ int matvalid = FetchMaterialState( mat, 0 );
+
+ // create faces
+ for ( i = 0; i < polylist.getNumElements(); i++ ) {
+ Face tempface;
+ if ( matvalid ) {
+ if ( use_material_spec ) {
+ // attach material specification
+ tempface.setShadingType( Face::material_shad );
+ tempface.AttachMaterial( new Material( mat ) );
+ } else {
+ // use gouraud_shad with diffuse color
+ tempface.setShadingType( Face::gouraud_shad );
+ tempface.setFaceColor( mat.getDiffuseColor() );
+ }
+ } else {
+ // use no_shad with index 255 if no material in state
+ tempface.setShadingType( Face::no_shad );
+ tempface.setFaceColor( 255 );
+ }
+
+ tempface.setId( facelist.getNumElements() );
+ facelist.AddElement( tempface );
+ }
+
+ // do post-processing after object has been built
+ PostProcessObject();
+}
+
+
+// construct b-rep from vrml cone primitive -----------------------------------
+//
+void BRep::BuildFromConePrimitive( const QvCone& node )
+{
+ // base object
+ VertexChunk& vtxlist = m_baseobject->getVertexList();
+ FaceChunk& facelist = m_baseobject->getFaceList();
+ PolygonList& polylist = m_baseobject->getPolygonList();
+
+ // set possible transformation as object's local transformation
+ Transform3 trafo;
+ FetchTransformationState( trafo );
+ m_baseobject->setObjectTransformation( trafo );
+
+ int slices4 = tessellation_slices;
+
+ double radius = node.bottomRadius.value;
+ double top_y = node.height.value / 2;
+ double bottom_y = - node.height.value / 2;
+
+ double phi = 0.0;
+ double phiinc = 1.570796327 / (double) slices4; // PI/2
+
+ // create bottom plate vertices
+ Vector3 basevec( radius, bottom_y, 0.0 );
+ Vector3 scancircle( basevec );
+ vtxlist.AddVertex( Vertex3( 0.0, bottom_y, 0.0 ) );
+ int i = 0;
+ for ( i = 0; i < slices4; i++ ) {
+ vtxlist.AddVertex( scancircle );
+ phi += phiinc;
+ double cosphi = cos( phi );
+ double sinphi = sin( phi );
+ double nextx = cosphi * basevec.getX() + sinphi * basevec.getZ();
+ double nextz = sinphi * basevec.getX() + cosphi * basevec.getZ();
+ scancircle.setX( nextx );
+ scancircle.setZ( -nextz );
+ }
+ for ( i = 0; i < slices4; i++ ) {
+ Vertex3 nv;
+ nv.setX( vtxlist[ i + 1 ].getZ() );
+ nv.setY( vtxlist[ i + 1 ].getY() );
+ nv.setZ( -vtxlist[ i + 1 ].getX() );
+ vtxlist.AddVertex( nv );
+ }
+ for ( i = 0; i < slices4; i++ ) {
+ Vertex3 nv;
+ nv.setX( -vtxlist[ i + 1 ].getX() );
+ nv.setY( vtxlist[ i + 1 ].getY() );
+ nv.setZ( -vtxlist[ i + 1 ].getZ() );
+ vtxlist.AddVertex( nv );
+ }
+ for ( i = 0; i < slices4; i++ ) {
+ Vertex3 nv;
+ nv.setX( -vtxlist[ i + 1 ].getZ() );
+ nv.setY( vtxlist[ i + 1 ].getY() );
+ nv.setZ( vtxlist[ i + 1 ].getX() );
+ vtxlist.AddVertex( nv );
+ }
+
+ // create top vertex
+ vtxlist.AddVertex( Vertex3( 0.0, top_y, 0.0 ) );
+
+ // create polygons
+ for ( i = 0; i < slices4 * 4 - 1; i++ ) {
+ // create bottom plate polygon
+ Polygon *bottompoly = polylist.NewPolygon();
+ bottompoly->setFaceId( 0 );
+ bottompoly->AppendNewVIndx( i + 1 );
+ bottompoly->AppendNewVIndx( i + 2 );
+ bottompoly->AppendNewVIndx( 0 );
+ // create side polygon
+ Polygon *sidepoly = polylist.NewPolygon();
+ sidepoly->setFaceId( i + 1 );
+ sidepoly->AppendNewVIndx( i + 1 );
+ sidepoly->AppendNewVIndx( slices4 * 4 + 1 );
+ sidepoly->AppendNewVIndx( i + 2 );
+ }
+
+ {
+ // create last bottom plate polygon
+ Polygon *bottompoly = polylist.NewPolygon();
+ bottompoly->setFaceId( 0 );
+ bottompoly->AppendNewVIndx( slices4 * 4 );
+ bottompoly->AppendNewVIndx( 1 );
+ bottompoly->AppendNewVIndx( 0 );
+ // create last side polygon
+ Polygon *sidepoly = polylist.NewPolygon();
+ sidepoly->setFaceId( slices4 * 4 );
+ sidepoly->AppendNewVIndx( slices4 * 4 );
+ sidepoly->AppendNewVIndx( slices4 * 4 + 1 );
+ sidepoly->AppendNewVIndx( 1 );
+ }
+
+ // fetch the first two materials
+ Material mat1, mat2;
+ int mat1valid = FetchMaterialState( mat1, 0 );
+ int mat2valid = FetchMaterialState( mat2, 1 );
+
+ // fetch the current material binding
+ int currentbinding;
+ FetchMaterialBindingState( currentbinding );
+
+ // apply material binding
+ if ( currentbinding != QvMaterialBinding::PER_PART &&
+ currentbinding != QvMaterialBinding::PER_PART_INDEXED ) {
+ mat2 = mat1;
+ mat2valid = mat1valid;
+ }
+
+ // create faces
+ for ( i = 0; i < slices4 * 4 + 1; i++ ) {
+
+ //NOTE:
+ // there are ( slices4 * 4 + 1 ) faces.
+ // the bottom plate is a single face although it consists
+ // of ( slices4 * 4 ) polygons.
+
+ Face tempface;
+ if ( mat1valid && mat2valid ) {
+ if ( use_material_spec ) {
+ // attach material specification
+ tempface.setShadingType( Face::material_shad );
+ if ( i == 0 )
+ tempface.AttachMaterial( new Material( mat2 ) );
+ else
+ tempface.AttachMaterial( new Material( mat1 ) );
+ } else {
+ // use gouraud_shad with diffuse color
+ tempface.setShadingType( Face::gouraud_shad );
+ if ( i == 0 )
+ tempface.setFaceColor( mat2.getDiffuseColor() );
+ else
+ tempface.setFaceColor( mat1.getDiffuseColor() );
+ }
+ } else {
+ // use no_shad with index 255 if no material in state
+ tempface.setShadingType( Face::no_shad );
+ tempface.setFaceColor( 255 );
+ }
+
+ tempface.setId( facelist.getNumElements() );
+ facelist.AddElement( tempface );
+ }
+
+ // do post-processing after object has been built
+ PostProcessObject();
+}
+
+
+// construct b-rep from vrml cylinder primitive -------------------------------
+//
+void BRep::BuildFromCylinderPrimitive( const QvCylinder& node )
+{
+ // base object
+ VertexChunk& vtxlist = m_baseobject->getVertexList();
+ FaceChunk& facelist = m_baseobject->getFaceList();
+ PolygonList& polylist = m_baseobject->getPolygonList();
+
+ // set possible transformation as object's local transformation
+ Transform3 trafo;
+ FetchTransformationState( trafo );
+ m_baseobject->setObjectTransformation( trafo );
+
+ int slices4 = tessellation_slices;
+
+ double radius = node.radius.value;
+ double top_y = node.height.value / 2;
+ double bottom_y = - node.height.value / 2;
+
+ double phi = 0.0;
+ double phiinc = 1.570796327 / (double) slices4; // PI/2
+
+ // create bottom plate vertices
+ Vector3 basevec( radius, bottom_y, 0.0 );
+ Vector3 scancircle( basevec );
+ vtxlist.AddVertex( Vertex3( 0.0, bottom_y, 0.0 ) );
+ int i = 0;
+ for ( i = 0; i < slices4; i++ ) {
+ vtxlist.AddVertex( scancircle );
+ phi += phiinc;
+ double cosphi = cos( phi );
+ double sinphi = sin( phi );
+ double nextx = cosphi * basevec.getX() + sinphi * basevec.getZ();
+ double nextz = sinphi * basevec.getX() + cosphi * basevec.getZ();
+ scancircle.setX( nextx );
+ scancircle.setZ( -nextz );
+ }
+ for ( i = 0; i < slices4; i++ ) {
+ Vertex3 nv;
+ nv.setX( vtxlist[ i + 1 ].getZ() );
+ nv.setY( vtxlist[ i + 1 ].getY() );
+ nv.setZ( -vtxlist[ i + 1 ].getX() );
+ vtxlist.AddVertex( nv );
+ }
+ for ( i = 0; i < slices4; i++ ) {
+ Vertex3 nv;
+ nv.setX( -vtxlist[ i + 1 ].getX() );
+ nv.setY( vtxlist[ i + 1 ].getY() );
+ nv.setZ( -vtxlist[ i + 1 ].getZ() );
+ vtxlist.AddVertex( nv );
+ }
+ for ( i = 0; i < slices4; i++ ) {
+ Vertex3 nv;
+ nv.setX( -vtxlist[ i + 1 ].getZ() );
+ nv.setY( vtxlist[ i + 1 ].getY() );
+ nv.setZ( vtxlist[ i + 1 ].getX() );
+ vtxlist.AddVertex( nv );
+ }
+
+ // create top plate vertices
+ vtxlist.AddVertex( Vertex3( 0.0, top_y, 0.0 ) );
+ for ( i = 0; i < slices4 * 4; i++ ) {
+ Vertex3 nv( vtxlist[ i + 1 ] );
+ nv.setY( top_y );
+ vtxlist.AddVertex( nv );
+ }
+
+ // create polygons
+ for ( i = 0; i < slices4 * 4 - 1; i++ ) {
+ // create bottom plate polygon
+ Polygon *bottompoly = polylist.NewPolygon();
+ bottompoly->setFaceId( 0 );
+ bottompoly->AppendNewVIndx( i + 1 );
+ bottompoly->AppendNewVIndx( i + 2 );
+ bottompoly->AppendNewVIndx( 0 );
+ // create top plate polygon
+ Polygon *toppoly = polylist.NewPolygon();
+ toppoly->setFaceId( 1 );
+ toppoly->AppendNewVIndx( i + slices4 * 4 + 3 );
+ toppoly->AppendNewVIndx( i + slices4 * 4 + 2 );
+ toppoly->AppendNewVIndx( slices4 * 4 + 1 );
+ // create side polygon
+ Polygon *sidepoly = polylist.NewPolygon();
+ sidepoly->setFaceId( i + 2 );
+ sidepoly->AppendNewVIndx( i + 1 );
+ sidepoly->AppendNewVIndx( i + slices4 * 4 + 2 );
+ sidepoly->AppendNewVIndx( i + slices4 * 4 + 3 );
+ sidepoly->AppendNewVIndx( i + 2 );
+ }
+
+ {
+ // create last bottom plate polygon
+ Polygon *bottompoly = polylist.NewPolygon();
+ bottompoly->setFaceId( 0 );
+ bottompoly->AppendNewVIndx( slices4 * 4 );
+ bottompoly->AppendNewVIndx( 1 );
+ bottompoly->AppendNewVIndx( 0 );
+ // create last top plate polygon
+ Polygon *toppoly = polylist.NewPolygon();
+ toppoly->setFaceId( 1 );
+ toppoly->AppendNewVIndx( slices4 * 4 + 2 );
+ toppoly->AppendNewVIndx( 2 * slices4 * 4 + 1 );
+ toppoly->AppendNewVIndx( slices4 * 4 + 1 );
+ // create last side polygon
+ Polygon *sidepoly = polylist.NewPolygon();
+ sidepoly->setFaceId( slices4 * 4 + 1 );
+ sidepoly->AppendNewVIndx( slices4 * 4 );
+ sidepoly->AppendNewVIndx( 2 * slices4 * 4 + 1 );
+ sidepoly->AppendNewVIndx( slices4 * 4 + 2 );
+ sidepoly->AppendNewVIndx( 1 );
+ }
+
+ // fetch the first three materials
+ Material mat1, mat2, mat3;
+ int mat1valid = FetchMaterialState( mat1, 0 );
+ int mat2valid = FetchMaterialState( mat2, 1 );
+ int mat3valid = FetchMaterialState( mat3, 2 );
+
+ // fetch the current material binding
+ int currentbinding;
+ FetchMaterialBindingState( currentbinding );
+
+ // apply material binding
+ if ( currentbinding != QvMaterialBinding::PER_PART &&
+ currentbinding != QvMaterialBinding::PER_PART_INDEXED ) {
+ mat2 = mat1;
+ mat3 = mat1;
+ mat2valid = mat1valid;
+ mat3valid = mat1valid;
+ }
+
+ // create faces
+ for ( i = 0; i < slices4 * 4 + 2; i++ ) {
+ Face tempface;
+
+ //NOTE:
+ // there are ( slices4 * 4 + 2 ) faces.
+ // the bottom and top plates are each a single face although
+ // they each consist of ( slices4 * 4 ) polygons.
+
+ if ( mat1valid && mat2valid && mat3valid ) {
+ if ( use_material_spec ) {
+ // attach material specification
+ tempface.setShadingType( Face::material_shad );
+ if ( i == 0 )
+ tempface.AttachMaterial( new Material( mat3 ) );
+ else if ( i == 1 )
+ tempface.AttachMaterial( new Material( mat2 ) );
+ else
+ tempface.AttachMaterial( new Material( mat1 ) );
+ } else {
+ // use gouraud_shad with diffuse color
+ tempface.setShadingType( Face::gouraud_shad );
+ if ( i == 0 )
+ tempface.setFaceColor( mat3.getDiffuseColor() );
+ else if ( i == 1 )
+ tempface.setFaceColor( mat2.getDiffuseColor() );
+ else
+ tempface.setFaceColor( mat1.getDiffuseColor() );
+ }
+ } else {
+ // use no_shad with index 255 if no material in state
+ tempface.setShadingType( Face::no_shad );
+ tempface.setFaceColor( 255 );
+ }
+
+ tempface.setId( facelist.getNumElements() );
+ facelist.AddElement( tempface );
+ }
+
+ // do post-processing after object has been built
+ PostProcessObject();
+}
+
+
+// construct b-rep from vrml cube primitive -----------------------------------
+//
+void BRep::BuildFromCubePrimitive( const QvCube& node )
+{
+ // base object
+ VertexChunk& vtxlist = m_baseobject->getVertexList();
+ FaceChunk& facelist = m_baseobject->getFaceList();
+ PolygonList& polylist = m_baseobject->getPolygonList();
+
+ // set possible transformation as object's local transformation
+ Transform3 trafo;
+ FetchTransformationState( trafo );
+ m_baseobject->setObjectTransformation( trafo );
+
+ double max_x = node.width.value / 2;
+ double max_y = node.height.value / 2;
+ double max_z = node.depth.value / 2;
+
+ vtxlist.AddVertex( Vertex3( -max_x, max_y, max_z ) );
+ vtxlist.AddVertex( Vertex3( max_x, max_y, max_z ) );
+ vtxlist.AddVertex( Vertex3( max_x, -max_y, max_z ) );
+ vtxlist.AddVertex( Vertex3( -max_x, -max_y, max_z ) );
+
+ vtxlist.AddVertex( Vertex3( -max_x, max_y, -max_z ) );
+ vtxlist.AddVertex( Vertex3( -max_x, -max_y, -max_z ) );
+ vtxlist.AddVertex( Vertex3( max_x, -max_y, -max_z ) );
+ vtxlist.AddVertex( Vertex3( max_x, max_y, -max_z ) );
+
+ Polygon *sidepoly = polylist.NewPolygon();
+ sidepoly->AppendNewVIndx( 0 ); sidepoly->AppendNewVIndx( 1 ); sidepoly->AppendNewVIndx( 2 ); sidepoly->AppendNewVIndx( 3 );
+ sidepoly = polylist.NewPolygon();
+ sidepoly->AppendNewVIndx( 1 ); sidepoly->AppendNewVIndx( 7 ); sidepoly->AppendNewVIndx( 6 ); sidepoly->AppendNewVIndx( 2 );
+ sidepoly = polylist.NewPolygon();
+ sidepoly->AppendNewVIndx( 7 ); sidepoly->AppendNewVIndx( 4 ); sidepoly->AppendNewVIndx( 5 ); sidepoly->AppendNewVIndx( 6 );
+ sidepoly = polylist.NewPolygon();
+ sidepoly->AppendNewVIndx( 4 ); sidepoly->AppendNewVIndx( 0 ); sidepoly->AppendNewVIndx( 3 ); sidepoly->AppendNewVIndx( 5 );
+ sidepoly = polylist.NewPolygon();
+ sidepoly->AppendNewVIndx( 3 ); sidepoly->AppendNewVIndx( 2 ); sidepoly->AppendNewVIndx( 6 ); sidepoly->AppendNewVIndx( 5 );
+ sidepoly = polylist.NewPolygon();
+ sidepoly->AppendNewVIndx( 1 ); sidepoly->AppendNewVIndx( 0 ); sidepoly->AppendNewVIndx( 4 ); sidepoly->AppendNewVIndx( 7 );
+
+ //TODO:
+ // polygons have to be created in the order prescribed by
+ // material application!
+
+ // fetch the first six materials
+ Material mats[ 6 ];
+ int matsvalid[ 6 ];
+ int i = 0;
+ for ( i = 0; i < 6; i++ )
+ matsvalid[ i ] = FetchMaterialState( mats[ i ], 0 );
+
+ // fetch the current material binding
+ int currentbinding;
+ FetchMaterialBindingState( currentbinding );
+
+ // apply material binding
+ if ( currentbinding != QvMaterialBinding::PER_PART &&
+ currentbinding != QvMaterialBinding::PER_PART_INDEXED &&
+ currentbinding != QvMaterialBinding::PER_FACE &&
+ currentbinding != QvMaterialBinding::PER_FACE_INDEXED )
+ for ( i = 1; i < 6; i++ ) {
+ mats[ i ] = mats[ 0 ];
+ matsvalid[ i ] = matsvalid[ 0 ];
+ }
+
+ // check validity of all materials
+ int allmatsvalid = 1;
+ for ( i = 0; i < 6; i++ )
+ if ( !matsvalid[ i ] )
+ allmatsvalid = 0;
+
+ // create faces
+ for ( i = 0; i < 6; i++ ) {
+ Face tempface;
+
+ if ( allmatsvalid ) {
+ if ( use_material_spec ) {
+ // attach material specification
+ tempface.setShadingType( Face::material_shad );
+ tempface.AttachMaterial( new Material( mats[ i ] ) );
+ } else {
+ // use gouraud_shad with diffuse color
+ tempface.setShadingType( Face::gouraud_shad );
+ tempface.setFaceColor( mats[ i ].getDiffuseColor() );
+ }
+ } else {
+ // use no_shad with index 255 if no material in state
+ tempface.setShadingType( Face::no_shad );
+ tempface.setFaceColor( 255 );
+ }
+
+ tempface.setId( facelist.getNumElements() );
+ facelist.AddElement( tempface );
+ }
+
+ // do post-processing after object has been built
+ PostProcessObject();
+}
+
+
+// create single face for specification in indexed face set -------------------
+//
+void BRep::CreateIndexedFace( Texture *texture, int curindex, int numtexindexs, long *texindexs, int v1, int v2, int v3 )
+{
+ // base object
+ VertexChunk& vtxlist = m_baseobject->getVertexList();
+ FaceChunk& facelist = m_baseobject->getFaceList();
+
+ // face to be created
+ Face tempface;
+
+ // fetch material
+ Material mat;
+ int matvalid = FetchMaterialState( mat, 0 );
+
+ if ( matvalid ) {
+ if ( use_material_spec ) {
+ // attach material specification
+ tempface.setShadingType( Face::material_shad );
+ tempface.AttachMaterial( new Material( mat ) );
+ } else {
+ // use gouraud_shad with diffuse color
+ tempface.setShadingType( Face::gouraud_shad );
+ tempface.setFaceColor( mat.getDiffuseColor() );
+ }
+ } else {
+ // use no_shad with index 255 if no material in state
+ tempface.setShadingType( Face::no_shad );
+ tempface.setFaceColor( 255 );
+ }
+
+ // check if face is textured
+ if ( texture != NULL ) {
+ int coordsnum;
+ float *texcoords = FetchTextureCoordinate2State( coordsnum );
+
+ // fetch (u,v) transformation
+ Transform2 trafo;
+ FetchTextureTransformationState( trafo );
+
+ // store fake vertex containing corresponding vertex indexes
+ Vertex2 fake( v1, v2, v3 );
+ tempface.MapXY( 0 ) = fake;
+
+ int mappingvalid = 0;
+
+ int coordindx = ( curindex - 3 < numtexindexs ) ? texindexs[ curindex - 3 ] : -1;
+ if ( ( coordindx >= 0 ) && ( coordindx < coordsnum ) ) {
+ tempface.MapUV( 0 ).setX( texcoords[ coordindx * 2 + 0 ] );
+ tempface.MapUV( 0 ).setY( texcoords[ coordindx * 2 + 1 ] );
+ tempface.MapUV( 0 ).setW( 1.0 );
+ Vertex2 tv = trafo.TransformVector2( tempface.MapUV( 0 ) );
+ tv.setX( tv.getX() * texture->getWidth() );
+ double ucoord = mirror_v_axis ? ( 1.0 - tv.getY() ) : tv.getY();
+ tv.setY( ucoord * texture->getHeight() );
+ tempface.MapUV( 0 ) = tv;
+ mappingvalid++;
+ }
+
+ coordindx = ( curindex - 2 < numtexindexs ) ? texindexs[ curindex - 2 ] : -1;
+ if ( ( coordindx >= 0 ) && ( coordindx < coordsnum ) ) {
+ tempface.MapUV( 1 ).setX( texcoords[ coordindx * 2 + 0 ] );
+ tempface.MapUV( 1 ).setY( texcoords[ coordindx * 2 + 1 ] );
+ tempface.MapUV( 1 ).setW( 1.0 );
+ Vertex2 tv = trafo.TransformVector2( tempface.MapUV( 1 ) );
+ tv.setX( tv.getX() * texture->getWidth() );
+ double ucoord = mirror_v_axis ? ( 1.0 - tv.getY() ) : tv.getY();
+ tv.setY( ucoord * texture->getHeight() );
+ tempface.MapUV( 1 ) = tv;
+ mappingvalid++;
+ }
+
+ coordindx = ( curindex - 1 < numtexindexs ) ? texindexs[ curindex - 1 ] : -1;
+ if ( ( coordindx >= 0 ) && ( coordindx < coordsnum ) ) {
+ tempface.MapUV( 2 ).setX( texcoords[ coordindx * 2 + 0 ] );
+ tempface.MapUV( 2 ).setY( texcoords[ coordindx * 2 + 1 ] );
+ tempface.MapUV( 2 ).setW( 1.0 );
+ Vertex2 tv = trafo.TransformVector2( tempface.MapUV( 2 ) );
+ tv.setX( tv.getX() * texture->getWidth() );
+ double ucoord = mirror_v_axis ? ( 1.0 - tv.getY() ) : tv.getY();
+ tv.setY( ucoord * texture->getHeight() );
+ tempface.MapUV( 2 ) = tv;
+ mappingvalid++;
+ }
+
+ // only set shading type to textured if all three
+ // mapping coordinates valid
+ if ( mappingvalid == 3 ) {
+ tempface.setShadingType( Face::ipol1tex_shad );
+ tempface.setTextureName( texture->getName() );
+ }
+ }
+
+ tempface.setId( facelist.getNumElements() );
+ facelist.AddElement( tempface );
+}
+
+
+// construct b-rep from vrml indexed face set ---------------------------------
+//
+void BRep::BuildFromIndexedFaceSet( const QvIndexedFaceSet& faceset )
+{
+ // check current shape hints
+ FetchShapeHintsState();
+
+ // check for texture mapping
+ Texture *texture = CheckTexture2State();
+
+ // determine number and address of vertices in current state
+ int numvertices;
+ float *vertices = FetchCoordinate3State( numvertices );
+
+ // base object
+ VertexChunk& vtxlist = m_baseobject->getVertexList();
+ FaceChunk& facelist = m_baseobject->getFaceList();
+ PolygonList& polylist = m_baseobject->getPolygonList();
+
+ // set possible transformation as object's local transformation
+ Transform3 trafo;
+ FetchTransformationState( trafo );
+ m_baseobject->setObjectTransformation( trafo );
+
+ // create vertices (regardless of usage)
+ for ( int i = 0; i < numvertices; i++ ) {
+ double x = vertices[ i * 3 + 0 ];
+ double y = vertices[ i * 3 + 1 ];
+ double z = vertices[ i * 3 + 2 ];
+ vtxlist.AddVertex( Vertex3( x, y, z ) );
+ }
+
+ //TODO:
+ // all vertices are included in every object, regardless of usage!
+
+ // fetch the current material binding
+ int currentbinding;
+ FetchMaterialBindingState( currentbinding );
+
+ // determine number and address of vertex indexes
+ int numvtxindexs = faceset.coordIndex.num;
+ long *vtxindexs = faceset.coordIndex.values;
+
+ // determine number and address of material indexes
+ int nummatindexs = faceset.materialIndex.num;
+ long *matindexs = faceset.materialIndex.values;
+
+ // determine number and address of normal indexes
+ int numnmlindexs = faceset.normalIndex.num;
+ long *nmlindexs = faceset.normalIndex.values;
+
+ // determine number and address of texture coordinate indexes
+ int numtexindexs = faceset.textureCoordIndex.num;
+ long *texindexs = faceset.textureCoordIndex.values;
+
+ // create polygons and faces
+ int vtxsread = 0;
+ int polysread = 0; // this also counts polygons removed due to degeneracy!
+ int v1, v2, v3;
+ Plane curplane;
+ while ( numvtxindexs > 0 ) {
+
+ // prepend new polygon to list
+ Polygon *poly = polylist.NewPolygon();
+
+ // create vertexlist for this polygon
+ int vtxcount = 0;
+ while ( numvtxindexs-- > 0 ) {
+ // read next vertex index
+ int vindx = *vtxindexs++;
+ vtxsread++;
+ vtxcount++;
+ // -1 is end marker for face
+ if ( vindx == -1 )
+ break;
+ if ( vindx >= numvertices ) {
+ {
+ StrScratch message;
+ sprintf( message, "**ERROR** [Specified vertex-index invalid]: %d\n", vindx );
+ ErrorMessage( message );
+ }
+ HandleCriticalError();
+ }
+
+ if ( vtxcount == 1 ) {
+ // store first vertex index
+ v1 = vindx;
+ } else if ( vtxcount == 2 ) {
+ // store second vertex index
+ v2 = vindx;
+ } else if ( vtxcount == 3 ) {
+ // store third vertex index
+ v3 = vindx;
+ // create plane for polygon (sidedness irrelevant!)
+ curplane.InitPlane( vtxlist[ v1 ], vtxlist[ v2 ], vtxlist[ v3 ] );
+ // count original polygons (including degenerate ones!)
+ polysread++;
+ // check if plane valid
+ if ( !curplane.PlaneValid() ) {
+ // remove polygon if invalid
+ polylist.DeleteHead();
+ // skip possibly remaining vertexindexes
+ while ( ( numvtxindexs-- > 0 ) && ( *vtxindexs++ != -1 ) )
+ vtxsread++;
+ vtxindexs--;
+ numvtxindexs++;
+ continue;
+ }
+ // create face
+ CreateIndexedFace( texture, vtxsread, numtexindexs, texindexs, v1, v2, v3 );
+// } else if ( vtxcount == 4 ) {
+ } else {
+ // create new polygon and face if next point not contained in
+ // previous triangle's plane or triangulation explicitly desired
+ if ( !curplane.PointContained( vtxlist[ vindx ] ) || do_triangulation ) {
+ // add new polygon to list
+ poly = polylist.NewPolygon();
+ if ( shapehint_vertexOrdering == QvShapeHints::CLOCKWISE ) {
+ polylist.AppendNewVIndx( v1 );
+ polylist.AppendNewVIndx( v3 );
+ } else {
+ polylist.PrependNewVIndx( v1 );
+ polylist.PrependNewVIndx( v3 );
+ }
+ // create plane for polygon
+ curplane.InitPlane( vtxlist[ v1 ], vtxlist[ v3 ], vtxlist[ vindx ] );
+ // check if plane valid
+ if ( !curplane.PlaneValid() ) {
+ // remove polygon if invalid
+ polylist.DeleteHead();
+ // skip possibly remaining vertexindexes
+ while ( ( numvtxindexs-- > 0 ) && ( *vtxindexs++ != -1 ) )
+ vtxsread++;
+ vtxindexs--;
+ numvtxindexs++;
+ continue;
+ }
+ // create face
+ CreateIndexedFace( texture, vtxsread, numtexindexs, texindexs, v1, v2, v3 );
+ }
+ // advance triangle fan
+ v3 = vindx;
+ }
+
+ // insert current vertex index into polygon
+ if ( shapehint_vertexOrdering == QvShapeHints::CLOCKWISE )
+ polylist.AppendNewVIndx( vindx );
+ else
+ polylist.PrependNewVIndx( vindx );
+ }
+
+ if ( polylist.FetchHead() != NULL ) {
+
+ //NOTE:
+ // if all polygons up to now have been removed due to degeneracy,
+ // polylist might contain not a single element! therefore,
+ // getNumVertices() cannot be used!
+
+ // check if polygon is at least triangle
+ if ( polylist.getNumVertices() < 3 ) {
+ {
+ StrScratch message;
+ sprintf( message, "**ERROR** [Face must have at least 3 vertices]: %d\n",
+ polylist.getNumElements() );
+ ErrorMessage( message );
+ }
+ HandleCriticalError();
+ }
+
+ } else {
+ StrScratch message;
+ sprintf( message, "**ERROR** [Polygon is degenerate]: %d\n", polysread );
+ ErrorMessage( message );
+ }
+ }
+
+ // do post-processing after object has been built
+ PostProcessObject();
+}
+
+
+// shape hints ----------------------------------------------------------------
+//
+int BRep::shapehint_vertexOrdering = QvShapeHints::UNKNOWN_ORDERING;
+int BRep::shapehint_shapeType = QvShapeHints::UNKNOWN_SHAPE_TYPE;
+int BRep::shapehint_faceType = QvShapeHints::CONVEX;
+float BRep::shapehint_creaseAngle = 0.5f;
+
+
+// full material specification usage control ----------------------------------
+//
+int BRep::use_material_spec = FALSE;
+
+
+// flag if v axis should be mirrored for texture coordinates ------------------
+//
+int BRep::mirror_v_axis = TRUE;
+
+
+// triangulation control ------------------------------------------------------
+//
+int BRep::do_triangulation = FALSE;
+
+
+// tessellation resolution in slices per PI/2 ---------------------------------
+//
+int BRep::tessellation_slices = 4;
+
+
+BSPLIB_NAMESPACE_END
+
+//-----------------------------------------------------------------------------
diff --git a/tool_src/BspLib/BRep.h b/tool_src/BspLib/BRep.h
new file mode 100644
index 0000000..57fff2c
--- /dev/null
+++ b/tool_src/BspLib/BRep.h
@@ -0,0 +1,93 @@
+//-----------------------------------------------------------------------------
+// BSPLIB HEADER: BRep.h
+//
+// Copyright (c) 1997-1998 by Markus Hadwiger
+// All Rights Reserved.
+//-----------------------------------------------------------------------------
+
+#ifndef _BREP_H_
+#define _BREP_H_
+
+// bsplib header files
+#include "BspLibDefs.h"
+#include "BspObjectList.h"
+#include "BoundingBox.h"
+#include "SystemIO.h"
+#include "Transform2.h"
+#include "Transform3.h"
+
+// qvlib header files
+#include <QvState.h>
+#include <QvSphere.h>
+#include <QvCone.h>
+#include <QvCube.h>
+#include <QvCylinder.h>
+#include <QvIndexedFaceSet.h>
+
+
+BSPLIB_NAMESPACE_BEGIN
+
+
+// b-rep class; used by vrml tree traversal to construct objects --------------
+//
+class BRep : public virtual SystemIO {
+
+public:
+ BRep( QvState *state );
+ ~BRep() { }
+
+ void BuildFromSpherePrimitive( const QvSphere& spherenode );
+ void BuildFromConePrimitive( const QvCone& spherenode );
+ void BuildFromCubePrimitive( const QvCube& spherenode );
+ void BuildFromCylinderPrimitive( const QvCylinder& spherenode );
+ void BuildFromIndexedFaceSet( const QvIndexedFaceSet& faceset );
+
+public:
+ static int getTriangulation() { return do_triangulation; }
+ static void setTriangulation( int tri ) { do_triangulation = tri; }
+
+ static int getTessellation() { return tessellation_slices; }
+ static void setTessellation( int tes ) { tessellation_slices = tes; }
+
+ static int getMaterialFlag() { return use_material_spec; }
+ static void setMaterialFlag( int mfl ) { use_material_spec = mfl; }
+
+ static int getMirrorTextureVFlag() { return mirror_v_axis; }
+ static void setMirrorTextureVFlag( int mtv ) { mirror_v_axis = mtv; }
+
+private:
+ float* FetchCoordinate3State( int &num );
+ float* FetchTextureCoordinate2State( int &num );
+ float* FetchNormalState( int &num );
+ void FetchTransformationState( Transform3& trafo );
+ void FetchTextureTransformationState( Transform2& trafo );
+ int FetchMaterialState( Material& mat, int indx );
+ void FetchMaterialBindingState( int& binding );
+ void FetchNormalBindingState( int& binding );
+ void FetchShapeHintsState();
+ Texture* CheckTexture2State();
+ void CreateIndexedFace( Texture *texture, int curindex, int numtexindexs, long *texindexs, int v1, int v2, int v3 );
+ void PostProcessObject();
+
+private:
+ static int shapehint_vertexOrdering;
+ static int shapehint_shapeType;
+ static int shapehint_faceType;
+ static float shapehint_creaseAngle;
+
+ static int use_material_spec;
+ static int mirror_v_axis;
+ static int do_triangulation;
+ static int tessellation_slices;
+
+private:
+ QvState* m_state;
+ BspObject* m_baseobject;
+};
+
+
+BSPLIB_NAMESPACE_END
+
+
+#endif // _BREP_H_
+
diff --git a/tool_src/BspLib/BSPNode.cpp b/tool_src/BspLib/BSPNode.cpp
new file mode 100644
index 0000000..4edd283
--- /dev/null
+++ b/tool_src/BspLib/BSPNode.cpp
@@ -0,0 +1,401 @@
+//-----------------------------------------------------------------------------
+// BSPLIB MODULE: BSPNode.cpp
+//
+// Copyright (c) 1996-1998 by Markus Hadwiger
+// All Rights Reserved.
+//-----------------------------------------------------------------------------
+
+// bsplib header files
+#include "BSPNode.h"
+#include "BoundingBox.h"
+#include "BspFormat.h"
+
+
+BSPLIB_NAMESPACE_BEGIN
+
+
+// construct BSPNode ----------------------------------------------------------
+//
+BSPNode::BSPNode( BSPNode *front, BSPNode *back, Polygon *poly, Polygon *backpoly, Plane *sep, BoundingBox *box, int num )
+{
+ frontsubtree = front;
+ backsubtree = back;
+ polygon = poly;
+ backpolygon = backpoly;
+ separatorplane = sep;
+ boundingbox = box;
+ nodenumber = num;
+}
+
+
+// destroy BSPNode ------------------------------------------------------------
+//
+BSPNode::~BSPNode()
+{
+ delete polygon;
+ delete backpolygon;
+ delete separatorplane;
+ delete boundingbox;
+ delete frontsubtree;
+ delete backsubtree;
+}
+
+
+// traverse bsp tree (preorder) and number nodes as encountered ---------------
+//
+void BSPNode::NumberBSPNodes( int& curno )
+{
+ // store nodenumber
+ nodenumber = ++curno;
+
+ // assign node numbers to all polygons contained in splitter plane
+ static Polygon *polylist;
+ for ( polylist = polygon ? polygon->getNext() : NULL; polylist; polylist = polylist->getNext() ) {
+ // only increment numbering, numbers don't get stored in polygons!
+ ++curno;
+ }
+ for ( polylist = backpolygon; polylist; polylist = polylist->getNext() ) {
+ // only increment numbering, numbers don't get stored in polygons!
+ ++curno;
+ }
+
+ // do numbering recursively for front- and backsubtree
+ if ( frontsubtree ) frontsubtree->NumberBSPNodes( curno );
+ if ( backsubtree ) backsubtree->NumberBSPNodes( curno );
+}
+
+
+// sum number of vertices of all polygon in tree ------------------------------
+//
+void BSPNode::SumVertexNums( int& vtxnum )
+{
+ // sum number of vertices of polygons contained in this plane
+ static Polygon *polylist;
+ for ( polylist = polygon; polylist; polylist = polylist->getNext() )
+ vtxnum += polylist->getNumVertices();
+ for ( polylist = backpolygon; polylist; polylist = polylist->getNext() )
+ vtxnum += polylist->getNumVertices();
+
+ // do sum recursively for front- and backsubtree
+ if ( frontsubtree ) frontsubtree->SumVertexNums( vtxnum );
+ if ( backsubtree ) backsubtree->SumVertexNums( vtxnum );
+}
+
+
+// traverse entire tree and correct relative polygon info to new base values --
+//
+void BSPNode::CorrectPolygonBases( BspObject *newbaseobj, int vertexindxbase, int faceidbase, int polygonidbase )
+{
+ static Polygon *polylist;
+ for ( polylist = polygon; polylist; polylist = polylist->getNext() )
+ polylist->CorrectBase( newbaseobj, vertexindxbase, faceidbase, polygonidbase );
+ for ( polylist = backpolygon; polylist; polylist = polylist->getNext() )
+ polylist->CorrectBase( newbaseobj, vertexindxbase, faceidbase, polygonidbase );
+
+ if ( frontsubtree ) frontsubtree->CorrectPolygonBases( newbaseobj, vertexindxbase, faceidbase, polygonidbase );
+ if ( backsubtree ) backsubtree->CorrectPolygonBases( newbaseobj, vertexindxbase, faceidbase, polygonidbase );
+}
+
+
+// traverse entire tree and correct relative polygon info to new base values --
+//
+void BSPNode::CorrectPolygonBasesByTable( BspObject *newbaseobj, int *vtxindxmap, int faceidbase, int polygonidbase )
+{
+ static Polygon *polylist;
+ for ( polylist = polygon; polylist; polylist = polylist->getNext() )
+ polylist->CorrectBaseByTable( newbaseobj, vtxindxmap, faceidbase, polygonidbase );
+ for ( polylist = backpolygon; polylist; polylist = polylist->getNext() )
+ polylist->CorrectBaseByTable( newbaseobj, vtxindxmap, faceidbase, polygonidbase );
+
+ if ( frontsubtree ) frontsubtree->CorrectPolygonBasesByTable( newbaseobj, vtxindxmap, faceidbase, polygonidbase );
+ if ( backsubtree ) backsubtree->CorrectPolygonBasesByTable( newbaseobj, vtxindxmap, faceidbase, polygonidbase );
+}
+
+
+// write bsp tree structure to output file (preorder traversal) ---------------
+//
+void BSPNode::WriteBSPTree( FILE *fp )
+{
+ static int lnodnum, rnodnum, cnodnum, bnodnum;
+ static int curnodnum;
+ static Polygon *polylist;
+
+ lnodnum = frontsubtree ? frontsubtree->nodenumber : 0;
+ rnodnum = backsubtree ? backsubtree->nodenumber : 0;
+
+ if ( polygon != NULL ) {
+ cnodnum = polygon->getNext() ? nodenumber + 1 : 0;
+ bnodnum = backpolygon ? nodenumber + polygon->getNumPolygons() : 0;
+ } else {
+ cnodnum = 0;
+ bnodnum = 0;
+ }
+
+ if ( outputformat == OUTPUT_OLD_STYLE ) {
+
+ if ( polygon != NULL ) {
+ // print head node
+ fprintf( fp, "%d: %d |%d|%d|%d-%d|\n",
+ nodenumber, polygon->getId() + 1, cnodnum, bnodnum, lnodnum, rnodnum );
+
+ // print list of contained nodes (frontfacing)
+ curnodnum = cnodnum;
+ polylist = polygon;
+ while ( ( polylist = polylist->getNext() ) != NULL ) {
+ cnodnum = polylist->getNext() ? ( curnodnum + 1 ) : 0;
+ fprintf( fp, "%d: %d |%d|0|\n", curnodnum++, polylist->getId() + 1, cnodnum );
+ }
+
+ // print list of contained nodes (backfacing)
+ curnodnum = bnodnum;
+ for ( polylist = backpolygon; polylist; polylist = polylist->getNext() ) {
+ bnodnum = polylist->getNext() ? ( curnodnum + 1 ) : 0;
+ fprintf( fp, "%d: %d |0|%d|\n", curnodnum++, polylist->getId() + 1, bnodnum );
+ }
+ } else {
+ //NOTE:
+ // nodes not containing polygons are not supported
+ // by the old ouput format!
+ fprintf( fp, "no polygon contained in node %d.", nodenumber );
+ }
+
+ } else {
+
+ // print head node
+ fprintf( fp, "%d: ", nodenumber );
+ if ( polygon != NULL )
+ fprintf( fp, "%s %d ", BspFormat::_bspspec_polygon_str, polygon->getId() + 1 );
+ if ( cnodnum != 0 )
+ fprintf( fp, "%s %d ", BspFormat::_bspspec_frontlist_str, cnodnum );
+ if ( bnodnum != 0 )
+ fprintf( fp, "%s %d ", BspFormat::_bspspec_backlist_str, bnodnum );
+ if ( lnodnum != 0 )
+ fprintf( fp, "%s %d ", BspFormat::_bspspec_fronttree_str, lnodnum );
+ if ( rnodnum != 0 )
+ fprintf( fp, "%s %d ", BspFormat::_bspspec_backtree_str, rnodnum );
+ if ( separatorplane != NULL ) {
+ Vector3 normal = separatorplane->getPlaneNormal();
+ fprintf( fp, "%s %f %f %f %f ", BspFormat::_bspspec_plane_str,
+ normal.getX(), normal.getY(), normal.getZ(),
+ separatorplane->getPlaneOffset() );
+ }
+ if ( boundingbox != NULL ) {
+ Vertex3 minvert = boundingbox->getMinVertex();
+ Vertex3 maxvert = boundingbox->getMaxVertex();
+ fprintf( fp, "%s %f %f %f %f %f %f ", BspFormat::_bspspec_boundingbox_str,
+ minvert.getX(), minvert.getY(), minvert.getZ(),
+ maxvert.getX(), maxvert.getY(), maxvert.getZ() );
+ }
+ fprintf( fp, "\n" );
+
+ // print list of contained nodes (frontfacing)
+ if ( polygon != NULL ) {
+ curnodnum = cnodnum;
+ polylist = polygon;
+ while ( ( polylist = polylist->getNext() ) != NULL ) {
+ fprintf( fp, "%d: ", curnodnum );
+ cnodnum = polylist->getNext() ? ++curnodnum : 0;
+ fprintf( fp, "%s %d ", BspFormat::_bspspec_polygon_str, polylist->getId() + 1 );
+ if ( cnodnum != 0 )
+ fprintf( fp, "%s %d", BspFormat::_bspspec_frontlist_str, cnodnum );
+ fprintf( fp, "\n" );
+ }
+ }
+
+ // print list of contained nodes (backfacing)
+ curnodnum = bnodnum;
+ for ( polylist = backpolygon; polylist; polylist = polylist->getNext() ) {
+ fprintf( fp, "%d: ", curnodnum );
+ bnodnum = polylist->getNext() ? ++curnodnum : 0;
+ fprintf( fp, "%s %d ", BspFormat::_bspspec_polygon_str, polylist->getId() + 1 );
+ if ( bnodnum != 0 )
+ fprintf( fp, "%s %d", BspFormat::_bspspec_backlist_str, bnodnum );
+ fprintf( fp, "\n" );
+ }
+
+ }
+
+ // write out front- and backsubtree recursively
+ if ( frontsubtree ) frontsubtree->WriteBSPTree( fp );
+ if ( backsubtree ) backsubtree->WriteBSPTree( fp );
+}
+
+
+// fetch pointer to polygon with given number contained in bsp tree -----------
+//
+Polygon *BSPNode::FetchBSPPolygon( int polyno )
+{
+ // search local node and contained list (frontfacing)
+ static Polygon *clist;
+ for ( clist = polygon; clist; clist = clist->getNext() ) {
+ if ( clist->getId() == polyno )
+ return clist;
+ }
+
+ // search list of contained backfacing polygons
+ for ( clist = backpolygon; clist; clist = clist->getNext() ) {
+ if ( clist->getId() == polyno )
+ return clist;
+ }
+
+ Polygon *search = NULL;
+
+ if ( frontsubtree )
+ search = frontsubtree->FetchBSPPolygon( polyno );
+ if ( ( search == NULL ) && backsubtree )
+ search = backsubtree->FetchBSPPolygon( polyno );
+
+ return search;
+}
+
+
+// fetch all polygon numbers contained in specific face -----------------------
+//
+void BSPNode::FetchFacePolygons( int faceno, PolygonList& facepolylist )
+{
+ // search local node and contained list (frontfacing)
+ static Polygon *clist;
+ for ( clist = polygon; clist; clist = clist->getNext() ) {
+ if ( clist->getFaceId() == faceno )
+ facepolylist.InsertPolygon( new Polygon( NULL, clist->getId(), clist->getFaceId() ) );
+ }
+
+ // search list of contained backfacing polygons
+ for ( clist = backpolygon; clist; clist = clist->getNext() ) {
+ if ( clist->getFaceId() == faceno )
+ facepolylist.InsertPolygon( new Polygon( NULL, clist->getId(), clist->getFaceId() ) );
+ }
+
+ // check children (subtrees)
+ if ( frontsubtree ) frontsubtree->FetchFacePolygons( faceno, facepolylist );
+ if ( backsubtree ) backsubtree->FetchFacePolygons( faceno, facepolylist );
+}
+
+
+// check edges for contained vertices and insert them as trace vertices -------
+//
+void BSPNode::CheckEdges()
+{
+ // check list of frontfacing polygons
+ if ( polygon ) polygon->CheckEdges();
+
+ // check list of backfacing polygons
+ if ( backpolygon ) backpolygon->CheckEdges();
+
+ // check children (subtrees)
+ if ( frontsubtree ) frontsubtree->CheckEdges();
+ if ( backsubtree ) backsubtree->CheckEdges();
+}
+
+
+// grow this node's bounding box by another node's ----------------------------
+//
+void BSPNode::GrowBoundingBox( BSPNode *othernode )
+{
+ if ( othernode != NULL ) {
+ // ensure other node has a bounding box (calculate if not)
+ if ( othernode->boundingbox == NULL )
+ othernode->CalcBoundingBoxes();
+ static BoundingBox *otherbox;
+ otherbox = othernode->boundingbox;
+
+ if ( boundingbox == NULL ) {
+ // if this node has no bounding box copy other node's
+ boundingbox = new BoundingBox( otherbox->getMinVertex(), otherbox->getMaxVertex() );
+ } else {
+ // merge the two bounding boxes
+ boundingbox->GrowBoundingBox( otherbox );
+ }
+ }
+}
+
+
+// calculate axial bounding box for this node and all children ----------------
+//
+void BSPNode::CalcBoundingBoxes()
+{
+ if ( boundingbox == NULL ) {
+
+ // if polygon(s) contained in this node calculate their bounding box
+ if ( polygon != NULL ) {
+ polygon->CalcBoundingBox( boundingbox );
+ if ( backpolygon != NULL ) {
+ static BoundingBox *backbox;
+ backpolygon->CalcBoundingBox( backbox );
+ boundingbox->GrowBoundingBox( backbox );
+ delete backbox;
+ }
+ }
+
+ // grow local bounding box by children's
+ GrowBoundingBox( frontsubtree );
+ GrowBoundingBox( backsubtree );
+ }
+}
+
+
+// calculate separator planes from polygons for entire bsp tree ---------------
+//
+void BSPNode::CalcSeparatorPlanes()
+{
+ if ( ( separatorplane == NULL ) && ( polygon != NULL ) ) {
+ separatorplane = new Plane( polygon->getFirstVertex(),
+ polygon->getSecondVertex(),
+ polygon->getThirdVertex() );
+ }
+
+ // check children (subtrees)
+ if ( frontsubtree ) frontsubtree->CalcSeparatorPlanes();
+ if ( backsubtree ) backsubtree->CalcSeparatorPlanes();
+}
+
+
+// format to use when writing bsp nodes to files ------------------------------
+//
+int BSPNode::outputformat = BSPNode::OUTPUT_KEY_VALUE_STYLE;
+
+
+// construct BSPNodeFlat ------------------------------------------------------
+//
+BSPNodeFlat::BSPNodeFlat( int front, int back, Polygon *poly, int clist, int blist, Plane *sep, BoundingBox *box, int num )
+{
+ frontsubtreeindx = front;
+ backsubtreeindx = back;
+ polygon = poly;
+ containedlistindx = clist;
+ backlistindx = blist;
+ separatorplane = sep;
+ boundingbox = box;
+ nodenumber = num;
+}
+
+
+// init BSPNodeFlat members ---------------------------------------------------
+//
+void BSPNodeFlat::InitNode( int front, int back, Polygon *poly, int clist, int blist, Plane *sep, BoundingBox *box, int num )
+{
+ frontsubtreeindx = front;
+ backsubtreeindx = back;
+ polygon = poly;
+ containedlistindx = clist;
+ backlistindx = blist;
+ separatorplane = sep;
+ boundingbox = box;
+ nodenumber = num;
+}
+
+
+// apply scale factor to separator plane and bounding box if attached ---------
+//
+void BSPNodeFlat::ApplyScaleFactor( double sfac )
+{
+ if ( separatorplane != NULL )
+ separatorplane->ApplyScaleFactor( sfac );
+ if ( boundingbox != NULL )
+ boundingbox->ApplyScaleFactor( sfac );
+}
+
+
+BSPLIB_NAMESPACE_END
+
+//-----------------------------------------------------------------------------
diff --git a/tool_src/BspLib/BSPNode.h b/tool_src/BspLib/BSPNode.h
new file mode 100644
index 0000000..0dba2ef
--- /dev/null
+++ b/tool_src/BspLib/BSPNode.h
@@ -0,0 +1,132 @@
+//-----------------------------------------------------------------------------
+// BSPLIB HEADER: BSPNode.h
+//
+// Copyright (c) 1996-1998 by Markus Hadwiger
+// All Rights Reserved.
+//-----------------------------------------------------------------------------
+
+#ifndef _BSPNODE_H_
+#define _BSPNODE_H_
+
+// bsplib header files
+#include "BspLibDefs.h"
+#include "PolygonList.h"
+#include "Plane.h"
+
+
+BSPLIB_NAMESPACE_BEGIN
+
+
+class BoundingBox;
+class BspObject;
+
+
+// node of bsp tree -----------------------------------------------------------
+//
+class BSPNode {
+
+public:
+
+ // output formats
+ enum {
+ OUTPUT_OLD_STYLE,
+ OUTPUT_KEY_VALUE_STYLE
+ };
+
+public:
+ BSPNode( BSPNode *front = NULL, BSPNode *back = NULL,
+ Polygon *poly = NULL, Polygon *backpoly = NULL,
+ Plane *sep = NULL, BoundingBox *box = NULL, int num = -1 );
+ ~BSPNode();
+
+public:
+ void NumberBSPNodes( int& curno );
+ void SumVertexNums( int& vtxnum );
+ void CorrectPolygonBases( BspObject *newbaseobj, int vertexindxbase, int faceidbase, int polygonidbase );
+ void CorrectPolygonBasesByTable( BspObject *newbaseobj, int *vtxindxmap, int faceidbase, int polygonidbase );
+ void WriteBSPTree( FILE *fp );
+ void CheckEdges();
+ void FetchFacePolygons( int facno, PolygonList& facepolylist );
+ Polygon* FetchBSPPolygon( int polyno );
+ void CalcBoundingBoxes();
+ void CalcSeparatorPlanes();
+
+ int getNodeNumber() const { return nodenumber; }
+ Polygon* getPolygon() { return polygon; }
+ Polygon* getBackPolygon() { return backpolygon; }
+ BSPNode* getFrontSubtree() const { return frontsubtree; }
+ BSPNode* getBackSubtree() const { return backsubtree; }
+
+ Plane* getSeparatorPlane() { return separatorplane; }
+ void setSeparatorPlane( Plane *sep ) { separatorplane = sep; }
+
+ BoundingBox*getBoundingBox() { return boundingbox; }
+ void setBoundingBox( BoundingBox *box ) { boundingbox = box; }
+
+private:
+ void GrowBoundingBox( BSPNode *othernode );
+
+public:
+ static int getOutputFormat() { return outputformat; }
+ static void setOutputFormat( int format ) { outputformat = format; }
+
+private:
+ static int outputformat; // format used to write bsp nodes to files
+
+private:
+ int nodenumber; // node id
+ Polygon* polygon; // list of frontfacing polygons in splitting plane
+ Polygon* backpolygon; // list of backfacing polygons in splitting plane
+ Plane* separatorplane; // plane if node is only separator (no polygons!)
+ BoundingBox*boundingbox; // bounding box containing node and all children
+ BSPNode* frontsubtree; // tree partitioning front halfspace
+ BSPNode* backsubtree; // tree partitioning back halfspace
+};
+
+
+// node of flat bsp tree ------------------------------------------------------
+//
+class BSPNodeFlat {
+
+public:
+ BSPNodeFlat( int front = 0, int back = 0,
+ Polygon *poly = NULL, int clist = 0, int blist = 0,
+ Plane *sep = NULL, BoundingBox *box = NULL, int num = -1 );
+ ~BSPNodeFlat() { /* don't delete polygon, separatorplane, and boundingbox!! */ }
+
+public:
+ void InitNode( int front, int back, Polygon *poly, int clist, int blist,
+ Plane *sep = NULL, BoundingBox *box = NULL, int num = -1 );
+
+ void ApplyScaleFactor( double sfac );
+
+ int getNodeNumber() const { return nodenumber; }
+ Polygon* getPolygon() { return polygon; }
+ int getContainedList() const { return containedlistindx; }
+ int getBackList() const { return backlistindx; }
+ int getFrontSubTree() const { return frontsubtreeindx; }
+ int getBackSubTree() const { return backsubtreeindx; }
+
+ Plane* getSeparatorPlane() { return separatorplane; }
+ void setSeparatorPlane( Plane *sep ) { separatorplane = sep; }
+
+ BoundingBox*getBoundingBox() { return boundingbox; }
+ void setBoundingBox( BoundingBox *box ) { boundingbox = box; }
+
+private:
+ int nodenumber; // node id (may be different than array index!!)
+ Polygon* polygon; // this node's polygon
+ Plane* separatorplane; // plane if node is only separator (no polygons!)
+ BoundingBox*boundingbox; // bounding box containing node and all children
+ int containedlistindx; // contained frontfacing polygons
+ int backlistindx; // contained backfacing polygons
+ int frontsubtreeindx; // front subtree
+ int backsubtreeindx; // back subtree
+};
+
+
+BSPLIB_NAMESPACE_END
+
+
+#endif // _BSPNODE_H_
+
diff --git a/tool_src/BspLib/BSPTree.cpp b/tool_src/BspLib/BSPTree.cpp
new file mode 100644
index 0000000..5c94dbe
--- /dev/null
+++ b/tool_src/BspLib/BSPTree.cpp
@@ -0,0 +1,121 @@
+//-----------------------------------------------------------------------------
+// BSPLIB MODULE: BSPTree.cpp
+//
+// Copyright (c) 1997-1998 by Markus Hadwiger
+// All Rights Reserved.
+//-----------------------------------------------------------------------------
+
+// bsplib header files
+#include "BSPTree.h"
+
+
+BSPLIB_NAMESPACE_BEGIN
+
+
+#define BLOCK_SIZE 4096
+
+
+// append new node to flat bsp tree -------------------------------------------
+//
+BSPNodeFlat *BSPTreeFlatRep::AppendNode( int front, int back, Polygon *poly, int clist, int blist )
+{
+ // expand storage area (array) if no space available
+ if ( nodestorage - numnodes == 0 ) {
+ BSPNodeFlat *newroot = new BSPNodeFlat[ nodestorage + BLOCK_SIZE ];
+ if ( root != NULL ) {
+ memcpy( newroot, root, nodestorage * sizeof( BSPNodeFlat ) );
+ delete[] root;
+ }
+ root = newroot;
+ nodestorage += BLOCK_SIZE;
+ }
+ // init new node and return its address
+ root[ numnodes ].InitNode( front, back, poly, clist, blist );
+ return root + numnodes++;
+}
+
+
+// fetch node per id (node number) --------------------------------------------
+//
+BSPNodeFlat *BSPTreeFlatRep::FetchNodePerId( int id )
+{
+ // id has to be greater than 0 since 0 means empty halfspace
+ return ( ( id > 0 ) && ( id <= numnodes ) ) ? ( root + id - 1 ) : NULL;
+}
+
+
+// apply scale factor to separator planes and bounding boxes of all nodes -----
+//
+void BSPTreeFlatRep::ApplyScaleFactor( double sfac )
+{
+ BSPNodeFlat *scan = root;
+ for ( int i = 0; i < numnodes; i++, scan++ )
+ scan->ApplyScaleFactor( sfac );
+}
+
+
+// build pointer-based bsp tree from flat representation ----------------------
+//
+BSPNode *BSPTreeFlatRep::BuildBSPTree( int nodenum )
+{
+ if ( nodenum == 0 )
+ return NULL;
+
+ BSPNodeFlat *node = FetchNodePerId( nodenum );
+ if ( node == NULL )
+ return NULL;
+
+ // get node's polygon
+ Polygon *poly = node->getPolygon();
+
+ // append contained list to polygon (frontfacing polygons)
+ static int containedindx;
+ static Polygon *precpoly;
+ containedindx = node->getContainedList();
+ precpoly = poly;
+ while ( containedindx > 0 ) {
+ static BSPNodeFlat *cnode;
+ static Polygon *cpoly;
+ cnode = FetchNodePerId( containedindx );
+ cpoly = cnode ? cnode->getPolygon() : NULL;
+ containedindx = cnode ? cnode->getContainedList() : 0;
+ precpoly->setNext( cpoly );
+ precpoly = cpoly;
+ }
+ if ( precpoly ) {
+ // detach original polygon list
+ precpoly->setNext( NULL );
+ }
+
+ // build list of backfacing polygons (backlist)
+ Polygon *backlist = NULL;
+ containedindx = node->getBackList();
+ precpoly = NULL;
+ while ( containedindx > 0 ) {
+ static BSPNodeFlat *cnode;
+ static Polygon *cpoly;
+ cnode = FetchNodePerId( containedindx );
+ cpoly = cnode ? cnode->getPolygon() : NULL;
+ containedindx = cnode ? cnode->getBackList() : 0;
+ if ( precpoly == NULL)
+ backlist = cpoly;
+ else
+ precpoly->setNext( cpoly );
+ precpoly = cpoly;
+ }
+ if ( precpoly ) {
+ // detach original polygon list
+ precpoly->setNext( NULL );
+ }
+
+ // recursively build front- and back-subtree
+ BSPNode *front = BuildBSPTree( node->getFrontSubTree() );
+ BSPNode *back = BuildBSPTree( node->getBackSubTree() );
+
+ return new BSPNode( front, back, poly, backlist, node->getSeparatorPlane(), node->getBoundingBox() );
+}
+
+
+BSPLIB_NAMESPACE_END
+
+//-----------------------------------------------------------------------------
diff --git a/tool_src/BspLib/BSPTree.h b/tool_src/BspLib/BSPTree.h
new file mode 100644
index 0000000..b96a93c
--- /dev/null
+++ b/tool_src/BspLib/BSPTree.h
@@ -0,0 +1,182 @@
+//-----------------------------------------------------------------------------
+// BSPLIB HEADER: BSPTree.h
+//
+// Copyright (c) 1997-1998 by Markus Hadwiger
+// All Rights Reserved.
+//-----------------------------------------------------------------------------
+
+#ifndef _BSPTREE_H_
+#define _BSPTREE_H_
+
+// bsplib header files
+#include "BspLibDefs.h"
+#include "BSPNode.h"
+
+
+BSPLIB_NAMESPACE_BEGIN
+
+
+// bsp tree; basically pointer to root node (representation class) ------------
+//
+class BSPTreeRep {
+
+ friend class BSPTree;
+
+private:
+ BSPTreeRep() : ref_count( 0 ) { root = NULL; }
+ ~BSPTreeRep() { delete root; }
+
+ BSPNode* InitTree( BSPNode *rootnode );
+ BSPNode* getRoot() { return root; }
+
+ void InvalidateTree();
+
+ int TreeEmpty() const { return ( root == NULL ); }
+
+private:
+ int ref_count;
+ BSPNode* root;
+};
+
+// init with entire tree of BSPNode objects -----------------------------------
+inline BSPNode *BSPTreeRep::InitTree( BSPNode *rootnode )
+{
+ delete root;
+ return ( root = rootnode );
+}
+
+// set root to null without deleting tree first -------------------------------
+inline void BSPTreeRep::InvalidateTree()
+{
+ root = NULL;
+}
+
+
+// bsp tree; basically pointer to root node (handle class) --------------------
+//
+class BSPTree {
+
+public:
+ BSPTree() { rep = new BSPTreeRep; rep->ref_count = 1; }
+ ~BSPTree() { if ( --rep->ref_count == 0 ) delete rep; }
+
+ BSPTree( const BSPTree& copyobj );
+ BSPTree& operator =( const BSPTree& copyobj );
+
+ // pass most operations through to BSPNode
+ BSPNode* operator->() { return rep->getRoot(); }
+
+ BSPNode* InitTree( BSPNode *rootnode ) { return rep->InitTree( rootnode ); }
+ BSPNode* getRoot() { return rep->getRoot(); }
+
+ void InvalidateTree() { rep->InvalidateTree(); }
+
+ int TreeEmpty() const { return rep->TreeEmpty(); }
+
+private:
+ BSPTreeRep* rep;
+};
+
+// copy constructor -----------------------------------------------------------
+inline BSPTree::BSPTree( const BSPTree& copyobj )
+{
+ rep = copyobj.rep;
+ rep->ref_count++;
+}
+
+// assignment operator --------------------------------------------------------
+inline BSPTree& BSPTree::operator =( const BSPTree& copyobj )
+{
+ if ( &copyobj != this ) {
+ if ( --rep->ref_count == 0 ) {
+ delete rep;
+ }
+ rep = copyobj.rep;
+ rep->ref_count++;
+ }
+ return *this;
+}
+
+
+// flat bsp tree; basically pointer to array (representation class) -----------
+//
+class BSPTreeFlatRep {
+
+ friend class BSPTreeFlat;
+
+private:
+ BSPTreeFlatRep() : ref_count( 0 ) { root = NULL; numnodes = 0; nodestorage = 0; }
+ ~BSPTreeFlatRep() { delete[] root; }
+
+ BSPNodeFlat* AppendNode( int front, int back, Polygon *poly, int clist, int blist );
+ BSPNodeFlat* FetchNodePerId( int id );
+ BSPNode* BuildBSPTree( int nodenum );
+ BSPNodeFlat* getRoot() { return root; }
+
+ int TreeEmpty() const { return ( root == NULL ); }
+ int getNumNodes() const { return numnodes; }
+
+ void ApplyScaleFactor( double sfac );
+ void DestroyTree() { delete[] root; root = NULL; numnodes = 0; nodestorage = 0; }
+
+private:
+ int ref_count;
+ int numnodes;
+ int nodestorage;
+ BSPNodeFlat* root;
+};
+
+
+// flat bsp tree; basically pointer to array (handle class) -------------------
+//
+class BSPTreeFlat {
+
+public:
+ BSPTreeFlat() { rep = new BSPTreeFlatRep; rep->ref_count = 1; }
+ ~BSPTreeFlat() { if ( --rep->ref_count == 0 ) delete rep; }
+
+ BSPTreeFlat( const BSPTreeFlat& copyobj );
+ BSPTreeFlat& operator =( const BSPTreeFlat& copyobj );
+
+ BSPNodeFlat* AppendNode( int front, int back, Polygon *poly, int clist, int blist )
+ { return rep->AppendNode( front, back, poly, clist, blist ); }
+ BSPNodeFlat* FetchNodePerId( int id ) { return rep->FetchNodePerId( id ); }
+ BSPNode* BuildBSPTree( int nodenum ) { return rep->BuildBSPTree( nodenum ); }
+ BSPNodeFlat* getRoot() { return rep->getRoot(); }
+
+ int TreeEmpty() const { return rep->TreeEmpty(); }
+ int getNumNodes() const { return rep->getNumNodes(); }
+
+ void ApplyScaleFactor( double sfac ) { rep->ApplyScaleFactor( sfac ); }
+ void DestroyTree() { rep->DestroyTree(); }
+
+private:
+ BSPTreeFlatRep* rep;
+};
+
+// copy constructor -----------------------------------------------------------
+inline BSPTreeFlat::BSPTreeFlat( const BSPTreeFlat& copyobj )
+{
+ rep = copyobj.rep;
+ rep->ref_count++;
+}
+
+// assignment operator --------------------------------------------------------
+inline BSPTreeFlat& BSPTreeFlat::operator =( const BSPTreeFlat& copyobj )
+{
+ if ( &copyobj != this ) {
+ if ( --rep->ref_count == 0 ) {
+ delete rep;
+ }
+ rep = copyobj.rep;
+ rep->ref_count++;
+ }
+ return *this;
+}
+
+
+BSPLIB_NAMESPACE_END
+
+
+#endif // _BSPTREE_H_
+
diff --git a/tool_src/BspLib/BoundingBox.cpp b/tool_src/BspLib/BoundingBox.cpp
new file mode 100644
index 0000000..04008c2
--- /dev/null
+++ b/tool_src/BspLib/BoundingBox.cpp
@@ -0,0 +1,223 @@
+//-----------------------------------------------------------------------------
+// BSPLIB MODULE: BoundingBox.cpp
+//
+// Copyright (c) 1997-1998 by Markus Hadwiger
+// All Rights Reserved.
+//-----------------------------------------------------------------------------
+
+// bsplib headers
+#include "BoundingBox.h"
+#include "ObjectBSPNode.h"
+#include "Plane.h"
+
+
+BSPLIB_NAMESPACE_BEGIN
+
+
+// apply scale factor to bounding box -----------------------------------------
+//
+void BoundingBox::ApplyScaleFactor( double sfac )
+{
+ //NOTE:
+ // this will be needed if the attached object is scaled.
+ // the scale factor is applied to the space containing the
+ // bounding box, i.e. its midpoint will move.
+
+ minvertex.setX( minvertex.getX() * sfac );
+ minvertex.setY( minvertex.getY() * sfac );
+ minvertex.setZ( minvertex.getZ() * sfac );
+
+ maxvertex.setX( maxvertex.getX() * sfac );
+ maxvertex.setY( maxvertex.getY() * sfac );
+ maxvertex.setZ( maxvertex.getZ() * sfac );
+}
+
+
+// grow this bounding box by another one (maximum/minimum merge) --------------
+//
+void BoundingBox::GrowBoundingBox( BoundingBox *otherbox )
+{
+ if ( otherbox != NULL ) {
+ if ( otherbox->minvertex.getX() < minvertex.getX() )
+ minvertex.setX( otherbox->minvertex.getX() );
+ if ( otherbox->minvertex.getY() < minvertex.getY() )
+ minvertex.setY( otherbox->minvertex.getY() );
+ if ( otherbox->minvertex.getZ() < minvertex.getZ() )
+ minvertex.setZ( otherbox->minvertex.getZ() );
+
+ if ( otherbox->maxvertex.getX() > maxvertex.getX() )
+ maxvertex.setX( otherbox->maxvertex.getX() );
+ if ( otherbox->maxvertex.getY() > maxvertex.getY() )
+ maxvertex.setY( otherbox->maxvertex.getY() );
+ if ( otherbox->maxvertex.getZ() > maxvertex.getZ() )
+ maxvertex.setZ( otherbox->maxvertex.getZ() );
+ }
+}
+
+
+// fill in bounding box as union of entire list -------------------------------
+//
+void BoundingBox::BoundingBoxListUnion( BoundingBox& unionbox )
+{
+ // init union box
+ delete unionbox.nextbox;
+ unionbox.nextbox = NULL;
+ unionbox.containedobject = NULL;
+ unionbox.minvertex = minvertex;
+ unionbox.maxvertex = maxvertex;
+
+ // build union of entire list
+ for ( BoundingBox *curbox = nextbox; curbox; curbox = curbox->nextbox )
+ unionbox.GrowBoundingBox( curbox );
+}
+
+
+// partition list of bounding boxing boxes and build tree structure -----------
+//
+ObjectBSPNode *BoundingBox::PartitionSpace()
+{
+ //NOTE:
+ // this function alters the link fields of the objects attached
+ // to bounding boxes. therefore, the original linked list of
+ // objects is invalid after this function! the objects themselves
+ // are only accessible via tree nodes afterwards.
+
+ //NOTE:
+ // analogously to polygon bsp trees where the polygon list is dissolved
+ // in the process of bsp compilation, the list of bounding boxes is
+ // completely dissolved by this function! that is, the bounding box
+ // for which PartitionSpace() has been invoked should not be accessed
+ // directly anymore. all bounding boxes can then be accessed via the
+ // generated object-bsp-tree!
+
+ // only one box in this subspace?
+ if ( nextbox == NULL ) {
+ // unlink tail of object list
+ containedobject->next = NULL;
+ // create ObjectBSPNode for this box (leaf!)
+ return new ObjectBSPNode( NULL, NULL, NULL, this );
+ }
+
+ // select a separating plane
+ Vector3 separatornormal( 1.0, 0.0, 0.0 );
+ double separatoroffset = maxvertex.getX();
+ int currentboundary = 0;
+ Plane *separator = new Plane( separatornormal, separatoroffset );
+ BoundingBox *currentbox = this;
+ // scan all bounding boxes to find a suitable separating plane
+ for ( currentbox = this; ; ) {
+
+ // check if plane separates bounding boxes cleanly
+ int cleanseparation = 1;
+ int membersofpos = 0;
+ int membersofneg = 0;
+ for ( BoundingBox *scan = this; scan; scan = scan->getNext() ) {
+ if ( !separator->PointInNegativeHalfspace( scan->getMinVertex() ) &&
+ !separator->PointInNegativeHalfspace( scan->getMaxVertex() ) ) {
+ membersofpos++;
+ } else if ( !separator->PointInPositiveHalfspace( scan->getMinVertex() ) &&
+ !separator->PointInPositiveHalfspace( scan->getMaxVertex() ) ) {
+ membersofneg++;
+ } else {
+ cleanseparation = 0;
+ break;
+ }
+ }
+ //NOTE:
+ // both halfspaces have to contain bounding boxes; separation of vacant
+ // space from inhabited space just makes the tree unnecessarily large.
+ // this does not influence if there is a clean separating plane or not!
+ if ( ( membersofpos > 0 ) && ( membersofneg > 0 ) && cleanseparation )
+ break;
+
+ // try next boundary plane
+ currentboundary = ( currentboundary + 1 ) % 6;
+ if ( currentboundary == 0 )
+ currentbox = currentbox->getNext();
+
+ if ( currentbox != NULL ) {
+ switch ( currentboundary ) {
+ case 0:
+ separatornormal = Vector3( 1.0, 0.0, 0.0 );
+ separatoroffset = currentbox->maxvertex.getX();
+ break;
+ case 1:
+ separatornormal = Vector3( 0.0, 1.0, 0.0 );
+ separatoroffset = currentbox->maxvertex.getY();
+ break;
+ case 2:
+ separatornormal = Vector3( 0.0, 0.0, 1.0 );
+ separatoroffset = currentbox->maxvertex.getZ();
+ break;
+ case 3:
+ separatornormal = Vector3( -1.0, 0.0, 0.0 );
+ separatoroffset = -currentbox->minvertex.getX();
+ break;
+ case 4:
+ separatornormal = Vector3( 0.0, -1.0, 0.0 );
+ separatoroffset = -currentbox->minvertex.getY();
+ break;
+ case 5:
+ separatornormal = Vector3( 0.0, 0.0, -1.0 );
+ separatoroffset = -currentbox->minvertex.getZ();
+ break;
+ }
+ separator->setPlaneNormal( separatornormal );
+ separator->setPlaneOffset( separatoroffset );
+ } else {
+ break;
+ }
+ }
+
+ BoundingBox *frontsubspace = NULL;
+ BoundingBox *backsubspace = NULL;
+
+ if ( currentbox != NULL ) {
+ // partition space into two halfspaces (walk list of bounding boxes)
+ for ( currentbox = this; currentbox; ) {
+ if ( !separator->PointInNegativeHalfspace( currentbox->getMinVertex() ) &&
+ !separator->PointInNegativeHalfspace( currentbox->getMaxVertex() ) ) {
+ // box contained in positive halfspace
+ BoundingBox *tmpbox = currentbox->getNext();
+ currentbox->nextbox = frontsubspace;
+ frontsubspace = currentbox;
+ currentbox = tmpbox;
+ } else {
+ // box contained in negative halfspace
+ BoundingBox *tmpbox = currentbox->getNext();
+ currentbox->nextbox = backsubspace;
+ backsubspace = currentbox;
+ currentbox = tmpbox;
+ }
+ }
+ } else {
+ // no suitable separating plane found: create list of unseparable objects
+ for ( currentbox = this; currentbox; currentbox = currentbox->getNext() ) {
+ currentbox->containedobject->next =
+ currentbox->getNext() ? currentbox->getNext()->containedobject : NULL;
+ }
+ // delete legacy bounding boxes
+ delete nextbox;
+ nextbox = NULL;
+ // create ObjectBSPNode for this box (leaf!)
+ return new ObjectBSPNode( NULL, NULL, NULL, this );
+
+ //NOTE:
+ // if bounding boxes cannot be separated cleanly, their corresponding objects
+ // are inserted into a linear list attached to a single bounding box. this
+ // bounding box, however, encompasses only the head of this list!
+ // for bsp compilation, the objects in these lists have to be explicitly merged
+ // into a single object. this is not done automatically!
+ // currently, only ObjectBSPNode::CreateObjectList() merges these objects.
+ }
+
+ // allocate new root; partition halfspaces recursively and return root
+ ObjectBSPNode *front = frontsubspace ? frontsubspace->PartitionSpace() : NULL;
+ ObjectBSPNode *back = backsubspace ? backsubspace->PartitionSpace() : NULL;
+ return new ObjectBSPNode( front, back, separator, NULL );
+}
+
+
+BSPLIB_NAMESPACE_END
+
+//-----------------------------------------------------------------------------
diff --git a/tool_src/BspLib/BoundingBox.h b/tool_src/BspLib/BoundingBox.h
new file mode 100644
index 0000000..417d854
--- /dev/null
+++ b/tool_src/BspLib/BoundingBox.h
@@ -0,0 +1,72 @@
+//-----------------------------------------------------------------------------
+// BSPLIB HEADER: BoundingBox.h
+//
+// Copyright (c) 1997-1998 by Markus Hadwiger
+// All Rights Reserved.
+//-----------------------------------------------------------------------------
+
+#ifndef _BOUNDINGBOX_H_
+#define _BOUNDINGBOX_H_
+
+// bsplib header files
+#include "BspLibDefs.h"
+#include "BspObject.h"
+#include "Vertex.h"
+
+
+BSPLIB_NAMESPACE_BEGIN
+
+
+// axial bounding box; can be part of singly linked list ----------------------
+//
+class BoundingBox {
+
+ friend class ObjectBSPNode;
+
+public:
+ BoundingBox() { containedobject = NULL; nextbox = NULL; }
+ BoundingBox( BspObject *cobj, BoundingBox *next = NULL );
+ BoundingBox( const Vertex3& minvert, const Vertex3& maxvert, BoundingBox *next = NULL );
+ ~BoundingBox() { delete nextbox; }
+
+ void ApplyScaleFactor( double sfac );
+ void GrowBoundingBox( BoundingBox *otherbox );
+ void BoundingBoxListUnion( BoundingBox& unionbox );
+ class ObjectBSPNode* PartitionSpace();
+
+ Vertex3 getMinVertex() const { return minvertex; }
+ Vertex3 getMaxVertex() const { return maxvertex; }
+ BspObject* getContainedObject() const { return containedobject; }
+ BoundingBox* getNext() const { return nextbox; }
+
+private:
+ Vertex3 minvertex;
+ Vertex3 maxvertex;
+ BspObject* containedobject;
+ BoundingBox* nextbox;
+};
+
+// construct bounding box by calculating its extents --------------------------
+inline BoundingBox::BoundingBox( BspObject *cobj, BoundingBox *next )
+{
+ if ( ( containedobject = cobj ) != NULL ) {
+ cobj->CalcBoundingBox( minvertex, maxvertex );
+ }
+ nextbox = next;
+}
+
+// construct bounding box directly --------------------------------------------
+inline BoundingBox::BoundingBox( const Vertex3& minvert, const Vertex3& maxvert, BoundingBox *next )
+{
+ minvertex = minvert;
+ maxvertex = maxvert;
+ containedobject = NULL;
+ nextbox = next;
+}
+
+
+BSPLIB_NAMESPACE_END
+
+
+#endif // _BOUNDINGBOX_H_
+
diff --git a/tool_src/BspLib/BspFormat.cpp b/tool_src/BspLib/BspFormat.cpp
new file mode 100644
index 0000000..a358339
--- /dev/null
+++ b/tool_src/BspLib/BspFormat.cpp
@@ -0,0 +1,71 @@
+//-----------------------------------------------------------------------------
+// BSPLIB MODULE: BspFormat.cpp
+//
+// Copyright (c) 1997 by Markus Hadwiger
+// All Rights Reserved.
+//-----------------------------------------------------------------------------
+
+// bsplib header files
+#include "BspFormat.h"
+
+
+BSPLIB_NAMESPACE_BEGIN
+
+
+// get index to section id specified as string (this function is static!) -----
+//
+int BspFormat::GetSectionId( char *section_name )
+{
+ int sectionid = SingleFormat::GetSectionId( section_name );
+ if ( sectionid == _nil ) {
+ for ( int i = 0; i < _num_bsp_sections - _num_single_sections; i++ )
+ if ( stricmp( section_name, section_strings[ i ] ) == 0 )
+ return section_ids[ i ];
+ }
+ return sectionid;
+}
+
+
+// get name of section specified via id (this function is static!) ------------
+//
+const char *BspFormat::GetSectionName( int section_id )
+{
+ const char *sectionname = SingleFormat::GetSectionName( section_id );
+ if ( sectionname == NULL ) {
+ return ( section_id < _num_bsp_sections ) ?
+ section_strings[ section_id - _num_single_sections ] : NULL;
+ }
+ return sectionname;
+}
+
+
+// BspFormat specific static variables ----------------------------------------
+//
+const char BspFormat::_bspsig_str[] = "#BSP";
+const char BspFormat::BSP_FILE_EXTENSION[] = ".bsp";
+
+const char BspFormat::_bspspec_polygon_str[] = "polygon";
+const char BspFormat::_bspspec_frontlist_str[] = "frontlist";
+const char BspFormat::_bspspec_backlist_str[] = "backlist";
+const char BspFormat::_bspspec_fronttree_str[] = "fronttree";
+const char BspFormat::_bspspec_backtree_str[] = "backtree";
+const char BspFormat::_bspspec_plane_str[] = "plane";
+const char BspFormat::_bspspec_boundingbox_str[] = "boundingbox";
+
+const char BspFormat::_bsptree_str[] = "#bsptree";
+const char BspFormat::_polygons_str[] = "#polygons";
+
+// additional section names table
+const char *BspFormat::section_strings[] = {
+ _bsptree_str,
+ _polygons_str
+};
+const int BspFormat::section_ids[] = {
+ _bsptree,
+ _polygons
+};
+
+
+BSPLIB_NAMESPACE_END
+
+//-----------------------------------------------------------------------------
diff --git a/tool_src/BspLib/BspFormat.h b/tool_src/BspLib/BspFormat.h
new file mode 100644
index 0000000..9097a80
--- /dev/null
+++ b/tool_src/BspLib/BspFormat.h
@@ -0,0 +1,77 @@
+//-----------------------------------------------------------------------------
+// BSPLIB HEADER: BspFormat.h
+//
+// Copyright (c) 1997 by Markus Hadwiger
+// All Rights Reserved.
+//-----------------------------------------------------------------------------
+
+#ifndef _BSPFORMAT_H_
+#define _BSPFORMAT_H_
+
+// bsplib header files
+#include "BspLibDefs.h"
+#include "SingleFormat.h"
+
+
+BSPLIB_NAMESPACE_BEGIN
+
+
+// class containing bsp format specifics --------------------------------------
+//
+class BspFormat : public virtual SingleFormat {
+
+protected:
+
+ // section enumeration
+ // (additional sections not supported by SingleFormat)
+ enum {
+ _bsptree = _num_single_sections,
+ _polygons,
+
+ _num_bsp_sections
+ };
+
+public:
+ BspFormat() { }
+ ~BspFormat() { }
+
+ BspFormat( const BspFormat& copyobj ) : SingleFormat( copyobj ) { }
+ BspFormat& operator =( const BspFormat& copyobj );
+
+protected:
+ static int GetSectionId( char *section_name );
+ static const char* GetSectionName( int section_id );
+
+public:
+ static const char _bspspec_polygon_str[];
+ static const char _bspspec_frontlist_str[];
+ static const char _bspspec_backlist_str[];
+ static const char _bspspec_fronttree_str[];
+ static const char _bspspec_backtree_str[];
+ static const char _bspspec_plane_str[];
+ static const char _bspspec_boundingbox_str[];
+
+protected:
+ static const char _bspsig_str[];
+ static const char BSP_FILE_EXTENSION[];
+
+ static const char _bsptree_str[];
+ static const char _polygons_str[];
+
+ static const char* section_strings[];
+ static const int section_ids[];
+};
+
+// assignment operator --------------------------------------------------------
+inline BspFormat& BspFormat::operator =( const BspFormat& copyobj )
+{
+ *(SingleFormat *)this = copyobj;
+ return *this;
+}
+
+
+BSPLIB_NAMESPACE_END
+
+
+#endif // _BSPFORMAT_H_
+
diff --git a/tool_src/BspLib/BspInput.cpp b/tool_src/BspLib/BspInput.cpp
new file mode 100644
index 0000000..b124e88
--- /dev/null
+++ b/tool_src/BspLib/BspInput.cpp
@@ -0,0 +1,406 @@
+//-----------------------------------------------------------------------------
+// BSPLIB MODULE: BspInput.cpp
+//
+// Copyright (c) 1996-1998 by Markus Hadwiger
+// All Rights Reserved.
+//-----------------------------------------------------------------------------
+
+// bsplib header files
+#include "BspInput.h"
+#include "BspObject.h"
+#include "BspTool.h"
+#include "BoundingBox.h"
+#include "Plane.h"
+
+
+BSPLIB_NAMESPACE_BEGIN
+
+
+// file is read and parsed immediately after construction of an object --------
+//
+BspInput::BspInput( BspObjectList objectlist, const char *filename ) :
+ SingleInput( objectlist, filename )
+{
+ ParseObjectData();
+}
+
+
+// destructor destroys only class members and base classes --------------------
+//
+BspInput::~BspInput()
+{
+}
+
+
+// assignment copies only the BspFormat part of the object --------------------
+//
+BspInput& BspInput::operator =( const BspInput& copyobj )
+{
+ *(BspFormat *)this = copyobj;
+ return *this;
+}
+
+
+// print error message if error in object data-file ---------------------------
+//
+void BspInput::ParseError( int section )
+{
+ //NOTE:
+ // GetSectionName() is overloaded and not virtual, therefore
+ // SingleInput's ParseError() cannot be used!
+ sprintf( line, "%sin section %s (line %d)", parser_err_str,
+ GetSectionName( section ), m_parser_lineno );
+ ErrorMessage( line );
+ HandleCriticalError();
+}
+
+
+// correct mapping coordinates if object scale, translation, etc. applied -----
+//
+void BspInput::CorrectMappingCoordinates()
+{
+ FaceChunk& facelist = m_baseobject->getFaceList();
+ int numfaces = facelist.getNumElements();
+ for ( int i = 0; i < numfaces; i++ )
+ if ( facelist[ i ].MappingAttached() )
+ for ( int j = 0; j < 3; j++ ) {
+ Vertex2 vtx = facelist[ i ].MapXY( j );
+ vtx.setX( vtx.getX() - NewOriginX );
+ vtx.setY( vtx.getY() - NewOriginY );
+ vtx.setW( vtx.getW() - NewOriginZ );
+ if ( PostProcessingFlags & FILTER_SCALE_FACTORS ) {
+ vtx.setX( vtx.getX() * ObjScaleX );
+ vtx.setY( vtx.getY() * ObjScaleY );
+ vtx.setW( vtx.getW() * ObjScaleZ );
+ }
+ facelist[ i ].MapXY( j ) = vtx;
+ }
+}
+
+
+// read polygon index list for current face -----------------------------------
+//
+void BspInput::ReadPolyIndxs( int& facesread )
+{
+ while ( m_scanptr != NULL ) {
+ // only end-of-line or comment terminates index-list
+ if ( *m_scanptr == ';' ) break;
+ // read polygon id
+ int polynumber;
+ ReadIntParameter( polynumber, 1 );
+ // find polygon referenced via its id
+ Polygon *poly = m_baseobject->getPolygonList().FindPolygon( polynumber );
+
+ if ( poly != NULL ) {
+ if ( poly->getFaceId() != -1 )
+ ParseError( m_section );
+ // store faceindex into polygon (converted to 0-start)
+ poly->setFaceId( facesread );
+ } else {
+ sprintf( line, "%s[Polygonindex invalid]: polygon %d in line %d\n",
+ parser_err_str, polynumber + 1, m_parser_lineno );
+ ErrorMessage( line );
+ HandleCriticalError();
+ }
+
+ m_scanptr = strtok( NULL, ",/ \t\n\r" );
+ }
+
+ facesread++;
+}
+
+
+// read face correspondences as direct three point mapping --------------------
+//
+void BspInput::ReadDirectCorrespondences( int& mappingsread )
+{
+ FaceChunk& facelist = m_baseobject->getFaceList();
+
+ int texmapcount = 0;
+ int corrfaceno = 0;
+ for ( corrfaceno = 0; corrfaceno < facelist.getNumElements(); corrfaceno++ ) {
+ if ( facelist[ corrfaceno ].FaceTexMapped() )
+ ++texmapcount;
+ if ( texmapcount > mappingsread )
+ break;
+ }
+
+ if ( corrfaceno == facelist.getNumElements() ) {
+ sprintf( line, "%s[Too many mappings specified]: line %d\n",
+ parser_err_str, m_parser_lineno );
+ ErrorMessage( line );
+ HandleCriticalError();
+ }
+
+ double x, y, z;
+ ReadThreeDoubles( x, y, z );
+ facelist[ corrfaceno ].MapXY( 0 ) = Vertex2( x, y, z );
+
+ for ( int k = 1; k < 6; k++ ) {
+ if ( m_input.ReadLine( line, TEXTLINE_MAX ) == NULL )
+ ParseError( m_section );
+ m_parser_lineno++;
+ if ( ( m_scanptr = strtok( line, ",/ \t\n\r" ) ) == NULL )
+ continue;
+ ReadThreeDoubles( x, y, z );
+ if ( k < 3 ) {
+ facelist[ corrfaceno ].MapXY( k ) = Vertex2( x, y, z );
+ } else {
+ facelist[ corrfaceno ].MapUV( k - 3 ) = Vertex2( x, y, z );
+ }
+ }
+
+ mappingsread++;
+}
+
+
+// read single node into bsp tree ---------------------------------------------
+//
+void BspInput::ReadBspTree()
+{
+ int polynumber = -1;
+ int clistindx = 0;
+ int blistindx = 0;
+ int fstindx = 0;
+ int bstindx = 0;
+
+ Plane *separator = NULL;
+ BoundingBox *box = NULL;
+
+ //NOTE:
+ // m_scanptr points to "<nodenumber>:", but the
+ // nodenumber contained in the file is ignored!
+
+ m_scanptr = strtok( NULL, ", \t\n\r" );
+
+ if ( isdigit( *m_scanptr ) ) {
+
+ // read polygon number
+ ReadIntParameter( polynumber, 1 );
+
+ // read nodenumber of head of contained list
+ m_scanptr = strtok( NULL, "|, \t\n\r" );
+ ReadIntParameter( clistindx, 0 );
+
+ // read nodenumber of head of backlist
+ m_scanptr = strtok( NULL, "|, \t\n\r" );
+ ReadIntParameter( blistindx, 0 );
+
+ //NOTE:
+ // the specification of a front- and back-subtree may be
+ // omitted. empty subtrees (nil) will be assumed.
+
+ // read index of front- and back-subtree if not contained node
+ if ( ( m_scanptr = strtok( NULL, "|-, \t\n\r" ) ) != NULL ) {
+ ReadIntParameter( fstindx, 0 );
+ m_scanptr = strtok( NULL, "|-, \t\n\r" );
+ ReadIntParameter( bstindx, 0 );
+ }
+
+ } else do {
+
+ // read line specified in new format (key/value style)
+ char *property = m_scanptr;
+ int error = 1;
+ if ( ( m_scanptr = strtok( NULL, " \t\n\r" ) ) != NULL ) {
+ if ( stricmp( property, _bspspec_polygon_str ) == 0 ) {
+ ReadIntParameter( polynumber, 1 );
+ error = 0;
+ } else if ( stricmp( property, _bspspec_frontlist_str ) == 0 ) {
+ ReadIntParameter( clistindx, 0 );
+ error = 0;
+ } else if ( stricmp( property, _bspspec_backlist_str ) == 0 ) {
+ ReadIntParameter( blistindx, 0 );
+ error = 0;
+ } else if ( stricmp( property, _bspspec_fronttree_str ) == 0 ) {
+ ReadIntParameter( fstindx, 0 );
+ error = 0;
+ } else if ( stricmp( property, _bspspec_backtree_str ) == 0 ) {
+ ReadIntParameter( bstindx, 0 );
+ error = 0;
+ } else if ( stricmp( property, _bspspec_plane_str ) == 0 ) {
+ double x, y, z, d;
+ ReadFourDoubles( x, y, z, d );
+ Vertex3 normal( x, y, z );
+ separator = new Plane( normal, d );
+ error = 0;
+ } else if ( stricmp( property, _bspspec_boundingbox_str ) == 0 ) {
+ Vertex3 v1, v2;
+ ReadSixDoubles( v1, v2 );
+ box = new BoundingBox( v1, v2 );
+ error = 0;
+ }
+ }
+ if ( error ) {
+ {
+ StrScratch error;
+ sprintf( error, "%s[Invalid property of bspnode]: %s (line %d)",
+ parser_err_str, property, m_parser_lineno );
+ ErrorMessage( error );
+ }
+ HandleCriticalError();
+ }
+
+ } while ( ( m_scanptr = strtok( NULL, " \t\n\r" ) ) != NULL );
+
+ // find polygon referenced via its id
+ Polygon *poly = NULL;
+ if ( polynumber >= 0 ) {
+ poly = m_baseobject->getPolygonList().FindPolygon( polynumber );
+ if ( poly == NULL ) {
+ sprintf( line, "%s[Polygonindex in bsp tree invalid]: %d\n",
+ parser_err_str, polynumber + 1 );
+ ErrorMessage( line );
+ HandleCriticalError();
+ }
+ }
+
+ // append new node to flat bsp tree
+ BSPTreeFlat& flatbsp = m_baseobject->getBSPTreeFlat();
+ BSPNodeFlat *flatnode = flatbsp.AppendNode( fstindx, bstindx, poly, clistindx, blistindx );
+
+ if ( separator != NULL ) {
+ // attach separator plane
+ flatnode->setSeparatorPlane( separator );
+ }
+ if ( box != NULL ) {
+ // attach bounding box
+ flatnode->setBoundingBox( box );
+ }
+}
+
+
+// parse object data-file -----------------------------------------------------
+//
+int BspInput::ParseObjectData()
+{
+ int facedef_itemsread = 0;
+ int faceprop_itemsread = 0;
+ int facenorm_itemsread = 0;
+ int mappdef_itemsread = 0;
+
+ InfoMessage( "Processing input data file (format='BSP V1.1') ..." );
+
+ // parse sections and read data -------------------------------
+ m_section = _nil;
+ while ( m_input.ReadLine( line, TEXTLINE_MAX ) != NULL ) {
+
+ if ( ( m_parser_lineno++ & PARSER_DOT_SIZE ) == 0 )
+ printf( "." ), fflush( stdout );
+
+ if ( ( m_scanptr = strtok( line, "/, \t\n\r" ) ) == NULL )
+ continue;
+ else if ( *m_scanptr == ';' )
+ continue;
+ else if ( strnicmp( m_scanptr, "<end", 4 ) == 0 )
+ break;
+ else if ( *m_scanptr == '#' ) {
+ if ( strncmp( m_scanptr, _bspsig_str, strlen( _bspsig_str ) ) == 0 ) {
+ m_section = _comment;
+ } else if ( ( m_section = GetSectionId( m_scanptr ) ) == _nil ) {
+ {
+ StrScratch error;
+ sprintf( error, "%s[Undefined section-name]: %s (line %d)",
+ parser_err_str, m_scanptr, m_parser_lineno );
+ ErrorMessage( error );
+ }
+ HandleCriticalError();
+ }
+ } else {
+ switch ( m_section ) {
+
+ // list of vertices ------------------------------------
+ case _vertices :
+ ReadVertex();
+ break;
+
+ // vertexnums of polygons ------------------------------
+ case _polygons :
+ ReadFace( FALSE );
+ break;
+
+ // definition of faces (consisting of polygons) --------
+ case _faces :
+ ReadPolyIndxs( facedef_itemsread );
+ break;
+
+ // bsptree ---------------------------------------------
+ case _bsptree :
+ ReadBspTree();
+ break;
+
+ // normals for face's planes ---------------------------
+ case _facenormals :
+ ReadFaceNormal( facenorm_itemsread );
+ break;
+
+ // properties of faces ---------------------------------
+ case _faceproperties :
+ ReadFaceProperties( faceprop_itemsread );
+ break;
+
+ // texture->face correspondences ----------------------
+ case _correspondences :
+ ReadDirectCorrespondences( mappdef_itemsread );
+ break;
+
+ // texturing data -----------------------------------
+ case _textures :
+ ReadTextures();
+ break;
+
+ // location of the object ---------------------------
+ case _worldlocation :
+ ReadWorldLocation();
+ break;
+
+ // location of camera -------------------------------
+ case _camera :
+ ReadCameraLocation();
+ break;
+
+ // filename of palette file -------------------------
+ case _palette :
+ ReadPaletteFilename();
+ break;
+
+ // scalefactors for object --------------------------
+ case _scalefactors :
+ ReadScaleFactors();
+ break;
+
+ // exchange command for axes ------------------------
+ case _xchange :
+ ReadXChangeCommand();
+ break;
+
+ // set new object origin ----------------------------
+ case _setorigin :
+ ReadOrigin();
+ break;
+
+ }
+ }
+ }
+
+ // do post processing after parse
+ CorrectMappingCoordinates();
+ ApplyOriginTranslation();
+ FilterAxesDirSwitch();
+ FilterScaleFactors();
+ FilterAxesExchange();
+ EnforceMaximumExtents();
+ m_baseobject->CheckParsedData();
+
+ InfoMessage( "\nObject data ok.\n" );
+
+ // do colorindex to rgb conversion
+ ConvertColIndxs();
+
+ return ( m_inputok = TRUE );
+}
+
+
+BSPLIB_NAMESPACE_END
+
+//-----------------------------------------------------------------------------
diff --git a/tool_src/BspLib/BspInput.h b/tool_src/BspLib/BspInput.h
new file mode 100644
index 0000000..930e112
--- /dev/null
+++ b/tool_src/BspLib/BspInput.h
@@ -0,0 +1,48 @@
+//-----------------------------------------------------------------------------
+// BSPLIB HEADER: BspInput.h
+//
+// Copyright (c) 1996-1998 by Markus Hadwiger
+// All Rights Reserved.
+//-----------------------------------------------------------------------------
+
+#ifndef _BSPINPUT_H_
+#define _BSPINPUT_H_
+
+// bsplib header files
+#include "BspLibDefs.h"
+#include "BspFormat.h"
+#include "SingleInput.h"
+
+
+BSPLIB_NAMESPACE_BEGIN
+
+
+// file input class for bsp format files --------------------------------------
+//
+class BspInput : public BspFormat, public SingleInput {
+
+public:
+ BspInput( BspObjectList objectlist, const char *filename );
+ ~BspInput();
+
+ BspInput& operator =( const BspInput& copyobj );
+
+public:
+ int ParseObjectData();
+
+private:
+ void CorrectMappingCoordinates();
+ void ReadPolyIndxs( int& facesread );
+ void ReadDirectCorrespondences( int& facesread );
+ void ReadBspTree();
+
+protected:
+ void ParseError( int section );
+};
+
+
+BSPLIB_NAMESPACE_END
+
+
+#endif // _BSPINPUT_H_
+
diff --git a/tool_src/BspLib/BspLib.vcproj b/tool_src/BspLib/BspLib.vcproj
new file mode 100755
index 0000000..93507ab
--- /dev/null
+++ b/tool_src/BspLib/BspLib.vcproj
@@ -0,0 +1,1055 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="7.10"
+ Name="BspLib"
+ SccProjectName="&quot;$/ParsecTools/BspLib&quot;, KUFAAAAA"
+ SccLocalPath=".">
+ <Platforms>
+ <Platform
+ Name="Win32"/>
+ </Platforms>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory=".\Debug"
+ IntermediateDirectory=".\Debug"
+ ConfigurationType="4"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="FALSE"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="..\BspLib;..\QvLib"
+ PreprocessorDefinitions="WIN32;_DEBUG;_LIB;VIEW_BSP"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="5"
+ RuntimeTypeInfo="TRUE"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderFile=".\Debug/BspLib.pch"
+ AssemblerListingLocation=".\Debug/"
+ ObjectFile=".\Debug/"
+ ProgramDataBaseFileName=".\Debug/"
+ BrowseInformation="1"
+ WarningLevel="3"
+ SuppressStartupBanner="TRUE"
+ DebugInformationFormat="4"
+ CompileAs="0"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile=".\Debug\BspLib.lib"
+ SuppressStartupBanner="TRUE"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG"
+ Culture="3079"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory=".\Release"
+ IntermediateDirectory=".\Release"
+ ConfigurationType="4"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="FALSE"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ InlineFunctionExpansion="1"
+ AdditionalIncludeDirectories="..\BspLib;..\QvLib"
+ PreprocessorDefinitions="WIN32;NDEBUG;_LIB;VIEW_BSP"
+ StringPooling="TRUE"
+ RuntimeLibrary="4"
+ EnableFunctionLevelLinking="TRUE"
+ RuntimeTypeInfo="TRUE"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderFile=".\Release/BspLib.pch"
+ AssemblerListingLocation=".\Release/"
+ ObjectFile=".\Release/"
+ ProgramDataBaseFileName=".\Release/"
+ WarningLevel="3"
+ SuppressStartupBanner="TRUE"
+ CompileAs="0"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile=".\Release\BspLib.lib"
+ SuppressStartupBanner="TRUE"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG"
+ Culture="3079"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat">
+ <File
+ RelativePath="AodFormat.cpp">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BasicRuntimeChecks="3"
+ BrowseInformation="1"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="AodInput.cpp">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BasicRuntimeChecks="3"
+ BrowseInformation="1"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="AodOutput.cpp">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BasicRuntimeChecks="3"
+ BrowseInformation="1"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="BoundingBox.cpp">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BasicRuntimeChecks="3"
+ BrowseInformation="1"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="BRep.cpp">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BasicRuntimeChecks="3"
+ BrowseInformation="1"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="BspFormat.cpp">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BasicRuntimeChecks="3"
+ BrowseInformation="1"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="BspInput.cpp">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BasicRuntimeChecks="3"
+ BrowseInformation="1"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="BSPNode.cpp">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BasicRuntimeChecks="3"
+ BrowseInformation="1"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="BspObject.cpp">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BasicRuntimeChecks="3"
+ BrowseInformation="1"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="BspObjectList.cpp">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BasicRuntimeChecks="3"
+ BrowseInformation="1"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="BspOutput.cpp">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BasicRuntimeChecks="3"
+ BrowseInformation="1"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="BspTool.cpp">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BasicRuntimeChecks="3"
+ BrowseInformation="1"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="BSPTree.cpp">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BasicRuntimeChecks="3"
+ BrowseInformation="1"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="EpsAreas.cpp">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BasicRuntimeChecks="3"
+ BrowseInformation="1"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="Face.cpp">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BasicRuntimeChecks="3"
+ BrowseInformation="1"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="InputData3D.cpp">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BasicRuntimeChecks="3"
+ BrowseInformation="1"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="IOData3D.cpp">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BasicRuntimeChecks="3"
+ BrowseInformation="1"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="LineSeg.cpp">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BasicRuntimeChecks="3"
+ BrowseInformation="1"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="Mapping.cpp">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BasicRuntimeChecks="3"
+ BrowseInformation="1"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="ObjectAodFormat.cpp">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BasicRuntimeChecks="3"
+ BrowseInformation="1"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="ObjectBinFormat.cpp">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BasicRuntimeChecks="3"
+ BrowseInformation="1"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="ObjectBspFormat.cpp">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BasicRuntimeChecks="3"
+ BrowseInformation="1"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="ObjectBSPNode.cpp">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BasicRuntimeChecks="3"
+ BrowseInformation="1"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="OutputData3D.cpp">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BasicRuntimeChecks="3"
+ BrowseInformation="1"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="Polygon.cpp">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BasicRuntimeChecks="3"
+ BrowseInformation="1"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="PolygonList.cpp">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BasicRuntimeChecks="3"
+ BrowseInformation="1"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="SingleFormat.cpp">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BasicRuntimeChecks="3"
+ BrowseInformation="1"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="SingleInput.cpp">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BasicRuntimeChecks="3"
+ BrowseInformation="1"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="SingleOutput.cpp">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BasicRuntimeChecks="3"
+ BrowseInformation="1"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="SystemIO.cpp">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BasicRuntimeChecks="3"
+ BrowseInformation="1"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="Texture.cpp">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BasicRuntimeChecks="3"
+ BrowseInformation="1"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="Transform2.cpp">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BasicRuntimeChecks="3"
+ BrowseInformation="1"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="Transform3.cpp">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BasicRuntimeChecks="3"
+ BrowseInformation="1"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="TriMapping.cpp">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BasicRuntimeChecks="3"
+ BrowseInformation="1"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="Vertex.cpp">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BasicRuntimeChecks="3"
+ BrowseInformation="1"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="VertexChunk.cpp">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BasicRuntimeChecks="3"
+ BrowseInformation="1"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="VrmlFile.cpp">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BasicRuntimeChecks="3"
+ BrowseInformation="1"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""/>
+ </FileConfiguration>
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl">
+ <File
+ RelativePath="AodFormat.h">
+ </File>
+ <File
+ RelativePath="AodInput.h">
+ </File>
+ <File
+ RelativePath="AodOutput.h">
+ </File>
+ <File
+ RelativePath="BoundingBox.h">
+ </File>
+ <File
+ RelativePath="BRep.h">
+ </File>
+ <File
+ RelativePath="BspFormat.h">
+ </File>
+ <File
+ RelativePath="BspInput.h">
+ </File>
+ <File
+ RelativePath="BspLibDefs.h">
+ </File>
+ <File
+ RelativePath="BSPNode.h">
+ </File>
+ <File
+ RelativePath="BspObject.h">
+ </File>
+ <File
+ RelativePath="BspObjectList.h">
+ </File>
+ <File
+ RelativePath="BspOutput.h">
+ </File>
+ <File
+ RelativePath="BspTool.h">
+ </File>
+ <File
+ RelativePath="BSPTree.h">
+ </File>
+ <File
+ RelativePath="Chunk.h">
+ </File>
+ <File
+ RelativePath="Debug.h">
+ </File>
+ <File
+ RelativePath="Face.h">
+ </File>
+ <File
+ RelativePath="InputData3D.h">
+ </File>
+ <File
+ RelativePath="IOData3D.h">
+ </File>
+ <File
+ RelativePath="LineSeg2.h">
+ </File>
+ <File
+ RelativePath="LineSeg3.h">
+ </File>
+ <File
+ RelativePath="Mapping.h">
+ </File>
+ <File
+ RelativePath="Material.h">
+ </File>
+ <File
+ RelativePath="ObjectAodFormat.h">
+ </File>
+ <File
+ RelativePath="ObjectBinFormat.h">
+ </File>
+ <File
+ RelativePath="ObjectBspFormat.h">
+ </File>
+ <File
+ RelativePath="ObjectBSPNode.h">
+ </File>
+ <File
+ RelativePath="ObjectBSPTree.h">
+ </File>
+ <File
+ RelativePath="OutputData3D.h">
+ </File>
+ <File
+ RelativePath="Plane.h">
+ </File>
+ <File
+ RelativePath="Polygon.h">
+ </File>
+ <File
+ RelativePath="PolygonList.h">
+ </File>
+ <File
+ RelativePath="SingleFormat.h">
+ </File>
+ <File
+ RelativePath="SingleInput.h">
+ </File>
+ <File
+ RelativePath="SingleOutput.h">
+ </File>
+ <File
+ RelativePath="SystemIO.h">
+ </File>
+ <File
+ RelativePath="Texture.h">
+ </File>
+ <File
+ RelativePath="Transform2.h">
+ </File>
+ <File
+ RelativePath="Transform3.h">
+ </File>
+ <File
+ RelativePath="TriMapping.h">
+ </File>
+ <File
+ RelativePath="Vector.h">
+ </File>
+ <File
+ RelativePath="Vector2.h">
+ </File>
+ <File
+ RelativePath="Vector3.h">
+ </File>
+ <File
+ RelativePath="Vertex.h">
+ </File>
+ <File
+ RelativePath="Vertex2.h">
+ </File>
+ <File
+ RelativePath="Vertex3.h">
+ </File>
+ <File
+ RelativePath="VertexChunk.h">
+ </File>
+ <File
+ RelativePath="VrmlFile.h">
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/tool_src/BspLib/BspLib.vcxproj b/tool_src/BspLib/BspLib.vcxproj
new file mode 100755
index 0000000..f1133db
--- /dev/null
+++ b/tool_src/BspLib/BspLib.vcxproj
@@ -0,0 +1,385 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <SccProjectName>"$/ParsecTools/BspLib", KUFAAAAA</SccProjectName>
+ <SccLocalPath>.</SccLocalPath>
+ <ProjectGuid>{AA6FAB40-A936-486C-9DB0-1ADDFFCD4D00}</ProjectGuid>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <PlatformToolset>v110</PlatformToolset>
+ <UseOfMfc>false</UseOfMfc>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <PlatformToolset>v110</PlatformToolset>
+ <UseOfMfc>false</UseOfMfc>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <_ProjectFileVersion>11.0.50727.1</_ProjectFileVersion>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <OutDir>.\Debug\</OutDir>
+ <IntDir>.\Debug\</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <OutDir>.\Release\</OutDir>
+ <IntDir>.\Release\</IntDir>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\BspLib;..\QvLib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;VIEW_BSP;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+ <RuntimeTypeInfo>true</RuntimeTypeInfo>
+ <PrecompiledHeader />
+ <PrecompiledHeaderOutputFile>.\Debug/BspLib.pch</PrecompiledHeaderOutputFile>
+ <AssemblerListingLocation>.\Debug/</AssemblerListingLocation>
+ <ObjectFileName>.\Debug/</ObjectFileName>
+ <ProgramDataBaseFileName>.\Debug/</ProgramDataBaseFileName>
+ <BrowseInformation>true</BrowseInformation>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
+ <CompileAs>Default</CompileAs>
+ </ClCompile>
+ <Lib>
+ <OutputFile>.\Debug\BspLib.lib</OutputFile>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </Lib>
+ <ResourceCompile>
+ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Culture>0x0c07</Culture>
+ </ResourceCompile>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <Optimization>MaxSpeed</Optimization>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <AdditionalIncludeDirectories>..\BspLib;..\QvLib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;VIEW_BSP;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <RuntimeTypeInfo>true</RuntimeTypeInfo>
+ <PrecompiledHeader />
+ <PrecompiledHeaderOutputFile>.\Release/BspLib.pch</PrecompiledHeaderOutputFile>
+ <AssemblerListingLocation>.\Release/</AssemblerListingLocation>
+ <ObjectFileName>.\Release/</ObjectFileName>
+ <ProgramDataBaseFileName>.\Release/</ProgramDataBaseFileName>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <CompileAs>Default</CompileAs>
+ </ClCompile>
+ <Lib>
+ <OutputFile>.\Release\BspLib.lib</OutputFile>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </Lib>
+ <ResourceCompile>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Culture>0x0c07</Culture>
+ </ResourceCompile>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="AodFormat.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ </ClCompile>
+ <ClCompile Include="AodInput.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ </ClCompile>
+ <ClCompile Include="AodOutput.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ </ClCompile>
+ <ClCompile Include="BoundingBox.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ </ClCompile>
+ <ClCompile Include="BRep.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ </ClCompile>
+ <ClCompile Include="BspFormat.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ </ClCompile>
+ <ClCompile Include="BspInput.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ </ClCompile>
+ <ClCompile Include="BSPNode.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ </ClCompile>
+ <ClCompile Include="BspObject.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ </ClCompile>
+ <ClCompile Include="BspObjectList.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ </ClCompile>
+ <ClCompile Include="BspOutput.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ </ClCompile>
+ <ClCompile Include="BspTool.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ </ClCompile>
+ <ClCompile Include="BSPTree.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ </ClCompile>
+ <ClCompile Include="EpsAreas.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ </ClCompile>
+ <ClCompile Include="Face.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ </ClCompile>
+ <ClCompile Include="InputData3D.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ </ClCompile>
+ <ClCompile Include="IOData3D.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ </ClCompile>
+ <ClCompile Include="LineSeg.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ </ClCompile>
+ <ClCompile Include="Mapping.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ </ClCompile>
+ <ClCompile Include="ObjectAodFormat.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ </ClCompile>
+ <ClCompile Include="ObjectBinFormat.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ </ClCompile>
+ <ClCompile Include="ObjectBspFormat.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ </ClCompile>
+ <ClCompile Include="ObjectBSPNode.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ </ClCompile>
+ <ClCompile Include="OutputData3D.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ </ClCompile>
+ <ClCompile Include="Polygon.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ </ClCompile>
+ <ClCompile Include="PolygonList.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ </ClCompile>
+ <ClCompile Include="SingleFormat.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ </ClCompile>
+ <ClCompile Include="SingleInput.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ </ClCompile>
+ <ClCompile Include="SingleOutput.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ </ClCompile>
+ <ClCompile Include="SystemIO.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ </ClCompile>
+ <ClCompile Include="Texture.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ </ClCompile>
+ <ClCompile Include="Transform2.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ </ClCompile>
+ <ClCompile Include="Transform3.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ </ClCompile>
+ <ClCompile Include="TriMapping.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ </ClCompile>
+ <ClCompile Include="Vertex.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ </ClCompile>
+ <ClCompile Include="VertexChunk.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ </ClCompile>
+ <ClCompile Include="VrmlFile.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="AodFormat.h" />
+ <ClInclude Include="AodInput.h" />
+ <ClInclude Include="AodOutput.h" />
+ <ClInclude Include="BoundingBox.h" />
+ <ClInclude Include="BRep.h" />
+ <ClInclude Include="BspFormat.h" />
+ <ClInclude Include="BspInput.h" />
+ <ClInclude Include="BspLibDefs.h" />
+ <ClInclude Include="BSPNode.h" />
+ <ClInclude Include="BspObject.h" />
+ <ClInclude Include="BspObjectList.h" />
+ <ClInclude Include="BspOutput.h" />
+ <ClInclude Include="BspTool.h" />
+ <ClInclude Include="BSPTree.h" />
+ <ClInclude Include="Chunk.h" />
+ <ClInclude Include="Debug.h" />
+ <ClInclude Include="Face.h" />
+ <ClInclude Include="InputData3D.h" />
+ <ClInclude Include="IOData3D.h" />
+ <ClInclude Include="LineSeg2.h" />
+ <ClInclude Include="LineSeg3.h" />
+ <ClInclude Include="Mapping.h" />
+ <ClInclude Include="Material.h" />
+ <ClInclude Include="ObjectAodFormat.h" />
+ <ClInclude Include="ObjectBinFormat.h" />
+ <ClInclude Include="ObjectBspFormat.h" />
+ <ClInclude Include="ObjectBSPNode.h" />
+ <ClInclude Include="ObjectBSPTree.h" />
+ <ClInclude Include="OutputData3D.h" />
+ <ClInclude Include="Plane.h" />
+ <ClInclude Include="Polygon.h" />
+ <ClInclude Include="PolygonList.h" />
+ <ClInclude Include="SingleFormat.h" />
+ <ClInclude Include="SingleInput.h" />
+ <ClInclude Include="SingleOutput.h" />
+ <ClInclude Include="SystemIO.h" />
+ <ClInclude Include="Texture.h" />
+ <ClInclude Include="Transform2.h" />
+ <ClInclude Include="Transform3.h" />
+ <ClInclude Include="TriMapping.h" />
+ <ClInclude Include="Vector.h" />
+ <ClInclude Include="Vector2.h" />
+ <ClInclude Include="Vector3.h" />
+ <ClInclude Include="Vertex.h" />
+ <ClInclude Include="Vertex2.h" />
+ <ClInclude Include="Vertex3.h" />
+ <ClInclude Include="VertexChunk.h" />
+ <ClInclude Include="VrmlFile.h" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/tool_src/BspLib/BspLib.vcxproj.filters b/tool_src/BspLib/BspLib.vcxproj.filters
new file mode 100755
index 0000000..6ba47a2
--- /dev/null
+++ b/tool_src/BspLib/BspLib.vcxproj.filters
@@ -0,0 +1,272 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="Source Files">
+ <UniqueIdentifier>{b92e77c0-0c19-4232-b527-b92d163e8f85}</UniqueIdentifier>
+ <Extensions>cpp;c;cxx;rc;def;r;odl;idl;hpj;bat</Extensions>
+ </Filter>
+ <Filter Include="Header Files">
+ <UniqueIdentifier>{3965bcee-c821-4b2c-a5df-99b4f75d7faf}</UniqueIdentifier>
+ <Extensions>h;hpp;hxx;hm;inl</Extensions>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="AodFormat.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="AodInput.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="AodOutput.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="BoundingBox.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="BRep.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="BspFormat.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="BspInput.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="BSPNode.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="BspObject.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="BspObjectList.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="BspOutput.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="BspTool.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="BSPTree.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="EpsAreas.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="Face.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="InputData3D.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="IOData3D.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="LineSeg.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="Mapping.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="ObjectAodFormat.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="ObjectBinFormat.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="ObjectBspFormat.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="ObjectBSPNode.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="OutputData3D.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="Polygon.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="PolygonList.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="SingleFormat.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="SingleInput.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="SingleOutput.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="SystemIO.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="Texture.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="Transform2.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="Transform3.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="TriMapping.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="Vertex.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="VertexChunk.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="VrmlFile.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="AodFormat.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="AodInput.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="AodOutput.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="BoundingBox.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="BRep.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="BspFormat.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="BspInput.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="BspLibDefs.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="BSPNode.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="BspObject.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="BspObjectList.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="BspOutput.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="BspTool.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="BSPTree.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="Chunk.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="Debug.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="Face.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="InputData3D.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="IOData3D.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="LineSeg2.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="LineSeg3.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="Mapping.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="Material.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="ObjectAodFormat.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="ObjectBinFormat.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="ObjectBspFormat.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="ObjectBSPNode.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="ObjectBSPTree.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="OutputData3D.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="Plane.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="Polygon.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="PolygonList.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="SingleFormat.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="SingleInput.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="SingleOutput.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="SystemIO.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="Texture.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="Transform2.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="Transform3.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="TriMapping.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="Vector.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="Vector2.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="Vector3.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="Vertex.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="Vertex2.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="Vertex3.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="VertexChunk.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="VrmlFile.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/tool_src/BspLib/BspLib.vcxproj.user b/tool_src/BspLib/BspLib.vcxproj.user
new file mode 100755
index 0000000..a375ae3
--- /dev/null
+++ b/tool_src/BspLib/BspLib.vcxproj.user
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup />
+</Project> \ No newline at end of file
diff --git a/tool_src/BspLib/BspLibDefs.h b/tool_src/BspLib/BspLibDefs.h
new file mode 100644
index 0000000..c6daca8
--- /dev/null
+++ b/tool_src/BspLib/BspLibDefs.h
@@ -0,0 +1,163 @@
+//-----------------------------------------------------------------------------
+// BSPLIB HEADER: BspLibDefs.h
+//
+// Copyright (c) 1996-1998 by Markus Hadwiger
+// All Rights Reserved.
+//-----------------------------------------------------------------------------
+
+#ifndef _BSPLIBDEFS_H_
+#define _BSPLIBDEFS_H_
+
+
+// standard C library headers -------------------------------------------------
+#include <ctype.h>
+#include <errno.h>
+#include <limits.h>
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdint.h>
+#include <stddef.h>
+
+
+// various build dependent macros ---------------------------------------------
+#ifdef _DEBUG
+
+#define PUBLIC
+#define PRIVATE static
+#define D(x) x
+#define CHECK_DEREFERENCING(x) x
+
+#else
+
+#define PUBLIC
+#define PRIVATE static
+#define D(x)
+#define CHECK_DEREFERENCING(x) x
+
+#endif
+
+
+// define NAMESPACE usage -----------------------------------------------------
+#define USE_BSPLIB_NAMESPACE
+
+#ifdef USE_BSPLIB_NAMESPACE
+
+#define BSPLIB_NAMESPACE BspLib
+#define BSPLIB_NAMESPACE_BEGIN namespace BSPLIB_NAMESPACE {
+#define BSPLIB_NAMESPACE_END }
+
+#else
+
+#define BSPLIB_NAMESPACE
+#define BSPLIB_NAMESPACE_BEGIN
+#define BSPLIB_NAMESPACE_END
+
+#endif
+
+
+#ifndef _WIN32
+ #define stricmp strcasecmp
+ #define strnicmp strncasecmp
+#endif
+
+
+// MS VC++ specific macros ----------------------------------------------------
+#ifdef _MSC_VER
+#define PATH_MAX _MAX_PATH
+#endif
+#define _CRT_SECURE_NO_WARNINGS 1
+
+
+// boolean values -------------------------------------------------------------
+#define TRUE 1
+#define FALSE 0
+
+// asm types ------------------------------------------------------------------
+typedef uint8_t byte;
+typedef uint16_t word;
+typedef uint32_t dword;
+
+// data types for coordinates -------------------------------------------------
+typedef int32_t fixed_t;
+typedef double hprec_t;
+
+// conversion macros for 3 and 2 digit values ---------------------------------
+#define DIG3_TO_STR( s, a ) (s)[0]=(((a)/100)%10)+'0';\
+ (s)[1]=(((a)/10)%10)+'0'; \
+ (s)[2]=((a)%10)+'0'; \
+ (s)[3]='\0';
+
+#define DIG2_TO_STR( s, a ) (s)[0]=(((a)/10)%10)+'0'; \
+ (s)[1]=((a)%10)+'0'; \
+ (s)[2]='\0';
+
+
+// some general structures ----------------------------------------------------
+//
+BSPLIB_NAMESPACE_BEGIN
+
+
+// RGB color triplet using bytes as members -----------------------------------
+struct ColorRGB {
+ byte R;
+ byte G;
+ byte B;
+};
+
+// RGB color triplet plus alpha using bytes as members ------------------------
+struct ColorRGBA {
+ byte R;
+ byte G;
+ byte B;
+ byte A;
+};
+
+// RGB color triplet using floats as members ----------------------------------
+struct ColorRGBf {
+ float R;
+ float G;
+ float B;
+};
+
+// RGB color triplet plus alpha using floats as members -----------------------
+struct ColorRGBAf {
+ float R;
+ float G;
+ float B;
+ float A;
+};
+
+
+// epsilon area specifications ------------------------------------------------
+//
+#define EPS_SCALAR EpsAreas::eps_scalarproduct
+#define EPS_COMP_ZERO EpsAreas::eps_vanishcomponent
+#define EPS_DENOM_ZERO EpsAreas::eps_vanishdenominator
+#define EPS_POINT_ON_PLANE EpsAreas::eps_planethickness
+#define EPS_POINT_ON_LINE EpsAreas::eps_pointonline
+#define EPS_POINT_ON_LINESEG EpsAreas::eps_pointonlineseg
+#define EPS_VERTEX_MERGE EpsAreas::eps_vertexmergearea
+
+class EpsAreas {
+
+public:
+ static double eps_scalarproduct; // epsilon area for general scalar product comparisons
+ static double eps_vanishcomponent; // epsilon area for vanishing vector components
+ static double eps_vanishdenominator; // epsilon area for vanishing denominators
+ static double eps_planethickness; // epsilon area for width of "infinitely thin" plane
+ static double eps_pointonline; // epsilon area for point on line determination
+ static double eps_pointonlineseg; // epsilon area for point on lineseg parameter (t)
+ static double eps_vertexmergearea; // epsilon area for merging of vertices
+};
+
+
+BSPLIB_NAMESPACE_END
+
+
+#endif // _BSPLIBDEFS_H_
+
+
+
+
diff --git a/tool_src/BspLib/BspObject.cpp b/tool_src/BspLib/BspObject.cpp
new file mode 100644
index 0000000..688c2c0
--- /dev/null
+++ b/tool_src/BspLib/BspObject.cpp
@@ -0,0 +1,641 @@
+//-----------------------------------------------------------------------------
+// BSPLIB MODULE: BspObject.cpp
+//
+// Copyright (c) 1996-1998 by Markus Hadwiger
+// All Rights Reserved.
+//-----------------------------------------------------------------------------
+
+// bsplib header files
+#include "BspObject.h"
+#include "BoundingBox.h"
+#include "IOData3D.h"
+
+
+BSPLIB_NAMESPACE_BEGIN
+
+// flags
+#define NO_CONSISTENCY_CHECKS
+
+
+// constructor for BspObjectInfo ----------------------------------------------
+//
+BspObjectInfo::BspObjectInfo()
+{
+ numvertices = 0;
+ numpolygons = 0;
+ numfaces = 0;
+ numtextures = 0;
+ numcorrespondences = 0;
+
+ numnormals = 0;
+ numtexmappedfaces = 0;
+
+ numvertices_in = 0;
+ numpolygons_in = 0;
+ numfaces_in = 0;
+
+ numbsppolygons = 0;
+ numpolygons_before_bsp = 0;
+
+ numtracevertices = 0;
+ nummultvertices = 0;
+ numsplitquadrilaterals = 0;
+}
+
+
+// constructor for BspObject --------------------------------------------------
+//
+BspObject::BspObject() : polygonlist( this )
+{
+ objectname = NULL; // no object name attached
+ next = NULL; // empty list
+ objecttrafo.LoadIdentity(); // load identity transformation
+}
+
+
+// set object's name (string is copied into the object!) ----------------------
+//
+void BspObject::setObjectName( char *name )
+{
+ delete objectname;
+ if ( name != NULL ) {
+ objectname = new char[ strlen( name ) + 1 ];
+ strcpy( objectname, name );
+ } else {
+ objectname = NULL;
+ }
+}
+
+
+// convert all faces with colorindexes to rgb triplets ------------------------
+//
+int BspObject::ConvertColorIndexesToRGB( char *palette, int changemode )
+{
+ int did_convert = FALSE;
+ for ( int i = 0; i < facelist.getNumElements(); i++ )
+ if ( facelist[ i ].ConvertColorIndexToRGB( palette, changemode ) )
+ did_convert = TRUE;
+ return did_convert;
+}
+
+
+// print inconsistency error message ------------------------------------------
+//
+void BspObject::InconsistencyError( const char *err )
+{
+ if ( err != NULL ) {
+ StrScratch message;
+ sprintf( message, "**ERROR** [Inconsistencies]: %s", err );
+ ErrorMessage( message );
+ }
+ HandleCriticalError();
+}
+
+
+// update entity counts of contained attribute lists --------------------------
+//
+void BspObject::UpdateAttributeNumbers()
+{
+ numvertices = vertexlist.getNumElements();
+ numpolygons = polygonlist.getNumElements();
+ numfaces = facelist.getNumElements();
+ numtextures = texturelist.getNumElements();
+ numcorrespondences = mappinglist.getNumElements();
+
+ numnormals = 0;
+ numtexmappedfaces = 0;
+
+ for ( int i = 0; i < numfaces; i++ ) {
+ // count number of faces with already calculated normals
+ if ( facelist[ i ].NormalValid() )
+ numnormals++;
+ // count number of texture mapped faces
+ if ( facelist[ i ].FaceTexMapped() )
+ numtexmappedfaces++;
+ }
+}
+
+
+// process data immediately after parse was done ------------------------------
+//
+void BspObject::CheckParsedData()
+{
+ // calculate entity counts
+ UpdateAttributeNumbers();
+
+ // remember number of input entities
+ numvertices_in = numvertices;
+ numpolygons_in = numpolygons;
+ numfaces_in = numfaces;
+
+#if !defined( NO_CONSISTENCY_CHECKS ) && !defined( VIEW_BSP )
+
+ // consistency checks
+ if ( numpolygons != numfaces )
+ InconsistencyError( "properties must be defined for every face!" );
+ if ( numcorrespondences != numtexmappedfaces )
+ InconsistencyError( "mapping must be specified for every texturemapped face!" );
+#endif
+
+}
+
+
+// display statistics (number of vertices, faces, polygons, etc.) -------------
+//
+void BspObject::DisplayStatistics()
+{
+ UpdateAttributeNumbers();
+
+ StrScratch message;
+ sprintf( message, "\n--- Statistics ---------------------\n" );
+
+#define sprintf InfoMessage( message ); sprintf
+
+ sprintf( message, "\nINPUT\n" );
+ sprintf( message, " Vertices = %d\n", numvertices_in );
+ sprintf( message, " Faces = %d\n", numfaces_in );
+ sprintf( message, " Polygons = %d\n", numpolygons_in );
+
+ sprintf( message, "\nOUTPUT\n" );
+ sprintf( message, " Vertices = %d\n", numvertices );
+ sprintf( message, " Faces = %d\n", numfaces );
+ sprintf( message, " Polygons = %d\n", numbsppolygons );
+
+ sprintf( message, "\nGENERAL\n" );
+ sprintf( message, " Textures = %d\n", numtextures );
+ sprintf( message, " TexFaces = %d\n", numtexmappedfaces );
+
+ sprintf( message, "\nANALYSIS\n" );
+ sprintf( message, " Inserted vertices = %d\n", numvertices - numvertices_in );
+ sprintf( message, " Inserted polygons = %d (%d split by bsp; %d split as quadrilateral)\n",
+ numbsppolygons - numpolygons_in,
+ numbsppolygons - numpolygons_in - numsplitquadrilaterals,
+ numsplitquadrilaterals );
+ sprintf( message, " Tracevertices = %d\n", numtracevertices );
+ sprintf( message, " Multiple vertices = %d\n", nummultvertices );
+
+ sprintf( message, "\n------------------------------------\n\n" );
+ InfoMessage( message );
+
+#undef sprintf
+
+}
+
+
+// scale entire object (correct vertices and mappings) ------------------------
+//
+void BspObject::ApplyScale( double scalefac )
+{
+ // scale entire vertex list
+ numvertices = vertexlist.getNumElements();
+ int i = 0;
+ for ( i = 0; i < numvertices; i++ ) {
+ vertexlist[ i ].setX( vertexlist[ i ].getX() * scalefac );
+ vertexlist[ i ].setY( vertexlist[ i ].getY() * scalefac );
+ vertexlist[ i ].setZ( vertexlist[ i ].getZ() * scalefac );
+ }
+ // scale (x,y,z) part of mappings
+ numfaces = facelist.getNumElements();
+ for ( i = 0; i < numfaces; i++ ) {
+ if ( facelist[ i ].MappingAttached() ) {
+ for ( int j = 0; j < 3; j++ ) {
+ Vertex2 vtx = facelist[ i ].MapXY( j );
+ vtx.setX( vtx.getX() * scalefac );
+ vtx.setY( vtx.getY() * scalefac );
+ vtx.setW( vtx.getW() * scalefac );
+ facelist[ i ].MapXY( j ) = vtx;
+ }
+ }
+ }
+}
+
+
+// apply translation to all coordinates and set center to (0,0,0) -------------
+//
+void BspObject::ApplyCenter()
+{
+ // get center
+ Vector3 cvec = objecttrafo.ExtractTranslation();
+ double cx = cvec.getX();
+ double cy = cvec.getY();
+ double cz = cvec.getZ();
+
+ // translate all vertices
+ numvertices = vertexlist.getNumElements();
+ for ( int i = 0; i < numvertices; i++ ) {
+ vertexlist[ i ].setX( vertexlist[ i ].getX() + cx );
+ vertexlist[ i ].setY( vertexlist[ i ].getY() + cy );
+ vertexlist[ i ].setZ( vertexlist[ i ].getZ() + cz );
+ }
+}
+
+
+// apply transformation matrix and set to identity afterwards -----------------
+//
+void BspObject::ApplyTransformation()
+{
+ // transform all vertices
+ numvertices = vertexlist.getNumElements();
+ for ( int i = 0; i < numvertices; i++ ) {
+ vertexlist[ i ] = objecttrafo.TransformVector3( vertexlist[ i ] );
+ }
+
+ objecttrafo.LoadIdentity();
+}
+
+
+// calculate axial bounding box -----------------------------------------------
+//
+void BspObject::CalcBoundingBox( Vertex3& minvertex, Vertex3& maxvertex )
+{
+ //NOTE:
+ // if a transformation is attached, only the translation is
+ // taken into account. so, the bounding box is not correct if,
+ // for instance, a rotation is attached.
+ // thus, ApplyTransformation() is normally invoked before
+ // bounding boxes are calculated.
+
+ // fetch object's location in world space
+ Vector3 worldcenter = objecttrafo.FetchTranslation();
+
+ if ( ( numvertices = vertexlist.getNumElements() ) < 1 ) {
+ minvertex = worldcenter;
+ maxvertex = worldcenter;
+ return;
+ }
+
+ // start with first vertex
+ minvertex = vertexlist[ 0 ];
+ maxvertex = vertexlist[ 0 ];
+
+ // test all other vertices
+ for ( int i = 1; i < numvertices; i++ ) {
+ Vertex3& testvertex = vertexlist[ i ];
+
+ if ( testvertex.getX() < minvertex.getX() )
+ minvertex.setX( testvertex.getX() );
+ if ( testvertex.getY() < minvertex.getY() )
+ minvertex.setY( testvertex.getY() );
+ if ( testvertex.getZ() < minvertex.getZ() )
+ minvertex.setZ( testvertex.getZ() );
+
+ if ( testvertex.getX() > maxvertex.getX() )
+ maxvertex.setX( testvertex.getX() );
+ if ( testvertex.getY() > maxvertex.getY() )
+ maxvertex.setY( testvertex.getY() );
+ if ( testvertex.getZ() > maxvertex.getZ() )
+ maxvertex.setZ( testvertex.getZ() );
+ }
+
+ minvertex += worldcenter;
+ maxvertex += worldcenter;
+}
+
+
+// check planes of all polygons contained in polygonlist ----------------------
+//
+void BspObject::CheckPolygonPlanes()
+{
+ // scan linear polygon list and check planes of all polygons
+ polygonlist.CheckPolygonPlanes();
+
+ // counts have to be updated; CheckPolygonPlanes() may have
+ // created new vertices, polygons, and faces
+ UpdateAttributeNumbers();
+
+ if( numnormals != numfaces ) {
+ ErrorMessage( "***ERROR*** Inconsistencies in normals!" );
+ HandleCriticalError();
+ }
+
+ if ( numsplitquadrilaterals > 0 ) {
+ StrScratch message;
+ sprintf( message, "\n%d quadrilaterals were split into triangles.\n",
+ numsplitquadrilaterals );
+ InfoMessage( message );
+ }
+}
+
+
+// check for multiple vertices in vertexlist ----------------------------------
+//
+void BspObject::CheckVertices( int verbose )
+{
+ // determine number of equal vertices in vertexlist
+ nummultvertices = vertexlist.CheckVertices( verbose );
+}
+
+
+// calculate bounding boxes for all nodes of bsp tree -------------------------
+//
+void BspObject::CalcBoundingBoxes()
+{
+ if ( !bsptree.TreeEmpty() ) {
+ InfoMessage( "\nCalculating bounding boxes for bsp-tree nodes...\n" );
+ bsptree->CalcBoundingBoxes();
+ }
+}
+
+
+// calculate separator planes for all polygon-nodes of bsp tree ---------------
+//
+void BspObject::CalcSeparatorPlanes()
+{
+ if ( !bsptree.TreeEmpty() ) {
+ InfoMessage( "\nCalculating explicit separator planes for bsp-tree nodes...\n" );
+ bsptree->CalcSeparatorPlanes();
+ }
+}
+
+
+// check edges of polygons contained in bsp tree for t-vertices ---------------
+//
+void BspObject::CheckEdges()
+{
+ if ( !bsptree.TreeEmpty() ) {
+ InfoMessage( "\nChecking edges of bsp-tree polygons...\n" );
+ bsptree->CheckEdges();
+ }
+}
+
+
+// calculate plane normals for all polygons -----------------------------------
+//
+void BspObject::CalcPlaneNormals()
+{
+ // scan linear polygon list and calculate normals for all polygons
+ polygonlist.CalcPlaneNormals();
+}
+
+
+// build a list of bounding boxes containing all objects of list --------------
+//
+BoundingBox *BspObject::BuildBoundingBoxList()
+{
+ // build bounding box list as secondary data structure.
+ // there is a bounding box for every object; order is reversed!
+ BoundingBox *headbox = NULL;
+ for ( BspObject *obj = this; obj; obj = obj->getNext() ) {
+ headbox = new BoundingBox( obj, headbox );
+ }
+
+ return headbox;
+}
+
+
+// build bsp tree and store pointer into object structure ---------------------
+//
+BSPNode *BspObject::BuildBSPTree()
+{
+ if ( bsptree.TreeEmpty() ) {
+ InfoMessage( "\nCompiling bsp tree...\n" );
+ numpolygons_before_bsp = numpolygons;
+ bsptree.InitTree( polygonlist.PartitionSpace() );
+ }
+
+ return bsptree.getRoot();
+}
+
+
+// build linked bsp tree from flat bsp tree -----------------------------------
+//
+BSPNode *BspObject::BuildBSPTreeFromFlat()
+{
+ if ( bsptree.TreeEmpty() ) {
+ InfoMessage( "\nBuilding linked bsp-tree from flat representation...\n" );
+ bsptree.InitTree( bsptreeflat.BuildBSPTree( 1 ) );
+ // linear list of polygons is not valid anymore!
+ polygonlist.InvalidateList();
+ }
+
+ return bsptree.getRoot();
+}
+
+
+// determine if linked bsp tree is available (non-empty) ----------------------
+//
+int BspObject::BSPTreeAvailable()
+{
+ return !bsptree.TreeEmpty();
+}
+
+
+// determine if flat bsp tree is available (non-empty) ------------------------
+//
+int BspObject::BSPTreeFlatAvailable()
+{
+ return !bsptreeflat.TreeEmpty();
+}
+
+
+// determine if any bsp tree is available (non-empty) -------------------------
+//
+int BspObject::BspTreeAvailable()
+{
+ return ( BSPTreeAvailable() || BSPTreeFlatAvailable() );
+}
+
+
+// merge another BspObject into this object (corrects everything necessary) ---
+//
+void BspObject::MergeObjects( BspObject *mergeobj )
+{
+ if ( mergeobj != NULL ) {
+
+ if ( !check_vertex_doublets_on_merge ) {
+
+ // merge vertex lists
+ int numsourcevertices = vertexlist.getNumElements();
+ int nummergevertices = mergeobj->vertexlist.getNumElements();
+ int i = 0;
+ for ( i = 0; i < nummergevertices; i++ ) {
+ vertexlist.AddVertex( mergeobj->vertexlist[ i ] );
+ }
+ numvertices += nummergevertices;
+ numvertices_in += mergeobj->numvertices_in;
+
+ // merge face lists
+ int numsourcefaces = facelist.getNumElements();
+ int nummergefaces = mergeobj->facelist.getNumElements();
+ for ( i = 0; i < nummergefaces; i++ ) {
+ Face& mergeface = mergeobj->facelist[ i ];
+ mergeface.setId( mergeface.getId() + numsourcefaces );
+ facelist.AddElement( mergeface );
+ }
+ numfaces += nummergefaces;
+ numfaces_in += mergeobj->numfaces_in;
+
+ // correct all polygons
+ if ( !mergeobj->BSPTreeAvailable() ) {
+ // correct entire polygon list
+ Polygon *polylist = mergeobj->polygonlist.FetchHead();
+ for ( ; polylist; polylist = polylist->getNext() )
+ polylist->CorrectBase( this, numsourcevertices, numsourcefaces, numpolygons );
+ numpolygons += mergeobj->numpolygons;
+ numpolygons_in += mergeobj->numpolygons_in;
+ // merge polygon lists
+ polygonlist.MergeLists( &mergeobj->polygonlist );
+ } else {
+ // correct all polygons contained in bsp tree
+ mergeobj->bsptree->CorrectPolygonBases( this, numsourcevertices, numsourcefaces, numbsppolygons );
+ numbsppolygons += mergeobj->numbsppolygons;
+ numpolygons_in += mergeobj->numpolygons_in;
+
+ //NOTE:
+ // the bsp trees themselves are not merged! no polygonlist is
+ // copied over, since it is empty. the bsp trees have to be
+ // merged somewhere else, to take over the polygons and the
+ // bsp tree structure!
+ }
+
+ } else {
+
+ //NOTE:
+ // this is the merging code that assumes that many vertices
+ // in the two objects are potentially exactly identical.
+ // therefore, the vertexlists are checked for doublets and
+ // vertex indexes contained in polygons are corrected thusly.
+ // since this normally is not necessary, the code is brute
+ // force, yielding quadratic performance!!
+ // however, in vrml files this may be a frequent case! if
+ // a connected object is saved as separate objects (e.g., to
+ // use more than one texture) the entire vertex list is often
+ // instanced via USE at each of these objects. this yields
+ // many objects with identical vertex lists.
+
+ // merge vertex lists and alloc index mapping table
+ int numsourcevertices = vertexlist.getNumElements();
+ int nummergevertices = mergeobj->vertexlist.getNumElements();
+ int numinsertvertices = 0;
+ int numinsertoriginal = 0;
+ int *indxmap = new int[ nummergevertices ];
+ int i = 0;
+ int j = 0;
+ for ( i = 0; i < nummergevertices; i++ ) {
+ for ( j = 0; j < numsourcevertices; j++ )
+ if ( vertexlist[ j ] == mergeobj->vertexlist[ i ] ) {
+ indxmap[ i ] = j;
+ break;
+ }
+ if ( j == numsourcevertices ) {
+ indxmap[ i ] = vertexlist.getNumElements();
+ vertexlist.AddVertex( mergeobj->vertexlist[ i ] );
+ numinsertvertices++;
+ if ( i < mergeobj->numvertices_in )
+ numinsertoriginal++;
+ }
+ }
+ numvertices += numinsertvertices;
+ numvertices_in += numinsertoriginal;
+
+ // merge face lists
+ int numsourcefaces = facelist.getNumElements();
+ int nummergefaces = mergeobj->facelist.getNumElements();
+ for ( i = 0; i < nummergefaces; i++ ) {
+ Face& mergeface = mergeobj->facelist[ i ];
+ mergeface.setId( mergeface.getId() + numsourcefaces );
+ facelist.AddElement( mergeface );
+ }
+ numfaces += nummergefaces;
+ numfaces_in += mergeobj->numfaces_in;
+
+ // correct all polygons
+ if ( !mergeobj->BSPTreeAvailable() ) {
+ // correct entire polygon list
+ Polygon *polylist = mergeobj->polygonlist.FetchHead();
+ for ( ; polylist; polylist = polylist->getNext() )
+ polylist->CorrectBaseByTable( this, indxmap, numsourcefaces, numpolygons );
+ numpolygons += mergeobj->numpolygons;
+ numpolygons_in += mergeobj->numpolygons_in;
+ // merge polygon lists
+ polygonlist.MergeLists( &mergeobj->polygonlist );
+ } else {
+ // correct all polygons contained in bsp tree
+ mergeobj->bsptree->CorrectPolygonBasesByTable( this, indxmap, numsourcefaces, numbsppolygons );
+ numbsppolygons += mergeobj->numbsppolygons;
+ numpolygons_in += mergeobj->numpolygons_in;
+ }
+
+ // free vertex index map
+ delete indxmap;
+ }
+
+ // merge texture lists
+ int numsourcetextures = texturelist.getNumElements();
+ int nummergetextures = mergeobj->texturelist.getNumElements();
+ int i = 0;
+ int j = 0;
+ for ( i = 0; i < nummergetextures; i++ ) {
+ //NOTE:
+ // terribly inefficient implementation. normally, number of
+ // textures should be very low. if this is not the case this
+ // may take considerable processing time!
+ for ( j = 0; j < numsourcetextures; j++ )
+ if ( strcmp( texturelist[ j ].getName(), mergeobj->texturelist[ i ].getName() ) == 0 )
+ break;
+ if ( j == numsourcetextures )
+ texturelist.AddElement( mergeobj->texturelist[ i ] );
+ }
+ numtextures += nummergetextures;
+
+ //NOTE:
+ // mappinglists need not be merged, since they are only temporarily
+ // used before complete face definitions are built. actual texture
+ // parameterization is a part of each face!
+
+ // add up other counts
+ numcorrespondences += mergeobj->numcorrespondences;
+ numnormals += mergeobj->numnormals;
+ numtexmappedfaces += mergeobj->numtexmappedfaces;
+ numtracevertices += mergeobj->numtracevertices;
+ nummultvertices += mergeobj->nummultvertices;
+ numsplitquadrilaterals += mergeobj->numsplitquadrilaterals;
+ numpolygons_before_bsp += mergeobj->numpolygons_before_bsp;
+ }
+
+}
+
+
+// collapse entire list of BspObjects into this object ------------------------
+//
+void BspObject::CollapseObjectList()
+{
+ //NOTE:
+ // this function only works if no bsp trees have been built yet!
+ // if bsp trees have already been built, ObjectBSPNode::CreateMergedBSPTree()
+ // may be used to merge all objects and bsp trees into one.
+
+ // exit if bsp tree available
+ if ( BspTreeAvailable() )
+ return;
+ BspObject *curobj = NULL;
+ curobj = getNext();
+ // merge all subsequent objects into this object
+ for ( curobj = curobj; curobj; curobj = curobj->getNext() ) {
+ MergeObjects( curobj );
+
+ // invalidate other object's polygonlist
+ curobj->getPolygonList().InvalidateList();
+
+ //NOTE:
+ // the polygon list must be invalidated prior to deletion
+ // because the actual polygons are now part of this object
+ // and therefore still in use!
+ }
+
+ // delete all objects that have been merged into this object
+ delete next;
+ next = NULL;
+
+ UpdateAttributeNumbers();
+}
+
+
+// static flags ---------------------------------------------------------------
+//
+int BspObject::check_vertex_doublets_on_merge = TRUE;
+
+
+BSPLIB_NAMESPACE_END
+
+//-----------------------------------------------------------------------------
diff --git a/tool_src/BspLib/BspObject.h b/tool_src/BspLib/BspObject.h
new file mode 100644
index 0000000..c2dfdd8
--- /dev/null
+++ b/tool_src/BspLib/BspObject.h
@@ -0,0 +1,258 @@
+//-----------------------------------------------------------------------------
+// BSPLIB HEADER: BspObject.h
+//
+// Copyright (c) 1996-1998 by Markus Hadwiger
+// All Rights Reserved.
+//-----------------------------------------------------------------------------
+
+#ifndef _BSPOBJECT_H_
+#define _BSPOBJECT_H_
+
+// bsplib header files
+#include "BspLibDefs.h"
+#include "SystemIO.h"
+#include "Chunk.h"
+#include "Face.h"
+#include "Mapping.h"
+#include "PolygonList.h"
+#include "BSPTree.h"
+#include "Texture.h"
+#include "Transform3.h"
+#include "Vertex.h"
+
+
+BSPLIB_NAMESPACE_BEGIN
+
+
+class BoundingBox;
+
+
+// base class for BspObject providing data members ----------------------------
+//
+class BspObjectInfo {
+
+ friend class BspObject;
+
+private:
+ BspObjectInfo();
+ ~BspObjectInfo() { }
+
+public:
+ int getNumVertices() const { return numvertices; }
+ int getNumPolygons() const { return numpolygons; }
+ int getNumFaces() const { return numfaces; }
+
+ int getInputVertices() const { return numvertices_in; }
+ int getInputPolygons() const { return numpolygons_in; }
+ int getInputFaces() const { return numfaces_in; }
+
+ int getBspPolygons() const { return numbsppolygons; }
+ int getPreBspPolygons() const { return numpolygons_before_bsp; }
+
+ int getNumTextures() const { return numtextures; }
+ int getNumMappings() const { return numcorrespondences; }
+ int getNumNormals() const { return numnormals; }
+ int getNumTexturedFaces() const { return numtexmappedfaces; }
+
+ int getNumTraceVertices() const { return numtracevertices; }
+ int getNumMultiVertices() const { return nummultvertices; }
+ int getNumSplitQuads() const { return numsplitquadrilaterals; }
+
+protected:
+ int numvertices; // number of vertices in vertexlist
+ int numpolygons; // number of polygons in polygonlist
+ int numfaces; // number of faces in facelist
+ int numtextures; // number of textures in texturelist
+ int numcorrespondences; // number of correspondences in mappinglist
+
+ int numnormals; // number of faces with valid normals
+ int numtexmappedfaces; // number of texture mapped faces
+
+ int numvertices_in; // copy of numvertices directly after parse
+ int numpolygons_in; // copy of numpolygons directly after parse
+ int numfaces_in; // copy of numfaces directly after parse
+
+ int numbsppolygons; // number of polygons contained in bsp tree
+ int numpolygons_before_bsp; // copy of numpolygons before start of bsp compilation
+
+ int numtracevertices; // number of vertices for edge tracing
+ int nummultvertices; // number of multiply contained vertices
+ int numsplitquadrilaterals; // number of quadrilaterals split into triangles
+};
+
+
+// class describing a generic 3-D object in BspLib ----------------------------
+//
+class BspObject : public BspObjectInfo, public virtual SystemIO {
+
+ friend class BoundingBox;
+ friend class BspObjectListRep;
+ friend class Face;
+ friend class ObjectBSPNode;
+ friend class Polygon;
+
+ friend class VrmlFile;
+
+public:
+ BspObject();
+ ~BspObject() { delete objectname; delete next; }
+
+ BspObject( const BspObject& copyobj );
+ BspObject& operator =( const BspObject& copyobj );
+
+ // merge another BspObject into this object. this renumbers the other
+ // object's vertices, faces, polygons, and vertexindexes in polygons
+ void MergeObjects( BspObject *mergeobj );
+
+ void CollapseObjectList(); // collapse entire list into this object
+
+ BoundingBox* BuildBoundingBoxList(); // build a list of bounding boxes
+
+ BSPNode* BuildBSPTree(); // build bsp tree from polygon list
+ BSPNode* BuildBSPTreeFromFlat(); // build bsp tree from flat representation
+
+ int BspTreeAvailable(); // any bsp tree available?
+ int BSPTreeAvailable(); // linked bsp tree available?
+ int BSPTreeFlatAvailable(); // flat bsp tree available?
+
+ // processing functions (typically passed through to primitives)
+ void CalcBoundingBoxes(); // operates on bsp tree only
+ void CalcSeparatorPlanes(); // operates on bsp tree only
+ void CheckEdges(); // operates on bsp tree only
+ void CheckPolygonPlanes(); // operates on polygon list only
+ void CheckVertices( int verbose ); // scans entire vertex list
+ void CalcPlaneNormals(); // operates on polygon list only
+ void CheckParsedData(); // some consistency checks
+ void UpdateAttributeNumbers(); // calc length of lists
+
+ int ConvertColorIndexesToRGB( char *palette, int changemode );
+
+ // return bounding box extents for this object
+ void CalcBoundingBox( Vertex3& minvertex, Vertex3& maxvertex );
+
+ // display some object statistics
+ void DisplayStatistics();
+
+ // ASCII output functions that have to be implemented by
+ // derived ObjectXXXFormat classes.
+ // must not be pure virtual!
+ virtual int WriteVertexList( FileAccess& fp ) { return FALSE; }
+ virtual int WritePolygonList( FileAccess& fp ) { return FALSE; }
+ virtual int WriteFaceList( FileAccess& fp ) { return FALSE; }
+ virtual int WriteFaceProperties( FileAccess& fp ) { return FALSE; }
+ virtual int WriteTextureList( FileAccess& fp ) { return FALSE; }
+ virtual int WriteMappingList( FileAccess& fp ) { return FALSE; }
+ virtual int WriteNormals( FileAccess& fp ) { return FALSE; }
+ virtual int WriteBSPTree( FileAccess& fp ) { return FALSE; }
+
+ // return contained objects
+ VertexChunk& getVertexList() { return vertexlist; }
+ PolygonList& getPolygonList() { return polygonlist; }
+ FaceChunk& getFaceList() { return facelist; }
+ TextureChunk& getTextureList() { return texturelist; }
+ MappingChunk& getMappingList() { return mappinglist; }
+ BSPTree& getBSPTree() { return bsptree; }
+ BSPTreeFlat& getBSPTreeFlat() { return bsptreeflat; }
+
+ // get/set object's name-string
+ char* getObjectName() const { return objectname; }
+ void setObjectName( char *name );
+
+ // get/set object's local transformation
+ Vertex3 getCenterInWorldSpace() const { return objecttrafo.FetchTranslation(); }
+ Transform3 getObjectTransformation() const { return objecttrafo; }
+ void setObjectTransformation( const Transform3& ot ) { objecttrafo = ot; }
+
+ // scale entire object (all vertices)
+ void ApplyScale( double scalefac );
+
+ // apply translation to all coordinates and set center to (0,0,0)
+ void ApplyCenter();
+
+ // apply transformation matrix and set to identity afterwards
+ void ApplyTransformation();
+
+ // return next object in list
+ BspObject* getNext() const { return next; }
+
+private:
+ void InconsistencyError( const char *err );
+
+public:
+ static int getEliminateDoubletsOnMergeFlag() { return check_vertex_doublets_on_merge; }
+ static void setEliminateDoubletsOnMergeFlag( int flag ) { check_vertex_doublets_on_merge = flag; }
+
+private:
+ static int check_vertex_doublets_on_merge;
+
+protected:
+ // contained objects
+ VertexChunk vertexlist; // list of vertices
+ PolygonList polygonlist; // list of polygons
+ FaceChunk facelist; // list of faces
+ TextureChunk texturelist; // list of textures
+ MappingChunk mappinglist; // list of mappings
+ BSPTree bsptree; // linked bsp tree
+ BSPTreeFlat bsptreeflat; // flat bsp tree
+ Transform3 objecttrafo; // attached transformation
+
+ // object's name if any defined
+ char* objectname;
+
+ // pointer to next object in list
+ BspObject* next;
+};
+
+// copy constructor -----------------------------------------------------------
+inline BspObject::BspObject( const BspObject& copyobj ) :
+ BspObjectInfo( copyobj ),
+ vertexlist( copyobj.vertexlist ),
+ polygonlist( copyobj.polygonlist ),
+ facelist( copyobj.facelist ),
+ texturelist( copyobj.texturelist ),
+ mappinglist( copyobj.mappinglist ),
+ bsptree( copyobj.bsptree ),
+ bsptreeflat( copyobj.bsptreeflat ),
+ objecttrafo( copyobj.objecttrafo )
+{
+ // copy object's name
+ objectname = NULL;
+ setObjectName( copyobj.objectname );
+
+ // unlink tail of list
+ next = NULL;
+}
+
+// assignment operator --------------------------------------------------------
+inline BspObject& BspObject::operator =( const BspObject& copyobj )
+{
+ if ( &copyobj != this ) {
+
+ // copy info part
+ *(BspObjectInfo *)this = copyobj;
+
+ // copy contained objects
+ vertexlist = copyobj.vertexlist;
+ polygonlist = copyobj.polygonlist;
+ facelist = copyobj.facelist;
+ texturelist = copyobj.texturelist;
+ mappinglist = copyobj.mappinglist;
+ bsptree = copyobj.bsptree;
+ bsptreeflat = copyobj.bsptreeflat;
+ objecttrafo = copyobj.objecttrafo;
+
+ // copy object's name
+ setObjectName( copyobj.objectname );
+
+ // unlink tail of list
+ next = NULL;
+ }
+ return *this;
+}
+
+
+BSPLIB_NAMESPACE_END
+
+
+#endif // _BSPOBJECT_H_
+
diff --git a/tool_src/BspLib/BspObjectList.cpp b/tool_src/BspLib/BspObjectList.cpp
new file mode 100644
index 0000000..604682b
--- /dev/null
+++ b/tool_src/BspLib/BspObjectList.cpp
@@ -0,0 +1,197 @@
+//-----------------------------------------------------------------------------
+// BSPLIB MODULE: BspObjectList.cpp
+//
+// Copyright (c) 1997-1998 by Markus Hadwiger
+// All Rights Reserved.
+//-----------------------------------------------------------------------------
+
+// bsplib header files
+#include "BspObjectList.h"
+
+
+BSPLIB_NAMESPACE_BEGIN
+
+
+// create new (default constructed) BspObject and prepend it to list ----------
+//
+BspObject *BspObjectListRep::CreateNewObject()
+{
+ BspObject *temp = new BspObject;
+ temp->next = list;
+ list = temp;
+ return list;
+}
+
+
+// insert existing BspObject at head of list ----------------------------------
+//
+BspObject *BspObjectListRep::InsertObject( BspObject *obj )
+{
+ if ( obj != NULL ) {
+ obj->next = list;
+ list = obj;
+ }
+ return obj;
+}
+
+
+// build a list of bounding boxes containing all objects of list --------------
+//
+BoundingBox *BspObjectListRep::BuildBoundingBoxList()
+{
+ return ( list ? list->BuildBoundingBoxList() : NULL );
+}
+
+
+// count number of objects in list --------------------------------------------
+//
+int BspObjectListRep::CountListObjects()
+{
+ int count = 0;
+ for ( BspObject *scan = list; scan; scan = scan->getNext() )
+ count++;
+ return count;
+}
+
+
+// prepare object bsp tree as secondary data structure ------------------------
+//
+int BspObjectListRep::PrepareObjectBSPTree( ObjectBSPTree& objbsptree )
+{
+ if ( list != NULL ) {
+ // create list of bounding boxes with contained objects
+ BoundingBox *bboxlist = BuildBoundingBoxList();
+ // partition space containing bounding boxes (list becomes invalid!)
+ objbsptree.InitTree( bboxlist->PartitionSpace() );
+ // create new object list, object bsp tree becomes secondary data structure
+ list = objbsptree->CreateObjectList();
+ }
+ return ( list != NULL );
+}
+
+
+// merge object bsp tree into a single object and attached bsp tree -----------
+//
+int BspObjectListRep::MergeObjectBSPTree( ObjectBSPTree& objbsptree )
+{
+ //NOTE:
+ // it is imperative that the passed in ObjectBSPTree really
+ // contains all BspObjects of this list! if this is not the
+ // case the list will simply be overwritten with a single-element
+ // list containing the aggregate object of all nodes of the
+ // passed in ObjectBSPTree. the original list nodes will be lost!
+
+ // create list consisting only of the merged object
+ list = objbsptree->CreateMergedBSPTree();
+
+ // delete all BspObjects contained in tree since they are now
+ // unnecessary. (their data is contained in the merged object.)
+ objbsptree->DeleteNodeBspObjects();
+ objbsptree.KillTree();
+
+ return ( list != NULL );
+}
+
+
+// collapse entire list of BspObjects into head of list -----------------------
+//
+int BspObjectListRep::CollapseObjectList()
+{
+ if ( list != NULL )
+ list->CollapseObjectList();
+ return ( list != NULL );
+}
+
+
+// process all objects contained in list --------------------------------------
+//
+int BspObjectListRep::ProcessObjects( int flags )
+{
+ // scan entire list
+ for ( BspObject *bspobject = list; bspobject; bspobject = bspobject->getNext() ) {
+
+ // apply transformations directly to vertices
+ if ( flags & BspObjectList::APPLY_TRANSFORMATIONS ) {
+ bspobject->ApplyTransformation();
+ }
+
+ // calculate plane normals for planes of all polygons
+ if ( flags & BspObjectList::CALC_PLANE_NORMALS )
+ bspobject->CalcPlaneNormals();
+
+ // build linked bsp tree from flat representation
+ if ( flags & BspObjectList::BUILD_FROM_FLAT ) {
+ if ( bspobject->BuildBSPTreeFromFlat() )
+ bspobject->bsptree->NumberBSPNodes( bspobject->numbsppolygons );
+ continue; // no other processing allowed
+ }
+
+ //TODO:
+ // 1. vertices zusammenlegen: MergeVertices()
+ // 2. ueberfluessige edges entfernen: CullNullEdges()
+ // 3. t vertices entfernen: EliminateTVertices()
+ // 4. faces zusammenlegen: MergeFaces()
+
+ // MergeFaces(): nur fuer 3d-studio tri-mesh!!
+ // fuer jedes triangle werden alle anderen gescannt, ob sie eine
+ // edge teilen. falls ja, wird fuer den dritten punkt geprueft, ob er
+ // in der selben ebene liegt. ja --> triangle to quadrilateral merge.
+ // der umlaufsinn der vertex numerierung wird dahingehend geprueft, ob
+ // er konsistent mit dem ergebnis-quad ist.
+ // nein: warnmeldung und kein mergen!!
+
+ if ( flags & BspObjectList::MERGE_VERTICES ) {
+ }
+
+ if ( flags & BspObjectList::CULL_NULL_EDGES ) {
+ }
+
+ if ( flags & BspObjectList::ELIMINATE_T_VERTICES ) {
+ }
+
+ if ( flags & BspObjectList::MERGE_FACES ) {
+ }
+
+ // split (possibly hand edited) faces with vertices not in same plane
+ if ( flags & BspObjectList::CHECK_PLANES )
+ bspobject->CheckPolygonPlanes();
+
+ // compile bsp tree and number nodes
+ if ( flags & BspObjectList::BUILD_BSP )
+ if ( bspobject->BuildBSPTree() )
+ bspobject->bsptree->NumberBSPNodes( bspobject->numbsppolygons );
+
+ // check for vertices with exact same coordinates
+ if ( flags & BspObjectList::CHECK_VERTICES )
+ bspobject->CheckVertices( TRUE );
+
+ // calc bounding boxes for all nodes
+ // operates on bsp tree only, so one has to be present!
+ if ( flags & BspObjectList::CALC_BOUNDING_BOXES )
+ bspobject->CalcBoundingBoxes();
+
+ // calc explicit separator planes for all nodes
+ // operates on bsp tree only, so one has to be present!
+ if ( flags & BspObjectList::CALC_SEPARATOR_PLANES )
+ bspobject->CalcSeparatorPlanes();
+
+ // check edges for t-vertices and eliminate them (insert trace vertices)
+ // operates on bsp tree only, so one has to be present!
+ if ( flags & BspObjectList::CHECK_EDGES )
+ bspobject->CheckEdges();
+
+ // display object and compilation statistics
+ if ( flags & BspObjectList::DISPLAY_STATS )
+ bspobject->DisplayStatistics();
+
+ // update attribute numbers, even if no statistics desired
+ bspobject->UpdateAttributeNumbers();
+ }
+
+ return TRUE;
+}
+
+
+BSPLIB_NAMESPACE_END
+
+//-----------------------------------------------------------------------------
diff --git a/tool_src/BspLib/BspObjectList.h b/tool_src/BspLib/BspObjectList.h
new file mode 100644
index 0000000..e4f8c17
--- /dev/null
+++ b/tool_src/BspLib/BspObjectList.h
@@ -0,0 +1,151 @@
+//-----------------------------------------------------------------------------
+// BSPLIB HEADER: BspObjectList.h
+//
+// Copyright (c) 1997-1998 by Markus Hadwiger
+// All Rights Reserved.
+//-----------------------------------------------------------------------------
+
+#ifndef _BSPOBJECTLIST_H_
+#define _BSPOBJECTLIST_H_
+
+// bsplib header files
+#include "BspLibDefs.h"
+#include "BspObject.h"
+#include "ObjectBSPTree.h"
+
+
+BSPLIB_NAMESPACE_BEGIN
+
+
+// class for list of BspObject items (representation class) -------------------
+//
+class BspObjectListRep {
+
+ friend class BspObjectList;
+
+public:
+ BspObjectListRep() : ref_count( 0 ) { list = NULL; }
+ ~BspObjectListRep() { delete list; }
+
+ BspObject* CreateNewObject(); // prepend empty object to list
+ BspObject* InsertObject( BspObject *obj ); // insert existing object at head
+
+ BoundingBox* BuildBoundingBoxList(); // build a list of bounding boxes
+
+ int CountListObjects(); // count list objects
+
+ int PrepareObjectBSPTree( ObjectBSPTree& objbsptree );
+ int MergeObjectBSPTree( ObjectBSPTree& objbsptree );
+
+ int CollapseObjectList(); // collapse list into its head object
+
+ int ProcessObjects( int flags ); // various processing functions
+
+ int BspTreeAvailable() { return list ? list->BspTreeAvailable() : FALSE; }
+ int BSPTreeAvailable() { return list ? list->BSPTreeAvailable() : FALSE; }
+ int BSPTreeFlatAvailable() { return list ? list->BSPTreeFlatAvailable() : FALSE; }
+
+ BspObject* getListHead() const { return list; }
+
+private:
+ int ref_count; // number of references to this list
+ BspObject* list; // first element in list
+};
+
+
+// class for list of BspObject items (handle class) ---------------------------
+//
+class BspObjectList {
+
+public:
+
+ // object processing flags
+ enum {
+ CHECK_PLANES = 0x0001,
+ BUILD_BSP = 0x0002,
+ CHECK_VERTICES = 0x0004,
+ CHECK_EDGES = 0x0008,
+ BUILD_BSP_WITH_CHECKS = 0x000F,
+ DISPLAY_STATS = 0x0010,
+ BUILD_FROM_FLAT = 0x0020,
+ MERGE_VERTICES = 0x0040,
+ CULL_NULL_EDGES = 0x0080,
+ ELIMINATE_T_VERTICES = 0x0100,
+ MERGE_FACES = 0x0200,
+ CALC_PLANE_NORMALS = 0x0400,
+ CALC_BOUNDING_BOXES = 0x0800,
+ CALC_SEPARATOR_PLANES = 0x1000,
+ APPLY_TRANSFORMATIONS = 0x2000,
+ };
+
+public:
+ BspObjectList() { rep = new BspObjectListRep(); rep->ref_count = 1; }
+ ~BspObjectList() { if ( --rep->ref_count == 0 ) delete rep; }
+
+ BspObjectList( const BspObjectList& copyobj );
+ BspObjectList& operator =( const BspObjectList& copyobj );
+
+ BspObject* CreateNewObject() { return rep->CreateNewObject(); }
+ BspObject* InsertObject( BspObject *obj ) { return rep->InsertObject( obj ); }
+
+ // create a list of bounding boxes containing a bounding box for each
+ // node in the list. user has to keep track of the list's head!
+ BoundingBox* BuildBoundingBoxList() { return rep->BuildBoundingBoxList(); }
+
+ int CountListObjects() { return rep->CountListObjects(); }
+
+ int PrepareObjectBSPTree( ObjectBSPTree& objbsptree ) { return rep->PrepareObjectBSPTree( objbsptree ); }
+ int MergeObjectBSPTree( ObjectBSPTree& objbsptree ) { return rep->MergeObjectBSPTree( objbsptree ); }
+
+ int CollapseObjectList() { return rep->CollapseObjectList(); }
+
+ // process entire list according to bitfield specifying desired processing
+ int ProcessObjects( int flags ) { return rep->ProcessObjects( flags ); }
+
+ // BSP tree of any representation available (linked or flat)?
+ int BspTreeAvailable() { return rep->BspTreeAvailable(); }
+ // linked BSP tree available?
+ int BSPTreeAvailable() { return rep->BSPTreeAvailable(); }
+ // flat BSP tree available?
+ int BSPTreeFlatAvailable() { return rep->BSPTreeFlatAvailable(); }
+
+ //NOTE:
+ // the previous functions actually return the state of the first BspObject
+ // in the list. if bsp trees have not been built through ProcessObjects()
+ // it is not guaranteed that the returned state holds for every object in
+ // the list! normally, list nodes should not be accessed separately, though.
+
+ // return pointer to first BspObject in list
+ BspObject* getListHead() { return rep->getListHead(); }
+
+private:
+ BspObjectListRep *rep;
+};
+
+// copy constructor for BspObjectList -----------------------------------------
+inline BspObjectList::BspObjectList( const BspObjectList& copyobj )
+{
+ rep = copyobj.rep; // shallow copy
+ rep->ref_count++; // with reference counting
+}
+
+// assignment operator for BspObjectList --------------------------------------
+inline BspObjectList& BspObjectList::operator =( const BspObjectList& copyobj )
+{
+ if ( &copyobj != this ) {
+ // old reference is overwritten
+ if ( --rep->ref_count == 0 ) {
+ delete rep;
+ }
+ rep = copyobj.rep; // shallow copy
+ rep->ref_count++; // with reference counting
+ }
+ return *this;
+}
+
+
+BSPLIB_NAMESPACE_END
+
+
+#endif // _BSPOBJECTLIST_H_
+
diff --git a/tool_src/BspLib/BspOutput.cpp b/tool_src/BspLib/BspOutput.cpp
new file mode 100644
index 0000000..b86fc9f
--- /dev/null
+++ b/tool_src/BspLib/BspOutput.cpp
@@ -0,0 +1,108 @@
+//-----------------------------------------------------------------------------
+// BSPLIB MODULE: BspOutput.cpp
+//
+// Copyright (c) 1996-1997 by Markus Hadwiger
+// All Rights Reserved.
+//-----------------------------------------------------------------------------
+
+// bsplib header files
+#include "BspOutput.h"
+#include "BspObject.h"
+#include "BspTool.h"
+#include "ObjectBspFormat.h"
+
+
+BSPLIB_NAMESPACE_BEGIN
+
+
+// construct BspOutput object -------------------------------------------------
+//
+BspOutput::BspOutput( BspObjectList objectlist, const char *filename ) :
+ SingleOutput( objectlist, BspTool::ChangeExtension( filename, BSP_FILE_EXTENSION ) )
+{
+}
+
+
+// construct BspOutput object using an InputData3D object ---------------------
+//
+BspOutput::BspOutput( const InputData3D& inputdata ) :
+ SingleOutput( inputdata.getObjectList(),
+ BspTool::ChangeExtension( inputdata.getFileName(), BSP_FILE_EXTENSION ) )
+{
+ // get pointer to "real" input object
+ InputData3D *inputobj = inputdata.getRealObject();
+
+ // try to isolate the BspFormat part of the input object
+ BspFormat *bspformat = dynamic_cast<BspFormat*>(inputobj);
+
+ // copy over if cast succeeded
+ if ( bspformat != NULL ) {
+
+ *(BspFormat *)this = *bspformat;
+
+ } else {
+
+ // try to isolate the SingleFormat part of the input object
+ SingleFormat *singleformat = dynamic_cast<SingleFormat*>(inputobj);
+
+ // copy over if cast succeeded
+ if ( singleformat != NULL )
+ *(SingleFormat *)this = *singleformat;
+ }
+}
+
+
+// write outputfile before destruction ----------------------------------------
+//
+BspOutput::~BspOutput()
+{
+ if ( m_output.Status() == SYSTEM_IO_OK )
+ WriteOutputFile();
+}
+
+
+// assignment copies only the BspFormat part of the object --------------------
+//
+BspOutput& BspOutput::operator =( const BspOutput& copyobj )
+{
+ *(BspFormat *)this = copyobj;
+ return *this;
+}
+
+
+// write '.bsp' file for this object ------------------------------------------
+//
+int BspOutput::WriteOutputFile()
+{
+ sprintf( line, "Writing compiled object data to \"%s\"...\n", (const char *) m_filename );
+ InfoMessage( line );
+
+ sprintf( line, "%s\n\n", BSP_SIGNATURE_1_1 );
+ m_output.WriteLine( line );
+
+ // write bsplib banner to file and init output data
+ SingleOutput::InitOutput();
+
+ // create 3-D object knowing about '.bsp' format
+ ObjectBspFormat obj( *m_baseobject, *this );
+
+ // write attribute lists
+ obj.WriteVertexList( m_output );
+ obj.WritePolygonList( m_output );
+ obj.WriteFaceList( m_output );
+ obj.WriteNormals( m_output );
+ obj.WriteFaceProperties( m_output );
+ obj.WriteMappingList( m_output );
+ obj.WriteBSPTree( m_output );
+ obj.WriteTextureList( m_output );
+
+ // write common part
+ SingleOutput::WriteOutputFile();
+
+ return m_output.Status();
+}
+
+
+BSPLIB_NAMESPACE_END
+
+//-----------------------------------------------------------------------------
diff --git a/tool_src/BspLib/BspOutput.h b/tool_src/BspLib/BspOutput.h
new file mode 100644
index 0000000..877fead
--- /dev/null
+++ b/tool_src/BspLib/BspOutput.h
@@ -0,0 +1,41 @@
+//-----------------------------------------------------------------------------
+// BSPLIB HEADER: BspOutput.h
+//
+// Copyright (c) 1996-1997 by Markus Hadwiger
+// All Rights Reserved.
+//-----------------------------------------------------------------------------
+
+#ifndef _BSPOUTPUT_H_
+#define _BSPOUTPUT_H_
+
+// bsplib header files
+#include "BspLibDefs.h"
+#include "BspFormat.h"
+#include "BspInput.h"
+#include "SingleOutput.h"
+
+
+BSPLIB_NAMESPACE_BEGIN
+
+
+// file output class for bsp format files -------------------------------------
+//
+class BspOutput : public BspFormat, public SingleOutput {
+
+public:
+ BspOutput( BspObjectList objectlist, const char *filename );
+ BspOutput( const InputData3D& inputdata );
+ ~BspOutput();
+
+ BspOutput& operator =( const BspOutput& copyobj );
+
+public:
+ int WriteOutputFile();
+};
+
+
+BSPLIB_NAMESPACE_END
+
+
+#endif // _BSPOUTPUT_H_
+
diff --git a/tool_src/BspLib/BspTool.cpp b/tool_src/BspLib/BspTool.cpp
new file mode 100644
index 0000000..23bcb8d
--- /dev/null
+++ b/tool_src/BspLib/BspTool.cpp
@@ -0,0 +1,68 @@
+//-----------------------------------------------------------------------------
+// BSPLIB MODULE: BspTool.cpp
+//
+// Copyright (c) 1997 by Markus Hadwiger
+// All Rights Reserved.
+//-----------------------------------------------------------------------------
+
+// bsplib header files
+#include "BspTool.h"
+
+// flags
+#define STRIP_PATH
+
+
+BSPLIB_NAMESPACE_BEGIN
+
+
+// create new string with altered extension -----------------------------------
+//
+String BspTool::ChangeExtension( const char *filename, const char *extension )
+{
+ if ( ( filename == NULL ) || ( extension == NULL ) )
+ return String( NULL );
+
+ int len = strlen( filename );
+ int pos = len;
+ char *name = NULL;
+ const char *scan = filename + pos;
+
+ while ( ( --pos > 0 ) && ( *--scan != '.' ) ) ;
+
+ if ( pos > 0 ) {
+ // change extension if there was an extension
+ name = new char[ pos + strlen( extension ) + 1 ];
+ strncpy( name, filename, pos );
+ strcpy( name + pos, extension );
+ } else {
+ // append new extension if there was no extension
+ name = new char[ len + strlen( extension ) + 1 ];
+ strcpy( name, filename );
+ strcpy( name + len, extension );
+ }
+
+#ifdef STRIP_PATH
+ String ret( SkipPath( name ) );
+#else
+ String ret( name );
+#endif
+
+ delete name;
+ return ret;
+}
+
+
+// create filename without path -----------------------------------------------
+//
+const String BspTool::SkipPath( const char *fullname )
+{
+ const char *scan = fullname + strlen( fullname ) - 1;
+ while ( ( *scan != '\\' ) && ( *scan != ':' ) && ( scan >= fullname ) )
+ scan--;
+ return String( scan + 1 );
+}
+
+
+BSPLIB_NAMESPACE_END
+
+//-----------------------------------------------------------------------------
diff --git a/tool_src/BspLib/BspTool.h b/tool_src/BspLib/BspTool.h
new file mode 100644
index 0000000..607592e
--- /dev/null
+++ b/tool_src/BspLib/BspTool.h
@@ -0,0 +1,34 @@
+//-----------------------------------------------------------------------------
+// BSPLIB HEADER: BspTool.h
+//
+// Copyright (c) 1997 by Markus Hadwiger
+// All Rights Reserved.
+//-----------------------------------------------------------------------------
+
+#ifndef _BSPTOOL_H_
+#define _BSPTOOL_H_
+
+// bsplib header files
+#include "BspLibDefs.h"
+#include "SystemIO.h"
+#include "Vertex.h"
+
+
+BSPLIB_NAMESPACE_BEGIN
+
+
+// BspTool contains miscellaneous helper functions ----------------------------
+//
+class BspTool {
+
+public:
+ static String ChangeExtension( const char *filename, const char *extension );
+ static const String SkipPath( const char *name );
+};
+
+
+BSPLIB_NAMESPACE_END
+
+
+#endif // _BSPTOOL_H_
+
diff --git a/tool_src/BspLib/COPYING b/tool_src/BspLib/COPYING
new file mode 100644
index 0000000..bf50f20
--- /dev/null
+++ b/tool_src/BspLib/COPYING
@@ -0,0 +1,482 @@
+ GNU LIBRARY GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1991 Free Software Foundation, Inc.
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the library GPL. It is
+ numbered 2 because it goes with version 2 of the ordinary GPL.]
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+ This license, the Library General Public License, applies to some
+specially designated Free Software Foundation software, and to any
+other libraries whose authors decide to use it. You can use it for
+your libraries, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if
+you distribute copies of the library, or if you modify it.
+
+ For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you. You must make sure that they, too, receive or can get the source
+code. If you link a program with the library, you must provide
+complete object files to the recipients so that they can relink them
+with the library, after making changes to the library and recompiling
+it. And you must show them these terms so they know their rights.
+
+ Our method of protecting your rights has two steps: (1) copyright
+the library, and (2) offer you this license which gives you legal
+permission to copy, distribute and/or modify the library.
+
+ Also, for each distributor's protection, we want to make certain
+that everyone understands that there is no warranty for this free
+library. If the library is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original
+version, so that any problems introduced by others will not reflect on
+the original authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that companies distributing free
+software will individually obtain patent licenses, thus in effect
+transforming the program into proprietary software. To prevent this,
+we have made it clear that any patent must be licensed for everyone's
+free use or not licensed at all.
+
+ Most GNU software, including some libraries, is covered by the ordinary
+GNU General Public License, which was designed for utility programs. This
+license, the GNU Library General Public License, applies to certain
+designated libraries. This license is quite different from the ordinary
+one; be sure to read it in full, and don't assume that anything in it is
+the same as in the ordinary license.
+
+ The reason we have a separate public license for some libraries is that
+they blur the distinction we usually make between modifying or adding to a
+program and simply using it. Linking a program with a library, without
+changing the library, is in some sense simply using the library, and is
+analogous to running a utility program or application program. However, in
+a textual and legal sense, the linked executable is a combined work, a
+derivative of the original library, and the ordinary General Public License
+treats it as such.
+
+ Because of this blurred distinction, using the ordinary General
+Public License for libraries did not effectively promote software
+sharing, because most developers did not use the libraries. We
+concluded that weaker conditions might promote sharing better.
+
+ However, unrestricted linking of non-free programs would deprive the
+users of those programs of all benefit from the free status of the
+libraries themselves. This Library General Public License is intended to
+permit developers of non-free programs to use free libraries, while
+preserving your freedom as a user of such programs to change the free
+libraries that are incorporated in them. (We have not seen how to achieve
+this as regards changes in header files, but we have achieved it as regards
+changes in the actual functions of the Library.) The hope is that this
+will lead to faster development of free libraries.
+
+ The precise terms and conditions for copying, distribution and
+modification follow. Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library". The
+former contains code derived from the library, while the latter only
+works together with the library.
+
+ Note that it is possible for a library to be covered by the ordinary
+General Public License rather than by this special one.
+
+ GNU LIBRARY GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License Agreement applies to any software library which
+contains a notice placed by the copyright holder or other authorized
+party saying it may be distributed under the terms of this Library
+General Public License (also called "this License"). Each licensee is
+addressed as "you".
+
+ A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+ The "Library", below, refers to any such software library or work
+which has been distributed under these terms. A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language. (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+ "Source code" for a work means the preferred form of the work for
+making modifications to it. For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+ Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it). Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+ 1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+ You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+ 2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) The modified work must itself be a software library.
+
+ b) You must cause the files modified to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ c) You must cause the whole of the work to be licensed at no
+ charge to all third parties under the terms of this License.
+
+ d) If a facility in the modified Library refers to a function or a
+ table of data to be supplied by an application program that uses
+ the facility, other than as an argument passed when the facility
+ is invoked, then you must make a good faith effort to ensure that,
+ in the event an application does not supply such function or
+ table, the facility still operates, and performs whatever part of
+ its purpose remains meaningful.
+
+ (For example, a function in a library to compute square roots has
+ a purpose that is entirely well-defined independent of the
+ application. Therefore, Subsection 2d requires that any
+ application-supplied function or table used by this function must
+ be optional: if the application does not supply it, the square
+ root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library. To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License. (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.) Do not make any other change in
+these notices.
+
+ Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+ This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+ 4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+ If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library". Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+ However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library". The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+ When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library. The
+threshold for this to be true is not precisely defined by law.
+
+ If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work. (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+ Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+ 6. As an exception to the Sections above, you may also compile or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+ You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License. You must supply a copy of this License. If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License. Also, you must do one
+of these things:
+
+ a) Accompany the work with the complete corresponding
+ machine-readable source code for the Library including whatever
+ changes were used in the work (which must be distributed under
+ Sections 1 and 2 above); and, if the work is an executable linked
+ with the Library, with the complete machine-readable "work that
+ uses the Library", as object code and/or source code, so that the
+ user can modify the Library and then relink to produce a modified
+ executable containing the modified Library. (It is understood
+ that the user who changes the contents of definitions files in the
+ Library will not necessarily be able to recompile the application
+ to use the modified definitions.)
+
+ b) Accompany the work with a written offer, valid for at
+ least three years, to give the same user the materials
+ specified in Subsection 6a, above, for a charge no more
+ than the cost of performing this distribution.
+
+ c) If distribution of the work is made by offering access to copy
+ from a designated place, offer equivalent access to copy the above
+ specified materials from the same place.
+
+ d) Verify that the user has already received a copy of these
+ materials or that you have already sent this user a copy.
+
+ For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it. However, as a special exception,
+the source code distributed need not include anything that is normally
+distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+ It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system. Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+ 7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+ a) Accompany the combined library with a copy of the same work
+ based on the Library, uncombined with any other library
+ facilities. This must be distributed under the terms of the
+ Sections above.
+
+ b) Give prominent notice with the combined library of the fact
+ that part of it is a work based on the Library, and explaining
+ where to find the accompanying uncombined form of the same work.
+
+ 8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License. Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License. However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+ 9. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Library or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+ 10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all. For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded. In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+ 13. The Free Software Foundation may publish revised and/or new
+versions of the Library General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation. If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+ 14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission. For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this. Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+ NO WARRANTY
+
+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Libraries
+
+ If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change. You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+ To apply these terms, attach the following notices to the library. It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the library's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307 USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the
+ library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+ <signature of Ty Coon>, 1 April 1990
+ Ty Coon, President of Vice
+
+That's all there is to it!
diff --git a/tool_src/BspLib/Chunk.h b/tool_src/BspLib/Chunk.h
new file mode 100644
index 0000000..db4fa62
--- /dev/null
+++ b/tool_src/BspLib/Chunk.h
@@ -0,0 +1,280 @@
+//-----------------------------------------------------------------------------
+// BSPLIB HEADER: Chunk.h
+//
+// Copyright (c) 1997 by Markus Hadwiger
+// All Rights Reserved.
+//-----------------------------------------------------------------------------
+
+#ifndef _CHUNK_H_
+#define _CHUNK_H_
+
+// bsplib header files
+#include "BspLibDefs.h"
+#include "SystemIO.h"
+
+
+// if this flag is set storage is increased by using lists
+//#define EXPAND_STORAGE_WITH_LISTS
+
+// if this flag is set storage is always increased two-fold
+#define EXPAND_EXPONENTIALLY
+
+// if this flag is set assignment operators for elements are not invoked
+//#define IGNORE_ELEMENT_ASSIGNMENT_OPERATORS
+
+
+BSPLIB_NAMESPACE_BEGIN
+
+
+// added for Visual C++ 6.0
+template<class T> class Chunk;
+
+
+// template for simple chunk class (actual representation) --------------------
+//
+template<class T>
+class ChunkRep : public virtual SystemIO {
+
+ friend class Chunk<T>;
+
+ // error identifiers
+ enum {
+ E_INVALIDINDX
+ };
+
+ void Error( int err ) const;
+
+private:
+ ChunkRep( int chunksize = 0 );
+ ~ChunkRep();
+
+ int AddElement( const T& element );
+ T& FetchElement( int index );
+
+ int getNumElements() const;
+
+private:
+ int ref_count;
+ int numelements;
+ int maxnumelements;
+ T* elements;
+ ChunkRep* next;
+
+ static const int CHUNK_SIZE;
+};
+
+
+// create new chunk -----------------------------------------------------------
+//
+template<class T>
+ChunkRep<T>::ChunkRep( int chunksize ) : ref_count( 0 )
+{
+ int challocsize = chunksize > 0 ? chunksize : CHUNK_SIZE;
+ elements = new T[ challocsize ];
+ maxnumelements = challocsize;
+ numelements = 0;
+ next = NULL;
+}
+
+
+// destroy list of chunks recursively -----------------------------------------
+//
+template<class T>
+ChunkRep<T>::~ChunkRep()
+{
+ delete[] elements;
+ delete next;
+}
+
+
+// error message handler ------------------------------------------------------
+//
+template<class T>
+void ChunkRep<T>::Error( int err ) const
+{
+ {
+ StrScratch message;
+ sprintf( message, "***ERROR*** in object of a class of template Chunk" );
+
+ switch ( err ) {
+
+ case E_INVALIDINDX:
+ sprintf( message + strlen( message ), ": [Invalid index]" );
+ break;
+ }
+
+ ErrorMessage( message );
+ }
+
+ HandleCriticalError();
+}
+
+
+// fetch element corresponding to specific index ------------------------------
+//
+template<class T>
+T& ChunkRep<T>::FetchElement( int index )
+{
+
+#ifdef EXPAND_STORAGE_WITH_LISTS
+
+ ChunkRep *vlist = this;
+ while ( ( vlist != NULL ) && ( index >= vlist->numelements ) ) {
+ index -= vlist->numelements;
+ vlist = vlist->next;
+ }
+
+ if ( vlist == NULL )
+ Error( E_INVALIDINDX );
+
+ // return element
+ return vlist->elements[ index ];
+
+#else
+
+ if ( index >= numelements )
+ Error( E_INVALIDINDX );
+
+ // return element
+ return elements[ index ];
+
+#endif
+
+}
+
+
+// insert element into chunk, return index ------------------------------------
+//
+template<class T>
+int ChunkRep<T>::AddElement( const T& element )
+{
+
+#ifdef EXPAND_STORAGE_WITH_LISTS
+
+ // if space in head-chunk insert element directly
+ if ( numelements < maxnumelements ) {
+ elements[ numelements ] = element;
+ return numelements++;
+
+ } else {
+
+ int numskipped = numelements;
+ ChunkRep *vlist = this;
+
+ // scan until non-full chunk found
+ while ( ( vlist->next != NULL ) && ( vlist->next->numelements == vlist->next->maxnumelements ) ) {
+ vlist = vlist->next;
+ numskipped += vlist->numelements;
+ }
+
+ // insert new chunk if all existing are full
+ if ( vlist->next == NULL ) {
+
+#ifdef EXPAND_EXPONENTIALLY
+ vlist->next = new ChunkRep( vlist->maxnumelements * 2 );
+#else
+ vlist->next = new ChunkRep;
+#endif
+ }
+
+ // insert new element
+ vlist->next->elements[ vlist->next->numelements ] = element;
+ return vlist->next->numelements++ + numskipped;
+ }
+
+#else
+
+ // expand storage if necessary
+ if ( numelements == maxnumelements ) {
+
+#ifdef EXPAND_EXPONENTIALLY
+ maxnumelements *= 2;
+#else
+ maxnumelements += CHUNK_SIZE;
+#endif
+ T *temp = new T[ maxnumelements ];
+
+#ifdef IGNORE_ELEMENT_ASSIGNMENT_OPERATORS
+ memcpy( temp, elements, numelements * sizeof( T ) );
+#else
+ for ( int i = 0; i < numelements; i++ )
+ temp[ i ] = elements[ i ];
+#endif
+ delete[] elements;
+ elements = temp;
+ }
+
+ elements[ numelements ] = element;
+ return numelements++;
+
+#endif
+
+}
+
+
+// return number of elements in entire chunk ----------------------------------
+//
+template<class T>
+int ChunkRep<T>::getNumElements() const
+{
+ int num = 0;
+ for ( const ChunkRep *vlist = this; vlist; vlist = vlist->next )
+ num += vlist->numelements;
+ return num;
+}
+
+
+// template for simple chunk class (handle class) -----------------------------
+//
+template<class T>
+class Chunk {
+
+public:
+ Chunk( int chunksize = 0 ) { rep = new ChunkRep<T>( chunksize ); rep->ref_count = 1; }
+ ~Chunk() { if ( --rep->ref_count == 0 ) delete rep; }
+
+ Chunk( const Chunk& copyobj );
+ Chunk& operator =( const Chunk& copyobj );
+
+ T& operator []( int index ) { return rep->FetchElement( index ); }
+ T& FetchElement( int index ) { return rep->FetchElement( index ); }
+ int AddElement( const T& element ) { return rep->AddElement( element ); }
+
+ int getNumElements() const { return rep->getNumElements(); }
+
+private:
+ ChunkRep<T>* rep;
+};
+
+
+// copy constructor for a Chunk -----------------------------------------------
+//
+template<class T>
+Chunk<T>::Chunk( const Chunk<T>& copyobj )
+{
+ rep = copyobj.rep;
+ rep->ref_count++;
+}
+
+
+// assignment operator for a Chunk --------------------------------------------
+//
+template<class T>
+Chunk<T>& Chunk<T>::operator =( const Chunk<T>& copyobj )
+{
+ if ( &copyobj != this ) {
+ if ( --rep->ref_count == 0 ) {
+ delete rep;
+ }
+ rep = copyobj.rep;
+ rep->ref_count++;
+ }
+ return *this;
+}
+
+
+BSPLIB_NAMESPACE_END
+
+
+#endif // _CHUNK_H_
+
diff --git a/tool_src/BspLib/EpsAreas.cpp b/tool_src/BspLib/EpsAreas.cpp
new file mode 100644
index 0000000..8f70803
--- /dev/null
+++ b/tool_src/BspLib/EpsAreas.cpp
@@ -0,0 +1,28 @@
+//-----------------------------------------------------------------------------
+// BSPLIB MODULE: EpsAreas.cpp
+//
+// Copyright (c) 1998 by Markus Hadwiger
+// All Rights Reserved.
+//-----------------------------------------------------------------------------
+
+// bsplib headers
+#include "BspLibDefs.h"
+
+
+BSPLIB_NAMESPACE_BEGIN
+
+
+// epsilon area specifications ------------------------------------------------
+//
+double EpsAreas::eps_scalarproduct = 1e-7;
+double EpsAreas::eps_planethickness = 1e-7;
+double EpsAreas::eps_vanishdenominator = 1e-7;
+double EpsAreas::eps_vanishcomponent = 1e-7;
+double EpsAreas::eps_pointonline = 1e-5;
+double EpsAreas::eps_pointonlineseg = 1e-4;
+double EpsAreas::eps_vertexmergearea = 1e-4;
+
+
+BSPLIB_NAMESPACE_END
+
+//-----------------------------------------------------------------------------
diff --git a/tool_src/BspLib/Face.cpp b/tool_src/BspLib/Face.cpp
new file mode 100644
index 0000000..4e529e4
--- /dev/null
+++ b/tool_src/BspLib/Face.cpp
@@ -0,0 +1,352 @@
+//-----------------------------------------------------------------------------
+// BSPLIB MODULE: Face.cpp
+//
+// Copyright (c) 1996-1998 by Markus Hadwiger
+// All Rights Reserved.
+//-----------------------------------------------------------------------------
+
+// bsplib headers
+#include "Face.h"
+#include "Chunk.h"
+
+
+BSPLIB_NAMESPACE_BEGIN
+
+
+// copy constructor for Face --------------------------------------------------
+//
+Face::Face( const Face& copyobj )
+{
+ faceid = copyobj.faceid;
+ facecolor_indx = copyobj.facecolor_indx;
+ facecolor_rgba = copyobj.facecolor_rgba;
+ shadingtype = copyobj.shadingtype;
+ colortype = copyobj.colortype;
+
+ faceplane = copyobj.faceplane ? new Plane( *copyobj.faceplane ) : NULL;
+ facematerial = copyobj.facematerial ? new Material( *copyobj.facematerial ) : NULL;
+ facemapping = copyobj.facemapping ? new TriMapping( *copyobj.facemapping ) : NULL;
+ texturename = copyobj.texturename ? new char[ strlen( copyobj.texturename ) + 1 ] : NULL;
+
+ if ( texturename != NULL )
+ strcpy( texturename, copyobj.texturename );
+}
+
+
+// assignment operator for Face -----------------------------------------------
+//
+Face& Face::operator =( const Face& copyobj )
+{
+ if ( &copyobj != this ) {
+ faceid = copyobj.faceid;
+ facecolor_indx = copyobj.facecolor_indx;
+ facecolor_rgba = copyobj.facecolor_rgba;
+ shadingtype = copyobj.shadingtype;
+ colortype = copyobj.colortype;
+
+ delete faceplane;
+ delete facematerial;
+ delete facemapping;
+ delete texturename;
+
+ faceplane = copyobj.faceplane ? new Plane( *copyobj.faceplane ) : NULL;
+ facematerial = copyobj.facematerial ? new Material( *copyobj.facematerial ) : NULL;
+ facemapping = copyobj.facemapping ? new TriMapping( *copyobj.facemapping ) : NULL;
+ texturename = copyobj.texturename ? new char[ strlen( copyobj.texturename ) + 1 ] : NULL;
+
+ if ( texturename != NULL )
+ strcpy( texturename, copyobj.texturename );
+ }
+ return *this;
+}
+
+
+// set name of texture for this face ------------------------------------------
+//
+void Face::setTextureName( const char *tname )
+{
+ delete texturename;
+ texturename = tname ? new char[ strlen( tname ) + 1 ] : NULL;
+ if ( texturename != NULL )
+ strcpy( texturename, tname );
+ colortype = no_col;
+}
+
+
+// calculate face's plane (normal and offset) and attach it -------------------
+//
+void Face::CalcPlane( const Vertex3& vertex1, const Vertex3& vertex2, const Vertex3& vertex3 )
+{
+ if ( faceplane && faceplane->PlaneValid() )
+ return;
+ if ( faceplane && faceplane->NormalValid() ) {
+ // if normal already valid only recalculate offset
+ faceplane->CalcPlaneOffset( vertex1 );
+ return;
+ }
+ // calculate completely new plane
+ delete faceplane;
+ faceplane = new Plane( vertex1, vertex2, vertex3 );
+
+ if ( !faceplane->PlaneValid() ) {
+ ErrorMessage( "\n***ERROR*** Collinear vertices encountered (BspLib::Face)." );
+ HandleCriticalError();
+ }
+}
+
+
+// attach normal after creating plane to store it in --------------------------
+//
+void Face::AttachNormal( const Vector3& normal )
+{
+ delete faceplane;
+ faceplane = new Plane( normal );
+}
+
+
+// attach face's plane calculated somewhere else ------------------------------
+//
+void Face::AttachPlane( Plane *plane )
+{
+ if ( plane != NULL ) {
+ delete faceplane;
+ faceplane = plane;
+ }
+}
+
+// attach material and set colortype accordingly ------------------------------
+//
+void Face::AttachMaterial( Material *mat )
+{
+ if ( mat != NULL ) {
+ delete facematerial;
+ facematerial = mat;
+ colortype = material_col;
+ }
+}
+
+
+// convert color index to RGB triplet using 256 color palette -----------------
+//
+int Face::ConvertColorIndexToRGB( char *palette, int changemode )
+{
+ if ( colortype == indexed_col ) {
+ byte *palentry = (byte *) palette + facecolor_indx * 3;
+ float oomax = 255.0f / 63.0f;
+ facecolor_rgba.R = (byte) ( palentry[ 0 ] * oomax );
+ facecolor_rgba.G = (byte) ( palentry[ 1 ] * oomax );
+ facecolor_rgba.B = (byte) ( palentry[ 2 ] * oomax );
+ facecolor_rgba.A = 255;
+ if ( changemode )
+ colortype = rgb_col;
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+
+// helper function ------------------------------------------------------------
+//
+inline void WriteRGBA( FILE *fp, const char *desc, ColorRGBA col )
+{
+ fprintf( fp, "%s %f %f %f %f ", desc,
+ col.R / 255.0f, col.G / 255.0f,
+ col.B / 255.0f, col.A / 255.0f );
+}
+
+
+// write face info to text-file -----------------------------------------------
+//
+void Face::WriteFaceInfo( FILE *fp ) const
+{
+ // write shading type specifier
+ fprintf( fp, "%s\t", prop_strings[ shadingtype & base_mask ] );
+
+ // write color if any attached and valid
+ if ( shadingtype & color_mask ) {
+ if ( colortype == indexed_col ) {
+ // write color index
+ fprintf( fp, "%s %d", color_strings[ colortype ], facecolor_indx );
+ } else if ( colortype == rgb_col ) {
+ // write (r,g,b) triplet
+ fprintf( fp, "%s %f %f %f", color_strings[ colortype ],
+ facecolor_rgba.R / 255.0f,
+ facecolor_rgba.G / 255.0f,
+ facecolor_rgba.B / 255.0f );
+ } else if ( colortype == material_col ) {
+ if ( facematerial != NULL ) {
+ fprintf( fp, "%s ", color_strings[ colortype ] );
+ ColorRGBA colquad;
+ colquad = facematerial->getAmbientColor();
+ WriteRGBA( fp, material_strings[ 0 ], colquad );
+ colquad = facematerial->getDiffuseColor();
+ WriteRGBA( fp, material_strings[ 1 ], colquad );
+ colquad = facematerial->getSpecularColor();
+ WriteRGBA( fp, material_strings[ 2 ], colquad );
+ colquad = facematerial->getEmissiveColor();
+ WriteRGBA( fp, material_strings[ 3 ], colquad );
+ fprintf( fp, "%s %f ", material_strings[ 4 ], facematerial->getShininess() );
+ fprintf( fp, "%s %f", material_strings[ 5 ], facematerial->getTransparency() );
+ } else {
+ fprintf( fp, "**INVALID MATERIAL**" );
+ }
+ }
+ }
+
+ // write texture info if any attached and valid
+ if ( shadingtype & texmap_mask ) {
+ if ( texturename != NULL )
+ fprintf( fp, "\"%s\"", texturename );
+ else
+ fprintf( fp, "**INVALID TEXTURE NAME**" );
+ }
+
+ // write face id as comment
+ fprintf( fp, "\t; %d\n", faceid + 1 );
+}
+
+
+// write facenormal to text-file ----------------------------------------------
+//
+void Face::WriteNormalInfo( FILE *fp ) const
+{
+ // write face's normal vector
+ if ( faceplane != NULL ) {
+ Vector3 normal = faceplane->getPlaneNormal();
+ fprintf( fp, "%f,\t%f,\t%f\t\t; %d\n",
+ normal.getX(),
+ normal.getY(),
+ normal.getZ(),
+ faceid + 1 );
+ } else {
+ // normal vector invalid (no plane attached)
+ fprintf( fp, "Normal of face #%d invalid.\n", faceid + 1 );
+ }
+}
+
+
+// write mapping info to text-file --------------------------------------------
+//
+void Face::WriteMappingInfo( FILE *fp ) const
+{
+ // write three point correspondences for mapping
+ if ( facemapping != NULL ) {
+ // write (x,y) domain
+ int i = 0 ;
+ for ( i = 0; i < 3; i++ ) {
+ Vector2 vertex = facemapping->getMapXY( i );
+ fprintf( fp, "%f,\t%f,\t%f\n",
+ vertex.getX(),
+ vertex.getY(),
+ vertex.getW() );
+ }
+ // write (u,v) domain
+ for ( i = 0; i < 3; i++ ) {
+ Vector2 vertex = facemapping->getMapUV( i );
+ fprintf( fp, "%f,\t%f,\t%f\n",
+ vertex.getX(),
+ vertex.getY(),
+ vertex.getW() );
+ }
+ fprintf( fp, "\n" );
+ } else {
+ // face mapping invalid (no affine mapping attached)
+ fprintf( fp, "Mapping for face #%d invalid.\n\n", faceid + 1 );
+ }
+}
+
+
+// unspecified error encountered ----------------------------------------------
+//
+void Face::Error() const
+{
+ ErrorMessage( "\n***ERROR*** in object of class BspLib::Face." );
+ HandleCriticalError();
+}
+
+
+// get index to type specified as string (this function is static!) -----------
+//
+int Face::GetTypeIndex( const char *type )
+{
+ for ( int i = 0; i < num_shading_types; i++ )
+ if ( stricmp( type, prop_strings[ i ] ) == 0 )
+ return prop_ids[ i ];
+
+ // -1 means type-string invalid, so no valid index can be returned
+ return -1;
+}
+
+
+// get index to color model specified as string (this function is static!) ----
+//
+int Face::GetColorModelIndex( const char *type )
+{
+ for ( int i = 0; i < num_color_models; i++ )
+ if ( stricmp( type, color_strings[ i ] ) == 0 )
+ return color_ids[ i ];
+
+ // -1 means type-string invalid, so no valid index can be returned
+ return -1;
+}
+
+
+// strings for specification of face shading type -----------------------------
+//
+const char *Face::prop_strings[] = {
+ "no_shad",
+ "flat_shad",
+ "gouraud_shad",
+ "afftex_shad",
+ "ipol1tex_shad",
+ "ipol2tex_shad",
+ "persptex_shad",
+ "material_shad",
+ "texmat_shad",
+};
+
+const int Face::prop_ids[] = {
+ no_shad,
+ flat_shad,
+ gouraud_shad,
+ afftex_shad,
+ ipol1tex_shad,
+ ipol2tex_shad,
+ persptex_shad,
+ material_shad,
+ texmat_shad,
+};
+
+const char *Face::color_strings[] = {
+ "no_col",
+ "indexed_col",
+ "rgb_col",
+ "material_col",
+};
+
+const int Face::color_ids[] = {
+ no_col,
+ indexed_col,
+ rgb_col,
+ material_col,
+};
+
+const char *Face::material_strings[] = {
+ "ambient_col",
+ "diffuse_col",
+ "specular_col",
+ "emissive_col",
+ "shininess",
+ "transparency",
+};
+
+
+// base size of face chunk ----------------------------------------------------
+//
+template <> const int ChunkRep<Face>::CHUNK_SIZE = 512;
+
+
+BSPLIB_NAMESPACE_END
+
+//-----------------------------------------------------------------------------
diff --git a/tool_src/BspLib/Face.h b/tool_src/BspLib/Face.h
new file mode 100644
index 0000000..ceec44a
--- /dev/null
+++ b/tool_src/BspLib/Face.h
@@ -0,0 +1,223 @@
+//-----------------------------------------------------------------------------
+// BSPLIB HEADER: Face.h
+//
+// Copyright (c) 1996-1998 by Markus Hadwiger
+// All Rights Reserved.
+//-----------------------------------------------------------------------------
+
+#ifndef _FACE_H_
+#define _FACE_H_
+
+// bsplib header files
+#include "BspLibDefs.h"
+#include "Chunk.h"
+#include "Material.h"
+#include "Plane.h"
+#include "SystemIO.h"
+#include "Texture.h"
+#include "TriMapping.h"
+#include "Vertex.h"
+
+
+BSPLIB_NAMESPACE_BEGIN
+
+
+// class describing a face (mainly in terms of its surface properties) --------
+//
+class Face : public virtual SystemIO {
+
+ void Error() const;
+
+public:
+
+ // shading types for faces
+ enum ShadingType {
+ no_shad = 0x1000, // fixed color (lighting independent ambient color)
+ flat_shad = 0x1001, // flat shading
+ gouraud_shad = 0x1002, // gouraud shading
+ afftex_shad = 0x2003, // affine texture mapping
+ ipol1tex_shad = 0x2004, // first order interpolated texture mapping (lin)
+ ipol2tex_shad = 0x2005, // second order interpolated texture mapping (quad)
+ persptex_shad = 0x2006, // perspective correct mapping without any interpolation
+ material_shad = 0x1007, // use material specification
+ texmat_shad = 0x3008, // textures modulated by material specification
+ num_shading_types = 9, // MUST SET THIS MANUALLY!!
+ base_mask = 0x00ff, // mask for basic shading type
+ color_mask = 0x1000, // mask to denote faces with attached color
+ texmap_mask = 0x2000, // mask to denote texture mapped faces
+ };
+
+ // color model identifiers
+ enum ColorModel {
+ no_col, // shading type has no associated color
+ indexed_col, // indexed color (color look up table index)
+ rgb_col, // color specified directly via separate channels
+ material_col, // use material specification
+ num_color_models
+ };
+
+public:
+ Face();
+ ~Face() { delete faceplane; delete facematerial; delete facemapping; delete texturename; }
+
+ Face( const Face& copyobj );
+ Face& operator =( const Face& copyobj );
+
+ int getId() const { return faceid; }
+ void setId( int id ) { faceid = id; }
+
+ Material getMaterial() const { if ( facematerial == NULL ) Error(); return *facematerial; }
+ Plane getPlane() const { if ( faceplane == NULL ) Error(); return *faceplane; }
+
+ Vector3 getPlaneNormal() const;
+ void setPlaneNormal( const Vector3& normal );
+
+ int getShadingType() const { return shadingtype; }
+ void setShadingType( int type );
+
+ int getColorType() const { return colortype; }
+ void getColorIndex( dword& col ) const { col = facecolor_indx; }
+ void getColorRGBA( ColorRGBA& col ) const { col = facecolor_rgba; }
+ void getColorChannels( float& r, float& g, float& b ) const;
+ const char *getTextureName() { return texturename; }
+
+ void setFaceColor( dword col );
+ void setFaceColor( ColorRGBA col );
+ void setTextureName( const char *tname );
+
+ int NormalValid() const { return faceplane ? faceplane->NormalValid() : FALSE; }
+ int PlaneValid() const { return faceplane ? faceplane->PlaneValid() : FALSE; }
+ int MaterialAttached() const { return ( facematerial != NULL ); }
+ int MappingAttached() const { return ( facemapping != NULL ); }
+ int FaceTexMapped() const { return ( ( shadingtype & texmap_mask ) != 0 ); }
+
+ void CalcPlane( const Vertex3& vertex1, const Vertex3& vertex2, const Vertex3& vertex3 );
+ void AttachNormal( const Vector3& normal );
+ void AttachPlane( Plane *plane );
+ void AttachMaterial( Material *mat );
+
+ int ConvertColorIndexToRGB( char *palette, int changemode );
+
+ Vertex2& MapXY( int indx );
+ Vertex2& MapUV( int indx );
+
+ void WriteFaceInfo( FILE *fp ) const;
+ void WriteNormalInfo( FILE *fp ) const;
+ void WriteMappingInfo( FILE *fp ) const;
+
+public:
+ static int GetTypeIndex( const char *type );
+ static int GetColorModelIndex( const char *type );
+
+public:
+ static const char* material_strings[]; // strings for material specification
+
+private:
+ static const char* prop_strings[]; // strings for shading types
+ static const int prop_ids[]; // ids corresponding to strings
+ static const char* color_strings[]; // strings for color models
+ static const int color_ids[]; // ids corresponding to strings
+
+private:
+ int faceid; // face's object-globally unique id
+ Plane* faceplane; // face's plane (normal vector and offset)
+
+ int shadingtype; // shading type, determines how face is rendered
+ int colortype; // color type, determines how color is specified
+
+ dword facecolor_indx; // face's color represented as color index
+ ColorRGBA facecolor_rgba; // face's color represented as rgba quadruplet
+ Material* facematerial; // OpenGL-style material properties
+ TriMapping* facemapping; // mapping definition for this face
+ char* texturename; // name of texture if any
+};
+
+// typedef chunk of faces -----------------------------------------------------
+typedef Chunk<Face> FaceChunk;
+
+// construct a Face -----------------------------------------------------------
+inline Face::Face()
+{
+ faceid = -1; // -1 means id invalid
+ shadingtype = -1; // -1 means type invalid
+ colortype = -1; // -1 means type invalid
+ faceplane = NULL; // face's plane not calculated
+ facematerial = NULL; // no material attached
+ facemapping = NULL; // no mapping attached
+ texturename = NULL; // no texture name
+}
+
+// get face's normal vector ---------------------------------------------------
+inline Vector3 Face::getPlaneNormal() const
+{
+ CHECK_DEREFERENCING(
+ if ( ( faceplane == NULL ) || !faceplane->NormalValid() )
+ Error();
+ );
+ return faceplane->getPlaneNormal();
+}
+
+// set face's normal vector ---------------------------------------------------
+inline void Face::setPlaneNormal( const Vector3& normal )
+{
+ CHECK_DEREFERENCING(
+ if ( ( faceplane == NULL ) || !faceplane->NormalValid() )
+ Error();
+ );
+ faceplane->setPlaneNormal( normal );
+}
+
+// set shading type -----------------------------------------------------------
+inline void Face::setShadingType( int type )
+{
+ CHECK_DEREFERENCING(
+ if ( ( type & base_mask ) >= num_shading_types )
+ Error();
+ );
+ shadingtype = type;
+}
+
+// set color specified in terms of a color index ------------------------------
+inline void Face::setFaceColor( dword col )
+{
+ facecolor_indx = col;
+ colortype = indexed_col;
+}
+
+// set color specified in terms of (r,g,b,a) ----------------------------------
+inline void Face::setFaceColor( ColorRGBA col )
+{
+ facecolor_rgba = col;
+ colortype = rgb_col;
+}
+
+// fetch rgb color channels converted to [0.0, 1.0] range ---------------------
+inline void Face::getColorChannels( float& r, float& g, float& b ) const
+{
+ r = facecolor_rgba.R / 255.0f;
+ g = facecolor_rgba.G / 255.0f;
+ b = facecolor_rgba.B / 255.0f;
+}
+
+// return mapping coordinates in (x,y)-domain ---------------------------------
+inline Vertex2& Face::MapXY( int indx )
+{
+ if ( facemapping == NULL )
+ facemapping = new TriMapping;
+ return facemapping->getMapXY( indx );
+}
+
+// return mapping coordinates in (u,v)-domain ---------------------------------
+inline Vertex2& Face::MapUV( int indx )
+{
+ if ( facemapping == NULL )
+ facemapping = new TriMapping;
+ return facemapping->getMapUV( indx );
+}
+
+
+BSPLIB_NAMESPACE_END
+
+
+#endif // _FACE_H_
+
diff --git a/tool_src/BspLib/IOData3D.cpp b/tool_src/BspLib/IOData3D.cpp
new file mode 100644
index 0000000..54c3663
--- /dev/null
+++ b/tool_src/BspLib/IOData3D.cpp
@@ -0,0 +1,45 @@
+//-----------------------------------------------------------------------------
+// BSPLIB MODULE: IOData3D.cpp
+//
+// Copyright (c) 1997 by Markus Hadwiger
+// All Rights Reserved.
+//-----------------------------------------------------------------------------
+
+// bsplib header files
+#include "IOData3D.h"
+
+
+BSPLIB_NAMESPACE_BEGIN
+
+
+// constructor for generic I/O class ------------------------------------------
+//
+IOData3D::IOData3D( BspObjectList objectlist, const String& filename, int checkflags ) :
+ m_objectlist( objectlist ),
+ m_filename( filename )
+{
+ if ( m_filename.IsNULL() && ( checkflags & CHECK_FILENAME ) ) {
+ ErrorMessage( "[IOData3D]: valid filename must be supplied." );
+ HandleCriticalError();
+ }
+}
+
+
+// signatures of recognized file formats --------------------------------------
+//
+const char IOData3D::AOD_SIGNATURE_1_1[] = "#AOD V1.1 ascii";
+const char IOData3D::BSP_SIGNATURE_1_1[] = "#BSP V1.1 ascii";
+const char IOData3D::VRML_SIGNATURE_1_0[] = "#VRML V1.0 ascii";
+const char IOData3D::_3DX_SIGNATURE_1_0[] = "3DX File 1.0";
+//ADD_FORMAT:
+
+
+// static string scratch pad --------------------------------------------------
+//
+const int IOData3D::TEXTLINE_MAX = 1023;
+char IOData3D::line[ TEXTLINE_MAX + 1 ] = "";
+
+
+BSPLIB_NAMESPACE_END
+
+//-----------------------------------------------------------------------------
diff --git a/tool_src/BspLib/IOData3D.h b/tool_src/BspLib/IOData3D.h
new file mode 100644
index 0000000..de5250d
--- /dev/null
+++ b/tool_src/BspLib/IOData3D.h
@@ -0,0 +1,76 @@
+//-----------------------------------------------------------------------------
+// BSPLIB HEADER: IOData3D.h
+//
+// Copyright (c) 1997 by Markus Hadwiger
+// All Rights Reserved.
+//-----------------------------------------------------------------------------
+
+#ifndef _IODATA3D_H_
+#define _IODATA3D_H_
+
+// bsplib header files
+#include "BspLibDefs.h"
+#include "BspObjectList.h"
+#include "SystemIO.h"
+
+
+BSPLIB_NAMESPACE_BEGIN
+
+
+// base class for all input/output classes dealing with 3-D data --------------
+//
+class IOData3D : public virtual SystemIO {
+
+public:
+
+ // format identifiers
+ enum {
+ DONT_CREATE_OBJECT = 0x0000, // indicates to not create an object
+ UNKNOWN_FORMAT = 0x0001, // no valid signature detected
+ AOD_FORMAT_1_1 = 0x0002, // aod v1.1
+ VRML_FORMAT_1_0 = 0x0003, // vrml v1.0
+ BSP_FORMAT_1_1 = 0x0004, // bsp v1.1
+ _3DX_FORMAT_1_0 = 0x0005, // 3dx v1.0
+ //ADD_FORMAT:
+ };
+
+protected:
+
+ // construction flags
+ enum {
+ NO_CHECKS = 0x0000, // no validity checks whatsoever
+ CHECK_FILENAME = 0x0001, // check if supplied filename is valid pointer
+ ALL_CHECKS = 0x0001
+ };
+
+public:
+ IOData3D( BspObjectList objectlist, const String& filename, int checkflags = ALL_CHECKS );
+ ~IOData3D() { }
+
+ BspObjectList getObjectList() const { return m_objectlist; }
+ String getFileName() const { return m_filename; }
+ void setFileName( const String& filename ) { m_filename = filename; }
+
+protected:
+ BspObjectList m_objectlist; // object database
+ String m_filename; // name of data file
+
+protected:
+ // file signatures
+ static const char AOD_SIGNATURE_1_1[];
+ static const char VRML_SIGNATURE_1_0[];
+ static const char BSP_SIGNATURE_1_1[];
+ static const char _3DX_SIGNATURE_1_0[];
+ //ADD_FORMAT:
+
+ // storage for a single line of text
+ static const int TEXTLINE_MAX;
+ static char line[];
+};
+
+
+BSPLIB_NAMESPACE_END
+
+
+#endif // _IODATA3D_H_
+
diff --git a/tool_src/BspLib/InputData3D.cpp b/tool_src/BspLib/InputData3D.cpp
new file mode 100644
index 0000000..48954c0
--- /dev/null
+++ b/tool_src/BspLib/InputData3D.cpp
@@ -0,0 +1,175 @@
+//-----------------------------------------------------------------------------
+// BSPLIB MODULE: InputData3D.cpp
+//
+// Copyright (c) 1997-1998 by Markus Hadwiger
+// All Rights Reserved.
+//-----------------------------------------------------------------------------
+
+// bsplib header files
+#include "InputData3D.h"
+#include "AodInput.h"
+#include "BspInput.h"
+#include "VrmlFile.h"
+//ADD_FORMAT:
+
+
+BSPLIB_NAMESPACE_BEGIN
+
+
+// "virtual" constructor for different input format objects -------------------
+//
+InputData3D::InputData3D( BspObjectList objectlist, const char *filename, int format ) :
+ IOData3D( objectlist, String( filename ) ),
+ m_data( NULL )
+{
+ // create "real" input object according to format of input file
+ if ( format != DONT_CREATE_OBJECT ) {
+ switch ( m_objectformat = ReadFileSignature() ) {
+
+ case AOD_FORMAT_1_1:
+ m_data = new AodInput( objectlist, filename );
+ break;
+
+ case BSP_FORMAT_1_1:
+ m_data = new BspInput( objectlist, filename );
+ break;
+
+ case VRML_FORMAT_1_0:
+ m_data = new VrmlFile( objectlist, filename );
+ break;
+
+ case _3DX_FORMAT_1_0:
+ //m_data = new ThreeDXInput( objectlist, filename );
+ //TODO: add 3dx support
+ break;
+
+ //ADD_FORMAT:
+
+ default:
+ ErrorMessage( "[InputData3D]: Unrecognized input file format." );
+ m_objectformat = UNKNOWN_FORMAT;
+ }
+ } else {
+ m_objectformat = format;
+ }
+
+ m_inputok = m_data ? m_data->InputDataValid() : FALSE;
+}
+
+
+// virtual destructor ---------------------------------------------------------
+//
+InputData3D::~InputData3D()
+{
+ // delete "real" object
+ delete m_data;
+}
+
+
+// redirection to ParseObjectData() of "real" object --------------------------
+//
+int InputData3D::ParseObjectData()
+{
+ return m_data ? m_data->ParseObjectData() : FALSE;
+}
+
+
+// determine file type according to signature in first line -------------------
+//
+int InputData3D::ReadFileSignature()
+{
+ FileAccess sig( m_filename, "r" );
+ sig.ReadLine( line, TEXTLINE_MAX, CHECK_ERRORS );
+
+ int filetype = UNKNOWN_FORMAT;
+
+ if ( strncmp( line, AOD_SIGNATURE_1_1, strlen( AOD_SIGNATURE_1_1 ) ) == 0 )
+ filetype = AOD_FORMAT_1_1;
+ else if ( strncmp( line, BSP_SIGNATURE_1_1, strlen( BSP_SIGNATURE_1_1 ) ) == 0 )
+ filetype = BSP_FORMAT_1_1;
+ else if ( strncmp( line, VRML_SIGNATURE_1_0, strlen( VRML_SIGNATURE_1_0 ) ) == 0 )
+ filetype = VRML_FORMAT_1_0;
+ else if ( strncmp( line, _3DX_SIGNATURE_1_0, strlen( _3DX_SIGNATURE_1_0 ) ) == 0 )
+ filetype = _3DX_FORMAT_1_0;
+ //ADD_FORMAT:
+
+ return filetype;
+}
+
+
+// set flag controlling color index to RGB conversion -------------------------
+//
+int InputData3D::EnableRGBConversion( int enable )
+{
+ int precstate = getRGBConversionFlag();
+ if ( enable )
+ PostProcessingFlags |= CONVERT_COLINDXS_TO_RGB;
+ else
+ PostProcessingFlags &= ~CONVERT_COLINDXS_TO_RGB;
+ return precstate;
+}
+
+
+// set flag controlling application of object scale factors -------------------
+//
+int InputData3D::EnableScaleFactors( int enable )
+{
+ int precstate = getScaleFactorsFlag();
+ if ( enable )
+ PostProcessingFlags |= FILTER_SCALE_FACTORS;
+ else
+ PostProcessingFlags &= ~FILTER_SCALE_FACTORS;
+ return precstate;
+}
+
+
+// set flag controlling change of axes per command ----------------------------
+//
+int InputData3D::EnableAxesChange( int enable )
+{
+ int precstate = getAxesChangeFlag();
+ if ( enable )
+ PostProcessingFlags |= DO_AXES_EXCHANGE;
+ else
+ PostProcessingFlags &= ~DO_AXES_EXCHANGE;
+ return precstate;
+}
+
+
+// set flag controlling enforcement of maximum coordinate extent --------------
+//
+int InputData3D::EnableMaximumExtent( int enable, double extent )
+{
+ int precstate = getEnforceExtentsFlag();
+ MaximumExtentToForce = extent;
+ if ( enable )
+ PostProcessingFlags |= FORCE_MAXIMUM_EXTENT;
+ else
+ PostProcessingFlags &= ~FORCE_MAXIMUM_EXTENT;
+ return precstate;
+}
+
+
+// set flag controlling n-gon enabling/disabling -------------------------------
+//
+int InputData3D::EnableAllowNGons( int enable )
+{
+ int precstate = getAllowNGonFlag();
+ if ( enable )
+ PostProcessingFlags |= ALLOW_N_GONS;
+ else
+ PostProcessingFlags &= ~ALLOW_N_GONS;
+ return precstate;
+}
+
+
+// InputData3D specific static variables --------------------------------------
+//
+dword InputData3D::PostProcessingFlags = InputData3D::FILTER_SCALE_FACTORS | InputData3D::DO_AXES_EXCHANGE;
+double InputData3D::MaximumExtentToForce = 100.0;
+const char InputData3D::parser_err_str[] = "\nObject parser: **ERROR** ";
+
+
+BSPLIB_NAMESPACE_END
+
+//-----------------------------------------------------------------------------
diff --git a/tool_src/BspLib/InputData3D.h b/tool_src/BspLib/InputData3D.h
new file mode 100644
index 0000000..ab295b3
--- /dev/null
+++ b/tool_src/BspLib/InputData3D.h
@@ -0,0 +1,83 @@
+//-----------------------------------------------------------------------------
+// BSPLIB HEADER: InputData3D.h
+//
+// Copyright (c) 1997-1998 by Markus Hadwiger
+// All Rights Reserved.
+//-----------------------------------------------------------------------------
+
+#ifndef _INPUTDATA3D_H_
+#define _INPUTDATA3D_H_
+
+// bsplib header files
+#include "BspLibDefs.h"
+#include "BspObjectList.h"
+#include "IOData3D.h"
+
+
+BSPLIB_NAMESPACE_BEGIN
+
+
+// generic input class for 3-D data -------------------------------------------
+//
+class InputData3D : public IOData3D {
+
+public:
+ // flags for automatic postprocessing of input data
+ enum {
+ CONVERT_COLINDXS_TO_RGB = 0x0001,
+ FILTER_SCALE_FACTORS = 0x0002,
+ FILTER_AXES_DIR_SWITCH = 0x0004,
+ FILTER_AXES_EXCHANGE = 0x0008,
+ DO_AXES_EXCHANGE = FILTER_AXES_DIR_SWITCH | FILTER_AXES_EXCHANGE,
+ FORCE_MAXIMUM_EXTENT = 0x0010,
+ ALLOW_N_GONS = 0x0020,
+ };
+
+public:
+ InputData3D( BspObjectList objectlist, const char *filename, int format = UNKNOWN_FORMAT );
+ virtual ~InputData3D();
+
+ virtual int ParseObjectData(); // parse data file
+
+ int getObjectFormat() const { return m_objectformat; } // get format of "real" object
+ InputData3D* getRealObject() const { return m_data; } // get pointer to "real" object
+
+ int InputDataValid() const { return m_inputok; } // input data parsed ok?
+
+ // set/reset flags for automatic postprocessing of input data
+ static int EnableRGBConversion( int enable );
+ static int EnableScaleFactors( int enable );
+ static int EnableAxesChange( int enable );
+ static int EnableMaximumExtent( int enable, double extent );
+ static int EnableAllowNGons( int enable );
+
+ // get state of flags for automatic postprocessing of input data
+ static int getRGBConversionFlag() { return ( ( PostProcessingFlags & CONVERT_COLINDXS_TO_RGB ) == CONVERT_COLINDXS_TO_RGB ); }
+ static int getScaleFactorsFlag() { return ( ( PostProcessingFlags & FILTER_SCALE_FACTORS ) == FILTER_SCALE_FACTORS ); }
+ static int getAxesChangeFlag() { return ( ( PostProcessingFlags & DO_AXES_EXCHANGE ) == DO_AXES_EXCHANGE ); }
+ static int getEnforceExtentsFlag() { return ( ( PostProcessingFlags & FORCE_MAXIMUM_EXTENT ) == FORCE_MAXIMUM_EXTENT ); }
+ static double getMaxExtents() { return MaximumExtentToForce; }
+ static int getAllowNGonFlag() { return ( ( PostProcessingFlags & ALLOW_N_GONS ) == ALLOW_N_GONS ); }
+
+private:
+ int ReadFileSignature();
+
+protected:
+ static dword PostProcessingFlags;
+ static double MaximumExtentToForce;
+ static const char parser_err_str[];
+
+protected:
+ int m_objectformat;
+ int m_inputok;
+
+private:
+ InputData3D* m_data;
+};
+
+
+BSPLIB_NAMESPACE_END
+
+
+#endif // _INPUTDATA3D_H_
+
diff --git a/tool_src/BspLib/LineSeg.cpp b/tool_src/BspLib/LineSeg.cpp
new file mode 100644
index 0000000..7fc1872
--- /dev/null
+++ b/tool_src/BspLib/LineSeg.cpp
@@ -0,0 +1,71 @@
+//-----------------------------------------------------------------------------
+// BSPLIB MODULE: LineSeg.cpp
+//
+// Copyright (c) 1997-1998 by Markus Hadwiger
+// All Rights Reserved.
+//-----------------------------------------------------------------------------
+
+// bsplib headers
+#include "Vertex.h"
+
+
+BSPLIB_NAMESPACE_BEGIN
+
+
+// check if a single vertex lies on a line segment ----------------------------
+//
+int LineSeg2::PointOnLineSeg( const Vertex2& vertex ) const
+{
+ if ( m_dirvec.IsNullVector() )
+ return FALSE;
+
+ Vector2 vertexvec( vertex - m_basevtx );
+ Vector2 crossprod( vertexvec, m_dirvec );
+
+ if ( ( crossprod.VecLength() / m_dirvec.VecLength() ) > EPS_POINT_ON_LINE )
+ return FALSE;
+
+ double t;
+ if ( fabs( m_dirvec.X ) >= EPS_DENOM_ZERO )
+ t = vertexvec.X / m_dirvec.X;
+ else if ( fabs( m_dirvec.Y ) >= EPS_DENOM_ZERO )
+ t = vertexvec.Y / m_dirvec.Y;
+ else
+ return FALSE;
+
+ return ( ( t >= EPS_POINT_ON_LINESEG ) && ( t <= 1.0 - EPS_POINT_ON_LINESEG ) );
+}
+
+
+// check if a single vertex lies on a line segment ----------------------------
+//
+int LineSeg3::PointOnLineSeg( const Vertex3& vertex ) const
+{
+ if ( m_dirvec.IsNullVector() )
+ return FALSE;
+
+ Vector3 vertexvec( vertex - m_basevtx );
+ Vector3 crossprod( vertexvec, m_dirvec );
+
+ // check if point lies on line
+ if ( ( crossprod.VecLength() / m_dirvec.VecLength() ) > EPS_POINT_ON_LINE )
+ return FALSE;
+
+ // check if it lies between start- and endvertex of lineseg
+ double t;
+ if ( fabs( m_dirvec.X ) >= EPS_DENOM_ZERO )
+ t = vertexvec.X / m_dirvec.X;
+ else if ( fabs( m_dirvec.Y ) >= EPS_DENOM_ZERO )
+ t = vertexvec.Y / m_dirvec.Y;
+ else if ( fabs( m_dirvec.Z ) >= EPS_DENOM_ZERO )
+ t = vertexvec.Z / m_dirvec.Z;
+ else
+ return FALSE;
+
+ return ( ( t >= EPS_POINT_ON_LINESEG ) && ( t <= 1.0 - EPS_POINT_ON_LINESEG ) );
+}
+
+
+BSPLIB_NAMESPACE_END
+
+//-----------------------------------------------------------------------------
diff --git a/tool_src/BspLib/LineSeg2.h b/tool_src/BspLib/LineSeg2.h
new file mode 100644
index 0000000..96cdbb8
--- /dev/null
+++ b/tool_src/BspLib/LineSeg2.h
@@ -0,0 +1,46 @@
+//-----------------------------------------------------------------------------
+// BSPLIB HEADER: LineSeg2.h
+//
+// Copyright (c) 1997 by Markus Hadwiger
+// All Rights Reserved.
+//-----------------------------------------------------------------------------
+
+#ifndef _LINESEG2_H_
+#define _LINESEG2_H_
+
+// bsplib header files
+#include "BspLibDefs.h"
+#include "Vector2.h"
+
+
+BSPLIB_NAMESPACE_BEGIN
+
+
+// line segment in 2-space ----------------------------------------------------
+//
+class LineSeg2 {
+
+public:
+ LineSeg2( const Vertex2& basevtx, const Vector2& dirvec );
+ ~LineSeg2() { }
+
+ int PointOnLineSeg( const Vertex2& vertex ) const;
+
+private:
+ Vertex2 m_basevtx;
+ Vector2 m_dirvec;
+};
+
+// construct a LineSeg2 using a basevertex and a direction vector -------------
+inline LineSeg2::LineSeg2( const Vertex2& basevtx, const Vector2& dirvec )
+{
+ m_basevtx = basevtx;
+ m_dirvec = dirvec;
+}
+
+
+BSPLIB_NAMESPACE_END
+
+
+#endif // _LINESEG2_H_
+
diff --git a/tool_src/BspLib/LineSeg3.h b/tool_src/BspLib/LineSeg3.h
new file mode 100644
index 0000000..0f436f3
--- /dev/null
+++ b/tool_src/BspLib/LineSeg3.h
@@ -0,0 +1,46 @@
+//-----------------------------------------------------------------------------
+// BSPLIB HEADER: LineSeg3.h
+//
+// Copyright (c) 1997 by Markus Hadwiger
+// All Rights Reserved.
+//-----------------------------------------------------------------------------
+
+#ifndef _LINESEG3_H_
+#define _LINESEG3_H_
+
+// bsplib header files
+#include "BspLibDefs.h"
+#include "Vector3.h"
+
+
+BSPLIB_NAMESPACE_BEGIN
+
+
+// line segment in 3-space ----------------------------------------------------
+//
+class LineSeg3 {
+
+public:
+ LineSeg3( const Vertex3& basevtx, const Vector3& dirvec );
+ ~LineSeg3() { }
+
+ int PointOnLineSeg( const Vertex3& vertex ) const;
+
+private:
+ Vertex3 m_basevtx;
+ Vector3 m_dirvec;
+};
+
+// construct a LineSeg3 using a basevertex and a direction vector -------------
+inline LineSeg3::LineSeg3( const Vertex3& basevtx, const Vector3& dirvec )
+{
+ m_basevtx = basevtx;
+ m_dirvec = dirvec;
+}
+
+
+BSPLIB_NAMESPACE_END
+
+
+#endif // _LINESEG3_H_
+
diff --git a/tool_src/BspLib/Makefile b/tool_src/BspLib/Makefile
new file mode 100644
index 0000000..7385303
--- /dev/null
+++ b/tool_src/BspLib/Makefile
@@ -0,0 +1,62 @@
+# BspLib makefile
+
+CFILES = AodFormat.cpp\
+AodInput.cpp\
+AodOutput.cpp\
+BRep.cpp\
+BSPNode.cpp\
+BSPTree.cpp\
+BoundingBox.cpp\
+BspFormat.cpp\
+BspInput.cpp\
+BspObject.cpp\
+BspObjectList.cpp\
+BspOutput.cpp\
+BspTool.cpp\
+EpsAreas.cpp\
+Face.cpp\
+IOData3D.cpp\
+InputData3D.cpp\
+LineSeg.cpp\
+Mapping.cpp\
+ObjectAodFormat.cpp\
+ObjectBSPNode.cpp\
+ObjectBinFormat.cpp\
+ObjectBspFormat.cpp\
+OutputData3D.cpp\
+Polygon.cpp\
+PolygonList.cpp\
+SingleFormat.cpp\
+SingleInput.cpp\
+SingleOutput.cpp\
+SystemIO.cpp\
+Texture.cpp\
+Transform2.cpp\
+Transform3.cpp\
+TriMapping.cpp\
+Vertex.cpp\
+VertexChunk.cpp\
+VrmlFile.cpp
+
+
+CFLAGS = -g -O2 -I../QvLib -I. -fno-for-scope\
+ -Dstricmp=strcasecmp -Dstrnicmp=strncasecmp
+
+# use this for JPEG support
+#CFLAGS = -g -O2 -I../QvLib -I. -fno-for-scope\
+# -Dstricmp=strcasecmp -Dstrnicmp=strncasecmp -DUSE_JPEG_LIBRARY
+
+all: libbsp.a
+
+libbsp.a: $(CFILES:.cpp=.o)
+ ar rc libbsp.a $(CFILES:.cpp=.o)
+ ranlib libbsp.a
+
+.cpp.o:
+ gcc $(CFLAGS) -o $@ -c $<
+
+clean:
+ rm -f *.o *.a *~
+
+
+
diff --git a/tool_src/BspLib/Mapping.cpp b/tool_src/BspLib/Mapping.cpp
new file mode 100644
index 0000000..956d66c
--- /dev/null
+++ b/tool_src/BspLib/Mapping.cpp
@@ -0,0 +1,63 @@
+//-----------------------------------------------------------------------------
+// BSPLIB MODULE: Mapping.cpp
+//
+// Copyright (c) 1996-1998 by Markus Hadwiger
+// All Rights Reserved.
+//-----------------------------------------------------------------------------
+
+// bsplib headers
+#include "Mapping.h"
+#include "Chunk.h"
+
+
+BSPLIB_NAMESPACE_BEGIN
+
+
+// write mapping info in vertexindexes with mappings format -------------------
+//
+void Mapping::WriteMappingInfo( FILE *fp ) const
+{
+ // write list of vertex indexes
+ int i = 0;
+ for ( i = 0; i < numvertexindxs; i++ ) {
+ fprintf( fp, ( i == numvertexindxs - 1 ) ?
+ "%d\n" : "%d, ", facevertexindxs[ i ] + 1 );
+ }
+
+ // write (u,v) coordinates
+ for ( i = 0; i < numvertexindxs; i++ ) {
+ fprintf( fp, "%f, \t%f\n",
+ mappingcoordinates[ i ].getX(),
+ mappingcoordinates[ i ].getY() );
+ }
+
+ fprintf( fp, "\n" );
+}
+
+
+// error in search of vertices ------------------------------------------------
+//
+void Mapping::Error( int vertindx )
+{
+ char *line = new char[ 1024 ];
+// fprintf( stderr, "***ERROR*** Correspondence not found (%d)!\n", corrno + 1 );
+ sprintf( line, "***ERROR*** Correspondence not found!\nsought vertex %d", vertindx + 1 );
+ ErrorMessage( line );
+ delete line;
+/*
+ fprintf( stderr, "list of vertices:\n" );
+ for ( int i = 0; i < numvertexindxs; i++ )
+ fprintf( stderr, "vertex %d\n", facevertexindxs[ i ] + 1 );
+*/
+ HandleCriticalError();
+}
+
+
+// size of mapping chunk ------------------------------------------------------
+//
+template <> const int ChunkRep<Mapping>::CHUNK_SIZE = 256;
+
+
+BSPLIB_NAMESPACE_END
+
+//-----------------------------------------------------------------------------
diff --git a/tool_src/BspLib/Mapping.h b/tool_src/BspLib/Mapping.h
new file mode 100644
index 0000000..52d01d0
--- /dev/null
+++ b/tool_src/BspLib/Mapping.h
@@ -0,0 +1,89 @@
+//-----------------------------------------------------------------------------
+// BSPLIB HEADER: Mapping.h
+//
+// Copyright (c) 1996-1998 by Markus Hadwiger
+// All Rights Reserved.
+//-----------------------------------------------------------------------------
+
+#ifndef _MAPPING_H_
+#define _MAPPING_H_
+
+// bsplib header files
+#include "BspLibDefs.h"
+#include "Chunk.h"
+#include "SystemIO.h"
+#include "Vertex.h"
+
+
+BSPLIB_NAMESPACE_BEGIN
+
+
+#define V_FACEVTXMAX 32 // vertices per face (actually, per polygon)
+
+
+// class that describes mapping for face with many vertices -------------------
+//
+class Mapping : public virtual SystemIO {
+
+ void Error( int vertindx );
+
+public:
+ Mapping() { numvertexindxs = 0; }
+ ~Mapping() { }
+
+ void InsertFaceVertex( int vindx ) { facevertexindxs[ numvertexindxs++ ] = vindx; }
+ void SetCorrespondence( int vindx, Vertex2 vertex );
+ Vertex2 FetchMapPoint( int vertindx );
+
+ int getNumVertices() { return numvertexindxs; }
+ void setNumVertices( int num ) { numvertexindxs = num; }
+ void setMappingCoordinates( int k, const Vertex2& vertex);
+
+ void WriteMappingInfo( FILE *fp ) const;
+
+private:
+ int numvertexindxs;
+ int facevertexindxs[ V_FACEVTXMAX ];
+ Vertex2 mappingcoordinates[ V_FACEVTXMAX ];
+};
+
+// typedef chunk of mappings --------------------------------------------------
+typedef Chunk<Mapping> MappingChunk;
+
+// set mapping coordinates ----------------------------------------------------
+inline void Mapping::setMappingCoordinates( int k, const Vertex2& vertex)
+{
+ if ( k < V_FACEVTXMAX )
+ mappingcoordinates[ k ] = vertex;
+ else
+ Error( k );
+}
+
+// set single correspondence -------------------------------------------------
+inline void Mapping::SetCorrespondence( int vindx, Vertex2 vertex )
+{
+ if ( numvertexindxs < V_FACEVTXMAX ) {
+ facevertexindxs[ numvertexindxs ] = vindx;
+ mappingcoordinates[ numvertexindxs ] = vertex;
+ numvertexindxs++;
+ } else {
+ Error( numvertexindxs );
+ }
+}
+
+// fetch corresponding mapping to face vertex ---------------------------------
+inline Vertex2 Mapping::FetchMapPoint( int vertindx )
+{
+ for ( int i = 0; i < numvertexindxs; i++ )
+ if ( facevertexindxs[ i ] == vertindx )
+ return mappingcoordinates[ i ];
+ Error( vertindx );
+ return Vertex2( 0, 0 ); // never reached
+}
+
+
+BSPLIB_NAMESPACE_END
+
+
+#endif // _MAPPING_H_
+
diff --git a/tool_src/BspLib/Material.h b/tool_src/BspLib/Material.h
new file mode 100644
index 0000000..a0c0f1f
--- /dev/null
+++ b/tool_src/BspLib/Material.h
@@ -0,0 +1,57 @@
+//-----------------------------------------------------------------------------
+// BSPLIB HEADER: Material.h
+//
+// Copyright (c) 1997-1998 by Markus Hadwiger
+// All Rights Reserved.
+//-----------------------------------------------------------------------------
+
+#ifndef _MATERIAL_H_
+#define _MATERIAL_H_
+
+// bsplib header files
+#include "BspLibDefs.h"
+#include "SystemIO.h"
+
+
+BSPLIB_NAMESPACE_BEGIN
+
+
+// class that describes OpenGL-style material properties ----------------------
+//
+class Material {
+
+public:
+ Material() { }
+ ~Material() { }
+
+ ColorRGBA getAmbientColor() { return ambientcolor; }
+ ColorRGBA getDiffuseColor() { return diffusecolor; }
+ ColorRGBA getSpecularColor() { return specularcolor; }
+ ColorRGBA getEmissiveColor() { return emissivecolor; }
+
+ void setAmbientColor( ColorRGBA col ) { ambientcolor = col; ambientcolor.A = 255; }
+ void setDiffuseColor( ColorRGBA col ) { diffusecolor = col; diffusecolor.A = 255; }
+ void setSpecularColor( ColorRGBA col ) { specularcolor = col; specularcolor.A = 255; }
+ void setEmissiveColor( ColorRGBA col ) { emissivecolor = col; emissivecolor.A = 255; }
+
+ float getShininess() { return shininess; }
+ float getTransparency() { return transparency; }
+
+ void setShininess( float s ) { shininess = s; }
+ void setTransparency( float t ) { transparency = t; }
+
+private:
+ ColorRGBA ambientcolor; // OpenGL-style material properties
+ ColorRGBA diffusecolor;
+ ColorRGBA specularcolor;
+ ColorRGBA emissivecolor;
+ float shininess;
+ float transparency;
+};
+
+
+BSPLIB_NAMESPACE_END
+
+
+#endif // _MATERIAL_H_
+
diff --git a/tool_src/BspLib/ObjectAodFormat.cpp b/tool_src/BspLib/ObjectAodFormat.cpp
new file mode 100644
index 0000000..be09e64
--- /dev/null
+++ b/tool_src/BspLib/ObjectAodFormat.cpp
@@ -0,0 +1,200 @@
+//-----------------------------------------------------------------------------
+// BSPLIB MODULE: ObjectAodFormat.cpp
+//
+// Copyright (c) 1996-1998 by Markus Hadwiger
+// All Rights Reserved.
+//-----------------------------------------------------------------------------
+
+// bsplib header files
+#include "BspLibDefs.h"
+#include "ObjectAodFormat.h"
+
+
+BSPLIB_NAMESPACE_BEGIN
+
+
+// write list of vertices -----------------------------------------------------
+//
+int ObjectAodFormat::WriteVertexList( FileAccess& output )
+{
+ if ( numvertices > 0 ) {
+
+ output.WriteLine( "; list of all vertices comprising the object -----------------------------\n" );
+ output.WriteLine( "; numbering starts with 1\n" );
+
+ sprintf( line, "%s\n", _vertices_str );
+ output.WriteLine( line );
+
+ for ( int i = 0; i < numvertices; i++ ) {
+ sprintf( line, "%f,\t%f,\t%f\t; %d\n",
+ vertexlist[ i ].getX(),
+ vertexlist[ i ].getY(),
+ vertexlist[ i ].getZ(),
+ i + 1 );
+ output.WriteLine( line );
+ }
+
+ output.WriteLine( "\n" );
+ }
+
+ return output.Status();
+}
+
+
+// write list of faces --------------------------------------------------------
+//
+int ObjectAodFormat::WriteFaceList( FileAccess& output )
+{
+ if ( numpolygons > 0 ) {
+
+ output.WriteLine( "; list of all faces ------------------------------------------------------\n" );
+ output.WriteLine( "; numbering starts with 1\n" );
+
+ sprintf( line, "%s\n", _faces_str );
+ output.WriteLine( line );
+
+ int i = 0;
+ WriteFaceInfo( output, polygonlist.FetchHead(), i );
+ output.WriteLine( "\n" );
+ }
+
+ return output.Status();
+}
+
+
+// write info about single face (vertexindexes comprising the face) -----------
+//
+void ObjectAodFormat::WriteFaceInfo( FileAccess& output, Polygon *poly, int& num )
+{
+#if 0
+ if ( poly->getNext() )
+ WriteFaceInfo( output, poly->getNext(), num );
+
+ poly->WriteVertexList( output, FALSE );
+ sprintf( line, "\t\t; %d\n", ++num );
+ output.WriteLine( line );
+
+#else
+ // scan polygons according to face id
+ Polygon *scan = NULL;
+ for ( int facecount = 0; ; facecount++ ) {
+ for ( scan = poly; scan; scan = scan->getNext() ) {
+ if ( scan->getFaceId() == facecount )
+ break;
+ }
+ if ( scan == NULL )
+ break;
+ scan->WriteVertexList( output, FALSE );
+ sprintf( line, "\t\t; %d\n", ++num );
+ output.WriteLine( line );
+ }
+
+ //NOTE:
+ // if there is no exact 1:1 correspondence between
+ // polygons and faces this will not work correctly!
+ // since for each face only one polygon is written,
+ // tessellated vrml cones and cylinders cannot be
+ // correctly written to AOD files.
+
+#endif
+}
+
+
+// write surface properties of faces ------------------------------------------
+//
+int ObjectAodFormat::WriteFaceProperties( FileAccess& output )
+{
+ if ( numfaces > 0 ) {
+
+ output.WriteLine( "; face material properties (color, texture, etc.) ------------------------\n" );
+
+ sprintf( line, "%s\n", _faceproperties_str );
+ output.WriteLine( line );
+
+ for ( int i = 0; i < numfaces; i++ )
+ facelist[ i ].WriteFaceInfo( output );
+
+ output.WriteLine( "\n" );
+ }
+
+ return output.Status();
+}
+
+
+// write face normals ---------------------------------------------------------
+//
+int ObjectAodFormat::WriteNormals( FileAccess& output )
+{
+ if ( numnormals > 0 ) {
+
+ output.WriteLine( "; face normals -----------------------------------------------------------\n" );
+
+ sprintf( line, "%s\n", _facenormals_str );
+ output.WriteLine( line );
+
+ for ( int i = 0; i < numfaces /*numnormals*/; i++ )
+ facelist[ i ].WriteNormalInfo( output );
+
+ output.WriteLine( "\n" );
+ }
+
+ return output.Status();
+}
+
+
+// write list of textures -----------------------------------------------------
+//
+int ObjectAodFormat::WriteTextureList( FileAccess& output )
+{
+ if ( numtextures > 0 ) {
+
+ output.WriteLine( "; texture definitions (sizes and filenames) ------------------------------\n" );
+
+ sprintf( line, "%s\n", _textures_str );
+ output.WriteLine( line );
+
+ for ( int i = 0; i < numtextures; i++ )
+ texturelist[ i ].WriteInfo( output );
+ }
+
+ return output.Status();
+}
+
+
+// write list of mapping coordinates (correspondences) ------------------------
+//
+int ObjectAodFormat::WriteMappingList( FileAccess& output )
+{
+ if ( numtexmappedfaces > 0 ) {
+
+ output.WriteLine( "; mapping parameters for textured faces ----------------------------------\n" );
+ sprintf( line, "%s\n", _correspondences_str );
+ output.WriteLine( line );
+ output.WriteLine( "\n" );
+
+ int curfaceno = 0;
+ for ( int i = 0; i < numtexmappedfaces; i++, curfaceno++ ) {
+ while ( !facelist[ curfaceno ].FaceTexMapped() )
+ curfaceno++;
+ sprintf( line, "; correspondence %d (face %d)\n", i + 1, curfaceno + 1 );
+ output.WriteLine( line );
+
+ if ( mappinglist.getNumElements() > i )
+ mappinglist[ i ].WriteMappingInfo( output );
+ else
+ facelist[ curfaceno ].WriteMappingInfo( output );
+ }
+ }
+
+ return output.Status();
+}
+
+
+// string scratchpad ----------------------------------------------------------
+//
+char ObjectAodFormat::line[ 1024 ] = "";
+
+
+BSPLIB_NAMESPACE_END
+
+//-----------------------------------------------------------------------------
diff --git a/tool_src/BspLib/ObjectAodFormat.h b/tool_src/BspLib/ObjectAodFormat.h
new file mode 100644
index 0000000..e900616
--- /dev/null
+++ b/tool_src/BspLib/ObjectAodFormat.h
@@ -0,0 +1,52 @@
+//-----------------------------------------------------------------------------
+// BSPLIB HEADER: ObjectAodFormat.h
+//
+// Copyright (c) 1997 by Markus Hadwiger
+// All Rights Reserved.
+//-----------------------------------------------------------------------------
+
+#ifndef _OBJECTAODFORMAT_H_
+#define _OBJECTAODFORMAT_H_
+
+// bsplib header files
+#include "BspLibDefs.h"
+#include "BspObject.h"
+#include "AodFormat.h"
+
+
+BSPLIB_NAMESPACE_BEGIN
+
+
+// BspObject capable of AodFormat I/O operations ------------------------------
+//
+class ObjectAodFormat : public BspObject, public AodFormat {
+
+public:
+ ObjectAodFormat( BspObject& object, AodFormat& format );
+ ~ObjectAodFormat() { }
+
+ virtual int WriteVertexList( FileAccess& output );
+ virtual int WriteFaceList( FileAccess& output );
+ virtual void WriteFaceInfo( FileAccess& output, Polygon *poly, int& num );
+ virtual int WriteFaceProperties( FileAccess& output );
+ virtual int WriteTextureList( FileAccess& output );
+ virtual int WriteMappingList( FileAccess& output );
+ virtual int WriteNormals( FileAccess& output );
+
+private:
+ static char line[]; // scratchpad
+};
+
+// construct by copying base class objects ------------------------------------
+inline ObjectAodFormat::ObjectAodFormat( BspObject& object, AodFormat& format ) :
+ BspObject( object ),
+ AodFormat( format )
+{
+}
+
+
+BSPLIB_NAMESPACE_END
+
+
+#endif // _OBJECTAODFORMAT_H_
+
diff --git a/tool_src/BspLib/ObjectBSPNode.cpp b/tool_src/BspLib/ObjectBSPNode.cpp
new file mode 100644
index 0000000..53e08a1
--- /dev/null
+++ b/tool_src/BspLib/ObjectBSPNode.cpp
@@ -0,0 +1,170 @@
+//-----------------------------------------------------------------------------
+// BSPLIB MODULE: ObjectBSPNode.cpp
+//
+// Copyright (c) 1997-1998 by Markus Hadwiger
+// All Rights Reserved.
+//-----------------------------------------------------------------------------
+
+// bsplib header files
+#include "ObjectBSPNode.h"
+
+
+BSPLIB_NAMESPACE_BEGIN
+
+
+// create linear object list from objects attached to nodes -------------------
+//
+BspObject *ObjectBSPNode::CreateObjectList()
+{
+ // process tree from its leaves upwards
+ BspObject *front = frontsubtree ? frontsubtree->CreateObjectList() : NULL;
+ BspObject *back = backsubtree ? backsubtree->CreateObjectList() : NULL;
+ BspObject *scan = NULL;
+ if ( front != NULL ) {
+ // append back-list to front-list if front-list exists
+
+ for ( scan = front; scan->next; scan = scan->next ) ;
+ scan->next = back;
+ }
+
+ if ( boundingbox != NULL ) {
+ static BspObject *headobject;
+ if ( ( headobject = boundingbox->containedobject ) != NULL ) {
+ // scan list and merge all subsequent objects into head object
+ static BspObject *scan;
+ for ( scan = headobject->next; scan; scan = scan->next ) {
+ headobject->MergeObjects( scan );
+ // invalidate other object's polygonlist
+ scan->getPolygonList().InvalidateList();
+ }
+ // delete all objects that have been merged into head
+ delete headobject->next;
+ // single object, no list
+ headobject->next = NULL;
+ // return head object now encompassing entire list
+ return headobject;
+ } else {
+ // return contatenated list for internal nodes with bounding box
+ return front ? front : back;
+ }
+ } else {
+ // simply return contatenated list for nodes without bounding box
+ return front ? front : back;
+ }
+}
+
+
+// merge all objects contained in tree into passed object ---------------------
+//
+void ObjectBSPNode::MergeTreeNodeObjects( BspObject *newobject )
+{
+ if ( separatorplane == NULL ) {
+ // merge leaf into already existing cumulative object
+ newobject->MergeObjects( boundingbox->containedobject );
+ // unlink list from already merged object
+ boundingbox->containedobject->next = NULL;
+
+ //NOTE:
+ // the merged objects must not be freed at this point,
+ // since they are still needed for the subsequent merging
+ // of bsp trees! nevertheless, their next field must be
+ // set to null, to prevent crosslinking of leaves.
+
+ } else {
+ // process subtrees; order not relevant in any way
+ if ( frontsubtree ) frontsubtree->MergeTreeNodeObjects( newobject );
+ if ( backsubtree ) backsubtree->MergeTreeNodeObjects( newobject );
+ }
+}
+
+
+// create unified (separator plane/polygon bsp) from object bsp tree ----------
+//
+BSPNode *ObjectBSPNode::CreateUnifiedBSPTree()
+{
+ //NOTE:
+ // the BSPTrees of the BspObjects are invalidated after they
+ // have been integrated into the unified BSPTree. this is done
+ // to prevent accidental deletion at the time when the underlying
+ // objects will be deleted. (which will normally be done in
+ // DeleteNodeBspObjects() later on.)
+
+ if ( separatorplane == NULL ) {
+ // node is leaf: return object's bsp tree
+ static BSPNode *root;
+ root = boundingbox->containedobject->getBSPTree().getRoot();
+ boundingbox->containedobject->getBSPTree().InvalidateTree();
+ return root;
+ } else {
+ // node is separator (internal node): create separator bsp node
+ BSPNode *front = frontsubtree ? frontsubtree->CreateUnifiedBSPTree() : NULL;
+ BSPNode *back = backsubtree ? backsubtree->CreateUnifiedBSPTree() : NULL;
+ return new BSPNode( front, back, NULL, NULL, separatorplane, NULL );
+ }
+}
+
+
+// merge all objects contained in object bsp tree into single object and tree -
+//
+BspObject *ObjectBSPNode::CreateMergedBSPTree()
+{
+ //NOTE:
+ // this function may only be invoked on ObjectBSPNodes which
+ // actually contain objects with valid BSPTrees! so, it may only
+ // be invoked after successful bsp compilation.
+
+ // create new object to encompass all other objects
+ BspObject *newobject = new BspObject;
+
+ // merge objects of nodes into one big object
+ MergeTreeNodeObjects( newobject );
+
+ // create unified bsp tree for all contained objects and their respective separators
+ newobject->getBSPTree().InitTree( CreateUnifiedBSPTree() );
+ newobject->numbsppolygons = 0;
+ newobject->getBSPTree()->NumberBSPNodes( newobject->numbsppolygons ); //CAVEAT: sind nicht alles Polygone!!! //TODO
+
+ newobject->UpdateAttributeNumbers();
+ return newobject;
+}
+
+
+// delete all BSPObjects attached to bounding boxes contained in tree ---------
+//
+void ObjectBSPNode::DeleteNodeBspObjects()
+{
+ if ( separatorplane == NULL ) {
+ // delete leaf
+ delete boundingbox->containedobject;
+ boundingbox->containedobject = NULL;
+ } else {
+ // detach separator plane from node to prevent accidental
+ // deletion later on. (planes are still used by unified
+ // bsp tree.)
+ separatorplane = NULL;
+ // process subtrees; order not relevant in any way
+ if ( frontsubtree ) frontsubtree->DeleteNodeBspObjects();
+ if ( backsubtree ) backsubtree->DeleteNodeBspObjects();
+ }
+}
+
+
+// traverse bsp tree (preorder) and number nodes as encountered ---------------
+//
+void ObjectBSPNode::NumberBSPNodes( int& curno )
+{
+ // never used
+}
+
+
+// write bsp tree structure to output file (preorder traversal) ---------------
+//
+void ObjectBSPNode::WriteBSPTree( FILE *fp ) const
+{
+ // never used
+}
+
+
+BSPLIB_NAMESPACE_END
+
+//-----------------------------------------------------------------------------
diff --git a/tool_src/BspLib/ObjectBSPNode.h b/tool_src/BspLib/ObjectBSPNode.h
new file mode 100644
index 0000000..e5301fe
--- /dev/null
+++ b/tool_src/BspLib/ObjectBSPNode.h
@@ -0,0 +1,70 @@
+//-----------------------------------------------------------------------------
+// BSPLIB HEADER: ObjectBSPNode.h
+//
+// Copyright (c) 1997-1998 by Markus Hadwiger
+// All Rights Reserved.
+//-----------------------------------------------------------------------------
+
+#ifndef _OBJECTBSPNODE_H_
+#define _OBJECTBSPNODE_H_
+
+// bsplib header files
+#include "BspLibDefs.h"
+#include "BoundingBox.h"
+#include "BspObject.h"
+#include "Plane.h"
+
+
+BSPLIB_NAMESPACE_BEGIN
+
+
+// node of object bsp tree (a bsp tree of whole objects instead of polygons) --
+//
+class ObjectBSPNode {
+
+public:
+ ObjectBSPNode( ObjectBSPNode *front = NULL, ObjectBSPNode *back = NULL, Plane *sep = NULL, BoundingBox *bbox = NULL, int id = -1 );
+ ~ObjectBSPNode() { delete separatorplane; delete boundingbox; delete frontsubtree; delete backsubtree; }
+
+ void NumberBSPNodes( int& curno );
+ void WriteBSPTree( FILE *fp ) const;
+
+ BspObject* CreateObjectList();
+ BspObject* CreateMergedBSPTree();
+
+ void DeleteNodeBspObjects();
+
+ int getNodeNumber() const { return nodenumber; }
+ Plane* getSeparatorPlane() const { return separatorplane; }
+ BoundingBox* getBoundingBox() const { return boundingbox; }
+ ObjectBSPNode* getFrontSubtree() const { return frontsubtree; }
+ ObjectBSPNode* getBackSubtree() const { return backsubtree; }
+
+private:
+ void MergeTreeNodeObjects( BspObject *newobject );
+ BSPNode* CreateUnifiedBSPTree();
+
+private:
+ int nodenumber; // this node's id
+ Plane* separatorplane; // plane inducing two halfspaces; NULL for leaves
+ BoundingBox* boundingbox; // attached bounding box; NULL for internal nodes
+ ObjectBSPNode* frontsubtree; // tree in front halfspace
+ ObjectBSPNode* backsubtree; // tree in back halfspace
+};
+
+// construct node -------------------------------------------------------------
+inline ObjectBSPNode::ObjectBSPNode( ObjectBSPNode *front, ObjectBSPNode *back, Plane *sep, BoundingBox *bbox, int id )
+{
+ frontsubtree = front;
+ backsubtree = back;
+ separatorplane = sep;
+ boundingbox = bbox;
+ nodenumber = id;
+}
+
+
+BSPLIB_NAMESPACE_END
+
+
+#endif // _OBJECTBSPNODE_H_
+
diff --git a/tool_src/BspLib/ObjectBSPTree.h b/tool_src/BspLib/ObjectBSPTree.h
new file mode 100644
index 0000000..5d505bc
--- /dev/null
+++ b/tool_src/BspLib/ObjectBSPTree.h
@@ -0,0 +1,97 @@
+//-----------------------------------------------------------------------------
+// BSPLIB HEADER: ObjectBSPTree.h
+//
+// Copyright (c) 1997-1998 by Markus Hadwiger
+// All Rights Reserved.
+//-----------------------------------------------------------------------------
+
+#ifndef _OBJECTBSPTREE_H_
+#define _OBJECTBSPTREE_H_
+
+// bsplib header files
+#include "BspLibDefs.h"
+#include "ObjectBSPNode.h"
+
+
+BSPLIB_NAMESPACE_BEGIN
+
+
+// bsp tree of objects; basically pointer to root node (representation class) -
+//
+class ObjectBSPTreeRep {
+
+ friend class ObjectBSPTree;
+
+private:
+ ObjectBSPTreeRep() : ref_count( 0 ) { root = NULL; }
+ ~ObjectBSPTreeRep() { delete root; }
+
+ void KillTree() { delete root; root = NULL; }
+ ObjectBSPNode* InitTree( ObjectBSPNode *rootnode );
+ ObjectBSPNode* getRoot() { return root; }
+
+ int TreeEmpty() const { return ( root == NULL ); }
+
+private:
+ int ref_count;
+ ObjectBSPNode* root;
+};
+
+// init with entire tree of ObjectBSPNode objects -----------------------------
+inline ObjectBSPNode *ObjectBSPTreeRep::InitTree( ObjectBSPNode *rootnode )
+{
+ delete root;
+ return ( root = rootnode );
+}
+
+
+// bsp tree of objects; basically pointer to root node (handle class) ---------
+//
+class ObjectBSPTree {
+
+public:
+ ObjectBSPTree() { rep = new ObjectBSPTreeRep; rep->ref_count = 1; }
+ ~ObjectBSPTree() { if ( --rep->ref_count == 0 ) delete rep; }
+
+ ObjectBSPTree( const ObjectBSPTree& copyobj );
+ ObjectBSPTree& operator =( const ObjectBSPTree& copyobj );
+
+ // pass most operations through to ObjectBSPNode
+ ObjectBSPNode* operator->() { return rep->getRoot(); }
+
+ void KillTree() { rep->KillTree(); }
+ ObjectBSPNode* InitTree( ObjectBSPNode *rootnode ) { return rep->InitTree( rootnode ); }
+ ObjectBSPNode* getRoot() { return rep->getRoot(); }
+
+ int TreeEmpty() const { return rep->TreeEmpty(); }
+
+private:
+ ObjectBSPTreeRep* rep;
+};
+
+// copy constructor -----------------------------------------------------------
+inline ObjectBSPTree::ObjectBSPTree( const ObjectBSPTree& copyobj )
+{
+ rep = copyobj.rep;
+ rep->ref_count++;
+}
+
+// assignment operator --------------------------------------------------------
+inline ObjectBSPTree& ObjectBSPTree::operator =( const ObjectBSPTree& copyobj )
+{
+ if ( &copyobj != this ) {
+ if ( --rep->ref_count == 0 ) {
+ delete rep;
+ }
+ rep = copyobj.rep;
+ rep->ref_count++;
+ }
+ return *this;
+}
+
+
+BSPLIB_NAMESPACE_END
+
+
+#endif // _OBJECTBSPTREE_H_
+
diff --git a/tool_src/BspLib/ObjectBinFormat.cpp b/tool_src/BspLib/ObjectBinFormat.cpp
new file mode 100644
index 0000000..c0b44a0
--- /dev/null
+++ b/tool_src/BspLib/ObjectBinFormat.cpp
@@ -0,0 +1,758 @@
+//-----------------------------------------------------------------------------
+// BSPLIB MODULE: ObjectBinFormat.cpp
+//
+// Copyright (c) 1998-1999 by Markus Hadwiger
+// All Rights Reserved.
+//-----------------------------------------------------------------------------
+
+// bsplib header files
+#include "BspLibDefs.h"
+#include "ObjectBinFormat.h"
+#include "Transform2.h"
+
+// parsec header files
+#include "../../src/libparsec/include/od_geomv.h"
+#include "../../src/libparsec/include/od_odt.h"
+
+
+#define VERTEX_SCALE_FAC ( 1.0 / 20.0 )
+
+// default to defining.
+#ifndef BIG_ENDIAN
+//#define BIG_ENDIAN
+#endif
+
+#ifdef BIG_ENDIAN
+
+#define SWAP_16(s) ( ((word)(s) >> 8) | ((word)(s) << 8) )
+#define SWAP_32(l) ( ( ((dword)(l) ) << 24 ) | \
+ ( ((dword)(l) ) >> 24 ) | \
+ ( ((dword)(l) & 0x0000ff00) << 8 ) | \
+ ( ((dword)(l) & 0x00ff0000) >> 8 ) )
+
+#else
+
+#define SWAP_16(s) ( s )
+#define SWAP_32(l) ( l )
+
+#endif // BIG_ENDIAN
+
+
+void OD2_Geomv_out( float *value )
+{
+
+ dword tmp = SWAP_32( DW32( *value ) );
+ *(dword *)value = tmp;
+
+}
+
+
+BSPLIB_NAMESPACE_BEGIN
+
+
+// calculate affine mapping using face's mapping specification ----------------
+//
+void ObjectBinFormat::ODT_CalcAffineMapping( Face& face, dword *dmatrx )
+{
+ Vertex2 vtx;
+ double mat[3][3];
+ int i = 0;
+ // build xyw-matrix
+ for ( i = 0; i < 3; i++ ) {
+ vtx = face.MapXY( i );
+ mat[ 0 ][ i ] = vtx.getX() * VERTEX_SCALE_FAC;
+ mat[ 1 ][ i ] = vtx.getY() * -VERTEX_SCALE_FAC;
+ mat[ 2 ][ i ] = vtx.getW() * -VERTEX_SCALE_FAC;
+ }
+ Transform2 xyw( (const double(*)[3]) mat );
+
+ // build uv1-matrix
+ for ( i = 0; i < 3; i++ ) {
+ vtx = face.MapUV( i );
+ mat[ 0 ][ i ] = vtx.getX();
+ mat[ 1 ][ i ] = vtx.getY();
+ mat[ 2 ][ i ] = vtx.getW();
+ }
+ Transform2 uv1( (const double(*)[3]) mat );
+
+ // invert uv1
+ Transform2 uv1i;
+ if ( !uv1.Inverse( uv1i ) ) {
+ ErrorMessage( "ObjectBinFormat::ODT_CalcAffineMapping(): Collinear mapping coordinates encountered!" );
+ }
+
+ // calculate affine mapping
+ Transform2 map( xyw );
+ map.Concat( uv1i );
+
+ // store result into destination structure (9 coefficients)
+ double (*affinemap)[ 3 ] = ( double (*)[3] ) map.LinMatrixAccess();
+ fixed_t (*dest)[ 4 ] = (fixed_t (*)[4]) dmatrx;
+ for ( i = 0; i < 3; i++ ) {
+ dest[ i ][ 0 ] = FLOAT_TO_FIXED( affinemap[ i ][ 0 ] );
+ dest[ i ][ 1 ] = FLOAT_TO_FIXED( affinemap[ i ][ 1 ] );
+ dest[ i ][ 2 ] = FLOAT_TO_FIXED( 0.0 ); // third column is zero
+ dest[ i ][ 3 ] = FLOAT_TO_FIXED( affinemap[ i ][ 2 ] );
+ }
+}
+
+
+// create object recognizeable by engine (ODT format) -------------------------
+//
+byte *ObjectBinFormat::ODT_CreateEngineObject( int& memblocksize )
+{
+ // fetch object data lists
+ VertexChunk& vtxlist = getVertexList();
+ PolygonList& polylist = getPolygonList();
+ FaceChunk& facelist = getFaceList();
+ TextureChunk& texlist = getTextureList();
+
+ // calculate some basic numbers
+ int numvertices = getNumVertices();
+ int numnormals = getNumNormals();
+ int numallvtxs = numvertices + numnormals;
+ int numpolygons = BSPTreeAvailable() ? getBspPolygons() : getNumPolygons();
+ int numfaces = getNumFaces();
+ int numbspnodes = getBspPolygons();
+
+ // count number of vertices of all polygons
+ int numvertexindices = 0;
+ if ( BSPTreeAvailable() )
+ bsptree->SumVertexNums( numvertexindices );
+ else
+ numvertexindices = polylist.FetchHead()->SumVertexNumsEntireList();
+
+ // calculate size of entire object structure
+ size_t objectmemsize = sizeof( ODT_GenObject ) + // generic object header
+ sizeof( ODT_Vertex3 ) * numallvtxs + // object space vertices
+ sizeof( ODT_Vertex3 ) * numallvtxs + // view space vertices
+ sizeof( ODT_ProjPoint ) * numallvtxs + // projected vertices
+ sizeof( ODT_SPoint ) * numallvtxs + // screen space vertices
+ sizeof( ODT_Poly ) * numpolygons + // polygon control data
+ sizeof( dword ) * numvertexindices + // polygon vertindx lists
+ sizeof( ODT_Face ) * numfaces + // face control data
+ sizeof( ODT_VisPolys ) + sizeof( dword ) * numpolygons + // vispolylist
+ sizeof( ODT_BSPNode ) * ( numbspnodes + 1 ); // bsp tree
+
+ // allocate memory for all object data (only excluding texturemaps)
+ ODT_GenObject *binobj = (ODT_GenObject *) new char[ objectmemsize ];
+ memset( binobj, 0x00, objectmemsize );
+
+ // fill in objectheader
+ binobj->NextObj = NULL;
+ binobj->PrevObj = NULL;
+ binobj->NextVisObj = NULL;
+ binobj->InstanceSize = sizeof( ODT_GenObject );
+ binobj->NumVerts = numallvtxs;
+ binobj->NumPolyVerts = numvertices;
+ binobj->NumNormals = numnormals;
+ binobj->VertexList = (ODT_Vertex3 *) ( binobj + 1 );
+ binobj->X_VertexList = (ODT_Vertex3 *)
+ ( (char *) binobj->VertexList + sizeof( ODT_Vertex3 ) * numallvtxs );
+ binobj->P_VertexList = (ODT_ProjPoint *)
+ ( (char *) binobj->X_VertexList + sizeof( ODT_Vertex3 ) * numallvtxs );
+ binobj->S_VertexList = (ODT_SPoint *)
+ ( (char *) binobj->P_VertexList + sizeof( ODT_ProjPoint ) * numallvtxs );
+ binobj->NumPolys = numpolygons;
+ binobj->PolyList = (ODT_Poly *)
+ ( (char *) binobj->S_VertexList + sizeof( ODT_SPoint ) * numallvtxs );
+ binobj->NumFaces = numfaces;
+ binobj->FaceList = (ODT_Face *)
+ ( (char *) binobj->PolyList + sizeof( ODT_Poly ) * numpolygons + sizeof( dword ) * numvertexindices );
+ binobj->VisPolyList = (ODT_VisPolys *)
+ ( (char *) binobj->FaceList + sizeof( ODT_Face ) * numfaces );
+ binobj->BSPTree = (ODT_BSPNode *)
+ ( (char *) binobj->VisPolyList + sizeof( ODT_VisPolys ) + sizeof( dword ) * numpolygons );
+
+ // calculate bounding sphere for object
+ double maxx = -100000; double minx = 100000;
+ double maxy = -100000; double miny = 100000;
+ double maxz = -100000; double minz = 100000;
+ double maxsphere = 0;
+ int i = 0;
+ for ( i = 0; i < numvertices; i++ ) {
+ // calc bounding sphere
+ double ctlength = ( (Vector3) vtxlist[ i ] ).VecLength();
+ if ( ctlength > maxsphere )
+ maxsphere = ctlength;
+ // calc bounding box
+ if ( vtxlist[ i ].getX() > maxx ) maxx = vtxlist[ i ].getX();
+ if ( vtxlist[ i ].getY() > maxy ) maxy = vtxlist[ i ].getY();
+ if ( vtxlist[ i ].getZ() > maxz ) maxz = vtxlist[ i ].getZ();
+ if ( vtxlist[ i ].getX() < minx ) minx = vtxlist[ i ].getX();
+ if ( vtxlist[ i ].getY() < miny ) miny = vtxlist[ i ].getY();
+ if ( vtxlist[ i ].getZ() < minz ) minz = vtxlist[ i ].getZ();
+ }
+
+ maxsphere *= VERTEX_SCALE_FAC;
+ binobj->BoundingSphere = FLOAT_TO_FIXED( maxsphere );
+ binobj->BoundingSphere2 = FLOAT_TO_FIXED( maxsphere * maxsphere );
+
+ // fill vertex list -----------------------------------
+ ODT_Vertex3 *vfillp = binobj->VertexList;
+ // store face normals first
+ for ( i = 0; i < numnormals; i++, vfillp++ ) {
+ Vector3 normal( facelist[ i ].getPlaneNormal() );
+ vfillp->X = FLOAT_TO_FIXED( normal.getX() );
+ vfillp->Y = FLOAT_TO_FIXED( -normal.getY() );
+ vfillp->Z = FLOAT_TO_FIXED( -normal.getZ() );
+ vfillp->Flags = 0x00000000L;
+ }
+ // store real vertices after face normals
+ for ( i = 0; i < numvertices; i++, vfillp++ ) {
+ vfillp->X = FLOAT_TO_FIXED( vtxlist[ i ].getX() * VERTEX_SCALE_FAC );
+ vfillp->Y = FLOAT_TO_FIXED( -vtxlist[ i ].getY() * VERTEX_SCALE_FAC );
+ vfillp->Z = FLOAT_TO_FIXED( -vtxlist[ i ].getZ() * VERTEX_SCALE_FAC );
+ vfillp->Flags = 0x00000000L;
+ }
+
+ // build flat bsp tree if not available
+ if ( BSPTreeAvailable() && !BSPTreeFlatAvailable() ) {
+ //TODO:
+ // implement flat->linked
+ }
+
+ // fill polygon array and vertex index arrays----------
+ ODT_Poly *pfillp = binobj->PolyList;
+ char *vertbase = (char *) pfillp + sizeof( ODT_Poly ) * numpolygons;
+ int countofs = 0;
+ if ( BSPTreeFlatAvailable() ) {
+ // scan polygons of flat bsp tree
+ int numnodes = bsptreeflat.getNumNodes();
+ for ( i = 1; i <= numnodes; i++ ) {
+ // node zero does not correspond to any polygon
+ // and is also not included in the number of nodes!
+ BSPNodeFlat *node = bsptreeflat.FetchNodePerId( i );
+ Polygon *polyscan = node->getPolygon();
+ int polyno = polyscan->getId();
+ pfillp[ polyno ].NumVerts = polyscan->getNumVertices();
+ pfillp[ polyno ].FaceIndx = polyscan->getFaceId();
+ pfillp[ polyno ].VertIndxs = (dword *) polyscan;
+ }
+ // scan polygons once again to assign vertex index lists
+ // in order instead of in the order of bsp nodes
+ for ( i = 1; i <= numnodes; i++, pfillp++ ) {
+ Polygon *polyscan = (Polygon *) pfillp->VertIndxs;
+ pfillp->VertIndxs = (dword *) ( vertbase + countofs );
+ // fill in array of vertex indexes
+ polyscan->FillVertexIndexArray( pfillp->VertIndxs );
+ countofs += sizeof( dword ) * pfillp->NumVerts;
+ }
+ } else {
+ // scan entire polygon list
+ Polygon *polyscan = polylist.FetchHead();
+ for ( i = 0; i < polylist.getNumElements(); i++, polyscan = polyscan->getNext(), pfillp++ ) {
+ pfillp->NumVerts = polyscan->getNumVertices();
+ pfillp->FaceIndx = polyscan->getFaceId();
+ pfillp->VertIndxs = (dword *) ( vertbase + countofs );
+ // fill in array of vertex indexes
+ polyscan->FillVertexIndexArray( pfillp->VertIndxs );
+ countofs += sizeof( dword ) * pfillp->NumVerts;
+ }
+ }
+ // correct vertex indexes to take face normals into account
+ dword *dfillp = (dword *) vertbase;
+ for ( i = 0; i < numvertexindices; i++ )
+ *dfillp++ += numnormals;
+
+ //NOTE:
+ // the object contains a pointer to the polygon list.
+ // this list contains all the polygon structures (no vertex indexes!)
+ // the vertex index lists for all the polygons of the object follow
+ // contiguously after all the polygon structures.
+
+ // fill face list (defines surface properties) --------
+ ODT_Face *ffillp = binobj->FaceList;
+ for ( i = 0; i < numfaces; i++, ffillp++ ) {
+ ffillp->TexMap = NULL;
+ ffillp->TexEqui = NULL;
+ ffillp->ColorRGB = 0;
+ ffillp->ColorIndx = 0;
+ ffillp->FaceNormalIndx = i;
+ ffillp->Shading = facelist[ i ].getShadingType() & Face::base_mask;
+
+ // write color if any attached and valid
+ if ( facelist[ i ].getShadingType() & Face::color_mask ) {
+ int coltype = facelist[ i ].getColorType();
+ if ( coltype == Face::indexed_col ) {
+ dword colindx;
+ facelist[ i ].getColorIndex( colindx );
+ ffillp->ColorIndx = ( ( ( ( ( colindx << 8 ) + colindx ) << 8 ) + colindx ) << 8 ) + colindx;
+ } else if ( coltype == Face::rgb_col ) {
+ ColorRGBA coltuple;
+ facelist[ i ].getColorRGBA( coltuple );
+ dword colrgb = ( ( ( ( ( coltuple.A << 8 ) + coltuple.B ) << 8 ) + coltuple.G ) << 8 ) + coltuple.R;
+ ffillp->ColorRGB = colrgb;
+ }
+ }
+
+ // attach texture
+ if ( facelist[ i ].getShadingType() & Face::texmap_mask ) {
+ const char *texname = facelist[ i ].getTextureName();
+ // simply store name and calc mapping
+ ffillp->TexMap = (char *) texname;
+ ODT_CalcAffineMapping( facelist[ i ], (dword *) ffillp->TexXmatrx );
+ }
+ }
+
+ // create bsp tree in object structure
+ if ( BSPTreeFlatAvailable() ) {
+ ODT_BSPNode *curbspnode = binobj->BSPTree + 1; // skip node at pos zero
+ for ( int i = 1; i <= bsptreeflat.getNumNodes(); i++, curbspnode++ ) {
+ BSPNodeFlat *node = bsptreeflat.FetchNodePerId( i );
+ curbspnode->Polygon = node->getPolygon()->getId();
+ curbspnode->Contained = node->getContainedList();
+ //curbspnode->BackList= node->getBackList(); //NOTE: not implemented!
+ curbspnode->FrontTree = node->getFrontSubTree();
+ curbspnode->BackTree = node->getBackSubTree();
+ }
+ }
+
+ memblocksize = objectmemsize;
+ return (byte *) binobj;
+}
+
+
+// create object that can be saved to file as single block (ODT format) -------
+//
+byte *ObjectBinFormat::ODT_CreateFileObject( int& memblocksize, byte *engineobj )
+{
+ ODT_GenObject *binobj = (ODT_GenObject *) engineobj;
+ TextureChunk& texlist = getTextureList();
+
+ // create table of texture names
+ char **texnameaddxs;
+ char *texturenames, *nexttexname;
+ int numtextures = texlist.getNumElements();
+ int texnamesize = 0;
+ int i = 0;
+ if ( numtextures > 0 ) {
+ for ( i = 0; i < numtextures; i++ )
+ texnamesize += strlen( texlist[ i ].getName() ) + 1;
+ texturenames = new char[ texnamesize ];
+ nexttexname = texturenames;
+ texnameaddxs = new char*[ numtextures ];
+ for ( i = 0; i < numtextures; i++ ) {
+ strcpy( nexttexname, texlist[ i ].getName() );
+ texnameaddxs[ i ] = nexttexname;
+ nexttexname += strlen( nexttexname ) + 1;
+ }
+ }
+
+ // correct texture pointers to point to texture names in block
+ ODT_Face *facescan = binobj->FaceList;
+ dword j = 0;
+ for ( j = 0; j < binobj->NumFaces; j++, facescan++ )
+ if ( facescan->TexMap != NULL )
+ for ( int k = 0; k < numtextures; k++ )
+ if ( strcmp( texnameaddxs[ k ], facescan->TexMap ) == 0 ) {
+// delete facescan->TexMap; // legacy
+ facescan->TexMap = (char *)
+ ( (ptrdiff_t) texnameaddxs[ k ] - (ptrdiff_t) texturenames + memblocksize );
+ break;
+ }
+
+ // make absolute pointers to vertex index lists header relative
+ ODT_Poly *polylist = binobj->PolyList;
+ for ( j = 0; j < binobj->NumPolys; j++, polylist++ ) {
+ polylist->VertIndxs = (dword *) ( (ptrdiff_t) polylist->VertIndxs - (ptrdiff_t) binobj );
+ }
+
+ // correct absolute pointers in object header to header-relative pointers
+ binobj->VertexList = (ODT_Vertex3 *) ( (ptrdiff_t) binobj->VertexList - (ptrdiff_t) binobj );
+ binobj->X_VertexList = (ODT_Vertex3 *) ( (ptrdiff_t) binobj->X_VertexList - (ptrdiff_t) binobj );
+ binobj->P_VertexList = (ODT_ProjPoint *) ( (ptrdiff_t) binobj->P_VertexList - (ptrdiff_t) binobj );
+ binobj->S_VertexList = (ODT_SPoint *) ( (ptrdiff_t) binobj->S_VertexList - (ptrdiff_t) binobj );
+ binobj->PolyList = (ODT_Poly *) ( (ptrdiff_t) binobj->PolyList - (ptrdiff_t) binobj );
+ binobj->FaceList = (ODT_Face *) ( (ptrdiff_t) binobj->FaceList - (ptrdiff_t) binobj );
+ binobj->VisPolyList = (ODT_VisPolys *) ( (ptrdiff_t) binobj->VisPolyList - (ptrdiff_t) binobj );
+ binobj->BSPTree = (ODT_BSPNode *) ( (ptrdiff_t) binobj->BSPTree - (ptrdiff_t) binobj );
+
+ // create block
+ byte *block = new byte[ memblocksize + texnamesize ];
+ memcpy( block, binobj, memblocksize );
+ if ( texnamesize > 0 ) {
+ memcpy( block + memblocksize, texturenames, texnamesize );
+ memblocksize += texnamesize;
+ // free texture name table
+ delete texturenames;
+ delete texnameaddxs;
+ }
+
+ return block;
+}
+
+
+// ----------------------------------------------------------------------------
+//
+#define DOUBLE_TO_OD2FLOAT(x) (float)(x)
+
+
+// calculate affine mapping using face's mapping specification ----------------
+//
+void ObjectBinFormat::OD2_CalcAffineMapping( Face& face, dword *dmatrx )
+{
+ Vertex2 vtx;
+ double mat[3][3];
+ int i = 0;
+ // build xyw-matrix
+ for ( i = 0; i < 3; i++ ) {
+ vtx = face.MapXY( i );
+ mat[ 0 ][ i ] = vtx.getX() * VERTEX_SCALE_FAC;
+ mat[ 1 ][ i ] = vtx.getY() * -VERTEX_SCALE_FAC;
+ mat[ 2 ][ i ] = vtx.getW() * -VERTEX_SCALE_FAC;
+ }
+ Transform2 xyw( (const double(*)[3]) mat );
+
+ // build uv1-matrix
+ for ( i = 0; i < 3; i++ ) {
+ vtx = face.MapUV( i );
+ mat[ 0 ][ i ] = vtx.getX();
+ mat[ 1 ][ i ] = vtx.getY();
+ mat[ 2 ][ i ] = vtx.getW();
+ }
+ Transform2 uv1( (const double(*)[3]) mat );
+
+ // invert uv1
+ Transform2 uv1i;
+ if ( !uv1.Inverse( uv1i ) ) {
+ ErrorMessage( "ObjectBinFormat::OD2_CalcAffineMapping(): Collinear mapping coordinates encountered!" );
+ }
+
+ // calculate affine mapping
+ Transform2 map( xyw );
+ map.Concat( uv1i );
+ // store result into destination structure (9 coefficients)
+ double (*affinemap)[ 3 ] = ( double (*)[3] ) map.LinMatrixAccess();
+ float (*dest)[ 4 ] = (float (*)[4]) dmatrx;
+ for ( i = 0; i < 3; i++ ) {
+
+ dest[ i ][ 0 ] = DOUBLE_TO_OD2FLOAT( affinemap[ i ][ 0 ] );
+ dest[ i ][ 1 ] = DOUBLE_TO_OD2FLOAT( affinemap[ i ][ 1 ] );
+ dest[ i ][ 2 ] = DOUBLE_TO_OD2FLOAT( 0.0 );
+ dest[ i ][ 3 ] = DOUBLE_TO_OD2FLOAT( affinemap[ i ][ 2 ] );
+
+ OD2_Geomv_out( &dest[ i ][ 0 ] );
+ OD2_Geomv_out( &dest[ i ][ 1 ] );
+ OD2_Geomv_out( &dest[ i ][ 2 ] );
+ OD2_Geomv_out( &dest[ i ][ 3 ] );
+ }
+}
+
+
+// create object recognizeable by engine (ODT format) -------------------------
+//
+byte *ObjectBinFormat::OD2_CreateEngineObject( int& memblocksize )
+{
+ // fetch object data lists
+ VertexChunk& vtxlist = getVertexList();
+ PolygonList& polylist = getPolygonList();
+ FaceChunk& facelist = getFaceList();
+ TextureChunk& texlist = getTextureList();
+
+ // calculate some basic numbers
+ int numvertices = getNumVertices();
+ int numnormals = getNumNormals();
+ int numallvtxs = numvertices + numnormals;
+ int numpolygons = BSPTreeAvailable() ? getBspPolygons() : getNumPolygons();
+ int numfaces = getNumFaces();
+ int numbspnodes = getBspPolygons();
+
+ // count number of vertices of all polygons
+ int numvertexindices = 0;
+ if ( BSPTreeAvailable() )
+ bsptree->SumVertexNums( numvertexindices );
+ else
+ numvertexindices = polylist.FetchHead()->SumVertexNumsEntireList();
+
+ // calculate size of entire object structure
+ size_t objectmemsize = sizeof( OD2_Root ) + // generic object header
+ sizeof( ODT_Vertex3 ) * numallvtxs + // object space vertices
+ sizeof( ODT_Poly ) * numpolygons + // polygon control data
+ sizeof( dword ) * numvertexindices + // polygon vertindx lists
+ sizeof( OD2_Face ) * numfaces; // face control data
+
+ // allocate memory for all object data (only excluding texturemaps)
+ OD2_Root *binobj = (OD2_Root *) new char[ objectmemsize ];
+ memset( binobj, 0x00, objectmemsize );
+
+ // fill in objectheader
+ strcpy( binobj->odt2, "ODT2\0" );
+ binobj->major = 1;
+ binobj->minor = 0;
+ binobj->rootflags = 0x0000;
+ binobj->rootflags2 = 0x0000;
+ binobj->NodeList = NULL;
+ binobj->Children[ 0 ] = NULL;
+ binobj->Children[ 1 ] = NULL;
+ binobj->InstanceSize = SWAP_32( sizeof( OD2_Root ) );
+ binobj->NumVerts = SWAP_32( numallvtxs );
+ binobj->NumPolyVerts = SWAP_32( numvertices );
+ binobj->NumNormals = SWAP_32( numnormals );
+ binobj->VertexList = (OD2_Vertex3 *) ( binobj + 1 );
+ binobj->NumPolys = numpolygons;
+ binobj->PolyList = (OD2_Poly *)
+ ( (char *) binobj->VertexList + sizeof( OD2_Vertex3 ) * numallvtxs );
+ binobj->NumFaces = numfaces;
+ binobj->FaceList = (OD2_Face *)
+ ( (char *) binobj->PolyList + sizeof( OD2_Poly ) * numpolygons + sizeof( dword ) * numvertexindices );
+ binobj->NumTextures = 0; // must be set later on
+
+ // calculate bounding sphere for object
+ double maxx = -100000; double minx = 100000;
+ double maxy = -100000; double miny = 100000;
+ double maxz = -100000; double minz = 100000;
+ double maxsphere = 0;
+ int i = 0;
+ for ( i = 0; i < numvertices; i++ ) {
+ // calc bounding sphere
+ double ctlength = ( (Vector3) vtxlist[ i ] ).VecLength();
+ if ( ctlength > maxsphere )
+ maxsphere = ctlength;
+ // calc bounding box
+ if ( vtxlist[ i ].getX() > maxx ) maxx = vtxlist[ i ].getX();
+ if ( vtxlist[ i ].getY() > maxy ) maxy = vtxlist[ i ].getY();
+ if ( vtxlist[ i ].getZ() > maxz ) maxz = vtxlist[ i ].getZ();
+ if ( vtxlist[ i ].getX() < minx ) minx = vtxlist[ i ].getX();
+ if ( vtxlist[ i ].getY() < miny ) miny = vtxlist[ i ].getY();
+ if ( vtxlist[ i ].getZ() < minz ) minz = vtxlist[ i ].getZ();
+ }
+
+ maxsphere *= VERTEX_SCALE_FAC;
+ binobj->BoundingSphere = DOUBLE_TO_OD2FLOAT( maxsphere );
+ OD2_Geomv_out( &binobj->BoundingSphere );
+
+ // fill vertex list -----------------------------------
+ OD2_Vertex3 *vfillp = binobj->VertexList;
+ // store face normals first
+ for ( i = 0; i < numnormals; i++, vfillp++ ) {
+ Vector3 normal( facelist[ i ].getPlaneNormal() );
+
+ vfillp->X = DOUBLE_TO_OD2FLOAT( normal.getX() );
+ vfillp->Y = DOUBLE_TO_OD2FLOAT( -normal.getY() );
+ vfillp->Z = DOUBLE_TO_OD2FLOAT( -normal.getZ() );
+
+ OD2_Geomv_out( &vfillp->X );
+ OD2_Geomv_out( &vfillp->Y );
+ OD2_Geomv_out( &vfillp->Z );
+
+ vfillp->Flags = SWAP_32( 0x00000000L );
+ }
+ // store real vertices after face normals
+ for ( i = 0; i < numvertices; i++, vfillp++ ) {
+
+ vfillp->X = DOUBLE_TO_OD2FLOAT( vtxlist[ i ].getX() * VERTEX_SCALE_FAC );
+ vfillp->Y = DOUBLE_TO_OD2FLOAT( -vtxlist[ i ].getY() * VERTEX_SCALE_FAC );
+ vfillp->Z = DOUBLE_TO_OD2FLOAT( -vtxlist[ i ].getZ() * VERTEX_SCALE_FAC );
+
+ OD2_Geomv_out( &vfillp->X );
+ OD2_Geomv_out( &vfillp->Y );
+ OD2_Geomv_out( &vfillp->Z );
+
+ vfillp->Flags = SWAP_32( 0x00000000L );
+ }
+
+ // fill polygon array and vertex index arrays----------
+ OD2_Poly *pfillp = binobj->PolyList;
+ char *vertbase = (char *) pfillp + sizeof( OD2_Poly ) * numpolygons;
+ int countofs = 0;
+ // scan entire polygon list
+ Polygon *polyscan = polylist.FetchHead();
+ for ( i = 0; i < polylist.getNumElements(); i++, polyscan = polyscan->getNext(), pfillp++ ) {
+ pfillp->NumVerts = polyscan->getNumVertices();
+ pfillp->FaceIndx = SWAP_32( polyscan->getFaceId() );
+ pfillp->VertIndxs = (dword *) ( vertbase + countofs );
+ // fill in array of vertex indexes
+ polyscan->FillVertexIndexArray( pfillp->VertIndxs );
+
+ countofs += sizeof( dword ) * pfillp->NumVerts;
+
+ pfillp->NumVerts = SWAP_32( pfillp->NumVerts );
+ }
+
+
+ // correct vertex indexes to take face normals into account
+ dword *dfillp = (dword *) vertbase;
+ for ( i = 0; i < numvertexindices; i++ ) {
+ *dfillp += numnormals;
+ *dfillp = SWAP_32( *dfillp );
+ dfillp++;
+ }
+
+ //NOTE:
+ // the object contains a pointer to the polygon list.
+ // this list contains all the polygon structures (no vertex indexes!)
+ // the vertex index lists for all the polygons of the object follow
+ // contiguously after all the polygon structures.
+
+ // fill face list (defines surface properties) --------
+ OD2_Face *ffillp = binobj->FaceList;
+ for ( i = 0; i < numfaces; i++, ffillp++ ) {
+ ffillp->TexMap = NULL;
+ ffillp->ColorRGB = 0;
+ ffillp->ColorIndx = 0;
+ ffillp->FaceNormalIndx = SWAP_32( i );
+ ffillp->Shading = SWAP_32( facelist[ i ].getShadingType() & Face::base_mask );
+
+ // write color if any attached and valid
+ if ( facelist[ i ].getShadingType() & Face::color_mask ) {
+ int coltype = facelist[ i ].getColorType();
+ if ( coltype == Face::indexed_col ) {
+ dword colindx;
+ facelist[ i ].getColorIndex( colindx );
+ ffillp->ColorIndx = SWAP_32( ( ( ( ( ( colindx << 8 ) + colindx ) << 8 ) + colindx ) << 8 ) + colindx);
+ } else if ( coltype == Face::rgb_col ) {
+ ColorRGBA coltuple;
+ facelist[ i ].getColorRGBA( coltuple );
+ dword colrgb = ( ( ( ( ( coltuple.A << 8 ) + coltuple.B ) << 8 ) + coltuple.G ) << 8 ) + coltuple.R;
+ ffillp->ColorRGB = SWAP_32( colrgb );
+ }
+ }
+
+ // attach texture
+ if ( facelist[ i ].getShadingType() & Face::texmap_mask ) {
+ const char *texname = facelist[ i ].getTextureName();
+ // simply store name and calc mapping
+ ffillp->TexMap = (char *) texname;
+ OD2_CalcAffineMapping( facelist[ i ], (dword *) ffillp->TexXmatrx );
+ }
+ }
+
+ memblocksize = objectmemsize;
+ return (byte *) binobj;
+}
+
+
+// create object that can be saved to file as single block (OD2 format) -------
+//
+byte *ObjectBinFormat::OD2_CreateFileObject( int& memblocksize, byte *engineobj )
+{
+ OD2_Root *binobj = (OD2_Root *) engineobj;
+ TextureChunk& texlist = getTextureList();
+
+ // create table of texture names
+ char **texnameaddxs;
+ char *texturenames, *nexttexname;
+ int numtextures = texlist.getNumElements();
+ int texnamesize = 0;
+ int i = 0;
+ if ( numtextures > 0 ) {
+ for ( i = 0; i < numtextures; i++ )
+ texnamesize += strlen( texlist[ i ].getName() ) + 1;
+ texturenames = new char[ texnamesize ];
+ nexttexname = texturenames;
+ texnameaddxs = new char*[ numtextures ];
+ for ( i = 0; i < numtextures; i++ ) {
+ strcpy( nexttexname, texlist[ i ].getName() );
+ texnameaddxs[ i ] = nexttexname;
+ nexttexname += strlen( nexttexname ) + 1;
+ }
+ }
+
+ // store number of textures
+ binobj->NumTextures = SWAP_32( numtextures );
+
+ // correct texture pointers to point to texture names in block
+ OD2_Face *facescan = binobj->FaceList;
+ dword j = 0;
+ for ( j = 0; j < binobj->NumFaces; j++, facescan++ )
+ if ( facescan->TexMap != NULL )
+ for ( int k = 0; k < numtextures; k++ )
+ if ( strcmp( texnameaddxs[ k ], facescan->TexMap ) == 0 ) {
+// delete facescan->TexMap; // legacy
+ facescan->TexMap = (char *) SWAP_32( ( (ptrdiff_t) texnameaddxs[ k ] - (ptrdiff_t) texturenames + memblocksize ) );
+ break;
+ }
+
+ binobj->NumFaces = SWAP_32( binobj->NumFaces );
+
+ // make absolute pointers to vertex index lists header relative
+ OD2_Poly *polylist = binobj->PolyList;
+ for ( j = 0; j < binobj->NumPolys; j++, polylist++ ) {
+ polylist->VertIndxs = (dword *) SWAP_32( ( (ptrdiff_t) polylist->VertIndxs - (ptrdiff_t) binobj ) );
+ }
+
+ binobj->NumPolys = SWAP_32( binobj->NumPolys );
+
+ // correct absolute pointers in object header to header-relative pointers
+// binobj->NodeList = (OD2_Node *) SWAP_32( (ptrdiff_t) binobj->NodeList - (ptrdiff_t) binobj );
+// binobj->Children[0] = (OD2_Child *) SWAP_32( (ptrdiff_t) binobj->Children[0] - (ptrdiff_t) binobj );
+// binobj->Children[1] = (OD2_Child *) SWAP_32( (ptrdiff_t) binobj->Children[1] - (ptrdiff_t) binobj );
+ binobj->VertexList = (OD2_Vertex3 *) SWAP_32( (ptrdiff_t) binobj->VertexList - (ptrdiff_t) binobj );
+ binobj->PolyList = (OD2_Poly *) SWAP_32( (ptrdiff_t) binobj->PolyList - (ptrdiff_t) binobj );
+ binobj->FaceList = (OD2_Face *) SWAP_32( (ptrdiff_t) binobj->FaceList - (ptrdiff_t) binobj );
+
+ // create block
+ byte *block = new byte[ memblocksize + texnamesize ];
+ memcpy( block, binobj, memblocksize );
+ if ( texnamesize > 0 ) {
+ memcpy( block + memblocksize, texturenames, texnamesize );
+ memblocksize += texnamesize;
+ // free texture name table
+ delete texturenames;
+ delete texnameaddxs;
+ }
+
+ return block;
+}
+
+
+// write entire object as binary file -----------------------------------------
+//
+int ObjectBinFormat::WriteDataToFile( const char *filename, int format )
+{
+ // to be filled
+ int memblocksize;
+ byte* engineobj = NULL;
+ byte* fileobj = NULL;
+
+ if ( format == BINFORMAT_ODT ) {
+
+ sprintf( line, "Writing object data to ODT file: \"%s\"...\n", filename );
+ InfoMessage( line );
+
+ // create object as binary block
+ engineobj = ODT_CreateEngineObject( memblocksize );
+
+ // convert object to destination file format
+ fileobj = ODT_CreateFileObject( memblocksize, engineobj );
+
+ } else if ( format == BINFORMAT_OD2 ) {
+
+ sprintf( line, "Writing object data to OD2 file: \"%s\"...\n", filename );
+ InfoMessage( line );
+
+ // create object as binary block
+ engineobj = OD2_CreateEngineObject( memblocksize );
+
+ // convert object to destination file format
+ fileobj = OD2_CreateFileObject( memblocksize, engineobj );
+
+ } else {
+ return FALSE;
+ }
+
+ // write binary object representation to file
+ int wstat = 0;
+ {
+ FileAccess ofile( filename, "wb" );
+ ofile.Write( fileobj, 1, memblocksize );
+ wstat = ofile.Status();
+ }
+
+ // free binary object memory blocks
+ delete fileobj;
+ delete engineobj;
+
+ return ( wstat == SYSTEM_IO_OK );
+}
+
+
+// string scratchpad ----------------------------------------------------------
+//
+char ObjectBinFormat::line[ 128 ] = "";
+
+
+BSPLIB_NAMESPACE_END
+
+//-----------------------------------------------------------------------------
diff --git a/tool_src/BspLib/ObjectBinFormat.h b/tool_src/BspLib/ObjectBinFormat.h
new file mode 100644
index 0000000..0810318
--- /dev/null
+++ b/tool_src/BspLib/ObjectBinFormat.h
@@ -0,0 +1,55 @@
+//-----------------------------------------------------------------------------
+// BSPLIB HEADER: ObjectBinFormat.h
+//
+// Copyright (c) 1998-1999 by Markus Hadwiger
+// All Rights Reserved.
+//-----------------------------------------------------------------------------
+
+#ifndef _OBJECTBINFORMAT_H_
+#define _OBJECTBINFORMAT_H_
+
+// bsplib header files
+#include "BspLibDefs.h"
+#include "BspObject.h"
+#include "SystemIO.h"
+
+
+BSPLIB_NAMESPACE_BEGIN
+
+
+// BspObject capable of writing itself in binary format -----------------------
+//
+class ObjectBinFormat : public BspObject, public virtual SystemIO {
+
+public:
+
+ // output formats
+ enum {
+ BINFORMAT_ODT, // ODT (old format: single object)
+ BINFORMAT_OD2, // OD2 (new format: scene/tree)
+ };
+
+public:
+ ObjectBinFormat( BspObject& object ) : BspObject( object ) { }
+ ~ObjectBinFormat() { }
+ int WriteDataToFile( const char *filename, int format );
+
+private:
+ void ODT_CalcAffineMapping( Face& face, dword *dmatrx );
+ byte * ODT_CreateEngineObject( int& memblocksize );
+ byte * ODT_CreateFileObject( int& memblocksize, byte *engineobj );
+
+ void OD2_CalcAffineMapping( Face& face, dword *dmatrx );
+ byte * OD2_CreateEngineObject( int& memblocksize );
+ byte * OD2_CreateFileObject( int& memblocksize, byte *engineobj );
+
+private:
+ static char line[]; // scratchpad
+};
+
+
+BSPLIB_NAMESPACE_END
+
+
+#endif // _OBJECTBINFORMAT_H_
+
diff --git a/tool_src/BspLib/ObjectBspFormat.cpp b/tool_src/BspLib/ObjectBspFormat.cpp
new file mode 100644
index 0000000..12082f0
--- /dev/null
+++ b/tool_src/BspLib/ObjectBspFormat.cpp
@@ -0,0 +1,213 @@
+//-----------------------------------------------------------------------------
+// BSPLIB MODULE: ObjectBspFormat.cpp
+//
+// Copyright (c) 1996-1997 by Markus Hadwiger
+// All Rights Reserved.
+//-----------------------------------------------------------------------------
+
+// bsplib header files
+#include "BspLibDefs.h"
+#include "ObjectBspFormat.h"
+
+
+BSPLIB_NAMESPACE_BEGIN
+
+
+// write list of vertices -----------------------------------------------------
+//
+int ObjectBspFormat::WriteVertexList( FileAccess& output )
+{
+ if ( numvertices > 0 ) {
+
+ output.WriteLine( "; list of all vertices comprising the object -----------------------------\n" );
+ output.WriteLine( "; numbering starts with 1\n" );
+
+ sprintf( line, "%s\n", _vertices_str );
+ output.WriteLine( line );
+
+ for ( int i = 0; i < numvertices; i++ ) {
+ sprintf( line, "%f,\t%f,\t%f\t; %d\n",
+ vertexlist[ i ].getX(),
+ vertexlist[ i ].getY(),
+ vertexlist[ i ].getZ(),
+ i + 1 );
+ output.WriteLine( line );
+ }
+
+ output.WriteLine( "\n" );
+ }
+
+ return output.Status();
+}
+
+
+// write list of polygons -----------------------------------------------------
+//
+int ObjectBspFormat::WritePolygonList( FileAccess& output )
+{
+ if ( numbsppolygons > 0 ) {
+
+ output.WriteLine( "; list of all polygons (faces split into pieces by bsp compiler) ---------\n" );
+ output.WriteLine( "; numbering starts with 1\n" );
+
+ sprintf( line, "%s\n", _polygons_str );
+ output.WriteLine( line );
+
+ int i = 0;
+ Polygon *poly;
+ while ( !bsptree.TreeEmpty() && ( ( poly = bsptree->FetchBSPPolygon( i ) ) != NULL ) ) {
+ poly->WriteVertexList( output, FALSE );
+ sprintf( line, "\t\t; %d\n", ++i );
+ output.WriteLine( line );
+ }
+ output.WriteLine( "\n" );
+
+ if ( i < numpolygons_before_bsp )
+ ErrorMessage( "***ERROR*** Polygon missing in BSP tree (ObjectBspFormat::WritePolygonList())." );
+ }
+
+ return output.Status();
+}
+
+
+// write list of faces (each face consists of one to many polygons) -----------
+//
+int ObjectBspFormat::WriteFaceList( FileAccess& output )
+{
+ if ( numfaces > 0 ) {
+
+ output.WriteLine( "; list of polygons comprising each face ----------------------------------\n" );
+ output.WriteLine( "; numbering starts with 1\n" );
+
+ sprintf( line, "%s\n", _faces_str );
+ output.WriteLine( line );
+
+ for ( int i = 0; i < numfaces; i++ ) {
+ PolygonList facepolylist( this );
+ if ( !bsptree.TreeEmpty() )
+ bsptree->FetchFacePolygons( i, facepolylist );
+ facepolylist.WritePolyList( output, i + 1 );
+ }
+
+ output.WriteLine( "\n" );
+ }
+
+ return output.Status();
+}
+
+
+// write surface properties of faces ------------------------------------------
+//
+int ObjectBspFormat::WriteFaceProperties( FileAccess& output )
+{
+ if ( numfaces > 0 ) {
+
+ output.WriteLine( "; face material properties (color, texture, etc.) ------------------------\n" );
+
+ sprintf( line, "%s\n", _faceproperties_str );
+ output.WriteLine( line );
+
+ for ( int i = 0; i < numfaces; i++ )
+ facelist[ i ].WriteFaceInfo( output );
+
+ output.WriteLine( "\n" );
+ }
+
+ return output.Status();
+}
+
+
+// write face normals ---------------------------------------------------------
+//
+int ObjectBspFormat::WriteNormals( FileAccess& output )
+{
+ if ( numnormals > 0 ) {
+
+ output.WriteLine( "; face normals -----------------------------------------------------------\n" );
+
+ sprintf( line, "%s\n", _facenormals_str );
+ output.WriteLine( line );
+
+ for ( int i = 0; i < numfaces /*numnormals*/; i++ )
+ facelist[ i ].WriteNormalInfo( output );
+
+ output.WriteLine( "\n" );
+ }
+
+ return output.Status();
+}
+
+
+// write list of textures -----------------------------------------------------
+//
+int ObjectBspFormat::WriteTextureList( FileAccess& output )
+{
+ if ( numtextures > 0 ) {
+
+ output.WriteLine( "; texture definitions (sizes and filenames) ------------------------------\n" );
+
+ sprintf( line, "%s\n", _textures_str );
+ output.WriteLine( line );
+
+ for ( int i = 0; i < numtextures; i++ )
+ texturelist[ i ].WriteInfo( output );
+ }
+
+ return output.Status();
+}
+
+
+// write list of mapping coordinates (correspondences) ------------------------
+//
+int ObjectBspFormat::WriteMappingList( FileAccess& output )
+{
+ if ( numtexmappedfaces > 0 ) {
+
+ output.WriteLine( "; mapping parameters for textured faces ----------------------------------\n" );
+ sprintf( line, "%s\n", _correspondences_str );
+ output.WriteLine( line );
+ output.WriteLine( "\n" );
+
+ int curfaceno = 0;
+ for ( int i = 0; i < numtexmappedfaces; i++, curfaceno++ ) {
+ while ( !facelist[ curfaceno ].FaceTexMapped() )
+ curfaceno++;
+ sprintf( line, "; correspondence %d (face %d)\n", i + 1, curfaceno + 1 );
+ output.WriteLine( line );
+
+ facelist[ curfaceno ].WriteMappingInfo( output );
+ }
+ }
+
+ return output.Status();
+}
+
+
+// write textual representation of bsp tree to output file --------------------
+//
+int ObjectBspFormat::WriteBSPTree( FileAccess& output )
+{
+ if ( !bsptree.TreeEmpty() ) {
+
+ output.WriteLine( "; polygon bsp tree -------------------------------------------------------\n" );
+
+ sprintf( line, "%s\n", _bsptree_str );
+ output.WriteLine( line );
+
+ bsptree->WriteBSPTree( output );
+
+ output.WriteLine( "\n" );
+ }
+
+ return output.Status();
+}
+
+
+// string scratchpad ----------------------------------------------------------
+//
+char ObjectBspFormat::line[ 1024 ] = "";
+
+
+BSPLIB_NAMESPACE_END
+
+//-----------------------------------------------------------------------------
diff --git a/tool_src/BspLib/ObjectBspFormat.h b/tool_src/BspLib/ObjectBspFormat.h
new file mode 100644
index 0000000..7d599eb
--- /dev/null
+++ b/tool_src/BspLib/ObjectBspFormat.h
@@ -0,0 +1,53 @@
+//-----------------------------------------------------------------------------
+// BSPLIB HEADER: ObjectBspFormat.h
+//
+// Copyright (c) 1997 by Markus Hadwiger
+// All Rights Reserved.
+//-----------------------------------------------------------------------------
+
+#ifndef _OBJECTBSPFORMAT_H_
+#define _OBJECTBSPFORMAT_H_
+
+// bsplib header files
+#include "BspLibDefs.h"
+#include "BspObject.h"
+#include "BspFormat.h"
+
+
+BSPLIB_NAMESPACE_BEGIN
+
+
+// BspObject capable of BspFormat I/O operations ------------------------------
+//
+class ObjectBspFormat : public BspObject, public BspFormat {
+
+public:
+ ObjectBspFormat( BspObject& object, BspFormat& format );
+ ~ObjectBspFormat() { }
+
+ virtual int WriteVertexList( FileAccess& output );
+ virtual int WritePolygonList( FileAccess& output );
+ virtual int WriteFaceList( FileAccess& output );
+ virtual int WriteFaceProperties( FileAccess& output );
+ virtual int WriteTextureList( FileAccess& output );
+ virtual int WriteMappingList( FileAccess& output );
+ virtual int WriteNormals( FileAccess& output );
+ virtual int WriteBSPTree( FileAccess& output );
+
+private:
+ static char line[]; // scratchpad
+};
+
+// construct by copying base class objects ------------------------------------
+inline ObjectBspFormat::ObjectBspFormat( BspObject& object, BspFormat& format ) :
+ BspObject( object ),
+ BspFormat( format )
+{
+}
+
+
+BSPLIB_NAMESPACE_END
+
+
+#endif // _OBJECTBSPFORMAT_H_
+
diff --git a/tool_src/BspLib/OutputData3D.cpp b/tool_src/BspLib/OutputData3D.cpp
new file mode 100644
index 0000000..f4e27d5
--- /dev/null
+++ b/tool_src/BspLib/OutputData3D.cpp
@@ -0,0 +1,105 @@
+//-----------------------------------------------------------------------------
+// BSPLIB MODULE: OutputData3D.cpp
+//
+// Copyright (c) 1997 by Markus Hadwiger
+// All Rights Reserved.
+//-----------------------------------------------------------------------------
+
+// bsplib header files
+#include "OutputData3D.h"
+#include "AodOutput.h"
+#include "BspOutput.h"
+//#include "VrmlOutput.h"
+
+//#define VRML_OUTPUT_POSSIBLE
+
+
+BSPLIB_NAMESPACE_BEGIN
+
+
+// "virtual" constructor for different output format objects ------------------
+//
+OutputData3D::OutputData3D( BspObjectList objectlist, const char *filename, int format ) :
+ IOData3D( objectlist, String( filename ) ),
+ m_data( NULL )
+{
+ // create "real" output object according to specified format of output file
+ if ( format != DONT_CREATE_OBJECT ) {
+ switch ( m_objectformat = format ) {
+
+ case AOD_FORMAT_1_1:
+ m_data = new AodOutput( objectlist, filename );
+ break;
+
+ case BSP_FORMAT_1_1:
+ m_data = new BspOutput( objectlist, filename );
+ break;
+
+#ifdef VRML_OUTPUT_POSSIBLE
+ case VRML_FORMAT_1_0:
+ m_data = new VrmlFile( objectlist, filename );
+ break;
+#endif
+ default:
+ ErrorMessage( "[OutputData3D]: Unrecognized output file format." );
+ m_objectformat = UNKNOWN_FORMAT;
+ }
+ } else {
+ m_objectformat = DONT_CREATE_OBJECT;
+ }
+}
+
+
+// constructor using an InputData3D object directly to get data ---------------
+//
+OutputData3D::OutputData3D( const InputData3D& inputdata, int format ) :
+ IOData3D( inputdata.getObjectList(), inputdata.getFileName() ),
+ m_data( NULL )
+{
+ // create "real" output object according to specified format of output file
+ if ( format != DONT_CREATE_OBJECT ) {
+ switch ( m_objectformat = format ) {
+
+ case AOD_FORMAT_1_1:
+ m_data = new AodOutput( inputdata );
+ break;
+
+ case BSP_FORMAT_1_1:
+ m_data = new BspOutput( inputdata );
+ break;
+
+#ifdef VRML_OUTPUT_POSSIBLE
+ case VRML_FORMAT_1_0:
+ m_data = new VrmlFile( inputdata );
+ break;
+#endif
+ default:
+ ErrorMessage( "[OutputData3D]: Unrecognized output file format." );
+ m_objectformat = UNKNOWN_FORMAT;
+ }
+ } else {
+ m_objectformat = DONT_CREATE_OBJECT;
+ }
+}
+
+
+// virtual destructor ---------------------------------------------------------
+//
+OutputData3D::~OutputData3D()
+{
+ // delete "real" object
+ delete m_data;
+}
+
+
+// redirection to WriteOutputFile() of "real" object --------------------------
+//
+int OutputData3D::WriteOutputFile()
+{
+ return m_data ? m_data->WriteOutputFile() : FALSE;
+}
+
+
+BSPLIB_NAMESPACE_END
+
+//-----------------------------------------------------------------------------
diff --git a/tool_src/BspLib/OutputData3D.h b/tool_src/BspLib/OutputData3D.h
new file mode 100644
index 0000000..2a61249
--- /dev/null
+++ b/tool_src/BspLib/OutputData3D.h
@@ -0,0 +1,44 @@
+//-----------------------------------------------------------------------------
+// BSPLIB HEADER: OutputData3D.h
+//
+// Copyright (c) 1997 by Markus Hadwiger
+// All Rights Reserved.
+//-----------------------------------------------------------------------------
+
+#ifndef _OUTPUTDATA3D_H_
+#define _OUTPUTDATA3D_H_
+
+// bsplib header files
+#include "BspLibDefs.h"
+#include "BspObjectList.h"
+#include "IOData3D.h"
+#include "InputData3D.h"
+
+
+BSPLIB_NAMESPACE_BEGIN
+
+
+// generic output class for 3-D data ------------------------------------------
+//
+class OutputData3D : public IOData3D {
+
+public:
+ OutputData3D( BspObjectList objectlist, const char *filename, int format = BSP_FORMAT_1_1 );
+ OutputData3D( const InputData3D& inputdata, int format = BSP_FORMAT_1_1 );
+ virtual ~OutputData3D();
+
+ virtual int WriteOutputFile();
+
+protected:
+ int m_objectformat;
+
+private:
+ OutputData3D* m_data;
+};
+
+
+BSPLIB_NAMESPACE_END
+
+
+#endif // _OUTPUTDATA3D_H_
+
diff --git a/tool_src/BspLib/Plane.h b/tool_src/BspLib/Plane.h
new file mode 100644
index 0000000..3489d0a
--- /dev/null
+++ b/tool_src/BspLib/Plane.h
@@ -0,0 +1,146 @@
+//-----------------------------------------------------------------------------
+// BSPLIB HEADER: Plane.h
+//
+// Copyright (c) 1997-1998 by Markus Hadwiger
+// All Rights Reserved.
+//-----------------------------------------------------------------------------
+
+#ifndef _PLANE_H_
+#define _PLANE_H_
+
+// bsplib header files
+#include "BspLibDefs.h"
+#include "Vertex.h"
+
+
+BSPLIB_NAMESPACE_BEGIN
+
+
+// plane in 3-space; represented by normal and distance to origin -------------
+//
+class Plane {
+
+ enum {
+ NORMAL_VALID = 0x0001,
+ OFFSET_VALID = 0x0002,
+ PLANE_VALID = NORMAL_VALID | OFFSET_VALID,
+ };
+
+public:
+ Plane() : m_valid( 0 ) { }
+ Plane( const Vector3& pnormal );
+ Plane( const Vector3& pnormal, double poffset );
+ Plane( const Vertex3& v1, const Vertex3& v2, const Vertex3& v3 );
+ ~Plane() { }
+
+ int InitPlane( const Vertex3& v1, const Vertex3& v2, const Vertex3& v3 );
+ int CalcPlaneOffset( const Vertex3& vtx );
+
+ Vector3 getPlaneNormal() const { return m_normal; }
+ void setPlaneNormal( const Vector3& pnormal ) { m_normal = pnormal; }
+
+ double getPlaneOffset() const { return m_offset; }
+ void setPlaneOffset( double poffset ) { m_offset = poffset; }
+
+ int NormalValid() const { return ( ( m_valid & NORMAL_VALID ) == NORMAL_VALID ); }
+ int PlaneValid() const { return ( ( m_valid & PLANE_VALID ) == PLANE_VALID ); }
+
+ void ApplyScaleFactor( double sfac );
+ void EliminateDirectionality();
+
+ int PointContained( const Vertex3& point ) const;
+ int PointInPositiveHalfspace( const Vertex3& point ) const;
+ int PointInNegativeHalfspace( const Vertex3& point ) const;
+
+private:
+ Vector3 m_normal; // normal of plane
+ double m_offset; // distance of plane to origin
+ int m_valid; // flag if plane specification indeed valid
+};
+
+// construct a plane from plane normal only: leave offset invalid -------------
+inline Plane::Plane( const Vector3& pnormal )
+{
+ m_normal = pnormal;
+ m_offset = 0.0;
+ m_valid = NORMAL_VALID;
+}
+
+// construct a plane from plane normal and distance to origin -----------------
+inline Plane::Plane( const Vector3& pnormal, double poffset )
+{
+ m_normal = pnormal;
+ m_offset = poffset;
+ m_valid = PLANE_VALID;
+}
+
+// construct a plane from three vertices (affine combination) -----------------
+inline Plane::Plane( const Vertex3& v1, const Vertex3& v2, const Vertex3& v3 )
+{
+ // normal is calculated so that the three vertices comprise a
+ // triangle with the front face in clockwise order
+ m_normal.CrossProduct( v3 - v1, v2 - v1 );
+
+ // m_valid will be set to 0 if the three vertices are collinear
+ m_valid = m_normal.Normalize() ? PLANE_VALID : 0;
+
+ // compute offset via dot product
+ m_offset = m_normal.DotProduct( v1 );
+}
+
+// init plane from three points (after construction!) -------------------------
+inline int Plane::InitPlane( const Vertex3& v1, const Vertex3& v2, const Vertex3& v3 )
+{
+ *this = Plane( v1, v2, v3 );
+ return m_valid;
+}
+
+// calculate plane's distance to origin using already valid normal ------------
+inline int Plane::CalcPlaneOffset( const Vertex3& vtx )
+{
+ // compute offset via dot product
+ m_offset = m_normal.DotProduct( vtx );
+ return ( m_valid |= OFFSET_VALID );
+}
+
+// apply scale factor to plane's distance to origin ---------------------------
+inline void Plane::ApplyScaleFactor( double sfac )
+{
+ // this will be needed if an object containing
+ // explicit plane information is scaled.
+ m_offset *= sfac;
+}
+
+// eliminate frontfacing/backfacing property; force positive offset -----------
+inline void Plane::EliminateDirectionality()
+{
+ if ( m_offset < 0.0 ) {
+ m_normal *= -1.0;
+ m_offset = -m_offset;
+ }
+}
+
+// determine if a point is contained in the plane -----------------------------
+inline int Plane::PointContained( const Vertex3& point ) const
+{
+ return ( fabs( m_normal.DotProduct( point ) - m_offset ) < EPS_POINT_ON_PLANE );
+}
+
+// determine if a point is contained in the positive open halfspace -----------
+inline int Plane::PointInPositiveHalfspace( const Vertex3& point ) const
+{
+ return ( m_normal.DotProduct( point ) - m_offset >= EPS_POINT_ON_PLANE );
+}
+
+// determine if a point is contained in the negative open halfspace -----------
+inline int Plane::PointInNegativeHalfspace( const Vertex3& point ) const
+{
+ return ( m_normal.DotProduct( point ) - m_offset <= -EPS_POINT_ON_PLANE );
+}
+
+
+BSPLIB_NAMESPACE_END
+
+
+#endif // _PLANE_H_
+
diff --git a/tool_src/BspLib/Polygon.cpp b/tool_src/BspLib/Polygon.cpp
new file mode 100644
index 0000000..543a1f7
--- /dev/null
+++ b/tool_src/BspLib/Polygon.cpp
@@ -0,0 +1,1042 @@
+//-----------------------------------------------------------------------------
+// BSPLIB MODULE: Polygon.cpp
+//
+// Copyright (c) 1996-1998 by Markus Hadwiger
+// All Rights Reserved.
+//-----------------------------------------------------------------------------
+
+// bsplib headers
+#include "BspObject.h"
+#include "Polygon.h"
+#include "BoundingBox.h"
+#include "BSPNode.h"
+#include "BspTool.h"
+#include "Vertex.h"
+
+
+BSPLIB_NAMESPACE_BEGIN
+
+
+// construct a Polygon --------------------------------------------------------
+//
+Polygon::Polygon( BspObject *bobj, int pno, int fno, Polygon *next, int num )
+{
+ baseobject = bobj;
+ polygonno = pno;
+ faceno = fno;
+ nextpolygon = next;
+ numpolygons = num;
+ numvertindxs = 0;
+ vertindxs = NULL;
+ vindxinsertpos = NULL;
+}
+
+
+// get vertexlist of object polygon belongs to --------------------------------
+//
+VertexChunk& Polygon::getVertexList()
+{
+ CHECK_DEREFERENCING(
+ if ( baseobject == NULL )
+ Error();
+ );
+ return baseobject->getVertexList();
+}
+
+
+// get facelist of object polygon belongs to ----------------------------------
+//
+FaceChunk& Polygon::getFaceList()
+{
+ CHECK_DEREFERENCING(
+ if ( baseobject == NULL )
+ Error();
+ );
+ return baseobject->getFaceList();
+}
+
+
+// create new polygon and prepend it to list (append list to new polygon) -----
+//
+Polygon *Polygon::NewPolygon()
+{
+ //CAVEAT:
+ // the automatical assignment of polygon and face number
+ // must be used judiciously! it's very easy to get the
+ // numbering wrong. also, a single polygon cannot be
+ // used as "polygon-factory" since it will always assign
+ // the same numbers to the new polygons, based on its own.
+
+ //NOTE:
+ // normally, this function should only be used like this:
+ // poly = poly->NewPolygon();
+
+ // automatically assign sequential polygon- and face-number
+ return new Polygon( baseobject, numpolygons, numpolygons, this, numpolygons + 1 );
+}
+
+
+// prepend existing polygon to list (polygon- and face id are not changed!) ---
+//
+Polygon *Polygon::InsertPolygon( Polygon *poly )
+{
+ poly->nextpolygon = this;
+ poly->numpolygons = numpolygons + 1;
+ poly->baseobject = baseobject;
+ return poly;
+}
+
+
+// delete head of polygon list; return rest of list ---------------------------
+//
+Polygon *Polygon::DeleteHead()
+{
+ Polygon *temp = nextpolygon;
+ nextpolygon = NULL;
+ delete this;
+ //CAVEAT:
+ // this can create problems if function not used correctly!
+ // INVOKE ONLY LIKE THIS: poly = poly->DeleteHead();
+ // otherwise a dangling pointer will be created!
+ // THIS FUNCTION MAY ALSO NEVER BE INVOKED ON STATICALLY
+ // ALLOCATED POLYGONS!!
+ return temp;
+}
+
+
+// find polygon with specific id ----------------------------------------------
+//
+Polygon *Polygon::FindPolygon( int id )
+{
+ // scan entire list and compare ids
+ for ( Polygon *scanpo = this; scanpo; scanpo = scanpo->getNext() ) {
+ if ( scanpo->getId() == id )
+ return scanpo;
+ }
+ // no polygon with this id found
+ return NULL;
+}
+
+
+// sum up vertex numbers for all polygons of list -----------------------------
+//
+int Polygon::SumVertexNumsEntireList()
+{
+ // scan entire list and compare ids
+ int count = 0;
+ for ( Polygon *scanpo = this; scanpo; scanpo = scanpo->getNext() )
+ count += scanpo->getNumVertices();
+ return count;
+}
+
+
+// correct relative values to refer to new base -------------------------------
+//
+void Polygon::CorrectBase( BspObject *newbaseobj, int vertexindxbase, int faceidbase, int polygonidbase )
+{
+ baseobject = newbaseobj;
+ faceno += faceidbase;
+ polygonno += polygonidbase;
+ // correct all vertex indexes by just adding offset value
+ for ( VIndx *vertlist = vertindxs; vertlist; vertlist = vertlist->getNext() )
+ vertlist->setIndx( vertlist->getIndx() + vertexindxbase );
+}
+
+
+// correct relative values to refer to new base using vertex index map --------
+//
+void Polygon::CorrectBaseByTable( BspObject *newbaseobj, int *vtxindxmap, int faceidbase, int polygonidbase )
+{
+ baseobject = newbaseobj;
+ faceno += faceidbase;
+ polygonno += polygonidbase;
+ // correct all vertex indexes using mapping table
+ for ( VIndx *vertlist = vertindxs; vertlist; vertlist = vertlist->getNext() )
+ vertlist->setIndx( vtxindxmap[ vertlist->getIndx() ] );
+}
+
+
+// write list of vertices to text-file ----------------------------------------
+//
+void Polygon::FillVertexIndexArray( dword *arr ) const
+{
+ // scan list of vertex indexes and write them into the int array
+ for ( VIndx *vertlist = vertindxs; vertlist; vertlist = vertlist->getNext() )
+ *arr++ = vertlist->getIndx();
+}
+
+
+// write list of vertices to text-file ----------------------------------------
+//
+void Polygon::WriteVertexList( FILE *fp, int cr ) const
+{
+ // scan list of vertex indexes and write them to text file
+ for ( VIndx *vertlist = vertindxs; vertlist; vertlist = vertlist->getNext() )
+ fprintf( fp, vertlist->getNext() ? "%d, " : "%d", vertlist->getIndx() + 1 );
+ if ( cr )
+ fprintf( fp, "\n" );
+}
+
+
+// write list of polygon numbers to text-file (reverse ordering) --------------
+//
+void Polygon::WritePolyList( FILE *fp ) const
+{
+ // recurse to achieve reverse ordering
+ if ( nextpolygon )
+ nextpolygon->WritePolyList( fp );
+
+ fprintf( fp, "%d, ", getId() + 1 );
+}
+
+
+// add new VIndx for polygon at head of vertindxs -----------------------------
+//
+void Polygon::PrependNewVIndx( int indx )
+{
+ // prepend new VIndx
+ VIndx *oldhead = vertindxs;
+ vertindxs = new VIndx( indx, oldhead );
+ // remember last node in list
+ if ( vindxinsertpos == NULL )
+ vindxinsertpos = vertindxs;
+ // update number of vertex indexes
+ numvertindxs++;
+}
+
+
+// add new VIndx for polygon at tail of vertindxs -----------------------------
+//
+void Polygon::AppendNewVIndx( int indx )
+{
+ // append new VIndx
+ if ( vindxinsertpos != NULL ) {
+ vindxinsertpos->setNext( new VIndx( indx ) );
+ vindxinsertpos = vindxinsertpos->getNext();
+ } else {
+ vertindxs = new VIndx( indx );
+ vindxinsertpos = vertindxs;
+ }
+ // update number of vertex indexes
+ numvertindxs++;
+}
+
+
+// append existing VIndx at tail of vertindxs ---------------------------------
+//
+void Polygon::AppendVIndx( VIndx *vindx )
+{
+ // append passed in VIndx
+ if ( vindxinsertpos ) {
+ vindxinsertpos->setNext( vindx );
+ } else {
+ vertindxs = vindx;
+ }
+
+ vindxinsertpos = vindx;
+ //CAVEAT:
+ // if passed in VIndx is the head of a list
+ // that list is unlinked when appending!
+ vindx->setNext( NULL );
+ // update number of vertex indexes
+ numvertindxs++;
+}
+
+
+// unlink last node in list of vertex indexes ---------------------------------
+//
+VIndx *Polygon::UnlinkLastVIndx()
+{
+ VIndx *vlist = vertindxs;
+ if ( vlist ) {
+ numvertindxs--;
+ if ( vlist->getNext() ) {
+ for ( ; vlist->getNext()->getNext(); vlist = vlist->getNext() ) ;
+ vindxinsertpos = vlist;
+ VIndx *node = vlist->getNext();
+ vlist->setNext( NULL );
+ return node;
+ } else {
+ // return one and only node in list
+ vindxinsertpos = NULL;
+ vertindxs = NULL;
+ return vlist;
+ }
+ } else {
+ // list was already empty
+ return NULL;
+ }
+}
+
+
+// calculate bounding box encompassing all polygons in list -------------------
+//
+void Polygon::CalcBoundingBox( BoundingBox* &boundingbox )
+{
+ VertexChunk& vtxlist = getVertexList();
+ VIndx *polyvertlist = getVList();
+
+ Vertex3 minvertex = vtxlist[ polyvertlist->getIndx() ];
+ Vertex3 maxvertex = vtxlist[ polyvertlist->getIndx() ];
+ polyvertlist = polyvertlist->getNext();
+
+ for ( Polygon *curpoly = this; ; ) {
+
+ for ( ; polyvertlist; polyvertlist = polyvertlist->getNext() ) {
+ Vertex3& testvertex = vtxlist[ polyvertlist->getIndx() ];
+
+ if ( testvertex.getX() < minvertex.getX() )
+ minvertex.setX( testvertex.getX() );
+ if ( testvertex.getY() < minvertex.getY() )
+ minvertex.setY( testvertex.getY() );
+ if ( testvertex.getZ() < minvertex.getZ() )
+ minvertex.setZ( testvertex.getZ() );
+
+ if ( testvertex.getX() > maxvertex.getX() )
+ maxvertex.setX( testvertex.getX() );
+ if ( testvertex.getY() > maxvertex.getY() )
+ maxvertex.setY( testvertex.getY() );
+ if ( testvertex.getZ() > maxvertex.getZ() )
+ maxvertex.setZ( testvertex.getZ() );
+ }
+
+ if ( ( curpoly = curpoly->getNext() ) != NULL )
+ polyvertlist = curpoly->getVList();
+ else
+ break;
+ }
+
+ //CAVEAT:
+ // boundingbox MUST NOT be initialized, since it
+ // is overwritten without deletion!
+ boundingbox = new BoundingBox( minvertex, maxvertex );
+}
+
+
+// check which class with respect to the splitter a given polygon belongs to --
+//
+int Polygon::CheckIntersection( Polygon *testpoly )
+{
+ VertexChunk& vtxlist = getVertexList();
+ Plane splitterplane = getPlane();
+
+ int numneg = 0, numpos = 0, numzero = 0;
+
+ // classify all vertices of polygon with respect to splitting plane
+ VIndx *polyvertlist = testpoly->getVList();
+ for ( ; polyvertlist; polyvertlist = polyvertlist->getNext() ) {
+ Vertex3 curvertex = vtxlist[ polyvertlist->getIndx() ];
+
+ if ( splitterplane.PointInPositiveHalfspace( curvertex ) )
+ numpos++;
+ else if ( splitterplane.PointInNegativeHalfspace( curvertex ) )
+ numneg++;
+ else
+ numzero++;
+ }
+
+ // determine polygon's classification from vertex classifications
+ if ( ( numneg == 0 ) && ( numpos == 0 ) )
+ return POLY_IN_SAME_PLANE;
+ else if ( numneg == 0 )
+ return POLY_IN_FRONT_SUBSPACE;
+ else if ( numpos == 0 )
+ return POLY_IN_BACK_SUBSPACE;
+ else
+ return POLY_STRADDLES_SPLITTER;
+}
+
+
+// check which halfspace another polygon's normal's tip lies in ---------------
+//
+int Polygon::NormalDirectionSimilar( Polygon *testpoly )
+{
+ // calculate position of normal's tip
+ Vertex3 normalstip = testpoly->getFirstVertex() + testpoly->getPlaneNormal();
+
+ // check position of tip with respect to this polygon's plane
+ return !getPlane().PointInNegativeHalfspace( normalstip );
+}
+
+
+// split polygon straddling two subspaces -------------------------------------
+//
+void Polygon::SplitPolygon( Polygon *poly, Polygon* &frontsubspace, Polygon* &backsubspace )
+{
+ VertexChunk& vtxlist = getVertexList();
+ FaceChunk& facelist = getFaceList();
+
+ if ( display_messages & MESSAGE_SPLITTING_POLYGON ) {
+ sprintf( str_scratchpad, "--- Splitting polygon %d\n", poly->getId() + 1 );
+ InfoMessage( str_scratchpad );
+ }
+
+ // create the two new polygons: one for each subspace.
+ // the original polygon (this) will not be deleted by this function.
+ Polygon *frontpoly = new Polygon( baseobject,
+ poly->getId(),
+ poly->getFaceId(),
+ frontsubspace );
+ Polygon *backpoly = new Polygon( baseobject,
+ poly->getId(),
+ poly->getFaceId(),
+ backsubspace );
+
+ // fetch normal vector and arbitrary point on splitter plane
+ Vector3 splitternormal = getPlaneNormal();
+ Vertex3 splittervertex = getFirstVertex();
+
+ // init pointer to vertex-list of source polygon
+ VIndx *polyvertlist = poly->getVList();
+
+ // check location of first vertex and set starting subspace accordingly
+ Vector3 directionvec( splittervertex, poly->getFirstVertex() );
+ if ( normalize_vectors )
+ directionvec.Normalize();
+ double scalprod( splitternormal.DotProduct( directionvec ) );
+
+ // check if first vertex lies in splitter plane
+ if ( fabs( scalprod ) < EPS_SCALAR ) {
+
+ if ( display_messages & MESSAGE_STARTVERTEX_IN_SPLITTER_PLANE ) {
+ sprintf( str_scratchpad, "Startvertex in splitter-plane: %d\n",
+ polyvertlist->getIndx() + 1 );
+ InfoMessage( str_scratchpad );
+ }
+ VIndx *scan = NULL;
+ // scan vertex list for vertex not contained in splitter plane
+ for ( scan = polyvertlist->getNext(); scan; scan = scan->getNext() ) {
+ directionvec.CreateDirVec( splittervertex, vtxlist[ scan->getIndx() ] );
+ if ( normalize_vectors )
+ directionvec.Normalize();
+ // set scalprod such that the start-subspace is opposite
+ // the first non-contained vertex's subspace
+ scalprod = -splitternormal.DotProduct( directionvec );
+ // exit loop if non-contained vertex found
+ if ( fabs( scalprod ) >= EPS_SCALAR )
+ break;
+ }
+
+ if ( display_messages & MESSAGE_STARTVERTEX_IN_SPLITTER_PLANE ) {
+ if ( scan == NULL ) {
+ sprintf( str_scratchpad, "WARNING: all vertices contained in splitter-plane!\n" );
+ } else {
+ sprintf( str_scratchpad, "Using vertex %d for halfspace classification.\n",
+ scan->getIndx() + 1 );
+ }
+ InfoMessage( str_scratchpad );
+ }
+ }
+/*
+ // check if polygon to split is non-convex
+ if ( [non-convex polygon] ) {
+ ErrorMessage( "***ERROR*** Non-convex polygon encountered while splitting." );
+ HandleCriticalError();
+ }
+*/
+ // select subspace to start in
+ int cursubspace = ( scalprod > 0.0 ) ? FRONT_SUBSPACE : BACK_SUBSPACE;
+
+ // split polygon into two polygons; one for each subspace ---------------
+ int twas1 = 0;
+ for ( ; polyvertlist; polyvertlist = polyvertlist->getNext() ) {
+
+ // copy current vertex from source polygon to its respective subspace
+ if ( cursubspace == FRONT_SUBSPACE )
+ frontpoly->AppendNewVIndx( polyvertlist->getIndx() );
+ else
+ backpoly->AppendNewVIndx( polyvertlist->getIndx() );
+
+ // check intersection of splitter plane with next lineseg -----
+ int nextvertex = polyvertlist->getNext() ?
+ polyvertlist->getNext()->getIndx() : poly->getVList()->getIndx();
+
+ // denominator is length of projection of lineseg onto plane normal
+ Vector3 linevec( vtxlist[ polyvertlist->getIndx() ], vtxlist[ nextvertex ] );
+ double denominator = splitternormal.DotProduct( linevec );
+
+ // numerator is distance from splittervertex to startvertex of lineseg
+ Vector3 directionvec( splittervertex, vtxlist[ polyvertlist->getIndx() ] );
+ double numerator = splitternormal.DotProduct( directionvec );
+
+ // if lineseg isn't parallel to splitter plane, check for intersection
+ if ( fabs( denominator ) >= EPS_DENOM_ZERO ) {
+
+ double t = - numerator / denominator;
+ if ( twas1 || ( fabs( t ) < EPS_POINT_ON_LINESEG ) ) {
+
+ if ( display_messages & MESSAGE_VERTEX_IN_SPLITTER_PLANE ) {
+ sprintf( str_scratchpad, "Vertex in splitter-plane! (%d)\n", polyvertlist->getIndx() + 1 );
+ InfoMessage( str_scratchpad );
+ }
+
+ // reset flag
+ twas1 = 0;
+
+ // switch subspace and insert same vertex again
+ cursubspace = -cursubspace;
+ if ( cursubspace == FRONT_SUBSPACE )
+ frontpoly->AppendNewVIndx( polyvertlist->getIndx() );
+ else
+ backpoly->AppendNewVIndx( polyvertlist->getIndx() );
+
+ // check if next vertex is contained in the other subspace
+ Vector3 directionvec( splittervertex, vtxlist[ nextvertex ] );
+ if ( normalize_vectors )
+ directionvec.Normalize();
+ double scalprod( splitternormal.DotProduct( directionvec ) );
+ if ( ( ( scalprod < 0.0 ) && ( cursubspace == FRONT_SUBSPACE ) ) ||
+ ( ( scalprod > 0.0 ) && ( cursubspace == BACK_SUBSPACE ) ) ) {
+ // switch back again
+ cursubspace = -cursubspace;
+ if ( display_messages & MESSAGE_VERTEX_IN_SPLITTER_PLANE ) {
+ sprintf( str_scratchpad, "Vertex alone in %s halfspace!\n",
+ ( cursubspace == BACK_SUBSPACE ) ? "front" : "back" );
+ InfoMessage( str_scratchpad );
+ }
+ }
+
+ //NOTE:
+ // the above check is necessary to avoid problems with polygons actually
+ // entirely contained in a single subspace but nevertheless classified as
+ // straddling. in this case the implicit subspace-switching for t=0 vertices
+ // would cause these vertices to be inserted into the wrong subspace!
+
+ } else if ( ( t >= EPS_POINT_ON_LINESEG ) && ( t <= 1.0 - EPS_POINT_ON_LINESEG ) ) {
+
+ // insert intersection point into both subspaces and switch
+ cursubspace = -cursubspace;
+ Vertex3 newvertex( linevec * t + vtxlist[ polyvertlist->getIndx() ] );
+ int newvertindx = vtxlist.FindCloseVertex( newvertex );
+ if ( newvertindx == -1 ) {
+ newvertindx = vtxlist.AddVertex( newvertex );
+ if ( display_messages & MESSAGE_NEW_SPLITVERTEX ) {
+ sprintf( str_scratchpad, "Inserting new split-vertex (%d)\n", vtxlist.getNumElements() );
+ InfoMessage( str_scratchpad );
+ }
+ } else if ( display_messages & MESSAGE_REUSING_SPLITVERTEX ) {
+ sprintf( str_scratchpad, "Reusing split-vertex (%d)\n", newvertindx + 1 );
+ InfoMessage( str_scratchpad );
+ }
+
+ frontpoly->AppendNewVIndx( newvertindx );
+ backpoly->AppendNewVIndx( newvertindx );
+
+ } else if ( fabs( t - 1.0 ) < EPS_POINT_ON_LINESEG ) {
+
+ // set flag
+ twas1 = 1;
+
+ //NOTE:
+ // this flag is necessary to avoid numerical problems when
+ // a vertex is classified as t=1 for one edge but is not
+ // classified as t=0 for the next edge.
+
+ // if this is not the last vertex it will be inserted
+ // during the next iteration. if not, the insertion
+ // must be done here, otherwise a vertex will be missing
+ // for the current polygon!
+ if ( polyvertlist->getNext() == NULL ) {
+ // determine vertex's subspace
+ Polygon *testpoly = ( cursubspace == FRONT_SUBSPACE ) ? frontpoly : backpoly;
+ // check if not already inserted as first vertex
+ if ( ( testpoly->getVList() != NULL ) &&
+ ( testpoly->getVList()->getIndx() == nextvertex ) )
+ continue;
+ // insert last vertex into its subspace
+ testpoly->AppendNewVIndx( nextvertex );
+ }
+ }
+
+ } else if ( polyvertlist->getNext() == NULL ) {
+
+ // determine last vertex's subspace
+ Polygon *testpoly = ( cursubspace == FRONT_SUBSPACE ) ? frontpoly : backpoly;
+ // check if not already inserted as first vertex
+ if ( ( testpoly->getVList() != NULL ) &&
+ ( testpoly->getVList()->getIndx() == nextvertex ) )
+ continue;
+ // insert last vertex into its subspace
+ testpoly->AppendNewVIndx( nextvertex );
+ }
+ }
+
+ // check generated polygons for degeneration
+ if ( frontpoly->HasArea() ) {
+ // insert front poly into front subspace
+ frontsubspace = frontpoly;
+ // check back poly
+ if ( backpoly->HasArea() ) {
+ // insert back poly into back subspace
+ backsubspace = backpoly;
+ // set new id in sequence
+ backpoly->setId( baseobject->getNumPolygons() );
+ // this poly has not been counted yet
+ baseobject->numpolygons++;
+ } else {
+ // remove degenerated back poly
+ backpoly->setNext( NULL );
+ delete backpoly;
+ if ( display_messages & MESSAGE_SPLITTING_POLYGON )
+ InfoMessage( "Split not carried out due to boundary case: polygon in front halfspace.\n" );
+ }
+ } else {
+ // remove degenerated front poly
+ frontpoly->setNext( NULL );
+ delete frontpoly;
+ if ( display_messages & MESSAGE_SPLITTING_POLYGON )
+ InfoMessage( "Split not carried out due to boundary case: polygon in back halfspace.\n" );
+ // check back poly
+ if ( backpoly->HasArea() ) {
+ // insert back poly into back subspace
+ backsubspace = backpoly;
+ } else {
+ // both polygons degenerated: should be impossible!
+ Error();
+ }
+ }
+}
+
+
+// partition list of polygons into two halfspaces (heavily recursive!) --------
+//
+BSPNode *Polygon::PartitionSpace()
+{
+ // display invocation message if flag set
+ if ( display_messages & MESSAGE_INVOCATION ) {
+ sprintf( str_scratchpad, "PartitionSpace() called: #%d polygon %d\n",
+ partition_callcount, getId() + 1 );
+ InfoMessage( str_scratchpad );
+ partition_callcount++;
+ }
+
+ // only one polygon in this halfspace?
+ if ( nextpolygon == NULL ) {
+ if ( display_messages & MESSAGE_INVOCATION ) {
+ sprintf( str_scratchpad, "Leaf: polygon %d\n", getId() + 1 );
+ InfoMessage( str_scratchpad );
+ }
+ return new BSPNode( NULL, NULL, this, NULL );
+ }
+
+ // used after recursive calls: has to be automatic!!
+ Polygon *splitter = this;
+
+ // take first polygon in list without testing?
+ if ( splitter_crit == SPLITTERCRIT_FIRST_POLY )
+ goto splitter_selected;
+
+ // find best candidate for splitter -----------------------------
+ static int bestnumsplitted;
+ static int bestnumcontained;
+ bestnumsplitted = INT_MAX;
+ bestnumcontained = 0;
+
+ static int samplecount;
+ samplecount = 0;
+
+ static Polygon *currentsplitter;
+ static Polygon *precpolygon;
+ static Polygon *splitterpred;
+ currentsplitter = this;
+ precpolygon = NULL;
+ splitterpred = NULL;
+
+ // walk polygon list trying to find appropriate splitter
+ for ( ; currentsplitter; precpolygon = currentsplitter, currentsplitter = currentsplitter->getNext() ) {
+
+ if ( splitter_crit == SPLITTERCRIT_RANDOM_SAMPLE ) {
+ //TODO: don't use rtl rand() as pseudo random number generator
+ //NOTE: assumes that RAND_MAX is at least 10000
+ if ( ( rand() % 10000 ) > test_probability )
+ continue;
+ }
+
+ static int numsplitted;
+ static int numcontained;
+ numsplitted = 0;
+ numcontained = 0;
+
+ // determine number of polygons splitted and contained by *currentsplitter, respectively
+ static Polygon *scanpo;
+ for ( scanpo = this; scanpo; scanpo = scanpo->getNext() ) {
+ if ( scanpo != currentsplitter ) {
+ switch ( currentsplitter->CheckIntersection( scanpo ) ) {
+ case POLY_STRADDLES_SPLITTER:
+ numsplitted++;
+ break;
+ case POLY_IN_SAME_PLANE:
+ numcontained++;
+ break;
+ default:
+ // *currentsplitter neither splits nor contains *scanpo
+ break;
+ }
+ }
+ }
+
+ if ( numsplitted == 0 ) {
+ // if nothing splitted at all, skip all other tests
+ splitter = currentsplitter;
+ splitterpred = precpolygon;
+ break;
+ } else if ( numsplitted < bestnumsplitted ) {
+ splitter = currentsplitter;
+ splitterpred = precpolygon;
+ bestnumsplitted = numsplitted;
+ bestnumcontained = numcontained;
+ } else if ( ( numsplitted == bestnumsplitted ) && ( numcontained > bestnumcontained ) ) {
+ splitter = currentsplitter;
+ splitterpred = precpolygon;
+ bestnumcontained = numcontained;
+ }
+
+ // test sample size for SPLITTERCRIT_SAMPLE_FIRST_N and SPLITTERCRIT_RANDOM_SAMPLE
+ if ( splitter_crit & SPLITTERCRITMASK_SAMPLESIZ ) {
+ // desired sample size already reached?
+ if ( ++samplecount >= sample_size )
+ break;
+ }
+ }
+
+splitter_selected:
+
+ // build polygon list without splitter
+ static Polygon *polylist;
+ polylist = this;
+ if ( splitter == polylist ) {
+ polylist = splitter->getNext();
+ } else {
+ splitterpred->setNext( splitter->getNext() );
+ }
+
+ splitter->setNext( NULL ); // unlink splitter from rest of list
+ splitter->setNumPolygons( 1 ); // splitter contains only itself
+
+ // display splitter info
+ if ( display_messages & MESSAGE_INVOCATION ) {
+ sprintf( str_scratchpad, "Splitter: polygon %d\n", splitter->getId() + 1 );
+ InfoMessage( str_scratchpad );
+ }
+
+ // partition space; create subspace lists -----------------------
+ Polygon *frontsubspace = NULL;
+ Polygon *backsubspace = NULL;
+ Polygon *backlist = NULL; // list of backfacing polygons
+
+ static Polygon *containlist; // append position for contained polygons
+ containlist = splitter;
+ while ( polylist != NULL ) {
+
+ static Polygon *temppoly;
+ switch ( splitter->CheckIntersection( polylist ) ) {
+
+ // polygon completely contained in front-subspace
+ case POLY_IN_FRONT_SUBSPACE:
+ temppoly = polylist->getNext();
+ polylist->setNext( frontsubspace );
+ frontsubspace = polylist;
+ polylist = temppoly;
+ break;
+
+ // polygon completely contained in back-subspace
+ case POLY_IN_BACK_SUBSPACE:
+ temppoly = polylist->getNext();
+ polylist->setNext( backsubspace );
+ backsubspace = polylist;
+ polylist = temppoly;
+ break;
+
+ // polygon straddles plane of splitter
+ case POLY_STRADDLES_SPLITTER:
+ // split polygon and add split pieces to the front- and back-subspace, respectively
+ splitter->SplitPolygon( polylist, frontsubspace, backsubspace );
+ // delete split polygon
+ polylist = polylist->DeleteHead();
+ break;
+
+ // polygon lies in same plane as splitter
+ case POLY_IN_SAME_PLANE:
+ temppoly = polylist->getNext();
+ if ( splitter->NormalDirectionSimilar( polylist ) ) {
+ // insert frontfacing polygon into contained list (at tail)
+ containlist->setNext( polylist );
+ containlist = polylist;
+ containlist->setNext( NULL );
+ containlist->setNumPolygons( 1 );
+ //CAVEAT:
+ // numpolygons is only correct for first polygon in contained-list (splitter)!!
+ splitter->numpolygons++;
+ } else {
+ // insert backfacing polygon into backlist (at head)
+ polylist->setNext( backlist );
+ polylist->setNumPolygons( backlist ? backlist->getNumPolygons() + 1 : 1 );
+ backlist = polylist;
+ }
+ polylist = temppoly;
+ break;
+ }
+ }
+
+ // allocate new root; partition halfspaces recursively and return root
+ BSPNode *front = frontsubspace ? frontsubspace->PartitionSpace() : NULL;
+ BSPNode *back = backsubspace ? backsubspace->PartitionSpace() : NULL;
+ return new BSPNode( front, back, splitter, backlist );
+}
+
+
+// calculate plane normals for planes of all polygons -------------------------
+//
+void Polygon::CalcPlaneNormals()
+{
+ // scan entire polygon list
+ FaceChunk& facelist = getFaceList();
+ for ( Polygon *polyscan = this; polyscan; polyscan = polyscan->getNext() ) {
+ // calculate plane (and normal) if not valid yet
+ Face& curface = facelist[ polyscan->getFaceId() ];
+ if ( !curface.PlaneValid() )
+ curface.CalcPlane( polyscan->getFirstVertex(),
+ polyscan->getSecondVertex(),
+ polyscan->getThirdVertex() );
+ }
+}
+
+
+// check all edges for t-vertices and insert trace-vertices as appropriate ----
+//
+void Polygon::CheckEdges()
+{
+ //NOTE:
+ // this function is terribly slow, because for every polygon
+ // every single edge is checked whether it contains any vertices.
+ // thus, overall every edge is checked twice for containment
+ // of all vertices and no topological information is used at all!
+
+ VertexChunk& vtxlist = getVertexList();
+
+ // scan all polygons
+ for ( Polygon *poly = this; poly; poly = poly->getNext() ) {
+ // just to be sure
+ int numvtxs = vtxlist.getNumElements();
+ if ( numvtxs < 3 )
+ continue;
+ // create vertex mask array
+ char *vmask = new char[ numvtxs ];
+ memset( vmask, 0, sizeof( char ) * numvtxs );
+ // scan all edges: init mask
+ VIndx *polyvertlist = poly->getVList();
+ for ( ; polyvertlist; polyvertlist = polyvertlist->getNext() )
+ vmask[ polyvertlist->getIndx() ] = 1;
+ // scan all edges: check t-junctions
+ polyvertlist = poly->getVList();
+ for ( ; polyvertlist; polyvertlist = polyvertlist->getNext() ) {
+ // determine next vertex with wrap-around
+ int nextvertex = polyvertlist->getNext() ?
+ polyvertlist->getNext()->getIndx() : poly->getVList()->getIndx();
+ // create directed edge
+ Vector3 linevec( vtxlist[ polyvertlist->getIndx() ], vtxlist[ nextvertex ] );
+ // check edge against all vertices not masked out
+ for ( int i = 0; i < numvtxs; i++ )
+ if ( vmask[ i ] == 0 ) {
+ LineSeg3 lineseg( vtxlist[ polyvertlist->getIndx() ], linevec );
+ if ( lineseg.PointOnLineSeg( vtxlist[ i ] ) ) {
+
+ // create new vertex-index
+ VIndx *tempvindx = new VIndx( i, polyvertlist->getNext() );
+ polyvertlist->setNext( tempvindx );
+ if ( tempvindx->getNext() == NULL ) {
+
+ //NOTE:
+ // if tracevertex is inserted into last edge, AppendNewVIndx() and AppendVIndx()
+ // wouldn't work anymore if the insertposition in the polygon isn't
+ // updated correctly; normally this isn't done anyway, though
+
+ vindxinsertpos = tempvindx;
+ }
+
+ // new endpoint for lineseg to check
+ nextvertex = i;
+ vmask[ i ] = 1;
+ linevec.CreateDirVec( vtxlist[ polyvertlist->getIndx() ], vtxlist[ nextvertex ] );
+ baseobject->numtracevertices++;
+
+ if ( display_messages & MESSAGE_TRACEVERTEX_INSERTED ) {
+ sprintf( str_scratchpad, "Trace vertex inserted: polygon %d, vertex %d\n",
+ poly->getId() + 1, i + 1 );
+ InfoMessage( str_scratchpad );
+ }
+ }
+ }
+ }
+ // remove mask array
+ delete vmask;
+ }
+}
+
+
+// split polygons with vertices not contained in the same plane ---------------
+//
+Polygon *Polygon::CheckPlanesAndMappings()
+{
+ //NOTE:
+ // for historical reasons this function checks only quadrilaterals
+ // for planarity! i.e., if a polygon has more than 4 vertices no
+ // check is done at all whether all vertices are contained in the
+ // same plane. quadrilaterals, however, are checked and split into
+ // two triangles if nonplanar.
+ // explicit triangulation of quadrilaterals can be forced by using
+ // the static Polygon::triangulate_all flag.
+
+ // fetch vertex and face lists
+ VertexChunk& vtxlist = getVertexList();
+ FaceChunk& facelist = getFaceList();
+
+ if ( display_messages & MESSAGE_CHECKING_POLYGON_PLANES )
+ InfoMessage( "\nChecking polygon planes and mappings...\n" );
+
+ // scan entire polygon list
+ Polygon *polylist = this;
+ for ( Polygon *polyscan = polylist; polyscan; polyscan = polyscan->getNext() ) {
+
+ Face& curface = facelist[ polyscan->getFaceId() ];
+ int vertindx1 = polyscan->getFirstVertexIndx();
+ int vertindx2 = polyscan->getSecondVertexIndx();
+ int vertindx3 = polyscan->getThirdVertexIndx();
+
+ // calculate face plane/normal if not already done
+ if ( !curface.PlaneValid() )
+ curface.CalcPlane( vtxlist[ vertindx1 ], vtxlist[ vertindx2 ], vtxlist[ vertindx3 ] );
+
+ // convert correspondences to face mapping if not already done
+ if ( curface.FaceTexMapped() && !curface.MappingAttached() ) {
+ // calc correspondence number
+ int corrno = 0;
+ for ( int i = 0; i < polyscan->getFaceId(); i++ )
+ if ( facelist[ i ].FaceTexMapped() )
+ corrno++;
+ // set projective space coordinates
+ curface.MapXY( 0 ).InitFromVertex3( vtxlist[ vertindx1 ] );
+ curface.MapXY( 1 ).InitFromVertex3( vtxlist[ vertindx2 ] );
+ curface.MapXY( 2 ).InitFromVertex3( vtxlist[ vertindx3 ] );
+ // set (u,v)-space coordinates
+ Vertex2 corrpoint;
+ corrpoint = baseobject->mappinglist[ corrno ].FetchMapPoint( vertindx1 );
+ curface.MapUV( 0 ) = corrpoint;
+ corrpoint = baseobject->mappinglist[ corrno ].FetchMapPoint( vertindx2 );
+ curface.MapUV( 1 ) = corrpoint;
+ corrpoint = baseobject->mappinglist[ corrno ].FetchMapPoint( vertindx3 );
+ curface.MapUV( 2 ) = corrpoint;
+ }
+
+ // check fourth vertex if face is quadrilateral
+ if ( polyscan->getNumVertices() == 4 ) {
+
+ VIndx *vindxscan = polyscan->getVList()->getNext()->getNext(); // pointer to third VIndx
+ int testvertindx = vindxscan->getNext()->getIndx(); // fourth vertindx
+ if ( !curface.getPlane().PointContained( vtxlist[ testvertindx ] ) || triangulate_all ) {
+
+ // split quadrilateral into triangles
+ polylist = polylist->NewPolygon(); // create second triangle
+ polylist->AppendNewVIndx( vertindx3 ); // append VIndx for third vertex
+ polylist->AppendVIndx( polyscan->UnlinkLastVIndx() ); // append existing VIndx for fourth vertex
+ polylist->AppendNewVIndx( vertindx1 ); // append VIndx for first vertex
+
+ if ( display_messages & MESSAGE_SPLITTING_QUADRILATERAL ) {
+ sprintf( str_scratchpad, "Splitting quadrilateral: polygon %d\n",
+ polyscan->getId() + 1 );
+ InfoMessage( str_scratchpad );
+ sprintf( str_scratchpad, "-->Creating new triangle: polygon %d\n",
+ polylist->getId() + 1 );
+ InfoMessage( str_scratchpad );
+ }
+ // update count of split quadrilaterals
+ baseobject->numsplitquadrilaterals++;
+ // create new face
+ int newfaceno = facelist.AddElement( curface );
+ Face& newface = facelist[ newfaceno ];
+ // update face id of new polygon
+ polylist->setFaceId( newfaceno );
+ // fetch first three vertices
+ vertindx1 = polylist->getFirstVertexIndx();
+ vertindx2 = polylist->getSecondVertexIndx();
+ vertindx3 = polylist->getThirdVertexIndx();
+ // calculate face normal
+ newface.CalcPlane( vtxlist[ vertindx1 ], vtxlist[ vertindx2 ], vtxlist[ vertindx3 ] );
+ // transfer mapping into face
+ if ( curface.FaceTexMapped() ) {
+ // calc correspondence number
+ int corrno = 0;
+ for ( int i = 0; i < polyscan->getFaceId(); i++ )
+ if( facelist[ i ].FaceTexMapped() )
+ corrno++;
+ // set projective space coordinates
+ newface.MapXY( 0 ).InitFromVertex3( vtxlist[ vertindx1 ] );
+ newface.MapXY( 1 ).InitFromVertex3( vtxlist[ vertindx2 ] );
+ newface.MapXY( 2 ).InitFromVertex3( vtxlist[ vertindx3 ] );
+ // set (u,v)-space coordinates
+ Vertex2 corrpoint;
+ corrpoint = baseobject->mappinglist[ corrno ].FetchMapPoint( vertindx1 );
+ newface.MapUV( 0 ) = corrpoint;
+ corrpoint = baseobject->mappinglist[ corrno ].FetchMapPoint( vertindx2 );
+ newface.MapUV( 1 ) = corrpoint;
+ corrpoint = baseobject->mappinglist[ corrno ].FetchMapPoint( vertindx3 );
+ newface.MapUV( 2 ) = corrpoint;
+ }
+ }
+ }
+ }
+
+ return polylist;
+}
+
+
+// calculate probability with which to test a single polygon ------------------
+//
+int Polygon::CalcSplitterTestProbability()
+{
+ double numerator = sample_size;
+ double denominator = numpolygons;
+ double prob = ( denominator > 0.0 ) ? numerator / denominator : 1.0;
+ prob = ( prob < 1.0 ) ? prob * 10000.0 : 10000.0;
+ test_probability = (int) floor( prob + 0.5 );
+ if ( test_probability < 1 ) test_probability = 1;
+ return ( numpolygons > 0 );
+}
+
+
+// unspecified error encountered ----------------------------------------------
+//
+void Polygon::Error() const
+{
+ ErrorMessage( "\n***ERROR*** in object of class BspLib::Polygon." );
+ HandleCriticalError();
+}
+
+
+// splitter selection ---------------------------------------------------------
+//
+int Polygon::splitter_crit = Polygon::SPLITTERCRIT_SAMPLE_ALL;
+int Polygon::sample_size = 20;
+int Polygon::test_probability = 10000; // means 100.00%
+
+
+// static flags ---------------------------------------------------------------
+//
+int Polygon::triangulate_all = FALSE;
+int Polygon::normalize_vectors = FALSE;
+int Polygon::display_messages = Polygon::MESSAGEMASK_DISPLAY_ALL;
+
+
+// counter for invocations of PartitionSpace() --------------------------------
+//
+int Polygon::partition_callcount = 0;
+
+
+// string scratch pad ---------------------------------------------------------
+//
+char Polygon::str_scratchpad[ 256 ] = "";
+
+
+BSPLIB_NAMESPACE_END
+
+//-----------------------------------------------------------------------------
diff --git a/tool_src/BspLib/Polygon.h b/tool_src/BspLib/Polygon.h
new file mode 100644
index 0000000..d83de32
--- /dev/null
+++ b/tool_src/BspLib/Polygon.h
@@ -0,0 +1,280 @@
+//-----------------------------------------------------------------------------
+// BSPLIB HEADER: Polygon.h
+//
+// Copyright (c) 1996-1998 by Markus Hadwiger
+// All Rights Reserved.
+//-----------------------------------------------------------------------------
+
+#ifndef _POLYGON_H_
+#define _POLYGON_H_
+
+// bsplib header files
+#include "BspLibDefs.h"
+#include "Chunk.h"
+#include "Face.h"
+#include "Plane.h"
+#include "SystemIO.h"
+
+
+BSPLIB_NAMESPACE_BEGIN
+
+
+class BoundingBox;
+
+
+// vertex index (element of vertex index list) --------------------------------
+//
+class VIndx {
+
+public:
+ VIndx( int indx = -1, VIndx *next = NULL ) { vertindx = indx; nextvertindx = next; }
+ ~VIndx() { delete nextvertindx; }
+
+ int getIndx() const { return vertindx; }
+ void setIndx( int indx ) { vertindx = indx; }
+
+ VIndx* getNext() const { return nextvertindx; }
+ void setNext( VIndx *next ) { nextvertindx = next; }
+
+private:
+ int vertindx; // -1 means end of list, regardless of nextvertindx
+ VIndx* nextvertindx; // pointer to next VIndx in singly linked list
+};
+
+
+class BSPNode;
+class BspObject;
+
+
+// single polygon (element of polygon list) -----------------------------------
+//
+class Polygon : public virtual SystemIO {
+
+ friend class PolygonListRep;
+
+ void Error() const;
+
+ // possible classifications of polygon with respect to splitting plane
+ enum {
+ POLY_IN_FRONT_SUBSPACE,
+ POLY_IN_BACK_SUBSPACE,
+ POLY_STRADDLES_SPLITTER,
+ POLY_IN_SAME_PLANE,
+ };
+
+ // frontsubspace/backsubspace identifiers
+ enum {
+ FRONT_SUBSPACE = 1,
+ BACK_SUBSPACE = -1
+ };
+
+public:
+
+ // splitter selection criteria
+ enum {
+ SPLITTERCRIT_FIRST_POLY = 0x0000, // always choose first polygon in list
+ SPLITTERCRIT_SAMPLE_FIRST_N = 0x0101, // test first n polygons in list
+ SPLITTERCRIT_SAMPLE_ALL = 0x0002, // test entire list and choose best
+ SPLITTERCRIT_RANDOM_SAMPLE = 0x0103, // sample n polygons randomly
+ SPLITTERCRITMASK_SAMPLESIZ = 0x0100, // flagmask if samplesize (n) needed
+ };
+
+ // message flags
+ enum {
+ MESSAGE_SPLITTING_POLYGON = 0x0001,
+ MESSAGE_STARTVERTEX_IN_SPLITTER_PLANE = 0x0002,
+ MESSAGE_VERTEX_IN_SPLITTER_PLANE = 0x0004,
+ MESSAGE_NEW_SPLITVERTEX = 0x0008,
+ MESSAGE_REUSING_SPLITVERTEX = 0x0010,
+ MESSAGE_TRACEVERTEX_INSERTED = 0x0020,
+ MESSAGE_SPLITTING_QUADRILATERAL = 0x0040,
+ MESSAGE_INVOCATION = 0x0080,
+ MESSAGE_CHECKING_POLYGON_PLANES = 0x0100,
+ MESSAGEMASK_DISPLAY_ALL = 0xffff
+ };
+
+public:
+ Polygon( BspObject *bobj, int pno = 0, int fno = 0, Polygon *next = NULL, int num = 1 );
+ ~Polygon() { delete vertindxs; delete nextpolygon; }
+
+ Polygon* NewPolygon(); // create new polygon with sequential id as head of list
+ Polygon* InsertPolygon( Polygon *poly ); // insert existing polygon as head of list
+ Polygon* DeleteHead(); // delete this, return rest of list (DANGEROUS!)
+ Polygon* FindPolygon( int id ); // return polygon in list having specified id
+ int SumVertexNumsEntireList(); // sum up vertex numbers for all polygons of list
+
+ void PrependNewVIndx( int indx ); // create new VIndx and prepend it to list (vertindxs)
+ void AppendNewVIndx( int indx = -1 ); // create new VIndx and append it to list (vertindxs)
+ void AppendVIndx( VIndx *vindx ); // append existing VIndx to list (vertindxs)
+ VIndx* UnlinkLastVIndx(); // return last VIndx in list after unlinking it
+
+ void CalcPlaneNormals(); // calc normals for all polygons in list
+ void CheckEdges(); // check edges for contained vertices (scans list!)
+ Polygon* CheckPlanesAndMappings(); // check planes and mappings of all polygons in list
+
+ // calculate bounding box encompassing all polygons in list
+ void CalcBoundingBox( BoundingBox* &boundingbox );
+
+ // classify polygon with respect to this polygon
+ int CheckIntersection( Polygon *testpoly );
+ // check if other polygon's normal is contained in this one's positive halfspace (predicate)
+ int NormalDirectionSimilar( Polygon *testpoly );
+ // split other polygon along this polygon; insert split pieces into their respective halfspaces
+ void SplitPolygon( Polygon *poly, Polygon* &frontsubspace, Polygon* &backsubspace );
+ // partition space encompassing entire polygon list; return created BSP tree's root
+ BSPNode* PartitionSpace();
+
+ // correct numberings (polygon-id, face-id, and vertex indexes) to new base
+ void CorrectBase( BspObject *newbaseobj, int vertexindxbase, int faceidbase, int polygonidbase );
+ void CorrectBaseByTable( BspObject *newbaseobj, int *vtxindxmap, int faceidbase, int polygonidbase );
+
+ int getId() const { return polygonno; }
+ void setId( int pno ) { polygonno = pno; }
+
+ int getFaceId() const { return faceno; }
+ void setFaceId( int fno ) { faceno = fno; }
+
+ int getNumPolygons() const { return numpolygons; }
+ void setNumPolygons( int len ) { numpolygons = len; }
+
+ Polygon* getNext() const { return nextpolygon; }
+ void setNext( Polygon *next ) { nextpolygon = next; }
+
+ int getNumVertices() const { return numvertindxs; }
+
+ VIndx* getVList() const { return vertindxs; }
+ BspObject* getBaseObject() const { return baseobject; }
+
+ VertexChunk& getVertexList();
+ FaceChunk& getFaceList();
+
+ int HasArea() const;
+
+ int getFirstVertexIndx() const;
+ int getSecondVertexIndx() const;
+ int getThirdVertexIndx() const;
+
+ Vertex3 getFirstVertex() const;
+ Vertex3 getSecondVertex() const;
+ Vertex3 getThirdVertex() const;
+
+ Plane getPlane() const { return ((Polygon *const)this)->getFaceList()[ faceno ].getPlane(); }
+ Vector3 getPlaneNormal() const { return ((Polygon *const)this)->getFaceList()[ faceno ].getPlaneNormal(); }
+
+ void FillVertexIndexArray( dword *arr ) const; // write list of vertices into array
+ void WriteVertexList( FILE *fp, int cr ) const; // write list of vertices to file
+ void WritePolyList( FILE *fp ) const; // write list of polygon ids to file
+
+ int CalcSplitterTestProbability();
+
+public:
+ static int getSplitterSelection() { return splitter_crit; }
+ static void setSplitterSelection( int criterion ) { splitter_crit = criterion; }
+
+ static int getSampleSize() { return sample_size; }
+ static void setSampleSize( int siz ) { sample_size = siz; }
+
+ static int getTriangulationFlag() { return triangulate_all; }
+ static void setTriangulationFlag( int flag ) { triangulate_all = flag; }
+
+ static int getNormalizeVectorsFlag() { return normalize_vectors; }
+ static void setNormalizeVectorsFlag( int flag ) { normalize_vectors = flag; }
+
+ static int getDisplayMessagesFlag() { return display_messages; }
+ static void setDisplayMessagesFlag( int flag ) { display_messages = flag; }
+
+ static void ResetCallCount() { partition_callcount = 0; }
+
+private:
+ static int splitter_crit; // splitter selection criterion to use
+ static int sample_size; // sample size for splitter sampling
+ static int triangulate_all; // triangulate polygons with more than three vertices
+ static int normalize_vectors; // always normalize direction vectors
+ static int display_messages; // display a message every time PartitionSpace() is invoked
+ static int partition_callcount;// call counter for PartitionSpace()
+ static int test_probability; // probability to test single polygon if SPLITTERCRIT_RANDOM_SAMPLE
+ static char str_scratchpad[]; // string scratch pad
+
+private:
+ int polygonno; // global number of this polygon
+ int faceno; // global number of face this polygon is contained in
+ int numpolygons; // length of singly linked polygon list
+ int numvertindxs; // number of entries in vertex index list attached to this polygon
+ VIndx* vertindxs; // pointer to first VIndx
+ VIndx* vindxinsertpos; // pointer to last VIndx (NULL means insert-position is at head)
+ BspObject* baseobject; // pointer to object this polygon belongs to
+ Polygon* nextpolygon; // pointer to next polygon in list
+};
+
+// determine if the polygon has area ------------------------------------------
+inline int Polygon::HasArea() const
+{
+ // collinear vertices are not checked here, the polygon need only have
+ // at least three vertices to count as having area!
+ return ( vertindxs && vertindxs->getNext() && vertindxs->getNext()->getNext() );
+}
+
+// get first vertex of polygon ------------------------------------------------
+inline int Polygon::getFirstVertexIndx() const
+{
+ CHECK_DEREFERENCING(
+ if ( vertindxs == NULL )
+ Error();
+ );
+ return vertindxs->getIndx();
+}
+inline Vertex3 Polygon::getFirstVertex() const
+{
+ CHECK_DEREFERENCING(
+ if ( vertindxs == NULL )
+ Error();
+ );
+ return ((Polygon *const)this)->getVertexList()[ vertindxs->getIndx() ];
+}
+
+// get second vertex of polygon -----------------------------------------------
+inline int Polygon::getSecondVertexIndx() const
+{
+ CHECK_DEREFERENCING(
+ if ( ( vertindxs == NULL ) || ( vertindxs->getNext() == NULL ) )
+ Error();
+ );
+ return vertindxs->getNext()->getIndx();
+}
+inline Vertex3 Polygon::getSecondVertex() const
+{
+ CHECK_DEREFERENCING(
+ if ( ( vertindxs == NULL ) || ( vertindxs->getNext() == NULL ) )
+ Error();
+ );
+ return ((Polygon *const)this)->getVertexList()[ vertindxs->getNext()->getIndx() ];
+}
+
+// get third vertex of polygon ------------------------------------------------
+inline int Polygon::getThirdVertexIndx() const
+{
+ CHECK_DEREFERENCING(
+ if ( ( vertindxs == NULL ) ||
+ ( vertindxs->getNext() == NULL ) ||
+ ( vertindxs->getNext()->getNext() == NULL ) )
+ Error();
+ );
+ return vertindxs->getNext()->getNext()->getIndx();
+}
+inline Vertex3 Polygon::getThirdVertex() const
+{
+ CHECK_DEREFERENCING(
+ if ( ( vertindxs == NULL ) ||
+ ( vertindxs->getNext() == NULL ) ||
+ ( vertindxs->getNext()->getNext() == NULL ) )
+ Error();
+ );
+ return ((Polygon *const)this)->getVertexList()[ vertindxs->getNext()->getNext()->getIndx() ];
+}
+
+
+BSPLIB_NAMESPACE_END
+
+
+#endif // _POLYGON_H_
+
diff --git a/tool_src/BspLib/PolygonList.cpp b/tool_src/BspLib/PolygonList.cpp
new file mode 100644
index 0000000..4233c42
--- /dev/null
+++ b/tool_src/BspLib/PolygonList.cpp
@@ -0,0 +1,213 @@
+//-----------------------------------------------------------------------------
+// BSPLIB MODULE: PolygonList.cpp
+//
+// Copyright (c) 1997 by Markus Hadwiger
+// All Rights Reserved.
+//-----------------------------------------------------------------------------
+
+// bsplib headers
+#include "PolygonList.h"
+#include "BspObject.h"
+#include "BspTool.h"
+#include "BSPNode.h"
+#include "Vertex.h"
+
+
+BSPLIB_NAMESPACE_BEGIN
+
+
+// init with already existing list of polygons --------------------------------
+//
+Polygon *PolygonListRep::InitList( Polygon *listhead )
+{
+ delete list;
+ list = listhead;
+ numpolygons = list ? list->getNumPolygons() : 0;
+
+ return list;
+}
+
+
+// merge another polygon list into this list ----------------------------------
+//
+void PolygonListRep::MergeLists( PolygonListRep *mergelist )
+{
+ if ( list != NULL ) {
+ // scan to end of local list
+ Polygon *poly = NULL;
+ for (poly = list; poly->getNext(); poly = poly->getNext() )
+ poly->setNumPolygons( poly->getNumPolygons() + mergelist->numpolygons );
+ // append mergelist
+ poly->setNext( mergelist->list );
+ poly->setNumPolygons( poly->getNumPolygons() + mergelist->numpolygons );
+ numpolygons += mergelist->numpolygons;
+ } else {
+ // local list is empty: simply take over mergelist
+ list = mergelist->list;
+ numpolygons = mergelist->numpolygons;
+ }
+}
+
+
+// create new polygon and add at head of list ---------------------------------
+//
+Polygon *PolygonListRep::NewPolygon()
+{
+ list = list ? list->NewPolygon() : new Polygon( baseobject );
+ numpolygons = list->getNumPolygons();
+
+ return list;
+}
+
+
+// insert existing polygon at head of list ------------------------------------
+//
+Polygon *PolygonListRep::InsertPolygon( Polygon *poly )
+{
+ if ( poly != NULL ) {
+
+ if ( list != NULL ) {
+ list = list->InsertPolygon( poly );
+ } else {
+ poly->setNext( NULL );
+ poly->setNumPolygons( 1 );
+ poly->baseobject = baseobject;
+ list = poly;
+ }
+ numpolygons = list->getNumPolygons();
+ }
+
+ return list;
+}
+
+
+// unlink head from list and return pointer to it -----------------------------
+//
+Polygon *PolygonListRep::UnlinkHead()
+{
+ Polygon *tmp = list;
+
+ if ( tmp != NULL ) {
+ list = tmp->getNext();
+ tmp->setNumPolygons( 1 );
+ tmp->setNext( NULL );
+ numpolygons = list ? list->getNumPolygons() : 0;
+ }
+
+ return tmp;
+}
+
+
+// delete head of list and return pointer to rest of list ---------------------
+//
+Polygon *PolygonListRep::DeleteHead()
+{
+ if ( list != NULL ) {
+ list = list->DeleteHead();
+ numpolygons = list ? list->getNumPolygons() : 0;
+ }
+
+ return list;
+}
+
+
+// calculate plane normals for planes of all polygons -------------------------
+//
+Polygon *PolygonListRep::CalcPlaneNormals()
+{
+ if ( list != NULL ) {
+ list->CalcPlaneNormals();
+ }
+
+ return list;
+}
+
+
+// check polygon planes for all polygons contained in list --------------------
+//
+Polygon *PolygonListRep::CheckPolygonPlanes()
+{
+ if ( list != NULL ) {
+ // list possibly grows due to checking planes!!
+ list = list->CheckPlanesAndMappings();
+ numpolygons = list->getNumPolygons();
+ }
+
+ return list;
+}
+
+
+// build bsp tree; polygon list is resolved in the process --------------------
+//
+BSPNode *PolygonListRep::PartitionSpace()
+{
+ BSPNode *bspnode = NULL;
+
+ if ( list != NULL ) {
+
+ if ( list->getSplitterSelection() == Polygon::SPLITTERCRIT_RANDOM_SAMPLE ) {
+ // calculate random sample probability
+ list->CalcSplitterTestProbability();
+ }
+
+ bspnode = list->PartitionSpace();
+ list = NULL;
+ numpolygons = 0;
+ //NOTE:
+ // the polygon list is resolved in the process of
+ // bsp compilation! polygons are only accessible as
+ // elements of the newly created bsp tree afterwards.
+ }
+
+ return bspnode;
+}
+
+
+// write list of polygon numbers to text-file (reverse ordering) --------------
+//
+void PolygonListRep::WritePolyList( FILE *fp, int no ) const
+{
+ if ( list != NULL ) {
+ if ( list->nextpolygon )
+ list->nextpolygon->WritePolyList( fp );
+ fprintf( fp, "%d\t\t; %d\n", list->getId() + 1, no );
+ }
+}
+
+
+// class PolygonList error message handler ------------------------------------
+//
+void PolygonListRep::Error( int err ) const
+{
+ {
+ StrScratch line;
+
+ switch ( err ) {
+
+ case E_NEWVINDX:
+ strcpy( line, "***ERROR*** in PolygonList::(Append|Prepend)NewVIndx()\n" );
+ break;
+
+ case E_APPENDVINDX:
+ strcpy( line, "***ERROR*** in PolygonList::AppendVIndx()\n" );
+ break;
+
+ case E_GETNUMVERTXS:
+ strcpy( line, "***ERROR*** in PolygonList::getNumElements()\n" );
+ break;
+
+ default:
+ strcpy( line, "***ERROR*** in object of class BspLib::PolygonList\n" );
+ break;
+ }
+
+ ErrorMessage( line );
+ }
+
+ HandleCriticalError();
+}
+
+
+BSPLIB_NAMESPACE_END
+
+//-----------------------------------------------------------------------------
diff --git a/tool_src/BspLib/PolygonList.h b/tool_src/BspLib/PolygonList.h
new file mode 100644
index 0000000..c06ec8c
--- /dev/null
+++ b/tool_src/BspLib/PolygonList.h
@@ -0,0 +1,153 @@
+//-----------------------------------------------------------------------------
+// BSPLIB HEADER: PolygonList.h
+//
+// Copyright (c) 1997 by Markus Hadwiger
+// All Rights Reserved.
+//-----------------------------------------------------------------------------
+
+#ifndef _POLYGONLIST_H_
+#define _POLYGONLIST_H_
+
+// bsplib header files
+#include "BspLibDefs.h"
+#include "Polygon.h"
+#include "SystemIO.h"
+
+
+BSPLIB_NAMESPACE_BEGIN
+
+
+class BSPNode;
+class BspObject;
+
+
+// singly linked polygon list (representation class) --------------------------
+//
+class PolygonListRep : public virtual SystemIO {
+
+ friend class PolygonList;
+
+ // error codes
+ enum {
+ E_NEWVINDX,
+ E_APPENDVINDX,
+ E_GETNUMVERTXS
+ };
+
+ // error handler for class PolygonList
+ void Error( int err ) const;
+
+private:
+ PolygonListRep( BspObject *bobj );
+ ~PolygonListRep() { delete list; }
+
+ void MergeLists( PolygonListRep *mergelist );
+
+ Polygon* InitList( Polygon *listhead );
+
+ // invalidate list without freeing dynamic storage
+ void InvalidateList() { list = NULL; numpolygons = 0; }
+
+ Polygon* FetchHead() { return list; }
+ Polygon* UnlinkHead();
+ Polygon* DeleteHead();
+ Polygon* FindPolygon( int id ) { return list ? list->FindPolygon( id ) : NULL; }
+
+ Polygon* NewPolygon();
+ Polygon* InsertPolygon( Polygon *poly );
+
+ void PrependNewVIndx( int indx = -1 ) { if ( list == NULL ) Error( E_NEWVINDX ); list->PrependNewVIndx( indx ); }
+ void AppendNewVIndx( int indx = -1 ) { if ( list == NULL ) Error( E_NEWVINDX ); list->AppendNewVIndx( indx ); }
+ void AppendVIndx( VIndx *vindx ) { if ( list == NULL ) Error( E_APPENDVINDX ); list->AppendVIndx( vindx ); }
+ Polygon* CalcPlaneNormals();
+ Polygon* CheckPolygonPlanes();
+ BSPNode* PartitionSpace();
+
+ void WritePolyList( FILE *fp, int no ) const;
+
+ int getNumElements() const { return numpolygons; }
+ int getNumVertices() const { if( list == NULL ) Error( E_GETNUMVERTXS ); return list->getNumVertices(); }
+
+private:
+ int ref_count; // number of references to this list
+ int numpolygons; // length of singly linked polygon list (not counting this head)
+ BspObject* baseobject; // this list contains polygons belonging to *baseobject
+ Polygon* list; // pointer to first polygon in list
+};
+
+// constructor without preexisting list ---------------------------------------
+inline PolygonListRep::PolygonListRep( BspObject *bobj ) : ref_count( 0 )
+{
+ baseobject = bobj;
+ list = NULL;
+ numpolygons = 0;
+}
+
+
+// singly linked polygon list (handle class) ----------------------------------
+//
+class PolygonList {
+
+public:
+ PolygonList( BspObject *bobj ) { rep = new PolygonListRep( bobj ); rep->ref_count = 1; }
+ ~PolygonList() { if ( --rep->ref_count == 0 ) delete rep; }
+
+ PolygonList( const PolygonList& copyobj );
+ PolygonList& operator =( const PolygonList& copyobj );
+
+ void MergeLists( PolygonList *mergelist ) { if ( mergelist ) rep->MergeLists( mergelist->rep ); }
+
+ Polygon* InitList( Polygon *listhead ) { return rep->InitList( listhead ); }
+ void InvalidateList() { rep->InvalidateList(); }
+
+ Polygon* FetchHead() { return rep->FetchHead(); }
+ Polygon* UnlinkHead() { return rep->UnlinkHead(); }
+ Polygon* DeleteHead() { return rep->DeleteHead(); }
+ Polygon* FindPolygon( int id ) { return rep->FindPolygon( id ); }
+
+ Polygon* NewPolygon() { return rep->NewPolygon(); }
+ Polygon* InsertPolygon( Polygon *poly ) { return rep->InsertPolygon( poly ); }
+
+ void PrependNewVIndx( int indx = -1 ) { rep->PrependNewVIndx( indx ); }
+ void AppendNewVIndx( int indx = -1 ) { rep->AppendNewVIndx( indx ); }
+ void AppendVIndx( VIndx *vindx ) { rep->AppendVIndx( vindx ); }
+ Polygon* CalcPlaneNormals() { return rep->CalcPlaneNormals(); }
+ Polygon* CheckPolygonPlanes() { return rep->CheckPolygonPlanes(); }
+ BSPNode* PartitionSpace() { return rep->PartitionSpace(); }
+
+ void WritePolyList( FILE *fp, int no ) const { rep->WritePolyList( fp, no ); }
+
+ int getNumElements() const { return rep->getNumElements(); }
+ int getNumVertices() const { return rep->getNumVertices(); }
+
+private:
+ PolygonListRep* rep;
+};
+
+// copy constructor for PolygonList -------------------------------------------
+inline PolygonList::PolygonList( const PolygonList& copyobj )
+{
+ rep = copyobj.rep; // shallow copy
+ rep->ref_count++; // with reference counting
+}
+
+// assignment operator for PolygonList ----------------------------------------
+inline PolygonList& PolygonList::operator =( const PolygonList& copyobj )
+{
+ if ( &copyobj != this ) {
+ // old reference is overwritten
+ if ( --rep->ref_count == 0 ) {
+ delete rep;
+ }
+ rep = copyobj.rep; // shallow copy
+ rep->ref_count++; // with reference counting
+ }
+ return *this;
+}
+
+
+BSPLIB_NAMESPACE_END
+
+
+#endif // _POLYGONLIST_H_
+
diff --git a/tool_src/BspLib/SingleFormat.cpp b/tool_src/BspLib/SingleFormat.cpp
new file mode 100644
index 0000000..f1db564
--- /dev/null
+++ b/tool_src/BspLib/SingleFormat.cpp
@@ -0,0 +1,158 @@
+//-----------------------------------------------------------------------------
+// BSPLIB MODULE: SingleFormat.cpp
+//
+// Copyright (c) 1997 by Markus Hadwiger
+// All Rights Reserved.
+//-----------------------------------------------------------------------------
+
+// bsplib header files
+#include "SingleFormat.h"
+
+
+BSPLIB_NAMESPACE_BEGIN
+
+
+// construct class SingleFormat by initializing Single specific members -------------
+//
+inline SingleFormatBase::SingleFormatBase()
+{
+ strcpy( xchangecmd, "xyz" );
+
+ AxesDirSwitch = Vertex3( 1.0, 1.0, 1.0 );
+
+ ObjScaleX = 1.0;
+ ObjScaleY = 1.0;
+ ObjScaleZ = 1.0;
+
+ NewOriginX = 0.0;
+ NewOriginY = 0.0;
+ NewOriginZ = 0.0;
+
+ worldlocation_set = FALSE;
+ camera_set = FALSE;
+ xchange_set = FALSE;
+ scalefactors_set = FALSE;
+ setorigin_set = FALSE;
+
+ // init default world and view matrix
+ for ( int j = 0; j < 4; j++ ) {
+ for ( int i = 0; i < 4; i++ ) {
+ int indx = j * 4 + i;
+ vm[ indx ] = wm[ indx ] = ( j == i ) ? 1.0 : 0.0;
+ }
+ }
+}
+
+
+// constructor for SingleFormat -----------------------------------------------
+//
+SingleFormat::SingleFormat()
+{
+ // all initializations are done
+ // in SingleFormatBase::SingleFormatBase()
+}
+
+
+// copy constructor for SingleFormat ------------------------------------------
+//
+SingleFormat::SingleFormat( const SingleFormat& copyobj ) :
+ SingleFormatBase( copyobj ),
+ m_palette_fname( copyobj.m_palette_fname )
+{
+}
+
+
+// assignment operator for SingleFormat ---------------------------------------
+//
+SingleFormat& SingleFormat::operator =( const SingleFormat& copyobj )
+{
+ if ( &copyobj != this ) {
+ *(SingleFormatBase *)this = copyobj;
+ m_palette_fname = copyobj.m_palette_fname;
+ }
+ return *this;
+}
+
+
+// get index to section id specified as string (this function is static!) -----
+//
+int SingleFormat::GetSectionId( char *section_name )
+{
+ for ( int i = _nil + 1; i < _num_single_sections; i++ )
+ if ( stricmp( section_name, section_strings[ i ] ) == 0 )
+ return section_ids[ i ];
+
+ // _nil means section name invalid, so no valid index can be returned
+ return _nil;
+}
+
+
+// get name of section specified via id (this function is static!) ------------
+//
+const char *SingleFormat::GetSectionName( int section_id )
+{
+ return ( section_id < _num_single_sections ) ? section_strings[ section_id ] : NULL;
+}
+
+
+// SingleFormat specific static variables -------------------------------------
+//
+
+// origin translation automatically applied to all objects
+const double SingleFormat::PREMOVEORIGIN_X = 0.0;
+const double SingleFormat::PREMOVEORIGIN_Y = 0.0;
+const double SingleFormat::PREMOVEORIGIN_Z = 0.0;
+
+// section names
+const char SingleFormat::_vertices_str[] = "#vertices";
+const char SingleFormat::_faces_str[] = "#faces";
+const char SingleFormat::_faceproperties_str[] = "#faceproperties";
+const char SingleFormat::_correspondences_str[] = "#correspondences";
+const char SingleFormat::_textures_str[] = "#textures";
+const char SingleFormat::_worldlocation_str[] = "#worldlocation";
+const char SingleFormat::_camera_str[] = "#camera";
+const char SingleFormat::_comment_str[] = "#comment";
+const char SingleFormat::_palette_str[] = "#palette";
+const char SingleFormat::_scalefactors_str[] = "#scalefactors";
+const char SingleFormat::_xchange_str[] = "#xchange";
+const char SingleFormat::_setorigin_str[] = "#setorigin";
+const char SingleFormat::_facenormals_str[] = "#facenormals";
+
+// section name table
+const char *SingleFormat::section_strings[] = {
+ NULL,
+ _vertices_str,
+ _faces_str,
+ _faceproperties_str,
+ _correspondences_str,
+ _textures_str,
+ _worldlocation_str,
+ _camera_str,
+ _comment_str,
+ _palette_str,
+ _scalefactors_str,
+ _xchange_str,
+ _setorigin_str,
+ _facenormals_str
+};
+const int SingleFormat::section_ids[] = {
+ _nil,
+ _vertices,
+ _faces,
+ _faceproperties,
+ _correspondences,
+ _textures,
+ _worldlocation,
+ _camera,
+ _comment,
+ _palette,
+ _scalefactors,
+ _xchange,
+ _setorigin,
+ _facenormals
+};
+
+
+BSPLIB_NAMESPACE_END
+
+//-----------------------------------------------------------------------------
diff --git a/tool_src/BspLib/SingleFormat.h b/tool_src/BspLib/SingleFormat.h
new file mode 100644
index 0000000..36d7fdd
--- /dev/null
+++ b/tool_src/BspLib/SingleFormat.h
@@ -0,0 +1,119 @@
+//-----------------------------------------------------------------------------
+// BSPLIB HEADER: SingleFormat.h
+//
+// Copyright (c) 1997 by Markus Hadwiger
+// All Rights Reserved.
+//-----------------------------------------------------------------------------
+
+#ifndef _SINGLEFORMAT_H_
+#define _SINGLEFORMAT_H_
+
+// bsplib header files
+#include "BspLibDefs.h"
+#include "SystemIO.h"
+#include "Vertex.h"
+
+
+BSPLIB_NAMESPACE_BEGIN
+
+
+// baseclass for single format type file input/output -------------------------
+//
+class SingleFormatBase {
+
+ friend class SingleFormat;
+
+private:
+ SingleFormatBase();
+ ~SingleFormatBase() { }
+
+protected:
+ char xchangecmd[4];
+
+ Vertex3 AxesDirSwitch;
+
+ double ObjScaleX;
+ double ObjScaleY;
+ double ObjScaleZ;
+
+ double NewOriginX;
+ double NewOriginY;
+ double NewOriginZ;
+
+ int worldlocation_set;
+ int camera_set;
+ int xchange_set;
+ int scalefactors_set;
+ int setorigin_set;
+
+ hprec_t wm[16]; // world matrix
+ hprec_t vm[16]; // view matrix
+};
+
+class SingleFormat : public SingleFormatBase {
+
+protected:
+
+ // section enumeration
+ enum {
+ _nil,
+ _vertices,
+ _faces,
+ _faceproperties,
+ _correspondences,
+ _textures,
+ _worldlocation,
+ _camera,
+ _comment,
+ _palette,
+ _scalefactors,
+ _xchange,
+ _setorigin,
+ _facenormals,
+
+ _num_single_sections
+ };
+
+public:
+ SingleFormat();
+ ~SingleFormat() { }
+
+ SingleFormat( const SingleFormat& copyobj );
+ SingleFormat& operator =( const SingleFormat& copyobj );
+
+protected:
+ String m_palette_fname;
+
+protected:
+ static int GetSectionId( char *section_name );
+ static const char* GetSectionName( int section_id );
+
+protected:
+ static const double PREMOVEORIGIN_X;
+ static const double PREMOVEORIGIN_Y;
+ static const double PREMOVEORIGIN_Z;
+
+ static const char _vertices_str[];
+ static const char _faces_str[];
+ static const char _faceproperties_str[];
+ static const char _correspondences_str[];
+ static const char _textures_str[];
+ static const char _worldlocation_str[];
+ static const char _camera_str[];
+ static const char _comment_str[];
+ static const char _palette_str[];
+ static const char _scalefactors_str[];
+ static const char _xchange_str[];
+ static const char _setorigin_str[];
+ static const char _facenormals_str[];
+
+ static const char* section_strings[];
+ static const int section_ids[];
+};
+
+
+BSPLIB_NAMESPACE_END
+
+
+#endif // _SINGLEFORMAT_H_
+
diff --git a/tool_src/BspLib/SingleInput.cpp b/tool_src/BspLib/SingleInput.cpp
new file mode 100644
index 0000000..1f13616
--- /dev/null
+++ b/tool_src/BspLib/SingleInput.cpp
@@ -0,0 +1,699 @@
+//-----------------------------------------------------------------------------
+// BSPLIB MODULE: SingleInput.cpp
+//
+// Copyright (c) 1996-1998 by Markus Hadwiger
+// All Rights Reserved.
+//-----------------------------------------------------------------------------
+
+// bsplib header files
+#include "SingleInput.h"
+#include "BspObject.h"
+#include "BspTool.h"
+
+
+BSPLIB_NAMESPACE_BEGIN
+
+
+// file is read and parsed immediately after construction of an object --------
+//
+SingleInput::SingleInput( BspObjectList objectlist, const char *filename ) :
+ InputData3D( objectlist, filename, DONT_CREATE_OBJECT ),
+ m_baseobject( objectlist.CreateNewObject() ),
+ m_input( filename, "r" )
+{
+ m_parser_lineno = 0;
+ ParseObjectData();
+}
+
+
+// destructor destroys only class members and the base classes ----------------
+//
+SingleInput::~SingleInput()
+{
+}
+
+
+// convert color indexes to rgb values ----------------------------------------
+//
+int SingleInput::ConvertColIndxs()
+{
+ // do colorindex to rgb conversion
+ if ( m_palette_fname != NULL ) {
+ char *palette = new char[ 256 * 3 ];
+ FileAccess palfile( m_palette_fname, "rb", 0 );
+ if ( palfile.Status() == SYSTEM_IO_OK ) {
+ if ( palfile.Read( palette, 3, 256 ) != SYSTEM_IO_OK ) {
+ if ( getRGBConversionFlag() )
+ ErrorMessage( "Specified palette invalid or read error.\n" );
+ delete palette;
+ return FALSE;
+ } else if ( m_baseobject->ConvertColorIndexesToRGB( palette, getRGBConversionFlag() ) ) {
+ if ( getRGBConversionFlag() )
+ InfoMessage( "Color indexes converted to RGB triplets.\n" );
+ delete palette;
+ }
+ } else {
+ if ( getRGBConversionFlag() )
+ ErrorMessage( "Specified palette not found.\n" );
+ delete palette;
+ return FALSE;
+ }
+ } else {
+ if ( getRGBConversionFlag() )
+ ErrorMessage( "Conversion col-indexes to RGB triplets desired, but no palette set!\n" );
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
+// apply translation specified as origin --------------------------------------
+//
+void SingleInput::ApplyOriginTranslation()
+{
+ //CAVEAT:
+ // this will corrupt explicit separator planes and bounding boxes.
+ // thus, it must only be used for files where these two data types
+ // don't occur!
+
+ // scan all vertices and translate them
+ VertexChunk& vtxlist = m_baseobject->getVertexList();
+ for ( int i = 0; i < vtxlist.getNumElements(); i++ ) {
+ vtxlist[ i ].setX( vtxlist[ i ].getX() - NewOriginX );
+ vtxlist[ i ].setY( vtxlist[ i ].getY() - NewOriginY );
+ vtxlist[ i ].setZ( vtxlist[ i ].getZ() - NewOriginZ );
+ }
+ NewOriginX = NewOriginY = NewOriginZ = 0.0;
+}
+
+
+// filter direction switches for axes -----------------------------------------
+//
+void SingleInput::FilterAxesDirSwitch()
+{
+ //CAVEAT:
+ // this will corrupt explicit separator planes, bounding boxes,
+ // and affine mappings. thus, it must only be used for files
+ // where these three data types don't occur!
+
+ if ( PostProcessingFlags & FILTER_AXES_DIR_SWITCH ) {
+
+ //NOTE:
+ // axis direction switches (negative object scale factors)
+ // are only filtered here. that is, they don't make it into
+ // the output file. they are only applied to the object if
+ // FILTER_AXES_EXCHANGE is also specified!
+
+ // filter direction switches of axes
+ double xc = ( ObjScaleX < 0 ) ? -1.0 : 1.0;
+ double yc = ( ObjScaleY < 0 ) ? -1.0 : 1.0;
+ double zc = ( ObjScaleZ < 0 ) ? -1.0 : 1.0;
+
+ AxesDirSwitch = Vertex3( xc, yc, zc );
+
+ ObjScaleX *= xc;
+ ObjScaleY *= yc;
+ ObjScaleZ *= zc;
+ }
+}
+
+
+// filter object scale factors and apply them ---------------------------------
+//
+void SingleInput::FilterScaleFactors()
+{
+ //CAVEAT:
+ // this will corrupt explicit separator planes, bounding boxes,
+ // and affine mappings. thus, it must only be used for files
+ // where these three data types don't occur!
+
+ if ( PostProcessingFlags & FILTER_SCALE_FACTORS ) {
+ // scan all vertices and apply scale factors
+ VertexChunk& vtxlist = m_baseobject->getVertexList();
+ for ( int i = 0; i < vtxlist.getNumElements(); i++ ) {
+ vtxlist[ i ].setX( vtxlist[ i ].getX() * ObjScaleX );
+ vtxlist[ i ].setY( vtxlist[ i ].getY() * ObjScaleY );
+ vtxlist[ i ].setZ( vtxlist[ i ].getZ() * ObjScaleZ );
+ }
+ // reset (filter) scale factors
+ ObjScaleX = ObjScaleY = ObjScaleZ = 1.0;
+ }
+}
+
+
+// exchange axes according to specification -----------------------------------
+//
+void SingleInput::FilterAxesExchange()
+{
+ //CAVEAT:
+ // this will corrupt explicit separator planes, bounding boxes,
+ // and affine mappings. thus, it must only be used for files
+ // where these three data types don't occur!
+
+ if ( PostProcessingFlags & FILTER_AXES_EXCHANGE ) {
+
+ // exchange axes by applying axes exchange command to every
+ // vertex. axis direction switches are also applied if they
+ // have been filtered previously (FILTER_AXES_DIR_SWITCH).
+ VertexChunk& vtxlist = m_baseobject->getVertexList();
+ for ( int i = 0; i < vtxlist.getNumElements(); i++ )
+ vtxlist[ i ].ChangeAxes( xchangecmd, AxesDirSwitch );
+
+ // reset exchange command
+ strcpy( xchangecmd, "xyz" );
+ }
+}
+
+
+// enforce maximum extents for all coordinates --------------------------------
+//
+void SingleInput::EnforceMaximumExtents()
+{
+ if ( PostProcessingFlags & FORCE_MAXIMUM_EXTENT ) {
+ // calculate scale factor for entire object
+ double fmext = getMaxExtents();
+ double mext = m_maximumextents.getX();
+ if ( m_maximumextents.getY() > mext ) mext = m_maximumextents.getY();
+ if ( m_maximumextents.getZ() > mext ) mext = m_maximumextents.getZ();
+ double cfac = fmext / ( 2 * mext );
+ // scan all vertices and apply scale factor
+ VertexChunk& vtxlist = m_baseobject->getVertexList();
+ for ( int i = 0; i < vtxlist.getNumElements(); i++ ) {
+ vtxlist[ i ].setX( vtxlist[ i ].getX() * cfac );
+ vtxlist[ i ].setY( vtxlist[ i ].getY() * cfac );
+ vtxlist[ i ].setZ( vtxlist[ i ].getZ() * cfac );
+ }
+ // apply scale factor to separator planes and
+ // bounding boxes of bsp tree nodes
+ m_baseobject->getBSPTreeFlat().ApplyScaleFactor( cfac );
+ }
+}
+
+
+// print error message if error in object data-file ---------------------------
+//
+void SingleInput::ParseError( int section )
+{
+ sprintf( line, "%sin section %s (line %d)", parser_err_str,
+ GetSectionName( section ), m_parser_lineno );
+ ErrorMessage( line );
+ HandleCriticalError();
+}
+
+
+// read single integer parameter ----------------------------------------------
+//
+void SingleInput::ReadIntParameter( int& param, int lowbound )
+{
+ char *remptr;
+ int fno = strtol( m_scanptr, &remptr, 10 );
+ if ( ( *remptr != '\0' ) || ( fno < lowbound ) )
+ ParseError( m_section );
+ param = fno - lowbound;
+}
+
+
+// read single floating point parameter ---------------------------------------
+//
+void SingleInput::ReadFloatParameter( double& param )
+{
+ char *remptr;
+ param = strtod( m_scanptr, &remptr );
+ if ( *remptr != '\0' )
+ ParseError( m_section );
+}
+
+
+// read two adjacent double values --------------------------------------------
+//
+void SingleInput::ReadTwoDoubles( double& x, double& y )
+{
+ ReadFloatParameter( x );
+ if ( ( m_scanptr = strtok( NULL, ",/ \t\n\r" ) ) == NULL )
+ ParseError( m_section );
+ ReadFloatParameter( y );
+}
+
+
+// read three adjacent double values ------------------------------------------
+//
+void SingleInput::ReadThreeDoubles( double& x, double& y, double& z )
+{
+ ReadFloatParameter( x );
+ if ( ( m_scanptr = strtok( NULL, ",/ \t\n\r" ) ) == NULL )
+ ParseError( m_section );
+ ReadFloatParameter( y );
+ if ( ( m_scanptr = strtok( NULL, ",/ \t\n\r" ) ) == NULL )
+ ParseError( m_section );
+ ReadFloatParameter( z );
+}
+
+
+// read four adjacent double values -------------------------------------------
+//
+void SingleInput::ReadFourDoubles( double& x, double& y, double& z, double& d )
+{
+ ReadFloatParameter( x );
+ if ( ( m_scanptr = strtok( NULL, ",/ \t\n\r" ) ) == NULL )
+ ParseError( m_section );
+ ReadFloatParameter( y );
+ if ( ( m_scanptr = strtok( NULL, ",/ \t\n\r" ) ) == NULL )
+ ParseError( m_section );
+ ReadFloatParameter( z );
+ if ( ( m_scanptr = strtok( NULL, ",/ \t\n\r" ) ) == NULL )
+ ParseError( m_section );
+ ReadFloatParameter( d );
+}
+
+
+// read six adjacent double values --------------------------------------------
+//
+void SingleInput::ReadSixDoubles( Vertex3& v1, Vertex3& v2 )
+{
+ double rdoub;
+
+ ReadFloatParameter( rdoub );
+ v1.setX( rdoub );
+ if ( ( m_scanptr = strtok( NULL, ",/ \t\n\r" ) ) == NULL )
+ ParseError( m_section );
+ ReadFloatParameter( rdoub );
+ v1.setY( rdoub );
+ if ( ( m_scanptr = strtok( NULL, ",/ \t\n\r" ) ) == NULL )
+ ParseError( m_section );
+ ReadFloatParameter( rdoub );
+ v1.setZ( rdoub );
+
+ if ( ( m_scanptr = strtok( NULL, ",/ \t\n\r" ) ) == NULL )
+ ParseError( m_section );
+ ReadFloatParameter( rdoub );
+ v2.setX( rdoub );
+ if ( ( m_scanptr = strtok( NULL, ",/ \t\n\r" ) ) == NULL )
+ ParseError( m_section );
+ ReadFloatParameter( rdoub );
+ v2.setY( rdoub );
+ if ( ( m_scanptr = strtok( NULL, ",/ \t\n\r" ) ) == NULL )
+ ParseError( m_section );
+ ReadFloatParameter( rdoub );
+ v2.setZ( rdoub );
+}
+
+
+// read three vertices specified in x y z order -------------------------------
+//
+void SingleInput::ReadVertex()
+{
+ double x, y, z;
+ ReadThreeDoubles( x, y, z );
+
+ double absx = fabs( x );
+ double absy = fabs( y );
+ double absz = fabs( z );
+
+ double mx = ( absx > m_maximumextents.getX() ) ? absx : m_maximumextents.getX();
+ double my = ( absy > m_maximumextents.getY() ) ? absy : m_maximumextents.getY();
+ double mz = ( absz > m_maximumextents.getZ() ) ? absz : m_maximumextents.getZ();
+
+ m_maximumextents = Vertex3( mx, my, mz );
+ m_baseobject->getVertexList().AddVertex( Vertex3( x, y, z ) );
+}
+
+
+// read face normal from file -------------------------------------------------
+//
+void SingleInput::ReadFaceNormal( int& normalsread )
+{
+ // read normal coordinates
+ double x, y, z;
+ ReadThreeDoubles( x, y, z );
+
+ // build normal
+ Vector3 normal( x, y, z );
+
+ // insert face into facelist
+ FaceChunk& facelist = m_baseobject->getFaceList();
+ if ( facelist.getNumElements() > normalsread ) {
+ // do nothing if normal already valid
+ if ( !facelist[ normalsread ].NormalValid() ) {
+ // attach normal to existing face
+ facelist[ normalsread ].AttachNormal( normal );
+ }
+ } else {
+ // create face containing only normal info
+ Face tempface;
+ tempface.AttachNormal( normal );
+ tempface.setId( facelist.getNumElements() );
+ facelist.AddElement( tempface );
+ }
+ normalsread++;
+}
+
+
+// read vertex indexes comprising a face --------------------------------------
+//
+void SingleInput::ReadFace( int aod_read )
+{
+ // add new polygon to list
+ Polygon *poly = m_baseobject->getPolygonList().NewPolygon();
+
+ // if not aod format, set face id to "invalid"
+ if ( !aod_read )
+ poly->setFaceId( -1 );
+
+ // create vertexlist for this polygon
+ while ( m_scanptr != NULL ) {
+ if ( *m_scanptr == ';' )
+ break;
+ char *remptr;
+ int fno = strtol( m_scanptr, &remptr, 10 );
+ if ( ( *remptr != '\0') || ( fno < 1 ) )
+ ParseError( m_section );
+
+ // store vertex index (converted to 0-base)
+ m_baseobject->getPolygonList().AppendNewVIndx( fno - 1 );
+ m_scanptr = strtok( NULL, ",/ \t\n\r" );
+ }
+
+ // check if face is either triangle or quadrilateral
+ if ( aod_read && !getAllowNGonFlag() ) {
+ int vnum = m_baseobject->getPolygonList().getNumVertices();
+ if ( ( vnum < 3 ) || ( vnum > 4 ) ) {
+ sprintf( line, "%s[Face must be triangle or quadrilateral]: %d",
+ parser_err_str, m_baseobject->getPolygonList().getNumElements() );
+ ErrorMessage( line );
+ HandleCriticalError();
+ }
+ }
+}
+
+
+// read RGBA quadruplet for material ------------------------------------------
+//
+void SingleInput::ReadMaterialRGBA( ColorRGBA &col, int indx )
+{
+ double c_r, c_g, c_b, c_a;
+ if ( strcmp( m_scanptr, Face::material_strings[ indx ] ) != 0 )
+ ParseError( m_section );
+ if ( ( m_scanptr = strtok( NULL, ",/ \t\n\r" ) ) == NULL )
+ ParseError( m_section );
+ ReadFourDoubles( c_r, c_g, c_b, c_a );
+ if ( ( m_scanptr = strtok( NULL, ",/ \t\n\r" ) ) == NULL )
+ ParseError( m_section );
+
+ col.R = (byte)( c_r * 255 );
+ col.G = (byte)( c_g * 255 );
+ col.B = (byte)( c_b * 255 );
+ col.A = (byte)( c_a * 255 );
+}
+
+
+// read material properties of a face -----------------------------------------
+//
+void SingleInput::ReadFaceProperties( int& facepropsread )
+{
+ // face to create
+ Face tempface;
+
+ // convert shading type string to type id
+ int shadingtypeid = tempface.GetTypeIndex( m_scanptr );
+ if ( shadingtypeid < 0 ) {
+ sprintf( line, "%s[Undefined face-property]: %s (line %d)",
+ parser_err_str, m_scanptr, m_parser_lineno );
+ ErrorMessage( line );
+ HandleCriticalError();
+ }
+
+ // set shading type for face
+ tempface.setShadingType( shadingtypeid );
+
+ // read color if necessary for shading type
+ if ( shadingtypeid & Face::color_mask ) {
+ if ( ( m_scanptr = strtok( NULL, ",/ \t\n\r" ) ) == NULL )
+ ParseError( m_section );
+
+ // determine how color is specified
+ int readrgb = 0;
+ if ( isalpha( *m_scanptr ) ) {
+ int colormodel = tempface.GetColorModelIndex( m_scanptr );
+ switch ( colormodel ) {
+ case Face::rgb_col:
+ readrgb = 1;
+ break;
+ case Face::indexed_col:
+ readrgb = 0;
+ break;
+ case Face::material_col:
+ readrgb = 2;
+ break;
+ default:
+ ParseError( m_section );
+ }
+
+ if ( ( m_scanptr = strtok( NULL, ",/ \t\n\r" ) ) == NULL )
+ ParseError( m_section );
+ }
+
+ // read color in specified (detected) model
+ if ( readrgb == 1 ) {
+ // read (r,g,b) triplet
+ double col_r, col_g, col_b;
+ ReadThreeDoubles( col_r, col_g, col_b );
+ ColorRGBA rgba_col;
+ rgba_col.R = (byte) ( col_r * 255 );
+ rgba_col.G = (byte) ( col_g * 255 );
+ rgba_col.B = (byte) ( col_b * 255 );
+ rgba_col.A = 255;
+ tempface.setFaceColor( rgba_col );
+ } else if ( readrgb == 2 ) {
+ // read material specification
+ Material *mat = new Material;
+ ColorRGBA colquad;
+ ReadMaterialRGBA( colquad, 0 );
+ mat->setAmbientColor( colquad );
+ ReadMaterialRGBA( colquad, 1 );
+ mat->setDiffuseColor( colquad );
+ ReadMaterialRGBA( colquad, 2 );
+ mat->setSpecularColor( colquad );
+ ReadMaterialRGBA( colquad, 3 );
+ mat->setEmissiveColor( colquad );
+ if ( strcmp( m_scanptr, Face::material_strings[ 4 ] ) != 0 )
+ ParseError( m_section );
+ if ( ( m_scanptr = strtok( NULL, ",/ \t\n\r" ) ) == NULL )
+ ParseError( m_section );
+ double floatpara;
+ ReadFloatParameter( floatpara );
+ mat->setShininess( (float) floatpara );
+ if ( ( m_scanptr = strtok( NULL, ",/ \t\n\r" ) ) == NULL )
+ ParseError( m_section );
+ if ( strcmp( m_scanptr, Face::material_strings[ 5 ] ) != 0 )
+ ParseError( m_section );
+ if ( ( m_scanptr = strtok( NULL, ",/ \t\n\r" ) ) == NULL )
+ ParseError( m_section );
+ ReadFloatParameter( floatpara );
+ mat->setTransparency( (float) floatpara );
+ // attach material
+ tempface.AttachMaterial( mat );
+ } else {
+ // read color index
+ char *remptr;
+ int fno = strtol( m_scanptr, &remptr, 10 );
+ if ( *remptr != '\0' )
+ ParseError( m_section );
+ tempface.setFaceColor( fno );
+ }
+
+ }
+
+ // read texture name if necessary for shading type
+ if ( shadingtypeid & Face::texmap_mask ) {
+ while ( *m_scanptr++ != '\0' ) ;
+ while ( ( *m_scanptr == ' ' ) || ( *m_scanptr == '\t' ) )
+ m_scanptr++;
+ if ( ( m_scanptr = strtok( m_scanptr, "\"" ) ) == NULL )
+ ParseError( m_section );
+ tempface.setTextureName( m_scanptr );
+ }
+
+ // insert face into facelist
+ FaceChunk& facelist = m_baseobject->getFaceList();
+ if ( facelist.getNumElements() > facepropsread ) {
+ if ( facelist[ facepropsread ].NormalValid() ) {
+ // take over normal if one has already been calculated
+ Vector3 normal = facelist[ facepropsread ].getPlaneNormal();
+ tempface.AttachNormal( normal );
+ }
+ tempface.setId( facelist[ facepropsread ].getId() );
+ facelist[ facepropsread ] = tempface;
+ } else {
+ tempface.setId( facelist.getNumElements() );
+ facelist.AddElement( tempface );
+ }
+ facepropsread++;
+}
+
+
+// read vertex correspondences specifying a mapping ---------------------------
+//
+void SingleInput::ReadCorrespondences()
+{
+ Mapping tempmapping;
+
+ // read vertexindexes for this face mapping (one line!)
+ while ( m_scanptr != NULL ) {
+ if ( *m_scanptr == ';' )
+ break;
+ int vertexno;
+ ReadIntParameter( vertexno, 1 );
+ tempmapping.InsertFaceVertex( vertexno );
+ m_scanptr = strtok( NULL, ",/ \t\n\r" );
+ }
+
+ // read correspondences for all vertexindexes
+ // (each correspondence has to be specified on a separate line!)
+ for ( int k = 0; k < tempmapping.getNumVertices(); k++ ) {
+ if ( m_input.ReadLine( line, TEXTLINE_MAX ) == NULL )
+ ParseError( m_section );
+
+ ++m_parser_lineno;
+ if ( ( m_scanptr = strtok( line, ",/ \t\n\r" ) ) == NULL )
+ continue;
+
+ double u, v;
+ ReadTwoDoubles( u, v );
+ tempmapping.setMappingCoordinates( k, Vertex2( u, v ) );
+ }
+
+ m_baseobject->getMappingList().AddElement( tempmapping );
+}
+
+
+// read texture definitions ---------------------------------------------------
+//
+void SingleInput::ReadTextures()
+{
+ char *remptr;
+
+ int txwidth = strtol( m_scanptr, &remptr, 10 );
+ if ( *remptr != '\0' ) ParseError( m_section );
+
+ if ( ( m_scanptr = strtok( NULL, ",/ \t\n\r" ) ) == NULL )
+ ParseError( m_section );
+
+ int txheight = strtol( m_scanptr, &remptr, 10 );
+ if ( *remptr != '\0' ) ParseError( m_section );
+
+ Texture temptex( txwidth, txheight );
+
+ while ( *m_scanptr++ != '\0' ) ;
+ while ( ( *m_scanptr == ' ' ) || ( *m_scanptr == '\t' ) )
+ m_scanptr++;
+ if ( ( m_scanptr = strtok( m_scanptr, "\"" ) ) == NULL )
+ ParseError( m_section );
+ temptex.setName( m_scanptr );
+
+ if ( ( m_scanptr = strtok( NULL, ",/ \t\n\r" ) ) == NULL )
+ ParseError( m_section );
+ temptex.setFile( m_scanptr );
+
+ m_baseobject->getTextureList().AddElement( temptex );
+}
+
+
+// read initial world location for viewer -------------------------------------
+//
+void SingleInput::ReadWorldLocation()
+{
+ if ( worldlocation_set++ )
+ ParseError( m_section );
+ int i = 0;
+ while ( m_scanptr != NULL ) {
+ if ( *m_scanptr == ';' )
+ break;
+ if ( i > 15 ) // read 16 matrix elements
+ ParseError( m_section );
+ double fval;
+ ReadFloatParameter( fval );
+ wm[ i++ ] = fval;
+ m_scanptr = strtok( NULL, ",/ \t\n\r" );
+ }
+ if ( i != 16 )
+ ParseError( m_section );
+}
+
+
+// read initial camera location for viewer ------------------------------------
+//
+void SingleInput::ReadCameraLocation()
+{
+ if ( camera_set++ )
+ ParseError( m_section );
+ int i = 0;
+ while ( m_scanptr != NULL ) {
+ if ( *m_scanptr == ';' )
+ break;
+ if ( i > 15 ) // read 16 matrix elements
+ ParseError( m_section );
+ double fval;
+ ReadFloatParameter( fval );
+ vm[ i++ ] = fval;
+ m_scanptr = strtok( NULL, ",/ \t\n\r" );
+ }
+ if ( i != 16 )
+ ParseError( m_section );
+}
+
+
+// read filename of palette data ----------------------------------------------
+//
+void SingleInput::ReadPaletteFilename()
+{
+ if ( m_palette_fname != NULL )
+ ParseError( m_section );
+ m_palette_fname = new char[ strlen( m_scanptr ) + 1 ];
+ strcpy( m_palette_fname, m_scanptr );
+}
+
+
+// read object scale factors --------------------------------------------------
+//
+void SingleInput::ReadScaleFactors()
+{
+ if ( scalefactors_set++ )
+ ParseError( m_section );
+ ReadThreeDoubles( ObjScaleX, ObjScaleY, ObjScaleZ );
+}
+
+
+// read axes exchange command -------------------------------------------------
+//
+void SingleInput::ReadXChangeCommand()
+{
+ if ( xchange_set++ )
+ ParseError( m_section );
+ if ( strlen( m_scanptr ) > 3 )
+ ParseError( m_section );
+ strcpy( xchangecmd, m_scanptr );
+}
+
+
+// read origin translation ----------------------------------------------------
+//
+void SingleInput::ReadOrigin()
+{
+ if ( setorigin_set++ )
+ ParseError( m_section );
+ ReadThreeDoubles( NewOriginX, NewOriginY, NewOriginZ );
+ NewOriginX += PREMOVEORIGIN_X;
+ NewOriginY += PREMOVEORIGIN_Y;
+ NewOriginZ += PREMOVEORIGIN_Z;
+}
+
+
+// every PARSER_DOT_SIZE + 1 parsed lines a dot is printed (bitmask!!) --------
+//
+const int SingleInput::PARSER_DOT_SIZE = 0x1f;
+
+
+BSPLIB_NAMESPACE_END
+
+//-----------------------------------------------------------------------------
diff --git a/tool_src/BspLib/SingleInput.h b/tool_src/BspLib/SingleInput.h
new file mode 100644
index 0000000..41e4218
--- /dev/null
+++ b/tool_src/BspLib/SingleInput.h
@@ -0,0 +1,83 @@
+//-----------------------------------------------------------------------------
+// BSPLIB HEADER: SingleInput.h
+//
+// Copyright (c) 1997-1998 by Markus Hadwiger
+// All Rights Reserved.
+//-----------------------------------------------------------------------------
+
+#ifndef _SINGLEINPUT_H_
+#define _SINGLEINPUT_H_
+
+// bsplib header files
+#include "BspLibDefs.h"
+#include "BspObject.h"
+#include "InputData3D.h"
+#include "SingleFormat.h"
+
+
+BSPLIB_NAMESPACE_BEGIN
+
+
+// class providing single format type input capability ------------------------
+//
+class SingleInput : public InputData3D, public virtual SingleFormat {
+
+ friend class AodOutput;
+ friend class BspOutput;
+
+protected:
+ SingleInput( BspObjectList objectlist, const char *filename );
+ ~SingleInput();
+
+protected:
+ int ConvertColIndxs();
+ void ApplyOriginTranslation();
+ void FilterAxesDirSwitch();
+ void FilterScaleFactors();
+ void FilterAxesExchange();
+ void EnforceMaximumExtents();
+
+ virtual void ParseError( int section );
+ void ReadIntParameter( int& param, int lowbound );
+ void ReadFloatParameter( double& param );
+ void ReadTwoDoubles( double& x, double& y );
+ void ReadThreeDoubles( double& x, double& y, double& z );
+ void ReadFourDoubles( double& x, double& y, double& z, double& d );
+ void ReadSixDoubles( Vertex3& v1, Vertex3& v2 );
+
+ void ReadVertex();
+ void ReadFaceNormal( int& normalsread );
+ void ReadFace( int aod_read );
+ void ReadFaceProperties( int& facepropsread );
+ void ReadCorrespondences();
+ void ReadTextures();
+ void ReadWorldLocation();
+ void ReadCameraLocation();
+ void ReadPaletteFilename();
+ void ReadScaleFactors();
+ void ReadXChangeCommand();
+ void ReadOrigin();
+
+private:
+ void ReadMaterialRGBA( ColorRGBA &col, int indx );
+
+protected:
+ static const int PARSER_DOT_SIZE;
+
+protected:
+ BspObject* m_baseobject;
+ FileAccess m_input;
+
+ char* m_scanptr;
+ int m_section;
+ int m_parser_lineno;
+
+ Vertex3 m_maximumextents;
+};
+
+
+BSPLIB_NAMESPACE_END
+
+
+#endif // _SINGLEINPUT_H_
+
diff --git a/tool_src/BspLib/SingleOutput.cpp b/tool_src/BspLib/SingleOutput.cpp
new file mode 100644
index 0000000..0c0aa52
--- /dev/null
+++ b/tool_src/BspLib/SingleOutput.cpp
@@ -0,0 +1,125 @@
+//-----------------------------------------------------------------------------
+// BSPLIB MODULE: SingleOutput.cpp
+//
+// Copyright (c) 1997-1998 by Markus Hadwiger
+// All Rights Reserved.
+//-----------------------------------------------------------------------------
+
+// bsplib header files
+#include "SingleOutput.h"
+#include "BspObject.h"
+#include "BspTool.h"
+
+
+BSPLIB_NAMESPACE_BEGIN
+
+
+// construct SingleOutput object ----------------------------------------------
+//
+SingleOutput::SingleOutput( BspObjectList objectlist, const char *filename ) :
+ OutputData3D( objectlist, filename, DONT_CREATE_OBJECT ),
+ m_baseobject( objectlist.getListHead() ),
+ m_output( filename, "w" )
+{
+}
+
+
+// destroy SingleOutput object ------------------------------------------------
+//
+SingleOutput::~SingleOutput()
+{
+}
+
+
+// assignment copies only the SingleFormat part of the object -----------------
+//
+SingleOutput& SingleOutput::operator =( const SingleOutput& copyobj )
+{
+ *(SingleFormat *)this = copyobj;
+ return *this;
+}
+
+
+// write bsplib banner to file and init output data ---------------------------
+//
+void SingleOutput::InitOutput()
+{
+ String filename = BspTool::SkipPath( m_filename );
+
+ // write file's name
+ sprintf( line, "; %s ----------------------------------------------\n",
+ (const char *) filename );
+ m_output.WriteLine( line );
+
+ // write banner
+ sprintf( line, "; automatically created by BspLib V%s\n", version_str );
+ m_output.WriteLine( line );
+ m_output.WriteLine( "; Copyright (c) by Markus Hadwiger 1996-1998\n\n" );
+
+ // ensure correctness of attribute counts
+ m_baseobject->UpdateAttributeNumbers();
+}
+
+
+// write single format part of file for this object ---------------------------
+//
+int SingleOutput::WriteOutputFile()
+{
+
+#define sprintf m_output.WriteLine( line ); sprintf
+
+#ifndef SHORT_OUTPUT_FORMAT
+
+ strcpy( line, "\n" );
+
+ if ( m_palette_fname ) {
+ sprintf( line, "; name of palette file ---------------------------------------------------\n" );
+ sprintf( line, "%s\n", _palette_str );
+ sprintf( line, "%s\n", (const char *) m_palette_fname );
+ sprintf( line, "\n" );
+ }
+
+ sprintf( line, "; scale factors for each axis --------------------------------------------\n" );
+ sprintf( line, "%s\n", _scalefactors_str );
+ sprintf( line, "%f, %f, %f\n", ObjScaleX, ObjScaleY, ObjScaleZ );
+ sprintf( line, "\n" );
+
+ sprintf( line, "; translation of origin --------------------------------------------------\n" );
+ sprintf( line, "%s\n", _setorigin_str );
+ sprintf( line, "%f, %f, %f\n", NewOriginX, NewOriginY, NewOriginZ );
+ sprintf( line, "\n" );
+
+ sprintf( line, "; exchange command for axes ----------------------------------------------\n" );
+ sprintf( line, "%s\n", _xchange_str );
+ sprintf( line, "%s\n", xchangecmd );
+ sprintf( line, "\n" );
+
+ sprintf( line, "; starting object location in objectviewer -------------------------------\n" );
+ sprintf( line, "%s\n", _worldlocation_str );
+ int i = 0;
+ for ( i = 0; i < 15; i++ ) {
+ sprintf( line, "%f, ", wm[ i ] );
+ }
+ sprintf( line, "%f\n", wm[ 15 ] );
+ sprintf( line, "\n" );
+
+ sprintf( line, "; starting camera location in objectviewer -------------------------------\n" );
+ sprintf( line, "%s\n", _camera_str );
+ for ( i = 0; i < 15; i++ ) {
+ sprintf( line, "%f, ", vm[ i ] );
+ }
+ sprintf( line, "%f\n", vm[ 15 ] );
+ sprintf( line, "\n" );
+
+#endif
+
+ sprintf( line, "<end-of-file ------------------------------------------------------------------>\n" );
+ m_output.WriteLine( line );
+
+ return m_output.Status();
+}
+
+
+BSPLIB_NAMESPACE_END
+
+//-----------------------------------------------------------------------------
diff --git a/tool_src/BspLib/SingleOutput.h b/tool_src/BspLib/SingleOutput.h
new file mode 100644
index 0000000..4296c42
--- /dev/null
+++ b/tool_src/BspLib/SingleOutput.h
@@ -0,0 +1,44 @@
+//-----------------------------------------------------------------------------
+// BSPLIB HEADER: SingleOutput.h
+//
+// Copyright (c) 1997 by Markus Hadwiger
+// All Rights Reserved.
+//-----------------------------------------------------------------------------
+
+#ifndef _SINGLEOUTPUT_H_
+#define _SINGLEOUTPUT_H_
+
+// bsplib header files
+#include "BspLibDefs.h"
+#include "BspObject.h"
+#include "OutputData3D.h"
+#include "SingleFormat.h"
+
+
+BSPLIB_NAMESPACE_BEGIN
+
+
+// class providing single format type output capability -----------------------
+//
+class SingleOutput : public OutputData3D, public virtual SingleFormat {
+
+protected:
+ SingleOutput( BspObjectList objectlist, const char *filename );
+ ~SingleOutput();
+
+ SingleOutput& operator =( const SingleOutput& copyobj );
+
+ void InitOutput();
+ virtual int WriteOutputFile();
+
+protected:
+ BspObject* m_baseobject;
+ FileAccess m_output;
+};
+
+
+BSPLIB_NAMESPACE_END
+
+
+#endif // _SINGLEOUTPUT_H_
+
diff --git a/tool_src/BspLib/SystemIO.cpp b/tool_src/BspLib/SystemIO.cpp
new file mode 100644
index 0000000..f5e1be6
--- /dev/null
+++ b/tool_src/BspLib/SystemIO.cpp
@@ -0,0 +1,314 @@
+//-----------------------------------------------------------------------------
+// BSPLIB MODULE: SystemIO.cpp
+//
+// Copyright (c) 1997-1998 by Markus Hadwiger
+// All Rights Reserved.
+//-----------------------------------------------------------------------------
+
+// bsplib header files
+#include "SystemIO.h"
+
+
+BSPLIB_NAMESPACE_BEGIN
+
+
+// define bsplib version string -----------------------------------------------
+//
+#define BSPLIB_VERSION "1.48"
+
+
+// set program's name which is an optional part of error messages -------------
+//
+void SystemIO::SetProgramName( const char *name )
+{
+ program_name = name;
+}
+
+
+// set callback for info message output function ------------------------------
+//
+void SystemIO::SetInfoMessageCallback( void (*callb)(const char*) )
+{
+ infomessage_callback = callb;
+}
+
+
+// set callback for error message output function -----------------------------
+//
+void SystemIO::SetErrorMessageCallback( void (*callb)(const char*) )
+{
+ errormessage_callback = callb;
+}
+
+
+// set callback for critical error handler ------------------------------------
+//
+void SystemIO::SetCriticalErrorCallback( int (*callb)(int) )
+{
+ criticalerror_callback = callb;
+}
+
+
+// display informational message (system dependent code encapsulated here) ----
+//
+void SystemIO::InfoMessage( const char *message )
+{
+ if ( infomessage_callback != NULL ) {
+ // call user supplied handler function
+ infomessage_callback( message );
+
+ } else {
+
+#if defined( _WINDOWS ) || defined( WIN32 )
+ MessageBox( hwnd_main, message, "BspLib Info", MB_OK | MB_ICONINFORMATION );
+#else
+ printf( "%s", message );
+ fflush( stdout );
+#endif
+
+ }
+}
+
+
+// display error message (system dependent code encapsulated here) ------------
+//
+void SystemIO::ErrorMessage( const char *message )
+{
+ if ( errormessage_callback != NULL ) {
+ // call user supplied handler function
+ errormessage_callback( message );
+
+ } else {
+
+#if defined( _WINDOWS ) || defined( WIN32 )
+ MessageBox( hwnd_main, message, "BspLib Error", MB_OK | MB_ICONERROR );
+#else
+ fflush( stdout );
+ fprintf( stderr, "%s: %s\n", program_name, message );
+ fflush( stderr );
+#endif
+
+ }
+}
+
+
+// reaction to critical error -------------------------------------------------
+//
+void SystemIO::HandleCriticalError( int flags )
+{
+ int handled = 0;
+ if ( criticalerror_callback != NULL ) {
+ // give user a chance to handle critical error
+ handled = criticalerror_callback( flags );
+ }
+ // if user failed to handle error exit from program
+ if ( !handled || ( ( flags & CRITERR_ALLOW_RET ) == 0 ) )
+ exit( EXIT_FAILURE );
+}
+
+
+// open file via FileAccess (resource acquisition is initialization) ----------
+//
+SystemIO::FileAccess::FileAccess( const char *fname, const char *mode, int flags )
+ : SystemIO::FilePtr( fname, mode )
+{
+ filename = new char[ strlen( fname ) + 1 ];
+ strcpy( filename, fname );
+
+ status = ( fp != NULL ) ? SYSTEM_IO_OK : FILE_NOT_FOUND;
+
+ if ( ( flags & CHECK_ERRORS ) && ( status != SYSTEM_IO_OK ) )
+ IOError( status );
+}
+
+
+// close FileAccess (resource acquisition is initialization) ------------------
+//
+SystemIO::FileAccess::~FileAccess()
+{
+ delete filename;
+}
+
+
+// reopen file ----------------------------------------------------------------
+//
+int SystemIO::FileAccess::ReOpen( const char *fname, const char *mode, int flags )
+{
+ if ( status == FILE_CLOSED ) {
+ status = ( fopen( fname, mode ) != NULL ) ? SYSTEM_IO_OK : FILE_NOT_FOUND;
+
+ if ( ( flags & CHECK_ERRORS ) && ( status != SYSTEM_IO_OK ) )
+ IOError( status );
+ return status;
+ } else {
+ return FILE_ALREADY_OPEN;
+ }
+}
+
+
+// close file -----------------------------------------------------------------
+//
+int SystemIO::FileAccess::Close()
+{
+ status = ( fclose( fp ) == 0 ) ? FILE_CLOSED : SYSTEM_IO_ERROR;
+ return ( status == FILE_CLOSED );
+}
+
+
+// read from file -------------------------------------------------------------
+//
+int SystemIO::FileAccess::Read( void *buffer, size_t size, size_t count, int flags )
+{
+ if ( status == SYSTEM_IO_OK ) {
+ if ( fread( buffer, size, count, fp ) == count )
+ status = SYSTEM_IO_OK;
+ else
+ status = feof( fp ) ? END_OF_FILE : FILE_READ_ERROR;
+
+ if ( ( flags & CHECK_ERRORS ) && ( status != SYSTEM_IO_OK ) )
+ IOError( status );
+ } else {
+ if ( flags & CHECK_ERRORS ) IOError( status );
+ }
+
+ return status;
+}
+
+
+// write to file --------------------------------------------------------------
+//
+int SystemIO::FileAccess::Write( void *buffer, size_t size, size_t count, int flags )
+{
+ if ( status == SYSTEM_IO_OK ) {
+ status = ( fwrite( buffer, size, count, fp ) == count ) ? SYSTEM_IO_OK : FILE_WRITE_ERROR;
+
+ if ( ( flags & CHECK_ERRORS ) && ( status != SYSTEM_IO_OK ) )
+ IOError( status );
+ } else {
+ if ( flags & CHECK_ERRORS ) IOError( status );
+ }
+
+ return status;
+}
+
+
+// read text line from file ---------------------------------------------------
+//
+char *SystemIO::FileAccess::ReadLine( char *line, int maxlen, int flags )
+{
+ if ( status == SYSTEM_IO_OK ) {
+ if ( fgets( line, maxlen, fp ) != NULL )
+ status = SYSTEM_IO_OK;
+ else
+ status = feof( fp ) ? END_OF_FILE : FILE_READ_ERROR;
+
+ if ( ( flags & CHECK_ERRORS ) && ( status != SYSTEM_IO_OK ) )
+ IOError( status );
+ return ( status == SYSTEM_IO_OK ) ? line : NULL;
+ } else {
+ if ( flags & CHECK_ERRORS ) IOError( status );
+ return NULL;
+ }
+}
+
+
+// write text line to file ----------------------------------------------------
+//
+const char *SystemIO::FileAccess::WriteLine( const char *line, int flags )
+{
+ if ( status == SYSTEM_IO_OK ) {
+ status = ( fprintf( fp, "%s", line ) != -1 ) ? SYSTEM_IO_OK : FILE_WRITE_ERROR;
+
+ if ( ( flags & CHECK_ERRORS ) && ( status != SYSTEM_IO_OK ) )
+ IOError( status );
+ return ( status == SYSTEM_IO_OK ) ? line : NULL;
+ } else {
+ if ( flags & CHECK_ERRORS ) IOError( status );
+ return NULL;
+ }
+}
+
+
+// I/O error handler ----------------------------------------------------------
+//
+void SystemIO::FileAccess::IOError( int errorcode )
+{
+ {
+ StrScratch errtext;
+ sprintf( errtext, "%s: %s", filename, strerror( errno ) );
+ ErrorMessage( errtext );
+ }
+ HandleCriticalError();
+}
+
+
+// construct String with init string ------------------------------------------
+//
+String::String( const char *src )
+{
+ if ( src != NULL ) {
+ data = new char[ strlen( src ) + 1 ];
+ strcpy( data, src );
+ } else {
+ data = NULL;
+ }
+}
+
+
+// copy constructor for String ------------------------------------------------
+//
+String::String( const String& copyobj )
+{
+ if ( copyobj.data != NULL ) {
+ data = new char[ strlen( copyobj.data ) + 1 ];
+ strcpy( data, copyobj.data );
+ } else {
+ data = NULL;
+ }
+}
+
+
+// assignment operator for String ---------------------------------------------
+//
+String& String::operator =( const String& copyobj )
+{
+ if ( &copyobj != this ) {
+ delete data;
+ if ( copyobj.data != NULL ) {
+ data = new char[ strlen( copyobj.data ) + 1 ];
+ strcpy( data, copyobj.data );
+ } else {
+ data = NULL;
+ }
+ }
+ return *this;
+}
+
+
+// pointer to global string containing the program's name ---------------------
+//
+const char *SystemIO::program_name = NULL;
+
+
+// pointers to user supplied callback functions -------------------------------
+//
+void (*SystemIO::infomessage_callback)(const char*) = NULL;
+void (*SystemIO::errormessage_callback)(const char*) = NULL;
+int (*SystemIO::criticalerror_callback)(int) = NULL;
+
+
+// handle of main window (used only when system is Win32) ---------------------
+//
+#if defined( _WINDOWS ) || defined( WIN32 )
+HWND SystemIO::hwnd_main = NULL;
+#endif
+
+
+// bsplib version string ------------------------------------------------------
+//
+const char SystemIO::version_str[] = BSPLIB_VERSION;
+
+
+BSPLIB_NAMESPACE_END
+
+//-----------------------------------------------------------------------------
diff --git a/tool_src/BspLib/SystemIO.h b/tool_src/BspLib/SystemIO.h
new file mode 100644
index 0000000..536ebf9
--- /dev/null
+++ b/tool_src/BspLib/SystemIO.h
@@ -0,0 +1,172 @@
+//-----------------------------------------------------------------------------
+// BSPLIB HEADER: SystemIO.h
+//
+// Copyright (c) 1997-1998 by Markus Hadwiger
+// All Rights Reserved.
+//-----------------------------------------------------------------------------
+
+#ifndef _SYSTEMIO_H_
+#define _SYSTEMIO_H_
+
+// bsplib header files
+#include "BspLibDefs.h"
+
+// windows header files
+#if defined( _WINDOWS ) || defined( WIN32 )
+#include "windows.h"
+#endif
+
+
+BSPLIB_NAMESPACE_BEGIN
+
+
+// system specific I/O class; virtual base of all I/O capable classes ---------
+//
+class SystemIO {
+
+public:
+
+ // possible status codes
+ enum {
+ SYSTEM_IO_OK = 0x0000,
+ SYSTEM_IO_ERROR = 0x0001,
+ END_OF_FILE = 0x0002,
+ FILE_NOT_FOUND = 0x0003,
+ FILE_READ_ERROR = 0x0004,
+ FILE_WRITE_ERROR = 0x0005,
+ FILE_CLOSED = 0x0006,
+ FILE_ALREADY_OPEN = 0x0007,
+ };
+
+ // error action flags for critical error handling
+ enum {
+ CRITERR_ALLOW_RET = 0x0001,
+ };
+
+ // error action flags for file access
+ enum {
+ CHECK_ERRORS = 0x0001,
+ };
+
+public:
+ static void InfoMessage( const char *message );
+ static void ErrorMessage( const char *message );
+ static void HandleCriticalError( int flags = 0 );
+ static void SetProgramName( const char *name );
+ static void SetInfoMessageCallback( void (*callb)(const char*) );
+ static void SetErrorMessageCallback( void (*callb)(const char*) );
+ static void SetCriticalErrorCallback( int (*callb)(int) );
+
+#if defined( _WINDOWS ) || defined( WIN32 )
+ static void SetMainWindowHandle( HWND hwnd ) { hwnd_main = hwnd; }
+#endif
+
+public:
+ static const char version_str[];
+
+private:
+ static const char *program_name;
+ static void (*infomessage_callback)(const char*);
+ static void (*errormessage_callback)(const char*);
+ static int (*criticalerror_callback)(int);
+
+#if defined( _WINDOWS ) || defined( WIN32 )
+ static HWND hwnd_main;
+#endif
+
+
+protected:
+
+
+// file ptr class supporting "resource acquisition is initialization" ----
+class FilePtr {
+
+public:
+ FilePtr( const char *fname, const char *mode ) { fp = fopen( fname, mode ); }
+ ~FilePtr() { if ( fp ) fclose( fp ); }
+
+ operator FILE*() { return fp; }
+
+protected:
+ FILE *fp;
+
+}; // class SystemIO::FilePtr
+
+
+// augmented FilePtr -----------------------------------------------------
+class FileAccess : public FilePtr {
+
+public:
+ FileAccess( const char *fname, const char *mode, int flags = CHECK_ERRORS );
+ ~FileAccess();
+
+ int ReOpen( const char *fname, const char *mode, int flags = CHECK_ERRORS );
+ int Close();
+
+ int Read( void *buffer, size_t size, size_t count, int flags = 0 );
+ int Write( void *buffer, size_t size, size_t count, int flags = 0 );
+
+ char *ReadLine( char *line, int maxlen, int flags = 0 );
+ const char *WriteLine( const char *line, int flags = 0 );
+
+ int Status() { return status; }
+
+ char *getFileName() { return filename; }
+
+private:
+ void IOError( int errorcode );
+
+private:
+ char *filename;
+ int status;
+
+}; // class SystemIO::FileAccess
+
+
+// string scratch pad ----------------------------------------------------
+class StrScratch {
+
+public:
+ StrScratch() { line = new char[ 1024 ]; }
+ ~StrScratch() { delete line; }
+
+ operator char*() { return line; }
+
+private:
+ char *line;
+
+}; // class SystemIO::StrScratch
+
+
+}; // class SystemIO
+
+
+// quick and dirty string class -----------------------------------------------
+//
+class String {
+
+public:
+ String() { data = NULL; }
+ String( const char *src );
+ ~String() { delete data; }
+
+ String( const String& copyobj );
+ String& operator =( const String& copyobj );
+
+ operator char*() { return data; }
+
+ int IsNULL() const { return ( data == NULL ); }
+ int IsEmpty() const { return data ? ( *data == '\0' ) : TRUE; }
+
+ int getLength() const { return data ? strlen( data ) : 0; }
+
+private:
+ char *data;
+};
+
+
+BSPLIB_NAMESPACE_END
+
+
+#endif // _SYSTEMIO_H_
+
diff --git a/tool_src/BspLib/Texture.cpp b/tool_src/BspLib/Texture.cpp
new file mode 100644
index 0000000..16fc494
--- /dev/null
+++ b/tool_src/BspLib/Texture.cpp
@@ -0,0 +1,77 @@
+//-----------------------------------------------------------------------------
+// BSPLIB MODULE: Texture.cpp
+//
+// Copyright (c) 1996-1997 by Markus Hadwiger
+// All Rights Reserved.
+//-----------------------------------------------------------------------------
+
+// bsplib headers
+#include "Texture.h"
+#include "Chunk.h"
+
+
+BSPLIB_NAMESPACE_BEGIN
+
+
+// write texture information to text file -------------------------------------
+//
+void Texture::WriteInfo( FILE *fp )
+{
+ fprintf( fp, "%d/%d\t\t\"%s\"\t\t%s\n", m_width, m_height, m_name, m_file );
+}
+
+
+// constructor for Texture ----------------------------------------------------
+//
+Texture::Texture( int w, int h, char *tname, char *fname )
+{
+ *m_name = 0;
+ *m_file = 0;
+
+ if ( tname != NULL ) {
+ setName( tname );
+ }
+
+ if ( fname != NULL ) {
+ setFile( fname );
+ }
+
+ m_width = w;
+ m_height = h;
+}
+
+
+// set name of texture --------------------------------------------------------
+//
+void Texture::setName( const char *tname )
+{
+ if ( tname != NULL ) {
+ strncpy( m_name, tname, MAX_TEXNAME );
+ m_name[ MAX_TEXNAME ] = 0;
+ } else {
+ *m_name = 0;
+ }
+}
+
+
+// set filename of texture data file ------------------------------------------
+//
+void Texture::setFile( const char *fname )
+{
+ if ( fname != NULL ) {
+ strncpy( m_file, fname, PATH_MAX );
+ m_file[ PATH_MAX ] = 0;
+ } else {
+ *m_file = 0;
+ }
+}
+
+
+// size of texture chunk ------------------------------------------------------
+//
+template <> const int ChunkRep<Texture>::CHUNK_SIZE = 128;
+
+
+BSPLIB_NAMESPACE_END
+
+//-----------------------------------------------------------------------------
diff --git a/tool_src/BspLib/Texture.h b/tool_src/BspLib/Texture.h
new file mode 100644
index 0000000..cbea4fe
--- /dev/null
+++ b/tool_src/BspLib/Texture.h
@@ -0,0 +1,58 @@
+//-----------------------------------------------------------------------------
+// BSPLIB HEADER: Texture.h
+//
+// Copyright (c) 1996-1997 by Markus Hadwiger
+// All Rights Reserved.
+//-----------------------------------------------------------------------------
+
+#ifndef _TEXTURE_H_
+#define _TEXTURE_H_
+
+// bsplib header files
+#include "BspLibDefs.h"
+#include "Chunk.h"
+#include "SystemIO.h"
+
+
+BSPLIB_NAMESPACE_BEGIN
+
+
+#define MAX_TEXNAME 31
+
+
+// class Texture; file oriented, only used for descriptive purposes -----------
+//
+class Texture : public virtual SystemIO {
+
+public:
+ Texture( int w = -1, int h = -1, char *tname = NULL, char *fname = NULL );
+ ~Texture() { }
+
+ int getWidth() const { return m_width; }
+ int getHeight() const { return m_height; }
+ const char* getName() const { return m_name; }
+ const char* getFile() const { return m_file; }
+
+ void setWidth( int w ) { m_width = w; }
+ void setHeight( int h ) { m_height = h; }
+ void setName( const char *tname );
+ void setFile( const char *fname );
+
+ void WriteInfo( FILE *fp );
+
+private:
+ int m_width;
+ int m_height;
+ char m_name[ MAX_TEXNAME + 1 ];
+ char m_file[ PATH_MAX + 1 ];
+};
+
+// typedef chunk of textures --------------------------------------------------
+typedef Chunk<Texture> TextureChunk;
+
+
+BSPLIB_NAMESPACE_END
+
+
+#endif // _TEXTURE_H_
+
diff --git a/tool_src/BspLib/Transform2.cpp b/tool_src/BspLib/Transform2.cpp
new file mode 100644
index 0000000..5d6a48b
--- /dev/null
+++ b/tool_src/BspLib/Transform2.cpp
@@ -0,0 +1,282 @@
+//-----------------------------------------------------------------------------
+// BSPLIB MODULE: Transform2.cpp
+//
+// Copyright (c) 1997-1998 by Markus Hadwiger
+// All Rights Reserved.
+//-----------------------------------------------------------------------------
+
+// bsplib headers
+#include "Transform2.h"
+
+
+BSPLIB_NAMESPACE_BEGIN
+
+
+// multiply two 3x3 matrices --------------------------------------------------
+//
+PRIVATE
+void mat3x3_mul( double dest_matrix[][3], const double matrix1[][3], const double matrix2[][3] )
+{
+ //NOTE:
+ // full homogeneous multiplication is performed. (that is, all 9
+ // elements are calculated.) normally this isn't necessary as
+ // most matrices are affine. but since this is no real-time
+ // application more flexibility seems better.
+/*
+ for ( int i = 0; i < 3; i++ ) {
+ for ( int j = 0; j < 3; j++ ) {
+ dest_matrix[ i ][ j ] = 0.0;
+ for ( int k = 0; k < 3; k++ )
+ dest_matrix[ i ][ j ] += matrix1[ i ][ k ] * matrix2[ k ][ j ];
+ }
+ }
+*/
+ dest_matrix[ 0 ][ 0 ] = matrix1[ 0 ][ 0 ] * matrix2[ 0 ][ 0 ] +
+ matrix1[ 0 ][ 1 ] * matrix2[ 1 ][ 0 ] +
+ matrix1[ 0 ][ 2 ] * matrix2[ 2 ][ 0 ];
+ dest_matrix[ 0 ][ 1 ] = matrix1[ 0 ][ 0 ] * matrix2[ 0 ][ 1 ] +
+ matrix1[ 0 ][ 1 ] * matrix2[ 1 ][ 1 ] +
+ matrix1[ 0 ][ 2 ] * matrix2[ 2 ][ 1 ];
+ dest_matrix[ 0 ][ 2 ] = matrix1[ 0 ][ 0 ] * matrix2[ 0 ][ 2 ] +
+ matrix1[ 0 ][ 1 ] * matrix2[ 1 ][ 2 ] +
+ matrix1[ 0 ][ 2 ] * matrix2[ 2 ][ 2 ];
+
+ dest_matrix[ 1 ][ 0 ] = matrix1[ 1 ][ 0 ] * matrix2[ 0 ][ 0 ] +
+ matrix1[ 1 ][ 1 ] * matrix2[ 1 ][ 0 ] +
+ matrix1[ 1 ][ 2 ] * matrix2[ 2 ][ 0 ];
+ dest_matrix[ 1 ][ 1 ] = matrix1[ 1 ][ 0 ] * matrix2[ 0 ][ 1 ] +
+ matrix1[ 1 ][ 1 ] * matrix2[ 1 ][ 1 ] +
+ matrix1[ 1 ][ 2 ] * matrix2[ 2 ][ 1 ];
+ dest_matrix[ 1 ][ 2 ] = matrix1[ 1 ][ 0 ] * matrix2[ 0 ][ 2 ] +
+ matrix1[ 1 ][ 1 ] * matrix2[ 1 ][ 2 ] +
+ matrix1[ 1 ][ 2 ] * matrix2[ 2 ][ 2 ];
+
+ dest_matrix[ 2 ][ 0 ] = matrix1[ 2 ][ 0 ] * matrix2[ 0 ][ 0 ] +
+ matrix1[ 2 ][ 1 ] * matrix2[ 1 ][ 0 ] +
+ matrix1[ 2 ][ 2 ] * matrix2[ 2 ][ 0 ];
+ dest_matrix[ 2 ][ 1 ] = matrix1[ 2 ][ 0 ] * matrix2[ 0 ][ 1 ] +
+ matrix1[ 2 ][ 1 ] * matrix2[ 1 ][ 1 ] +
+ matrix1[ 2 ][ 2 ] * matrix2[ 2 ][ 1 ];
+ dest_matrix[ 2 ][ 2 ] = matrix1[ 2 ][ 0 ] * matrix2[ 0 ][ 2 ] +
+ matrix1[ 2 ][ 1 ] * matrix2[ 1 ][ 2 ] +
+ matrix1[ 2 ][ 2 ] * matrix2[ 2 ][ 2 ];
+}
+
+
+// calculate concatenation; don't overwrite object matrix ---------------------
+//
+Transform2 operator *( const Transform2& trafo1, const Transform2& trafo2 )
+{
+ Transform2 temp;
+ mat3x3_mul( temp.m_matrix, trafo1.m_matrix, trafo2.m_matrix );
+ return temp;
+}
+
+
+// calculate concatenation as new object matrix -------------------------------
+//
+Transform2& Transform2::Concat( const Transform2& cattrafo )
+{
+ Transform2 temp;
+ mat3x3_mul( temp.m_matrix, (const double(*)[3]) m_matrix, cattrafo.m_matrix );
+ memcpy( m_matrix, temp.m_matrix, sizeof( m_matrix ) );
+ return *this;
+}
+
+
+// reversed concatenation -----------------------------------------------------
+//
+Transform2& Transform2::ConcatR( const Transform2& cattrafo )
+{
+ Transform2 temp;
+ mat3x3_mul( temp.m_matrix, cattrafo.m_matrix, (const double(*)[3]) m_matrix );
+ memcpy( m_matrix, temp.m_matrix, sizeof( m_matrix ) );
+ return *this;
+}
+
+
+// transform Vector2 by matrix (homogeneous component is also evaluated!) -----
+//
+Vector2 Transform2::TransformVector2( const Vector2& vec ) const
+{
+ Vector2 temp;
+ temp.setX( m_matrix[ 0 ][ 0 ] * vec.getX() + m_matrix[ 1 ][ 0 ] * vec.getY() + m_matrix[ 2 ][ 0 ] * vec.getW() );
+ temp.setY( m_matrix[ 0 ][ 1 ] * vec.getX() + m_matrix[ 1 ][ 1 ] * vec.getY() + m_matrix[ 2 ][ 1 ] * vec.getW() );
+ temp.setW( m_matrix[ 0 ][ 2 ] * vec.getX() + m_matrix[ 1 ][ 2 ] * vec.getY() + m_matrix[ 2 ][ 2 ] * vec.getW() );
+ return temp;
+}
+
+
+// calc determinant of matrix -------------------------------------------------
+//
+double Transform2::Determinant()
+{
+ // calc determinant using rule of sarrus
+ double pos;
+ pos = m_matrix[ 0 ][ 0 ] * m_matrix[ 1 ][ 1 ] * m_matrix[ 2 ][ 2 ];
+ pos += m_matrix[ 0 ][ 1 ] * m_matrix[ 1 ][ 2 ] * m_matrix[ 2 ][ 0 ];
+ pos += m_matrix[ 0 ][ 2 ] * m_matrix[ 1 ][ 0 ] * m_matrix[ 2 ][ 1 ];
+ double neg;
+ neg = m_matrix[ 0 ][ 0 ] * m_matrix[ 1 ][ 2 ] * m_matrix[ 2 ][ 1 ];
+ neg += m_matrix[ 0 ][ 1 ] * m_matrix[ 1 ][ 0 ] * m_matrix[ 2 ][ 2 ];
+ neg += m_matrix[ 0 ][ 2 ] * m_matrix[ 1 ][ 1 ] * m_matrix[ 2 ][ 0 ];
+
+ return ( pos - neg );
+}
+
+
+// calc matrix inverse --------------------------------------------------------
+//
+int Transform2::Inverse( Transform2& inverse )
+{
+ // calculate determinant
+ double det = Determinant();
+ // check for singularity
+ if ( fabs( det ) < EPS_DENOM_ZERO )
+ return 0;
+
+ // calculate inverse
+ double detinv = 1 / det;
+ inverse.m_matrix[ 0 ][ 0 ] = ( m_matrix[ 1 ][ 1 ] * m_matrix[ 2 ][ 2 ] - m_matrix[ 1 ][ 2 ] * m_matrix[ 2 ][ 1 ] ) * detinv;
+ inverse.m_matrix[ 0 ][ 1 ] = ( m_matrix[ 0 ][ 2 ] * m_matrix[ 2 ][ 1 ] - m_matrix[ 0 ][ 1 ] * m_matrix[ 2 ][ 2 ] ) * detinv;
+ inverse.m_matrix[ 0 ][ 2 ] = ( m_matrix[ 0 ][ 1 ] * m_matrix[ 1 ][ 2 ] - m_matrix[ 0 ][ 2 ] * m_matrix[ 1 ][ 1 ] ) * detinv;
+ inverse.m_matrix[ 1 ][ 0 ] = ( m_matrix[ 1 ][ 2 ] * m_matrix[ 2 ][ 0 ] - m_matrix[ 1 ][ 0 ] * m_matrix[ 2 ][ 2 ] ) * detinv;
+ inverse.m_matrix[ 1 ][ 1 ] = ( m_matrix[ 0 ][ 0 ] * m_matrix[ 2 ][ 2 ] - m_matrix[ 0 ][ 2 ] * m_matrix[ 2 ][ 0 ] ) * detinv;
+ inverse.m_matrix[ 1 ][ 2 ] = ( m_matrix[ 0 ][ 2 ] * m_matrix[ 1 ][ 0 ] - m_matrix[ 0 ][ 0 ] * m_matrix[ 1 ][ 2 ] ) * detinv;
+ inverse.m_matrix[ 2 ][ 0 ] = ( m_matrix[ 1 ][ 0 ] * m_matrix[ 2 ][ 1 ] - m_matrix[ 1 ][ 1 ] * m_matrix[ 2 ][ 0 ] ) * detinv;
+ inverse.m_matrix[ 2 ][ 1 ] = ( m_matrix[ 0 ][ 1 ] * m_matrix[ 2 ][ 0 ] - m_matrix[ 0 ][ 0 ] * m_matrix[ 2 ][ 1 ] ) * detinv;
+ inverse.m_matrix[ 2 ][ 2 ] = ( m_matrix[ 0 ][ 0 ] * m_matrix[ 1 ][ 1 ] - m_matrix[ 0 ][ 1 ] * m_matrix[ 1 ][ 0 ] ) * detinv;
+
+ return 1;
+}
+
+
+// fetch translation part of matrix -------------------------------------------
+//
+Vector2 Transform2::FetchTranslation() const
+{
+ // return translation vector
+ return Vector2( m_matrix[ 2 ][ 0 ], m_matrix[ 2 ][ 1 ] );
+}
+
+
+// extract translation part of matrix; set to NULL translation afterwards -----
+//
+Vector2 Transform2::ExtractTranslation()
+{
+ // create translation vector
+ Vector2 temp( m_matrix[ 2 ][ 0 ], m_matrix[ 2 ][ 1 ] );
+ // zero translation part of matrix
+ m_matrix[ 2 ][ 0 ] = 0.0;
+ m_matrix[ 2 ][ 1 ] = 0.0;
+ return temp;
+}
+
+
+// create rotation matrix -----------------------------------------------------
+//
+Transform2& Transform2::LoadRotation( double angle )
+{
+ // init matrix
+ LoadIdentity();
+
+ // set rotated basis
+ m_matrix[ 0 ][ 0 ] = cos( angle );
+ m_matrix[ 0 ][ 1 ] = sin( angle );
+ m_matrix[ 1 ][ 0 ] = -m_matrix[ 0 ][ 1 ];
+ m_matrix[ 1 ][ 1 ] = m_matrix[ 0 ][ 0 ];
+
+ return *this;
+}
+
+
+// create scale matrix --------------------------------------------------------
+//
+Transform2& Transform2::LoadScale( double x, double y )
+{
+ LoadIdentity();
+ m_matrix[ 0 ][ 0 ] = x;
+ m_matrix[ 1 ][ 1 ] = y;
+ return *this;
+}
+
+
+// create translation matrix --------------------------------------------------
+//
+Transform2& Transform2::LoadTranslation( double x, double y )
+{
+ LoadIdentity();
+ m_matrix[ 2 ][ 0 ] = x;
+ m_matrix[ 2 ][ 1 ] = y;
+ return *this;
+}
+
+
+// rotate around arbitrary axis -----------------------------------------------
+//
+Transform2& Transform2::Rotate( double angle )
+{
+ Transform2 temp;
+ temp.LoadRotation( angle );
+ Concat( temp );
+ return *this;
+}
+
+
+// rotate around arbitrary axis (reversed) ------------------------------------
+//
+Transform2& Transform2::RotateR( double angle )
+{
+ Transform2 temp;
+ temp.LoadRotation( angle );
+ ConcatR( temp );
+ return *this;
+}
+
+
+// apply scale factors --------------------------------------------------------
+//
+Transform2& Transform2::Scale( double x, double y )
+{
+ Transform2 temp;
+ temp.LoadScale( x, y );
+ Concat( temp );
+ return *this;
+}
+
+
+// apply scale factors (reversed) ---------------------------------------------
+//
+Transform2& Transform2::ScaleR( double x, double y )
+{
+ Transform2 temp;
+ temp.LoadScale( x, y );
+ ConcatR( temp );
+ return *this;
+}
+
+
+// apply translation ----------------------------------------------------------
+//
+Transform2& Transform2::Translate( double x, double y )
+{
+ m_matrix[ 2 ][ 0 ] += x;
+ m_matrix[ 2 ][ 1 ] += y;
+ return *this;
+}
+
+
+// apply translation (reversed) -----------------------------------------------
+//
+Transform2& Transform2::TranslateR( double x, double y )
+{
+ Transform2 temp;
+ temp.LoadTranslation( x, y );
+ ConcatR( temp );
+ return *this;
+}
+
+
+BSPLIB_NAMESPACE_END
+
+//-----------------------------------------------------------------------------
diff --git a/tool_src/BspLib/Transform2.h b/tool_src/BspLib/Transform2.h
new file mode 100644
index 0000000..b5785ab
--- /dev/null
+++ b/tool_src/BspLib/Transform2.h
@@ -0,0 +1,111 @@
+//-----------------------------------------------------------------------------
+// BSPLIB HEADER: Transform2.h
+//
+// Copyright (c) 1997-1998 by Markus Hadwiger
+// All Rights Reserved.
+//-----------------------------------------------------------------------------
+
+#ifndef _TRANSFORM2_H_
+#define _TRANSFORM2_H_
+
+// bsplib header files
+#include "BspLibDefs.h"
+#include "Vertex.h"
+
+
+BSPLIB_NAMESPACE_BEGIN
+
+
+// general 2-D homogeneous transformation -------------------------------------
+//
+class Transform2 {
+
+ friend Transform2 operator *( const Transform2& trafo1, const Transform2& trafo2 );
+
+public:
+ Transform2();
+ Transform2( const float trafo[3][3] );
+ Transform2( const double trafo[3][3] );
+ ~Transform2() { }
+
+ // transform single vector by current transformation
+ Vector2 TransformVector2( const Vector2& vec ) const;
+
+ double Determinant(); // calc matrix's determinant
+ int Inverse( Transform2& inverse ); // calc matrix's inverse
+
+ // concatenate two transformations (natural and reversed order)
+ Transform2& Concat( const Transform2& cattrafo );
+ Transform2& ConcatR( const Transform2& cattrafo );
+
+ // create elementary matrices
+ Transform2& LoadIdentity();
+ Transform2& LoadRotation( double angle );
+ Transform2& LoadScale( double x, double y );
+ Transform2& LoadTranslation( double x, double y );
+
+ // elementary transformations in natural order
+ Transform2& Rotate( double angle );
+ Transform2& Scale( double x, double y );
+ Transform2& Translate( double x, double y );
+
+ // elementary transformations in reversed order
+ Transform2& RotateR( double angle );
+ Transform2& ScaleR( double x, double y );
+ Transform2& TranslateR( double x, double y );
+
+ // fetch translation part (optionally set it null afterwards)
+ Vector2 FetchTranslation() const;
+ Vector2 ExtractTranslation();
+
+ // fetch pointer to matrix
+ double * LinMatrixAccess() { return (double *) m_matrix; }
+
+private:
+ // 3x3 matrix for 2-D homogeneous transformation (row vectors!)
+ double m_matrix[3][3];
+};
+
+// load identity matrix -------------------------------------------------------
+inline Transform2& Transform2::LoadIdentity()
+{
+ memset( m_matrix, 0, sizeof( m_matrix ) );
+
+ m_matrix[ 0 ][ 0 ] = 1.0;
+ m_matrix[ 1 ][ 1 ] = 1.0;
+ m_matrix[ 2 ][ 2 ] = 1.0;
+
+ return *this;
+}
+
+// construct a Transform2 -----------------------------------------------------
+inline Transform2::Transform2()
+{
+// LoadIdentity();
+}
+
+// construct a Transform2 directly from 3x3 matrix ----------------------------
+inline Transform2::Transform2( const double trafo[3][3] )
+{
+ //CAVEAT:
+ // the outer dimension of the matrix is not enforced!!
+ // trafo is actually of type double(*)[3]
+ memcpy( m_matrix, trafo, sizeof( m_matrix ) );
+}
+
+// construct a Transform2 directly from 3x3 matrix ----------------------------
+inline Transform2::Transform2( const float trafo[3][3] )
+{
+ //CAVEAT:
+ // the outer dimension of the matrix is not enforced!!
+ // trafo is actually of type float(*)[3]
+ for ( int i = 0; i < 9; i++ )
+ ((double *)m_matrix)[ i ] = (double) ((float *)trafo)[ i ];
+}
+
+
+BSPLIB_NAMESPACE_END
+
+
+#endif // _TRANSFORM2_H_
+
diff --git a/tool_src/BspLib/Transform3.cpp b/tool_src/BspLib/Transform3.cpp
new file mode 100644
index 0000000..7f8b54d
--- /dev/null
+++ b/tool_src/BspLib/Transform3.cpp
@@ -0,0 +1,312 @@
+//-----------------------------------------------------------------------------
+// BSPLIB MODULE: Transform3.cpp
+//
+// Copyright (c) 1997-1998 by Markus Hadwiger
+// All Rights Reserved.
+//-----------------------------------------------------------------------------
+
+// bsplib headers
+#include "Transform3.h"
+
+
+BSPLIB_NAMESPACE_BEGIN
+
+
+// multiply two 4x4 matrices --------------------------------------------------
+//
+PRIVATE
+void mat4x4_mul( double dest_matrix[][4], const double matrix1[][4], const double matrix2[][4] )
+{
+ //NOTE:
+ // full homogeneous multiplication is performed. (that is, all 16
+ // elements are calculated.) normally this isn't necessary as
+ // most matrices are affine. but since this is no real-time
+ // application more flexibility seems better.
+/*
+ for ( int i = 0; i < 4; i++ ) {
+ for ( int j = 0; j < 4; j++ ) {
+ dest_matrix[ i ][ j ] = 0.0;
+ for ( int k = 0; k < 4; k++ )
+ dest_matrix[ i ][ j ] += matrix1[ i ][ k ] * matrix2[ k ][ j ];
+ }
+ }
+*/
+ dest_matrix[ 0 ][ 0 ] = matrix1[ 0 ][ 0 ] * matrix2[ 0 ][ 0 ] +
+ matrix1[ 0 ][ 1 ] * matrix2[ 1 ][ 0 ] +
+ matrix1[ 0 ][ 2 ] * matrix2[ 2 ][ 0 ] +
+ matrix1[ 0 ][ 3 ] * matrix2[ 3 ][ 0 ];
+ dest_matrix[ 0 ][ 1 ] = matrix1[ 0 ][ 0 ] * matrix2[ 0 ][ 1 ] +
+ matrix1[ 0 ][ 1 ] * matrix2[ 1 ][ 1 ] +
+ matrix1[ 0 ][ 2 ] * matrix2[ 2 ][ 1 ] +
+ matrix1[ 0 ][ 3 ] * matrix2[ 3 ][ 1 ];
+ dest_matrix[ 0 ][ 2 ] = matrix1[ 0 ][ 0 ] * matrix2[ 0 ][ 2 ] +
+ matrix1[ 0 ][ 1 ] * matrix2[ 1 ][ 2 ] +
+ matrix1[ 0 ][ 2 ] * matrix2[ 2 ][ 2 ] +
+ matrix1[ 0 ][ 3 ] * matrix2[ 3 ][ 2 ];
+ dest_matrix[ 0 ][ 3 ] = matrix1[ 0 ][ 0 ] * matrix2[ 0 ][ 3 ] +
+ matrix1[ 0 ][ 1 ] * matrix2[ 1 ][ 3 ] +
+ matrix1[ 0 ][ 2 ] * matrix2[ 2 ][ 3 ] +
+ matrix1[ 0 ][ 3 ] * matrix2[ 3 ][ 3 ];
+
+ dest_matrix[ 1 ][ 0 ] = matrix1[ 1 ][ 0 ] * matrix2[ 0 ][ 0 ] +
+ matrix1[ 1 ][ 1 ] * matrix2[ 1 ][ 0 ] +
+ matrix1[ 1 ][ 2 ] * matrix2[ 2 ][ 0 ] +
+ matrix1[ 1 ][ 3 ] * matrix2[ 3 ][ 0 ];
+ dest_matrix[ 1 ][ 1 ] = matrix1[ 1 ][ 0 ] * matrix2[ 0 ][ 1 ] +
+ matrix1[ 1 ][ 1 ] * matrix2[ 1 ][ 1 ] +
+ matrix1[ 1 ][ 2 ] * matrix2[ 2 ][ 1 ] +
+ matrix1[ 1 ][ 3 ] * matrix2[ 3 ][ 1 ];
+ dest_matrix[ 1 ][ 2 ] = matrix1[ 1 ][ 0 ] * matrix2[ 0 ][ 2 ] +
+ matrix1[ 1 ][ 1 ] * matrix2[ 1 ][ 2 ] +
+ matrix1[ 1 ][ 2 ] * matrix2[ 2 ][ 2 ] +
+ matrix1[ 1 ][ 3 ] * matrix2[ 3 ][ 2 ];
+ dest_matrix[ 1 ][ 3 ] = matrix1[ 1 ][ 0 ] * matrix2[ 0 ][ 3 ] +
+ matrix1[ 1 ][ 1 ] * matrix2[ 1 ][ 3 ] +
+ matrix1[ 1 ][ 2 ] * matrix2[ 2 ][ 3 ] +
+ matrix1[ 1 ][ 3 ] * matrix2[ 3 ][ 3 ];
+
+ dest_matrix[ 2 ][ 0 ] = matrix1[ 2 ][ 0 ] * matrix2[ 0 ][ 0 ] +
+ matrix1[ 2 ][ 1 ] * matrix2[ 1 ][ 0 ] +
+ matrix1[ 2 ][ 2 ] * matrix2[ 2 ][ 0 ] +
+ matrix1[ 2 ][ 3 ] * matrix2[ 3 ][ 0 ];
+ dest_matrix[ 2 ][ 1 ] = matrix1[ 2 ][ 0 ] * matrix2[ 0 ][ 1 ] +
+ matrix1[ 2 ][ 1 ] * matrix2[ 1 ][ 1 ] +
+ matrix1[ 2 ][ 2 ] * matrix2[ 2 ][ 1 ] +
+ matrix1[ 2 ][ 3 ] * matrix2[ 3 ][ 1 ];
+ dest_matrix[ 2 ][ 2 ] = matrix1[ 2 ][ 0 ] * matrix2[ 0 ][ 2 ] +
+ matrix1[ 2 ][ 1 ] * matrix2[ 1 ][ 2 ] +
+ matrix1[ 2 ][ 2 ] * matrix2[ 2 ][ 2 ] +
+ matrix1[ 2 ][ 3 ] * matrix2[ 3 ][ 2 ];
+ dest_matrix[ 2 ][ 3 ] = matrix1[ 2 ][ 0 ] * matrix2[ 0 ][ 3 ] +
+ matrix1[ 2 ][ 1 ] * matrix2[ 1 ][ 3 ] +
+ matrix1[ 2 ][ 2 ] * matrix2[ 2 ][ 3 ] +
+ matrix1[ 2 ][ 3 ] * matrix2[ 3 ][ 3 ];
+
+ dest_matrix[ 3 ][ 0 ] = matrix1[ 3 ][ 0 ] * matrix2[ 0 ][ 0 ] +
+ matrix1[ 3 ][ 1 ] * matrix2[ 1 ][ 0 ] +
+ matrix1[ 3 ][ 2 ] * matrix2[ 2 ][ 0 ] +
+ matrix1[ 3 ][ 3 ] * matrix2[ 3 ][ 0 ];
+ dest_matrix[ 3 ][ 1 ] = matrix1[ 3 ][ 0 ] * matrix2[ 0 ][ 1 ] +
+ matrix1[ 3 ][ 1 ] * matrix2[ 1 ][ 1 ] +
+ matrix1[ 3 ][ 2 ] * matrix2[ 2 ][ 1 ] +
+ matrix1[ 3 ][ 3 ] * matrix2[ 3 ][ 1 ];
+ dest_matrix[ 3 ][ 2 ] = matrix1[ 3 ][ 0 ] * matrix2[ 0 ][ 2 ] +
+ matrix1[ 3 ][ 1 ] * matrix2[ 1 ][ 2 ] +
+ matrix1[ 3 ][ 2 ] * matrix2[ 2 ][ 2 ] +
+ matrix1[ 3 ][ 3 ] * matrix2[ 3 ][ 2 ];
+ dest_matrix[ 3 ][ 3 ] = matrix1[ 3 ][ 0 ] * matrix2[ 0 ][ 3 ] +
+ matrix1[ 3 ][ 1 ] * matrix2[ 1 ][ 3 ] +
+ matrix1[ 3 ][ 2 ] * matrix2[ 2 ][ 3 ] +
+ matrix1[ 3 ][ 3 ] * matrix2[ 3 ][ 3 ];
+}
+
+
+// calculate concatenation; don't overwrite object matrix ---------------------
+//
+Transform3 operator *( const Transform3& trafo1, const Transform3& trafo2 )
+{
+ Transform3 temp;
+ mat4x4_mul( temp.m_matrix, trafo1.m_matrix, trafo2.m_matrix );
+ return temp;
+}
+
+
+// calculate concatenation as new object matrix -------------------------------
+//
+Transform3& Transform3::Concat( const Transform3& cattrafo )
+{
+ Transform3 temp;
+ mat4x4_mul( temp.m_matrix, (const double(*)[4]) m_matrix, cattrafo.m_matrix );
+ memcpy( m_matrix, temp.m_matrix, sizeof( m_matrix ) );
+ return *this;
+}
+
+
+// reversed concatenation -----------------------------------------------------
+//
+Transform3& Transform3::ConcatR( const Transform3& cattrafo )
+{
+ Transform3 temp;
+ mat4x4_mul( temp.m_matrix, cattrafo.m_matrix, (const double(*)[4]) m_matrix );
+ memcpy( m_matrix, temp.m_matrix, sizeof( m_matrix ) );
+ return *this;
+}
+
+
+// transform Vector3 by matrix (homogeneous component is also evaluated!) -----
+//
+Vector3 Transform3::TransformVector3( const Vector3& vec ) const
+{
+ Vector3 temp;
+ temp.setX( m_matrix[ 0 ][ 0 ] * vec.getX() + m_matrix[ 1 ][ 0 ] * vec.getY() + m_matrix[ 2 ][ 0 ] * vec.getZ() + m_matrix[ 3 ][ 0 ] * vec.getW() );
+ temp.setY( m_matrix[ 0 ][ 1 ] * vec.getX() + m_matrix[ 1 ][ 1 ] * vec.getY() + m_matrix[ 2 ][ 1 ] * vec.getZ() + m_matrix[ 3 ][ 1 ] * vec.getW() );
+ temp.setZ( m_matrix[ 0 ][ 2 ] * vec.getX() + m_matrix[ 1 ][ 2 ] * vec.getY() + m_matrix[ 2 ][ 2 ] * vec.getZ() + m_matrix[ 3 ][ 2 ] * vec.getW() );
+ temp.setW( m_matrix[ 0 ][ 3 ] * vec.getX() + m_matrix[ 1 ][ 3 ] * vec.getY() + m_matrix[ 2 ][ 3 ] * vec.getZ() + m_matrix[ 3 ][ 3 ] * vec.getW() );
+ return temp;
+}
+
+
+// fetch translation part of matrix -------------------------------------------
+//
+Vector3 Transform3::FetchTranslation() const
+{
+ // return translation vector
+ return Vector3( m_matrix[ 3 ][ 0 ], m_matrix[ 3 ][ 1 ], m_matrix[ 3 ][ 2 ] );
+}
+
+
+// extract translation part of matrix; set to NULL translation afterwards -----
+//
+Vector3 Transform3::ExtractTranslation()
+{
+ // create translation vector
+ Vector3 temp( m_matrix[ 3 ][ 0 ], m_matrix[ 3 ][ 1 ], m_matrix[ 3 ][ 2 ] );
+ // zero translation part of matrix
+ m_matrix[ 3 ][ 0 ] = 0.0;
+ m_matrix[ 3 ][ 1 ] = 0.0;
+ m_matrix[ 3 ][ 2 ] = 0.0;
+ return temp;
+}
+
+
+// create rotation matrix -----------------------------------------------------
+//
+Transform3& Transform3::LoadRotation( double angle, double x, double y, double z )
+{
+ // init matrix
+ LoadIdentity();
+
+ // normalize axis of rotation
+ Vector3 axis( x, y, z );
+ if ( !axis.Normalize() ) {
+ // NULL vector: return identity matrix
+ return *this;
+ }
+
+ // calculate unit quaternion corresponding to rotation
+ double phi2 = -angle / 2;
+ double sinphi2 = sin( phi2 );
+ double W = cos( phi2 );
+ double X = sinphi2 * axis.getX();
+ double Y = sinphi2 * axis.getY();
+ double Z = sinphi2 * axis.getZ();
+
+ // calculate intermediate terms
+ double X2 = X * X;
+ double Y2 = Y * Y;
+ double Z2 = Z * Z;
+ double XY = X * Y;
+ double XZ = X * Z;
+ double YZ = Y * Z;
+ double WX = W * X;
+ double WY = W * Y;
+ double WZ = W * Z;
+
+ // convert quaternion into rotation matrix
+ m_matrix[ 0 ][ 0 ] = 1 - ( Y2 + Z2 ) * 2;
+ m_matrix[ 0 ][ 1 ] = ( XY - WZ ) * 2;
+ m_matrix[ 0 ][ 2 ] = ( XZ + WY ) * 2;
+ m_matrix[ 1 ][ 0 ] = ( XY + WZ ) * 2;
+ m_matrix[ 1 ][ 1 ] = 1 - ( X2 + Z2 ) * 2;
+ m_matrix[ 1 ][ 2 ] = ( YZ - WX ) * 2;
+ m_matrix[ 2 ][ 0 ] = ( XZ - WY ) * 2;
+ m_matrix[ 2 ][ 1 ] = ( YZ + WX ) * 2;
+ m_matrix[ 2 ][ 2 ] = 1 - ( X2 + Y2 ) * 2;
+
+ return *this;
+}
+
+
+// create scale matrix --------------------------------------------------------
+//
+Transform3& Transform3::LoadScale( double x, double y, double z )
+{
+ LoadIdentity();
+ m_matrix[ 0 ][ 0 ] = x;
+ m_matrix[ 1 ][ 1 ] = y;
+ m_matrix[ 2 ][ 2 ] = z;
+ return *this;
+}
+
+
+// create translation matrix --------------------------------------------------
+//
+Transform3& Transform3::LoadTranslation( double x, double y, double z )
+{
+ LoadIdentity();
+ m_matrix[ 3 ][ 0 ] = x;
+ m_matrix[ 3 ][ 1 ] = y;
+ m_matrix[ 3 ][ 2 ] = z;
+ return *this;
+}
+
+
+// rotate around arbitrary axis -----------------------------------------------
+//
+Transform3& Transform3::Rotate( double angle, double x, double y, double z )
+{
+ Transform3 temp;
+ temp.LoadRotation( angle, x, y, z );
+ Concat( temp );
+ return *this;
+}
+
+
+// rotate around arbitrary axis (reversed) ------------------------------------
+//
+Transform3& Transform3::RotateR( double angle, double x, double y, double z )
+{
+ Transform3 temp;
+ temp.LoadRotation( angle, x, y, z );
+ ConcatR( temp );
+ return *this;
+}
+
+
+// apply scale factors --------------------------------------------------------
+//
+Transform3& Transform3::Scale( double x, double y, double z )
+{
+ Transform3 temp;
+ temp.LoadScale( x, y, z );
+ Concat( temp );
+ return *this;
+}
+
+
+// apply scale factors (reversed) ---------------------------------------------
+//
+Transform3& Transform3::ScaleR( double x, double y, double z )
+{
+ Transform3 temp;
+ temp.LoadScale( x, y, z );
+ ConcatR( temp );
+ return *this;
+}
+
+
+// apply translation ----------------------------------------------------------
+//
+Transform3& Transform3::Translate( double x, double y, double z )
+{
+ m_matrix[ 3 ][ 0 ] += x;
+ m_matrix[ 3 ][ 1 ] += y;
+ m_matrix[ 3 ][ 2 ] += z;
+ return *this;
+}
+
+
+// apply translation (reversed) -----------------------------------------------
+//
+Transform3& Transform3::TranslateR( double x, double y, double z )
+{
+ Transform3 temp;
+ temp.LoadTranslation( x, y, z );
+ ConcatR( temp );
+ return *this;
+}
+
+
+BSPLIB_NAMESPACE_END
+
+//-----------------------------------------------------------------------------
diff --git a/tool_src/BspLib/Transform3.h b/tool_src/BspLib/Transform3.h
new file mode 100644
index 0000000..58a1b7e
--- /dev/null
+++ b/tool_src/BspLib/Transform3.h
@@ -0,0 +1,106 @@
+//-----------------------------------------------------------------------------
+// BSPLIB HEADER: Transform3.h
+//
+// Copyright (c) 1997 by Markus Hadwiger
+// All Rights Reserved.
+//-----------------------------------------------------------------------------
+
+#ifndef _TRANSFORM3_H_
+#define _TRANSFORM3_H_
+
+// bsplib header files
+#include "BspLibDefs.h"
+#include "Vertex.h"
+
+
+BSPLIB_NAMESPACE_BEGIN
+
+
+// general 3-D homogeneous transformation -------------------------------------
+//
+class Transform3 {
+
+ friend Transform3 operator *( const Transform3& trafo1, const Transform3& trafo2 );
+
+public:
+ Transform3();
+ Transform3( const float trafo[4][4] );
+ Transform3( const double trafo[4][4] );
+ ~Transform3() { }
+
+ // transform single vector by current transformation
+ Vector3 TransformVector3( const Vector3& vec ) const;
+
+ // concatenate two transformations (natural and reversed order)
+ Transform3& Concat( const Transform3& cattrafo );
+ Transform3& ConcatR( const Transform3& cattrafo );
+
+ // create elementary matrices
+ Transform3& LoadIdentity();
+ Transform3& LoadRotation( double angle, double x, double y, double z );
+ Transform3& LoadScale( double x, double y, double z );
+ Transform3& LoadTranslation( double x, double y, double z );
+
+ // elementary transformations in natural order
+ Transform3& Rotate( double angle, double x, double y, double z );
+ Transform3& Scale( double x, double y, double z );
+ Transform3& Translate( double x, double y, double z );
+
+ // elementary transformations in reversed order
+ Transform3& RotateR( double angle, double x, double y, double z );
+ Transform3& ScaleR( double x, double y, double z );
+ Transform3& TranslateR( double x, double y, double z );
+
+ // fetch translation part (optionally set it null afterwards)
+ Vector3 FetchTranslation() const;
+ Vector3 ExtractTranslation();
+
+private:
+ // 4x4 matrix for 3-D homogeneous transformation (row vectors!)
+ double m_matrix[4][4];
+};
+
+// load identity matrix -------------------------------------------------------
+inline Transform3& Transform3::LoadIdentity()
+{
+ memset( m_matrix, 0, sizeof( m_matrix ) );
+
+ m_matrix[ 0 ][ 0 ] = 1.0;
+ m_matrix[ 1 ][ 1 ] = 1.0;
+ m_matrix[ 2 ][ 2 ] = 1.0;
+ m_matrix[ 3 ][ 3 ] = 1.0;
+
+ return *this;
+}
+
+// construct a transform3 -----------------------------------------------------
+inline Transform3::Transform3()
+{
+// LoadIdentity();
+}
+
+// construct a transform3 directly from 4x4 matrix ----------------------------
+inline Transform3::Transform3( const double trafo[4][4] )
+{
+ //CAVEAT:
+ // the outer dimension of the matrix is not enforced!!
+ // trafo is actually of type double(*)[4]
+ memcpy( m_matrix, trafo, sizeof( m_matrix ) );
+}
+
+// construct a transform3 directly from 4x4 matrix ----------------------------
+inline Transform3::Transform3( const float trafo[4][4] )
+{
+ //CAVEAT:
+ // the outer dimension of the matrix is not enforced!!
+ // trafo is actually of type float(*)[4]
+ for ( int i = 0; i < 16; i++ )
+ ((double *)m_matrix)[ i ] = (double) ((float *)trafo)[ i ];
+}
+
+
+BSPLIB_NAMESPACE_END
+
+
+#endif // _TRANSFORM3_H_
+
diff --git a/tool_src/BspLib/TriMapping.cpp b/tool_src/BspLib/TriMapping.cpp
new file mode 100644
index 0000000..c2e2185
--- /dev/null
+++ b/tool_src/BspLib/TriMapping.cpp
@@ -0,0 +1,26 @@
+//-----------------------------------------------------------------------------
+// BSPLIB MODULE: TriMapping.cpp
+//
+// Copyright (c) 1997 by Markus Hadwiger
+// All Rights Reserved.
+//-----------------------------------------------------------------------------
+
+// bsplib headers
+#include "TriMapping.h"
+
+
+BSPLIB_NAMESPACE_BEGIN
+
+
+// invalid index for mapping vertex -------------------------------------------
+//
+void TriMapping::Error() const
+{
+ ErrorMessage( "\n***ERROR*** Invalid index in BspLib::TriMapping." );
+ HandleCriticalError();
+}
+
+
+BSPLIB_NAMESPACE_END
+
+//-----------------------------------------------------------------------------
diff --git a/tool_src/BspLib/TriMapping.h b/tool_src/BspLib/TriMapping.h
new file mode 100644
index 0000000..896b147
--- /dev/null
+++ b/tool_src/BspLib/TriMapping.h
@@ -0,0 +1,43 @@
+//-----------------------------------------------------------------------------
+// BSPLIB HEADER: TriMapping.h
+//
+// Copyright (c) 1997 by Markus Hadwiger
+// All Rights Reserved.
+//-----------------------------------------------------------------------------
+
+#ifndef _TRIMAPPING_H_
+#define _TRIMAPPING_H_
+
+// bsplib header files
+#include "BspLibDefs.h"
+#include "SystemIO.h"
+#include "Vertex.h"
+
+
+BSPLIB_NAMESPACE_BEGIN
+
+
+// affine mapping specification for a triangle --------------------------------
+//
+class TriMapping : public virtual SystemIO {
+
+ void Error() const;
+
+public:
+ TriMapping() { }
+ ~TriMapping() { }
+
+ Vertex2& getMapXY( int indx ) { if ( indx > 2 ) Error(); return map_xy[ indx ]; }
+ Vertex2& getMapUV( int indx ) { if ( indx > 2 ) Error(); return map_uv[ indx ]; }
+
+private:
+ Vertex2 map_xy[ 3 ]; // mapping is specified via three
+ Vertex2 map_uv[ 3 ]; // point correspondences
+};
+
+
+BSPLIB_NAMESPACE_END
+
+
+#endif // _TRIMAPPING_H_
+
diff --git a/tool_src/BspLib/Vector.h b/tool_src/BspLib/Vector.h
new file mode 100644
index 0000000..92f9bbe
--- /dev/null
+++ b/tool_src/BspLib/Vector.h
@@ -0,0 +1,100 @@
+//-----------------------------------------------------------------------------
+// BSPLIB HEADER: Vector.h
+//
+// Copyright (c) 1997 by Markus Hadwiger
+// All Rights Reserved.
+//-----------------------------------------------------------------------------
+
+#ifndef _VECTOR_H_
+#define _VECTOR_H_
+
+// bsplib header files
+#include "Vector3.h"
+#include "Vector2.h"
+
+
+BSPLIB_NAMESPACE_BEGIN
+
+
+// vertex plus vector yields vertex -------------------------------------------
+inline Vertex3 operator +( const Vertex3 v1, const Vector3 v2 )
+{
+ return Vertex3( v1.X + v2.X, v1.Y + v2.Y, v1.Z + v2.Z, 1.0 );
+}
+
+// vector plus vertex yields vertex -------------------------------------------
+inline Vertex3 operator +( const Vector3 v1, const Vertex3 v2 )
+{
+ return Vertex3( v1.X + v2.X, v1.Y + v2.Y, v1.Z + v2.Z, 1.0 );
+}
+
+// vertex minus vertex yields vector ------------------------------------------
+inline Vector3 operator -( const Vertex3 v1, const Vertex3 v2 )
+{
+ return Vector3( v1.X - v2.X, v1.Y - v2.Y, v1.Z - v2.Z, 1.0 );
+}
+
+// vertex minus vector yields vertex ------------------------------------------
+inline Vertex3 operator -( const Vertex3 v1, const Vector3 v2 )
+{
+ return Vertex3( v1.X - v2.X, v1.Y - v2.Y, v1.Z - v2.Z, 1.0 );
+}
+
+// vector plus vector yields vector -------------------------------------------
+inline Vector3 operator +( const Vector3 v1, const Vector3 v2 )
+{
+ return Vector3( v1.X + v2.X, v1.Y + v2.Y, v1.Z + v2.Z, 1.0 );
+}
+
+// vector minus vector yields vector ------------------------------------------
+inline Vector3 operator -( const Vector3 v1, const Vector3 v2 )
+{
+ return Vector3( v1.X - v2.X, v1.Y - v2.Y, v1.Z - v2.Z, 1.0 );
+}
+
+
+//-----------------------------------------------------------------------------
+
+
+// vertex plus vector yields vertex -------------------------------------------
+inline Vertex2 operator +( const Vertex2 v1, const Vector2 v2 )
+{
+ return Vertex2( v1.X + v2.X, v1.Y + v2.Y, 1.0 );
+}
+
+// vector plus vertex yields vertex -------------------------------------------
+inline Vertex2 operator +( const Vector2 v1, const Vertex2 v2 )
+{
+ return Vertex2( v1.X + v2.X, v1.Y + v2.Y, 1.0 );
+}
+
+// vertex minus vertex yields vector ------------------------------------------
+inline Vector2 operator -( const Vertex2 v1, const Vertex2 v2 )
+{
+ return Vector2( v1.X - v2.X, v1.Y - v2.Y, 1.0 );
+}
+
+// vertex minus vector yields vertex ------------------------------------------
+inline Vertex2 operator -( const Vertex2 v1, const Vector2 v2 )
+{
+ return Vertex2( v1.X - v2.X, v1.Y - v2.Y, 1.0 );
+}
+
+// vector plus vector yields vector -------------------------------------------
+inline Vector2 operator +( const Vector2 v1, const Vector2 v2 )
+{
+ return Vector2( v1.X + v2.X, v1.Y + v2.Y, 1.0 );
+}
+
+// vector minus vector yields vector ------------------------------------------
+inline Vector2 operator -( const Vector2 v1, const Vector2 v2 )
+{
+ return Vector2( v1.X - v2.X, v1.Y - v2.Y, 1.0 );
+}
+
+
+BSPLIB_NAMESPACE_END
+
+
+#endif // _VECTOR_H_
+
diff --git a/tool_src/BspLib/Vector2.h b/tool_src/BspLib/Vector2.h
new file mode 100644
index 0000000..7b9f275
--- /dev/null
+++ b/tool_src/BspLib/Vector2.h
@@ -0,0 +1,113 @@
+//-----------------------------------------------------------------------------
+// BSPLIB HEADER: Vector2.h
+//
+// Copyright (c) 1997 by Markus Hadwiger
+// All Rights Reserved.
+//-----------------------------------------------------------------------------
+
+#ifndef _VECTOR2_H_
+#define _VECTOR2_H_
+
+// bsplib header files
+#include "BspLibDefs.h"
+#include "Vertex2.h"
+
+
+BSPLIB_NAMESPACE_BEGIN
+
+
+// vector times scalar (post-multiply) ----------------------------------------
+inline Vector2 operator *( const Vector2 v1, double t )
+{
+ return Vector2( v1.X * t, v1.Y * t, 1.0 );
+}
+
+// scalar times vector (pre-multiply) -----------------------------------------
+inline Vector2 operator *( double t, const Vector2 v1 )
+{
+ return Vector2( v1.X * t, v1.Y * t, 1.0 );
+}
+
+// operator '+=' does memberwise addition for (X,Y) ---------------------------
+inline Vector2& Vector2::operator +=( const Vector2 v )
+{
+ X += v.X;
+ Y += v.Y;
+ return *this;
+}
+
+// operator '-=' does memberwise subtraction for (X,Y) ------------------------
+inline Vector2& Vector2::operator -=( const Vector2 v )
+{
+ X -= v.X;
+ Y -= v.Y;
+ return *this;
+}
+
+// operator '*=' does multiplication with a scalar ----------------------------
+inline Vector2& Vector2::operator *=( double t )
+{
+ X *= t;
+ Y *= t;
+ return *this;
+}
+
+// normalize vector (homogeneous coordinate will be set to one) ---------------
+inline int Vector2::Normalize()
+{
+ if ( IsNullVector() )
+ return FALSE;
+
+ double oonorm = 1 / VecLength();
+ X = X * oonorm;
+ Y = Y * oonorm;
+ W = 1.0;
+ return TRUE;
+}
+
+// homogenize vector (divide by homogeneous coordinate) -----------------------
+inline int Vector2::Homogenize()
+{
+ if ( fabs( W ) < EPS_DENOM_ZERO )
+ return FALSE;
+
+ double oow = 1 / W;
+ X = X * oow;
+ Y = Y * oow;
+ W = 1.0;
+ return TRUE;
+}
+
+// check if vector has length zero (employs an epsilon area) ------------------
+inline int Vector2::IsNullVector() const
+{
+ // the epsilon area is employed componentwise, not for the length itself!
+ return ( ( fabs( X ) < EPS_COMP_ZERO ) && ( fabs( Y ) < EPS_COMP_ZERO ) );
+}
+
+// calculate length of two dimensional vector ---------------------------------
+inline hprec_t Vector2::VecLength() const
+{
+ return sqrt( X * X + Y * Y );
+}
+
+// calculate floating point scalar-product ------------------------------------
+inline hprec_t Vector2::DotProduct( const Vector2& vect ) const
+{
+ return ( vect.X * X ) + ( vect.Y * Y );
+}
+
+// calc vector directed from second vertex to first vertex --------------------
+inline void Vector2::CreateDirVec( const Vertex2& vertex1, const Vertex2& vertex2 )
+{
+ X = vertex2.X - vertex1.X;
+ Y = vertex2.Y - vertex1.Y;
+ W = 1.0;
+}
+
+
+BSPLIB_NAMESPACE_END
+
+
+#endif // _VECTOR2_H_
+
diff --git a/tool_src/BspLib/Vector3.h b/tool_src/BspLib/Vector3.h
new file mode 100644
index 0000000..f2c34e0
--- /dev/null
+++ b/tool_src/BspLib/Vector3.h
@@ -0,0 +1,134 @@
+//-----------------------------------------------------------------------------
+// BSPLIB HEADER: Vector3.h
+//
+// Copyright (c) 1997 by Markus Hadwiger
+// All Rights Reserved.
+//-----------------------------------------------------------------------------
+
+#ifndef _VECTOR3_H_
+#define _VECTOR3_H_
+
+// bsplib header files
+#include "BspLibDefs.h"
+#include "Vertex3.h"
+
+
+BSPLIB_NAMESPACE_BEGIN
+
+
+// vector times scalar (post-multiply) ----------------------------------------
+inline Vector3 operator *( const Vector3 v1, double t )
+{
+ return Vector3( v1.X * t, v1.Y * t, v1.Z * t, 1.0 );
+}
+
+// scalar times vector (pre-multiply) -----------------------------------------
+inline Vector3 operator *( double t, const Vector3 v1 )
+{
+ return Vector3( v1.X * t, v1.Y * t, v1.Z * t, 1.0 );
+}
+
+// construct Vector3 as cross product of two other vectors --------------------
+inline Vector3::Vector3( const Vector3& v1, const Vector3& v2 )
+{
+ CrossProduct( v1, v2 );
+}
+
+// operator '+=' does memberwise addition for (X,Y,Z) -------------------------
+inline Vector3& Vector3::operator +=( const Vector3 v )
+{
+ X += v.X;
+ Y += v.Y;
+ Z += v.Z;
+ return *this;
+}
+
+// operator '-=' does memberwise subtraction for (X,Y,Z) ----------------------
+inline Vector3& Vector3::operator -=( const Vector3 v )
+{
+ X -= v.X;
+ Y -= v.Y;
+ Z -= v.Z;
+ return *this;
+}
+
+// operator '*=' does multiplication with a scalar ----------------------------
+inline Vector3& Vector3::operator *=( double t )
+{
+ X *= t;
+ Y *= t;
+ Z *= t;
+ return *this;
+}
+
+// normalize vector (homogeneous coordinate will be set to one) ---------------
+inline int Vector3::Normalize()
+{
+ if ( IsNullVector() )
+ return FALSE;
+
+ double oonorm = 1 / VecLength();
+ X = X * oonorm;
+ Y = Y * oonorm;
+ Z = Z * oonorm;
+ W = 1.0;
+ return TRUE;
+}
+
+// homogenize vector (divide by homogeneous coordinate) -----------------------
+inline int Vector3::Homogenize()
+{
+ if ( fabs( W ) < EPS_DENOM_ZERO )
+ return FALSE;
+
+ double oow = 1 / W;
+ X = X * oow;
+ Y = Y * oow;
+ Z = Z * oow;
+ W = 1.0;
+ return TRUE;
+}
+
+// check if vector has length zero (employs an epsilon area) ------------------
+inline int Vector3::IsNullVector() const
+{
+ // the epsilon area is employed componentwise, not for the length itself!
+ return ( ( fabs( X ) < EPS_COMP_ZERO ) && ( fabs( Y ) < EPS_COMP_ZERO ) && ( fabs( Z ) < EPS_COMP_ZERO ) );
+}
+
+// calculate length of three dimensional vector -------------------------------
+inline hprec_t Vector3::VecLength() const
+{
+ return sqrt( X * X + Y * Y + Z * Z );
+}
+
+// calculate floating point scalar-product ------------------------------------
+inline hprec_t Vector3::DotProduct( const Vector3& vect ) const
+{
+ return ( vect.X * X ) + ( vect.Y * Y ) + ( vect.Z * Z );
+}
+
+// calculate floating point cross-product -------------------------------------
+inline void Vector3::CrossProduct( const Vector3& vect1, const Vector3& vect2 )
+{
+ X = ( vect1.Y * vect2.Z ) - ( vect1.Z * vect2.Y );
+ Y = ( vect1.Z * vect2.X ) - ( vect1.X * vect2.Z );
+ Z = ( vect1.X * vect2.Y ) - ( vect1.Y * vect2.X );
+ W = 1.0;
+}
+
+// calc vector directed from second vertex to first vertex --------------------
+inline void Vector3::CreateDirVec( const Vertex3& vertex1, const Vertex3& vertex2 )
+{
+ X = vertex2.X - vertex1.X;
+ Y = vertex2.Y - vertex1.Y;
+ Z = vertex2.Z - vertex1.Z;
+ W = 1.0;
+}
+
+
+BSPLIB_NAMESPACE_END
+
+
+#endif // _VECTOR3_H_
+
diff --git a/tool_src/BspLib/Vertex.cpp b/tool_src/BspLib/Vertex.cpp
new file mode 100644
index 0000000..f46b038
--- /dev/null
+++ b/tool_src/BspLib/Vertex.cpp
@@ -0,0 +1,47 @@
+//-----------------------------------------------------------------------------
+// BSPLIB MODULE: Vertex.cpp
+//
+// Copyright (c) 1996-1997 by Markus Hadwiger
+// All Rights Reserved.
+//-----------------------------------------------------------------------------
+
+// bsplib headers
+#include "Vertex.h"
+
+
+BSPLIB_NAMESPACE_BEGIN
+
+
+// set specified coordinate to specified value --------------------------------
+void Vertex3::ChangeAxis( const char xchar, const hprec_t src )
+{
+ switch ( xchar ) {
+ case 'x':
+ X = src;
+ break;
+ case 'y':
+ Y = src;
+ break;
+ case 'z':
+ Z = src;
+ break;
+ default:
+ fflush( stdout );
+ fprintf( stderr, "\n\n**ERROR** [illegal xchange parameters]\n" );
+ exit( EXIT_FAILURE );
+ }
+}
+
+// change all axes according to xchange-command -------------------------------
+void Vertex3::ChangeAxes( const char *xchangecmd, const Vertex3& ads )
+{
+ Vertex3 temp = *this;
+ ChangeAxis( xchangecmd[ 0 ], temp.X * ads.X );
+ ChangeAxis( xchangecmd[ 1 ], temp.Y * ads.Y );
+ ChangeAxis( xchangecmd[ 2 ], temp.Z * ads.Z );
+}
+
+
+BSPLIB_NAMESPACE_END
+
+//-----------------------------------------------------------------------------
diff --git a/tool_src/BspLib/Vertex.h b/tool_src/BspLib/Vertex.h
new file mode 100644
index 0000000..7a4db5f
--- /dev/null
+++ b/tool_src/BspLib/Vertex.h
@@ -0,0 +1,206 @@
+//-----------------------------------------------------------------------------
+// BSPLIB HEADER: Vertex.h
+//
+// Copyright (c) 1997 by Markus Hadwiger
+// All Rights Reserved.
+//-----------------------------------------------------------------------------
+
+#ifndef _VERTEX_H_
+#define _VERTEX_H_
+
+// bsplib header files
+#include "BspLibDefs.h"
+
+
+BSPLIB_NAMESPACE_BEGIN
+
+
+// single 3-D vertex ----------------------------------------------------------
+//
+class Vertex3 {
+
+ friend class Vector3;
+ friend class LineSeg3;
+
+ friend int operator ==( const Vertex3 v1, const Vertex3 v2 );
+ friend int operator !=( const Vertex3 v1, const Vertex3 v2 );
+
+ friend class Vector3 operator -( const Vertex3 v1, const Vertex3 v2 );
+
+ friend Vertex3 operator +( const Vertex3 v1, const class ector3 v2 );
+ friend Vertex3 operator +( const class Vector3 v1, const Vertex3 v2 );
+ friend Vertex3 operator -( const Vertex3 v1, const class Vector3 v2 );
+
+public:
+ Vertex3( hprec_t x = 0, hprec_t y = 0, hprec_t z = 0, hprec_t w = 1.0 );
+ ~Vertex3() { }
+
+ Vertex3& operator +=( const Vector3 v );
+ Vertex3& operator -=( const Vector3 v );
+
+ int IsInVicinity( const Vertex3& vertex ) const;
+ void ChangeAxes( const char *xchangecmd, const Vertex3& ads );
+
+ hprec_t getX() const { return X; }
+ hprec_t getY() const { return Y; }
+ hprec_t getZ() const { return Z; }
+ hprec_t getW() const { return W; }
+
+ void setX( hprec_t x ) { X = x; }
+ void setY( hprec_t y ) { Y = y; }
+ void setZ( hprec_t z ) { Z = z; }
+ void setW( hprec_t w ) { W = w; }
+ hprec_t X;
+ hprec_t Y;
+ hprec_t Z;
+ hprec_t W;
+
+private:
+ void ChangeAxis( const char xchar, const hprec_t src );
+
+protected:
+};
+
+
+// single 3-D vector ----------------------------------------------------------
+//
+class Vector3 : public Vertex3 {
+
+ friend class LineSeg3;
+
+ friend Vector3 operator -( const Vertex3 v1, const Vertex3 v2 );
+
+ friend Vertex3 operator +( const Vertex3 v1, const Vector3 v2 );
+ friend Vertex3 operator +( const Vector3 v1, const Vertex3 v2 );
+ friend Vertex3 operator -( const Vertex3 v1, const Vector3 v2 );
+
+ friend Vector3 operator +( const Vector3 v1, const Vector3 v2 );
+ friend Vector3 operator -( const Vector3 v1, const Vector3 v2 );
+
+ friend Vector3 operator *( const Vector3 v1, double t );
+ friend Vector3 operator *( double t, const Vector3 v1 );
+
+public:
+ Vector3( hprec_t x = 0, hprec_t y = 0, hprec_t z = 0, hprec_t w = 1.0 )
+ : Vertex3( x, y, z, w ) { }
+ // initialize as direction vector
+ Vector3( const Vertex3& v1, const Vertex3& v2 )
+ : Vertex3( v2.X - v1.X, v2.Y - v1.Y, v2.Z - v1.Z ) { }
+ // initialize as cross product
+ Vector3( const Vector3& v1, const Vector3& v2 );
+ // conversion from Vertex3
+ Vector3( const Vertex3& vtx ) { *(Vertex3*)this = vtx; }
+ ~Vector3() { }
+
+ Vector3& operator +=( const Vector3 v );
+ Vector3& operator -=( const Vector3 v );
+
+ Vector3& operator *=( double t );
+
+ int Normalize();
+ int Homogenize();
+ int IsNullVector() const;
+ hprec_t VecLength() const;
+ hprec_t DotProduct( const Vector3& vect ) const;
+ void CrossProduct( const Vector3& vect1, const Vector3& vect2 );
+ void CreateDirVec( const Vertex3& vertex1, const Vertex3& vertex2 );
+};
+
+
+// single 2-D vertex ----------------------------------------------------------
+//
+class Vertex2 {
+
+ friend class Vector2;
+ friend class LineSeg2;
+
+ friend int operator ==( const Vertex2 v1, const Vertex2 v2 );
+ friend int operator !=( const Vertex2 v1, const Vertex2 v2 );
+
+ friend class Vector2 operator -( const Vertex2 v1, const Vertex2 v2 );
+
+ friend Vertex2 operator +( const Vertex2 v1, const class Vector2 v2 );
+ friend Vertex2 operator +( const class Vector2 v1, const Vertex2 v2 );
+ friend Vertex2 operator -( const Vertex2 v1, const class Vector2 v2 );
+
+public:
+ Vertex2( hprec_t x = 0, hprec_t y = 0, hprec_t w = 1.0 ) { X = x; Y = y; W = w; }
+ // conversion Vector2 -> Vertex2
+ Vertex2( const Vector2& vect );
+ ~Vertex2() { }
+
+ Vertex2& operator +=( const Vector2 v );
+ Vertex2& operator -=( const Vector2 v );
+
+ int IsInVicinity( const Vertex2& vertex ) const;
+ void InitFromVertex3( const Vertex3& vertex );
+
+ hprec_t getX() const { return X; }
+ hprec_t getY() const { return Y; }
+ hprec_t getW() const { return W; }
+
+ void setX( hprec_t x ) { X = x; }
+ void setY( hprec_t y ) { Y = y; }
+ void setW( hprec_t w ) { W = w; }
+
+protected:
+ hprec_t X;
+ hprec_t Y;
+ hprec_t W;
+};
+
+
+// single 2-D vector ----------------------------------------------------------
+//
+class Vector2 : public Vertex2 {
+
+ friend class LineSeg2;
+
+ friend Vector2 operator -( const Vertex2 v1, const Vertex2 v2 );
+
+ friend Vertex2 operator +( const Vertex2 v1, const Vector2 v2 );
+ friend Vertex2 operator +( const Vector2 v1, const Vertex2 v2 );
+ friend Vertex2 operator -( const Vertex2 v1, const Vector2 v2 );
+
+ friend Vector2 operator +( const Vector2 v1, const Vector2 v2 );
+ friend Vector2 operator -( const Vector2 v1, const Vector2 v2 );
+
+ friend Vector2 operator *( const Vector2 v1, double t );
+ friend Vector2 operator *( double t, const Vector2 v1 );
+
+public:
+ Vector2( hprec_t x = 0, hprec_t y = 0, hprec_t w = 1.0 )
+ : Vertex2( x, y, w ) { }
+ // initialize as direction vector
+ Vector2( const Vertex2& v1, const Vertex2& v2 )
+ : Vertex2( v2.X - v1.X, v2.Y - v1.Y ) { }
+ // conversion from Vertex2
+ Vector2( const Vertex2& vtx ) { *(Vertex2*)this = vtx; }
+ ~Vector2() { }
+
+ Vector2& operator +=( const Vector2 v );
+ Vector2& operator -=( const Vector2 v );
+
+ Vector2& operator *=( double t );
+
+ int Normalize();
+ int Homogenize();
+ int IsNullVector() const;
+ hprec_t VecLength() const;
+ hprec_t DotProduct( const Vector2& vect ) const;
+ void CreateDirVec( const Vertex2& vertex, const Vertex2& dirvec );
+};
+
+
+BSPLIB_NAMESPACE_END
+
+
+// include vector and lineseg capability, and chunks of vertices
+#include "Vector.h"
+#include "LineSeg2.h"
+#include "LineSeg3.h"
+#include "VertexChunk.h"
+
+
+#endif // _VERTEX_H_
+
diff --git a/tool_src/BspLib/Vertex2.h b/tool_src/BspLib/Vertex2.h
new file mode 100644
index 0000000..5ebf100
--- /dev/null
+++ b/tool_src/BspLib/Vertex2.h
@@ -0,0 +1,76 @@
+//-----------------------------------------------------------------------------
+// BSPLIB HEADER: Vertex2.h
+//
+// Copyright (c) 1997 by Markus Hadwiger
+// All Rights Reserved.
+//-----------------------------------------------------------------------------
+
+#ifndef _VERTEX2_H_
+#define _VERTEX2_H_
+
+// bsplib header files
+#include "BspLibDefs.h"
+
+
+BSPLIB_NAMESPACE_BEGIN
+
+
+// conversion from Vector2 to Vertex2 -----------------------------------------
+inline Vertex2::Vertex2( const Vector2& vect )
+{
+ X = vect.X;
+ Y = vect.Y;
+ W = vect.W;
+}
+
+// operator '==' does memberwise comparison for (X,Y,W) -----------------------
+inline int operator ==( const Vertex2 v1, const Vertex2 v2 )
+{
+ return ( ( v1.X == v2.X ) && ( v1.Y == v2.Y ) && ( v1.W == v2.W ) );
+}
+
+// operator '!=' does memberwise comparison for (X,Y,W) -----------------------
+inline int operator !=( const Vertex2 v1, const Vertex2 v2 )
+{
+ return ( ( v1.X != v2.X ) || ( v1.Y != v2.Y ) || ( v1.W != v2.W ) );
+}
+
+// operator '+=' does memberwise addition for (X,Y) ---------------------------
+inline Vertex2& Vertex2::operator +=( const Vector2 v )
+{
+ X += v.X;
+ Y += v.Y;
+
+ return *this;
+}
+
+// operator '-=' does memberwise subtraction for (X,Y) ------------------------
+inline Vertex2& Vertex2::operator -=( const Vector2 v )
+{
+ X -= v.X;
+ Y -= v.Y;
+
+ return *this;
+}
+
+// check if specified vertex is in vicinity of local vertex -------------------
+inline int Vertex2::IsInVicinity( const Vertex2& vertex ) const
+{
+ return ( ( fabs( X - vertex.X ) < EPS_VERTEX_MERGE ) &&
+ ( fabs( Y - vertex.Y ) < EPS_VERTEX_MERGE ) );
+}
+
+// copy three coordinates into two plus w -------------------------------------
+inline void Vertex2::InitFromVertex3( const Vertex3& vertex )
+{
+ X = vertex.getX();
+ Y = vertex.getY();
+ W = vertex.getZ();
+}
+
+
+BSPLIB_NAMESPACE_END
+
+
+#endif // _VERTEX2_H_
+
diff --git a/tool_src/BspLib/Vertex3.h b/tool_src/BspLib/Vertex3.h
new file mode 100644
index 0000000..113b9c2
--- /dev/null
+++ b/tool_src/BspLib/Vertex3.h
@@ -0,0 +1,72 @@
+//-----------------------------------------------------------------------------
+// BSPLIB HEADER: Vertex3.h
+//
+// Copyright (c) 1997 by Markus Hadwiger
+// All Rights Reserved.
+//-----------------------------------------------------------------------------
+
+#ifndef _VERTEX3_H_
+#define _VERTEX3_H_
+
+// bsplib header files
+#include "BspLibDefs.h"
+
+
+BSPLIB_NAMESPACE_BEGIN
+
+
+// construct Vertex3 by initializing member coordinates -----------------------
+inline Vertex3::Vertex3( hprec_t x, hprec_t y, hprec_t z, hprec_t w )
+{
+ X = x;
+ Y = y;
+ Z = z;
+ W = w;
+}
+
+// operator '==' does memberwise comparison for (X,Y,Z,W) ---------------------
+inline int operator ==( const Vertex3 v1, const Vertex3 v2 )
+{
+ return ( ( v1.X == v2.X ) && ( v1.Y == v2.Y ) && ( v1.Z == v2.Z ) && ( v1.W == v2.W ) );
+}
+
+// operator '!=' does memberwise comparison for (X,Y,Z,W) ---------------------
+inline int operator !=( const Vertex3 v1, const Vertex3 v2 )
+{
+ return ( ( v1.X != v2.X ) || ( v1.Y != v2.Y ) || ( v1.Z != v2.Z ) || ( v1.W != v2.W ) );
+}
+
+// operator '+=' does memberwise addition for (X,Y,Z) -------------------------
+inline Vertex3& Vertex3::operator +=( const Vector3 v )
+{
+ X += v.X;
+ Y += v.Y;
+ Z += v.Z;
+
+ return *this;
+}
+
+// operator '-=' does memberwise subtraction for (X,Y,Z) ----------------------
+inline Vertex3& Vertex3::operator -=( const Vector3 v )
+{
+ X -= v.X;
+ Y -= v.Y;
+ Z -= v.Z;
+
+ return *this;
+}
+
+// check if specified vertex is in vicinity of local vertex -------------------
+inline int Vertex3::IsInVicinity( const Vertex3& vertex ) const
+{
+ return ( ( fabs( X - vertex.X ) < EPS_VERTEX_MERGE ) &&
+ ( fabs( Y - vertex.Y ) < EPS_VERTEX_MERGE ) &&
+ ( fabs( Z - vertex.Z ) < EPS_VERTEX_MERGE ) );
+}
+
+
+BSPLIB_NAMESPACE_END
+
+
+#endif // _VERTEX3_H_
+
diff --git a/tool_src/BspLib/VertexChunk.cpp b/tool_src/BspLib/VertexChunk.cpp
new file mode 100644
index 0000000..8bce25a
--- /dev/null
+++ b/tool_src/BspLib/VertexChunk.cpp
@@ -0,0 +1,237 @@
+//-----------------------------------------------------------------------------
+// BSPLIB MODULE: VertexChunk.cpp
+//
+// Copyright (c) 1997 by Markus Hadwiger
+// All Rights Reserved.
+//-----------------------------------------------------------------------------
+
+// bsplib headers
+#include "Vertex.h"
+
+
+// if this flag is set storage is increased by using lists.
+// this can be very inefficient and should only be used for
+// testing purposes!
+// if not set, storage is expanded in realloc() style.
+//#define EXPAND_STORAGE_WITH_LISTS
+
+// if this flag is set storage is always increased two-fold
+#define EXPAND_EXPONENTIALLY
+
+
+BSPLIB_NAMESPACE_BEGIN
+
+
+// return number of vertices in entire vertex chunk list ----------------------
+//
+int VertexChunkRep::getNumElements() const
+{
+ int num = 0;
+ for ( const VertexChunkRep *vlist = this; vlist; vlist = vlist->next )
+ num += vlist->numvertices;
+ return num;
+}
+
+
+// fetch index to specified vertex if vertex already exists -------------------
+//
+int VertexChunkRep::FindVertex( const Vertex3& vertex )
+{
+ int numskipped = 0;
+
+ VertexChunkRep *vlist = this;
+ while ( ( vlist != NULL ) && ( vlist->numvertices > 0 ) ) {
+ for ( int i = 0; i < vlist->numvertices; i++ )
+ if ( vertices[ i ] == vertex )
+ return i + numskipped;
+ numskipped += vlist->numvertices;
+ vlist = vlist->next;
+ }
+
+ // vertex not found
+ return -1;
+}
+
+
+// fetch vertex-index if close enough vertex already exists -------------------
+//
+int VertexChunkRep::FindCloseVertex( const Vertex3& vertex, int skip )
+{
+ int numskipped = 0;
+
+ VertexChunkRep *vlist = this;
+ while ( ( vlist != NULL ) && ( vlist->numvertices > 0 ) ) {
+ for ( int i = 0; i < vlist->numvertices; i++ )
+ if ( ( i + numskipped > skip ) && vertices[ i ].IsInVicinity( vertex ) )
+ return i + numskipped;
+ numskipped += vlist->numvertices;
+ vlist = vlist->next;
+ }
+
+ // vertex not found
+ return -1;
+}
+
+
+// fetch vertex corresponding to specific index -------------------------------
+//
+Vertex3& VertexChunkRep::FetchVertex( int index )
+{
+
+#ifdef EXPAND_STORAGE_WITH_LISTS
+
+ VertexChunkRep *vlist = this;
+ while ( ( vlist != NULL ) && ( index >= vlist->numvertices ) ) {
+ index -= vlist->numvertices;
+ vlist = vlist->next;
+ }
+
+ if ( vlist == NULL ) {
+ // invalid index (too large)
+ ErrorMessage( "\n***ERROR*** Invalid index in VertexChunk.\n" );
+ HandleCriticalError();
+ }
+
+ // return vertex
+ return vlist->vertices[ index ];
+
+#else
+
+ if ( index >= numvertices ) {
+ // invalid index (too large)
+ ErrorMessage( "\n***ERROR*** Invalid index in VertexChunk.\n" );
+ HandleCriticalError();
+ }
+
+ // return vertex
+ return vertices[ index ];
+
+#endif
+
+}
+
+
+// check if multiple vertices exist for the same actual point -----------------
+//
+int VertexChunkRep::CheckVertices( int verbose )
+{
+ StrScratch message;
+
+ if ( verbose ) {
+ InfoMessage( "\nChecking vertices...\n" );
+ }
+
+ nummultvertices = 0;
+ int multi = 0;
+ for ( int i = 0; i < getNumElements(); i++ ) {
+ int vertindx = FindCloseVertex( FetchVertex( i ), i );
+ if ( vertindx != -1 ) {
+ if ( verbose ) {
+ if ( multi == 0 ) {
+ InfoMessage( "*** multiple vertices found ***\n" );
+ multi++;
+ }
+ sprintf( message, "Vertex %d is same as %d\n", i + 1, vertindx + 1 );
+ InfoMessage( message );
+ }
+ nummultvertices++;
+ }
+ }
+
+ return nummultvertices;
+}
+
+
+// insert vertex into list of vertex chunks, return index; check doublets -----
+//
+int VertexChunkRep::AddVertex( Vertex3 vertex )
+{
+
+#ifdef EXPAND_STORAGE_WITH_LISTS
+
+ // if vertex contained in head-chunk return index
+ if ( eliminatedoublets )
+ for ( int i = 0; i < numvertices; i++ )
+ if ( VerticesEqual( vertices[ i ], vertex ) )
+ return i;
+
+ // if space in head-chunk insert vertex directly
+ if ( numvertices < maxnumvertices ) {
+
+ vertices[ numvertices ] = vertex;
+ return numvertices++;
+
+ } else {
+
+ int numskipped = numvertices;
+ VertexChunkRep *vlist = this;
+
+ // scan until non-full chunk found
+ while ( ( vlist->next != NULL ) && ( vlist->next->numvertices == vlist->next->maxnumvertices ) ) {
+
+ if ( eliminatedoublets )
+ for ( int i = 0; i < vlist->next->numvertices; i++ )
+ if ( VerticesEqual( vlist->next->vertices[ i ], vertex ) )
+ return i + numskipped;
+ vlist = vlist->next;
+ numskipped += vlist->numvertices;
+ }
+
+ if ( vlist->next == NULL ) {
+ // insert new chunk if all existing are full
+#ifdef EXPAND_EXPONENTIALLY
+ vlist->next = new VertexChunkRep( vlist->maxnumvertices * 2 );
+#else
+ vlist->next = new VertexChunkRep;
+#endif
+ } else {
+ if ( eliminatedoublets )
+ for ( int i = 0; i < vlist->next->numvertices; i++ )
+ if ( VerticesEqual( vlist->next->vertices[ i ], vertex ) )
+ return i + numskipped;
+ }
+
+ // insert new vertex
+ vlist->next->vertices[ vlist->next->numvertices ] = vertex;
+ return vlist->next->numvertices++ + numskipped;
+ }
+
+#else
+
+ // if vertex already contained in chunk return index
+ if ( eliminatedoublets )
+ for ( int i = 0; i < numvertices; i++ )
+ if ( VerticesEqual( vertices[ i ], vertex ) )
+ return i;
+
+ // expand storage if necessary
+ if ( numvertices == maxnumvertices ) {
+
+#ifdef EXPAND_EXPONENTIALLY
+ maxnumvertices *= 2;
+#else
+ maxnumvertices += CHUNK_SIZE;
+#endif
+ Vertex3 *temp = new Vertex3[ maxnumvertices ];
+ memcpy( temp, vertices, numvertices * sizeof( Vertex3 ) );
+ delete[] vertices;
+ vertices = temp;
+ }
+
+ vertices[ numvertices ] = vertex;
+ return numvertices++;
+
+#endif
+
+}
+
+
+// VertexChunkRep specific static variables -----------------------------------
+//
+const int VertexChunkRep::CHUNK_SIZE = 256;
+int VertexChunkRep::eliminatedoublets = 0;
+
+
+BSPLIB_NAMESPACE_END
+
+//-----------------------------------------------------------------------------
diff --git a/tool_src/BspLib/VertexChunk.h b/tool_src/BspLib/VertexChunk.h
new file mode 100644
index 0000000..dd5274a
--- /dev/null
+++ b/tool_src/BspLib/VertexChunk.h
@@ -0,0 +1,129 @@
+//-----------------------------------------------------------------------------
+// BSPLIB HEADER: VertexChunk.h
+//
+// Copyright (c) 1997 by Markus Hadwiger
+// All Rights Reserved.
+//-----------------------------------------------------------------------------
+
+#ifndef _VERTEXCHUNK_H_
+#define _VERTEXCHUNK_H_
+
+// bsplib header files
+#include "BspLibDefs.h"
+#include "SystemIO.h"
+
+
+BSPLIB_NAMESPACE_BEGIN
+
+
+// chunk of 3-D vertices (actual representation) ------------------------------
+//
+class VertexChunkRep : public virtual SystemIO {
+
+ friend class VertexChunk;
+
+private:
+ VertexChunkRep( int chunksize = 0 );
+ ~VertexChunkRep();
+
+ Vertex3& FetchVertex( int index );
+ int AddVertex( Vertex3 vertex );
+ int FindVertex( const Vertex3& vertex );
+ int FindCloseVertex( const Vertex3& vertex, int skip = -1 );
+ int CheckVertices( int verbose );
+
+ int getNumElements() const;
+
+private:
+ void ChangeAxis( char xchar, hprec_t src );
+ int VerticesEqual( Vertex3 v1, Vertex3 v2 );
+
+private:
+ int ref_count;
+
+ int numvertices;
+ int maxnumvertices;
+ Vertex3* vertices;
+ VertexChunkRep* next;
+
+ int nummultvertices;
+ static int eliminatedoublets;
+ static const int CHUNK_SIZE;
+};
+
+// create new vertex chunk ----------------------------------------------------
+inline VertexChunkRep::VertexChunkRep( int chunksize ) : ref_count( 0 )
+{
+ int challocsize = chunksize > 0 ? chunksize : CHUNK_SIZE;
+ vertices = new Vertex3[ challocsize ];
+ maxnumvertices = challocsize;
+ numvertices = 0;
+ next = NULL;
+}
+
+// destroy list of vertex chunks recursively ----------------------------------
+inline VertexChunkRep::~VertexChunkRep()
+{
+ delete next;
+ delete[] vertices;
+}
+
+// check if two vertices are equal --------------------------------------------
+inline int VertexChunkRep::VerticesEqual( Vertex3 v1, Vertex3 v2 )
+{
+// return v1.IsInVicinity( v2 );
+ return ( v1 == v2 );
+}
+
+
+// chunk of 3-D vertices (handle class) ---------------------------------------
+//
+class VertexChunk {
+
+public:
+ VertexChunk( int chunksize = 0 ) { rep = new VertexChunkRep( chunksize ); rep->ref_count = 1; }
+ ~VertexChunk() { if ( --rep->ref_count == 0 ) delete rep; }
+
+ VertexChunk( const VertexChunk& copyobj );
+ VertexChunk& operator =( const VertexChunk& copyobj );
+
+ Vertex3& operator []( int index ) { return rep->FetchVertex( index ); }
+ Vertex3& FetchVertex( int index ) { return rep->FetchVertex( index ); }
+
+ int AddVertex( const Vertex3 vertex ) { return rep->AddVertex( vertex ); }
+ int FindVertex( const Vertex3& vertex ) { return rep->FindVertex( vertex ); }
+ int FindCloseVertex( Vertex3 vertex, int skip = -1 ) { return rep->FindCloseVertex( vertex, skip ); }
+ int CheckVertices( int verbose ) { return rep->CheckVertices( verbose ); }
+
+ int getNumElements() const { return rep->getNumElements(); }
+
+private:
+ VertexChunkRep* rep;
+};
+
+// copy constructor for VertexChunk -------------------------------------------
+inline VertexChunk::VertexChunk( const VertexChunk& copyobj )
+{
+ rep = copyobj.rep;
+ rep->ref_count++;
+}
+
+// assignment operator for VertexChunk ----------------------------------------
+inline VertexChunk& VertexChunk::operator =( const VertexChunk& copyobj )
+{
+ if ( &copyobj != this ) {
+ if ( --rep->ref_count == 0 ) {
+ delete rep;
+ }
+ rep = copyobj.rep;
+ rep->ref_count++;
+ }
+ return *this;
+}
+
+
+BSPLIB_NAMESPACE_END
+
+
+#endif // _VERTEXCHUNK_H_
+
diff --git a/tool_src/BspLib/VrmlFile.cpp b/tool_src/BspLib/VrmlFile.cpp
new file mode 100644
index 0000000..64f2df1
--- /dev/null
+++ b/tool_src/BspLib/VrmlFile.cpp
@@ -0,0 +1,133 @@
+//-----------------------------------------------------------------------------
+// BSPLIB MODULE: VrmlFile.cpp
+//
+// Copyright (c) 1997-1998 by Markus Hadwiger
+// All Rights Reserved.
+//-----------------------------------------------------------------------------
+
+// bsplib header files
+#include "VrmlFile.h"
+#include "BspObject.h"
+#include "BspTool.h"
+
+// qvlib header files
+#include <QvDB.h>
+#include <QvInput.h>
+#include <QvNode.h>
+#include <QvState.h>
+
+
+BSPLIB_NAMESPACE_BEGIN
+
+
+// file is read and parsed immediately after construction ---------------------
+//
+VrmlFile::VrmlFile( BspObjectList objectlist, const char *filename ) :
+ InputData3D( objectlist, filename, DONT_CREATE_OBJECT ),
+ m_bboxlist( NULL )
+{
+ ParseObjectData();
+}
+
+
+// write outputfile before destruction ----------------------------------------
+//
+VrmlFile::~VrmlFile()
+{
+ if ( m_inputok && !m_filename.IsNULL() )
+ WriteOutputFile();
+ delete m_bboxlist;
+}
+
+
+// apply all transformations to scene -----------------------------------------
+//
+void VrmlFile::ApplySceneTransformations()
+{
+ BspObject *sceneobj = m_objectlist.getListHead();
+ for ( ; sceneobj; sceneobj = sceneobj->getNext() )
+ sceneobj->ApplyTransformation();
+}
+
+
+// enforce maximum extents for entire scene -----------------------------------
+//
+void VrmlFile::EnforceSceneExtents( BoundingBox& unionbox )
+{
+ double fmext = getMaxExtents();
+
+ Vertex3 minvertex = unionbox.getMinVertex();
+ Vertex3 maxvertex = unionbox.getMaxVertex();
+
+ double extent_x = maxvertex.getX() - minvertex.getX();
+ double extent_y = maxvertex.getY() - minvertex.getY();
+ double extent_z = maxvertex.getZ() - minvertex.getZ();
+
+ double mext = extent_x;
+ if ( extent_y > mext ) mext = extent_y;
+ if ( extent_z > mext ) mext = extent_z;
+ double cfac = fmext / mext;
+
+ BspObject *sceneobj = m_objectlist.getListHead();
+ for ( ; sceneobj; sceneobj = sceneobj->getNext() )
+ sceneobj->ApplyScale( cfac );
+}
+
+
+// parse vrml 1.0 file and build data structures for all contained objects ----
+//
+int VrmlFile::ParseObjectData()
+{
+ // open input data file
+ FileAccess input( m_filename, "r" );
+ InfoMessage( "Processing input data file (format='VRML V1.0') ..." );
+
+ // init qvlib database
+ QvDB::init();
+
+ // tie input file to QvInput object
+ QvInput inputdata;
+ inputdata.setFilePointer( input );
+
+ // read and parse vrml input data
+ QvNode *vrmlroot = NULL;
+ if ( QvDB::read( &inputdata, vrmlroot ) && ( vrmlroot != NULL ) ) {
+ InfoMessage( "\nObject data ok.\n" );
+ m_inputok = TRUE;
+ } else {
+ sprintf( line, "%sVRML tree data invalid.\n", parser_err_str );
+ ErrorMessage( line );
+ HandleCriticalError( CRITERR_ALLOW_RET );
+ delete vrmlroot;
+ return ( m_inputok = FALSE );
+ }
+
+ // create object for traversal state
+ QvState state( this );
+
+ // traverse entire vrml tree and construct scene representation for bsplib
+ vrmlroot->traverse( &state );
+
+ // if scene scale desired calculate union bounding box and scale entire scene
+ if ( getEnforceExtentsFlag() && ( m_bboxlist != NULL ) ) {
+ BoundingBox unionbox;
+ m_bboxlist->BoundingBoxListUnion( unionbox );
+ EnforceSceneExtents( unionbox );
+ }
+
+ delete vrmlroot;
+ return m_inputok;
+}
+
+
+// write output file(s) for objects constructed out of vrml file --------------
+//
+int VrmlFile::WriteOutputFile()
+{
+ return FALSE;
+}
+
+
+BSPLIB_NAMESPACE_END
+
+//-----------------------------------------------------------------------------
diff --git a/tool_src/BspLib/VrmlFile.h b/tool_src/BspLib/VrmlFile.h
new file mode 100644
index 0000000..7b0dfd6
--- /dev/null
+++ b/tool_src/BspLib/VrmlFile.h
@@ -0,0 +1,48 @@
+//-----------------------------------------------------------------------------
+// BSPLIB HEADER: VrmlFile.h
+//
+// Copyright (c) 1997 by Markus Hadwiger
+// All Rights Reserved.
+//-----------------------------------------------------------------------------
+
+#ifndef _VRMLFILE_H_
+#define _VRMLFILE_H_
+
+// bsplib header files
+#include "BspLibDefs.h"
+#include "BoundingBox.h"
+#include "InputData3D.h"
+
+
+BSPLIB_NAMESPACE_BEGIN
+
+
+class BspObjectList;
+
+// file manipulation class for vrml format files ------------------------------
+//
+class VrmlFile : public InputData3D {
+
+ friend class BRep;
+
+public:
+ VrmlFile( BspObjectList objectlist, const char *filename );
+ ~VrmlFile();
+
+ int ParseObjectData();
+ int WriteOutputFile();
+
+private:
+ void ApplySceneTransformations();
+ void EnforceSceneExtents( BoundingBox& unionbox );
+
+private:
+ BoundingBox* m_bboxlist;
+};
+
+
+BSPLIB_NAMESPACE_END
+
+
+#endif // _VRMLFILE_H_
+
diff --git a/tool_src/QvLib/Makefile b/tool_src/QvLib/Makefile
new file mode 100644
index 0000000..b1c0e0a
--- /dev/null
+++ b/tool_src/QvLib/Makefile
@@ -0,0 +1,90 @@
+# QvLib makefile
+
+CFILES = QvChildList.cpp\
+QvCone.cpp\
+QvCoordinate3.cpp\
+QvCube.cpp\
+QvCylinder.cpp\
+QvDb.cpp\
+QvDebugError.cpp\
+QvDict.cpp\
+QvDirectionalLight.cpp\
+QvElement.cpp\
+QvField.cpp\
+QvFieldData.cpp\
+QvGroup.cpp\
+QvIndexedFaceSet.cpp\
+QvIndexedLineSet.cpp\
+QvInfo.cpp\
+QvInput.cpp\
+QvLevelOfDetail.cpp\
+QvLists.cpp\
+QvMFColor.cpp\
+QvMFFloat.cpp\
+QvMFLong.cpp\
+QvMFVec2f.cpp\
+QvMFVec3f.cpp\
+QvMaterial.cpp\
+QvMaterialBinding.cpp\
+QvMatrixTransform.cpp\
+QvName.cpp\
+QvNode.cpp\
+QvNormal.cpp\
+QvNormalBinding.cpp\
+QvOrthographicCamera.cpp\
+QvPList.cpp\
+QvPerspectiveCamera.cpp\
+QvPointLight.cpp\
+QvPointSet.cpp\
+QvReadError.cpp\
+QvRotation.cpp\
+QvSFBitMask.cpp\
+QvSFBool.cpp\
+QvSFColor.cpp\
+QvSFEnum.cpp\
+QvSFFloat.cpp\
+QvSFImage.cpp\
+QvSFLong.cpp\
+QvSFMatrix.cpp\
+QvSFRotation.cpp\
+QvSFString.cpp\
+QvSFVec2f.cpp\
+QvSFVec3f.cpp\
+QvScale.cpp\
+QvSeparator.cpp\
+QvShapeHints.cpp\
+QvSphere.cpp\
+QvSpotlight.cpp\
+QvState.cpp\
+QvString.cpp\
+QvSwitch.cpp\
+QvTexture2.cpp\
+QvTexture2Transform.cpp\
+QvTextureCoordinate2.cpp\
+QvTransform.cpp\
+QvTransformSeparator.cpp\
+QvTranslation.cpp\
+QvTraverse.cpp\
+QvUnknownNode.cpp\
+QvWWWAnchor.cpp\
+QvWWWInline.cpp
+
+
+CFLAGS = -g -O2 -I. -I../BspLib -fno-for-scope\
+ -Dstricmp=strcasecmp -Dstrnicmp=strncasecmp
+
+all: libqv.a
+
+libqv.a: $(CFILES:.cpp=.o)
+ ar rc libqv.a $(CFILES:.cpp=.o)
+ ranlib libqv.a
+
+.cpp.o:
+ gcc $(CFLAGS) -o $@ -c $<
+
+clean:
+ rm -f *.o *.a *~
+
+
+
+
diff --git a/tool_src/QvLib/QvBasic.h b/tool_src/QvLib/QvBasic.h
new file mode 100644
index 0000000..f54c906
--- /dev/null
+++ b/tool_src/QvLib/QvBasic.h
@@ -0,0 +1,46 @@
+#ifndef _QV_BASIC_
+#define _QV_BASIC_
+
+#ifdef WIN32
+typedef unsigned long u_long;
+#define M_PI 3.1415926536
+#define M_PI_4 (M_PI/4.0)
+#endif
+
+#include <sys/types.h>
+#ifndef WIN32
+//#include <libc.h>
+#include <stdlib.h>
+
+#else
+#include <stdlib.h>
+#endif /* WIN32 */
+#include <stdio.h>
+
+#ifndef FALSE
+# define FALSE 0
+# define TRUE 1
+#endif
+
+typedef int QvBool;
+
+// This uses the preprocessor to quote a string
+#if defined(__STDC__) || defined(__ANSI_CPP__) /* ANSI C */
+# define QV__QUOTE(str) #str
+#else /* Non-ANSI C */
+#ifdef WIN32
+# define QV__QUOTE(str) #str
+#else
+# define QV__QUOTE(str) "str"
+#endif
+#endif
+
+// This uses the preprocessor to concatenate two strings
+#if defined(__STDC__) || defined(__ANSI_CPP__) /* ANSI C */
+# define QV__CONCAT(str1, str2) str1##str2
+#else /* Non-ANSI C */
+# define QV__CONCAT(str1, str2) str1/**/str2
+#endif
+
+#endif /* _QV_BASIC_ */
+
diff --git a/tool_src/QvLib/QvChildList.cpp b/tool_src/QvLib/QvChildList.cpp
new file mode 100644
index 0000000..5fba922
--- /dev/null
+++ b/tool_src/QvLib/QvChildList.cpp
@@ -0,0 +1,10 @@
+#include <QvChildList.h>
+
+QvChildList::QvChildList() : QvNodeList()
+{
+}
+
+QvChildList::~QvChildList()
+{
+ truncate(0);
+}
diff --git a/tool_src/QvLib/QvChildList.h b/tool_src/QvLib/QvChildList.h
new file mode 100644
index 0000000..f200c28
--- /dev/null
+++ b/tool_src/QvLib/QvChildList.h
@@ -0,0 +1,13 @@
+#ifndef _QV_CHILD_LIST_
+#define _QV_CHILD_LIST_
+
+#include <QvLists.h>
+
+class QvChildList : public QvNodeList {
+
+ public:
+ QvChildList();
+ ~QvChildList();
+};
+
+#endif /* _QV_CHILD_LIST_ */
diff --git a/tool_src/QvLib/QvCone.cpp b/tool_src/QvLib/QvCone.cpp
new file mode 100644
index 0000000..b8724f3
--- /dev/null
+++ b/tool_src/QvLib/QvCone.cpp
@@ -0,0 +1,27 @@
+#include <QvCone.h>
+
+QV_NODE_SOURCE(QvCone);
+
+QvCone::QvCone()
+{
+ QV_NODE_CONSTRUCTOR(QvCone);
+ isBuiltIn = TRUE;
+
+ QV_NODE_ADD_FIELD(parts);
+ QV_NODE_ADD_FIELD(bottomRadius);
+ QV_NODE_ADD_FIELD(height);
+
+ parts.value = ALL;
+ bottomRadius.value = 1.0;
+ height.value = 2.0;
+
+ QV_NODE_DEFINE_ENUM_VALUE(Part, SIDES);
+ QV_NODE_DEFINE_ENUM_VALUE(Part, BOTTOM);
+ QV_NODE_DEFINE_ENUM_VALUE(Part, ALL);
+
+ QV_NODE_SET_SF_ENUM_TYPE(parts, Part);
+}
+
+QvCone::~QvCone()
+{
+}
diff --git a/tool_src/QvLib/QvCone.h b/tool_src/QvLib/QvCone.h
new file mode 100644
index 0000000..74a3291
--- /dev/null
+++ b/tool_src/QvLib/QvCone.h
@@ -0,0 +1,26 @@
+#ifndef _QV_CONE_
+#define _QV_CONE_
+
+#include <QvSFBitMask.h>
+#include <QvSFFloat.h>
+#include <QvSubNode.h>
+
+class QvCone : public QvNode {
+
+ QV_NODE_HEADER(QvCone);
+
+ public:
+
+ enum Part { // Cone parts:
+ SIDES = 0x01, // The conical part
+ BOTTOM = 0x02, // The bottom circular face
+ ALL = 0x03 // All parts
+ };
+
+ // Fields
+ QvSFBitMask parts; // Visible parts of cone
+ QvSFFloat bottomRadius; // Radius of bottom circular face
+ QvSFFloat height; // Size in y dimension
+};
+
+#endif /* _QV_CONE_ */
diff --git a/tool_src/QvLib/QvCoordinate3.cpp b/tool_src/QvLib/QvCoordinate3.cpp
new file mode 100644
index 0000000..9822b97
--- /dev/null
+++ b/tool_src/QvLib/QvCoordinate3.cpp
@@ -0,0 +1,17 @@
+#include <QvCoordinate3.h>
+
+QV_NODE_SOURCE(QvCoordinate3);
+
+QvCoordinate3::QvCoordinate3()
+{
+ QV_NODE_CONSTRUCTOR(QvCoordinate3);
+ isBuiltIn = TRUE;
+
+ QV_NODE_ADD_FIELD(point);
+
+ point.values[0] = point.values[1] = point.values[2] = 0.0;
+}
+
+QvCoordinate3::~QvCoordinate3()
+{
+}
diff --git a/tool_src/QvLib/QvCoordinate3.h b/tool_src/QvLib/QvCoordinate3.h
new file mode 100644
index 0000000..035e692
--- /dev/null
+++ b/tool_src/QvLib/QvCoordinate3.h
@@ -0,0 +1,16 @@
+#ifndef _QV_COORDINATE3_
+#define _QV_COORDINATE3_
+
+#include <QvMFVec3f.h>
+#include <QvSubNode.h>
+
+class QvCoordinate3 : public QvNode {
+
+ QV_NODE_HEADER(QvCoordinate3);
+
+ public:
+ // Fields
+ QvMFVec3f point; // Coordinate point(s)
+};
+
+#endif /* _QV_COORDINATE3_ */
diff --git a/tool_src/QvLib/QvCube.cpp b/tool_src/QvLib/QvCube.cpp
new file mode 100644
index 0000000..eec1cd0
--- /dev/null
+++ b/tool_src/QvLib/QvCube.cpp
@@ -0,0 +1,21 @@
+#include <QvCube.h>
+
+QV_NODE_SOURCE(QvCube);
+
+QvCube::QvCube()
+{
+ QV_NODE_CONSTRUCTOR(QvCube);
+ isBuiltIn = TRUE;
+
+ QV_NODE_ADD_FIELD(width);
+ QV_NODE_ADD_FIELD(height);
+ QV_NODE_ADD_FIELD(depth);
+
+ width.value = 2.0;
+ height.value = 2.0;
+ depth.value = 2.0;
+}
+
+QvCube::~QvCube()
+{
+}
diff --git a/tool_src/QvLib/QvCube.h b/tool_src/QvLib/QvCube.h
new file mode 100644
index 0000000..fe02d92
--- /dev/null
+++ b/tool_src/QvLib/QvCube.h
@@ -0,0 +1,18 @@
+#ifndef _QV_CUBE_
+#define _QV_CUBE_
+
+#include <QvSFFloat.h>
+#include <QvSubNode.h>
+
+class QvCube : public QvNode {
+
+ QV_NODE_HEADER(QvCube);
+
+ public:
+ // Fields
+ QvSFFloat width; // Size in x dimension
+ QvSFFloat height; // Size in y dimension
+ QvSFFloat depth; // Size in z dimension
+};
+
+#endif /* _QV_CUBE_ */
diff --git a/tool_src/QvLib/QvCylinder.cpp b/tool_src/QvLib/QvCylinder.cpp
new file mode 100644
index 0000000..a2b871a
--- /dev/null
+++ b/tool_src/QvLib/QvCylinder.cpp
@@ -0,0 +1,28 @@
+#include <QvCylinder.h>
+
+QV_NODE_SOURCE(QvCylinder);
+
+QvCylinder::QvCylinder()
+{
+ QV_NODE_CONSTRUCTOR(QvCylinder);
+ isBuiltIn = TRUE;
+
+ QV_NODE_ADD_FIELD(parts);
+ QV_NODE_ADD_FIELD(radius);
+ QV_NODE_ADD_FIELD(height);
+
+ parts.value = ALL;
+ radius.value = 1.0;
+ height.value = 2.0;
+
+ QV_NODE_DEFINE_ENUM_VALUE(Part, SIDES);
+ QV_NODE_DEFINE_ENUM_VALUE(Part, TOP);
+ QV_NODE_DEFINE_ENUM_VALUE(Part, BOTTOM);
+ QV_NODE_DEFINE_ENUM_VALUE(Part, ALL);
+
+ QV_NODE_SET_SF_ENUM_TYPE(parts, Part);
+}
+
+QvCylinder::~QvCylinder()
+{
+}
diff --git a/tool_src/QvLib/QvCylinder.h b/tool_src/QvLib/QvCylinder.h
new file mode 100644
index 0000000..9a762df
--- /dev/null
+++ b/tool_src/QvLib/QvCylinder.h
@@ -0,0 +1,27 @@
+#ifndef _QV_CYLINDER_
+#define _QV_CYLINDER_
+
+#include <QvSFBitMask.h>
+#include <QvSFFloat.h>
+#include <QvSubNode.h>
+
+class QvCylinder : public QvNode {
+
+ QV_NODE_HEADER(QvCylinder);
+
+ public:
+
+ enum Part { // Cylinder parts
+ SIDES = 0x01, // The tubular part
+ TOP = 0x02, // The top circular face
+ BOTTOM = 0x04, // The bottom circular face
+ ALL = 0x07, // All parts
+ };
+
+ // Fields
+ QvSFBitMask parts; // Visible parts of cylinder
+ QvSFFloat radius; // Radius in x and z dimensions
+ QvSFFloat height; // Size in y dimension
+};
+
+#endif /* _QV_CYLINDER_ */
diff --git a/tool_src/QvLib/QvDB.h b/tool_src/QvLib/QvDB.h
new file mode 100644
index 0000000..aee530c
--- /dev/null
+++ b/tool_src/QvLib/QvDB.h
@@ -0,0 +1,18 @@
+#ifndef _QV_DB_
+#define _QV_DB_
+
+#include <QvBasic.h>
+
+class QvInput;
+class QvNode;
+class QvField;
+
+class QvDB {
+ public:
+ static const char *versionString;
+
+ static void init();
+ static QvBool read(QvInput *in, QvNode *&rootNode);
+};
+
+#endif /* _QV_DB_ */
diff --git a/tool_src/QvLib/QvDb.cpp b/tool_src/QvLib/QvDb.cpp
new file mode 100644
index 0000000..6d4ddf7
--- /dev/null
+++ b/tool_src/QvLib/QvDb.cpp
@@ -0,0 +1,29 @@
+#include <QvDB.h>
+#include <QvInput.h>
+#include <QvReadError.h>
+#include <QvNode.h>
+
+const char *QvDB::versionString = "Reference VRML Parser 1.0";
+
+void
+QvDB::init()
+{
+ QvNode::init();
+}
+
+QvBool
+QvDB::read(QvInput *in, QvNode *&node)
+{
+ QvBool ret;
+
+ ret = QvNode::read(in, node);
+
+ if (ret && node == NULL && ! in->eof()) {
+ char c;
+ in->get(c);
+ QvReadError::post(in, "Extra characters ('%c') found in input", c);
+ ret = FALSE;
+ }
+
+ return ret;
+}
diff --git a/tool_src/QvLib/QvDebugError.cpp b/tool_src/QvLib/QvDebugError.cpp
new file mode 100644
index 0000000..c8cbd03
--- /dev/null
+++ b/tool_src/QvLib/QvDebugError.cpp
@@ -0,0 +1,16 @@
+#include <stdarg.h>
+#include <QvString.h>
+#include <QvDebugError.h>
+
+void
+QvDebugError::post(const char *methodName, const char *formatString ...)
+{
+ char buf[10000];
+ va_list ap;
+
+ va_start(ap, formatString);
+ vsprintf(buf, formatString, ap);
+ va_end(ap);
+
+ fprintf(stderr, "VRML error in %s(): %s\n", methodName, buf);
+}
diff --git a/tool_src/QvLib/QvDebugError.h b/tool_src/QvLib/QvDebugError.h
new file mode 100644
index 0000000..4fff114
--- /dev/null
+++ b/tool_src/QvLib/QvDebugError.h
@@ -0,0 +1,9 @@
+#ifndef _QV_DEBUG_ERROR
+#define _QV_DEBUG_ERROR
+
+class QvDebugError {
+ public:
+ static void post(const char *methodName, const char *formatString ...);
+};
+
+#endif /* _QV_DEBUG_ERROR */
diff --git a/tool_src/QvLib/QvDict.cpp b/tool_src/QvLib/QvDict.cpp
new file mode 100644
index 0000000..52b3be6
--- /dev/null
+++ b/tool_src/QvLib/QvDict.cpp
@@ -0,0 +1,98 @@
+#include <QvDict.h>
+
+struct QvDictListThing {
+ QvPList *keyList;
+ QvPList *valueList;
+};
+
+QvDict::QvDict( int entries )
+{
+ tableSize=entries;
+ buckets=new QvDictEntry *[tableSize];
+ for (int i = 0; i < tableSize; i++)
+ buckets[i] = NULL;
+}
+
+QvDict::~QvDict()
+{
+ clear();
+ delete [] buckets;
+}
+
+void
+QvDict::clear()
+{
+ int i;
+ QvDictEntry *entry, *nextEntry;
+
+ for (i = 0; i < tableSize; i++) {
+
+ for (entry = buckets[i]; entry != NULL; entry = nextEntry) {
+ nextEntry = entry->next;
+ delete entry;
+ }
+ buckets[i] = NULL;
+ }
+}
+
+QvBool
+QvDict::enter(u_long key, void *value)
+{
+ QvDictEntry *&entry = findEntry(key);
+
+ if (entry == NULL) {
+ entry = new QvDictEntry(key, value);
+ entry->next = NULL;
+ return TRUE;
+ }
+ else {
+ entry->value = value;
+ return FALSE;
+ }
+}
+
+QvBool
+QvDict::find(u_long key, void *&value) const
+{
+ QvDictEntry *&entry = findEntry(key);
+
+ if (entry == NULL) {
+ value = NULL;
+ return FALSE;
+ }
+ else {
+ value = entry->value;
+ return TRUE;
+ }
+}
+
+QvDictEntry *&
+QvDict::findEntry(u_long key) const
+{
+ QvDictEntry **entry;
+
+ entry = &buckets[key % tableSize];
+
+ while (*entry != NULL) {
+ if ((*entry)->key == key)
+ break;
+ entry = &(*entry)->next;
+ }
+ return *entry;
+}
+
+QvBool
+QvDict::remove(u_long key)
+{
+ QvDictEntry *&entry = findEntry(key);
+ QvDictEntry *tmp;
+
+ if (entry == NULL)
+ return FALSE;
+ else {
+ tmp = entry;
+ entry = entry->next;
+ delete tmp;
+ return TRUE;
+ }
+}
diff --git a/tool_src/QvLib/QvDict.h b/tool_src/QvLib/QvDict.h
new file mode 100644
index 0000000..3a3aebe
--- /dev/null
+++ b/tool_src/QvLib/QvDict.h
@@ -0,0 +1,33 @@
+#ifndef _QV_DICT_
+#define _QV_DICT_
+
+#include <QvBasic.h>
+#include <QvString.h>
+#include <QvPList.h>
+
+class QvDictEntry {
+ private:
+ u_long key;
+ void * value;
+ QvDictEntry * next;
+ QvDictEntry(u_long k, void *v) { key = k; value = v; };
+
+friend class QvDict;
+};
+
+class QvDict {
+ public:
+ QvDict( int entries = 251 );
+ ~QvDict();
+ void clear();
+ QvBool enter(u_long key, void *value);
+ QvBool find(u_long key, void *&value) const;
+ QvBool remove(u_long key);
+
+ private:
+ int tableSize;
+ QvDictEntry * *buckets;
+ QvDictEntry *& findEntry(u_long key) const;
+};
+
+#endif /* _QV_DICT_ */
diff --git a/tool_src/QvLib/QvDirectionalLight.cpp b/tool_src/QvLib/QvDirectionalLight.cpp
new file mode 100644
index 0000000..b1e53d3
--- /dev/null
+++ b/tool_src/QvLib/QvDirectionalLight.cpp
@@ -0,0 +1,25 @@
+#include <QvDirectionalLight.h>
+
+QV_NODE_SOURCE(QvDirectionalLight);
+
+QvDirectionalLight::QvDirectionalLight()
+{
+ QV_NODE_CONSTRUCTOR(QvDirectionalLight);
+ isBuiltIn = TRUE;
+
+ QV_NODE_ADD_FIELD(on);
+ QV_NODE_ADD_FIELD(intensity);
+ QV_NODE_ADD_FIELD(color);
+ QV_NODE_ADD_FIELD(direction);
+
+ on.value = TRUE;
+ intensity.value = 1.0;
+ color.value[0] = color.value[1] = color.value[2] = 1.0;
+ direction.value[0] = 0.0;
+ direction.value[1] = 0.0;
+ direction.value[2] = -1.0;
+}
+
+QvDirectionalLight::~QvDirectionalLight()
+{
+}
diff --git a/tool_src/QvLib/QvDirectionalLight.h b/tool_src/QvLib/QvDirectionalLight.h
new file mode 100644
index 0000000..cd5e22d
--- /dev/null
+++ b/tool_src/QvLib/QvDirectionalLight.h
@@ -0,0 +1,22 @@
+#ifndef _QV_DIRECTIONAL_LIGHT_
+#define _QV_DIRECTIONAL_LIGHT_
+
+#include <QvSFBool.h>
+#include <QvSFColor.h>
+#include <QvSFFloat.h>
+#include <QvSFVec3f.h>
+#include <QvSubNode.h>
+
+class QvDirectionalLight : public QvNode {
+
+ QV_NODE_HEADER(QvDirectionalLight);
+
+ public:
+ // Fields
+ QvSFBool on; // Whether light is on
+ QvSFFloat intensity; // Source intensity (0 to 1)
+ QvSFColor color; // RGB source color
+ QvSFVec3f direction; // Illumination direction vector
+};
+
+#endif /* _QV_DIRECTIONAL_LIGHT_ */
diff --git a/tool_src/QvLib/QvElement.cpp b/tool_src/QvLib/QvElement.cpp
new file mode 100644
index 0000000..28ddb88
--- /dev/null
+++ b/tool_src/QvLib/QvElement.cpp
@@ -0,0 +1,38 @@
+#include <QvElement.h>
+
+const char *QvElement::nodeTypeNames[NumNodeTypes] = {
+ "Unknown",
+ "OrthographicCamera",
+ "PerspectiveCamera",
+ "DirectionalLight",
+ "PointLight",
+ "SpotLight",
+ "NoOpTransform",
+ "MatrixTransform",
+ "Rotation",
+ "Scale",
+ "Transform",
+ "Translation",
+};
+
+QvElement::QvElement()
+{
+ // These will be set to something real when the element is
+ // added to the state
+ depth = -1;
+ next = NULL;
+
+ // Presumably, the caller will set these
+ data = NULL;
+ type = Unknown;
+}
+
+QvElement::~QvElement()
+{
+}
+
+void
+QvElement::print()
+{
+ printf("\t\tElement of type %s\n", nodeTypeNames[type]);
+}
diff --git a/tool_src/QvLib/QvElement.h b/tool_src/QvLib/QvElement.h
new file mode 100644
index 0000000..58c5ce1
--- /dev/null
+++ b/tool_src/QvLib/QvElement.h
@@ -0,0 +1,62 @@
+#ifndef _QV_ELEMENT_
+#define _QV_ELEMENT_
+
+#include <QvBasic.h>
+
+class QvNode;
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// The base class element; the data is a pointer to some QvNode. The
+// type of the node can be inferred from the use of the element
+// instance in a particular stack in the state. In some cases, the
+// "type" field is used to distinguish among various possible node
+// types within a single stack.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+class QvElement {
+
+ public:
+
+ enum NodeType {
+ // Fallback case
+ Unknown,
+
+ // Types of cameras in camera stack
+ OrthographicCamera,
+ PerspectiveCamera,
+
+ // Types of lights in light stack
+ DirectionalLight,
+ PointLight,
+ SpotLight,
+
+ // Types of transformations in transformation stack
+ NoOpTransform, // For QvTransformSeparator
+ MatrixTransform,
+ Rotation,
+ Scale,
+ Transform,
+ Translation,
+
+ // This has to be last!!!
+ NumNodeTypes,
+ };
+
+ static const char *nodeTypeNames[NumNodeTypes]; // Names of node types
+
+ int depth; // Depth of element in state
+ QvElement *next; // Next element in stack
+ QvNode *data; // Pointer to node containing data
+ NodeType type; // Type of data node
+
+ QvElement();
+ virtual ~QvElement();
+
+ QvElement operator= (QvElement * x){ return *x;}
+ // Prints contents for debugging, mostly
+ virtual void print();
+};
+
+#endif /* _QV_ELEMENT_ */
diff --git a/tool_src/QvLib/QvField.cpp b/tool_src/QvLib/QvField.cpp
new file mode 100644
index 0000000..e682dda
--- /dev/null
+++ b/tool_src/QvLib/QvField.cpp
@@ -0,0 +1,175 @@
+#include <QvInput.h>
+#include <QvReadError.h>
+#include <QvFields.h>
+
+// Special characters in files
+#define OPEN_BRACE_CHAR '['
+#define CLOSE_BRACE_CHAR ']'
+#define VALUE_SEPARATOR_CHAR ','
+#define IGNORE_CHAR '~'
+
+QvField::~QvField()
+{
+}
+
+void
+QvField::setContainer(QvNode *cont)
+{
+ container = cont;
+ setDefault(TRUE);
+}
+
+QvBool
+QvField::read(QvInput *in, const QvName &name)
+{
+ char c;
+
+ setDefault(FALSE);
+
+ if (in->read(c) && c == IGNORE_CHAR) {
+ setDefault(TRUE);
+ setIgnored(TRUE);
+ }
+
+ else {
+ setIgnored(FALSE);
+
+ in->putBack(c);
+
+ if (! readValue(in)) {
+ QvReadError::post(in, "Couldn't read value for field \"%s\"",
+ name.getString());
+ return FALSE;
+ }
+
+ if (in->read(c)) {
+ if (c == IGNORE_CHAR)
+ setIgnored(TRUE);
+ else
+ in->putBack(c);
+ }
+ }
+
+ return TRUE;
+}
+
+QvField *
+QvField::createInstanceFromName(const QvName &className)
+{
+#define TRY_CLASS(name, class) \
+ else if (className == name) \
+ inst = new class
+
+ QvField *inst = NULL;
+
+ if (0) ; // So "else" works in first TRY_CLASS
+
+ TRY_CLASS("MFColor", QvMFColor);
+ TRY_CLASS("MFFloat", QvMFFloat);
+ TRY_CLASS("MFLong", QvMFLong);
+ TRY_CLASS("MFVec2f", QvMFVec2f);
+ TRY_CLASS("MFVec3f", QvMFVec3f);
+ TRY_CLASS("SFBitMask", QvSFBitMask);
+ TRY_CLASS("SFBool", QvSFBool);
+ TRY_CLASS("SFColor", QvSFColor);
+ TRY_CLASS("SFEnum", QvSFEnum);
+ TRY_CLASS("SFFloat", QvSFFloat);
+ TRY_CLASS("SFImage", QvSFImage);
+ TRY_CLASS("SFLong", QvSFLong);
+ TRY_CLASS("SFMatrix", QvSFMatrix);
+ TRY_CLASS("SFRotation", QvSFRotation);
+ TRY_CLASS("SFString", QvSFString);
+ TRY_CLASS("SFVec2f", QvSFVec2f);
+ TRY_CLASS("SFVec3f", QvSFVec3f);
+
+ return inst;
+
+#undef TRY_CLASS
+}
+
+QvSField::QvSField()
+{
+}
+
+
+QvSField::~QvSField()
+{
+}
+
+QvMField::QvMField()
+{
+ maxNum = num = 0;
+}
+
+QvMField::~QvMField()
+{
+}
+
+void
+QvMField::makeRoom(int newNum)
+{
+ if (newNum != num)
+ allocValues(newNum);
+}
+
+QvBool
+QvMField::readValue(QvInput *in)
+{
+ char c;
+ int curIndex = 0;
+
+ if (in->read(c) && c == OPEN_BRACE_CHAR) {
+
+ if (in->read(c) && c == CLOSE_BRACE_CHAR)
+ ;
+ else {
+ in->putBack(c);
+
+ while (TRUE) {
+
+ if (curIndex >= num)
+ makeRoom(curIndex + 1);
+
+ if (! read1Value(in, curIndex++) || ! in->read(c)) {
+ QvReadError::post(in, "Couldn't read value %d of field",
+ curIndex);
+ return FALSE;
+ }
+
+ if (c == VALUE_SEPARATOR_CHAR) {
+ if (in->read(c)) {
+ if (c == CLOSE_BRACE_CHAR)
+ break;
+ else
+ in->putBack(c);
+ }
+ }
+
+ else if (c == CLOSE_BRACE_CHAR)
+ break;
+
+ else {
+ QvReadError::post(in,
+ "Expected '%c' or '%c' but got "
+ "'%c' while reading value %d",
+ VALUE_SEPARATOR_CHAR,
+ CLOSE_BRACE_CHAR, c,
+ curIndex);
+ return FALSE;
+ }
+ }
+ }
+
+ if (curIndex < num)
+ makeRoom(curIndex);
+ }
+
+ else {
+ in->putBack(c);
+ makeRoom(1);
+ if (! read1Value(in, 0))
+ return FALSE;
+ }
+
+ return TRUE;
+}
diff --git a/tool_src/QvLib/QvField.h b/tool_src/QvLib/QvField.h
new file mode 100644
index 0000000..ff32ade
--- /dev/null
+++ b/tool_src/QvLib/QvField.h
@@ -0,0 +1,72 @@
+#ifndef _QV_FIELD_
+#define _QV_FIELD_
+
+#include <QvString.h>
+
+class QvInput;
+class QvNode;
+
+class QvField {
+ public:
+ virtual ~QvField();
+
+ void setIgnored(QvBool ig) { flags.ignored = ig; }
+ QvBool isIgnored() const { return flags.ignored; }
+
+ QvBool isDefault() const { return flags.hasDefault; }
+
+ QvNode * getContainer() const { return container; }
+
+ void setDefault(QvBool def) { flags.hasDefault = def; }
+ void setContainer(QvNode *cont);
+ QvBool read(QvInput *in, const QvName &name);
+
+ QvField() { flags.hasDefault = TRUE; flags.ignored = FALSE; }
+
+ public:
+
+ private:
+ struct {
+ unsigned int hasDefault : 1; // Field is set to default value
+ unsigned int ignored : 1; // Field value is to be ignored
+ } flags;
+
+ QvNode *container;
+
+ static QvField * createInstanceFromName(const QvName &className);
+ virtual QvBool readValue(QvInput *in) = 0;
+
+friend class QvFieldData;
+};
+
+class QvSField : public QvField {
+ public:
+ virtual ~QvSField();
+
+ protected:
+ QvSField();
+
+ private:
+ virtual QvBool readValue(QvInput *in) = 0;
+};
+
+class QvMField : public QvField {
+
+ public:
+ int num; // Number of values
+ int maxNum; // Number of values allocated
+
+ // Destructor
+ virtual ~QvMField();
+
+ protected:
+ QvMField();
+ virtual void makeRoom(int newNum);
+
+ private:
+ virtual void allocValues(int num) = 0;
+ virtual QvBool readValue(QvInput *in);
+ virtual QvBool read1Value(QvInput *in, int index) = 0;
+};
+
+#endif /* _QV_FIELD_ */
diff --git a/tool_src/QvLib/QvFieldData.cpp b/tool_src/QvLib/QvFieldData.cpp
new file mode 100644
index 0000000..afe55da
--- /dev/null
+++ b/tool_src/QvLib/QvFieldData.cpp
@@ -0,0 +1,266 @@
+#include <QvInput.h>
+#include <QvReadError.h>
+#include <QvField.h>
+#include <QvFieldData.h>
+#include <QvUnknownNode.h>
+
+#define OPEN_BRACE_CHAR '['
+#define CLOSE_BRACE_CHAR ']'
+#define VALUE_SEPARATOR_CHAR ','
+
+struct QvFieldEntry {
+ QvName name;
+ long offset;
+};
+
+struct QvEnumEntry {
+ QvName typeName;
+ int num;
+ int arraySize;
+ int *vals;
+ QvName *names;
+ QvEnumEntry(const QvName &name);
+ ~QvEnumEntry();
+
+ static int growSize;
+};
+
+int QvEnumEntry::growSize = 6;
+
+QvEnumEntry::QvEnumEntry(const QvName &name)
+{
+ typeName = name;
+ num = 0;
+ arraySize = growSize;
+ vals = new int[arraySize];
+ names = new QvName[arraySize];
+}
+
+QvEnumEntry::~QvEnumEntry()
+{
+ delete [] vals;
+ delete [] names;
+}
+
+QvFieldData::~QvFieldData()
+{
+ struct QvFieldEntry *tmpField;
+ struct QvEnumEntry *tmpEnum;
+
+ for (int i=0; i<fields.getLength(); i++) {
+ tmpField = (struct QvFieldEntry *)fields[i];
+ delete tmpField;
+ }
+
+ for (int j=0; j<enums.getLength(); j++) {
+ tmpEnum = (struct QvEnumEntry *)enums[j];
+ delete tmpEnum;
+ }
+}
+
+void
+QvFieldData::addField(QvNode *defobj, const char *fieldName,
+ const QvField *field)
+{
+ struct QvFieldEntry *newField = new struct QvFieldEntry;
+ newField->name = fieldName;
+ newField->offset = (const char *) field - (const char *) defobj;
+
+ fields.append((void *) newField);
+}
+
+const QvName &
+QvFieldData::getFieldName(int index) const
+{
+ return ((QvFieldEntry *) fields[index])->name;
+}
+
+QvField *
+QvFieldData::getField(const QvNode *object, int index) const
+{
+ return (QvField *) ((char *) object +
+ ((QvFieldEntry *) fields[index])->offset);
+}
+
+#include <ctype.h>
+static QvName
+stripWhite(const char *name)
+{
+ int firstchar = -1;
+ int lastchar = -1;
+ int lastwhite = -1;
+ int i =0;
+ for ( i=0; name[i]; i++) {
+ if (isspace(name[i]))
+ lastwhite = i;
+ else {
+ if (firstchar == -1) firstchar = i;
+ lastchar = i;
+ }
+ }
+
+ if (lastchar > lastwhite)
+ return QvName(&name[firstchar]);
+
+ char buf[500];
+ int b;
+ for (b=0, i=firstchar; i<=lastchar; i++, b++)
+ buf[b] = name[i];
+ buf[b] = 0;
+ return QvName(buf);
+}
+
+void
+QvFieldData::addEnumValue(const char *typeNameArg,
+ const char *valNameArg, int val)
+{
+ struct QvEnumEntry *e = NULL;
+ QvName typeName = stripWhite(typeNameArg);
+ QvName valName = stripWhite(valNameArg);
+
+ for (int i=0; i<enums.getLength(); i++) {
+ e = (struct QvEnumEntry *) enums[i];
+ if (e->typeName == typeName)
+ break;
+ else
+ e = NULL;
+ }
+ if (e == NULL) {
+ e = new QvEnumEntry(typeName);
+ enums.append((void*) e);
+ }
+ if (e->num == e->arraySize) {
+ e->arraySize += QvEnumEntry::growSize;
+ int *ovals = e->vals;
+ QvName *onames = e->names;
+ e->vals = new int[e->arraySize];
+ e->names = new QvName[e->arraySize];
+ for (int i=0; i<e->num; i++) {
+ e->vals[i] = ovals[i];
+ e->names[i] = onames[i];
+ }
+ delete [] ovals;
+ delete [] onames;
+ }
+ e->vals[e->num] = val;
+ e->names[e->num] = valName;
+ e->num++;
+}
+
+void
+QvFieldData::getEnumData(const char *typeNameArg, int &num,
+ const int *&vals, const QvName *&names)
+{
+ QvName typeName = stripWhite(typeNameArg);
+
+ for (int i=0; i<enums.getLength(); i++) {
+ struct QvEnumEntry *e = (struct QvEnumEntry *) enums[i];
+ if (e->typeName == typeName) {
+ num = e->num;
+ vals = e->vals;
+ names = e->names;
+ return;
+ }
+ }
+ num = 0;
+ vals = NULL;
+ names = NULL;
+}
+
+QvBool
+QvFieldData::readFieldTypes(QvInput *in, QvNode *object)
+{
+ QvBool gotChar;
+ QvName fieldType, fieldName;
+ char c;
+
+ if (! ((gotChar = in->read(c)) || c != OPEN_BRACE_CHAR))
+ return FALSE;
+
+ if (in->read(c) && c == CLOSE_BRACE_CHAR)
+ return TRUE;
+
+ in->putBack(c);
+
+ QvBool alreadyHasFields = (object->isBuiltIn || getNumFields() != 0);
+
+ while (TRUE) {
+
+ if (! in->read(fieldType, TRUE) || ! in->read(fieldName, TRUE))
+ return FALSE;
+
+ if (! alreadyHasFields) {
+ QvField *fld = QvField::createInstanceFromName(fieldType);
+ fld->setContainer(object);
+ addField(object, fieldName.getString(), fld);
+ }
+
+ if (! in->read(c))
+ return FALSE;
+ if (c == VALUE_SEPARATOR_CHAR) {
+
+ if (in->read(c)) {
+ if (c == CLOSE_BRACE_CHAR)
+ return TRUE;
+ else
+ in->putBack(c);
+ }
+ }
+ else if (c == CLOSE_BRACE_CHAR)
+ return TRUE;
+ else
+ return FALSE;
+ }
+}
+
+QvBool
+QvFieldData::read(QvInput *in, QvNode *object,
+ QvBool errorOnUnknownField) const
+{
+ QvName fieldName;
+
+ if (fields.getLength() == 0) return TRUE;
+
+ while (TRUE) {
+
+ if (! in->read(fieldName, TRUE) || ! fieldName)
+ return TRUE;
+
+ QvBool foundName;
+ if (! read(in, object, fieldName, foundName))
+ return FALSE;
+
+ if (!foundName) {
+ if (errorOnUnknownField) {
+ QvReadError::post(in, "Unknown field \"%s\"",
+ fieldName.getString());
+ return FALSE;
+ }
+ else {
+ in->putBack(fieldName.getString());
+ return TRUE;
+ }
+ }
+ }
+}
+
+QvBool
+QvFieldData::read(QvInput *in, QvNode *object,
+ const QvName &fieldName, QvBool &foundName) const
+{
+ int i = 0;
+ for ( i = 0; i < fields.getLength(); i++) {
+ QvName fni = getFieldName(i);
+
+ if (fieldName == fni) {
+ if (! getField(object, i)->read(in, fieldName))
+ return FALSE;
+ break;
+ }
+ }
+ if (i == fields.getLength())
+ foundName = FALSE;
+ else foundName = TRUE;
+
+ return TRUE;
+}
diff --git a/tool_src/QvLib/QvFieldData.h b/tool_src/QvLib/QvFieldData.h
new file mode 100644
index 0000000..3fb74d8
--- /dev/null
+++ b/tool_src/QvLib/QvFieldData.h
@@ -0,0 +1,46 @@
+#ifndef _QV_FIELD_DATA_
+#define _QV_FIELD_DATA_
+
+#include <QvBasic.h>
+#include <QvPList.h>
+#include <QvString.h>
+
+class QvField;
+class QvInput;
+class QvNode;
+
+class QvFieldData {
+ public:
+ QvFieldData() {}
+ ~QvFieldData();
+
+ void addField(QvNode *defObject, const char *fieldName,
+ const QvField *field);
+
+ int getNumFields() const { return fields.getLength(); }
+
+ const QvName & getFieldName(int index) const;
+
+ QvField * getField(const QvNode *object,
+ int index) const;
+
+ void addEnumValue(const char *typeName,
+ const char *valName, int val);
+ void getEnumData(const char *typeName, int &num,
+ const int *&vals, const QvName *&names);
+
+ QvBool read(QvInput *in, QvNode *object,
+ QvBool errorOnUnknownField = TRUE) const;
+
+ QvBool read(QvInput *in, QvNode *object,
+ const QvName &fieldName,
+ QvBool &foundName) const;
+
+ QvBool readFieldTypes(QvInput *in, QvNode *object);
+
+ private:
+ QvPList fields;
+ QvPList enums;
+};
+
+#endif /* _QV_FIELD_DATA_ */
diff --git a/tool_src/QvLib/QvFields.h b/tool_src/QvLib/QvFields.h
new file mode 100644
index 0000000..f731b0d
--- /dev/null
+++ b/tool_src/QvLib/QvFields.h
@@ -0,0 +1,23 @@
+#ifndef _QV_FIELDS_
+#define _QV_FIELDS_
+
+#include <QvMFColor.h>
+#include <QvMFFloat.h>
+#include <QvMFLong.h>
+#include <QvMFVec2f.h>
+#include <QvMFVec3f.h>
+
+#include <QvSFBitMask.h>
+#include <QvSFBool.h>
+#include <QvSFColor.h>
+#include <QvSFEnum.h>
+#include <QvSFFloat.h>
+#include <QvSFImage.h>
+#include <QvSFLong.h>
+#include <QvSFMatrix.h>
+#include <QvSFRotation.h>
+#include <QvSFString.h>
+#include <QvSFVec2f.h>
+#include <QvSFVec3f.h>
+
+#endif /* _QV_FIELDS_ */
diff --git a/tool_src/QvLib/QvGroup.cpp b/tool_src/QvLib/QvGroup.cpp
new file mode 100644
index 0000000..96795c5
--- /dev/null
+++ b/tool_src/QvLib/QvGroup.cpp
@@ -0,0 +1,81 @@
+#include <QvInput.h>
+#include <QvReadError.h>
+#include <QvFieldData.h>
+#include <QvChildList.h>
+#include <QvGroup.h>
+
+QV_NODE_SOURCE(QvGroup);
+
+QvGroup::QvGroup()
+{
+ children = new QvChildList();
+ QV_NODE_CONSTRUCTOR(QvGroup);
+ isBuiltIn = TRUE;
+}
+
+QvGroup::~QvGroup()
+{
+ delete children;
+}
+
+QvNode *
+QvGroup::getChild(int index) const
+{
+ return(*children)[index];
+}
+
+int
+QvGroup::getNumChildren() const
+{
+ return children->getLength();
+}
+
+QvChildList *
+QvGroup::getChildren() const
+{
+ return children;
+}
+
+QvBool
+QvGroup::readInstance(QvInput *in)
+{
+ QvName typeString;
+ QvFieldData *fieldData = getFieldData();
+
+ if (! isBuiltIn) {
+ if (in->read(typeString, TRUE)) {
+ if (typeString == "fields") {
+ if (! fieldData->readFieldTypes(in, this)) {
+ QvReadError::post(in, "Bad field specifications for node");
+ return FALSE;
+ }
+ }
+ else
+ in->putBack(typeString.getString());
+ }
+ }
+
+ return (fieldData->read(in, this, FALSE) && readChildren(in));
+}
+
+QvBool
+QvGroup::readChildren(QvInput *in)
+{
+ QvNode *child;
+ QvBool ret = TRUE;
+
+ while (TRUE) {
+ if (read(in, child)) {
+ if (child != NULL)
+ children->append(child);
+ else
+ break;
+ }
+ else {
+ ret = FALSE;
+ break;
+ }
+ }
+
+ return ret;
+}
diff --git a/tool_src/QvLib/QvGroup.h b/tool_src/QvLib/QvGroup.h
new file mode 100644
index 0000000..0cb092a
--- /dev/null
+++ b/tool_src/QvLib/QvGroup.h
@@ -0,0 +1,19 @@
+#ifndef _QV_GROUP_
+#define _QV_GROUP_
+
+class QvChildList;
+#include <QvSubNode.h>
+
+class QvGroup : public QvNode {
+
+ QV_NODE_HEADER(QvGroup);
+
+ public:
+ QvNode * getChild(int index) const;
+ int getNumChildren() const;
+ virtual QvChildList *getChildren() const;
+ virtual QvBool readInstance(QvInput *in);
+ virtual QvBool readChildren(QvInput *in);
+};
+
+#endif /* _QV_GROUP_ */
diff --git a/tool_src/QvLib/QvIndexedFaceSet.cpp b/tool_src/QvLib/QvIndexedFaceSet.cpp
new file mode 100644
index 0000000..c5cbe26
--- /dev/null
+++ b/tool_src/QvLib/QvIndexedFaceSet.cpp
@@ -0,0 +1,23 @@
+#include <QvIndexedFaceSet.h>
+
+QV_NODE_SOURCE(QvIndexedFaceSet);
+
+QvIndexedFaceSet::QvIndexedFaceSet()
+{
+ QV_NODE_CONSTRUCTOR(QvIndexedFaceSet);
+ isBuiltIn = TRUE;
+
+ QV_NODE_ADD_FIELD(coordIndex);
+ QV_NODE_ADD_FIELD(materialIndex);
+ QV_NODE_ADD_FIELD(normalIndex);
+ QV_NODE_ADD_FIELD(textureCoordIndex);
+
+ coordIndex.values[0] = 0;
+ materialIndex.values[0] = QV_END_FACE_INDEX;
+ normalIndex.values[0] = QV_END_FACE_INDEX;
+ textureCoordIndex.values[0] = QV_END_FACE_INDEX;
+}
+
+QvIndexedFaceSet::~QvIndexedFaceSet()
+{
+}
diff --git a/tool_src/QvLib/QvIndexedFaceSet.h b/tool_src/QvLib/QvIndexedFaceSet.h
new file mode 100644
index 0000000..ffe4a5b
--- /dev/null
+++ b/tool_src/QvLib/QvIndexedFaceSet.h
@@ -0,0 +1,21 @@
+#ifndef _QV_INDEXED_FACE_SET_
+#define _QV_INDEXED_FACE_SET_
+
+#include <QvMFLong.h>
+#include <QvSubNode.h>
+
+#define QV_END_FACE_INDEX (-1)
+
+class QvIndexedFaceSet : public QvNode {
+
+ QV_NODE_HEADER(QvIndexedFaceSet);
+
+ public:
+ // Fields:
+ QvMFLong coordIndex; // Coordinate indices
+ QvMFLong materialIndex; // Material indices
+ QvMFLong normalIndex; // Surface normal indices
+ QvMFLong textureCoordIndex; // Texture Coordinate indices
+};
+
+#endif /* _QV_INDEXED_FACE_SET_ */
diff --git a/tool_src/QvLib/QvIndexedLineSet.cpp b/tool_src/QvLib/QvIndexedLineSet.cpp
new file mode 100644
index 0000000..79c10a6
--- /dev/null
+++ b/tool_src/QvLib/QvIndexedLineSet.cpp
@@ -0,0 +1,23 @@
+#include <QvIndexedLineSet.h>
+
+QV_NODE_SOURCE(QvIndexedLineSet);
+
+QvIndexedLineSet::QvIndexedLineSet()
+{
+ QV_NODE_CONSTRUCTOR(QvIndexedLineSet);
+ isBuiltIn = TRUE;
+
+ QV_NODE_ADD_FIELD(coordIndex);
+ QV_NODE_ADD_FIELD(materialIndex);
+ QV_NODE_ADD_FIELD(normalIndex);
+ QV_NODE_ADD_FIELD(textureCoordIndex);
+
+ coordIndex.values[0] = 0;
+ materialIndex.values[0] = QV_END_LINE_INDEX;
+ normalIndex.values[0] = QV_END_LINE_INDEX;
+ textureCoordIndex.values[0] = QV_END_LINE_INDEX;
+}
+
+QvIndexedLineSet::~QvIndexedLineSet()
+{
+}
diff --git a/tool_src/QvLib/QvIndexedLineSet.h b/tool_src/QvLib/QvIndexedLineSet.h
new file mode 100644
index 0000000..cfcecd7
--- /dev/null
+++ b/tool_src/QvLib/QvIndexedLineSet.h
@@ -0,0 +1,21 @@
+#ifndef _QV_INDEXED_LINE_SET_
+#define _QV_INDEXED_LINE_SET_
+
+#include <QvMFLong.h>
+#include <QvSubNode.h>
+
+#define QV_END_LINE_INDEX (-1)
+
+class QvIndexedLineSet : public QvNode {
+
+ QV_NODE_HEADER(QvIndexedLineSet);
+
+ public:
+ // Fields:
+ QvMFLong coordIndex; // Coordinate indices
+ QvMFLong materialIndex; // Material indices
+ QvMFLong normalIndex; // Surline normal indices
+ QvMFLong textureCoordIndex; // Texture Coordinate indices
+};
+
+#endif /* _QV_INDEXED_LINE_SET_ */
diff --git a/tool_src/QvLib/QvInfo.cpp b/tool_src/QvLib/QvInfo.cpp
new file mode 100644
index 0000000..4ab54fc
--- /dev/null
+++ b/tool_src/QvLib/QvInfo.cpp
@@ -0,0 +1,17 @@
+#include <QvInfo.h>
+
+QV_NODE_SOURCE(QvInfo);
+
+QvInfo::QvInfo()
+{
+ QV_NODE_CONSTRUCTOR(QvInfo);
+ isBuiltIn = TRUE;
+
+ QV_NODE_ADD_FIELD(string);
+
+ string.value = "<Undefined info>";
+}
+
+QvInfo::~QvInfo()
+{
+}
diff --git a/tool_src/QvLib/QvInfo.h b/tool_src/QvLib/QvInfo.h
new file mode 100644
index 0000000..4173253
--- /dev/null
+++ b/tool_src/QvLib/QvInfo.h
@@ -0,0 +1,16 @@
+#ifndef _QV_INFO_
+#define _QV_INFO_
+
+#include <QvSFString.h>
+#include <QvSubNode.h>
+
+class QvInfo : public QvNode {
+
+ QV_NODE_HEADER(QvInfo);
+
+ public:
+ // Fields
+ QvSFString string; // Info string
+};
+
+#endif /* _QV_INFO_ */
diff --git a/tool_src/QvLib/QvInput.cpp b/tool_src/QvLib/QvInput.cpp
new file mode 100644
index 0000000..2f77669
--- /dev/null
+++ b/tool_src/QvLib/QvInput.cpp
@@ -0,0 +1,568 @@
+#include <ctype.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <QvInput.h>
+#include <QvDebugError.h>
+#include <QvReadError.h>
+#include <QvNode.h>
+
+#define CURVERSION 1.0 // Current version of file format
+#define COMMENT_CHAR '#'
+
+static const int numValidASCIIHeaders = 1;
+struct headerStorage
+{
+ const char *string;
+ float version;
+};
+
+static const headerStorage ASCIIHeader[1] = {
+ { "#VRML V1.0 ascii", /* 20 chars */ 1.0 },
+};
+
+float
+QvInput::isASCIIHeader(const char *string)
+{
+ for (int i = 0; i < numValidASCIIHeaders; i++) {
+ if (strcmp(ASCIIHeader[i].string, string) == 0)
+ return ASCIIHeader[i].version;
+ }
+ return FALSE;
+}
+
+QvInput::QvInput()
+{
+ setFilePointer(stdin);
+}
+
+QvInput::~QvInput()
+{
+}
+
+void
+QvInput::setFilePointer(FILE *newFP)
+{
+ fp = newFP;
+ lineNum = 1;
+ version = CURVERSION;
+ readHeader = FALSE;
+ headerOk = TRUE;
+ backBufIndex = -1;
+}
+
+float
+QvInput::getVersion()
+{
+ if (! readHeader)
+ (void) checkHeader();
+
+ return version;
+}
+
+QvBool
+QvInput::get(char &c)
+{
+ QvBool ret;
+
+ if (backBufIndex >= 0) {
+ c = backBuf.getString()[backBufIndex++];
+
+ if (c != '\0')
+ return TRUE;
+
+ backBuf.makeEmpty();
+ backBufIndex = -1;
+ }
+
+ if (! readHeader && ! checkHeader())
+ return FALSE;
+
+ if (eof()) {
+ c = (char)EOF;
+ ret = FALSE;
+ }
+
+ else {
+ int i = getc(fp);
+
+ if (i == EOF) {
+ c = (char)EOF;
+ ret = FALSE;
+ }
+ else {
+ c = (char) i;
+ ret = TRUE;
+ }
+ }
+
+ return ret;
+}
+
+QvBool
+QvInput::read(char &c)
+{
+ return (skipWhiteSpace() && get(c));
+}
+
+QvBool
+QvInput::read(QvString &s)
+{
+ if (! skipWhiteSpace())
+ return FALSE;
+
+ QvBool quoted;
+ char c;
+ char bufStore[256];
+ char *buf;
+ int bytesLeft;
+
+ s.makeEmpty();
+
+ if (! get(c))
+ return FALSE;
+
+ quoted = (c == '\"');
+ if (! quoted)
+ putBack(c);
+
+ do {
+ buf = bufStore;
+ bytesLeft = sizeof(bufStore) - 1;
+
+ while (bytesLeft > 0) {
+
+ if (! get(*buf))
+ break;
+
+ if (quoted) {
+ if (*buf == '\"')
+ break;
+
+ if (*buf == '\\') {
+ if ((get(c)) && c == '\"')
+ *buf = '\"';
+ else
+ putBack(c);
+ }
+
+ if (*buf == '\n')
+ lineNum++;
+ }
+
+ else if (isspace(*buf)) {
+ putBack(*buf);
+ break;
+ }
+
+ buf++;
+ bytesLeft--;
+ }
+ *buf = '\0';
+
+ s += bufStore;
+
+ } while (bytesLeft == 0);
+
+ return TRUE;
+}
+
+QvBool
+QvInput::read(QvName &n, QvBool validIdent)
+{
+ QvBool gotChar;
+
+ if (! skipWhiteSpace())
+ return FALSE;
+
+ if (! validIdent) {
+ QvString s;
+
+ if (! read(s))
+ return FALSE;
+
+ n = s;
+ }
+
+ else {
+ char buf[256];
+ char *b = buf;
+ char c;
+
+ if ((gotChar = get(c)) && QvName::isIdentStartChar(c)) {
+ *b++ = c;
+
+ while ((gotChar = get(c)) && QvName::isIdentChar(c)) {
+ if (b - buf < 255)
+ *b++ = c;
+ }
+ }
+ *b = '\0';
+
+ if (gotChar)
+ putBack(c);
+
+ n = buf;
+ }
+
+ return TRUE;
+}
+
+#define READ_NUM(reader, readType, num, type) \
+ QvBool ok; \
+ if (! skipWhiteSpace()) \
+ ok = FALSE; \
+ else { \
+ readType _tmp; \
+ ok = reader(_tmp); \
+ if (ok) \
+ num = (type) _tmp; \
+ } \
+ return ok
+
+#define READ_INTEGER(num, type) \
+ READ_NUM(readInteger, long, num, type)
+
+#define READ_UNSIGNED_INTEGER(num, type) \
+ READ_NUM(readUnsignedInteger, unsigned long, num, type)
+
+#define READ_REAL(num, type) \
+ READ_NUM(readReal, double, num, type)
+
+QvBool
+QvInput::read(int &i)
+{
+ READ_INTEGER(i, int);
+}
+
+QvBool
+QvInput::read(unsigned int &i)
+{
+ READ_UNSIGNED_INTEGER(i, unsigned int);
+}
+
+QvBool
+QvInput::read(short &s)
+{
+ READ_INTEGER(s, short);
+}
+
+QvBool
+QvInput::read(unsigned short &s)
+{
+ READ_UNSIGNED_INTEGER(s, unsigned short);
+}
+
+QvBool
+QvInput::read(long &l)
+{
+ READ_INTEGER(l, long);
+}
+
+QvBool
+QvInput::read(unsigned long &l)
+{
+ READ_UNSIGNED_INTEGER(l, unsigned long);
+}
+
+QvBool
+QvInput::read(float &f)
+{
+ READ_REAL(f, float);
+}
+
+QvBool
+QvInput::read(double &d)
+{
+ READ_REAL(d, double);
+}
+
+QvBool
+QvInput::eof() const
+{
+ return feof(fp);
+}
+
+void
+QvInput::getLocationString(QvString &string) const
+{
+ char buf[128];
+ sprintf(buf, "\tOccurred at line %3d", lineNum);
+ string = buf;
+}
+
+void
+QvInput::putBack(char c)
+{
+ if (c == (char) EOF)
+ return;
+
+ if (backBufIndex >= 0)
+ --backBufIndex;
+ else
+ ungetc(c, fp);
+}
+
+void
+QvInput::putBack(const char *string)
+{
+ backBuf = string;
+ backBufIndex = 0;
+}
+
+QvBool
+QvInput::checkHeader()
+{
+ char c;
+
+ readHeader = TRUE;
+
+ if (get(c)) {
+ if (c == COMMENT_CHAR) {
+ char buf[256];
+ int i = 0;
+
+ buf[i++] = c;
+ while (get(c) && c != '\n')
+ buf[i++] = c;
+ buf[i] = '\0';
+ if (c == '\n')
+ lineNum++;
+
+ if ((version = isASCIIHeader(buf)))
+ return TRUE;
+ }
+
+ else
+ putBack(c);
+ }
+
+ QvReadError::post(this, "File does not have a valid header string");
+ headerOk = FALSE;
+ return FALSE;
+}
+
+QvBool
+QvInput::skipWhiteSpace()
+{
+ char c;
+ QvBool gotChar;
+
+ if (! readHeader && ! checkHeader())
+ return FALSE;
+
+ while (TRUE) {
+
+ while ((gotChar = get(c)) && isspace(c))
+ if (c == '\n')
+ lineNum++;
+
+ if (! gotChar)
+ break;
+
+ if (c == COMMENT_CHAR) {
+ while (get(c) && c != '\n')
+ ;
+
+ if (eof())
+ QvReadError::post(this, "EOF reached before end of comment");
+ else
+ lineNum++;
+ }
+ else {
+ putBack(c);
+ break; }
+ }
+
+ return TRUE;
+}
+
+QvBool
+QvInput::readInteger(long &l)
+{
+ char str[32];
+ char *s = str;
+
+ if (readChar(s, '-') || readChar(s, '+'))
+ s++;
+
+ if (! readUnsignedIntegerString(s))
+ return FALSE;
+
+ l = strtol(str, NULL, 0);
+
+ return TRUE;
+}
+
+QvBool
+QvInput::readUnsignedInteger(unsigned long &l)
+{
+ char str[32];
+ if (! readUnsignedIntegerString(str))
+ return FALSE;
+
+ l = strtoul(str, NULL, 0);
+
+ return TRUE;
+}
+
+QvBool
+QvInput::readUnsignedIntegerString(char *str)
+{
+ int minSize = 1;
+ char *s = str;
+
+ if (readChar(s, '0')) {
+
+ if (readChar(s + 1, 'x')) {
+ s += 2 + readHexDigits(s + 2);
+ minSize = 3;
+ }
+
+ else
+ s += 1 + readDigits(s + 1);
+ }
+
+ else
+ s += readDigits(s);
+
+ if (s - str < minSize)
+ return FALSE;
+
+ *s = '\0';
+
+ return TRUE;
+}
+
+QvBool
+QvInput::readReal(double &d)
+{
+ char str[32];
+ int n;
+ char *s = str;
+ QvBool gotNum = FALSE;
+
+ n = readChar(s, '-');
+ if (n == 0)
+ n = readChar(s, '+');
+ s += n;
+
+ if ((n = readDigits(s)) > 0) {
+ gotNum = TRUE;
+ s += n;
+ }
+
+ if (readChar(s, '.') > 0) {
+ s++;
+
+ if ((n = readDigits(s)) > 0) {
+ gotNum = TRUE;
+ s += n;
+ }
+ }
+
+ if (! gotNum)
+ return FALSE;
+
+ n = readChar(s, 'e');
+ if (n == 0)
+ n = readChar(s, 'E');
+
+ if (n > 0) {
+ s += n;
+
+ n = readChar(s, '-');
+ if (n == 0)
+ n = readChar(s, '+');
+ s += n;
+
+ if ((n = readDigits(s)) > 0)
+ s += n;
+
+ else
+ return FALSE; }
+
+ *s = '\0';
+
+ d = atof(str);
+
+ return TRUE;
+}
+
+int
+QvInput::readDigits(char *string)
+{
+ char c, *s = string;
+
+ while (get(c)) {
+
+ if (isdigit(c))
+ *s++ = c;
+
+ else {
+ putBack(c);
+ break;
+ }
+ }
+
+ return s - string;
+}
+
+int
+QvInput::readHexDigits(char *string)
+{
+ char c, *s = string;
+
+ while (get(c)) {
+
+ if (isxdigit(c))
+ *s++ = c;
+
+ else {
+ putBack(c);
+ break;
+ }
+ }
+
+ return s - string;
+}
+
+int
+QvInput::readChar(char *string, char charToRead)
+{
+ char c;
+ int ret;
+
+ if (! get(c))
+ ret = 0;
+
+ else if (c == charToRead) {
+ *string = c;
+ ret = 1;
+ }
+
+ else {
+ putBack(c);
+ ret = 0;
+ }
+
+ return ret;
+}
+
+void
+QvInput::addReference(const QvName &name, QvNode *node)
+{
+ refDict.enter((u_long) name.getString(), (void *) node);
+
+ node->setName(name);
+}
+
+QvNode *
+QvInput::findReference(const QvName &name) const
+{
+ void *node;
+
+ if (refDict.find((u_long) name.getString(), node))
+ return (QvNode *) node;
+
+ return NULL;
+}
diff --git a/tool_src/QvLib/QvInput.h b/tool_src/QvLib/QvInput.h
new file mode 100644
index 0000000..f458aed
--- /dev/null
+++ b/tool_src/QvLib/QvInput.h
@@ -0,0 +1,65 @@
+#ifndef _QV_INPUT_
+#define _QV_INPUT_
+
+#include <QvDict.h>
+#include <QvString.h>
+
+class QvNode;
+class QvDB;
+
+class QvInput {
+ public:
+
+ QvInput();
+ ~QvInput();
+
+ static float isASCIIHeader(const char *string);
+ void setFilePointer(FILE *newFP);
+ FILE * getCurFile() const { return fp; }
+ float getVersion();
+ QvBool get(char &c);
+ QvBool read(char &c);
+ QvBool read(QvString &s);
+ QvBool read(QvName &n, QvBool validIdent = FALSE);
+ QvBool read(int &i);
+ QvBool read(unsigned int &i);
+ QvBool read(short &s);
+ QvBool read(unsigned short &s);
+ QvBool read(long &l);
+ QvBool read(unsigned long &l);
+ QvBool read(float &f);
+ QvBool read(double &d);
+ QvBool eof() const;
+ void getLocationString(QvString &string) const;
+ void putBack(char c);
+ void putBack(const char *string);
+ void addReference(const QvName &name, QvNode *node);
+ QvNode * findReference(const QvName &name) const;
+
+ private:
+ FILE *fp; // File pointer
+ int lineNum; // Number of line currently reading
+ float version; // Version number of file
+ QvBool readHeader; // TRUE if header was checked for A/B
+ QvBool headerOk; // TRUE if header was read ok
+ QvDict refDict; // Node reference dictionary
+ QvString backBuf;
+ int backBufIndex;
+
+ QvBool checkHeader();
+
+ QvBool skipWhiteSpace();
+
+ QvBool readInteger(long &l);
+ QvBool readUnsignedInteger(unsigned long &l);
+ QvBool readReal(double &d);
+ QvBool readUnsignedIntegerString(char *str);
+ int readDigits(char *string);
+ int readHexDigits(char *string);
+ int readChar(char *string, char charToRead);
+
+friend class QvNode;
+friend class QvDB;
+};
+
+#endif /* _QV_INPUT_ */
diff --git a/tool_src/QvLib/QvLevelOfDetail.cpp b/tool_src/QvLib/QvLevelOfDetail.cpp
new file mode 100644
index 0000000..28c1b48
--- /dev/null
+++ b/tool_src/QvLib/QvLevelOfDetail.cpp
@@ -0,0 +1,17 @@
+#include <QvLevelOfDetail.h>
+
+QV_NODE_SOURCE(QvLevelOfDetail);
+
+QvLevelOfDetail::QvLevelOfDetail()
+{
+ QV_NODE_CONSTRUCTOR(QvLevelOfDetail);
+ isBuiltIn = TRUE;
+
+ QV_NODE_ADD_FIELD(screenArea);
+
+ screenArea.values[0] = 0;
+}
+
+QvLevelOfDetail::~QvLevelOfDetail()
+{
+}
diff --git a/tool_src/QvLib/QvLevelOfDetail.h b/tool_src/QvLib/QvLevelOfDetail.h
new file mode 100644
index 0000000..8557cbb
--- /dev/null
+++ b/tool_src/QvLib/QvLevelOfDetail.h
@@ -0,0 +1,16 @@
+#ifndef _QV_LEVEL_OF_DETAIL_
+#define _QV_LEVEL_OF_DETAIL_
+
+#include <QvMFFloat.h>
+#include <QvGroup.h>
+
+class QvLevelOfDetail : public QvGroup {
+
+ QV_NODE_HEADER(QvLevelOfDetail);
+
+ public:
+ // Fields
+ QvMFFloat screenArea; // Areas to use for comparison
+};
+
+#endif /* _QV_LEVEL_OF_DETAIL_ */
diff --git a/tool_src/QvLib/QvLib.vcproj b/tool_src/QvLib/QvLib.vcproj
new file mode 100755
index 0000000..acd9d61
--- /dev/null
+++ b/tool_src/QvLib/QvLib.vcproj
@@ -0,0 +1,1765 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="7.10"
+ Name="QvLib"
+ SccProjectName="&quot;$/ParsecTools/QvLib&quot;"
+ SccLocalPath=".">
+ <Platforms>
+ <Platform
+ Name="Win32"/>
+ </Platforms>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory=".\Debug"
+ IntermediateDirectory=".\Debug"
+ ConfigurationType="4"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="FALSE"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="..\BspLib;..\QvLib"
+ PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="5"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderFile=".\Debug/QvLib.pch"
+ AssemblerListingLocation=".\Debug/"
+ ObjectFile=".\Debug/"
+ ProgramDataBaseFileName=".\Debug/"
+ WarningLevel="3"
+ SuppressStartupBanner="TRUE"
+ DebugInformationFormat="4"
+ CompileAs="0"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile=".\Debug\QvLib.lib"
+ SuppressStartupBanner="TRUE"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG"
+ Culture="3079"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory=".\Release"
+ IntermediateDirectory=".\Release"
+ ConfigurationType="4"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="FALSE"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ InlineFunctionExpansion="1"
+ AdditionalIncludeDirectories="..\BspLib;..\QvLib"
+ PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
+ StringPooling="TRUE"
+ RuntimeLibrary="4"
+ EnableFunctionLevelLinking="TRUE"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderFile=".\Release/QvLib.pch"
+ AssemblerListingLocation=".\Release/"
+ ObjectFile=".\Release/"
+ ProgramDataBaseFileName=".\Release/"
+ BrowseInformation="1"
+ WarningLevel="3"
+ SuppressStartupBanner="TRUE"
+ CompileAs="0"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile=".\Release\QvLib.lib"
+ SuppressStartupBanner="TRUE"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG"
+ Culture="3079"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <File
+ RelativePath="Qvbasic.h">
+ </File>
+ <File
+ RelativePath="QvChildList.cpp">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BasicRuntimeChecks="3"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BrowseInformation="1"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="Qvchildlist.h">
+ </File>
+ <File
+ RelativePath="QvCone.cpp">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BasicRuntimeChecks="3"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BrowseInformation="1"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="Qvcone.h">
+ </File>
+ <File
+ RelativePath="QvCoordinate3.cpp">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BasicRuntimeChecks="3"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BrowseInformation="1"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="Qvcoordinate3.h">
+ </File>
+ <File
+ RelativePath="QvCube.cpp">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BasicRuntimeChecks="3"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BrowseInformation="1"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="Qvcube.h">
+ </File>
+ <File
+ RelativePath="QvCylinder.cpp">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BasicRuntimeChecks="3"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BrowseInformation="1"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="Qvcylinder.h">
+ </File>
+ <File
+ RelativePath="QvDb.cpp">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BasicRuntimeChecks="3"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BrowseInformation="1"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="Qvdb.h">
+ </File>
+ <File
+ RelativePath="QvDebugError.cpp">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BasicRuntimeChecks="3"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BrowseInformation="1"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="Qvdebugerror.h">
+ </File>
+ <File
+ RelativePath="QvDict.cpp">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BasicRuntimeChecks="3"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BrowseInformation="1"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="Qvdict.h">
+ </File>
+ <File
+ RelativePath="QvDirectionalLight.cpp">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BasicRuntimeChecks="3"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BrowseInformation="1"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="Qvdirectionallight.h">
+ </File>
+ <File
+ RelativePath="QvElement.cpp">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BasicRuntimeChecks="3"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BrowseInformation="1"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="Qvelement.h">
+ </File>
+ <File
+ RelativePath="QvField.cpp">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BasicRuntimeChecks="3"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BrowseInformation="1"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="Qvfield.h">
+ </File>
+ <File
+ RelativePath="QvFieldData.cpp">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BasicRuntimeChecks="3"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BrowseInformation="1"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="Qvfielddata.h">
+ </File>
+ <File
+ RelativePath="Qvfields.h">
+ </File>
+ <File
+ RelativePath="QvGroup.cpp">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BasicRuntimeChecks="3"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BrowseInformation="1"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="Qvgroup.h">
+ </File>
+ <File
+ RelativePath="QvIndexedFaceSet.cpp">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BasicRuntimeChecks="3"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BrowseInformation="1"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="Qvindexedfaceset.h">
+ </File>
+ <File
+ RelativePath="QvIndexedLineSet.cpp">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BasicRuntimeChecks="3"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BrowseInformation="1"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="Qvindexedlineset.h">
+ </File>
+ <File
+ RelativePath="QvInfo.cpp">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BasicRuntimeChecks="3"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BrowseInformation="1"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="Qvinfo.h">
+ </File>
+ <File
+ RelativePath="QvInput.cpp">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BasicRuntimeChecks="3"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BrowseInformation="1"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="Qvinput.h">
+ </File>
+ <File
+ RelativePath="QvLevelOfDetail.cpp">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BasicRuntimeChecks="3"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BrowseInformation="1"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="Qvlevelofdetail.h">
+ </File>
+ <File
+ RelativePath="QvLists.cpp">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BasicRuntimeChecks="3"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BrowseInformation="1"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="Qvlists.h">
+ </File>
+ <File
+ RelativePath="QvMaterial.cpp">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BasicRuntimeChecks="3"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BrowseInformation="1"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="Qvmaterial.h">
+ </File>
+ <File
+ RelativePath="QvMaterialBinding.cpp">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BasicRuntimeChecks="3"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BrowseInformation="1"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="Qvmaterialbinding.h">
+ </File>
+ <File
+ RelativePath="QvMatrixTransform.cpp">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BasicRuntimeChecks="3"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BrowseInformation="1"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="Qvmatrixtransform.h">
+ </File>
+ <File
+ RelativePath="QvMFColor.cpp">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BasicRuntimeChecks="3"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BrowseInformation="1"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="Qvmfcolor.h">
+ </File>
+ <File
+ RelativePath="QvMFFloat.cpp">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BasicRuntimeChecks="3"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BrowseInformation="1"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="Qvmffloat.h">
+ </File>
+ <File
+ RelativePath="QvMFLong.cpp">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BasicRuntimeChecks="3"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BrowseInformation="1"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="Qvmflong.h">
+ </File>
+ <File
+ RelativePath="QvMFVec2f.cpp">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BasicRuntimeChecks="3"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BrowseInformation="1"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="Qvmfvec2f.h">
+ </File>
+ <File
+ RelativePath="QvMFVec3f.cpp">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BasicRuntimeChecks="3"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BrowseInformation="1"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="Qvmfvec3f.h">
+ </File>
+ <File
+ RelativePath="QvName.cpp">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BasicRuntimeChecks="3"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BrowseInformation="1"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="QvNode.cpp">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BasicRuntimeChecks="3"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BrowseInformation="1"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="Qvnode.h">
+ </File>
+ <File
+ RelativePath="Qvnodes.h">
+ </File>
+ <File
+ RelativePath="QvNormal.cpp">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BasicRuntimeChecks="3"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BrowseInformation="1"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="Qvnormal.h">
+ </File>
+ <File
+ RelativePath="QvNormalBinding.cpp">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BasicRuntimeChecks="3"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BrowseInformation="1"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="Qvnormalbinding.h">
+ </File>
+ <File
+ RelativePath="QvOrthographicCamera.cpp">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BasicRuntimeChecks="3"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BrowseInformation="1"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="Qvorthographiccamera.h">
+ </File>
+ <File
+ RelativePath="QvPerspectiveCamera.cpp">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BasicRuntimeChecks="3"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BrowseInformation="1"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="Qvperspectivecamera.h">
+ </File>
+ <File
+ RelativePath="QvPList.cpp">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BasicRuntimeChecks="3"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BrowseInformation="1"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="Qvplist.h">
+ </File>
+ <File
+ RelativePath="QvPointLight.cpp">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BasicRuntimeChecks="3"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BrowseInformation="1"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="Qvpointlight.h">
+ </File>
+ <File
+ RelativePath="QvPointSet.cpp">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BasicRuntimeChecks="3"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BrowseInformation="1"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="Qvpointset.h">
+ </File>
+ <File
+ RelativePath="QvReadError.cpp">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BasicRuntimeChecks="3"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BrowseInformation="1"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="Qvreaderror.h">
+ </File>
+ <File
+ RelativePath="QvRotation.cpp">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BasicRuntimeChecks="3"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BrowseInformation="1"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="Qvrotation.h">
+ </File>
+ <File
+ RelativePath="QvScale.cpp">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BasicRuntimeChecks="3"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BrowseInformation="1"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="Qvscale.h">
+ </File>
+ <File
+ RelativePath="QvSeparator.cpp">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BasicRuntimeChecks="3"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BrowseInformation="1"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="Qvseparator.h">
+ </File>
+ <File
+ RelativePath="QvSFBitMask.cpp">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BasicRuntimeChecks="3"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BrowseInformation="1"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="Qvsfbitmask.h">
+ </File>
+ <File
+ RelativePath="QvSFBool.cpp">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BasicRuntimeChecks="3"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BrowseInformation="1"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="Qvsfbool.h">
+ </File>
+ <File
+ RelativePath="QvSFColor.cpp">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BasicRuntimeChecks="3"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BrowseInformation="1"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="Qvsfcolor.h">
+ </File>
+ <File
+ RelativePath="QvSFEnum.cpp">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BasicRuntimeChecks="3"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BrowseInformation="1"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="Qvsfenum.h">
+ </File>
+ <File
+ RelativePath="QvSFFloat.cpp">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BasicRuntimeChecks="3"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BrowseInformation="1"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="Qvsffloat.h">
+ </File>
+ <File
+ RelativePath="QvSFImage.cpp">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BasicRuntimeChecks="3"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BrowseInformation="1"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="Qvsfimage.h">
+ </File>
+ <File
+ RelativePath="QvSFLong.cpp">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BasicRuntimeChecks="3"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BrowseInformation="1"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="Qvsflong.h">
+ </File>
+ <File
+ RelativePath="QvSFMatrix.cpp">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BasicRuntimeChecks="3"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BrowseInformation="1"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="Qvsfmatrix.h">
+ </File>
+ <File
+ RelativePath="QvSFRotation.cpp">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BasicRuntimeChecks="3"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BrowseInformation="1"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="Qvsfrotation.h">
+ </File>
+ <File
+ RelativePath="QvSFString.cpp">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BasicRuntimeChecks="3"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BrowseInformation="1"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="Qvsfstring.h">
+ </File>
+ <File
+ RelativePath="QvSFVec2f.cpp">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BasicRuntimeChecks="3"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BrowseInformation="1"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="Qvsfvec2f.h">
+ </File>
+ <File
+ RelativePath="QvSFVec3f.cpp">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BasicRuntimeChecks="3"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BrowseInformation="1"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="Qvsfvec3f.h">
+ </File>
+ <File
+ RelativePath="QvShapeHints.cpp">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BasicRuntimeChecks="3"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BrowseInformation="1"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="Qvshapehints.h">
+ </File>
+ <File
+ RelativePath="QvSphere.cpp">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BasicRuntimeChecks="3"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BrowseInformation="1"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="Qvsphere.h">
+ </File>
+ <File
+ RelativePath="QvSpotlight.cpp">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BasicRuntimeChecks="3"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BrowseInformation="1"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="Qvspotlight.h">
+ </File>
+ <File
+ RelativePath="QvState.cpp">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BasicRuntimeChecks="3"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BrowseInformation="1"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="Qvstate.h">
+ </File>
+ <File
+ RelativePath="QvString.cpp">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BasicRuntimeChecks="3"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BrowseInformation="1"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="Qvstring.h">
+ </File>
+ <File
+ RelativePath="Qvsubfield.h">
+ </File>
+ <File
+ RelativePath="Qvsubnode.h">
+ </File>
+ <File
+ RelativePath="QvSwitch.cpp">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BasicRuntimeChecks="3"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BrowseInformation="1"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="Qvswitch.h">
+ </File>
+ <File
+ RelativePath="QvTexture2.cpp">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BasicRuntimeChecks="3"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BrowseInformation="1"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="Qvtexture2.h">
+ </File>
+ <File
+ RelativePath="QvTexture2Transform.cpp">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BasicRuntimeChecks="3"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BrowseInformation="1"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="Qvtexture2transform.h">
+ </File>
+ <File
+ RelativePath="QvTextureCoordinate2.cpp">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BasicRuntimeChecks="3"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BrowseInformation="1"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="Qvtexturecoordinate2.h">
+ </File>
+ <File
+ RelativePath="QvTransform.cpp">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BasicRuntimeChecks="3"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BrowseInformation="1"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="Qvtransform.h">
+ </File>
+ <File
+ RelativePath="QvTransformSeparator.cpp">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BasicRuntimeChecks="3"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BrowseInformation="1"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="Qvtransformseparator.h">
+ </File>
+ <File
+ RelativePath="QvTranslation.cpp">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BasicRuntimeChecks="3"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BrowseInformation="1"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="Qvtranslation.h">
+ </File>
+ <File
+ RelativePath="QvTraverse.cpp">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BasicRuntimeChecks="3"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BrowseInformation="1"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="QvUnknownNode.cpp">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BasicRuntimeChecks="3"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BrowseInformation="1"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="Qvunknownnode.h">
+ </File>
+ <File
+ RelativePath="QvWWWAnchor.cpp">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BasicRuntimeChecks="3"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BrowseInformation="1"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="Qvwwwanchor.h">
+ </File>
+ <File
+ RelativePath="QvWWWInline.cpp">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BasicRuntimeChecks="3"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BrowseInformation="1"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="Qvwwwinline.h">
+ </File>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/tool_src/QvLib/QvLib.vcxproj b/tool_src/QvLib/QvLib.vcxproj
new file mode 100755
index 0000000..9951ca7
--- /dev/null
+++ b/tool_src/QvLib/QvLib.vcxproj
@@ -0,0 +1,597 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <SccProjectName>"$/ParsecTools/QvLib"</SccProjectName>
+ <SccLocalPath>.</SccLocalPath>
+ <ProjectGuid>{A7E24141-287A-4D83-9C15-8A7EDC9A02A2}</ProjectGuid>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <PlatformToolset>v110</PlatformToolset>
+ <UseOfMfc>false</UseOfMfc>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <PlatformToolset>v110</PlatformToolset>
+ <UseOfMfc>false</UseOfMfc>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <_ProjectFileVersion>11.0.50727.1</_ProjectFileVersion>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <OutDir>.\Debug\</OutDir>
+ <IntDir>.\Debug\</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <OutDir>.\Release\</OutDir>
+ <IntDir>.\Release\</IntDir>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\BspLib;..\QvLib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+ <PrecompiledHeader />
+ <PrecompiledHeaderOutputFile>.\Debug/QvLib.pch</PrecompiledHeaderOutputFile>
+ <AssemblerListingLocation>.\Debug/</AssemblerListingLocation>
+ <ObjectFileName>.\Debug/</ObjectFileName>
+ <ProgramDataBaseFileName>.\Debug/</ProgramDataBaseFileName>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
+ <CompileAs>Default</CompileAs>
+ </ClCompile>
+ <Lib>
+ <OutputFile>.\Debug\QvLib.lib</OutputFile>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </Lib>
+ <ResourceCompile>
+ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Culture>0x0c07</Culture>
+ </ResourceCompile>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <Optimization>MaxSpeed</Optimization>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <AdditionalIncludeDirectories>..\BspLib;..\QvLib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeader />
+ <PrecompiledHeaderOutputFile>.\Release/QvLib.pch</PrecompiledHeaderOutputFile>
+ <AssemblerListingLocation>.\Release/</AssemblerListingLocation>
+ <ObjectFileName>.\Release/</ObjectFileName>
+ <ProgramDataBaseFileName>.\Release/</ProgramDataBaseFileName>
+ <BrowseInformation>true</BrowseInformation>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <CompileAs>Default</CompileAs>
+ </ClCompile>
+ <Lib>
+ <OutputFile>.\Release\QvLib.lib</OutputFile>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </Lib>
+ <ResourceCompile>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Culture>0x0c07</Culture>
+ </ResourceCompile>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClInclude Include="Qvbasic.h" />
+ <ClInclude Include="Qvchildlist.h" />
+ <ClInclude Include="Qvcone.h" />
+ <ClInclude Include="Qvcoordinate3.h" />
+ <ClInclude Include="Qvcube.h" />
+ <ClInclude Include="Qvcylinder.h" />
+ <ClInclude Include="Qvdb.h" />
+ <ClInclude Include="Qvdebugerror.h" />
+ <ClInclude Include="Qvdict.h" />
+ <ClInclude Include="Qvdirectionallight.h" />
+ <ClInclude Include="Qvelement.h" />
+ <ClInclude Include="Qvfield.h" />
+ <ClInclude Include="Qvfielddata.h" />
+ <ClInclude Include="Qvfields.h" />
+ <ClInclude Include="Qvgroup.h" />
+ <ClInclude Include="Qvindexedfaceset.h" />
+ <ClInclude Include="Qvindexedlineset.h" />
+ <ClInclude Include="Qvinfo.h" />
+ <ClInclude Include="Qvinput.h" />
+ <ClInclude Include="Qvlevelofdetail.h" />
+ <ClInclude Include="Qvlists.h" />
+ <ClInclude Include="Qvmaterial.h" />
+ <ClInclude Include="Qvmaterialbinding.h" />
+ <ClInclude Include="Qvmatrixtransform.h" />
+ <ClInclude Include="Qvmfcolor.h" />
+ <ClInclude Include="Qvmffloat.h" />
+ <ClInclude Include="Qvmflong.h" />
+ <ClInclude Include="Qvmfvec2f.h" />
+ <ClInclude Include="Qvmfvec3f.h" />
+ <ClInclude Include="Qvnode.h" />
+ <ClInclude Include="Qvnodes.h" />
+ <ClInclude Include="Qvnormal.h" />
+ <ClInclude Include="Qvnormalbinding.h" />
+ <ClInclude Include="Qvorthographiccamera.h" />
+ <ClInclude Include="Qvperspectivecamera.h" />
+ <ClInclude Include="Qvplist.h" />
+ <ClInclude Include="Qvpointlight.h" />
+ <ClInclude Include="Qvpointset.h" />
+ <ClInclude Include="Qvreaderror.h" />
+ <ClInclude Include="Qvrotation.h" />
+ <ClInclude Include="Qvscale.h" />
+ <ClInclude Include="Qvseparator.h" />
+ <ClInclude Include="Qvsfbitmask.h" />
+ <ClInclude Include="Qvsfbool.h" />
+ <ClInclude Include="Qvsfcolor.h" />
+ <ClInclude Include="Qvsfenum.h" />
+ <ClInclude Include="Qvsffloat.h" />
+ <ClInclude Include="Qvsfimage.h" />
+ <ClInclude Include="Qvsflong.h" />
+ <ClInclude Include="Qvsfmatrix.h" />
+ <ClInclude Include="Qvsfrotation.h" />
+ <ClInclude Include="Qvsfstring.h" />
+ <ClInclude Include="Qvsfvec2f.h" />
+ <ClInclude Include="Qvsfvec3f.h" />
+ <ClInclude Include="Qvshapehints.h" />
+ <ClInclude Include="Qvsphere.h" />
+ <ClInclude Include="Qvspotlight.h" />
+ <ClInclude Include="Qvstate.h" />
+ <ClInclude Include="Qvstring.h" />
+ <ClInclude Include="Qvsubfield.h" />
+ <ClInclude Include="Qvsubnode.h" />
+ <ClInclude Include="Qvswitch.h" />
+ <ClInclude Include="Qvtexture2.h" />
+ <ClInclude Include="Qvtexture2transform.h" />
+ <ClInclude Include="Qvtexturecoordinate2.h" />
+ <ClInclude Include="Qvtransform.h" />
+ <ClInclude Include="Qvtransformseparator.h" />
+ <ClInclude Include="Qvtranslation.h" />
+ <ClInclude Include="Qvunknownnode.h" />
+ <ClInclude Include="Qvwwwanchor.h" />
+ <ClInclude Include="Qvwwwinline.h" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="QvChildList.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
+ </ClCompile>
+ <ClCompile Include="QvCone.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
+ </ClCompile>
+ <ClCompile Include="QvCoordinate3.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
+ </ClCompile>
+ <ClCompile Include="QvCube.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
+ </ClCompile>
+ <ClCompile Include="QvCylinder.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
+ </ClCompile>
+ <ClCompile Include="QvDb.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
+ </ClCompile>
+ <ClCompile Include="QvDebugError.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
+ </ClCompile>
+ <ClCompile Include="QvDict.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
+ </ClCompile>
+ <ClCompile Include="QvDirectionalLight.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
+ </ClCompile>
+ <ClCompile Include="QvElement.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
+ </ClCompile>
+ <ClCompile Include="QvField.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
+ </ClCompile>
+ <ClCompile Include="QvFieldData.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
+ </ClCompile>
+ <ClCompile Include="QvGroup.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
+ </ClCompile>
+ <ClCompile Include="QvIndexedFaceSet.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
+ </ClCompile>
+ <ClCompile Include="QvIndexedLineSet.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
+ </ClCompile>
+ <ClCompile Include="QvInfo.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
+ </ClCompile>
+ <ClCompile Include="QvInput.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
+ </ClCompile>
+ <ClCompile Include="QvLevelOfDetail.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
+ </ClCompile>
+ <ClCompile Include="QvLists.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
+ </ClCompile>
+ <ClCompile Include="QvMaterial.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
+ </ClCompile>
+ <ClCompile Include="QvMaterialBinding.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
+ </ClCompile>
+ <ClCompile Include="QvMatrixTransform.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
+ </ClCompile>
+ <ClCompile Include="QvMFColor.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
+ </ClCompile>
+ <ClCompile Include="QvMFFloat.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
+ </ClCompile>
+ <ClCompile Include="QvMFLong.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
+ </ClCompile>
+ <ClCompile Include="QvMFVec2f.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
+ </ClCompile>
+ <ClCompile Include="QvMFVec3f.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
+ </ClCompile>
+ <ClCompile Include="QvName.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
+ </ClCompile>
+ <ClCompile Include="QvNode.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
+ </ClCompile>
+ <ClCompile Include="QvNormal.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
+ </ClCompile>
+ <ClCompile Include="QvNormalBinding.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
+ </ClCompile>
+ <ClCompile Include="QvOrthographicCamera.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
+ </ClCompile>
+ <ClCompile Include="QvPerspectiveCamera.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
+ </ClCompile>
+ <ClCompile Include="QvPList.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
+ </ClCompile>
+ <ClCompile Include="QvPointLight.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
+ </ClCompile>
+ <ClCompile Include="QvPointSet.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
+ </ClCompile>
+ <ClCompile Include="QvReadError.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
+ </ClCompile>
+ <ClCompile Include="QvRotation.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
+ </ClCompile>
+ <ClCompile Include="QvScale.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
+ </ClCompile>
+ <ClCompile Include="QvSeparator.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
+ </ClCompile>
+ <ClCompile Include="QvSFBitMask.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
+ </ClCompile>
+ <ClCompile Include="QvSFBool.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
+ </ClCompile>
+ <ClCompile Include="QvSFColor.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
+ </ClCompile>
+ <ClCompile Include="QvSFEnum.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
+ </ClCompile>
+ <ClCompile Include="QvSFFloat.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
+ </ClCompile>
+ <ClCompile Include="QvSFImage.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
+ </ClCompile>
+ <ClCompile Include="QvSFLong.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
+ </ClCompile>
+ <ClCompile Include="QvSFMatrix.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
+ </ClCompile>
+ <ClCompile Include="QvSFRotation.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
+ </ClCompile>
+ <ClCompile Include="QvSFString.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
+ </ClCompile>
+ <ClCompile Include="QvSFVec2f.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
+ </ClCompile>
+ <ClCompile Include="QvSFVec3f.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
+ </ClCompile>
+ <ClCompile Include="QvShapeHints.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
+ </ClCompile>
+ <ClCompile Include="QvSphere.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
+ </ClCompile>
+ <ClCompile Include="QvSpotlight.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
+ </ClCompile>
+ <ClCompile Include="QvState.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
+ </ClCompile>
+ <ClCompile Include="QvString.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
+ </ClCompile>
+ <ClCompile Include="QvSwitch.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
+ </ClCompile>
+ <ClCompile Include="QvTexture2.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
+ </ClCompile>
+ <ClCompile Include="QvTexture2Transform.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
+ </ClCompile>
+ <ClCompile Include="QvTextureCoordinate2.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
+ </ClCompile>
+ <ClCompile Include="QvTransform.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
+ </ClCompile>
+ <ClCompile Include="QvTransformSeparator.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
+ </ClCompile>
+ <ClCompile Include="QvTranslation.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
+ </ClCompile>
+ <ClCompile Include="QvTraverse.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
+ </ClCompile>
+ <ClCompile Include="QvUnknownNode.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
+ </ClCompile>
+ <ClCompile Include="QvWWWAnchor.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
+ </ClCompile>
+ <ClCompile Include="QvWWWInline.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\BspLib\BspLib.vcxproj">
+ <Project>{aa6fab40-a936-486c-9db0-1addffcd4d00}</Project>
+ </ProjectReference>
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/tool_src/QvLib/QvLists.cpp b/tool_src/QvLib/QvLists.cpp
new file mode 100644
index 0000000..2c844a4
--- /dev/null
+++ b/tool_src/QvLib/QvLists.cpp
@@ -0,0 +1,5 @@
+#include <QvLists.h>
+
+QvNodeList::QvNodeList() : QvPList()
+{
+}
diff --git a/tool_src/QvLib/QvLists.h b/tool_src/QvLib/QvLists.h
new file mode 100644
index 0000000..7b9ec15
--- /dev/null
+++ b/tool_src/QvLib/QvLists.h
@@ -0,0 +1,17 @@
+#ifndef _QV_LISTS_
+#define _QV_LISTS_
+
+#include <QvPList.h>
+
+class QvField;
+class QvNode;
+
+class QvNodeList : public QvPList {
+ public:
+ QvNodeList();
+ ~QvNodeList() { truncate(0); }
+ QvNode * operator [](int i) const
+ { return ( (QvNode *) ( (*(const QvPList *) this) [i] ) ); }
+};
+
+#endif /* _QV_LISTS_ */
diff --git a/tool_src/QvLib/QvMFColor.cpp b/tool_src/QvLib/QvMFColor.cpp
new file mode 100644
index 0000000..10fbaeb
--- /dev/null
+++ b/tool_src/QvLib/QvMFColor.cpp
@@ -0,0 +1,13 @@
+#include <QvMFColor.h>
+
+QV_MFIELD_SOURCE(QvMFColor, float, 3);
+
+QvBool
+QvMFColor::read1Value(QvInput *in, int index)
+{
+ float *valuePtr = values + index * 3;
+
+ return (in->read(valuePtr[0]) &&
+ in->read(valuePtr[1]) &&
+ in->read(valuePtr[2]));
+}
diff --git a/tool_src/QvLib/QvMFColor.h b/tool_src/QvLib/QvMFColor.h
new file mode 100644
index 0000000..3950c2f
--- /dev/null
+++ b/tool_src/QvLib/QvMFColor.h
@@ -0,0 +1,12 @@
+#ifndef _QV_MF_COLOR_
+#define _QV_MF_COLOR_
+
+#include <QvSubField.h>
+
+class QvMFColor : public QvMField {
+ public:
+ float *values; // 3 per color
+ QV_MFIELD_HEADER(QvMFColor);
+};
+
+#endif /* _QV_MF_COLOR_ */
diff --git a/tool_src/QvLib/QvMFFloat.cpp b/tool_src/QvLib/QvMFFloat.cpp
new file mode 100644
index 0000000..240df46
--- /dev/null
+++ b/tool_src/QvLib/QvMFFloat.cpp
@@ -0,0 +1,9 @@
+#include <QvMFFloat.h>
+
+QV_MFIELD_SOURCE(QvMFFloat, float, 1);
+
+QvBool
+QvMFFloat::read1Value(QvInput *in, int index)
+{
+ return in->read(values[index]);
+}
diff --git a/tool_src/QvLib/QvMFFloat.h b/tool_src/QvLib/QvMFFloat.h
new file mode 100644
index 0000000..cf88135
--- /dev/null
+++ b/tool_src/QvLib/QvMFFloat.h
@@ -0,0 +1,12 @@
+#ifndef _QV_MF_FLOAT_
+#define _QV_MF_FLOAT_
+
+#include <QvSubField.h>
+
+class QvMFFloat : public QvMField {
+ public:
+ float *values;
+ QV_MFIELD_HEADER(QvMFFloat);
+};
+
+#endif /* _QV_MF_FLOAT_ */
diff --git a/tool_src/QvLib/QvMFLong.cpp b/tool_src/QvLib/QvMFLong.cpp
new file mode 100644
index 0000000..e0e069c
--- /dev/null
+++ b/tool_src/QvLib/QvMFLong.cpp
@@ -0,0 +1,9 @@
+#include <QvMFLong.h>
+
+QV_MFIELD_SOURCE(QvMFLong, long, 1);
+
+QvBool
+QvMFLong::read1Value(QvInput *in, int index)
+{
+ return in->read(values[index]);
+}
diff --git a/tool_src/QvLib/QvMFLong.h b/tool_src/QvLib/QvMFLong.h
new file mode 100644
index 0000000..4e092d6
--- /dev/null
+++ b/tool_src/QvLib/QvMFLong.h
@@ -0,0 +1,12 @@
+#ifndef _QV_MF_LONG_
+#define _QV_MF_LONG_
+
+#include <QvSubField.h>
+
+class QvMFLong : public QvMField {
+ public:
+ long *values;
+ QV_MFIELD_HEADER(QvMFLong);
+};
+
+#endif /* _QV_MF_LONG_ */
diff --git a/tool_src/QvLib/QvMFVec2f.cpp b/tool_src/QvLib/QvMFVec2f.cpp
new file mode 100644
index 0000000..2a265f5
--- /dev/null
+++ b/tool_src/QvLib/QvMFVec2f.cpp
@@ -0,0 +1,12 @@
+#include <QvMFVec2f.h>
+
+QV_MFIELD_SOURCE(QvMFVec2f, float, 2);
+
+QvBool
+QvMFVec2f::read1Value(QvInput *in, int index)
+{
+ float *valuePtr = values + index * 2;
+
+ return (in->read(valuePtr[0]) &&
+ in->read(valuePtr[1]));
+}
diff --git a/tool_src/QvLib/QvMFVec2f.h b/tool_src/QvLib/QvMFVec2f.h
new file mode 100644
index 0000000..56b8958
--- /dev/null
+++ b/tool_src/QvLib/QvMFVec2f.h
@@ -0,0 +1,12 @@
+#ifndef _QV_MF_VEC2F_
+#define _QV_MF_VEC2F_
+
+#include <QvSubField.h>
+
+class QvMFVec2f : public QvMField {
+ public:
+ float *values;
+ QV_MFIELD_HEADER(QvMFVec2f);
+};
+
+#endif /* _QV_MF_VEC2F_ */
diff --git a/tool_src/QvLib/QvMFVec3f.cpp b/tool_src/QvLib/QvMFVec3f.cpp
new file mode 100644
index 0000000..1022579
--- /dev/null
+++ b/tool_src/QvLib/QvMFVec3f.cpp
@@ -0,0 +1,13 @@
+#include <QvMFVec3f.h>
+
+QV_MFIELD_SOURCE(QvMFVec3f, float, 3);
+
+QvBool
+QvMFVec3f::read1Value(QvInput *in, int index)
+{
+ float *valuePtr = values + index * 3;
+
+ return (in->read(valuePtr[0]) &&
+ in->read(valuePtr[1]) &&
+ in->read(valuePtr[2]));
+}
diff --git a/tool_src/QvLib/QvMFVec3f.h b/tool_src/QvLib/QvMFVec3f.h
new file mode 100644
index 0000000..e3efd93
--- /dev/null
+++ b/tool_src/QvLib/QvMFVec3f.h
@@ -0,0 +1,12 @@
+#ifndef _QV_MF_VEC3F_
+#define _QV_MF_VEC3F_
+
+#include <QvSubField.h>
+
+class QvMFVec3f : public QvMField {
+ public:
+ float *values;
+ QV_MFIELD_HEADER(QvMFVec3f);
+};
+
+#endif /* _QV_MF_VEC3F_ */
diff --git a/tool_src/QvLib/QvMaterial.cpp b/tool_src/QvLib/QvMaterial.cpp
new file mode 100644
index 0000000..9b5bc43
--- /dev/null
+++ b/tool_src/QvLib/QvMaterial.cpp
@@ -0,0 +1,27 @@
+#include <QvMaterial.h>
+
+QV_NODE_SOURCE(QvMaterial);
+
+QvMaterial::QvMaterial()
+{
+ QV_NODE_CONSTRUCTOR(QvMaterial);
+ isBuiltIn = TRUE;
+
+ QV_NODE_ADD_FIELD(ambientColor);
+ QV_NODE_ADD_FIELD(diffuseColor);
+ QV_NODE_ADD_FIELD(specularColor);
+ QV_NODE_ADD_FIELD(emissiveColor);
+ QV_NODE_ADD_FIELD(shininess);
+ QV_NODE_ADD_FIELD(transparency);
+
+ ambientColor.values[0]=ambientColor.values[1]=ambientColor.values[2] = 0.2;
+ diffuseColor.values[0]=diffuseColor.values[1]=diffuseColor.values[2] = 0.2;
+ specularColor.values[0]=specularColor.values[1]=specularColor.values[2]=0.;
+ emissiveColor.values[0]=emissiveColor.values[1]=emissiveColor.values[2]=0.;
+ shininess.values[0] = 0.2;
+ transparency.values[0] = 0.0;
+}
+
+QvMaterial::~QvMaterial()
+{
+}
diff --git a/tool_src/QvLib/QvMaterial.h b/tool_src/QvLib/QvMaterial.h
new file mode 100644
index 0000000..3a15905
--- /dev/null
+++ b/tool_src/QvLib/QvMaterial.h
@@ -0,0 +1,22 @@
+#ifndef _QV_MATERIAL_
+#define _QV_MATERIAL_
+
+#include <QvMFColor.h>
+#include <QvMFFloat.h>
+#include <QvSubNode.h>
+
+class QvMaterial : public QvNode {
+
+ QV_NODE_HEADER(QvMaterial);
+
+ public:
+ // Fields
+ QvMFColor ambientColor; // Ambient color
+ QvMFColor diffuseColor; // Diffuse color
+ QvMFColor specularColor; // Specular color
+ QvMFColor emissiveColor; // Emissive color
+ QvMFFloat shininess; // Shininess
+ QvMFFloat transparency; // Transparency
+};
+
+#endif /* _QV_MATERIAL_ */
diff --git a/tool_src/QvLib/QvMaterialBinding.cpp b/tool_src/QvLib/QvMaterialBinding.cpp
new file mode 100644
index 0000000..f4289d4
--- /dev/null
+++ b/tool_src/QvLib/QvMaterialBinding.cpp
@@ -0,0 +1,31 @@
+#include <QvMaterialBinding.h>
+
+QV_NODE_SOURCE(QvMaterialBinding);
+
+
+QvMaterialBinding::QvMaterialBinding()
+{
+ QV_NODE_CONSTRUCTOR(QvMaterialBinding);
+ isBuiltIn = TRUE;
+
+ QV_NODE_ADD_FIELD(value);
+
+ value.value = DEFAULT;
+
+ QV_NODE_DEFINE_ENUM_VALUE(Binding, DEFAULT);
+ QV_NODE_DEFINE_ENUM_VALUE(Binding, NONE);
+ QV_NODE_DEFINE_ENUM_VALUE(Binding, OVERALL);
+ QV_NODE_DEFINE_ENUM_VALUE(Binding, PER_PART);
+ QV_NODE_DEFINE_ENUM_VALUE(Binding, PER_PART_INDEXED);
+ QV_NODE_DEFINE_ENUM_VALUE(Binding, PER_FACE);
+ QV_NODE_DEFINE_ENUM_VALUE(Binding, PER_FACE_INDEXED);
+ QV_NODE_DEFINE_ENUM_VALUE(Binding, PER_VERTEX);
+ QV_NODE_DEFINE_ENUM_VALUE(Binding, PER_VERTEX_INDEXED);
+
+ QV_NODE_SET_SF_ENUM_TYPE(value, Binding);
+}
+
+
+QvMaterialBinding::~QvMaterialBinding()
+{
+}
diff --git a/tool_src/QvLib/QvMaterialBinding.h b/tool_src/QvLib/QvMaterialBinding.h
new file mode 100644
index 0000000..138148e
--- /dev/null
+++ b/tool_src/QvLib/QvMaterialBinding.h
@@ -0,0 +1,28 @@
+#ifndef _QV_MATERIAL_BINDING_
+#define _QV_MATERIAL_BINDING_
+
+#include <QvSFEnum.h>
+#include <QvSubNode.h>
+
+class QvMaterialBinding : public QvNode {
+
+ QV_NODE_HEADER(QvMaterialBinding);
+
+ public:
+ enum Binding {
+ DEFAULT,
+ NONE,
+ OVERALL,
+ PER_PART,
+ PER_PART_INDEXED,
+ PER_FACE,
+ PER_FACE_INDEXED,
+ PER_VERTEX,
+ PER_VERTEX_INDEXED,
+ };
+
+ // Fields:
+ QvSFEnum value;
+};
+
+#endif /* _QV_MATERIAL_BINDING_ */
diff --git a/tool_src/QvLib/QvMatrixTransform.cpp b/tool_src/QvLib/QvMatrixTransform.cpp
new file mode 100644
index 0000000..dc3d7ae
--- /dev/null
+++ b/tool_src/QvLib/QvMatrixTransform.cpp
@@ -0,0 +1,20 @@
+#include <QvMatrixTransform.h>
+
+QV_NODE_SOURCE(QvMatrixTransform);
+
+
+QvMatrixTransform::QvMatrixTransform()
+{
+ QV_NODE_CONSTRUCTOR(QvMatrixTransform);
+ isBuiltIn = TRUE;
+
+ QV_NODE_ADD_FIELD(matrix);
+
+ for (int i = 0; i < 4; i++)
+ for (int j = 0; j < 4; j++)
+ matrix.value[i][j] = (i == j ? 1.0 : 0.0);
+}
+
+QvMatrixTransform::~QvMatrixTransform()
+{
+}
diff --git a/tool_src/QvLib/QvMatrixTransform.h b/tool_src/QvLib/QvMatrixTransform.h
new file mode 100644
index 0000000..a608cbf
--- /dev/null
+++ b/tool_src/QvLib/QvMatrixTransform.h
@@ -0,0 +1,16 @@
+#ifndef _QV_MATRIX_TRANSFORM_
+#define _QV_MATRIX_TRANSFORM_
+
+#include <QvSFMatrix.h>
+#include <QvSubNode.h>
+
+class QvMatrixTransform : public QvNode {
+
+ QV_NODE_HEADER(QvMatrixTransform);
+
+ public:
+ // Fields
+ QvSFMatrix matrix; // Transformation matrix
+};
+
+#endif /* _QV_MATRIX_TRANSFORM_ */
diff --git a/tool_src/QvLib/QvName.cpp b/tool_src/QvLib/QvName.cpp
new file mode 100644
index 0000000..626c6b8
--- /dev/null
+++ b/tool_src/QvLib/QvName.cpp
@@ -0,0 +1,126 @@
+#include <QvString.h>
+#include <ctype.h>
+
+#define CHUNK_SIZE 4000
+
+struct QvNameChunk {
+ char mem[CHUNK_SIZE];
+ char *curByte;
+ int bytesLeft;
+ struct QvNameChunk *next;
+};
+
+int QvNameEntry::nameTableSize;
+QvNameEntry ** QvNameEntry::nameTable;
+struct QvNameChunk *QvNameEntry::chunk;
+
+void
+QvNameEntry::initClass()
+{
+ int i;
+
+
+ nameTableSize = 1999;
+ nameTable = new QvNameEntry *[nameTableSize];
+
+ for (i = 0; i < nameTableSize; i++)
+ nameTable[i] = NULL;
+
+ chunk = NULL;
+}
+
+const QvNameEntry *
+QvNameEntry::insert(const char *s)
+{
+ u_long h = QvString::hash(s);
+ u_long i;
+ QvNameEntry *entry;
+ QvNameEntry *head;
+
+ if (nameTableSize == 0)
+ initClass();
+
+ i = h % nameTableSize;
+ entry = head = nameTable[i];
+
+ while (entry != NULL) {
+ if (entry->hashValue == h && entry->isEqual(s))
+ break;
+ entry = entry->next;
+ }
+
+ if (entry == NULL) {
+
+ int len = strlen(s) + 1;
+
+ if (len >= CHUNK_SIZE)
+ s = strdup(s);
+
+ else {
+
+ if (chunk == NULL || chunk->bytesLeft < len) {
+ struct QvNameChunk *newChunk = new QvNameChunk;
+
+ newChunk->curByte = newChunk->mem;
+ newChunk->bytesLeft = CHUNK_SIZE;
+ newChunk->next = chunk;
+
+ chunk = newChunk;
+ }
+
+ strcpy(chunk->curByte, s);
+ s = chunk->curByte;
+
+ chunk->curByte += len;
+ chunk->bytesLeft -= len;
+ }
+
+ entry = new QvNameEntry(s, h, head);
+ nameTable[i] = entry;
+ }
+
+ return entry;
+}
+
+QvName::QvName()
+{
+ entry = QvNameEntry::insert("");
+}
+
+QvBool
+QvName::isIdentStartChar(char c)
+{
+ if (isdigit(c)) return FALSE;
+
+ return isIdentChar(c);
+}
+
+QvBool
+QvName::isIdentChar(char c)
+{
+ if (isalnum(c) || c == '_') return TRUE;
+
+ return FALSE;
+}
+
+QvBool
+QvName::isNodeNameStartChar(char c)
+{
+ if (isdigit(c)) return FALSE;
+
+ return isIdentChar(c);
+}
+
+static const char
+badCharacters[] = "+\'\"\\{}";
+
+QvBool
+QvName::isNodeNameChar(char c)
+{
+ if (isalnum(c)) return TRUE;
+
+ if ((strchr(badCharacters, c) != NULL) ||
+ isspace(c) || iscntrl(c)) return FALSE;
+
+ return TRUE;
+}
diff --git a/tool_src/QvLib/QvNode.cpp b/tool_src/QvLib/QvNode.cpp
new file mode 100644
index 0000000..40fad6b
--- /dev/null
+++ b/tool_src/QvLib/QvNode.cpp
@@ -0,0 +1,381 @@
+#include <ctype.h>
+#include <QvDB.h>
+#include <QvInput.h>
+#include <QvDebugError.h>
+#include <QvReadError.h>
+#include <QvField.h>
+#include <QvFieldData.h>
+#include <QvNodes.h>
+#include <QvUnknownNode.h>
+
+// The global name dictionary
+QvDict *QvNode::nameDict = NULL;
+
+// Syntax for writing instances to files
+#define OPEN_BRACE '{'
+#define CLOSE_BRACE '}'
+#define DEFINITION_KEYWORD "DEF"
+#define REFERENCE_KEYWORD "USE"
+#define NULL_KEYWORD "NULL"
+
+void
+QvNode::init()
+{
+ if (nameDict == NULL)
+ nameDict = new QvDict;
+}
+
+QvNode::QvNode()
+{
+ objName = new QvName("");
+}
+
+QvNode::~QvNode()
+{
+ if (! !(*objName))
+ removeName(this, objName->getString());
+ delete objName;
+}
+
+const QvName &
+QvNode::getName() const
+{
+ return *objName;
+}
+
+void
+QvNode::setName(const QvName &newName)
+{
+ if (! !(*objName)) {
+ removeName(this, objName->getString());
+ }
+ delete objName;
+
+ const char *str = newName.getString();
+ QvBool isBad = 0;
+
+ if (newName.getLength() > 0 &&
+ !QvName::isNodeNameStartChar(str[0])) isBad = TRUE;
+
+ int i;
+ for (i = 1; i < newName.getLength() && !isBad; i++) {
+ isBad = !QvName::isNodeNameChar(str[i]);
+ }
+
+ if (isBad) {
+ QvString goodString;
+
+ if (!QvName::isNodeNameStartChar(str[0])) {
+ goodString += "_";
+ }
+ for (i = 0; i < newName.getLength(); i++) {
+ char temp[2];
+ temp[0] = str[i]; temp[1] = '\0';
+ if (!QvName::isNodeNameChar(str[i]))
+ goodString += "_";
+ else
+ goodString += temp;
+ }
+#ifdef DEBUG
+ QvDebugError::post("QvNode::setName", "Bad characters in"
+ " name '%s'. Replacing with name '%s'",
+ str, goodString.getString());
+#endif
+ objName = new QvName(goodString);
+ }
+ else {
+ objName = new QvName(newName);
+ }
+ if (! !(*objName)) {
+ addName(this, objName->getString());
+ }
+}
+
+void
+QvNode::addName(QvNode *b, const char *name)
+{
+ QvPList *list;
+ void *t;
+ if (!nameDict->find((u_long)name, t)) {
+ list = new QvPList;
+ nameDict->enter((u_long)name, list);
+ }
+ else {
+ list = (QvPList *)t;
+ }
+
+ list->append(b);
+}
+
+void
+QvNode::removeName(QvNode *b, const char *name)
+{
+ QvPList *list;
+ QvBool found;
+ void *t;
+ int i;
+
+ found = nameDict->find((u_long) name, t);
+
+ if (found) {
+ list = (QvPList *) t;
+ i = list->find(b);
+
+ if (i < 0)
+ found = FALSE;
+
+ else
+ list->remove(i);
+ }
+
+ if (! found)
+ QvDebugError::post("QvNode::removeName",
+ "Name \"%s\" (node %x) is not in dictionary",
+ name, b);
+}
+
+QvBool
+QvNode::read(QvInput *in, QvNode *&node)
+{
+ QvBool ret;
+ QvName name;
+
+ if (! in->read(name, TRUE)) {
+ node = NULL;
+ ret = in->headerOk;
+ }
+
+ else if (! name || name == NULL_KEYWORD) {
+ node = NULL;
+ ret = TRUE;
+ }
+
+ else if (name == REFERENCE_KEYWORD) {
+ node = readReference(in);
+ ret = (node != NULL);
+ }
+
+ else
+ ret = readNode(in, name, node);
+
+ return ret;
+}
+
+QvBool
+QvNode::readInstance(QvInput *in)
+{
+ QvName typeString;
+ QvFieldData *fieldData = getFieldData();
+
+ if (in->read(typeString, TRUE)) {
+ if (typeString == "fields") {
+ if (! fieldData->readFieldTypes(in, this)) {
+ QvReadError::post(in, "Bad field specifications for node");
+ return FALSE;
+ }
+ }
+ else
+ in->putBack(typeString.getString());
+ }
+
+ if (! fieldData->read(in, this))
+ return FALSE;
+
+ return TRUE;
+}
+
+QvNode *
+QvNode::readReference(QvInput *in)
+{
+ QvName refName;
+ QvNode *node;
+
+ if (! in->read(refName, FALSE)) {
+ QvReadError::post(in, "Premature end of file after "
+ REFERENCE_KEYWORD);
+ node = NULL;
+ }
+
+ else if ((node = in->findReference(refName)) == NULL)
+ QvReadError::post(in, "Unknown reference \"%s\"",
+ refName.getString());
+
+ return node;
+}
+
+QvBool
+QvNode::readNode(QvInput *in, QvName &className, QvNode *&node)
+{
+ QvBool gotChar;
+ QvName refName;
+ char c;
+ QvBool ret = TRUE, flush = FALSE;
+
+ node = NULL;
+
+ if (className == DEFINITION_KEYWORD) {
+ if (! in->read(refName, FALSE) || ! in->read(className, TRUE)) {
+ QvReadError::post(in, "Premature end of file after "
+ DEFINITION_KEYWORD);
+ ret = FALSE;
+ }
+
+ if (! refName) {
+ QvReadError::post(in, "No name given after ", DEFINITION_KEYWORD);
+ ret = FALSE;
+ }
+
+ if (! className) {
+ QvReadError::post(in, "Invalid definition of %s",
+ refName.getString());
+ ret = FALSE;
+ }
+ }
+
+ if (ret) {
+
+ if (! (gotChar = in->read(c)) || c != OPEN_BRACE) {
+ if (gotChar)
+ QvReadError::post(in, "Expected '%c'; got '%c'",
+ OPEN_BRACE, c);
+ else
+ QvReadError::post(in, "Expected '%c'; got EOF", OPEN_BRACE);
+ ret = FALSE;
+ }
+
+ else {
+ ret = readNodeInstance(in, className, refName, node);
+
+ if (! ret)
+ flush = TRUE;
+
+ else if (! (gotChar = in->read(c)) || c != CLOSE_BRACE) {
+ if (gotChar)
+ QvReadError::post(in, "Expected '%c'; got '%c'",
+ CLOSE_BRACE, c);
+ else
+ QvReadError::post(in, "Expected '%c'; got EOF",
+ CLOSE_BRACE);
+ ret = FALSE;
+ }
+ }
+ }
+
+ if (! ret && flush)
+ flushInput(in);
+
+ return ret;
+}
+
+QvBool
+QvNode::readNodeInstance(QvInput *in, const QvName &className,
+ const QvName &refName, QvNode *&node)
+{
+ node = createInstance(in, className);
+ if (node == NULL)
+ return FALSE;
+
+ if (! (! refName))
+ in->addReference(refName, node);
+
+ return node->readInstance(in);
+}
+
+QvNode *
+QvNode::createInstance(QvInput *in, const QvName &className)
+{
+ QvNode *instance;
+ QvString unknownString;
+
+ instance = createInstanceFromName(className);
+
+ if (instance == NULL) {
+
+ if (! in->read(unknownString) || unknownString != "fields") {
+ QvReadError::post(in, "Unknown class \"%s\"",
+ className.getString());
+ return NULL;
+ }
+
+ else if (unknownString == "fields") {
+ QvUnknownNode *tmpNode = new QvUnknownNode;
+ tmpNode->setClassName(className.getString());
+ instance = tmpNode;
+ in->putBack(unknownString.getString());
+ }
+ }
+
+ return instance;
+}
+
+QvNode *
+QvNode::createInstanceFromName(const QvName &className)
+{
+#define TRY_CLASS(name, class) \
+ else if (className == name) \
+ inst = new class
+
+ QvNode *inst = NULL;
+
+ if (0) ; // So "else" works in first TRY_CLASS
+ TRY_CLASS("Cone", QvCone);
+ TRY_CLASS("Coordinate3", QvCoordinate3);
+ TRY_CLASS("Cube", QvCube);
+ TRY_CLASS("Cylinder", QvCylinder);
+ TRY_CLASS("DirectionalLight", QvDirectionalLight);
+ TRY_CLASS("Group", QvGroup);
+ TRY_CLASS("IndexedFaceSet", QvIndexedFaceSet);
+ TRY_CLASS("IndexedLineSet", QvIndexedLineSet);
+ TRY_CLASS("Info", QvInfo);
+ TRY_CLASS("LevelOfDetail", QvLevelOfDetail);
+ TRY_CLASS("Material", QvMaterial);
+ TRY_CLASS("MaterialBinding", QvMaterialBinding);
+ TRY_CLASS("MatrixTransform", QvMatrixTransform);
+ TRY_CLASS("Normal", QvNormal);
+ TRY_CLASS("NormalBinding", QvNormalBinding);
+ TRY_CLASS("OrthographicCamera", QvOrthographicCamera);
+ TRY_CLASS("PerspectiveCamera", QvPerspectiveCamera);
+ TRY_CLASS("PointLight", QvPointLight);
+ TRY_CLASS("PointSet", QvPointSet);
+ TRY_CLASS("Rotation", QvRotation);
+ TRY_CLASS("Scale", QvScale);
+ TRY_CLASS("Separator", QvSeparator);
+ TRY_CLASS("ShapeHints", QvShapeHints);
+ TRY_CLASS("Sphere", QvSphere);
+ TRY_CLASS("SpotLight", QvSpotLight);
+ TRY_CLASS("Switch", QvSwitch);
+ TRY_CLASS("Texture2", QvTexture2);
+ TRY_CLASS("Texture2Transform", QvTexture2Transform);
+ TRY_CLASS("TextureCoordinate2", QvTextureCoordinate2);
+ TRY_CLASS("Transform", QvTransform);
+ TRY_CLASS("TransformSeparator", QvTransformSeparator);
+ TRY_CLASS("Translation", QvTranslation);
+ TRY_CLASS("WWWAnchor", QvWWWAnchor);
+ TRY_CLASS("WWWInline", QvWWWInline);
+
+ return inst;
+
+#undef TRY_CLASS
+}
+
+void
+QvNode::flushInput(QvInput *in)
+{
+ int nestLevel = 1;
+ char c;
+
+ while (nestLevel > 0 && in->get(c)) {
+
+ if (c == CLOSE_BRACE)
+ nestLevel--;
+
+ else if (c == OPEN_BRACE)
+ nestLevel++;
+ }
+}
+
+#undef OPEN_BRACE
+#undef CLOSE_BRACE
+#undef DEFINITION_KEYWORD
+#undef REFERENCE_KEYWORD
+#undef NULL_KEYWORD
diff --git a/tool_src/QvLib/QvNode.h b/tool_src/QvLib/QvNode.h
new file mode 100644
index 0000000..a24d6ea
--- /dev/null
+++ b/tool_src/QvLib/QvNode.h
@@ -0,0 +1,57 @@
+#ifndef _QV_NODE_
+#define _QV_NODE_
+
+#include <QvString.h>
+
+class QvChildList;
+class QvDict;
+class QvFieldData;
+class QvInput;
+class QvNodeList;
+class QvState;
+
+class QvNode {
+
+ public:
+ enum Stage {
+ FIRST_INSTANCE, // First real instance being constructed
+ PROTO_INSTANCE, // Prototype instance being constructed
+ OTHER_INSTANCE, // Subsequent instance being constructed
+ };
+
+ QvFieldData *fieldData;
+ QvChildList *children;
+ QvBool isBuiltIn;
+
+ QvName *objName;
+ QvNode();
+ virtual ~QvNode();
+
+ const QvName & getName() const;
+ void setName(const QvName &name);
+
+ static void init();
+ static QvBool read(QvInput *in, QvNode *&node);
+
+ virtual QvFieldData *getFieldData() = 0;
+
+ virtual void traverse(QvState *state) = 0;
+
+ protected:
+ virtual QvBool readInstance(QvInput *in);
+
+ private:
+ static QvDict *nameDict;
+
+ static void addName(QvNode *, const char *);
+ static void removeName(QvNode *, const char *);
+ static QvNode * readReference(QvInput *in);
+ static QvBool readNode(QvInput *in, QvName &className,QvNode *&node);
+ static QvBool readNodeInstance(QvInput *in, const QvName &className,
+ const QvName &refName, QvNode *&node);
+ static QvNode * createInstance(QvInput *in, const QvName &className);
+ static QvNode * createInstanceFromName(const QvName &className);
+ static void flushInput(QvInput *in);
+};
+
+#endif /* _QV_NODE_ */
diff --git a/tool_src/QvLib/QvNodes.h b/tool_src/QvLib/QvNodes.h
new file mode 100644
index 0000000..75d85d2
--- /dev/null
+++ b/tool_src/QvLib/QvNodes.h
@@ -0,0 +1,39 @@
+#ifndef _QV_NODES_
+#define _QV_NODES_
+
+#include <QvCone.h>
+#include <QvCoordinate3.h>
+#include <QvCube.h>
+#include <QvCylinder.h>
+#include <QvDirectionalLight.h>
+#include <QvGroup.h>
+#include <QvIndexedFaceSet.h>
+#include <QvIndexedLineSet.h>
+#include <QvInfo.h>
+#include <QvLevelOfDetail.h>
+#include <QvMaterial.h>
+#include <QvMaterialBinding.h>
+#include <QvMatrixTransform.h>
+#include <QvNormal.h>
+#include <QvNormalBinding.h>
+#include <QvOrthographicCamera.h>
+#include <QvPerspectiveCamera.h>
+#include <QvPointLight.h>
+#include <QvPointSet.h>
+#include <QvRotation.h>
+#include <QvScale.h>
+#include <QvSeparator.h>
+#include <QvShapeHints.h>
+#include <QvSphere.h>
+#include <QvSpotLight.h>
+#include <QvSwitch.h>
+#include <QvTexture2.h>
+#include <QvTexture2Transform.h>
+#include <QvTextureCoordinate2.h>
+#include <QvTransform.h>
+#include <QvTransformSeparator.h>
+#include <QvTranslation.h>
+#include <QvWWWAnchor.h>
+#include <QvWWWInline.h>
+
+#endif /* _QV_NODES_ */
diff --git a/tool_src/QvLib/QvNormal.cpp b/tool_src/QvLib/QvNormal.cpp
new file mode 100644
index 0000000..2d91800
--- /dev/null
+++ b/tool_src/QvLib/QvNormal.cpp
@@ -0,0 +1,19 @@
+#include <QvNormal.h>
+
+QV_NODE_SOURCE(QvNormal);
+
+QvNormal::QvNormal()
+{
+ QV_NODE_CONSTRUCTOR(QvNormal);
+ isBuiltIn = TRUE;
+
+ QV_NODE_ADD_FIELD(vector);
+
+ vector.values[0] = 0.0;
+ vector.values[1] = 0.0;
+ vector.values[2] = 1.0;
+}
+
+QvNormal::~QvNormal()
+{
+}
diff --git a/tool_src/QvLib/QvNormal.h b/tool_src/QvLib/QvNormal.h
new file mode 100644
index 0000000..75a1020
--- /dev/null
+++ b/tool_src/QvLib/QvNormal.h
@@ -0,0 +1,16 @@
+#ifndef _QV_NORMAL_
+#define _QV_NORMAL_
+
+#include <QvMFVec3f.h>
+#include <QvSubNode.h>
+
+class QvNormal : public QvNode {
+
+ QV_NODE_HEADER(QvNormal);
+
+ public:
+ // Fields
+ QvMFVec3f vector; // Normal vector(s)
+};
+
+#endif /* _QV_NORMAL_ */
diff --git a/tool_src/QvLib/QvNormalBinding.cpp b/tool_src/QvLib/QvNormalBinding.cpp
new file mode 100644
index 0000000..db53681
--- /dev/null
+++ b/tool_src/QvLib/QvNormalBinding.cpp
@@ -0,0 +1,29 @@
+#include <QvNormalBinding.h>
+
+QV_NODE_SOURCE(QvNormalBinding);
+
+QvNormalBinding::QvNormalBinding()
+{
+ QV_NODE_CONSTRUCTOR(QvNormalBinding);
+ isBuiltIn = TRUE;
+
+ QV_NODE_ADD_FIELD(value);
+
+ value.value = DEFAULT;
+
+ QV_NODE_DEFINE_ENUM_VALUE(Binding, DEFAULT);
+ QV_NODE_DEFINE_ENUM_VALUE(Binding, NONE);
+ QV_NODE_DEFINE_ENUM_VALUE(Binding, OVERALL);
+ QV_NODE_DEFINE_ENUM_VALUE(Binding, PER_PART);
+ QV_NODE_DEFINE_ENUM_VALUE(Binding, PER_PART_INDEXED);
+ QV_NODE_DEFINE_ENUM_VALUE(Binding, PER_FACE);
+ QV_NODE_DEFINE_ENUM_VALUE(Binding, PER_FACE_INDEXED);
+ QV_NODE_DEFINE_ENUM_VALUE(Binding, PER_VERTEX);
+ QV_NODE_DEFINE_ENUM_VALUE(Binding, PER_VERTEX_INDEXED);
+
+ QV_NODE_SET_SF_ENUM_TYPE(value, Binding);
+}
+
+QvNormalBinding::~QvNormalBinding()
+{
+}
diff --git a/tool_src/QvLib/QvNormalBinding.h b/tool_src/QvLib/QvNormalBinding.h
new file mode 100644
index 0000000..e690fdd
--- /dev/null
+++ b/tool_src/QvLib/QvNormalBinding.h
@@ -0,0 +1,28 @@
+#ifndef _QV_NORMAL_BINDING_
+#define _QV_NORMAL_BINDING_
+
+#include <QvSFEnum.h>
+#include <QvSubNode.h>
+
+class QvNormalBinding : public QvNode {
+
+ QV_NODE_HEADER(QvNormalBinding);
+
+ public:
+ enum Binding {
+ DEFAULT,
+ NONE,
+ OVERALL,
+ PER_PART,
+ PER_PART_INDEXED,
+ PER_FACE,
+ PER_FACE_INDEXED,
+ PER_VERTEX,
+ PER_VERTEX_INDEXED,
+ };
+
+ // Fields
+ QvSFEnum value; // Normal binding value
+};
+
+#endif /* _QV_NORMAL_BINDING_ */
diff --git a/tool_src/QvLib/QvOrthographicCamera.cpp b/tool_src/QvLib/QvOrthographicCamera.cpp
new file mode 100644
index 0000000..3a04d1c
--- /dev/null
+++ b/tool_src/QvLib/QvOrthographicCamera.cpp
@@ -0,0 +1,28 @@
+#include <QvOrthographicCamera.h>
+
+QV_NODE_SOURCE(QvOrthographicCamera);
+
+QvOrthographicCamera::QvOrthographicCamera()
+{
+ QV_NODE_CONSTRUCTOR(QvOrthographicCamera);
+ isBuiltIn = TRUE;
+
+ QV_NODE_ADD_FIELD(position);
+ QV_NODE_ADD_FIELD(orientation);
+ QV_NODE_ADD_FIELD(focalDistance);
+ QV_NODE_ADD_FIELD(height);
+
+ position.value[0] = 0.0;
+ position.value[1] = 0.0;
+ position.value[2] = 1.0;
+ orientation.axis[0] = 0.0;
+ orientation.axis[1] = 0.0;
+ orientation.axis[2] = 1.0;
+ orientation.angle = 0.0;
+ focalDistance.value = 5.0;
+ height.value = 2.0;
+}
+
+QvOrthographicCamera::~QvOrthographicCamera()
+{
+}
diff --git a/tool_src/QvLib/QvOrthographicCamera.h b/tool_src/QvLib/QvOrthographicCamera.h
new file mode 100644
index 0000000..1d44fda
--- /dev/null
+++ b/tool_src/QvLib/QvOrthographicCamera.h
@@ -0,0 +1,22 @@
+#ifndef _QV_ORTHOGRAPHIC_CAMERA_
+#define _QV_ORTHOGRAPHIC_CAMERA_
+
+#include <QvSFFloat.h>
+#include <QvSFRotation.h>
+#include <QvSFVec3f.h>
+#include <QvSubNode.h>
+
+class QvOrthographicCamera : public QvNode {
+
+ QV_NODE_HEADER(QvOrthographicCamera);
+
+ public:
+ QvSFVec3f position; // Location of viewpoint
+ QvSFRotation orientation; // Orientation (rotation with
+ // respect to (0,0,-1) vector)
+ QvSFFloat focalDistance; // Distance from viewpoint to
+ // point of focus.
+ QvSFFloat height; // Height of view volume
+};
+
+#endif /* _QV_ORTHOGRAPHIC_CAMERA_ */
diff --git a/tool_src/QvLib/QvPList.cpp b/tool_src/QvLib/QvPList.cpp
new file mode 100644
index 0000000..6872428
--- /dev/null
+++ b/tool_src/QvLib/QvPList.cpp
@@ -0,0 +1,64 @@
+#include <QvPList.h>
+
+#define DEFAULT_INITIAL_SIZE 4
+
+QvPList::QvPList()
+{
+ ptrs = NULL;
+ nPtrs = ptrsSize = 0;
+
+ setSize(0);
+}
+
+QvPList::~QvPList()
+{
+ if (ptrs != NULL)
+ delete [] ptrs;
+}
+
+int
+QvPList::find(const void *ptr) const
+{
+ int i;
+
+ for (i = 0; i < nPtrs; i++)
+ if (ptrs[i] == ptr)
+ return(i);
+
+ return -1;
+}
+
+void
+QvPList::remove(int which)
+{
+ int i;
+
+ for (i = which; i < nPtrs - 1; i++)
+ ptrs[i] = ptrs[i + 1];
+
+ setSize(nPtrs - 1);
+}
+
+void
+QvPList::expand(int size)
+{
+ void **newPtrs;
+ int i;
+
+ if (ptrsSize == 0)
+ ptrsSize = DEFAULT_INITIAL_SIZE;
+
+ while (size > ptrsSize) {
+ ptrsSize *= 2;
+ }
+
+ newPtrs = (void **) new uintptr_t[ptrsSize];
+
+ if (ptrs != NULL) {
+ for (i = 0; i < nPtrs; i++)
+ newPtrs[i] = ptrs[i];
+ delete [] ptrs;
+ }
+
+ ptrs = newPtrs;
+}
diff --git a/tool_src/QvLib/QvPList.h b/tool_src/QvLib/QvPList.h
new file mode 100644
index 0000000..50f3eff
--- /dev/null
+++ b/tool_src/QvLib/QvPList.h
@@ -0,0 +1,29 @@
+#ifndef _QV_PLIST_
+#define _QV_PLIST_
+
+#include <QvBasic.h>
+
+class QvPList {
+ public:
+ QvPList();
+ ~QvPList();
+ void append(void * ptr)
+ { if (nPtrs + 1 > ptrsSize) expand(nPtrs + 1);
+ ptrs[nPtrs++] = ptr; }
+ int find(const void *ptr) const;
+ void remove(int which);
+ int getLength() const { return (int) nPtrs; }
+ void truncate(int start)
+ { nPtrs = start; }
+ void *& operator [](int i) const { return ptrs[i]; }
+
+ private:
+ void ** ptrs;
+ int nPtrs;
+ int ptrsSize;
+ void setSize(int size)
+ { if (size > ptrsSize) expand(size); nPtrs = size; }
+ void expand(int size);
+};
+
+#endif /* _QV_PLIST_ */
diff --git a/tool_src/QvLib/QvPerspectiveCamera.cpp b/tool_src/QvLib/QvPerspectiveCamera.cpp
new file mode 100644
index 0000000..5083108
--- /dev/null
+++ b/tool_src/QvLib/QvPerspectiveCamera.cpp
@@ -0,0 +1,30 @@
+#include "math.h"
+
+#include <QvPerspectiveCamera.h>
+
+QV_NODE_SOURCE(QvPerspectiveCamera);
+
+QvPerspectiveCamera::QvPerspectiveCamera()
+{
+ QV_NODE_CONSTRUCTOR(QvPerspectiveCamera);
+ isBuiltIn = TRUE;
+
+ QV_NODE_ADD_FIELD(position);
+ QV_NODE_ADD_FIELD(orientation);
+ QV_NODE_ADD_FIELD(focalDistance);
+ QV_NODE_ADD_FIELD(heightAngle);
+
+ position.value[0] = 0.0;
+ position.value[1] = 0.0;
+ position.value[2] = 1.0;
+ orientation.axis[0] = 0.0;
+ orientation.axis[1] = 0.0;
+ orientation.axis[2] = 1.0;
+ orientation.angle = 0.0;
+ focalDistance.value = 5.0;
+ heightAngle.value = M_PI_4; // 45 degrees
+}
+
+QvPerspectiveCamera::~QvPerspectiveCamera()
+{
+}
diff --git a/tool_src/QvLib/QvPerspectiveCamera.h b/tool_src/QvLib/QvPerspectiveCamera.h
new file mode 100644
index 0000000..9ac8543
--- /dev/null
+++ b/tool_src/QvLib/QvPerspectiveCamera.h
@@ -0,0 +1,23 @@
+#ifndef _QV_PERSPECTIVE_CAMERA_
+#define _QV_PERSPECTIVE_CAMERA_
+
+#include <QvSFFloat.h>
+#include <QvSFRotation.h>
+#include <QvSFVec3f.h>
+#include <QvSubNode.h>
+
+class QvPerspectiveCamera : public QvNode {
+
+ QV_NODE_HEADER(QvPerspectiveCamera);
+
+ public:
+ QvSFVec3f position; // Location of viewpoint
+ QvSFRotation orientation; // Orientation (rotation with
+ // respect to (0,0,-1) vector)
+ QvSFFloat focalDistance; // Distance from viewpoint to
+ // point of focus.
+ QvSFFloat heightAngle; // Angle (in radians) of field
+ // of view, in height direction
+};
+
+#endif /* _QV_PERSPECTIVE_CAMERA_ */
diff --git a/tool_src/QvLib/QvPointLight.cpp b/tool_src/QvLib/QvPointLight.cpp
new file mode 100644
index 0000000..18652e1
--- /dev/null
+++ b/tool_src/QvLib/QvPointLight.cpp
@@ -0,0 +1,25 @@
+#include <QvPointLight.h>
+
+QV_NODE_SOURCE(QvPointLight);
+
+QvPointLight::QvPointLight()
+{
+ QV_NODE_CONSTRUCTOR(QvPointLight);
+ isBuiltIn = TRUE;
+
+ QV_NODE_ADD_FIELD(on);
+ QV_NODE_ADD_FIELD(intensity);
+ QV_NODE_ADD_FIELD(color);
+ QV_NODE_ADD_FIELD(location);
+
+ on.value = TRUE;
+ intensity.value = 1.0;
+ color.value[0] = color.value[1] = color.value[2] = 1.0;
+ location.value[0] = 0.0;
+ location.value[1] = 0.0;
+ location.value[2] = 1.0;
+}
+
+QvPointLight::~QvPointLight()
+{
+}
diff --git a/tool_src/QvLib/QvPointLight.h b/tool_src/QvLib/QvPointLight.h
new file mode 100644
index 0000000..09008bf
--- /dev/null
+++ b/tool_src/QvLib/QvPointLight.h
@@ -0,0 +1,22 @@
+#ifndef _QV_POINT_LIGHT_
+#define _QV_POINT_LIGHT_
+
+#include <QvSFBool.h>
+#include <QvSFColor.h>
+#include <QvSFFloat.h>
+#include <QvSFVec3f.h>
+#include <QvSubNode.h>
+
+class QvPointLight : public QvNode {
+
+ QV_NODE_HEADER(QvPointLight);
+
+ public:
+ // Fields
+ QvSFBool on; // Whether light is on
+ QvSFFloat intensity; // Source intensity (0 to 1)
+ QvSFColor color; // RGB source color
+ QvSFVec3f location; // Source location
+};
+
+#endif /* _QV_POINT_LIGHT_ */
diff --git a/tool_src/QvLib/QvPointSet.cpp b/tool_src/QvLib/QvPointSet.cpp
new file mode 100644
index 0000000..ed8dfdf
--- /dev/null
+++ b/tool_src/QvLib/QvPointSet.cpp
@@ -0,0 +1,19 @@
+#include <QvPointSet.h>
+
+QV_NODE_SOURCE(QvPointSet);
+
+QvPointSet::QvPointSet()
+{
+ QV_NODE_CONSTRUCTOR(QvPointSet);
+ isBuiltIn = TRUE;
+
+ QV_NODE_ADD_FIELD(startIndex);
+ QV_NODE_ADD_FIELD(numPoints);
+
+ startIndex.value = 0;
+ numPoints.value = QV_POINT_SET_USE_REST_OF_POINTS;
+}
+
+QvPointSet::~QvPointSet()
+{
+}
diff --git a/tool_src/QvLib/QvPointSet.h b/tool_src/QvLib/QvPointSet.h
new file mode 100644
index 0000000..aebc871
--- /dev/null
+++ b/tool_src/QvLib/QvPointSet.h
@@ -0,0 +1,19 @@
+#ifndef _QV_POINT_SET_
+#define _QV_POINT_SET_
+
+#include <QvSFLong.h>
+#include <QvSubNode.h>
+
+#define QV_POINT_SET_USE_REST_OF_POINTS (-1)
+
+class QvPointSet : public QvNode {
+
+ QV_NODE_HEADER(QvPointSet);
+
+ public:
+ // Fields
+ QvSFLong startIndex; // Index of 1st coordinate of shape
+ QvSFLong numPoints; // Number of points to draw
+};
+
+#endif /* _QV_POINT_SET_ */
diff --git a/tool_src/QvLib/QvReadError.cpp b/tool_src/QvLib/QvReadError.cpp
new file mode 100644
index 0000000..313525f
--- /dev/null
+++ b/tool_src/QvLib/QvReadError.cpp
@@ -0,0 +1,19 @@
+#include <stdarg.h>
+#include <QvString.h>
+#include <QvInput.h>
+#include <QvReadError.h>
+
+void
+QvReadError::post(const QvInput *in, const char *formatString ...)
+{
+ char buf[10000];
+ va_list ap;
+
+ va_start(ap, formatString);
+ vsprintf(buf, formatString, ap);
+ va_end(ap);
+
+ QvString locstr;
+ in->getLocationString(locstr);
+ fprintf(stderr, "VRML read error: %s\n%s\n", buf, locstr.getString());
+}
diff --git a/tool_src/QvLib/QvReadError.h b/tool_src/QvLib/QvReadError.h
new file mode 100644
index 0000000..61c4468
--- /dev/null
+++ b/tool_src/QvLib/QvReadError.h
@@ -0,0 +1,11 @@
+#ifndef _QV_READ_ERROR
+#define _QV_READ_ERROR
+
+class QvInput;
+
+class QvReadError {
+ public:
+ static void post(const QvInput *in, const char *formatString ...);
+};
+
+#endif /* _QV_READ_ERROR */
diff --git a/tool_src/QvLib/QvRotation.cpp b/tool_src/QvLib/QvRotation.cpp
new file mode 100644
index 0000000..345ee19
--- /dev/null
+++ b/tool_src/QvLib/QvRotation.cpp
@@ -0,0 +1,20 @@
+#include <QvRotation.h>
+
+QV_NODE_SOURCE(QvRotation);
+
+QvRotation::QvRotation()
+{
+ QV_NODE_CONSTRUCTOR(QvRotation);
+ isBuiltIn = TRUE;
+
+ QV_NODE_ADD_FIELD(rotation);
+
+ rotation.axis[0] = 0.0;
+ rotation.axis[1] = 0.0;
+ rotation.axis[2] = 1.0;
+ rotation.angle = 0.0;
+}
+
+QvRotation::~QvRotation()
+{
+}
diff --git a/tool_src/QvLib/QvRotation.h b/tool_src/QvLib/QvRotation.h
new file mode 100644
index 0000000..9029420
--- /dev/null
+++ b/tool_src/QvLib/QvRotation.h
@@ -0,0 +1,16 @@
+#ifndef _QV_ROTATION_
+#define _QV_ROTATION_
+
+#include <QvSFRotation.h>
+#include <QvSubNode.h>
+
+class QvRotation : public QvNode {
+
+ QV_NODE_HEADER(QvRotation);
+
+ public:
+ // Fields
+ QvSFRotation rotation; // Rotation
+};
+
+#endif /* _QV_ROTATION_ */
diff --git a/tool_src/QvLib/QvSFBitMask.cpp b/tool_src/QvLib/QvSFBitMask.cpp
new file mode 100644
index 0000000..d4c89df
--- /dev/null
+++ b/tool_src/QvLib/QvSFBitMask.cpp
@@ -0,0 +1,84 @@
+#include <QvDebugError.h>
+#include <QvReadError.h>
+#include <QvSFBitMask.h>
+
+// Special characters when reading or writing value in ASCII
+#define OPEN_PAREN '('
+#define CLOSE_PAREN ')'
+#define BITWISE_OR '|'
+
+QV_SFIELD_SOURCE(QvSFBitMask);
+
+QvBool
+QvSFBitMask::readValue(QvInput *in)
+{
+ char c;
+ QvName n;
+ int v;
+
+#ifdef DEBUG
+ if (enumValues == NULL) {
+ QvDebugError::post("QvSFBitMask::readValue",
+ "Enum values were never initialized");
+ QvReadError::post(in, "Couldn't read QvSFBitMask values");
+ return FALSE;
+ }
+#endif /* DEBUG */
+
+ value = 0;
+
+ // Read first character
+ if (! in->read(c))
+ return FALSE;
+
+ // Check for parenthesized list of bitwise-or'ed flags
+ if (c == OPEN_PAREN) {
+
+ // Read names separated by BITWISE_OR
+ while (TRUE) {
+ if (in->read(n, TRUE) && ! (! n) ) {
+
+ if (findEnumValue(n, v))
+ value |= v;
+
+ else {
+ QvReadError::post(in, "Unknown QvSFBitMask bit "
+ "mask value \"%s\"", n.getString());
+ return FALSE;
+ }
+ }
+
+ if (! in->read(c)) {
+ QvReadError::post(in, "EOF reached before '%c' "
+ "in QvSFBitMask value", CLOSE_PAREN);
+ return FALSE;
+ }
+
+ if (c == CLOSE_PAREN)
+ break;
+
+ else if (c != BITWISE_OR) {
+ QvReadError::post(in, "Expected '%c' or '%c', got '%c' ",
+ "in QvSFBitMask value",
+ BITWISE_OR, CLOSE_PAREN, c);
+ return FALSE;
+ }
+ }
+ }
+
+ else {
+ in->putBack(c);
+
+ // Read mnemonic value as a character string identifier
+ if (! in->read(n, TRUE))
+ return FALSE;
+
+ if (! findEnumValue(n, value)) {
+ QvReadError::post(in, "Unknown QvSFBitMask bit "
+ "mask value \"%s\"", n.getString());
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
diff --git a/tool_src/QvLib/QvSFBitMask.h b/tool_src/QvLib/QvSFBitMask.h
new file mode 100644
index 0000000..274b8d0
--- /dev/null
+++ b/tool_src/QvLib/QvSFBitMask.h
@@ -0,0 +1,12 @@
+#ifndef _QV_SF_BIT_MASK_
+#define _QV_SF_BIT_MASK_
+
+#include <QvSFEnum.h>
+
+class QvSFBitMask : public QvSFEnum {
+ public:
+ // Inherits value
+ QV_SFIELD_HEADER(QvSFBitMask);
+};
+
+#endif /* _QV_SF_BIT_MASK_ */
diff --git a/tool_src/QvLib/QvSFBool.cpp b/tool_src/QvLib/QvSFBool.cpp
new file mode 100644
index 0000000..a1ecd9c
--- /dev/null
+++ b/tool_src/QvLib/QvSFBool.cpp
@@ -0,0 +1,37 @@
+#include <QvReadError.h>
+#include <QvSFBool.h>
+
+QV_SFIELD_SOURCE(QvSFBool);
+
+QvBool
+QvSFBool::readValue(QvInput *in)
+{
+ // accept 0 or 1
+ if (in->read(value)) {
+ if (value != 0 && value != 1) {
+ QvReadError::post(in, "Illegal value for QvSFBool: %d "
+ "(must be 0 or 1)", value);
+ return FALSE;
+ }
+ return TRUE;
+ }
+
+ // read TRUE/FALSE keyword
+ QvName n;
+ if (! in->read(n, TRUE))
+ return FALSE;
+
+ if (n == "TRUE") {
+ value = TRUE;
+ return TRUE;
+ }
+
+ if (n == "FALSE") {
+ value = FALSE;
+ return TRUE;
+ }
+
+ QvReadError::post(in, "Unknown value (\"%s\") for QvSFBool ",
+ "(must be TRUE or FALSE)", n.getString());
+ return FALSE;
+}
diff --git a/tool_src/QvLib/QvSFBool.h b/tool_src/QvLib/QvSFBool.h
new file mode 100644
index 0000000..929618e
--- /dev/null
+++ b/tool_src/QvLib/QvSFBool.h
@@ -0,0 +1,12 @@
+#ifndef _QV_SF_BOOL_
+#define _QV_SF_BOOL_
+
+#include <QvSubField.h>
+
+class QvSFBool : public QvSField {
+ public:
+ QvBool value;
+ QV_SFIELD_HEADER(QvSFBool);
+};
+
+#endif /* _QV_SF_BOOL_ */
diff --git a/tool_src/QvLib/QvSFColor.cpp b/tool_src/QvLib/QvSFColor.cpp
new file mode 100644
index 0000000..add6f6e
--- /dev/null
+++ b/tool_src/QvLib/QvSFColor.cpp
@@ -0,0 +1,11 @@
+#include <QvSFColor.h>
+
+QV_SFIELD_SOURCE(QvSFColor);
+
+QvBool
+QvSFColor::readValue(QvInput *in)
+{
+ return (in->read(value[0]) &&
+ in->read(value[1]) &&
+ in->read(value[2]));
+}
diff --git a/tool_src/QvLib/QvSFColor.h b/tool_src/QvLib/QvSFColor.h
new file mode 100644
index 0000000..d724b36
--- /dev/null
+++ b/tool_src/QvLib/QvSFColor.h
@@ -0,0 +1,12 @@
+#ifndef _QV_SF_COLOR_
+#define _QV_SF_COLOR_
+
+#include <QvSubField.h>
+
+class QvSFColor : public QvSField {
+ public:
+ float value[3];
+ QV_SFIELD_HEADER(QvSFColor);
+};
+
+#endif /* _QV_SF_COLOR_ */
diff --git a/tool_src/QvLib/QvSFEnum.cpp b/tool_src/QvLib/QvSFEnum.cpp
new file mode 100644
index 0000000..2c41da9
--- /dev/null
+++ b/tool_src/QvLib/QvSFEnum.cpp
@@ -0,0 +1,58 @@
+#include <QvDebugError.h>
+#include <QvReadError.h>
+#include <QvSFEnum.h>
+
+// Can't use macro, since we define a constructor.
+
+QvSFEnum::QvSFEnum()
+{
+ enumValues = NULL;
+ enumNames = NULL;
+}
+
+QvSFEnum::~QvSFEnum()
+{
+}
+
+QvBool
+QvSFEnum::findEnumValue(const QvName &name, int &val) const
+{
+ int i;
+
+ // Look through names table for one that matches
+ for (i = 0; i < numEnums; i++) {
+ if (name == enumNames[i]) {
+ val = enumValues[i];
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+QvBool
+QvSFEnum::readValue(QvInput *in)
+{
+ QvName n;
+
+#ifdef DEBUG
+ if (enumValues == NULL) {
+ QvDebugError::post("QvSFEnum::readValue",
+ "Enum values were never initialized");
+ QvReadError::post(in, "Couldn't read QvSFEnum value");
+ return FALSE;
+ }
+#endif /* DEBUG */
+
+ // Read mnemonic value as a character string identifier
+ if (! in->read(n, TRUE))
+ return FALSE;
+
+ if (findEnumValue(n, value))
+ return TRUE;
+
+ // Not found? Too bad
+ QvReadError::post(in, "Unknown QvSFEnum enumeration value \"%s\"",
+ n.getString());
+ return FALSE;
+}
diff --git a/tool_src/QvLib/QvSFEnum.h b/tool_src/QvLib/QvSFEnum.h
new file mode 100644
index 0000000..14a6c4b
--- /dev/null
+++ b/tool_src/QvLib/QvSFEnum.h
@@ -0,0 +1,38 @@
+#ifndef _QV_SF_ENUM_
+#define _QV_SF_ENUM_
+
+#include <QvString.h>
+#include <QvSubField.h>
+
+class QvSFEnum : public QvSField {
+ public:
+ int value;
+ QV_SFIELD_HEADER(QvSFEnum);
+
+ // Sets up value/name correspondances
+ void setEnums(int num, const int vals[], const QvName names[])
+ { numEnums = num; enumValues = vals; enumNames = names; }
+
+ int numEnums; // Number of enumeration values
+ const int *enumValues; // Enumeration values
+ const QvName *enumNames; // Mnemonic names of values
+
+ // Looks up enum name, returns value. Returns FALSE if not found.
+ QvBool findEnumValue(const QvName &name, int &val) const;
+};
+
+#define QV_NODE_SET_SF_ENUM_TYPE(fieldName, enumType) \
+ do { \
+ int _so_sf_enum_num; \
+ const int *_so_sf_enum_vals; \
+ const QvName *_so_sf_enum_names; \
+ fieldData->getEnumData(QV__QUOTE(enumType), \
+ _so_sf_enum_num, \
+ _so_sf_enum_vals, \
+ _so_sf_enum_names); \
+ fieldName.setEnums(_so_sf_enum_num, \
+ _so_sf_enum_vals, \
+ _so_sf_enum_names); \
+ } while (0)
+
+#endif /* _QV_SF_ENUM_ */
diff --git a/tool_src/QvLib/QvSFFloat.cpp b/tool_src/QvLib/QvSFFloat.cpp
new file mode 100644
index 0000000..c3e693d
--- /dev/null
+++ b/tool_src/QvLib/QvSFFloat.cpp
@@ -0,0 +1,9 @@
+#include <QvSFFloat.h>
+
+QV_SFIELD_SOURCE(QvSFFloat);
+
+QvBool
+QvSFFloat::readValue(QvInput *in)
+{
+ return in->read(value);
+}
diff --git a/tool_src/QvLib/QvSFFloat.h b/tool_src/QvLib/QvSFFloat.h
new file mode 100644
index 0000000..f8fde12
--- /dev/null
+++ b/tool_src/QvLib/QvSFFloat.h
@@ -0,0 +1,12 @@
+#ifndef _QV_SF_FLOAT_
+#define _QV_SF_FLOAT_
+
+#include <QvSubField.h>
+
+class QvSFFloat : public QvSField {
+ public:
+ float value;
+ QV_SFIELD_HEADER(QvSFFloat);
+};
+
+#endif /* _QV_SF_FLOAT_ */
diff --git a/tool_src/QvLib/QvSFImage.cpp b/tool_src/QvLib/QvSFImage.cpp
new file mode 100644
index 0000000..d733bf2
--- /dev/null
+++ b/tool_src/QvLib/QvSFImage.cpp
@@ -0,0 +1,39 @@
+#include <QvSFImage.h>
+
+// Can't use macro, since we define a constructor.
+
+QvSFImage::QvSFImage()
+{
+ size[0] = size[1] = 0;
+ numComponents = 0;
+ bytes = NULL;
+}
+
+QvSFImage::~QvSFImage()
+{
+ if (bytes != NULL)
+ delete [] bytes;
+}
+QvBool
+QvSFImage::readValue(QvInput *in)
+{
+ if (! in->read(size[0]) ||
+ ! in->read(size[1]) ||
+ ! in->read(numComponents))
+ return FALSE;
+
+ if (bytes != NULL)
+ delete [] bytes;
+ bytes = new unsigned char[size[0] * size[1] * numComponents];
+
+ int byte = 0;
+ for (int i = 0; i < size[0] * size[1]; i++) {
+ unsigned long l;
+ if (! in->read(l))
+ return FALSE;
+ for (int j = 0; j < numComponents; j++)
+ bytes[byte++] =
+ (unsigned char) ((l >> (8*(numComponents-j-1))) & 0xFF);
+ }
+ return TRUE;
+}
diff --git a/tool_src/QvLib/QvSFImage.h b/tool_src/QvLib/QvSFImage.h
new file mode 100644
index 0000000..80a1fe1
--- /dev/null
+++ b/tool_src/QvLib/QvSFImage.h
@@ -0,0 +1,14 @@
+#ifndef _QV_SF_IMAGE_
+#define _QV_SF_IMAGE_
+
+#include <QvSubField.h>
+
+class QvSFImage : public QvSField {
+ public:
+ short size[2]; // Width and height of image
+ int numComponents; // Number of components per pixel
+ unsigned char * bytes; // Array of pixels
+ QV_SFIELD_HEADER(QvSFImage);
+};
+
+#endif /* _QV_SF_IMAGE_ */
diff --git a/tool_src/QvLib/QvSFLong.cpp b/tool_src/QvLib/QvSFLong.cpp
new file mode 100644
index 0000000..929583f
--- /dev/null
+++ b/tool_src/QvLib/QvSFLong.cpp
@@ -0,0 +1,9 @@
+#include <QvSFLong.h>
+
+QV_SFIELD_SOURCE(QvSFLong);
+
+QvBool
+QvSFLong::readValue(QvInput *in)
+{
+ return in->read(value);
+}
diff --git a/tool_src/QvLib/QvSFLong.h b/tool_src/QvLib/QvSFLong.h
new file mode 100644
index 0000000..96c7406
--- /dev/null
+++ b/tool_src/QvLib/QvSFLong.h
@@ -0,0 +1,12 @@
+#ifndef _QV_SF_LONG_
+#define _QV_SF_LONG_
+
+#include <QvSubField.h>
+
+class QvSFLong : public QvSField {
+ public:
+ long value;
+ QV_SFIELD_HEADER(QvSFLong);
+};
+
+#endif /* _QV_SF_LONG_ */
diff --git a/tool_src/QvLib/QvSFMatrix.cpp b/tool_src/QvLib/QvSFMatrix.cpp
new file mode 100644
index 0000000..b6a4f87
--- /dev/null
+++ b/tool_src/QvLib/QvSFMatrix.cpp
@@ -0,0 +1,16 @@
+#include <QvSFMatrix.h>
+
+QV_SFIELD_SOURCE(QvSFMatrix);
+
+QvBool
+QvSFMatrix::readValue(QvInput *in)
+{
+ return (in->read(value[0][0]) && in->read(value[0][1]) &&
+ in->read(value[0][2]) && in->read(value[0][3]) &&
+ in->read(value[1][0]) && in->read(value[1][1]) &&
+ in->read(value[1][2]) && in->read(value[1][3]) &&
+ in->read(value[2][0]) && in->read(value[2][1]) &&
+ in->read(value[2][2]) && in->read(value[2][3]) &&
+ in->read(value[3][0]) && in->read(value[3][1]) &&
+ in->read(value[3][2]) && in->read(value[3][3]));
+}
diff --git a/tool_src/QvLib/QvSFMatrix.h b/tool_src/QvLib/QvSFMatrix.h
new file mode 100644
index 0000000..e00b7ae
--- /dev/null
+++ b/tool_src/QvLib/QvSFMatrix.h
@@ -0,0 +1,12 @@
+#ifndef _QV_SF_MATRIX_
+#define _QV_SF_MATRIX_
+
+#include <QvSubField.h>
+
+class QvSFMatrix : public QvSField {
+ public:
+ float value[4][4];
+ QV_SFIELD_HEADER(QvSFMatrix);
+};
+
+#endif /* _QV_SF_MATRIX_ */
diff --git a/tool_src/QvLib/QvSFRotation.cpp b/tool_src/QvLib/QvSFRotation.cpp
new file mode 100644
index 0000000..a76beb6
--- /dev/null
+++ b/tool_src/QvLib/QvSFRotation.cpp
@@ -0,0 +1,12 @@
+#include <QvSFRotation.h>
+
+QV_SFIELD_SOURCE(QvSFRotation);
+
+QvBool
+QvSFRotation::readValue(QvInput *in)
+{
+ return (in->read(axis[0]) &&
+ in->read(axis[1]) &&
+ in->read(axis[2]) &&
+ in->read(angle));
+}
diff --git a/tool_src/QvLib/QvSFRotation.h b/tool_src/QvLib/QvSFRotation.h
new file mode 100644
index 0000000..5402f94
--- /dev/null
+++ b/tool_src/QvLib/QvSFRotation.h
@@ -0,0 +1,13 @@
+#ifndef _QV_SF_ROTATION_
+#define _QV_SF_ROTATION_
+
+#include <QvSubField.h>
+
+class QvSFRotation : public QvSField {
+ public:
+ float axis[3];
+ float angle;
+ QV_SFIELD_HEADER(QvSFRotation);
+};
+
+#endif /* _QV_SF_ROTATION_ */
diff --git a/tool_src/QvLib/QvSFString.cpp b/tool_src/QvLib/QvSFString.cpp
new file mode 100644
index 0000000..9ddad5c
--- /dev/null
+++ b/tool_src/QvLib/QvSFString.cpp
@@ -0,0 +1,9 @@
+#include <QvSFString.h>
+
+QV_SFIELD_SOURCE(QvSFString);
+
+QvBool
+QvSFString::readValue(QvInput *in)
+{
+ return in->read(value);
+}
diff --git a/tool_src/QvLib/QvSFString.h b/tool_src/QvLib/QvSFString.h
new file mode 100644
index 0000000..70c9048
--- /dev/null
+++ b/tool_src/QvLib/QvSFString.h
@@ -0,0 +1,12 @@
+#ifndef _QV_SF_STRING_
+#define _QV_SF_STRING_
+
+#include <QvSubField.h>
+
+class QvSFString : public QvSField {
+ public:
+ QvString value;
+ QV_SFIELD_HEADER(QvSFString);
+};
+
+#endif /* _QV_SF_STRING_ */
diff --git a/tool_src/QvLib/QvSFVec2f.cpp b/tool_src/QvLib/QvSFVec2f.cpp
new file mode 100644
index 0000000..de1eace
--- /dev/null
+++ b/tool_src/QvLib/QvSFVec2f.cpp
@@ -0,0 +1,10 @@
+#include <QvSFVec2f.h>
+
+QV_SFIELD_SOURCE(QvSFVec2f);
+
+QvBool
+QvSFVec2f::readValue(QvInput *in)
+{
+ return (in->read(value[0]) &&
+ in->read(value[1]));
+}
diff --git a/tool_src/QvLib/QvSFVec2f.h b/tool_src/QvLib/QvSFVec2f.h
new file mode 100644
index 0000000..2863a26
--- /dev/null
+++ b/tool_src/QvLib/QvSFVec2f.h
@@ -0,0 +1,12 @@
+#ifndef _QV_SF_VEC2F_
+#define _QV_SF_VEC2F_
+
+#include <QvSubField.h>
+
+class QvSFVec2f : public QvSField {
+ public:
+ float value[2];
+ QV_SFIELD_HEADER(QvSFVec2f);
+};
+
+#endif /* _QV_SF_VEC2F_ */
diff --git a/tool_src/QvLib/QvSFVec3f.cpp b/tool_src/QvLib/QvSFVec3f.cpp
new file mode 100644
index 0000000..01148e6
--- /dev/null
+++ b/tool_src/QvLib/QvSFVec3f.cpp
@@ -0,0 +1,11 @@
+#include <QvSFVec3f.h>
+
+QV_SFIELD_SOURCE(QvSFVec3f);
+
+QvBool
+QvSFVec3f::readValue(QvInput *in)
+{
+ return (in->read(value[0]) &&
+ in->read(value[1]) &&
+ in->read(value[2]));
+}
diff --git a/tool_src/QvLib/QvSFVec3f.h b/tool_src/QvLib/QvSFVec3f.h
new file mode 100644
index 0000000..c8b2c0f
--- /dev/null
+++ b/tool_src/QvLib/QvSFVec3f.h
@@ -0,0 +1,12 @@
+#ifndef _QV_SF_VEC3F_
+#define _QV_SF_VEC3F_
+
+#include <QvSubField.h>
+
+class QvSFVec3f : public QvSField {
+ public:
+ float value[3];
+ QV_SFIELD_HEADER(QvSFVec3f);
+};
+
+#endif /* _QV_SF_VEC3F_ */
diff --git a/tool_src/QvLib/QvScale.cpp b/tool_src/QvLib/QvScale.cpp
new file mode 100644
index 0000000..e09a08e
--- /dev/null
+++ b/tool_src/QvLib/QvScale.cpp
@@ -0,0 +1,17 @@
+#include <QvScale.h>
+
+QV_NODE_SOURCE(QvScale);
+
+QvScale::QvScale()
+{
+ QV_NODE_CONSTRUCTOR(QvScale);
+ isBuiltIn = TRUE;
+
+ QV_NODE_ADD_FIELD(scaleFactor);
+
+ scaleFactor.value[0] = scaleFactor.value[1] = scaleFactor.value[2] =1.0;
+}
+
+QvScale::~QvScale()
+{
+}
diff --git a/tool_src/QvLib/QvScale.h b/tool_src/QvLib/QvScale.h
new file mode 100644
index 0000000..06384d7
--- /dev/null
+++ b/tool_src/QvLib/QvScale.h
@@ -0,0 +1,16 @@
+#ifndef _QV_SCALE_
+#define _QV_SCALE_
+
+#include <QvSFVec3f.h>
+#include <QvSubNode.h>
+
+class QvScale : public QvNode {
+
+ QV_NODE_HEADER(QvScale);
+
+ public:
+ // Fields
+ QvSFVec3f scaleFactor; // Scale factors in x, y, and z
+};
+
+#endif /* _QV_SCALE_ */
diff --git a/tool_src/QvLib/QvSeparator.cpp b/tool_src/QvLib/QvSeparator.cpp
new file mode 100644
index 0000000..5c9751e
--- /dev/null
+++ b/tool_src/QvLib/QvSeparator.cpp
@@ -0,0 +1,23 @@
+#include <QvSeparator.h>
+
+QV_NODE_SOURCE(QvSeparator);
+
+QvSeparator::QvSeparator()
+{
+ QV_NODE_CONSTRUCTOR(QvSeparator);
+ isBuiltIn = TRUE;
+
+ QV_NODE_ADD_FIELD(renderCulling);
+
+ renderCulling.value = AUTO;
+
+ QV_NODE_DEFINE_ENUM_VALUE(CullEnabled, ON);
+ QV_NODE_DEFINE_ENUM_VALUE(CullEnabled, OFF);
+ QV_NODE_DEFINE_ENUM_VALUE(CullEnabled, AUTO);
+
+ QV_NODE_SET_SF_ENUM_TYPE(renderCulling, CullEnabled);
+}
+
+QvSeparator::~QvSeparator()
+{
+}
diff --git a/tool_src/QvLib/QvSeparator.h b/tool_src/QvLib/QvSeparator.h
new file mode 100644
index 0000000..a6a8688
--- /dev/null
+++ b/tool_src/QvLib/QvSeparator.h
@@ -0,0 +1,24 @@
+#ifndef _QV_SEPARATOR_
+#define _QV_SEPARATOR_
+
+#include <QvSFEnum.h>
+#include <QvGroup.h>
+
+#include <QvSFBitMask.h>
+
+class QvSeparator : public QvGroup {
+
+ QV_NODE_HEADER(QvSeparator);
+
+ public:
+ enum CullEnabled { // Possible values for culling
+ OFF, // Never cull
+ ON, // Always cull
+ AUTO, // Decide based on some heuristic
+ };
+
+ // Fields
+ QvSFEnum renderCulling;
+};
+
+#endif /* _QV_SEPARATOR_ */
diff --git a/tool_src/QvLib/QvShapeHints.cpp b/tool_src/QvLib/QvShapeHints.cpp
new file mode 100644
index 0000000..7c868c2
--- /dev/null
+++ b/tool_src/QvLib/QvShapeHints.cpp
@@ -0,0 +1,37 @@
+#include <QvShapeHints.h>
+
+QV_NODE_SOURCE(QvShapeHints);
+
+QvShapeHints::QvShapeHints()
+{
+ QV_NODE_CONSTRUCTOR(QvShapeHints);
+ isBuiltIn = TRUE;
+
+ QV_NODE_ADD_FIELD(vertexOrdering);
+ QV_NODE_ADD_FIELD(shapeType);
+ QV_NODE_ADD_FIELD(faceType);
+ QV_NODE_ADD_FIELD(creaseAngle);
+
+ vertexOrdering.value = UNKNOWN_ORDERING;
+ shapeType.value = UNKNOWN_SHAPE_TYPE;
+ faceType.value = CONVEX;
+ creaseAngle.value = 0.5;
+
+ QV_NODE_DEFINE_ENUM_VALUE(VertexOrdering, UNKNOWN_ORDERING);
+ QV_NODE_DEFINE_ENUM_VALUE(VertexOrdering, CLOCKWISE);
+ QV_NODE_DEFINE_ENUM_VALUE(VertexOrdering, COUNTERCLOCKWISE);
+
+ QV_NODE_DEFINE_ENUM_VALUE(ShapeType, UNKNOWN_SHAPE_TYPE);
+ QV_NODE_DEFINE_ENUM_VALUE(ShapeType, SOLID);
+
+ QV_NODE_DEFINE_ENUM_VALUE(FaceType, UNKNOWN_FACE_TYPE);
+ QV_NODE_DEFINE_ENUM_VALUE(FaceType, CONVEX);
+
+ QV_NODE_SET_SF_ENUM_TYPE(vertexOrdering, VertexOrdering);
+ QV_NODE_SET_SF_ENUM_TYPE(shapeType, ShapeType);
+ QV_NODE_SET_SF_ENUM_TYPE(faceType, FaceType);
+}
+
+QvShapeHints::~QvShapeHints()
+{
+}
diff --git a/tool_src/QvLib/QvShapeHints.h b/tool_src/QvLib/QvShapeHints.h
new file mode 100644
index 0000000..e816239
--- /dev/null
+++ b/tool_src/QvLib/QvShapeHints.h
@@ -0,0 +1,36 @@
+#ifndef _QV_SHAPE_HINTS_
+#define _QV_SHAPE_HINTS_
+
+#include <QvSFEnum.h>
+#include <QvSFFloat.h>
+#include <QvSubNode.h>
+
+class QvShapeHints : public QvNode {
+
+ QV_NODE_HEADER(QvShapeHints);
+
+ public:
+ enum VertexOrdering {
+ UNKNOWN_ORDERING,
+ CLOCKWISE,
+ COUNTERCLOCKWISE,
+ };
+
+ enum ShapeType {
+ UNKNOWN_SHAPE_TYPE,
+ SOLID,
+ };
+
+ enum FaceType {
+ UNKNOWN_FACE_TYPE,
+ CONVEX,
+ };
+
+ // Fields
+ QvSFEnum vertexOrdering; // Ordering of face vertices
+ QvSFEnum shapeType; // Info about shape geometry
+ QvSFEnum faceType; // Info about face geometry
+ QvSFFloat creaseAngle; // Smallest angle for sharp edge
+};
+
+#endif /* _QV_SHAPE_HINTS_ */
diff --git a/tool_src/QvLib/QvSphere.cpp b/tool_src/QvLib/QvSphere.cpp
new file mode 100644
index 0000000..c15d830
--- /dev/null
+++ b/tool_src/QvLib/QvSphere.cpp
@@ -0,0 +1,17 @@
+#include <QvSphere.h>
+
+QV_NODE_SOURCE(QvSphere);
+
+QvSphere::QvSphere()
+{
+ QV_NODE_CONSTRUCTOR(QvSphere);
+ isBuiltIn = TRUE;
+
+ QV_NODE_ADD_FIELD(radius);
+
+ radius.value = 1.0;
+}
+
+QvSphere::~QvSphere()
+{
+}
diff --git a/tool_src/QvLib/QvSphere.h b/tool_src/QvLib/QvSphere.h
new file mode 100644
index 0000000..f867c54
--- /dev/null
+++ b/tool_src/QvLib/QvSphere.h
@@ -0,0 +1,17 @@
+#ifndef _QV_SPHERE_
+#define _QV_SPHERE_
+
+#include <QvSFFloat.h>
+#include <QvSubNode.h>
+
+class QvSphere : public QvNode {
+
+ QV_NODE_HEADER(QvSphere);
+
+ public:
+ // Fields
+ QvSFFloat radius; // Radius of sphere
+};
+
+#endif /* _QV_SPHERE_ */
+
diff --git a/tool_src/QvLib/QvSpotLight.h b/tool_src/QvLib/QvSpotLight.h
new file mode 100644
index 0000000..81f739a
--- /dev/null
+++ b/tool_src/QvLib/QvSpotLight.h
@@ -0,0 +1,29 @@
+#ifndef _QV_SPOT_LIGHT_
+#define _QV_SPOT_LIGHT_
+
+#include <QvSFBool.h>
+#include <QvSFColor.h>
+#include <QvSFFloat.h>
+#include <QvSFVec3f.h>
+#include <QvSubNode.h>
+
+class QvSpotLight : public QvNode {
+
+ QV_NODE_HEADER(QvSpotLight);
+
+ public:
+ // Fields:
+ QvSFBool on; // Whether light is on
+ QvSFFloat intensity; // Source intensity (0 to 1)
+ QvSFColor color; // RGB source color
+ QvSFVec3f location; // Source location
+ QvSFVec3f direction; // Primary direction of illumination
+ QvSFFloat dropOffRate; // Rate of intensity drop-off from primary
+ // direction: 0 = constant intensity,
+ // 1 = sharp drop-off
+ QvSFFloat cutOffAngle; // Angle (in radians) outside of which
+ // intensity is zero, measured from
+ // edge of cone to other edge
+};
+
+#endif /* _QV_SPOT_LIGHT_ */
diff --git a/tool_src/QvLib/QvSpotlight.cpp b/tool_src/QvLib/QvSpotlight.cpp
new file mode 100644
index 0000000..5273711
--- /dev/null
+++ b/tool_src/QvLib/QvSpotlight.cpp
@@ -0,0 +1,35 @@
+#include "math.h"
+
+#include <QvSpotLight.h>
+
+QV_NODE_SOURCE(QvSpotLight);
+
+QvSpotLight::QvSpotLight()
+{
+ QV_NODE_CONSTRUCTOR(QvSpotLight);
+ isBuiltIn = TRUE;
+
+ QV_NODE_ADD_FIELD(on);
+ QV_NODE_ADD_FIELD(intensity);
+ QV_NODE_ADD_FIELD(color);
+ QV_NODE_ADD_FIELD(location);
+ QV_NODE_ADD_FIELD(direction);
+ QV_NODE_ADD_FIELD(dropOffRate);
+ QV_NODE_ADD_FIELD(cutOffAngle);
+
+ on.value = TRUE;
+ intensity.value = 1.0;
+ color.value[0] = color.value[1] = color.value[2] = 1.0;
+ location.value[0] = 0.0;
+ location.value[1] = 0.0;
+ location.value[2] = 1.0;
+ direction.value[0] = 0.0;
+ direction.value[1] = 0.0;
+ direction.value[2] = -1.0;
+ dropOffRate.value = 0.0;
+ cutOffAngle.value = M_PI / 4.0;
+}
+
+QvSpotLight::~QvSpotLight()
+{
+}
diff --git a/tool_src/QvLib/QvState.cpp b/tool_src/QvLib/QvState.cpp
new file mode 100644
index 0000000..6a629b8
--- /dev/null
+++ b/tool_src/QvLib/QvState.cpp
@@ -0,0 +1,128 @@
+
+//[MSH_START]
+// 02/01/98: moved FetchCoordinate3State(), FetchMaterialState(), and
+// FetchMaterialBindingState() into class BRep.
+// 01/01/98: added new material retrieval code (msh)
+// 05/05/97: added new constructor (msh)
+// 04/03/97: added display of coordinate3 stack (msh)
+//[MSH_END]
+
+#include <QvState.h>
+
+
+const char *QvState::stackNames[NumStacks] = {
+ "Camera",
+ "Coordinate3",
+ "Light",
+ "MaterialBinding",
+ "Material",
+ "NormalBinding",
+ "Normal",
+ "ShapeHints",
+ "Texture2",
+ "Texture2Transformation",
+ "TextureCoordinate2",
+ "Transformation",
+};
+
+//[MSH_START]
+QvState::QvState( BSPLIB_NAMESPACE::VrmlFile *base )
+{
+ vrmlfile_base = base;
+ //stacks = new QvElement[NumStacks];
+
+ //stacks = (QvElement **) new QvElement[NumStacks];
+ //stacks = new QvElement * [NumStacks];
+
+ for (int i = 0; i < NumStacks; i++){
+ stacks[i] = NULL;
+ }
+ depth = 0;
+}
+//[MSH_END]
+
+QvState::QvState()
+{
+//[MSH_START]
+ vrmlfile_base = NULL;
+//[MSH_END]
+
+ //stacks = new QvElement[NumStacks];
+ //stacks = (QvElement **) new QvElement[NumStacks];
+ //stacks = new QvElement * [NumStacks];
+
+ int i = 0;
+ for (i = 0; i < NumStacks; i++){
+ stacks[i] = NULL;
+ }
+ depth = 0;
+}
+
+QvState::~QvState()
+{
+ while (depth > 0)
+ pop();
+
+ //delete [] stacks;
+}
+
+void
+QvState::addElement(StackIndex stackIndex, QvElement *elt)
+{
+ elt->depth = depth;
+ elt->next = stacks[stackIndex];
+ stacks[stackIndex] = elt;
+}
+
+void
+QvState::push()
+{
+ depth++;
+}
+
+void
+QvState::pop()
+{
+ depth--;
+
+ for (int i = 0; i < NumStacks; i++)
+ while (stacks[i] != NULL && stacks[i]->depth > depth)
+ popElement((StackIndex) i);
+}
+
+void
+QvState::popElement(StackIndex stackIndex)
+{
+ QvElement *elt = stacks[stackIndex];
+ stacks[stackIndex] = elt->next;
+ delete elt;
+}
+
+void
+QvState::print()
+{
+ printf("Traversal state:\n");
+
+ for (int i = 0; i < NumStacks; i++) {
+ printf("\tStack [%2d] (%s):\n", i, stackNames[i]);
+
+ if (stacks[i] == NULL){
+ printf("\t\tNULL\n");
+ } else {
+ for (QvElement *elt = stacks[i]; elt != NULL; elt = elt->next) {
+ elt->print();
+//[MSH_START]
+/*
+ if ( i == Coordinate3Index ) {
+ QvCoordinate3 *c3 = (QvCoordinate3 *) elt->data;
+ for ( int j = 0; j < c3->point.num; j++ )
+ printf( "point[%d]=%f %f %f\n", j, c3->point.values[ j*3 ], c3->point.values[ j*3 + 1 ], c3->point.values[ j*3 + 2 ] );
+
+ }
+*/
+//[MSH_END]
+ }
+ }
+
+ }
+}
diff --git a/tool_src/QvLib/QvState.h b/tool_src/QvLib/QvState.h
new file mode 100644
index 0000000..433f8f2
--- /dev/null
+++ b/tool_src/QvLib/QvState.h
@@ -0,0 +1,64 @@
+#ifndef _QV_STATE_
+#define _QV_STATE_
+
+#include <QvElement.h>
+
+//[MSH_START]
+#include "VrmlFile.h"
+//[MSH_END]
+
+class QvState {
+
+ public:
+
+ // Stack indices, based on type of elements in them:
+ enum StackIndex {
+ CameraIndex,
+ Coordinate3Index,
+ LightIndex,
+ MaterialBindingIndex,
+ MaterialIndex,
+ NormalBindingIndex,
+ NormalIndex,
+ ShapeHintsIndex,
+ Texture2Index,
+ Texture2TransformationIndex,
+ TextureCoordinate2Index,
+ TransformationIndex,
+
+ // This has to be last!!!
+ NumStacks,
+ };
+
+ static const char *stackNames[NumStacks]; // Names of stacks
+
+ int depth; // Current state depth
+ QvElement *stacks[NumStacks]; // Stacks of elements
+
+//[MSH_START]
+ BSPLIB_NAMESPACE::VrmlFile *vrmlfile_base;
+ QvState( BSPLIB_NAMESPACE::VrmlFile *base );
+//[MSH_END]
+
+ QvState();
+ ~QvState();
+
+ // Adds an element instance to the indexed stack
+ void addElement(StackIndex stackIndex, QvElement *elt);
+
+ // Returns top element on a stack
+ QvElement * getTopElement(StackIndex stackIndex)
+ { return stacks[stackIndex]; }
+
+ // Pushes/pops the stacks
+ void push();
+ void pop();
+
+ // Pops top element off one stack
+ void popElement(StackIndex stackIndex);
+
+ // Prints contents for debugging, mostly
+ void print();
+};
+
+#endif /* _QV_STATE_ */
diff --git a/tool_src/QvLib/QvString.cpp b/tool_src/QvLib/QvString.cpp
new file mode 100644
index 0000000..a5562a3
--- /dev/null
+++ b/tool_src/QvLib/QvString.cpp
@@ -0,0 +1,106 @@
+#include <QvString.h>
+
+QvString::~QvString()
+{
+ if (string != staticStorage)
+ delete [] string;
+}
+
+void
+QvString::expand(int bySize)
+{
+ int newSize = strlen(string) + bySize + 1;
+
+ if (newSize >= QV_STRING_STATIC_STORAGE_SIZE &&
+ (string == staticStorage || newSize > storageSize)) {
+
+ char *newString = new char[newSize];
+
+ strcpy(newString, string);
+
+ if (string != staticStorage)
+ delete [] string;
+
+ string = newString;
+ storageSize = newSize;
+ }
+}
+
+u_long
+QvString::hash(const char *s)
+{
+ u_long total, shift;
+
+ total = shift = 0;
+ while (*s) {
+ total = total ^ ((*s) << shift);
+ shift+=5;
+ if (shift>24) shift -= 24;
+ s++;
+ }
+
+ return( total );
+}
+
+void
+QvString::makeEmpty(QvBool freeOld)
+{
+ if (string != staticStorage) {
+ if (freeOld)
+ delete [] string;
+ string = staticStorage;
+ }
+ string[0] = '\0';
+}
+
+QvString &
+QvString::operator =(const char *str)
+{
+ int size = strlen(str) + 1;
+
+ if (str >= string &&
+ str < string + (string != staticStorage ? storageSize :
+ QV_STRING_STATIC_STORAGE_SIZE)) {
+
+ QvString tmp = str;
+ *this = tmp;
+ return *this;
+ }
+
+ if (size < QV_STRING_STATIC_STORAGE_SIZE) {
+ if (string != staticStorage)
+ makeEmpty();
+ }
+
+ else if (string == staticStorage)
+ string = new char[size];
+
+ else if (size > storageSize) {
+ delete [] string;
+ string = new char[size];
+ }
+
+ strcpy(string, str);
+ storageSize = size;
+ return *this;
+}
+
+QvString &
+QvString::operator +=(const char *str)
+{
+ expand(strlen(str));
+ strcat(string, str);
+ return *this;
+}
+
+int
+operator ==(const QvString &str, const char *s)
+{
+ return (str.string[0] == s[0] && ! strcmp(str.string, s));
+}
+
+int
+operator !=(const QvString &str, const char *s)
+{
+ return (str.string[0] != s[0] || strcmp(str.string, s));
+}
diff --git a/tool_src/QvLib/QvString.h b/tool_src/QvLib/QvString.h
new file mode 100644
index 0000000..ae49676
--- /dev/null
+++ b/tool_src/QvLib/QvString.h
@@ -0,0 +1,101 @@
+#ifndef _QV_STRING_
+#define _QV_STRING_
+
+#include <QvBasic.h>
+#include <string.h>
+
+class QvString {
+ public:
+ QvString() { string = staticStorage;
+ string[0] = '\0'; }
+ QvString(const char *str) { string = staticStorage;
+ *this = str; }
+ QvString(const QvString &str) { string = staticStorage;
+ *this = str.string; }
+ ~QvString();
+ u_long hash() { return QvString::hash(string); }
+ int getLength() const { return strlen(string); }
+ void makeEmpty(QvBool freeOld = TRUE);
+ const char * getString() const { return string; }
+ QvString & operator =(const char *str);
+ QvString & operator =(const QvString &str)
+ { return (*this = str.string); }
+ QvString & operator +=(const char *str);
+ int operator !() const { return (string[0] == '\0'); }
+ friend int operator ==(const QvString &str, const char *s);
+
+ friend int operator ==(const char *s, const QvString &str)
+ { return (str == s); }
+
+ friend int operator ==(const QvString &str1, const QvString &str2)
+ { return (str1 == str2.string); }
+ friend int operator !=(const QvString &str, const char *s);
+
+ friend int operator !=(const char *s, const QvString &str)
+ { return (str != s); }
+ friend int operator !=(const QvString &str1,
+ const QvString &str2)
+ { return (str1 != str2.string); }
+ static u_long hash(const char *s);
+ private:
+ char *string;
+ int storageSize;
+#define QV_STRING_STATIC_STORAGE_SIZE 32
+ char staticStorage[QV_STRING_STATIC_STORAGE_SIZE];
+ void expand(int bySize);
+};
+
+class QvNameEntry {
+ public:
+ QvBool isEmpty() const { return (string[0] == '\0'); }
+ QvBool isEqual(const char *s) const
+ { return (string[0] == s[0] && ! strcmp(string, s)); }
+ private:
+ static int nameTableSize;
+ static QvNameEntry **nameTable;
+ static struct QvNameChunk *chunk;
+ const char *string;
+ u_long hashValue;
+ QvNameEntry *next;
+ static void initClass();
+ QvNameEntry(const char *s, u_long h, QvNameEntry *n)
+ { string = s; hashValue = h; next = n; }
+ static const QvNameEntry * insert(const char *s);
+
+friend class QvName;
+};
+
+class QvName {
+ public:
+ QvName();
+ QvName(const char *s) { entry = QvNameEntry::insert(s); }
+ QvName(const QvString &s) { entry = QvNameEntry::insert(s.getString()); }
+
+ QvName(const QvName &n) { entry = n.entry; }
+ ~QvName() {}
+ const char *getString() const { return entry->string; }
+ int getLength() const { return strlen(entry->string); }
+ static QvBool isIdentStartChar(char c);
+ static QvBool isIdentChar(char c);
+ static QvBool isNodeNameStartChar(char c);
+ static QvBool isNodeNameChar(char c);
+ int operator !() const { return entry->isEmpty(); }
+ friend int operator ==(const QvName &n, const char *s)
+ { return n.entry->isEqual(s); }
+ friend int operator ==(const char *s, const QvName &n)
+ { return n.entry->isEqual(s); }
+
+ friend int operator ==(const QvName &n1, const QvName &n2)
+ { return n1.entry == n2.entry; }
+ friend int operator !=(const QvName &n, const char *s)
+ { return ! n.entry->isEqual(s); }
+ friend int operator !=(const char *s, const QvName &n)
+ { return ! n.entry->isEqual(s); }
+
+ friend int operator !=(const QvName &n1, const QvName &n2)
+ { return n1.entry != n2.entry; }
+ private:
+ const QvNameEntry *entry;
+};
+
+#endif /* _QV_STRING_ */
diff --git a/tool_src/QvLib/QvSubField.h b/tool_src/QvLib/QvSubField.h
new file mode 100644
index 0000000..a9fdea5
--- /dev/null
+++ b/tool_src/QvLib/QvSubField.h
@@ -0,0 +1,72 @@
+#ifndef _QV_SUB_FIELD_
+#define _QV_SUB_FIELD_
+
+#include <QvField.h>
+#include <QvInput.h>
+
+/////////////////////////////////////////////////////////////////////////////
+
+#define QV_SFIELD_HEADER(className) \
+ public: \
+ className(); \
+ virtual ~className(); \
+ virtual QvBool readValue(QvInput *in)
+
+/////////////////////////////////////////////////////////////////////////////
+
+#define QV_MFIELD_HEADER(className) \
+ public: \
+ className(); \
+ virtual ~className(); \
+ virtual QvBool read1Value(QvInput *in, int index); \
+ void allocValues(int newNum)
+
+/////////////////////////////////////////////////////////////////////////////
+
+#define QV_SFIELD_SOURCE(className) \
+ \
+className::className() \
+{ \
+} \
+className::~className() \
+{ \
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+#define QV_MFIELD_SOURCE(className, valueType, numValues) \
+ \
+className::className() \
+{ \
+ values = NULL; \
+ /* Make room for 1 value to start */ \
+ allocValues(1); \
+} \
+ \
+className::~className() \
+{ \
+ if (values != NULL) \
+ free((char *) values); \
+} \
+ \
+void \
+className::allocValues(int newNum) \
+{ \
+ if (values == NULL) { \
+ if (newNum > 0) \
+ values = (valueType *) \
+ malloc(numValues * sizeof(valueType) * newNum); \
+ } \
+ else { \
+ if (newNum > 0) \
+ values = (valueType *) \
+ realloc(values, numValues * sizeof(valueType) * newNum); \
+ else { \
+ free((char *) values); \
+ values = NULL; \
+ } \
+ } \
+ num = maxNum = newNum; \
+}
+
+#endif /* _QV_SUB_FIELD_ */
diff --git a/tool_src/QvLib/QvSubNode.h b/tool_src/QvLib/QvSubNode.h
new file mode 100644
index 0000000..c79c025
--- /dev/null
+++ b/tool_src/QvLib/QvSubNode.h
@@ -0,0 +1,41 @@
+#ifndef _QV_SUB_NODE_
+#define _QV_SUB_NODE_
+
+#include <QvFieldData.h>
+#include <QvNode.h>
+
+#define QV_NODE_HEADER(className) \
+ public: \
+ className(); \
+ virtual ~className(); \
+ virtual void traverse(QvState *state); \
+ private: \
+ static QvBool firstInstance; \
+ static QvFieldData *fieldData; \
+ virtual QvFieldData *getFieldData() { return fieldData; }
+
+#define QV_NODE_SOURCE(className) \
+ QvFieldData *className::fieldData; \
+ QvBool className::firstInstance = TRUE;
+
+#define QV_NODE_CONSTRUCTOR(className) \
+ if (fieldData == NULL) \
+ fieldData = new QvFieldData; \
+ else \
+ firstInstance = FALSE; \
+ isBuiltIn = FALSE; \
+
+#define QV_NODE_IS_FIRST_INSTANCE() (firstInstance == TRUE)
+
+#define QV_NODE_ADD_FIELD(fieldName) \
+ if (firstInstance) \
+ fieldData->addField(this, QV__QUOTE(fieldName), &this->fieldName); \
+ this->fieldName.setContainer(this);
+
+#define QV_NODE_DEFINE_ENUM_VALUE(enumType,enumValue) \
+ if (firstInstance) \
+ fieldData->addEnumValue(QV__QUOTE(enumType), \
+ QV__QUOTE(enumValue), enumValue)
+
+#endif /* _QV_SUB_NODE_ */
+
diff --git a/tool_src/QvLib/QvSwitch.cpp b/tool_src/QvLib/QvSwitch.cpp
new file mode 100644
index 0000000..ddbc8e4
--- /dev/null
+++ b/tool_src/QvLib/QvSwitch.cpp
@@ -0,0 +1,17 @@
+#include <QvSwitch.h>
+
+QV_NODE_SOURCE(QvSwitch);
+
+QvSwitch::QvSwitch()
+{
+ QV_NODE_CONSTRUCTOR(QvSwitch);
+ isBuiltIn = TRUE;
+
+ QV_NODE_ADD_FIELD(whichChild);
+
+ whichChild.value = QV_SWITCH_NONE;
+}
+
+QvSwitch::~QvSwitch()
+{
+}
diff --git a/tool_src/QvLib/QvSwitch.h b/tool_src/QvLib/QvSwitch.h
new file mode 100644
index 0000000..47998cc
--- /dev/null
+++ b/tool_src/QvLib/QvSwitch.h
@@ -0,0 +1,19 @@
+#ifndef _QV_SWITCH_
+#define _QV_SWITCH_
+
+#include <QvSFLong.h>
+#include <QvGroup.h>
+
+#define QV_SWITCH_NONE (-1) /* Don't traverse any children */
+#define QV_SWITCH_ALL (-3) /* Traverse all children */
+
+class QvSwitch : public QvGroup {
+
+ QV_NODE_HEADER(QvSwitch);
+
+ public:
+ // Fields
+ QvSFLong whichChild; // Child to traverse
+};
+
+#endif /* _QV_SWITCH_ */
diff --git a/tool_src/QvLib/QvTexture2.cpp b/tool_src/QvLib/QvTexture2.cpp
new file mode 100644
index 0000000..ca06351
--- /dev/null
+++ b/tool_src/QvLib/QvTexture2.cpp
@@ -0,0 +1,55 @@
+#include <QvTexture2.h>
+
+QV_NODE_SOURCE(QvTexture2);
+
+QvTexture2::QvTexture2()
+{
+ QV_NODE_CONSTRUCTOR(QvTexture2);
+ isBuiltIn = TRUE;
+
+ QV_NODE_ADD_FIELD(filename);
+ QV_NODE_ADD_FIELD(image);
+ QV_NODE_ADD_FIELD(wrapS);
+ QV_NODE_ADD_FIELD(wrapT);
+
+ filename.value = "";
+ image.size[0] = image.size[1] = 0.0;
+ image.numComponents = 0;
+ image.bytes = NULL;
+ wrapS.value = REPEAT;
+ wrapT.value = REPEAT;
+
+ QV_NODE_DEFINE_ENUM_VALUE(Wrap, REPEAT);
+ QV_NODE_DEFINE_ENUM_VALUE(Wrap, CLAMP);
+
+ QV_NODE_SET_SF_ENUM_TYPE(wrapS, Wrap);
+ QV_NODE_SET_SF_ENUM_TYPE(wrapT, Wrap);
+}
+
+QvTexture2::~QvTexture2()
+{
+}
+
+QvBool
+QvTexture2::readInstance(QvInput *in)
+{
+ QvBool readOK = QvNode::readInstance(in);
+
+ if (readOK && ! filename.isDefault()) {
+ if (! readImage())
+ readOK = FALSE;
+ image.setDefault(TRUE);
+ }
+
+ return readOK;
+}
+
+QvBool
+QvTexture2::readImage()
+{
+ // ???
+ // ??? Read image from filename and store results in image field.
+ // ???
+
+ return TRUE;
+}
diff --git a/tool_src/QvLib/QvTexture2.h b/tool_src/QvLib/QvTexture2.h
new file mode 100644
index 0000000..2933078
--- /dev/null
+++ b/tool_src/QvLib/QvTexture2.h
@@ -0,0 +1,29 @@
+#ifndef _QV_TEXTURE_2_
+#define _QV_TEXTURE_2_
+
+#include <QvSFEnum.h>
+#include <QvSFImage.h>
+#include <QvSFString.h>
+#include <QvSubNode.h>
+
+class QvTexture2 : public QvNode {
+
+ QV_NODE_HEADER(QvTexture2);
+
+ public:
+ enum Wrap { // Texture wrap type
+ REPEAT,
+ CLAMP,
+ };
+
+ // Fields.
+ QvSFString filename; // file to read texture from
+ QvSFImage image; // The texture
+ QvSFEnum wrapS;
+ QvSFEnum wrapT;
+
+ virtual QvBool readInstance(QvInput *in);
+ QvBool readImage();
+};
+
+#endif /* _QV_TEXTURE_2_ */
diff --git a/tool_src/QvLib/QvTexture2Transform.cpp b/tool_src/QvLib/QvTexture2Transform.cpp
new file mode 100644
index 0000000..22b2e6f
--- /dev/null
+++ b/tool_src/QvLib/QvTexture2Transform.cpp
@@ -0,0 +1,23 @@
+#include <QvTexture2Transform.h>
+
+QV_NODE_SOURCE(QvTexture2Transform);
+
+QvTexture2Transform::QvTexture2Transform()
+{
+ QV_NODE_CONSTRUCTOR(QvTexture2Transform);
+ isBuiltIn = TRUE;
+
+ QV_NODE_ADD_FIELD(translation);
+ QV_NODE_ADD_FIELD(rotation);
+ QV_NODE_ADD_FIELD(scaleFactor);
+ QV_NODE_ADD_FIELD(center);
+
+ translation.value[0] = translation.value[1] = 0.0;
+ rotation.value = 0.0;
+ scaleFactor.value[0] = scaleFactor.value[1] = 1.0;
+ center.value[0] = center.value[1] = 0.0;
+}
+
+QvTexture2Transform::~QvTexture2Transform()
+{
+}
diff --git a/tool_src/QvLib/QvTexture2Transform.h b/tool_src/QvLib/QvTexture2Transform.h
new file mode 100644
index 0000000..e2b5066
--- /dev/null
+++ b/tool_src/QvLib/QvTexture2Transform.h
@@ -0,0 +1,20 @@
+#ifndef _QV_TEXTURE_2_TRANSFORM_
+#define _QV_TEXTURE_2_TRANSFORM_
+
+#include <QvSFFloat.h>
+#include <QvSFVec2f.h>
+#include <QvSubNode.h>
+
+class QvTexture2Transform : public QvNode {
+
+ QV_NODE_HEADER(QvTexture2Transform);
+
+ public:
+ // Fields
+ QvSFVec2f translation; // Translation vector
+ QvSFFloat rotation; // Rotation
+ QvSFVec2f scaleFactor; // Scale factors
+ QvSFVec2f center; // Center point for scale and rotate
+};
+
+#endif /* _QV_TEXTURE_2_TRANSFORM_ */
diff --git a/tool_src/QvLib/QvTextureCoordinate2.cpp b/tool_src/QvLib/QvTextureCoordinate2.cpp
new file mode 100644
index 0000000..f2783b1
--- /dev/null
+++ b/tool_src/QvLib/QvTextureCoordinate2.cpp
@@ -0,0 +1,17 @@
+#include <QvTextureCoordinate2.h>
+
+QV_NODE_SOURCE(QvTextureCoordinate2);
+
+QvTextureCoordinate2::QvTextureCoordinate2()
+{
+ QV_NODE_CONSTRUCTOR(QvTextureCoordinate2);
+ isBuiltIn = TRUE;
+
+ QV_NODE_ADD_FIELD(point);
+
+ point.values[0] = point.values[1] = 0.0;
+}
+
+QvTextureCoordinate2::~QvTextureCoordinate2()
+{
+}
diff --git a/tool_src/QvLib/QvTextureCoordinate2.h b/tool_src/QvLib/QvTextureCoordinate2.h
new file mode 100644
index 0000000..9534e94
--- /dev/null
+++ b/tool_src/QvLib/QvTextureCoordinate2.h
@@ -0,0 +1,16 @@
+#ifndef _QV_TEXTURE_COORDINATE_2_
+#define _QV_TEXTURE_COORDINATE_2_
+
+#include <QvMFVec2f.h>
+#include <QvSubNode.h>
+
+class QvTextureCoordinate2 : public QvNode {
+
+ QV_NODE_HEADER(QvTextureCoordinate2);
+
+ public:
+ // Fields
+ QvMFVec2f point; // TextureCoordinate point(s)
+};
+
+#endif /* _QV_TEXTURE_COORDINATE_2_ */
diff --git a/tool_src/QvLib/QvTransform.cpp b/tool_src/QvLib/QvTransform.cpp
new file mode 100644
index 0000000..5e265f1
--- /dev/null
+++ b/tool_src/QvLib/QvTransform.cpp
@@ -0,0 +1,31 @@
+#include <QvTransform.h>
+
+QV_NODE_SOURCE(QvTransform);
+
+QvTransform::QvTransform()
+{
+ QV_NODE_CONSTRUCTOR(QvTransform);
+ isBuiltIn = TRUE;
+
+ QV_NODE_ADD_FIELD(translation);
+ QV_NODE_ADD_FIELD(rotation);
+ QV_NODE_ADD_FIELD(scaleFactor);
+ QV_NODE_ADD_FIELD(scaleOrientation);
+ QV_NODE_ADD_FIELD(center);
+
+ translation.value[0] = translation.value[1] = translation.value[2] = 0.0;
+ rotation.axis[0] = 0.0;
+ rotation.axis[1] = 0.0;
+ rotation.axis[2] = 1.0;
+ rotation.angle = 0.0;
+ scaleFactor.value[0] = scaleFactor.value[1] = scaleFactor.value[2] = 1.0;
+ scaleOrientation.axis[0] = 0.0;
+ scaleOrientation.axis[1] = 0.0;
+ scaleOrientation.axis[2] = 1.0;
+ scaleOrientation.angle = 0.0;
+ center.value[0] = center.value[1] = center.value[2] = 0.0;
+}
+
+QvTransform::~QvTransform()
+{
+}
diff --git a/tool_src/QvLib/QvTransform.h b/tool_src/QvLib/QvTransform.h
new file mode 100644
index 0000000..be64031
--- /dev/null
+++ b/tool_src/QvLib/QvTransform.h
@@ -0,0 +1,21 @@
+#ifndef _QV_TRANSFORM_
+#define _QV_TRANSFORM_
+
+#include <QvSFRotation.h>
+#include <QvSFVec3f.h>
+#include <QvSubNode.h>
+
+class QvTransform : public QvNode {
+
+ QV_NODE_HEADER(QvTransform);
+
+ public:
+ // Fields
+ QvSFVec3f translation; // Translation vector
+ QvSFRotation rotation; // Rotation
+ QvSFVec3f scaleFactor; // Scale factors
+ QvSFRotation scaleOrientation;// Defines rotational space for scale
+ QvSFVec3f center; // Center point for scale and rotate
+};
+
+#endif /* _QV_TRANSFORM_ */
diff --git a/tool_src/QvLib/QvTransformSeparator.cpp b/tool_src/QvLib/QvTransformSeparator.cpp
new file mode 100644
index 0000000..416754f
--- /dev/null
+++ b/tool_src/QvLib/QvTransformSeparator.cpp
@@ -0,0 +1,13 @@
+#include <QvTransformSeparator.h>
+
+QV_NODE_SOURCE(QvTransformSeparator);
+
+QvTransformSeparator::QvTransformSeparator()
+{
+ QV_NODE_CONSTRUCTOR(QvTransformSeparator);
+ isBuiltIn = TRUE;
+}
+
+QvTransformSeparator::~QvTransformSeparator()
+{
+}
diff --git a/tool_src/QvLib/QvTransformSeparator.h b/tool_src/QvLib/QvTransformSeparator.h
new file mode 100644
index 0000000..90cc435
--- /dev/null
+++ b/tool_src/QvLib/QvTransformSeparator.h
@@ -0,0 +1,13 @@
+#ifndef _QV_TRANSFORM_SEPARATOR_
+#define _QV_TRANSFORM_SEPARATOR_
+
+#include <QvGroup.h>
+
+class QvTransformSeparator : public QvGroup {
+
+ QV_NODE_HEADER(QvTransformSeparator);
+
+ // No fields
+};
+
+#endif /* _QV_TRANSFORM_SEPARATOR_ */
diff --git a/tool_src/QvLib/QvTranslation.cpp b/tool_src/QvLib/QvTranslation.cpp
new file mode 100644
index 0000000..1b79720
--- /dev/null
+++ b/tool_src/QvLib/QvTranslation.cpp
@@ -0,0 +1,17 @@
+#include <QvTranslation.h>
+
+QV_NODE_SOURCE(QvTranslation);
+
+QvTranslation::QvTranslation()
+{
+ QV_NODE_CONSTRUCTOR(QvTranslation);
+ isBuiltIn = TRUE;
+
+ QV_NODE_ADD_FIELD(translation);
+
+ translation.value[0] = translation.value[1] = translation.value[2] = 0.0;
+}
+
+QvTranslation::~QvTranslation()
+{
+}
diff --git a/tool_src/QvLib/QvTranslation.h b/tool_src/QvLib/QvTranslation.h
new file mode 100644
index 0000000..0921b5d
--- /dev/null
+++ b/tool_src/QvLib/QvTranslation.h
@@ -0,0 +1,16 @@
+#ifndef _QV_TRANSLATION_
+#define _QV_TRANSLATION_
+
+#include <QvSFVec3f.h>
+#include <QvSubNode.h>
+
+class QvTranslation : public QvNode {
+
+ QV_NODE_HEADER(QvTranslation);
+
+ public:
+ // Fields
+ QvSFVec3f translation; // Translation vector
+};
+
+#endif /* _QV_TRANSLATION_ */
diff --git a/tool_src/QvLib/QvTraverse.cpp b/tool_src/QvLib/QvTraverse.cpp
new file mode 100644
index 0000000..07da40c
--- /dev/null
+++ b/tool_src/QvLib/QvTraverse.cpp
@@ -0,0 +1,317 @@
+#include <QvElement.h>
+#include <QvNodes.h>
+#include <QvState.h>
+//#ifdef WIN32
+#include <QvUnknownNode.h>
+//#endif
+
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// Traversal code for all nodes. The default method (in QvNode) does
+// nothing. Because traverse() is defined in the header for ALL node
+// classes, each one has an implementation here.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+// For debugging
+static int indent = 0;
+static void
+announce(const char *className)
+{
+ for (int i = 0; i < indent; i++)
+ printf("\t");
+ printf("Traversing a %s\n", className);
+}
+#define ANNOUNCE(className) announce(QV__QUOTE(className))
+
+#define DEFAULT_TRAVERSE(className) \
+void \
+className::traverse(QvState *) \
+{ \
+ ANNOUNCE(className); \
+}
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// Groups.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+void
+QvGroup::traverse(QvState *state)
+{
+ ANNOUNCE(QvGroup);
+ indent++;
+ for (int i = 0; i < getNumChildren(); i++)
+ getChild(i)->traverse(state);
+ indent--;
+}
+
+void
+QvLevelOfDetail::traverse(QvState *state)
+{
+ ANNOUNCE(QvLevelOfDetail);
+ indent++;
+
+ // ??? In a real implementation, this would choose a child based
+ // ??? on the projected screen areas.
+ if (getNumChildren() > 0)
+ getChild(0)->traverse(state);
+
+ indent--;
+}
+
+void
+QvSeparator::traverse(QvState *state)
+{
+ ANNOUNCE(QvSeparator);
+ state->push();
+ indent++;
+ for (int i = 0; i < getNumChildren(); i++)
+ getChild(i)->traverse(state);
+ indent--;
+ state->pop();
+}
+
+void
+QvSwitch::traverse(QvState *state)
+{
+ ANNOUNCE(QvSwitch);
+ indent++;
+
+ int which = whichChild.value;
+
+ if (which == QV_SWITCH_NONE)
+ ;
+
+ else if (which == QV_SWITCH_ALL)
+ for (int i = 0; i < getNumChildren(); i++)
+ getChild(i)->traverse(state);
+
+ else
+ if (which < getNumChildren())
+ getChild(which)->traverse(state);
+
+ indent--;
+}
+
+void
+QvTransformSeparator::traverse(QvState *state)
+{
+ ANNOUNCE(QvTransformSeparator);
+
+ // We need to "push" just the transformation stack. We'll
+ // accomplish this by just pushing a no-op transformation onto
+ // that stack. When we "pop", we'll restore that stack to its
+ // previous state.
+
+ QvElement *markerElt = new QvElement;
+ markerElt->data = this;
+ markerElt->type = QvElement::NoOpTransform;
+ state->addElement(QvState::TransformationIndex, markerElt);
+
+ indent++;
+ for (int i = 0; i < getNumChildren(); i++)
+ getChild(i)->traverse(state);
+ indent--;
+
+ // Now do the "pop"
+ while (state->getTopElement(QvState::TransformationIndex) != markerElt)
+ state->popElement(QvState::TransformationIndex);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// Properties.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#define DO_PROPERTY(className, stackIndex) \
+void \
+className::traverse(QvState *state) \
+{ \
+ ANNOUNCE(className); \
+ QvElement *elt = new QvElement; \
+ elt->data = this; \
+ state->addElement(QvState::stackIndex, elt); \
+}
+
+#define DO_TYPED_PROPERTY(className, stackIndex, eltType) \
+void \
+className::traverse(QvState *state) \
+{ \
+ ANNOUNCE(className); \
+ QvElement *elt = new QvElement; \
+ elt->data = this; \
+ elt->type = QvElement::eltType; \
+ state->addElement(QvState::stackIndex, elt); \
+}
+
+
+void QvCoordinate3::traverse(QvState *state)
+{
+ ANNOUNCE(QvCoordinate3);
+ QvElement *elt = new QvElement;
+ elt->data = this;
+ state->addElement(QvState::Coordinate3Index, elt);
+
+//[MSH_START]
+/*
+ for ( int i = 0; i < point.num; i++ )
+ printf( "point[%d]=%f %f %f\n", i, point.values[ i*3 ], point.values[ i*3 + 1 ], point.values[ i*3 + 2 ] );
+*/
+//[MSH_END]
+
+ printf( "---------------------------------------\n" );
+}
+//DO_PROPERTY(QvCoordinate3, Coordinate3Index)
+//--------------------------------------------
+
+DO_PROPERTY(QvMaterial, MaterialIndex)
+DO_PROPERTY(QvMaterialBinding, MaterialBindingIndex)
+DO_PROPERTY(QvNormal, NormalIndex)
+DO_PROPERTY(QvNormalBinding, NormalBindingIndex)
+DO_PROPERTY(QvShapeHints, ShapeHintsIndex)
+DO_PROPERTY(QvTextureCoordinate2, TextureCoordinate2Index)
+DO_PROPERTY(QvTexture2, Texture2Index)
+DO_PROPERTY(QvTexture2Transform, Texture2TransformationIndex)
+
+DO_TYPED_PROPERTY(QvDirectionalLight, LightIndex, DirectionalLight)
+DO_TYPED_PROPERTY(QvPointLight, LightIndex, PointLight)
+DO_TYPED_PROPERTY(QvSpotLight, LightIndex, SpotLight)
+
+DO_TYPED_PROPERTY(QvOrthographicCamera, CameraIndex, OrthographicCamera)
+DO_TYPED_PROPERTY(QvPerspectiveCamera, CameraIndex, PerspectiveCamera)
+
+DO_TYPED_PROPERTY(QvTransform, TransformationIndex, Transform)
+DO_TYPED_PROPERTY(QvRotation, TransformationIndex, Rotation)
+DO_TYPED_PROPERTY(QvMatrixTransform, TransformationIndex, MatrixTransform)
+DO_TYPED_PROPERTY(QvTranslation, TransformationIndex, Translation)
+DO_TYPED_PROPERTY(QvScale, TransformationIndex, Scale)
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// Shapes.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+static void
+printProperties(QvState *state)
+{
+ printf("--------------------------------------------------------------\n");
+ state->print();
+ printf("--------------------------------------------------------------\n");
+}
+
+#define DO_SHAPE(className) \
+void \
+className::traverse(QvState *state) \
+{ \
+ ANNOUNCE(className); \
+ printProperties(state); \
+}
+
+//[MSH_START]
+/*
+void QvCone::traverse(QvState *state)
+{
+ ANNOUNCE(QvCone);
+ printf( "\tbottomRadius=%f\n", bottomRadius.value );
+ printf( "\theight=%f\n", height.value );
+ printf( "\tparts=%d\n", parts.value );
+ printf( "---------------------------------------\n" );
+ printProperties(state);
+}
+*/
+//[MSH_END]
+
+
+
+//[MSH_START]
+
+//DO_SHAPE(QvSphere)
+//DO_SHAPE(QvCone)
+//DO_SHAPE(QvCube)
+//DO_SHAPE(QvCylinder)
+
+#include "BspObjectList.h"
+#include "BRep.h"
+
+void QvSphere::traverse(QvState *state)
+{
+ ANNOUNCE(QvSphere);
+ BSPLIB_NAMESPACE::BRep brep( state );
+ brep.BuildFromSpherePrimitive( *this );
+}
+
+void QvCone::traverse(QvState *state)
+{
+ ANNOUNCE(QvCone);
+ BSPLIB_NAMESPACE::BRep brep( state );
+ brep.BuildFromConePrimitive( *this );
+}
+
+void QvCube::traverse(QvState *state)
+{
+ ANNOUNCE(QvCube);
+ BSPLIB_NAMESPACE::BRep brep( state );
+ brep.BuildFromCubePrimitive( *this );
+}
+
+
+void QvCylinder::traverse(QvState *state)
+{
+ ANNOUNCE(QvCylinder);
+ BSPLIB_NAMESPACE::BRep brep( state );
+ brep.BuildFromCylinderPrimitive( *this );
+}
+
+void QvIndexedFaceSet::traverse(QvState *state)
+{
+ ANNOUNCE(QvIndexedFaceSet);
+/*
+ for ( int i = 0; i < coordIndex.num; i++ )
+ printf( "coordIndex[%d]=%d\n", i, coordIndex.values[ i ] );
+ printf( "---------------------------------------\n" );
+*/
+ // build b-rep out of this indexed face set and current state
+ BSPLIB_NAMESPACE::BRep brep( state );
+ brep.BuildFromIndexedFaceSet( *this );
+}
+//[MSH_END]
+
+//DO_SHAPE(QvIndexedFaceSet)
+//--------------------------------------------
+
+DO_SHAPE(QvIndexedLineSet)
+DO_SHAPE(QvPointSet)
+
+
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// WWW-specific nodes.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+// ???
+DEFAULT_TRAVERSE(QvWWWAnchor)
+DEFAULT_TRAVERSE(QvWWWInline)
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// Default traversal methods. These nodes have no effects during traversal.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+DEFAULT_TRAVERSE(QvInfo)
+DEFAULT_TRAVERSE(QvUnknownNode)
+
+//////////////////////////////////////////////////////////////////////////////
+
+#undef ANNOUNCE
+#undef DEFAULT_TRAVERSE
+#undef DO_PROPERTY
+#undef DO_SHAPE
+#undef DO_TYPED_PROPERTY
diff --git a/tool_src/QvLib/QvTraverse.p b/tool_src/QvLib/QvTraverse.p
new file mode 100644
index 0000000..15aa9ae
--- /dev/null
+++ b/tool_src/QvLib/QvTraverse.p
@@ -0,0 +1,15927 @@
+# 1 "QvTraverse.cpp"
+# 1 "QvElement.h" 1
+
+
+
+# 1 "QvBasic.h" 1
+
+
+
+
+
+
+
+
+
+# 1 "/usr/include/sys/types.h" 1 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 1 "/usr/include/sys/cdefs.h" 1 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 121 "/usr/include/sys/cdefs.h" 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 67 "/usr/include/sys/types.h" 2 3 4
+
+
+
+# 1 "/usr/include/machine/types.h" 1 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 1 "/usr/include/ppc/types.h" 1 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+typedef signed char int8_t;
+typedef unsigned char u_int8_t;
+typedef short int16_t;
+typedef unsigned short u_int16_t;
+typedef int int32_t;
+typedef unsigned int u_int32_t;
+typedef long long int64_t;
+typedef unsigned long long u_int64_t;
+
+typedef int32_t register_t;
+
+
+typedef int *intptr_t;
+typedef unsigned long *uintptr_t;
+
+
+
+# 30 "/usr/include/machine/types.h" 2 3 4
+
+
+
+
+
+
+
+
+
+# 70 "/usr/include/sys/types.h" 2 3 4
+
+
+# 1 "/usr/include/machine/ansi.h" 1 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 1 "/usr/include/ppc/ansi.h" 1 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 34 "/usr/include/machine/ansi.h" 2 3 4
+
+
+
+
+
+
+
+
+
+# 72 "/usr/include/sys/types.h" 2 3 4
+
+# 1 "/usr/include/machine/endian.h" 1 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 1 "/usr/include/ppc/endian.h" 1 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+extern "C" {
+unsigned long htonl (unsigned long) ;
+unsigned short htons (unsigned short) ;
+unsigned long ntohl (unsigned long) ;
+unsigned short ntohs (unsigned short) ;
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 116 "/usr/include/ppc/endian.h" 3 4
+
+
+
+# 30 "/usr/include/machine/endian.h" 2 3 4
+
+
+
+
+
+
+
+
+
+# 73 "/usr/include/sys/types.h" 2 3 4
+
+
+
+typedef unsigned char u_char;
+typedef unsigned short u_short;
+typedef unsigned int u_int;
+typedef unsigned long u_long;
+typedef unsigned short ushort;
+typedef unsigned int uint;
+
+
+typedef u_int64_t u_quad_t;
+typedef int64_t quad_t;
+typedef quad_t * qaddr_t;
+
+typedef char * caddr_t;
+typedef int32_t daddr_t;
+typedef int32_t dev_t;
+typedef u_int32_t fixpt_t;
+typedef u_int32_t gid_t;
+typedef u_int32_t ino_t;
+typedef long key_t;
+typedef u_int16_t mode_t;
+typedef u_int16_t nlink_t;
+typedef quad_t off_t;
+typedef int32_t pid_t;
+typedef quad_t rlim_t;
+typedef int32_t segsz_t;
+typedef int32_t swblk_t;
+typedef u_int32_t uid_t;
+
+
+
+
+
+
+
+
+
+
+
+typedef unsigned long clock_t;
+
+
+
+
+typedef long unsigned int size_t;
+
+
+
+
+typedef int ssize_t;
+
+
+
+
+typedef long time_t;
+
+
+
+
+
+
+
+
+
+
+
+
+
+typedef int32_t fd_mask;
+
+
+
+
+
+
+typedef struct fd_set {
+ fd_mask fds_bits[((( 256 ) + (( (sizeof(fd_mask) * 8 ) ) - 1)) / ( (sizeof(fd_mask) * 8 ) )) ];
+} fd_set;
+
+
+
+
+
+
+
+# 174 "/usr/include/sys/types.h" 3 4
+
+
+
+
+
+struct _pthread_handler_rec
+{
+ void (*routine)(void *);
+ void *arg;
+ struct _pthread_handler_rec *next;
+};
+
+
+
+
+
+
+
+
+
+
+
+
+typedef struct _opaque_pthread_t { long sig; struct _pthread_handler_rec *cleanup_stack; char opaque[596 ];} *pthread_t;
+
+typedef struct _opaque_pthread_attr_t { long sig; char opaque[36 ]; } pthread_attr_t;
+
+typedef struct _opaque_pthread_mutexattr_t { long sig; char opaque[8 ]; } pthread_mutexattr_t;
+
+typedef struct _opaque_pthread_mutex_t { long sig; char opaque[40 ]; } pthread_mutex_t;
+
+typedef struct _opaque_pthread_condattr_t { long sig; char opaque[4 ]; } pthread_condattr_t;
+
+typedef struct _opaque_pthread_cond_t { long sig; char opaque[24 ]; } pthread_cond_t;
+
+typedef struct { long sig; char opaque[4 ]; } pthread_once_t;
+
+
+
+typedef unsigned long pthread_key_t;
+
+
+# 10 "QvBasic.h" 2
+
+
+# 1 "/usr/include/libc.h" 1 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 1 "/usr/include/stdio.h" 1 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+typedef off_t fpos_t;
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+struct __sbuf {
+ unsigned char *_base;
+ int _size;
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+typedef struct __sFILE {
+ unsigned char *_p;
+ int _r;
+ int _w;
+ short _flags;
+ short _file;
+ struct __sbuf _bf;
+ int _lbfsize;
+
+
+ void *_cookie;
+ int (*_close) (void *) ;
+ int (*_read) (void *, char *, int) ;
+ fpos_t (*_seek) (void *, fpos_t, int) ;
+ int (*_write) (void *, const char *, int) ;
+
+
+ struct __sbuf _ub;
+ unsigned char *_up;
+ int _ur;
+
+
+ unsigned char _ubuf[3];
+ unsigned char _nbuf[1];
+
+
+ struct __sbuf _lb;
+
+
+ int _blksize;
+ fpos_t _offset;
+} FILE;
+
+extern "C" {
+extern FILE __sF[];
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+extern "C" {
+void clearerr (FILE *) ;
+int fclose (FILE *) ;
+int feof (FILE *) ;
+int ferror (FILE *) ;
+int fflush (FILE *) ;
+int fgetc (FILE *) ;
+int fgetpos (FILE *, fpos_t *) ;
+char *fgets (char *, size_t, FILE *) ;
+FILE *fopen (const char *, const char *) ;
+int fprintf (FILE *, const char *, ...) ;
+int fputc (int, FILE *) ;
+int fputs (const char *, FILE *) ;
+size_t fread (void *, size_t, size_t, FILE *) ;
+FILE *freopen (const char *, const char *, FILE *) ;
+int fscanf (FILE *, const char *, ...) ;
+int fseek (FILE *, long, int) ;
+int fsetpos (FILE *, const fpos_t *) ;
+long ftell (FILE *) ;
+size_t fwrite (const void *, size_t, size_t, FILE *) ;
+int getc (FILE *) ;
+int getchar (void) ;
+char *gets (char *) ;
+
+extern int sys_nerr;
+extern const char * const sys_errlist[];
+
+void perror (const char *) ;
+int printf (const char *, ...) ;
+int putc (int, FILE *) ;
+int putchar (int) ;
+int puts (const char *) ;
+int remove (const char *) ;
+int rename (const char *, const char *) ;
+void rewind (FILE *) ;
+int scanf (const char *, ...) ;
+void setbuf (FILE *, char *) ;
+int setvbuf (FILE *, char *, int, size_t) ;
+int sprintf (char *, const char *, ...) ;
+int sscanf (const char *, const char *, ...) ;
+FILE *tmpfile (void) ;
+char *tmpnam (char *) ;
+int ungetc (int, FILE *) ;
+int vfprintf (FILE *, const char *, char * ) ;
+int vprintf (const char *, char * ) ;
+int vsprintf (char *, const char *, char * ) ;
+}
+
+
+
+
+
+
+
+
+extern "C" {
+char *ctermid (char *) ;
+FILE *fdopen (int, const char *) ;
+int fileno (FILE *) ;
+}
+
+
+
+
+
+
+extern "C" {
+char *fgetln (FILE *, size_t *) ;
+int fpurge (FILE *) ;
+int fseeko (FILE *, fpos_t, int) ;
+fpos_t ftello (FILE *) ;
+int getw (FILE *) ;
+int pclose (FILE *) ;
+FILE *popen (const char *, const char *) ;
+int putw (int, FILE *) ;
+void setbuffer (FILE *, char *, int) ;
+int setlinebuf (FILE *) ;
+char *tempnam (const char *, const char *) ;
+int snprintf (char *, size_t, const char *, ...) ;
+int vsnprintf (char *, size_t, const char *, char * ) ;
+int vscanf (const char *, char * ) ;
+int vsscanf (const char *, const char *, char * ) ;
+FILE *zopen (const char *, const char *, int) ;
+}
+
+
+
+
+
+
+
+
+
+
+
+extern "C" {
+FILE *funopen (const void *,
+ int (*)(void *, char *, int),
+ int (*)(void *, const char *, int),
+ fpos_t (*)(void *, fpos_t, int),
+ int (*)(void *)) ;
+}
+
+
+
+
+
+
+
+extern "C" {
+int __srget (FILE *) ;
+int __svfscanf (FILE *, const char *, char * ) ;
+int __swbuf (int, FILE *) ;
+}
+
+
+
+
+
+
+
+static inline int __sputc(int _c, FILE *_p) {
+ if (--_p->_w >= 0 || (_p->_w >= _p->_lbfsize && (char)_c != '\n'))
+ return (*_p->_p++ = _c);
+ else
+ return (__swbuf(_c, _p));
+}
+# 379 "/usr/include/stdio.h" 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 29 "/usr/include/libc.h" 2 3 4
+
+# 1 "/usr/include/standards.h" 1 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 30 "/usr/include/libc.h" 2 3 4
+
+# 1 "/usr/include/unistd.h" 1 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 1 "/usr/include/sys/unistd.h" 1 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 72 "/usr/include/unistd.h" 2 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+extern "C" {
+ void
+ _exit (int) ;
+int access (const char *, int) ;
+unsigned int alarm (unsigned int) ;
+int chdir (const char *) ;
+int chown (const char *, uid_t, gid_t) ;
+int close (int) ;
+size_t confstr (int, char *, size_t) ;
+int dup (int) ;
+int dup2 (int, int) ;
+int execl (const char *, const char *, ...) ;
+int execle (const char *, const char *, ...) ;
+int execlp (const char *, const char *, ...) ;
+int execv (const char *, char * const *) ;
+int execve (const char *, char * const *, char * const *) ;
+int execvp (const char *, char * const *) ;
+pid_t fork (void) ;
+long fpathconf (int, int) ;
+char *getcwd (char *, size_t) ;
+gid_t getegid (void) ;
+uid_t geteuid (void) ;
+gid_t getgid (void) ;
+int getgroups (int, gid_t []) ;
+char *getlogin (void) ;
+pid_t getpgrp (void) ;
+pid_t getpid (void) ;
+pid_t getppid (void) ;
+uid_t getuid (void) ;
+int isatty (int) ;
+int link (const char *, const char *) ;
+off_t lseek (int, off_t, int) ;
+long pathconf (const char *, int) ;
+int pause (void) ;
+int pipe (int *) ;
+ssize_t read (int, void *, size_t) ;
+int rmdir (const char *) ;
+int setgid (gid_t) ;
+int setpgid (pid_t, pid_t) ;
+pid_t setsid (void) ;
+int setuid (uid_t) ;
+unsigned int sleep (unsigned int) ;
+long sysconf (int) ;
+pid_t tcgetpgrp (int) ;
+int tcsetpgrp (int, pid_t) ;
+char *ttyname (int) ;
+int unlink (const char *) ;
+ssize_t write (int, const void *, size_t) ;
+
+extern char *optarg;
+extern int optind, opterr, optopt, optreset;
+int getopt (int, char * const [], const char *) ;
+
+
+
+struct timeval;
+
+int acct (const char *) ;
+int async_daemon (void) ;
+char *brk (const char *) ;
+int chroot (const char *) ;
+char *crypt (const char *, const char *) ;
+int des_cipher (const char *, char *, long, int) ;
+int des_setkey (const char *key) ;
+int encrypt (char *, int) ;
+void endusershell (void) ;
+int exect (const char *, char * const *, char * const *) ;
+int fchdir (int) ;
+int fchown (int, int, int) ;
+int fsync (int) ;
+int ftruncate (int, off_t) ;
+int getdtablesize (void) ;
+int getgrouplist (const char *, int, int *, int *) ;
+long gethostid (void) ;
+int gethostname (char *, int) ;
+mode_t getmode (const void *, mode_t) ;
+ int
+ getpagesize (void) ;
+char *getpass (const char *) ;
+char *getusershell (void) ;
+char *getwd (char *) ;
+int initgroups (const char *, int) ;
+int iruserok (unsigned long, int, const char *, const char *) ;
+int mknod (const char *, mode_t, dev_t) ;
+int mkstemp (char *) ;
+char *mktemp (char *) ;
+int nfssvc (int, void *) ;
+int nice (int) ;
+
+
+
+
+# 1 "/usr/include/signal.h" 1 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 1 "/usr/include/sys/signal.h" 1 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 1 "/usr/include/machine/signal.h" 1 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 1 "/usr/include/ppc/signal.h" 1 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+typedef int sig_atomic_t;
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+typedef enum {
+ REGS_SAVED_NONE,
+ REGS_SAVED_CALLER,
+
+
+ REGS_SAVED_ALL
+} regs_saved_t;
+
+
+
+
+
+
+
+
+
+struct sigcontext {
+ int sc_onstack;
+ int sc_mask;
+ int sc_ir;
+ int sc_psw;
+ int sc_sp;
+ void *sc_regs;
+};
+
+
+
+# 27 "/usr/include/machine/signal.h" 2 3 4
+
+
+
+
+
+
+
+
+
+# 70 "/usr/include/sys/signal.h" 2 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+typedef unsigned int sigset_t;
+
+
+
+
+struct sigaction {
+
+ void (*sa_handler)(int);
+
+
+
+ sigset_t sa_mask;
+ int sa_flags;
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+typedef void (*sig_t) (int) ;
+
+
+
+
+struct sigaltstack {
+ char *ss_sp;
+ int ss_size;
+ int ss_flags;
+};
+
+
+
+
+
+
+
+struct sigvec {
+ void (*sv_handler)();
+ int sv_mask;
+ int sv_flags;
+};
+
+
+
+
+
+
+
+
+struct sigstack {
+ char *ss_sp;
+ int ss_onstack;
+};
+
+
+
+
+
+
+
+# 213 "/usr/include/sys/signal.h" 3 4
+
+
+
+
+
+
+
+
+
+
+
+extern "C" {
+void (*signal (int, void (*) (int) ) ) (int) ;
+}
+
+# 62 "/usr/include/signal.h" 2 3 4
+
+
+
+extern const char * const sys_signame[32 ];
+extern const char * const sys_siglist[32 ];
+
+
+extern "C" {
+int raise (int) ;
+
+int kill (pid_t, int) ;
+int sigaction (int, const struct sigaction *, struct sigaction *) ;
+int sigaddset (sigset_t *, int) ;
+int sigdelset (sigset_t *, int) ;
+int sigemptyset (sigset_t *) ;
+int sigfillset (sigset_t *) ;
+int sigismember (const sigset_t *, int) ;
+int sigpending (sigset_t *) ;
+int sigprocmask (int, const sigset_t *, sigset_t *) ;
+int sigsuspend (const sigset_t *) ;
+
+int killpg (pid_t, int) ;
+int sigblock (int) ;
+int siginterrupt (int, int) ;
+int sigpause (int) ;
+int sigreturn (struct sigcontext *) ;
+int sigsetmask (int) ;
+int sigvec (int, struct sigvec *, struct sigvec *) ;
+void psignal (unsigned int, const char *) ;
+
+
+}
+
+
+
+
+
+
+
+
+
+# 176 "/usr/include/unistd.h" 2 3 4
+
+
+int profil (char *, int, int, int) ;
+int rcmd (char **, int, const char *,
+ const char *, const char *, int *) ;
+char *re_comp (const char *) ;
+int re_exec (const char *) ;
+int readlink (const char *, char *, int) ;
+int reboot (int) ;
+int revoke (const char *) ;
+int rresvport (int *) ;
+int ruserok (const char *, int, const char *, const char *) ;
+char *sbrk (int) ;
+int select (int, fd_set *, fd_set *, fd_set *, struct timeval *) ;
+int setegid (gid_t) ;
+int seteuid (uid_t) ;
+int setgroups (int, const gid_t *) ;
+void sethostid (long) ;
+int sethostname (const char *, int) ;
+int setkey (const char *) ;
+int setlogin (const char *) ;
+void *setmode (const char *) ;
+int setpgrp (pid_t pid, pid_t pgrp) ;
+int setregid (gid_t, gid_t) ;
+int setreuid (uid_t, uid_t) ;
+int setrgid (gid_t) ;
+int setruid (uid_t) ;
+void setusershell (void) ;
+int swapon (const char *) ;
+int symlink (const char *, const char *) ;
+void sync (void) ;
+int syscall (int, ...) ;
+int truncate (const char *, off_t) ;
+int ttyslot (void) ;
+unsigned int ualarm (unsigned int, unsigned int) ;
+int unwhiteout (const char *) ;
+void usleep (unsigned int) ;
+void *valloc (size_t) ;
+pid_t vfork (void) ;
+
+extern char *suboptarg;
+int getsubopt (char **, char * const *, char **) ;
+
+
+int getattrlist (const char*,void*,void*,size_t,unsigned long) ;
+int setattrlist (const char*,void*,void*,size_t,unsigned long) ;
+int exchangedata (const char*,const char*,unsigned long) ;
+int checkuseraccess (const char*,uid_t,gid_t*,int,int,unsigned long) ;
+int getdirentriesattr (int,void*,void*,size_t,unsigned long*,unsigned long*,unsigned long*,unsigned long) ;
+int searchfs (const char*,void*,void*,unsigned long,unsigned long,void*) ;
+
+int fsctl (const char *,unsigned long,void*,unsigned long) ;
+
+
+
+}
+
+
+# 31 "/usr/include/libc.h" 2 3 4
+
+
+
+
+
+
+# 1 "/usr/include/string.h" 1 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+extern "C" {
+void *memchr (const void *, int, size_t) ;
+int memcmp (const void *, const void *, size_t) ;
+void *memcpy (void *, const void *, size_t) ;
+void *memmove (void *, const void *, size_t) ;
+void *memset (void *, int, size_t) ;
+char *strcat (char *, const char *) ;
+char *strchr (const char *, int) ;
+int strcmp (const char *, const char *) ;
+int strcoll (const char *, const char *) ;
+char *strcpy (char *, const char *) ;
+size_t strcspn (const char *, const char *) ;
+char *strerror (int) ;
+size_t strlen (const char *) ;
+char *strncat (char *, const char *, size_t) ;
+int strncmp (const char *, const char *, size_t) ;
+char *strncpy (char *, const char *, size_t) ;
+char *strpbrk (const char *, const char *) ;
+char *strrchr (const char *, int) ;
+size_t strspn (const char *, const char *) ;
+char *strstr (const char *, const char *) ;
+char *strtok (char *, const char *) ;
+size_t strxfrm (char *, const char *, size_t) ;
+
+
+
+int bcmp (const void *, const void *, size_t) ;
+void bcopy (const void *, void *, size_t) ;
+void bzero (void *, size_t) ;
+int ffs (int) ;
+char *index (const char *, int) ;
+void *memccpy (void *, const void *, int, size_t) ;
+char *rindex (const char *, int) ;
+int strcasecmp (const char *, const char *) ;
+char *strdup (const char *) ;
+void strmode (int, char *) ;
+int strncasecmp (const char *, const char *, size_t) ;
+char *strsep (char **, const char *) ;
+void swab (const void *, void *, size_t) ;
+
+}
+
+
+# 37 "/usr/include/libc.h" 2 3 4
+
+# 1 "/usr/include/stdlib.h" 1 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+typedef __wchar_t rune_t;
+
+typedef __wchar_t wchar_t;
+
+
+typedef struct {
+ int quot;
+ int rem;
+} div_t;
+
+typedef struct {
+ long quot;
+ long rem;
+} ldiv_t;
+
+
+
+
+
+
+
+
+
+
+extern int __mb_cur_max;
+
+
+
+
+extern "C" {
+ void
+ abort (void) ;
+ int
+ abs (int) ;
+int atexit (void (*)(void)) ;
+double atof (const char *) ;
+int atoi (const char *) ;
+long atol (const char *) ;
+void *bsearch (const void *, const void *, size_t,
+ size_t, int (*)(const void *, const void *)) ;
+void *calloc (size_t, size_t) ;
+ div_t
+ div (int, int) ;
+ void
+ exit (int) ;
+void free (void *) ;
+char *getenv (const char *) ;
+ long
+ labs (long) ;
+ ldiv_t
+ ldiv (long, long) ;
+void *malloc (size_t) ;
+void qsort (void *, size_t, size_t,
+ int (*)(const void *, const void *)) ;
+int rand (void) ;
+void *realloc (void *, size_t) ;
+void srand (unsigned) ;
+double strtod (const char *, char **) ;
+long strtol (const char *, char **, int) ;
+unsigned long
+ strtoul (const char *, char **, int) ;
+int system (const char *) ;
+
+
+int mblen (const char *, size_t) ;
+size_t mbstowcs (wchar_t *, const char *, size_t) ;
+int wctomb (char *, wchar_t) ;
+int mbtowc (wchar_t *, const char *, size_t) ;
+size_t wcstombs (char *, const wchar_t *, size_t) ;
+
+
+int putenv (const char *) ;
+int setenv (const char *, const char *, int) ;
+
+
+
+void *alloca (size_t) ;
+
+char *getbsize (int *, long *) ;
+char *cgetcap (char *, char *, int) ;
+int cgetclose (void) ;
+int cgetent (char **, char **, char *) ;
+int cgetfirst (char **, char **) ;
+int cgetmatch (char *, char *) ;
+int cgetnext (char **, char **) ;
+int cgetnum (char *, char *, long *) ;
+int cgetset (char *) ;
+int cgetstr (char *, char *, char **) ;
+int cgetustr (char *, char *, char **) ;
+
+int daemon (int, int) ;
+char *devname (int, int) ;
+int getloadavg (double [], int) ;
+
+char *group_from_gid (unsigned long, int) ;
+int heapsort (void *, size_t, size_t,
+ int (*)(const void *, const void *)) ;
+char *initstate (unsigned long, char *, long) ;
+int mergesort (void *, size_t, size_t,
+ int (*)(const void *, const void *)) ;
+int radixsort (const unsigned char **, int, const unsigned char *,
+ unsigned) ;
+int sradixsort (const unsigned char **, int, const unsigned char *,
+ unsigned) ;
+long random (void) ;
+char *realpath (const char *, char resolved_path[]) ;
+char *setstate (char *) ;
+void srandom (unsigned long) ;
+char *user_from_uid (unsigned long, int) ;
+
+long long
+ strtoq (const char *, char **, int) ;
+unsigned long long
+ strtouq (const char *, char **, int) ;
+
+void unsetenv (const char *) ;
+
+}
+
+
+# 38 "/usr/include/libc.h" 2 3 4
+
+# 1 "/usr/include/time.h" 1 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+struct tm {
+ int tm_sec;
+ int tm_min;
+ int tm_hour;
+ int tm_mday;
+ int tm_mon;
+ int tm_year;
+ int tm_wday;
+ int tm_yday;
+ int tm_isdst;
+ long tm_gmtoff;
+ char *tm_zone;
+};
+
+# 1 "/usr/include/gcc/darwin/2.95.2/g++/../machine/limits.h" 1 3
+
+
+# 1 "/usr/include/ppc/limits.h" 1 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 3 "/usr/include/gcc/darwin/2.95.2/g++/../machine/limits.h" 2 3
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 100 "/usr/include/time.h" 2 3 4
+
+
+
+
+
+
+extern "C" {
+char *asctime (const struct tm *) ;
+clock_t clock (void) ;
+char *ctime (const time_t *) ;
+double difftime (time_t, time_t) ;
+struct tm *gmtime (const time_t *) ;
+struct tm *localtime (const time_t *) ;
+time_t mktime (struct tm *) ;
+size_t strftime (char *, size_t, const char *, const struct tm *) ;
+time_t time (time_t *) ;
+
+
+void tzset (void) ;
+
+
+
+char *timezone (int, int) ;
+void tzsetwall (void) ;
+
+}
+
+
+# 39 "/usr/include/libc.h" 2 3 4
+
+# 1 "/usr/include/gcc/darwin/2.95.2/g++/../stdarg.h" 1 3
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 1 "/usr/include/gcc/darwin/2.95.2/g++/../va-ppc.h" 1 3
+
+
+
+
+
+
+
+
+typedef char *__gnuc_va_list;
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 43 "/usr/include/gcc/darwin/2.95.2/g++/../va-ppc.h" 3
+
+
+
+void va_end (__gnuc_va_list);
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 352 "/usr/include/gcc/darwin/2.95.2/g++/../va-ppc.h" 3
+
+# 42 "/usr/include/gcc/darwin/2.95.2/g++/../stdarg.h" 2 3
+
+# 131 "/usr/include/gcc/darwin/2.95.2/g++/../stdarg.h" 3
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 175 "/usr/include/gcc/darwin/2.95.2/g++/../stdarg.h" 3
+
+
+
+
+
+
+
+
+
+
+
+
+
+typedef __gnuc_va_list va_list;
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 40 "/usr/include/libc.h" 2 3 4
+
+
+
+# 1 "/usr/include/sys/mount.h" 1 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 1 "/usr/include/sys/ucred.h" 1 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 1 "/usr/include/sys/param.h" 1 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 1 "/usr/include/sys/syslimits.h" 1 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 88 "/usr/include/sys/param.h" 2 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 1 "/usr/include/machine/param.h" 1 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 1 "/usr/include/ppc/param.h" 1 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 30 "/usr/include/machine/param.h" 2 3 4
+
+
+
+
+
+
+
+
+
+# 102 "/usr/include/sys/param.h" 2 3 4
+
+# 1 "/usr/include/gcc/darwin/2.95.2/g++/../machine/limits.h" 1 3
+# 10 "/usr/include/gcc/darwin/2.95.2/g++/../machine/limits.h" 3
+
+# 108 "/usr/include/gcc/darwin/2.95.2/g++/../machine/limits.h" 3
+
+# 103 "/usr/include/sys/param.h" 2 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 61 "/usr/include/sys/ucred.h" 2 3 4
+
+
+
+
+
+struct ucred {
+ u_long cr_ref;
+ uid_t cr_uid;
+ short cr_ngroups;
+ gid_t cr_groups[16 ];
+};
+
+
+
+
+# 88 "/usr/include/sys/ucred.h" 3 4
+
+
+
+# 62 "/usr/include/sys/mount.h" 2 3 4
+
+
+# 1 "/usr/include/sys/queue.h" 1 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 184 "/usr/include/sys/queue.h" 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 260 "/usr/include/sys/queue.h" 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 378 "/usr/include/sys/queue.h" 3 4
+
+
+
+
+
+
+
+
+
+# 395 "/usr/include/sys/queue.h" 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 453 "/usr/include/sys/queue.h" 3 4
+
+
+# 463 "/usr/include/sys/queue.h" 3 4
+
+
+# 473 "/usr/include/sys/queue.h" 3 4
+
+
+# 483 "/usr/include/sys/queue.h" 3 4
+
+
+
+
+
+
+
+
+# 502 "/usr/include/sys/queue.h" 3 4
+
+# 548 "/usr/include/sys/queue.h" 3 4
+
+
+
+# 64 "/usr/include/sys/mount.h" 2 3 4
+
+# 1 "/usr/include/sys/lock.h" 1 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 74 "/usr/include/sys/lock.h" 3 4
+
+
+
+
+
+# 1 "/usr/include/mach/boolean.h" 1 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 1 "/usr/include/mach/machine/boolean.h" 1 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 1 "/usr/include/mach/ppc/boolean.h" 1 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+typedef int boolean_t;
+
+
+# 27 "/usr/include/mach/machine/boolean.h" 2 3 4
+
+
+
+
+
+
+
+
+
+# 127 "/usr/include/mach/boolean.h" 2 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 79 "/usr/include/sys/lock.h" 2 3 4
+
+
+
+struct slock{
+ volatile unsigned int lock_data[10];
+};
+
+
+
+
+
+typedef struct slock simple_lock_data_t;
+typedef struct slock *simple_lock_t;
+
+
+
+
+
+
+
+
+
+
+
+struct lock__bsd__ {
+ simple_lock_data_t
+ lk_interlock;
+ u_int lk_flags;
+ int lk_sharecount;
+ int lk_waitcount;
+ short lk_exclusivecount;
+ short lk_prio;
+ char *lk_wmesg;
+ int lk_timo;
+ pid_t lk_lockholder;
+ void *lk_lockthread;
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+struct proc;
+
+void lockinit (struct lock__bsd__ *, int prio, char *wmesg, int timo,
+ int flags) ;
+int lockmgr (struct lock__bsd__ *, u_int flags,
+ simple_lock_t, struct proc *p) ;
+int lockstatus (struct lock__bsd__ *) ;
+
+
+# 65 "/usr/include/sys/mount.h" 2 3 4
+
+# 1 "/usr/include/net/radix.h" 1 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+struct radix_node {
+ struct radix_mask *rn_mklist;
+ struct radix_node *rn_p;
+ short rn_b;
+ char rn_bmask;
+ u_char rn_flags;
+
+
+
+ union {
+ struct {
+ caddr_t rn_Key;
+ caddr_t rn_Mask;
+ struct radix_node *rn_Dupedkey;
+ } rn_leaf;
+ struct {
+ int rn_Off;
+ struct radix_node *rn_L;
+ struct radix_node *rn_R;
+ } rn_node;
+ } rn_u;
+
+
+
+
+
+};
+
+
+
+
+
+
+
+
+
+
+
+
+struct radix_mask {
+ short rm_b;
+ char rm_unused;
+ u_char rm_flags;
+ struct radix_mask *rm_mklist;
+ union {
+ caddr_t rmu_mask;
+ struct radix_node *rmu_leaf;
+ } rm_rmu;
+ int rm_refs;
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+typedef int walktree_f_t (struct radix_node *, void *) ;
+
+struct radix_node_head {
+ struct radix_node *rnh_treetop;
+ int rnh_addrsize;
+ int rnh_pktsize;
+ struct radix_node *(*rnh_addaddr)
+ (void *v, void *mask,
+ struct radix_node_head *head, struct radix_node nodes[]) ;
+ struct radix_node *(*rnh_addpkt)
+ (void *v, void *mask,
+ struct radix_node_head *head, struct radix_node nodes[]) ;
+ struct radix_node *(*rnh_deladdr)
+ (void *v, void *mask, struct radix_node_head *head) ;
+ struct radix_node *(*rnh_delpkt)
+ (void *v, void *mask, struct radix_node_head *head) ;
+ struct radix_node *(*rnh_matchaddr)
+ (void *v, struct radix_node_head *head) ;
+ struct radix_node *(*rnh_lookup)
+ (void *v, void *mask, struct radix_node_head *head) ;
+ struct radix_node *(*rnh_matchpkt)
+ (void *v, struct radix_node_head *head) ;
+ int (*rnh_walktree)
+ (struct radix_node_head *head, walktree_f_t *f, void *w) ;
+ int (*rnh_walktree_from)
+ (struct radix_node_head *head, void *a, void *m,
+ walktree_f_t *f, void *w) ;
+ void (*rnh_close)
+ (struct radix_node *rn, struct radix_node_head *head) ;
+ struct radix_node rnh_nodes[3];
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+void rn_init (void) ;
+int rn_inithead (void **, int) ;
+int rn_refines (void *, void *) ;
+struct radix_node
+ *rn_addmask (void *, int, int) ,
+ *rn_addroute (void *, void *, struct radix_node_head *,
+ struct radix_node [2]) ,
+ *rn_delete (void *, void *, struct radix_node_head *) ,
+ *rn_lookup (void *v_arg, void *m_arg,
+ struct radix_node_head *head) ,
+ *rn_match (void *, struct radix_node_head *) ;
+
+
+
+# 66 "/usr/include/sys/mount.h" 2 3 4
+
+# 1 "/usr/include/sys/socket.h" 1 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+struct linger {
+ int l_onoff;
+ int l_linger;
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+struct sockaddr {
+ u_char sa_len;
+ u_char sa_family;
+ char sa_data[14];
+};
+
+
+
+
+
+
+struct sockproto {
+ u_short sp_family;
+ u_short sp_protocol;
+};
+
+
+
+
+
+
+
+
+
+
+
+struct sockaddr_storage {
+ u_char ss_len;
+ u_char ss_family;
+ char _ss_pad1[((sizeof(int64_t)) - sizeof(u_char) * 2) ];
+ int64_t _ss_align;
+ char _ss_pad2[(128 - sizeof(u_char) * 2 - ((sizeof(int64_t)) - sizeof(u_char) * 2) - (sizeof(int64_t)) ) ];
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 295 "/usr/include/sys/socket.h" 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+struct msghdr {
+ caddr_t msg_name;
+ u_int msg_namelen;
+ struct iovec *msg_iov;
+ u_int msg_iovlen;
+ caddr_t msg_control;
+ u_int msg_controllen;
+ int msg_flags;
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+struct cmsghdr {
+ u_int cmsg_len;
+ int cmsg_level;
+ int cmsg_type;
+
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+struct osockaddr {
+ u_short sa_family;
+ char sa_data[14];
+};
+
+
+
+
+struct omsghdr {
+ caddr_t msg_name;
+ int msg_namelen;
+ struct iovec *msg_iov;
+ int msg_iovlen;
+ caddr_t msg_accrights;
+ int msg_accrightslen;
+};
+
+
+
+
+
+
+
+
+# 427 "/usr/include/sys/socket.h" 3 4
+
+
+
+
+
+
+extern "C" {
+int accept (int, struct sockaddr *, int *) ;
+int bind (int, const struct sockaddr *, int) ;
+int connect (int, const struct sockaddr *, int) ;
+int getpeername (int, struct sockaddr *, int *) ;
+int getsockname (int, struct sockaddr *, int *) ;
+int getsockopt (int, int, int, void *, int *) ;
+int listen (int, int) ;
+ssize_t recv (int, void *, size_t, int) ;
+ssize_t recvfrom (int, void *, size_t, int, struct sockaddr *, int *) ;
+ssize_t recvmsg (int, struct msghdr *, int) ;
+ssize_t send (int, const void *, size_t, int) ;
+ssize_t sendto (int, const void *,
+ size_t, int, const struct sockaddr *, int) ;
+ssize_t sendmsg (int, const struct msghdr *, int) ;
+
+
+
+int setsockopt (int, int, int, const void *, int) ;
+int shutdown (int, int) ;
+int socket (int, int, int) ;
+int socketpair (int, int, int, int *) ;
+}
+
+
+
+# 67 "/usr/include/sys/mount.h" 2 3 4
+
+
+typedef struct fsid { int32_t val[2]; } fsid_t;
+
+
+
+
+
+
+
+struct fid {
+ u_short fid_len;
+ u_short fid_reserved;
+ char fid_data[16 ];
+};
+
+
+
+
+
+
+
+
+struct statfs {
+ short f_otype;
+ short f_oflags;
+ long f_bsize;
+ long f_iosize;
+ long f_blocks;
+ long f_bfree;
+ long f_bavail;
+ long f_files;
+ long f_ffree;
+ fsid_t f_fsid;
+ uid_t f_owner;
+ short f_reserved1;
+ short f_type;
+ long f_flags;
+ long f_reserved2[2];
+ char f_fstypename[15 ];
+ char f_mntonname[90 ];
+ char f_mntfromname[90 ];
+
+
+
+
+ char f_reserved3;
+ long f_reserved4[4];
+
+};
+
+
+
+
+
+
+struct vnodelst { struct vnode *lh_first; } ;
+
+struct mount {
+ struct { struct mount *cqe_next; struct mount *cqe_prev; } mnt_list;
+ struct vfsops *mnt_op;
+ struct vfsconf *mnt_vfc;
+ struct vnode *mnt_vnodecovered;
+ struct vnodelst mnt_vnodelist;
+ struct lock__bsd__ mnt_lock;
+ int mnt_flag;
+ int mnt_kern_flag;
+ int mnt_maxsymlinklen;
+ struct statfs mnt_stat;
+ qaddr_t mnt_data;
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+struct fhandle {
+ fsid_t fh_fsid;
+ struct fid fh_fid;
+};
+typedef struct fhandle fhandle_t;
+
+
+
+
+struct export_args {
+ int ex_flags;
+ uid_t ex_root;
+ struct ucred ex_anon;
+ struct sockaddr *ex_addr;
+ int ex_addrlen;
+ struct sockaddr *ex_mask;
+ int ex_masklen;
+};
+
+
+
+
+
+
+struct vfsconf {
+ struct vfsops *vfc_vfsops;
+ char vfc_name[15 ];
+ int vfc_typenum;
+ int vfc_refcount;
+ int vfc_flags;
+ int (*vfc_mountroot)(void);
+ struct vfsconf *vfc_next;
+};
+
+# 361 "/usr/include/sys/mount.h" 3 4
+
+
+
+
+extern "C" {
+int fstatfs (int, struct statfs *) ;
+int getfh (const char *, fhandle_t *) ;
+int getfsstat (struct statfs *, long, int) ;
+int getmntinfo (struct statfs **, int) ;
+int mount (const char *, const char *, int, void *) ;
+int statfs (const char *, struct statfs *) ;
+int unmount (const char *, int) ;
+}
+
+
+
+# 43 "/usr/include/libc.h" 2 3 4
+
+
+# 1 "/usr/include/sys/wait.h" 1 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+union wait {
+ int w_status;
+
+
+
+ struct {
+
+
+
+
+
+
+
+ unsigned int w_Filler:16,
+ w_Retcode:8,
+ w_Coredump:1,
+ w_Termsig:7;
+
+ } w_T;
+
+
+
+
+
+ struct {
+
+
+
+
+
+
+ unsigned int w_Filler:16,
+ w_Stopsig:8,
+ w_Stopval:8;
+
+ } w_S;
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+extern "C" {
+struct rusage;
+
+pid_t wait (int *) ;
+pid_t waitpid (pid_t, int *, int) ;
+
+pid_t wait3 (int *, int, struct rusage *) ;
+pid_t wait4 (pid_t, int *, int, struct rusage *) ;
+
+}
+
+
+# 45 "/usr/include/libc.h" 2 3 4
+
+# 1 "/usr/include/sys/time.h" 1 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+struct timeval {
+ int32_t tv_sec;
+ int32_t tv_usec;
+};
+
+
+
+
+struct timespec {
+ time_t tv_sec;
+ int32_t tv_nsec;
+};
+
+
+
+
+
+
+
+
+
+
+struct timezone {
+ int tz_minuteswest;
+ int tz_dsttime;
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 121 "/usr/include/sys/time.h" 3 4
+
+# 130 "/usr/include/sys/time.h" 3 4
+
+
+
+
+
+
+
+
+
+struct itimerval {
+ struct timeval it_interval;
+ struct timeval it_value;
+};
+
+
+
+
+struct clockinfo {
+ int hz;
+ int tick;
+ int tickadj;
+ int stathz;
+ int profhz;
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+extern "C" {
+int adjtime (const struct timeval *, struct timeval *) ;
+int getitimer (int, struct itimerval *) ;
+int gettimeofday (struct timeval *, struct timezone *) ;
+int setitimer (int, const struct itimerval *, struct itimerval *) ;
+int settimeofday (const struct timeval *, const struct timezone *) ;
+int utimes (const char *, const struct timeval *) ;
+}
+
+
+
+
+
+# 46 "/usr/include/libc.h" 2 3 4
+
+# 1 "/usr/include/sys/times.h" 1 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+struct tms {
+ clock_t tms_utime;
+ clock_t tms_stime;
+ clock_t tms_cutime;
+ clock_t tms_cstime;
+};
+
+
+
+
+extern "C" {
+clock_t times (struct tms *) ;
+}
+
+
+# 47 "/usr/include/libc.h" 2 3 4
+
+# 1 "/usr/include/sys/resource.h" 1 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+struct rusage {
+ struct timeval ru_utime;
+ struct timeval ru_stime;
+ long ru_maxrss;
+
+ long ru_ixrss;
+ long ru_idrss;
+ long ru_isrss;
+ long ru_minflt;
+ long ru_majflt;
+ long ru_nswap;
+ long ru_inblock;
+ long ru_oublock;
+ long ru_msgsnd;
+ long ru_msgrcv;
+ long ru_nsignals;
+ long ru_nvcsw;
+ long ru_nivcsw;
+
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+struct orlimit {
+ int32_t rlim_cur;
+ int32_t rlim_max;
+};
+
+struct rlimit {
+ rlim_t rlim_cur;
+ rlim_t rlim_max;
+};
+
+
+struct loadavg {
+ fixpt_t ldavg[3];
+ long fscale;
+};
+
+
+
+
+
+
+
+extern "C" {
+int getpriority (int, int) ;
+int getrlimit (int, struct rlimit *) ;
+int getrusage (int, struct rusage *) ;
+int setpriority (int, int, int) ;
+int setrlimit (int, const struct rlimit *) ;
+}
+
+
+
+# 48 "/usr/include/libc.h" 2 3 4
+
+
+
+
+# 1 "/usr/include/sys/stat.h" 1 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+struct ostat {
+ u_int16_t st_dev;
+ ino_t st_ino;
+ mode_t st_mode;
+ nlink_t st_nlink;
+ u_int16_t st_uid;
+ u_int16_t st_gid;
+ u_int16_t st_rdev;
+ int32_t st_size;
+ struct timespec st_atimespec;
+ struct timespec st_mtimespec;
+ struct timespec st_ctimespec;
+ int32_t st_blksize;
+ int32_t st_blocks;
+ u_int32_t st_flags;
+ u_int32_t st_gen;
+};
+
+
+struct stat {
+ dev_t st_dev;
+ ino_t st_ino;
+ mode_t st_mode;
+ nlink_t st_nlink;
+ uid_t st_uid;
+ gid_t st_gid;
+ dev_t st_rdev;
+
+ struct timespec st_atimespec;
+ struct timespec st_mtimespec;
+ struct timespec st_ctimespec;
+
+
+
+
+
+
+
+
+ off_t st_size;
+ int64_t st_blocks;
+ u_int32_t st_blksize;
+ u_int32_t st_flags;
+ u_int32_t st_gen;
+ int32_t st_lspare;
+ int64_t st_qspare[2];
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+extern "C" {
+int chmod (const char *, mode_t) ;
+int fstat (int, struct stat *) ;
+int mkdir (const char *, mode_t) ;
+int mkfifo (const char *, mode_t) ;
+int stat (const char *, struct stat *) ;
+mode_t umask (mode_t) ;
+
+int chflags (const char *, u_long) ;
+int fchflags (int, u_long) ;
+int fchmod (int, mode_t) ;
+int lstat (const char *, struct stat *) ;
+
+}
+
+
+# 52 "/usr/include/libc.h" 2 3 4
+
+# 1 "/usr/include/sys/file.h" 1 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 1 "/usr/include/sys/fcntl.h" 1 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 131 "/usr/include/sys/fcntl.h" 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+struct flock {
+ off_t l_start;
+ off_t l_len;
+ pid_t l_pid;
+ short l_type;
+ short l_whence;
+};
+
+
+
+
+
+
+struct radvisory {
+ off_t ra_offset;
+ int ra_count;
+};
+
+
+
+
+
+
+
+
+
+
+
+
+typedef struct fstore {
+ u_int32_t fst_flags;
+ int fst_posmode;
+ off_t fst_offset;
+ off_t fst_length;
+ off_t fst_bytesalloc;
+} fstore_t;
+
+
+
+typedef struct fbootstraptransfer {
+ off_t fbt_offset;
+ size_t fbt_length;
+ void *fbt_buffer;
+} fbootstraptransfer_t;
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+struct log2phys {
+ u_int32_t l2p_flags;
+ off_t l2p_contigbytes;
+ off_t l2p_devoffset;
+};
+
+
+
+
+
+
+
+
+
+extern "C" {
+int open (const char *, int, ...) ;
+int creat (const char *, mode_t) ;
+int fcntl (int, int, ...) ;
+
+int flock (int, int) ;
+
+}
+
+
+
+# 61 "/usr/include/sys/file.h" 2 3 4
+
+
+
+# 112 "/usr/include/sys/file.h" 3 4
+
+
+
+# 53 "/usr/include/libc.h" 2 3 4
+
+
+# 1 "/usr/include/sys/ioctl.h" 1 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 1 "/usr/include/sys/ttycom.h" 1 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 1 "/usr/include/sys/ioccom.h" 1 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 66 "/usr/include/sys/ttycom.h" 2 3 4
+
+
+
+
+
+
+
+
+
+
+
+struct winsize {
+ unsigned short ws_row;
+ unsigned short ws_col;
+ unsigned short ws_xpixel;
+ unsigned short ws_ypixel;
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 66 "/usr/include/sys/ioctl.h" 2 3 4
+
+
+
+
+
+
+
+struct ttysize {
+ unsigned short ts_lines;
+ unsigned short ts_cols;
+ unsigned short ts_xxx;
+ unsigned short ts_yyy;
+};
+
+
+
+
+
+# 1 "/usr/include/sys/filio.h" 1 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 84 "/usr/include/sys/ioctl.h" 2 3 4
+
+# 1 "/usr/include/sys/sockio.h" 1 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 85 "/usr/include/sys/ioctl.h" 2 3 4
+
+
+
+
+
+
+extern "C" {
+int ioctl (int, unsigned long, ...) ;
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 55 "/usr/include/libc.h" 2 3 4
+
+# 1 "/usr/include/netinet/in.h" 1 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+struct in_addr {
+ u_int32_t s_addr;
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+struct sockaddr_in {
+ u_char sin_len;
+ u_char sin_family;
+ u_short sin_port;
+ struct in_addr sin_addr;
+ char sin_zero[8];
+};
+
+
+
+
+
+
+
+
+
+
+struct ip_opts {
+ struct in_addr ip_dst;
+ char ip_opts[40];
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+struct ip_mreq {
+ struct in_addr imr_multiaddr;
+ struct in_addr imr_interface;
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 456 "/usr/include/netinet/in.h" 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 499 "/usr/include/netinet/in.h" 3 4
+
+
+
+# 1 "/usr/include/netinet6/in6.h" 1 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+struct in6_addr {
+ union {
+ u_int8_t __u6_addr8[16];
+ u_int16_t __u6_addr16[8];
+ u_int32_t __u6_addr32[4];
+ } __u6_addr;
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+struct sockaddr_in6 {
+ u_int8_t sin6_len;
+ u_int8_t sin6_family;
+ u_int16_t sin6_port;
+ u_int32_t sin6_flowinfo;
+ struct in6_addr sin6_addr;
+ u_int32_t sin6_scope_id;
+};
+
+
+
+
+# 166 "/usr/include/netinet6/in6.h" 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 199 "/usr/include/netinet6/in6.h" 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 335 "/usr/include/netinet6/in6.h" 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+struct route_in6 {
+ struct rtentry *ro_rt;
+ struct sockaddr_in6 ro_dst;
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+struct ipv6_mreq {
+ struct in6_addr ipv6mr_multiaddr;
+ u_int ipv6mr_interface;
+};
+
+
+
+
+struct in6_pktinfo {
+ struct in6_addr ipi6_addr;
+ u_int ipi6_ifindex;
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 530 "/usr/include/netinet6/in6.h" 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 611 "/usr/include/netinet6/in6.h" 3 4
+
+# 640 "/usr/include/netinet6/in6.h" 3 4
+
+
+
+# 666 "/usr/include/netinet6/in6.h" 3 4
+
+
+extern "C" {
+struct cmsghdr;
+
+extern int inet6_option_space (int) ;
+extern int inet6_option_init (void *, struct cmsghdr **, int) ;
+extern int inet6_option_append (struct cmsghdr *, const u_int8_t *,
+ int, int) ;
+extern u_int8_t *inet6_option_alloc (struct cmsghdr *, int, int, int) ;
+extern int inet6_option_next (const struct cmsghdr *, u_int8_t **) ;
+extern int inet6_option_find (const struct cmsghdr *, u_int8_t **, int) ;
+
+extern size_t inet6_rthdr_space (int, int) ;
+extern struct cmsghdr *inet6_rthdr_init (void *, int) ;
+extern int inet6_rthdr_add (struct cmsghdr *, const struct in6_addr *,
+ unsigned int) ;
+extern int inet6_rthdr_lasthop (struct cmsghdr *, unsigned int) ;
+
+
+
+extern int inet6_rthdr_segments (const struct cmsghdr *) ;
+extern struct in6_addr *inet6_rthdr_getaddr (struct cmsghdr *, int) ;
+extern int inet6_rthdr_getflags (const struct cmsghdr *, int) ;
+
+extern int inet6_opt_init (void *, size_t) ;
+extern int inet6_opt_append (void *, size_t, int, u_int8_t,
+ size_t, u_int8_t, void **) ;
+extern int inet6_opt_finish (void *, size_t, int) ;
+extern int inet6_opt_set_val (void *, size_t, void *, int) ;
+
+extern int inet6_opt_next (void *, size_t, int, u_int8_t *,
+ size_t *, void **) ;
+extern int inet6_opt_find (void *, size_t, int, u_int8_t,
+ size_t *, void **) ;
+extern int inet6_opt_get_val (void *, size_t, void *, int) ;
+extern size_t inet6_rth_space (int, int) ;
+extern void *inet6_rth_init (void *, int, int, int) ;
+extern int inet6_rth_add (void *, const struct in6_addr *) ;
+extern int inet6_rth_reverse (const void *, void *) ;
+extern int inet6_rth_segments (const void *) ;
+extern struct in6_addr *inet6_rth_getaddr (const void *, int) ;
+}
+
+
+# 502 "/usr/include/netinet/in.h" 2 3 4
+
+
+
+# 514 "/usr/include/netinet/in.h" 3 4
+
+
+
+# 56 "/usr/include/libc.h" 2 3 4
+
+# 1 "/usr/include/arpa/inet.h" 1 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+extern "C" {
+unsigned long inet_addr (const char *) ;
+int inet_aton (const char *, struct in_addr *) ;
+unsigned long inet_lnaof (struct in_addr) ;
+struct in_addr inet_makeaddr (u_long , u_long) ;
+unsigned long inet_netof (struct in_addr) ;
+unsigned long inet_network (const char *) ;
+char *inet_ntoa (struct in_addr) ;
+}
+
+
+# 57 "/usr/include/libc.h" 2 3 4
+
+# 1 "/usr/include/mach/machine/vm_types.h" 1 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 1 "/usr/include/mach/ppc/vm_types.h" 1 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+typedef unsigned int natural_t;
+
+
+
+
+
+
+
+
+typedef int integer_t;
+
+
+
+
+
+
+
+
+
+
+
+
+
+typedef natural_t vm_offset_t;
+
+
+
+
+
+
+typedef natural_t vm_size_t;
+typedef unsigned long long vm_double_size_t;
+
+
+
+
+typedef unsigned int space_t;
+
+
+
+
+
+
+
+
+
+
+# 27 "/usr/include/mach/machine/vm_types.h" 2 3 4
+
+
+
+
+
+
+
+
+
+# 58 "/usr/include/libc.h" 2 3 4
+
+
+# 1 "/usr/include/mach/kern_return.h" 1 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 1 "/usr/include/mach/machine/kern_return.h" 1 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 1 "/usr/include/mach/ppc/kern_return.h" 1 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+typedef int kern_return_t;
+
+
+# 27 "/usr/include/mach/machine/kern_return.h" 2 3 4
+
+
+
+
+
+
+
+
+
+# 64 "/usr/include/mach/kern_return.h" 2 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 60 "/usr/include/libc.h" 2 3 4
+
+
+struct qelem {
+ struct qelem *q_forw;
+ struct qelem *q_back;
+ char *q_data;
+};
+
+extern kern_return_t map_fd(int fd, vm_offset_t offset,
+ vm_offset_t *addr, boolean_t find_space, vm_size_t numbytes);
+
+
+
+# 12 "QvBasic.h" 2
+
+
+
+
+
+
+
+
+
+
+
+typedef int QvBool;
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 4 "QvElement.h" 2
+
+
+class QvNode;
+
+
+
+
+
+
+
+
+
+
+
+class QvElement {
+
+ public:
+
+ enum NodeType {
+
+ Unknown,
+
+
+ OrthographicCamera,
+ PerspectiveCamera,
+
+
+ DirectionalLight,
+ PointLight,
+ SpotLight,
+
+
+ NoOpTransform,
+ MatrixTransform,
+ Rotation,
+ Scale,
+ Transform,
+ Translation,
+
+
+ NumNodeTypes,
+ };
+
+ static const char *nodeTypeNames[NumNodeTypes];
+
+ int depth;
+ QvElement *next;
+ QvNode *data;
+ NodeType type;
+
+ QvElement();
+ virtual ~QvElement();
+
+
+ virtual void print();
+};
+
+
+# 1 "QvTraverse.cpp" 2
+
+# 1 "QvNodes.h" 1
+
+
+
+# 1 "QvCone.h" 1
+
+
+
+# 1 "QvSFBitMask.h" 1
+
+
+
+# 1 "QvSFEnum.h" 1
+
+
+
+# 1 "QvString.h" 1
+
+
+
+
+
+
+class QvString {
+ public:
+ QvString() { string = staticStorage;
+ string[0] = '\0'; }
+ QvString(const char *str) { string = staticStorage;
+ *this = str; }
+ QvString(const QvString &str) { string = staticStorage;
+ *this = str.string; }
+ ~QvString();
+ u_long hash() { return QvString::hash(string); }
+ int getLength() const { return strlen(string); }
+ void makeEmpty(QvBool freeOld = 1 );
+ const char * getString() const { return string; }
+ QvString & operator =(const char *str);
+ QvString & operator =(const QvString &str)
+ { return (*this = str.string); }
+ QvString & operator +=(const char *str);
+ int operator !() const { return (string[0] == '\0'); }
+ friend int operator ==(const QvString &str, const char *s);
+
+ friend int operator ==(const char *s, const QvString &str)
+ { return (str == s); }
+
+ friend int operator ==(const QvString &str1, const QvString &str2)
+ { return (str1 == str2.string); }
+ friend int operator !=(const QvString &str, const char *s);
+
+ friend int operator !=(const char *s, const QvString &str)
+ { return (str != s); }
+ friend int operator !=(const QvString &str1,
+ const QvString &str2)
+ { return (str1 != str2.string); }
+ static u_long hash(const char *s);
+ private:
+ char *string;
+ int storageSize;
+
+ char staticStorage[32 ];
+ void expand(int bySize);
+};
+
+class QvNameEntry {
+ public:
+ QvBool isEmpty() const { return (string[0] == '\0'); }
+ QvBool isEqual(const char *s) const
+ { return (string[0] == s[0] && ! strcmp(string, s)); }
+ private:
+ static int nameTableSize;
+ static QvNameEntry **nameTable;
+ static struct QvNameChunk *chunk;
+ const char *string;
+ u_long hashValue;
+ QvNameEntry *next;
+ static void initClass();
+ QvNameEntry(const char *s, u_long h, QvNameEntry *n)
+ { string = s; hashValue = h; next = n; }
+ static const QvNameEntry * insert(const char *s);
+
+friend class QvName;
+};
+
+class QvName {
+ public:
+ QvName();
+ QvName(const char *s) { entry = QvNameEntry::insert(s); }
+ QvName(const QvString &s) { entry = QvNameEntry::insert(s.getString()); }
+
+ QvName(const QvName &n) { entry = n.entry; }
+ ~QvName() {}
+ const char *getString() const { return entry->string; }
+ int getLength() const { return strlen(entry->string); }
+ static QvBool isIdentStartChar(char c);
+ static QvBool isIdentChar(char c);
+ static QvBool isNodeNameStartChar(char c);
+ static QvBool isNodeNameChar(char c);
+ int operator !() const { return entry->isEmpty(); }
+ friend int operator ==(const QvName &n, const char *s)
+ { return n.entry->isEqual(s); }
+ friend int operator ==(const char *s, const QvName &n)
+ { return n.entry->isEqual(s); }
+
+ friend int operator ==(const QvName &n1, const QvName &n2)
+ { return n1.entry == n2.entry; }
+ friend int operator !=(const QvName &n, const char *s)
+ { return ! n.entry->isEqual(s); }
+ friend int operator !=(const char *s, const QvName &n)
+ { return ! n.entry->isEqual(s); }
+
+ friend int operator !=(const QvName &n1, const QvName &n2)
+ { return n1.entry != n2.entry; }
+ private:
+ const QvNameEntry *entry;
+};
+
+
+# 4 "QvSFEnum.h" 2
+
+# 1 "QvSubField.h" 1
+
+
+
+# 1 "QvField.h" 1
+
+
+
+
+
+class QvInput;
+class QvNode;
+
+class QvField {
+ public:
+ virtual ~QvField();
+
+ void setIgnored(QvBool ig) { flags.ignored = ig; }
+ QvBool isIgnored() const { return flags.ignored; }
+
+ QvBool isDefault() const { return flags.hasDefault; }
+
+ QvNode * getContainer() const { return container; }
+
+ void setDefault(QvBool def) { flags.hasDefault = def; }
+ void setContainer(QvNode *cont);
+ QvBool read(QvInput *in, const QvName &name);
+
+ QvField() { flags.hasDefault = 1 ; flags.ignored = 0 ; }
+
+ public:
+
+ private:
+ struct {
+ unsigned int hasDefault : 1;
+ unsigned int ignored : 1;
+ } flags;
+
+ QvNode *container;
+
+ static QvField * createInstanceFromName(const QvName &className);
+ virtual QvBool readValue(QvInput *in) = 0;
+
+friend class QvFieldData;
+};
+
+class QvSField : public QvField {
+ public:
+ virtual ~QvSField();
+
+ protected:
+ QvSField();
+
+ private:
+ virtual QvBool readValue(QvInput *in) = 0;
+};
+
+class QvMField : public QvField {
+
+ public:
+ int num;
+ int maxNum;
+
+
+ virtual ~QvMField();
+
+ protected:
+ QvMField();
+ virtual void makeRoom(int newNum);
+
+ private:
+ virtual void allocValues(int num) = 0;
+ virtual QvBool readValue(QvInput *in);
+ virtual QvBool read1Value(QvInput *in, int index) = 0;
+};
+
+
+# 4 "QvSubField.h" 2
+
+# 1 "QvInput.h" 1
+
+
+
+# 1 "QvDict.h" 1
+
+
+
+
+
+# 1 "QvPList.h" 1
+
+
+
+
+
+class QvPList {
+ public:
+ QvPList();
+ ~QvPList();
+ void append(void * ptr)
+ { if (nPtrs + 1 > ptrsSize) expand(nPtrs + 1);
+ ptrs[nPtrs++] = ptr; }
+ int find(const void *ptr) const;
+ void remove(int which);
+ int getLength() const { return (int) nPtrs; }
+ void truncate(int start)
+ { nPtrs = start; }
+ void *& operator [](int i) const { return ptrs[i]; }
+
+ private:
+ void ** ptrs;
+ int nPtrs;
+ int ptrsSize;
+ void setSize(int size)
+ { if (size > ptrsSize) expand(size); nPtrs = size; }
+ void expand(int size);
+};
+
+
+# 6 "QvDict.h" 2
+
+
+class QvDictEntry {
+ private:
+ u_long key;
+ void * value;
+ QvDictEntry * next;
+ QvDictEntry(u_long k, void *v) { key = k; value = v; };
+
+friend class QvDict;
+};
+
+class QvDict {
+ public:
+ QvDict( int entries = 251 );
+ ~QvDict();
+ void clear();
+ QvBool enter(u_long key, void *value);
+ QvBool find(u_long key, void *&value) const;
+ QvBool remove(u_long key);
+
+ private:
+ int tableSize;
+ QvDictEntry * *buckets;
+ QvDictEntry *& findEntry(u_long key) const;
+};
+
+
+# 4 "QvInput.h" 2
+
+
+
+class QvNode;
+class QvDB;
+
+class QvInput {
+ public:
+
+ QvInput();
+ ~QvInput();
+
+ static float isASCIIHeader(const char *string);
+ void setFilePointer(FILE *newFP);
+ FILE * getCurFile() const { return fp; }
+ float getVersion();
+ QvBool get(char &c);
+ QvBool read(char &c);
+ QvBool read(QvString &s);
+ QvBool read(QvName &n, QvBool validIdent = 0 );
+ QvBool read(int &i);
+ QvBool read(unsigned int &i);
+ QvBool read(short &s);
+ QvBool read(unsigned short &s);
+ QvBool read(long &l);
+ QvBool read(unsigned long &l);
+ QvBool read(float &f);
+ QvBool read(double &d);
+ QvBool eof() const;
+ void getLocationString(QvString &string) const;
+ void putBack(char c);
+ void putBack(const char *string);
+ void addReference(const QvName &name, QvNode *node);
+ QvNode * findReference(const QvName &name) const;
+
+ private:
+ FILE *fp;
+ int lineNum;
+ float version;
+ QvBool readHeader;
+ QvBool headerOk;
+ QvDict refDict;
+ QvString backBuf;
+ int backBufIndex;
+
+ QvBool checkHeader();
+
+ QvBool skipWhiteSpace();
+
+ QvBool readInteger(long &l);
+ QvBool readUnsignedInteger(unsigned long &l);
+ QvBool readReal(double &d);
+ QvBool readUnsignedIntegerString(char *str);
+ int readDigits(char *string);
+ int readHexDigits(char *string);
+ int readChar(char *string, char charToRead);
+
+friend class QvNode;
+friend class QvDB;
+};
+
+
+# 5 "QvSubField.h" 2
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 71 "QvSubField.h"
+
+
+# 5 "QvSFEnum.h" 2
+
+
+class QvSFEnum : public QvSField {
+ public:
+ int value;
+ public: QvSFEnum (); virtual ~ QvSFEnum (); virtual QvBool readValue(QvInput *in) ;
+
+
+ void setEnums(int num, const int vals[], const QvName names[])
+ { numEnums = num; enumValues = vals; enumNames = names; }
+
+ int numEnums;
+ const int *enumValues;
+ const QvName *enumNames;
+
+
+ QvBool findEnumValue(const QvName &name, int &val) const;
+};
+
+
+# 37 "QvSFEnum.h"
+
+
+# 4 "QvSFBitMask.h" 2
+
+
+class QvSFBitMask : public QvSFEnum {
+ public:
+
+ public: QvSFBitMask (); virtual ~ QvSFBitMask (); virtual QvBool readValue(QvInput *in) ;
+};
+
+
+# 4 "QvCone.h" 2
+
+# 1 "QvSFFloat.h" 1
+
+
+
+
+
+class QvSFFloat : public QvSField {
+ public:
+ float value;
+ public: QvSFFloat (); virtual ~ QvSFFloat (); virtual QvBool readValue(QvInput *in) ;
+};
+
+
+# 5 "QvCone.h" 2
+
+# 1 "QvSubNode.h" 1
+
+
+
+# 1 "QvFieldData.h" 1
+
+
+
+
+
+
+
+class QvField;
+class QvInput;
+class QvNode;
+
+class QvFieldData {
+ public:
+ QvFieldData() {}
+ ~QvFieldData();
+
+ void addField(QvNode *defObject, const char *fieldName,
+ const QvField *field);
+
+ int getNumFields() const { return fields.getLength(); }
+
+ const QvName & getFieldName(int index) const;
+
+ QvField * getField(const QvNode *object,
+ int index) const;
+
+ void addEnumValue(const char *typeName,
+ const char *valName, int val);
+ void getEnumData(const char *typeName, int &num,
+ const int *&vals, const QvName *&names);
+
+ QvBool read(QvInput *in, QvNode *object,
+ QvBool errorOnUnknownField = 1 ) const;
+
+ QvBool read(QvInput *in, QvNode *object,
+ const QvName &fieldName,
+ QvBool &foundName) const;
+
+ QvBool readFieldTypes(QvInput *in, QvNode *object);
+
+ private:
+ QvPList fields;
+ QvPList enums;
+};
+
+
+# 4 "QvSubNode.h" 2
+
+# 1 "QvNode.h" 1
+
+
+
+
+
+class QvChildList;
+class QvDict;
+class QvFieldData;
+class QvInput;
+class QvNodeList;
+class QvState;
+
+class QvNode {
+
+ public:
+ enum Stage {
+ FIRST_INSTANCE,
+ PROTO_INSTANCE,
+ OTHER_INSTANCE,
+ };
+
+ QvFieldData *fieldData;
+ QvChildList *children;
+ QvBool isBuiltIn;
+
+ QvName *objName;
+ QvNode();
+ virtual ~QvNode();
+
+ const QvName & getName() const;
+ void setName(const QvName &name);
+
+ static void init();
+ static QvBool read(QvInput *in, QvNode *&node);
+
+ virtual QvFieldData *getFieldData() = 0;
+
+ virtual void traverse(QvState *state) = 0;
+
+ protected:
+ virtual QvBool readInstance(QvInput *in);
+
+ private:
+ static QvDict *nameDict;
+
+ static void addName(QvNode *, const char *);
+ static void removeName(QvNode *, const char *);
+ static QvNode * readReference(QvInput *in);
+ static QvBool readNode(QvInput *in, QvName &className,QvNode *&node);
+ static QvBool readNodeInstance(QvInput *in, const QvName &className,
+ const QvName &refName, QvNode *&node);
+ static QvNode * createInstance(QvInput *in, const QvName &className);
+ static QvNode * createInstanceFromName(const QvName &className);
+ static void flushInput(QvInput *in);
+};
+
+
+# 5 "QvSubNode.h" 2
+
+
+
+# 16 "QvSubNode.h"
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 6 "QvCone.h" 2
+
+
+class QvCone : public QvNode {
+
+ public: QvCone :: QvCone (); virtual ~ QvCone (); virtual void traverse(QvState *state); private: static QvBool firstInstance; static QvFieldData *fieldData; virtual QvFieldData *getFieldData() { return fieldData; } ;
+
+ public:
+
+ enum Part {
+ SIDES = 0x01,
+ BOTTOM = 0x02,
+ ALL = 0x03
+ };
+
+
+ QvSFBitMask parts;
+ QvSFFloat bottomRadius;
+ QvSFFloat height;
+};
+
+
+# 4 "QvNodes.h" 2
+
+# 1 "QvCoordinate3.h" 1
+
+
+
+# 1 "QvMFVec3f.h" 1
+
+
+
+
+
+class QvMFVec3f : public QvMField {
+ public:
+ float *values;
+ public: QvMFVec3f (); virtual ~ QvMFVec3f (); virtual QvBool read1Value(QvInput *in, int index); void allocValues(int newNum) ;
+};
+
+
+# 4 "QvCoordinate3.h" 2
+
+
+
+class QvCoordinate3 : public QvNode {
+
+ public: QvCoordinate3 :: QvCoordinate3 (); virtual ~ QvCoordinate3 (); virtual void traverse(QvState *state); private: static QvBool firstInstance; static QvFieldData *fieldData; virtual QvFieldData *getFieldData() { return fieldData; } ;
+
+ public:
+
+ QvMFVec3f point;
+};
+
+
+# 5 "QvNodes.h" 2
+
+# 1 "QvCube.h" 1
+
+
+
+
+
+
+class QvCube : public QvNode {
+
+ public: QvCube :: QvCube (); virtual ~ QvCube (); virtual void traverse(QvState *state); private: static QvBool firstInstance; static QvFieldData *fieldData; virtual QvFieldData *getFieldData() { return fieldData; } ;
+
+ public:
+
+ QvSFFloat width;
+ QvSFFloat height;
+ QvSFFloat depth;
+};
+
+
+# 6 "QvNodes.h" 2
+
+# 1 "QvCylinder.h" 1
+
+
+
+
+
+
+
+class QvCylinder : public QvNode {
+
+ public: QvCylinder :: QvCylinder (); virtual ~ QvCylinder (); virtual void traverse(QvState *state); private: static QvBool firstInstance; static QvFieldData *fieldData; virtual QvFieldData *getFieldData() { return fieldData; } ;
+
+ public:
+
+ enum Part {
+ SIDES = 0x01,
+ TOP = 0x02,
+ BOTTOM = 0x04,
+ ALL = 0x07,
+ };
+
+
+ QvSFBitMask parts;
+ QvSFFloat radius;
+ QvSFFloat height;
+};
+
+
+# 7 "QvNodes.h" 2
+
+# 1 "QvDirectionalLight.h" 1
+
+
+
+# 1 "QvSFBool.h" 1
+
+
+
+
+
+class QvSFBool : public QvSField {
+ public:
+ QvBool value;
+ public: QvSFBool (); virtual ~ QvSFBool (); virtual QvBool readValue(QvInput *in) ;
+};
+
+
+# 4 "QvDirectionalLight.h" 2
+
+# 1 "QvSFColor.h" 1
+
+
+
+
+
+class QvSFColor : public QvSField {
+ public:
+ float value[3];
+ public: QvSFColor (); virtual ~ QvSFColor (); virtual QvBool readValue(QvInput *in) ;
+};
+
+
+# 5 "QvDirectionalLight.h" 2
+
+
+# 1 "QvSFVec3f.h" 1
+
+
+
+
+
+class QvSFVec3f : public QvSField {
+ public:
+ float value[3];
+ public: QvSFVec3f (); virtual ~ QvSFVec3f (); virtual QvBool readValue(QvInput *in) ;
+};
+
+
+# 7 "QvDirectionalLight.h" 2
+
+
+
+class QvDirectionalLight : public QvNode {
+
+ public: QvDirectionalLight :: QvDirectionalLight (); virtual ~ QvDirectionalLight (); virtual void traverse(QvState *state); private: static QvBool firstInstance; static QvFieldData *fieldData; virtual QvFieldData *getFieldData() { return fieldData; } ;
+
+ public:
+
+ QvSFBool on;
+ QvSFFloat intensity;
+ QvSFColor color;
+ QvSFVec3f direction;
+};
+
+
+# 8 "QvNodes.h" 2
+
+# 1 "QvGroup.h" 1
+
+
+
+class QvChildList;
+
+
+class QvGroup : public QvNode {
+
+ public: QvGroup :: QvGroup (); virtual ~ QvGroup (); virtual void traverse(QvState *state); private: static QvBool firstInstance; static QvFieldData *fieldData; virtual QvFieldData *getFieldData() { return fieldData; } ;
+
+ public:
+ QvNode * getChild(int index) const;
+ int getNumChildren() const;
+ virtual QvChildList *getChildren() const;
+ virtual QvBool readInstance(QvInput *in);
+ virtual QvBool readChildren(QvInput *in);
+};
+
+
+# 9 "QvNodes.h" 2
+
+# 1 "QvIndexedFaceSet.h" 1
+
+
+
+# 1 "QvMFLong.h" 1
+
+
+
+
+
+class QvMFLong : public QvMField {
+ public:
+ long *values;
+ public: QvMFLong (); virtual ~ QvMFLong (); virtual QvBool read1Value(QvInput *in, int index); void allocValues(int newNum) ;
+};
+
+
+# 4 "QvIndexedFaceSet.h" 2
+
+
+
+
+
+class QvIndexedFaceSet : public QvNode {
+
+ public: QvIndexedFaceSet :: QvIndexedFaceSet (); virtual ~ QvIndexedFaceSet (); virtual void traverse(QvState *state); private: static QvBool firstInstance; static QvFieldData *fieldData; virtual QvFieldData *getFieldData() { return fieldData; } ;
+
+ public:
+
+ QvMFLong coordIndex;
+ QvMFLong materialIndex;
+ QvMFLong normalIndex;
+ QvMFLong textureCoordIndex;
+};
+
+
+# 10 "QvNodes.h" 2
+
+# 1 "QvIndexedLineSet.h" 1
+
+
+
+
+
+
+
+
+class QvIndexedLineSet : public QvNode {
+
+ public: QvIndexedLineSet :: QvIndexedLineSet (); virtual ~ QvIndexedLineSet (); virtual void traverse(QvState *state); private: static QvBool firstInstance; static QvFieldData *fieldData; virtual QvFieldData *getFieldData() { return fieldData; } ;
+
+ public:
+
+ QvMFLong coordIndex;
+ QvMFLong materialIndex;
+ QvMFLong normalIndex;
+ QvMFLong textureCoordIndex;
+};
+
+
+# 11 "QvNodes.h" 2
+
+# 1 "QvInfo.h" 1
+
+
+
+# 1 "QvSFString.h" 1
+
+
+
+
+
+class QvSFString : public QvSField {
+ public:
+ QvString value;
+ public: QvSFString (); virtual ~ QvSFString (); virtual QvBool readValue(QvInput *in) ;
+};
+
+
+# 4 "QvInfo.h" 2
+
+
+
+class QvInfo : public QvNode {
+
+ public: QvInfo :: QvInfo (); virtual ~ QvInfo (); virtual void traverse(QvState *state); private: static QvBool firstInstance; static QvFieldData *fieldData; virtual QvFieldData *getFieldData() { return fieldData; } ;
+
+ public:
+
+ QvSFString string;
+};
+
+
+# 12 "QvNodes.h" 2
+
+# 1 "QvLevelOfDetail.h" 1
+
+
+
+# 1 "QvMFFloat.h" 1
+
+
+
+
+
+class QvMFFloat : public QvMField {
+ public:
+ float *values;
+ public: QvMFFloat (); virtual ~ QvMFFloat (); virtual QvBool read1Value(QvInput *in, int index); void allocValues(int newNum) ;
+};
+
+
+# 4 "QvLevelOfDetail.h" 2
+
+
+
+class QvLevelOfDetail : public QvGroup {
+
+ public: QvLevelOfDetail :: QvLevelOfDetail (); virtual ~ QvLevelOfDetail (); virtual void traverse(QvState *state); private: static QvBool firstInstance; static QvFieldData *fieldData; virtual QvFieldData *getFieldData() { return fieldData; } ;
+
+ public:
+
+ QvMFFloat screenArea;
+};
+
+
+# 13 "QvNodes.h" 2
+
+# 1 "QvMaterial.h" 1
+
+
+
+# 1 "QvMFColor.h" 1
+
+
+
+
+
+class QvMFColor : public QvMField {
+ public:
+ float *values;
+ public: QvMFColor (); virtual ~ QvMFColor (); virtual QvBool read1Value(QvInput *in, int index); void allocValues(int newNum) ;
+};
+
+
+# 4 "QvMaterial.h" 2
+
+
+
+
+class QvMaterial : public QvNode {
+
+ public: QvMaterial :: QvMaterial (); virtual ~ QvMaterial (); virtual void traverse(QvState *state); private: static QvBool firstInstance; static QvFieldData *fieldData; virtual QvFieldData *getFieldData() { return fieldData; } ;
+
+ public:
+
+ QvMFColor ambientColor;
+ QvMFColor diffuseColor;
+ QvMFColor specularColor;
+ QvMFColor emissiveColor;
+ QvMFFloat shininess;
+ QvMFFloat transparency;
+};
+
+
+# 14 "QvNodes.h" 2
+
+# 1 "QvMaterialBinding.h" 1
+
+
+
+
+
+
+class QvMaterialBinding : public QvNode {
+
+ public: QvMaterialBinding :: QvMaterialBinding (); virtual ~ QvMaterialBinding (); virtual void traverse(QvState *state); private: static QvBool firstInstance; static QvFieldData *fieldData; virtual QvFieldData *getFieldData() { return fieldData; } ;
+
+ public:
+ enum Binding {
+ DEFAULT,
+ NONE,
+ OVERALL,
+ PER_PART,
+ PER_PART_INDEXED,
+ PER_FACE,
+ PER_FACE_INDEXED,
+ PER_VERTEX,
+ PER_VERTEX_INDEXED,
+ };
+
+
+ QvSFEnum value;
+};
+
+
+# 15 "QvNodes.h" 2
+
+# 1 "QvMatrixTransform.h" 1
+
+
+
+# 1 "QvSFMatrix.h" 1
+
+
+
+
+
+class QvSFMatrix : public QvSField {
+ public:
+ float value[4][4];
+ public: QvSFMatrix (); virtual ~ QvSFMatrix (); virtual QvBool readValue(QvInput *in) ;
+};
+
+
+# 4 "QvMatrixTransform.h" 2
+
+
+
+class QvMatrixTransform : public QvNode {
+
+ public: QvMatrixTransform :: QvMatrixTransform (); virtual ~ QvMatrixTransform (); virtual void traverse(QvState *state); private: static QvBool firstInstance; static QvFieldData *fieldData; virtual QvFieldData *getFieldData() { return fieldData; } ;
+
+ public:
+
+ QvSFMatrix matrix;
+};
+
+
+# 16 "QvNodes.h" 2
+
+# 1 "QvNormal.h" 1
+
+
+
+
+
+
+class QvNormal : public QvNode {
+
+ public: QvNormal :: QvNormal (); virtual ~ QvNormal (); virtual void traverse(QvState *state); private: static QvBool firstInstance; static QvFieldData *fieldData; virtual QvFieldData *getFieldData() { return fieldData; } ;
+
+ public:
+
+ QvMFVec3f vector;
+};
+
+
+# 17 "QvNodes.h" 2
+
+# 1 "QvNormalBinding.h" 1
+
+
+
+
+
+
+class QvNormalBinding : public QvNode {
+
+ public: QvNormalBinding :: QvNormalBinding (); virtual ~ QvNormalBinding (); virtual void traverse(QvState *state); private: static QvBool firstInstance; static QvFieldData *fieldData; virtual QvFieldData *getFieldData() { return fieldData; } ;
+
+ public:
+ enum Binding {
+ DEFAULT,
+ NONE,
+ OVERALL,
+ PER_PART,
+ PER_PART_INDEXED,
+ PER_FACE,
+ PER_FACE_INDEXED,
+ PER_VERTEX,
+ PER_VERTEX_INDEXED,
+ };
+
+
+ QvSFEnum value;
+};
+
+
+# 18 "QvNodes.h" 2
+
+# 1 "QvOrthographicCamera.h" 1
+
+
+
+
+# 1 "QvSFRotation.h" 1
+
+
+
+
+
+class QvSFRotation : public QvSField {
+ public:
+ float axis[3];
+ float angle;
+ public: QvSFRotation (); virtual ~ QvSFRotation (); virtual QvBool readValue(QvInput *in) ;
+};
+
+
+# 5 "QvOrthographicCamera.h" 2
+
+
+
+
+class QvOrthographicCamera : public QvNode {
+
+ public: QvOrthographicCamera :: QvOrthographicCamera (); virtual ~ QvOrthographicCamera (); virtual void traverse(QvState *state); private: static QvBool firstInstance; static QvFieldData *fieldData; virtual QvFieldData *getFieldData() { return fieldData; } ;
+
+ public:
+ QvSFVec3f position;
+ QvSFRotation orientation;
+
+ QvSFFloat focalDistance;
+
+ QvSFFloat height;
+};
+
+
+# 19 "QvNodes.h" 2
+
+# 1 "QvPerspectiveCamera.h" 1
+
+
+
+
+
+
+
+
+class QvPerspectiveCamera : public QvNode {
+
+ public: QvPerspectiveCamera :: QvPerspectiveCamera (); virtual ~ QvPerspectiveCamera (); virtual void traverse(QvState *state); private: static QvBool firstInstance; static QvFieldData *fieldData; virtual QvFieldData *getFieldData() { return fieldData; } ;
+
+ public:
+ QvSFVec3f position;
+ QvSFRotation orientation;
+
+ QvSFFloat focalDistance;
+
+ QvSFFloat heightAngle;
+
+};
+
+
+# 20 "QvNodes.h" 2
+
+# 1 "QvPointLight.h" 1
+
+
+
+
+
+
+
+
+
+class QvPointLight : public QvNode {
+
+ public: QvPointLight :: QvPointLight (); virtual ~ QvPointLight (); virtual void traverse(QvState *state); private: static QvBool firstInstance; static QvFieldData *fieldData; virtual QvFieldData *getFieldData() { return fieldData; } ;
+
+ public:
+
+ QvSFBool on;
+ QvSFFloat intensity;
+ QvSFColor color;
+ QvSFVec3f location;
+};
+
+
+# 21 "QvNodes.h" 2
+
+# 1 "QvPointSet.h" 1
+
+
+
+# 1 "QvSFLong.h" 1
+
+
+
+
+
+class QvSFLong : public QvSField {
+ public:
+ long value;
+ public: QvSFLong (); virtual ~ QvSFLong (); virtual QvBool readValue(QvInput *in) ;
+};
+
+
+# 4 "QvPointSet.h" 2
+
+
+
+
+
+class QvPointSet : public QvNode {
+
+ public: QvPointSet :: QvPointSet (); virtual ~ QvPointSet (); virtual void traverse(QvState *state); private: static QvBool firstInstance; static QvFieldData *fieldData; virtual QvFieldData *getFieldData() { return fieldData; } ;
+
+ public:
+
+ QvSFLong startIndex;
+ QvSFLong numPoints;
+};
+
+
+# 22 "QvNodes.h" 2
+
+# 1 "QvRotation.h" 1
+
+
+
+
+
+
+class QvRotation : public QvNode {
+
+ public: QvRotation :: QvRotation (); virtual ~ QvRotation (); virtual void traverse(QvState *state); private: static QvBool firstInstance; static QvFieldData *fieldData; virtual QvFieldData *getFieldData() { return fieldData; } ;
+
+ public:
+
+ QvSFRotation rotation;
+};
+
+
+# 23 "QvNodes.h" 2
+
+# 1 "QvScale.h" 1
+
+
+
+
+
+
+class QvScale : public QvNode {
+
+ public: QvScale :: QvScale (); virtual ~ QvScale (); virtual void traverse(QvState *state); private: static QvBool firstInstance; static QvFieldData *fieldData; virtual QvFieldData *getFieldData() { return fieldData; } ;
+
+ public:
+
+ QvSFVec3f scaleFactor;
+};
+
+
+# 24 "QvNodes.h" 2
+
+# 1 "QvSeparator.h" 1
+
+
+
+
+
+
+
+
+class QvSeparator : public QvGroup {
+
+ public: QvSeparator :: QvSeparator (); virtual ~ QvSeparator (); virtual void traverse(QvState *state); private: static QvBool firstInstance; static QvFieldData *fieldData; virtual QvFieldData *getFieldData() { return fieldData; } ;
+
+ public:
+ enum CullEnabled {
+ OFF,
+ ON,
+ AUTO,
+ };
+
+
+ QvSFEnum renderCulling;
+};
+
+
+# 25 "QvNodes.h" 2
+
+# 1 "QvShapeHints.h" 1
+
+
+
+
+
+
+
+class QvShapeHints : public QvNode {
+
+ public: QvShapeHints :: QvShapeHints (); virtual ~ QvShapeHints (); virtual void traverse(QvState *state); private: static QvBool firstInstance; static QvFieldData *fieldData; virtual QvFieldData *getFieldData() { return fieldData; } ;
+
+ public:
+ enum VertexOrdering {
+ UNKNOWN_ORDERING,
+ CLOCKWISE,
+ COUNTERCLOCKWISE,
+ };
+
+ enum ShapeType {
+ UNKNOWN_SHAPE_TYPE,
+ SOLID,
+ };
+
+ enum FaceType {
+ UNKNOWN_FACE_TYPE,
+ CONVEX,
+ };
+
+
+ QvSFEnum vertexOrdering;
+ QvSFEnum shapeType;
+ QvSFEnum faceType;
+ QvSFFloat creaseAngle;
+};
+
+
+# 26 "QvNodes.h" 2
+
+# 1 "QvSphere.h" 1
+
+
+
+
+
+
+class QvSphere : public QvNode {
+
+ public: QvSphere :: QvSphere (); virtual ~ QvSphere (); virtual void traverse(QvState *state); private: static QvBool firstInstance; static QvFieldData *fieldData; virtual QvFieldData *getFieldData() { return fieldData; } ;
+
+ public:
+
+ QvSFFloat radius;
+};
+
+
+
+# 27 "QvNodes.h" 2
+
+# 1 "QvSpotLight.h" 1
+
+
+
+
+
+
+
+
+
+class QvSpotLight : public QvNode {
+
+ public: QvSpotLight :: QvSpotLight (); virtual ~ QvSpotLight (); virtual void traverse(QvState *state); private: static QvBool firstInstance; static QvFieldData *fieldData; virtual QvFieldData *getFieldData() { return fieldData; } ;
+
+ public:
+
+ QvSFBool on;
+ QvSFFloat intensity;
+ QvSFColor color;
+ QvSFVec3f location;
+ QvSFVec3f direction;
+ QvSFFloat dropOffRate;
+
+
+ QvSFFloat cutOffAngle;
+
+
+};
+
+
+# 28 "QvNodes.h" 2
+
+# 1 "QvSwitch.h" 1
+
+
+
+
+
+
+
+
+
+class QvSwitch : public QvGroup {
+
+ public: QvSwitch :: QvSwitch (); virtual ~ QvSwitch (); virtual void traverse(QvState *state); private: static QvBool firstInstance; static QvFieldData *fieldData; virtual QvFieldData *getFieldData() { return fieldData; } ;
+
+ public:
+
+ QvSFLong whichChild;
+};
+
+
+# 29 "QvNodes.h" 2
+
+# 1 "QvTexture2.h" 1
+
+
+
+
+# 1 "QvSFImage.h" 1
+
+
+
+
+
+class QvSFImage : public QvSField {
+ public:
+ short size[2];
+ int numComponents;
+ unsigned char * bytes;
+ public: QvSFImage (); virtual ~ QvSFImage (); virtual QvBool readValue(QvInput *in) ;
+};
+
+
+# 5 "QvTexture2.h" 2
+
+
+
+
+class QvTexture2 : public QvNode {
+
+ public: QvTexture2 :: QvTexture2 (); virtual ~ QvTexture2 (); virtual void traverse(QvState *state); private: static QvBool firstInstance; static QvFieldData *fieldData; virtual QvFieldData *getFieldData() { return fieldData; } ;
+
+ public:
+ enum Wrap {
+ REPEAT,
+ CLAMP,
+ };
+
+
+ QvSFString filename;
+ QvSFImage image;
+ QvSFEnum wrapS;
+ QvSFEnum wrapT;
+
+ virtual QvBool readInstance(QvInput *in);
+ QvBool readImage();
+};
+
+
+# 30 "QvNodes.h" 2
+
+# 1 "QvTexture2Transform.h" 1
+
+
+
+
+# 1 "QvSFVec2f.h" 1
+
+
+
+
+
+class QvSFVec2f : public QvSField {
+ public:
+ float value[2];
+ public: QvSFVec2f (); virtual ~ QvSFVec2f (); virtual QvBool readValue(QvInput *in) ;
+};
+
+
+# 5 "QvTexture2Transform.h" 2
+
+
+
+class QvTexture2Transform : public QvNode {
+
+ public: QvTexture2Transform :: QvTexture2Transform (); virtual ~ QvTexture2Transform (); virtual void traverse(QvState *state); private: static QvBool firstInstance; static QvFieldData *fieldData; virtual QvFieldData *getFieldData() { return fieldData; } ;
+
+ public:
+
+ QvSFVec2f translation;
+ QvSFFloat rotation;
+ QvSFVec2f scaleFactor;
+ QvSFVec2f center;
+};
+
+
+# 31 "QvNodes.h" 2
+
+# 1 "QvTextureCoordinate2.h" 1
+
+
+
+# 1 "QvMFVec2f.h" 1
+
+
+
+
+
+class QvMFVec2f : public QvMField {
+ public:
+ float *values;
+ public: QvMFVec2f (); virtual ~ QvMFVec2f (); virtual QvBool read1Value(QvInput *in, int index); void allocValues(int newNum) ;
+};
+
+
+# 4 "QvTextureCoordinate2.h" 2
+
+
+
+class QvTextureCoordinate2 : public QvNode {
+
+ public: QvTextureCoordinate2 :: QvTextureCoordinate2 (); virtual ~ QvTextureCoordinate2 (); virtual void traverse(QvState *state); private: static QvBool firstInstance; static QvFieldData *fieldData; virtual QvFieldData *getFieldData() { return fieldData; } ;
+
+ public:
+
+ QvMFVec2f point;
+};
+
+
+# 32 "QvNodes.h" 2
+
+# 1 "QvTransform.h" 1
+
+
+
+
+
+
+
+class QvTransform : public QvNode {
+
+ public: QvTransform :: QvTransform (); virtual ~ QvTransform (); virtual void traverse(QvState *state); private: static QvBool firstInstance; static QvFieldData *fieldData; virtual QvFieldData *getFieldData() { return fieldData; } ;
+
+ public:
+
+ QvSFVec3f translation;
+ QvSFRotation rotation;
+ QvSFVec3f scaleFactor;
+ QvSFRotation scaleOrientation;
+ QvSFVec3f center;
+};
+
+
+# 33 "QvNodes.h" 2
+
+# 1 "QvTransformSeparator.h" 1
+
+
+
+
+
+class QvTransformSeparator : public QvGroup {
+
+ public: QvTransformSeparator :: QvTransformSeparator (); virtual ~ QvTransformSeparator (); virtual void traverse(QvState *state); private: static QvBool firstInstance; static QvFieldData *fieldData; virtual QvFieldData *getFieldData() { return fieldData; } ;
+
+
+};
+
+
+# 34 "QvNodes.h" 2
+
+# 1 "QvTranslation.h" 1
+
+
+
+
+
+
+class QvTranslation : public QvNode {
+
+ public: QvTranslation :: QvTranslation (); virtual ~ QvTranslation (); virtual void traverse(QvState *state); private: static QvBool firstInstance; static QvFieldData *fieldData; virtual QvFieldData *getFieldData() { return fieldData; } ;
+
+ public:
+
+ QvSFVec3f translation;
+};
+
+
+# 35 "QvNodes.h" 2
+
+# 1 "QvWWWAnchor.h" 1
+
+
+
+
+
+
+
+class QvWWWAnchor : public QvGroup {
+
+ public: QvWWWAnchor :: QvWWWAnchor (); virtual ~ QvWWWAnchor (); virtual void traverse(QvState *state); private: static QvBool firstInstance; static QvFieldData *fieldData; virtual QvFieldData *getFieldData() { return fieldData; } ;
+
+ public:
+
+ enum Map {
+ NONE,
+ POINT,
+ };
+
+
+ QvSFString name;
+ QvSFEnum map;
+};
+
+
+# 36 "QvNodes.h" 2
+
+# 1 "QvWWWInline.h" 1
+
+
+
+
+
+
+
+class QvWWWInline : public QvGroup {
+
+ public: QvWWWInline :: QvWWWInline (); virtual ~ QvWWWInline (); virtual void traverse(QvState *state); private: static QvBool firstInstance; static QvFieldData *fieldData; virtual QvFieldData *getFieldData() { return fieldData; } ;
+
+ public:
+
+ QvSFString name;
+ QvSFVec3f bboxSize;
+ QvSFVec3f bboxCenter;
+};
+
+
+# 37 "QvNodes.h" 2
+
+
+
+# 2 "QvTraverse.cpp" 2
+
+# 1 "QvState.h" 1
+
+
+
+
+
+
+# 1 "../BspLib/VrmlFile.h" 1
+
+
+
+
+
+
+
+
+
+
+
+# 1 "../BspLib/BspLibDefs.h" 1
+
+
+
+
+
+
+
+
+
+
+
+
+# 1 "/usr/include/ctype.h" 1 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 1 "/usr/include/runetype.h" 1 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+typedef struct {
+ rune_t min;
+ rune_t max;
+ rune_t map;
+ unsigned long *types;
+} _RuneEntry;
+
+typedef struct {
+ int nranges;
+ _RuneEntry *ranges;
+} _RuneRange;
+
+typedef struct {
+ char magic[8];
+ char encoding[32];
+
+ rune_t (*sgetrune)
+ (const char *, unsigned int, char const **) ;
+ int (*sputrune)
+ (rune_t, char *, unsigned int, char **) ;
+ rune_t invalid_rune;
+
+ unsigned long runetype[(1 <<8 ) ];
+ rune_t maplower[(1 <<8 ) ];
+ rune_t mapupper[(1 <<8 ) ];
+
+
+
+
+
+
+ _RuneRange runetype_ext;
+ _RuneRange maplower_ext;
+ _RuneRange mapupper_ext;
+
+ void *variable;
+ int variable_len;
+} _RuneLocale;
+
+
+
+extern _RuneLocale _DefaultRuneLocale;
+extern _RuneLocale *_CurrentRuneLocale;
+
+
+# 68 "/usr/include/ctype.h" 2 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+extern "C" {
+unsigned long ___runetype (__wchar_t ) ;
+__wchar_t ___tolower (__wchar_t ) ;
+__wchar_t ___toupper (__wchar_t ) ;
+}
+
+
+
+
+
+
+
+
+
+
+
+static inline int
+__istype(__wchar_t c, unsigned long f)
+{
+ return((((c & (~((1 <<8 ) - 1)) ) ? ___runetype(c) :
+ _CurrentRuneLocale->runetype[c]) & f) ? 1 : 0);
+}
+
+static inline int
+__isctype(__wchar_t c, unsigned long f)
+{
+ return((((c & (~((1 <<8 ) - 1)) ) ? 0 :
+ _DefaultRuneLocale.runetype[c]) & f) ? 1 : 0);
+}
+
+
+
+static inline __wchar_t
+toupper(__wchar_t c)
+{
+ return((c & (~((1 <<8 ) - 1)) ) ?
+ ___toupper(c) : _CurrentRuneLocale->mapupper[c]);
+}
+
+static inline __wchar_t
+tolower(__wchar_t c)
+{
+ return((c & (~((1 <<8 ) - 1)) ) ?
+ ___tolower(c) : _CurrentRuneLocale->maplower[c]);
+}
+
+
+# 166 "/usr/include/ctype.h" 3 4
+
+
+
+# 13 "../BspLib/BspLibDefs.h" 2
+
+# 1 "/usr/include/errno.h" 1 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 1 "/usr/include/sys/errno.h" 1 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+extern "C" {
+extern int * __error (void) ;
+
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 22 "/usr/include/errno.h" 2 3 4
+
+
+# 14 "../BspLib/BspLibDefs.h" 2
+
+# 1 "/usr/include/limits.h" 1 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 1 "/usr/include/gcc/darwin/2.95.2/g++/../machine/limits.h" 1 3
+# 10 "/usr/include/gcc/darwin/2.95.2/g++/../machine/limits.h" 3
+
+# 108 "/usr/include/gcc/darwin/2.95.2/g++/../machine/limits.h" 3
+
+# 62 "/usr/include/limits.h" 2 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 15 "../BspLib/BspLibDefs.h" 2
+
+# 1 "/usr/include/math.h" 1 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+extern int signgam;
+
+
+enum fdversion {fdlibm_ieee = -1, fdlibm_svid, fdlibm_xopen, fdlibm_posix};
+
+
+
+
+
+
+
+
+
+
+
+extern enum fdversion _fdlib_version ;
+
+
+
+
+
+
+# 91 "/usr/include/math.h" 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+extern "C" {
+
+
+
+extern double acos (double) ;
+extern double asin (double) ;
+extern double atan (double) ;
+extern double atan2 (double, double) ;
+extern double cos (double) ;
+extern double sin (double) ;
+extern double tan (double) ;
+
+extern double cosh (double) ;
+extern double sinh (double) ;
+extern double tanh (double) ;
+
+extern double exp (double) ;
+extern double frexp (double, int *) ;
+extern double ldexp (double, int) ;
+extern double log (double) ;
+extern double log10 (double) ;
+extern double modf (double, double *) ;
+
+extern double pow (double, double) ;
+extern double sqrt (double) ;
+
+extern double ceil (double) ;
+extern double fabs (double) ;
+extern double floor (double) ;
+extern double fmod (double, double) ;
+
+
+extern double erf (double) ;
+extern double erfc (double) ;
+extern double gamma (double) ;
+extern double hypot (double, double) ;
+extern int isinf (double) ;
+extern int isnan (double) ;
+extern int finite (double) ;
+extern double j0 (double) ;
+extern double j1 (double) ;
+extern double jn (int, double) ;
+extern double lgamma (double) ;
+extern double y0 (double) ;
+extern double y1 (double) ;
+extern double yn (int, double) ;
+
+
+extern double acosh (double) ;
+extern double asinh (double) ;
+extern double atanh (double) ;
+extern double cbrt (double) ;
+extern double logb (double) ;
+extern double nextafter (double, double) ;
+extern double remainder (double, double) ;
+extern double scalb (double, int) ;
+
+
+
+
+
+
+
+
+extern double significand (double) ;
+
+
+
+
+extern double copysign (double, double) ;
+extern int ilogb (double) ;
+extern double rint (double) ;
+extern double scalbn (double, int) ;
+
+
+
+
+extern double cabs();
+extern double drem (double, double) ;
+extern double expm1 (double) ;
+extern double log1p (double) ;
+
+
+
+
+
+
+
+
+
+
+
+}
+
+
+# 16 "../BspLib/BspLibDefs.h" 2
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+typedef unsigned char byte;
+typedef unsigned short word;
+typedef unsigned long dword;
+
+
+typedef long fixed_t;
+typedef float float_t;
+typedef double hprec_t;
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+namespace BspLib {
+
+
+
+struct ColorRGB {
+ byte R;
+ byte G;
+ byte B;
+};
+
+
+struct ColorRGBA {
+ byte R;
+ byte G;
+ byte B;
+ byte A;
+};
+
+
+struct ColorRGBf {
+ float R;
+ float G;
+ float B;
+};
+
+
+struct ColorRGBAf {
+ float R;
+ float G;
+ float B;
+ float A;
+};
+
+
+
+
+
+
+
+
+
+
+
+
+class EpsAreas {
+
+public:
+ static double eps_scalarproduct;
+ static double eps_vanishcomponent;
+ static double eps_vanishdenominator;
+ static double eps_planethickness;
+ static double eps_pointonline;
+ static double eps_pointonlineseg;
+ static double eps_vertexmergearea;
+};
+
+
+}
+
+
+
+
+# 12 "../BspLib/VrmlFile.h" 2
+
+# 1 "../BspLib/BoundingBox.h" 1
+
+
+
+
+
+
+
+
+
+
+
+
+# 1 "../BspLib/BspObject.h" 1
+
+
+
+
+
+
+
+
+
+
+
+
+# 1 "../BspLib/SystemIO.h" 1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+namespace BspLib {
+
+
+
+
+class SystemIO {
+
+public:
+
+
+ enum {
+ SYSTEM_IO_OK = 0x0000,
+ SYSTEM_IO_ERROR = 0x0001,
+ END_OF_FILE = 0x0002,
+ FILE_NOT_FOUND = 0x0003,
+ FILE_READ_ERROR = 0x0004,
+ FILE_WRITE_ERROR = 0x0005,
+ FILE_CLOSED = 0x0006,
+ FILE_ALREADY_OPEN = 0x0007,
+ };
+
+
+ enum {
+ CRITERR_ALLOW_RET = 0x0001,
+ };
+
+
+ enum {
+ CHECK_ERRORS = 0x0001,
+ };
+
+public:
+ static void InfoMessage( char *message );
+ static void ErrorMessage( char *message );
+ static void HandleCriticalError( int flags = 0 );
+ static void SetProgramName( const char *name );
+ static void SetInfoMessageCallback( void (*callb)(char*) );
+ static void SetErrorMessageCallback( void (*callb)(char*) );
+ static void SetCriticalErrorCallback( int (*callb)(int) );
+
+
+
+
+
+public:
+ static const char version_str[];
+
+private:
+ static const char *program_name;
+ static void (*infomessage_callback)(char*);
+ static void (*errormessage_callback)(char*);
+ static int (*criticalerror_callback)(int);
+
+
+
+
+
+
+protected:
+
+
+
+class FilePtr {
+
+public:
+ FilePtr( const char *fname, const char *mode ) { fp = fopen( fname, mode ); }
+ ~FilePtr() { if ( fp ) fclose( fp ); }
+
+ operator FILE*() { return fp; }
+
+protected:
+ FILE *fp;
+
+};
+
+
+
+class FileAccess : public FilePtr {
+
+public:
+ FileAccess( const char *fname, const char *mode, int flags = CHECK_ERRORS );
+ ~FileAccess();
+
+ int ReOpen( const char *fname, const char *mode, int flags = CHECK_ERRORS );
+ int Close();
+
+ int Read( void *buffer, size_t size, size_t count, int flags = 0 );
+ int Write( void *buffer, size_t size, size_t count, int flags = 0 );
+
+ char *ReadLine( char *line, int maxlen, int flags = 0 );
+ char *WriteLine( char *line, int flags = 0 );
+
+ int Status() { return status; }
+
+ char *getFileName() { return filename; }
+
+private:
+ void IOError( int errorcode );
+
+private:
+ char *filename;
+ int status;
+
+};
+
+
+
+class StrScratch {
+
+public:
+ StrScratch() { line = new char[ 1024 ]; }
+ ~StrScratch() { delete line; }
+
+ operator char*() { return line; }
+
+private:
+ char *line;
+
+};
+
+
+};
+
+
+
+
+class String {
+
+public:
+ String() { data = 0 ; }
+ String( const char *src );
+ ~String() { delete data; }
+
+ String( const String& copyobj );
+ String& operator =( const String& copyobj );
+
+ operator char*() { return data; }
+
+ int IsNULL() const { return ( data == 0 ); }
+ int IsEmpty() const { return data ? ( *data == '\0' ) : 1 ; }
+
+ int getLength() const { return data ? strlen( data ) : 0; }
+
+private:
+ char *data;
+};
+
+
+}
+
+
+
+
+# 13 "../BspLib/BspObject.h" 2
+
+# 1 "../BspLib/Chunk.h" 1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+namespace BspLib {
+
+
+
+template<class T> class Chunk;
+
+
+
+
+template<class T>
+class ChunkRep : public virtual SystemIO {
+
+ friend class Chunk<T>;
+
+
+ enum {
+ E_INVALIDINDX
+ };
+
+ void Error( int err ) const;
+
+private:
+ ChunkRep( int chunksize = 0 );
+ ~ChunkRep();
+
+ int AddElement( const T& element );
+ T& FetchElement( int index );
+
+ int getNumElements() const;
+
+private:
+ int ref_count;
+ int numelements;
+ int maxnumelements;
+ T* elements;
+ ChunkRep* next;
+
+ static const int CHUNK_SIZE;
+};
+
+
+
+
+template<class T>
+ChunkRep<T>::ChunkRep( int chunksize ) : ref_count( 0 )
+{
+ int challocsize = chunksize > 0 ? chunksize : CHUNK_SIZE;
+ elements = new T[ challocsize ];
+ maxnumelements = challocsize;
+ numelements = 0;
+ next = 0 ;
+}
+
+
+
+
+template<class T>
+ChunkRep<T>::~ChunkRep()
+{
+ delete[] elements;
+ delete next;
+}
+
+
+
+
+template<class T>
+void ChunkRep<T>::Error( int err ) const
+{
+ {
+ StrScratch message;
+ sprintf( message, "***ERROR*** in object of a class of template Chunk" );
+
+ switch ( err ) {
+
+ case E_INVALIDINDX:
+ sprintf( message + strlen( message ), ": [Invalid index]" );
+ break;
+ }
+
+ ErrorMessage( message );
+ }
+
+ HandleCriticalError();
+}
+
+
+
+
+template<class T>
+T& ChunkRep<T>::FetchElement( int index )
+{
+
+# 133 "../BspLib/Chunk.h"
+
+
+ if ( index >= numelements )
+ Error( E_INVALIDINDX );
+
+
+ return elements[ index ];
+
+
+
+}
+
+
+
+
+template<class T>
+int ChunkRep<T>::AddElement( const T& element )
+{
+
+# 185 "../BspLib/Chunk.h"
+
+
+
+ if ( numelements == maxnumelements ) {
+
+
+ maxnumelements *= 2;
+
+
+
+ T *temp = new T[ maxnumelements ];
+
+
+
+
+ for ( int i = 0; i < numelements; i++ )
+ temp[ i ] = elements[ i ];
+
+ delete[] elements;
+ elements = temp;
+ }
+
+ elements[ numelements ] = element;
+ return numelements++;
+
+
+
+}
+
+
+
+
+template<class T>
+int ChunkRep<T>::getNumElements() const
+{
+ int num = 0;
+ for ( const ChunkRep *vlist = this; vlist; vlist = vlist->next )
+ num += vlist->numelements;
+ return num;
+}
+
+
+
+
+template<class T>
+class Chunk {
+
+public:
+ Chunk( int chunksize = 0 ) { rep = new ChunkRep<T>( chunksize ); rep->ref_count = 1; }
+ ~Chunk() { if ( --rep->ref_count == 0 ) delete rep; }
+
+ Chunk( const Chunk& copyobj );
+ Chunk& operator =( const Chunk& copyobj );
+
+ T& operator []( int index ) { return rep->FetchElement( index ); }
+ T& FetchElement( int index ) { return rep->FetchElement( index ); }
+ int AddElement( const T& element ) { return rep->AddElement( element ); }
+
+ int getNumElements() const { return rep->getNumElements(); }
+
+private:
+ ChunkRep<T>* rep;
+};
+
+
+
+
+template<class T>
+Chunk<T>::Chunk( const Chunk<T>& copyobj )
+{
+ rep = copyobj.rep;
+ rep->ref_count++;
+}
+
+
+
+
+template<class T>
+Chunk<T>& Chunk<T>::operator =( const Chunk<T>& copyobj )
+{
+ if ( &copyobj != this ) {
+ if ( --rep->ref_count == 0 ) {
+ delete rep;
+ }
+ rep = copyobj.rep;
+ rep->ref_count++;
+ }
+ return *this;
+}
+
+
+}
+
+
+
+
+# 14 "../BspLib/BspObject.h" 2
+
+# 1 "../BspLib/Face.h" 1
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 1 "../BspLib/Material.h" 1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+namespace BspLib {
+
+
+
+
+class Material {
+
+public:
+ Material() { }
+ ~Material() { }
+
+ ColorRGBA getAmbientColor() { return ambientcolor; }
+ ColorRGBA getDiffuseColor() { return diffusecolor; }
+ ColorRGBA getSpecularColor() { return specularcolor; }
+ ColorRGBA getEmissiveColor() { return emissivecolor; }
+
+ void setAmbientColor( ColorRGBA col ) { ambientcolor = col; ambientcolor.A = 255; }
+ void setDiffuseColor( ColorRGBA col ) { diffusecolor = col; diffusecolor.A = 255; }
+ void setSpecularColor( ColorRGBA col ) { specularcolor = col; specularcolor.A = 255; }
+ void setEmissiveColor( ColorRGBA col ) { emissivecolor = col; emissivecolor.A = 255; }
+
+ float getShininess() { return shininess; }
+ float getTransparency() { return transparency; }
+
+ void setShininess( float s ) { shininess = s; }
+ void setTransparency( float t ) { transparency = t; }
+
+private:
+ ColorRGBA ambientcolor;
+ ColorRGBA diffusecolor;
+ ColorRGBA specularcolor;
+ ColorRGBA emissivecolor;
+ float shininess;
+ float transparency;
+};
+
+
+}
+
+
+
+
+# 14 "../BspLib/Face.h" 2
+
+# 1 "../BspLib/Plane.h" 1
+
+
+
+
+
+
+
+
+
+
+
+
+# 1 "../BspLib/Vertex.h" 1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+namespace BspLib {
+
+
+
+
+class Vertex3 {
+
+ friend class Vector3;
+ friend class LineSeg3;
+
+ friend int operator ==( const Vertex3 v1, const Vertex3 v2 );
+ friend int operator !=( const Vertex3 v1, const Vertex3 v2 );
+
+ friend Vector3 operator -( const Vertex3 v1, const Vertex3 v2 );
+
+ friend Vertex3 operator +( const Vertex3 v1, const Vector3 v2 );
+ friend Vertex3 operator +( const Vector3 v1, const Vertex3 v2 );
+ friend Vertex3 operator -( const Vertex3 v1, const Vector3 v2 );
+
+public:
+ Vertex3( hprec_t x = 0, hprec_t y = 0, hprec_t z = 0, hprec_t w = 1.0 );
+ ~Vertex3() { }
+
+ Vertex3& operator +=( const Vector3 v );
+ Vertex3& operator -=( const Vector3 v );
+
+ int IsInVicinity( const Vertex3& vertex ) const;
+ void ChangeAxes( const char *xchangecmd, const Vertex3& ads );
+
+ hprec_t getX() const { return X; }
+ hprec_t getY() const { return Y; }
+ hprec_t getZ() const { return Z; }
+ hprec_t getW() const { return W; }
+
+ void setX( hprec_t x ) { X = x; }
+ void setY( hprec_t y ) { Y = y; }
+ void setZ( hprec_t z ) { Z = z; }
+ void setW( hprec_t w ) { W = w; }
+
+private:
+ void ChangeAxis( const char xchar, const hprec_t src );
+
+protected:
+ hprec_t X;
+ hprec_t Y;
+ hprec_t Z;
+ hprec_t W;
+};
+
+
+
+
+class Vector3 : public Vertex3 {
+
+ friend class LineSeg3;
+
+ friend Vector3 operator -( const Vertex3 v1, const Vertex3 v2 );
+
+ friend Vertex3 operator +( const Vertex3 v1, const Vector3 v2 );
+ friend Vertex3 operator +( const Vector3 v1, const Vertex3 v2 );
+ friend Vertex3 operator -( const Vertex3 v1, const Vector3 v2 );
+
+ friend Vector3 operator +( const Vector3 v1, const Vector3 v2 );
+ friend Vector3 operator -( const Vector3 v1, const Vector3 v2 );
+
+ friend Vector3 operator *( const Vector3 v1, double t );
+ friend Vector3 operator *( double t, const Vector3 v1 );
+
+public:
+ Vector3( hprec_t x = 0, hprec_t y = 0, hprec_t z = 0, hprec_t w = 1.0 )
+ : Vertex3( x, y, z, w ) { }
+
+ Vector3( const Vertex3& v1, const Vertex3& v2 )
+ : Vertex3( v2.X - v1.X, v2.Y - v1.Y, v2.Z - v1.Z ) { }
+
+ Vector3( const Vector3& v1, const Vector3& v2 );
+
+ Vector3( const Vertex3& vtx ) { *(Vertex3*)this = vtx; }
+ ~Vector3() { }
+
+ Vector3& operator +=( const Vector3 v );
+ Vector3& operator -=( const Vector3 v );
+
+ Vector3& operator *=( double t );
+
+ int Normalize();
+ int Homogenize();
+ int IsNullVector() const;
+ hprec_t VecLength() const;
+ hprec_t DotProduct( const Vector3& vect ) const;
+ void CrossProduct( const Vector3& vect1, const Vector3& vect2 );
+ void CreateDirVec( const Vertex3& vertex1, const Vertex3& vertex2 );
+};
+
+
+
+
+class Vertex2 {
+
+ friend class Vector2;
+ friend class LineSeg2;
+
+ friend int operator ==( const Vertex2 v1, const Vertex2 v2 );
+ friend int operator !=( const Vertex2 v1, const Vertex2 v2 );
+
+ friend Vector2 operator -( const Vertex2 v1, const Vertex2 v2 );
+
+ friend Vertex2 operator +( const Vertex2 v1, const Vector2 v2 );
+ friend Vertex2 operator +( const Vector2 v1, const Vertex2 v2 );
+ friend Vertex2 operator -( const Vertex2 v1, const Vector2 v2 );
+
+public:
+ Vertex2( hprec_t x = 0, hprec_t y = 0, hprec_t w = 1.0 ) { X = x; Y = y; W = w; }
+
+ Vertex2( const Vector2& vect );
+ ~Vertex2() { }
+
+ Vertex2& operator +=( const Vector2 v );
+ Vertex2& operator -=( const Vector2 v );
+
+ int IsInVicinity( const Vertex2& vertex ) const;
+ void InitFromVertex3( const Vertex3& vertex );
+
+ hprec_t getX() const { return X; }
+ hprec_t getY() const { return Y; }
+ hprec_t getW() const { return W; }
+
+ void setX( hprec_t x ) { X = x; }
+ void setY( hprec_t y ) { Y = y; }
+ void setW( hprec_t w ) { W = w; }
+
+protected:
+ hprec_t X;
+ hprec_t Y;
+ hprec_t W;
+};
+
+
+
+
+class Vector2 : public Vertex2 {
+
+ friend class LineSeg2;
+
+ friend Vector2 operator -( const Vertex2 v1, const Vertex2 v2 );
+
+ friend Vertex2 operator +( const Vertex2 v1, const Vector2 v2 );
+ friend Vertex2 operator +( const Vector2 v1, const Vertex2 v2 );
+ friend Vertex2 operator -( const Vertex2 v1, const Vector2 v2 );
+
+ friend Vector2 operator +( const Vector2 v1, const Vector2 v2 );
+ friend Vector2 operator -( const Vector2 v1, const Vector2 v2 );
+
+ friend Vector2 operator *( const Vector2 v1, double t );
+ friend Vector2 operator *( double t, const Vector2 v1 );
+
+public:
+ Vector2( hprec_t x = 0, hprec_t y = 0, hprec_t w = 1.0 )
+ : Vertex2( x, y, w ) { }
+
+ Vector2( const Vertex2& v1, const Vertex2& v2 )
+ : Vertex2( v2.X - v1.X, v2.Y - v1.Y ) { }
+
+ Vector2( const Vertex2& vtx ) { *(Vertex2*)this = vtx; }
+ ~Vector2() { }
+
+ Vector2& operator +=( const Vector2 v );
+ Vector2& operator -=( const Vector2 v );
+
+ Vector2& operator *=( double t );
+
+ int Normalize();
+ int Homogenize();
+ int IsNullVector() const;
+ hprec_t VecLength() const;
+ hprec_t DotProduct( const Vector2& vect ) const;
+ void CreateDirVec( const Vertex2& vertex, const Vertex2& dirvec );
+};
+
+
+}
+
+
+
+# 1 "../BspLib/Vector.h" 1
+
+
+
+
+
+
+
+
+
+
+
+# 1 "../BspLib/Vector3.h" 1
+
+
+
+
+
+
+
+
+
+
+
+
+# 1 "../BspLib/Vertex3.h" 1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+namespace BspLib {
+
+
+
+inline Vertex3::Vertex3( hprec_t x, hprec_t y, hprec_t z, hprec_t w )
+{
+ X = x;
+ Y = y;
+ Z = z;
+ W = w;
+}
+
+
+inline int operator ==( const Vertex3 v1, const Vertex3 v2 )
+{
+ return ( ( v1.X == v2.X ) && ( v1.Y == v2.Y ) && ( v1.Z == v2.Z ) && ( v1.W == v2.W ) );
+}
+
+
+inline int operator !=( const Vertex3 v1, const Vertex3 v2 )
+{
+ return ( ( v1.X != v2.X ) || ( v1.Y != v2.Y ) || ( v1.Z != v2.Z ) || ( v1.W != v2.W ) );
+}
+
+
+inline Vertex3& Vertex3::operator +=( const Vector3 v )
+{
+ X += v.X;
+ Y += v.Y;
+ Z += v.Z;
+
+ return *this;
+}
+
+
+inline Vertex3& Vertex3::operator -=( const Vector3 v )
+{
+ X -= v.X;
+ Y -= v.Y;
+ Z -= v.Z;
+
+ return *this;
+}
+
+
+inline int Vertex3::IsInVicinity( const Vertex3& vertex ) const
+{
+ return ( ( fabs( X - vertex.X ) < EpsAreas::eps_vertexmergearea ) &&
+ ( fabs( Y - vertex.Y ) < EpsAreas::eps_vertexmergearea ) &&
+ ( fabs( Z - vertex.Z ) < EpsAreas::eps_vertexmergearea ) );
+}
+
+
+}
+
+
+
+
+# 13 "../BspLib/Vector3.h" 2
+
+
+
+namespace BspLib {
+
+
+
+inline Vector3 operator *( const Vector3 v1, double t )
+{
+ return Vector3( v1.X * t, v1.Y * t, v1.Z * t, 1.0 );
+}
+
+
+inline Vector3 operator *( double t, const Vector3 v1 )
+{
+ return Vector3( v1.X * t, v1.Y * t, v1.Z * t, 1.0 );
+}
+
+
+inline Vector3::Vector3( const Vector3& v1, const Vector3& v2 )
+{
+ CrossProduct( v1, v2 );
+}
+
+
+inline Vector3& Vector3::operator +=( const Vector3 v )
+{
+ X += v.X;
+ Y += v.Y;
+ Z += v.Z;
+ return *this;
+}
+
+
+inline Vector3& Vector3::operator -=( const Vector3 v )
+{
+ X -= v.X;
+ Y -= v.Y;
+ Z -= v.Z;
+ return *this;
+}
+
+
+inline Vector3& Vector3::operator *=( double t )
+{
+ X *= t;
+ Y *= t;
+ Z *= t;
+ return *this;
+}
+
+
+inline int Vector3::Normalize()
+{
+ if ( IsNullVector() )
+ return 0 ;
+
+ double oonorm = 1 / VecLength();
+ X = X * oonorm;
+ Y = Y * oonorm;
+ Z = Z * oonorm;
+ W = 1.0;
+ return 1 ;
+}
+
+
+inline int Vector3::Homogenize()
+{
+ if ( fabs( W ) < EpsAreas::eps_vanishdenominator )
+ return 0 ;
+
+ double oow = 1 / W;
+ X = X * oow;
+ Y = Y * oow;
+ Z = Z * oow;
+ W = 1.0;
+ return 1 ;
+}
+
+
+inline int Vector3::IsNullVector() const
+{
+
+ return ( ( fabs( X ) < EpsAreas::eps_vanishcomponent ) && ( fabs( Y ) < EpsAreas::eps_vanishcomponent ) && ( fabs( Z ) < EpsAreas::eps_vanishcomponent ) );
+}
+
+
+inline hprec_t Vector3::VecLength() const
+{
+ return sqrt( X * X + Y * Y + Z * Z );
+}
+
+
+inline hprec_t Vector3::DotProduct( const Vector3& vect ) const
+{
+ return ( vect.X * X ) + ( vect.Y * Y ) + ( vect.Z * Z );
+}
+
+
+inline void Vector3::CrossProduct( const Vector3& vect1, const Vector3& vect2 )
+{
+ X = ( vect1.Y * vect2.Z ) - ( vect1.Z * vect2.Y );
+ Y = ( vect1.Z * vect2.X ) - ( vect1.X * vect2.Z );
+ Z = ( vect1.X * vect2.Y ) - ( vect1.Y * vect2.X );
+ W = 1.0;
+}
+
+
+inline void Vector3::CreateDirVec( const Vertex3& vertex1, const Vertex3& vertex2 )
+{
+ X = vertex2.X - vertex1.X;
+ Y = vertex2.Y - vertex1.Y;
+ Z = vertex2.Z - vertex1.Z;
+ W = 1.0;
+}
+
+
+}
+
+
+
+
+# 12 "../BspLib/Vector.h" 2
+
+# 1 "../BspLib/Vector2.h" 1
+
+
+
+
+
+
+
+
+
+
+
+
+# 1 "../BspLib/Vertex2.h" 1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+namespace BspLib {
+
+
+
+inline Vertex2::Vertex2( const Vector2& vect )
+{
+ X = vect.X;
+ Y = vect.Y;
+ W = vect.W;
+}
+
+
+inline int operator ==( const Vertex2 v1, const Vertex2 v2 )
+{
+ return ( ( v1.X == v2.X ) && ( v1.Y == v2.Y ) && ( v1.W == v2.W ) );
+}
+
+
+inline int operator !=( const Vertex2 v1, const Vertex2 v2 )
+{
+ return ( ( v1.X != v2.X ) || ( v1.Y != v2.Y ) || ( v1.W != v2.W ) );
+}
+
+
+inline Vertex2& Vertex2::operator +=( const Vector2 v )
+{
+ X += v.X;
+ Y += v.Y;
+
+ return *this;
+}
+
+
+inline Vertex2& Vertex2::operator -=( const Vector2 v )
+{
+ X -= v.X;
+ Y -= v.Y;
+
+ return *this;
+}
+
+
+inline int Vertex2::IsInVicinity( const Vertex2& vertex ) const
+{
+ return ( ( fabs( X - vertex.X ) < EpsAreas::eps_vertexmergearea ) &&
+ ( fabs( Y - vertex.Y ) < EpsAreas::eps_vertexmergearea ) );
+}
+
+
+inline void Vertex2::InitFromVertex3( const Vertex3& vertex )
+{
+ X = vertex.getX();
+ Y = vertex.getY();
+ W = vertex.getZ();
+}
+
+
+}
+
+
+
+
+# 13 "../BspLib/Vector2.h" 2
+
+
+
+namespace BspLib {
+
+
+
+inline Vector2 operator *( const Vector2 v1, double t )
+{
+ return Vector2( v1.X * t, v1.Y * t, 1.0 );
+}
+
+
+inline Vector2 operator *( double t, const Vector2 v1 )
+{
+ return Vector2( v1.X * t, v1.Y * t, 1.0 );
+}
+
+
+inline Vector2& Vector2::operator +=( const Vector2 v )
+{
+ X += v.X;
+ Y += v.Y;
+ return *this;
+}
+
+
+inline Vector2& Vector2::operator -=( const Vector2 v )
+{
+ X -= v.X;
+ Y -= v.Y;
+ return *this;
+}
+
+
+inline Vector2& Vector2::operator *=( double t )
+{
+ X *= t;
+ Y *= t;
+ return *this;
+}
+
+
+inline int Vector2::Normalize()
+{
+ if ( IsNullVector() )
+ return 0 ;
+
+ double oonorm = 1 / VecLength();
+ X = X * oonorm;
+ Y = Y * oonorm;
+ W = 1.0;
+ return 1 ;
+}
+
+
+inline int Vector2::Homogenize()
+{
+ if ( fabs( W ) < EpsAreas::eps_vanishdenominator )
+ return 0 ;
+
+ double oow = 1 / W;
+ X = X * oow;
+ Y = Y * oow;
+ W = 1.0;
+ return 1 ;
+}
+
+
+inline int Vector2::IsNullVector() const
+{
+
+ return ( ( fabs( X ) < EpsAreas::eps_vanishcomponent ) && ( fabs( Y ) < EpsAreas::eps_vanishcomponent ) );
+}
+
+
+inline hprec_t Vector2::VecLength() const
+{
+ return sqrt( X * X + Y * Y );
+}
+
+
+inline hprec_t Vector2::DotProduct( const Vector2& vect ) const
+{
+ return ( vect.X * X ) + ( vect.Y * Y );
+}
+
+
+inline void Vector2::CreateDirVec( const Vertex2& vertex1, const Vertex2& vertex2 )
+{
+ X = vertex2.X - vertex1.X;
+ Y = vertex2.Y - vertex1.Y;
+ W = 1.0;
+}
+
+
+}
+
+
+
+
+# 13 "../BspLib/Vector.h" 2
+
+
+
+namespace BspLib {
+
+
+
+inline Vertex3 operator +( const Vertex3 v1, const Vector3 v2 )
+{
+ return Vertex3( v1.X + v2.X, v1.Y + v2.Y, v1.Z + v2.Z, 1.0 );
+}
+
+
+inline Vertex3 operator +( const Vector3 v1, const Vertex3 v2 )
+{
+ return Vertex3( v1.X + v2.X, v1.Y + v2.Y, v1.Z + v2.Z, 1.0 );
+}
+
+
+inline Vector3 operator -( const Vertex3 v1, const Vertex3 v2 )
+{
+ return Vector3( v1.X - v2.X, v1.Y - v2.Y, v1.Z - v2.Z, 1.0 );
+}
+
+
+inline Vertex3 operator -( const Vertex3 v1, const Vector3 v2 )
+{
+ return Vertex3( v1.X - v2.X, v1.Y - v2.Y, v1.Z - v2.Z, 1.0 );
+}
+
+
+inline Vector3 operator +( const Vector3 v1, const Vector3 v2 )
+{
+ return Vector3( v1.X + v2.X, v1.Y + v2.Y, v1.Z + v2.Z, 1.0 );
+}
+
+
+inline Vector3 operator -( const Vector3 v1, const Vector3 v2 )
+{
+ return Vector3( v1.X - v2.X, v1.Y - v2.Y, v1.Z - v2.Z, 1.0 );
+}
+
+
+
+
+
+
+inline Vertex2 operator +( const Vertex2 v1, const Vector2 v2 )
+{
+ return Vertex2( v1.X + v2.X, v1.Y + v2.Y, 1.0 );
+}
+
+
+inline Vertex2 operator +( const Vector2 v1, const Vertex2 v2 )
+{
+ return Vertex2( v1.X + v2.X, v1.Y + v2.Y, 1.0 );
+}
+
+
+inline Vector2 operator -( const Vertex2 v1, const Vertex2 v2 )
+{
+ return Vector2( v1.X - v2.X, v1.Y - v2.Y, 1.0 );
+}
+
+
+inline Vertex2 operator -( const Vertex2 v1, const Vector2 v2 )
+{
+ return Vertex2( v1.X - v2.X, v1.Y - v2.Y, 1.0 );
+}
+
+
+inline Vector2 operator +( const Vector2 v1, const Vector2 v2 )
+{
+ return Vector2( v1.X + v2.X, v1.Y + v2.Y, 1.0 );
+}
+
+
+inline Vector2 operator -( const Vector2 v1, const Vector2 v2 )
+{
+ return Vector2( v1.X - v2.X, v1.Y - v2.Y, 1.0 );
+}
+
+
+}
+
+
+
+
+# 199 "../BspLib/Vertex.h" 2
+
+# 1 "../BspLib/LineSeg2.h" 1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+namespace BspLib {
+
+
+
+
+class LineSeg2 {
+
+public:
+ LineSeg2( const Vertex2& basevtx, const Vector2& dirvec );
+ ~LineSeg2() { }
+
+ int PointOnLineSeg( const Vertex2& vertex ) const;
+
+private:
+ Vertex2 m_basevtx;
+ Vector2 m_dirvec;
+};
+
+
+inline LineSeg2::LineSeg2( const Vertex2& basevtx, const Vector2& dirvec )
+{
+ m_basevtx = basevtx;
+ m_dirvec = dirvec;
+}
+
+
+}
+
+
+
+
+# 200 "../BspLib/Vertex.h" 2
+
+# 1 "../BspLib/LineSeg3.h" 1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+namespace BspLib {
+
+
+
+
+class LineSeg3 {
+
+public:
+ LineSeg3( const Vertex3& basevtx, const Vector3& dirvec );
+ ~LineSeg3() { }
+
+ int PointOnLineSeg( const Vertex3& vertex ) const;
+
+private:
+ Vertex3 m_basevtx;
+ Vector3 m_dirvec;
+};
+
+
+inline LineSeg3::LineSeg3( const Vertex3& basevtx, const Vector3& dirvec )
+{
+ m_basevtx = basevtx;
+ m_dirvec = dirvec;
+}
+
+
+}
+
+
+
+
+# 201 "../BspLib/Vertex.h" 2
+
+# 1 "../BspLib/VertexChunk.h" 1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+namespace BspLib {
+
+
+
+
+class VertexChunkRep : public virtual SystemIO {
+
+ friend class VertexChunk;
+
+private:
+ VertexChunkRep( int chunksize = 0 );
+ ~VertexChunkRep();
+
+ Vertex3& FetchVertex( int index );
+ int AddVertex( Vertex3 vertex );
+ int FindVertex( const Vertex3& vertex );
+ int FindCloseVertex( const Vertex3& vertex, int skip = -1 );
+ int CheckVertices( int verbose );
+
+ int getNumElements() const;
+
+private:
+ void ChangeAxis( char xchar, hprec_t src );
+ int VerticesEqual( Vertex3 v1, Vertex3 v2 );
+
+private:
+ int ref_count;
+
+ int numvertices;
+ int maxnumvertices;
+ Vertex3* vertices;
+ VertexChunkRep* next;
+
+ int nummultvertices;
+ static int eliminatedoublets;
+ static const int CHUNK_SIZE;
+};
+
+
+inline VertexChunkRep::VertexChunkRep( int chunksize ) : ref_count( 0 )
+{
+ int challocsize = chunksize > 0 ? chunksize : CHUNK_SIZE;
+ vertices = new Vertex3[ challocsize ];
+ maxnumvertices = challocsize;
+ numvertices = 0;
+ next = 0 ;
+}
+
+
+inline VertexChunkRep::~VertexChunkRep()
+{
+ delete next;
+ delete[] vertices;
+}
+
+
+inline int VertexChunkRep::VerticesEqual( Vertex3 v1, Vertex3 v2 )
+{
+
+ return ( v1 == v2 );
+}
+
+
+
+
+class VertexChunk {
+
+public:
+ VertexChunk( int chunksize = 0 ) { rep = new VertexChunkRep( chunksize ); rep->ref_count = 1; }
+ ~VertexChunk() { if ( --rep->ref_count == 0 ) delete rep; }
+
+ VertexChunk( const VertexChunk& copyobj );
+ VertexChunk& operator =( const VertexChunk& copyobj );
+
+ Vertex3& operator []( int index ) { return rep->FetchVertex( index ); }
+ Vertex3& FetchVertex( int index ) { return rep->FetchVertex( index ); }
+
+ int AddVertex( const Vertex3 vertex ) { return rep->AddVertex( vertex ); }
+ int FindVertex( const Vertex3& vertex ) { return rep->FindVertex( vertex ); }
+ int FindCloseVertex( Vertex3 vertex, int skip = -1 ) { return rep->FindCloseVertex( vertex, skip ); }
+ int CheckVertices( int verbose ) { return rep->CheckVertices( verbose ); }
+
+ int getNumElements() const { return rep->getNumElements(); }
+
+private:
+ VertexChunkRep* rep;
+};
+
+
+inline VertexChunk::VertexChunk( const VertexChunk& copyobj )
+{
+ rep = copyobj.rep;
+ rep->ref_count++;
+}
+
+
+inline VertexChunk& VertexChunk::operator =( const VertexChunk& copyobj )
+{
+ if ( &copyobj != this ) {
+ if ( --rep->ref_count == 0 ) {
+ delete rep;
+ }
+ rep = copyobj.rep;
+ rep->ref_count++;
+ }
+ return *this;
+}
+
+
+}
+
+
+
+
+# 202 "../BspLib/Vertex.h" 2
+
+
+
+
+
+# 13 "../BspLib/Plane.h" 2
+
+
+
+namespace BspLib {
+
+
+
+
+class Plane {
+
+ enum {
+ NORMAL_VALID = 0x0001,
+ OFFSET_VALID = 0x0002,
+ PLANE_VALID = NORMAL_VALID | OFFSET_VALID,
+ };
+
+public:
+ Plane() : m_valid( 0 ) { }
+ Plane( const Vector3& pnormal );
+ Plane( const Vector3& pnormal, double poffset );
+ Plane( const Vertex3& v1, const Vertex3& v2, const Vertex3& v3 );
+ ~Plane() { }
+
+ int InitPlane( const Vertex3& v1, const Vertex3& v2, const Vertex3& v3 );
+ int CalcPlaneOffset( const Vertex3& vtx );
+
+ Vector3 getPlaneNormal() const { return m_normal; }
+ void setPlaneNormal( const Vector3& pnormal ) { m_normal = pnormal; }
+
+ double getPlaneOffset() const { return m_offset; }
+ void setPlaneOffset( double poffset ) { m_offset = poffset; }
+
+ int NormalValid() const { return ( ( m_valid & NORMAL_VALID ) == NORMAL_VALID ); }
+ int PlaneValid() const { return ( ( m_valid & PLANE_VALID ) == PLANE_VALID ); }
+
+ void ApplyScaleFactor( double sfac );
+ void EliminateDirectionality();
+
+ int PointContained( const Vertex3& point ) const;
+ int PointInPositiveHalfspace( const Vertex3& point ) const;
+ int PointInNegativeHalfspace( const Vertex3& point ) const;
+
+private:
+ Vector3 m_normal;
+ double m_offset;
+ int m_valid;
+};
+
+
+inline Plane::Plane( const Vector3& pnormal )
+{
+ m_normal = pnormal;
+ m_offset = 0.0;
+ m_valid = NORMAL_VALID;
+}
+
+
+inline Plane::Plane( const Vector3& pnormal, double poffset )
+{
+ m_normal = pnormal;
+ m_offset = poffset;
+ m_valid = PLANE_VALID;
+}
+
+
+inline Plane::Plane( const Vertex3& v1, const Vertex3& v2, const Vertex3& v3 )
+{
+
+
+ m_normal.CrossProduct( v3 - v1, v2 - v1 );
+
+
+ m_valid = m_normal.Normalize() ? PLANE_VALID : 0;
+
+
+ m_offset = m_normal.DotProduct( v1 );
+}
+
+
+inline int Plane::InitPlane( const Vertex3& v1, const Vertex3& v2, const Vertex3& v3 )
+{
+ *this = Plane( v1, v2, v3 );
+ return m_valid;
+}
+
+
+inline int Plane::CalcPlaneOffset( const Vertex3& vtx )
+{
+
+ m_offset = m_normal.DotProduct( vtx );
+ return ( m_valid |= OFFSET_VALID );
+}
+
+
+inline void Plane::ApplyScaleFactor( double sfac )
+{
+
+
+ m_offset *= sfac;
+}
+
+
+inline void Plane::EliminateDirectionality()
+{
+ if ( m_offset < 0.0 ) {
+ m_normal *= -1.0;
+ m_offset = -m_offset;
+ }
+}
+
+
+inline int Plane::PointContained( const Vertex3& point ) const
+{
+ return ( fabs( m_normal.DotProduct( point ) - m_offset ) < EpsAreas::eps_planethickness );
+}
+
+
+inline int Plane::PointInPositiveHalfspace( const Vertex3& point ) const
+{
+ return ( m_normal.DotProduct( point ) - m_offset >= EpsAreas::eps_planethickness );
+}
+
+
+inline int Plane::PointInNegativeHalfspace( const Vertex3& point ) const
+{
+ return ( m_normal.DotProduct( point ) - m_offset <= - EpsAreas::eps_planethickness );
+}
+
+
+}
+
+
+
+
+# 15 "../BspLib/Face.h" 2
+
+
+# 1 "../BspLib/Texture.h" 1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+namespace BspLib {
+
+
+
+
+
+
+
+class Texture : public virtual SystemIO {
+
+public:
+ Texture( int w = -1, int h = -1, char *tname = 0 , char *fname = 0 );
+ ~Texture() { }
+
+ int getWidth() const { return m_width; }
+ int getHeight() const { return m_height; }
+ const char* getName() const { return m_name; }
+ const char* getFile() const { return m_file; }
+
+ void setWidth( int w ) { m_width = w; }
+ void setHeight( int h ) { m_height = h; }
+ void setName( const char *tname );
+ void setFile( const char *fname );
+
+ void WriteInfo( FILE *fp );
+
+private:
+ int m_width;
+ int m_height;
+ char m_name[ 31 + 1 ];
+ char m_file[ 1024 + 1 ];
+};
+
+
+typedef Chunk<Texture> TextureChunk;
+
+
+}
+
+
+
+
+# 17 "../BspLib/Face.h" 2
+
+# 1 "../BspLib/TriMapping.h" 1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+namespace BspLib {
+
+
+
+
+class TriMapping : public virtual SystemIO {
+
+ void Error() const;
+
+public:
+ TriMapping() { }
+ ~TriMapping() { }
+
+ Vertex2& getMapXY( int indx ) { if ( indx > 2 ) Error(); return map_xy[ indx ]; }
+ Vertex2& getMapUV( int indx ) { if ( indx > 2 ) Error(); return map_uv[ indx ]; }
+
+private:
+ Vertex2 map_xy[ 3 ];
+ Vertex2 map_uv[ 3 ];
+};
+
+
+}
+
+
+
+
+# 18 "../BspLib/Face.h" 2
+
+
+
+
+namespace BspLib {
+
+
+
+
+class Face : public virtual SystemIO {
+
+ void Error() const;
+
+public:
+
+
+ enum ShadingType {
+ no_shad = 0x1000,
+ flat_shad = 0x1001,
+ gouraud_shad = 0x1002,
+ afftex_shad = 0x2003,
+ ipol1tex_shad = 0x2004,
+ ipol2tex_shad = 0x2005,
+ persptex_shad = 0x2006,
+ material_shad = 0x1007,
+ texmat_shad = 0x3008,
+ num_shading_types = 9,
+ base_mask = 0x00ff,
+ color_mask = 0x1000,
+ texmap_mask = 0x2000,
+ };
+
+
+ enum ColorModel {
+ no_col,
+ indexed_col,
+ rgb_col,
+ material_col,
+ num_color_models
+ };
+
+public:
+ Face();
+ ~Face() { delete faceplane; delete facematerial; delete facemapping; delete texturename; }
+
+ Face( const Face& copyobj );
+ Face& operator =( const Face& copyobj );
+
+ int getId() const { return faceid; }
+ void setId( int id ) { faceid = id; }
+
+ Material getMaterial() const { if ( facematerial == 0 ) Error(); return *facematerial; }
+ Plane getPlane() const { if ( faceplane == 0 ) Error(); return *faceplane; }
+
+ Vector3 getPlaneNormal() const;
+ void setPlaneNormal( const Vector3& normal );
+
+ int getShadingType() const { return shadingtype; }
+ void setShadingType( int type );
+
+ int getColorType() const { return colortype; }
+ void getColorIndex( dword& col ) const { col = facecolor_indx; }
+ void getColorRGBA( ColorRGBA& col ) const { col = facecolor_rgba; }
+ void getColorChannels( float& r, float& g, float& b ) const;
+ const char *getTextureName() { return texturename; }
+
+ void setFaceColor( dword col );
+ void setFaceColor( ColorRGBA col );
+ void setTextureName( const char *tname );
+
+ int NormalValid() const { return faceplane ? faceplane->NormalValid() : 0 ; }
+ int PlaneValid() const { return faceplane ? faceplane->PlaneValid() : 0 ; }
+ int MaterialAttached() const { return ( facematerial != 0 ); }
+ int MappingAttached() const { return ( facemapping != 0 ); }
+ int FaceTexMapped() const { return ( ( shadingtype & texmap_mask ) != 0 ); }
+
+ void CalcPlane( const Vertex3& vertex1, const Vertex3& vertex2, const Vertex3& vertex3 );
+ void AttachNormal( const Vector3& normal );
+ void AttachPlane( Plane *plane );
+ void AttachMaterial( Material *mat );
+
+ int ConvertColorIndexToRGB( char *palette, int changemode );
+
+ Vertex2& MapXY( int indx );
+ Vertex2& MapUV( int indx );
+
+ void WriteFaceInfo( FILE *fp ) const;
+ void WriteNormalInfo( FILE *fp ) const;
+ void WriteMappingInfo( FILE *fp ) const;
+
+public:
+ static int GetTypeIndex( const char *type );
+ static int GetColorModelIndex( const char *type );
+
+public:
+ static const char* material_strings[];
+
+private:
+ static const char* prop_strings[];
+ static const int prop_ids[];
+ static const char* color_strings[];
+ static const int color_ids[];
+
+private:
+ int faceid;
+ Plane* faceplane;
+
+ int shadingtype;
+ int colortype;
+
+ dword facecolor_indx;
+ ColorRGBA facecolor_rgba;
+ Material* facematerial;
+ TriMapping* facemapping;
+ char* texturename;
+};
+
+
+typedef Chunk<Face> FaceChunk;
+
+
+inline Face::Face()
+{
+ faceid = -1;
+ shadingtype = -1;
+ colortype = -1;
+ faceplane = 0 ;
+ facematerial = 0 ;
+ facemapping = 0 ;
+ texturename = 0 ;
+}
+
+
+inline Vector3 Face::getPlaneNormal() const
+{
+
+ if ( ( faceplane == 0 ) || !faceplane->NormalValid() )
+ Error();
+ ;
+ return faceplane->getPlaneNormal();
+}
+
+
+inline void Face::setPlaneNormal( const Vector3& normal )
+{
+
+ if ( ( faceplane == 0 ) || !faceplane->NormalValid() )
+ Error();
+ ;
+ faceplane->setPlaneNormal( normal );
+}
+
+
+inline void Face::setShadingType( int type )
+{
+
+ if ( ( type & base_mask ) >= num_shading_types )
+ Error();
+ ;
+ shadingtype = type;
+}
+
+
+inline void Face::setFaceColor( dword col )
+{
+ facecolor_indx = col;
+ colortype = indexed_col;
+}
+
+
+inline void Face::setFaceColor( ColorRGBA col )
+{
+ facecolor_rgba = col;
+ colortype = rgb_col;
+}
+
+
+inline void Face::getColorChannels( float& r, float& g, float& b ) const
+{
+ r = facecolor_rgba.R / 255.0f;
+ g = facecolor_rgba.G / 255.0f;
+ b = facecolor_rgba.B / 255.0f;
+}
+
+
+inline Vertex2& Face::MapXY( int indx )
+{
+ if ( facemapping == 0 )
+ facemapping = new TriMapping;
+ return facemapping->getMapXY( indx );
+}
+
+
+inline Vertex2& Face::MapUV( int indx )
+{
+ if ( facemapping == 0 )
+ facemapping = new TriMapping;
+ return facemapping->getMapUV( indx );
+}
+
+
+}
+
+
+
+
+# 15 "../BspLib/BspObject.h" 2
+
+# 1 "../BspLib/Mapping.h" 1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+namespace BspLib {
+
+
+
+
+
+
+
+class Mapping : public virtual SystemIO {
+
+ void Error( int vertindx );
+
+public:
+ Mapping() { numvertexindxs = 0; }
+ ~Mapping() { }
+
+ void InsertFaceVertex( int vindx ) { facevertexindxs[ numvertexindxs++ ] = vindx; }
+ void SetCorrespondence( int vindx, Vertex2 vertex );
+ Vertex2 FetchMapPoint( int vertindx );
+
+ int getNumVertices() { return numvertexindxs; }
+ void setNumVertices( int num ) { numvertexindxs = num; }
+ void setMappingCoordinates( int k, const Vertex2& vertex);
+
+ void WriteMappingInfo( FILE *fp ) const;
+
+private:
+ int numvertexindxs;
+ int facevertexindxs[ 32 ];
+ Vertex2 mappingcoordinates[ 32 ];
+};
+
+
+typedef Chunk<Mapping> MappingChunk;
+
+
+inline void Mapping::setMappingCoordinates( int k, const Vertex2& vertex)
+{
+ if ( k < 32 )
+ mappingcoordinates[ k ] = vertex;
+ else
+ Error( k );
+}
+
+
+inline void Mapping::SetCorrespondence( int vindx, Vertex2 vertex )
+{
+ if ( numvertexindxs < 32 ) {
+ facevertexindxs[ numvertexindxs ] = vindx;
+ mappingcoordinates[ numvertexindxs ] = vertex;
+ numvertexindxs++;
+ } else {
+ Error( numvertexindxs );
+ }
+}
+
+
+inline Vertex2 Mapping::FetchMapPoint( int vertindx )
+{
+ for ( int i = 0; i < numvertexindxs; i++ )
+ if ( facevertexindxs[ i ] == vertindx )
+ return mappingcoordinates[ i ];
+ Error( vertindx );
+ return Vertex2( 0, 0 );
+}
+
+
+}
+
+
+
+
+# 16 "../BspLib/BspObject.h" 2
+
+# 1 "../BspLib/PolygonList.h" 1
+
+
+
+
+
+
+
+
+
+
+
+
+# 1 "../BspLib/Polygon.h" 1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+namespace BspLib {
+
+
+class BoundingBox;
+
+
+
+
+class VIndx {
+
+public:
+ VIndx( int indx = -1, VIndx *next = 0 ) { vertindx = indx; nextvertindx = next; }
+ ~VIndx() { delete nextvertindx; }
+
+ int getIndx() const { return vertindx; }
+ void setIndx( int indx ) { vertindx = indx; }
+
+ VIndx* getNext() const { return nextvertindx; }
+ void setNext( VIndx *next ) { nextvertindx = next; }
+
+private:
+ int vertindx;
+ VIndx* nextvertindx;
+};
+
+
+class BSPNode;
+class BspObject;
+
+
+
+
+class Polygon : public virtual SystemIO {
+
+ friend class PolygonListRep;
+
+ void Error() const;
+
+
+ enum {
+ POLY_IN_FRONT_SUBSPACE,
+ POLY_IN_BACK_SUBSPACE,
+ POLY_STRADDLES_SPLITTER,
+ POLY_IN_SAME_PLANE,
+ };
+
+
+ enum {
+ FRONT_SUBSPACE = 1,
+ BACK_SUBSPACE = -1
+ };
+
+public:
+
+
+ enum {
+ SPLITTERCRIT_FIRST_POLY = 0x0000,
+ SPLITTERCRIT_SAMPLE_FIRST_N = 0x0101,
+ SPLITTERCRIT_SAMPLE_ALL = 0x0002,
+ SPLITTERCRIT_RANDOM_SAMPLE = 0x0103,
+ SPLITTERCRITMASK_SAMPLESIZ = 0x0100,
+ };
+
+
+ enum {
+ MESSAGE_SPLITTING_POLYGON = 0x0001,
+ MESSAGE_STARTVERTEX_IN_SPLITTER_PLANE = 0x0002,
+ MESSAGE_VERTEX_IN_SPLITTER_PLANE = 0x0004,
+ MESSAGE_NEW_SPLITVERTEX = 0x0008,
+ MESSAGE_REUSING_SPLITVERTEX = 0x0010,
+ MESSAGE_TRACEVERTEX_INSERTED = 0x0020,
+ MESSAGE_SPLITTING_QUADRILATERAL = 0x0040,
+ MESSAGE_INVOCATION = 0x0080,
+ MESSAGE_CHECKING_POLYGON_PLANES = 0x0100,
+ MESSAGEMASK_DISPLAY_ALL = 0xffff
+ };
+
+public:
+ Polygon( BspObject *bobj, int pno = 0, int fno = 0, Polygon *next = 0 , int num = 1 );
+ ~Polygon() { delete vertindxs; delete nextpolygon; }
+
+ Polygon* NewPolygon();
+ Polygon* InsertPolygon( Polygon *poly );
+ Polygon* DeleteHead();
+ Polygon* FindPolygon( int id );
+ int SumVertexNumsEntireList();
+
+ void PrependNewVIndx( int indx );
+ void AppendNewVIndx( int indx = -1 );
+ void AppendVIndx( VIndx *vindx );
+ VIndx* UnlinkLastVIndx();
+
+ void CalcPlaneNormals();
+ void CheckEdges();
+ Polygon* CheckPlanesAndMappings();
+
+
+ void CalcBoundingBox( BoundingBox* &boundingbox );
+
+
+ int CheckIntersection( Polygon *testpoly );
+
+ int NormalDirectionSimilar( Polygon *testpoly );
+
+ void SplitPolygon( Polygon *poly, Polygon* &frontsubspace, Polygon* &backsubspace );
+
+ BSPNode* PartitionSpace();
+
+
+ void CorrectBase( BspObject *newbaseobj, int vertexindxbase, int faceidbase, int polygonidbase );
+ void CorrectBaseByTable( BspObject *newbaseobj, int *vtxindxmap, int faceidbase, int polygonidbase );
+
+ int getId() const { return polygonno; }
+ void setId( int pno ) { polygonno = pno; }
+
+ int getFaceId() const { return faceno; }
+ void setFaceId( int fno ) { faceno = fno; }
+
+ int getNumPolygons() const { return numpolygons; }
+ void setNumPolygons( int len ) { numpolygons = len; }
+
+ Polygon* getNext() const { return nextpolygon; }
+ void setNext( Polygon *next ) { nextpolygon = next; }
+
+ int getNumVertices() const { return numvertindxs; }
+
+ VIndx* getVList() const { return vertindxs; }
+ BspObject* getBaseObject() const { return baseobject; }
+
+ VertexChunk& getVertexList();
+ FaceChunk& getFaceList();
+
+ int HasArea() const;
+
+ int getFirstVertexIndx() const;
+ int getSecondVertexIndx() const;
+ int getThirdVertexIndx() const;
+
+ Vertex3 getFirstVertex() const;
+ Vertex3 getSecondVertex() const;
+ Vertex3 getThirdVertex() const;
+
+ Plane getPlane() const { return ((Polygon *const)this)->getFaceList()[ faceno ].getPlane(); }
+ Vector3 getPlaneNormal() const { return ((Polygon *const)this)->getFaceList()[ faceno ].getPlaneNormal(); }
+
+ void FillVertexIndexArray( dword *arr ) const;
+ void WriteVertexList( FILE *fp, int cr ) const;
+ void WritePolyList( FILE *fp ) const;
+
+ int CalcSplitterTestProbability();
+
+public:
+ static int getSplitterSelection() { return splitter_crit; }
+ static void setSplitterSelection( int criterion ) { splitter_crit = criterion; }
+
+ static int getSampleSize() { return sample_size; }
+ static void setSampleSize( int siz ) { sample_size = siz; }
+
+ static int getTriangulationFlag() { return triangulate_all; }
+ static void setTriangulationFlag( int flag ) { triangulate_all = flag; }
+
+ static int getNormalizeVectorsFlag() { return normalize_vectors; }
+ static void setNormalizeVectorsFlag( int flag ) { normalize_vectors = flag; }
+
+ static int getDisplayMessagesFlag() { return display_messages; }
+ static void setDisplayMessagesFlag( int flag ) { display_messages = flag; }
+
+ static void ResetCallCount() { partition_callcount = 0; }
+
+private:
+ static int splitter_crit;
+ static int sample_size;
+ static int triangulate_all;
+ static int normalize_vectors;
+ static int display_messages;
+ static int partition_callcount;
+ static int test_probability;
+ static char str_scratchpad[];
+
+private:
+ int polygonno;
+ int faceno;
+ int numpolygons;
+ int numvertindxs;
+ VIndx* vertindxs;
+ VIndx* vindxinsertpos;
+ BspObject* baseobject;
+ Polygon* nextpolygon;
+};
+
+
+inline int Polygon::HasArea() const
+{
+
+
+ return ( vertindxs && vertindxs->getNext() && vertindxs->getNext()->getNext() );
+}
+
+
+inline int Polygon::getFirstVertexIndx() const
+{
+
+ if ( vertindxs == 0 )
+ Error();
+ ;
+ return vertindxs->getIndx();
+}
+inline Vertex3 Polygon::getFirstVertex() const
+{
+
+ if ( vertindxs == 0 )
+ Error();
+ ;
+ return ((Polygon *const)this)->getVertexList()[ vertindxs->getIndx() ];
+}
+
+
+inline int Polygon::getSecondVertexIndx() const
+{
+
+ if ( ( vertindxs == 0 ) || ( vertindxs->getNext() == 0 ) )
+ Error();
+ ;
+ return vertindxs->getNext()->getIndx();
+}
+inline Vertex3 Polygon::getSecondVertex() const
+{
+
+ if ( ( vertindxs == 0 ) || ( vertindxs->getNext() == 0 ) )
+ Error();
+ ;
+ return ((Polygon *const)this)->getVertexList()[ vertindxs->getNext()->getIndx() ];
+}
+
+
+inline int Polygon::getThirdVertexIndx() const
+{
+
+ if ( ( vertindxs == 0 ) ||
+ ( vertindxs->getNext() == 0 ) ||
+ ( vertindxs->getNext()->getNext() == 0 ) )
+ Error();
+ ;
+ return vertindxs->getNext()->getNext()->getIndx();
+}
+inline Vertex3 Polygon::getThirdVertex() const
+{
+
+ if ( ( vertindxs == 0 ) ||
+ ( vertindxs->getNext() == 0 ) ||
+ ( vertindxs->getNext()->getNext() == 0 ) )
+ Error();
+ ;
+ return ((Polygon *const)this)->getVertexList()[ vertindxs->getNext()->getNext()->getIndx() ];
+}
+
+
+}
+
+
+
+
+# 13 "../BspLib/PolygonList.h" 2
+
+
+
+
+namespace BspLib {
+
+
+class BSPNode;
+class BspObject;
+
+
+
+
+class PolygonListRep : public virtual SystemIO {
+
+ friend class PolygonList;
+
+
+ enum {
+ E_NEWVINDX,
+ E_APPENDVINDX,
+ E_GETNUMVERTXS
+ };
+
+
+ void Error( int err ) const;
+
+private:
+ PolygonListRep( BspObject *bobj );
+ ~PolygonListRep() { delete list; }
+
+ void MergeLists( PolygonListRep *mergelist );
+
+ Polygon* InitList( Polygon *listhead );
+
+
+ void InvalidateList() { list = 0 ; numpolygons = 0; }
+
+ Polygon* FetchHead() { return list; }
+ Polygon* UnlinkHead();
+ Polygon* DeleteHead();
+ Polygon* FindPolygon( int id ) { return list ? list->FindPolygon( id ) : 0 ; }
+
+ Polygon* NewPolygon();
+ Polygon* InsertPolygon( Polygon *poly );
+
+ void PrependNewVIndx( int indx = -1 ) { if ( list == 0 ) Error( E_NEWVINDX ); list->PrependNewVIndx( indx ); }
+ void AppendNewVIndx( int indx = -1 ) { if ( list == 0 ) Error( E_NEWVINDX ); list->AppendNewVIndx( indx ); }
+ void AppendVIndx( VIndx *vindx ) { if ( list == 0 ) Error( E_APPENDVINDX ); list->AppendVIndx( vindx ); }
+ Polygon* CalcPlaneNormals();
+ Polygon* CheckPolygonPlanes();
+ BSPNode* PartitionSpace();
+
+ void WritePolyList( FILE *fp, int no ) const;
+
+ int getNumElements() const { return numpolygons; }
+ int getNumVertices() const { if( list == 0 ) Error( E_GETNUMVERTXS ); return list->getNumVertices(); }
+
+private:
+ int ref_count;
+ int numpolygons;
+ BspObject* baseobject;
+ Polygon* list;
+};
+
+
+inline PolygonListRep::PolygonListRep( BspObject *bobj ) : ref_count( 0 )
+{
+ baseobject = bobj;
+ list = 0 ;
+ numpolygons = 0;
+}
+
+
+
+
+class PolygonList {
+
+public:
+ PolygonList( BspObject *bobj ) { rep = new PolygonListRep( bobj ); rep->ref_count = 1; }
+ ~PolygonList() { if ( --rep->ref_count == 0 ) delete rep; }
+
+ PolygonList( const PolygonList& copyobj );
+ PolygonList& operator =( const PolygonList& copyobj );
+
+ void MergeLists( PolygonList *mergelist ) { if ( mergelist ) rep->MergeLists( mergelist->rep ); }
+
+ Polygon* InitList( Polygon *listhead ) { return rep->InitList( listhead ); }
+ void InvalidateList() { rep->InvalidateList(); }
+
+ Polygon* FetchHead() { return rep->FetchHead(); }
+ Polygon* UnlinkHead() { return rep->UnlinkHead(); }
+ Polygon* DeleteHead() { return rep->DeleteHead(); }
+ Polygon* FindPolygon( int id ) { return rep->FindPolygon( id ); }
+
+ Polygon* NewPolygon() { return rep->NewPolygon(); }
+ Polygon* InsertPolygon( Polygon *poly ) { return rep->InsertPolygon( poly ); }
+
+ void PrependNewVIndx( int indx = -1 ) { rep->PrependNewVIndx( indx ); }
+ void AppendNewVIndx( int indx = -1 ) { rep->AppendNewVIndx( indx ); }
+ void AppendVIndx( VIndx *vindx ) { rep->AppendVIndx( vindx ); }
+ Polygon* CalcPlaneNormals() { return rep->CalcPlaneNormals(); }
+ Polygon* CheckPolygonPlanes() { return rep->CheckPolygonPlanes(); }
+ BSPNode* PartitionSpace() { return rep->PartitionSpace(); }
+
+ void WritePolyList( FILE *fp, int no ) const { rep->WritePolyList( fp, no ); }
+
+ int getNumElements() const { return rep->getNumElements(); }
+ int getNumVertices() const { return rep->getNumVertices(); }
+
+private:
+ PolygonListRep* rep;
+};
+
+
+inline PolygonList::PolygonList( const PolygonList& copyobj )
+{
+ rep = copyobj.rep;
+ rep->ref_count++;
+}
+
+
+inline PolygonList& PolygonList::operator =( const PolygonList& copyobj )
+{
+ if ( &copyobj != this ) {
+
+ if ( --rep->ref_count == 0 ) {
+ delete rep;
+ }
+ rep = copyobj.rep;
+ rep->ref_count++;
+ }
+ return *this;
+}
+
+
+}
+
+
+
+
+# 17 "../BspLib/BspObject.h" 2
+
+# 1 "../BspLib/BSPTree.h" 1
+
+
+
+
+
+
+
+
+
+
+
+
+# 1 "../BspLib/BspNode.h" 1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+namespace BspLib {
+
+
+class BoundingBox;
+class BspObject;
+
+
+
+
+class BSPNode {
+
+public:
+
+
+ enum {
+ OUTPUT_OLD_STYLE,
+ OUTPUT_KEY_VALUE_STYLE
+ };
+
+public:
+ BSPNode( BSPNode *front = 0 , BSPNode *back = 0 ,
+ Polygon *poly = 0 , Polygon *backpoly = 0 ,
+ Plane *sep = 0 , BoundingBox *box = 0 , int num = -1 );
+ ~BSPNode();
+
+public:
+ void NumberBSPNodes( int& curno );
+ void SumVertexNums( int& vtxnum );
+ void CorrectPolygonBases( BspObject *newbaseobj, int vertexindxbase, int faceidbase, int polygonidbase );
+ void CorrectPolygonBasesByTable( BspObject *newbaseobj, int *vtxindxmap, int faceidbase, int polygonidbase );
+ void WriteBSPTree( FILE *fp );
+ void CheckEdges();
+ void FetchFacePolygons( int facno, PolygonList& facepolylist );
+ Polygon* FetchBSPPolygon( int polyno );
+ void CalcBoundingBoxes();
+ void CalcSeparatorPlanes();
+
+ int getNodeNumber() const { return nodenumber; }
+ Polygon* getPolygon() { return polygon; }
+ Polygon* getBackPolygon() { return backpolygon; }
+ BSPNode* getFrontSubtree() const { return frontsubtree; }
+ BSPNode* getBackSubtree() const { return backsubtree; }
+
+ Plane* getSeparatorPlane() { return separatorplane; }
+ void setSeparatorPlane( Plane *sep ) { separatorplane = sep; }
+
+ BoundingBox*getBoundingBox() { return boundingbox; }
+ void setBoundingBox( BoundingBox *box ) { boundingbox = box; }
+
+private:
+ void GrowBoundingBox( BSPNode *othernode );
+
+public:
+ static int getOutputFormat() { return outputformat; }
+ static void setOutputFormat( int format ) { outputformat = format; }
+
+private:
+ static int outputformat;
+
+private:
+ int nodenumber;
+ Polygon* polygon;
+ Polygon* backpolygon;
+ Plane* separatorplane;
+ BoundingBox*boundingbox;
+ BSPNode* frontsubtree;
+ BSPNode* backsubtree;
+};
+
+
+
+
+class BSPNodeFlat {
+
+public:
+ BSPNodeFlat( int front = 0, int back = 0,
+ Polygon *poly = 0 , int clist = 0, int blist = 0,
+ Plane *sep = 0 , BoundingBox *box = 0 , int num = -1 );
+ ~BSPNodeFlat() { }
+
+public:
+ void InitNode( int front, int back, Polygon *poly, int clist, int blist,
+ Plane *sep = 0 , BoundingBox *box = 0 , int num = -1 );
+
+ void ApplyScaleFactor( double sfac );
+
+ int getNodeNumber() const { return nodenumber; }
+ Polygon* getPolygon() { return polygon; }
+ int getContainedList() const { return containedlistindx; }
+ int getBackList() const { return backlistindx; }
+ int getFrontSubTree() const { return frontsubtreeindx; }
+ int getBackSubTree() const { return backsubtreeindx; }
+
+ Plane* getSeparatorPlane() { return separatorplane; }
+ void setSeparatorPlane( Plane *sep ) { separatorplane = sep; }
+
+ BoundingBox*getBoundingBox() { return boundingbox; }
+ void setBoundingBox( BoundingBox *box ) { boundingbox = box; }
+
+private:
+ int nodenumber;
+ Polygon* polygon;
+ Plane* separatorplane;
+ BoundingBox*boundingbox;
+ int containedlistindx;
+ int backlistindx;
+ int frontsubtreeindx;
+ int backsubtreeindx;
+};
+
+
+}
+
+
+
+
+# 13 "../BspLib/BSPTree.h" 2
+
+
+
+namespace BspLib {
+
+
+
+
+class BSPTreeRep {
+
+ friend class BSPTree;
+
+private:
+ BSPTreeRep() : ref_count( 0 ) { root = 0 ; }
+ ~BSPTreeRep() { delete root; }
+
+ BSPNode* InitTree( BSPNode *rootnode );
+ BSPNode* getRoot() { return root; }
+
+ void InvalidateTree();
+
+ int TreeEmpty() const { return ( root == 0 ); }
+
+private:
+ int ref_count;
+ BSPNode* root;
+};
+
+
+inline BSPNode *BSPTreeRep::InitTree( BSPNode *rootnode )
+{
+ delete root;
+ return ( root = rootnode );
+}
+
+
+inline void BSPTreeRep::InvalidateTree()
+{
+ root = 0 ;
+}
+
+
+
+
+class BSPTree {
+
+public:
+ BSPTree() { rep = new BSPTreeRep; rep->ref_count = 1; }
+ ~BSPTree() { if ( --rep->ref_count == 0 ) delete rep; }
+
+ BSPTree( const BSPTree& copyobj );
+ BSPTree& operator =( const BSPTree& copyobj );
+
+
+ BSPNode* operator->() { return rep->getRoot(); }
+
+ BSPNode* InitTree( BSPNode *rootnode ) { return rep->InitTree( rootnode ); }
+ BSPNode* getRoot() { return rep->getRoot(); }
+
+ void InvalidateTree() { rep->InvalidateTree(); }
+
+ int TreeEmpty() const { return rep->TreeEmpty(); }
+
+private:
+ BSPTreeRep* rep;
+};
+
+
+inline BSPTree::BSPTree( const BSPTree& copyobj )
+{
+ rep = copyobj.rep;
+ rep->ref_count++;
+}
+
+
+inline BSPTree& BSPTree::operator =( const BSPTree& copyobj )
+{
+ if ( &copyobj != this ) {
+ if ( --rep->ref_count == 0 ) {
+ delete rep;
+ }
+ rep = copyobj.rep;
+ rep->ref_count++;
+ }
+ return *this;
+}
+
+
+
+
+class BSPTreeFlatRep {
+
+ friend class BSPTreeFlat;
+
+private:
+ BSPTreeFlatRep() : ref_count( 0 ) { root = 0 ; numnodes = 0; nodestorage = 0; }
+ ~BSPTreeFlatRep() { delete[] root; }
+
+ BSPNodeFlat* AppendNode( int front, int back, Polygon *poly, int clist, int blist );
+ BSPNodeFlat* FetchNodePerId( int id );
+ BSPNode* BuildBSPTree( int nodenum );
+ BSPNodeFlat* getRoot() { return root; }
+
+ int TreeEmpty() const { return ( root == 0 ); }
+ int getNumNodes() const { return numnodes; }
+
+ void ApplyScaleFactor( double sfac );
+ void DestroyTree() { delete[] root; root = 0 ; numnodes = 0; nodestorage = 0; }
+
+private:
+ int ref_count;
+ int numnodes;
+ int nodestorage;
+ BSPNodeFlat* root;
+};
+
+
+
+
+class BSPTreeFlat {
+
+public:
+ BSPTreeFlat() { rep = new BSPTreeFlatRep; rep->ref_count = 1; }
+ ~BSPTreeFlat() { if ( --rep->ref_count == 0 ) delete rep; }
+
+ BSPTreeFlat( const BSPTreeFlat& copyobj );
+ BSPTreeFlat& operator =( const BSPTreeFlat& copyobj );
+
+ BSPNodeFlat* AppendNode( int front, int back, Polygon *poly, int clist, int blist )
+ { return rep->AppendNode( front, back, poly, clist, blist ); }
+ BSPNodeFlat* FetchNodePerId( int id ) { return rep->FetchNodePerId( id ); }
+ BSPNode* BuildBSPTree( int nodenum ) { return rep->BuildBSPTree( nodenum ); }
+ BSPNodeFlat* getRoot() { return rep->getRoot(); }
+
+ int TreeEmpty() const { return rep->TreeEmpty(); }
+ int getNumNodes() const { return rep->getNumNodes(); }
+
+ void ApplyScaleFactor( double sfac ) { rep->ApplyScaleFactor( sfac ); }
+ void DestroyTree() { rep->DestroyTree(); }
+
+private:
+ BSPTreeFlatRep* rep;
+};
+
+
+inline BSPTreeFlat::BSPTreeFlat( const BSPTreeFlat& copyobj )
+{
+ rep = copyobj.rep;
+ rep->ref_count++;
+}
+
+
+inline BSPTreeFlat& BSPTreeFlat::operator =( const BSPTreeFlat& copyobj )
+{
+ if ( &copyobj != this ) {
+ if ( --rep->ref_count == 0 ) {
+ delete rep;
+ }
+ rep = copyobj.rep;
+ rep->ref_count++;
+ }
+ return *this;
+}
+
+
+}
+
+
+
+
+# 18 "../BspLib/BspObject.h" 2
+
+
+# 1 "../BspLib/Transform3.h" 1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+namespace BspLib {
+
+
+
+
+class Transform3 {
+
+ friend Transform3 operator *( const Transform3& trafo1, const Transform3& trafo2 );
+
+public:
+ Transform3();
+ Transform3( const float trafo[4][4] );
+ Transform3( const double trafo[4][4] );
+ ~Transform3() { }
+
+
+ Vector3 TransformVector3( const Vector3& vec ) const;
+
+
+ Transform3& Concat( const Transform3& cattrafo );
+ Transform3& ConcatR( const Transform3& cattrafo );
+
+
+ Transform3& LoadIdentity();
+ Transform3& LoadRotation( double angle, double x, double y, double z );
+ Transform3& LoadScale( double x, double y, double z );
+ Transform3& LoadTranslation( double x, double y, double z );
+
+
+ Transform3& Rotate( double angle, double x, double y, double z );
+ Transform3& Scale( double x, double y, double z );
+ Transform3& Translate( double x, double y, double z );
+
+
+ Transform3& RotateR( double angle, double x, double y, double z );
+ Transform3& ScaleR( double x, double y, double z );
+ Transform3& TranslateR( double x, double y, double z );
+
+
+ Vector3 FetchTranslation() const;
+ Vector3 ExtractTranslation();
+
+private:
+
+ double m_matrix[4][4];
+};
+
+
+inline Transform3& Transform3::LoadIdentity()
+{
+ memset( m_matrix, 0, sizeof( m_matrix ) );
+
+ m_matrix[ 0 ][ 0 ] = 1.0;
+ m_matrix[ 1 ][ 1 ] = 1.0;
+ m_matrix[ 2 ][ 2 ] = 1.0;
+ m_matrix[ 3 ][ 3 ] = 1.0;
+
+ return *this;
+}
+
+
+inline Transform3::Transform3()
+{
+
+}
+
+
+inline Transform3::Transform3( const double trafo[4][4] )
+{
+
+
+
+ memcpy( m_matrix, trafo, sizeof( m_matrix ) );
+}
+
+
+inline Transform3::Transform3( const float trafo[4][4] )
+{
+
+
+
+ for ( int i = 0; i < 16; i++ )
+ ((double *)m_matrix)[ i ] = (double) ((float *)trafo)[ i ];
+}
+
+
+}
+
+
+
+
+# 20 "../BspLib/BspObject.h" 2
+
+
+
+
+namespace BspLib {
+
+
+class BoundingBox;
+
+
+
+
+class BspObjectInfo {
+
+ friend class BspObject;
+
+private:
+ BspObjectInfo();
+ ~BspObjectInfo() { }
+
+public:
+ int getNumVertices() const { return numvertices; }
+ int getNumPolygons() const { return numpolygons; }
+ int getNumFaces() const { return numfaces; }
+
+ int getInputVertices() const { return numvertices_in; }
+ int getInputPolygons() const { return numpolygons_in; }
+ int getInputFaces() const { return numfaces_in; }
+
+ int getBspPolygons() const { return numbsppolygons; }
+ int getPreBspPolygons() const { return numpolygons_before_bsp; }
+
+ int getNumTextures() const { return numtextures; }
+ int getNumMappings() const { return numcorrespondences; }
+ int getNumNormals() const { return numnormals; }
+ int getNumTexturedFaces() const { return numtexmappedfaces; }
+
+ int getNumTraceVertices() const { return numtracevertices; }
+ int getNumMultiVertices() const { return nummultvertices; }
+ int getNumSplitQuads() const { return numsplitquadrilaterals; }
+
+protected:
+ int numvertices;
+ int numpolygons;
+ int numfaces;
+ int numtextures;
+ int numcorrespondences;
+
+ int numnormals;
+ int numtexmappedfaces;
+
+ int numvertices_in;
+ int numpolygons_in;
+ int numfaces_in;
+
+ int numbsppolygons;
+ int numpolygons_before_bsp;
+
+ int numtracevertices;
+ int nummultvertices;
+ int numsplitquadrilaterals;
+};
+
+
+
+
+class BspObject : public BspObjectInfo, public virtual SystemIO {
+
+ friend class BoundingBox;
+ friend class BspObjectListRep;
+ friend class Face;
+ friend class ObjectBSPNode;
+ friend class Polygon;
+
+ friend class VrmlFile;
+
+public:
+ BspObject();
+ ~BspObject() { delete objectname; delete next; }
+
+ BspObject( const BspObject& copyobj );
+ BspObject& operator =( const BspObject& copyobj );
+
+
+
+ void MergeObjects( BspObject *mergeobj );
+
+ void CollapseObjectList();
+
+ BoundingBox* BuildBoundingBoxList();
+
+ BSPNode* BuildBSPTree();
+ BSPNode* BuildBSPTreeFromFlat();
+
+ int BspTreeAvailable();
+ int BSPTreeAvailable();
+ int BSPTreeFlatAvailable();
+
+
+ void CalcBoundingBoxes();
+ void CalcSeparatorPlanes();
+ void CheckEdges();
+ void CheckPolygonPlanes();
+ void CheckVertices( int verbose );
+ void CalcPlaneNormals();
+ void CheckParsedData();
+ void UpdateAttributeNumbers();
+
+ int ConvertColorIndexesToRGB( char *palette, int changemode );
+
+
+ void CalcBoundingBox( Vertex3& minvertex, Vertex3& maxvertex );
+
+
+ void DisplayStatistics();
+
+
+
+
+ virtual int WriteVertexList( FileAccess& fp ) { return 0 ; }
+ virtual int WritePolygonList( FileAccess& fp ) { return 0 ; }
+ virtual int WriteFaceList( FileAccess& fp ) { return 0 ; }
+ virtual int WriteFaceProperties( FileAccess& fp ) { return 0 ; }
+ virtual int WriteTextureList( FileAccess& fp ) { return 0 ; }
+ virtual int WriteMappingList( FileAccess& fp ) { return 0 ; }
+ virtual int WriteNormals( FileAccess& fp ) { return 0 ; }
+ virtual int WriteBSPTree( FileAccess& fp ) { return 0 ; }
+
+
+ VertexChunk& getVertexList() { return vertexlist; }
+ PolygonList& getPolygonList() { return polygonlist; }
+ FaceChunk& getFaceList() { return facelist; }
+ TextureChunk& getTextureList() { return texturelist; }
+ MappingChunk& getMappingList() { return mappinglist; }
+ BSPTree& getBSPTree() { return bsptree; }
+ BSPTreeFlat& getBSPTreeFlat() { return bsptreeflat; }
+
+
+ char* getObjectName() const { return objectname; }
+ void setObjectName( char *name );
+
+
+ Vertex3 getCenterInWorldSpace() const { return objecttrafo.FetchTranslation(); }
+ Transform3 getObjectTransformation() const { return objecttrafo; }
+ void setObjectTransformation( const Transform3& ot ) { objecttrafo = ot; }
+
+
+ void ApplyScale( double scalefac );
+
+
+ void ApplyCenter();
+
+
+ void ApplyTransformation();
+
+
+ BspObject* getNext() const { return next; }
+
+private:
+ void InconsistencyError( const char *err );
+
+public:
+ static int getEliminateDoubletsOnMergeFlag() { return check_vertex_doublets_on_merge; }
+ static void setEliminateDoubletsOnMergeFlag( int flag ) { check_vertex_doublets_on_merge = flag; }
+
+private:
+ static int check_vertex_doublets_on_merge;
+
+protected:
+
+ VertexChunk vertexlist;
+ PolygonList polygonlist;
+ FaceChunk facelist;
+ TextureChunk texturelist;
+ MappingChunk mappinglist;
+ BSPTree bsptree;
+ BSPTreeFlat bsptreeflat;
+ Transform3 objecttrafo;
+
+
+ char* objectname;
+
+
+ BspObject* next;
+};
+
+
+inline BspObject::BspObject( const BspObject& copyobj ) :
+ BspObjectInfo( copyobj ),
+ vertexlist( copyobj.vertexlist ),
+ polygonlist( copyobj.polygonlist ),
+ facelist( copyobj.facelist ),
+ texturelist( copyobj.texturelist ),
+ mappinglist( copyobj.mappinglist ),
+ bsptree( copyobj.bsptree ),
+ bsptreeflat( copyobj.bsptreeflat ),
+ objecttrafo( copyobj.objecttrafo )
+{
+
+ objectname = 0 ;
+ setObjectName( copyobj.objectname );
+
+
+ next = 0 ;
+}
+
+
+inline BspObject& BspObject::operator =( const BspObject& copyobj )
+{
+ if ( &copyobj != this ) {
+
+
+ *(BspObjectInfo *)this = copyobj;
+
+
+ vertexlist = copyobj.vertexlist;
+ polygonlist = copyobj.polygonlist;
+ facelist = copyobj.facelist;
+ texturelist = copyobj.texturelist;
+ mappinglist = copyobj.mappinglist;
+ bsptree = copyobj.bsptree;
+ bsptreeflat = copyobj.bsptreeflat;
+ objecttrafo = copyobj.objecttrafo;
+
+
+ setObjectName( copyobj.objectname );
+
+
+ next = 0 ;
+ }
+ return *this;
+}
+
+
+}
+
+
+
+
+# 13 "../BspLib/BoundingBox.h" 2
+
+
+
+
+namespace BspLib {
+
+
+
+
+class BoundingBox {
+
+ friend class ObjectBSPNode;
+
+public:
+ BoundingBox() { containedobject = 0 ; nextbox = 0 ; }
+ BoundingBox( BspObject *cobj, BoundingBox *next = 0 );
+ BoundingBox( const Vertex3& minvert, const Vertex3& maxvert, BoundingBox *next = 0 );
+ ~BoundingBox() { delete nextbox; }
+
+ void ApplyScaleFactor( double sfac );
+ void GrowBoundingBox( BoundingBox *otherbox );
+ void BoundingBoxListUnion( BoundingBox& unionbox );
+ ObjectBSPNode* PartitionSpace();
+
+ Vertex3 getMinVertex() const { return minvertex; }
+ Vertex3 getMaxVertex() const { return maxvertex; }
+ BspObject* getContainedObject() const { return containedobject; }
+ BoundingBox* getNext() const { return nextbox; }
+
+private:
+ Vertex3 minvertex;
+ Vertex3 maxvertex;
+ BspObject* containedobject;
+ BoundingBox* nextbox;
+};
+
+
+inline BoundingBox::BoundingBox( BspObject *cobj, BoundingBox *next )
+{
+ if ( ( containedobject = cobj ) != 0 ) {
+ cobj->CalcBoundingBox( minvertex, maxvertex );
+ }
+ nextbox = next;
+}
+
+
+inline BoundingBox::BoundingBox( const Vertex3& minvert, const Vertex3& maxvert, BoundingBox *next )
+{
+ minvertex = minvert;
+ maxvertex = maxvert;
+ containedobject = 0 ;
+ nextbox = next;
+}
+
+
+}
+
+
+
+
+# 13 "../BspLib/VrmlFile.h" 2
+
+# 1 "../BspLib/InputData3D.h" 1
+
+
+
+
+
+
+
+
+
+
+
+
+# 1 "../BspLib/BspObjectList.h" 1
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 1 "../BspLib/ObjectBSPTree.h" 1
+
+
+
+
+
+
+
+
+
+
+
+
+# 1 "../BspLib/ObjectBSPNode.h" 1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+namespace BspLib {
+
+
+
+
+class ObjectBSPNode {
+
+public:
+ ObjectBSPNode( ObjectBSPNode *front = 0 , ObjectBSPNode *back = 0 , Plane *sep = 0 , BoundingBox *bbox = 0 , int id = -1 );
+ ~ObjectBSPNode() { delete separatorplane; delete boundingbox; delete frontsubtree; delete backsubtree; }
+
+ void NumberBSPNodes( int& curno );
+ void WriteBSPTree( FILE *fp ) const;
+
+ BspObject* CreateObjectList();
+ BspObject* CreateMergedBSPTree();
+
+ void DeleteNodeBspObjects();
+
+ int getNodeNumber() const { return nodenumber; }
+ Plane* getSeparatorPlane() const { return separatorplane; }
+ BoundingBox* getBoundingBox() const { return boundingbox; }
+ ObjectBSPNode* getFrontSubtree() const { return frontsubtree; }
+ ObjectBSPNode* getBackSubtree() const { return backsubtree; }
+
+private:
+ void MergeTreeNodeObjects( BspObject *newobject );
+ BSPNode* CreateUnifiedBSPTree();
+
+private:
+ int nodenumber;
+ Plane* separatorplane;
+ BoundingBox* boundingbox;
+ ObjectBSPNode* frontsubtree;
+ ObjectBSPNode* backsubtree;
+};
+
+
+inline ObjectBSPNode::ObjectBSPNode( ObjectBSPNode *front, ObjectBSPNode *back, Plane *sep, BoundingBox *bbox, int id )
+{
+ frontsubtree = front;
+ backsubtree = back;
+ separatorplane = sep;
+ boundingbox = bbox;
+ nodenumber = id;
+}
+
+
+}
+
+
+
+
+# 13 "../BspLib/ObjectBSPTree.h" 2
+
+
+
+namespace BspLib {
+
+
+
+
+class ObjectBSPTreeRep {
+
+ friend class ObjectBSPTree;
+
+private:
+ ObjectBSPTreeRep() : ref_count( 0 ) { root = 0 ; }
+ ~ObjectBSPTreeRep() { delete root; }
+
+ void KillTree() { delete root; root = 0 ; }
+ ObjectBSPNode* InitTree( ObjectBSPNode *rootnode );
+ ObjectBSPNode* getRoot() { return root; }
+
+ int TreeEmpty() const { return ( root == 0 ); }
+
+private:
+ int ref_count;
+ ObjectBSPNode* root;
+};
+
+
+inline ObjectBSPNode *ObjectBSPTreeRep::InitTree( ObjectBSPNode *rootnode )
+{
+ delete root;
+ return ( root = rootnode );
+}
+
+
+
+
+class ObjectBSPTree {
+
+public:
+ ObjectBSPTree() { rep = new ObjectBSPTreeRep; rep->ref_count = 1; }
+ ~ObjectBSPTree() { if ( --rep->ref_count == 0 ) delete rep; }
+
+ ObjectBSPTree( const ObjectBSPTree& copyobj );
+ ObjectBSPTree& operator =( const ObjectBSPTree& copyobj );
+
+
+ ObjectBSPNode* operator->() { return rep->getRoot(); }
+
+ void KillTree() { rep->KillTree(); }
+ ObjectBSPNode* InitTree( ObjectBSPNode *rootnode ) { return rep->InitTree( rootnode ); }
+ ObjectBSPNode* getRoot() { return rep->getRoot(); }
+
+ int TreeEmpty() const { return rep->TreeEmpty(); }
+
+private:
+ ObjectBSPTreeRep* rep;
+};
+
+
+inline ObjectBSPTree::ObjectBSPTree( const ObjectBSPTree& copyobj )
+{
+ rep = copyobj.rep;
+ rep->ref_count++;
+}
+
+
+inline ObjectBSPTree& ObjectBSPTree::operator =( const ObjectBSPTree& copyobj )
+{
+ if ( &copyobj != this ) {
+ if ( --rep->ref_count == 0 ) {
+ delete rep;
+ }
+ rep = copyobj.rep;
+ rep->ref_count++;
+ }
+ return *this;
+}
+
+
+}
+
+
+
+
+# 14 "../BspLib/BspObjectList.h" 2
+
+
+
+namespace BspLib {
+
+
+
+
+class BspObjectListRep {
+
+ friend class BspObjectList;
+
+public:
+ BspObjectListRep() : ref_count( 0 ) { list = 0 ; }
+ ~BspObjectListRep() { delete list; }
+
+ BspObject* CreateNewObject();
+ BspObject* InsertObject( BspObject *obj );
+
+ BoundingBox* BuildBoundingBoxList();
+
+ int CountListObjects();
+
+ int PrepareObjectBSPTree( ObjectBSPTree& objbsptree );
+ int MergeObjectBSPTree( ObjectBSPTree& objbsptree );
+
+ int CollapseObjectList();
+
+ int ProcessObjects( int flags );
+
+ int BspTreeAvailable() { return list ? list->BspTreeAvailable() : 0 ; }
+ int BSPTreeAvailable() { return list ? list->BSPTreeAvailable() : 0 ; }
+ int BSPTreeFlatAvailable() { return list ? list->BSPTreeFlatAvailable() : 0 ; }
+
+ BspObject* getListHead() const { return list; }
+
+private:
+ int ref_count;
+ BspObject* list;
+};
+
+
+
+
+class BspObjectList {
+
+public:
+
+
+ enum {
+ CHECK_PLANES = 0x0001,
+ BUILD_BSP = 0x0002,
+ CHECK_VERTICES = 0x0004,
+ CHECK_EDGES = 0x0008,
+ BUILD_BSP_WITH_CHECKS = 0x000F,
+ DISPLAY_STATS = 0x0010,
+ BUILD_FROM_FLAT = 0x0020,
+ MERGE_VERTICES = 0x0040,
+ CULL_NULL_EDGES = 0x0080,
+ ELIMINATE_T_VERTICES = 0x0100,
+ MERGE_FACES = 0x0200,
+ CALC_PLANE_NORMALS = 0x0400,
+ CALC_BOUNDING_BOXES = 0x0800,
+ CALC_SEPARATOR_PLANES = 0x1000,
+ APPLY_TRANSFORMATIONS = 0x2000,
+ };
+
+public:
+ BspObjectList() { rep = new BspObjectListRep(); rep->ref_count = 1; }
+ ~BspObjectList() { if ( --rep->ref_count == 0 ) delete rep; }
+
+ BspObjectList( const BspObjectList& copyobj );
+ BspObjectList& operator =( const BspObjectList& copyobj );
+
+ BspObject* CreateNewObject() { return rep->CreateNewObject(); }
+ BspObject* InsertObject( BspObject *obj ) { return rep->InsertObject( obj ); }
+
+
+
+ BoundingBox* BuildBoundingBoxList() { return rep->BuildBoundingBoxList(); }
+
+ int CountListObjects() { return rep->CountListObjects(); }
+
+ int PrepareObjectBSPTree( ObjectBSPTree& objbsptree ) { return rep->PrepareObjectBSPTree( objbsptree ); }
+ int MergeObjectBSPTree( ObjectBSPTree& objbsptree ) { return rep->MergeObjectBSPTree( objbsptree ); }
+
+ int CollapseObjectList() { return rep->CollapseObjectList(); }
+
+
+ int ProcessObjects( int flags ) { return rep->ProcessObjects( flags ); }
+
+
+ int BspTreeAvailable() { return rep->BspTreeAvailable(); }
+
+ int BSPTreeAvailable() { return rep->BSPTreeAvailable(); }
+
+ int BSPTreeFlatAvailable() { return rep->BSPTreeFlatAvailable(); }
+
+
+
+
+
+
+
+
+ BspObject* getListHead() { return rep->getListHead(); }
+
+private:
+ BspObjectListRep *rep;
+};
+
+
+inline BspObjectList::BspObjectList( const BspObjectList& copyobj )
+{
+ rep = copyobj.rep;
+ rep->ref_count++;
+}
+
+
+inline BspObjectList& BspObjectList::operator =( const BspObjectList& copyobj )
+{
+ if ( &copyobj != this ) {
+
+ if ( --rep->ref_count == 0 ) {
+ delete rep;
+ }
+ rep = copyobj.rep;
+ rep->ref_count++;
+ }
+ return *this;
+}
+
+
+}
+
+
+
+
+# 13 "../BspLib/InputData3D.h" 2
+
+# 1 "../BspLib/IOData3D.h" 1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+namespace BspLib {
+
+
+
+
+class IOData3D : public virtual SystemIO {
+
+public:
+
+
+ enum {
+ DONT_CREATE_OBJECT = 0x0000,
+ UNKNOWN_FORMAT = 0x0001,
+ AOD_FORMAT_1_1 = 0x0002,
+ VRML_FORMAT_1_0 = 0x0003,
+ BSP_FORMAT_1_1 = 0x0004,
+ _3DX_FORMAT_1_0 = 0x0005,
+
+ };
+
+protected:
+
+
+ enum {
+ NO_CHECKS = 0x0000,
+ CHECK_FILENAME = 0x0001,
+ ALL_CHECKS = 0x0001
+ };
+
+public:
+ IOData3D( BspObjectList objectlist, const String& filename, int checkflags = ALL_CHECKS );
+ ~IOData3D() { }
+
+ BspObjectList getObjectList() const { return m_objectlist; }
+ String getFileName() const { return m_filename; }
+ void setFileName( const String& filename ) { m_filename = filename; }
+
+protected:
+ BspObjectList m_objectlist;
+ String m_filename;
+
+protected:
+
+ static const char AOD_SIGNATURE_1_1[];
+ static const char VRML_SIGNATURE_1_0[];
+ static const char BSP_SIGNATURE_1_1[];
+ static const char _3DX_SIGNATURE_1_0[];
+
+
+
+ static const int TEXTLINE_MAX;
+ static char line[];
+};
+
+
+}
+
+
+
+
+# 14 "../BspLib/InputData3D.h" 2
+
+
+
+namespace BspLib {
+
+
+
+
+class InputData3D : public IOData3D {
+
+public:
+
+ enum {
+ CONVERT_COLINDXS_TO_RGB = 0x0001,
+ FILTER_SCALE_FACTORS = 0x0002,
+ FILTER_AXES_DIR_SWITCH = 0x0004,
+ FILTER_AXES_EXCHANGE = 0x0008,
+ DO_AXES_EXCHANGE = FILTER_AXES_DIR_SWITCH | FILTER_AXES_EXCHANGE,
+ FORCE_MAXIMUM_EXTENT = 0x0010,
+ ALLOW_N_GONS = 0x0020,
+ };
+
+public:
+ InputData3D( BspObjectList objectlist, const char *filename, int format = UNKNOWN_FORMAT );
+ virtual ~InputData3D();
+
+ virtual int ParseObjectData();
+
+ int getObjectFormat() const { return m_objectformat; }
+ InputData3D* getRealObject() const { return m_data; }
+
+ int InputDataValid() const { return m_inputok; }
+
+
+ static int EnableRGBConversion( int enable );
+ static int EnableScaleFactors( int enable );
+ static int EnableAxesChange( int enable );
+ static int EnableMaximumExtent( int enable, double extent );
+ static int EnableAllowNGons( int enable );
+
+
+ static int getRGBConversionFlag() { return ( ( PostProcessingFlags & CONVERT_COLINDXS_TO_RGB ) == CONVERT_COLINDXS_TO_RGB ); }
+ static int getScaleFactorsFlag() { return ( ( PostProcessingFlags & FILTER_SCALE_FACTORS ) == FILTER_SCALE_FACTORS ); }
+ static int getAxesChangeFlag() { return ( ( PostProcessingFlags & DO_AXES_EXCHANGE ) == DO_AXES_EXCHANGE ); }
+ static int getEnforceExtentsFlag() { return ( ( PostProcessingFlags & FORCE_MAXIMUM_EXTENT ) == FORCE_MAXIMUM_EXTENT ); }
+ static double getMaxExtents() { return MaximumExtentToForce; }
+ static int getAllowNGonFlag() { return ( ( PostProcessingFlags & ALLOW_N_GONS ) == ALLOW_N_GONS ); }
+
+private:
+ int ReadFileSignature();
+
+protected:
+ static dword PostProcessingFlags;
+ static double MaximumExtentToForce;
+ static const char parser_err_str[];
+
+protected:
+ int m_objectformat;
+ int m_inputok;
+
+private:
+ InputData3D* m_data;
+};
+
+
+}
+
+
+
+
+# 14 "../BspLib/VrmlFile.h" 2
+
+
+
+namespace BspLib {
+
+
+class BspObjectList;
+
+
+
+class VrmlFile : public InputData3D {
+
+ friend class BRep;
+
+public:
+ VrmlFile( BspObjectList objectlist, const char *filename );
+ ~VrmlFile();
+
+ int ParseObjectData();
+ int WriteOutputFile();
+
+private:
+ void ApplySceneTransformations();
+ void EnforceSceneExtents( BoundingBox& unionbox );
+
+private:
+ BoundingBox* m_bboxlist;
+};
+
+
+}
+
+
+
+
+# 7 "QvState.h" 2
+
+
+
+class QvState {
+
+ public:
+
+
+ enum StackIndex {
+ CameraIndex,
+ Coordinate3Index,
+ LightIndex,
+ MaterialBindingIndex,
+ MaterialIndex,
+ NormalBindingIndex,
+ NormalIndex,
+ ShapeHintsIndex,
+ Texture2Index,
+ Texture2TransformationIndex,
+ TextureCoordinate2Index,
+ TransformationIndex,
+
+
+ NumStacks,
+ };
+
+ static const char *stackNames[NumStacks];
+
+ int depth;
+ QvElement **stacks;
+
+
+ BspLib ::VrmlFile *vrmlfile_base;
+ QvState( BspLib ::VrmlFile *base );
+
+
+ QvState();
+ ~QvState();
+
+
+ void addElement(StackIndex stackIndex, QvElement *elt);
+
+
+ QvElement * getTopElement(StackIndex stackIndex)
+ { return stacks[stackIndex]; }
+
+
+ void push();
+ void pop();
+
+
+ void popElement(StackIndex stackIndex);
+
+
+ void print();
+};
+
+
+# 3 "QvTraverse.cpp" 2
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+static int indent = 0;
+static void
+announce(const char *className)
+{
+ for (int i = 0; i < indent; i++)
+ printf("\t");
+ printf("Traversing a %s\n", className);
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+void
+QvGroup::traverse(QvState *state)
+{
+ announce("QvGroup" ) ;
+ indent++;
+ for (int i = 0; i < getNumChildren(); i++)
+ getChild(i)->traverse(state);
+ indent--;
+}
+
+void
+QvLevelOfDetail::traverse(QvState *state)
+{
+ announce("QvLevelOfDetail" ) ;
+ indent++;
+
+
+
+ if (getNumChildren() > 0)
+ getChild(0)->traverse(state);
+
+ indent--;
+}
+
+void
+QvSeparator::traverse(QvState *state)
+{
+ announce("QvSeparator" ) ;
+ state->push();
+ indent++;
+ for (int i = 0; i < getNumChildren(); i++)
+ getChild(i)->traverse(state);
+ indent--;
+ state->pop();
+}
+
+void
+QvSwitch::traverse(QvState *state)
+{
+ announce("QvSwitch" ) ;
+ indent++;
+
+ int which = whichChild.value;
+
+ if (which == (-1) )
+ ;
+
+ else if (which == (-3) )
+ for (int i = 0; i < getNumChildren(); i++)
+ getChild(i)->traverse(state);
+
+ else
+ if (which < getNumChildren())
+ getChild(which)->traverse(state);
+
+ indent--;
+}
+
+void
+QvTransformSeparator::traverse(QvState *state)
+{
+ announce("QvTransformSeparator" ) ;
+
+
+
+
+
+
+ QvElement *markerElt = new QvElement;
+ markerElt->data = this;
+ markerElt->type = QvElement::NoOpTransform;
+ state->addElement(QvState::TransformationIndex, markerElt);
+
+ indent++;
+ for (int i = 0; i < getNumChildren(); i++)
+ getChild(i)->traverse(state);
+ indent--;
+
+
+ while (state->getTopElement(QvState::TransformationIndex) != markerElt)
+ state->popElement(QvState::TransformationIndex);
+}
+
+
+
+
+
+
+
+
+# 139 "QvTraverse.cpp"
+
+
+# 150 "QvTraverse.cpp"
+
+
+void QvCoordinate3::traverse(QvState *state)
+{
+ announce("QvCoordinate3" ) ;
+ QvElement *elt = new QvElement;
+ elt->data = this;
+ state->addElement(QvState::Coordinate3Index, elt);
+
+
+
+
+
+
+
+
+ printf( "---------------------------------------\n" );
+}
+
+
+
+void QvMaterial ::traverse(QvState *state) { announce("QvMaterial" ) ; QvElement *elt = new QvElement; elt->data = this; state->addElement(QvState:: MaterialIndex , elt); }
+void QvMaterialBinding ::traverse(QvState *state) { announce("QvMaterialBinding" ) ; QvElement *elt = new QvElement; elt->data = this; state->addElement(QvState:: MaterialBindingIndex , elt); }
+void QvNormal ::traverse(QvState *state) { announce("QvNormal" ) ; QvElement *elt = new QvElement; elt->data = this; state->addElement(QvState:: NormalIndex , elt); }
+void QvNormalBinding ::traverse(QvState *state) { announce("QvNormalBinding" ) ; QvElement *elt = new QvElement; elt->data = this; state->addElement(QvState:: NormalBindingIndex , elt); }
+void QvShapeHints ::traverse(QvState *state) { announce("QvShapeHints" ) ; QvElement *elt = new QvElement; elt->data = this; state->addElement(QvState:: ShapeHintsIndex , elt); }
+void QvTextureCoordinate2 ::traverse(QvState *state) { announce("QvTextureCoordinate2" ) ; QvElement *elt = new QvElement; elt->data = this; state->addElement(QvState:: TextureCoordinate2Index , elt); }
+void QvTexture2 ::traverse(QvState *state) { announce("QvTexture2" ) ; QvElement *elt = new QvElement; elt->data = this; state->addElement(QvState:: Texture2Index , elt); }
+void QvTexture2Transform ::traverse(QvState *state) { announce("QvTexture2Transform" ) ; QvElement *elt = new QvElement; elt->data = this; state->addElement(QvState:: Texture2TransformationIndex , elt); }
+
+void QvDirectionalLight ::traverse(QvState *state) { announce("QvDirectionalLight" ) ; QvElement *elt = new QvElement; elt->data = this; elt->type = QvElement:: DirectionalLight ; state->addElement(QvState:: LightIndex , elt); }
+void QvPointLight ::traverse(QvState *state) { announce("QvPointLight" ) ; QvElement *elt = new QvElement; elt->data = this; elt->type = QvElement:: PointLight ; state->addElement(QvState:: LightIndex , elt); }
+void QvSpotLight ::traverse(QvState *state) { announce("QvSpotLight" ) ; QvElement *elt = new QvElement; elt->data = this; elt->type = QvElement:: SpotLight ; state->addElement(QvState:: LightIndex , elt); }
+
+void QvOrthographicCamera ::traverse(QvState *state) { announce("QvOrthographicCamera" ) ; QvElement *elt = new QvElement; elt->data = this; elt->type = QvElement:: OrthographicCamera ; state->addElement(QvState:: CameraIndex , elt); }
+void QvPerspectiveCamera ::traverse(QvState *state) { announce("QvPerspectiveCamera" ) ; QvElement *elt = new QvElement; elt->data = this; elt->type = QvElement:: PerspectiveCamera ; state->addElement(QvState:: CameraIndex , elt); }
+
+void QvTransform ::traverse(QvState *state) { announce("QvTransform" ) ; QvElement *elt = new QvElement; elt->data = this; elt->type = QvElement:: Transform ; state->addElement(QvState:: TransformationIndex , elt); }
+void QvRotation ::traverse(QvState *state) { announce("QvRotation" ) ; QvElement *elt = new QvElement; elt->data = this; elt->type = QvElement:: Rotation ; state->addElement(QvState:: TransformationIndex , elt); }
+void QvMatrixTransform ::traverse(QvState *state) { announce("QvMatrixTransform" ) ; QvElement *elt = new QvElement; elt->data = this; elt->type = QvElement:: MatrixTransform ; state->addElement(QvState:: TransformationIndex , elt); }
+void QvTranslation ::traverse(QvState *state) { announce("QvTranslation" ) ; QvElement *elt = new QvElement; elt->data = this; elt->type = QvElement:: Translation ; state->addElement(QvState:: TransformationIndex , elt); }
+void QvScale ::traverse(QvState *state) { announce("QvScale" ) ; QvElement *elt = new QvElement; elt->data = this; elt->type = QvElement:: Scale ; state->addElement(QvState:: TransformationIndex , elt); }
+
+
+
+
+
+
+
+static void
+printProperties(QvState *state)
+{
+ printf("--------------------------------------------------------------\n");
+ state->print();
+ printf("--------------------------------------------------------------\n");
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 1 "../BspLib/BRep.h" 1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 1 "../BspLib/Transform2.h" 1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+namespace BspLib {
+
+
+
+
+class Transform2 {
+
+ friend Transform2 operator *( const Transform2& trafo1, const Transform2& trafo2 );
+
+public:
+ Transform2();
+ Transform2( const float trafo[3][3] );
+ Transform2( const double trafo[3][3] );
+ ~Transform2() { }
+
+
+ Vector2 TransformVector2( const Vector2& vec ) const;
+
+ double Determinant();
+ int Inverse( Transform2& inverse );
+
+
+ Transform2& Concat( const Transform2& cattrafo );
+ Transform2& ConcatR( const Transform2& cattrafo );
+
+
+ Transform2& LoadIdentity();
+ Transform2& LoadRotation( double angle );
+ Transform2& LoadScale( double x, double y );
+ Transform2& LoadTranslation( double x, double y );
+
+
+ Transform2& Rotate( double angle );
+ Transform2& Scale( double x, double y );
+ Transform2& Translate( double x, double y );
+
+
+ Transform2& RotateR( double angle );
+ Transform2& ScaleR( double x, double y );
+ Transform2& TranslateR( double x, double y );
+
+
+ Vector2 FetchTranslation() const;
+ Vector2 ExtractTranslation();
+
+
+ double * LinMatrixAccess() { return (double *) m_matrix; }
+
+private:
+
+ double m_matrix[3][3];
+};
+
+
+inline Transform2& Transform2::LoadIdentity()
+{
+ memset( m_matrix, 0, sizeof( m_matrix ) );
+
+ m_matrix[ 0 ][ 0 ] = 1.0;
+ m_matrix[ 1 ][ 1 ] = 1.0;
+ m_matrix[ 2 ][ 2 ] = 1.0;
+
+ return *this;
+}
+
+
+inline Transform2::Transform2()
+{
+
+}
+
+
+inline Transform2::Transform2( const double trafo[3][3] )
+{
+
+
+
+ memcpy( m_matrix, trafo, sizeof( m_matrix ) );
+}
+
+
+inline Transform2::Transform2( const float trafo[3][3] )
+{
+
+
+
+ for ( int i = 0; i < 9; i++ )
+ ((double *)m_matrix)[ i ] = (double) ((float *)trafo)[ i ];
+}
+
+
+}
+
+
+
+
+# 16 "../BspLib/BRep.h" 2
+
+
+
+
+
+
+
+
+
+
+
+
+namespace BspLib {
+
+
+
+
+class BRep : public virtual SystemIO {
+
+public:
+ BRep( QvState *state );
+ ~BRep() { }
+
+ void BuildFromSpherePrimitive( const QvSphere& spherenode );
+ void BuildFromConePrimitive( const QvCone& spherenode );
+ void BuildFromCubePrimitive( const QvCube& spherenode );
+ void BuildFromCylinderPrimitive( const QvCylinder& spherenode );
+ void BuildFromIndexedFaceSet( const QvIndexedFaceSet& faceset );
+
+public:
+ static int getTriangulation() { return do_triangulation; }
+ static void setTriangulation( int tri ) { do_triangulation = tri; }
+
+ static int getTessellation() { return tessellation_slices; }
+ static void setTessellation( int tes ) { tessellation_slices = tes; }
+
+ static int getMaterialFlag() { return use_material_spec; }
+ static void setMaterialFlag( int mfl ) { use_material_spec = mfl; }
+
+ static int getMirrorTextureVFlag() { return mirror_v_axis; }
+ static void setMirrorTextureVFlag( int mtv ) { mirror_v_axis = mtv; }
+
+private:
+ float* FetchCoordinate3State( int &num );
+ float* FetchTextureCoordinate2State( int &num );
+ float* FetchNormalState( int &num );
+ void FetchTransformationState( Transform3& trafo );
+ void FetchTextureTransformationState( Transform2& trafo );
+ int FetchMaterialState( Material& mat, int indx );
+ void FetchMaterialBindingState( int& binding );
+ void FetchNormalBindingState( int& binding );
+ void FetchShapeHintsState();
+ Texture* CheckTexture2State();
+ void CreateIndexedFace( Texture *texture, int curindex, int numtexindexs, long *texindexs, int v1, int v2, int v3 );
+ void PostProcessObject();
+
+private:
+ static int shapehint_vertexOrdering;
+ static int shapehint_shapeType;
+ static int shapehint_faceType;
+ static float shapehint_creaseAngle;
+
+ static int use_material_spec;
+ static int mirror_v_axis;
+ static int do_triangulation;
+ static int tessellation_slices;
+
+private:
+ QvState* m_state;
+ BspObject* m_baseobject;
+};
+
+
+}
+
+
+
+
+# 239 "QvTraverse.cpp" 2
+
+
+void QvSphere::traverse(QvState *state)
+{
+ announce("QvSphere" ) ;
+ BspLib ::BRep brep( state );
+ brep.BuildFromSpherePrimitive( *this );
+}
+
+void QvCone::traverse(QvState *state)
+{
+ announce("QvCone" ) ;
+ BspLib ::BRep brep( state );
+ brep.BuildFromConePrimitive( *this );
+}
+
+void QvCube::traverse(QvState *state)
+{
+ announce("QvCube" ) ;
+ BspLib ::BRep brep( state );
+ brep.BuildFromCubePrimitive( *this );
+}
+
+
+void QvCylinder::traverse(QvState *state)
+{
+ announce("QvCylinder" ) ;
+ BspLib ::BRep brep( state );
+ brep.BuildFromCylinderPrimitive( *this );
+}
+
+void QvIndexedFaceSet::traverse(QvState *state)
+{
+ announce("QvIndexedFaceSet" ) ;
+
+
+
+
+
+
+ BspLib ::BRep brep( state );
+ brep.BuildFromIndexedFaceSet( *this );
+}
+
+
+
+
+
+void QvIndexedLineSet ::traverse(QvState *state) { announce("QvIndexedLineSet" ) ; printProperties(state); }
+void QvPointSet ::traverse(QvState *state) { announce("QvPointSet" ) ; printProperties(state); }
+
+
+
+
+
+
+
+
+
+
+void QvWWWAnchor ::traverse(QvState *) { announce("QvWWWAnchor" ) ; }
+void QvWWWInline ::traverse(QvState *) { announce("QvWWWInline" ) ; }
+
+
+
+
+
+
+
+void QvInfo ::traverse(QvState *) { announce("QvInfo" ) ; }
+void QvUnknownNode ::traverse(QvState *) { announce("QvUnknownNode" ) ; }
+
+
+
+
+
+
+
+
diff --git a/tool_src/QvLib/QvUnknownNode.cpp b/tool_src/QvLib/QvUnknownNode.cpp
new file mode 100644
index 0000000..7444669
--- /dev/null
+++ b/tool_src/QvLib/QvUnknownNode.cpp
@@ -0,0 +1,26 @@
+#include <QvUnknownNode.h>
+
+QV_NODE_SOURCE(QvUnknownNode);
+
+QvUnknownNode::QvUnknownNode()
+{
+ QV_NODE_CONSTRUCTOR(QvUnknownNode);
+
+ className = NULL;
+
+ // Set global field data to this instance's
+ instanceFieldData = new QvFieldData;
+ fieldData = instanceFieldData;
+}
+
+void
+QvUnknownNode::setClassName(const char *name)
+{
+ className = strdup(name);
+}
+
+QvUnknownNode::~QvUnknownNode()
+{
+ if (className != NULL)
+ free((void *) className);
+}
diff --git a/tool_src/QvLib/QvUnknownNode.h b/tool_src/QvLib/QvUnknownNode.h
new file mode 100644
index 0000000..68dde4f
--- /dev/null
+++ b/tool_src/QvLib/QvUnknownNode.h
@@ -0,0 +1,18 @@
+#ifndef _QV_UNKNOWN_NODE_
+#define _QV_UNKNOWN_NODE_
+
+#include <QvGroup.h>
+
+class QvUnknownNode : public QvGroup {
+
+ QV_NODE_HEADER(QvUnknownNode);
+
+ public:
+ const char *className;
+ QvFieldData *instanceFieldData;
+
+ void setClassName(const char *name);
+};
+
+#endif /* _QV_UNKNOWN_NODE_ */
+
diff --git a/tool_src/QvLib/QvWWWAnchor.cpp b/tool_src/QvLib/QvWWWAnchor.cpp
new file mode 100644
index 0000000..232fe6a
--- /dev/null
+++ b/tool_src/QvLib/QvWWWAnchor.cpp
@@ -0,0 +1,24 @@
+#include <QvWWWAnchor.h>
+
+QV_NODE_SOURCE(QvWWWAnchor);
+
+QvWWWAnchor::QvWWWAnchor()
+{
+ QV_NODE_CONSTRUCTOR(QvWWWAnchor);
+ isBuiltIn = TRUE;
+
+ QV_NODE_ADD_FIELD(name);
+ QV_NODE_ADD_FIELD(map);
+
+ name.value = "";
+ map.value = NONE;
+
+ QV_NODE_DEFINE_ENUM_VALUE(Map, NONE);
+ QV_NODE_DEFINE_ENUM_VALUE(Map, POINT);
+
+ QV_NODE_SET_SF_ENUM_TYPE(map, Map);
+}
+
+QvWWWAnchor::~QvWWWAnchor()
+{
+}
diff --git a/tool_src/QvLib/QvWWWAnchor.h b/tool_src/QvLib/QvWWWAnchor.h
new file mode 100644
index 0000000..988a40e
--- /dev/null
+++ b/tool_src/QvLib/QvWWWAnchor.h
@@ -0,0 +1,24 @@
+#ifndef _QV_WWW_ANCHOR_
+#define _QV_WWW_ANCHOR_
+
+#include <QvSFEnum.h>
+#include <QvSFString.h>
+#include <QvGroup.h>
+
+class QvWWWAnchor : public QvGroup {
+
+ QV_NODE_HEADER(QvWWWAnchor);
+
+ public:
+
+ enum Map { // Map types:
+ NONE, // Leave URL name alone
+ POINT, // Add object coords to URL name
+ };
+
+ // Fields
+ QvSFString name; // URL name
+ QvSFEnum map; // How to map pick to URL name
+};
+
+#endif /* _QV_WWW_ANCHOR_ */
diff --git a/tool_src/QvLib/QvWWWInline.cpp b/tool_src/QvLib/QvWWWInline.cpp
new file mode 100644
index 0000000..13db2aa
--- /dev/null
+++ b/tool_src/QvLib/QvWWWInline.cpp
@@ -0,0 +1,24 @@
+#ifdef WIN32
+#include <QvSFString.h>
+#endif
+#include <QvWWWInline.h>
+
+QV_NODE_SOURCE(QvWWWInline);
+
+QvWWWInline::QvWWWInline()
+{
+ QV_NODE_CONSTRUCTOR(QvWWWInline);
+ isBuiltIn = TRUE;
+
+ QV_NODE_ADD_FIELD(name);
+ QV_NODE_ADD_FIELD(bboxSize);
+ QV_NODE_ADD_FIELD(bboxCenter);
+
+ name.value = "";
+ bboxSize.value[0] = bboxSize.value[0] = bboxSize.value[0] = 0.0;
+ bboxCenter.value[0] = bboxCenter.value[0] = bboxCenter.value[0] = 0.0;
+}
+
+QvWWWInline::~QvWWWInline()
+{
+}
diff --git a/tool_src/QvLib/QvWWWInline.h b/tool_src/QvLib/QvWWWInline.h
new file mode 100644
index 0000000..3dd1441
--- /dev/null
+++ b/tool_src/QvLib/QvWWWInline.h
@@ -0,0 +1,20 @@
+#ifndef _QV_WWW_INLINE_
+#define _QV_WWW_INLINE_
+
+#include <QvSFEnum.h>
+#include <QvSFVec3f.h>
+#include <QvSFString.h>
+#include <QvGroup.h>
+
+class QvWWWInline : public QvGroup {
+
+ QV_NODE_HEADER(QvWWWInline);
+
+ public:
+ // Fields
+ QvSFString name; // URL name
+ QvSFVec3f bboxSize; // Size of 3D bounding box
+ QvSFVec3f bboxCenter; // Center of 3D bounding box
+};
+
+#endif /* _QV_WWW_INLINE_ */
diff --git a/tool_src/QvLib/QvWWWInline.p b/tool_src/QvLib/QvWWWInline.p
new file mode 100644
index 0000000..917b9ab
--- /dev/null
+++ b/tool_src/QvLib/QvWWWInline.p
@@ -0,0 +1,9602 @@
+# 1 "QvWWWInline.cpp"
+
+
+
+# 1 "QvWWWInline.h" 1
+
+
+
+# 1 "QvSFEnum.h" 1
+
+
+
+# 1 "QvString.h" 1
+
+
+
+# 1 "QvBasic.h" 1
+
+
+
+
+
+
+
+
+
+# 1 "/usr/include/sys/types.h" 1 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 1 "/usr/include/sys/cdefs.h" 1 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 121 "/usr/include/sys/cdefs.h" 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 67 "/usr/include/sys/types.h" 2 3 4
+
+
+
+# 1 "/usr/include/machine/types.h" 1 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 1 "/usr/include/ppc/types.h" 1 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+typedef signed char int8_t;
+typedef unsigned char u_int8_t;
+typedef short int16_t;
+typedef unsigned short u_int16_t;
+typedef int int32_t;
+typedef unsigned int u_int32_t;
+typedef long long int64_t;
+typedef unsigned long long u_int64_t;
+
+typedef int32_t register_t;
+
+
+typedef int *intptr_t;
+typedef unsigned long *uintptr_t;
+
+
+
+# 30 "/usr/include/machine/types.h" 2 3 4
+
+
+
+
+
+
+
+
+
+# 70 "/usr/include/sys/types.h" 2 3 4
+
+
+# 1 "/usr/include/machine/ansi.h" 1 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 1 "/usr/include/ppc/ansi.h" 1 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 34 "/usr/include/machine/ansi.h" 2 3 4
+
+
+
+
+
+
+
+
+
+# 72 "/usr/include/sys/types.h" 2 3 4
+
+# 1 "/usr/include/machine/endian.h" 1 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 1 "/usr/include/ppc/endian.h" 1 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+extern "C" {
+unsigned long htonl (unsigned long) ;
+unsigned short htons (unsigned short) ;
+unsigned long ntohl (unsigned long) ;
+unsigned short ntohs (unsigned short) ;
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 116 "/usr/include/ppc/endian.h" 3 4
+
+
+
+# 30 "/usr/include/machine/endian.h" 2 3 4
+
+
+
+
+
+
+
+
+
+# 73 "/usr/include/sys/types.h" 2 3 4
+
+
+
+typedef unsigned char u_char;
+typedef unsigned short u_short;
+typedef unsigned int u_int;
+typedef unsigned long u_long;
+typedef unsigned short ushort;
+typedef unsigned int uint;
+
+
+typedef u_int64_t u_quad_t;
+typedef int64_t quad_t;
+typedef quad_t * qaddr_t;
+
+typedef char * caddr_t;
+typedef int32_t daddr_t;
+typedef int32_t dev_t;
+typedef u_int32_t fixpt_t;
+typedef u_int32_t gid_t;
+typedef u_int32_t ino_t;
+typedef long key_t;
+typedef u_int16_t mode_t;
+typedef u_int16_t nlink_t;
+typedef quad_t off_t;
+typedef int32_t pid_t;
+typedef quad_t rlim_t;
+typedef int32_t segsz_t;
+typedef int32_t swblk_t;
+typedef u_int32_t uid_t;
+
+
+
+
+
+
+
+
+
+
+
+typedef unsigned long clock_t;
+
+
+
+
+typedef long unsigned int size_t;
+
+
+
+
+typedef int ssize_t;
+
+
+
+
+typedef long time_t;
+
+
+
+
+
+
+
+
+
+
+
+
+
+typedef int32_t fd_mask;
+
+
+
+
+
+
+typedef struct fd_set {
+ fd_mask fds_bits[((( 256 ) + (( (sizeof(fd_mask) * 8 ) ) - 1)) / ( (sizeof(fd_mask) * 8 ) )) ];
+} fd_set;
+
+
+
+
+
+
+
+# 174 "/usr/include/sys/types.h" 3 4
+
+
+
+
+
+struct _pthread_handler_rec
+{
+ void (*routine)(void *);
+ void *arg;
+ struct _pthread_handler_rec *next;
+};
+
+
+
+
+
+
+
+
+
+
+
+
+typedef struct _opaque_pthread_t { long sig; struct _pthread_handler_rec *cleanup_stack; char opaque[596 ];} *pthread_t;
+
+typedef struct _opaque_pthread_attr_t { long sig; char opaque[36 ]; } pthread_attr_t;
+
+typedef struct _opaque_pthread_mutexattr_t { long sig; char opaque[8 ]; } pthread_mutexattr_t;
+
+typedef struct _opaque_pthread_mutex_t { long sig; char opaque[40 ]; } pthread_mutex_t;
+
+typedef struct _opaque_pthread_condattr_t { long sig; char opaque[4 ]; } pthread_condattr_t;
+
+typedef struct _opaque_pthread_cond_t { long sig; char opaque[24 ]; } pthread_cond_t;
+
+typedef struct { long sig; char opaque[4 ]; } pthread_once_t;
+
+
+
+typedef unsigned long pthread_key_t;
+
+
+# 10 "QvBasic.h" 2
+
+
+# 1 "/usr/include/libc.h" 1 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 1 "/usr/include/stdio.h" 1 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+typedef off_t fpos_t;
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+struct __sbuf {
+ unsigned char *_base;
+ int _size;
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+typedef struct __sFILE {
+ unsigned char *_p;
+ int _r;
+ int _w;
+ short _flags;
+ short _file;
+ struct __sbuf _bf;
+ int _lbfsize;
+
+
+ void *_cookie;
+ int (*_close) (void *) ;
+ int (*_read) (void *, char *, int) ;
+ fpos_t (*_seek) (void *, fpos_t, int) ;
+ int (*_write) (void *, const char *, int) ;
+
+
+ struct __sbuf _ub;
+ unsigned char *_up;
+ int _ur;
+
+
+ unsigned char _ubuf[3];
+ unsigned char _nbuf[1];
+
+
+ struct __sbuf _lb;
+
+
+ int _blksize;
+ fpos_t _offset;
+} FILE;
+
+extern "C" {
+extern FILE __sF[];
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+extern "C" {
+void clearerr (FILE *) ;
+int fclose (FILE *) ;
+int feof (FILE *) ;
+int ferror (FILE *) ;
+int fflush (FILE *) ;
+int fgetc (FILE *) ;
+int fgetpos (FILE *, fpos_t *) ;
+char *fgets (char *, size_t, FILE *) ;
+FILE *fopen (const char *, const char *) ;
+int fprintf (FILE *, const char *, ...) ;
+int fputc (int, FILE *) ;
+int fputs (const char *, FILE *) ;
+size_t fread (void *, size_t, size_t, FILE *) ;
+FILE *freopen (const char *, const char *, FILE *) ;
+int fscanf (FILE *, const char *, ...) ;
+int fseek (FILE *, long, int) ;
+int fsetpos (FILE *, const fpos_t *) ;
+long ftell (FILE *) ;
+size_t fwrite (const void *, size_t, size_t, FILE *) ;
+int getc (FILE *) ;
+int getchar (void) ;
+char *gets (char *) ;
+
+extern int sys_nerr;
+extern const char * const sys_errlist[];
+
+void perror (const char *) ;
+int printf (const char *, ...) ;
+int putc (int, FILE *) ;
+int putchar (int) ;
+int puts (const char *) ;
+int remove (const char *) ;
+int rename (const char *, const char *) ;
+void rewind (FILE *) ;
+int scanf (const char *, ...) ;
+void setbuf (FILE *, char *) ;
+int setvbuf (FILE *, char *, int, size_t) ;
+int sprintf (char *, const char *, ...) ;
+int sscanf (const char *, const char *, ...) ;
+FILE *tmpfile (void) ;
+char *tmpnam (char *) ;
+int ungetc (int, FILE *) ;
+int vfprintf (FILE *, const char *, char * ) ;
+int vprintf (const char *, char * ) ;
+int vsprintf (char *, const char *, char * ) ;
+}
+
+
+
+
+
+
+
+
+extern "C" {
+char *ctermid (char *) ;
+FILE *fdopen (int, const char *) ;
+int fileno (FILE *) ;
+}
+
+
+
+
+
+
+extern "C" {
+char *fgetln (FILE *, size_t *) ;
+int fpurge (FILE *) ;
+int fseeko (FILE *, fpos_t, int) ;
+fpos_t ftello (FILE *) ;
+int getw (FILE *) ;
+int pclose (FILE *) ;
+FILE *popen (const char *, const char *) ;
+int putw (int, FILE *) ;
+void setbuffer (FILE *, char *, int) ;
+int setlinebuf (FILE *) ;
+char *tempnam (const char *, const char *) ;
+int snprintf (char *, size_t, const char *, ...) ;
+int vsnprintf (char *, size_t, const char *, char * ) ;
+int vscanf (const char *, char * ) ;
+int vsscanf (const char *, const char *, char * ) ;
+FILE *zopen (const char *, const char *, int) ;
+}
+
+
+
+
+
+
+
+
+
+
+
+extern "C" {
+FILE *funopen (const void *,
+ int (*)(void *, char *, int),
+ int (*)(void *, const char *, int),
+ fpos_t (*)(void *, fpos_t, int),
+ int (*)(void *)) ;
+}
+
+
+
+
+
+
+
+extern "C" {
+int __srget (FILE *) ;
+int __svfscanf (FILE *, const char *, char * ) ;
+int __swbuf (int, FILE *) ;
+}
+
+
+
+
+
+
+
+static inline int __sputc(int _c, FILE *_p) {
+ if (--_p->_w >= 0 || (_p->_w >= _p->_lbfsize && (char)_c != '\n'))
+ return (*_p->_p++ = _c);
+ else
+ return (__swbuf(_c, _p));
+}
+# 379 "/usr/include/stdio.h" 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 29 "/usr/include/libc.h" 2 3 4
+
+# 1 "/usr/include/standards.h" 1 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 30 "/usr/include/libc.h" 2 3 4
+
+# 1 "/usr/include/unistd.h" 1 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 1 "/usr/include/sys/unistd.h" 1 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 72 "/usr/include/unistd.h" 2 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+extern "C" {
+ void
+ _exit (int) ;
+int access (const char *, int) ;
+unsigned int alarm (unsigned int) ;
+int chdir (const char *) ;
+int chown (const char *, uid_t, gid_t) ;
+int close (int) ;
+size_t confstr (int, char *, size_t) ;
+int dup (int) ;
+int dup2 (int, int) ;
+int execl (const char *, const char *, ...) ;
+int execle (const char *, const char *, ...) ;
+int execlp (const char *, const char *, ...) ;
+int execv (const char *, char * const *) ;
+int execve (const char *, char * const *, char * const *) ;
+int execvp (const char *, char * const *) ;
+pid_t fork (void) ;
+long fpathconf (int, int) ;
+char *getcwd (char *, size_t) ;
+gid_t getegid (void) ;
+uid_t geteuid (void) ;
+gid_t getgid (void) ;
+int getgroups (int, gid_t []) ;
+char *getlogin (void) ;
+pid_t getpgrp (void) ;
+pid_t getpid (void) ;
+pid_t getppid (void) ;
+uid_t getuid (void) ;
+int isatty (int) ;
+int link (const char *, const char *) ;
+off_t lseek (int, off_t, int) ;
+long pathconf (const char *, int) ;
+int pause (void) ;
+int pipe (int *) ;
+ssize_t read (int, void *, size_t) ;
+int rmdir (const char *) ;
+int setgid (gid_t) ;
+int setpgid (pid_t, pid_t) ;
+pid_t setsid (void) ;
+int setuid (uid_t) ;
+unsigned int sleep (unsigned int) ;
+long sysconf (int) ;
+pid_t tcgetpgrp (int) ;
+int tcsetpgrp (int, pid_t) ;
+char *ttyname (int) ;
+int unlink (const char *) ;
+ssize_t write (int, const void *, size_t) ;
+
+extern char *optarg;
+extern int optind, opterr, optopt, optreset;
+int getopt (int, char * const [], const char *) ;
+
+
+
+struct timeval;
+
+int acct (const char *) ;
+int async_daemon (void) ;
+char *brk (const char *) ;
+int chroot (const char *) ;
+char *crypt (const char *, const char *) ;
+int des_cipher (const char *, char *, long, int) ;
+int des_setkey (const char *key) ;
+int encrypt (char *, int) ;
+void endusershell (void) ;
+int exect (const char *, char * const *, char * const *) ;
+int fchdir (int) ;
+int fchown (int, int, int) ;
+int fsync (int) ;
+int ftruncate (int, off_t) ;
+int getdtablesize (void) ;
+int getgrouplist (const char *, int, int *, int *) ;
+long gethostid (void) ;
+int gethostname (char *, int) ;
+mode_t getmode (const void *, mode_t) ;
+ int
+ getpagesize (void) ;
+char *getpass (const char *) ;
+char *getusershell (void) ;
+char *getwd (char *) ;
+int initgroups (const char *, int) ;
+int iruserok (unsigned long, int, const char *, const char *) ;
+int mknod (const char *, mode_t, dev_t) ;
+int mkstemp (char *) ;
+char *mktemp (char *) ;
+int nfssvc (int, void *) ;
+int nice (int) ;
+
+
+
+
+# 1 "/usr/include/signal.h" 1 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 1 "/usr/include/sys/signal.h" 1 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 1 "/usr/include/machine/signal.h" 1 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 1 "/usr/include/ppc/signal.h" 1 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+typedef int sig_atomic_t;
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+typedef enum {
+ REGS_SAVED_NONE,
+ REGS_SAVED_CALLER,
+
+
+ REGS_SAVED_ALL
+} regs_saved_t;
+
+
+
+
+
+
+
+
+
+struct sigcontext {
+ int sc_onstack;
+ int sc_mask;
+ int sc_ir;
+ int sc_psw;
+ int sc_sp;
+ void *sc_regs;
+};
+
+
+
+# 27 "/usr/include/machine/signal.h" 2 3 4
+
+
+
+
+
+
+
+
+
+# 70 "/usr/include/sys/signal.h" 2 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+typedef unsigned int sigset_t;
+
+
+
+
+struct sigaction {
+
+ void (*sa_handler)(int);
+
+
+
+ sigset_t sa_mask;
+ int sa_flags;
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+typedef void (*sig_t) (int) ;
+
+
+
+
+struct sigaltstack {
+ char *ss_sp;
+ int ss_size;
+ int ss_flags;
+};
+
+
+
+
+
+
+
+struct sigvec {
+ void (*sv_handler)();
+ int sv_mask;
+ int sv_flags;
+};
+
+
+
+
+
+
+
+
+struct sigstack {
+ char *ss_sp;
+ int ss_onstack;
+};
+
+
+
+
+
+
+
+# 213 "/usr/include/sys/signal.h" 3 4
+
+
+
+
+
+
+
+
+
+
+
+extern "C" {
+void (*signal (int, void (*) (int) ) ) (int) ;
+}
+
+# 62 "/usr/include/signal.h" 2 3 4
+
+
+
+extern const char * const sys_signame[32 ];
+extern const char * const sys_siglist[32 ];
+
+
+extern "C" {
+int raise (int) ;
+
+int kill (pid_t, int) ;
+int sigaction (int, const struct sigaction *, struct sigaction *) ;
+int sigaddset (sigset_t *, int) ;
+int sigdelset (sigset_t *, int) ;
+int sigemptyset (sigset_t *) ;
+int sigfillset (sigset_t *) ;
+int sigismember (const sigset_t *, int) ;
+int sigpending (sigset_t *) ;
+int sigprocmask (int, const sigset_t *, sigset_t *) ;
+int sigsuspend (const sigset_t *) ;
+
+int killpg (pid_t, int) ;
+int sigblock (int) ;
+int siginterrupt (int, int) ;
+int sigpause (int) ;
+int sigreturn (struct sigcontext *) ;
+int sigsetmask (int) ;
+int sigvec (int, struct sigvec *, struct sigvec *) ;
+void psignal (unsigned int, const char *) ;
+
+
+}
+
+
+
+
+
+
+
+
+
+# 176 "/usr/include/unistd.h" 2 3 4
+
+
+int profil (char *, int, int, int) ;
+int rcmd (char **, int, const char *,
+ const char *, const char *, int *) ;
+char *re_comp (const char *) ;
+int re_exec (const char *) ;
+int readlink (const char *, char *, int) ;
+int reboot (int) ;
+int revoke (const char *) ;
+int rresvport (int *) ;
+int ruserok (const char *, int, const char *, const char *) ;
+char *sbrk (int) ;
+int select (int, fd_set *, fd_set *, fd_set *, struct timeval *) ;
+int setegid (gid_t) ;
+int seteuid (uid_t) ;
+int setgroups (int, const gid_t *) ;
+void sethostid (long) ;
+int sethostname (const char *, int) ;
+int setkey (const char *) ;
+int setlogin (const char *) ;
+void *setmode (const char *) ;
+int setpgrp (pid_t pid, pid_t pgrp) ;
+int setregid (gid_t, gid_t) ;
+int setreuid (uid_t, uid_t) ;
+int setrgid (gid_t) ;
+int setruid (uid_t) ;
+void setusershell (void) ;
+int swapon (const char *) ;
+int symlink (const char *, const char *) ;
+void sync (void) ;
+int syscall (int, ...) ;
+int truncate (const char *, off_t) ;
+int ttyslot (void) ;
+unsigned int ualarm (unsigned int, unsigned int) ;
+int unwhiteout (const char *) ;
+void usleep (unsigned int) ;
+void *valloc (size_t) ;
+pid_t vfork (void) ;
+
+extern char *suboptarg;
+int getsubopt (char **, char * const *, char **) ;
+
+
+int getattrlist (const char*,void*,void*,size_t,unsigned long) ;
+int setattrlist (const char*,void*,void*,size_t,unsigned long) ;
+int exchangedata (const char*,const char*,unsigned long) ;
+int checkuseraccess (const char*,uid_t,gid_t*,int,int,unsigned long) ;
+int getdirentriesattr (int,void*,void*,size_t,unsigned long*,unsigned long*,unsigned long*,unsigned long) ;
+int searchfs (const char*,void*,void*,unsigned long,unsigned long,void*) ;
+
+int fsctl (const char *,unsigned long,void*,unsigned long) ;
+
+
+
+}
+
+
+# 31 "/usr/include/libc.h" 2 3 4
+
+
+
+
+
+
+# 1 "/usr/include/string.h" 1 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+extern "C" {
+void *memchr (const void *, int, size_t) ;
+int memcmp (const void *, const void *, size_t) ;
+void *memcpy (void *, const void *, size_t) ;
+void *memmove (void *, const void *, size_t) ;
+void *memset (void *, int, size_t) ;
+char *strcat (char *, const char *) ;
+char *strchr (const char *, int) ;
+int strcmp (const char *, const char *) ;
+int strcoll (const char *, const char *) ;
+char *strcpy (char *, const char *) ;
+size_t strcspn (const char *, const char *) ;
+char *strerror (int) ;
+size_t strlen (const char *) ;
+char *strncat (char *, const char *, size_t) ;
+int strncmp (const char *, const char *, size_t) ;
+char *strncpy (char *, const char *, size_t) ;
+char *strpbrk (const char *, const char *) ;
+char *strrchr (const char *, int) ;
+size_t strspn (const char *, const char *) ;
+char *strstr (const char *, const char *) ;
+char *strtok (char *, const char *) ;
+size_t strxfrm (char *, const char *, size_t) ;
+
+
+
+int bcmp (const void *, const void *, size_t) ;
+void bcopy (const void *, void *, size_t) ;
+void bzero (void *, size_t) ;
+int ffs (int) ;
+char *index (const char *, int) ;
+void *memccpy (void *, const void *, int, size_t) ;
+char *rindex (const char *, int) ;
+int strcasecmp (const char *, const char *) ;
+char *strdup (const char *) ;
+void strmode (int, char *) ;
+int strncasecmp (const char *, const char *, size_t) ;
+char *strsep (char **, const char *) ;
+void swab (const void *, void *, size_t) ;
+
+}
+
+
+# 37 "/usr/include/libc.h" 2 3 4
+
+# 1 "/usr/include/stdlib.h" 1 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+typedef __wchar_t rune_t;
+
+typedef __wchar_t wchar_t;
+
+
+typedef struct {
+ int quot;
+ int rem;
+} div_t;
+
+typedef struct {
+ long quot;
+ long rem;
+} ldiv_t;
+
+
+
+
+
+
+
+
+
+
+extern int __mb_cur_max;
+
+
+
+
+extern "C" {
+ void
+ abort (void) ;
+ int
+ abs (int) ;
+int atexit (void (*)(void)) ;
+double atof (const char *) ;
+int atoi (const char *) ;
+long atol (const char *) ;
+void *bsearch (const void *, const void *, size_t,
+ size_t, int (*)(const void *, const void *)) ;
+void *calloc (size_t, size_t) ;
+ div_t
+ div (int, int) ;
+ void
+ exit (int) ;
+void free (void *) ;
+char *getenv (const char *) ;
+ long
+ labs (long) ;
+ ldiv_t
+ ldiv (long, long) ;
+void *malloc (size_t) ;
+void qsort (void *, size_t, size_t,
+ int (*)(const void *, const void *)) ;
+int rand (void) ;
+void *realloc (void *, size_t) ;
+void srand (unsigned) ;
+double strtod (const char *, char **) ;
+long strtol (const char *, char **, int) ;
+unsigned long
+ strtoul (const char *, char **, int) ;
+int system (const char *) ;
+
+
+int mblen (const char *, size_t) ;
+size_t mbstowcs (wchar_t *, const char *, size_t) ;
+int wctomb (char *, wchar_t) ;
+int mbtowc (wchar_t *, const char *, size_t) ;
+size_t wcstombs (char *, const wchar_t *, size_t) ;
+
+
+int putenv (const char *) ;
+int setenv (const char *, const char *, int) ;
+
+
+
+void *alloca (size_t) ;
+
+char *getbsize (int *, long *) ;
+char *cgetcap (char *, char *, int) ;
+int cgetclose (void) ;
+int cgetent (char **, char **, char *) ;
+int cgetfirst (char **, char **) ;
+int cgetmatch (char *, char *) ;
+int cgetnext (char **, char **) ;
+int cgetnum (char *, char *, long *) ;
+int cgetset (char *) ;
+int cgetstr (char *, char *, char **) ;
+int cgetustr (char *, char *, char **) ;
+
+int daemon (int, int) ;
+char *devname (int, int) ;
+int getloadavg (double [], int) ;
+
+char *group_from_gid (unsigned long, int) ;
+int heapsort (void *, size_t, size_t,
+ int (*)(const void *, const void *)) ;
+char *initstate (unsigned long, char *, long) ;
+int mergesort (void *, size_t, size_t,
+ int (*)(const void *, const void *)) ;
+int radixsort (const unsigned char **, int, const unsigned char *,
+ unsigned) ;
+int sradixsort (const unsigned char **, int, const unsigned char *,
+ unsigned) ;
+long random (void) ;
+char *realpath (const char *, char resolved_path[]) ;
+char *setstate (char *) ;
+void srandom (unsigned long) ;
+char *user_from_uid (unsigned long, int) ;
+
+long long
+ strtoq (const char *, char **, int) ;
+unsigned long long
+ strtouq (const char *, char **, int) ;
+
+void unsetenv (const char *) ;
+
+}
+
+
+# 38 "/usr/include/libc.h" 2 3 4
+
+# 1 "/usr/include/time.h" 1 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+struct tm {
+ int tm_sec;
+ int tm_min;
+ int tm_hour;
+ int tm_mday;
+ int tm_mon;
+ int tm_year;
+ int tm_wday;
+ int tm_yday;
+ int tm_isdst;
+ long tm_gmtoff;
+ char *tm_zone;
+};
+
+# 1 "/usr/include/gcc/darwin/2.95.2/g++/../machine/limits.h" 1 3
+
+
+# 1 "/usr/include/ppc/limits.h" 1 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 3 "/usr/include/gcc/darwin/2.95.2/g++/../machine/limits.h" 2 3
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 100 "/usr/include/time.h" 2 3 4
+
+
+
+
+
+
+extern "C" {
+char *asctime (const struct tm *) ;
+clock_t clock (void) ;
+char *ctime (const time_t *) ;
+double difftime (time_t, time_t) ;
+struct tm *gmtime (const time_t *) ;
+struct tm *localtime (const time_t *) ;
+time_t mktime (struct tm *) ;
+size_t strftime (char *, size_t, const char *, const struct tm *) ;
+time_t time (time_t *) ;
+
+
+void tzset (void) ;
+
+
+
+char *timezone (int, int) ;
+void tzsetwall (void) ;
+
+}
+
+
+# 39 "/usr/include/libc.h" 2 3 4
+
+# 1 "/usr/include/gcc/darwin/2.95.2/g++/../stdarg.h" 1 3
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 1 "/usr/include/gcc/darwin/2.95.2/g++/../va-ppc.h" 1 3
+
+
+
+
+
+
+
+
+typedef char *__gnuc_va_list;
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 43 "/usr/include/gcc/darwin/2.95.2/g++/../va-ppc.h" 3
+
+
+
+void va_end (__gnuc_va_list);
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 352 "/usr/include/gcc/darwin/2.95.2/g++/../va-ppc.h" 3
+
+# 42 "/usr/include/gcc/darwin/2.95.2/g++/../stdarg.h" 2 3
+
+# 131 "/usr/include/gcc/darwin/2.95.2/g++/../stdarg.h" 3
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 175 "/usr/include/gcc/darwin/2.95.2/g++/../stdarg.h" 3
+
+
+
+
+
+
+
+
+
+
+
+
+
+typedef __gnuc_va_list va_list;
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 40 "/usr/include/libc.h" 2 3 4
+
+
+
+# 1 "/usr/include/sys/mount.h" 1 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 1 "/usr/include/sys/ucred.h" 1 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 1 "/usr/include/sys/param.h" 1 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 1 "/usr/include/sys/syslimits.h" 1 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 88 "/usr/include/sys/param.h" 2 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 1 "/usr/include/machine/param.h" 1 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 1 "/usr/include/ppc/param.h" 1 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 30 "/usr/include/machine/param.h" 2 3 4
+
+
+
+
+
+
+
+
+
+# 102 "/usr/include/sys/param.h" 2 3 4
+
+# 1 "/usr/include/gcc/darwin/2.95.2/g++/../machine/limits.h" 1 3
+# 10 "/usr/include/gcc/darwin/2.95.2/g++/../machine/limits.h" 3
+
+# 108 "/usr/include/gcc/darwin/2.95.2/g++/../machine/limits.h" 3
+
+# 103 "/usr/include/sys/param.h" 2 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 61 "/usr/include/sys/ucred.h" 2 3 4
+
+
+
+
+
+struct ucred {
+ u_long cr_ref;
+ uid_t cr_uid;
+ short cr_ngroups;
+ gid_t cr_groups[16 ];
+};
+
+
+
+
+# 88 "/usr/include/sys/ucred.h" 3 4
+
+
+
+# 62 "/usr/include/sys/mount.h" 2 3 4
+
+
+# 1 "/usr/include/sys/queue.h" 1 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 184 "/usr/include/sys/queue.h" 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 260 "/usr/include/sys/queue.h" 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 378 "/usr/include/sys/queue.h" 3 4
+
+
+
+
+
+
+
+
+
+# 395 "/usr/include/sys/queue.h" 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 453 "/usr/include/sys/queue.h" 3 4
+
+
+# 463 "/usr/include/sys/queue.h" 3 4
+
+
+# 473 "/usr/include/sys/queue.h" 3 4
+
+
+# 483 "/usr/include/sys/queue.h" 3 4
+
+
+
+
+
+
+
+
+# 502 "/usr/include/sys/queue.h" 3 4
+
+# 548 "/usr/include/sys/queue.h" 3 4
+
+
+
+# 64 "/usr/include/sys/mount.h" 2 3 4
+
+# 1 "/usr/include/sys/lock.h" 1 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 74 "/usr/include/sys/lock.h" 3 4
+
+
+
+
+
+# 1 "/usr/include/mach/boolean.h" 1 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 1 "/usr/include/mach/machine/boolean.h" 1 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 1 "/usr/include/mach/ppc/boolean.h" 1 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+typedef int boolean_t;
+
+
+# 27 "/usr/include/mach/machine/boolean.h" 2 3 4
+
+
+
+
+
+
+
+
+
+# 127 "/usr/include/mach/boolean.h" 2 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 79 "/usr/include/sys/lock.h" 2 3 4
+
+
+
+struct slock{
+ volatile unsigned int lock_data[10];
+};
+
+
+
+
+
+typedef struct slock simple_lock_data_t;
+typedef struct slock *simple_lock_t;
+
+
+
+
+
+
+
+
+
+
+
+struct lock__bsd__ {
+ simple_lock_data_t
+ lk_interlock;
+ u_int lk_flags;
+ int lk_sharecount;
+ int lk_waitcount;
+ short lk_exclusivecount;
+ short lk_prio;
+ char *lk_wmesg;
+ int lk_timo;
+ pid_t lk_lockholder;
+ void *lk_lockthread;
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+struct proc;
+
+void lockinit (struct lock__bsd__ *, int prio, char *wmesg, int timo,
+ int flags) ;
+int lockmgr (struct lock__bsd__ *, u_int flags,
+ simple_lock_t, struct proc *p) ;
+int lockstatus (struct lock__bsd__ *) ;
+
+
+# 65 "/usr/include/sys/mount.h" 2 3 4
+
+# 1 "/usr/include/net/radix.h" 1 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+struct radix_node {
+ struct radix_mask *rn_mklist;
+ struct radix_node *rn_p;
+ short rn_b;
+ char rn_bmask;
+ u_char rn_flags;
+
+
+
+ union {
+ struct {
+ caddr_t rn_Key;
+ caddr_t rn_Mask;
+ struct radix_node *rn_Dupedkey;
+ } rn_leaf;
+ struct {
+ int rn_Off;
+ struct radix_node *rn_L;
+ struct radix_node *rn_R;
+ } rn_node;
+ } rn_u;
+
+
+
+
+
+};
+
+
+
+
+
+
+
+
+
+
+
+
+struct radix_mask {
+ short rm_b;
+ char rm_unused;
+ u_char rm_flags;
+ struct radix_mask *rm_mklist;
+ union {
+ caddr_t rmu_mask;
+ struct radix_node *rmu_leaf;
+ } rm_rmu;
+ int rm_refs;
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+typedef int walktree_f_t (struct radix_node *, void *) ;
+
+struct radix_node_head {
+ struct radix_node *rnh_treetop;
+ int rnh_addrsize;
+ int rnh_pktsize;
+ struct radix_node *(*rnh_addaddr)
+ (void *v, void *mask,
+ struct radix_node_head *head, struct radix_node nodes[]) ;
+ struct radix_node *(*rnh_addpkt)
+ (void *v, void *mask,
+ struct radix_node_head *head, struct radix_node nodes[]) ;
+ struct radix_node *(*rnh_deladdr)
+ (void *v, void *mask, struct radix_node_head *head) ;
+ struct radix_node *(*rnh_delpkt)
+ (void *v, void *mask, struct radix_node_head *head) ;
+ struct radix_node *(*rnh_matchaddr)
+ (void *v, struct radix_node_head *head) ;
+ struct radix_node *(*rnh_lookup)
+ (void *v, void *mask, struct radix_node_head *head) ;
+ struct radix_node *(*rnh_matchpkt)
+ (void *v, struct radix_node_head *head) ;
+ int (*rnh_walktree)
+ (struct radix_node_head *head, walktree_f_t *f, void *w) ;
+ int (*rnh_walktree_from)
+ (struct radix_node_head *head, void *a, void *m,
+ walktree_f_t *f, void *w) ;
+ void (*rnh_close)
+ (struct radix_node *rn, struct radix_node_head *head) ;
+ struct radix_node rnh_nodes[3];
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+void rn_init (void) ;
+int rn_inithead (void **, int) ;
+int rn_refines (void *, void *) ;
+struct radix_node
+ *rn_addmask (void *, int, int) ,
+ *rn_addroute (void *, void *, struct radix_node_head *,
+ struct radix_node [2]) ,
+ *rn_delete (void *, void *, struct radix_node_head *) ,
+ *rn_lookup (void *v_arg, void *m_arg,
+ struct radix_node_head *head) ,
+ *rn_match (void *, struct radix_node_head *) ;
+
+
+
+# 66 "/usr/include/sys/mount.h" 2 3 4
+
+# 1 "/usr/include/sys/socket.h" 1 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+struct linger {
+ int l_onoff;
+ int l_linger;
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+struct sockaddr {
+ u_char sa_len;
+ u_char sa_family;
+ char sa_data[14];
+};
+
+
+
+
+
+
+struct sockproto {
+ u_short sp_family;
+ u_short sp_protocol;
+};
+
+
+
+
+
+
+
+
+
+
+
+struct sockaddr_storage {
+ u_char ss_len;
+ u_char ss_family;
+ char _ss_pad1[((sizeof(int64_t)) - sizeof(u_char) * 2) ];
+ int64_t _ss_align;
+ char _ss_pad2[(128 - sizeof(u_char) * 2 - ((sizeof(int64_t)) - sizeof(u_char) * 2) - (sizeof(int64_t)) ) ];
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 295 "/usr/include/sys/socket.h" 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+struct msghdr {
+ caddr_t msg_name;
+ u_int msg_namelen;
+ struct iovec *msg_iov;
+ u_int msg_iovlen;
+ caddr_t msg_control;
+ u_int msg_controllen;
+ int msg_flags;
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+struct cmsghdr {
+ u_int cmsg_len;
+ int cmsg_level;
+ int cmsg_type;
+
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+struct osockaddr {
+ u_short sa_family;
+ char sa_data[14];
+};
+
+
+
+
+struct omsghdr {
+ caddr_t msg_name;
+ int msg_namelen;
+ struct iovec *msg_iov;
+ int msg_iovlen;
+ caddr_t msg_accrights;
+ int msg_accrightslen;
+};
+
+
+
+
+
+
+
+
+# 427 "/usr/include/sys/socket.h" 3 4
+
+
+
+
+
+
+extern "C" {
+int accept (int, struct sockaddr *, int *) ;
+int bind (int, const struct sockaddr *, int) ;
+int connect (int, const struct sockaddr *, int) ;
+int getpeername (int, struct sockaddr *, int *) ;
+int getsockname (int, struct sockaddr *, int *) ;
+int getsockopt (int, int, int, void *, int *) ;
+int listen (int, int) ;
+ssize_t recv (int, void *, size_t, int) ;
+ssize_t recvfrom (int, void *, size_t, int, struct sockaddr *, int *) ;
+ssize_t recvmsg (int, struct msghdr *, int) ;
+ssize_t send (int, const void *, size_t, int) ;
+ssize_t sendto (int, const void *,
+ size_t, int, const struct sockaddr *, int) ;
+ssize_t sendmsg (int, const struct msghdr *, int) ;
+
+
+
+int setsockopt (int, int, int, const void *, int) ;
+int shutdown (int, int) ;
+int socket (int, int, int) ;
+int socketpair (int, int, int, int *) ;
+}
+
+
+
+# 67 "/usr/include/sys/mount.h" 2 3 4
+
+
+typedef struct fsid { int32_t val[2]; } fsid_t;
+
+
+
+
+
+
+
+struct fid {
+ u_short fid_len;
+ u_short fid_reserved;
+ char fid_data[16 ];
+};
+
+
+
+
+
+
+
+
+struct statfs {
+ short f_otype;
+ short f_oflags;
+ long f_bsize;
+ long f_iosize;
+ long f_blocks;
+ long f_bfree;
+ long f_bavail;
+ long f_files;
+ long f_ffree;
+ fsid_t f_fsid;
+ uid_t f_owner;
+ short f_reserved1;
+ short f_type;
+ long f_flags;
+ long f_reserved2[2];
+ char f_fstypename[15 ];
+ char f_mntonname[90 ];
+ char f_mntfromname[90 ];
+
+
+
+
+ char f_reserved3;
+ long f_reserved4[4];
+
+};
+
+
+
+
+
+
+struct vnodelst { struct vnode *lh_first; } ;
+
+struct mount {
+ struct { struct mount *cqe_next; struct mount *cqe_prev; } mnt_list;
+ struct vfsops *mnt_op;
+ struct vfsconf *mnt_vfc;
+ struct vnode *mnt_vnodecovered;
+ struct vnodelst mnt_vnodelist;
+ struct lock__bsd__ mnt_lock;
+ int mnt_flag;
+ int mnt_kern_flag;
+ int mnt_maxsymlinklen;
+ struct statfs mnt_stat;
+ qaddr_t mnt_data;
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+struct fhandle {
+ fsid_t fh_fsid;
+ struct fid fh_fid;
+};
+typedef struct fhandle fhandle_t;
+
+
+
+
+struct export_args {
+ int ex_flags;
+ uid_t ex_root;
+ struct ucred ex_anon;
+ struct sockaddr *ex_addr;
+ int ex_addrlen;
+ struct sockaddr *ex_mask;
+ int ex_masklen;
+};
+
+
+
+
+
+
+struct vfsconf {
+ struct vfsops *vfc_vfsops;
+ char vfc_name[15 ];
+ int vfc_typenum;
+ int vfc_refcount;
+ int vfc_flags;
+ int (*vfc_mountroot)(void);
+ struct vfsconf *vfc_next;
+};
+
+# 361 "/usr/include/sys/mount.h" 3 4
+
+
+
+
+extern "C" {
+int fstatfs (int, struct statfs *) ;
+int getfh (const char *, fhandle_t *) ;
+int getfsstat (struct statfs *, long, int) ;
+int getmntinfo (struct statfs **, int) ;
+int mount (const char *, const char *, int, void *) ;
+int statfs (const char *, struct statfs *) ;
+int unmount (const char *, int) ;
+}
+
+
+
+# 43 "/usr/include/libc.h" 2 3 4
+
+
+# 1 "/usr/include/sys/wait.h" 1 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+union wait {
+ int w_status;
+
+
+
+ struct {
+
+
+
+
+
+
+
+ unsigned int w_Filler:16,
+ w_Retcode:8,
+ w_Coredump:1,
+ w_Termsig:7;
+
+ } w_T;
+
+
+
+
+
+ struct {
+
+
+
+
+
+
+ unsigned int w_Filler:16,
+ w_Stopsig:8,
+ w_Stopval:8;
+
+ } w_S;
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+extern "C" {
+struct rusage;
+
+pid_t wait (int *) ;
+pid_t waitpid (pid_t, int *, int) ;
+
+pid_t wait3 (int *, int, struct rusage *) ;
+pid_t wait4 (pid_t, int *, int, struct rusage *) ;
+
+}
+
+
+# 45 "/usr/include/libc.h" 2 3 4
+
+# 1 "/usr/include/sys/time.h" 1 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+struct timeval {
+ int32_t tv_sec;
+ int32_t tv_usec;
+};
+
+
+
+
+struct timespec {
+ time_t tv_sec;
+ int32_t tv_nsec;
+};
+
+
+
+
+
+
+
+
+
+
+struct timezone {
+ int tz_minuteswest;
+ int tz_dsttime;
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 121 "/usr/include/sys/time.h" 3 4
+
+# 130 "/usr/include/sys/time.h" 3 4
+
+
+
+
+
+
+
+
+
+struct itimerval {
+ struct timeval it_interval;
+ struct timeval it_value;
+};
+
+
+
+
+struct clockinfo {
+ int hz;
+ int tick;
+ int tickadj;
+ int stathz;
+ int profhz;
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+extern "C" {
+int adjtime (const struct timeval *, struct timeval *) ;
+int getitimer (int, struct itimerval *) ;
+int gettimeofday (struct timeval *, struct timezone *) ;
+int setitimer (int, const struct itimerval *, struct itimerval *) ;
+int settimeofday (const struct timeval *, const struct timezone *) ;
+int utimes (const char *, const struct timeval *) ;
+}
+
+
+
+
+
+# 46 "/usr/include/libc.h" 2 3 4
+
+# 1 "/usr/include/sys/times.h" 1 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+struct tms {
+ clock_t tms_utime;
+ clock_t tms_stime;
+ clock_t tms_cutime;
+ clock_t tms_cstime;
+};
+
+
+
+
+extern "C" {
+clock_t times (struct tms *) ;
+}
+
+
+# 47 "/usr/include/libc.h" 2 3 4
+
+# 1 "/usr/include/sys/resource.h" 1 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+struct rusage {
+ struct timeval ru_utime;
+ struct timeval ru_stime;
+ long ru_maxrss;
+
+ long ru_ixrss;
+ long ru_idrss;
+ long ru_isrss;
+ long ru_minflt;
+ long ru_majflt;
+ long ru_nswap;
+ long ru_inblock;
+ long ru_oublock;
+ long ru_msgsnd;
+ long ru_msgrcv;
+ long ru_nsignals;
+ long ru_nvcsw;
+ long ru_nivcsw;
+
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+struct orlimit {
+ int32_t rlim_cur;
+ int32_t rlim_max;
+};
+
+struct rlimit {
+ rlim_t rlim_cur;
+ rlim_t rlim_max;
+};
+
+
+struct loadavg {
+ fixpt_t ldavg[3];
+ long fscale;
+};
+
+
+
+
+
+
+
+extern "C" {
+int getpriority (int, int) ;
+int getrlimit (int, struct rlimit *) ;
+int getrusage (int, struct rusage *) ;
+int setpriority (int, int, int) ;
+int setrlimit (int, const struct rlimit *) ;
+}
+
+
+
+# 48 "/usr/include/libc.h" 2 3 4
+
+
+
+
+# 1 "/usr/include/sys/stat.h" 1 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+struct ostat {
+ u_int16_t st_dev;
+ ino_t st_ino;
+ mode_t st_mode;
+ nlink_t st_nlink;
+ u_int16_t st_uid;
+ u_int16_t st_gid;
+ u_int16_t st_rdev;
+ int32_t st_size;
+ struct timespec st_atimespec;
+ struct timespec st_mtimespec;
+ struct timespec st_ctimespec;
+ int32_t st_blksize;
+ int32_t st_blocks;
+ u_int32_t st_flags;
+ u_int32_t st_gen;
+};
+
+
+struct stat {
+ dev_t st_dev;
+ ino_t st_ino;
+ mode_t st_mode;
+ nlink_t st_nlink;
+ uid_t st_uid;
+ gid_t st_gid;
+ dev_t st_rdev;
+
+ struct timespec st_atimespec;
+ struct timespec st_mtimespec;
+ struct timespec st_ctimespec;
+
+
+
+
+
+
+
+
+ off_t st_size;
+ int64_t st_blocks;
+ u_int32_t st_blksize;
+ u_int32_t st_flags;
+ u_int32_t st_gen;
+ int32_t st_lspare;
+ int64_t st_qspare[2];
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+extern "C" {
+int chmod (const char *, mode_t) ;
+int fstat (int, struct stat *) ;
+int mkdir (const char *, mode_t) ;
+int mkfifo (const char *, mode_t) ;
+int stat (const char *, struct stat *) ;
+mode_t umask (mode_t) ;
+
+int chflags (const char *, u_long) ;
+int fchflags (int, u_long) ;
+int fchmod (int, mode_t) ;
+int lstat (const char *, struct stat *) ;
+
+}
+
+
+# 52 "/usr/include/libc.h" 2 3 4
+
+# 1 "/usr/include/sys/file.h" 1 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 1 "/usr/include/sys/fcntl.h" 1 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 131 "/usr/include/sys/fcntl.h" 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+struct flock {
+ off_t l_start;
+ off_t l_len;
+ pid_t l_pid;
+ short l_type;
+ short l_whence;
+};
+
+
+
+
+
+
+struct radvisory {
+ off_t ra_offset;
+ int ra_count;
+};
+
+
+
+
+
+
+
+
+
+
+
+
+typedef struct fstore {
+ u_int32_t fst_flags;
+ int fst_posmode;
+ off_t fst_offset;
+ off_t fst_length;
+ off_t fst_bytesalloc;
+} fstore_t;
+
+
+
+typedef struct fbootstraptransfer {
+ off_t fbt_offset;
+ size_t fbt_length;
+ void *fbt_buffer;
+} fbootstraptransfer_t;
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+struct log2phys {
+ u_int32_t l2p_flags;
+ off_t l2p_contigbytes;
+ off_t l2p_devoffset;
+};
+
+
+
+
+
+
+
+
+
+extern "C" {
+int open (const char *, int, ...) ;
+int creat (const char *, mode_t) ;
+int fcntl (int, int, ...) ;
+
+int flock (int, int) ;
+
+}
+
+
+
+# 61 "/usr/include/sys/file.h" 2 3 4
+
+
+
+# 112 "/usr/include/sys/file.h" 3 4
+
+
+
+# 53 "/usr/include/libc.h" 2 3 4
+
+
+# 1 "/usr/include/sys/ioctl.h" 1 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 1 "/usr/include/sys/ttycom.h" 1 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 1 "/usr/include/sys/ioccom.h" 1 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 66 "/usr/include/sys/ttycom.h" 2 3 4
+
+
+
+
+
+
+
+
+
+
+
+struct winsize {
+ unsigned short ws_row;
+ unsigned short ws_col;
+ unsigned short ws_xpixel;
+ unsigned short ws_ypixel;
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 66 "/usr/include/sys/ioctl.h" 2 3 4
+
+
+
+
+
+
+
+struct ttysize {
+ unsigned short ts_lines;
+ unsigned short ts_cols;
+ unsigned short ts_xxx;
+ unsigned short ts_yyy;
+};
+
+
+
+
+
+# 1 "/usr/include/sys/filio.h" 1 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 84 "/usr/include/sys/ioctl.h" 2 3 4
+
+# 1 "/usr/include/sys/sockio.h" 1 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 85 "/usr/include/sys/ioctl.h" 2 3 4
+
+
+
+
+
+
+extern "C" {
+int ioctl (int, unsigned long, ...) ;
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 55 "/usr/include/libc.h" 2 3 4
+
+# 1 "/usr/include/netinet/in.h" 1 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+struct in_addr {
+ u_int32_t s_addr;
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+struct sockaddr_in {
+ u_char sin_len;
+ u_char sin_family;
+ u_short sin_port;
+ struct in_addr sin_addr;
+ char sin_zero[8];
+};
+
+
+
+
+
+
+
+
+
+
+struct ip_opts {
+ struct in_addr ip_dst;
+ char ip_opts[40];
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+struct ip_mreq {
+ struct in_addr imr_multiaddr;
+ struct in_addr imr_interface;
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 456 "/usr/include/netinet/in.h" 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 499 "/usr/include/netinet/in.h" 3 4
+
+
+
+# 1 "/usr/include/netinet6/in6.h" 1 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+struct in6_addr {
+ union {
+ u_int8_t __u6_addr8[16];
+ u_int16_t __u6_addr16[8];
+ u_int32_t __u6_addr32[4];
+ } __u6_addr;
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+struct sockaddr_in6 {
+ u_int8_t sin6_len;
+ u_int8_t sin6_family;
+ u_int16_t sin6_port;
+ u_int32_t sin6_flowinfo;
+ struct in6_addr sin6_addr;
+ u_int32_t sin6_scope_id;
+};
+
+
+
+
+# 166 "/usr/include/netinet6/in6.h" 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 199 "/usr/include/netinet6/in6.h" 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 335 "/usr/include/netinet6/in6.h" 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+struct route_in6 {
+ struct rtentry *ro_rt;
+ struct sockaddr_in6 ro_dst;
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+struct ipv6_mreq {
+ struct in6_addr ipv6mr_multiaddr;
+ u_int ipv6mr_interface;
+};
+
+
+
+
+struct in6_pktinfo {
+ struct in6_addr ipi6_addr;
+ u_int ipi6_ifindex;
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 530 "/usr/include/netinet6/in6.h" 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 611 "/usr/include/netinet6/in6.h" 3 4
+
+# 640 "/usr/include/netinet6/in6.h" 3 4
+
+
+
+# 666 "/usr/include/netinet6/in6.h" 3 4
+
+
+extern "C" {
+struct cmsghdr;
+
+extern int inet6_option_space (int) ;
+extern int inet6_option_init (void *, struct cmsghdr **, int) ;
+extern int inet6_option_append (struct cmsghdr *, const u_int8_t *,
+ int, int) ;
+extern u_int8_t *inet6_option_alloc (struct cmsghdr *, int, int, int) ;
+extern int inet6_option_next (const struct cmsghdr *, u_int8_t **) ;
+extern int inet6_option_find (const struct cmsghdr *, u_int8_t **, int) ;
+
+extern size_t inet6_rthdr_space (int, int) ;
+extern struct cmsghdr *inet6_rthdr_init (void *, int) ;
+extern int inet6_rthdr_add (struct cmsghdr *, const struct in6_addr *,
+ unsigned int) ;
+extern int inet6_rthdr_lasthop (struct cmsghdr *, unsigned int) ;
+
+
+
+extern int inet6_rthdr_segments (const struct cmsghdr *) ;
+extern struct in6_addr *inet6_rthdr_getaddr (struct cmsghdr *, int) ;
+extern int inet6_rthdr_getflags (const struct cmsghdr *, int) ;
+
+extern int inet6_opt_init (void *, size_t) ;
+extern int inet6_opt_append (void *, size_t, int, u_int8_t,
+ size_t, u_int8_t, void **) ;
+extern int inet6_opt_finish (void *, size_t, int) ;
+extern int inet6_opt_set_val (void *, size_t, void *, int) ;
+
+extern int inet6_opt_next (void *, size_t, int, u_int8_t *,
+ size_t *, void **) ;
+extern int inet6_opt_find (void *, size_t, int, u_int8_t,
+ size_t *, void **) ;
+extern int inet6_opt_get_val (void *, size_t, void *, int) ;
+extern size_t inet6_rth_space (int, int) ;
+extern void *inet6_rth_init (void *, int, int, int) ;
+extern int inet6_rth_add (void *, const struct in6_addr *) ;
+extern int inet6_rth_reverse (const void *, void *) ;
+extern int inet6_rth_segments (const void *) ;
+extern struct in6_addr *inet6_rth_getaddr (const void *, int) ;
+}
+
+
+# 502 "/usr/include/netinet/in.h" 2 3 4
+
+
+
+# 514 "/usr/include/netinet/in.h" 3 4
+
+
+
+# 56 "/usr/include/libc.h" 2 3 4
+
+# 1 "/usr/include/arpa/inet.h" 1 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+extern "C" {
+unsigned long inet_addr (const char *) ;
+int inet_aton (const char *, struct in_addr *) ;
+unsigned long inet_lnaof (struct in_addr) ;
+struct in_addr inet_makeaddr (u_long , u_long) ;
+unsigned long inet_netof (struct in_addr) ;
+unsigned long inet_network (const char *) ;
+char *inet_ntoa (struct in_addr) ;
+}
+
+
+# 57 "/usr/include/libc.h" 2 3 4
+
+# 1 "/usr/include/mach/machine/vm_types.h" 1 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 1 "/usr/include/mach/ppc/vm_types.h" 1 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+typedef unsigned int natural_t;
+
+
+
+
+
+
+
+
+typedef int integer_t;
+
+
+
+
+
+
+
+
+
+
+
+
+
+typedef natural_t vm_offset_t;
+
+
+
+
+
+
+typedef natural_t vm_size_t;
+typedef unsigned long long vm_double_size_t;
+
+
+
+
+typedef unsigned int space_t;
+
+
+
+
+
+
+
+
+
+
+# 27 "/usr/include/mach/machine/vm_types.h" 2 3 4
+
+
+
+
+
+
+
+
+
+# 58 "/usr/include/libc.h" 2 3 4
+
+
+# 1 "/usr/include/mach/kern_return.h" 1 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 1 "/usr/include/mach/machine/kern_return.h" 1 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 1 "/usr/include/mach/ppc/kern_return.h" 1 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+typedef int kern_return_t;
+
+
+# 27 "/usr/include/mach/machine/kern_return.h" 2 3 4
+
+
+
+
+
+
+
+
+
+# 64 "/usr/include/mach/kern_return.h" 2 3 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 60 "/usr/include/libc.h" 2 3 4
+
+
+struct qelem {
+ struct qelem *q_forw;
+ struct qelem *q_back;
+ char *q_data;
+};
+
+extern kern_return_t map_fd(int fd, vm_offset_t offset,
+ vm_offset_t *addr, boolean_t find_space, vm_size_t numbytes);
+
+
+
+# 12 "QvBasic.h" 2
+
+
+
+
+
+
+
+
+
+
+
+typedef int QvBool;
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 4 "QvString.h" 2
+
+
+
+class QvString {
+ public:
+ QvString() { string = staticStorage;
+ string[0] = '\0'; }
+ QvString(const char *str) { string = staticStorage;
+ *this = str; }
+ QvString(const QvString &str) { string = staticStorage;
+ *this = str.string; }
+ ~QvString();
+ u_long hash() { return QvString::hash(string); }
+ int getLength() const { return strlen(string); }
+ void makeEmpty(QvBool freeOld = 1 );
+ const char * getString() const { return string; }
+ QvString & operator =(const char *str);
+ QvString & operator =(const QvString &str)
+ { return (*this = str.string); }
+ QvString & operator +=(const char *str);
+ int operator !() const { return (string[0] == '\0'); }
+ friend int operator ==(const QvString &str, const char *s);
+
+ friend int operator ==(const char *s, const QvString &str)
+ { return (str == s); }
+
+ friend int operator ==(const QvString &str1, const QvString &str2)
+ { return (str1 == str2.string); }
+ friend int operator !=(const QvString &str, const char *s);
+
+ friend int operator !=(const char *s, const QvString &str)
+ { return (str != s); }
+ friend int operator !=(const QvString &str1,
+ const QvString &str2)
+ { return (str1 != str2.string); }
+ static u_long hash(const char *s);
+ private:
+ char *string;
+ int storageSize;
+
+ char staticStorage[32 ];
+ void expand(int bySize);
+};
+
+class QvNameEntry {
+ public:
+ QvBool isEmpty() const { return (string[0] == '\0'); }
+ QvBool isEqual(const char *s) const
+ { return (string[0] == s[0] && ! strcmp(string, s)); }
+ private:
+ static int nameTableSize;
+ static QvNameEntry **nameTable;
+ static struct QvNameChunk *chunk;
+ const char *string;
+ u_long hashValue;
+ QvNameEntry *next;
+ static void initClass();
+ QvNameEntry(const char *s, u_long h, QvNameEntry *n)
+ { string = s; hashValue = h; next = n; }
+ static const QvNameEntry * insert(const char *s);
+
+friend class QvName;
+};
+
+class QvName {
+ public:
+ QvName();
+ QvName(const char *s) { entry = QvNameEntry::insert(s); }
+ QvName(const QvString &s) { entry = QvNameEntry::insert(s.getString()); }
+
+ QvName(const QvName &n) { entry = n.entry; }
+ ~QvName() {}
+ const char *getString() const { return entry->string; }
+ int getLength() const { return strlen(entry->string); }
+ static QvBool isIdentStartChar(char c);
+ static QvBool isIdentChar(char c);
+ static QvBool isNodeNameStartChar(char c);
+ static QvBool isNodeNameChar(char c);
+ int operator !() const { return entry->isEmpty(); }
+ friend int operator ==(const QvName &n, const char *s)
+ { return n.entry->isEqual(s); }
+ friend int operator ==(const char *s, const QvName &n)
+ { return n.entry->isEqual(s); }
+
+ friend int operator ==(const QvName &n1, const QvName &n2)
+ { return n1.entry == n2.entry; }
+ friend int operator !=(const QvName &n, const char *s)
+ { return ! n.entry->isEqual(s); }
+ friend int operator !=(const char *s, const QvName &n)
+ { return ! n.entry->isEqual(s); }
+
+ friend int operator !=(const QvName &n1, const QvName &n2)
+ { return n1.entry != n2.entry; }
+ private:
+ const QvNameEntry *entry;
+};
+
+
+# 4 "QvSFEnum.h" 2
+
+# 1 "QvSubField.h" 1
+
+
+
+# 1 "QvField.h" 1
+
+
+
+
+
+class QvInput;
+class QvNode;
+
+class QvField {
+ public:
+ virtual ~QvField();
+
+ void setIgnored(QvBool ig) { flags.ignored = ig; }
+ QvBool isIgnored() const { return flags.ignored; }
+
+ QvBool isDefault() const { return flags.hasDefault; }
+
+ QvNode * getContainer() const { return container; }
+
+ void setDefault(QvBool def) { flags.hasDefault = def; }
+ void setContainer(QvNode *cont);
+ QvBool read(QvInput *in, const QvName &name);
+
+ QvField() { flags.hasDefault = 1 ; flags.ignored = 0 ; }
+
+ public:
+
+ private:
+ struct {
+ unsigned int hasDefault : 1;
+ unsigned int ignored : 1;
+ } flags;
+
+ QvNode *container;
+
+ static QvField * createInstanceFromName(const QvName &className);
+ virtual QvBool readValue(QvInput *in) = 0;
+
+friend class QvFieldData;
+};
+
+class QvSField : public QvField {
+ public:
+ virtual ~QvSField();
+
+ protected:
+ QvSField();
+
+ private:
+ virtual QvBool readValue(QvInput *in) = 0;
+};
+
+class QvMField : public QvField {
+
+ public:
+ int num;
+ int maxNum;
+
+
+ virtual ~QvMField();
+
+ protected:
+ QvMField();
+ virtual void makeRoom(int newNum);
+
+ private:
+ virtual void allocValues(int num) = 0;
+ virtual QvBool readValue(QvInput *in);
+ virtual QvBool read1Value(QvInput *in, int index) = 0;
+};
+
+
+# 4 "QvSubField.h" 2
+
+# 1 "QvInput.h" 1
+
+
+
+# 1 "QvDict.h" 1
+
+
+
+
+
+# 1 "QvPList.h" 1
+
+
+
+
+
+class QvPList {
+ public:
+ QvPList();
+ ~QvPList();
+ void append(void * ptr)
+ { if (nPtrs + 1 > ptrsSize) expand(nPtrs + 1);
+ ptrs[nPtrs++] = ptr; }
+ int find(const void *ptr) const;
+ void remove(int which);
+ int getLength() const { return (int) nPtrs; }
+ void truncate(int start)
+ { nPtrs = start; }
+ void *& operator [](int i) const { return ptrs[i]; }
+
+ private:
+ void ** ptrs;
+ int nPtrs;
+ int ptrsSize;
+ void setSize(int size)
+ { if (size > ptrsSize) expand(size); nPtrs = size; }
+ void expand(int size);
+};
+
+
+# 6 "QvDict.h" 2
+
+
+class QvDictEntry {
+ private:
+ u_long key;
+ void * value;
+ QvDictEntry * next;
+ QvDictEntry(u_long k, void *v) { key = k; value = v; };
+
+friend class QvDict;
+};
+
+class QvDict {
+ public:
+ QvDict( int entries = 251 );
+ ~QvDict();
+ void clear();
+ QvBool enter(u_long key, void *value);
+ QvBool find(u_long key, void *&value) const;
+ QvBool remove(u_long key);
+
+ private:
+ int tableSize;
+ QvDictEntry * *buckets;
+ QvDictEntry *& findEntry(u_long key) const;
+};
+
+
+# 4 "QvInput.h" 2
+
+
+
+class QvNode;
+class QvDB;
+
+class QvInput {
+ public:
+
+ QvInput();
+ ~QvInput();
+
+ static float isASCIIHeader(const char *string);
+ void setFilePointer(FILE *newFP);
+ FILE * getCurFile() const { return fp; }
+ float getVersion();
+ QvBool get(char &c);
+ QvBool read(char &c);
+ QvBool read(QvString &s);
+ QvBool read(QvName &n, QvBool validIdent = 0 );
+ QvBool read(int &i);
+ QvBool read(unsigned int &i);
+ QvBool read(short &s);
+ QvBool read(unsigned short &s);
+ QvBool read(long &l);
+ QvBool read(unsigned long &l);
+ QvBool read(float &f);
+ QvBool read(double &d);
+ QvBool eof() const;
+ void getLocationString(QvString &string) const;
+ void putBack(char c);
+ void putBack(const char *string);
+ void addReference(const QvName &name, QvNode *node);
+ QvNode * findReference(const QvName &name) const;
+
+ private:
+ FILE *fp;
+ int lineNum;
+ float version;
+ QvBool readHeader;
+ QvBool headerOk;
+ QvDict refDict;
+ QvString backBuf;
+ int backBufIndex;
+
+ QvBool checkHeader();
+
+ QvBool skipWhiteSpace();
+
+ QvBool readInteger(long &l);
+ QvBool readUnsignedInteger(unsigned long &l);
+ QvBool readReal(double &d);
+ QvBool readUnsignedIntegerString(char *str);
+ int readDigits(char *string);
+ int readHexDigits(char *string);
+ int readChar(char *string, char charToRead);
+
+friend class QvNode;
+friend class QvDB;
+};
+
+
+# 5 "QvSubField.h" 2
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 71 "QvSubField.h"
+
+
+# 5 "QvSFEnum.h" 2
+
+
+class QvSFEnum : public QvSField {
+ public:
+ int value;
+ public: QvSFEnum (); virtual ~ QvSFEnum (); virtual QvBool readValue(QvInput *in) ;
+
+
+ void setEnums(int num, const int vals[], const QvName names[])
+ { numEnums = num; enumValues = vals; enumNames = names; }
+
+ int numEnums;
+ const int *enumValues;
+ const QvName *enumNames;
+
+
+ QvBool findEnumValue(const QvName &name, int &val) const;
+};
+
+
+# 37 "QvSFEnum.h"
+
+
+# 4 "QvWWWInline.h" 2
+
+# 1 "QvSFVec3f.h" 1
+
+
+
+
+
+class QvSFVec3f : public QvSField {
+ public:
+ float value[3];
+ public: QvSFVec3f (); virtual ~ QvSFVec3f (); virtual QvBool readValue(QvInput *in) ;
+};
+
+
+# 5 "QvWWWInline.h" 2
+
+# 1 "QvGroup.h" 1
+
+
+
+class QvChildList;
+# 1 "QvSubNode.h" 1
+
+
+
+# 1 "QvFieldData.h" 1
+
+
+
+
+
+
+
+class QvField;
+class QvInput;
+class QvNode;
+
+class QvFieldData {
+ public:
+ QvFieldData() {}
+ ~QvFieldData();
+
+ void addField(QvNode *defObject, const char *fieldName,
+ const QvField *field);
+
+ int getNumFields() const { return fields.getLength(); }
+
+ const QvName & getFieldName(int index) const;
+
+ QvField * getField(const QvNode *object,
+ int index) const;
+
+ void addEnumValue(const char *typeName,
+ const char *valName, int val);
+ void getEnumData(const char *typeName, int &num,
+ const int *&vals, const QvName *&names);
+
+ QvBool read(QvInput *in, QvNode *object,
+ QvBool errorOnUnknownField = 1 ) const;
+
+ QvBool read(QvInput *in, QvNode *object,
+ const QvName &fieldName,
+ QvBool &foundName) const;
+
+ QvBool readFieldTypes(QvInput *in, QvNode *object);
+
+ private:
+ QvPList fields;
+ QvPList enums;
+};
+
+
+# 4 "QvSubNode.h" 2
+
+# 1 "QvNode.h" 1
+
+
+
+
+
+class QvChildList;
+class QvDict;
+class QvFieldData;
+class QvInput;
+class QvNodeList;
+class QvState;
+
+class QvNode {
+
+ public:
+ enum Stage {
+ FIRST_INSTANCE,
+ PROTO_INSTANCE,
+ OTHER_INSTANCE,
+ };
+
+ QvFieldData *fieldData;
+ QvChildList *children;
+ QvBool isBuiltIn;
+
+ QvName *objName;
+ QvNode();
+ virtual ~QvNode();
+
+ const QvName & getName() const;
+ void setName(const QvName &name);
+
+ static void init();
+ static QvBool read(QvInput *in, QvNode *&node);
+
+ virtual QvFieldData *getFieldData() = 0;
+
+ virtual void traverse(QvState *state) = 0;
+
+ protected:
+ virtual QvBool readInstance(QvInput *in);
+
+ private:
+ static QvDict *nameDict;
+
+ static void addName(QvNode *, const char *);
+ static void removeName(QvNode *, const char *);
+ static QvNode * readReference(QvInput *in);
+ static QvBool readNode(QvInput *in, QvName &className,QvNode *&node);
+ static QvBool readNodeInstance(QvInput *in, const QvName &className,
+ const QvName &refName, QvNode *&node);
+ static QvNode * createInstance(QvInput *in, const QvName &className);
+ static QvNode * createInstanceFromName(const QvName &className);
+ static void flushInput(QvInput *in);
+};
+
+
+# 5 "QvSubNode.h" 2
+
+
+
+# 16 "QvSubNode.h"
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 5 "QvGroup.h" 2
+
+
+class QvGroup : public QvNode {
+
+ public: QvGroup :: QvGroup (); virtual ~ QvGroup (); virtual void traverse(QvState *state); private: static QvBool firstInstance; static QvFieldData *fieldData; virtual QvFieldData *getFieldData() { return fieldData; } ;
+
+ public:
+ QvNode * getChild(int index) const;
+ int getNumChildren() const;
+ virtual QvChildList *getChildren() const;
+ virtual QvBool readInstance(QvInput *in);
+ virtual QvBool readChildren(QvInput *in);
+};
+
+
+# 6 "QvWWWInline.h" 2
+
+
+class QvWWWInline : public QvGroup {
+
+ public: QvWWWInline :: QvWWWInline (); virtual ~ QvWWWInline (); virtual void traverse(QvState *state); private: static QvBool firstInstance; static QvFieldData *fieldData; virtual QvFieldData *getFieldData() { return fieldData; } ;
+
+ public:
+
+ QvSFString name;
+ QvSFVec3f bboxSize;
+ QvSFVec3f bboxCenter;
+};
+
+
+# 4 "QvWWWInline.cpp" 2
+
+
+QvFieldData * QvWWWInline ::fieldData; QvBool QvWWWInline ::firstInstance = 1 ; ;
+
+QvWWWInline::QvWWWInline()
+{
+ if (fieldData == 0 ) fieldData = new QvFieldData; else firstInstance = 0 ; isBuiltIn = 0 ; ;
+ isBuiltIn = 1 ;
+
+ if (firstInstance) fieldData->addField(this, "name" , &this-> name ); this-> name .setContainer(this); ;
+ if (firstInstance) fieldData->addField(this, "bboxSize" , &this-> bboxSize ); this-> bboxSize .setContainer(this); ;
+ if (firstInstance) fieldData->addField(this, "bboxCenter" , &this-> bboxCenter ); this-> bboxCenter .setContainer(this); ;
+
+ name.value = "";
+ bboxSize.value[0] = bboxSize.value[0] = bboxSize.value[0] = 0.0;
+ bboxCenter.value[0] = bboxCenter.value[0] = bboxCenter.value[0] = 0.0;
+}
+
+QvWWWInline::~QvWWWInline()
+{
+}
diff --git a/tool_src/makeodt/COPYING b/tool_src/makeodt/COPYING
new file mode 100644
index 0000000..bf50f20
--- /dev/null
+++ b/tool_src/makeodt/COPYING
@@ -0,0 +1,482 @@
+ GNU LIBRARY GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1991 Free Software Foundation, Inc.
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the library GPL. It is
+ numbered 2 because it goes with version 2 of the ordinary GPL.]
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+ This license, the Library General Public License, applies to some
+specially designated Free Software Foundation software, and to any
+other libraries whose authors decide to use it. You can use it for
+your libraries, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if
+you distribute copies of the library, or if you modify it.
+
+ For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you. You must make sure that they, too, receive or can get the source
+code. If you link a program with the library, you must provide
+complete object files to the recipients so that they can relink them
+with the library, after making changes to the library and recompiling
+it. And you must show them these terms so they know their rights.
+
+ Our method of protecting your rights has two steps: (1) copyright
+the library, and (2) offer you this license which gives you legal
+permission to copy, distribute and/or modify the library.
+
+ Also, for each distributor's protection, we want to make certain
+that everyone understands that there is no warranty for this free
+library. If the library is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original
+version, so that any problems introduced by others will not reflect on
+the original authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that companies distributing free
+software will individually obtain patent licenses, thus in effect
+transforming the program into proprietary software. To prevent this,
+we have made it clear that any patent must be licensed for everyone's
+free use or not licensed at all.
+
+ Most GNU software, including some libraries, is covered by the ordinary
+GNU General Public License, which was designed for utility programs. This
+license, the GNU Library General Public License, applies to certain
+designated libraries. This license is quite different from the ordinary
+one; be sure to read it in full, and don't assume that anything in it is
+the same as in the ordinary license.
+
+ The reason we have a separate public license for some libraries is that
+they blur the distinction we usually make between modifying or adding to a
+program and simply using it. Linking a program with a library, without
+changing the library, is in some sense simply using the library, and is
+analogous to running a utility program or application program. However, in
+a textual and legal sense, the linked executable is a combined work, a
+derivative of the original library, and the ordinary General Public License
+treats it as such.
+
+ Because of this blurred distinction, using the ordinary General
+Public License for libraries did not effectively promote software
+sharing, because most developers did not use the libraries. We
+concluded that weaker conditions might promote sharing better.
+
+ However, unrestricted linking of non-free programs would deprive the
+users of those programs of all benefit from the free status of the
+libraries themselves. This Library General Public License is intended to
+permit developers of non-free programs to use free libraries, while
+preserving your freedom as a user of such programs to change the free
+libraries that are incorporated in them. (We have not seen how to achieve
+this as regards changes in header files, but we have achieved it as regards
+changes in the actual functions of the Library.) The hope is that this
+will lead to faster development of free libraries.
+
+ The precise terms and conditions for copying, distribution and
+modification follow. Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library". The
+former contains code derived from the library, while the latter only
+works together with the library.
+
+ Note that it is possible for a library to be covered by the ordinary
+General Public License rather than by this special one.
+
+ GNU LIBRARY GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License Agreement applies to any software library which
+contains a notice placed by the copyright holder or other authorized
+party saying it may be distributed under the terms of this Library
+General Public License (also called "this License"). Each licensee is
+addressed as "you".
+
+ A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+ The "Library", below, refers to any such software library or work
+which has been distributed under these terms. A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language. (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+ "Source code" for a work means the preferred form of the work for
+making modifications to it. For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+ Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it). Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+ 1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+ You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+ 2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) The modified work must itself be a software library.
+
+ b) You must cause the files modified to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ c) You must cause the whole of the work to be licensed at no
+ charge to all third parties under the terms of this License.
+
+ d) If a facility in the modified Library refers to a function or a
+ table of data to be supplied by an application program that uses
+ the facility, other than as an argument passed when the facility
+ is invoked, then you must make a good faith effort to ensure that,
+ in the event an application does not supply such function or
+ table, the facility still operates, and performs whatever part of
+ its purpose remains meaningful.
+
+ (For example, a function in a library to compute square roots has
+ a purpose that is entirely well-defined independent of the
+ application. Therefore, Subsection 2d requires that any
+ application-supplied function or table used by this function must
+ be optional: if the application does not supply it, the square
+ root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library. To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License. (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.) Do not make any other change in
+these notices.
+
+ Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+ This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+ 4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+ If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library". Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+ However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library". The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+ When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library. The
+threshold for this to be true is not precisely defined by law.
+
+ If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work. (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+ Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+ 6. As an exception to the Sections above, you may also compile or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+ You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License. You must supply a copy of this License. If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License. Also, you must do one
+of these things:
+
+ a) Accompany the work with the complete corresponding
+ machine-readable source code for the Library including whatever
+ changes were used in the work (which must be distributed under
+ Sections 1 and 2 above); and, if the work is an executable linked
+ with the Library, with the complete machine-readable "work that
+ uses the Library", as object code and/or source code, so that the
+ user can modify the Library and then relink to produce a modified
+ executable containing the modified Library. (It is understood
+ that the user who changes the contents of definitions files in the
+ Library will not necessarily be able to recompile the application
+ to use the modified definitions.)
+
+ b) Accompany the work with a written offer, valid for at
+ least three years, to give the same user the materials
+ specified in Subsection 6a, above, for a charge no more
+ than the cost of performing this distribution.
+
+ c) If distribution of the work is made by offering access to copy
+ from a designated place, offer equivalent access to copy the above
+ specified materials from the same place.
+
+ d) Verify that the user has already received a copy of these
+ materials or that you have already sent this user a copy.
+
+ For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it. However, as a special exception,
+the source code distributed need not include anything that is normally
+distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+ It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system. Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+ 7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+ a) Accompany the combined library with a copy of the same work
+ based on the Library, uncombined with any other library
+ facilities. This must be distributed under the terms of the
+ Sections above.
+
+ b) Give prominent notice with the combined library of the fact
+ that part of it is a work based on the Library, and explaining
+ where to find the accompanying uncombined form of the same work.
+
+ 8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License. Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License. However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+ 9. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Library or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+ 10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all. For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded. In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+ 13. The Free Software Foundation may publish revised and/or new
+versions of the Library General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation. If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+ 14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission. For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this. Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+ NO WARRANTY
+
+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Libraries
+
+ If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change. You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+ To apply these terms, attach the following notices to the library. It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the library's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307 USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the
+ library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+ <signature of Ty Coon>, 1 April 1990
+ Ty Coon, President of Vice
+
+That's all there is to it!
diff --git a/tool_src/makeodt/Makefile b/tool_src/makeodt/Makefile
new file mode 100644
index 0000000..8315365
--- /dev/null
+++ b/tool_src/makeodt/Makefile
@@ -0,0 +1,18 @@
+CFILES = makeodt.c getopt.c
+
+CFLAGS = -g -O2 -x c++ -fno-for-scope -I../BspLib -I../QvLib
+
+all: makeodt
+
+clean:
+ rm -f *.o *~ makeodt
+
+makeodt: $(CFILES:.c=.o) ../BspLib/libbsp.a ../QvLib/libqv.a
+ $(CC) -o makeodt $(CFILES:.c=.o) ../BspLib/libbsp.a ../QvLib/libqv.a -lstdc++
+
+# use this if you've compiled BspLib with JPEG support
+#makeodt: $(CFILES:.c=.o) ../BspLib/libbsp.a ../QvLib/libqv.a
+# $(CC) -o makeodt $(CFILES:.c=.o) ../BspLib/libbsp.a ../QvLib/libqv.a -lstdc++ -ljpeg
+
+
+
diff --git a/tool_src/makeodt/getopt.cpp b/tool_src/makeodt/getopt.cpp
new file mode 100644
index 0000000..a6dc89e
--- /dev/null
+++ b/tool_src/makeodt/getopt.cpp
@@ -0,0 +1,620 @@
+/*
+ * PARSEC MODULE (ENGINE CORE)
+ * Command Line Options Support V1.05
+ *
+ * Copyright (c) Markus Hadwiger 1999-2000
+ * All Rights Reserved.
+ */
+
+// C library
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+// local module header
+#include "getopt.h"
+
+
+
+// command line options tables ------------------------------------------------
+//
+#define DEFAULT_MAX_OPTIONS 32
+
+static cli_option_s cli_options_default[ DEFAULT_MAX_OPTIONS ];
+static cli_option_s* cli_options = cli_options_default;
+static int num_cli_options = 0;
+static int max_cli_options = DEFAULT_MAX_OPTIONS;
+
+
+// shortcut for registering a new set command line option ---------------------
+//
+int OPT_RegisterSetOption( const char *optshort, const char *optlong, int (*func)() )
+{
+ ASSERT( ( optshort != NULL ) || ( optlong != NULL ) );
+ ASSERT( func != NULL );
+
+ cli_option_s clioption;
+ memset( &clioption, 0, sizeof( cli_option_s ) );
+
+ clioption.opt_short = optshort;
+ clioption.opt_long = optlong;
+ clioption.exec_set = func;
+
+ return OPT_RegisterOption( &clioption );
+}
+
+
+// shortcut for registering a new int command line option ---------------------
+//
+int OPT_RegisterIntOption( const char *optshort, const char *optlong, int (*func)(int*) )
+{
+ ASSERT( ( optshort != NULL ) || ( optlong != NULL ) );
+ ASSERT( func != NULL );
+
+ cli_option_s clioption;
+ memset( &clioption, 0, sizeof( cli_option_s ) );
+
+ clioption.opt_short = optshort;
+ clioption.opt_long = optlong;
+ clioption.num_int = 1;
+ clioption.exec_int = func;
+
+ return OPT_RegisterOption( &clioption );
+}
+
+
+// shortcut for registering a new float command line option -------------------
+//
+int OPT_RegisterFloatOption( const char *optshort, const char *optlong, int (*func)(float*) )
+{
+ ASSERT( ( optshort != NULL ) || ( optlong != NULL ) );
+ ASSERT( func != NULL );
+
+ cli_option_s clioption;
+ memset( &clioption, 0, sizeof( cli_option_s ) );
+
+ clioption.opt_short = optshort;
+ clioption.opt_long = optlong;
+ clioption.num_float = 1;
+ clioption.exec_float = func;
+
+ return OPT_RegisterOption( &clioption );
+}
+
+
+// shortcut for registering a new string command line option ------------------
+//
+int OPT_RegisterStringOption( const char *optshort, const char *optlong, int (*func)(char**) )
+{
+ ASSERT( ( optshort != NULL ) || ( optlong != NULL ) );
+ ASSERT( func != NULL );
+
+ cli_option_s clioption;
+ memset( &clioption, 0, sizeof( cli_option_s ) );
+
+ clioption.opt_short = optshort;
+ clioption.opt_long = optlong;
+ clioption.num_string = 1;
+ clioption.exec_string = func;
+
+ return OPT_RegisterOption( &clioption );
+}
+
+
+// register a new command line option -----------------------------------------
+//
+int OPT_RegisterOption( cli_option_s *regopt )
+{
+ //NOTE:
+ //CAVEAT:
+ // the supplied option strings are not copied
+ // by this function. thus, the caller MUST ENSURE
+ // that these strings are available indefinitely.
+ // (e.g., allocated statically.)
+
+ ASSERT( regopt != NULL );
+ ASSERT( num_cli_options <= max_cli_options );
+
+ // expand table memory if already used up
+ if ( num_cli_options == max_cli_options ) {
+
+ // expand exponentially
+ int newtabsize = max_cli_options * 2;
+
+ // alloc new table
+ cli_option_s * newlist = new cli_option_s[newtabsize];
+ if ( newlist == NULL ) {
+ ASSERT( 0 );
+ return FALSE;
+ }
+
+ // set new size
+ max_cli_options = newtabsize;
+
+ // move old table
+ memcpy( newlist, cli_options, sizeof( cli_option_s ) * num_cli_options );
+ if ( cli_options != cli_options_default )
+ delete [] cli_options;
+ cli_options = newlist;
+ }
+
+ // append new command line option
+ ASSERT( num_cli_options < max_cli_options );
+ cli_options[ num_cli_options++ ] = *regopt;
+
+ return TRUE;
+}
+
+
+// application name option tables ---------------------------------------------
+//
+#define DEFAULT_MAX_APPLICATIONS 8
+
+static app_option_s app_options_default[ DEFAULT_MAX_APPLICATIONS ];
+static app_option_s* app_options = app_options_default;
+static int num_app_options = 0;
+static int max_app_options = DEFAULT_MAX_APPLICATIONS;
+
+
+// register a special command line option for application invocation ----------
+//
+int OPT_RegisterApplication( char *appname, void (*appmain)(int,char**) )
+{
+ ASSERT( appname != NULL );
+ ASSERT( appmain != NULL );
+
+ //NOTE:
+ //CAVEAT:
+ // the supplied name string is not copied
+ // by this function. thus, the caller MUST ENSURE
+ // that this string is available indefinitely.
+ // (e.g., allocated statically.)
+
+ ASSERT( num_app_options <= max_app_options );
+
+ // expand table memory if already used up
+ if ( num_app_options == max_app_options ) {
+
+ // expand exponentially
+ int newtabsize = max_app_options * 2;
+
+ // alloc new table
+ app_option_s * newlist = new app_option_s[newtabsize];
+ if ( newlist == NULL ) {
+ ASSERT( 0 );
+ return FALSE;
+ }
+
+ // set new size
+ max_app_options = newtabsize;
+
+ // move old table
+ memcpy( newlist, app_options, sizeof( app_option_s ) * num_app_options );
+ if ( app_options != app_options_default )
+ delete [] app_options;
+ app_options = newlist;
+ }
+
+ // append new command line option
+ ASSERT( num_app_options < max_app_options );
+ app_options[ num_app_options ].appname = appname;
+ app_options[ num_app_options ].appmain = appmain;
+ num_app_options++;
+
+ return TRUE;
+}
+
+
+// remove all registered options ----------------------------------------------
+//
+void OPT_ClearOptions()
+{
+ // free expanded table memory if present
+ if ( cli_options != cli_options_default ) {
+ delete [] cli_options;
+ cli_options = cli_options_default;
+ }
+
+ num_cli_options = 0;
+ max_cli_options = DEFAULT_MAX_OPTIONS;
+
+ // free expanded table memory if present
+ if ( app_options != app_options_default ) {
+ delete [] app_options;
+ app_options = app_options_default;
+ }
+
+ num_app_options = 0;
+ max_app_options = DEFAULT_MAX_APPLICATIONS;
+}
+
+
+// options parsing globals ----------------------------------------------------
+//
+#define MAX_INT_PARAMS 8
+#define MAX_FLOAT_PARAMS 8
+#define MAX_STRING_PARAMS 4
+
+static int cur_opt_indx;
+static int cur_int_indx;
+static int cur_float_indx;
+static int cur_string_indx;
+
+static int want_params_int = 0;
+static int want_params_float = 0;
+static int want_params_string = 0;
+
+static int params_int[ MAX_INT_PARAMS ];
+static float params_float[ MAX_FLOAT_PARAMS ];
+static char* params_string[ MAX_STRING_PARAMS ];
+
+
+// exec set option immediately/schedule others for parameter parsing ----------
+//
+PRIVATE
+int ScheduleOption( int indx )
+{
+ cli_option_s *refopt = &cli_options[ indx ];
+
+ // remember option we found
+ cur_opt_indx = indx;
+
+ if ( cli_options[ indx ].exec_set ) {
+
+ want_params_int = 0;
+ want_params_float = 0;
+ want_params_string = 0;
+
+ // set options will be called immediately
+ return (*cli_options[ indx ].exec_set)();
+
+ } else {
+
+ cur_int_indx = 0;
+ cur_float_indx = 0;
+ cur_string_indx = 0;
+
+ want_params_int = refopt->num_int;
+ want_params_float = refopt->num_float;
+ want_params_string = refopt->num_string;
+
+ // options with parameters will be called after
+ // parameter parsing has completed
+ return TRUE;
+ }
+}
+
+
+// try to find a match for the whole short option string ----------------------
+//
+PRIVATE
+int CheckShortStringMatch( char *opt )
+{
+ ASSERT( opt != NULL );
+ int indx = 0;
+ // try first to match the entire string
+ for ( indx = 0; indx < num_cli_options; indx++ ) {
+
+ cli_option_s *refopt = &cli_options[ indx ];
+ if ( refopt->opt_short != NULL ) {
+ if ( strcmp( opt, refopt->opt_short ) == 0 ) {
+
+ // exec immediately/schedule parameter parsing
+ if ( !ScheduleOption( indx ) ) {
+ return FALSE;
+ }
+ break;
+ }
+ }
+ }
+
+ // return whether full-string match found
+ return ( indx < num_cli_options );
+}
+
+
+// extract multiple options from a single short option string -----------------
+//
+PRIVATE
+int CheckShortCharContained( char *opt )
+{
+ ASSERT( opt != NULL );
+
+ // make absolutely sure the supplied string is writable
+ char temp[ 20 + 1 ];
+ strncpy( temp, opt, 20 );
+ temp[ 20 ] = 0;
+ opt = temp;
+
+ // scan all registered short (-) options
+ for ( int indx = 0; indx < num_cli_options; indx++ ) {
+ if ( cli_options[ indx ].opt_short != NULL ) {
+
+ if ( strlen( opt ) < 2 ) {
+ if ( *opt == *cli_options[ indx ].opt_short ) {
+ // exec immediately/schedule parameter parsing
+ if ( !ScheduleOption( indx ) ) {
+ return FALSE;
+ }
+ }
+ } else {
+ // search for current option in multiple options string
+ for ( char *optchar = opt; *optchar != 0; optchar++ ) {
+ if ( *optchar == *cli_options[ indx ].opt_short ) {
+ // only set options allowed
+ if ( cli_options[ indx ].exec_set ) {
+ if ( !(*cli_options[ indx ].exec_set)() ) {
+ return FALSE;
+ }
+ } else {
+ return FALSE;
+ }
+ // remove as recognized
+ *optchar = ' ';
+ }
+ }
+ }
+ }
+ }
+
+ // check whether all options recognized
+ for ( char *optchar = opt; *optchar != 0; optchar++ ) {
+ if ( *optchar != ' ' ) {
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+
+// try to match the supplied string with one or more short options ------------
+//
+PRIVATE
+int CheckShortOption( char *opt )
+{
+ ASSERT( opt != NULL );
+
+ // try first to match the entire string
+ if ( CheckShortStringMatch( opt ) )
+ return TRUE;
+
+ // if no string-match use string as set of options
+ return CheckShortCharContained( opt );
+}
+
+
+// try to match the supplied string with a long option ------------------------
+//
+PRIVATE
+int CheckLongOption( char *opt )
+{
+ ASSERT( opt != NULL );
+ int indx = 0;
+ // compare with all registered long (--) options
+ for ( indx = 0; indx < num_cli_options; indx++ ) {
+
+ cli_option_s *refopt = &cli_options[ indx ];
+ if ( refopt->opt_long != NULL ) {
+ if ( strcmp( opt, refopt->opt_long ) == 0 ) {
+
+ // exec immediately/schedule parameter parsing
+ if ( !ScheduleOption( indx ) ) {
+ return FALSE;
+ }
+ break;
+ }
+ }
+ }
+
+ // return whether match found
+ return ( indx < num_cli_options );
+}
+
+
+// get int parameter for command line option ----------------------------------
+//
+PRIVATE
+int GetOptionIntParam( char *paramstr )
+{
+ ASSERT( paramstr != NULL );
+
+ char *errpart;
+ long iparam = strtol( paramstr, &errpart, 10 );
+
+ if ( *errpart != 0 ) {
+ return FALSE;
+ }
+
+ // store int into table
+ params_int[ cur_int_indx++ ] = iparam;
+
+ // submit completed table to registered function
+ if ( --want_params_int == 0 ) {
+ if ( !(*cli_options[ cur_opt_indx ].exec_int)( params_int ) ) {
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+
+// get float parameter for command line option --------------------------------
+//
+PRIVATE
+int GetOptionFloatParam( char *paramstr )
+{
+ ASSERT( paramstr != NULL );
+
+ char *errpart;
+ double fparam = strtod( paramstr, &errpart );
+
+ if ( *errpart != 0 ) {
+ return FALSE;
+ }
+
+ // store float into table
+ params_float[ cur_float_indx++ ] = fparam;
+
+ // submit completed table to registered function
+ if ( --want_params_float == 0 ) {
+ if ( !(*cli_options[ cur_opt_indx ].exec_float)( params_float ) ) {
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+
+// get string parameter for command line option -------------------------------
+//
+PRIVATE
+int GetOptionStringParam( char *paramstr )
+{
+ ASSERT( paramstr != NULL );
+
+ // store pointer into table
+ params_string[ cur_string_indx++ ] = paramstr;
+
+ // submit completed table to registered function
+ if ( --want_params_string == 0 ) {
+ if ( !(*cli_options[ cur_opt_indx ].exec_string)( params_string ) ) {
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+
+// determine whether there are still parameters missing for previous option ---
+//
+PRIVATE
+int OptionParamsPending()
+{
+ int pendingparams = want_params_int + want_params_float + want_params_string;
+
+ if ( pendingparams > 0 ) {
+ MSGOUT( "Parameters missing.\n" );
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+
+// parse a command line option specifier --------------------------------------
+//
+PRIVATE
+int ParseOptionSpecifier( char **argv, int curopt )
+{
+ ASSERT( argv != NULL );
+ ASSERT( *argv != NULL );
+
+ // make sure there are no parameters missing for previous option
+ if ( OptionParamsPending() ) {
+ return FALSE;
+ }
+
+ int optvalid = TRUE;
+
+ // distinguish short and long options via second '-'
+ if ( argv[ curopt ][ 1 ] != '-' ) {
+ optvalid = CheckShortOption( &argv[ curopt ][ 1 ] );
+ } else {
+ optvalid = CheckLongOption( &argv[ curopt ][ 2 ] );
+ }
+
+ return optvalid;
+}
+
+
+// parse a command line option parameter --------------------------------------
+//
+PRIVATE
+int ParseOptionParameter( char **argv, int curopt )
+{
+ ASSERT( argv != NULL );
+ ASSERT( *argv != NULL );
+
+ int optvalid = TRUE;
+
+ // check for parameters
+ if ( want_params_int > 0 ) {
+ optvalid = GetOptionIntParam( argv[ curopt ] );
+ } else if ( want_params_float > 0 ) {
+ optvalid = GetOptionFloatParam( argv[ curopt ] );
+ } else if ( want_params_string > 0 ) {
+ optvalid = GetOptionStringParam( argv[ curopt ] );
+ }
+
+ return optvalid;
+}
+
+
+// parse a command line option that specifies an application ------------------
+//
+PRIVATE
+void CheckApplicationOption( int argc, char **argv )
+{
+ if ( argc < 2 )
+ return;
+
+ // compare with all registered application names
+ for ( int indx = 0; indx < num_app_options; indx++ ) {
+
+ ASSERT( app_options[ indx ].appname != NULL );
+ ASSERT( app_options[ indx ].appmain != NULL );
+
+ if ( strcmp( argv[ 1 ], app_options[ indx ].appname ) == 0 ) {
+
+ // remove appname option from command line and hand over
+ argv[ 1 ] = argv[ 0 ];
+ (*app_options[ indx ].appmain)( argc - 1, argv + 1 );
+ }
+ }
+}
+
+
+// execute all registered command line options (parse command line) -----------
+//
+int OPT_ExecRegisteredOptions( int argc, char **argv )
+{
+ ASSERT( argc > 0 );
+ ASSERT( argv != NULL );
+
+ // if an application option is found this never returns
+ CheckApplicationOption( argc, argv );
+
+ // parse conventional command line options
+ for ( int curopt = 1; curopt < argc; curopt++ ) {
+
+ // check for beginning of new option
+ if ( argv[ curopt ][ 0 ] == '-' ) {
+
+ if ( !ParseOptionSpecifier( argv, curopt ) ) {
+ MSGOUT( "Invalid option supplied: %s.\n", argv[ curopt ] );
+ return FALSE;
+ }
+
+ } else {
+
+ if ( !ParseOptionParameter( argv, curopt ) ) {
+ MSGOUT( "Invalid parameter supplied: %s.\n", argv[ curopt ] );
+ return FALSE;
+ }
+ }
+ }
+
+ // make sure there are no parameters missing for last option
+ if ( OptionParamsPending() ) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
diff --git a/tool_src/makeodt/getopt.h b/tool_src/makeodt/getopt.h
new file mode 100644
index 0000000..9cb29c2
--- /dev/null
+++ b/tool_src/makeodt/getopt.h
@@ -0,0 +1,78 @@
+/*
+ * PARSEC HEADER: e_getopt.h
+ */
+
+#ifndef _E_GETOPT_H_
+#define _E_GETOPT_H_
+
+#include <stdint.h>
+
+
+
+// ----------------------------------------------------------------------------
+//
+#define ASSERT assert
+#define PRIVATE static
+#define PUBLIC
+#define MSGOUT printf
+
+typedef uint8_t byte;
+typedef uint16_t word;
+typedef uint32_t dword;
+
+#ifndef TRUE
+ #define TRUE 1
+#endif
+#ifndef FALSE
+ #define FALSE 0
+#endif
+
+
+
+
+// command line options table entry
+
+struct cli_option_s {
+
+ const char* opt_short;
+ const char* opt_long;
+
+ dword _mksiz32;
+
+ byte _dummy;
+ byte num_int;
+ byte num_float;
+ byte num_string;
+
+ int (*exec_set)();
+ int (*exec_int)(int*);
+ int (*exec_float)(float*);
+ int (*exec_string)(char**);
+};
+
+
+// application name option table entry
+
+struct app_option_s {
+
+ char* appname;
+ void (*appmain)(int,char**);
+};
+
+
+// external functions
+
+int OPT_RegisterSetOption( const char *optshort, const char *optlong, int (*func)() );
+int OPT_RegisterIntOption( char *optshort, const char *optlong, int (*func)(int*) );
+int OPT_RegisterFloatOption( const char *optshort, const char *optlong, int (*func)(float*) );
+int OPT_RegisterStringOption( const char *optshort, const char *optlong, int (*func)(char**) );
+int OPT_RegisterOption( cli_option_s *regopt );
+int OPT_RegisterApplication( char *appname, void (*appmain)(int,char**) );
+
+void OPT_ClearOptions();
+
+int OPT_ExecRegisteredOptions( int argc, char **argv );
+
+
+#endif // _E_GETOPT_H_
+
diff --git a/tool_src/makeodt/makeodt b/tool_src/makeodt/makeodt
new file mode 100755
index 0000000..39591b8
--- /dev/null
+++ b/tool_src/makeodt/makeodt
Binary files differ
diff --git a/tool_src/makeodt/makeodt.cpp b/tool_src/makeodt/makeodt.cpp
new file mode 100644
index 0000000..8b9f296
--- /dev/null
+++ b/tool_src/makeodt/makeodt.cpp
@@ -0,0 +1,633 @@
+/*
+ * makeodt.cpp
+ */
+
+
+// bsplib headers
+#include "BRep.h"
+#include "InputData3D.h"
+#include "OutputData3D.h"
+#include "BspObjectList.h"
+#include "BoundingBox.h"
+#include "ObjectBSPNode.h"
+#include "ObjectBinFormat.h"
+
+#include "getopt.h"
+
+using BspLib::InputData3D;
+using BspLib::BspObjectList;
+using BspLib::Vector3;
+using BspLib::Vertex3;
+using BspLib::ObjectBSPTree;
+
+
+// string constants -----------------------------------------------------------
+//
+static const char options_invalid[] = "\nUse \"-h\" for a list of command line options.\n";
+
+
+// pointer to input data object -----------------------------------------------
+//
+class Scene {
+
+public:
+ Scene() { m_inputscene = NULL; m_objectlist = NULL; m_objbsptree = NULL; }
+ ~Scene() { delete m_objbsptree; delete m_objectlist; }
+
+ void AllocObjectList();
+ void DestroyObjectList();
+
+ void BuildObjectBSPTree();
+
+ void setInput( InputData3D *inp ) { m_inputscene = inp; }
+ InputData3D* getInput() { return m_inputscene; }
+ void deleteInput() { if ( m_inputscene != NULL ) { delete m_inputscene; m_inputscene = NULL; } }
+
+ BspObjectList* getObjectList() { return m_objectlist; }
+
+private:
+ // pointer to input data object
+ BspLib::InputData3D* m_inputscene;
+
+ // object bsp tree (convex subspaces contain entire objects)
+ BspLib::ObjectBSPTree* m_objbsptree;
+
+ // object list
+ BspLib::BspObjectList* m_objectlist;
+};
+
+
+// allocate new objectlist (an already existing list will be destroyed) -------
+//
+void Scene::AllocObjectList()
+{
+ if ( m_objbsptree != NULL ) {
+ delete m_objbsptree;
+ m_objbsptree = NULL;
+ }
+
+ if ( m_objectlist != NULL ) {
+ delete m_objectlist;
+ }
+ m_objectlist = new BspObjectList;
+}
+
+
+// destroy objectlist ---------------------------------------------------------
+//
+void Scene::DestroyObjectList()
+{
+ delete m_objbsptree;
+ m_objbsptree = NULL;
+
+ delete m_objectlist;
+ m_objectlist = NULL;
+}
+
+
+// build a bsp tree of objects from unordered object list ---------------------
+//
+void Scene::BuildObjectBSPTree()
+{
+ if ( m_objectlist != NULL ) {
+ BspLib::BoundingBox *boxlist = m_objectlist->BuildBoundingBoxList();
+ m_objbsptree = new BspLib::ObjectBSPTree;
+ m_objbsptree->InitTree( boxlist ? boxlist->PartitionSpace() : NULL );
+ }
+}
+
+
+// ----------------------------------------------------------------------------
+//
+static Scene* world = NULL;
+
+
+// filename of currently loaded object file -----------------------------------
+//
+static char current_object_file[ PATH_MAX + 1 ] = "";
+
+
+// ----------------------------------------------------------------------------
+//
+static char input_file_name[ PATH_MAX + 1 ] = "";
+
+
+// ----------------------------------------------------------------------------
+//
+static int bspgenopt_actions[] = { 0, 0, 0, 0 };
+static int bspgenopt_outpoptions[] = { 0, 0, 0, 0 };
+static int bspgenopt_policy[] = { 0, 0, 0, 0 };
+static int bspgenopt_samplesize = 0;
+static int bspgenopt_sampletype = 0;
+
+static int bspgeoopt_pregeometry[] = { 0, 0, 0, 0 };
+static int bspgeoopt_postgeometry[] = { 0, 0, 0, 0 };
+static int bspgeoopt_enforceeps[] = { 0, 0, 0, 0 };
+static double bspgeoopt_epsilons[] = { 0.0, 0.0, 0.0, 0.0 };
+
+static int vrmlopt_gen[] = { 0, 0, 0, 0, 0, 0 };
+static int vrmlopt_lod = 0;
+static int vrmlopt_tessellation = 8;
+
+static int mesgopt_mesg[] = { 0, 0, 0, 0, 0 };
+static int mesgopt_misc[] = { 0, 0, 0, 0 };
+static int mesgopt_stat[] = { 0, 0, 0, 0 };
+static int mesgopt_err[] = { 0, 0, 0, 0 };
+
+static int objprocessor_opt[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+
+
+// submit selected bsp compilation options to bsplib --------------------------
+//
+PRIVATE
+void SetBspLibOptions()
+{
+ using namespace BspLib;
+
+ if ( bspgeoopt_enforceeps[ 3 ] ) {
+ EpsAreas::eps_scalarproduct = bspgeoopt_epsilons[ 3 ];
+ EpsAreas::eps_planethickness = bspgeoopt_epsilons[ 3 ];
+// EpsAreas::eps_vanishdenominator = bspgeoopt_epsilons[ 3 ];
+// EpsAreas::eps_vanishcomponent = bspgeoopt_epsilons[ 3 ];
+ }
+ if ( bspgeoopt_enforceeps[ 2 ] ) {
+ EpsAreas::eps_pointonlineseg = bspgeoopt_epsilons[ 2 ];
+ }
+ if ( bspgeoopt_enforceeps[ 1 ] ) {
+ EpsAreas::eps_vertexmergearea = bspgeoopt_epsilons[ 1 ];
+ }
+
+ static int splittercrit_values[] = {
+ Polygon::SPLITTERCRIT_FIRST_POLY,
+ Polygon::SPLITTERCRIT_SAMPLE_FIRST_N,
+ Polygon::SPLITTERCRIT_SAMPLE_ALL,
+ Polygon::SPLITTERCRIT_RANDOM_SAMPLE
+ };
+
+ InputData3D::EnableRGBConversion( bspgenopt_actions[ 1 ] );
+ InputData3D::EnableMaximumExtent( bspgeoopt_pregeometry[ 3 ], bspgeoopt_epsilons[ 0 ] );
+ InputData3D::EnableScaleFactors( bspgenopt_actions[ 2 ] );
+ InputData3D::EnableAxesChange( bspgenopt_actions[ 3 ] );
+ InputData3D::EnableAllowNGons( !bspgenopt_policy[ 1 ] );
+
+ Polygon::setSplitterSelection( splittercrit_values[ bspgenopt_sampletype ] );
+ Polygon::setSampleSize( bspgenopt_samplesize );
+ Polygon::setTriangulationFlag( bspgenopt_policy[ 3 ] );
+
+ BspObject::setEliminateDoubletsOnMergeFlag( bspgenopt_policy[ 2 ] );
+
+ int msgflags = Polygon::MESSAGEMASK_DISPLAY_ALL & ~Polygon::MESSAGE_CHECKING_POLYGON_PLANES;
+ if ( !mesgopt_mesg[ 0 ] )
+ msgflags &= ~( Polygon::MESSAGE_NEW_SPLITVERTEX |
+ Polygon::MESSAGE_REUSING_SPLITVERTEX |
+ Polygon::MESSAGE_TRACEVERTEX_INSERTED );
+ if ( !mesgopt_mesg[ 1 ] )
+ msgflags &= ~Polygon::MESSAGE_SPLITTING_QUADRILATERAL;
+ if ( !mesgopt_mesg[ 2 ] )
+ msgflags &= ~( Polygon::MESSAGE_STARTVERTEX_IN_SPLITTER_PLANE | Polygon::MESSAGE_VERTEX_IN_SPLITTER_PLANE );
+ if ( !mesgopt_mesg[ 3 ] )
+ msgflags &= ~Polygon::MESSAGE_INVOCATION;
+ if ( !mesgopt_mesg[ 4 ] )
+ msgflags &= ~Polygon::MESSAGE_SPLITTING_POLYGON;
+ Polygon::setDisplayMessagesFlag( msgflags );
+
+ BRep::setTriangulation( vrmlopt_gen[ 2 ] );
+ BRep::setMaterialFlag( vrmlopt_gen[ 4 ] );
+ BRep::setMirrorTextureVFlag( vrmlopt_gen[ 5 ] );
+ BRep::setTessellation( vrmlopt_tessellation );
+}
+
+
+// set global bsplib options to user specified values -------------------------
+//
+PRIVATE
+void InitBspLibOptions()
+{
+ bspgeoopt_epsilons[ 3 ] = BspLib::EpsAreas::eps_planethickness;
+ bspgeoopt_epsilons[ 2 ] = BspLib::EpsAreas::eps_pointonlineseg;
+ bspgeoopt_epsilons[ 1 ] = BspLib::EpsAreas::eps_vertexmergearea;
+
+ bspgeoopt_epsilons[ 0 ] = 600.0;// maximum extents to force
+
+ bspgeoopt_enforceeps[ 0 ] = 0; // use default epsilon areas
+ bspgeoopt_enforceeps[ 1 ] = 0;
+ bspgeoopt_enforceeps[ 2 ] = 0;
+ bspgeoopt_enforceeps[ 3 ] = 0;
+
+ bspgenopt_actions[ 1 ] = 0; // don't convert color indexes to rgb triplets
+ bspgenopt_actions[ 2 ] = 0; // don't apply specified object scale factors
+ bspgenopt_actions[ 3 ] = 0; // don't apply axes mapping
+
+ bspgenopt_policy[ 0 ] = 1; // always normalize normal vectors
+ bspgenopt_policy[ 1 ] = 1; // allow only triangles and quadrilaterals
+ bspgenopt_policy[ 2 ] = 1; // eliminate vertex doublets on object merge
+ bspgenopt_policy[ 3 ] = 0; // don't always triangulate
+
+ vrmlopt_lod = 0;
+ vrmlopt_tessellation = 4; // set vrml tessellation resolution per PI/2
+ vrmlopt_gen[ 1 ] = 1; // tessellate vrml primitives
+ vrmlopt_gen[ 2 ] = 0; // triangulate vrml objects
+ vrmlopt_gen[ 3 ] = 1; // build bounding box hierarchy
+ vrmlopt_gen[ 4 ] = 0; // don't use full material specification
+ vrmlopt_gen[ 5 ] = 1; // mirror texture v axis
+
+ mesgopt_misc[ 0 ] = 0; // don't create messagelog
+ mesgopt_misc[ 1 ] = 0; // don't create output window
+
+ bspgenopt_samplesize = 20; // set n=20 (sample size)
+ bspgenopt_sampletype = 1; // sample first n polygons
+
+ bspgeoopt_pregeometry[ 0 ] = 0; // n/a
+ bspgeoopt_pregeometry[ 1 ] = 0; // n/a
+ bspgeoopt_pregeometry[ 2 ] = 1; // check planes of faces
+ bspgeoopt_pregeometry[ 3 ] = 1; // enforce maximum object extents
+
+ bspgeoopt_postgeometry[ 0 ] = 0; // don't insert trace vertices
+ bspgeoopt_postgeometry[ 1 ] = 0; // check for multiple vertices
+ bspgeoopt_postgeometry[ 2 ] = 0; // don't calc node bounding boxes
+ bspgeoopt_postgeometry[ 3 ] = 0; // don't calc explicit separator planes
+
+ mesgopt_mesg[ 0 ] = 1; // show message on vertex insertion
+ mesgopt_mesg[ 1 ] = 1; // show message on triangulation of quadrilateral
+ mesgopt_mesg[ 2 ] = 0; // don't show message on vertex contained in splitter plane
+ mesgopt_mesg[ 3 ] = 0; // don't show message on every call of PartitionSpace()
+ mesgopt_mesg[ 4 ] = 1; // show message on splitting of polygon
+
+ mesgopt_stat[ 0 ] = 0; // don't display basic statistics
+ mesgopt_stat[ 1 ] = 0; // don't display detailed statistics
+
+ bspgenopt_outpoptions[ 0 ] = 1; // write normal vectors
+ bspgenopt_outpoptions[ 1 ] = 1; // write palette info
+ bspgenopt_outpoptions[ 2 ] = 0; // don't write compiler info
+ bspgenopt_outpoptions[ 3 ] = 0; // don't write viewer info
+
+ mesgopt_err[ 0 ] = 1; // display error message on non-convex polygon
+
+ SetBspLibOptions(); // pass options to bsplib
+}
+
+
+
+
+
+// check if bsp tree is available for current scene ---------------------------
+//
+int BspTreeAvailable()
+{
+ BspLib::BspObjectList *objectlist = world->getObjectList();
+ BspLib::BspObject *obj = objectlist ? objectlist->getListHead() : NULL;
+ return ( obj ? obj->BspTreeAvailable() : 0 );
+}
+
+
+// merge entire object list into single object --------------------------------
+//
+void MergeListIntoSingleObject()
+{
+ if ( world->getObjectList() ) {
+
+ if ( !BspTreeAvailable() ) {
+
+ // configure BspLib
+ SetBspLibOptions();
+
+ // do actual merge
+ world->getObjectList()->CollapseObjectList();
+ MSGOUT( "Objectlist merged into single object.\n" );
+
+ } else {
+
+ MSGOUT( "Objects already bsp-compiled: Merging not possible.\n" );
+ }
+
+ } else {
+
+ MSGOUT( "No objects to merge.\n" );
+ }
+}
+
+
+// ----------------------------------------------------------------------------
+//
+enum {
+
+ OUTPUT_FORMAT_SINGLE,
+ OUTPUT_FORMAT_ODT,
+ OUTPUT_FORMAT_OD2,
+};
+
+
+
+static int output_format = OUTPUT_FORMAT_OD2;
+static int bsp_compile_done = FALSE;
+
+
+static int critical_bsplib_error = 0;
+
+
+// handle critical error encountered within bsplib ----------------------------
+//
+PRIVATE
+int CriticalBspLibError( int flags )
+{
+/*
+ // close message log if enabled
+ if ( messagelog_fp != NULL ) {
+ fclose( messagelog_fp );
+ messagelog_fp = NULL;
+ }
+*/
+ if ( ( flags & BspLib::SystemIO::CRITERR_ALLOW_RET ) == 0 ) {
+ return 0;
+ } else {
+ critical_bsplib_error = 1;
+ return 1;
+ }
+}
+
+
+// close an open data file ----------------------------------------------------
+//
+PRIVATE
+void CloseDataFile()
+{
+ // reset compile done flag
+ bsp_compile_done = FALSE;
+
+ // delete old InputData3D object
+ world->deleteInput();
+
+ // destroy old object list
+ world->DestroyObjectList();
+
+ // no current file name
+ *current_object_file = 0;
+}
+
+
+// read data file, parse it, and establish scene graph in memory --------------
+//
+PRIVATE
+int ReadDataFile( char *fullfname, char *fname )
+{
+ // delete old InputData3D object
+ world->deleteInput();
+
+ // allocate new BspObjectList (delete old)
+ world->AllocObjectList();
+
+ // configure BspLib
+ SetBspLibOptions();
+
+ // create input data
+ BspObjectList *objectlist = world->getObjectList();
+ world->setInput( new BspLib::InputData3D( *objectlist, fullfname ) );
+
+ // process already parsed input if valid
+ if ( !world->getInput()->InputDataValid() ) {
+ CloseDataFile();
+ return FALSE;
+ }
+
+ // calculate plane normals if not already valid (read from input file)
+ objectlist->ProcessObjects( BspObjectList::CALC_PLANE_NORMALS );
+
+ // check if bsp tree read from file and update caption accordingly
+ int anybsp = objectlist->BspTreeAvailable();
+// Global::UpdateCaption( hwnd, fname, anybsp ?
+// Global::CAPTION_BSPCOMPILED : Global::CAPTION_NOBSPAVAILABLE );
+
+ // check if only flat tree available
+ if ( anybsp && !objectlist->BSPTreeAvailable() ) {
+ // if only flat bsp tree available build linked tree from it
+ objectlist->ProcessObjects( BspObjectList::BUILD_FROM_FLAT );
+ }
+
+// if ( !anybsp ) {
+// world.setUseBSP( FALSE );
+// CheckRenderingMenuItems( GetMenu( hwndMain ) );
+// }
+
+ // set current object file name
+ strcpy( current_object_file, fname );
+
+ return TRUE;
+}
+
+
+// ----------------------------------------------------------------------------
+//
+PRIVATE
+int OpenInput()
+{
+ // reset compile done flag
+ bsp_compile_done = FALSE;
+
+ // register callbacks with bsplib
+ critical_bsplib_error = 0;
+ BspLib::SystemIO::SetCriticalErrorCallback( CriticalBspLibError );
+
+ // read in data file
+ int rc = ReadDataFile( input_file_name, input_file_name );
+
+ // unregister callbacks
+ BspLib::SystemIO::SetCriticalErrorCallback( NULL );
+
+ return rc;
+}
+
+
+// ----------------------------------------------------------------------------
+//
+PRIVATE
+void SaveOutput()
+{
+ if ( !world->getObjectList() ) {
+ MSGOUT( "No objects to save.\n" );
+ return;
+ }
+
+ char *outname = new char[ PATH_MAX + 1 ];
+ strcpy( outname, current_object_file );
+ int n = strlen( outname );
+ while ( ( n > 0 ) && ( outname[ n ] != '.' ) )
+ --n;
+ strcpy( &outname[ n ], ".od2" );
+
+ // configure BspLib
+ SetBspLibOptions();
+
+ // check if binary output is desired
+ if ( ( output_format == OUTPUT_FORMAT_ODT ) ||
+ ( output_format == OUTPUT_FORMAT_OD2 ) ) {
+
+ if ( BspTreeAvailable() ) {
+
+ // do direct binary output of ODT or OD2 file containing BSP tree
+ BspObjectList *objectlist = world->getObjectList();
+ BspLib::ObjectBinFormat outobj( *objectlist->getListHead() );
+
+ int format = ( output_format == OUTPUT_FORMAT_OD2 ) ?
+ BspLib::ObjectBinFormat::BINFORMAT_OD2 : BspLib::ObjectBinFormat::BINFORMAT_ODT;
+ outobj.WriteDataToFile( outname, format );
+
+ } else {
+
+ if ( output_format == OUTPUT_FORMAT_OD2 ) {
+
+ // do direct binary output of OD2 file without BSP tree
+ BspObjectList *objectlist = world->getObjectList();
+ BspLib::ObjectBinFormat outobj( *objectlist->getListHead() );
+ outobj.WriteDataToFile( outname, BspLib::ObjectBinFormat::BINFORMAT_OD2 );
+ }
+ }
+
+ } else {
+
+ // do output in BspLib's singleoutput formats
+ if ( output_format == OUTPUT_FORMAT_SINGLE ) {
+
+ int format;
+ if ( BspTreeAvailable() ) {
+ format = BspLib::IOData3D::BSP_FORMAT_1_1;
+ } else {
+ format = BspLib::IOData3D::AOD_FORMAT_1_1;
+ // merge all objects in list into single object
+ world->getObjectList()->CollapseObjectList();
+ }
+
+ // write output file
+ if ( world->getInput() != NULL ) {
+ world->getInput()->setFileName( outname );
+ BspLib::OutputData3D outputdata( *world->getInput(), format );
+ }
+ }
+ }
+
+ delete outname;
+}
+
+
+
+
+
+// ----------------------------------------------------------------------------
+//
+
+
+
+// ----------------------------------------------------------------------------
+//
+PRIVATE
+int OptSetInputFile( char **filename )
+{
+ char *name = filename[ 0 ];
+
+ strcpy( input_file_name, name );
+
+ return TRUE;
+}
+
+// ----------------------------------------------------------------------------
+//
+PRIVATE
+int OptSetObjectScale( float *scale )
+{
+ bspgeoopt_epsilons[ 0 ] = *scale;
+
+ return TRUE;
+}
+
+
+// register command line options ----------------------------------------------
+//
+PRIVATE
+void RegisterOptions()
+{
+ OPT_RegisterStringOption( "i", "input", OptSetInputFile );
+ OPT_RegisterFloatOption( "s", "scale", OptSetObjectScale );
+}
+
+
+// ----------------------------------------------------------------------------
+//
+void msg_callback( const char *msg )
+{
+ printf( "%s", msg );
+// printf( "\n" );
+}
+
+
+// ----------------------------------------------------------------------------
+//
+PRIVATE
+int InitMakeODT()
+{
+ BspLib::SystemIO::SetProgramName( "makeodt" );
+
+#if defined ( _WINDOWS ) || defined ( WIN32 )
+ BspLib::SystemIO::SetMainWindowHandle( NULL );
+#endif
+
+ BspLib::SystemIO::SetInfoMessageCallback( msg_callback );
+ BspLib::SystemIO::SetErrorMessageCallback( msg_callback );
+
+ InitBspLibOptions();
+
+ return TRUE;
+}
+
+
+// ----------------------------------------------------------------------------
+//
+PRIVATE
+void ConvertObject()
+{
+ // create global scene
+ world = new Scene;
+
+ // open, convert, save
+ if ( OpenInput() ) {
+ MergeListIntoSingleObject();
+ SaveOutput();
+ }
+
+ // delete global scene
+ delete world;
+ world = NULL;
+}
+
+
+// main -----------------------------------------------------------------------
+//
+int main( int argc, char **argv )
+{
+ // init application
+ if ( !InitMakeODT() ) {
+ return EXIT_FAILURE;
+ }
+
+ // register command line options
+ RegisterOptions();
+
+ // exec all registered command line options
+ if ( !OPT_ExecRegisteredOptions( argc, argv ) ) {
+ MSGOUT( options_invalid );
+ exit( EXIT_FAILURE );
+ }
+
+ // set modified options
+ SetBspLibOptions();
+
+ // check for file name
+ if ( input_file_name[ 0 ] == 0 ) {
+ MSGOUT( "No file name specified.\n" );
+ exit( EXIT_FAILURE );
+ }
+
+ // do object conversion
+ ConvertObject();
+
+ return EXIT_SUCCESS;
+}
+
diff --git a/tool_src/makeodt/makeodt.h b/tool_src/makeodt/makeodt.h
new file mode 100644
index 0000000..62fad85
--- /dev/null
+++ b/tool_src/makeodt/makeodt.h
@@ -0,0 +1,40 @@
+/*
+ * makeodt.h
+ */
+
+#ifndef _MAKEODT_H_
+#define _MAKEODT_H_
+
+
+// windows specific includes
+#ifdef _MSC_VER
+
+ #include <windows.h>
+ #include <commctrl.h>
+ #include <commdlg.h>
+ #include <afxres.h>
+ #include <richedit.h>
+ #include "resource.h"
+
+ #define PATH_MAX _MAX_PATH
+
+#endif
+
+// opengl specific includes
+//#include <gl\gl.h>
+//#include <gl\glu.h>
+
+
+// epsilon area for width of "infinitely thin" plane
+#define SCALAR_EPS 0.00000005
+
+// epsilon area for point on line determination
+//#define POINT_ON_LINESEG_EPS 0.00000001
+#define POINT_ON_LINESEG_EPS 0.02
+
+// epsilon area for merging of vertices
+#define VERTEX_MERGE_EPS 0.00000005
+
+
+
+#endif // _MAKEODT_H_
diff --git a/tool_src/makeodt/makeodt.sln b/tool_src/makeodt/makeodt.sln
new file mode 100755
index 0000000..f221937
--- /dev/null
+++ b/tool_src/makeodt/makeodt.sln
@@ -0,0 +1,54 @@
+Microsoft Visual Studio Solution File, Format Version 8.00
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "BspLib", "..\BspLib\BspLib.vcproj", "{F043C82B-28EC-4BA9-8C68-33708D9E3702}"
+ ProjectSection(ProjectDependencies) = postProject
+ {7B6BE4D0-375E-4615-BBC6-426AD251B41C} = {7B6BE4D0-375E-4615-BBC6-426AD251B41C}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "QvLib", "..\QvLib\QvLib.vcproj", "{7B6BE4D0-375E-4615-BBC6-426AD251B41C}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "makeodt", "makeodt.vcproj", "{17796602-07C1-47DB-8D8E-C6E0125B2AD7}"
+ ProjectSection(ProjectDependencies) = postProject
+ {F043C82B-28EC-4BA9-8C68-33708D9E3702} = {F043C82B-28EC-4BA9-8C68-33708D9E3702}
+ EndProjectSection
+EndProject
+Global
+ GlobalSection(SourceCodeControl) = preSolution
+ SccNumberOfProjects = 3
+ SccProjectUniqueName0 = ..\\BspLib\\BspLib.vcproj
+ SccProjectName0 = \u0022$/ParsecTools/BspLib\u0022,\u0020KUFAAAAA
+ SccLocalPath0 = ..\\BspLib
+ SccProvider0 = MSSCCI:Perforce\u0020SCM
+ SccProjectUniqueName1 = ..\\QvLib\\QvLib.vcproj
+ SccProjectName1 = \u0022$/ParsecTools/QvLib\u0022
+ SccLocalPath1 = ..\\QvLib
+ SccProvider1 = MSSCCI:Perforce\u0020SCM
+ SccProjectUniqueName2 = makeodt.vcproj
+ SccProjectName2 = \u0022$/ParsecTools/makeodt\u0022,\u0020BUGAAAAA
+ SccLocalPath2 = .
+ SccProvider2 = MSSCCI:Perforce\u0020SCM
+ EndGlobalSection
+ GlobalSection(SolutionConfiguration) = preSolution
+ Debug = Debug
+ Release = Release
+ EndGlobalSection
+ GlobalSection(ProjectConfiguration) = postSolution
+ {F043C82B-28EC-4BA9-8C68-33708D9E3702}.Debug.ActiveCfg = Debug|Win32
+ {F043C82B-28EC-4BA9-8C68-33708D9E3702}.Debug.Build.0 = Debug|Win32
+ {F043C82B-28EC-4BA9-8C68-33708D9E3702}.Release.ActiveCfg = Release|Win32
+ {F043C82B-28EC-4BA9-8C68-33708D9E3702}.Release.Build.0 = Release|Win32
+ {7B6BE4D0-375E-4615-BBC6-426AD251B41C}.Debug.ActiveCfg = Debug|Win32
+ {7B6BE4D0-375E-4615-BBC6-426AD251B41C}.Debug.Build.0 = Debug|Win32
+ {7B6BE4D0-375E-4615-BBC6-426AD251B41C}.Release.ActiveCfg = Release|Win32
+ {7B6BE4D0-375E-4615-BBC6-426AD251B41C}.Release.Build.0 = Release|Win32
+ {17796602-07C1-47DB-8D8E-C6E0125B2AD7}.Debug.ActiveCfg = Debug|Win32
+ {17796602-07C1-47DB-8D8E-C6E0125B2AD7}.Debug.Build.0 = Debug|Win32
+ {17796602-07C1-47DB-8D8E-C6E0125B2AD7}.Release.ActiveCfg = Release|Win32
+ {17796602-07C1-47DB-8D8E-C6E0125B2AD7}.Release.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ EndGlobalSection
+ GlobalSection(ExtensibilityAddIns) = postSolution
+ EndGlobalSection
+EndGlobal
diff --git a/tool_src/makeodt/makeodt.vcproj b/tool_src/makeodt/makeodt.vcproj
new file mode 100755
index 0000000..20b3a3b
--- /dev/null
+++ b/tool_src/makeodt/makeodt.vcproj
@@ -0,0 +1,195 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="7.10"
+ Name="makeodt"
+ SccProjectName="&quot;$/ParsecTools/makeodt&quot;, BUGAAAAA"
+ SccLocalPath=".">
+ <Platforms>
+ <Platform
+ Name="Win32"/>
+ </Platforms>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory=".\Debug"
+ IntermediateDirectory=".\Debug"
+ ConfigurationType="1"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="FALSE"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="..\BspLib;..\QvLib"
+ PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="5"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderFile=".\Debug/makeodt.pch"
+ AssemblerListingLocation=".\Debug/"
+ ObjectFile=".\Debug/"
+ ProgramDataBaseFileName=".\Debug/"
+ BrowseInformation="1"
+ WarningLevel="3"
+ SuppressStartupBanner="TRUE"
+ DebugInformationFormat="4"
+ CompileAs="2"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="..\bsplib\debug\bsplib.lib opengl32.lib glu32.lib comctl32.lib odbc32.lib odbccp32.lib"
+ OutputFile=".\Debug/makeodt.exe"
+ LinkIncremental="1"
+ SuppressStartupBanner="TRUE"
+ GenerateDebugInformation="TRUE"
+ ProgramDatabaseFile=".\Debug/makeodt.pdb"
+ SubSystem="1"
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"
+ TypeLibraryName=".\Debug/makeodt.tlb"
+ HeaderFileName=""/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG"
+ Culture="1033"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory=".\Release"
+ IntermediateDirectory=".\Release"
+ ConfigurationType="1"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="FALSE"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ InlineFunctionExpansion="1"
+ AdditionalIncludeDirectories="..\BspLib;..\QvLib"
+ PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
+ StringPooling="TRUE"
+ RuntimeLibrary="4"
+ EnableFunctionLevelLinking="TRUE"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderFile=".\Release/makeodt.pch"
+ AssemblerListingLocation=".\Release/"
+ ObjectFile=".\Release/"
+ ProgramDataBaseFileName=".\Release/"
+ WarningLevel="3"
+ SuppressStartupBanner="TRUE"
+ CompileAs="2"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="..\bsplib\release\bsplib.lib opengl32.lib glu32.lib comctl32.lib user 32.lib odbc32.lib odbccp32.lib"
+ OutputFile=".\Release/makeodt.exe"
+ LinkIncremental="1"
+ SuppressStartupBanner="TRUE"
+ ProgramDatabaseFile=".\Release/makeodt.pdb"
+ SubSystem="1"
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"
+ TypeLibraryName=".\Release/makeodt.tlb"
+ HeaderFileName=""/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG"
+ Culture="1033"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <File
+ RelativePath="getopt.c">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BasicRuntimeChecks="3"
+ BrowseInformation="1"
+ CompileAs="2"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ CompileAs="2"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="getopt.h">
+ </File>
+ <File
+ RelativePath="makeodt.c">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BasicRuntimeChecks="3"
+ BrowseInformation="1"
+ CompileAs="2"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ CompileAs="2"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="makeodt.h">
+ </File>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/tool_src/makeodt/makeodt.vcxproj b/tool_src/makeodt/makeodt.vcxproj
new file mode 100755
index 0000000..c3ceeb9
--- /dev/null
+++ b/tool_src/makeodt/makeodt.vcxproj
@@ -0,0 +1,159 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <SccProjectName>"$/ParsecTools/makeodt", BUGAAAAA</SccProjectName>
+ <SccLocalPath>.</SccLocalPath>
+ <ProjectGuid>{F98D4CB3-A9E1-449B-9D43-E09F25A50DAF}</ProjectGuid>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <PlatformToolset>v110</PlatformToolset>
+ <UseOfMfc>false</UseOfMfc>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <PlatformToolset>v110</PlatformToolset>
+ <UseOfMfc>false</UseOfMfc>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <_ProjectFileVersion>11.0.50727.1</_ProjectFileVersion>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <OutDir>.\Debug\</OutDir>
+ <IntDir>.\Debug\</IntDir>
+ <LinkIncremental>false</LinkIncremental>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <OutDir>.\Release\</OutDir>
+ <IntDir>.\Release\</IntDir>
+ <LinkIncremental>false</LinkIncremental>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\BspLib;..\QvLib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+ <PrecompiledHeader />
+ <PrecompiledHeaderOutputFile>.\Debug/makeodt.pch</PrecompiledHeaderOutputFile>
+ <AssemblerListingLocation>.\Debug/</AssemblerListingLocation>
+ <ObjectFileName>.\Debug/</ObjectFileName>
+ <ProgramDataBaseFileName>.\Debug/</ProgramDataBaseFileName>
+ <BrowseInformation>true</BrowseInformation>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
+ <CompileAs>CompileAsCpp</CompileAs>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>..\bsplib\debug\bsplib.lib;opengl32.lib;glu32.lib;comctl32.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>.\Debug/makeodt.exe</OutputFile>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>.\Debug/makeodt.pdb</ProgramDatabaseFile>
+ <SubSystem>Console</SubSystem>
+ <TargetMachine>MachineX86</TargetMachine>
+ </Link>
+ <Midl>
+ <TypeLibraryName>.\Debug/makeodt.tlb</TypeLibraryName>
+ <HeaderFileName />
+ </Midl>
+ <ResourceCompile>
+ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Culture>0x0409</Culture>
+ </ResourceCompile>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <Optimization>MaxSpeed</Optimization>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <AdditionalIncludeDirectories>..\BspLib;..\QvLib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeader />
+ <PrecompiledHeaderOutputFile>.\Release/makeodt.pch</PrecompiledHeaderOutputFile>
+ <AssemblerListingLocation>.\Release/</AssemblerListingLocation>
+ <ObjectFileName>.\Release/</ObjectFileName>
+ <ProgramDataBaseFileName>.\Release/</ProgramDataBaseFileName>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <CompileAs>CompileAsCpp</CompileAs>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>..\bsplib\release\bsplib.lib;..\qvlib\release\qvlib.lib;opengl32.lib;glu32.lib;comctl32.lib;user32.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>.\Release/makeodt.exe</OutputFile>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <ProgramDatabaseFile>.\Release/makeodt.pdb</ProgramDatabaseFile>
+ <SubSystem>Console</SubSystem>
+ <TargetMachine>MachineX86</TargetMachine>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ </Link>
+ <Midl>
+ <TypeLibraryName>.\Release/makeodt.tlb</TypeLibraryName>
+ <HeaderFileName />
+ </Midl>
+ <ResourceCompile>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Culture>0x0409</Culture>
+ </ResourceCompile>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="getopt.c">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
+ <CompileAs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">CompileAsCpp</CompileAs>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ <CompileAs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">CompileAsCpp</CompileAs>
+ </ClCompile>
+ <ClCompile Include="makeodt.c">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
+ <CompileAs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">CompileAsCpp</CompileAs>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ <CompileAs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">CompileAsCpp</CompileAs>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="getopt.h" />
+ <ClInclude Include="makeodt.h" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\BspLib\BspLib.vcxproj">
+ <Project>{aa6fab40-a936-486c-9db0-1addffcd4d00}</Project>
+ </ProjectReference>
+ <ProjectReference Include="..\QvLib\QvLib.vcxproj">
+ <Project>{a7e24141-287a-4d83-9c15-8a7edc9a02a2}</Project>
+ </ProjectReference>
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/tool_src/makeodt/meshconv.exe b/tool_src/makeodt/meshconv.exe
new file mode 100755
index 0000000..bfd2b51
--- /dev/null
+++ b/tool_src/makeodt/meshconv.exe
Binary files differ
diff --git a/tool_src/makeodt/planet1.wrl b/tool_src/makeodt/planet1.wrl
new file mode 100755
index 0000000..5724423
--- /dev/null
+++ b/tool_src/makeodt/planet1.wrl
@@ -0,0 +1,396 @@
+#VRML V1.0 ascii
+
+# Blender V249
+
+# 'Switch' is used as a hack, to ensure it is not part of the drawing
+
+Separator {
+Switch {
+ DEF default
+ Material {
+ diffuseColor 0.788235 0.811765 0.690196
+ specularColor 1.000000 1.000000 1.000000
+ shininess 0.500000
+ transparency 0.000000
+ }
+ DEF sphere1_default
+ Separator {
+ Coordinate3 {
+ point [
+ 0.382683 0.000000 0.923880,
+ 0.353553 -0.146447 0.923880,
+ 0.270598 -0.270598 0.923880,
+ 0.146447 -0.353553 0.923880,
+ 0.000000 -0.382683 0.923880,
+ -0.146447 -0.353553 0.923880,
+ -0.270598 -0.270598 0.923880,
+ -0.353553 -0.146447 0.923880,
+ -0.382683 0.000000 0.923880,
+ -0.353553 0.146447 0.923880,
+ -0.270598 0.270598 0.923880,
+ -0.146447 0.353553 0.923880,
+ -0.000000 0.382683 0.923880,
+ 0.146447 0.353553 0.923880,
+ 0.270598 0.270598 0.923880,
+ 0.353553 0.146447 0.923880,
+ 0.707107 0.000000 0.707107,
+ 0.653282 -0.270598 0.707107,
+ 0.500000 -0.500000 0.707107,
+ 0.270598 -0.653282 0.707107,
+ 0.000000 -0.707107 0.707107,
+ -0.270598 -0.653282 0.707107,
+ -0.500000 -0.500000 0.707107,
+ -0.653282 -0.270598 0.707107,
+ -0.707107 -0.000000 0.707107,
+ -0.653282 0.270598 0.707107,
+ -0.500000 0.500000 0.707107,
+ -0.270598 0.653282 0.707107,
+ -0.000000 0.707107 0.707107,
+ 0.270598 0.653282 0.707107,
+ 0.500000 0.500000 0.707107,
+ 0.653282 0.270598 0.707107,
+ 0.923880 0.000000 0.382683,
+ 0.853553 -0.353553 0.382683,
+ 0.653282 -0.653282 0.382683,
+ 0.353553 -0.853553 0.382683,
+ 0.000000 -0.923880 0.382683,
+ -0.353553 -0.853553 0.382683,
+ -0.653282 -0.653282 0.382683,
+ -0.853553 -0.353553 0.382683,
+ -0.923880 -0.000000 0.382683,
+ -0.853553 0.353553 0.382683,
+ -0.653282 0.653282 0.382683,
+ -0.353553 0.853553 0.382683,
+ -0.000000 0.923880 0.382683,
+ 0.353553 0.853553 0.382683,
+ 0.653282 0.653282 0.382683,
+ 0.853553 0.353553 0.382683,
+ 1.000000 0.000000 0.000000,
+ 0.923880 -0.382683 0.000000,
+ 0.707107 -0.707107 0.000000,
+ 0.382683 -0.923880 0.000000,
+ 0.000000 -1.000000 0.000000,
+ -0.382683 -0.923880 0.000000,
+ -0.707107 -0.707107 0.000000,
+ -0.923880 -0.382683 0.000000,
+ -1.000000 -0.000000 0.000000,
+ -0.923880 0.382683 0.000000,
+ -0.707107 0.707107 0.000000,
+ -0.382683 0.923880 0.000000,
+ -0.000000 1.000000 0.000000,
+ 0.382683 0.923880 0.000000,
+ 0.707107 0.707107 0.000000,
+ 0.923880 0.382683 0.000000,
+ 0.923880 -0.000000 -0.382683,
+ 0.853553 -0.353553 -0.382683,
+ 0.653282 -0.653282 -0.382683,
+ 0.353553 -0.853553 -0.382683,
+ 0.000000 -0.923880 -0.382683,
+ -0.353553 -0.853553 -0.382683,
+ -0.653282 -0.653282 -0.382683,
+ -0.853553 -0.353553 -0.382683,
+ -0.923880 -0.000000 -0.382683,
+ -0.853553 0.353553 -0.382683,
+ -0.653282 0.653282 -0.382683,
+ -0.353553 0.853553 -0.382683,
+ -0.000000 0.923880 -0.382683,
+ 0.353553 0.853553 -0.382683,
+ 0.653282 0.653282 -0.382683,
+ 0.853553 0.353553 -0.382683,
+ 0.707107 -0.000000 -0.707107,
+ 0.653282 -0.270598 -0.707107,
+ 0.500000 -0.500000 -0.707107,
+ 0.270598 -0.653282 -0.707107,
+ 0.000000 -0.707107 -0.707107,
+ -0.270598 -0.653282 -0.707107,
+ -0.500000 -0.500000 -0.707107,
+ -0.653282 -0.270598 -0.707107,
+ -0.707107 -0.000000 -0.707107,
+ -0.653282 0.270598 -0.707107,
+ -0.500000 0.500000 -0.707107,
+ -0.270598 0.653282 -0.707107,
+ -0.000000 0.707107 -0.707107,
+ 0.270598 0.653282 -0.707107,
+ 0.500000 0.500000 -0.707107,
+ 0.653282 0.270598 -0.707107,
+ 0.382683 -0.000000 -0.923880,
+ 0.353553 -0.146447 -0.923880,
+ 0.270598 -0.270598 -0.923880,
+ 0.146447 -0.353553 -0.923880,
+ 0.000000 -0.382683 -0.923880,
+ -0.146447 -0.353553 -0.923880,
+ -0.270598 -0.270598 -0.923880,
+ -0.353553 -0.146447 -0.923880,
+ -0.382683 -0.000000 -0.923880,
+ -0.353553 0.146447 -0.923880,
+ -0.270598 0.270598 -0.923880,
+ -0.146447 0.353553 -0.923880,
+ -0.000000 0.382683 -0.923880,
+ 0.146447 0.353553 -0.923880,
+ 0.270598 0.270598 -0.923880,
+ 0.353553 0.146447 -0.923880,
+ 0.000000 0.000000 1.000000,
+ 0.000000 -0.000000 -1.000000,
+ ]
+ }
+ USE default
+
+ IndexedFaceSet {
+ coordIndex [
+ 0, 112, 1, -1,
+ 1, 112, 2, -1,
+ 2, 112, 3, -1,
+ 3, 112, 4, -1,
+ 4, 112, 5, -1,
+ 5, 112, 6, -1,
+ 6, 112, 7, -1,
+ 7, 112, 8, -1,
+ 8, 112, 9, -1,
+ 9, 112, 10, -1,
+ 10, 112, 11, -1,
+ 11, 112, 12, -1,
+ 12, 112, 13, -1,
+ 13, 112, 14, -1,
+ 14, 112, 15, -1,
+ 112, 0, 15, -1,
+ 97, 113, 96, -1,
+ 98, 113, 97, -1,
+ 99, 113, 98, -1,
+ 100, 113, 99, -1,
+ 101, 113, 100, -1,
+ 102, 113, 101, -1,
+ 103, 113, 102, -1,
+ 104, 113, 103, -1,
+ 105, 113, 104, -1,
+ 106, 113, 105, -1,
+ 107, 113, 106, -1,
+ 108, 113, 107, -1,
+ 109, 113, 108, -1,
+ 110, 113, 109, -1,
+ 111, 113, 110, -1,
+ 96, 113, 111, -1,
+ 1, 17, 16, -1,
+ 16, 0, 1, -1,
+ 2, 18, 17, -1,
+ 17, 1, 2, -1,
+ 19, 18, 2, -1,
+ 2, 3, 19, -1,
+ 20, 19, 3, -1,
+ 3, 4, 20, -1,
+ 5, 21, 20, -1,
+ 5, 20, 4, -1,
+ 6, 22, 21, -1,
+ 6, 21, 5, -1,
+ 23, 22, 6, -1,
+ 6, 7, 23, -1,
+ 24, 23, 7, -1,
+ 7, 8, 24, -1,
+ 9, 25, 24, -1,
+ 9, 24, 8, -1,
+ 10, 26, 25, -1,
+ 10, 25, 9, -1,
+ 11, 27, 10, -1,
+ 27, 26, 10, -1,
+ 12, 28, 11, -1,
+ 28, 27, 11, -1,
+ 13, 29, 12, -1,
+ 29, 28, 12, -1,
+ 14, 30, 29, -1,
+ 29, 13, 14, -1,
+ 15, 31, 14, -1,
+ 31, 30, 14, -1,
+ 0, 16, 15, -1,
+ 16, 31, 15, -1,
+ 17, 33, 32, -1,
+ 32, 16, 17, -1,
+ 18, 34, 33, -1,
+ 33, 17, 18, -1,
+ 35, 34, 18, -1,
+ 18, 19, 35, -1,
+ 20, 36, 35, -1,
+ 20, 35, 19, -1,
+ 21, 37, 36, -1,
+ 21, 36, 20, -1,
+ 22, 38, 37, -1,
+ 22, 37, 21, -1,
+ 39, 38, 22, -1,
+ 22, 23, 39, -1,
+ 40, 39, 23, -1,
+ 23, 24, 40, -1,
+ 25, 41, 40, -1,
+ 25, 40, 24, -1,
+ 26, 42, 41, -1,
+ 26, 41, 25, -1,
+ 27, 43, 26, -1,
+ 43, 42, 26, -1,
+ 28, 44, 27, -1,
+ 44, 43, 27, -1,
+ 29, 45, 28, -1,
+ 45, 44, 28, -1,
+ 30, 46, 45, -1,
+ 45, 29, 30, -1,
+ 31, 47, 30, -1,
+ 47, 46, 30, -1,
+ 16, 32, 31, -1,
+ 32, 47, 31, -1,
+ 33, 49, 32, -1,
+ 49, 48, 32, -1,
+ 34, 50, 33, -1,
+ 50, 49, 33, -1,
+ 35, 51, 34, -1,
+ 51, 50, 34, -1,
+ 36, 52, 35, -1,
+ 52, 51, 35, -1,
+ 37, 53, 36, -1,
+ 53, 52, 36, -1,
+ 38, 54, 37, -1,
+ 54, 53, 37, -1,
+ 39, 55, 54, -1,
+ 39, 54, 38, -1,
+ 40, 56, 39, -1,
+ 56, 55, 39, -1,
+ 41, 57, 56, -1,
+ 41, 56, 40, -1,
+ 42, 58, 41, -1,
+ 58, 57, 41, -1,
+ 43, 59, 58, -1,
+ 43, 58, 42, -1,
+ 44, 60, 43, -1,
+ 60, 59, 43, -1,
+ 45, 61, 44, -1,
+ 61, 60, 44, -1,
+ 46, 62, 45, -1,
+ 62, 61, 45, -1,
+ 47, 63, 46, -1,
+ 63, 62, 46, -1,
+ 32, 48, 47, -1,
+ 48, 63, 47, -1,
+ 49, 65, 48, -1,
+ 65, 64, 48, -1,
+ 50, 66, 49, -1,
+ 66, 65, 49, -1,
+ 51, 67, 50, -1,
+ 67, 66, 50, -1,
+ 52, 68, 51, -1,
+ 68, 67, 51, -1,
+ 53, 69, 52, -1,
+ 69, 68, 52, -1,
+ 54, 70, 69, -1,
+ 54, 69, 53, -1,
+ 55, 71, 70, -1,
+ 55, 70, 54, -1,
+ 56, 72, 55, -1,
+ 72, 71, 55, -1,
+ 73, 72, 56, -1,
+ 56, 57, 73, -1,
+ 58, 74, 73, -1,
+ 58, 73, 57, -1,
+ 59, 75, 58, -1,
+ 75, 74, 58, -1,
+ 60, 76, 59, -1,
+ 76, 75, 59, -1,
+ 61, 77, 76, -1,
+ 61, 76, 60, -1,
+ 62, 78, 61, -1,
+ 78, 77, 61, -1,
+ 63, 79, 62, -1,
+ 79, 78, 62, -1,
+ 48, 64, 63, -1,
+ 64, 79, 63, -1,
+ 65, 81, 80, -1,
+ 80, 64, 65, -1,
+ 66, 82, 65, -1,
+ 82, 81, 65, -1,
+ 67, 83, 82, -1,
+ 67, 82, 66, -1,
+ 68, 84, 83, -1,
+ 68, 83, 67, -1,
+ 85, 84, 68, -1,
+ 68, 69, 85, -1,
+ 86, 85, 69, -1,
+ 69, 70, 86, -1,
+ 71, 87, 86, -1,
+ 71, 86, 70, -1,
+ 72, 88, 87, -1,
+ 72, 87, 71, -1,
+ 89, 88, 72, -1,
+ 72, 73, 89, -1,
+ 90, 89, 73, -1,
+ 73, 74, 90, -1,
+ 75, 91, 90, -1,
+ 90, 74, 75, -1,
+ 76, 92, 91, -1,
+ 91, 75, 76, -1,
+ 77, 93, 92, -1,
+ 92, 76, 77, -1,
+ 78, 94, 77, -1,
+ 94, 93, 77, -1,
+ 79, 95, 94, -1,
+ 94, 78, 79, -1,
+ 64, 80, 95, -1,
+ 95, 79, 64, -1,
+ 81, 97, 96, -1,
+ 96, 80, 81, -1,
+ 82, 98, 81, -1,
+ 98, 97, 81, -1,
+ 83, 99, 98, -1,
+ 83, 98, 82, -1,
+ 84, 100, 99, -1,
+ 84, 99, 83, -1,
+ 101, 100, 84, -1,
+ 84, 85, 101, -1,
+ 102, 101, 85, -1,
+ 85, 86, 102, -1,
+ 87, 103, 102, -1,
+ 87, 102, 86, -1,
+ 88, 104, 103, -1,
+ 88, 103, 87, -1,
+ 105, 104, 88, -1,
+ 88, 89, 105, -1,
+ 106, 105, 89, -1,
+ 89, 90, 106, -1,
+ 91, 107, 106, -1,
+ 106, 90, 91, -1,
+ 92, 108, 107, -1,
+ 107, 91, 92, -1,
+ 93, 109, 108, -1,
+ 108, 92, 93, -1,
+ 94, 110, 93, -1,
+ 110, 109, 93, -1,
+ 95, 111, 110, -1,
+ 110, 94, 95, -1,
+ 80, 96, 111, -1,
+ 111, 95, 80, -1,
+ ]
+ }
+ }
+
+ # Hidden Objects, in invisible layers
+
+}
+
+# Visible Objects
+
+Separator {
+ MatrixTransform {
+ matrix
+ 0.685880 -0.317370 0.654862 0.000000
+ 0.727634 0.312469 -0.610666 0.000000
+ -0.010817 0.895343 0.445245 0.000000
+ -0.338183 -0.376694 -11.252342 1.000000
+ }
+ PerspectiveCamera {
+ focalDistance 3.500000
+ }
+ Separator {
+ MatrixTransform {
+ matrix
+ 1.000000 0.000000 0.000000 0.000000
+ 0.000000 1.000000 0.000000 0.000000
+ 0.000000 0.000000 1.000000 0.000000
+ 0.000000 0.000000 0.000000 1.000000
+ }
+ USE sphere1_default
+ }
+}
+}
diff --git a/tool_src/makeodt/test_ship b/tool_src/makeodt/test_ship
new file mode 100755
index 0000000..db9c10c
--- /dev/null
+++ b/tool_src/makeodt/test_ship
@@ -0,0 +1,526 @@
+#VRML V1.0 ascii
+
+# Blender V249
+
+# 'Switch' is used as a hack, to ensure it is not part of the drawing
+
+Separator {
+Switch {
+ DEF default
+ Material {
+ diffuseColor 0.788235 0.811765 0.690196
+ specularColor 1.000000 1.000000 1.000000
+ shininess 0.500000
+ transparency 0.000000
+ }
+ DEF cube1_copy_default
+ Separator {
+ Coordinate3 {
+ point [
+ 0.846830 0.004765 -0.000674,
+ 0.846830 0.004765 0.631326,
+ 0.994718 0.004765 0.631326,
+ 0.994718 0.004765 -0.000674,
+ 0.846830 1.104445 -0.000674,
+ 0.846830 1.104445 0.631326,
+ 0.994718 1.104445 0.631326,
+ 0.994718 1.104445 -0.000674,
+ ]
+ }
+ USE default
+
+ IndexedFaceSet {
+ coordIndex [
+ 3, 2, 1, -1,
+ 1, 0, 3, -1,
+ 3, 7, 6, -1,
+ 3, 6, 2, -1,
+ 0, 4, 7, -1,
+ 0, 7, 3, -1,
+ 2, 6, 5, -1,
+ 5, 1, 2, -1,
+ 5, 6, 7, -1,
+ 7, 4, 5, -1,
+ 5, 0, 1, -1,
+ 4, 0, 5, -1,
+ ]
+ }
+ }
+ DEF cube1_default
+ Separator {
+ Coordinate3 {
+ point [
+ -0.998504 0.004765 -0.000674,
+ -0.998504 0.004765 0.631326,
+ -0.850616 0.004765 0.631326,
+ -0.850616 0.004765 -0.000674,
+ -0.998504 1.104445 -0.000674,
+ -0.998504 1.104445 0.631326,
+ -0.850616 1.104445 0.631326,
+ -0.850616 1.104445 -0.000674,
+ ]
+ }
+ USE default
+
+ IndexedFaceSet {
+ coordIndex [
+ 3, 2, 1, -1,
+ 1, 0, 3, -1,
+ 3, 7, 6, -1,
+ 3, 6, 2, -1,
+ 0, 4, 7, -1,
+ 0, 7, 3, -1,
+ 2, 6, 5, -1,
+ 5, 1, 2, -1,
+ 5, 6, 7, -1,
+ 7, 4, 5, -1,
+ 5, 0, 1, -1,
+ 4, 0, 5, -1,
+ ]
+ }
+ }
+ DEF cube2_default
+ Separator {
+ Coordinate3 {
+ point [
+ -1.000000 -1.986667 0.005170,
+ -1.000000 -1.986667 0.627719,
+ 1.000000 -1.986667 0.627719,
+ 1.000000 -1.986667 0.005170,
+ -1.000000 0.013333 0.005170,
+ -1.000000 0.013333 0.627719,
+ 1.000000 0.013333 0.627719,
+ 1.000000 0.013333 0.005170,
+ 0.000000 -1.986667 0.627719,
+ 0.000000 -1.986667 0.005170,
+ 0.382683 -2.885333 1.259880,
+ 0.353553 -3.031780 1.259880,
+ 0.270598 -3.155931 1.259880,
+ 0.146447 -3.238887 1.259880,
+ 0.000000 -3.268017 1.259880,
+ -0.146447 -3.238887 1.259880,
+ -0.270598 -3.155931 1.259880,
+ -0.353553 -3.031780 1.259880,
+ -0.382683 -2.885333 1.259880,
+ -0.353553 -2.738887 1.259880,
+ -0.270598 -2.614735 1.259880,
+ -0.146447 -2.531780 1.259880,
+ -0.000000 -2.502650 1.259880,
+ 0.146447 -2.531780 1.259880,
+ 0.270598 -2.614735 1.259880,
+ 0.353553 -2.738887 1.259880,
+ 0.707107 -2.885333 1.043107,
+ 0.653282 -3.155931 1.043107,
+ 0.500000 -3.385333 1.043107,
+ 0.270598 -3.538615 1.043107,
+ 0.000000 -3.592440 1.043107,
+ -0.270598 -3.538615 1.043107,
+ -0.500000 -3.385333 1.043107,
+ -0.653282 -3.155931 1.043107,
+ -0.707107 -2.885333 1.043107,
+ -0.653282 -2.614735 1.043107,
+ -0.500000 -2.385333 1.043107,
+ -0.270598 -2.232052 1.043107,
+ -0.000000 -2.178226 1.043107,
+ 0.270598 -2.232052 1.043107,
+ 0.500000 -2.385333 1.043107,
+ 0.653282 -2.614735 1.043107,
+ 0.923880 -2.885333 0.718683,
+ 0.853553 -3.238887 0.718683,
+ 0.653282 -3.538615 0.718683,
+ 0.353553 -3.738887 0.718683,
+ 0.000000 -3.809213 0.718683,
+ -0.353553 -3.738887 0.718683,
+ -0.653282 -3.538615 0.718683,
+ -0.853553 -3.238887 0.718683,
+ -0.923880 -2.885333 0.718683,
+ -0.853553 -2.531780 0.718683,
+ -0.653282 -2.232052 0.718683,
+ -0.353553 -2.031780 0.718683,
+ -0.000000 -1.961454 0.718683,
+ 0.353553 -2.031780 0.718683,
+ 0.653282 -2.232052 0.718683,
+ 0.853553 -2.531780 0.718683,
+ 1.000000 -2.885333 0.336000,
+ 0.923880 -3.268017 0.336000,
+ 0.707107 -3.592440 0.336000,
+ 0.382683 -3.809213 0.336000,
+ 0.000000 -3.885333 0.336000,
+ -0.382683 -3.809213 0.336000,
+ -0.707107 -3.592440 0.336000,
+ -0.923880 -3.268017 0.336000,
+ -1.000000 -2.885333 0.336000,
+ -0.923880 -2.502650 0.336000,
+ -0.707107 -2.178226 0.336000,
+ -0.000000 -1.885333 0.336000,
+ 0.707107 -2.178226 0.336000,
+ 0.923880 -2.502650 0.336000,
+ 0.923880 -2.885333 -0.046683,
+ 0.853553 -3.238887 -0.046683,
+ 0.653282 -3.538615 -0.046683,
+ 0.353553 -3.738887 -0.046683,
+ 0.000000 -3.809213 -0.046683,
+ -0.353553 -3.738887 -0.046683,
+ -0.653282 -3.538615 -0.046683,
+ -0.853553 -3.238887 -0.046683,
+ -0.923880 -2.885333 -0.046683,
+ -0.853553 -2.531780 -0.046683,
+ -0.653282 -2.232052 -0.046683,
+ -0.353553 -2.031780 -0.046683,
+ -0.000000 -1.961454 -0.046683,
+ 0.353553 -2.031780 -0.046683,
+ 0.653282 -2.232052 -0.046683,
+ 0.853553 -2.531780 -0.046683,
+ 0.707107 -2.885333 -0.371107,
+ 0.653282 -3.155931 -0.371107,
+ 0.500000 -3.385333 -0.371107,
+ 0.270598 -3.538615 -0.371107,
+ 0.000000 -3.592440 -0.371107,
+ -0.270598 -3.538615 -0.371107,
+ -0.500000 -3.385333 -0.371107,
+ -0.653282 -3.155931 -0.371107,
+ -0.707107 -2.885333 -0.371107,
+ -0.653282 -2.614735 -0.371107,
+ -0.500000 -2.385333 -0.371107,
+ -0.270598 -2.232052 -0.371107,
+ -0.000000 -2.178226 -0.371107,
+ 0.270598 -2.232052 -0.371107,
+ 0.500000 -2.385333 -0.371107,
+ 0.653282 -2.614735 -0.371107,
+ 0.382683 -2.885333 -0.587880,
+ 0.353553 -3.031780 -0.587880,
+ 0.270598 -3.155931 -0.587880,
+ 0.146447 -3.238887 -0.587880,
+ 0.000000 -3.268017 -0.587880,
+ -0.146447 -3.238887 -0.587880,
+ -0.270598 -3.155931 -0.587880,
+ -0.353553 -3.031780 -0.587880,
+ -0.382683 -2.885333 -0.587880,
+ -0.353553 -2.738887 -0.587880,
+ -0.270598 -2.614735 -0.587880,
+ -0.146447 -2.531780 -0.587880,
+ -0.000000 -2.502650 -0.587880,
+ 0.146447 -2.531780 -0.587880,
+ 0.270598 -2.614735 -0.587880,
+ 0.353553 -2.738887 -0.587880,
+ 0.000000 -2.885333 1.336000,
+ 0.000000 -2.885333 -0.664000,
+ -0.500000 -1.986667 0.005170,
+ 0.000000 -1.986667 0.316444,
+ -0.500000 -1.986667 0.627719,
+ -1.000000 -1.986667 0.316444,
+ 0.500000 -1.986667 0.627719,
+ 0.000000 -1.986667 0.160807,
+ 1.000000 -1.986667 0.316444,
+ ]
+ }
+ USE default
+
+ IndexedFaceSet {
+ coordIndex [
+ 128, 3, 7, -1,
+ 128, 7, 6, -1,
+ 128, 6, 2, -1,
+ 4, 7, 9, -1,
+ 4, 9, 122, -1,
+ 7, 3, 9, -1,
+ 122, 0, 4, -1,
+ 8, 126, 6, -1,
+ 126, 2, 6, -1,
+ 5, 124, 8, -1,
+ 5, 8, 6, -1,
+ 5, 1, 124, -1,
+ 6, 7, 4, -1,
+ 4, 5, 6, -1,
+ 125, 1, 5, -1,
+ 125, 5, 4, -1,
+ 4, 0, 125, -1,
+ 10, 120, 11, -1,
+ 11, 120, 12, -1,
+ 12, 120, 13, -1,
+ 13, 120, 14, -1,
+ 14, 120, 15, -1,
+ 15, 120, 16, -1,
+ 16, 120, 17, -1,
+ 17, 120, 18, -1,
+ 18, 120, 19, -1,
+ 19, 120, 20, -1,
+ 20, 120, 21, -1,
+ 21, 120, 22, -1,
+ 22, 120, 23, -1,
+ 23, 120, 24, -1,
+ 24, 120, 25, -1,
+ 25, 120, 10, -1,
+ 105, 121, 104, -1,
+ 106, 121, 105, -1,
+ 107, 121, 106, -1,
+ 108, 121, 107, -1,
+ 109, 121, 108, -1,
+ 110, 121, 109, -1,
+ 111, 121, 110, -1,
+ 112, 121, 111, -1,
+ 113, 121, 112, -1,
+ 114, 121, 113, -1,
+ 115, 121, 114, -1,
+ 116, 121, 115, -1,
+ 117, 121, 116, -1,
+ 118, 121, 117, -1,
+ 119, 121, 118, -1,
+ 104, 121, 119, -1,
+ 11, 27, 10, -1,
+ 27, 26, 10, -1,
+ 12, 28, 27, -1,
+ 27, 11, 12, -1,
+ 29, 28, 12, -1,
+ 12, 13, 29, -1,
+ 30, 29, 13, -1,
+ 13, 14, 30, -1,
+ 15, 31, 30, -1,
+ 15, 30, 14, -1,
+ 16, 32, 31, -1,
+ 16, 31, 15, -1,
+ 33, 32, 16, -1,
+ 16, 17, 33, -1,
+ 18, 34, 33, -1,
+ 18, 33, 17, -1,
+ 19, 35, 34, -1,
+ 19, 34, 18, -1,
+ 20, 36, 35, -1,
+ 20, 35, 19, -1,
+ 21, 37, 20, -1,
+ 37, 36, 20, -1,
+ 22, 38, 21, -1,
+ 38, 37, 21, -1,
+ 23, 39, 22, -1,
+ 39, 38, 22, -1,
+ 24, 40, 39, -1,
+ 39, 23, 24, -1,
+ 25, 41, 24, -1,
+ 41, 40, 24, -1,
+ 10, 26, 25, -1,
+ 26, 41, 25, -1,
+ 27, 43, 26, -1,
+ 43, 42, 26, -1,
+ 28, 44, 43, -1,
+ 43, 27, 28, -1,
+ 45, 44, 28, -1,
+ 28, 29, 45, -1,
+ 30, 46, 45, -1,
+ 30, 45, 29, -1,
+ 31, 47, 46, -1,
+ 31, 46, 30, -1,
+ 32, 48, 47, -1,
+ 32, 47, 31, -1,
+ 49, 48, 32, -1,
+ 32, 33, 49, -1,
+ 34, 50, 49, -1,
+ 34, 49, 33, -1,
+ 35, 51, 50, -1,
+ 35, 50, 34, -1,
+ 36, 52, 51, -1,
+ 36, 51, 35, -1,
+ 37, 53, 36, -1,
+ 53, 52, 36, -1,
+ 38, 54, 37, -1,
+ 54, 53, 37, -1,
+ 39, 55, 38, -1,
+ 55, 54, 38, -1,
+ 40, 56, 55, -1,
+ 55, 39, 40, -1,
+ 41, 57, 40, -1,
+ 57, 56, 40, -1,
+ 26, 42, 41, -1,
+ 42, 57, 41, -1,
+ 43, 59, 42, -1,
+ 59, 58, 42, -1,
+ 44, 60, 59, -1,
+ 44, 59, 43, -1,
+ 45, 61, 44, -1,
+ 61, 60, 44, -1,
+ 46, 62, 61, -1,
+ 46, 61, 45, -1,
+ 47, 63, 62, -1,
+ 47, 62, 46, -1,
+ 48, 64, 47, -1,
+ 64, 63, 47, -1,
+ 49, 65, 48, -1,
+ 65, 64, 48, -1,
+ 50, 66, 65, -1,
+ 50, 65, 49, -1,
+ 51, 67, 66, -1,
+ 51, 66, 50, -1,
+ 52, 68, 51, -1,
+ 68, 67, 51, -1,
+ 57, 71, 56, -1,
+ 71, 70, 56, -1,
+ 42, 58, 57, -1,
+ 58, 71, 57, -1,
+ 59, 73, 58, -1,
+ 73, 72, 58, -1,
+ 60, 74, 59, -1,
+ 74, 73, 59, -1,
+ 61, 75, 60, -1,
+ 75, 74, 60, -1,
+ 62, 76, 61, -1,
+ 76, 75, 61, -1,
+ 63, 77, 62, -1,
+ 77, 76, 62, -1,
+ 64, 78, 63, -1,
+ 78, 77, 63, -1,
+ 65, 79, 78, -1,
+ 65, 78, 64, -1,
+ 66, 80, 79, -1,
+ 66, 79, 65, -1,
+ 81, 80, 66, -1,
+ 66, 67, 81, -1,
+ 68, 82, 67, -1,
+ 82, 81, 67, -1,
+ 71, 87, 70, -1,
+ 87, 86, 70, -1,
+ 58, 72, 71, -1,
+ 72, 87, 71, -1,
+ 73, 89, 88, -1,
+ 88, 72, 73, -1,
+ 74, 90, 73, -1,
+ 90, 89, 73, -1,
+ 75, 91, 90, -1,
+ 75, 90, 74, -1,
+ 76, 92, 91, -1,
+ 76, 91, 75, -1,
+ 93, 92, 76, -1,
+ 76, 77, 93, -1,
+ 94, 93, 77, -1,
+ 77, 78, 94, -1,
+ 79, 95, 94, -1,
+ 79, 94, 78, -1,
+ 80, 96, 95, -1,
+ 80, 95, 79, -1,
+ 97, 96, 80, -1,
+ 80, 81, 97, -1,
+ 98, 97, 81, -1,
+ 81, 82, 98, -1,
+ 83, 99, 98, -1,
+ 98, 82, 83, -1,
+ 84, 100, 99, -1,
+ 99, 83, 84, -1,
+ 85, 101, 100, -1,
+ 100, 84, 85, -1,
+ 86, 102, 85, -1,
+ 102, 101, 85, -1,
+ 87, 103, 102, -1,
+ 102, 86, 87, -1,
+ 72, 88, 103, -1,
+ 103, 87, 72, -1,
+ 89, 105, 88, -1,
+ 105, 104, 88, -1,
+ 90, 106, 89, -1,
+ 106, 105, 89, -1,
+ 91, 107, 106, -1,
+ 91, 106, 90, -1,
+ 92, 108, 107, -1,
+ 92, 107, 91, -1,
+ 109, 108, 92, -1,
+ 92, 93, 109, -1,
+ 110, 109, 93, -1,
+ 93, 94, 110, -1,
+ 95, 111, 110, -1,
+ 95, 110, 94, -1,
+ 96, 112, 111, -1,
+ 96, 111, 95, -1,
+ 113, 112, 96, -1,
+ 96, 97, 113, -1,
+ 114, 113, 97, -1,
+ 97, 98, 114, -1,
+ 99, 115, 114, -1,
+ 114, 98, 99, -1,
+ 100, 116, 115, -1,
+ 115, 99, 100, -1,
+ 101, 117, 116, -1,
+ 116, 100, 101, -1,
+ 102, 118, 101, -1,
+ 118, 117, 101, -1,
+ 103, 119, 118, -1,
+ 118, 102, 103, -1,
+ 88, 104, 119, -1,
+ 119, 103, 88, -1,
+ 52, 53, 124, -1,
+ 124, 1, 52, -1,
+ 54, 8, 53, -1,
+ 8, 124, 53, -1,
+ 8, 54, 69, -1,
+ 84, 9, 127, -1,
+ 83, 122, 9, -1,
+ 83, 9, 84, -1,
+ 122, 83, 82, -1,
+ 82, 0, 122, -1,
+ 0, 82, 68, -1,
+ 0, 68, 125, -1,
+ 52, 1, 68, -1,
+ 1, 125, 68, -1,
+ 2, 56, 70, -1,
+ 70, 128, 2, -1,
+ 56, 2, 126, -1,
+ 126, 55, 56, -1,
+ 8, 54, 55, -1,
+ 8, 55, 126, -1,
+ 8, 123, 69, -1,
+ 69, 123, 127, -1,
+ 127, 84, 69, -1,
+ 84, 9, 85, -1,
+ 3, 86, 85, -1,
+ 85, 9, 3, -1,
+ 3, 128, 70, -1,
+ 70, 86, 3, -1,
+ ]
+ }
+ }
+
+ # Hidden Objects, in invisible layers
+
+}
+
+# Visible Objects
+
+Separator {
+ MatrixTransform {
+ matrix
+ 0.685880 -0.317370 0.654862 0.000000
+ 0.727634 0.312469 -0.610666 0.000000
+ -0.010817 0.895343 0.445245 0.000000
+ -0.338183 -0.376694 -11.252342 1.000000
+ }
+ PerspectiveCamera {
+ focalDistance 3.500000
+ }
+ Separator {
+ MatrixTransform {
+ matrix
+ 1.000000 0.000000 0.000000 0.000000
+ 0.000000 1.000000 0.000000 0.000000
+ 0.000000 0.000000 1.000000 0.000000
+ -4.314717 1.826668 0.000000 1.000000
+ }
+ USE cube1_default
+ }
+ Separator {
+ MatrixTransform {
+ matrix
+ 1.000000 0.000000 0.000000 0.000000
+ 0.000000 1.000000 0.000000 0.000000
+ 0.000000 0.000000 1.000000 0.000000
+ -4.314717 1.826668 -0.223175 1.000000
+ }
+ USE cube2_default
+ }
+ Separator {
+ MatrixTransform {
+ matrix
+ 1.000000 0.000000 0.000000 0.000000
+ 0.000000 1.000000 0.000000 0.000000
+ 0.000000 0.000000 1.000000 0.000000
+ -4.314717 1.826668 0.000000 1.000000
+ }
+ USE cube1_copy_default
+ }
+}
+}
diff --git a/tool_src/makeodt/test_ship2.vrml b/tool_src/makeodt/test_ship2.vrml
new file mode 100755
index 0000000..1f6e043
--- /dev/null
+++ b/tool_src/makeodt/test_ship2.vrml
@@ -0,0 +1,52 @@
+#VRML V1.0 ascii
+Separator {
+ Coordinate3 {
+ point [
+0.846830,-0.000674,-0.004765,0.846830,0.631326,-0.004765,0.99471,0.631326,-0.004765,0.994718,-0.000674,-0.004765,0.846830,-0.000674,-1.104445,0.846830,0.631326,-1.104445,0.994718,0.631326,-1.104445,0.994718,-0.000674,-1.104445,-1.000000,0.005170,1.986667,-1.000000,0.627719,1.986667,1.000000,0.627719,1.986667,1.000000,0.005170,1.986667,-1.000000,0.005170,-0.013333,-1.000000,0.627719,-0.013333,1.000000,0.627719,-0.013333,1.000000,0.005170,-0.013333,0.000000,0.627719,1.986667,0.000000,0.005170,1.986667,0.382683,1.259880,2.885333,0.353553,1.259880,3.031780,0.270598,1.259880,3.155931,0.146447,1.259880,3.238887,0.000000,1.259880,3.268017,-0.146447,1.259880,3.238887,-0.270598,1.259880,3.155931,-0.353553,1.259880,3.031780,-0.382683,1.259880,2.885333,-0.353553,1.259880,2.738887,-0.270598,1.259880,2.614735,-0.146447,1.259880,2.531780,-0.000000,1.259880,2.502650,0.146447,1.259880,2.531780,0.270598,1.259880,2.614735,0.353553,1.259880,2.738887,0.707107,1.043107,2.885333,0.653281,1.043107,3.155931,0.500000,1.043107,3.385333,0.270598,1.043107,3.538615,0.000000,1.043107,3.592440,-0.270598,1.043107,3.538615,-0.500000,1.043107,3.385333,-0.653281,1.043107,3.155931,-0.707107,1.043107,2.885333,-0.653281,1.043107,2.614735,-0.500000,1.043107,2.385333,-0.270598,1.043107,2.232052,-0.000000,1.043107,2.178227,0.270598,1.043107,2.232052,0.500000,1.043107,2.385333,0.653281,1.043107,2.614735,0.923880,0.718683,2.885333,0.853553,0.718683,3.238887,0.653281,0.718683,3.538615,0.353553,0.718683,3.738887,0.000000,0.718683,3.809213,-0.353553,0.718683,3.738887,-0.653281,0.718683,3.538615,-0.853553,0.718683,3.238887,-0.923880,0.718683,2.885333,-0.853553,0.718683,2.531780,-0.653281,0.718683,2.232052,-0.353553,0.718683,2.031780,-0.000000,0.718683,1.961454,0.353553,0.718683,2.031780,0.653281,0.718683,2.232052,0.853553,0.718683,2.531780,1.000000,0.336000,2.885333,0.923880,0.336000,3.268017,0.707107,0.336000,3.592440,0.382683,0.336000,3.809213,0.000000,0.336000,3.885333,-0.382683,0.336000,3.809213,-0.707107,0.336000,3.592440,-0.923880,0.336000,3.268017,-1.000000,0.336000,2.885333,-0.923880,0.336000,2.502650,-0.707107,0.336000,2.178227,-0.000000,0.336000,1.885333,0.707107,0.336000,2.178227,0.923880,0.336000,2.502650,0.923880,-0.046683,2.885333,0.853553,-0.046683,3.238887,0.653281,-0.046683,3.538615,0.353553,-0.046683,3.738887,0.000000,-0.046683,3.809213,-0.353553,-0.046683,3.738887,-0.653281,-0.046683,3.538615,-0.853553,-0.046683,3.238887,-0.923880,-0.046683,2.885333,-0.853553,-0.046683,2.531780,-0.653281,-0.046683,2.232052,-0.353553,-0.046683,2.031780,-0.000000,-0.046683,1.961454,0.353553,-0.046683,2.031780,0.653281,-0.046683,2.232052,0.853553,-0.046683,2.531780,0.707107,-0.371107,2.885333,0.653281,-0.371107,3.155931,0.500000,-0.371107,3.385333,0.270598,-0.371107,3.538615,0.000000,-0.371107,3.592440,-0.270598,-0.371107,3.538615,-0.500000,-0.371107,3.385333,-0.653281,-0.371107,3.155931,-0.707107,-0.371107,2.885333,-0.653281,-0.371107,2.614735,-0.500000,-0.371107,2.385333,-0.270598,-0.371107,2.232052,-0.000000,-0.371107,2.178227,0.270598,-0.371107,2.232052,0.500000,-0.371107,2.385333,0.653281,-0.371107,2.614735,0.382683,-0.587880,2.885333,0.353553,-0.587880,3.031780,0.270598,-0.587880,3.155931,0.146447,-0.587880,3.238887,0.000000,-0.587880,3.268017,-0.146447,-0.587880,3.238887,-0.270598,-0.587880,3.155931,-0.353553,-0.587880,3.031780,-0.382683,-0.587880,2.885333,-0.353553,-0.587880,2.738887,-0.270598,-0.587880,2.614735,-0.146447,-0.587880,2.531780,-0.000000,-0.587880,2.502650,0.146447,-0.587880,2.531780,0.270598,-0.587880,2.614735,0.353553,-0.587880,2.738887,0.000000,1.336000,2.885333,0.000000,-0.664000,2.885333,-0.500000,0.005170,1.986667,0.000000,0.316444,1.986667,-0.500000,0.627719,1.986667,-1.000000,0.316444,1.986667,0.500000,0.627719,1.986667,0.000000,0.160807,1.986667,1.000000,0.316444,1.986667,-0.998504,-0.000674,-0.004765,-0.998504,0.631326,-0.004765,-0.850616,0.631326,-0.004765,-0.850616,-0.000674,-0.004765,-0.998504,-0.000674,-1.104445,-0.998504,0.631326,-1.104445,-0.850616,0.631326,-1.104445,-0.850616,-0.000674,-1.104445,
+ ]
+ }
+ IndexedFaceSet {
+ coordIndex [
+0 1 5 4 -1
+0 3 2 1 -1 0 4 7 3 -1 1 2 6 5 -1 2 3 7 6 -1
+4 5 6 7 -1 8 12 15 11 17 130 -1 8 90 76 133 -1 8 130 91 90 -1
+8 133 9 13 12 -1 9 60 61 132 -1 9 132 16 134 10 14 13 -1 9 133 76 60 -1
+10 64 78 136 -1 10 134 63 64 -1 10 136 11 15 14 -1 11 94 93 17 -1
+11 136 78 94 -1 12 13 14 15 -1 16 62 63 134 -1 16 62 77 131 -1
+16 131 77 62 -1 16 132 61 62 -1 17 92 91 130 -1 17 93 92 135 -1
+17 135 131 77 92 -1 18 19 35 34 -1 18 33 128 -1 18 34 49 33 -1
+18 128 19 -1 19 20 36 35 -1 19 128 20 -1 20 21 37 36 -1
+20 128 21 -1 21 22 38 37 -1 21 128 22 -1 22 23 39 38 -1
+22 128 23 -1 23 24 40 39 -1 23 128 24 -1 24 25 41 40 -1
+24 128 25 -1 25 26 42 41 -1 25 128 26 -1 26 27 43 42 -1
+26 128 27 -1 27 28 44 43 -1 27 128 28 -1 28 29 45 44 -1
+28 128 29 -1 29 30 46 45 -1 29 128 30 -1 30 31 47 46 -1
+30 128 31 -1 31 32 48 47 -1 31 128 32 -1 32 33 49 48 -1
+32 128 33 -1 34 35 51 50 -1 34 50 65 49 -1 35 36 52 51 -1
+36 37 53 52 -1 37 38 54 53 -1 38 39 55 54 -1 39 40 56 55 -1
+40 41 57 56 -1 41 42 58 57 -1 42 43 59 58 -1 43 44 60 59 -1
+44 45 61 60 -1 45 46 62 61 -1 46 47 63 62 -1 47 48 64 63 -1
+48 49 65 64 -1 50 51 67 66 -1 50 66 79 65 -1 51 52 68 67 -1
+52 53 69 68 -1 53 54 70 69 -1 54 55 71 70 -1 55 56 72 71 -1
+56 57 73 72 -1 57 58 74 73 -1 58 59 75 74 -1 59 60 76 75 -1
+64 65 79 78 -1 66 67 81 80 -1 66 80 95 79 -1 67 68 82 81 -1
+68 69 83 82 -1 69 70 84 83 -1 70 71 85 84 -1 71 72 86 85 -1
+72 73 87 86 -1 73 74 88 87 -1 74 75 89 88 -1 75 76 90 89 -1
+77 131 135 92 -1 78 79 95 94 -1 80 81 97 96 -1 80 96 111 95 -1
+81 82 98 97 -1 82 83 99 98 -1 83 84 100 99 -1 84 85 101 100 -1
+85 86 102 101 -1 86 87 103 102 -1 87 88 104 103 -1 88 89 105 104 -1
+89 90 106 105 -1 90 91 107 106 -1 91 92 108 107 -1 92 93 109 108 -1
+93 94 110 109 -1 94 95 111 110 -1 96 97 113 112 -1 96 112 127 111 -1
+97 98 114 113 -1 98 99 115 114 -1 99 100 116 115 -1 100 101 117 116 -1
+101 102 118 117 -1 102 103 119 118 -1 103 104 120 119 -1 104 105 121 120 -1
+105 106 122 121 -1 106 107 123 122 -1 107 108 124 123 -1 108 109 125 124 -1
+109 110 126 125 -1 110 111 127 126 -1 112 113 129 -1 112 129 127 -1
+113 114 129 -1 114 115 129 -1 115 116 129 -1 116 117 129 -1
+117 118 129 -1 118 119 129 -1 119 120 129 -1 120 121 129 -1
+121 122 129 -1 122 123 129 -1 123 124 129 -1 124 125 129 -1
+125 126 129 -1 126 127 129 -1 137 138 142 141 -1 137 140 139 138 -1
+137 141 144 140 -1 138 139 143 142 -1 139 140 144 143 -1 141 142 143 144 -1
+
+ ]
+ }
+}
diff --git a/tool_src/makeodt/test_ship2.vrml~ b/tool_src/makeodt/test_ship2.vrml~
new file mode 100755
index 0000000..c535b1e
--- /dev/null
+++ b/tool_src/makeodt/test_ship2.vrml~
@@ -0,0 +1,52 @@
+#VRML V1.0 ascii
+Separator {
+ Coordinate3 {
+ point [
+0.846830, -0.000674, -0.004765, 0.846830, 0.631326, -0.004765, 0.99471, 0.631326, -0.004765, 0.994718, -0.000674, -0.004765, 0.846830, -0.000674, -1.104445, 0.846830, 0.631326, -1.104445, 0.994718, 0.631326, -1.104445, 0.994718, -0.000674, -1.104445, -1.000000, 0.005170, 1.986667, -1.000000, 0.627719, 1.986667, 1.000000, 0.627719, 1.986667, 1.000000, 0.005170, 1.986667, -1.000000, 0.005170, -0.013333, -1.000000, 0.627719, -0.013333, 1.000000, 0.627719, -0.013333, 1.000000, 0.005170, -0.013333, 0.000000, 0.627719, 1.986667, 0.000000, 0.005170, 1.986667, 0.382683, 1.259880, 2.885333, 0.353553, 1.259880, 3.031780, 0.270598, 1.259880, 3.155931, 0.146447, 1.259880, 3.238887, 0.000000, 1.259880, 3.268017, -0.146447, 1.259880, 3.238887, -0.270598, 1.259880, 3.155931, -0.353553, 1.259880, 3.031780, -0.382683, 1.259880, 2.885333, -0.353553, 1.259880, 2.738887, -0.270598, 1.259880, 2.614735, -0.146447, 1.259880, 2.531780, -0.000000, 1.259880, 2.502650, 0.146447, 1.259880, 2.531780, 0.270598, 1.259880, 2.614735, 0.353553, 1.259880, 2.738887, 0.707107, 1.043107, 2.885333, 0.653281, 1.043107, 3.155931, 0.500000, 1.043107, 3.385333, 0.270598, 1.043107, 3.538615, 0.000000, 1.043107, 3.592440, -0.270598, 1.043107, 3.538615, -0.500000, 1.043107, 3.385333, -0.653281, 1.043107, 3.155931, -0.707107, 1.043107, 2.885333, -0.653281, 1.043107, 2.614735, -0.500000, 1.043107, 2.385333, -0.270598, 1.043107, 2.232052, -0.000000, 1.043107, 2.178227, 0.270598, 1.043107, 2.232052, 0.500000, 1.043107, 2.385333, 0.653281, 1.043107, 2.614735, 0.923880, 0.718683, 2.885333, 0.853553, 0.718683, 3.238887, 0.653281, 0.718683, 3.538615, 0.353553, 0.718683, 3.738887, 0.000000, 0.718683, 3.809213, -0.353553, 0.718683, 3.738887, -0.653281, 0.718683, 3.538615, -0.853553, 0.718683, 3.238887, -0.923880, 0.718683, 2.885333, -0.853553, 0.718683, 2.531780, -0.653281, 0.718683, 2.232052, -0.353553, 0.718683, 2.031780, -0.000000, 0.718683, 1.961454, 0.353553, 0.718683, 2.031780, 0.653281, 0.718683, 2.232052, 0.853553, 0.718683, 2.531780, 1.000000, 0.336000, 2.885333, 0.923880, 0.336000, 3.268017, 0.707107, 0.336000, 3.592440, 0.382683, 0.336000, 3.809213, 0.000000, 0.336000, 3.885333, -0.382683, 0.336000, 3.809213, -0.707107, 0.336000, 3.592440, -0.923880, 0.336000, 3.268017, -1.000000, 0.336000, 2.885333, -0.923880, 0.336000, 2.502650, -0.707107, 0.336000, 2.178227, -0.000000, 0.336000, 1.885333, 0.707107, 0.336000, 2.178227, 0.923880, 0.336000, 2.502650, 0.923880, -0.046683, 2.885333, 0.853553, -0.046683, 3.238887, 0.653281, -0.046683, 3.538615, 0.353553, -0.046683, 3.738887, 0.000000, -0.046683, 3.809213, -0.353553, -0.046683, 3.738887, -0.653281, -0.046683, 3.538615, -0.853553, -0.046683, 3.238887, -0.923880, -0.046683, 2.885333, -0.853553, -0.046683, 2.531780, -0.653281, -0.046683, 2.232052, -0.353553, -0.046683, 2.031780, -0.000000, -0.046683, 1.961454, 0.353553, -0.046683, 2.031780, 0.653281, -0.046683, 2.232052, 0.853553, -0.046683, 2.531780, 0.707107, -0.371107, 2.885333, 0.653281, -0.371107, 3.155931, 0.500000, -0.371107, 3.385333, 0.270598, -0.371107, 3.538615, 0.000000, -0.371107, 3.592440, -0.270598, -0.371107, 3.538615, -0.500000, -0.371107, 3.385333, -0.653281, -0.371107, 3.155931, -0.707107, -0.371107, 2.885333, -0.653281, -0.371107, 2.614735, -0.500000, -0.371107, 2.385333, -0.270598, -0.371107, 2.232052, -0.000000, -0.371107, 2.178227, 0.270598, -0.371107, 2.232052, 0.500000, -0.371107, 2.385333, 0.653281, -0.371107, 2.614735, 0.382683, -0.587880, 2.885333, 0.353553, -0.587880, 3.031780, 0.270598, -0.587880, 3.155931, 0.146447, -0.587880, 3.238887, 0.000000, -0.587880, 3.268017, -0.146447, -0.587880, 3.238887, -0.270598, -0.587880, 3.155931, -0.353553, -0.587880, 3.031780, -0.382683, -0.587880, 2.885333, -0.353553, -0.587880, 2.738887, -0.270598, -0.587880, 2.614735, -0.146447, -0.587880, 2.531780, -0.000000, -0.587880, 2.502650, 0.146447, -0.587880, 2.531780, 0.270598, -0.587880, 2.614735, 0.353553, -0.587880, 2.738887, 0.000000, 1.336000, 2.885333, 0.000000, -0.664000, 2.885333, -0.500000, 0.005170, 1.986667, 0.000000, 0.316444, 1.986667, -0.500000, 0.627719, 1.986667, -1.000000, 0.316444, 1.986667, 0.500000, 0.627719, 1.986667, 0.000000, 0.160807, 1.986667, 1.000000, 0.316444, 1.986667, -0.998504, -0.000674, -0.004765, -0.998504, 0.631326, -0.004765, -0.850616, 0.631326, -0.004765, -0.850616, -0.000674, -0.004765, -0.998504, -0.000674, -1.104445, -0.998504, 0.631326, -1.104445, -0.850616, 0.631326, -1.104445, -0.850616, -0.000674, -1.104445,
+ ]
+ }
+ IndexedFaceSet {
+ coordIndex [
+0 1 5 4 -1
+0 3 2 1 -1 0 4 7 3 -1 1 2 6 5 -1 2 3 7 6 -1
+4 5 6 7 -1 8 12 15 11 17 130 -1 8 90 76 133 -1 8 130 91 90 -1
+8 133 9 13 12 -1 9 60 61 132 -1 9 132 16 134 10 14 13 -1 9 133 76 60 -1
+10 64 78 136 -1 10 134 63 64 -1 10 136 11 15 14 -1 11 94 93 17 -1
+11 136 78 94 -1 12 13 14 15 -1 16 62 63 134 -1 16 62 77 131 -1
+16 131 77 62 -1 16 132 61 62 -1 17 92 91 130 -1 17 93 92 135 -1
+17 135 131 77 92 -1 18 19 35 34 -1 18 33 128 -1 18 34 49 33 -1
+18 128 19 -1 19 20 36 35 -1 19 128 20 -1 20 21 37 36 -1
+20 128 21 -1 21 22 38 37 -1 21 128 22 -1 22 23 39 38 -1
+22 128 23 -1 23 24 40 39 -1 23 128 24 -1 24 25 41 40 -1
+24 128 25 -1 25 26 42 41 -1 25 128 26 -1 26 27 43 42 -1
+26 128 27 -1 27 28 44 43 -1 27 128 28 -1 28 29 45 44 -1
+28 128 29 -1 29 30 46 45 -1 29 128 30 -1 30 31 47 46 -1
+30 128 31 -1 31 32 48 47 -1 31 128 32 -1 32 33 49 48 -1
+32 128 33 -1 34 35 51 50 -1 34 50 65 49 -1 35 36 52 51 -1
+36 37 53 52 -1 37 38 54 53 -1 38 39 55 54 -1 39 40 56 55 -1
+40 41 57 56 -1 41 42 58 57 -1 42 43 59 58 -1 43 44 60 59 -1
+44 45 61 60 -1 45 46 62 61 -1 46 47 63 62 -1 47 48 64 63 -1
+48 49 65 64 -1 50 51 67 66 -1 50 66 79 65 -1 51 52 68 67 -1
+52 53 69 68 -1 53 54 70 69 -1 54 55 71 70 -1 55 56 72 71 -1
+56 57 73 72 -1 57 58 74 73 -1 58 59 75 74 -1 59 60 76 75 -1
+64 65 79 78 -1 66 67 81 80 -1 66 80 95 79 -1 67 68 82 81 -1
+68 69 83 82 -1 69 70 84 83 -1 70 71 85 84 -1 71 72 86 85 -1
+72 73 87 86 -1 73 74 88 87 -1 74 75 89 88 -1 75 76 90 89 -1
+77 131 135 92 -1 78 79 95 94 -1 80 81 97 96 -1 80 96 111 95 -1
+81 82 98 97 -1 82 83 99 98 -1 83 84 100 99 -1 84 85 101 100 -1
+85 86 102 101 -1 86 87 103 102 -1 87 88 104 103 -1 88 89 105 104 -1
+89 90 106 105 -1 90 91 107 106 -1 91 92 108 107 -1 92 93 109 108 -1
+93 94 110 109 -1 94 95 111 110 -1 96 97 113 112 -1 96 112 127 111 -1
+97 98 114 113 -1 98 99 115 114 -1 99 100 116 115 -1 100 101 117 116 -1
+101 102 118 117 -1 102 103 119 118 -1 103 104 120 119 -1 104 105 121 120 -1
+105 106 122 121 -1 106 107 123 122 -1 107 108 124 123 -1 108 109 125 124 -1
+109 110 126 125 -1 110 111 127 126 -1 112 113 129 -1 112 129 127 -1
+113 114 129 -1 114 115 129 -1 115 116 129 -1 116 117 129 -1
+117 118 129 -1 118 119 129 -1 119 120 129 -1 120 121 129 -1
+121 122 129 -1 122 123 129 -1 123 124 129 -1 124 125 129 -1
+125 126 129 -1 126 127 129 -1 137 138 142 141 -1 137 140 139 138 -1
+137 141 144 140 -1 138 139 143 142 -1 139 140 144 143 -1 141 142 143 144 -1
+
+ ]
+ }
+}
diff --git a/tool_src/makeodt/test_ship~ b/tool_src/makeodt/test_ship~
new file mode 100755
index 0000000..175051d
--- /dev/null
+++ b/tool_src/makeodt/test_ship~
@@ -0,0 +1,649 @@
+#VRML V1.0 ascii
+DEF cube1_copy3 Transform {
+ Shape {
+ appearance Appearance {
+ material DEF default Material {
+ diffuseColor 0.7898538076923077 0.8133333333333334 0.6940444444444445
+ emissiveColor 0.0 0.0 0.0
+ specularColor 1.0 1.0 1.0
+ ambientIntensity 0.765743861823362
+ transparency 0.0
+ shininess 1.0
+ }
+ }
+ geometry IndexedFaceSet {
+ normalPerVertex TRUE
+ coord Coordinate { point [
+ 0.8468295871412848 -6.73734278962182e-4 -0.004764781349210434,
+ 0.8468295871412848 0.6313262657210368 -0.004764781349210434,
+ 0.9947175871412842 0.6313262657210368 -0.004764781349210434,
+ 0.9947175871412842 -6.73734278962182e-4 -0.004764781349210434,
+ 0.8468295871412848 -6.73734278962182e-4 -1.1044447813492089,
+ 0.8468295871412848 0.6313262657210368 -1.1044447813492089,
+ 0.9947175871412842 0.6313262657210368 -1.1044447813492089,
+ 0.9947175871412842 -6.73734278962182e-4 -1.1044447813492089 ] }
+ coordIndex [
+ 0, 1, 5, 4, -1,
+ 0, 3, 2, 1, -1,
+ 0, 4, 7, 3, -1,
+ 1, 2, 6, 5, -1,
+ 2, 3, 7, 6, -1,
+ 4, 5, 6, 7, -1 ]
+ normal Normal { vector [
+ -0.5773502691896258 -0.5773502691896258 0.5773502691896258,
+ -0.5773502691896258 0.5773502691896258 0.5773502691896258,
+ 0.5773502691896258 0.5773502691896258 0.5773502691896258,
+ 0.5773502691896258 -0.5773502691896258 0.5773502691896258,
+ -0.5773502691896258 -0.5773502691896258 -0.5773502691896258,
+ -0.5773502691896258 0.5773502691896258 -0.5773502691896258,
+ 0.5773502691896258 0.5773502691896258 -0.5773502691896258,
+ 0.5773502691896258 -0.5773502691896258 -0.5773502691896258 ] }
+ normalIndex [
+ 0, 1, 5, 4, -1,
+ 0, 3, 2, 1, -1,
+ 0, 4, 7, 3, -1,
+ 1, 2, 6, 5, -1,
+ 2, 3, 7, 6, -1,
+ 4, 5, 6, 7, -1 ]
+ }
+ }
+}
+
+DEF cube2 Transform {
+ Shape {
+ appearance Appearance {
+ material USE default
+ }
+ geometry IndexedFaceSet {
+ normalPerVertex TRUE
+ coord Coordinate { point [
+ -0.9999999999999999 0.005169841948445655 1.9866666666666666,
+ -0.9999999999999999 0.6277190469404448 1.9866666666666666,
+ 1.0 0.6277190469404448 1.9866666666666666,
+ 1.0 0.005169841948445655 1.9866666666666666,
+ -0.9999999999999999 0.005169841948445655 -0.013333333333333607,
+ -0.9999999999999999 0.6277190469404448 -0.013333333333333607,
+ 1.0 0.6277190469404448 -0.013333333333333607,
+ 1.0 0.005169841948445655 -0.013333333333333607,
+ 1.1102230246251565e-16 0.6277190469404448 1.9866666666666666,
+ 1.1102230246251565e-16 0.005169841948445655 1.9866666666666666,
+ 0.3826834323650898 1.2598795325112868 2.885333333333333,
+ 0.3535533905932738 1.2598795325112868 3.031779942740059,
+ 0.2705980500730985 1.2598795325112868 3.1559313834064318,
+ 0.14644660940672627 1.2598795325112868 3.238886723926607,
+ 2.3432602026631493e-17 1.2598795325112868 3.2680167656984227,
+ -0.1464466094067262 1.2598795325112868 3.238886723926607,
+ -0.27059805007309845 1.2598795325112868 3.1559313834064318,
+ -0.3535533905932738 1.2598795325112868 3.0317799427400596,
+ -0.3826834323650898 1.2598795325112868 2.885333333333333,
+ -0.3535533905932738 1.2598795325112868 2.738886723926607,
+ -0.27059805007309856 1.2598795325112868 2.6147352832602344,
+ -0.14644660940672646 1.2598795325112868 2.5317799427400596,
+ -7.029780607989448e-17 1.2598795325112868 2.5026499009682435,
+ 0.14644660940672632 1.2598795325112868 2.5317799427400596,
+ 0.27059805007309845 1.2598795325112868 2.6147352832602344,
+ 0.3535533905932737 1.2598795325112868 2.7388867239266066,
+ 0.7071067811865475 1.0431067811865478 2.885333333333333,
+ 0.6532814824381882 1.0431067811865478 3.1559313834064318,
+ 0.5 1.0431067811865478 3.385333333333333,
+ 0.2705980500730985 1.0431067811865478 3.5386148157715214,
+ 4.329780281177466e-17 1.0431067811865478 3.5924401145198805,
+ -0.27059805007309845 1.0431067811865478 3.5386148157715214,
+ -0.4999999999999999 1.0431067811865478 3.385333333333333,
+ -0.6532814824381882 1.0431067811865478 3.1559313834064318,
+ -0.7071067811865475 1.0431067811865478 2.885333333333333,
+ -0.6532814824381883 1.0431067811865478 2.614735283260235,
+ -0.5000000000000001 1.0431067811865478 2.385333333333333,
+ -0.2705980500730989 1.0431067811865478 2.232051850895145,
+ -1.2989340843532398e-16 1.0431067811865478 2.1782265521467856,
+ 0.2705980500730986 1.0431067811865478 2.232051850895145,
+ 0.49999999999999983 1.0431067811865478 2.385333333333333,
+ 0.6532814824381881 1.0431067811865478 2.6147352832602344,
+ 0.9238795325112867 0.7186834323650899 2.885333333333333,
+ 0.8535533905932737 0.7186834323650899 3.238886723926607,
+ 0.6532814824381883 0.7186834323650899 3.5386148157715214,
+ 0.35355339059327384 0.7186834323650899 3.7388867239266066,
+ 5.657130561438501e-17 0.7186834323650899 3.8092128658446196,
+ -0.35355339059327373 0.7186834323650899 3.7388867239266066,
+ -0.6532814824381882 0.7186834323650899 3.5386148157715214,
+ -0.8535533905932737 0.7186834323650899 3.238886723926607,
+ -0.9238795325112867 0.7186834323650899 2.885333333333333,
+ -0.8535533905932738 0.7186834323650899 2.5317799427400596,
+ -0.6532814824381884 0.7186834323650899 2.232051850895145,
+ -0.3535533905932743 0.7186834323650899 2.0317799427400596,
+ -1.6971391684315505e-16 0.7186834323650899 1.9614538008220463,
+ 0.35355339059327395 0.7186834323650899 2.0317799427400596,
+ 0.6532814824381881 0.7186834323650899 2.232051850895145,
+ 0.8535533905932735 0.7186834323650899 2.5317799427400587,
+ 1.0 0.3360000000000002 2.885333333333333,
+ 0.9238795325112867 0.3360000000000002 3.2680167656984227,
+ 0.7071067811865476 0.3360000000000002 3.5924401145198805,
+ 0.38268343236508984 0.3360000000000002 3.8092128658446196,
+ 6.123233995736766e-17 0.3360000000000002 3.885333333333333,
+ -0.3826834323650897 0.3360000000000002 3.8092128658446196,
+ -0.7071067811865475 0.3360000000000002 3.5924401145198805,
+ -0.9238795325112867 0.3360000000000002 3.268016765698423,
+ -1.0 0.3360000000000002 2.885333333333333,
+ -0.9238795325112868 0.3360000000000002 2.5026499009682435,
+ -0.7071067811865477 0.3360000000000002 2.1782265521467856,
+ -1.8369701987210297e-16 0.3360000000000002 1.885333333333333,
+ 0.7071067811865474 0.3360000000000002 2.1782265521467856,
+ 0.9238795325112865 0.3360000000000002 2.5026499009682426,
+ 0.9238795325112867 -0.046683432365089594 2.885333333333333,
+ 0.8535533905932737 -0.046683432365089594 3.238886723926607,
+ 0.6532814824381883 -0.046683432365089594 3.5386148157715214,
+ 0.35355339059327384 -0.046683432365089594 3.7388867239266066,
+ 5.657130561438501e-17 -0.046683432365089594 3.8092128658446196,
+ -0.35355339059327373 -0.046683432365089594 3.7388867239266066,
+ -0.6532814824381882 -0.046683432365089594 3.5386148157715214,
+ -0.8535533905932737 -0.046683432365089594 3.238886723926607,
+ -0.9238795325112867 -0.046683432365089594 2.885333333333333,
+ -0.8535533905932738 -0.046683432365089594 2.5317799427400596,
+ -0.6532814824381884 -0.046683432365089594 2.232051850895145,
+ -0.3535533905932743 -0.046683432365089594 2.0317799427400596,
+ -1.6971391684315505e-16 -0.046683432365089594 1.9614538008220463,
+ 0.35355339059327395 -0.046683432365089594 2.0317799427400596,
+ 0.6532814824381881 -0.046683432365089594 2.232051850895145,
+ 0.8535533905932735 -0.046683432365089594 2.5317799427400587,
+ 0.7071067811865476 -0.37110678118654733 2.885333333333333,
+ 0.6532814824381883 -0.37110678118654733 3.1559313834064318,
+ 0.5000000000000001 -0.37110678118654733 3.385333333333333,
+ 0.27059805007309856 -0.37110678118654733 3.5386148157715214,
+ 4.329780281177467e-17 -0.37110678118654733 3.5924401145198805,
+ -0.2705980500730985 -0.37110678118654733 3.5386148157715214,
+ -0.5 -0.37110678118654733 3.385333333333333,
+ -0.6532814824381883 -0.37110678118654733 3.1559313834064318,
+ -0.7071067811865476 -0.37110678118654733 2.885333333333333,
+ -0.6532814824381884 -0.37110678118654733 2.6147352832602344,
+ -0.5000000000000001 -0.37110678118654733 2.385333333333333,
+ -0.2705980500730989 -0.37110678118654733 2.232051850895145,
+ -1.29893408435324e-16 -0.37110678118654733 2.1782265521467856,
+ 0.2705980500730987 -0.37110678118654733 2.232051850895145,
+ 0.4999999999999999 -0.37110678118654733 2.385333333333333,
+ 0.6532814824381882 -0.37110678118654733 2.614735283260234,
+ 0.3826834323650899 -0.5878795325112867 2.885333333333333,
+ 0.35355339059327384 -0.5878795325112867 3.0317799427400596,
+ 0.2705980500730986 -0.5878795325112867 3.1559313834064318,
+ 0.1464466094067263 -0.5878795325112867 3.238886723926607,
+ 2.34326020266315e-17 -0.5878795325112867 3.268016765698423,
+ -0.14644660940672627 -0.5878795325112867 3.238886723926607,
+ -0.27059805007309856 -0.5878795325112867 3.1559313834064318,
+ -0.35355339059327384 -0.5878795325112867 3.0317799427400596,
+ -0.3826834323650899 -0.5878795325112867 2.885333333333333,
+ -0.3535533905932739 -0.5878795325112867 2.738886723926607,
+ -0.2705980500730986 -0.5878795325112867 2.6147352832602344,
+ -0.1464466094067265 -0.5878795325112867 2.531779942740059,
+ -7.029780607989449e-17 -0.5878795325112867 2.502649900968243,
+ 0.14644660940672638 -0.5878795325112867 2.531779942740059,
+ 0.2705980500730985 -0.5878795325112867 2.6147352832602344,
+ 0.3535533905932738 -0.5878795325112867 2.7388867239266066,
+ 0.0 1.336 2.885333333333333,
+ 0.0 -0.6639999999999999 2.885333333333333,
+ -0.4999999999999999 0.005169841948445655 1.9866666666666666,
+ 1.1102230246251565e-16 0.3164444444444452 1.9866666666666666,
+ -0.4999999999999999 0.6277190469404448 1.9866666666666666,
+ -0.9999999999999999 0.3164444444444452 1.9866666666666666,
+ 0.5 0.6277190469404448 1.9866666666666666,
+ 1.1102230246251565e-16 0.16080714319644543 1.9866666666666666,
+ 1.0 0.3164444444444452 1.9866666666666666 ] }
+ coordIndex [
+ 0, 4, 7, 3, 9, 122, -1,
+ 0, 82, 68, 125, -1,
+ 0, 122, 83, 82, -1,
+ 0, 125, 1, 5, 4, -1,
+ 1, 52, 53, 124, -1,
+ 1, 124, 8, 126, 2, 6, 5, -1,
+ 1, 125, 68, 52, -1,
+ 2, 56, 70, 128, -1,
+ 2, 126, 55, 56, -1,
+ 2, 128, 3, 7, 6, -1,
+ 3, 86, 85, 9, -1,
+ 3, 128, 70, 86, -1,
+ 4, 5, 6, 7, -1,
+ 8, 54, 55, 126, -1,
+ 8, 54, 69, 123, -1,
+ 8, 123, 69, 54, -1,
+ 8, 124, 53, 54, -1,
+ 9, 84, 83, 122, -1,
+ 9, 85, 84, 127, -1,
+ 9, 127, 123, 69, 84, -1,
+ 10, 11, 27, 26, -1,
+ 10, 25, 120, -1,
+ 10, 26, 41, 25, -1,
+ 10, 120, 11, -1,
+ 11, 12, 28, 27, -1,
+ 11, 120, 12, -1,
+ 12, 13, 29, 28, -1,
+ 12, 120, 13, -1,
+ 13, 14, 30, 29, -1,
+ 13, 120, 14, -1,
+ 14, 15, 31, 30, -1,
+ 14, 120, 15, -1,
+ 15, 16, 32, 31, -1,
+ 15, 120, 16, -1,
+ 16, 17, 33, 32, -1,
+ 16, 120, 17, -1,
+ 17, 18, 34, 33, -1,
+ 17, 120, 18, -1,
+ 18, 19, 35, 34, -1,
+ 18, 120, 19, -1,
+ 19, 20, 36, 35, -1,
+ 19, 120, 20, -1,
+ 20, 21, 37, 36, -1,
+ 20, 120, 21, -1,
+ 21, 22, 38, 37, -1,
+ 21, 120, 22, -1,
+ 22, 23, 39, 38, -1,
+ 22, 120, 23, -1,
+ 23, 24, 40, 39, -1,
+ 23, 120, 24, -1,
+ 24, 25, 41, 40, -1,
+ 24, 120, 25, -1,
+ 26, 27, 43, 42, -1,
+ 26, 42, 57, 41, -1,
+ 27, 28, 44, 43, -1,
+ 28, 29, 45, 44, -1,
+ 29, 30, 46, 45, -1,
+ 30, 31, 47, 46, -1,
+ 31, 32, 48, 47, -1,
+ 32, 33, 49, 48, -1,
+ 33, 34, 50, 49, -1,
+ 34, 35, 51, 50, -1,
+ 35, 36, 52, 51, -1,
+ 36, 37, 53, 52, -1,
+ 37, 38, 54, 53, -1,
+ 38, 39, 55, 54, -1,
+ 39, 40, 56, 55, -1,
+ 40, 41, 57, 56, -1,
+ 42, 43, 59, 58, -1,
+ 42, 58, 71, 57, -1,
+ 43, 44, 60, 59, -1,
+ 44, 45, 61, 60, -1,
+ 45, 46, 62, 61, -1,
+ 46, 47, 63, 62, -1,
+ 47, 48, 64, 63, -1,
+ 48, 49, 65, 64, -1,
+ 49, 50, 66, 65, -1,
+ 50, 51, 67, 66, -1,
+ 51, 52, 68, 67, -1,
+ 56, 57, 71, 70, -1,
+ 58, 59, 73, 72, -1,
+ 58, 72, 87, 71, -1,
+ 59, 60, 74, 73, -1,
+ 60, 61, 75, 74, -1,
+ 61, 62, 76, 75, -1,
+ 62, 63, 77, 76, -1,
+ 63, 64, 78, 77, -1,
+ 64, 65, 79, 78, -1,
+ 65, 66, 80, 79, -1,
+ 66, 67, 81, 80, -1,
+ 67, 68, 82, 81, -1,
+ 69, 123, 127, 84, -1,
+ 70, 71, 87, 86, -1,
+ 72, 73, 89, 88, -1,
+ 72, 88, 103, 87, -1,
+ 73, 74, 90, 89, -1,
+ 74, 75, 91, 90, -1,
+ 75, 76, 92, 91, -1,
+ 76, 77, 93, 92, -1,
+ 77, 78, 94, 93, -1,
+ 78, 79, 95, 94, -1,
+ 79, 80, 96, 95, -1,
+ 80, 81, 97, 96, -1,
+ 81, 82, 98, 97, -1,
+ 82, 83, 99, 98, -1,
+ 83, 84, 100, 99, -1,
+ 84, 85, 101, 100, -1,
+ 85, 86, 102, 101, -1,
+ 86, 87, 103, 102, -1,
+ 88, 89, 105, 104, -1,
+ 88, 104, 119, 103, -1,
+ 89, 90, 106, 105, -1,
+ 90, 91, 107, 106, -1,
+ 91, 92, 108, 107, -1,
+ 92, 93, 109, 108, -1,
+ 93, 94, 110, 109, -1,
+ 94, 95, 111, 110, -1,
+ 95, 96, 112, 111, -1,
+ 96, 97, 113, 112, -1,
+ 97, 98, 114, 113, -1,
+ 98, 99, 115, 114, -1,
+ 99, 100, 116, 115, -1,
+ 100, 101, 117, 116, -1,
+ 101, 102, 118, 117, -1,
+ 102, 103, 119, 118, -1,
+ 104, 105, 121, -1,
+ 104, 121, 119, -1,
+ 105, 106, 121, -1,
+ 106, 107, 121, -1,
+ 107, 108, 121, -1,
+ 108, 109, 121, -1,
+ 109, 110, 121, -1,
+ 110, 111, 121, -1,
+ 111, 112, 121, -1,
+ 112, 113, 121, -1,
+ 113, 114, 121, -1,
+ 114, 115, 121, -1,
+ 115, 116, 121, -1,
+ 116, 117, 121, -1,
+ 117, 118, 121, -1,
+ 118, 119, 121, -1 ]
+ normal Normal { vector [
+ -0.6240633571449417 -0.7485126584990751 0.2242180330295314,
+ -0.650954127081745 0.7404676088514826 0.1672317095440063,
+ 0.650954127081745 0.7404676088514826 0.16723170954400657,
+ 0.6318942805859536 -0.751054552590261 0.19138097396607326,
+ -0.5773502691896258 -0.5773502691896258 -0.5773502691896258,
+ -0.5773502691896258 0.5773502691896258 -0.5773502691896258,
+ 0.5773502691896258 0.5773502691896258 -0.5773502691896258,
+ 0.5773502691896258 -0.5773502691896258 -0.5773502691896258,
+ 0.0 0.565148350259218 -0.8249892982331858,
+ -0.23500029272775183 -0.6317521592780225 -0.7386907821716926,
+ 0.38219483938718757 0.9240817630198109 -2.1651891604597196e-16,
+ 0.3531019895412615 0.9240817630198108 0.14625963296891295,
+ 0.2702525626651842 0.9240817630198107 0.27025256266518366,
+ 0.14625963296891326 0.9240817630198107 0.3531019895412615,
+ -3.5494904269831466e-18 0.9240817630198109 0.3821948393871877,
+ -0.1462596329689133 0.9240817630198109 0.3531019895412611,
+ -0.27025256266518427 0.9240817630198107 0.2702525626651838,
+ -0.3531019895412614 0.9240817630198107 0.14625963296891334,
+ -0.3821948393871877 0.9240817630198109 -5.3242356404747206e-17,
+ -0.35310198954126143 0.9240817630198108 -0.146259632968913,
+ -0.27025256266518427 0.9240817630198108 -0.27025256266518355,
+ -0.14625963296891334 0.9240817630198107 -0.35310198954126143,
+ 1.4197961707932586e-17 0.9240817630198109 -0.3821948393871877,
+ 0.14625963296891342 0.9240817630198109 -0.3531019895412611,
+ 0.2702525626651843 0.9240817630198107 -0.2702525626651838,
+ 0.35310198954126126 0.9240817630198108 -0.14625963296891348,
+ 0.7065844951662994 0.7076286817184462 -1.3574214643678983e-16,
+ 0.6527989530739642 0.7076286817184461 0.2703981798661935,
+ 0.4996306880133637 0.7076286817184461 0.49963068801336363,
+ 0.2703981798661935 0.707628681718446 0.6527989530739644,
+ 7.14432349667315e-18 0.707628681718446 0.7065844951662995,
+ -0.2703981798661935 0.7076286817184461 0.6527989530739644,
+ -0.49963068801336347 0.707628681718446 0.4996306880133637,
+ -0.6527989530739642 0.7076286817184461 0.27039817986619374,
+ -0.7065844951662994 0.7076286817184462 0.0,
+ -0.6527989530739643 0.7076286817184461 -0.2703981798661933,
+ -0.4996306880133637 0.7076286817184462 -0.4996306880133633,
+ -0.27039817986619363 0.7076286817184462 -0.6527989530739641,
+ 1.42886469933463e-17 0.7076286817184462 -0.7065844951662993,
+ 0.2703981798661937 0.7076286817184462 -0.6527989530739642,
+ 0.4996306880133635 0.7076286817184461 -0.4996306880133637,
+ 0.652798953073964 0.7076286817184461 -0.27039817986619386,
+ 0.9236821150189284 0.3831596930708646 -1.5098010521668608e-16,
+ 0.8533710006127241 0.38315969307086456 0.35347784218968914,
+ 0.6531418871906168 0.3831596930708645 0.6531418871906169,
+ 0.35347784218968903 0.38315969307086445 0.8533710006127243,
+ 7.189528819842194e-18 0.3831596930708645 0.9236821150189285,
+ -0.35347784218968903 0.3831596930708644 0.8533710006127243,
+ -0.6531418871906165 0.3831596930708646 0.653141887190617,
+ -0.853371000612724 0.3831596930708647 0.3534778421896893,
+ -0.9236821150189283 0.38315969307086467 3.594764409921097e-17,
+ -0.8533710006127242 0.38315969307086467 -0.35347784218968886,
+ -0.7223342359851773 0.5963875260285549 -0.3500788058726916,
+ -0.21775214356583708 0.5866924766250825 -0.7799845779526734,
+ 2.860287267299096e-17 0.3713065094700714 -0.9285103532137656,
+ 0.21775214356583705 0.5866924766250825 -0.7799845779526734,
+ 0.7223342359851772 0.5963875260285552 -0.3500788058726921,
+ 0.853371000612724 0.3831596930708647 -0.3534778421896896,
+ 1.0 1.4416425122373137e-17 -1.2974782610135823e-16,
+ 0.9238795325112867 7.208212561186569e-18 0.3826834323650898,
+ 0.7071067811865474 0.0 0.7071067811865476,
+ 0.3826834323650897 0.0 0.9238795325112867,
+ 0.0 0.0 1.0,
+ -0.3826834323650897 0.0 0.9238795325112867,
+ -0.7071067811865472 0.0 0.7071067811865479,
+ -0.9238795325112867 7.208212561186569e-18 0.38268343236509,
+ -1.0 2.1624637683559703e-17 2.883285024474627e-17,
+ -0.9238795325112868 1.4416425122373134e-17 -0.3826834323650895,
+ -0.979804198942987 -8.001428153710795e-5 0.1999593091891605,
+ 0.0 0.0 0.0,
+ 0.9798041989429871 -8.001428153710805e-5 0.19995930918916033,
+ 0.9238795325112865 2.1624637683559706e-17 -0.3826834323650903,
+ 0.9236821150189284 -0.38315969307086456 -1.150324611174751e-16,
+ 0.8533710006127242 -0.38315969307086456 0.35347784218968925,
+ 0.6531418871906167 -0.38315969307086445 0.653141887190617,
+ 0.35347784218968903 -0.38315969307086445 0.8533710006127243,
+ 0.0 -0.38315969307086456 0.9236821150189284,
+ -0.3534778421896891 -0.3831596930708645 0.8533710006127242,
+ -0.6531418871906165 -0.3831596930708645 0.6531418871906172,
+ -0.8533710006127241 -0.3831596930708646 0.35347784218968925,
+ -0.9236821150189284 -0.38315969307086456 5.751623055873755e-17,
+ -0.8533710006127242 -0.38315969307086456 -0.353477842189689,
+ -0.7206785268238779 -0.6196204571264978 -0.310954900404086,
+ -0.20878340774558274 -0.6418351695013081 -0.7378733657216316,
+ 0.07524776421035834 -0.273464800429631 -0.9589341879958835,
+ 0.3103679659015334 -0.4910959505070567 -0.8139388755537575,
+ 0.716861671283461 -0.610664583830416 -0.33644926853822693,
+ 0.853371000612724 -0.38315969307086456 -0.3534778421896897,
+ 0.7065844951662995 -0.7076286817184458 -9.287620545675093e-17,
+ 0.6527989530739644 -0.707628681718446 0.27039817986619374,
+ 0.4996306880133637 -0.7076286817184458 0.49963068801336386,
+ 0.2703981798661937 -0.7076286817184457 0.6527989530739646,
+ 0.0 -0.7076286817184456 0.7065844951662998,
+ -0.27039817986619374 -0.7076286817184457 0.6527989530739645,
+ -0.4996306880133637 -0.7076286817184458 0.49963068801336397,
+ -0.6527989530739644 -0.707628681718446 0.2703981798661938,
+ -0.7065844951662995 -0.7076286817184458 7.144323496673148e-17,
+ -0.6527989530739644 -0.7076286817184458 -0.2703981798661936,
+ -0.4996306880133638 -0.7076286817184458 -0.49963068801336363,
+ -0.2703981798661938 -0.707628681718446 -0.6527989530739644,
+ 3.572161748336574e-18 -0.7076286817184457 -0.7065844951662996,
+ 0.27039817986619386 -0.7076286817184457 -0.6527989530739644,
+ 0.49963068801336363 -0.7076286817184457 -0.49963068801336397,
+ 0.6527989530739642 -0.7076286817184458 -0.270398179866194,
+ 0.3821948393871877 -0.9240817630198108 -7.098980853966295e-18,
+ 0.3531019895412617 -0.9240817630198107 0.14625963296891312,
+ 0.2702525626651844 -0.9240817630198106 0.2702525626651842,
+ 0.1462596329689137 -0.9240817630198106 0.35310198954126193,
+ 0.0 -0.9240817630198107 0.38219483938718807,
+ -0.14625963296891378 -0.9240817630198106 0.35310198954126165,
+ -0.2702525626651844 -0.9240817630198106 0.2702525626651842,
+ -0.35310198954126165 -0.9240817630198107 0.14625963296891337,
+ -0.38219483938718785 -0.9240817630198108 -6.389082768569665e-17,
+ -0.3531019895412615 -0.9240817630198108 -0.14625963296891303,
+ -0.2702525626651844 -0.9240817630198106 -0.2702525626651839,
+ -0.14625963296891378 -0.9240817630198106 -0.3531019895412619,
+ -3.549490426983147e-18 -0.9240817630198107 -0.3821948393871882,
+ 0.14625963296891384 -0.9240817630198107 -0.35310198954126154,
+ 0.27025256266518444 -0.9240817630198106 -0.27025256266518427,
+ 0.3531019895412614 -0.9240817630198108 -0.14625963296891342,
+ -1.770039962878225e-18 1.0 -8.09793283016788e-17,
+ -1.41603197030258e-17 -1.0 2.389553949885604e-17,
+ -0.05434413215433992 -0.8828441771580279 -0.4665113869548697,
+ 0.0 0.0 0.0,
+ -0.0722585041213054 0.8311532080571771 -0.551328444140527,
+ -0.7892432490336516 -8.362826735961186e-5 0.6140806843250473,
+ 0.07225850412130536 0.8311532080571772 -0.5513284441405267,
+ 0.34814845525242477 0.40992601037208287 -0.8430618714695721,
+ 0.7892432490336513 -8.362826735961187e-5 0.6140806843250476 ] }
+ normalIndex [
+ 0, 4, 7, 3, 9, 122, -1,
+ 0, 82, 68, 125, -1,
+ 0, 122, 83, 82, -1,
+ 0, 125, 1, 5, 4, -1,
+ 1, 52, 53, 124, -1,
+ 1, 124, 8, 126, 2, 6, 5, -1,
+ 1, 125, 68, 52, -1,
+ 2, 56, 70, 128, -1,
+ 2, 126, 55, 56, -1,
+ 2, 128, 3, 7, 6, -1,
+ 3, 86, 85, 9, -1,
+ 3, 128, 70, 86, -1,
+ 4, 5, 6, 7, -1,
+ 8, 54, 55, 126, -1,
+ 8, 54, 69, 123, -1,
+ 8, 123, 69, 54, -1,
+ 8, 124, 53, 54, -1,
+ 9, 84, 83, 122, -1,
+ 9, 85, 84, 127, -1,
+ 9, 127, 123, 69, 84, -1,
+ 10, 11, 27, 26, -1,
+ 10, 25, 120, -1,
+ 10, 26, 41, 25, -1,
+ 10, 120, 11, -1,
+ 11, 12, 28, 27, -1,
+ 11, 120, 12, -1,
+ 12, 13, 29, 28, -1,
+ 12, 120, 13, -1,
+ 13, 14, 30, 29, -1,
+ 13, 120, 14, -1,
+ 14, 15, 31, 30, -1,
+ 14, 120, 15, -1,
+ 15, 16, 32, 31, -1,
+ 15, 120, 16, -1,
+ 16, 17, 33, 32, -1,
+ 16, 120, 17, -1,
+ 17, 18, 34, 33, -1,
+ 17, 120, 18, -1,
+ 18, 19, 35, 34, -1,
+ 18, 120, 19, -1,
+ 19, 20, 36, 35, -1,
+ 19, 120, 20, -1,
+ 20, 21, 37, 36, -1,
+ 20, 120, 21, -1,
+ 21, 22, 38, 37, -1,
+ 21, 120, 22, -1,
+ 22, 23, 39, 38, -1,
+ 22, 120, 23, -1,
+ 23, 24, 40, 39, -1,
+ 23, 120, 24, -1,
+ 24, 25, 41, 40, -1,
+ 24, 120, 25, -1,
+ 26, 27, 43, 42, -1,
+ 26, 42, 57, 41, -1,
+ 27, 28, 44, 43, -1,
+ 28, 29, 45, 44, -1,
+ 29, 30, 46, 45, -1,
+ 30, 31, 47, 46, -1,
+ 31, 32, 48, 47, -1,
+ 32, 33, 49, 48, -1,
+ 33, 34, 50, 49, -1,
+ 34, 35, 51, 50, -1,
+ 35, 36, 52, 51, -1,
+ 36, 37, 53, 52, -1,
+ 37, 38, 54, 53, -1,
+ 38, 39, 55, 54, -1,
+ 39, 40, 56, 55, -1,
+ 40, 41, 57, 56, -1,
+ 42, 43, 59, 58, -1,
+ 42, 58, 71, 57, -1,
+ 43, 44, 60, 59, -1,
+ 44, 45, 61, 60, -1,
+ 45, 46, 62, 61, -1,
+ 46, 47, 63, 62, -1,
+ 47, 48, 64, 63, -1,
+ 48, 49, 65, 64, -1,
+ 49, 50, 66, 65, -1,
+ 50, 51, 67, 66, -1,
+ 51, 52, 68, 67, -1,
+ 56, 57, 71, 70, -1,
+ 58, 59, 73, 72, -1,
+ 58, 72, 87, 71, -1,
+ 59, 60, 74, 73, -1,
+ 60, 61, 75, 74, -1,
+ 61, 62, 76, 75, -1,
+ 62, 63, 77, 76, -1,
+ 63, 64, 78, 77, -1,
+ 64, 65, 79, 78, -1,
+ 65, 66, 80, 79, -1,
+ 66, 67, 81, 80, -1,
+ 67, 68, 82, 81, -1,
+ 69, 123, 127, 84, -1,
+ 70, 71, 87, 86, -1,
+ 72, 73, 89, 88, -1,
+ 72, 88, 103, 87, -1,
+ 73, 74, 90, 89, -1,
+ 74, 75, 91, 90, -1,
+ 75, 76, 92, 91, -1,
+ 76, 77, 93, 92, -1,
+ 77, 78, 94, 93, -1,
+ 78, 79, 95, 94, -1,
+ 79, 80, 96, 95, -1,
+ 80, 81, 97, 96, -1,
+ 81, 82, 98, 97, -1,
+ 82, 83, 99, 98, -1,
+ 83, 84, 100, 99, -1,
+ 84, 85, 101, 100, -1,
+ 85, 86, 102, 101, -1,
+ 86, 87, 103, 102, -1,
+ 88, 89, 105, 104, -1,
+ 88, 104, 119, 103, -1,
+ 89, 90, 106, 105, -1,
+ 90, 91, 107, 106, -1,
+ 91, 92, 108, 107, -1,
+ 92, 93, 109, 108, -1,
+ 93, 94, 110, 109, -1,
+ 94, 95, 111, 110, -1,
+ 95, 96, 112, 111, -1,
+ 96, 97, 113, 112, -1,
+ 97, 98, 114, 113, -1,
+ 98, 99, 115, 114, -1,
+ 99, 100, 116, 115, -1,
+ 100, 101, 117, 116, -1,
+ 101, 102, 118, 117, -1,
+ 102, 103, 119, 118, -1,
+ 104, 105, 121, -1,
+ 104, 121, 119, -1,
+ 105, 106, 121, -1,
+ 106, 107, 121, -1,
+ 107, 108, 121, -1,
+ 108, 109, 121, -1,
+ 109, 110, 121, -1,
+ 110, 111, 121, -1,
+ 111, 112, 121, -1,
+ 112, 113, 121, -1,
+ 113, 114, 121, -1,
+ 114, 115, 121, -1,
+ 115, 116, 121, -1,
+ 116, 117, 121, -1,
+ 117, 118, 121, -1,
+ 118, 119, 121, -1 ]
+ }
+ }
+}
+
+DEF cube1 Transform {
+ Shape {
+ appearance Appearance {
+ material USE default
+ }
+ geometry IndexedFaceSet {
+ normalPerVertex TRUE
+ coord Coordinate { point [
+ -0.9985037461920492 -6.73734278962182e-4 -0.004764781349210434,
+ -0.9985037461920492 0.6313262657210368 -0.004764781349210434,
+ -0.8506157461920497 0.6313262657210368 -0.004764781349210434,
+ -0.8506157461920497 -6.73734278962182e-4 -0.004764781349210434,
+ -0.9985037461920492 -6.73734278962182e-4 -1.1044447813492089,
+ -0.9985037461920492 0.6313262657210368 -1.1044447813492089,
+ -0.8506157461920497 0.6313262657210368 -1.1044447813492089,
+ -0.8506157461920497 -6.73734278962182e-4 -1.1044447813492089 ] }
+ coordIndex [
+ 0, 1, 5, 4, -1,
+ 0, 3, 2, 1, -1,
+ 0, 4, 7, 3, -1,
+ 1, 2, 6, 5, -1,
+ 2, 3, 7, 6, -1,
+ 4, 5, 6, 7, -1 ]
+ normal Normal { vector [
+ -0.5773502691896258 -0.5773502691896258 0.5773502691896258,
+ -0.5773502691896258 0.5773502691896258 0.5773502691896258,
+ 0.5773502691896258 0.5773502691896258 0.5773502691896258,
+ 0.5773502691896258 -0.5773502691896258 0.5773502691896258,
+ -0.5773502691896258 -0.5773502691896258 -0.5773502691896258,
+ -0.5773502691896258 0.5773502691896258 -0.5773502691896258,
+ 0.5773502691896258 0.5773502691896258 -0.5773502691896258,
+ 0.5773502691896258 -0.5773502691896258 -0.5773502691896258 ] }
+ normalIndex [
+ 0, 1, 5, 4, -1,
+ 0, 3, 2, 1, -1,
+ 0, 4, 7, 3, -1,
+ 1, 2, 6, 5, -1,
+ 2, 3, 7, 6, -1,
+ 4, 5, 6, 7, -1 ]
+ }
+ }
+}
+
diff --git a/tool_src/redhat_install_build_deps32.sh b/tool_src/redhat_install_build_deps32.sh
new file mode 100755
index 0000000..884f3fb
--- /dev/null
+++ b/tool_src/redhat_install_build_deps32.sh
@@ -0,0 +1,25 @@
+#!/bin/bash
+echo; echo;
+echo "This program should, in theory, install all the deps needed to"
+echo "compile Open Parsec on a Red Hat based system (RHEL 6.x and higher"
+echo; echo;
+echo "*** WARNING *** *** WARNING *** *** WARNING *** "
+echo ; echo
+echo "This program WILL remove some programs which depend on 64bit SDL"
+echo "since 32bit SDL cannot co-exist at the moment. You will be prompted"
+echo "by yum to remove them."
+echo; echo
+echo "Press Enter to continue."
+read
+echo "Attempting to remove previous verisons of SDL..."
+yum remove "SDL*"
+if [ "$?" -ne "0" ]
+then
+ echo "*** Exiting on user cancel. Open Parsec Build Dependencies not installed!!!"
+ exit 1
+fi
+
+echo;
+echo;
+echo "Installing build Dependencies."
+yum -y install glibc-devel.i686 libjpeg-devel.i686 libstdc++-devel.i686 libXext-devel.i686 http://www.libsdl.org/release/SDL-devel-1.2.15-1.i386.rpm http://www.libsdl.org/release/SDL-1.2.15-1.i386.rpm http://www.libsdl.org/projects/SDL_mixer/release/SDL_mixer-1.2.12-1.i386.rpm http://www.libsdl.org/projects/SDL_mixer/release/SDL_mixer-devel-1.2.12-1.i386.rpm