mirror of
https://github.com/scratchfoundation/bgfx.git
synced 2024-11-29 11:05:36 -05:00
378 lines
10 KiB
C
378 lines
10 KiB
C
|
//-----------------------------------------------------------------------------
|
||
|
// Product: OpenCTM
|
||
|
// File: openctmpp.h
|
||
|
// Description: C++ wrapper for the OpenCTM API.
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Copyright (c) 2009-2010 Marcus Geelnard
|
||
|
//
|
||
|
// This software is provided 'as-is', without any express or implied
|
||
|
// warranty. In no event will the authors be held liable for any damages
|
||
|
// arising from the use of this software.
|
||
|
//
|
||
|
// Permission is granted to anyone to use this software for any purpose,
|
||
|
// including commercial applications, and to alter it and redistribute it
|
||
|
// freely, subject to the following restrictions:
|
||
|
//
|
||
|
// 1. The origin of this software must not be misrepresented; you must not
|
||
|
// claim that you wrote the original software. If you use this software
|
||
|
// in a product, an acknowledgment in the product documentation would be
|
||
|
// appreciated but is not required.
|
||
|
//
|
||
|
// 2. Altered source versions must be plainly marked as such, and must not
|
||
|
// be misrepresented as being the original software.
|
||
|
//
|
||
|
// 3. This notice may not be removed or altered from any source
|
||
|
// distribution.
|
||
|
//-----------------------------------------------------------------------------
|
||
|
|
||
|
// To disable C++ extensions, define OPENCTM_NO_CPP
|
||
|
#ifndef OPENCTM_NO_CPP
|
||
|
|
||
|
#ifndef __OPENCTMPP_H_
|
||
|
#define __OPENCTMPP_H_
|
||
|
|
||
|
// Just in case (if this file was included from outside openctm.h)...
|
||
|
#ifndef __OPENCTM_H_
|
||
|
#include "openctm.h"
|
||
|
#endif
|
||
|
|
||
|
#include <exception>
|
||
|
|
||
|
/// OpenCTM exception. When an error occurs, a \c ctm_error exception is
|
||
|
/// thrown. Its what() function returns the name of the OpenCTM error code
|
||
|
/// (for instance "CTM_INVALID_OPERATION").
|
||
|
class ctm_error: public std::exception
|
||
|
{
|
||
|
private:
|
||
|
CTMenum mErrorCode;
|
||
|
|
||
|
public:
|
||
|
explicit ctm_error(CTMenum aError)
|
||
|
{
|
||
|
mErrorCode = aError;
|
||
|
}
|
||
|
|
||
|
virtual const char* what() const throw()
|
||
|
{
|
||
|
return ctmErrorString(mErrorCode);
|
||
|
}
|
||
|
|
||
|
CTMenum error_code() const throw()
|
||
|
{
|
||
|
return mErrorCode;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
|
||
|
/// OpenCTM importer class. This is a C++ wrapper class for an OpenCTM import
|
||
|
/// context. Usage example:
|
||
|
///
|
||
|
/// @code
|
||
|
/// // Create a new OpenCTM importer object
|
||
|
/// CTMimporter ctm;
|
||
|
///
|
||
|
/// // Load the OpenCTM file
|
||
|
/// ctm.Load("mymesh.ctm");
|
||
|
///
|
||
|
/// // Access the mesh data
|
||
|
/// vertCount = ctm.GetInteger(CTM_VERTEX_COUNT);
|
||
|
/// vertices = ctm.GetFloatArray(CTM_VERTICES);
|
||
|
/// triCount = ctm.GetInteger(CTM_TRIANGLE_COUNT);
|
||
|
/// indices = ctm.GetIntegerArray(CTM_INDICES);
|
||
|
///
|
||
|
/// // Deal with the mesh (e.g. transcode it to our internal representation)
|
||
|
/// // ...
|
||
|
/// @endcode
|
||
|
|
||
|
class CTMimporter {
|
||
|
private:
|
||
|
/// The OpenCTM context handle.
|
||
|
CTMcontext mContext;
|
||
|
|
||
|
/// Check for OpenCTM errors, and throw an exception if an error has
|
||
|
/// occured.
|
||
|
void CheckError()
|
||
|
{
|
||
|
CTMenum err = ctmGetError(mContext);
|
||
|
if(err != CTM_NONE)
|
||
|
throw ctm_error(err);
|
||
|
}
|
||
|
|
||
|
public:
|
||
|
/// Constructor
|
||
|
CTMimporter()
|
||
|
{
|
||
|
mContext = ctmNewContext(CTM_IMPORT);
|
||
|
}
|
||
|
|
||
|
/// Destructor
|
||
|
~CTMimporter()
|
||
|
{
|
||
|
ctmFreeContext(mContext);
|
||
|
}
|
||
|
|
||
|
/// Wrapper for ctmGetInteger()
|
||
|
CTMuint GetInteger(CTMenum aProperty)
|
||
|
{
|
||
|
CTMuint res = ctmGetInteger(mContext, aProperty);
|
||
|
CheckError();
|
||
|
return res;
|
||
|
}
|
||
|
|
||
|
/// Wrapper for ctmGetFloat()
|
||
|
CTMfloat GetFloat(CTMenum aProperty)
|
||
|
{
|
||
|
CTMfloat res = ctmGetFloat(mContext, aProperty);
|
||
|
CheckError();
|
||
|
return res;
|
||
|
}
|
||
|
|
||
|
/// Wrapper for ctmGetIntegerArray()
|
||
|
const CTMuint * GetIntegerArray(CTMenum aProperty)
|
||
|
{
|
||
|
const CTMuint * res = ctmGetIntegerArray(mContext, aProperty);
|
||
|
CheckError();
|
||
|
return res;
|
||
|
}
|
||
|
|
||
|
/// Wrapper for ctmGetFloatArray()
|
||
|
const CTMfloat * GetFloatArray(CTMenum aProperty)
|
||
|
{
|
||
|
const CTMfloat * res = ctmGetFloatArray(mContext, aProperty);
|
||
|
CheckError();
|
||
|
return res;
|
||
|
}
|
||
|
|
||
|
/// Wrapper for ctmGetNamedUVMap()
|
||
|
CTMenum GetNamedUVMap(const char * aName)
|
||
|
{
|
||
|
CTMenum res = ctmGetNamedUVMap(mContext, aName);
|
||
|
CheckError();
|
||
|
return res;
|
||
|
}
|
||
|
|
||
|
/// Wrapper for ctmGetUVMapString()
|
||
|
const char * GetUVMapString(CTMenum aUVMap, CTMenum aProperty)
|
||
|
{
|
||
|
const char * res = ctmGetUVMapString(mContext, aUVMap, aProperty);
|
||
|
CheckError();
|
||
|
return res;
|
||
|
}
|
||
|
|
||
|
/// Wrapper for ctmGetUVMapFloat()
|
||
|
CTMfloat GetUVMapFloat(CTMenum aUVMap, CTMenum aProperty)
|
||
|
{
|
||
|
CTMfloat res = ctmGetUVMapFloat(mContext, aUVMap, aProperty);
|
||
|
CheckError();
|
||
|
return res;
|
||
|
}
|
||
|
|
||
|
/// Wrapper for ctmGetNamedAttribMap()
|
||
|
CTMenum GetNamedAttribMap(const char * aName)
|
||
|
{
|
||
|
CTMenum res = ctmGetNamedAttribMap(mContext, aName);
|
||
|
CheckError();
|
||
|
return res;
|
||
|
}
|
||
|
|
||
|
/// Wrapper for ctmGetAttribMapString()
|
||
|
const char * GetAttribMapString(CTMenum aAttribMap, CTMenum aProperty)
|
||
|
{
|
||
|
const char * res = ctmGetAttribMapString(mContext, aAttribMap, aProperty);
|
||
|
CheckError();
|
||
|
return res;
|
||
|
}
|
||
|
|
||
|
/// Wrapper for ctmGetAttribMapFloat()
|
||
|
CTMfloat GetAttribMapFloat(CTMenum aAttribMap, CTMenum aProperty)
|
||
|
{
|
||
|
CTMfloat res = ctmGetAttribMapFloat(mContext, aAttribMap, aProperty);
|
||
|
CheckError();
|
||
|
return res;
|
||
|
}
|
||
|
|
||
|
/// Wrapper for ctmGetString()
|
||
|
const char * GetString(CTMenum aProperty)
|
||
|
{
|
||
|
const char * res = ctmGetString(mContext, aProperty);
|
||
|
CheckError();
|
||
|
return res;
|
||
|
}
|
||
|
|
||
|
/// Wrapper for ctmLoad()
|
||
|
void Load(const char * aFileName)
|
||
|
{
|
||
|
ctmLoad(mContext, aFileName);
|
||
|
CheckError();
|
||
|
}
|
||
|
|
||
|
/// Wrapper for ctmLoadCustom()
|
||
|
void LoadCustom(CTMreadfn aReadFn, void * aUserData)
|
||
|
{
|
||
|
ctmLoadCustom(mContext, aReadFn, aUserData);
|
||
|
CheckError();
|
||
|
}
|
||
|
|
||
|
// You can not copy nor assign from one CTMimporter object to another, since
|
||
|
// the object contains hidden state. By declaring these dummy prototypes
|
||
|
// without an implementation, you will at least get linker errors if you try
|
||
|
// to copy or assign a CTMimporter object.
|
||
|
CTMimporter(const CTMimporter& v);
|
||
|
CTMimporter& operator=(const CTMimporter& v);
|
||
|
};
|
||
|
|
||
|
|
||
|
/// OpenCTM exporter class. This is a C++ wrapper class for an OpenCTM export
|
||
|
/// context. Usage example:
|
||
|
/// @code
|
||
|
/// void MySaveFile(CTMuint aVertCount, CTMuint aTriCount, CTMfloat * aVertices,
|
||
|
/// CTMuint * aIndices, const char * aFileName)
|
||
|
/// {
|
||
|
/// // Create a new OpenCTM exporter object
|
||
|
/// CTMexporter ctm;
|
||
|
///
|
||
|
/// // Define our mesh representation to OpenCTM (store references to it in
|
||
|
/// // the context)
|
||
|
/// ctm.DefineMesh(aVertices, aVertCount, aIndices, aTriCount, NULL);
|
||
|
///
|
||
|
/// // Save the OpenCTM file
|
||
|
/// ctm.Save(aFileName);
|
||
|
/// }
|
||
|
/// @endcode
|
||
|
|
||
|
class CTMexporter {
|
||
|
private:
|
||
|
/// The OpenCTM context handle.
|
||
|
CTMcontext mContext;
|
||
|
|
||
|
/// Check for OpenCTM errors, and throw an exception if an error has
|
||
|
/// occured.
|
||
|
void CheckError()
|
||
|
{
|
||
|
CTMenum err = ctmGetError(mContext);
|
||
|
if(err != CTM_NONE)
|
||
|
throw ctm_error(err);
|
||
|
}
|
||
|
|
||
|
public:
|
||
|
/// Constructor
|
||
|
CTMexporter()
|
||
|
{
|
||
|
mContext = ctmNewContext(CTM_EXPORT);
|
||
|
}
|
||
|
|
||
|
/// Destructor
|
||
|
~CTMexporter()
|
||
|
{
|
||
|
ctmFreeContext(mContext);
|
||
|
}
|
||
|
|
||
|
/// Wrapper for ctmCompressionMethod()
|
||
|
void CompressionMethod(CTMenum aMethod)
|
||
|
{
|
||
|
ctmCompressionMethod(mContext, aMethod);
|
||
|
CheckError();
|
||
|
}
|
||
|
|
||
|
/// Wrapper for ctmCompressionLevel()
|
||
|
void CompressionLevel(CTMuint aLevel)
|
||
|
{
|
||
|
ctmCompressionLevel(mContext, aLevel);
|
||
|
CheckError();
|
||
|
}
|
||
|
|
||
|
/// Wrapper for ctmVertexPrecision()
|
||
|
void VertexPrecision(CTMfloat aPrecision)
|
||
|
{
|
||
|
ctmVertexPrecision(mContext, aPrecision);
|
||
|
CheckError();
|
||
|
}
|
||
|
|
||
|
/// Wrapper for ctmVertexPrecisionRel()
|
||
|
void VertexPrecisionRel(CTMfloat aRelPrecision)
|
||
|
{
|
||
|
ctmVertexPrecisionRel(mContext, aRelPrecision);
|
||
|
CheckError();
|
||
|
}
|
||
|
|
||
|
/// Wrapper for ctmNormalPrecision()
|
||
|
void NormalPrecision(CTMfloat aPrecision)
|
||
|
{
|
||
|
ctmNormalPrecision(mContext, aPrecision);
|
||
|
CheckError();
|
||
|
}
|
||
|
|
||
|
/// Wrapper for ctmUVCoordPrecision()
|
||
|
void UVCoordPrecision(CTMenum aUVMap, CTMfloat aPrecision)
|
||
|
{
|
||
|
ctmUVCoordPrecision(mContext, aUVMap, aPrecision);
|
||
|
CheckError();
|
||
|
}
|
||
|
|
||
|
/// Wrapper for ctmAttribPrecision()
|
||
|
void AttribPrecision(CTMenum aAttribMap, CTMfloat aPrecision)
|
||
|
{
|
||
|
ctmAttribPrecision(mContext, aAttribMap, aPrecision);
|
||
|
CheckError();
|
||
|
}
|
||
|
|
||
|
/// Wrapper for ctmFileComment()
|
||
|
void FileComment(const char * aFileComment)
|
||
|
{
|
||
|
ctmFileComment(mContext, aFileComment);
|
||
|
CheckError();
|
||
|
}
|
||
|
|
||
|
/// Wrapper for ctmDefineMesh()
|
||
|
void DefineMesh(const CTMfloat * aVertices, CTMuint aVertexCount,
|
||
|
const CTMuint * aIndices, CTMuint aTriangleCount,
|
||
|
const CTMfloat * aNormals)
|
||
|
{
|
||
|
ctmDefineMesh(mContext, aVertices, aVertexCount, aIndices, aTriangleCount,
|
||
|
aNormals);
|
||
|
CheckError();
|
||
|
}
|
||
|
|
||
|
/// Wrapper for ctmAddUVMap()
|
||
|
CTMenum AddUVMap(const CTMfloat * aUVCoords, const char * aName,
|
||
|
const char * aFileName)
|
||
|
{
|
||
|
CTMenum res = ctmAddUVMap(mContext, aUVCoords, aName, aFileName);
|
||
|
CheckError();
|
||
|
return res;
|
||
|
}
|
||
|
|
||
|
/// Wrapper for ctmAddAttribMap()
|
||
|
CTMenum AddAttribMap(const CTMfloat * aAttribValues, const char * aName)
|
||
|
{
|
||
|
CTMenum res = ctmAddAttribMap(mContext, aAttribValues, aName);
|
||
|
CheckError();
|
||
|
return res;
|
||
|
}
|
||
|
|
||
|
/// Wrapper for ctmSave()
|
||
|
void Save(const char * aFileName)
|
||
|
{
|
||
|
ctmSave(mContext, aFileName);
|
||
|
CheckError();
|
||
|
}
|
||
|
|
||
|
/// Wrapper for ctmSaveCustom()
|
||
|
void SaveCustom(CTMwritefn aWriteFn, void * aUserData)
|
||
|
{
|
||
|
ctmSaveCustom(mContext, aWriteFn, aUserData);
|
||
|
CheckError();
|
||
|
}
|
||
|
|
||
|
// You can not copy nor assign from one CTMexporter object to another, since
|
||
|
// the object contains hidden state. By declaring these dummy prototypes
|
||
|
// without an implementation, you will at least get linker errors if you try
|
||
|
// to copy or assign a CTMexporter object.
|
||
|
CTMexporter(const CTMexporter& v);
|
||
|
CTMexporter& operator=(const CTMexporter& v);
|
||
|
};
|
||
|
|
||
|
#endif // __OPENCTMPP_H_
|
||
|
|
||
|
#endif // OPENCTM_NO_CPP
|