[
  {
    "path": ".gitignore",
    "content": "# =============== #\n# Unity generated #\n# =============== #\nTemp/\nObj/\nUnityGenerated/\nLibrary/\n\n# ===================================== #\n# Visual Studio / MonoDevelop generated #\n# ===================================== #\nExportedObj/\n*.svd\n*.userprefs\n*.csproj\n*.pidb\n*.suo\n*.sln\n*.user\n*.unityproj\n*.booproj\n.vs\n# ============ #\n# OS generated #\n# ============ #\n.DS_Store\n.DS_Store?\n._*\n.Spotlight-V100\n.Trashes\nIcon?\nehthumbs.db\nThumbs.db\ndemo/Assets/UnityVS/\n"
  },
  {
    "path": "MIT-LICENSE",
    "content": "Copyright (c) 2009 Alan Shaw\r\nUnity C# Translation Copyright (c) 2014 Julian Ceipek\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining\r\na copy of this software and associated documentation files (the\r\n\"Software\"), to deal in the Software without restriction, including\r\nwithout limitation the rights to use, copy, modify, merge, publish,\r\ndistribute, sublicense, and/or sell copies of the Software, and to\r\npermit persons to whom the Software is furnished to do so, subject to\r\nthe following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be\r\nincluded in all copies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\r\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\r\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\r\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\r\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE."
  },
  {
    "path": "README.md",
    "content": "polygon-map-unity\n==============\n\nA C#/Unity3d implementation of Polygon Map Generation per the article [here](http://www-cs-students.stanford.edu/~amitp/game-programming/polygon-map-generation/), using the\nas3delaunay library from [here](https://github.com/jceipek/Unity-delaunay)\n\n![Polygon Map Generator](/screenshot.PNG?raw=true)\n"
  },
  {
    "path": "demo/Assets/Camera.cs",
    "content": "﻿using UnityEngine;\nusing System.Collections;\nusing Assets.Map;\n\npublic class Camera : MonoBehaviour\n{\n    public Map Map;\n    float _mousePosX;\n    float _mousePosY;\n    float _scrollSpeed = 0.2f;\n    float _zoomSpeed = 1f;\n    Vector2 _mouseLeftClick;\n\n    void Update()\n    {\n        float deltaX = Input.mousePosition.x - _mousePosX;\n        float deltaY = Input.mousePosition.y - _mousePosY;\n        \n        _mousePosX = Input.mousePosition.x;\n        _mousePosY = Input.mousePosition.y;\n\n        if (Input.GetMouseButton(0))\n        {\n            Ray ray = GetComponent<UnityEngine.Camera>().ScreenPointToRay(Input.mousePosition);\n            RaycastHit hit;\n            if (Physics.Raycast(ray, out hit))\n            {\n                _mouseLeftClick = hit.point;\n                Map.Click(_mouseLeftClick);\n            }\n        }\n\n        if (Input.GetMouseButton(1))\n        {\n            var newX = Mathf.Clamp(transform.parent.position.x + deltaX * _scrollSpeed, 0, Map.Width);\n            var newY = Mathf.Clamp(transform.parent.position.y + deltaY * _scrollSpeed, 0, Map.Height);\n\n            transform.parent.position = new Vector3(newX, newY, transform.parent.position.z);\n        }\n\n        if (Input.GetAxis(\"Mouse ScrollWheel\") < 0 && transform.parent.localPosition.z > -20)\n        {\n            transform.parent.Translate(new Vector3(0, 0, -_zoomSpeed));\n        }\n\n        if (Input.GetAxis(\"Mouse ScrollWheel\") > 0 && transform.parent.localPosition.z < -5)\n        {\n            transform.parent.Translate(new Vector3(0, 0, _zoomSpeed));\n        }\n    }\n}\n"
  },
  {
    "path": "demo/Assets/Camera.cs.meta",
    "content": "fileFormatVersion: 2\nguid: ebee29ebdbfbce74297756dd0f6f3a0f\nMonoImporter:\n  serializedVersion: 2\n  defaultReferences: []\n  executionOrder: 0\n  icon: {instanceID: 0}\n  userData: \n"
  },
  {
    "path": "demo/Assets/Demo.unity",
    "content": "%YAML 1.1\n%TAG !u! tag:unity3d.com,2011:\n--- !u!29 &1\nSceneSettings:\n  m_ObjectHideFlags: 0\n  m_PVSData: \n  m_PVSObjectsArray: []\n  m_PVSPortalsArray: []\n  m_OcclusionBakeSettings:\n    smallestOccluder: 5\n    smallestHole: .25\n    backfaceThreshold: 100\n--- !u!104 &2\nRenderSettings:\n  m_Fog: 0\n  m_FogColor: {r: .5, g: .5, b: .5, a: 1}\n  m_FogMode: 3\n  m_FogDensity: .00999999978\n  m_LinearFogStart: 0\n  m_LinearFogEnd: 300\n  m_AmbientLight: {r: .200000003, g: .200000003, b: .200000003, a: 1}\n  m_SkyboxMaterial: {fileID: 0}\n  m_HaloStrength: .5\n  m_FlareStrength: 1\n  m_FlareFadeSpeed: 3\n  m_HaloTexture: {fileID: 0}\n  m_SpotCookie: {fileID: 0}\n  m_ObjectHideFlags: 0\n--- !u!127 &3\nLevelGameManager:\n  m_ObjectHideFlags: 0\n--- !u!157 &4\nLightmapSettings:\n  m_ObjectHideFlags: 0\n  m_LightProbes: {fileID: 0}\n  m_Lightmaps: []\n  m_LightmapsMode: 1\n  m_BakedColorSpace: 0\n  m_UseDualLightmapsInForward: 0\n  m_LightmapEditorSettings:\n    m_Resolution: 50\n    m_LastUsedResolution: 0\n    m_TextureWidth: 1024\n    m_TextureHeight: 1024\n    m_BounceBoost: 1\n    m_BounceIntensity: 1\n    m_SkyLightColor: {r: .860000014, g: .930000007, b: 1, a: 1}\n    m_SkyLightIntensity: 0\n    m_Quality: 0\n    m_Bounces: 1\n    m_FinalGatherRays: 1000\n    m_FinalGatherContrastThreshold: .0500000007\n    m_FinalGatherGradientThreshold: 0\n    m_FinalGatherInterpolationPoints: 15\n    m_AOAmount: 0\n    m_AOMaxDistance: .100000001\n    m_AOContrast: 1\n    m_LODSurfaceMappingDistance: 1\n    m_Padding: 0\n    m_TextureCompression: 0\n    m_LockAtlas: 0\n--- !u!196 &5\nNavMeshSettings:\n  m_ObjectHideFlags: 0\n  m_BuildSettings:\n    agentRadius: .5\n    agentHeight: 2\n    agentSlope: 45\n    agentClimb: .400000006\n    ledgeDropHeight: 0\n    maxJumpAcrossDistance: 0\n    accuratePlacement: 0\n    minRegionArea: 2\n    widthInaccuracy: 16.666666\n    heightInaccuracy: 10\n  m_NavMesh: {fileID: 0}\n--- !u!1 &620502837\nGameObject:\n  m_ObjectHideFlags: 0\n  m_PrefabParentObject: {fileID: 0}\n  m_PrefabInternal: {fileID: 0}\n  serializedVersion: 4\n  m_Component:\n  - 4: {fileID: 620502838}\n  m_Layer: 0\n  m_Name: Camera\n  m_TagString: Untagged\n  m_Icon: {fileID: 0}\n  m_NavMeshLayer: 0\n  m_StaticEditorFlags: 0\n  m_IsActive: 1\n--- !u!4 &620502838\nTransform:\n  m_ObjectHideFlags: 0\n  m_PrefabParentObject: {fileID: 0}\n  m_PrefabInternal: {fileID: 0}\n  m_GameObject: {fileID: 620502837}\n  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}\n  m_LocalPosition: {x: 25, y: 25, z: -10}\n  m_LocalScale: {x: 1, y: 1, z: 1}\n  m_Children:\n  - {fileID: 2037205295}\n  - {fileID: 818690204}\n  m_Father: {fileID: 0}\n  m_RootOrder: 1\n--- !u!1 &818690203\nGameObject:\n  m_ObjectHideFlags: 0\n  m_PrefabParentObject: {fileID: 0}\n  m_PrefabInternal: {fileID: 0}\n  serializedVersion: 4\n  m_Component:\n  - 4: {fileID: 818690204}\n  - 108: {fileID: 818690205}\n  m_Layer: 0\n  m_Name: Directional light\n  m_TagString: Untagged\n  m_Icon: {fileID: 0}\n  m_NavMeshLayer: 0\n  m_StaticEditorFlags: 0\n  m_IsActive: 1\n--- !u!4 &818690204\nTransform:\n  m_ObjectHideFlags: 0\n  m_PrefabParentObject: {fileID: 0}\n  m_PrefabInternal: {fileID: 0}\n  m_GameObject: {fileID: 818690203}\n  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}\n  m_LocalPosition: {x: 0, y: 0, z: 0}\n  m_LocalScale: {x: 1, y: 1, z: 1}\n  m_Children: []\n  m_Father: {fileID: 620502838}\n  m_RootOrder: 1\n--- !u!108 &818690205\nLight:\n  m_ObjectHideFlags: 0\n  m_PrefabParentObject: {fileID: 0}\n  m_PrefabInternal: {fileID: 0}\n  m_GameObject: {fileID: 818690203}\n  m_Enabled: 1\n  serializedVersion: 3\n  m_Type: 1\n  m_Color: {r: 1, g: 1, b: 1, a: 1}\n  m_Intensity: .5\n  m_Range: 10\n  m_SpotAngle: 30\n  m_CookieSize: 10\n  m_Shadows:\n    m_Type: 0\n    m_Resolution: -1\n    m_Strength: 1\n    m_Bias: .0500000007\n    m_Softness: 4\n    m_SoftnessFade: 1\n  m_Cookie: {fileID: 0}\n  m_DrawHalo: 0\n  m_ActuallyLightmapped: 0\n  m_Flare: {fileID: 0}\n  m_RenderMode: 0\n  m_CullingMask:\n    serializedVersion: 2\n    m_Bits: 4294967295\n  m_Lightmapping: 1\n  m_ShadowSamples: 1\n  m_ShadowRadius: 0\n  m_ShadowAngle: 0\n  m_IndirectIntensity: 1\n  m_AreaSize: {x: 1, y: 1}\n--- !u!1 &1071619055\nGameObject:\n  m_ObjectHideFlags: 0\n  m_PrefabParentObject: {fileID: 0}\n  m_PrefabInternal: {fileID: 0}\n  serializedVersion: 4\n  m_Component:\n  - 4: {fileID: 1071619059}\n  - 33: {fileID: 1071619058}\n  - 135: {fileID: 1071619057}\n  - 23: {fileID: 1071619056}\n  m_Layer: 0\n  m_Name: Selector\n  m_TagString: Untagged\n  m_Icon: {fileID: 0}\n  m_NavMeshLayer: 0\n  m_StaticEditorFlags: 0\n  m_IsActive: 1\n--- !u!23 &1071619056\nRenderer:\n  m_ObjectHideFlags: 0\n  m_PrefabParentObject: {fileID: 0}\n  m_PrefabInternal: {fileID: 0}\n  m_GameObject: {fileID: 1071619055}\n  m_Enabled: 1\n  m_CastShadows: 1\n  m_ReceiveShadows: 1\n  m_LightmapIndex: 255\n  m_LightmapTilingOffset: {x: 1, y: 1, z: 0, w: 0}\n  m_Materials:\n  - {fileID: 2100000, guid: 6dca14a4c7e41c646a06c11e677259d1, type: 2}\n  m_SubsetIndices: \n  m_StaticBatchRoot: {fileID: 0}\n  m_UseLightProbes: 0\n  m_LightProbeAnchor: {fileID: 0}\n  m_ScaleInLightmap: 1\n  m_SortingLayerID: 0\n  m_SortingOrder: 0\n--- !u!135 &1071619057\nSphereCollider:\n  m_ObjectHideFlags: 0\n  m_PrefabParentObject: {fileID: 0}\n  m_PrefabInternal: {fileID: 0}\n  m_GameObject: {fileID: 1071619055}\n  m_Material: {fileID: 0}\n  m_IsTrigger: 0\n  m_Enabled: 1\n  serializedVersion: 2\n  m_Radius: .5\n  m_Center: {x: 0, y: 0, z: 0}\n--- !u!33 &1071619058\nMeshFilter:\n  m_ObjectHideFlags: 0\n  m_PrefabParentObject: {fileID: 0}\n  m_PrefabInternal: {fileID: 0}\n  m_GameObject: {fileID: 1071619055}\n  m_Mesh: {fileID: 10207, guid: 0000000000000000e000000000000000, type: 0}\n--- !u!4 &1071619059\nTransform:\n  m_ObjectHideFlags: 0\n  m_PrefabParentObject: {fileID: 0}\n  m_PrefabInternal: {fileID: 0}\n  m_GameObject: {fileID: 1071619055}\n  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}\n  m_LocalPosition: {x: 11.3982372, y: 29.8553162, z: -14.5}\n  m_LocalScale: {x: 1, y: 1, z: 1}\n  m_Children: []\n  m_Father: {fileID: 0}\n  m_RootOrder: 2\n--- !u!1 &1149984434\nGameObject:\n  m_ObjectHideFlags: 0\n  m_PrefabParentObject: {fileID: 0}\n  m_PrefabInternal: {fileID: 0}\n  serializedVersion: 4\n  m_Component:\n  - 4: {fileID: 1149984438}\n  - 33: {fileID: 1149984437}\n  - 64: {fileID: 1149984436}\n  - 23: {fileID: 1149984435}\n  - 114: {fileID: 1149984439}\n  m_Layer: 0\n  m_Name: Map\n  m_TagString: Untagged\n  m_Icon: {fileID: 0}\n  m_NavMeshLayer: 0\n  m_StaticEditorFlags: 0\n  m_IsActive: 1\n--- !u!23 &1149984435\nRenderer:\n  m_ObjectHideFlags: 0\n  m_PrefabParentObject: {fileID: 0}\n  m_PrefabInternal: {fileID: 0}\n  m_GameObject: {fileID: 1149984434}\n  m_Enabled: 1\n  m_CastShadows: 1\n  m_ReceiveShadows: 1\n  m_LightmapIndex: 255\n  m_LightmapTilingOffset: {x: 1, y: 1, z: 0, w: 0}\n  m_Materials:\n  - {fileID: 2100000, guid: 361fa52b5561d434baaff15f2fe36f3d, type: 2}\n  m_SubsetIndices: \n  m_StaticBatchRoot: {fileID: 0}\n  m_UseLightProbes: 0\n  m_LightProbeAnchor: {fileID: 0}\n  m_ScaleInLightmap: 1\n  m_SortingLayerID: 0\n  m_SortingOrder: 0\n--- !u!64 &1149984436\nMeshCollider:\n  m_ObjectHideFlags: 0\n  m_PrefabParentObject: {fileID: 0}\n  m_PrefabInternal: {fileID: 0}\n  m_GameObject: {fileID: 1149984434}\n  m_Material: {fileID: 0}\n  m_IsTrigger: 0\n  m_Enabled: 1\n  serializedVersion: 2\n  m_SmoothSphereCollisions: 0\n  m_Convex: 0\n  m_Mesh: {fileID: 10209, guid: 0000000000000000e000000000000000, type: 0}\n--- !u!33 &1149984437\nMeshFilter:\n  m_ObjectHideFlags: 0\n  m_PrefabParentObject: {fileID: 0}\n  m_PrefabInternal: {fileID: 0}\n  m_GameObject: {fileID: 1149984434}\n  m_Mesh: {fileID: 10209, guid: 0000000000000000e000000000000000, type: 0}\n--- !u!4 &1149984438\nTransform:\n  m_ObjectHideFlags: 0\n  m_PrefabParentObject: {fileID: 0}\n  m_PrefabInternal: {fileID: 0}\n  m_GameObject: {fileID: 1149984434}\n  m_LocalRotation: {x: 0, y: .707106829, z: -.707106829, w: 0}\n  m_LocalPosition: {x: 0, y: 0, z: 0}\n  m_LocalScale: {x: 5, y: 5, z: 5}\n  m_Children: []\n  m_Father: {fileID: 0}\n  m_RootOrder: 0\n--- !u!114 &1149984439\nMonoBehaviour:\n  m_ObjectHideFlags: 0\n  m_PrefabParentObject: {fileID: 0}\n  m_PrefabInternal: {fileID: 0}\n  m_GameObject: {fileID: 1149984434}\n  m_Enabled: 1\n  m_EditorHideFlags: 0\n  m_Script: {fileID: 11500000, guid: 6b8eb48d5779546089555c7b0bd5341e, type: 3}\n  m_Name: \n  m_EditorClassIdentifier: \n--- !u!1 &2037205290\nGameObject:\n  m_ObjectHideFlags: 0\n  m_PrefabParentObject: {fileID: 0}\n  m_PrefabInternal: {fileID: 0}\n  serializedVersion: 4\n  m_Component:\n  - 4: {fileID: 2037205295}\n  - 20: {fileID: 2037205294}\n  - 92: {fileID: 2037205293}\n  - 124: {fileID: 2037205292}\n  - 81: {fileID: 2037205291}\n  - 114: {fileID: 2037205296}\n  m_Layer: 0\n  m_Name: Main Camera\n  m_TagString: MainCamera\n  m_Icon: {fileID: 0}\n  m_NavMeshLayer: 0\n  m_StaticEditorFlags: 0\n  m_IsActive: 1\n--- !u!81 &2037205291\nAudioListener:\n  m_ObjectHideFlags: 0\n  m_PrefabParentObject: {fileID: 0}\n  m_PrefabInternal: {fileID: 0}\n  m_GameObject: {fileID: 2037205290}\n  m_Enabled: 1\n--- !u!124 &2037205292\nBehaviour:\n  m_ObjectHideFlags: 0\n  m_PrefabParentObject: {fileID: 0}\n  m_PrefabInternal: {fileID: 0}\n  m_GameObject: {fileID: 2037205290}\n  m_Enabled: 1\n--- !u!92 &2037205293\nBehaviour:\n  m_ObjectHideFlags: 0\n  m_PrefabParentObject: {fileID: 0}\n  m_PrefabInternal: {fileID: 0}\n  m_GameObject: {fileID: 2037205290}\n  m_Enabled: 1\n--- !u!20 &2037205294\nCamera:\n  m_ObjectHideFlags: 0\n  m_PrefabParentObject: {fileID: 0}\n  m_PrefabInternal: {fileID: 0}\n  m_GameObject: {fileID: 2037205290}\n  m_Enabled: 1\n  serializedVersion: 2\n  m_ClearFlags: 1\n  m_BackGroundColor: {r: 0, g: 0, b: 0, a: .0196078438}\n  m_NormalizedViewPortRect:\n    serializedVersion: 2\n    x: 0\n    y: 0\n    width: 1\n    height: 1\n  near clip plane: .300000012\n  far clip plane: 1000\n  field of view: 60\n  orthographic: 0\n  orthographic size: 30\n  m_Depth: -1\n  m_CullingMask:\n    serializedVersion: 2\n    m_Bits: 4294967295\n  m_RenderingPath: -1\n  m_TargetTexture: {fileID: 0}\n  m_TargetDisplay: 0\n  m_HDR: 0\n  m_OcclusionCulling: 1\n  m_StereoConvergence: 10\n  m_StereoSeparation: .0219999999\n--- !u!4 &2037205295\nTransform:\n  m_ObjectHideFlags: 0\n  m_PrefabParentObject: {fileID: 0}\n  m_PrefabInternal: {fileID: 0}\n  m_GameObject: {fileID: 2037205290}\n  m_LocalRotation: {x: -.258819044, y: 0, z: 0, w: .965925813}\n  m_LocalPosition: {x: 0, y: 0, z: 0}\n  m_LocalScale: {x: 1, y: 1, z: 1}\n  m_Children: []\n  m_Father: {fileID: 620502838}\n  m_RootOrder: 0\n--- !u!114 &2037205296\nMonoBehaviour:\n  m_ObjectHideFlags: 0\n  m_PrefabParentObject: {fileID: 0}\n  m_PrefabInternal: {fileID: 0}\n  m_GameObject: {fileID: 2037205290}\n  m_Enabled: 1\n  m_EditorHideFlags: 0\n  m_Script: {fileID: 11500000, guid: ebee29ebdbfbce74297756dd0f6f3a0f, type: 3}\n  m_Name: \n  m_EditorClassIdentifier: \n"
  },
  {
    "path": "demo/Assets/Demo.unity.meta",
    "content": "fileFormatVersion: 2\nguid: 79883178826fb4e77a1f5cda54f78635\nDefaultImporter:\n  userData: \n"
  },
  {
    "path": "demo/Assets/Extensions/Vector2Extensions.cs",
    "content": "﻿using System.Collections.Generic;\nusing UnityEngine;\nusing System.Linq;\n\npublic static class Vector2Extensions\n{\n    public static Vector2 Interpolate(Vector2 pt1, Vector2 pt2, float f)\n    {\n        var x = f * pt1.x + (1 - f) * pt2.x;\n        var y = f * pt1.y + (1 - f) * pt2.y;\n\n        return new Vector2(x, y);\n    }\n\n    public static void DrawLine(this Texture2D tex, int x0, int y0, int x1, int y1, Color col)\n    {\n        int dy = (int)(y1 - y0);\n        int dx = (int)(x1 - x0);\n        int stepx, stepy;\n\n        if (dy < 0) { dy = -dy; stepy = -1; }\n        else { stepy = 1; }\n        if (dx < 0) { dx = -dx; stepx = -1; }\n        else { stepx = 1; }\n        dy <<= 1;\n        dx <<= 1;\n\n        float fraction = 0;\n\n        tex.SetPixel(x0, y0, col);\n        if (dx > dy)\n        {\n            fraction = dy - (dx >> 1);\n            while (Mathf.Abs(x0 - x1) > 1)\n            {\n                if (fraction >= 0)\n                {\n                    y0 += stepy;\n                    fraction -= dx;\n                }\n                x0 += stepx;\n                fraction += dy;\n                tex.SetPixel(x0, y0, col);\n            }\n        }\n        else\n        {\n            fraction = dx - (dy >> 1);\n            while (Mathf.Abs(y0 - y1) > 1)\n            {\n                if (fraction >= 0)\n                {\n                    x0 += stepx;\n                    fraction -= dy;\n                }\n                y0 += stepy;\n                fraction += dx;\n                tex.SetPixel(x0, y0, col);\n            }\n        }\n    }\n\n    public struct Point\n    {\n        public short x;\n        public short y;\n        public Point(short aX, short aY) { x = aX; y = aY; }\n        public Point(int aX, int aY) : this((short)aX, (short)aY) { }\n    }\n\n    public static void FillPolygon(this Texture2D texture, Vector2[] points, Color color)\n    {\n        // http://alienryderflex.com/polygon_fill/\n\n        var IMAGE_BOT = (int)points.Max(p => p.y);\n        var IMAGE_TOP = (int)points.Min(p => p.y);\n        var IMAGE_LEFT = (int)points.Min(p => p.x);\n        var IMAGE_RIGHT = (int)points.Max(p => p.x);\n        var MAX_POLY_CORNERS = points.Count();\n        var polyCorners = MAX_POLY_CORNERS;\n        var polyY = points.Select(p => p.y).ToArray();\n        var polyX = points.Select(p => p.x).ToArray();\n        int[] nodeX = new int[MAX_POLY_CORNERS];\n        int nodes, pixelX, i, j, swap;\n\n        //  Loop through the rows of the image.\n        for (int pixelY = IMAGE_TOP; pixelY <= IMAGE_BOT; pixelY++)\n        {\n\n            //  Build a list of nodes.\n            nodes = 0;\n            j = polyCorners - 1;\n            for (i = 0; i < polyCorners; i++)\n            {\n                if (polyY[i] < (float)pixelY && polyY[j] >= (float)pixelY || polyY[j] < (float)pixelY && polyY[i] >= (float)pixelY)\n                {\n                    nodeX[nodes++] = (int)(polyX[i] + (pixelY - polyY[i]) / (polyY[j] - polyY[i]) * (polyX[j] - polyX[i]));\n                }\n                j = i;\n            }\n\n            //  Sort the nodes, via a simple “Bubble” sort.\n            i = 0;\n            while (i < nodes - 1)\n            {\n                if (nodeX[i] > nodeX[i + 1])\n                {\n                    swap = nodeX[i]; nodeX[i] = nodeX[i + 1]; nodeX[i + 1] = swap; if (i != 0) i--;\n                }\n                else\n                {\n                    i++;\n                }\n            }\n\n            //  Fill the pixels between node pairs.\n            for (i = 0; i < nodes; i += 2)\n            {\n                if (nodeX[i] >= IMAGE_RIGHT) \n                    break;\n                if (nodeX[i + 1] > IMAGE_LEFT)\n                {\n                    if (nodeX[i] < IMAGE_LEFT) \n                        nodeX[i] = IMAGE_LEFT;\n                    if (nodeX[i + 1] > IMAGE_RIGHT) \n                        nodeX[i + 1] = IMAGE_RIGHT;\n                    for (j = nodeX[i]; j < nodeX[i + 1]; j++)\n                        texture.SetPixel(j, pixelY, color);\n                }\n            }\n        }\n    }\n}\n\n\n"
  },
  {
    "path": "demo/Assets/Extensions/Vector2Extensions.cs.meta",
    "content": "fileFormatVersion: 2\nguid: 409695d23ff505645855976e99707c87\nMonoImporter:\n  serializedVersion: 2\n  defaultReferences: []\n  executionOrder: 0\n  icon: {instanceID: 0}\n  userData: \n"
  },
  {
    "path": "demo/Assets/Extensions.meta",
    "content": "fileFormatVersion: 2\nguid: 9a8f1e17724625a4f9126906c5829861\nfolderAsset: yes\nDefaultImporter:\n  userData: \n"
  },
  {
    "path": "demo/Assets/Main.cs",
    "content": "using UnityEngine;\nusing System.Collections.Generic;\nusing Delaunay;\nusing Delaunay.Geo;\nusing System.Linq;\nusing Assets.Map;\n\npublic class Main : MonoBehaviour\n{\n    Map _map;\n    const int _textureScale = 50;\n    GameObject _selector;\n    public bool Regenerate;\n    public int Seed;\n    public float PerlinCheckValue = 0.3f;\n\n    void Update()\n    {\n        if (_map != null && _map.SelectedCenter != null)\n        {\n            _selector.transform.localPosition = new Vector3(_map.SelectedCenter.point.x, _map.SelectedCenter.point.y, 1);\n        }\n        if (Regenerate)\n        {\n            Regenerate = false;\n            Awake();\n        }\n    }\n\n\tvoid Awake ()\n\t{\n        IslandShape.PERLIN_CHECK_VALUE = PerlinCheckValue;\n\n        _selector = GameObject.Find(\"Selector\");\n\n        Random.seed = Seed;\n            \n        _map = new Map();\n\n        GameObject.Find(\"Main Camera\").GetComponentInChildren<Camera>().Map = _map;\n\n        new MapTexture(_textureScale).AttachTexture(GameObject.Find(\"Map\"), _map);\n\t}\n}"
  },
  {
    "path": "demo/Assets/Main.cs.meta",
    "content": "fileFormatVersion: 2\nguid: 6b8eb48d5779546089555c7b0bd5341e\nMonoImporter:\n  serializedVersion: 2\n  defaultReferences: []\n  executionOrder: 0\n  icon: {instanceID: 0}\n  userData: \n"
  },
  {
    "path": "demo/Assets/Map/Biome.cs",
    "content": "﻿using System.Collections.Generic;\nusing UnityEngine;\n\nnamespace Assets.Map\n{\n    public static class BiomeProperties\n    {\n        public static Dictionary<Biome, Color> Colors = new Dictionary<Biome, Color>\n        {\n            { Biome.Ocean, HexToColor(\"44447a\") },\n            //{ COAST, HexToColor(\"33335a\") },\n            //{ LAKESHORE, HexToColor(\"225588\") },\n            { Biome.Lake, HexToColor(\"336699\") },\n            //{ RIVER, HexToColor(\"225588\") },\n            { Biome.Marsh, HexToColor(\"2f6666\") },\n            { Biome.Ice, HexToColor(\"99ffff\") },\n            { Biome.Beach, HexToColor(\"a09077\") },\n            //{ ROAD1, HexToColor(\"442211\") },\n            //{ ROAD2, HexToColor(\"553322\") },\n            //{ ROAD3, HexToColor(\"664433\") },\n            //{ BRIDGE, HexToColor(\"686860\") },\n            //{ LAVA, HexToColor(\"cc3333\") },\n            { Biome.Snow, HexToColor(\"ffffff\") },\n            { Biome.Tundra, HexToColor(\"bbbbaa\") },\n            { Biome.Bare, HexToColor(\"888888\") },\n            { Biome.Scorched, HexToColor(\"555555\") },\n            { Biome.Taiga, HexToColor(\"99aa77\") },\n            { Biome.Shrubland, HexToColor(\"889977\") },\n            { Biome.TemperateDesert, HexToColor(\"c9d29b\") },\n            { Biome.TemperateRainForest, HexToColor(\"448855\") },\n            { Biome.TemperateDeciduousForest, HexToColor(\"679459\") },\n            { Biome.Grassland, HexToColor(\"88aa55\") },\n            { Biome.SubtropicalDesert, HexToColor(\"d2b98b\") },\n            { Biome.TropicalRainForest, HexToColor(\"337755\") },\n            { Biome.TropicalSeasonalForest, HexToColor(\"559944\") }\n        };\n        static Color HexToColor(string hex)\n        {\n            byte r = byte.Parse(hex.Substring(0, 2), System.Globalization.NumberStyles.HexNumber);\n            byte g = byte.Parse(hex.Substring(2, 2), System.Globalization.NumberStyles.HexNumber);\n            byte b = byte.Parse(hex.Substring(4, 2), System.Globalization.NumberStyles.HexNumber);\n            return new Color32(r, g, b, 255);\n        }\n    }\n\n    public enum Biome\n    {\n        Ocean,\n        Marsh,\n        Ice,\n        Lake,\n        Beach,\n        Snow,\n        Tundra,\n        Bare,\n        Scorched,\n        Taiga,\n        Shrubland,\n        TemperateDesert,\n        TemperateRainForest,\n        TemperateDeciduousForest,\n        Grassland,\n        TropicalRainForest,\n        TropicalSeasonalForest,\n        SubtropicalDesert\n    }\n}\n"
  },
  {
    "path": "demo/Assets/Map/Biome.cs.meta",
    "content": "fileFormatVersion: 2\nguid: cecdebe37f8d1974cb9939167f280bdc\nMonoImporter:\n  serializedVersion: 2\n  defaultReferences: []\n  executionOrder: 0\n  icon: {instanceID: 0}\n  userData: \n"
  },
  {
    "path": "demo/Assets/Map/Center.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing UnityEngine;\n\nnamespace Assets.Map\n{\n    public class Center\n    {\n        public int index;\n        public Vector2 point;   // location\n        public bool water;      // lake or ocean\n        public bool ocean;      // ocean\n        public bool coast;      // land polygon touching an ocean\n        public bool border;     // at the edge of the map\n        public Biome biome;     // biome type \n        public float elevation; // 0.0-1.0\n        public float moisture;  // 0.0-1.0\n        public List<Center> neighbors = new List<Center>();\n        public List<Edge> borders = new List<Edge>();\n        public List<Corner> corners = new List<Corner>();\n\n        public bool PointInside(float x, float y)\n        {\n            // http://alienryderflex.com/polygon/\n            //  Globals which should be set before calling this function:\n            //\n            //  int    polyCorners  =  how many corners the polygon has\n            //  float  polyX[]      =  horizontal coordinates of corners\n            //  float  polyY[]      =  vertical coordinates of corners\n            //  float  x, y         =  point to be tested\n            //\n            //  (Globals are used in this example for purposes of speed.  Change as\n            //  desired.)\n            //\n            //  The function will return YES if the point x,y is inside the polygon, or\n            //  NO if it is not.  If the point is exactly on the edge of the polygon,\n            //  then the function may return YES or NO.\n            //\n            //  Note that division by zero is avoided because the division is protected\n            //  by the \"if\" clause which surrounds it.\n\n            var polyCorners = corners.Count;\n\n            int j = polyCorners - 1;\n            bool oddNodes = false;\n            var polyX = corners.Select(p => p.point.x).ToArray();\n            var polyY = corners.Select(p => p.point.y).ToArray();\n\n            for (var i = 0; i < polyCorners; i++)\n            {\n                if ((polyY[i] < y && polyY[j] >= y\n                || polyY[j] < y && polyY[i] >= y)\n                && (polyX[i] <= x || polyX[j] <= x))\n                {\n                    oddNodes ^= (polyX[i] + (y - polyY[i]) / (polyY[j] - polyY[i]) * (polyX[j] - polyX[i]) < x);\n                }\n                j = i;\n            }\n\n            return oddNodes;\n        }\n    }\n}\n"
  },
  {
    "path": "demo/Assets/Map/Center.cs.meta",
    "content": "fileFormatVersion: 2\nguid: cbea49a0f7f303249bd2f75bb089d732\nMonoImporter:\n  serializedVersion: 2\n  defaultReferences: []\n  executionOrder: 0\n  icon: {instanceID: 0}\n  userData: \n"
  },
  {
    "path": "demo/Assets/Map/Corner.cs",
    "content": "﻿using System.Collections.Generic;\nusing UnityEngine;\n\nnamespace Assets.Map\n{\n    public class Corner\n    {\n        public int index;\n\n        public Vector2 point;  // location\n        public bool ocean;  // ocean\n        public bool water;  // lake or ocean\n        public bool coast;  // touches ocean and land polygons\n        public bool border;  // at the edge of the map\n        public float elevation;  // 0.0-1.0\n        public float moisture;  // 0.0-1.0\n\n        public List<Center> touches = new List<Center>();\n        public List<Edge> protrudes = new List<Edge>();\n        public List<Corner> adjacent = new List<Corner>();\n\n        public int river;  // 0 if no river, or volume of water in river\n        public Corner downslope;  // pointer to adjacent corner most downhill\n        public Corner watershed;  // pointer to coastal corner, or null\n        public int watershed_size;\n    }\n}\n"
  },
  {
    "path": "demo/Assets/Map/Corner.cs.meta",
    "content": "fileFormatVersion: 2\nguid: c7a8fe7402f2c0042b39747d693377ad\nMonoImporter:\n  serializedVersion: 2\n  defaultReferences: []\n  executionOrder: 0\n  icon: {instanceID: 0}\n  userData: \n"
  },
  {
    "path": "demo/Assets/Map/Edge.cs",
    "content": "﻿using System.Collections.Generic;\nusing UnityEngine;\n\nnamespace Assets.Map\n{\n    public class Edge\n    {\n        public int index;\n        public Center d0, d1;  // Delaunay edge\n        public Corner v0, v1;  // Voronoi edge\n        public Vector2 midpoint;  // halfway between v0,v1\n        public int river;  // volume of water, or 0\n    }\n}\n"
  },
  {
    "path": "demo/Assets/Map/Edge.cs.meta",
    "content": "fileFormatVersion: 2\nguid: c1a292e422f56c64f87c50773e2aa693\nMonoImporter:\n  serializedVersion: 2\n  defaultReferences: []\n  executionOrder: 0\n  icon: {instanceID: 0}\n  userData: \n"
  },
  {
    "path": "demo/Assets/Map/Graph.cs",
    "content": "﻿using Delaunay;\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing UnityEngine;\n\nnamespace Assets.Map\n{\n    public class Graph\n    {\n        List<KeyValuePair<int, Corner>> _cornerMap = new List<KeyValuePair<int, Corner>>();\n        Func<Vector2, bool> inside;\n        bool _needsMoreRandomness;\n\n        public int Width { get; private set; }\n        public int Height { get; private set; }\n        public List<Center> centers = new List<Center>();\n        public List<Corner> corners = new List<Corner>();\n        public List<Edge> edges = new List<Edge>();\n\n        private List<Corner> LandCorners { get { return corners.Where(p => !p.ocean && !p.coast).ToList(); } }\n\n        public Graph(IEnumerable<Vector2> points, Voronoi voronoi, int width, int height, float lakeThreshold)\n        {\n            Width = width;\n            Height = height;\n            inside = IslandShape.makePerlin();\n\n            BuildGraph(points, voronoi);\n            AssignCornerElevations();\n            AssignOceanCoastAndLand(lakeThreshold);\n            RedistributeElevations();\n\n            AssignPolygonElevations();\n\n            // Determine downslope paths.\n            CalculateDownslopes();\n\n            // Determine watersheds: for every corner, where does it flow\n            // out into the ocean? \n            CalculateWatersheds();\n\n            // Create rivers.\n            CreateRivers();\n\n            // Determine moisture at corners, starting at rivers\n            // and lakes, but not oceans. Then redistribute\n            // moisture to cover the entire range evenly from 0.0\n            // to 1.0. Then assign polygon moisture as the average\n            // of the corner moisture.\n            AssignCornerMoisture();\n            RedistributeMoisture();\n            AssignPolygonMoisture();\n\n            centers.ForEach(p => p.biome = GetBiome(p));\n        }\n\n        private void BuildGraph(IEnumerable<Vector2> points, Delaunay.Voronoi voronoi)\n        {\n            // Build graph data structure in 'edges', 'centers', 'corners',\n            // based on information in the Voronoi results: point.neighbors\n            // will be a list of neighboring points of the same type (corner\n            // or center); point.edges will be a list of edges that include\n            // that point. Each edge connects to four points: the Voronoi edge\n            // edge.{v0,v1} and its dual Delaunay triangle edge edge.{d0,d1}.\n            // For boundary polygons, the Delaunay edge will have one null\n            // point, and the Voronoi edge may be null.\n            var libedges = voronoi.Edges();\n\n            var centerLookup = new Dictionary<Vector2?, Center>();\n\n            // Build Center objects for each of the points, and a lookup map\n            // to find those Center objects again as we build the graph\n            foreach (var point in points)\n            {\n                var p = new Center { index = centers.Count, point = point };\n                centers.Add(p);\n                centerLookup[point] = p;\n            }\n\n            // Workaround for Voronoi lib bug: we need to call region()\n            // before Edges or neighboringSites are available\n            foreach (var p in centers)\n            {\n                voronoi.Region(p.point);\n            }\n\n            foreach (var libedge in libedges)\n            {\n                var dedge = libedge.DelaunayLine();\n                var vedge = libedge.VoronoiEdge();\n\n                // Fill the graph data. Make an Edge object corresponding to\n                // the edge from the voronoi library.\n                var edge = new Edge\n                {\n                    index = edges.Count,\n                    river = 0,\n\n                    // Edges point to corners. Edges point to centers. \n                    v0 = MakeCorner(vedge.p0),\n                    v1 = MakeCorner(vedge.p1),\n                    d0 = centerLookup[dedge.p0],\n                    d1 = centerLookup[dedge.p1]\n                };\n                if (vedge.p0.HasValue && vedge.p1.HasValue)\n                    edge.midpoint = Vector2Extensions.Interpolate(vedge.p0.Value, vedge.p1.Value, 0.5f);\n\n                edges.Add(edge);\n\n                // Centers point to edges. Corners point to edges.\n                if (edge.d0 != null) { edge.d0.borders.Add(edge); }\n                if (edge.d1 != null) { edge.d1.borders.Add(edge); }\n                if (edge.v0 != null) { edge.v0.protrudes.Add(edge); }\n                if (edge.v1 != null) { edge.v1.protrudes.Add(edge); }\n\n                // Centers point to centers.\n                if (edge.d0 != null && edge.d1 != null)\n                {\n                    AddToCenterList(edge.d0.neighbors, edge.d1);\n                    AddToCenterList(edge.d1.neighbors, edge.d0);\n                }\n\n                // Corners point to corners\n                if (edge.v0 != null && edge.v1 != null)\n                {\n                    AddToCornerList(edge.v0.adjacent, edge.v1);\n                    AddToCornerList(edge.v1.adjacent, edge.v0);\n                }\n\n                // Centers point to corners\n                if (edge.d0 != null)\n                {\n                    AddToCornerList(edge.d0.corners, edge.v0);\n                    AddToCornerList(edge.d0.corners, edge.v1);\n                }\n                if (edge.d1 != null)\n                {\n                    AddToCornerList(edge.d1.corners, edge.v0);\n                    AddToCornerList(edge.d1.corners, edge.v1);\n                }\n\n                // Corners point to centers\n                if (edge.v0 != null)\n                {\n                    AddToCenterList(edge.v0.touches, edge.d0);\n                    AddToCenterList(edge.v0.touches, edge.d1);\n                }\n                if (edge.v1 != null)\n                {\n                    AddToCenterList(edge.v1.touches, edge.d0);\n                    AddToCenterList(edge.v1.touches, edge.d1);\n                }\n            }\n\n            // TODO: use edges to determine these\n            var topLeft = centers.OrderBy(p => p.point.x + p.point.y).First();\n            AddCorner(topLeft, 0, 0);\n\n            var bottomRight = centers.OrderByDescending(p => p.point.x + p.point.y).First();\n            AddCorner(bottomRight, Width, Height);\n\n            var topRight = centers.OrderByDescending(p => Width - p.point.x + p.point.y).First();\n            AddCorner(topRight, 0, Height);\n\n            var bottomLeft = centers.OrderByDescending(p => p.point.x + Height - p.point.y).First();\n            AddCorner(bottomLeft, Width, 0);\n\n            // required for polygon fill\n            foreach (var center in centers)\n            {\n                center.corners.Sort(ClockwiseComparison(center));\n            }\n        }\n\n        private static void AddCorner(Center topLeft, int x, int y)\n        {\n            if (topLeft.point.x != x || topLeft.point.y != y)\n                topLeft.corners.Add(new Corner { ocean = true, point = new Vector2(x, y) });\n        }\n\n        private Comparison<Corner> ClockwiseComparison(Center center)\n        {\n            Comparison<Corner> result =\n                (a, b) =>\n                {\n                    return (int)(((a.point.x - center.point.x) * (b.point.y - center.point.y) - (b.point.x - center.point.x) * (a.point.y - center.point.y)) * 1000);\n                };\n            return result;\n        }\n\n        private Corner MakeCorner(Vector2? nullablePoint)\n        {\n            // The Voronoi library generates multiple Point objects for\n            // corners, and we need to canonicalize to one Corner object.\n            // To make lookup fast, we keep an array of Points, bucketed by\n            // x value, and then we only have to look at other Points in\n            // nearby buckets. When we fail to find one, we'll create a new\n            // Corner object.\n\n            if (nullablePoint == null)\n                return null;\n\n            var point = nullablePoint.Value;\n\n            for (var i = (int)(point.x - 1); i <= (int)(point.x + 1); i++)\n            {\n                foreach (var kvp in _cornerMap.Where(p => p.Key == i))\n                {\n                    var dx = point.x - kvp.Value.point.x;\n                    var dy = point.y - kvp.Value.point.y;\n                    if (dx * dx + dy * dy < 1e-6)\n                        return kvp.Value;\n                }\n            }\n\n            var corner = new Corner { index = corners.Count, point = point };\n            corners.Add(corner);\n            corner.border = point.x == 0 || point.x == Width || point.y == 0 || point.y == Height;\n\n            _cornerMap.Add(new KeyValuePair<int, Corner>((int)(point.x), corner));\n\n            return corner;\n        }\n\n        private void AddToCornerList(List<Corner> v, Corner x)\n        {\n            if (x != null && v.IndexOf(x) < 0)\n                v.Add(x);\n        }\n\n        private void AddToCenterList(List<Center> v, Center x)\n        {\n            if (x != null && v.IndexOf(x) < 0) { v.Add(x); }\n        }\n\n        private void AssignCornerElevations()\n        {\n            // Determine elevations and water at Voronoi corners. By\n            // construction, we have no local minima. This is important for\n            // the downslope vectors later, which are used in the river\n            // construction algorithm. Also by construction, inlets/bays\n            // push low elevation areas inland, which means many rivers end\n            // up flowing out through them. Also by construction, lakes\n            // often end up on river paths because they don't raise the\n            // elevation as much as other terrain does.\n\n            //var q:Corner, s:Corner;\n            var queue = new Queue<Corner>();\n\n            foreach (var q in corners)\n            {\n                q.water = !inside(q.point);\n            }\n\n            foreach (var q in corners)\n            {\n                // The edges of the map are elevation 0\n                if (q.border)\n                {\n                    q.elevation = 0;\n                    queue.Enqueue(q);\n                }\n                else\n                {\n                    q.elevation = float.PositiveInfinity;\n                }\n            }\n\n            // Traverse the graph and assign elevations to each point. As we\n            // move away from the map border, increase the elevations. This\n            // guarantees that rivers always have a way down to the coast by\n            // going downhill (no local minima).\n            while (queue.Any())\n            {\n                var q = queue.Dequeue();\n\n                foreach (var s in q.adjacent)\n                {\n                    // Every step up is epsilon over water or 1 over land. The\n                    // number doesn't matter because we'll rescale the\n                    // elevations later.\n                    var newElevation = 0.01f + q.elevation;\n                    if (!q.water && !s.water)\n                    {\n                        newElevation += 1;\n                        if (_needsMoreRandomness)\n                        {\n                            // HACK: the map looks nice because of randomness of\n                            // points, randomness of rivers, and randomness of\n                            // edges. Without random point selection, I needed to\n                            // inject some more randomness to make maps look\n                            // nicer. I'm doing it here, with elevations, but I\n                            // think there must be a better way. This hack is only\n                            // used with square/hexagon grids.\n                            newElevation += UnityEngine.Random.value; ;\n                        }\n                    }\n                    // If this point changed, we'll add it to the queue so\n                    // that we can process its neighbors too.\n                    if (newElevation < s.elevation)\n                    {\n                        s.elevation = newElevation;\n                        queue.Enqueue(s);\n                    }\n                }\n            }\n        }\n\n        private void AssignOceanCoastAndLand(float lakeThreshold)\n        {\n            // Compute polygon attributes 'ocean' and 'water' based on the\n            // corner attributes. Count the water corners per\n            // polygon. Oceans are all polygons connected to the edge of the\n            // map. In the first pass, mark the edges of the map as ocean;\n            // in the second pass, mark any water-containing polygon\n            // connected an ocean as ocean.\n            var queue = new Queue<Center>();\n            //var p:Center, q:Corner, r:Center, numWater:int;\n\n            foreach (var p in centers)\n            {\n                var numWater = 0;\n                foreach (var q in p.corners)\n                {\n                    if (q.border)\n                    {\n                        p.border = true;\n                        p.ocean = true;\n                        q.water = true;\n                        queue.Enqueue(p);\n                    }\n\n                    if (q.water)\n                        numWater += 1;\n\n                }\n                p.water = (p.ocean || numWater >= p.corners.Count * lakeThreshold);\n            }\n            while (queue.Any())\n            {\n                var p = queue.Dequeue();\n                foreach (var r in p.neighbors)\n                {\n                    if (r.water && !r.ocean)\n                    {\n                        r.ocean = true;\n                        queue.Enqueue(r);\n                    }\n                }\n            }\n\n            // Set the polygon attribute 'coast' based on its neighbors. If\n            // it has at least one ocean and at least one land neighbor,\n            // then this is a coastal polygon.\n            foreach (var p in centers)\n            {\n                var numOcean = 0;\n                var numLand = 0;\n                foreach (var r in p.neighbors)\n                {\n                    numOcean += r.ocean ? 1 : 0;\n                    numLand += !r.water ? 1 : 0;\n                }\n                p.coast = (numOcean > 0) && (numLand > 0);\n            }\n\n            // Set the corner attributes based on the computed polygon\n            // attributes. If all polygons connected to this corner are\n            // ocean, then it's ocean; if all are land, then it's land;\n            // otherwise it's coast.\n            foreach (var q in corners)\n            {\n                var numOcean = 0;\n                var numLand = 0;\n                foreach (var p in q.touches)\n                {\n                    numOcean += p.ocean ? 1 : 0;\n                    numLand += !p.water ? 1 : 0;\n                }\n                q.ocean = (numOcean == q.touches.Count);\n                q.coast = (numOcean > 0) && (numLand > 0);\n                q.water = q.border || ((numLand != q.touches.Count) && !q.coast);\n            }\n        }\n\n        private void RedistributeElevations()\n        {\n            // Change the overall distribution of elevations so that lower\n            // elevations are more common than higher\n            // elevations. Specifically, we want elevation X to have frequency\n            // (1-X).  To do this we will sort the corners, then set each\n            // corner to its desired elevation.\n\n            var locations = LandCorners;\n            // SCALE_FACTOR increases the mountain area. At 1.0 the maximum\n            // elevation barely shows up on the map, so we set it to 1.1.\n            var SCALE_FACTOR = 1.1f;\n            locations.Sort((a, b) => a.elevation.CompareTo(b.elevation));\n            for (int i = 0; i < locations.Count; i++)\n            {\n                // Let y(x) be the total area that we want at elevation <= x.\n                // We want the higher elevations to occur less than lower\n                // ones, and set the area to be y(x) = 1 - (1-x)^2.\n                var y = (float)i / (locations.Count - 1);\n                // Now we have to solve for x, given the known y.\n                //  *  y = 1 - (1-x)^2\n                //  *  y = 1 - (1 - 2x + x^2)\n                //  *  y = 2x - x^2\n                //  *  x^2 - 2x + y = 0\n                // From this we can use the quadratic equation to get:\n                float x = Mathf.Sqrt(SCALE_FACTOR) - Mathf.Sqrt(SCALE_FACTOR * (1 - y));\n                if (x > 1.0) x = 1.0f;  // TODO: does this break downslopes?\n                locations[i].elevation = x;\n            }\n\n            // Assign elevations to non-land corners\n            corners.Where(p => p.ocean || p.coast).ToList().ForEach(p => p.elevation = 0);\n        }\n\n        private void AssignPolygonElevations()\n        {\n            // Polygon elevations are the average of their corners\n            foreach (var p in centers)\n            {\n                var sumElevation = 0.0f;\n                foreach (var q in p.corners)\n                {\n                    sumElevation += q.elevation;\n                }\n                p.elevation = sumElevation / p.corners.Count;\n            }\n        }\n\n        private void CalculateDownslopes()\n        {\n            // Calculate downslope pointers.  At every point, we point to the\n            // point downstream from it, or to itself.  This is used for\n            // generating rivers and watersheds.\n\n            foreach (var q in corners)\n            {\n                var r = q;\n                foreach (var s in q.adjacent)\n                {\n                    if (s.elevation <= r.elevation)\n                    {\n                        r = s;\n                    }\n                }\n                q.downslope = r;\n            }\n        }\n\n        private void CalculateWatersheds()\n        {\n            // Calculate the watershed of every land point. The watershed is\n            // the last downstream land point in the downslope graph. TODO:\n            // watersheds are currently calculated on corners, but it'd be\n            // more useful to compute them on polygon centers so that every\n            // polygon can be marked as being in one watershed.\n\n            // Initially the watershed pointer points downslope one step.      \n            foreach (var q in corners)\n            {\n                q.watershed = q;\n                if (!q.ocean && !q.coast)\n                {\n                    q.watershed = q.downslope;\n                }\n            }\n            // Follow the downslope pointers to the coast. Limit to 100\n            // iterations although most of the time with numPoints==2000 it\n            // only takes 20 iterations because most points are not far from\n            // a coast.  TODO: can run faster by looking at\n            // p.watershed.watershed instead of p.downslope.watershed.\n            for (var i = 0; i < 100; i++)\n            {\n                var changed = false;\n                foreach (var q in corners)\n                {\n                    if (!q.ocean && !q.coast && !q.watershed.coast)\n                    {\n                        var r = q.downslope.watershed;\n                        if (!r.ocean) q.watershed = r;\n                        changed = true;\n                    }\n                }\n                if (!changed) break;\n            }\n            // How big is each watershed?\n            foreach (var q in corners)\n            {\n                var r = q.watershed;\n                r.watershed_size = 1 + r.watershed_size;\n            }\n        }\n\n        private void CreateRivers()\n        {\n            // Create rivers along edges. Pick a random corner point, then\n            // move downslope. Mark the edges and corners as rivers.\n            for (var i = 0; i < (Width + Height) / 4; i++)\n            {\n                var q = corners[UnityEngine.Random.Range(0, corners.Count - 1)];\n                if (q.ocean || q.elevation < 0.3 || q.elevation > 0.9) continue;\n                // Bias rivers to go west: if (q.downslope.x > q.x) continue;\n                while (!q.coast)\n                {\n                    if (q == q.downslope)\n                    {\n                        break;\n                    }\n                    var edge = lookupEdgeFromCorner(q, q.downslope);\n                    edge.river = edge.river + 1;\n                    q.river++;\n                    q.downslope.river++;  // TODO: fix double count\n                    q = q.downslope;\n                }\n            }\n        }\n\n        private void AssignCornerMoisture()\n        {\n            // Calculate moisture. Freshwater sources spread moisture: rivers\n            // and lakes (not oceans). Saltwater sources have moisture but do\n            // not spread it (we set it at the end, after propagation).\n\n            var queue = new Queue<Corner>();\n            // Fresh water\n            foreach (var q in corners)\n            {\n                if ((q.water || q.river > 0) && !q.ocean)\n                {\n                    q.moisture = q.river > 0 ? Mathf.Min(3.0f, (0.2f * q.river)) : 1.0f;\n                    queue.Enqueue(q);\n                }\n                else\n                {\n                    q.moisture = 0;\n                }\n            }\n            while (queue.Any())\n            {\n                var q = queue.Dequeue();\n\n                foreach (var r in q.adjacent)\n                {\n                    var newMoisture = q.moisture * 0.9f;\n                    if (newMoisture > r.moisture)\n                    {\n                        r.moisture = newMoisture;\n                        queue.Enqueue(r);\n                    }\n                }\n            }\n            // Salt water\n            foreach (var q in corners)\n            {\n                if (q.ocean || q.coast)\n                {\n                    q.moisture = 1.0f;\n                }\n            }\n        }\n\n        private void AssignPolygonMoisture()\n        {\n            // Polygon moisture is the average of the moisture at corners\n            foreach (var p in centers)\n            {\n                var sumMoisture = 0.0f;\n                foreach (var q in p.corners)\n                {\n                    if (q.moisture > 1.0)\n                        q.moisture = 1.0f;\n                    sumMoisture += q.moisture;\n                }\n                p.moisture = sumMoisture / p.corners.Count;\n            }\n        }\n\n        private Edge lookupEdgeFromCenter(Center p, Center r)\n        {\n            foreach (var edge in p.borders)\n            {\n                if (edge.d0 == r || edge.d1 == r)\n                    return edge;\n            }\n            return null;\n        }\n\n        private Edge lookupEdgeFromCorner(Corner q, Corner s)\n        {\n            foreach (var edge in q.protrudes)\n            {\n                if (edge.v0 == s || edge.v1 == s)\n                    return edge;\n            }\n            return null;\n        }\n\n        private void RedistributeMoisture()\n        {\n            // Change the overall distribution of moisture to be evenly distributed.\n            var locations = LandCorners;\n            locations.Sort((a, b) => a.moisture.CompareTo(b.moisture));\n\n            for (var i = 0; i < locations.Count; i++)\n            {\n                locations[i].moisture = (float)i / (locations.Count - 1);\n            }\n        }\n\n        static Biome GetBiome(Center p)\n        {\n            if (p.ocean)\n            {\n                return Biome.Ocean;\n            }\n            else if (p.water)\n            {\n                if (p.elevation < 0.1) return Biome.Marsh;\n                if (p.elevation > 0.8) return Biome.Ice;\n                return Biome.Lake;\n            }\n            else if (p.coast)\n            {\n                return Biome.Beach;\n            }\n            else if (p.elevation > 0.8)\n            {\n                if (p.moisture > 0.50) return Biome.Snow;\n                else if (p.moisture > 0.33) return Biome.Tundra;\n                else if (p.moisture > 0.16) return Biome.Bare;\n                else return Biome.Scorched;\n            }\n            else if (p.elevation > 0.6)\n            {\n                if (p.moisture > 0.66) return Biome.Taiga;\n                else if (p.moisture > 0.33) return Biome.Shrubland;\n                else return Biome.TemperateDesert;\n            }\n            else if (p.elevation > 0.3)\n            {\n                if (p.moisture > 0.83) return Biome.TemperateRainForest;\n                else if (p.moisture > 0.50) return Biome.TemperateDeciduousForest;\n                else if (p.moisture > 0.16) return Biome.Grassland;\n                else return Biome.TemperateDesert;\n            }\n            else\n            {\n                if (p.moisture > 0.66) return Biome.TropicalRainForest;\n                else if (p.moisture > 0.33) return Biome.TropicalSeasonalForest;\n                else if (p.moisture > 0.16) return Biome.Grassland;\n                else return Biome.SubtropicalDesert;\n            }\n        }\n\n        public static IEnumerable<Vector2> RelaxPoints(IEnumerable<Vector2> startingPoints, float width, float height)\n        {\n            Delaunay.Voronoi v = new Delaunay.Voronoi(startingPoints.ToList(), null, new Rect(0, 0, width, height));\n            foreach (var point in startingPoints)\n            {\n                var region = v.Region(point);\n                point.Set(0, 0);\n                foreach (var r in region)\n                    point.Set(point.x + r.x, point.y + r.y);\n\n                point.Set(point.x / region.Count, point.y / region.Count);\n                yield return point;\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "demo/Assets/Map/Graph.cs.meta",
    "content": "fileFormatVersion: 2\nguid: e8a146a4bf4be4b47a37168e1541a1ff\nMonoImporter:\n  serializedVersion: 2\n  defaultReferences: []\n  executionOrder: 0\n  icon: {instanceID: 0}\n  userData: \n"
  },
  {
    "path": "demo/Assets/Map/IslandShape.cs",
    "content": "﻿using System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing UnityEngine;\n\nnamespace Assets.Map\n{\n    public class IslandShape\n    {\n        // This class has factory functions for generating islands of\n        // different shapes. The factory returns a function that takes a\n        // normalized point (x and y are -1 to +1) and returns true if the\n        // point should be on the island, and false if it should be water\n        // (lake or ocean).\n\n        // The radial island radius is based on overlapping sine waves \n        public static float ISLAND_FACTOR = 1.07f;  // 1.0 means no small islands; 2.0 leads to a lot\n        public static float PERLIN_CHECK_VALUE = 0.3f;\n\n        public static System.Func<Vector2, bool> makeRadial()\n        {\n            var bumps = Random.Range(1, 6);\n            var startAngle = Random.value * 2 * Mathf.PI;\n            var dipAngle = Random.value * 2 * Mathf.PI;\n\n            var random = Random.value;\n            var start = 0.2f;\n            var end = 0.7f;\n\n            var dipWidth = (end - start) * random + start;\n\n            System.Func<Vector2, bool> inside = q =>\n            {\n                var angle = Mathf.Atan2(q.y, q.x);\n                var length = 0.5 * (Mathf.Max(Mathf.Abs(q.x), Mathf.Abs(q.y)) + q.magnitude);\n\n                var r1 = 0.5 + 0.40 * Mathf.Sin(startAngle + bumps * angle + Mathf.Cos((bumps + 3) * angle));\n                var r2 = 0.7 - 0.20 * Mathf.Sin(startAngle + bumps * angle - Mathf.Sin((bumps + 2) * angle));\n                if (Mathf.Abs(angle - dipAngle) < dipWidth\n                    || Mathf.Abs(angle - dipAngle + 2 * Mathf.PI) < dipWidth\n                    || Mathf.Abs(angle - dipAngle - 2 * Mathf.PI) < dipWidth)\n                {\n                    r1 = r2 = 0.2;\n                }\n                var result = (length < r1 || (length > r1 * ISLAND_FACTOR && length < r2));\n                return result;\n            };\n\n            return inside;\n        }\n\n        // The Perlin-based island combines perlin noise with the radius\n        public static System.Func<Vector2, bool> makePerlin()\n        {\n            var offset = Random.Range(0, 100000);\n            System.Func<Vector2, bool> inside = q =>\n            {\n                q = new Vector2(q.x / 25 - 1, q.y / 25 - 1);\n                var x = q.x + offset;\n                var y = q.y + offset;\n                var perlin = Mathf.PerlinNoise(x/10 , y/10);\n                var checkValue = (PERLIN_CHECK_VALUE + PERLIN_CHECK_VALUE * q.magnitude * q.magnitude);\n                var result = perlin > checkValue;\n                return result;\n            };\n            return inside;\n        }\n\n        // The square shape fills the entire space with land\n        public static System.Func<Vector2, bool> makeSquare()\n        {\n            System.Func<Vector2, bool> inside = q => { return true; };\n            return inside;\n        }\n    }\n}\n"
  },
  {
    "path": "demo/Assets/Map/IslandShape.cs.meta",
    "content": "fileFormatVersion: 2\nguid: c5b3ffa4871be074aa1ce33f637c319f\nMonoImporter:\n  serializedVersion: 2\n  defaultReferences: []\n  executionOrder: 0\n  icon: {instanceID: 0}\n  userData: \n"
  },
  {
    "path": "demo/Assets/Map/Map.cs",
    "content": "﻿using Delaunay;\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing UnityEngine;\n\nnamespace Assets.Map\n{\n    public class Map\n    {\n        private int _pointCount = 500;\n        float _lakeThreshold = 0.3f;\n        public const float Width = 50;\n        public const float Height = 50;\n        const int NUM_LLOYD_RELAXATIONS = 2;\n        \n        public Graph Graph { get; private set; }\n        public Center SelectedCenter { get; private set; }\n\n        public Map()\n        {\n            List<uint> colors = new List<uint>();\n            var points = new List<Vector2>();\n\n            for (int i = 0; i < _pointCount; i++)\n            {\n                colors.Add(0);\n                points.Add(new Vector2(\n                        UnityEngine.Random.Range(0, Width),\n                        UnityEngine.Random.Range(0, Height))\n                );\n            }\n\n            for (int i = 0; i < NUM_LLOYD_RELAXATIONS; i++)\n                points = Graph.RelaxPoints(points, Width, Height).ToList();\n\n            var voronoi = new Voronoi(points, colors, new Rect(0, 0, Width, Height));\n            \n            Graph = new Graph(points, voronoi, (int)Width, (int)Height, _lakeThreshold);\n        }\n\n        internal void Click(Vector2 point)\n        {\n            SelectedCenter = Graph.centers.FirstOrDefault(p => p.PointInside(point.x, point.y));\n        }\n    }\n}\n"
  },
  {
    "path": "demo/Assets/Map/Map.cs.meta",
    "content": "fileFormatVersion: 2\nguid: d04dc414d23e3bf43ae38677c94982f3\nMonoImporter:\n  serializedVersion: 2\n  defaultReferences: []\n  executionOrder: 0\n  icon: {instanceID: 0}\n  userData: \n"
  },
  {
    "path": "demo/Assets/Map/MapTexture.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing UnityEngine;\n\nnamespace Assets.Map\n{\n    public class MapTexture\n    {\n        int _textureScale;\n        public MapTexture(int textureScale)\n        {\n            _textureScale = textureScale;\n        }\n\n        public void AttachTexture(GameObject plane, Map map)\n        {\n\n            int _textureWidth = (int)Map.Width * _textureScale;\n            int _textureHeight = (int)Map.Height * _textureScale;\n\n            Texture2D texture = new Texture2D(_textureWidth, _textureHeight);\n            texture.SetPixels(Enumerable.Repeat(Color.magenta, _textureWidth * _textureHeight).ToArray());\n\n            var lines = map.Graph.edges.Where(p => p.v0 != null).Select(p => new[] \n            { \n                p.v0.point.x, p.v0.point.y,\n                p.v1.point.x, p.v1.point.y\n            }).ToArray();\n\n            foreach (var c in map.Graph.centers)\n                texture.FillPolygon(c.corners.Select(p => new Vector2(p.point.x * _textureScale, p.point.y * _textureScale)).ToArray(), BiomeProperties.Colors[c.biome]);\n\n            foreach (var line in lines)\n                DrawLine(texture, line[0], line[1], line[2], line[3], Color.black);\n\n            foreach (var line in map.Graph.edges.Where(p => p.river > 0 && !p.d0.water && !p.d1.water))\n                DrawLine(texture, line.v0.point.x, line.v0.point.y, line.v1.point.x, line.v1.point.y, Color.blue);\n\n            texture.Apply();\n\n            plane.GetComponent<Renderer>().material.mainTexture = texture;\n            plane.transform.localPosition = new Vector3(Map.Width / 2, Map.Height / 2, 1);\n        }\n\n        private void DrawLine(Texture2D texture, float x0, float y0, float x1, float y1, Color color)\n        {\n            texture.DrawLine((int)(x0 * _textureScale), (int)(y0 * _textureScale), (int)(x1 * _textureScale), (int)(y1 * _textureScale), color);\n        }\n    }\n}\n"
  },
  {
    "path": "demo/Assets/Map/MapTexture.cs.meta",
    "content": "fileFormatVersion: 2\nguid: c460af6532c409546ae639121253b9dd\nMonoImporter:\n  serializedVersion: 2\n  defaultReferences: []\n  executionOrder: 0\n  icon: {instanceID: 0}\n  userData: \n"
  },
  {
    "path": "demo/Assets/Map.meta",
    "content": "fileFormatVersion: 2\nguid: 8974cff9fe327e543b7a4c7516d81785\nfolderAsset: yes\nDefaultImporter:\n  userData: \n"
  },
  {
    "path": "demo/Assets/Materials/Selector.mat",
    "content": "%YAML 1.1\n%TAG !u! tag:unity3d.com,2011:\n--- !u!21 &2100000\nMaterial:\n  serializedVersion: 3\n  m_ObjectHideFlags: 0\n  m_PrefabParentObject: {fileID: 0}\n  m_PrefabInternal: {fileID: 0}\n  m_Name: Selector\n  m_Shader: {fileID: 30, guid: 0000000000000000f000000000000000, type: 0}\n  m_ShaderKeywords: []\n  m_CustomRenderQueue: -1\n  m_SavedProperties:\n    serializedVersion: 2\n    m_TexEnvs:\n      data:\n        first:\n          name: _MainTex\n        second:\n          m_Texture: {fileID: 0}\n          m_Scale: {x: 1, y: 1}\n          m_Offset: {x: 0, y: 0}\n      data:\n        first:\n          name: _BumpMap\n        second:\n          m_Texture: {fileID: 0}\n          m_Scale: {x: 1, y: 1}\n          m_Offset: {x: 0, y: 0}\n      data:\n        first:\n          name: _Illum\n        second:\n          m_Texture: {fileID: 0}\n          m_Scale: {x: 1, y: 1}\n          m_Offset: {x: 0, y: 0}\n    m_Floats:\n      data:\n        first:\n          name: _Cutoff\n        second: .5\n      data:\n        first:\n          name: _EmissionLM\n        second: 0\n    m_Colors:\n      data:\n        first:\n          name: _Color\n        second: {r: 1, g: 0, b: 0, a: .858823538}\n"
  },
  {
    "path": "demo/Assets/Materials/Selector.mat.meta",
    "content": "fileFormatVersion: 2\nguid: 6dca14a4c7e41c646a06c11e677259d1\nNativeFormatImporter:\n  userData: \n"
  },
  {
    "path": "demo/Assets/Materials.meta",
    "content": "fileFormatVersion: 2\nguid: 6cc64df6c68419e4aaa0adb31c277cbd\nfolderAsset: yes\nDefaultImporter:\n  userData: \n"
  },
  {
    "path": "demo/Assets/Unity-delaunay/Delaunay/DelaunayHelpers.cs",
    "content": "using UnityEngine;\nusing System;\nusing System.Collections.Generic;\nusing Delaunay.Geo;\nusing Delaunay.LR;\n\nnamespace Delaunay\n{\t\n\n\tpublic class Node\n\t{\n\t\tpublic static Stack<Node> pool = new Stack<Node> ();\n\t\t\n\t\tpublic Node parent;\n\t\tpublic int treeSize;\n\t}\n\n\tpublic enum KruskalType\n\t{\n\t\tMINIMUM,\n\t\tMAXIMUM\n\t}\n\n\tpublic static class DelaunayHelpers\n\t{\n\t\tpublic static List<LineSegment> VisibleLineSegments (List<Edge> edges)\n\t\t{\n\t\t\tList<LineSegment> segments = new List<LineSegment> ();\n\t\t\t\n\t\t\tfor (int i = 0; i<edges.Count; i++) {\n\t\t\t\tEdge edge = edges [i];\n\t\t\t\tif (edge.visible) {\n\t\t\t\t\tNullable<Vector2> p1 = edge.clippedEnds [Side.LEFT];\n\t\t\t\t\tNullable<Vector2> p2 = edge.clippedEnds [Side.RIGHT];\n\t\t\t\t\tsegments.Add (new LineSegment (p1, p2));\n\t\t\t\t}\n\t\t\t}\n\t\t\t\n\t\t\treturn segments;\n\t\t}\n\n\t\tpublic static List<Edge> SelectEdgesForSitePoint (Vector2 coord, List<Edge> edgesToTest)\n\t\t{\n\t\t\treturn edgesToTest.FindAll (delegate (Edge edge) {\n\t\t\t\treturn ((edge.leftSite != null && edge.leftSite.Coord == coord)\n\t\t\t\t\t|| (edge.rightSite != null && edge.rightSite.Coord == coord));\n\t\t\t});\n\t\t}\n\n\t\tpublic static List<Edge> SelectNonIntersectingEdges (/*keepOutMask:BitmapData,*/List<Edge> edgesToTest)\n\t\t{\n//\t\t\tif (keepOutMask == null)\n//\t\t\t{\n\t\t\treturn edgesToTest;\n//\t\t\t}\n\t\t\t\n//\t\t\tvar zeroPoint:Point = new Point();\n//\t\t\treturn edgesToTest.filter(myTest);\n//\t\t\t\n//\t\t\tfunction myTest(edge:Edge, index:int, vector:Vector.<Edge>):Boolean\n//\t\t\t{\n//\t\t\t\tvar delaunayLineBmp:BitmapData = edge.makeDelaunayLineBmp();\n//\t\t\t\tvar notIntersecting:Boolean = !(keepOutMask.hitTest(zeroPoint, 1, delaunayLineBmp, zeroPoint, 1));\n//\t\t\t\tdelaunayLineBmp.dispose();\n//\t\t\t\treturn notIntersecting;\n//\t\t\t}\n\t\t}\n\n\t\tpublic static List<LineSegment> DelaunayLinesForEdges (List<Edge> edges)\n\t\t{\n\t\t\tList<LineSegment> segments = new List<LineSegment> ();\n\t\t\tEdge edge;\n\t\t\tfor (int i = 0; i < edges.Count; i++) {\n\t\t\t\tedge = edges [i];\n\t\t\t\tsegments.Add (edge.DelaunayLine ());\n\t\t\t}\n\t\t\treturn segments;\n\t\t}\n\t\t\n\t\t/**\n\t\t*  Kruskal's spanning tree algorithm with union-find\n\t\t * Skiena: The Algorithm Design Manual, p. 196ff\n\t\t * Note: the sites are implied: they consist of the end points of the line segments\n\t\t*/\n\t\tpublic static List<LineSegment> Kruskal (List<LineSegment> lineSegments, KruskalType type = KruskalType.MINIMUM)\n\t\t{\n\t\t\tDictionary<Nullable<Vector2>,Node> nodes = new Dictionary<Nullable<Vector2>,Node> ();\n\t\t\tList<LineSegment> mst = new List<LineSegment> ();\n\t\t\tStack<Node> nodePool = Node.pool;\n\t\t\t\n\t\t\tswitch (type) {\n\t\t\t// note that the compare functions are the reverse of what you'd expect\n\t\t\t// because (see below) we traverse the lineSegments in reverse order for speed\n\t\t\tcase KruskalType.MAXIMUM:\n\t\t\t\tlineSegments.Sort (delegate (LineSegment l1, LineSegment l2) {\n\t\t\t\t\treturn LineSegment.CompareLengths (l1, l2);\n\t\t\t\t});\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tlineSegments.Sort (delegate (LineSegment l1, LineSegment l2) {\n\t\t\t\t\treturn LineSegment.CompareLengths_MAX (l1, l2);\n\t\t\t\t});\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\t\n\t\t\tfor (int i = lineSegments.Count; --i > -1;) {\n\t\t\t\tLineSegment lineSegment = lineSegments [i];\n\n\t\t\t\tNode node0 = null;\n\t\t\t\tNode rootOfSet0;\n\t\t\t\tif (!nodes.ContainsKey (lineSegment.p0)) {\n\t\t\t\t\tnode0 = nodePool.Count > 0 ? nodePool.Pop () : new Node ();\n\t\t\t\t\t// intialize the node:\n\t\t\t\t\trootOfSet0 = node0.parent = node0;\n\t\t\t\t\tnode0.treeSize = 1;\n\t\t\t\t\t\n\t\t\t\t\tnodes [lineSegment.p0] = node0;\n\t\t\t\t} else {\n\t\t\t\t\tnode0 = nodes [lineSegment.p0];\n\t\t\t\t\trootOfSet0 = Find (node0);\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\tNode node1 = null;\n\t\t\t\tNode rootOfSet1;\n\t\t\t\tif (!nodes.ContainsKey (lineSegment.p1)) {\n\t\t\t\t\tnode1 = nodePool.Count > 0 ? nodePool.Pop () : new Node ();\n\t\t\t\t\t// intialize the node:\n\t\t\t\t\trootOfSet1 = node1.parent = node1;\n\t\t\t\t\tnode1.treeSize = 1;\n\t\t\t\t\t\n\t\t\t\t\tnodes [lineSegment.p1] = node1;\n\t\t\t\t} else {\n\t\t\t\t\tnode1 = nodes [lineSegment.p1];\n\t\t\t\t\trootOfSet1 = Find (node1);\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\tif (rootOfSet0 != rootOfSet1) {\t// nodes not in same set\n\t\t\t\t\tmst.Add (lineSegment);\n\t\t\t\t\t\n\t\t\t\t\t// merge the two sets:\n\t\t\t\t\tint treeSize0 = rootOfSet0.treeSize;\n\t\t\t\t\tint treeSize1 = rootOfSet1.treeSize;\n\t\t\t\t\tif (treeSize0 >= treeSize1) {\n\t\t\t\t\t\t// set0 absorbs set1:\n\t\t\t\t\t\trootOfSet1.parent = rootOfSet0;\n\t\t\t\t\t\trootOfSet0.treeSize += treeSize1;\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// set1 absorbs set0:\n\t\t\t\t\t\trootOfSet0.parent = rootOfSet1;\n\t\t\t\t\t\trootOfSet1.treeSize += treeSize0;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tforeach (Node node in nodes.Values) {\n\t\t\t\tnodePool.Push (node);\n\t\t\t}\n\t\t\t\n\t\t\treturn mst;\n\t\t}\n\n\t\tprivate static Node Find (Node node)\n\t\t{\n\t\t\tif (node.parent == node) {\n\t\t\t\treturn node;\n\t\t\t} else {\n\t\t\t\tNode root = Find (node.parent);\n\t\t\t\t// this line is just to speed up subsequent finds by keeping the tree depth low:\n\t\t\t\tnode.parent = root;\n\t\t\t\treturn root;\n\t\t\t}\n\t\t}\n\t}\n\n\n}"
  },
  {
    "path": "demo/Assets/Unity-delaunay/Delaunay/DelaunayHelpers.cs.meta",
    "content": "fileFormatVersion: 2\nguid: 3e5cf667cd9df4f68a86433bcfff21d4\nMonoImporter:\n  serializedVersion: 2\n  defaultReferences: []\n  executionOrder: 0\n  icon: {instanceID: 0}\n  userData: \n"
  },
  {
    "path": "demo/Assets/Unity-delaunay/Delaunay/Edge.cs",
    "content": "using UnityEngine;\nusing System;\nusing System.Collections.Generic;\nusing Delaunay.Geo;\nusing Delaunay.LR;\n\nnamespace Delaunay\n{\n\t//\timport com.nodename.geom.LineSegment;\n\t//\t\n\t//\timport flash.display.BitmapData;\n\t//\timport flash.display.CapsStyle;\n\t//\timport flash.display.Graphics;\n\t//\timport flash.display.LineScaleMode;\n\t//\timport flash.display.Sprite;\n\t//\timport flash.geom.Point;\n\t//\timport flash.geom.Rectangle;\n\t//\timport flash.utils.Dictionary;\n\t\t\n\t/**\n\t\t * The line segment connecting the two Sites is part of the Delaunay triangulation;\n\t\t * the line segment connecting the two Vertices is part of the Voronoi diagram\n\t\t * @author ashaw\n\t\t * \n\t\t */\n\tpublic sealed class Edge\n\t{\n\t\tprivate static Stack<Edge> _pool = new Stack<Edge> ();\n\n\t\t/**\n\t\t\t * This is the only way to create a new Edge \n\t\t\t * @param site0\n\t\t\t * @param site1\n\t\t\t * @return \n\t\t\t * \n\t\t\t */\n\t\tpublic static Edge CreateBisectingEdge (Site site0, Site site1)\n\t\t{\n\t\t\tfloat dx, dy, absdx, absdy;\n\t\t\tfloat a, b, c;\n\t\t\t\n\t\t\tdx = site1.x - site0.x;\n\t\t\tdy = site1.y - site0.y;\n\t\t\tabsdx = dx > 0 ? dx : -dx;\n\t\t\tabsdy = dy > 0 ? dy : -dy;\n\t\t\tc = site0.x * dx + site0.y * dy + (dx * dx + dy * dy) * 0.5f;\n\t\t\tif (absdx > absdy) {\n\t\t\t\ta = 1.0f;\n\t\t\t\tb = dy / dx;\n\t\t\t\tc /= dx;\n\t\t\t} else {\n\t\t\t\tb = 1.0f;\n\t\t\t\ta = dx / dy;\n\t\t\t\tc /= dy;\n\t\t\t}\n\t\t\t\t\n\t\t\tEdge edge = Edge.Create ();\n\t\t\t\n\t\t\tedge.leftSite = site0;\n\t\t\tedge.rightSite = site1;\n\t\t\tsite0.AddEdge (edge);\n\t\t\tsite1.AddEdge (edge);\n\t\t\t\t\n\t\t\tedge._leftVertex = null;\n\t\t\tedge._rightVertex = null;\n\t\t\t\t\n\t\t\tedge.a = a;\n\t\t\tedge.b = b;\n\t\t\tedge.c = c;\n\t\t\t//trace(\"createBisectingEdge: a \", edge.a, \"b\", edge.b, \"c\", edge.c);\n\t\t\t\t\n\t\t\treturn edge;\n\t\t}\n\n\t\tprivate static Edge Create ()\n\t\t{\n\t\t\tEdge edge;\n\t\t\tif (_pool.Count > 0) {\n\t\t\t\tedge = _pool.Pop ();\n\t\t\t\tedge.Init ();\n\t\t\t} else {\n\t\t\t\tedge = new Edge ();\n\t\t\t}\n\t\t\treturn edge;\n\t\t}\n\t\t\t\n\t\t//\t\tprivate static const LINESPRITE:Sprite = new Sprite();\n\t\t//\t\tprivate static const GRAPHICS:Graphics = LINESPRITE.graphics;\n\t\t//\t\t\n\t\t//\t\tprivate var _delaunayLineBmp:BitmapData;\n\t\t//\t\tinternal function get delaunayLineBmp():BitmapData\n\t\t//\t\t{\n\t\t//\t\t\tif (!_delaunayLineBmp)\n\t\t//\t\t\t{\n\t\t//\t\t\t\t_delaunayLineBmp = makeDelaunayLineBmp();\n\t\t//\t\t\t}\n\t\t//\t\t\treturn _delaunayLineBmp;\n\t\t//\t\t}\n\t\t//\t\t\n\t\t//\t\t// making this available to Voronoi; running out of memory in AIR so I cannot cache the bmp\n\t\t//\t\tinternal function makeDelaunayLineBmp():BitmapData\n\t\t//\t\t{\n\t\t//\t\t\tvar p0:Point = leftSite.coord;\n\t\t//\t\t\tvar p1:Point = rightSite.coord;\n\t\t//\t\t\t\n\t\t//\t\t\tGRAPHICS.clear();\n\t\t//\t\t\t// clear() resets line style back to undefined!\n\t\t//\t\t\tGRAPHICS.lineStyle(0, 0, 1.0, false, LineScaleMode.NONE, CapsStyle.NONE);\n\t\t//\t\t\tGRAPHICS.moveTo(p0.x, p0.y);\n\t\t//\t\t\tGRAPHICS.lineTo(p1.x, p1.y);\n\t\t//\t\t\t\t\t\t\n\t\t//\t\t\tvar w:int = int(Math.ceil(Math.max(p0.x, p1.x)));\n\t\t//\t\t\tif (w < 1)\n\t\t//\t\t\t{\n\t\t//\t\t\t\tw = 1;\n\t\t//\t\t\t}\n\t\t//\t\t\tvar h:int = int(Math.ceil(Math.max(p0.y, p1.y)));\n\t\t//\t\t\tif (h < 1)\n\t\t//\t\t\t{\n\t\t//\t\t\t\th = 1;\n\t\t//\t\t\t}\n\t\t//\t\t\tvar bmp:BitmapData = new BitmapData(w, h, true, 0);\n\t\t//\t\t\tbmp.draw(LINESPRITE);\n\t\t//\t\t\treturn bmp;\n\t\t//\t\t\t}\n\n\t\tpublic LineSegment DelaunayLine ()\n\t\t{\n\t\t\t// draw a line connecting the input Sites for which the edge is a bisector:\n\t\t\treturn new LineSegment (leftSite.Coord, rightSite.Coord);\n\t\t}\n\n\t\tpublic LineSegment VoronoiEdge ()\n\t\t{\n\t\t\tif (!visible)\n\t\t\t\treturn new LineSegment (null, null);\n\t\t\treturn new LineSegment (_clippedVertices [Side.LEFT],\n\t                                         _clippedVertices [Side.RIGHT]);\n\t\t}\n\n\t\tprivate static int _nedges = 0;\n\t\t\t\n\t\tpublic static readonly Edge DELETED = new Edge ();\n\t\t\t\n\t\t// the equation of the edge: ax + by = c\n\t\tpublic float a, b, c;\n\t\t\t\n\t\t// the two Voronoi vertices that the edge connects\n\t\t//\t\t(if one of them is null, the edge extends to infinity)\n\t\tprivate Vertex _leftVertex;\n\t\tpublic Vertex leftVertex {\n\t\t\tget { return _leftVertex;}\n\t\t}\n\t\tprivate Vertex _rightVertex;\n\t\tpublic Vertex rightVertex {\n\t\t\tget { return _rightVertex;}\n\t\t}\n\t\tpublic Vertex Vertex (Side leftRight)\n\t\t{\n\t\t\treturn (leftRight == Side.LEFT) ? _leftVertex : _rightVertex;\n\t\t}\n\t\tpublic void SetVertex (Side leftRight, Vertex v)\n\t\t{\n\t\t\tif (leftRight == Side.LEFT) {\n\t\t\t\t_leftVertex = v;\n\t\t\t} else {\n\t\t\t\t_rightVertex = v;\n\t\t\t}\n\t\t}\n\t\t\t\n\t\tpublic bool IsPartOfConvexHull ()\n\t\t{\n\t\t\treturn (_leftVertex == null || _rightVertex == null);\n\t\t}\n\t\t\t\n\t\tpublic float SitesDistance ()\n\t\t{\n\t\t\treturn Vector2.Distance (leftSite.Coord, rightSite.Coord);\n\t\t}\n\t\t\t\n\t\tpublic static int CompareSitesDistances_MAX (Edge edge0, Edge edge1)\n\t\t{\n\t\t\tfloat length0 = edge0.SitesDistance ();\n\t\t\tfloat length1 = edge1.SitesDistance ();\n\t\t\tif (length0 < length1) {\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t\tif (length0 > length1) {\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t\treturn 0;\n\t\t}\n\t\t\t\n\t\tpublic static int CompareSitesDistances (Edge edge0, Edge edge1)\n\t\t{\n\t\t\treturn - CompareSitesDistances_MAX (edge0, edge1);\n\t\t}\n\t\t\t\n\t\t// Once clipVertices() is called, this Dictionary will hold two Points\n\t\t// representing the clipped coordinates of the left and right ends...\n\t\tprivate Dictionary<Side,Nullable<Vector2>> _clippedVertices;\n\t\tpublic Dictionary<Side,Nullable<Vector2>> clippedEnds {\n\t\t\tget { return _clippedVertices;}\n\t\t}\n\t\t// unless the entire Edge is outside the bounds.\n\t\t// In that case visible will be false:\n\t\tpublic bool visible {\n\t\t\tget { return _clippedVertices != null;}\n\t\t}\n\t\t\t\n\t\t// the two input Sites for which this Edge is a bisector:\n\t\tprivate Dictionary<Side,Site> _sites;\n\t\tpublic Site leftSite {\n\t\t\tget{ return _sites [Side.LEFT];}\n\t\t\tset{ _sites [Side.LEFT] = value;}\n\t\t\t\t\n\t\t}\n\t\tpublic Site rightSite {\n\t\t\tget { return _sites [Side.RIGHT];}\n\t\t\tset { _sites [Side.RIGHT] = value;}\t\t\t\n\t\t}\n\n\t\tpublic Site Site (Side leftRight)\n\t\t{\n\t\t\treturn _sites [leftRight];\n\t\t}\n\t\t\t\n\t\tprivate int _edgeIndex;\n\t\t\t\n\t\tpublic void Dispose ()\n\t\t{\n//\t\t\tif (_delaunayLineBmp) {\n//\t\t\t\t_delaunayLineBmp.Dispose ();\n//\t\t\t\t_delaunayLineBmp = null;\n//\t\t\t}\n\t\t\t_leftVertex = null;\n\t\t\t_rightVertex = null;\n\t\t\tif (_clippedVertices != null) {\n\t\t\t\t_clippedVertices [Side.LEFT] = null;\n\t\t\t\t_clippedVertices [Side.RIGHT] = null;\n\t\t\t\t_clippedVertices = null;\n\t\t\t}\n\t\t\t_sites [Side.LEFT] = null;\n\t\t\t_sites [Side.RIGHT] = null;\n\t\t\t_sites = null;\n\t\t\t\t\n\t\t\t_pool.Push (this);\n\t\t}\n\n\t\tprivate Edge ()\n\t\t{\n\t\t\t//\t\t\tif (lock != PrivateConstructorEnforcer)\n\t\t\t//\t\t\t{\n\t\t\t//\t\t\t\tthrow new Error(\"Edge: constructor is private\");\n\t\t\t//\t\t\t}\n\t\t\t\t\n\t\t\t_edgeIndex = _nedges++;\n\t\t\tInit ();\n\t\t}\n\t\t\t\n\t\tprivate void Init ()\n\t\t{\t\n\t\t\t_sites = new Dictionary<Side,Site> ();\n\t\t}\n\t\t\t\n\t\tpublic override string ToString ()\n\t\t{\n\t\t\treturn \"Edge \" + _edgeIndex.ToString () + \"; sites \" + _sites [Side.LEFT].ToString () + \", \" + _sites [Side.RIGHT].ToString ()\n\t\t\t\t+ \"; endVertices \" + ((_leftVertex != null) ? _leftVertex.vertexIndex.ToString () : \"null\") + \", \"\n\t\t\t\t+ ((_rightVertex != null) ? _rightVertex.vertexIndex.ToString () : \"null\") + \"::\";\n\t\t}\n\n\t\t/**\n\t\t\t * Set _clippedVertices to contain the two ends of the portion of the Voronoi edge that is visible\n\t\t\t * within the bounds.  If no part of the Edge falls within the bounds, leave _clippedVertices null. \n\t\t\t * @param bounds\n\t\t\t * \n\t\t\t */\n\t\tpublic void ClipVertices (Rect bounds)\n\t\t{\n\t\t\tfloat xmin = bounds.xMin;\n\t\t\tfloat ymin = bounds.yMin;\n\t\t\tfloat xmax = bounds.xMax;\n\t\t\tfloat ymax = bounds.yMax;\n\t\t\t\t\n\t\t\tVertex vertex0, vertex1;\n\t\t\tfloat x0, x1, y0, y1;\n\t\t\t\t\n\t\t\tif (a == 1.0 && b >= 0.0) {\n\t\t\t\tvertex0 = _rightVertex;\n\t\t\t\tvertex1 = _leftVertex;\n\t\t\t} else {\n\t\t\t\tvertex0 = _leftVertex;\n\t\t\t\tvertex1 = _rightVertex;\n\t\t\t}\n\t\t\t\n\t\t\tif (a == 1.0) {\n\t\t\t\ty0 = ymin;\n\t\t\t\tif (vertex0 != null && vertex0.y > ymin) {\n\t\t\t\t\ty0 = vertex0.y;\n\t\t\t\t}\n\t\t\t\tif (y0 > ymax) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tx0 = c - b * y0;\n\t\t\t\t\t\n\t\t\t\ty1 = ymax;\n\t\t\t\tif (vertex1 != null && vertex1.y < ymax) {\n\t\t\t\t\ty1 = vertex1.y;\n\t\t\t\t}\n\t\t\t\tif (y1 < ymin) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tx1 = c - b * y1;\n\t\t\t\t\t\n\t\t\t\tif ((x0 > xmax && x1 > xmax) || (x0 < xmin && x1 < xmin)) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\t\t\n\t\t\t\tif (x0 > xmax) {\n\t\t\t\t\tx0 = xmax;\n\t\t\t\t\ty0 = (c - x0) / b;\n\t\t\t\t} else if (x0 < xmin) {\n\t\t\t\t\tx0 = xmin;\n\t\t\t\t\ty0 = (c - x0) / b;\n\t\t\t\t}\n\t\t\t\t\t\n\t\t\t\tif (x1 > xmax) {\n\t\t\t\t\tx1 = xmax;\n\t\t\t\t\ty1 = (c - x1) / b;\n\t\t\t\t} else if (x1 < xmin) {\n\t\t\t\t\tx1 = xmin;\n\t\t\t\t\ty1 = (c - x1) / b;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tx0 = xmin;\n\t\t\t\tif (vertex0 != null && vertex0.x > xmin) {\n\t\t\t\t\tx0 = vertex0.x;\n\t\t\t\t}\n\t\t\t\tif (x0 > xmax) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\ty0 = c - a * x0;\n\t\t\t\t\t\n\t\t\t\tx1 = xmax;\n\t\t\t\tif (vertex1 != null && vertex1.x < xmax) {\n\t\t\t\t\tx1 = vertex1.x;\n\t\t\t\t}\n\t\t\t\tif (x1 < xmin) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\ty1 = c - a * x1;\n\t\t\t\t\t\n\t\t\t\tif ((y0 > ymax && y1 > ymax) || (y0 < ymin && y1 < ymin)) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\t\t\n\t\t\t\tif (y0 > ymax) {\n\t\t\t\t\ty0 = ymax;\n\t\t\t\t\tx0 = (c - y0) / a;\n\t\t\t\t} else if (y0 < ymin) {\n\t\t\t\t\ty0 = ymin;\n\t\t\t\t\tx0 = (c - y0) / a;\n\t\t\t\t}\n\t\t\t\t\t\n\t\t\t\tif (y1 > ymax) {\n\t\t\t\t\ty1 = ymax;\n\t\t\t\t\tx1 = (c - y1) / a;\n\t\t\t\t} else if (y1 < ymin) {\n\t\t\t\t\ty1 = ymin;\n\t\t\t\t\tx1 = (c - y1) / a;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t//\t\t\t_clippedVertices = new Dictionary(true); // XXX: Weak ref'd dict might be a problem to use standard\n\t\t\t_clippedVertices = new Dictionary<Side,Nullable<Vector2>> ();\n\t\t\tif (vertex0 == _leftVertex) {\n\t\t\t\t_clippedVertices [Side.LEFT] = new Vector2 (x0, y0);\n\t\t\t\t_clippedVertices [Side.RIGHT] = new Vector2 (x1, y1);\n\t\t\t} else {\n\t\t\t\t_clippedVertices [Side.RIGHT] = new Vector2 (x0, y0);\n\t\t\t\t_clippedVertices [Side.LEFT] = new Vector2 (x1, y1);\n\t\t\t}\n\t\t}\n\n\t}\n}\n\n//class PrivateConstructorEnforcer {}"
  },
  {
    "path": "demo/Assets/Unity-delaunay/Delaunay/Edge.cs.meta",
    "content": "fileFormatVersion: 2\nguid: 49202b1d309f140d6bd015a7fbce4b64\nMonoImporter:\n  serializedVersion: 2\n  defaultReferences: []\n  executionOrder: 0\n  icon: {instanceID: 0}\n  userData: \n"
  },
  {
    "path": "demo/Assets/Unity-delaunay/Delaunay/EdgeList.cs",
    "content": "using UnityEngine;\nusing Delaunay.Utils;\n\nnamespace Delaunay\n{\n\t\n\tinternal sealed class EdgeList: Utils.IDisposable\n\t{\n\t\tprivate float _deltax;\n\t\tprivate float _xmin;\n\t\t\n\t\tprivate int _hashsize;\n\t\tprivate Halfedge[] _hash;\n\t\tprivate Halfedge _leftEnd;\n\t\tpublic Halfedge leftEnd {\n\t\t\tget { return _leftEnd;}\n\t\t}\n\t\tprivate Halfedge _rightEnd;\n\t\tpublic Halfedge rightEnd {\n\t\t\tget { return _rightEnd;}\n\t\t}\n\t\t\n\t\tpublic void Dispose ()\n\t\t{\n\t\t\tHalfedge halfEdge = _leftEnd;\n\t\t\tHalfedge prevHe;\n\t\t\twhile (halfEdge != _rightEnd) {\n\t\t\t\tprevHe = halfEdge;\n\t\t\t\thalfEdge = halfEdge.edgeListRightNeighbor;\n\t\t\t\tprevHe.Dispose ();\n\t\t\t}\n\t\t\t_leftEnd = null;\n\t\t\t_rightEnd.Dispose ();\n\t\t\t_rightEnd = null;\n\n\t\t\tint i;\n\t\t\tfor (i = 0; i < _hashsize; ++i) {\n\t\t\t\t_hash [i] = null;\n\t\t\t}\n\t\t\t_hash = null;\n\t\t}\n\t\t\n\t\tpublic EdgeList (float xmin, float deltax, int sqrt_nsites)\n\t\t{\n\t\t\t_xmin = xmin;\n\t\t\t_deltax = deltax;\n\t\t\t_hashsize = 2 * sqrt_nsites;\n\n\t\t\t_hash = new Halfedge[_hashsize];\n\t\t\t\n\t\t\t// two dummy Halfedges:\n\t\t\t_leftEnd = Halfedge.CreateDummy ();\n\t\t\t_rightEnd = Halfedge.CreateDummy ();\n\t\t\t_leftEnd.edgeListLeftNeighbor = null;\n\t\t\t_leftEnd.edgeListRightNeighbor = _rightEnd;\n\t\t\t_rightEnd.edgeListLeftNeighbor = _leftEnd;\n\t\t\t_rightEnd.edgeListRightNeighbor = null;\n\t\t\t_hash [0] = _leftEnd;\n\t\t\t_hash [_hashsize - 1] = _rightEnd;\n\t\t}\n\n\t\t/**\n\t\t * Insert newHalfedge to the right of lb \n\t\t * @param lb\n\t\t * @param newHalfedge\n\t\t * \n\t\t */\n\t\tpublic void Insert (Halfedge lb, Halfedge newHalfedge)\n\t\t{\n\t\t\tnewHalfedge.edgeListLeftNeighbor = lb;\n\t\t\tnewHalfedge.edgeListRightNeighbor = lb.edgeListRightNeighbor;\n\t\t\tlb.edgeListRightNeighbor.edgeListLeftNeighbor = newHalfedge;\n\t\t\tlb.edgeListRightNeighbor = newHalfedge;\n\t\t}\n\n\t\t/**\n\t\t * This function only removes the Halfedge from the left-right list.\n\t\t * We cannot dispose it yet because we are still using it. \n\t\t * @param halfEdge\n\t\t * \n\t\t */\n\t\tpublic void Remove (Halfedge halfEdge)\n\t\t{\n\t\t\thalfEdge.edgeListLeftNeighbor.edgeListRightNeighbor = halfEdge.edgeListRightNeighbor;\n\t\t\thalfEdge.edgeListRightNeighbor.edgeListLeftNeighbor = halfEdge.edgeListLeftNeighbor;\n\t\t\thalfEdge.edge = Edge.DELETED;\n\t\t\thalfEdge.edgeListLeftNeighbor = halfEdge.edgeListRightNeighbor = null;\n\t\t}\n\n\t\t/**\n\t\t * Find the rightmost Halfedge that is still left of p \n\t\t * @param p\n\t\t * @return \n\t\t * \n\t\t */\n\t\tpublic Halfedge EdgeListLeftNeighbor (Vector2 p)\n\t\t{\n\t\t\tint i, bucket;\n\t\t\tHalfedge halfEdge;\n\t\t\n\t\t\t/* Use hash table to get close to desired halfedge */\n\t\t\tbucket = (int)((p.x - _xmin) / _deltax * _hashsize);\n\t\t\tif (bucket < 0) {\n\t\t\t\tbucket = 0;\n\t\t\t}\n\t\t\tif (bucket >= _hashsize) {\n\t\t\t\tbucket = _hashsize - 1;\n\t\t\t}\n\t\t\thalfEdge = GetHash (bucket);\n\t\t\tif (halfEdge == null) {\n\t\t\t\tfor (i = 1; true; ++i) {\n\t\t\t\t\tif ((halfEdge = GetHash (bucket - i)) != null)\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tif ((halfEdge = GetHash (bucket + i)) != null)\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\t/* Now search linear list of halfedges for the correct one */\n\t\t\tif (halfEdge == leftEnd || (halfEdge != rightEnd && halfEdge.IsLeftOf (p))) {\n\t\t\t\tdo {\n\t\t\t\t\thalfEdge = halfEdge.edgeListRightNeighbor;\n\t\t\t\t} while (halfEdge != rightEnd && halfEdge.IsLeftOf(p));\n\t\t\t\thalfEdge = halfEdge.edgeListLeftNeighbor;\n\t\t\t} else {\n\t\t\t\tdo {\n\t\t\t\t\thalfEdge = halfEdge.edgeListLeftNeighbor;\n\t\t\t\t} while (halfEdge != leftEnd && !halfEdge.IsLeftOf(p));\n\t\t\t}\n\t\t\n\t\t\t/* Update hash table and reference counts */\n\t\t\tif (bucket > 0 && bucket < _hashsize - 1) {\n\t\t\t\t_hash [bucket] = halfEdge;\n\t\t\t}\n\t\t\treturn halfEdge;\n\t\t}\n\n\t\t/* Get entry from hash table, pruning any deleted nodes */\n\t\tprivate Halfedge GetHash (int b)\n\t\t{\n\t\t\tHalfedge halfEdge;\n\t\t\n\t\t\tif (b < 0 || b >= _hashsize) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\thalfEdge = _hash [b]; \n\t\t\tif (halfEdge != null && halfEdge.edge == Edge.DELETED) {\n\t\t\t\t/* Hash table points to deleted halfedge.  Patch as necessary. */\n\t\t\t\t_hash [b] = null;\n\t\t\t\t// still can't dispose halfEdge yet!\n\t\t\t\treturn null;\n\t\t\t} else {\n\t\t\t\treturn halfEdge;\n\t\t\t}\n\t\t}\n\n\t}\n}"
  },
  {
    "path": "demo/Assets/Unity-delaunay/Delaunay/EdgeList.cs.meta",
    "content": "fileFormatVersion: 2\nguid: 0f2bfd7ed370844afb774f34e1d6366a\nMonoImporter:\n  serializedVersion: 2\n  defaultReferences: []\n  executionOrder: 0\n  icon: {instanceID: 0}\n  userData: \n"
  },
  {
    "path": "demo/Assets/Unity-delaunay/Delaunay/EdgeReorderer.cs",
    "content": "using Delaunay.LR;\nusing Delaunay.Utils;\nusing System.Collections.Generic;\n\nnamespace Delaunay\n{\n\tpublic enum VertexOrSite\n\t{\n\t\tVERTEX,\n\t\tSITE\n\t}\n\t\n\tsealed class EdgeReorderer: Utils.IDisposable\n\t{\n\t\tprivate List<Edge> _edges;\n\t\tprivate List<Side> _edgeOrientations;\n\t\tpublic List<Edge> edges {\n\t\t\tget { return _edges;}\n\t\t}\n\t\tpublic List<Side> edgeOrientations {\n\t\t\tget{ return _edgeOrientations;}\n\t\t}\n\t\t\n\t\tpublic EdgeReorderer (List<Edge> origEdges, VertexOrSite criterion)\n\t\t{\n\t\t\t_edges = new List<Edge> ();\n\t\t\t_edgeOrientations = new List<Side> ();\n\t\t\tif (origEdges.Count > 0) {\n\t\t\t\t_edges = ReorderEdges (origEdges, criterion);\n\t\t\t}\n\t\t}\n\t\t\n\t\tpublic void Dispose ()\n\t\t{\n\t\t\t_edges = null;\n\t\t\t_edgeOrientations = null;\n\t\t}\n\n\t\tprivate List<Edge> ReorderEdges (List<Edge> origEdges, VertexOrSite criterion)\n\t\t{\n\t\t\tint i;\n\t\t\tint n = origEdges.Count;\n\t\t\tEdge edge;\n\t\t\t// we're going to reorder the edges in order of traversal\n\t\t\tbool[] done = new bool[n];\n\t\t\tint nDone = 0;\n\t\t\tfor (int j=0; j<n; j++) {\n\t\t\t\tdone [j] = false;\n\t\t\t}\n\t\t\tList<Edge> newEdges = new List<Edge> (); // TODO: Switch to Deque if performance is a concern\n\t\t\t\n\t\t\ti = 0;\n\t\t\tedge = origEdges [i];\n\t\t\tnewEdges.Add (edge);\n\t\t\t_edgeOrientations.Add (Side.LEFT);\n\t\t\tICoord firstPoint = (criterion == VertexOrSite.VERTEX) ? (ICoord)edge.leftVertex : (ICoord)edge.leftSite;\n\t\t\tICoord lastPoint = (criterion == VertexOrSite.VERTEX) ? (ICoord)edge.rightVertex : (ICoord)edge.rightSite;\n\t\t\t\n\t\t\tif (firstPoint == Vertex.VERTEX_AT_INFINITY || lastPoint == Vertex.VERTEX_AT_INFINITY) {\n\t\t\t\treturn new List<Edge> ();\n\t\t\t}\n\t\t\t\n\t\t\tdone [i] = true;\n\t\t\t++nDone;\n\t\t\t\n\t\t\twhile (nDone < n) {\n\t\t\t\tfor (i = 1; i < n; ++i) {\n\t\t\t\t\tif (done [i]) {\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tedge = origEdges [i];\n\t\t\t\t\tICoord leftPoint = (criterion == VertexOrSite.VERTEX) ? (ICoord)edge.leftVertex : (ICoord)edge.leftSite;\n\t\t\t\t\tICoord rightPoint = (criterion == VertexOrSite.VERTEX) ? (ICoord)edge.rightVertex : (ICoord)edge.rightSite;\n\t\t\t\t\tif (leftPoint == Vertex.VERTEX_AT_INFINITY || rightPoint == Vertex.VERTEX_AT_INFINITY) {\n\t\t\t\t\t\treturn new List<Edge> ();\n\t\t\t\t\t}\n\t\t\t\t\tif (leftPoint == lastPoint) {\n\t\t\t\t\t\tlastPoint = rightPoint;\n\t\t\t\t\t\t_edgeOrientations.Add (Side.LEFT);\n\t\t\t\t\t\tnewEdges.Add (edge);\n\t\t\t\t\t\tdone [i] = true;\n\t\t\t\t\t} else if (rightPoint == firstPoint) {\n\t\t\t\t\t\tfirstPoint = leftPoint;\n\t\t\t\t\t\t_edgeOrientations.Insert (0, Side.LEFT); // TODO: Change datastructure if this is slow\n\t\t\t\t\t\tnewEdges.Insert (0, edge);\n\t\t\t\t\t\tdone [i] = true;\n\t\t\t\t\t} else if (leftPoint == firstPoint) {\n\t\t\t\t\t\tfirstPoint = rightPoint;\n\t\t\t\t\t\t_edgeOrientations.Insert (0, Side.RIGHT);\n\t\t\t\t\t\tnewEdges.Insert (0, edge);\n\t\t\t\t\t\tdone [i] = true;\n\t\t\t\t\t} else if (rightPoint == lastPoint) {\n\t\t\t\t\t\tlastPoint = leftPoint;\n\t\t\t\t\t\t_edgeOrientations.Add (Side.RIGHT);\n\t\t\t\t\t\tnewEdges.Add (edge);\n\t\t\t\t\t\tdone [i] = true;\n\t\t\t\t\t}\n\t\t\t\t\tif (done [i]) {\n\t\t\t\t\t\t++nDone;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\t\n\t\t\treturn newEdges;\n\t\t}\n\n\t}\n}"
  },
  {
    "path": "demo/Assets/Unity-delaunay/Delaunay/EdgeReorderer.cs.meta",
    "content": "fileFormatVersion: 2\nguid: a6e9c0c7f4ae649678b34ec5397e4079\nMonoImporter:\n  serializedVersion: 2\n  defaultReferences: []\n  executionOrder: 0\n  icon: {instanceID: 0}\n  userData: \n"
  },
  {
    "path": "demo/Assets/Unity-delaunay/Delaunay/Halfedge.cs",
    "content": "using UnityEngine;\nusing System;\nusing System.Collections.Generic;\nusing Delaunay.LR;\nusing Delaunay.Geo;\nusing Delaunay.Utils;\n\nnamespace Delaunay\n{\n\n\t\n\tpublic sealed class Halfedge: Delaunay.Utils.IDisposable\n\t{\n\t\tprivate static Stack<Halfedge> _pool = new Stack<Halfedge> ();\n\t\tpublic static Halfedge Create (Edge edge, Nullable<Side> lr)\n\t\t{\n\t\t\tif (_pool.Count > 0) {\n\t\t\t\treturn _pool.Pop ().Init (edge, lr);\n\t\t\t} else {\n\t\t\t\treturn new Halfedge (edge, lr);\n\t\t\t}\n\t\t}\n\t\t\n\t\tpublic static Halfedge CreateDummy ()\n\t\t{\n\t\t\treturn Create (null, null);\n\t\t}\n\t\t\n\t\tpublic Halfedge edgeListLeftNeighbor, edgeListRightNeighbor;\n\t\tpublic Halfedge nextInPriorityQueue;\n\t\t\n\t\tpublic Edge edge;\n\t\tpublic Nullable<Side> leftRight;\n\t\tpublic Vertex vertex;\n\t\t\n\t\t// the vertex's y-coordinate in the transformed Voronoi space V*\n\t\tpublic float ystar;\n\n\t\tpublic Halfedge (Edge edge = null, Nullable<Side> lr = null)\n\t\t{\n\t\t\tInit (edge, lr);\n\t\t}\n\t\t\n\t\tprivate Halfedge Init (Edge edge, Nullable<Side> lr)\n\t\t{\n\t\t\tthis.edge = edge;\n\t\t\tleftRight = lr;\n\t\t\tnextInPriorityQueue = null;\n\t\t\tvertex = null;\n\t\t\treturn this;\n\t\t}\n\t\t\n\t\tpublic override string ToString ()\n\t\t{\n\t\t\treturn \"Halfedge (leftRight: \" + leftRight.ToString () + \"; vertex: \" + vertex.ToString () + \")\";\n\t\t}\n\t\t\n\t\tpublic void Dispose ()\n\t\t{\n\t\t\tif (edgeListLeftNeighbor != null || edgeListRightNeighbor != null) {\n\t\t\t\t// still in EdgeList\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (nextInPriorityQueue != null) {\n\t\t\t\t// still in PriorityQueue\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tedge = null;\n\t\t\tleftRight = null;\n\t\t\tvertex = null;\n\t\t\t_pool.Push (this);\n\t\t}\n\t\t\n\t\tpublic void ReallyDispose ()\n\t\t{\n\t\t\tedgeListLeftNeighbor = null;\n\t\t\tedgeListRightNeighbor = null;\n\t\t\tnextInPriorityQueue = null;\n\t\t\tedge = null;\n\t\t\tleftRight = null;\n\t\t\tvertex = null;\n\t\t\t_pool.Push (this);\n\t\t}\n\n\t\tinternal bool IsLeftOf (Vector2 p)\n\t\t{\n\t\t\tSite topSite;\n\t\t\tbool rightOfSite, above, fast;\n\t\t\tfloat dxp, dyp, dxs, t1, t2, t3, yl;\n\t\t\t\n\t\t\ttopSite = edge.rightSite;\n\t\t\trightOfSite = p.x > topSite.x;\n\t\t\tif (rightOfSite && this.leftRight == Side.LEFT) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tif (!rightOfSite && this.leftRight == Side.RIGHT) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\t\n\t\t\tif (edge.a == 1.0) {\n\t\t\t\tdyp = p.y - topSite.y;\n\t\t\t\tdxp = p.x - topSite.x;\n\t\t\t\tfast = false;\n\t\t\t\tif ((!rightOfSite && edge.b < 0.0) || (rightOfSite && edge.b >= 0.0)) {\n\t\t\t\t\tabove = dyp >= edge.b * dxp;\t\n\t\t\t\t\tfast = above;\n\t\t\t\t} else {\n\t\t\t\t\tabove = p.x + p.y * edge.b > edge.c;\n\t\t\t\t\tif (edge.b < 0.0) {\n\t\t\t\t\t\tabove = !above;\n\t\t\t\t\t}\n\t\t\t\t\tif (!above) {\n\t\t\t\t\t\tfast = true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (!fast) {\n\t\t\t\t\tdxs = topSite.x - edge.leftSite.x;\n\t\t\t\t\tabove = edge.b * (dxp * dxp - dyp * dyp) <\n\t\t\t\t\t\tdxs * dyp * (1.0 + 2.0 * dxp / dxs + edge.b * edge.b);\n\t\t\t\t\tif (edge.b < 0.0) {\n\t\t\t\t\t\tabove = !above;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {  /* edge.b == 1.0 */\n\t\t\t\tyl = edge.c - edge.a * p.x;\n\t\t\t\tt1 = p.y - yl;\n\t\t\t\tt2 = p.x - topSite.x;\n\t\t\t\tt3 = yl - topSite.y;\n\t\t\t\tabove = t1 * t1 > t2 * t2 + t3 * t3;\n\t\t\t}\n\t\t\treturn this.leftRight == Side.LEFT ? above : !above;\n\t\t}\n\n\t}\n}"
  },
  {
    "path": "demo/Assets/Unity-delaunay/Delaunay/Halfedge.cs.meta",
    "content": "fileFormatVersion: 2\nguid: e873e30775b564fbd9b4b27ac5b0787a\nMonoImporter:\n  serializedVersion: 2\n  defaultReferences: []\n  executionOrder: 0\n  icon: {instanceID: 0}\n  userData: \n"
  },
  {
    "path": "demo/Assets/Unity-delaunay/Delaunay/HalfedgePriorityQueue.cs",
    "content": "using UnityEngine;\nusing System.Collections.Generic;\nusing Delaunay.Utils;\n\nnamespace Delaunay\n{\n\t\n\tinternal sealed class HalfedgePriorityQueue: Utils.IDisposable // also known as heap\n\t{\n\t\tprivate Halfedge[] _hash;\n\t\tprivate int _count;\n\t\tprivate int _minBucket;\n\t\tprivate int _hashsize;\n\t\t\n\t\tprivate float _ymin;\n\t\tprivate float _deltay;\n\t\t\n\t\tpublic HalfedgePriorityQueue (float ymin, float deltay, int sqrt_nsites)\n\t\t{\n\t\t\t_ymin = ymin;\n\t\t\t_deltay = deltay;\n\t\t\t_hashsize = 4 * sqrt_nsites;\n\t\t\tInitialize ();\n\t\t}\n\t\t\n\t\tpublic void Dispose ()\n\t\t{\n\t\t\t// get rid of dummies\n\t\t\tfor (int i = 0; i < _hashsize; ++i) {\n\t\t\t\t_hash [i].Dispose ();\n\t\t\t\t_hash [i] = null;\n\t\t\t}\n\t\t\t_hash = null;\n\t\t}\n\n\t\tprivate void Initialize ()\n\t\t{\n\t\t\tint i;\n\t\t\n\t\t\t_count = 0;\n\t\t\t_minBucket = 0;\n\t\t\t_hash = new Halfedge[_hashsize];\n\t\t\t// dummy Halfedge at the top of each hash\n\t\t\tfor (i = 0; i < _hashsize; ++i) {\n\t\t\t\t_hash [i] = Halfedge.CreateDummy ();\n\t\t\t\t_hash [i].nextInPriorityQueue = null;\n\t\t\t}\n\t\t}\n\n\t\tpublic void Insert (Halfedge halfEdge)\n\t\t{\n\t\t\tHalfedge previous, next;\n\t\t\tint insertionBucket = Bucket (halfEdge);\n\t\t\tif (insertionBucket < _minBucket) {\n\t\t\t\t_minBucket = insertionBucket;\n\t\t\t}\n\t\t\tprevious = _hash [insertionBucket];\n\t\t\twhile ((next = previous.nextInPriorityQueue) != null\n\t\t\t&&     (halfEdge.ystar  > next.ystar || (halfEdge.ystar == next.ystar && halfEdge.vertex.x > next.vertex.x))) {\n\t\t\t\tprevious = next;\n\t\t\t}\n\t\t\thalfEdge.nextInPriorityQueue = previous.nextInPriorityQueue; \n\t\t\tprevious.nextInPriorityQueue = halfEdge;\n\t\t\t++_count;\n\t\t}\n\n\t\tpublic void Remove (Halfedge halfEdge)\n\t\t{\n\t\t\tHalfedge previous;\n\t\t\tint removalBucket = Bucket (halfEdge);\n\t\t\t\n\t\t\tif (halfEdge.vertex != null) {\n\t\t\t\tprevious = _hash [removalBucket];\n\t\t\t\twhile (previous.nextInPriorityQueue != halfEdge) {\n\t\t\t\t\tprevious = previous.nextInPriorityQueue;\n\t\t\t\t}\n\t\t\t\tprevious.nextInPriorityQueue = halfEdge.nextInPriorityQueue;\n\t\t\t\t_count--;\n\t\t\t\thalfEdge.vertex = null;\n\t\t\t\thalfEdge.nextInPriorityQueue = null;\n\t\t\t\thalfEdge.Dispose ();\n\t\t\t}\n\t\t}\n\n\t\tprivate int Bucket (Halfedge halfEdge)\n\t\t{\n\t\t\tint theBucket = (int)((halfEdge.ystar - _ymin) / _deltay * _hashsize);\n\t\t\tif (theBucket < 0)\n\t\t\t\ttheBucket = 0;\n\t\t\tif (theBucket >= _hashsize)\n\t\t\t\ttheBucket = _hashsize - 1;\n\t\t\treturn theBucket;\n\t\t}\n\t\t\n\t\tprivate bool IsEmpty (int bucket)\n\t\t{\n\t\t\treturn (_hash [bucket].nextInPriorityQueue == null);\n\t\t}\n\t\t\n\t\t/**\n\t\t * move _minBucket until it contains an actual Halfedge (not just the dummy at the top); \n\t\t * \n\t\t */\n\t\tprivate void AdjustMinBucket ()\n\t\t{\n\t\t\twhile (_minBucket < _hashsize - 1 && IsEmpty(_minBucket)) {\n\t\t\t\t++_minBucket;\n\t\t\t}\n\t\t}\n\n\t\tpublic bool Empty ()\n\t\t{\n\t\t\treturn _count == 0;\n\t\t}\n\n\t\t/**\n\t\t * @return coordinates of the Halfedge's vertex in V*, the transformed Voronoi diagram\n\t\t * \n\t\t */\n\t\tpublic Vector2 Min ()\n\t\t{\n\t\t\tAdjustMinBucket ();\n\t\t\tHalfedge answer = _hash [_minBucket].nextInPriorityQueue;\n\t\t\treturn new Vector2 (answer.vertex.x, answer.ystar);\n\t\t}\n\n\t\t/**\n\t\t * remove and return the min Halfedge\n\t\t * @return \n\t\t * \n\t\t */\n\t\tpublic Halfedge ExtractMin ()\n\t\t{\n\t\t\tHalfedge answer;\n\t\t\n\t\t\t// get the first real Halfedge in _minBucket\n\t\t\tanswer = _hash [_minBucket].nextInPriorityQueue;\n\t\t\t\n\t\t\t_hash [_minBucket].nextInPriorityQueue = answer.nextInPriorityQueue;\n\t\t\t_count--;\n\t\t\tanswer.nextInPriorityQueue = null;\n\t\t\t\n\t\t\treturn answer;\n\t\t}\n\n\t}\n}"
  },
  {
    "path": "demo/Assets/Unity-delaunay/Delaunay/HalfedgePriorityQueue.cs.meta",
    "content": "fileFormatVersion: 2\nguid: 6ba85128b77e245478cd4bc1ac6c8f60\nMonoImporter:\n  serializedVersion: 2\n  defaultReferences: []\n  executionOrder: 0\n  icon: {instanceID: 0}\n  userData: \n"
  },
  {
    "path": "demo/Assets/Unity-delaunay/Delaunay/ICoord.cs",
    "content": "using UnityEngine;\n\nnamespace Delaunay\n{\n\t\n\tpublic interface ICoord\n\t{\n\t\tVector2 Coord {\n\t\t\tget;\n\t\t}\n\t}\n}"
  },
  {
    "path": "demo/Assets/Unity-delaunay/Delaunay/ICoord.cs.meta",
    "content": "fileFormatVersion: 2\nguid: 6a0a816d1340149068ec7fa5bc31c72c\nMonoImporter:\n  serializedVersion: 2\n  defaultReferences: []\n  executionOrder: 0\n  icon: {instanceID: 0}\n  userData: \n"
  },
  {
    "path": "demo/Assets/Unity-delaunay/Delaunay/LR.cs",
    "content": "namespace Delaunay\n{\n\tnamespace LR\n\t{\n\t\tpublic enum Side\n\t\t{\n\t\t\tLEFT = 0,\n\t\t\tRIGHT\n\t\t}\n\n\t\tpublic class SideHelper\n\t\t{\n\t\t\tpublic static Side Other (Side leftRight)\n\t\t\t{\n\t\t\t\treturn leftRight == Side.LEFT ? Side.RIGHT : Side.LEFT;\n\t\t\t}\n\t\t}\n\n\t}\n}"
  },
  {
    "path": "demo/Assets/Unity-delaunay/Delaunay/LR.cs.meta",
    "content": "fileFormatVersion: 2\nguid: 42741f042d2e748aaaf15e94b6ba71dd\nMonoImporter:\n  serializedVersion: 2\n  defaultReferences: []\n  executionOrder: 0\n  icon: {instanceID: 0}\n  userData: \n"
  },
  {
    "path": "demo/Assets/Unity-delaunay/Delaunay/Site.cs",
    "content": "using UnityEngine;\nusing System;\nusing System.Collections.Generic;\nusing Delaunay.Geo;\nusing Delaunay.LR;\n\nnamespace Delaunay\n{\n\t\t\n\tpublic sealed class Site: ICoord, IComparable\n\t{\n\t\tprivate static Stack<Site> _pool = new Stack<Site> ();\n\t\tpublic static Site Create (Vector2 p, uint index, float weight, uint color)\n\t\t{\n\t\t\tif (_pool.Count > 0) {\n\t\t\t\treturn _pool.Pop ().Init (p, index, weight, color);\n\t\t\t} else {\n\t\t\t\treturn new Site (p, index, weight, color);\n\t\t\t}\n\t\t}\n\t\t\n\t\tinternal static void SortSites (List<Site> sites)\n\t\t{\n//\t\t\tsites.sort(Site.compare);\n\t\t\tsites.Sort (); // XXX: Check if this works\n\t\t}\n\n\t\t/**\n\t\t * sort sites on y, then x, coord\n\t\t * also change each site's _siteIndex to match its new position in the list\n\t\t * so the _siteIndex can be used to identify the site for nearest-neighbor queries\n\t\t * \n\t\t * haha \"also\" - means more than one responsibility...\n\t\t * \n\t\t */\n\t\tpublic int CompareTo (System.Object obj) // XXX: Really, really worried about this because it depends on how sorting works in AS3 impl - Julian\n\t\t{\n\t\t\tSite s2 = (Site)obj;\n\n\t\t\tint returnValue = Voronoi.CompareByYThenX (this, s2);\n\t\t\t\n\t\t\t// swap _siteIndex values if necessary to match new ordering:\n\t\t\tuint tempIndex;\n\t\t\tif (returnValue == -1) {\n\t\t\t\tif (this._siteIndex > s2._siteIndex) {\n\t\t\t\t\ttempIndex = this._siteIndex;\n\t\t\t\t\tthis._siteIndex = s2._siteIndex;\n\t\t\t\t\ts2._siteIndex = tempIndex;\n\t\t\t\t}\n\t\t\t} else if (returnValue == 1) {\n\t\t\t\tif (s2._siteIndex > this._siteIndex) {\n\t\t\t\t\ttempIndex = s2._siteIndex;\n\t\t\t\t\ts2._siteIndex = this._siteIndex;\n\t\t\t\t\tthis._siteIndex = tempIndex;\n\t\t\t\t}\n\t\t\t\t\n\t\t\t}\n\t\t\t\n\t\t\treturn returnValue;\n\t\t}\n\n\n\t\tprivate static readonly float EPSILON = .005f;\n\t\tprivate static bool CloseEnough (Vector2 p0, Vector2 p1)\n\t\t{\n\t\t\treturn Vector2.Distance (p0, p1) < EPSILON;\n\t\t}\n\t\t\t\t\n\t\tprivate Vector2 _coord;\n\t\tpublic Vector2 Coord {\n\t\t\tget { return _coord;}\n\t\t}\n\t\t\n\t\tpublic uint color;\n\t\tpublic float weight;\n\t\t\n\t\tprivate uint _siteIndex;\n\t\t\n\t\t// the edges that define this Site's Voronoi region:\n\t\tprivate List<Edge> _edges;\n\t\tinternal List<Edge> edges {\n\t\t\tget { return _edges;}\n\t\t}\n\t\t// which end of each edge hooks up with the previous edge in _edges:\n\t\tprivate List<Side> _edgeOrientations;\n\t\t// ordered list of points that define the region clipped to bounds:\n\t\tprivate List<Vector2> _region;\n\n\t\tprivate Site (Vector2 p, uint index, float weight, uint color)\n\t\t{\n//\t\t\tif (lock != PrivateConstructorEnforcer)\n//\t\t\t{\n//\t\t\t\tthrow new Error(\"Site constructor is private\");\n//\t\t\t}\n\t\t\tInit (p, index, weight, color);\n\t\t}\n\t\t\n\t\tprivate Site Init (Vector2 p, uint index, float weight, uint color)\n\t\t{\n\t\t\t_coord = p;\n\t\t\t_siteIndex = index;\n\t\t\tthis.weight = weight;\n\t\t\tthis.color = color;\n\t\t\t_edges = new List<Edge> ();\n\t\t\t_region = null;\n\t\t\treturn this;\n\t\t}\n\t\t\n\t\tpublic override string ToString ()\n\t\t{\n\t\t\treturn \"Site \" + _siteIndex.ToString () + \": \" + Coord.ToString ();\n\t\t}\n\t\t\n\t\tprivate void Move (Vector2 p)\n\t\t{\n\t\t\tClear ();\n\t\t\t_coord = p;\n\t\t}\n\t\t\n\t\tpublic void Dispose ()\n\t\t{\n//\t\t\t_coord = null;\n\t\t\tClear ();\n\t\t\t_pool.Push (this);\n\t\t}\n\t\t\n\t\tprivate void Clear ()\n\t\t{\n\t\t\tif (_edges != null) {\n\t\t\t\t_edges.Clear ();\n\t\t\t\t_edges = null;\n\t\t\t}\n\t\t\tif (_edgeOrientations != null) {\n\t\t\t\t_edgeOrientations.Clear ();\n\t\t\t\t_edgeOrientations = null;\n\t\t\t}\n\t\t\tif (_region != null) {\n\t\t\t\t_region.Clear ();\n\t\t\t\t_region = null;\n\t\t\t}\n\t\t}\n\t\t\n\t\tpublic void AddEdge (Edge edge)\n\t\t{\n\t\t\t_edges.Add (edge);\n\t\t}\n\t\t\n\t\tpublic Edge NearestEdge ()\n\t\t{\n\t\t\t_edges.Sort (delegate (Edge a, Edge b) {\n\t\t\t\treturn Edge.CompareSitesDistances (a, b);\n\t\t\t});\n\t\t\treturn _edges [0];\n\t\t}\n\t\t\n\t\tpublic List<Site> NeighborSites ()\n\t\t{\n\t\t\tif (_edges == null || _edges.Count == 0) {\n\t\t\t\treturn new List<Site> ();\n\t\t\t}\n\t\t\tif (_edgeOrientations == null) { \n\t\t\t\tReorderEdges ();\n\t\t\t}\n\t\t\tList<Site> list = new List<Site> ();\n\t\t\tEdge edge;\n\t\t\tfor (int i = 0; i < _edges.Count; i++) {\n\t\t\t\tedge = _edges [i];\n\t\t\t\tlist.Add (NeighborSite (edge));\n\t\t\t}\n\t\t\treturn list;\n\t\t}\n\t\t\t\n\t\tprivate Site NeighborSite (Edge edge)\n\t\t{\n\t\t\tif (this == edge.leftSite) {\n\t\t\t\treturn edge.rightSite;\n\t\t\t}\n\t\t\tif (this == edge.rightSite) {\n\t\t\t\treturn edge.leftSite;\n\t\t\t}\n\t\t\treturn null;\n\t\t}\n\t\t\n\t\tinternal List<Vector2> Region (Rect clippingBounds)\n\t\t{\n\t\t\tif (_edges == null || _edges.Count == 0) {\n\t\t\t\treturn new List<Vector2> ();\n\t\t\t}\n\t\t\tif (_edgeOrientations == null) { \n\t\t\t\tReorderEdges ();\n\t\t\t\t_region = ClipToBounds (clippingBounds);\n\t\t\t\tif ((new Polygon (_region)).Winding () == Winding.CLOCKWISE) {\n\t\t\t\t\t_region.Reverse ();\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn _region;\n\t\t}\n\t\t\n\t\tprivate void ReorderEdges ()\n\t\t{\n\t\t\t//trace(\"_edges:\", _edges);\n\t\t\tEdgeReorderer reorderer = new EdgeReorderer (_edges, VertexOrSite.VERTEX);\n\t\t\t_edges = reorderer.edges;\n\t\t\t//trace(\"reordered:\", _edges);\n\t\t\t_edgeOrientations = reorderer.edgeOrientations;\n\t\t\treorderer.Dispose ();\n\t\t}\n\t\t\n\t\tprivate List<Vector2> ClipToBounds (Rect bounds)\n\t\t{\n\t\t\tList<Vector2> points = new List<Vector2> ();\n\t\t\tint n = _edges.Count;\n\t\t\tint i = 0;\n\t\t\tEdge edge;\n\t\t\twhile (i < n && ((_edges[i] as Edge).visible == false)) {\n\t\t\t\t++i;\n\t\t\t}\n\t\t\t\n\t\t\tif (i == n) {\n\t\t\t\t// no edges visible\n\t\t\t\treturn new List<Vector2> ();\n\t\t\t}\n\t\t\tedge = _edges [i];\n\t\t\tSide orientation = _edgeOrientations [i];\n\n\t\t\tif (edge.clippedEnds [orientation] == null) {\n\t\t\t\tDebug.LogError (\"XXX: Null detected when there should be a Vector2!\");\n\t\t\t}\n\t\t\tif (edge.clippedEnds [SideHelper.Other (orientation)] == null) {\n\t\t\t\tDebug.LogError (\"XXX: Null detected when there should be a Vector2!\");\n\t\t\t}\n\t\t\tpoints.Add ((Vector2)edge.clippedEnds [orientation]);\n\t\t\tpoints.Add ((Vector2)edge.clippedEnds [SideHelper.Other (orientation)]);\n\t\t\t\n\t\t\tfor (int j = i + 1; j < n; ++j) {\n\t\t\t\tedge = _edges [j];\n\t\t\t\tif (edge.visible == false) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tConnect (points, j, bounds);\n\t\t\t}\n\t\t\t// close up the polygon by adding another corner point of the bounds if needed:\n\t\t\tConnect (points, i, bounds, true);\n\t\t\t\n\t\t\treturn points;\n\t\t}\n\t\t\n\t\tprivate void Connect (List<Vector2> points, int j, Rect bounds, bool closingUp = false)\n\t\t{\n\t\t\tVector2 rightPoint = points [points.Count - 1];\n\t\t\tEdge newEdge = _edges [j] as Edge;\n\t\t\tSide newOrientation = _edgeOrientations [j];\n\t\t\t// the point that  must be connected to rightPoint:\n\t\t\tif (newEdge.clippedEnds [newOrientation] == null) {\n\t\t\t\tDebug.LogError (\"XXX: Null detected when there should be a Vector2!\");\n\t\t\t}\n\t\t\tVector2 newPoint = (Vector2)newEdge.clippedEnds [newOrientation];\n\t\t\tif (!CloseEnough (rightPoint, newPoint)) {\n\t\t\t\t// The points do not coincide, so they must have been clipped at the bounds;\n\t\t\t\t// see if they are on the same border of the bounds:\n\t\t\t\tif (rightPoint.x != newPoint.x\n\t\t\t\t\t&& rightPoint.y != newPoint.y) {\n\t\t\t\t\t// They are on different borders of the bounds;\n\t\t\t\t\t// insert one or two corners of bounds as needed to hook them up:\n\t\t\t\t\t// (NOTE this will not be correct if the region should take up more than\n\t\t\t\t\t// half of the bounds rect, for then we will have gone the wrong way\n\t\t\t\t\t// around the bounds and included the smaller part rather than the larger)\n\t\t\t\t\tint rightCheck = BoundsCheck.Check (rightPoint, bounds);\n\t\t\t\t\tint newCheck = BoundsCheck.Check (newPoint, bounds);\n\t\t\t\t\tfloat px, py;\n\t\t\t\t\tif ((rightCheck & BoundsCheck.RIGHT) != 0) {\n\t\t\t\t\t\tpx = bounds.xMax;\n\t\t\t\t\t\tif ((newCheck & BoundsCheck.BOTTOM) != 0) {\n\t\t\t\t\t\t\tpy = bounds.yMax;\n\t\t\t\t\t\t\tpoints.Add (new Vector2 (px, py));\n\t\t\t\t\t\t} else if ((newCheck & BoundsCheck.TOP) != 0) {\n\t\t\t\t\t\t\tpy = bounds.yMin;\n\t\t\t\t\t\t\tpoints.Add (new Vector2 (px, py));\n\t\t\t\t\t\t} else if ((newCheck & BoundsCheck.LEFT) != 0) {\n\t\t\t\t\t\t\tif (rightPoint.y - bounds.y + newPoint.y - bounds.y < bounds.height) {\n\t\t\t\t\t\t\t\tpy = bounds.yMin;\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tpy = bounds.yMax;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tpoints.Add (new Vector2 (px, py));\n\t\t\t\t\t\t\tpoints.Add (new Vector2 (bounds.xMin, py));\n\t\t\t\t\t\t}\n\t\t\t\t\t} else if ((rightCheck & BoundsCheck.LEFT) != 0) {\n\t\t\t\t\t\tpx = bounds.xMin;\n\t\t\t\t\t\tif ((newCheck & BoundsCheck.BOTTOM) != 0) {\n\t\t\t\t\t\t\tpy = bounds.yMax;\n\t\t\t\t\t\t\tpoints.Add (new Vector2 (px, py));\n\t\t\t\t\t\t} else if ((newCheck & BoundsCheck.TOP) != 0) {\n\t\t\t\t\t\t\tpy = bounds.yMin;\n\t\t\t\t\t\t\tpoints.Add (new Vector2 (px, py));\n\t\t\t\t\t\t} else if ((newCheck & BoundsCheck.RIGHT) != 0) {\n\t\t\t\t\t\t\tif (rightPoint.y - bounds.y + newPoint.y - bounds.y < bounds.height) {\n\t\t\t\t\t\t\t\tpy = bounds.yMin;\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tpy = bounds.yMax;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tpoints.Add (new Vector2 (px, py));\n\t\t\t\t\t\t\tpoints.Add (new Vector2 (bounds.xMax, py));\n\t\t\t\t\t\t}\n\t\t\t\t\t} else if ((rightCheck & BoundsCheck.TOP) != 0) {\n\t\t\t\t\t\tpy = bounds.yMin;\n\t\t\t\t\t\tif ((newCheck & BoundsCheck.RIGHT) != 0) {\n\t\t\t\t\t\t\tpx = bounds.xMax;\n\t\t\t\t\t\t\tpoints.Add (new Vector2 (px, py));\n\t\t\t\t\t\t} else if ((newCheck & BoundsCheck.LEFT) != 0) {\n\t\t\t\t\t\t\tpx = bounds.xMin;\n\t\t\t\t\t\t\tpoints.Add (new Vector2 (px, py));\n\t\t\t\t\t\t} else if ((newCheck & BoundsCheck.BOTTOM) != 0) {\n\t\t\t\t\t\t\tif (rightPoint.x - bounds.x + newPoint.x - bounds.x < bounds.width) {\n\t\t\t\t\t\t\t\tpx = bounds.xMin;\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tpx = bounds.xMax;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tpoints.Add (new Vector2 (px, py));\n\t\t\t\t\t\t\tpoints.Add (new Vector2 (px, bounds.yMax));\n\t\t\t\t\t\t}\n\t\t\t\t\t} else if ((rightCheck & BoundsCheck.BOTTOM) != 0) {\n\t\t\t\t\t\tpy = bounds.yMax;\n\t\t\t\t\t\tif ((newCheck & BoundsCheck.RIGHT) != 0) {\n\t\t\t\t\t\t\tpx = bounds.xMax;\n\t\t\t\t\t\t\tpoints.Add (new Vector2 (px, py));\n\t\t\t\t\t\t} else if ((newCheck & BoundsCheck.LEFT) != 0) {\n\t\t\t\t\t\t\tpx = bounds.xMin;\n\t\t\t\t\t\t\tpoints.Add (new Vector2 (px, py));\n\t\t\t\t\t\t} else if ((newCheck & BoundsCheck.TOP) != 0) {\n\t\t\t\t\t\t\tif (rightPoint.x - bounds.x + newPoint.x - bounds.x < bounds.width) {\n\t\t\t\t\t\t\t\tpx = bounds.xMin;\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tpx = bounds.xMax;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tpoints.Add (new Vector2 (px, py));\n\t\t\t\t\t\t\tpoints.Add (new Vector2 (px, bounds.yMin));\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (closingUp) {\n\t\t\t\t\t// newEdge's ends have already been added\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tpoints.Add (newPoint);\n\t\t\t}\n\t\t\tif (newEdge.clippedEnds [SideHelper.Other (newOrientation)] == null) {\n\t\t\t\tDebug.LogError (\"XXX: Null detected when there should be a Vector2!\");\n\t\t\t}\n\t\t\tVector2 newRightPoint = (Vector2)newEdge.clippedEnds [SideHelper.Other (newOrientation)];\n\t\t\tif (!CloseEnough (points [0], newRightPoint)) {\n\t\t\t\tpoints.Add (newRightPoint);\n\t\t\t}\n\t\t}\n\t\t\t\t\t\t\t\t\n\t\tpublic float x {\n\t\t\tget { return _coord.x;}\n\t\t}\n\t\tinternal float y {\n\t\t\tget { return _coord.y;}\n\t\t}\n\t\t\n\t\tpublic float Dist (ICoord p)\n\t\t{\n\t\t\treturn Vector2.Distance (p.Coord, this._coord);\n\t\t}\n\n\t}\n}\n\n//\tclass PrivateConstructorEnforcer {}\n\n//\timport flash.geom.Point;\n//\timport flash.geom.Rectangle;\n\t\nstatic class BoundsCheck\n{\n\tpublic static readonly int TOP = 1;\n\tpublic static readonly int BOTTOM = 2;\n\tpublic static readonly int LEFT = 4;\n\tpublic static readonly int RIGHT = 8;\n\t\t\n\t/**\n\t\t * \n\t\t * @param point\n\t\t * @param bounds\n\t\t * @return an int with the appropriate bits set if the Point lies on the corresponding bounds lines\n\t\t * \n\t\t */\n\tpublic static int Check (Vector2 point, Rect bounds)\n\t{\n\t\tint value = 0;\n\t\tif (point.x == bounds.xMin) {\n\t\t\tvalue |= LEFT;\n\t\t}\n\t\tif (point.x == bounds.xMax) {\n\t\t\tvalue |= RIGHT;\n\t\t}\n\t\tif (point.y == bounds.yMin) {\n\t\t\tvalue |= TOP;\n\t\t}\n\t\tif (point.y == bounds.yMax) {\n\t\t\tvalue |= BOTTOM;\n\t\t}\n\t\treturn value;\n\t}\n}"
  },
  {
    "path": "demo/Assets/Unity-delaunay/Delaunay/Site.cs.meta",
    "content": "fileFormatVersion: 2\nguid: fa5d818389dce40d29f97fb47bf83081\nMonoImporter:\n  serializedVersion: 2\n  defaultReferences: []\n  executionOrder: 0\n  icon: {instanceID: 0}\n  userData: \n"
  },
  {
    "path": "demo/Assets/Unity-delaunay/Delaunay/SiteList.cs",
    "content": "using UnityEngine;\nusing System;\nusing System.Collections.Generic;\nusing Delaunay.Geo;\nusing Delaunay.Utils;\n\nnamespace Delaunay\n{\r\n\r\n\tpublic sealed class SiteList: Utils.IDisposable\n\t{\n\t\tprivate List<Site> _sites;\n\t\tprivate int _currentIndex;\n\t\t\n\t\tprivate bool _sorted;\n\t\t\n\t\tpublic SiteList ()\n\t\t{\n\t\t\t_sites = new List<Site> ();\n\t\t\t_sorted = false;\r\n\t\t}\n\t\t\n\t\tpublic void Dispose ()\n\t\t{\n\t\t\tif (_sites != null) {\n\t\t\t\tfor (int i = 0; i < _sites.Count; i++) {\n\t\t\t\t\tSite site = _sites [i];\n\t\t\t\t\tsite.Dispose ();\n\t\t\t\t}\n\t\t\t\t_sites.Clear ();\n\t\t\t\t_sites = null;\n\t\t\t}\n\t\t}\n\t\t\n\t\tpublic int Add (Site site)\n\t\t{\n\t\t\t_sorted = false;\n\t\t\t_sites.Add (site);\n\t\t\treturn _sites.Count;\n\t\t}\n\t\t\n\t\tpublic int Count {\n\t\t\tget { return _sites.Count;}\n\t\t}\n\t\t\n\t\tpublic Site Next ()\n\t\t{\n\t\t\tif (_sorted == false) {\n\t\t\t\tUnityEngine.Debug.LogError (\"SiteList::next():  sites have not been sorted\");\n\t\t\t}\n\t\t\tif (_currentIndex < _sites.Count) {\n\t\t\t\treturn _sites [_currentIndex++];\n\t\t\t} else {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t}\n\n\t\tinternal Rect GetSitesBounds ()\n\t\t{\n\t\t\tif (_sorted == false) {\n\t\t\t\tSite.SortSites (_sites);\n\t\t\t\t_currentIndex = 0;\n\t\t\t\t_sorted = true;\n\t\t\t}\n\t\t\tfloat xmin, xmax, ymin, ymax;\n\t\t\tif (_sites.Count == 0) {\n\t\t\t\treturn new Rect (0, 0, 0, 0);\n\t\t\t}\n\t\t\txmin = float.MaxValue;\n\t\t\txmax = float.MinValue;\n\t\t\tfor (int i = 0; i<_sites.Count; i++) {\n\t\t\t\tSite site = _sites [i];\n\t\t\t\tif (site.x < xmin) {\n\t\t\t\t\txmin = site.x;\n\t\t\t\t}\n\t\t\t\tif (site.x > xmax) {\n\t\t\t\t\txmax = site.x;\n\t\t\t\t}\n\t\t\t}\n\t\t\t// here's where we assume that the sites have been sorted on y:\n\t\t\tymin = _sites [0].y;\n\t\t\tymax = _sites [_sites.Count - 1].y;\n\t\t\t\n\t\t\treturn new Rect (xmin, ymin, xmax - xmin, ymax - ymin);\n\t\t}\n\n\t\tpublic List<uint> SiteColors (/*BitmapData referenceImage = null*/)\n\t\t{\n\t\t\tList<uint> colors = new List<uint> ();\n\t\t\tSite site;\n\t\t\tfor (int i = 0; i< _sites.Count; i++) {\n\t\t\t\tsite = _sites [i];\n\t\t\t\tcolors.Add (/*referenceImage ? referenceImage.getPixel(site.x, site.y) :*/site.color);\n\t\t\t}\n\t\t\treturn colors;\n\t\t}\n\n\t\tpublic List<Vector2> SiteCoords ()\n\t\t{\n\t\t\tList<Vector2> coords = new List<Vector2> ();\n\t\t\tSite site;\n\t\t\tfor (int i = 0; i<_sites.Count; i++) {\n\t\t\t\tsite = _sites [i];\n\t\t\t\tcoords.Add (site.Coord);\n\t\t\t}\n\t\t\treturn coords;\n\t\t}\n\n\t\t/**\n\t\t * \n\t\t * @return the largest circle centered at each site that fits in its region;\n\t\t * if the region is infinite, return a circle of radius 0.\n\t\t * \n\t\t */\n\t\tpublic List<Circle> Circles ()\n\t\t{\n\t\t\tList<Circle> circles = new List<Circle> ();\n\t\t\tSite site;\n\t\t\tfor (int i = 0; i<_sites.Count; i++) {\n\t\t\t\tsite = _sites [i];\n\t\t\t\tfloat radius = 0f;\n\t\t\t\tEdge nearestEdge = site.NearestEdge ();\n\t\t\t\t\n\t\t\t\tif (!nearestEdge.IsPartOfConvexHull ()) {\n\t\t\t\t\tradius = nearestEdge.SitesDistance () * 0.5f;\n\t\t\t\t}\n\t\t\t\tcircles.Add (new Circle (site.x, site.y, radius));\n\t\t\t}\n\t\t\treturn circles;\n\t\t}\n\n\t\tpublic List<List<Vector2>> Regions (Rect plotBounds)\n\t\t{\n\t\t\tList<List<Vector2>> regions = new List<List<Vector2>> ();\n\t\t\tSite site;\n\t\t\tfor (int i = 0; i< _sites.Count; i++) {\n\t\t\t\tsite = _sites [i];\n\t\t\t\tregions.Add (site.Region (plotBounds));\n\t\t\t}\n\t\t\treturn regions;\n\t\t}\n\n\t\t/**\n\t\t * \n\t\t * @param proximityMap a BitmapData whose regions are filled with the site index values; see PlanePointsCanvas::fillRegions()\n\t\t * @param x\n\t\t * @param y\n\t\t * @return coordinates of nearest Site to (x, y)\n\t\t * \n\t\t */\n\t\tpublic Nullable<Vector2> NearestSitePoint (/*proximityMap:BitmapData,*/float x, float y)\n\t\t{\n//\t\t\tuint index = proximityMap.getPixel(x, y);\n//\t\t\tif (index > _sites.length - 1)\n//\t\t\t{\n\t\t\treturn null;\n//\t\t\t}\n//\t\t\treturn _sites[index].coord;\n\t\t}\n\t\t\n\t}\n}"
  },
  {
    "path": "demo/Assets/Unity-delaunay/Delaunay/SiteList.cs.meta",
    "content": "fileFormatVersion: 2\nguid: d11fa694a445f4fbb9c6ef8f51d7d549\nMonoImporter:\n  serializedVersion: 2\n  defaultReferences: []\n  executionOrder: 0\n  icon: {instanceID: 0}\n  userData: \n"
  },
  {
    "path": "demo/Assets/Unity-delaunay/Delaunay/Triangle.cs",
    "content": "using System.Collections.Generic;\nusing Delaunay.Utils;\n\nnamespace Delaunay\n{\n\t\n\tpublic sealed class Triangle: IDisposable\n\t{\n\t\tprivate List<Site> _sites;\n\t\tpublic List<Site> sites {\n\t\t\tget { return this._sites; }\n\t\t}\n\t\t\n\t\tpublic Triangle (Site a, Site b, Site c)\n\t\t{\n\t\t\t_sites = new List<Site> () { a, b, c };\n\t\t}\n\t\t\n\t\tpublic void Dispose ()\n\t\t{\n\t\t\t_sites.Clear ();\n\t\t\t_sites = null;\n\t\t}\n\n\t}\n}"
  },
  {
    "path": "demo/Assets/Unity-delaunay/Delaunay/Triangle.cs.meta",
    "content": "fileFormatVersion: 2\nguid: c86ee3287678f413e99d8256fcbbbd6f\nMonoImporter:\n  serializedVersion: 2\n  defaultReferences: []\n  executionOrder: 0\n  icon: {instanceID: 0}\n  userData: \n"
  },
  {
    "path": "demo/Assets/Unity-delaunay/Delaunay/Vertex.cs",
    "content": "using UnityEngine;\nusing System;\nusing System.Collections.Generic;\nusing Delaunay.LR;\n\nnamespace Delaunay\n{\n\t\n\tpublic sealed class Vertex: ICoord\n\t{\n\t\tpublic static readonly Vertex VERTEX_AT_INFINITY = new Vertex (float.NaN, float.NaN);\n\t\t\n\t\tprivate static Stack<Vertex> _pool = new Stack<Vertex> ();\n\t\tprivate static Vertex Create (float x, float y)\n\t\t{\n\t\t\tif (float.IsNaN (x) || float.IsNaN (y)) {\n\t\t\t\treturn VERTEX_AT_INFINITY;\n\t\t\t}\n\t\t\tif (_pool.Count > 0) {\n\t\t\t\treturn _pool.Pop ().Init (x, y);\n\t\t\t} else {\n\t\t\t\treturn new Vertex (x, y);\n\t\t\t}\n\t\t}\n\n\n\t\tprivate static int _nvertices = 0;\n\t\t\n\t\tprivate Vector2 _coord;\n\t\tpublic Vector2 Coord {\n\t\t\tget { return _coord;}\n\t\t}\n\t\tprivate int _vertexIndex;\n\t\tpublic int vertexIndex {\n\t\t\tget { return _vertexIndex;}\n\t\t}\n\t\t\n\t\tpublic Vertex (float x, float y)\n\t\t{\n\t\t\tInit (x, y);\n\t\t}\n\t\t\n\t\tprivate Vertex Init (float x, float y)\n\t\t{\n\t\t\t_coord = new Vector2 (x, y);\n\t\t\treturn this;\n\t\t}\n\t\t\n\t\tpublic void Dispose ()\n\t\t{\n\t\t\t_pool.Push (this);\n\t\t}\n\t\t\n\t\tpublic void SetIndex ()\n\t\t{\n\t\t\t_vertexIndex = _nvertices++;\n\t\t}\n\t\t\n\t\tpublic override string ToString ()\n\t\t{\n\t\t\treturn \"Vertex (\" + _vertexIndex + \")\";\n\t\t}\n\n\t\t/**\n\t\t * This is the only way to make a Vertex\n\t\t * \n\t\t * @param halfedge0\n\t\t * @param halfedge1\n\t\t * @return \n\t\t * \n\t\t */\n\t\tpublic static Vertex Intersect (Halfedge halfedge0, Halfedge halfedge1)\n\t\t{\n\t\t\tEdge edge0, edge1, edge;\n\t\t\tHalfedge halfedge;\n\t\t\tfloat determinant, intersectionX, intersectionY;\n\t\t\tbool rightOfSite;\n\t\t\n\t\t\tedge0 = halfedge0.edge;\n\t\t\tedge1 = halfedge1.edge;\n\t\t\tif (edge0 == null || edge1 == null) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tif (edge0.rightSite == edge1.rightSite) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\n\t\t\tdeterminant = edge0.a * edge1.b - edge0.b * edge1.a;\n\t\t\tif (-1.0e-10 < determinant && determinant < 1.0e-10) {\n\t\t\t\t// the edges are parallel\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\n\t\t\tintersectionX = (edge0.c * edge1.b - edge1.c * edge0.b) / determinant;\n\t\t\tintersectionY = (edge1.c * edge0.a - edge0.c * edge1.a) / determinant;\n\t\t\n\t\t\tif (Voronoi.CompareByYThenX (edge0.rightSite, edge1.rightSite) < 0) {\n\t\t\t\thalfedge = halfedge0;\n\t\t\t\tedge = edge0;\n\t\t\t} else {\n\t\t\t\thalfedge = halfedge1;\n\t\t\t\tedge = edge1;\n\t\t\t}\n\t\t\trightOfSite = intersectionX >= edge.rightSite.x;\n\t\t\tif ((rightOfSite && halfedge.leftRight == Side.LEFT)\n\t\t\t\t|| (!rightOfSite && halfedge.leftRight == Side.RIGHT)) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\n\t\t\treturn Vertex.Create (intersectionX, intersectionY);\n\t\t}\n\t\t\n\t\tpublic float x {\n\t\t\tget { return _coord.x;}\n\t\t}\n\t\tpublic float y {\n\t\t\tget{ return _coord.y;}\n\t\t}\n\t\t\n\t}\n}"
  },
  {
    "path": "demo/Assets/Unity-delaunay/Delaunay/Vertex.cs.meta",
    "content": "fileFormatVersion: 2\nguid: 16e154efbeed043e1865a7d95f623368\nMonoImporter:\n  serializedVersion: 2\n  defaultReferences: []\n  executionOrder: 0\n  icon: {instanceID: 0}\n  userData: \n"
  },
  {
    "path": "demo/Assets/Unity-delaunay/Delaunay/Voronoi.cs",
    "content": "/*\n * The author of this software is Steven Fortune.  Copyright (c) 1994 by AT&T\n * Bell Laboratories.\n * Permission to use, copy, modify, and distribute this software for any\n * purpose without fee is hereby granted, provided that this entire notice\n * is included in all copies of any software which is or includes a copy\n * or modification of this software and in all copies of the supporting\n * documentation for such software.\n * THIS SOFTWARE IS BEING PROVIDED \"AS IS\", WITHOUT ANY EXPRESS OR IMPLIED\n * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHORS NOR AT&T MAKE ANY\n * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY\n * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.\n */\n\nusing UnityEngine;\nusing System;\nusing System.Collections.Generic;\nusing Delaunay.Geo;\nusing Delaunay.Utils;\nusing Delaunay.LR;\n\nnamespace Delaunay\n{\n\tpublic sealed class Voronoi: Utils.IDisposable\n\t{\n\t\tprivate SiteList _sites;\n\t\tprivate Dictionary <Vector2,Site> _sitesIndexedByLocation;\n\t\tprivate List<Triangle> _triangles;\n\t\tprivate List<Edge> _edges;\n\n\t\t\n\t\t// TODO generalize this so it doesn't have to be a rectangle;\n\t\t// then we can make the fractal voronois-within-voronois\n\t\tprivate Rect _plotBounds;\n\t\tpublic Rect plotBounds {\n\t\t\tget { return _plotBounds;}\n\t\t}\n\t\t\n\t\tpublic void Dispose ()\n\t\t{\n\t\t\tint i, n;\n\t\t\tif (_sites != null) {\n\t\t\t\t_sites.Dispose ();\n\t\t\t\t_sites = null;\n\t\t\t}\n\t\t\tif (_triangles != null) {\n\t\t\t\tn = _triangles.Count;\n\t\t\t\tfor (i = 0; i < n; ++i) {\n\t\t\t\t\t_triangles [i].Dispose ();\n\t\t\t\t}\n\t\t\t\t_triangles.Clear ();\n\t\t\t\t_triangles = null;\n\t\t\t}\n\t\t\tif (_edges != null) {\n\t\t\t\tn = _edges.Count;\n\t\t\t\tfor (i = 0; i < n; ++i) {\n\t\t\t\t\t_edges [i].Dispose ();\n\t\t\t\t}\n\t\t\t\t_edges.Clear ();\n\t\t\t\t_edges = null;\n\t\t\t}\n//\t\t\t_plotBounds = null;\n\t\t\t_sitesIndexedByLocation = null;\n\t\t}\n\t\t\n\t\tpublic Voronoi (List<Vector2> points, List<uint> colors, Rect plotBounds)\n\t\t{\n\t\t\t_sites = new SiteList ();\n\t\t\t_sitesIndexedByLocation = new Dictionary <Vector2,Site> (); // XXX: Used to be Dictionary(true) -- weak refs. \n\t\t\tAddSites (points, colors);\n\t\t\t_plotBounds = plotBounds;\n\t\t\t_triangles = new List<Triangle> ();\n\t\t\t_edges = new List<Edge> ();\n\t\t\tFortunesAlgorithm ();\n\t\t}\n\t\t\n\t\tprivate void AddSites (List<Vector2> points, List<uint> colors)\n\t\t{\n\t\t\tint length = points.Count;\n\t\t\tfor (int i = 0; i < length; ++i) {\n\t\t\t\tAddSite (points [i], (colors != null) ? colors [i] : 0, i);\n\t\t\t}\n\t\t}\n\t\t\n\t\tprivate void AddSite (Vector2 p, uint color, int index)\n\t\t{\n\t\t\tif (_sitesIndexedByLocation.ContainsKey (p))\n\t\t\t\treturn; // Prevent duplicate site! (Adapted from https://github.com/nodename/as3delaunay/issues/1)\n\t\t\tfloat weight = UnityEngine.Random.value * 100f;\n\t\t\tSite site = Site.Create (p, (uint)index, weight, color);\n\t\t\t_sites.Add (site);\n\t\t\t_sitesIndexedByLocation [p] = site;\n\t\t}\n\n\t\tpublic List<Edge> Edges ()\n\t\t{\n\t\t\treturn _edges;\n\t\t}\n          \n\t\tpublic List<Vector2> Region (Vector2 p)\n\t\t{\n\t\t\tSite site = _sitesIndexedByLocation [p];\n\t\t\tif (site == null) {\n\t\t\t\treturn new List<Vector2> ();\n\t\t\t}\n\t\t\treturn site.Region (_plotBounds);\n\t\t}\n\n\t\t// TODO: bug: if you call this before you call region(), something goes wrong :(\n\t\tpublic List<Vector2> NeighborSitesForSite (Vector2 coord)\n\t\t{\n\t\t\tList<Vector2> points = new List<Vector2> ();\n\t\t\tSite site = _sitesIndexedByLocation [coord];\n\t\t\tif (site == null) {\n\t\t\t\treturn points;\n\t\t\t}\n\t\t\tList<Site> sites = site.NeighborSites ();\n\t\t\tSite neighbor;\n\t\t\tfor (int nIndex =0; nIndex<sites.Count; nIndex++) {\n\t\t\t\tneighbor = sites [nIndex];\n\t\t\t\tpoints.Add (neighbor.Coord);\n\t\t\t}\n\t\t\treturn points;\n\t\t}\n\n\t\tpublic List<Circle> Circles ()\n\t\t{\n\t\t\treturn _sites.Circles ();\n\t\t}\n\t\t\n\t\tpublic List<LineSegment> VoronoiBoundaryForSite (Vector2 coord)\n\t\t{\n\t\t\treturn DelaunayHelpers.VisibleLineSegments (DelaunayHelpers.SelectEdgesForSitePoint (coord, _edges));\n\t\t}\n\n\t\tpublic List<LineSegment> DelaunayLinesForSite (Vector2 coord)\n\t\t{\n\t\t\treturn DelaunayHelpers.DelaunayLinesForEdges (DelaunayHelpers.SelectEdgesForSitePoint (coord, _edges));\n\t\t}\n\t\t\n\t\tpublic List<LineSegment> VoronoiDiagram ()\n\t\t{\n\t\t\treturn DelaunayHelpers.VisibleLineSegments (_edges);\n\t\t}\n\t\t\n\t\tpublic List<LineSegment> DelaunayTriangulation (/*BitmapData keepOutMask = null*/)\n\t\t{\n\t\t\treturn DelaunayHelpers.DelaunayLinesForEdges (DelaunayHelpers.SelectNonIntersectingEdges (/*keepOutMask,*/_edges));\n\t\t}\n\t\t\n\t\tpublic List<LineSegment> Hull ()\n\t\t{\n\t\t\treturn DelaunayHelpers.DelaunayLinesForEdges (HullEdges ());\n\t\t}\n\t\t\n\t\tprivate List<Edge> HullEdges ()\n\t\t{\n\t\t\treturn _edges.FindAll (delegate (Edge edge) {\n\t\t\t\treturn (edge.IsPartOfConvexHull ());\n\t\t\t});\n\t\t}\n\n\t\tpublic List<Vector2> HullPointsInOrder ()\n\t\t{\n\t\t\tList<Edge> hullEdges = HullEdges ();\n\t\t\t\n\t\t\tList<Vector2> points = new List<Vector2> ();\n\t\t\tif (hullEdges.Count == 0) {\n\t\t\t\treturn points;\n\t\t\t}\n\t\t\t\n\t\t\tEdgeReorderer reorderer = new EdgeReorderer (hullEdges, VertexOrSite.SITE);\n\t\t\thullEdges = reorderer.edges;\n\t\t\tList<Side> orientations = reorderer.edgeOrientations;\n\t\t\treorderer.Dispose ();\n\t\t\t\n\t\t\tSide orientation;\n\n\t\t\tint n = hullEdges.Count;\n\t\t\tfor (int i = 0; i < n; ++i) {\n\t\t\t\tEdge edge = hullEdges [i];\n\t\t\t\torientation = orientations [i];\n\t\t\t\tpoints.Add (edge.Site (orientation).Coord);\n\t\t\t}\n\t\t\treturn points;\n\t\t}\n\t\t\n\t\tpublic List<LineSegment> SpanningTree (KruskalType type = KruskalType.MINIMUM/*, BitmapData keepOutMask = null*/)\n\t\t{\n\t\t\tList<Edge> edges = DelaunayHelpers.SelectNonIntersectingEdges (/*keepOutMask,*/_edges);\n\t\t\tList<LineSegment> segments = DelaunayHelpers.DelaunayLinesForEdges (edges);\n\t\t\treturn DelaunayHelpers.Kruskal (segments, type);\n\t\t}\n\n\t\tpublic List<List<Vector2>> Regions ()\n\t\t{\n\t\t\treturn _sites.Regions (_plotBounds);\n\t\t}\n\t\t\n\t\tpublic List<uint> SiteColors (/*BitmapData referenceImage = null*/)\n\t\t{\n\t\t\treturn _sites.SiteColors (/*referenceImage*/);\n\t\t}\n\t\t\n\t\t/**\n\t\t * \n\t\t * @param proximityMap a BitmapData whose regions are filled with the site index values; see PlanePointsCanvas::fillRegions()\n\t\t * @param x\n\t\t * @param y\n\t\t * @return coordinates of nearest Site to (x, y)\n\t\t * \n\t\t */\n\t\tpublic Nullable<Vector2> NearestSitePoint (/*BitmapData proximityMap,*/float x, float y)\n\t\t{\n\t\t\treturn _sites.NearestSitePoint (/*proximityMap,*/x, y);\n\t\t}\n\t\t\n\t\tpublic List<Vector2> SiteCoords ()\n\t\t{\n\t\t\treturn _sites.SiteCoords ();\n\t\t}\n\n\t\tprivate Site fortunesAlgorithm_bottomMostSite;\n\t\tprivate void FortunesAlgorithm ()\n\t\t{\n\t\t\tSite newSite, bottomSite, topSite, tempSite;\n\t\t\tVertex v, vertex;\n\t\t\tVector2 newintstar = Vector2.zero; //Because the compiler doesn't know that it will have a value - Julian\n\t\t\tSide leftRight;\n\t\t\tHalfedge lbnd, rbnd, llbnd, rrbnd, bisector;\n\t\t\tEdge edge;\n\t\t\t\n\t\t\tRect dataBounds = _sites.GetSitesBounds ();\n\t\t\t\n\t\t\tint sqrt_nsites = (int)(Mathf.Sqrt (_sites.Count + 4));\n\t\t\tHalfedgePriorityQueue heap = new HalfedgePriorityQueue (dataBounds.y, dataBounds.height, sqrt_nsites);\n\t\t\tEdgeList edgeList = new EdgeList (dataBounds.x, dataBounds.width, sqrt_nsites);\n\t\t\tList<Halfedge> halfEdges = new List<Halfedge> ();\n\t\t\tList<Vertex> vertices = new List<Vertex> ();\n\t\t\t\n\t\t\tfortunesAlgorithm_bottomMostSite = _sites.Next ();\n\t\t\tnewSite = _sites.Next ();\n\t\t\t\n\t\t\tfor (;;) {\n\t\t\t\tif (heap.Empty () == false) {\n\t\t\t\t\tnewintstar = heap.Min ();\n\t\t\t\t}\n\t\t\t\n\t\t\t\tif (newSite != null \n\t\t\t\t\t&& (heap.Empty () || CompareByYThenX (newSite, newintstar) < 0)) {\n\t\t\t\t\t/* new site is smallest */\n\t\t\t\t\t//trace(\"smallest: new site \" + newSite);\n\t\t\t\t\t\n\t\t\t\t\t// Step 8:\n\t\t\t\t\tlbnd = edgeList.EdgeListLeftNeighbor (newSite.Coord);\t// the Halfedge just to the left of newSite\n\t\t\t\t\t//trace(\"lbnd: \" + lbnd);\n\t\t\t\t\trbnd = lbnd.edgeListRightNeighbor;\t\t// the Halfedge just to the right\n\t\t\t\t\t//trace(\"rbnd: \" + rbnd);\n\t\t\t\t\tbottomSite = FortunesAlgorithm_rightRegion (lbnd);\t\t// this is the same as leftRegion(rbnd)\n\t\t\t\t\t// this Site determines the region containing the new site\n\t\t\t\t\t//trace(\"new Site is in region of existing site: \" + bottomSite);\n\t\t\t\t\t\n\t\t\t\t\t// Step 9:\n\t\t\t\t\tedge = Edge.CreateBisectingEdge (bottomSite, newSite);\n\t\t\t\t\t//trace(\"new edge: \" + edge);\n\t\t\t\t\t_edges.Add (edge);\n\t\t\t\t\t\n\t\t\t\t\tbisector = Halfedge.Create (edge, Side.LEFT);\n\t\t\t\t\thalfEdges.Add (bisector);\n\t\t\t\t\t// inserting two Halfedges into edgeList constitutes Step 10:\n\t\t\t\t\t// insert bisector to the right of lbnd:\n\t\t\t\t\tedgeList.Insert (lbnd, bisector);\n\t\t\t\t\t\n\t\t\t\t\t// first half of Step 11:\n\t\t\t\t\tif ((vertex = Vertex.Intersect (lbnd, bisector)) != null) {\n\t\t\t\t\t\tvertices.Add (vertex);\n\t\t\t\t\t\theap.Remove (lbnd);\n\t\t\t\t\t\tlbnd.vertex = vertex;\n\t\t\t\t\t\tlbnd.ystar = vertex.y + newSite.Dist (vertex);\n\t\t\t\t\t\theap.Insert (lbnd);\n\t\t\t\t\t}\n\t\t\t\t\t\n\t\t\t\t\tlbnd = bisector;\n\t\t\t\t\tbisector = Halfedge.Create (edge, Side.RIGHT);\n\t\t\t\t\thalfEdges.Add (bisector);\n\t\t\t\t\t// second Halfedge for Step 10:\n\t\t\t\t\t// insert bisector to the right of lbnd:\n\t\t\t\t\tedgeList.Insert (lbnd, bisector);\n\t\t\t\t\t\n\t\t\t\t\t// second half of Step 11:\n\t\t\t\t\tif ((vertex = Vertex.Intersect (bisector, rbnd)) != null) {\n\t\t\t\t\t\tvertices.Add (vertex);\n\t\t\t\t\t\tbisector.vertex = vertex;\n\t\t\t\t\t\tbisector.ystar = vertex.y + newSite.Dist (vertex);\n\t\t\t\t\t\theap.Insert (bisector);\t\n\t\t\t\t\t}\n\t\t\t\t\t\n\t\t\t\t\tnewSite = _sites.Next ();\t\n\t\t\t\t} else if (heap.Empty () == false) {\n\t\t\t\t\t/* intersection is smallest */\n\t\t\t\t\tlbnd = heap.ExtractMin ();\n\t\t\t\t\tllbnd = lbnd.edgeListLeftNeighbor;\n\t\t\t\t\trbnd = lbnd.edgeListRightNeighbor;\n\t\t\t\t\trrbnd = rbnd.edgeListRightNeighbor;\n\t\t\t\t\tbottomSite = FortunesAlgorithm_leftRegion (lbnd);\n\t\t\t\t\ttopSite = FortunesAlgorithm_rightRegion (rbnd);\n\t\t\t\t\t// these three sites define a Delaunay triangle\n\t\t\t\t\t// (not actually using these for anything...)\n\t\t\t\t\t//_triangles.push(new Triangle(bottomSite, topSite, rightRegion(lbnd)));\n\t\t\t\t\t\n\t\t\t\t\tv = lbnd.vertex;\n\t\t\t\t\tv.SetIndex ();\n\t\t\t\t\tlbnd.edge.SetVertex ((Side)lbnd.leftRight, v);\n\t\t\t\t\trbnd.edge.SetVertex ((Side)rbnd.leftRight, v);\n\t\t\t\t\tedgeList.Remove (lbnd); \n\t\t\t\t\theap.Remove (rbnd);\n\t\t\t\t\tedgeList.Remove (rbnd); \n\t\t\t\t\tleftRight = Side.LEFT;\n\t\t\t\t\tif (bottomSite.y > topSite.y) {\n\t\t\t\t\t\ttempSite = bottomSite;\n\t\t\t\t\t\tbottomSite = topSite;\n\t\t\t\t\t\ttopSite = tempSite;\n\t\t\t\t\t\tleftRight = Side.RIGHT;\n\t\t\t\t\t}\n\t\t\t\t\tedge = Edge.CreateBisectingEdge (bottomSite, topSite);\n\t\t\t\t\t_edges.Add (edge);\n\t\t\t\t\tbisector = Halfedge.Create (edge, leftRight);\n\t\t\t\t\thalfEdges.Add (bisector);\n\t\t\t\t\tedgeList.Insert (llbnd, bisector);\n\t\t\t\t\tedge.SetVertex (SideHelper.Other (leftRight), v);\n\t\t\t\t\tif ((vertex = Vertex.Intersect (llbnd, bisector)) != null) {\n\t\t\t\t\t\tvertices.Add (vertex);\n\t\t\t\t\t\theap.Remove (llbnd);\n\t\t\t\t\t\tllbnd.vertex = vertex;\n\t\t\t\t\t\tllbnd.ystar = vertex.y + bottomSite.Dist (vertex);\n\t\t\t\t\t\theap.Insert (llbnd);\n\t\t\t\t\t}\n\t\t\t\t\tif ((vertex = Vertex.Intersect (bisector, rrbnd)) != null) {\n\t\t\t\t\t\tvertices.Add (vertex);\n\t\t\t\t\t\tbisector.vertex = vertex;\n\t\t\t\t\t\tbisector.ystar = vertex.y + bottomSite.Dist (vertex);\n\t\t\t\t\t\theap.Insert (bisector);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\t\n\t\t\t// heap should be empty now\n\t\t\theap.Dispose ();\n\t\t\tedgeList.Dispose ();\n\t\t\t\n\t\t\tfor (int hIndex = 0; hIndex<halfEdges.Count; hIndex++) {\n\t\t\t\tHalfedge halfEdge = halfEdges [hIndex];\n\t\t\t\thalfEdge.ReallyDispose ();\n\t\t\t}\n\t\t\thalfEdges.Clear ();\n\t\t\t\n\t\t\t// we need the vertices to clip the edges\n\t\t\tfor (int eIndex = 0; eIndex<_edges.Count; eIndex++) {\n\t\t\t\tedge = _edges [eIndex];\n\t\t\t\tedge.ClipVertices (_plotBounds);\n\t\t\t}\n\t\t\t// but we don't actually ever use them again!\n\t\t\tfor (int vIndex = 0; vIndex<vertices.Count; vIndex++) {\n\t\t\t\tvertex = vertices [vIndex];\n\t\t\t\tvertex.Dispose ();\n\t\t\t}\n\t\t\tvertices.Clear ();\n\t\t}\n\n\t\tprivate Site FortunesAlgorithm_leftRegion (Halfedge he)\n\t\t{\n\t\t\tEdge edge = he.edge;\n\t\t\tif (edge == null) {\n\t\t\t\treturn fortunesAlgorithm_bottomMostSite;\n\t\t\t}\n\t\t\treturn edge.Site ((Side)he.leftRight);\n\t\t}\n\t\t\n\t\tprivate Site FortunesAlgorithm_rightRegion (Halfedge he)\n\t\t{\n\t\t\tEdge edge = he.edge;\n\t\t\tif (edge == null) {\n\t\t\t\treturn fortunesAlgorithm_bottomMostSite;\n\t\t\t}\n\t\t\treturn edge.Site (SideHelper.Other ((Side)he.leftRight));\n\t\t}\n\n\t\tpublic static int CompareByYThenX (Site s1, Site s2)\n\t\t{\n\t\t\tif (s1.y < s2.y)\n\t\t\t\treturn -1;\n\t\t\tif (s1.y > s2.y)\n\t\t\t\treturn 1;\n\t\t\tif (s1.x < s2.x)\n\t\t\t\treturn -1;\n\t\t\tif (s1.x > s2.x)\n\t\t\t\treturn 1;\n\t\t\treturn 0;\n\t\t}\n\n\t\tpublic static int CompareByYThenX (Site s1, Vector2 s2)\n\t\t{\n\t\t\tif (s1.y < s2.y)\n\t\t\t\treturn -1;\n\t\t\tif (s1.y > s2.y)\n\t\t\t\treturn 1;\n\t\t\tif (s1.x < s2.x)\n\t\t\t\treturn -1;\n\t\t\tif (s1.x > s2.x)\n\t\t\t\treturn 1;\n\t\t\treturn 0;\n\t\t}\n\n\t}\n}"
  },
  {
    "path": "demo/Assets/Unity-delaunay/Delaunay/Voronoi.cs.meta",
    "content": "fileFormatVersion: 2\nguid: 8a659b037ca774ad4b255ac68dbe65ae\nMonoImporter:\n  serializedVersion: 2\n  defaultReferences: []\n  executionOrder: 0\n  icon: {instanceID: 0}\n  userData: \n"
  },
  {
    "path": "demo/Assets/Unity-delaunay/Delaunay.meta",
    "content": "fileFormatVersion: 2\nguid: 7ea91cd8b2a424a0f97e63013b752cdc\nfolderAsset: yes\nDefaultImporter:\n  userData: \n"
  },
  {
    "path": "demo/Assets/Unity-delaunay/Plane Material.mat",
    "content": "%YAML 1.1\n%TAG !u! tag:unity3d.com,2011:\n--- !u!21 &2100000\nMaterial:\n  serializedVersion: 3\n  m_ObjectHideFlags: 0\n  m_PrefabParentObject: {fileID: 0}\n  m_PrefabInternal: {fileID: 0}\n  m_Name: Plane Material\n  m_Shader: {fileID: 7, guid: 0000000000000000f000000000000000, type: 0}\n  m_ShaderKeywords: []\n  m_CustomRenderQueue: -1\n  m_SavedProperties:\n    serializedVersion: 2\n    m_TexEnvs:\n      data:\n        first:\n          name: _MainTex\n        second:\n          m_Texture: {fileID: 0}\n          m_Scale: {x: 1, y: 1}\n          m_Offset: {x: 0, y: 0}\n      data:\n        first:\n          name: _Illum\n        second:\n          m_Texture: {fileID: 0}\n          m_Scale: {x: 1, y: 1}\n          m_Offset: {x: 0, y: 0}\n    m_Floats:\n      data:\n        first:\n          name: _EmissionLM\n        second: 0\n    m_Colors:\n      data:\n        first:\n          name: _Color\n        second: {r: 1, g: 1, b: 1, a: 1}\n"
  },
  {
    "path": "demo/Assets/Unity-delaunay/Plane Material.mat.meta",
    "content": "fileFormatVersion: 2\nguid: 361fa52b5561d434baaff15f2fe36f3d\nNativeFormatImporter:\n  userData: \n"
  },
  {
    "path": "demo/Assets/Unity-delaunay/geom/Circle.cs",
    "content": "using UnityEngine;\nusing System;\n\nnamespace Delaunay\n{\t\n\tnamespace Geo\n\t{\n\t\tpublic sealed class Circle\n\t\t{\n\t\t\tpublic Vector2 center;\n\t\t\tpublic float radius;\n\t\t\n\t\t\tpublic Circle (float centerX, float centerY, float radius)\n\t\t\t{\n\t\t\t\tthis.center = new Vector2 (centerX, centerY);\n\t\t\t\tthis.radius = radius;\n\t\t\t}\n\t\t\n\t\t\tpublic override string ToString ()\n\t\t\t{\n\t\t\t\treturn \"Circle (center: \" + center.ToString () + \"; radius: \" + radius.ToString () + \")\";\n\t\t\t}\n\n\t\t}\n\t}\n}"
  },
  {
    "path": "demo/Assets/Unity-delaunay/geom/Circle.cs.meta",
    "content": "fileFormatVersion: 2\nguid: e5300884d68b94e1c958b6328944dcca\nMonoImporter:\n  serializedVersion: 2\n  defaultReferences: []\n  executionOrder: 0\n  icon: {instanceID: 0}\n  userData: \n"
  },
  {
    "path": "demo/Assets/Unity-delaunay/geom/LineSegment.cs",
    "content": "using UnityEngine;\nusing System;\n\nnamespace Delaunay\n{\n\tnamespace Geo\n\t{\n\t\tpublic sealed class LineSegment\n\t\t{\n\t\t\tpublic static int CompareLengths_MAX (LineSegment segment0, LineSegment segment1)\n\t\t\t{\n\t\t\t\tfloat length0 = Vector2.Distance ((Vector2)segment0.p0, (Vector2)segment0.p1);\n\t\t\t\tfloat length1 = Vector2.Distance ((Vector2)segment1.p0, (Vector2)segment1.p1);\n\t\t\t\tif (length0 < length1) {\n\t\t\t\t\treturn 1;\n\t\t\t\t}\n\t\t\t\tif (length0 > length1) {\n\t\t\t\t\treturn -1;\n\t\t\t\t}\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t\n\t\t\tpublic static int CompareLengths (LineSegment edge0, LineSegment edge1)\n\t\t\t{\n\t\t\t\treturn - CompareLengths_MAX (edge0, edge1);\n\t\t\t}\n\n\t\t\tpublic Nullable<Vector2> p0;\n\t\t\tpublic Nullable<Vector2> p1;\n\t\t\n\t\t\tpublic LineSegment (Nullable<Vector2> p0, Nullable<Vector2> p1)\n\t\t\t{\n\t\t\t\tthis.p0 = p0;\n\t\t\t\tthis.p1 = p1;\n\t\t\t}\n\t\t\n\t\t}\n\t}\n}"
  },
  {
    "path": "demo/Assets/Unity-delaunay/geom/LineSegment.cs.meta",
    "content": "fileFormatVersion: 2\nguid: 76312350a2abb4fa9a9926fc7da2287d\nMonoImporter:\n  serializedVersion: 2\n  defaultReferences: []\n  executionOrder: 0\n  icon: {instanceID: 0}\n  userData: \n"
  },
  {
    "path": "demo/Assets/Unity-delaunay/geom/Polygon.cs",
    "content": "using UnityEngine;\nusing System.Collections.Generic;\n\nnamespace Delaunay\n{\n\tnamespace Geo\n\t{\n\t\tpublic sealed class Polygon\n\t\t{\n\t\t\tprivate List<Vector2> _vertices;\n\n\t\t\tpublic Polygon (List<Vector2> vertices)\n\t\t\t{\n\t\t\t\t_vertices = vertices;\n\t\t\t}\n\n\t\t\tpublic float Area ()\n\t\t\t{\n\t\t\t\treturn Mathf.Abs (SignedDoubleArea () * 0.5f); // XXX: I'm a bit nervous about this; not sure what the * 0.5 is for, bithacking?\n\t\t\t}\n\n\t\t\tpublic Winding Winding ()\n\t\t\t{\n\t\t\t\tfloat signedDoubleArea = SignedDoubleArea ();\n\t\t\t\tif (signedDoubleArea < 0) {\n\t\t\t\t\treturn Geo.Winding.CLOCKWISE;\n\t\t\t\t}\n\t\t\t\tif (signedDoubleArea > 0) {\n\t\t\t\t\treturn Geo.Winding.COUNTERCLOCKWISE;\n\t\t\t\t}\n\t\t\t\treturn Geo.Winding.NONE;\n\t\t\t}\n\n\t\t\tprivate float SignedDoubleArea () // XXX: I'm a bit nervous about this because Actionscript represents everything as doubles, not floats\n\t\t\t{\n\t\t\t\tint index, nextIndex;\n\t\t\t\tint n = _vertices.Count;\n\t\t\t\tVector2 point, next;\n\t\t\t\tfloat signedDoubleArea = 0; // Losing lots of precision?\n\t\t\t\tfor (index = 0; index < n; ++index) {\n\t\t\t\t\tnextIndex = (index + 1) % n;\n\t\t\t\t\tpoint = _vertices [index];\n\t\t\t\t\tnext = _vertices [nextIndex];\n\t\t\t\t\tsignedDoubleArea += point.x * next.y - next.x * point.y;\n\t\t\t\t}\n\t\t\t\treturn signedDoubleArea;\n\t\t\t}\n\t\t}\n\t}\n}"
  },
  {
    "path": "demo/Assets/Unity-delaunay/geom/Polygon.cs.meta",
    "content": "fileFormatVersion: 2\nguid: e59bb833c9cf045e992b44a5e23837cb\nMonoImporter:\n  serializedVersion: 2\n  defaultReferences: []\n  executionOrder: 0\n  icon: {instanceID: 0}\n  userData: \n"
  },
  {
    "path": "demo/Assets/Unity-delaunay/geom/Winding.cs",
    "content": "namespace Delaunay\n{\n\tnamespace Geo {\n\t\tpublic enum Winding\n\t\t{\n\t\t\tNONE = 0, CLOCKWISE, COUNTERCLOCKWISE\n\t\t}\t\t\n\t}\n}"
  },
  {
    "path": "demo/Assets/Unity-delaunay/geom/Winding.cs.meta",
    "content": "fileFormatVersion: 2\nguid: 1a38f1425b42547898d3b2ef6c865e05\nMonoImporter:\n  serializedVersion: 2\n  defaultReferences: []\n  executionOrder: 0\n  icon: {instanceID: 0}\n  userData: \n"
  },
  {
    "path": "demo/Assets/Unity-delaunay/geom.meta",
    "content": "fileFormatVersion: 2\nguid: 2ee5f0dcc71544e1dade82ac72f7fc3d\nfolderAsset: yes\nDefaultImporter:\n  userData: \n"
  },
  {
    "path": "demo/Assets/Unity-delaunay/utils/IDisposable.cs",
    "content": "namespace Delaunay\n{\n\tnamespace Utils\n\t{\n\t\tpublic interface IDisposable\n\t\t{\n\t\t\tvoid Dispose ();\n\t\t}\n\t}\n}"
  },
  {
    "path": "demo/Assets/Unity-delaunay/utils/IDisposable.cs.meta",
    "content": "fileFormatVersion: 2\nguid: 7cb01ead474dc485fa87ef0e202dcc6d\nMonoImporter:\n  serializedVersion: 2\n  defaultReferences: []\n  executionOrder: 0\n  icon: {instanceID: 0}\n  userData: \n"
  },
  {
    "path": "demo/Assets/Unity-delaunay/utils.meta",
    "content": "fileFormatVersion: 2\nguid: 6505f93572a1d41a38b2f1aeee65897b\nfolderAsset: yes\nDefaultImporter:\n  userData: \n"
  },
  {
    "path": "demo/Assets/Unity-delaunay.meta",
    "content": "fileFormatVersion: 2\nguid: adf918391394e4918943cbf0bb3dd6ea\nfolderAsset: yes\nDefaultImporter:\n  userData: \n"
  },
  {
    "path": "demo/ProjectSettings/AudioManager.asset",
    "content": "%YAML 1.1\n%TAG !u! tag:unity3d.com,2011:\n--- !u!11 &1\nAudioManager:\n  m_ObjectHideFlags: 0\n  m_Volume: 1\n  Rolloff Scale: 1\n  m_SpeedOfSound: 347\n  Doppler Factor: 1\n  Default Speaker Mode: 2\n  m_DSPBufferSize: 0\n  m_DisableAudio: 0\n"
  },
  {
    "path": "demo/ProjectSettings/ClusterInputManager.asset",
    "content": "%YAML 1.1\n%TAG !u! tag:unity3d.com,2011:\n--- !u!236 &1\nClusterInputManager:\n  m_ObjectHideFlags: 0\n  m_Inputs: []\n"
  },
  {
    "path": "demo/ProjectSettings/DynamicsManager.asset",
    "content": "%YAML 1.1\n%TAG !u! tag:unity3d.com,2011:\n--- !u!55 &1\nPhysicsManager:\n  m_ObjectHideFlags: 0\n  m_Gravity: {x: 0, y: -9.81000042, z: 0}\n  m_DefaultMaterial: {fileID: 0}\n  m_BounceThreshold: 2\n  m_SleepVelocity: .150000006\n  m_SleepAngularVelocity: .140000001\n  m_MaxAngularVelocity: 7\n  m_MinPenetrationForPenalty: .00999999978\n  m_SolverIterationCount: 6\n  m_RaycastsHitTriggers: 1\n  m_LayerCollisionMatrix: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n"
  },
  {
    "path": "demo/ProjectSettings/EditorBuildSettings.asset",
    "content": "%YAML 1.1\n%TAG !u! tag:unity3d.com,2011:\n--- !u!1045 &1\nEditorBuildSettings:\n  m_ObjectHideFlags: 0\n  serializedVersion: 2\n  m_Scenes: []\n"
  },
  {
    "path": "demo/ProjectSettings/EditorSettings.asset",
    "content": "%YAML 1.1\n%TAG !u! tag:unity3d.com,2011:\n--- !u!159 &1\nEditorSettings:\n  m_ObjectHideFlags: 0\n  serializedVersion: 3\n  m_ExternalVersionControlSupport: Hidden Meta Files\n  m_SerializationMode: 2\n  m_WebSecurityEmulationEnabled: 0\n  m_WebSecurityEmulationHostUrl: http://www.mydomain.com/mygame.unity3d\n  m_DefaultBehaviorMode: 1\n  m_SpritePackerMode: 0\n"
  },
  {
    "path": "demo/ProjectSettings/GraphicsSettings.asset",
    "content": "%YAML 1.1\n%TAG !u! tag:unity3d.com,2011:\n--- !u!30 &1\nGraphicsSettings:\n  m_ObjectHideFlags: 0\n  serializedVersion: 12\n  m_Deferred:\n    m_Mode: 1\n    m_Shader: {fileID: 69, guid: 0000000000000000f000000000000000, type: 0}\n  m_DeferredReflections:\n    m_Mode: 1\n    m_Shader: {fileID: 74, guid: 0000000000000000f000000000000000, type: 0}\n  m_ScreenSpaceShadows:\n    m_Mode: 1\n    m_Shader: {fileID: 64, guid: 0000000000000000f000000000000000, type: 0}\n  m_LegacyDeferred:\n    m_Mode: 1\n    m_Shader: {fileID: 63, guid: 0000000000000000f000000000000000, type: 0}\n  m_DepthNormals:\n    m_Mode: 1\n    m_Shader: {fileID: 62, guid: 0000000000000000f000000000000000, type: 0}\n  m_MotionVectors:\n    m_Mode: 1\n    m_Shader: {fileID: 75, guid: 0000000000000000f000000000000000, type: 0}\n  m_LightHalo:\n    m_Mode: 1\n    m_Shader: {fileID: 105, guid: 0000000000000000f000000000000000, type: 0}\n  m_LensFlare:\n    m_Mode: 1\n    m_Shader: {fileID: 102, guid: 0000000000000000f000000000000000, type: 0}\n  m_AlwaysIncludedShaders:\n  - {fileID: 7, guid: 0000000000000000f000000000000000, type: 0}\n  - {fileID: 15104, guid: 0000000000000000f000000000000000, type: 0}\n  - {fileID: 15105, guid: 0000000000000000f000000000000000, type: 0}\n  - {fileID: 15106, guid: 0000000000000000f000000000000000, type: 0}\n  - {fileID: 10753, guid: 0000000000000000f000000000000000, type: 0}\n  - {fileID: 10770, guid: 0000000000000000f000000000000000, type: 0}\n  m_PreloadedShaders: []\n  m_SpritesDefaultMaterial: {fileID: 10754, guid: 0000000000000000f000000000000000,\n    type: 0}\n  m_CustomRenderPipeline: {fileID: 0}\n  m_TransparencySortMode: 0\n  m_TransparencySortAxis: {x: 0, y: 0, z: 1}\n  m_DefaultRenderingPath: 1\n  m_DefaultMobileRenderingPath: 1\n  m_TierSettings: []\n  m_LightmapStripping: 0\n  m_FogStripping: 0\n  m_InstancingStripping: 0\n  m_LightmapKeepPlain: 1\n  m_LightmapKeepDirCombined: 1\n  m_LightmapKeepDynamicPlain: 1\n  m_LightmapKeepDynamicDirCombined: 1\n  m_LightmapKeepShadowMask: 1\n  m_LightmapKeepSubtractive: 1\n  m_FogKeepLinear: 1\n  m_FogKeepExp: 1\n  m_FogKeepExp2: 1\n  m_AlbedoSwatchInfos: []\n  m_LightsUseLinearIntensity: 0\n  m_LightsUseColorTemperature: 0\n"
  },
  {
    "path": "demo/ProjectSettings/InputManager.asset",
    "content": "%YAML 1.1\n%TAG !u! tag:unity3d.com,2011:\n--- !u!13 &1\nInputManager:\n  m_ObjectHideFlags: 0\n  m_Axes:\n  - serializedVersion: 3\n    m_Name: Horizontal\n    descriptiveName: \n    descriptiveNegativeName: \n    negativeButton: left\n    positiveButton: right\n    altNegativeButton: a\n    altPositiveButton: d\n    gravity: 3\n    dead: .00100000005\n    sensitivity: 3\n    snap: 1\n    invert: 0\n    type: 0\n    axis: 0\n    joyNum: 0\n  - serializedVersion: 3\n    m_Name: Vertical\n    descriptiveName: \n    descriptiveNegativeName: \n    negativeButton: down\n    positiveButton: up\n    altNegativeButton: s\n    altPositiveButton: w\n    gravity: 3\n    dead: .00100000005\n    sensitivity: 3\n    snap: 1\n    invert: 0\n    type: 0\n    axis: 0\n    joyNum: 0\n  - serializedVersion: 3\n    m_Name: Fire1\n    descriptiveName: \n    descriptiveNegativeName: \n    negativeButton: \n    positiveButton: left ctrl\n    altNegativeButton: \n    altPositiveButton: mouse 0\n    gravity: 1000\n    dead: .00100000005\n    sensitivity: 1000\n    snap: 0\n    invert: 0\n    type: 0\n    axis: 0\n    joyNum: 0\n  - serializedVersion: 3\n    m_Name: Fire2\n    descriptiveName: \n    descriptiveNegativeName: \n    negativeButton: \n    positiveButton: left alt\n    altNegativeButton: \n    altPositiveButton: mouse 1\n    gravity: 1000\n    dead: .00100000005\n    sensitivity: 1000\n    snap: 0\n    invert: 0\n    type: 0\n    axis: 0\n    joyNum: 0\n  - serializedVersion: 3\n    m_Name: Fire3\n    descriptiveName: \n    descriptiveNegativeName: \n    negativeButton: \n    positiveButton: left cmd\n    altNegativeButton: \n    altPositiveButton: mouse 2\n    gravity: 1000\n    dead: .00100000005\n    sensitivity: 1000\n    snap: 0\n    invert: 0\n    type: 0\n    axis: 0\n    joyNum: 0\n  - serializedVersion: 3\n    m_Name: Jump\n    descriptiveName: \n    descriptiveNegativeName: \n    negativeButton: \n    positiveButton: space\n    altNegativeButton: \n    altPositiveButton: \n    gravity: 1000\n    dead: .00100000005\n    sensitivity: 1000\n    snap: 0\n    invert: 0\n    type: 0\n    axis: 0\n    joyNum: 0\n  - serializedVersion: 3\n    m_Name: Mouse X\n    descriptiveName: \n    descriptiveNegativeName: \n    negativeButton: \n    positiveButton: \n    altNegativeButton: \n    altPositiveButton: \n    gravity: 0\n    dead: 0\n    sensitivity: .100000001\n    snap: 0\n    invert: 0\n    type: 1\n    axis: 0\n    joyNum: 0\n  - serializedVersion: 3\n    m_Name: Mouse Y\n    descriptiveName: \n    descriptiveNegativeName: \n    negativeButton: \n    positiveButton: \n    altNegativeButton: \n    altPositiveButton: \n    gravity: 0\n    dead: 0\n    sensitivity: .100000001\n    snap: 0\n    invert: 0\n    type: 1\n    axis: 1\n    joyNum: 0\n  - serializedVersion: 3\n    m_Name: Mouse ScrollWheel\n    descriptiveName: \n    descriptiveNegativeName: \n    negativeButton: \n    positiveButton: \n    altNegativeButton: \n    altPositiveButton: \n    gravity: 0\n    dead: 0\n    sensitivity: .100000001\n    snap: 0\n    invert: 0\n    type: 1\n    axis: 2\n    joyNum: 0\n  - serializedVersion: 3\n    m_Name: Horizontal\n    descriptiveName: \n    descriptiveNegativeName: \n    negativeButton: \n    positiveButton: \n    altNegativeButton: \n    altPositiveButton: \n    gravity: 0\n    dead: .189999998\n    sensitivity: 1\n    snap: 0\n    invert: 0\n    type: 2\n    axis: 0\n    joyNum: 0\n  - serializedVersion: 3\n    m_Name: Vertical\n    descriptiveName: \n    descriptiveNegativeName: \n    negativeButton: \n    positiveButton: \n    altNegativeButton: \n    altPositiveButton: \n    gravity: 0\n    dead: .189999998\n    sensitivity: 1\n    snap: 0\n    invert: 1\n    type: 2\n    axis: 1\n    joyNum: 0\n  - serializedVersion: 3\n    m_Name: Fire1\n    descriptiveName: \n    descriptiveNegativeName: \n    negativeButton: \n    positiveButton: joystick button 0\n    altNegativeButton: \n    altPositiveButton: \n    gravity: 1000\n    dead: .00100000005\n    sensitivity: 1000\n    snap: 0\n    invert: 0\n    type: 0\n    axis: 0\n    joyNum: 0\n  - serializedVersion: 3\n    m_Name: Fire2\n    descriptiveName: \n    descriptiveNegativeName: \n    negativeButton: \n    positiveButton: joystick button 1\n    altNegativeButton: \n    altPositiveButton: \n    gravity: 1000\n    dead: .00100000005\n    sensitivity: 1000\n    snap: 0\n    invert: 0\n    type: 0\n    axis: 0\n    joyNum: 0\n  - serializedVersion: 3\n    m_Name: Fire3\n    descriptiveName: \n    descriptiveNegativeName: \n    negativeButton: \n    positiveButton: joystick button 2\n    altNegativeButton: \n    altPositiveButton: \n    gravity: 1000\n    dead: .00100000005\n    sensitivity: 1000\n    snap: 0\n    invert: 0\n    type: 0\n    axis: 0\n    joyNum: 0\n  - serializedVersion: 3\n    m_Name: Jump\n    descriptiveName: \n    descriptiveNegativeName: \n    negativeButton: \n    positiveButton: joystick button 3\n    altNegativeButton: \n    altPositiveButton: \n    gravity: 1000\n    dead: .00100000005\n    sensitivity: 1000\n    snap: 0\n    invert: 0\n    type: 0\n    axis: 0\n    joyNum: 0\n"
  },
  {
    "path": "demo/ProjectSettings/NavMeshAreas.asset",
    "content": "%YAML 1.1\n%TAG !u! tag:unity3d.com,2011:\n--- !u!126 &1\nNavMeshLayers:\n  m_ObjectHideFlags: 0\n  Built-in Layer 0:\n    name: Default\n    cost: 1\n    editType: 2\n  Built-in Layer 1:\n    name: Not Walkable\n    cost: 1\n    editType: 0\n  Built-in Layer 2:\n    name: Jump\n    cost: 2\n    editType: 2\n  User Layer 0:\n    name: \n    cost: 1\n    editType: 3\n  User Layer 1:\n    name: \n    cost: 1\n    editType: 3\n  User Layer 2:\n    name: \n    cost: 1\n    editType: 3\n  User Layer 3:\n    name: \n    cost: 1\n    editType: 3\n  User Layer 4:\n    name: \n    cost: 1\n    editType: 3\n  User Layer 5:\n    name: \n    cost: 1\n    editType: 3\n  User Layer 6:\n    name: \n    cost: 1\n    editType: 3\n  User Layer 7:\n    name: \n    cost: 1\n    editType: 3\n  User Layer 8:\n    name: \n    cost: 1\n    editType: 3\n  User Layer 9:\n    name: \n    cost: 1\n    editType: 3\n  User Layer 10:\n    name: \n    cost: 1\n    editType: 3\n  User Layer 11:\n    name: \n    cost: 1\n    editType: 3\n  User Layer 12:\n    name: \n    cost: 1\n    editType: 3\n  User Layer 13:\n    name: \n    cost: 1\n    editType: 3\n  User Layer 14:\n    name: \n    cost: 1\n    editType: 3\n  User Layer 15:\n    name: \n    cost: 1\n    editType: 3\n  User Layer 16:\n    name: \n    cost: 1\n    editType: 3\n  User Layer 17:\n    name: \n    cost: 1\n    editType: 3\n  User Layer 18:\n    name: \n    cost: 1\n    editType: 3\n  User Layer 19:\n    name: \n    cost: 1\n    editType: 3\n  User Layer 20:\n    name: \n    cost: 1\n    editType: 3\n  User Layer 21:\n    name: \n    cost: 1\n    editType: 3\n  User Layer 22:\n    name: \n    cost: 1\n    editType: 3\n  User Layer 23:\n    name: \n    cost: 1\n    editType: 3\n  User Layer 24:\n    name: \n    cost: 1\n    editType: 3\n  User Layer 25:\n    name: \n    cost: 1\n    editType: 3\n  User Layer 26:\n    name: \n    cost: 1\n    editType: 3\n  User Layer 27:\n    name: \n    cost: 1\n    editType: 3\n  User Layer 28:\n    name: \n    cost: 1\n    editType: 3\n"
  },
  {
    "path": "demo/ProjectSettings/NavMeshLayers.asset",
    "content": "%YAML 1.1\n%TAG !u! tag:unity3d.com,2011:\n--- !u!126 &1\nNavMeshLayers:\n  m_ObjectHideFlags: 0\n  Built-in Layer 0:\n    name: Default\n    cost: 1\n    editType: 2\n  Built-in Layer 1:\n    name: Not Walkable\n    cost: 1\n    editType: 0\n  Built-in Layer 2:\n    name: Jump\n    cost: 2\n    editType: 2\n  User Layer 0:\n    name: \n    cost: 1\n    editType: 3\n  User Layer 1:\n    name: \n    cost: 1\n    editType: 3\n  User Layer 2:\n    name: \n    cost: 1\n    editType: 3\n  User Layer 3:\n    name: \n    cost: 1\n    editType: 3\n  User Layer 4:\n    name: \n    cost: 1\n    editType: 3\n  User Layer 5:\n    name: \n    cost: 1\n    editType: 3\n  User Layer 6:\n    name: \n    cost: 1\n    editType: 3\n  User Layer 7:\n    name: \n    cost: 1\n    editType: 3\n  User Layer 8:\n    name: \n    cost: 1\n    editType: 3\n  User Layer 9:\n    name: \n    cost: 1\n    editType: 3\n  User Layer 10:\n    name: \n    cost: 1\n    editType: 3\n  User Layer 11:\n    name: \n    cost: 1\n    editType: 3\n  User Layer 12:\n    name: \n    cost: 1\n    editType: 3\n  User Layer 13:\n    name: \n    cost: 1\n    editType: 3\n  User Layer 14:\n    name: \n    cost: 1\n    editType: 3\n  User Layer 15:\n    name: \n    cost: 1\n    editType: 3\n  User Layer 16:\n    name: \n    cost: 1\n    editType: 3\n  User Layer 17:\n    name: \n    cost: 1\n    editType: 3\n  User Layer 18:\n    name: \n    cost: 1\n    editType: 3\n  User Layer 19:\n    name: \n    cost: 1\n    editType: 3\n  User Layer 20:\n    name: \n    cost: 1\n    editType: 3\n  User Layer 21:\n    name: \n    cost: 1\n    editType: 3\n  User Layer 22:\n    name: \n    cost: 1\n    editType: 3\n  User Layer 23:\n    name: \n    cost: 1\n    editType: 3\n  User Layer 24:\n    name: \n    cost: 1\n    editType: 3\n  User Layer 25:\n    name: \n    cost: 1\n    editType: 3\n  User Layer 26:\n    name: \n    cost: 1\n    editType: 3\n  User Layer 27:\n    name: \n    cost: 1\n    editType: 3\n  User Layer 28:\n    name: \n    cost: 1\n    editType: 3\n"
  },
  {
    "path": "demo/ProjectSettings/NetworkManager.asset",
    "content": "%YAML 1.1\n%TAG !u! tag:unity3d.com,2011:\n--- !u!149 &1\nNetworkManager:\n  m_ObjectHideFlags: 0\n  m_DebugLevel: 0\n  m_Sendrate: 15\n  m_AssetToPrefab: {}\n"
  },
  {
    "path": "demo/ProjectSettings/Physics2DSettings.asset",
    "content": "%YAML 1.1\n%TAG !u! tag:unity3d.com,2011:\n--- !u!19 &1\nPhysics2DSettings:\n  m_ObjectHideFlags: 0\n  m_Gravity: {x: 0, y: -9.81000042}\n  m_DefaultMaterial: {fileID: 0}\n  m_VelocityIterations: 8\n  m_PositionIterations: 3\n  m_VelocityThreshold: 1\n  m_MaxLinearCorrection: .200000003\n  m_MaxAngularCorrection: 8\n  m_MaxTranslationSpeed: 100\n  m_MaxRotationSpeed: 360\n  m_BaumgarteScale: .200000003\n  m_BaumgarteTimeOfImpactScale: .75\n  m_TimeToSleep: .5\n  m_LinearSleepTolerance: .00999999978\n  m_AngularSleepTolerance: 2\n  m_RaycastsHitTriggers: 1\n  m_LayerCollisionMatrix: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n"
  },
  {
    "path": "demo/ProjectSettings/ProjectSettings.asset",
    "content": "%YAML 1.1\n%TAG !u! tag:unity3d.com,2011:\n--- !u!129 &1\nPlayerSettings:\n  m_ObjectHideFlags: 0\n  serializedVersion: 12\n  productGUID: 0af961f893b0243a1953a65081cbafc9\n  AndroidProfiler: 0\n  defaultScreenOrientation: 0\n  targetDevice: 2\n  useOnDemandResources: 0\n  accelerometerFrequency: 60\n  companyName: DefaultCompany\n  productName: demo\n  defaultCursor: {fileID: 0}\n  cursorHotspot: {x: 0, y: 0}\n  m_SplashScreenBackgroundColor: {r: 0.13725491, g: 0.12156863, b: 0.1254902, a: 1}\n  m_ShowUnitySplashScreen: 1\n  m_ShowUnitySplashLogo: 1\n  m_SplashScreenOverlayOpacity: 1\n  m_SplashScreenAnimation: 1\n  m_SplashScreenLogoStyle: 1\n  m_SplashScreenDrawMode: 0\n  m_SplashScreenBackgroundAnimationZoom: 1\n  m_SplashScreenLogoAnimationZoom: 1\n  m_SplashScreenBackgroundLandscapeAspect: 1\n  m_SplashScreenBackgroundPortraitAspect: 1\n  m_SplashScreenBackgroundLandscapeUvs:\n    serializedVersion: 2\n    x: 0\n    y: 0\n    width: 1\n    height: 1\n  m_SplashScreenBackgroundPortraitUvs:\n    serializedVersion: 2\n    x: 0\n    y: 0\n    width: 1\n    height: 1\n  m_SplashScreenLogos: []\n  m_SplashScreenBackgroundLandscape: {fileID: 0}\n  m_SplashScreenBackgroundPortrait: {fileID: 0}\n  m_VirtualRealitySplashScreen: {fileID: 0}\n  m_HolographicTrackingLossScreen: {fileID: 0}\n  defaultScreenWidth: 1024\n  defaultScreenHeight: 768\n  defaultScreenWidthWeb: 960\n  defaultScreenHeightWeb: 600\n  m_StereoRenderingPath: 0\n  m_ActiveColorSpace: 0\n  m_MTRendering: 1\n  m_MobileMTRendering: 0\n  m_StackTraceTypes: 010000000100000001000000010000000100000001000000\n  iosShowActivityIndicatorOnLoading: -1\n  androidShowActivityIndicatorOnLoading: -1\n  tizenShowActivityIndicatorOnLoading: -1\n  iosAppInBackgroundBehavior: 0\n  displayResolutionDialog: 1\n  iosAllowHTTPDownload: 1\n  allowedAutorotateToPortrait: 1\n  allowedAutorotateToPortraitUpsideDown: 1\n  allowedAutorotateToLandscapeRight: 1\n  allowedAutorotateToLandscapeLeft: 1\n  useOSAutorotation: 1\n  use32BitDisplayBuffer: 1\n  disableDepthAndStencilBuffers: 0\n  defaultIsFullScreen: 1\n  defaultIsNativeResolution: 1\n  runInBackground: 1\n  captureSingleScreen: 0\n  muteOtherAudioSources: 0\n  Prepare IOS For Recording: 0\n  Force IOS Speakers When Recording: 0\n  submitAnalytics: 1\n  usePlayerLog: 1\n  bakeCollisionMeshes: 0\n  forceSingleInstance: 0\n  resizableWindow: 0\n  useMacAppStoreValidation: 0\n  macAppStoreCategory: public.app-category.games\n  gpuSkinning: 0\n  graphicsJobs: 0\n  xboxPIXTextureCapture: 0\n  xboxEnableAvatar: 0\n  xboxEnableKinect: 0\n  xboxEnableKinectAutoTracking: 0\n  xboxEnableFitness: 0\n  visibleInBackground: 0\n  allowFullscreenSwitch: 1\n  graphicsJobMode: 0\n  macFullscreenMode: 2\n  d3d9FullscreenMode: 1\n  d3d11FullscreenMode: 1\n  xboxSpeechDB: 0\n  xboxEnableHeadOrientation: 0\n  xboxEnableGuest: 0\n  xboxEnablePIXSampling: 0\n  n3dsDisableStereoscopicView: 0\n  n3dsEnableSharedListOpt: 1\n  n3dsEnableVSync: 0\n  ignoreAlphaClear: 0\n  xboxOneResolution: 0\n  xboxOneMonoLoggingLevel: 0\n  xboxOneLoggingLevel: 1\n  xboxOneDisableEsram: 0\n  videoMemoryForVertexBuffers: 0\n  psp2PowerMode: 0\n  psp2AcquireBGM: 1\n  wiiUTVResolution: 0\n  wiiUGamePadMSAA: 1\n  wiiUSupportsNunchuk: 0\n  wiiUSupportsClassicController: 0\n  wiiUSupportsBalanceBoard: 0\n  wiiUSupportsMotionPlus: 0\n  wiiUSupportsProController: 0\n  wiiUAllowScreenCapture: 1\n  wiiUControllerCount: 0\n  m_SupportedAspectRatios:\n    4:3: 1\n    5:4: 1\n    16:10: 1\n    16:9: 1\n    Others: 1\n  bundleVersion: 1.0\n  preloadedAssets: []\n  metroInputSource: 0\n  m_HolographicPauseOnTrackingLoss: 1\n  xboxOneDisableKinectGpuReservation: 0\n  xboxOneEnable7thCore: 0\n  vrSettings:\n    cardboard:\n      depthFormat: 0\n      enableTransitionView: 0\n    daydream:\n      depthFormat: 0\n      useSustainedPerformanceMode: 0\n    hololens:\n      depthFormat: 1\n  protectGraphicsMemory: 0\n  useHDRDisplay: 0\n  targetPixelDensity: 0\n  resolutionScalingMode: 0\n  applicationIdentifier:\n    Android: \n    Standalone: unity.DefaultCompany.demo\n    Tizen: \n    iOS: com.Company.ProductName\n    tvOS: \n  buildNumber:\n    iOS: \n  AndroidBundleVersionCode: 1\n  AndroidMinSdkVersion: 16\n  AndroidTargetSdkVersion: 0\n  AndroidPreferredInstallLocation: 1\n  aotOptions: \n  stripEngineCode: 1\n  iPhoneStrippingLevel: 0\n  iPhoneScriptCallOptimization: 0\n  ForceInternetPermission: 0\n  ForceSDCardPermission: 0\n  CreateWallpaper: 0\n  APKExpansionFiles: 0\n  keepLoadedShadersAlive: 0\n  StripUnusedMeshComponents: 0\n  VertexChannelCompressionMask:\n    serializedVersion: 2\n    m_Bits: 238\n  iPhoneSdkVersion: 988\n  iOSTargetOSVersionString: \n  tvOSSdkVersion: 0\n  tvOSRequireExtendedGameController: 0\n  tvOSTargetOSVersionString: \n  uIPrerenderedIcon: 0\n  uIRequiresPersistentWiFi: 0\n  uIRequiresFullScreen: 1\n  uIStatusBarHidden: 1\n  uIExitOnSuspend: 0\n  uIStatusBarStyle: 0\n  iPhoneSplashScreen: {fileID: 0}\n  iPhoneHighResSplashScreen: {fileID: 0}\n  iPhoneTallHighResSplashScreen: {fileID: 0}\n  iPhone47inSplashScreen: {fileID: 0}\n  iPhone55inPortraitSplashScreen: {fileID: 0}\n  iPhone55inLandscapeSplashScreen: {fileID: 0}\n  iPadPortraitSplashScreen: {fileID: 0}\n  iPadHighResPortraitSplashScreen: {fileID: 0}\n  iPadLandscapeSplashScreen: {fileID: 0}\n  iPadHighResLandscapeSplashScreen: {fileID: 0}\n  appleTVSplashScreen: {fileID: 0}\n  tvOSSmallIconLayers: []\n  tvOSLargeIconLayers: []\n  tvOSTopShelfImageLayers: []\n  tvOSTopShelfImageWideLayers: []\n  iOSLaunchScreenType: 0\n  iOSLaunchScreenPortrait: {fileID: 0}\n  iOSLaunchScreenLandscape: {fileID: 0}\n  iOSLaunchScreenBackgroundColor:\n    serializedVersion: 2\n    rgba: 0\n  iOSLaunchScreenFillPct: 100\n  iOSLaunchScreenSize: 100\n  iOSLaunchScreenCustomXibPath: \n  iOSLaunchScreeniPadType: 0\n  iOSLaunchScreeniPadImage: {fileID: 0}\n  iOSLaunchScreeniPadBackgroundColor:\n    serializedVersion: 2\n    rgba: 0\n  iOSLaunchScreeniPadFillPct: 100\n  iOSLaunchScreeniPadSize: 100\n  iOSLaunchScreeniPadCustomXibPath: \n  iOSDeviceRequirements: []\n  iOSURLSchemes: []\n  iOSBackgroundModes: 0\n  iOSMetalForceHardShadows: 0\n  metalEditorSupport: 1\n  metalAPIValidation: 1\n  iOSRenderExtraFrameOnPause: 1\n  appleDeveloperTeamID: \n  iOSManualSigningProvisioningProfileID: \n  tvOSManualSigningProvisioningProfileID: \n  appleEnableAutomaticSigning: 0\n  AndroidTargetDevice: 0\n  AndroidSplashScreenScale: 0\n  androidSplashScreen: {fileID: 0}\n  AndroidKeystoreName: \n  AndroidKeyaliasName: \n  AndroidTVCompatibility: 1\n  AndroidIsGame: 1\n  androidEnableBanner: 1\n  m_AndroidBanners:\n  - width: 320\n    height: 180\n    banner: {fileID: 0}\n  androidGamepadSupportLevel: 0\n  resolutionDialogBanner: {fileID: 0}\n  m_BuildTargetIcons: []\n  m_BuildTargetBatching: []\n  m_BuildTargetGraphicsAPIs:\n  - m_BuildTarget: AndroidPlayer\n    m_APIs: 08000000\n    m_Automatic: 0\n  m_BuildTargetVRSettings: []\n  openGLRequireES31: 0\n  openGLRequireES31AEP: 0\n  webPlayerTemplate: APPLICATION:Default\n  m_TemplateCustomTags: {}\n  wiiUTitleID: 0005000011000000\n  wiiUGroupID: 00010000\n  wiiUCommonSaveSize: 4096\n  wiiUAccountSaveSize: 2048\n  wiiUOlvAccessKey: 0\n  wiiUTinCode: 0\n  wiiUJoinGameId: 0\n  wiiUJoinGameModeMask: 0000000000000000\n  wiiUCommonBossSize: 0\n  wiiUAccountBossSize: 0\n  wiiUAddOnUniqueIDs: []\n  wiiUMainThreadStackSize: 3072\n  wiiULoaderThreadStackSize: 1024\n  wiiUSystemHeapSize: 128\n  wiiUTVStartupScreen: {fileID: 0}\n  wiiUGamePadStartupScreen: {fileID: 0}\n  wiiUDrcBufferDisabled: 0\n  wiiUProfilerLibPath: \n  playModeTestRunnerEnabled: 0\n  actionOnDotNetUnhandledException: 1\n  enableInternalProfiler: 0\n  logObjCUncaughtExceptions: 1\n  enableCrashReportAPI: 0\n  cameraUsageDescription: \n  locationUsageDescription: \n  microphoneUsageDescription: \n  switchNetLibKey: \n  switchSocketMemoryPoolSize: 6144\n  switchSocketAllocatorPoolSize: 128\n  switchSocketConcurrencyLimit: 14\n  switchScreenResolutionBehavior: 2\n  switchUseCPUProfiler: 0\n  switchApplicationID: 0x01004b9000490000\n  switchNSODependencies: \n  switchTitleNames_0: \n  switchTitleNames_1: \n  switchTitleNames_2: \n  switchTitleNames_3: \n  switchTitleNames_4: \n  switchTitleNames_5: \n  switchTitleNames_6: \n  switchTitleNames_7: \n  switchTitleNames_8: \n  switchTitleNames_9: \n  switchTitleNames_10: \n  switchTitleNames_11: \n  switchPublisherNames_0: \n  switchPublisherNames_1: \n  switchPublisherNames_2: \n  switchPublisherNames_3: \n  switchPublisherNames_4: \n  switchPublisherNames_5: \n  switchPublisherNames_6: \n  switchPublisherNames_7: \n  switchPublisherNames_8: \n  switchPublisherNames_9: \n  switchPublisherNames_10: \n  switchPublisherNames_11: \n  switchIcons_0: {fileID: 0}\n  switchIcons_1: {fileID: 0}\n  switchIcons_2: {fileID: 0}\n  switchIcons_3: {fileID: 0}\n  switchIcons_4: {fileID: 0}\n  switchIcons_5: {fileID: 0}\n  switchIcons_6: {fileID: 0}\n  switchIcons_7: {fileID: 0}\n  switchIcons_8: {fileID: 0}\n  switchIcons_9: {fileID: 0}\n  switchIcons_10: {fileID: 0}\n  switchIcons_11: {fileID: 0}\n  switchSmallIcons_0: {fileID: 0}\n  switchSmallIcons_1: {fileID: 0}\n  switchSmallIcons_2: {fileID: 0}\n  switchSmallIcons_3: {fileID: 0}\n  switchSmallIcons_4: {fileID: 0}\n  switchSmallIcons_5: {fileID: 0}\n  switchSmallIcons_6: {fileID: 0}\n  switchSmallIcons_7: {fileID: 0}\n  switchSmallIcons_8: {fileID: 0}\n  switchSmallIcons_9: {fileID: 0}\n  switchSmallIcons_10: {fileID: 0}\n  switchSmallIcons_11: {fileID: 0}\n  switchManualHTML: \n  switchAccessibleURLs: \n  switchLegalInformation: \n  switchMainThreadStackSize: 1048576\n  switchPresenceGroupId: \n  switchLogoHandling: 0\n  switchReleaseVersion: 0\n  switchDisplayVersion: 1.0.0\n  switchStartupUserAccount: 0\n  switchTouchScreenUsage: 0\n  switchSupportedLanguagesMask: 0\n  switchLogoType: 0\n  switchApplicationErrorCodeCategory: \n  switchUserAccountSaveDataSize: 0\n  switchUserAccountSaveDataJournalSize: 0\n  switchApplicationAttribute: 0\n  switchCardSpecSize: -1\n  switchCardSpecClock: -1\n  switchRatingsMask: 0\n  switchRatingsInt_0: 0\n  switchRatingsInt_1: 0\n  switchRatingsInt_2: 0\n  switchRatingsInt_3: 0\n  switchRatingsInt_4: 0\n  switchRatingsInt_5: 0\n  switchRatingsInt_6: 0\n  switchRatingsInt_7: 0\n  switchRatingsInt_8: 0\n  switchRatingsInt_9: 0\n  switchRatingsInt_10: 0\n  switchRatingsInt_11: 0\n  switchLocalCommunicationIds_0: \n  switchLocalCommunicationIds_1: \n  switchLocalCommunicationIds_2: \n  switchLocalCommunicationIds_3: \n  switchLocalCommunicationIds_4: \n  switchLocalCommunicationIds_5: \n  switchLocalCommunicationIds_6: \n  switchLocalCommunicationIds_7: \n  switchParentalControl: 0\n  switchAllowsScreenshot: 1\n  switchDataLossConfirmation: 0\n  switchSupportedNpadStyles: 3\n  switchSocketConfigEnabled: 0\n  switchTcpInitialSendBufferSize: 32\n  switchTcpInitialReceiveBufferSize: 64\n  switchTcpAutoSendBufferSizeMax: 256\n  switchTcpAutoReceiveBufferSizeMax: 256\n  switchUdpSendBufferSize: 9\n  switchUdpReceiveBufferSize: 42\n  switchSocketBufferEfficiency: 4\n  switchSocketInitializeEnabled: 1\n  switchNetworkInterfaceManagerInitializeEnabled: 1\n  switchPlayerConnectionEnabled: 1\n  ps4NPAgeRating: 12\n  ps4NPTitleSecret: \n  ps4NPTrophyPackPath: \n  ps4ParentalLevel: 11\n  ps4ContentID: ED1633-NPXX51362_00-0000000000000000\n  ps4Category: 0\n  ps4MasterVersion: 01.00\n  ps4AppVersion: 01.00\n  ps4AppType: 0\n  ps4ParamSfxPath: \n  ps4VideoOutPixelFormat: 0\n  ps4VideoOutInitialWidth: 1920\n  ps4VideoOutBaseModeInitialWidth: 1920\n  ps4VideoOutReprojectionRate: 120\n  ps4PronunciationXMLPath: \n  ps4PronunciationSIGPath: \n  ps4BackgroundImagePath: \n  ps4StartupImagePath: \n  ps4SaveDataImagePath: \n  ps4SdkOverride: \n  ps4BGMPath: \n  ps4ShareFilePath: \n  ps4ShareOverlayImagePath: \n  ps4PrivacyGuardImagePath: \n  ps4NPtitleDatPath: \n  ps4RemotePlayKeyAssignment: -1\n  ps4RemotePlayKeyMappingDir: \n  ps4PlayTogetherPlayerCount: 0\n  ps4EnterButtonAssignment: 1\n  ps4ApplicationParam1: 0\n  ps4ApplicationParam2: 0\n  ps4ApplicationParam3: 0\n  ps4ApplicationParam4: 0\n  ps4DownloadDataSize: 0\n  ps4GarlicHeapSize: 2048\n  ps4ProGarlicHeapSize: 2560\n  ps4Passcode: eaoEiIgxIX4a2dREbbSqWy6yhKIDCdJO\n  ps4pnSessions: 1\n  ps4pnPresence: 1\n  ps4pnFriends: 1\n  ps4pnGameCustomData: 1\n  playerPrefsSupport: 0\n  restrictedAudioUsageRights: 0\n  ps4UseResolutionFallback: 0\n  ps4ReprojectionSupport: 0\n  ps4UseAudio3dBackend: 0\n  ps4SocialScreenEnabled: 0\n  ps4ScriptOptimizationLevel: 0\n  ps4Audio3dVirtualSpeakerCount: 14\n  ps4attribCpuUsage: 0\n  ps4PatchPkgPath: \n  ps4PatchLatestPkgPath: \n  ps4PatchChangeinfoPath: \n  ps4PatchDayOne: 0\n  ps4attribUserManagement: 0\n  ps4attribMoveSupport: 0\n  ps4attrib3DSupport: 0\n  ps4attribShareSupport: 0\n  ps4attribExclusiveVR: 0\n  ps4disableAutoHideSplash: 0\n  ps4videoRecordingFeaturesUsed: 0\n  ps4contentSearchFeaturesUsed: 0\n  ps4attribEyeToEyeDistanceSettingVR: 0\n  ps4IncludedModules: []\n  monoEnv: \n  psp2Splashimage: {fileID: 0}\n  psp2NPTrophyPackPath: \n  psp2NPSupportGBMorGJP: 0\n  psp2NPAgeRating: 12\n  psp2NPTitleDatPath: \n  psp2NPCommsID: \n  psp2NPCommunicationsID: \n  psp2NPCommsPassphrase: \n  psp2NPCommsSig: \n  psp2ParamSfxPath: \n  psp2ManualPath: \n  psp2LiveAreaGatePath: \n  psp2LiveAreaBackroundPath: \n  psp2LiveAreaPath: \n  psp2LiveAreaTrialPath: \n  psp2PatchChangeInfoPath: \n  psp2PatchOriginalPackage: \n  psp2PackagePassword: yapnxrpMCARCr4zdGc81tBDKsMlaZTXC\n  psp2KeystoneFile: \n  psp2MemoryExpansionMode: 0\n  psp2DRMType: 0\n  psp2StorageType: 0\n  psp2MediaCapacity: 0\n  psp2DLCConfigPath: \n  psp2ThumbnailPath: \n  psp2BackgroundPath: \n  psp2SoundPath: \n  psp2TrophyCommId: \n  psp2TrophyPackagePath: \n  psp2PackagedResourcesPath: \n  psp2SaveDataQuota: 10240\n  psp2ParentalLevel: 1\n  psp2ShortTitle: Not Set\n  psp2ContentID: IV0000-ABCD12345_00-0123456789ABCDEF\n  psp2Category: 0\n  psp2MasterVersion: 01.00\n  psp2AppVersion: 01.00\n  psp2TVBootMode: 0\n  psp2EnterButtonAssignment: 2\n  psp2TVDisableEmu: 0\n  psp2AllowTwitterDialog: 1\n  psp2Upgradable: 0\n  psp2HealthWarning: 0\n  psp2UseLibLocation: 0\n  psp2InfoBarOnStartup: 0\n  psp2InfoBarColor: 0\n  psp2ScriptOptimizationLevel: 0\n  psmSplashimage: {fileID: 0}\n  splashScreenBackgroundSourceLandscape: {fileID: 0}\n  splashScreenBackgroundSourcePortrait: {fileID: 0}\n  spritePackerPolicy: \n  webGLMemorySize: 256\n  webGLExceptionSupport: 1\n  webGLNameFilesAsHashes: 0\n  webGLDataCaching: 0\n  webGLDebugSymbols: 0\n  webGLEmscriptenArgs: \n  webGLModulesDirectory: \n  webGLTemplate: APPLICATION:Default\n  webGLAnalyzeBuildSize: 0\n  webGLUseEmbeddedResources: 0\n  webGLUseWasm: 0\n  webGLCompressionFormat: 1\n  scriptingDefineSymbols: {}\n  platformArchitecture: {}\n  scriptingBackend: {}\n  incrementalIl2cppBuild: {}\n  additionalIl2CppArgs: \n  scriptingRuntimeVersion: 0\n  apiCompatibilityLevelPerPlatform: {}\n  m_RenderingPath: 1\n  m_MobileRenderingPath: 1\n  metroPackageName: demo\n  metroPackageVersion: \n  metroCertificatePath: \n  metroCertificatePassword: \n  metroCertificateSubject: \n  metroCertificateIssuer: \n  metroCertificateNotAfter: 0000000000000000\n  metroApplicationDescription: demo\n  wsaImages: {}\n  metroTileShortName: \n  metroCommandLineArgsFile: \n  metroTileShowName: 0\n  metroMediumTileShowName: 0\n  metroLargeTileShowName: 0\n  metroWideTileShowName: 0\n  metroDefaultTileSize: 1\n  metroTileForegroundText: 1\n  metroTileBackgroundColor: {r: 0, g: 0, b: 0, a: 1}\n  metroSplashScreenBackgroundColor: {r: 0, g: 0, b: 0, a: 1}\n  metroSplashScreenUseBackgroundColor: 0\n  platformCapabilities: {}\n  metroFTAName: \n  metroFTAFileTypes: []\n  metroProtocolName: \n  metroCompilationOverrides: 1\n  tizenProductDescription: \n  tizenProductURL: \n  tizenSigningProfileName: \n  tizenGPSPermissions: 0\n  tizenMicrophonePermissions: 0\n  tizenDeploymentTarget: \n  tizenDeploymentTargetType: -1\n  tizenMinOSVersion: 1\n  n3dsUseExtSaveData: 0\n  n3dsCompressStaticMem: 1\n  n3dsExtSaveDataNumber: 0x12345\n  n3dsStackSize: 131072\n  n3dsTargetPlatform: 2\n  n3dsRegion: 7\n  n3dsMediaSize: 0\n  n3dsLogoStyle: 3\n  n3dsTitle: GameName\n  n3dsProductCode: \n  n3dsApplicationId: 0xFF3FF\n  stvDeviceAddress: \n  stvProductDescription: \n  stvProductAuthor: \n  stvProductAuthorEmail: \n  stvProductLink: \n  stvProductCategory: 0\n  XboxOneProductId: \n  XboxOneUpdateKey: \n  XboxOneSandboxId: \n  XboxOneContentId: \n  XboxOneTitleId: \n  XboxOneSCId: \n  XboxOneGameOsOverridePath: \n  XboxOnePackagingOverridePath: \n  XboxOneAppManifestOverridePath: \n  XboxOnePackageEncryption: 0\n  XboxOnePackageUpdateGranularity: 2\n  XboxOneDescription: \n  XboxOneLanguage:\n  - enus\n  XboxOneCapability: []\n  XboxOneGameRating: {}\n  XboxOneIsContentPackage: 0\n  XboxOneEnableGPUVariability: 0\n  XboxOneSockets: {}\n  XboxOneSplashScreen: {fileID: 0}\n  XboxOneAllowedProductIds: []\n  XboxOnePersistentLocalStorageSize: 0\n  xboxOneScriptCompiler: 0\n  vrEditorSettings:\n    daydream:\n      daydreamIconForeground: {fileID: 0}\n      daydreamIconBackground: {fileID: 0}\n  cloudServicesEnabled: {}\n  facebookSdkVersion: 7.9.4\n  apiCompatibilityLevel: 2\n  cloudProjectId: \n  projectName: \n  organizationId: \n  cloudEnabled: 0\n  enableNativePlatformBackendsForNewInputSystem: 0\n  disableOldInputManagerSupport: 0\n"
  },
  {
    "path": "demo/ProjectSettings/ProjectVersion.txt",
    "content": "m_EditorVersion: 2017.1.1f1\n"
  },
  {
    "path": "demo/ProjectSettings/QualitySettings.asset",
    "content": "%YAML 1.1\n%TAG !u! tag:unity3d.com,2011:\n--- !u!47 &1\nQualitySettings:\n  m_ObjectHideFlags: 0\n  serializedVersion: 5\n  m_CurrentQuality: 3\n  m_QualitySettings:\n  - serializedVersion: 2\n    name: Fastest\n    pixelLightCount: 0\n    shadows: 0\n    shadowResolution: 0\n    shadowProjection: 1\n    shadowCascades: 1\n    shadowDistance: 15\n    blendWeights: 1\n    textureQuality: 1\n    anisotropicTextures: 0\n    antiAliasing: 0\n    softParticles: 0\n    softVegetation: 0\n    vSyncCount: 0\n    lodBias: .300000012\n    maximumLODLevel: 0\n    particleRaycastBudget: 4\n    excludedTargetPlatforms: []\n  - serializedVersion: 2\n    name: Fast\n    pixelLightCount: 0\n    shadows: 0\n    shadowResolution: 0\n    shadowProjection: 1\n    shadowCascades: 1\n    shadowDistance: 20\n    blendWeights: 2\n    textureQuality: 0\n    anisotropicTextures: 0\n    antiAliasing: 0\n    softParticles: 0\n    softVegetation: 0\n    vSyncCount: 0\n    lodBias: .400000006\n    maximumLODLevel: 0\n    particleRaycastBudget: 16\n    excludedTargetPlatforms: []\n  - serializedVersion: 2\n    name: Simple\n    pixelLightCount: 1\n    shadows: 1\n    shadowResolution: 0\n    shadowProjection: 1\n    shadowCascades: 1\n    shadowDistance: 20\n    blendWeights: 2\n    textureQuality: 0\n    anisotropicTextures: 1\n    antiAliasing: 0\n    softParticles: 0\n    softVegetation: 0\n    vSyncCount: 0\n    lodBias: .699999988\n    maximumLODLevel: 0\n    particleRaycastBudget: 64\n    excludedTargetPlatforms: []\n  - serializedVersion: 2\n    name: Good\n    pixelLightCount: 2\n    shadows: 2\n    shadowResolution: 1\n    shadowProjection: 1\n    shadowCascades: 2\n    shadowDistance: 40\n    blendWeights: 2\n    textureQuality: 0\n    anisotropicTextures: 1\n    antiAliasing: 0\n    softParticles: 0\n    softVegetation: 1\n    vSyncCount: 1\n    lodBias: 1\n    maximumLODLevel: 0\n    particleRaycastBudget: 256\n    excludedTargetPlatforms: []\n  - serializedVersion: 2\n    name: Beautiful\n    pixelLightCount: 3\n    shadows: 2\n    shadowResolution: 2\n    shadowProjection: 1\n    shadowCascades: 2\n    shadowDistance: 70\n    blendWeights: 4\n    textureQuality: 0\n    anisotropicTextures: 2\n    antiAliasing: 2\n    softParticles: 1\n    softVegetation: 1\n    vSyncCount: 1\n    lodBias: 1.5\n    maximumLODLevel: 0\n    particleRaycastBudget: 1024\n    excludedTargetPlatforms: []\n  - serializedVersion: 2\n    name: Fantastic\n    pixelLightCount: 4\n    shadows: 2\n    shadowResolution: 2\n    shadowProjection: 1\n    shadowCascades: 4\n    shadowDistance: 150\n    blendWeights: 4\n    textureQuality: 0\n    anisotropicTextures: 2\n    antiAliasing: 2\n    softParticles: 1\n    softVegetation: 1\n    vSyncCount: 1\n    lodBias: 2\n    maximumLODLevel: 0\n    particleRaycastBudget: 4096\n    excludedTargetPlatforms: []\n  m_PerPlatformDefaultQuality: {}\n"
  },
  {
    "path": "demo/ProjectSettings/TagManager.asset",
    "content": "%YAML 1.1\n%TAG !u! tag:unity3d.com,2011:\n--- !u!78 &1\nTagManager:\n  tags:\n  - \n  Builtin Layer 0: Default\n  Builtin Layer 1: TransparentFX\n  Builtin Layer 2: Ignore Raycast\n  Builtin Layer 3: \n  Builtin Layer 4: Water\n  Builtin Layer 5: UI\n  Builtin Layer 6: \n  Builtin Layer 7: \n  User Layer 8: \n  User Layer 9: \n  User Layer 10: \n  User Layer 11: \n  User Layer 12: \n  User Layer 13: \n  User Layer 14: \n  User Layer 15: \n  User Layer 16: \n  User Layer 17: \n  User Layer 18: \n  User Layer 19: \n  User Layer 20: \n  User Layer 21: \n  User Layer 22: \n  User Layer 23: \n  User Layer 24: \n  User Layer 25: \n  User Layer 26: \n  User Layer 27: \n  User Layer 28: \n  User Layer 29: \n  User Layer 30: \n  User Layer 31: \n  m_SortingLayers:\n  - name: Default\n    userID: 0\n    uniqueID: 0\n    locked: 0\n"
  },
  {
    "path": "demo/ProjectSettings/TimeManager.asset",
    "content": "%YAML 1.1\n%TAG !u! tag:unity3d.com,2011:\n--- !u!5 &1\nTimeManager:\n  m_ObjectHideFlags: 0\n  Fixed Timestep: .0199999996\n  Maximum Allowed Timestep: .333333343\n  m_TimeScale: 1\n"
  },
  {
    "path": "demo/ProjectSettings/UnityConnectSettings.asset",
    "content": "%YAML 1.1\n%TAG !u! tag:unity3d.com,2011:\n--- !u!310 &1\nUnityConnectSettings:\n  m_ObjectHideFlags: 0\n  m_Enabled: 0\n  m_TestMode: 0\n  m_TestEventUrl: \n  m_TestConfigUrl: \n  m_TestInitMode: 0\n  CrashReportingSettings:\n    m_EventUrl: https://perf-events.cloud.unity3d.com/api/events/crashes\n    m_Enabled: 0\n    m_CaptureEditorExceptions: 1\n  UnityPurchasingSettings:\n    m_Enabled: 0\n    m_TestMode: 0\n  UnityAnalyticsSettings:\n    m_Enabled: 0\n    m_InitializeOnStartup: 1\n    m_TestMode: 0\n    m_TestEventUrl: \n    m_TestConfigUrl: \n  UnityAdsSettings:\n    m_Enabled: 0\n    m_InitializeOnStartup: 1\n    m_TestMode: 0\n    m_EnabledPlatforms: 4294967295\n    m_IosGameId: \n    m_AndroidGameId: \n    m_GameIds: {}\n    m_GameId: \n  PerformanceReportingSettings:\n    m_Enabled: 0\n"
  }
]