Advertisement
KaiClavier

STMVertexMod.cs (Curve along circle)

Jul 29th, 2022
27
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 5.79 KB | None | 0 0
  1. //Copyright (c) 2022 Kai Clavier [kaiclavier.com] Do Not Distribute
  2. using UnityEngine;
  3. using System.Collections;
  4.  
  5. public class STMVertexMod : MonoBehaviour
  6. {
  7.     //directly modify vertices
  8.     [Header("Curve")]
  9.     public Vector3 positionOffset;
  10.     public float angleOffset = -1f;
  11.     public Vector3 pivot;
  12.     public float letterRotation = 1f;
  13.  
  14.     [Header("Circle")]
  15.     public float radius = 2f;
  16.     [Range(0.0001f,1f)]
  17.     public float amountOfCircle = 1f;
  18.     public bool positionsFillCircle = true;
  19.  
  20.  
  21.    
  22.     public void AlignToGrid(Vector3[] verts, Vector3[] middles, Vector3[] positions){
  23.         //figure out offset of first position to grid
  24.         int rowStart = 0;
  25.         Vector3 posDifference = RoundDifference(positions[0]);
  26.         for(int i=0, iL=positions.Length; i<iL; i++){
  27.             if(positions[i].y != positions[rowStart].y){
  28.                 rowStart = i; //new row
  29.                 posDifference = RoundDifference(positions[rowStart]);
  30.             }
  31.             verts[4*i+0] += posDifference; //apply this offset to every vertice
  32.             verts[4*i+1] += posDifference;
  33.             verts[4*i+2] += posDifference;
  34.             verts[4*i+3] += posDifference;
  35.         }
  36.     }
  37.     private Vector3 RoundDifference(Vector3 original){
  38.         Vector3 roundedPos = new Vector3(Mathf.Round(original.x), Mathf.Round(original.y), Mathf.Round(original.z));
  39.         return original - roundedPos;
  40.     }
  41.     public void ApplyCurveToVertices(Vector3[] verts, Vector3[] middles, Vector3[] positions){
  42.         for(int i=0, iL=verts.Length / 4; i<iL; i++){
  43.             //offset position...
  44.             //In this for loop,
  45.             //verts[4*i+0] is the top-left corner
  46.             //verts[4*i+1] is the top-right corner
  47.             //verts[4*i+2] is the bottom-right corner
  48.             //verts[4*i+3] is the bottom-left corner... of a single letter!
  49.            
  50.             verts[4*i+0] -= new Vector3(positionOffset.x,verts[4*i+0].x * positionOffset.y,positionOffset.z);
  51.             verts[4*i+1] -= new Vector3(positionOffset.x,verts[4*i+0].x * positionOffset.y,positionOffset.z);
  52.             verts[4*i+2] -= new Vector3(positionOffset.x,verts[4*i+0].x * positionOffset.y,positionOffset.z);
  53.             verts[4*i+3] -= new Vector3(positionOffset.x,verts[4*i+0].x * positionOffset.y,positionOffset.z);
  54.            
  55.             //rotate letter...
  56.             //Vector3 middleOfLetter = Vector3.Lerp(verts[4*i+0], verts[4*i+2], 0.5f);
  57.             //this isn't neccesarily the middle of the letter, as some points go below
  58.             Vector3 rotationPoint = new Vector3(middles[i].x, positions[i].y, middles[i].z);
  59.             Vector3 angle = new Vector3(0f,0f,angleOffset * middles[i].x);
  60.             if(float.IsNaN(angle.z)){
  61.                 angle = Vector3.zero; //awful
  62.             }
  63.            
  64.             verts[4*i+0] = RotatePointAroundPivot(verts[4*i+0], rotationPoint, angle);
  65.             verts[4*i+1] = RotatePointAroundPivot(verts[4*i+1], rotationPoint, angle);
  66.             verts[4*i+2] = RotatePointAroundPivot(verts[4*i+2], rotationPoint, angle);
  67.             verts[4*i+3] = RotatePointAroundPivot(verts[4*i+3], rotationPoint, angle);
  68.             //Vector3 pivot = info[i].Middle;
  69.             angle.z += (positions[i].y * letterRotation);
  70.             verts[4*i+0] = RotatePointAroundPivot(verts[4*i+0], pivot, angle);
  71.             verts[4*i+1] = RotatePointAroundPivot(verts[4*i+1], pivot, angle);
  72.             verts[4*i+2] = RotatePointAroundPivot(verts[4*i+2], pivot, angle);
  73.             verts[4*i+3] = RotatePointAroundPivot(verts[4*i+3], pivot, angle);
  74.         }
  75.     }
  76.     private Vector3 RotatePointAroundPivot(Vector3 point, Vector3 myPivot, Vector3 angles) {
  77.         Vector3 dir = point - myPivot; // get point direction relative to myPivot
  78.         dir = Quaternion.Euler(angles) * dir; // rotate it
  79.         point = dir + myPivot; // calculate rotated point
  80.         return point; // return it
  81.     }
  82.  
  83.     public void WrapAroundCircle(Vector3[] verts, Vector3[] middles, Vector3[] positions){
  84.  
  85.         //get widest point.
  86.         float furthestPoint = 0.00001f;
  87.         for(int i=0; i<verts.Length / 4; i++)
  88.         {
  89.             furthestPoint = Mathf.Max(furthestPoint, verts[4*i+2].x);
  90.         }
  91.        
  92.         float circleCircumference = radius * 2f * Mathf.PI;
  93.         float myAmountOfCircle = amountOfCircle;
  94.         if(!positionsFillCircle)
  95.         {
  96.             myAmountOfCircle = furthestPoint / circleCircumference;
  97.             if(myAmountOfCircle > 1f)
  98.             {
  99.                 myAmountOfCircle = 1f;
  100.             }
  101.         }
  102.         //for every vert...
  103.         for(int i=0, iL=verts.Length / 4; i<iL; i++)
  104.         {
  105.            
  106.             //how far downt he circle the letter is
  107.             float amt = positions[i].x / furthestPoint * Mathf.PI * myAmountOfCircle;
  108.             //same but in degrees
  109.             float eulerAmt = positions[i].x / furthestPoint * myAmountOfCircle * -180f - 90f;
  110.             //get local position of verts
  111.             Vector3 localVert0 = Vector3.zero;
  112.             Vector3 localVert1 = verts[4*i+1] - verts[4*i+0];
  113.             Vector3 localVert2 = verts[4*i+2] - verts[4*i+0];
  114.             Vector3 localVert3 = verts[4*i+3] - verts[4*i+0];
  115.  
  116.            
  117.             verts[4*i+0] = new Vector3(Mathf.Cos(amt) * radius + localVert0.x, -Mathf.Sin(amt) * radius + verts[4*i+0].y, verts[4*i+0].z);
  118.             verts[4*i+1] = new Vector3(Mathf.Cos(amt) * radius + localVert1.x, -Mathf.Sin(amt) * radius + verts[4*i+1].y, verts[4*i+1].z);
  119.             verts[4*i+2] = new Vector3(Mathf.Cos(amt) * radius + localVert2.x, -Mathf.Sin(amt) * radius + verts[4*i+2].y, verts[4*i+2].z);
  120.             verts[4*i+3] = new Vector3(Mathf.Cos(amt) * radius + localVert3.x, -Mathf.Sin(amt) * radius + verts[4*i+3].y, verts[4*i+3].z);
  121.             //recalculate middle point based on new position
  122.             //so... this position is the "base line" of the letter vertically, and the middle horizontally.
  123.             Vector3 rotationPoint = new Vector3(Mathf.Cos(amt) * radius + middles[i].x - positions[i].x, -Mathf.Sin(amt) * radius + positions[i].y, positions[i].z);
  124.            
  125.             //rotate letter...
  126.             Vector3 angle = new Vector3(0f,0f,eulerAmt);
  127.             if(float.IsNaN(angle.z))
  128.             {
  129.                 angle = Vector3.zero; //awful
  130.             }
  131.             verts[4*i+0] = RotatePointAroundPivot(verts[4*i+0], rotationPoint, angle);
  132.             verts[4*i+1] = RotatePointAroundPivot(verts[4*i+1], rotationPoint, angle);
  133.             verts[4*i+2] = RotatePointAroundPivot(verts[4*i+2], rotationPoint, angle);
  134.             verts[4*i+3] = RotatePointAroundPivot(verts[4*i+3], rotationPoint, angle);
  135.            
  136.         }
  137.     }
  138.  
  139. }
  140.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement