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.4 by gwlarson, Wed Aug 26 17:26:26 1998 UTC

# Line 25 | Line 25 | int    (*dobj_lightsamp)() = NULL;     /* pointer to function
25   #define MAXAC           64              /* 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 329 | Line 336 | ssph_compute()                 /* compute source set from sphere sam
336                                  addcolor(dlightsets->lamb, ssamp[alt][azi].val);
337          d = 1.0/ncells;
338          scalecolor(dlightsets->lamb, d);
339 <                                        /* clear sphere sample array */
339 > done:                                   /* clear sphere sample array */
340          bzero((char *)ssamp, sizeof(ssamp));
341          return(ncells);
342   }
# Line 349 | Line 356 | int    force;
356          if (op->drawcode != DO_LIGHT)
357                  return(0);
358                                          /* check for usable light set */
359 <        multp3(ocent, op->center, op->xfb.f.xfm);
359 >        getdcent(ocent, op);
360          for (dl = dlightsets; dl != NULL; dl = dl->next)
361                  if ((d2 = dist2(dl->lcent, ocent)) < mind2) {
362                          op->ol = dl;
363                          mind2 = d2;
364                  }
365                                          /* the following is heuristic */
366 <        d2 = 2.*op->radius*op->xfb.f.sca; d2 *= d2;
366 >        d2 = 2.*getdrad(op); d2 *= d2;
367          if ((dl = op->ol) != NULL && (mind2 < 0.0625*dl->ravg*dl->ravg ||
368 <                mind2 < 4.*op->radius*op->xfb.f.sca*op->radius*op->xfb.f.sca))
368 >                        mind2 < 4.*getdrad(op)*getdrad(op)))
369                  return(1);
370          if (!force)
371                  return(0);
# Line 475 | Line 482 | register char  *args;
482                  dobj_unmove();
483                  break;
484          case DO_OBJECT:                         /* print object statistics */
485 <                dobj_putstats(na ? alist[0] : curname, sstdout);
485 >                if (dobj_putstats(na ? alist[0] : curname, sstdout))
486 >                        if (na && alist[0][0] != '*' &&
487 >                                        strcmp(alist[0], curname))
488 >                                savedxf(curobj = getdobj(alist[0]));
489                  break;
490          case DO_DUP:                            /* duplicate object */
491                  for (nn = 0; nn < na; nn++)
# Line 499 | Line 509 | register char  *args;
509                          dobj_xform(curname, 1, na-nn, alist+nn);
510                  else
511                          curobj->drawcode = DO_HIDE;
512 +                savedxf(curobj);
513                  break;
514          case DO_SHOW:                           /* change rendering option */
515          case DO_LIGHT:
# Line 535 | Line 546 | char   *oct, *nam;
546                  error(COMMAND, "illegal name");
547                  return(0);
548          }
549 +        if (getdobj(nam) != NULL) {
550 +                error(COMMAND, "name already taken (unload first)");
551 +                return(0);
552 +        }
553                                          /* get octree path */
554          if ((fpp = getpath(oct, getlibpath(), R_OK)) == NULL) {
555                  sprintf(errmsg, "cannot find octree \"%s\"", oct);
# Line 542 | Line 557 | char   *oct, *nam;
557                  return(0);
558          }
559          strcpy(fpath, fpp);
545        freedobj(getdobj(nam));         /* free previous use of nam */
560          op = (DOBJECT *)malloc(sizeof(DOBJECT));
561          if (op == NULL)
562                  error(SYSTEM, "out of memory in dobj_load");
# Line 655 | Line 669 | FILE   *fp;
669                  error(COMMAND, "unknown object");
670                  return(0);
671          }
672 <        multp3(ocent, op->center, op->xfb.f.xfm);
672 >        getdcent(ocent, op);
673          fprintf(fp, "%s: %s, center [%f %f %f], radius %f", op->name,
674 <                        op->drawcode==DO_HIDE ? "hid" :
675 <                        op->drawcode==DO_LIGHT && op->ol!=NULL ? "lit" :
674 >                        op->drawcode==DO_HIDE ? "hidden" :
675 >                        op->drawcode==DO_LIGHT && op->ol!=NULL ? "lighted" :
676                          "shown",
677 <                        ocent[0],ocent[1],ocent[2], op->radius*op->xfb.f.sca);
677 >                        ocent[0],ocent[1],ocent[2], getdrad(op));
678          if (op->xfac)
679                  fputs(", (xform", fp);
680          for (i = 0; i < op->xfac; i++) {
# Line 717 | Line 731 | char   *oldnm, *nam;
731                  error(COMMAND, "illegal name");
732                  return(0);
733          }
734 +        if (getdobj(nam) != NULL) {
735 +                error(COMMAND, "name already taken (unload first)");
736 +                return(0);
737 +        }
738                                          /* allocate and copy struct */
739          opdup = (DOBJECT *)malloc(sizeof(DOBJECT));
740          if (opdup == NULL)
# Line 756 | Line 774 | int    cn;
774          } else if ((op = getdobj(nam)) == NULL) {
775                  error(COMMAND, "unknown object");
776                  return(0);
777 <        } else if ((op->drawcode = cn) == DO_LIGHT)
778 <                getdlights(op, 1);
779 <        else
777 >        } else if ((op->drawcode = cn) == DO_LIGHT) {
778 >                if (!getdlights(op, 1))
779 >                        error(COMMAND, "insufficient samples to light object");
780 >        } else
781                  op->ol = NULL;
782  
783          if (dobj_lightsamp != NULL) {           /* restore beam set */
# Line 772 | Line 791 | int    cn;
791  
792  
793   double
794 < dobj_trace(rorg, rdir)          /* check for ray intersection with objects */
794 > dobj_trace(nm, rorg, rdir)      /* check for ray intersection with object(s) */
795 > char    nm[];
796   FVECT   rorg, rdir;
797   {
798          register DOBJECT        *op;
799          FVECT   xorg, xdir;
800 <        double  darr[6], mindist = FHUGE;
801 <                                        /* check each visible object */
802 <        for (op = dobjects; op != NULL; op = op->next) {
803 <                if (op->drawcode == DO_HIDE)
804 <                        continue;
805 <                if (op->xfac) {         /* transform ray */
806 <                        multp3(xorg, rorg, op->xfb.b.xfm);
807 <                        multv3(xdir, rdir, op->xfb.b.xfm);
808 <                        VCOPY(darr, xorg); VCOPY(darr+3, xdir);
809 <                } else {
810 <                        VCOPY(darr, rorg); VCOPY(darr+3, rdir);
800 >        double  darr[6];
801 >                                        /* check each visible object? */
802 >        if (nm == NULL || *nm == '*') {
803 >                double  dist, mindist = 1.01*FHUGE;
804 >
805 >                if (nm != NULL) nm[0] = '\0';
806 >                for (op = dobjects; op != NULL; op = op->next) {
807 >                        if (op->drawcode == DO_HIDE)
808 >                                continue;
809 >                        dist = dobj_trace(op->name, rorg, rdir);
810 >                        if (dist < mindist) {
811 >                                if (nm != NULL) strcpy(nm, op->name);
812 >                                mindist = dist;
813 >                        }
814                  }
815 <                                        /* 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];
815 >                return(mindist);
816          }
817 <        return(mindist);
817 >                                        /* else check particular object */
818 >        if ((op = getdobj(nm)) == NULL) {
819 >                error(COMMAND, "unknown object");
820 >                return(FHUGE);
821 >        }
822 >        if (op->xfac) {         /* put ray in local coordinates */
823 >                multp3(xorg, rorg, op->xfb.b.xfm);
824 >                multv3(xdir, rdir, op->xfb.b.xfm);
825 >                VCOPY(darr, xorg); VCOPY(darr+3, xdir);
826 >        } else {
827 >                VCOPY(darr, rorg); VCOPY(darr+3, rdir);
828 >        }
829 >                                /* trace it */
830 >        if (process(op->rtp, darr, darr, sizeof(double),
831 >                        6*sizeof(double)) != sizeof(double))
832 >                error(SYSTEM, "rtrace communication error");
833 >                                /* return distance */
834 >        if (darr[0] >= .99*FHUGE)
835 >                return(FHUGE);
836 >        return(darr[0]*op->xfb.f.sca);
837   }
838  
839  
# Line 805 | Line 841 | dobj_render()                  /* render our objects in OpenGL */
841   {
842          GLboolean       normalizing;
843          GLfloat vec[4];
844 +        FVECT   v1;
845          register DOBJECT        *op;
846          register int    i;
847                                          /* anything to render? */
# Line 815 | Line 852 | dobj_render()                  /* render our objects in OpenGL */
852                  return(1);
853                                          /* set up general rendering params */
854          glGetBooleanv(GL_NORMALIZE, &normalizing);
855 <        glPushAttrib(GL_LIGHTING_BIT|GL_TRANSFORM_BIT|
856 <                        GL_DEPTH_BUFFER_BIT|GL_POLYGON_BIT);
855 >        glPushAttrib(GL_LIGHTING_BIT|GL_TRANSFORM_BIT|GL_ENABLE_BIT|
856 >                GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_POLYGON_BIT);
857          glDepthFunc(GL_LESS);
858          glEnable(GL_DEPTH_TEST);
859          glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
# Line 836 | Line 873 | dobj_render()                  /* render our objects in OpenGL */
873                  if (op->drawcode == DO_LIGHT && op->ol != NULL) {
874                          BYTE    pval;
875                          double  expval, d;
876 <
876 >                                                /* use computed sources */
877                          if (tmMapPixels(&pval, &op->ol->larb, TM_NOCHROM, 1)
878                                          != TM_E_OK)
879                                  error(CONSISTENCY, "dobj_render w/o tone map");
# Line 862 | Line 899 | dobj_render()                  /* render our objects in OpenGL */
899                                  glLightfv(glightid[i], GL_AMBIENT, vec);
900                                  glEnable(glightid[i]);
901                          }
902 <                } else {
903 <                        vec[0] = vec[1] = vec[2] = 1.; vec[3] = 1.;
902 >                } else {                        /* fake lighting */
903 >                        vec[0] = vec[1] = vec[2] = 0.; vec[3] = 1.;
904                          glLightModelfv(GL_LIGHT_MODEL_AMBIENT, vec);
905 +                        getdcent(v1, op);
906 +                        VSUB(v1, odev.v.vp, v1);
907 +                        if (normalize(v1) <= getdrad(op)) {
908 +                                vec[0] = -odev.v.vdir[0];
909 +                                vec[1] = -odev.v.vdir[1];
910 +                                vec[2] = -odev.v.vdir[2];
911 +                        } else
912 +                                VCOPY(vec, v1);
913 +                        vec[3] = 0.;
914 +                        glLightfv(GL_LIGHT0, GL_POSITION, vec);
915 +                        vec[0] = vec[1] = vec[2] = .7; vec[3] = 1.;
916 +                        glLightfv(GL_LIGHT0, GL_SPECULAR, vec);
917 +                        glLightfv(GL_LIGHT0, GL_DIFFUSE, vec);
918 +                        vec[0] = vec[1] = vec[2] = .3; vec[3] = 1.;
919 +                        glLightfv(GL_LIGHT0, GL_AMBIENT, vec);
920 +                        glEnable(GL_LIGHT0);
921                  }
922                                          /* set up object transform */
923                  if (op->xfac) {
# Line 893 | Line 946 | dobj_render()                  /* render our objects in OpenGL */
946                  if (op->drawcode == DO_LIGHT && op->ol != NULL)
947                          for (i = op->ol->nl; i--; )
948                                  glDisable(glightid[i]);
949 +                else
950 +                        glDisable(GL_LIGHT0);
951                                          /* check errors */
897                rgl_checkerr("rendering object in dobj_render");
952          }
953          glPopAttrib();                  /* restore rendering params */
954 +        rgl_checkerr("rendering objects in dobj_render");
955          return(1);
956   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines