Пример #1
0
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;
}
Пример #2
0
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;
}
Пример #3
0
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;
}
Пример #4
0
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;
}
Пример #5
0
Файл: BBox.cpp Проект: janba/GEL
/*

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;
  }
Пример #6
0
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);
	}
}