Added textures to biomes and an expression parser.
This commit is contained in:
parent
b1a8da324d
commit
c80b035ce7
23
.gitignore
vendored
23
.gitignore
vendored
@ -3,6 +3,29 @@ Game/Logs/
|
||||
Game/[Oo]bj/
|
||||
Game/[Tt]emp/
|
||||
|
||||
# Unity specific
|
||||
/[Ll]ibrary/
|
||||
/[Tt]emp/
|
||||
/[Oo]bj/
|
||||
/[Bb]uild/
|
||||
|
||||
# Autogenerated VS/MD solution and project files
|
||||
*.csproj
|
||||
*.unityproj
|
||||
*.sln
|
||||
*.suo
|
||||
*.tmp
|
||||
*.user
|
||||
*.userprefs
|
||||
*.pidb
|
||||
*.booproj
|
||||
|
||||
# Unity3D generated meta files
|
||||
*.pidb.meta
|
||||
|
||||
# Unity3D Generated File On Crash Reports
|
||||
sysinfo.txt
|
||||
|
||||
# User-specific files
|
||||
*.suo
|
||||
*.user
|
||||
|
@ -53,6 +53,7 @@
|
||||
<Compile Include="Assets\Scripts\Model\Biome.cs" />
|
||||
<Compile Include="Assets\Scripts\Model\Config\TerrainGeneratorConfig.cs" />
|
||||
<Compile Include="Assets\Scripts\Model\Map.cs" />
|
||||
<Compile Include="Assets\Scripts\Model\Texture.cs" />
|
||||
<Compile Include="Assets\Scripts\Noise\NoiseGenerator.cs" />
|
||||
<Compile Include="Assets\Scripts\Noise\PerlinNoiseGenerator.cs" />
|
||||
<Compile Include="Assets\Scripts\Unity\InitializeScript.cs" />
|
||||
@ -60,6 +61,7 @@
|
||||
<Compile Include="Assets\Scripts\Utils\Algorithms.cs" />
|
||||
<Compile Include="Assets\Scripts\Utils\Algorithms\GridTraverseAlgorithm.cs" />
|
||||
<Compile Include="Assets\Scripts\Utils\ColorHelper.cs" />
|
||||
<Compile Include="Assets\Scripts\Utils\Expression.cs" />
|
||||
<Compile Include="Assets\Scripts\Utils\Logger.cs" />
|
||||
<Compile Include="Assets\Scripts\Utils\RandomExtensions.cs" />
|
||||
<Compile Include="Assets\Scripts\Utils\Range.cs" />
|
||||
|
@ -53,6 +53,7 @@
|
||||
<Compile Include="Assets\Scripts\Model\Biome.cs" />
|
||||
<Compile Include="Assets\Scripts\Model\Config\TerrainGeneratorConfig.cs" />
|
||||
<Compile Include="Assets\Scripts\Model\Map.cs" />
|
||||
<Compile Include="Assets\Scripts\Model\Texture.cs" />
|
||||
<Compile Include="Assets\Scripts\Noise\NoiseGenerator.cs" />
|
||||
<Compile Include="Assets\Scripts\Noise\PerlinNoiseGenerator.cs" />
|
||||
<Compile Include="Assets\Scripts\Unity\InitializeScript.cs" />
|
||||
@ -60,6 +61,7 @@
|
||||
<Compile Include="Assets\Scripts\Utils\Algorithms.cs" />
|
||||
<Compile Include="Assets\Scripts\Utils\Algorithms\GridTraverseAlgorithm.cs" />
|
||||
<Compile Include="Assets\Scripts\Utils\ColorHelper.cs" />
|
||||
<Compile Include="Assets\Scripts\Utils\Expression.cs" />
|
||||
<Compile Include="Assets\Scripts\Utils\Logger.cs" />
|
||||
<Compile Include="Assets\Scripts\Utils\RandomExtensions.cs" />
|
||||
<Compile Include="Assets\Scripts\Utils\Range.cs" />
|
||||
|
@ -40,5 +40,11 @@ namespace TransportGame.Model
|
||||
/// </summary>
|
||||
[XmlElement("vegetationDensity")]
|
||||
public Range VegetationDensity { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets an array of textures to use
|
||||
/// </summary>
|
||||
[XmlArray("textures")]
|
||||
public Texture[] Textures { get; set; }
|
||||
}
|
||||
}
|
||||
|
@ -2,10 +2,17 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace Assets.Scripts.Model
|
||||
namespace TransportGame.Model
|
||||
{
|
||||
class Texture
|
||||
[XmlRoot("texture")]
|
||||
public class Texture
|
||||
{
|
||||
[XmlAttribute("src")]
|
||||
public string Source { get; set; }
|
||||
|
||||
[XmlAttribute("expr")]
|
||||
public string Expression { get; set; }
|
||||
}
|
||||
}
|
||||
|
425
Game/Assets/Scripts/Utils/Expression.cs
Normal file
425
Game/Assets/Scripts/Utils/Expression.cs
Normal file
@ -0,0 +1,425 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using UnityEngine;
|
||||
|
||||
namespace GraphingCalculator
|
||||
{
|
||||
public class Expression
|
||||
{
|
||||
#region Types
|
||||
|
||||
public enum TokenType
|
||||
{
|
||||
None, Literal, Identifier, Operator, ArgSeparator,
|
||||
LParanthesis, RParanthesis, Function
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Represents a token
|
||||
/// </summary>
|
||||
protected class Token
|
||||
{
|
||||
public TokenType Type { get; set; }
|
||||
public string Text { get; set; }
|
||||
|
||||
public Token(TokenType type, string text)
|
||||
{
|
||||
Type = type;
|
||||
Text = text;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Variables, properties
|
||||
|
||||
private string expressionString;
|
||||
private bool parsed = false;
|
||||
|
||||
protected List<Token> Tokens { get; private set; }
|
||||
protected List<Token> Postfix { get; private set; }
|
||||
public Dictionary<string, float> Variables { get; private set; }
|
||||
|
||||
public string ExpressionString
|
||||
{
|
||||
get { return expressionString; }
|
||||
set
|
||||
{
|
||||
expressionString = value;
|
||||
parsed = false;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Other stuff
|
||||
|
||||
public void AddVariable(string name, float value)
|
||||
{
|
||||
Variables.Add(name, value);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructor
|
||||
public Expression()
|
||||
{
|
||||
Tokens = new List<Token>();
|
||||
Postfix = new List<Token>();
|
||||
Variables = new Dictionary<string, float>();
|
||||
|
||||
Variables.Add("pi", Mathf.PI);
|
||||
}
|
||||
|
||||
public Expression(string expr)
|
||||
: this()
|
||||
{
|
||||
expressionString = expr;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Parser
|
||||
|
||||
private void AnalyzeLex()
|
||||
{
|
||||
Tokens.Clear();
|
||||
|
||||
for (int i = 0; i < ExpressionString.Length; i++)
|
||||
{
|
||||
if (char.IsWhiteSpace(ExpressionString[i])) continue;
|
||||
|
||||
if (IsOperator(ExpressionString[i]))
|
||||
{
|
||||
// Handle unary minus
|
||||
if (IsUnaryMinus(ExpressionString[i]))
|
||||
Tokens.Add(new Token(TokenType.Operator, "u"));
|
||||
|
||||
else
|
||||
Tokens.Add(new Token(TokenType.Operator, ExpressionString[i].ToString()));
|
||||
}
|
||||
|
||||
else if (ExpressionString[i] == '(')
|
||||
Tokens.Add(new Token(TokenType.LParanthesis, ExpressionString[i].ToString()));
|
||||
|
||||
else if (ExpressionString[i] == ')')
|
||||
Tokens.Add(new Token(TokenType.RParanthesis, ExpressionString[i].ToString()));
|
||||
|
||||
else if (ExpressionString[i] == ',')
|
||||
Tokens.Add(new Token(TokenType.ArgSeparator, ExpressionString[i].ToString()));
|
||||
|
||||
else if (Char.IsDigit(ExpressionString[i]))
|
||||
Tokens.Add(new Token(TokenType.Literal, GetLiteral(ExpressionString, ref i)));
|
||||
|
||||
else if (Char.IsLetter(ExpressionString[i]))
|
||||
Tokens.Add(new Token(TokenType.Identifier, GetIdentifier(ExpressionString, ref i)));
|
||||
|
||||
else throw new Exception("Unrecognized character found!");
|
||||
}
|
||||
}
|
||||
|
||||
private void ConvertPostfix()
|
||||
{
|
||||
Stack<Token> stack = new Stack<Token>();
|
||||
|
||||
for (int i = 0; i < Tokens.Count; i++)
|
||||
{
|
||||
Token t = Tokens[i];
|
||||
|
||||
switch (t.Type)
|
||||
{
|
||||
case TokenType.Identifier:
|
||||
|
||||
// Followed by '(' means function
|
||||
if (i + 1 < Tokens.Count && Tokens[i + 1].Type == TokenType.LParanthesis)
|
||||
stack.Push(new Token(TokenType.Function, t.Text));
|
||||
|
||||
// Else, variable
|
||||
else Postfix.Add(t);
|
||||
|
||||
break;
|
||||
|
||||
case TokenType.Literal:
|
||||
Postfix.Add(t);
|
||||
break;
|
||||
|
||||
case TokenType.ArgSeparator:
|
||||
|
||||
// We pop everything from the stack until left paranthesis open
|
||||
while (stack.Peek().Type != TokenType.LParanthesis)
|
||||
{
|
||||
Postfix.Add(stack.Pop());
|
||||
|
||||
if (stack.Count == 0)
|
||||
throw new Exception("Syntax error! Unexpected comma.");
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case TokenType.Operator:
|
||||
|
||||
if (IsLeftAssociative(t.Text))
|
||||
{
|
||||
while (stack.Count != 0 && Precedence(t.Text) <= Precedence(stack.Peek().Text))
|
||||
Postfix.Add(stack.Pop());
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
while (stack.Count != 0 && Precedence(t.Text) < Precedence(stack.Peek().Text))
|
||||
Postfix.Add(stack.Pop());
|
||||
}
|
||||
|
||||
stack.Push(t);
|
||||
break;
|
||||
|
||||
case TokenType.LParanthesis:
|
||||
stack.Push(t);
|
||||
break;
|
||||
|
||||
case TokenType.RParanthesis:
|
||||
|
||||
while (stack.Peek().Type != TokenType.LParanthesis)
|
||||
{
|
||||
Postfix.Add(stack.Pop());
|
||||
|
||||
if (stack.Count == 0)
|
||||
throw new Exception("Mismatched parantheses!");
|
||||
}
|
||||
|
||||
stack.Pop(); // Pop Lparanthesis
|
||||
|
||||
if (stack.Count > 0 && stack.Peek().Type == TokenType.Function)
|
||||
Postfix.Add(stack.Pop()); // Pop function name
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
while (stack.Count > 0)
|
||||
{
|
||||
if (stack.Peek().Type == TokenType.LParanthesis)
|
||||
throw new Exception("Mismatched parantheses!");
|
||||
|
||||
Postfix.Add(stack.Pop());
|
||||
}
|
||||
}
|
||||
|
||||
public void ParseExpression()
|
||||
{
|
||||
if (!parsed)
|
||||
{
|
||||
Tokens.Clear();
|
||||
Postfix.Clear();
|
||||
|
||||
AnalyzeLex();
|
||||
ConvertPostfix();
|
||||
}
|
||||
}
|
||||
|
||||
public float Evaluate()
|
||||
{
|
||||
// Parse expression first
|
||||
ParseExpression();
|
||||
|
||||
// Expression is empty, so is result
|
||||
if (Postfix.Count == 0)
|
||||
return 0;
|
||||
|
||||
Stack<float> stack = new Stack<float>();
|
||||
|
||||
foreach (var t in Postfix)
|
||||
{
|
||||
switch (t.Type)
|
||||
{
|
||||
// We already replace functions, so identifiers are variables
|
||||
case TokenType.Identifier:
|
||||
|
||||
if (!Variables.ContainsKey(t.Text))
|
||||
throw new Exception("Undefined variable '" + t.Text + "'.");
|
||||
|
||||
stack.Push(Variables[t.Text]);
|
||||
break;
|
||||
|
||||
case TokenType.Literal:
|
||||
stack.Push(float.Parse(t.Text));
|
||||
break;
|
||||
|
||||
case TokenType.Operator:
|
||||
switch (t.Text)
|
||||
{
|
||||
case "u":
|
||||
stack.Push(stack.Pop() * -1);
|
||||
break;
|
||||
|
||||
case "+":
|
||||
stack.Push(stack.Pop() + stack.Pop());
|
||||
break;
|
||||
|
||||
case "-":
|
||||
{
|
||||
float b = stack.Pop();
|
||||
float a = stack.Pop();
|
||||
stack.Push(a - b);
|
||||
}
|
||||
break;
|
||||
|
||||
case "*":
|
||||
stack.Push(stack.Pop() * stack.Pop());
|
||||
break;
|
||||
|
||||
case "/":
|
||||
{
|
||||
float b = stack.Pop();
|
||||
float a = stack.Pop();
|
||||
stack.Push(a / b);
|
||||
}
|
||||
break;
|
||||
|
||||
case "%":
|
||||
{
|
||||
float b = stack.Pop();
|
||||
float a = stack.Pop();
|
||||
stack.Push(a % b);
|
||||
}
|
||||
break;
|
||||
|
||||
case "^":
|
||||
{
|
||||
float b = stack.Pop();
|
||||
float a = stack.Pop();
|
||||
stack.Push(Mathf.Pow(a, b));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case TokenType.Function:
|
||||
EvaluateFunction(t.Text, ref stack);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return stack.Pop();
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Helper routines
|
||||
|
||||
private bool IsUnaryMinus(char c)
|
||||
{
|
||||
if (c == '-')
|
||||
{
|
||||
// Nothing in front, definitely unary
|
||||
if (Tokens.Count == 0)
|
||||
return true;
|
||||
|
||||
// See what's in front
|
||||
TokenType inFront = Tokens.Last().Type;
|
||||
|
||||
// If what's in front cannot be an operand, than it is unary minus
|
||||
return inFront == TokenType.ArgSeparator || inFront == TokenType.LParanthesis || inFront == TokenType.Operator;
|
||||
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private void EvaluateFunction(string func, ref Stack<float> stack)
|
||||
{
|
||||
switch (func)
|
||||
{
|
||||
case "sin": stack.Push(Mathf.Sin(stack.Pop())); break;
|
||||
case "cos": stack.Push(Mathf.Cos(stack.Pop())); break;
|
||||
case "tan": stack.Push(Mathf.Tan(stack.Pop())); break;
|
||||
case "ctan": stack.Push(1 / Mathf.Tan(stack.Pop())); break;
|
||||
|
||||
case "arcsin": stack.Push(Mathf.Asin(stack.Pop())); break;
|
||||
case "asin": stack.Push(Mathf.Asin(stack.Pop())); break;
|
||||
case "arccos": stack.Push(Mathf.Acos(stack.Pop())); break;
|
||||
case "acos": stack.Push(Mathf.Acos(stack.Pop())); break;
|
||||
case "arctan": stack.Push(Mathf.Atan(stack.Pop())); break;
|
||||
case "atan": stack.Push(Mathf.Atan(stack.Pop())); break;
|
||||
|
||||
case "truncate":
|
||||
case "floor": stack.Push(Mathf.Floor(stack.Pop())); break;
|
||||
case "ceil":
|
||||
case "ceiling": stack.Push(Mathf.Ceil(stack.Pop())); break;
|
||||
|
||||
case "sqrt": stack.Push(Mathf.Sqrt(stack.Pop())); break;
|
||||
case "cbrt": stack.Push(Mathf.Pow(stack.Pop(), 1.0f / 3.0f)); break;
|
||||
case "root": stack.Push(Mathf.Pow(stack.Pop(), 1 / stack.Pop())); break;
|
||||
|
||||
case "abs": stack.Push(Math.Abs(stack.Pop())); break;
|
||||
case "max": stack.Push(Math.Max(stack.Pop(), stack.Pop())); break;
|
||||
case "min": stack.Push(Math.Min(stack.Pop(), stack.Pop())); break;
|
||||
|
||||
case "lg": stack.Push(Mathf.Log10(stack.Pop())); break;
|
||||
case "log": stack.Push(Mathf.Log(stack.Pop(), stack.Pop())); break;
|
||||
|
||||
case "clamp01": stack.Push(Mathf.Clamp01(stack.Pop())); break;
|
||||
case "clamp": stack.Push(Mathf.Clamp(stack.Pop(), stack.Pop(), stack.Pop())); break;
|
||||
case "lerp": stack.Push(Mathf.Lerp(stack.Pop(), stack.Pop(), stack.Pop())); break;
|
||||
|
||||
default: throw new Exception("Undefined function '" + func + "'.");
|
||||
}
|
||||
}
|
||||
|
||||
private static bool IsLeftAssociative(string op)
|
||||
{
|
||||
return (op != "^");
|
||||
}
|
||||
|
||||
private static int Precedence(string op)
|
||||
{
|
||||
switch (op)
|
||||
{
|
||||
case "+":
|
||||
case "-": return 1;
|
||||
|
||||
case "*":
|
||||
case "/":
|
||||
case "%": return 2;
|
||||
|
||||
case "u":
|
||||
case "^": return 3;
|
||||
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
|
||||
private static bool IsOperator(char c)
|
||||
{
|
||||
const string operators = "+-*/%^";
|
||||
return operators.Contains(c);
|
||||
}
|
||||
|
||||
private static string GetIdentifier(string s, ref int index)
|
||||
{
|
||||
int start = index;
|
||||
|
||||
while (index < s.Length && (char.IsLetterOrDigit(s[index]) || s[index] == '_'))
|
||||
++index;
|
||||
|
||||
index -= 1;
|
||||
|
||||
return s.Substring(start, index + 1 - start);
|
||||
}
|
||||
|
||||
private static string GetLiteral(string s, ref int index)
|
||||
{
|
||||
int start = index;
|
||||
|
||||
while (index < s.Length && (char.IsDigit(s[index]) || s[index] == '.'))
|
||||
++index;
|
||||
|
||||
index -= 1;
|
||||
|
||||
return s.Substring(start, index + 1 - start);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Game/Library/metadata/3c/3c67fd1150208b74a835ab23e76d4024
Normal file
BIN
Game/Library/metadata/3c/3c67fd1150208b74a835ab23e76d4024
Normal file
Binary file not shown.
BIN
Game/Library/metadata/3c/3c67fd1150208b74a835ab23e76d4024.info
Normal file
BIN
Game/Library/metadata/3c/3c67fd1150208b74a835ab23e76d4024.info
Normal file
Binary file not shown.
Binary file not shown.
BIN
Game/Library/metadata/93/9376fb88fdf55af4db8c52c23079dad3
Normal file
BIN
Game/Library/metadata/93/9376fb88fdf55af4db8c52c23079dad3
Normal file
Binary file not shown.
BIN
Game/Library/metadata/93/9376fb88fdf55af4db8c52c23079dad3.info
Normal file
BIN
Game/Library/metadata/93/9376fb88fdf55af4db8c52c23079dad3.info
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -1,3 +1,9 @@
|
||||
Base path: C:/Program Files/Unity/Editor/Data
|
||||
Pipe name: \\.\pipe\UnityShaderCompiler-32bit-1-8304
|
||||
Cmd: getPlatforms
|
||||
Unhandled exception: Readfile from pipe failed. GLE=The pipe has been ended.
|
||||
|
||||
|
||||
Quitting shader compiler process
|
||||
|
||||
Crashed!
|
||||
|
File diff suppressed because one or more lines are too long
@ -85,6 +85,7 @@
|
||||
<Compile Include="Assets\Scripts\Utils\Algorithms.cs" />
|
||||
<Compile Include="Assets\Scripts\Utils\Algorithms\GridTraverseAlgorithm.cs" />
|
||||
<Compile Include="Assets\Scripts\Utils\ColorHelper.cs" />
|
||||
<Compile Include="Assets\Scripts\Utils\Expression.cs" />
|
||||
<Compile Include="Assets\Scripts\Utils\Logger.cs" />
|
||||
<Compile Include="Assets\Scripts\Utils\RandomExtensions.cs" />
|
||||
<Compile Include="Assets\Scripts\Utils\Range.cs" />
|
||||
|
Loading…
Reference in New Issue
Block a user