ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/util/ranimove.c
Revision: 3.3
Committed: Mon Mar 10 17:26:26 2003 UTC (21 years ago) by greg
Content type: text/plain
Branch: MAIN
CVS Tags: rad3R5
Changes since 3.2: +2 -1 lines
Log Message:
Compile fixes for Linux

File Contents

# Content
1 #ifndef lint
2 static const char RCSid[] = "$Id";
3 #endif
4 /*
5 * Radiance object animation program
6 *
7 * Main program and control file handling.
8 *
9 * See ranimove.h and the ranimove(1) man page for details.
10 */
11
12 #include "copyright.h"
13
14 #include "ranimove.h"
15 #include <time.h>
16 #include <sys/time.h>
17 #include <ctype.h>
18
19 int NVARS = NV_INIT; /* total number of variables */
20
21 VARIABLE vv[] = VV_INIT; /* variable-value pairs */
22
23 extern int nowarn; /* don't report warnings? */
24 int silent = 0; /* run silently? */
25
26 int quickstart = 0; /* time initial frame as well? */
27
28 int nprocs = 1; /* number of rendering processes */
29
30 int rtperfrm = 60; /* seconds to spend per frame */
31
32 double ndthresh = 2.; /* noticeable difference threshold */
33 int ndtset = 0; /* user threshold -- stop when reached? */
34
35 int fbeg = 1; /* starting frame */
36 int fend = 0; /* ending frame */
37 int fcur; /* current frame being rendered */
38
39 char lorendoptf[32]; /* low quality options file */
40 RAYPARAMS lorendparams; /* low quality rendering parameters */
41 char hirendoptf[32]; /* high quality options file */
42 RAYPARAMS hirendparams; /* high quality rendering parameters */
43 RAYPARAMS *curparams; /* current parameter settings */
44 int twolevels; /* low and high quality differ */
45
46 double mblur; /* vflt(MBLUR) */
47 double rate; /* vflt(RATE) */
48
49 char objtmpf[32]; /* object temporary file */
50
51 struct ObjMove *obj_move; /* object movements */
52
53 int haveprio = 0; /* high-level saliency specified */
54
55 int gargc; /* global argc for printargs */
56 char **gargv; /* global argv for printargs */
57
58
59 int
60 main(argc, argv)
61 int argc;
62 char *argv[];
63 {
64 int explicate = 0;
65 char *cfname;
66 int i;
67
68 progname = argv[0]; /* get arguments */
69 gargc = argc;
70 gargv = argv;
71 for (i = 1; i < argc && argv[i][0] == '-'; i++)
72 switch (argv[i][1]) {
73 case 't': /* seconds per frame */
74 rtperfrm = atoi(argv[++i]);
75 break;
76 case 'd': /* noticeable difference */
77 ndthresh = atof(argv[++i]);
78 ndtset = 1;
79 break;
80 case 'e': /* print variables */
81 explicate++;
82 break;
83 case 's': /* silent running */
84 silent++;
85 break;
86 case 'q': /* start quickly */
87 quickstart++;
88 break;
89 case 'w': /* turn off warnings */
90 nowarn++;
91 break;
92 case 'f': /* frame range */
93 switch (sscanf(argv[++i], "%d,%d", &fbeg, &fend)) {
94 case 2:
95 if ((fbeg <= 0 | fend < fbeg))
96 goto userr;
97 break;
98 case 1:
99 if (fbeg <= 0)
100 goto userr;
101 fend = 0;
102 break;
103 default:
104 goto userr;
105 }
106 break;
107 case 'n': /* number of processes */
108 nprocs = atoi(argv[++i]);
109 break;
110 default:
111 goto userr;
112 }
113 if (rtperfrm <= 0) {
114 if (!ndtset)
115 error(USER, "specify -d jnd with -t 0");
116 rtperfrm = 7*24*3600;
117 }
118 if (i != argc-1)
119 goto userr;
120 cfname = argv[i];
121 /* load variables */
122 loadvars(cfname);
123 /* check variables */
124 checkvalues();
125 /* load RIF if any */
126 if (vdef(RIF))
127 getradfile(vval(RIF));
128 /* set defaults */
129 setdefaults();
130 /* print variables */
131 if (explicate)
132 printvars(stdout);
133 /* run animation */
134 if (nprocs > 0)
135 animate();
136 /* all done */
137 if (lorendoptf[0])
138 unlink(lorendoptf);
139 if (hirendoptf[0])
140 unlink(hirendoptf);
141 if (objtmpf[0])
142 unlink(objtmpf);
143 return(0);
144 userr:
145 fprintf(stderr,
146 "Usage: %s [-n nprocs][-f beg,end][-t sec][-d jnd][-s][-w][-e] anim_file\n",
147 progname);
148 quit(1);
149 }
150
151
152 void
153 eputs(s) /* put string to stderr */
154 register char *s;
155 {
156 static int midline = 0;
157
158 if (!*s)
159 return;
160 if (!midline++) {
161 fputs(progname, stderr);
162 fputs(": ", stderr);
163 }
164 fputs(s, stderr);
165 if (s[strlen(s)-1] == '\n') {
166 fflush(stderr);
167 midline = 0;
168 }
169 }
170
171
172 void
173 setdefaults() /* set default values */
174 {
175 int nviews;
176 int decades;
177 char buf[256];
178 int i;
179
180 if (!vdef(OCTREEF)) {
181 sprintf(errmsg, "%s or %s must be defined",
182 vnam(OCTREEF), vnam(RIF));
183 error(USER, errmsg);
184 }
185 if (!vdef(VIEWFILE)) {
186 sprintf(errmsg, "%s must be defined", vnam(VIEWFILE));
187 error(USER, errmsg);
188 }
189 nviews = countviews();
190 if (!nviews)
191 error(USER, "no views in view file");
192 if (!vdef(END)) {
193 if (nviews == 1) {
194 sprintf(errmsg, "%s must be defined for single view",
195 vnam(END));
196 error(USER, errmsg);
197 }
198 sprintf(buf, "%d", nviews);
199 vval(END) = savqstr(buf);
200 vdef(END)++;
201 }
202 if (!fend)
203 fend = vint(END);
204 if (fbeg > fend)
205 error(USER, "begin after end");
206 if (!vdef(BASENAME)) {
207 decades = (int)log10((double)vint(END)) + 1;
208 if (decades < 3) decades = 3;
209 sprintf(buf, "frame%%0%dd", decades);
210 vval(BASENAME) = savqstr(buf);
211 vdef(BASENAME)++;
212 }
213 if (!vdef(RATE)) {
214 vval(RATE) = "8";
215 vdef(RATE)++;
216 }
217 rate = vflt(RATE);
218 if (!vdef(RESOLUTION)) {
219 vval(RESOLUTION) = "640";
220 vdef(RESOLUTION)++;
221 }
222 if (!vdef(MBLUR)) {
223 vval(MBLUR) = "0";
224 vdef(MBLUR)++;
225 }
226 mblur = vflt(MBLUR);
227 if (mblur > 1.)
228 mblur = 1.;
229 /* set up objects */
230 if (vdef(MOVE)) {
231 obj_move = (struct ObjMove *)malloc(
232 sizeof(struct ObjMove)*vdef(MOVE) );
233 if (obj_move == NULL)
234 error(SYSTEM, "out of memory in setdefaults");
235 for (i = 0; i < vdef(MOVE); i++)
236 setmove(&obj_move[i], nvalue(MOVE, i));
237 }
238 /* set up high quality options */
239 setrendparams(hirendoptf, vval(HIGHQ));
240 ray_save(&hirendparams);
241 /* set up low quality options */
242 setrendparams(lorendoptf, vval(LOWQ));
243 ray_save(&lorendparams);
244 curparams = &lorendparams;
245 twolevels = bcmp(&lorendparams, &hirendparams, sizeof(RAYPARAMS));
246 }
247
248
249 void
250 setmove(om, ms) /* assign a move object from spec. */
251 struct ObjMove *om;
252 char *ms;
253 {
254 char parname[128];
255 char *cp;
256
257 ms = nextword(parname, sizeof(parname), ms);
258 if (!parname[0])
259 goto badspec;
260 for (cp = parname; *cp; cp++)
261 if (isspace(*cp))
262 *cp = '_';
263 for (om->parent = (om - obj_move); om->parent--; )
264 if (!strcmp(parname, obj_move[om->parent].name))
265 break;
266 if (om->parent < 0 &&
267 strcmp(parname, ".") && strcmp(parname, VOIDID)) {
268 sprintf(errmsg, "undefined parent object '%s'", parname);
269 error(USER, errmsg);
270 }
271 ms = nextword(om->name, sizeof(om->name), ms);
272 if (!om->name[0])
273 goto badspec;
274 for (cp = om->name; *cp; cp++)
275 if (isspace(*cp))
276 *cp = '_';
277 ms = nextword(om->xf_file, sizeof(om->xf_file), ms);
278 if (!strcmp(om->xf_file, "."))
279 om->xf_file[0] = '\0';
280 if (!om->xf_file[0]) {
281 om->xfs[0] = '\0';
282 } else if (om->xf_file[0] == '-') {
283 strcpy(om->xfs, om->xf_file);
284 om->xf_file[0] = '\0';
285 }
286 ms = nextword(om->spec, sizeof(om->spec), ms);
287 if (om->spec[0]) {
288 if (!strcmp(om->spec, ".") || !strcmp(om->spec, VOIDID))
289 om->spec[0] = '\0';
290 ms = nextword(om->prio_file, sizeof(om->prio_file), ms);
291 } else
292 om->prio_file[0] = '\0';
293 if (om->prio_file[0]) {
294 if (isflt(om->prio_file)) {
295 om->prio = atof(om->prio_file);
296 om->prio_file[0] = '\0';
297 haveprio |= (om->prio < 0.95 | om->prio > 1.05);
298 } else
299 haveprio = 1;
300 } else
301 om->prio = 1.;
302 om->cfm = -1;
303 return;
304 badspec:
305 error(USER, "bad object specification");
306 }
307
308
309 void
310 setrendparams(optf, qval) /* set global rendering parameters */
311 char *optf;
312 char *qval;
313 {
314 char *argv[1024];
315 char **av = argv;
316 int ac, i, rval;
317
318 av[ac=0] = NULL;
319 /* load options from file, first */
320 if (optf != NULL && *optf) {
321 ac = wordfile(av, optf);
322 if (ac < 0) {
323 sprintf(errmsg, "cannot load options file \"%s\"",
324 optf);
325 error(SYSTEM, errmsg);
326 }
327 }
328 /* then from options string */
329 if (qval != NULL && qval[0] == '-')
330 ac += wordstring(av+ac, qval);
331
332 /* start with default parameters */
333 ray_defaults(NULL);
334 /* set what we have */
335 for (i = 0; i < ac; i++) {
336 while ((rval = expandarg(&ac, &av, i)) > 0)
337 ;
338 if (rval < 0) {
339 sprintf(errmsg, "cannot expand '%s'", av[i]);
340 error(SYSTEM, errmsg);
341 }
342 if (!strcmp(av[i], "-w")) {
343 nowarn++;
344 continue;
345 }
346 rval = getrenderopt(ac-i, av+i);
347 if (rval >= 0) {
348 i += rval;
349 continue;
350 }
351 sprintf(errmsg, "bad render option at '%s'", av[i]);
352 error(USER, errmsg);
353 }
354 }
355
356
357 void
358 getradfile(rfargs) /* run rad and get needed variables */
359 char *rfargs;
360 {
361 static short mvar[] = {OCONV,OCTREEF,RESOLUTION,EXPOSURE,-1};
362 char combuf[256];
363 register int i;
364 register char *cp;
365 char *pippt;
366 /* create rad command */
367 strcpy(lorendoptf, "ranim0.opt");
368 sprintf(combuf,
369 "rad -v 0 -s -e -w %s %s oconv=-f OPTFILE=%s | egrep '^[ \t]*(NOMATCH",
370 rfargs,
371 (vdef(LOWQ) && vval(LOWQ)[0]!='-') ? vval(LOWQ) : "",
372 lorendoptf);
373 cp = combuf;
374 while (*cp) {
375 if (*cp == '|') pippt = cp;
376 cp++;
377 } /* match unset variables */
378 for (i = 0; mvar[i] >= 0; i++)
379 if (!vdef(mvar[i])) {
380 *cp++ = '|';
381 strcpy(cp, vnam(mvar[i]));
382 while (*cp) cp++;
383 pippt = NULL;
384 }
385 if (pippt != NULL)
386 strcpy(pippt, "> /dev/null"); /* nothing to match */
387 else {
388 strcpy(cp, ")[ \t]*=' > ranimove.var");
389 cp += 11; /* point to file name */
390 }
391 system(combuf); /* ignore exit code */
392 if (pippt == NULL) { /* load variables and remove file */
393 loadvars(cp);
394 unlink(cp);
395 }
396 if (!vdef(HIGHQ) || vval(HIGHQ)[0]=='-') {
397 strcpy(hirendoptf, lorendoptf);
398 return;
399 }
400 /* get high quality options */
401 strcpy(hirendoptf, "ranim1.opt");
402 sprintf(combuf, "rad -v 0 -s -w %s %s OPTFILE=%s",
403 rfargs, vval(HIGHQ), hirendoptf);
404 system(combuf);
405 }
406
407
408 void
409 animate() /* run through animation */
410 {
411 int rpass;
412
413 if (fbeg > 1) /* synchronize transforms */
414 getoctspec(fbeg-1);
415
416 for (fcur = fbeg; fcur <= fend; fcur++) {
417 if (!silent)
418 printf("Frame %d:\n", fcur);
419 /* base rendering */
420 init_frame();
421 /* refinement */
422 for (rpass = 0; refine_frame(rpass); rpass++)
423 ;
424 /* final filter pass */
425 filter_frame();
426 /* output frame */
427 send_frame();
428 }
429 /* free resources */
430 free_frame();
431 if (nprocs > 1)
432 ray_pdone(1);
433 else
434 ray_done(1);
435 getview(0);
436 getexp(0);
437 }
438
439
440 VIEW *
441 getview(n) /* get view number n */
442 int n;
443 {
444 static FILE *viewfp = NULL; /* view file pointer */
445 static int viewnum = 0; /* current view number */
446 static VIEW curview = STDVIEW; /* current view */
447 char linebuf[256];
448
449 if (n == 0) { /* signal to close file and clean up */
450 if (viewfp != NULL) {
451 fclose(viewfp);
452 viewfp = NULL;
453 viewnum = 0;
454 copystruct(&curview, &stdview);
455 }
456 return(NULL);
457 }
458 if (viewfp == NULL) { /* open file */
459 if ((viewfp = fopen(vval(VIEWFILE), "r")) == NULL) {
460 perror(vval(VIEWFILE));
461 quit(1);
462 }
463 } else if (n > 0 && n < viewnum) { /* rewind file */
464 if (viewnum == 1 && feof(viewfp))
465 return(&curview); /* just one view */
466 if (fseek(viewfp, 0L, 0) == EOF) {
467 perror(vval(VIEWFILE));
468 quit(1);
469 }
470 copystruct(&curview, &stdview);
471 viewnum = 0;
472 }
473 if (n < 0) { /* get next view */
474 register int c = getc(viewfp);
475 if (c == EOF)
476 return(NULL); /* that's it */
477 ungetc(c, viewfp);
478 n = viewnum + 1;
479 }
480 while (n > viewnum) { /* scan to desired view */
481 if (fgets(linebuf, sizeof(linebuf), viewfp) == NULL)
482 return(viewnum==1 ? &curview : (VIEW *)NULL);
483 if (isview(linebuf) && sscanview(&curview, linebuf) > 0)
484 viewnum++;
485 }
486 return(&curview); /* return it */
487 }
488
489
490 int
491 countviews() /* count views in view file */
492 {
493 int n;
494
495 if (getview(n=1) == NULL)
496 return(0);
497 while (getview(-1) != NULL)
498 n++;
499 return(n);
500 }
501
502
503 char *
504 getexp(n) /* get exposure for nth frame */
505 int n;
506 {
507 extern char *fskip();
508 static char expval[32];
509 static FILE *expfp = NULL;
510 static int curfrm = 0;
511 register char *cp;
512
513 if (n == 0) { /* signal to close file */
514 if (expfp != NULL) {
515 fclose(expfp);
516 expfp = NULL;
517 }
518 return(NULL);
519 }
520 if (!vdef(EXPOSURE)) /* no setting (auto) */
521 return(NULL);
522 if (isflt(vval(EXPOSURE))) /* always the same */
523 return(vval(EXPOSURE));
524 if (expfp == NULL) { /* open exposure file */
525 if ((expfp = fopen(vval(EXPOSURE), "r")) == NULL) {
526 sprintf(errmsg, "cannot open exposure file \"%s\"",
527 vval(EXPOSURE));
528 error(SYSTEM, errmsg);
529 }
530 curfrm = 0;
531 }
532 if (curfrm > n) { /* rewind if necessary */
533 rewind(expfp);
534 curfrm = 0;
535 }
536 while (n > curfrm) { /* read to line */
537 if (fgets(expval, sizeof(expval), expfp) == NULL) {
538 sprintf(errmsg, "%s: too few exposures",
539 vval(EXPOSURE));
540 error(USER, errmsg);
541 }
542 if (strlen(expval) == sizeof(expval)-1)
543 goto formerr;
544 curfrm++;
545 }
546 cp = fskip(expval); /* check format */
547 if (cp != NULL)
548 while (isspace(*cp))
549 *cp++ = '\0';
550 if (cp == NULL || *cp)
551 goto formerr;
552 return(expval); /* return value */
553 formerr:
554 sprintf(errmsg, "%s: exposure format error on line %d",
555 vval(EXPOSURE), curfrm);
556 error(USER, errmsg);
557 }
558
559
560 double
561 expspec_val(s) /* get exposure value from spec. */
562 char *s;
563 {
564 double expval;
565
566 if (s == NULL || !*s)
567 return(1.0);
568
569 expval = atof(s);
570 if ((s[0] == '+' | s[0] == '-'))
571 return(pow(2.0, expval));
572 return(expval);
573 }
574
575
576 char *
577 getoctspec(n) /* get octree for the given frame */
578 int n;
579 {
580 static char combuf[1024];
581 int cfm = 0;
582 int uses_inline;
583 FILE *fp;
584 int i;
585 /* is octree static? */
586 if (!vdef(MOVE))
587 return(vval(OCTREEF));
588 /* done already */
589 if (n == cfm)
590 return(combuf);
591 /* else create object file */
592 strcpy(objtmpf, "movinobj.rad");
593 fp = fopen(objtmpf, "w");
594 if (fp == NULL) {
595 sprintf(errmsg, "cannot write to moving objects file '%s'",
596 objtmpf);
597 error(SYSTEM, errmsg);
598 }
599 uses_inline = 0;
600 for (i = 0; i < vdef(MOVE); i++) {
601 int inlc = (obj_move[i].spec[0] == '!');
602 if (!obj_move[i].spec[0])
603 continue;
604 if (inlc)
605 fprintf(fp, "%s %d \\\n\t| xform",
606 obj_move[i].spec, n);
607 else
608 fputs("!xform", fp);
609 fprintf(fp, " -n %s", getobjname(&obj_move[i]));
610 fputs(getxf(&obj_move[i], n), fp);
611 if (!inlc)
612 fprintf(fp, " %s\n", obj_move[i].spec);
613 else
614 fputc('\n', fp);
615 uses_inline |= inlc;
616 }
617 if (fclose(fp) == EOF)
618 error(SYSTEM, "error writing moving objects file");
619 if (uses_inline)
620 sprintf(combuf, "!oconv %s -f -i '%s' %s",
621 vdef(OCONV) ? vval(OCONV) : "",
622 vval(OCTREEF), objtmpf);
623 else
624 sprintf(combuf, "!xform -f %s | oconv -f -i '%s' -",
625 objtmpf, vval(OCTREEF));
626 return(combuf);
627 }
628
629
630 char *
631 getobjname(om) /* get fully qualified object name */
632 register struct ObjMove *om;
633 {
634 static char objName[512];
635 register char *cp = objName;
636
637 strcpy(cp, om->name);
638 while (om->parent >= 0) {
639 while (*cp) cp++;
640 *cp++ = '@';
641 om = &obj_move[om->parent];
642 strcpy(cp, om->name);
643 }
644 return(objName);
645 }
646
647
648 char *
649 getxf(om, n) /* get total transform for object */
650 register struct ObjMove *om;
651 int n;
652 {
653 static char xfsbuf[4096];
654 char *xfp;
655 int framestep = 0;
656 XF oxf;
657 FILE *fp;
658 char abuf[512];
659 char *av[64];
660 int ac;
661 int i;
662 register char *cp;
663 /* get parent transform, first */
664 if (om->parent >= 0)
665 xfp = getxf(&obj_move[om->parent], n);
666 else
667 *(xfp = xfsbuf + sizeof(xfsbuf)-1) = '\0';
668 /* get transform spec. & priority */
669 if (om->cfm != n) {
670 if (om->xf_file[0]) {
671 fp = fopen(om->xf_file, "r");
672 if (fp == NULL) {
673 sprintf(errmsg,
674 "cannot open transform file '%s'",
675 om->xf_file);
676 error(SYSTEM, errmsg);
677 }
678 for (i = 0; i < n; i++)
679 if (fgetline(om->xfs, sizeof(om->xfs), fp)
680 == NULL) {
681 sprintf(errmsg,
682 "too few transforms in file '%s'",
683 om->xf_file);
684 error(USER, errmsg);
685 }
686 fclose(fp);
687 }
688 strcpy(cp=abuf, om->xfs);
689 ac = 0;
690 for ( ; ; ) {
691 while (isspace(*cp))
692 *cp++ = '\0';
693 if (!*cp)
694 break;
695 av[ac++] = cp;
696 while (*++cp && !isspace(*cp))
697 ;
698 }
699 av[ac] = NULL;
700 if (xf(&oxf, ac, av) != ac ||
701 fabs(oxf.sca) <= FTINY) {
702 sprintf(errmsg, "bad transform args: %s",
703 om->xfs);
704 error(USER, errmsg);
705 }
706 copymat4(om->xfm, oxf.xfm);
707 if (om->prio_file[0]) {
708 fp = fopen(om->prio_file, "r");
709 if (fp == NULL) {
710 sprintf(errmsg,
711 "cannot open priority file '%s'",
712 om->prio_file);
713 error(SYSTEM, errmsg);
714 }
715 for (i = 0; i < n; i++)
716 if (fgets(abuf, sizeof(abuf), fp)
717 == NULL) {
718 sprintf(errmsg,
719 "too few priorities in file '%s'",
720 om->prio_file);
721 error(USER, errmsg);
722 }
723 fclose(fp);
724 cp = fskip(abuf);
725 if (cp != NULL)
726 while (isspace(*cp))
727 *cp++ = '\0';
728 if (cp == NULL || *cp) {
729 sprintf(errmsg,
730 "priority '%s' in file '%s' not a number",
731 abuf, om->prio_file);
732 error(USER, errmsg);
733 }
734 om->prio = atof(abuf);
735 }
736 framestep = (n == om->cfm + 1);
737 om->cfm = n;
738 }
739 /* prepend to parent transform */
740 if (om->xfs[0]) {
741 i = strlen(om->xfs);
742 if (xfp - i <= xfsbuf)
743 error(INTERNAL, "transform too long in getxf");
744 cp = om->xfs + i;
745 while (i--)
746 *--xfp = *--cp;
747 *--xfp = ' ';
748 }
749 if (framestep)
750 copymat4(oxf.xfm, om->cxfm);
751 if (om->parent >= 0) {
752 multmat4(om->cxfm, om->xfm, obj_move[om->parent].cxfm);
753 om->cprio = obj_move[om->parent].cprio * om->prio;
754 } else {
755 copymat4(om->cxfm, om->xfm);
756 om->cprio = om->prio;
757 }
758 /* XXX bxfm relies on call order */
759 if (framestep)
760 if (invmat4(om->bxfm, om->cxfm))
761 multmat4(om->bxfm, om->bxfm, oxf.xfm);
762 else
763 setident4(om->bxfm);
764 /* all done */
765 return(xfp);
766 }
767
768
769 int
770 getmove(obj) /* find matching move object */
771 OBJECT obj;
772 {
773 static int lasti;
774 static OBJECT lasto = OVOID;
775 char *onm, *objnm;
776 int len, len2;
777 register int i;
778
779 if (obj == OVOID)
780 return(-1);
781 if (obj == lasto)
782 return(lasti);
783 /* look for matching object */
784 onm = objptr(obj)->oname;
785 for (i = vdef(MOVE); i--; ) {
786 objnm = obj_move[i].name;
787 len = strlen(objnm);
788 if (!strncmp(onm, objnm, len)) {
789 if ((obj_move[i].parent < 0 & onm[len] == '.'))
790 break;
791 objnm = getobjname(&obj_move[i]) + len;
792 len2 = strlen(objnm);
793 if (!strncmp(onm+len, objnm, len2) && onm[len+len2] == '.')
794 break;
795 }
796 }
797 lasto = obj; /* cache what we found */
798 return(lasti = i);
799 }
800
801
802 double
803 obj_prio(obj) /* return priority for object */
804 OBJECT obj;
805 {
806 int moi;
807
808 if (obj == OVOID || (moi = getmove(obj)) < 0)
809 return(1.0);
810 return(obj_move[moi].cprio);
811 }
812
813
814 double
815 getTime() /* get current time (CPU or real) */
816 {
817 struct timeval time_now;
818 /* return CPU time if one process */
819 if (nprocs == 1)
820 return((double)clock()*(1.0/(double)CLOCKS_PER_SEC));
821 /* otherwise, return wall time */
822 gettimeofday(&time_now, NULL);
823 return((double)time_now.tv_sec + 1e-6*(double)time_now.tv_usec);
824 }