bgfx/3rdparty/openctm/tools/ctm.cpp
2012-10-07 20:41:18 -07:00

166 lines
5.4 KiB
C++

//-----------------------------------------------------------------------------
// Product: OpenCTM tools
// File: ctm.h
// Description: Implementation of the OpenCTM file format importer/exporter.
//-----------------------------------------------------------------------------
// 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.
//-----------------------------------------------------------------------------
#include <stdexcept>
#include <openctm.h>
#include "ctm.h"
using namespace std;
/// Import an OpenCTM file from a file.
void Import_CTM(const char * aFileName, Mesh * aMesh)
{
// Clear the mesh
aMesh->Clear();
// Load the file using the OpenCTM API
CTMimporter ctm;
// Load the file
ctm.Load(aFileName);
// Extract file comment
const char * comment = ctm.GetString(CTM_FILE_COMMENT);
if(comment)
aMesh->mComment = string(comment);
// Extract indices
CTMuint numTriangles = ctm.GetInteger(CTM_TRIANGLE_COUNT);
aMesh->mIndices.resize(numTriangles * 3);
const CTMuint * indices = ctm.GetIntegerArray(CTM_INDICES);
for(CTMuint i = 0; i < numTriangles * 3; ++ i)
aMesh->mIndices[i] = indices[i];
// Extract vertices
CTMuint numVertices = ctm.GetInteger(CTM_VERTEX_COUNT);
aMesh->mVertices.resize(numVertices);
const CTMfloat * vertices = ctm.GetFloatArray(CTM_VERTICES);
for(CTMuint i = 0; i < numVertices; ++ i)
{
aMesh->mVertices[i].x = vertices[i * 3];
aMesh->mVertices[i].y = vertices[i * 3 + 1];
aMesh->mVertices[i].z = vertices[i * 3 + 2];
}
// Extract normals
if(ctm.GetInteger(CTM_HAS_NORMALS) == CTM_TRUE)
{
aMesh->mNormals.resize(numVertices);
const CTMfloat * normals = ctm.GetFloatArray(CTM_NORMALS);
for(CTMuint i = 0; i < numVertices; ++ i)
{
aMesh->mNormals[i].x = normals[i * 3];
aMesh->mNormals[i].y = normals[i * 3 + 1];
aMesh->mNormals[i].z = normals[i * 3 + 2];
}
}
// Extract texture coordinates
if(ctm.GetInteger(CTM_UV_MAP_COUNT) > 0)
{
aMesh->mTexCoords.resize(numVertices);
const CTMfloat * texCoords = ctm.GetFloatArray(CTM_UV_MAP_1);
for(CTMuint i = 0; i < numVertices; ++ i)
{
aMesh->mTexCoords[i].u = texCoords[i * 2];
aMesh->mTexCoords[i].v = texCoords[i * 2 + 1];
}
const char * str = ctm.GetUVMapString(CTM_UV_MAP_1, CTM_FILE_NAME);
if(str)
aMesh->mTexFileName = string(str);
else
aMesh->mTexFileName = string("");
}
// Extract colors
CTMenum colorAttrib = ctm.GetNamedAttribMap("Color");
if(colorAttrib != CTM_NONE)
{
aMesh->mColors.resize(numVertices);
const CTMfloat * colors = ctm.GetFloatArray(colorAttrib);
for(CTMuint i = 0; i < numVertices; ++ i)
{
aMesh->mColors[i].x = colors[i * 4];
aMesh->mColors[i].y = colors[i * 4 + 1];
aMesh->mColors[i].z = colors[i * 4 + 2];
aMesh->mColors[i].w = colors[i * 4 + 3];
}
}
}
/// Export an OpenCTM file to a file.
void Export_CTM(const char * aFileName, Mesh * aMesh, Options &aOptions)
{
// Save the file using the OpenCTM API
CTMexporter ctm;
// Define mesh
CTMfloat * normals = 0;
if(aMesh->HasNormals() && !aOptions.mNoNormals)
normals = &aMesh->mNormals[0].x;
ctm.DefineMesh((CTMfloat *) &aMesh->mVertices[0].x, aMesh->mVertices.size(),
(const CTMuint*) &aMesh->mIndices[0], aMesh->mIndices.size() / 3,
normals);
// Define texture coordinates
if(aMesh->HasTexCoords())
{
const char * fileName = NULL;
if(aMesh->mTexFileName.size() > 0)
fileName = aMesh->mTexFileName.c_str();
CTMenum map = ctm.AddUVMap(&aMesh->mTexCoords[0].u, "Diffuse color", fileName);
ctm.UVCoordPrecision(map, aOptions.mTexMapPrecision);
}
// Define vertex colors
if(aMesh->HasColors())
{
CTMenum map = ctm.AddAttribMap(&aMesh->mColors[0].x, "Color");
ctm.AttribPrecision(map, aOptions.mColorPrecision);
}
// Set file comment
if(aMesh->mComment.size() > 0)
ctm.FileComment(aMesh->mComment.c_str());
// Set compression method and level
ctm.CompressionMethod(aOptions.mMethod);
ctm.CompressionLevel(aOptions.mLevel);
// Set vertex precision
if(aOptions.mVertexPrecision > 0.0f)
ctm.VertexPrecision(aOptions.mVertexPrecision);
else
ctm.VertexPrecisionRel(aOptions.mVertexPrecisionRel);
// Set normal precision
ctm.NormalPrecision(aOptions.mNormalPrecision);
// Export file
ctm.Save(aFileName);
}