ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/util/ranimove.c
Revision: 3.12
Committed: Tue Sep 28 17:54:19 2004 UTC (20 years ago) by greg
Content type: text/plain
Branch: MAIN
CVS Tags: rad3R7P2, rad3R7P1, rad3R6, rad3R6P1, rad3R8, rad3R9
Changes since 3.11: +1 -1 lines
Log Message:
Fixed messed-up RCCS Id at top of file

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