Mesh::Mesh(vector<Vertex> vertices, vector<Texture> textures, vector<glm::uvec3> indices, float max_X, float max_Y, float max_Z/*, vector<int> edgeIndicesToIndices*/) { this->vertices = vertices; this->textures = textures; this->indices = indices; //this->faceEdgeIndicesToIndices = edgeIndicesToIndices; //create_indices(); //shrink_vertices(); getAdjacentFacesVector(); //calcMax(); maxX = max_X; maxY = max_Y; maxZ = max_Z; calculateVertexNormals(); }
int CObject::loadObject(std::string path){ std::fstream file(path, std::fstream::in | std::fstream::out); if (!file.is_open()){ std::cout << "No se pudo abrir el archivo" << std::endl; return 0; } int i, j, indexMinMax = 0, numF; GLfloat point; std::vector <GLuint> fc,ft; GLuint pt; std::string type; file >> type; j = 0; fc.clear(); while (!file.eof()){ std::string subtype = type.substr(0, 1); std::string line; if (subtype == "#"){ std::getline(file, line); } if (type == "vt"){ std::getline(file, line); } if (type == "vn"){ std::getline(file, line); } //List of Vertex if (type == "v"){ for (i = 0; i < 3; i++){ file >> point; mVertex.push_back(point); switch (i){ case 0: if (xmin == NULL){ xmin = point; } else{ if (point < xmin) xmin = point; } if (xmax == NULL){ xmax = point; } else{ if (point > xmax) xmax = point; } break; case 1: if (ymin == NULL){ ymin = point; } else{ if (point < ymin) ymin = point; } if (ymax == NULL){ ymax = point; } else{ if (point > ymax) ymax = point; } break; case 2: if (zmin == NULL){ zmin = point; } else{ if (point < zmin) zmin = point; } if (zmax == NULL){ zmax = point; } else{ if (point > zmax) zmax = point; } break; } } mColor.push_back(0); mColor.push_back(1); mColor.push_back(0); nVertex++; // //calculateMinMax(indexMinMax); indexMinMax++; // }//List of Faces if (type == "f"){ std::getline(file, line); char * tok = strtok(&line[0u], " "); while (tok != NULL){ std::string num = tok; std::size_t pos = num.find("/"); num = num.substr(0, pos); pt = stoi(num); fc.push_back(pt); tok = strtok(NULL, " "); } nFaces++; for (j = 1; j < fc.size() - 1; j++){ mIndexes.push_back(fc[0] - 1); mIndexes.push_back(fc[j] - 1); mIndexes.push_back(fc[j + 1] - 1); } fc.clear(); } file >> type; } xmid = (xmin + xmax) / 2; ymid = (ymin + ymax) / 2; zmid = (zmin + zmax) / 2; calculateFaceNormals(); calculateVertexNormals(); //Initialize buffer file.close(); std::cout << "Object loaded" << std::endl; return 1; }
//function to pass all the array buffers into the openGL vertex buffers //P.S - This function has to be called in the end, once all the attributes for the objects have been set. void Object::initBuffers(const GLuint& program){ cout << "Normals Size: " << normals.size() << endl; cout << "Tangents Size: " << tangents.size() << endl; //get the attribute ids GLuint vertexAttributeID = glGetAttribLocation(program, "vPosition"); GLuint normalAttributeID = glGetAttribLocation(program, "vNormal"); GLuint uvAttributeID = glGetAttribLocation(program, "vTexCoord"); GLuint tangentAttributeID = glGetAttribLocation(program, "vTangent"); outVertices = new float[faces.size() * 3 * 3]; outNormals = new float[faces.size() * 3 * 3]; Vec3f v, n, t; int index = 0; for(unsigned i = 0; i < faces.size(); i++){ n = normals.at(faces.at(i)->n); if (tangents.size() > 0){ t = tangents.at(faces.at(i)->t); } for (unsigned j = 0; j < 3; j++){ v = points.at((*faces.at(i))[j]); outVertices[index] = v.x; outVertices[index + 1] = v.y; outVertices[index + 2] = v.z; if(!smooth){ outNormals[index] = n.x; outNormals[index + 1] = n.y; outNormals[index + 2] = n.z; if (t != Vec3f()){ outTangents[index] = t.x; outTangents[index + 1] = t.y; outTangents[index + 2] = t.z; } } index += 3; } } if (smooth){ calculateVertexNormals(); if (tangents.size() > 0){ calculateVertexTangents(); } } glBindVertexArray(vao); glGenBuffers(4, vbo); //pass the vertex buffers glBindBuffer(GL_ARRAY_BUFFER, vbo[0]); glBufferData(GL_ARRAY_BUFFER, faces.size() * 3 * 3 * sizeof(float), outVertices, GL_STATIC_DRAW); glEnableVertexAttribArray(vertexAttributeID); glVertexAttribPointer(vertexAttributeID, 3, GL_FLOAT, GL_FALSE, 0, 0); //pass the normal buffers (face or vertex) glBindBuffer(GL_ARRAY_BUFFER, vbo[1]); if(smooth) glBufferData(GL_ARRAY_BUFFER, faces.size() * 3 * 3 * sizeof(float), outVertexNormals, GL_STATIC_DRAW); else glBufferData(GL_ARRAY_BUFFER, faces.size() * 3 * 3 * sizeof(float), outNormals, GL_STATIC_DRAW); glEnableVertexAttribArray(normalAttributeID); glVertexAttribPointer(normalAttributeID, 3, GL_FLOAT, GL_FALSE, 0, 0); if(uv.size() > 0){ outUV = new float[uv.size() * 2]; index = 0; for(unsigned i = 0; i < uv.size(); i++){ outUV[index] = uv.at(i).x; outUV[index + 1] = uv.at(i).y; index += 2; } //pass the uv coord buffers glBindBuffer(GL_ARRAY_BUFFER, vbo[2]); glBufferData(GL_ARRAY_BUFFER, uv.size() * 2 * sizeof(float), outUV, GL_STATIC_DRAW); glEnableVertexAttribArray(uvAttributeID); glVertexAttribPointer(uvAttributeID, 2, GL_FLOAT, GL_FALSE, 0, 0); } if (tangents.size() > 0){ glBindBuffer(GL_ARRAY_BUFFER, vbo[3]); if (smooth) glBufferData(GL_ARRAY_BUFFER, faces.size() * 3 * 3 * sizeof(float), outVertexTangents, GL_STATIC_DRAW); else glBufferData(GL_ARRAY_BUFFER, faces.size() * 3 * 3 * sizeof(float), outTangents, GL_STATIC_DRAW); glEnableVertexAttribArray(tangentAttributeID); glVertexAttribPointer(tangentAttributeID, 3, GL_FLOAT, GL_FALSE, 0, 0); } }
IndexedFaceSetNode::IndexedFaceSetNode(VRMLParser& parser) :ccw(true),solid(true),convex(true), colorPerVertex(true), normalPerVertex(true),creaseAngle(0.0f) { /* Check for the opening brace: */ if(!parser.isToken("{")) Misc::throwStdErr("IndexedFaceSetNode::IndexedFaceSetNode: Missing opening brace in node definition"); parser.getNextToken(); /* Process attributes until closing brace: */ while(!parser.isToken("}")) { if(parser.isToken("ccw")) { parser.getNextToken(); ccw=SFBool::parse(parser); } else if(parser.isToken("solid")) { parser.getNextToken(); solid=SFBool::parse(parser); } else if(parser.isToken("convex")) { parser.getNextToken(); convex=SFBool::parse(parser); } else if(parser.isToken("colorPerVertex")) { parser.getNextToken(); colorPerVertex=SFBool::parse(parser); } else if(parser.isToken("normalPerVertex")) { parser.getNextToken(); normalPerVertex=SFBool::parse(parser); } else if(parser.isToken("creaseAngle")) { parser.getNextToken(); creaseAngle=SFFloat::parse(parser); } else if(parser.isToken("texCoord")) { /* Parse the texture coordinate node: */ parser.getNextToken(); texCoord=parser.getNextNode(); } else if(parser.isToken("color")) { /* Parse the color node: */ parser.getNextToken(); color=parser.getNextNode(); } else if(parser.isToken("normal")) { /* Parse the normal node: */ parser.getNextToken(); normal=parser.getNextNode(); } else if(parser.isToken("coord")) { /* Parse the coordinate node: */ parser.getNextToken(); coord=parser.getNextNode(); } else if(parser.isToken("texCoordIndex")) { /* Parse the texture coordinate index array: */ parser.getNextToken(); texCoordIndices=MFInt32::parse(parser); } else if(parser.isToken("colorIndex")) { /* Parse the color index array: */ parser.getNextToken(); colorIndices=MFInt32::parse(parser); } else if(parser.isToken("normalIndex")) { /* Parse the normal vector index array: */ parser.getNextToken(); normalIndices=MFInt32::parse(parser); } else if(parser.isToken("coordIndex")) { /* Parse the coordinate index array: */ parser.getNextToken(); coordIndices=MFInt32::parse(parser); /* Terminate the coordinate index array: */ if(coordIndices.back()>=0) coordIndices.push_back(-1); } else Misc::throwStdErr("IndexedFaceSetNode::IndexedFaceSetNode: unknown attribute \"%s\" in node definition",parser.getToken()); } /* Skip the closing brace: */ parser.getNextToken(); /* Create normal vectors if necessary: */ CoordinateNode* c=dynamic_cast<CoordinateNode*>(coord.getPointer()); NormalNode* n=dynamic_cast<NormalNode*>(normal.getPointer()); if(coord!=0&&n==0) { /* Create a new normal node and clear the normal index array: */ n=new NormalNode; normal=n; normalIndices.clear(); /* Create normal vectors and normal indices: */ if(normalPerVertex) calculateVertexNormals(c,coordIndices,Math::cos(creaseAngle),n,normalIndices); else calculateFaceNormals(c,coordIndices,n); } }
Model::Model(const char* filename) { char lineBuf[1024]; FILE* f = fopen(filename, "r"); // Initialize the extents - hopefully 1e10 is big enough! mExtents.minX = 1e10; mExtents.maxX = -1e10; mExtents.minY = 1e10; mExtents.maxY = -1e10; mExtents.minZ = 1e10; mExtents.maxZ = -1e10; // Read the list of points while(!feof(f)){ // Read the first character, ignoring whitespace char type1, type2; fscanf(f, " %c%c", &type1, &type2); if(type1 == 'v' && type2 == ' '){ // Vertex float x, y, z; fscanf(f, "%f %f %f", &x, &y, &z); // Read the three coordinates mVertices.push_back(point3(x, y, z)); // Save them in the vector if(x < mExtents.minX){ mExtents.minX = x; } if(y < mExtents.minY){ mExtents.minY = y; } if(z < mExtents.minZ){ mExtents.minZ = z; } if(x > mExtents.maxX){ mExtents.maxX = x; } if(y > mExtents.maxY){ mExtents.maxY = y; } if(z > mExtents.maxZ){ mExtents.maxZ = z; } } else if(type1 == 'v' && type2 == 'n'){ // Vertex normal float x, y, z; fscanf(f, "%f %f %f", &x, &y, &z); mVertexNormals.push_back(point3(x, y, z)); } else if(type1 == 'v' && type2 == 't'){ // Texture coordinate float x, y, z; fscanf(f, "%f %f %f", &x, &y, &z); mTextureCoords.push_back(point3(x, y, z)); } else if(type1 == 'f'){ // Face // This could be specified as either "f A B C" or as "f A/Anorm/Atex B/Bnorm/Btex ..." fscanf(f, " %[^\n]", lineBuf); if(strchr(lineBuf, '/')){ unsigned int a, aNorm, aTex, b, bNorm, bTex, c, cNorm, cTex; sscanf(lineBuf, "%d/%d/%d %d/%d/%d %d/%d/%d", &a, &aNorm, &aTex, &b, &bNorm, &bTex, &c, &cNorm, &cTex); mTriangles.push_back(triangle(a-1, b-1, c-1)); } else{ unsigned int a, b, c; sscanf(lineBuf, "%d %d %d", &a, &b, &c); // Read the three indices mTriangles.push_back(triangle(a-1, b-1, c-1)); // Save them in the vector } } else if(type1 == '#'){ // Comment; eat up the whole line fscanf(f, " %[^\n]", lineBuf); } else{ LOGI("Unexpected input character '%c' while reading OBJ file %s\n", type1, filename); fscanf(f, " %[^\n]", lineBuf); // Eat the whole line } } LOGI("Loaded model %s with %ld vertices, %ld faces\n", filename, mVertices.size(), mTriangles.size()); calculateFaceNormals(); if(mVertexNormals.size() == 0){ calculateVertexNormals(); } // Create buffer handles for all of our vertex attribute buffers glGenBuffers(4, mAttributeBuffers); loadVertexBuffers(); mFlatShading = true; mUseTexture = false; // Not ready to use texture until we've loaded one }
void Ivy::birth() { //evolve a gaussian filter over the adhesian vectors float gaussian[11] = {1.0f, 2.0f, 4.0f, 7.0f, 9.0f, 10.0f, 9.0f, 7.0f, 4.0f, 2.0f, 1.0f }; for(unsigned int r=0; r < roots.size(); r++) { for(int g = 0; g <5; ++g) { IvyRoot root = roots[r]; for(unsigned int n=0; n < root.nodes.size(); n++) { Vector3d e; for (int i = -5; i <= 5; ++i) { Vector3d tmpAdhesion; if ((n + i) < 0) tmpAdhesion = root.nodes.front().adhesionVector; if ((n + i) >= root.nodes.size()) tmpAdhesion = root.nodes.back().adhesionVector; if (((n + i) >= 0) && ((n + i) < root.nodes.size())) tmpAdhesion = root.nodes[n + i].adhesionVector; e += tmpAdhesion * gaussian[i+5]; } root.nodes[n].smoothAdhesionVector = e / 56.0f; } for(unsigned int n=0; n < root.nodes.size(); n++) { root.nodes[n].adhesionVector = root.nodes[n].smoothAdhesionVector; } } } // for (std::vector<IvyRoot>::iterator root = roots.begin(); root != roots.end(); ++root) // { // for (int g = 0; g < 5; ++g) // { // for (std::vector<IvyNode>::iterator node = root->nodes.begin(); node != root->nodes.end(); ++node) // { // Vector3d e; // for (int i = -5; i <= 5; ++i) // { // Vector3d tmpAdhesion; // if ((node + i) < root->nodes.begin()) // tmpAdhesion = root->nodes.front().adhesionVector; // if ((node + i) >= root->nodes.end()) // tmpAdhesion = root->nodes.back().adhesionVector; // if (((node + i) >= root->nodes.begin()) && ((node + i) < root->nodes.end())) // tmpAdhesion = (node + i)->adhesionVector; // e += tmpAdhesion * gaussian[i+5]; // } // node->smoothAdhesionVector = e / 56.0f; // } // for (std::vector<IvyNode>::iterator node = root->nodes.begin(); node != root->nodes.end(); ++node) // { // node->adhesionVector = node->smoothAdhesionVector; // } // } // } //parameters that depend on the scene object bounding sphere float local_ivyLeafSize = Common::mesh.boundingSphereRadius * ivySize * ivyLeafSize; float local_ivyBranchSize = Common::mesh.boundingSphereRadius * ivySize * ivyBranchSize; //reset existing geometry BasicMesh::reset(); //set data path path = "../textures/"; //create material for leafs BasicMaterial tmpMaterial; tmpMaterial.id = 1; tmpMaterial.name = "leaf_adult"; tmpMaterial.texFile = "efeu1.png"; materials.push_back( tmpMaterial ); //create second material for leafs tmpMaterial.id = 2; tmpMaterial.name = "leaf_young"; tmpMaterial.texFile = "efeu0.png"; materials.push_back( tmpMaterial ); //create material for branches tmpMaterial.id = 3; tmpMaterial.name = "branch"; tmpMaterial.texFile = "efeu_branch.png"; materials.push_back( tmpMaterial ); //create leafs for (std::vector<IvyRoot>::iterator root = roots.begin(); root != roots.end(); ++root) { //simple multiplier, just to make it a more dense for (int i = 0; i < 10; ++i) { //srand(i + (root - roots.begin()) * 10); for (std::vector<IvyNode>::iterator node = root->nodes.begin(); node != root->nodes.end(); ++node) { //weight depending on ratio of node length to total length float weight = pow(node->length / root->nodes.back().length, 0.7f); //test: the probability of leaves on the ground is increased float groundIvy = std::max<float>(0.0f, -Vector3d::dotProduct( Vector3d(0.0f, 1.0f, 0.0f), Vector3d::getNormalized(node->adhesionVector) )); weight += groundIvy * pow(1.0f - node->length / root->nodes.back().length, 2.0f); //random influence float probability = rand()/(float)RAND_MAX; if (probability * weight > leafProbability) { //alignment weight depends on the adhesion "strength" float alignmentWeight = node->adhesionVector.length(); //horizontal angle (+ an epsilon vector, otherwise there's a problem at 0� and 90�... mmmh) float phi = Vector2d::vectorToPolar( Vector2d::getNormalized( Vector2d(node->adhesionVector.z, node->adhesionVector.x) ) + Vector2d::getEpsilon() ) - PI * 0.5f; //vertical angle, trimmed by 0.5 float theta = Vector3d::getAngle( node->adhesionVector, Vector3d(0.0f, -1.0f, 0.0f) ) * 0.5f; //center of leaf quad Vector3d center = node->pos + Vector3d::getRandomized() * local_ivyLeafSize; //size of leaf float sizeWeight = 1.5f - (cos(weight * 2.0f * PI) * 0.5f + 0.5f); //random influence phi += (rand()/(float)RAND_MAX - 0.5f) * (1.3f - alignmentWeight); theta += (rand()/(float)RAND_MAX - 0.5f) * (1.1f - alignmentWeight); //create vertices BasicVertex tmpVertex; tmpVertex.pos = center + Vector3d(-local_ivyLeafSize * sizeWeight, 0.0f, local_ivyLeafSize * sizeWeight); tmpVertex.pos = Vector3d::rotateAroundAxis(tmpVertex.pos, center, Vector3d(0.0f, 0.0f, 1.0f), theta); tmpVertex.pos = Vector3d::rotateAroundAxis(tmpVertex.pos, center, Vector3d(0.0f, 1.0f, 0.0f), phi); tmpVertex.pos += Vector3d::getRandomized() * local_ivyLeafSize * sizeWeight * 0.5f; vertices.push_back( tmpVertex ); tmpVertex.pos = center + Vector3d( local_ivyLeafSize * sizeWeight, 0.0f, local_ivyLeafSize * sizeWeight); tmpVertex.pos = Vector3d::rotateAroundAxis(tmpVertex.pos, center, Vector3d(0.0f, 0.0f, 1.0f), theta); tmpVertex.pos = Vector3d::rotateAroundAxis(tmpVertex.pos, center, Vector3d(0.0f, 1.0f, 0.0f), phi); tmpVertex.pos += Vector3d::getRandomized() * local_ivyLeafSize * sizeWeight * 0.5f; vertices.push_back( tmpVertex ); tmpVertex.pos = center + Vector3d(-local_ivyLeafSize * sizeWeight, 0.0f, -local_ivyLeafSize * sizeWeight); tmpVertex.pos = Vector3d::rotateAroundAxis(tmpVertex.pos, center, Vector3d(0.0f, 0.0f, 1.0f), theta); tmpVertex.pos = Vector3d::rotateAroundAxis(tmpVertex.pos, center, Vector3d(0.0f, 1.0f, 0.0f), phi); tmpVertex.pos += Vector3d::getRandomized() * local_ivyLeafSize * sizeWeight * 0.5f; vertices.push_back( tmpVertex ); tmpVertex.pos = center + Vector3d( local_ivyLeafSize * sizeWeight, 0.0f, -local_ivyLeafSize * sizeWeight); tmpVertex.pos = Vector3d::rotateAroundAxis(tmpVertex.pos, center, Vector3d(0.0f, 0.0f, 1.0f), theta); tmpVertex.pos = Vector3d::rotateAroundAxis(tmpVertex.pos, center, Vector3d(0.0f, 1.0f, 0.0f), phi); tmpVertex.pos += Vector3d::getRandomized() * local_ivyLeafSize * sizeWeight * 0.5f; vertices.push_back( tmpVertex ); //create texCoords BasicTexCoord tmpTexCoord; tmpTexCoord.pos = Vector2d( 0.0f, 1.0f); texCoords.push_back( tmpTexCoord ); tmpTexCoord.pos = Vector2d( 1.0f, 1.0f); texCoords.push_back( tmpTexCoord ); tmpTexCoord.pos = Vector2d( 0.0f, 0.0f); texCoords.push_back( tmpTexCoord ); tmpTexCoord.pos = Vector2d( 1.0f, 0.0f); texCoords.push_back( tmpTexCoord ); //create triangle BasicTriangle tmpTriangle; tmpTriangle.matid = 1; float probability = rand()/(float)RAND_MAX; if (probability * weight > leafProbability) tmpTriangle.matid = 2; tmpTriangle.v0id = (unsigned int)vertices.size()-1; tmpTriangle.v1id = (unsigned int)vertices.size()-3; tmpTriangle.v2id = (unsigned int)vertices.size()-2; tmpTriangle.t0id = (unsigned int)vertices.size()-1; tmpTriangle.t1id = (unsigned int)vertices.size()-3; tmpTriangle.t2id = (unsigned int)vertices.size()-2; triangles.push_back( tmpTriangle ); tmpTriangle.v0id = (unsigned int)vertices.size()-2; tmpTriangle.v1id = (unsigned int)vertices.size()-0; tmpTriangle.v2id = (unsigned int)vertices.size()-1; tmpTriangle.t0id = (unsigned int)vertices.size()-2; tmpTriangle.t1id = (unsigned int)vertices.size()-0; tmpTriangle.t2id = (unsigned int)vertices.size()-1; triangles.push_back( tmpTriangle ); } } } } //branches for (std::vector<IvyRoot>::iterator root = roots.begin(); root != roots.end(); ++root) { //process only roots with more than one node if (root->nodes.size() == 1) continue; //branch diameter depends on number of parents float local_ivyBranchDiameter = 1.0f / (float)(root->parents + 1) + 1.0f; for (std::vector<IvyNode>::iterator node = root->nodes.begin(); node != root->nodes.end()-1; ++node) { //weight depending on ratio of node length to total length float weight = node->length / root->nodes.back().length; //create trihedral vertices Vector3d up = Vector3d(0.0f, -1.0f, 0.0f); Vector3d basis = Vector3d::getNormalized((node + 1)->pos - node->pos); Vector3d b0 = Vector3d::getNormalized( Vector3d::crossProduct(up, basis) ) * local_ivyBranchDiameter * local_ivyBranchSize * (1.3f - weight) + node->pos; Vector3d b1 = Vector3d::rotateAroundAxis(b0, node->pos, basis, 2.09f); Vector3d b2 = Vector3d::rotateAroundAxis(b0, node->pos, basis, 4.18f); //create vertices BasicVertex tmpVertex; tmpVertex.pos = b0; vertices.push_back( tmpVertex ); tmpVertex.pos = b1; vertices.push_back( tmpVertex ); tmpVertex.pos = b2; vertices.push_back( tmpVertex ); //create texCoords BasicTexCoord tmpTexCoord; float texV = (node - root->nodes.begin()) % 2 == 0 ? 1.0f : 0.0f; tmpTexCoord.pos = Vector2d( 0.0f, texV); texCoords.push_back( tmpTexCoord ); tmpTexCoord.pos = Vector2d( 0.3f, texV); texCoords.push_back( tmpTexCoord ); tmpTexCoord.pos = Vector2d( 0.6f, texV); texCoords.push_back( tmpTexCoord ); if (node == root->nodes.begin()) continue; //create triangle BasicTriangle tmpTriangle; tmpTriangle.matid = 3; tmpTriangle.v0id = (unsigned int)vertices.size()-3; tmpTriangle.v1id = (unsigned int)vertices.size()-0; tmpTriangle.v2id = (unsigned int)vertices.size()-4; tmpTriangle.t0id = (unsigned int)vertices.size()-3; tmpTriangle.t1id = (unsigned int)vertices.size()-0; tmpTriangle.t2id = (unsigned int)vertices.size()-4; triangles.push_back( tmpTriangle ); tmpTriangle.v0id = (unsigned int)vertices.size()-4; tmpTriangle.v1id = (unsigned int)vertices.size()-0; tmpTriangle.v2id = (unsigned int)vertices.size()-1; tmpTriangle.t0id = (unsigned int)vertices.size()-4; tmpTriangle.t1id = (unsigned int)vertices.size()-0; tmpTriangle.t2id = (unsigned int)vertices.size()-1; triangles.push_back( tmpTriangle ); tmpTriangle.v0id = (unsigned int)vertices.size()-4; tmpTriangle.v1id = (unsigned int)vertices.size()-1; tmpTriangle.v2id = (unsigned int)vertices.size()-5; tmpTriangle.t0id = (unsigned int)vertices.size()-4; tmpTriangle.t1id = (unsigned int)vertices.size()-1; tmpTriangle.t2id = (unsigned int)vertices.size()-5; triangles.push_back( tmpTriangle ); tmpTriangle.v0id = (unsigned int)vertices.size()-5; tmpTriangle.v1id = (unsigned int)vertices.size()-1; tmpTriangle.v2id = (unsigned int)vertices.size()-2; tmpTriangle.t0id = (unsigned int)vertices.size()-5; tmpTriangle.t1id = (unsigned int)vertices.size()-1; tmpTriangle.t2id = (unsigned int)vertices.size()-2; triangles.push_back( tmpTriangle ); tmpTriangle.v0id = (unsigned int)vertices.size()-5; tmpTriangle.v1id = (unsigned int)vertices.size()-2; tmpTriangle.v2id = (unsigned int)vertices.size()-0; tmpTriangle.t0id = (unsigned int)vertices.size()-5; tmpTriangle.t1id = (unsigned int)vertices.size()-2; tmpTriangle.t2id = (unsigned int)vertices.size()-0; triangles.push_back( tmpTriangle ); tmpTriangle.v0id = (unsigned int)vertices.size()-5; tmpTriangle.v1id = (unsigned int)vertices.size()-0; tmpTriangle.v2id = (unsigned int)vertices.size()-3; tmpTriangle.t0id = (unsigned int)vertices.size()-5; tmpTriangle.t1id = (unsigned int)vertices.size()-0; tmpTriangle.t2id = (unsigned int)vertices.size()-3; triangles.push_back( tmpTriangle ); } } //initialize ivy mesh loadTextures(); prepareData(); calculateVertexNormals(); prepareData(); createDisplayList(true); }