lwObject *lwGetObject( char *filename, unsigned int *failID, int *failpos ) { FILE *fp = NULL; lwObject *object; lwLayer *layer; lwNode *node; unsigned int id, formsize, type, cksize; int i, rlen; /* open the file */ fp = fopen( filename, "rb" ); if ( !fp ) return NULL; /* read the first 12 bytes */ set_flen( 0 ); id = getU4( fp ); formsize = getU4( fp ); type = getU4( fp ); if ( 12 != get_flen() ) { fclose( fp ); return NULL; } /* is this a LW object? */ if ( id != ID_FORM ) { fclose( fp ); if ( failpos ) *failpos = 12; return NULL; } if ( type != ID_LWO2 ) { fclose( fp ); if ( type == ID_LWOB ) return lwGetObject5( filename, failID, failpos ); else { if ( failpos ) *failpos = 12; return NULL; } } /* allocate an object and a default layer */ object = calloc( 1, sizeof( lwObject )); if ( !object ) goto Fail; layer = calloc( 1, sizeof( lwLayer )); if ( !layer ) goto Fail; object->layer = layer; /* get the first chunk header */ id = getU4( fp ); cksize = getU4( fp ); if ( 0 > get_flen() ) goto Fail; /* process chunks as they're encountered */ while ( 1 ) { cksize += cksize & 1; switch ( id ) { case ID_LAYR: if ( object->nlayers > 0 ) { layer = calloc( 1, sizeof( lwLayer )); if ( !layer ) goto Fail; lwListAdd( &object->layer, layer ); } object->nlayers++; set_flen( 0 ); layer->index = getU2( fp ); layer->flags = getU2( fp ); layer->pivot[ 0 ] = getF4( fp ); layer->pivot[ 1 ] = getF4( fp ); layer->pivot[ 2 ] = getF4( fp ); layer->name = getS0( fp ); rlen = get_flen(); if ( rlen < 0 || rlen > cksize ) goto Fail; if ( rlen <= cksize - 2 ) layer->parent = getU2( fp ); if ( rlen < cksize ) fseek( fp, cksize - rlen, SEEK_CUR ); break; case ID_PNTS: if ( !lwGetPoints( fp, cksize, &layer->point )) goto Fail; break; case ID_POLS: if ( !lwGetPolygons( fp, cksize, &layer->polygon, layer->point.offset )) goto Fail; break; case ID_VMAP: case ID_VMAD: node = ( lwNode * ) lwGetVMap( fp, cksize, layer->point.offset, layer->polygon.offset, id == ID_VMAD ); if ( !node ) goto Fail; lwListAdd( &layer->vmap, node ); layer->nvmaps++; break; case ID_PTAG: if ( !lwGetPolygonTags( fp, cksize, &object->taglist, &layer->polygon )) goto Fail; break; case ID_BBOX: set_flen( 0 ); for ( i = 0; i < 6; i++ ) layer->bbox[ i ] = getF4( fp ); rlen = get_flen(); if ( rlen < 0 || rlen > cksize ) goto Fail; if ( rlen < cksize ) fseek( fp, cksize - rlen, SEEK_CUR ); break; case ID_TAGS: if ( !lwGetTags( fp, cksize, &object->taglist )) goto Fail; break; case ID_ENVL: node = ( lwNode * ) lwGetEnvelope( fp, cksize ); if ( !node ) goto Fail; lwListAdd( &object->env, node ); object->nenvs++; break; case ID_CLIP: node = ( lwNode * ) lwGetClip( fp, cksize ); if ( !node ) goto Fail; lwListAdd( &object->clip, node ); object->nclips++; break; case ID_SURF: node = ( lwNode * ) lwGetSurface( fp, cksize ); if ( !node ) goto Fail; lwListAdd( &object->surf, node ); object->nsurfs++; break; case ID_DESC: case ID_TEXT: case ID_ICON: default: fseek( fp, cksize, SEEK_CUR ); break; } /* end of the file? */ if ( formsize <= ftell( fp ) - 8 ) break; /* get the next chunk header */ set_flen( 0 ); id = getU4( fp ); cksize = getU4( fp ); if ( 8 != get_flen() ) goto Fail; } fclose( fp ); fp = NULL; if ( object->nlayers == 0 ) object->nlayers = 1; layer = object->layer; while ( layer ) { lwGetBoundingBox( &layer->point, layer->bbox ); lwGetPolyNormals( &layer->point, &layer->polygon ); if ( !lwGetPointPolygons( &layer->point, &layer->polygon )) goto Fail; if ( !lwResolvePolySurfaces( &layer->polygon, &object->taglist, &object->surf, &object->nsurfs )) goto Fail; lwGetVertNormals( &layer->point, &layer->polygon ); if ( !lwGetPointVMaps( &layer->point, layer->vmap )) goto Fail; if ( !lwGetPolyVMaps( &layer->polygon, layer->vmap )) goto Fail; layer = layer->next; } return object; Fail: if ( failID ) *failID = id; if ( fp ) { if ( failpos ) *failpos = ftell( fp ); fclose( fp ); } lwFreeObject( object ); return NULL; }
mesh_t *LoadLWO(char *filename) { unsigned int failID = 0; int failpos; char *sfailID[5]; mesh_t *mesh; lwObject *lwobj = lwGetObject5(filename, &failID, &failpos); memset(sfailID, 0, 5); memcpy(sfailID, &failID, 4); if(failID > 0) printf("failID: %s\n", sfailID); if(lwobj != 0) { //printf("nlayers : %i\n", lwobj->nlayers); if(lwobj->nlayers > 1) return 0; // Read layers and polygons mesh = new mesh_t; int ti = 0; for(int l = 0; l < lwobj->nlayers; l++) { lwPolygonList *polylist = &lwobj->layer[l].polygon; lwPointList *pointlist = &lwobj->layer[l].point; // printf("poly count: %i\n", polylist->count); // printf("point count: %i\n", pointlist->count); int tri_count = 0; for(int p = 0; p < polylist->count; p++) { lwPolygon *poly = &polylist->pol[p]; if(poly->nverts >= 3) { tri_count += (poly->nverts-2); } } mesh->numtris = tri_count; // Allocate mesh->tris = new tri_t[mesh->numtris]; mesh->norms = new norm_t[mesh->numtris]; mesh->c = new col_t[mesh->numtris]; //printf("numtries: %i\n", mesh->numtris); lwPoint *point = pointlist->pt; for(int p = 0; p < polylist->count; p++) { // printf("poly nverts: %i\n", poly->nverts); lwPolygon *poly = &polylist->pol[p]; // printf("surf name: %s\n", poly->surf->name); if(poly->nverts == 3) { lwPoint *v1 = &point[ poly->v[0].index ]; lwPoint *v2 = &point[ poly->v[1].index ]; lwPoint *v3 = &point[ poly->v[2].index ]; float *n1 = poly->v[0].norm; float *n2 = poly->v[1].norm; float *n3 = poly->v[2].norm; SetTri(mesh, ti, v1, v2, v3, n1, n2, n3, poly->surf->color.rgb); ti++; } else { if(poly->nverts > 3) { lwPolygon *poly = &polylist->pol[p]; lwPoint *v1 = &point[ poly->v[0].index ]; lwPoint *v2 = &point[ poly->v[1].index ]; lwPoint *v3 = &point[ poly->v[2].index ]; float *n1 = poly->v[0].norm; float *n2 = poly->v[1].norm; float *n3 = poly->v[2].norm; SetTri(mesh, ti, v1, v2, v3, n1, n2, n3, poly->surf->color.rgb); // printf("normal %g, %g, %g\n", poly->v[0].norm[0], poly->v[0].norm[1], poly->v[0].norm[2]); ti++; for(int i=2; i < poly->nverts-1; i++) { lwPoint *v2 = &point[ poly->v[i].index ]; lwPoint *v3 = &point[ poly->v[i+1].index ]; float *n2 = poly->v[i].norm; float *n3 = poly->v[i+1].norm; SetTri(mesh, ti, v1, v2, v3, n1, n2, n3, poly->surf->color.rgb); ti++; } } else { printf("poly nverts: %i\n", poly->nverts); } } } } } else { printf("failID : %i , failpos: %i\n", failID, failpos); } lwFreeObject(lwobj); return mesh; }