Logo Search packages:      
Sourcecode: acm version File versions  Download package

VOrder.c

#include "Vlib.h"
#include <math.h>

#define mag(x,y,z) sqrt ( (x) * (x) + (y) * (y) + (z) * (z) )

struct _euler {
      double    yaw;
      double    pitch;
};

struct entry {
      int       id;
      double    d;
      struct entry *next;
};

/*
 *  Views corresponding to each of the eight defined major aspects
 */

static struct _euler view[] =
{
      {DEGtoRAD(90.0), DEGtoRAD(0.0)},    /* 0 - right */
      {DEGtoRAD(-90.0), DEGtoRAD(0.0)},   /* 1 - left */
      {DEGtoRAD(45.0), DEGtoRAD(45.0)},   /* 2 - front right bottom */
      {DEGtoRAD(45.0), DEGtoRAD(-45.0)},  /* 3 - front right top    */
      {DEGtoRAD(-45.0), DEGtoRAD(45.0)},  /* 4 - front left bottom  */
      {DEGtoRAD(-45.0), DEGtoRAD(-45.0)},       /* 5 - front left top     */
      {DEGtoRAD(135.0), DEGtoRAD(45.0)},  /* 6 - aft right bottom   */
      {DEGtoRAD(135.0), DEGtoRAD(-45.0)},       /* 7 - aft right top      */
      {DEGtoRAD(-135.0), DEGtoRAD(45.0)},       /* 8 - aft left bottom    */
      {DEGtoRAD(-135.0), DEGtoRAD(-45.0)},      /* 9 - aft left top       */
};

static char *aspect_name[] =
{
      "left",
      "right",
      "front right bottom",
      "front right top",
      "front left bottom",
      "front left top",
      "aft right bottom",
      "aft right top",
      "aft left bottom",
      "aft left top"
};

void
VComputePolygonOrdering(VObject * obj)
{
      register int i, j, k, inserted;
      register double d, dn;
      VMatrix   mtx;
      VPoint    pt1, pt2;
      VPolygon **p;
      struct entry ent[VmaxVP], *head, *e, *last_e;

      obj->order = (unsigned short *)
            Vmalloc(sizeof(unsigned short) * NUM_ASPECTS * obj->numPolys);

      for (i = 0; i < NUM_ASPECTS; ++i) {

            VIdentMatrix(&mtx);
            VRotate(&mtx, YRotation, -view[i].pitch);
            VRotate(&mtx, ZRotation, view[i].yaw);
            pt1.x = obj->extent * 10.0;
            pt1.y = pt1.z = 0.0;
            VTransform(&pt1, &mtx, &pt2);
            head = (struct entry *) NULL;
            for (j = 0, p = obj->polygon; j < obj->numPolys; ++j) {

/*
 *  Compute the distance to the farthest vertex on this polygon
 */

                  dn = mag(p[j]->vertex[0].x - pt2.x,
                               p[j]->vertex[0].y - pt2.y,
                               p[j]->vertex[0].z - pt2.z);

                  for (k = 1; k < p[j]->numVtces; ++k) {
                        d = mag(
                                       p[j]->vertex[k].x - pt2.x,
                                       p[j]->vertex[k].y - pt2.y,
                                       p[j]->vertex[k].z - pt2.z);
                        if (d > dn) {
                              dn = d;
                        }
                  }

                  ent[j].id = j;
                  ent[j].d = dn;

/*
 *  Insert this entry into the descending sorted list of polygons
 */

                  if (!head) {
                        ent[j].next = head;
                        head = &ent[j];
                  }
                  else {
                        last_e = (struct entry *) NULL;
                        inserted = 0;
                        for (e = head; e; e = e->next) {
                              if (e->d < ent[j].d) {
                                    if (last_e) {
                                          ent[j].next = last_e->next;
                                          last_e->next = &ent[j];
                                    }
                                    else {
                                          ent[j].next = e;
                                          head = &ent[j];
                                    }
                                    inserted = 1;
                                    break;
                              }
                              last_e = e;
                        }
                        if (inserted == 0) {
                              last_e->next = &ent[j];
                              ent[j].next = (struct entry *) NULL;

                        }
                  }
            }

/*
 *  Copy this list as the hints for this quadrant.
 */

            k = obj->numPolys * i;
            for (j = 0, e = head; j < obj->numPolys; ++j, e = e->next) {
                  obj->order[k + j] = e->id;
            }

      }
}

/*
 *  Determine if an object should be ordered.  Objects that are not made of
 *  entirely the same color, or that have colored back-sides probably should
 *  be ordered.
 */

int
VObjectNeedsOrdering(VObject * obj)
{
      VPolygon **p;
      VColor   *c;
      int       i;

      if (obj->order || obj->numPolys == 0) {
            return 0;
      }

      c = obj->polygon[0]->color;

      for (i = 0, p = obj->polygon; i < obj->numPolys; ++i) {
#ifdef notdef
            if (p[i]->color != c) {
                  return 1;
            }
#endif
            if (p[i]->backColor) {
                  return 1;
            }
      }

      return 0;
}

int
VComputeObjectAspect(VObject * obj, VPoint * loc)
{
      register int q;
      register double a, b, c, m;

      m = mag(loc->x, loc->y, loc->z);

      a = VDotProd(loc, &obj->xaxis);
      b = VDotProd(loc, &obj->yaxis) / m;
      c = VDotProd(loc, &obj->zaxis);

/*
 *  If the absolute angle between the Y axis and viewing vector is less than 30
 *  degrees, then it is either a right or left aspect.
 */

      if (b > 0.866) {
            return 1;
      }
      else if (b < -0.866) {
            return 0;
      }

      if (a < 0.0) {
/* front */
            if (b < 0.0) {
/* front right */
                  if (c < 0.0) {
/* front right bottom */
                        q = 2;
                  }
                  else {
/* front right top */
                        q = 3;
                  }
            }
            else {
/* front left */
                  if (c < 0.0) {
/* front left bottom */
                        q = 4;
                  }
                  else {
/* front left top */
                        q = 5;
                  }
            }
      }
      else {
/* aft */
            if (b < 0.0) {
/* aft right */
                  if (c < 0.0) {
/* aft right bottom */
                        q = 6;
                  }
                  else {
/* aft right top */
                        q = 7;
                  }
            }
            else {
/* aft left */
                  if (c < 0.0) {
/* aft left bottom */
                        q = 8;
                  }
                  else {
/* aft left top */
                        q = 9;
                  }
            }
      }

      return q;
}

char     *
VGetAspectName(int aspect)
{
      return aspect_name[aspect];
}

Generated by  Doxygen 1.6.0   Back to index