void ZoaDebugFunctions::trimeshDrawNormals( ci::TriMesh &mesh )
{
	std::vector<ci::Vec3f> meshVertices = mesh.getVertices();
	std::vector<ci::Vec3f> meshNormals = mesh.getNormals();
	for( size_t i = 3; i < meshNormals.size(); i+=4 )
	{
		float t = 0.5f; // Because T is 0.5 it's not really necessary but the we could project along the plane this way
		ci::Vec3f midPoint = ci::Vec3f( (1.0f - t) * ( meshVertices[i-2] ) + t * ( meshVertices[i] ) );
		ci::Vec3f normal = meshNormals[i]*10;
		ci::gl::drawVector( midPoint, midPoint+normal, 10, 2.5);
	}
}
void DelaunayMeshMaker::update(){
	mTesselator->update();

	if( mNeedsProcessing && mTesselator->isRunning() ){
		mTesselator->interrupt();
	}else if( mNeedsProcessing && !mTesselator->isRunning() ){
		mNeedsProcessing = false;
		mTesselator->process( mBorderPoints, mSteinerPoints, mBlend, mSurface, mDepthOffset );
	}

	if( mBlend != mPrevBlend ){
		mPrevBlend = mBlend;
	}
	
	if( mDepthOffset != mPrevDepthOffset ){
		std::vector<Vec3f> verts = mMesh.getVertices();
		std::vector<Vec3f> newVerts;

		int count = 0;
		for( auto itr = verts.begin(); itr != verts.end(); ++itr ){
			float z = (*itr).z;

			newVerts.push_back( Vec3f( (*itr).x, (*itr).y, mDepthRandom[count] * mDepthOffset ) );
			count++;
		}

		mMesh.getVertices().swap( newVerts );
		mMesh.recalculateNormals();

		mVboMesh = gl::VboMesh( mMesh );
		mPrevDepthOffset = mDepthOffset;
	}

	if( mScaleDown != mScaleDownPrev ){
		mScaleDownPrev = mScaleDown;
		mEdgeDetectSurface = edgeDetect( Surface8u( mSurface ), mCannyMinThreshold, mCannyMaxThreshold, mScaleDownPrev );
	}
}
void ZoaDebugFunctions::calculateTriMeshNormals( ci::TriMesh &mesh )
{
	const std::vector<ci::Vec3f>& vertices = mesh.getVertices();
	const std::vector<uint32_t>& indices = mesh.getIndices();

	// remove all current normals
	std::vector<ci::Vec3f>& normals = mesh.getNormals();
	normals.reserve( mesh.getNumVertices() );
	normals.clear();

	// set the normal for each vertex to (0, 0, 0)
	for(size_t i=0; i < mesh.getNumVertices(); ++i)
		normals.push_back( ci::Vec3f::zero() );

	// Average out the normal for each vertex at an index
	for(size_t i=0; i< mesh.getNumTriangles(); ++i)
	{
		ci::Vec3f v0 = vertices[ indices[i * 3] ];
		ci::Vec3f v1 = vertices[ indices[i * 3 + 1] ];
		ci::Vec3f v2 = vertices[ indices[i * 3 + 2] ];

		// calculate normal and normalize it, so each of the normals equally contributes to the final result
		ci::Vec3f e0 = v2 - v0;
		ci::Vec3f e1 = v2 - v1;
		ci::Vec3f n = e0.cross(e1).normalized();

		// add the normal to the final result, so we get an average of the normals of each triangle
		normals[ indices[i * 3] ] += n;
		normals[ indices[i * 3 + 1] ] += n;
		normals[ indices[i * 3 + 2] ] += n;
	}

	// the normals are probably not normalized by now, so make sure their lengths will be 1.0 as expected
	for(size_t i=0;i< normals.size();++i) {
		normals[i].normalize();
	}
}
TriMesh MeshHelper::subdivide( const ci::TriMesh &triMesh, uint32_t division, bool normalize )
{
	if ( division <= 1 || triMesh.getNumIndices() == 0 || triMesh.getNumVertices() == 0 ) {
		return triMesh;
	}

	vector<uint32_t> indices	= triMesh.getIndices();
	vector<Vec3f> normals		= triMesh.getNormals();
	vector<Vec3f> positions		= triMesh.getVertices();
	vector<Vec2f> texCoords		= triMesh.getTexCoords();

	vector<uint32_t> indicesBuffer( indices );
	indices.clear();
	indices.reserve( indicesBuffer.size() * 4 );
 
	uint32_t index0;
	uint32_t index1;
	uint32_t index2;
	uint32_t index3;
	uint32_t index4;
	uint32_t index5;
	for ( vector<uint32_t>::const_iterator iter = indicesBuffer.begin(); iter != indicesBuffer.end(); ) {
		index0 = *iter;
		++iter;
		index1 = *iter;
		++iter;
		index2 = *iter;
		++iter;

		if ( normalize ) {
			index3 = positions.size();
			positions.push_back( positions.at( index0 ).lerp( 0.5f, positions.at( index1 ) ).normalized() * 0.5f );
			index4 = positions.size();
			positions.push_back( positions.at( index1 ).lerp( 0.5f, positions.at( index2 ) ).normalized() * 0.5f );
			index5 = positions.size();
			positions.push_back( positions.at( index2 ).lerp( 0.5f, positions.at( index0 ) ).normalized() * 0.5f );
		} else {
			index3 = positions.size(); 
			positions.push_back( positions.at( index0 ).lerp( 0.5f, positions.at( index1 ) ) );
			index4 = positions.size();
			positions.push_back( positions.at( index1 ).lerp( 0.5f, positions.at( index2 ) ) );
			index5 = positions.size();
			positions.push_back( positions.at( index2 ).lerp( 0.5f, positions.at( index0 ) ) );
		}
	
		if ( !normals.empty() ) {
			normals.push_back( normals.at( index0 ).lerp( 0.5f, normals.at( index1 ) ) );
			normals.push_back( normals.at( index1 ).lerp( 0.5f, normals.at( index2 ) ) );
			normals.push_back( normals.at( index2 ).lerp( 0.5f, normals.at( index0 ) ) );
		}

		if ( !texCoords.empty() ) {
			texCoords.push_back( texCoords.at( index0 ).lerp( 0.5f, texCoords.at( index1 ) ) );
			texCoords.push_back( texCoords.at( index1 ).lerp( 0.5f, texCoords.at( index2 ) ) );
			texCoords.push_back( texCoords.at( index2 ).lerp( 0.5f, texCoords.at( index0 ) ) );
		}

		indices.push_back( index0 ); 
		indices.push_back( index3 ); 
		indices.push_back( index5 );
		
		indices.push_back( index3 ); 
		indices.push_back( index1 );
		indices.push_back( index4 );
		
		indices.push_back( index5 ); 
		indices.push_back( index4 ); 
		indices.push_back( index2 );
		
		indices.push_back( index3 ); 
		indices.push_back( index4 ); 
		indices.push_back( index5 );
	}

	ci::TriMesh mesh = create( indices, positions, normals, texCoords );
	
	indices.clear();
	normals.clear();
	positions.clear();
	texCoords.clear();

	return subdivide( mesh, division - 1, normalize );
}