moved files around

This commit is contained in:
ejcoumans
2006-05-25 19:18:29 +00:00
commit e061ec1ebf
1024 changed files with 349445 additions and 0 deletions

View File

@@ -0,0 +1,48 @@
/*
Copyright (C) 2005-2006 Feeling Software Inc.
MIT License: http://www.opensource.org/licenses/mit-license.php
*/
/**
@file FUAssert.h
This file contains a simple debugging assertion mechanism.
*/
#ifndef _FU_ASSERT_H_
#define _FU_ASSERT_H_
/**
Breaks into the debugger.
In debug builds, this intentionally crashes the application.
In release builds, this is an empty function.
*/
inline void DEBUGGER_BREAK()
{
#ifdef _DEBUG
#ifdef WIN32
_asm int 3;
#else
// Force a crash?
uint32* __p = NULL;
uint32 __v = *__p;
*__p = 0xD1ED0D1E;
__v = __v + 1;
#endif // WIN32
#endif // _DEBUG
}
/** Forces the debugger to break, or take the fall-back.
@param command The fall_back command to execute. */
#define FUFail(command) { DEBUGGER_BREAK(); command; }
/** Asserts that a condition is met.
Use this macro, instead of 'if' statements
when you are asserting for a programmer's error.
@param condition The condition to assert.
@param fall_back The command to execute if the condition is not met. */
#define FUAssert(condition, fall_back) { if (!(condition)) { DEBUGGER_BREAK(); fall_back; } }
#endif // _FU_ASSERT_H_

View File

@@ -0,0 +1,122 @@
/*
Copyright (C) 2005-2006 Feeling Software Inc.
MIT License: http://www.opensource.org/licenses/mit-license.php
*/
/*
Based on the FS Import classes:
Copyright (C) 2005-2006 Feeling Software Inc
Copyright (C) 2005-2006 Autodesk Media Entertainment
MIT License: http://www.opensource.org/licenses/mit-license.php
*/
#include "StdAfx.h"
#include "FUtils/FUCrc32.h"
namespace FUCrc32
{
const uint32 kCRCTable[256] = {
0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3,
0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91,
0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5,
0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B,
0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F,
0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D,
0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01,
0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457,
0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB,
0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9,
0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD,
0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683,
0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7,
0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5,
0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79,
0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F,
0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713,
0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21,
0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45,
0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB,
0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF,
0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D
};
#ifdef UNICODE
crc32 CRC32(const fstring& s) { return CRC32(s.c_str()); }
crc32 CRC32(const fchar* sz)
{
uint32 crc = 0xffffffff;
while(*sz != 0)
{
crc = (crc >> 8) ^ kCRCTable[(crc & 0xFF) ^ (uint8)(*sz++)];
}
return (crc32) (crc ^ 0xffffffff);
}
#endif // UNICODE
crc32 CRC32(const string& s) { return CRC32(s.c_str()); }
crc32 CRC32(const char* sz)
{
uint32 crc = 0xffffffff;
while(*sz != 0)
{
crc = (crc >> 8) ^ kCRCTable[(crc & 0xFF) ^ (uint8)(*sz++)];
}
return (crc32) (crc ^ 0xffffffff);
}
/*
// ** The above table was created using the following code:
** Adapted from http://www.createwindow.com/programming/crc32/
unsigned long Reflect(unsigned long ref, char ch)
{
unsigned long value(0);
for(long i = 1; i < (ch + 1); i++)
{
if(ref & 1)
value |= 1 << (ch - i);
ref >>= 1;
}
return value;
}
static void InitCRCTable()
{
unsigned long ulPolynomial = 0x04c11db7;
ofstream fOut;
fOut.open("CRCTable.txt", ios_base::out | ios_base::binary);
assert(fOut.is_open());
for(long i = 0; i <= 0xFF; i++)
{
g_uiCRCTable[i]=Reflect(i, 8) << 24;
for (long j = 0; j < 8; j++)
g_uiCRCTable[i] = (g_uiCRCTable[i] << 1) ^ (g_uiCRCTable[i] & (1 << 31) ? ulPolynomial : 0);
g_uiCRCTable[i] = Reflect(g_uiCRCTable[i], 32);
char sz[256];
snprintf(sz, 256, "0x%08X, ", g_uiCRCTable[i]);
fOut << sz;
}
fOut.close();
}
*/
};

View File

@@ -0,0 +1,41 @@
/*
Copyright (C) 2005-2006 Feeling Software Inc.
MIT License: http://www.opensource.org/licenses/mit-license.php
*/
/*
Based on the FS Import classes:
Copyright (C) 2005-2006 Feeling Software Inc
Copyright (C) 2005-2006 Autodesk Media Entertainment
MIT License: http://www.opensource.org/licenses/mit-license.php
*/
/**
@file FUCrc32.h
This file contains the CRC-32 hashing functions.
*/
#ifndef _FU_CRC32_H_
#define _FU_CRC32_H_
/**
CRC-32 hashing functions.
CRC-32 is a commonly used hashing mechanism for strings.
@ingroup FUtils
*/
namespace FUCrc32
{
/** A CRC32 hash value. */
typedef uint32 crc32;
/** Hashes a string.
@param text The string to hash.
@return The 32-bit hash value. */
crc32 FCOLLADA_EXPORT CRC32(const fstring& text);
crc32 FCOLLADA_EXPORT CRC32(const fchar* text); /**< See above. */
crc32 FCOLLADA_EXPORT CRC32(const string& text); /**< See above. */
crc32 FCOLLADA_EXPORT CRC32(const char* text); /**< See above. */
};
#endif // _FU_CRC32_H_

View File

@@ -0,0 +1,228 @@
/*
Copyright (C) 2005-2006 Feeling Software Inc.
MIT License: http://www.opensource.org/licenses/mit-license.php
*/
/*
Based on the FS Import classes:
Copyright (C) 2005-2006 Feeling Software Inc
Copyright (C) 2005-2006 Autodesk Media Entertainment
MIT License: http://www.opensource.org/licenses/mit-license.php
*/
#include "StdAfx.h"
#include "FUtils/FUDaeEnum.h"
#include "FUtils/FUDaeSyntax.h"
namespace FUDaeInterpolation
{
Interpolation FromString(const string& value)
{
if (value == DAE_NONE_INTERPOLATION) return STEP;
else if (value == DAE_STEP_INTERPOLATION) return STEP;
else if (value == DAE_LINEAR_INTERPOLATION) return LINEAR;
else if (value == DAE_BEZIER_INTERPOLATION) return BEZIER;
else return UNKNOWN;
}
const char* ToString(const Interpolation& value)
{
switch (value)
{
case STEP: return DAE_STEP_INTERPOLATION;
case LINEAR: return DAE_LINEAR_INTERPOLATION;
case BEZIER: return DAE_BEZIER_INTERPOLATION;
case UNKNOWN:
default: return DAEERR_UNKNOWN_ELEMENT;
}
}
};
namespace FUDaeFunction
{
Function FromString(const char* value)
{
if (IsEquivalent(value, DAE_CONSTANT_FUNCTION)) return CONSTANT;
else if (IsEquivalent(value, DAE_LINEAR_FUNCTION)) return LINEAR;
else if (IsEquivalent(value, DAE_QUADRATIC_FUNCTION)) return QUADRATIC;
else return UNKNOWN;
}
};
namespace FUDaeTextureChannel
{
Channel FromString(const string& value)
{
if (value == DAE_AMBIENT_TEXTURE_CHANNEL) return AMBIENT;
else if (value == DAE_BUMP_TEXTURE_CHANNEL) return BUMP;
else if (value == DAE_DIFFUSE_TEXTURE_CHANNEL) return DIFFUSE;
else if (value == DAE_DISPLACEMENT_TEXTURE_CHANNEL) return DISPLACEMENT;
else if (value == DAE_EMISSION_TEXTURE_CHANNEL) return EMISSION;
else if (value == DAE_FILTER_TEXTURE_CHANNEL) return FILTER;
else if (value == DAE_OPACITY_TEXTURE_CHANNEL) return OPACITY;
else if (value == DAE_REFLECTION_TEXTURE_CHANNEL) return REFLECTION;
else if (value == DAE_REFRACTION_TEXTURE_CHANNEL) return REFRACTION;
else if (value == DAE_SHININESS_TEXTURE_CHANNEL) return SHININESS;
else if (value == DAE_SPECULAR_TEXTURE_CHANNEL) return SPECULAR;
else if (value == DAE_SPECULARLEVEL_TEXTURE_CHANNEL) return SPECULAR_LEVEL;
else if (value == DAE_TRANSPARENT_TEXTURE_CHANNEL) return TRANSPARENT;
else return UNKNOWN;
}
};
namespace FUDaeMorphMethod
{
Method FromString(const char* value)
{
if (IsEquivalent(value, DAE_NORMALIZED_MORPH_METHOD)) return NORMALIZED;
else if (IsEquivalent(value, DAE_RELATIVE_MORPH_METHOD)) return RELATIVE;
else return DEFAULT;
}
const char* ToString(Method method)
{
switch (method)
{
case NORMALIZED: return DAE_NORMALIZED_MORPH_METHOD;
case RELATIVE: return DAE_RELATIVE_MORPH_METHOD;
case UNKNOWN:
default: return DAEERR_UNKNOWN_MORPH_METHOD;
}
}
};
namespace FUDaeInfinity
{
Infinity FromString(const char* value)
{
if (IsEquivalent(value, DAEMAYA_CONSTANT_INFINITY)) return CONSTANT;
else if (IsEquivalent(value, DAEMAYA_LINEAR_INFINITY)) return LINEAR;
else if (IsEquivalent(value, DAEMAYA_CYCLE_INFINITY)) return CYCLE;
else if (IsEquivalent(value, DAEMAYA_CYCLE_RELATIVE_INFINITY)) return CYCLE_RELATIVE;
else if (IsEquivalent(value, DAEMAYA_OSCILLATE_INFINITY)) return OSCILLATE;
else return DEFAULT;
}
const char* ToString(Infinity type)
{
switch (type)
{
case CONSTANT: return DAEMAYA_CONSTANT_INFINITY;
case LINEAR: return DAEMAYA_LINEAR_INFINITY;
case CYCLE: return DAEMAYA_CYCLE_INFINITY;
case CYCLE_RELATIVE: return DAEMAYA_CYCLE_RELATIVE_INFINITY;
case OSCILLATE: return DAEMAYA_OSCILLATE_INFINITY;
default: return DAEMAYA_CONSTANT_INFINITY;
}
}
};
namespace FUDaeBlendMode
{
Mode FromString(const char* value)
{
if (IsEquivalent(value, DAEMAYA_NONE_BLENDMODE)) return NONE;
else if (IsEquivalent(value, DAEMAYA_OVER_BLENDMODE)) return OVER;
else if (IsEquivalent(value, DAEMAYA_IN_BLENDMODE)) return IN;
else if (IsEquivalent(value, DAEMAYA_OUT_BLENDMODE)) return OUT;
else if (IsEquivalent(value, DAEMAYA_ADD_BLENDMODE)) return ADD;
else if (IsEquivalent(value, DAEMAYA_SUBSTRACT_BLENDMODE)) return SUBSTRACT;
else if (IsEquivalent(value, DAEMAYA_MULTIPLY_BLENDMODE)) return MULTIPLY;
else if (IsEquivalent(value, DAEMAYA_DIFFERENCE_BLENDMODE)) return DIFFERENCE;
else if (IsEquivalent(value, DAEMAYA_LIGHTEN_BLENDMODE)) return LIGHTEN;
else if (IsEquivalent(value, DAEMAYA_DARKEN_BLENDMODE)) return DARKEN;
else if (IsEquivalent(value, DAEMAYA_SATURATE_BLENDMODE)) return SATURATE;
else if (IsEquivalent(value, DAEMAYA_DESATURATE_BLENDMODE)) return DESATURATE;
else if (IsEquivalent(value, DAEMAYA_ILLUMINATE_BLENDMODE)) return ILLUMINATE;
else return UNKNOWN;
}
const char* ToString(Mode mode)
{
switch (mode)
{
case NONE: return DAEMAYA_NONE_BLENDMODE;
case OVER: return DAEMAYA_OVER_BLENDMODE;
case IN: return DAEMAYA_IN_BLENDMODE;
case OUT: return DAEMAYA_OUT_BLENDMODE;
case ADD: return DAEMAYA_ADD_BLENDMODE;
case SUBSTRACT: return DAEMAYA_SUBSTRACT_BLENDMODE;
case MULTIPLY: return DAEMAYA_MULTIPLY_BLENDMODE;
case DIFFERENCE: return DAEMAYA_DIFFERENCE_BLENDMODE;
case LIGHTEN: return DAEMAYA_LIGHTEN_BLENDMODE;
case DARKEN: return DAEMAYA_DARKEN_BLENDMODE;
case SATURATE: return DAEMAYA_SATURATE_BLENDMODE;
case DESATURATE: return DAEMAYA_DESATURATE_BLENDMODE;
case ILLUMINATE: return DAEMAYA_ILLUMINATE_BLENDMODE;
default: return DAEMAYA_NONE_BLENDMODE;
}
}
}
namespace FUDaeGeometryInput
{
Semantic FromString(const char* value)
{
if (IsEquivalent(value, DAE_POSITION_INPUT)) return POSITION;
else if (IsEquivalent(value, DAE_VERTEX_INPUT)) return VERTEX;
else if (IsEquivalent(value, DAE_NORMAL_INPUT)) return NORMAL;
else if (IsEquivalent(value, DAE_GEOTANGENT_INPUT)) return GEOTANGENT;
else if (IsEquivalent(value, DAE_GEOBINORMAL_INPUT)) return GEOBINORMAL;
else if (IsEquivalent(value, DAE_TEXCOORD_INPUT)) return TEXCOORD;
else if (IsEquivalent(value, DAE_TEXTANGENT_INPUT)) return TEXTANGENT;
else if (IsEquivalent(value, DAE_TEXBINORMAL_INPUT)) return TEXBINORMAL;
else if (IsEquivalent(value, DAE_MAPPING_INPUT)) return UV;
else if (IsEquivalent(value, DAE_COLOR_INPUT)) return COLOR;
else if (IsEquivalent(value, DAEMAYA_EXTRA_INPUT)) return EXTRA;
else return UNKNOWN;
}
const char* ToString(Semantic semantic)
{
switch(semantic)
{
case POSITION: return DAE_POSITION_INPUT;
case VERTEX: return DAE_VERTEX_INPUT;
case NORMAL: return DAE_NORMAL_INPUT;
case GEOTANGENT: return DAE_GEOTANGENT_INPUT;
case GEOBINORMAL: return DAE_GEOBINORMAL_INPUT;
case TEXCOORD: return DAE_TEXCOORD_INPUT;
case TEXTANGENT: return DAE_TEXTANGENT_INPUT;
case TEXBINORMAL: return DAE_TEXBINORMAL_INPUT;
case UV: return DAE_MAPPING_INPUT;
case COLOR: return DAE_COLOR_INPUT;
case EXTRA: return DAEMAYA_EXTRA_INPUT;
case UNKNOWN:
default: return DAEERR_UNKNOWN_INPUT;
}
}
}
namespace FUDaeProfileType
{
Type FromString(const char* value)
{
if (IsEquivalent(value, DAE_FX_PROFILE_COMMON_ELEMENT)) return COMMON;
else if (IsEquivalent(value, DAE_FX_PROFILE_CG_ELEMENT)) return CG;
else if (IsEquivalent(value, DAE_FX_PROFILE_HLSL_ELEMENT)) return HLSL;
else if (IsEquivalent(value, DAE_FX_PROFILE_GLSL_ELEMENT)) return GLSL;
else if (IsEquivalent(value, DAE_FX_PROFILE_GLES_ELEMENT)) return GLES;
else return UNKNOWN;
}
const char* ToString(Type type)
{
switch(type)
{
case COMMON: return DAE_FX_PROFILE_COMMON_ELEMENT;
case CG: return DAE_FX_PROFILE_CG_ELEMENT;
case HLSL: return DAE_FX_PROFILE_HLSL_ELEMENT;
case GLSL: return DAE_FX_PROFILE_GLSL_ELEMENT;
case GLES: return DAE_FX_PROFILE_GLES_ELEMENT;
case UNKNOWN:
default: return DAEERR_UNKNOWN_INPUT;
}
}
}

View File

@@ -0,0 +1,220 @@
/*
Copyright (C) 2005-2006 Feeling Software Inc.
MIT License: http://www.opensource.org/licenses/mit-license.php
*/
/*
Based on the FS Import classes:
Copyright (C) 2005-2006 Feeling Software Inc
Copyright (C) 2005-2006 Autodesk Media Entertainment
MIT License: http://www.opensource.org/licenses/mit-license.php
*/
#ifndef _FU_DAE_ENUM_H_
#define _FU_DAE_ENUM_H_
// Animation curve interpolation function
// Defaults to the STEP interpolation by definition in COLLADA.
// BEZIER is the more common interpolation type
namespace FUDaeInterpolation
{
enum Interpolation
{
STEP = 0, //equivalent to no interpolation
LINEAR,
BEZIER,
UNKNOWN,
DEFAULT = STEP,
};
FCOLLADA_EXPORT Interpolation FromString(const string& value);
const char* ToString(const Interpolation& value);
};
typedef vector<FUDaeInterpolation::Interpolation> FUDaeInterpolationList;
// COLLADA generic degree function. Used by lights and the profile_COMMON materials.
namespace FUDaeFunction
{
enum Function
{
CONSTANT = 0,
LINEAR,
QUADRATIC,
UNKNOWN,
DEFAULT = CONSTANT,
};
FCOLLADA_EXPORT Function FromString(const char* value);
inline Function FromString(const string& value) { return FromString(value.c_str()); }
};
// Material texture channels. Used by profile_common materials to assign textures to channels/slots
// Multi-texturing is done by assigning more than one texture per slot.
// Defaults to diffuse texture slot
#undef TRANSPARENT // Win32: GDI stupidely defines this in the global namespace
namespace FUDaeTextureChannel
{
enum Channel
{
AMBIENT = 0,
BUMP,
DIFFUSE,
DISPLACEMENT,
EMISSION,
FILTER,
OPACITY,
REFLECTION,
REFRACTION,
SHININESS,
SPECULAR,
SPECULAR_LEVEL,
TRANSPARENT,
COUNT,
UNKNOWN,
DEFAULT = DIFFUSE,
};
FCOLLADA_EXPORT Channel FromString(const string& value);
};
// Morph controller method
// NORMALIZED implies that the morph targets all have absolute vertex positions
// RELATIVE implies that the morph targets have relative vertex positions
//
// Whether the vertex position is relative or absolute is irrelevant,
// as long as you use the correct weight generation function:
// NORMALIZED: base_weight = 1.0f - SUM(weight[t])
// RELATIVE: base_weight = 1.0f
// and position[k] = SUM(weight[t][k] * position[t][k])
#undef RELATIVE // Win32: GDI stupidely defines this in the global namespace
namespace FUDaeMorphMethod
{
enum Method
{
NORMALIZED = 0,
RELATIVE,
UNKNOWN,
DEFAULT = NORMALIZED,
};
FCOLLADA_EXPORT Method FromString(const char* value);
FCOLLADA_EXPORT const char* ToString(Method method);
inline Method FromString(const string& value) { return FromString(value.c_str()); }
};
// Maya uses the infinity to determine what happens outside an animation curve
// Intentionally matches the MFnAnimCurve::InfinityType enum
namespace FUDaeInfinity
{
enum Infinity
{
CONSTANT = 0,
LINEAR,
CYCLE,
CYCLE_RELATIVE,
OSCILLATE,
UNKNOWN,
DEFAULT = CONSTANT
};
FCOLLADA_EXPORT Infinity FromString(const char* value);
FCOLLADA_EXPORT const char* ToString(Infinity infinity);
inline Infinity FromString(const string& value) { return FromString(value.c_str()); }
};
// Maya uses the blend mode for texturing purposes
// Intentionally matches the equivalent Maya enum
#undef IN
#undef OUT
#undef DIFFERENCE
namespace FUDaeBlendMode
{
enum Mode
{
NONE,
OVER,
IN,
OUT,
ADD,
SUBSTRACT,
MULTIPLY,
DIFFERENCE,
LIGHTEN,
DARKEN,
SATURATE,
DESATURATE,
ILLUMINATE,
UNKNOWN,
DEFAULT = NONE,
};
FCOLLADA_EXPORT Mode FromString(const char* value);
FCOLLADA_EXPORT const char* ToString(Mode mode);
inline Mode FromString(const string& value) { return FromString(value.c_str()); }
}
// Geometry Input Semantics
// Found in the <mesh><vertices>, <mesh><polygons>...
namespace FUDaeGeometryInput
{
enum Semantic
{
POSITION = 0,
VERTEX,
NORMAL,
GEOTANGENT,
GEOBINORMAL,
TEXCOORD,
TEXTANGENT,
TEXBINORMAL,
UV,
COLOR,
EXTRA, // Maya-specific, used for blind data
UNKNOWN = -1,
};
typedef vector<Semantic> SemanticList;
FCOLLADA_EXPORT Semantic FromString(const char* value);
FCOLLADA_EXPORT const char* ToString(Semantic semantic);
inline Semantic FromString(const string& value) { return FromString(value.c_str()); }
}
/** The types of effect profiles. */
namespace FUDaeProfileType
{
/** Enumerates the types of effect profiles. */
enum Type
{
CG, /**< The CG profile. */
HLSL, /**< The HLSL profile for DirectX. */
GLSL, /**< The GLSL profile for OpenGL. */
GLES, /**< The GLES profile for OpenGL ES. */
COMMON, /**< The common profile which encapsulates the standard lighting equations: Lambert, Phong, Blinn. */
UNKNOWN /**< Not a valid profile type. */
};
/** Converts the COLLADA profile name string to a profile type.
Examples of COLLADA profile name strings are 'profile_CG' and 'profile_COMMON'.
@param value The profile name string.
@return The profile type. */
FCOLLADA_EXPORT Type FromString(const char* value);
inline Type FromString(const string& value) { return FromString(value.c_str()); } /**< See above. */
/** Converts the profile type to its COLLADA profile name string.
Examples of COLLADA profile name strings are 'profile_CG' and 'profile_COMMON'.
@param type The profile type.
@return The name string for the profile type. */
FCOLLADA_EXPORT const char* ToString(Type type);
}
#endif // _FU_DAE_ENUM_H_

View File

@@ -0,0 +1,446 @@
/*
Copyright (C) 2005-2006 Feeling Software Inc.
MIT License: http://www.opensource.org/licenses/mit-license.php
*/
/*
Based on the FS Import classes:
Copyright (C) 2005-2006 Feeling Software Inc
Copyright (C) 2005-2006 Autodesk Media Entertainment
MIT License: http://www.opensource.org/licenses/mit-license.php
*/
#include "StdAfx.h"
#include "FUtils/FUDaeParser.h"
#include "FUtils/FUDaeEnum.h"
#include "FUtils/FUStringConversion.h"
#include "FUtils/FUXmlNodeIdPair.h"
namespace FUDaeParser
{
// Returns the first child node with a given id
xmlNode* FindChildById(xmlNode* parent, const string& id)
{
if (parent != NULL && !id.empty())
{
const char* localId = id.c_str();
if (localId[0] == '#') ++localId;
for (xmlNode* child = parent->children; child != NULL; child = child->next)
{
if (child->type == XML_ELEMENT_NODE)
{
string nodeId = ReadNodeId(child);
if (nodeId == localId) return child;
}
}
}
return NULL;
}
// Returns the first child node of a given "ref" property
xmlNode* FindChildByRef(xmlNode* parent, const char* ref)
{
return FindChildByProperty(parent, DAE_REF_ATTRIBUTE, ref);
}
// Returns the first child with the given 'sid' value within a given xml hierarchy
xmlNode* FindHierarchyChildBySid(xmlNode* hierarchyRoot, const char* sid)
{
xmlNode* found = NULL;
for (xmlNode* child = hierarchyRoot->children; child != NULL && found == NULL; child = child->next)
{
if (child->type != XML_ELEMENT_NODE) continue;
if (ReadNodeProperty(child, DAE_SID_ATTRIBUTE) == sid) return child;
found = FindHierarchyChildBySid(child, sid);
}
return found;
}
// Returns the first technique node with a given profile
xmlNode* FindTechnique(xmlNode* parent, const char* profile)
{
if (parent != NULL)
{
if (IsEquivalent(profile, DAE_COMMON_PROFILE))
{
// COLLADA 1.4: Look for the <technique_common> element
xmlNode* techniqueNode = FindChildByType(parent, DAE_TECHNIQUE_COMMON_ELEMENT);
if (techniqueNode != NULL) return techniqueNode;
}
xmlNodeList techniqueNodes;
FindChildrenByType(parent, DAE_TECHNIQUE_ELEMENT, techniqueNodes);
size_t techniqueNodeCount = techniqueNodes.size();
for (size_t i = 0; i < techniqueNodeCount; ++i)
{
xmlNode* techniqueNode = techniqueNodes[i];
string techniqueProfile = ReadNodeProperty(techniqueNode, DAE_PROFILE_ATTRIBUTE);
if (techniqueProfile == profile) return techniqueNode;
}
}
return NULL;
}
// Returns the accessor node for a given source node
xmlNode* FindTechniqueAccessor(xmlNode* parent)
{
xmlNode* techniqueNode = FindTechnique(parent, DAE_COMMON_PROFILE);
return FindChildByType(techniqueNode, DAE_ACCESSOR_ELEMENT);
}
// Returns the array node from a given array type
xmlNode* FindArray(xmlNode* parent, const char* arrayType)
{
xmlNode* stronglyTypedArrayNode = FindChildByType(parent, arrayType);
if (stronglyTypedArrayNode != NULL) return stronglyTypedArrayNode;
xmlNode* weaklyTypedArrayNode = FindChildByType(parent, DAE_ARRAY_ELEMENT);
if (weaklyTypedArrayNode != NULL) return weaklyTypedArrayNode;
return NULL;
}
// Returns a list of parameter names and nodes held by a given XML node
// Useful for COLLADA 1.3 backward-compatibility: the names are taken from the <param> node's 'name' attribute
void FindParameters(xmlNode* parent, StringList& parameterNames, xmlNodeList& parameterNodes)
{
if (parent == NULL || parameterNames.size() != parameterNodes.size()) return;
size_t originalCount = parameterNodes.size();
for (xmlNode* child = parent->children; child != NULL; child = child->next)
{
if (child->type != XML_ELEMENT_NODE) continue;
// Drop the technique and exta elements that may be found
if (IsEquivalent(child->name, DAE_TECHNIQUE_ELEMENT) ||
IsEquivalent(child->name, DAE_EXTRA_ELEMENT)) continue;
// Buffer this parameter node
parameterNodes.push_back(child);
}
// Retrieve all the parameter's names
size_t parameterNodeCount = parameterNodes.size();
parameterNames.resize(parameterNodeCount);
for (size_t i = originalCount; i < parameterNodeCount; ++i)
{
xmlNode* node = parameterNodes[i];
if (IsEquivalent(node->name, DAE_PARAMETER_ELEMENT)) parameterNames[i] = ReadNodeName(node);
else parameterNames[i] = (const char*) node->name;
}
}
// Retrieves a list of floats from a source node
// Returns the data's stride.
uint32 ReadSource(xmlNode* sourceNode, FloatList& array)
{
uint32 stride = 0;
if (sourceNode != NULL)
{
// Get the accessor's count
xmlNode* accessorNode = FindTechniqueAccessor(sourceNode);
stride = ReadNodeStride(accessorNode);
array.resize(ReadNodeCount(accessorNode) * stride);
xmlNode* arrayNode = FindArray(sourceNode, DAE_FLOAT_ARRAY_ELEMENT);
const char* arrayContent = ReadNodeContentDirect(arrayNode);
FUStringConversion::ToFloatList(arrayContent, array);
}
return stride;
}
// Retrieves a list of signed integers from a source node
void ReadSource(xmlNode* sourceNode, Int32List& array)
{
if (sourceNode != NULL)
{
// Get the accessor's count
xmlNode* accessorNode = FindTechniqueAccessor(sourceNode);
array.resize(ReadNodeCount(accessorNode));
xmlNode* arrayNode = FindArray(sourceNode, DAE_FLOAT_ARRAY_ELEMENT);
const char* arrayContent = ReadNodeContentDirect(arrayNode);
FUStringConversion::ToInt32List(arrayContent, array);
}
}
// Retrieves a list of strings from a source node
void ReadSource(xmlNode* sourceNode, StringList& array)
{
if (sourceNode != NULL)
{
// Get the accessor's count
xmlNode* accessorNode = FindTechniqueAccessor(sourceNode);
array.resize(ReadNodeCount(accessorNode));
xmlNode* arrayNode = FindArray(sourceNode, DAE_NAME_ARRAY_ELEMENT);
if (arrayNode == NULL) arrayNode = FindArray(sourceNode, DAE_IDREF_ARRAY_ELEMENT);
const char* arrayContent = ReadNodeContentDirect(arrayNode);
FUStringConversion::ToStringList(arrayContent, array);
}
}
// Retrieves a list of points from a source node
void ReadSource(xmlNode* sourceNode, FMVector3List& array, float lengthFactor)
{
if (sourceNode != NULL)
{
// Get the accessor's count
xmlNode* accessorNode = FindTechniqueAccessor(sourceNode);
array.resize(ReadNodeCount(accessorNode));
xmlNode* arrayNode = FindArray(sourceNode, DAE_FLOAT_ARRAY_ELEMENT);
const char* arrayContent = ReadNodeContentDirect(arrayNode);
FUStringConversion::ToPointList(arrayContent, array, lengthFactor);
}
}
// Retrieves a list of matrices from a source node
void ReadSource(xmlNode* sourceNode, FMMatrix44List& array, float lengthFactor)
{
if (sourceNode != NULL)
{
// Get the accessor's count
xmlNode* accessorNode = FindTechniqueAccessor(sourceNode);
array.resize(ReadNodeCount(accessorNode));
xmlNode* arrayNode = FindArray(sourceNode, DAE_FLOAT_ARRAY_ELEMENT);
const char* arrayContent = ReadNodeContentDirect(arrayNode);
FUStringConversion::ToMatrixList(arrayContent, array, lengthFactor);
}
}
// Retrieves a series of interleaved floats from a source node
void ReadSourceInterleaved(xmlNode* sourceNode, vector<FloatList*>& arrays)
{
if (sourceNode != NULL)
{
// Get the accessor's count
xmlNode* accessorNode = FindTechniqueAccessor(sourceNode);
uint32 count = ReadNodeCount(accessorNode);
for (vector<FloatList*>::iterator it = arrays.begin(); it != arrays.end(); ++it)
{
(*it)->resize(count);
}
// Use the stride to pad the interleaved float lists or remove extra elements
uint32 stride = ReadNodeStride(accessorNode);
while (stride < arrays.size()) arrays.pop_back();
while (stride > arrays.size()) arrays.push_back(NULL);
// Read and parse the float array
xmlNode* arrayNode = FindArray(sourceNode, DAE_FLOAT_ARRAY_ELEMENT);
const char* arrayContent = ReadNodeContentDirect(arrayNode);
FUStringConversion::ToInterleavedFloatList(arrayContent, arrays);
}
}
// Retrieves a series of interpolation values from a source node
void ReadSourceInterpolation(xmlNode* sourceNode, UInt32List& array)
{
if (sourceNode != NULL)
{
// Get the accessor's count
xmlNode* accessorNode = FindTechniqueAccessor(sourceNode);
uint32 count = ReadNodeCount(accessorNode);
array.resize(count);
StringList stringArray(count);
xmlNode* arrayNode = FindArray(sourceNode, DAE_NAME_ARRAY_ELEMENT);
const char* arrayContent = ReadNodeContentDirect(arrayNode);
FUStringConversion::ToStringList(arrayContent, stringArray);
for (uint32 i = 0; i < count; ++i)
{
array[i] = (uint32) FUDaeInterpolation::FromString(stringArray[i]);
}
}
}
// Retrieves a series of interpolation values from a source node
void ReadSourceInterpolationInterleaved(xmlNode* sourceNode, vector<UInt32List*>& arrays)
{
if (sourceNode != NULL)
{
// Get the accessor's count
xmlNode* accessorNode = FindTechniqueAccessor(sourceNode);
uint32 count = ReadNodeCount(accessorNode);
for (vector<UInt32List*>::iterator it = arrays.begin(); it != arrays.end(); ++it)
{
(*it)->resize(count);
}
// Get the source node's stride from the accessor node
uint32 stride = ReadNodeStride(accessorNode);
while (stride < arrays.size()) arrays.pop_back();
StringList stringArray(count * stride);
xmlNode* arrayNode = FindArray(sourceNode, DAE_NAME_ARRAY_ELEMENT);
const char* arrayContent = ReadNodeContentDirect(arrayNode);
FUStringConversion::ToStringList(arrayContent, stringArray);
for (uint32 i = 0; i < count; ++i)
{
for (size_t j = 0; j < arrays.size(); ++j)
{
arrays[j]->at(i) = (uint32) FUDaeInterpolation::FromString(stringArray[i * stride + j]);
}
}
}
}
// Retrieves the target property of a targeting node, split into its pointer and its qualifier(s)
void ReadNodeTargetProperty(xmlNode* targetingNode, string& pointer, string& qualifier)
{
string target = ReadNodeProperty(targetingNode, DAE_TARGET_ATTRIBUTE);
SplitTarget(target, pointer, qualifier);
}
// Split the target string into its pointer and its qualifier(s)
void SplitTarget(const string& target, string& pointer, string& qualifier)
{
uint32 splitIndex = (uint32) target.find_first_of("([.");
if (splitIndex != string::npos)
{
pointer = target.substr(0, splitIndex);
qualifier = target.substr(splitIndex);
}
else
{
pointer = target;
qualifier.clear();
}
}
// Calculate the target pointer for a targetable node
void CalculateNodeTargetPointer(xmlNode* target, string& pointer)
{
if (target != NULL)
{
// The target node should have either a subid or an id
if (HasNodeProperty(target, DAE_ID_ATTRIBUTE))
{
pointer = ReadNodeId(target);
return;
}
else if (!HasNodeProperty(target, DAE_SID_ATTRIBUTE))
{
pointer.clear();
return;
}
// Generate a list of parent nodes up to the first properly identified parent
xmlNodeList traversal;
traversal.push_back(target);
xmlNode* current = target->parent;
while (current != NULL)
{
traversal.push_back(current);
if (HasNodeProperty(current, DAE_ID_ATTRIBUTE)) break;
current = current->parent;
}
// The top parent should have the ID property
FUSStringBuilder builder;
intptr_t nodeCount = (intptr_t) traversal.size();
builder.append(ReadNodeId(traversal[nodeCount - 1]));
if (builder.empty()) { pointer.clear(); return; }
// Build up the target string
for (intptr_t i = nodeCount - 2; i >= 0; --i)
{
xmlNode* node = traversal[i];
string subId = ReadNodeProperty(node, DAE_SID_ATTRIBUTE);
if (!subId.empty())
{
builder.append('/');
builder.append(subId);
}
}
pointer = builder.ToString();
}
else pointer.clear();
}
// Parse the target elements of the matrix
int32 ReadTargetMatrixElement(string& qualifier)
{
int32 returnValue = -1;
const char* c = qualifier.c_str();
while(*c == '(' || *c == '[')
{
const char* number = ++c;
while (*c >= '0' && *c <= '9') ++c;
if (*c == ')' || *c == ']')
{
returnValue = FUStringConversion::ToInt32(number);
string temp = c + 1;
qualifier = temp;
break;
}
}
return returnValue;
}
// Parse the Url attribute off a node
FUUri ReadNodeUrl(xmlNode* node, const char* attribute)
{
FUUri out;
string uriString = ReadNodeProperty(node, attribute);
uint32 suffixStart = (uint32) uriString.find('#');
if (suffixStart == string::npos) out.prefix = TO_FSTRING(uriString);
else
{
out.prefix = TO_FSTRING(uriString.substr(0, suffixStart));
out.suffix = uriString.substr(suffixStart + 1);
}
return out;
}
// Parse the count attribute off a node
uint32 ReadNodeCount(xmlNode* node)
{
string countString = ReadNodeProperty(node, DAE_COUNT_ATTRIBUTE);
return FUStringConversion::ToUInt32(countString);
}
// Parse the stride attribute off a node
uint32 ReadNodeStride(xmlNode* node)
{
string strideString = ReadNodeProperty(node, DAE_STRIDE_ATTRIBUTE);
uint32 stride = FUStringConversion::ToUInt32(strideString);
if (stride == 0) stride = 1;
return stride;
}
// Pre-buffer the children of a node, with their ids for performance optimization
void ReadChildrenIds(xmlNode* node, FUXmlNodeIdPairList& pairs)
{
// To avoid unnecessary memory copies:
// Start with calculating the maximum child count
uint32 nodeCount = 0;
for (xmlNode* child = node->children; child != NULL; child = child->next)
{
if (child->type == XML_ELEMENT_NODE) ++nodeCount;
}
// Now, buffer the child nodes and their ids
pairs.reserve(nodeCount);
for (xmlNode* child = node->children; child != NULL; child = child->next)
{
if (child->type == XML_ELEMENT_NODE)
{
FUXmlNodeIdPairList::iterator it = pairs.insert(pairs.end(), FUXmlNodeIdPair());
(*it).node = child;
(*it).id = ReadNodePropertyCRC(child, DAE_ID_ATTRIBUTE);
}
}
}
// Skip the pound(#) character from a COLLADA id string
const char* SkipPound(const string& id)
{
const char* s = id.c_str();
if (s == NULL) return NULL;
else if (*s == '#') ++s;
return s;
}
}

