Skip to content

Instantly share code, notes, and snippets.

@miketahani
Forked from patriciogonzalezvivo/MakingGeometries.md
Created December 12, 2020 18:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save miketahani/bd209c1725d46ba0e99b57240112b3d8 to your computer and use it in GitHub Desktop.
Save miketahani/bd209c1725d46ba0e99b57240112b3d8 to your computer and use it in GitHub Desktop.
Creating Geometries in openFrameworks

Face by Face

void addFace(ofMesh& mesh, ofVec3f a, ofVec3f b, ofVec3f c) {
	ofVec3f normal = ((b - a).cross(c - a)).normalize();
	mesh.addNormal(normal);
	mesh.addVertex(a);
	mesh.addNormal(normal);
	mesh.addVertex(b);
	mesh.addNormal(normal);
	mesh.addVertex(c);
}

//--------------------------------------------------------------
void addFace(ofMesh& mesh, ofVec3f a, ofVec3f b, ofVec3f c, ofVec3f d) {
	addFace(mesh, a, b, c);
	addFace(mesh, a, c, d);
}

//--------------------------------------------------------------
void makeTerrainFromImg(const ofImage &img){

	mesh.setMode(OF_PRIMITIVE_TRIANGLES);
	int skip = 1;	
	int width = img.getWidth();
	int height = img.getHeight();
	for(int y = 0; y < height - skip; y += skip) {
		for(int x = 0; x < width - skip; x += skip) {
			ofVec3f nw = getVertexFromImg(img, x, y);
			ofVec3f ne = getVertexFromImg(img, x + skip, y);
			ofVec3f sw = getVertexFromImg(img, x, y + skip);
			ofVec3f se = getVertexFromImg(img, x + skip, y + skip);
			
			addFace(mesh, nw, ne, se, sw);
		}
	}

}

Flat Mesh of Triangles

void makeFlatMesh(){

    int scale = 15;
    int w = ofGetWidth()/scale;
    int h = ofGetHeight()/scale;
    for (int y = 0; y < h; y++){
        for (int x = 0; x<w; x++){
            
            //  Per pixel we set the position, normal and texCoord
            //
            float offsetX = 0;
            float offsetY = (x%2==1)?0.5:0.0;
            terrain.addVertex(ofPoint((x+offsetX)*scale,(y+offsetY)*scale,0));
            terrain.addNormal(ofPoint(1,0,0));
            terrain.addTexCoord(ofVec2f((float)(x+offsetX)/(float)w,(float)(y+offsetY)/(float)h));
        }
    }

    for (int y = 0; y<h-1; y++){
        for (int x=0; x<w-1; x++){
            if(x%2==0){
                terrain.addIndex(x+y*w);				// a
                terrain.addIndex((x+1)+y*w);			// b
                terrain.addIndex(x+(y+1)*w);			// d
                
                terrain.addIndex((x+1)+y*w);			// b
                terrain.addIndex((x+1)+(y+1)*w);		// c
                terrain.addIndex(x+(y+1)*w);			// d
            } else {
                terrain.addIndex((x+1)+y*w);			// b
                terrain.addIndex(x+y*w);				// a
                terrain.addIndex((x+1)+(y+1)*w);		// c
                
                terrain.addIndex(x+y*w);				// a
                terrain.addIndex(x+(y+1)*w);			// d
                terrain.addIndex((x+1)+(y+1)*w);		// c
            }
        }
    }
}

Fixing Normals

Universal function which sets normals for the triangle mesh

void setNormals( ofMesh &mesh ){

	//The number of the vertices
	int nV = mesh.getNumVertices();
	
	//The number of the triangles
	int nT = mesh.getNumIndices() / 3;

	vector<ofPoint> norm( nV ); //Array for the normals

	//Scan all the triangles. For each triangle add its
	//normal to norm's vectors of triangle's vertices
	for (int t=0; t<nT; t++) {

		//Get indices of the triangle t
		int i1 = mesh.getIndex( 3 * t );
		int i2 = mesh.getIndex( 3 * t + 1 );
		int i3 = mesh.getIndex( 3 * t + 2 );
		
		//Get vertices of the triangle
		const ofPoint &v1 = mesh.getVertex( i1 );
		const ofPoint &v2 = mesh.getVertex( i2 );
		const ofPoint &v3 = mesh.getVertex( i3 );
		
		//Compute the triangle's normal
		ofPoint dir = ( (v2 - v1).crossed( v3 - v1 ) ).normalized();
		
		//Accumulate it to norm array for i1, i2, i3
		norm[ i1 ] += dir;
		norm[ i2 ] += dir;
		norm[ i3 ] += dir;
	}

	//Normalize the normal's length
	for (int i=0; i<nV; i++) {
		norm[i].normalize();
	}

	//Set the normals to mesh
	mesh.clearNormals();
	mesh.addNormals( norm );
}

Old and dirty

{
ofFloatPixels heightMap;
heightMap.allocate( _width, _height, OF_PIXELS_RGBA);
// Put the pixels
 
ofFloatPixels norms;
norms.allocate( _width, _height, OF_PIXELS_RGBA);
// put the pixels
            
int width = heightMap.getWidth();
int height = heightMap.getHeight();
float flResolution = 4; // 1-10
float flHeightScale = 300;
float textureScale = 1.0;
            
// Generate Vertex Field
nVertexCount = (int) ( width * height * 6 / ( flResolution * flResolution ) );
            
pVertices	= new ofVec3f[nVertexCount];		// Allocate Vertex Data
pTexCoords	= new ofVec2f[nVertexCount];		// Allocate Tex Coord Data
pNormals		= new ofVec3f[nVertexCount];		// Allocate Normals
            
int nX, nZ, nTri, nIndex=0;                     // Create Variables
float flX, flZ;
            
for( nZ = 0; nZ < height-flResolution ; nZ += (int) flResolution ){
	for( nX = 0; nX < width-flResolution ; nX += (int) flResolution ){
		for( nTri = 0; nTri < 6; nTri++ ){
			// Using This Quick Hack, Figure The X,Z Position Of The Point
			flX = (float) nX + ( ( nTri == 1 || nTri == 2 || nTri == 5 ) ? flResolution : 0.0f );
			flZ = (float) nZ + ( ( nTri == 2 || nTri == 4 || nTri == 5 ) ? flResolution : 0.0f );
                        
			// Set The Data, Using PtHeight To Obtain The Y Value
			pVertices[nIndex].x = flX - ( width *0.5 );
			pVertices[nIndex].y = heightMap.getColor((int)flX, (int)flZ).r * flHeightScale;
			pVertices[nIndex].z = flZ - ( height *0.5 );
                        
                        // 3	0 --- 1		nTri reference
                        // | \	  \	  |
                        // |   \	\ |
                        // 4 --- 5	  2
                        
`			// Stretch The Texture Across The Entire Mesh
			pTexCoords[nIndex].x = flX * textureScale;// / width;
			pTexCoords[nIndex].y = flZ * textureScale;// / height;
                        
			// Normals by vert
			pNormals[nIndex].x = norms.getColor((int)flX, (int)flZ).r;
			pNormals[nIndex].y = norms.getColor((int)flX, (int)flZ).b;
			pNormals[nIndex].z = norms.getColor((int)flX, (int)flZ).g;
                        
			// Increment Our Index
			nIndex++;
		}				
	}
}
            
vbo.setVertexData(pVertices, nVertexCount, GL_STREAM_DRAW);
vbo.setNormalData(pNormals, nVertexCount, GL_STREAM_DRAW);
vbo.setTexCoordData(pTexCoords, nVertexCount, GL_STREAM_DRAW);
            
// Our Copy Of The Data Is No Longer Necessary, It Is Safe In The Graphics Card
delete [] pVertices; pVertices = NULL;
delete [] pTexCoords; pTexCoords = NULL;
delete [] pNormals; pNormals = NULL;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment