public static bool ProcessTime(ref MinMax <float> timeRange, ref bool isFade, float initialTime, float finalTime, ref List <ParticleEmitterToken> .Enumerator tokenIter) { // determine if this time specification is a fade directive if (tokenIter.Current.Type == TokenType.KeywordFade) { // it is... the next token must be "so" ParticleEmitterTokenizer.NextToken(ref tokenIter); if (tokenIter.Current.Type != TokenType.KeywordSo) { throw new Exception("Expecting \"so\" after \"fade\"."); } // flip the fade flag on isFade = true; // move to next token (so that we land on "at" for the code below) ParticleEmitterTokenizer.NextToken(ref tokenIter); } else { isFade = false; // just to be safe } switch (tokenIter.Current.Type) { case TokenType.KeywordAt: { // easy, just grab the time ParticleEmitterTokenizer.NextToken(ref tokenIter); timeRange = ProcessNumber(ref tokenIter); } break; case TokenType.KeywordInitial: { // use initial time that was passed in. if (isFade) { throw new Exception("Cannot use \"fade so\" modifier on \"initial\" times."); } timeRange.Min = initialTime; timeRange.Max = initialTime; ParticleEmitterTokenizer.NextToken(ref tokenIter); } break; case TokenType.KeywordFinal: { // use final time that was passed in. timeRange.Min = finalTime; timeRange.Max = finalTime; ParticleEmitterTokenizer.NextToken(ref tokenIter); } break; default: throw new Exception("Expected time specifier: \"[fade so] at\", \"initial\", or \"[fade so] final\""); } return(true); }
public static MinMax <float> ProcessNumber(ref List <ParticleEmitterToken> .Enumerator tokenIter) { MinMax <float> number = new MinMax <float>(); // the first token is either the random keyword, or it's an actual number. switch (tokenIter.Current.Type) { case TokenType.KeywordRandom: // parse random number into minmax ParticleEmitterTokenizer.NextToken(ref tokenIter); if (tokenIter.Current.Type != TokenType.OpenParen) { throw new Exception("Expecting opening paren after Random keyword."); } ParticleEmitterTokenizer.NextToken(ref tokenIter); if (tokenIter.Current.Type != TokenType.RealNumber) { throw new Exception("Expecting first number within Random(...)."); } number.Min = float.Parse(tokenIter.Current.StringValue, CultureInfo.InvariantCulture.NumberFormat); ParticleEmitterTokenizer.NextToken(ref tokenIter); if (tokenIter.Current.Type != TokenType.Comma) { throw new Exception("Expecting comma within Random(...)."); } ParticleEmitterTokenizer.NextToken(ref tokenIter); if (tokenIter.Current.Type != TokenType.RealNumber) { throw new Exception("Expecting second number within Random(...)."); } number.Max = float.Parse(tokenIter.Current.StringValue, CultureInfo.InvariantCulture.NumberFormat); ParticleEmitterTokenizer.NextToken(ref tokenIter); if (tokenIter.Current.Type != TokenType.CloseParen) { throw new Exception("Missing close paren on Random(...)."); } ParticleEmitterTokenizer.NextToken(ref tokenIter); break; case TokenType.RealNumber: // min and max both equal realnumber if (tokenIter.Current.Type != TokenType.RealNumber) { throw new Exception("Expecting number."); } number.Max = number.Min = float.Parse(tokenIter.Current.StringValue, CultureInfo.InvariantCulture.NumberFormat); ParticleEmitterTokenizer.NextToken(ref tokenIter); break; default: throw new Exception("Expecting either Random(...) or a number value."); } return(number); }
public static MinMax <Color> ProcessColor(ref List <ParticleEmitterToken> .Enumerator tokenIter) { MinMax <Color> c = new MinMax <Color>(); // this token needs to be a RGBA keyword. if (tokenIter.Current.Type != TokenType.KeywordColor) { throw new Exception("Expecting RGBA(...)!"); } ParticleEmitterTokenizer.NextToken(ref tokenIter); if (tokenIter.Current.Type != TokenType.OpenParen) { throw new Exception("Expecting ( after RGBA!"); } MinMax <float> r = new MinMax <float>(); MinMax <float> g = new MinMax <float>(); MinMax <float> b = new MinMax <float>(); MinMax <float> a = new MinMax <float>(); ParticleEmitterTokenizer.NextToken(ref tokenIter); r = ProcessNumber(ref tokenIter); if (tokenIter.Current.Type != TokenType.Comma) { throw new Exception("Color components must be seperated by a comma."); } ParticleEmitterTokenizer.NextToken(ref tokenIter); g = ProcessNumber(ref tokenIter); if (tokenIter.Current.Type != TokenType.Comma) { throw new Exception("Color components must be seperated by a comma."); } ParticleEmitterTokenizer.NextToken(ref tokenIter); b = ProcessNumber(ref tokenIter); if (tokenIter.Current.Type != TokenType.Comma) { throw new Exception("Color components must be seperated by a comma."); } ParticleEmitterTokenizer.NextToken(ref tokenIter); a = ProcessNumber(ref tokenIter); if (tokenIter.Current.Type != TokenType.CloseParen) { throw new Exception("Expecting ) to close vector."); } ParticleEmitterTokenizer.NextToken(ref tokenIter); c.Min = new Color(r.Min, g.Min, b.Min, a.Min); c.Max = new Color(r.Max, g.Max, b.Max, a.Max); return(c); }