ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/Development/ray/src/common/instance.c
Revision: 2.13
Committed: Tue Nov 5 00:03:10 2024 UTC (13 months, 3 weeks ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.12: +23 -20 lines
Log Message:
style: ANSIfication

File Contents

# Content
1 #ifndef lint
2 static const char RCSid[] = "$Id: instance.c,v 2.12 2016/03/22 03:56:17 greg Exp $";
3 #endif
4 /*
5 * instance.c - routines for octree objects.
6 */
7
8 #include "copyright.h"
9
10 #include "rtmath.h"
11 #include "rterror.h"
12 #include "rtio.h"
13 #include "paths.h"
14
15 #include "octree.h"
16 #include "object.h"
17 #include "instance.h"
18
19 #define IO_ILLEGAL (IO_FILES|IO_INFO)
20
21 static SCENE *slist = NULL; /* list of loaded octrees */
22
23
24 SCENE *
25 getscene( /* get new octree reference */
26 char *sname,
27 int flags
28 )
29 {
30 char *pathname;
31 SCENE *sc;
32
33 flags &= ~IO_ILLEGAL; /* not allowed */
34 for (sc = slist; sc != NULL; sc = sc->next)
35 if (!strcmp(sname, sc->name))
36 break;
37 if (sc == NULL) {
38 sc = (SCENE *)malloc(sizeof(SCENE));
39 if (sc == NULL)
40 error(SYSTEM, "out of memory in getscene");
41 sc->name = savestr(sname);
42 sc->nref = 0;
43 sc->ldflags = 0;
44 sc->scube.cutree = EMPTY;
45 sc->scube.cuorg[0] = sc->scube.cuorg[1] =
46 sc->scube.cuorg[2] = 0.;
47 sc->scube.cusize = 0.;
48 sc->firstobj = sc->nobjs = 0;
49 sc->next = slist;
50 slist = sc;
51 }
52 if ((pathname = getpath(sname, getrlibpath(), R_OK)) == NULL) {
53 sprintf(errmsg, "cannot find octree file \"%s\"", sname);
54 error(SYSTEM, errmsg);
55 }
56 flags &= ~sc->ldflags; /* skip what's already loaded */
57 if (flags & IO_SCENE)
58 sc->firstobj = nobjects;
59 if (flags)
60 readoct(pathname, flags, &sc->scube, NULL);
61 if (flags & IO_SCENE)
62 sc->nobjs = nobjects - sc->firstobj;
63 sc->ldflags |= flags;
64 sc->nref++; /* increase reference count */
65 return(sc);
66 }
67
68
69 INSTANCE *
70 getinstance( /* get instance structure */
71 OBJREC *o,
72 int flags
73 )
74 {
75 INSTANCE *ins;
76
77 flags &= ~IO_ILLEGAL; /* not allowed */
78 if ((ins = (INSTANCE *)o->os) == NULL) {
79 if ((ins = (INSTANCE *)malloc(sizeof(INSTANCE))) == NULL)
80 error(SYSTEM, "out of memory in getinstance");
81 if (o->oargs.nsargs < 1)
82 objerror(o, USER, "bad # of arguments");
83 if (fullxf(&ins->x, o->oargs.nsargs-1,
84 o->oargs.sarg+1) != o->oargs.nsargs-1)
85 objerror(o, USER, "bad transform");
86 if (ins->x.f.sca < 0.0) {
87 ins->x.f.sca = -ins->x.f.sca;
88 ins->x.b.sca = -ins->x.b.sca;
89 }
90 ins->obj = NULL;
91 o->os = (char *)ins;
92 }
93 if (ins->obj == NULL) {
94 ins->obj = getscene(o->oargs.sarg[0], flags);
95 } else if ((flags &= ~ins->obj->ldflags)) {
96 if (flags & IO_SCENE)
97 ins->obj->firstobj = nobjects;
98 if (flags)
99 readoct(getpath(o->oargs.sarg[0], getrlibpath(), R_OK),
100 flags, &ins->obj->scube, NULL);
101 if (flags & IO_SCENE)
102 ins->obj->nobjs = nobjects - ins->obj->firstobj;
103 ins->obj->ldflags |= flags;
104 }
105 return(ins);
106 }
107
108
109 void
110 freescene( /* release a scene reference */
111 SCENE *sc
112 )
113 {
114 SCENE shead;
115 SCENE *scp;
116
117 if (sc == NULL)
118 return;
119 if (sc->nref <= 0)
120 error(CONSISTENCY, "unreferenced scene in freescene");
121 if (--sc->nref) /* still in use? */
122 return;
123 shead.next = slist; /* else remove from our list */
124 for (scp = &shead; scp->next != NULL; scp = scp->next)
125 if (scp->next == sc) {
126 scp->next = sc->next;
127 sc->next = NULL;
128 break;
129 }
130 if (sc->next != NULL) /* can't be in list anymore */
131 error(CONSISTENCY, "unlisted scene in freescene");
132 slist = shead.next;
133 freestr(sc->name); /* free memory */
134 octfree(sc->scube.cutree);
135 freeobjects(sc->firstobj, sc->nobjs);
136 free(sc);
137 }
138
139
140 void
141 freeinstance( /* free memory associated with instance */
142 OBJREC *o
143 )
144 {
145 if (o->os == NULL)
146 return;
147 freescene((*(INSTANCE *)o->os).obj);
148 free(o->os);
149 o->os = NULL;
150 }