View File

@@ -0,0 +1,71 @@
/*
Copyright (C) 2005-2006 Feeling Software Inc.
MIT License: http://www.opensource.org/licenses/mit-license.php
*/
/*
Based on the FS Import classes:
Copyright (C) 2005-2006 Feeling Software Inc
Copyright (C) 2005-2006 Autodesk Media Entertainment
MIT License: http://www.opensource.org/licenses/mit-license.php
*/
#ifndef _FU_DAE_PARSER_
#define _FU_DAE_PARSER_
#ifdef HAS_LIBXML
#include "FUtils/FUDaeSyntax.h"
#include "FUtils/FUUri.h"
#include "FUtils/FUXmlParser.h"
#include "FUtils/FUXmlNodeIdPair.h"
namespace FUDaeParser
{
using namespace FUXmlParser;
// Retrieve specific child nodes
FCOLLADA_EXPORT xmlNode* FindChildById(xmlNode* parent, const string& id);
FCOLLADA_EXPORT xmlNode* FindChildByRef(xmlNode* parent, const char* ref);
FCOLLADA_EXPORT xmlNode* FindHierarchyChildBySid(xmlNode* hierarchyRoot, const char* sid);
FCOLLADA_EXPORT xmlNode* FindTechnique(xmlNode* parent, const char* profile);
FCOLLADA_EXPORT xmlNode* FindTechniqueAccessor(xmlNode* parent);
FCOLLADA_EXPORT xmlNode* FindArray(xmlNode* parent, const char* arrayType);
FCOLLADA_EXPORT void FindParameters(xmlNode* parent, StringList& parameterNames, xmlNodeList& parameterNodes);
// Import source arrays
FCOLLADA_EXPORT uint32 ReadSource(xmlNode* sourceNode, FloatList& array);
FCOLLADA_EXPORT void ReadSource(xmlNode* sourceNode, Int32List& array);
FCOLLADA_EXPORT void ReadSource(xmlNode* sourceNode, StringList& array);
FCOLLADA_EXPORT void ReadSource(xmlNode* sourceNode, FMVector3List& array, float lengthFactor=1.0f);
FCOLLADA_EXPORT void ReadSource(xmlNode* sourceNode, FMMatrix44List& array, float lengthFactor=1.0f);
FCOLLADA_EXPORT void ReadSourceInterleaved(xmlNode* sourceNode, vector<FloatList*>& arrays);
FCOLLADA_EXPORT void ReadSourceInterpolation(xmlNode* sourceNode, UInt32List& array);
FCOLLADA_EXPORT void ReadSourceInterpolationInterleaved(xmlNode* sourceNode, vector<UInt32List*>& arrays);
// Target support
FCOLLADA_EXPORT void ReadNodeTargetProperty(xmlNode* targetingNode, string& pointer, string& qualifier);
FCOLLADA_EXPORT void SplitTarget(const string& target, string& pointer, string& qualifier);
FCOLLADA_EXPORT void CalculateNodeTargetPointer(xmlNode* targetedNode, string& pointer);
FCOLLADA_EXPORT int32 ReadTargetMatrixElement(string& qualifier);
// Retrieve common node properties
inline string ReadNodeId(xmlNode* node) { return ReadNodeProperty(node, DAE_ID_ATTRIBUTE); }
inline string ReadNodeSid(xmlNode* node) { return ReadNodeProperty(node, DAE_SID_ATTRIBUTE); }
inline string ReadNodeSemantic(xmlNode* node) { return ReadNodeProperty(node, DAE_SEMANTIC_ATTRIBUTE); }
inline string ReadNodeName(xmlNode* node) { return ReadNodeProperty(node, DAE_NAME_ATTRIBUTE); }
inline string ReadNodeSource(xmlNode* node) { return ReadNodeProperty(node, DAE_SOURCE_ATTRIBUTE); }
inline string ReadNodeStage(xmlNode* node) { return ReadNodeProperty(node, DAE_STAGE_ATTRIBUTE); }
FCOLLADA_EXPORT FUUri ReadNodeUrl(xmlNode* node, const char* attribute=DAE_URL_ATTRIBUTE);
FCOLLADA_EXPORT uint32 ReadNodeCount(xmlNode* node);
FCOLLADA_EXPORT uint32 ReadNodeStride(xmlNode* node);
// Pre-buffer the children of a node, with their ids, for performance optimization
FCOLLADA_EXPORT void ReadChildrenIds(xmlNode* node, FUXmlNodeIdPairList& pairs);
// Skip the pound(#) character from a COLLADA id string
FCOLLADA_EXPORT const char* SkipPound(const string& id);
};
#endif // HAS_LIBXML
#endif // _FU_DAE_PARSER_

View File

@@ -0,0 +1,611 @@
/*
Copyright (C) 2005-2006 Feeling Software Inc.
MIT License: http://www.opensource.org/licenses/mit-license.php
*/
/*
Based on the FS Import classes:
Copyright (C) 2005-2006 Feeling Software Inc
Copyright (C) 2005-2006 Autodesk Media Entertainment
MIT License: http://www.opensource.org/licenses/mit-license.php
*/
#ifndef _DAE_SYNTAX_H_
#define _DAE_SYNTAX_H_
// COLLADA Versioning information
#define DAE_NAMESPACE_ATTRIBUTE "xmlns"
#define DAE_SCHEMA_LOCATION "http://www.collada.org/2005/11/COLLADASchema"
#define DAE_VERSION_ATTRIBUTE "version"
#define DAE_SCHEMA_VERSION "1.4.0"
// COLLADA 1.4 elements
#define DAE_LIBRARY_ANIMATION_ELEMENT "library_animations"
#define DAE_LIBRARY_ANIMATION_CLIP_ELEMENT "library_animation_clips"
#define DAE_LIBRARY_CAMERA_ELEMENT "library_cameras"
#define DAE_LIBRARY_CONTROLLER_ELEMENT "library_controllers"
#define DAE_LIBRARY_EFFECT_ELEMENT "library_effects"
#define DAE_LIBRARY_FFIELDS_ELEMENT "library_force_fields"
#define DAE_LIBRARY_GEOMETRY_ELEMENT "library_geometries"
#define DAE_LIBRARY_IMAGE_ELEMENT "library_images"
#define DAE_LIBRARY_LIGHT_ELEMENT "library_lights"
#define DAE_LIBRARY_MATERIAL_ELEMENT "library_materials"
#define DAE_LIBRARY_NODE_ELEMENT "library_nodes"
#define DAE_LIBRARY_PMATERIAL_ELEMENT "library_physics_materials"
#define DAE_LIBRARY_PMODEL_ELEMENT "library_physics_models"
#define DAE_LIBRARY_PSCENE_ELEMENT "library_physics_scenes"
#define DAE_LIBRARY_VSCENE_ELEMENT "library_visual_scenes"
#define DAE_INSTANCE_ANIMATION_ELEMENT "instance_animation"
#define DAE_INSTANCE_CAMERA_ELEMENT "instance_camera"
#define DAE_INSTANCE_CONTROLLER_ELEMENT "instance_controller"
#define DAE_INSTANCE_EFFECT_ELEMENT "instance_effect"
#define DAE_INSTANCE_GEOMETRY_ELEMENT "instance_geometry"
#define DAE_INSTANCE_LIGHT_ELEMENT "instance_light"
#define DAE_INSTANCE_MATERIAL_ELEMENT "instance_material"
#define DAE_INSTANCE_NODE_ELEMENT "instance_node"
#define DAE_INSTANCE_VSCENE_ELEMENT "instance_visual_scene"
#define DAE_ANIMCLIP_ELEMENT "animation_clip"
#define DAE_BIND_ELEMENT "bind"
#define DAE_BINDMATERIAL_ELEMENT "bind_material"
#define DAE_COLOR_ELEMENT "color"
#define DAE_CONTROL_VERTICES_ELEMENT "control_vertices"
#define DAE_EFFECT_ELEMENT "effect"
#define DAE_MIP_LEVELS "mip_levels"
#define DAE_MIPMAP_GENERATE "mipmap_generate"
#define DAE_SAMPLER_ELEMENT "sampler"
#define DAE_SKELETON_ELEMENT "skeleton"
#define DAE_TARGETS_ELEMENT "targets"
#define DAE_TECHNIQUE_COMMON_ELEMENT "technique_common"
#define DAE_VIEWPORT_RATIO "viewport_ratio"
#define DAE_VSCENE_ELEMENT "visual_scene"
#define DAE_WEIGHTS_ELEMENT "vertex_weights"
#define DAE_VERTEXCOUNT_ELEMENT "vcount"
#define DAE_INITASNULL_ELEMENT "init_as_null"
#define DAE_INITASTARGET_ELEMENT "init_as_target"
#define DAE_INITCUBE_ELEMENT "init_cube"
#define DAE_INITVOLUME_ELEMENT "init_volume"
#define DAE_INITPLANAR_ELEMENT "init_planar"
#define DAE_INITFROM_ELEMENT "init_from"
#define DAE_ALL_ELEMENT "all"
#define DAE_PRIMARY_ELEMENT "primary"
#define DAE_FACE_ELEMENT "face"
#define DAE_ORDER_ELEMENT "order"
#define DAE_FX_PROFILE_COMMON_ELEMENT "profile_COMMON"
#define DAE_FX_PROFILE_CG_ELEMENT "profile_CG"
#define DAE_FX_PROFILE_HLSL_ELEMENT "profile_HLSL"
#define DAE_FX_PROFILE_GLSL_ELEMENT "profile_GLSL"
#define DAE_FX_PROFILE_GLES_ELEMENT "profile_GLES"
#define DAE_FXCMN_ANNOTATE_ELEMENT "annotate"
#define DAE_FXCMN_BIND_ELEMENT "bind"
#define DAE_FXCMN_BOOL_ELEMENT "bool"
#define DAE_FXCMN_CODE_ELEMENT "code"
#define DAE_FXCMN_COMPILERTARGET_ELEMENT "compiler_target"
#define DAE_FXCMN_COMPILEROPTIONS_ELEMENT "compiler_options"
#define DAE_FXCMN_INT_ELEMENT "int"
#define DAE_FXCMN_HALF_ELEMENT "half"
#define DAE_FXCMN_HALF2_ELEMENT "half2"
#define DAE_FXCMN_HALF3_ELEMENT "half3"
#define DAE_FXCMN_HALF4_ELEMENT "half4"
#define DAE_FXCMN_HALF4X4_ELEMENT "half4x4"
#define DAE_FXCMN_FLOAT_ELEMENT "float"
#define DAE_FXCMN_FLOAT2_ELEMENT "float2"
#define DAE_FXCMN_FLOAT3_ELEMENT "float3"
#define DAE_FXCMN_FLOAT4_ELEMENT "float4"
#define DAE_FXCMN_FLOAT4X4_ELEMENT "float4x4"
#define DAE_FXCMN_HINT_ELEMENT "technique_hint"
#define DAE_FXCMN_INCLUDE_ELEMENT "include"
#define DAE_FXCMN_SURFACE_ELEMENT "surface"
#define DAE_FXCMN_SAMPLER1D_ELEMENT "sampler1D"
#define DAE_FXCMN_SAMPLER2D_ELEMENT "sampler2D"
#define DAE_FXCMN_SAMPLER3D_ELEMENT "sampler3D"
#define DAE_FXCMN_SAMPLERCUBE_ELEMENT "samplerCUBE"
#define DAE_FXCMN_SEMANTIC_ELEMENT "semantic"
#define DAE_FXCMN_SETPARAM_ELEMENT "setparam"
#define DAE_FXCMN_NEWPARAM_ELEMENT "newparam"
#define DAE_FXCMN_STRING_ELEMENT "string"
#define DAE_FXCMN_NAME_ELEMENT "name"
#define DAE_FXCMN_VERTEX_SHADER "VERTEX"
#define DAE_FXCMN_FRAGMENT_SHADER "FRAGMENT"
#define DAE_FXSTD_CONSTANT_ELEMENT "constant"
#define DAE_FXSTD_LAMBERT_ELEMENT "lambert"
#define DAE_FXSTD_PHONG_ELEMENT "phong"
#define DAE_FXSTD_BLINN_ELEMENT "blinn"
#define DAE_FXSTD_COLOR_ELEMENT "color"
#define DAE_FXSTD_FLOAT_ELEMENT "float"
#define DAE_FXSTD_SAMPLER_ELEMENT "texture"
#define DAE_FXSTD_TEXTURE_ATTRIBUTE "texture"
#define DAE_FXSTD_TEXTURESET_ATTRIBUTE "texcoord"
#define DAE_CONTROLLER_SKIN_ELEMENT "skin"
#define DAE_CONTROLLER_MORPH_ELEMENT "morph"
#define DAE_CAMERA_PERSP_ELEMENT "perspective"
#define DAE_CAMERA_ORTHO_ELEMENT "orthographic"
#define DAE_ASPECT_CAMERA_PARAMETER "aspect_ratio"
#define DAE_XFOV_CAMERA_PARAMETER "xfov"
#define DAE_YFOV_CAMERA_PARAMETER "yfov"
#define DAE_ZNEAR_CAMERA_PARAMETER "znear"
#define DAE_ZFAR_CAMERA_PARAMETER "zfar"
#define DAE_XMAG_CAMERA_PARAMETER "xmag"
#define DAE_YMAG_CAMERA_PARAMETER "ymag"
#define DAE_AMBIENT_MATERIAL_PARAMETER "ambient"
#define DAE_BUMP_MATERIAL_PARAMETER "bump"
#define DAE_DIFFUSE_MATERIAL_PARAMETER "diffuse"
#define DAE_EMISSION_MATERIAL_PARAMETER "emission"
#define DAE_TRANSPARENCY_MATERIAL_PARAMETER "transparency"
#define DAE_TRANSPARENT_MATERIAL_PARAMETER "transparent"
#define DAE_REFLECTIVE_MATERIAL_PARAMETER "reflective"
#define DAE_REFLECTIVITY_MATERIAL_PARAMETER "reflectivity"
#define DAE_SHININESS_MATERIAL_PARAMETER "shininess"
#define DAE_SPECULAR_MATERIAL_PARAMETER "specular"
#define DAE_LIGHT_AMBIENT_ELEMENT "ambient"
#define DAE_LIGHT_POINT_ELEMENT "point"
#define DAE_LIGHT_DIRECTIONAL_ELEMENT "directional"
#define DAE_LIGHT_SPOT_ELEMENT "spot"
#define DAE_COLOR_LIGHT_PARAMETER "color"
#define DAE_CONST_ATTENUATION_LIGHT_PARAMETER "constant_attenuation"
#define DAE_LIN_ATTENUATION_LIGHT_PARAMETER "linear_attenuation"
#define DAE_QUAD_ATTENUATION_LIGHT_PARAMETER "quadratic_attenuation"
#define DAE_FALLOFFEXPONENT_LIGHT_PARAMETER "falloff_exponent"
#define DAE_FALLOFFANGLE_LIGHT_PARAMETER "falloff_angle"
#define DAE_BINDSHAPEMX_SKIN_PARAMETER "bind_shape_matrix"
#define DAE_CONTRIBUTOR_ASSET_ELEMENT "contributor"
#define DAE_AUTHOR_ASSET_PARAMETER "author"
#define DAE_AUTHORINGTOOL_ASSET_PARAMETER "authoring_tool"
#define DAE_CREATED_ASSET_PARAMETER "created"
#define DAE_COMMENTS_ASSET_PARAMETER "comments"
#define DAE_COPYRIGHT_ASSET_PARAMETER "copyright"
#define DAE_KEYWORDS_ASSET_PARAMETER "keywords"
#define DAE_MODIFIED_ASSET_PARAMETER "modified"
#define DAE_REVISION_ASSET_PARAMETER "revision"
#define DAE_SOURCEDATA_ASSET_PARAMETER "source_data"
#define DAE_SUBJECT_ASSET_PARAMETER "subject"
#define DAE_TITLE_ASSET_PARAMETER "title"
#define DAE_UNITS_ASSET_PARAMETER "unit"
#define DAE_UPAXIS_ASSET_PARAMETER "up_axis"
#define DAE_PHYSICS_STATIC_FRICTION "static_friction"
#define DAE_PHYSICS_DYNAMIC_FRICTION "dynamic_friction"
#define DAE_PHYSICS_RESTITUTION "restitution"
// COLLADA 1.4 attributes
#define DAE_CLOSED_ATTRIBUTE "closed"
#define DAE_COUNT_ATTRIBUTE "count"
#define DAE_END_ATTRIBUTE "end"
#define DAE_ID_ATTRIBUTE "id"
#define DAE_MATERIAL_ATTRIBUTE "material"
#define DAE_METERS_ATTRIBUTE "meter"
#define DAE_METHOD_ATTRIBUTE "method"
#define DAE_NAME_ATTRIBUTE "name"
#define DAE_OFFSET_ATTRIBUTE "offset"
#define DAE_PLATFORM_ATTRIBUTE "platform"
#define DAE_PROFILE_ATTRIBUTE "profile"
#define DAE_REF_ATTRIBUTE "ref"
#define DAE_SEMANTIC_ATTRIBUTE "semantic"
#define DAE_SET_ATTRIBUTE "set"
#define DAE_SID_ATTRIBUTE "sid"
#define DAE_START_ATTRIBUTE "start"
#define DAE_STRIDE_ATTRIBUTE "stride"
#define DAE_SOURCE_ATTRIBUTE "source"
#define DAE_SYMBOL_ATTRIBUTE "symbol"
#define DAE_TARGET_ATTRIBUTE "target"
#define DAE_URL_ATTRIBUTE "url"
#define DAE_STAGE_ATTRIBUTE "stage"
#define DAE_MIP_ATTRIBUTE "mip"
#define DAE_SLICE_ATTRIBUTE "slice"
#define DAE_FACE_ATTRIBUTE "face"
// COLLADA 1.4 types
#define DAE_FLOAT_TYPE "float"
#define DAE_IDREF_TYPE "IDREF"
#define DAE_MATRIX_TYPE "float4x4"
#define DAE_NAME_TYPE "Name"
// COLLADA 1.4 enumerations
#define DAE_AMBIENT_TEXTURE_CHANNEL "AMBIENT"
#define DAE_BUMP_TEXTURE_CHANNEL "BUMP"
#define DAE_DIFFUSE_TEXTURE_CHANNEL "DIFFUSE"
#define DAE_DISPLACEMENT_TEXTURE_CHANNEL "DISPLACEMENT"
#define DAE_EMISSION_TEXTURE_CHANNEL "GLOW"
#define DAE_FILTER_TEXTURE_CHANNEL "FILTER"
#define DAE_OPACITY_TEXTURE_CHANNEL "OPACITY"
#define DAE_REFLECTION_TEXTURE_CHANNEL "REFLECTION"
#define DAE_REFRACTION_TEXTURE_CHANNEL "REFRACTION"
#define DAE_SHININESS_TEXTURE_CHANNEL "SHININESS"
#define DAE_SPECULAR_TEXTURE_CHANNEL "SPECULAR"
#define DAE_SPECULARLEVEL_TEXTURE_CHANNEL "SPECULAR-LEVEL"
#define DAE_TRANSPARENT_TEXTURE_CHANNEL "TRANSPARENT"
#define DAE_NORMALIZED_MORPH_METHOD "NORMALIZED"
#define DAE_RELATIVE_MORPH_METHOD "RELATIVE"
#define DAE_WEIGHT_MORPH_INPUT "MORPH_WEIGHT"
#define DAE_WEIGHT_MORPH_INPUT_DEPRECATED "WEIGHT"
#define DAE_TARGET_MORPH_INPUT "MORPH_TARGET"
#define DAE_TARGET_MORPH_INPUT_DEPRECATED "TARGET"
#define DAE_TIME_TARGET "TIME"
#define DAE_JOINT_NODE_TYPE "JOINT"
#define DAE_NODE_NODE_TYPE "NODE"
#define DAE_POSITION_SPLINE_INPUT "POSITION"
#define DAE_KNOT_SPLINE_INPUT "KNOTSEQUENCES"
// Collada 1.4 physics
#define DAE_PHYSICS_MATERIAL_ELEMENT "physics_material"
#define DAE_PHYSICS_MODEL_ELEMENT "physics_model"
#define DAE_PHYSICS_SCENE_ELEMENT "physics_scene"
#define DAE_INSTANCE_PHYSICS_MATERIAL_ELEMENT "instance_physics_material"
#define DAE_INSTANCE_PHYSICS_MODEL_ELEMENT "instance_physics_model"
#define DAE_INSTANCE_PHYSICS_SCENE_ELEMENT "instance_physics_scene"
#define DAE_INSTANCE_RIGID_BODY_ELEMENT "instance_rigid_body"
#define DAE_INSTANCE_RIGID_CONSTRAINT_ELEMENT "instance_rigid_constraint"
#define DAE_INSTANCE_FORCE_FIELD_ELEMENT "instance_force_field"
#define DAE_TIME_STEP_ATTRIBUTE "time_step"
#define DAE_GRAVITY_ATTRIBUTE "gravity"
#define DAE_RESTITUTION_ATTRIBUTE "restitution"
#define DAE_STATIC_FRICTION_ATTRIBUTE "static_friction"
#define DAE_DYNAMIC_FRICTION_ATTRIBUTE "dynamic_friction"
#define DAE_VELOCITY_ELEMENT "velocity"
#define DAE_ANGULAR_VELOCITY_ELEMENT "angular_velocity"
#define DAE_BODY_ATTRIBUTE "body"
#define DAE_CONSTRAINT_ATTRIBUTE "constraint"
#define DAE_MASS_FRAME_ELEMENT "mass_frame"
#define DAE_LIMITS_ELEMENT "limits"
#define DAE_LINEAR_ELEMENT "linear"
#define DAE_ANGULAR_ELEMENT "angular"
#define DAE_SWING_CONE_AND_TWIST_ELEMENT "swing_cone_and_twist"
#define DAE_CONVEX_HULL_OF_ATTRIBUTE "convex_hull_of"
#define DAE_HEIGHT_ELEMENT "height"
// Physics extension. Currently in prototype phase.
#define DAE_MIN_ELEMENT "min"
#define DAE_MAX_ELEMENT "max"
#define DAE_SHAPE_ELEMENT "shape"
#define DAE_RIGID_BODY_ELEMENT "rigid_body"
#define DAE_DYNAMIC_ELEMENT "dynamic"
#define DAE_HOLLOW_ELEMENT "hollow"
#define DAE_MASS_ELEMENT "mass"
#define DAE_BOX_ELEMENT "box"
#define DAE_SPHERE_ELEMENT "sphere"
#define DAE_CAPSULE_ELEMENT "capsule"
#define DAE_CYLINDER_ELEMENT "cylinder"
#define DAE_ELLIPSOID_ELEMENT "ellipsoid"
#define DAE_TAPERED_CAPSULE_ELEMENT "tapered_capsule"
#define DAE_TAPERED_CYLINDER_ELEMENT "tapered_cylinder"
#define DAE_PLANE_ELEMENT "plane"
#define DAE_FORMAT_ELEMENT "format"
#define DAE_FORMAT_HINT_ELEMENT "format_hint"
#define DAE_HALF_EXTENTS_ELEMENT "half_extents"
#define DAE_EQUATION_ELEMENT "equation"
#define DAE_SIZE_ELEMENT "size"
#define DAE_RADIUS_ELEMENT "radius"
#define DAE_RADIUS1_ELEMENT "radius1"
#define DAE_RADIUS2_ELEMENT "radius2"
#define DAE_CONVEX_MESH_ELEMENT "convex_mesh"
#define DAE_INERTIA_ELEMENT "inertia"
#define DAE_DENSITY_ELEMENT "density"
#define DAE_CENTER_OF_MASS_ELEMENT "center_of_mass"
#define DAE_DYNAMICS_ELEMENT "dynamics"
#define DAE_RIGID_CONSTRAINT_ELEMENT "rigid_constraint"
#define DAE_FORCE_FIELD_ELEMENT "force_field"
#define DAE_ATTACHMENT_ELEMENT "attachment"
#define DAE_REF_ATTACHMENT_ELEMENT "ref_attachment"
#define DAE_ROT_LIMIT_MIN_ELEMENT "rot_limit_min"
#define DAE_ROT_LIMIT_MAX_ELEMENT "rot_limit_max"
#define DAE_TRANS_LIMIT_MIN_ELEMENT "trans_limit_min"
#define DAE_TRANS_LIMIT_MAX_ELEMENT "trans_limit_max"
#define DAE_ENABLED_ELEMENT "enabled"
#define DAE_INTERPENETRATE_ELEMENT "interpenetrate"
#define DAE_SPRING_ELEMENT "spring"
#define DAE_STIFFNESS_ELEMENT "stiffness"
#define DAE_DAMPING_ELEMENT "damping"
#define DAE_TARGET_VALUE_ELEMENT "target_value"
#define DAE_REST_LENGTH_ELEMENT "rest_length"
#define DAE_ANNOTATE_ELEMENT "annotate"
#define DAE_TRUE_KEYWORD "true"
#define DAE_FALSE_KEYWORD "false"
// COLLADA 1.3 elements
#define DAE_ACCESSOR_ELEMENT "accessor"
#define DAE_ANIMATION_ELEMENT "animation"
#define DAE_ASSET_ELEMENT "asset"
#define DAE_CAMERA_ELEMENT "camera"
#define DAE_CHANNEL_ELEMENT "channel"
#define DAE_CHANNELS_ELEMENT "channels"
#define DAE_COLLADA_ELEMENT "COLLADA"
#define DAE_COMBINER_ELEMENT "combiner" // [Deprecated 1.4]
#define DAE_CONTROLLER_ELEMENT "controller"
#define DAE_DEPTH_ELEMENT "depth"
#define DAE_EXTRA_ELEMENT "extra"
#define DAE_RANGE_ELEMENT "range"
#define DAE_FLOAT_ARRAY_ELEMENT "float_array"
#define DAE_GEOMETRY_ELEMENT "geometry"
#define DAE_HOLE_ELEMENT "h"
#define DAE_IDREF_ARRAY_ELEMENT "IDREF_array"
#define DAE_IMAGE_ELEMENT "image"
#define DAE_INPUT_ELEMENT "input"
#define DAE_INT_ARRAY_ELEMENT "int_array"
#define DAE_INSTANCE_ELEMENT "instance" // [Deprecated 1.4]
#define DAE_JOINTS_ELEMENT "joints"
#define DAE_LIBRARY_ELEMENT "library" // [Deprecated 1.4]
#define DAE_LIGHT_ELEMENT "light"
#define DAE_LOOKAT_ELEMENT "lookat"
#define DAE_MATERIAL_ELEMENT "material"
#define DAE_MATRIX_ELEMENT "matrix"
#define DAE_MESH_ELEMENT "mesh"
#define DAE_NAME_ARRAY_ELEMENT "Name_array"
#define DAE_NODE_ELEMENT "node"
#define DAE_OPTICS_ELEMENT "optics"
#define DAE_PARAMETER_ELEMENT "param"
#define DAE_PASS_ELEMENT "pass"
#define DAE_POLYGON_ELEMENT "p"
#define DAE_POLYGONHOLED_ELEMENT "ph"
#define DAE_POLYGONS_ELEMENT "polygons"
#define DAE_POLYLIST_ELEMENT "polylist"
#define DAE_PROGRAM_ELEMENT "program" // [Deprecated 1.4]
#define DAE_ROTATE_ELEMENT "rotate"
#define DAE_SCALE_ELEMENT "scale"
#define DAE_SCENE_ELEMENT "scene"
#define DAE_SHADER_ELEMENT "shader"
#define DAE_SOURCE_ELEMENT "source"
#define DAE_SPLINE_ELEMENT "spline"
#define DAE_SKEW_ELEMENT "skew"
#define DAE_TECHNIQUE_ELEMENT "technique"
#define DAE_TEXTURE_ELEMENT "texture"
#define DAE_TRANSLATE_ELEMENT "translate"
#define DAE_TRIANGLES_ELEMENT "triangles"
#define DAE_VERTEX_ELEMENT "v"
#define DAE_VERTICES_ELEMENT "vertices"
#define DAE_WIDTH_ELEMENT "width"
// COLLADA 1.3 attributes
#define DAE_IDX_ATTRIBUTE "idx" // [Deprecated 1.4] - Replaced by 'offset'
#define DAE_TYPE_ATTRIBUTE "type" // [Deprecated 1.4]
// COLLADA 1.3 enumerations
#define DAE_COMMON_PROFILE "COMMON" // [Deprecated 1.4] - Replaced by the <technique_common> element
#define DAE_COLOR_INPUT "COLOR"
#define DAE_GEOBINORMAL_INPUT "BINORMAL"
#define DAE_GEOTANGENT_INPUT "TANGENT"
#define DAE_IMAGE_INPUT "IMAGE"
#define DAE_MAPPING_INPUT "UV"
#define DAE_NORMAL_INPUT "NORMAL"
#define DAE_POSITION_INPUT "POSITION"
#define DAE_TEXCOORD_INPUT "TEXCOORD"
#define DAE_TEXBINORMAL_INPUT "TEXBINORMAL"
#define DAE_TEXTANGENT_INPUT "TEXTANGENT"
#define DAE_TEXTURE_INPUT "TEXTURE"
#define DAE_VERTEX_INPUT "VERTEX"
#define DAE_BINDMATRIX_SKIN_INPUT "INV_BIND_MATRIX"
#define DAE_BINDNORMAL_SKIN_INPUT "BIND_SHAPE_NORMAL" // [Deprecated 1.4]
#define DAE_BINDPOS_SKIN_INPUT "BIND_SHAPE_POSITION" // [Deprecated 1.4]
#define DAE_JOINT_SKIN_INPUT "JOINT"
#define DAE_JOINTWEIGHT_SKIN_INPUT "JOINTS_AND_WEIGHTS" // [Deprecated 1.4]
#define DAE_WEIGHT_SKIN_INPUT "WEIGHT"
#define DAE_INPUT_ANIMATION_INPUT "INPUT"
#define DAE_OUTPUT_ANIMATION_INPUT "OUTPUT"
#define DAE_INTANGENT_ANIMATION_INPUT "IN_TANGENT"
#define DAE_OUTTANGENT_ANIMATION_INPUT "OUT_TANGENT"
#define DAE_INTERPOLATION_ANIMATION_INPUT "INTERPOLATION"
#define DAE_ANIMATION_TYPE "ANIMATION" // [Deprecated 1.4]
#define DAE_CAMERA_TYPE "CAMERA" // [Deprecated 1.4]
#define DAE_CONTROLLER_TYPE "CONTROLLER" // [Deprecated 1.4]
#define DAE_EFFECT_TYPE "EFFECT" // [Deprecated 1.4]
#define DAE_IMAGE_TYPE "IMAGE" // [Deprecated 1.4]
#define DAE_GEOMETRY_TYPE "GEOMETRY" // [Deprecated 1.4]
#define DAE_LIGHT_TYPE "LIGHT" // [Deprecated 1.4]
#define DAE_MATERIAL_TYPE "MATERIAL" // [Deprecated 1.4]
#define DAE_TEXTURE_TYPE "TEXTURE" // [Deprecated 1.4]
#define DAE_PERSPECTIVE_CAMERA_TYPE "PERSPECTIVE" // [Deprecated 1.4]
#define DAE_ORTHOGRAPHIC_CAMERA_TYPE "ORTHOGRAPHIC" // [Deprecated 1.4]
#define DAE_XFOV_CAMERA_PARAMETER1_3 "XFOV" // [Deprecated 1.4]
#define DAE_YFOV_CAMERA_PARAMETER1_3 "YFOV" // [Deprecated 1.4]
#define DAE_ZNEAR_CAMERA_PARAMETER1_3 "ZNEAR" // [Deprecated 1.4]
#define DAE_ZFAR_CAMERA_PARAMETER1_3 "ZFAR" // [Deprecated 1.4]
#define DAE_LEFT_CAMERA_PARAMETER1_3 "LEFT" // [Deprecated 1.4]
#define DAE_RIGHT_CAMERA_PARAMETER1_3 "RIGHT" // [Deprecated 1.4]
#define DAE_TOP_CAMERA_PARAMETER1_3 "TOP" // [Deprecated 1.4]
#define DAE_BOTTOM_CAMERA_PARAMETER1_3 "BOTTOM" // [Deprecated 1.4]
#define DAE_AMBIENT_LIGHT_TYPE "AMBIENT" // [Deprecated 1.4]
#define DAE_POINT_LIGHT_TYPE "POINT" // [Deprecated 1.4]
#define DAE_DIRECTIONAL_LIGHT_TYPE "DIRECTIONAL" // [Deprecated 1.4]
#define DAE_SPOT_LIGHT_TYPE "SPOT" // [Deprecated 1.4]
#define DAE_COLOR_LIGHT_PARAMETER1_3 "COLOR" // [Deprecated 1.4]
#define DAE_ATTENUATION_LIGHT_PARAMETER1_3 "ATTENUATION" // [Deprecated 1.4]
#define DAE_ATTENUATIONSCALE_LIGHT_PARAMETER1_3 "ATTENUATION_SCALE" // [Deprecated 1.4]
#define DAE_FALLOFF_LIGHT_PARAMETER1_3 "FALLOFF" // [Deprecated 1.4]
#define DAE_FALLOFFSCALE_LIGHT_PARAMETER1_3 "FALLOFF_SCALE" // [Deprecated 1.4]
#define DAE_ANGLE_LIGHT_PARAMETER1_3 "ANGLE" // [Deprecated 1.4]
#define DAE_X_UP "X_UP"
#define DAE_Y_UP "Y_UP"
#define DAE_Z_UP "Z_UP"
#define DAE_NONE_INTERPOLATION "NONE" // [Deprecated 1.3] ColladaMaya exported this until September 2005
#define DAE_STEP_INTERPOLATION "STEP"
#define DAE_LINEAR_INTERPOLATION "LINEAR"
#define DAE_BEZIER_INTERPOLATION "BEZIER"
#define DAE_CONSTANT_FUNCTION "CONSTANT"
#define DAE_LINEAR_FUNCTION "LINEAR"
#define DAE_QUADRATIC_FUNCTION "QUADRATIC"
#define DAE_CONSTANT_MATERIAL_PROGRAM "CONSTANT" // [Deprecated 1.4]
#define DAE_LAMBERT_MATERIAL_PROGRAM "LAMBERT" // [Deprecated 1.4]
#define DAE_PHONG_MATERIAL_PROGRAM "PHONG" // [Deprecated 1.4]
#define DAE_AMBIENT_MATERIAL_PARAMETER1_3 "AMBIENT" // [Deprecated 1.4]
#define DAE_DIFFUSE_MATERIAL_PARAMETER1_3 "DIFFUSE" // [Deprecated 1.4]
#define DAE_EMISSION_MATERIAL_PARAMETER1_3 "EMISSION" // [Deprecated 1.4]
#define DAE_TRANSPARENCY_MATERIAL_PARAMETER1_3 "TRANSPARENCY" // [Deprecated 1.4]
#define DAE_TRANSPARENT_MATERIAL_PARAMETER1_3 "TRANSPARENT" // [Deprecated 1.4]
#define DAE_REFLECTIVE_MATERIAL_PARAMETER1_3 "REFLECTIVE" // [Deprecated 1.4]
#define DAE_REFLECTIVITY_MATERIAL_PARAMETER1_3 "REFLECTIVITY" // [Deprecated 1.4]
#define DAE_SHININESS_MATERIAL_PARAMETER1_3 "SHININESS" // [Deprecated 1.4]
#define DAE_SPECULAR_MATERIAL_PARAMETER1_3 "SPECULAR" // [Deprecated 1.4]
// COLLADA 1.2 elements
#define DAE_ARRAY_ELEMENT "array" // [Deprecated 1.3]
// COLLADA 1.4 Shared elements
#define DAESHD_DOUBLESIDED_PARAMETER "double_sided"
#define DAESHD_INTENSITY_LIGHT_PARAMETER "intensity"
// COLLADA 1.3 Shared elements
#define DAESHD_INTENSITY_LIGHT_PARAMETER1_3 "INTENSITY" // [Deprecated 1.4]
// COLLADA 1.4 Max-specific profile
#define DAEMAX_MAX_PROFILE "MAX3D"
#define DAEMAX_TARGET_CAMERA_PARAMETER "target"
#define DAEMAX_ASPECTRATIO_LIGHT_PARAMETER "aspect_ratio"
#define DAEMAX_TARGET_LIGHT_PARAMETER "target"
#define DAEMAX_OUTERCONE_LIGHT_PARAMETER "outer_cone"
#define DAEMAX_OVERSHOOT_LIGHT_PARAMETER "overshoot"
#define DAEMAX_SPECLEVEL_MATERIAL_PARAMETER "spec_level"
#define DAEMAX_DISPLACEMENT_MATERIAL_PARAMETER "displacement"
#define DAEMAX_EMISSIONLEVEL_MATERIAL_PARAMETER "emission_level"
#define DAEMAX_FACETED_MATERIAL_PARAMETER "faceted"
#define DAEMAX_FILTERCOLOR_MATERIAL_PARAMETER "filter_color"
#define DAEMAX_INDEXOFREFRACTION_MATERIAL_PARAMETER "index_of_refraction"
#define DAEMAX_USERPROPERTIES_NODE_PARAMETER "user_properties"
#define DAEMAX_WIREFRAME_MATERIAL_PARAMETER "wireframe"
#define DAEMAX_FACEMAP_MATERIAL_PARAMETER "face_map"
#define DAEMAX_AMOUNT_TEXTURE_PARAMETER "amount"
// COLLADA 1.3 Max-specific profile
#define DAEMAX_TARGET_CAMERA_PARAMETER1_3 "TARGET" // [Deprecated 1.4]
#define DAEMAX_ASPECTRATIO_LIGHT_PARAMETER1_3 "ASPECT_RATIO" // [Deprecated 1.4]
#define DAEMAX_TARGET_LIGHT_PARAMETER1_3 "TARGET" // [Deprecated 1.4]
#define DAEMAX_OUTERCONE_LIGHT_PARAMETER1_3 "OUTERCONE" // [Deprecated 1.4]
#define DAEMAX_OVERSHOOT_LIGHT_PARAMETER1_3 "OVERSHOOT" // [Deprecated 1.4]
#define DAEMAX_SPECLEVEL_MATERIAL_PARAMETER1_3 "SPEC_LEVEL" // [Deprecated 1.4]
#define DAEMAX_EMISSIONLEVEL_MATERIAL_PARAMETER1_3 "EMISSION_LEVEL" // [Deprecated 1.4]
#define DAEMAX_FACETED_MATERIAL_PARAMETER1_3 "FACETED" // [Deprecated 1.4]
#define DAEMAX_USERPROPERTIES_NODE_PARAMETER1_3 "USER_PROPERTIES" // [Deprecated 1.4]
// MAYA Profile Syntax Definitions
// COLLADA 1.4 Maya-specific definitions
#define DAEMAYA_MAYA_PROFILE "MAYA"
#define DAEMAYA_VAPERTURE_PARAMETER "vertical_aperture"
#define DAEMAYA_HAPERTURE_PARAMETER "horizontal_aperture"
#define DAEMAYA_LENSSQUEEZE_PARAMETER "lens_squeeze"
#define DAEMAYA_PENUMBRA_LIGHT_PARAMETER "penumbra_angle"
#define DAEMAYA_DROPOFF_LIGHT_PARAMETER "dropoff"
#define DAEMAYA_NOTE_PARAMETER "note"
#define DAEMAYA_VISIBILITY_PARAMETER "visibility"
#define DAEMAYA_ENDTIME_PARAMETER "end_time"
#define DAEMAYA_STARTTIME_PARAMETER "start_time"
#define DAEMAYA_DRIVER_INPUT "DRIVER"
#define DAEMAYA_EXTRA_INPUT "EXTRA"
#define DAEMAYA_WEIGHT_INPUT "WEIGHT"
#define DAEMAYA_INTANGENTWEIGHT_ANIMATION_INPUT "IN_TANGENT_WEIGHT"
#define DAEMAYA_OUTTANGENTWEIGHT_ANIMATION_INPUT "OUT_TANGENT_WEIGHT"
// COLLADA 1.3 Maya-specific definitions
#define DAEMAYA_BLINDNAME_PARAMETER "BLINDNAME"
#define DAEMAYA_BLINDTYPEID_PARAMETER "BLINDTYPEID"
#define DAEMAYA_DOUBLE_SIDED_PARAMETER "DOUBLE_SIDED"
#define DAEMAYA_LAYER_PARAMETER "layer"
#define DAEMAYA_LONGNAME_PARAMETER "long_name"
#define DAEMAYA_PREINFINITY_PARAMETER "pre_infinity"
#define DAEMAYA_POSTINFINITY_PARAMETER "post_infinity"
#define DAEMAYA_PREINFINITY_PARAMETER1_3 "PRE_INFINITY"
#define DAEMAYA_POSTINFINITY_PARAMETER1_3 "POST_INFINITY"
#define DAEMAYA_SHORTNAME_PARAMETER "short_name"
#define DAEMAYA_MAYA_NOTE_PARAMETER1_3 "MAYA_NOTE" // [Deprecated 1.4]
#define DAEMAYA_VISIBILITY_PARAMETER1_3 "VISIBILITY" // [Deprecated 1.4]
#define DAEMAYA_ENDTIME_PARAMETER1_3 "END_TIME" // [Deprecated 1.4]
#define DAEMAYA_STARTTIME_PARAMETER1_3 "START_TIME" // [Deprecated 1.4]
#define DAEMAYA_VAPERTURE_PARAMETER1_3 "VERTICAL_APERTURE" // [Deprecated 1.4]
#define DAEMAYA_HAPERTURE_PARAMETER1_3 "HORIZONTAL_APERTURE" // [Deprecated 1.4]
#define DAEMAYA_LENSSQUEEZE_PARAMETER1_3 "LENS_SQUEEZE" // [Deprecated 1.4]
#define DAEMAYA_TEXTURE_WRAPU_PARAMETER "wrapU"
#define DAEMAYA_TEXTURE_WRAPV_PARAMETER "wrapV"
#define DAEMAYA_TEXTURE_MIRRORU_PARAMETER "mirrorU"
#define DAEMAYA_TEXTURE_MIRRORV_PARAMETER "mirrorV"
#define DAEMAYA_TEXTURE_COVERAGEU_PARAMETER "coverageU"
#define DAEMAYA_TEXTURE_COVERAGEV_PARAMETER "coverageV"
#define DAEMAYA_TEXTURE_TRANSFRAMEU_PARAMETER "translateFrameU"
#define DAEMAYA_TEXTURE_TRANSFRAMEV_PARAMETER "translateFrameV"
#define DAEMAYA_TEXTURE_ROTFRAME_PARAMETER "rotateFrame"
#define DAEMAYA_TEXTURE_STAGGER_PARAMETER "stagger"
#define DAEMAYA_TEXTURE_REPEATU_PARAMETER "repeatU"
#define DAEMAYA_TEXTURE_REPEATV_PARAMETER "repeatV"
#define DAEMAYA_TEXTURE_OFFSETU_PARAMETER "offsetU"
#define DAEMAYA_TEXTURE_OFFSETV_PARAMETER "offsetV"
#define DAEMAYA_TEXTURE_ROTATEUV_PARAMETER "rotateUV"
#define DAEMAYA_TEXTURE_NOISEU_PARAMETER "noiseU"
#define DAEMAYA_TEXTURE_NOISEV_PARAMETER "noiseV"
#define DAEMAYA_TEXTURE_FAST_PARAMETER "fast"
#define DAEMAYA_TEXTURE_BLENDMODE_PARAMETER "blend_mode"
#define DAEMAYA_TEXTURE_BLENDMODE_PARAMETER1_3 "BLEND_MODE"
#define DAEMAYA_PENUMBRA_LIGHT_PARAMETER1_3 "PENUMBRA_ANGLE" // [Deprecated 1.4]
#define DAEMAYA_CONSTANT_INFINITY "CONSTANT"
#define DAEMAYA_LINEAR_INFINITY "LINEAR"
#define DAEMAYA_CYCLE_INFINITY "CYCLE"
#define DAEMAYA_CYCLE_RELATIVE_INFINITY "CYCLE_RELATIVE"
#define DAEMAYA_OSCILLATE_INFINITY "OSCILLATE"
#define DAEMAYA_NONE_BLENDMODE "NONE"
#define DAEMAYA_OVER_BLENDMODE "OVER"
#define DAEMAYA_IN_BLENDMODE "IN"
#define DAEMAYA_OUT_BLENDMODE "OUT"
#define DAEMAYA_ADD_BLENDMODE "ADD"
#define DAEMAYA_SUBSTRACT_BLENDMODE "SUBSTRACT"
#define DAEMAYA_MULTIPLY_BLENDMODE "MULTIPLY"
#define DAEMAYA_DIFFERENCE_BLENDMODE "DIFFERENCE"
#define DAEMAYA_LIGHTEN_BLENDMODE "LIGHTEN"
#define DAEMAYA_DARKEN_BLENDMODE "DARKEN"
#define DAEMAYA_SATURATE_BLENDMODE "SATURATE"
#define DAEMAYA_DESATURATE_BLENDMODE "DESATURATE"
#define DAEMAYA_ILLUMINATE_BLENDMODE "ILLUMINATE"
#define DAEMAYA_PROJECTION_ELEMENT "projection"
#define DAEMAYA_PROJECTION_TYPE_PARAMETER "type"
#define DAEMAYA_PROJECTION_MATRIX_PARAMETER "matrix"
#define DAEMAYA_PROJECTION_PROGRAM "PROJECTION" // [Deprecated 1.4]
#define DAEMAYA_PROJECTION_TYPE_PARAMETER1_3 "TYPE" // [Deprecated 1.4]
#define DAEMAYA_PROJECTION_MATRIX_PARAMETER1_3 "MATRIX" // [Deprecated 1.4]
// COLLADA Error export syntax
#define DAEERR_UNKNOWN_ELEMENT "unknown"
#define DAEERR_UNKNOWN_IDREF "UNKNOWN_IDREF"
#define DAEERR_UNKNOWN_INPUT "UNKNOWN"
#define DAEERR_UNKNOWN_MORPH_METHOD "UNKNOWN"
#endif // _DAE_SYNTAX_H_

View File

@@ -0,0 +1,351 @@
/*
Copyright (C) 2005-2006 Feeling Software Inc.
MIT License: http://www.opensource.org/licenses/mit-license.php
*/
#include "StdAfx.h"
#include "FUtils/FUDaeParser.h"
#include "FUtils/FUDaeWriter.h"
using namespace FUDaeParser;
#define FLOAT_STR_ESTIMATE 12
namespace FUDaeWriter
{
// List of common accessor types
const char* FUDaeAccessor::XYZW[] = { "X", "Y", "Z", "W", 0 };
const char* FUDaeAccessor::RGBA[] = { "R", "G", "B", "A", 0 };
const char* FUDaeAccessor::STPQ[] = { "S", "T", "P", "Q", 0 };
// Write out the <extra><technique> element unto the given parent xml tree node.
// Check for only one <extra> element for this profile.
xmlNode* AddExtraTechniqueChild(xmlNode* parent, const char* profile)
{
xmlNode* techniqueNode = NULL;
if (parent != NULL)
{
xmlNode* extraNode = AddChildOnce(parent, DAE_EXTRA_ELEMENT);
techniqueNode = AddTechniqueChild(extraNode, profile);
}
return techniqueNode;
}
// Write out the <technique> element unto the given parent xml tree node.
// Check for only one <technique> element for this profile.
xmlNode* AddTechniqueChild(xmlNode* parent, const char* profile)
{
xmlNode* techniqueNode = NULL;
if (parent != NULL)
{
techniqueNode = FindTechnique(parent, profile);
if (techniqueNode == NULL)
{
techniqueNode = AddChild(parent, DAE_TECHNIQUE_ELEMENT);
AddAttribute(techniqueNode, DAE_PROFILE_ATTRIBUTE, profile);
}
}
return techniqueNode;
}
xmlNode* AddParameter(xmlNode* parent, const char* name, const char* type)
{
xmlNode* parameterNode = AddChild(parent, DAE_PARAMETER_ELEMENT);
if (name != NULL) AddAttribute(parameterNode, DAE_NAME_ATTRIBUTE, name);
if (type == NULL) type = DAE_FLOAT_TYPE;
AddAttribute(parameterNode, DAE_TYPE_ATTRIBUTE, type);
return parameterNode;
}
xmlNode* AddInput(xmlNode* parent, const char* sourceId, const char* semantic, int32 offset, int32 set)
{
if (sourceId == NULL || *sourceId == 0 || semantic == NULL || *semantic == 0) return NULL;
xmlNode* inputNode = AddChild(parent, DAE_INPUT_ELEMENT);
AddAttribute(inputNode, DAE_SEMANTIC_ATTRIBUTE, semantic);
AddAttribute(inputNode, DAE_SOURCE_ATTRIBUTE, string("#") + sourceId);
if (offset >= 0) AddAttribute(inputNode, DAE_OFFSET_ATTRIBUTE, offset);
if (set >= 0) AddAttribute(inputNode, DAE_SET_ATTRIBUTE, set);
return inputNode;
}
xmlNode* AddArray(xmlNode* parent, const char* id, const char* arrayType, const char* content, size_t count)
{
xmlNode* arrayNode = AddChild(parent, arrayType, content);
AddAttribute(arrayNode, DAE_ID_ATTRIBUTE, id);
AddAttribute(arrayNode, DAE_COUNT_ATTRIBUTE, count);
return arrayNode;
}
xmlNode* AddArray(xmlNode* parent, const char* id, const FMVector3List& values, float lengthFactor)
{
// Reserve the necessary space within the string builder
globalSBuilder.clear();
size_t valueCount = values.size();
globalSBuilder.reserve(valueCount * 3 * FLOAT_STR_ESTIMATE);
if (valueCount > 0)
{
// Write out the values
FMVector3List::const_iterator itP = values.begin();
FUStringConversion::ToString(globalSBuilder, *itP, lengthFactor);
for (++itP; itP != values.end(); ++itP) { globalSBuilder.append(' '); FUStringConversion::ToString(globalSBuilder, *itP, lengthFactor); }
}
// Create the typed array node.
return AddArray(parent, id, DAE_FLOAT_ARRAY_ELEMENT, globalSBuilder.ToCharPtr(), valueCount * 3);
}
xmlNode* AddArray(xmlNode* parent, const char* id, const FMMatrix44List& values, float lengthFactor)
{
globalSBuilder.clear();
size_t valueCount = values.size();
globalSBuilder.reserve(valueCount * 16 * FLOAT_STR_ESTIMATE);
if (valueCount > 0)
{
FMMatrix44List::const_iterator itM = values.begin();
FUStringConversion::ToString(globalSBuilder, *itM, lengthFactor);
for (++itM; itM != values.end(); ++itM) { globalSBuilder.append(' '); FUStringConversion::ToString(globalSBuilder, *itM, lengthFactor); }
}
return AddArray(parent, id, DAE_FLOAT_ARRAY_ELEMENT, globalSBuilder.ToCharPtr(), valueCount * 16);
}
xmlNode* AddArray(xmlNode* parent, const char* id, const FloatList& values, float lengthFactor)
{
size_t valueCount = values.size();
globalSBuilder.clear();
globalSBuilder.reserve(valueCount * FLOAT_STR_ESTIMATE);
FUStringConversion::ToString(globalSBuilder, values, lengthFactor);
return AddArray(parent, id, DAE_FLOAT_ARRAY_ELEMENT, globalSBuilder.ToCharPtr(), valueCount);
}
xmlNode* AddArray(xmlNode* parent, const char* id, const StringList& values, const char* arrayType)
{
size_t valueCount = values.size();
globalSBuilder.reserve(valueCount * 18); // Pulled out of a hat
globalSBuilder.clear();
if (valueCount > 0)
{
StringList::const_iterator itV = values.begin();
globalSBuilder.set(*itV);
for (++itV; itV != values.end(); ++itV) { globalSBuilder.append(' '); globalSBuilder.append(*itV); }
}
return AddArray(parent, id, arrayType, globalSBuilder.ToCharPtr(), valueCount);
}
xmlNode* AddAccessor(xmlNode* parent, const char* arrayId, size_t count, size_t stride, const char** parameters, const char* type)
{
// Create the accessor element and fill its basic properties
xmlNode* accessorNode = AddChild(parent, DAE_ACCESSOR_ELEMENT);
AddAttribute(accessorNode, DAE_SOURCE_ATTRIBUTE, string("#") + arrayId);
AddAttribute(accessorNode, DAE_COUNT_ATTRIBUTE, count);
AddAttribute(accessorNode, DAE_STRIDE_ATTRIBUTE, stride);
// Create the stride parameters
if (type == NULL) type = DAE_FLOAT_TYPE;
if (!IsEquivalent(type, DAE_MATRIX_TYPE))
{
size_t p = 0;
for (size_t i = 0; i < stride; ++i)
{
const char* parameter = NULL;
if (parameters != NULL)
{
parameter = parameters[p++];
if (parameter == NULL) { parameter = parameters[0]; p = 0; }
}
AddParameter(accessorNode, parameter, type);
}
}
else
{
const char* parameter = (parameters != NULL) ? *parameters : NULL;
AddParameter(accessorNode, parameter, type);
}
return accessorNode;
}
xmlNode* AddSourceMatrix(xmlNode* parent, const char* id, const FMMatrix44List& values, float lengthFactor)
{
xmlNode* sourceNode = AddChild(parent, DAE_SOURCE_ELEMENT);
AddAttribute(sourceNode, DAE_ID_ATTRIBUTE, id);
FUSStringBuilder arrayId(id); arrayId.append("-array");
AddArray(sourceNode, arrayId.ToCharPtr(), values, lengthFactor);
xmlNode* techniqueCommonNode = AddChild(sourceNode, DAE_TECHNIQUE_COMMON_ELEMENT);
AddAccessor(techniqueCommonNode, arrayId.ToCharPtr(), values.size(), 16, NULL, DAE_MATRIX_TYPE);
return sourceNode;
}
xmlNode* AddSourceColor(xmlNode* parent, const char* id, const FMVector3List& values)
{
xmlNode* sourceNode = AddChild(parent, DAE_SOURCE_ELEMENT);
AddAttribute(sourceNode, DAE_ID_ATTRIBUTE, id);
FUSStringBuilder arrayId(id); arrayId.append("-array");
AddArray(sourceNode, arrayId.ToCharPtr(), values);
xmlNode* techniqueCommonNode = AddChild(sourceNode, DAE_TECHNIQUE_COMMON_ELEMENT);
AddAccessor(techniqueCommonNode, arrayId.ToCharPtr(), values.size(), 3, FUDaeAccessor::RGBA, DAE_FLOAT_TYPE);
return sourceNode;
}
xmlNode* AddSourceTexcoord(xmlNode* parent, const char* id, const FMVector3List& values)
{
xmlNode* sourceNode = AddChild(parent, DAE_SOURCE_ELEMENT);
AddAttribute(sourceNode, DAE_ID_ATTRIBUTE, id);
FUSStringBuilder arrayId(id); arrayId.append("-array");
AddArray(sourceNode, arrayId.ToCharPtr(), values);
xmlNode* techniqueCommonNode = AddChild(sourceNode, DAE_TECHNIQUE_COMMON_ELEMENT);
AddAccessor(techniqueCommonNode, arrayId.ToCharPtr(), values.size(), 3, FUDaeAccessor::STPQ, DAE_FLOAT_TYPE);
return sourceNode;
}
xmlNode* AddSourcePosition(xmlNode* parent, const char* id, const FMVector3List& values, float lengthFactor)
{
xmlNode* sourceNode = AddChild(parent, DAE_SOURCE_ELEMENT);
AddAttribute(sourceNode, DAE_ID_ATTRIBUTE, id);
FUSStringBuilder arrayId(id); arrayId.append("-array");
AddArray(sourceNode, arrayId.ToCharPtr(), values, lengthFactor);
xmlNode* techniqueCommonNode = AddChild(sourceNode, DAE_TECHNIQUE_COMMON_ELEMENT);
AddAccessor(techniqueCommonNode, arrayId.ToCharPtr(), values.size(), 3, FUDaeAccessor::XYZW, DAE_FLOAT_TYPE);
return sourceNode;
}
xmlNode* AddSourceFloat(xmlNode* parent, const char* id, const FloatList& values, const char* parameter, float lengthFactor)
{ return AddSourceFloat(parent, id, values, 1, &parameter, lengthFactor); }
xmlNode* AddSourceFloat(xmlNode* parent, const char* id, const FloatList& values, size_t stride, const char** parameters, float lengthFactor)
{
xmlNode* sourceNode = AddChild(parent, DAE_SOURCE_ELEMENT);
AddAttribute(sourceNode, DAE_ID_ATTRIBUTE, id);
FUSStringBuilder arrayId(id); arrayId.append("-array");
AddArray(sourceNode, arrayId.ToCharPtr(), values, lengthFactor);
xmlNode* techniqueCommonNode = AddChild(sourceNode, DAE_TECHNIQUE_COMMON_ELEMENT);
if (stride == 0) stride = 1;
AddAccessor(techniqueCommonNode, arrayId.ToCharPtr(), values.size() / stride, stride, parameters, DAE_FLOAT_TYPE);
return sourceNode;
}
xmlNode* AddSourceString(xmlNode* parent, const char* id, const StringList& values, const char* parameter)
{
xmlNode* sourceNode = AddChild(parent, DAE_SOURCE_ELEMENT);
AddAttribute(sourceNode, DAE_ID_ATTRIBUTE, id);
FUSStringBuilder arrayId(id); arrayId.append("-array");
AddArray(sourceNode, arrayId.ToCharPtr(), values, DAE_NAME_ARRAY_ELEMENT);
xmlNode* techniqueCommonNode = AddChild(sourceNode, DAE_TECHNIQUE_COMMON_ELEMENT);
AddAccessor(techniqueCommonNode, arrayId.ToCharPtr(), values.size(), 1, &parameter, DAE_NAME_TYPE);
return sourceNode;
}
xmlNode* AddSourceIDRef(xmlNode* parent, const char* id, const StringList& values, const char* parameter)
{
xmlNode* sourceNode = AddChild(parent, DAE_SOURCE_ELEMENT);
AddAttribute(sourceNode, DAE_ID_ATTRIBUTE, id);
FUSStringBuilder arrayId(id); arrayId.append("-array");
AddArray(sourceNode, arrayId.ToCharPtr(), values, DAE_IDREF_ARRAY_ELEMENT);
xmlNode* techniqueCommonNode = AddChild(sourceNode, DAE_TECHNIQUE_COMMON_ELEMENT);
AddAccessor(techniqueCommonNode, arrayId.ToCharPtr(), values.size(), 1, &parameter, DAE_IDREF_TYPE);
return sourceNode;
}
xmlNode* AddSourceInterpolation(xmlNode* parent, const char* id, const FUDaeInterpolationList& interpolations)
{
xmlNode* sourceNode = AddChild(parent, DAE_SOURCE_ELEMENT);
AddAttribute(sourceNode, DAE_ID_ATTRIBUTE, id);
FUSStringBuilder arrayId(id); arrayId.append("-array");
globalSBuilder.clear();
size_t valueCount = interpolations.size();
if (valueCount > 0)
{
FUDaeInterpolationList::const_iterator itI = interpolations.begin();
globalSBuilder.append(FUDaeInterpolation::ToString(*itI));
for (++itI; itI != interpolations.end(); ++itI)
{
globalSBuilder.append(' '); globalSBuilder.append(FUDaeInterpolation::ToString(*itI));
}
}
AddArray(sourceNode, arrayId.ToCharPtr(), DAE_NAME_ARRAY_ELEMENT, globalSBuilder.ToCharPtr(), valueCount);
xmlNode* techniqueCommonNode = AddChild(sourceNode, DAE_TECHNIQUE_COMMON_ELEMENT);
const char* parameter = "INTERPOLATION";
AddAccessor(techniqueCommonNode, arrayId.ToCharPtr(), valueCount, 1, &parameter, DAE_NAME_TYPE);
return sourceNode;
}
// Clean-up the id and names to match the schema definitions of 'IDref' and 'Name'.
string CleanId(const char* c)
{
globalSBuilder.clear();
if (*c != 0)
{
// First character: alphabetic or '_'.
if ((*c >= 'a' && *c <= 'z') || (*c >= 'A' && *c <= 'Z') || *c == '_') globalSBuilder += *c;
else globalSBuilder += '_';
// Other characters: alphabetic, numeric or '_'.
// Otherwise, use HTML extended character write-up: &#<num>;
for (++c; *c != 0; ++c)
{
if ((*c >= 'a' && *c <= 'z') || (*c >= 'A' && *c <= 'Z') || (*c >= '0' && *c <= '9') || *c == '_' || *c == '-') globalSBuilder += *c;
else globalSBuilder += '_';
}
}
return globalSBuilder.ToString();
}
fstring CleanName(const fchar* c)
{
globalBuilder.clear();
if (*c != 0)
{
// First character: alphabetic, '_' or ':'.
if ((*c >= 'a' && *c <= 'z') || (*c >= 'A' && *c <= 'Z') || *c == '_' || *c == ':') globalBuilder += *c;
else globalBuilder += '_';
// Other characters: alphabetic, numeric, '_', ':', '-' or '.'.
// Otherwise, use HTML extended character write-up: &#<num>;
for (++c; *c != 0; ++c)
{
if ((*c >= 'a' && *c <= 'z') || (*c >= 'A' && *c <= 'Z') || (*c >= '0' && *c <= '9') || *c == '_' || *c == ':' || *c == '-' || *c == '.') globalBuilder += *c;
else { globalBuilder += '%'; globalBuilder += (uint32) *c; }
}
}
return globalBuilder.ToString();
}
// Add an 'sid' attribute to the given xml node, ensuring unicity. Returns the final 'sid' value.
FCOLLADA_EXPORT string AddNodeSid(xmlNode* node, const char* wantedSid)
{
// Find the first parent node with an id or sid. If this node has an id, return right away.
xmlNode* parentNode = node;
for (parentNode = node; parentNode != NULL; parentNode = parentNode->parent)
{
if (HasNodeProperty(parentNode, DAE_ID_ATTRIBUTE) || HasNodeProperty(parentNode, DAE_SID_ATTRIBUTE)) break;
}
if (parentNode == node)
{
if (!HasNodeProperty(parentNode, DAE_SID_ATTRIBUTE)) AddAttribute(node, DAE_SID_ATTRIBUTE, wantedSid);
return wantedSid;
}
if (parentNode == NULL)
{
// Retrieve the last parent node available
for (parentNode = node; parentNode->parent != NULL; parentNode = parentNode->parent) {}
}
// Check the wanted sid for unicity
xmlNode* existingNode = FindHierarchyChildBySid(parentNode, wantedSid);
if (existingNode == NULL)
{
AddAttribute(node, DAE_SID_ATTRIBUTE, wantedSid);
return wantedSid;
}
// Generate new sids with an incremental counter.
for (uint32 counter = 2; counter < 100; ++counter)
{
globalSBuilder.set(wantedSid); globalSBuilder.append(counter);
existingNode = FindHierarchyChildBySid(parentNode, globalSBuilder.ToCharPtr());
if (existingNode == NULL)
{
AddAttribute(node, DAE_SID_ATTRIBUTE, globalSBuilder);
return globalSBuilder.ToString();
}
}
return string("");
}
};

View File

@@ -0,0 +1,263 @@
/*
Copyright (C) 2005-2006 Feeling Software Inc.
MIT License: http://www.opensource.org/licenses/mit-license.php
*/
/**
@file FUDaeWriter.h
This file contains the FUDaeWriter namespace.
*/
#ifndef _FU_DAE_WRITER_H_
#define _FU_DAE_WRITER_H_
#ifdef HAS_LIBXML
#include "FUtils/FUDaeEnum.h"
#include "FUtils/FUDaeSyntax.h"
#include "FUtils/FUUri.h"
#include "FUtils/FUXmlWriter.h"
/**
Common COLLADA XML writing functions.
Based on top of the FUXmlWriter namespace and the LibXML2 library.
This whole namespace is considered external and should only be used
by the FCollada library.
@ingroup FUtils
*/
namespace FUDaeWriter
{
using namespace FUXmlWriter;
/** Common accessor type string arrays.
These are NULL-terminated and can be used with the AddAccessor function. */
struct FCOLLADA_EXPORT FUDaeAccessor
{
static const char* XYZW[]; /**< Use for vector and position sources. */
static const char* RGBA[]; /**< Use for color sources. */
static const char* STPQ[]; /**< Use for texture coordinate sources. */
};
/** Writes out the \<extra\>\<technique\> element unto the given parent xml tree node.
This function ensures that only one \<extra\> element exists and that only
one \<technique\> element exists for the given profile.
@param parent The parent XML tree node.
@param profile The application-specific profile name.
@return The \<technique\> XML tree node. */
FCOLLADA_EXPORT xmlNode* AddExtraTechniqueChild(xmlNode* parent, const char* profile);
/** Writes out the \<technique\> element unto the given parent xml tree node.
This function ensures that only one \<technique\> element exists for the given profile.
@param parent The parent XML tree node.
@param profile The application-specific profile name.
@return The \<technique\> XML tree node. */
FCOLLADA_EXPORT xmlNode* AddTechniqueChild(xmlNode* parent, const char* profile);
/** Writes out a COLLADA parameter element.
This is used for the source accessors.
A COLLADA parameter has the form: \<param name='' type=''\>value\</param\>.
@param parent The parent XML tree node.
@param name The name attribute value.
@param type The type attribute value.
@return The created \<param\> XML tree node. */
FCOLLADA_EXPORT xmlNode* AddParameter(xmlNode* parent, const char* name, const char* type);
/** Writes out a COLLADA input element.
This is a very common element. For example, it is used in
the \<polygons\>, \<sampler\> and \<joints\> elements.
A COLLADA input has the form: \<input source='\#source_id' semantic='' offset='' set=''/\>.
@param parent The parent XML tree node.
@param sourceId The source attribute value.
This is the COLLADA id of a valid \<source\> element.
@param semantic The semantic attribute value.
This is a valid COLLADA semantic.
For example: POSITION, TEXCOORD, WEIGHT, IN_TANGENT.
@param offset The optional offset attribute value.
When used in conjunction with the \<v\> or the \<p\> elements, this is
the offset for the input data indices within the interleaved indices.
@param set The optional set attribute value.
This unsigned integer is used to tied together multiple inputs.
@return The created \<input\> XML tree node. */
FCOLLADA_EXPORT xmlNode* AddInput(xmlNode* parent, const char* sourceId, const char* semantic, int32 offset=-1, int32 set=-1);
inline xmlNode* AddInput(xmlNode* parent, const string& sourceId, const char* semantic, int32 offset=-1, int32 set=-1) { return AddInput(parent, sourceId.c_str(), semantic, offset, set); } /**< See above. */
/** Writes out a COLLADA strongly-typed data array.
To write out data values, it is preferable to use the AddSourceX functions.
@param parent The parent XML tree node.
@param id The COLLADA id of the array.
This id is used only by the accessor of a source.
@param arrayType The strongly-typed name of the array.
For example: \<float_array\>, \<Name_array\>.
@param content The array content.
@param count The number of entries within the content of the array.
@return The created XML tree node. */
FCOLLADA_EXPORT xmlNode* AddArray(xmlNode* parent, const char* id, const char* arrayType, const char* content, size_t count);
/** Writes out a COLLADA array of matrices.
To write out data values, it is preferable to use the AddSourceX functions.
@param parent The parent XML tree node.
@param id The COLLADA id of the array.
This id is used only by the accessor of a source.
@param values A list of matrices.
@param lengthFactor An optional scale factor for
the translation column of the matrices.
@return The created XML tree node. */
FCOLLADA_EXPORT xmlNode* AddArray(xmlNode* parent, const char* id, const FMMatrix44List& values, float lengthFactor=1.0f);
/** Writes out a COLLADA array of 3D vectors.
To write out data values, it is preferable to use the AddSourceX functions.
@param parent The parent XML tree node.
@param id The COLLADA id of the array.
This id is used only by the accessor of a source.
@param values A list of 3D vectors.
@param lengthFactor An optional scale factor for all the 3D vectors.
@return The created XML tree node. */
FCOLLADA_EXPORT xmlNode* AddArray(xmlNode* parent, const char* id, const FMVector3List& values, float lengthFactor=1.0f);
/** Writes out a COLLADA array of floating-point values.
To write out data values, it is preferable to use the AddSourceX functions.
@param parent The parent XML tree node.
@param id The COLLADA id of the array.
This id is used only by the accessor of a source.
@param values A list of floating-point values.
@param lengthFactor An optional scale factor for all the floating-point values.
@return The created XML tree node. */
FCOLLADA_EXPORT xmlNode* AddArray(xmlNode* parent, const char* id, const FloatList& values, float lengthFactor=1.0f);
/** Writes out a COLLADA array of UTF-8 tokens.
To write out data values, it is preferable to use the AddSourceX functions.
@param parent The parent XML tree node.
@param id The COLLADA id of the array.
This id is used only by the accessor of a source.
@param values A list of UTF-8 tokens. The members of this list will appear
space-separated within the COLLADA document.
@param arrayType The COLLADA element name for the output array.
Defaults to \<Name_array\>. This might also be \<IDRef_array\>.
@return The created XML tree node. */
FCOLLADA_EXPORT xmlNode* AddArray(xmlNode* parent, const char* id, const StringList& values, const char* arrayType=DAE_NAME_ARRAY_ELEMENT);
/** Writes out a COLLADA accessor to be used within a source.
This function should really be called only from within AddSourceX functions.
@param parent The parent XML tree node.
@param arrayId The COLLADA id of the array.
@param count The number of complete elements within the array.
@param stride The number of values that should be used together to create one array element.
@param parameters The list of parameter names.
Some valid parameter names are available in the FUDaeAccessor class.
@param type The type name of the parameters. Examples: float, float4x4, Name or IDRef.
@return The created XML tree node. */
FCOLLADA_EXPORT xmlNode* AddAccessor(xmlNode* parent, const char* arrayId, size_t count, size_t stride=1, const char** parameters=NULL, const char* type=NULL);
inline xmlNode* AddAccessor(xmlNode* parent, const string& arrayId, size_t count, size_t stride=1, const char** parameters=NULL, const char* type=NULL) { return AddAccessor(parent, arrayId.c_str(), count, stride, parameters, type); } /**< See above. */
/** Writes out a COLLADA multi-dimensional source of floating-point values.
@param parent The parent XML tree node.
@param id The COLLADA id of the source.
@param values The list of floating-point values.
@param stride The number of dimensions. This is the number of
floating-point values that should be used together to create one element.
@param parameters The list of accessor parameter names.
Some valid parameter names are available in the FUDaeAccessor class.
@param lengthFactor An optional scale factor for all the floating-point values.
@return The created XML tree node. */
FCOLLADA_EXPORT xmlNode* AddSourceFloat(xmlNode* parent, const char* id, const FloatList& values, size_t stride=1, const char** parameters=NULL, float lengthFactor=1.0f);
inline xmlNode* AddSourceFloat(xmlNode* parent, const string& id, const FloatList& values, size_t stride=1, const char** parameters=NULL, float lengthFactor=1.0f) { return AddSourceFloat(parent, id.c_str(), values, stride, parameters, lengthFactor); } /**< See above. */
/** Writes out a COLLADA source of floating-point values.
@param parent The parent XML tree node.
@param id The COLLADA id of the source.
@param values The list of floating-point values.
@param parameter The accessor parameter name.
Some valid parameter names are available in the FUDaeAccessor class.
@param lengthFactor An optional scale factor for all the floating-point values.
@return The created XML tree node. */
FCOLLADA_EXPORT xmlNode* AddSourceFloat(xmlNode* parent, const char* id, const FloatList& values, const char* parameter=NULL, float lengthFactor=1.0f);
inline xmlNode* AddSourceFloat(xmlNode* parent, const string& id, const FloatList& values, const char* parameter=NULL, float lengthFactor=1.0f) { return AddSourceFloat(parent, id.c_str(), values, parameter, lengthFactor); } /**< See above. */
/** Writes out a COLLADA source of matrices.
@param parent The parent XML tree node.
@param id The COLLADA id of the source.
@param values The list of matrices.
@param lengthFactor An optional scale factor for all the floating-point values.
@return The created XML tree node. */
FCOLLADA_EXPORT xmlNode* AddSourceMatrix(xmlNode* parent, const char* id, const FMMatrix44List& values, float lengthFactor=1.0f);
inline xmlNode* AddSourceMatrix(xmlNode* parent, const string& id, const FMMatrix44List& values, float lengthFactor=1.0f) { return AddSourceMatrix(parent, id.c_str(), values, lengthFactor); } /**< See above. */
/** Writes out a COLLADA source of matrices.
@param parent The parent XML tree node.
@param id The COLLADA id of the source.
@param values The list of matrices.
@return The created XML tree node. */
FCOLLADA_EXPORT xmlNode* AddSourceColor(xmlNode* parent, const char* id, const FMVector3List& values);
inline xmlNode* AddSourceColor(xmlNode* parent, const string& id, const FMVector3List& values) { return AddSourceColor(parent, id.c_str(), values); } /**< See above. */
/** Writes out a COLLADA source of texture coordinates.
@param parent The parent XML tree node.
@param id The COLLADA id of the source.
@param values The list of 3D texture coordinates.
@return The created XML tree node. */
FCOLLADA_EXPORT xmlNode* AddSourceTexcoord(xmlNode* parent, const char* id, const FMVector3List& values);
inline xmlNode* AddSourceTexcoord(xmlNode* parent, const string& id, const FMVector3List& values) { return AddSourceTexcoord(parent, id.c_str(), values); } /**< See above. */
/** Writes out a COLLADA source of 3D positions or vectors.
@param parent The parent XML tree node.
@param id The COLLADA id of the source.
@param values The list of 3D vectors.
@param lengthFactor An optional scale factor for all the 3D vectors.
@return The created XML tree node. */
FCOLLADA_EXPORT xmlNode* AddSourcePosition(xmlNode* parent, const char* id, const FMVector3List& values, float lengthFactor=1.0f);
inline xmlNode* AddSourcePosition(xmlNode* parent, const string& id, const FMVector3List& values, float lengthFactor=1.0f) { return AddSourcePosition(parent, id.c_str(), values, lengthFactor); } /**< See above. */
/** Writes out a COLLADA source of UTF-8 tokens.
@param parent The parent XML tree node.
@param id The COLLADA id of the source.
@param values The list of UTF-8 tokens. This list will be space-
separated within the COLLADA document, so you none of the
token should have spaces in them.
@param parameter The name of the accessor parameter.
@return The created XML tree node. */
FCOLLADA_EXPORT xmlNode* AddSourceString(xmlNode* parent, const char* id, const StringList& values, const char* parameter=NULL);
inline xmlNode* AddSourceString(xmlNode* parent, const string& id, const StringList& values, const char* parameter=NULL) { return AddSourceString(parent, id.c_str(), values, parameter); } /**< See above. */
/** Writes out a COLLADA source of COLLADA references.
@param parent The parent XML tree node.
@param id The COLLADA id of the source.
@param values The list of COLLADA references.
@param parameter The name of the accessor parameter.
@return The created XML tree node. */
FCOLLADA_EXPORT xmlNode* AddSourceIDRef(xmlNode* parent, const char* id, const StringList& values, const char* parameter=NULL);
inline xmlNode* AddSourceIDRef(xmlNode* parent, const string& id, const StringList& values, const char* parameter=NULL) { return AddSourceIDRef(parent, id.c_str(), values, parameter); } /**< See above. */
/** Writes out a COLLADA source of interpolation tokens.
This function is used within the export of animation curves.
@param parent The parent XML tree node.
@param id The COLLADA id of the source.
@param interpolations The list of interpolation tokens.
@return The created XML tree node. */
FCOLLADA_EXPORT xmlNode* AddSourceInterpolation(xmlNode* parent, const char* id, const FUDaeInterpolationList& interpolations);
inline xmlNode* AddSourceInterpolation(xmlNode* parent, const string& id, const FUDaeInterpolationList& values) { return AddSourceInterpolation(parent, id.c_str(), values); } /**< See above. */
/** Cleans up a given name into a valid COLLADA id.
This function does no check for uniqueness.
@param id A name.
@return A valid COLLADA id. */
FCOLLADA_EXPORT string CleanId(const char* id);
inline string CleanId(const string& id) { return CleanId(id.c_str()); } /**< See above. */
/** Cleans up a given name into a valid COLLADA name.
@param name A name.
@return A valid COLLADA name. */
FCOLLADA_EXPORT fstring CleanName(const fchar* name);
inline fstring CleanName(const fstring& name) { return CleanName(name.c_str()); } /**< See above. */
/** Adds the 'sid' attribute to a given XML tree node.
The sub-id is verified to ensure uniqueness within the scope.
@param node The XML tree node.
@param wantedSid The wanted sub-id.
@return The actual sub-id written to the XML tree node. */
FCOLLADA_EXPORT string AddNodeSid(xmlNode* node, const char* wantedSid);
};
#endif // HAS_LIBXML
#endif // _FU_DAE_WRITER_H_

View File

@@ -0,0 +1,51 @@
/*
Copyright (C) 2005-2006 Feeling Software Inc.
MIT License: http://www.opensource.org/licenses/mit-license.php
*/
#include "StdAfx.h"
#include "FUtils/FUDateTime.h"
#include <time.h>
FUDateTime::FUDateTime(const FUDateTime& time)
{
seconds = time.seconds;
minutes = time.minutes;
hour = time.hour;
day = time.day;
month = time.month;
year = time.year;
}
FUDateTime::FUDateTime()
{
seconds = minutes = hour = 0;
day = month = 1;
year = 1900;
}
FUDateTime::~FUDateTime()
{
}
FUDateTime FUDateTime::GetNow()
{
FUDateTime dateTime;
// Get current UTC time
time_t currentTime;
time(&currentTime);
tm* utcTime = gmtime(&currentTime);
// Convert to our own data structure
dateTime.SetSeconds(utcTime->tm_sec);
dateTime.SetMinutes(utcTime->tm_min);
dateTime.SetHour(utcTime->tm_hour);
dateTime.SetDay(utcTime->tm_mday);
dateTime.SetMonth(utcTime->tm_mon + 1);
dateTime.SetYear(utcTime->tm_year + 1900);
return dateTime;
}

View File

@@ -0,0 +1,93 @@
/*
Copyright (C) 2006 Feeling Software Inc
MIT License: http://www.opensource.org/licenses/mit-license.php
*/
/**
@file FUDateTime.h
This file contains the FUDateTime class.
*/
#ifndef _FU_DATETIME_H_
#define _FU_DATETIME_H_
/**
A common date-time.
Encapsulates the OS-dependant timing functions. Use the static member function: GetNow()
to sample the current time. The day and month values are 1-indexed, to be user-friendly.
@ingroup FUtils
*/
class FCOLLADA_EXPORT FUDateTime
{
private:
// To be more friendly, 'day' and 'month' are 1-indexed
uint32 seconds;
uint32 minutes;
uint32 hour;
uint32 day;
uint32 month;
uint32 year;
public:
/** Default constructor. The default date-time is set to 01/01/1900 at 00:00:00. */
FUDateTime();
/** Copy constructor. Creates an identical clone of the given date-time structure.
@param time The date-time structure to copy. */
FUDateTime(const FUDateTime& time);
/** Destructor. */
~FUDateTime();
/** Retrieves the seconds component of the date-time structure.
@returns The seconds component. The seconds component is always in the range [0, 60[. */
inline uint32 GetSeconds() const { return seconds; }
/** Retrieves the minutes component of the date-time structure.
@returns The minutes component. The minutes component is always in the range [0, 60[. */
inline uint32 GetMinutes() const { return minutes; }
/** Retrieves the hour component of the date-time structure.
@returns The hour component. The hour component is always in the range [0, 24[. */
inline uint32 GetHour() const { return hour; }
/** Retrieves the day component of the date-time structure.
@returns The day component. The day component is 1-indexed and has an upper range
that depends on the month component. The valid range for the day component is [1, 31].*/
inline uint32 GetDay() const { return day; }
/** Retrieves the month component of the date-time structure.
@returns The month component. The month component is 1-indexed and is always in the range [1, 12].*/
inline uint32 GetMonth() const { return month; }
/** Retrieves the year component of the date-time structure.
@returns The year component. The year component represents the full year value,
where a value of 2000 is returned for the year 2000.*/
inline uint32 GetYear() const { return year; }
/** Sets the seconds component of the date-time structure.
@param _seconds The new seconds value. No verification is made
to verify that the new value is within the valid range. */
inline void SetSeconds(uint32 _seconds) { seconds = _seconds; }
/** Sets the minutes component of the date-time structure.
@param _minutes The new seconds value. No verification is made
to verify that the new value is within the valid range. */
inline void SetMinutes(uint32 _minutes) { minutes = _minutes; }
/** Sets the hour component of the date-time structure.
@param _hour The new seconds value. No verification is made
to verify that the new value is within the valid range. */
inline void SetHour(uint32 _hour) { hour = _hour; }
/** Sets the day component of the date-time structure.
@param _day The new seconds value. No verification is made
to verify that the new value is within the valid range. */
inline void SetDay(uint32 _day) { day = _day; }
/** Sets the month component of the date-time structure.
@param _month The new seconds value. No verification is made
to verify that the new value is within the valid range. */
inline void SetMonth(uint32 _month) { month = _month; }
/** Sets the year component of the date-time structure.
@param _year The new seconds value. No verification is made
to verify that the new value is within the valid range. */
inline void SetYear(uint32 _year) { year = _year; }
/** Creates a date-time structure to represent the current time.
Encapsulates the OS-dependant time() function.
@return The current date-time. */
static FUDateTime GetNow();
};
#endif // _FU_DATETIME_H_

View File

@@ -0,0 +1,107 @@
/*
Copyright (C) 2005-2006 Feeling Software Inc.
MIT License: http://www.opensource.org/licenses/mit-license.php
*/
#include "StdAfx.h"
#include "FUtils/FUDebug.h"
#include "FUtils/FUStringConversion.h"
#ifdef _DEBUG
#if defined(LINUX) || defined(MAC_TIGER)
#define STRING_OUT(sz) cerr << (sz) << endl
#elif defined(WIN32)
#define STRING_OUT(sz) OutputDebugString(sz); OutputDebugString(FC("\n"))
#endif
static void DebugString(const fchar* message)
{
STRING_OUT(message);
}
#ifdef UNICODE
static void DebugString(const char* message)
{
fstring str = TO_FSTRING(message);
DebugString(str.c_str());
}
#endif // UNICODE
void DebugOut(const char* filename, uint32 line, const char* message, ...)
{
va_list vars;
va_start(vars, message);
DebugOutV(filename, line, message, vars);
va_end(vars);
}
void DebugOut(const char* message, ...)
{
va_list vars;
va_start(vars, message);
DebugOutV(message, vars);
va_end(vars);
}
void DebugOutV(const char* filename, uint32 line, const char* message, va_list& vars)
{
char buffer[256];
snprintf(buffer, 256, "[%s@%lu] ", filename, line);
buffer[255] = 0;
DebugString(buffer);
DebugOutV(message, vars);
}
void DebugOutV(const char* message, va_list& vars)
{
uint32 length = (uint32) strlen(message);
char* buffer = new char[length + 256];
vsnprintf(buffer, length + 256, message, vars);
buffer[length + 255] = 0;
DebugString(buffer);
SAFE_DELETE_ARRAY(buffer);
}
#ifdef UNICODE
void DebugOut(const char* filename, uint32 line, const fchar* message, ...)
{
va_list vars;
va_start(vars, message);
DebugOutV(filename, line, message, vars);
va_end(vars);
}
void DebugOut(const fchar* message, ...)
{
va_list vars;
va_start(vars, message);
DebugOutV(message, vars);
va_end(vars);
}
void DebugOutV(const char* filename, uint32 line, const fchar* message, va_list& vars)
{
char buffer[256];
snprintf(buffer, 256, "[%s@%lu] ", filename, line);
buffer[255] = 0;
DebugString(buffer);
DebugOutV(message, vars);
}
void DebugOutV(const fchar* message, va_list& vars)
{
uint32 length = (uint32) fstrlen(message);
fchar* buffer = new fchar[length + 256];
fvsnprintf(buffer, length + 256, message, vars);
buffer[length + 255] = 0;
DebugString(buffer);
SAFE_DELETE_ARRAY(buffer);
}
#endif // UNICODE
#endif // _DEBUG

View File

@@ -0,0 +1,79 @@
/*
Copyright (C) 2005-2006 Feeling Software Inc.
MIT License: http://www.opensource.org/licenses/mit-license.php
*/
/**
@file FUDebug.h
This file contains macros useful to write debugging output.
*/
#ifndef _FU_DEBUG_H_
#define _FU_DEBUG_H_
/** Outputs a string to the debug monitor.
@param token The string to output. */
#define DEBUG_OUT(token) ::DebugOut(__FILE__, __LINE__, token);
/** Outputs a string to the debug monitor.
@param token The formatted string to output.
@param arg1 A first argument. */
#define DEBUG_OUT1(token, arg1) ::DebugOut(__FILE__, __LINE__, token, arg1);
/** Outputs a string to the debug monitor.
@param token The formatted string to output.
@param arg1 A first argument.
@param arg2 A second argument. */
#define DEBUG_OUT2(token, arg1, arg2) ::DebugOut(__FILE__, __LINE__, token, arg1, arg2);
#ifndef _DEBUG
/** Outputs a string to the debug monitor.
The formatted message is the first parameter. */
inline void DebugOut(const char*, ...) {}
#ifdef UNICODE
inline void DebugOut(const fchar*, ...) {} /**< See above. */
#endif // UNICODE
/** Outputs a string to the debug monitor.
The formatted message is the first parameter.
The second parameter is the variable parmeter list. */
inline void DebugOutV(const char*, va_list&) {}
#ifdef UNICODE
inline void DebugOutV(const fchar*, va_list&) {} /**< See above. */
#endif // UNICODE
/** Outputs a string to the debug monitor.
The filename and line number are the first two parameters.
The formatted message is the third parameter. */
inline void DebugOut(const char*, uint32, const char*, ...) {}
#ifdef UNICODE
inline void DebugOut(const char*, uint32, const fchar*, ...) {} /**< See above. */
#endif // UNICODE
/** Outputs a string to the debug monitor.
The filename and line number are the first two parameters.
The formatted message is the third parameter.
The fourth parameter is the variable parameter list. */
inline void DebugOutV(const char*, uint32, const char*, va_list&) {}
#ifdef UNICODE
inline void DebugOutV(const char*, uint32, const fchar*, va_list&) {} /**< See above. */
#endif // UNICODE
#else // _DEBUG
#ifdef UNICODE
void FCOLLADA_EXPORT DebugOut(const char* filename, uint32 line, const fchar* message, ...);
void FCOLLADA_EXPORT DebugOut(const fchar* message, ...);
void FCOLLADA_EXPORT DebugOutV(const char* filename, uint32 line, const fchar* message, va_list& vars);
void FCOLLADA_EXPORT DebugOutV(const fchar* message, va_list& vars);
#endif // UNICODE
void FCOLLADA_EXPORT DebugOut(const char* filename, uint32 line, const char* message, ...);
void FCOLLADA_EXPORT DebugOut(const char* message, ...);
void FCOLLADA_EXPORT DebugOutV(const char* filename, uint32 line, const char* message, va_list& vars);
void FCOLLADA_EXPORT DebugOutV(const char* message, va_list& vars);
#endif // _DEBUG
#endif // _FU_DEBUG_H_

View File

@@ -0,0 +1,167 @@
/*
Copyright (C) 2005-2006 Feeling Software Inc.
MIT License: http://www.opensource.org/licenses/mit-license.php
*/
/*
This file was taken off the Protect project on 26-09-2005
*/
#ifndef _EVENT_H_
#define _EVENT_H_
// Zero argument Event
class FUEvent0
{
private:
typedef IFunctor0<void> THandler;
typedef vector<THandler*> THandlerList;
THandlerList m_xHandlers;
public:
FUEvent0() {}
~FUEvent0()
{
CLEAR_POINTER_VECTOR(m_xHandlers);
}
size_t GetHandlerCount() { return m_xHandlers.size(); }
void InsertHandler(THandler* pFunctor)
{
m_xHandlers.push_back(pFunctor);
}
void RemoveHandler(void* pObject, void* pFunction)
{
THandlerList::iterator it;
for (it = m_xHandlers.begin(); it != m_xHandlers.end(); ++it)
{
if ((*it)->Compare(pObject, pFunction))
{
delete (*it);
m_xHandlers.erase(it);
break;
}
}
}
void operator()()
{
THandlerList::iterator it;
for (it = m_xHandlers.begin(); it != m_xHandlers.end(); ++it)
{
(*(*it))();
}
}
};
// One argument Event
template <typename Arg1>
class FUEvent1
{
private:
typedef IFunctor1<Arg1, void> THandler;
typedef vector<THandler> THandlerList;
THandlerList m_xHandlers;
public:
FUEvent1() {}
~FUEvent1()
{
assert(m_xHandlers.empty());
}
size_t GetHandlerCount() { return m_xHandlers.size(); }
void InsertHandler(THandler* pFunctor)
{
m_xHandlers.push_back(pFunctor);
}
void RemoveHandler(void* pObject, void* pFunction)
{
typename THandlerList::iterator it;
for (it = m_xHandlers.begin(); it != m_xHandlers.end(); ++it)
{
if ((*it)->Compare(pObject, pFunction))
{
delete (*it);
m_xHandlers.erase(it);
break;
}
}
}
void operator()(Arg1 sArgument1)
{
typename THandlerList::iterator it;
for (it = m_xHandlers.begin(); it != m_xHandlers.end(); ++it)
{
(*(*it))(sArgument1);
}
}
};
// Two arguments Event
template <typename Arg1, typename Arg2>
class FUEvent2
{
private:
typedef IFunctor2<Arg1, Arg2, void> THandler;
typedef vector<THandler*> THandlerList;
THandlerList m_xHandlers;
public:
FUEvent2() {}
~FUEvent2()
{
assert(m_xHandlers.empty());
}
size_t GetHandlerCount() { return m_xHandlers.size(); }
void InsertHandler(THandler* pFunctor)
{
m_xHandlers.push_back(pFunctor);
}
void RemoveHandler(void* pObject, void* pFunction)
{
typename THandlerList::iterator it;
for (it = m_xHandlers.begin(); it != m_xHandlers.end(); ++it)
{
if ((*it)->Compare(pObject, pFunction))
{
delete (*it);
m_xHandlers.erase(it);
break;
}
}
}
void operator()(Arg1 sArgument1, Arg2 sArgument2)
{
typename THandlerList::iterator it;
for (it = m_xHandlers.begin(); it != m_xHandlers.end(); ++it)
{
(*(*it))(sArgument1, sArgument2);
}
}
};
// Macro for member function pointer type bypass
template <typename Class>
class FURemoveHandler0
{
public:
void operator() (FUEvent0* event, Class* pObject, void (Class::*pFunction)(void))
{
void* pVoid = *(void**)&pFunction;
event->RemoveHandler(pObject, pVoid);
}
};
#endif // _EVENT_H_

View File

@@ -0,0 +1,75 @@
/*
Copyright (C) 2005-2006 Feeling Software Inc.
MIT License: http://www.opensource.org/licenses/mit-license.php
*/
#include "StdAfx.h"
#include "FUtils/FUFile.h"
FUFile::FUFile(const char* filename, Mode mode)
{
const char* openMode;
switch (mode)
{
case READ: openMode = "rb"; break;
case WRITE: openMode = "wb"; break;
default: openMode = "rb"; break;
}
filePtr = fopen(filename, openMode);
}
FUFile::FUFile()
{
filePtr = NULL;
}
FUFile::~FUFile()
{
if (filePtr != NULL)
{
Close();
}
}
// Retrieve the file length
uint32 FUFile::GetLength()
{
FUAssert(IsOpen(), return 0);
uint32 currentPosition = ftell(filePtr);
if (fseek(filePtr, 0, SEEK_END) != 0) return 0;
uint32 length = ftell(filePtr);
if (fseek(filePtr, currentPosition, SEEK_SET) != 0) return 0;
return length;
}
// Reads in a piece of the file into the given buffer
bool FUFile::Read(void* buffer, size_t length)
{
FUAssert(IsOpen(), return false);
return fread(buffer, length, 1, filePtr) == 1;
}
// Write out some data to a file
bool FUFile::Write(const void* buffer, size_t length)
{
FUAssert(IsOpen(), return false);
return fwrite(buffer, length, 1, filePtr) == 1;
}
// Flush/close the file stream
void FUFile::Flush()
{
FUAssert(IsOpen(), );
fflush(filePtr);
}
void FUFile::Close()
{
FUAssert(IsOpen(), );
fclose(filePtr);
filePtr = NULL;
}

View File

@@ -0,0 +1,40 @@
/*
Copyright (C) 2005-2006 Feeling Software Inc.
MIT License: http://www.opensource.org/licenses/mit-license.php
*/
#ifndef _FU_FILE_H_
#define _FU_FILE_H_
class FCOLLADA_EXPORT FUFile
{
public:
enum Mode
{
READ,
WRITE
};
private:
FILE* filePtr;
public:
FUFile(const char* filename, Mode mode);
FUFile();
~FUFile();
bool IsOpen() { return filePtr != NULL; }
// Retrieve the file length
uint32 GetLength();
// Writes/Reads in a piece of the file from/into the given buffer
bool Read(void* buffer, size_t length);
bool Write(const void* buffer, size_t length);
// Flush/close the file stream
void Flush();
void Close();
};
#endif // _FU_FILE_H_

View File

@@ -0,0 +1,305 @@
/*
Copyright (C) 2005-2006 Feeling Software Inc.
MIT License: http://www.opensource.org/licenses/mit-license.php
*/
/*
Based on the FS Import classes:
Copyright (C) 2005-2006 Feeling Software Inc
Copyright (C) 2005-2006 Autodesk Media Entertainment
MIT License: http://www.opensource.org/licenses/mit-license.php
*/
#include "StdAfx.h"
#include "FUtils/FUFile.h"
#include "FUtils/FUFileManager.h"
#include "FUtils/FUStringConversion.h"
#if defined(WIN32)
#include <direct.h>
#endif
FUFileManager::FUFileManager()
{
// Push on the stack the original root path
char fullPath[MAX_PATH];
getcwd(fullPath, MAX_PATH);
pathStack.push_back(TO_FSTRING(fullPath));
}
FUFileManager::~FUFileManager()
{
}
// Set a new root path
void FUFileManager::PushRootPath(const fstring& path)
{
// Ensure that the new root path is an absolute root path.
fstring absolutePath = MakeFilePathAbsolute(path);
pathStack.push_back(absolutePath);
fchdir(path.c_str());
}
// Go back to the previous root path
void FUFileManager::PopRootPath()
{
if (pathStack.size() > 1)
{
pathStack.pop_back();
fchdir(pathStack.back().c_str());
}
}
// Set the current path root, using a known filename
void FUFileManager::PushRootFile(const fstring& filename)
{
// Strip the filename of the actual file's name
fstring path = StripFileFromPath(filename);
PushRootPath(path);
}
void FUFileManager::PopRootFile()
{
PopRootPath();
}
// Open a file to read
FUFile* FUFileManager::OpenFile(const fstring& filename, bool write)
{
fstring absoluteFilename = MakeFilePathAbsolute(filename);
string dumpFilename = FUStringConversion::ToString(absoluteFilename);
return new FUFile(dumpFilename.c_str(), write ? FUFile::WRITE : FUFile::READ);
}
// Massage a given filename to be absolute
fstring FUFileManager::GetFilePath(const fstring& fileURL)
{
// Strip any prefix
fstring filename = fileURL;
std::replace(filename.begin(), filename.end(), '\\', '/');
if (filename.size() > 7 && filename.substr(0, 7) == FC("file://"))
{
filename = filename.c_str() + 7;
if (filename.size() > 3 && filename[0] == '/' && (filename[2] == ':' || filename[2] == '|'))
{
filename = filename.c_str() + 1;
}
if (filename[1] == '|') filename[1] = ':';
}
// Replace any '%' character string into the wanted characters: %20 is common.
for (size_t pos = filename.find('%'); pos != fstring::npos; pos = filename.find('%'))
{
const fchar* pc = filename.c_str() + pos + 1; // +1 to skip/erase the '%' character
uint32 value = FUStringConversion::HexToUInt32(&pc, 2);
size_t count = (pc - filename.c_str()) - pos;
filename.erase(pos, count);
filename.insert(pos, 1, (fchar) value);
}
return MakeFilePathAbsolute(filename);
}
// Transform a file path into a file URL
fstring FUFileManager::GetFileURL(const fstring& filepath, bool relative)
{
fstring url;
if (relative)
{
url = MakeFilePathRelative(filepath);
if (!url.empty() && url[0] != '.')
{
// Unable to make the path relative, so return an absolute path
relative = false;
}
}
if (!relative)
{
// Transform into an absolute file path
fstring url = MakeFilePathAbsolute(filepath);
std::replace(url.begin(), url.end(), ':', '|');
std::replace(url.begin(), url.end(), '\\', '/');
url = fstring(FC("file://")) + url;
}
// Remove any invalid character(s) using the %X guideline
/*for (size_t p = 0; p < url.size(); ++p)
{
fchar c = url[p];
if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') ||
c == '.' || c == '|' || c == '/' || c == '-' || c == '_')
{
// Valid characters
}
else
{
url.erase(p, 1);
globalBuilder.set('%'); <---- NEED TO BE IN HEX
globalBuilder.append(c);
url.append(globalBuilder.ToCharPtr());
}
}*/
return url;
}
// Strip a full filename of its filename, returning the path
fstring FUFileManager::StripFileFromPath(const fstring& filename)
{
fchar fullPath[MAX_PATH + 1];
fstrncpy(fullPath, filename.c_str(), MAX_PATH);
fullPath[MAX_PATH] = 0;
fchar* lastSlash = fstrrchr(fullPath, FC('/'));
fchar* lastBackslash = fstrrchr(fullPath, FC('\\'));
lastSlash = max(lastSlash, lastBackslash);
if (lastSlash != NULL) *lastSlash = 0;
return fstring(fullPath);
}
// Extract the file extension out of a filename
fstring FUFileManager::GetFileExtension(const fstring& _filename)
{
fchar filename[MAX_PATH];
fstrncpy(filename, _filename.c_str(), MAX_PATH);
filename[MAX_PATH - 1] = 0;
fchar* lastPeriod = fstrrchr(filename, '.');
if (lastPeriod == NULL) return fstring();
fchar* lastSlash = fstrrchr(filename, '/');
fchar* lastBackslash = fstrrchr(filename, '\\');
lastSlash = max(lastSlash, lastBackslash);
if (lastSlash > lastPeriod) return fstring();
fstrlower(lastPeriod + 1);
return fstring(lastPeriod + 1);
}
// For a relative path, extract the list of the individual paths that must be traversed to get to the file.
void FUFileManager::ExtractPathStack(const fstring& name, FStringList& list, bool includeFilename)
{
list.clear();
list.reserve(6);
fstring split = name;
while (split.length() > 0)
{
// Extract out the next path
size_t slashIndex = split.find_first_of('/');
size_t bslashIndex = split.find_first_of('\\');
size_t pathSeparator;
if (slashIndex != fstring::npos && bslashIndex != fstring::npos) pathSeparator = min(slashIndex, bslashIndex);
else if (bslashIndex != fstring::npos) pathSeparator = bslashIndex;
else if (slashIndex != fstring::npos) pathSeparator = slashIndex;
else
{
if (includeFilename) list.push_back(split);
break;
}
list.push_back(split.substr(0, pathSeparator));
split = split.substr(pathSeparator + 1, split.length() - pathSeparator - 1);
}
}
// Make a file path relative/absolute
fstring FUFileManager::MakeFilePathAbsolute(const fstring& _filePath)
{
fstring filePath = _filePath;
if ((filePath.size() > 1 && (filePath[0] == '/' || filePath[0] == '\\')) ||
(filePath.size() > 2 && (filePath[1] == ':' || filePath[1] == '|')))
{
// Already an absolute filepath
}
else
{
// Relative file path.
FStringList documentPaths, localPaths;
ExtractPathStack(pathStack.back(), documentPaths, true);
ExtractPathStack(filePath, localPaths, true);
for (FStringList::iterator it = localPaths.begin(); it != localPaths.end(); ++it)
{
// Look for special relative path tokens: '.' and '..'
if ((*it) == FC(".")) {} // do nothing
else if ((*it) == FC("..")) { documentPaths.pop_back(); } // pop one path out
else { documentPaths.push_back(*it); } // traverse this path
}
// Recreate the absolute filename
filePath.clear();
for (FStringList::iterator it = documentPaths.begin(); it != documentPaths.end(); ++it)
{
if (!filePath.empty()) filePath.push_back('/');
filePath += (*it);
}
if (filePath.size() < 2 || (filePath[1] != ':' && filePath[1] != '|'))
{
filePath.insert(0, '/');
}
}
#ifdef WIN32
std::replace(filePath.begin(), filePath.end(), '/', '\\');
#endif // WIN32
return filePath;
}
fstring FUFileManager::MakeFilePathRelative(const fstring& _filePath)
{
fstring filePath = _filePath;
if (!filePath.empty() && filePath[0] != '.')
{
// First, ensure we have an absolute file path
filePath = MakeFilePathAbsolute(_filePath);
// Relative file path.
FStringList documentPaths, localPaths;
ExtractPathStack(pathStack.back(), documentPaths, true);
ExtractPathStack(filePath, localPaths, true);
// Extract the filename from the path stack
fstring filename = localPaths.back();
localPaths.pop_back();
// Look for commonality in the path stacks
size_t documentPathCount = documentPaths.size();
size_t filePathCount = localPaths.size();
size_t matchIndex = 0;
for (; matchIndex < filePathCount && matchIndex < documentPathCount; ++matchIndex)
{
if (fstricmp(documentPaths[matchIndex].c_str(), localPaths[matchIndex].c_str()) != 0) break;
}
if (matchIndex != 0)
{
// There is some similar part, so generate the relative filename
fstring relativePath;
if (documentPathCount > matchIndex)
{
// Backtrack the document's path
for (size_t i = matchIndex; i < documentPathCount; ++i)
{
relativePath += fstring(FC("../"));
}
}
else
{
// Start at the document's root folder
relativePath = FC("./");
}
// Add the file's relative path
for (size_t i = matchIndex; i < filePathCount; ++i)
{
relativePath += filePath[i] + fstring(FC("/"));
}
filePath = relativePath + filename;
}
}
return filePath;
}

View File

@@ -0,0 +1,55 @@
/*
Copyright (C) 2005-2006 Feeling Software Inc.
MIT License: http://www.opensource.org/licenses/mit-license.php
*/
/*
Based on the FS Import classes:
Copyright (C) 2005-2006 Feeling Software Inc
Copyright (C) 2005-2006 Autodesk Media Entertainment
MIT License: http://www.opensource.org/licenses/mit-license.php
*/
#ifndef _FU_FILE_MANAGER_H_
#define _FU_FILE_MANAGER_H_
class FUFile;
class FCOLLADA_EXPORT FUFileManager
{
private:
FStringList pathStack;
public:
FUFileManager();
~FUFileManager();
// Root path stack
const fstring& GetCurrentPath() { return pathStack.back(); }
void PushRootPath(const fstring& path);
void PopRootPath();
void PushRootFile(const fstring& filename);
void PopRootFile();
// Some file access
FUFile* OpenFile(const fstring& filename, bool write=true);
// Extract information from filenames
static fstring StripFileFromPath(const fstring& filename);
static fstring GetFileExtension(const fstring& filename);
// Make a file path relative/absolute
fstring MakeFilePathAbsolute(const fstring& filePath);
fstring MakeFilePathRelative(const fstring& filePath);
// Transform a file URL into a file path
fstring GetFilePath(const fstring& fileURL);
// Transform a file path into a file URL
fstring GetFileURL(const fstring& filepath, bool relative);
// For a relative path, extract the list of the individual paths that must be traversed to get to the file.
static void ExtractPathStack(const fstring& filename, FStringList& list, bool includeFilename);
};
#endif // _FU_FILE_MANAGER_H_

View File

@@ -0,0 +1,149 @@
/*
Copyright (C) 2005-2006 Feeling Software Inc.
MIT License: http://www.opensource.org/licenses/mit-license.php
*/
/*
This file was taken off the Protect project on 26-09-2005
*/
#ifndef _FUNCTOR_H_
#define _FUNCTOR_H_
// Functor with no argument.
template<typename ReturnType>
class IFunctor0
{
public:
virtual ~IFunctor0() {}
virtual ReturnType operator()() const = 0;
virtual bool Compare(void* pObject, void* pFunction) const = 0;
};
template<typename Class, typename ReturnType>
class FUFunctor0 : public IFunctor0<ReturnType>
{
private:
Class* m_pObject;
ReturnType (Class::*m_pFunction) ();
public:
FUFunctor0(Class* pObject, ReturnType (Class::*pFunction) ()) { m_pObject = pObject; m_pFunction = pFunction; }
virtual ReturnType operator()() const
{ return ((*m_pObject).*m_pFunction)(); }
virtual bool Compare(void* pObject, void* pFunction) const
{ return pObject == m_pObject && (unsigned long)pFunction == *(unsigned long*)&m_pFunction; }
};
template<typename ReturnType>
class FUStaticFunctor0 : public IFunctor0<ReturnType>
{
private:
ReturnType (*m_pFunction) ();
public:
FUStaticFunctor0(ReturnType (*pFunction) ()) { m_pFunction = pFunction; }
virtual ReturnType operator()() const
{ return (*m_pFunction)(); }
virtual bool Compare(void*, void* pFunction) const
{ return (unsigned long)pFunction == *(unsigned long*)&m_pFunction; }
};
// Functor with one argument.
template<typename Arg1, typename ReturnType>
class IFunctor1
{
public:
virtual ~IFunctor1() {}
virtual ReturnType operator()(Arg1 sArgument1) const = 0;
virtual bool Compare(void* pObject, void* pFunction) const = 0;
};
template<typename Class, typename Arg1, typename ReturnType>
class FUFunctor1 : public IFunctor1<Arg1, ReturnType>
{
private:
Class* m_pObject;
ReturnType (Class::*m_pFunction) (Arg1);
public:
FUFunctor1(Class* pObject, ReturnType (Class::*pFunction) (Arg1)) { m_pObject = pObject; m_pFunction = pFunction; }
virtual ReturnType operator()(Arg1 sArgument1) const
{ return ((*m_pObject).*m_pFunction)(sArgument1); }
virtual bool Compare(void* pObject, void* pFunction) const
{ return pObject == m_pObject && (unsigned long)pFunction == *(unsigned long*)&m_pFunction; }
};
template<typename Arg1, typename ReturnType>
class FUStaticFunctor1 : public IFunctor1<Arg1, ReturnType>
{
private:
ReturnType (*m_pFunction) (Arg1);
public:
FUStaticFunctor1(ReturnType (*pFunction) (Arg1)) { m_pFunction = pFunction; }
virtual ReturnType operator()(Arg1 sArgument1) const
{ return (*m_pFunction)(sArgument1); }
virtual bool Compare(void*, void* pFunction) const
{ return (unsigned long)pFunction == *(unsigned long*)&m_pFunction; }
};
// Functor with two argument.
template<typename Arg1, typename Arg2, typename ReturnType>
class IFunctor2
{
public:
virtual ~IFunctor2() {}
virtual ReturnType operator()(Arg1 sArgument1, Arg2 sArgument2) const = 0;
virtual bool Compare(void* pObject, void* pFunction) const = 0;
};
template<typename Class, typename Arg1, typename Arg2, typename ReturnType>
class FUFunctor2 : public IFunctor2<Arg1, Arg2, ReturnType>
{
private:
Class* m_pObject;
ReturnType (Class::*m_pFunction) (Arg1, Arg2);
public:
FUFunctor2(Class* pObject, ReturnType (Class::*pFunction) (Arg1, Arg2)) { m_pObject = pObject; m_pFunction = pFunction; }
virtual ReturnType operator()(Arg1 sArgument1, Arg2 sArgument2) const
{ return ((*m_pObject).*m_pFunction)(sArgument1, sArgument2); }
virtual bool Compare(void* pObject, void* pFunction) const
{ return pObject == m_pObject && (unsigned long)pFunction == *(unsigned long*)&m_pFunction; }
};
template<typename Arg1, typename Arg2, typename ReturnType>
class FUStaticFunctor2 : public IFunctor2<Arg1, Arg2, ReturnType>
{
private:
ReturnType (*m_pFunction) (Arg1, Arg2);
public:
FUStaticFunctor2(ReturnType (*pFunction) (Arg1, Arg2)) { m_pFunction = pFunction; }
virtual ReturnType operator()(Arg1 sArgument1, Arg2 sArgument2) const
{ return (*m_pFunction)(sArgument1, sArgument2); }
virtual bool Compare(void*, void* pFunction) const
{ return (unsigned long)pFunction == *(unsigned long*)&m_pFunction; }
};
// Macro for member function pointer type bypass
#define FUNCTOR_COMPARE(sFunctor, pObject, pFunction, bRet) \
{ \
void* pVoid; \
__asm { __asm push eax __asm mov eax, pFunction __asm mov pVoid, eax __asm pop eax } \
bRet = sFunctor.Compare(pObject, pVoid); \
}
#endif //_FUNCTOR_H_

View File

@@ -0,0 +1,57 @@
/*
Copyright (C) 2005-2006 Feeling Software Inc.
MIT License: http://www.opensource.org/licenses/mit-license.php
*/
#include "StdAfx.h"
#include "FUtils/FULogFile.h"
#include "FUtils/FUFile.h"
FULogFile::FULogFile(const char* filename)
{
file = new FUFile(filename, FUFile::WRITE);
}
FULogFile::~FULogFile()
{
SAFE_DELETE(file);
}
void FULogFile::WriteLine(const char* filename, uint32 linenum, const char* message, ...)
{
WriteLine("[%s:%d]", filename, (unsigned int) linenum);
va_list vars;
va_start(vars, message);
WriteLineV(message, vars);
va_end(vars);
}
void FULogFile::WriteLine(const char* message, ...)
{
va_list vars;
va_start(vars, message);
WriteLineV(message, vars);
va_end(vars);
}
void FULogFile::WriteLineV(const char* message, va_list& vars)
{
size_t len = strlen(message);
char* buffer = new char[len + 1024];
vsnprintf(buffer, len + 1024, message, vars);
buffer[len + 1023] = 0;
if (file->IsOpen())
{
file->Write(buffer, strlen(buffer) - 1);
file->Write("\n\r", 2);
}
SAFE_DELETE_ARRAY(buffer);
}
void FULogFile::Flush()
{
file->Flush();
}

View File

@@ -0,0 +1,27 @@
/*
Copyright (C) 2005-2006 Feeling Software Inc.
MIT License: http://www.opensource.org/licenses/mit-license.php
*/
#ifndef _FU_LOG_FILE_H_
#define _FU_LOG_FILE_H_
class FUFile;
class FCOLLADA_EXPORT FULogFile
{
private:
FUFile* file;
public:
FULogFile(const char* filename);
~FULogFile();
void WriteLine(const char* filename, uint32 linenum, const char* message, ...);
void WriteLine(const char* message, ...);
void WriteLineV(const char* message, va_list& vars);
void Flush();
};
#endif // _FU_LOG_FILE_H_

View File

@@ -0,0 +1,67 @@
/*
Copyright (C) 2005-2006 Feeling Software Inc.
MIT License: http://www.opensource.org/licenses/mit-license.php
*/
/*
* The idea is simple: the object registers itself in the constructor, with the container.
* It keeps a pointer to this container, so that the parent can easily access it
* In the destructor, the object unregisters itself with the container.
*/
#include "StdAfx.h"
#include "FUtils/FUObject.h"
#ifdef _DEBUG
FUObject::FUObject(FUObjectContainer* _container, const char* _className)
#else
FUObject::FUObject(FUObjectContainer* _container)
#endif
{
container = _container;
#ifdef _DEBUG
className = _className;
#endif
if (container != NULL)
{
container->RegisterObject(this);
}
}
FUObject::~FUObject()
{
if (container != NULL)
{
container->UnregisterObject(this);
container = NULL;
}
}
FUObjectContainer::~FUObjectContainer()
{
#ifdef _DEBUG
while (!objects.empty())
{
FUObject* o = objects.back();
SAFE_DELETE(o); //FIXME: this might cause a crash, but it's good for finding bugs or memory leaks.
}
#endif
}
void FUObjectContainer::RegisterObject(FUObject* object)
{
#if defined(_DEBUG) && defined(_WIN32)
// If the check below fails, you are registering an object twice with this container
FUObjectList::iterator it = std::find(objects.begin(), objects.end(), object);
if (it != objects.end()) { __asm int 3 };
#endif
objects.push_back(object);
}
void FUObjectContainer::UnregisterObject(FUObject* object)
{
FUObjectList::iterator it = std::find(objects.begin(), objects.end(), object);
if (it != objects.end()) objects.erase(it);
#if defined(_DEBUG) && defined(_WIN32)
else { __asm int 3 };
#endif
}

View File

@@ -0,0 +1,102 @@
/*
Copyright (C) 2005-2006 Feeling Software Inc.
MIT License: http://www.opensource.org/licenses/mit-license.php
*/
/*
The idea is simple: the object registers itself in the constructor, with the container.
It keeps a pointer to this container, so that the parent can easily access it
In the destructor, the object unregisters itself with the container.
*/
/**
@file FUObject.h
This file contains the FUObject class and the FUObjectContaimer class.
*/
#ifndef _FU_OBJECT_H_
#define _FU_OBJECT_H_
class FUObjectContainer;
/**
A contained object.
Each object holds a pointer to the container that contains it.
This pointer is useful so that the container can be notified if the object
gets released by someone else.
*/
class FCOLLADA_EXPORT FUObject
{
private:
FUObjectContainer* container;
#ifdef _DEBUG
const char* className;
#endif // _DEBUG
protected:
/** Retrieves the container of the object.
@return A pointer to the container. */
inline FUObjectContainer* GetContainer() { return container; }
inline const FUObjectContainer* GetContainer() const { return container; } /**< See above. */
public:
#ifndef _DEBUG
/** Constructor.
Although it is not an abstract class, class is
not meant to be used directly. This constructor
informs the container of the object's creation.
@param container The container that contains this object. */
FUObject(FUObjectContainer* container);
/** Overwrites the token name of the object.
This token name is used for debugging purposes only.
@param UNUSED The token name for the class of the object. */
inline void SetClassName(const char* UNUSED(_className)) {};
#else
FUObject(FUObjectContainer* container, const char* className);
inline void SetClassName(const char* _className) {className = _className;}
#endif
/** Destructor.
This function informs the container of this object's release. */
~FUObject();
};
/** A dynamically-sized array of contained objects. */
typedef vector<FUObject*> FUObjectList;
/**
An object container
Each container holds a list of contained objects.
It will release all the objects when it is released and the
objects inform it of their creation/destruction.
*/
class FCOLLADA_EXPORT FUObjectContainer
{
private:
friend class FUObject;
FUObjectList objects;
void RegisterObject(FUObject* object);
void UnregisterObject(FUObject* object);
public:
/** Constructor: empty. */
FUObjectContainer() {}
/** Destructor.
Releases all the objects contained within this container. */
virtual ~FUObjectContainer();
};
#ifndef _DEBUG
/** Encapsulates the FUObject class constructor.
This macro is useful to rid ourselves of the 'className' parameter in retail builds.
@param container The container that contains the object.
@param className The token name used only for debugging purposes. */
#define FUObject_Construct(container, className) FUObject(container)
#else
#define FUObject_Construct(container, className) FUObject(container, className)
#endif
#endif // _FU_OBJECT_H_

View File

@@ -0,0 +1,120 @@
/*
Copyright (C) 2005-2006 Feeling Software Inc.
MIT License: http://www.opensource.org/licenses/mit-license.php
*/
/*
Taken off the Protect project in 2005.
*/
/**
@file FUSingleton.h
This file contains macros to easily implement singletons.
A singleton is a class which has only one object of this class.
The advantage of a singleton over a static class is that the
application controls when and how the singleton is created and
destroyed. The disadvantage of a singleton is that you have one
extra memory lookup to do.
*/
#ifndef _FU_SINGLETON_H_
#define _FU_SINGLETON_H_
/** Declares a singleton.
Use this macros within the class declaration.
@param className The name of the class. */
#define DECLARE_SINGLETON_CLASS(className) \
private: \
static className* m_pSingleton; \
public: \
static bool CreateSingleton(); \
static void DestroySingleton(); \
friend className* Get##className();
/** Declares a singleton.
Use this macros within the class declaration.
@param className The name of the class.
@param createArgs An argument for the constructor of the singleton. */
#define DECLARE_SINGLETON_CLASS_WITH_ARGS(className, createArgs) \
private: \
static className* m_pSingleton; \
public: \
static bool CreateSingleton(createArgs); \
static void DestroySingleton(); \
friend className* Get##className();
/** Declares a singleton.
Use this macros within the class declaration.
@param className The name of the class.
@param createArgs1 A first argument for the constructor of the singleton.
@param createArgs2 A second argument for the constructor of the singleton. */
#define DECLARE_SINGLETON_CLASS_WITH_ARGS2(className, createArgs1, createArgs2) \
private: \
static className* m_pSingleton; \
public: \
static bool CreateSingleton(createArgs1, createArgs2); \
static void DestroySingleton(); \
friend className* Get##className();
/** Implements the singleton.
Use this macros within the class implementation.
@param className The name of the class. */
#define IMPLEMENT_SINGLETON(className) \
IMPLEMENT_CREATE_SINGLETON(className) \
IMPLEMENT_DESTROY_SINGLETON(className)
/** Implements the singleton.
Use this macros within the class implementation.
@param className The name of the class.
@param createArg1 The argument for the constructor of the singleton. */
#define IMPLEMENT_SINGLETON_WITH_ARGS(className, createArg1) \
IMPLEMENT_CREATE_SINGLETON_WITH_ARGS(className, createArg1) \
IMPLEMENT_DESTROY_SINGLETON(className)
/** Implements the singleton.
Use this macros within the class implementation.
@param className The name of the class.
@param createArg1 A first argument for the constructor of the singleton.
@param createArg2 A second argument for the constructor of the singleton. */
#define IMPLEMENT_SINGLETON_WITH_ARGS2(className, createArg1, createArg2) \
IMPLEMENT_CREATE_SINGLETON_WITH_ARGS2(className, createArg1, createArg2) \
IMPLEMENT_DESTROY_SINGLETON(className)
/** Implements the construction of a singleton.
Use this macros within the class implementation.
@param className The name of the class. */
#define IMPLEMENT_CREATE_SINGLETON(className) \
className* className::m_pSingleton; \
className* Get##className() { return className::m_pSingleton; } \
bool className::CreateSingleton() { \
m_pSingleton = new className(); \
return true; }
/** Implements the construction of a singleton.
Use this macros within the class implementation.
@param className The name of the class.
@param createArg1 The argument for the constructor of the singleton. */
#define IMPLEMENT_CREATE_SINGLETON_WITH_ARGS(className, createArg1) \
className* className::m_pSingleton; \
className* Get##className() { return className::m_pSingleton; } \
bool className::CreateSingleton(createArg1 argument1) { \
m_pSingleton = new className(argument1); }
/** Implements the construction of a singleton.
Use this macros within the class implementation.
@param className The name of the class.
@param createArg1 A first argument for the constructor of the singleton.
@param createArg2 A second argument for the constructor of the singleton. */
#define IMPLEMENT_CREATE_SINGLETON_WITH_ARGS2(className, createArg1, createArg2) \
className* className::m_pSingleton; \
className* Get##className() { return className::m_pSingleton; } \
bool className::CreateSingleton(createArg1 argument1, createArg2 argument2) { \
m_pSingleton = new className(argument1, argument2); }
/** Implements the destruction of a singleton.
Use this macros within the class implementation.
@param className The name of the class. */
#define IMPLEMENT_DESTROY_SINGLETON(className) \
void className::DestroySingleton() \
{ SAFE_DELETE(m_pSingleton); }
#endif // _FU_SINGLETON_H_

View File

@@ -0,0 +1,91 @@
/*
Copyright (C) 2005-2006 Feeling Software Inc.
MIT License: http://www.opensource.org/licenses/mit-license.php
*/
/*
Based on the FS Import classes:
Copyright (C) 2005-2006 Feeling Software Inc
Copyright (C) 2005-2006 Autodesk Media Entertainment
MIT License: http://www.opensource.org/licenses/mit-license.php
*/
/**
@file FUStatus.h
This file contains the FUStatus class.
*/
#ifndef _FU_STATUS_H_
#define _FU_STATUS_H_
/**
A return status structure that includes a string.
Contains a return code as well as a string which explains the errors and warnings
attached to the return code. The return code is either 'successful' or 'failure'.
If the return code is 'failure', proceeding normally may be dangerous.
This structure is used by the FCDocument classes to explain parsing errors.
@ingroup FUtils
*/
class FCOLLADA_EXPORT FUStatus
{
private:
fstring errorString;
bool callSuccessful;
public:
/** Default Constructor.
The default return code is 'successful'.
@param _callSuccessful Whether the return code should be set to 'successful'. */
FUStatus(bool _callSuccessful=true) { callSuccessful = _callSuccessful; }
/** Sets the value of the return code to 'failure'.
@return The error code structure. Returns itself to support
multiple subsequent operations in one statement. */
FUStatus& Fail() { callSuccessful = false; return *this; }
/** Sets the value of the return code to 'failure'.
@param str The error string for the error encountered.
@param line A line number.
@return The return status structure. Returns itself to support
multiple subsequent operations in one statement. */
FUStatus& Fail(const fstring& str, size_t line=0) { callSuccessful = false; AppendString(FS("ERROR[") + TO_FSTRING(line) + FS("]: ") + str); return *this; }
FUStatus& Fail(const fchar* str, size_t line=0) { callSuccessful = false; AppendString(FS("ERROR[") + TO_FSTRING(line) + FS("]: ") + str); return *this; } /**< See above. */
/** Adds a warning to the return status. A warning does not set the return code to 'failure'.
@param str The warning string for the error encountered.
@param line A line number.
@return The return status structure. Returns itself to support
multiple subsequent operations in one statement. */
FUStatus& Warning(const fstring& str, size_t line=0) { AppendString(FS("WARNING[") + TO_FSTRING(line) + FS("]: ") + str); return *this; }
FUStatus& Warning(const fchar* str, size_t line=0) { AppendString(FS("WARNING[") + TO_FSTRING(line) + FS("]: ") + str); return *this; } /**< See above. */
/** Merges two return stati together.
Appends to this return status the error string from the given status.
The merged return code is 'failure', if either return codes are 'failure'.
@param a The return status to merge with. */
void AppendStatus(const FUStatus& a) { AppendString(a.errorString); callSuccessful &= a.callSuccessful; }
/** Appends a return string to the return status.
A 'newline' code is added between return strings.
@param str The return string to append. */
void AppendString(const fstring& str) { AppendString(str.c_str()); }
void AppendString(const fchar* str) { if (*str != 0) { if (!errorString.empty()) errorString += FC("\r\n"); errorString += str; } } /**< See above. */
/** Retrieves the error/return string for this return status.
@return The return string. */
const fchar* GetErrorString() const { return errorString.empty() ? (callSuccessful ? FC("Success") : FC("Failure")) : errorString.c_str(); }
/** Retrieves whether the return status is 'successful'.
@return Whether the return status is 'successful'. */
bool IsSuccessful() const { return callSuccessful; }
/** Retrieves whether the return status is 'failure'.
@return Whether the return status is 'failure'. */
bool IsFailure() const { return !callSuccessful; }
/** Transforms the return status into a boolean primitive.
@return Whether the return status is 'successful'. */
operator bool() const { return callSuccessful; }
};
#endif // _FU_STATUS_H_

View File

