Exemple #1
0
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;
}
Exemple #2
0
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;

}