/*
-======================================================================
-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 = ( int ) 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( 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( &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 * ) 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;
}