bool quakelib::Element<nverts>::overlaps(const Element<nverts> &block) const {
	bool					normal_a_sep, normal_b_sep;
	std::vector<Vec<3> >	normals;
	unsigned int			i, j;
	
	normals.push_back(block.normal());
	normals.push_back(normal());
	
	normal_a_sep = check_separation(normals[0], block);
	normal_b_sep = check_separation(normals[1], block);
	
	if (normal_a_sep || normal_b_sep) {
		//there is no intersection
		return false;
	} else {
		//there could be an intersection
		//test if they are co-planar
		Vec<3> cross = normal().cross(block.normal());
		std::vector<Vec<3> > edges_a;
		std::vector<Vec<3> > edges_b;
		std::vector<Vec<3> > sep_vecs;
		
		edges_a.push_back(block._vert[1] - block._vert[0]);
		edges_a.push_back(block._vert[2] - block._vert[1]);
		edges_a.push_back(block._vert[3] - block._vert[2]);
		edges_a.push_back(block._vert[0] - block._vert[3]);
		
		edges_b.push_back(_vert[1] - _vert[0]);
		edges_b.push_back(_vert[2] - _vert[1]);
		edges_b.push_back(_vert[3] - _vert[2]);
		edges_b.push_back(_vert[0] - _vert[3]);
		
		if (cross.mag() > 0) {
			//they are not co-planar
			for (i=0;i<edges_a.size();i++) {
				for (j=0;j<edges_b.size();j++) {
					sep_vecs.push_back(edges_a[i].cross(edges_b[j]).unit_vector());
				}
			}
		} else {
			//they are coplanar. the case where they could be parallel is tested with the normal separations.
			//this is now the 2d case.
			for (i=0;i<edges_a.size();i++) {
				sep_vecs.push_back(normals[0].cross(edges_a[i]).unit_vector());
			}
			for (i=0;i<edges_b.size();i++) {
				sep_vecs.push_back(normals[0].cross(edges_b[i]).unit_vector());
			}
		}
		
		for (i=0; i < sep_vecs.size(); i++) {
			// if any of the results are seperated the elements don't intersect
			if (check_separation(sep_vecs[0], block)) {
				return false;
			}
		}
		
		return true;
	}
}
Exemplo n.º 2
0
Quat TangentSpace::expMap(const Vec  &p)
{
    float theta = p.mag();
    //float theta = Quat::spherical_distance(centre, p);

    float convFactor = 0.0;
    if(fabs(theta) < 0.00001)
        convFactor = 0.0;
    else
        convFactor = sin(theta)/theta;

    Quat p1;
    //Quat p2;

    p1[0] = cos (theta);
    p1[1] = p[0]*convFactor;
    p1[2] = p[1]*convFactor;
    p1[3] = p[2]*convFactor;

    p1 = p1*centre;

    //p2[0] = p1[0] + coordAxes[0][0];
    //p2[1] = p1[1] + coordAxes[0][1];
    //p2[2] = p1[2] + coordAxes[0][2];
    //p2[3] = p1[3] + coordAxes[0][3];

    //p2[0]  = p1[0]*coordAxes[0][0] + p1[1]*coordAxes[1][0];
    //p2[0] += p1[2]*coordAxes[2][0] + p1[3]*coordAxes[3][0];

    //p2[1]  = p1[0]*coordAxes[0][1] + p1[1]*coordAxes[1][1];
    //p2[1] += p1[2]*coordAxes[2][1] + p1[3]*coordAxes[3][1];

    //p2[2]  = p1[0]*coordAxes[0][2] + p1[1]*coordAxes[1][2];
    //p2[2] += p1[2]*coordAxes[2][2] + p1[3]*coordAxes[3][2];

    //p2[3]  = p1[0]*coordAxes[0][3] + p1[1]*coordAxes[1][3];
    //p2[3] += p1[2]*coordAxes[2][3] + p1[3]*coordAxes[3][3];

    return p1;
}
Exemplo n.º 3
0
/** Phong lighting model
 ** @param pt intersection point
 ** @param n normal of pt
 ** @param light pointer to the light source
 ** @param obj pointer to the object
 ** @param ray ray
 ** @return color calculated from local shading using phong model
 **/
Vec phongModel(Vec pt, Vec n, Light* light, Shape* obj, Ray ray) {
  float t;
  Vec v = ray.getOrig() - pt; v = v.normalize(); // vector to viewer
  Vec l = light->pos - pt;
  float dis = l.mag(); // distance to light source
  l = l.normalize(); // vector to light source
  Vec ir = n * (2 * n.dot(l)) - l; ir = ir.normalize(); // vector of ideal reflector
  Vec intensity = light->intensity; // light intensity
  Ray shadowRay(pt, l, 0, 9999, ShadowRay);  // shadow ray to the light source
  float f = light->attenFac(dis); // attentuation factor
  Pigment p = obj->getPigment();
  Vec obj_color; // object color
  float scalar; int tmp;
  if (p.type == SOLID) {
    obj_color = p.c1;
  } else if (p.type == CHECKER) {
    scalar = p.width;
    tmp = (int)(pt.x/scalar) + (int)(pt.y/scalar) + (int)(pt.z/scalar);
    if (tmp % 2 == 0) obj_color = p.c1;
    else obj_color = p.c2;
  } else if (p.type == TEXTURE) {
    if (obj->getType() == sphere)
      obj_color = sphereMapping(pt, n, p);
  }
  
  // get the surface parameters
  SurFinish appearance = obj->getSurFin();
  float Ka = appearance.ambient; // ambient coefficient
  float Kd = appearance.diffuse; // diffuse coefficient
  float Ks = appearance.specular; // specular coefficient
  float shininess = appearance.shininess;
  
  // for each object in the scene, see if is blocks the light
  if (light->type != ambient) {
    for (ShapeIter its = scene.shapes.begin(); its != scene.shapes.end(); its++) {
      if ((*its) == obj) continue;
      
      if ((*its)->getType() == sphere) {
        Sphere *shape = dynamic_cast<Sphere*>(*its);
        if (shape->intersect(shadowRay, t) && t < dis)
          return black;
      } else if((*its)->getType() == polyhedron){
        Polyhedron *shape = dynamic_cast<Polyhedron*>(*its);
        if (shape->intersect(shadowRay, t) && t < dis) {
          return black;
        }
      } else if((*its)->getType() == triangleMesh){
        TriangleMesh *shape = dynamic_cast<TriangleMesh*>(*its);
        if (shape->intersect(shadowRay, t) && shadowRay.calcDest(t).mag() < dis)
          return black;
      }
    }
  }
  
  Vec diffuse(0.0, 0.0, 0.0);
  Vec specular(0.0, 0.0, 0.0);
  // if the light is casted from front
  if (n.dot(l) > 0) {
    diffuse = intensity * (Kd * n.dot(l) * f);
    specular = white * (Ks * pow(v.dot(ir),shininess) * f);
    // update light color
    intensity.x = (light->type != ambient) ? diffuse.x * obj_color.x + specular.x : obj_color.x * Ka;
    intensity.y = (light->type != ambient) ? diffuse.y * obj_color.y + specular.y : obj_color.y * Ka;
    intensity.z = (light->type != ambient) ? diffuse.z * obj_color.z + specular.z : obj_color.z * Ka;
  } // if the light is casted from behind
  else {
    intensity.x = (light->type != ambient) ? black.x : obj_color.x * Ka;
    intensity.y = (light->type != ambient) ? black.y : obj_color.y * Ka;
    intensity.z = (light->type != ambient) ? black.z : obj_color.z * Ka;
  }
  
  return intensity;
}