⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lwreader.cpp

📁 赫赫大名的 OGRE 游戏引擎
💻 CPP
📖 第 1 页 / 共 4 页
字号:
}


/*======================================================================
add_tvel()

Add a triple of envelopes to simulate the old texture velocity
parameters.
======================================================================*/

int lwReader::add_tvel( float pos[], float vel[], venvelopes &envelopes )
{
	lwEnvelope *env;
	lwKey *key0, *key1;
	int i;

	for ( i = 0; i < 3; i++ )
	{
		env = new lwEnvelope;
		key0 = new lwKey(0.0f, pos[ i ]);
		key1 = new lwKey(1.0f, pos[ i ] + vel[ i ] * 30.0f); // 30.0f == NTSC related ? 

		key0->shape = key1->shape = ID_LINE;

		env->keys.push_back( key0 );
		env->keys.push_back( key1 );

		env->type = 0x0301 + i;
		env->name = (char *)malloc(11);
		if ( env->name )
		{
			strcpy( env->name, "Position.X" );
			env->name[ 9 ] += i;
		}

		env->behavior[ 0 ] = BEH_LINEAR;
		env->behavior[ 1 ] = BEH_LINEAR;

		envelopes.push_back( env );
		env->index = envelopes.size()-1;
	}
	return env->index - 2;
}


/*======================================================================
get_texture()

Create a new texture for BTEX, CTEX, etc. subchunks.
======================================================================*/

lwTexture *lwReader::get_texture( char *s )
{
	lwTexture *tex = new lwTexture;
	if ( !tex ) return NULL;

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

lwSurface *lwReader::lwGetLWOBSurface( lwObject *obj )
{
	lwTexture *tex = 0;
	lwPlugin *shdr = 0;
	char *s;
	float v[ 3 ];
	unsigned int flags;
	unsigned short sz;
	int rlen, i;

	long filepos = is->tellg();
	long chunkstart = filepos;
	long chunkend = chunkstart + chunksize;

	/* allocate the Surface structure */

	lwSurface *surf = new lwSurface;
	if ( !surf ) return NULL;

	/* name */

	surf->name = getS0();

	/* process subchunks as they're encountered */
	filepos = is->tellg();
	if (filepos == -1) return surf;
	if ( filepos > chunkend ) return surf; // error: read too much

	while( filepos < chunkend )
	{
		currentchunkid = getU4();
		sz = getU2();
		sz += sz & 1;
		flen = 0;

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

		case ID_FLAG:
			flags = getU2();
			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() / 256.0f;
			break;

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

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

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

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

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

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

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

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

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

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

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

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

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

		case ID_BTEX:
			s = getbytes( sz );
			tex = get_texture( s );
			surf->bump.textures.push_back( tex );
			break;

		case ID_CTEX:
			s = getbytes( sz );
			tex = get_texture( s );
			surf->color.textures.push_back( tex );
			break;

		case ID_DTEX:
			s = getbytes( sz );
			tex = get_texture( s );
			surf->diffuse.textures.push_back( tex );
			break;

		case ID_LTEX:
			s = getbytes( sz );
			tex = get_texture( s );
			surf->luminosity.textures.push_back( tex );
			break;

		case ID_RTEX:
			s = getbytes( sz );
			tex = get_texture( s );
			surf->reflection.val.textures.push_back( tex );
			break;

		case ID_STEX:
			s = getbytes( sz );
			tex = get_texture( s );
			surf->specularity.textures.push_back( tex );
			break;

		case ID_TTEX:
			s = getbytes( sz );
			tex = get_texture( s );
			surf->transparency.val.textures.push_back( tex );
			break;

		case ID_TFLG:
			flags = getU2();

			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;
				if ( flags & 32 )
					tex->param.imap->pblend = 1;
				if ( flags & 64 )
				{
					tex->param.imap->aa_strength = 1.0f;
					tex->param.imap->aas_flags = 1;
				}
			}
			if ( tex->type == ID_PROC )
				tex->param.proc->axis = i;

			if ( flags & 8 ) tex->tmap.coord_sys = 1;
			if ( flags & 16 ) tex->negative = 1;
			break;

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

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

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

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

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

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

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

		case ID_TIMG:
			if ( tex->type == ID_IMAP )
			{
				s = getS0();
				tex->param.imap->cindex = add_clip( s, obj->clips );
			}
			break;

		case ID_TAAS:
			if ( tex->type == ID_IMAP )
			{
				tex->param.imap->aa_strength = getF4();
				tex->param.imap->aas_flags = 1;
			}
			break;

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

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

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

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

		case ID_SHDR:
			shdr = new lwPlugin;
			if ( !shdr ) goto Fail;
			shdr->name = getbytes( sz );
			surf->shaders.push_back( shdr );
			break;

		case ID_SDAT:
			shdr->data = getbytes( sz );
			break;
		default:
			break;
		}

		/* error while reading current subchunk? */

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

		/* skip unread parts of the current subchunk */

		if ( rlen < sz )
			is->seekg(sz - rlen, ios_base::cur );

		/* end of the SURF chunk? */

		filepos = is->tellg();
		if ( filepos == -1 ) break; // end of file ?
		if ( filepos > chunkend ) // error: read too much
		{
			is->seekg(chunkend, ios_base::beg );
			break;
		}
	}
	return surf;
