Example #1
0
void ConeRenderer::init(ShaderProgram* prog)
{
	if(_vbo) {
	    _vbo->bind();
	    _vbo->setPointer();
	    return;
	}
	_vbo = make_resource<VBO>(getResourceManager(),
	                          "P");
	_vbo->overrideIndex(getResourceManager()->geometryCache()->getIndexForAttribute("P"));
	_vbo->bind();
	prog->bindAttributeLocation(_vbo.get());

	VertexList verts;

    //cone
    verts.push_back(glm::vec3(0, 1, 0));
    for(int i=0; i <= _segments; i++) {
        float pni = 2 * PI * float(i) / _segments;
        verts.push_back(glm::vec3(sin(pni), 0, cos(pni)));
    }
    //disc
    verts.push_back(glm::vec3());
    for(int i=_segments; i >= 0; i--) {
        float pni = 2 * PI * float(i) / _segments;
        verts.push_back(glm::vec3(sin(pni), 0, cos(pni)));
    }

    _vbo->data(verts);
    _vbo->setPointer();
}
void Cylinder::buildTopCap(VertexList& vertices, IndexList& indices)
{
	UINT baseIndex = (UINT)vertices.size();

	// Duplicate cap vertices because the texture coordinates and normals differ.
	float y = 0.5f*mHeight;

	// vertices of ring
	float dTheta = 2.0f*PI/mNumSlices;
	for(UINT i = 0; i <= mNumSlices; ++i)
	{
		float x = mTopRadius*cosf(i*dTheta);
		float z = mTopRadius*sinf(i*dTheta);

		// Map [-1,1]-->[0,1] for planar texture coordinates.
		float u = +0.5f*x/mTopRadius + 0.5f;
		float v = -0.5f*z/mTopRadius + 0.5f;

		vertices.push_back( Vertex(x, y, z, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, u, v) );
	}

	// cap center vertex
	vertices.push_back( Vertex(0.0f, y, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.5f, 0.5f) );

	// index of center vertex
	UINT centerIndex = (UINT)vertices.size()-1;

	for(UINT i = 0; i < mNumSlices; ++i)
	{
		indices.push_back(centerIndex);
		indices.push_back(baseIndex + i+1);
		indices.push_back(baseIndex + i);
	}
}
Example #3
0
void PolyMesh::findNeighbors( osg::Vec3 p, VertexList& vlist )
{
    for ( EdgeMap::iterator itr=_edges.begin(); itr!=_edges.end(); ++itr )
    {
        if ( equivalent(itr->first.first,p) )
            vlist.push_back( itr->first.second );
        else if ( equivalent(itr->first.second,p) )
            vlist.push_back( itr->first.first );
    }
}
Example #4
0
//***************************************************************************************
// Name: Subdivide
// Desc: Function subdivides every input triangle into four triangles of equal area.
//***************************************************************************************
void Subdivide(VertexList& vertices, IndexList& indices)
{
	VertexList vin = vertices;
	IndexList  iin = indices;

	vertices.resize(0);
	indices.resize(0);

	//       v1
	//       *
	//      / \
	//     /   \
	//  m0*-----*m1
	//   / \   / \
	//  /   \ /   \
	// *-----*-----*
	// v0    m2     v2

	UINT numTris = (UINT)iin.size()/3;
	for(UINT i = 0; i < numTris; ++i)
	{
		D3DXVECTOR3 v0 = vin[ iin[i*3+0] ];
		D3DXVECTOR3 v1 = vin[ iin[i*3+1] ];
		D3DXVECTOR3 v2 = vin[ iin[i*3+2] ];

		D3DXVECTOR3 m0 = 0.5f*(v0 + v1);
		D3DXVECTOR3 m1 = 0.5f*(v1 + v2);
		D3DXVECTOR3 m2 = 0.5f*(v0 + v2);

		vertices.push_back(v0); // 0
		vertices.push_back(v1); // 1
		vertices.push_back(v2); // 2
		vertices.push_back(m0); // 3
		vertices.push_back(m1); // 4
		vertices.push_back(m2); // 5
 
		indices.push_back(i*6+0);
		indices.push_back(i*6+3);
		indices.push_back(i*6+5);

		indices.push_back(i*6+3);
		indices.push_back(i*6+4);
		indices.push_back(i*6+5);

		indices.push_back(i*6+5);
		indices.push_back(i*6+4);
		indices.push_back(i*6+2);

		indices.push_back(i*6+3);
		indices.push_back(i*6+1);
		indices.push_back(i*6+4);
	}
}
Example #5
0
ListPair KDTree::splitListBy(const size_t& index, const VertexList& sourceList,
        const VertexPtr& sourceVert){
    VertexList left;
    VertexList right;

    for(VertexPtr elem : sourceList){
        if((*elem)[index] < (*sourceVert)[index]){
            left.push_back(elem);
        }else{
            right.push_back(elem);
        }
    }
    return ListPair(left, right);
}
void copyPointListToVertexList(const PointList& in,VertexList& out)
{
    out.reserve(in.size());
    for(PointList::const_iterator itr=in.begin();
        itr!=in.end();
        ++itr)
    {
        out.push_back(itr->second);
    }
}
Example #7
0
bool PLY2Reader::loadPLY2Mesh(std::shared_ptr<Shape> shape, std::string fname)
{
  std::ifstream f_handler(fname);
  if (!f_handler)
  {
    std::cout << "Open file failed.\n";
    return false;
  }

  std::string line;
  std::stringstream ss;

  int num_vertex = 0;
  int num_face = 0;
  VertexList vertexList;
  FaceList faceList;
  STLVectorf UVList;

  getline(f_handler, line);
  ss.str(line);
  ss >> num_vertex;
  getline(f_handler, line);
  ss.str(line);
  ss >> num_face;

  for (int i = 0; i < num_vertex; ++i)
  {
    float v;
    for (int j = 0; j < 3; ++j)
    {
      getline(f_handler, line);
      ss.str(line);
      ss >> v;
      vertexList.push_back(v);
    }
  }

  for (int i = 0; i < num_face; ++i)
  {
    int f;
    for (int j = 0; j < 3; ++j)
    {
      getline(f_handler, line);
      ss.str(line);
      ss >> f;
      faceList.push_back(f);
    }
  }

  shape->init(vertexList, faceList, UVList);
  return true;
}
Example #8
0
VertexList KDTree::findKNearestNeighbours(const VertexPtr source,
        const size_t numNeighbours){
    VertexList result;
    //Stopwatch findS("NKSearch");
    LimitedPriorityQueue resultQueue(numNeighbours);
    findKNearestNeighbours(m_root, resultQueue, source);
    while(!resultQueue.empty()){
        VertexDistPair pair = resultQueue.top();
        VertexPtr vrtx = std::get<0>(pair);
        result.push_back(vrtx);
        resultQueue.pop();
    }
    //findS.stop();
    return result;
}
Example #9
0
void LineRenderer::init(ShaderProgram* prog)
{
    _vbo = make_resource<VBO>(getResourceManager(),
                              "P");
    _vbo->overrideIndex(getResourceManager()->geometryCache()->getIndexForAttribute("P"));
    _vbo->bind();
    prog->bindAttributeLocation(_vbo.get());

    VertexList points;
    for(auto p : _points) {
        points.push_back(p);
    }
    _vbo->data(points);
    _vbo->setPointer();
}
Example #10
0
void KDTree::findInRadius(const NodePtr& src, const HyperSphere& sphere,
            VertexList& result) const{

    if(src->isLeaf()){
        for(VertexPtr vrtx : src->getBucket()){
            if(sphere.contains(vrtx)){
                result.push_back(vrtx);
            }
        }
    }
    if(src->getLeft() != nullptr){
        if(sphere.intersectsRegion(src->getDomain())){
            findInRadius(src->getLeft(), sphere, result);
        }
    }
    if(src->getRight() != nullptr){
        if(sphere.intersectsRegion(src->getDomain())){
            findInRadius(src->getRight(), sphere, result);
        }
    }
}
    void StaticGeometryBuffer::_generateIndices()
    {
        _indexList.clear();

        VertexList  newVertList;
        //DebugText   debugText;

        for( uint i = 0; i < _vertexList.size(); ++i )
        {
            bool repeated = false;

            ///FLip uv's for openGL
            _vertexList[ i ].texCoord.y = 1 - _vertexList[ i ].texCoord.y;

            for( uint j = 0; j < newVertList.size(); ++j )
            {

                repeated = _isSameVertex( _vertexList[ i ], newVertList[ j ] );

                if( repeated )
                {
                    _indexList.push_back( j );
                    break;
                }
            }


            if( !repeated )
            {
                newVertList.push_back( _vertexList[ i ] );
                _indexList.push_back( newVertList.size() - 1 );
            }
        }

        _vertexList = newVertList;
    }