@@ -0,0 +1,84 @@
/*
Copyright (C) 2005-2006 Feeling Software Inc.
MIT License: http://www.opensource.org/licenses/mit-license.php
*/
/**
@file FUString.h
This file includes FUStringBuilder.h and FUStringConversion.h
and defines important string-related macros and inline functions.
*/
#ifndef _FU_STRING_H_
#define _FU_STRING_H_
/** A dynamically-sized array of Unicode strings. */
typedef vector<fstring> FStringList;
/** A dynamically-sized array of simple strings. */
typedef vector<string> StringList;
/** Returns whether two 8-bit strings are equivalent. This is a case-sensitive comparison.
@param sz1 The first 8-bit string to compare.
@param sz2 The second 8-bit string to compare.
@return Whether the two 8-bit strings are equivalent. */
inline bool IsEquivalent(const char* sz1, const char* sz2) { return strcmp(sz1, sz2) == 0; }
inline bool IsEquivalent(const string& sz1, const char* sz2) { return strcmp(sz1.c_str(), sz2) == 0; } /**< See above. */
inline bool IsEquivalent(const char* sz1, const string& sz2) { return strcmp(sz1, sz2.c_str()) == 0; } /**< See above. */
inline bool IsEquivalent(const string& sz1, const string& sz2) { return strcmp(sz1.c_str(), sz2.c_str()) == 0; } /**< See above. */
/** Returns whether two 8-bit strings are equivalent. This is a case-sensitive comparison.
@param sz1 The first 8-bit string to compare.
@param sz2 The second 8-bit string to compare.
@return Whether the two 8-bit strings are equivalent. */
inline bool operator==(const string& sz1, const char* sz2) { return strcmp(sz1.c_str(), sz2) == 0; }
/** Appends a signed integer to an 8-bit string. This function is meant
for debugging purposes. Use the FUStringBuilder class instead.
@param sz1 The 8-bit string prefix.
@param i The signed integer to convert and append.
@return The final 8-bit string. */
FCOLLADA_EXPORT string operator+(const string& sz1, int32 i);
#ifdef UNICODE
/** Returns whether two Unicode strings are equivalent. This is a case-sensitive comparison.
@param sz1 The first Unicode string to compare.
@param sz2 The second Unicode string to compare.
@return Whether the two Unicode strings are equivalent. */
inline bool IsEquivalent(const fchar* sz1, const fchar* sz2) { return fstrcmp(sz1, sz2) == 0; }
inline bool IsEquivalent(const fstring& sz1, const fchar* sz2) { return fstrcmp(sz1.c_str(), sz2) == 0; } /**< See above. */
inline bool IsEquivalent(const fchar* sz1, const fstring& sz2) { return fstrcmp(sz1, sz2.c_str()) == 0; } /**< See above. */
inline bool IsEquivalent(const fstring& sz1, const fstring& sz2) { return fstrcmp(sz1.c_str(), sz2.c_str()) == 0; } /**< See above. */
/** Returns whether two Unicode strings are equivalent. This is a case-sensitive comparison.
@param sz1 The first Unicode string to compare.
@param sz2 The second Unicode string to compare.
@return Whether the two Unicode strings are equivalent. */
inline bool operator==(const fstring& sz1, const fchar* sz2) { return fstrcmp(sz1.c_str(), sz2) == 0; }
/** Appends a signed integer to a Unicode string. This function is meant
for debugging purposes. Use the FUStringBuilder class instead.
@param sz1 The Unicode string prefix.
@param i The signed integer to convert and append.
@return The final Unicode string. */
FCOLLADA_EXPORT fstring operator+(const fstring& sz1, int32 i);
#endif // UNICODE
// Include the main string modification classes.
#include "FUtils/FUStringBuilder.h"
#include "FUtils/FUStringConversion.h"
/** A Unicode string from a constant 8-bit string. */
#define FS(a) fstring(FC(a))
/** A Unicode string from any convertable value: string, vector-type or simple numeric. */
#define TO_FSTRING(a) FUStringConversion::ToFString(a)
/** An 8-bit string from any convertable value: Unicode string, vector-type or simple numeric. */
#define TO_STRING(a) FUStringConversion::ToString(a)
/** An empty UTF-8 string. This string is returned in many functions when there is an error. */
extern FCOLLADA_EXPORT const string emptyString;
/** An empty Unicode string. This string is returned in many functions when there is an error. */
extern FCOLLADA_EXPORT const fstring emptyFString;
#endif // _FU_STRING_H_

View File

@@ -0,0 +1,276 @@
/*
Copyright (C) 2005-2006 Feeling Software Inc.
MIT License: http://www.opensource.org/licenses/mit-license.php
*/
/*
Based on the FS Import classes:
Copyright (C) 2005-2006 Feeling Software Inc
Copyright (C) 2005-2006 Autodesk Media Entertainment
MIT License: http://www.opensource.org/licenses/mit-license.php
*/
/**
@file FUStringBuilder.h
This file contains the FUStringBuilderT template class,
its defined template classes and its helper classes.
*/
#ifndef _FCU_STRING_BUILDER_
#define _FCU_STRING_BUILDER_
/**
A dynamically-sized string object.
The template has two arguments: the character definition and
the sprintf() functor class for float to string conversions.
This class should be used for all the string operations, as it contains a
dynamically-resized buffer that is not directly tied to its content's length.
@ingroup FUtils
*/
template <class Char, class SPrintF>
class FUStringBuilderT
{
private:
Char* buffer;
size_t reserved;
size_t size;
public:
/** The standard string object which correspond to the builder. */
typedef std::basic_string<Char> String;
/** Creates a new builder with the content of the given string.
@param sz A string. Its content will be copied within the builder. */
FUStringBuilderT(const String& sz);
/** Creates a new builder with the content of the given character array.
@param sz A character array. Its content will be copied within the builder.
It must terminate with an element containing the 'zero' value. */
FUStringBuilderT(const Char* sz);
/** Creates a new builder with an empty buffer.
@see reserve
@param reserved The number of character slots to reserve within the empty buffer. */
FUStringBuilderT(size_t reserved);
/** Creates a new builder with an empty buffer. */
FUStringBuilderT();
/** Deletes the builder. Its buffer will be cleared.
Any pointers to its data will be dangling. */
~FUStringBuilderT();
/** Reserves a given number of character slots.
If the builder has a buffer with a different number of character slots, a new
buffer will be allocated. If the builder has contents, it will be copied within
the new buffer. If there is more content than the new buffer can handle, it will
be discarded.
@param length The number of character slots to reserve. */
void reserve(size_t length);
/** Retrieves the length of the content within the builder.
@return The length of the string. */
inline size_t length() { return size; }
/** Clears the content of the builder.
This does not re-allocate a new buffer. */
void clear();
/** Retrieves whether the builder is empty.
A builder is considered empty when it has no content, regardless of
the size or allocation status of its buffer.
@return Whether the builder is empty. */
inline bool empty() { return size == 0; }
/** Appends a character to the content of the builder.
@param c A character. May not be the 'zero' value. */
void append(Char c);
/** Appends a string to the content of the builder.
@param sz A string. */
void append(const String& sz);
/** Appends a character array to the content of the builder.
@param sz A character array. It must terminate with an
element containing the 'zero' value. */
void append(const Char* sz);
/** Appends the content of a builder to the content of this builder.
@param b A string builder. */
void append(const FUStringBuilderT& b);
/** Appends the integer value, after converting it to a string,
to the content of the builder.
@param i An integer value. */
void append(int32 i);
void append(uint32 i); /**< See above. */
void append(uint64 i); /**< See above. */
inline void append(int i) { append((int32) i); } /**< See above. */
#ifdef _W64
inline void append(_W64 unsigned int i) { append((uint32) i); } /**< See above. */
#else
inline void append(unsigned int i) { append((uint32) i); } /**< See above. */
#endif
/** Appends the floating-point value, after converting it to a string,
to the content of the builder. If the floating-point value is the special token
that represents infinity, the string "INF" is appended. If it represents
the negative infinity, the string "-INF" is appended. If it represents the
impossibility, the string "NaN" is appended.
@param f A floating-point value. */
void append(float f);
void append(double f); /**< See above. */
/** Appends a value to the content of the builder.
This is a shortcut for the append function.
@see append
@param val A value. This may be numerical, a character, a character array or a string. */
template<typename TYPE> inline FUStringBuilderT& operator+=(const TYPE& val) { append(val); return *this; }
/** Appends a character array to the content of the builder.
A newline character will be appended after the character array.
@param sz A character array. It must terminate with an
element containing the 'zero' value. */
void appendLine(const Char* sz);
/** Removes a section of the content of the builder.
Every character that occurs after the given index will be removed,
resulting in a shrunk string.
@param start An index within the content of the builder. */
void remove(int32 start);
/** Removes a section of the content of the builder.
The substring defined by the 'start' and 'end' indices will be
removed. The 'start' character is removed and is replaced by
the 'end' character.
@param start The index of the first character of the substring to remove.
@param end The index of the first character after the removed substring. */
void remove(int32 start, int32 end);
/** Removes the last character of the content of the builder. */
inline void pop_back() { if (size > 0) --size; }
/** Sets the content of the builder to a given value.
This clears the builder of all its content and appends the given value.
@param val A value. This may be numerical, a character, a character array or a string. */
template<typename TYPE> inline void set(const TYPE& val) { clear(); append(val); }
template<typename TYPE> inline FUStringBuilderT& operator=(const TYPE& val) { clear(); append(val); return *this; } /**< See above. */
/** Converts the content of the builder to a standard string.
@return A string with the content of the builder. */
String ToString();
operator String() { return ToString(); } /**< See above. */
/** Converts the content of the builder to a character array.
@return A character array with the content of the builder.
This pointer is valid for the lifetime of the buffer of the builder, so
do not keep it around. This character array should not be modified. */
const Char* ToCharPtr();
operator const Char*() { return ToCharPtr(); } /**< See above. */
/** Retrieves the index of the first character within the content of the builder
that is equivalent to the given character.
@param c The character to match.
@return The index of the first equivalent character. -1 is returned if no
character matches the given character. */
int32 index(Char c);
/** Retrieves the index of the last character within the content of the builder
that is equivalent to the given character.
@param c The character to match.
@return The index of the last equivalent character. -1 is returned if no
character matches the given character. */
int32 rindex(Char c);
private:
void enlarge(size_t minimum);
};
/**
Encapsulates the 8-bit string numerical conversion functions.
The 'snprintf' function is used so no locale information is handled.
*/
class SprintF
{
public:
/** Converts a signed integer into the given constant-sized string.
@param output A constant-sized string.
@param length The size of the constant-sized string.
@param i A signed integer. */
void PrintInt32(char* output, uint32 length, int32 i) { snprintf(output, length, "%i", i); }
/** Converts an unsigned integer into the given constant-sized string.
@param output A constant-sized string.
@param length The size of the constant-sized string.
@param i An unsigned integer. */
void PrintUInt32(char* output, uint32 length, uint32 i) { snprintf(output, length, "%u", i); }
void PrintUInt64(char* output, uint32 length, uint64 i) { snprintf(output, length, "%u", i); } /**< See above. */
/** Converts a floating-point value into the given constant-sized string.
@param output A constant-sized string.
@param length The size of the constant-sized string.
@param f A floating-point value. */
void PrintFloat(char* output, uint32 length, double f) { snprintf(output, length, "%f", f); }
/** Retrieves the length of a constant-sized string.
@param in A character array which is terminated with a 'zero' element.
@return The number of element preceeding the 'zero' element. */
size_t StrLen(const char* in) { return strlen(in); }
};
/**
Encapsulates the Unicode string numerical conversion functions.
The 'fsnprintf' function is used so no locale information is handled.
*/
class SFprintF
{
public:
/** Converts a signed integer into the given constant-sized string.
@param output A constant-sized string.
@param length The size of the constant-sized string.
@param i A signed integer. */
void PrintInt32(fchar* output, uint32 length, int32 i) { fsnprintf(output, length, FC("%i"), i); }
/** Converts an unsigned integer into the given constant-sized string.
@param output A constant-sized string.
@param length The size of the constant-sized string.
@param i An unsigned integer. */
void PrintUInt32(fchar* output, uint32 length, uint32 i) { fsnprintf(output, length, FC("%u"), i); }
/** Converts an unsigned integer into the given constant-sized string.
@param output A constant-sized string.
@param length The size of the constant-sized string.
@param i An unsigned integer. */
void PrintUInt64(fchar* output, uint32 length, uint64 i) { fsnprintf(output, length, FC("%u"), i); }
/** Converts a floating-point value into the given constant-sized string.
@param output A constant-sized string.
@param length The size of the constant-sized string.
@param f A floating-point value. */
void PrintFloat(fchar* output, uint32 length, double f) { fsnprintf(output, length, FC("%f"), f); }
/** Retrieves the length of a constant-sized string.
@param in A character array which is terminated with a 'zero' element.
@return The number of element preceeding the 'zero' element. */
size_t StrLen(const fchar* in) { return fstrlen(in); }
};
typedef FUStringBuilderT<fchar, SFprintF> FUStringBuilder; /**< A Unicode string builder. */
typedef FUStringBuilderT<char, SprintF> FUSStringBuilder; /**< A 8-bit string builder. */
/** Declares a global Unicode string builder.
As many functions within FCollada use the global string builders, their content is often overwritten.
Use this builder only for quick conversion or character accumulation. */
FCOLLADA_EXPORT extern FUStringBuilder globalBuilder;
/** Declares a global 8-bit string builder.
As many functions within FCollada use the global string builders, their content is often overwritten.
Use this builder only for quick conversion or character accumulation. */
FCOLLADA_EXPORT extern FUSStringBuilder globalSBuilder;
#include "FUtils/FUStringBuilder.hpp"
#endif // _FCU_STRING_BUILDER_

View File

@@ -0,0 +1,275 @@
/*
Copyright (C) 2005-2006 Feeling Software Inc.
MIT License: http://www.opensource.org/licenses/mit-license.php
*/
/*
Based on the FS Import classes:
Copyright (C) 2005-2006 Feeling Software Inc
Copyright (C) 2005-2006 Autodesk Media Entertainment
MIT License: http://www.opensource.org/licenses/mit-license.php
*/
#include <limits>
#ifdef WIN32
#include <float.h>
#endif
#ifndef SAFE_DELETE_ARRAY
#define SAFE_DELETE_ARRAY(ptr) if (ptr != NULL) { delete [] ptr; ptr = NULL; }
#endif
template <class Char, class SPrintF>
FUStringBuilderT<Char,SPrintF>::FUStringBuilderT(const String& sz)
{
this->buffer = NULL;
this->size = 0;
this->reserved = 0;
reserve(sz.size() + 32);
append(sz.c_str());
}
template <class Char, class SPrintF>
FUStringBuilderT<Char,SPrintF>::FUStringBuilderT(const Char* sz)
{
this->buffer = NULL;
this->size = 0;
this->reserved = 0;
SPrintF s;
reserve(s.StrLen(sz) + 32);
append(sz);
}
template <class Char, class SPrintF>
FUStringBuilderT<Char,SPrintF>::FUStringBuilderT(size_t reservation)
{
this->buffer = NULL;
this->size = 0;
this->reserved = 0;
reserve(reservation);
}
template <class Char, class SPrintF>
FUStringBuilderT<Char,SPrintF>::FUStringBuilderT()
{
this->buffer = NULL;
this->size = 0;
this->reserved = 0;
#ifndef _DEBUG
reserve(32);
#endif
}
template <class Char, class SPrintF>
FUStringBuilderT<Char,SPrintF>::~FUStringBuilderT()
{
reserve(0);
}
template <class Char, class SPrintF>
void FUStringBuilderT<Char,SPrintF>::enlarge(size_t minimum)
{
reserve(max(reserved + minimum + 32, 2 * reserved + 32));
}
template <class Char, class SPrintF>
void FUStringBuilderT<Char,SPrintF>::clear()
{
size = 0;
}
template <class Char, class SPrintF>
void FUStringBuilderT<Char,SPrintF>::reserve(size_t _length)
{
FUAssert(size <= reserved, );
if (_length > reserved)
{
Char* b = new Char[_length];
memcpy(b, buffer, size * sizeof(Char));
SAFE_DELETE_ARRAY(buffer);
buffer = b;
reserved = _length;
}
else if (_length == 0)
{
SAFE_DELETE_ARRAY(buffer);
size = reserved = 0;
}
else if (_length < reserved)
{
size_t realSize = min(size, _length);
Char* b = new Char[_length];
memcpy(b, buffer, realSize * sizeof(Char));
SAFE_DELETE_ARRAY(buffer);
buffer = b;
reserved = _length;
size = realSize;
}
}
template <class Char, class SPrintF>
void FUStringBuilderT<Char,SPrintF>::append(Char c)
{
if (size + 1 >= reserved) enlarge(2);
buffer[size++] = c;
}
template <class Char, class SPrintF>
void FUStringBuilderT<Char,SPrintF>::append(const String& sz) { append(sz.c_str()); }
template <class Char, class SPrintF>
void FUStringBuilderT<Char,SPrintF>::append(const Char* sz)
{
// This is optimized for SMALL strings.
for (; *sz != 0; ++sz)
{
if (size >= reserved) enlarge(64);
buffer[size++] = *sz;
}
}
template <class Char, class SPrintF>
void FUStringBuilderT<Char,SPrintF>::append(const FUStringBuilderT& b)
{
if (size + b.size >= reserved) enlarge(64 + size + b.size - reserved);
memcpy(buffer + size, b.buffer, b.size * sizeof(Char));
size += b.size;
}
template <class Char, class SPrintF>
void FUStringBuilderT<Char,SPrintF>::append(uint32 i)
{
Char sz[128];
SPrintF writer; writer.PrintUInt32(sz, 128, i);
append(sz);
}
template <class Char, class SPrintF>
void FUStringBuilderT<Char,SPrintF>::append(uint64 i)
{
Char sz[128];
SPrintF writer; writer.PrintUInt64(sz, 128, i);
append(sz);
}
template <class Char, class SPrintF>
void FUStringBuilderT<Char,SPrintF>::append(int32 i)
{
Char sz[128];
SPrintF writer; writer.PrintInt32(sz, 128, i);
append(sz);
}
template <class Char, class SPrintF>
void FUStringBuilderT<Char,SPrintF>::append(float f)
{
if (f != std::numeric_limits<float>::infinity() && f != -std::numeric_limits<float>::infinity() && f != std::numeric_limits<float>::quiet_NaN() && f != std::numeric_limits<float>::signaling_NaN())
{
if (IsEquivalent(f, 0.0f, std::numeric_limits<float>::epsilon())) append('0');
else
{
Char sz[128];
SPrintF writer; writer.PrintFloat(sz, 128, f);
append(sz);
}
}
else if (f == std::numeric_limits<float>::infinity())
{ append('I'); append('N'); append('F'); }
else if (f == -std::numeric_limits<float>::infinity())
{ append('-'); append('I'); append('N'); append('F'); }
else
{ append('N'); append('a'); append('N'); }
}
template <class Char, class SPrintF>
void FUStringBuilderT<Char,SPrintF>::append(double f)
{
if (f != std::numeric_limits<double>::infinity() && f != -std::numeric_limits<double>::infinity() && f != std::numeric_limits<double>::quiet_NaN() && f != std::numeric_limits<double>::signaling_NaN())
{
if (IsEquivalent(f, 0.0, std::numeric_limits<double>::epsilon())) append('0');
else
{
Char sz[128];
SPrintF writer; writer.PrintFloat(sz, 128, f);
append(sz);
}
}
else if (f == std::numeric_limits<double>::infinity())
{ append('I'); append('N'); append('F'); }
else if (f == -std::numeric_limits<double>::infinity())
{ append('-'); append('I'); append('N'); append('F'); }
else
{ append('N'); append('a'); append('N'); }
}
template <class Char, class SPrintF>
void FUStringBuilderT<Char,SPrintF>::appendLine(const Char* sz)
{
append(sz);
append("\n");
}
template <class Char, class SPrintF>
void FUStringBuilderT<Char,SPrintF>::remove(int32 start)
{
if ((int32)size > start && start >= 0) size = start;
}
template <class Char, class SPrintF>
void FUStringBuilderT<Char,SPrintF>::remove(int32 start, int32 end)
{
int32 diff = end - start;
if ((int32)size >= end && start >= 0 && diff > 0)
{
const Char* stop = buffer + size - diff;
for (Char* p = buffer + start; p != stop; ++p)
{
*p = *(p + diff);
}
size -= diff;
}
}
template <class Char, class SPrintF>
typename FUStringBuilderT<Char,SPrintF>::String FUStringBuilderT<Char,SPrintF>::ToString()
{
return String((const Char*)*this);
}
template <class Char, class SPrintF>
const Char* FUStringBuilderT<Char,SPrintF>::ToCharPtr()
{
if (size + 1 > reserved) enlarge(1);
buffer[size] = 0;
return buffer;
}
template <class Char, class SPrintF>
int32 FUStringBuilderT<Char,SPrintF>::index(Char c)
{
if (buffer != NULL && size > 0)
{
const Char* end = buffer + size + 1;
for (const Char* p = buffer; p != end; ++p)
{
if (*p == c) return (int32)(p - buffer);
}
}
return -1;
}
template <class Char, class SPrintF>
int32 FUStringBuilderT<Char,SPrintF>::rindex(Char c)
{
if (buffer != NULL && size > 0)
{
for (const Char* p = buffer + size - 1; p != buffer; --p)
{
if (*p == c) return (int32)(p - buffer);
}
}
return -1;
}

View File

@@ -0,0 +1,830 @@
/*
Copyright (C) 2005-2006 Feeling Software Inc.
MIT License: http://www.opensource.org/licenses/mit-license.php
*/
/*
Based on the FS Import classes:
Copyright (C) 2005-2006 Feeling Software Inc
Copyright (C) 2005-2006 Autodesk Media Entertainment
MIT License: http://www.opensource.org/licenses/mit-license.php
*/
#include "StdAfx.h"
#include "FUtils/FUStringConversion.h"
#include "FUtils/FUStringBuilder.h"
#include "FUtils/FUDateTime.h"
FUStringBuilder globalBuilder;
FUSStringBuilder globalSBuilder;
// Some string writer macros
#define SPACE builder.append(' ')
#define VAL(x) builder.append(x)
// Convert a UTF-8 string to a fstring
#ifdef UNICODE
fstring FUStringConversion::ToFString(const char* value)
{
globalBuilder.clear();
uint32 length = (uint32) strlen(value);
globalBuilder.reserve(length + 1);
for(uint32 i = 0; i < length; ++i)
{
globalBuilder.append((fchar)value[i]);
}
return globalBuilder.ToString();
}
#else // UNICODE
fstring FUStringConversion::ToFString(const char* value) { return fstring(value); }
#endif // UNICODE
// Convert a fstring string to a UTF-8 string
#ifdef UNICODE
string FUStringConversion::ToString(const fchar* value)
{
globalSBuilder.clear();
uint32 length = (uint32) fstrlen(value);
globalSBuilder.reserve(length + 1);
for(uint32 i = 0; i < length; ++i)
{
if (value[i] < 0xFF || (value[i] & (~0xFF)) >= 32) globalSBuilder.append((char)value[i]);
else globalSBuilder.append('_'); // some generic enough character
}
return globalSBuilder.ToString();
}
#else // UNICODE
string FUStringConversion::ToString(const fchar* value) { return string(value); }
#endif // UNICODE
// Convert a fstring to a boolean value
#ifdef UNICODE
bool FUStringConversion::ToBoolean(const fchar* value)
{
return value != NULL && *value != 0 && *value != '0' && *value != 'f' && *value != 'F';
}
#endif // UNICODE
bool FUStringConversion::ToBoolean(const char* value)
{
return value != NULL && *value != 0 && *value != '0' && *value != 'f' && *value != 'F';
}
// Convert a fstring to a int32 and advance the character pointer
#ifdef UNICODE
int32 FUStringConversion::ToInt32(const fchar** value)
{
if (!*value) return 0;
// Skip beginning white spaces
const fchar* s = *value;
fchar c;
while ((c = *s) != 0 && (c == ' ' || c == '\t' || c == '\r' || c == '\n')) { ++s; }
int32 val = 0;
int32 sign = 1;
if (*s == '-') { ++s; sign = -1; }
while ((c = *s) != 0)
{
if (c >= '0' && c <= '9') val = val * 10 + c - '0';
else break;
++s;
}
val *= sign;
while ((c = *s) != '\0' && (c != ' ' && c != '\t' && c != '\n')) s++;
while ((c = *s) != '\0' && (c == ' ' || c == '\t' || c == '\n')) s++;
*value = s;
return val;
}
#endif // UNICODE
int32 FUStringConversion::ToInt32(const char** value)
{
if (!*value) return 0;
// Skip beginning white spaces
const char* s = *value;
char c;
while ((c = *s) != 0 && (c == ' ' || c == '\t' || c == '\r' || c == '\n')) { ++s; }
int32 val = 0;
int32 sign = 1;
if (*s == '-') { ++s; sign = -1; }
while ((c = *s) != 0)
{
if (c >= '0' && c <= '9') val = val * 10 + c - '0';
else break;
++s;
}
val *= sign;
while ((c = *s) != '\0' && (c != ' ' && c != '\t' && c != '\n')) s++;
while ((c = *s) != '\0' && (c == ' ' || c == '\t' || c == '\n')) s++;
*value = s;
return val;
}
// Convert a fstring to a float and advance the character pointer
#ifdef UNICODE
float FUStringConversion::ToFloat(const fchar** value)
{
const fchar* s = *value;
if (s == NULL || *s == 0) return 0.0f;
// Skip beginning white spaces
fchar c;
while ((c = *s) != 0 && (c == ' ' || c == '\t' || c == '\r' || c == '\n')) { ++s; }
// Skip all the plausible numerical characters
double val = 0.0;
int sign = 1;
if (*s == '-') { ++s; sign = -1; }
int32 decimals = 0;
int32 exponent = 0;
bool infinity = false;
bool nonValidFound = false;
while ((c = *s) != 0 && !nonValidFound)
{
switch(c)
{
case '.': decimals = 1; break;
case '0': val *= 10.0; decimals *= 10; break;
case '1': val = val * 10.0 + 1; decimals *= 10; break;
case '2': val = val * 10.0 + 2; decimals *= 10; break;
case '3': val = val * 10.0 + 3; decimals *= 10; break;
case '4': val = val * 10.0 + 4; decimals *= 10; break;
case '5': val = val * 10.0 + 5; decimals *= 10; break;
case '6': val = val * 10.0 + 6; decimals *= 10; break;
case '7': val = val * 10.0 + 7; decimals *= 10; break;
case '8': val = val * 10.0 + 8; decimals *= 10; break;
case '9': val = val * 10.0 + 9; decimals *= 10; break;
case 'e':
case 'E': ++s; exponent = ToInt32(&s); --s;
case 'I': nonValidFound = true; infinity = true; --s; break;
default: nonValidFound = true; --s; break;
}
++s;
}
if(infinity) // test for infinity
{
infinity = false;
if(*s=='I')
if(*(++s)=='N')
if(*(++s)=='F')
{
infinity = true;
decimals=0;
val = std::numeric_limits<double>::infinity() * (double)sign;
}
}
if(!infinity)
{
// Generate the value
if (decimals != 0) val /= (double)decimals;
val *= (double)sign;
if (exponent != 0) val *= pow(10.0, (double) exponent);
}
// Find next whitespaces and Skip end whitespaces
while ((c = *s) != 0 && c != ' ' && c != '\t' && c != '\r' && c != '\n') { ++s; }
while ((c = *s) != 0 && (c == ' ' || c == '\t' || c == '\r' || c == '\n')) { ++s; }
*value = s;
return (float)val;
}
#endif // UNICODE
float FUStringConversion::ToFloat(const char** value)
{
const char* s = *value;
if (s == NULL || *s == 0) return 0.0f;
// Skip beginning white spaces
char c;
while ((c = *s) != 0 && (c == ' ' || c == '\t' || c == '\r' || c == '\n')) { ++s; }
// Skip all the plausible numerical characters
double val = 0.0;
int sign = 1;
if (*s == '-') { ++s; sign = -1; }
int32 decimals = 0;
int32 exponent = 0;
bool infinity = false;
bool nonValidFound = false;
while ((c = *s) != 0 && !nonValidFound)
{
switch(c)
{
case '.': decimals = 1; break;
case '0': val *= 10.0; decimals *= 10; break;
case '1': val = val * 10.0 + 1; decimals *= 10; break;
case '2': val = val * 10.0 + 2; decimals *= 10; break;
case '3': val = val * 10.0 + 3; decimals *= 10; break;
case '4': val = val * 10.0 + 4; decimals *= 10; break;
case '5': val = val * 10.0 + 5; decimals *= 10; break;
case '6': val = val * 10.0 + 6; decimals *= 10; break;
case '7': val = val * 10.0 + 7; decimals *= 10; break;
case '8': val = val * 10.0 + 8; decimals *= 10; break;
case '9': val = val * 10.0 + 9; decimals *= 10; break;
case 'e':
case 'E': ++s; exponent = ToInt32(&s); --s;
case 'I': nonValidFound = true; infinity = true; --s; break;
default: nonValidFound = true; --s; break;
}
++s;
}
if(infinity) // test for infinity
{
infinity = false;
if(*s=='I')
if(*(++s)=='N')
if(*(++s)=='F')
{
infinity = true;
decimals=0;
val = std::numeric_limits<double>::infinity() * (double)sign;
}
}
if(!infinity)
{
// Generate the value
if (decimals != 0) val /= (double)decimals;
val *= (double)sign;
if (exponent != 0) val *= pow(10.0, (double) exponent);
}
// Find next whitespaces and Skip end whitespaces
while ((c = *s) != 0 && c != ' ' && c != '\t' && c != '\r' && c != '\n') { ++s; }
while ((c = *s) != 0 && (c == ' ' || c == '\t' || c == '\r' || c == '\n')) { ++s; }
*value = s;
return (float)val;
}
// Convert a fstring to a uint32 and advance the character pointer
#ifdef UNICODE
uint32 FUStringConversion::ToUInt32(const fchar** value)
{
if (value == NULL || *value == NULL || **value == 0) return 0;
// Skip beginning white spaces
const fchar* s = *value;
fchar c;
while ((c = *s) != 0 && (c == ' ' || c == '\t' || c == '\r' || c == '\n')) { ++s; }
uint32 val = 0;
while ((c = *s) != 0)
{
if (c >= '0' && c <= '9') val = val * 10 + c - '0';
else break;
++s;
}
while ((c = *s) != '\0' && (c != ' ' && c != '\t' && c != '\n')) s++;
while ((c = *s) != '\0' && (c == ' ' || c == '\t' || c == '\n')) s++;
*value = s;
return val;
}
#endif // UNICODE
uint32 FUStringConversion::ToUInt32(const char** value)
{
if (value == NULL || *value == NULL || **value == 0) return 0;
// Skip beginning white spaces
const char* s = *value;
char c;
while ((c = *s) != 0 && (c == ' ' || c == '\t' || c == '\r' || c == '\n')) { ++s; }
uint32 val = 0;
while ((c = *s) != 0)
{
if (c >= '0' && c <= '9') val = val * 10 + c - '0';
else break;
++s;
}
while ((c = *s) != '\0' && (c != ' ' && c != '\t' && c != '\n')) s++;
while ((c = *s) != '\0' && (c == ' ' || c == '\t' || c == '\n')) s++;
*value = s;
return val;
}
uint32 FUStringConversion::HexToUInt32(const char** value, uint32 count)
{
if (value == NULL || *value == NULL || **value == 0) return 0;
const char* s = *value;
char c;
uint32 val = 0;
for (uint32 i = 0; i < count && (c = *s) != 0; ++i)
{
if (c >= '0' && c <= '9') val = val * 16 + c - '0';
else if (c >= 'A' && c <= 'F') val = val * 16 + c + 10 - 'A';
else if (c >= 'a' && c <= 'f') val = val * 16 + c + 10 - 'a';
else break;
++s;
}
*value = s;
return val;
}
#ifdef UNICODE
uint32 FUStringConversion::HexToUInt32(const fchar** value, uint32 count)
{
if (value == NULL || *value == NULL || **value == 0) return 0;
const fchar* s = *value;
fchar c;
uint32 val = 0;
for (uint32 i = 0; i < count && (c = *s) != 0; ++i)
{
if (c >= '0' && c <= '9') val = val * 16 + c - '0';
else if (c >= 'A' && c <= 'Z') val = val * 16 + c + 10 - 'A';
else if (c >= 'a' && c <= 'z') val = val * 16 + c + 10 - 'a';
else break;
++s;
}
*value = s;
return val;
}
#endif // UNICODE
#ifdef UNICODE
void FUStringConversion::ToMatrix(const fchar** s, FMMatrix44& mx, float lengthFactor)
{
if (s != NULL && *s != NULL && **s != 0)
{
// COLLADA is Column major
mx[0][0] = ToFloat(s); mx[1][0] = ToFloat(s); mx[2][0] = ToFloat(s); mx[3][0] = ToFloat(s) * lengthFactor;
mx[0][1] = ToFloat(s); mx[1][1] = ToFloat(s); mx[2][1] = ToFloat(s); mx[3][1] = ToFloat(s) * lengthFactor;
mx[0][2] = ToFloat(s); mx[1][2] = ToFloat(s); mx[2][2] = ToFloat(s); mx[3][2] = ToFloat(s) * lengthFactor;
mx[0][3] = ToFloat(s); mx[1][3] = ToFloat(s); mx[2][3] = ToFloat(s); mx[3][3] = ToFloat(s);
}
}
#endif // UNICODE
void FUStringConversion::ToMatrix(const char** s, FMMatrix44& mx, float lengthFactor)
{
if (s != NULL && *s != NULL && **s != 0)
{
// COLLADA is Column major
mx[0][0] = ToFloat(s); mx[1][0] = ToFloat(s); mx[2][0] = ToFloat(s); mx[3][0] = ToFloat(s) * lengthFactor;
mx[0][1] = ToFloat(s); mx[1][1] = ToFloat(s); mx[2][1] = ToFloat(s); mx[3][1] = ToFloat(s) * lengthFactor;
mx[0][2] = ToFloat(s); mx[1][2] = ToFloat(s); mx[2][2] = ToFloat(s); mx[3][2] = ToFloat(s) * lengthFactor;
mx[0][3] = ToFloat(s); mx[1][3] = ToFloat(s); mx[2][3] = ToFloat(s); mx[3][3] = ToFloat(s);
}
}
// Convert a matrix to a string
void FUStringConversion::ToString(FUSStringBuilder& builder, const FMMatrix44& m, float lengthFactor)
{
VAL(m[0][0]); SPACE; VAL(m[1][0]); SPACE; VAL(m[2][0]); SPACE; VAL(m[3][0] * lengthFactor); SPACE;
VAL(m[0][1]); SPACE; VAL(m[1][1]); SPACE; VAL(m[2][1]); SPACE; VAL(m[3][1] * lengthFactor); SPACE;
VAL(m[0][2]); SPACE; VAL(m[1][2]); SPACE; VAL(m[2][2]); SPACE; VAL(m[3][2] * lengthFactor); SPACE;
VAL(m[0][3]); SPACE; VAL(m[1][3]); SPACE; VAL(m[2][3]); SPACE; VAL(m[3][3]);
}
string FUStringConversion::ToString(const FMMatrix44& m, float lengthFactor)
{
globalSBuilder.clear();
ToString(globalSBuilder, m, lengthFactor);
return globalSBuilder.ToString();
}
string FUStringConversion::ToString(const FUDateTime& dateTime)
{
char sz[21];
snprintf(sz, 21, "%04d-%02d-%02dT%02d:%02d:%02dZ", dateTime.GetYear(), dateTime.GetMonth(), dateTime.GetDay(), dateTime.GetHour(), dateTime.GetMinutes(), dateTime.GetSeconds());
sz[20] = 0;
return string(sz);
}
// Convert a matrix to a fstring
void FUStringConversion::ToFString(FUStringBuilder& builder, const FMMatrix44& m, float lengthFactor)
{
VAL(m[0][0]); SPACE; VAL(m[1][0]); SPACE; VAL(m[2][0]); SPACE; VAL(m[3][0] * lengthFactor); SPACE;
VAL(m[0][1]); SPACE; VAL(m[1][1]); SPACE; VAL(m[2][1]); SPACE; VAL(m[3][1] * lengthFactor); SPACE;
VAL(m[0][2]); SPACE; VAL(m[1][2]); SPACE; VAL(m[2][2]); SPACE; VAL(m[3][2] * lengthFactor); SPACE;
VAL(m[0][3]); SPACE; VAL(m[1][3]); SPACE; VAL(m[2][3]); SPACE; VAL(m[3][3]);
}
fstring FUStringConversion::ToFString(const FMMatrix44& m, float lengthFactor)
{
globalBuilder.clear();
ToFString(globalBuilder, m, lengthFactor);
return globalBuilder.ToString();
}
fstring FUStringConversion::ToFString(const FUDateTime& dateTime)
{
fchar sz[21];
fsnprintf(sz, 21, FC("%04d-%02d-%02dT%02d:%02d:%02dZ"), dateTime.GetYear(), dateTime.GetMonth(), dateTime.GetDay(), dateTime.GetHour(), dateTime.GetMinutes(), dateTime.GetSeconds());
sz[20] = 0;
return fstring(sz);
}
void FUStringConversion::ToDateTime(const char* value, FUDateTime& dateTime)
{
// We're not in the business of checking the string value for UTC correctness: assume "YYYY-MM-DDTHH:MM:SSZ".
if (strlen(value) == 20)
{
dateTime.SetYear(ToUInt32(value)); value += 5;
dateTime.SetMonth(ToUInt32(value)); value += 3;
dateTime.SetDay(ToUInt32(value)); value += 3;
dateTime.SetHour(ToUInt32(value)); value += 3;
dateTime.SetMinutes(ToUInt32(value)); value += 3;
dateTime.SetSeconds(ToUInt32(value)); value += 3;
}
}
#ifdef UNICODE
void FUStringConversion::ToDateTime(const fchar* value, FUDateTime& dateTime)
{
if (fstrlen(value) == 20)
{
dateTime.SetYear(ToUInt32(value)); value += 5;
dateTime.SetMonth(ToUInt32(value)); value += 3;
dateTime.SetDay(ToUInt32(value)); value += 3;
dateTime.SetHour(ToUInt32(value)); value += 3;
dateTime.SetMinutes(ToUInt32(value)); value += 3;
dateTime.SetSeconds(ToUInt32(value)); value += 3;
}
}
#endif
#ifdef HAS_VECTORTYPES
// Split a fstring into multiple substrings
void FUStringConversion::ToFStringList(const fstring& value, FStringList& array)
{
const fchar* s = value.c_str();
// Skip beginning white spaces
fchar c;
while ((c = *s) != 0 && (c == ' ' || c == '\t' || c == '\r' || c == '\n')) { ++s; }
size_t index = 0;
while (*s != 0)
{
const fchar* word = s;
// Find next white space
while ((c = *s) != 0 && c != ' ' && c != '\t' && c != '\r' && c != '\n') { ++s; }
if (index < array.size()) array[index++].append(word, s - word);
else { array.push_back(fstring(word, s - word)); index++; }
// Skip all white spaces
while ((c = *s) != 0 && (c == ' ' || c == '\t' || c == '\r' || c == '\n')) { ++s; }
}
}
void FUStringConversion::ToStringList(const string& value, StringList& array)
{
const char* s = value.c_str();
// Skip beginning white spaces
char c;
while ((c = *s) != 0 && (c == ' ' || c == '\t' || c == '\r' || c == '\n')) { ++s; }
size_t index = 0;
while (*s != 0)
{
const char* word = s;
// Find next white space
while ((c = *s) != 0 && c != ' ' && c != '\t' && c != '\r' && c != '\n') { ++s; }
if (index < array.size()) array[index++].append(word, s - word);
else { array.push_back(string(word, s - word)); index++; }
// Skip all white spaces
while ((c = *s) != 0 && (c == ' ' || c == '\t' || c == '\r' || c == '\n')) { ++s; }
}
}
#ifdef UNICODE
void FUStringConversion::ToStringList(const fchar* value, StringList& array)
{
// Performance could be improved...
ToStringList(ToString(value), array);
}
#endif
// Convert a fstring to a 32-bit integer list
#ifdef UNICODE
void FUStringConversion::ToInt32List(const fchar* value, Int32List& array)
{
if (value != NULL && *value != 0)
{
size_t length = array.size();
for (size_t count = 0; count < length && *value != 0; ++count) array[count] = ToInt32(&value);
while (*value != 0) { int32 i = ToInt32(&value); array.push_back(i); }
}
}
#endif // UNICODE
void FUStringConversion::ToInt32List(const char* value, Int32List& array)
{
if (value != NULL && *value != 0)
{
size_t length = array.size();
for (size_t count = 0; count < length && *value != 0; ++count) array[count] = ToInt32(&value);
while (*value != 0) { int32 i = ToInt32(&value); array.push_back(i); }
}
}
// Convert a fstring to a 32-bit unsigned integer list
#ifdef UNICODE
void FUStringConversion::ToUInt32List(const fchar* value, UInt32List& array)
{
if (value != NULL && *value != 0)
{
size_t length = array.size();
for (size_t count = 0; count < length && *value != 0; ++count) array[count] = ToUInt32(&value);
while (*value != 0) { int32 i = ToUInt32(&value); array.push_back(i); }
}
}
#endif // UNICODE
void FUStringConversion::ToUInt32List(const char* value, UInt32List& array)
{
if (value != NULL && *value != 0)
{
size_t length = array.size();
for (size_t count = 0; count < length && *value != 0; ++count) array[count] = ToUInt32(&value);
while (*value != 0) { int32 i = ToUInt32(&value); array.push_back(i); }
}
}
// Convert a fstring to 32-bit floating point list
#ifdef UNICODE
void FUStringConversion::ToFloatList(const fchar* value, FloatList& array)
{
if (value != NULL && *value != 0)
{
size_t length = array.size();
for (size_t count = 0; count < length && *value != 0; ++count) array[count] = ToFloat(&value);
while (*value != 0) array.push_back(ToFloat(&value));
}
}
#endif // UNICODE
void FUStringConversion::ToFloatList(const char* value, FloatList& array)
{
if (value != NULL && *value != 0)
{
size_t length = array.size();
for (size_t count = 0; count < length && *value != 0; ++count) array[count] = ToFloat(&value);
while (*value != 0) array.push_back(ToFloat(&value));
}
}
// Convert a fstring to a list of interleaved floating points
#ifdef UNICODE
void FUStringConversion::ToInterleavedFloatList(const fchar* value, const vector<FloatList*>& arrays)
{
size_t stride = arrays.size();
if (value != NULL && *value != 0 && stride > 0)
{
size_t length = arrays[0]->size();
for (size_t count = 0; count < length && *value != 0; ++count)
{
for (size_t i = 0; i < stride && *value != 0; ++i)
{
FloatList* array = arrays[i];
if (array != NULL) array->at(count) = ToFloat(&value);
else ToFloat(&value);
}
}
while (*value != 0)
{
for (size_t i = 0; i < stride && *value != 0; ++i)
{
FloatList* array = arrays[i];
if (array != NULL) array->push_back(ToFloat(&value));
else ToFloat(&value);
}
}
}
}
#endif // UNICODE
void FUStringConversion::ToInterleavedFloatList(const char* value, const vector<FloatList*>& arrays)
{
size_t stride = arrays.size();
if (value != NULL && *value != 0 && stride > 0)
{
size_t length = arrays[0]->size();
for (size_t count = 0; count < length && *value != 0; ++count)
{
for (size_t i = 0; i < stride && *value != 0; ++i)
{
FloatList* array = arrays[i];
if (array != NULL) array->at(count) = ToFloat(&value);
else ToFloat(&value);
}
}
while (*value != 0)
{
for (size_t i = 0; i < stride && *value != 0; ++i)
{
FloatList* array = arrays[i];
if (array != NULL) array->push_back(ToFloat(&value));
else ToFloat(&value);
}
}
}
}
// Convert a fstring to a (X,Y,Z) Point object
#ifdef UNICODE
FMVector3 FUStringConversion::ToPoint(const fchar** value, float lengthFactor)
{
FMVector3 p;
if (value != NULL && *value != NULL && **value != 0)
{
p.x = ToFloat(value) * lengthFactor;
p.y = ToFloat(value) * lengthFactor;
p.z = ToFloat(value) * lengthFactor;
}
return p;
}
#endif // UNICODE
FMVector3 FUStringConversion::ToPoint(const char** value, float lengthFactor)
{
FMVector3 p;
if (value != NULL && *value != NULL && **value != 0)
{
p.x = ToFloat(value) * lengthFactor;
p.y = ToFloat(value) * lengthFactor;
p.z = ToFloat(value) * lengthFactor;
}
return p;
}
// Convert a point to a string
void FUStringConversion::ToString(FUSStringBuilder& builder, const FMVector3& p, float lengthFactor)
{
VAL(p.x * lengthFactor); SPACE; VAL(p.y * lengthFactor); SPACE; VAL(p.z * lengthFactor);
}
string FUStringConversion::ToString(const FMVector3& p, float lengthFactor)
{
globalSBuilder.clear();
ToString(globalSBuilder, p, lengthFactor);
return globalSBuilder.ToString();
}
// Convert a vector4 to a string
void FUStringConversion::ToString(FUSStringBuilder& builder, const FMVector4& p, float lengthFactor)
{
VAL(p.w * lengthFactor); SPACE; VAL(p.x * lengthFactor); SPACE; VAL(p.y * lengthFactor); SPACE; VAL(p.z * lengthFactor);
}
string FUStringConversion::ToString(const FMVector4& p, float lengthFactor)
{
globalSBuilder.clear();
ToString(globalSBuilder, p, lengthFactor);
return globalSBuilder.ToString();
}
// Convert a point to a fstring
void FUStringConversion::ToFString(FUStringBuilder& builder, const FMVector3& p, float lengthFactor)
{
VAL(p.x * lengthFactor); SPACE; VAL(p.y * lengthFactor); SPACE; VAL(p.z * lengthFactor);
}
fstring FUStringConversion::ToFString(const FMVector3& p, float lengthFactor)
{
globalBuilder.clear();
ToFString(globalBuilder, p, lengthFactor);
return globalBuilder.ToString();
}
#ifdef HAS_VECTORTYPES
void FUStringConversion::ToString(FUSStringBuilder& builder, const FloatList& values, float lengthFactor)
{
if (values.empty()) return;
if (!builder.empty()) SPACE;
FloatList::const_iterator itV = values.begin();
if (IsEquivalent(lengthFactor, 1.0f))
{
builder.append(*itV);
for (++itV; itV != values.end(); ++itV) { SPACE; VAL(*itV); }
}
else
{
builder.append(*itV * lengthFactor);
for (++itV; itV != values.end(); ++itV) { SPACE; VAL(*itV * lengthFactor); }
}
}
void FUStringConversion::ToString(FUSStringBuilder& builder, const Int32List& values)
{
if (values.empty()) return;
if (!builder.empty()) SPACE;
Int32List::const_iterator itV = values.begin();
builder.append(*itV);
for (; itV != values.end(); ++itV) { SPACE; VAL(*itV); }
}
void FUStringConversion::ToString(FUSStringBuilder& builder, const UInt32List& values)
{
if (values.empty()) return;
if (!builder.empty()) SPACE;
UInt32List::const_iterator itV = values.begin();
builder.append(*itV);
for (; itV != values.end(); ++itV) { SPACE; VAL(*itV); }
}
#endif // HAS_VECTORTYPES
// Convert a fstring to a list of matrices
#ifdef UNICODE
void FUStringConversion::ToMatrixList(const fchar* value, FMMatrix44List& array, float lengthFactor)
{
if (value != NULL && *value != 0)
{
size_t length = array.size();
for (size_t count = 0; count < length && *value != 0; ++count)
{
ToMatrix(&value, array[count], lengthFactor);
}
while (*value != 0)
{
FMMatrix44List::iterator it = array.insert(array.end(), FMMatrix44::Identity);
ToMatrix(&value, *it, lengthFactor);
}
}
}
#endif // UNICODE
void FUStringConversion::ToMatrixList(const char* value, FMMatrix44List& array, float lengthFactor)
{
if (value != NULL && *value != 0)
{
size_t length = array.size();
for (size_t count = 0; count < length && *value != 0; ++count)
{
ToMatrix(&value, array[count], lengthFactor);
}
while (*value != 0)
{
FMMatrix44List::iterator it = array.insert(array.end(), FMMatrix44::Identity);
ToMatrix(&value, *it, lengthFactor);
}
}
}
#ifdef UNICODE
void FUStringConversion::ToPointList(const fchar* value, FMVector3List& array, float lengthFactor)
{
if (value != NULL && *value != 0)
{
size_t length = array.size();
for (size_t count = 0; count < length && *value != 0; ++count)
{
array[count] = ToPoint(&value, lengthFactor);
}
while (*value != 0) array.push_back(ToPoint(&value, lengthFactor));
}
}
#endif // UNICODE
void FUStringConversion::ToPointList(const char* value, FMVector3List& array, float lengthFactor)
{
if (value != NULL && *value != 0)
{
size_t length = array.size();
for (size_t count = 0; count < length && *value != 0; ++count)
{
array[count] = ToPoint(&value, lengthFactor);
}
while (*value != 0) array.push_back(ToPoint(&value, lengthFactor));
}
}
#endif // HAS_VECTORTYPES
// Parasitic: Common string operators
#ifdef UNICODE
fstring operator+(const fstring& sz1, int32 i)
{
globalBuilder.set(sz1);
globalBuilder.append(i);
return globalBuilder.ToString();
}
#endif // UNICODE
string operator+(const string& sz1, int32 i)
{
globalSBuilder.set(sz1);
globalSBuilder.append(i);
return globalSBuilder.ToString();
}
// Parasitic: empty string constants
const string emptyString("");
const fstring emptyFString(FC(""));

View File

@@ -0,0 +1,318 @@
/*
Copyright (C) 2005-2006 Feeling Software Inc.
MIT License: http://www.opensource.org/licenses/mit-license.php
*/
/*
Based on the FS Import classes:
Copyright (C) 2005-2006 Feeling Software Inc
Copyright (C) 2005-2006 Autodesk Media Entertainment
MIT License: http://www.opensource.org/licenses/mit-license.php
*/
/**
@file FUStringConversion.h
This file contains the FUStringConversion class.
*/
#ifndef _FCU_STRING_CONVERSION_
#define _FCU_STRING_CONVERSION_
class FUDateTime;
/**
Common string conversion.
This static class contains the parsing function for Unicode and 8-bit/UTF-8
strings into common data types: integers, booleans, floating-point values,
vectors, matrices, date-time, etc. and dynamically-sized array of these types.
This class can also convert common data types into an 8-bit or a Unicode string and
it contains conversion functions to convert string between 8-bit and Unicode.
@ingroup FUtils
*/
class FCOLLADA_EXPORT FUStringConversion
{
private: FUStringConversion() {}
public:
/** Converts a 8-bit string to a Unicode string.
@param value The 8-bit string.
@return The converted Unicode string. */
static fstring ToFString(const char* value);
inline static fstring ToFString(const string& value) { return ToFString(value.c_str()); } /**< See above. */
/** Converts an Unicode string to a 8-bit string.
@param value The Unicode string.
@return The converted 8-bit string. */
static string ToString(const fchar* value);
inline static string ToString(const fstring& value) { return ToString(value.c_str()); } /**< See above. */
/** Parses a string into a boolean value.
@param value The string.
@return The parsed boolean value. */
static bool ToBoolean(const char* value);
inline static bool ToBoolean(const string& value) { return ToBoolean(value.c_str()); } /**< See above. */
#ifdef UNICODE
static bool ToBoolean(const fchar* value); /**< See above. */
inline static bool ToBoolean(const fstring& value) { return ToBoolean(value.c_str()); } /**< See above. */
#endif
/** Parses a string into a floating-point value.
@param value The string. For the string pointer versions of this function,
the pointer will point to the last processed characters after the parsing.
@return The parsed floating-point value. */
static float ToFloat(const char** value);
inline static float ToFloat(const char* value) { return ToFloat(&value); } /**< See above. */
inline static float ToFloat(const string& value) { return ToFloat(value.c_str()); } /**< See above. */
#ifdef UNICODE
static float ToFloat(const fchar** value); /**< See above. */
inline static float ToFloat(const fstring& value) { return ToFloat(value.c_str()); } /**< See above. */
inline static float ToFloat(const fchar* value) { return ToFloat(&value); } /**< See above. */
#endif
/** Parses a string into a signed integer.
@param value The string. For the string pointer versions of this function,
the pointer will point to the last processed characters after the parsing.
@return The parsed signed integer. */
static int32 ToInt32(const char** value);
inline static int32 ToInt32(const char* value) { return ToInt32(&value); } /**< See above. */
inline static int32 ToInt32(const string& value) { return ToInt32(value.c_str()); } /**< See above. */
#ifdef UNICODE
static int32 ToInt32(const fchar** value); /**< See above. */
inline static int32 ToInt32(const fchar* value) { return ToInt32(&value); } /**< See above. */
inline static int32 ToInt32(const fstring& value) { return ToInt32(value.c_str()); } /**< See above. */
#endif
/** Parses a string into an unsigned integer.
@param value The string. For the string pointer versions of this function,
the pointer will point to the last processed characters after the parsing.
@return The parsed unsigned integer. */
static uint32 ToUInt32(const char** value);
inline static uint32 ToUInt32(const char* value) { return ToUInt32(&value); } /**< See above. */
inline static uint32 ToUInt32(const string& value) { return ToUInt32(value.c_str()); } /**< See above. */
#ifdef UNICODE
static uint32 ToUInt32(const fchar** value); /**< See above. */
inline static uint32 ToUInt32(const fchar* value) { return ToUInt32(&value); } /**< See above. */
inline static uint32 ToUInt32(const fstring& value) { return ToUInt32(value.c_str()); } /**< See above. */
#endif
/** Parses a string into an unsigned integer. The string is assumed to have
an unsigned integer in hexadecimal format.
@param value The string. For the string pointer versions of this function,
the pointer will point to the last processed characters after the parsing.
@param count The maxmimum number of characters to parse.
For example, a count of 2 will read in an 8-bit character.
@return The parsed unsigned integer. */
static uint32 HexToUInt32(const char** value, uint32 count=UINT_MAX);
inline static uint32 HexToUInt32(const char* value, uint32 count=UINT_MAX) { return HexToUInt32(&value, count); } /**< See above. */
inline static uint32 HexToUInt32(const string& value, uint32 count=UINT_MAX) { return HexToUInt32(value.c_str(), count); } /**< See above. */
#ifdef UNICODE
static uint32 HexToUInt32(const fchar** value, uint32 count=UINT_MAX); /**< See above. */
inline static uint32 HexToUInt32(const fchar* value, uint32 count=UINT_MAX) { return HexToUInt32(&value, count); } /**< See above. */
inline static uint32 HexToUInt32(const fstring& value, uint32 count=UINT_MAX) { return HexToUInt32(value.c_str(), count); } /**< See above. */
#endif
/** Parses a string into a 3D vector.
@param value The string. For the string pointer versions of this function,
the pointer will point to the last processed characters after the parsing.
@param lengthFactor An optional factor that will scale the 3D vector.
@return The parsed 3D vector. */
static FMVector3 ToPoint(const char** value, float lengthFactor=1.0f);
inline static FMVector3 ToPoint(const char* value, float lengthFactor=1.0f) { return ToPoint(&value, lengthFactor); } /**< See above. */
inline static FMVector3 ToPoint(const string& value, float lengthFactor=1.0f) { return ToPoint(value.c_str(), lengthFactor); } /**< See above. */
#ifdef UNICODE
static FMVector3 ToPoint(const fchar** value, float lengthFactor=1.0f); /**< See above. */
inline static FMVector3 ToPoint(const fchar* value, float lengthFactor=1.0f) { return ToPoint(&value, lengthFactor); } /**< See above. */
inline static FMVector3 ToPoint(const fstring& value, float lengthFactor=1.0f) { return ToPoint(value.c_str(), lengthFactor); } /**< See above. */
#endif
/** Parses a string into a 4x4 matrix.
@param value The string. For the string pointer versions of this function,
the pointer will point to the last processed characters after the parsing.
@param mx The matrix to be filled in.
@param lengthFactor An optional factor that will scale the translation column
of the matrix. */
static void ToMatrix(const char** value, FMMatrix44& mx, float lengthFactor=1.0f);
inline static void ToMatrix(const char* value, FMMatrix44& mx, float lengthFactor=1.0f) { return ToMatrix(&value, mx, lengthFactor); } /**< See above. */
inline static void ToMatrix(const string& value, FMMatrix44& mx, float lengthFactor=1.0f) { return ToMatrix(value.c_str(), mx, lengthFactor); } /**< See above. */
#ifdef UNICODE
static void ToMatrix(const fchar** value, FMMatrix44& mx, float lengthFactor=1.0f); /**< See above. */
inline static void ToMatrix(const fchar* value, FMMatrix44& mx, float lengthFactor=1.0f) { return ToMatrix(&value, mx, lengthFactor); } /**< See above. */
inline static void ToMatrix(const fstring& value, FMMatrix44& mx, float lengthFactor=1.0f) { return ToMatrix(value.c_str(), mx, lengthFactor); } /**< See above. */
#endif
/** Parses a string into a datetime structure.
@param value The string.
@param dateTime The datetime structure to fill in. */
static void ToDateTime(const char* value, FUDateTime& dateTime);
inline static void ToDateTime(const string& value, FUDateTime& dateTime) { return ToDateTime(value.c_str(), dateTime); } /**< See above. */
#ifdef UNICODE
static void ToDateTime(const fchar* value, FUDateTime& dateTime); /**< See above. */
inline static void ToDateTime(const fstring& value, FUDateTime& dateTime) { return ToDateTime(value.c_str(), dateTime); } /**< See above. */
#endif
#ifdef HAS_VECTORTYPES
/** Splits a string into multiple substrings.
The separator used here are the white-spaces.
@param value The string.
@param array A list of strings that will be filled in. */
static void ToFStringList(const fstring& value, FStringList& array);
static void ToStringList(const string& value, StringList& array); /**< See above. */
#ifdef UNICODE
static void ToStringList(const fchar* value, StringList& array); /**< See above. */
inline static void ToStringList(const fstring& value, StringList& array) { return ToStringList(value.c_str(), array); } /**< See above. */
#endif
/** Parses a string into a list of floating point values.
@param value The string.
@param array The list of floating point values to fill in. */
static void ToFloatList(const char* value, FloatList& array);
inline static void ToFloatList(const string& value, FloatList& array) { return ToFloatList(value.c_str(), array); } /**< See above. */
#ifdef UNICODE
static void ToFloatList(const fchar* value, FloatList& array); /**< See above. */
inline static void ToFloatList(const fstring& value, FloatList& array) { return ToFloatList(value.c_str(), array); } /**< See above. */
#endif
/** Parses a string into a list of signed integers.
@param value The string.
@param array The list of signed integers to fill in. */
static void ToInt32List(const char* value, Int32List& array);
inline static void ToInt32List(const string& value, Int32List& array) { return ToInt32List(value.c_str(), array); } /**< See above. */
#ifdef UNICODE
static void ToInt32List(const fchar* value, Int32List& array); /**< See above. */
inline static void ToInt32List(const fstring& value, Int32List& array) { return ToInt32List(value.c_str(), array); } /**< See above. */
#endif
/** Parses a string into a list of unsigned integers.
@param value The string.
@param array The list of unsigned integers to fill in. */
static void ToUInt32List(const char* value, UInt32List& array);
inline static void ToUInt32List(const string& value, UInt32List& array) { return ToUInt32List(value.c_str(), array); } /**< See above. */
#ifdef UNICODE
static void ToUInt32List(const fchar* value, UInt32List& array); /**< See above. */
inline static void ToUInt32List(const fstring& value, UInt32List& array) { return ToUInt32List(value.c_str(), array); } /**< See above. */
#endif
/** Parses a string containing interleaved floating-point values.
The values will be stored in multiple, independent lists.
@param value The string containing interleaved floating-point values.
@param arrays The lists of floating-point values to fill in. */
static void ToInterleavedFloatList(const char* value, const vector<FloatList*>& arrays);
inline static void ToInterleavedFloatList(const string& value, const vector<FloatList*>& arrays) { return ToInterleavedFloatList(value.c_str(), arrays); } /**< See above. */
#ifdef UNICODE
static void ToInterleavedFloatList(const fchar* value, const vector<FloatList*>& arrays); /**< See above. */
inline static void ToInterleavedFloatList(const fstring& value, const vector<FloatList*>& arrays) { return ToInterleavedFloatList(value.c_str(), arrays); } /**< See above. */
#endif
/** Parses a string into a list of matrices.
@param value The string.
@param array The list of matrices to fill in.
@param lengthFactor An optional factor that will scale the translation column
of the matrices. */
static void ToMatrixList(const char* value, FMMatrix44List& array, float lengthFactor=1.0f);
inline static void ToMatrixList(const string& value, FMMatrix44List& array, float lengthFactor=1.0f) { return ToMatrixList(value.c_str(), array, lengthFactor); } /**< See above. */
#ifdef UNICODE
static void ToMatrixList(const fchar* value, FMMatrix44List& array, float lengthFactor=1.0f); /**< See above. */
inline static void ToMatrixList(const fstring& value, FMMatrix44List& array, float lengthFactor=1.0f) { return ToMatrixList(value.c_str(), array, lengthFactor); } /**< See above. */
#endif
/** Parses a string into a list of 3D points.
@param value The string.
@param array The list of 3D points to fill in.
@param lengthFactor An optional factor that will scale the points. */
static void ToPointList(const char* value, FMVector3List& array, float lengthFactor=1.0f);
inline static void ToPointList(const string& value, FMVector3List& array, float lengthFactor=1.0f) { return ToPointList(value.c_str(), array, lengthFactor); } /**< See above. */
#ifdef UNICODE
static void ToPointList(const fchar* value, FMVector3List& array, float lengthFactor=1.0f); /**< See above. */
inline static void ToPointList(const fstring& value, FMVector3List& array, float lengthFactor=1.0f) { return ToPointList(value.c_str(), array, lengthFactor); } /**< See above. */
#endif
/** Converts a list of floating-point values into a string.
@param builder The string builder that will contain the list of values.
This string builder is not cleared of its contents and a space
character will be added if it is not empty.
@param values The list of floating-point values to convert.
@param lengthFactor An optional factor that will scale all the
floating-point values. */
static void ToString(FUSStringBuilder& builder, const FloatList& values, float lengthFactor=1.0f);
/** Converts a list of signed integers into a string.
@param builder The string builder that will contain the list of values.
This string builder is not cleared of its contents and a space
character will be added if it is not empty.
@param values The list of signed integers to convert. */
static void ToString(FUSStringBuilder& builder, const Int32List& values);
/** Converts a list of unsigned integers into a string.
@param builder The string builder that will contain the list of values.
This string builder is not cleared of its contents and a space
character will be added if it is not empty.
@param values The list of unsigned integers to convert. */
static void ToString(FUSStringBuilder& builder, const UInt32List& values);
#endif // HAS_VECTORTYPES
/** Converts a 4D vector into a string.
@param p The 4D vector to convert.
@param lengthFactor An optional factor that will scale the vector.
@return The string containing the converted vector. */
static string ToString(const FMVector4& p, float lengthFactor=1.0f);
/** Converts a matrix into a string.
@param value The matrix to convert.
@param lengthFactor An optional factor that will scale the translation
column of the matrix.
@return The string containing the converted matrix. */
static string ToString(const FMMatrix44& value, float lengthFactor=1.0f);
static fstring ToFString(const FMMatrix44& value, float lengthFactor=1.0f); /**< See above. */
/** Converts a 3D vector into a string.
@param value The 3D vector to convert.
@param lengthFactor An optional factor that will scale the vector.
@return The string containing the converted vector. */
static string ToString(const FMVector3& value, float lengthFactor=1.0f);
static fstring ToFString(const FMVector3& value, float lengthFactor=1.0f); /**< See above. */
/** Converts a datetime structure into a string.
@param dateTime The datetime structure to convert.
@return The string containing the converted datetime structure. */
static string ToString(const FUDateTime& dateTime);
static fstring ToFString(const FUDateTime& dateTime); /**< See above. */
/** Converts a primitive value into a string.
This function is templatized to use the global string builders to
convert most primitive value types, such as signed integers,
unsigned integers and single floating-point values, into strings.
@see FUStringBuilderT
@param value A primitive value.
@return The string containing the converted primitive value. */
template <typename T> static string ToString(const T& value) { globalSBuilder.set(value); return globalSBuilder.ToString(); }
template <typename T> static fstring ToFString(const T& value) { globalBuilder.set(value); return globalBuilder.ToString(); } /**< See above. */
/** Converts a matrix into a string.
@param builder The string builder that will contain the matrix.
This string builder is not cleared of its contents.
@param value The matrix to convert.
@param lengthFactor An optional factor that will scale the translation
column of the matrix. */
static void ToString(FUSStringBuilder& builder, const FMMatrix44& value, float lengthFactor=1.0f);
static void ToFString(FUStringBuilder& builder, const FMMatrix44& value, float lengthFactor=1.0f); /**< See above. */
/** Converts a 3D vector into a string.
@param builder The string builder that will contain the 3D vector.
This string builder is not cleared of its contents.
@param value The 3D vector to convert.
@param lengthFactor An optional factor that will scale the vector. */
static void ToString(FUSStringBuilder& builder, const FMVector3& value, float lengthFactor=1.0f);
static void ToFString(FUStringBuilder& builder, const FMVector3& value, float lengthFactor=1.0f); /**< See above. */
/** Converts a 4D vector into a string.
@param builder The string builder that will contain the 4D vector.
This string builder is not cleared of its contents.
@param p The 4D vector to convert.
@param lengthFactor An optional factor that will scale the vector. */
static void ToString(FUSStringBuilder& builder, const FMVector4& p, float lengthFactor=1.0f);
};
#endif // _FCU_STRING_CONVERSION_

View File

@@ -0,0 +1,83 @@
/*
Copyright (C) 2005-2006 Feeling Software Inc.
MIT License: http://www.opensource.org/licenses/mit-license.php
*/
/**
@file FUUniqueStringMap.h
This file contains the FUUniqueStringMapT template.
*/
#ifndef _FU_UNIQUE_ID_MAP_H_
#define _FU_UNIQUE_ID_MAP_H_
/**
A set of unique strings.
This class adds three functions to the STL map in order to
keep the strings inside unique: AddUniqueString, Exists and Erase.
@ingroup FUtils
*/
template <typename STRING_BUILDER>
class FUUniqueStringMapT : map<typename STRING_BUILDER::String, void*>
{
private:
typedef map<typename STRING_BUILDER::String, void*> Super;
public:
/** Adds a string to the map.
If the string isn't unique, it will be modified in order to make it unique.
@param wantedStr The string to add. This reference will be directly
modified to hold the actual unique string added to the map. */
void AddUniqueString(typename STRING_BUILDER::String& wantedStr);
/** Retrieves whether a given string is contained within the map.
@param str The string. */
bool Exists(const typename STRING_BUILDER::String& str) const;
/** Erases a string from the map.
@param str A string contained within the map. */
void Erase(const typename STRING_BUILDER::String& str);
};
typedef FUUniqueStringMapT<FUSStringBuilder> FUSUniqueStringMap; /**< A map of unique UTF-8 strings. */
typedef FUUniqueStringMapT<FUStringBuilder> FUUniqueStringMap; /**< A map of unique Unicode strings. */
template <typename Builder>
void FUUniqueStringMapT<Builder>::AddUniqueString(typename Builder::String& wantedStr)
{
if (Exists(wantedStr))
{
// Attempt to generate a new string by appending an increasing counter.
uint32 counter = 2;
static const maxCounter = 256;
Builder buffer;
buffer.reserve(wantedStr.length() + 5);
do
{
buffer.set(wantedStr);
buffer.append(counter);
} while (counter++ < maxCounter && Exists(buffer.ToString()));
// Hopefully, this is now unique.
wantedStr = buffer.ToString();
}
insert(Super::value_type(wantedStr, NULL));
}
template <typename Builder>
bool FUUniqueStringMapT<Builder>::Exists(const typename Builder::String& str) const
{
const_iterator it = find(str);
return it != end();
}
template <typename Builder>
void FUUniqueStringMapT<Builder>::Erase(const typename Builder::String& str)
{
iterator it = find(str);
if (it != end()) erase(it);
}
#endif // _FU_UNIQUE_ID_MAP_H_

View File

@@ -0,0 +1,23 @@
/*
Copyright (C) 2005-2006 Feeling Software Inc.
MIT License: http://www.opensource.org/licenses/mit-license.php
*/
/*
Based on the FS Import classes:
Copyright (C) 2005-2006 Feeling Software Inc
Copyright (C) 2005-2006 Autodesk Media Entertainment
MIT License: http://www.opensource.org/licenses/mit-license.php
*/
#ifndef _FU_URI_H_
#define _FU_URI_H_
class FUUri
{
public:
fstring prefix;
string suffix;
};
#endif // _FU_URI_H_

View File

@@ -0,0 +1,29 @@
/*
Copyright (C) 2005-2006 Feeling Software Inc.
MIT License: http://www.opensource.org/licenses/mit-license.php
*/
/*
Based on the FS Import classes:
Copyright (C) 2005-2006 Feeling Software Inc
Copyright (C) 2005-2006 Autodesk Media Entertainment
MIT License: http://www.opensource.org/licenses/mit-license.php
*/
#ifndef _FU_XML_NODE_ID_PAIR_H_
#define _FU_XML_NODE_ID_PAIR_H_
#ifdef HAS_LIBXML
class FUXmlNodeIdPair
{
public:
FUCrc32::crc32 id;
xmlNode* node;
};
typedef vector<FUXmlNodeIdPair> FUXmlNodeIdPairList;
#endif // HAS_LIBXML
#endif // _FU_XML_NODE_ID_PAIR_H_

View File

@@ -0,0 +1,178 @@
/*
Copyright (C) 2005-2006 Feeling Software Inc.
MIT License: http://www.opensource.org/licenses/mit-license.php
*/
/*
Based on the FS Import classes:
Copyright (C) 2005-2006 Feeling Software Inc
Copyright (C) 2005-2006 Autodesk Media Entertainment
MIT License: http://www.opensource.org/licenses/mit-license.php
*/
#include "StdAfx.h"
#include "FUtils/FUXmlParser.h"
#define xmlT(a) (const xmlChar*) (a)
namespace FUXmlParser
{
// Returns the first child node of a given type
xmlNode* FindChildByType(xmlNode* parent, const char* type)
{
if (parent != NULL)
{
for (xmlNode* child = parent->children; child != NULL; child = child->next)
{
if (child->type == XML_ELEMENT_NODE)
{
if (IsEquivalent(child->name, type)) return child;
}
}
}
return NULL;
}
// return the first child node of a given name
xmlNode* FindChildByName(xmlNode* parent, const char* name)
{
if (parent != NULL)
{
for (xmlNode* child = parent->children; child != NULL; child = child->next)
{
if (child->type == XML_ELEMENT_NODE)
{
string str_name = ReadNodeProperty(child, "name");
if (str_name == name) return child;
}
}
}
return NULL;
}
// return the first child node of a given property value
xmlNode* FindChildByProperty(xmlNode* parent, const char* prop, const char* val )
{
if (parent != NULL)
{
for (xmlNode* child = parent->children; child != NULL; child = child->next)
{
string str_pop = ReadNodeProperty(child, prop);
if (str_pop == val) return child;
}
}
return NULL;
}
// return the first node in list of a given property
xmlNode* FindNodeInListByProperty(xmlNodeList list, const char* property, const char* prop)
{
for (xmlNodeList::iterator it = list.begin(); it != list.end(); ++it)
{
xmlNode* element = *it;
string str_prop = ReadNodeProperty(element, property);
if (str_prop == prop) return element;
}
return NULL;
}
// Retrieves all the child nodes of a given type
void FindChildrenByType(xmlNode* parent, const char* type, xmlNodeList& nodes)
{
if (parent != NULL)
{
for (xmlNode* child = parent->children; child != NULL; child = child->next)
{
if (child->type == XML_ELEMENT_NODE)
{
if (IsEquivalent(child->name, type)) nodes.push_back(child);
}
}
}
}
// Returns whether the given node has the given property
bool HasNodeProperty(xmlNode* node, const char* property)
{
xmlAttr* attribute = xmlHasProp(node, xmlT(property));
return attribute != NULL;
}
// Returns the string value of a node's property
string ReadNodeProperty(xmlNode* node, const char* property)
{
string ret;
if (node != NULL && property != NULL)
{
xmlChar* data = xmlGetProp(node, xmlT(property));
if (data != NULL) ret = (const char*) data;
xmlFree(data);
}
// Process the string for special characters
XmlToString(ret);
return ret;
}
// Returns the CRC value of a node's property
FUCrc32::crc32 ReadNodePropertyCRC(xmlNode* node, const char* property)
{
FUCrc32::crc32 ret = 0;
if (node != NULL && property != NULL)
{
xmlChar* data = xmlGetProp(node, xmlT(property));
if (data != NULL) ret = FUCrc32::CRC32((const char*) data);
xmlFree(data);
}
return ret;
}
// Returns the text content directly attached to a node
const char* ReadNodeContentDirect(xmlNode* node)
{
if (node == NULL || node->children == NULL
|| node->children->type != XML_TEXT_NODE || node->children->content == NULL) return "";
return (const char*) node->children->content;
}
// Returns the inner text content of a node
string ReadNodeContentFull(xmlNode* node)
{
string ret;
if (node != NULL)
{
xmlChar* content = xmlNodeGetContent(node);
ret = (const char*) content;
xmlFree(content);
}
return ret;
}
// Convert a XML string to a text string: handles the '%' character
void XmlToString(string& s)
{
if (s.find('%') == string::npos) return;
// Replace all the '%XX' characters by the equivalent hex value
const char* original = s.c_str();
uint32 length = (uint32) s.length();
char* copy = new char[length],* p = copy;
for (uint32 i = 0; i < length; ++i, ++p)
{
char c = original[i];
if (c != '%' || i >= length - 2) *p = c;
else
{
char* dummy;
p[0] = original[i + 1]; p[1] = original[i + 2]; p[2] = 0;
uint32 v = strtoul(p, &dummy, 16);
*p = (char) v;
i += 2;
}
}
*p = 0;
s = copy;
}
};

View File

@@ -0,0 +1,41 @@
/*
Copyright (C) 2005-2006 Feeling Software Inc.
MIT License: http://www.opensource.org/licenses/mit-license.php
*/
/*
Based on the FS Import classes:
Copyright (C) 2005-2006 Feeling Software Inc
Copyright (C) 2005-2006 Autodesk Media Entertainment
MIT License: http://www.opensource.org/licenses/mit-license.php
*/
#ifndef _FU_XML_PARSER_H_
#define _FU_XML_PARSER_H_
#ifdef HAS_LIBXML
namespace FUXmlParser
{
// Retrieve specific child nodes
FCOLLADA_EXPORT xmlNode* FindChildByType(xmlNode* parent, const char* type);
FCOLLADA_EXPORT xmlNode* FindChildByName(xmlNode* parent, const char* name);
FCOLLADA_EXPORT void FindChildrenByType(xmlNode* parent, const char* type, xmlNodeList& nodes);
FCOLLADA_EXPORT xmlNode* FindChildByProperty(xmlNode* parent, const char* prop, const char* val );
FCOLLADA_EXPORT xmlNode* FindNodeInListByProperty(xmlNodeList list, const char* property, const char* prop);
// Retrieve node property and content
FCOLLADA_EXPORT bool HasNodeProperty(xmlNode* node, const char* property);
FCOLLADA_EXPORT string ReadNodeProperty(xmlNode* node, const char* property);
FCOLLADA_EXPORT FUCrc32::crc32 ReadNodePropertyCRC(xmlNode* node, const char* property);
FCOLLADA_EXPORT const char* ReadNodeContentDirect(xmlNode* node);
FCOLLADA_EXPORT string ReadNodeContentFull(xmlNode* node);
// Process values
FCOLLADA_EXPORT void XmlToString(string& s);
};
inline bool IsEquivalent(const xmlChar* sz1, const char* sz2) { return IsEquivalent((const char*) sz1, sz2); }
#endif // HAS_LIBXML
#endif //_FU_XML_PARSER_H_

View File

@@ -0,0 +1,137 @@
/*
Copyright (C) 2005-2006 Feeling Software Inc.
MIT License: http://www.opensource.org/licenses/mit-license.php
*/
#include "StdAfx.h"
#include "FUtils/FUXmlWriter.h"
#include "FUtils/FUXmlParser.h"
#include "FUtils/FUStringConversion.h"
#define xcT(text) (const xmlChar*) (text)
namespace FUXmlWriter
{
// Create a new xml tree node
xmlNode* CreateNode(const char* name)
{
return xmlNewNode(NULL, xcT(name));
}
// Create a new xml tree child node, parented to the given xml tree node
void AddChild(xmlNode* parent, xmlNode* child)
{
xmlAddChild(parent, child);
}
xmlNode* AddChild(xmlNode* parent, const char* name)
{
return (parent != NULL) ? xmlNewChild(parent, NULL, xcT(name), NULL) : NULL;
}
xmlNode* AddChild(xmlNode* parent, const char* name, const char* content)
{
if (content != NULL && *content == 0) content = NULL;
return (parent != NULL) ? xmlNewChild(parent, NULL, xcT(name), xcT(content)) : NULL;
}
#ifdef UNICODE
xmlNode* AddChild(xmlNode* parent, const char* name, const fstring& content)
{
string s = FUStringConversion::ToString(content);
return AddChild(parent, name, !s.empty() ? s.c_str() : NULL);
}
#endif
xmlNode* AddChildOnce(xmlNode* parent, const char* name, const char* content)
{
xmlNode* node = NULL;
if (parent != NULL)
{
node = FUXmlParser::FindChildByType(parent, name);
if (node == NULL) node = AddChild(parent, name, (content == NULL || *content == 0) ? NULL : content);
}
return node;
}
// Create/Append a new xml tree node, as a sibling to a given xml tree node
void AddSibling(xmlNode* sibling, xmlNode* dangling)
{
xmlAddSibling(sibling, dangling);
}
xmlNode* AddSibling(xmlNode* node, const char* name)
{
xmlNode* n = CreateNode(name);
AddSibling(node, n);
return n;
}
void AddContent(xmlNode* node, const char* content)
{
if (node != NULL)
{
xmlNodeAddContent(node, xcT(content));
}
}
#ifdef UNICODE
void AddContent(xmlNode* node, const fstring& content)
{
string s = FUStringConversion::ToString(content);
AddContent(node, s.c_str());
}
#endif
void AddAttribute(xmlNode* node, const char* attributeName, const char* value)
{
if (node != NULL)
{
xmlNewProp(node, xcT(attributeName), xcT(value));
}
}
#ifdef UNICODE
void AddAttribute(xmlNode* node, const char* attributeName, const fstring& attributeValue)
{
string s = FUStringConversion::ToString(attributeValue);
AddAttribute(node, attributeName, s.c_str());
}
#endif
// Insert a child, respecting lexical ordering
void AddChildSorted(xmlNode* parent, xmlNode* child)
{
// Do an insertion sort in alphabetical order of the element names.
// Walk backward from the last child, to make sure that
// the chronological ordering of elements of the same type is respected.
//
for (xmlNode* p = xmlGetLastChild(parent); p != NULL; p = p->prev)
{
if (p->type != XML_ELEMENT_NODE) continue;
if (strcmp((const char*) p->name, (const char*) child->name) <= 0)
{
xmlAddNextSibling(p, child);
return;
}
}
// Add to the top of the list.
if (parent->children && parent->children->type == XML_ELEMENT_NODE)
{
xmlAddPrevSibling(parent->children, child);
}
else
{
AddChild(parent, child);
}
}
xmlNode* AddChildSorted(xmlNode* parent, const char* name, const char* content)
{
xmlNode* node = CreateNode(name);
if (content != NULL && *content != 0) xmlNodeAddContent(node, xcT(content));
AddChildSorted(parent, node);
return node;
}
};

View File

@@ -0,0 +1,157 @@
/*
Copyright (C) 2005-2006 Feeling Software Inc.
MIT License: http://www.opensource.org/licenses/mit-license.php
*/
/**
@file FUXmlWriter.h
This file defines the FUXmlWriter namespace.
*/
#ifndef _FU_XML_WRITER_H_
#define _FU_XML_WRITER_H_
#ifdef HAS_LIBXML
/**
Common XML writing utility functions.
Based on top of the LibXML2 library.
This whole namespace is considered external and should only be used
by the FCollada library.
@ingroup FUtils
*/
namespace FUXmlWriter
{
/** Creates a dangling XML tree node.
@param name The name of the new XML tree node.
@return The new XML tree node. This pointer should never be NULL. */
FCOLLADA_EXPORT xmlNode* CreateNode(const char* name);
/** Appends a dangling XML tree child node to a XML tree node.
The child XML tree node is added at the end of the parent XML tree node children list.
@param parent The parent XML tree node.
@param child The child XML tree node. */
FCOLLADA_EXPORT void AddChild(xmlNode* parent, xmlNode* child);
/** Creates a child XML tree node within a XML tree node.
The child XML tree node is added at the end of the parent XML tree node children list.
@param parent The parent XML tree node.
@param name The name of the new child node.
@return The new child XML tree node. */
FCOLLADA_EXPORT xmlNode* AddChild(xmlNode* parent, const char* name);
/** Creates a child XML tree node within a XML tree node.
The child XML tree node is added at the end of the parent XML tree node children list.
The given content string is added to the returned child XML tree node.
@param parent The parent XML tree node.
@param name The name of the new child XML tree node.
@param content The content to add to the new child XML tree node.
@return The new child XML tree node. */
FCOLLADA_EXPORT xmlNode* AddChild(xmlNode* parent, const char* name, const char* content);
#ifdef UNICODE
FCOLLADA_EXPORT xmlNode* AddChild(xmlNode* parent, const char* name, const fstring& content); /**< See above. */
#endif
inline xmlNode* AddChild(xmlNode* parent, const char* name, const string& content) { return AddChild(parent, name, content.c_str()); } /**< See above. */
inline xmlNode* AddChild(xmlNode* parent, const char* name, FUSStringBuilder& content) { return AddChild(parent, name, content.ToCharPtr()); } /**< See above. */
/** Creates a child XML tree node within a XML tree node.
The child XML tree node is added at the end of the parent XML tree node children list.
The given content value is added, in string-form, to the returned child XML tree node.
@param parent The parent XML tree node.
@param name The name of the new child XML tree node.
@param value A primitive value. This value is stringified and added, as content, to the new child XML tree node.
@return The new child XML tree node. */
template <typename T> inline xmlNode* AddChild(xmlNode* parent, const char* name, const T& value) { globalSBuilder.set(value); return AddChild(parent, name, globalSBuilder); }
/** Appends a dangling XML tree node as a sibling of a XML tree node.
Two sibling XML tree nodes have the same parent XML tree node.
The dangling XML tree node is added at the end of the parent XML tree node children list.
@param sibling The sibling XML tree node. It must have a valid parent XML tree node.
@param dangling The dangling XML tree node. */
FCOLLADA_EXPORT void AddSibling(xmlNode* sibling, xmlNode* dangling);
/** Creates a XML tree node as a sibling of a XML tree node.
Two sibling XML tree nodes have the same parent XML tree node.
The new XML tree node is added at the end of the parent XML tree node children list.
@param sibling The sibling XML tree node. It must have a valid parent XML tree node.
@param name The name of the new XML tree node.
@return The new sibling XML tree node. */
FCOLLADA_EXPORT xmlNode* AddSibling(xmlNode* sibling, const char* name);
/** Returns a child XML tree node within a XML tree node.
If the child XML tree node with the given name does not exists, it is created and
the given content is added to the new XML tree node.
@param parent The parent XML tree node.
@param name The name of the child XML tree node.
@param content The content to add to the child XML tree node, if it must be created.
@return The child XML tree node. */
FCOLLADA_EXPORT xmlNode* AddChildOnce(xmlNode* parent, const char* name, const char* content=NULL);
inline xmlNode* AddChildOnce(xmlNode* parent, const char* name, const string& content) { return AddChildOnce(parent, name, content.c_str()); } /**< See above. */
inline xmlNode* AddChildOnce(xmlNode* parent, const char* name, FUSStringBuilder& content) { return AddChildOnce(parent, name, content.ToCharPtr()); } /**< See above. */
/** Returns a child XML tree node within a XML tree node.
If the child XML tree node with the given name does not exists, it is created and
the given content is added to the new XML tree node.
@param parent The parent XML tree node.
@param name The name of the child XML tree node.
@param value A primitive value. If the child XML tree node must be created: this value is stringified and added as content.
@return The child XML tree node. */
template <typename T> inline xmlNode* AddChildOnce(xmlNode* parent, const char* name, const T& value) { globalSBuilder.set(value); return AddChildOnce(parent, name, globalSBuilder); }
/** Appends a content string to a XML tree node.
The content string is added at the end of the XML tree node's content, with no special characters added.
@param node The XML tree node.
@param content The content to add to the XML tree node. */
FCOLLADA_EXPORT void AddContent(xmlNode* node, const char* content);
#ifdef UNICODE
FCOLLADA_EXPORT void AddContent(xmlNode* node, const fstring& content); /**< See above. */
#endif
inline void AddContent(xmlNode* node, const string& content) { AddContent(node, content.c_str()); } /**< See above. */
inline void AddContent(xmlNode* node, FUSStringBuilder& content) { AddContent(node, content.ToCharPtr()); } /**< See above. */
/** Appends a primitive value to a XML tree node.
The primitive value is added at the end of the XML tree node's content, with no special characters added.
@param node The XML tree node.
@param value A primitive value. The value is stringified and added as content to the XML tree node. */
template <typename T> inline void AddContent(xmlNode* node, const T& value) { globalSBuilder.set(value); return AddContent(node, globalSBuilder); }
/** Appends a XML attribute to a XML tree node.
A XML attribute appears in the form @<node name="value"/@>.
@param node The XML tree node.
@param attributeName The name of the XML attribute.
@param attributeValue The value of the XML attribute. */
FCOLLADA_EXPORT void AddAttribute(xmlNode* node, const char* attributeName, const char* attributeValue);
#ifdef UNICODE
FCOLLADA_EXPORT void AddAttribute(xmlNode* node, const char* attributeName, const fstring& attributeValue); /**< See above. */
#endif
inline void AddAttribute(xmlNode* node, const char* attributeName, FUSStringBuilder& attributeValue) { AddAttribute(node, attributeName, attributeValue.ToCharPtr()); } /**< See above. */
inline void AddAttribute(xmlNode* node, const char* attributeName, const string& attributeValue) { AddAttribute(node, attributeName, attributeValue.c_str()); } /**< See above. */
/** Appends a XML attribute to a XML tree node.
A XML attribute appears in the form @<node name="value"@/@>.
@param node The XML tree node.
@param attributeName The name of the XML attribute.
@param attributeValue A primitive value. The value is stringified and set as the value of the XML attribute. */
template <typename T> inline void AddAttribute(xmlNode* node, const char* attributeName, const T& attributeValue) { globalSBuilder.set(attributeValue); AddAttribute(node, attributeName, globalSBuilder.ToCharPtr()); }
/** Appends a dangling XML tree node to a XML tree node
The dangling XML tree node is inserted in lexical order,
after all the sibling XML tree node with the same name.
@param parent The XML tree node onto which the dangling XML node tree is appended.
@param child The dangling XML tree node. */
FCOLLADA_EXPORT void AddChildSorted(xmlNode* parent, xmlNode* child);
/** Creates a new child XML tree node of a XML tree node
The new child XML tree node is inserted in lexical order,
after all the sibling XML tree node with the same name.
@param parent The XML tree node onto which the new XML node tree is created.
@param name The name of the new child XML tree node.
@param content A content string to be added to the child XML tree node.
@return The new child XML tree node. */
FCOLLADA_EXPORT xmlNode* AddChildSorted(xmlNode* parent, const char* name, const char* content=NULL);
};
#endif // HAS_LIBXML
#endif // _FU_XML_WRITER_H_

View File

@@ -0,0 +1,92 @@
/*
Copyright (C) 2005-2006 Feeling Software Inc.
MIT License: http://www.opensource.org/licenses/mit-license.php
*/
/*
Based on the FS Import classes:
Copyright (C) 2005-2006 Feeling Software Inc
Copyright (C) 2005-2006 Autodesk Media Entertainment
MIT License: http://www.opensource.org/licenses/mit-license.php
*/
/**
@file FUtils.h
Includes the common utilities classes and macros.
*/
/** @defgroup FUtils Utility Classes. */
#ifndef _F_UTILS_H_
#define _F_UTILS_H_
// STL
#ifdef _WIN32
#pragma warning(disable:4702)
#endif
#include <string>
#include <vector>
#include <set>
#include <xtree>
#include <map>
#include <algorithm>
#ifdef _WIN32
#pragma warning(default:4702)
#endif
// Pre-include the platform-specific macros and definitions
#include "FUtils/Platforms.h"
#include "FUtils/FUAssert.h"
// PLUG_CRT enforces CRT memory checks every 128 allocations
// and CRT memory leaks output
#if defined(_DEBUG) && defined(WIN32) && defined(MEMORY_DEBUG)
#define PLUG_CRT
#ifdef PLUG_CRT
#include <crtdbg.h>
#define DEBUG_CLIENTBLOCK new( _CLIENT_BLOCK, __FILE__, __LINE__)
#define new DEBUG_CLIENTBLOCK
#endif // PLUG_CRT
#endif // _DEBUG & WIN32 & MEMORY_DEBUG
// FMath
#define HAS_VECTORTYPES /**< Used by FCollada, this #define implies that we are including all the common dynamically-sized arrays. */
#include "FMath/FMath.h"
// LibXML
#ifndef NO_LIBXML
#define HAS_LIBXML /**< Used by FCollada, this #define implies that we are including LibXML functions in the library interface. */
#define LIBXML_STATIC /**< Used by LibXML, this #define implies that we are statically-linking the LibXML. */
#include <libxml/tree.h>
#else
typedef struct _xmlNode xmlNode;
#endif
typedef vector<struct _xmlNode*> xmlNodeList; /**< A dynamically-sized array of XML nodes. */
// SAFE_DELETE Macro set.
#define SAFE_DELETE(ptr) if ((ptr) != NULL) { delete (ptr); (ptr) = NULL; } /**< This macro safely deletes a pointer and sets the given pointer to NULL. */
#define SAFE_DELETE_ARRAY(ptr) if (ptr != NULL) { delete [] ptr; ptr = NULL; } /**< This macro safely deletes an heap array and sets the given pointer to NULL. */
#define SAFE_FREE(ptr) if (ptr != NULL) { free(ptr); ptr = NULL; } /**< This macro safely frees a memory block and sets the given pointer to NULL. */
#define SAFE_RELEASE(ptr) if ((ptr) != NULL) { (ptr)->Release(); (ptr) = NULL; } /**< This macro safely releases an interface and sets the given pointer to NULL. */
#define CLEAR_POINTER_VECTOR(a) { size_t l = (a).size(); for (size_t i = 0; i < l; ++i) SAFE_DELETE((a)[i]); (a).clear(); } /**< This macro deletes all the object pointers contained within a vector and clears it. */
#define CLEAR_POINTER_MAP(mapT, a) { for (mapT::iterator it = (a).begin(); it != (a).end(); ++it) SAFE_DELETE((*it).second); (a).clear(); } /**< This macro deletes all the object pointers contained within a map and clears it. */
// Conversion macros
#define UNUSED(a) /**< Removes a piece of code during the pre-process. This macro is useful for these pesky unused variable warnings. */
#ifdef _DEBUG
#define UNUSED_NDEBUG(a) a
#else
#define UNUSED_NDEBUG(a) /**< Removes a piece of debug code during the pre-process. This macro is useful for these pesky unused variable warnings. */
#endif // _DEBUG
#undef min
#define min(a, b) std::min(a, b) /**< Retrieves the smallest of two values. */
#undef max
#define max(a, b) std::max(a, b) /**< Retrieves the largest of two values. */
// More complex utility classes
#include "FUtils/FUString.h"
#include "FUtils/FUCrc32.h"
#include "FUtils/FUDebug.h"
#include "FUtils/FUStatus.h"
#endif // _F_UTILS_H_

View File

@@ -0,0 +1,33 @@
#!/usr/bin/make
# FUtils makefile for PS3
include ../../MakeDefs
LIBNAME = libfutils
prefix=..
INCPATH=$(prefix)/include
LIBPATH=$(prefix)/lib
PPU_INCDIRS=-I$(INCPATH) -I.. -I../LibXML/include
PPU_OPTIMIZE_LV= -O3 -funroll-loops
PPU_LIB_TARGET=$(LIBNAME).a
PPU_SRCS = \
FUCrc32.cpp \
FUDaeEnum.cpp \
FUDaeParser.cpp \
FUDaeWriter.cpp \
FUDateTime.cpp \
FUDebug.cpp \
FUFile.cpp \
FUFileManager.cpp \
FULogFile.cpp \
FUObject.cpp \
FUStringConversion.cpp \
FUXmlParser.cpp \
FUXmlWriter.cpp \
StdAfx.cpp
include ../../MakeRules

View File

@@ -0,0 +1,6 @@
INCLUDES = -I$(top_srcdir)/. -I/usr/include/libxml2
METASOURCES = AUTO
noinst_LIBRARIES = libFUtils.a
libFUtils_a_SOURCES = FUDaeParser.cpp FUStringConversion.cpp FUXmlParser.cpp \
FUDebug.cpp
noinst_HEADERS = FUDebug.h

View File

@@ -0,0 +1,181 @@
/*
Copyright (C) 2005-2006 Feeling Software Inc.
MIT License: http://www.opensource.org/licenses/mit-license.php
*/
/*
Based on the FS Import classes:
Copyright (C) 2005-2006 Feeling Software Inc
Copyright (C) 2005-2006 Autodesk Media Entertainment
MIT License: http://www.opensource.org/licenses/mit-license.php
*/
#ifndef _PLATFORMS_H_
#define _PLATFORMS_H_
#ifdef FCOLLADA_DLL
// Disable the "private member not available for export" warning,
// because I don't feel like writing interfaces
#pragma warning(disable:4251)
#ifdef FCOLLADA_INTERNAL
#define FCOLLADA_EXPORT __declspec(dllexport)
#else
#define FCOLLADA_EXPORT __declspec(dllimport)
#endif
#else
#define FCOLLADA_EXPORT
#endif
// Ensure that both UNICODE and _UNICODE are set.
#ifdef UNICODE
#ifndef _UNICODE
#define _UNICODE
#endif
#else
#ifdef _UNICODE
#define UNICODE
#endif
#endif
#include <math.h>
#ifdef WIN32
#pragma warning(disable:4702)
#include <windows.h>
#else
#ifdef MAC_TIGER
#include <ctype.h>
#include <wctype.h>
#else // MAC_TIGER
#if defined(LINUX)
#else // LINUX
#error "Unsupported platform."
#endif // LINUX
#endif // MAC_TIGER
#endif // WIN32
// Cross-platform type definitions
#ifdef WIN32
#define int8 char
typedef short int16;
typedef long int32;
typedef __int64 int64;
typedef unsigned char uint8;
typedef unsigned short uint16;
typedef unsigned long uint32;
typedef unsigned __int64 uint64;
#else // For LINUX and MAC_TIGER
#define int8 char
typedef short int16;
typedef long int32;
typedef long long int64;
typedef unsigned char uint8;
typedef unsigned short uint16;
typedef unsigned long uint32;
typedef unsigned long long uint64;
#endif
// Important functions that some OSes have missing!
#ifdef MAC_TIGER
inline char* strlower(char* str) { char* it = str; while (*it != 0) { *it = tolower(*it); ++it; } return str; }
inline wchar_t* wcslwr(wchar_t* str) { wchar_t* it = str; while (*it != 0) { *it = towlower(*it); ++it; } return str; }
#ifndef isinf
#define isinf __isinff
#endif
#define stricmp strcasecmp
#endif // MAC_TIGER
// Cross-platform needed functions
#ifdef WIN32
#define vsnprintf _vsnprintf
#define snprintf _snprintf
#define vsnwprintf _vsnwprintf
#define snwprintf _snwprintf
#define strlower _strlwr
#else // WIN32
#define vsnwprintf vswprintf
#define snwprintf swprintf
#endif // WIN32
// For Doxygen purposes, we stopped using the "using namespace std;" statement and use shortcuts instead.
/** A STL string. */
typedef std::string string;
/** A STL map. */
template <typename _Kty, typename _Ty>
class map : public std::map<_Kty, _Ty> {};
// fstring and character definition
#ifdef UNICODE
#ifdef WIN32
#include <tchar.h>
typedef TCHAR fchar;
typedef std::basic_string<fchar> fstring;
#define FC(a) __T(a)
#define fstrlen _tcslen
#define fstrcmp _tcscmp
#define fstricmp _tcsicmp
#define fstrncpy _tcsncpy
#define fstrrchr _tcsrchr
#define fstrlower _tcslwr
#define fsnprintf _sntprintf
#define fvsnprintf _vsntprintf
#define fchdir _tchdir
#else // For MacOSX and Linux platforms
#define fchar wchar_t
typedef std::wstring fstring;
#define FC(a) L ## a
#define fstrlen wcslen
#define fstrcmp wcscmp
#define fstricmp wcsicmp
#define fstrncpy wcsncpy
#define fstrrchr wcsrchr
#define fstrlower wcslwr
#define fsnprintf swprintf
#define fvsnprintf vswprintf
#define fchdir(a) chdir(FUStringConversion::ToString(a).c_str())
#endif // WIN32
#else // UNICODE
typedef char fchar;
typedef std::basic_string<fchar> fstring;
#define FC(a) a
#define fstrlen strlen
#define fstrcmp strcmp
#define fstricmp stricmp
#define fstrncpy strncpy
#define fstrrchr strrchr
#define fstrlower strlower
#define fsnprintf snprintf
#define fvsnprintf vsnprintf
#define fatol atol
#define fatof atof
#define fchdir chdir
#endif // UNICODE
#ifndef WIN32
#define MAX_PATH 1024
#endif // !WIN32
#endif // _PLATFORMS_H_

View File

@@ -0,0 +1 @@
#include "StdAfx.h"

View File

@@ -0,0 +1,11 @@
/*
Copyright (C) 2005-2006 Feeling Software Inc.
MIT License: http://www.opensource.org/licenses/mit-license.php
*/
#ifndef _STD_AFX_H_
#define _STD_AFX_H_
#include "FUtils/FUtils.h"
#endif // _STD_AFX_H_