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; } }
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; }
/** 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; }