Skip to content

Instantly share code, notes, and snippets.

@HAliss
Created July 25, 2022 09:16
Show Gist options
  • Save HAliss/3dbe1688d65bf77d9fcdd08a81dab4b4 to your computer and use it in GitHub Desktop.
Save HAliss/3dbe1688d65bf77d9fcdd08a81dab4b4 to your computer and use it in GitHub Desktop.
Bezier visualization script for grass blade generation
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[ExecuteAlways]
public class BezierTest : MonoBehaviour {
public int numOfPoints;
public float height = 1;
public float forwardRotation = 0;
public float curvature = 0;
private Vector3 normal = Vector3.up;
private Vector3 tangent = Vector3.right;
private Vector3[] points;
private Vector3[] tangents;
private Vector3 pointA, pointB, handle;
private void OnEnable() {
normal = transform.up;
tangent = transform.right;
}
private void Update() {
Vector3 bitangent = Vector3.Cross(normal, tangent).normalized;
pointA = Vector3.zero;
pointB = Vector3.zero + normal * height + forwardRotation * height * bitangent;
handle = (pointA + pointB) * 0.5f - Vector3.Cross(pointB - pointA, tangent).normalized * curvature * forwardRotation * height;
points = new Vector3[numOfPoints];
tangents = new Vector3[numOfPoints];
for (int i = 0; i < numOfPoints; i++) {
float t = (float)i / numOfPoints;
points[i] = GetBezierPoint(pointA, pointB, handle, t);
tangents[i] = GetBezierPointTangent(pointA, pointB, handle, t);
}
}
private Vector3 GetBezierPoint(Vector3 pointA, Vector3 pointB, Vector3 handle, float t) {
return (1 - t) * ((1 - t) * pointA + t * handle) + t * ((1 - t) * handle + t * pointB);
}
private Vector3 GetBezierPointTangent(Vector3 pointA, Vector3 pointB, Vector3 handle, float t) {
return (2 * t * (pointA - 2 * handle + pointB) + 2 * (handle - pointA)).normalized;
}
private void OnDrawGizmos() {
Gizmos.color = Color.green;
Vector3 worldPointA = transform.TransformPoint(pointA);
Vector3 worldPointB = transform.TransformPoint(pointB);
Vector3 worldHandle = transform.TransformPoint(handle);
Gizmos.DrawSphere(worldPointA, 0.1f);
Gizmos.DrawSphere(worldPointB, 0.1f);
Gizmos.DrawSphere(worldHandle, 0.15f);
Gizmos.DrawLine(worldPointA, worldPointB);
Gizmos.DrawLine(worldHandle, (worldPointA + worldPointB) * 0.5f);
for (int i = 0; i < points.Length; i++) {
Gizmos.color = Color.yellow;
Vector3 point = transform.TransformPoint(points[i]);
Gizmos.DrawSphere(point, 0.05f);
if (i < points.Length - 1) {
Gizmos.DrawLine(point, transform.TransformPoint(points[i + 1]));
} else {
Gizmos.DrawLine(point, worldPointB);
}
Gizmos.color = Color.red;
Gizmos.DrawRay(point, transform.TransformDirection(tangents[i]));
Gizmos.color = Color.blue;
Vector3 normal = transform.TransformDirection(Quaternion.AngleAxis(90, tangent) * tangents[i]).normalized;
Gizmos.DrawRay(point, normal);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment