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.2 by gwlarson, Fri Aug 21 11:38:22 1998 UTC vs.
Revision 3.9 by gwlarson, Thu Dec 31 12:57:06 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       5.0             /* source threshold w.r.t. mean */
# Line 320 | 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 414 | Line 416 | memerr:
416   }
417  
418  
419 < static int
419 > static
420   cmderror(cn, err)               /* report command error */
421   int     cn;
422   char    *err;
423   {
424          sprintf(errmsg, "%s: %s", rhdcmd[cn], err);
425          error(COMMAND, errmsg);
424        return(cn);
426   }
427  
428  
# Line 430 | Line 431 | dobj_command(cmd, args)                /* run object display command
431   char    *cmd;
432   register char   *args;
433   {
434 +        int     somechange = 0;
435          int     cn, na, doxfm;
436          register int    nn;
437          char    *alist[MAXAC+1], *nm;
# Line 457 | Line 459 | register char  *args;
459                          dobj_load(alist[0], alist[0]);
460                  else if (na == 2)
461                          dobj_load(alist[0], alist[1]);
462 <                else
463 <                        return(cmderror(cn, "need octree [name]"));
462 >                else {
463 >                        cmderror(cn, "need octree [name]");
464 >                        return(0);
465 >                }
466                  break;
467 <        case DO_UNLOAD:                         /* unload an object */
467 >        case DO_UNLOAD:                         /* clear an object */
468                  if (na > 1) goto toomany;
469                  if (na && alist[0][0] == '*')
470 <                        dobj_cleanup();
470 >                        somechange += dobj_cleanup();
471                  else
472 <                        dobj_unload(na ? alist[0] : curname);
472 >                        somechange += dobj_unload(na ? alist[0] : curname);
473                  break;
474          case DO_XFORM:                          /* transform object */
475          case DO_MOVE:
# Line 474 | Line 478 | register char  *args;
478                  } else {
479                          nm = curname; nn = 0;
480                  }
481 <                if (cn == DO_MOVE && nn >= na)
482 <                        return(cmderror(cn, "missing transform"));
483 <                dobj_xform(nm, cn==DO_MOVE, na-nn, alist+nn);
481 >                if (cn == DO_MOVE && nn >= na) {
482 >                        cmderror(cn, "missing transform");
483 >                        return(0);
484 >                }
485 >                somechange += dobj_xform(nm, cn==DO_MOVE, na-nn, alist+nn);
486                  break;
487          case DO_UNMOVE:                         /* undo last transform */
488 <                dobj_unmove();
488 >                somechange += dobj_unmove();
489                  break;
490          case DO_OBJECT:                         /* print object statistics */
491 <                dobj_putstats(na ? alist[0] : curname, sstdout);
491 >                if (dobj_putstats(na ? alist[0] : curname, sstdout))
492 >                        if (na && alist[0][0] != '*' && (curobj == NULL ||
493 >                                        strcmp(alist[0], curobj->name)))
494 >                                savedxf(curobj = getdobj(alist[0]));
495                  break;
496          case DO_DUP:                            /* duplicate object */
497                  for (nn = 0; nn < na; nn++)
# Line 490 | Line 499 | register char  *args;
499                                  break;
500                  switch (nn) {
501                  case 0:
502 <                        return(cmderror(cn, "need new object name"));
502 >                        cmderror(cn, "need new object name");
503 >                        return(0);
504                  case 1:
505                          nm = curname;
506                          break;
# Line 503 | Line 513 | register char  *args;
513                  if (!dobj_dup(nm, alist[nn-1]))
514                          break;
515                  if (na > nn)
516 <                        dobj_xform(curname, 1, na-nn, alist+nn);
516 >                        somechange += dobj_xform(curname, 1, na-nn, alist+nn);
517                  else
518                          curobj->drawcode = DO_HIDE;
519 +                savedxf(curobj);
520                  break;
521          case DO_SHOW:                           /* change rendering option */
522          case DO_LIGHT:
523          case DO_HIDE:
524                  if (na > 1) goto toomany;
525                  dobj_lighting(na ? alist[0] : curname, cn);
526 +                somechange++;
527                  break;
528          default:
529                  error(CONSISTENCY, "bad command id in dobj_command");
530          }
531 <        dev_view(&odev.v);                      /* redraw */
520 <        return(cn);
531 >        return(somechange);
532   toomany:
533          return(cmderror(cn, "too many arguments"));
534   }
# Line 542 | Line 553 | char   *oct, *nam;
553                  error(COMMAND, "illegal name");
554                  return(0);
555          }
556 +        if (getdobj(nam) != NULL) {
557 +                error(COMMAND, "name already taken (clear first)");
558 +                return(0);
559 +        }
560                                          /* get octree path */
561          if ((fpp = getpath(oct, getlibpath(), R_OK)) == NULL) {
562                  sprintf(errmsg, "cannot find octree \"%s\"", oct);
# Line 549 | Line 564 | char   *oct, *nam;
564                  return(0);
565          }
566          strcpy(fpath, fpp);
552        freedobj(getdobj(nam));         /* free previous use of nam */
567          op = (DOBJECT *)malloc(sizeof(DOBJECT));
568          if (op == NULL)
569                  error(SYSTEM, "out of memory in dobj_load");
# Line 562 | Line 576 | char   *oct, *nam;
576          op->xfav[op->xfac=0] = NULL;
577                                          /* load octree into display list */
578          dolights = 0;
579 +        domats = 1;
580          op->listid = rgl_octlist(fpath, op->center, &op->radius);
581                                          /* start rtrace */
582          rtargv[RTARGC-1] = fpath;
# Line 605 | Line 620 | dobj_cleanup()                         /* free all resources */
620   }
621  
622  
623 < dobj_xform(nam, add, ac, av)            /* set/add transform for nam */
623 > dobj_xform(nam, rel, ac, av)            /* set/add transform for nam */
624   char    *nam;
625 < int     add, ac;
625 > int     rel, ac;
626   char    **av;
627   {
628          register DOBJECT        *op;
629 +        FVECT   cent;
630 +        double  rad;
631 +        char    scoord[16];
632 +        int     i;
633  
634          if ((op = getdobj(nam)) == NULL) {
635                  error(COMMAND, "no object");
636                  return(0);
637          }
638 <        if (add) add = op->xfac;
639 <        if (ac + add > MAXAC) {
638 >        if (rel)
639 >                rel = op->xfac + 8;
640 >        if (ac + rel > MAXAC) {
641                  error(COMMAND, "too many transform arguments");
642                  return(0);
643          }
644 <        savedxf(curobj = op);
645 <        if (!add)
644 >        savedxf(curobj = op);           /* remember current transform */
645 >        if (rel && ac == 4 && !strcmp(av[0], "-t"))
646 >                rel = -1;                       /* don't move for translate */
647 >        else {
648 >                getdcent(cent, op);             /* don't move if near orig. */
649 >                rad = getdrad(op);
650 >                if (DOT(cent,cent) < rad*rad)
651 >                        rel = -1;
652 >        }
653 >        if (!rel) {                             /* remove old transform */
654                  while (op->xfac)
655                          freestr(op->xfav[--op->xfac]);
656 +        } else if (rel > 0) {                   /* relative move */
657 +                op->xfav[op->xfac++] = savestr("-t");
658 +                for (i = 0; i < 3; i++) {
659 +                        sprintf(scoord, "%.4e", -cent[i]);
660 +                        op->xfav[op->xfac++] = savestr(scoord);
661 +                }
662 +        }
663          while (ac--)
664                  op->xfav[op->xfac++] = savestr(*av++);
665 +        if (rel > 0) {                          /* move back */
666 +                op->xfav[op->xfac++] = savestr("-t");
667 +                for (i = 0; i < 3; i++) {
668 +                        sprintf(scoord, "%.4e", cent[i]);
669 +                        op->xfav[op->xfac++] = savestr(scoord);
670 +                }
671 +        }
672          op->xfav[op->xfac] = NULL;
673          if (fullxf(&op->xfb, op->xfac, op->xfav) != op->xfac) {
674                  error(COMMAND, "bad transform arguments");
# Line 663 | Line 705 | FILE   *fp;
705                  return(0);
706          }
707          getdcent(ocent, op);
708 <        fprintf(fp, "%s: %s, center [%f %f %f], radius %f", op->name,
709 <                        op->drawcode==DO_HIDE ? "hid" :
710 <                        op->drawcode==DO_LIGHT && op->ol!=NULL ? "lit" :
708 >        fprintf(fp, "%s: %s, center [%g %g %g], radius %g", op->name,
709 >                        op->drawcode==DO_HIDE ? "hidden" :
710 >                        op->drawcode==DO_LIGHT && op->ol!=NULL ? "lighted" :
711                          "shown",
712                          ocent[0],ocent[1],ocent[2], getdrad(op));
713          if (op->xfac)
# Line 724 | Line 766 | char   *oldnm, *nam;
766                  error(COMMAND, "illegal name");
767                  return(0);
768          }
769 +        if (getdobj(nam) != NULL) {
770 +                error(COMMAND, "name already taken (clear first)");
771 +                return(0);
772 +        }
773                                          /* allocate and copy struct */
774          opdup = (DOBJECT *)malloc(sizeof(DOBJECT));
775          if (opdup == NULL)
# Line 763 | Line 809 | int    cn;
809          } else if ((op = getdobj(nam)) == NULL) {
810                  error(COMMAND, "unknown object");
811                  return(0);
812 <        } else if ((op->drawcode = cn) == DO_LIGHT)
813 <                getdlights(op, 1);
814 <        else
812 >        } else if ((op->drawcode = cn) == DO_LIGHT) {
813 >                if (!getdlights(op, 1))
814 >                        error(COMMAND, "insufficient samples to light object");
815 >        } else
816                  op->ol = NULL;
817  
818          if (dobj_lightsamp != NULL) {           /* restore beam set */
# Line 786 | Line 833 | FVECT   rorg, rdir;
833          register DOBJECT        *op;
834          FVECT   xorg, xdir;
835          double  darr[6];
836 <
836 >                                        /* check each visible object? */
837          if (nm == NULL || *nm == '*') {
838                  double  dist, mindist = 1.01*FHUGE;
839 <                                        /* check each visible object */
839 >
840 >                if (nm != NULL) nm[0] = '\0';
841                  for (op = dobjects; op != NULL; op = op->next) {
842                          if (op->drawcode == DO_HIDE)
843                                  continue;
844                          dist = dobj_trace(op->name, rorg, rdir);
845                          if (dist < mindist) {
846 <                                dist = mindist;
847 <                                if (nm != NULL)
800 <                                        strcpy(nm, op->name);
846 >                                if (nm != NULL) strcpy(nm, op->name);
847 >                                mindist = dist;
848                          }
849                  }
850                  return(mindist);
# Line 807 | Line 854 | FVECT   rorg, rdir;
854                  error(COMMAND, "unknown object");
855                  return(FHUGE);
856          }
857 <        if (op->xfac) {         /* transform ray */
857 >        if (op->xfac) {         /* put ray in local coordinates */
858                  multp3(xorg, rorg, op->xfb.b.xfm);
859                  multv3(xdir, rdir, op->xfb.b.xfm);
860                  VCOPY(darr, xorg); VCOPY(darr+3, xdir);
# Line 821 | Line 868 | FVECT   rorg, rdir;
868                                  /* return distance */
869          if (darr[0] >= .99*FHUGE)
870                  return(FHUGE);
871 <        return(darr[0] * op->xfb.f.sca);
871 >        return(darr[0]*op->xfb.f.sca);
872   }
873  
874  
875 + int
876   dobj_render()                   /* render our objects in OpenGL */
877   {
878 +        int     nrendered = 0;
879          GLboolean       normalizing;
880          GLfloat vec[4];
881          FVECT   v1;
# Line 837 | Line 886 | dobj_render()                  /* render our objects in OpenGL */
886                  if (op->drawcode != DO_HIDE)
887                          break;
888          if (op == NULL)
889 <                return(1);
889 >                return(0);
890                                          /* set up general rendering params */
891          glGetBooleanv(GL_NORMALIZE, &normalizing);
892 <        glPushAttrib(GL_LIGHTING_BIT|GL_TRANSFORM_BIT|
893 <                        GL_DEPTH_BUFFER_BIT|GL_POLYGON_BIT);
892 >        glPushAttrib(GL_LIGHTING_BIT|GL_TRANSFORM_BIT|GL_ENABLE_BIT|
893 >                GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_POLYGON_BIT);
894          glDepthFunc(GL_LESS);
895          glEnable(GL_DEPTH_TEST);
896          glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
# Line 887 | Line 936 | dobj_render()                  /* render our objects in OpenGL */
936                                  glLightfv(glightid[i], GL_AMBIENT, vec);
937                                  glEnable(glightid[i]);
938                          }
939 <                } else {                        /* no sources to draw on */
939 >                } else {                        /* fake lighting */
940                          vec[0] = vec[1] = vec[2] = 0.; vec[3] = 1.;
941                          glLightModelfv(GL_LIGHT_MODEL_AMBIENT, vec);
942                          getdcent(v1, op);
# Line 923 | Line 972 | dobj_render()                  /* render our objects in OpenGL */
972                  }
973                                          /* render the display list */
974                  glCallList(op->listid);
975 +                nrendered++;
976                                          /* restore matrix */
977                  if (op->xfac) {
978                          glMatrixMode(GL_MODELVIEW);
# Line 937 | Line 987 | dobj_render()                  /* render our objects in OpenGL */
987                  else
988                          glDisable(GL_LIGHT0);
989                                          /* check errors */
940                rgl_checkerr("rendering object in dobj_render");
990          }
991          glPopAttrib();                  /* restore rendering params */
992 <        return(1);
992 >        rgl_checkerr("rendering objects in dobj_render");
993 >        return(nrendered);
994   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines