void ZoaDebugFunctions::addQuadToMesh( ci::TriMesh& mesh, const ci::Vec3f& P0, const ci::Vec3f& P1, const ci::Vec3f& P2, const ci::Vec3f& P3, const ci::ColorA& color )
{
	ci::Vec3f e0 = P2 - P0;
	ci::Vec3f e1 = P2 - P1;
	ci::Vec3f n = e0.cross(e1).normalized();

	mesh.appendVertex( P0 );
	mesh.appendColorRGBA( color );
	mesh.appendNormal( n );

	mesh.appendVertex( P1 );
	mesh.appendColorRGBA( color );
	mesh.appendNormal( n );

	mesh.appendVertex( P2 );
	mesh.appendColorRGBA( color );
	mesh.appendNormal( n );

	mesh.appendVertex( P3 );
	mesh.appendColorRGBA( color );
	mesh.appendNormal( n );

	int vert0 = mesh.getNumVertices() - 4;
	int vert1 = mesh.getNumVertices() - 1;
	int vert2 = mesh.getNumVertices() - 2;
	int vert3 = mesh.getNumVertices() - 3;

	mesh.appendTriangle( vert0, vert3, vert1 );
	mesh.appendTriangle( vert3, vert2, vert1 );
}
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 );
}
Exemple #4
0
void World::generateMesh(ci::TriMesh & mesh)
{
   using namespace ci;
   
   Vec3f offset = Vec3f(m_size * -0.5f, m_size * -0.5f, m_size * -0.5f);
   
   for (size_t z = 0; z < m_size; ++z)
      for (size_t y = 0; y < m_size; ++y)
         for (size_t x = 0; x < m_size; ++x)
         {
            if (cell(x, y, z) == AIR)
            {
               for (size_t i = 0; i < 6; ++i)
               {
                  int index = getNeigbour(x, y, z, i);
                  
                  if (index != -1)
                  {
                     if (cell(index) == DIRT)
                     {
                        Vec3f normal = getNeigbourOffset(i);
                        Vec3f up = std::abs(normal.dot(Vec3f::yAxis())) > 0.9f ? Vec3f::zAxis() : Vec3f::yAxis();                   
                        Vec3f side = normal.cross(up) * 0.5f;
                        up = up * 0.5f;
                        
                        Vec3f pos = offset + Vec3f(x, y, z) + (normal * 0.5f);
                        
                        size_t indexStart = mesh.getNumVertices();
                        
                        
                        // Layout of the quad
                        //
                        // 0 --------------- 3
                        // |        ^ up     |
                        // |        |        |
                        // |  side  |        |
                        // |  <-----o pos    |
                        // |                 |
                        // |                 |
                        // |                 |
                        // 1 --------------- 2
                        
                        // Create the vertex data
                        mesh.appendVertex(pos + side + up);
                        mesh.appendVertex(pos + side - up);
                        mesh.appendVertex(pos - side - up);
                        mesh.appendVertex(pos - side + up);
                        mesh.appendNormal(-normal);
                        mesh.appendNormal(-normal);
                        mesh.appendNormal(-normal);
                        mesh.appendNormal(-normal);
                        
                        // Create triangle data
                        mesh.appendTriangle(indexStart + 0, indexStart + 1, indexStart + 2);
                        mesh.appendTriangle(indexStart + 0, indexStart + 2, indexStart + 3);
                     }
                  }
               }
            }
         }
}