]> de.git.xonotic.org Git - xonotic/netradiant.git/blob - libs/picomodel/lwo/vmap.c
my own uncrustify run
[xonotic/netradiant.git] / libs / picomodel / lwo / vmap.c
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
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
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
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
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 }