ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/hd/rhdobj.c
(Generate patch)

Comparing ray/src/hd/rhdobj.c (file contents):
Revision 3.1 by gwlarson, Wed Aug 19 17:45:24 1998 UTC vs.
Revision 3.7 by gwlarson, Fri Dec 18 11:06:45 1998 UTC

# Line 5 | Line 5 | static char SCCSid[] = "$SunId$ SGI";
5   #endif
6  
7   /*
8 < * Routines for loading and displaying Radiance objects under OpenGL in rholo.
8 > * Routines for loading and displaying Radiance objects in rholo with GLX.
9   */
10  
11   #include "radogl.h"
# Line 22 | Line 22 | int    (*dobj_lightsamp)() = NULL;     /* pointer to function
22  
23   #define AVGREFL         0.5             /* assumed average reflectance */
24  
25 < #define MAXAC           64              /* maximum number of args */
25 > #define MAXAC           512             /* maximum number of args */
26  
27   #ifndef MINTHRESH
28 < #define MINTHRESH       7.0             /* source threshold w.r.t. mean */
28 > #define MINTHRESH       5.0             /* source threshold w.r.t. mean */
29   #endif
30  
31   #ifndef NALT
# Line 69 | Line 69 | static DOBJECT *curobj;                /* current (last referred) ob
69   static int      lastxfac;               /* last number of transform args */
70   static char     *lastxfav[MAXAC+1];     /* saved transform arguments */
71  
72 + #define getdcent(c,op)  multp3(c,(op)->center,(op)->xfb.f.xfm)
73 + #define getdrad(op)     ((op)->radius*(op)->xfb.f.sca)
74 +
75   #define RTARGC  8
76   static char     *rtargv[RTARGC+1] = {"rtrace", "-h-", "-w-", "-fdd",
77                                          "-x", "1", "-oL"};
# Line 279 | Line 282 | ssph_compute()                 /* compute source set from sphere sam
282                                  ncells++;
283                          }
284          if (dlightsets == NULL | ncells < NALT*NAZI/4) {
285 <                bzero((char *)ssamp, sizeof(ssamp));
286 <                return(0);
285 >                ncells = 0;
286 >                goto done;
287          }
288                                                  /* harmonic mean distance */
289          if (dlightsets->ravg > FTINY)
# Line 289 | Line 292 | ssph_compute()                 /* compute source set from sphere sam
292                  dlightsets->ravg = FHUGE;
293                                                  /* light source threshold */
294          thresh = MINTHRESH*bright(csum)/ncells;
295 +        if (thresh <= FTINY) {
296 +                ncells = 0;
297 +                goto done;
298 +        }
299                                                  /* avg. reflected brightness */
300          d = AVGREFL / (double)ncells;  
301          scalecolor(csum, d);
302          if (tmCvColors(&dlightsets->larb, TM_NOCHROM, csum, 1) != TM_E_OK)
303 <                error(CONSISTENCY, "bad tone mapping in ssph_compute");
303 >                error(CONSISTENCY, "tone mapping problem in ssph_compute");
304                                          /* greedy light source clustering */
305          while (dlightsets->nl < MAXLIGHTS) {
306                  maxbr = 0.;                     /* find brightest cell */
# Line 313 | Line 320 | ssph_compute()                 /* compute source set from sphere sam
320                                  continue;               /* too dim */
321                          ssph_direc(v, alt, azi);        /* else add it in */
322                          VSUM(ls->direc, ls->direc, v, d);
323 <                        ls->omega++;
323 >                        ls->omega += 1.;
324                          addcolor(ls->val, ssamp[alt][azi].val);
325 +                                                        /* remove from list */
326                          setcolor(ssamp[alt][azi].val, 0., 0., 0.);
327 +                        ssamp[alt][azi].nsamp = 0;
328                  }
329                  d = 1./ls->omega;                       /* avg. brightness */
330                  scalecolor(ls->val, d);
# Line 329 | Line 338 | ssph_compute()                 /* compute source set from sphere sam
338                                  addcolor(dlightsets->lamb, ssamp[alt][azi].val);
339          d = 1.0/ncells;
340          scalecolor(dlightsets->lamb, d);
341 <                                        /* clear sphere sample array */
341 > done:                                   /* clear sphere sample array */
342          bzero((char *)ssamp, sizeof(ssamp));
343          return(ncells);
344   }
# Line 349 | Line 358 | int    force;
358          if (op->drawcode != DO_LIGHT)
359                  return(0);
360                                          /* check for usable light set */
361 <        multp3(ocent, op->center, op->xfb.f.xfm);
361 >        getdcent(ocent, op);
362          for (dl = dlightsets; dl != NULL; dl = dl->next)
363                  if ((d2 = dist2(dl->lcent, ocent)) < mind2) {
364                          op->ol = dl;
365                          mind2 = d2;
366                  }
367                                          /* the following is heuristic */
368 <        d2 = 2.*op->radius*op->xfb.f.sca; d2 *= d2;
368 >        d2 = 2.*getdrad(op); d2 *= d2;
369          if ((dl = op->ol) != NULL && (mind2 < 0.0625*dl->ravg*dl->ravg ||
370 <                mind2 < 4.*op->radius*op->xfb.f.sca*op->radius*op->xfb.f.sca))
370 >                        mind2 < 4.*getdrad(op)*getdrad(op)))
371                  return(1);
372          if (!force)
373                  return(0);
# Line 453 | Line 462 | register char  *args;
462                  else
463                          return(cmderror(cn, "need octree [name]"));
464                  break;
465 <        case DO_UNLOAD:                         /* unload an object */
465 >        case DO_UNLOAD:                         /* clear an object */
466                  if (na > 1) goto toomany;
467                  if (na && alist[0][0] == '*')
468                          dobj_cleanup();
# Line 475 | Line 484 | register char  *args;
484                  dobj_unmove();
485                  break;
486          case DO_OBJECT:                         /* print object statistics */
487 <                dobj_putstats(na ? alist[0] : curname, sstdout);
487 >                if (dobj_putstats(na ? alist[0] : curname, sstdout))
488 >                        if (na && alist[0][0] != '*' && (curobj == NULL ||
489 >                                        strcmp(alist[0], curobj->name)))
490 >                                savedxf(curobj = getdobj(alist[0]));
491                  break;
492          case DO_DUP:                            /* duplicate object */
493                  for (nn = 0; nn < na; nn++)
# Line 499 | Line 511 | register char  *args;
511                          dobj_xform(curname, 1, na-nn, alist+nn);
512                  else
513                          curobj->drawcode = DO_HIDE;
514 +                savedxf(curobj);
515                  break;
516          case DO_SHOW:                           /* change rendering option */
517          case DO_LIGHT:
# Line 535 | Line 548 | char   *oct, *nam;
548                  error(COMMAND, "illegal name");
549                  return(0);
550          }
551 +        if (getdobj(nam) != NULL) {
552 +                error(COMMAND, "name already taken (clear first)");
553 +                return(0);
554 +        }
555                                          /* get octree path */
556          if ((fpp = getpath(oct, getlibpath(), R_OK)) == NULL) {
557                  sprintf(errmsg, "cannot find octree \"%s\"", oct);
# Line 542 | Line 559 | char   *oct, *nam;
559                  return(0);
560          }
561          strcpy(fpath, fpp);
545        freedobj(getdobj(nam));         /* free previous use of nam */
562          op = (DOBJECT *)malloc(sizeof(DOBJECT));
563          if (op == NULL)
564                  error(SYSTEM, "out of memory in dobj_load");
# Line 598 | Line 614 | dobj_cleanup()                         /* free all resources */
614   }
615  
616  
617 < dobj_xform(nam, add, ac, av)            /* set/add transform for nam */
617 > dobj_xform(nam, rel, ac, av)            /* set/add transform for nam */
618   char    *nam;
619 < int     add, ac;
619 > int     rel, ac;
620   char    **av;
621   {
622          register DOBJECT        *op;
623 +        FVECT   cent;
624 +        double  rad;
625 +        char    scoord[16];
626 +        int     i;
627  
628          if ((op = getdobj(nam)) == NULL) {
629                  error(COMMAND, "no object");
630                  return(0);
631          }
632 <        if (add) add = op->xfac;
633 <        if (ac + add > MAXAC) {
632 >        if (rel)
633 >                rel = op->xfac + 8;
634 >        if (ac + rel > MAXAC) {
635                  error(COMMAND, "too many transform arguments");
636                  return(0);
637          }
638 <        savedxf(curobj = op);
639 <        if (!add)
638 >        savedxf(curobj = op);           /* remember current transform */
639 >        if (rel && ac == 4 && !strcmp(av[0], "-t"))
640 >                rel = -1;                       /* don't move for translate */
641 >        else {
642 >                getdcent(cent, op);             /* don't move if near orig. */
643 >                rad = getdrad(op);
644 >                if (DOT(cent,cent) < rad*rad)
645 >                        rel = -1;
646 >        }
647 >        if (!rel) {                             /* remove old transform */
648                  while (op->xfac)
649                          freestr(op->xfav[--op->xfac]);
650 +        } else if (rel > 0) {                   /* relative move */
651 +                op->xfav[op->xfac++] = savestr("-t");
652 +                for (i = 0; i < 3; i++) {
653 +                        sprintf(scoord, "%.4e", -cent[i]);
654 +                        op->xfav[op->xfac++] = savestr(scoord);
655 +                }
656 +        }
657          while (ac--)
658                  op->xfav[op->xfac++] = savestr(*av++);
659 +        if (rel > 0) {                          /* move back */
660 +                op->xfav[op->xfac++] = savestr("-t");
661 +                for (i = 0; i < 3; i++) {
662 +                        sprintf(scoord, "%.4e", cent[i]);
663 +                        op->xfav[op->xfac++] = savestr(scoord);
664 +                }
665 +        }
666          op->xfav[op->xfac] = NULL;
667          if (fullxf(&op->xfb, op->xfac, op->xfav) != op->xfac) {
668                  error(COMMAND, "bad transform arguments");
# Line 655 | Line 698 | FILE   *fp;
698                  error(COMMAND, "unknown object");
699                  return(0);
700          }
701 <        multp3(ocent, op->center, op->xfb.f.xfm);
702 <        fprintf(fp, "%s: %s, center [%f %f %f], radius %f", op->name,
703 <                        op->drawcode==DO_HIDE ? "hid" :
704 <                        op->drawcode==DO_LIGHT && op->ol!=NULL ? "lit" :
701 >        getdcent(ocent, op);
702 >        fprintf(fp, "%s: %s, center [%g %g %g], radius %g", op->name,
703 >                        op->drawcode==DO_HIDE ? "hidden" :
704 >                        op->drawcode==DO_LIGHT && op->ol!=NULL ? "lighted" :
705                          "shown",
706 <                        ocent[0],ocent[1],ocent[2], op->radius*op->xfb.f.sca);
706 >                        ocent[0],ocent[1],ocent[2], getdrad(op));
707          if (op->xfac)
708                  fputs(", (xform", fp);
709          for (i = 0; i < op->xfac; i++) {
# Line 717 | Line 760 | char   *oldnm, *nam;
760                  error(COMMAND, "illegal name");
761                  return(0);
762          }
763 +        if (getdobj(nam) != NULL) {
764 +                error(COMMAND, "name already taken (clear first)");
765 +                return(0);
766 +        }
767                                          /* allocate and copy struct */
768          opdup = (DOBJECT *)malloc(sizeof(DOBJECT));
769          if (opdup == NULL)
# Line 756 | Line 803 | int    cn;
803          } else if ((op = getdobj(nam)) == NULL) {
804                  error(COMMAND, "unknown object");
805                  return(0);
806 <        } else if ((op->drawcode = cn) == DO_LIGHT)
807 <                getdlights(op, 1);
808 <        else
806 >        } else if ((op->drawcode = cn) == DO_LIGHT) {
807 >                if (!getdlights(op, 1))
808 >                        error(COMMAND, "insufficient samples to light object");
809 >        } else
810                  op->ol = NULL;
811  
812          if (dobj_lightsamp != NULL) {           /* restore beam set */
# Line 772 | Line 820 | int    cn;
820  
821  
822   double
823 < dobj_trace(rorg, rdir)          /* check for ray intersection with objects */
823 > dobj_trace(nm, rorg, rdir)      /* check for ray intersection with object(s) */
824 > char    nm[];
825   FVECT   rorg, rdir;
826   {
827          register DOBJECT        *op;
828          FVECT   xorg, xdir;
829 <        double  darr[6], mindist = FHUGE;
830 <                                        /* check each visible object */
831 <        for (op = dobjects; op != NULL; op = op->next) {
832 <                if (op->drawcode == DO_HIDE)
833 <                        continue;
834 <                if (op->xfac) {         /* transform ray */
835 <                        multp3(xorg, rorg, op->xfb.b.xfm);
836 <                        multv3(xdir, rdir, op->xfb.b.xfm);
837 <                        VCOPY(darr, xorg); VCOPY(darr+3, xdir);
838 <                } else {
839 <                        VCOPY(darr, rorg); VCOPY(darr+3, rdir);
829 >        double  darr[6];
830 >                                        /* check each visible object? */
831 >        if (nm == NULL || *nm == '*') {
832 >                double  dist, mindist = 1.01*FHUGE;
833 >
834 >                if (nm != NULL) nm[0] = '\0';
835 >                for (op = dobjects; op != NULL; op = op->next) {
836 >                        if (op->drawcode == DO_HIDE)
837 >                                continue;
838 >                        dist = dobj_trace(op->name, rorg, rdir);
839 >                        if (dist < mindist) {
840 >                                if (nm != NULL) strcpy(nm, op->name);
841 >                                mindist = dist;
842 >                        }
843                  }
844 <                                        /* trace it */
793 <                if (process(op->rtp, darr, darr, sizeof(double),
794 <                                6*sizeof(double)) != sizeof(double))
795 <                        error(SYSTEM, "rtrace communication error");
796 <                                        /* get closest */
797 <                if ((darr[0] *= op->xfb.f.sca) < mindist)
798 <                        mindist = darr[0];
844 >                return(mindist);
845          }
846 <        return(mindist);
846 >                                        /* else check particular object */
847 >        if ((op = getdobj(nm)) == NULL) {
848 >                error(COMMAND, "unknown object");
849 >                return(FHUGE);
850 >        }
851 >        if (op->xfac) {         /* put ray in local coordinates */
852 >                multp3(xorg, rorg, op->xfb.b.xfm);
853 >                multv3(xdir, rdir, op->xfb.b.xfm);
854 >                VCOPY(darr, xorg); VCOPY(darr+3, xdir);
855 >        } else {
856 >                VCOPY(darr, rorg); VCOPY(darr+3, rdir);
857 >        }
858 >                                /* trace it */
859 >        if (process(op->rtp, darr, darr, sizeof(double),
860 >                        6*sizeof(double)) != sizeof(double))
861 >                error(SYSTEM, "rtrace communication error");
862 >                                /* return distance */
863 >        if (darr[0] >= .99*FHUGE)
864 >                return(FHUGE);
865 >        return(darr[0]*op->xfb.f.sca);
866   }
867  
868  
869 + int
870   dobj_render()                   /* render our objects in OpenGL */
871   {
872 +        int     nrendered = 0;
873          GLboolean       normalizing;
874          GLfloat vec[4];
875 +        FVECT   v1;
876          register DOBJECT        *op;
877          register int    i;
878                                          /* anything to render? */
# Line 812 | Line 880 | dobj_render()                  /* render our objects in OpenGL */
880                  if (op->drawcode != DO_HIDE)
881                          break;
882          if (op == NULL)
883 <                return(1);
883 >                return(0);
884                                          /* set up general rendering params */
885          glGetBooleanv(GL_NORMALIZE, &normalizing);
886 <        glPushAttrib(GL_LIGHTING_BIT|GL_TRANSFORM_BIT|
887 <                        GL_DEPTH_BUFFER_BIT|GL_POLYGON_BIT);
886 >        glPushAttrib(GL_LIGHTING_BIT|GL_TRANSFORM_BIT|GL_ENABLE_BIT|
887 >                GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_POLYGON_BIT);
888          glDepthFunc(GL_LESS);
889          glEnable(GL_DEPTH_TEST);
890          glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
# Line 836 | Line 904 | dobj_render()                  /* render our objects in OpenGL */
904                  if (op->drawcode == DO_LIGHT && op->ol != NULL) {
905                          BYTE    pval;
906                          double  expval, d;
907 <
907 >                                                /* use computed sources */
908                          if (tmMapPixels(&pval, &op->ol->larb, TM_NOCHROM, 1)
909                                          != TM_E_OK)
910                                  error(CONSISTENCY, "dobj_render w/o tone map");
# Line 862 | Line 930 | dobj_render()                  /* render our objects in OpenGL */
930                                  glLightfv(glightid[i], GL_AMBIENT, vec);
931                                  glEnable(glightid[i]);
932                          }
933 <                } else {
934 <                        vec[0] = vec[1] = vec[2] = 1.; vec[3] = 1.;
933 >                } else {                        /* fake lighting */
934 >                        vec[0] = vec[1] = vec[2] = 0.; vec[3] = 1.;
935                          glLightModelfv(GL_LIGHT_MODEL_AMBIENT, vec);
936 +                        getdcent(v1, op);
937 +                        VSUB(v1, odev.v.vp, v1);
938 +                        if (normalize(v1) <= getdrad(op)) {
939 +                                vec[0] = -odev.v.vdir[0];
940 +                                vec[1] = -odev.v.vdir[1];
941 +                                vec[2] = -odev.v.vdir[2];
942 +                        } else
943 +                                VCOPY(vec, v1);
944 +                        vec[3] = 0.;
945 +                        glLightfv(GL_LIGHT0, GL_POSITION, vec);
946 +                        vec[0] = vec[1] = vec[2] = .7; vec[3] = 1.;
947 +                        glLightfv(GL_LIGHT0, GL_SPECULAR, vec);
948 +                        glLightfv(GL_LIGHT0, GL_DIFFUSE, vec);
949 +                        vec[0] = vec[1] = vec[2] = .3; vec[3] = 1.;
950 +                        glLightfv(GL_LIGHT0, GL_AMBIENT, vec);
951 +                        glEnable(GL_LIGHT0);
952                  }
953                                          /* set up object transform */
954                  if (op->xfac) {
# Line 882 | Line 966 | dobj_render()                  /* render our objects in OpenGL */
966                  }
967                                          /* render the display list */
968                  glCallList(op->listid);
969 +                nrendered++;
970                                          /* restore matrix */
971                  if (op->xfac) {
972                          glMatrixMode(GL_MODELVIEW);
# Line 893 | Line 978 | dobj_render()                  /* render our objects in OpenGL */
978                  if (op->drawcode == DO_LIGHT && op->ol != NULL)
979                          for (i = op->ol->nl; i--; )
980                                  glDisable(glightid[i]);
981 +                else
982 +                        glDisable(GL_LIGHT0);
983                                          /* check errors */
897                rgl_checkerr("rendering object in dobj_render");
984          }
985          glPopAttrib();                  /* restore rendering params */
986 <        return(1);
986 >        rgl_checkerr("rendering objects in dobj_render");
987 >        return(nrendered);
988   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines