private static void BuildStep(ParticleSystemLogicStep step, StringBuilder output, int depth, Random random)
		{
			for (int i = 0; i < depth; i++)
				output.Append('\t');


			if (opTypes == null)
			{
				opTypes = new Dictionary<string, char>();
				opTypes.Add("div", '/');
				opTypes.Add("add", '+');
				opTypes.Add("sub", '-');
				opTypes.Add("mul", '*');
			}
			if (step.children == null)
			{
				//this is a simple function
				switch (step.type)
				{
					case "set":
						output.Append(step.target);
						output.Append(" = ");
						output.Append(step.arg0);
						output.AppendLine(";");
						return;
					case "madd":
						output.Append(step.target);
						output.Append(" += ");
						output.Append(step.arg0);
						output.Append(" * ");
						output.Append(step.arg1);
						output.AppendLine(";");
						return;
					case "add":
					case "sub":
					case "mul":
					case "div":
						output.Append(step.target);
						output.Append(' ');
						if (step.arg1 == null)
						{
							output.Append(opTypes[step.type]);
							output.Append("= ");
							output.Append(step.arg0);
						}
						else
						{
							output.Append("= ");
							output.Append(step.arg0);
							output.Append(' ');
							output.Append(opTypes[step.type]);
							output.Append(' ');
							output.Append(step.arg1);
						}
						output.AppendLine(";");
						return;
					default:
						//function
						output.Append(step.target);
						output.Append(" = ");
						output.Append(step.type);
						output.Append('(');
						output.Append(step.arg0);
						if (step.arg1 != null)
						{
							output.Append(',');
							output.Append(step.arg1);
						}
						if (step.type.StartsWith("rand"))
						{
							//add two static-random numbers onto the end of the function call
							output.Append(", randIndex.x + ");
							output.Append(random.NextDouble());
							output.Append(", randIndex.y + ");
							output.Append(random.NextDouble());
						}
						output.AppendLine(");");
						return;
				}
			}
			else
			{
				//branching operations
				switch (step.type)
				{
					case "loop":

						//for loop
						output.Append("for (int i");
						output.Append(depth);
						output.Append("; i");
						output.Append(depth);
						output.Append(" < ");
						output.Append(step.arg0);
						output.Append("; i");
						output.Append(depth);
						output.AppendLine("++)");
						// {
						for (int i = 0; i < depth; i++)
							output.Append('\t');
						output.AppendLine("{");

						//children
						for (int i = 0; i < step.children.Length; i++)
							BuildStep(step.children[i], output, depth + 1, random);

						// }
						for (int i = 0; i < depth; i++)
							output.Append('\t');
						output.AppendLine("}");

						return;

					case "if_equal":
					case "if_notequal":
					case "if_lessequal":
					case "if_greaterequal":
					case "if_less":
					case "if_greater":

						//if (
						output.Append("if (");
						output.Append(step.arg0);
						output.Append(' ');

						//operator
						if (step.type == "if_equal") output.Append("==");
						if (step.type == "if_notequal") output.Append("!=");
						if (step.type == "if_lessequal") output.Append("<=");
						if (step.type == "if_greaterequal") output.Append(">=");
						if (step.type == "if_less") output.Append('<');
						if (step.type == "if_greater") output.Append('>');

						output.Append(' ');
						output.Append(step.arg1);
						output.AppendLine(")");

						// {
						for (int i = 0; i < depth; i++)
							output.Append('\t');
						output.AppendLine("{");

						//children
						for (int i = 0; i < step.children.Length; i++)
							BuildStep(step.children[i], output, depth + 1,random);

						// }
						for (int i = 0; i < depth; i++)
							output.Append('\t');
						output.AppendLine("}");

						return;
					}	
			}
		}
