2 ======================================================================
5 The entry point for loading LightWave object files.
8 ====================================================================== */
10 #include "../picointernal.h"
13 /* disable warnings */
15 #pragma warning( disable:4018 ) /* signed/unsigned mismatch */
20 ======================================================================
23 Free memory used by an lwLayer.
24 ====================================================================== */
26 void lwFreeLayer( lwLayer *layer ){
29 _pico_free( layer->name );
31 lwFreePoints( &layer->point );
32 lwFreePolygons( &layer->polygon );
33 lwListFree( layer->vmap, lwFreeVMap );
40 ======================================================================
43 Free memory used by an lwObject.
44 ====================================================================== */
46 void lwFreeObject( lwObject *object ){
48 lwListFree( object->layer, lwFreeLayer );
49 lwListFree( object->env, lwFreeEnvelope );
50 lwListFree( object->clip, lwFreeClip );
51 lwListFree( object->surf, lwFreeSurface );
52 lwFreeTags( &object->taglist );
59 ======================================================================
62 Returns the contents of a LightWave object, given its filename, or
63 NULL if the file couldn't be loaded. On failure, failID and failpos
64 can be used to diagnose the cause.
66 1. If the file isn't an LWO2 or an LWOB, failpos will contain 12 and
67 failID will be unchanged.
69 2. If an error occurs while reading, failID will contain the most
70 recently read IFF chunk ID, and failpos will contain the value
71 returned by _pico_memstream_tell() at the time of the failure.
73 3. If the file couldn't be opened, or an error occurs while reading
74 the first 12 bytes, both failID and failpos will be unchanged.
76 If you don't need this information, failID and failpos can be NULL.
77 ====================================================================== */
79 lwObject *lwGetObject( char *filename, picoMemStream_t *fp, unsigned int *failID, int *failpos ){
83 unsigned int id, formsize, type, cksize;
92 /* read the first 12 bytes */
96 formsize = getU4( fp );
98 if ( 12 != get_flen() ) {
102 /* is this a LW object? */
104 if ( id != ID_FORM ) {
111 if ( type != ID_LWO2 ) {
112 if ( type == ID_LWOB ) {
113 return lwGetObject5( filename, fp, failID, failpos );
123 /* allocate an object and a default layer */
125 object = _pico_calloc( 1, sizeof( lwObject ) );
130 layer = _pico_calloc( 1, sizeof( lwLayer ) );
134 object->layer = layer;
136 /* get the first chunk header */
139 cksize = getU4( fp );
140 if ( 0 > get_flen() ) {
144 /* process chunks as they're encountered */
147 cksize += cksize & 1;
152 if ( object->nlayers > 0 ) {
153 layer = _pico_calloc( 1, sizeof( lwLayer ) );
157 lwListAdd( &object->layer, layer );
162 layer->index = getU2( fp );
163 layer->flags = getU2( fp );
164 layer->pivot[ 0 ] = getF4( fp );
165 layer->pivot[ 1 ] = getF4( fp );
166 layer->pivot[ 2 ] = getF4( fp );
167 layer->name = getS0( fp );
170 if ( rlen < 0 || rlen > cksize ) {
173 if ( rlen <= cksize - 2 ) {
174 layer->parent = getU2( fp );
177 if ( rlen < cksize ) {
178 _pico_memstream_seek( fp, cksize - rlen, PICO_SEEK_CUR );
183 if ( !lwGetPoints( fp, cksize, &layer->point ) ) {
189 if ( !lwGetPolygons( fp, cksize, &layer->polygon,
190 layer->point.offset ) ) {
197 node = ( lwNode * ) lwGetVMap( fp, cksize, layer->point.offset,
198 layer->polygon.offset, id == ID_VMAD );
202 lwListAdd( &layer->vmap, node );
207 if ( !lwGetPolygonTags( fp, cksize, &object->taglist,
208 &layer->polygon ) ) {
215 for ( i = 0; i < 6; i++ )
216 layer->bbox[ i ] = getF4( fp );
218 if ( rlen < 0 || rlen > cksize ) {
221 if ( rlen < cksize ) {
222 _pico_memstream_seek( fp, cksize - rlen, PICO_SEEK_CUR );
227 if ( !lwGetTags( fp, cksize, &object->taglist ) ) {
233 node = ( lwNode * ) lwGetEnvelope( fp, cksize );
237 lwListAdd( &object->env, node );
242 node = ( lwNode * ) lwGetClip( fp, cksize );
246 lwListAdd( &object->clip, node );
251 node = ( lwNode * ) lwGetSurface( fp, cksize );
255 lwListAdd( &object->surf, node );
263 _pico_memstream_seek( fp, cksize, PICO_SEEK_CUR );
267 /* end of the file? */
269 if ( formsize <= _pico_memstream_tell( fp ) - 8 ) {
273 /* get the next chunk header */
277 cksize = getU4( fp );
278 if ( 8 != get_flen() ) {
283 if ( object->nlayers == 0 ) {
287 layer = object->layer;
289 lwGetBoundingBox( &layer->point, layer->bbox );
290 lwGetPolyNormals( &layer->point, &layer->polygon );
291 if ( !lwGetPointPolygons( &layer->point, &layer->polygon ) ) {
294 if ( !lwResolvePolySurfaces( &layer->polygon, &object->taglist,
295 &object->surf, &object->nsurfs ) ) {
298 lwGetVertNormals( &layer->point, &layer->polygon );
299 if ( !lwGetPointVMaps( &layer->point, layer->vmap ) ) {
302 if ( !lwGetPolyVMaps( &layer->polygon, layer->vmap ) ) {
316 *failpos = _pico_memstream_tell( fp );
319 lwFreeObject( object );
323 int lwValidateObject( char *filename, picoMemStream_t *fp, unsigned int *failID, int *failpos ){
324 unsigned int id, formsize, type;
329 return PICO_PMV_ERROR_MEMORY;
332 /* read the first 12 bytes */
336 formsize = getU4( fp );
338 if ( 12 != get_flen() ) {
339 return PICO_PMV_ERROR_SIZE;
342 /* is this a LW object? */
344 if ( id != ID_FORM ) {
348 return PICO_PMV_ERROR_SIZE;
351 if ( type != ID_LWO2 ) {
352 if ( type == ID_LWOB ) {
353 return lwValidateObject5( filename, fp, failID, failpos );
359 return PICO_PMV_ERROR_IDENT;