diff --git a/Assets/Prefab/Corner.prefab b/Assets/Prefab/Corner.prefab new file mode 100644 index 0000000..c2a7dd4 --- /dev/null +++ b/Assets/Prefab/Corner.prefab @@ -0,0 +1,86 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1 &8436342362251790789 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 3267798293087391163} + - component: {fileID: 8123763127160245226} + m_Layer: 0 + m_Name: Corner + m_TagString: Debug + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &3267798293087391163 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8436342362251790789} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 2.3934019, y: -0.570142, z: 0} + m_LocalScale: {x: 0.25, y: 0.25, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 0} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!212 &8123763127160245226 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8436342362251790789} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 10754, guid: 0000000000000000f000000000000000, type: 0} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 10 + m_Sprite: {fileID: -2413806693520163455, guid: a86470a33a6bf42c4b3595704624658b, type: 3} + m_Color: {r: 0.8679245, g: 0.23394188, b: 0.23394188, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 0 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 diff --git a/Assets/Prefab/Corner.prefab.meta b/Assets/Prefab/Corner.prefab.meta new file mode 100644 index 0000000..0eb18d0 --- /dev/null +++ b/Assets/Prefab/Corner.prefab.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 36301c8c8d0592e4f9b221b3e3a2dbfb +PrefabImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Prefab/Line.prefab b/Assets/Prefab/Line.prefab new file mode 100644 index 0000000..81b0722 --- /dev/null +++ b/Assets/Prefab/Line.prefab @@ -0,0 +1,149 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1 &7699902697329990514 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 6710405407982841221} + - component: {fileID: 1357702157035357323} + - component: {fileID: 2121914630852398314} + m_Layer: 0 + m_Name: Line + m_TagString: Line + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &6710405407982841221 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7699902697329990514} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 0} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!120 &1357702157035357323 +LineRenderer: + serializedVersion: 2 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7699902697329990514} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 0 + m_LightProbeUsage: 0 + m_ReflectionProbeUsage: 0 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 10306, guid: 0000000000000000f000000000000000, type: 0} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 3 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 5 + m_Positions: [] + m_Parameters: + serializedVersion: 3 + widthMultiplier: 0.2 + widthCurve: + serializedVersion: 2 + m_Curve: + - serializedVersion: 3 + time: 0 + value: 1 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + weightedMode: 0 + inWeight: 0.33333334 + outWeight: 0.33333334 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + colorGradient: + serializedVersion: 2 + key0: {r: 1, g: 1, b: 1, a: 1} + key1: {r: 1, g: 1, b: 1, a: 1} + key2: {r: 0, g: 0, b: 0, a: 0} + key3: {r: 0, g: 0, b: 0, a: 0} + key4: {r: 0, g: 0, b: 0, a: 0} + key5: {r: 0, g: 0, b: 0, a: 0} + key6: {r: 0, g: 0, b: 0, a: 0} + key7: {r: 0, g: 0, b: 0, a: 0} + ctime0: 0 + ctime1: 65535 + ctime2: 0 + ctime3: 0 + ctime4: 0 + ctime5: 0 + ctime6: 0 + ctime7: 0 + atime0: 0 + atime1: 65535 + atime2: 0 + atime3: 0 + atime4: 0 + atime5: 0 + atime6: 0 + atime7: 0 + m_Mode: 0 + m_ColorSpace: -1 + m_NumColorKeys: 2 + m_NumAlphaKeys: 2 + numCornerVertices: 10 + numCapVertices: 0 + alignment: 0 + textureMode: 0 + textureScale: {x: 1, y: 1} + shadowBias: 0.5 + generateLightingData: 0 + m_MaskInteraction: 0 + m_UseWorldSpace: 1 + m_Loop: 0 + m_ApplyActiveColorSpace: 1 +--- !u!114 &2121914630852398314 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7699902697329990514} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4943222137739f4dac023bf5bfe8bdb, type: 3} + m_Name: + m_EditorClassIdentifier: diff --git a/Assets/Prefab/Line.prefab.meta b/Assets/Prefab/Line.prefab.meta new file mode 100644 index 0000000..0fcf6ee --- /dev/null +++ b/Assets/Prefab/Line.prefab.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 9bfd9c62c84e72e4a91cc92140c1fa0d +PrefabImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Prefab/LineDebug.prefab b/Assets/Prefab/LineDebug.prefab new file mode 100644 index 0000000..5f9e06a --- /dev/null +++ b/Assets/Prefab/LineDebug.prefab @@ -0,0 +1,136 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1 &7699902697329990514 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 6710405407982841221} + - component: {fileID: 1357702157035357323} + m_Layer: 0 + m_Name: LineDebug + m_TagString: Debug + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &6710405407982841221 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7699902697329990514} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 0} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!120 &1357702157035357323 +LineRenderer: + serializedVersion: 2 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7699902697329990514} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 0 + m_LightProbeUsage: 0 + m_ReflectionProbeUsage: 0 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 10306, guid: 0000000000000000f000000000000000, type: 0} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 3 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 5 + m_Positions: [] + m_Parameters: + serializedVersion: 3 + widthMultiplier: 0.1 + widthCurve: + serializedVersion: 2 + m_Curve: + - serializedVersion: 3 + time: 0 + value: 1 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + weightedMode: 0 + inWeight: 0.33333334 + outWeight: 0.33333334 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + colorGradient: + serializedVersion: 2 + key0: {r: 1, g: 1, b: 1, a: 1} + key1: {r: 1, g: 1, b: 1, a: 1} + key2: {r: 0, g: 0, b: 0, a: 0} + key3: {r: 0, g: 0, b: 0, a: 0} + key4: {r: 0, g: 0, b: 0, a: 0} + key5: {r: 0, g: 0, b: 0, a: 0} + key6: {r: 0, g: 0, b: 0, a: 0} + key7: {r: 0, g: 0, b: 0, a: 0} + ctime0: 0 + ctime1: 65535 + ctime2: 0 + ctime3: 0 + ctime4: 0 + ctime5: 0 + ctime6: 0 + ctime7: 0 + atime0: 0 + atime1: 65535 + atime2: 0 + atime3: 0 + atime4: 0 + atime5: 0 + atime6: 0 + atime7: 0 + m_Mode: 0 + m_ColorSpace: -1 + m_NumColorKeys: 2 + m_NumAlphaKeys: 2 + numCornerVertices: 10 + numCapVertices: 0 + alignment: 0 + textureMode: 0 + textureScale: {x: 1, y: 1} + shadowBias: 0.5 + generateLightingData: 0 + m_MaskInteraction: 0 + m_UseWorldSpace: 1 + m_Loop: 0 + m_ApplyActiveColorSpace: 1 diff --git a/Assets/Prefab/LineDebug.prefab.meta b/Assets/Prefab/LineDebug.prefab.meta new file mode 100644 index 0000000..0b32737 --- /dev/null +++ b/Assets/Prefab/LineDebug.prefab.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: f65d4bf0b26f7754db3d3b3449ea5069 +PrefabImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scenes/SampleScene.unity b/Assets/Scenes/SketchTest.unity similarity index 69% rename from Assets/Scenes/SampleScene.unity rename to Assets/Scenes/SketchTest.unity index 8531273..4264a0a 100644 --- a/Assets/Scenes/SampleScene.unity +++ b/Assets/Scenes/SketchTest.unity @@ -160,7 +160,7 @@ Camera: m_Enabled: 1 serializedVersion: 2 m_ClearFlags: 2 - m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0} + m_BackGroundColor: {r: 0.21960786, g: 0.21960786, b: 0.21960786, a: 0} m_projectionMatrixMode: 1 m_GateFitMode: 2 m_FOVAxisMode: 0 @@ -232,8 +232,70 @@ MonoBehaviour: serializedVersion: 2 m_Bits: 4294967295 m_MaxRayIntersections: 0 +--- !u!1001 &973154724 +PrefabInstance: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_Modification: + serializedVersion: 3 + m_TransformParent: {fileID: 0} + m_Modifications: + - target: {fileID: 2121914630852398314, guid: 9bfd9c62c84e72e4a91cc92140c1fa0d, type: 3} + propertyPath: debugObject + value: + objectReference: {fileID: 8436342362251790789, guid: 36301c8c8d0592e4f9b221b3e3a2dbfb, type: 3} + - target: {fileID: 6710405407982841221, guid: 9bfd9c62c84e72e4a91cc92140c1fa0d, type: 3} + propertyPath: m_LocalPosition.x + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 6710405407982841221, guid: 9bfd9c62c84e72e4a91cc92140c1fa0d, type: 3} + propertyPath: m_LocalPosition.y + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 6710405407982841221, guid: 9bfd9c62c84e72e4a91cc92140c1fa0d, type: 3} + propertyPath: m_LocalPosition.z + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 6710405407982841221, guid: 9bfd9c62c84e72e4a91cc92140c1fa0d, type: 3} + propertyPath: m_LocalRotation.w + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 6710405407982841221, guid: 9bfd9c62c84e72e4a91cc92140c1fa0d, type: 3} + propertyPath: m_LocalRotation.x + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 6710405407982841221, guid: 9bfd9c62c84e72e4a91cc92140c1fa0d, type: 3} + propertyPath: m_LocalRotation.y + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 6710405407982841221, guid: 9bfd9c62c84e72e4a91cc92140c1fa0d, type: 3} + propertyPath: m_LocalRotation.z + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 6710405407982841221, guid: 9bfd9c62c84e72e4a91cc92140c1fa0d, type: 3} + propertyPath: m_LocalEulerAnglesHint.x + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 6710405407982841221, guid: 9bfd9c62c84e72e4a91cc92140c1fa0d, type: 3} + propertyPath: m_LocalEulerAnglesHint.y + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 6710405407982841221, guid: 9bfd9c62c84e72e4a91cc92140c1fa0d, type: 3} + propertyPath: m_LocalEulerAnglesHint.z + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 7699902697329990514, guid: 9bfd9c62c84e72e4a91cc92140c1fa0d, type: 3} + propertyPath: m_Name + value: Line + objectReference: {fileID: 0} + m_RemovedComponents: [] + m_RemovedGameObjects: [] + m_AddedGameObjects: [] + m_AddedComponents: [] + m_SourcePrefab: {fileID: 100100000, guid: 9bfd9c62c84e72e4a91cc92140c1fa0d, type: 3} --- !u!1660057539 &9223372036854775807 SceneRoots: m_ObjectHideFlags: 0 m_Roots: - {fileID: 519420032} + - {fileID: 973154724} diff --git a/Assets/Scenes/SampleScene.unity.meta b/Assets/Scenes/SketchTest.unity.meta similarity index 100% rename from Assets/Scenes/SampleScene.unity.meta rename to Assets/Scenes/SketchTest.unity.meta diff --git a/Assets/Scripts/ExtraMath.cs b/Assets/Scripts/ExtraMath.cs new file mode 100644 index 0000000..bc315e5 --- /dev/null +++ b/Assets/Scripts/ExtraMath.cs @@ -0,0 +1,71 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +public class ExtraMath : MonoBehaviour +{ + public static float Sum(float[] values) + { + float sum = 0; + foreach (float value in values) + { + sum += value; + } + return sum; + } + + public static float[] PerpendicularBisect(Vector3 begin, Vector3 end) + { + float slope = (end.y - begin.y) / (end.x - begin.x) + 0.00000000001f; + slope = -1 / slope; + Vector3 centerPoint = new Vector3((begin.x + end.x) / 2, ((begin.y + end.y) / 2), 0); + float yIntercept = centerPoint.y - (centerPoint.x * slope); + + // RecognizerDebuger.Instance.DrawLine(new float[] {slope, yIntercept}); + return new float[] { slope, yIntercept }; + } + + public static Vector2 LineIntercept(float[] line1, float[] line2) + { + float x = (line2[1] - line1[1]) / (line1[0] - line2[0] + 0.0000001f); + float y = line1[0] * x + line1[1]; + + return new Vector3(x, y, 0); + } + + public static void LinearRegression(Vector3[] points, out float rSquared, out float yIntercept, out float slope) + { + float sumOfX = 0; + float sumOfY = 0; + float sumOfXSq = 0; + float sumOfYSq = 0; + float sumCodeviates = 0; + + for (var i = 0; i < points.Length; i++) + { + var x = points[i].x; + var y = points[i].y; + sumCodeviates += x * y; + sumOfX += x; + sumOfY += y; + sumOfXSq += x * x; + sumOfYSq += y * y; + } + + var count = points.Length; + var ssX = sumOfXSq - ((sumOfX * sumOfX) / count); + var ssY = sumOfYSq - ((sumOfY * sumOfY) / count); + + var rNumerator = (count * sumCodeviates) - (sumOfX * sumOfY); + var rDenom = (count * sumOfXSq - (sumOfX * sumOfX)) * (count * sumOfYSq - (sumOfY * sumOfY)); + var sCo = sumCodeviates - ((sumOfX * sumOfY) / count); + + var meanX = sumOfX / count; + var meanY = sumOfY / count; + var dblR = rNumerator / Mathf.Sqrt(rDenom); + + rSquared = dblR * dblR; + yIntercept = meanY - ((sCo / ssX) * meanX); + slope = sCo / ssX; + } +} diff --git a/Assets/Scripts/ExtraMath.cs.meta b/Assets/Scripts/ExtraMath.cs.meta new file mode 100644 index 0000000..c92c95a --- /dev/null +++ b/Assets/Scripts/ExtraMath.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 801afb66c9a7b0249a9a4d9a65aa0f71 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/LineDrawer.cs b/Assets/Scripts/LineDrawer.cs new file mode 100644 index 0000000..276f44f --- /dev/null +++ b/Assets/Scripts/LineDrawer.cs @@ -0,0 +1,120 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +public class LineDrawer : MonoBehaviour +{ + public GameObject debugObject; + + private LineRenderer currentLine; + + private void Start() + { + currentLine = GetComponent(); + } + + private void Update() + { + if (Input.touchCount == 0) + { + return; + } + + Touch touch = Input.GetTouch(0); + switch (touch.phase) + { + case TouchPhase.Began: + AddPoint(currentLine, touch.position); + break; + case TouchPhase.Moved: + if (Vector3.Distance(AdjustPointToScreen(5, touch.position), + currentLine.GetPosition(currentLine.positionCount - 1)) > 0.1f) + { + AddPoint(currentLine, touch.position); + } + + // RecognizerDebuger.Instance.DeleteDebug(); + + Vector3[] points = new Vector3[currentLine.positionCount]; + currentLine.GetPositions(points); + + // float[] direction = PreRecognition.DirectionChangeCalculator(points); + // float[] curvature = PreRecognition.CurvatureCalculator(points, direction); + // int[] corners = PreRecognition.CornerCalculator(points, PreRecognition.LineLengthCalculator(points), + // curvature); + + // foreach (int corner in corners) + // { + // Vector3 cornerPosition = points[corner]; + // RecognizerDebuger.Instance.CornerDebuger(cornerPosition); + // } + + // PrimitiveContainer[] primitives = HighLevelRecognition.PrimitiveShapeGenerator(points); + // string primOutput = "Primitives: "; + // foreach(PrimitiveContainer p in primitives) + // { + // if (p.Type == 0) + // { + // primOutput = primOutput + ", Line"; + // } + // else + // { + // primOutput = primOutput + ", Arc"; + // } + // } + // Debug.Log(primOutput); + break; + case TouchPhase.Ended: + + Vector3[] points2 = new Vector3[currentLine.positionCount]; + currentLine.GetPositions(points2); + // TemplateCreator.Instance.AddJSON(HighLevelRecognition.PrimitiveShapeGenerator(points2)); + PrimitiveContainer[] primitives = HighLevelRecognition.PrimitiveShapeGenerator(points2); + Debug.Log(SketchOutput.Output(primitives)); + currentLine.positionCount = 0; + break; + case TouchPhase.Canceled: + // ShapeRecognition.Calculate(); + currentLine.positionCount = 0; + break; + } + } + + private void RemoveDuplicates(LineRenderer lineRenderer) + { + Vector3 previousPoint = lineRenderer.GetPosition(lineRenderer.positionCount - 2); + Vector3 currentPoint = lineRenderer.GetPosition(lineRenderer.positionCount - 1); + + if (previousPoint[0] == currentPoint[0] && previousPoint[1] == currentPoint[1]) + { + lineRenderer.positionCount--; + } + } + + private void AddPoint(LineRenderer lineRenderer, Vector3 position) + { + lineRenderer.positionCount++; + lineRenderer.SetPosition(lineRenderer.positionCount - 1, AdjustPointToScreen(5, position)); + } + + private Vector3 AdjustPointToScreen(float cameraHeight, Vector3 position) + { + // Center the point to the screen + position.x = position.x - (Screen.width / 2f); + position.y = position.y - (Screen.height / 2f); + + // Adjust the point to the camera + position.x = (position.x / Screen.width) * cameraHeight * (Screen.width / (float)Screen.height) * 2f; + position.y = (position.y / Screen.height) * cameraHeight * 2f; + + return position; + } + + private void OnApplicationPause(bool pause) + { + if (pause == true) + { + Destroy(currentLine); + } + } +} diff --git a/Assets/Scripts/LineDrawer.cs.meta b/Assets/Scripts/LineDrawer.cs.meta new file mode 100644 index 0000000..2ac70ad --- /dev/null +++ b/Assets/Scripts/LineDrawer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f4943222137739f4dac023bf5bfe8bdb +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/MobileFramerateCap.cs b/Assets/Scripts/MobileFramerateCap.cs new file mode 100644 index 0000000..009fc49 --- /dev/null +++ b/Assets/Scripts/MobileFramerateCap.cs @@ -0,0 +1,11 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +public class MobileFramerateCap : MonoBehaviour +{ + void Start() + { + Application.targetFrameRate = 60; + } +} diff --git a/Assets/Scripts/MobileFramerateCap.cs.meta b/Assets/Scripts/MobileFramerateCap.cs.meta new file mode 100644 index 0000000..4d29a34 --- /dev/null +++ b/Assets/Scripts/MobileFramerateCap.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 01765cea177b78b42b57acdac4dcb12f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Recognition.meta b/Assets/Scripts/Recognition.meta new file mode 100644 index 0000000..507c3f1 --- /dev/null +++ b/Assets/Scripts/Recognition.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 6dac1d84f4bd9cb43a3dbf8acaa9f3d2 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Recognition/DebugJSON.meta b/Assets/Scripts/Recognition/DebugJSON.meta new file mode 100644 index 0000000..f271c0c --- /dev/null +++ b/Assets/Scripts/Recognition/DebugJSON.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 08da41962ac141340900b887ce94fb2f +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Recognition/DebugJSON/SketchAnaylsis.cs b/Assets/Scripts/Recognition/DebugJSON/SketchAnaylsis.cs new file mode 100644 index 0000000..46ef128 --- /dev/null +++ b/Assets/Scripts/Recognition/DebugJSON/SketchAnaylsis.cs @@ -0,0 +1,81 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; +using System.IO; +using Newtonsoft.Json; + +public class SketchAnaylsis : MonoBehaviour +{ + public string fileName = ""; + + void Start() + { + string filePath = Application.dataPath + "/" + fileName + ".json"; + List sketchList; + + if (File.Exists(filePath)) + { + string fileContents = File.ReadAllText(filePath); + sketchList = JsonConvert.DeserializeObject>(fileContents); + } + else + { + return; + } + + List lineDeviationList = new List(); + List circleDeviationList = new List(); + List arcSizeList = new List(); + List listDCR = new List(); + List listNDDE = new List(); + + foreach (Vector3[] points in sketchList) + { + float[] directionSlice = PreRecognition.DirectionChangeCalculator(points); + lineDeviationList.Add(ShapeRecognition.LineDeviation(points)); + float[] circle = ShapeRecognition.CircleDeviation(points); + circleDeviationList.Add(circle[0]); + arcSizeList.Add(circle[1]); + listDCR.Add(PreRecognition.DCR_Calculator(directionSlice)); + listNDDE.Add(PreRecognition.NDDE_Calculator(directionSlice, points)); + } + + lineDeviationList.Sort(); + circleDeviationList.Sort(); + arcSizeList.Sort(); + listDCR.Sort(); + listNDDE.Sort(); + + Debug.Log("Line Deviation -> " + QuartileRange(lineDeviationList)); + Debug.Log("Circle Deviation -> " + QuartileRange(circleDeviationList)); + Debug.Log("Arc Size -> " + QuartileRange(arcSizeList)); + Debug.Log("DCR -> " + QuartileRange(listDCR)); + Debug.Log("NDDE -> " + QuartileRange(listNDDE)); + } + + public string StandardDeviation(List list) + { + float sum = 0; + foreach (float f in list) + { + sum += f; + } + float average = sum / list.Count; + float variance = 0; + foreach (float f in list) + { + variance += (f - average) * (f - average); + } + variance /= list.Count; + float standardDeviation = Mathf.Sqrt(variance); + return "Average: " + average + " Standard Deviation: " + standardDeviation; + } + + public string QuartileRange(List list) + { + float q1 = list[list.Count / 4]; + float q2 = list[list.Count / 2]; + float q3 = list[list.Count * 3 / 4]; + return "Q1: " + q1 + " Q2: " + q2 + " Q3: " + q3; + } +} diff --git a/Assets/Scripts/Recognition/DebugJSON/SketchAnaylsis.cs.meta b/Assets/Scripts/Recognition/DebugJSON/SketchAnaylsis.cs.meta new file mode 100644 index 0000000..1808d43 --- /dev/null +++ b/Assets/Scripts/Recognition/DebugJSON/SketchAnaylsis.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5248eee77821b34439167f4876259508 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Recognition/DebugJSON/SketchJsonStorage.cs b/Assets/Scripts/Recognition/DebugJSON/SketchJsonStorage.cs new file mode 100644 index 0000000..bd02d86 --- /dev/null +++ b/Assets/Scripts/Recognition/DebugJSON/SketchJsonStorage.cs @@ -0,0 +1,36 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; +using System.IO; +using Newtonsoft.Json; + +public class SketchJsonStorage : MonoBehaviour +{ + + public static SketchJsonStorage Instance = null; + public string fileName; + public List sketchList = new List(); + + public void Awake() + { + Instance = this; + } + + public void AddJSON(Vector3[] sketch) + { + string filePath = Application.dataPath + "/" + fileName + ".json"; + + if (File.Exists(filePath)) + { + string fileContents = File.ReadAllText(filePath); + sketchList = JsonConvert.DeserializeObject>(fileContents); + } + + sketchList.Add(sketch); + + string json = JsonConvert.SerializeObject( + sketchList, Formatting.Indented, + new JsonSerializerSettings { ReferenceLoopHandling = ReferenceLoopHandling.Ignore }); + File.WriteAllText(filePath, json); + } +} diff --git a/Assets/Scripts/Recognition/DebugJSON/SketchJsonStorage.cs.meta b/Assets/Scripts/Recognition/DebugJSON/SketchJsonStorage.cs.meta new file mode 100644 index 0000000..1eac95b --- /dev/null +++ b/Assets/Scripts/Recognition/DebugJSON/SketchJsonStorage.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 36804f1139d8d854c922d0b74315dde1 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Recognition/DebugJSON/TemplateCreator.cs b/Assets/Scripts/Recognition/DebugJSON/TemplateCreator.cs new file mode 100644 index 0000000..56e2438 --- /dev/null +++ b/Assets/Scripts/Recognition/DebugJSON/TemplateCreator.cs @@ -0,0 +1,28 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; +using System.IO; +using Newtonsoft.Json; + +public class TemplateCreator : MonoBehaviour +{ + public static TemplateCreator Instance = null; + public string fileName; + public List sketchList = new List(); + + public void Awake() + { + Instance = this; + } + + public void AddJSON(PrimitiveContainer[] sketch) + { + string filePath = Application.dataPath + "/" + fileName + ".json"; + + string json = JsonConvert.SerializeObject( + sketch, Formatting.Indented, + new JsonSerializerSettings { ReferenceLoopHandling = ReferenceLoopHandling.Ignore, + NullValueHandling = NullValueHandling.Ignore }); + File.WriteAllText(filePath, json); + } +} diff --git a/Assets/Scripts/Recognition/DebugJSON/TemplateCreator.cs.meta b/Assets/Scripts/Recognition/DebugJSON/TemplateCreator.cs.meta new file mode 100644 index 0000000..7b746f7 --- /dev/null +++ b/Assets/Scripts/Recognition/DebugJSON/TemplateCreator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5344db1702382834bb9e88a48d4d8ed1 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Recognition/HighLevelRecognition.cs b/Assets/Scripts/Recognition/HighLevelRecognition.cs new file mode 100644 index 0000000..0422072 --- /dev/null +++ b/Assets/Scripts/Recognition/HighLevelRecognition.cs @@ -0,0 +1,157 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; +using System.Linq; + +public class HighLevelRecognition : MonoBehaviour +{ + public static float RadianConvert(float radian) + { + radian = radian % (2 * Mathf.PI); + if (radian < 0) + { + radian += 2 * Mathf.PI; + } + return radian; + } + + public static PrimitiveContainer[] PrimitiveShapeGenerator(Vector3[] points) + { + if (points.Length <= 6) + { + return new PrimitiveContainer[] {}; + } + List primitives = new List(); + float[] direction = PreRecognition.DirectionChangeCalculator(points); + int[] corners = PreRecognition.CornerCalculator(points, PreRecognition.LineLengthCalculator(points), + PreRecognition.CurvatureCalculator(points, direction)); + int i = 2; + while (i < corners.Length) + { + Vector3[] pointSlice = points[corners[i - 2]..corners[i]]; + float[] directionSlice = PreRecognition.DirectionChangeCalculator(pointSlice); + float lineDeviation = ShapeRecognition.LineDeviation(pointSlice); + float[] circle = ShapeRecognition.CircleDeviation(pointSlice); + float DCR = PreRecognition.DCR_Calculator(directionSlice); + float NDDE = PreRecognition.NDDE_Calculator(directionSlice, pointSlice); + if (circle[1] < 0.2f) + { + if (DCR > 3f && lineDeviation > 0.1f) + { + // Is Polyline + PrimitiveContainer line = new PrimitiveContainer(); + line.Length = PreRecognition.LineLengthCalculator(pointSlice).Last(); + line.Rotation = Mathf.Atan2(pointSlice[corners[i - 1] - corners[i - 2]].y - pointSlice[0].y, + pointSlice[corners[i - 1] - corners[i - 2]].x - pointSlice[0].x); + line.Type = 0; + primitives.Add(line); + i += 1; + } + else + { + // Is Line + PrimitiveContainer line = new PrimitiveContainer(); + line.Length = PreRecognition.LineLengthCalculator(pointSlice).Last(); + line.Rotation = Mathf.Atan2(pointSlice[pointSlice.Length - 1].y - pointSlice[0].y, + pointSlice[pointSlice.Length - 1].x - pointSlice[0].x); + line.Type = 0; + primitives.Add(line); + + i += 2; + } + } + else + { + if (circle[0] < lineDeviation && DCR < 3.5f && NDDE > 0.65f) + { + // Is Arc, Keep going + int current = i; + for (int u = i + 1; u < corners.Length; u++) + { + pointSlice = points[corners[i - 2]..corners[u]]; + directionSlice = PreRecognition.DirectionChangeCalculator(pointSlice); + lineDeviation = ShapeRecognition.LineDeviation(pointSlice); + circle = ShapeRecognition.CircleDeviation(pointSlice); + direction = PreRecognition.DirectionChangeCalculator(pointSlice); + DCR = PreRecognition.DCR_Calculator(directionSlice); + NDDE = PreRecognition.NDDE_Calculator(directionSlice, pointSlice); + + if (circle[0] < lineDeviation && circle[1] < 1.2 && DCR < 3.5f && NDDE > 0.7f) + { + current = u; + continue; + } + else + { + break; + } + } + PrimitiveContainer arc = new PrimitiveContainer(); + arc.Type = 1; + arc.Length = PreRecognition.LineLengthCalculator(points[corners[i - 2]..corners[current]]).Last(); + arc.ConcaveUp = ShapeRecognition.IsConcaveUp(pointSlice, points[corners[i - 1]]); + arc.Completeness = circle[1]; + arc.Rotation = ShapeRecognition.ArcRotation(pointSlice); + primitives.Add(arc); + i = current + 2; + } + else + { + if (DCR > 3f && lineDeviation > 0.2f) + { + // Is Polyline + PrimitiveContainer line = new PrimitiveContainer(); + line.Length = PreRecognition.LineLengthCalculator(pointSlice).Last(); + line.Rotation = Mathf.Atan2(pointSlice[corners[i - 1] - corners[i - 2]].y - pointSlice[0].y, + pointSlice[corners[i - 1] - corners[i - 2]].x - pointSlice[0].x); + line.Type = 0; + primitives.Add(line); + i += 1; + } + else + { + // Is Line + PrimitiveContainer line = new PrimitiveContainer(); + line.Length = PreRecognition.LineLengthCalculator(pointSlice).Last(); + line.Rotation = Mathf.Atan2(pointSlice[pointSlice.Length - 1].y - pointSlice[0].y, + pointSlice[pointSlice.Length - 1].x - pointSlice[0].x); + line.Type = 0; + primitives.Add(line); + i += 2; + } + } + } + } + if (i == corners.Length) + { + Vector3[] pointSlice = points[corners[i - 2]..corners[i - 1]]; + PrimitiveContainer line = new PrimitiveContainer(); + line.Length = PreRecognition.LineLengthCalculator(pointSlice).Last(); + line.Rotation = Mathf.Atan2(pointSlice[pointSlice.Length - 1].y - pointSlice[0].y, + pointSlice[pointSlice.Length - 1].x - pointSlice[0].x); + line.Type = 0; + primitives.Add(line); + } + float rotationStart = primitives[0].Rotation; + + // Set the first rotation to 0, and the rest to the difference between the first and the current + primitives[0].Rotation = 0.0f; + for (int a = 1; a < primitives.Count; a++) + { + primitives[a].Rotation = RadianConvert(primitives[a].Rotation - rotationStart); + } + + // Normalize the length of the primitives + float totalLength = 0.0f; + foreach (PrimitiveContainer p in primitives) + { + totalLength += p.Length; + } + + for (int a = 0; a < primitives.Count; a++) + { + primitives[a].Length = primitives[a].Length / totalLength; + } + return primitives.ToArray(); + } +} diff --git a/Assets/Scripts/Recognition/HighLevelRecognition.cs.meta b/Assets/Scripts/Recognition/HighLevelRecognition.cs.meta new file mode 100644 index 0000000..2d205a1 --- /dev/null +++ b/Assets/Scripts/Recognition/HighLevelRecognition.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6bcc4ffd6abec4247af5fef2f514619b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Recognition/PreRecognition.cs b/Assets/Scripts/Recognition/PreRecognition.cs new file mode 100644 index 0000000..477b184 --- /dev/null +++ b/Assets/Scripts/Recognition/PreRecognition.cs @@ -0,0 +1,302 @@ +using System.Collections; +using System.Collections.Generic; +using System; +using UnityEngine; + +public class PreRecognition : MonoBehaviour +{ + public static Vector3[] TestCorner(Vector3[] points, float[] curvature) + { + List cornerList = new List(); + cornerList.Add(points[0]); + // Caculates corner range by comparing the distance between points and the line length + for (int i = 1; i < points.Length; i++) + { + if (curvature[i] > 3.5f) + { + cornerList.Add(points[i]); + } + } + + // Keeps endpoints as corners + cornerList.Add(points[points.Length - 1]); + + return cornerList.ToArray(); + } + + public static int[] CornerCalculator(Vector3[] points, float[] lineLength, float[] curvature) + { + int currentCorner = 0; + List cornerList = new List(); + cornerList.Add(0.0f); + float totalCurvature = ExtraMath.Sum(curvature); + int count = 0; + // Caculates corner range by comparing the distance between points and the line length + for (int i = 1; i < points.Length; i++) + { + // 0.955 doesn't over create points + if (Vector3.Distance(points[currentCorner], points[i]) / (lineLength[i] - lineLength[currentCorner]) <= + 0.9f) + { + currentCorner = i; + cornerList.Add(i); + count += 1; + } + } + + // Keeps endpoints as corners + cornerList.Add(points.Length - 1); + count += 1; + + // Finds the exact corner using the highest curvature + List exactCorner = new List(); + exactCorner.Add(0); + for (int cornerIndex = 1; cornerIndex < count; cornerIndex++) + { + int start = (int)cornerList[cornerIndex] - + (int)Mathf.Ceil((cornerList[cornerIndex] - cornerList[cornerIndex - 1]) / 2.65f); + start = Mathf.Max(0, start); + + int end = (int)cornerList[cornerIndex] + + (int)Mathf.Ceil((cornerList[cornerIndex + 1] - cornerList[cornerIndex]) / 2.65f); + end = Mathf.Min(points.Length, end); + float max = 0.0f; + int maxIndex = 0; + + for (int i = start; i < end; i++) + { + if (max < curvature[i]) + { + max = curvature[i]; + maxIndex = i; + } + } + exactCorner.Add(maxIndex); + } + exactCorner.Add(points.Length - 1); + + return exactCorner.ToArray(); + } + + public static float[] CurvatureCalculator(Vector3[] points, float[] directions) + { + float[] curvature = new float[points.Length]; + curvature[0] = 0.0f; + for (int i = 1; i < points.Length; i++) + { + float angle = Mathf.Abs(directions[i] - directions[i - 1]); + float distance = Vector3.Distance(points[i], points[i - 1]); + curvature[i] = angle / distance; + } + return curvature; + } + + public static float CornerDeviation(float[] curvature) + { + int endTail = (int)Mathf.Ceil(0.9f * curvature.Length); + int beginingTail = (int)Math.Floor(0.1f * curvature.Length); + float[] curvatureTrim = new float[endTail - beginingTail]; + for (int i = beginingTail; i < endTail; i++) + { + curvatureTrim[i - beginingTail] = curvature[i]; + } + + float curveAverage = ExtraMath.Sum(curvatureTrim) / curvatureTrim.Length; + float deviationPercent = 0.0f; + + foreach (float curve in curvatureTrim) + { + deviationPercent += Mathf.Abs(curve - curveAverage) / curveAverage; + } + + return deviationPercent / curvatureTrim.Length; + } + + // public static int[] ArcDifferentiantion(float[] curvature, int[] corners, Vector3[] points) + // { + // List arcList = new List(); + // int i = 0; + // int u = 2; + // float[] directionArray = PreRecognition.DirectionChangeCalculator(points); + + // while (u < corners.Length) + // { + // Vector3[] pointSlice = new ArraySegment(points, corners[i], corners[u] - corners[i]).ToArray(); + // float[] directionSlice = new ArraySegment(directionArray, corners[i], corners[u] - + // corners[i]).ToArray(); + + // float NDDE = PreRecognition.NDDE_Calculator(directionSlice, pointSlice); + // float DCR = PreRecognition.DCR_Calculator(directionSlice); + + // if (DCR < 3.2f && NDDE > 0.7f) + // { + // u += 1; + // } + // else if (ShapeRecognition.IsLine(pointSlice)) + // { + // arcList.Add(0); + // i = u; + // u += 2; + // } + // else + // { + // if (u - i > 2) + // { + // arcList.Add(1); + // } + // else + // { + // arcList.Add(0); + // } + // i = u - 1; + // u = i + 2; + // } + // } + + // if (u - i > 2) + // { + // arcList.Add(1); + // } + // else if (corners.Length - 1 > i) + // { + // arcList.Add(0); + // } + // return arcList.ToArray(); + // } + + public static float[] DirectionChangeCalculator(Vector3[] points) + { + float[] direction = new float[points.Length]; + direction[0] = 0.0f; + int[] completeRev = new int[points.Length]; + + // Calculates direction + for (int i = 0; i < points.Length - 1; i++) + { + direction[i + 1] = Mathf.Atan2(points[i + 1].y - points[i].y, points[i + 1].x - points[i].x); + } + + // Calculates the completed rotation + for (int i = 1; i < direction.Length; i++) + { + completeRev[i] = completeRev[i - 1]; + if (Mathf.Abs(direction[i - 1]) >= 2.0f && Mathf.Sign(direction[i - 1]) != Mathf.Sign(direction[i])) + { + if (Mathf.Sign(direction[i - 1]) == 1.0f) + { + completeRev[i] += 1; + } + else + { + completeRev[i] -= 1; + } + } + } + + // Adds value for each completed rotation + for (int i = 0; i < direction.Length; i++) + { + direction[i] += Mathf.PI * completeRev[i] * 2.0f; + } + return direction; + } + + public static float RadianCalculator(float[] direction) + { + // Takes the total rotation and checks if it is over 1.31 radians after removing tails + int beginingTail = (int)Mathf.Floor(direction.Length * 0.03f); + int endingTail = (int)Mathf.Floor(direction.Length * 0.97f); + + return Mathf.Abs(direction[endingTail] - direction[beginingTail]) / (Mathf.PI * 2.0f); + } + + public static bool ClosedFigureCalculator(Vector3[] points, float radians) + { + float endDistance = Vector3.Distance(points[0], points[points.Length - 1]); + float lineLength = 0.0f; + for (int i = 1; i < points.Length; i++) + { + lineLength += Mathf.Abs(Vector3.Distance(points[i], points[i - 1])); + } + if (endDistance / lineLength < 0.16f && radians > 0.75f) + { + return true; + } + else + { + return false; + } + } + + public static bool OvertracedCalculator(float radians) + { + if (radians > 1.25f) + { + return true; + } + else + { + return false; + } + } + + public static float[] LineLengthCalculator(Vector3[] points) + { + float[] lineLength = new float[points.Length]; + for (int i = 1; i < points.Length; i++) + { + lineLength[i] = lineLength[i - 1] + Mathf.Abs(Vector3.Distance(points[i], points[i - 1])); + } + return lineLength; + } + + public static float DCR_Calculator(float[] direction) + { + if (direction.Length < 5) + { + return 0.0f; + } + + int beginingTail = (int)Mathf.Floor(direction.Length * 0.1f); + int endingTail = (int)Mathf.Floor(direction.Length * 0.9f); + float maxDC = 0.0f; + float sumDC = 0.0f; + for (int i = beginingTail; i < endingTail; i++) + { + float directionChange = Mathf.Abs(direction[i + 1] - direction[i]); + if (directionChange > maxDC) + { + maxDC = directionChange; + } + sumDC += directionChange; + } + float averageDC = sumDC / (endingTail - beginingTail); + return maxDC / averageDC; + } + + public static float NDDE_Calculator(float[] direction, Vector3[] points) + { + float highestDirection = -10000.0f; + int highestPoint = 0; + float lowestDirection = 1000000.0f; + int lowestPoint = 0; + float[] lineLength = LineLengthCalculator(points); + lineLength[0] = 0.0f; + int completeRev = 0; + + for (int i = 1; i < direction.Length; i++) + { + if (direction[i] + Mathf.PI * completeRev > highestDirection) + { + highestDirection = direction[i] + Mathf.PI * completeRev; + highestPoint = i - 1; + } + if (direction[i] + Mathf.PI * completeRev < lowestDirection) + { + lowestDirection = direction[i] + Mathf.PI * completeRev; + lowestPoint = i - 1; + } + } + return Mathf.Abs(lineLength[highestPoint] - lineLength[lowestPoint]) / lineLength[lineLength.Length - 1]; + } +} diff --git a/Assets/Scripts/Recognition/PreRecognition.cs.meta b/Assets/Scripts/Recognition/PreRecognition.cs.meta new file mode 100644 index 0000000..5e51e53 --- /dev/null +++ b/Assets/Scripts/Recognition/PreRecognition.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d88510e2a0777a241a89ac752ede579c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Recognition/PrimitiveContainer.cs b/Assets/Scripts/Recognition/PrimitiveContainer.cs new file mode 100644 index 0000000..3746989 --- /dev/null +++ b/Assets/Scripts/Recognition/PrimitiveContainer.cs @@ -0,0 +1,15 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +public class PrimitiveContainer +{ + // General + public int Type = 0; // 0 = Line, 1 = Arc + public float Rotation = 0.0f; // Rotation of the primitive + public float Length = 0.0f; // Length of the primitive + + // Arc/Circle Specific + public bool ConcaveUp = false; // Whether the arc is concave up or down + public float Completeness = 0.0f; // How much of the circle is drawn +} diff --git a/Assets/Scripts/Recognition/PrimitiveContainer.cs.meta b/Assets/Scripts/Recognition/PrimitiveContainer.cs.meta new file mode 100644 index 0000000..d0cd750 --- /dev/null +++ b/Assets/Scripts/Recognition/PrimitiveContainer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2920e61892d451b4d9716f1c19e453b0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Recognition/RecognizerDebuger.cs b/Assets/Scripts/Recognition/RecognizerDebuger.cs new file mode 100644 index 0000000..36c31c8 --- /dev/null +++ b/Assets/Scripts/Recognition/RecognizerDebuger.cs @@ -0,0 +1,44 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +public class RecognizerDebuger : MonoBehaviour +{ + public static RecognizerDebuger Instance; + public GameObject Line; + public GameObject Corner; + + public void Awake() + { + Instance = this; + } + + public void CornerDebuger(Vector3 cornerPoint) + { + Instantiate(Corner, cornerPoint, Quaternion.identity); + } + + public void DeleteDebug() + { + GameObject[] corners = GameObject.FindGameObjectsWithTag("Debug"); + foreach (GameObject corner in corners) + { + Destroy(corner); + } + } + + public void DrawLine(float[] lineEquation) + { + Vector3 startPoint = new Vector3(0, -5, 0); + Vector3 endPoint = new Vector3(0, 5, 0); + + startPoint.x = (startPoint.y - lineEquation[1]) / lineEquation[0]; + endPoint.x = (endPoint.y - lineEquation[1]) / lineEquation[0]; + + GameObject line = Instantiate(Line, Vector3.zero, Quaternion.identity); + + LineRenderer lineRenderer = line.GetComponent(); + lineRenderer.positionCount = 2; + lineRenderer.SetPositions(new Vector3[] { startPoint, endPoint }); + } +} diff --git a/Assets/Scripts/Recognition/RecognizerDebuger.cs.meta b/Assets/Scripts/Recognition/RecognizerDebuger.cs.meta new file mode 100644 index 0000000..a13d35a --- /dev/null +++ b/Assets/Scripts/Recognition/RecognizerDebuger.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 24e506f99554fc646874098a9f1ae935 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Recognition/ShapeRecognition.cs b/Assets/Scripts/Recognition/ShapeRecognition.cs new file mode 100644 index 0000000..781fa60 --- /dev/null +++ b/Assets/Scripts/Recognition/ShapeRecognition.cs @@ -0,0 +1,118 @@ +using System.Collections; +using System.Linq; +using System.Collections.Generic; +using UnityEngine; + +public class ShapeRecognition : MonoBehaviour +{ + public static float LineDeviation(Vector3[] points) + { + float rSquared; + float yIntercept; + float slope; + + ExtraMath.LinearRegression(points, out rSquared, out yIntercept, out slope); + float totalDeviation = 0f; + + // Calculates deviation from best fit line + for (int i = 0; i < points.Length; i++) + { + float y = yIntercept + slope * points[i].x; + totalDeviation += Mathf.Abs(points[i].y - y); + } + + return totalDeviation / points.Length; + } + + public static float[] CircleDeviation(Vector3[] points) + { + + float lineLength = 0.0f; + + for (int i = 1; i < points.Length; i++) + { + lineLength += Mathf.Abs(Vector3.Distance(points[i], points[i - 1])); + } + + Vector3 centerPoint = FindCenterpoint(points); + // Find the average radius + float radius = 0.0f; + + for (int i = 0; i < points.Length; i++) + { + radius += Vector3.Distance(points[i], centerPoint); + } + radius /= points.Length; + + float deviationTotal = 0.0f; + + foreach (Vector3 point in points) + { + deviationTotal += Mathf.Abs(Vector3.Distance(point, centerPoint) - radius) / radius; + } + + return new float[] { deviationTotal / points.Length, lineLength / (radius * 2 * Mathf.PI) }; + } + + public static Vector3 FindCenterpoint(Vector3[] points) + { + // Perpendicular bisectors intersect at the center of the circle + int pq = (int)(points.Length / 3); + float[] line1 = ExtraMath.PerpendicularBisect(points[0], points[pq]); + float[] line2 = ExtraMath.PerpendicularBisect(points[pq], points[pq * 2]); + float[] line3 = ExtraMath.PerpendicularBisect(points[pq * 2], points[points.Length - 1]); + + Vector3 center1 = ExtraMath.LineIntercept(line1, line2); + Vector3 center2 = ExtraMath.LineIntercept(line1, line3); + Vector3 center3 = ExtraMath.LineIntercept(line2, line3); + + Vector3 centerPoint; + + float distance1 = Vector3.Distance(center1, center2); + float distance2 = Vector3.Distance(center2, center3); + float distance3 = Vector3.Distance(center1, center3); + + // Find the two closest points and average them to find the center + if (distance1 <= distance2 && distance1 <= distance3) + { + centerPoint = new Vector3((center1.x + center2.x) / 2, (center1.y + center2.y) / 2, 0); + } + else if (distance2 <= distance1 && distance2 <= distance3) + { + centerPoint = new Vector3((center2.x + center3.x) / 2, (center2.y + center3.y) / 2, 0); + } + else + { + centerPoint = new Vector3((center1.x + center3.x) / 2, (center1.y + center3.y) / 2, 0); + } + return centerPoint; + } + + public static bool IsConcaveUp(Vector3[] points, Vector3 corner) + { + Vector3 centerPoint = FindCenterpoint(points); + + float startToCenter = Mathf.Atan2(centerPoint.y - points[0].y, centerPoint.x - points[0].x); + float centerToCorner = Mathf.Atan2(corner.y - centerPoint.y, corner.x - centerPoint.x); + + centerToCorner = centerToCorner - startToCenter; + if (centerToCorner < 0) + { + centerToCorner += 2 * Mathf.PI; + } + if (centerToCorner < Mathf.PI) + { + return false; + } + else + { + return true; + } + } + + public static float ArcRotation(Vector3[] points) + { + Vector3 centerPoint = FindCenterpoint(points); + return Mathf.Atan2(points[points.Length - 1].y - centerPoint.y, points[points.Length - 1].x - centerPoint.x); + } +} diff --git a/Assets/Scripts/Recognition/ShapeRecognition.cs.meta b/Assets/Scripts/Recognition/ShapeRecognition.cs.meta new file mode 100644 index 0000000..aae9d44 --- /dev/null +++ b/Assets/Scripts/Recognition/ShapeRecognition.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0179145accdd76a4f83731b6534632b2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Recognition/SketchOutput.cs b/Assets/Scripts/Recognition/SketchOutput.cs new file mode 100644 index 0000000..7140a3a --- /dev/null +++ b/Assets/Scripts/Recognition/SketchOutput.cs @@ -0,0 +1,118 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; +using System.IO; +using Newtonsoft.Json; + +public class SketchOutput : MonoBehaviour +{ + public static string Output(PrimitiveContainer[] sketch) + { + string filePath = Application.dataPath + "/Templates/Lightning.json"; + string fileContents = File.ReadAllText(filePath); + PrimitiveContainer[] template = JsonConvert.DeserializeObject(fileContents); + if (Compare(sketch, template)) + { + return "Lightning"; + } + + filePath = Application.dataPath + "/Templates/Shield.json"; + fileContents = File.ReadAllText(filePath); + template = JsonConvert.DeserializeObject(fileContents); + if (Compare(sketch, template)) + { + return "Shield"; + } + + filePath = Application.dataPath + "/Templates/Water.json"; + fileContents = File.ReadAllText(filePath); + template = JsonConvert.DeserializeObject(fileContents); + if (Compare(sketch, template)) + { + return "Water"; + } + + return "None"; + } + + public static bool Compare(PrimitiveContainer[] sketch, PrimitiveContainer[] template, float threshold = 0.25f) + { + float sizeCheck = (1.0f / template.Length) * 0.2f; + int u = 0; + bool? concaveReverse = null; + + for (int i = 0; i < sketch.Length; i++) + { + if (sketch[i].Length < sizeCheck) + { + continue; + } + if (template.Length == u) + { + return false; + } + if (sketch[i].Type != template[u].Type) + { + return false; + } + if (thresholdCheck(sketch[i].Length, template[u].Length, threshold) && + radianThresholdCheck(sketch[i].Rotation, template[u].Rotation, 1.5f)) + { + if (sketch[i].Type == 1) + { + if (concaveReverse == null) + { + concaveReverse = sketch[i].ConcaveUp != template[u].ConcaveUp; + } + if (concaveReverse == true) + { + sketch[i].ConcaveUp = !sketch[i].ConcaveUp; + } + if (thresholdCheck(sketch[i].Completeness, template[u].Completeness, threshold) && + sketch[i].ConcaveUp == template[u].ConcaveUp) + { + u += 1; + } + } + else + { + u += 1; + } + } + else + { + return false; + } + } + return template.Length == u; + } + + private static bool thresholdCheck(float a, float b, float threshold) + { + return a * (1 - threshold) < b && a * (1 + threshold) > b; + } + + private static bool radianThresholdCheck(float a, float b, float radianThreshold) + { + if (b + radianThreshold > 2 * Mathf.PI) + { + if (a < b + radianThreshold - (2 * Mathf.PI)) + { + return true; + } + } + if (b - radianThreshold < 0) + { + if (b - radianThreshold + (2 * Mathf.PI) < a) + { + return true; + } + } + if (b - radianThreshold < a && a < b + radianThreshold) + { + return true; + } + + return false; + } +} diff --git a/Assets/Scripts/Recognition/SketchOutput.cs.meta b/Assets/Scripts/Recognition/SketchOutput.cs.meta new file mode 100644 index 0000000..ed5e58a --- /dev/null +++ b/Assets/Scripts/Recognition/SketchOutput.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 59fb4c610ce29194ebd767b1494bac53 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Templates.meta b/Assets/Templates.meta new file mode 100644 index 0000000..bfadaff --- /dev/null +++ b/Assets/Templates.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 0c1f0c5e8b4cf4d47bd730ae4fbc27f6 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Templates/Lightning.json b/Assets/Templates/Lightning.json new file mode 100644 index 0000000..b05a352 --- /dev/null +++ b/Assets/Templates/Lightning.json @@ -0,0 +1,23 @@ +[ + { + "Type": 0, + "Rotation": 0.0, + "Length": 0.4076188, + "ConcaveUp": false, + "Completeness": 0.0 + }, + { + "Type": 0, + "Rotation": 2.40771317, + "Length": 0.368411481, + "ConcaveUp": false, + "Completeness": 0.0 + }, + { + "Type": 0, + "Rotation": 6.26135445, + "Length": 0.223969668, + "ConcaveUp": false, + "Completeness": 0.0 + } +] \ No newline at end of file diff --git a/Assets/Templates/Lightning.json.meta b/Assets/Templates/Lightning.json.meta new file mode 100644 index 0000000..0157254 --- /dev/null +++ b/Assets/Templates/Lightning.json.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 03e8262b98dd15844953a199327e46cd +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Templates/Shield.json b/Assets/Templates/Shield.json new file mode 100644 index 0000000..b0fc25d --- /dev/null +++ b/Assets/Templates/Shield.json @@ -0,0 +1,9 @@ +[ + { + "Type": 1, + "Rotation": 0.0, + "Length": 1.0, + "ConcaveUp": false, + "Completeness": 1.0 + } +] \ No newline at end of file diff --git a/Assets/Templates/Shield.json.meta b/Assets/Templates/Shield.json.meta new file mode 100644 index 0000000..97cad35 --- /dev/null +++ b/Assets/Templates/Shield.json.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: c8c05874b22149e4ea4880d54c1344be +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Templates/Water.json b/Assets/Templates/Water.json new file mode 100644 index 0000000..d4d5074 --- /dev/null +++ b/Assets/Templates/Water.json @@ -0,0 +1,16 @@ +[ + { + "Type": 1, + "Rotation": 0.0, + "Length": 0.5047563, + "ConcaveUp": true, + "Completeness": 0.8546553 + }, + { + "Type": 1, + "Rotation": 0.5974314, + "Length": 0.495243728, + "ConcaveUp": true, + "Completeness": 0.505029261 + } +] \ No newline at end of file diff --git a/Assets/Templates/Water.json.meta b/Assets/Templates/Water.json.meta new file mode 100644 index 0000000..adfb348 --- /dev/null +++ b/Assets/Templates/Water.json.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 213445624567cf6459a132d66b8b8e9d +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/manifest.json b/Packages/manifest.json index 953588c..2a6f75a 100644 --- a/Packages/manifest.json +++ b/Packages/manifest.json @@ -7,6 +7,7 @@ "com.unity.ide.rider": "3.0.24", "com.unity.ide.visualstudio": "2.0.18", "com.unity.ide.vscode": "1.2.5", + "com.unity.nuget.newtonsoft-json": "3.2.1", "com.unity.test-framework": "1.1.33", "com.unity.textmeshpro": "3.0.6", "com.unity.timeline": "1.7.5", diff --git a/Packages/packages-lock.json b/Packages/packages-lock.json index 12df8d1..dd6dff6 100644 --- a/Packages/packages-lock.json +++ b/Packages/packages-lock.json @@ -219,6 +219,13 @@ }, "url": "https://packages.unity.com" }, + "com.unity.nuget.newtonsoft-json": { + "version": "3.2.1", + "depth": 0, + "source": "registry", + "dependencies": {}, + "url": "https://packages.unity.com" + }, "com.unity.profiling.core": { "version": "1.0.2", "depth": 2, diff --git a/Prefab/Corner.prefab b/Prefab/Corner.prefab new file mode 100644 index 0000000..c2a7dd4 --- /dev/null +++ b/Prefab/Corner.prefab @@ -0,0 +1,86 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1 &8436342362251790789 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 3267798293087391163} + - component: {fileID: 8123763127160245226} + m_Layer: 0 + m_Name: Corner + m_TagString: Debug + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &3267798293087391163 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8436342362251790789} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 2.3934019, y: -0.570142, z: 0} + m_LocalScale: {x: 0.25, y: 0.25, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 0} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!212 &8123763127160245226 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8436342362251790789} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 10754, guid: 0000000000000000f000000000000000, type: 0} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 10 + m_Sprite: {fileID: -2413806693520163455, guid: a86470a33a6bf42c4b3595704624658b, type: 3} + m_Color: {r: 0.8679245, g: 0.23394188, b: 0.23394188, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 0 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 diff --git a/Prefab/Corner.prefab.meta b/Prefab/Corner.prefab.meta new file mode 100644 index 0000000..0eb18d0 --- /dev/null +++ b/Prefab/Corner.prefab.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 36301c8c8d0592e4f9b221b3e3a2dbfb +PrefabImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Prefab/Line.prefab b/Prefab/Line.prefab new file mode 100644 index 0000000..81b0722 --- /dev/null +++ b/Prefab/Line.prefab @@ -0,0 +1,149 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1 &7699902697329990514 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 6710405407982841221} + - component: {fileID: 1357702157035357323} + - component: {fileID: 2121914630852398314} + m_Layer: 0 + m_Name: Line + m_TagString: Line + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &6710405407982841221 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7699902697329990514} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 0} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!120 &1357702157035357323 +LineRenderer: + serializedVersion: 2 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7699902697329990514} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 0 + m_LightProbeUsage: 0 + m_ReflectionProbeUsage: 0 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 10306, guid: 0000000000000000f000000000000000, type: 0} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 3 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 5 + m_Positions: [] + m_Parameters: + serializedVersion: 3 + widthMultiplier: 0.2 + widthCurve: + serializedVersion: 2 + m_Curve: + - serializedVersion: 3 + time: 0 + value: 1 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + weightedMode: 0 + inWeight: 0.33333334 + outWeight: 0.33333334 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + colorGradient: + serializedVersion: 2 + key0: {r: 1, g: 1, b: 1, a: 1} + key1: {r: 1, g: 1, b: 1, a: 1} + key2: {r: 0, g: 0, b: 0, a: 0} + key3: {r: 0, g: 0, b: 0, a: 0} + key4: {r: 0, g: 0, b: 0, a: 0} + key5: {r: 0, g: 0, b: 0, a: 0} + key6: {r: 0, g: 0, b: 0, a: 0} + key7: {r: 0, g: 0, b: 0, a: 0} + ctime0: 0 + ctime1: 65535 + ctime2: 0 + ctime3: 0 + ctime4: 0 + ctime5: 0 + ctime6: 0 + ctime7: 0 + atime0: 0 + atime1: 65535 + atime2: 0 + atime3: 0 + atime4: 0 + atime5: 0 + atime6: 0 + atime7: 0 + m_Mode: 0 + m_ColorSpace: -1 + m_NumColorKeys: 2 + m_NumAlphaKeys: 2 + numCornerVertices: 10 + numCapVertices: 0 + alignment: 0 + textureMode: 0 + textureScale: {x: 1, y: 1} + shadowBias: 0.5 + generateLightingData: 0 + m_MaskInteraction: 0 + m_UseWorldSpace: 1 + m_Loop: 0 + m_ApplyActiveColorSpace: 1 +--- !u!114 &2121914630852398314 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7699902697329990514} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4943222137739f4dac023bf5bfe8bdb, type: 3} + m_Name: + m_EditorClassIdentifier: diff --git a/Prefab/Line.prefab.meta b/Prefab/Line.prefab.meta new file mode 100644 index 0000000..0fcf6ee --- /dev/null +++ b/Prefab/Line.prefab.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 9bfd9c62c84e72e4a91cc92140c1fa0d +PrefabImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Prefab/LineDebug.prefab b/Prefab/LineDebug.prefab new file mode 100644 index 0000000..5f9e06a --- /dev/null +++ b/Prefab/LineDebug.prefab @@ -0,0 +1,136 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1 &7699902697329990514 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 6710405407982841221} + - component: {fileID: 1357702157035357323} + m_Layer: 0 + m_Name: LineDebug + m_TagString: Debug + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &6710405407982841221 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7699902697329990514} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 0} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!120 &1357702157035357323 +LineRenderer: + serializedVersion: 2 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7699902697329990514} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 0 + m_LightProbeUsage: 0 + m_ReflectionProbeUsage: 0 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 10306, guid: 0000000000000000f000000000000000, type: 0} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 3 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 5 + m_Positions: [] + m_Parameters: + serializedVersion: 3 + widthMultiplier: 0.1 + widthCurve: + serializedVersion: 2 + m_Curve: + - serializedVersion: 3 + time: 0 + value: 1 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + weightedMode: 0 + inWeight: 0.33333334 + outWeight: 0.33333334 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + colorGradient: + serializedVersion: 2 + key0: {r: 1, g: 1, b: 1, a: 1} + key1: {r: 1, g: 1, b: 1, a: 1} + key2: {r: 0, g: 0, b: 0, a: 0} + key3: {r: 0, g: 0, b: 0, a: 0} + key4: {r: 0, g: 0, b: 0, a: 0} + key5: {r: 0, g: 0, b: 0, a: 0} + key6: {r: 0, g: 0, b: 0, a: 0} + key7: {r: 0, g: 0, b: 0, a: 0} + ctime0: 0 + ctime1: 65535 + ctime2: 0 + ctime3: 0 + ctime4: 0 + ctime5: 0 + ctime6: 0 + ctime7: 0 + atime0: 0 + atime1: 65535 + atime2: 0 + atime3: 0 + atime4: 0 + atime5: 0 + atime6: 0 + atime7: 0 + m_Mode: 0 + m_ColorSpace: -1 + m_NumColorKeys: 2 + m_NumAlphaKeys: 2 + numCornerVertices: 10 + numCapVertices: 0 + alignment: 0 + textureMode: 0 + textureScale: {x: 1, y: 1} + shadowBias: 0.5 + generateLightingData: 0 + m_MaskInteraction: 0 + m_UseWorldSpace: 1 + m_Loop: 0 + m_ApplyActiveColorSpace: 1 diff --git a/Prefab/LineDebug.prefab.meta b/Prefab/LineDebug.prefab.meta new file mode 100644 index 0000000..0b32737 --- /dev/null +++ b/Prefab/LineDebug.prefab.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: f65d4bf0b26f7754db3d3b3449ea5069 +PrefabImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Tools/.clang-format b/Tools/.clang-format new file mode 100644 index 0000000..bb649bb --- /dev/null +++ b/Tools/.clang-format @@ -0,0 +1,10 @@ +# Copyright (c) TigardHighGDC +# SPDX-License SPDX-License-Identifier: Apache-2.0 + +--- +Language: CSharp +BasedOnStyle: Microsoft +IndentWidth: 4 +AccessModifierOffset: -4 +ColumnLimit: 120 +AllowShortFunctionsOnASingleLine: None diff --git a/UserSettings/Layouts/default-2022.dwlt b/UserSettings/Layouts/default-2022.dwlt index eb60435..1189de8 100644 --- a/UserSettings/Layouts/default-2022.dwlt +++ b/UserSettings/Layouts/default-2022.dwlt @@ -15,11 +15,11 @@ MonoBehaviour: m_PixelRect: serializedVersion: 2 x: 0 - y: 43.2 + y: 42 width: 1536 - height: 772.8 + height: 774 m_ShowMode: 4 - m_Title: Hierarchy + m_Title: Simulator m_RootView: {fileID: 2} m_MinSize: {x: 875, y: 300} m_MaxSize: {x: 10000, y: 10000} @@ -45,7 +45,7 @@ MonoBehaviour: x: 0 y: 0 width: 1536 - height: 772.8 + height: 774 m_MinSize: {x: 875, y: 300} m_MaxSize: {x: 10000, y: 10000} m_UseTopView: 1 @@ -90,7 +90,7 @@ MonoBehaviour: m_Position: serializedVersion: 2 x: 0 - y: 752.8 + y: 754 width: 1536 height: 20 m_MinSize: {x: 0, y: 0} @@ -115,11 +115,11 @@ MonoBehaviour: x: 0 y: 30 width: 1536 - height: 722.8 + height: 724 m_MinSize: {x: 300, y: 100} m_MaxSize: {x: 24288, y: 16192} vertical: 0 - controlID: 37 + controlID: 44 --- !u!114 &6 MonoBehaviour: m_ObjectHideFlags: 52 @@ -140,11 +140,11 @@ MonoBehaviour: x: 0 y: 0 width: 1172.8 - height: 722.8 + height: 724 m_MinSize: {x: 200, y: 100} m_MaxSize: {x: 16192, y: 16192} vertical: 1 - controlID: 38 + controlID: 45 --- !u!114 &7 MonoBehaviour: m_ObjectHideFlags: 52 @@ -165,7 +165,7 @@ MonoBehaviour: x: 0 y: 0 width: 1172.8 - height: 428.8 + height: 429.6 m_MinSize: {x: 200, y: 50} m_MaxSize: {x: 16192, y: 8096} vertical: 0 @@ -188,7 +188,7 @@ MonoBehaviour: x: 0 y: 0 width: 290.4 - height: 428.8 + height: 429.6 m_MinSize: {x: 201, y: 221} m_MaxSize: {x: 4001, y: 4021} m_ActualView: {fileID: 13} @@ -214,7 +214,7 @@ MonoBehaviour: x: 290.4 y: 0 width: 882.4 - height: 428.8 + height: 429.6 m_MinSize: {x: 202, y: 221} m_MaxSize: {x: 4002, y: 4021} m_ActualView: {fileID: 12} @@ -222,7 +222,7 @@ MonoBehaviour: - {fileID: 14} - {fileID: 12} m_Selected: 1 - m_LastSelected: 0 + m_LastSelected: 1 --- !u!114 &10 MonoBehaviour: m_ObjectHideFlags: 52 @@ -239,9 +239,9 @@ MonoBehaviour: m_Position: serializedVersion: 2 x: 0 - y: 428.8 + y: 429.6 width: 1172.8 - height: 294 + height: 294.4 m_MinSize: {x: 231, y: 271} m_MaxSize: {x: 10001, y: 10021} m_ActualView: {fileID: 15} @@ -268,7 +268,7 @@ MonoBehaviour: x: 1172.8 y: 0 width: 363.19995 - height: 722.8 + height: 724 m_MinSize: {x: 276, y: 71} m_MaxSize: {x: 4001, y: 4021} m_ActualView: {fileID: 17} @@ -297,9 +297,9 @@ MonoBehaviour: m_Pos: serializedVersion: 2 x: 290.4 - y: 73.6 + y: 72 width: 880.4 - height: 407.8 + height: 408.6 m_SerializedDataModeController: m_DataMode: 0 m_PreferredDataMode: 0 @@ -366,9 +366,9 @@ MonoBehaviour: m_Pos: serializedVersion: 2 x: 0 - y: 73.6 + y: 72 width: 289.4 - height: 407.8 + height: 408.6 m_SerializedDataModeController: m_DataMode: 0 m_PreferredDataMode: 0 @@ -382,9 +382,9 @@ MonoBehaviour: m_SceneHierarchy: m_TreeViewState: scrollPos: {x: 0, y: 0} - m_SelectedIDs: 7af8ffff - m_LastClickedID: -1926 - m_ExpandedIDs: 86f8ffff92f8ffff9cf8fffff4faffff + m_SelectedIDs: bc650000 + m_LastClickedID: 0 + m_ExpandedIDs: f2f9ffff m_RenameOverlay: m_UserAcceptedRename: 0 m_Name: @@ -790,9 +790,9 @@ MonoBehaviour: m_PlayAudio: 0 m_AudioPlay: 0 m_Position: - m_Target: {x: 540, y: 1169, z: 0} + m_Target: {x: 437, y: 189.8, z: 0} speed: 2 - m_Value: {x: 540, y: 1169, z: 0} + m_Value: {x: 437, y: 189.8, z: 0} m_RenderMode: 0 m_CameraMode: drawMode: 0 @@ -842,9 +842,9 @@ MonoBehaviour: speed: 2 m_Value: {x: 0, y: 0, z: 0, w: 1} m_Size: - m_Target: 1287.696 + m_Target: 476.43787 speed: 2 - m_Value: 1287.696 + m_Value: 476.43787 m_Ortho: m_Target: 1 speed: 2 @@ -890,9 +890,9 @@ MonoBehaviour: m_Pos: serializedVersion: 2 x: 0 - y: 502.4 + y: 501.6 width: 1171.8 - height: 273 + height: 273.4 m_SerializedDataModeController: m_DataMode: 0 m_PreferredDataMode: 0 @@ -914,7 +914,7 @@ MonoBehaviour: m_SkipHidden: 0 m_SearchArea: 1 m_Folders: - - Assets/Scripts + - Assets/Templates m_Globs: [] m_OriginalText: m_ImportLogFlags: 0 @@ -922,16 +922,16 @@ MonoBehaviour: m_ViewMode: 1 m_StartGridSize: 64 m_LastFolders: - - Assets/Scripts + - Assets/Templates m_LastFoldersGridSize: -1 - m_LastProjectPath: C:\Users\cwitt\Documents\GitHub\WizardGame + m_LastProjectPath: C:\Code\WizardGame m_LockTracker: m_IsLocked: 0 m_FolderTreeState: scrollPos: {x: 0, y: 0} - m_SelectedIDs: 94630000 - m_LastClickedID: 25492 - m_ExpandedIDs: 000000007463000076630000786300007a6300007c6300007e63000000ca9a3b + m_SelectedIDs: bc650000 + m_LastClickedID: 26044 + m_ExpandedIDs: 000000002a64000000ca9a3b m_RenameOverlay: m_UserAcceptedRename: 0 m_Name: @@ -959,7 +959,7 @@ MonoBehaviour: scrollPos: {x: 0, y: 0} m_SelectedIDs: m_LastClickedID: 0 - m_ExpandedIDs: 000000007463000076630000786300007a6300007c6300007e630000 + m_ExpandedIDs: 000000002a640000 m_RenameOverlay: m_UserAcceptedRename: 0 m_Name: @@ -1036,9 +1036,9 @@ MonoBehaviour: m_Pos: serializedVersion: 2 x: 0 - y: 502.4 + y: 501.6 width: 1171.8 - height: 273 + height: 273.4 m_SerializedDataModeController: m_DataMode: 0 m_PreferredDataMode: 0 @@ -1070,9 +1070,9 @@ MonoBehaviour: m_Pos: serializedVersion: 2 x: 1172.8 - y: 73.6 + y: 72 width: 362.19995 - height: 701.8 + height: 703 m_SerializedDataModeController: m_DataMode: 0 m_PreferredDataMode: 0