//--------------------------------------------------------------
        bool load(const string& path, ofMesh& mesh)
        {
            ofFile file(path, ofFile::ReadOnly, true);
            if (!file.exists()) {
                ofLogError("ofxBinaryMesh::load") << "Cannot open file at " << path;
                return false;
            }

            mesh.clear();

            int numVerts = 0;
            file.read((char *)(&numVerts), sizeof(int));
            if (numVerts > 0) {
                mesh.getVertices().resize(numVerts);
                file.read((char *)(&(mesh.getVertices())[0]), sizeof(ofPoint) * numVerts);
            }

            int numNormals = 0;
            file.read((char *)(&numNormals), sizeof(int));
            if (numNormals > 0) {
                mesh.getNormals().resize(numNormals);
                file.read((char *)(&(mesh.getNormals())[0]), sizeof(ofPoint) * numNormals);
            }

            int numTexCoords = 0;
            file.read((char *)(&numTexCoords), sizeof(int));
            if (numTexCoords > 0) {
                mesh.getTexCoords().resize(numTexCoords);
                file.read((char *)(&(mesh.getTexCoords())[0]), sizeof(ofVec2f) * numTexCoords);
            }

            int numColors = 0;
            file.read((char *)(&numColors), sizeof(int));
            if (numColors > 0) {
                mesh.getColors().resize(numColors);
                file.read((char *)(&(mesh.getColors())[0]), sizeof(ofFloatColor) * numColors);
            }

            int numIndices = 0;
            file.read((char *)(&numIndices), sizeof(int));
            if (numIndices > 0) {
                mesh.getIndices().resize(numIndices);
                file.read((char *)(&(mesh.getIndices())[0]), sizeof(ofIndexType) * numIndices);
            }

            file.close();

			return true;
        }
ofMesh & ofBitmapStringGetMesh(const string & text, int x, int y){

	int len = (int)text.length();
	//float yOffset = 0;
	float fontSize = 8.0f;
	bool bOrigin = false;

	float sx = x;
	float sy = y-fontSize;

	ofDrawBitmapCharacterStart(text.size());

	for(int c = 0; c < len; c++){
		if(text[c] == '\n'){

			sy += bOrigin ? -1 : 1 * (fontSize*1.7);
			sx = x;

			//glRasterPos2f(x,y + (int)yOffset);
		} else if (text[c] >= 32){
			// < 32 = control characters - don't draw
			// solves a bug with control characters
			// getting drawn when they ought to not be
			ofDrawBitmapCharacter(text[c], (int)sx, (int)sy);

			sx += fontSize;
		}
	}
	//We do this because its way faster
	charMesh.getVertices().resize(vC);
	charMesh.getTexCoords().resize(vC);
	return charMesh;

}
//---------------------------------------------------------------------
void ofDrawBitmapCharacterEnd(){
	if( vC > 0 ){
		charMesh.getVertices().resize(vC);
		charMesh.getTexCoords().resize(vC);
		bitmappedFontTexture.bind();

		ofPtr<ofGLProgrammableRenderer> programmableRenderer = ofGetGLProgrammableRenderer();

		if (!programmableRenderer){
			#ifndef TARGET_OPENGLES
				// this temporarily enables alpha testing,
				// which discards pixels unless their alpha is 1.0f
				glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT);
				glEnable(GL_ALPHA_TEST);
				glAlphaFunc(GL_GREATER, 0);
			#endif
		}else{
			// glPush/PopAttrib is deprecated + we are doing the alpha test through a shader
			programmableRenderer->setAlphaBitmapText(true);
		}

		charMesh.draw();

		if (!programmableRenderer){
			#ifndef TARGET_OPENGLES
				glPopAttrib();
			#endif
		}else{
			programmableRenderer->setAlphaBitmapText(false);
		}

		bitmappedFontTexture.unbind();
	}

}
//---------------------------------------------------------------------
void  ofDrawBitmapCharacter(int character, int x , int y){

	if(!bBitmapTexturePrepared){
		prepareBitmapTexture();
	}
		
	if (character < 128) {		

		float posTexW = (float)(character % 16)/16.0f;
		float posTexH = ((int)(character / 16.0f))/16.0f;

		float texY1 = posTexH;
		float texY2 = posTexH+heightTex;

		//TODO: look into a better fix.
		//old ofDrawBitmapString was 3 pixels higher, so this version renders text in a different position.
		//3 pixel adjustment corrects that when y is flpped 5 when it's not.
		int yOffset = 14;
		if(!ofIsVFlipped()){
			y += 5;
			y += yOffset;
			yOffset *= -1;
		}else{
			y -= 3;
		}


		charMesh.getTexCoords()[vC].set(posTexW,texY1);
		charMesh.getTexCoords()[vC+1].set(posTexW + widthTex,texY1);
		charMesh.getTexCoords()[vC+2].set(posTexW+widthTex,texY2);

		charMesh.getTexCoords()[vC+3].set(posTexW + widthTex,texY2);
		charMesh.getTexCoords()[vC+4].set(posTexW,texY2);
		charMesh.getTexCoords()[vC+5].set(posTexW,texY1);

		charMesh.getVertices()[vC].set(x,y);
		charMesh.getVertices()[vC+1].set(x+8,y);
		charMesh.getVertices()[vC+2].set(x+8,y+yOffset);

		charMesh.getVertices()[vC+3].set(x+8,y+yOffset);
		charMesh.getVertices()[vC+4].set(x,y+yOffset);
		charMesh.getVertices()[vC+5].set(x,y);
			
		vC += 6;
	}	
}
void ofxObjLoader::save(string path, ofMesh& mesh){
    path = ofToDataPath(path);
    
    GLuint writeMode = GLM_NONE;
    
    GLMmodel* m = new GLMmodel();
    if(mesh.getNumVertices() > 0){
        m->numvertices = mesh.getNumVertices();
	    m->vertices = new GLfloat[m->numvertices*3+1];
        memcpy(&m->vertices[3], &mesh.getVertices()[0].x, sizeof(ofVec3f) * mesh.getNumVertices());
    }
    else {
        ofLogError("ofxObjLoader::save -- No vertices to save!");
        return;
    }
    
    if(mesh.getNumNormals() > 0){
        m->numnormals = mesh.getNumNormals();
        m->normals = new GLfloat[m->numnormals*3+1];
        memcpy(&m->normals[3], &mesh.getNormals()[0].x, sizeof(ofVec3f)*mesh.getNumNormals());
        writeMode |= GLM_SMOOTH;
    }
	
    if(mesh.getNumTexCoords() > 0){
        m->numtexcoords = mesh.getNumTexCoords();
        m->texcoords = new GLfloat[m->numtexcoords*2+1];
        memcpy(&m->texcoords[2], &mesh.getTexCoords()[0].x, sizeof(ofVec2f)*mesh.getNumTexCoords());
        writeMode |= GLM_TEXTURE;
    }
    
    if(mesh.getNumIndices() > 0){
        //create triangles
		m->numtriangles = mesh.getNumIndices()/3;
        m->triangles = new GLMtriangle[m->numtriangles];
        
        //add them all to one group
        m->groups = new GLMgroup();
        m->groups->next = NULL;
        m->groups->material = NULL;
        string name = "ofMesh";
        m->groups->name = (char*)malloc(sizeof(char) * name.length()+1);
        strcpy(m->groups->name, name.c_str());
        
        m->groups->numtriangles = mesh.getNumIndices()/3;
		m->groups->triangles = new GLuint[m->groups->numtriangles];
        m->numgroups = 1;
        for(int i = 0; i < mesh.getNumIndices()/3; i++){
            memcpy(m->triangles[i].vindices, &mesh.getIndices()[i*3], sizeof(GLuint)*3);
            memcpy(m->triangles[i].nindices, &mesh.getIndices()[i*3], sizeof(GLuint)*3);
            memcpy(m->triangles[i].tindices, &mesh.getIndices()[i*3], sizeof(GLuint)*3);
            m->groups->triangles[i] = i;
        }
    }
    
    glmWriteOBJ(m, (char*)path.c_str(), writeMode);
    glmDelete(m);
}
//---------------------------------------------------------------------
void ofDrawBitmapCharacterStart(int stringLength){
	charMesh.getVertices().resize(6 * stringLength);
	charMesh.getTexCoords().resize(6 * stringLength);

	if(!bBitmapTexturePrepared){
		prepareBitmapTexture();
	}
	
	vC = 0;
}
//---------------------------------------------------------------------
static void addBitmapCharacter(ofMesh & charMesh, int & vertexCount, int character, int x , int y, bool vFlipped){
	if (character < 128) {		

		float posTexW = (float)(character % 16)/16.0f;
		float posTexH = ((int)(character / 16.0f))/16.0f;

		float texY1 = posTexH;
		float texY2 = posTexH+heightTex;

		//TODO: look into a better fix.
		//old ofDrawBitmapString was 3 pixels higher, so this version renders text in a different position.
		//3 pixel adjustment corrects that when y is flpped 5 when it's not.
		int yOffset = 14;
		if(!vFlipped){
			y += 5;
			y += yOffset;
			yOffset *= -1;
		}else{
			y -= 3;
		}

		size_t vC = vertexCount;
		charMesh.getTexCoords()[vC] = {posTexW,texY1};
		charMesh.getTexCoords()[vC+1] = {posTexW + widthTex,texY1};
		charMesh.getTexCoords()[vC+2] = {posTexW+widthTex,texY2};

		charMesh.getTexCoords()[vC+3] = {posTexW + widthTex,texY2};
		charMesh.getTexCoords()[vC+4] = {posTexW,texY2};
		charMesh.getTexCoords()[vC+5] = {posTexW,texY1};

		charMesh.getVertices()[vC] = glm::vec3(x,y,0.f);
		charMesh.getVertices()[vC+1] = glm::vec3(x+8,y,0.f);
		charMesh.getVertices()[vC+2] = glm::vec3(x+8,y+yOffset,0.f);

		charMesh.getVertices()[vC+3] = glm::vec3(x+8,y+yOffset,0.f);
		charMesh.getVertices()[vC+4] = glm::vec3(x,y+yOffset,0.f);
		charMesh.getVertices()[vC+5] = glm::vec3(x,y,0.f);

		vertexCount += 6;
	}	
}
Beispiel #8
0
void addForheadToFaceMesh(ofMesh & input){
	
	if (input.getVertices().size() != 66) return;
	
	static int forehead[10] = {0,17,18,19,20,/*21,22,*/23,24,25,26,16};		// skipping 21 and 22 because there is a triangle that overlaps somehow
	ofPoint extras[10];
	ofVec2f texture[10];
	
	for (int i = 0; i < 10; i++){
		extras[i] = input.getVertices()[forehead[i]] + (input.getVertices()[27] - input.getVertices()[33]);
		texture[i] = input.getTexCoords()[forehead[i]] + (input.getTexCoords()[27] - input.getTexCoords()[33]);
		input.addVertex(extras[i]);
		input.addTexCoord(texture[i]);				 
	}
	
	for (int i = 0; i < (10-1); i++){
	
		// a b c
		// b c d;
		
		int a = forehead[i];
		int b = 66 + i;
		int c = forehead[i+1];
		
		input.addIndex(a);
		input.addIndex(b);
		input.addIndex(c);
		
		int d = 66 + i + 1;
		
		input.addIndex(b);
		input.addIndex(c);
		input.addIndex(d);
		
	}
	
}
Beispiel #9
0
void ofxMesh::fromMesh(const ofMesh & mesh){
    if (mesh.hasVertices()) {
        getVertices()=mesh.getVertices();
    }
    if (mesh.hasColors()) {
        getColors()=mesh.getColors();
    }
    if (mesh.hasNormals()) {
        getNormals()=mesh.getNormals();
    }
    if (mesh.hasTexCoords()) {
        getTexCoords()=mesh.getTexCoords();
    }
    if (mesh.hasIndices()) {
        getIndices()=mesh.getIndices();
    }
}
Beispiel #10
0
void ofxMesh::toMesh(ofMesh & mesh){
    mesh.clear();
    if (hasVertices()) {
        mesh.getVertices()=getVertices();
    }
    if (hasColors()) {
        mesh.getColors()=getColors();
    }
    if (hasNormals()) {
        mesh.getNormals()=getNormals();
    }
    if (hasTexCoords()) {
        mesh.getTexCoords()=getTexCoords();
    }
    if (hasIndices()) {
        mesh.getIndices()=getIndices();
    }
}
Beispiel #11
0
glmMesh toGlm(const ofMesh &_mesh){
    glmMesh mesh;
    
    for (auto &it : _mesh.getColors()) {
        mesh.addColor(toGlm(it));
    }
    
    for (auto &it : _mesh.getVertices()) {
        mesh.addVertex(toGlm(it));
    }
    
    for (auto &it : _mesh.getNormals()) {
        mesh.addNormal(toGlm(it));
    }
    
    for (auto &it : _mesh.getTexCoords()) {
        mesh.addTexCoord(toGlm(it));
    }
    
    for (auto &it : _mesh.getIndices()) {
        mesh.addIndex(toGlm(it));
    }
    
    GLenum drawMode = ofGetGLPrimitiveMode(_mesh.getMode());
    if (drawMode == GL_POINTS) {
        mesh.setDrawMode(POINTS);
    } else if (drawMode == GL_LINES){
        mesh.setDrawMode(LINES);
    } else if (drawMode == GL_LINE_STRIP){
        mesh.setDrawMode(LINE_STRIP);
    } else if (drawMode == GL_TRIANGLES){
        mesh.setDrawMode(TRIANGLES);
    } else if (drawMode == GL_TRIANGLE_STRIP){
        mesh.setDrawMode(TRIANGLE_STRIP);
    }
    
    
    
    return mesh;
}
void CloudsVisualSystem3DModelLoader::facetMesh( ofMesh& smoothedMesh, ofMesh& targetMesh )
{
	//get our vertex, uv and face info
	vector<ofVec3f>& v = smoothedMesh.getVertices();
	vector<ofVec2f>& uv = smoothedMesh.getTexCoords();
	vector<ofIndexType>& indices = smoothedMesh.getIndices();
	bool hasTC = smoothedMesh.getNumTexCoords();
	
	//use these to store our new mesh info
	vector<ofVec3f> facetedVertices( indices.size() );
	vector<ofVec3f> facetedNormals( indices.size() );
	vector<ofVec2f> facetedTexCoords;
	if(hasTC){
		facetedTexCoords.resize( indices.size() );
	}
	vector<ofIndexType> facetedIndices( indices.size() );
	
	//store vertex and uv data
	for (int i=0; i < indices.size(); i++) {
		facetedIndices[i] = i;
		facetedVertices[i] = v[indices[i]];
		if(hasTC)	facetedTexCoords[i] = uv[indices[i]];
	}
	
	//calculate our face normals
	ofVec3f n;
	for (int i=0; i < facetedIndices.size(); i+=3) {
		n = normalFrom3Points( facetedVertices[i], facetedVertices[i+1], facetedVertices[i+2]);
		facetedNormals[i] = n;
		facetedNormals[i+1] = n;
		facetedNormals[i+2] = n;
	}
	
	//setup our faceted mesh. this should still work if our targetMesh is our smoothMesh
	targetMesh.clear();
	targetMesh.addVertices( facetedVertices );
	targetMesh.addNormals( facetedNormals );
	if(hasTC)	targetMesh.addTexCoords( facetedTexCoords );
	targetMesh.addIndices( facetedIndices );
}
        //--------------------------------------------------------------
        void save(const string& path, const ofMesh& mesh)
        {
            ofFile file(path, ofFile::WriteOnly, true);

            int numVerts = mesh.getNumVertices();
            file.write((char *)(&numVerts), sizeof(int));
            if (numVerts > 0) {
                file.write((char *)(&(mesh.getVertices())[0]), sizeof(ofPoint) * numVerts);
            }

            int numNormals = mesh.getNumNormals();
            file.write((char *)(&numNormals), sizeof(int));
            if (numNormals > 0) {
                file.write((char *)(&(mesh.getNormals())[0]), sizeof(ofPoint) * numNormals);
            }

            int numTexCoords = mesh.getNumTexCoords();
            file.write((char *)(&numTexCoords), sizeof(int));
            if (numTexCoords > 0) {
                file.write((char *)(&(mesh.getTexCoords())[0]), sizeof(ofVec2f) * numTexCoords);
            }

            int numColors = mesh.getNumColors();
            file.write((char *)(&numColors), sizeof(int));
            if (numColors > 0) {
                file.write((char *)(&(mesh.getColors())[0]), sizeof(ofFloatColor) * numColors);
            }

            int numIndices = mesh.getNumIndices();
            file.write((char *)(&numIndices), sizeof(int));
            if (numIndices > 0) {
                file.write((char *)(&(mesh.getIndices())[0]), sizeof(ofIndexType) * numIndices);
            }

            file.close();
        }
