1 /*
2 ======================================================================
3 vmap.c
4
5 Vertex map functions for an LWO2 reader.
6
7 Ernie Wright 17 Sep 00
8 ====================================================================== */
9
10 #include "../picointernal.h"
11 #include "lwo2.h"
12
13
14 /*
15 ======================================================================
16 lwFreeVMap()
17
18 Free memory used by an lwVMap.
19 ====================================================================== */
20
lwFreeVMap(lwVMap * vmap)21 void lwFreeVMap( lwVMap *vmap ){
22 if ( vmap ) {
23 if ( vmap->name ) {
24 _pico_free( vmap->name );
25 }
26 if ( vmap->vindex ) {
27 _pico_free( vmap->vindex );
28 }
29 if ( vmap->pindex ) {
30 _pico_free( vmap->pindex );
31 }
32 if ( vmap->val ) {
33 if ( vmap->val[ 0 ] ) {
34 _pico_free( vmap->val[ 0 ] );
35 }
36 _pico_free( vmap->val );
37 }
38 _pico_free( vmap );
39 }
40 }
41
42
43 /*
44 ======================================================================
45 lwGetVMap()
46
47 Read an lwVMap from a VMAP or VMAD chunk in an LWO2.
48 ====================================================================== */
49
lwGetVMap(picoMemStream_t * fp,int cksize,int ptoffset,int poloffset,int perpoly)50 lwVMap *lwGetVMap( picoMemStream_t *fp, int cksize, int ptoffset, int poloffset,
51 int perpoly ){
52 unsigned char *buf, *bp;
53 lwVMap *vmap;
54 float *f;
55 int i, j, npts, rlen;
56
57
58 /* read the whole chunk */
59
60 set_flen( 0 );
61 buf = getbytes( fp, cksize );
62 if ( !buf ) {
63 return NULL;
64 }
65
66 vmap = _pico_calloc( 1, sizeof( lwVMap ) );
67 if ( !vmap ) {
68 _pico_free( buf );
69 return NULL;
70 }
71
72 /* initialize the vmap */
73
74 vmap->perpoly = perpoly;
75
76 bp = buf;
77 set_flen( 0 );
78 vmap->type = sgetU4( &bp );
79 vmap->dim = sgetU2( &bp );
80 vmap->name = sgetS0( &bp );
81 rlen = get_flen();
82
83 /* count the vmap records */
84
85 npts = 0;
86 while ( bp < buf + cksize ) {
87 i = sgetVX( &bp );
88 if ( perpoly ) {
89 i = sgetVX( &bp );
90 }
91 bp += vmap->dim * sizeof( float );
92 ++npts;
93 }
94
95 /* allocate the vmap */
96
97 vmap->nverts = npts;
98 vmap->vindex = _pico_calloc( npts, sizeof( int ) );
99 if ( !vmap->vindex ) {
100 goto Fail;
101 }
102 if ( perpoly ) {
103 vmap->pindex = _pico_calloc( npts, sizeof( int ) );
104 if ( !vmap->pindex ) {
105 goto Fail;
106 }
107 }
108
109 if ( vmap->dim > 0 ) {
110 vmap->val = _pico_calloc( npts, sizeof( float * ) );
111 if ( !vmap->val ) {
112 goto Fail;
113 }
114 f = _pico_alloc( npts * vmap->dim * sizeof( float ) );
115 if ( !f ) {
116 goto Fail;
117 }
118 for ( i = 0; i < npts; i++ )
119 vmap->val[ i ] = f + i * vmap->dim;
120 }
121
122 /* fill in the vmap values */
123
124 bp = buf + rlen;
125 for ( i = 0; i < npts; i++ ) {
126 vmap->vindex[ i ] = sgetVX( &bp );
127 if ( perpoly ) {
128 vmap->pindex[ i ] = sgetVX( &bp );
129 }
130 for ( j = 0; j < vmap->dim; j++ )
131 vmap->val[ i ][ j ] = sgetF4( &bp );
132 }
133
134 _pico_free( buf );
135 return vmap;
136
137 Fail:
138 if ( buf ) {
139 _pico_free( buf );
140 }
141 lwFreeVMap( vmap );
142 return NULL;
143 }
144
145
146 /*
147 ======================================================================
148 lwGetPointVMaps()
149
150 Fill in the lwVMapPt structure for each point.
151 ====================================================================== */
152
lwGetPointVMaps(lwPointList * point,lwVMap * vmap)153 int lwGetPointVMaps( lwPointList *point, lwVMap *vmap ){
154 lwVMap *vm;
155 int i, j, n;
156
157 /* count the number of vmap values for each point */
158
159 vm = vmap;
160 while ( vm ) {
161 if ( !vm->perpoly ) {
162 for ( i = 0; i < vm->nverts; i++ )
163 ++point->pt[ vm->vindex[ i ]].nvmaps;
164 }
165 vm = vm->next;
166 }
167
168 /* allocate vmap references for each mapped point */
169
170 for ( i = 0; i < point->count; i++ ) {
171 if ( point->pt[ i ].nvmaps ) {
172 point->pt[ i ].vm = _pico_calloc( point->pt[ i ].nvmaps, sizeof( lwVMapPt ) );
173 if ( !point->pt[ i ].vm ) {
174 return 0;
175 }
176 point->pt[ i ].nvmaps = 0;
177 }
178 }
179
180 /* fill in vmap references for each mapped point */
181
182 vm = vmap;
183 while ( vm ) {
184 if ( !vm->perpoly ) {
185 for ( i = 0; i < vm->nverts; i++ ) {
186 j = vm->vindex[ i ];
187 n = point->pt[ j ].nvmaps;
188 point->pt[ j ].vm[ n ].vmap = vm;
189 point->pt[ j ].vm[ n ].index = i;
190 ++point->pt[ j ].nvmaps;
191 }
192 }
193 vm = vm->next;
194 }
195
196 return 1;
197 }
198
199
200 /*
201 ======================================================================
202 lwGetPolyVMaps()
203
204 Fill in the lwVMapPt structure for each polygon vertex.
205 ====================================================================== */
206
lwGetPolyVMaps(lwPolygonList * polygon,lwVMap * vmap)207 int lwGetPolyVMaps( lwPolygonList *polygon, lwVMap *vmap ){
208 lwVMap *vm;
209 lwPolVert *pv;
210 int i, j;
211
212 /* count the number of vmap values for each polygon vertex */
213
214 vm = vmap;
215 while ( vm ) {
216 if ( vm->perpoly ) {
217 for ( i = 0; i < vm->nverts; i++ ) {
218 for ( j = 0; j < polygon->pol[ vm->pindex[ i ]].nverts; j++ ) {
219 pv = &polygon->pol[ vm->pindex[ i ]].v[ j ];
220 if ( vm->vindex[ i ] == pv->index ) {
221 ++pv->nvmaps;
222 break;
223 }
224 }
225 }
226 }
227 vm = vm->next;
228 }
229
230 /* allocate vmap references for each mapped vertex */
231
232 for ( i = 0; i < polygon->count; i++ ) {
233 for ( j = 0; j < polygon->pol[ i ].nverts; j++ ) {
234 pv = &polygon->pol[ i ].v[ j ];
235 if ( pv->nvmaps ) {
236 pv->vm = _pico_calloc( pv->nvmaps, sizeof( lwVMapPt ) );
237 if ( !pv->vm ) {
238 return 0;
239 }
240 pv->nvmaps = 0;
241 }
242 }
243 }
244
245 /* fill in vmap references for each mapped point */
246
247 vm = vmap;
248 while ( vm ) {
249 if ( vm->perpoly ) {
250 for ( i = 0; i < vm->nverts; i++ ) {
251 for ( j = 0; j < polygon->pol[ vm->pindex[ i ]].nverts; j++ ) {
252 pv = &polygon->pol[ vm->pindex[ i ]].v[ j ];
253 if ( vm->vindex[ i ] == pv->index ) {
254 pv->vm[ pv->nvmaps ].vmap = vm;
255 pv->vm[ pv->nvmaps ].index = i;
256 ++pv->nvmaps;
257 break;
258 }
259 }
260 }
261 }
262 vm = vm->next;
263 }
264
265 return 1;
266 }
267