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); }
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; }
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); }
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); }