Fail:
	if ( surf ) delete surf;
	return NULL;
}


/*
======================================================================
lwGetSurface()

Read an lwSurface from an LWO2 file.
====================================================================== */

lwSurface *lwReader::lwGetSurface()
{
	lwSurface *surf;
	lwTexture *tex;
	lwPlugin *shdr;
	unsigned int id, type;
	unsigned short sz;
	unsigned int pos, rlen, fpos;
	
	/* allocate the Surface structure */
	
	surf = new lwSurface;
	if ( !surf ) goto Fail;
	
	/* remember where we started */
	
	flen = 0;
	pos = is->tellg();
	
	/* names */
	
	surf->name = getS0();
	surf->srcname = getS0();
	
	/* first subchunk header */
	
	id = getU4();
	sz = getU2();
	if ( 0 > flen ) goto Fail;
	
	/* process subchunks as they're encountered */
	
	while ( 1 ) {
		sz += sz & 1;
		flen = 0;
		
		switch ( id ) {
		case ID_COLR:
			surf->color.rgb[ 0 ] = getF4();
			surf->color.rgb[ 1 ] = getF4();
			surf->color.rgb[ 2 ] = getF4();
			surf->color.eindex = getVX();
			break;
			
		case ID_LUMI:
			surf->luminosity.val = getF4();
			surf->luminosity.eindex = getVX();
			break;
			
		case ID_DIFF:
			surf->diffuse.val = getF4();
			surf->diffuse.eindex = getVX();
			break;
			
		case ID_SPEC:
			surf->specularity.val = getF4();
			surf->specularity.eindex = getVX();
			break;
			
		case ID_GLOS:
			surf->glossiness.val = getF4();
			surf->glossiness.eindex = getVX();
			break;
			
		case ID_REFL:
			surf->reflection.val.val = getF4();
			surf->reflection.val.eindex = getVX();
			break;
			
		case ID_RFOP:
			surf->reflection.options = getU2();
			break;
			
		case ID_RIMG:
			surf->reflection.cindex = getVX();
			break;
			
		case ID_RSAN:
			surf->reflection.seam_angle = getF4();
			break;
			
		case ID_TRAN:
			surf->transparency.val.val = getF4();
			surf->transparency.val.eindex = getVX();
			break;
			
		case ID_TROP:
			surf->transparency.options = getU2();
			break;
			
		case ID_TIMG:
			surf->transparency.cindex = getVX();
			break;
			
		case ID_RIND:
			surf->eta.val = getF4();
			surf->eta.eindex = getVX();
			break;
			
		case ID_TRNL:
			surf->translucency.val = getF4();
			surf->translucency.eindex = getVX();
			break;
			
		case ID_BUMP:
			surf->bump.val = getF4();
			surf->bump.eindex = getVX();
			break;
			
		case ID_SMAN:
			surf->smooth = getF4();
			break;
			
		case ID_SIDE:
			surf->sideflags = getU2();
			break;
			
		case ID_CLRH:
			surf->color_hilite.val = getF4();
			surf->color_hilite.eindex = getVX();
			break;
			
		case ID_CLRF:
			surf->color_filter.val = getF4();
			surf->color_filter.eindex = getVX();
			break;
			
		case ID_ADTR:
			surf->add_trans.val = getF4();
			surf->add_trans.eindex = getVX();
			break;
			
		case ID_SHRP:
			surf->dif_sharp.val = getF4();
			surf->dif_sharp.eindex = getVX();
			break;
			
		case ID_GVAL:
			surf->glow.val = getF4();
			surf->glow.eindex = getVX();
			break;
			
		case ID_LINE:
			surf->line.enabled = 1;
			if ( sz >= 2 ) surf->line.flags = getU2();
			if ( sz >= 6 ) surf->line.size.val = getF4();
			if ( sz >= 8 ) surf->line.size.eindex = getVX();
			break;
			
		case ID_ALPH:
			surf->alpha_mode = getU2();
			surf->alpha = getF4();
			break;
			
		case ID_AVAL:
			surf->alpha = getF4();
			break;
			
		case ID_BLOK:
			type = getU4();
			
			switch ( type ) {
			case ID_IMAP:
			case ID_PROC:
			case ID_GRAD:
				tex = lwGetTexture( sz - 4, type );
				if ( !tex ) goto Fail;
				if ( !surf->addTexture(tex) ) delete tex;
				flen += 4;
				break;
			case ID_SHDR:
				shdr = lwGetShader( sz - 4 );
				if ( !shdr ) goto Fail;
				surf->shaders.insert(lower_bound(surf->shaders.begin(), surf->shaders.end(), shdr), shdr);
				flen += 4;
				break;
			}
			break;
			
			default:
				break;
	}
	
	/* error while reading current subchunk? */
	
	rlen = flen;
	if ( rlen < 0 || rlen > sz ) goto Fail;
	
	/* skip unread parts of the current subchunk */
	
	if ( rlen < sz )
		is->seekg(sz - rlen, ios_base::cur );
	
	/* end of the SURF chunk? */
	
	fpos = is->tellg();
	if ( fpos == -1 ) break;
	if ( chunksize + pos <= fpos ) break;
	
	/* get the next subchunk header */
	
	flen = 0;
	id = getU4();
	sz = getU2();
	if ( 6 != flen ) goto Fail;
   }
   
   return surf;
   
Fail:
   if ( surf ) delete surf;
   return NULL;
}

