projekt-modelowanie/Assets/Scripts/LeafGrowScript.cs

338 lines
14 KiB
C#

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class LeafGrowScript : MonoBehaviour
{
public GameObject parent;
public GameObject materialSettings;
[Header("Leaf shape")]
public Vector2[] widthCurveKeyPoints = {new Vector2(0.0f, 0.0f), new Vector2(0.5f, 1.0f), new Vector2(1.0f, 0.0f)};
public Vector2[] foldCurveKeyPoints = {new Vector2(0.0f, 0.0f), new Vector2(0.5f, 1.0f), new Vector2(1.0f, 0.0f)};
public float lengthScale = 0.06f;
public float thickness = 0.01f;
public float infold = 0.03f;
[Header("Animation and resolution")]
public float framesBetweenSteps = 2.0f;
public int numberOfAnimationSteps = 30;
[Comment("The number of animation steps also affects the resolution of the model", "8 * numberOfAnimationSteps = number of vertices")]
public bool commentSpace = true;
// EditorGUILayout.HelpBox("Number of animation steps also affects resolution of the model" , MessageType.Info);
[Header("Special features")]
public bool roughEdges = false;
public int roughEdgesSize = 10;
public int numberOfBranchesPairs = 10;
public bool showBranches = false;
public bool colision = false;
public Rigidbody colisionJoint;
[Header("Position")]
public float positionX = 0.0f;
public float positionY = 0.0f;
public float positionZ = 0.0f;
[Header("Rotation")]
public float rotationX = 0.0f;
public float rotationY = 0.0f;
public float rotationZ = 0.0f;
[Header("Copies of leaf")]
public int numberOfCopies = 0;
public float positionXMove = 0.0f;
public float positionYMove = 0.0f;
public float positionZMove = 0.0f;
public float rotationXChange = 0.0f;
public float rotationYChange = 0.0f;
public float rotationZChange = 0.0f;
public int animationStepsChange = -1;
[Comment("Decrease the number of animation steps with each copy", "AnimationStepsLimit")]
public bool commentSpaceB = true;
public int animationFrameDelay = 2;
[Comment("Delay between creation of each copy", "animationFrameDelay")]
public bool commentSpaceC = true;
int maxNumberOfSteps = 0;
int frame = 0;
// Start is called before the first frame update
public void addNewLeaf(GameObject newParent, Vector3 newPosition, Vector3 newRotation, Vector2[] newWidthCurveKeyPoints, Vector2[] newFoldCurveKeyPoints, float newLengthScale, float newThickness, float newInfold)
{
GameObject leafObject = new GameObject("newLeaf");
int i = 0;
MeshFilter leafMeshFilter = leafObject.AddComponent<MeshFilter>();
leafMeshFilter = materialSettings.GetComponent<MeshFilter>();
MeshRenderer leafMeshRenderer = leafObject.AddComponent<MeshRenderer>();
leafMeshRenderer = materialSettings.GetComponent<MeshRenderer>();
leafObject.GetComponent<MeshRenderer>().material = materialSettings.GetComponent<MeshRenderer>().material;
LeafGrow newLeaf = leafObject.AddComponent<LeafGrow>();
leafObject.GetComponent<Transform>().parent = newParent.GetComponent<Transform>();
leafObject.GetComponent<Transform>().localPosition = newPosition;
leafObject.GetComponent<Transform>().localRotation = Quaternion.Euler(newRotation.x, newRotation.y, newRotation.z);
Keyframe[] widthCurveKeys = new Keyframe[newWidthCurveKeyPoints.Length];
float directionIn = 0.0f;
float directionOut= 0.0f;
for(i=0;i<newWidthCurveKeyPoints.Length;i++)
{
directionIn = 0.0f;
directionOut = 0.0f;
if(i != 0 && i != newWidthCurveKeyPoints.Length-1)
{
if(newWidthCurveKeyPoints[i+1].y > newWidthCurveKeyPoints[i-1].y)
{
directionIn = (newWidthCurveKeyPoints[i+1].x - newWidthCurveKeyPoints[i-1].x);
}
if(newWidthCurveKeyPoints[i+1].y < newWidthCurveKeyPoints[i-1].y)
{
directionIn = (newWidthCurveKeyPoints[i-1].x - newWidthCurveKeyPoints[i+1].x);
}
if(newWidthCurveKeyPoints[i-1].y > newWidthCurveKeyPoints[i+1].y)
{
directionOut = (newWidthCurveKeyPoints[i-1].x - newWidthCurveKeyPoints[i+1].x);
}
if(newWidthCurveKeyPoints[i-1].y < newWidthCurveKeyPoints[i+1].y)
{
directionOut = (newWidthCurveKeyPoints[i+1].x - newWidthCurveKeyPoints[i-1].x);
}
widthCurveKeys[i] = new Keyframe(newWidthCurveKeyPoints[i].x, newWidthCurveKeyPoints[i].y, directionIn, directionOut, 0.4f ,0.4f);
}
else
{
widthCurveKeys[i] = new Keyframe(newWidthCurveKeyPoints[i].x, newWidthCurveKeyPoints[i].y, 0,0,0,0);
}
}
AnimationCurve widthCurve = new AnimationCurve(widthCurveKeys);
// widthCurve.preWrapMode = WrapMode.PingPong;
// widthCurve.postWrapMode = WrapMode.PingPong;
Keyframe[] foldCurveKeys = new Keyframe[newFoldCurveKeyPoints.Length];
for(i=0;i<newFoldCurveKeyPoints.Length;i++)
{
directionIn = 0.0f;
directionOut = 0.0f;
if(i != 0 && i != newFoldCurveKeyPoints.Length-1)
{
if(newFoldCurveKeyPoints[i+1].y > newFoldCurveKeyPoints[i-1].y)
{
directionIn = (newFoldCurveKeyPoints[i+1].x - newFoldCurveKeyPoints[i-1].x);
}
if(newFoldCurveKeyPoints[i+1].y < newFoldCurveKeyPoints[i-1].y)
{
directionIn = (newFoldCurveKeyPoints[i-1].x - newFoldCurveKeyPoints[i+1].x);
}
if(newFoldCurveKeyPoints[i-1].y > newFoldCurveKeyPoints[i+1].y)
{
directionOut = (newFoldCurveKeyPoints[i-1].x - newFoldCurveKeyPoints[i+1].x);
}
if(newFoldCurveKeyPoints[i-1].y < newFoldCurveKeyPoints[i+1].y)
{
directionOut = (newFoldCurveKeyPoints[i+1].x - newFoldCurveKeyPoints[i-1].x);
}
foldCurveKeys[i] = new Keyframe(newFoldCurveKeyPoints[i].x, newFoldCurveKeyPoints[i].y, directionIn, directionOut, 0.4f ,0.4f);
}
else
{
foldCurveKeys[i] = new Keyframe(newFoldCurveKeyPoints[i].x, newFoldCurveKeyPoints[i].y, 0,0,0,0);
}
}
AnimationCurve foldCurve = new AnimationCurve(foldCurveKeys);
// foldCurve.preWrapMode = WrapMode.PingPong;
// foldCurve.postWrapMode = WrapMode.PingPong;
newLeaf.widthCurve = widthCurve;
newLeaf.foldCurve = foldCurve;
newLeaf.length = newLengthScale;
newLeaf.thickness = newThickness;
newLeaf.infold = newInfold;
newLeaf.framesBetweenSteps = framesBetweenSteps;
newLeaf.numberOfAnimationSteps = numberOfAnimationSteps;
newLeaf.roughEdges = roughEdges;
newLeaf.roughEdgesSize = roughEdgesSize;
newLeaf.numberOfBranchesPairs = numberOfBranchesPairs;
newLeaf.showBranches = showBranches;
newLeaf.colision = colision;
newLeaf.colisionJoint = colisionJoint;
newLeaf.maxNumberOfSteps = maxNumberOfSteps;
}
public void Grow(bool inEditor = false)
{
GameObject leafObject = new GameObject("leafScriptStart");
int i = 0;
MeshFilter leafMeshFilter = leafObject.AddComponent<MeshFilter>();
leafMeshFilter = materialSettings.GetComponent<MeshFilter>();
MeshRenderer leafMeshRenderer = leafObject.AddComponent<MeshRenderer>();
leafMeshRenderer = materialSettings.GetComponent<MeshRenderer>();
leafObject.GetComponent<MeshRenderer>().material = materialSettings.GetComponent<MeshRenderer>().material;
LeafGrow newLeaf = leafObject.AddComponent<LeafGrow>();
leafObject.GetComponent<Transform>().parent = parent.GetComponent<Transform>();
leafObject.GetComponent<Transform>().localPosition = new Vector3(positionX, positionY, positionZ);
leafObject.GetComponent<Transform>().localRotation = Quaternion.Euler(rotationX, rotationY, rotationZ);
Keyframe[] widthCurveKeys = new Keyframe[widthCurveKeyPoints.Length];
float directionIn = 0.0f;
float directionOut= 0.0f;
for(i=0;i<widthCurveKeyPoints.Length;i++)
{
directionIn = 0.0f;
directionOut = 0.0f;
if(i != 0 && i != widthCurveKeyPoints.Length-1)
{
if(widthCurveKeyPoints[i+1].y > widthCurveKeyPoints[i-1].y)
{
directionIn = (widthCurveKeyPoints[i+1].x - widthCurveKeyPoints[i-1].x);
}
if(widthCurveKeyPoints[i+1].y < widthCurveKeyPoints[i-1].y)
{
directionIn = (widthCurveKeyPoints[i-1].x - widthCurveKeyPoints[i+1].x);
}
if(widthCurveKeyPoints[i-1].y > widthCurveKeyPoints[i+1].y)
{
directionOut = (widthCurveKeyPoints[i-1].x - widthCurveKeyPoints[i+1].x);
}
if(widthCurveKeyPoints[i-1].y < widthCurveKeyPoints[i+1].y)
{
directionOut = (widthCurveKeyPoints[i+1].x - widthCurveKeyPoints[i-1].x);
}
widthCurveKeys[i] = new Keyframe(widthCurveKeyPoints[i].x, widthCurveKeyPoints[i].y, directionIn, directionOut, 0.4f ,0.4f);
}
else
{
widthCurveKeys[i] = new Keyframe(widthCurveKeyPoints[i].x, widthCurveKeyPoints[i].y, 0,0,0,0);
}
}
AnimationCurve widthCurve = new AnimationCurve(widthCurveKeys);
// widthCurve.preWrapMode = WrapMode.PingPong;
// widthCurve.postWrapMode = WrapMode.PingPong;
Keyframe[] foldCurveKeys = new Keyframe[foldCurveKeyPoints.Length];
for(i=0;i<foldCurveKeyPoints.Length;i++)
{
directionIn = 0.0f;
directionOut = 0.0f;
if(i != 0 && i != foldCurveKeyPoints.Length-1)
{
if(foldCurveKeyPoints[i+1].y > foldCurveKeyPoints[i-1].y)
{
directionIn = (foldCurveKeyPoints[i+1].x - foldCurveKeyPoints[i-1].x);
}
if(foldCurveKeyPoints[i+1].y < foldCurveKeyPoints[i-1].y)
{
directionIn = (foldCurveKeyPoints[i-1].x - foldCurveKeyPoints[i+1].x);
}
if(foldCurveKeyPoints[i-1].y > foldCurveKeyPoints[i+1].y)
{
directionOut = (foldCurveKeyPoints[i-1].x - foldCurveKeyPoints[i+1].x);
}
if(foldCurveKeyPoints[i-1].y < foldCurveKeyPoints[i+1].y)
{
directionOut = (foldCurveKeyPoints[i+1].x - foldCurveKeyPoints[i-1].x);
}
foldCurveKeys[i] = new Keyframe(foldCurveKeyPoints[i].x, foldCurveKeyPoints[i].y, directionIn, directionOut, 0.4f ,0.4f);
}
else
{
foldCurveKeys[i] = new Keyframe(foldCurveKeyPoints[i].x, foldCurveKeyPoints[i].y, 0,0,0,0);
}
}
AnimationCurve foldCurve = new AnimationCurve(foldCurveKeys);
// foldCurve.preWrapMode = WrapMode.PingPong;
// foldCurve.postWrapMode = WrapMode.PingPong;
newLeaf.widthCurve = widthCurve;
newLeaf.foldCurve = foldCurve;
newLeaf.length = lengthScale;
newLeaf.thickness = thickness;
newLeaf.infold = infold;
newLeaf.framesBetweenSteps = framesBetweenSteps;
newLeaf.numberOfAnimationSteps = numberOfAnimationSteps;
newLeaf.roughEdges = roughEdges;
newLeaf.roughEdgesSize = roughEdgesSize;
newLeaf.numberOfBranchesPairs = numberOfBranchesPairs;
newLeaf.showBranches = showBranches;
newLeaf.colision = colision;
newLeaf.colisionJoint = colisionJoint;
newLeaf.maxNumberOfSteps = maxNumberOfSteps;
if(inEditor)
{
newLeaf.DrawLeaf();
}
nextCopy();
}
void nextCopy()
{
positionX += positionXMove;
positionY += positionYMove;
positionZ += positionZMove;
rotationX += rotationXChange;
rotationY += rotationYChange;
rotationZ += rotationZChange;
if(numberOfAnimationSteps > 4)
{
numberOfAnimationSteps += animationStepsChange;
}
}
private Vector3 spos;
private Vector3 srot;
private int numberOfAnimationStepsStart;
void Start()
{
maxNumberOfSteps = numberOfAnimationSteps;
spos = new Vector3(positionX, positionY, positionZ);
srot = new Vector3(rotationX, rotationY, rotationZ);
numberOfAnimationStepsStart = numberOfAnimationSteps;
}
public void DrawLeaf()
{
Start();
for(int i=0; i<numberOfCopies; i++)
{
Grow(true);
}
positionX = spos.x;
positionY = spos.y;
positionZ = spos.z;
rotationX = srot.x;
rotationY = srot.y;
rotationZ = srot.z;
numberOfAnimationSteps = numberOfAnimationStepsStart;
}
// Update is called once per frame
void Update()
{
if(frame < numberOfCopies*animationFrameDelay)
{
if(frame%animationFrameDelay == 0)
{
Grow();
}
}
else
{
if(animationFrameDelay == 0 && frame == 1)
{
for(int i=0; i<numberOfCopies; i++)
{
Grow();
}
}
}
frame += 1;
}
}