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

Comparing ray/src/cv/mgflib/xf.c (file contents):
Revision 1.4 by greg, Sat Jun 25 16:33:19 1994 UTC vs.
Revision 1.14 by greg, Fri Feb 28 20:11:30 2003 UTC

# Line 1 | Line 1
1 /* Copyright (c) 1994 Regents of the University of California */
2
1   #ifndef lint
2 < static char SCCSid[] = "$SunId$ LBL";
2 > static const char       RCSid[] = "$Id$";
3   #endif
6
4   /*
5   * Routines for 4x4 homogeneous, rigid-body transformations
6   */
7  
8   #include <stdio.h>
9   #include <math.h>
10 + #include <stdlib.h>
11   #include <string.h>
12   #include "parser.h"
13  
# Line 21 | Line 19 | MAT4  m4ident = MAT4IDENT;
19  
20   static MAT4  m4tmp;             /* for efficiency */
21  
22 < int     xf_argc;                        /* total # transform args. */
23 < char    **xf_argv;                      /* transform arguments */
24 < XF_SPEC *xf_context;                    /* current context */
22 > XF_SPEC *xf_context = NULL;     /* current context */
23 > char    **xf_argend;            /* end of transform argument list */
24 > static char     **xf_argbeg;    /* beginning of transform argument list */
25  
28 static int      xf_maxarg;              /* # allocated arguments */
26  
30
27   int
28   xf_handler(ac, av)              /* handle xf entity */
29   int     ac;
30   char    **av;
31   {
36 #define randshift(x,n)  ((long)(x) << shifttab[(n)&63])
37        static char     shifttab[64] = { 15, 5, 11, 5, 6, 3,
38                                9, 15, 13, 2, 13, 5, 2, 12, 14, 11,
39                                11, 12, 12, 3, 2, 11, 8, 12, 1, 12,
40                                5, 4, 15, 9, 14, 5, 13, 14, 2, 10,
41                                10, 14, 12, 3, 5, 5, 14, 6, 12, 11,
42                                13, 9, 12, 8, 1, 6, 5, 12, 7, 13,
43                                15, 8, 9, 2, 6, 11, 9, 11 };
44        register int    i;
32          register XF_SPEC        *spec;
33 <        XF      thisxf;
33 >        register int    n;
34 >        int     rv;
35  
36 <        if (ac == 1) {                  /* pop top transform */
36 >        if (ac == 1) {                  /* something with existing transform */
37                  if ((spec = xf_context) == NULL)
38 <                        return(MG_OK);          /* should be error? */
39 <                while (xf_argc > spec->xav0)
40 <                        free((MEM_PTR)xf_argv[--xf_argc]);
41 <                xf_argv[xf_argc] = NULL;
42 <                xf_context = spec->prev;
43 <                free((MEM_PTR)spec);
44 <                return(MG_OK);
38 >                        return(MG_ECNTXT);
39 >                n = -1;
40 >                if (spec->xarr != NULL) {       /* check for iteration */
41 >                        register struct xf_array        *ap = spec->xarr;
42 >
43 >                        (void)xf_aname((struct xf_array *)NULL);
44 >                        n = ap->ndim;
45 >                        while (n--) {
46 >                                if (++ap->aarg[n].i < ap->aarg[n].n)
47 >                                        break;
48 >                                (void)strcpy(ap->aarg[n].arg, "0");
49 >                                ap->aarg[n].i = 0;
50 >                        }
51 >                        if (n >= 0) {
52 >                                if ((rv = mg_fgoto(&ap->spos)) != MG_OK)
53 >                                        return(rv);
54 >                                sprintf(ap->aarg[n].arg, "%d", ap->aarg[n].i);
55 >                                (void)xf_aname(ap);
56 >                        }
57 >                }
58 >                if (n < 0) {                    /* pop transform */
59 >                        xf_context = spec->prev;
60 >                        free_xf(spec);
61 >                        return(MG_OK);
62 >                }
63 >        } else {                        /* else allocate transform */
64 >                if ((spec = new_xf(ac-1, av+1)) == NULL)
65 >                        return(MG_EMEM);
66 >                if (spec->xarr != NULL)
67 >                        (void)xf_aname(spec->xarr);
68 >                spec->prev = xf_context;        /* push onto stack */
69 >                xf_context = spec;
70          }
71                                          /* translate new specification */
72 <        if (xf(&thisxf, ac-1, av+1) != ac-1)
72 >        n = xf_ac(spec);
73 >        n -= xf_ac(spec->prev);         /* incremental comp. is more eff. */
74 >        if (xf(&spec->xf, n, xf_av(spec)) != n)
75                  return(MG_ETYPE);
76 <                                        /* allocate space for new transform */
77 <        spec = (XF_SPEC *)malloc(sizeof(XF_SPEC));
76 >                                        /* check for vertex reversal */
77 >        if ((spec->rev = (spec->xf.sca < 0.)))
78 >                spec->xf.sca = -spec->xf.sca;
79 >                                        /* compute total transformation */
80 >        if (spec->prev != NULL) {
81 >                multmat4(spec->xf.xfm, spec->xf.xfm, spec->prev->xf.xfm);
82 >                spec->xf.sca *= spec->prev->xf.sca;
83 >                spec->rev ^= spec->prev->rev;
84 >        }
85 >        spec->xid = comp_xfid(spec->xf.xfm);    /* compute unique ID */
86 >        return(MG_OK);
87 > }
88 >
89 >
90 > XF_SPEC *
91 > new_xf(ac, av)                  /* allocate new transform structure */
92 > int     ac;
93 > char    **av;
94 > {
95 >        register XF_SPEC        *spec;
96 >        register int    i;
97 >        char    *cp;
98 >        int     n, ndim;
99 >
100 >        ndim = 0;
101 >        n = 0;                          /* compute space req'd by arguments */
102 >        for (i = 0; i < ac; i++)
103 >                if (!strcmp(av[i], "-a")) {
104 >                        ndim++;
105 >                        i++;
106 >                } else
107 >                        n += strlen(av[i]) + 1;
108 >        if (ndim > XF_MAXDIM)
109 >                return(NULL);
110 >        spec = (XF_SPEC *)malloc(sizeof(XF_SPEC) + n);
111          if (spec == NULL)
112 <                return(MG_EMEM);
113 <        spec->xav0 = xf_argc;
114 <        spec->xac = ac-1;
112 >                return(NULL);
113 >        if (ndim) {
114 >                spec->xarr = (struct xf_array *)malloc(sizeof(struct xf_array));
115 >                if (spec->xarr == NULL)
116 >                        return(NULL);
117 >                mg_fgetpos(&spec->xarr->spos);
118 >                spec->xarr->ndim = 0;           /* incremented below */
119 >        } else
120 >                spec->xarr = NULL;
121 >        spec->xac = ac + xf_argc;
122                                          /* and store new xf arguments */
123 <        if (xf_argc+ac > xf_maxarg) {
124 <                if (!xf_maxarg)
125 <                        xf_argv = (char **)malloc(
126 <                                        (xf_maxarg=ac)*sizeof(char *));
127 <                else
128 <                        xf_argv = (char **)realloc((MEM_PTR)xf_argv,
129 <                                        (xf_maxarg+=ac)*sizeof(char *));
130 <                if (xf_argv == NULL)
131 <                        return(MG_EMEM);
123 >        if (xf_argbeg == NULL || xf_av(spec) < xf_argbeg) {
124 >                register char   **newav =
125 >                                (char **)malloc((spec->xac+1)*sizeof(char *));
126 >                if (newav == NULL)
127 >                        return(NULL);
128 >                for (i = xf_argc; i-- > 0; )
129 >                        newav[ac+i] = xf_argend[i-xf_context->xac];
130 >                *(xf_argend = newav + spec->xac) = NULL;
131 >                if (xf_argbeg != NULL)
132 >                        free((MEM_PTR)xf_argbeg);
133 >                xf_argbeg = newav;
134          }
135 <        for (i = 0; i < ac-1; i++) {
136 <                xf_argv[xf_argc] = (char *)malloc(strlen(av[i+1])+1);
137 <                if (xf_argv[xf_argc] == NULL)
138 <                        return(MG_EMEM);
139 <                strcpy(xf_argv[xf_argc++], av[i+1]);
135 >        cp = (char *)(spec + 1);        /* use memory allocated above */
136 >        for (i = 0; i < ac; i++)
137 >                if (!strcmp(av[i], "-a")) {
138 >                        xf_av(spec)[i++] = "-i";
139 >                        xf_av(spec)[i] = strcpy(
140 >                                        spec->xarr->aarg[spec->xarr->ndim].arg,
141 >                                        "0");
142 >                        spec->xarr->aarg[spec->xarr->ndim].i = 0;
143 >                        spec->xarr->aarg[spec->xarr->ndim++].n = atoi(av[i]);
144 >                } else {
145 >                        xf_av(spec)[i] = strcpy(cp, av[i]);
146 >                        cp += strlen(av[i]) + 1;
147 >                }
148 >        return(spec);
149 > }
150 >
151 >
152 > void
153 > free_xf(spec)                   /* free a transform */
154 > register XF_SPEC        *spec;
155 > {
156 >        if (spec->xarr != NULL)
157 >                free((MEM_PTR)spec->xarr);
158 >        free((MEM_PTR)spec);
159 > }
160 >
161 >
162 > int
163 > xf_aname(ap)                    /* put out name for this instance */
164 > register struct xf_array        *ap;
165 > {
166 >        static char     oname[10*XF_MAXDIM];
167 >        static char     *oav[3] = {mg_ename[MG_E_OBJECT], oname};
168 >        register int    i;
169 >        register char   *cp1, *cp2;
170 >
171 >        if (ap == NULL)
172 >                return(mg_handle(MG_E_OBJECT, 1, oav));
173 >        cp1 = oname;
174 >        *cp1 = 'a';
175 >        for (i = 0; i < ap->ndim; i++) {
176 >                for (cp2 = ap->aarg[i].arg; *cp2; )
177 >                        *++cp1 = *cp2++;
178 >                *++cp1 = '.';
179          }
180 <        xf_argv[xf_argc] = NULL;
181 <                                        /* compute total transformation */
182 <        if (xf_context != NULL) {
87 <                multmat4(spec->xf.xfm, xf_context->xf.xfm, thisxf.xfm);
88 <                spec->xf.sca = xf_context->xf.sca * thisxf.sca;
89 <        } else
90 <                spec->xf = thisxf;
91 <        spec->xid = 0;                  /* compute unique transform id */
92 <        for (i = 0; i < sizeof(MAT4)/sizeof(unsigned short); i++)
93 <                spec->xid ^= randshift(((unsigned short *)&spec->xf.xfm)[i],i);
180 >        *cp1 = '\0';
181 >        return(mg_handle(MG_E_OBJECT, 2, oav));
182 > }
183  
184 <        spec->prev = xf_context;        /* push new transform onto stack */
185 <        xf_context = spec;
186 <        return(MG_OK);
187 < #undef randshift
184 >
185 > long
186 > comp_xfid(xfm)                  /* compute unique ID from matrix */
187 > register MAT4   xfm;
188 > {
189 >        static char     shifttab[64] = { 15, 5, 11, 5, 6, 3,
190 >                                9, 15, 13, 2, 13, 5, 2, 12, 14, 11,
191 >                                11, 12, 12, 3, 2, 11, 8, 12, 1, 12,
192 >                                5, 4, 15, 9, 14, 5, 13, 14, 2, 10,
193 >                                10, 14, 12, 3, 5, 5, 14, 6, 12, 11,
194 >                                13, 9, 12, 8, 1, 6, 5, 12, 7, 13,
195 >                                15, 8, 9, 2, 6, 11, 9, 11 };
196 >        register int    i;
197 >        register long   xid;
198 >
199 >        xid = 0;                        /* compute unique transform id */
200 >        for (i = 0; i < sizeof(MAT4)/sizeof(unsigned short); i++)
201 >                xid ^= (long)(((unsigned short *)xfm)[i]) << shifttab[i&63];
202 >        return(xid);
203   }
204  
205  
# Line 104 | Line 208 | xf_clear()                     /* clear transform stack */
208   {
209          register XF_SPEC        *spec;
210  
211 <        while (xf_argc)
212 <                free((MEM_PTR)xf_argv[--xf_argc]);
213 <        if (xf_maxarg) {
110 <                free((MEM_PTR)xf_argv);
111 <                xf_argv = NULL;
112 <                xf_maxarg = 0;
211 >        if (xf_argbeg != NULL) {
212 >                free((MEM_PTR)xf_argbeg);
213 >                xf_argbeg = xf_argend = NULL;
214          }
215          while ((spec = xf_context) != NULL) {
216                  xf_context = spec->prev;
217 <                free((MEM_PTR)spec);
217 >                free_xf(spec);
218          }
219   }
220  
# Line 123 | Line 224 | xf_xfmpoint(v1, v2)            /* transform a point by the curre
224   FVECT   v1, v2;
225   {
226          if (xf_context == NULL) {
227 <                v1[0] = v2[0];
127 <                v1[1] = v2[1];
128 <                v1[2] = v2[2];
227 >                VCOPY(v1, v2);
228                  return;
229          }
230          multp3(v1, v2, xf_context->xf.xfm);
# Line 137 | Line 236 | xf_xfmvect(v1, v2)             /* transform a vector using curren
236   FVECT   v1, v2;
237   {
238          if (xf_context == NULL) {
239 <                v1[0] = v2[0];
141 <                v1[1] = v2[1];
142 <                v1[2] = v2[2];
239 >                VCOPY(v1, v2);
240                  return;
241          }
242          multv3(v1, v2, xf_context->xf.xfm);

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines