Skip to content

Instantly share code, notes, and snippets.

@arielm
Created June 2, 2011 12:41
Show Gist options
  • Save arielm/1004350 to your computer and use it in GitHub Desktop.
Save arielm/1004350 to your computer and use it in GitHub Desktop.
A quick and dirty version of Cinder's Trimesh, to be used on iOS
/*
Copyright (c) 2010, The Barbarian Group
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that
the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list of conditions and
the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and
the following disclaimer in the documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
#include "TriMesh16.h"
using std::vector;
namespace cinder {
void TriMesh16::clear()
{
mVertices.clear();
mNormals.clear();
mTexCoords.clear();
mIndices.clear();
}
void TriMesh16::getTriangleVertices( size_t idx, Vec3f *a, Vec3f *b, Vec3f *c ) const
{
*a = mVertices[ mIndices[idx * 3] ];
*b = mVertices[ mIndices[idx * 3 + 1] ];
*c = mVertices[ mIndices[idx * 3 + 2] ];
}
AxisAlignedBox3f TriMesh16::calcBoundingBox() const
{
if( mVertices.empty() )
return AxisAlignedBox3f( Vec3f::zero(), Vec3f::zero() );
Vec3f min(mVertices[0]), max(mVertices[0]);
for( size_t i = 1; i < mVertices.size(); ++i ) {
if( mVertices[i].x < min.x )
min.x = mVertices[i].x;
else if( mVertices[i].x > max.x )
max.x = mVertices[i].x;
if( mVertices[i].y < min.y )
min.y = mVertices[i].y;
else if( mVertices[i].y > max.y )
max.y = mVertices[i].y;
if( mVertices[i].z < min.z )
min.z = mVertices[i].z;
else if( mVertices[i].z > max.z )
max.z = mVertices[i].z;
}
return AxisAlignedBox3f( min, max );
}
AxisAlignedBox3f TriMesh16::calcBoundingBox( const Matrix44f &transform ) const
{
if( mVertices.empty() )
return AxisAlignedBox3f( Vec3f::zero(), Vec3f::zero() );
Vec3f min( transform.transformPointAffine( mVertices[0] ) );
Vec3f max( min );
for( size_t i = 0; i < mVertices.size(); ++i ) {
Vec3f v = transform.transformPointAffine( mVertices[i] );
if( v.x < min.x )
min.x = v.x;
else if( v.x > max.x )
max.x = v.x;
if( v.y < min.y )
min.y = v.y;
else if( v.y > max.y )
max.y = v.y;
if( v.z < min.z )
min.z = v.z;
else if( v.z > max.z )
max.z = v.z;
}
return AxisAlignedBox3f( min, max );
}
void TriMesh16::read( DataSourceRef dataSource )
{
IStreamRef in = dataSource->createStream();
clear();
uint8_t versionNumber;
in->read( &versionNumber );
uint32_t numVertices, numNormals, numTexCoords, numIndices;
in->readLittle( &numVertices );
in->readLittle( &numNormals );
in->readLittle( &numTexCoords );
in->readLittle( &numIndices );
for( size_t idx = 0; idx < numVertices; ++idx ) {
Vec3f v;
in->readLittle( &v.x ); in->readLittle( &v.y ); in->readLittle( &v.z );
mVertices.push_back( v );
}
for( size_t idx = 0; idx < numNormals; ++idx ) {
Vec3f v;
in->readLittle( &v.x ); in->readLittle( &v.y ); in->readLittle( &v.z );
mNormals.push_back( v );
}
for( size_t idx = 0; idx < numTexCoords; ++idx ) {
Vec2f v;
in->readLittle( &v.x ); in->readLittle( &v.y );
mTexCoords.push_back( v );
}
for( size_t idx = 0; idx < numIndices; ++idx ) {
uint32_t v;
in->readLittle( &v );
mIndices.push_back( static_cast<uint16_t>(v) );
}
}
} // namespace cinder
/*
Copyright (c) 2010, The Barbarian Group
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that
the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list of conditions and
the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and
the following disclaimer in the documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
#pragma once
#include <vector>
#include "cinder/Vector.h"
#include "cinder/AxisAlignedBox.h"
#include "cinder/DataSource.h"
#include "cinder/DataTarget.h"
#include "cinder/Matrix.h"
namespace cinder {
class TriMesh16 {
public:
void clear();
bool hasNormals() const { return ! mNormals.empty(); }
bool hasTexCoords() const { return ! mTexCoords.empty(); }
void appendVertex( const Vec3f &v ) { mVertices.push_back( v ); }
void appendNormal( const Vec3f &v ) { mNormals.push_back( v ); }
void appendIndex( uint16_t i) { mIndices.push_back( i ); }
void appendTexCoord( const Vec2f &v ) { mTexCoords.push_back( v ); }
void appendTriangle( size_t v0, size_t v1, size_t v2 ) { mIndices.push_back( v0 ); mIndices.push_back( v1 ); mIndices.push_back( v2 ); }
size_t getNumIndices() const { return mIndices.size(); }
size_t getNumTriangles() const { return mIndices.size() / 3; }
size_t getNumVertices() const { return mVertices.size(); }
//! Puts the 3 vertices of triangle number \a idx into \a a, \a b and \a c.
void getTriangleVertices( size_t idx, Vec3f *a, Vec3f *b, Vec3f *c ) const;
const std::vector<Vec3f>& getVertices() const { return mVertices; }
const std::vector<Vec3f>& getNormals() const { return mNormals; }
const std::vector<Vec2f>& getTexCoords() const { return mTexCoords; }
const std::vector<uint16_t>& getIndices() const { return mIndices; }
//! Calculates the bounding box of all vertices
AxisAlignedBox3f calcBoundingBox() const;
//! Calculates the bounding box of all vertices as transformed by \a transform
AxisAlignedBox3f calcBoundingBox( const Matrix44f &transform ) const;
void read( DataSourceRef in );
private:
std::vector<Vec3f> mVertices;
std::vector<Vec3f> mNormals;
std::vector<Vec2f> mTexCoords;
std::vector<uint16_t> mIndices;
};
} // namespace cinder
/*
* THE MESH AND TEXTURE ARE FROM THE Picking3D SAMPLE
*/
TriMesh16 *duckMesh = new TriMesh16;
duckMesh->read(loadResource(RES_DUCKY_MESH));
gl::Texture::Format format;
format.enableMipmapping(true);
ImageSourceRef img = loadImage(loadResource(RES_DUCKY_TEX)); // BE SURE TO RESCALE ducky.png TO 256x256 (1024x1024 IS OVERKILL FOR iOS)
gl::Texture *duckTexture = new gl::Texture(img, format);
glColor4f(1, 1, 1, 1);
duckTexture->enableAndBind();
drawMesh(duckMesh, true, true);
duckTexture->unbind();
void drawMesh(TriMesh16 *mesh, bool useTexture, bool useNormals)
{
if (useTexture && mesh->hasTexCoords())
{
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, 0, &(mesh->getTexCoords()[0]));
}
if (useNormals && mesh->hasNormals())
{
glEnableClientState( GL_NORMAL_ARRAY );
glNormalPointer(GL_FLOAT, 0, &(mesh->getNormals()[0]) );
}
glEnableClientState( GL_VERTEX_ARRAY );
glVertexPointer(3, GL_FLOAT, 0, &(mesh->getVertices()[0]));
glDrawElements(GL_TRIANGLES, mesh->getNumIndices(), GL_UNSIGNED_SHORT, &(mesh->getIndices()[0]));
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment