void ofxNDCircularGradient(float radius, const ofColor & start, const ofColor & end) { int n = 32; // circular gradient resolution static ofMesh _nd_cg_mesh; _nd_cg_mesh.clear(); _nd_cg_mesh.setMode(OF_PRIMITIVE_TRIANGLE_FAN); ofVec2f center(0,0); _nd_cg_mesh.addVertex(center); float angleBisector = TWO_PI / (n * 2); float smallRadius = radius; float bigRadius = smallRadius / cos(angleBisector); for(int i = 0; i <= n; i++) { float theta = i * TWO_PI / n; _nd_cg_mesh.addVertex(center + ofVec2f(sin(theta), cos(theta)) * bigRadius); } _nd_cg_mesh.clearColors(); _nd_cg_mesh.addColor(start); for(int i = 0; i <= n; i++) { _nd_cg_mesh.addColor(end); } _nd_cg_mesh.draw(); }
void MeshHelper::fuseNeighbours( ofMesh& outputMesh, const ofMesh& sourceMesh, float fuseDistance ) { //@todo tex coords, normals assert( sourceMesh.getMode() == OF_PRIMITIVE_TRIANGLES ); if ( fuseDistance < 0 ) { // fuse close-enough vertices // first define 'close enough' as 1/10000 of smallest dimension of the bounding box width/height/depth ofVec3f tlb, brf; // top left back, bottom right front calculateAABoundingBox( sourceMesh, tlb, brf ); float minDimension = min(brf.x-tlb.x,min(brf.y-tlb.y, brf.z-tlb.z)); fuseDistance = minDimension * 0.00001f; } // now fuse map<int,int> fused; vector<ofVec3f> vertices; for ( int i=0; i<sourceMesh.getNumVertices(); i++ ) { const ofVec3f& vertex = sourceMesh.getVertex(i); //vertex.rotate(10, 10, 10); bool didFuse = false; for ( int j=0; j<vertices.size(); j++ ) { if ( (vertex-vertices[j]).length()<fuseDistance ) { // fuse i to j fused[i] = j; didFuse = true; break; } } if ( !didFuse ) { vertices.push_back( vertex ); fused[i] = vertices.size()-1; } } // build the output mesh outputMesh.clear(); outputMesh.addVertices(vertices); if ( sourceMesh.getNumIndices() > 0 ) { // walk through indices to build up the new mesh const vector<ofIndexType>& indices = sourceMesh.getIndices(); for ( int i=0; i<indices.size(); i+=3 ) { assert( fused.find( indices[i] ) != fused.end() ); assert( fused.find( indices[i+1] ) != fused.end() ); assert( fused.find( indices[i+2] ) != fused.end() ); outputMesh.addTriangle( fused[indices[i]], fused[indices[i+1]], fused[indices[i+2]] ); } } else { // triangles are just triples of vertices for ( int i=0; i<sourceMesh.getNumVertices(); i+=3 ) { outputMesh.addTriangle( fused[i], fused[i+1], fused[i+2] ); } } ofLogNotice("MeshHelper") << "fuseNeighbours: input " << sourceMesh.getNumVertices() << " vertices/" << sourceMesh.getNumIndices() << " indices, output " << outputMesh.getNumVertices() << " vertices/" << outputMesh.getNumIndices() << " indices"; }
//-------------------------------------------------------------- void testApp::draw(){ fbo.begin(); ofSetTextureWrap(GL_REPEAT,GL_REPEAT); fbfbo.draw(0,2); //cam.draw(0,0); fbfbo.getTextureReference().bind(); trik2.draw(); fbfbo.getTextureReference().unbind(); ofSetColor(255,255,255); if(tritimer>tritimerlimit){ float xpt, ypt,xtoff,ytoff; //draw gradient splashes ofMesh trik; for(int b = 0;b<5;b++){ xtoff = ofRandomf()*0.5; ytoff = ofRandomf()*0.5; for(int i=0;i<3;i++){ xpt = ofRandomuf()*2+xtoff; ypt = ofRandomuf()*2+ytoff; trik.addVertex(ofVec3f(xpt*w,ypt*h,0)); trik.addColor(ofFloatColor(float(ofRandomuf()>0.5)*0.6+0.4,float(ofRandomuf()>0.5)*0.5+0.5,float(ofRandomuf()>0.5)*0.7+0.3)); } } trik.draw(); tritimer = 0; tritimerlimit= ofRandom(20,200); } if(tritimer2>45){ //re-generate the feedback triangles float xpt, ypt,xoff,yoff,xtoff,ytoff; trik2.clear(); //ofEnableNormalizedTexCoords(); for(int b = 0;b<5;b++){ xoff = ofRandomf()*0.1; yoff = ofRandomf()*0.1; xtoff = ofRandomf()*0.5; ytoff = ofRandomf()*0.5; for(int i=0;i<3;i++){ xpt = ofRandomuf()+xtoff; ypt = ofRandomuf()+ytoff; trik2.addVertex(ofVec3f((xpt+xoff)*w,(ypt+yoff)*h,0)); trik2.addTexCoord(ofVec2f(xpt*w,ypt*h)); trik2.addColor(ofFloatColor(1,1,1)); } } tritimer2=0; tritimer2limit= ofRandom(20,200); //ofDisableNormalizedTexCoords(); } fbo.end(); fbfbo.begin(); fbo.draw(0,0); fbfbo.end(); fbo.draw(0,0); }
void update() { int n = mesh.getNumVertices(); int start = ofMap(mouseX, 0, ofGetWidth(), 0, n, true); controlPoints.clear(); controlPoints.setMode(OF_PRIMITIVE_POINTS); for(int i = start; i < n; i++) { unsigned int index = rankedCorners[i]; controlPoints.addVertex(mesh.getVertex(index)); } }
OFX_OBJLOADER_BEGIN_NAMESPACE void load(string path, ofMesh& mesh, bool generateNormals, bool flipFace) { path = ofToDataPath(path); mesh.clear(); GLMmodel* m; m = glmReadOBJ((char*)path.c_str()); if (generateNormals) { glmFacetNormals(m); glmVertexNormals(m, 90); } if (flipFace) { glmReverseWinding(m); } for (int j = 0; j < m->numtriangles; j++) { const GLMtriangle &tri = m->triangles[j]; for (int k = 0; k < 3; k++) { GLfloat *v = m->vertices + (tri.vindices[k] * 3); mesh.addVertex(ofVec3f(v[0], v[1], v[2])); if (m->colors) { GLfloat *c = m->colors + (tri.vindices[k] * 3); mesh.addColor(ofFloatColor(c[0], c[1], c[2])); } if (m->normals && ofInRange(tri.nindices[k], 0, m->numnormals)) { GLfloat *n = m->normals + (tri.nindices[k] * 3); mesh.addNormal(ofVec3f(n[0], n[1], n[2])); } if (m->texcoords && ofInRange(tri.tindices[k], 0, m->numtexcoords)) { GLfloat *c = m->texcoords + (tri.tindices[k] * 2); mesh.addTexCoord(ofVec2f(c[0], c[1])); } } } glmDelete(m); }
//---------------------------------------- void ofGenerateSphereMesh( ofMesh& _mesh, float _radius, int _numRings, int _numSegments ){ cout << "*** ofGenerateSphereMesh ***" << endl; _mesh.clear(); float uTile = 1.0f; // Texcoord tiling, do we want to support that? float vTile = 1.0f; float fDeltaRingAngle = (PI / _numRings); float fDeltaSegAngle = (TWO_PI / _numSegments); int offset = 0; // Generate the group of rings for the sphere for(unsigned int ring = 0; ring <= _numRings; ring++ ) { float r0 = _radius * sinf (ring * fDeltaRingAngle); float y0 = _radius * cosf (ring * fDeltaRingAngle); // Generate the group of segments for the current ring for(unsigned int seg = 0; seg <= _numSegments; seg++) { float x0 = r0 * sinf(seg * fDeltaSegAngle); float z0 = r0 * cosf(seg * fDeltaSegAngle); // Add one vertex to the strip which makes up the sphere ofVec3f pos(x0, y0, z0); _mesh.addVertex( pos ); _mesh.addNormal( pos.getNormalized() ); if( ofGetPrimitiveGenerateTexCoords() ){ //for (unsigned int tc=0;tc<numTexCoordSet;tc++) _mesh.addTexCoord( ofVec2f( (float) seg / (float)_numSegments * uTile, (float) ring / (float)_numRings * vTile ) ); } if (ring != _numRings) { // each vertex (except the last) has six indices pointing to it _mesh.addIndex(offset + _numSegments); _mesh.addIndex(offset); _mesh.addIndex(offset + _numSegments + 1); _mesh.addIndex(offset); _mesh.addIndex(offset + 1); _mesh.addIndex(offset + _numSegments + 1); offset ++; } }; // end for seg } // end for ring }
void update() { ofVec2f cur(mouseX, mouseY); historyMesh.addVertex(cur); vector<ofVec2f*> neighbors = data.getNeighborsRatio(cur, .1); neighborsMesh.clear(); for(int i = 0; i < neighbors.size(); i++) { neighborsMesh.addVertex(*neighbors[i]); } float minimumDistance = getMinimumDistance(cur, neighbors); if(neighbors.size() == 0 || minimumDistance > 16) { data.add(cur, cur); dataMesh.addVertex(cur); } }
//-------------------------------------------------------------- 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; }
void update() { mesh.clear(); float t = ofGetElapsedTimef() * 0.3; float noise_scale = 0.05; float size = 300; float shape_size = 200; int num = 100; for (int i = 0; i < num; i++) { ofVec3f base(ofSignedNoise(10, 0, 0, i * noise_scale + t), ofSignedNoise(0, 10, 0, i * noise_scale + t), ofSignedNoise(0, 0, 10, i * noise_scale + t)); ofVec3f v0(ofSignedNoise(1, 0, 0, i * noise_scale + t), ofSignedNoise(0, 1, 0, i * noise_scale + t), ofSignedNoise(0, 0, 1, i * noise_scale + t)); ofVec3f v1(ofSignedNoise(2, 0, 0, i * noise_scale + t), ofSignedNoise(0, 2, 0, i * noise_scale + t), ofSignedNoise(0, 0, 2, i * noise_scale + t)); ofVec3f v2(ofSignedNoise(3, 0, 0, i * noise_scale + t), ofSignedNoise(0, 3, 0, i * noise_scale + t), ofSignedNoise(0, 0, 3, i * noise_scale + t)); float hue = ofMap(i, 0, num, 0, 1); ofFloatColor c = ofFloatColor::fromHsb(hue, 1, 1); float s = fabs(sin(i * 0.1 + t)) + 0.1; mesh.addColor(c); mesh.addColor(c); mesh.addColor(c); mesh.addVertex(base * size + v0 * shape_size * s); mesh.addVertex(base * size + v1 * shape_size * s); mesh.addVertex(base * size + v2 * shape_size * s); } IndexColor::convertColorToTexCoord(mesh); // export to abc abc_out.addPolyMesh("/mesh", mesh); }
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(); } }
void ofxObjLoader::load(string path, ofMesh& mesh, bool generateNormals) { path = ofToDataPath(path); mesh.clear(); GLMmodel* m; m = glmReadOBJ((char*)path.c_str()); if(generateNormals){ glmFacetNormals(m); glmVertexNormals(m, 90); } GLfloat *v, *n, *c; for(int i = 1; i <= m->numvertices; i++){ v = &m->vertices[3 * i]; mesh.addVertex(ofVec3f(v[0], v[1], v[2])); } for(int i = 1; i <= m->numnormals; i++){ n = &m->normals[3 * i]; mesh.addNormal(ofVec3f(n[0], n[1], n[2])); } for(int i = 1; i <= m->numtexcoords; i++){ c = &m->texcoords[2 * i]; mesh.addTexCoord(ofVec2f(c[0], c[1])); } for (int i = 0; i < m->numtriangles; i++) { GLMtriangle &t = m->triangles[i]; //NOTE: ofMesh does not have support for different indices for tex coords and mormals mesh.addIndex(t.vindices[0]); mesh.addIndex(t.vindices[1]); mesh.addIndex(t.vindices[2]); } glmDelete(m); return mesh; }
//---------------------------------------------------------- void ofTessellator::performTessellation(ofPolyWindingMode polyWindingMode, ofMesh& dstmesh, bool bIs2D ) { if (!tessTesselate(cacheTess, polyWindingMode, TESS_POLYGONS, 3, 3, 0)){ ofLogError("ofTessellator") << "performTessellation(): mesh polygon tessellation failed, winding mode " << polyWindingMode; return; } int numVertices = tessGetVertexCount( cacheTess ); int numIndices = tessGetElementCount( cacheTess )*3; dstmesh.clear(); dstmesh.addVertices((ofDefaultVertexType*)tessGetVertices(cacheTess),numVertices); dstmesh.addIndices((ofIndexType*)tessGetElements(cacheTess),numIndices); /*ofIndexType * tessElements = (ofIndexType *)tessGetElements(cacheTess); for(int i=0;i<numIndices;i++){ if(tessElements[i]!=TESS_UNDEF) dstmesh.addIndex(tessElements[i]); }*/ dstmesh.setMode(OF_PRIMITIVE_TRIANGLES); }
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 Helix::generateVertices(std::deque<ofVec3f>& spine, ofMesh& vertices) { vertices.clear(); std::vector<ofVec3f> points; for(int i = 1; i < spine.size(); ++i) { ofVec3f& a0 = spine[i-1]; ofVec3f& a2 = spine[i]; ofVec3f t = a2 - a0; ofVec3f c(0.0f, a0.y, 0.0f); // <-- we could use one spine in the center and swirl around that ofVec3f perp = a0 - c; perp.normalize(); perp *= ribbon_thickness; ofVec3f diry = perp.getCrossed(t); //cross(perp, t); diry.normalize(); diry *= ribbon_height; points.push_back((a0 - perp) - diry); points.push_back((a0 + perp) - diry); points.push_back((a2 + perp) + diry); points.push_back((a2 - perp) + diry); } int num_slices = points.size() / 4; for(int i = 0; i < num_slices - 1; ++i) { int dx = i * 4; ofVec3f& a0 = points[dx + 0]; ofVec3f& a3 = points[dx + 3]; ofVec3f& a4 = points[dx + 4]; vertices.addVertex(a0); vertices.addVertex(a3); } }
//from ofSetSphereResolution void testApp::buildSphereMesh(int radius, int res, ofMesh & sphereMesh) { int n = res * 2; float ndiv2=(float)n/2; /* Original code by Paul Bourke A more efficient contribution by Federico Dosil (below) Draw a point for zero radius spheres Use CCW facet ordering http://paulbourke.net/texture_colour/texturemap/ */ float theta2 = TWO_PI; float phi1 = -HALF_PI; float phi2 = HALF_PI; // float r = 1.f; // normalize the verts float r = radius; sphereMesh.clear(); //sphereMesh.setMode(OF_PRIMITIVE_TRIANGLE_STRIP); int i, j; float theta1 = 0.f; float jdivn,j1divn,idivn,dosdivn,unodivn=1/(float)n,t1,t2,t3,cost1,cost2,cte1,cte3; cte3 = (theta2-theta1)/n; cte1 = (phi2-phi1)/ndiv2; dosdivn = 2*unodivn; ofVec3f e,p,e2,p2; if (n < 0){ n = -n; ndiv2 = -ndiv2; } if (n < 4) {n = 4; ndiv2=(float)n/2;} if(r <= 0) r = -r; t2=phi1; cost2=cos(phi1); j1divn=0; ofVec3f vert, normal; ofVec2f tcoord; for (j=0;j<ndiv2;j++) { t1 = t2; t2 += cte1; t3 = theta1 - cte3; cost1 = cost2; cost2 = cos(t2); e.y = sin(t1); e2.y = sin(t2); p.y = r * e.y; p2.y = r * e2.y; idivn=0; jdivn=j1divn; j1divn+=dosdivn; for (i=0;i<=n;i++) { t3 += cte3; e.x = cost1 * cos(t3); e.z = cost1 * sin(t3); p.x = r * e.x; p.z = r * e.z; normal.set( e.x, e.y, e.z ); tcoord.set( idivn, jdivn); vert.set( p.x, p.y, p.z ); sphereMesh.addNormal(normal); sphereMesh.addTexCoord(tcoord); sphereMesh.addVertex(vert); e2.x = cost2 * cos(t3); e2.z = cost2 * sin(t3); p2.x = r * e2.x; p2.z = r * e2.z; normal.set(e2.x, e2.y, e2.z); tcoord.set(idivn, j1divn); vert.set(p2.x, p2.y, p2.z); sphereMesh.addNormal(normal); sphereMesh.addTexCoord(tcoord); sphereMesh.addVertex(vert); idivn += unodivn; } } }
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 ); }
void ofApp::createSegmentedMeshTriangles(const ofVec3f& center, ofMesh &mesh, double radius, double limitH, int textWidth, int textHeight) //using triangles only { int h, drawH, drawW, w; int divNumber = 32; double theta, phi, phi_1, limitW; ofVec3f p; mesh.clear(); //Handle special cases if (radius < 0) radius = -radius; if (precision < 0) precision = -precision; if (precision < 4 || radius <= 0) { mesh.addVertex(center); return; } mesh.setMode(OF_PRIMITIVE_TRIANGLES); //limitH = 3.14 / (double) hDivNumber; limitW = limitH * (textWidth/(double)textHeight); drawH = textHeight / divNumber; drawW = textWidth / divNumber; for(h = 0; h < drawH; h++) //create the mesh { phi = (((h * divNumber) * limitH)/(double) textHeight) + (1.57079632679 - (limitH/ (double )2)); //phi_1 = (((h+1) * limitH)/(double) textHeight) + (1.57079632679 - (limitH/ (double )2)); for(w = 1; w <= drawW; w++) //count forward { theta = (limitW * (w * divNumber)) / (double) textWidth + (1.57079632679 - (limitW/ (double )2)); p.x = radius*cos(theta)*sin(phi); p.y = radius* sin(theta)*sin(phi); p.z = radius*cos(phi); /*p.x = w; p.y = 2; p.z = h;*/ mesh.addTexCoord(ofVec2f((w*divNumber), (h*divNumber))); mesh.addVertex(p); } } /*for (int y = 0; y<drawH; y = y+1){ for (int x=0; x<drawW; x = x + 1){ const ofIndexType texIndex = static_cast<ofIndexType>(x + y*drawW); mesh.setTexCoord(texIndex, ofVec2f((w*divNumber), (h*divNumber))); } }*/ //mesh.clearIndices(); for (int y = 0; y<drawH-1; y = y+1){ for (int x=0; x<drawW-1; x++){ mesh.addIndex(x+y*drawW); // 0 mesh.addIndex(x+(y+1)*drawW); // 10 mesh.addIndex((x+1)+(y+1)*drawW); // 11 // mesh.addIndex(x); // 0 //mesh.addIndex(x+drawW); // 10 //mesh.addIndex((x+1)+drawW); // 11 mesh.addIndex((x+1)+y*drawW); // 1 mesh.addIndex(x+y*drawW); // 0 mesh.addIndex((x+1)+(y+1)*drawW); // 11 } } }
/* Old, beta function, use the triangle funtion now */ void ofApp::createSegmentedMeshMine(const ofVec3f& center, ofMesh &mesh, double radius, int textWidth, int textHeight) { //uses triangle strips int h, hTemp, w; double theta, phi, phi_1, limitH, limitW; ofVec3f p; mesh.clear(); //Handle special cases if (radius < 0) radius = -radius; if (precision < 0) precision = -precision; if (precision < 4 || radius <= 0) { mesh.addVertex(center); return; } //mesh.setupIndicesAuto(); textWidth = textWidth / 4; textHeight = textHeight / 4; mesh.setMode( OF_PRIMITIVE_TRIANGLE_STRIP); limitH = 3.14 / (double) 3; limitW = limitH * (textWidth/(double)textHeight); for(hTemp = 0; hTemp < textHeight-1; hTemp = hTemp+2) { h = hTemp; //phi = (h * 3.141)/(double) textHeight; //phi_1 = ((h+1) * 3.141)/(double) textHeight; phi = ((h * limitH)/(double) textHeight) + (1.57079632679 - (limitH/ (double )2)); phi_1 = (((h+1) * limitH)/(double) textHeight) + (1.57079632679 - (limitH/ (double )2)); for(w = 0; w <= textWidth; w++) //count forward { theta = (limitW * w) / (double) textWidth + (1.57079632679 - (limitW/ (double )2)); // p.x = radius * cos(theta); //p.y = h; //p.z = radius * sin(theta); p.x = radius*cos(theta)*sin(phi); p.y = radius* sin(theta)*sin(phi); p.z = radius*cos(phi); mesh.addTexCoord(ofVec2f(4*w, 4*h)); mesh.addVertex(p); //p.x = radius *cos(theta); //p.y = h+1; //p.z = radius * sin(theta); p.x = radius*cos(theta)*sin(phi_1); p.y = radius* sin(theta)*sin(phi_1); p.z = radius*cos(phi_1); mesh.addTexCoord(ofVec2f(4*w, (4*h)+1)); mesh.addVertex(p); } h = hTemp+1; phi = ((h * limitH)/(double) textHeight) + (1.57079632679 - (limitH/ (double )2)); phi_1 = (((h+1) * limitH)/(double) textHeight) + (1.57079632679 - (limitH/ (double )2)); for(w = textWidth; w>=0; w--) //count backwards { theta = (limitW * w) / (double) textWidth + (1.57079632679 - (limitW/ (double )2)); p.x = radius*cos(theta)*sin(phi); p.y = radius* sin(theta)*sin(phi); p.z = radius*cos(phi); mesh.addTexCoord(ofVec2f(w, h)); mesh.addVertex(p); p.x = radius*cos(theta)*sin(phi_1); p.y = radius* sin(theta)*sin(phi_1); p.z = radius*cos(phi_1); mesh.addTexCoord(ofVec2f(w, h+1)); mesh.addVertex(p); } } }
void ofApp::createSegmentedMesh(const ofVec3f& center, ofMesh &mesh, double radius, int precision, int textWidth, int textHeight, double theta1, double theta2, double phi1, double phi2) { /* original funtion used as inspiration Create a sphere centered at c, with radius r, and precision n Draw a point for zero radius spheres Use CCW facet ordering Partial spheres can be created using theta1->theta2, phi1->phi2 in radians 0 < theta < 2pi, -pi/2 < phi < pi/2 */ int i,j; double t1,t2,t3; ofVec3f e,p; mesh.clear(); /* Handle special cases */ if (radius < 0) radius = -radius; if (precision < 0) precision = -precision; if (precision < 4 || radius <= 0) { mesh.addVertex(center); return; } for (j=0;j<precision/2;j++) { t1 = phi1 + j * (phi2 - phi1) / (precision/2); t2 = phi1 + (j + 1) * (phi2 - phi1) / (precision/2); mesh.setMode(OF_PRIMITIVE_POINTS ); //mesh.setMode( OF_PRIMITIVE_LINE_STRIP); for (i=0;i<=precision;i++) { t3 = theta1 + i * (theta2 - theta1) / precision; e.x = cos(t1) * cos(t3); e.y = sin(t1); e.z = cos(t1) * sin(t3); p.x = center.x + radius * e.x; p.y = center.y + radius * e.y; p.z = center.z + radius * e.z; mesh.addNormal(e); mesh.addTexCoord(ofVec2f( (i/(double)precision) * textWidth, textHeight - (2*j/(double)precision) * textHeight)); mesh.addVertex(p); e.x = cos(t2) * cos(t3); e.y = sin(t2); e.z = cos(t2) * sin(t3); p.x = center.x + radius * e.x; p.y = center.y + radius * e.y; p.z = center.z + radius * e.z; mesh.addNormal(e); mesh.addTexCoord(ofVec2f( (i/(double)precision) * textWidth, textHeight - (2*(j+1)/(double)precision) * textHeight)); mesh.addVertex(p); } } }