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; } } }
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)); } } }
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; } } }