/** * Add a quad, using indices, with clockwise front face vertex order */ void addQuad(IndexType const bottomLeft, IndexType const topLeft, IndexType const topRight, IndexType const bottomRight) { mesh.addIndex(bottomLeft); mesh.addIndex(topLeft); mesh.addIndex(topRight); mesh.addIndex(topRight); mesh.addIndex(bottomRight); mesh.addIndex(bottomLeft); }
void ofxFaceTracker::addTriangleIndices(ofMesh& mesh) const { int in = tri.rows; for(int i = 0; i < tri.rows; i++) { int i0 = tri.it(i, 0), i1 = tri.it(i, 1), i2 = tri.it(i, 2); bool visible = getVisibility(i0) && getVisibility(i1) && getVisibility(i2); if(useInvisible || visible) { mesh.addIndex(i0); mesh.addIndex(i1); mesh.addIndex(i2); } } }
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 MeshHelper::appendMesh( ofMesh& targetMesh, const ofMesh& toAppend, bool fuse ) { ofIndexType indexOffset = targetMesh.getNumVertices(); targetMesh.addVertices( toAppend.getVertices() ); // append indices const vector<ofIndexType>& indices = toAppend.getIndices(); for ( int i=0; i<indices.size(); i++ ) { targetMesh.addIndex( indices[i]+indexOffset ); } if ( fuse ) fuseNeighbours(targetMesh); }
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); } }
//-------------------------------------------------------------- static void aiMeshToOfMesh(const aiMesh* aim, ofMesh& ofm, ofxAssimpMeshHelper * helper = NULL){ // default to triangle mode ofm.setMode(OF_PRIMITIVE_TRIANGLES); // copy vertices for (int i=0; i < (int)aim->mNumVertices;i++){ ofm.addVertex(ofVec3f(aim->mVertices[i].x,aim->mVertices[i].y,aim->mVertices[i].z)); } if(aim->HasNormals()){ for (int i=0; i < (int)aim->mNumVertices;i++){ ofm.addNormal(ofVec3f(aim->mNormals[i].x,aim->mNormals[i].y,aim->mNormals[i].z)); } } // aiVector3D * mTextureCoords [AI_MAX_NUMBER_OF_TEXTURECOORDS] // just one for now if(aim->GetNumUVChannels()>0){ for (int i=0; i < (int)aim->mNumVertices;i++){ if( helper != NULL && helper->texture.getWidth() > 0.0 ){ ofVec2f texCoord = helper->texture.getCoordFromPercent(aim->mTextureCoords[0][i].x ,aim->mTextureCoords[0][i].y); ofm.addTexCoord(texCoord); }else{ ofm.addTexCoord(ofVec2f(aim->mTextureCoords[0][i].x ,aim->mTextureCoords[0][i].y)); } } } //aiColor4D * mColors [AI_MAX_NUMBER_OF_COLOR_SETS] // just one for now if(aim->GetNumColorChannels()>0){ for (int i=0; i < (int)aim->mNumVertices;i++){ ofm.addColor(aiColorToOfColor(aim->mColors[0][i])); } } for (int i=0; i <(int) aim->mNumFaces;i++){ if(aim->mFaces[i].mNumIndices>3){ ofLog(OF_LOG_WARNING,"non-triangular face found: model face # " + ofToString(i)); } for (int j=0; j<(int)aim->mFaces[i].mNumIndices; j++){ ofm.addIndex(aim->mFaces[i].mIndices[j]); } } ofm.setName(string(aim->mName.data)); // ofm.materialId = aim->mMaterialIndex; }
//---------------------------------------- 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 ofxLSTriangle::generate(ofMesh& mesh, const ofxLSBranch branch, const float length){ //if you set offsetBetweenBranches to 0, all the triangles composing // the branch will start exactly where the previous one finish, // to make them look a bit more intricates, I've overlapped them a bit const int offsetBetweenBranches = 10; const int radius = branch.capSizes.first; const int scaledRadius = branch.capSizes.second; const float stepLenght = length; ofMatrix4x4 beginMatrix = branch.begin.getGlobalTransformMatrix(); ofMatrix4x4 endMatrix = branch.end.getGlobalTransformMatrix(); vector<ofVec3f> topValues; vector<ofVec3f> bottomValues; // create top and bottom points for (int i = 0; i < resolution; i++){ float theta = 2.0f * 3.1415926f * float(i) / float(resolution); float x = radius * cosf(theta); float z = radius * sinf(theta); float y = 0; ofVec3f circleBottom = ofVec3f(x, y-offsetBetweenBranches, z); bottomValues.push_back(circleBottom); float topX = scaledRadius * cosf(theta); float topZ = scaledRadius * sinf(theta); float topY = 0; ofVec3f circleTop = ofVec3f(topX, topY+offsetBetweenBranches, topZ); topValues.push_back(circleTop); } //random shuffle them random_shuffle(topValues.begin(), topValues.end()); random_shuffle(bottomValues.begin(), bottomValues.end()); int n_triangles = resolution; int firstIndex = mesh.getNumVertices(); float middleLength = stepLenght /2; for (unsigned int i = 0; i< (n_triangles*3); i += 3) { ofVec3f firstV = topValues.at(i/3); ofVec3f thirdV = bottomValues.at(i/3); ofVec3f secondV = bottomValues.at(i/3); //secondV.z = ofRandom(-scaledRadius, radius); secondV.y = ofRandom(middleLength -radius*2, middleLength + radius*2); mesh.addIndex(firstIndex +i); mesh.addIndex(firstIndex +i+1); mesh.addIndex(firstIndex +i+2); //find position AND direction of 2 vertices of the triangle; ofVec3f e1 = firstV - secondV; ofVec3f e2 = thirdV - secondV; //Use these 2 vertices to find the normal ofVec3f no = e2.cross( e1 ).normalize(); mesh.addVertex(firstV * endMatrix); mesh.addNormal(no); mesh.addVertex(secondV * (beginMatrix)); mesh.addNormal(no); mesh.addVertex(thirdV * beginMatrix); mesh.addNormal(no); } }
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 } } }
void ofxPolyvox::polyvoxToOfMesh(const PolyVox::SurfaceMesh<PositionMaterialNormal>& surfaceMesh, ofMesh& polyvxToOfMesh, bool setColor){ //Convienient access to the vertices and indices const vector<uint32_t>& vecIndices = surfaceMesh.getIndices(); const vector<PositionMaterialNormal>& vecVertices = surfaceMesh.getVertices();//surfaceMesh.getRawVertexData(); ofIndexType ofVecIndices; const void* pIndices = static_cast<const void*>(&(vecIndices[0])); int* indices = (int*)pIndices; vector<int> indx; for (int i = 0; i < surfaceMesh.getNoOfIndices(); i++ ){ indx.push_back(indices[i]); //cout << "indices:" << indices[i] << endl; polyvxToOfMesh.addIndex(indx[i]); } ofLog(OF_LOG_NOTICE, "ofMesh: number of indices is %d", polyvxToOfMesh.getNumIndices()); ofVec3f ofVecVertices; for (int i = 0; i < surfaceMesh.getNoOfVertices(); i++ ){ PositionMaterialNormal vert0 = vecVertices[i]; ofVecVertices = ofVec3f(vert0.getPosition().getX(),vert0.getPosition().getY(),vert0.getPosition().getZ()); polyvxToOfMesh.addVertex(ofVecVertices); } ofLog(OF_LOG_NOTICE, "ofMesh: number of vertices is %d", polyvxToOfMesh.getNumVertices()); ofVec3f ofVecNormals; for (int i = 0; i < surfaceMesh.getNoOfVertices(); i++ ){ PositionMaterialNormal vert0 = vecVertices[i]; ofVecNormals = ofVec3f(vert0.getNormal().getX(),vert0.getNormal().getY(),vert0.getNormal().getZ()); polyvxToOfMesh.addNormal(ofVecNormals); } ofLog(OF_LOG_NOTICE, "ofMesh: number of normals is %d", polyvxToOfMesh.getNumNormals()); if(setColor){ for (int i = 0; i < surfaceMesh.getNoOfVertices(); i++ ){ PositionMaterialNormal vert0 = vecVertices[i]; uint8_t material = static_cast<uint8_t>(vert0.getMaterial() + 0.5); //cout << "material:" << int(material) << endl; ofFloatColor colour = convertMaterialIDToColour(material); //cout << colour << endl; polyvxToOfMesh.addColor(colour); bool col = polyvxToOfMesh.hasColors(); //cout << "hasColors:" << col << endl; } } }