X-Git-Url: https://de.git.xonotic.org/?a=blobdiff_plain;f=libs%2Fpicomodel%2Flwo%2Fpntspols.c;h=fc2f642e7b54ca73137c994b7caa89303fac279b;hb=e4287c28bb2dafedc81c66e63951d947cfbeb225;hp=314758199c07d2ec1e88002996466d8975805ba4;hpb=231225d6f97d0b926b2e896e5783cccfbc7c5619;p=xonotic%2Fnetradiant.git diff --git a/libs/picomodel/lwo/pntspols.c b/libs/picomodel/lwo/pntspols.c index 31475819..fc2f642e 100644 --- a/libs/picomodel/lwo/pntspols.c +++ b/libs/picomodel/lwo/pntspols.c @@ -1,537 +1,588 @@ /* -====================================================================== -pntspols.c + ====================================================================== + pntspols.c -Point and polygon functions for an LWO2 reader. + Point and polygon functions for an LWO2 reader. -Ernie Wright 17 Sep 00 -====================================================================== */ + Ernie Wright 17 Sep 00 + ====================================================================== */ #include "../picointernal.h" #include "lwo2.h" /* -====================================================================== -lwFreePoints() - -Free the memory used by an lwPointList. -====================================================================== */ - -void lwFreePoints( lwPointList *point ) -{ - int i; - - if ( point ) { - if ( point->pt ) { - for ( i = 0; i < point->count; i++ ) { - if ( point->pt[ i ].pol ) _pico_free( point->pt[ i ].pol ); - if ( point->pt[ i ].vm ) _pico_free( point->pt[ i ].vm ); - } - _pico_free( point->pt ); - } - memset( point, 0, sizeof( lwPointList )); - } + ====================================================================== + lwFreePoints() + + Free the memory used by an lwPointList. + ====================================================================== */ + +void lwFreePoints( lwPointList *point ){ + int i; + + if ( point ) { + if ( point->pt ) { + for ( i = 0; i < point->count; i++ ) { + if ( point->pt[ i ].pol ) { + _pico_free( point->pt[ i ].pol ); + } + if ( point->pt[ i ].vm ) { + _pico_free( point->pt[ i ].vm ); + } + } + _pico_free( point->pt ); + } + memset( point, 0, sizeof( lwPointList ) ); + } } /* -====================================================================== -lwFreePolygons() - -Free the memory used by an lwPolygonList. -====================================================================== */ - -void lwFreePolygons( lwPolygonList *plist ) -{ - int i, j; - - if ( plist ) { - if ( plist->pol ) { - for ( i = 0; i < plist->count; i++ ) { - if ( plist->pol[ i ].v ) { - for ( j = 0; j < plist->pol[ i ].nverts; j++ ) - if ( plist->pol[ i ].v[ j ].vm ) - _pico_free( plist->pol[ i ].v[ j ].vm ); - } - } - if ( plist->pol[ 0 ].v ) - _pico_free( plist->pol[ 0 ].v ); - _pico_free( plist->pol ); - } - memset( plist, 0, sizeof( lwPolygonList )); - } + ====================================================================== + lwFreePolygons() + + Free the memory used by an lwPolygonList. + ====================================================================== */ + +void lwFreePolygons( lwPolygonList *plist ){ + int i, j; + + if ( plist ) { + if ( plist->pol ) { + for ( i = 0; i < plist->count; i++ ) { + if ( plist->pol[ i ].v ) { + for ( j = 0; j < plist->pol[ i ].nverts; j++ ) + if ( plist->pol[ i ].v[ j ].vm ) { + _pico_free( plist->pol[ i ].v[ j ].vm ); + } + } + } + if ( plist->pol[ 0 ].v ) { + _pico_free( plist->pol[ 0 ].v ); + } + _pico_free( plist->pol ); + } + memset( plist, 0, sizeof( lwPolygonList ) ); + } } /* -====================================================================== -lwGetPoints() + ====================================================================== + lwGetPoints() -Read point records from a PNTS chunk in an LWO2 file. The points are -added to the array in the lwPointList. -====================================================================== */ + Read point records from a PNTS chunk in an LWO2 file. The points are + added to the array in the lwPointList. + ====================================================================== */ -int lwGetPoints( picoMemStream_t *fp, int cksize, lwPointList *point ) -{ - float *f; - int np, i, j; +int lwGetPoints( picoMemStream_t *fp, int cksize, lwPointList *point ){ + float *f; + int np, i, j; - if ( cksize == 1 ) return 1; + if ( cksize == 1 ) { + return 1; + } - /* extend the point array to hold the new points */ + /* extend the point array to hold the new points */ - np = cksize / 12; - point->offset = point->count; - point->count += np; - if ( !_pico_realloc( (void *) &point->pt, (point->count - np) * sizeof( lwPoint ), point->count * sizeof( lwPoint )) ) - return 0; - memset( &point->pt[ point->offset ], 0, np * sizeof( lwPoint )); + np = cksize / 12; + point->offset = point->count; + point->count += np; + if ( !_pico_realloc( (void *) &point->pt, ( point->count - np ) * sizeof( lwPoint ), point->count * sizeof( lwPoint ) ) ) { + return 0; + } + memset( &point->pt[ point->offset ], 0, np * sizeof( lwPoint ) ); - /* read the whole chunk */ + /* read the whole chunk */ - f = ( float * ) getbytes( fp, cksize ); - if ( !f ) return 0; - revbytes( f, 4, np * 3 ); + f = ( float * ) getbytes( fp, cksize ); + if ( !f ) { + return 0; + } + revbytes( f, 4, np * 3 ); - /* assign position values */ + /* assign position values */ - for ( i = 0, j = 0; i < np; i++, j += 3 ) { - point->pt[ i ].pos[ 0 ] = f[ j ]; - point->pt[ i ].pos[ 1 ] = f[ j + 1 ]; - point->pt[ i ].pos[ 2 ] = f[ j + 2 ]; - } + for ( i = 0, j = 0; i < np; i++, j += 3 ) { + point->pt[ i ].pos[ 0 ] = f[ j ]; + point->pt[ i ].pos[ 1 ] = f[ j + 1 ]; + point->pt[ i ].pos[ 2 ] = f[ j + 2 ]; + } - _pico_free( f ); - return 1; + _pico_free( f ); + return 1; } /* -====================================================================== -lwGetBoundingBox() - -Calculate the bounding box for a point list, but only if the bounding -box hasn't already been initialized. -====================================================================== */ - -void lwGetBoundingBox( lwPointList *point, float bbox[] ) -{ - int i, j; - - if ( point->count == 0 ) return; - - for ( i = 0; i < 6; i++ ) - if ( bbox[ i ] != 0.0f ) return; - - bbox[ 0 ] = bbox[ 1 ] = bbox[ 2 ] = 1e20f; - bbox[ 3 ] = bbox[ 4 ] = bbox[ 5 ] = -1e20f; - for ( i = 0; i < point->count; i++ ) { - for ( j = 0; j < 3; j++ ) { - if ( bbox[ j ] > point->pt[ i ].pos[ j ] ) - bbox[ j ] = point->pt[ i ].pos[ j ]; - if ( bbox[ j + 3 ] < point->pt[ i ].pos[ j ] ) - bbox[ j + 3 ] = point->pt[ i ].pos[ j ]; - } - } + ====================================================================== + lwGetBoundingBox() + + Calculate the bounding box for a point list, but only if the bounding + box hasn't already been initialized. + ====================================================================== */ + +void lwGetBoundingBox( lwPointList *point, float bbox[] ){ + int i, j; + + if ( point->count == 0 ) { + return; + } + + for ( i = 0; i < 6; i++ ) + if ( bbox[ i ] != 0.0f ) { + return; + } + + bbox[ 0 ] = bbox[ 1 ] = bbox[ 2 ] = 1e20f; + bbox[ 3 ] = bbox[ 4 ] = bbox[ 5 ] = -1e20f; + for ( i = 0; i < point->count; i++ ) { + for ( j = 0; j < 3; j++ ) { + if ( bbox[ j ] > point->pt[ i ].pos[ j ] ) { + bbox[ j ] = point->pt[ i ].pos[ j ]; + } + if ( bbox[ j + 3 ] < point->pt[ i ].pos[ j ] ) { + bbox[ j + 3 ] = point->pt[ i ].pos[ j ]; + } + } + } } /* -====================================================================== -lwAllocPolygons() + ====================================================================== + lwAllocPolygons() -Allocate or extend the polygon arrays to hold new records. -====================================================================== */ + Allocate or extend the polygon arrays to hold new records. + ====================================================================== */ -int lwAllocPolygons( lwPolygonList *plist, int npols, int nverts ) -{ - int i; +int lwAllocPolygons( lwPolygonList *plist, int npols, int nverts ){ + int i; - plist->offset = plist->count; - plist->count += npols; - if ( !_pico_realloc( (void *) &plist->pol, (plist->count - npols) * sizeof( lwPolygon ), plist->count * sizeof( lwPolygon )) ) - return 0; - memset( plist->pol + plist->offset, 0, npols * sizeof( lwPolygon )); + plist->offset = plist->count; + plist->count += npols; + if ( !_pico_realloc( (void *) &plist->pol, ( plist->count - npols ) * sizeof( lwPolygon ), plist->count * sizeof( lwPolygon ) ) ) { + return 0; + } + memset( plist->pol + plist->offset, 0, npols * sizeof( lwPolygon ) ); - plist->voffset = plist->vcount; - plist->vcount += nverts; - if ( !_pico_realloc( (void *) &plist->pol[ 0 ].v, (plist->vcount - nverts) * sizeof( lwPolVert ), plist->vcount * sizeof( lwPolVert )) ) - return 0; - memset( plist->pol[ 0 ].v + plist->voffset, 0, nverts * sizeof( lwPolVert )); + plist->voffset = plist->vcount; + plist->vcount += nverts; + if ( !_pico_realloc( (void *) &plist->pol[ 0 ].v, ( plist->vcount - nverts ) * sizeof( lwPolVert ), plist->vcount * sizeof( lwPolVert ) ) ) { + return 0; + } + memset( plist->pol[ 0 ].v + plist->voffset, 0, nverts * sizeof( lwPolVert ) ); - /* fix up the old vertex pointers */ + /* fix up the old vertex pointers */ - for ( i = 1; i < plist->offset; i++ ) - plist->pol[ i ].v = plist->pol[ i - 1 ].v + plist->pol[ i - 1 ].nverts; + for ( i = 1; i < plist->offset; i++ ) + plist->pol[ i ].v = plist->pol[ i - 1 ].v + plist->pol[ i - 1 ].nverts; - return 1; + return 1; } /* -====================================================================== -lwGetPolygons() - -Read polygon records from a POLS chunk in an LWO2 file. The polygons -are added to the array in the lwPolygonList. -====================================================================== */ - -int lwGetPolygons( picoMemStream_t *fp, int cksize, lwPolygonList *plist, int ptoffset ) -{ - lwPolygon *pp; - lwPolVert *pv; - unsigned char *buf, *bp; - int i, j, flags, nv, nverts, npols; - unsigned int type; - - - if ( cksize == 0 ) return 1; - - /* read the whole chunk */ - - set_flen( 0 ); - type = getU4( fp ); - buf = getbytes( fp, cksize - 4 ); - if ( cksize != get_flen() ) goto Fail; - - /* count the polygons and vertices */ - - nverts = 0; - npols = 0; - bp = buf; - - while ( bp < buf + cksize - 4 ) { - nv = sgetU2( &bp ); - nv &= 0x03FF; - nverts += nv; - npols++; - for ( i = 0; i < nv; i++ ) - j = sgetVX( &bp ); - } - - if ( !lwAllocPolygons( plist, npols, nverts )) - goto Fail; - - /* fill in the new polygons */ - - bp = buf; - pp = plist->pol + plist->offset; - pv = plist->pol[ 0 ].v + plist->voffset; - - for ( i = 0; i < npols; i++ ) { - nv = sgetU2( &bp ); - flags = nv & 0xFC00; - nv &= 0x03FF; - - pp->nverts = nv; - pp->flags = flags; - pp->type = type; - if ( !pp->v ) pp->v = pv; - for ( j = 0; j < nv; j++ ) - pp->v[ j ].index = sgetVX( &bp ) + ptoffset; - - pp++; - pv += nv; - } - - _pico_free( buf ); - return 1; + ====================================================================== + lwGetPolygons() + + Read polygon records from a POLS chunk in an LWO2 file. The polygons + are added to the array in the lwPolygonList. + ====================================================================== */ + +int lwGetPolygons( picoMemStream_t *fp, int cksize, lwPolygonList *plist, int ptoffset ){ + lwPolygon *pp; + lwPolVert *pv; + unsigned char *buf, *bp; + int i, j, flags, nv, nverts, npols; + unsigned int type; + + + if ( cksize == 0 ) { + return 1; + } + + /* read the whole chunk */ + + set_flen( 0 ); + type = getU4( fp ); + buf = getbytes( fp, cksize - 4 ); + if ( cksize != get_flen() ) { + goto Fail; + } + + /* count the polygons and vertices */ + + nverts = 0; + npols = 0; + bp = buf; + + while ( bp < buf + cksize - 4 ) { + nv = sgetU2( &bp ); + nv &= 0x03FF; + nverts += nv; + npols++; + for ( i = 0; i < nv; i++ ) + j = sgetVX( &bp ); + } + + if ( !lwAllocPolygons( plist, npols, nverts ) ) { + goto Fail; + } + + /* fill in the new polygons */ + + bp = buf; + pp = plist->pol + plist->offset; + pv = plist->pol[ 0 ].v + plist->voffset; + + for ( i = 0; i < npols; i++ ) { + nv = sgetU2( &bp ); + flags = nv & 0xFC00; + nv &= 0x03FF; + + pp->nverts = nv; + pp->flags = flags; + pp->type = type; + if ( !pp->v ) { + pp->v = pv; + } + for ( j = 0; j < nv; j++ ) + pp->v[ j ].index = sgetVX( &bp ) + ptoffset; + + pp++; + pv += nv; + } + + _pico_free( buf ); + return 1; Fail: - if ( buf ) _pico_free( buf ); - lwFreePolygons( plist ); - return 0; + if ( buf ) { + _pico_free( buf ); + } + lwFreePolygons( plist ); + return 0; } /* -====================================================================== -lwGetPolyNormals() - -Calculate the polygon normals. By convention, LW's polygon normals -are found as the cross product of the first and last edges. It's -undefined for one- and two-point polygons. -====================================================================== */ - -void lwGetPolyNormals( lwPointList *point, lwPolygonList *polygon ) -{ - int i, j; - float p1[ 3 ], p2[ 3 ], pn[ 3 ], v1[ 3 ], v2[ 3 ]; - - for ( i = 0; i < polygon->count; i++ ) { - if ( polygon->pol[ i ].nverts < 3 ) continue; - for ( j = 0; j < 3; j++ ) { - p1[ j ] = point->pt[ polygon->pol[ i ].v[ 0 ].index ].pos[ j ]; - p2[ j ] = point->pt[ polygon->pol[ i ].v[ 1 ].index ].pos[ j ]; - pn[ j ] = point->pt[ polygon->pol[ i ].v[ - polygon->pol[ i ].nverts - 1 ].index ].pos[ j ]; - } - - for ( j = 0; j < 3; j++ ) { - v1[ j ] = p2[ j ] - p1[ j ]; - v2[ j ] = pn[ j ] - p1[ j ]; - } - - cross( v1, v2, polygon->pol[ i ].norm ); - normalize( polygon->pol[ i ].norm ); - } + ====================================================================== + lwGetPolyNormals() + + Calculate the polygon normals. By convention, LW's polygon normals + are found as the cross product of the first and last edges. It's + undefined for one- and two-point polygons. + ====================================================================== */ + +void lwGetPolyNormals( lwPointList *point, lwPolygonList *polygon ){ + int i, j; + float p1[ 3 ], p2[ 3 ], pn[ 3 ], v1[ 3 ], v2[ 3 ]; + + for ( i = 0; i < polygon->count; i++ ) { + if ( polygon->pol[ i ].nverts < 3 ) { + continue; + } + for ( j = 0; j < 3; j++ ) { + p1[ j ] = point->pt[ polygon->pol[ i ].v[ 0 ].index ].pos[ j ]; + p2[ j ] = point->pt[ polygon->pol[ i ].v[ 1 ].index ].pos[ j ]; + pn[ j ] = point->pt[ polygon->pol[ i ].v[ + polygon->pol[ i ].nverts - 1 ].index ].pos[ j ]; + } + + for ( j = 0; j < 3; j++ ) { + v1[ j ] = p2[ j ] - p1[ j ]; + v2[ j ] = pn[ j ] - p1[ j ]; + } + + cross( v1, v2, polygon->pol[ i ].norm ); + normalize( polygon->pol[ i ].norm ); + } } /* -====================================================================== -lwGetPointPolygons() - -For each point, fill in the indexes of the polygons that share the -point. Returns 0 if any of the memory allocations fail, otherwise -returns 1. -====================================================================== */ - -int lwGetPointPolygons( lwPointList *point, lwPolygonList *polygon ) -{ - int i, j, k; - - /* count the number of polygons per point */ - - for ( i = 0; i < polygon->count; i++ ) - for ( j = 0; j < polygon->pol[ i ].nverts; j++ ) - ++point->pt[ polygon->pol[ i ].v[ j ].index ].npols; - - /* alloc per-point polygon arrays */ - - for ( i = 0; i < point->count; i++ ) { - if ( point->pt[ i ].npols == 0 ) continue; - point->pt[ i ].pol = _pico_calloc( point->pt[ i ].npols, sizeof( int )); - if ( !point->pt[ i ].pol ) return 0; - point->pt[ i ].npols = 0; - } - - /* fill in polygon array for each point */ - - for ( i = 0; i < polygon->count; i++ ) { - for ( j = 0; j < polygon->pol[ i ].nverts; j++ ) { - k = polygon->pol[ i ].v[ j ].index; - point->pt[ k ].pol[ point->pt[ k ].npols ] = i; - ++point->pt[ k ].npols; - } - } - - return 1; + ====================================================================== + lwGetPointPolygons() + + For each point, fill in the indexes of the polygons that share the + point. Returns 0 if any of the memory allocations fail, otherwise + returns 1. + ====================================================================== */ + +int lwGetPointPolygons( lwPointList *point, lwPolygonList *polygon ){ + int i, j, k; + + /* count the number of polygons per point */ + + for ( i = 0; i < polygon->count; i++ ) + for ( j = 0; j < polygon->pol[ i ].nverts; j++ ) + ++point->pt[ polygon->pol[ i ].v[ j ].index ].npols; + + /* alloc per-point polygon arrays */ + + for ( i = 0; i < point->count; i++ ) { + if ( point->pt[ i ].npols == 0 ) { + continue; + } + point->pt[ i ].pol = _pico_calloc( point->pt[ i ].npols, sizeof( int ) ); + if ( !point->pt[ i ].pol ) { + return 0; + } + point->pt[ i ].npols = 0; + } + + /* fill in polygon array for each point */ + + for ( i = 0; i < polygon->count; i++ ) { + for ( j = 0; j < polygon->pol[ i ].nverts; j++ ) { + k = polygon->pol[ i ].v[ j ].index; + point->pt[ k ].pol[ point->pt[ k ].npols ] = i; + ++point->pt[ k ].npols; + } + } + + return 1; } /* -====================================================================== -lwResolvePolySurfaces() + ====================================================================== + lwResolvePolySurfaces() -Convert tag indexes into actual lwSurface pointers. If any polygons -point to tags for which no corresponding surface can be found, a -default surface is created. -====================================================================== */ + Convert tag indexes into actual lwSurface pointers. If any polygons + point to tags for which no corresponding surface can be found, a + default surface is created. + ====================================================================== */ int lwResolvePolySurfaces( lwPolygonList *polygon, lwTagList *tlist, - lwSurface **surf, int *nsurfs ) -{ - lwSurface **s, *st; - int i, index; - - if ( tlist->count == 0 ) return 1; - - s = _pico_calloc( tlist->count, sizeof( lwSurface * )); - if ( !s ) return 0; - - for ( i = 0; i < tlist->count; i++ ) { - st = *surf; - while ( st ) { - if ( !strcmp( st->name, tlist->tag[ i ] )) { - s[ i ] = st; - break; - } - st = st->next; - } - } - - for ( i = 0; i < polygon->count; i++ ) { - index = ( size_t ) polygon->pol[ i ].surf; - if ( index < 0 || index > tlist->count ) return 0; - if ( !s[ index ] ) { - s[ index ] = lwDefaultSurface(); - if ( !s[ index ] ) return 0; - s[ index ]->name = _pico_alloc( strlen( tlist->tag[ index ] ) + 1 ); - if ( !s[ index ]->name ) return 0; - strcpy( s[ index ]->name, tlist->tag[ index ] ); - lwListAdd( (void *) surf, s[ index ] ); - *nsurfs = *nsurfs + 1; - } - polygon->pol[ i ].surf = s[ index ]; - } - - _pico_free( s ); - return 1; + lwSurface **surf, int *nsurfs ){ + lwSurface **s, *st; + int i, index; + + if ( tlist->count == 0 ) { + return 1; + } + + s = _pico_calloc( tlist->count, sizeof( lwSurface * ) ); + if ( !s ) { + return 0; + } + + for ( i = 0; i < tlist->count; i++ ) { + st = *surf; + while ( st ) { + if ( !strcmp( st->name, tlist->tag[ i ] ) ) { + s[ i ] = st; + break; + } + st = st->next; + } + } + + for ( i = 0; i < polygon->count; i++ ) { + index = ( size_t ) polygon->pol[ i ].surf; + if ( index < 0 || index > tlist->count ) { + return 0; + } + if ( !s[ index ] ) { + s[ index ] = lwDefaultSurface(); + if ( !s[ index ] ) { + return 0; + } + s[ index ]->name = _pico_alloc( strlen( tlist->tag[ index ] ) + 1 ); + if ( !s[ index ]->name ) { + return 0; + } + strcpy( s[ index ]->name, tlist->tag[ index ] ); + lwListAdd( (void *) surf, s[ index ] ); + *nsurfs = *nsurfs + 1; + } + polygon->pol[ i ].surf = s[ index ]; + } + + _pico_free( s ); + return 1; } /* -====================================================================== -lwGetVertNormals() - -Calculate the vertex normals. For each polygon vertex, sum the -normals of the polygons that share the point. If the normals of the -current and adjacent polygons form an angle greater than the max -smoothing angle for the current polygon's surface, the normal of the -adjacent polygon is excluded from the sum. It's also excluded if the -polygons aren't in the same smoothing group. - -Assumes that lwGetPointPolygons(), lwGetPolyNormals() and -lwResolvePolySurfaces() have already been called. -====================================================================== */ - -void lwGetVertNormals( lwPointList *point, lwPolygonList *polygon ) -{ - int j, k, n, g, h, p; - float a; - - for ( j = 0; j < polygon->count; j++ ) { - for ( n = 0; n < polygon->pol[ j ].nverts; n++ ) { - for ( k = 0; k < 3; k++ ) - polygon->pol[ j ].v[ n ].norm[ k ] = polygon->pol[ j ].norm[ k ]; - - if ( polygon->pol[ j ].surf->smooth <= 0 ) continue; - - p = polygon->pol[ j ].v[ n ].index; - - for ( g = 0; g < point->pt[ p ].npols; g++ ) { - h = point->pt[ p ].pol[ g ]; - if ( h == j ) continue; - - if ( polygon->pol[ j ].smoothgrp != polygon->pol[ h ].smoothgrp ) - continue; - a = vecangle( polygon->pol[ j ].norm, polygon->pol[ h ].norm ); - if ( a > polygon->pol[ j ].surf->smooth ) continue; - - for ( k = 0; k < 3; k++ ) - polygon->pol[ j ].v[ n ].norm[ k ] += polygon->pol[ h ].norm[ k ]; - } - - normalize( polygon->pol[ j ].v[ n ].norm ); - } - } + ====================================================================== + lwGetVertNormals() + + Calculate the vertex normals. For each polygon vertex, sum the + normals of the polygons that share the point. If the normals of the + current and adjacent polygons form an angle greater than the max + smoothing angle for the current polygon's surface, the normal of the + adjacent polygon is excluded from the sum. It's also excluded if the + polygons aren't in the same smoothing group. + + Assumes that lwGetPointPolygons(), lwGetPolyNormals() and + lwResolvePolySurfaces() have already been called. + ====================================================================== */ + +void lwGetVertNormals( lwPointList *point, lwPolygonList *polygon ){ + int j, k, n, g, h, p; + float a; + + for ( j = 0; j < polygon->count; j++ ) { + for ( n = 0; n < polygon->pol[ j ].nverts; n++ ) { + for ( k = 0; k < 3; k++ ) + polygon->pol[ j ].v[ n ].norm[ k ] = polygon->pol[ j ].norm[ k ]; + + if ( polygon->pol[ j ].surf->smooth <= 0 ) { + continue; + } + + p = polygon->pol[ j ].v[ n ].index; + + for ( g = 0; g < point->pt[ p ].npols; g++ ) { + h = point->pt[ p ].pol[ g ]; + if ( h == j ) { + continue; + } + + if ( polygon->pol[ j ].smoothgrp != polygon->pol[ h ].smoothgrp ) { + continue; + } + a = vecangle( polygon->pol[ j ].norm, polygon->pol[ h ].norm ); + if ( a > polygon->pol[ j ].surf->smooth ) { + continue; + } + + for ( k = 0; k < 3; k++ ) + polygon->pol[ j ].v[ n ].norm[ k ] += polygon->pol[ h ].norm[ k ]; + } + + normalize( polygon->pol[ j ].v[ n ].norm ); + } + } } /* -====================================================================== -lwFreeTags() - -Free memory used by an lwTagList. -====================================================================== */ - -void lwFreeTags( lwTagList *tlist ) -{ - int i; - - if ( tlist ) { - if ( tlist->tag ) { - for ( i = 0; i < tlist->count; i++ ) - if ( tlist->tag[ i ] ) _pico_free( tlist->tag[ i ] ); - _pico_free( tlist->tag ); - } - memset( tlist, 0, sizeof( lwTagList )); - } + ====================================================================== + lwFreeTags() + + Free memory used by an lwTagList. + ====================================================================== */ + +void lwFreeTags( lwTagList *tlist ){ + int i; + + if ( tlist ) { + if ( tlist->tag ) { + for ( i = 0; i < tlist->count; i++ ) + if ( tlist->tag[ i ] ) { + _pico_free( tlist->tag[ i ] ); + } + _pico_free( tlist->tag ); + } + memset( tlist, 0, sizeof( lwTagList ) ); + } } /* -====================================================================== -lwGetTags() + ====================================================================== + lwGetTags() -Read tag strings from a TAGS chunk in an LWO2 file. The tags are -added to the lwTagList array. -====================================================================== */ + Read tag strings from a TAGS chunk in an LWO2 file. The tags are + added to the lwTagList array. + ====================================================================== */ -int lwGetTags( picoMemStream_t *fp, int cksize, lwTagList *tlist ) -{ - char *buf, *bp; - int i, len, ntags; +int lwGetTags( picoMemStream_t *fp, int cksize, lwTagList *tlist ){ + char *buf, *bp; + int i, len, ntags; - if ( cksize == 0 ) return 1; + if ( cksize == 0 ) { + return 1; + } - /* read the whole chunk */ + /* read the whole chunk */ - set_flen( 0 ); - buf = getbytes( fp, cksize ); - if ( !buf ) return 0; + set_flen( 0 ); + buf = getbytes( fp, cksize ); + if ( !buf ) { + return 0; + } - /* count the strings */ + /* count the strings */ - ntags = 0; - bp = buf; - while ( bp < buf + cksize ) { - len = strlen( bp ) + 1; - len += len & 1; - bp += len; - ++ntags; - } + ntags = 0; + bp = buf; + while ( bp < buf + cksize ) { + len = strlen( bp ) + 1; + len += len & 1; + bp += len; + ++ntags; + } - /* expand the string array to hold the new tags */ + /* expand the string array to hold the new tags */ - tlist->offset = tlist->count; - tlist->count += ntags; - if ( !_pico_realloc( (void *) &tlist->tag, (tlist->count - ntags) * sizeof( char * ), tlist->count * sizeof( char * )) ) - goto Fail; - memset( &tlist->tag[ tlist->offset ], 0, ntags * sizeof( char * )); + tlist->offset = tlist->count; + tlist->count += ntags; + if ( !_pico_realloc( (void *) &tlist->tag, ( tlist->count - ntags ) * sizeof( char * ), tlist->count * sizeof( char * ) ) ) { + goto Fail; + } + memset( &tlist->tag[ tlist->offset ], 0, ntags * sizeof( char * ) ); - /* copy the new tags to the tag array */ + /* copy the new tags to the tag array */ - bp = buf; - for ( i = 0; i < ntags; i++ ) - tlist->tag[ i + tlist->offset ] = sgetS0( (unsigned char **) &bp ); + bp = buf; + for ( i = 0; i < ntags; i++ ) + tlist->tag[ i + tlist->offset ] = sgetS0( (unsigned char **) &bp ); - _pico_free( buf ); - return 1; + _pico_free( buf ); + return 1; Fail: - if ( buf ) _pico_free( buf ); - return 0; + if ( buf ) { + _pico_free( buf ); + } + return 0; } /* -====================================================================== -lwGetPolygonTags() + ====================================================================== + lwGetPolygonTags() -Read polygon tags from a PTAG chunk in an LWO2 file. -====================================================================== */ + Read polygon tags from a PTAG chunk in an LWO2 file. + ====================================================================== */ int lwGetPolygonTags( picoMemStream_t *fp, int cksize, lwTagList *tlist, - lwPolygonList *plist ) -{ - unsigned int type; - int rlen = 0, i, j; - - set_flen( 0 ); - type = getU4( fp ); - rlen = get_flen(); - if ( rlen < 0 ) return 0; - - if ( type != ID_SURF && type != ID_PART && type != ID_SMGP ) { - _pico_memstream_seek( fp, cksize - 4, PICO_SEEK_CUR ); - return 1; - } - - while ( rlen < cksize ) { - i = getVX( fp ) + plist->offset; - j = getVX( fp ) + tlist->offset; - rlen = get_flen(); - if ( rlen < 0 || rlen > cksize ) return 0; - - switch ( type ) { - case ID_SURF: plist->pol[ i ].surf = ( lwSurface * ) (size_t) j; break; - case ID_PART: plist->pol[ i ].part = j; break; - case ID_SMGP: plist->pol[ i ].smoothgrp = j; break; - } - } - - return 1; + lwPolygonList *plist ){ + unsigned int type; + int rlen = 0, i, j; + + set_flen( 0 ); + type = getU4( fp ); + rlen = get_flen(); + if ( rlen < 0 ) { + return 0; + } + + if ( type != ID_SURF && type != ID_PART && type != ID_SMGP ) { + _pico_memstream_seek( fp, cksize - 4, PICO_SEEK_CUR ); + return 1; + } + + while ( rlen < cksize ) { + i = getVX( fp ) + plist->offset; + j = getVX( fp ) + tlist->offset; + rlen = get_flen(); + if ( rlen < 0 || rlen > cksize ) { + return 0; + } + + switch ( type ) { + case ID_SURF: plist->pol[ i ].surf = ( lwSurface * ) (size_t) j; break; + case ID_PART: plist->pol[ i ].part = j; break; + case ID_SMGP: plist->pol[ i ].smoothgrp = j; break; + } + } + + return 1; }