vector<int> Graph::getShortestPath(int start, int finish) { map<int,int> distances; priority_queue<Vertex> nodes; map<int,Vertex> previous; vector<int> path; map<int, vector<Vertex> >::iterator it; map<int, int>::iterator dis_it; map<int, Vertex>::iterator pre_it; for(it = this->vertexes.begin(); it != this->vertexes.end(); ++it) { if (it->first == start) { distances.insert(make_pair(start, 0)); nodes.push(Vertex(start, 0)); } else { distances.insert(make_pair(it->first, MAX_VALUE)); nodes.push(Vertex(it->first, MAX_VALUE)); } previous.insert(make_pair(it->first, Vertex(-1, 0))); } while(!nodes.empty()) { Vertex smallest = nodes.top(); nodes.pop(); if (smallest.getId() == finish) { while((pre_it = previous.find(smallest.getId())) != previous.end() && pre_it->second.getId()!=-1) { path.push_back(pre_it->first); smallest = pre_it->second; } if (!path.empty()) { path.push_back(start); } return path; } dis_it = distances.find(smallest.getId()); if (dis_it == distances.end()) { cout << "can not find distance for:" << smallest.getId() << endl; return path; } int distanceValue = dis_it->second; if (distanceValue == MAX_VALUE) { break; } it = this->vertexes.find(smallest.getId()); if (it == vertexes.end()) { return path; } vector<Vertex> nearNodes = it->second; for(int i = 0; i<nearNodes.size(); i++) { int n_id = nearNodes[i].getId(); int n_dis = nearNodes[i].getDistance(); int alt = distanceValue + n_dis; dis_it = distances.find(n_id); if (dis_it == distances.end()) { cout << "----------a----"<<endl; return path; } int dd = dis_it->second; bool need_fill = false; if (alt < dd) { //map无法覆盖key,只能下标方式 distances[n_id] = alt; previous[n_id] = smallest; vector<Vertex> tmp; need_fill = true; } vector<Vertex> tmp; while(!nodes.empty()) { Vertex v = nodes.top(); nodes.pop(); if (v.getId() == n_id && need_fill == true) { v.setDistance(alt); } tmp.push_back(v); } for (int k=0; k < tmp.size(); k++) { nodes.push(tmp[k]); } } } vector<int> v; //for(dis_it= distances.begin(); dis_it != distances.end(); dis_it++) { // v.push_back(dis_it->first); //} return v; }
bool MeshBuilder::buildMesh(const MeshData& data, Mesh& mesh) { std::map<std::pair<int, int>, int> edgeCount; std::map<std::pair<int, int>, HalfEdgeIter> existingHalfEdges; std::map<int, VertexIter> indexToVertex; std::map<HalfEdgeIter, bool> hasFlipEdge; preallocateMeshElements(data, mesh); // insert vertices into mesh and map vertex indices to vertex pointers for (unsigned int i = 0; i < data.positions.size(); i++) { VertexIter vertex = mesh.vertices.insert(mesh.vertices.end(), Vertex()); vertex->position = data.positions[i]; vertex->he = isolated.begin(); indexToVertex[i] = vertex; } // insert uvs into mesh for (unsigned int i = 0; i < data.uvs.size(); i++) { VectorIter uv = mesh.uvs.insert(mesh.uvs.end(), Eigen::Vector3d()); *uv = data.uvs[i]; } // insert normals into mesh for (unsigned int i = 0; i < data.normals.size(); i++) { VectorIter normal = mesh.normals.insert(mesh.normals.end(), Eigen::Vector3d()); *normal = data.normals[i]; } // insert faces into mesh int faceIndex = 0; bool degenerateFaces = false; for (std::vector<std::vector<Index>>::const_iterator f = data.indices.begin(); f != data.indices.end(); f ++) { int n = (int)f->size(); // check if face is degenerate if (n < 3) { std::cerr << "Error: face " << faceIndex << " is degenerate" << std::endl; degenerateFaces = true; continue; } // create face FaceIter newFace = mesh.faces.insert(mesh.faces.end(), Face()); // create a halfedge for each edge of the face std::vector<HalfEdgeIter> halfEdges(n); for (int i = 0; i < n; i++) { halfEdges[i] = mesh.halfEdges.insert(mesh.halfEdges.end(), HalfEdge()); } // initialize the halfedges for (int i = 0; i < n; i++) { // vertex indices int a = (*f)[i].position; int b = (*f)[(i+1)%n].position; // set halfedge attributes halfEdges[i]->next = halfEdges[(i+1)%n]; halfEdges[i]->vertex = indexToVertex[a]; int uv = (*f)[i].uv; if (uv >= 0) halfEdges[i]->uv = data.uvs[uv]; else halfEdges[i]->uv.setZero(); int normal = (*f)[i].normal; if (normal >= 0) halfEdges[i]->normal = data.normals[normal]; else halfEdges[i]->normal.setZero(); halfEdges[i]->onBoundary = false; // keep track of which halfedges have flip edges defined (for deteting boundaries) hasFlipEdge[halfEdges[i]] = false; // point vertex a at the current halfedge indexToVertex[a]->he = halfEdges[i]; // point new face and halfedge to each other halfEdges[i]->face = newFace; newFace->he = halfEdges[i]; // if an edge between a and b has been created in the past, it is the flip edge of the current halfedge if (a > b) std::swap(a, b); if (existingHalfEdges.find(std::pair<int, int>(a, b)) != existingHalfEdges.end()) { halfEdges[i]->flip = existingHalfEdges[std::pair<int, int>(a, b)]; halfEdges[i]->flip->flip = halfEdges[i]; halfEdges[i]->edge = halfEdges[i]->flip->edge; hasFlipEdge[halfEdges[i]] = true; hasFlipEdge[halfEdges[i]->flip] = true; } else { // create an edge and set its halfedge halfEdges[i]->edge = mesh.edges.insert(mesh.edges.end(), Edge()); halfEdges[i]->edge->he = halfEdges[i]; edgeCount[std::pair<int, int>(a, b)] = 0; } // record that halfedge has been created from a to b existingHalfEdges[std::pair<int, int>(a, b)] = halfEdges[i]; // check for nonmanifold edges edgeCount[std::pair<int, int>(a, b)] ++; if (edgeCount[std::pair<int, int>(a, b)] > 2) { std::cerr << "Error: edge " << a << ", " << b << " is non manifold" << std::endl; return false; } } faceIndex++; } if (degenerateFaces) { return false; } // insert extra faces for boundary cycle for (HalfEdgeIter currHe = mesh.halfEdges.begin(); currHe != mesh.halfEdges.end(); currHe++) { // if a halfedge with no flip edge is found, create a new face and link it the corresponding boundary cycle if (!hasFlipEdge[currHe]) { // create face FaceIter newFace = mesh.faces.insert(mesh.faces.end(), Face()); // walk along boundary cycle std::vector<HalfEdgeIter> boundaryCycle; HalfEdgeIter he = currHe; do { // create a new halfedge on the boundary face HalfEdgeIter newHe = mesh.halfEdges.insert(mesh.halfEdges.end(), HalfEdge()); newHe->onBoundary = true; // link the current halfedge in the cycle to its new flip edge he->flip = newHe; // grab the next halfedge along the boundary by finding // the next halfedge around the current vertex that doesn't // have a flip edge defined HalfEdgeIter nextHe = he->next; while (hasFlipEdge[nextHe]) { nextHe = nextHe->flip->next; } // set attritubes for new halfedge newHe->flip = he; newHe->vertex = nextHe->vertex; newHe->edge = he->edge; newHe->face = newFace; newHe->uv = nextHe->uv; // set face's halfedge to boundary halfedge newFace->he = newHe; boundaryCycle.push_back(newHe); // continue walk along cycle he = nextHe; } while (he != currHe); // link the cycle of boundary halfedges together int n = (int)boundaryCycle.size(); for (int i = 0; i < n; i++) { boundaryCycle[i]->next = boundaryCycle[(i+n-1)%n]; hasFlipEdge[boundaryCycle[i]] = true; hasFlipEdge[boundaryCycle[i]->flip] = true; } mesh.boundaries.insert(mesh.boundaries.end(), boundaryCycle[0]); } } indexVertices(mesh); checkIsolatedVertices(mesh); checkNonManifoldVertices(mesh); return true; }
void Scene::render(RenderContext* renderContext) { renderContext->scene = this; renderContext->viewpoint = viewpoint; // // CLEAR BUFFERS // GLbitfield clearFlags = 0; // Depth Buffer glClearDepth(1.0); glDepthFunc(GL_LESS); clearFlags |= GL_DEPTH_BUFFER_BIT; // Color Buffer (optional - depends on background node) clearFlags |= background->setupClear(renderContext); // clear glClear(clearFlags); // // SETUP LIGHTING MODEL // setupLightModel(renderContext); Sphere total_bsphere; if (data_bbox.isValid()) { // // GET DATA VOLUME SPHERE // total_bsphere = Sphere( (bboxDeco) ? bboxDeco->getBoundingBox(data_bbox) : data_bbox ); } else { total_bsphere = Sphere( Vertex(0,0,0), 1 ); } // // SETUP VIEWPORT TRANSFORMATION // glViewport(0,0,renderContext->size.width, renderContext->size.height); // // // viewpoint->setupFrustum( renderContext, total_bsphere ); // // RENDER BACKGROUND // background->render(renderContext); // // RENDER MODEL // if (data_bbox.isValid() ) { // // SETUP CAMERA // viewpoint->setupTransformation( renderContext, total_bsphere); // // RENDER BBOX DECO // if (bboxDeco) bboxDeco->render(renderContext); // // RENDER SOLID SHAPES // glEnable(GL_DEPTH_TEST); ListIterator iter(&shapes); for(iter.first(); !iter.isDone(); iter.next() ) { Shape* shape = (Shape*) iter.getCurrent(); if (!shape->getMaterial().alphablend) shape->render(renderContext); } // // RENDER ALPHA SHADED // for(iter.first(); !iter.isDone(); iter.next() ) { Shape* shape = (Shape*) iter.getCurrent(); if (shape->getMaterial().alphablend) shape->render(renderContext); } } }
Model ModelsFactory::cylinder(long double radius, long double height, int sides) { height /= 2.0L; Mesh *mesh = new Mesh(); Model model = Model(QString("(G) cylinder"), mesh, RGBA(0, 255, 0, 255)); int nbVerticesCap = sides + 1; int verticesLength = nbVerticesCap + nbVerticesCap;// + sides * 2 + 2; Vertex *vertices = new Vertex[verticesLength]; int vert = 0; const long double _2pi = M_PI * 2.0L; // Bottom cap // Центральная вершина нижней крышки vertices[vert++] = Vertex(0.0L, -height, 0.0L); while (vert <= sides) { long double rad = (long double)vert / sides * _2pi; vertices[vert] = Vertex(std::cos(rad) * radius, -height, std::sin(rad) * radius); vert++; } // Top cap vertices[vert++] = Vertex(0.0L, height, 0.0L); while (vert <= sides * 2 + 1) { long double rad = (long double)(vert - sides - 1) / sides * _2pi; vertices[vert] = Vertex(std::cos(rad) * radius, height, std::sin(rad) * radius); vert++; } // Triangles int nbTriangles = sides * 4;//sides * sides;// + sides * 2; int *triangles = new int[nbTriangles * 3/* + 3*/]; // Bottom cap int tri = 0; int i = 0; while (tri < sides - 1) { triangles[i] = 0; triangles[i + 1] = tri + 1; triangles[i + 2] = tri + 2; tri++; i += 3; } triangles[i] = 0; triangles[i + 1] = tri + 1; triangles[i + 2] = 1; tri++; i += 3; // Top cap tri++; while (tri < sides * 2) { triangles[i] = tri + 2; triangles[i + 1] = tri + 1; triangles[i + 2] = nbVerticesCap; tri++; i += 3; } triangles[i] = nbVerticesCap + 1; triangles[i + 1] = tri + 1; triangles[i + 2] = nbVerticesCap; tri++; i += 3; tri++; // Sides int j = tri; while (j <= nbTriangles - 2) { triangles[i] = tri - nbVerticesCap * 2 + 1; triangles[i + 1] = tri - nbVerticesCap + 1; triangles[i + 2] = tri - nbVerticesCap * 2 + 2; //tri++; j++; i += 3; triangles[i] = tri - nbVerticesCap * 2 + 2; triangles[i + 1] = tri - nbVerticesCap + 1; triangles[i + 2] = tri - nbVerticesCap + 2; tri++; j++; i += 3; } triangles[i] = tri - nbVerticesCap * 2 + 1; triangles[i + 1] = tri - nbVerticesCap + 1; triangles[i + 2] = 1; i += 3; triangles[i] = 1; triangles[i + 1] = tri - nbVerticesCap + 1; triangles[i + 2] = 1 + nbVerticesCap; for (int i = 0; i < verticesLength; i++) { mesh->addVertex(vertices[i]); } for (int i = 0; i < nbTriangles * 3; i += 3) { mesh->addFace(Face(triangles[i], triangles[i + 1], triangles[i + 2])); } delete[] triangles; delete[] vertices; return model; }
void GeometricHelperTest::LineSegmentLineIntersectionTest() { { LineSegment ls(Vertex(0, 1), Vertex(1, 1)); Line line(Vertex(0, 0), Vertex(1, 2)); // segment/line intersect boost::optional<Vertex> intersection_point_opt = GeometricHelper::intersect(ls, line); CPPUNIT_ASSERT_MESSAGE("Intersection point expected", bool(intersection_point_opt)); Vertex intersection_point = *intersection_point_opt; CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Intersection point error", 0.5, intersection_point.x(), 1E-10); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Intersection point error", 1.0, intersection_point.y(), 1E-10); } { LineSegment ls(Vertex(0, 3), Vertex(1, 3)); Line line(Vertex(0, 0), Vertex(0.25, 1)); // segment/line intersect boost::optional<Vertex> intersection_point_opt = GeometricHelper::intersect(ls, line); CPPUNIT_ASSERT_MESSAGE("Intersection point expected", bool(intersection_point_opt)); Vertex intersection_point = *intersection_point_opt; CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Intersection point error", 0.75, intersection_point.x(), 1E-10); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Intersection point error", 3.0, intersection_point.y(), 1E-10); } { LineSegment ls(Vertex(0, 1), Vertex(1, 1)); Line line(Vertex(0.25, 2), Vertex(1, 4)); // segment/line do not intersect boost::optional<Vertex> intersection_point_opt = GeometricHelper::intersect(ls, line); CPPUNIT_ASSERT_MESSAGE("No intersection point expected", !bool(intersection_point_opt)); } { LineSegment ls(Vertex(0, 1), Vertex(1, 1)); Line line(Vertex(0, 0), Vertex(2, 1)); // segments do not intersect boost::optional<Vertex> intersection_point_opt = GeometricHelper::intersect(ls, line); CPPUNIT_ASSERT_MESSAGE("No intersection point expected", !bool(intersection_point_opt)); } { LineSegment ls(Vertex(0, 1), Vertex(1, 1)); Line line(Vertex(0.5, 1), Vertex(2, 1)); // segment/line overlap boost::optional<Vertex> intersection_point_opt = GeometricHelper::intersect(ls, line); CPPUNIT_ASSERT_MESSAGE("No intersection point expected", !bool(intersection_point_opt)); } { LineSegment ls(Vertex(0.5, 1), Vertex(1, 1)); Line line(Vertex(0, 1), Vertex(2, 1)); // segment contained in line boost::optional<Vertex> intersection_point_opt = GeometricHelper::intersect(ls, line); CPPUNIT_ASSERT_MESSAGE("No intersection point expected", !bool(intersection_point_opt)); } { LineSegment ls(Vertex(0, 1), Vertex(1, 1)); Line line(Vertex(1.5, 1), Vertex(2, 1)); // segment and line parallel boost::optional<Vertex> intersection_point_opt = GeometricHelper::intersect(ls, line); CPPUNIT_ASSERT_MESSAGE("No intersection point expected", !bool(intersection_point_opt)); } { LineSegment ls(Vertex(0, 1), Vertex(1, 1)); Line line(Vertex(1.5, 2), Vertex(2, 2)); // segment and line parallel, but not collinear boost::optional<Vertex> intersection_point_opt = GeometricHelper::intersect(ls, line); CPPUNIT_ASSERT_MESSAGE("No intersection point expected", !bool(intersection_point_opt)); } }
NV_INT32 ComputeLineDistanceFilter (NV_F64_COORD2 lineStart, NV_F64_COORD2 lineEnd, MISC *misc, OPTIONS *options) { NV_INT32 numPointsWithin = 0; NV_FLOAT64 utmE, utmN; NV_BOOL hitMax = NVFalse; QColor color; QColor GetAVShotColor (NV_INT32 index, MISC *misc, OPTIONS *options); for (NV_INT32 i = 0; i < misc->abe_share->point_cloud_count; i++) { // only check non-deleted shots if ((!check_bounds (options, misc, i, NVTrue, NVFalse)) && misc->data[i].type == PFM_CZMIL_DATA) { NV_FLOAT64 x = misc->data[i].x * NV_DEG_TO_RAD; NV_FLOAT64 y = misc->data[i].y * NV_DEG_TO_RAD; pj_transform (misc->pj_latlon, misc->pj_utm, 1, 1, &x, &y, NULL); utmE = x; utmN = y; Vertex ptOfInterest (utmE, utmN, 0.0f); Vertex closestPt = Vector::ClosestPtOnLine (Vertex (lineStart.x, lineStart.y, 0.0f), Vertex (lineEnd.x, lineEnd.y, 0.0f), ptOfInterest); if (Vector::GetDistance (ptOfInterest, closestPt) < options->distThresh) { // load up the shots array for AV misc->avb.shotArray[numPointsWithin].recordNumber = misc->data[i].rec; misc->avb.shotArray[numPointsWithin].subRecordNumber = misc->data[i].sub; misc->avb.shotArray[numPointsWithin].pfmHandle = misc->pfm_handle[misc->data[i].pfm]; misc->avb.shotArray[numPointsWithin].fileNo = misc->data[i].file; misc->avb.shotArray[numPointsWithin].masterIdx = i; misc->avb.shotArray[numPointsWithin].type = misc->data[i].type; color = GetAVShotColor (i, misc, options); misc->avb.shotArray[numPointsWithin].colorH = color.hue (); misc->avb.shotArray[numPointsWithin].colorS = color.saturation(); misc->avb.shotArray[numPointsWithin].colorV = color.value(); numPointsWithin++; if (numPointsWithin == MAX_ATTRIBUTE_SHOTS) { hitMax = NVTrue; // If we hit the maximum, send a message out for the user to re-select. QString msg = QString (pfmEdit3D::tr ("The line specified results in more shots satisfying the threshold than can be held (MAX = %1).\n").arg (MAX_ATTRIBUTE_SHOTS) + pfmEdit3D::tr ("Please draw a shorter line or change the distance threshold parameter")); QMessageBox::warning (0, pfmEdit3D::tr ("pfmEdit3D"), msg); return 0; break; } } } } // lock shared memory and load up shots and notify AV new data is coming misc->abeShare->lock(); if (numPointsWithin > 0) { misc->av_dist_count = numPointsWithin; misc->av_dist_list = (NV_INT32 *) realloc (misc->av_dist_list, (misc->av_dist_count + 1) * sizeof (NV_INT32)); if (misc->av_dist_list == NULL) { perror ("Allocating misc->av_dist_list memory in pfmEdit3D"); exit (-1); } for (NV_INT32 i = 0; i < numPointsWithin; i++) { misc->abe_share->avShare.shots[i] = misc->avb.shotArray[i]; misc->av_dist_list[i] = misc->avb.shotArray[i].masterIdx; } } misc->abe_share->avShare.numShots = numPointsWithin; misc->abe_share->avShare.avNewData = NVTrue; misc->abe_share->avShare.hitMax = hitMax; misc->abeShare->unlock(); return (numPointsWithin); }
void CSimpleUGraph< ObjT, Compare >::AddVertex( const ObjT &oNewVertex ) { Vertex u; typename DataVertexMapT::iterator vMapPos; bool bInserted; if( oDataToVertexMap.find( oNewVertex ) != oDataToVertexMap.end() ) return; // note that Vertex() is just a place holder boost::tie( vMapPos, bInserted ) = oDataToVertexMap.insert( std::make_pair( oNewVertex, Vertex() ) ); if ( bInserted ) // If data is not already added in the map { u = add_vertex( oBoostGraph ); // add new vertex to graph oVertexToDataMap[ u ] = oNewVertex; // name the vertex with the current data vMapPos->second = u; // assign the correct vertex to the map } // If data (NewVertex) already exist in the map, do nothing }
void AnimatedMesh::LoadFromFile(string file) { // if substr of the last 4 = .obj do this: - else load other format / print error ObjLoader oj; // Get the directory correct string tempFilename = file; string pathfolder = ""; size_t slashpos = tempFilename.find("/"); while(slashpos != string::npos) { slashpos = tempFilename.find("/"); pathfolder += tempFilename.substr(0, slashpos+1); tempFilename = tempFilename.substr(slashpos + 1); } ifstream anifile; anifile.open(file); if(anifile) { string line = ""; getline(anifile, line); int nrOfKeyframes = atoi(line.c_str()); for(int a = 0; a < nrOfKeyframes; a++) { int time = 0; string path = ""; getline(anifile, line); time = atoi(line.c_str()); getline(anifile, path); KeyFrame* frame = new KeyFrame(); frame->time = time; { ObjData* od = oj.LoadObjFile(pathfolder + path); MaloW::Array<MaterialData>* mats = od->mats; for(int q = 0; q < mats->size(); q++) { bool hasFace = false; MeshStrip* strip = new MeshStrip(); int nrOfVerts = 0; Vertex* tempverts = new Vertex[od->faces->size()*3]; for(int i = 0; i < od->faces->size(); i++) { if(od->faces->get(i).material == mats->get(q).name) { int vertpos = od->faces->get(i).data[0][0] - 1; int textcoord = od->faces->get(i).data[0][1] - 1; int norm = od->faces->get(i).data[0][2] - 1; tempverts[nrOfVerts] = Vertex(od->vertspos->get(vertpos), od->textcoords->get(textcoord), od->vertsnorms->get(norm)); nrOfVerts++; vertpos = od->faces->get(i).data[2][0] - 1; textcoord = od->faces->get(i).data[2][1] - 1; norm = od->faces->get(i).data[2][2] - 1; tempverts[nrOfVerts] = Vertex(od->vertspos->get(vertpos), od->textcoords->get(textcoord), od->vertsnorms->get(norm)); nrOfVerts++; vertpos = od->faces->get(i).data[1][0] - 1; textcoord = od->faces->get(i).data[1][1] - 1; norm = od->faces->get(i).data[1][2] - 1; tempverts[nrOfVerts] = Vertex(od->vertspos->get(vertpos), od->textcoords->get(textcoord), od->vertsnorms->get(norm)); nrOfVerts++; hasFace = true; } } strip->setNrOfVerts(nrOfVerts); Vertex* verts = new Vertex[nrOfVerts]; for(int z = 0; z < nrOfVerts; z++) { verts[z] = tempverts[z]; } delete tempverts; strip->SetVerts(verts); strip->SetTexturePath(od->mats->get(q).texture); Material* mat = new Material(); mat->AmbientColor = od->mats->get(q).ka; if(mat->AmbientColor == D3DXVECTOR3(0.0f, 0.0f, 0.0f)) //////////// MaloW Fix, otherwise completely black with most objs mat->AmbientColor += D3DXVECTOR3(0.2f, 0.2f, 0.2f); //////////// MaloW Fix, otherwise completely black with most objs mat->DiffuseColor = od->mats->get(q).kd; if(mat->DiffuseColor == D3DXVECTOR3(0.0f, 0.0f, 0.0f)) //////////// MaloW Fix, otherwise completely black with most objs mat->DiffuseColor += D3DXVECTOR3(0.6f, 0.6f, 0.6f); //////////// MaloW Fix, otherwise completely black with most objs mat->SpecularColor = od->mats->get(q).ks; strip->SetMaterial(mat); if(hasFace) frame->strips->add(strip); else delete strip; } this->topology = D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST; delete od; } this->mKeyFrames->add(frame); } } else MaloW::Debug("Failed to open AnimatedMesh: " + file); }
void Text::UpdateGeometry() { assert(myFont != NULL); // Clear the previous geometry myVertices.Clear(); // No text: nothing to draw if (myString.IsEmpty()) return; // Compute values related to the text style bool bold = (myStyle & Bold) != 0; bool underlined = (myStyle & Underlined) != 0; float italic = (myStyle & Italic) ? 0.208f : 0.f; // 12 degrees float underlineOffset = myCharacterSize * 0.1f; float underlineThickness = myCharacterSize * (bold ? 0.1f : 0.07f); // Precompute the variables needed by the algorithm float hspace = static_cast<float>(myFont->GetGlyph(L' ', myCharacterSize, bold).Advance); float vspace = static_cast<float>(myFont->GetLineSpacing(myCharacterSize)); float x = 0.f; float y = static_cast<float>(myCharacterSize); // Create one quad for each character Uint32 prevChar = 0; for (std::size_t i = 0; i < myString.GetSize(); ++i) { Uint32 curChar = myString[i]; // Apply the kerning offset x += static_cast<float>(myFont->GetKerning(prevChar, curChar, myCharacterSize)); prevChar = curChar; // If we're using the underlined style and there's a new line, draw a line if (underlined && (curChar == L'\n')) { float top = y + underlineOffset; float bottom = top + underlineThickness; myVertices.Append(Vertex(Vector2f(0, top), myColor, Vector2f(1, 1))); myVertices.Append(Vertex(Vector2f(x, top), myColor, Vector2f(2, 1))); myVertices.Append(Vertex(Vector2f(x, bottom), myColor, Vector2f(2, 2))); myVertices.Append(Vertex(Vector2f(0, bottom), myColor, Vector2f(1, 2))); } // Handle special characters switch (curChar) { case L' ' : x += hspace; continue; case L'\t' : x += hspace * 4; continue; case L'\n' : y += vspace; x = 0; continue; case L'\v' : y += vspace * 4; continue; } // Extract the current glyph's description const Glyph& glyph = myFont->GetGlyph(curChar, myCharacterSize, bold); int left = glyph.Bounds.Left; int top = glyph.Bounds.Top; int right = glyph.Bounds.Left + glyph.Bounds.Width; int bottom = glyph.Bounds.Top + glyph.Bounds.Height; float u1 = static_cast<float>(glyph.TextureRect.Left); float v1 = static_cast<float>(glyph.TextureRect.Top); float u2 = static_cast<float>(glyph.TextureRect.Left + glyph.TextureRect.Width); float v2 = static_cast<float>(glyph.TextureRect.Top + glyph.TextureRect.Height); // Add a quad for the current character myVertices.Append(Vertex(Vector2f(x + left - italic * top, y + top), myColor, Vector2f(u1, v1))); myVertices.Append(Vertex(Vector2f(x + right - italic * top, y + top), myColor, Vector2f(u2, v1))); myVertices.Append(Vertex(Vector2f(x + right - italic * bottom, y + bottom), myColor, Vector2f(u2, v2))); myVertices.Append(Vertex(Vector2f(x + left - italic * bottom, y + bottom), myColor, Vector2f(u1, v2))); // Advance to the next character x += glyph.Advance; } // If we're using the underlined style, add the last line if (underlined) { float top = y + underlineOffset; float bottom = top + underlineThickness; myVertices.Append(Vertex(Vector2f(0, top), myColor, Vector2f(1, 1))); myVertices.Append(Vertex(Vector2f(x, top), myColor, Vector2f(2, 1))); myVertices.Append(Vertex(Vector2f(x, bottom), myColor, Vector2f(2, 2))); myVertices.Append(Vertex(Vector2f(0, bottom), myColor, Vector2f(1, 2))); } // Recompute the bounding rectangle myBounds = myVertices.GetBounds(); }
static Polygon CreateRect (float x, float y, float width, float height) { return CreateRect(Vertex(x, y), width, height); }
void GraphicsSystem::Vertex(float x, float y, float z) { Vect v(x, y, z); Vertex(v); }
void Cuboid::CreateVertexBuffer(const float width, const float height, const float depth) { Vertex cubeVerts[] = { //Front Vertex(glm::vec3(width, height, -depth), glm::vec2(0.0f, 0.0f), glm::vec3(0.0f, 0.0f, -1.0f)), Vertex(glm::vec3(-width, height, -depth), glm::vec2(1.0f, 0.0f), glm::vec3(0.0f, 0.0f, -1.0f)), Vertex(glm::vec3(-width, -height, -depth), glm::vec2(1.0f, 1.0f), glm::vec3(0.0f, 0.0f, -1.0f)), Vertex(glm::vec3(width, -height, -depth), glm::vec2(0.0f, 1.0f), glm::vec3(0.0f, 0.0f, -1.0f)), //Back Vertex(glm::vec3(width, height, depth), glm::vec2(0.0f, 0.0f), glm::vec3(0.0f, 0.0f, 1.0f)), Vertex(glm::vec3(-width, height, depth), glm::vec2(1.0f, 0.0f), glm::vec3(0.0f, 0.0f, 1.0f)), Vertex(glm::vec3(-width, -height, depth), glm::vec2(1.0f, 1.0f), glm::vec3(0.0f, 0.0f, 1.0f)), Vertex(glm::vec3(width, -height, depth), glm::vec2(0.0f, 1.0f), glm::vec3(0.0f, 0.0f, 1.0f)), //Right Vertex(glm::vec3(-width, height, -depth), glm::vec2(0.0f, 0.0f), glm::vec3(-1.0f, 0.0f, 0.0f)), Vertex(glm::vec3(-width, height, depth), glm::vec2(1.0f, 0.0f), glm::vec3(-1.0f, 0.0f, 0.0f)), Vertex(glm::vec3(-width, -height, depth), glm::vec2(1.0f, 1.0f), glm::vec3(-1.0f, 0.0f, 0.0f)), Vertex(glm::vec3(-width, -height, -depth), glm::vec2(0.0f, 1.0f), glm::vec3(-1.0f, 0.0f, 0.0f)), //Left Vertex(glm::vec3(width, height, -depth), glm::vec2(0.0f, 0.0f), glm::vec3(1.0f, 0.0f, 0.0f)), Vertex(glm::vec3(width, height, depth), glm::vec2(1.0f, 0.0f), glm::vec3(1.0f, 0.0f, 0.0f)), Vertex(glm::vec3(width, -height, depth), glm::vec2(1.0f, 1.0f), glm::vec3(1.0f, 0.0f, 0.0f)), Vertex(glm::vec3(width, -height, -depth), glm::vec2(0.0f, 1.0f), glm::vec3(1.0f, 0.0f, 0.0f)), //Top Vertex(glm::vec3(-width, height, depth), glm::vec2(0.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f)), Vertex(glm::vec3(width, height, depth), glm::vec2(1.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f)), Vertex(glm::vec3(width, height, -depth), glm::vec2(1.0f, 1.0f), glm::vec3(0.0f, 1.0f, 0.0f)), Vertex(glm::vec3(-width, height, -depth), glm::vec2(0.0f, 1.0f), glm::vec3(0.0f, 1.0f, 0.0f)), //Bottom Vertex(glm::vec3(-width, -height, depth), glm::vec2(0.0f, 0.0f), glm::vec3(0.0f, -1.0f, 0.0f)), Vertex(glm::vec3(width, -height, depth), glm::vec2(1.0f, 0.0f), glm::vec3(0.0f, -1.0f, 0.0f)), Vertex(glm::vec3(width, -height, -depth), glm::vec2(1.0f, 1.0f), glm::vec3(0.0f, -1.0f, 0.0f)), Vertex(glm::vec3(-width, -height, -depth), glm::vec2(0.0f, 1.0f), glm::vec3(0.0f, -1.0f, 0.0f)) }; glm::vec3 cVerts[] = { //Front glm::vec3(width, height, -depth), glm::vec3(-width, height, -depth), glm::vec3(-width, -height, -depth), glm::vec3(width, -height, -depth), //Back glm::vec3(width, height, depth), glm::vec3(-width, height, depth), glm::vec3(-width, -height, depth), glm::vec3(width, -height, depth), }; renderVertsCount = 24; colliderVertsCount = 8; faceIndicesCount = 30; verts.reserve(renderVertsCount); for(int i = 0; i < renderVertsCount; i++) verts.push_back(cubeVerts[i]); collisionVerts.reserve(colliderVertsCount); for(int i = 0; i < colliderVertsCount; i++) collisionVerts.push_back(cVerts[i]); const int arr[] = { 4, 0,3,2,1, //Front 4, 4,5,6,7, //Back 4, 1,2,6,5, //Right 4, 0,4,7,3, //Left 4, 5,4,0,1, //Top 4, 6,2,3,7 //Bottom }; faceIndices.reserve(faceIndicesCount); for(int i = 0; i < faceIndicesCount; i++) faceIndices.push_back(arr[i]); glGenBuffers(1, &VBO); glBindBuffer(GL_ARRAY_BUFFER, VBO); glBufferData(GL_ARRAY_BUFFER, sizeof(cubeVerts), cubeVerts, GL_STATIC_DRAW); }
void Polyhedron::initPolyhedron(int _m, int _n) { origin = new Point(0, 3, 0); Vector3f farpoint[20][3]; //corners of a triangle that encompass all points of ico triangle std::vector<Triangle> subTriangles; std::vector<Point> basepoint; //points on an abstract triangle that coincide with actual points on the real triangle. x = A, y = B, z = C std::vector<Point *> pPoints; if (_m < 0 || _n < 0) return; if (_n > _m) { m = _n; n = _m; } else { m = _m; n = _n; } //debug unsigned int currentTime = SDL_GetTicks(), newTime; std::cout << m << ", " << n << '\n'; float L = m + n * 2 - 3; if (n == 0) { L = m; for (int i = 0; i < 20; i++) { farpoint[i][0] = icoTriangles[i].a; farpoint[i][1] = icoTriangles[i].b; farpoint[i][2] = icoTriangles[i].c; } //populate basepoint array for (int A = 0; A < m + 1; A++) { for (int B = L - A; B < m + 1; B++) { basepoint.push_back(Vector3f(A, B, m * 2 - A - B)); } } } if (n > 0) { float length = sqrt(pow(m + n / 2, 2) + pow(tri_height*n, 2)); //length of the side of the triangle //Begin by finding 3 points that encompass all possible points within the triangle float angle = atan((tri_height * m) / (n + m / 2)); float x = n / 2; float y = tan(angle) * x; float h = y / sin(angle); //hypotneuse float s_length = length - h; float l = tri_height * (n - 2); float w = (m * 2 + n * 4 - 6) * tri_height / 3; float q = w - y - l; for (int i = 0; i < 20; i++) { Vector3f Z = icoTriangles[i].center; Vector3f D = (icoTriangles[i].a * (s_length)+icoTriangles[i].b * (h)) / length; Vector3f E = (icoTriangles[i].b * (s_length)+icoTriangles[i].c * (h)) / length; Vector3f F = (icoTriangles[i].c * (s_length)+icoTriangles[i].a * (h)) / length; Vector3f D_diff = Z - D; Vector3f E_diff = Z - E; Vector3f F_diff = Z - F; farpoint[i][0] = D - D_diff * ((w - q) / q); farpoint[i][1] = E - E_diff * ((w - q) / q); farpoint[i][2] = F - F_diff * ((w - q) / q); } //populate basepoint array Vector2f bA = { 0, L }; Vector2f bB = { L, 0 }; Vector2f bC = { L, L }; Vector2f rA = { n - 2, m + n * 2 - 2 }; Vector2f rB = { m + n - 2, n - 2 }; Vector2f rC = { m + n * 2 - 2, m + n - 2 }; //slopes of line of triangle float mAB = (rB.y - rA.y) / (rB.x - rA.x); float mBC = (rC.y - rB.y) / (rC.x - rB.x); float mAC = (rC.y - rA.y) / (rC.x - rA.x); //now find every point within the triangle, excluding ones outside the triangle for (int A = 0; A < L + 1; A++) { for (int B = L - A; B < L + 1; B++) { int C = L * 2 - A - B; if (rA.y - mAB * rA.x <= B - mAB * A) { if (rB.y - mBC * rB.x <= B - mBC * A) { if (rC.y - mAC * rC.x >= B - mAC * A) { basepoint.push_back(Vector3f(A, B, C)); //std::cout << A << ", " << B << ", " << C << "\n"; } } } } } } points.reserve(basepoint.size() * 20 + 13); //this makes sure the vectors memory is never reallocated, which would invalidate any pointers to its contents //fill in known neighbours now, its faster this way std::vector<Point>::iterator nearPointsTemp[6]; std::vector<std::vector<int>> nearPoints(basepoint.size()); int index = 0; for (std::vector<Point>::iterator i = basepoint.begin(); i != basepoint.end(); i++) { nearPointsTemp[0] = std::find(basepoint.begin(), i, *i + Vector3f(-1, 0, 1)); nearPointsTemp[1] = std::find(basepoint.begin(), i, *i + Vector3f(-1, 1, 0)); if (index > 0 && *std::prev(i,1) == *i + Vector3f(0, -1, 1)) { nearPointsTemp[2] = std::prev(i,1); } else { nearPointsTemp[2] = basepoint.end(); } if (index < basepoint.size() - 1 && *std::next(i,1) == *i + Vector3f(0, 1, -1)) { nearPointsTemp[3] = std::next(i,1); } else { nearPointsTemp[3] = basepoint.end(); } nearPointsTemp[4] = std::find(i, basepoint.end(), *i + Vector3f(1, -1, 0)); nearPointsTemp[5] = std::find(i, basepoint.end(), *i + Vector3f(1, 0, -1)); for (int j = 0; j < 6; j++) { if (nearPointsTemp[j] != basepoint.end() && nearPointsTemp[j] != i) { basepoint[index].neighbour.push_back(&*nearPointsTemp[j]); nearPoints[index].push_back(nearPointsTemp[j] - basepoint.begin()); } } index++; } //take the basepoints and use them as a template to populate all 20 sides of the icosahedron. if (m == 1 && n == 1) L = 1; //otherwise L would be 0 and would cause a divide by zero error Point temp_Point; std::vector<Point>::iterator cPoint; for (int i = 0; i < 20; i++) { std::vector<Point *> facePoints; //place the actual points for (int j = 0; j < basepoint.size(); j++) { temp_Point = (farpoint[i][0] * (L - basepoint[j].x) + farpoint[i][1] * (L - basepoint[j].y) + farpoint[i][2] * (L - basepoint[j].z)) / L; cPoint = std::find(points.begin(), points.end(), temp_Point); if (cPoint == points.end()) { points.push_back(temp_Point); facePoints.push_back(&points.back()); } else { facePoints.push_back(&*cPoint); } } //now link the known neighbours together for (int j = 0; j < basepoint.size(); j++) { for (int k = 0; k < basepoint[j].neighbour.size(); k++) { facePoints[j]->neighbour.push_back(facePoints[nearPoints[j][k]]); } } } //Make sure that the pentagons only get 5 neighbours. The first 12 points should be the pentagons as they were added in first unsigned vSize = points.size(); for (unsigned i = 0; i < 12; i++) { points[i].neighbours = 5; } //Normalize the points to form a sphere for (unsigned i = 0; i < vSize; i++) { points[i].Normalize(); } //now figure out all the missing neighbours for each point std::vector<Point *> vecNeighbour; std::vector<Point *>::iterator it; //First add each point that doesnt have all its neighbours to a vector of pointers for (unsigned i = 0; i < vSize; i++) { if (points[i].neighbour.size() != points[i].neighbours) vecNeighbour.push_back(&points[i]); } do { origin = vecNeighbour.back(); vecNeighbour.pop_back(); //sort by distance to the point being neighboured, origin, and then fill in the missing neighbours vSize = vecNeighbour.size(); for (unsigned i = 0; i < vSize; i++) { vecNeighbour[i]->setDistFromOrigin(); } std::sort(vecNeighbour.begin(), vecNeighbour.end(), SORT_BY_PROXIMITY); int limit = origin->neighbours; if (limit > vSize) limit = vSize; for (unsigned i = 0; i < limit; i++) { if (std::find(origin->neighbour.begin(), origin->neighbour.end(), vecNeighbour[i]) == origin->neighbour.end()) { origin->neighbour.push_back(vecNeighbour[i]); vecNeighbour[i]->neighbour.push_back(origin); } if (origin->neighbour.size() == origin->neighbours) break; } vSize = points.size(); vecNeighbour.clear(); for (unsigned i = 0; i < vSize; i++) { if (points[i].neighbour.size() != points[i].neighbours) vecNeighbour.push_back(&points[i]); } } while (vecNeighbour.size() > 0); vSize = points.size(); //Assign a number to each point, starting from the top and working down in a spiral. //first establish the first and second point Point * tempPoint = &points[0]; for (unsigned i = 1; i < vSize; i++) { if (points[i].y > tempPoint->y) tempPoint = &points[i]; } //get the highest point by y value tempPoint->ID = 0; tempPoint = tempPoint->neighbour[0]; tempPoint->ID = 1; for (unsigned i = 2; i < vSize; i++) { int least[6] = { tempPoint->ID, tempPoint->ID, tempPoint->ID, tempPoint->ID, tempPoint->ID, tempPoint->ID }; for (unsigned j = 0; j < tempPoint->neighbours; j++) { if (tempPoint->neighbour[j]->ID == -1) { for (unsigned h = 0; h < tempPoint->neighbour[j]->neighbours; h++) { if (tempPoint->neighbour[j]->neighbour[h]->ID != -1 && tempPoint->neighbour[j]->neighbour[h]->ID < least[j]) { least[j] = tempPoint->neighbour[j]->neighbour[h]->ID; } } } } int next = 0; for (unsigned j = 1; j < tempPoint->neighbours; j++) { if (least[j] < least[next]) next = j; } tempPoint = tempPoint->neighbour[next]; tempPoint->ID = i; } //Put the points into order then populate the hexagons and pentagons for (unsigned i = 0; i < vSize; i++) { int least = 0; int least2 = 0; std::vector<Point *> tempHolder; std::vector<Point *> tempHolder2; std::sort(points[i].neighbour.begin(), points[i].neighbour.end(), [](Point* a, Point* b) { return a->y < b->y; }); tempHolder.push_back(points[i].neighbour[0]); //start with the lowest ID'd neighbour. I might later change it to highest y value neighbour //then find the next neighbour that borders the first. There will be two, find both and use the one with the lowest ID for (unsigned h = 1; h < points[i].neighbours; h++) { if(std::find(points[i].neighbour[h]->neighbour.begin(), points[i].neighbour[h]->neighbour.end(), tempHolder[0]) != points[i].neighbour[h]->neighbour.end()) { tempHolder2.push_back(points[i].neighbour[h]); } } int xSign = 1; int zSign = 1; if (points[i].x < 0) xSign = -1; if (points[i].z < 0) zSign = -1; if (points[i].z * zSign < points[i].x * xSign) { if (tempHolder2[0]->z * xSign < tempHolder2[1]->z * xSign) tempHolder.push_back(tempHolder2[1]); else tempHolder.push_back(tempHolder2[0]); } else { if (tempHolder2[0]->x * zSign > tempHolder2[1]->x * zSign) tempHolder.push_back(tempHolder2[1]); else tempHolder.push_back(tempHolder2[0]); } //now find the rest of them for (unsigned j = 2; j < points[i].neighbours; j++) { for (unsigned h = 1; h < points[i].neighbours; h++) { if(std::find(tempHolder.begin(), tempHolder.end(), points[i].neighbour[h]) == tempHolder.end() && std::find(points[i].neighbour[h]->neighbour.begin(), points[i].neighbour[h]->neighbour.end(), tempHolder[j - 1]) != points[i].neighbour[h]->neighbour.end()) { tempHolder.push_back(points[i].neighbour[h]); h = points[i].neighbours; //break this loop } } } points[i].neighbour = tempHolder; faces.push_back(Face(points[i].neighbours, points[i].ID)); //then create the hexagon or pentagon Vector3f temp3f; faces[i].corners.push_back((points[i] + *points[i].neighbour[0] + *points[i].neighbour[points[i].neighbours - 1]) / 3); temp3f += (points[i] + *points[i].neighbour[0] + *points[i].neighbour[points[i].neighbours - 1]) / 3; for (unsigned j = 1; j < points[i].neighbours; j++) { faces[i].corners.push_back((points[i] + *points[i].neighbour[j] + *points[i].neighbour[j - 1]) / 3); temp3f += (points[i] + *points[i].neighbour[j] + *points[i].neighbour[j - 1]) / 3; } faces[i].center = temp3f / faces[i].n; } std::sort(faces.begin(), faces.end(), [](Face a, Face b) { return a.ID > b.ID; }); //now sort the faces by ID for testing purposes. This will ruin pointers but its okay for now as they are not currently needed //Now lets make the masks. First increase the dimensions so that they just barely overtake the faces masks = faces; for (unsigned int i = 0; i < vSize; i++) { masks[i].center *= 1.0001; for (unsigned int j = 0; j < faces[i].n; j++) { masks[i].corners[j] *= 1.0001; } } std::vector<Vertex> _VBO; radius = 2 / (faces[1].center - faces[0].center).length(); for (unsigned i = 0; i < faces.size(); i++) { if (faces[i].ID != -1) { int j; for (j = faces[i].ID; j > 100; j -= 100) {} if (faces[i].n == 6) { _VBO.push_back(Vertex(faces[i].corners[5] * radius, Vector2f(0.0f, 0.075f) + textureGrid[j], faces[i].center)); _VBO.push_back(Vertex(faces[i].corners[4] * radius, Vector2f(0.05f, 0.1f) + textureGrid[j], faces[i].center)); _VBO.push_back(Vertex(faces[i].corners[3] * radius, Vector2f(0.1f, 0.075f) + textureGrid[j], faces[i].center)); _VBO.push_back(Vertex(faces[i].corners[5] * radius, Vector2f(0.0f, 0.075f) + textureGrid[j], faces[i].center)); _VBO.push_back(Vertex(faces[i].corners[3] * radius, Vector2f(0.1f, 0.075f) + textureGrid[j], faces[i].center)); _VBO.push_back(Vertex(faces[i].corners[2] * radius, Vector2f(0.1f, 0.025f) + textureGrid[j], faces[i].center)); _VBO.push_back(Vertex(faces[i].corners[0] * radius, Vector2f(0.0f, 0.025f) + textureGrid[j], faces[i].center)); _VBO.push_back(Vertex(faces[i].corners[5] * radius, Vector2f(0.0f, 0.075f) + textureGrid[j], faces[i].center)); _VBO.push_back(Vertex(faces[i].corners[2] * radius, Vector2f(0.1f, 0.025f) + textureGrid[j], faces[i].center)); _VBO.push_back(Vertex(faces[i].corners[1] * radius, Vector2f(0.05f, 0.0f) + textureGrid[j], faces[i].center)); _VBO.push_back(Vertex(faces[i].corners[0] * radius, Vector2f(0.0f, 0.025f) + textureGrid[j], faces[i].center)); _VBO.push_back(Vertex(faces[i].corners[2] * radius, Vector2f(0.1f, 0.025f) + textureGrid[j], faces[i].center)); } if (faces[i].n == 5) { _VBO.push_back(Vertex(faces[i].corners[4] * radius, Vector2f(0.0f, 0.062f) + textureGrid[j], faces[i].center)); _VBO.push_back(Vertex(faces[i].corners[3] * radius, Vector2f(0.05f, 0.1f) + textureGrid[j], faces[i].center)); _VBO.push_back(Vertex(faces[i].corners[2] * radius, Vector2f(0.1f, 0.062f) + textureGrid[j], faces[i].center)); _VBO.push_back(Vertex(faces[i].corners[0] * radius, Vector2f(0.02f, 0.0f) + textureGrid[j], faces[i].center)); _VBO.push_back(Vertex(faces[i].corners[4] * radius, Vector2f(0.0f, 0.062f) + textureGrid[j], faces[i].center)); _VBO.push_back(Vertex(faces[i].corners[2] * radius, Vector2f(0.1f, 0.062f) + textureGrid[j], faces[i].center)); _VBO.push_back(Vertex(faces[i].corners[1] * radius, Vector2f(0.08f, 0.0f) + textureGrid[j], faces[i].center)); _VBO.push_back(Vertex(faces[i].corners[0] * radius, Vector2f(0.02f, 0.0f) + textureGrid[j], faces[i].center)); _VBO.push_back(Vertex(faces[i].corners[2] * radius, Vector2f(0.1f, 0.062f) + textureGrid[j], faces[i].center)); } } } glGenBuffers(1, &VBO); numV = _VBO.size(); roundNormals(&_VBO[0], numV); glBindBuffer(GL_ARRAY_BUFFER, VBO); glBufferData(GL_ARRAY_BUFFER, numV * sizeof(Vertex), &_VBO[0], GL_STATIC_DRAW); //end of test code //debug =============================================================================================================== newTime = SDL_GetTicks(); std::cout << (newTime - currentTime) << '\n'; currentTime = SDL_GetTicks(); }
void Text::ensureGeometryUpdate() const { // Do nothing, if geometry has not changed if (!m_geometryNeedUpdate) return; // Mark geometry as updated m_geometryNeedUpdate = false; // Clear the previous geometry m_vertices.clear(); m_bounds = FloatRect(); // No font: nothing to draw if (!m_font) return; // No text: nothing to draw if (m_string.isEmpty()) return; // Compute values related to the text style bool bold = (m_style & Bold) != 0; bool underlined = (m_style & Underlined) != 0; float italic = (m_style & Italic) ? 0.208f : 0.f; // 12 degrees float underlineOffset = m_characterSize * 0.1f; float underlineThickness = m_characterSize * (bold ? 0.1f : 0.07f); // Precompute the variables needed by the algorithm float hspace = static_cast<float>(m_font->getGlyph(L' ', m_characterSize, bold).advance); float vspace = static_cast<float>(m_font->getLineSpacing(m_characterSize)); float x = 0.f; float y = static_cast<float>(m_characterSize); // Create one quad for each character float minX = static_cast<float>(m_characterSize); float minY = static_cast<float>(m_characterSize); float maxX = 0.f; float maxY = 0.f; Uint32 prevChar = 0; for (std::size_t i = 0; i < m_string.getSize(); ++i) { Uint32 curChar = m_string[i]; // Apply the kerning offset x += static_cast<float>(m_font->getKerning(prevChar, curChar, m_characterSize)); prevChar = curChar; // If we're using the underlined style and there's a new line, draw a line if (underlined && (curChar == L'\n')) { float top = y + underlineOffset; float bottom = top + underlineThickness; m_vertices.append(Vertex(Vector2f(0, top), m_color, Vector2f(1, 1))); m_vertices.append(Vertex(Vector2f(x, top), m_color, Vector2f(1, 1))); m_vertices.append(Vertex(Vector2f(0, bottom), m_color, Vector2f(1, 1))); m_vertices.append(Vertex(Vector2f(0, bottom), m_color, Vector2f(1, 1))); m_vertices.append(Vertex(Vector2f(x, top), m_color, Vector2f(1, 1))); m_vertices.append(Vertex(Vector2f(x, bottom), m_color, Vector2f(1, 1))); } // Handle special characters if ((curChar == ' ') || (curChar == '\t') || (curChar == '\n')) { // Update the current bounds (min coordinates) minX = std::min(minX, x); minY = std::min(minY, y); switch (curChar) { case ' ' : x += hspace; break; case '\t' : x += hspace * 4; break; case '\n' : y += vspace; x = 0; break; } // Update the current bounds (max coordinates) maxX = std::max(maxX, x); maxY = std::max(maxY, y); // Next glyph, no need to create a quad for whitespace continue; } // Extract the current glyph's description const Glyph& glyph = m_font->getGlyph(curChar, m_characterSize, bold); int left = glyph.bounds.left; int top = glyph.bounds.top; int right = glyph.bounds.left + glyph.bounds.width; int bottom = glyph.bounds.top + glyph.bounds.height; float u1 = static_cast<float>(glyph.textureRect.left); float v1 = static_cast<float>(glyph.textureRect.top); float u2 = static_cast<float>(glyph.textureRect.left + glyph.textureRect.width); float v2 = static_cast<float>(glyph.textureRect.top + glyph.textureRect.height); // Add a quad for the current character m_vertices.append(Vertex(Vector2f(x + left - italic * top, y + top), m_color, Vector2f(u1, v1))); m_vertices.append(Vertex(Vector2f(x + right - italic * top, y + top), m_color, Vector2f(u2, v1))); m_vertices.append(Vertex(Vector2f(x + left - italic * bottom, y + bottom), m_color, Vector2f(u1, v2))); m_vertices.append(Vertex(Vector2f(x + left - italic * bottom, y + bottom), m_color, Vector2f(u1, v2))); m_vertices.append(Vertex(Vector2f(x + right - italic * top, y + top), m_color, Vector2f(u2, v1))); m_vertices.append(Vertex(Vector2f(x + right - italic * bottom, y + bottom), m_color, Vector2f(u2, v2))); // Update the current bounds minX = std::min(minX, x + left - italic * bottom); maxX = std::max(maxX, x + right - italic * top); minY = std::min(minY, y + top); maxY = std::max(maxY, y + bottom); // Advance to the next character x += glyph.advance; } // If we're using the underlined style, add the last line if (underlined) { float top = y + underlineOffset; float bottom = top + underlineThickness; m_vertices.append(Vertex(Vector2f(0, top), m_color, Vector2f(1, 1))); m_vertices.append(Vertex(Vector2f(x, top), m_color, Vector2f(1, 1))); m_vertices.append(Vertex(Vector2f(0, bottom), m_color, Vector2f(1, 1))); m_vertices.append(Vertex(Vector2f(0, bottom), m_color, Vector2f(1, 1))); m_vertices.append(Vertex(Vector2f(x, top), m_color, Vector2f(1, 1))); m_vertices.append(Vertex(Vector2f(x, bottom), m_color, Vector2f(1, 1))); } // Update the bounding rectangle m_bounds.left = minX; m_bounds.top = minY; m_bounds.width = maxX - minX; m_bounds.height = maxY - minY; }
unsigned int DispInfo::parse(std::istream& stream) { unsigned int numparsed = 0; std::string curline; while (trim(curline) != "{") { getline(stream, curline); numparsed++; } unsigned int depth = 1; std::map<std::string, std::map<std::string, std::string>> tempKeys; while (getline(stream, curline)) { numparsed++; if (trim(curline) == "}") { std::cout << "IS THIS REAL LIFE??\n"; if (--depth == 0) break; } else if (trim(curline) != "" && trim(curline)[0] != '\"') { auto cpos = stream.tellg(); std::string peekline; getline(stream, peekline); stream.seekg(cpos); if (trim(peekline) == "{") { std::string groupName = trim(curline); std::map<std::string, std::string> group; while (getline(stream, curline)) { numparsed++; if (trim(curline) == "}") { break; } else { KeyVal k(curline); group[k.key] = k.val; } } tempKeys[groupName] = move(group); } } else if (trim(curline) == "{") { ++depth; } else { KeyVal parsed(curline); keyvals[parsed.key] = parsed.val; } } int power = atoi(keyvals["power"].c_str()); int size = (int)pow(2, power) + 1; info = std::vector<std::vector<SingleDisp>>(size, std::vector<SingleDisp>(size, SingleDisp())); for (int row = 0; row < size; row++) { std::string rowID = "row"; rowID += std::to_string(row); auto norm = splitstr(tempKeys["normals"][rowID]); auto dist = splitstr(tempKeys["distances"][rowID]); auto off = splitstr(tempKeys["offsets"][rowID]); auto off_norm = splitstr(tempKeys["offset_normals"][rowID]); auto alpha = splitstr(tempKeys["alphas"][rowID]); for (int col = 0; col < size; col++) { auto& curInfo = info[row][col]; size_t vertInd = 3 * col; curInfo.normal = Vertex(norm[vertInd] + ' ' + norm[vertInd + 1] + ' ' + norm[vertInd + 2]); curInfo.distance = atof(dist[col].c_str()); curInfo.offset = Vertex(off[vertInd] + ' ' + off[vertInd + 1] + ' ' + off[vertInd + 2]); curInfo.offset_normal = Vertex(off_norm[vertInd] + ' ' + off_norm[vertInd + 1] + ' ' + off_norm[vertInd + 2]); curInfo.alpha = (char)atoi(alpha[col].c_str()); } } return numparsed; }
void Sphere::buildStacks(VertexList& vertices, IndexList& indices) { float phiStep = PI/mNumStacks; // do not count the poles as rings UINT numRings = mNumStacks-1; // Compute vertices for each stack ring. for(UINT i = 1; i <= numRings; ++i) { float phi = i*phiStep; // vertices of ring float thetaStep = 2.0f*PI/mNumSlices; for(UINT j = 0; j <= mNumSlices; ++j) { float theta = j*thetaStep; Vertex v; // spherical to cartesian v.pos.x = mRadius*sinf(phi)*cosf(theta); v.pos.y = mRadius*cosf(phi); v.pos.z = mRadius*sinf(phi)*sinf(theta); // partial derivative of P with respect to theta v.tangent.x = -mRadius*sinf(phi)*sinf(theta); v.tangent.y = 0.0f; v.tangent.z = mRadius*sinf(phi)*cosf(theta); D3DXVec3Normalize(&v.normal, &v.pos); v.texC.x = theta / (2.0f*PI); v.texC.y = phi / PI; vertices.push_back( v ); } } // poles: note that there will be texture coordinate distortion vertices.push_back( Vertex(0.0f, -mRadius, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 1.0f) ); vertices.push_back( Vertex(0.0f, mRadius, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f) ); UINT northPoleIndex = (UINT)vertices.size()-1; UINT southPoleIndex = (UINT)vertices.size()-2; UINT numRingVertices = mNumSlices+1; // Compute indices for inner stacks (not connected to poles). for(UINT i = 0; i < mNumStacks-2; ++i) { for(UINT j = 0; j < mNumSlices; ++j) { indices.push_back(i*numRingVertices + j); indices.push_back(i*numRingVertices + j+1); indices.push_back((i+1)*numRingVertices + j); indices.push_back((i+1)*numRingVertices + j); indices.push_back(i*numRingVertices + j+1); indices.push_back((i+1)*numRingVertices + j+1); } } // Compute indices for top stack. The top stack was written // first to the vertex buffer. for(UINT i = 0; i < mNumSlices; ++i) { indices.push_back(northPoleIndex); indices.push_back(i+1); indices.push_back(i); } // Compute indices for bottom stack. The bottom stack was written // last to the vertex buffer, so we need to offset to the index // of first vertex in the last ring. UINT baseIndex = (numRings-1)*numRingVertices; for(UINT i = 0; i < mNumSlices; ++i) { indices.push_back(southPoleIndex); indices.push_back(baseIndex+i); indices.push_back(baseIndex+i+1); } }
int main(int argc, char **argv) { gsl_rng_env_setup(); T = gsl_rng_default; r = gsl_rng_alloc (T); gsl_rng_set(r, time(NULL)); Graph *g = new Graph(); g->addVertex(Vertex(1, "v1", 0, 0, 0, 1.0, 1.0, 1.0)); g->addVertex(Vertex(2, "v2", 0, 0, 0, 1.0, 0.2, 0.2)); g->addVertex(Vertex(3, "v3", 0, 0, 0, 0.2, 1.0, 0.2)); g->addVertex(Vertex(4, "v4", 0, 0, 0, 0.2, 0.2, 1.0)); g->addEdge(1, 2); g->addEdge(1, 3); g->addEdge(3, 4); ptr population(new std::vector<Graph>(4, *g)); /* std::cout << "Population" << std::endl; printgraph(population); ptr reproduced = reproduce(population); std::cout << "Reproduced" << std::endl; printgraph(reproduced); ptr offsprings = genetic(reproduced); std::cout << "Offsprings" << std::endl; printgraph(offsprings); population = succession(population, offsprings); std::cout << "After one iteration" << std::endl; printgraph(population); */ int iterationcount = 0; double bestv = best(population); double bestvold = bestv * 2; std::cout << "best " << bestv << "; bestvold " << bestvold << std::endl; while (fabs(bestvold - bestv)/bestvold > 0.00000001) { ++iterationcount; ptr offsprings = genetic(reproduce(population)); population = succession(population, offsprings); bestvold = bestv; bestv = best(population); } std::cout << "Possible result found after " << iterationcount << "iterations: " << std::endl; printgraph(population); const Graph *bestgraph = bestg(population); for (Graph::vertices_const_iterator i = bestgraph->vertices.begin(); i != bestgraph->vertices.end(); ++i) { const Vertex &v = i->second; std::cout << "\"" << v.name << "\""; std::cout << "\[email protected]" << v.x << " " << v.y << " " << v.z; std::cout << "\tcolor" << v.r << " " << v.g << " " << v.b; std::cout << "\tfrozen light size 1.0" << std::endl; } gsl_rng_free (r); return 0; }
void MxyVBOTree::buildTrunk(){ vec3f segmentBottomCenterPos; Vertex (*_vertices); GLuint *_indices; float radius = _radius; float h = _height / float(_numSegments); vec3f segmentTopCenterPos = segmentBottomCenterPos + vec3f( 0.0f, h, 0.0f); GLuint baseIndex =0; _vertices = new Vertex[_branchSides * 2]; /*std::cout<<"set"<<_branchSides * 2<<std::endl;*/ for ( int i = 0; i < _branchSides; i++){ float x = sinf( float(i)/float(_branchSides) * 2.0f * 3.1415927f); float z = cosf( float(i)/float(_branchSides) * 2.0f * 3.1415927f); vec3f currentSideDir( x, 0.0f, z); vec3f highvertex = segmentTopCenterPos + currentSideDir * (radius - _radius/float(_numSegments - 2)) * 0.05f; vec3f lowvertex = segmentBottomCenterPos + currentSideDir * radius * 0.05f; testar.push_back(highvertex); testar.push_back(lowvertex); //low _vertices[i].position[X_POS] = lowvertex.x; _vertices[i].position[Y_POS] = lowvertex.y; _vertices[i].position[Z_POS] = lowvertex.z; _vertices[i].normal[X_POS] = currentSideDir.x; _vertices[i].normal[Y_POS] = currentSideDir.y; _vertices[i].normal[Z_POS] = currentSideDir.z; _vertices[i].colour[R_POS] = 0.5; _vertices[i].colour[G_POS] = 0.0; _vertices[i].colour[B_POS] = 0.5; _vertices[i].colour[A_POS] = 1.0; _vertices[i].texture[U_POS] = 0.0; _vertices[i].texture[V_POS] = 0.0; //high _vertices[i+1].position[X_POS] = highvertex.x; _vertices[i+1].position[Y_POS] = highvertex.y; _vertices[i+1].position[Z_POS] = highvertex.z; _vertices[i+1].normal[X_POS] = currentSideDir.x; _vertices[i+1].normal[Y_POS] = currentSideDir.y; _vertices[i+1].normal[Z_POS] = currentSideDir.z; _vertices[i+1].colour[R_POS] = 0.5; _vertices[i+1].colour[G_POS] = 0.0; _vertices[i+1].colour[B_POS] = 0.5; _vertices[i+1].colour[A_POS] = 1.0; _vertices[i+1].texture[U_POS] = 0.0; _vertices[i+1].texture[V_POS] = 0.0; } /*std::cout<<testar.size()<<std::endl;*/ _indices = new GLuint[_branchSides * 6]; /*vector<GLuint> _trunkIndices;*/ //generate index for (int jj = 0; jj < _branchSides; jj++) { _indices[jj] = ( baseIndex + jj * 2); _indices[jj+1] = ( baseIndex + jj * 2 + 1); _indices[jj+2] = ( baseIndex + (jj * 2 + 2) % (_branchSides * 2)); _indices[jj+3] = ( baseIndex + (jj * 2 + 2) % (_branchSides * 2)); _indices[jj+4] = ( baseIndex + jj * 2 + 1); _indices[jj+5] = ( baseIndex + (jj * 2 + 3) % (_branchSides * 2)); } _numberOfVertices = _branchSides * 2; _numberOfIndices = _branchSides * 6; glGenBuffers(1, &_vboids); glBindBuffer(GL_ARRAY_BUFFER_ARB, _vboids); glBufferData(GL_ARRAY_BUFFER_ARB, sizeof(Vertex)*_numberOfVertices, 0, GL_STATIC_DRAW_ARB); glBufferSubData(GL_ARRAY_BUFFER_ARB, 0, sizeof(Vertex)*_numberOfVertices, _vertices); glGenBuffers(1, &_indexVboId); // Generate buffer glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _indexVboId); glBufferData(GL_ELEMENT_ARRAY_BUFFER, _numberOfIndices * sizeof(GLuint), _indices, GL_STATIC_DRAW); glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, sizeof(GLuint)*_numberOfIndices, _indices); glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); }
void GeometryGenerator::CreateBox(float width, float height, float depth, MeshData& meshData) { // // Create the vertices. // Vertex v[24]; float w2 = 0.5f*width; float h2 = 0.5f*height; float d2 = 0.5f*depth; // Fill in the front face vertex data. v[0] = Vertex(-w2, -h2, -d2, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f); v[1] = Vertex(-w2, +h2, -d2, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f); v[2] = Vertex(+w2, +h2, -d2, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f); v[3] = Vertex(+w2, -h2, -d2, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f); // Fill in the back face vertex data. v[4] = Vertex(-w2, -h2, +d2, 0.0f, 0.0f, 1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 1.0f); v[5] = Vertex(+w2, -h2, +d2, 0.0f, 0.0f, 1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f); v[6] = Vertex(+w2, +h2, +d2, 0.0f, 0.0f, 1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f); v[7] = Vertex(-w2, +h2, +d2, 0.0f, 0.0f, 1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f); // Fill in the top face vertex data. v[8] = Vertex(-w2, +h2, -d2, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f); v[9] = Vertex(-w2, +h2, +d2, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f); v[10] = Vertex(+w2, +h2, +d2, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f); v[11] = Vertex(+w2, +h2, -d2, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f); // Fill in the bottom face vertex data. v[12] = Vertex(-w2, -h2, -d2, 0.0f, -1.0f, 0.0f, -1.0f, 0.0f, 0.0f, 1.0f, 1.0f); v[13] = Vertex(+w2, -h2, -d2, 0.0f, -1.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f); v[14] = Vertex(+w2, -h2, +d2, 0.0f, -1.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f); v[15] = Vertex(-w2, -h2, +d2, 0.0f, -1.0f, 0.0f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f); // Fill in the left face vertex data. v[16] = Vertex(-w2, -h2, +d2, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f); v[17] = Vertex(-w2, +h2, +d2, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f); v[18] = Vertex(-w2, +h2, -d2, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f); v[19] = Vertex(-w2, -h2, -d2, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f); // Fill in the right face vertex data. v[20] = Vertex(+w2, -h2, -d2, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f); v[21] = Vertex(+w2, +h2, -d2, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f); v[22] = Vertex(+w2, +h2, +d2, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f); v[23] = Vertex(+w2, -h2, +d2, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f); meshData.Vertices.assign(&v[0], &v[24]); // // Create the indices. // UINT i[36]; // Fill in the front face index data i[0] = 0; i[1] = 1; i[2] = 2; i[3] = 0; i[4] = 2; i[5] = 3; // Fill in the back face index data i[6] = 4; i[7] = 5; i[8] = 6; i[9] = 4; i[10] = 6; i[11] = 7; // Fill in the top face index data i[12] = 8; i[13] = 9; i[14] = 10; i[15] = 8; i[16] = 10; i[17] = 11; // Fill in the bottom face index data i[18] = 12; i[19] = 13; i[20] = 14; i[21] = 12; i[22] = 14; i[23] = 15; // Fill in the left face index data i[24] = 16; i[25] = 17; i[26] = 18; i[27] = 16; i[28] = 18; i[29] = 19; // Fill in the right face index data i[30] = 20; i[31] = 21; i[32] = 22; i[33] = 20; i[34] = 22; i[35] = 23; meshData.Indices.assign(&i[0], &i[36]); }
Mesh* Mesh::loadObject(std::string filename){ std::vector<Vertex> vertices; std::vector<unsigned int> indices; std::ifstream file(filename.c_str(), std::ios::in | std::ios::binary); if(!file.good()){ std::cout<<"Mesh Loader: Nu am gasit fisierul obj "<<filename<<" sau nu am drepturile sa il deschid!"<<std::endl; std::terminate(); } std::string line; std::vector<std::string> tokens, facetokens; std::vector<glm::vec3> positions; positions.reserve(1000); std::vector<glm::vec3> normals; normals.reserve(1000); std::vector<glm::vec2> texcoords; texcoords.reserve(1000); while(std::getline(file,line)){ //tokenizeaza linie citita _stringTokenize(line,tokens); //daca nu am nimic merg mai departe if(tokens.size()==0) continue; //daca am un comentariu merg mai departe if(tokens.size()>0 && tokens[0].at(0)=='#') continue; //daca am un vertex if(tokens.size()>3 && tokens[0]=="v") positions.push_back(glm::vec3(_stringToFloat(tokens[1]), _stringToFloat(tokens[2]), _stringToFloat(tokens[3]) )); //daca am o normala if(tokens.size()>3 && tokens[0]=="vn") normals.push_back(glm::vec3(_stringToFloat(tokens[1]), _stringToFloat(tokens[2]), _stringToFloat(tokens[3]) )); //daca am un texcoord if(tokens.size()>2 && tokens[0]=="vt") texcoords.push_back(glm::vec2(_stringToFloat(tokens[1]), _stringToFloat(tokens[2]) )); //daca am o fata (f+ minim 3 indecsi) if(tokens.size()>=4 && tokens[0]=="f"){ //foloseste primul vertex al fetei pentru a determina formatul fetei (v v/t v//n v/t/n) = (1 2 3 4) unsigned int face_format = 0; if(tokens[1].find("//")!=std::string::npos) face_format = 3; _faceTokenize(tokens[1],facetokens); if(facetokens.size()==3) face_format =4; // vertecsi/texcoords/normale else{ if(facetokens.size()==2){ if(face_format !=3) face_format=2; //daca nu am vertecsi/normale am vertecsi/texcoords }else{ face_format =1; //doar vertecsi } } //primul index din acest poligon unsigned int index_of_first_vertex_of_face = -1; for(unsigned int num_token =1; num_token<tokens.size();num_token++){ if(tokens[num_token].at(0)=='#') break; //comment dupa fata _faceTokenize(tokens[num_token],facetokens); if(face_format==1){ //doar pozitie int p_index = _stringToInt(facetokens[0]); if(p_index>0) p_index -=1; //obj has 1...n indices else p_index = positions.size()+p_index; //index negativ vertices.push_back(Vertex(glm::vec3(positions[p_index].x, positions[p_index].y, positions[p_index].z))); }else if(face_format==2){ // pozitie si texcoord int p_index = _stringToInt(facetokens[0]); if(p_index>0) p_index -=1; //obj has 1...n indices else p_index = positions.size()+p_index; //index negativ int t_index = _stringToInt(facetokens[1]); if(t_index>0) t_index -=1; //obj has 1...n indices else t_index = texcoords.size()+t_index; //index negativ vertices.push_back(Vertex(glm::vec3(positions[p_index].x, positions[p_index].y, positions[p_index].z),glm::vec2(texcoords[t_index].x, texcoords[t_index].y))); }else if(face_format==3){ //pozitie si normala int p_index = _stringToInt(facetokens[0]); if(p_index>0) p_index -=1; //obj has 1...n indices else p_index = positions.size()+p_index; //index negativ int n_index = _stringToInt(facetokens[1]); if(n_index>0) n_index -=1; //obj has 1...n indices else n_index = normals.size()+n_index; //index negativ vertices.push_back(Vertex(glm::vec3(positions[p_index].x, positions[p_index].y, positions[p_index].z), glm::vec3(normals[n_index].x, normals[n_index].y, normals[n_index].z))); }else{ //pozitie normala si texcoord int p_index = _stringToInt(facetokens[0]); if(p_index>0) p_index -=1; //obj has 1...n indices else p_index = positions.size()+p_index; //index negativ int t_index = _stringToInt(facetokens[1]); if(t_index>0) t_index -=1; //obj has 1...n indices else t_index = normals.size()+t_index; //index negativ int n_index = _stringToInt(facetokens[2]); if(n_index>0) n_index -=1; //obj has 1...n indices else n_index = normals.size()+n_index; //index negativ vertices.push_back(Vertex(glm::vec3(positions[p_index].x, positions[p_index].y, positions[p_index].z),glm::vec3(normals[n_index].x, normals[n_index].y, normals[n_index].z), glm::vec2(texcoords[t_index].x, texcoords[t_index].y))); } //adauga si indecsii if(num_token<4){ if(num_token == 1) index_of_first_vertex_of_face = vertices.size()-1; //doar triunghiuri f 0 1 2 3 (4 indecsi, primul e ocupat de f) indices.push_back(vertices.size()-1); }else{ //polygon => triunghi cu ultimul predecesor vertexului nou adaugat si 0 relativ la vertecsi poligon(independent clockwise) indices.push_back(index_of_first_vertex_of_face); indices.push_back(vertices.size()-2); indices.push_back(vertices.size()-1); } }//end for }//end face }//end while return new Mesh(vertices, indices); }
Model ModelsFactory::camera(long double width, long double length, long double height, long double radius, long double lensWidth, long double lensMountLength, long double lensMountWidth, long double marginWidth, long double sideButtonsHeight, long double shutterButtonHeight, long double sideButtonsRadius, long double shutterButtonRadius) { if (width <= 0.0L || 3.0L * width >= length || 1.5L * width >= height) { throw std::out_of_range("Ширина должна быть больше 0.0, меньше 1/3 длины и меньше 2/3 высоты!"); } if (length <= 0.0L) { throw std::out_of_range("Длина должна быть больше 0.0!"); } if (height <= 0.0L || height >= length) { throw std::out_of_range("Высота должна быть больше 0.0 и меньше длины!"); } if (radius <= 0.0L || radius > lensMountLength) { throw std::out_of_range("Радиус объектива должен быть больше 0.0 и меньше либо равен длине крепления объектива!"); } if (lensWidth <= 0.0L) { throw std::out_of_range("Ширина объектива должна быть больше 0.0!"); } if (lensMountLength <= 0.25L * length || lensMountLength >= 0.5L * length) { throw std::out_of_range("Длина крепления объектива должна быть больше 1/4 и меньше 1/2 длины фотоаппарата!"); } if (lensMountWidth <= 0.0L || lensMountWidth >= width) { throw std::out_of_range("Ширина крепления объектива должна быть больше 0.0 и меньше ширины фотоаппарата!"); } if (marginWidth <= 0.0L || 2.0L * marginWidth + lensMountLength >= length) { throw std::out_of_range("Длина свободной части должна быть больше 0.0 и соответствовать длине крепления объектива!"); } if (sideButtonsHeight <= 0.0L) { throw std::out_of_range("Высота боковых кнопок должна быть больше 0.0!"); } if (shutterButtonHeight <= 0.0L) { throw std::out_of_range("Высота кнопки спуска затвора должна быть больше 0.0!"); } if (sideButtonsRadius <= 0.0L || sideButtonsRadius >= width) { throw std::out_of_range("Радиус боковых кнопок должен быть больше 0.0 и меньше ширины фотоаппарата!"); } if (shutterButtonRadius <= 0.0L || 3.0L * shutterButtonRadius >= width) { throw std::out_of_range("Радиус кнопки спуска затвора должен быть больше 0.0 и меньше 1/3 ширины фотоаппарата!"); } Mesh *mesh = new Mesh(); Model result = Model("Camera", mesh, RGBA(255, 0, 255, 255)); result.setParameters(width, length, height, radius, lensWidth, lensMountLength, lensMountWidth, marginWidth, sideButtonsHeight, shutterButtonHeight, sideButtonsRadius, shutterButtonRadius); Model base = ModelsFactory::box(width, length, height); Mesh *currentMesh = base.mesh(); int numVertices = currentMesh->numVertices(); int numFaces = currentMesh->numFaces(); int verticesOffset = 0; for (int i = 0; i < numVertices; i++) { mesh->addVertex(currentMesh->getVertex(i)); } for (int i = 0; i < numFaces; i++) { Face face = currentMesh->getFace(i); face.v1 += verticesOffset; face.v2 += verticesOffset; face.v3 += verticesOffset; mesh->addFace(face); } verticesOffset += numVertices; Model lensMount = ModelsFactory::lensMount(lensMountWidth, lensMountLength, length - marginWidth * 2.0L, height); currentMesh = lensMount.mesh(); numVertices = currentMesh->numVertices(); numFaces = currentMesh->numFaces(); for (int i = 0; i < numVertices; i++) { Vertex vertex = currentMesh->getVertex(i); mesh->addVertex(Vertex(vertex.x(), vertex.y(), vertex.z() - (width / 2.0L + lensMountWidth / 2.0L))); } for (int i = 0; i < numFaces; i++) { Face face = currentMesh->getFace(i); face.v1 += verticesOffset; face.v2 += verticesOffset; face.v3 += verticesOffset; mesh->addFace(face); } verticesOffset += numVertices; Model lens = ModelsFactory::cylinder(radius, lensWidth, 12); currentMesh = lens.mesh(); numVertices = currentMesh->numVertices(); numFaces = currentMesh->numFaces(); for (int i = 0; i < numVertices; i++) { Vertex vertex = currentMesh->getVertex(i); Matrix rotationMatrix = Matrix::rotationX(degreeToRadian(90.0L)); Vec4f newPosition = Vec4f(vertex.position()) * rotationMatrix; Vec3f newPositionV3 = Vec3f(newPosition); mesh->addVertex(Vertex(newPositionV3.x, newPositionV3.y, newPositionV3.z - (width / 2.0L + lensMountWidth + lensWidth / 2.0L))); } for (int i = 0; i < numFaces; i++) { Face face = currentMesh->getFace(i); face.v1 += verticesOffset; face.v2 += verticesOffset; face.v3 += verticesOffset; mesh->addFace(face); } verticesOffset += numVertices; Model rightSideButton = ModelsFactory::cylinder(sideButtonsRadius, sideButtonsHeight, 12); currentMesh = rightSideButton.mesh(); numVertices = currentMesh->numVertices(); numFaces = currentMesh->numFaces(); for (int i = 0; i < numVertices; i++) { Vertex vertex = currentMesh->getVertex(i); mesh->addVertex(Vertex(vertex.x() - length / 2.0L + marginWidth / 2.0L, vertex.y() + height / 2.0L + sideButtonsHeight / 2.0L, vertex.z())); } for (int i = 0; i < numFaces; i++) { Face face = currentMesh->getFace(i); face.v1 += verticesOffset; face.v2 += verticesOffset; face.v3 += verticesOffset; mesh->addFace(face); } verticesOffset += numVertices; Model leftSideButton = ModelsFactory::cylinder(sideButtonsRadius, sideButtonsHeight, 12); currentMesh = leftSideButton.mesh(); numVertices = currentMesh->numVertices(); numFaces = currentMesh->numFaces(); for (int i = 0; i < numVertices; i++) { Vertex vertex = currentMesh->getVertex(i); mesh->addVertex(Vertex(vertex.x() + length / 2.0L - marginWidth / 2.0L, vertex.y() + height / 2.0L + sideButtonsHeight / 2.0L, vertex.z())); } for (int i = 0; i < numFaces; i++) { Face face = currentMesh->getFace(i); face.v1 += verticesOffset; face.v2 += verticesOffset; face.v3 += verticesOffset; mesh->addFace(face); } verticesOffset += numVertices; Model centerButton = ModelsFactory::cylinder(sideButtonsRadius, sideButtonsHeight / 2.0L, 12); currentMesh = centerButton.mesh(); numVertices = currentMesh->numVertices(); numFaces = currentMesh->numFaces(); for (int i = 0; i < numVertices; i++) { Vertex vertex = currentMesh->getVertex(i); mesh->addVertex(Vertex(vertex.x(), vertex.y() + height / 2.0L + sideButtonsHeight / 4.0L, vertex.z())); } for (int i = 0; i < numFaces; i++) { Face face = currentMesh->getFace(i); face.v1 += verticesOffset; face.v2 += verticesOffset; face.v3 += verticesOffset; mesh->addFace(face); } verticesOffset += numVertices; Model shutterButton = ModelsFactory::cylinder(shutterButtonRadius, shutterButtonHeight, 12); currentMesh = shutterButton.mesh(); numVertices = currentMesh->numVertices(); numFaces = currentMesh->numFaces(); for (int i = 0; i < numVertices; i++) { Vertex vertex = currentMesh->getVertex(i); mesh->addVertex(Vertex(vertex.x() - length / 4.0L + marginWidth / 4.0L, vertex.y() + height / 2.0L + shutterButtonHeight / 2.0L, vertex.z() + width / 4.0L)); } for (int i = 0; i < numFaces; i++) { Face face = currentMesh->getFace(i); face.v1 += verticesOffset; face.v2 += verticesOffset; face.v3 += verticesOffset; mesh->addFace(face); } verticesOffset += numVertices; return result; }
// // Framework Functions // bool Setup() { // // Create the vertex buffer. // Device->CreateVertexBuffer( 3 * sizeof(Vertex), // size in bytes D3DUSAGE_WRITEONLY, // flags Vertex::FVF, // vertex format D3DPOOL_MANAGED, // managed memory pool &Triangle, // return create vertex buffer 0); // not used - set to 0 // // Fill the buffers with the triangle data. // Vertex* vertices; Triangle->Lock(0, 0, (void**)&vertices, 0); /* 这三个顶点的定义顺序是顺时针!!: 1 / \ / \ 0 -------- 2 */ vertices[0] = Vertex(-1.0f, 0.0f, 2.0f); // 顺时针定义各个顶点,因为这里默认世界坐标系和观察坐标系一致 vertices[1] = Vertex( 0.0f, 3.0f, 2.0f); // 如果不是顺时针即逆时针,表示背面,默认是不会显示的,除非改变背面裁剪计算方式 vertices[2] = Vertex( 1.0f, 0.0f, 2.0f); Triangle->Unlock(); /* 渲染管线~=渲染流水线~=绘图步骤 // 1.没有设置本地坐标到世界坐标的转换,是因为想直接使用本地坐标系的坐标在世界坐标系用(当做两个坐标系重合) 换而言之,就是默认的本地坐标转成世界坐标的矩阵是单位矩阵I(因为任意向量乘以I都不会改变) Device->GetTransform(D3DTS_WORLD,&V); // 2.这里没有设置摄像机,那么视图矩阵默认是? D3DXMATRIX V; Device->GetTransform(D3DTS_VIEW,&V); 结果获得一个4阶单位矩阵,即视点眼睛在原点,视线是往Z轴正方向即屏幕里面. 其实就是拿世界坐标系中的坐标直接而不转换的,在观察坐标系中绘制使用(当做两个坐标系重合) //3.没有设置背面裁剪,使用 DWORD dwValue; Device->GetRasterStatus(D3DRS_CULLMODE,&dwValue); 结果获得3==D3DCULL_CCW,即按逆时针方向进行剔除(以观察坐标系[view sapce]为参考) 也就是默认剔除逆时针方向的三角形 //4.光照暂时没看到 //5.裁剪书上没有介绍 //6.投影转换,这边步骤必不可少! */ // // Set the projection matrix. // D3DXMATRIX proj; D3DXMatrixPerspectiveFovLH( &proj, // result D3DX_PI * 0.5f, // 90 - degrees (float)Width / (float)Height, // aspect ratio 1.0f, // near plane 1000.0f); // far plane Device->SetTransform(D3DTS_PROJECTION, &proj); /* 7.视口变换 D3DVIEWPORT9 vp; Device->GetViewport(&vp); 得到默认的vp={0,0,640,480,0,1},默认是渲染窗口大小 8.光栅化(硬件完成,但是我们设置一些状态去影响他) */ // // Set wireframe mode render state. 默认填充方式是D3DFILL_SOLID实心 // Device->SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME);// 默认填充方式是D3DFILL_SOLID实心 return true; }
void GeometricHelperTest::LineSegmentIntersectionTest() { { LineSegment ls1(Vertex(0, 1), Vertex(1, 1)); LineSegment ls2(Vertex(0, 0), Vertex(1, 2)); // segments intersect boost::optional<Vertex> intersection_point_opt = GeometricHelper::intersect(ls1, ls2); CPPUNIT_ASSERT_MESSAGE("Intersection point expected", bool(intersection_point_opt)); Vertex intersection_point = *intersection_point_opt; CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Intersection point error", 0.5, intersection_point.x(), 1E-10); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Intersection point error", 1.0, intersection_point.y(), 1E-10); } { LineSegment ls1(Vertex(0, 1), Vertex(1, 1)); LineSegment ls2(Vertex(0, 0), Vertex(2, 1)); // segments do not intersect boost::optional<Vertex> intersection_point_opt = GeometricHelper::intersect(ls1, ls2); CPPUNIT_ASSERT_MESSAGE("No intersection point expected", !bool(intersection_point_opt)); } { LineSegment ls1(Vertex(0, 1), Vertex(1, 1)); LineSegment ls2(Vertex(0.5, 1), Vertex(2, 1)); // segments overlap boost::optional<Vertex> intersection_point_opt = GeometricHelper::intersect(ls1, ls2); CPPUNIT_ASSERT_MESSAGE("No intersection point expected", !bool(intersection_point_opt)); } { LineSegment ls1(Vertex(0.5, 1), Vertex(1, 1)); LineSegment ls2(Vertex(0, 1), Vertex(2, 1)); // segment 1 contained in segment 2 boost::optional<Vertex> intersection_point_opt = GeometricHelper::intersect(ls1, ls2); CPPUNIT_ASSERT_MESSAGE("No intersection point expected", !bool(intersection_point_opt)); } { LineSegment ls1(Vertex(0, 1), Vertex(1, 1)); LineSegment ls2(Vertex(1.5, 1), Vertex(2, 1)); // segments parallel boost::optional<Vertex> intersection_point_opt = GeometricHelper::intersect(ls1, ls2); CPPUNIT_ASSERT_MESSAGE("No intersection point expected", !bool(intersection_point_opt)); } }
void RoadGraph::_generateMeshVerticesDefault2(VBORenderManager& rendManager, const QString &linesN, const QString &pointsN) { const int renderRoadType=1; float deltaZ=10;//G::global().getFloat("3d_road_deltaZ");//avoid road intersect with terrain { float const maxSegmentLeng=5.0f;//5.0f RoadEdgeIter ei, eiEnd; QVector3D p0,p1; std::vector<Vertex> vertROAD[2]; std::vector<Vertex> intersectCirclesV; QVector3D a0,a1,a2,a3; QVector3D per,dir,lastDir; float length; for (boost::tie(ei, eiEnd) = boost::edges(graph); ei != eiEnd; ++ei) { if (!graph[*ei]->valid) continue; RoadEdgePtr edge = graph[*ei]; float hWidth=1.1f*graph[*ei]->getWidth()/2.0f;//magic 1.1f !!!! (make roads go below buildings int type; switch (graph[*ei]->type) { case RoadEdge::TYPE_HIGHWAY: type=1;//should have its texture!!! TODO break; case RoadEdge::TYPE_BOULEVARD: case RoadEdge::TYPE_AVENUE: type=1; break; case RoadEdge::TYPE_STREET: type=0; break; default: type=0; break; } //float lengthMoved=0;//road texture dX float lengthMovedL=0;//road texture dX float lengthMovedR=0;//road texture dX for(int pL=0;pL<edge->polyline3D.size()-1;pL++){//note -1 bool bigAngle=false; p0 = edge->polyline3D[pL]; p1 = edge->polyline3D[pL+1]; p0.setZ(deltaZ); p1.setZ(deltaZ); lastDir=dir;//save to compare dir=(p1-p0);//.normalized(); length=dir.length(); dir/=length; //per=(QVector3D::crossProduct(dir,QVector3D(0,0,1.0f)).normalized());//need normalized()? per = QVector3D(-dir.y(), dir.x(), 0.0f).normalized(); if (pL == 0) { a0 = p0 - per * hWidth; a3 = p0 + per * hWidth; } a1 = p1 - per * hWidth; a2 = p1 + per * hWidth; if (pL < edge->polyline3D.size() - 2) { QVector3D p2 = edge->polyline3D[pL + 2]; p2.setZ(deltaZ); Util::getIrregularBisector(p0, p1, p2, hWidth, hWidth, a2); Util::getIrregularBisector(p0, p1, p2, -hWidth, -hWidth, a1); a1.setZ(deltaZ); a2.setZ(deltaZ); } float middLenghtR=length; float middLenghtL=length; float segmentLengR, segmentLengL; int numSegments=ceil(length/5.0f); float dW=7.5f;//tex size in m QVector3D b0, b3; QVector3D b1 = a0; QVector3D b2 = a3; QVector3D vecR = a1 - a0; QVector3D vecL = a2 - a3; for(int nS=0;nS<numSegments;nS++){ segmentLengR=std::min(maxSegmentLeng,middLenghtR); segmentLengL=std::min(maxSegmentLeng,middLenghtL); b0 = b1; b3 = b2; if (nS < numSegments - 1) { b1 += dir * segmentLengR; b2 += dir * segmentLengL; } else { b1 = a1; b2 = a2; } //printf("a %f %f b %f %f %f %f\n",a2.z(),a1.z(),b0.z(),b1.z(),b2.z(),b3.z()); vertROAD[type].push_back(Vertex(b0,QVector3D(),QVector3D(0,0,1.0f),QVector3D(1,lengthMovedR / dW,0))); vertROAD[type].push_back(Vertex(b1,QVector3D(),QVector3D(0,0,1.0f),QVector3D(1,(lengthMovedR + segmentLengR) / dW,0))); vertROAD[type].push_back(Vertex(b2,QVector3D(),QVector3D(0,0,1.0f),QVector3D(0,(lengthMovedL + segmentLengL) / dW,0))); vertROAD[type].push_back(Vertex(b3,QVector3D(),QVector3D(0,0,1.0f),QVector3D(0,lengthMovedL / dW,0))); lengthMovedR+=segmentLengR; lengthMovedL+=segmentLengL; middLenghtR-=segmentLengR; middLenghtL-=segmentLengL; } a3 = a2; a0 = a1; } } // add all geometry rendManager.addStaticGeometry("3d_roads",vertROAD[0],"../data/textures/roads/road_2lines.jpg",GL_QUADS,2|mode_AdaptTerrain); rendManager.addStaticGeometry("3d_roads",vertROAD[1],"../data/textures/roads/road_4lines.jpg",GL_QUADS,2|mode_AdaptTerrain); } return; { // 2. INTERSECTIONS std::vector<Vertex> intersectCirclesV; RoadVertexIter vi, vend; for (boost::tie(vi, vend) = boost::vertices(graph); vi != vend; ++vi) { if (!graph[*vi]->valid) continue; int outDegree=0;//boost::out_degree(*vi,roadGraph.graph); RoadOutEdgeIter oei, oeend; for (boost::tie(oei, oeend) = boost::out_edges(*vi, graph); oei != oeend; ++oei) { if (!graph[*oei]->valid) continue; outDegree++; } //////////////////////// // 2.1 JUST TWO OR LESS--> CIRCLE BELOW if(outDegree<=3){//if(outDegree<=2){ // get the largest width of the outing edges float max_r = 0; int max_roadType = 0; float offset = 0.3f; RoadOutEdgeIter oei, oeend; for (boost::tie(oei, oeend) = boost::out_edges(*vi, graph); oei != oeend; ++oei) { if (!graph[*oei]->valid) continue; float r = graph[*oei]->getWidth(); if (r > max_r) { max_r = r; } if (graph[*oei]->type > max_roadType) { max_roadType = graph[*oei]->type; } } QVector3D center=graph[*vi]->pt3D; if(outDegree<=2) center.setZ(deltaZ-0.1f);//below else center.setZ(deltaZ+0.1f);//above float radi1 = max_r /2.0f; if(outDegree==2)radi1*=1.10f; const float numSides=20; const float deltaAngle=( 1.0f / numSides ) * 3.14159f * 2.0f; float angle=0.0f; QVector3D nP,oP; oP=QVector3D( radi1 * cos( angle ), radi1 * sin( angle ),0.0f );//init point for(int i=0;i<numSides+1;i++){ angle=deltaAngle*i; nP=QVector3D( radi1 * cos( angle ), radi1 * sin( angle ),0.0f ); intersectCirclesV.push_back(Vertex(center,center/7.5f)); intersectCirclesV.push_back(Vertex(center+oP,(center+oP)/7.5f)); intersectCirclesV.push_back(Vertex(center+nP,(center+nP)/7.5f)); oP=nP; } }else{ //////////////////////// // 2.2 FOUR OR MORE--> COMPLEX INTERSECTION //printf("a\n"); //////////// // 2.2.1 For each vertex find edges and short by angle QVector2D referenceVector(0,1); QVector2D p0,p1; std::vector<std::pair<std::pair<QVector3D,QVector2D>,float>> edgeAngleOut; int numOutEdges=0; RoadOutEdgeIter Oei, Oei_end; float angleRef=atan2(referenceVector.y(),referenceVector.x()); //printf("a1\n"); for(boost::tie(Oei, Oei_end) = boost::out_edges(*vi,graph); Oei != Oei_end; ++Oei){ if (!graph[*Oei]->valid) continue; // find first segment RoadEdgePtr edge = graph[*Oei]; //printf("a11 poly %d\n",edge->polyline.size()); Polyline2D polyline = GraphUtil::orderPolyLine(*this, *Oei, *vi); p0 = polyline[0]; p1 = polyline[1]; QVector2D edgeDir=(p1-p0).normalized();// NOTE p1-p0 p1=p0+edgeDir*30.0f;//expand edge to make sure it is long enough float angle=angleRef-atan2(edgeDir.y(),edgeDir.x()); float width=edge->getWidth()*1.1f;//1.1 (since in render this is also applied) edgeAngleOut.push_back(std::make_pair(std::make_pair(QVector3D(p0.x(),p0.y(),width),p1),angle));//z as width numOutEdges++; } //printf("a2\n"); if(edgeAngleOut.size()>0){ std::sort( edgeAngleOut.begin(), edgeAngleOut.end(), compare2ndPartTuple2); } //printf("b\n"); // 2.2.2 Create intersection geometry of the given edges QVector3D ed1p0,ed1p1; QVector3D ed1p0L,ed1p1L,ed1p0R,ed1p1R; QVector3D ed2p0L,ed2p1L,ed2p0R,ed2p1R;//right QVector3D ed1Dir,ed1Per; QVector3D ed2DirL,ed2DirR,ed2PerL,ed2PerR; float ed1W; float ed2WL,ed2WR; std::vector<QVector3D> interPoints; std::vector<Vertex> interVertex; std::vector<Vertex> interPedX; std::vector<Vertex> interPedXLineR; //printf("c\n"); for(int eN=0;eN<edgeAngleOut.size();eN++){ //printf("** eN %d\n",eN); // a) ED1: this edge ed1W=edgeAngleOut[eN].first.first.z();//use z as width ed1p0=edgeAngleOut[eN].first.first; ed1p0.setZ(0); ed1p1=edgeAngleOut[eN].first.second.toVector3D(); // compute right side ed1Dir=(ed1p0-ed1p1).normalized();//ends in 0 ed1Per=(QVector3D::crossProduct(ed1Dir,QVector3D(0,0,1.0f)).normalized());//need normalized()? ed1p0R=ed1p0+ed1Per*ed1W/2.0f; ed1p1R=ed1p1+ed1Per*ed1W/2.0f; // compute left side ed1p0L=ed1p0-ed1Per*ed1W/2.0f; ed1p1L=ed1p1-ed1Per*ed1W/2.0f; // b) ED2: next edge int lastEdge=eN-1; if(lastEdge<0)lastEdge=edgeAngleOut.size()-1; //printf("last eN %d\n",lastEdge); ed2WL=edgeAngleOut[lastEdge].first.first.z();//use z as width ed2p0L=edgeAngleOut[lastEdge].first.first; ed2p0L.setZ(0); ed2p1L=edgeAngleOut[lastEdge].first.second.toVector3D(); // compute left side ed2DirL=(ed2p0L-ed2p1L).normalized();//ends in 0 ed2PerL=(QVector3D::crossProduct(ed2DirL,QVector3D(0,0,1.0f)).normalized());//need normalized()? ed2p0L-=ed2PerL*ed2WL/2.0f; ed2p1L-=ed2PerL*ed2WL/2.0f; // c) ED2: last edge int nextEdge=(eN+1)%edgeAngleOut.size(); //printf("next eN %d\n",nextEdge); ed2WR=edgeAngleOut[nextEdge].first.first.z();//use z as width ed2p0R=edgeAngleOut[nextEdge].first.first; ed2p0R.setZ(0); ed2p1R=edgeAngleOut[nextEdge].first.second.toVector3D(); // compute left side ed2DirR=(ed2p0R-ed2p1R).normalized();//ends in 0 ed2PerR=(QVector3D::crossProduct(ed2DirR,QVector3D(0,0,1.0f)).normalized());//need normalized()? ed2p0R+=ed2PerR*ed2WR/2.0f; ed2p1R+=ed2PerR*ed2WR/2.0f; ////////////////////////////////////////// // d) Computer interior coordinates // d.1 computer intersection left QVector3D intPoint1(FLT_MAX,0,0); if(acos(QVector3D::dotProduct(ed1Dir,ed2DirL))<(170.0f*0.0174532925f)){//angle smaller than 45 degrees float tab,tcd; //printf("ED1 %f %f --> %f %f ED2 %f %f --> %f %f\n",ed1p0R.x(),ed1p0R.y(),ed1p1R.x(),ed1p1R.y(), ed2p0L.x(),ed2p0L.y(),ed2p1L.x(),ed2p1L.y()); if(Util::segmentSegmentIntersectXY3D(ed1p0R,ed1p1R,ed2p0L,ed2p1L,&tab,&tcd, false,intPoint1)==false&&false){ printf("ERROR: Parallel!!!\n"); continue; }else{ //printf("Int %f %f\n",intPoint1.x(),intPoint1.y()); //printf("ADD: No Parallel!!!\n"); } } // d.2 computer intersecion right QVector3D intPoint2(FLT_MAX,0,0); if(acos(QVector3D::dotProduct(ed1Dir,ed2DirR))<(170.0f*0.0174532925f)){//angle smaller than 45 degrees float tab,tcd; //printf("ED1 %f %f --> %f %f ED2 %f %f --> %f %f\n",ed1p0L.x(),ed1p0L.y(),ed1p1L.x(),ed1p1L.y(), ed2p0R.x(),ed2p0R.y(),ed2p1R.x(),ed2p1R.y()); if(Util::segmentSegmentIntersectXY3D(ed1p0L,ed1p1L,ed2p0R,ed2p1R,&tab,&tcd, false,intPoint2)==false){ printf("ERROR: Parallel!!!\n"); continue; }else{ //printf("Int %f %f\n",intPoint2.x(),intPoint2.y()); //printf("ADD: No Parallel!!!\n"); } } if(intPoint1.x()==FLT_MAX&&intPoint2.x()==FLT_MAX){ printf("ERROR: No intersect both sides\n"); printf("angle1 %f\n",acos(QVector3D::dotProduct(ed1Dir,ed2DirR))/0.0174532925f); printf("angle2 %f\n",acos(QVector3D::dotProduct(ed1Dir,ed2DirL))/0.0174532925f); exit(0);//for now exit program } if(intPoint1.x()==FLT_MAX){ intPoint1=intPoint2-ed1Per*ed1W; } if(intPoint2.x()==FLT_MAX){ intPoint2=intPoint1+ed1Per*ed1W; } // middle float zOff=0.1f; intPoint2.setZ(deltaZ+zOff); intPoint1.setZ(deltaZ+zOff); interPoints.push_back(intPoint1); interPoints.push_back(intPoint2); // EDIT: to make the stop line perpendicular to the road direction if (QVector3D::dotProduct(intPoint1 - intPoint2, ed1Dir) >= 0) { intPoint1 -= ed1Dir * QVector3D::dotProduct(intPoint1 - intPoint2, ed1Dir); } else { intPoint2 += ed1Dir * QVector3D::dotProduct(intPoint1 - intPoint2, ed1Dir); } // pedX interPedX.push_back(Vertex(intPoint1,QVector3D(0-0.07f,0,0))); interPedX.push_back(Vertex(intPoint2,QVector3D(ed1W/7.5f+0.07f,0,0))); interPedX.push_back(Vertex(intPoint2-ed1Dir*3.5f,QVector3D(ed1W/7.5f+0.07f,1.0f,0))); interPedX.push_back(Vertex(intPoint1-ed1Dir*3.5f,QVector3D(0.0f-0.07f,1.0f,0))); // Line in right lines QVector3D midPoint=(intPoint2+intPoint1)/2.0f+0.2f*ed1Per; interPedXLineR.push_back(Vertex(intPoint1-ed1Dir*3.5f,QVector3D(0,0.0f,0))); interPedXLineR.push_back(Vertex(midPoint-ed1Dir*3.5f,QVector3D(1.0f,0.0f,0))); interPedXLineR.push_back(Vertex(midPoint-ed1Dir*4.25f,QVector3D(1.0f,1.0f,0))); interPedXLineR.push_back(Vertex(intPoint1-ed1Dir*4.25f,QVector3D(0.0f,1.0f,0))); } //printf("EdgeOut %d interVertex %d\n",edgeAngleOut.size(),interVertex.size()); //rendManager.addStaticGeometry("3d_roads_interCom",interVertex,"../data/textures/roads/road_pedX.jpg",GL_POINTS,1|mode_AdaptTerrain);//POINTS (tex meant to set points) if(interPoints.size()>2){ { for(int iP=0;iP<interPoints.size()-1;iP++){//remove duplicated if((interPoints[iP]-interPoints[iP+1]).lengthSquared()<0.5f){ interPoints.erase(interPoints.begin()+iP); iP--; } } } rendManager.addStaticGeometry2("3d_roads_interCom",interPoints,0.0f,false,"../data/textures/roads/road_0lines.jpg",GL_QUADS,2|mode_AdaptTerrain,QVector3D(1.0f/7.5f,1.0f/7.5f,1),QVector3D());//0.0f (moved before) } rendManager.addStaticGeometry("3d_roads_interCom",interPedX,"../data/textures/roads/road_pedX.jpg",GL_QUADS,2|mode_AdaptTerrain); rendManager.addStaticGeometry("3d_roads_interCom",interPedXLineR,"../data/textures/roads/road_pedXLineR.jpg",GL_QUADS,2|mode_AdaptTerrain); } }//all vertex rendManager.addStaticGeometry("3d_roads_inter",intersectCirclesV,"../data/textures/roads/road_0lines.jpg",GL_TRIANGLES,2|mode_AdaptTerrain); } }//
void GeometricHelperTest::LineSegmentRayIntersectionTest() { { LineSegment ls1(Vertex(0, 1), Vertex(1, 1)); Ray ray(Vertex(0, 0), Vertex(1, 2)); // segment/ray intersect boost::optional<Vertex> intersection_point_opt = GeometricHelper::intersect(ls1, ray); CPPUNIT_ASSERT_MESSAGE("Intersection point expected", bool(intersection_point_opt)); Vertex intersection_point = *intersection_point_opt; CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Intersection point error", 0.5, intersection_point.x(), 1E-10); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Intersection point error", 1.0, intersection_point.y(), 1E-10); } { LineSegment ls1(Vertex(0, 3), Vertex(1, 3)); Ray ray(Vertex(0, 0), Vertex(0.25, 1)); // segment/ray intersect boost::optional<Vertex> intersection_point_opt = GeometricHelper::intersect(ls1, ray); CPPUNIT_ASSERT_MESSAGE("Intersection point expected", bool(intersection_point_opt)); Vertex intersection_point = *intersection_point_opt; CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Intersection point error", 0.75, intersection_point.x(), 1E-10); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Intersection point error", 3.0, intersection_point.y(), 1E-10); } { LineSegment ls1(Vertex(0, 1), Vertex(1, 1)); Ray ray(Vertex(0.25, 2), Vertex(1, 4)); // segment/ray do not intersect boost::optional<Vertex> intersection_point_opt = GeometricHelper::intersect(ls1, ray); CPPUNIT_ASSERT_MESSAGE("No intersection point expected", !bool(intersection_point_opt)); } { LineSegment ls(Vertex(0, 1), Vertex(1, 1)); Ray ray(Vertex(0, 0), Vertex(2, 1)); // segments do not intersect boost::optional<Vertex> intersection_point_opt = GeometricHelper::intersect(ls, ray); CPPUNIT_ASSERT_MESSAGE("No intersection point expected", !bool(intersection_point_opt)); } { LineSegment ls(Vertex(0, 1), Vertex(1, 1)); Ray ray(Vertex(0.5, 1), Vertex(2, 1)); // segment/ray overlap boost::optional<Vertex> intersection_point_opt = GeometricHelper::intersect(ls, ray); CPPUNIT_ASSERT_MESSAGE("No intersection point expected", !bool(intersection_point_opt)); } { LineSegment ls(Vertex(0.5, 1), Vertex(1, 1)); Ray ray(Vertex(0, 1), Vertex(2, 1)); // segment contained in ray boost::optional<Vertex> intersection_point_opt = GeometricHelper::intersect(ls, ray); CPPUNIT_ASSERT_MESSAGE("No intersection point expected", !bool(intersection_point_opt)); } { LineSegment ls(Vertex(0, 1), Vertex(1, 1)); Ray ray(Vertex(1.5, 1), Vertex(2, 1)); // segment and ray parallel boost::optional<Vertex> intersection_point_opt = GeometricHelper::intersect(ls, ray); CPPUNIT_ASSERT_MESSAGE("No intersection point expected", !bool(intersection_point_opt)); } }
void RoadGraph::_generateMeshVerticesDefault(VBORenderManager& renderManager, const QString &linesN, const QString &pointsN) { ////////////////////////////////////// // EDGES { RoadEdgeIter ei, eend; for (boost::tie(ei, eend) = boost::edges(graph); ei != eend; ++ei) { if (!graph[*ei]->valid) continue; int num = graph[*ei]->polyline3D.size(); if (num <= 1) continue; float halfWidth = graph[*ei]->getWidth()*0.5f;//it should not have /2.0f (but compensated below) std::vector<Vertex> vert(4*(num - 1)); std::vector<Vertex> vertBg(4*(num - 1)); // Type QColor color;// = graph[*ei]->color; QColor colorO; float heightOffset = 0.0f; float heightOffsetO=0.0f; switch (graph[*ei]->type) { case RoadEdge::TYPE_HIGHWAY: heightOffset = 0.8f; heightOffsetO = 0.3f; color=QColor(0xfa,0x9e,0x25); colorO=QColor(0x00, 0x00, 0x00);//QColor(0xdf,0x9c,0x13); halfWidth*=1.4f; break; case RoadEdge::TYPE_BOULEVARD: heightOffset = 0.5f; heightOffsetO = 0.2f; color=QColor(0xff,0xe1,0x68); colorO=QColor(0x00, 0x00, 0x00);//QColor(0xe5,0xbd,0x4d); halfWidth*=1.4f; break; case RoadEdge::TYPE_AVENUE: heightOffset = 0.6f; heightOffsetO = 0.1f; color=QColor(0xff,0xe1,0x68); colorO=QColor(0x00, 0x00, 0x00);//QColor(0xe5,0xbd,0x4d); halfWidth*=1.4f; break; case RoadEdge::TYPE_STREET: heightOffset = 0.4f; heightOffsetO = 0.1f; color=QColor(0xff,0xff,0xff); colorO=QColor(0x00, 0x00, 0x00);//QColor(0xd7,0xd1,0xc7); halfWidth*=1.8f; break; } halfWidth+= G::global().getFloat("2DroadsExtraWidth"); heightOffset+=0.45f;//to have park below heightOffsetO+=0.45f;//to have park below float halfWidthBg = halfWidth + G::global().getFloat("2DroadsStroke");//it should not depend on the type 3.5f QVector3D p0, p1, p2, p3; QVector3D p0Bg, p1Bg, p2Bg, p3Bg; for (int i = 0; i < num - 1; ++i) { QVector3D pt1 = graph[*ei]->polyline3D[i]; QVector3D pt2 = graph[*ei]->polyline3D[i + 1]; QVector3D perp = pt2 - pt1; perp = QVector3D(-perp.y(), perp.x(), 0.0f); perp.normalize(); if (i == 0) { p0 = pt1 + perp * halfWidth; p1 = pt1 - perp * halfWidth; p0Bg = pt1 + perp * halfWidthBg; p1Bg = pt1 - perp * halfWidthBg; } p2 = pt2 - perp * halfWidth; p3 = pt2 + perp * halfWidth; p2Bg = pt2 - perp * halfWidthBg; p3Bg = pt2 + perp * halfWidthBg; QVector3D normal = Util::calculateNormal(p0, p1, p2); if (i < num - 2) { QVector3D pt3 = graph[*ei]->polyline3D[i + 2]; Util::getIrregularBisector(pt1, pt2, pt3, halfWidth, halfWidth, p3); Util::getIrregularBisector(pt1, pt2, pt3, -halfWidth, -halfWidth, p2); Util::getIrregularBisector(pt1, pt2, pt3, halfWidthBg, halfWidthBg, p3Bg); Util::getIrregularBisector(pt1, pt2, pt3, -halfWidthBg, -halfWidthBg, p2Bg); } vert[i*4+0]=Vertex(p0,QVector3D(),QVector3D(0,0,1.0f),QVector3D(0,0,0));// pos color normal texture vert[i*4+1]=Vertex(p1,QVector3D(),QVector3D(0,0,1.0f),QVector3D(1,0,0));// pos color normal texture vert[i*4+2]=Vertex(p2,QVector3D(),QVector3D(0,0,1.0f),QVector3D(1,1,0));// pos color normal texture vert[i*4+2]=Vertex(p3,QVector3D(),QVector3D(0,0,1.0f),QVector3D(0,1,0));// pos color normal texture /* vert[i*4+0]=Vertex(p0.x(),p0.y(),p0.z()+heightOffset,color.redF(),color.greenF(),color.blueF(),0,0,1.0f,0,0,0);// pos color normal texture vert[i*4+1]=Vertex(p1.x(),p1.y(),p1.z()+heightOffset,color.redF(),color.greenF(),color.blueF(),0,0,1.0f,1,0,0);// pos color normal texture vert[i*4+2]=Vertex(p2.x(),p2.y(),p2.z()+heightOffset,color.redF(),color.greenF(),color.blueF(),0,0,1.0f,1,1,0);// pos color normal texture vert[i*4+3]=Vertex(p3.x(),p3.y(),p3.z()+heightOffset,color.redF(),color.greenF(),color.blueF(),0,0,1.0f,0,1,0);// pos color normal texture */ vertBg[i*4+0]=Vertex(p0Bg.x(),p0Bg.y(),p0Bg.z()+heightOffsetO,colorO.redF(),colorO.greenF(),colorO.blueF(),0,0,1.0f,0,0,0);// pos color normal texture vertBg[i*4+1]=Vertex(p1Bg.x(),p1Bg.y(),p1Bg.z()+heightOffsetO,colorO.redF(),colorO.greenF(),colorO.blueF(),0,0,1.0f,0,0,0);// pos color normal texture vertBg[i*4+2]=Vertex(p2Bg.x(),p2Bg.y(),p2Bg.z()+heightOffsetO,colorO.redF(),colorO.greenF(),colorO.blueF(),0,0,1.0f,0,0,0);// pos color normal texture vertBg[i*4+3]=Vertex(p3Bg.x(),p3Bg.y(),p3Bg.z()+heightOffsetO,colorO.redF(),colorO.greenF(),colorO.blueF(),0,0,1.0f,0,0,0);// pos color normal texture p0 = p3; p1 = p2; p0Bg = p3Bg; p1Bg = p2Bg; } //renderManager.addStaticGeometry(linesN, vert, "", GL_QUADS, 1);//MODE=1 color //renderManager.addStaticGeometry(linesN, vertBg, "", GL_QUADS, 1);//MODE=1 color renderManager.addStaticGeometry(linesN, vert, "../data/extures/roads/road_2lines.jpg", GL_QUADS, 2|mode_AdaptTerrain); } } ///////////////////////////////////////////////////// // INTERSECTIONS { RoadVertexIter vi, vend; for (boost::tie(vi, vend) = boost::vertices(graph); vi != vend; ++vi) { if (!graph[*vi]->valid) continue; // get the largest width of the outing edges QColor color;// = graph[*ei]->color; QColor colorO; float heightOffset = 0.0f; float heightOffsetO=0.0f; bool render = false; int maxType=-1; float halfWidth; RoadOutEdgeIter oei, oeend; for (boost::tie(oei, oeend) = boost::out_edges(*vi, graph); oei != oeend; ++oei) { if (!graph[*oei]->valid) continue; //printf("type %d\n",graph[*oei]->type); if(maxType>graph[*oei]->type) continue; maxType=graph[*oei]->type; halfWidth=graph[*oei]->getWidth()*0.5f;//it should not have /2.0f (but compensated below) switch (graph[*oei]->type) { case RoadEdge::TYPE_HIGHWAY: render = true; heightOffset = 0.6f; heightOffsetO = 0.3f; color=QColor(0xfa,0x9e,0x25); colorO=QColor(0x00, 0x00, 0x00);//QColor(0xdf,0x9c,0x13); halfWidth*=1.4f; continue; case RoadEdge::TYPE_BOULEVARD: heightOffset = 0.5f; heightOffsetO = 0.2f; color=QColor(0xff,0xe1,0x68); colorO=QColor(0x00, 0x00, 0x00);//QColor(0xe5,0xbd,0x4d); halfWidth*=1.4f; continue; case RoadEdge::TYPE_AVENUE: render = true; heightOffset = 0.5f; heightOffsetO = 0.2f; color=QColor(0xff,0xe1,0x68); colorO=QColor(0x00, 0x00, 0x00);//QColor(0xe5,0xbd,0x4d); halfWidth*=1.4f; continue; case RoadEdge::TYPE_STREET: render = true; heightOffset = 0.4f; heightOffsetO = 0.2f; color=QColor(0xff,0xff,0xff); colorO=QColor(0x00, 0x00, 0x00);//QColor(0xd7,0xd1,0xc7); halfWidth*=1.8f; continue; } } halfWidth+= G::global().getFloat("2DroadsExtraWidth"); heightOffset+=0.45f;//to have park below heightOffsetO+=0.45f;//to have park below float max_r=halfWidth; float max_rO=halfWidth + G::global().getFloat("2DroadsStroke");//it should not depend on the type 3.5f std::vector<Vertex> vert(3*20); std::vector<Vertex> vertBg(3*20); for (int i = 0; i < 20; ++i) { float angle1 = 2.0 * M_PI * i / 20.0f; float angle2 = 2.0 * M_PI * (i + 1) / 20.0f; vert[i*3+0]=Vertex(graph[*vi]->pt3D.x(), graph[*vi]->pt3D.y(), graph[*vi]->pt3D.z() + heightOffset, color.redF(), color.greenF(), color.blueF(), 0, 0, 1.0f, 0, 0, 0); vert[i*3+1]=Vertex(graph[*vi]->pt3D.x() + max_r * cosf(angle1), graph[*vi]->pt3D.y() + max_r * sinf(angle1), graph[*vi]->pt3D.z() + heightOffset, color.redF(), color.greenF(), color.blueF(), 0, 0, 1.0f, 0, 0, 0); vert[i*3+2]=Vertex(graph[*vi]->pt3D.x() + max_r * cosf(angle2), graph[*vi]->pt3D.y() + max_r * sinf(angle2), graph[*vi]->pt3D.z() + heightOffset, color.redF(), color.greenF(), color.blueF(), 0, 0, 1.0f, 0, 0, 0); vertBg[i*3+0]=Vertex(graph[*vi]->pt3D.x(), graph[*vi]->pt3D.y(), graph[*vi]->pt3D.z() + heightOffsetO, colorO.redF(), colorO.greenF(), colorO.blueF(), 0, 0, 1.0f, 0, 0, 0); vertBg[i*3+1]=Vertex(graph[*vi]->pt3D.x() + max_rO * cosf(angle1), graph[*vi]->pt3D.y() + max_rO * sinf(angle1), graph[*vi]->pt3D.z() + heightOffsetO, colorO.redF(), colorO.greenF(), colorO.blueF(), 0, 0, 1.0f, 0, 0, 0); vertBg[i*3+2]=Vertex(graph[*vi]->pt3D.x() + max_rO * cosf(angle2), graph[*vi]->pt3D.y() + max_rO * sinf(angle2), graph[*vi]->pt3D.z() + heightOffsetO, colorO.redF(), colorO.greenF(), colorO.blueF(), 0, 0, 1.0f, 0, 0, 0); } //renderManager.addStaticGeometry(pointsN, vert, "", GL_TRIANGLES, 1);//MODE=1 color //renderManager.addStaticGeometry(pointsN, vertBg, "", GL_TRIANGLES, 1);//MODE=1 color } } }
bool d3d::DrawBasicScene(IDirect3DDevice9* device, float scale) { static IDirect3DVertexBuffer9* floor = 0; static IDirect3DTexture9* tex = 0; static ID3DXMesh* pillar = 0; HRESULT hr = 0; if( device == 0 ) { if( floor && tex && pillar ) { // they already exist, destroy them d3d::Release<IDirect3DVertexBuffer9*>(floor); d3d::Release<IDirect3DTexture9*>(tex); d3d::Release<ID3DXMesh*>(pillar); } } else if( !floor && !tex && !pillar ) { // they don't exist, create them device->CreateVertexBuffer( 6 * sizeof(d3d::Vertex), 0, d3d::Vertex::FVF, D3DPOOL_MANAGED, &floor, 0); Vertex* v = 0; floor->Lock(0, 0, (void**)&v, 0); v[0] = Vertex(-20.0f, -2.5f, -20.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f); v[1] = Vertex(-20.0f, -2.5f, 20.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f); v[2] = Vertex( 20.0f, -2.5f, 20.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f); v[3] = Vertex(-20.0f, -2.5f, -20.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f); v[4] = Vertex( 20.0f, -2.5f, 20.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f); v[5] = Vertex( 20.0f, -2.5f, -20.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f); floor->Unlock(); D3DXCreateCylinder(device, 0.5f, 0.5f, 5.0f, 20, 20, &pillar, 0); D3DXCreateTextureFromFile( device, "desert.bmp", &tex); } else { // // Pre-Render Setup // device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); device->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_POINT); D3DXVECTOR3 dir(0.707f, -0.707f, 0.707f); D3DXCOLOR col(1.0f, 1.0f, 1.0f, 1.0f); D3DLIGHT9 light = d3d::InitDirectionalLight(&dir, &col); device->SetLight(0, &light); device->LightEnable(0, true); device->SetRenderState(D3DRS_NORMALIZENORMALS, true); device->SetRenderState(D3DRS_SPECULARENABLE, true); // // Render // D3DXMATRIX T, R, P, S; D3DXMatrixScaling(&S, scale, scale, scale); // used to rotate cylinders to be parallel with world's y-axis D3DXMatrixRotationX(&R, -D3DX_PI * 0.5f); // draw floor D3DXMatrixIdentity(&T); T = T * S; device->SetTransform(D3DTS_WORLD, &T); device->SetMaterial(&d3d::WHITE_MTRL); device->SetTexture(0, tex); device->SetStreamSource(0, floor, 0, sizeof(Vertex)); device->SetFVF(Vertex::FVF); device->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 2); // draw pillars device->SetMaterial(&d3d::BLUE_MTRL); device->SetTexture(0, 0); for(int i = 0; i < 5; i++) { D3DXMatrixTranslation(&T, -5.0f, 0.0f, -15.0f + (i * 7.5f)); P = R * T * S; device->SetTransform(D3DTS_WORLD, &P); pillar->DrawSubset(0); D3DXMatrixTranslation(&T, 5.0f, 0.0f, -15.0f + (i * 7.5f)); P = R * T * S; device->SetTransform(D3DTS_WORLD, &P); pillar->DrawSubset(0); } } return true; }
// // Framework Functions // bool Setup() { // // Create the BackDrop quad. // Device->CreateVertexBuffer( 6 * sizeof(Vertex), D3DUSAGE_WRITEONLY, FVF_VERTEX, D3DPOOL_MANAGED, &BackDropVB, 0); Vertex* v; BackDropVB->Lock(0, 0, (void**)&v, 0); // quad built from two triangles, note texture coordinates: v[0] = Vertex(-10.0f, -10.0f, 5.0f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f); v[1] = Vertex(-10.0f, 10.0f, 5.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f); v[2] = Vertex( 10.0f, 10.0f, 5.0f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f); v[3] = Vertex(-10.0f, -10.0f, 5.0f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f); v[4] = Vertex( 10.0f, 10.0f, 5.0f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f); v[5] = Vertex( 10.0f, -10.0f, 5.0f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f); BackDropVB->Unlock(); // // Create the cube. // Box = new Cube(Device); // // Load the textures and set filters. // D3DXCreateTextureFromFile( Device, "cratewalpha.dds", &CrateTex); D3DXCreateTextureFromFile( Device, "lobbyxpos.jpg", &BackDropTex); Device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); Device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); Device->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_POINT); // // set alpha blending stuff // // use alpha channel in texture for alpha Device->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); Device->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); // set blending factors so that alpha component determines transparency Device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); Device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); // // disable lighting // Device->SetRenderState(D3DRS_LIGHTING, false); // // set camera // D3DXVECTOR3 pos(0.0f, 0.f, -2.5f); D3DXVECTOR3 target(0.0f, 0.0f, 0.0f); D3DXVECTOR3 up(0.0f, 1.0f, 0.0f); D3DXMATRIX V; D3DXMatrixLookAtLH( &V, &pos, &target, &up); Device->SetTransform(D3DTS_VIEW, &V); // // Set projection matrix // D3DXMATRIX proj; D3DXMatrixPerspectiveFovLH( &proj, D3DX_PI * 0.5f, // 90 - degree (float)Width / (float)Height, 1.0f, 1000.0f); Device->SetTransform(D3DTS_PROJECTION, &proj); return true; }
void TestClusteringPopulationAnalyzer::testEvaluatePopulationOneThread(void) { Graph graph; // Initialize graph graph.addVertex(Vertex(0)); graph.addVertex(Vertex(1)); graph.addVertex(Vertex(2)); graph.addVertex(Vertex(3)); graph.addVertex(Vertex(4)); graph.addVertex(Vertex(5)); graph.addVertex(Vertex(6)); graph.addVertex(Vertex(7)); graph.addEdge(Vertex(0), Vertex(1), 0.2); graph.addEdge(Vertex(1), Vertex(2), 0.3); graph.addEdge(Vertex(1), Vertex(3), 0.5); graph.addEdge(Vertex(2), Vertex(3), 0.4); graph.addEdge(Vertex(3), Vertex(4), 0.2); graph.addEdge(Vertex(4), Vertex(5), 0.5); graph.addEdge(Vertex(4), Vertex(6), 0.6); graph.addEdge(Vertex(5), Vertex(6), 0.7); graph.addEdge(Vertex(6), Vertex(7), 0.1); IntegerEncodingInitializer initVec(&graph); std::vector<PopulationMember<IntegerVectorEncoding, double>> vecPop; for (size_t i = 0; i < populationSize; i++) { PopulationMember<IntegerVectorEncoding, double> member; member.fitnessValue = 0.0; member.modified = true; member.populationEncoding = initVec.getRandomSolution(); vecPop.push_back(member); } ClusteringPopulationAnalyzer<FitnessAnalyzer, std::vector<PopulationMember<IntegerVectorEncoding, double>>> analyzer(&graph, &vecPop, 1); analyzer.evaluatePopulation(); FitnessAnalyzer singleAnalyzer; for (auto& e : vecPop) { CPPUNIT_ASSERT(singleAnalyzer.analyze(&e.populationEncoding, &graph) == e.fitnessValue); } }
Sun::Sun(Camera *cam, class Geometry *parent){ camera = cam; mat1 = new Material("Textures/Lens/Halo",Texture::cRGB); mat1->SetMode(MATERIAL_SOURCE_DIFFUSE|MATERIAL_DEST_ADD_SOURCE); //MATERIAL_DEST_MULTIPLY_ONE_MINUS_ALPHA); mat2 = new Material("Textures/Lens/Sun",Texture::cRGB); mat2->SetMode(MATERIAL_SOURCE_DIFFUSE|MATERIAL_DEST_ADD_SOURCE); //MULTIPLY_ONE_MINUS_ALPHA); //mat1->SetTransparency(.6f); //mat2->SetTransparency(.8f); mat1->SetTransparency(.95f); mat2->SetTransparency(.8f); Geometry *g = new Geometry(); g->SetName(0,"Sun"); g->Apply(mat1); /* g->Add(Vector(-6000/2/3, 6000/2/3,0)); g->Add(Vector( 6000/2/3, 6000/2/3,0)); g->Add(Vector( 6000/2/3,-6000/2/3,0)); g->Add(Vector(-6000/2/3,-6000/2/3,0)); g->Add(Vector(-6000*5/2, 6000*5/2,-10000)); g->Add(Vector( 6000*5/2, 6000*5/2,-10000)); g->Add(Vector( 6000*5/2,-6000*5/2,-10000)); g->Add(Vector(-6000*5/2,-6000*5/2,-10000)); */ g->Add(Vector(-6000*5/2, 6000*5/2,0)); g->Add(Vector( 6000*5/2, 6000*5/2,0)); g->Add(Vector( 6000*5/2,-6000*5/2,0)); g->Add(Vector(-6000*5/2,-6000*5/2,0)); g->Add(Vector(-6000*5/2, 6000*5/2,-10000)); g->Add(Vector( 6000*5/2, 6000*5/2,-10000)); g->Add(Vector( 6000*5/2,-6000*5/2,-10000)); g->Add(Vector(-6000*5/2,-6000*5/2,-10000)); g->Add(Vertex(0,0,0)); g->Add(Vertex(1,1,0)); g->Add(Vertex(2,1,1)); g->Add(Vertex(3,0,1)); g->Add(Vertex(4,0,0)); g->Add(Vertex(5,1,0)); g->Add(Vertex(6,1,1)); g->Add(Vertex(7,0,1)); IndexedPolygon *pol; pol = new IndexedPolygon(g); //new IndexedPolygon(g); pol->Add(0); pol->Add(1); pol->Add(2); pol->Add(3); //pol->Apply(mat1); /* pol = new IndexedPolygon(g); //new IndexedPolygon(g); pol->Apply(mat2); pol->Add(4); pol->Add(5); pol->Add(6); pol->Add(7);*/ Intelligence::Apply(g); g->Node::Apply(0,this); parent->Node::Apply(0,g); SetPosition(Vector(0,0,50000)); g->SetSquareRadius(0); }