Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.Collections;
- using System.Collections.Generic;
- using System.Security.Permissions;
- using src.lib;
- using UnityEngine;
- using Random = UnityEngine.Random;
- public class TestPlush : MonoBehaviour
- {
- private Mesh mesh;
- private List<Vector2> _uvs;
- private List<Vector3> _vertices;
- private List<Vector3> _normals;
- private List<int> _triangles;
- private Transform _wayTrans;
- private Transform _castTrans;
- [SerializeField] private bool debugDraw;
- [Space(10)] public float step;
- public int steps;
- public float slip;
- public float width;
- public float padding;
- public int res;
- private float[] _cachedRandom = new float[1000];
- private int currentRandomIndex = 0;
- [Space(20)] [SerializeField] private int stepsPerAngle;
- [SerializeField] private float maxCastAngle = 60f;
- [SerializeField] private float castAngleStep = 10f;
- // Use this for initialization
- void Start()
- {
- mesh = new Mesh();
- GetComponent<MeshFilter>().mesh = mesh;
- _uvs = new List<Vector2>();
- _vertices = new List<Vector3>();
- _normals = new List<Vector3>();
- _triangles = new List<int>();
- _wayTrans = new GameObject().transform;
- _castTrans = new GameObject().transform;
- for (int i = 0; i < _cachedRandom.Length; i++)
- {
- _cachedRandom[i] = Random.value;
- }
- }
- // Update is called once per frame
- public void ReCalculate()
- {
- _wayTrans.position = transform.position;
- _wayTrans.rotation = Quaternion.LookRotation(transform.up, transform.forward);
- Ray ray = new Ray(transform.position, transform.forward);
- RaycastHit hit = new RaycastHit();
- Physics.Raycast(ray, out hit);
- if (hit.collider != null)
- {
- LineDrawer.DrawLine(transform.position, hit.point, Color.green, false);
- }
- Color color = Color.green;
- Vector3 prevSegmentEnd = transform.position;
- _vertices.Clear();
- _triangles.Clear();
- mesh.SetTriangles(_triangles, 0);
- float grav = 2f;
- _oldPoints.Clear();
- _newPoints.Clear();
- for (int i = 0; i < res; i++)
- {
- float angle = (float) i / res * 6.28f;
- Vector3 pos = new Vector3(Mathf.Cos(angle) * width, Mathf.Sin(angle) * width, 0);
- pos = transform.TransformPoint(pos);
- _oldPoints.Add(pos);
- }
- RefreshRandom();
- for (int i = 0; i < steps; i++)
- {
- Vector3 prevHitPoint = hit.point;
- Vector3 prevNormal = hit.normal;
- int rayNum = 0;
- float currentAngleD = 0f;
- _castTrans.position = _wayTrans.position;
- color = Color.white;
- Quaternion startRotation = Quaternion.LookRotation((_wayTrans.up + _wayTrans.forward) / 2, (_wayTrans.up - _wayTrans.forward) / 2);
- while (true)
- {
- _castTrans.rotation = startRotation;
- if (rayNum > 0)
- {
- if ((rayNum - 1) % stepsPerAngle == 0)
- {
- color.r *= 0.8f;
- color.g *= 0.8f;
- color.b *= 0.8f;
- currentAngleD += castAngleStep;
- if (currentAngleD > maxCastAngle)
- break;
- }
- float angle = (rayNum % (float) stepsPerAngle) / (float) stepsPerAngle * 6.28f;
- float sin = Mathf.Sin(angle);
- float cos = Mathf.Cos(angle);
- _castTrans.Rotate(new Vector3(sin * currentAngleD, cos * currentAngleD, 0), Space.Self);
- }
- float rayMaxLenght = 0.15f;
- if (debugDraw)
- LineDrawer.DrawLine(_castTrans.position, _castTrans.position + _castTrans.forward * rayMaxLenght, rayNum == 0 ? Color.yellow : color);
- Vector3 rayDirection = _castTrans.forward;
- ray = new Ray(_wayTrans.position, rayDirection);
- Physics.Raycast(ray, out hit, 0.1f);
- if (hit.collider != null)
- {
- if (debugDraw)
- LineDrawer.DrawLine(ray.origin, hit.point, Color.green);
- Vector3 target = hit.point + hit.normal * slip;
- _wayTrans.rotation = Quaternion.LookRotation(target - _wayTrans.position, -hit.normal);
- _wayTrans.position = (target - _wayTrans.position) * step + target;
- if (!debugDraw)
- {
- CreateTubeSegment(_wayTrans.position);
- }
- break;
- }
- rayNum++;
- }
- }
- mesh.SetVertices(_vertices);
- mesh.SetTriangles(_triangles, 0);
- mesh.RecalculateNormals(60);
- mesh.RecalculateTangents();
- }
- private List<Vector3> _oldPoints = new List<Vector3>();
- private List<Vector3> _newPoints = new List<Vector3>();
- private void CreateTubeSegment(Vector3 segmentEnd)
- {
- Vector3 p1;
- Vector3 p2;
- Vector3 p3;
- Vector3 p4;
- for (int j = 0; j < res; j++)
- {
- float angle = (float) j / res * 6.28f;
- Vector3 pos = new Vector3(Mathf.Cos(angle) * width, Mathf.Sin(angle) * width, 0);
- pos = _wayTrans.TransformPoint(pos) - _wayTrans.position + segmentEnd;
- _newPoints.Add(pos);
- }
- for (int j = 0; j < res; j++)
- {
- p1 = _oldPoints[j];
- p2 = _newPoints[j];
- if (j < res - 1)
- {
- p3 = _oldPoints[j + 1];
- p4 = _newPoints[j + 1];
- }
- else
- {
- p3 = _oldPoints[0];
- p4 = _newPoints[0];
- }
- CreateQuad(p1, p2, p3, p4);
- }
- List<Vector3> temp = _oldPoints;
- _oldPoints = _newPoints;
- _newPoints = temp;
- _newPoints.Clear();
- }
- private void CreateQuad(Vector3 p1, Vector3 p2, Vector3 p3, Vector3 p4)
- {
- int start = _vertices.Count;
- _vertices.Add(transform.InverseTransformPoint(p1));
- _vertices.Add(transform.InverseTransformPoint(p2));
- _vertices.Add(transform.InverseTransformPoint(p3));
- _vertices.Add(transform.InverseTransformPoint(p4));
- _triangles.Add(start);
- _triangles.Add(start + 2);
- _triangles.Add(start + 1);
- _triangles.Add(start + 2);
- _triangles.Add(start + 3);
- _triangles.Add(start + 1);
- }
- public Vector3 RotatePointAroundPivot(Vector3 point, Vector3 pivot, Vector3 angles)
- {
- return Quaternion.Euler(angles) * (point - pivot) + pivot;
- }
- private float GetNextRandom()
- {
- return _cachedRandom[currentRandomIndex++];
- }
- private void RefreshRandom()
- {
- currentRandomIndex = 0;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement