Пример #1
0
void predg3f_param(struct predgparam3f_s *pp, const struct predg3f_s *g)
{
    struct vec3f_s p, q, u, v;
    int za, zb;

    predg3f_pquv(&p, &q, &u, &v, g);

    pp->a = vec3f_len(&p) * vec3f_len(&q);
    pp->b = vec3f_len(&u) * vec3f_len(&v);
    pp->c = g->c;

    za = almost_zero(pp->a);
    zb = almost_zero(pp->b);

    if (!za || !zb)
        predg3f_eigen(&pp->q, 0, g);
    else
        mat44f_zero(&pp->q);

    if (!za && !zb)
        pp->t = ellipsoidal_param_case(pp->a, pp->b, pp->c);
    else if (!za || !zb)
        pp->t = toroidal_param_case(pp->a, pp->b, pp->c);
    else
        pp->t = inproper_param_case();
}
Пример #2
0
    virtual double intersect(Ray ray) const {
        Vector edge1 = vertices[1] - vertices[0];
        Vector edge2 = vertices[3] - vertices[0];
        //Begin calculating determinant - also used to calculate u parameter
        Vector P = vec(ray.direction, edge2);
        double det = dot(P, edge1);
        double inv_det = 1.0 / det;
        Vector move = ray.start - vertices[0];

        double u = dot(move, P) * inv_det;
        Vector Q = vec(move, edge1);
        double v = dot(ray.direction, Q) * inv_det;
        if(almost_zero(det) || u < -EPS || u > 1.0 + EPS || v < -EPS || u + v  > 1.0 + EPS) {
            Vector edge2 = vertices[1] - vertices[2];
            Vector edge1 = vertices[3] - vertices[2];
            //Begin calculating determinant - also used to calculate u parameter
            Vector P = vec(ray.direction, edge2);
            double det = dot(P, edge1);
            double inv_det = 1.0 / det;
            Vector move = ray.start - vertices[2];

            double u = dot(move, P) * inv_det;
            Vector Q = vec(move, edge1);
            double v = dot(ray.direction, Q) * inv_det;
            if(almost_zero(det) || u < -EPS || u > 1.0 + EPS || v < -EPS || u + v  > 1.0 + EPS) {
                return INFINITY;
            }
            double t = dot(edge2, Q) * inv_det;
            return t;
        }
        double t = dot(edge2, Q) * inv_det;
        return t;
    }
Пример #3
0
static void calc_r(struct vec3f_s *r, const struct vec3f_s *v)
{
    if (!almost_zero(v->x))
        vec3f_set(r, -v->y, v->x, v->z); /* take x-y plane */
    else if (!almost_zero(v->y))
        vec3f_set(r, v->x, -v->z, v->y); /* take y-z plane */
    else
        vec3f_set(r, v->z, v->y, -v->x); /* take z-x plane */
}
Пример #4
0
static void predgparam3f_eval_a_torus(double *t12, double *t23, double *t31, double *t0, const struct predgparam3f_s *pp, double u, double v, int component)
{
    double alpha = u * 2 * PI;
    double beta = v * 2 * PI;

    assert(component == 0);

    if (almost_zero(pp->b))
    {
        double rp = sqrt((pp->a + pp->c) / (2 * pp->a));
        double rm = sqrt((pp->a - pp->c) / (2 * pp->a));

        *t12 = rp * cos(alpha);
        *t23 = rp * sin(alpha);
        *t31 = rm * cos(beta);
        *t0 = rm * sin(beta);
    }
    else
    {
        double rp = sqrt((pp->b + pp->c) / (2 * pp->b));
        double rm = sqrt((pp->b - pp->c) / (2 * pp->b));

        *t12 = rp * cos(alpha);
        *t23 = rm * sin(alpha);
        *t31 = rp * cos(beta);
        *t0 = rm * sin(beta);
    }
}
	void main_shadow(void *arg, const color & Kt,
		const scalar &refraction_thickness,
		const scalar &cutoff_threshold)
	{
		// the light has falled off to almost black, 
		// no need to trace
		if (almost_black(Cl))
		{
			return;
		}

		scalar transp = average(&Kt);

		// we are less transparent if the surface is treated as two sided
		if (refraction_thickness > 0.0f)
		{
			transp = transp * transp;
		}

		// the same with opaque shader
		if (almost_zero(transp, cutoff_threshold))
		{
			Cl = color(0.0f);
			Ol = color(1.0f);
			return;
		}

		// reduce the length of ray direction to limit the maximum distance
		Cl = trace_shadow(P, I - (P - E), Cl) * transp;
		Ol = (1.0f - transp);
	}
Пример #6
0
bool intersectAabb(const Aabb& box, const Ray& ray, floating& a, floating& b) {
    const Point  origin = ray.origin();
    const Vector dir = ray.dir();

    a = std::numeric_limits<floating>::min();
    b = std::numeric_limits<floating>::max();

    for (uint8_t i = 0; i < 3; ++i) {
        if (almost_zero(dir[i])) {
            if (origin[i] < box.m_p1[i] || origin[i] > box.m_p2[i]) {
                return false;
            }

            continue;
        }

        floating idir = 1.0 / dir[i];
        floating at = (box.m_p1[i] - origin[i]) * idir;
        floating bt = (box.m_p2[i] - origin[i]) * idir;

        if (at > bt)
            idir = at, at = bt, bt = idir;
        if (at > a)
            a = at;
        if (bt < b)
            b = bt;
        if (b < 0 || a > b)
            return false;
    }

    return true;
}
Пример #7
0
enum predgtype3f_e predg3f_type(const struct predg3f_s *g)
{
    struct vec3f_s p, q, u, v;
    double a, b;
    int za, zb;

    predg3f_pquv(&p, &q, &u, &v, g);

    a = vec3f_len(&p) * vec3f_len(&q);
    b = vec3f_len(&u) * vec3f_len(&v);
    za = almost_zero(a);
    zb = almost_zero(b);

    if (!za && !zb)
        return predgtype3f_ellipsoidal;
    else if (!za || !zb)
        return predgtype3f_toroidal;
    else
        return predgtype3f_inproper;
}
Пример #8
0
static enum predgparamtype3f_e toroidal_param_case(double a, double b, double c)
{
    if (almost_zero(a) && !almost_zero(b))
    {
        if (c >= -b && c <= b)
            return predgparamtype3f_a_torus;
        else
            return predgparamtype3f_an_empty_set;
    }

    if (!almost_zero(a) && almost_zero(b))
    {
        if (c >= -a && c <= a)
            return predgparamtype3f_a_torus;
        else
            return predgparamtype3f_an_empty_set;
    }

    assert(0);
    return predgparamtype3f_an_empty_set;
}
Пример #9
0
 void enchance_balance() {
     double factor = -INFINITY;
     for (int x = 0; x < width; ++x) {
         for (int y = 0; y < height; ++y) {
             for (int comp = 0; comp < 3; ++comp) {
                 double cur = buffer[x][y].coord[comp];
                 if (cur > factor) {
                     factor = cur;
                 }
             }
         }
     }
     if (almost_zero(factor)) {
         return;
     }
     for (int x = 0; x < width; ++x) {
         for (int y = 0; y < height; ++y) {
             buffer[x][y] /= factor;
         }
     }
 };
Пример #10
0
static int almost_equal(double x, double y)
{
    return almost_zero(x - y);
}
Пример #11
0
static int almost_zero_vector(const struct vec3f_s *v)
{
    return almost_zero(v->x) && almost_zero(v->y) && almost_zero(v->z);
}