projekt-modelowanie/Assets/Scripts/LeafGrow.cs

861 lines
38 KiB
C#

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Globalization;
#if UNITY_EDITOR
using UnityEditor;
using System.Linq;
public class CommentAttribute : PropertyAttribute {
public readonly string tooltip;
public readonly string comment;
public CommentAttribute( string comment, string tooltip ) {
this.tooltip = tooltip;
this.comment = comment;
}
}
[CustomPropertyDrawer(typeof(CommentAttribute))]
public class CommentDrawer : PropertyDrawer {
const int textHeight = 20;
CommentAttribute commentAttribute { get { return (CommentAttribute)attribute; } }
public override float GetPropertyHeight(SerializedProperty prop, GUIContent label) {
return textHeight;
}
public override void OnGUI(Rect position, SerializedProperty prop, GUIContent label) {
EditorGUI.LabelField(position,new GUIContent(commentAttribute.comment,commentAttribute.tooltip));
}
}
#endif
public class LeafGrow : MonoBehaviour
{
Vector3[] newVertices;
Vector2[] newUV;
int[] newTriangles;
float[] _widthCurve_; //widthCurve
float[] _foldCurve_; //foldCurve
int frame = 0;
[Header("Leaf shape")]
public float length = 0.06f;
public float width = 1.0f;
public float thickness = 0.01f;
public AnimationCurve widthCurve = AnimationCurve.Linear(0, 0, 1, 1);
public AnimationCurve foldCurve = AnimationCurve.Linear(0, 0, 1, 1);
public float infold = 0.03f;
float startInfold = 0.03f;
[Header("Animation and resolution")]
public float framesBetweenSteps = 30.0f;
public int numberOfAnimationSteps = 30;
public bool constantResolution = true;
[Comment("The number of animation steps also affects the resolution of the model", "8 * numberOfAnimationSteps = number of vertices")]
public bool commentSpace = true;
[HideInInspector]
[Range(0.000f,0.01f)]
public float simplification = 0.000f;
// EditorGUILayout.HelpBox("Number of animation steps also affects resolution of the model" , MessageType.Info);
//[Header("Special features")]
[HideInInspector]
public bool roughEdges = false;
[HideInInspector]
public int roughEdgesSize = 10;
[HideInInspector]
public int numberOfBranchesPairs = 10;
[HideInInspector]
public bool showBranches = false;
[HideInInspector]
public bool colision = false;
[HideInInspector]
public Rigidbody colisionJoint;
float infoldch;
[HideInInspector]
public int maxNumberOfSteps = 0;
int maxNumberOfStepsB = 0;
// Start is called before the first frame update
void Start() {
startInfold = infold;
if (numberOfBranchesPairs * 5 > numberOfAnimationSteps) {
numberOfBranchesPairs = numberOfAnimationSteps / 10;
}
// _widthCurve_ = new float[] {0.0f, 0.25f, 0.5f, 0.55f, 0.54f, 0.53f, 0.52f, 0.50f, 0.48f, 0.45f, 0.41f, 0.36f, 0.31f, 0.26f, 0.21f, 0.16f, 0.11f, 0.06f, 0.03f, 0.0f};
// _foldCurve_ = new float[] {0.0f, 0.02f, 0.03f, 0.035f, 0.04f, 0.04f, 0.037f, 0.035f, 0.031f, 0.027f, 0.024f, 0.021f, 0.019f, 0.016f, 0.013f, 0.010f, 0.007f, 0.004f, 0.001f, 0.0f};
float numberOfAnimationStepsf = (float)numberOfAnimationSteps;
_widthCurve_ = new float[numberOfAnimationSteps + 1];
_foldCurve_ = new float[numberOfAnimationSteps + 1];
float i = 0;
for (i = 0; i < numberOfAnimationStepsf; i += 1.0f) {
_widthCurve_[(int)i] = (float)widthCurve.Evaluate(i / (numberOfAnimationStepsf));
_foldCurve_[(int)i] = (float)foldCurve.Evaluate(i / (numberOfAnimationStepsf));
}
float foldMin = _foldCurve_.Min();
float widthMin = _widthCurve_.Min();
float widthMax = _widthCurve_.Max();
for (i = 0; i < numberOfAnimationStepsf; i += 1.0f) {
_widthCurve_[(int)i] = (_widthCurve_[(int)i] - widthMin) / (widthMax - widthMin);
_foldCurve_[(int)i] = (_foldCurve_[(int)i]- _foldCurve_[0])*length;
}
if (maxNumberOfSteps == 0.0) {
maxNumberOfStepsB = _widthCurve_.Length - 1;
}
else {
maxNumberOfStepsB = maxNumberOfSteps;
}
maxNumberOfSteps = _widthCurve_.Length - 1;
// }
}
// Update is called once per frame
void Update() {
frame += 1;
if (frame <= framesBetweenSteps * maxNumberOfSteps) {
UpdateLeafMesh();
}
if (frame == framesBetweenSteps * maxNumberOfSteps + 3 && colision) {
gameObject.GetComponent<MeshCollider>().sharedMesh = null;
}
}
public void DrawLeaf() {
Start();
frame = (int)(framesBetweenSteps * maxNumberOfSteps);
UpdateLeafMesh();
infold = startInfold;
}
void UpdateLeafMesh() {
float frameScaled = (float)frame / framesBetweenSteps;
float[] _widthCurve = new float[(int)frameScaled + 1];
float[] _foldCurve = new float[(int)frameScaled + 1];
if (constantResolution) {
_widthCurve = new float[_widthCurve_.Length];
_foldCurve = new float[_foldCurve_.Length];
}
float scale = frameScaled / (float)maxNumberOfSteps;
float scaleB = frameScaled / (float)maxNumberOfStepsB;
int j = 0;
for (j = 0; j < frameScaled; j++) {
_widthCurve[j] = _widthCurve_[(int)((float)j / scale)] * scaleB;
_foldCurve[j] = _foldCurve_[(int)((float)j / scale)] * scaleB;
}
if (frame == framesBetweenSteps * maxNumberOfSteps || constantResolution) {
if (frame == framesBetweenSteps * maxNumberOfSteps) {
scaleB = (frameScaled - 1.0f) / (float)maxNumberOfStepsB;
}
for (j = 0; j < _widthCurve_.Length; j++) {
_widthCurve[j] = _widthCurve_[j] * scaleB;
}
for (j = 0; j < _foldCurve_.Length; j++) {
_foldCurve[j] = _foldCurve_[j] * scaleB;
}
// _widthCurve = _widthCurve_;
// _foldCurve = _foldCurve_;
// scaleB = 1.0f;
infold = startInfold;
}
else {
infold = (_widthCurve_[(int)frameScaled] / 10.0f) + startInfold;
}
infoldch = 2.0f * infold / _widthCurve.Length;
float infoldFrame = infold;
if (constantResolution) {
float scaleLboost = 1.0f;
if (frameScaled * 3.0f < numberOfAnimationSteps) {
scaleLboost = frameScaled * 3.0f / numberOfAnimationSteps;
}
scaleL = (scaleLboost + scaleB) / 2.0f;
}
if (showBranches) {
branchesMargin = (int)((float)numberOfAnimationSteps * 0.15f);
branchesDistance = 0;
if (numberOfBranchesPairs > 0) {
branchesDistance = (numberOfAnimationSteps - (branchesMargin * 2)) / numberOfBranchesPairs;
}
}
// // float version (constant distance between vertices groups)
// Mesh mesh = createSweepSufraceMesh(lengthScale, infold, _widthCurve, _foldCurve);
// GetComponent<MeshFilter>().mesh = mesh;
//
// Vector2 version (distance between vertices groups can be defined (last parameter is Vector2 x=fold, y=distance from start (lenght of leaf from the begining to this point)))
CurvesContainer newSimpleCurves = simplifyCurves(_widthCurve, _foldCurve, simplification);
Mesh mesh = createSweepSufraceMeshVector(length, width, newSimpleCurves._widthCurve, newSimpleCurves._foldCurve);
GetComponent<MeshFilter>().mesh = mesh;
if (frame == framesBetweenSteps * maxNumberOfSteps && colision) {
gameObject.AddComponent<Rigidbody>();
gameObject.GetComponent<Rigidbody>().useGravity = false;
gameObject.AddComponent<SpringJoint>();
gameObject.GetComponent<SpringJoint>().connectedBody = colisionJoint;
// gameObject.GetComponent<Rigidbody>().isKinematic = true;
gameObject.AddComponent<MeshCollider>();
gameObject.GetComponent<MeshCollider>().convex = true;
gameObject.GetComponent<MeshCollider>().sharedMesh = mesh;
}
}
int branchesMargin = 0;
int branchesDistance = 0;
float scaleL = 1.0f;
Mesh createSweepSufraceMesh(float length, float width, float[] _widthCurve, float[] _foldCurve)//Vector2[] foldCurve)
{
Mesh mesh = new Mesh();
int j = 0;
Vector3[] newVertices = new Vector3[_widthCurve.Length * 6];
Vector3[] newnormals = new Vector3[_widthCurve.Length * 6];
float i = 0.0f;
float re = 0.0f;
int al = _widthCurve.Length * 3;
for (i = 0.0f; i < _widthCurve.Length; i++) {
float thicknessThisRow = thickness;
infold = (float)gauss(((double)i) / ((_widthCurve.Length)), 0.5, 0.0, 1.0) * startInfold;
if (i == _widthCurve.Length - 1) {
infold = 0;
thicknessThisRow = 0.0001f;
_widthCurve[(int)i] = 0.00001f;
Debug.Log("last Frame");
}
Debug.Log("#infold = " + infold);
if (roughEdges && i > roughEdgesSize * 4.0f) {
re = 0.005f * (float)(i % roughEdgesSize);
if (re > _widthCurve[(int)i] / 4.0f) {
re = _widthCurve[(int)i] / 4.0f;
}
}
else {
re = 0.0f;
}
// ------- downside of the leaf --------
Vector3 newVer = new Vector3((length / numberOfAnimationSteps) * i * scaleL, _widthCurve[(int)i] * width + re, _foldCurve[(int)i] - infold * (0.3f + _widthCurve[(int)i]));
newVertices[(int)i * 3 + 0] = newVer;
newnormals[(int)i * 3 + 0] = new Vector3(0, 0, 1);
newVer = new Vector3((length / numberOfAnimationSteps) * i * scaleL, 0.0f, _foldCurve[(int)i] + thicknessThisRow);
newVertices[(int)i * 3 + 1] = newVer;
newnormals[(int)i * 3 + 1] = new Vector3(0, 0, 1);
newVer = new Vector3((length / numberOfAnimationSteps) * i * scaleL, -1.0f * _widthCurve[(int)i] * width + re, _foldCurve[(int)i] - infold * (0.3f + _widthCurve[(int)i]));
newVertices[(int)i * 3 + 2] = newVer;
newnormals[(int)i * 3 + 2] = new Vector3(0, 0, 1);
// ------- upside of the leaf --------
newVer = new Vector3((length / numberOfAnimationSteps) * i * scaleL, _widthCurve[(int)i] * width + re, _foldCurve[(int)i] - infold * (0.3f + _widthCurve[(int)i]));
newVertices[(int)i * 3 + 0 + al] = newVer;
newnormals[(int)i * 3 + 0 + al] = new Vector3(0, 0, -1);
newVer = new Vector3((length / numberOfAnimationSteps) * i * scaleL, 0.0f, _foldCurve[(int)i]);
newVertices[(int)i * 3 + 1 + al] = newVer;
newnormals[(int)i * 3 + 1 + al] = new Vector3(0, 0, -1);
newVer = new Vector3((length / numberOfAnimationSteps) * i * scaleL, -1.0f * _widthCurve[(int)i] * width + re, _foldCurve[(int)i] - infold * (0.3f + _widthCurve[(int)i]));
newVertices[(int)i * 3 + 2 + al] = newVer;
newnormals[(int)i * 3 + 2 + al] = new Vector3(0, 0, -1);
// newVer = new Vector3((length/numberOfAnimationSteps)*i*scaleL, 0.0f, _foldCurve[(int)i]);
// newVertices[(int)i + al] = newVer;
// newnormals[(int)i + al] = new Vector3(0, 0, -1);
}
if (branchesDistance == 0 || !showBranches) {
newTriangles = new int[(_widthCurve.Length - 1) * (24 * 2)];
}
else {
newTriangles = new int[(_widthCurve.Length - 1) * (24 * 2) + 24 * ((_widthCurve.Length / branchesDistance))];
}
int ti = 0;
for (j = 1; j < _widthCurve.Length; j++) {
int k = j - 1;
if (showBranches || j != _widthCurve.Length - 1) {
// ------- downside of the leaf --------
newTriangles[ti++] = k * 3 + 1;
newTriangles[ti++] = k * 3;
newTriangles[ti++] = j * 3;
newTriangles[ti++] = k * 3 + 1;
newTriangles[ti++] = j * 3;
newTriangles[ti++] = j * 3 + 1;
newTriangles[ti++] = k * 3 + 1;
newTriangles[ti++] = j * 3 + 2;
newTriangles[ti++] = k * 3 + 2;
newTriangles[ti++] = k * 3 + 1;
newTriangles[ti++] = j * 3 + 1;
newTriangles[ti++] = j * 3 + 2;
// ------- upside of the leaf --------
newTriangles[ti++] = k * 3 + 1 + al;
newTriangles[ti++] = j * 3 + 0 + al;
newTriangles[ti++] = k * 3 + 0 + al;
newTriangles[ti++] = k * 3 + 1 + al;
newTriangles[ti++] = j * 3 + 1 + al;
newTriangles[ti++] = j * 3 + 0 + al;
newTriangles[ti++] = k * 3 + 1 + al;
newTriangles[ti++] = k * 3 + 2 + al;
newTriangles[ti++] = j * 3 + 2 + al;
newTriangles[ti++] = k * 3 + 1 + al;
newTriangles[ti++] = j * 3 + 2 + al;
newTriangles[ti++] = j * 3 + 1 + al;
// newTriangles[ti++] = k * 3;
// newTriangles[ti++] = k + al;
// newTriangles[ti++] = j * 3;
//
// newTriangles[ti++] = j * 3;
// newTriangles[ti++] = k + al;
// newTriangles[ti++] = j + al;
//
//
// newTriangles[ti++] = k * 3 + 2;
// newTriangles[ti++] = j * 3 + 2;
// newTriangles[ti++] = k + al;
//
//
// newTriangles[ti++] = j + al;
// newTriangles[ti++] = k + al;
// newTriangles[ti++] = j * 3 + 2;
}
}
int abr = _widthCurve.Length * 4;
float mz = 0.0f;
Vector2[] newUV = new Vector2[newVertices.Length];
for (j = 0; j < newUV.Length; j++) {
if (j < abr) {
newUV[j] = new Vector2(newVertices[j].x, newVertices[j].z);
if (mz < newVertices[j].z) {
mz = newVertices[j].z;
}
}
else {
newUV[j] = new Vector2(newVertices[j].x, newVertices[j].z + mz);
}
}
mesh.vertices = newVertices;
// mesh.uv = newUV;
mesh.triangles = newTriangles;
mesh.RecalculateBounds();
mesh.triangles = mesh.triangles.Reverse().ToArray();
mesh.normals = newnormals;
mesh.RecalculateNormals();
if (showBranches) {
// newTriangles = newTriangles.Reverse().ToArray();
for (i = 0.0f; i < _widthCurve.Length; i++) {
float branchThickness = 1.2f * thickness;
if (_widthCurve[(int)i] / 10.0f < branchThickness) {
branchThickness = _widthCurve[(int)i] / 10.0f;
}
Vector3 newVer = new Vector3((length / numberOfAnimationSteps) * i * scaleL, 0.0f, _foldCurve[(int)i] + (branchThickness));
newVertices[(int)i * 4 + 0 + abr] = newVer;
newVer = new Vector3((length / numberOfAnimationSteps) * i * scaleL, 0.0f, _foldCurve[(int)i] - (branchThickness));
newVertices[(int)i * 4 + 1 + abr] = newVer;
newVer = new Vector3((length / numberOfAnimationSteps) * i * scaleL, branchThickness, _foldCurve[(int)i]);
newVertices[(int)i * 4 + 2 + abr] = newVer;
newVer = new Vector3((length / numberOfAnimationSteps) * i * scaleL, -branchThickness, _foldCurve[(int)i]);
newVertices[(int)i * 4 + 3 + abr] = newVer;
Debug.Log("#_foldCurve[(int)i]=" + _foldCurve[(int)i]);
}
for (j = 1; j < _widthCurve.Length; j++) {
int k = j - 1;
// prawa i lewa patrząc od góry ODWRÓCONE
newTriangles[ti++] = k * 4 + 0 + abr;//góra prawa i 2 na dole
newTriangles[ti++] = k * 4 + 2 + abr;
newTriangles[ti++] = j * 4 + 2 + abr;
newTriangles[ti++] = j * 4 + 2 + abr;//góra prawa i 2 u góry
newTriangles[ti++] = j * 4 + 0 + abr;
newTriangles[ti++] = k * 4 + 0 + abr;
//
newTriangles[ti++] = k * 4 + 3 + abr;//góra lewa i 2 na dole
newTriangles[ti++] = k * 4 + 0 + abr;
newTriangles[ti++] = j * 4 + 0 + abr;
newTriangles[ti++] = j * 4 + 3 + abr;//góra lewa i 2 u góry
newTriangles[ti++] = k * 4 + 3 + abr;
newTriangles[ti++] = j * 4 + 0 + abr;
//
newTriangles[ti++] = j * 4 + 3 + abr;//dół lewa i 2 na dole
newTriangles[ti++] = k * 4 + 1 + abr;
newTriangles[ti++] = k * 4 + 3 + abr;
//
newTriangles[ti++] = j * 4 + 3 + abr;//dół lewa i 2 u góry
newTriangles[ti++] = j * 4 + 1 + abr;
newTriangles[ti++] = k * 4 + 1 + abr;
//
newTriangles[ti++] = j * 4 + 1 + abr;//dół prawa i 2 na dole
newTriangles[ti++] = k * 4 + 2 + abr;
newTriangles[ti++] = k * 4 + 1 + abr;
//
newTriangles[ti++] = j * 4 + 2 + abr;//dół prawa i 2 u góry
newTriangles[ti++] = k * 4 + 2 + abr;
newTriangles[ti++] = j * 4 + 1 + abr;
//// prawa i lewa patrząc od góry
//
// newTriangles[ti++] = k * 4 + 0 + abr;//góra prawa i 2 na dole
// newTriangles[ti++] = j * 4 + 0 + abr;
// newTriangles[ti++] = k * 4 + 3 + abr;
//
// newTriangles[ti++] = j * 4 + 3 + abr;//góra lewa i 2 u góry
// newTriangles[ti++] = j * 4 + 0 + abr;
// newTriangles[ti++] = k * 4 + 0 + abr;
////
// newTriangles[ti++] = k * 4 + 3 + abr;//góra lewa i 2 na dole
// newTriangles[ti++] = j * 4 + 0 + abr;
// newTriangles[ti++] = k * 4 + 0 + abr;
//
// newTriangles[ti++] = j * 4 + 3 + abr;//góra prawa i 2 u góry
// newTriangles[ti++] = j * 4 + 0 + abr;
// newTriangles[ti++] = k * 4 + 3 + abr;
////
////
// newTriangles[ti++] = j * 4 + 3 + abr;//dół lewa i 2 na dole
// newTriangles[ti++] = k * 4 + 3 + abr;
// newTriangles[ti++] = k * 4 + 1 + abr;
////
////
// newTriangles[ti++] = j * 4 + 3 + abr;//dół lewa i 2 u góry
// newTriangles[ti++] = k * 4 + 1 + abr;
// newTriangles[ti++] = j * 4 + 1 + abr;
////
// newTriangles[ti++] = j * 4 + 1 + abr;//dół prawa i 2 na dole
// newTriangles[ti++] = k * 4 + 1 + abr;
// newTriangles[ti++] = k * 4 + 2 + abr;
////
// newTriangles[ti++] = j * 4 + 2 + abr;//dół prawa i 2 u góry
// newTriangles[ti++] = j * 4 + 1 + abr;
// newTriangles[ti++] = k * 4 + 2 + abr;
if (branchesDistance > 2) {
if (j % branchesDistance == 0 && j + branchesMargin < _widthCurve.Length && _widthCurve.Length > 2 * branchesMargin) {
newTriangles[ti++] = k * 4 + 1 + abr;
newTriangles[ti++] = k * 4 + 2 + abr;
newTriangles[ti++] = j * 3 + 2 + branchesMargin * 3;
newTriangles[ti++] = k * 4 + 1 + abr;
newTriangles[ti++] = k * 4 + 2 + abr;
newTriangles[ti++] = j * 3 + 0 + branchesMargin * 3;
newTriangles[ti++] = k * 4 + 0 + abr;
newTriangles[ti++] = k * 4 + 2 + abr;
newTriangles[ti++] = j * 3 + 2 + branchesMargin * 3;
newTriangles[ti++] = k * 4 + 0 + abr;
newTriangles[ti++] = k * 4 + 3 + abr;
newTriangles[ti++] = j * 3 + 0 + branchesMargin * 3;
newTriangles[ti++] = k * 4 + 1 + abr;
newTriangles[ti++] = k * 4 + 3 + abr;
newTriangles[ti++] = j * 3 + 2 + branchesMargin * 3;
newTriangles[ti++] = k * 4 + 1 + abr;
newTriangles[ti++] = k * 4 + 3 + abr;
newTriangles[ti++] = j * 3 + 0 + branchesMargin * 3;
newTriangles[ti++] = k * 4 + 0 + abr;
newTriangles[ti++] = k * 4 + 3 + abr;
newTriangles[ti++] = j * 3 + 2 + branchesMargin * 3;
newTriangles[ti++] = k * 4 + 0 + abr;
newTriangles[ti++] = k * 4 + 3 + abr;
newTriangles[ti++] = j * 3 + 0 + branchesMargin * 3;
}
}
}
mesh.vertices = newVertices;
// mesh.uv = newUV;
mesh.triangles = newTriangles;
mesh.triangles = mesh.triangles.Reverse().ToArray();
}
newUV = new Vector2[newVertices.Length];
mz = 0.0f;
for (j = 0; j < newUV.Length; j++) {
// if(j<abr)
// {
newUV[j] = new Vector2(newVertices[j].x, newVertices[j].y);
// }
// else
// {
// newUV[j] = new Vector2(newVertices[j].x, newVertices[j].z+mz);
// }
}
Color[] colors = new Color[newVertices.Length];
for (j = 0; j < newVertices.Length; j++)
colors[j] = new Color(0.0f, 0.26f, 0.0f);
mesh.colors = colors;
mesh.RecalculateBounds();
// mesh.RecalculateNormals();
mesh.uv = newUV;
return mesh;
}
Mesh createSweepSufraceMeshVector(float length, float width, float[] _widthCurve, Vector2[] _foldCurve) {
Mesh mesh = new Mesh();
int j = 0;
Vector3[] newVertices = new Vector3[_widthCurve.Length * 6];
Vector3[] newnormals = new Vector3[_widthCurve.Length * 6];
float i = 0.0f;
float re = 0.0f;
int al = _widthCurve.Length * 3;
for (i = 0.0f; i < _widthCurve.Length; i++) {
float thicknessThisRow = thickness;
infold = (float)gauss(((double)i) / ((_widthCurve.Length)), 0.5, 0.0, 1.0) * startInfold;
if (i > _widthCurve.Length - 3) {
infold = 0;
thicknessThisRow = 0.0001f;
_widthCurve[(int)i] = 0.00001f;
Debug.Log("last Frame");
}
Debug.Log("#infold = " + infold);
if (roughEdges && i > roughEdgesSize * 4.0f) {
re = 0.005f * (float)(i % roughEdgesSize);
if (re > _widthCurve[(int)i] / 4.0f) {
re = _widthCurve[(int)i] / 4.0f;
}
}
else {
re = 0.0f;
}
// ------- downside of the leaf --------
Vector3 newVer = new Vector3((length / numberOfAnimationSteps) * scaleL * _foldCurve[(int)i].y, _widthCurve[(int)i] * width + re, _foldCurve[(int)i].x - infold * (0.3f + _widthCurve[(int)i]));
newVertices[(int)i * 3 + 0] = newVer;
newnormals[(int)i * 3 + 0] = new Vector3(0, 0, 1);
newVer = new Vector3((length / numberOfAnimationSteps) * scaleL * _foldCurve[(int)i].y, 0.0f, _foldCurve[(int)i].x + thicknessThisRow);
newVertices[(int)i * 3 + 1] = newVer;
newnormals[(int)i * 3 + 1] = new Vector3(0, 0, 1);
newVer = new Vector3((length / numberOfAnimationSteps) * scaleL * _foldCurve[(int)i].y, -1.0f * _widthCurve[(int)i] * width + re, _foldCurve[(int)i].x - infold * (0.3f + _widthCurve[(int)i]));
newVertices[(int)i * 3 + 2] = newVer;
newnormals[(int)i * 3 + 2] = new Vector3(0, 0, 1);
// ------- upside of the leaf --------
newVer = new Vector3((length / numberOfAnimationSteps) * scaleL * _foldCurve[(int)i].y, _widthCurve[(int)i] * width + re, _foldCurve[(int)i].x - infold * (0.3f + _widthCurve[(int)i]));
newVertices[(int)i * 3 + 0 + al] = newVer;
newnormals[(int)i * 3 + 0 + al] = new Vector3(0, 0, -1);
newVer = new Vector3((length / numberOfAnimationSteps) * scaleL * _foldCurve[(int)i].y, 0.0f, _foldCurve[(int)i].x);
newVertices[(int)i * 3 + 1 + al] = newVer;
newnormals[(int)i * 3 + 1 + al] = new Vector3(0, 0, -1);
newVer = new Vector3((length / numberOfAnimationSteps) * scaleL * _foldCurve[(int)i].y, -1.0f * _widthCurve[(int)i] * width + re, _foldCurve[(int)i].x - infold * (0.3f + _widthCurve[(int)i]));
newVertices[(int)i * 3 + 2 + al] = newVer;
newnormals[(int)i * 3 + 2 + al] = new Vector3(0, 0, -1);
}
if (branchesDistance == 0 || !showBranches) {
newTriangles = new int[(_widthCurve.Length - 1) * (24 * 2)];
}
else {
newTriangles = new int[(_widthCurve.Length - 1) * (24 * 2) + 24 * ((_widthCurve.Length / branchesDistance))];
}
int ti = 0;
for (j = 1; j < _widthCurve.Length; j++) {
int k = j - 1;
if (showBranches || j != _widthCurve.Length - 1) {
// ------- downside of the leaf --------
newTriangles[ti++] = k * 3 + 1;
newTriangles[ti++] = k * 3;
newTriangles[ti++] = j * 3;
newTriangles[ti++] = k * 3 + 1;
newTriangles[ti++] = j * 3;
newTriangles[ti++] = j * 3 + 1;
newTriangles[ti++] = k * 3 + 1;
newTriangles[ti++] = j * 3 + 2;
newTriangles[ti++] = k * 3 + 2;
newTriangles[ti++] = k * 3 + 1;
newTriangles[ti++] = j * 3 + 1;
newTriangles[ti++] = j * 3 + 2;
// ------- upside of the leaf --------
newTriangles[ti++] = k * 3 + 1 + al;
newTriangles[ti++] = j * 3 + 0 + al;
newTriangles[ti++] = k * 3 + 0 + al;
newTriangles[ti++] = k * 3 + 1 + al;
newTriangles[ti++] = j * 3 + 1 + al;
newTriangles[ti++] = j * 3 + 0 + al;
newTriangles[ti++] = k * 3 + 1 + al;
newTriangles[ti++] = k * 3 + 2 + al;
newTriangles[ti++] = j * 3 + 2 + al;
newTriangles[ti++] = k * 3 + 1 + al;
newTriangles[ti++] = j * 3 + 2 + al;
newTriangles[ti++] = j * 3 + 1 + al;
}
}
int abr = _widthCurve.Length * 4;
float mz = 0.0f;
Vector2[] newUV = new Vector2[newVertices.Length];
for (j = 0; j < newUV.Length; j++) {
if (j < abr) {
newUV[j] = new Vector2(newVertices[j].x, newVertices[j].z);
if (mz < newVertices[j].z) {
mz = newVertices[j].z;
}
}
else {
newUV[j] = new Vector2(newVertices[j].x, newVertices[j].z + mz);
}
}
mesh.vertices = newVertices;
// mesh.uv = newUV;
mesh.triangles = newTriangles;
mesh.RecalculateBounds();
mesh.triangles = mesh.triangles.Reverse().ToArray();
mesh.normals = newnormals;
mesh.RecalculateNormals();
if (showBranches) {
// newTriangles = newTriangles.Reverse().ToArray();
for (i = 0.0f; i < _widthCurve.Length; i++) {
float branchThickness = 1.2f * thickness;
if (_widthCurve[(int)i] / 10.0f < branchThickness) {
branchThickness = _widthCurve[(int)i] / 10.0f;
}
Vector3 newVer = new Vector3((length / numberOfAnimationSteps) * scaleL * _foldCurve[(int)i].y, 0.0f, _foldCurve[(int)i].x + (branchThickness));
newVertices[(int)i * 4 + 0 + abr] = newVer;
newVer = new Vector3((length / numberOfAnimationSteps) * scaleL * _foldCurve[(int)i].y, 0.0f, _foldCurve[(int)i].x - (branchThickness));
newVertices[(int)i * 4 + 1 + abr] = newVer;
newVer = new Vector3((length / numberOfAnimationSteps) * scaleL * _foldCurve[(int)i].y, branchThickness, _foldCurve[(int)i].x);
newVertices[(int)i * 4 + 2 + abr] = newVer;
newVer = new Vector3((length / numberOfAnimationSteps) * scaleL * _foldCurve[(int)i].y, -branchThickness, _foldCurve[(int)i].x);
newVertices[(int)i * 4 + 3 + abr] = newVer;
Debug.Log("#_foldCurve[(int)i]=" + _foldCurve[(int)i]);
}
for (j = 1; j < _widthCurve.Length; j++) {
int k = j - 1;
// prawa i lewa patrząc od góry ODWRÓCONE
newTriangles[ti++] = k * 4 + 0 + abr;//góra prawa i 2 na dole
newTriangles[ti++] = k * 4 + 2 + abr;
newTriangles[ti++] = j * 4 + 2 + abr;
newTriangles[ti++] = j * 4 + 2 + abr;//góra prawa i 2 u góry
newTriangles[ti++] = j * 4 + 0 + abr;
newTriangles[ti++] = k * 4 + 0 + abr;
//
newTriangles[ti++] = k * 4 + 3 + abr;//góra lewa i 2 na dole
newTriangles[ti++] = k * 4 + 0 + abr;
newTriangles[ti++] = j * 4 + 0 + abr;
newTriangles[ti++] = j * 4 + 3 + abr;//góra lewa i 2 u góry
newTriangles[ti++] = k * 4 + 3 + abr;
newTriangles[ti++] = j * 4 + 0 + abr;
//
newTriangles[ti++] = j * 4 + 3 + abr;//dół lewa i 2 na dole
newTriangles[ti++] = k * 4 + 1 + abr;
newTriangles[ti++] = k * 4 + 3 + abr;
//
newTriangles[ti++] = j * 4 + 3 + abr;//dół lewa i 2 u góry
newTriangles[ti++] = j * 4 + 1 + abr;
newTriangles[ti++] = k * 4 + 1 + abr;
//
newTriangles[ti++] = j * 4 + 1 + abr;//dół prawa i 2 na dole
newTriangles[ti++] = k * 4 + 2 + abr;
newTriangles[ti++] = k * 4 + 1 + abr;
//
newTriangles[ti++] = j * 4 + 2 + abr;//dół prawa i 2 u góry
newTriangles[ti++] = k * 4 + 2 + abr;
newTriangles[ti++] = j * 4 + 1 + abr;
//// prawa i lewa patrząc od góry
//
// newTriangles[ti++] = k * 4 + 0 + abr;//góra prawa i 2 na dole
// newTriangles[ti++] = j * 4 + 0 + abr;
// newTriangles[ti++] = k * 4 + 3 + abr;
//
// newTriangles[ti++] = j * 4 + 3 + abr;//góra lewa i 2 u góry
// newTriangles[ti++] = j * 4 + 0 + abr;
// newTriangles[ti++] = k * 4 + 0 + abr;
////
// newTriangles[ti++] = k * 4 + 3 + abr;//góra lewa i 2 na dole
// newTriangles[ti++] = j * 4 + 0 + abr;
// newTriangles[ti++] = k * 4 + 0 + abr;
//
// newTriangles[ti++] = j * 4 + 3 + abr;//góra prawa i 2 u góry
// newTriangles[ti++] = j * 4 + 0 + abr;
// newTriangles[ti++] = k * 4 + 3 + abr;
////
////
// newTriangles[ti++] = j * 4 + 3 + abr;//dół lewa i 2 na dole
// newTriangles[ti++] = k * 4 + 3 + abr;
// newTriangles[ti++] = k * 4 + 1 + abr;
////
////
// newTriangles[ti++] = j * 4 + 3 + abr;//dół lewa i 2 u góry
// newTriangles[ti++] = k * 4 + 1 + abr;
// newTriangles[ti++] = j * 4 + 1 + abr;
////
// newTriangles[ti++] = j * 4 + 1 + abr;//dół prawa i 2 na dole
// newTriangles[ti++] = k * 4 + 1 + abr;
// newTriangles[ti++] = k * 4 + 2 + abr;
////
// newTriangles[ti++] = j * 4 + 2 + abr;//dół prawa i 2 u góry
// newTriangles[ti++] = j * 4 + 1 + abr;
// newTriangles[ti++] = k * 4 + 2 + abr;
if (branchesDistance > 2) {
if (j % branchesDistance == 0 && j + branchesMargin < _widthCurve.Length && _widthCurve.Length > 2 * branchesMargin) {
newTriangles[ti++] = k * 4 + 1 + abr;
newTriangles[ti++] = k * 4 + 2 + abr;
newTriangles[ti++] = j * 3 + 2 + branchesMargin * 3;
newTriangles[ti++] = k * 4 + 1 + abr;
newTriangles[ti++] = k * 4 + 2 + abr;
newTriangles[ti++] = j * 3 + 0 + branchesMargin * 3;
newTriangles[ti++] = k * 4 + 0 + abr;
newTriangles[ti++] = k * 4 + 2 + abr;
newTriangles[ti++] = j * 3 + 2 + branchesMargin * 3;
newTriangles[ti++] = k * 4 + 0 + abr;
newTriangles[ti++] = k * 4 + 3 + abr;
newTriangles[ti++] = j * 3 + 0 + branchesMargin * 3;
newTriangles[ti++] = k * 4 + 1 + abr;
newTriangles[ti++] = k * 4 + 3 + abr;
newTriangles[ti++] = j * 3 + 2 + branchesMargin * 3;
newTriangles[ti++] = k * 4 + 1 + abr;
newTriangles[ti++] = k * 4 + 3 + abr;
newTriangles[ti++] = j * 3 + 0 + branchesMargin * 3;
newTriangles[ti++] = k * 4 + 0 + abr;
newTriangles[ti++] = k * 4 + 3 + abr;
newTriangles[ti++] = j * 3 + 2 + branchesMargin * 3;
newTriangles[ti++] = k * 4 + 0 + abr;
newTriangles[ti++] = k * 4 + 3 + abr;
newTriangles[ti++] = j * 3 + 0 + branchesMargin * 3;
}
}
}
mesh.vertices = newVertices;
// mesh.uv = newUV;
mesh.triangles = newTriangles;
mesh.triangles = mesh.triangles.Reverse().ToArray();
}
newUV = new Vector2[newVertices.Length];
mz = 0.0f;
for (j = 0; j < newUV.Length; j++) {
// if(j<abr)
// {
newUV[j] = new Vector2(newVertices[j].x, newVertices[j].y);
// }
// else
// {
// newUV[j] = new Vector2(newVertices[j].x, newVertices[j].z+mz);
// }
}
Color[] colors = new Color[newVertices.Length];
for (j = 0; j < newVertices.Length; j++)
colors[j] = new Color(0.0f, 0.26f, 0.0f);
mesh.colors = colors;
mesh.RecalculateBounds();
// mesh.RecalculateNormals();
mesh.uv = newUV;
Debug.Log("#vert " + mesh.vertices.Length);
Debug.Log("#tris " + (newTriangles.Length / 3));
return mesh;
}
double gauss(double x, double a, double b, double c)//b = 0, a=0.5, c = 1
{
var v1 = (x - b);
var v2 = (v1 * v1) / (2 * (c * c));
var v3 = a * (double)Mathf.Exp((float)-v2);
return v3;
}
struct CurvesContainer {
public CurvesContainer(float[] x, Vector2[] y) {
_widthCurve = x;
_foldCurve = y;
}
public float[] _widthCurve;
public Vector2[] _foldCurve;
}
private CurvesContainer simplifyCurves(float[] _widthCurve, float[] _foldCurve, float simplification) {
Vector2[] _foldCurveVectorFull = new Vector2[_foldCurve.Length];
float[] _widthCurveNewFull = new float[_foldCurve.Length];
int j = 0;
for (int i = 0; i < _foldCurve.Length; i++) {
if (i > 1 && i < _foldCurve.Length - 2) {
if (Mathf.Abs((_widthCurve[i + 1] - _widthCurve[i]) - (_widthCurve[i] - _widthCurve[i - 1])) < simplification) {
continue;
}
}
_foldCurveVectorFull[j] = new Vector2(_foldCurve[i], i);
_widthCurveNewFull[j++] = _widthCurve[i];
}
Vector2[] _foldCurveVector = new Vector2[j];
float[] _widthCurveNew = new float[j];
for (int i = 0; i < j; i++) {
_foldCurveVector[i] = _foldCurveVectorFull[i];
_widthCurveNew[i] = _widthCurveNewFull[i];
}
return new CurvesContainer(_widthCurveNew, _foldCurveVector);
}
}