void Cylinder::buildStacks(VertexList& vertices, IndexList& indices)
{
	float stackHeight = mHeight / mNumStacks;

	// Amount to increment radius as we move up each stack level from bottom to top.
	float radiusStep = (mTopRadius - mBottomRadius) / mNumStacks;

	UINT numRings = mNumStacks+1;

	// Compute vertices for each stack ring.
	for(UINT i = 0; i < numRings; ++i)
	{
		float y = -0.5f*mHeight + i*stackHeight;
		float r = mBottomRadius + i*radiusStep;

		// Height and radius of next ring up.
		float y_next = -0.5f*mHeight + (i+1)*stackHeight;
		float r_next = mBottomRadius + (i+1)*radiusStep;
	 
		// vertices of ring
		float dTheta = 2.0f*PI/mNumSlices;
		for(UINT j = 0; j <= mNumSlices; ++j)
		{
			float c = cosf(j*dTheta);
			float s = sinf(j*dTheta);

			float u = (float)j/mNumSlices;
			float v = 1.0f - (float)i/mNumStacks;

			// Partial derivative in theta direction to get tangent vector (this is a unit vector).
			D3DXVECTOR3 T(-s, 0.0f, c);

			// Compute tangent vector down the slope of the cone (if the top/bottom 
			// radii differ then we get a cone and not a true cylinder).
			D3DXVECTOR3 P(r*c, y, r*s);
			D3DXVECTOR3 P_next(r_next*c, y_next, r_next*s);
			D3DXVECTOR3 B = P - P_next;
			D3DXVec3Normalize(&B, &B);

			D3DXVECTOR3 N;
			D3DXVec3Cross(&N, &T, &B);
			D3DXVec3Normalize(&N, &N);

			vertices.push_back( Vertex(P.x, P.y, P.z, T.x, T.y, T.z, N.x, N.y, N.z, u, v) );
		}
	}

	UINT numRingVertices = mNumSlices+1;

	// Compute indices for each stack.
	for(UINT i = 0; i < mNumStacks; ++i)
	{
		for(UINT j = 0; j < mNumSlices; ++j)
		{
			indices.push_back(i*numRingVertices + j);
			indices.push_back((i+1)*numRingVertices + j);
			indices.push_back((i+1)*numRingVertices + j+1);

			indices.push_back(i*numRingVertices + j);
			indices.push_back((i+1)*numRingVertices + j+1);
			indices.push_back(i*numRingVertices + j+1);
		}
	}
}
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);
	}
}
Example #14
0
      void Smooth::operator() (const Mesh& in, Mesh& out) const
      {
        std::unique_ptr<ProgressBar> progress;
        if (message.size())
          progress.reset (new ProgressBar (message, 8));
        out.clear();

        const size_t V = in.num_vertices();
        if (!V) return;

        if (in.num_quads())
          throw Exception ("For now, mesh smoothing is only supported for triangular meshes");
        const size_t T = in.num_triangles();
        if (V == 3*T)
          throw Exception ("Cannot perform smoothing on this mesh: no triangulation information");

        // Pre-compute polygon centroids and areas
        VertexList centroids;
        vector<default_type> areas;
        for (TriangleList::const_iterator p = in.triangles.begin(); p != in.triangles.end(); ++p) {
          centroids.push_back ((in.vertices[(*p)[0]] + in.vertices[(*p)[1]] + in.vertices[(*p)[2]]) * (1.0/3.0));
          areas.push_back (area (in, *p));
        }
        if (progress) ++(*progress);

        // Perform pre-calculation of an appropriate mesh neighbourhood for each vertex
        // Use knowledge of the connections between vertices provided by the triangles/quads to
        //   perform an iterative search outward from each vertex, selecting a subset of
        //   polygons for each vertex
        // Extent of window should be approximately the value of spatial_factor, though only an
        //   approximate windowing is likely to be used (i.e. number of iterations)
        //
        // Initialisation is different to iterations: Need a single pass to find those
        //   polygons that actually use the vertex
        vector< std::set<uint32_t> > vert_polys (V, std::set<uint32_t>());
        // For each vertex, don't just want to store the polygons within the neighbourhood;
        //   also want to store those that will be expanded from in the next iteration
        vector< vector<uint32_t> > vert_polys_to_expand (V, vector<uint32_t>());

        for (uint32_t t = 0; t != T; ++t) {
          for (uint32_t i = 0; i != 3; ++i) {
            vert_polys[(in.triangles[t])[i]].insert (t);
            vert_polys_to_expand[(in.triangles[t])[i]].push_back (t);
          }
        }
        if (progress) ++(*progress);

        // Now, we want to expand this selection outwards for each vertex
        // To do this, also want to produce a list for each polygon: containing those polygons
        //   that share a common edge (i.e. two vertices)
        vector< vector<uint32_t> > poly_neighbours (T, vector<uint32_t>());
        for (uint32_t i = 0; i != T; ++i) {
          for (uint32_t j = i+1; j != T; ++j) {
            if (in.triangles[i].shares_edge (in.triangles[j])) {
              poly_neighbours[i].push_back (j);
              poly_neighbours[j].push_back (i);

            }
          }
        }
        if (progress) ++(*progress);

        // TODO Will want to develop a better heuristic for this
        for (size_t iter = 0; iter != 8; ++iter) {
          for (uint32_t v = 0; v != V; ++v) {

            // Find polygons at the outer edge of this expanding front, and add them to the neighbourhood for this vertex
            vector<uint32_t> next_front;
            for (vector<uint32_t>::const_iterator front = vert_polys_to_expand[v].begin(); front != vert_polys_to_expand[v].end(); ++front) {
              for (vector<uint32_t>::const_iterator expansion = poly_neighbours[*front].begin(); expansion != poly_neighbours[*front].end(); ++expansion) {
                const std::set<uint32_t>::const_iterator existing = vert_polys[v].find (*expansion);
                if (existing == vert_polys[v].end()) {
                  vert_polys[v].insert (*expansion);
                  next_front.push_back (*expansion);
                }
              }
            }
            vert_polys_to_expand[v] = std::move (next_front);

          }
        }
        if (progress) ++(*progress);



        // Need to perform a first mollification pass, where the polygon normals are
        //   smoothed but the vertices are not perturbed
        // However, in order to calculate these new normals, we need to calculate new vertex positions!
        VertexList mollified_vertices;
        // Use half standard spatial factor for mollification
        // Denominator = 2(SF/2)^2
        const default_type spatial_mollification_power_multiplier = -2.0 / Math::pow2 (spatial);
        // No need to normalise the Gaussian; have to explicitly normalise afterwards
        for (uint32_t v = 0; v != V; ++v) {

          Vertex new_pos (0.0, 0.0, 0.0);
          default_type sum_weights = 0.0;

          // For now, just use every polygon as part of the estimate
          // Eventually, restrict this to some form of mesh neighbourhood
          //for (size_t i = 0; i != centroids.size(); ++i) {
          for (std::set<uint32_t>::const_iterator it = vert_polys[v].begin(); it != vert_polys[v].end(); ++it) {
            const uint32_t i = *it;
            default_type this_weight = areas[i];
            const default_type distance_sq = (centroids[i] - in.vertices[v]).squaredNorm();
            this_weight *= std::exp (distance_sq * spatial_mollification_power_multiplier);
            const Vertex prediction = centroids[i];
            new_pos += this_weight * prediction;
            sum_weights += this_weight;
          }

          new_pos *= (1.0 / sum_weights);
          mollified_vertices.push_back (new_pos);

        }
        if (progress) ++(*progress);

        // Have new vertices; compute polygon normals based on these vertices
        Mesh mollified_mesh;
        mollified_mesh.load (mollified_vertices, in.triangles);
        VertexList tangents;
        for (TriangleList::const_iterator p = mollified_mesh.triangles.begin(); p != mollified_mesh.triangles.end(); ++p)
          tangents.push_back (normal (mollified_mesh, *p));
        if (progress) ++(*progress);

        // Now perform the actual smoothing
        const default_type spatial_power_multiplier = -0.5 / Math::pow2 (spatial);
        const default_type influence_power_multiplier = -0.5 / Math::pow2 (influence);
        for (size_t v = 0; v != V; ++v) {

          Vertex new_pos (0.0, 0.0, 0.0);
          default_type sum_weights = 0.0;

          //for (size_t i = 0; i != centroids.size(); ++i) {
          for (std::set<uint32_t>::const_iterator it = vert_polys[v].begin(); it != vert_polys[v].end(); ++it) {
            const uint32_t i = *it;
            default_type this_weight = areas[i];
            const default_type distance_sq = (centroids[i] - in.vertices[v]).squaredNorm();
            this_weight *= std::exp (distance_sq * spatial_power_multiplier);
            const default_type prediction_distance = (centroids[i] - in.vertices[v]).dot (tangents[i]);
            const Vertex prediction = in.vertices[v] + (tangents[i] * prediction_distance);
            this_weight *= std::exp (Math::pow2 (prediction_distance) * influence_power_multiplier);
            new_pos += this_weight * prediction;
            sum_weights += this_weight;
          }

          new_pos *= (1.0 / sum_weights);
          out.vertices.push_back (new_pos);

        }
        if (progress) ++(*progress);

        out.triangles = in.triangles;

        // If the vertex normals were calculated previously, re-calculate them
        if (in.have_normals())
          out.calculate_normals();

      }