Esempio n. 1
0
static lwTexture *get_texture( char *s )
{
   lwTexture *tex;

   tex = _pico_calloc( 1, sizeof( lwTexture ));
   if ( !tex ) return NULL;

   tex->tmap.size.val[ 0 ] =
   tex->tmap.size.val[ 1 ] =
   tex->tmap.size.val[ 2 ] = 1.0f;
   tex->opacity.val = 1.0f;
   tex->enabled = 1;

   if ( strstr( s, "Image Map" )) {
      tex->type = ID_IMAP;
      if ( strstr( s, "Planar" ))           tex->param.imap.projection = 0;
      else if ( strstr( s, "Cylindrical" )) tex->param.imap.projection = 1;
      else if ( strstr( s, "Spherical" ))   tex->param.imap.projection = 2;
      else if ( strstr( s, "Cubic" ))       tex->param.imap.projection = 3;
      else if ( strstr( s, "Front" ))       tex->param.imap.projection = 4;
      tex->param.imap.aa_strength = 1.0f;
      tex->param.imap.amplitude.val = 1.0f;
      _pico_free( s );
   }
   else {
      tex->type = ID_PROC;
      tex->param.proc.name = s;
   }

   return tex;
}
Esempio n. 2
0
static int add_clip( char *s, lwClip **clist, int *nclips )
{
   lwClip *clip;
   char *p;

   clip = _pico_calloc( 1, sizeof( lwClip ));
   if ( !clip ) return 0;

   clip->contrast.val = 1.0f;
   clip->brightness.val = 1.0f;
   clip->saturation.val = 1.0f;
   clip->gamma.val = 1.0f;

   if ( (p = strstr( s, "(sequence)" ))) {
      p[ -1 ] = 0;
      clip->type = ID_ISEQ;
      clip->source.seq.prefix = s;
      clip->source.seq.digits = 3;
   }
   else {
      clip->type = ID_STIL;
      clip->source.still.name = s;
   }

   (*nclips)++;
   clip->index = *nclips;

   lwListAdd( (void *) clist, clip );

   return clip->index;
}
Esempio n. 3
0
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;
}
Esempio n. 4
0
static aseMaterial_t* _ase_add_material( aseMaterial_t **list, int mtlIdParent )
{
	aseMaterial_t *mtl = _pico_calloc( 1, sizeof( aseMaterial_t ) );
	mtl->mtlId = mtlIdParent;
	mtl->subMtls = NULL;
	mtl->next = *list;
	*list = mtl;

	return mtl;
}
Esempio n. 5
0
static int add_tvel( float pos[], float vel[], lwEnvelope **elist, int *nenvs )
{
   lwEnvelope *env;
   lwKey *key0, *key1;
   int i;

   for ( i = 0; i < 3; i++ ) {
      env = _pico_calloc( 1, sizeof( lwEnvelope ));
      key0 = _pico_calloc( 1, sizeof( lwKey ));
      key1 = _pico_calloc( 1, sizeof( lwKey ));
      if ( !env || !key0 || !key1 ) return 0;

      key0->next = key1;
      key0->value = pos[ i ];
      key0->time = 0.0f;
      key1->prev = key0;
      key1->value = pos[ i ] + vel[ i ] * 30.0f;
      key1->time = 1.0f;
      key0->shape = key1->shape = ID_LINE;

      env->index = *nenvs + i + 1;
      env->type = 0x0301 + i;
      env->name = _pico_alloc( 11 );
      if ( env->name ) {
         strcpy( env->name, "Position.X" );
         env->name[ 9 ] += i;
      }
      env->key = key0;
      env->nkeys = 2;
      env->behavior[ 0 ] = BEH_LINEAR;
      env->behavior[ 1 ] = BEH_LINEAR;

      lwListAdd( (void *) elist, env );
   }

   *nenvs += 3;
   return env->index - 2;
}
Esempio n. 6
0
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 ) ( (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;
}
Esempio n. 7
0
void PicoFixSurfaceNormals (picoSurface_t* surface)
{
	picoVec3_t* normals = (picoVec3_t*) _pico_calloc(surface->numVertexes, sizeof(picoVec3_t));

	_pico_normals_zero(normals, normals + surface->numVertexes);

	_pico_triangles_generate_weighted_normals(surface->index, surface->index + surface->numIndexes, surface->xyz,
			normals);
	_pico_vertices_combine_shared_normals(surface->xyz, surface->smoothingGroup, normals, surface->numVertexes);

	_pico_normals_normalize(normals, normals + surface->numVertexes);

	_pico_normals_assign_generated_normals(surface->normal, surface->normal + surface->numVertexes, normals);

	_pico_free(normals);
}
Esempio n. 8
0
static aseSubMaterial_t* _ase_add_submaterial( aseMaterial_t **list, int mtlIdParent, int subMtlId, picoShader_t* shader )
{
	aseMaterial_t *parent = _ase_get_material( *list,  mtlIdParent );
	aseSubMaterial_t *subMtl = _pico_calloc( 1, sizeof ( aseSubMaterial_t ) );

	if ( !parent )
	{
		parent = _ase_add_material ( list , mtlIdParent );
	}

	subMtl->shader = shader;
	subMtl->subMtlId = subMtlId;
	subMtl->next = parent->subMtls;
	parent->subMtls = subMtl;

	return subMtl;
}
Esempio n. 9
0
lwTexture *lwGetTexture( picoMemStream_t *fp, int bloksz, unsigned int type ) {
    lwTexture *tex;
    unsigned short sz;
    int ok;

    tex = _pico_calloc( 1, sizeof( lwTexture ) );
    if ( !tex ) {
        return NULL;
    }

    tex->type = type;
    tex->tmap.size.val[ 0 ] =
        tex->tmap.size.val[ 1 ] =
            tex->tmap.size.val[ 2 ] = 1.0f;
    tex->opacity.val = 1.0f;
    tex->enabled = 1;

    sz = getU2( fp );
    if ( !lwGetTHeader( fp, sz, tex ) ) {
        _pico_free( tex );
        return NULL;
    }

    sz = bloksz - sz - 6;
    switch ( type ) {
    case ID_IMAP:
        ok = lwGetImageMap( fp, sz, tex );
        break;
    case ID_PROC:
        ok = lwGetProcedural( fp, sz, tex );
        break;
    case ID_GRAD:
        ok = lwGetGradient( fp, sz, tex );
        break;
    default:
        ok = !_pico_memstream_seek( fp, sz, PICO_SEEK_CUR );
    }

    if ( !ok ) {
        lwFreeTexture( tex );
        return NULL;
    }

    set_flen( bloksz );
    return tex;
}
Esempio n. 10
0
lwSurface *lwDefaultSurface( void ){
	lwSurface *surf;

	surf = _pico_calloc( 1, sizeof( lwSurface ) );
	if ( !surf ) {
		return NULL;
	}

	surf->color.rgb[ 0 ] = 0.78431f;
	surf->color.rgb[ 1 ] = 0.78431f;
	surf->color.rgb[ 2 ] = 0.78431f;
	surf->diffuse.val    = 1.0f;
	surf->glossiness.val = 0.4f;
	surf->bump.val       = 1.0f;
	surf->eta.val        = 1.0f;
	surf->sideflags      = 1;

	return surf;
}
Esempio n. 11
0
lwPlugin *lwGetShader( picoMemStream_t *fp, int bloksz ){
	lwPlugin *shdr;
	unsigned int id;
	unsigned short sz;
	int hsz, rlen, pos;

	shdr = _pico_calloc( 1, sizeof( lwPlugin ) );
	if ( !shdr ) {
		return NULL;
	}

	pos = _pico_memstream_tell( fp );
	set_flen( 0 );
	hsz = getU2( fp );
	shdr->ord = getS0( fp );
	id = getU4( fp );
	sz = getU2( fp );
	if ( 0 > get_flen() ) {
		goto Fail;
	}

	while ( hsz > 0 ) {
		sz += sz & 1;
		hsz -= sz;
		if ( id == ID_ENAB ) {
			shdr->flags = getU2( fp );
			break;
		}
		else {
			_pico_memstream_seek( fp, sz, PICO_SEEK_CUR );
			id = getU4( fp );
			sz = getU2( fp );
		}
	}

	id = getU4( fp );
	sz = getU2( fp );
	if ( 0 > get_flen() ) {
		goto Fail;
	}

	while ( 1 ) {
		sz += sz & 1;
		set_flen( 0 );

		switch ( id ) {
		case ID_FUNC:
			shdr->name = getS0( fp );
			rlen = get_flen();
			shdr->data = getbytes( fp, sz - rlen );
			break;

		default:
			break;
		}

		/* error while reading the current subchunk? */

		rlen = get_flen();
		if ( rlen < 0 || rlen > sz ) {
			goto Fail;
		}

		/* skip unread parts of the current subchunk */

		if ( rlen < sz ) {
			_pico_memstream_seek( fp, sz - rlen, PICO_SEEK_CUR );
		}

		/* end of the shader block? */

		if ( bloksz <= _pico_memstream_tell( fp ) - pos ) {
			break;
		}

		/* get the next subchunk header */

		set_flen( 0 );
		id = getU4( fp );
		sz = getU2( fp );
		if ( 6 != get_flen() ) {
			goto Fail;
		}
	}

	set_flen( _pico_memstream_tell( fp ) - pos );
	return shdr;

Fail:
	lwFreePlugin( shdr );
	return NULL;
}
Esempio n. 12
0
int lwGetGradient( picoMemStream_t *fp, int rsz, lwTexture *tex ){
	unsigned int id;
	unsigned short sz;
	int rlen, pos, i, j, nkeys;

	pos = _pico_memstream_tell( fp );
	id = getU4( fp );
	sz = getU2( fp );
	if ( 0 > get_flen() ) {
		return 0;
	}

	while ( 1 ) {
		sz += sz & 1;
		set_flen( 0 );

		switch ( id ) {
		case ID_TMAP:
			if ( !lwGetTMap( fp, sz, &tex->tmap ) ) {
				return 0;
			}
			break;

		case ID_PNAM:
			tex->param.grad.paramname = getS0( fp );
			break;

		case ID_INAM:
			tex->param.grad.itemname = getS0( fp );
			break;

		case ID_GRST:
			tex->param.grad.start = getF4( fp );
			break;

		case ID_GREN:
			tex->param.grad.end = getF4( fp );
			break;

		case ID_GRPT:
			tex->param.grad.repeat = getU2( fp );
			break;

		case ID_FKEY:
			nkeys = sz / sizeof( lwGradKey );
			tex->param.grad.key = _pico_calloc( nkeys, sizeof( lwGradKey ) );
			if ( !tex->param.grad.key ) {
				return 0;
			}
			for ( i = 0; i < nkeys; i++ ) {
				tex->param.grad.key[ i ].value = getF4( fp );
				for ( j = 0; j < 4; j++ )
					tex->param.grad.key[ i ].rgba[ j ] = getF4( fp );
			}
			break;

		case ID_IKEY:
			nkeys = sz / 2;
			tex->param.grad.ikey = _pico_calloc( nkeys, sizeof( short ) );
			if ( !tex->param.grad.ikey ) {
				return 0;
			}
			for ( i = 0; i < nkeys; i++ )
				tex->param.grad.ikey[ i ] = getU2( fp );
			break;

		default:
			break;
		}

		/* error while reading the current subchunk? */

		rlen = get_flen();
		if ( rlen < 0 || rlen > sz ) {
			return 0;
		}

		/* skip unread parts of the current subchunk */

		if ( rlen < sz ) {
			_pico_memstream_seek( fp, sz - rlen, PICO_SEEK_CUR );
		}

		/* end of the gradient? */

		if ( rsz <= _pico_memstream_tell( fp ) - pos ) {
			break;
		}

		/* get the next subchunk header */

		set_flen( 0 );
		id = getU4( fp );
		sz = getU2( fp );
		if ( 6 != get_flen() ) {
			return 0;
		}
	}

	set_flen( _pico_memstream_tell( fp ) - pos );
	return 1;
}
Esempio n. 13
0
lwObject *lwGetObject5( char *filename, picoMemStream_t *fp, unsigned int *failID, int *failpos )
{
   lwObject *object;
   lwLayer *layer;
   lwNode *node;
   unsigned int id, formsize, type, cksize;


   /* open the file */

   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() ) {
      return NULL;
   }

   /* LWOB? */

   if ( id != ID_FORM || type != ID_LWOB ) {
      if ( failpos ) *failpos = 12;
      return NULL;
   }

   /* allocate an object and a default layer */

   object = _pico_calloc( 1, sizeof( lwObject ));
   if ( !object ) goto Fail;

   layer = _pico_calloc( 1, sizeof( lwLayer ));
   if ( !layer ) goto Fail;
   object->layer = layer;
   object->nlayers = 1;

   /* 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_PNTS:
            if ( !lwGetPoints( fp, cksize, &layer->point ))
               goto Fail;
            break;

         case ID_POLS:
            if ( !lwGetPolygons5( fp, cksize, &layer->polygon,
               layer->point.offset ))
               goto Fail;
            break;

         case ID_SRFS:
            if ( !lwGetTags( fp, cksize, &object->taglist ))
               goto Fail;
            break;

         case ID_SURF:
            node = ( lwNode * ) lwGetSurface5( fp, cksize, object );
            if ( !node ) goto Fail;
            lwListAdd( (void *) &object->surf, node );
            object->nsurfs++;
            break;

         default:
            _pico_memstream_seek( fp, cksize, PICO_SEEK_CUR );
            break;
      }

      /* end of the file? */

      if ( formsize <= _pico_memstream_tell( fp ) - 8 ) break;

      /* get the next chunk header */

      set_flen( 0 );
      id = getU4( fp );
      cksize = getU4( fp );
      if ( 8 != get_flen() ) goto Fail;
   }

   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 );

   return object;

Fail:
   if ( failID ) *failID = id;
   if ( fp ) {
      if ( failpos ) *failpos = _pico_memstream_tell( fp );
   }
   lwFreeObject( object );
   return NULL;
}
Esempio n. 14
0
lwSurface *lwGetSurface5( picoMemStream_t *fp, int cksize, lwObject *obj )
{
   lwSurface *surf;
   lwTexture *tex;
   lwPlugin *shdr;
   char *s;
   float v[ 3 ];
   unsigned int id, flags;
   unsigned short sz;
   int pos, rlen, i;

   tex = NULL;
   shdr = NULL;

   /* allocate the Surface structure */

   surf = _pico_calloc( 1, sizeof( lwSurface ));
   if ( !surf ) goto Fail;

   /* non-zero defaults */

   surf->color.rgb[ 0 ] = 0.78431f;
   surf->color.rgb[ 1 ] = 0.78431f;
   surf->color.rgb[ 2 ] = 0.78431f;
   surf->diffuse.val    = 1.0f;
   surf->glossiness.val = 0.4f;
   surf->bump.val       = 1.0f;
   surf->eta.val        = 1.0f;
   surf->sideflags      = 1;

   /* remember where we started */

   set_flen( 0 );
   pos = _pico_memstream_tell( fp );

   /* name */

   surf->name = getS0( fp );

   /* first subchunk header */

   id = getU4( fp );
   sz = getU2( fp );
   if ( 0 > get_flen() ) goto Fail;

   /* process subchunks as they're encountered */

   while ( 1 ) {
      sz += sz & 1;
      set_flen( 0 );

      switch ( id ) {
         case ID_COLR:
            surf->color.rgb[ 0 ] = getU1( fp ) / 255.0f;
            surf->color.rgb[ 1 ] = getU1( fp ) / 255.0f;
            surf->color.rgb[ 2 ] = getU1( fp ) / 255.0f;
            break;

         case ID_FLAG:
            flags = getU2( fp );
            if ( flags &   4 ) surf->smooth = 1.56207f;
            if ( flags &   8 ) surf->color_hilite.val = 1.0f;
            if ( flags &  16 ) surf->color_filter.val = 1.0f;
            if ( flags & 128 ) surf->dif_sharp.val = 0.5f;
            if ( flags & 256 ) surf->sideflags = 3;
            if ( flags & 512 ) surf->add_trans.val = 1.0f;
            break;

         case ID_LUMI:
            surf->luminosity.val = getI2( fp ) / 256.0f;
            break;

         case ID_VLUM:
            surf->luminosity.val = getF4( fp );
            break;

         case ID_DIFF:
            surf->diffuse.val = getI2( fp ) / 256.0f;
            break;

         case ID_VDIF:
            surf->diffuse.val = getF4( fp );
            break;

         case ID_SPEC:
            surf->specularity.val = getI2( fp ) / 256.0f;
            break;

         case ID_VSPC:
            surf->specularity.val = getF4( fp );
            break;

         case ID_GLOS:
            surf->glossiness.val = ( float ) log( getU2( fp )) / 20.7944f;
            break;

         case ID_SMAN:
            surf->smooth = getF4( fp );
            break;

         case ID_REFL:
            surf->reflection.val.val = getI2( fp ) / 256.0f;
            break;

         case ID_RFLT:
            surf->reflection.options = getU2( fp );
            break;

         case ID_RIMG:
            s = getS0( fp );
            surf->reflection.cindex = add_clip( s, &obj->clip, &obj->nclips );
            surf->reflection.options = 3;
            break;

         case ID_RSAN:
            surf->reflection.seam_angle = getF4( fp );
            break;

         case ID_TRAN:
            surf->transparency.val.val = getI2( fp ) / 256.0f;
            break;

         case ID_RIND:
            surf->eta.val = getF4( fp );
            break;

         case ID_BTEX:
            s = getbytes( fp, sz );
            tex = get_texture( s );
            lwListAdd( (void *) &surf->bump.tex, tex );
            break;

         case ID_CTEX:
            s = getbytes( fp, sz );
            tex = get_texture( s );
            lwListAdd( (void *) &surf->color.tex, tex );
            break;

         case ID_DTEX:
            s = getbytes( fp, sz );
            tex = get_texture( s );
            lwListAdd( (void *) &surf->diffuse.tex, tex );
            break;

         case ID_LTEX:
            s = getbytes( fp, sz );
            tex = get_texture( s );
            lwListAdd( (void *) &surf->luminosity.tex, tex );
            break;

         case ID_RTEX:
            s = getbytes( fp, sz );
            tex = get_texture( s );
            lwListAdd( (void *) &surf->reflection.val.tex, tex );
            break;

         case ID_STEX:
            s = getbytes( fp, sz );
            tex = get_texture( s );
            lwListAdd( (void *) &surf->specularity.tex, tex );
            break;

         case ID_TTEX:
            s = getbytes( fp, sz );
            tex = get_texture( s );
            lwListAdd( (void *) &surf->transparency.val.tex, tex );
            break;

         case ID_TFLG:
            flags = getU2( fp );

			i = 0; // greebo: initialise to fix compiler warnings

            if ( flags & 1 ) i = 0;
            if ( flags & 2 ) i = 1;
            if ( flags & 4 ) i = 2;
            tex->axis = i;
            if ( tex->type == ID_IMAP )
               tex->param.imap.axis = i;
            else
               tex->param.proc.axis = i;

            if ( flags &  8 ) tex->tmap.coord_sys = 1;
            if ( flags & 16 ) tex->negative = 1;
            if ( flags & 32 ) tex->param.imap.pblend = 1;
            if ( flags & 64 ) {
               tex->param.imap.aa_strength = 1.0f;
               tex->param.imap.aas_flags = 1;
            }
            break;

         case ID_TSIZ:
            for ( i = 0; i < 3; i++ )
               tex->tmap.size.val[ i ] = getF4( fp );
            break;

         case ID_TCTR:
            for ( i = 0; i < 3; i++ )
               tex->tmap.center.val[ i ] = getF4( fp );
            break;

         case ID_TFAL:
            for ( i = 0; i < 3; i++ )
               tex->tmap.falloff.val[ i ] = getF4( fp );
            break;

         case ID_TVEL:
            for ( i = 0; i < 3; i++ )
               v[ i ] = getF4( fp );
            tex->tmap.center.eindex = add_tvel( tex->tmap.center.val, v,
               &obj->env, &obj->nenvs );
            break;

         case ID_TCLR:
            if ( tex->type == ID_PROC )
               for ( i = 0; i < 3; i++ )
                  tex->param.proc.value[ i ] = getU1( fp ) / 255.0f;
            break;

         case ID_TVAL:
            tex->param.proc.value[ 0 ] = getI2( fp ) / 256.0f;
            break;

         case ID_TAMP:
            if ( tex->type == ID_IMAP )
               tex->param.imap.amplitude.val = getF4( fp );
            break;

         case ID_TIMG:
            s = getS0( fp );
            tex->param.imap.cindex = add_clip( s, &obj->clip, &obj->nclips );
            break;

         case ID_TAAS:
            tex->param.imap.aa_strength = getF4( fp );
            tex->param.imap.aas_flags = 1;
            break;

         case ID_TREF:
            tex->tmap.ref_object = getbytes( fp, sz );
            break;

         case ID_TOPC:
            tex->opacity.val = getF4( fp );
            break;

         case ID_TFP0:
            if ( tex->type == ID_IMAP )
               tex->param.imap.wrapw.val = getF4( fp );
            break;

         case ID_TFP1:
            if ( tex->type == ID_IMAP )
               tex->param.imap.wraph.val = getF4( fp );
            break;

         case ID_SHDR:
            shdr = _pico_calloc( 1, sizeof( lwPlugin ));
            if ( !shdr ) goto Fail;
            shdr->name = getbytes( fp, sz );
            lwListAdd( (void *) &surf->shader, shdr );
            surf->nshaders++;
            break;

         case ID_SDAT:
            shdr->data = getbytes( fp, sz );
            break;

         default:
            break;
      }

      /* error while reading current subchunk? */

      rlen = get_flen();
      if ( rlen < 0 || rlen > sz ) goto Fail;

      /* skip unread parts of the current subchunk */

      if ( rlen < sz )
         _pico_memstream_seek( fp, sz - rlen, PICO_SEEK_CUR );

      /* end of the SURF chunk? */

      if ( cksize <= _pico_memstream_tell( fp ) - pos )
         break;

      /* get the next subchunk header */

      set_flen( 0 );
      id = getU4( fp );
      sz = getU2( fp );
      if ( 6 != get_flen() ) goto Fail;
   }

   return surf;

Fail:
   if ( surf ) lwFreeSurface( surf );
   return NULL;
}
Esempio n. 15
0
lwClip *lwGetClip( picoMemStream_t *fp, int cksize ){
	lwClip *clip;
	lwPlugin *filt;
	unsigned int id;
	unsigned short sz;
	int pos, rlen;


	/* allocate the Clip structure */

	clip = _pico_calloc( 1, sizeof( lwClip ) );
	if ( !clip ) {
		goto Fail;
	}

	clip->contrast.val = 1.0f;
	clip->brightness.val = 1.0f;
	clip->saturation.val = 1.0f;
	clip->gamma.val = 1.0f;

	/* remember where we started */

	set_flen( 0 );
	pos = _pico_memstream_tell( fp );

	/* index */

	clip->index = getI4( fp );

	/* first subchunk header */

	clip->type = getU4( fp );
	sz = getU2( fp );
	if ( 0 > get_flen() ) {
		goto Fail;
	}

	sz += sz & 1;
	set_flen( 0 );

	switch ( clip->type ) {
	case ID_STIL:
		clip->source.still.name = getS0( fp );
		break;

	case ID_ISEQ:
		clip->source.seq.digits  = getU1( fp );
		clip->source.seq.flags   = getU1( fp );
		clip->source.seq.offset  = getI2( fp );
		getU2( fp );   /* not sure what this is yet */
		clip->source.seq.start   = getI2( fp );
		clip->source.seq.end     = getI2( fp );
		clip->source.seq.prefix  = getS0( fp );
		clip->source.seq.suffix  = getS0( fp );
		break;

	case ID_ANIM:
		clip->source.anim.name   = getS0( fp );
		clip->source.anim.server = getS0( fp );
		rlen = get_flen();
		clip->source.anim.data   = getbytes( fp, sz - rlen );
		break;

	case ID_XREF:
		clip->source.xref.index  = getI4( fp );
		clip->source.xref.string = getS0( fp );
		break;

	case ID_STCC:
		clip->source.cycle.lo   = getI2( fp );
		clip->source.cycle.hi   = getI2( fp );
		clip->source.cycle.name = getS0( fp );
		break;

	default:
		break;
	}

	/* error while reading current subchunk? */

	rlen = get_flen();
	if ( rlen < 0 || rlen > sz ) {
		goto Fail;
	}

	/* skip unread parts of the current subchunk */

	if ( rlen < sz ) {
		_pico_memstream_seek( fp, sz - rlen, PICO_SEEK_CUR );
	}

	/* end of the CLIP chunk? */

	rlen = _pico_memstream_tell( fp ) - pos;
	if ( cksize < rlen ) {
		goto Fail;
	}
	if ( cksize == rlen ) {
		return clip;
	}

	/* process subchunks as they're encountered */

	id = getU4( fp );
	sz = getU2( fp );
	if ( 0 > get_flen() ) {
		goto Fail;
	}

	while ( 1 ) {
		sz += sz & 1;
		set_flen( 0 );

		switch ( id ) {
		case ID_TIME:
			clip->start_time = getF4( fp );
			clip->duration = getF4( fp );
			clip->frame_rate = getF4( fp );
			break;

		case ID_CONT:
			clip->contrast.val = getF4( fp );
			clip->contrast.eindex = getVX( fp );
			break;

		case ID_BRIT:
			clip->brightness.val = getF4( fp );
			clip->brightness.eindex = getVX( fp );
			break;

		case ID_SATR:
			clip->saturation.val = getF4( fp );
			clip->saturation.eindex = getVX( fp );
			break;

		case ID_HUE:
			clip->hue.val = getF4( fp );
			clip->hue.eindex = getVX( fp );
			break;

		case ID_GAMM:
			clip->gamma.val = getF4( fp );
			clip->gamma.eindex = getVX( fp );
			break;

		case ID_NEGA:
			clip->negative = getU2( fp );
			break;

		case ID_IFLT:
		case ID_PFLT:
			filt = _pico_calloc( 1, sizeof( lwPlugin ) );
			if ( !filt ) {
				goto Fail;
			}

			filt->name = getS0( fp );
			filt->flags = getU2( fp );
			rlen = get_flen();
			filt->data = getbytes( fp, sz - rlen );

			if ( id == ID_IFLT ) {
				lwListAdd( &clip->ifilter, filt );
				clip->nifilters++;
			}
			else {
				lwListAdd( &clip->pfilter, filt );
				clip->npfilters++;
			}
			break;

		default:
			break;
		}

		/* error while reading current subchunk? */

		rlen = get_flen();
		if ( rlen < 0 || rlen > sz ) {
			goto Fail;
		}

		/* skip unread parts of the current subchunk */

		if ( rlen < sz ) {
			_pico_memstream_seek( fp, sz - rlen, PICO_SEEK_CUR );
		}

		/* end of the CLIP chunk? */

		rlen = _pico_memstream_tell( fp ) - pos;
		if ( cksize < rlen ) {
			goto Fail;
		}
		if ( cksize == rlen ) {
			break;
		}

		/* get the next chunk header */

		set_flen( 0 );
		id = getU4( fp );
		sz = getU2( fp );
		if ( 6 != get_flen() ) {
			goto Fail;
		}
	}

	return clip;

Fail:
	lwFreeClip( clip );
	return NULL;
}
Esempio n. 16
0
lwObject *lwGetObject( char *filename, picoMemStream_t *fp, unsigned int *failID, int *failpos ){
	lwObject *object;
	lwLayer *layer;
	lwNode *node;
	unsigned int id, formsize, type, cksize;
	int i, rlen;

	/* open the file */

	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() ) {
		return NULL;
	}

	/* is this a LW object? */

	if ( id != ID_FORM ) {
		if ( failpos ) {
			*failpos = 12;
		}
		return NULL;
	}

	if ( type != ID_LWO2 ) {
		if ( type == ID_LWOB ) {
			return lwGetObject5( filename, fp, failID, failpos );
		}
		else {
			if ( failpos ) {
				*failpos = 12;
			}
			return NULL;
		}
	}

	/* allocate an object and a default layer */

	object = _pico_calloc( 1, sizeof( lwObject ) );
	if ( !object ) {
		goto Fail;
	}

	layer = _pico_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 = _pico_calloc( 1, sizeof( lwLayer ) );
				if ( !layer ) {
					goto Fail;
				}
				lwListAdd( (void **) &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 );
			}
			rlen = get_flen();
			if ( rlen < cksize ) {
				_pico_memstream_seek( fp, cksize - rlen, PICO_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( (void **) &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 ) {
				_pico_memstream_seek( fp, cksize - rlen, PICO_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( (void **) &object->env, node );
			object->nenvs++;
			break;

		case ID_CLIP:
			node = ( lwNode * ) lwGetClip( fp, cksize );
			if ( !node ) {
				goto Fail;
			}
			lwListAdd( (void **) &object->clip, node );
			object->nclips++;
			break;

		case ID_SURF:
			node = ( lwNode * ) lwGetSurface( fp, cksize );
			if ( !node ) {
				goto Fail;
			}
			lwListAdd( (void **) &object->surf, node );
			object->nsurfs++;
			break;

		case ID_DESC:
		case ID_TEXT:
		case ID_ICON:
		default:
			_pico_memstream_seek( fp, cksize, PICO_SEEK_CUR );
			break;
		}

		/* end of the file? */

		if ( formsize <= _pico_memstream_tell( fp ) - 8 ) {
			break;
		}

		/* get the next chunk header */

		set_flen( 0 );
		id = getU4( fp );
		cksize = getU4( fp );
		if ( 8 != get_flen() ) {
			goto Fail;
		}
	}

	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 = _pico_memstream_tell( fp );
		}
	}
	lwFreeObject( object );
	return NULL;
}
Esempio n. 17
0
static void binarytree_reserve (BinaryTree* self, size_t size)
{
	self->data = self->last = _pico_calloc(size, sizeof(BinaryTreeNode));
}
Esempio n. 18
0
/* _ase_load:
 *  loads a 3dsmax ase model file.
*/
static picoModel_t *_ase_load( PM_PARAMS_LOAD )
{
	picoModel_t    *model;
	picoParser_t   *p;
	char			lastNodeName[ 1024 ];

	aseVertex_t* vertices = NULL;
	aseTexCoord_t* texcoords = NULL;
	aseColor_t* colors = NULL;
	aseFace_t* faces = NULL;
	int numVertices = 0;
	int numFaces = 0;
	int numTextureVertices = 0;
	int numTextureVertexFaces = 0;
	int numColorVertices = 0;
	int numColorVertexFaces = 0;
	int vertexId = 0;
   int currentVertexFace=0;
   int currentVertexIndex=0;
   int counter=0;
   int submodel=0;

	aseMaterial_t* materials = NULL;

#ifdef DEBUG_PM_ASE
	clock_t start, finish;
	double elapsed;
	start = clock();
#endif

	/* helper */
	#define _ase_error_return(m) \
	{ \
		_pico_printf( PICO_ERROR,"%s in ASE, line %d.",m,p->curLine); \
		_pico_free_parser( p ); \
		PicoFreeModel( model ); \
		return NULL; \
	}
	/* create a new pico parser */
	p = _pico_new_parser( (picoByte_t *)buffer,bufSize );
	if (p == NULL) return NULL;

	/* create a new pico model */
	model = PicoNewModel();
	if (model == NULL)
	{
		_pico_free_parser( p );
		return NULL;
	}
	/* do model setup */
	PicoSetModelFrameNum( model, frameNum );
	PicoSetModelName( model, fileName );
	PicoSetModelFileName( model, fileName );

	/* initialize some stuff */
	memset( lastNodeName,0,sizeof(lastNodeName) );

	/* parse ase model file */
	while( 1 )
	{
		/* get first token on line */
		if (_pico_parse_first( p ) == NULL)
			break;

		/* we just skip empty lines */
		if (p->token == NULL || !strlen( p->token ))
			continue;

		/* we skip invalid ase statements */
		if (p->token[0] != '*' && p->token[0] != '{' && p->token[0] != '}')
		{
			_pico_parse_skip_rest( p );
			continue;
		}
		/* remember node name */
		if (!_pico_stricmp(p->token,"*node_name"))
		{
			/* read node name */
			char *ptr = _pico_parse( p,0 );
			if (ptr == NULL)
				_ase_error_return("Node name parse error");

			/* remember node name */
			strncpy( lastNodeName,ptr,sizeof(lastNodeName) );
		}
		/* model mesh (originally contained within geomobject) */
		else if (!_pico_stricmp(p->token,"*mesh"))
		{
			/* finish existing surface */
			_ase_submit_triangles(model, materials, vertices, texcoords, colors, faces, numFaces,numVertices,submodel++);
			_pico_free(faces);
			_pico_free(vertices);
			_pico_free(texcoords);
			_pico_free(colors);
		}
		else if (!_pico_stricmp(p->token,"*mesh_numvertex"))
		{
  			if (!_pico_parse_int( p, &numVertices) )
				_ase_error_return("Missing MESH_NUMVERTEX value");

			vertices = _pico_calloc(numVertices, sizeof(aseVertex_t));
         currentVertexIndex=0;   
		}
		else if (!_pico_stricmp(p->token,"*mesh_numfaces"))
		{
			if (!_pico_parse_int( p, &numFaces) )
				_ase_error_return("Missing MESH_NUMFACES value");

			faces = _pico_calloc(numFaces, sizeof(aseFace_t));

		}
		else if (!_pico_stricmp(p->token,"*mesh_numtvertex"))
		{
			if (!_pico_parse_int( p, &numTextureVertices) )
				_ase_error_return("Missing MESH_NUMTVERTEX value");

			texcoords = _pico_calloc(numTextureVertices, sizeof(aseTexCoord_t));
		}
		else if (!_pico_stricmp(p->token,"*mesh_numtvfaces"))
		{
			if (!_pico_parse_int( p, &numTextureVertexFaces) )
				_ase_error_return("Missing MESH_NUMTVFACES value");
		}
		else if (!_pico_stricmp(p->token,"*mesh_numcvertex"))
		{
			if (!_pico_parse_int( p, &numColorVertices) )
				_ase_error_return("Missing MESH_NUMCVERTEX value");

			colors = _pico_calloc(numColorVertices, sizeof(aseColor_t));
			memset( colors, 255, numColorVertices * sizeof( aseColor_t ) );	/* ydnar: force colors to white initially */
		}
		else if (!_pico_stricmp(p->token,"*mesh_numcvfaces"))
		{
			if (!_pico_parse_int( p, &numColorVertexFaces) )
				_ase_error_return("Missing MESH_NUMCVFACES value");
		}
		/* mesh material reference. this usually comes at the end of */
		/* geomobjects after the mesh blocks. we must assume that the */
		/* new mesh was already created so all we can do here is assign */
		/* the material reference id (shader index) now. */
		else if (!_pico_stricmp(p->token,"*material_ref"))
		{
			int mtlId;

			/* get the material ref (0..n) */
			if (!_pico_parse_int( p,&mtlId) )
				_ase_error_return("Missing material reference ID");

			{
				int i = 0;
				/* fix up all of the aseFaceList in the surface to point to the parent material */
				/* we've already saved off their subMtl */
				for(; i < numFaces; ++i)
				{
					faces[i].materialId = mtlId;
				}
			}
		}
		/* model mesh vertex */
		else if (!_pico_stricmp(p->token,"*mesh_vertex"))
		{
			int			index;

			if( numVertices == 0 )
				_ase_error_return("Vertex parse error");

			/* get vertex data (orig: index +y -x +z) */
			if (!_pico_parse_int( p,&index ))
				_ase_error_return("Vertex parse error");
			if (!_pico_parse_vec( p,vertices[index].xyz ))
				_ase_error_return("Vertex parse error");

			vertices[index].id = vertexId++;
		}
		else if (!_pico_stricmp(p->token,"*mesh_facenormal"))
		{
		   //Grab the faceindex for the next vertex normals.
         if( numVertices == 0 )
				_ase_error_return("Vertex parse error (facenormals)");

         if (!_pico_parse_int( p,&currentVertexFace ))
				_ase_error_return("Vertex parse error");

 			if (!_pico_parse_vec( p,faces[currentVertexFace].facenormal ))
				_ase_error_return("Vertex parse error");

      }
      /* model mesh vertex normal */
		else if (!_pico_stricmp(p->token,"*mesh_vertexnormal"))
		{
			int			index;

			if( numVertices == 0 )
				_ase_error_return("Vertex parse error");

			/* get vertex data (orig: index +y -x +z) */
			if (!_pico_parse_int( p,&index ))
				_ase_error_return("Vertex parse error");

         //^^ Index is 'wrong' in .ase models.  they reference the same vert index with multiple normals..
         // I've tried, this is a lost cause.  Use the SG's
         // 
			/*
         
         if (!_pico_parse_vec( p,vertices[counter].normal ))
				_ase_error_return("Vertex parse error");
         vertices[counter].faceid=index;
         counter++;
         */
		}
		/* model mesh face */
		else if (!_pico_stricmp(p->token,"*mesh_normals"))
      {
      //   counter=0; //part of the above vertex normals fix
      }
         
      /* model mesh face */
		else if (!_pico_stricmp(p->token,"*mesh_face"))
		{
			picoIndex_t indexes[3];
			int index;
			
			if( numFaces == 0 )
				_ase_error_return("Face parse error");

			/* get face index */
			if (!_pico_parse_int( p,&index ))
				_ase_error_return("Face parse error");

			/* get 1st vertex index */
			_pico_parse( p,0 );
			if (!_pico_parse_int( p,&indexes[0] ))
				_ase_error_return("Face parse error");

			/* get 2nd vertex index */
			_pico_parse( p,0 );
			if (!_pico_parse_int( p,&indexes[1] ))
				_ase_error_return("Face parse error");

			/* get 3rd vertex index */
			_pico_parse( p,0 );
			if (!_pico_parse_int( p,&indexes[2] ))
				_ase_error_return("Face parse error");
			
			/* parse to the subMaterial ID */
			while ( 1 )
			{
				if (!_pico_parse (p,0)) /* EOL */
				{
					break;
				}
				if (!_pico_stricmp (p->token,"*MESH_SMOOTHING" ))
				{
               int total=0;
               char* point;
               char* start;
               _pico_parse(p,0);

               point=p->token;
               start=point;
               faces[index].smoothingGroup=0;
              
               //Super dodgy comma delimited string parse
               while (*point<'A') 
               {
                  if (*point<=32 || *point==',')
                  {
                     total=atoi(start);
                     if (total!=0)
                     {
                        faces[index].smoothingGroup+=1<<total;
                     }
                     start=point+1;
                  }
                  
                  point++;
               }
               
               
			      
               
            }
				if (!_pico_stricmp (p->token,"*MESH_MTLID" ))
				{
					_pico_parse_int ( p , &faces[index].subMaterialId );
				}
			}
			
			faces[index].materialId = 0;
			faces[index].indices[0] = indexes[2];
			faces[index].indices[1] = indexes[1];
			faces[index].indices[2] = indexes[0];
		}
		/* model texture vertex */
		else if (!_pico_stricmp(p->token,"*mesh_tvert"))
		{
			int			index;

			if( numVertices == 0 )
				_ase_error_return("Vertex parse error");

			/* get uv vertex index */
			if (!_pico_parse_int( p,&index ))
				_ase_error_return("UV vertex parse error");

			/* get uv vertex s */
			if (!_pico_parse_float( p,&texcoords[index].texcoord[0] ))
				_ase_error_return("UV vertex parse error");

			/* get uv vertex t */
			if (!_pico_parse_float( p,&texcoords[index].texcoord[1] ))
				_ase_error_return("UV vertex parse error");
			
			/* ydnar: invert t */
			texcoords[index].texcoord[ 1 ] = 1.0f - texcoords[index].texcoord[ 1 ];
		}
		/* ydnar: model mesh texture face */
		else if( !_pico_stricmp( p->token, "*mesh_tface" ) )
		{
			picoIndex_t indexes[3];
			int			index;
			
			if( numFaces == 0 )
				_ase_error_return("Texture face parse error");
			
			/* get face index */
			if (!_pico_parse_int( p,&index ))
				_ase_error_return("Texture face parse error");
			
			/* get 1st vertex index */
			if (!_pico_parse_int( p,&indexes[0] ))
				_ase_error_return("Texture face parse error");
			
			/* get 2nd vertex index */
			if (!_pico_parse_int( p,&indexes[1] ))
				_ase_error_return("Texture face parse error");
			
			/* get 3rd vertex index */
			if (!_pico_parse_int( p,&indexes[2] ))
				_ase_error_return("Texture face parse error");

			faces[index].indices[3] = indexes[2];
			faces[index].indices[4] = indexes[1];
			faces[index].indices[5] = indexes[0];
		}
		/* model color vertex */
		else if (!_pico_stricmp(p->token,"*mesh_vertcol"))
		{
			int			index;
			float		colorInput;

			if( numVertices == 0 )
				_ase_error_return("Color Vertex parse error");

			/* get color vertex index */
			if (!_pico_parse_int( p,&index ))
				_ase_error_return("Color vertex parse error");

			/* get R component */
			if (!_pico_parse_float( p,&colorInput ))
				_ase_error_return("Color vertex parse error");
			colors[index].color[0] = (picoByte_t)(colorInput * 255);

			/* get G component */
			if (!_pico_parse_float( p,&colorInput ))
				_ase_error_return("Color vertex parse error");
			colors[index].color[1] = (picoByte_t)(colorInput * 255);

			/* get B component */
			if (!_pico_parse_float( p,&colorInput ))
				_ase_error_return("Color vertex parse error");
			colors[index].color[2] = (picoByte_t)(colorInput * 255);
			
			/* leave alpha alone since we don't get any data from the ASE format */
			colors[index].color[3] = 255;

         /* 27 hack, red as alpha */
         colors[index].color[3]=colors[index].color[0];
         colors[index].color[0]=255;
         colors[index].color[1]=255;
         colors[index].color[2]=255;

		}
		/* model color face */
		else if (!_pico_stricmp(p->token,"*mesh_cface"))
		{
			picoIndex_t indexes[3];
			int			index;

			if( numFaces == 0 )
				_ase_error_return("Face parse error");

			/* get face index */
			if (!_pico_parse_int( p,&index ))
				_ase_error_return("Face parse error");

			/* get 1st cvertex index */
			//			_pico_parse( p,0 );
			if (!_pico_parse_int( p,&indexes[0] ))
				_ase_error_return("Face parse error");

			/* get 2nd cvertex index */
			//			_pico_parse( p,0 );
			if (!_pico_parse_int( p,&indexes[1] ))
				_ase_error_return("Face parse error");

			/* get 3rd cvertex index */
			//			_pico_parse( p,0 );
			if (!_pico_parse_int( p,&indexes[2] ))
				_ase_error_return("Face parse error");

			faces[index].indices[6] = indexes[2];
			faces[index].indices[7] = indexes[1];
			faces[index].indices[8] = indexes[0];
		}
		/* model material */
		else if( !_pico_stricmp( p->token, "*material" ) )
		{
			aseSubMaterial_t*	subMaterial = NULL;
			picoShader_t		*shader;
			int					level = 1, index;
			char				materialName[ 1024 ];
			float				transValue = 0.0f, shineValue = 1.0f;
			picoColor_t			ambientColor, diffuseColor, specularColor;
			char				*mapname = NULL;
			int					subMtlId, subMaterialLevel = -1;
			
			
			/* get material index */
			_pico_parse_int( p,&index );
			
			/* check brace */
			if (!_pico_parse_check(p,1,"{"))
				_ase_error_return("Material missing opening brace");
			
			/* parse material block */
			while( 1 )
			{
				/* get next token */
				if (_pico_parse(p,1) == NULL) break;
				if (!strlen(p->token)) continue;

				/* handle levels */
				if (p->token[0] == '{') level++;
				if (p->token[0] == '}') level--;
				if (!level) break;

				if( level == subMaterialLevel )
				{
					/* set material name */
					_pico_first_token( materialName );
					PicoSetShaderName( shader, materialName);

					/* set shader's transparency */
					PicoSetShaderTransparency( shader,transValue );

					/* set shader's ambient color */
					PicoSetShaderAmbientColor( shader,ambientColor );

					/* set diffuse alpha to transparency */
					diffuseColor[3] = (picoByte_t)( transValue * 255.0 );

					/* set shader's diffuse color */
					PicoSetShaderDiffuseColor( shader,diffuseColor );

					/* set shader's specular color */
					PicoSetShaderSpecularColor( shader,specularColor );

					/* set shader's shininess */
					PicoSetShaderShininess( shader,shineValue );

					/* set material map name */
					PicoSetShaderMapName( shader, mapname );

					subMaterial = _ase_add_submaterial( &materials, index, subMtlId, shader );
					subMaterialLevel = -1;
				}

				/* parse submaterial index */
				if (!_pico_stricmp(p->token,"*submaterial"))
				{											
					/* allocate new pico shader */
					_pico_parse_int( p , &subMtlId );

					shader = PicoNewShader( model );
					if (shader == NULL)
					{
						PicoFreeModel( model );
						return NULL;
					}			
					subMaterialLevel = level;
				}
				/* parse material name */
				else if (!_pico_stricmp(p->token,"*material_name"))
				{
					char* name = _pico_parse(p,0);
					if ( name == NULL)
						_ase_error_return("Missing material name");
					
					strcpy ( materialName , name );
					/* skip rest and continue with next token */
					_pico_parse_skip_rest( p );
					continue;
				}
				/* parse material transparency */
				else if (!_pico_stricmp(p->token,"*material_transparency"))
				{
					/* get transparency value from ase */
					if (!_pico_parse_float( p,&transValue ))
						_ase_error_return("Material transparency parse error");

					/* skip rest and continue with next token */
					_pico_parse_skip_rest( p );
					continue;
				}
				/* parse material shininess */
				else if (!_pico_stricmp(p->token,"*material_shine"))
				{
					/* remark:
					 * - not sure but instead of '*material_shine' i might
					 *   need to use '*material_shinestrength' */

					/* get shine value from ase */
					if (!_pico_parse_float( p,&shineValue ))
						_ase_error_return("Material shine parse error");

					/* scale ase shine range 0..1 to pico range 0..127 */
					shineValue *= 128.0;

					/* skip rest and continue with next token */
					_pico_parse_skip_rest( p );
					continue;
				}
				/* parse ambient material color */
				else if (!_pico_stricmp(p->token,"*material_ambient"))
				{
					picoVec3_t  vec;
					/* get r,g,b float values from ase */
					if (!_pico_parse_vec( p,vec ))
						_ase_error_return("Material color parse error");

					/* setup 0..255 range color values */
					ambientColor[ 0 ] = (int)( vec[ 0 ] * 255.0 );
					ambientColor[ 1 ] = (int)( vec[ 1 ] * 255.0 );
					ambientColor[ 2 ] = (int)( vec[ 2 ] * 255.0 );
					ambientColor[ 3 ] = (int)( 255 );

					/* skip rest and continue with next token */
					_pico_parse_skip_rest( p );
					continue;
				}
				/* parse diffuse material color */
				else if (!_pico_stricmp(p->token,"*material_diffuse"))
				{
					picoVec3_t  vec;

					/* get r,g,b float values from ase */
					if (!_pico_parse_vec( p,vec ))
						_ase_error_return("Material color parse error");

					/* setup 0..255 range color */
					diffuseColor[ 0 ] = (int)( vec[ 0 ] * 255.0 );
					diffuseColor[ 1 ] = (int)( vec[ 1 ] * 255.0 );
					diffuseColor[ 2 ] = (int)( vec[ 2 ] * 255.0 );
					diffuseColor[ 3 ] = (int)( 255 );

					/* skip rest and continue with next token */
					_pico_parse_skip_rest( p );
					continue;
				}
				/* parse specular material color */
				else if (!_pico_stricmp(p->token,"*material_specular"))
				{
					picoVec3_t  vec;

					/* get r,g,b float values from ase */
					if (!_pico_parse_vec( p,vec ))
						_ase_error_return("Material color parse error");

					/* setup 0..255 range color */
					specularColor[ 0 ] = (int)( vec[ 0 ] * 255 );
					specularColor[ 1 ] = (int)( vec[ 1 ] * 255 );
					specularColor[ 2 ] = (int)( vec[ 2 ] * 255 );
					specularColor[ 3 ] = (int)( 255 );

					/* skip rest and continue with next token */
					_pico_parse_skip_rest( p );
					continue;
				}
				/* material diffuse map */
				else if (!_pico_stricmp(p->token,"*map_diffuse") )
				{
					int sublevel = 0;

					/* parse material block */
					while( 1 )
					{
						/* get next token */
						if (_pico_parse(p,1) == NULL) break;
						if (!strlen(p->token)) continue;
						
						/* handle levels */
						if (p->token[0] == '{') sublevel++;
						if (p->token[0] == '}') sublevel--;
						if (!sublevel) break;
						
						/* parse diffuse map bitmap */
						if (!_pico_stricmp(p->token,"*bitmap"))
						{
							char* name = _pico_parse(p,0);
							if (name == NULL)
								_ase_error_return("Missing material map bitmap name");
							mapname = _pico_alloc ( strlen ( name ) + 1 );
							strcpy ( mapname, name );
							/* skip rest and continue with next token */
							_pico_parse_skip_rest( p );
							continue;
						}
					}
				}
				/* end map_diffuse block */
			}
			/* end material block */

			if( subMaterial == NULL )
			{
				/* allocate new pico shader */
				shader = PicoNewShader( model );
				if (shader == NULL)
				{
					PicoFreeModel( model );
					return NULL;
				}

				/* set material name */
				PicoSetShaderName( shader,materialName );

				/* set shader's transparency */
				PicoSetShaderTransparency( shader,transValue );

				/* set shader's ambient color */
				PicoSetShaderAmbientColor( shader,ambientColor );

				/* set diffuse alpha to transparency */
				diffuseColor[3] = (picoByte_t)( transValue * 255.0 );

				/* set shader's diffuse color */
				PicoSetShaderDiffuseColor( shader,diffuseColor );

				/* set shader's specular color */
				PicoSetShaderSpecularColor( shader,specularColor );

				/* set shader's shininess */
				PicoSetShaderShininess( shader,shineValue );

				/* set material map name */
				PicoSetShaderMapName( shader, mapname );

        /* extract shadername from bitmap path */
        if(mapname != NULL)
        {
          char* p = mapname;

          /* convert to shader-name format */
          {
            /* unix-style path separators */
            char* s = mapname;
            for(; *s != '\0'; ++s)
            {
              if(*s == '\\')
              {
                *s = '/';
              }
            }
          }
          {
            /* remove extension */
            char* last_period = strrchr(p, '.');
            if(last_period != NULL)
            {
              *last_period = '\0';
            }
          }

          /* find game root */
          for(; *p != '\0'; ++p)
          {
            if(_pico_strnicmp(p, "quake", 5) == 0 || _pico_strnicmp(p, "doom", 4) == 0)
            {
              break;
            }
          }
          /* root-relative */
          for(; *p != '\0'; ++p)
          {
            if(*p == '/')
            {
              ++p;
              break;
            }
          }
          /* game-relative */
          for(; *p != '\0'; ++p)
          {
            if(*p == '/')
            {
              ++p;
              break;
            }
          }

          if(*p != '\0')
          {
				    /* set material name */
				    PicoSetShaderName( shader,p );
          }
        }

        /* this is just a material with 1 submaterial */
				subMaterial = _ase_add_submaterial( &materials, index, 0, shader );
			}
			
			/* ydnar: free mapname */
			if( mapname != NULL )
				_pico_free( mapname );
		}	// !_pico_stricmp ( "*material" )

		/* skip unparsed rest of line and continue */
		_pico_parse_skip_rest( p );
	}
	
	/* ydnar: finish existing surface */
	_ase_submit_triangles(model, materials, vertices, texcoords, colors, faces, numFaces,numVertices,submodel++);
	_pico_free(faces);
	_pico_free(vertices);
	_pico_free(texcoords);
	_pico_free(colors);

#ifdef DEBUG_PM_ASE
	_ase_print_materials(materials);
	finish = clock();
	elapsed = (double)(finish - start) / CLOCKS_PER_SEC;
	_pico_printf( PICO_NORMAL, "Loaded model in in %-.2f second(s)\n", elapsed );
#endif //DEBUG_PM_ASE

	_ase_free_materials(&materials);

  _pico_free_parser( p );

	/* return allocated pico model */
	return model;
}
Esempio n. 19
0
void aseUniqueIndices_reserve(aseUniqueIndices_t* self, picoIndex_t size)
{
	self->data = self->last = (picoIndex_t*)_pico_calloc(size, sizeof(picoIndex_t));
}
Esempio n. 20
0
lwEnvelope *lwGetEnvelope( picoMemStream_t *fp, int cksize )
{
   lwEnvelope *env;
   lwKey *key;
   lwPlugin *plug;
   unsigned int id;
   unsigned short sz;
   float f[ 4 ];
   int i, nparams, pos, rlen;

   key = NULL;

   /* allocate the Envelope structure */

   env = _pico_calloc( 1, sizeof( lwEnvelope ));
   if ( !env ) goto Fail;

   /* remember where we started */

   set_flen( 0 );
   pos = (int)_pico_memstream_tell( fp );

   /* index */

   env->index = getVX( fp );

   /* first subchunk header */

   id = getU4( fp );
   sz = getU2( fp );
   if ( 0 > get_flen() ) goto Fail;

   /* process subchunks as they're encountered */

   while ( 1 ) {
      sz += sz & 1;
      set_flen( 0 );

      switch ( id ) {
         case ID_TYPE:
            env->type = getU2( fp );
            break;

         case ID_NAME:
            env->name = getS0( fp );
            break;

         case ID_PRE:
            env->behavior[ 0 ] = getU2( fp );
            break;

         case ID_POST:
            env->behavior[ 1 ] = getU2( fp );
            break;

         case ID_KEY:
            key = _pico_calloc( 1, sizeof( lwKey ));
            if ( !key ) goto Fail;
            key->time = getF4( fp );
            key->value = getF4( fp );
            lwListInsert( (void **) &env->key, key, (int (*)(void *, void *))compare_keys );
            env->nkeys++;
            break;

         case ID_SPAN:
            if ( !key ) goto Fail;
            key->shape = getU4( fp );

            nparams = ( sz - 4 ) / 4;
            if ( nparams > 4 ) nparams = 4;
            for ( i = 0; i < nparams; i++ )
               f[ i ] = getF4( fp );

            switch ( key->shape ) {
               case ID_TCB:
                  key->tension = f[ 0 ];
                  key->continuity = f[ 1 ];
                  key->bias = f[ 2 ];
                  break;

               case ID_BEZI:
               case ID_HERM:
               case ID_BEZ2:
                  for ( i = 0; i < nparams; i++ )
                     key->param[ i ] = f[ i ];
                  break;
            }
            break;

         case ID_CHAN:
            plug = _pico_calloc( 1, sizeof( lwPlugin ));
            if ( !plug ) goto Fail;

            plug->name = getS0( fp );
            plug->flags = getU2( fp );
            plug->data = getbytes( fp, sz - get_flen() );

            lwListAdd( (void *) &env->cfilter, plug );
            env->ncfilters++;
            break;

         default:
            break;
      }

      /* error while reading current subchunk? */

      rlen = get_flen();
      if ( rlen < 0 || rlen > sz ) goto Fail;

      /* skip unread parts of the current subchunk */

      if ( rlen < sz )
         _pico_memstream_seek( fp, sz - rlen, PICO_SEEK_CUR );

      /* end of the ENVL chunk? */

      rlen = (int)_pico_memstream_tell( fp ) - pos;
      if ( cksize < rlen ) goto Fail;
      if ( cksize == rlen ) break;

      /* get the next subchunk header */

      set_flen( 0 );
      id = getU4( fp );
      sz = getU2( fp );
      if ( 6 != get_flen() ) goto Fail;
   }

   return env;

Fail:
   lwFreeEnvelope( env );
   return NULL;
}
Esempio n. 21
0
lwSurface *lwGetSurface( picoMemStream_t *fp, int cksize ){
	lwSurface *surf;
	lwTexture *tex;
	lwPlugin *shdr;
	unsigned int id, type;
	unsigned short sz;
	int pos, rlen;


	/* allocate the Surface structure */

	surf = _pico_calloc( 1, sizeof( lwSurface ) );
	if ( !surf ) {
		goto Fail;
	}

	/* non-zero defaults */

	surf->color.rgb[ 0 ] = 0.78431f;
	surf->color.rgb[ 1 ] = 0.78431f;
	surf->color.rgb[ 2 ] = 0.78431f;
	surf->diffuse.val    = 1.0f;
	surf->glossiness.val = 0.4f;
	surf->bump.val       = 1.0f;
	surf->eta.val        = 1.0f;
	surf->sideflags      = 1;

	/* remember where we started */

	set_flen( 0 );
	pos = _pico_memstream_tell( fp );

	/* names */

	surf->name = getS0( fp );
	surf->srcname = getS0( fp );

	/* first subchunk header */

	id = getU4( fp );
	sz = getU2( fp );
	if ( 0 > get_flen() ) {
		goto Fail;
	}

	/* process subchunks as they're encountered */

	while ( 1 ) {
		sz += sz & 1;
		set_flen( 0 );

		switch ( id ) {
		case ID_COLR:
			surf->color.rgb[ 0 ] = getF4( fp );
			surf->color.rgb[ 1 ] = getF4( fp );
			surf->color.rgb[ 2 ] = getF4( fp );
			surf->color.eindex = getVX( fp );
			break;

		case ID_LUMI:
			surf->luminosity.val = getF4( fp );
			surf->luminosity.eindex = getVX( fp );
			break;

		case ID_DIFF:
			surf->diffuse.val = getF4( fp );
			surf->diffuse.eindex = getVX( fp );
			break;

		case ID_SPEC:
			surf->specularity.val = getF4( fp );
			surf->specularity.eindex = getVX( fp );
			break;

		case ID_GLOS:
			surf->glossiness.val = getF4( fp );
			surf->glossiness.eindex = getVX( fp );
			break;

		case ID_REFL:
			surf->reflection.val.val = getF4( fp );
			surf->reflection.val.eindex = getVX( fp );
			break;

		case ID_RFOP:
			surf->reflection.options = getU2( fp );
			break;

		case ID_RIMG:
			surf->reflection.cindex = getVX( fp );
			break;

		case ID_RSAN:
			surf->reflection.seam_angle = getF4( fp );
			break;

		case ID_TRAN:
			surf->transparency.val.val = getF4( fp );
			surf->transparency.val.eindex = getVX( fp );
			break;

		case ID_TROP:
			surf->transparency.options = getU2( fp );
			break;

		case ID_TIMG:
			surf->transparency.cindex = getVX( fp );
			break;

		case ID_RIND:
			surf->eta.val = getF4( fp );
			surf->eta.eindex = getVX( fp );
			break;

		case ID_TRNL:
			surf->translucency.val = getF4( fp );
			surf->translucency.eindex = getVX( fp );
			break;

		case ID_BUMP:
			surf->bump.val = getF4( fp );
			surf->bump.eindex = getVX( fp );
			break;

		case ID_SMAN:
			surf->smooth = getF4( fp );
			break;

		case ID_SIDE:
			surf->sideflags = getU2( fp );
			break;

		case ID_CLRH:
			surf->color_hilite.val = getF4( fp );
			surf->color_hilite.eindex = getVX( fp );
			break;

		case ID_CLRF:
			surf->color_filter.val = getF4( fp );
			surf->color_filter.eindex = getVX( fp );
			break;

		case ID_ADTR:
			surf->add_trans.val = getF4( fp );
			surf->add_trans.eindex = getVX( fp );
			break;

		case ID_SHRP:
			surf->dif_sharp.val = getF4( fp );
			surf->dif_sharp.eindex = getVX( fp );
			break;

		case ID_GVAL:
			surf->glow.val = getF4( fp );
			surf->glow.eindex = getVX( fp );
			break;

		case ID_LINE:
			surf->line.enabled = 1;
			if ( sz >= 2 ) {
				surf->line.flags = getU2( fp );
			}
			if ( sz >= 6 ) {
				surf->line.size.val = getF4( fp );
			}
			if ( sz >= 8 ) {
				surf->line.size.eindex = getVX( fp );
			}
			break;

		case ID_ALPH:
			surf->alpha_mode = getU2( fp );
			surf->alpha = getF4( fp );
			break;

		case ID_AVAL:
			surf->alpha = getF4( fp );
			break;

		case ID_BLOK:
			type = getU4( fp );

			switch ( type ) {
			case ID_IMAP:
			case ID_PROC:
			case ID_GRAD:
				tex = lwGetTexture( fp, sz - 4, type );
				if ( !tex ) {
					goto Fail;
				}
				if ( !add_texture( surf, tex ) ) {
					lwFreeTexture( tex );
				}
				set_flen( 4 + get_flen() );
				break;
			case ID_SHDR:
				shdr = lwGetShader( fp, sz - 4 );
				if ( !shdr ) {
					goto Fail;
				}
				lwListInsert( (void **) &surf->shader, shdr, (void *) compare_shaders );
				++surf->nshaders;
				set_flen( 4 + get_flen() );
				break;
			}
			break;

		default:
			break;
		}

		/* error while reading current subchunk? */

		rlen = get_flen();
		if ( rlen < 0 || rlen > sz ) {
			goto Fail;
		}

		/* skip unread parts of the current subchunk */

		if ( rlen < sz ) {
			_pico_memstream_seek( fp, sz - rlen, PICO_SEEK_CUR );
		}

		/* end of the SURF chunk? */

		if ( cksize <= _pico_memstream_tell( fp ) - pos ) {
			break;
		}

		/* get the next subchunk header */

		set_flen( 0 );
		id = getU4( fp );
		sz = getU2( fp );
		if ( 6 != get_flen() ) {
			goto Fail;
		}
	}

	return surf;

Fail:
	if ( surf ) {
		lwFreeSurface( surf );
	}
	return NULL;
}
Esempio n. 22
0
static void indexarray_reserve (IndexArray* self, size_t size)
{
	self->data = self->last = _pico_calloc(size, sizeof(picoIndex_t));
}