Beispiel #14
0
vector<float> Model::generateTangents(ofMesh& mesh) {
	// Tangent generation adapted from algorithm at http://www.terathon.com/code/tangent.html
	auto vertices = mesh.getVertices();
	auto normals = mesh.getNormals();
	auto texcoords = mesh.getTexCoords();
	auto triangles = mesh.getIndices();

	vector<float> tangents(vertices.size()*4);

	vector<ofVec3f> tan1(vertices.size(), ofVec3f(0,0,0));
	vector<ofVec3f> tan2(vertices.size(), ofVec3f(0,0,0));

	for (unsigned int i = 0; i < triangles.size(); i += 3) {
		long i1 = triangles[i];
		long i2 = triangles[i+1];
		long i3 = triangles[i+2];

		const ofVec3f& v1 = vertices[i1];
		const ofVec3f& v2 = vertices[i2];
		const ofVec3f& v3 = vertices[i3];

		const ofVec2f& w1 = texcoords[i1];
		const ofVec2f& w2 = texcoords[i2];
		const ofVec2f& w3 = texcoords[i3];

		float x1 = v2.x - v1.x;
		float x2 = v3.x - v1.x;
		float y1 = v2.y - v1.y;
		float y2 = v3.y - v1.y;
		float z1 = v2.z - v1.z;
		float z2 = v3.z - v1.z;

		float s1 = w2.x - w1.x;
		float s2 = w3.x - w1.x;
		float t1 = w2.y - w1.y;
		float t2 = w3.y - w1.y;

		float r = 1.0F / (s1 * t2 - s2 * t1);
		ofVec3f sdir((t2 * x1 - t1 * x2) * r, 
					 (t2 * y1 - t1 * y2) * r,
					 (t2 * z1 - t1 * z2) * r);
		ofVec3f tdir((s1 * x2 - s2 * x1) * r,
					 (s1 * y2 - s2 * y1) * r,
					 (s1 * z2 - s2 * z1) * r);

		tan1[i1] += sdir;
		tan1[i2] += sdir;
		tan1[i3] += sdir;

		tan2[i1] += tdir;
		tan2[i2] += tdir;
		tan2[i3] += tdir;
	}

	for (unsigned int i = 0; i < vertices.size(); ++i) {
		ofVec3f& n = normals[i];
		ofVec3f& t = tan1[i];

		// Gram-Schmidt orthogonalize
		auto tangent = (t - n * n.dot(t)).normalize();
		// Calculate handedness
		float w = (n.cross(t).dot(tan2[i]) < 0.0) ? -1.0 : 1.0;

		tangents[i*4] = tangent.x;
		tangents[i*4+1] = tangent.y;
		tangents[i*4+2] = tangent.z;
		tangents[i*4+3] = w;
	}

	return tangents;
}
void CloudsVisualSystem3DModelLoader::smoothMesh( ofMesh& facetedMesh, ofMesh& targetMesh, int precision)
{
	cout << "smoothing mesh" << endl;
	
	//get our vertex, uv and face info
	vector<ofVec3f>& v = facetedMesh.getVertices();
	vector<ofVec2f>& uv = facetedMesh.getTexCoords();
	vector<ofIndexType>& indices = facetedMesh.getIndices();
	bool hasTC = facetedMesh.getNumTexCoords();
	
	//use these to store our new mesh info
	map<string, unsigned int> mergeMap;
	vector<ofVec3f> smoothVertices;
	vector<ofVec3f> smoothNormals;
	vector<ofVec2f> smoothTexCoords;
	vector<ofIndexType> smoothIndices;
	
	//merge our vertices by pointing near by vertices to the same index
	for (int i=0; i<v.size(); i++)
	{
		mergeMap[ vec3ToString( v[i], precision ) ] = i;
	}
	
	//fill our smoothed vertex array with merged vertices & tex coords
	smoothVertices.resize( mergeMap.size() );
	if(hasTC)	smoothTexCoords.resize( mergeMap.size() );
	int smoothVertexCount = 0;
	for (map<string, unsigned int>::iterator it = mergeMap.begin(); it != mergeMap.end(); it++)
	{
		smoothVertices[smoothVertexCount] = v[it->second];
		if(hasTC)	smoothTexCoords[smoothVertexCount] = uv[it->second];
		it->second = smoothVertexCount;//store our new vertex index
		smoothVertexCount++;
	}
	
	
	//reconstruct our faces by reassigning their indices to the merged vertices
	smoothIndices.resize( indices.size() );
	for (int i=0; i<indices.size(); i++)
	{
		//use our old vertex poisition to retrieve our new index
		smoothIndices[i] = mergeMap[ vec3ToString( v[ indices[i] ], precision ) ];
	}
	
	//calculate our normals
	smoothNormals.resize( smoothVertices.size() );
	ofVec3f n;
	for (int i=0; i<smoothIndices.size(); i+=3)
	{
		n = normalFrom3Points( smoothVertices[smoothIndices[i]], smoothVertices[smoothIndices[i+1]], smoothVertices[smoothIndices[i+2]] );
		smoothNormals[smoothIndices[i]] += n;
		smoothNormals[smoothIndices[i+1]] += n;
		smoothNormals[smoothIndices[i+2]] += n;
	}
	
	for (int i=0; i<smoothNormals.size(); i++)
	{
		smoothNormals[i].normalize();
	}
	
	//setup our smoothed mesh. this should still work if our targetMesh is our facetedMesh
	targetMesh.clear();
	targetMesh.addVertices( smoothVertices );
	targetMesh.addNormals( smoothNormals );
	if(hasTC)	targetMesh.addTexCoords( smoothTexCoords );
	targetMesh.addIndices( smoothIndices );
}