Пример #1
0
void		intersect_scene(t_env *e)
{
	int			inter;
	double		t;
	size_t		prim;
	size_t		object;

	e->t = INFINITY;
	e->p_hit = NULL;
	e->o_hit = NULL;
	e->hit_type = 0;
	prim = e->prims;
	object = e->objects;
	while (prim--)
		if ((inter = intersect_prim(e, &e->ray, prim, &t)) && t < e->t)
		{
			e->ray.inter = inter;
			e->t = t;
			e->p_hit = e->prim[prim];
			e->hit_type = PRIMITIVE;
		}
	while (object--)
		if (intersect_box(&e->ray, e->object[object]->box))
			intersect_object(e, e->object[object], &t);
}
Пример #2
0
GimpRGB
get_ray_color_box (GimpVector3 *pos)
{
  GimpVector3        lvp, ldir, vp, p, dir, ns, nn;
  GimpRGB             color, color2;
  gfloat             m[16];
  gint               i;
  FaceIntersectInfo  face_intersect[2];

  color = background;
  vp = mapvals.viewpoint;
  p = *pos;

  /* Translate viewpoint so that the box has its origin */
  /* at its lower left corner.                          */
  /* ================================================== */

  vp.x = vp.x - mapvals.position.x;
  vp.y = vp.y - mapvals.position.y;
  vp.z = vp.z - mapvals.position.z;

  p.x = p.x - mapvals.position.x;
  p.y = p.y - mapvals.position.y;
  p.z = p.z - mapvals.position.z;

  /* Compute direction */
  /* ================= */

  gimp_vector3_sub (&dir, &p, &vp);
  gimp_vector3_normalize (&dir);

  /* Compute inverse of rotation matrix and apply it to   */
  /* the viewpoint and direction. This transforms the     */
  /* observer into the local coordinate system of the box */
  /* ==================================================== */

  memcpy (m, rotmat, sizeof (gfloat) * 16);

  transpose_mat (m);

  vecmulmat (&lvp, &vp, m);
  vecmulmat (&ldir, &dir, m);

  /* Ok. Now the observer is in the space where the box is located */
  /* with its lower left corner at the origin and its axis aligned */
  /* to the cartesian basis. Check if the transformed ray hits it. */
  /* ============================================================= */

  face_intersect[0].t = 1000000.0;
  face_intersect[1].t = 1000000.0;

  if (intersect_box (mapvals.scale, lvp, ldir, face_intersect) == TRUE)
    {
      /* We've hit the box. Transform the hit points and */
      /* normals back into the world coordinate system   */
      /* =============================================== */

      for (i = 0; i < 2; i++)
        {
          vecmulmat (&ns, &face_intersect[i].s, rotmat);
          vecmulmat (&nn, &face_intersect[i].n, rotmat);

          ns.x = ns.x + mapvals.position.x;
          ns.y = ns.y + mapvals.position.y;
          ns.z = ns.z + mapvals.position.z;

          face_intersect[i].s = ns;
          face_intersect[i].n = nn;
        }

      color = get_box_image_color (face_intersect[0].face,
				   face_intersect[0].u,
				   face_intersect[0].v);

      /* Check for total transparency... */
      /* =============================== */

      if (color.a < 1.0)
        {
          /* Hey, we can see  through here!      */
          /* Lets see what's on the other side.. */
          /* =================================== */

          color = phong_shade (&face_intersect[0].s,
			       &mapvals.viewpoint,
			       &face_intersect[0].n,
			       &mapvals.lightsource.position,
			       &color,
			       &mapvals.lightsource.color,
			       mapvals.lightsource.type);

          gimp_rgb_clamp (&color);

          color2 = get_box_image_color (face_intersect[1].face,
					face_intersect[1].u,
					face_intersect[1].v);

          /* Make the normal point inwards */
          /* ============================= */

          gimp_vector3_mul (&face_intersect[1].n, -1.0);

          color2 = phong_shade (&face_intersect[1].s,
				&mapvals.viewpoint,
				&face_intersect[1].n,
				&mapvals.lightsource.position,
				&color2,
				&mapvals.lightsource.color,
				mapvals.lightsource.type);

          gimp_rgb_clamp (&color2);

          if (mapvals.transparent_background == FALSE && color2.a < 1.0)
            {
	      gimp_rgb_composite (&color2, &background,
				  GIMP_RGB_COMPOSITE_BEHIND);
	    }

          /* Compute a mix of the first and second colors */
          /* ============================================ */

	  gimp_rgb_composite (&color, &color2, GIMP_RGB_COMPOSITE_NORMAL);
          gimp_rgb_clamp (&color);
        }
      else if (color.a != 0.0 && mapvals.lightsource.type != NO_LIGHT)
        {
	  color = phong_shade (&face_intersect[0].s,
			       &mapvals.viewpoint,
			       &face_intersect[0].n,
			       &mapvals.lightsource.position,
			       &color,
			       &mapvals.lightsource.color,
			       mapvals.lightsource.type);

	  gimp_rgb_clamp (&color);
        }
    }
  else
    {
      if (mapvals.transparent_background == TRUE)
	gimp_rgb_set_alpha (&color, 0.0);
    }

  return color;
}
Пример #3
0
static void decimatepages(fz_context *ctx, pdf_document *doc)
{
	pdf_obj *oldroot, *root, *pages, *kids, *parent;
	int num_pages = pdf_count_pages(ctx, doc);
	int page, kidcount;

	oldroot = pdf_dict_get(ctx, pdf_trailer(ctx, doc), PDF_NAME_Root);
	pages = pdf_dict_get(ctx, oldroot, PDF_NAME_Pages);

	root = pdf_new_dict(ctx, doc, 2);
	pdf_dict_put(ctx, root, PDF_NAME_Type, pdf_dict_get(ctx, oldroot, PDF_NAME_Type));
	pdf_dict_put(ctx, root, PDF_NAME_Pages, pdf_dict_get(ctx, oldroot, PDF_NAME_Pages));

	pdf_update_object(ctx, doc, pdf_to_num(ctx, oldroot), root);

	pdf_drop_obj(ctx, root);

	/* Create a new kids array with our new pages in */
	parent = pdf_new_indirect(ctx, doc, pdf_to_num(ctx, pages), pdf_to_gen(ctx, pages));
	kids = pdf_new_array(ctx, doc, 1);

	kidcount = 0;
	for (page=0; page < num_pages; page++)
	{
		pdf_page *page_details = pdf_load_page(ctx, doc, page);
		int xf = x_factor, yf = y_factor;
		int x, y;
		float w = page_details->mediabox.x1 - page_details->mediabox.x0;
		float h = page_details->mediabox.y1 - page_details->mediabox.y0;

		if (xf == 0 && yf == 0)
		{
			/* Nothing specified, so split along the long edge */
			if (w > h)
				xf = 2, yf = 1;
			else
				xf = 1, yf = 2;
		}
		else if (xf == 0)
			xf = 1;
		else if (yf == 0)
			yf = 1;

		for (y = yf-1; y >= 0; y--)
		{
			for (x = 0; x < xf; x++)
			{
				pdf_obj *newpageobj, *newpageref, *newmediabox;
				fz_rect mb;
				int num;

				newpageobj = pdf_copy_dict(ctx, pdf_lookup_page_obj(ctx, doc, page));
				num = pdf_create_object(ctx, doc);
				pdf_update_object(ctx, doc, num, newpageobj);
				newpageref = pdf_new_indirect(ctx, doc, num, 0);

				newmediabox = pdf_new_array(ctx, doc, 4);

				mb.x0 = page_details->mediabox.x0 + (w/xf)*x;
				if (x == xf-1)
					mb.x1 = page_details->mediabox.x1;
				else
					mb.x1 = page_details->mediabox.x0 + (w/xf)*(x+1);
				mb.y0 = page_details->mediabox.y0 + (h/yf)*y;
				if (y == yf-1)
					mb.y1 = page_details->mediabox.y1;
				else
					mb.y1 = page_details->mediabox.y0 + (h/yf)*(y+1);

				pdf_array_push(ctx, newmediabox, pdf_new_real(ctx, doc, mb.x0));
				pdf_array_push(ctx, newmediabox, pdf_new_real(ctx, doc, mb.y0));
				pdf_array_push(ctx, newmediabox, pdf_new_real(ctx, doc, mb.x1));
				pdf_array_push(ctx, newmediabox, pdf_new_real(ctx, doc, mb.y1));

				pdf_dict_put(ctx, newpageobj, PDF_NAME_Parent, parent);
				pdf_dict_put(ctx, newpageobj, PDF_NAME_MediaBox, newmediabox);

				intersect_box(ctx, doc, newpageobj, PDF_NAME_CropBox, &mb);
				intersect_box(ctx, doc, newpageobj, PDF_NAME_BleedBox, &mb);
				intersect_box(ctx, doc, newpageobj, PDF_NAME_TrimBox, &mb);
				intersect_box(ctx, doc, newpageobj, PDF_NAME_ArtBox, &mb);

				/* Store page object in new kids array */
				pdf_array_push(ctx, kids, newpageref);

				kidcount++;
			}
		}
	}

	pdf_drop_obj(ctx, parent);

	/* Update page count and kids array */
	pdf_dict_put(ctx, pages, PDF_NAME_Count, pdf_new_int(ctx, doc, kidcount));
	pdf_dict_put(ctx, pages, PDF_NAME_Kids, kids);
	pdf_drop_obj(ctx, kids);
}
Пример #4
0
bool Superellipsoid::Intersect(const BasicRay& ray, IStack& Depth_Stack, TraceThreadData *Thread)
{
    int i, cnt, Found = false;
    DBL dists[PLANECOUNT+2];
    DBL t, t1, t2, v0, v1, len;
    Vector3d P, D, P0, P1, P2, P3;

    /* Transform the ray into the superellipsoid space. */

    MInvTransPoint(P, ray.Origin, Trans);

    MInvTransDirection(D, ray.Direction, Trans);

    len = D.length();

    D /= len;

    /* Intersect superellipsoid's bounding box. */

    if (!intersect_box(P, D, &t1, &t2))
    {
        return(false);
    }

    /* Test if superellipsoid lies 'behind' the ray origin. */

    if (t2 < DEPTH_TOLERANCE)
    {
        return(false);
    }

    cnt = 0;

    if (t1 < DEPTH_TOLERANCE)
    {
        t1 = DEPTH_TOLERANCE;
    }

    dists[cnt++] = t1;
    dists[cnt++] = t2;

    /* Intersect ray with planes cutting superellipsoids in pieces. */

    cnt = find_ray_plane_points(P, D, cnt, dists, t1, t2);

    if (cnt <= 1)
    {
        return(false);
    }

    P0 = P + dists[0] * D;

    v0 = evaluate_superellipsoid(P0);

    if (fabs(v0) < ZERO_TOLERANCE)
    {
        if (insert_hit(ray, dists[0] / len, Depth_Stack, Thread))
        {
            if (Type & IS_CHILD_OBJECT)
            {
                Found = true;
            }
            else
            {
                return(true);
            }
        }
    }

    for (i = 1; i < cnt; i++)
    {
        P1 = P + dists[i] * D;

        v1 = evaluate_superellipsoid(P1);

        if (fabs(v1) < ZERO_TOLERANCE)
        {
            if (insert_hit(ray, dists[i] / len, Depth_Stack, Thread))
            {
                if (Type & IS_CHILD_OBJECT)
                {
                    Found = true;
                }
                else
                {
                    return(true);
                }
            }
        }
        else
        {
            if (v0 * v1 < 0.0)
            {
                /* Opposite signs, there must be a root between */

                solve_hit1(v0, P0, v1, P1, P2);

                P3 = P2 - P;

                t = P3.length();

                if (insert_hit(ray, t / len, Depth_Stack, Thread))
                {
                    if (Type & IS_CHILD_OBJECT)
                    {
                        Found = true;
                    }
                    else
                    {
                        return(true);
                    }
                }
            }
            else
            {
                /*
                 * Although there was no sign change, we may actually be approaching
                 * the surface. In this case, we are being fooled by the shape of the
                 * surface into thinking there isn't a root between sample points.
                 */

                if (check_hit2(P, D, dists[i-1], P0, v0, dists[i], &t, P2))
                {
                    if (insert_hit(ray, t / len, Depth_Stack, Thread))
                    {
                        if (Type & IS_CHILD_OBJECT)
                        {
                            Found = true;
                        }
                        else
                        {
                            return(true);
                        }
                    }
                    else
                    {
                        break;
                    }
                }
            }
        }

        v0 = v1;

        P0 = P1;
    }

    return(Found);
}