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 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();
	}
}
Ejemplo n.º 3
0
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 );
}