//-------------------------------------------------------------- void ofApp::setup(){ W = 100; H = 100; for (int y=0; y<H; y++) { for (int x=0; x<W; x++) { mesh.addVertex( ofPoint( (x - W/2) * 6, (y - H/2) * 6, 0 ) ); mesh.addColor( ofColor( 0, 0, 0 ) ); } } //Set up vertices and colors //Set up triangles' indices for (int y=0; y<H-1; y++) { for (int x=0; x<W-1; x++) { int i1 = x + W * y; int i2 = x+1 + W * y; int i3 = x + W * (y+1); int i4 = x+1 + W * (y+1); mesh.addTriangle( i1, i2, i3 ); mesh.addTriangle( i2, i4, i3 ); } } setNormals( mesh ); light.enable(); }
/*! Add \a quads - a series of one or more quads - to this builder. If \a quads has less than four vertices this function exits without doing anything. One normal per quad is calculated if \a quads does not have normals. For this reason quads should have all four vertices in the same plane. If the vertices do not lie in the same plane, use addTriangleStrip() to add two adjacent triangles instead. Since internally \l{geometry-building}{quads are stored as two triangles}, each quad is actually divided in half into two triangles. Degenerate triangles are skipped in the same way as addTriangles(). \sa addTriangles(), addTriangleStrip() */ void QGLBuilder::addQuads(const QGeometryData &quads) { if (quads.count() < 4) return; QGeometryData q = quads; bool calcNormal = !q.hasField(QGL::Normal); if (calcNormal) { QVector3DArray nm(q.count()); q.appendNormalArray(nm); } bool skip = false; int k = 0; QVector3D norm; for (int i = 0; i < q.count(); i += 4) { if (calcNormal) skip = qCalculateNormal(i, i+1, i+2, q, &norm); if (!skip) dptr->addTriangle(i, i+1, i+2, q, k); if (skip) skip = qCalculateNormal(i, i+2, i+3, q, &norm); if (!skip) { if (calcNormal) setNormals(i, i+2, i+3, q, norm); dptr->addTriangle(i, i+2, i+3, q, k); } } dptr->currentNode->setCount(dptr->currentNode->count() + k); }
static bool qCalculateNormal(int i, int j, int k, QGeometryData &p, QVector3D *vec = 0) { QVector3D norm; QVector3D *n = &norm; if (vec) n = vec; bool nullTriangle = false; *n = QVector3D::crossProduct(p.vertexAt(j) - p.vertexAt(i), p.vertexAt(k) - p.vertexAt(j)); if (qFskIsNull(n->x())) n->setX(0.0f); if (qFskIsNull(n->y())) n->setY(0.0f); if (qFskIsNull(n->z())) n->setZ(0.0f); if (n->isNull()) { nullTriangle = true; } else { setNormals(i, j, k, p, *n); } return nullTriangle; }
/*! Adds to this section a set of quads defined by \a strip. If \a strip has less than four vertices this function exits without doing anything. The first quad is formed from the 0'th, 2'nd, 3'rd and 1'st vertices. The second quad is formed from the 2'nd, 4'th, 5'th and 3'rd vertices, and so on, as shown in this diagram: \image quads.png One normal per quad is calculated if \a strip does not have normals. For this reason quads should have all four vertices in the same plane. If the vertices do not lie in the same plane, use addTriangles() instead. Since internally \l{geometry-building}{quads are stored as two triangles}, each quad is actually divided in half into two triangles. Degenerate triangles are skipped in the same way as addTriangles(). \sa addQuads(), addTriangleStrip() */ void QGLBuilder::addQuadStrip(const QGeometryData &strip) { if (strip.count() < 4) return; QGeometryData s = strip; bool calcNormal = !s.hasField(QGL::Normal); if (calcNormal) { QVector3DArray nm(s.count()); s.appendNormalArray(nm); } bool skip = false; QVector3D norm; int k = 0; for (int i = 0; i < s.count() - 3; i += 2) { if (calcNormal) skip = qCalculateNormal(i, i+2, i+3, s, &norm); if (!skip) dptr->addTriangle(i, i+2, i+3, s, k); if (skip) skip = qCalculateNormal(i, i+3, i+1, s, &norm); if (!skip) { if (calcNormal) setNormals(i, i+3, i+1, s, norm); dptr->addTriangle(i, i+3, i+1, s, k); } } dptr->currentNode->setCount(dptr->currentNode->count() + k); }
//----------------------------------------------------------------------------------------- // void ofApp::update() { float time = ofGetElapsedTimef(); // time is equal to the amount of time passed // changes the vertices for each mesh at j for(int j=0; j<number; j++) { for(int y=0; y<h; y++) { for(int x=0; x<w; x++) { // vertex index int i = x + w * y; ofPoint pt = mesh[j].getVertex(i); float noise = ofNoise(x, y, time * 0.5); // Perlin noise value float rNoise = ofSignedNoise(x*0.5, y*0.3, time*0.1); // Creates a Perlin signed noise value for the red value of the mesh color // comment above line and uncomment line below for a variation of blue, purple, and red colors // float rNoise = ofSignedNoise(x*0.5, y*0.3, time); float bNoise = ofSignedNoise(x*0.5, y*0.3, time*0.1); // creates a Perlin signed noise value for the blue value of the mesh pt.z = noise ; // assigns noise to the z value so the noise affects the z space of the mesh mesh[j].setVertex(i, pt); mesh[j].setColor(i, ofColor(250*rNoise, 0, 250*bNoise)); // sets color of mesh // note: only using red and blue to make a purple color, then adding the rNoise and bNoise to change the values of red and blue to make different shades of purple } } setNormals(mesh[j]); // updates the normals for each mesh at j } }
//http://www.packtpub.com/sites/default/files/9781849518048_Chapter_07.pdf //knotExample void ofApp::addCircle( ofVec3f nextPoint, ofMesh &mesh ){ float time = ofGetElapsedTimef(); //Time //Parameters – twisting and rotating angles and color ofFloatColor color( ofNoise( time * 0.05 ), ofNoise( time * 0.1 ), ofNoise( time * 0.15 )); color.setSaturation( 1.0 ); //Make the color maximally //Add vertices for (int i=0; i<circleN; i++) { float angle = float(i) / circleN * TWO_PI+(PI*0.25); float x = Rad * cos( angle ); float y = Rad * sin( angle ); ofPoint p = nextPoint+ofVec3f(x ,y , 0); mesh.addVertex( p ); mesh.addColor( color ); } //Add the triangles int base = mesh.getNumVertices() - 2 * circleN; if ( base >= 0 ) { //Check if it is not the first step //and we really need to add the triangles for (int i=0; i<circleN; i++) { int a = base + i; int b = base + (i + 1) % circleN; int c = circleN + a; int d = circleN + b; mesh.addTriangle(a,b,d); mesh.addTriangle(a, d, c); } //Update the normals setNormals( mesh ); } }
//-------------------------------------------------------------- void ofxOcean::setupMesh(float W, float H, int gridSize){ mesh.clear(); mesh.setMode(OF_PRIMITIVE_TRIANGLES); mesh.clear(); mesh.enableColors(); mesh.enableIndices(); mesh.enableNormals(); mesh.disableTextures(); //Set up vertices and colors bool odd = true; float offset = 0; for (int y=0; y<H; y+=gridSize) { for (int x=0; x<W; x+=gridSize) { if (odd) { if (x == 0) { //mesh.addVertex(ofPoint(0, y, 0)); //mesh.addColor( ofColor( 0, 0, 0 ) ); } offset = gridSize/2.0; } else { offset = 0; } mesh.addVertex(ofPoint(x+offset, y, 0)); mesh.addColor( ofColor(255.f, 255.f, 255.f, 64.f) ); } if (!odd){ //mesh.addVertex(ofPoint(W-gridSize/2, y, 0)); //mesh.addColor( ofColor( 0, 0, 0 ) ); } odd = !odd; } //Set up triangles' indices odd = true; int numRows = H/gridSize; int numCols = W/gridSize; for (int y=0; y<numRows-1; y++) { for (int x=0; x<numCols-1; x++) { int i1 = x + numCols * y; int i2 = x+1 + numCols * y; int i3 = x + numCols * (y+1); int i4 = x+1 + numCols * (y+1); if (odd) { mesh.addTriangle( i1, i4, i3 ); mesh.addTriangle( i1, i2, i4 ); } else { mesh.addTriangle( i1, i2, i3 ); mesh.addTriangle( i2, i4, i3 ); } } odd = !odd; } setNormals( mesh ); //Set normals }
/*! Add a series of quads by 'interleaving' \a top and \a bottom. This function behaves like quadStrip(), where the odd-numbered vertices in the input primitive are from \a top and the even-numbered vertices from \a bottom. It is trivial to do extrusions using this function: \code // create a series of quads for an extruded edge along -Y addQuadsInterleaved(topEdge, topEdge.translated(QVector3D(0, -1, 0)); \endcode N quad faces are generated where \c{N == min(top.count(), bottom.count() - 1}. If \a top or \a bottom has less than 2 elements, this functions does nothing. Each face is formed by the \c{i'th} and \c{(i + 1)'th} vertices of \a bottom, followed by the \c{(i + 1)'th} and \c{i'th} vertices of \a top. If the vertices in \a top and \a bottom are the perimeter vertices of two polygons then this function can be used to generate quads which form the sides of a \l{http://en.wikipedia.org/wiki/Prism_(geometry)}{prism} with the polygons as the prisms top and bottom end-faces. \image quad-extrude.png In the diagram above, the \a top is shown in orange, and the \a bottom in dark yellow. The first generated quad, (a, b, c, d) is generated in the order shown by the blue arrow. To create such a extruded prismatic solid, complete with top and bottom cap polygons, given just the top edge do this: \code QGeometryData top = buildTopEdge(); QGeometryData bottom = top.translated(QVector3D(0, 0, -1)); builder.addQuadsInterleaved(top, bottom); builder.addTriangulatedFace(top); builder.addTriangulatedFace(bottom.reversed()); \endcode The \a bottom QGeometryData must be \b{reversed} so that the correct winding for an outward facing polygon is obtained. */ void QGLBuilder::addQuadsInterleaved(const QGeometryData &top, const QGeometryData &bottom) { if (top.count() < 2 || bottom.count() < 2) return; QGeometryData zipped = bottom.interleavedWith(top); bool calcNormal = !zipped.hasField(QGL::Normal); if (calcNormal) { QVector3DArray nm(zipped.count()); zipped.appendNormalArray(nm); } bool skip = false; QVector3D norm; int k = 0; for (int i = 0; i < zipped.count() - 2; i += 2) { if (calcNormal) skip = qCalculateNormal(i, i+2, i+3, zipped, &norm); if (!skip) dptr->addTriangle(i, i+2, i+3, zipped, k); if (skip) skip = qCalculateNormal(i, i+3, i+1, zipped, &norm); if (!skip) { if (calcNormal) setNormals(i, i+3, i+1, zipped, norm); dptr->addTriangle(i, i+3, i+1, zipped, k); } } dptr->currentNode->setCount(dptr->currentNode->count() + k); }
//-------------------------------------------------------------- void ofApp::setup(){ gridWidth = 200; gridHeight = 200; // set up the vertices and colors //first on the y axis for(int y = 0; y < gridWidth; y++){ //now on the x axis for(int x = 0; x < gridHeight; x++){ myMesh.addVertex(ofPoint((x-gridWidth*0.5)*6, (y-gridHeight*0.5)*6, 0)); myMesh.addColor(ofColor(0,0,0)); } } // set up triangles indices //first on the y axis for(int y = 0; y < gridWidth - 1; y++){ //now on the x axis for(int x = 0; x < gridHeight -1; x++){ i1 = x + gridWidth * y; i2 = x+1 + gridWidth * y; i3 = x + gridWidth * (y+1); i4 = x+1 + gridWidth * (y+1); myMesh.addTriangle( i1, i2, i3); myMesh.addTriangle( i2, i4, i3); } } setNormals(myMesh); myLight.enable(); }
//-------------------------------------------------------------- void ofApp::setup(){ //Pyramid's base vertices with indices 0, 1, 2 mesh.addVertex( ofPoint( -200, -100, -50 ) ); mesh.addVertex( ofPoint( 200, -100, -50 ) ); mesh.addVertex( ofPoint( 0, 200, 0 ) ); //Pyramid's top vertex with index 3 mesh.addVertex( ofPoint( 0, 0, 50 ) ); //Vertices with indices 3, 2, 0 mesh.addTriangle( 3, 2, 0 ); //Vertices with indices 3, 1, 2 mesh.addTriangle( 3, 1, 2 ); //Vertices with indices 3, 0, 1 mesh.addTriangle( 3, 0, 1 ); setNormals( mesh ); //Set normals to the surface //Note, setNormals is our function, //which is declared //Enabling light source light.enable(); }
void Terrain::setBezierMode(bool draw_bezier) { if(this->draw_bezier != draw_bezier) { this->draw_bezier = draw_bezier; draw_bezier ? setNormalsBezier() : setNormals(); } }
//----------------------------------------------------------------------------------------- // void ofApp::setup() { fontSmall.loadFont("Fonts/DIN.otf", 8 ); //resolution W = 300; H = 300; camera.setNearClip(0.01f); //the starting point of the camera camera.setPosition( 0, 20 , 180 ); camera.setMovementMaxSpeed( 0.1f ); //material and light setup material.setShininess( 100 ); material.setSpecularColor(ofColor(40, 100,255, 250)); pointLight.setDiffuseColor( ofFloatColor(.85, .85, .55) ); pointLight.setSpecularColor( ofFloatColor(1.f, 1.f, 1.f)); pointLight2.setDiffuseColor( ofFloatColor( 238.f/255.f, 57.f/255.f, 135.f/255.f )); pointLight2.setSpecularColor(ofFloatColor(.8f, .8f, .9f)); pointLight3.setDiffuseColor( ofFloatColor(40.f/255.f,110/255.f,135.f/255.f) ); pointLight3.setSpecularColor( ofFloatColor(.2, .2, .2) ); //initialize points and color to the mesh for(int x = 0; x < W; x++){ for (int y = 0; y< H; y++){ ofPoint vert = ofPoint(x - W/2 , y - H/2, 0); mesh.addVertex(vert); mesh.addColor( ofColor( 0, 0, 0 ) ); } } //initializ small triangles that make up the mesh for (int x = 0 ; x < W-1; x ++) { for (int y= 0; y < H-1; y++) { int index1 = x * W + y; int index2 = (x+1) * W + y; int index3 = x * W+(y+1); int index4 = (x+1) * W + (y + 1); mesh.addTriangle(index1, index2, index3); mesh.addTriangle(index3, index2, index4); } } setNormals(mesh); }
TriangleFace::TriangleFace(const Ric::Vector &v0, const Ric::Vector &v1, const Ric::Vector &v2, const Ric::Material &material) : material_(material), v0_(v0), v1_(v1), v2_(v2), fc_((v0+v1+v2)/3), n_(((v1-v0)^(v2-v0)).Normalized()), area_(((v1-v0)^(v2-v0)).Length()), vertex_texture_coord(false), vertex_normal_(false) { setNormals(n_,n_,n_); }
//----------------------------------------------------------------------------------------- // void ofApp::update() { float time = ofGetElapsedTimef(); for (int y=0; y<H; y++) { for (int x=0; x<W; x++) { int i = x + W * y; //Vertex index ofPoint p = mesh.getVertex( i ); //the following equation is based on the linear theory of ocean surface waves // assuming the amplitude of waves on the water surface is infinitely small so the surface is almost exactly a plane. To simplify the mathematics, we can also assume that the flow is 2-dimensional with waves traveling in the x-direction. //read more details on http://oceanworld.tamu.edu/resources/ocng_textbook/chapter16/chapter16_01.htm freq = sqrt(g * k); float height = amp * sin(k * x - freq * time * 2); // the z position of each mesh vertex are determined by the x position, the height that's caculated by the linear theory of the ocean suface wave, and ofSignedNoise, which returns a number between -1 and 1 p.z = (W-x)/7.f * ofSignedNoise(height * .001, y*.007, height)+ofSignedNoise(x * .01, y*.08, height); // p.z = (W-x)/15.f * height * ofSignedNoise(height * .001, y*.007 ); mesh.setVertex( i, p ); //The color of vertex changes as the z position goes up and down mesh.setColor(i, ofFloatColor( (abs(height) + .5) * 30/255.f, (abs(height) + .5) * 80/255.f, (abs(height) + .5)*100/255.f)); // mesh.setColor( i, ofFloatColor( // ofMap(height, amp, -amp, 60, 100)/255.f, // 1- ofMap(height, amp, -amp, 200, 250)/255.f, // ofMap(height, amp, -amp, 200, 250)/255.f // )); } } setNormals( mesh ); //the light moves position and changes color pointLight.setPosition((ofGetWidth()*.5)+ cos(ofGetElapsedTimef()*.5)*(ofGetWidth()*.3), ofGetHeight()/2, 500); pointLight2.setPosition((ofGetWidth()*.5)+ cos(ofGetElapsedTimef()*.15)*(ofGetWidth()*.3), ofGetHeight()*.5 + sin(ofGetElapsedTimef()*.7)*(ofGetHeight()), -300); pointLight3.setPosition( cos(ofGetElapsedTimef()*1.5) * ofGetWidth()*.5, sin(ofGetElapsedTimef()*1.5f) * ofGetWidth()*.5, cos(ofGetElapsedTimef()*.2) * ofGetWidth() ); }
//----------------------------------------------------------------------------- // build a surface void Wreck::buildSurface( mgBezier& bodySpline, double bodyScale, int bodySteps, mgBezier& lenSpline, double lenScale, int lenSteps, const mgMatrix4& xform, BOOL outwards, int texture) { double bodyLen = bodySpline.getLength(); double lenLen = lenSpline.getLength(); mgVertexTA* points = new mgVertexTA[(bodySteps+1) * (lenSteps+1)]; mgPoint3 lenPt, bodyPt, xpt; for (int i = 0; i <= lenSteps; i++) { lenSpline.splinePt((lenLen * i)/lenSteps, lenPt); double ht = lenPt.y - lenPt.z; for (int j = 0; j <= bodySteps; j++) { bodySpline.splinePt((bodyLen * j)/bodySteps, bodyPt); mgVertexTA* v = &points[i*(bodySteps+1)+j]; mgPoint3 pt(lenScale * (ht * bodyScale * bodyPt.x), lenScale * (lenPt.z + ht * bodyScale * bodyPt.y), lenScale * lenPt.x); xform.mapPt(pt, xpt); v->setPoint(xpt.x, xpt.y, xpt.z); v->setTexture(2*j/(double) bodySteps, 2*i/(double) lenSteps, texture); } } // set all the normals setNormals(points, lenSteps+1, bodySteps+1, outwards); int vertexBase = m_vertexes->getLength(); for (int i = 0; i < (lenSteps+1)*(bodySteps+1); i++) m_vertexes->addVertex(&points[i]); m_indexes->addGrid(vertexBase, bodySteps+1, lenSteps, bodySteps, outwards); delete points; }
void Terrain::heighten(int y){ int scaleFact = .1; if(y<0){ scaleFact *= -1; } max_height = 0; for(int w = 0; w < width; w++){ for(int h = 0; h< height; h++){ (coords[w][h])[1] += height_map[3*(w*width+h)+1]*scaleFact; if((coords[w][h])[1] > max_height) max_height = (coords[w][h])[1]; } } setNormals(); }
void ModelMD2::prepareFrame() { #ifdef DEBUG static bool isFirst = true; if (isFirst) { printf("Call ModelMD2::prepareFrame()...\n"); isFirst = false; } #endif if (m_actionIdx == -1) return; float *uvs = (float *) malloc(m_header.numTriangles * 6 * sizeof(float)); float *vertices = (float *) malloc(m_header.numTriangles * 9 * sizeof(float)); float *normals = (float *) malloc(m_header.numTriangles * 9 * sizeof(float)); int i, j, uvIdx = 0, vertexIdx = 0, normalIdx = 0; md2_frame_t *f = &m_frames[m_frameIdx]; for (i = 0; i < m_header.numTriangles; i++) { md2_triangle_t *t = &m_triangles[i]; for (j = 0; j < 3; j++) { //set uvs uvs[uvIdx++] = (float) m_texCoords[t->textureIndices[j]].s / (float) m_header.skinWidth; uvs[uvIdx++] = 1.0f - (float) m_texCoords[t->textureIndices[j]].t / (float) m_header.skinHeight; //set vertices & normals vertices[vertexIdx++] = f->vertices[t->vertexIndices[j]].vertex[0]; vertices[vertexIdx++] = f->vertices[t->vertexIndices[j]].vertex[1]; vertices[vertexIdx++] = f->vertices[t->vertexIndices[j]].vertex[2]; normals[normalIdx++] = f->vertices[t->vertexIndices[j]].normal[0]; normals[normalIdx++] = f->vertices[t->vertexIndices[j]].normal[2]; normals[normalIdx++] = f->vertices[t->vertexIndices[j]].normal[1]; } } setVertices(vertices, m_header.numTriangles * 9 * sizeof(float)); setNormals(normals, m_header.numTriangles * 9 * sizeof(float)); setUvs(uvs, m_header.numTriangles * 6 * sizeof(float)); FREEANDNULL(vertices); FREEANDNULL(normals); FREEANDNULL(uvs); m_frameIdx++; if (m_frameIdx > m_actions[m_actionIdx].max_idx) m_frameIdx = m_isLooped ? m_actions[m_actionIdx].min_idx : m_actions[m_actionIdx].max_idx; }
//----------------------------------------------------------------------------------------- // void ofApp::setup() { fontSmall.loadFont("Fonts/DIN.otf", 8 ); // Give us a starting point for the camera camera.setNearClip(0.01f); camera.setPosition( 0, 4, 40 ); camera.setMovementMaxSpeed( 0.1f ); h = 30; // initializing height for the height of the mesh w = 30; // initializing width for the width of the mesh // sets up vertices and colors of each mesh at i for(int i=0; i<number; i++) { for(int y=0; y<h; y++) { for(int x=0; x<w; x++) { mesh[i].addVertex(ofPoint((x-w/2), (y-h/2), 0)); mesh[i].addColor(ofColor(255, 255, 255)); } } // sets up the indices of triangles to make a grid of triangles for(int y=0; y<h-1; y++) { for(int x=0; x<w-1; x++) { int index1 = x + w * y; int index2 = x+1 + w * y; int index3 = x + w * (y+1); int index4 = x+1 + w * (y+1); mesh[i].addTriangle(index1, index2, index3); mesh[i].addTriangle(index2, index4, index3); } } setNormals(mesh[i]); // sets normals to surface } light1.enable(); // enables light }
//-------------------------------------------------------------- void testApp::setup(){ //Set up vertices and colors for (int y=0; y<H; y++) { for (int x=0; x<W; x++) { mesh.addVertex( ofPoint( (x - W/2) * 12*4, (y - H/2) * 12*4, 0 ) ); mesh.addColor( ofColor( 0, 255, 0 ) ); } } //Set up triangles' indices for (int y=0; y<H-1; y++) { for (int x=0; x<W-1; x++) { int i1 = x + W * y; int i2 = x+1 + W * y; int i3 = x + W * (y+1); int i4 = x+1 + W * (y+1); mesh.addTriangle( i1, i2, i3 ); mesh.addTriangle( i3, i1, i2 ); } } setNormals( mesh ); //Set normals // light.enable(); //Enable lighting // listen on the given port //********************************************** //********************************************** // cout << "listening for osc messages on port " << PORT << "\n"; receiver.setup(PORT); ofBackground(30, 30, 130); nBandsToUse = 1024; receivedFft = new float[nBandsToUse]; for (int i = 0; i < nBandsToUse; i++){ receivedFft[i] = 0; } //********************************************** //********************************************** }
//----------------------------------------------------------------------------- // create ring void Wreck::createRing( mgMatrix4& xform, int ringSteps, int circleSteps) { mgBezier ringSpline; ringSpline.addVertex(mgPoint3( 0.0, 4.0, 0.0), mgPoint3( 0.0+13, 4.0, 0.0)); ringSpline.addVertex(mgPoint3( 13.0, 0.0, 0.0), mgPoint3( 13.0, 0.0+4, 0.0)); ringSpline.addVertex(mgPoint3( 0.0, -4.0, 0.0), mgPoint3( 0.0+13, -4.0, 0.0)); double ringLen = ringSpline.getLength(); mgVertexTA* points = new mgVertexTA[(ringSteps+1) * (circleSteps+1)]; mgPoint3 ringPt, xpt; for (int i = 0; i <= circleSteps; i++) { double angle = (i*2*PI)/circleSteps; for (int j = 0; j <= ringSteps; j++) { ringSpline.splinePt((ringLen * j)/ringSteps, ringPt); mgVertexTA* v = &points[i*(ringSteps+1)+j]; mgPoint3 pt(cos(angle) * ringPt.x, sin(angle) * ringPt.x, ringPt.y); xform.mapPt(pt, xpt); v->setPoint(xpt.x, xpt.y, xpt.z); v->setTexture(xpt.z/100 + 2*j/(double) ringSteps, 2*i/(double) circleSteps, 0); } } // set all the normals setNormals(points, circleSteps+1, ringSteps+1, true); int vertexBase = m_vertexes->getLength(); for (int i = 0; i < (circleSteps+1)*(ringSteps+1); i++) m_vertexes->addVertex(&points[i]); m_indexes->addGrid(vertexBase, ringSteps+1, circleSteps, ringSteps, true); delete points; }
void PyramidBrush::setup() { parameters.setName("PyramidBrush"); parameters.add(historyMax.set("historyMax", 2000, 100, 10000)); parameters.add(brushType.set("type line", 0, 0, 1)); parameters.add(size.set("size", 1, 0, 2)); parameters.add(opacity.set("opacity", 20, 0, 255)); parameters.add(lineWidth.set("lineWidth", 0.2, 0., 5.)); parameters.add(swatch.set("swatch", 0, 0, 12)); parameters.add(bgColor.set("bgColor", ofColor(0, 0), ofColor(0, 0), ofColor(255, 255))); parameters.add(activeColor.set("activeColor", ofColor(0, 0), ofColor(0, 0), ofColor(255, 255))); parameters.add(col1.set("col1", ofColor(0, 0), ofColor(0, 0), ofColor(255, 255))); parameters.add(col2.set("col2", ofColor(0, 0), ofColor(0, 0), ofColor(255, 255))); parameters.add(col3.set("col3", ofColor(0, 0), ofColor(0, 0), ofColor(255, 255))); ofPoint v0 = ofPoint( -200, -100, 0 ); ofPoint v1 = ofPoint( 200, -100, 0 ); ofPoint v2 = ofPoint( 0, 200, 0 ); //Pyramid's top vertex ofPoint v3 = ofPoint( 0, 0, 500 ); //Add triangles by its vertices mesh.addVertex( v3 ); mesh.addVertex( v2 ); mesh.addVertex( v0 ); mesh.addVertex( v3 ); mesh.addVertex( v1 ); mesh.addVertex( v2 ); mesh.addVertex( v3 ); mesh.addVertex( v0 ); mesh.addVertex( v1 ); mesh.setupIndicesAuto(); //Set up indices setNormals(mesh); //light.enable(); mesh.addTexCoord( ofPoint( 100, 100 ) ); //v3 mesh.addTexCoord( ofPoint( 10, 300 ) ); //v2 mesh.addTexCoord( ofPoint( 10, 10 ) ); //v0 mesh.addTexCoord( ofPoint( 100, 100 ) ); //v3 mesh.addTexCoord( ofPoint( 300, 10 ) ); //v1 mesh.addTexCoord( ofPoint( 10, 300 ) ); //v2 mesh.addTexCoord( ofPoint( 100, 100 ) ); //v3 mesh.addTexCoord( ofPoint( 10, 10 ) ); //v0 mesh.addTexCoord( ofPoint( 300, 10 ) ); //v1 ofLoadImage(meshTex, "knife.jpg"); return; }
//-------------------------------------------------------------- void testApp::setup(){ //Pyramid's base vertices ofPoint v0 = ofPoint( -200, -100, 0 ); ofPoint v1 = ofPoint( 200, -100, 0 ); ofPoint v2 = ofPoint( 0, 200, 0 ); //Pyramid's top vertex ofPoint v3 = ofPoint( 0, 0, 100 ); //Add triangles by its vertices mesh.addVertex( v3 ); mesh.addVertex( v2 ); mesh.addVertex( v0 ); mesh.addVertex( v3 ); mesh.addVertex( v1 ); mesh.addVertex( v2 ); mesh.addVertex( v3 ); mesh.addVertex( v0 ); mesh.addVertex( v1 ); mesh.setupIndicesAuto(); //Set up indices setNormals( mesh ); //Set normals to the surface //Note, setNormals is our function, //which is declared //Enabling light source light.enable(); }
bool Terrain::init(const char * ppmFile){ height_map = Texture::loadPPM(ppmFile, width, height); /* Create a 1024*1024 array of vertex coordinates (Vector3). Populate the array as follows: the x values should correspond to the array's x index, the z values to the y index. For example: Vector3[x][y].x = x, Vector3[x][y].z = y. The y value should be the corresponding value from the height map array (Vector3[x][y].y = heightmap[x][y]). */ for(int x = 0; x < width; x++){ for(int y = 0; y < height; y++){ coords[x][y] = Vector3(x, height_map[3*(x*height + y)], y); if((coords[x][y])[1] > max_height) max_height = (coords[x][y])[1]; } } setNormals(); update_levels(0); return true; }
//-------------------------------------------------------------- void ofApp::update(){ float time = ofGetElapsedTimef(); //Get time //Change vertices for (int y=0; y<gridHeight; y++) { for (int x=0; x<gridWidth; x++) { int i = x + gridWidth * y; //Vertex index ofPoint p = myMesh.getVertex( i ); //Get Perlin noise value float value = ofNoise( x * 0.05, y * 0.05, time * 0.5 ); //Change z-coordinate of vertex p.z = value * 100; myMesh.setVertex( i, p ); //Change color of vertex myMesh.setColor( i, ofColor( value*255, value * 255, 255 ) ); } } setNormals( myMesh ); //Update the normals }
//----------------------------------------------------------------------------------------- // void ofApp::setup() { fontSmall.loadFont("Fonts/DIN.otf", 8 ); circ = ofVec3f (0, 0, 0); //used for animation radius = 2; //used for animation //change this to zero if you want to have movement that gains momentum over time // Give us a starting point for the camera camera.setNearClip(0.01f); camera.setPosition( 0, 4, 10 ); camera.setMovementMaxSpeed( 0.1f ); H = 30; //height for mesh W = 30; //width for mesh color = ofColor(100, 50, 200); //starting color //sets up the mesh's vertices and color for (int y = 0; y < H; y++){ //as long as y is less than 30 for (int x = 0; x < W; x++){ //and x is less than 30 mesh.addVertex(ofVec3f((x - W/2), (y - H/2), 0)); //add a vertex along each of these x and y points mesh.addColor(color); //puts the color in } } //sets up the triangle indices for (int y=0; y<H-1; y++) { //as long as y is less than the height-1 for (int x=0; x<W-1; x++) { //and x is less than the width-1 int i1 = x + W * y; //0 is the first index int i2 = x+1 + W * y; //1 is the second int i3 = x + W * (y+1); //30 is the third int i4 = x+1 + W * (y+1); //31 is the fourth mesh.addTriangle( i1, i2, i3 ); //0, 1, 30 mesh.addTriangle( i2, i4, i3 ); //1, 31, 30 } } setNormals(mesh); //sets the normals to the mesh (function down below) }
//-------------------------------------------------------------- void ofxOcean::update(){ // z = sin(y) int W = width/gridSize; int H = height/gridSize; float time = ofGetElapsedTimef(); //Change vertices for (int y=0; y<H; y++) { //float waveZ = sin(y * waveAmplitude + time * waveSpeed) * waveHeight; for (int x=0; x<W; x++) { float waveZ = sin((y*waveDirection.y + x*waveDirection.x) * waveAmplitude + time * waveSpeed) * waveHeight; waveZ += sin((y*waveDirection2.y + x*waveDirection2.x) * waveAmplitude2 + time * waveSpeed2) * waveHeight2; int i = x + W * y; //Vertex index ofPoint p = mesh.getVertex( i ); //Get Perlin noise value float value = ofNoise( x * gridSize * noiseAmp * 0.001, y * gridSize * noiseAmp * 0.001, time * noiseSpeed * 0.2 ); // 0.2 //Change z-coordinate of vertex p.z = value * noiseHeight; //25 p.z += waveZ; mesh.setVertex( i, p ); //Change color of vertex mesh.setColor( i, color); } } setNormals( mesh ); //Update the normals }
//----------------------------------------------------------------------------------------- // void ofApp::update() { float time = ofGetElapsedTimef(); //our time variable for animation //radius += 0.001; //uncomment this if you want to have movement that gains momentum for (int y=0; y<H; y++) { //for as long as y is less than the height for (int x=0; x<W; x++) { //and x is less than the width int i = x + W * y; //our vertex index will equal x plus the width times y ofPoint v = mesh.getVertex( i ); //gets the vertices along all the points circ.x = x + radius * cos(time); circ.y = y + radius * sin(time); circ.z = circ.x * circ.y; float move = ofNoise( circ.x * 0.05, circ.y * 0.05, circ.z * 0.05 ); //noise value for animation v.z = move; //changes the z values of the mesh points using the noise value mesh.setVertex( i, v ); //updates the mesh vertices mesh.setColor( i, ofColor( move*180, move * 50, 220 ) ); //changes the color based on z movement } } setNormals( mesh ); //updates the normals }
//-------------------------------------------------------------- void testApp::update(){ keyValue = receivedFft[50]*15; keyValue = ofMap(keyValue, 0.0, 1.0, 0.0, 8.0); keyValue *= 0.95; // cout << "keyValue: "<< keyValue<< endl; float time = ofGetElapsedTimef(); //Get time //Change vertices for (int y=0; y<H; y++) { for (int x=0; x<W; x++) { int i = x + W * y; //Vertex index ofPoint p = mesh.getVertex( i ); //Get Perlin noise value float value = ofNoise( x * 0.1, y * 0.1, time * 1 ); //Change z-coordinate of vertex p.z = value *100*keyValue; // p.x = x+100 * smoothedVol; mesh.setVertex( i, p ); //Change color of vertex mesh.setColor( i, ofColor( 255, 0, 255, 100 ) ); } } setNormals( mesh ); //Update the normals //audio********************************************** //********************************************** //// hide old messages for(int i = 0; i < NUM_MSG_STRINGS; i++){ if(timers[i] < ofGetElapsedTimef()){ msg_strings[i] = ""; } } // check for waiting messages while(receiver.hasWaitingMessages()){ // get the next message ofxOscMessage m; receiver.getNextMessage(&m); if(m.getAddress() == "/channel_01/FFT"){ int index = m.getArgAsInt32(0); float val = m.getArgAsFloat(1); receivedFft[index] = val; //cout << "recvd: " << index << " :\t"<<val<<endl; } else { string msg_string; msg_string = m.getAddress(); cout << "unrecognized message" << msg_string << endl; } } //********************************************** //********************************************** }
void SkeletonBlendedGeometry::changed(ConstFieldMaskArg whichField, UInt32 origin, BitVector details) { Inherited::changed(whichField, origin, details); if((whichField & BaseGeometryFieldMask) && getBaseGeometry() != NULL) { if(getBaseGeometry()->getTypes() != NULL) { setTypes(getBaseGeometry()->getTypes()); } if(getBaseGeometry()->getLengths() != NULL) { setLengths(getBaseGeometry()->getLengths()); } if(getBaseGeometry()->getPositions() != NULL) { GeoPropertyUnrecPtr Pos(getBaseGeometry()->getPositions()->clone()); setPositions(dynamic_pointer_cast<GeoVectorProperty>(Pos)); } if(getBaseGeometry()->getNormals() != NULL) { GeoPropertyUnrecPtr Norm(getBaseGeometry()->getNormals()->clone()); setNormals(dynamic_pointer_cast<GeoVectorProperty>(Norm)); } if(getBaseGeometry()->getColors() != NULL) { setColors(getBaseGeometry()->getColors()); } if(getBaseGeometry()->getSecondaryColors() != NULL) { setSecondaryColors(getBaseGeometry()->getSecondaryColors()); } if(getBaseGeometry()->getTexCoords() != NULL) { setTexCoords(getBaseGeometry()->getTexCoords()); } if(getBaseGeometry()->getTexCoords1() != NULL) { setTexCoords1(getBaseGeometry()->getTexCoords1()); } if(getBaseGeometry()->getTexCoords2() != NULL) { setTexCoords2(getBaseGeometry()->getTexCoords2()); } if(getBaseGeometry()->getTexCoords3() != NULL) { setTexCoords3(getBaseGeometry()->getTexCoords3()); } if(getBaseGeometry()->getTexCoords4() != NULL) { setTexCoords4(getBaseGeometry()->getTexCoords4()); } if(getBaseGeometry()->getTexCoords5() != NULL) { setTexCoords5(getBaseGeometry()->getTexCoords5()); } if(getBaseGeometry()->getTexCoords6() != NULL) { setTexCoords6(getBaseGeometry()->getTexCoords6()); } if(getBaseGeometry()->getTexCoords7() != NULL) { setTexCoords7(getBaseGeometry()->getTexCoords7()); } if(getBaseGeometry()->getIndices() != NULL) { setIndices(getBaseGeometry()->getIndices()); } setMaterial(getBaseGeometry()->getMaterial()); } if( (whichField & InternalJointsFieldMask) || (whichField & InternalWeightIndexesFieldMask) || (whichField & InternalWeightsFieldMask)) { calculatePositions(); } }
//----------------------------------------------------------------------------- // create shell of tower void Tower::createShell() { int vertexCount = (APT_STEPS+1) * (FLOOR_STEPS+1); int indexCount = 6*APT_STEPS*FLOOR_STEPS; int glassIndexCount = 6*FLOORS * FLOOR_STEPS; m_shellVertexes = mgVertex::newBuffer(vertexCount); m_shellIndexes = mgDisplay->newIndexBuffer(indexCount); m_glassIndexes = mgDisplay->newIndexBuffer(glassIndexCount); mgVertex* points = new mgVertex[(FLOOR_STEPS+1) * (APT_STEPS+1)]; mgPoint3 aptPt, floorPt; for (int i = 0; i <= APT_STEPS; i++) { m_aptSpline.splinePt(m_floorDists[i], aptPt); double ht = aptPt.y - aptPt.z; for (int j = 0; j <= FLOOR_STEPS; j++) { m_floorSpline.splinePt((m_floorLen * j)/FLOOR_STEPS, floorPt); mgVertex* v = &points[i*(FLOOR_STEPS+1)+j]; mgPoint3 pt(APT_SCALE * (ht * FLOOR_SCALE * floorPt.x), APT_SCALE * (aptPt.z + ht * FLOOR_SCALE * floorPt.y), APT_SCALE * aptPt.x); v->setPoint(pt.x, pt.y, pt.z); v->setTexture(2*j/(double) FLOOR_STEPS, 2*i/(double) APT_STEPS); // v->setTexture((pt.x+pt.y)/40, pt.z/40); } } // set all the normals setNormals(points, APT_STEPS+1, FLOOR_STEPS+1, false); int vertexBase = m_shellVertexes->getLength(); for (int i = 0; i < (APT_STEPS+1)*(FLOOR_STEPS+1); i++) m_shellVertexes->addVertex(&points[i]); int rowSize = FLOOR_STEPS+1; for (int i = 0; i < APT_STEPS; i++) { for (int j = 0; j < FLOOR_STEPS; j++) { int index = vertexBase + i*rowSize+j; // if a window row/col if (i > 15 && i < 15+FLOORS*3 && (i-15)%3 != 0 && ((j > 62 && j < 88) || (j > 12 && j < 38))) { m_glassIndexes->addIndex(index); // tl m_glassIndexes->addIndex(index+rowSize); // bl m_glassIndexes->addIndex(index+1); // tr m_glassIndexes->addIndex(index+rowSize); // bl m_glassIndexes->addIndex(index+rowSize+1); // br m_glassIndexes->addIndex(index+1); // tr } else { m_shellIndexes->addIndex(index); // tl m_shellIndexes->addIndex(index+rowSize); // bl m_shellIndexes->addIndex(index+1); // tr m_shellIndexes->addIndex(index+rowSize); // bl m_shellIndexes->addIndex(index+rowSize+1); // br m_shellIndexes->addIndex(index+1); // tr } } } delete points; }