Example #2
0
        private static void BuildLogic(CodeStatementCollection statements, ReadOnlyArrayCollection <ParticleSystemLogicStep> steps, Dictionary <string, bool> argUsed, int depth)
        {
            for (int i = 0; i < steps.Length; i++)
            {
                ParticleSystemLogicStep step = steps[i];

                CodeExpression arg0   = Arg(step.arg0);
                CodeExpression arg1   = Arg(step.arg1);
                CodeExpression argT   = Arg(step.target);
                CodeExpression target = Arg(step.target);

                if (arg0 != null && arg0 is CodePrimitiveExpression == false)
                {
                    argUsed[step.arg0] = true;
                }
                if (arg1 != null && arg1 is CodePrimitiveExpression == false)
                {
                    argUsed[step.arg1] = true;
                }
                if (target != null && target is CodePrimitiveExpression == false)
                {
                    argUsed[step.target] = true;
                }

                if (step.Children.Length > 0)
                {
                    CodeVariableReferenceExpression local = new CodeVariableReferenceExpression("i" + depth);

                    if (step.type == "loop")
                    {
                        CodeIterationStatement iteration = new CodeIterationStatement();

                        iteration.InitStatement      = new CodeVariableDeclarationStatement(typeof(uint), local.VariableName, new CodePrimitiveExpression((uint)0));
                        iteration.TestExpression     = new CodeBinaryOperatorExpression(local, CodeBinaryOperatorType.LessThan, arg0);
                        iteration.IncrementStatement = new CodeAssignStatement(local, new CodeBinaryOperatorExpression(local, CodeBinaryOperatorType.Add, new CodePrimitiveExpression((uint)1)));

                        BuildLogic(iteration.Statements, step.Children, argUsed, depth + 1);
                        statements.Add(iteration);
                    }
                    else
                    {
                        CodeBinaryOperatorType op = CodeBinaryOperatorType.IdentityEquality;
                        //if
                        switch (step.type)
                        {
                        case "if_notequal":
                            op = CodeBinaryOperatorType.IdentityInequality;
                            break;

                        case "if_lessequal":
                            op = CodeBinaryOperatorType.LessThanOrEqual;
                            break;

                        case "if_greaterequal":
                            op = CodeBinaryOperatorType.GreaterThanOrEqual;
                            break;

                        case "if_less":
                            op = CodeBinaryOperatorType.LessThan;
                            break;

                        case "if_greater":
                            op = CodeBinaryOperatorType.GreaterThan;
                            break;
                        }

                        CodeConditionStatement condition = new CodeConditionStatement();
                        condition.Condition = new CodeBinaryOperatorExpression(
                            arg0, op, arg1);


                        BuildLogic(condition.TrueStatements, step.Children, argUsed, depth + 1);

                        statements.Add(condition);
                    }
                }
                else
                {
                    CodeExpression expression = null;

                    switch (step.type)
                    {
                    case "set":
                        expression = arg0;
                        break;

                    case "add":
                        expression = Op(CodeBinaryOperatorType.Add, argT, arg0, arg1);
                        break;

                    case "sub":
                        expression = Op(CodeBinaryOperatorType.Subtract, argT, arg0, arg1);
                        break;

                    case "mul":
                        expression = Op(CodeBinaryOperatorType.Multiply, argT, arg0, arg1);
                        break;

                    case "div":
                        expression = Op(CodeBinaryOperatorType.Divide, argT, arg0, arg1);
                        break;

                    case "abs":
                    case "sign":
                    case "cos":
                    case "sin":
                    case "acos":
                    case "asin":
                    case "tan":
                    case "atan":
                    case "sqrt":
                        expression = MathOp1(step.type, arg0);
                        break;

                    case "atan2":
                    case "min":
                    case "max":
                        expression = MathOp2(step.type, arg0, arg1);
                        break;

                    case "saturate":
                        expression =
                            MathOp2("max",
                                    new CodePrimitiveExpression(0.0f),
                                    MathOp2("min", new CodePrimitiveExpression(1.0f),
                                            arg0));
                        break;

                    case "rsqrt":
                        expression =
                            new CodeBinaryOperatorExpression(
                                new CodePrimitiveExpression(1.0f), CodeBinaryOperatorType.Divide,
                                MathOp1("sqrt", arg0));
                        break;

                    case "madd":
                        expression =
                            new CodeBinaryOperatorExpression(argT,
                                                             CodeBinaryOperatorType.Add,
                                                             new CodeBinaryOperatorExpression(arg0,
                                                                                              CodeBinaryOperatorType.Multiply,
                                                                                              arg1));
                        break;

                    case "rand":
                        argUsed["rand"] = true;
                        expression      = Rand(arg0, arg1, statements);
                        break;

                    case "rand_smooth":
                        argUsed["rand"] = true;
                        expression      = RandSmooth(arg0, arg1, statements);
                        break;
                    }

                    if (expression == null)
                    {
                        throw new ArgumentNullException("Unknown statement " + step.type);
                    }

                    statements.Add(new CodeAssignStatement(target,
                                                           expression));
                }
            }
        }
