예제 #1
0
파일: mesh.cpp 프로젝트: 0ctobyte/cs488
NonhierSphere Mesh::getBoundingBall(const std::vector<Point3D>& verts) const
{
  Point3D C = verts[0] + 0.5*(verts[1]-verts[0]);
  double radius = (verts[1] - verts[0]).length() / 2.0;

  // This is the bouncing ball algorithm. Take any two points and construct the sphere's center
  // at the center point of the line between the two vertices and raidus half the distance
  // between the two vertices
  // Then loop through each vertex. If it is outside the sphere then move the sphere's center
  // a little bit towards the point while growing the radius as well so that the point is now inside 
  // the sphere. Keep doing this until there are no vertices outside the sphere
  for(bool outsider = true; outsider == true;)
  {
    outsider = false;
    for(auto v : verts)
    {
      double length = (v-C).length();
      if(length > radius)
      {
        double diff = length - radius;
        double delta = diff / length;
        C = C + (0.5 * delta)*(v-C);
        radius = radius + (0.5 * diff);
        outsider = true;
      }
    }
  }

  return NonhierSphere(C, radius);
}
예제 #2
0
Mesh::Mesh(const std::vector<Point3D>& verts,
           const std::vector< std::vector<int> >& faces,
           const std::vector<Vector3D>& upVectors)
  : m_verts(verts),
    m_polygons(),
    m_boundingSphere(Point3D(0.0, 0.0, 0.0), 0.0)
{
  for (std::vector<Face>::const_iterator it = faces.begin(); it != faces.end(); it++) {
    Vector3D v1 = verts[it->at(0)] - verts[it->at(1)];
    Vector3D v2 = verts[it->at(2)] - verts[it->at(1)];
    Vector3D normal = v2.cross(v1); 
    
    std::vector<Point3D> vertices;
    for (Face::const_iterator it2 = it->begin(); it2 != it->end(); it2++) {
      vertices.push_back(verts[*it2]);
    }

    // Just put something on the plane for the up vector.
    m_polygons.push_back(Polygon(vertices, normal, v1));
  }

  // If we're given up vectors add them to the polygons.
  if (!upVectors.empty()) {
    std::vector<Polygon>::iterator p = m_polygons.begin();
    std::vector<Vector3D>::const_iterator it = upVectors.begin();
    for ( ; p != m_polygons.end() && it != upVectors.end(); it++, p++) {
      p->set_upVector(*it);
    }
  }

  // Now create our bounding sphere
  // Idea is to find max distance between two points.
  // TODO: I don't think this is right....
  double maxDist = 0.0;
  Point3D point1, point2;
  for (std::vector<Point3D>::const_iterator p1 = verts.begin(); p1 != verts.end(); p1++) {
    for (std::vector<Point3D>::const_iterator p2 = p1 + 1; p2 != verts.end(); p2++) {
      double dist = (*p1 - *p2).length();
      if (dist > maxDist) {
        maxDist = dist;
        point1 = *p1;
        point2 = *p2;
      }
    }
  }

  double radius = maxDist / 2.0;
  Point3D center = (1.0/2.0) * (point1 + point2);
  m_boundingSphere = NonhierSphere(center, radius);
}
예제 #3
0
SphericalLight::SphericalLight(glm::vec3 position, glm::vec3 color, double radius) :
AreaLight(position, color),
_radius(radius)
{
	m_primitive = NonhierSphere(position, _radius);
}