BOOL linesegment_triangle(const LLVector3 &point_a, const LLVector3 &point_b, const LLVector3 &point_0, const LLVector3 &point_1, const LLVector3 &point_2, LLVector3 &intersection, LLVector3 &intersection_normal) { LLVector3 ray_direction = point_b - point_a; F32 segment_length = ray_direction.normVec(); if (ray_triangle(point_a, ray_direction, point_0, point_1, point_2, intersection, intersection_normal)) { if (segment_length >= (point_a - intersection).magVec()) { return TRUE; } } return FALSE; }
BOOL ray_pyramid(const LLVector3 &ray_point, const LLVector3 &ray_direction, const LLVector3 &p_center, const LLVector3 &p_scale, const LLQuaternion &p_rotation, LLVector3 &intersection, LLVector3 &intersection_normal) { // center of mass of pyramid is located 1/4 its height from the base F32 x = 0.5f * p_scale.mV[VX]; F32 y = 0.5f * p_scale.mV[VY]; F32 z = 0.25f * p_scale.mV[VZ]; LLVector3 point0(0.0f, 0.0f, p_scale.mV[VZ] - z); LLVector3 point1( x, y, -z); LLVector3 point2(-x, y, -z); LLVector3 point3(-x, -y, -z); LLVector3 point4( x, -y, -z); // transform these points into absolute frame point0 = (point0 * p_rotation) + p_center; point1 = (point1 * p_rotation) + p_center; point2 = (point2 * p_rotation) + p_center; point3 = (point3 * p_rotation) + p_center; point4 = (point4 * p_rotation) + p_center; // test ray intersection for each face BOOL b_hit = FALSE; LLVector3 face_intersection, face_normal; F32 distance_squared = 1.0e12f; F32 temp; // face 0 if (ray_direction * ( (point1 - point4) % (point0 - point4)) < 0.0f && ray_triangle(ray_point, ray_direction, point4, point1, point0, intersection, intersection_normal)) { distance_squared = (ray_point - intersection).magVecSquared(); b_hit = TRUE; } // face 1 if (ray_direction * ( (point2 - point1) % (point0 - point1)) < 0.0f && ray_triangle(ray_point, ray_direction, point1, point2, point0, face_intersection, face_normal)) { if (TRUE == b_hit) { temp = (ray_point - face_intersection).magVecSquared(); if (temp < distance_squared) { distance_squared = temp; intersection = face_intersection; intersection_normal = face_normal; } } else { distance_squared = (ray_point - face_intersection).magVecSquared(); intersection = face_intersection; intersection_normal = face_normal; b_hit = TRUE; } } // face 2 if (ray_direction * ( (point3 - point2) % (point0 - point2)) < 0.0f && ray_triangle(ray_point, ray_direction, point2, point3, point0, face_intersection, face_normal)) { if (TRUE == b_hit) { temp = (ray_point - face_intersection).magVecSquared(); if (temp < distance_squared) { distance_squared = temp; intersection = face_intersection; intersection_normal = face_normal; } } else { distance_squared = (ray_point - face_intersection).magVecSquared(); intersection = face_intersection; intersection_normal = face_normal; b_hit = TRUE; } } // face 3 if (ray_direction * ( (point4 - point3) % (point0 - point3)) < 0.0f && ray_triangle(ray_point, ray_direction, point3, point4, point0, face_intersection, face_normal)) { if (TRUE == b_hit) { temp = (ray_point - face_intersection).magVecSquared(); if (temp < distance_squared) { distance_squared = temp; intersection = face_intersection; intersection_normal = face_normal; } } else { distance_squared = (ray_point - face_intersection).magVecSquared(); intersection = face_intersection; intersection_normal = face_normal; b_hit = TRUE; } } // face 4 if (ray_direction * ( (point3 - point4) % (point2 - point4)) < 0.0f && ray_quadrangle(ray_point, ray_direction, point4, point3, point2, face_intersection, face_normal)) { if (TRUE == b_hit) { temp = (ray_point - face_intersection).magVecSquared(); if (temp < distance_squared) { intersection = face_intersection; intersection_normal = face_normal; } } else { intersection = face_intersection; intersection_normal = face_normal; b_hit = TRUE; } } return b_hit; }
BOOL ray_tetrahedron(const LLVector3 &ray_point, const LLVector3 &ray_direction, const LLVector3 &t_center, const LLVector3 &t_scale, const LLQuaternion &t_rotation, LLVector3 &intersection, LLVector3 &intersection_normal) { F32 a = 0.5f * F_SQRT3; // height of unit triangle F32 b = 1.0f / F_SQRT3; // distance of center of unit triangle to each point F32 c = F_SQRT2 / F_SQRT3; // height of unit tetrahedron F32 d = 0.5f * F_SQRT3 / F_SQRT2; // distance of center of tetrahedron to each point // if we want the tetrahedron to have unit height (c = 1.0) then we need to divide // each constant by hieght of a unit tetrahedron F32 oo_c = 1.0f / c; a = a * oo_c; b = b * oo_c; c = 1.0f; d = d * oo_c; F32 e = 0.5f * oo_c; LLVector3 point0( 0.0f, 0.0f, t_scale.mV[VZ] * d); LLVector3 point1(t_scale.mV[VX] * b, 0.0f, t_scale.mV[VZ] * (d-c)); LLVector3 point2(t_scale.mV[VX] * (b-a), e * t_scale.mV[VY], t_scale.mV[VZ] * (d-c)); LLVector3 point3(t_scale.mV[VX] * (b-a), -e * t_scale.mV[VY], t_scale.mV[VZ] * (d-c)); // transform these points into absolute frame point0 = (point0 * t_rotation) + t_center; point1 = (point1 * t_rotation) + t_center; point2 = (point2 * t_rotation) + t_center; point3 = (point3 * t_rotation) + t_center; // test ray intersection for each face BOOL b_hit = FALSE; LLVector3 face_intersection, face_normal; F32 distance_squared = 1.0e12f; F32 temp; // face 0 if (ray_direction * ( (point2 - point1) % (point0 - point1)) < 0.0f && ray_triangle(ray_point, ray_direction, point1, point2, point0, intersection, intersection_normal)) { distance_squared = (ray_point - intersection).magVecSquared(); b_hit = TRUE; } // face 1 if (ray_direction * ( (point3 - point2) % (point0 - point2)) < 0.0f && ray_triangle(ray_point, ray_direction, point2, point3, point0, face_intersection, face_normal)) { if (TRUE == b_hit) { temp = (ray_point - face_intersection).magVecSquared(); if (temp < distance_squared) { distance_squared = temp; intersection = face_intersection; intersection_normal = face_normal; } } else { distance_squared = (ray_point - face_intersection).magVecSquared(); intersection = face_intersection; intersection_normal = face_normal; b_hit = TRUE; } } // face 2 if (ray_direction * ( (point1 - point3) % (point0 - point3)) < 0.0f && ray_triangle(ray_point, ray_direction, point3, point1, point0, face_intersection, face_normal)) { if (TRUE == b_hit) { temp = (ray_point - face_intersection).magVecSquared(); if (temp < distance_squared) { distance_squared = temp; intersection = face_intersection; intersection_normal = face_normal; } } else { distance_squared = (ray_point - face_intersection).magVecSquared(); intersection = face_intersection; intersection_normal = face_normal; b_hit = TRUE; } } // face 3 if (ray_direction * ( (point2 - point3) % (point1 - point3)) < 0.0f && ray_triangle(ray_point, ray_direction, point3, point2, point1, face_intersection, face_normal)) { if (TRUE == b_hit) { temp = (ray_point - face_intersection).magVecSquared(); if (temp < distance_squared) { intersection = face_intersection; intersection_normal = face_normal; } } else { intersection = face_intersection; intersection_normal = face_normal; b_hit = TRUE; } } return b_hit; }
BOOL ray_prism(const LLVector3 &ray_point, const LLVector3 &ray_direction, const LLVector3 &prism_center, const LLVector3 &prism_scale, const LLQuaternion &prism_rotation, LLVector3 &intersection, LLVector3 &intersection_normal) { // (0) Z // /| \ . // (1)| \ /|\ _.Y // | \ \ | /| // | |\ \ | / // | | \(0)\ | / // | | \ \ |/ // | | \ \ (*)----> X // |(3)---\---(2) // |/ \ / // (4)-------(5) // need to calculate the points of the prism so we can run ray tests with each face F32 x = prism_scale.mV[VX]; F32 y = prism_scale.mV[VY]; F32 z = prism_scale.mV[VZ]; F32 tx = x * 2.0f / 3.0f; F32 ty = y * 0.5f; F32 tz = z * 2.0f / 3.0f; LLVector3 point0(tx-x, ty, tz); LLVector3 point1(tx-x, -ty, tz); LLVector3 point2(tx, ty, tz-z); LLVector3 point3(tx-x, ty, tz-z); LLVector3 point4(tx-x, -ty, tz-z); LLVector3 point5(tx, -ty, tz-z); // transform these points into absolute frame point0 = (point0 * prism_rotation) + prism_center; point1 = (point1 * prism_rotation) + prism_center; point2 = (point2 * prism_rotation) + prism_center; point3 = (point3 * prism_rotation) + prism_center; point4 = (point4 * prism_rotation) + prism_center; point5 = (point5 * prism_rotation) + prism_center; // test ray intersection for each face BOOL b_hit = FALSE; LLVector3 face_intersection, face_normal; F32 distance_squared = 0.0f; F32 temp; // face 0 if (ray_direction * ( (point0 - point2) % (point5 - point2)) < 0.0f && ray_quadrangle(ray_point, ray_direction, point5, point2, point0, intersection, intersection_normal)) { distance_squared = (ray_point - intersection).magVecSquared(); b_hit = TRUE; } // face 1 if (ray_direction * ( (point0 - point3) % (point2 - point3)) < 0.0f && ray_triangle(ray_point, ray_direction, point2, point3, point0, face_intersection, face_normal)) { if (TRUE == b_hit) { temp = (ray_point - face_intersection).magVecSquared(); if (temp < distance_squared) { distance_squared = temp; intersection = face_intersection; intersection_normal = face_normal; } } else { distance_squared = (ray_point - face_intersection).magVecSquared(); intersection = face_intersection; intersection_normal = face_normal; b_hit = TRUE; } } // face 2 if (ray_direction * ( (point1 - point4) % (point3 - point4)) < 0.0f && ray_quadrangle(ray_point, ray_direction, point3, point4, point1, face_intersection, face_normal)) { if (TRUE == b_hit) { temp = (ray_point - face_intersection).magVecSquared(); if (temp < distance_squared) { distance_squared = temp; intersection = face_intersection; intersection_normal = face_normal; } } else { distance_squared = (ray_point - face_intersection).magVecSquared(); intersection = face_intersection; intersection_normal = face_normal; b_hit = TRUE; } } // face 3 if (ray_direction * ( (point5 - point4) % (point1 - point4)) < 0.0f && ray_triangle(ray_point, ray_direction, point1, point4, point5, face_intersection, face_normal)) { if (TRUE == b_hit) { temp = (ray_point - face_intersection).magVecSquared(); if (temp < distance_squared) { distance_squared = temp; intersection = face_intersection; intersection_normal = face_normal; } } else { distance_squared = (ray_point - face_intersection).magVecSquared(); intersection = face_intersection; intersection_normal = face_normal; b_hit = TRUE; } } // face 4 if (ray_direction * ( (point4 - point5) % (point2 - point5)) < 0.0f && ray_quadrangle(ray_point, ray_direction, point2, point5, point4, face_intersection, face_normal)) { if (TRUE == b_hit) { temp = (ray_point - face_intersection).magVecSquared(); if (temp < distance_squared) { distance_squared = temp; intersection = face_intersection; intersection_normal = face_normal; } } else { distance_squared = (ray_point - face_intersection).magVecSquared(); intersection = face_intersection; intersection_normal = face_normal; b_hit = TRUE; } } return b_hit; }
/* bool BBox::intersect_triangle_left(ISectTri &tri, double plane, int axis) { if (tri.point0[axis]<=plane) return true; if (tri.point1[axis]<=plane) return true; if (tri.point2[axis]<=plane) return true; return false; } bool BBox::intersect_triangle_right(ISectTri &tri, double plane, int axis) { if (tri.point0[axis]>=plane) return true; if (tri.point1[axis]>=plane) return true; if (tri.point2[axis]>=plane) return true; return false; } */ bool BBox::intersect_triangle(ISectTri &tri) { Vec3f tmin_corner = min_corner - Vec3f(f_eps); Vec3f tmax_corner = max_corner + Vec3f(f_eps); // Vertex in box test: // If any of the triangle vertices are inside the box then // the triangle intersects the box if (in_interval(tmin_corner[0],tri.point0[0],tmax_corner[0]) && in_interval(tmin_corner[1],tri.point0[1],tmax_corner[1]) && in_interval(tmin_corner[2],tri.point0[2],tmax_corner[2])) return true; if (in_interval(tmin_corner[0],tri.point1[0],tmax_corner[0]) && in_interval(tmin_corner[1],tri.point1[1],tmax_corner[1]) && in_interval(tmin_corner[2],tri.point1[2],tmax_corner[2])) return true; if (in_interval(tmin_corner[0],tri.point2[0],tmax_corner[0]) && in_interval(tmin_corner[1],tri.point2[1],tmax_corner[1]) && in_interval(tmin_corner[2],tri.point2[2],tmax_corner[2])) return true; // Triangle outside box test: // If all of the triangle vertices are outside one of the planes // defining the sides of the box then the triangle can be trivially // rejected as outside int i; for(i=0;i<3;i++) if (tri.point0[i]<tmin_corner[i] && tri.point1[i]<tmin_corner[i] && tri.point2[i]<tmin_corner[i]) return false; for(i=0;i<3;i++) if (tri.point0[i]>tmax_corner[i] && tri.point1[i]>tmax_corner[i] && tri.point2[i]>tmax_corner[i]) return false; // Triangle edges - box intersection test if (intersect_edge_box(tri.point0, tri.point1)) return true; if (intersect_edge_box(tri.point1, tri.point2)) return true; if (intersect_edge_box(tri.point2, tri.point0)) return true; // Box diagonal - triangle intersection test, 4 tests in total Vec3f corner0; Vec3f corner1; Vec3f tmin_corner_e = tmin_corner; Vec3f tmax_corner_e = tmax_corner; corner0.set(tmin_corner_e[0],tmin_corner_e[1],tmin_corner_e[2]); corner1.set(tmax_corner_e[0],tmax_corner_e[1],tmax_corner_e[2]); if (ray_triangle(corner0, corner1, tri)) return true; corner0.set(tmax_corner_e[0],tmin_corner_e[1],tmin_corner_e[2]); corner1.set(tmin_corner_e[0],tmax_corner_e[1],tmax_corner_e[2]); if (ray_triangle(corner0, corner1, tri)) return true; corner0.set(tmin_corner_e[0],tmax_corner_e[1],tmin_corner_e[2]); corner1.set(tmax_corner_e[0],tmin_corner_e[1],tmax_corner_e[2]); if (ray_triangle(corner0, corner1, tri)) return true; corner0.set(tmin_corner_e[0],tmin_corner_e[1],tmax_corner_e[2]); corner1.set(tmax_corner_e[0],tmax_corner_e[1],tmin_corner_e[2]); if (ray_triangle(corner0, corner1, tri)) return true; // None succeded return false; }
void render_vertex_colors() { printf ( "_\t_\tRENDERING VERTEX COLORS_\t_\t_\t_\t_\n"); for(size_t i = 0; i < verts.size(); ++i )// each vertex { vertex_t&v = verts[i]; for(size_t j = 0; j < lights.size(); ++j )// each light { // int blocked = 0; const light_t&L = lights[j]; if( L.dont_bake ) continue; vec3 start, dir; if( L.type == light_t::SUN ){ start = v.pos;//inset;//+L.dir*.000001; dir = L.dir*2048.f; }else{ start = L.pos; dir = (v.pos - L.pos ); } //early if ( vdot ( L.pos - v.pos, v.normal ) <= 0.f )continue; //test triangles (TODO/NOTE : DONT FACE CULL ) int blocked=0; //ERROR LAYS HERE!!! NOT IN TANGENT for(size_t k = 0; k < polys.size()&& !blocked; ++k )// each polygon { const poly_t&p = polys[k]; //is this vertex used in the poly? // for (int pi = 0; pi < 3 ; ++pi) // alt, use some margin // if( (int)i == (int)p.index[pi] ) // continue; blocked |= ray_triangle( start, dir, verts[p.index[0]].pos, verts[p.index[1]].pos, verts[p.index[2]].pos); } if( !blocked ) { //todo inverse linear / square vec3 d,dN; float f,dp; if( L.type == light_t::SUN ){ dN = L.dir; f = 1.f; }else { d = L.pos - v.pos; dN=vnormal( d ); f = 1.-fmin(1.f, vlen(d) / L.dist ); } for( int k = 0; k<3; ++k ) { dp = fmax(0.f,vdot( v.basis[k], dN ) ); v.basis_color[k]+=L.rgb*f*dp; } //float f = 1.-fmin(1.f, vlen(d) / L.dist ); //float f = 1.f/(1.f + vdot( d, d ) );//inv square //not as prominent but sphere like //float f = 1.f-1.f/(1.f + fmax(0.f,L.dist-vlen( d ) ) );//inv } } //printf ("C = %.2f,%.2f,%.2f\n", v.init_rgb.x, v.init_rgb.y, v.init_rgb.z); } }