home *** CD-ROM | disk | FTP | other *** search
- /*
- * composite.c -- standard routines for composites
- *
- * (c) 1993, 1994 by Han-Wen Nienhuys <hanwen@stack.urc.tue.nl>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
- #include "ray.h"
- #include "proto.h"
- #include "extern.h"
-
- extern struct methods my_methods;
-
- /*
- * Intersect a ray with a composite.
- *
- * 1. intersect the element list of the composite
- */
-
- /*
- * we should do some special handling of clipping shapes.
- */
-
- PRIVATE bool
- all_vanilla_composite_intersections(dqueue * globq, object *c, struct ray *r, int flags, bool *ins)
- {
- object *p;
- bool gotcha;
-
-
-
- gotcha = FALSE;
-
- for (p = c->data.composite->contents; p != NULL; p = p->next) {
-
- /* walk the element list, and intersect each element */
- if (intersect_object(globq, p, r, flags))
- gotcha = TRUE;
-
- if (!(flags & CHKALL))
- r->maxt = globq->t;
-
- if (globq->t < r->mint) /* early exit possible? */
- break;
- }
-
- return gotcha;
- }
-
- PRIVATE bool
- all_composite_intersections(dqueue * globq, object *c, struct ray *r, int flags, bool *ins)
- {
-
- bool gotcha;
-
- my_methods.test++;
- gotcha = c->data.composite->all_intersections_method(globq, c, r, flags, ins);
- if (gotcha)
- my_methods.hit++;
-
- return gotcha;
- }
-
-
-
-
- /* speed up the composite */
- PUBLIC void
- speed_composite(object *o, vector spd)
- {
- speed_object_list(o->data.composite->contents, spd);
- }
-
-
- /* initialize a composite_data struct */
- PRIVATE void
- init_composite(struct composite_data *t)
- {
- t->contents = NULL;
- t->optitype = NONE;
- t->all_intersections_method = all_vanilla_composite_intersections;
- }
-
- PRIVATE struct composite_data *
- get_new_composite(void)
- {
- struct composite_data *p;
- p = ALLOC(struct composite_data);
-
- CHECK_MEM(p, my_methods.name);
- init_composite(p);
- return p;
- }
-
- /* append an object to the composite c */
- PUBLIC void
- add_to_composite(object *c, object *o)
- {
- object *tmp;
-
- tmp = c->data.composite->contents;
- c->data.composite->contents = o;
- o->next = tmp;
- o->daddy = c;
- }
-
- /* this is getting boring... */
- PRIVATE void
- copy_composite(object *dst, object *src)
- {
- object *p,
- *new;
-
-
- if (dst->type != COMPOSITE)
- dst->data.composite = get_new_composite();
-
- dst->type = src->type;
-
- for (p = src->data.composite->contents; p != NULL; p = p->next) {
- new = get_new_object();
- copy_object(new, p);
- add_to_composite(dst, new);
- }
- }
-
- /* standard */
- PRIVATE void
- translate_composite(object *c, vector t)
- {
- translate_object_list(c->data.composite->contents, t);
- }
-
- /* hooooeeewaahhh, Geez, why do I write these comments? */
- PRIVATE void
- rotate_composite(object *c, matrix rotmat)
- {
- rotate_object_list(c->data.composite->contents, rotmat);
- }
-
- /* 3X raden (Yes, you folks out there, I'm now commenting in Dutch! */
- PRIVATE void
- scale_composite(object *c, vector s)
- {
- scale_object_list(c->data.composite->contents, s);
- }
-
- /*
- * I guess .. because somebody will read them, some day (Hello, is there
- * somebody out there?
- *
- * and another free_XXX() (en wat hebben ze gewonnen, Pierre, als ze goed
- * raden waar dit voor is ?
- */
- PRIVATE void
- free_composite(object *c)
- {
- free_object_list(c->data.composite->contents);
- c->type = NOSHAPE;
- }
-
- /* do debugging stuff */
- PRIVATE void
- print_composite(object *c)
- {
- #ifdef DEBUG
- struct composite_data *p = c->data.composite;
-
- printf(" { optimisation %d\n", p->optitype);
- print_object_list(p->contents);
- printf("}");
- #endif
- }
-
- PRIVATE bool
- inside_composite(object *o, vector x)
- {
- assert(FALSE);
- }
-
- PRIVATE vector
- composite_normal(struct intersect i, vector x)
- {
- assert(FALSE);
- }
-
- PRIVATE void
- precompute_composite(object *o)
- {
- object *op;
- struct composite_data *c;
-
- c = o->data.composite;
- precompute_object_list(c->contents);
-
- /* for the data: union of bboxes */
- for (op = c->contents; op != NULL; op = op->next) {
- if (op->bmin.x < o->bmin.x)
- o->bmin.x = op->bmin.x;
- if (op->bmin.y < o->bmin.y)
- o->bmin.y = op->bmin.y;
- if (op->bmin.z < o->bmin.z)
- o->bmin.z = op->bmin.z;
- if (op->bmax.x > o->bmax.x)
- o->bmax.x = op->bmax.x;
- if (op->bmax.y > o->bmax.y)
- o->bmax.y = op->bmax.y;
- if (op->bmax.z > o->bmax.z)
- o->bmax.z = op->bmax.z;
- }
-
- /* bounds: intersection of bboxes */
- for (op = o->bound; op != NULL; op = op->next) {
- o->bmin.x = MAX(o->bmin.x, op->bmin.x);
- o->bmin.y = MAX(o->bmin.y, op->bmin.y);
- o->bmin.z = MAX(o->bmin.z, op->bmin.z);
- o->bmax.x = MIN(o->bmax.x, op->bmax.x);
- o->bmax.y = MIN(o->bmax.y, op->bmax.y);
- o->bmax.z = MIN(o->bmax.z, op->bmax.z);
- }
-
- switch (c->optitype) {
- case NONE:
- c->all_intersections_method = all_vanilla_composite_intersections;
- break;
- default:
- assert(FALSE);
- }
- my_methods.howmuch++;
- global_stats.nonprims++;
- }
-
- PRIVATE struct methods my_methods =
- {
- all_composite_intersections,
- composite_normal,
- copy_composite,
- inside_composite,
- rotate_composite,
- translate_composite,
- scale_composite,
- free_composite,
- print_composite,
- precompute_composite,
- "composite",
- };
-
-
- PUBLIC object *
- get_new_composite_object(void)
- {
- object *p;
-
- p = (object *) get_new_object();
- p->data.composite = get_new_composite();
-
- p->type = COMPOSITE;
- p->methods = &my_methods;
- return p;
- }
-
- /* hoihoihoihoi. */
-