/*
================
idAASFileLocal::ParseNodes
================
*/
bool idAASFileLocal::ParseNodes(idLexer &src)
{
	int numNodes, i;
	aasNode_t node;

	numNodes = src.ParseInt();
	nodes.Resize(numNodes);

	if (!src.ExpectTokenString("{")) {
		return false;
	}

	for (i = 0; i < numNodes; i++) {
		src.ParseInt();
		src.ExpectTokenString("(");
		node.planeNum = src.ParseInt();
		node.children[0] = src.ParseInt();
		node.children[1] = src.ParseInt();
		src.ExpectTokenString(")");
		nodes.Append(node);
	}

	if (!src.ExpectTokenString("}")) {
		return false;
	}

	return true;
}
Beispiel #2
0
/*
================
idAASFileLocal::ParseReachabilities
================
*/
bool idAASFileLocal::ParseReachabilities( idLexer &src, int areaNum )
{
    int num, j;
    aasArea_t *area;
    idReachability reach, *newReach;
    idReachability_Special *special;

    area = &areas[areaNum];

    num = src.ParseInt();
    src.ExpectTokenString( "{" );
    area->reach = NULL;
    area->rev_reach = NULL;
    area->travelFlags = AreaContentsTravelFlags( areaNum );
    for ( j = 0; j < num; j++ )
    {
        Reachability_Read( src, &reach );
        switch( reach.travelType )
        {
        case TFL_SPECIAL:
            newReach = special = new idReachability_Special();
            Reachability_Special_Read( src, special );
            break;
        default:
            newReach = new idReachability();
            break;
        }
        newReach->CopyBase( reach );
        newReach->fromAreaNum = areaNum;
        newReach->next = area->reach;
        area->reach = newReach;
    }
    src.ExpectTokenString( "}" );
    return true;
}
Beispiel #3
0
/*
================
idAASFileLocal::ParseAreas
================
*/
bool idAASFileLocal::ParseAreas( idLexer &src ) {
	int numAreas, i;
	aasArea_t area;

	numAreas = src.ParseInt();
	areas.Resize( numAreas );
	if ( !src.ExpectTokenString( "{" ) ) {
		return false;
	}
	for ( i = 0; i < numAreas; i++ ) {
		src.ParseInt();
		src.ExpectTokenString( "(" );
		area.flags = src.ParseInt();
		area.contents = src.ParseInt();
		area.firstFace = src.ParseInt();
		area.numFaces = src.ParseInt();
		area.cluster = src.ParseInt();
		area.clusterAreaNum = src.ParseInt();
		src.ExpectTokenString( ")" );
		areas.Append( area );
		ParseReachabilities( src, i );
	}
	if ( !src.ExpectTokenString( "}" ) ) {
		return false;
	}

	LinkReversedReachability();

	return true;
}
Beispiel #4
0
/*
================
idAASFileLocal::ParsePortals
================
*/
bool idAASFileLocal::ParsePortals( idLexer &src ) {
	int numPortals, i;
	aasPortal_t portal;

	numPortals = src.ParseInt();
	portals.Resize( numPortals );
	if ( !src.ExpectTokenString( "{" ) ) {
		return false;
	}
	for ( i = 0; i < numPortals; i++ ) {
		src.ParseInt();
		src.ExpectTokenString( "(" );
		portal.areaNum = src.ParseInt();
		portal.clusters[0] = src.ParseInt();
		portal.clusters[1] = src.ParseInt();
		portal.clusterAreaNum[0] = src.ParseInt();
		portal.clusterAreaNum[1] = src.ParseInt();
		src.ExpectTokenString( ")" );
		portals.Append( portal );
	}
	if ( !src.ExpectTokenString( "}" ) ) {
		return false;
	}
	return true;
}
/*
================
idAASFileLocal::ParsePlanes
================
*/
bool idAASFileLocal::ParsePlanes(idLexer &src)
{
	int numPlanes, i;
	idPlane plane;
	idVec4 vec;

	numPlanes = src.ParseInt();
	planeList.Resize(numPlanes);

	if (!src.ExpectTokenString("{")) {
		return false;
	}

	for (i = 0; i < numPlanes; i++) {
		src.ParseInt();

		if (!src.Parse1DMatrix(4, vec.ToFloatPtr())) {
			return false;
		}

		plane.SetNormal(vec.ToVec3());
		plane.SetDist(vec[3]);
		planeList.Append(plane);
	}

	if (!src.ExpectTokenString("}")) {
		return false;
	}

	return true;
}
/*
================
idAASFileLocal::ParseVertices
================
*/
bool idAASFileLocal::ParseVertices(idLexer &src)
{
	int numVertices, i;
	idVec3 vec;

	numVertices = src.ParseInt();
	vertices.Resize(numVertices);

	if (!src.ExpectTokenString("{")) {
		return false;
	}

	for (i = 0; i < numVertices; i++) {
		src.ParseInt();

		if (!src.Parse1DMatrix(3, vec.ToFloatPtr())) {
			return false;
		}

		vertices.Append(vec);
	}

	if (!src.ExpectTokenString("}")) {
		return false;
	}

	return true;
}
/*
================
idAASFileLocal::ParseIndex
================
*/
bool idAASFileLocal::ParseIndex(idLexer &src, idList<aasIndex_t> &indexes)
{
	int numIndexes, i;
	aasIndex_t index;

	numIndexes = src.ParseInt();
	indexes.Resize(numIndexes);

	if (!src.ExpectTokenString("{")) {
		return false;
	}

	for (i = 0; i < numIndexes; i++) {
		src.ParseInt();
		src.ExpectTokenString("(");
		index = src.ParseInt();
		src.ExpectTokenString(")");
		indexes.Append(index);
	}

	if (!src.ExpectTokenString("}")) {
		return false;
	}

	return true;
}
/*
============
idAASSettings::ParseBBoxes
============
*/
bool idAASSettings::ParseBBoxes(idLexer &src)
{
	idToken token;
	idBounds bounds;

	numBoundingBoxes = 0;

	if (!src.ExpectTokenString("{")) {
		return false;
	}

	while (src.ReadToken(&token)) {
		if (token == "}") {
			return true;
		}

		src.UnreadToken(&token);
		src.Parse1DMatrix(3, bounds[0].ToFloatPtr());

		if (!src.ExpectTokenString("-")) {
			return false;
		}

		src.Parse1DMatrix(3, bounds[1].ToFloatPtr());

		boundingBoxes[numBoundingBoxes++] = bounds;
	}

	return false;
}
/*
================
idAASFileLocal::ParseClusters
================
*/
bool idAASFileLocal::ParseClusters(idLexer &src)
{
	int numClusters, i;
	aasCluster_t cluster;

	numClusters = src.ParseInt();
	clusters.Resize(numClusters);

	if (!src.ExpectTokenString("{")) {
		return false;
	}

	for (i = 0; i < numClusters; i++) {
		src.ParseInt();
		src.ExpectTokenString("(");
		cluster.numAreas = src.ParseInt();
		cluster.numReachableAreas = src.ParseInt();
		cluster.firstPortal = src.ParseInt();
		cluster.numPortals = src.ParseInt();
		src.ExpectTokenString(")");
		clusters.Append(cluster);
	}

	if (!src.ExpectTokenString("}")) {
		return false;
	}

	return true;
}
Beispiel #10
0
/*
================
idAASFileLocal::ParseEdges
================
*/
bool idAASFileLocal::ParseEdges( idLexer &src )
{
    int numEdges, i;
    aasEdge_t edge;

    numEdges = src.ParseInt();
    edges.Resize( numEdges );
    if ( !src.ExpectTokenString( "{" ) )
    {
        return false;
    }
    for ( i = 0; i < numEdges; i++ )
    {
        src.ParseInt();
        src.ExpectTokenString( "(" );
        edge.vertexNum[0] = src.ParseInt();
        edge.vertexNum[1] = src.ParseInt();
        src.ExpectTokenString( ")" );
        edges.Append( edge );
    }
    if ( !src.ExpectTokenString( "}" ) )
    {
        return false;
    }
    return true;
}
Beispiel #11
0
/*
================
idAASFileLocal::ParseFaces
================
*/
bool idAASFileLocal::ParseFaces( idLexer &src )
{
    int numFaces, i;
    aasFace_t face;

    numFaces = src.ParseInt();
    faces.Resize( numFaces );
    if ( !src.ExpectTokenString( "{" ) )
    {
        return false;
    }
    for ( i = 0; i < numFaces; i++ )
    {
        src.ParseInt();
        src.ExpectTokenString( "(" );
        face.planeNum = src.ParseInt();
        face.flags = src.ParseInt();
        face.areas[0] = src.ParseInt();
        face.areas[1] = src.ParseInt();
        face.firstEdge = src.ParseInt();
        face.numEdges = src.ParseInt();
        src.ExpectTokenString( ")" );
        faces.Append( face );
    }
    if ( !src.ExpectTokenString( "}" ) )
    {
        return false;
    }
    return true;
}
Beispiel #12
0
/*
================
idDeclAF::ParseHinge
================
*/
bool idDeclAF::ParseHinge( idLexer &src ) {
	idToken token;
	idDeclAF_Constraint *constraint = new idDeclAF_Constraint;

	constraint->SetDefault( this );
	constraints.Alloc() = constraint;

	if ( !src.ExpectTokenType( TT_STRING, 0, &token ) ||
			!src.ExpectTokenString( "{" ) ) {
		return false;
	}

	constraint->type = DECLAF_CONSTRAINT_HINGE;
	constraint->limit = idDeclAF_Constraint::LIMIT_NONE;
	constraint->name = token;
	constraint->friction = 0.5f;
	constraint->anchor.ToVec3().Zero();
	constraint->axis.ToVec3().Zero();

	while( src.ReadToken( &token ) ) {

		if ( !token.Icmp( "body1" ) ) {
			src.ExpectTokenType( TT_STRING, 0, &token );
			constraint->body1 = token;
		} else if ( !token.Icmp( "body2" ) ) {
			src.ExpectTokenType( TT_STRING, 0, &token );
			constraint->body2 = token;
		} else if ( !token.Icmp( "anchor" ) ) {
			if ( !constraint->anchor.Parse( src ) ) {
				return false;
			}
		} else if ( !token.Icmp( "axis" ) ) {
			if ( !constraint->axis.Parse( src ) ) {
				return false;
			}
		} else if ( !token.Icmp( "limit" ) ) {
			constraint->limitAngles[0] = src.ParseFloat();
			if ( !src.ExpectTokenString( "," ) ) {
				return false;
			}
			constraint->limitAngles[1] = src.ParseFloat();
			if ( !src.ExpectTokenString( "," ) ) {
				return false;
			}
			constraint->limitAngles[2] = src.ParseFloat();
			constraint->limit = idDeclAF_Constraint::LIMIT_CONE;
		} else if ( !token.Icmp( "friction" ) ) {
			constraint->friction = src.ParseFloat();
		} else if ( token == "}" ) {
			break;
		} else {
			src.Error( "unknown token %s in hinge", token.c_str() );
			return false;
		}
	}

	return true;
}
/*
========================
ParseInOutStruct
========================
*/
void ParseInOutStruct( idLexer & src, int attribType, idList< inOutVariable_t > & inOutVars ) {
	src.ExpectTokenString( "{" );

	while( !src.CheckTokenString( "}" ) ) {
		inOutVariable_t var;

		idToken token;
		src.ReadToken( &token );
		var.type = token;
		src.ReadToken( &token );
		var.nameCg = token;

		if ( !src.CheckTokenString( ":" ) ) {
			src.SkipUntilString( ";" );
			continue;
		}

		src.ReadToken( &token );
		var.nameGLSL = token;
		src.ExpectTokenString( ";" );

		// convert the type
		for ( int i = 0; typeConversion[i].typeCG != NULL; i++ ) {
			if ( var.type.Cmp( typeConversion[i].typeCG ) == 0 ) {
				var.type = typeConversion[i].typeGLSL;
				break;
			}
		}

		// convert the semantic to a GLSL name
		for ( int i = 0; attribsPC[i].semantic != NULL; i++ ) {
			if ( ( attribsPC[i].flags & attribType ) != 0 ) {
				if ( var.nameGLSL.Cmp( attribsPC[i].semantic ) == 0 ) {
					var.nameGLSL = attribsPC[i].glsl;
					break;
				}
			}
		}

		// check if it was defined previously
		var.declareInOut = true;
		for ( int i = 0; i < inOutVars.Num(); i++ ) {
			if ( var.nameGLSL == inOutVars[i].nameGLSL ) {
				var.declareInOut = false;
				break;
			}
		}

		inOutVars.Append( var );
	}

	src.ExpectTokenString( ";" );
}
Beispiel #14
0
/*
===================
MatchAndAppendToken
===================
*/
static void MatchAndAppendToken( idLexer &src, const char *match ) {
	if ( !src.ExpectTokenString( match ) ) {
		return;
	}
	// a matched token won't need a leading space
	idStr::Append( parseBuffer, MAX_IMAGE_NAME, match );
}
Beispiel #15
0
/*
============
idAASSettings::ParseFloat
============
*/
bool idAASSettings::ParseFloat( idLexer &src, float &f ) {
	if ( !src.ExpectTokenString( "=" ) ) {
		return false;
	}
	f = src.ParseFloat();
	return true;
}
Beispiel #16
0
/*
================
idDeclAF::ParseFixed
================
*/
bool idDeclAF::ParseFixed( idLexer &src ) {
	idToken token;
	idDeclAF_Constraint *constraint = new idDeclAF_Constraint;

	constraint->SetDefault( this );
	constraints.Alloc() = constraint;

	if ( !src.ExpectTokenType( TT_STRING, 0, &token ) ||
			!src.ExpectTokenString( "{" ) ) {
		return false;
	}

	constraint->type = DECLAF_CONSTRAINT_FIXED;
	constraint->name = token;

	while( src.ReadToken( &token ) ) {

		if ( !token.Icmp( "body1" ) ) {
			src.ExpectTokenType( TT_STRING, 0, &token );
			constraint->body1 = token;
		} else if ( !token.Icmp( "body2" ) ) {
			src.ExpectTokenType( TT_STRING, 0, &token );
			constraint->body2 = token;
		} else if ( token == "}" ) {
			break;
		} else {
			src.Error( "unknown token %s in ball and socket joint", token.c_str() );
			return false;
		}
	}

	return true;
}
Beispiel #17
0
/*
============
idAASSettings::ParseBool
============
*/
bool idAASSettings::ParseBool( idLexer &src, bool &b ) {
	if ( !src.ExpectTokenString( "=" ) ) {
		return false;
	}
	b = src.ParseBool();
	return true;
}
Beispiel #18
0
/*
============
idAASSettings::ParseInt
============
*/
bool idAASSettings::ParseInt( idLexer &src, int &i ) {
	if ( !src.ExpectTokenString( "=" ) ) {
		return false;
	}
	i = src.ParseInt();
	return true;
}
Beispiel #19
0
/*
================
idTypeInfoTools::ParseTemplateArguments
================
*/
bool idTypeInfoTools::ParseTemplateArguments( idLexer &src, idStr &arguments ) {
	int indent;
	idToken token;

	arguments = "";

	if ( !src.ExpectTokenString( "<" ) ) {
		return false;
	}

	indent = 1;
	while( indent ) {
		if ( !src.ReadToken( &token ) ) {
			break;
		}
		if ( token == "<" ) {
			indent++;
		} else if ( token == ">" ) {
			indent--;
		} else {
			if ( arguments.Length() ) {
				arguments += " ";
			}
			arguments += token;
		}
	}
	return true;
}
Beispiel #20
0
/*
============
idAASSettings::ParseVector
============
*/
bool idAASSettings::ParseVector( idLexer &src, idVec3 &vec )
{
    if ( !src.ExpectTokenString( "=" ) )
    {
        return false;
    }
    return ( src.Parse1DMatrix( 3, vec.ToFloatPtr() ) != 0 );
}
Beispiel #21
0
/*
================
idDeclAF::ParseSpring
================
*/
bool idDeclAF::ParseSpring( idLexer &src ) {
	idToken token;
	idDeclAF_Constraint *constraint = new idDeclAF_Constraint;

	constraint->SetDefault( this );
	constraints.Alloc() = constraint;

	if ( !src.ExpectTokenType( TT_STRING, 0, &token ) ||
			!src.ExpectTokenString( "{" ) ) {
		return false;
	}

	constraint->type = DECLAF_CONSTRAINT_SPRING;
	constraint->limit = idDeclAF_Constraint::LIMIT_NONE;
	constraint->name = token;
	constraint->friction = 0.5f;

	while( src.ReadToken( &token ) ) {

		if ( !token.Icmp( "body1" ) ) {
			src.ExpectTokenType( TT_STRING, 0, &token );
			constraint->body1 = token;
		} else if ( !token.Icmp( "body2" ) ) {
			src.ExpectTokenType( TT_STRING, 0, &token );
			constraint->body2 = token;
		} else if ( !token.Icmp( "anchor1" ) ) {
			if ( !constraint->anchor.Parse( src ) ) {
				return false;
			}
		} else if ( !token.Icmp( "anchor2" ) ) {
			if ( !constraint->anchor2.Parse( src ) ) {
				return false;
			}
		} else if ( !token.Icmp( "friction" ) ) {
			constraint->friction = src.ParseFloat();
		} else if ( !token.Icmp( "stretch" ) ) {
			constraint->stretch = src.ParseFloat();
		} else if ( !token.Icmp( "compress" ) ) {
			constraint->compress = src.ParseFloat();
		} else if ( !token.Icmp( "damping" ) ) {
			constraint->damping = src.ParseFloat();
		} else if ( !token.Icmp( "restLength" ) ) {
			constraint->restLength = src.ParseFloat();
		} else if ( !token.Icmp( "minLength" ) ) {
			constraint->minLength = src.ParseFloat();
		} else if ( !token.Icmp( "maxLength" ) ) {
			constraint->maxLength = src.ParseFloat();
		} else if ( token == "}" ) {
			break;
		} else {
			src.Error( "unknown token %s in spring", token.c_str() );
			return false;
		}
	}

	return true;
}
Beispiel #22
0
/*
================
idDeclAF::ParseSlider
================
*/
bool idDeclAF::ParseSlider( idLexer& src )
{
	idToken token;
	idDeclAF_Constraint* constraint = new( TAG_DECL ) idDeclAF_Constraint;
	
	constraint->SetDefault( this );
	constraints.Alloc() = constraint;
	
	if( !src.ExpectTokenType( TT_STRING, 0, &token ) ||
			!src.ExpectTokenString( "{" ) )
	{
		return false;
	}
	
	constraint->type = DECLAF_CONSTRAINT_SLIDER;
	constraint->limit = idDeclAF_Constraint::LIMIT_NONE;
	constraint->name = token;
	constraint->friction = 0.5f;
	
	while( src.ReadToken( &token ) )
	{
	
		if( !token.Icmp( "body1" ) )
		{
			src.ExpectTokenType( TT_STRING, 0, &token );
			constraint->body1 = token;
		}
		else if( !token.Icmp( "body2" ) )
		{
			src.ExpectTokenType( TT_STRING, 0, &token );
			constraint->body2 = token;
		}
		else if( !token.Icmp( "axis" ) )
		{
			if( !constraint->axis.Parse( src ) )
			{
				return false;
			}
		}
		else if( !token.Icmp( "friction" ) )
		{
			constraint->friction = src.ParseFloat();
		}
		else if( token == "}" )
		{
			break;
		}
		else
		{
			src.Error( "unknown token %s in slider", token.c_str() );
			return false;
		}
	}
	
	return true;
}
Beispiel #23
0
/*
================
Reachability_Special_Read
================
*/
bool Reachability_Special_Read( idLexer &src, idReachability_Special *reach ) {
	idToken key, value;

	src.ExpectTokenString( "{" );
	while( src.ReadToken( &key ) ) {
		if ( key == "}" ) {
			return true;
		}
		src.ExpectTokenType( TT_STRING, 0, &value );
		reach->dict.Set( key, value );
	}
	return false;
}
/*
===============
idSoundShader::ParseShader
===============
*/
bool idSoundShader::ParseShader( idLexer &src )
{
    int			i;
    idToken		token;

    parms.minDistance = 1;
    parms.maxDistance = 10;
    parms.volume = 1;
    parms.shakes = 0;
    parms.soundShaderFlags = 0;
    parms.soundClass = 0;

    speakerMask = 0;
    altSound = NULL;

    for( i = 0; i < SOUND_MAX_LIST_WAVS; i++ )
    {
        leadins[i] = NULL;
        entries[i] = NULL;
    }
    numEntries = 0;
    numLeadins = 0;

    int	maxSamples = idSoundSystemLocal::s_maxSoundsPerShader.GetInteger();
    if ( com_makingBuild.GetBool() || maxSamples <= 0 || maxSamples > SOUND_MAX_LIST_WAVS )
    {
        maxSamples = SOUND_MAX_LIST_WAVS;
    }

    while ( 1 )
    {
        if ( !src.ExpectAnyToken( &token ) )
        {
            return false;
        }
        // end of definition
        else if ( token == "}" )
        {
            break;
        }
        // minimum number of sounds
        else if ( !token.Icmp( "minSamples" ) )
        {
            maxSamples = idMath::ClampInt( src.ParseInt(), SOUND_MAX_LIST_WAVS, maxSamples );
        }
        // description
        else if ( !token.Icmp( "description" ) )
        {
            src.ReadTokenOnLine( &token );
            desc = token.c_str();
        }
        // mindistance
        else if ( !token.Icmp( "mindistance" ) )
        {
            parms.minDistance = src.ParseFloat();
        }
        // maxdistance
        else if ( !token.Icmp( "maxdistance" ) )
        {
            parms.maxDistance = src.ParseFloat();
        }
        // shakes screen
        else if ( !token.Icmp( "shakes" ) )
        {
            src.ExpectAnyToken( &token );
            if ( token.type == TT_NUMBER )
            {
                parms.shakes = token.GetFloatValue();
            }
            else
            {
                src.UnreadToken( &token );
                parms.shakes = 1.0f;
            }
        }
        // reverb
        else if ( !token.Icmp( "reverb" ) )
        {
            int reg0 = src.ParseFloat();
            if ( !src.ExpectTokenString( "," ) )
            {
                src.FreeSource();
                return false;
            }
            int reg1 = src.ParseFloat();
            // no longer supported
        }
        // volume
        else if ( !token.Icmp( "volume" ) )
        {
            parms.volume = src.ParseFloat();
        }
        // leadinVolume is used to allow light breaking leadin sounds to be much louder than the broken loop
        else if ( !token.Icmp( "leadinVolume" ) )
        {
            leadinVolume = src.ParseFloat();
        }
        // speaker mask
        else if ( !token.Icmp( "mask_center" ) )
        {
            speakerMask |= 1<<SPEAKER_CENTER;
        }
        // speaker mask
        else if ( !token.Icmp( "mask_left" ) )
        {
            speakerMask |= 1<<SPEAKER_LEFT;
        }
        // speaker mask
        else if ( !token.Icmp( "mask_right" ) )
        {
            speakerMask |= 1<<SPEAKER_RIGHT;
        }
        // speaker mask
        else if ( !token.Icmp( "mask_backright" ) )
        {
            speakerMask |= 1<<SPEAKER_BACKRIGHT;
        }
        // speaker mask
        else if ( !token.Icmp( "mask_backleft" ) )
        {
            speakerMask |= 1<<SPEAKER_BACKLEFT;
        }
        // speaker mask
        else if ( !token.Icmp( "mask_lfe" ) )
        {
            speakerMask |= 1<<SPEAKER_LFE;
        }
        // soundClass
        else if ( !token.Icmp( "soundClass" ) )
        {
            parms.soundClass = src.ParseInt();
            if ( parms.soundClass < 0 || parms.soundClass >= SOUND_MAX_CLASSES )
            {
                src.Warning( "SoundClass out of range" );
                return false;
            }
        }
        // altSound
        else if ( !token.Icmp( "altSound" ) )
        {
            if ( !src.ExpectAnyToken( &token ) )
            {
                return false;
            }
            altSound = declManager->FindSound( token.c_str() );
        }
        // ordered
        else if ( !token.Icmp( "ordered" ) )
        {
            // no longer supported
        }
        // no_dups
        else if ( !token.Icmp( "no_dups" ) )
        {
            parms.soundShaderFlags |= SSF_NO_DUPS;
        }
        // no_flicker
        else if ( !token.Icmp( "no_flicker" ) )
        {
            parms.soundShaderFlags |= SSF_NO_FLICKER;
        }
        // plain
        else if ( !token.Icmp( "plain" ) )
        {
            // no longer supported
        }
        // looping
        else if ( !token.Icmp( "looping" ) )
        {
            parms.soundShaderFlags |= SSF_LOOPING;
        }
        // no occlusion
        else if ( !token.Icmp( "no_occlusion" ) )
        {
            parms.soundShaderFlags |= SSF_NO_OCCLUSION;
        }
        // private
        else if ( !token.Icmp( "private" ) )
        {
            parms.soundShaderFlags |= SSF_PRIVATE_SOUND;
        }
        // antiPrivate
        else if ( !token.Icmp( "antiPrivate" ) )
        {
            parms.soundShaderFlags |= SSF_ANTI_PRIVATE_SOUND;
        }
        // once
        else if ( !token.Icmp( "playonce" ) )
        {
            parms.soundShaderFlags |= SSF_PLAY_ONCE;
        }
        // global
        else if ( !token.Icmp( "global" ) )
        {
            parms.soundShaderFlags |= SSF_GLOBAL;
        }
        // unclamped
        else if ( !token.Icmp( "unclamped" ) )
        {
            parms.soundShaderFlags |= SSF_UNCLAMPED;
        }
        // omnidirectional
        else if ( !token.Icmp( "omnidirectional" ) )
        {
            parms.soundShaderFlags |= SSF_OMNIDIRECTIONAL;
        }
        // onDemand can't be a parms, because we must track all references and overrides would confuse it
        else if ( !token.Icmp( "onDemand" ) )
        {
            // no longer loading sounds on demand
            //onDemand = true;
        }

        // the wave files
        else if ( !token.Icmp( "leadin" ) )
        {
            // add to the leadin list
            if ( !src.ReadToken( &token ) )
            {
                src.Warning( "Expected sound after leadin" );
                return false;
            }
            if ( soundSystemLocal.soundCache && numLeadins < maxSamples )
            {
                leadins[ numLeadins ] = soundSystemLocal.soundCache->FindSound( token.c_str(), onDemand );
                numLeadins++;
            }
        }
        else if ( token.Find( ".wav", false ) != -1 || token.Find( ".ogg", false ) != -1 )
        {
            // add to the wav list
            if ( soundSystemLocal.soundCache && numEntries < maxSamples )
            {
                token.BackSlashesToSlashes();
                idStr lang = cvarSystem->GetCVarString( "sys_lang" );
                if ( lang.Icmp( "english" ) != 0 && token.Find( "sound/vo/", false ) >= 0 )
                {
                    idStr work = token;
                    work.ToLower();
                    work.StripLeading( "sound/vo/" );
                    work = va( "sound/vo/%s/%s", lang.c_str(), work.c_str() );
                    if ( fileSystem->ReadFile( work, NULL, NULL ) > 0 )
                    {
                        token = work;
                    }
                    else
                    {
                        // also try to find it with the .ogg extension
                        work.SetFileExtension( ".ogg" );
                        if ( fileSystem->ReadFile( work, NULL, NULL ) > 0 )
                        {
                            token = work;
                        }
                    }
                }
                entries[ numEntries ] = soundSystemLocal.soundCache->FindSound( token.c_str(), onDemand );
                numEntries++;
            }
        }
        else
        {
            src.Warning( "unknown token '%s'", token.c_str() );
            return false;
        }
    }

    if ( parms.shakes > 0.0f )
    {
        CheckShakesAndOgg();
    }

    return true;
}
Beispiel #25
0
/*
================
idDeclAF::ParseBody
================
*/
bool idDeclAF::ParseBody( idLexer &src ) {
	bool hasJoint = false;
	idToken token;
	idAFVector angles;
	idDeclAF_Body *body = new idDeclAF_Body;

	bodies.Alloc() = body;

	body->SetDefault( this );

	if ( !src.ExpectTokenType( TT_STRING, 0, &token ) ||
			!src.ExpectTokenString( "{" ) ) {
		return false;
	}

	body->name = token;
	if ( !body->name.Icmp( "origin" ) || !body->name.Icmp( "world" ) ) {
		src.Error( "a body may not be named \"origin\" or \"world\"" );
		return false;
	}

	while( src.ReadToken( &token ) ) {

		if ( !token.Icmp( "model" ) ) {
			if ( !src.ExpectTokenType( TT_NAME, 0, &token ) ) {
				return false;
			}
			if ( !token.Icmp( "box" ) ) {
				body->modelType = TRM_BOX;
				if ( !src.ExpectTokenString( "(" ) ||
					!body->v1.Parse( src ) ||
					!src.ExpectTokenString( "," ) ||
					!body->v2.Parse( src ) ||
					!src.ExpectTokenString( ")" ) ) {
					return false;
				}
			} else if ( !token.Icmp( "octahedron" ) ) {
				body->modelType = TRM_OCTAHEDRON;
				if ( !src.ExpectTokenString( "(" ) ||
					!body->v1.Parse( src ) ||
					!src.ExpectTokenString( "," ) ||
					!body->v2.Parse( src ) ||
					!src.ExpectTokenString( ")" ) ) {
					return false;
				}
			} else if ( !token.Icmp( "dodecahedron" ) ) {
				body->modelType = TRM_DODECAHEDRON;
				if ( !src.ExpectTokenString( "(" ) ||
					!body->v1.Parse( src ) ||
					!src.ExpectTokenString( "," ) ||
					!body->v2.Parse( src ) ||
					!src.ExpectTokenString( ")" ) ) {
					return false;
				}
			} else if ( !token.Icmp( "cylinder" ) ) {
				body->modelType = TRM_CYLINDER;
				if ( !src.ExpectTokenString( "(" ) ||
					!body->v1.Parse( src ) ||
					!src.ExpectTokenString( "," ) ||
					!body->v2.Parse( src ) ||
					!src.ExpectTokenString( "," ) ) {
					return false;
				}
				body->numSides = src.ParseInt();
				if ( !src.ExpectTokenString( ")" ) ) {
					return false;
				}
			} else if ( !token.Icmp( "cone" ) ) {
				body->modelType = TRM_CONE;
				if ( !src.ExpectTokenString( "(" ) ||
					!body->v1.Parse( src ) ||
					!src.ExpectTokenString( "," ) ||
					!body->v2.Parse( src ) ||
					!src.ExpectTokenString( "," ) ) {
					return false;
				}
				body->numSides = src.ParseInt();
				if ( !src.ExpectTokenString( ")" ) ) {
					return false;
				}
			} else if ( !token.Icmp( "bone" ) ) {
				body->modelType = TRM_BONE;
				if ( !src.ExpectTokenString( "(" ) ||
					!body->v1.Parse( src ) ||
					!src.ExpectTokenString( "," ) ||
					!body->v2.Parse( src ) ||
					!src.ExpectTokenString( "," ) ) {
					return false;
				}
				body->width = src.ParseFloat();
				if ( !src.ExpectTokenString( ")" ) ) {
					return false;
				}
			} else if ( !token.Icmp( "custom" ) ) {
				src.Error( "custom models not yet implemented" );
				return false;
			} else {
				src.Error( "unkown model type %s", token.c_str() );
				return false;
			}
		} else if ( !token.Icmp( "origin" ) ) {
			if ( !body->origin.Parse( src ) ) {
				return false;
			}
		} else if ( !token.Icmp( "angles" ) ) {
			if ( !angles.Parse( src ) ) {
				return false;
			}
			body->angles = idAngles( angles.ToVec3().x, angles.ToVec3().y, angles.ToVec3().z );
		} else if ( !token.Icmp( "joint" ) ) {
			if ( !src.ExpectTokenType( TT_STRING, 0, &token ) ) {
				return false;
			}
			body->jointName = token;
			hasJoint = true;
		} else if ( !token.Icmp( "mod" ) ) {
			if ( !src.ExpectAnyToken( &token ) ) {
				return false;
			}
			body->jointMod = JointModFromString( token.c_str() );
		} else if ( !token.Icmp( "density" ) ) {
			body->density = src.ParseFloat();
		} else if ( !token.Icmp( "inertiaScale" ) ) {
			src.Parse1DMatrix( 9, body->inertiaScale[0].ToFloatPtr() );
		} else if ( !token.Icmp( "friction" ) ) {
			body->linearFriction = src.ParseFloat();
			src.ExpectTokenString( "," );
			body->angularFriction = src.ParseFloat();
			src.ExpectTokenString( "," );
			body->contactFriction = src.ParseFloat();
		} else if ( !token.Icmp( "contents" ) ) {
			ParseContents( src, body->contents );
		} else if ( !token.Icmp( "clipMask" ) ) {
			ParseContents( src, body->clipMask );
		} else if ( !token.Icmp( "selfCollision" ) ) {
			body->selfCollision = src.ParseBool();
		} else if ( !token.Icmp( "containedjoints" ) ) {
			if ( !src.ExpectTokenType( TT_STRING, 0, &token ) ) {
				return false;
			}
			body->containedJoints = token;
		} else if ( !token.Icmp( "frictionDirection" ) ) {
			if ( !body->frictionDirection.Parse( src ) ) {
				return false;
			}
		} else if ( !token.Icmp( "contactMotorDirection" ) ) {
			if ( !body->contactMotorDirection.Parse( src ) ) {
				return false;
			}
		} else if ( token == "}" ) {
			break;
		} else {
			src.Error( "unknown token %s in body", token.c_str() );
			return false;
		}
	}

	if ( body->modelType == TRM_INVALID ) {
		src.Error( "no model set for body" );
		return false;
	}

	if ( !hasJoint ) {
		src.Error( "no joint set for body" );
		return false;
	}

	body->clipMask |= CONTENTS_MOVEABLECLIP;

	return true;
}
Beispiel #26
0
/*
================
idAFVector::Parse
================
*/
bool idAFVector::Parse( idLexer &src ) {
	idToken token;

	if ( !src.ReadToken( &token ) ) {
		return false;
	}

	if ( token == "-" ) {
		negate = true;
		if ( !src.ReadToken( &token ) ) {
			return false;
		}
	}
	else {
		negate = false;
	}

	if ( token == "(" ) {
		type = idAFVector::VEC_COORDS;
		vec.x = src.ParseFloat();
		src.ExpectTokenString( "," );
		vec.y = src.ParseFloat();
		src.ExpectTokenString( "," );
		vec.z = src.ParseFloat();
		src.ExpectTokenString( ")" );
	}
	else if ( token == "joint" ) {
		type = idAFVector::VEC_JOINT;
		src.ExpectTokenString( "(" );
		src.ReadToken( &token );
		joint1 = token;
		src.ExpectTokenString( ")" );
	}
	else if ( token == "bonecenter" ) {
		type = idAFVector::VEC_BONECENTER;
		src.ExpectTokenString( "(" );
		src.ReadToken( &token );
		joint1 = token;
		src.ExpectTokenString( "," );
		src.ReadToken( &token );
		joint2 = token;
		src.ExpectTokenString( ")" );
	}
	else if ( token == "bonedir" ) {
		type = idAFVector::VEC_BONEDIR;
		src.ExpectTokenString( "(" );
		src.ReadToken( &token );
		joint1 = token;
		src.ExpectTokenString( "," );
		src.ReadToken( &token );
		joint2 = token;
		src.ExpectTokenString( ")" );
	}
	else {
		src.Error( "unknown token %s in vector", token.c_str() );
		return false;
	}

	return true;
}
Beispiel #27
0
/*
================
idDeclAF::ParseSettings
================
*/
bool idDeclAF::ParseSettings( idLexer &src ) {
	idToken token;

	if ( !src.ExpectTokenString( "{" ) ) {
		return false;
	}

	while( src.ReadToken( &token ) ) {

		if ( !token.Icmp( "mesh" ) ) {
			if ( !src.ExpectTokenType( TT_STRING, 0, &token ) ) {
				return false;
			}
		} else if ( !token.Icmp( "anim" ) ) {
			if ( !src.ExpectTokenType( TT_STRING, 0, &token ) ) {
				return false;
			}
		} else if ( !token.Icmp( "model" ) ) {
			if ( !src.ExpectTokenType( TT_STRING, 0, &token ) ) {
				return false;
			}
			model = token;
		} else if ( !token.Icmp( "skin" ) ) {
			if ( !src.ExpectTokenType( TT_STRING, 0, &token ) ) {
				return false;
			}
			skin = token;
		} else if ( !token.Icmp( "friction" ) ) {

			defaultLinearFriction = src.ParseFloat();
			if ( !src.ExpectTokenString( "," ) ) {
				return false;
			}
			defaultAngularFriction = src.ParseFloat();
			if ( !src.ExpectTokenString( "," ) ) {
				return false;
			}
			defaultContactFriction = src.ParseFloat();
			if ( src.CheckTokenString( "," ) ) {
				defaultConstraintFriction = src.ParseFloat();
			}
		} else if ( !token.Icmp( "totalMass" ) ) {
			totalMass = src.ParseFloat();
		} else if ( !token.Icmp( "suspendSpeed" ) ) {

			suspendVelocity[0] = src.ParseFloat();
			if ( !src.ExpectTokenString( "," ) ) {
				return false;
			}
			suspendVelocity[1] = src.ParseFloat();
			if ( !src.ExpectTokenString( "," ) ) {
				return false;
			}
			suspendAcceleration[0] = src.ParseFloat();
			if ( !src.ExpectTokenString( "," ) ) {
				return false;
			}
			suspendAcceleration[1] = src.ParseFloat();
		} else if ( !token.Icmp( "noMoveTime" ) ) {
			noMoveTime = src.ParseFloat();
		} else if ( !token.Icmp( "noMoveTranslation" ) ) {
			noMoveTranslation = src.ParseFloat();
		} else if ( !token.Icmp( "noMoveRotation" ) ) {
			noMoveRotation = src.ParseFloat();
		} else if ( !token.Icmp( "minMoveTime" ) ) {
			minMoveTime = src.ParseFloat();
		} else if ( !token.Icmp( "maxMoveTime" ) ) {
			maxMoveTime = src.ParseFloat();
		} else if ( !token.Icmp( "contents" ) ) {
			ParseContents( src, contents );
		} else if ( !token.Icmp( "clipMask" ) ) {
			ParseContents( src, clipMask );
		} else if ( !token.Icmp( "selfCollision" ) ) {
			selfCollision = src.ParseBool();
		} else if ( token == "}" ) {
			break;
		} else {
			src.Error( "unknown token %s in settings", token.c_str() );
			return false;
		}
	}

	return true;
}
Beispiel #28
0
/*
================
idDeclFX::ParseSingleFXAction
================
*/
void idDeclFX::ParseSingleFXAction( idLexer &src, idFXSingleAction& FXAction ) {
	idToken token;

	FXAction.type = -1;
	FXAction.sibling = -1;

	FXAction.data = "<none>";
	FXAction.name = "<none>";
	FXAction.fire = "<none>";

	FXAction.delay = 0.0f;
	FXAction.duration = 0.0f;
	FXAction.restart = 0.0f;
	FXAction.size = 0.0f;
	FXAction.fadeInTime = 0.0f;
	FXAction.fadeOutTime = 0.0f;
	FXAction.shakeTime = 0.0f;
	FXAction.shakeAmplitude = 0.0f;
	FXAction.shakeDistance = 0.0f;
	FXAction.shakeFalloff = false;
	FXAction.shakeImpulse = 0.0f;
	FXAction.shakeIgnoreMaster = false;
	FXAction.lightRadius = 0.0f;
	FXAction.rotate = 0.0f;
	FXAction.random1 = 0.0f;
	FXAction.random2 = 0.0f;

	FXAction.lightColor = vec3_origin;
	FXAction.offset = vec3_origin;
	FXAction.axis = mat3_identity;

	FXAction.bindParticles = false;
	FXAction.explicitAxis = false;
	FXAction.noshadows = false;
	FXAction.particleTrackVelocity = false;
	FXAction.trackOrigin = false;
	FXAction.soundStarted = false;

	while (1) {
		if ( !src.ReadToken( &token ) ) {
			break;
		}

		if ( !token.Icmp( "}" ) ) {
			break;
		}

		if ( !token.Icmp( "shake" ) ) {
			FXAction.type = FX_SHAKE;
			FXAction.shakeTime = src.ParseFloat();
			src.ExpectTokenString(",");
			FXAction.shakeAmplitude = src.ParseFloat();
			src.ExpectTokenString(",");
			FXAction.shakeDistance = src.ParseFloat();
			src.ExpectTokenString(",");
			FXAction.shakeFalloff = src.ParseBool();
			src.ExpectTokenString(",");
			FXAction.shakeImpulse = src.ParseFloat();
			continue;
		}

		if ( !token.Icmp( "noshadows" ) ) {
			FXAction.noshadows = true;
			continue;
		}

		if ( !token.Icmp( "name" ) ) {
			src.ReadToken( &token );
			FXAction.name = token;
			continue;
		}

		if ( !token.Icmp( "fire") ) {
			src.ReadToken( &token );
			FXAction.fire = token;
			continue;
		}

		if ( !token.Icmp( "random" ) ) {
			FXAction.random1 = src.ParseFloat();
			src.ExpectTokenString( "," );
			FXAction.random2 = src.ParseFloat();
			FXAction.delay = 0.0f;		// check random
			continue;
		}

		if ( !token.Icmp( "delay" ) ) {
			FXAction.delay = src.ParseFloat();
			continue;
		}

		if ( !token.Icmp( "rotate" ) ) {
			FXAction.rotate = src.ParseFloat();
			continue;
		}

		if ( !token.Icmp( "duration" ) ) {
			FXAction.duration = src.ParseFloat();
			continue;
		}

		if ( !token.Icmp( "trackorigin" ) ) {
			FXAction.trackOrigin = src.ParseBool();
			continue;
		}

		if (!token.Icmp("restart")) {
			FXAction.restart = src.ParseFloat();
			continue;
		}

		if ( !token.Icmp( "fadeIn" ) ) {
			FXAction.fadeInTime = src.ParseFloat();
			continue;
		}

		if ( !token.Icmp( "fadeOut" ) ) {
			FXAction.fadeOutTime = src.ParseFloat();
			continue;
		}

		if ( !token.Icmp( "size" ) ) {
			FXAction.size = src.ParseFloat();
			continue;
		}

		if ( !token.Icmp( "offset" ) ) {
			FXAction.offset.x = src.ParseFloat();
			src.ExpectTokenString( "," );
			FXAction.offset.y = src.ParseFloat();
			src.ExpectTokenString( "," );
			FXAction.offset.z = src.ParseFloat();
			continue;
		}

		if ( !token.Icmp( "axis" ) ) {
			idVec3 v;
			v.x = src.ParseFloat();
			src.ExpectTokenString( "," );
			v.y = src.ParseFloat();
			src.ExpectTokenString( "," );
			v.z = src.ParseFloat();
			v.Normalize();
			FXAction.axis = v.ToMat3();
			FXAction.explicitAxis = true;
			continue;
		}

		if ( !token.Icmp( "angle" ) ) {
			idAngles a;
			a[0] = src.ParseFloat();
			src.ExpectTokenString( "," );
			a[1] = src.ParseFloat();
			src.ExpectTokenString( "," );
			a[2] = src.ParseFloat();
			FXAction.axis = a.ToMat3();
			FXAction.explicitAxis = true;
			continue;
		}

		if ( !token.Icmp( "uselight" ) ) {
			src.ReadToken( &token );
			FXAction.data = token;
			for( int i = 0; i < events.Num(); i++ ) {
				if ( events[i].name.Icmp( FXAction.data ) == 0 ) {
					FXAction.sibling = i;
					FXAction.lightColor = events[i].lightColor;
					FXAction.lightRadius = events[i].lightRadius;
				}
			}
			FXAction.type = FX_LIGHT;

			// precache the light material
			declManager->FindMaterial( FXAction.data );
			continue;
		}

		if ( !token.Icmp( "attachlight" ) ) {
			src.ReadToken( &token );
			FXAction.data = token;
			FXAction.type = FX_ATTACHLIGHT;

			// precache it
			declManager->FindMaterial( FXAction.data );
			continue;
		}

		if ( !token.Icmp( "attachentity" ) ) {
			src.ReadToken( &token );
			FXAction.data = token;
			FXAction.type = FX_ATTACHENTITY;

			// precache the model
			renderModelManager->FindModel( FXAction.data );
			continue;
		}

		if ( !token.Icmp( "launch" ) ) {
			src.ReadToken( &token );
			FXAction.data = token;
			FXAction.type = FX_LAUNCH;

			// precache the entity def
			declManager->FindType( DECL_ENTITYDEF, FXAction.data );
			continue;
		}

		if ( !token.Icmp( "useModel" ) ) {
			src.ReadToken( &token );
			FXAction.data = token;
			for( int i = 0; i < events.Num(); i++ ) {
				if ( events[i].name.Icmp( FXAction.data ) == 0 ) {
					FXAction.sibling = i;
				}
			}
			FXAction.type = FX_MODEL;

			// precache the model
			renderModelManager->FindModel( FXAction.data );
			continue;
		}

		if ( !token.Icmp( "light" ) ) {
			src.ReadToken( &token );
			FXAction.data = token;
			src.ExpectTokenString( "," );
			FXAction.lightColor[0] = src.ParseFloat();
			src.ExpectTokenString( "," );
			FXAction.lightColor[1] = src.ParseFloat();
			src.ExpectTokenString( "," );
			FXAction.lightColor[2] = src.ParseFloat();
			src.ExpectTokenString( "," );
			FXAction.lightRadius = src.ParseFloat();
			FXAction.type = FX_LIGHT;

			// precache the light material
			declManager->FindMaterial( FXAction.data );
			continue;
		}
	
		if ( !token.Icmp( "model" ) ) {
			src.ReadToken( &token );
			FXAction.data = token;
			FXAction.type = FX_MODEL;

			// precache it
			renderModelManager->FindModel( FXAction.data );
			continue;
		}

		if ( !token.Icmp( "particle" ) ) {	// FIXME: now the same as model
			src.ReadToken( &token );
			FXAction.data = token;
			FXAction.type = FX_PARTICLE;

			// precache it
			renderModelManager->FindModel( FXAction.data );
			continue;
		}

		if ( !token.Icmp( "decal" ) ) {
			src.ReadToken( &token );
			FXAction.data = token;
			FXAction.type = FX_DECAL;

			// precache it
			declManager->FindMaterial( FXAction.data );
			continue;
		}

		if ( !token.Icmp( "particleTrackVelocity" ) ) {
			FXAction.particleTrackVelocity = true;
			continue;
		}

		if ( !token.Icmp( "sound" ) ) {
			src.ReadToken( &token );
			FXAction.data = token;
			FXAction.type = FX_SOUND;

			// precache it
			declManager->FindSound( FXAction.data );
			continue;
		}

		if ( !token.Icmp( "ignoreMaster" ) ) {
			FXAction.shakeIgnoreMaster = true;
			continue;
		}

		if ( !token.Icmp( "shockwave" ) ) {
			src.ReadToken( &token );
			FXAction.data = token;
			FXAction.type = FX_SHOCKWAVE;

			// precache the entity def
			declManager->FindType( DECL_ENTITYDEF, FXAction.data );
			continue;
		}

		src.Warning( "FX File: bad token" );
		continue;
	}
}
Beispiel #29
0
/*
====================
idMD5Mesh::ParseMesh
====================
*/
void idMD5Mesh::ParseMesh( idLexer& parser, int numJoints, const idJointMat* joints )
{
	idToken		token;
	idToken		name;
	
	parser.ExpectTokenString( "{" );
	
	//
	// parse name
	//
	if( parser.CheckTokenString( "name" ) )
	{
		parser.ReadToken( &name );
	}
	
	//
	// parse shader
	//
	parser.ExpectTokenString( "shader" );
	
	parser.ReadToken( &token );
	idStr shaderName = token;
	
	shader = declManager->FindMaterial( shaderName );
	
	//
	// parse texture coordinates
	//
	parser.ExpectTokenString( "numverts" );
	int count = parser.ParseInt();
	if( count < 0 )
	{
		parser.Error( "Invalid size: %s", token.c_str() );
	}
	
	this->numVerts = count;
	
	idList<idVec2> texCoords;
	idList<int> firstWeightForVertex;
	idList<int> numWeightsForVertex;
	
	texCoords.SetNum( count );
	firstWeightForVertex.SetNum( count );
	numWeightsForVertex.SetNum( count );
	
	int numWeights = 0;
	int maxweight = 0;
	for( int i = 0; i < texCoords.Num(); i++ )
	{
		parser.ExpectTokenString( "vert" );
		parser.ParseInt();
		
		parser.Parse1DMatrix( 2, texCoords[ i ].ToFloatPtr() );
		
		firstWeightForVertex[ i ]	= parser.ParseInt();
		numWeightsForVertex[ i ]	= parser.ParseInt();
		
		if( !numWeightsForVertex[ i ] )
		{
			parser.Error( "Vertex without any joint weights." );
		}
		
		numWeights += numWeightsForVertex[ i ];
		if( numWeightsForVertex[ i ] + firstWeightForVertex[ i ] > maxweight )
		{
			maxweight = numWeightsForVertex[ i ] + firstWeightForVertex[ i ];
		}
	}
	
	//
	// parse tris
	//
	parser.ExpectTokenString( "numtris" );
	count = parser.ParseInt();
	if( count < 0 )
	{
		parser.Error( "Invalid size: %d", count );
	}
	
	idList<int> tris;
	tris.SetNum( count * 3 );
	numTris = count;
	for( int i = 0; i < count; i++ )
	{
		parser.ExpectTokenString( "tri" );
		parser.ParseInt();
		
		tris[ i * 3 + 0 ] = parser.ParseInt();
		tris[ i * 3 + 1 ] = parser.ParseInt();
		tris[ i * 3 + 2 ] = parser.ParseInt();
	}
	
	//
	// parse weights
	//
	parser.ExpectTokenString( "numweights" );
	count = parser.ParseInt();
	if( count < 0 )
	{
		parser.Error( "Invalid size: %d", count );
	}
	
	if( maxweight > count )
	{
		parser.Warning( "Vertices reference out of range weights in model (%d of %d weights).", maxweight, count );
	}
	
	idList<vertexWeight_t> tempWeights;
	tempWeights.SetNum( count );
	assert( numJoints < 256 );		// so we can pack into bytes
	
	for( int i = 0; i < count; i++ )
	{
		parser.ExpectTokenString( "weight" );
		parser.ParseInt();
		
		int jointnum = parser.ParseInt();
		if( ( jointnum < 0 ) || ( jointnum >= numJoints ) )
		{
			parser.Error( "Joint Index out of range(%d): %d", numJoints, jointnum );
		}
		
		tempWeights[ i ].joint			= jointnum;
		tempWeights[ i ].jointWeight	= parser.ParseFloat();
		
		parser.Parse1DMatrix( 3, tempWeights[ i ].offset.ToFloatPtr() );
	}
	
	// create pre-scaled weights and an index for the vertex/joint lookup
	idVec4* scaledWeights = ( idVec4* ) Mem_Alloc16( numWeights * sizeof( scaledWeights[0] ), TAG_MD5_WEIGHT );
	int* weightIndex = ( int* ) Mem_Alloc16( numWeights * 2 * sizeof( weightIndex[0] ), TAG_MD5_INDEX );
	memset( weightIndex, 0, numWeights * 2 * sizeof( weightIndex[0] ) );
	
	count = 0;
	for( int i = 0; i < texCoords.Num(); i++ )
	{
		int num = firstWeightForVertex[i];
		for( int j = 0; j < numWeightsForVertex[i]; j++, num++, count++ )
		{
			scaledWeights[count].ToVec3() = tempWeights[num].offset * tempWeights[num].jointWeight;
			scaledWeights[count].w = tempWeights[num].jointWeight;
			weightIndex[count * 2 + 0] = tempWeights[num].joint * sizeof( idJointMat );
		}
		weightIndex[count * 2 - 1] = 1;
	}
	
	parser.ExpectTokenString( "}" );
	
	// update counters
	c_numVerts += texCoords.Num();
	c_numWeights += numWeights;
	c_numWeightJoints++;
	for( int i = 0; i < numWeights; i++ )
	{
		c_numWeightJoints += weightIndex[i * 2 + 1];
	}
	
	//
	// build a base pose that can be used for skinning
	//
	idDrawVert* basePose = ( idDrawVert* )Mem_ClearedAlloc( texCoords.Num() * sizeof( *basePose ), TAG_MD5_BASE );
	for( int j = 0, i = 0; i < texCoords.Num(); i++ )
	{
		idVec3 v = ( *( idJointMat* )( ( byte* )joints + weightIndex[j * 2 + 0] ) ) * scaledWeights[j];
		while( weightIndex[j * 2 + 1] == 0 )
		{
			j++;
			v += ( *( idJointMat* )( ( byte* )joints + weightIndex[j * 2 + 0] ) ) * scaledWeights[j];
		}
		j++;
		
		basePose[i].Clear();
		basePose[i].xyz = v;
		basePose[i].SetTexCoord( texCoords[i] );
	}
	
	// build the weights and bone indexes into the verts, so they will be duplicated
	// as necessary at mirror seems
	
	static int maxWeightsPerVert;
	static float maxResidualWeight;
	
	const int MAX_VERTEX_WEIGHTS = 4;
	
	idList< bool > jointIsUsed;
	jointIsUsed.SetNum( numJoints );
	for( int i = 0; i < jointIsUsed.Num(); i++ )
	{
		jointIsUsed[i] = false;
	}
	
	numMeshJoints = 0;
	maxJointVertDist = 0.0f;
	
	//-----------------------------------------
	// new-style setup for fixed four weights and normal / tangent deformation
	//
	// Several important models have >25% residual weight in joints after the
	// first four, which is worrisome for using a fixed four joint deformation.
	//-----------------------------------------
	for( int i = 0; i < texCoords.Num(); i++ )
	{
		idDrawVert& dv = basePose[i];
		
		// some models do have >4 joint weights, so it is necessary to sort and renormalize
		
		// sort the weights and take the four largest
		int	weights[256];
		const int numWeights = numWeightsForVertex[ i ];
		for( int j = 0; j < numWeights; j++ )
		{
			weights[j] = firstWeightForVertex[i] + j;
		}
		// bubble sort
		for( int j = 0; j < numWeights; j++ )
		{
			for( int k = 0; k < numWeights - 1 - j; k++ )
			{
				if( tempWeights[weights[k]].jointWeight < tempWeights[weights[k + 1]].jointWeight )
				{
					SwapValues( weights[k], weights[k + 1] );
				}
			}
		}
		
		if( numWeights > maxWeightsPerVert )
		{
			maxWeightsPerVert = numWeights;
		}
		
		const int usedWeights = Min( MAX_VERTEX_WEIGHTS, numWeights );
		
		float totalWeight = 0;
		for( int j = 0; j < numWeights; j++ )
		{
			totalWeight += tempWeights[weights[j]].jointWeight;
		}
		assert( totalWeight > 0.999f && totalWeight < 1.001f );
		
		float usedWeight = 0;
		for( int j = 0; j < usedWeights; j++ )
		{
			usedWeight += tempWeights[weights[j]].jointWeight;
		}
		
		const float residualWeight = totalWeight - usedWeight;
		if( residualWeight > maxResidualWeight )
		{
			maxResidualWeight = residualWeight;
		}
		
		byte finalWeights[MAX_VERTEX_WEIGHTS] = { 0 };
		byte finalJointIndecies[MAX_VERTEX_WEIGHTS] = { 0 };
		for( int j = 0; j < usedWeights; j++ )
		{
			const vertexWeight_t& weight = tempWeights[weights[j]];
			const int jointIndex = weight.joint;
			const float fw = weight.jointWeight;
			assert( fw >= 0.0f && fw <= 1.0f );
			const float normalizedWeight = fw / usedWeight;
			finalWeights[j] = idMath::Ftob( normalizedWeight * 255.0f );
			finalJointIndecies[j] = jointIndex;
		}
		
		// Sort the weights and indices for hardware skinning
		for( int k = 0; k < 3; ++k )
		{
			for( int l = k + 1; l < 4; ++l )
			{
				if( finalWeights[l] > finalWeights[k] )
				{
					SwapValues( finalWeights[k], finalWeights[l] );
					SwapValues( finalJointIndecies[k], finalJointIndecies[l] );
				}
			}
		}
		
		// Give any left over to the biggest weight
		finalWeights[0] += Max( 255 - finalWeights[0] - finalWeights[1] - finalWeights[2] - finalWeights[3], 0 );
		
		dv.color[0] = finalJointIndecies[0];
		dv.color[1] = finalJointIndecies[1];
		dv.color[2] = finalJointIndecies[2];
		dv.color[3] = finalJointIndecies[3];
		
		dv.color2[0] = finalWeights[0];
		dv.color2[1] = finalWeights[1];
		dv.color2[2] = finalWeights[2];
		dv.color2[3] = finalWeights[3];
		
		for( int j = usedWeights; j < 4; j++ )
		{
			assert( dv.color2[j] == 0 );
		}
		
		for( int j = 0; j < usedWeights; j++ )
		{
			if( !jointIsUsed[finalJointIndecies[j]] )
			{
				jointIsUsed[finalJointIndecies[j]] = true;
				numMeshJoints++;
			}
			const idJointMat& joint = joints[finalJointIndecies[j]];
			float dist = ( dv.xyz - joint.GetTranslation() ).Length();
			if( dist > maxJointVertDist )
			{
				maxJointVertDist = dist;
			}
		}
	}
	
	meshJoints = ( byte* ) Mem_Alloc( numMeshJoints * sizeof( meshJoints[0] ), TAG_MODEL );
	numMeshJoints = 0;
	for( int i = 0; i < numJoints; i++ )
	{
		if( jointIsUsed[i] )
		{
			meshJoints[numMeshJoints++] = i;
		}
	}
	
	// build the deformInfo and collect a final base pose with the mirror
	// seam verts properly including the bone weights
	deformInfo = R_BuildDeformInfo( texCoords.Num(), basePose, tris.Num(), tris.Ptr(),
									shader->UseUnsmoothedTangents() );
									
	for( int i = 0; i < deformInfo->numOutputVerts; i++ )
	{
		for( int j = 0; j < 4; j++ )
		{
			if( deformInfo->verts[i].color[j] >= numJoints )
			{
				idLib::FatalError( "Bad joint index" );
			}
		}
	}
	
	Mem_Free( basePose );
}
Beispiel #30
0
/*
================
idDeclAF::ParseUniversalJoint
================
*/
bool idDeclAF::ParseUniversalJoint( idLexer &src ) {
	idToken token;
	idDeclAF_Constraint *constraint = new idDeclAF_Constraint;

	constraint->SetDefault( this );
	constraints.Alloc() = constraint;

	if ( !src.ExpectTokenType( TT_STRING, 0, &token ) ||
			!src.ExpectTokenString( "{" ) ) {
		return false;
	}

	constraint->type = DECLAF_CONSTRAINT_UNIVERSALJOINT;
	constraint->limit = idDeclAF_Constraint::LIMIT_NONE;
	constraint->name = token;
	constraint->friction = 0.5f;
	constraint->anchor.ToVec3().Zero();
	constraint->shaft[0].ToVec3().Zero();
	constraint->shaft[1].ToVec3().Zero();

	while( src.ReadToken( &token ) ) {

		if ( !token.Icmp( "body1" ) ) {
			src.ExpectTokenType( TT_STRING, 0, &token );
			constraint->body1 = token;
		} else if ( !token.Icmp( "body2" ) ) {
			src.ExpectTokenType( TT_STRING, 0, &token );
			constraint->body2 = token;
		} else if ( !token.Icmp( "anchor" ) ) {
			if ( !constraint->anchor.Parse( src ) ) {
				return false;
			}
		} else if ( !token.Icmp( "shafts" ) ) {
			if ( !constraint->shaft[0].Parse( src ) ||
					!src.ExpectTokenString( "," ) ||
					!constraint->shaft[1].Parse( src ) ) {
				return false;
			}
		} else if ( !token.Icmp( "conelimit" ) ) {
			if ( !constraint->limitAxis.Parse( src ) ||
				!src.ExpectTokenString( "," ) ) {
					return false;
			}
			constraint->limitAngles[0] = src.ParseFloat();
			constraint->limit = idDeclAF_Constraint::LIMIT_CONE;
		} else if ( !token.Icmp( "pyramidlimit" ) ) {
			if ( !constraint->limitAxis.Parse( src ) ||
				!src.ExpectTokenString( "," ) ) {
					return false;
			}
			constraint->limitAngles[0] = src.ParseFloat();
			if ( !src.ExpectTokenString( "," ) ) {
				return false;
			}
			constraint->limitAngles[1] = src.ParseFloat();
			if ( !src.ExpectTokenString( "," ) ) {
				return false;
			}
			constraint->limitAngles[2] = src.ParseFloat();
			constraint->limit = idDeclAF_Constraint::LIMIT_PYRAMID;
		} else if ( !token.Icmp( "friction" ) ) {
			constraint->friction = src.ParseFloat();
		} else if ( token == "}" ) {
			break;
		} else {
			src.Error( "unknown token %s in universal joint", token.c_str() );
			return false;
		}
	}

	return true;
}