123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165 |
- //### Bezier Logic
- //This is an utilety class for all major calculations related to vectorized bezier curve.
- //
- //License information: [ASSET STORE TERMS OF SERVICE AND EULA](https://unity3d.com/legal/as_terms)
- //
- //Developed by [MathArtCode](https://www.assetstore.unity3d.com/en/#!/search/page=1/sortby=popularity/query=publisher:8738) team, 2015
- using System;
- using System.Linq;
- using Assets.Scripts.BezierCurvedParticlesFlow.Interfaces;
- using UnityEngine;
- namespace Assets.Scripts.BezierCurvedParticlesFlow.Utilities {
- [Serializable]
- public sealed class BezierLogic : IBezierLogic {
- [SerializeField]
- private Vector3[] _points;
- //All points are handeled inside a single array
- //- positioning (end points) have indexes 0, 3, 6, ...
- //- angles (control points) have indexes 1,2, 4,5, ...
- private Vector3[] Points {
- get {
- if (_points == null) {
- Reset();
- }
- return _points;
- }
- }
- // Provides ammount of all points (end points + control pouints in AI terminolagy)
- public int ControlPointCount {
- get { return Points.Length; }
- }
- // Provides ammount of all curved segments of Bezier curve
- private int CurveCount {
- get { return (Points.Length - 1)/3; }
- }
- // Returns a coordinate point relative to curve 'time' where 0 is bezier curve beginning and 1 is end of the bezier curve (length vise)
- public Vector3 GetPoint(float t) {
- int i;
- if (t >= 1f) {
- t = 1f;
- i = _points.Length - 4;
- }
- else {
- t = Mathf.Clamp01(t)*CurveCount;
- i = (int) t;
- t -= i;
- i *= 3;
- }
- return GetPoint(_points[i], _points[i + 1], _points[i + 2], _points[i + 3], t);
- }
- // Returns a velocity point relative to curve 'time' where 0 is bezier curve beginning and 1 is end of the bezier curve (length vise)
- public Vector3 GetVelocity(float t) {
- int i;
- if (t >= 1f) {
- t = 1f;
- i = _points.Length - 4;
- }
- else {
- t = Mathf.Clamp01(t)*CurveCount;
- i = (int) t;
- t -= i;
- i *= 3;
- }
- return
- GetFirstDerivative(_points[i], _points[i + 1], _points[i + 2], _points[i + 3], t);
- }
- // Returns a normalized velocity point relative to curve 'time' where 0 is bezier curve beginning and 1 is end of the bezier curve (length vise)
- public Vector3 GetDirection(float t) {
- return GetVelocity(t).normalized;
- }
- //### Mathematical core of Bezier Logic
- private static Vector3 GetPoint(Vector3 p0, Vector3 p1, Vector3 p2, Vector3 p3, float t) {
- t = Mathf.Clamp01(t);
- var oneMinusT = 1f - t;
- return
- oneMinusT*oneMinusT*oneMinusT*p0 +
- 3f*oneMinusT*oneMinusT*t*p1 +
- 3f*oneMinusT*t*t*p2 +
- t*t*t*p3;
- }
- private static Vector3 GetFirstDerivative(Vector3 p0, Vector3 p1, Vector3 p2, Vector3 p3, float t) {
- t = Mathf.Clamp01(t);
- var oneMinusT = 1f - t;
- return
- 3f*oneMinusT*oneMinusT*(p1 - p0) +
- 6f*oneMinusT*t*(p2 - p1) +
- 3f*t*t*(p3 - p2);
- }
- //Resets component to its default 2 points (forming a straight line)
- public void Reset() {
- _points = new[] {
- new Vector3(0f, 0f, 0f),
- new Vector3(2f, 0f, 0f),
- new Vector3(3f, 0f, 0f),
- new Vector3(4f, 0f, 0f)
- };
- }
- //Returns a point by its index
- //- positioning (end points) have indexes 0, 3, 6, ...
- //- angles (control points) have indexes 1,2, 4,5, ...
- public Vector3 GetControlPoint(int index) {
- return Points[index];
- }
- //Sets a point value by its index
- //- positioning (end points) have indexes 0, 3, 6 ...
- //- angles (control points) have indexes 1,2, 4,5, ...
- public void SetControlPoint(int index, Vector3 point) {
- if (index%3 == 0) {
- var delta = point - Points[index];
- if (index > 0) {
- _points[index - 1] += delta;
- }
- if (index + 1 < _points.Length) {
- _points[index + 1] += delta;
- }
- }
- Points[index] = point;
- }
- // Adds a position point + 2 angle points
- public void AddPoint() {
- var length = Points.Length;
- var point = _points[length - 1];
- var velocity = GetDirection(1f);
- Array.Resize(ref _points, length + 3);
- length = Points.Length;
- point += velocity;
- _points[length - 3] = point;
- point += velocity;
- _points[length - 2] = point;
- point += velocity;
- _points[length - 1] = point;
- }
- // Removes a position point + 2 angle points. gets an end point index as an argument
- //- positioning (end points) have indexes 0, 3, 6...
- public void RemovePoint(int selectedIndex) {
- var points = Points.ToList();
- if (selectedIndex == _points.Length - 1) {
- points.RemoveRange(selectedIndex - 2, 3);
- }
- else {
- points.RemoveRange(selectedIndex - 1, 3);
- }
- _points = points.ToArray();
- }
- }
- }
|