Example #3
0
        private static void BuildStep(ParticleSystemLogicStep step, StringBuilder output, int depth, Random random)
        {
            for (int i = 0; i < depth; i++)
            {
                output.Append('\t');
            }


            if (opTypes == null)
            {
                opTypes = new Dictionary <string, char>();
                opTypes.Add("div", '/');
                opTypes.Add("add", '+');
                opTypes.Add("sub", '-');
                opTypes.Add("mul", '*');
            }
            if (step.children == null)
            {
                //this is a simple function
                switch (step.type)
                {
                case "set":
                    output.Append(step.target);
                    output.Append(" = ");
                    output.Append(step.arg0);
                    output.AppendLine(";");
                    return;

                case "madd":
                    output.Append(step.target);
                    output.Append(" += ");
                    output.Append(step.arg0);
                    output.Append(" * ");
                    output.Append(step.arg1);
                    output.AppendLine(";");
                    return;

                case "add":
                case "sub":
                case "mul":
                case "div":
                    output.Append(step.target);
                    output.Append(' ');
                    if (step.arg1 == null)
                    {
                        output.Append(opTypes[step.type]);
                        output.Append("= ");
                        output.Append(step.arg0);
                    }
                    else
                    {
                        output.Append("= ");
                        output.Append(step.arg0);
                        output.Append(' ');
                        output.Append(opTypes[step.type]);
                        output.Append(' ');
                        output.Append(step.arg1);
                    }
                    output.AppendLine(";");
                    return;

                default:
                    //function
                    output.Append(step.target);
                    output.Append(" = ");
                    output.Append(step.type);
                    output.Append('(');
                    output.Append(step.arg0);
                    if (step.arg1 != null)
                    {
                        output.Append(',');
                        output.Append(step.arg1);
                    }
                    if (step.type.StartsWith("rand"))
                    {
                        //add two static-random numbers onto the end of the function call
                        output.Append(", randIndex.x + ");
                        output.Append(random.NextDouble());
                        output.Append(", randIndex.y + ");
                        output.Append(random.NextDouble());
                    }
                    output.AppendLine(");");
                    return;
                }
            }
            else
            {
                //branching operations
                switch (step.type)
                {
                case "loop":

                    //for loop
                    output.Append("for (int i");
                    output.Append(depth);
                    output.Append("; i");
                    output.Append(depth);
                    output.Append(" < ");
                    output.Append(step.arg0);
                    output.Append("; i");
                    output.Append(depth);
                    output.AppendLine("++)");
                    // {
                    for (int i = 0; i < depth; i++)
                    {
                        output.Append('\t');
                    }
                    output.AppendLine("{");

                    //children
                    for (int i = 0; i < step.children.Length; i++)
                    {
                        BuildStep(step.children[i], output, depth + 1, random);
                    }

                    // }
                    for (int i = 0; i < depth; i++)
                    {
                        output.Append('\t');
                    }
                    output.AppendLine("}");

                    return;

                case "if_equal":
                case "if_notequal":
                case "if_lessequal":
                case "if_greaterequal":
                case "if_less":
                case "if_greater":

                    //if (
                    output.Append("if (");
                    output.Append(step.arg0);
                    output.Append(' ');

                    //operator
                    if (step.type == "if_equal")
                    {
                        output.Append("==");
                    }
                    if (step.type == "if_notequal")
                    {
                        output.Append("!=");
                    }
                    if (step.type == "if_lessequal")
                    {
                        output.Append("<=");
                    }
                    if (step.type == "if_greaterequal")
                    {
                        output.Append(">=");
                    }
                    if (step.type == "if_less")
                    {
                        output.Append('<');
                    }
                    if (step.type == "if_greater")
                    {
                        output.Append('>');
                    }

                    output.Append(' ');
                    output.Append(step.arg1);
                    output.AppendLine(")");

                    // {
                    for (int i = 0; i < depth; i++)
                    {
                        output.Append('\t');
                    }
                    output.AppendLine("{");

                    //children
                    for (int i = 0; i < step.children.Length; i++)
                    {
                        BuildStep(step.children[i], output, depth + 1, random);
                    }

                    // }
                    for (int i = 0; i < depth; i++)
                    {
                        output.Append('\t');
                    }
                    output.AppendLine("}");

                    return;
                }
            }
        }