Пример #1
0
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;
}
Пример #2
0
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;
}
Пример #3
0
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);
    }

  }
}
Пример #4
0
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));
    }
}
Пример #6
0
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);
}
Пример #7
0
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

}
Пример #8
0
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);
}
Пример #9
0
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();
}
Пример #10
0
	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);
}
Пример #12
0
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);
}
Пример #13
0
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();
}
Пример #14
0
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;
}
Пример #15
0
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;
}
Пример #16
0
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);
	}
}
Пример #17
0
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 << "\t@" << 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;
}
Пример #18
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]);
}
Пример #20
0
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);
}
Пример #21
0
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;
}
Пример #22
0
//
// 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));
    }
}
Пример #24
0
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));
    }
}
Пример #26
0
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
		}
	}
}
Пример #27
0
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;
}
Пример #28
0
//
// 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);
    }
}
Пример #30
0
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);
}