Inheritance: idTech4.Text.idDecl
Exemple #1
0
        public void SetAnimation(idDeclModel modelDef, string sourceName, string animName, idMD5Anim[] md5anims)
        {
            _modelDef = modelDef;
            _anims    = md5anims;

            _realName  = sourceName;
            _name      = animName;
            _animFlags = new AnimationFlags();
            _frameCommands.Clear();
            _frameLookups.Clear();
        }
Exemple #2
0
        public idRenderModel SetModel(string modelName)
        {
            FreeData();

            // check if we're just clearing the model
            if ((modelName == null) || (modelName == string.Empty))
            {
                return(null);
            }

            _modelDef = idR.DeclManager.FindType <idDeclModel>(DeclType.ModelDef, modelName, false);

            if (_modelDef == null)
            {
                return(null);
            }

            idRenderModel renderModel = _modelDef.Model;

            if (renderModel == null)
            {
                _modelDef = null;
                return(null);
            }

            // make sure model hasn't been purged
            _modelDef.Touch();

            _modelDef.SetupJoints(_joints, ref _frameBounds, _removeOriginOffset);
            _modelDef.Model.Reset();

            // set the modelDef on all channels
            for (int i = (int)AnimationChannel.All; i < (int)AnimationChannel.Count; i++)
            {
                for (int j = 0; j < idR.AnimationCountPerChannel; j++)
                {
                    _channels[i, j].Reset(_modelDef);
                }
            }

            return(_modelDef.Model);
        }
Exemple #3
0
        public void Reset(idDeclModel modelDef)
        {
            _modelDef           = modelDef;
            _cycle              = 1;
            _startTime          = 0;
            _endTime            = 0;
            _timeOffset         = 0;
            _rate               = 1.0f;
            _frame              = 0;
            _allowMove          = true;
            _allowFrameCommands = true;
            _animNumber         = 0;

            _animWeights = new float[idR.MaxSyncedAnimations];

            _blendStartValue = 0.0f;
            _blendEndValue   = 0.0f;
            _blendStartTime  = 0;
            _blendDuration   = 0;
        }
Exemple #4
0
        private void FreeData()
        {
            if (_entity != null)
            {
                _entity.BecomeInactive(EntityThinkFlags.Animate);
            }

            for (int i = (int)AnimationChannel.All; i < (int)AnimationChannel.Count; i++)
            {
                for (int j = 0; j < idR.AnimationCountPerChannel; j++)
                {
                    _channels[i, j].Reset(null);
                }
            }

            idConsole.Warning("TODOO: jointMods.DeleteContents(true);");

            _joints   = null;
            _modelDef = null;

            ForceUpdate();
        }
Exemple #5
0
		private void FreeData()
		{
			if(_entity != null)
			{
				_entity.BecomeInactive(EntityThinkFlags.Animate);
			}

			for(int i = (int) AnimationChannel.All; i < (int) AnimationChannel.Count; i++)
			{
				for(int j = 0; j < idR.AnimationCountPerChannel; j++)
				{
					_channels[i, j].Reset(null);
				}
			}

			idConsole.Warning("TODOO: jointMods.DeleteContents(true);");

			_joints = null;
			_modelDef = null;

			ForceUpdate();
		}
Exemple #6
0
		public idRenderModel SetModel(string modelName)
		{
			FreeData();

			// check if we're just clearing the model
			if((modelName == null) || (modelName == string.Empty))
			{
				return null;
			}

			_modelDef = idR.DeclManager.FindType<idDeclModel>(DeclType.ModelDef, modelName, false);

			if(_modelDef == null)
			{
				return null;
			}

			idRenderModel renderModel = _modelDef.Model;

			if(renderModel == null)
			{
				_modelDef = null;
				return null;
			}

			// make sure model hasn't been purged
			_modelDef.Touch();

			_modelDef.SetupJoints(_joints, ref _frameBounds, _removeOriginOffset);
			_modelDef.Model.Reset();

			// set the modelDef on all channels
			for(int i = (int) AnimationChannel.All; i < (int) AnimationChannel.Count; i++)
			{
				for(int j = 0; j < idR.AnimationCountPerChannel; j++)
				{
					_channels[i, j].Reset(_modelDef);
				}
			}

			return _modelDef.Model;
		}
Exemple #7
0
        public string AddFrameCommand(idDeclModel modelDef, int frameIndex, idLexer lexer, idDict def)
        {
            // make sure we're within bounds
            if ((frameIndex < 1) || (frameIndex > _anims[0].FrameCount))
            {
                return(string.Format("Frame {0} out of range", frameIndex));
            }

            // frame numbers are 1 based in .def files, but 0 based internally
            frameIndex--;

            idToken token;
            AnimationFrameCommand frameCommand = new AnimationFrameCommand();

            if ((token = lexer.ReadTokenOnLine()) == null)
            {
                return("Unexpected end of line");
            }

            string tokenValue = token.ToString();

            if (tokenValue == "call")
            {
                if ((token = lexer.ReadTokenOnLine()) == null)
                {
                    return("Unexpected end of line");
                }

                tokenValue        = token.ToString();
                frameCommand.Type = AnimationFrameCommandType.ScriptFunction;
                idConsole.Warning("TODO: fc.function = gameLocal.program.FindFunction( token );");

                if (frameCommand.Function == null)
                {
                    return(string.Format("Function '{0}' not found", tokenValue));
                }
            }
            else if (tokenValue == "object_call")
            {
                if ((token = lexer.ReadTokenOnLine()) == null)
                {
                    return("Unexpected end of line");
                }

                tokenValue          = token.ToString();
                frameCommand.Type   = AnimationFrameCommandType.ScriptFunctionObject;
                frameCommand.String = tokenValue;
            }
            else if (tokenValue == "event")
            {
                if ((token = lexer.ReadTokenOnLine()) == null)
                {
                    return("Unexpected end of line");
                }

                tokenValue        = token.ToString();
                frameCommand.Type = AnimationFrameCommandType.EventFunction;

                idConsole.Warning("TODO: idAnim Event");

                /*const idEventDef *ev = idEventDef::FindEvent( token );
                 * if ( !ev ) {
                 *      return va( "Event '%s' not found", token.c_str() );
                 * }
                 * if ( ev->GetNumArgs() != 0 ) {
                 *      return va( "Event '%s' has arguments", token.c_str() );
                 * }*/

                frameCommand.String = tokenValue;
            }
            else if ((tokenValue == "sound") ||
                     (tokenValue == "sound_voice") ||
                     (tokenValue == "sound_voice2") ||
                     (tokenValue == "sound_body") ||
                     (tokenValue == "sound_body2") ||
                     (tokenValue == "sound_body3") ||
                     (tokenValue == "sound_weapon") ||
                     (tokenValue == "sound_global") ||
                     (tokenValue == "sound_item") ||
                     (tokenValue == "sound_chatter"))
            {
                if ((token = lexer.ReadTokenOnLine()) == null)
                {
                    return("Unexpected end of line");
                }

                switch (tokenValue)
                {
                case "sound":
                    frameCommand.Type = AnimationFrameCommandType.Sound;
                    break;

                case "sound_voice":
                    frameCommand.Type = AnimationFrameCommandType.SoundVoice;
                    break;

                case "sound_voice2":
                    frameCommand.Type = AnimationFrameCommandType.SoundVoice2;
                    break;

                case "sound_body":
                    frameCommand.Type = AnimationFrameCommandType.SoundBody;
                    break;

                case "sound_body2":
                    frameCommand.Type = AnimationFrameCommandType.SoundBody2;
                    break;

                case "sound_body3":
                    frameCommand.Type = AnimationFrameCommandType.SoundBody3;
                    break;

                case "sound_weapon":
                    frameCommand.Type = AnimationFrameCommandType.SoundWeapon;
                    break;

                case "sound_global":
                    frameCommand.Type = AnimationFrameCommandType.SoundGlobal;
                    break;

                case "sound_item":
                    frameCommand.Type = AnimationFrameCommandType.SoundItem;
                    break;

                case "sound_chatter":
                    frameCommand.Type = AnimationFrameCommandType.SoundChatter;
                    break;
                }

                tokenValue = token.ToString();

                if (tokenValue.StartsWith("snd_") == true)
                {
                    frameCommand.String = tokenValue;
                }
                else
                {
                    frameCommand.SoundMaterial = idE.DeclManager.FindSound(tokenValue);

                    if (frameCommand.SoundMaterial.State == DeclState.Defaulted)
                    {
                        idConsole.Warning("Sound '{0}' not found", tokenValue);
                    }
                }
            }
            else if (tokenValue == "skin")
            {
                if ((token = lexer.ReadTokenOnLine()) == null)
                {
                    return("Unexpected end of line");
                }

                tokenValue        = token.ToString();
                frameCommand.Type = AnimationFrameCommandType.Skin;

                if (tokenValue == "none")
                {
                    frameCommand.Skin = null;
                }
                else
                {
                    frameCommand.Skin = idE.DeclManager.FindSkin(tokenValue);

                    if (frameCommand.Skin == null)
                    {
                        return(string.Format("Skin '{0}' not found", tokenValue));
                    }
                }
            }
            else if (tokenValue == "fx")
            {
                if ((token = lexer.ReadTokenOnLine()) == null)
                {
                    return("Unexpected end of line");
                }

                tokenValue        = token.ToString();
                frameCommand.Type = AnimationFrameCommandType.Fx;

                if (idE.DeclManager.FindType(DeclType.Fx, tokenValue) == null)
                {
                    return(string.Format("fx '{0}' not found", tokenValue));
                }

                frameCommand.String = tokenValue;
            }
            else if (tokenValue == "trigger")
            {
                if ((token = lexer.ReadTokenOnLine()) == null)
                {
                    return("Unexpected end of line");
                }

                tokenValue          = token.ToString();
                frameCommand.Type   = AnimationFrameCommandType.Trigger;
                frameCommand.String = tokenValue;
            }
            else if (tokenValue == "triggerSmokeParticle")
            {
                if ((token = lexer.ReadTokenOnLine()) == null)
                {
                    return("Unexpected end of line");
                }

                tokenValue          = token.ToString();
                frameCommand.Type   = AnimationFrameCommandType.TriggerSmokeParticle;
                frameCommand.String = tokenValue;
            }
            else if ((tokenValue == "melee") ||
                     (tokenValue == "direct_damage") ||
                     (tokenValue == "attack_begin"))
            {
                if ((token = lexer.ReadTokenOnLine()) == null)
                {
                    return("Unexpected end of line");
                }

                switch (tokenValue)
                {
                case "melee":
                    frameCommand.Type = AnimationFrameCommandType.Melee;
                    break;

                case "direct_damage":
                    frameCommand.Type = AnimationFrameCommandType.DirectDamage;
                    break;

                case "attack_begin":
                    frameCommand.Type = AnimationFrameCommandType.BeginAttack;
                    break;
                }

                tokenValue = token.ToString();

                if (idR.Game.FindEntityDef(tokenValue, false) == null)
                {
                    return(string.Format("Unknown entityDef '{0}'", tokenValue));
                }

                frameCommand.String = tokenValue;
            }
            else if (tokenValue == "attack_end")
            {
                frameCommand.Type = AnimationFrameCommandType.EndAttack;
            }
            else if (tokenValue == "muzzle_flash")
            {
                if ((token = lexer.ReadTokenOnLine()) == null)
                {
                    return("Unexpected end of line");
                }

                tokenValue = token.ToString();

                if ((tokenValue != string.Empty) && (modelDef.FindJoint(tokenValue) == null))
                {
                    return(string.Format("Joint '{0}' not found", tokenValue));
                }

                frameCommand.Type   = AnimationFrameCommandType.MuzzleFlash;
                frameCommand.String = tokenValue;
            }
            else if ((tokenValue == "create_missile") ||
                     (tokenValue == "launch_missile"))
            {
                if ((token = lexer.ReadTokenOnLine()) == null)
                {
                    return("Unexpected end of line");
                }

                switch (tokenValue)
                {
                case "create_missile":
                    frameCommand.Type = AnimationFrameCommandType.CreateMissile;
                    break;

                case "launch_missile":
                    frameCommand.Type = AnimationFrameCommandType.LaunchMissile;
                    break;
                }

                tokenValue          = token.ToString();
                frameCommand.String = tokenValue;

                if (modelDef.FindJoint(tokenValue) == null)
                {
                    return(string.Format("Joint '{0}' not found", tokenValue));
                }
            }
            else if (tokenValue == "fire_missile_at_target")
            {
                if ((token = lexer.ReadTokenOnLine()) == null)
                {
                    return("Unexpected end of line");
                }

                JointInfo jointInfo = modelDef.FindJoint(token.ToString());

                if (jointInfo == null)
                {
                    return(string.Format("Joint '{0}' not found", token.ToString()));
                }

                if ((token = lexer.ReadTokenOnLine()) == null)
                {
                    return("Unexpected end of line");
                }

                frameCommand.Type   = AnimationFrameCommandType.FireMissileAtTarget;
                frameCommand.String = token.ToString();
                frameCommand.Index  = jointInfo.Index;
            }
            else if (tokenValue == "footstep")
            {
                frameCommand.Type = AnimationFrameCommandType.Footstep;
            }
            else if (tokenValue == "leftfoot")
            {
                frameCommand.Type = AnimationFrameCommandType.LeftFoot;
            }
            else if (tokenValue == "rightfoot")
            {
                frameCommand.Type = AnimationFrameCommandType.RightFoot;
            }
            else if (tokenValue == "enableEyeFocus")
            {
                frameCommand.Type = AnimationFrameCommandType.EnableEyeFocus;
            }
            else if (tokenValue == "disableEyeFocus")
            {
                frameCommand.Type = AnimationFrameCommandType.DisableEyeFocus;
            }
            else if (tokenValue == "disableGravity")
            {
                frameCommand.Type = AnimationFrameCommandType.DisableGravity;
            }
            else if (tokenValue == "enableGravity")
            {
                frameCommand.Type = AnimationFrameCommandType.EnableGravity;
            }
            else if (tokenValue == "jump")
            {
                frameCommand.Type = AnimationFrameCommandType.Jump;
            }
            else if (tokenValue == "enableClip")
            {
                frameCommand.Type = AnimationFrameCommandType.EnableClip;
            }
            else if (tokenValue == "disableClip")
            {
                frameCommand.Type = AnimationFrameCommandType.DisableClip;
            }
            else if (tokenValue == "enableWalkIK")
            {
                frameCommand.Type = AnimationFrameCommandType.EnableWalkIk;
            }
            else if (tokenValue == "disableWalkIK")
            {
                frameCommand.Type = AnimationFrameCommandType.DisableWalkIk;
            }
            else if (tokenValue == "enableLegIK")
            {
                if ((token = lexer.ReadTokenOnLine()) == null)
                {
                    return("Unexpected end of file");
                }

                frameCommand.Type  = AnimationFrameCommandType.EnableLegIk;
                frameCommand.Index = int.Parse(token.ToString());
            }
            else if (tokenValue == "disableLegIK")
            {
                if ((token = lexer.ReadTokenOnLine()) == null)
                {
                    return("Unexpected end of file");
                }

                frameCommand.Type  = AnimationFrameCommandType.DisableLegIk;
                frameCommand.Index = int.Parse(token.ToString());
            }
            else if (tokenValue == "recordDemo")
            {
                frameCommand.Type = AnimationFrameCommandType.RecordDemo;

                if ((token = lexer.ReadTokenOnLine()) != null)
                {
                    frameCommand.String = token.ToString();
                }
            }
            else if (tokenValue == "aviGame")
            {
                frameCommand.Type = AnimationFrameCommandType.AviGame;

                if ((token = lexer.ReadTokenOnLine()) != null)
                {
                    frameCommand.String = token.ToString();
                }
            }
            else
            {
                return(string.Format("Unknown command '{0}'", tokenValue));
            }

            // check if we've initialized the frame lookup table
            if (_frameLookups.Count == 0)
            {
                // we haven't, so allocate the table and initialize it

                for (int i = 0; i < _anims[0].FrameCount; i++)
                {
                    _frameLookups.Add(new AnimationFrameLookup());
                }
            }

            // calculate the index of the new command
            int index = _frameLookups[frameIndex].FirstCommand + _frameLookups[frameIndex].Index;
            int count = _frameLookups.Count;

            _frameCommands.Insert(index, frameCommand);

            // fix the indices of any later frames to account for the inserted command
            for (int i = frameIndex + 1; i < count; i++)
            {
                _frameLookups[i].FirstCommand++;
            }

            // increase the number of commands on this frame
            _frameLookups[frameIndex].Index++;

            // return with no error
            return(null);
        }
Exemple #8
0
		public void Reset(idDeclModel modelDef)
		{
			_modelDef = modelDef;
			_cycle = 1;
			_startTime = 0;
			_endTime = 0;
			_timeOffset = 0;
			_rate = 1.0f;
			_frame = 0;
			_allowMove = true;
			_allowFrameCommands = true;
			_animNumber = 0;

			_animWeights = new float[idR.MaxSyncedAnimations];

			_blendStartValue = 0.0f;
			_blendEndValue = 0.0f;
			_blendStartTime = 0;
			_blendDuration = 0;
		}
Exemple #9
0
		public void SetAnimation(idDeclModel modelDef, string sourceName, string animName, idMD5Anim[] md5anims)
		{
			_modelDef = modelDef;
			_anims = md5anims;
			
			_realName = sourceName;
			_name = animName;
			_animFlags = new AnimationFlags();
			_frameCommands.Clear();
			_frameLookups.Clear();
		}
Exemple #10
0
		public string AddFrameCommand(idDeclModel modelDef, int frameIndex, idLexer lexer, idDict def)
		{
			// make sure we're within bounds
			if((frameIndex < 1) || (frameIndex > _anims[0].FrameCount))
			{
				return string.Format("Frame {0} out of range", frameIndex);
			}

			// frame numbers are 1 based in .def files, but 0 based internally
			frameIndex--;

			idToken token;
			AnimationFrameCommand frameCommand = new AnimationFrameCommand();

			if((token = lexer.ReadTokenOnLine()) == null)
			{
				return "Unexpected end of line";
			}

			string tokenValue = token.ToString();

			if(tokenValue == "call")
			{
				if((token = lexer.ReadTokenOnLine()) == null)
				{
					return "Unexpected end of line";
				}

				tokenValue = token.ToString();
				frameCommand.Type = AnimationFrameCommandType.ScriptFunction;
				idConsole.Warning("TODO: fc.function = gameLocal.program.FindFunction( token );");

				if(frameCommand.Function == null)
				{
					return string.Format("Function '{0}' not found", tokenValue);
				}
			}
			else if(tokenValue == "object_call")
			{
				if((token = lexer.ReadTokenOnLine()) == null)
				{
					return "Unexpected end of line";
				}

				tokenValue = token.ToString();
				frameCommand.Type = AnimationFrameCommandType.ScriptFunctionObject;
				frameCommand.String = tokenValue;
			}
			else if(tokenValue == "event")
			{
				if((token = lexer.ReadTokenOnLine()) == null)
				{
					return "Unexpected end of line";
				}

				tokenValue = token.ToString();
				frameCommand.Type = AnimationFrameCommandType.EventFunction;

				idConsole.Warning("TODO: idAnim Event");
				/*const idEventDef *ev = idEventDef::FindEvent( token );
				if ( !ev ) {
					return va( "Event '%s' not found", token.c_str() );
				}
				if ( ev->GetNumArgs() != 0 ) {
					return va( "Event '%s' has arguments", token.c_str() );
				}*/

				frameCommand.String = tokenValue;
			} 
			else if((tokenValue == "sound") 
				|| (tokenValue == "sound_voice")
				|| (tokenValue == "sound_voice2")
				|| (tokenValue == "sound_body")
				|| (tokenValue == "sound_body2")
				|| (tokenValue == "sound_body3")
				|| (tokenValue == "sound_weapon")
				|| (tokenValue == "sound_global")
				|| (tokenValue == "sound_item")
				|| (tokenValue == "sound_chatter"))
			{
				if((token = lexer.ReadTokenOnLine()) == null)
				{
					return "Unexpected end of line";
				}

				switch(tokenValue)
				{
					case "sound":
						frameCommand.Type = AnimationFrameCommandType.Sound;
						break;

					case "sound_voice":
						frameCommand.Type = AnimationFrameCommandType.SoundVoice;
						break;

					case "sound_voice2":
						frameCommand.Type = AnimationFrameCommandType.SoundVoice2;
						break;

					case "sound_body":
						frameCommand.Type = AnimationFrameCommandType.SoundBody;
						break;

					case "sound_body2":
						frameCommand.Type = AnimationFrameCommandType.SoundBody2;
						break;

					case "sound_body3":
						frameCommand.Type = AnimationFrameCommandType.SoundBody3;
						break;

					case "sound_weapon":
						frameCommand.Type = AnimationFrameCommandType.SoundWeapon;
						break;

					case "sound_global":
						frameCommand.Type = AnimationFrameCommandType.SoundGlobal;
						break;

					case "sound_item":
						frameCommand.Type = AnimationFrameCommandType.SoundItem;
						break;

					case "sound_chatter":
						frameCommand.Type = AnimationFrameCommandType.SoundChatter;
						break;
				}
				
				tokenValue = token.ToString();

				if(tokenValue.StartsWith("snd_") == true)
				{
					frameCommand.String = tokenValue;
				}
				else
				{
					frameCommand.SoundMaterial = idE.DeclManager.FindSound(tokenValue);

					if(frameCommand.SoundMaterial.State == DeclState.Defaulted)
					{
						idConsole.Warning("Sound '{0}' not found", tokenValue);
					}
				}
			}
			else if(tokenValue == "skin")
			{
				if((token = lexer.ReadTokenOnLine()) == null)
				{
					return "Unexpected end of line";
				}

				tokenValue = token.ToString();
				frameCommand.Type = AnimationFrameCommandType.Skin;

				if(tokenValue == "none")
				{
					frameCommand.Skin = null;
				}
				else
				{
					frameCommand.Skin = idE.DeclManager.FindSkin(tokenValue);

					if(frameCommand.Skin == null)
					{
						return string.Format("Skin '{0}' not found", tokenValue);
					}
				}
			}
			else if(tokenValue == "fx")
			{
				if((token = lexer.ReadTokenOnLine()) == null)
				{
					return "Unexpected end of line";
				}

				tokenValue = token.ToString();
				frameCommand.Type = AnimationFrameCommandType.Fx;

				if(idE.DeclManager.FindType(DeclType.Fx, tokenValue) == null)
				{
					return string.Format("fx '{0}' not found", tokenValue);
				}

				frameCommand.String = tokenValue;
			}
			else if(tokenValue == "trigger")
			{
				if((token = lexer.ReadTokenOnLine()) == null)
				{
					return "Unexpected end of line";
				}
				
				tokenValue = token.ToString();
				frameCommand.Type = AnimationFrameCommandType.Trigger;
				frameCommand.String = tokenValue;
			}
			else if(tokenValue == "triggerSmokeParticle")
			{
				if((token = lexer.ReadTokenOnLine()) == null)
				{
					return "Unexpected end of line";
				}

				tokenValue = token.ToString();
				frameCommand.Type = AnimationFrameCommandType.TriggerSmokeParticle;
				frameCommand.String = tokenValue;
			}
			else if((tokenValue == "melee")
				|| (tokenValue == "direct_damage")
				|| (tokenValue == "attack_begin"))
			{
				if((token = lexer.ReadTokenOnLine()) == null)
				{
					return "Unexpected end of line";
				}

				switch(tokenValue)
				{
					case "melee":
						frameCommand.Type = AnimationFrameCommandType.Melee;
						break;

					case "direct_damage":
						frameCommand.Type = AnimationFrameCommandType.DirectDamage;
						break;

					case "attack_begin":
						frameCommand.Type = AnimationFrameCommandType.BeginAttack;
						break;
				}

				tokenValue = token.ToString();
								
				if(idR.Game.FindEntityDef(tokenValue, false) == null)
				{
					return string.Format("Unknown entityDef '{0}'", tokenValue);
				}

				frameCommand.String = tokenValue;
			}
			else if(tokenValue == "attack_end")
			{
				frameCommand.Type = AnimationFrameCommandType.EndAttack;
			}
			else if(tokenValue == "muzzle_flash")
			{
				if((token = lexer.ReadTokenOnLine()) == null)
				{
					return "Unexpected end of line";
				}

				tokenValue = token.ToString();

				if((tokenValue != string.Empty) && (modelDef.FindJoint(tokenValue) == null))
				{
					return string.Format("Joint '{0}' not found", tokenValue);
				}

				frameCommand.Type = AnimationFrameCommandType.MuzzleFlash;
				frameCommand.String = tokenValue;
			}
			else if((tokenValue == "create_missile")
				|| (tokenValue == "launch_missile"))
			{
				if((token = lexer.ReadTokenOnLine()) == null)
				{
					return "Unexpected end of line";
				}

				switch(tokenValue)
				{
					case "create_missile":
						frameCommand.Type = AnimationFrameCommandType.CreateMissile;
						break;

					case "launch_missile":
						frameCommand.Type = AnimationFrameCommandType.LaunchMissile;
						break;
				}

				tokenValue = token.ToString();
				frameCommand.String = tokenValue;

				if(modelDef.FindJoint(tokenValue) == null)
				{
					return string.Format("Joint '{0}' not found", tokenValue);
				}
			}
			else if(tokenValue == "fire_missile_at_target")
			{
				if((token = lexer.ReadTokenOnLine()) == null)
				{
					return "Unexpected end of line";
				}

				JointInfo jointInfo = modelDef.FindJoint(token.ToString());

				if(jointInfo == null)
				{
					return string.Format("Joint '{0}' not found", token.ToString());
				}

				if((token = lexer.ReadTokenOnLine()) == null)
				{
					return "Unexpected end of line";
				}

				frameCommand.Type = AnimationFrameCommandType.FireMissileAtTarget;
				frameCommand.String = token.ToString();
				frameCommand.Index = jointInfo.Index;
			}
			else if(tokenValue == "footstep")
			{
				frameCommand.Type = AnimationFrameCommandType.Footstep;
			}
			else if(tokenValue == "leftfoot")
			{
				frameCommand.Type = AnimationFrameCommandType.LeftFoot;
			}
			else if(tokenValue == "rightfoot")
			{
				frameCommand.Type = AnimationFrameCommandType.RightFoot;
			}
			else if(tokenValue == "enableEyeFocus")
			{
				frameCommand.Type = AnimationFrameCommandType.EnableEyeFocus;
			}
			else if(tokenValue == "disableEyeFocus")
			{
				frameCommand.Type = AnimationFrameCommandType.DisableEyeFocus;
			}
			else if(tokenValue == "disableGravity")
			{
				frameCommand.Type = AnimationFrameCommandType.DisableGravity;
			}
			else if(tokenValue == "enableGravity")
			{
				frameCommand.Type = AnimationFrameCommandType.EnableGravity;
			}
			else if(tokenValue == "jump")
			{
				frameCommand.Type = AnimationFrameCommandType.Jump;
			}
			else if(tokenValue == "enableClip")
			{
				frameCommand.Type = AnimationFrameCommandType.EnableClip;
			}
			else if(tokenValue == "disableClip")
			{
				frameCommand.Type = AnimationFrameCommandType.DisableClip;
			}
			else if(tokenValue == "enableWalkIK")
			{
				frameCommand.Type = AnimationFrameCommandType.EnableWalkIk;
			}
			else if(tokenValue == "disableWalkIK")
			{
				frameCommand.Type = AnimationFrameCommandType.DisableWalkIk;
			}
			else if(tokenValue == "enableLegIK")
			{
				if((token = lexer.ReadTokenOnLine()) == null)
				{
					return "Unexpected end of file";
				}

				frameCommand.Type = AnimationFrameCommandType.EnableLegIk;
				frameCommand.Index = int.Parse(token.ToString());
			}
			else if(tokenValue == "disableLegIK")
			{
				if((token = lexer.ReadTokenOnLine()) == null)
				{
					return "Unexpected end of file";
				}

				frameCommand.Type = AnimationFrameCommandType.DisableLegIk;
				frameCommand.Index = int.Parse(token.ToString());
			}
			else if(tokenValue == "recordDemo")
			{
				frameCommand.Type = AnimationFrameCommandType.RecordDemo;

				if((token = lexer.ReadTokenOnLine()) != null)
				{
					frameCommand.String = token.ToString();
				}
			}
			else if(tokenValue == "aviGame")
			{
				frameCommand.Type = AnimationFrameCommandType.AviGame;

				if((token = lexer.ReadTokenOnLine()) != null)
				{
					frameCommand.String = token.ToString();
				}
			}
			else
			{
				return string.Format("Unknown command '{0}'", tokenValue);
			}

			// check if we've initialized the frame lookup table
			if(_frameLookups.Count == 0)
			{
				// we haven't, so allocate the table and initialize it

				for(int i = 0; i < _anims[0].FrameCount; i++)
				{
					_frameLookups.Add(new AnimationFrameLookup());
				}
			}

			// calculate the index of the new command
			int index = _frameLookups[frameIndex].FirstCommand + _frameLookups[frameIndex].Index;
			int count = _frameLookups.Count;

			_frameCommands.Insert(index, frameCommand);

			// fix the indices of any later frames to account for the inserted command
			for(int i = frameIndex + 1; i < count; i++)
			{
				_frameLookups[i].FirstCommand++;
			}

			// increase the number of commands on this frame
			_frameLookups[frameIndex].Index++;

			// return with no error
			return null;
		}