390 lines
10 KiB
C#
390 lines
10 KiB
C#
using System;
|
|
using UnityEngine;
|
|
|
|
namespace Mtree
|
|
{
|
|
[Serializable]
|
|
public class TreeFunction
|
|
{
|
|
public static int positionOffset = 30;
|
|
|
|
public static int height = 37;
|
|
|
|
public static int width = 200;
|
|
|
|
public static int margin = -3;
|
|
|
|
public static int deleteButtonSize = 18;
|
|
|
|
public GUIStyle nodeStyle;
|
|
|
|
public GUIStyle selectedNodeStyle;
|
|
|
|
public GUIStyle deleteButtonStyle;
|
|
|
|
public int seed;
|
|
|
|
public FunctionType type;
|
|
|
|
public int id;
|
|
|
|
public int position;
|
|
|
|
public Rect rect;
|
|
|
|
public Rect deleteRect;
|
|
|
|
public int parentId;
|
|
|
|
public TreeFunction parent;
|
|
|
|
public string name;
|
|
|
|
public float TradiusMultiplier = 0.3f;
|
|
|
|
public AnimationCurve Tradius;
|
|
|
|
public float Tlength = 10f;
|
|
|
|
public int Tnumber = 1;
|
|
|
|
public float Trandomness = 0.1f;
|
|
|
|
public float ToriginAttraction = 0.1f;
|
|
|
|
public float Tresolution = 1.5f;
|
|
|
|
public AnimationCurve TrootShape;
|
|
|
|
public float TrootRadius = 0.25f;
|
|
|
|
public float TrootInnerRadius = 0.2f;
|
|
|
|
public float TrootHeight = 1f;
|
|
|
|
public float TrootResolution = 3f;
|
|
|
|
public int TflareNumber = 5;
|
|
|
|
public float TspinAmount = 0.1f;
|
|
|
|
public float TdisplacementStrength = 1f;
|
|
|
|
public float TdisplacementSize = 2.5f;
|
|
|
|
public float TheightOffset = 0.5f;
|
|
|
|
public float Glength = 10f;
|
|
|
|
public AnimationCurve GlengthCurve = AnimationCurve.Linear(0f, 1f, 1f, 0.8f);
|
|
|
|
public float Gresolution = 1f;
|
|
|
|
public float GsplitProba = 0.1f;
|
|
|
|
public float GsplitAngle = 0.5f;
|
|
|
|
public int GmaxSplits = 2;
|
|
|
|
public AnimationCurve Gradius = AnimationCurve.EaseInOut(0f, 1f, 1f, 0f);
|
|
|
|
public AnimationCurve GsplitProbaCurve = AnimationCurve.Linear(0f, 0.5f, 1f, 1f);
|
|
|
|
public float GsplitRadius = 0.8f;
|
|
|
|
public float Grandomness = 0.25f;
|
|
|
|
public float GupAttraction = 0.5f;
|
|
|
|
public float GgravityStrength = 0.1f;
|
|
|
|
public int Snumber = 25;
|
|
|
|
public float SsplitAngle = 0.5f;
|
|
|
|
public float SsplitRadius = 0.6f;
|
|
|
|
public float Sstart = 0.2f;
|
|
|
|
public float Sspread = 1f;
|
|
|
|
public float Blength = 7f;
|
|
|
|
public AnimationCurve BlengthCurve = AnimationCurve.Linear(0f, 1f, 1f, 0.8f);
|
|
|
|
public float Bresolution = 1f;
|
|
|
|
public int Bnumber = 25;
|
|
|
|
public float BsplitProba = 0.2f;
|
|
|
|
public float Bangle = 0.7f;
|
|
|
|
public float Brandomness = 0.3f;
|
|
|
|
public AnimationCurve Bshape = AnimationCurve.Linear(0f, 1f, 1f, 0f);
|
|
|
|
public AnimationCurve BsplitProbaCurve = AnimationCurve.Linear(0f, 0.5f, 1f, 1f);
|
|
|
|
public float Bradius = 0.7f;
|
|
|
|
public float BupAttraction = 0.7f;
|
|
|
|
public float Bstart = 0.2f;
|
|
|
|
public float BgravityStrength = 0.1f;
|
|
|
|
public int LleafType = 4;
|
|
|
|
public string[] LleafTypesNames = new string[7] { "cross", "diamond cross", "diamond", "long", "plane", "Procedural", "custom" };
|
|
|
|
public Mesh[] LleafMesh = new Mesh[1] { Resources.LoadAll<Mesh>("Mtree/branches")[6] };
|
|
|
|
public int Lnumber = 250;
|
|
|
|
public float LmaxRadius = 0.25f;
|
|
|
|
public float Lsize = 2f;
|
|
|
|
public bool LoverrideNormals = true;
|
|
|
|
public float LminWeight = 0.2f;
|
|
|
|
public float LmaxWeight = 0.5f;
|
|
|
|
public float Llength = 2f;
|
|
|
|
public AnimationCurve LlengthCurve = AnimationCurve.Linear(0f, 1f, 1f, 0.5f);
|
|
|
|
public int LuLoops = 2;
|
|
|
|
public float Lresolution = 1f;
|
|
|
|
public float LgravityStrength = 1f;
|
|
|
|
public bool Lprocedural;
|
|
|
|
public TreeFunction(int id, FunctionType type, TreeFunction parent)
|
|
{
|
|
UpdateStyle();
|
|
this.id = id;
|
|
this.type = type;
|
|
this.parent = parent;
|
|
parentId = ((parent != null) ? parent.id : (-1));
|
|
name = type.ToString();
|
|
position = ((parent != null) ? (parent.position + positionOffset) : 0);
|
|
seed = UnityEngine.Random.Range(0, 1000);
|
|
rect = default(Rect);
|
|
deleteRect = default(Rect);
|
|
if (type == FunctionType.Grow)
|
|
{
|
|
Keyframe[] keys = new Keyframe[2]
|
|
{
|
|
new Keyframe(0f, 1f, 0f, 0f),
|
|
new Keyframe(1f, 0f, -0.5f, -1f)
|
|
};
|
|
Gradius = new AnimationCurve(keys);
|
|
}
|
|
if (type == FunctionType.Branch && parent != null && parent.type != FunctionType.Trunk)
|
|
{
|
|
Blength = 3f;
|
|
Bstart = 0.2f;
|
|
Bangle = 0.5f;
|
|
Bnumber = 55;
|
|
Bresolution = 1f;
|
|
}
|
|
if (type == FunctionType.Trunk)
|
|
{
|
|
Keyframe[] keys2 = new Keyframe[2]
|
|
{
|
|
new Keyframe(0f, 1f, 0f, 0f),
|
|
new Keyframe(1f, 0f, -1f, -1f)
|
|
};
|
|
Tradius = new AnimationCurve(keys2);
|
|
Keyframe[] keys3 = new Keyframe[2]
|
|
{
|
|
new Keyframe(0f, 1f, -2f, -2f),
|
|
new Keyframe(1f, 0f, 0f, 0f)
|
|
};
|
|
TrootShape = new AnimationCurve(keys3);
|
|
}
|
|
}
|
|
|
|
public void Execute(MTree tree)
|
|
{
|
|
int selection = ((parent != null) ? parent.id : 0);
|
|
UnityEngine.Random.InitState(seed);
|
|
if (type == FunctionType.Trunk)
|
|
{
|
|
tree.AddTrunk(Vector3.down * TheightOffset, Vector3.up, Tlength, Tradius, TradiusMultiplier, Tresolution, Trandomness, id, TrootShape, TrootRadius, TrootHeight, TrootResolution, ToriginAttraction);
|
|
}
|
|
if (type == FunctionType.Grow)
|
|
{
|
|
tree.Grow(Glength, GlengthCurve, Gresolution, GsplitProba, GsplitProbaCurve, GsplitAngle, GmaxSplits, selection, id, Grandomness, Gradius, GsplitRadius, GupAttraction, GgravityStrength, 0f, 0.001f);
|
|
}
|
|
if (type == FunctionType.Split)
|
|
{
|
|
tree.Split(selection, Snumber, SsplitAngle, id, SsplitRadius, Sstart, Sspread, 0f);
|
|
}
|
|
if (type == FunctionType.Branch)
|
|
{
|
|
tree.AddBranches(selection, Blength, BlengthCurve, Bresolution, Bnumber, BsplitProba, BsplitProbaCurve, Bangle, Brandomness, Bshape, Bradius, BupAttraction, id, Bstart, BgravityStrength, 0f, 0.001f);
|
|
}
|
|
if (type == FunctionType.Leaf)
|
|
{
|
|
tree.AddLeafs(LmaxRadius, Lnumber, LleafMesh, Lsize, LoverrideNormals, LminWeight, LmaxWeight, selection, 70f, Lprocedural, Llength, Lresolution, LuLoops, LgravityStrength);
|
|
}
|
|
}
|
|
|
|
public void UpdateRect(int offset)
|
|
{
|
|
position = ((parent != null) ? (parent.position + positionOffset) : 0);
|
|
int num = offset * (height + margin);
|
|
rect.Set(position, num, width, height);
|
|
deleteRect.Set(position + width - 12 - deleteButtonSize, num + (height - deleteButtonSize) / 2, deleteButtonSize, deleteButtonSize);
|
|
}
|
|
|
|
public void UpdateStyle()
|
|
{
|
|
}
|
|
|
|
public void Draw(bool isSelected = false)
|
|
{
|
|
}
|
|
|
|
public void RevertOutOfBoundValues()
|
|
{
|
|
if (Bstart > 1f)
|
|
{
|
|
Bstart = 0.2f;
|
|
}
|
|
if (Sstart > 1f)
|
|
{
|
|
Sstart = 0.2f;
|
|
}
|
|
if (LmaxRadius > 1f)
|
|
{
|
|
LmaxRadius = 0.25f;
|
|
}
|
|
}
|
|
|
|
public TreeFunctionAsset ToFunctionAsset(TreeFunctionAsset parent)
|
|
{
|
|
switch (type)
|
|
{
|
|
case FunctionType.Trunk:
|
|
return ToTrunkFunction(parent);
|
|
case FunctionType.Grow:
|
|
return ToGrowFunction(parent);
|
|
case FunctionType.Split:
|
|
return ToSplitFunction(parent);
|
|
case FunctionType.Branch:
|
|
return ToBranchFunction(parent);
|
|
case FunctionType.Leaf:
|
|
return ToLeafFunction(parent);
|
|
default:
|
|
return null;
|
|
}
|
|
}
|
|
|
|
private TreeFunctionAsset ToTrunkFunction(TreeFunctionAsset parent)
|
|
{
|
|
TrunkFunction trunkFunction = ScriptableObject.CreateInstance<TrunkFunction>();
|
|
trunkFunction.Init(parent);
|
|
trunkFunction.number = Tnumber;
|
|
trunkFunction.displacementSize = TdisplacementSize;
|
|
trunkFunction.displacementStrength = TdisplacementStrength;
|
|
trunkFunction.seed = seed;
|
|
trunkFunction.flareNumber = TflareNumber;
|
|
trunkFunction.heightOffset = TheightOffset;
|
|
trunkFunction.length = Tlength;
|
|
trunkFunction.originAttraction = ToriginAttraction;
|
|
trunkFunction.radius = Tradius;
|
|
trunkFunction.radiusMultiplier = TradiusMultiplier;
|
|
trunkFunction.randomness = Trandomness;
|
|
trunkFunction.resolution = Tresolution;
|
|
trunkFunction.rootHeight = TrootHeight;
|
|
trunkFunction.rootInnerRadius = TrootInnerRadius;
|
|
trunkFunction.rootRadius = TrootRadius;
|
|
trunkFunction.rootResolution = TrootResolution;
|
|
trunkFunction.rootShape = TrootShape;
|
|
trunkFunction.spinAmount = TspinAmount;
|
|
return trunkFunction;
|
|
}
|
|
|
|
private TreeFunctionAsset ToGrowFunction(TreeFunctionAsset parent)
|
|
{
|
|
GrowFunction growFunction = ScriptableObject.CreateInstance<GrowFunction>();
|
|
growFunction.Init(parent);
|
|
growFunction.gravityStrength = GgravityStrength;
|
|
growFunction.length = Glength;
|
|
growFunction.lengthCurve = GlengthCurve;
|
|
growFunction.maxSplits = GmaxSplits;
|
|
growFunction.radius = Gradius;
|
|
growFunction.randomness = Grandomness;
|
|
growFunction.resolution = Gresolution;
|
|
growFunction.seed = seed;
|
|
growFunction.splitAngle = GsplitAngle;
|
|
growFunction.splitProba = GsplitProba;
|
|
growFunction.splitProbaCurve = GsplitProbaCurve;
|
|
growFunction.splitRadius = GsplitRadius;
|
|
growFunction.upAttraction = GupAttraction;
|
|
return growFunction;
|
|
}
|
|
|
|
private TreeFunctionAsset ToSplitFunction(TreeFunctionAsset parent)
|
|
{
|
|
SplitFunction splitFunction = ScriptableObject.CreateInstance<SplitFunction>();
|
|
splitFunction.Init(parent);
|
|
splitFunction.number = Snumber * 3;
|
|
splitFunction.seed = seed;
|
|
splitFunction.splitAngle = SsplitAngle;
|
|
splitFunction.splitRadius = SsplitRadius;
|
|
splitFunction.spread = Sspread;
|
|
splitFunction.start = Sstart;
|
|
return splitFunction;
|
|
}
|
|
|
|
private TreeFunctionAsset ToBranchFunction(TreeFunctionAsset parent)
|
|
{
|
|
BranchFunction branchFunction = ScriptableObject.CreateInstance<BranchFunction>();
|
|
branchFunction.Init(parent);
|
|
branchFunction.angle = Bangle;
|
|
branchFunction.gravityStrength = BgravityStrength;
|
|
branchFunction.length = Blength;
|
|
branchFunction.lengthCurve = BlengthCurve;
|
|
branchFunction.number = Bnumber * 3;
|
|
branchFunction.radius = Bradius;
|
|
branchFunction.randomness = Brandomness;
|
|
branchFunction.resolution = Bresolution;
|
|
branchFunction.seed = seed;
|
|
branchFunction.shape = Bshape;
|
|
branchFunction.splitProba = BsplitProba;
|
|
branchFunction.splitProbaCurve = BsplitProbaCurve;
|
|
branchFunction.start = Bstart;
|
|
branchFunction.upAttraction = BupAttraction;
|
|
return branchFunction;
|
|
}
|
|
|
|
private TreeFunctionAsset ToLeafFunction(TreeFunctionAsset parent)
|
|
{
|
|
LeafFunction leafFunction = ScriptableObject.CreateInstance<LeafFunction>();
|
|
leafFunction.Init(parent);
|
|
leafFunction.gravityStrength = LgravityStrength;
|
|
leafFunction.leafType = LleafType;
|
|
leafFunction.length = Llength;
|
|
leafFunction.lengthCurve = LlengthCurve;
|
|
leafFunction.maxRadius = LmaxRadius;
|
|
leafFunction.maxWeight = LmaxWeight;
|
|
leafFunction.minWeight = LminWeight;
|
|
leafFunction.number = Lnumber;
|
|
leafFunction.overrideNormals = LoverrideNormals;
|
|
leafFunction.resolution = Lresolution;
|
|
leafFunction.seed = seed;
|
|
leafFunction.size = Lsize;
|
|
leafFunction.uLoops = LuLoops;
|
|
return leafFunction;
|
|
}
|
|
}
|
|
}
|