├── .gitignore ├── Assets ├── BezierCurves.meta ├── BezierCurves │ ├── Editor.meta │ ├── Editor │ │ ├── BezierCurveEditor.cs │ │ ├── BezierCurveEditor.cs.meta │ │ ├── BezierPointEditor.cs │ │ └── BezierPointEditor.cs.meta │ ├── Example.unity │ ├── Example.unity.meta │ ├── Scripts.meta │ ├── Scripts │ │ ├── BezierCurve.cs │ │ ├── BezierCurve.cs.meta │ │ ├── BezierPoint.cs │ │ └── BezierPoint.cs.meta │ ├── readme.txt │ └── readme.txt.meta ├── CurveModifier.meta ├── CurveModifier │ ├── Materials.meta │ ├── Materials │ │ ├── Dragon Curve Modifier.mat │ │ ├── Dragon Curve Modifier.mat.meta │ │ ├── Dragon Curve Offset.mat │ │ ├── Dragon Curve Offset.mat.meta │ │ ├── Dragon Curve.mat │ │ └── Dragon Curve.mat.meta │ ├── Meshes.meta │ ├── Meshes │ │ ├── Dragon.meta │ │ └── Dragon │ │ │ ├── Dragon.fbx │ │ │ ├── Dragon.fbx.meta │ │ │ ├── Dragon.png │ │ │ ├── Dragon.png.meta │ │ │ ├── Materials.meta │ │ │ ├── Materials │ │ │ ├── No Name.mat │ │ │ └── No Name.mat.meta │ │ │ ├── credits.txt │ │ │ └── credits.txt.meta │ ├── Scenes.meta │ ├── Scenes │ │ ├── BezierExample.unity │ │ ├── BezierExample.unity.meta │ │ ├── FollowExample.unity │ │ ├── FollowExample.unity.meta │ │ ├── ScriptExample.unity │ │ └── ScriptExample.unity.meta │ ├── Scripts.meta │ ├── Scripts │ │ ├── CurveModifier.cs │ │ ├── CurveModifier.cs.meta │ │ ├── Examples.meta │ │ ├── Examples │ │ │ ├── BezierCurveModifier.cs │ │ │ ├── BezierCurveModifier.cs.meta │ │ │ ├── FollowCurveModifier.cs │ │ │ ├── FollowCurveModifier.cs.meta │ │ │ ├── ScriptCurveModifier.cs │ │ │ └── ScriptCurveModifier.cs.meta │ │ ├── Utils.meta │ │ └── Utils │ │ │ ├── CullingBounds.cs │ │ │ ├── CullingBounds.cs.meta │ │ │ ├── RumbleRigidbody.cs │ │ │ └── RumbleRigidbody.cs.meta │ ├── Shaders.meta │ └── Shaders │ │ ├── CurveModifier.shader │ │ ├── CurveModifier.shader.meta │ │ ├── Utils.cginc │ │ └── Utils.cginc.meta ├── SimpleCurveModifier.meta └── SimpleCurveModifier │ ├── Sel.meta │ ├── Sel │ ├── sel.fbx │ ├── sel.fbx.meta │ ├── sel.jpg │ ├── sel.jpg.meta │ ├── sel.txt │ └── sel.txt.meta │ ├── SimpleCurveModifier.cs │ ├── SimpleCurveModifier.cs.meta │ ├── SimpleCurveModifier.mat │ ├── SimpleCurveModifier.mat.meta │ ├── SimpleCurveModifier.shader │ ├── SimpleCurveModifier.shader.meta │ ├── SimpleCurveModifier.unity │ └── SimpleCurveModifier.unity.meta ├── LICENSE ├── ProjectSettings ├── AudioManager.asset ├── ClusterInputManager.asset ├── DynamicsManager.asset ├── EditorBuildSettings.asset ├── EditorSettings.asset ├── GraphicsSettings.asset ├── InputManager.asset ├── NavMeshAreas.asset ├── NetworkManager.asset ├── Physics2DSettings.asset ├── ProjectSettings.asset ├── ProjectVersion.txt ├── QualitySettings.asset ├── TagManager.asset ├── TimeManager.asset └── UnityConnectSettings.asset ├── README.md ├── UnityPackageManager └── manifest.json └── images ├── 217.gif ├── 228.gif ├── 235.gif ├── 242.gif ├── 243.gif ├── 244.gif ├── 245.gif ├── 246.gif ├── 247.gif ├── 251.gif ├── 254.gif ├── 29.gif ├── 81.gif ├── 81.png ├── maths.jpg ├── maxpayne1.gif ├── snake1.PNG ├── ui1.PNG ├── ui2.PNG └── ui3.gif /.gitignore: -------------------------------------------------------------------------------- 1 | /[Ll]ibrary/ 2 | /[Tt]emp/ 3 | /[Oo]bj/ 4 | /[Bb]uild/ 5 | /[Bb]uilds/ 6 | /Assets/AssetStoreTools* 7 | 8 | *.ogv 9 | *.ogv.meta 10 | 11 | *.mp4 12 | *.mp4.meta 13 | 14 | *.avi 15 | *.avi.meta 16 | 17 | *.mov 18 | *.mov.meta 19 | 20 | # Autogenerated VS/MD solution and project files 21 | ExportedObj/ 22 | *.csproj 23 | *.unityproj 24 | *.sln 25 | *.suo 26 | *.tmp 27 | *.user 28 | *.userprefs 29 | *.pidb 30 | *.booproj 31 | *.svd 32 | 33 | 34 | # Unity3D generated meta files 35 | *.pidb.meta 36 | 37 | # Unity3D Generated File On Crash Reports 38 | sysinfo.txt 39 | -------------------------------------------------------------------------------- /Assets/BezierCurves.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 266b730162cc653478fe954b21f99f90 3 | folderAsset: yes 4 | timeCreated: 1465247153 5 | licenseType: Free 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/BezierCurves/Editor.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 9dac9c0af05b62e41a5392a0b0982385 3 | folderAsset: yes 4 | timeCreated: 1460770912 5 | licenseType: Free 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/BezierCurves/Editor/BezierCurveEditor.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using UnityEditor; 3 | using System.Collections; 4 | 5 | [CustomEditor(typeof(BezierCurve))] 6 | public class BezierCurveEditor : Editor 7 | { 8 | BezierCurve curve; 9 | SerializedProperty resolutionProp; 10 | SerializedProperty closeProp; 11 | SerializedProperty pointsProp; 12 | SerializedProperty colorProp; 13 | 14 | private static bool showPoints = true; 15 | 16 | void OnEnable() 17 | { 18 | curve = (BezierCurve)target; 19 | 20 | resolutionProp = serializedObject.FindProperty("resolution"); 21 | closeProp = serializedObject.FindProperty("_close"); 22 | pointsProp = serializedObject.FindProperty("points"); 23 | colorProp = serializedObject.FindProperty("drawColor"); 24 | } 25 | 26 | public override void OnInspectorGUI() 27 | { 28 | serializedObject.Update(); 29 | 30 | EditorGUILayout.PropertyField(resolutionProp); 31 | EditorGUILayout.PropertyField(closeProp); 32 | EditorGUILayout.PropertyField(colorProp); 33 | 34 | showPoints = EditorGUILayout.Foldout(showPoints, "Points"); 35 | 36 | if(showPoints) 37 | { 38 | int pointCount = pointsProp.arraySize; 39 | 40 | for(int i = 0; i < pointCount; i++) 41 | { 42 | DrawPointInspector(curve[i], i); 43 | } 44 | 45 | if(GUILayout.Button("Add Point")) 46 | { 47 | Undo.RegisterSceneUndo("Add Point"); 48 | 49 | GameObject pointObject = new GameObject("Point "+pointsProp.arraySize); 50 | pointObject.transform.parent = curve.transform; 51 | pointObject.transform.localPosition = Vector3.zero; 52 | BezierPoint newPoint = pointObject.AddComponent(); 53 | 54 | newPoint.curve = curve; 55 | newPoint.handle1 = Vector3.right*0.1f; 56 | newPoint.handle2 = -Vector3.right*0.1f; 57 | 58 | pointsProp.InsertArrayElementAtIndex(pointsProp.arraySize); 59 | pointsProp.GetArrayElementAtIndex(pointsProp.arraySize - 1).objectReferenceValue = newPoint; 60 | } 61 | } 62 | 63 | if(GUI.changed) 64 | { 65 | serializedObject.ApplyModifiedProperties(); 66 | EditorUtility.SetDirty(target); 67 | } 68 | } 69 | 70 | void OnSceneGUI() 71 | { 72 | for(int i = 0; i < curve.pointCount; i++) 73 | { 74 | DrawPointSceneGUI(curve[i]); 75 | } 76 | } 77 | 78 | void DrawPointInspector(BezierPoint point, int index) 79 | { 80 | SerializedObject serObj = new SerializedObject(point); 81 | 82 | SerializedProperty handleStyleProp = serObj.FindProperty("handleStyle"); 83 | SerializedProperty handle1Prop = serObj.FindProperty("_handle1"); 84 | SerializedProperty handle2Prop = serObj.FindProperty("_handle2"); 85 | 86 | EditorGUILayout.BeginHorizontal(); 87 | 88 | if(GUILayout.Button("X", GUILayout.Width(20))) 89 | { 90 | Undo.RegisterSceneUndo("Remove Point"); 91 | pointsProp.MoveArrayElement(curve.GetPointIndex(point), curve.pointCount - 1); 92 | pointsProp.arraySize--; 93 | DestroyImmediate(point.gameObject); 94 | return; 95 | } 96 | 97 | EditorGUILayout.ObjectField(point.gameObject, typeof(GameObject), true); 98 | 99 | if(index != 0 && GUILayout.Button(@"/\", GUILayout.Width(25))) 100 | { 101 | UnityEngine.Object other = pointsProp.GetArrayElementAtIndex(index - 1).objectReferenceValue; 102 | pointsProp.GetArrayElementAtIndex(index - 1).objectReferenceValue = point; 103 | pointsProp.GetArrayElementAtIndex(index).objectReferenceValue = other; 104 | } 105 | 106 | if(index != pointsProp.arraySize - 1 && GUILayout.Button(@"\/", GUILayout.Width(25))) 107 | { 108 | UnityEngine.Object other = pointsProp.GetArrayElementAtIndex(index + 1).objectReferenceValue; 109 | pointsProp.GetArrayElementAtIndex(index + 1).objectReferenceValue = point; 110 | pointsProp.GetArrayElementAtIndex(index).objectReferenceValue = other; 111 | } 112 | 113 | EditorGUILayout.EndHorizontal(); 114 | 115 | EditorGUI.indentLevel++; 116 | EditorGUI.indentLevel++; 117 | 118 | int newType = (int)((object)EditorGUILayout.EnumPopup("Handle Type", (BezierPoint.HandleStyle)handleStyleProp.enumValueIndex)); 119 | 120 | if(newType != handleStyleProp.enumValueIndex) 121 | { 122 | handleStyleProp.enumValueIndex = newType; 123 | if(newType == 0) 124 | { 125 | if(handle1Prop.vector3Value != Vector3.zero) handle2Prop.vector3Value = -handle1Prop.vector3Value; 126 | else if(handle2Prop.vector3Value != Vector3.zero) handle1Prop.vector3Value = -handle2Prop.vector3Value; 127 | else 128 | { 129 | handle1Prop.vector3Value = new Vector3(0.1f, 0, 0); 130 | handle2Prop.vector3Value = new Vector3(-0.1f, 0, 0); 131 | } 132 | } 133 | 134 | else if(newType == 1) 135 | { 136 | if(handle1Prop.vector3Value == Vector3.zero && handle2Prop.vector3Value == Vector3.zero) 137 | { 138 | handle1Prop.vector3Value = new Vector3(0.1f, 0, 0); 139 | handle2Prop.vector3Value = new Vector3(-0.1f, 0, 0); 140 | } 141 | } 142 | 143 | else if(newType == 2) 144 | { 145 | handle1Prop.vector3Value = Vector3.zero; 146 | handle2Prop.vector3Value = Vector3.zero; 147 | } 148 | } 149 | 150 | Vector3 newPointPos = EditorGUILayout.Vector3Field("Position : ", point.transform.localPosition); 151 | if(newPointPos != point.transform.localPosition) 152 | { 153 | Undo.RegisterUndo(point.transform, "Move Bezier Point"); 154 | point.transform.localPosition = newPointPos; 155 | } 156 | 157 | if(handleStyleProp.enumValueIndex == 0) 158 | { 159 | Vector3 newPosition; 160 | 161 | newPosition = EditorGUILayout.Vector3Field("Handle 1", handle1Prop.vector3Value); 162 | if(newPosition != handle1Prop.vector3Value) 163 | { 164 | handle1Prop.vector3Value = newPosition; 165 | handle2Prop.vector3Value = -newPosition; 166 | } 167 | 168 | newPosition = EditorGUILayout.Vector3Field("Handle 2", handle2Prop.vector3Value); 169 | if(newPosition != handle2Prop.vector3Value) 170 | { 171 | handle1Prop.vector3Value = -newPosition; 172 | handle2Prop.vector3Value = newPosition; 173 | } 174 | } 175 | 176 | else if(handleStyleProp.enumValueIndex == 1) 177 | { 178 | EditorGUILayout.PropertyField(handle1Prop); 179 | EditorGUILayout.PropertyField(handle2Prop); 180 | } 181 | 182 | EditorGUI.indentLevel--; 183 | EditorGUI.indentLevel--; 184 | 185 | if(GUI.changed) 186 | { 187 | serObj.ApplyModifiedProperties(); 188 | EditorUtility.SetDirty(serObj.targetObject); 189 | } 190 | } 191 | 192 | static void DrawPointSceneGUI(BezierPoint point) 193 | { 194 | Handles.Label(point.position + new Vector3(0, HandleUtility.GetHandleSize(point.position) * 0.4f, 0), point.gameObject.name); 195 | 196 | Handles.color = Color.green; 197 | Vector3 newPosition = Handles.FreeMoveHandle(point.position, point.transform.rotation, HandleUtility.GetHandleSize(point.position)*0.1f, Vector3.zero, Handles.RectangleCap); 198 | 199 | if(newPosition != point.position) 200 | { 201 | Undo.RegisterUndo(point.transform, "Move Point"); 202 | point.transform.position = newPosition; 203 | } 204 | 205 | if(point.handleStyle != BezierPoint.HandleStyle.None) 206 | { 207 | Handles.color = Color.cyan; 208 | Vector3 newGlobal1 = Handles.FreeMoveHandle(point.globalHandle1, point.transform.rotation, HandleUtility.GetHandleSize(point.globalHandle1)*0.075f, Vector3.zero, Handles.CircleCap); 209 | if(point.globalHandle1 != newGlobal1) 210 | { 211 | Undo.RegisterUndo(point, "Move Handle"); 212 | point.globalHandle1 = newGlobal1; 213 | if(point.handleStyle == BezierPoint.HandleStyle.Connected) point.globalHandle2 = -(newGlobal1 - point.position) + point.position; 214 | } 215 | 216 | Vector3 newGlobal2 = Handles.FreeMoveHandle(point.globalHandle2, point.transform.rotation, HandleUtility.GetHandleSize(point.globalHandle2)*0.075f, Vector3.zero, Handles.CircleCap); 217 | if(point.globalHandle2 != newGlobal2) 218 | { 219 | Undo.RegisterUndo(point, "Move Handle"); 220 | point.globalHandle2 = newGlobal2; 221 | if(point.handleStyle == BezierPoint.HandleStyle.Connected) point.globalHandle1 = -(newGlobal2 - point.position) + point.position; 222 | } 223 | 224 | Handles.color = Color.yellow; 225 | Handles.DrawLine(point.position, point.globalHandle1); 226 | Handles.DrawLine(point.position, point.globalHandle2); 227 | } 228 | } 229 | 230 | public static void DrawOtherPoints(BezierCurve curve, BezierPoint caller) 231 | { 232 | foreach(BezierPoint p in curve.GetAnchorPoints()) 233 | { 234 | if(p != caller) DrawPointSceneGUI(p); 235 | } 236 | } 237 | 238 | [MenuItem("GameObject/Create Other/Bezier Curve")] 239 | public static void CreateCurve(MenuCommand command) 240 | { 241 | GameObject curveObject = new GameObject("BezierCurve"); 242 | Undo.RegisterUndo(curveObject, "Undo Create Curve"); 243 | BezierCurve curve = curveObject.AddComponent(); 244 | 245 | BezierPoint p1 = curve.AddPointAt(Vector3.forward * 0.5f); 246 | p1.handleStyle = BezierPoint.HandleStyle.Connected; 247 | p1.handle1 = new Vector3(-0.28f, 0, 0); 248 | 249 | BezierPoint p2 = curve.AddPointAt(Vector3.right * 0.5f); 250 | p2.handleStyle = BezierPoint.HandleStyle.Connected; 251 | p2.handle1 = new Vector3(0, 0, 0.28f); 252 | 253 | BezierPoint p3 = curve.AddPointAt(-Vector3.forward * 0.5f); 254 | p3.handleStyle = BezierPoint.HandleStyle.Connected; 255 | p3.handle1 = new Vector3(0.28f, 0, 0); 256 | 257 | BezierPoint p4 = curve.AddPointAt(-Vector3.right * 0.5f); 258 | p4.handleStyle = BezierPoint.HandleStyle.Connected; 259 | p4.handle1 = new Vector3(0, 0, -0.28f); 260 | 261 | curve.close = true; 262 | } 263 | } 264 | -------------------------------------------------------------------------------- /Assets/BezierCurves/Editor/BezierCurveEditor.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 076c82ebe1ea6b249b4e66e85cdf269a 3 | timeCreated: 18446744011573954816 4 | MonoImporter: 5 | externalObjects: {} 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/BezierCurves/Editor/BezierPointEditor.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using UnityEditor; 3 | using System.Collections; 4 | 5 | [CustomEditor(typeof(BezierPoint))] 6 | [CanEditMultipleObjects] 7 | public class BezierPointEditor : Editor { 8 | 9 | BezierPoint point; 10 | 11 | SerializedProperty handleTypeProp; 12 | SerializedProperty handle1Prop; 13 | SerializedProperty handle2Prop; 14 | 15 | private delegate void HandleFunction(BezierPoint p); 16 | private HandleFunction[] handlers = new HandleFunction[] { HandleConnected, HandleBroken, HandleAbsent }; 17 | 18 | void OnEnable(){ 19 | point = (BezierPoint)target; 20 | 21 | handleTypeProp = serializedObject.FindProperty("handleStyle"); 22 | handle1Prop = serializedObject.FindProperty("_handle1"); 23 | handle2Prop = serializedObject.FindProperty("_handle2"); 24 | } 25 | 26 | public override void OnInspectorGUI (){ 27 | 28 | serializedObject.Update(); 29 | 30 | BezierPoint.HandleStyle newHandleType = (BezierPoint.HandleStyle)EditorGUILayout.EnumPopup("Handle Type", (BezierPoint.HandleStyle)handleTypeProp.intValue); 31 | 32 | if(newHandleType != (BezierPoint.HandleStyle)handleTypeProp.intValue) 33 | { 34 | handleTypeProp.intValue = (int)newHandleType; 35 | 36 | if((int)newHandleType == 0) 37 | { 38 | if(handle1Prop.vector3Value != Vector3.zero) handle2Prop.vector3Value = -handle1Prop.vector3Value; 39 | else if(handle2Prop.vector3Value != Vector3.zero) handle1Prop.vector3Value = -handle2Prop.vector3Value; 40 | else 41 | { 42 | handle1Prop.vector3Value = new Vector3(0.1f, 0, 0); 43 | handle2Prop.vector3Value = new Vector3(-0.1f, 0, 0); 44 | } 45 | } 46 | 47 | else if((int)newHandleType == 1) 48 | { 49 | if(handle1Prop.vector3Value == Vector3.zero && handle2Prop.vector3Value == Vector3.zero) 50 | { 51 | handle1Prop.vector3Value = new Vector3(0.1f, 0, 0); 52 | handle2Prop.vector3Value = new Vector3(-0.1f, 0, 0); 53 | } 54 | } 55 | 56 | else if((int)newHandleType == 2) 57 | { 58 | handle1Prop.vector3Value = Vector3.zero; 59 | handle2Prop.vector3Value = Vector3.zero; 60 | } 61 | } 62 | 63 | if(handleTypeProp.intValue != 2) 64 | { 65 | Vector3 newHandle1 = EditorGUILayout.Vector3Field("Handle 1", handle1Prop.vector3Value); 66 | Vector3 newHandle2 = EditorGUILayout.Vector3Field("Handle 2", handle2Prop.vector3Value); 67 | 68 | if(handleTypeProp.intValue == 0){ 69 | if(newHandle1 != handle1Prop.vector3Value){ 70 | handle1Prop.vector3Value = newHandle1; 71 | handle2Prop.vector3Value = -newHandle1; 72 | } 73 | 74 | else if(newHandle2 != handle2Prop.vector3Value){ 75 | handle1Prop.vector3Value = -newHandle2; 76 | handle2Prop.vector3Value = newHandle2; 77 | } 78 | } 79 | 80 | else{ 81 | handle1Prop.vector3Value = newHandle1; 82 | handle2Prop.vector3Value = newHandle2; 83 | } 84 | } 85 | 86 | if(GUI.changed){ 87 | serializedObject.ApplyModifiedProperties(); 88 | EditorUtility.SetDirty(target); 89 | } 90 | } 91 | 92 | void OnSceneGUI() 93 | { 94 | 95 | Handles.color = Color.green; 96 | Vector3 newPosition = Handles.FreeMoveHandle(point.position, point.transform.rotation, HandleUtility.GetHandleSize(point.position)*0.2f, Vector3.zero, Handles.CubeCap); 97 | if(point.position != newPosition) point.position = newPosition; 98 | 99 | handlers[(int)point.handleStyle](point); 100 | 101 | Handles.color = Color.yellow; 102 | Handles.DrawLine(point.position, point.globalHandle1); 103 | Handles.DrawLine(point.position, point.globalHandle2); 104 | 105 | BezierCurveEditor.DrawOtherPoints(point.curve, point); 106 | } 107 | 108 | private static void HandleConnected(BezierPoint p){ 109 | Handles.color = Color.cyan; 110 | 111 | Vector3 newGlobal1 = Handles.FreeMoveHandle(p.globalHandle1, p.transform.rotation, HandleUtility.GetHandleSize(p.globalHandle1)*0.15f, Vector3.zero, Handles.SphereCap); 112 | 113 | if(newGlobal1 != p.globalHandle1){ 114 | Undo.RegisterUndo(p, "Move Handle"); 115 | p.globalHandle1 = newGlobal1; 116 | p.globalHandle2 = -(newGlobal1 - p.position) + p.position; 117 | } 118 | 119 | Vector3 newGlobal2 = Handles.FreeMoveHandle(p.globalHandle2, p.transform.rotation, HandleUtility.GetHandleSize(p.globalHandle2)*0.15f, Vector3.zero, Handles.SphereCap); 120 | 121 | if(newGlobal2 != p.globalHandle2){ 122 | Undo.RegisterUndo(p, "Move Handle"); 123 | p.globalHandle1 = -(newGlobal2 - p.position) + p.position; 124 | p.globalHandle2 = newGlobal2; 125 | } 126 | } 127 | 128 | private static void HandleBroken(BezierPoint p){ 129 | Handles.color = Color.cyan; 130 | 131 | Vector3 newGlobal1 = Handles.FreeMoveHandle(p.globalHandle1, Quaternion.identity, HandleUtility.GetHandleSize(p.globalHandle1)*0.15f, Vector3.zero, Handles.SphereCap); 132 | Vector3 newGlobal2 = Handles.FreeMoveHandle(p.globalHandle2, Quaternion.identity, HandleUtility.GetHandleSize(p.globalHandle2)*0.15f, Vector3.zero, Handles.SphereCap); 133 | 134 | if(newGlobal1 != p.globalHandle1) 135 | { 136 | Undo.RegisterUndo(p, "Move Handle"); 137 | p.globalHandle1 = newGlobal1; 138 | } 139 | 140 | if(newGlobal2 != p.globalHandle2) 141 | { 142 | Undo.RegisterUndo(p, "Move Handle"); 143 | p.globalHandle2 = newGlobal2; 144 | } 145 | } 146 | 147 | private static void HandleAbsent(BezierPoint p) 148 | { 149 | p.handle1 = Vector3.zero; 150 | p.handle2 = Vector3.zero; 151 | } 152 | } -------------------------------------------------------------------------------- /Assets/BezierCurves/Editor/BezierPointEditor.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 2f40a14ecad007949831de4081a5a58e 3 | timeCreated: 18446744011573954816 4 | MonoImporter: 5 | externalObjects: {} 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/BezierCurves/Example.unity: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leon196/CurveModifier/adcd27ae180c31bf5ce01896009a4c0b9aeb7a40/Assets/BezierCurves/Example.unity -------------------------------------------------------------------------------- /Assets/BezierCurves/Example.unity.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 3b3fe768c68c21647b45cad53f1d7c06 3 | timeCreated: 18446744011573954816 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/BezierCurves/Scripts.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 0fcc0ec16e821a54abfa7f393a5a32a9 3 | folderAsset: yes 4 | timeCreated: 1460770912 5 | licenseType: Free 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/BezierCurves/Scripts/BezierCurve.cs: -------------------------------------------------------------------------------- 1 | #region UsingStatements 2 | 3 | using UnityEngine; 4 | using System; 5 | using System.Collections; 6 | using System.Collections.Generic; 7 | 8 | #endregion 9 | 10 | /// 11 | /// - Class for describing and drawing Bezier Curves 12 | /// - Efficiently handles approximate length calculation through 'dirty' system 13 | /// - Has static functions for getting points on curves constructed by Vector3 parameters (GetPoint, GetCubicPoint, GetQuadraticPoint, and GetLinearPoint) 14 | /// 15 | [ExecuteInEditMode] 16 | [Serializable] 17 | public class BezierCurve : MonoBehaviour { 18 | 19 | #region PublicVariables 20 | 21 | /// 22 | /// - the number of mid-points calculated for each pair of bezier points 23 | /// - used for drawing the curve in the editor 24 | /// - used for calculating the "length" variable 25 | /// 26 | public int resolution = 30; 27 | 28 | /// 29 | /// Gets or sets a value indicating whether this is dirty. 30 | /// 31 | /// 32 | /// true if dirty; otherwise, false. 33 | /// 34 | public bool dirty { get; private set; } 35 | 36 | /// 37 | /// - color this curve will be drawn with in the editor 38 | /// - set in the editor 39 | /// 40 | public Color drawColor = Color.white; 41 | 42 | #endregion 43 | 44 | #region PublicProperties 45 | 46 | /// 47 | /// - set in the editor 48 | /// - used to determine if the curve should be drawn as "closed" in the editor 49 | /// - used to determine if the curve's length should include the curve between the first and the last points in "points" array 50 | /// - setting this value will cause the curve to become dirty 51 | /// 52 | [SerializeField] private bool _close; 53 | public bool close 54 | { 55 | get { return _close; } 56 | set 57 | { 58 | if(_close == value) return; 59 | _close = value; 60 | dirty = true; 61 | } 62 | } 63 | 64 | /// 65 | /// - set internally 66 | /// - gets point corresponding to "index" in "points" array 67 | /// - does not allow direct set 68 | /// 69 | /// 70 | /// - the index 71 | /// 72 | public BezierPoint this[int index] 73 | { 74 | get { return points[index]; } 75 | } 76 | 77 | /// 78 | /// - number of points stored in 'points' variable 79 | /// - set internally 80 | /// - does not include "handles" 81 | /// 82 | /// 83 | /// - The point count 84 | /// 85 | public int pointCount 86 | { 87 | get { return points.Length; } 88 | } 89 | 90 | /// 91 | /// - The approximate length of the curve 92 | /// - recalculates if the curve is "dirty" 93 | /// 94 | private float _length; 95 | public float length 96 | { 97 | get 98 | { 99 | if(dirty) 100 | { 101 | _length = 0; 102 | for(int i = 0; i < points.Length - 1; i++){ 103 | _length += ApproximateLength(points[i], points[i + 1], resolution); 104 | } 105 | 106 | if(close) _length += ApproximateLength(points[points.Length - 1], points[0], resolution); 107 | 108 | dirty = false; 109 | } 110 | 111 | return _length; 112 | } 113 | } 114 | 115 | #endregion 116 | 117 | #region PrivateVariables 118 | 119 | /// 120 | /// - Array of point objects that make up this curve 121 | /// - Populated through editor 122 | /// 123 | [SerializeField] private BezierPoint[] points = new BezierPoint[0]; 124 | 125 | #endregion 126 | 127 | #region UnityFunctions 128 | 129 | void OnDrawGizmos () { 130 | Gizmos.color = drawColor; 131 | 132 | if(points.Length > 1){ 133 | for(int i = 0; i < points.Length - 1; i++){ 134 | DrawCurve(points[i], points[i+1], resolution); 135 | } 136 | 137 | if (close) DrawCurve(points[points.Length - 1], points[0], resolution); 138 | } 139 | } 140 | 141 | void Awake(){ 142 | dirty = true; 143 | } 144 | 145 | #endregion 146 | 147 | #region PublicFunctions 148 | 149 | /// 150 | /// - Adds the given point to the end of the curve ("points" array) 151 | /// 152 | /// 153 | /// - The point to add. 154 | /// 155 | public void AddPoint(BezierPoint point) 156 | { 157 | List tempArray = new List(points); 158 | tempArray.Add(point); 159 | points = tempArray.ToArray(); 160 | dirty = true; 161 | } 162 | 163 | /// 164 | /// - Adds a point at position 165 | /// 166 | /// 167 | /// - The point object 168 | /// 169 | /// 170 | /// - Where to add the point 171 | /// 172 | public BezierPoint AddPointAt(Vector3 position) 173 | { 174 | GameObject pointObject = new GameObject("Point "+pointCount); 175 | 176 | pointObject.transform.parent = transform; 177 | pointObject.transform.position = position; 178 | 179 | BezierPoint newPoint = pointObject.AddComponent(); 180 | newPoint.curve = this; 181 | 182 | return newPoint; 183 | } 184 | 185 | /// 186 | /// - Removes the given point from the curve ("points" array) 187 | /// 188 | /// 189 | /// - The point to remove 190 | /// 191 | public void RemovePoint(BezierPoint point) 192 | { 193 | List tempArray = new List(points); 194 | tempArray.Remove(point); 195 | points = tempArray.ToArray(); 196 | dirty = false; 197 | } 198 | 199 | /// 200 | /// - Gets a copy of the bezier point array used to define this curve 201 | /// 202 | /// 203 | /// - The cloned array of points 204 | /// 205 | public BezierPoint[] GetAnchorPoints() 206 | { 207 | return (BezierPoint[])points.Clone(); 208 | } 209 | 210 | /// 211 | /// - Gets the point at 't' percent along this curve 212 | /// 213 | /// 214 | /// - Returns the point at 't' percent 215 | /// 216 | /// 217 | /// - Value between 0 and 1 representing the percent along the curve (0 = 0%, 1 = 100%) 218 | /// 219 | public Vector3 GetPointAt(float t) 220 | { 221 | if(t <= 0) return points[0].position; 222 | else if (t >= 1) return points[points.Length - 1].position; 223 | 224 | float totalPercent = 0; 225 | float curvePercent = 0; 226 | 227 | BezierPoint p1 = null; 228 | BezierPoint p2 = null; 229 | 230 | for(int i = 0; i < points.Length - 1; i++) 231 | { 232 | curvePercent = ApproximateLength(points[i], points[i + 1], 10) / length; 233 | if(totalPercent + curvePercent > t) 234 | { 235 | p1 = points[i]; 236 | p2 = points[i + 1]; 237 | break; 238 | } 239 | 240 | else totalPercent += curvePercent; 241 | } 242 | 243 | if(close && p1 == null) 244 | { 245 | p1 = points[points.Length - 1]; 246 | p2 = points[0]; 247 | } 248 | 249 | t -= totalPercent; 250 | 251 | return GetPoint(p1, p2, t / curvePercent); 252 | } 253 | 254 | /// 255 | /// - Get the index of the given point in this curve 256 | /// 257 | /// 258 | /// - The index, or -1 if the point is not found 259 | /// 260 | /// 261 | /// - Point to search for 262 | /// 263 | public int GetPointIndex(BezierPoint point) 264 | { 265 | int result = -1; 266 | for(int i = 0; i < points.Length; i++) 267 | { 268 | if(points[i] == point) 269 | { 270 | result = i; 271 | break; 272 | } 273 | } 274 | 275 | return result; 276 | } 277 | 278 | /// 279 | /// - Sets this curve to 'dirty' 280 | /// - Forces the curve to recalculate its length 281 | /// 282 | public void SetDirty() 283 | { 284 | dirty = true; 285 | } 286 | 287 | #endregion 288 | 289 | #region PublicStaticFunctions 290 | 291 | /// 292 | /// - Draws the curve in the Editor 293 | /// 294 | /// 295 | /// - The bezier point at the beginning of the curve 296 | /// 297 | /// 298 | /// - The bezier point at the end of the curve 299 | /// 300 | /// 301 | /// - The number of segments along the curve to draw 302 | /// 303 | public static void DrawCurve(BezierPoint p1, BezierPoint p2, int resolution) 304 | { 305 | int limit = resolution+1; 306 | float _res = resolution; 307 | Vector3 lastPoint = p1.position; 308 | Vector3 currentPoint = Vector3.zero; 309 | 310 | for(int i = 1; i < limit; i++){ 311 | currentPoint = GetPoint(p1, p2, i/_res); 312 | Gizmos.DrawLine(lastPoint, currentPoint); 313 | lastPoint = currentPoint; 314 | } 315 | } 316 | 317 | /// 318 | /// - Gets the point 't' percent along a curve 319 | /// - Automatically calculates for the number of relevant points 320 | /// 321 | /// 322 | /// - The point 't' percent along the curve 323 | /// 324 | /// 325 | /// - The bezier point at the beginning of the curve 326 | /// 327 | /// 328 | /// - The bezier point at the end of the curve 329 | /// 330 | /// 331 | /// - Value between 0 and 1 representing the percent along the curve (0 = 0%, 1 = 100%) 332 | /// 333 | public static Vector3 GetPoint(BezierPoint p1, BezierPoint p2, float t) 334 | { 335 | if(p1.handle2 != Vector3.zero) 336 | { 337 | if(p2.handle1 != Vector3.zero) return GetCubicCurvePoint(p1.position, p1.globalHandle2, p2.globalHandle1, p2.position, t); 338 | else return GetQuadraticCurvePoint(p1.position, p1.globalHandle2, p2.position, t); 339 | } 340 | 341 | else 342 | { 343 | if(p2.handle1 != Vector3.zero) return GetQuadraticCurvePoint(p1.position, p2.globalHandle1, p2.position, t); 344 | else return GetLinearPoint(p1.position, p2.position, t); 345 | } 346 | } 347 | 348 | /// 349 | /// - Gets the point 't' percent along a third-order curve 350 | /// 351 | /// 352 | /// - The point 't' percent along the curve 353 | /// 354 | /// 355 | /// - The point at the beginning of the curve 356 | /// 357 | /// 358 | /// - The second point along the curve 359 | /// 360 | /// 361 | /// - The third point along the curve 362 | /// 363 | /// 364 | /// - The point at the end of the curve 365 | /// 366 | /// 367 | /// - Value between 0 and 1 representing the percent along the curve (0 = 0%, 1 = 100%) 368 | /// 369 | public static Vector3 GetCubicCurvePoint(Vector3 p1, Vector3 p2, Vector3 p3, Vector3 p4, float t) 370 | { 371 | t = Mathf.Clamp01(t); 372 | 373 | Vector3 part1 = Mathf.Pow(1 - t, 3) * p1; 374 | Vector3 part2 = 3 * Mathf.Pow(1 - t, 2) * t * p2; 375 | Vector3 part3 = 3 * (1 - t) * Mathf.Pow(t, 2) * p3; 376 | Vector3 part4 = Mathf.Pow(t, 3) * p4; 377 | 378 | return part1 + part2 + part3 + part4; 379 | } 380 | 381 | /// 382 | /// - Gets the point 't' percent along a second-order curve 383 | /// 384 | /// 385 | /// - The point 't' percent along the curve 386 | /// 387 | /// 388 | /// - The point at the beginning of the curve 389 | /// 390 | /// 391 | /// - The second point along the curve 392 | /// 393 | /// 394 | /// - The point at the end of the curve 395 | /// 396 | /// 397 | /// - Value between 0 and 1 representing the percent along the curve (0 = 0%, 1 = 100%) 398 | /// 399 | public static Vector3 GetQuadraticCurvePoint(Vector3 p1, Vector3 p2, Vector3 p3, float t) 400 | { 401 | t = Mathf.Clamp01(t); 402 | 403 | Vector3 part1 = Mathf.Pow(1 - t, 2) * p1; 404 | Vector3 part2 = 2 * (1 - t) * t * p2; 405 | Vector3 part3 = Mathf.Pow(t, 2) * p3; 406 | 407 | return part1 + part2 + part3; 408 | } 409 | 410 | /// 411 | /// - Gets point 't' percent along a linear "curve" (line) 412 | /// - This is exactly equivalent to Vector3.Lerp 413 | /// 414 | /// 415 | /// - The point 't' percent along the curve 416 | /// 417 | /// 418 | /// - The point at the beginning of the line 419 | /// 420 | /// 421 | /// - The point at the end of the line 422 | /// 423 | /// 424 | /// - Value between 0 and 1 representing the percent along the line (0 = 0%, 1 = 100%) 425 | /// 426 | public static Vector3 GetLinearPoint(Vector3 p1, Vector3 p2, float t) 427 | { 428 | return p1 + ((p2 - p1) * t); 429 | } 430 | 431 | /// 432 | /// - Gets point 't' percent along n-order curve 433 | /// 434 | /// 435 | /// - The point 't' percent along the curve 436 | /// 437 | /// 438 | /// - Value between 0 and 1 representing the percent along the curve (0 = 0%, 1 = 100%) 439 | /// 440 | /// 441 | /// - The points used to define the curve 442 | /// 443 | public static Vector3 GetPoint(float t, params Vector3[] points){ 444 | t = Mathf.Clamp01(t); 445 | 446 | int order = points.Length-1; 447 | Vector3 point = Vector3.zero; 448 | Vector3 vectorToAdd; 449 | 450 | for(int i = 0; i < points.Length; i++){ 451 | vectorToAdd = points[points.Length-i-1] * (BinomialCoefficient(i, order) * Mathf.Pow(t, order-i) * Mathf.Pow((1-t), i)); 452 | point += vectorToAdd; 453 | } 454 | 455 | return point; 456 | } 457 | 458 | /// 459 | /// - Approximates the length 460 | /// 461 | /// 462 | /// - The approximate length 463 | /// 464 | /// 465 | /// - The bezier point at the start of the curve 466 | /// 467 | /// 468 | /// - The bezier point at the end of the curve 469 | /// 470 | /// 471 | /// - The number of points along the curve used to create measurable segments 472 | /// 473 | public static float ApproximateLength(BezierPoint p1, BezierPoint p2, int resolution = 10) 474 | { 475 | float _res = resolution; 476 | float total = 0; 477 | Vector3 lastPosition = p1.position; 478 | Vector3 currentPosition; 479 | 480 | for(int i = 0; i < resolution + 1; i++) 481 | { 482 | currentPosition = GetPoint(p1, p2, i / _res); 483 | total += (currentPosition - lastPosition).magnitude; 484 | lastPosition = currentPosition; 485 | } 486 | 487 | return total; 488 | } 489 | 490 | #endregion 491 | 492 | #region UtilityFunctions 493 | 494 | private static int BinomialCoefficient(int i, int n){ 495 | return Factoral(n)/(Factoral(i)*Factoral(n-i)); 496 | } 497 | 498 | private static int Factoral(int i){ 499 | if(i == 0) return 1; 500 | 501 | int total = 1; 502 | 503 | while(i-1 >= 0){ 504 | total *= i; 505 | i--; 506 | } 507 | 508 | return total; 509 | } 510 | 511 | #endregion 512 | 513 | /* needs testing 514 | public Vector3 GetPointAtDistance(float distance) 515 | { 516 | if(close) 517 | { 518 | if(distance < 0) while(distance < 0) { distance += length; } 519 | else if(distance > length) while(distance > length) { distance -= length; } 520 | } 521 | 522 | else 523 | { 524 | if(distance <= 0) return points[0].position; 525 | else if(distance >= length) return points[points.Length - 1].position; 526 | } 527 | 528 | float totalLength = 0; 529 | float curveLength = 0; 530 | 531 | BezierPoint firstPoint = null; 532 | BezierPoint secondPoint = null; 533 | 534 | for(int i = 0; i < points.Length - 1; i++) 535 | { 536 | curveLength = ApproximateLength(points[i], points[i + 1], resolution); 537 | if(totalLength + curveLength >= distance) 538 | { 539 | firstPoint = points[i]; 540 | secondPoint = points[i+1]; 541 | break; 542 | } 543 | else totalLength += curveLength; 544 | } 545 | 546 | if(firstPoint == null) 547 | { 548 | firstPoint = points[points.Length - 1]; 549 | secondPoint = points[0]; 550 | curveLength = ApproximateLength(firstPoint, secondPoint, resolution); 551 | } 552 | 553 | distance -= totalLength; 554 | return GetPoint(distance / curveLength, firstPoint, secondPoint); 555 | } 556 | */ 557 | } -------------------------------------------------------------------------------- /Assets/BezierCurves/Scripts/BezierCurve.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 4234cd2c43978e041bbe9323c195c4bd 3 | timeCreated: 18446744011573954816 4 | MonoImporter: 5 | externalObjects: {} 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/BezierCurves/Scripts/BezierPoint.cs: -------------------------------------------------------------------------------- 1 | #region UsingStatements 2 | 3 | using UnityEngine; 4 | using System; 5 | using System.Collections; 6 | 7 | #endregion 8 | 9 | /// 10 | /// - Helper class for storing and manipulating Bezier Point data 11 | /// - Ensures that handles are in correct relation to one another 12 | /// - Handles adding/removing self from curve point lists 13 | /// - Calls SetDirty() on curve when edited 14 | /// 15 | [Serializable] 16 | public class BezierPoint : MonoBehaviour{ 17 | 18 | #region PublicEnumerations 19 | 20 | /// 21 | /// - Enumeration describing the relationship between a point's handles 22 | /// - Connected : The point's handles are mirrored across the point 23 | /// - Broken : Each handle moves independently of the other 24 | /// - None : This point has no handles (both handles are located ON the point) 25 | /// 26 | public enum HandleStyle 27 | { 28 | Connected, 29 | Broken, 30 | None, 31 | } 32 | 33 | #endregion 34 | 35 | #region PublicProperties 36 | 37 | /// 38 | /// - Curve this point belongs to 39 | /// - Changing this value will automatically remove this point from the current curve and add it to the new one 40 | /// 41 | [SerializeField] 42 | private BezierCurve _curve; 43 | public BezierCurve curve 44 | { 45 | get{return _curve;} 46 | set 47 | { 48 | if(_curve) _curve.RemovePoint(this); 49 | _curve = value; 50 | _curve.AddPoint(this); 51 | } 52 | } 53 | 54 | /// 55 | /// - Value describing the relationship between this point's handles 56 | /// 57 | public HandleStyle handleStyle; 58 | 59 | /// 60 | /// - Shortcut to transform.position 61 | /// 62 | /// 63 | /// - The point's world position 64 | /// 65 | public Vector3 position 66 | { 67 | get { return transform.position; } 68 | set { transform.position = value; } 69 | } 70 | 71 | /// 72 | /// - Shortcut to transform.localPosition 73 | /// 74 | /// 75 | /// - The point's local position. 76 | /// 77 | public Vector3 localPosition 78 | { 79 | get { return transform.localPosition; } 80 | set { transform.localPosition = value; } 81 | } 82 | 83 | /// 84 | /// - Local position of the first handle 85 | /// - Setting this value will cause the curve to become dirty 86 | /// - This handle effects the curve generated from this point and the point proceeding it in curve.points 87 | /// 88 | [SerializeField] 89 | private Vector3 _handle1; 90 | public Vector3 handle1 91 | { 92 | get { return _handle1; } 93 | set 94 | { 95 | if(_handle1 == value) return; 96 | _handle1 = value; 97 | if(handleStyle == HandleStyle.None) handleStyle = HandleStyle.Broken; 98 | else if(handleStyle == HandleStyle.Connected) _handle2 = -value; 99 | _curve.SetDirty(); 100 | } 101 | } 102 | 103 | /// 104 | /// - Global position of the first handle 105 | /// - Ultimately stored in the 'handle1' variable 106 | /// - Setting this value will cause the curve to become dirty 107 | /// - This handle effects the curve generated from this point and the point proceeding it in curve.points 108 | /// 109 | public Vector3 globalHandle1 110 | { 111 | get{return transform.TransformPoint(handle1);} 112 | set{handle1 = transform.InverseTransformPoint(value);} 113 | } 114 | 115 | /// 116 | /// - Local position of the second handle 117 | /// - Setting this value will cause the curve to become dirty 118 | /// - This handle effects the curve generated from this point and the point coming after it in curve.points 119 | /// 120 | [SerializeField] 121 | private Vector3 _handle2; 122 | public Vector3 handle2 123 | { 124 | get { return _handle2; } 125 | set 126 | { 127 | if(_handle2 == value) return; 128 | _handle2 = value; 129 | if(handleStyle == HandleStyle.None) handleStyle = HandleStyle.Broken; 130 | else if(handleStyle == HandleStyle.Connected) _handle1 = -value; 131 | _curve.SetDirty(); 132 | } 133 | } 134 | 135 | /// 136 | /// - Global position of the second handle 137 | /// - Ultimately stored in the 'handle2' variable 138 | /// - Setting this value will cause the curve to become dirty 139 | /// - This handle effects the curve generated from this point and the point coming after it in curve.points 140 | /// 141 | public Vector3 globalHandle2 142 | { 143 | get{return transform.TransformPoint(handle2);} 144 | set{handle2 = transform.InverseTransformPoint(value);} 145 | } 146 | 147 | #endregion 148 | 149 | #region PrivateVariables 150 | 151 | /// 152 | /// - Used to determine if this point has moved since the last frame 153 | /// 154 | private Vector3 lastPosition; 155 | 156 | #endregion 157 | 158 | #region MonoBehaviourFunctions 159 | 160 | void Update() 161 | { 162 | if(!_curve.dirty && transform.position != lastPosition) 163 | { 164 | _curve.SetDirty(); 165 | lastPosition = transform.position; 166 | } 167 | } 168 | 169 | #endregion 170 | } 171 | -------------------------------------------------------------------------------- /Assets/BezierCurves/Scripts/BezierPoint.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1dff893e341592e438963ea8cbceb377 3 | timeCreated: 18446744011573954816 4 | MonoImporter: 5 | externalObjects: {} 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/BezierCurves/readme.txt: -------------------------------------------------------------------------------- 1 | Product : Bezier Curve Editor Package 2 | Studio : Arkham Interactive 3 | Date : September 9th, 2013 4 | Version : 1.0 5 | Email : support@arkhaminteractive.com 6 | 7 | How to use: 8 | 1) Add BezierCurve package to your Unity project 9 | 2a) Add BezierCurve.cs script from Assets/BezierCurves/Scripts to any object 10 | 2b) Alternatively, select GameObject/Create Other/Bezier Curve 11 | 3) Use "Add Point" button to add bezier points to the curve 12 | 4) Use "X" button to remove bezier points from the curve 13 | 5) Use "/\" or "\/" to move points up or down in the curve order 14 | 15 | - The BezierCurve class also contains static functions used for getting points on first, second, and third order bezier curves. 16 | - These functions take the positions of the anchor points as arguments. 17 | - Instances of the BezierCurve object use these same functions to calculate positions. -------------------------------------------------------------------------------- /Assets/BezierCurves/readme.txt.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1c019e87c4c680d4ba6e2fb138a2e1ee 3 | timeCreated: 18446744011573954816 4 | TextScriptImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/CurveModifier.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 73046806497d08b46b07e413d27405ee 3 | folderAsset: yes 4 | timeCreated: 1519043037 5 | licenseType: Free 6 | DefaultImporter: 7 | externalObjects: {} 8 | userData: 9 | assetBundleName: 10 | assetBundleVariant: 11 | -------------------------------------------------------------------------------- /Assets/CurveModifier/Materials.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e6b3d1db98b548a4997e4e813515fe9b 3 | folderAsset: yes 4 | timeCreated: 1462837566 5 | licenseType: Free 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/CurveModifier/Materials/Dragon Curve Modifier.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leon196/CurveModifier/adcd27ae180c31bf5ce01896009a4c0b9aeb7a40/Assets/CurveModifier/Materials/Dragon Curve Modifier.mat -------------------------------------------------------------------------------- /Assets/CurveModifier/Materials/Dragon Curve Modifier.mat.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f03637ad2b34c834ca266c80c56f880c 3 | timeCreated: 1465338802 4 | licenseType: Free 5 | NativeFormatImporter: 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/CurveModifier/Materials/Dragon Curve Offset.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leon196/CurveModifier/adcd27ae180c31bf5ce01896009a4c0b9aeb7a40/Assets/CurveModifier/Materials/Dragon Curve Offset.mat -------------------------------------------------------------------------------- /Assets/CurveModifier/Materials/Dragon Curve Offset.mat.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 561ab3e4f88f3054e8cecf76955c7b13 3 | timeCreated: 1465520184 4 | licenseType: Free 5 | NativeFormatImporter: 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/CurveModifier/Materials/Dragon Curve.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leon196/CurveModifier/adcd27ae180c31bf5ce01896009a4c0b9aeb7a40/Assets/CurveModifier/Materials/Dragon Curve.mat -------------------------------------------------------------------------------- /Assets/CurveModifier/Materials/Dragon Curve.mat.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c3afd4caf928adf409a7326c679db4eb 3 | timeCreated: 1465338802 4 | licenseType: Free 5 | NativeFormatImporter: 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/CurveModifier/Meshes.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d371661d826adb549b33b13b891155bc 3 | folderAsset: yes 4 | timeCreated: 1465247153 5 | licenseType: Free 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/CurveModifier/Meshes/Dragon.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 2d4368e8272b1734b94174ae3a3d5d9b 3 | folderAsset: yes 4 | timeCreated: 1465328971 5 | licenseType: Free 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/CurveModifier/Meshes/Dragon/Dragon.fbx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leon196/CurveModifier/adcd27ae180c31bf5ce01896009a4c0b9aeb7a40/Assets/CurveModifier/Meshes/Dragon/Dragon.fbx -------------------------------------------------------------------------------- /Assets/CurveModifier/Meshes/Dragon/Dragon.fbx.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a630d2ed28b5c684abf8d54ebe017623 3 | timeCreated: 1465328982 4 | licenseType: Free 5 | ModelImporter: 6 | serializedVersion: 19 7 | fileIDToRecycleName: 8 | 100000: //RootNode 9 | 400000: //RootNode 10 | 2300000: //RootNode 11 | 3300000: //RootNode 12 | 4300000: Dragon With Pearl 13 | materials: 14 | importMaterials: 1 15 | materialName: 0 16 | materialSearch: 1 17 | animations: 18 | legacyGenerateAnimations: 4 19 | bakeSimulation: 0 20 | resampleRotations: 1 21 | optimizeGameObjects: 0 22 | motionNodeName: 23 | animationImportErrors: 24 | animationImportWarnings: 25 | animationRetargetingWarnings: 26 | animationDoRetargetingWarnings: 0 27 | animationCompression: 1 28 | animationRotationError: 0.5 29 | animationPositionError: 0.5 30 | animationScaleError: 0.5 31 | animationWrapMode: 0 32 | extraExposedTransformPaths: [] 33 | clipAnimations: [] 34 | isReadable: 1 35 | meshes: 36 | lODScreenPercentages: [] 37 | globalScale: 100 38 | meshCompression: 0 39 | addColliders: 0 40 | importBlendShapes: 1 41 | swapUVChannels: 0 42 | generateSecondaryUV: 0 43 | useFileUnits: 1 44 | optimizeMeshForGPU: 1 45 | keepQuads: 0 46 | weldVertices: 1 47 | secondaryUVAngleDistortion: 8 48 | secondaryUVAreaDistortion: 15.000001 49 | secondaryUVHardAngle: 88 50 | secondaryUVPackMargin: 4 51 | useFileScale: 1 52 | tangentSpace: 53 | normalSmoothAngle: 60 54 | normalImportMode: 0 55 | tangentImportMode: 3 56 | importAnimation: 1 57 | copyAvatar: 0 58 | humanDescription: 59 | human: [] 60 | skeleton: [] 61 | armTwist: 0.5 62 | foreArmTwist: 0.5 63 | upperLegTwist: 0.5 64 | legTwist: 0.5 65 | armStretch: 0.05 66 | legStretch: 0.05 67 | feetSpacing: 0 68 | rootMotionBoneName: 69 | hasTranslationDoF: 0 70 | lastHumanDescriptionAvatarSource: {instanceID: 0} 71 | animationType: 0 72 | humanoidOversampling: 1 73 | additionalBone: 0 74 | userData: 75 | assetBundleName: 76 | assetBundleVariant: 77 | -------------------------------------------------------------------------------- /Assets/CurveModifier/Meshes/Dragon/Dragon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leon196/CurveModifier/adcd27ae180c31bf5ce01896009a4c0b9aeb7a40/Assets/CurveModifier/Meshes/Dragon/Dragon.png -------------------------------------------------------------------------------- /Assets/CurveModifier/Meshes/Dragon/Dragon.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 637053d2dece3c546b35b875e739c2a4 3 | timeCreated: 1465328973 4 | licenseType: Free 5 | TextureImporter: 6 | fileIDToRecycleName: {} 7 | serializedVersion: 2 8 | mipmaps: 9 | mipMapMode: 0 10 | enableMipMap: 1 11 | linearTexture: 0 12 | correctGamma: 0 13 | fadeOut: 0 14 | borderMipMap: 0 15 | mipMapFadeDistanceStart: 1 16 | mipMapFadeDistanceEnd: 3 17 | bumpmap: 18 | convertToNormalMap: 0 19 | externalNormalMap: 0 20 | heightScale: 0.25 21 | normalMapFilter: 0 22 | isReadable: 0 23 | grayScaleToAlpha: 0 24 | generateCubemap: 0 25 | cubemapConvolution: 0 26 | cubemapConvolutionSteps: 7 27 | cubemapConvolutionExponent: 1.5 28 | seamlessCubemap: 0 29 | textureFormat: -1 30 | maxTextureSize: 2048 31 | textureSettings: 32 | filterMode: -1 33 | aniso: -1 34 | mipBias: -1 35 | wrapMode: -1 36 | nPOTScale: 1 37 | lightmap: 0 38 | rGBM: 0 39 | compressionQuality: 50 40 | allowsAlphaSplitting: 0 41 | spriteMode: 0 42 | spriteExtrude: 1 43 | spriteMeshType: 1 44 | alignment: 0 45 | spritePivot: {x: 0.5, y: 0.5} 46 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 47 | spritePixelsToUnits: 100 48 | alphaIsTransparency: 0 49 | textureType: -1 50 | buildTargetSettings: [] 51 | spriteSheet: 52 | sprites: [] 53 | outline: [] 54 | spritePackingTag: 55 | userData: 56 | assetBundleName: 57 | assetBundleVariant: 58 | -------------------------------------------------------------------------------- /Assets/CurveModifier/Meshes/Dragon/Materials.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 265d617ed3bb2214eb5c209adbea2daa 3 | folderAsset: yes 4 | timeCreated: 1465328982 5 | licenseType: Free 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/CurveModifier/Meshes/Dragon/Materials/No Name.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leon196/CurveModifier/adcd27ae180c31bf5ce01896009a4c0b9aeb7a40/Assets/CurveModifier/Meshes/Dragon/Materials/No Name.mat -------------------------------------------------------------------------------- /Assets/CurveModifier/Meshes/Dragon/Materials/No Name.mat.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1c5e5a7508c758d45a049287afccb5cd 3 | timeCreated: 1465333091 4 | licenseType: Free 5 | NativeFormatImporter: 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/CurveModifier/Meshes/Dragon/credits.txt: -------------------------------------------------------------------------------- 1 | Dragon with pearl by Artec 3D is licensed under CC Attribution-ShareAlike 2 | https://skfb.ly/M7sW -------------------------------------------------------------------------------- /Assets/CurveModifier/Meshes/Dragon/credits.txt.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c09f03109cc93d1458efe33b55981db2 3 | timeCreated: 1465349040 4 | licenseType: Free 5 | TextScriptImporter: 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/CurveModifier/Scenes.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6ee5b7cca05489a43960b68474c89bcd 3 | folderAsset: yes 4 | timeCreated: 1465247292 5 | licenseType: Free 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/CurveModifier/Scenes/BezierExample.unity: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leon196/CurveModifier/adcd27ae180c31bf5ce01896009a4c0b9aeb7a40/Assets/CurveModifier/Scenes/BezierExample.unity -------------------------------------------------------------------------------- /Assets/CurveModifier/Scenes/BezierExample.unity.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c64971c079194c84a9d9d724ab3fb2e4 3 | timeCreated: 1465338787 4 | licenseType: Free 5 | DefaultImporter: 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/CurveModifier/Scenes/FollowExample.unity: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leon196/CurveModifier/adcd27ae180c31bf5ce01896009a4c0b9aeb7a40/Assets/CurveModifier/Scenes/FollowExample.unity -------------------------------------------------------------------------------- /Assets/CurveModifier/Scenes/FollowExample.unity.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e46d0d735e2e9cd48a0f6d6f3e623b30 3 | timeCreated: 1465260117 4 | licenseType: Free 5 | DefaultImporter: 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/CurveModifier/Scenes/ScriptExample.unity: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leon196/CurveModifier/adcd27ae180c31bf5ce01896009a4c0b9aeb7a40/Assets/CurveModifier/Scenes/ScriptExample.unity -------------------------------------------------------------------------------- /Assets/CurveModifier/Scenes/ScriptExample.unity.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1aa57fc8ddcbeda4e94657b9ec5765b4 3 | timeCreated: 1465340320 4 | licenseType: Free 5 | DefaultImporter: 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/CurveModifier/Scripts.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b6427cf0fc236014ea025c72d9735641 3 | folderAsset: yes 4 | timeCreated: 1465247153 5 | licenseType: Free 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/CurveModifier/Scripts/CurveModifier.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System.Collections; 3 | 4 | public class CurveModifier : MonoBehaviour 5 | { 6 | public enum CurveAxis { XYZ, XZY, ZYX }; 7 | 8 | public int resolution = 32; 9 | public bool shouldUpdate = true; 10 | public bool showCurve = false; 11 | public bool curveLoop = false; 12 | public bool inverseCurve = false; 13 | public CurveAxis curveAxis = CurveAxis.XYZ; 14 | public float cycleOffset = 0f; 15 | public float cycleTimeScale = 0f; 16 | public float curveScale = 1f; 17 | public float planarScale = 1f; 18 | 19 | protected Texture2D texture; 20 | protected Color[] colorArray; 21 | protected Vector3[] vectorArray; 22 | protected Renderer[] rendererArray; 23 | protected MeshFilter[] meshFilterArray; 24 | 25 | private Vector3 forward = Vector3.forward; 26 | private Vector3 up = Vector3.up; 27 | private Vector3 right = Vector3.right; 28 | 29 | public void Init () 30 | { 31 | texture = new Texture2D(resolution, 1, TextureFormat.RGBAFloat, false); 32 | colorArray = new Color[resolution]; 33 | vectorArray = new Vector3[resolution]; 34 | rendererArray = GetComponentsInChildren(); 35 | meshFilterArray = GetComponentsInChildren(); 36 | CurveToTexture(); 37 | } 38 | 39 | public virtual Vector3 GetCurvePoint (float ratio) 40 | { 41 | if (vectorArray != null) { 42 | return vectorArray[(int)Mathf.Clamp(Mathf.Floor(vectorArray.Length * ratio), 0f, vectorArray.Length - 1)]; 43 | } else { 44 | return Vector3.zero; 45 | } 46 | } 47 | 48 | public Vector3 GetCurveCenter () 49 | { 50 | Vector3 center = Vector3.zero; 51 | for (int i = 0; i < resolution; ++i) { 52 | center += GetCurvePoint(i / (float)resolution); 53 | } 54 | return center / (float)resolution; 55 | } 56 | 57 | public Vector3 GetCurveSize () 58 | { 59 | Vector3 center = GetCurveCenter(); 60 | Vector3 size = Vector3.one * -Mathf.Infinity; 61 | for (int i = 0; i < resolution; ++i) { 62 | Vector3 point = GetCurvePoint(i / (float)resolution) - center; 63 | size.x = Mathf.Max(size.x, Mathf.Abs(point.x)); 64 | size.y = Mathf.Max(size.y, Mathf.Abs(point.y)); 65 | size.z = Mathf.Max(size.z, Mathf.Abs(point.z)); 66 | } 67 | return size * 2f; 68 | } 69 | 70 | public void CurveToTexture () 71 | { 72 | if (texture != null) 73 | { 74 | int i = 0; 75 | Vector3 p; 76 | for (i = 0; i < resolution; ++i) { 77 | p = GetCurvePoint(i / (float)resolution); 78 | colorArray[i].r = p.x; 79 | colorArray[i].g = p.y; 80 | colorArray[i].b = p.z; 81 | } 82 | 83 | texture.SetPixels(colorArray); 84 | texture.Apply(); 85 | 86 | SetupAxis(); 87 | 88 | if (meshFilterArray != null) 89 | { 90 | foreach (MeshFilter meshFilter in meshFilterArray) 91 | { 92 | Bounds bounds = meshFilter.sharedMesh.bounds; 93 | bounds.center = Vector3.zero; 94 | bounds.size = GetCurveSize(); 95 | meshFilter.sharedMesh.bounds = bounds; 96 | } 97 | } 98 | } 99 | 100 | if (rendererArray != null) 101 | { 102 | foreach (Renderer renderer in rendererArray) 103 | { 104 | foreach (Material material in renderer.sharedMaterials) 105 | { 106 | material.SetTexture("_CurveTexture", texture); 107 | material.SetFloat("_CurveResolution", resolution); 108 | material.SetFloat("_ShouldLoop", curveLoop ? 1f : 0f); 109 | material.SetFloat("_ShouldInverse", inverseCurve ? 1f : 0f); 110 | material.SetFloat("_CycleOffset", cycleOffset); 111 | material.SetFloat("_CycleTime", 100f + Time.time * cycleTimeScale / 10f); 112 | material.SetFloat("_CurveScale", curveScale); 113 | material.SetFloat("_PlanarScale", planarScale); 114 | material.SetVector("_Forward", forward); 115 | material.SetVector("_Up", up); 116 | material.SetVector("_Right", right); 117 | } 118 | } 119 | } 120 | } 121 | 122 | void SetupAxis () 123 | { 124 | switch (curveAxis) 125 | { 126 | case CurveAxis.XYZ : 127 | { 128 | forward = Vector3.forward; 129 | up = Vector3.up; 130 | right = Vector3.right; 131 | break; 132 | } 133 | case CurveAxis.XZY : 134 | { 135 | forward = Vector3.up; 136 | up = Vector3.forward; 137 | right = Vector3.right; 138 | break; 139 | } 140 | case CurveAxis.ZYX : 141 | { 142 | forward = Vector3.right; 143 | up = Vector3.up; 144 | right = Vector3.forward; 145 | break; 146 | } 147 | } 148 | } 149 | 150 | public virtual float GetCurveLength () 151 | { 152 | float dist = 0f; 153 | Vector3 from, to; 154 | for(int i = 0; i < resolution - 1; i++) 155 | { 156 | from = GetCurvePoint(i / (float)resolution); 157 | to = GetCurvePoint((i + 1) / (float)resolution); 158 | dist += Vector3.Distance(from, to); 159 | } 160 | return dist; 161 | } 162 | 163 | void OnDrawGizmos () 164 | { 165 | if (showCurve) 166 | { 167 | float res = resolution - 1; 168 | Vector3 from = Vector3.zero; 169 | Vector3 to = Vector3.zero; 170 | Gizmos.color = Color.red; 171 | for (int i = 0; i < resolution - 1; ++i) { 172 | from = GetCurvePoint(i / (float)res); 173 | to = GetCurvePoint(((i+1) / (float)res)); 174 | 175 | Gizmos.DrawLine(from, to); 176 | Gizmos.DrawLine(from, from + Vector3.Cross(from.normalized, to.normalized).normalized); 177 | } 178 | 179 | Gizmos.color = Color.yellow; 180 | if (meshFilterArray != null) 181 | { 182 | foreach (MeshFilter meshFilter in meshFilterArray) 183 | { 184 | Bounds bounds = meshFilter.sharedMesh.bounds; 185 | Gizmos.DrawWireCube(GetCurveCenter() + bounds.center, bounds.size); 186 | } 187 | } 188 | } 189 | } 190 | } 191 | -------------------------------------------------------------------------------- /Assets/CurveModifier/Scripts/CurveModifier.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 983151a4748534d44bd25caa1d0aa664 3 | timeCreated: 1465319753 4 | licenseType: Free 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/CurveModifier/Scripts/Examples.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: dab7c93a9a14360448a90801a437fb20 3 | folderAsset: yes 4 | timeCreated: 1465340348 5 | licenseType: Free 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/CurveModifier/Scripts/Examples/BezierCurveModifier.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System.Collections; 3 | 4 | [ExecuteInEditMode] 5 | public class BezierCurveModifier : CurveModifier 6 | { 7 | public BezierCurve bezierCurve; 8 | 9 | void OnEnable () 10 | { 11 | if (bezierCurve != null) { 12 | resolution = bezierCurve.resolution; 13 | Init(); 14 | CurveToTexture(); 15 | } 16 | } 17 | 18 | public override Vector3 GetCurvePoint (float ratio) 19 | { 20 | if (bezierCurve != null) { 21 | return bezierCurve.GetPointAt(ratio); 22 | } else { 23 | return Vector3.zero; 24 | } 25 | } 26 | 27 | public override float GetCurveLength () 28 | { 29 | if (bezierCurve != null) { 30 | return bezierCurve.length; 31 | } else { 32 | return base.GetCurveLength(); 33 | } 34 | } 35 | 36 | void OnRenderObject () 37 | { 38 | if (shouldUpdate) 39 | { 40 | if (vectorArray != null && vectorArray.Length != resolution) 41 | { 42 | Init(); 43 | } 44 | 45 | CurveToTexture(); 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /Assets/CurveModifier/Scripts/Examples/BezierCurveModifier.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 4a944f34418b8a94ea9b9df1f7e80813 3 | timeCreated: 1465247382 4 | licenseType: Free 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/CurveModifier/Scripts/Examples/FollowCurveModifier.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System.Collections; 3 | 4 | [ExecuteInEditMode] 5 | public class FollowCurveModifier : CurveModifier 6 | { 7 | public Transform target; 8 | public float deltaScale = 10f; 9 | public float minimumDistance = 0.1f; 10 | public float maximumDistance = 1f; 11 | 12 | void OnEnable () 13 | { 14 | Init(); 15 | } 16 | 17 | void OnRenderObject () 18 | { 19 | if (shouldUpdate && target != null) 20 | { 21 | if (vectorArray.Length == resolution) 22 | { 23 | vectorArray[resolution - 1] = target.position; 24 | for (int i = 0; i < resolution - 1; ++i) 25 | { 26 | float ratio = Mathf.Clamp(Time.deltaTime * deltaScale, 0f, 1f); 27 | if (Vector3.Distance(vectorArray[i], vectorArray[i + 1]) > maximumDistance) 28 | { 29 | vectorArray[i] = vectorArray[i + 1] + maximumDistance * Vector3.Normalize(vectorArray[i] - vectorArray[i + 1]); 30 | } 31 | else if (Vector3.Distance(vectorArray[i], vectorArray[i + 1]) < minimumDistance) 32 | { 33 | vectorArray[i] = vectorArray[i + 1] + minimumDistance * Vector3.Normalize(vectorArray[i] - vectorArray[i + 1]); 34 | } 35 | else 36 | { 37 | vectorArray[i] = Vector3.Lerp(vectorArray[i], vectorArray[i + 1], ratio); 38 | } 39 | } 40 | } 41 | else 42 | { 43 | Init(); 44 | } 45 | 46 | CurveToTexture(); 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /Assets/CurveModifier/Scripts/Examples/FollowCurveModifier.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: aef0c75a64779c246b86c199a61d5d5e 3 | timeCreated: 1465262725 4 | licenseType: Free 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/CurveModifier/Scripts/Examples/ScriptCurveModifier.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System.Collections; 3 | 4 | [ExecuteInEditMode] 5 | public class ScriptCurveModifier : CurveModifier 6 | { 7 | public float radius = 10f; 8 | public float height = 1f; 9 | 10 | void OnEnable () 11 | { 12 | Init(); 13 | CurveToTexture(); 14 | } 15 | 16 | public override Vector3 GetCurvePoint (float ratio) 17 | { 18 | float angle = ratio * Mathf.PI * 2f; 19 | return new Vector3(Mathf.Cos(angle) * radius, Mathf.Sin(angle * 5) * height, Mathf.Sin(angle) * radius); 20 | } 21 | 22 | void OnRenderObject () 23 | { 24 | if (shouldUpdate) 25 | { 26 | if (vectorArray.Length != resolution) 27 | { 28 | Init(); 29 | } 30 | 31 | CurveToTexture(); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /Assets/CurveModifier/Scripts/Examples/ScriptCurveModifier.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f3a8b0890244b114290a326541add82f 3 | timeCreated: 1465340494 4 | licenseType: Free 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/CurveModifier/Scripts/Utils.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 750f65b705afd4946a58a63742ff0818 3 | folderAsset: yes 4 | timeCreated: 1465247399 5 | licenseType: Free 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/CurveModifier/Scripts/Utils/CullingBounds.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System.Collections; 3 | 4 | [ExecuteInEditMode] 5 | public class CullingBounds : MonoBehaviour 6 | { 7 | public float distance = 100f; 8 | 9 | void OnEnable () 10 | { 11 | Renderer[] rendererArray = gameObject.GetComponentsInChildren(); 12 | foreach (Renderer renderer in rendererArray) 13 | { 14 | MeshFilter meshFilter = renderer.GetComponent(); 15 | if (meshFilter != null) { 16 | meshFilter.sharedMesh.bounds = new Bounds (transform.position, Vector3.one * distance); 17 | } 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /Assets/CurveModifier/Scripts/Utils/CullingBounds.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 9d8f1fedb6061c241967aaac0096e7e6 3 | timeCreated: 1465247158 4 | licenseType: Free 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/CurveModifier/Scripts/Utils/RumbleRigidbody.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System.Collections; 3 | 4 | public class RumbleRigidbody : MonoBehaviour 5 | { 6 | public float strength = 2f; 7 | private Rigidbody[] rigidbodyArray; 8 | private float lastTime = 0f; 9 | private float delay = 1f; 10 | 11 | void Start () 12 | { 13 | rigidbodyArray = GameObject.FindObjectsOfType(); 14 | } 15 | 16 | Vector3 RandomDirection (float min, float max) 17 | { 18 | return new Vector3(Random.Range(min, max), Random.Range(min, max), Random.Range(min, max)); 19 | } 20 | 21 | void Update () 22 | { 23 | if (lastTime + delay < Time.time) { 24 | lastTime = Time.time; 25 | foreach (Rigidbody rigidbody in rigidbodyArray) { 26 | rigidbody.AddForce(RandomDirection(-strength, strength), ForceMode.Impulse); 27 | rigidbody.AddTorque(RandomDirection(-strength, strength), ForceMode.Impulse); 28 | } 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /Assets/CurveModifier/Scripts/Utils/RumbleRigidbody.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 82de81eab1524554abf804d5970ca4aa 3 | timeCreated: 1465261818 4 | licenseType: Free 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/CurveModifier/Shaders.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 862aacc7c97ea7743af790ba4809ecc5 3 | folderAsset: yes 4 | timeCreated: 1465247153 5 | licenseType: Free 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/CurveModifier/Shaders/CurveModifier.shader: -------------------------------------------------------------------------------- 1 | // Upgrade NOTE: replaced '_World2Object' with 'unity_WorldToObject' 2 | // Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)' 3 | 4 | Shader "Custom/CurveModifier" 5 | { 6 | Properties 7 | { 8 | _MainTex ("Texture", 2D) = "white" {} 9 | _Color ("Color", Color) = (1,1,1,1) 10 | } 11 | SubShader 12 | { 13 | Tags { "RenderType"="Opaque" } 14 | LOD 100 15 | Cull Off 16 | 17 | Pass { 18 | CGPROGRAM 19 | #pragma vertex vert 20 | #pragma fragment frag 21 | #pragma target 3.0 22 | #include "UnityCG.cginc" 23 | 24 | struct appdata { 25 | float4 vertex : POSITION; 26 | float2 uv : TEXCOORD0; 27 | }; 28 | 29 | struct v2f { 30 | float2 uv : TEXCOORD0; 31 | float4 vertex : SV_POSITION; 32 | float curveRatio : TEXCOORD1; 33 | float3 color : COLOR; 34 | }; 35 | 36 | sampler2D _MainTex; 37 | sampler2D _CurveTexture; 38 | sampler2D _CurveVectorUpTexture; 39 | float4 _MainTex_ST; 40 | fixed4 _Color; 41 | float3 _Forward; 42 | float3 _Up; 43 | float3 _Right; 44 | float _CurveResolution; 45 | float _ShouldInverse; 46 | float _ShouldLoop; 47 | float _CycleOffset; 48 | float _CycleTime; 49 | float _CurveScale; 50 | float _PlanarScale; 51 | 52 | // this function set the vertex position 53 | v2f vert (appdata v) 54 | { 55 | v2f o; 56 | 57 | // use transform component 58 | float4 vertex = mul(unity_WorldToObject, v.vertex); 59 | 60 | // axis setup (compress vectors into scalars) 61 | float vertexForward = vertex.x * _Forward.x + vertex.y * _Forward.y + vertex.z * _Forward.z; 62 | float vertexRight = vertex.x * _Right.x + vertex.y * _Right.y + vertex.z * _Right.z; 63 | float vertexUp = vertex.x * _Up.x + vertex.y * _Up.y + vertex.z * _Up.z; 64 | 65 | // the actual clamped ratio position on the curve 66 | float ratio = fmod(abs(vertexForward * _CurveScale + _CycleTime + _CycleOffset), 1.0); 67 | ratio = lerp(ratio, 1.0 - ratio, _ShouldInverse); 68 | 69 | // used to distribute point on the plane that is perpendicular to the curve forward 70 | float angle = atan2(vertexUp, vertexRight); 71 | float radius = length(float2(vertexRight * _PlanarScale, vertexUp * _PlanarScale)); 72 | 73 | // get current point through the texture 74 | float4 p = float4(ratio, 0.0, 0.0, 0.0); 75 | float3 bezierPoint = mul(unity_WorldToObject, tex2Dlod(_CurveTexture, p)); 76 | 77 | // get neighbors of the current ratio 78 | float unit = 1.0 / _CurveResolution; 79 | float next = fmod(ratio + unit, 1.0); 80 | float prev = fmod(ratio - unit + 1.0, 1.0); 81 | float ratioNext = lerp(next, prev, _ShouldInverse); 82 | float ratioPrevious = lerp(prev, next, _ShouldInverse); 83 | 84 | // get next and previous point through the texture 85 | p.x = ratioNext; 86 | float3 bezierPointNext = mul(unity_WorldToObject, tex2Dlod(_CurveTexture, p)); 87 | p.x = ratioPrevious; 88 | float3 bezierPointPrevious = mul(unity_WorldToObject, tex2Dlod(_CurveTexture, p)); 89 | 90 | // find out vectors 91 | float3 forward = normalize(bezierPointNext - bezierPoint); 92 | // float3 backward = normalize(bezierPointPrevious - bezierPoint); 93 | float3 up = normalize(cross(normalize(bezierPoint), normalize(bezierPointNext))); 94 | // float3 up = normalize(cross(forward, backward)); 95 | float3 right = normalize(cross(forward, up)); 96 | 97 | // voila 98 | vertex.xyz = bezierPoint + right * cos(angle) * radius + up * sin(angle) * radius; 99 | 100 | // unity stuff 101 | o.curveRatio = lerp(ratio, -1.0, step(1.0, ratio + unit)); 102 | o.curveRatio = lerp(o.curveRatio, -1.0, step(ratio - unit, 0.0)); 103 | o.color = up; 104 | o.vertex = UnityObjectToClipPos(vertex); 105 | o.uv = TRANSFORM_TEX(v.uv, _MainTex); 106 | return o; 107 | } 108 | 109 | // this function give the pixel color 110 | fixed4 frag (v2f i) : SV_Target 111 | { 112 | fixed4 col = tex2D(_MainTex, i.uv) * _Color; 113 | float unit = 1.0 / _CurveResolution; 114 | if (i.curveRatio < 0.0) { 115 | clip(_ShouldLoop - 0.5); 116 | } 117 | // return col; 118 | return col;// * fixed4(i.color * 0.5 + 0.5, 1.0); 119 | } 120 | ENDCG 121 | } 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /Assets/CurveModifier/Shaders/CurveModifier.shader.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 044d6ab4b3512c1499ff6caf8a870e8d 3 | timeCreated: 1465316021 4 | licenseType: Free 5 | ShaderImporter: 6 | defaultTextures: [] 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/CurveModifier/Shaders/Utils.cginc: -------------------------------------------------------------------------------- 1 | 2 | #define PI 3.141592653589 3 | #define PI2 6.283185307179 4 | 5 | float oscillation (float t, float speed) 6 | { 7 | return sin(t * speed) * 0.5 + 0.5; 8 | } 9 | 10 | float segment(float amount, float segments) 11 | { 12 | return floor(amount * segments) / segments; 13 | } 14 | 15 | float2 pixelize(float2 uv, float segments) 16 | { 17 | return floor(uv * segments) / segments; 18 | } 19 | 20 | float2 pixelize(float2 uv, float2 segments) 21 | { 22 | return floor(uv * segments) / segments; 23 | } 24 | 25 | float4 posterize ( float4 color, float segments ) 26 | { 27 | return float4(floor(color.rgb * segments) / segments, 1.0); 28 | } 29 | 30 | float2 videoUV (float2 uv) 31 | { 32 | return float2(uv.x, 1.0 - uv.y); 33 | } 34 | 35 | float2 wrapUV (float2 uv) 36 | { 37 | return fmod(abs(uv), 1.0); 38 | } 39 | 40 | float2 kaleidoGrid(float2 p) 41 | { 42 | return fmod(lerp(p, 1.0 - p, float2(step(fmod(p, 2.0), float2(1.0, 1.0)))), 1.0); 43 | } 44 | 45 | float kaleido (float d, float t) 46 | { 47 | d += t * lerp(-1.0, 1.0, fmod(floor(abs(d)), 2.0)); 48 | float dMod = fmod(abs(d), 1.0); 49 | return lerp(1.0 - dMod, dMod, fmod(floor(abs(d)), 2.0)); 50 | } 51 | 52 | float2 mouseFromCenter (float2 mouse, float2 resolution) 53 | { 54 | mouse /= resolution; 55 | mouse = (mouse - float2(0.5, 0.5)) * 2.0; 56 | mouse.y *= -1.0; 57 | return mouse; 58 | } 59 | 60 | float luminance ( float3 color ) 61 | { 62 | return (color.r + color.g + color.b) / 3.0; 63 | } 64 | 65 | float reflectance(float3 a, float3 b) 66 | { 67 | return dot(normalize(a), normalize(b)) * 0.5 + 0.5; 68 | } 69 | 70 | half4 filter (sampler2D bitmap, float2 uv, float2 dimension) 71 | { 72 | half4 color = half4(0.0, 0.0, 0.0, 0.0); 73 | 74 | color += -1.0 * tex2D(bitmap, uv + float2(-2, -2) / dimension); 75 | color += -1.0 * tex2D(bitmap, uv + float2(-2, -1) / dimension); 76 | color += -1.0 * tex2D(bitmap, uv + float2(-2, 0) / dimension); 77 | color += -1.0 * tex2D(bitmap, uv + float2(-2, 1) / dimension); 78 | color += -1.0 * tex2D(bitmap, uv + float2(-2, 2) / dimension); 79 | 80 | color += -1.0 * tex2D(bitmap, uv + float2(-1, -2) / dimension); 81 | color += -1.0 * tex2D(bitmap, uv + float2(-1, -1) / dimension); 82 | color += -1.0 * tex2D(bitmap, uv + float2(-1, 0) / dimension); 83 | color += -1.0 * tex2D(bitmap, uv + float2(-1, 1) / dimension); 84 | color += -1.0 * tex2D(bitmap, uv + float2(-1, 2) / dimension); 85 | 86 | color += -1.0 * tex2D(bitmap, uv + float2( 0, -2) / dimension); 87 | color += -1.0 * tex2D(bitmap, uv + float2( 0, -1) / dimension); 88 | color += 24.0 * tex2D(bitmap, uv + float2( 0, 0) / dimension); 89 | color += -1.0 * tex2D(bitmap, uv + float2( 0, 1) / dimension); 90 | color += -1.0 * tex2D(bitmap, uv + float2( 0, 2) / dimension); 91 | 92 | color += -1.0 * tex2D(bitmap, uv + float2( 1, -2) / dimension); 93 | color += -1.0 * tex2D(bitmap, uv + float2( 1, -1) / dimension); 94 | color += -1.0 * tex2D(bitmap, uv + float2( 1, 0) / dimension); 95 | color += -1.0 * tex2D(bitmap, uv + float2( 1, 1) / dimension); 96 | color += -1.0 * tex2D(bitmap, uv + float2( 1, 2) / dimension); 97 | 98 | color += -1.0 * tex2D(bitmap, uv + float2( 2, -2) / dimension); 99 | color += -1.0 * tex2D(bitmap, uv + float2( 2, -1) / dimension); 100 | color += -1.0 * tex2D(bitmap, uv + float2( 2, 0) / dimension); 101 | color += -1.0 * tex2D(bitmap, uv + float2( 2, 1) / dimension); 102 | color += -1.0 * tex2D(bitmap, uv + float2( 2, 2) / dimension); 103 | 104 | return color; 105 | } 106 | 107 | half4 cheesyBlur (sampler2D bitmap, float2 uv, float2 dimension) 108 | { 109 | half4 color = half4(0.0, 0.0, 0.0, 0.0); 110 | color += 0.2 * tex2D(bitmap, uv + float2(0, 0) / dimension); 111 | color += 0.2 * tex2D(bitmap, uv + float2(0, -1) / dimension); 112 | color += 0.2 * tex2D(bitmap, uv + float2( -1, 0) / dimension); 113 | color += 0.2 * tex2D(bitmap, uv + float2( 0, 1) / dimension); 114 | color += 0.2 * tex2D(bitmap, uv + float2( 1, 0) / dimension); 115 | return color; 116 | } 117 | 118 | float2 lightDirection (sampler2D bitmap, float2 uv, float2 dimension) 119 | { 120 | float2 force = float2(0.0, 0.0); 121 | float3 c = tex2D(bitmap, uv).rgb; 122 | float l = Luminance(c); 123 | 124 | c = tex2D(bitmap, uv - float2(1.0, 0.0) / dimension).rgb; 125 | force.x += Luminance(c) - l; 126 | 127 | c = tex2D(bitmap, uv + float2(1.0, 0.0) / dimension).rgb; 128 | force.x += l - Luminance(c); 129 | 130 | c = tex2D(bitmap, uv - float2(0.0, 1.0) / dimension).rgb; 131 | force.y += Luminance(c) - l; 132 | 133 | c = tex2D(bitmap, uv + float2(0.0, 1.0) / dimension).rgb; 134 | force.y += l - Luminance(c); 135 | 136 | return force; 137 | // return normalize(force); 138 | } 139 | 140 | float2 lightDirectionUnit (sampler2D bitmap, float2 uv, float2 dimension) 141 | { 142 | float2 force = float2(0.0, 0.0); 143 | float3 c = tex2D(bitmap, uv).rgb; 144 | float l = Luminance(c); 145 | 146 | c = tex2D(bitmap, uv - float2(1.0, 0.0) / dimension).rgb; 147 | force.x += step(l, Luminance(c)) * 2 - 1; 148 | 149 | c = tex2D(bitmap, uv + float2(1.0, 0.0) / dimension).rgb; 150 | force.x += step(Luminance(c), l) * 2 - 1; 151 | 152 | c = tex2D(bitmap, uv - float2(0.0, 1.0) / dimension).rgb; 153 | force.y += step(l, Luminance(c)) * 2 - 1; 154 | 155 | c = tex2D(bitmap, uv + float2(0.0, 1.0) / dimension).rgb; 156 | force.y += step(Luminance(c), l) * 2 - 1; 157 | 158 | return force; 159 | // return normalize(force); 160 | } 161 | 162 | float grid2D (float x, float lineDistance, float lineThickness) 163 | { 164 | return step(fmod(x, lineDistance), lineThickness); 165 | } 166 | 167 | float dentDeScie (float x) 168 | { 169 | return 1.0 - abs(fmod(abs(x), 1.0) * 2.0 - 1.0); 170 | } 171 | 172 | float vectorToNumber1 (float3 v) 173 | { 174 | return ((v.x + v.y + v.z) / 3.0) * 0.5 + 0.5; 175 | } 176 | 177 | float vectorToNumber2 (float3 v) 178 | { 179 | return (atan2(v.y, v.x) * 0.5 / PI + 0.5 + atan2(v.z, v.x) * 0.5 / PI + 0.5 ) / 2.0; 180 | } 181 | 182 | float vectorToNumber3 (float normal1, float normal2) 183 | { 184 | return 1.0 - dot(normal1, normal2) * 0.5 + 0.5; 185 | } 186 | 187 | // http://stackoverflow.com/questions/12964279/whats-the-origin-of-this-glsl-rand-one-liner 188 | float rand(float2 co) 189 | { 190 | return frac(sin(dot(co.xy ,float2(12.9898,78.233))) * 43758.5453); 191 | } 192 | 193 | // From Anton Roy -> https://www.shadertoy.com/view/Xs23DG 194 | float4 filter5x5 (float filter[25], sampler2D bitmap, float2 uv, float2 dimension) 195 | { 196 | float4 color = float4(0.0, 0.0, 0.0, 0.0); 197 | for (int i = 0; i < 5; ++i) 198 | for (int j = 0; j < 5; ++j) 199 | color += filter[i * 5 + j] * tex2D(bitmap, uv + float2(i - 2, j - 2) / dimension); 200 | return color; 201 | } 202 | 203 | float3 rotateY(float3 v, float t) 204 | { 205 | float cost = cos(t); float sint = sin(t); 206 | return float3(v.x * cost + v.z * sint, v.y, -v.x * sint + v.z * cost); 207 | } 208 | 209 | float3 rotateX(float3 v, float t) 210 | { 211 | float cost = cos(t); float sint = sin(t); 212 | return float3(v.x, v.y * cost - v.z * sint, v.y * sint + v.z * cost); 213 | } 214 | 215 | float3 getNormal(float3 a, float3 b, float3 c) 216 | { 217 | float3 u = b - a; 218 | float3 v = c - a; 219 | float3 normal = float3(1.0, 0.0, 0.0); 220 | normal.x = u.y * v.z - u.z * v.y; 221 | normal.y = u.z * v.x - u.x * v.z; 222 | normal.z = u.x * v.y - u.y * v.x; 223 | return normalize(normal); 224 | } 225 | 226 | // hash based 3d value noise 227 | // function taken from https://www.shadertoy.com/view/XslGRr 228 | // Created by inigo quilez - iq/2013 229 | // License Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License. 230 | 231 | // ported from GLSL to HLSL 232 | float hash( float n ) 233 | { 234 | return frac(sin(n)*43758.5453); 235 | } 236 | 237 | float noiseIQ( float3 x ) 238 | { 239 | // The noise function returns a value in the range -1.0f -> 1.0f 240 | float3 p = floor(x); 241 | float3 f = frac(x); 242 | f = f*f*(3.0-2.0*f); 243 | float n = p.x + p.y*57.0 + 113.0*p.z; 244 | return lerp(lerp(lerp( hash(n+0.0), hash(n+1.0),f.x), 245 | lerp( hash(n+57.0), hash(n+58.0),f.x),f.y), 246 | lerp(lerp( hash(n+113.0), hash(n+114.0),f.x), 247 | lerp( hash(n+170.0), hash(n+171.0),f.x),f.y),f.z); 248 | } 249 | 250 | // by Inigo Quilez 251 | 252 | float sphere( float3 p, float s ) 253 | { 254 | return length(p)-s; 255 | } 256 | 257 | float addition( float d1, float d2 ) 258 | { 259 | return min(d1,d2); 260 | } 261 | 262 | float substraction( float d1, float d2 ) 263 | { 264 | return max(-d1,d2); 265 | } 266 | 267 | float intersection( float d1, float d2 ) 268 | { 269 | return max(d1,d2); 270 | } 271 | 272 | float3 grid(float3 p, float3 size) 273 | { 274 | return fmod(p, size) - size * 0.5; 275 | } 276 | 277 | 278 | // Sam Hocevar 279 | float3 rgb2hsv(float3 c) 280 | { 281 | float4 K = float4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0); 282 | float4 p = lerp(float4(c.bg, K.wz), float4(c.gb, K.xy), step(c.b, c.g)); 283 | float4 q = lerp(float4(p.xyw, c.r), float4(c.r, p.yzx), step(p.x, c.r)); 284 | 285 | float d = q.x - min(q.w, q.y); 286 | float e = 1.0e-10; 287 | return float3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x); 288 | } 289 | 290 | // Sam Hocevar 291 | float3 hsv2rgb(float3 c) 292 | { 293 | float4 K = float4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0); 294 | float3 p = abs(frac(c.xxx + K.xyz) * 6.0 - K.www); 295 | return c.z * lerp(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y); 296 | } 297 | 298 | // Many thanks to Brandon Pelfrey 299 | // https://github.com/brandonpelfrey/complex-function-plot/blob/master/index.htm 300 | 301 | #define M_E 2.7182818284 302 | 303 | float arg(float2 x) { return atan2(x.y, x.x); } 304 | float complex_r(float x, float y) { return length(float2(x,y)); } 305 | float complex_theta(float x, float y) { return arg(float2(x,y)); } 306 | float2 complex(float x, float y) { return float2(x,y); } 307 | 308 | // https://en.wikipedia.org/wiki/Complex_number#Elementary_operations 309 | float2 complex_add(float2 x, float2 y) { return x + y; } 310 | float2 complex_sub(float2 x, float2 y) { return x - y; } 311 | float2 complex_mul(float2 x, float2 y) { return float2( x.x*y.x-x.y*y.y, x.y*y.x+x.x*y.y); } 312 | float2 complex_div(float2 x, float2 y) { return float2( (x.x*y.x+x.y*y.y)/(y.x*y.x+y.y*y.y), (x.y*y.x-x.x*y.y)/(y.x*y.x+y.y*y.y)); } 313 | 314 | // http://www.abecedarical.com/zenosamples/zs_complexnumbers.html 315 | float2 complex_pow(float2 x, float2 y) { 316 | float rho = length(x); 317 | float theta = arg(x); 318 | float angle = y.x * theta + y.y * log(rho); 319 | float real = cos(angle); 320 | float imag = sin(angle); 321 | return float2(real, imag) * (pow(rho, y.x) * pow(M_E, -y.y * theta)); 322 | } 323 | 324 | float2 complex_sin(float2 x) { 325 | float2 iz = complex_mul(float2(0.0, 1.0), x); 326 | float2 inz = complex_mul(float2(0.0, -1.0), x); 327 | float2 eiz = complex_pow( float2(M_E, 0.0), iz ); 328 | float2 einz = complex_pow( float2(M_E, 0.0), inz ); 329 | return complex_div( eiz - einz, float2(0.0, 2.0)); 330 | } 331 | 332 | float2 complex_cos(float2 x) { 333 | float2 iz = complex_mul(float2(0.0, 1.0), x); 334 | float2 inz = complex_mul(float2(0.0, -1.0), x); 335 | float2 eiz = complex_pow( float2(M_E, 0.0), iz ); 336 | float2 einz = complex_pow( float2(M_E, 0.0), inz ); 337 | return complex_div( eiz + einz, float2(2.0, 0.0)); 338 | } 339 | 340 | float2 complex_log(float2 x) { 341 | return float2( log( length(x) ), arg(x) ); 342 | } 343 | -------------------------------------------------------------------------------- /Assets/CurveModifier/Shaders/Utils.cginc.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 0f3490bedd7dffa47a78584863f68ea5 3 | timeCreated: 1465473656 4 | licenseType: Free 5 | ShaderImporter: 6 | defaultTextures: [] 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/SimpleCurveModifier.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 69f9163dc08e78b4d894bd80066eebbc 3 | folderAsset: yes 4 | timeCreated: 1519043033 5 | licenseType: Free 6 | DefaultImporter: 7 | externalObjects: {} 8 | userData: 9 | assetBundleName: 10 | assetBundleVariant: 11 | -------------------------------------------------------------------------------- /Assets/SimpleCurveModifier/Sel.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d60a0caea1568e748a379ac78c886122 3 | folderAsset: yes 4 | timeCreated: 1519042272 5 | licenseType: Free 6 | DefaultImporter: 7 | externalObjects: {} 8 | userData: 9 | assetBundleName: 10 | assetBundleVariant: 11 | -------------------------------------------------------------------------------- /Assets/SimpleCurveModifier/Sel/sel.fbx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leon196/CurveModifier/adcd27ae180c31bf5ce01896009a4c0b9aeb7a40/Assets/SimpleCurveModifier/Sel/sel.fbx -------------------------------------------------------------------------------- /Assets/SimpleCurveModifier/Sel/sel.fbx.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6dcb2164c05f83747acc47ef2e800b45 3 | timeCreated: 1519041993 4 | licenseType: Free 5 | ModelImporter: 6 | serializedVersion: 22 7 | fileIDToRecycleName: 8 | 100000: Bone002 9 | 100002: Bone003 10 | 100004: Bone004 11 | 100006: Bone005 12 | 100008: Bone006 13 | 100010: Bone007 14 | 100012: Bone008 15 | 100014: Bone009 16 | 100016: Bone010 17 | 100018: Bone011 18 | 100020: Bone012 19 | 100022: Bone013 20 | 100024: Bone014 21 | 100026: Bone015 22 | 100028: Bone016 23 | 100030: Bone017 24 | 100032: Bone018 25 | 100034: Bone019 26 | 100036: Bone020 27 | 100038: Bone021 28 | 100040: Bone022 29 | 100042: Bone023 30 | 100044: Bone025 31 | 100046: Bone027 32 | 100048: Bone029 33 | 100050: Bone031 34 | 100052: Bone033 35 | 100054: Bone035 36 | 100056: Bone036 37 | 100058: Bone037 38 | 100060: Bone038 39 | 100062: Bone039 40 | 100064: Bone040 41 | 100066: Bone041 42 | 100068: Bone042 43 | 100070: Bone043 44 | 100072: Bone044 45 | 100074: Bone045 46 | 100076: Bone047 47 | 100078: Bone050 48 | 100080: Bone051 49 | 100082: Bone053 50 | 100084: Bone056 51 | 100086: Bone057 52 | 100088: Bone058 53 | 100090: Bone059 54 | 100092: Bone060 55 | 100094: Bone061 56 | 100096: Bone062 57 | 100098: Bone063 58 | 100100: Bone064 59 | 100102: Bone065 60 | 100104: Bone066 61 | 100106: Bone067 62 | 100108: Bone068 63 | 100110: Bone069 64 | 100112: Bone070 65 | 100114: Bone071 66 | 100116: Bone072 67 | 100118: Bone073 68 | 100120: Bone074 69 | 100122: Bone075 70 | 100124: Bone076 71 | 100126: Bone077 72 | 100128: Bone078 73 | 100130: Bone079 74 | 100132: Bone080 75 | 100134: Bone081 76 | 100136: Bone082 77 | 100138: Bone083 78 | 100140: Bone084 79 | 100142: Bone085 80 | 100144: Bone086 81 | 100146: Bone087 82 | 100148: Bone088 83 | 100150: Bone089 84 | 100152: Bone090 85 | 100154: Bone091 86 | 100156: Bone092 87 | 100158: Bone093 88 | 100160: Bone094 89 | 100162: Bone095 90 | 100164: Bone096 91 | 100166: Bone097 92 | 100168: Bone098 93 | 100170: Bone099 94 | 100172: Plane001 95 | 100174: Plane002 96 | 100176: //RootNode 97 | 400000: Bone002 98 | 400002: Bone003 99 | 400004: Bone004 100 | 400006: Bone005 101 | 400008: Bone006 102 | 400010: Bone007 103 | 400012: Bone008 104 | 400014: Bone009 105 | 400016: Bone010 106 | 400018: Bone011 107 | 400020: Bone012 108 | 400022: Bone013 109 | 400024: Bone014 110 | 400026: Bone015 111 | 400028: Bone016 112 | 400030: Bone017 113 | 400032: Bone018 114 | 400034: Bone019 115 | 400036: Bone020 116 | 400038: Bone021 117 | 400040: Bone022 118 | 400042: Bone023 119 | 400044: Bone025 120 | 400046: Bone027 121 | 400048: Bone029 122 | 400050: Bone031 123 | 400052: Bone033 124 | 400054: Bone035 125 | 400056: Bone036 126 | 400058: Bone037 127 | 400060: Bone038 128 | 400062: Bone039 129 | 400064: Bone040 130 | 400066: Bone041 131 | 400068: Bone042 132 | 400070: Bone043 133 | 400072: Bone044 134 | 400074: Bone045 135 | 400076: Bone047 136 | 400078: Bone050 137 | 400080: Bone051 138 | 400082: Bone053 139 | 400084: Bone056 140 | 400086: Bone057 141 | 400088: Bone058 142 | 400090: Bone059 143 | 400092: Bone060 144 | 400094: Bone061 145 | 400096: Bone062 146 | 400098: Bone063 147 | 400100: Bone064 148 | 400102: Bone065 149 | 400104: Bone066 150 | 400106: Bone067 151 | 400108: Bone068 152 | 400110: Bone069 153 | 400112: Bone070 154 | 400114: Bone071 155 | 400116: Bone072 156 | 400118: Bone073 157 | 400120: Bone074 158 | 400122: Bone075 159 | 400124: Bone076 160 | 400126: Bone077 161 | 400128: Bone078 162 | 400130: Bone079 163 | 400132: Bone080 164 | 400134: Bone081 165 | 400136: Bone082 166 | 400138: Bone083 167 | 400140: Bone084 168 | 400142: Bone085 169 | 400144: Bone086 170 | 400146: Bone087 171 | 400148: Bone088 172 | 400150: Bone089 173 | 400152: Bone090 174 | 400154: Bone091 175 | 400156: Bone092 176 | 400158: Bone093 177 | 400160: Bone094 178 | 400162: Bone095 179 | 400164: Bone096 180 | 400166: Bone097 181 | 400168: Bone098 182 | 400170: Bone099 183 | 400172: Plane001 184 | 400174: Plane002 185 | 400176: //RootNode 186 | 2100000: 'Material #2' 187 | 2100002: Sel 188 | 2300000: //RootNode 189 | 3300000: //RootNode 190 | 4300000: Plane001 191 | 4300002: Plane002 192 | 4300004: Sel 193 | 7400000: Take 001 194 | 9500000: //RootNode 195 | 13700000: Plane001 196 | 13700002: Plane002 197 | externalObjects: {} 198 | materials: 199 | importMaterials: 1 200 | materialName: 0 201 | materialSearch: 1 202 | materialLocation: 1 203 | animations: 204 | legacyGenerateAnimations: 4 205 | bakeSimulation: 0 206 | resampleCurves: 1 207 | optimizeGameObjects: 0 208 | motionNodeName: 209 | rigImportErrors: 210 | rigImportWarnings: 211 | animationImportErrors: 212 | animationImportWarnings: 213 | animationRetargetingWarnings: 214 | animationDoRetargetingWarnings: 0 215 | importAnimatedCustomProperties: 0 216 | animationCompression: 1 217 | animationRotationError: 0.5 218 | animationPositionError: 0.5 219 | animationScaleError: 0.5 220 | animationWrapMode: 0 221 | extraExposedTransformPaths: [] 222 | extraUserProperties: [] 223 | clipAnimations: [] 224 | isReadable: 1 225 | meshes: 226 | lODScreenPercentages: [] 227 | globalScale: 1 228 | meshCompression: 0 229 | addColliders: 0 230 | importVisibility: 1 231 | importBlendShapes: 1 232 | importCameras: 1 233 | importLights: 1 234 | swapUVChannels: 0 235 | generateSecondaryUV: 0 236 | useFileUnits: 1 237 | optimizeMeshForGPU: 1 238 | keepQuads: 0 239 | weldVertices: 1 240 | preserveHierarchy: 0 241 | indexFormat: 0 242 | secondaryUVAngleDistortion: 8 243 | secondaryUVAreaDistortion: 15.000001 244 | secondaryUVHardAngle: 88 245 | secondaryUVPackMargin: 4 246 | useFileScale: 0 247 | tangentSpace: 248 | normalSmoothAngle: 60 249 | normalImportMode: 0 250 | tangentImportMode: 3 251 | normalCalculationMode: 4 252 | importAnimation: 0 253 | copyAvatar: 0 254 | humanDescription: 255 | serializedVersion: 2 256 | human: [] 257 | skeleton: [] 258 | armTwist: 0.5 259 | foreArmTwist: 0.5 260 | upperLegTwist: 0.5 261 | legTwist: 0.5 262 | armStretch: 0.05 263 | legStretch: 0.05 264 | feetSpacing: 0 265 | rootMotionBoneName: 266 | rootMotionBoneRotation: {x: 0, y: 0, z: 0, w: 1} 267 | hasTranslationDoF: 0 268 | hasExtraRoot: 0 269 | skeletonHasParents: 1 270 | lastHumanDescriptionAvatarSource: {instanceID: 0} 271 | animationType: 2 272 | humanoidOversampling: 1 273 | additionalBone: 0 274 | userData: 275 | assetBundleName: 276 | assetBundleVariant: 277 | -------------------------------------------------------------------------------- /Assets/SimpleCurveModifier/Sel/sel.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leon196/CurveModifier/adcd27ae180c31bf5ce01896009a4c0b9aeb7a40/Assets/SimpleCurveModifier/Sel/sel.jpg -------------------------------------------------------------------------------- /Assets/SimpleCurveModifier/Sel/sel.jpg.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e75725da7e95b2045aef3f66d70c0135 3 | timeCreated: 1519041993 4 | licenseType: Free 5 | TextureImporter: 6 | fileIDToRecycleName: {} 7 | externalObjects: {} 8 | serializedVersion: 4 9 | mipmaps: 10 | mipMapMode: 0 11 | enableMipMap: 1 12 | sRGBTexture: 1 13 | linearTexture: 0 14 | fadeOut: 0 15 | borderMipMap: 0 16 | mipMapsPreserveCoverage: 0 17 | alphaTestReferenceValue: 0.5 18 | mipMapFadeDistanceStart: 1 19 | mipMapFadeDistanceEnd: 3 20 | bumpmap: 21 | convertToNormalMap: 0 22 | externalNormalMap: 0 23 | heightScale: 0.25 24 | normalMapFilter: 0 25 | isReadable: 0 26 | grayScaleToAlpha: 0 27 | generateCubemap: 6 28 | cubemapConvolution: 0 29 | seamlessCubemap: 0 30 | textureFormat: 1 31 | maxTextureSize: 2048 32 | textureSettings: 33 | serializedVersion: 2 34 | filterMode: -1 35 | aniso: -1 36 | mipBias: -1 37 | wrapU: -1 38 | wrapV: -1 39 | wrapW: -1 40 | nPOTScale: 1 41 | lightmap: 0 42 | compressionQuality: 50 43 | spriteMode: 0 44 | spriteExtrude: 1 45 | spriteMeshType: 1 46 | alignment: 0 47 | spritePivot: {x: 0.5, y: 0.5} 48 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 49 | spritePixelsToUnits: 100 50 | alphaUsage: 1 51 | alphaIsTransparency: 0 52 | spriteTessellationDetail: -1 53 | textureType: 0 54 | textureShape: 1 55 | maxTextureSizeSet: 0 56 | compressionQualitySet: 0 57 | textureFormatSet: 0 58 | platformSettings: 59 | - buildTarget: DefaultTexturePlatform 60 | maxTextureSize: 2048 61 | resizeAlgorithm: 0 62 | textureFormat: -1 63 | textureCompression: 1 64 | compressionQuality: 50 65 | crunchedCompression: 0 66 | allowsAlphaSplitting: 0 67 | overridden: 0 68 | androidETC2FallbackOverride: 0 69 | spriteSheet: 70 | serializedVersion: 2 71 | sprites: [] 72 | outline: [] 73 | physicsShape: [] 74 | spritePackingTag: 75 | userData: 76 | assetBundleName: 77 | assetBundleVariant: 78 | -------------------------------------------------------------------------------- /Assets/SimpleCurveModifier/Sel/sel.txt: -------------------------------------------------------------------------------- 1 | Sel by Shakiller 2 | CC Attribution 3 | https://sketchfab.com/models/358ad8ccbc1740af8c13f019d90adb18# -------------------------------------------------------------------------------- /Assets/SimpleCurveModifier/Sel/sel.txt.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 25f512fbbc06d32488e1d20ab674f4a1 3 | timeCreated: 1519041993 4 | licenseType: Free 5 | TextScriptImporter: 6 | externalObjects: {} 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/SimpleCurveModifier/SimpleCurveModifier.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using UnityEngine; 4 | 5 | public class SimpleCurveModifier : MonoBehaviour { 6 | 7 | public BezierCurve bezierCurve; 8 | public Material curveMaterial; 9 | private Texture2D texture; 10 | 11 | void Start () { 12 | GeneratePositionTexture(); 13 | 14 | // distribute allover the curve 15 | // transform.localScale = Vector3.one / GetComponent().bounds.size.y; 16 | } 17 | 18 | void Update () { 19 | curveMaterial.SetTexture("_CurveTexture", texture); 20 | } 21 | 22 | void GeneratePositionTexture () { 23 | texture = new Texture2D(32, 1, TextureFormat.RGBAFloat, false); 24 | Color[] pixels = new Color[texture.width]; 25 | for (int i = 0; i < texture.width; ++i) { 26 | Vector3 position = bezierCurve.GetPointAt((float)i/(float)texture.width); 27 | pixels[i].r = position.x; 28 | pixels[i].g = position.y; 29 | pixels[i].b = position.z; 30 | } 31 | texture.SetPixels(pixels); 32 | texture.Apply(); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /Assets/SimpleCurveModifier/SimpleCurveModifier.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 259c05a42e32c5e4a9e9d195e1174987 3 | timeCreated: 1519042332 4 | licenseType: Free 5 | MonoImporter: 6 | externalObjects: {} 7 | serializedVersion: 2 8 | defaultReferences: [] 9 | executionOrder: 0 10 | icon: {instanceID: 0} 11 | userData: 12 | assetBundleName: 13 | assetBundleVariant: 14 | -------------------------------------------------------------------------------- /Assets/SimpleCurveModifier/SimpleCurveModifier.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leon196/CurveModifier/adcd27ae180c31bf5ce01896009a4c0b9aeb7a40/Assets/SimpleCurveModifier/SimpleCurveModifier.mat -------------------------------------------------------------------------------- /Assets/SimpleCurveModifier/SimpleCurveModifier.mat.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c982d02ec864ffa4c858f863184e3524 3 | timeCreated: 1519042993 4 | licenseType: Free 5 | NativeFormatImporter: 6 | externalObjects: {} 7 | mainObjectFileID: 2100000 8 | userData: 9 | assetBundleName: 10 | assetBundleVariant: 11 | -------------------------------------------------------------------------------- /Assets/SimpleCurveModifier/SimpleCurveModifier.shader: -------------------------------------------------------------------------------- 1 | Shader "Unlit/SimpleCurveModifier" 2 | { 3 | Properties 4 | { 5 | _MainTex ("Texture", 2D) = "white" {} 6 | _Speed ("Speed", Float) = 1 7 | _Length ("Length", Float) = 1 8 | _Radius ("Radius", Float) = 1 9 | } 10 | SubShader 11 | { 12 | Tags { "RenderType"="Opaque" } 13 | LOD 100 14 | 15 | Pass 16 | { 17 | CGPROGRAM 18 | #pragma vertex vert 19 | #pragma fragment frag 20 | 21 | #include "UnityCG.cginc" 22 | 23 | struct attributes 24 | { 25 | float4 position : POSITION; 26 | float2 uv : TEXCOORD0; 27 | }; 28 | 29 | struct varying 30 | { 31 | float4 position : SV_POSITION; 32 | float2 uv : TEXCOORD0; 33 | }; 34 | 35 | uniform sampler2D _MainTex, _CurveTexture; 36 | uniform float4 _MainTex_ST; 37 | uniform float _Speed, _Length, _Radius; 38 | 39 | varying vert (attributes v) 40 | { 41 | varying o; 42 | 43 | o.position = mul(UNITY_MATRIX_M, v.position); 44 | 45 | float current = fmod(o.position.y * _Length + _Time.y * _Speed, 1.); 46 | float next = fmod(current + .01, 1.); 47 | 48 | float3 curvePosition = tex2Dlod(_CurveTexture, float4(current,0,0,0)).xyz; 49 | float3 curvePositionNext = tex2Dlod(_CurveTexture, float4(next,0,0,0)).xyz; 50 | 51 | float3 forward = normalize(curvePositionNext - curvePosition); 52 | // float3 up = normalize(cross(float3(0,1,0), forward)); 53 | float3 up = normalize(cross(normalize(curvePositionNext), normalize(curvePosition))); 54 | float3 right = normalize(cross(forward, up)); 55 | 56 | float angle = atan2(o.position.z, o.position.x); 57 | float radius = length(o.position.xz) * _Radius; 58 | o.position.xyz = curvePosition + (right * cos(angle) + up * sin(angle)) * radius; 59 | 60 | o.position = mul(UNITY_MATRIX_VP, o.position); 61 | o.uv = TRANSFORM_TEX(v.uv, _MainTex); 62 | return o; 63 | } 64 | 65 | fixed4 frag (varying i) : SV_Target 66 | { 67 | fixed4 color = tex2D(_MainTex, i.uv); 68 | return color; 69 | } 70 | ENDCG 71 | } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /Assets/SimpleCurveModifier/SimpleCurveModifier.shader.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a960e20437c7ded4389abc41b75480f3 3 | timeCreated: 1519043018 4 | licenseType: Free 5 | ShaderImporter: 6 | externalObjects: {} 7 | defaultTextures: [] 8 | userData: 9 | assetBundleName: 10 | assetBundleVariant: 11 | -------------------------------------------------------------------------------- /Assets/SimpleCurveModifier/SimpleCurveModifier.unity: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leon196/CurveModifier/adcd27ae180c31bf5ce01896009a4c0b9aeb7a40/Assets/SimpleCurveModifier/SimpleCurveModifier.unity -------------------------------------------------------------------------------- /Assets/SimpleCurveModifier/SimpleCurveModifier.unity.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 260d6e5d52ef2f444bf9dda7a24f3f4e 3 | timeCreated: 1519042344 4 | licenseType: Free 5 | DefaultImporter: 6 | externalObjects: {} 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 3, 29 June 2007 3 | 4 | Copyright (C) 2007 Free Software Foundation, Inc. 5 | Everyone is permitted to copy and distribute verbatim copies 6 | of this license document, but changing it is not allowed. 7 | 8 | Preamble 9 | 10 | The GNU General Public License is a free, copyleft license for 11 | software and other kinds of works. 12 | 13 | The licenses for most software and other practical works are designed 14 | to take away your freedom to share and change the works. By contrast, 15 | the GNU General Public License is intended to guarantee your freedom to 16 | share and change all versions of a program--to make sure it remains free 17 | software for all its users. We, the Free Software Foundation, use the 18 | GNU General Public License for most of our software; it applies also to 19 | any other work released this way by its authors. You can apply it to 20 | your programs, too. 21 | 22 | When we speak of free software, we are referring to freedom, not 23 | price. Our General Public Licenses are designed to make sure that you 24 | have the freedom to distribute copies of free software (and charge for 25 | them if you wish), that you receive source code or can get it if you 26 | want it, that you can change the software or use pieces of it in new 27 | free programs, and that you know you can do these things. 28 | 29 | To protect your rights, we need to prevent others from denying you 30 | these rights or asking you to surrender the rights. Therefore, you have 31 | certain responsibilities if you distribute copies of the software, or if 32 | you modify it: responsibilities to respect the freedom of others. 33 | 34 | For example, if you distribute copies of such a program, whether 35 | gratis or for a fee, you must pass on to the recipients the same 36 | freedoms that you received. You must make sure that they, too, receive 37 | or can get the source code. And you must show them these terms so they 38 | know their rights. 39 | 40 | Developers that use the GNU GPL protect your rights with two steps: 41 | (1) assert copyright on the software, and (2) offer you this License 42 | giving you legal permission to copy, distribute and/or modify it. 43 | 44 | For the developers' and authors' protection, the GPL clearly explains 45 | that there is no warranty for this free software. For both users' and 46 | authors' sake, the GPL requires that modified versions be marked as 47 | changed, so that their problems will not be attributed erroneously to 48 | authors of previous versions. 49 | 50 | Some devices are designed to deny users access to install or run 51 | modified versions of the software inside them, although the manufacturer 52 | can do so. This is fundamentally incompatible with the aim of 53 | protecting users' freedom to change the software. The systematic 54 | pattern of such abuse occurs in the area of products for individuals to 55 | use, which is precisely where it is most unacceptable. Therefore, we 56 | have designed this version of the GPL to prohibit the practice for those 57 | products. If such problems arise substantially in other domains, we 58 | stand ready to extend this provision to those domains in future versions 59 | of the GPL, as needed to protect the freedom of users. 60 | 61 | Finally, every program is threatened constantly by software patents. 62 | States should not allow patents to restrict development and use of 63 | software on general-purpose computers, but in those that do, we wish to 64 | avoid the special danger that patents applied to a free program could 65 | make it effectively proprietary. To prevent this, the GPL assures that 66 | patents cannot be used to render the program non-free. 67 | 68 | The precise terms and conditions for copying, distribution and 69 | modification follow. 70 | 71 | TERMS AND CONDITIONS 72 | 73 | 0. Definitions. 74 | 75 | "This License" refers to version 3 of the GNU General Public License. 76 | 77 | "Copyright" also means copyright-like laws that apply to other kinds of 78 | works, such as semiconductor masks. 79 | 80 | "The Program" refers to any copyrightable work licensed under this 81 | License. Each licensee is addressed as "you". "Licensees" and 82 | "recipients" may be individuals or organizations. 83 | 84 | To "modify" a work means to copy from or adapt all or part of the work 85 | in a fashion requiring copyright permission, other than the making of an 86 | exact copy. The resulting work is called a "modified version" of the 87 | earlier work or a work "based on" the earlier work. 88 | 89 | A "covered work" means either the unmodified Program or a work based 90 | on the Program. 91 | 92 | To "propagate" a work means to do anything with it that, without 93 | permission, would make you directly or secondarily liable for 94 | infringement under applicable copyright law, except executing it on a 95 | computer or modifying a private copy. Propagation includes copying, 96 | distribution (with or without modification), making available to the 97 | public, and in some countries other activities as well. 98 | 99 | To "convey" a work means any kind of propagation that enables other 100 | parties to make or receive copies. Mere interaction with a user through 101 | a computer network, with no transfer of a copy, is not conveying. 102 | 103 | An interactive user interface displays "Appropriate Legal Notices" 104 | to the extent that it includes a convenient and prominently visible 105 | feature that (1) displays an appropriate copyright notice, and (2) 106 | tells the user that there is no warranty for the work (except to the 107 | extent that warranties are provided), that licensees may convey the 108 | work under this License, and how to view a copy of this License. If 109 | the interface presents a list of user commands or options, such as a 110 | menu, a prominent item in the list meets this criterion. 111 | 112 | 1. Source Code. 113 | 114 | The "source code" for a work means the preferred form of the work 115 | for making modifications to it. "Object code" means any non-source 116 | form of a work. 117 | 118 | A "Standard Interface" means an interface that either is an official 119 | standard defined by a recognized standards body, or, in the case of 120 | interfaces specified for a particular programming language, one that 121 | is widely used among developers working in that language. 122 | 123 | The "System Libraries" of an executable work include anything, other 124 | than the work as a whole, that (a) is included in the normal form of 125 | packaging a Major Component, but which is not part of that Major 126 | Component, and (b) serves only to enable use of the work with that 127 | Major Component, or to implement a Standard Interface for which an 128 | implementation is available to the public in source code form. A 129 | "Major Component", in this context, means a major essential component 130 | (kernel, window system, and so on) of the specific operating system 131 | (if any) on which the executable work runs, or a compiler used to 132 | produce the work, or an object code interpreter used to run it. 133 | 134 | The "Corresponding Source" for a work in object code form means all 135 | the source code needed to generate, install, and (for an executable 136 | work) run the object code and to modify the work, including scripts to 137 | control those activities. However, it does not include the work's 138 | System Libraries, or general-purpose tools or generally available free 139 | programs which are used unmodified in performing those activities but 140 | which are not part of the work. For example, Corresponding Source 141 | includes interface definition files associated with source files for 142 | the work, and the source code for shared libraries and dynamically 143 | linked subprograms that the work is specifically designed to require, 144 | such as by intimate data communication or control flow between those 145 | subprograms and other parts of the work. 146 | 147 | The Corresponding Source need not include anything that users 148 | can regenerate automatically from other parts of the Corresponding 149 | Source. 150 | 151 | The Corresponding Source for a work in source code form is that 152 | same work. 153 | 154 | 2. Basic Permissions. 155 | 156 | All rights granted under this License are granted for the term of 157 | copyright on the Program, and are irrevocable provided the stated 158 | conditions are met. This License explicitly affirms your unlimited 159 | permission to run the unmodified Program. The output from running a 160 | covered work is covered by this License only if the output, given its 161 | content, constitutes a covered work. This License acknowledges your 162 | rights of fair use or other equivalent, as provided by copyright law. 163 | 164 | You may make, run and propagate covered works that you do not 165 | convey, without conditions so long as your license otherwise remains 166 | in force. You may convey covered works to others for the sole purpose 167 | of having them make modifications exclusively for you, or provide you 168 | with facilities for running those works, provided that you comply with 169 | the terms of this License in conveying all material for which you do 170 | not control copyright. Those thus making or running the covered works 171 | for you must do so exclusively on your behalf, under your direction 172 | and control, on terms that prohibit them from making any copies of 173 | your copyrighted material outside their relationship with you. 174 | 175 | Conveying under any other circumstances is permitted solely under 176 | the conditions stated below. Sublicensing is not allowed; section 10 177 | makes it unnecessary. 178 | 179 | 3. Protecting Users' Legal Rights From Anti-Circumvention Law. 180 | 181 | No covered work shall be deemed part of an effective technological 182 | measure under any applicable law fulfilling obligations under article 183 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or 184 | similar laws prohibiting or restricting circumvention of such 185 | measures. 186 | 187 | When you convey a covered work, you waive any legal power to forbid 188 | circumvention of technological measures to the extent such circumvention 189 | is effected by exercising rights under this License with respect to 190 | the covered work, and you disclaim any intention to limit operation or 191 | modification of the work as a means of enforcing, against the work's 192 | users, your or third parties' legal rights to forbid circumvention of 193 | technological measures. 194 | 195 | 4. Conveying Verbatim Copies. 196 | 197 | You may convey verbatim copies of the Program's source code as you 198 | receive it, in any medium, provided that you conspicuously and 199 | appropriately publish on each copy an appropriate copyright notice; 200 | keep intact all notices stating that this License and any 201 | non-permissive terms added in accord with section 7 apply to the code; 202 | keep intact all notices of the absence of any warranty; and give all 203 | recipients a copy of this License along with the Program. 204 | 205 | You may charge any price or no price for each copy that you convey, 206 | and you may offer support or warranty protection for a fee. 207 | 208 | 5. Conveying Modified Source Versions. 209 | 210 | You may convey a work based on the Program, or the modifications to 211 | produce it from the Program, in the form of source code under the 212 | terms of section 4, provided that you also meet all of these conditions: 213 | 214 | a) The work must carry prominent notices stating that you modified 215 | it, and giving a relevant date. 216 | 217 | b) The work must carry prominent notices stating that it is 218 | released under this License and any conditions added under section 219 | 7. This requirement modifies the requirement in section 4 to 220 | "keep intact all notices". 221 | 222 | c) You must license the entire work, as a whole, under this 223 | License to anyone who comes into possession of a copy. This 224 | License will therefore apply, along with any applicable section 7 225 | additional terms, to the whole of the work, and all its parts, 226 | regardless of how they are packaged. This License gives no 227 | permission to license the work in any other way, but it does not 228 | invalidate such permission if you have separately received it. 229 | 230 | d) If the work has interactive user interfaces, each must display 231 | Appropriate Legal Notices; however, if the Program has interactive 232 | interfaces that do not display Appropriate Legal Notices, your 233 | work need not make them do so. 234 | 235 | A compilation of a covered work with other separate and independent 236 | works, which are not by their nature extensions of the covered work, 237 | and which are not combined with it such as to form a larger program, 238 | in or on a volume of a storage or distribution medium, is called an 239 | "aggregate" if the compilation and its resulting copyright are not 240 | used to limit the access or legal rights of the compilation's users 241 | beyond what the individual works permit. Inclusion of a covered work 242 | in an aggregate does not cause this License to apply to the other 243 | parts of the aggregate. 244 | 245 | 6. Conveying Non-Source Forms. 246 | 247 | You may convey a covered work in object code form under the terms 248 | of sections 4 and 5, provided that you also convey the 249 | machine-readable Corresponding Source under the terms of this License, 250 | in one of these ways: 251 | 252 | a) Convey the object code in, or embodied in, a physical product 253 | (including a physical distribution medium), accompanied by the 254 | Corresponding Source fixed on a durable physical medium 255 | customarily used for software interchange. 256 | 257 | b) Convey the object code in, or embodied in, a physical product 258 | (including a physical distribution medium), accompanied by a 259 | written offer, valid for at least three years and valid for as 260 | long as you offer spare parts or customer support for that product 261 | model, to give anyone who possesses the object code either (1) a 262 | copy of the Corresponding Source for all the software in the 263 | product that is covered by this License, on a durable physical 264 | medium customarily used for software interchange, for a price no 265 | more than your reasonable cost of physically performing this 266 | conveying of source, or (2) access to copy the 267 | Corresponding Source from a network server at no charge. 268 | 269 | c) Convey individual copies of the object code with a copy of the 270 | written offer to provide the Corresponding Source. This 271 | alternative is allowed only occasionally and noncommercially, and 272 | only if you received the object code with such an offer, in accord 273 | with subsection 6b. 274 | 275 | d) Convey the object code by offering access from a designated 276 | place (gratis or for a charge), and offer equivalent access to the 277 | Corresponding Source in the same way through the same place at no 278 | further charge. You need not require recipients to copy the 279 | Corresponding Source along with the object code. If the place to 280 | copy the object code is a network server, the Corresponding Source 281 | may be on a different server (operated by you or a third party) 282 | that supports equivalent copying facilities, provided you maintain 283 | clear directions next to the object code saying where to find the 284 | Corresponding Source. Regardless of what server hosts the 285 | Corresponding Source, you remain obligated to ensure that it is 286 | available for as long as needed to satisfy these requirements. 287 | 288 | e) Convey the object code using peer-to-peer transmission, provided 289 | you inform other peers where the object code and Corresponding 290 | Source of the work are being offered to the general public at no 291 | charge under subsection 6d. 292 | 293 | A separable portion of the object code, whose source code is excluded 294 | from the Corresponding Source as a System Library, need not be 295 | included in conveying the object code work. 296 | 297 | A "User Product" is either (1) a "consumer product", which means any 298 | tangible personal property which is normally used for personal, family, 299 | or household purposes, or (2) anything designed or sold for incorporation 300 | into a dwelling. In determining whether a product is a consumer product, 301 | doubtful cases shall be resolved in favor of coverage. For a particular 302 | product received by a particular user, "normally used" refers to a 303 | typical or common use of that class of product, regardless of the status 304 | of the particular user or of the way in which the particular user 305 | actually uses, or expects or is expected to use, the product. A product 306 | is a consumer product regardless of whether the product has substantial 307 | commercial, industrial or non-consumer uses, unless such uses represent 308 | the only significant mode of use of the product. 309 | 310 | "Installation Information" for a User Product means any methods, 311 | procedures, authorization keys, or other information required to install 312 | and execute modified versions of a covered work in that User Product from 313 | a modified version of its Corresponding Source. The information must 314 | suffice to ensure that the continued functioning of the modified object 315 | code is in no case prevented or interfered with solely because 316 | modification has been made. 317 | 318 | If you convey an object code work under this section in, or with, or 319 | specifically for use in, a User Product, and the conveying occurs as 320 | part of a transaction in which the right of possession and use of the 321 | User Product is transferred to the recipient in perpetuity or for a 322 | fixed term (regardless of how the transaction is characterized), the 323 | Corresponding Source conveyed under this section must be accompanied 324 | by the Installation Information. But this requirement does not apply 325 | if neither you nor any third party retains the ability to install 326 | modified object code on the User Product (for example, the work has 327 | been installed in ROM). 328 | 329 | The requirement to provide Installation Information does not include a 330 | requirement to continue to provide support service, warranty, or updates 331 | for a work that has been modified or installed by the recipient, or for 332 | the User Product in which it has been modified or installed. Access to a 333 | network may be denied when the modification itself materially and 334 | adversely affects the operation of the network or violates the rules and 335 | protocols for communication across the network. 336 | 337 | Corresponding Source conveyed, and Installation Information provided, 338 | in accord with this section must be in a format that is publicly 339 | documented (and with an implementation available to the public in 340 | source code form), and must require no special password or key for 341 | unpacking, reading or copying. 342 | 343 | 7. Additional Terms. 344 | 345 | "Additional permissions" are terms that supplement the terms of this 346 | License by making exceptions from one or more of its conditions. 347 | Additional permissions that are applicable to the entire Program shall 348 | be treated as though they were included in this License, to the extent 349 | that they are valid under applicable law. If additional permissions 350 | apply only to part of the Program, that part may be used separately 351 | under those permissions, but the entire Program remains governed by 352 | this License without regard to the additional permissions. 353 | 354 | When you convey a copy of a covered work, you may at your option 355 | remove any additional permissions from that copy, or from any part of 356 | it. (Additional permissions may be written to require their own 357 | removal in certain cases when you modify the work.) You may place 358 | additional permissions on material, added by you to a covered work, 359 | for which you have or can give appropriate copyright permission. 360 | 361 | Notwithstanding any other provision of this License, for material you 362 | add to a covered work, you may (if authorized by the copyright holders of 363 | that material) supplement the terms of this License with terms: 364 | 365 | a) Disclaiming warranty or limiting liability differently from the 366 | terms of sections 15 and 16 of this License; or 367 | 368 | b) Requiring preservation of specified reasonable legal notices or 369 | author attributions in that material or in the Appropriate Legal 370 | Notices displayed by works containing it; or 371 | 372 | c) Prohibiting misrepresentation of the origin of that material, or 373 | requiring that modified versions of such material be marked in 374 | reasonable ways as different from the original version; or 375 | 376 | d) Limiting the use for publicity purposes of names of licensors or 377 | authors of the material; or 378 | 379 | e) Declining to grant rights under trademark law for use of some 380 | trade names, trademarks, or service marks; or 381 | 382 | f) Requiring indemnification of licensors and authors of that 383 | material by anyone who conveys the material (or modified versions of 384 | it) with contractual assumptions of liability to the recipient, for 385 | any liability that these contractual assumptions directly impose on 386 | those licensors and authors. 387 | 388 | All other non-permissive additional terms are considered "further 389 | restrictions" within the meaning of section 10. If the Program as you 390 | received it, or any part of it, contains a notice stating that it is 391 | governed by this License along with a term that is a further 392 | restriction, you may remove that term. If a license document contains 393 | a further restriction but permits relicensing or conveying under this 394 | License, you may add to a covered work material governed by the terms 395 | of that license document, provided that the further restriction does 396 | not survive such relicensing or conveying. 397 | 398 | If you add terms to a covered work in accord with this section, you 399 | must place, in the relevant source files, a statement of the 400 | additional terms that apply to those files, or a notice indicating 401 | where to find the applicable terms. 402 | 403 | Additional terms, permissive or non-permissive, may be stated in the 404 | form of a separately written license, or stated as exceptions; 405 | the above requirements apply either way. 406 | 407 | 8. Termination. 408 | 409 | You may not propagate or modify a covered work except as expressly 410 | provided under this License. Any attempt otherwise to propagate or 411 | modify it is void, and will automatically terminate your rights under 412 | this License (including any patent licenses granted under the third 413 | paragraph of section 11). 414 | 415 | However, if you cease all violation of this License, then your 416 | license from a particular copyright holder is reinstated (a) 417 | provisionally, unless and until the copyright holder explicitly and 418 | finally terminates your license, and (b) permanently, if the copyright 419 | holder fails to notify you of the violation by some reasonable means 420 | prior to 60 days after the cessation. 421 | 422 | Moreover, your license from a particular copyright holder is 423 | reinstated permanently if the copyright holder notifies you of the 424 | violation by some reasonable means, this is the first time you have 425 | received notice of violation of this License (for any work) from that 426 | copyright holder, and you cure the violation prior to 30 days after 427 | your receipt of the notice. 428 | 429 | Termination of your rights under this section does not terminate the 430 | licenses of parties who have received copies or rights from you under 431 | this License. If your rights have been terminated and not permanently 432 | reinstated, you do not qualify to receive new licenses for the same 433 | material under section 10. 434 | 435 | 9. Acceptance Not Required for Having Copies. 436 | 437 | You are not required to accept this License in order to receive or 438 | run a copy of the Program. Ancillary propagation of a covered work 439 | occurring solely as a consequence of using peer-to-peer transmission 440 | to receive a copy likewise does not require acceptance. However, 441 | nothing other than this License grants you permission to propagate or 442 | modify any covered work. These actions infringe copyright if you do 443 | not accept this License. Therefore, by modifying or propagating a 444 | covered work, you indicate your acceptance of this License to do so. 445 | 446 | 10. Automatic Licensing of Downstream Recipients. 447 | 448 | Each time you convey a covered work, the recipient automatically 449 | receives a license from the original licensors, to run, modify and 450 | propagate that work, subject to this License. You are not responsible 451 | for enforcing compliance by third parties with this License. 452 | 453 | An "entity transaction" is a transaction transferring control of an 454 | organization, or substantially all assets of one, or subdividing an 455 | organization, or merging organizations. If propagation of a covered 456 | work results from an entity transaction, each party to that 457 | transaction who receives a copy of the work also receives whatever 458 | licenses to the work the party's predecessor in interest had or could 459 | give under the previous paragraph, plus a right to possession of the 460 | Corresponding Source of the work from the predecessor in interest, if 461 | the predecessor has it or can get it with reasonable efforts. 462 | 463 | You may not impose any further restrictions on the exercise of the 464 | rights granted or affirmed under this License. For example, you may 465 | not impose a license fee, royalty, or other charge for exercise of 466 | rights granted under this License, and you may not initiate litigation 467 | (including a cross-claim or counterclaim in a lawsuit) alleging that 468 | any patent claim is infringed by making, using, selling, offering for 469 | sale, or importing the Program or any portion of it. 470 | 471 | 11. Patents. 472 | 473 | A "contributor" is a copyright holder who authorizes use under this 474 | License of the Program or a work on which the Program is based. The 475 | work thus licensed is called the contributor's "contributor version". 476 | 477 | A contributor's "essential patent claims" are all patent claims 478 | owned or controlled by the contributor, whether already acquired or 479 | hereafter acquired, that would be infringed by some manner, permitted 480 | by this License, of making, using, or selling its contributor version, 481 | but do not include claims that would be infringed only as a 482 | consequence of further modification of the contributor version. For 483 | purposes of this definition, "control" includes the right to grant 484 | patent sublicenses in a manner consistent with the requirements of 485 | this License. 486 | 487 | Each contributor grants you a non-exclusive, worldwide, royalty-free 488 | patent license under the contributor's essential patent claims, to 489 | make, use, sell, offer for sale, import and otherwise run, modify and 490 | propagate the contents of its contributor version. 491 | 492 | In the following three paragraphs, a "patent license" is any express 493 | agreement or commitment, however denominated, not to enforce a patent 494 | (such as an express permission to practice a patent or covenant not to 495 | sue for patent infringement). To "grant" such a patent license to a 496 | party means to make such an agreement or commitment not to enforce a 497 | patent against the party. 498 | 499 | If you convey a covered work, knowingly relying on a patent license, 500 | and the Corresponding Source of the work is not available for anyone 501 | to copy, free of charge and under the terms of this License, through a 502 | publicly available network server or other readily accessible means, 503 | then you must either (1) cause the Corresponding Source to be so 504 | available, or (2) arrange to deprive yourself of the benefit of the 505 | patent license for this particular work, or (3) arrange, in a manner 506 | consistent with the requirements of this License, to extend the patent 507 | license to downstream recipients. "Knowingly relying" means you have 508 | actual knowledge that, but for the patent license, your conveying the 509 | covered work in a country, or your recipient's use of the covered work 510 | in a country, would infringe one or more identifiable patents in that 511 | country that you have reason to believe are valid. 512 | 513 | If, pursuant to or in connection with a single transaction or 514 | arrangement, you convey, or propagate by procuring conveyance of, a 515 | covered work, and grant a patent license to some of the parties 516 | receiving the covered work authorizing them to use, propagate, modify 517 | or convey a specific copy of the covered work, then the patent license 518 | you grant is automatically extended to all recipients of the covered 519 | work and works based on it. 520 | 521 | A patent license is "discriminatory" if it does not include within 522 | the scope of its coverage, prohibits the exercise of, or is 523 | conditioned on the non-exercise of one or more of the rights that are 524 | specifically granted under this License. You may not convey a covered 525 | work if you are a party to an arrangement with a third party that is 526 | in the business of distributing software, under which you make payment 527 | to the third party based on the extent of your activity of conveying 528 | the work, and under which the third party grants, to any of the 529 | parties who would receive the covered work from you, a discriminatory 530 | patent license (a) in connection with copies of the covered work 531 | conveyed by you (or copies made from those copies), or (b) primarily 532 | for and in connection with specific products or compilations that 533 | contain the covered work, unless you entered into that arrangement, 534 | or that patent license was granted, prior to 28 March 2007. 535 | 536 | Nothing in this License shall be construed as excluding or limiting 537 | any implied license or other defenses to infringement that may 538 | otherwise be available to you under applicable patent law. 539 | 540 | 12. No Surrender of Others' Freedom. 541 | 542 | If conditions are imposed on you (whether by court order, agreement or 543 | otherwise) that contradict the conditions of this License, they do not 544 | excuse you from the conditions of this License. If you cannot convey a 545 | covered work so as to satisfy simultaneously your obligations under this 546 | License and any other pertinent obligations, then as a consequence you may 547 | not convey it at all. For example, if you agree to terms that obligate you 548 | to collect a royalty for further conveying from those to whom you convey 549 | the Program, the only way you could satisfy both those terms and this 550 | License would be to refrain entirely from conveying the Program. 551 | 552 | 13. Use with the GNU Affero General Public License. 553 | 554 | Notwithstanding any other provision of this License, you have 555 | permission to link or combine any covered work with a work licensed 556 | under version 3 of the GNU Affero General Public License into a single 557 | combined work, and to convey the resulting work. The terms of this 558 | License will continue to apply to the part which is the covered work, 559 | but the special requirements of the GNU Affero General Public License, 560 | section 13, concerning interaction through a network will apply to the 561 | combination as such. 562 | 563 | 14. Revised Versions of this License. 564 | 565 | The Free Software Foundation may publish revised and/or new versions of 566 | the GNU General Public License from time to time. Such new versions will 567 | be similar in spirit to the present version, but may differ in detail to 568 | address new problems or concerns. 569 | 570 | Each version is given a distinguishing version number. If the 571 | Program specifies that a certain numbered version of the GNU General 572 | Public License "or any later version" applies to it, you have the 573 | option of following the terms and conditions either of that numbered 574 | version or of any later version published by the Free Software 575 | Foundation. If the Program does not specify a version number of the 576 | GNU General Public License, you may choose any version ever published 577 | by the Free Software Foundation. 578 | 579 | If the Program specifies that a proxy can decide which future 580 | versions of the GNU General Public License can be used, that proxy's 581 | public statement of acceptance of a version permanently authorizes you 582 | to choose that version for the Program. 583 | 584 | Later license versions may give you additional or different 585 | permissions. However, no additional obligations are imposed on any 586 | author or copyright holder as a result of your choosing to follow a 587 | later version. 588 | 589 | 15. Disclaimer of Warranty. 590 | 591 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY 592 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT 593 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY 594 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, 595 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 596 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM 597 | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF 598 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 599 | 600 | 16. Limitation of Liability. 601 | 602 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 603 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS 604 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY 605 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE 606 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF 607 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD 608 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), 609 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF 610 | SUCH DAMAGES. 611 | 612 | 17. Interpretation of Sections 15 and 16. 613 | 614 | If the disclaimer of warranty and limitation of liability provided 615 | above cannot be given local legal effect according to their terms, 616 | reviewing courts shall apply local law that most closely approximates 617 | an absolute waiver of all civil liability in connection with the 618 | Program, unless a warranty or assumption of liability accompanies a 619 | copy of the Program in return for a fee. 620 | 621 | END OF TERMS AND CONDITIONS 622 | 623 | How to Apply These Terms to Your New Programs 624 | 625 | If you develop a new program, and you want it to be of the greatest 626 | possible use to the public, the best way to achieve this is to make it 627 | free software which everyone can redistribute and change under these terms. 628 | 629 | To do so, attach the following notices to the program. It is safest 630 | to attach them to the start of each source file to most effectively 631 | state the exclusion of warranty; and each file should have at least 632 | the "copyright" line and a pointer to where the full notice is found. 633 | 634 | 635 | Copyright (C) 636 | 637 | This program is free software: you can redistribute it and/or modify 638 | it under the terms of the GNU General Public License as published by 639 | the Free Software Foundation, either version 3 of the License, or 640 | (at your option) any later version. 641 | 642 | This program is distributed in the hope that it will be useful, 643 | but WITHOUT ANY WARRANTY; without even the implied warranty of 644 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 645 | GNU General Public License for more details. 646 | 647 | You should have received a copy of the GNU General Public License 648 | along with this program. If not, see . 649 | 650 | Also add information on how to contact you by electronic and paper mail. 651 | 652 | If the program does terminal interaction, make it output a short 653 | notice like this when it starts in an interactive mode: 654 | 655 | Copyright (C) 656 | This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 657 | This is free software, and you are welcome to redistribute it 658 | under certain conditions; type `show c' for details. 659 | 660 | The hypothetical commands `show w' and `show c' should show the appropriate 661 | parts of the General Public License. Of course, your program's commands 662 | might be different; for a GUI interface, you would use an "about box". 663 | 664 | You should also get your employer (if you work as a programmer) or school, 665 | if any, to sign a "copyright disclaimer" for the program, if necessary. 666 | For more information on this, and how to apply and follow the GNU GPL, see 667 | . 668 | 669 | The GNU General Public License does not permit incorporating your program 670 | into proprietary programs. If your program is a subroutine library, you 671 | may consider it more useful to permit linking proprietary applications with 672 | the library. If this is what you want to do, use the GNU Lesser General 673 | Public License instead of this License. But first, please read 674 | . 675 | -------------------------------------------------------------------------------- /ProjectSettings/AudioManager.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leon196/CurveModifier/adcd27ae180c31bf5ce01896009a4c0b9aeb7a40/ProjectSettings/AudioManager.asset -------------------------------------------------------------------------------- /ProjectSettings/ClusterInputManager.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leon196/CurveModifier/adcd27ae180c31bf5ce01896009a4c0b9aeb7a40/ProjectSettings/ClusterInputManager.asset -------------------------------------------------------------------------------- /ProjectSettings/DynamicsManager.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leon196/CurveModifier/adcd27ae180c31bf5ce01896009a4c0b9aeb7a40/ProjectSettings/DynamicsManager.asset -------------------------------------------------------------------------------- /ProjectSettings/EditorBuildSettings.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leon196/CurveModifier/adcd27ae180c31bf5ce01896009a4c0b9aeb7a40/ProjectSettings/EditorBuildSettings.asset -------------------------------------------------------------------------------- /ProjectSettings/EditorSettings.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leon196/CurveModifier/adcd27ae180c31bf5ce01896009a4c0b9aeb7a40/ProjectSettings/EditorSettings.asset -------------------------------------------------------------------------------- /ProjectSettings/GraphicsSettings.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leon196/CurveModifier/adcd27ae180c31bf5ce01896009a4c0b9aeb7a40/ProjectSettings/GraphicsSettings.asset -------------------------------------------------------------------------------- /ProjectSettings/InputManager.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leon196/CurveModifier/adcd27ae180c31bf5ce01896009a4c0b9aeb7a40/ProjectSettings/InputManager.asset -------------------------------------------------------------------------------- /ProjectSettings/NavMeshAreas.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leon196/CurveModifier/adcd27ae180c31bf5ce01896009a4c0b9aeb7a40/ProjectSettings/NavMeshAreas.asset -------------------------------------------------------------------------------- /ProjectSettings/NetworkManager.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leon196/CurveModifier/adcd27ae180c31bf5ce01896009a4c0b9aeb7a40/ProjectSettings/NetworkManager.asset -------------------------------------------------------------------------------- /ProjectSettings/Physics2DSettings.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leon196/CurveModifier/adcd27ae180c31bf5ce01896009a4c0b9aeb7a40/ProjectSettings/Physics2DSettings.asset -------------------------------------------------------------------------------- /ProjectSettings/ProjectSettings.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leon196/CurveModifier/adcd27ae180c31bf5ce01896009a4c0b9aeb7a40/ProjectSettings/ProjectSettings.asset -------------------------------------------------------------------------------- /ProjectSettings/ProjectVersion.txt: -------------------------------------------------------------------------------- 1 | m_EditorVersion: 2017.3.1f1 2 | -------------------------------------------------------------------------------- /ProjectSettings/QualitySettings.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leon196/CurveModifier/adcd27ae180c31bf5ce01896009a4c0b9aeb7a40/ProjectSettings/QualitySettings.asset -------------------------------------------------------------------------------- /ProjectSettings/TagManager.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leon196/CurveModifier/adcd27ae180c31bf5ce01896009a4c0b9aeb7a40/ProjectSettings/TagManager.asset -------------------------------------------------------------------------------- /ProjectSettings/TimeManager.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leon196/CurveModifier/adcd27ae180c31bf5ce01896009a4c0b9aeb7a40/ProjectSettings/TimeManager.asset -------------------------------------------------------------------------------- /ProjectSettings/UnityConnectSettings.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leon196/CurveModifier/adcd27ae180c31bf5ce01896009a4c0b9aeb7a40/ProjectSettings/UnityConnectSettings.asset -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ### Update Feb 19, 2018 : Very simple curve modifier example 2 | 3 | 4 | 5 | 6 | #### The curve modifier in a vertex shader 7 | ```HLSL 8 | float current = fmod(position.y, 1.); 9 | float next = fmod(current + .01, 1.); 10 | 11 | float3 curvePosition = tex2Dlod(_CurveTexture, float4(current,0,0,0)).xyz; 12 | float3 curvePositionNext = tex2Dlod(_CurveTexture, float4(next,0,0,0)).xyz; 13 | 14 | float3 forward = normalize(curvePositionNext - curvePosition); 15 | float3 up = normalize(cross(normalize(curvePositionNext), normalize(curvePosition))); 16 | float3 right = normalize(cross(forward, up)); 17 | 18 | float angle = atan2(position.z, position.x); 19 | float radius = length(position.xz); 20 | position.xyz = curvePosition + (right * cos(angle) + up * sin(angle)) * radius; 21 | ``` 22 | 23 | [SimpleCurveModifier.shader](https://github.com/leon196/CurveModifier/blob/master/Assets/SimpleCurveModifier/SimpleCurveModifier.shader) 24 | 25 | [Fish mesh by Shakiller - CC Attribution](https://sketchfab.com/models/358ad8ccbc1740af8c13f019d90adb18#) 26 | 27 | ### Update Jun 8, 2016 : fixed curve issue 28 | - bezier curve edits can now be undo. 29 | - deformation is now smooth all along the path 30 | 31 | 32 | 33 | # What is happening in this gif ? 34 | 35 | A 3D model of a dragon is being deformed in real-time along a curve with a vertex shader. 36 | The curve is made by following a physicalized box. 37 | 38 | 39 | 40 | 41 | # The story behind a gif 42 | 43 | I've discovered the **curve modifier** in [Blender](https://www.blender.org) and really love it. 44 | People on Twitter went crazy with the gif below, so I always wanted to share how to do it. 45 | 46 | 47 | 48 | 49 | # And ? 50 | 51 | One night I couldn't sleep, because I had an intuition. 52 | I thought I could make the maths for the curve modifier above. 53 | 54 | 55 | 56 | Turns out it is always more complicated than excepted. 57 | It took me time to figure out the geometry involved. 58 | Struggling with maths is hard and frustrating. 59 | But what a satisfaction when things work! 60 | 61 | #### No interpolation 62 | The gif below is the first tentative. 63 | It looks cool, but it is not perfect. 64 | It needs a smooth linear interpolation. 65 | 66 | 67 | 68 | #### With interpolation 69 | This is mainly because I used an array of float to pass positions to the shader. 70 | And I've discovered that you could just send float within a texture. 71 | It's great because texture gets a linear interpolation filter. 72 | 73 | 74 | 75 | #### Warning 76 | It is almost working like a charm, but my curve modifier still got weird glitches. 77 | I guess I'm fine with it since I'm just doing it to mess with shaders. 78 | 79 | # Let's do it in Unity3D with a vertex shader ! 80 | 81 | In this repository, you will find the scripts and the shader. 82 | 83 | 84 | 85 | The **CurveModifier.cs** is the base script used to simplify different cases of application. 86 | His main function is to translate an array of vector into a texture. 87 | An important information is that the texture format is **RGBAFloat**. 88 | It allows the texture to store 32 bit floats, and so positions. 89 | 90 | #### Simplified version of what CurveModifier.cs does 91 | ```javascript 92 | void Init () { 93 | texture = new Texture2D(resolution, 1, TextureFormat.RGBAFloat, false); 94 | colorArray = new Color[resolution]; 95 | vectorArray = new Vector3[resolution]; 96 | } 97 | 98 | // Get a curve point with a clamped ratio 99 | public Vector3 GetCurvePoint (float ratio) { 100 | return vectorArray[ (int) Mathf.Floor ( vectorArray.Length * ratio ) ]; 101 | } 102 | 103 | // Store points into a texture 104 | public void CurveToTexture () { 105 | for (int i = 0; i < resolution; ++i) { 106 | float ratio = i / (float)resolution; 107 | Vector3 p = GetCurvePoint(ratio); 108 | colorArray[i] = new Color(p.x, p.y, p.z, 0.0); 109 | } 110 | texture.SetPixels(colorArray); 111 | texture.Apply(); 112 | } 113 | ``` 114 | 115 | So for example we can use a Bezier Curve like [this one on the Asset Store](https://www.assetstore.unity3d.com/#!/content/11278). 116 | And then just fill the vector array with the bezier points. 117 | You can check **BezierCurveModifier.cs** that uses the bezier package. 118 | 119 | #### Let's get scared at looking the vertex shader 120 | ```javascript 121 | // this function set the vertex position 122 | v2f vert (appdata v) 123 | { 124 | // unity stuff 125 | v2f o; 126 | 127 | // use transform component 128 | float4 vertex = mul(_Object2World, v.vertex); 129 | 130 | // axis setup (compress vectors into scalars) 131 | float vertexForward = vertex.x * _Forward.x + vertex.y * _Forward.y + vertex.z * _Forward.z; 132 | float vertexRight = vertex.x * _Right.x + vertex.y * _Right.y + vertex.z * _Right.z; 133 | float vertexUp = vertex.x * _Up.x + vertex.y * _Up.y + vertex.z * _Up.z; 134 | 135 | // the actual clamped ratio position on the curve 136 | float ratio = abs(vertexForward + _Time.x * _TimeSpeed); 137 | ratio = lerp(clamp(ratio, 0.0, 1.0), fmod(ratio, 1.0), _ShouldLoop); 138 | 139 | // used to distribute point on the plane that is perpendicular to the curve forward 140 | float angle = atan2(vertexUp, vertexRight); 141 | float radius = length(float2(vertexRight, vertexUp)); 142 | 143 | // get current point through the texture 144 | float4 p = float4(ratio, 0.0, 0.0, 0.0); 145 | float3 bezierPoint = mul(_World2Object, tex2Dlod(_CurveTexture, p)); 146 | 147 | // get neighbors of the current ratio 148 | float unit = 1.0 / _CurveResolution; 149 | float ratioNext = fmod(ratio + unit, 1.0); 150 | float ratioPrevious = fmod(ratio - unit + 1.0, 1.0); 151 | 152 | // make things loop or not 153 | ratioNext = lerp(clamp(abs(ratio + unit), 0.0, 1.0), ratioNext, _ShouldLoop); 154 | ratioPrevious = lerp(clamp(abs(ratio - unit), 0.0, 1.0), ratioPrevious, _ShouldLoop); 155 | 156 | // get next and previous point through the texture 157 | p.x = ratioNext; 158 | float3 bezierPointNext = mul(_World2Object, tex2Dlod(_CurveTexture, p)); 159 | p.x = ratioPrevious; 160 | float3 bezierPointPrevious = mul(_World2Object, tex2Dlod(_CurveTexture, p)); 161 | 162 | // find out vectors 163 | float3 forward = normalize(bezierPointNext - bezierPoint); 164 | float3 backward = normalize(bezierPointPrevious - bezierPoint); 165 | float3 up = normalize(cross(forward, backward)); 166 | float3 right = normalize(cross(forward, up)); 167 | 168 | // voila 169 | vertex.xyz = bezierPoint + right * cos(angle) * radius + up * sin(angle) * radius; 170 | 171 | // unity stuff 172 | o.vertex = mul(UNITY_MATRIX_MVP, vertex); 173 | o.uv = TRANSFORM_TEX(v.uv, _MainTex); 174 | return o; 175 | } 176 | ``` 177 | 178 | Looks like hieroglyphs, right ? I still can't believe it works. 179 | My methodology is to change a + into a * and watch if things get better. 180 | And with luck, sometimes you find the right combination. 181 | 182 | # Let's play with the examples 183 | 184 | ## Things to know about the curve modifier 185 | 186 | #### You have to find the right curve axis. 187 | 188 | 189 | #### Changing position and rotation will have consequences 190 | 191 | 192 | #### ~~You can change the scale to adjust the curve distribution~~ 193 | 194 | 195 | #### You can adjust the curve distribution with these two parameters 196 | 197 | 198 | #### ~~There is chance that you will need a bigger culling bounds~~ 199 | ~~Because the shader won't change the mesh bounds.~~ 200 | ~~So the camera can be out of range.~~ 201 | ~~And the model can disappear from the frustum culling.~~ 202 | 203 | 204 | 205 | #### Culling bounds is now auto calculated 206 | 207 | ## Things to know about the Bezier Curve modifier 208 | 209 | You can modify the spline to change the curve. 210 | 211 | 212 | 213 | You can change the cycle offset speed. 214 | 215 | 216 | 217 | ## Things to know about the Follow Curve modifier 218 | 219 | You can change the how quick you follow the target. 220 | 221 | 222 | 223 | # Alright folks 224 | 225 | Of course there is lot of things left to do. Like bugs fix, solid curve system and better user experience. 226 | But I am just having fun with vertex shaders on my free time and feel satisfied with the actual prototype. 227 | Feels free to contact me if you want to improve the project. 228 | 229 | I would love to hear about your project if you are using my shader. 230 | You can contact me on Twitter : [@leondenise](https://www.twitter.com/leondenise) 231 | And please share your code like everyone else in this open source community <3 232 | -------------------------------------------------------------------------------- /UnityPackageManager/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | } 4 | } 5 | -------------------------------------------------------------------------------- /images/217.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leon196/CurveModifier/adcd27ae180c31bf5ce01896009a4c0b9aeb7a40/images/217.gif -------------------------------------------------------------------------------- /images/228.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leon196/CurveModifier/adcd27ae180c31bf5ce01896009a4c0b9aeb7a40/images/228.gif -------------------------------------------------------------------------------- /images/235.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leon196/CurveModifier/adcd27ae180c31bf5ce01896009a4c0b9aeb7a40/images/235.gif -------------------------------------------------------------------------------- /images/242.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leon196/CurveModifier/adcd27ae180c31bf5ce01896009a4c0b9aeb7a40/images/242.gif -------------------------------------------------------------------------------- /images/243.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leon196/CurveModifier/adcd27ae180c31bf5ce01896009a4c0b9aeb7a40/images/243.gif -------------------------------------------------------------------------------- /images/244.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leon196/CurveModifier/adcd27ae180c31bf5ce01896009a4c0b9aeb7a40/images/244.gif -------------------------------------------------------------------------------- /images/245.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leon196/CurveModifier/adcd27ae180c31bf5ce01896009a4c0b9aeb7a40/images/245.gif -------------------------------------------------------------------------------- /images/246.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leon196/CurveModifier/adcd27ae180c31bf5ce01896009a4c0b9aeb7a40/images/246.gif -------------------------------------------------------------------------------- /images/247.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leon196/CurveModifier/adcd27ae180c31bf5ce01896009a4c0b9aeb7a40/images/247.gif -------------------------------------------------------------------------------- /images/251.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leon196/CurveModifier/adcd27ae180c31bf5ce01896009a4c0b9aeb7a40/images/251.gif -------------------------------------------------------------------------------- /images/254.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leon196/CurveModifier/adcd27ae180c31bf5ce01896009a4c0b9aeb7a40/images/254.gif -------------------------------------------------------------------------------- /images/29.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leon196/CurveModifier/adcd27ae180c31bf5ce01896009a4c0b9aeb7a40/images/29.gif -------------------------------------------------------------------------------- /images/81.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leon196/CurveModifier/adcd27ae180c31bf5ce01896009a4c0b9aeb7a40/images/81.gif -------------------------------------------------------------------------------- /images/81.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leon196/CurveModifier/adcd27ae180c31bf5ce01896009a4c0b9aeb7a40/images/81.png -------------------------------------------------------------------------------- /images/maths.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leon196/CurveModifier/adcd27ae180c31bf5ce01896009a4c0b9aeb7a40/images/maths.jpg -------------------------------------------------------------------------------- /images/maxpayne1.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leon196/CurveModifier/adcd27ae180c31bf5ce01896009a4c0b9aeb7a40/images/maxpayne1.gif -------------------------------------------------------------------------------- /images/snake1.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leon196/CurveModifier/adcd27ae180c31bf5ce01896009a4c0b9aeb7a40/images/snake1.PNG -------------------------------------------------------------------------------- /images/ui1.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leon196/CurveModifier/adcd27ae180c31bf5ce01896009a4c0b9aeb7a40/images/ui1.PNG -------------------------------------------------------------------------------- /images/ui2.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leon196/CurveModifier/adcd27ae180c31bf5ce01896009a4c0b9aeb7a40/images/ui2.PNG -------------------------------------------------------------------------------- /images/ui3.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leon196/CurveModifier/adcd27ae180c31bf5ce01896009a4c0b9aeb7a40/images/ui3.gif --------------------------------------------------------------------------------