/*
======================================================================
lwGetVMap()

  Read an lwVMap from a VMAP or VMAD chunk in an LWO2.
====================================================================== */

lwVMap *lwReader::lwGetVMap( int ptoffset, int poloffset, int perpoly )
{
	char *buf, *bp;
	lwVMap *vmap;
	unsigned int i, j, npts, rlen;
	
	/* read the whole chunk */
	
	flen = 0;
	buf = getbytes( chunksize );
	if ( !buf ) return NULL;
	
	vmap = new lwVMap;
	if ( !vmap ) {
		free(buf);
		return NULL;
	}
	
	/* initialize the vmap */
	
	vmap->perpoly = perpoly;
	
	bp = buf;
	flen = 0;
	vmap->type = sgetU4( &bp );
	vmap->dim  = sgetU2( &bp );
	vmap->name = sgetS0( &bp );
	rlen = flen;
	
	/* count the vmap records */
	
	npts = 0;
	while ( bp < buf + chunksize ) {
		i = sgetVX( &bp );
		if ( perpoly )
			i = sgetVX( &bp );
		bp += vmap->dim * sizeof( float );
		++npts;
	}
	
	/* allocate the vmap */
	
	vmap->nverts = npts;
	vmap->vindex = (int *)malloc(npts * sizeof(int));
	if ( !vmap->vindex ) goto Fail;
	if ( perpoly )
	{
		vmap->pindex = (int *)malloc(npts * sizeof(int));
		if ( !vmap->pindex ) goto Fail;
	}
	
	if ( vmap->dim > 0 )
	{
		vmap->val = (float **)malloc(npts * sizeof(float *));
		if ( !vmap->val ) goto Fail;
		for ( i = 0; i < npts; i++ )
			vmap->val[ i ] = (float *)malloc(vmap->dim * sizeof( float ));
	}
	
	/* fill in the vmap values */
	
	bp = buf + rlen;
	for ( i = 0; i < npts; i++ ) {
		vmap->vindex[ i ] = sgetVX( &bp );
		if ( perpoly )
			vmap->pindex[ i ] = sgetVX( &bp );
		for ( j = 0; j < vmap->dim; j++ )
			vmap->val[ i ][ j ] = sgetF4( &bp );
	}
	
	free(buf);
	return vmap;
	
Fail:
	free(buf);
	delete vmap;
	return NULL;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -