├── .gitignore ├── .idea └── .idea.Unity-Dungeon-Generator │ ├── .idea │ ├── codeStyles │ │ └── codeStyleConfig.xml │ ├── contentModel.xml │ ├── encodings.xml │ ├── indexLayout.xml │ ├── modules.xml │ ├── projectSettingsUpdater.xml │ ├── vcs.xml │ └── workspace.xml │ └── riderModule.iml ├── .vscode └── settings.json ├── Assets ├── Delaunay.meta ├── Delaunay │ ├── Demo.unity │ ├── Demo.unity.meta │ ├── Unity-delaunay.meta │ ├── Unity-delaunay │ │ ├── Delaunay.meta │ │ ├── Delaunay │ │ │ ├── DelaunayHelpers.cs │ │ │ ├── DelaunayHelpers.cs.meta │ │ │ ├── Edge.cs │ │ │ ├── Edge.cs.meta │ │ │ ├── EdgeList.cs │ │ │ ├── EdgeList.cs.meta │ │ │ ├── EdgeReorderer.cs │ │ │ ├── EdgeReorderer.cs.meta │ │ │ ├── Halfedge.cs │ │ │ ├── Halfedge.cs.meta │ │ │ ├── HalfedgePriorityQueue.cs │ │ │ ├── HalfedgePriorityQueue.cs.meta │ │ │ ├── ICoord.cs │ │ │ ├── ICoord.cs.meta │ │ │ ├── LR.cs │ │ │ ├── LR.cs.meta │ │ │ ├── Site.cs │ │ │ ├── Site.cs.meta │ │ │ ├── SiteList.cs │ │ │ ├── SiteList.cs.meta │ │ │ ├── Triangle.cs │ │ │ ├── Triangle.cs.meta │ │ │ ├── Vertex.cs │ │ │ ├── Vertex.cs.meta │ │ │ ├── Voronoi.cs │ │ │ └── Voronoi.cs.meta │ │ ├── geom.meta │ │ ├── geom │ │ │ ├── Circle.cs │ │ │ ├── Circle.cs.meta │ │ │ ├── LineSegment.cs │ │ │ ├── LineSegment.cs.meta │ │ │ ├── Polygon.cs │ │ │ ├── Polygon.cs.meta │ │ │ ├── Winding.cs │ │ │ └── Winding.cs.meta │ │ ├── utils.meta │ │ └── utils │ │ │ ├── IDisposable.cs │ │ │ └── IDisposable.cs.meta │ ├── VoronoiDemo.cs │ └── VoronoiDemo.cs.meta ├── DungeonGenerator.meta └── DungeonGenerator │ ├── Dungeon.meta │ ├── Dungeon │ ├── Nodes.meta │ └── Nodes │ │ ├── DungeonNodes.asset │ │ ├── DungeonNodes.asset.meta │ │ ├── TilemapNodes.asset │ │ └── TilemapNodes.asset.meta │ ├── Scenes.meta │ ├── Scenes │ ├── SampleScene.unity │ └── SampleScene.unity.meta │ ├── Scripts.meta │ └── Scripts │ ├── Editor.meta │ ├── Editor │ ├── BuiltInResourcesWindow.cs │ ├── BuiltInResourcesWindow.cs.meta │ ├── DungeonGeneratorEditor.cs │ ├── DungeonGeneratorEditor.cs.meta │ ├── NodeGraphDungeonWindow.cs │ ├── NodeGraphDungeonWindow.cs.meta │ ├── NodeGraphGeneratorEditor.cs │ └── NodeGraphGeneratorEditor.cs.meta │ ├── Math2D.meta │ ├── Math2D │ ├── Math2d.cs │ └── Math2d.cs.meta │ ├── ProceduralDungeonGenerator.meta │ └── ProceduralDungeonGenerator │ ├── BSPDungeonGeneration.cs │ ├── BSPDungeonGeneration.cs.meta │ ├── DelaunayDungeonGenerator.cs │ ├── DelaunayDungeonGenerator.cs.meta │ ├── DungeonGenerator.cs │ ├── DungeonGenerator.cs.meta │ ├── DungeonRoomsGenerator.cs │ ├── DungeonRoomsGenerator.cs.meta │ ├── Olds.meta │ ├── Olds │ ├── NodeGraphGenerator.cs │ ├── NodeGraphGenerator.cs.meta │ ├── NodeTilemapDungeonGenerator.cs │ ├── NodeTilemapDungeonGenerator.cs.meta │ ├── TilemapDungeonGenerator.cs │ └── TilemapDungeonGenerator.cs.meta │ ├── Room.cs │ ├── Room.cs.meta │ ├── TilemapBSPDriver.cs │ └── TilemapBSPDriver.cs.meta ├── LICENSE.md ├── Packages ├── manifest.json └── packages-lock.json ├── ProjectSettings ├── AudioManager.asset ├── ClusterInputManager.asset ├── DynamicsManager.asset ├── EditorBuildSettings.asset ├── EditorSettings.asset ├── GraphicsSettings.asset ├── InputManager.asset ├── NavMeshAreas.asset ├── NetworkManager.asset ├── Physics2DSettings.asset ├── PresetManager.asset ├── ProjectSettings.asset ├── ProjectVersion.txt ├── QualitySettings.asset ├── TagManager.asset ├── TimeManager.asset ├── UnityConnectSettings.asset ├── VFXManager.asset └── XRSettings.asset ├── README.md ├── bsp.gif ├── bsp.jpg ├── delaunay.gif └── delaunay.jpg /.gitignore: -------------------------------------------------------------------------------- 1 | [Ll]ibrary/ 2 | [Tt]emp/ 3 | [Oo]bj/ 4 | [Bb]uild/ 5 | [Bb]uilds/ 6 | [Ll]ogs/ 7 | [Aa]ssets/AssetStoreTools* 8 | [Aa]ssets/Plugins* 9 | [Aa]ssets/SD_Project* 10 | [Aa]ssets/SimpleNote* 11 | [Aa]ssets/DungeonGenerator/Prefabs* 12 | [Aa]ssets/Tilemap* 13 | [Aa]ssets/Scenes* 14 | 15 | 16 | # Visual Studio cache directory 17 | .vs/ 18 | 19 | # Gradle cache directory 20 | .gradle/ 21 | 22 | # Autogenerated VS/MD/Consulo solution and project files 23 | ExportedObj/ 24 | .consulo/ 25 | *.csproj 26 | *.unityproj 27 | *.sln 28 | *.suo 29 | *.tmp 30 | *.user 31 | *.userprefs 32 | *.pidb 33 | *.booproj 34 | *.svd 35 | *.pdb 36 | *.opendb 37 | *.VC.db 38 | 39 | # Unity3D generated meta files 40 | *.pidb.meta 41 | *.pdb.meta 42 | 43 | # Unity3D generated file on crash reports 44 | sysinfo.txt 45 | 46 | # Builds 47 | *.apk 48 | *.unitypackage 49 | 50 | # Crashlytics generated file 51 | Assets/StreamingAssets/crashlytics-build.properties 52 | -------------------------------------------------------------------------------- /.idea/.idea.Unity-Dungeon-Generator/.idea/codeStyles/codeStyleConfig.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 5 | -------------------------------------------------------------------------------- /.idea/.idea.Unity-Dungeon-Generator/.idea/contentModel.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /.idea/.idea.Unity-Dungeon-Generator/.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /.idea/.idea.Unity-Dungeon-Generator/.idea/indexLayout.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Library/PackageCache/com.unity.ads@3.4.9 7 | Library/PackageCache/com.unity.analytics@3.3.5 8 | Library/PackageCache/com.unity.collab-proxy@1.2.16 9 | Library/PackageCache/com.unity.ext.nunit@1.0.0 10 | Library/PackageCache/com.unity.ide.rider@1.1.4 11 | Library/PackageCache/com.unity.ide.vscode@1.2.1 12 | Library/PackageCache/com.unity.multiplayer-hlapi@1.0.6 13 | Library/PackageCache/com.unity.purchasing@2.1.0 14 | Library/PackageCache/com.unity.test-framework@1.1.16 15 | Library/PackageCache/com.unity.textmeshpro@2.0.1 16 | Library/PackageCache/com.unity.timeline@1.2.6 17 | Library/PackageCache/com.unity.xr.legacyinputhelpers@2.1.4 18 | Library/PackageCache/nuget.mono-cecil@0.1.6-preview 19 | Packages 20 | ProjectSettings 21 | 22 | 23 | .git 24 | .idea 25 | .vscode 26 | Library 27 | Logs 28 | Temp 29 | obj 30 | 31 | 32 | -------------------------------------------------------------------------------- /.idea/.idea.Unity-Dungeon-Generator/.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.idea/.idea.Unity-Dungeon-Generator/.idea/projectSettingsUpdater.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /.idea/.idea.Unity-Dungeon-Generator/.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/.idea.Unity-Dungeon-Generator/.idea/workspace.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 16 | 17 | 19 | 20 | 21 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 38 | 39 | 40 | 41 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 1604130023059 55 | 60 | 61 | 62 | 63 | 65 | 66 | 67 | 68 | 70 | -------------------------------------------------------------------------------- /.idea/.idea.Unity-Dungeon-Generator/riderModule.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "files.exclude": 3 | { 4 | "**/.DS_Store":true, 5 | "**/.git":true, 6 | "**/.gitignore":true, 7 | "**/.gitmodules":true, 8 | "**/*.booproj":true, 9 | "**/*.pidb":true, 10 | "**/*.suo":true, 11 | "**/*.user":true, 12 | "**/*.userprefs":true, 13 | "**/*.unityproj":true, 14 | "**/*.dll":true, 15 | "**/*.exe":true, 16 | "**/*.pdf":true, 17 | "**/*.mid":true, 18 | "**/*.midi":true, 19 | "**/*.wav":true, 20 | "**/*.gif":true, 21 | "**/*.ico":true, 22 | "**/*.jpg":true, 23 | "**/*.jpeg":true, 24 | "**/*.png":true, 25 | "**/*.psd":true, 26 | "**/*.tga":true, 27 | "**/*.tif":true, 28 | "**/*.tiff":true, 29 | "**/*.3ds":true, 30 | "**/*.3DS":true, 31 | "**/*.fbx":true, 32 | "**/*.FBX":true, 33 | "**/*.lxo":true, 34 | "**/*.LXO":true, 35 | "**/*.ma":true, 36 | "**/*.MA":true, 37 | "**/*.obj":true, 38 | "**/*.OBJ":true, 39 | "**/*.asset":true, 40 | "**/*.cubemap":true, 41 | "**/*.flare":true, 42 | "**/*.mat":true, 43 | "**/*.meta":true, 44 | "**/*.prefab":true, 45 | "**/*.unity":true, 46 | "build/":true, 47 | "Build/":true, 48 | "Library/":true, 49 | "library/":true, 50 | "obj/":true, 51 | "Obj/":true, 52 | "ProjectSettings/":true, 53 | "temp/":true, 54 | "Temp/":true 55 | } 56 | } -------------------------------------------------------------------------------- /Assets/Delaunay.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 48df59c5d997aa34bb7224cd2154ad0b 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/Delaunay/Demo.unity: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!29 &1 4 | SceneSettings: 5 | m_ObjectHideFlags: 0 6 | m_PVSData: 7 | m_PVSObjectsArray: [] 8 | m_PVSPortalsArray: [] 9 | m_OcclusionBakeSettings: 10 | smallestOccluder: 5 11 | smallestHole: .25 12 | backfaceThreshold: 100 13 | --- !u!104 &2 14 | RenderSettings: 15 | m_Fog: 0 16 | m_FogColor: {r: .5, g: .5, b: .5, a: 1} 17 | m_FogMode: 3 18 | m_FogDensity: .00999999978 19 | m_LinearFogStart: 0 20 | m_LinearFogEnd: 300 21 | m_AmbientLight: {r: .200000003, g: .200000003, b: .200000003, a: 1} 22 | m_SkyboxMaterial: {fileID: 0} 23 | m_HaloStrength: .5 24 | m_FlareStrength: 1 25 | m_FlareFadeSpeed: 3 26 | m_HaloTexture: {fileID: 0} 27 | m_SpotCookie: {fileID: 0} 28 | m_ObjectHideFlags: 0 29 | --- !u!127 &3 30 | LevelGameManager: 31 | m_ObjectHideFlags: 0 32 | --- !u!157 &4 33 | LightmapSettings: 34 | m_ObjectHideFlags: 0 35 | m_LightProbes: {fileID: 0} 36 | m_Lightmaps: [] 37 | m_LightmapsMode: 1 38 | m_BakedColorSpace: 0 39 | m_UseDualLightmapsInForward: 0 40 | m_LightmapEditorSettings: 41 | m_Resolution: 50 42 | m_LastUsedResolution: 0 43 | m_TextureWidth: 1024 44 | m_TextureHeight: 1024 45 | m_BounceBoost: 1 46 | m_BounceIntensity: 1 47 | m_SkyLightColor: {r: .860000014, g: .930000007, b: 1, a: 1} 48 | m_SkyLightIntensity: 0 49 | m_Quality: 0 50 | m_Bounces: 1 51 | m_FinalGatherRays: 1000 52 | m_FinalGatherContrastThreshold: .0500000007 53 | m_FinalGatherGradientThreshold: 0 54 | m_FinalGatherInterpolationPoints: 15 55 | m_AOAmount: 0 56 | m_AOMaxDistance: .100000001 57 | m_AOContrast: 1 58 | m_LODSurfaceMappingDistance: 1 59 | m_Padding: 0 60 | m_TextureCompression: 0 61 | m_LockAtlas: 0 62 | --- !u!196 &5 63 | NavMeshSettings: 64 | m_ObjectHideFlags: 0 65 | m_BuildSettings: 66 | agentRadius: .5 67 | agentHeight: 2 68 | agentSlope: 45 69 | agentClimb: .400000006 70 | ledgeDropHeight: 0 71 | maxJumpAcrossDistance: 0 72 | accuratePlacement: 0 73 | minRegionArea: 2 74 | widthInaccuracy: 16.666666 75 | heightInaccuracy: 10 76 | m_NavMesh: {fileID: 0} 77 | --- !u!1 &1746107355 78 | GameObject: 79 | m_ObjectHideFlags: 0 80 | m_PrefabParentObject: {fileID: 0} 81 | m_PrefabInternal: {fileID: 0} 82 | serializedVersion: 4 83 | m_Component: 84 | - 4: {fileID: 1746107357} 85 | - 114: {fileID: 1746107356} 86 | m_Layer: 0 87 | m_Name: VoronoiDemo 88 | m_TagString: Untagged 89 | m_Icon: {fileID: 0} 90 | m_NavMeshLayer: 0 91 | m_StaticEditorFlags: 0 92 | m_IsActive: 1 93 | --- !u!114 &1746107356 94 | MonoBehaviour: 95 | m_ObjectHideFlags: 0 96 | m_PrefabParentObject: {fileID: 0} 97 | m_PrefabInternal: {fileID: 0} 98 | m_GameObject: {fileID: 1746107355} 99 | m_Enabled: 1 100 | m_EditorHideFlags: 0 101 | m_Script: {fileID: 11500000, guid: 6b8eb48d5779546089555c7b0bd5341e, type: 3} 102 | m_Name: 103 | m_EditorClassIdentifier: 104 | m_pointCount: 300 105 | --- !u!4 &1746107357 106 | Transform: 107 | m_ObjectHideFlags: 0 108 | m_PrefabParentObject: {fileID: 0} 109 | m_PrefabInternal: {fileID: 0} 110 | m_GameObject: {fileID: 1746107355} 111 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 112 | m_LocalPosition: {x: 44.6139297, y: 18.9922752, z: 0} 113 | m_LocalScale: {x: 1, y: 1, z: 1} 114 | m_Children: [] 115 | m_Father: {fileID: 0} 116 | m_RootOrder: 1 117 | --- !u!1 &2037205290 118 | GameObject: 119 | m_ObjectHideFlags: 0 120 | m_PrefabParentObject: {fileID: 0} 121 | m_PrefabInternal: {fileID: 0} 122 | serializedVersion: 4 123 | m_Component: 124 | - 4: {fileID: 2037205295} 125 | - 20: {fileID: 2037205294} 126 | - 92: {fileID: 2037205293} 127 | - 124: {fileID: 2037205292} 128 | - 81: {fileID: 2037205291} 129 | m_Layer: 0 130 | m_Name: Main Camera 131 | m_TagString: MainCamera 132 | m_Icon: {fileID: 0} 133 | m_NavMeshLayer: 0 134 | m_StaticEditorFlags: 0 135 | m_IsActive: 1 136 | --- !u!81 &2037205291 137 | AudioListener: 138 | m_ObjectHideFlags: 0 139 | m_PrefabParentObject: {fileID: 0} 140 | m_PrefabInternal: {fileID: 0} 141 | m_GameObject: {fileID: 2037205290} 142 | m_Enabled: 1 143 | --- !u!124 &2037205292 144 | Behaviour: 145 | m_ObjectHideFlags: 0 146 | m_PrefabParentObject: {fileID: 0} 147 | m_PrefabInternal: {fileID: 0} 148 | m_GameObject: {fileID: 2037205290} 149 | m_Enabled: 1 150 | --- !u!92 &2037205293 151 | Behaviour: 152 | m_ObjectHideFlags: 0 153 | m_PrefabParentObject: {fileID: 0} 154 | m_PrefabInternal: {fileID: 0} 155 | m_GameObject: {fileID: 2037205290} 156 | m_Enabled: 1 157 | --- !u!20 &2037205294 158 | Camera: 159 | m_ObjectHideFlags: 0 160 | m_PrefabParentObject: {fileID: 0} 161 | m_PrefabInternal: {fileID: 0} 162 | m_GameObject: {fileID: 2037205290} 163 | m_Enabled: 1 164 | serializedVersion: 2 165 | m_ClearFlags: 1 166 | m_BackGroundColor: {r: 0, g: 0, b: 0, a: .0196078438} 167 | m_NormalizedViewPortRect: 168 | serializedVersion: 2 169 | x: 0 170 | y: 0 171 | width: 1 172 | height: 1 173 | near clip plane: .300000012 174 | far clip plane: 1000 175 | field of view: 60 176 | orthographic: 1 177 | orthographic size: 30 178 | m_Depth: -1 179 | m_CullingMask: 180 | serializedVersion: 2 181 | m_Bits: 4294967295 182 | m_RenderingPath: -1 183 | m_TargetTexture: {fileID: 0} 184 | m_TargetDisplay: 0 185 | m_HDR: 0 186 | m_OcclusionCulling: 1 187 | m_StereoConvergence: 10 188 | m_StereoSeparation: .0219999999 189 | --- !u!4 &2037205295 190 | Transform: 191 | m_ObjectHideFlags: 0 192 | m_PrefabParentObject: {fileID: 0} 193 | m_PrefabInternal: {fileID: 0} 194 | m_GameObject: {fileID: 2037205290} 195 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 196 | m_LocalPosition: {x: 50, y: 25, z: -10} 197 | m_LocalScale: {x: 1, y: 1, z: 1} 198 | m_Children: [] 199 | m_Father: {fileID: 0} 200 | m_RootOrder: 0 201 | -------------------------------------------------------------------------------- /Assets/Delaunay/Demo.unity.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 79883178826fb4e77a1f5cda54f78635 3 | DefaultImporter: 4 | userData: 5 | -------------------------------------------------------------------------------- /Assets/Delaunay/Unity-delaunay.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: adf918391394e4918943cbf0bb3dd6ea 3 | folderAsset: yes 4 | DefaultImporter: 5 | userData: 6 | -------------------------------------------------------------------------------- /Assets/Delaunay/Unity-delaunay/Delaunay.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 7ea91cd8b2a424a0f97e63013b752cdc 3 | folderAsset: yes 4 | DefaultImporter: 5 | userData: 6 | -------------------------------------------------------------------------------- /Assets/Delaunay/Unity-delaunay/Delaunay/DelaunayHelpers.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System; 3 | using System.Collections.Generic; 4 | using Delaunay.Geo; 5 | using Delaunay.LR; 6 | 7 | namespace Delaunay 8 | { 9 | 10 | public class Node 11 | { 12 | public static Stack pool = new Stack (); 13 | 14 | public Node parent; 15 | public int treeSize; 16 | } 17 | 18 | public enum KruskalType 19 | { 20 | MINIMUM, 21 | MAXIMUM 22 | } 23 | 24 | public static class DelaunayHelpers 25 | { 26 | public static List VisibleLineSegments (List edges) 27 | { 28 | List segments = new List (); 29 | 30 | for (int i = 0; i p1 = edge.clippedEnds [Side.LEFT]; 34 | Nullable p2 = edge.clippedEnds [Side.RIGHT]; 35 | segments.Add (new LineSegment (p1, p2)); 36 | } 37 | } 38 | 39 | return segments; 40 | } 41 | 42 | public static List SelectEdgesForSitePoint (Vector2 coord, List edgesToTest) 43 | { 44 | return edgesToTest.FindAll (delegate (Edge edge) { 45 | return ((edge.leftSite != null && edge.leftSite.Coord == coord) 46 | || (edge.rightSite != null && edge.rightSite.Coord == coord)); 47 | }); 48 | } 49 | 50 | public static List SelectNonIntersectingEdges (/*keepOutMask:BitmapData,*/List edgesToTest) 51 | { 52 | // if (keepOutMask == null) 53 | // { 54 | return edgesToTest; 55 | // } 56 | 57 | // var zeroPoint:Point = new Point(); 58 | // return edgesToTest.filter(myTest); 59 | // 60 | // function myTest(edge:Edge, index:int, vector:Vector.):Boolean 61 | // { 62 | // var delaunayLineBmp:BitmapData = edge.makeDelaunayLineBmp(); 63 | // var notIntersecting:Boolean = !(keepOutMask.hitTest(zeroPoint, 1, delaunayLineBmp, zeroPoint, 1)); 64 | // delaunayLineBmp.dispose(); 65 | // return notIntersecting; 66 | // } 67 | } 68 | 69 | public static List DelaunayLinesForEdges (List edges) 70 | { 71 | List segments = new List (); 72 | Edge edge; 73 | for (int i = 0; i < edges.Count; i++) { 74 | edge = edges [i]; 75 | segments.Add (edge.DelaunayLine ()); 76 | } 77 | return segments; 78 | } 79 | 80 | /** 81 | * Kruskal's spanning tree algorithm with union-find 82 | * Skiena: The Algorithm Design Manual, p. 196ff 83 | * Note: the sites are implied: they consist of the end points of the line segments 84 | */ 85 | public static List Kruskal (List lineSegments, KruskalType type = KruskalType.MINIMUM) 86 | { 87 | Dictionary,Node> nodes = new Dictionary,Node> (); 88 | List mst = new List (); 89 | Stack nodePool = Node.pool; 90 | 91 | switch (type) { 92 | // note that the compare functions are the reverse of what you'd expect 93 | // because (see below) we traverse the lineSegments in reverse order for speed 94 | case KruskalType.MAXIMUM: 95 | lineSegments.Sort (delegate (LineSegment l1, LineSegment l2) { 96 | return LineSegment.CompareLengths (l1, l2); 97 | }); 98 | break; 99 | default: 100 | lineSegments.Sort (delegate (LineSegment l1, LineSegment l2) { 101 | return LineSegment.CompareLengths_MAX (l1, l2); 102 | }); 103 | break; 104 | } 105 | 106 | for (int i = lineSegments.Count; --i > -1;) { 107 | LineSegment lineSegment = lineSegments [i]; 108 | 109 | Node node0 = null; 110 | Node rootOfSet0; 111 | if (!nodes.ContainsKey (lineSegment.p0)) { 112 | node0 = nodePool.Count > 0 ? nodePool.Pop () : new Node (); 113 | // intialize the node: 114 | rootOfSet0 = node0.parent = node0; 115 | node0.treeSize = 1; 116 | 117 | nodes [lineSegment.p0] = node0; 118 | } else { 119 | node0 = nodes [lineSegment.p0]; 120 | rootOfSet0 = Find (node0); 121 | } 122 | 123 | Node node1 = null; 124 | Node rootOfSet1; 125 | if (!nodes.ContainsKey (lineSegment.p1)) { 126 | node1 = nodePool.Count > 0 ? nodePool.Pop () : new Node (); 127 | // intialize the node: 128 | rootOfSet1 = node1.parent = node1; 129 | node1.treeSize = 1; 130 | 131 | nodes [lineSegment.p1] = node1; 132 | } else { 133 | node1 = nodes [lineSegment.p1]; 134 | rootOfSet1 = Find (node1); 135 | } 136 | 137 | if (rootOfSet0 != rootOfSet1) { // nodes not in same set 138 | mst.Add (lineSegment); 139 | 140 | // merge the two sets: 141 | int treeSize0 = rootOfSet0.treeSize; 142 | int treeSize1 = rootOfSet1.treeSize; 143 | if (treeSize0 >= treeSize1) { 144 | // set0 absorbs set1: 145 | rootOfSet1.parent = rootOfSet0; 146 | rootOfSet0.treeSize += treeSize1; 147 | } else { 148 | // set1 absorbs set0: 149 | rootOfSet0.parent = rootOfSet1; 150 | rootOfSet1.treeSize += treeSize0; 151 | } 152 | } 153 | } 154 | foreach (Node node in nodes.Values) { 155 | nodePool.Push (node); 156 | } 157 | 158 | return mst; 159 | } 160 | 161 | private static Node Find (Node node) 162 | { 163 | if (node.parent == node) { 164 | return node; 165 | } else { 166 | Node root = Find (node.parent); 167 | // this line is just to speed up subsequent finds by keeping the tree depth low: 168 | node.parent = root; 169 | return root; 170 | } 171 | } 172 | } 173 | 174 | 175 | } -------------------------------------------------------------------------------- /Assets/Delaunay/Unity-delaunay/Delaunay/DelaunayHelpers.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 3e5cf667cd9df4f68a86433bcfff21d4 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/Delaunay/Unity-delaunay/Delaunay/Edge.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System; 3 | using System.Collections.Generic; 4 | using Delaunay.Geo; 5 | using Delaunay.LR; 6 | 7 | namespace Delaunay 8 | { 9 | // import com.nodename.geom.LineSegment; 10 | // 11 | // import flash.display.BitmapData; 12 | // import flash.display.CapsStyle; 13 | // import flash.display.Graphics; 14 | // import flash.display.LineScaleMode; 15 | // import flash.display.Sprite; 16 | // import flash.geom.Point; 17 | // import flash.geom.Rectangle; 18 | // import flash.utils.Dictionary; 19 | 20 | /** 21 | * The line segment connecting the two Sites is part of the Delaunay triangulation; 22 | * the line segment connecting the two Vertices is part of the Voronoi diagram 23 | * @author ashaw 24 | * 25 | */ 26 | public sealed class Edge 27 | { 28 | private static Stack _pool = new Stack (); 29 | 30 | /** 31 | * This is the only way to create a new Edge 32 | * @param site0 33 | * @param site1 34 | * @return 35 | * 36 | */ 37 | public static Edge CreateBisectingEdge (Site site0, Site site1) 38 | { 39 | float dx, dy, absdx, absdy; 40 | float a, b, c; 41 | 42 | dx = site1.x - site0.x; 43 | dy = site1.y - site0.y; 44 | absdx = dx > 0 ? dx : -dx; 45 | absdy = dy > 0 ? dy : -dy; 46 | c = site0.x * dx + site0.y * dy + (dx * dx + dy * dy) * 0.5f; 47 | if (absdx > absdy) { 48 | a = 1.0f; 49 | b = dy / dx; 50 | c /= dx; 51 | } else { 52 | b = 1.0f; 53 | a = dx / dy; 54 | c /= dy; 55 | } 56 | 57 | Edge edge = Edge.Create (); 58 | 59 | edge.leftSite = site0; 60 | edge.rightSite = site1; 61 | site0.AddEdge (edge); 62 | site1.AddEdge (edge); 63 | 64 | edge._leftVertex = null; 65 | edge._rightVertex = null; 66 | 67 | edge.a = a; 68 | edge.b = b; 69 | edge.c = c; 70 | //trace("createBisectingEdge: a ", edge.a, "b", edge.b, "c", edge.c); 71 | 72 | return edge; 73 | } 74 | 75 | private static Edge Create () 76 | { 77 | Edge edge; 78 | if (_pool.Count > 0) { 79 | edge = _pool.Pop (); 80 | edge.Init (); 81 | } else { 82 | edge = new Edge (); 83 | } 84 | return edge; 85 | } 86 | 87 | // private static const LINESPRITE:Sprite = new Sprite(); 88 | // private static const GRAPHICS:Graphics = LINESPRITE.graphics; 89 | // 90 | // private var _delaunayLineBmp:BitmapData; 91 | // internal function get delaunayLineBmp():BitmapData 92 | // { 93 | // if (!_delaunayLineBmp) 94 | // { 95 | // _delaunayLineBmp = makeDelaunayLineBmp(); 96 | // } 97 | // return _delaunayLineBmp; 98 | // } 99 | // 100 | // // making this available to Voronoi; running out of memory in AIR so I cannot cache the bmp 101 | // internal function makeDelaunayLineBmp():BitmapData 102 | // { 103 | // var p0:Point = leftSite.coord; 104 | // var p1:Point = rightSite.coord; 105 | // 106 | // GRAPHICS.clear(); 107 | // // clear() resets line style back to undefined! 108 | // GRAPHICS.lineStyle(0, 0, 1.0, false, LineScaleMode.NONE, CapsStyle.NONE); 109 | // GRAPHICS.moveTo(p0.x, p0.y); 110 | // GRAPHICS.lineTo(p1.x, p1.y); 111 | // 112 | // var w:int = int(Math.ceil(Math.max(p0.x, p1.x))); 113 | // if (w < 1) 114 | // { 115 | // w = 1; 116 | // } 117 | // var h:int = int(Math.ceil(Math.max(p0.y, p1.y))); 118 | // if (h < 1) 119 | // { 120 | // h = 1; 121 | // } 122 | // var bmp:BitmapData = new BitmapData(w, h, true, 0); 123 | // bmp.draw(LINESPRITE); 124 | // return bmp; 125 | // } 126 | 127 | public LineSegment DelaunayLine () 128 | { 129 | // draw a line connecting the input Sites for which the edge is a bisector: 130 | return new LineSegment (leftSite.Coord, rightSite.Coord); 131 | } 132 | 133 | public LineSegment VoronoiEdge () 134 | { 135 | if (!visible) 136 | return new LineSegment (null, null); 137 | return new LineSegment (_clippedVertices [Side.LEFT], 138 | _clippedVertices [Side.RIGHT]); 139 | } 140 | 141 | private static int _nedges = 0; 142 | 143 | public static readonly Edge DELETED = new Edge (); 144 | 145 | // the equation of the edge: ax + by = c 146 | public float a, b, c; 147 | 148 | // the two Voronoi vertices that the edge connects 149 | // (if one of them is null, the edge extends to infinity) 150 | private Vertex _leftVertex; 151 | public Vertex leftVertex { 152 | get { return _leftVertex;} 153 | } 154 | private Vertex _rightVertex; 155 | public Vertex rightVertex { 156 | get { return _rightVertex;} 157 | } 158 | public Vertex Vertex (Side leftRight) 159 | { 160 | return (leftRight == Side.LEFT) ? _leftVertex : _rightVertex; 161 | } 162 | public void SetVertex (Side leftRight, Vertex v) 163 | { 164 | if (leftRight == Side.LEFT) { 165 | _leftVertex = v; 166 | } else { 167 | _rightVertex = v; 168 | } 169 | } 170 | 171 | public bool IsPartOfConvexHull () 172 | { 173 | return (_leftVertex == null || _rightVertex == null); 174 | } 175 | 176 | public float SitesDistance () 177 | { 178 | return Vector2.Distance (leftSite.Coord, rightSite.Coord); 179 | } 180 | 181 | public static int CompareSitesDistances_MAX (Edge edge0, Edge edge1) 182 | { 183 | float length0 = edge0.SitesDistance (); 184 | float length1 = edge1.SitesDistance (); 185 | if (length0 < length1) { 186 | return 1; 187 | } 188 | if (length0 > length1) { 189 | return -1; 190 | } 191 | return 0; 192 | } 193 | 194 | public static int CompareSitesDistances (Edge edge0, Edge edge1) 195 | { 196 | return - CompareSitesDistances_MAX (edge0, edge1); 197 | } 198 | 199 | // Once clipVertices() is called, this Dictionary will hold two Points 200 | // representing the clipped coordinates of the left and right ends... 201 | private Dictionary> _clippedVertices; 202 | public Dictionary> clippedEnds { 203 | get { return _clippedVertices;} 204 | } 205 | // unless the entire Edge is outside the bounds. 206 | // In that case visible will be false: 207 | public bool visible { 208 | get { return _clippedVertices != null;} 209 | } 210 | 211 | // the two input Sites for which this Edge is a bisector: 212 | private Dictionary _sites; 213 | public Site leftSite { 214 | get{ return _sites [Side.LEFT];} 215 | set{ _sites [Side.LEFT] = value;} 216 | 217 | } 218 | public Site rightSite { 219 | get { return _sites [Side.RIGHT];} 220 | set { _sites [Side.RIGHT] = value;} 221 | } 222 | 223 | public Site Site (Side leftRight) 224 | { 225 | return _sites [leftRight]; 226 | } 227 | 228 | private int _edgeIndex; 229 | 230 | public void Dispose () 231 | { 232 | // if (_delaunayLineBmp) { 233 | // _delaunayLineBmp.Dispose (); 234 | // _delaunayLineBmp = null; 235 | // } 236 | _leftVertex = null; 237 | _rightVertex = null; 238 | if (_clippedVertices != null) { 239 | _clippedVertices [Side.LEFT] = null; 240 | _clippedVertices [Side.RIGHT] = null; 241 | _clippedVertices = null; 242 | } 243 | _sites [Side.LEFT] = null; 244 | _sites [Side.RIGHT] = null; 245 | _sites = null; 246 | 247 | _pool.Push (this); 248 | } 249 | 250 | private Edge () 251 | { 252 | // if (lock != PrivateConstructorEnforcer) 253 | // { 254 | // throw new Error("Edge: constructor is private"); 255 | // } 256 | 257 | _edgeIndex = _nedges++; 258 | Init (); 259 | } 260 | 261 | private void Init () 262 | { 263 | _sites = new Dictionary (); 264 | } 265 | 266 | public override string ToString () 267 | { 268 | return "Edge " + _edgeIndex.ToString () + "; sites " + _sites [Side.LEFT].ToString () + ", " + _sites [Side.RIGHT].ToString () 269 | + "; endVertices " + ((_leftVertex != null) ? _leftVertex.vertexIndex.ToString () : "null") + ", " 270 | + ((_rightVertex != null) ? _rightVertex.vertexIndex.ToString () : "null") + "::"; 271 | } 272 | 273 | /** 274 | * Set _clippedVertices to contain the two ends of the portion of the Voronoi edge that is visible 275 | * within the bounds. If no part of the Edge falls within the bounds, leave _clippedVertices null. 276 | * @param bounds 277 | * 278 | */ 279 | public void ClipVertices (Rect bounds) 280 | { 281 | float xmin = bounds.xMin; 282 | float ymin = bounds.yMin; 283 | float xmax = bounds.xMax; 284 | float ymax = bounds.yMax; 285 | 286 | Vertex vertex0, vertex1; 287 | float x0, x1, y0, y1; 288 | 289 | if (a == 1.0 && b >= 0.0) { 290 | vertex0 = _rightVertex; 291 | vertex1 = _leftVertex; 292 | } else { 293 | vertex0 = _leftVertex; 294 | vertex1 = _rightVertex; 295 | } 296 | 297 | if (a == 1.0) { 298 | y0 = ymin; 299 | if (vertex0 != null && vertex0.y > ymin) { 300 | y0 = vertex0.y; 301 | } 302 | if (y0 > ymax) { 303 | return; 304 | } 305 | x0 = c - b * y0; 306 | 307 | y1 = ymax; 308 | if (vertex1 != null && vertex1.y < ymax) { 309 | y1 = vertex1.y; 310 | } 311 | if (y1 < ymin) { 312 | return; 313 | } 314 | x1 = c - b * y1; 315 | 316 | if ((x0 > xmax && x1 > xmax) || (x0 < xmin && x1 < xmin)) { 317 | return; 318 | } 319 | 320 | if (x0 > xmax) { 321 | x0 = xmax; 322 | y0 = (c - x0) / b; 323 | } else if (x0 < xmin) { 324 | x0 = xmin; 325 | y0 = (c - x0) / b; 326 | } 327 | 328 | if (x1 > xmax) { 329 | x1 = xmax; 330 | y1 = (c - x1) / b; 331 | } else if (x1 < xmin) { 332 | x1 = xmin; 333 | y1 = (c - x1) / b; 334 | } 335 | } else { 336 | x0 = xmin; 337 | if (vertex0 != null && vertex0.x > xmin) { 338 | x0 = vertex0.x; 339 | } 340 | if (x0 > xmax) { 341 | return; 342 | } 343 | y0 = c - a * x0; 344 | 345 | x1 = xmax; 346 | if (vertex1 != null && vertex1.x < xmax) { 347 | x1 = vertex1.x; 348 | } 349 | if (x1 < xmin) { 350 | return; 351 | } 352 | y1 = c - a * x1; 353 | 354 | if ((y0 > ymax && y1 > ymax) || (y0 < ymin && y1 < ymin)) { 355 | return; 356 | } 357 | 358 | if (y0 > ymax) { 359 | y0 = ymax; 360 | x0 = (c - y0) / a; 361 | } else if (y0 < ymin) { 362 | y0 = ymin; 363 | x0 = (c - y0) / a; 364 | } 365 | 366 | if (y1 > ymax) { 367 | y1 = ymax; 368 | x1 = (c - y1) / a; 369 | } else if (y1 < ymin) { 370 | y1 = ymin; 371 | x1 = (c - y1) / a; 372 | } 373 | } 374 | 375 | // _clippedVertices = new Dictionary(true); // XXX: Weak ref'd dict might be a problem to use standard 376 | _clippedVertices = new Dictionary> (); 377 | if (vertex0 == _leftVertex) { 378 | _clippedVertices [Side.LEFT] = new Vector2 (x0, y0); 379 | _clippedVertices [Side.RIGHT] = new Vector2 (x1, y1); 380 | } else { 381 | _clippedVertices [Side.RIGHT] = new Vector2 (x0, y0); 382 | _clippedVertices [Side.LEFT] = new Vector2 (x1, y1); 383 | } 384 | } 385 | 386 | } 387 | } 388 | 389 | //class PrivateConstructorEnforcer {} -------------------------------------------------------------------------------- /Assets/Delaunay/Unity-delaunay/Delaunay/Edge.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 49202b1d309f140d6bd015a7fbce4b64 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/Delaunay/Unity-delaunay/Delaunay/EdgeList.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using Delaunay.Utils; 3 | 4 | namespace Delaunay 5 | { 6 | 7 | internal sealed class EdgeList: Utils.IDisposable 8 | { 9 | private float _deltax; 10 | private float _xmin; 11 | 12 | private int _hashsize; 13 | private Halfedge[] _hash; 14 | private Halfedge _leftEnd; 15 | public Halfedge leftEnd { 16 | get { return _leftEnd;} 17 | } 18 | private Halfedge _rightEnd; 19 | public Halfedge rightEnd { 20 | get { return _rightEnd;} 21 | } 22 | 23 | public void Dispose () 24 | { 25 | Halfedge halfEdge = _leftEnd; 26 | Halfedge prevHe; 27 | while (halfEdge != _rightEnd) { 28 | prevHe = halfEdge; 29 | halfEdge = halfEdge.edgeListRightNeighbor; 30 | prevHe.Dispose (); 31 | } 32 | _leftEnd = null; 33 | _rightEnd.Dispose (); 34 | _rightEnd = null; 35 | 36 | int i; 37 | for (i = 0; i < _hashsize; ++i) { 38 | _hash [i] = null; 39 | } 40 | _hash = null; 41 | } 42 | 43 | public EdgeList (float xmin, float deltax, int sqrt_nsites) 44 | { 45 | _xmin = xmin; 46 | _deltax = deltax; 47 | _hashsize = 2 * sqrt_nsites; 48 | 49 | _hash = new Halfedge[_hashsize]; 50 | 51 | // two dummy Halfedges: 52 | _leftEnd = Halfedge.CreateDummy (); 53 | _rightEnd = Halfedge.CreateDummy (); 54 | _leftEnd.edgeListLeftNeighbor = null; 55 | _leftEnd.edgeListRightNeighbor = _rightEnd; 56 | _rightEnd.edgeListLeftNeighbor = _leftEnd; 57 | _rightEnd.edgeListRightNeighbor = null; 58 | _hash [0] = _leftEnd; 59 | _hash [_hashsize - 1] = _rightEnd; 60 | } 61 | 62 | /** 63 | * Insert newHalfedge to the right of lb 64 | * @param lb 65 | * @param newHalfedge 66 | * 67 | */ 68 | public void Insert (Halfedge lb, Halfedge newHalfedge) 69 | { 70 | newHalfedge.edgeListLeftNeighbor = lb; 71 | newHalfedge.edgeListRightNeighbor = lb.edgeListRightNeighbor; 72 | lb.edgeListRightNeighbor.edgeListLeftNeighbor = newHalfedge; 73 | lb.edgeListRightNeighbor = newHalfedge; 74 | } 75 | 76 | /** 77 | * This function only removes the Halfedge from the left-right list. 78 | * We cannot dispose it yet because we are still using it. 79 | * @param halfEdge 80 | * 81 | */ 82 | public void Remove (Halfedge halfEdge) 83 | { 84 | halfEdge.edgeListLeftNeighbor.edgeListRightNeighbor = halfEdge.edgeListRightNeighbor; 85 | halfEdge.edgeListRightNeighbor.edgeListLeftNeighbor = halfEdge.edgeListLeftNeighbor; 86 | halfEdge.edge = Edge.DELETED; 87 | halfEdge.edgeListLeftNeighbor = halfEdge.edgeListRightNeighbor = null; 88 | } 89 | 90 | /** 91 | * Find the rightmost Halfedge that is still left of p 92 | * @param p 93 | * @return 94 | * 95 | */ 96 | public Halfedge EdgeListLeftNeighbor (Vector2 p) 97 | { 98 | int i, bucket; 99 | Halfedge halfEdge; 100 | 101 | /* Use hash table to get close to desired halfedge */ 102 | bucket = (int)((p.x - _xmin) / _deltax * _hashsize); 103 | if (bucket < 0) { 104 | bucket = 0; 105 | } 106 | if (bucket >= _hashsize) { 107 | bucket = _hashsize - 1; 108 | } 109 | halfEdge = GetHash (bucket); 110 | if (halfEdge == null) { 111 | for (i = 1; true; ++i) { 112 | if ((halfEdge = GetHash (bucket - i)) != null) 113 | break; 114 | if ((halfEdge = GetHash (bucket + i)) != null) 115 | break; 116 | } 117 | } 118 | /* Now search linear list of halfedges for the correct one */ 119 | if (halfEdge == leftEnd || (halfEdge != rightEnd && halfEdge.IsLeftOf (p))) { 120 | do { 121 | halfEdge = halfEdge.edgeListRightNeighbor; 122 | } while (halfEdge != rightEnd && halfEdge.IsLeftOf(p)); 123 | halfEdge = halfEdge.edgeListLeftNeighbor; 124 | } else { 125 | do { 126 | halfEdge = halfEdge.edgeListLeftNeighbor; 127 | } while (halfEdge != leftEnd && !halfEdge.IsLeftOf(p)); 128 | } 129 | 130 | /* Update hash table and reference counts */ 131 | if (bucket > 0 && bucket < _hashsize - 1) { 132 | _hash [bucket] = halfEdge; 133 | } 134 | return halfEdge; 135 | } 136 | 137 | /* Get entry from hash table, pruning any deleted nodes */ 138 | private Halfedge GetHash (int b) 139 | { 140 | Halfedge halfEdge; 141 | 142 | if (b < 0 || b >= _hashsize) { 143 | return null; 144 | } 145 | halfEdge = _hash [b]; 146 | if (halfEdge != null && halfEdge.edge == Edge.DELETED) { 147 | /* Hash table points to deleted halfedge. Patch as necessary. */ 148 | _hash [b] = null; 149 | // still can't dispose halfEdge yet! 150 | return null; 151 | } else { 152 | return halfEdge; 153 | } 154 | } 155 | 156 | } 157 | } -------------------------------------------------------------------------------- /Assets/Delaunay/Unity-delaunay/Delaunay/EdgeList.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 0f2bfd7ed370844afb774f34e1d6366a 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/Delaunay/Unity-delaunay/Delaunay/EdgeReorderer.cs: -------------------------------------------------------------------------------- 1 | using Delaunay.LR; 2 | using Delaunay.Utils; 3 | using System.Collections.Generic; 4 | 5 | namespace Delaunay 6 | { 7 | public enum VertexOrSite 8 | { 9 | VERTEX, 10 | SITE 11 | } 12 | 13 | sealed class EdgeReorderer: Utils.IDisposable 14 | { 15 | private List _edges; 16 | private List _edgeOrientations; 17 | public List edges { 18 | get { return _edges;} 19 | } 20 | public List edgeOrientations { 21 | get{ return _edgeOrientations;} 22 | } 23 | 24 | public EdgeReorderer (List origEdges, VertexOrSite criterion) 25 | { 26 | _edges = new List (); 27 | _edgeOrientations = new List (); 28 | if (origEdges.Count > 0) { 29 | _edges = ReorderEdges (origEdges, criterion); 30 | } 31 | } 32 | 33 | public void Dispose () 34 | { 35 | _edges = null; 36 | _edgeOrientations = null; 37 | } 38 | 39 | private List ReorderEdges (List origEdges, VertexOrSite criterion) 40 | { 41 | int i; 42 | int n = origEdges.Count; 43 | Edge edge; 44 | // we're going to reorder the edges in order of traversal 45 | bool[] done = new bool[n]; 46 | int nDone = 0; 47 | for (int j=0; j newEdges = new List (); // TODO: Switch to Deque if performance is a concern 51 | 52 | i = 0; 53 | edge = origEdges [i]; 54 | newEdges.Add (edge); 55 | _edgeOrientations.Add (Side.LEFT); 56 | ICoord firstPoint = (criterion == VertexOrSite.VERTEX) ? (ICoord)edge.leftVertex : (ICoord)edge.leftSite; 57 | ICoord lastPoint = (criterion == VertexOrSite.VERTEX) ? (ICoord)edge.rightVertex : (ICoord)edge.rightSite; 58 | 59 | if (firstPoint == Vertex.VERTEX_AT_INFINITY || lastPoint == Vertex.VERTEX_AT_INFINITY) { 60 | return new List (); 61 | } 62 | 63 | done [i] = true; 64 | ++nDone; 65 | 66 | while (nDone < n) { 67 | for (i = 1; i < n; ++i) { 68 | if (done [i]) { 69 | continue; 70 | } 71 | edge = origEdges [i]; 72 | ICoord leftPoint = (criterion == VertexOrSite.VERTEX) ? (ICoord)edge.leftVertex : (ICoord)edge.leftSite; 73 | ICoord rightPoint = (criterion == VertexOrSite.VERTEX) ? (ICoord)edge.rightVertex : (ICoord)edge.rightSite; 74 | if (leftPoint == Vertex.VERTEX_AT_INFINITY || rightPoint == Vertex.VERTEX_AT_INFINITY) { 75 | return new List (); 76 | } 77 | if (leftPoint == lastPoint) { 78 | lastPoint = rightPoint; 79 | _edgeOrientations.Add (Side.LEFT); 80 | newEdges.Add (edge); 81 | done [i] = true; 82 | } else if (rightPoint == firstPoint) { 83 | firstPoint = leftPoint; 84 | _edgeOrientations.Insert (0, Side.LEFT); // TODO: Change datastructure if this is slow 85 | newEdges.Insert (0, edge); 86 | done [i] = true; 87 | } else if (leftPoint == firstPoint) { 88 | firstPoint = rightPoint; 89 | _edgeOrientations.Insert (0, Side.RIGHT); 90 | newEdges.Insert (0, edge); 91 | done [i] = true; 92 | } else if (rightPoint == lastPoint) { 93 | lastPoint = leftPoint; 94 | _edgeOrientations.Add (Side.RIGHT); 95 | newEdges.Add (edge); 96 | done [i] = true; 97 | } 98 | if (done [i]) { 99 | ++nDone; 100 | } 101 | } 102 | } 103 | 104 | return newEdges; 105 | } 106 | 107 | } 108 | } -------------------------------------------------------------------------------- /Assets/Delaunay/Unity-delaunay/Delaunay/EdgeReorderer.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a6e9c0c7f4ae649678b34ec5397e4079 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/Delaunay/Unity-delaunay/Delaunay/Halfedge.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System; 3 | using System.Collections.Generic; 4 | using Delaunay.LR; 5 | using Delaunay.Geo; 6 | using Delaunay.Utils; 7 | 8 | namespace Delaunay 9 | { 10 | 11 | 12 | public sealed class Halfedge: Delaunay.Utils.IDisposable 13 | { 14 | private static Stack _pool = new Stack (); 15 | public static Halfedge Create (Edge edge, Nullable lr) 16 | { 17 | if (_pool.Count > 0) { 18 | return _pool.Pop ().Init (edge, lr); 19 | } else { 20 | return new Halfedge (edge, lr); 21 | } 22 | } 23 | 24 | public static Halfedge CreateDummy () 25 | { 26 | return Create (null, null); 27 | } 28 | 29 | public Halfedge edgeListLeftNeighbor, edgeListRightNeighbor; 30 | public Halfedge nextInPriorityQueue; 31 | 32 | public Edge edge; 33 | public Nullable leftRight; 34 | public Vertex vertex; 35 | 36 | // the vertex's y-coordinate in the transformed Voronoi space V* 37 | public float ystar; 38 | 39 | public Halfedge (Edge edge = null, Nullable lr = null) 40 | { 41 | Init (edge, lr); 42 | } 43 | 44 | private Halfedge Init (Edge edge, Nullable lr) 45 | { 46 | this.edge = edge; 47 | leftRight = lr; 48 | nextInPriorityQueue = null; 49 | vertex = null; 50 | return this; 51 | } 52 | 53 | public override string ToString () 54 | { 55 | return "Halfedge (leftRight: " + leftRight.ToString () + "; vertex: " + vertex.ToString () + ")"; 56 | } 57 | 58 | public void Dispose () 59 | { 60 | if (edgeListLeftNeighbor != null || edgeListRightNeighbor != null) { 61 | // still in EdgeList 62 | return; 63 | } 64 | if (nextInPriorityQueue != null) { 65 | // still in PriorityQueue 66 | return; 67 | } 68 | edge = null; 69 | leftRight = null; 70 | vertex = null; 71 | _pool.Push (this); 72 | } 73 | 74 | public void ReallyDispose () 75 | { 76 | edgeListLeftNeighbor = null; 77 | edgeListRightNeighbor = null; 78 | nextInPriorityQueue = null; 79 | edge = null; 80 | leftRight = null; 81 | vertex = null; 82 | _pool.Push (this); 83 | } 84 | 85 | internal bool IsLeftOf (Vector2 p) 86 | { 87 | Site topSite; 88 | bool rightOfSite, above, fast; 89 | float dxp, dyp, dxs, t1, t2, t3, yl; 90 | 91 | topSite = edge.rightSite; 92 | rightOfSite = p.x > topSite.x; 93 | if (rightOfSite && this.leftRight == Side.LEFT) { 94 | return true; 95 | } 96 | if (!rightOfSite && this.leftRight == Side.RIGHT) { 97 | return false; 98 | } 99 | 100 | if (edge.a == 1.0) { 101 | dyp = p.y - topSite.y; 102 | dxp = p.x - topSite.x; 103 | fast = false; 104 | if ((!rightOfSite && edge.b < 0.0) || (rightOfSite && edge.b >= 0.0)) { 105 | above = dyp >= edge.b * dxp; 106 | fast = above; 107 | } else { 108 | above = p.x + p.y * edge.b > edge.c; 109 | if (edge.b < 0.0) { 110 | above = !above; 111 | } 112 | if (!above) { 113 | fast = true; 114 | } 115 | } 116 | if (!fast) { 117 | dxs = topSite.x - edge.leftSite.x; 118 | above = edge.b * (dxp * dxp - dyp * dyp) < 119 | dxs * dyp * (1.0 + 2.0 * dxp / dxs + edge.b * edge.b); 120 | if (edge.b < 0.0) { 121 | above = !above; 122 | } 123 | } 124 | } else { /* edge.b == 1.0 */ 125 | yl = edge.c - edge.a * p.x; 126 | t1 = p.y - yl; 127 | t2 = p.x - topSite.x; 128 | t3 = yl - topSite.y; 129 | above = t1 * t1 > t2 * t2 + t3 * t3; 130 | } 131 | return this.leftRight == Side.LEFT ? above : !above; 132 | } 133 | 134 | } 135 | } -------------------------------------------------------------------------------- /Assets/Delaunay/Unity-delaunay/Delaunay/Halfedge.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e873e30775b564fbd9b4b27ac5b0787a 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/Delaunay/Unity-delaunay/Delaunay/HalfedgePriorityQueue.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System.Collections.Generic; 3 | using Delaunay.Utils; 4 | 5 | namespace Delaunay 6 | { 7 | 8 | internal sealed class HalfedgePriorityQueue: Utils.IDisposable // also known as heap 9 | { 10 | private Halfedge[] _hash; 11 | private int _count; 12 | private int _minBucket; 13 | private int _hashsize; 14 | 15 | private float _ymin; 16 | private float _deltay; 17 | 18 | public HalfedgePriorityQueue (float ymin, float deltay, int sqrt_nsites) 19 | { 20 | _ymin = ymin; 21 | _deltay = deltay; 22 | _hashsize = 4 * sqrt_nsites; 23 | Initialize (); 24 | } 25 | 26 | public void Dispose () 27 | { 28 | // get rid of dummies 29 | for (int i = 0; i < _hashsize; ++i) { 30 | _hash [i].Dispose (); 31 | _hash [i] = null; 32 | } 33 | _hash = null; 34 | } 35 | 36 | private void Initialize () 37 | { 38 | int i; 39 | 40 | _count = 0; 41 | _minBucket = 0; 42 | _hash = new Halfedge[_hashsize]; 43 | // dummy Halfedge at the top of each hash 44 | for (i = 0; i < _hashsize; ++i) { 45 | _hash [i] = Halfedge.CreateDummy (); 46 | _hash [i].nextInPriorityQueue = null; 47 | } 48 | } 49 | 50 | public void Insert (Halfedge halfEdge) 51 | { 52 | Halfedge previous, next; 53 | int insertionBucket = Bucket (halfEdge); 54 | if (insertionBucket < _minBucket) { 55 | _minBucket = insertionBucket; 56 | } 57 | previous = _hash [insertionBucket]; 58 | while ((next = previous.nextInPriorityQueue) != null 59 | && (halfEdge.ystar > next.ystar || (halfEdge.ystar == next.ystar && halfEdge.vertex.x > next.vertex.x))) { 60 | previous = next; 61 | } 62 | halfEdge.nextInPriorityQueue = previous.nextInPriorityQueue; 63 | previous.nextInPriorityQueue = halfEdge; 64 | ++_count; 65 | } 66 | 67 | public void Remove (Halfedge halfEdge) 68 | { 69 | Halfedge previous; 70 | int removalBucket = Bucket (halfEdge); 71 | 72 | if (halfEdge.vertex != null) { 73 | previous = _hash [removalBucket]; 74 | while (previous.nextInPriorityQueue != halfEdge) { 75 | previous = previous.nextInPriorityQueue; 76 | } 77 | previous.nextInPriorityQueue = halfEdge.nextInPriorityQueue; 78 | _count--; 79 | halfEdge.vertex = null; 80 | halfEdge.nextInPriorityQueue = null; 81 | halfEdge.Dispose (); 82 | } 83 | } 84 | 85 | private int Bucket (Halfedge halfEdge) 86 | { 87 | int theBucket = (int)((halfEdge.ystar - _ymin) / _deltay * _hashsize); 88 | if (theBucket < 0) 89 | theBucket = 0; 90 | if (theBucket >= _hashsize) 91 | theBucket = _hashsize - 1; 92 | return theBucket; 93 | } 94 | 95 | private bool IsEmpty (int bucket) 96 | { 97 | return (_hash [bucket].nextInPriorityQueue == null); 98 | } 99 | 100 | /** 101 | * move _minBucket until it contains an actual Halfedge (not just the dummy at the top); 102 | * 103 | */ 104 | private void AdjustMinBucket () 105 | { 106 | while (_minBucket < _hashsize - 1 && IsEmpty(_minBucket)) { 107 | ++_minBucket; 108 | } 109 | } 110 | 111 | public bool Empty () 112 | { 113 | return _count == 0; 114 | } 115 | 116 | /** 117 | * @return coordinates of the Halfedge's vertex in V*, the transformed Voronoi diagram 118 | * 119 | */ 120 | public Vector2 Min () 121 | { 122 | AdjustMinBucket (); 123 | Halfedge answer = _hash [_minBucket].nextInPriorityQueue; 124 | return new Vector2 (answer.vertex.x, answer.ystar); 125 | } 126 | 127 | /** 128 | * remove and return the min Halfedge 129 | * @return 130 | * 131 | */ 132 | public Halfedge ExtractMin () 133 | { 134 | Halfedge answer; 135 | 136 | // get the first real Halfedge in _minBucket 137 | answer = _hash [_minBucket].nextInPriorityQueue; 138 | 139 | _hash [_minBucket].nextInPriorityQueue = answer.nextInPriorityQueue; 140 | _count--; 141 | answer.nextInPriorityQueue = null; 142 | 143 | return answer; 144 | } 145 | 146 | } 147 | } -------------------------------------------------------------------------------- /Assets/Delaunay/Unity-delaunay/Delaunay/HalfedgePriorityQueue.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6ba85128b77e245478cd4bc1ac6c8f60 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/Delaunay/Unity-delaunay/Delaunay/ICoord.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | namespace Delaunay 4 | { 5 | 6 | public interface ICoord 7 | { 8 | Vector2 Coord { 9 | get; 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /Assets/Delaunay/Unity-delaunay/Delaunay/ICoord.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6a0a816d1340149068ec7fa5bc31c72c 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/Delaunay/Unity-delaunay/Delaunay/LR.cs: -------------------------------------------------------------------------------- 1 | namespace Delaunay 2 | { 3 | namespace LR 4 | { 5 | public enum Side 6 | { 7 | LEFT = 0, 8 | RIGHT 9 | } 10 | 11 | public class SideHelper 12 | { 13 | public static Side Other (Side leftRight) 14 | { 15 | return leftRight == Side.LEFT ? Side.RIGHT : Side.LEFT; 16 | } 17 | } 18 | 19 | } 20 | } -------------------------------------------------------------------------------- /Assets/Delaunay/Unity-delaunay/Delaunay/LR.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 42741f042d2e748aaaf15e94b6ba71dd 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/Delaunay/Unity-delaunay/Delaunay/Site.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System; 3 | using System.Collections.Generic; 4 | using Delaunay.Geo; 5 | using Delaunay.LR; 6 | 7 | namespace Delaunay 8 | { 9 | 10 | public sealed class Site: ICoord, IComparable 11 | { 12 | private static Stack _pool = new Stack (); 13 | public static Site Create (Vector2 p, uint index, float weight, uint color) 14 | { 15 | if (_pool.Count > 0) { 16 | return _pool.Pop ().Init (p, index, weight, color); 17 | } else { 18 | return new Site (p, index, weight, color); 19 | } 20 | } 21 | 22 | internal static void SortSites (List sites) 23 | { 24 | // sites.sort(Site.compare); 25 | sites.Sort (); // XXX: Check if this works 26 | } 27 | 28 | /** 29 | * sort sites on y, then x, coord 30 | * also change each site's _siteIndex to match its new position in the list 31 | * so the _siteIndex can be used to identify the site for nearest-neighbor queries 32 | * 33 | * haha "also" - means more than one responsibility... 34 | * 35 | */ 36 | public int CompareTo (System.Object obj) // XXX: Really, really worried about this because it depends on how sorting works in AS3 impl - Julian 37 | { 38 | Site s2 = (Site)obj; 39 | 40 | int returnValue = Voronoi.CompareByYThenX (this, s2); 41 | 42 | // swap _siteIndex values if necessary to match new ordering: 43 | uint tempIndex; 44 | if (returnValue == -1) { 45 | if (this._siteIndex > s2._siteIndex) { 46 | tempIndex = this._siteIndex; 47 | this._siteIndex = s2._siteIndex; 48 | s2._siteIndex = tempIndex; 49 | } 50 | } else if (returnValue == 1) { 51 | if (s2._siteIndex > this._siteIndex) { 52 | tempIndex = s2._siteIndex; 53 | s2._siteIndex = this._siteIndex; 54 | this._siteIndex = tempIndex; 55 | } 56 | 57 | } 58 | 59 | return returnValue; 60 | } 61 | 62 | 63 | private static readonly float EPSILON = .005f; 64 | private static bool CloseEnough (Vector2 p0, Vector2 p1) 65 | { 66 | return Vector2.Distance (p0, p1) < EPSILON; 67 | } 68 | 69 | private Vector2 _coord; 70 | public Vector2 Coord { 71 | get { return _coord;} 72 | } 73 | 74 | public uint color; 75 | public float weight; 76 | 77 | private uint _siteIndex; 78 | 79 | // the edges that define this Site's Voronoi region: 80 | private List _edges; 81 | internal List edges { 82 | get { return _edges;} 83 | } 84 | // which end of each edge hooks up with the previous edge in _edges: 85 | private List _edgeOrientations; 86 | // ordered list of points that define the region clipped to bounds: 87 | private List _region; 88 | 89 | private Site (Vector2 p, uint index, float weight, uint color) 90 | { 91 | // if (lock != PrivateConstructorEnforcer) 92 | // { 93 | // throw new Error("Site constructor is private"); 94 | // } 95 | Init (p, index, weight, color); 96 | } 97 | 98 | private Site Init (Vector2 p, uint index, float weight, uint color) 99 | { 100 | _coord = p; 101 | _siteIndex = index; 102 | this.weight = weight; 103 | this.color = color; 104 | _edges = new List (); 105 | _region = null; 106 | return this; 107 | } 108 | 109 | public override string ToString () 110 | { 111 | return "Site " + _siteIndex.ToString () + ": " + Coord.ToString (); 112 | } 113 | 114 | private void Move (Vector2 p) 115 | { 116 | Clear (); 117 | _coord = p; 118 | } 119 | 120 | public void Dispose () 121 | { 122 | // _coord = null; 123 | Clear (); 124 | _pool.Push (this); 125 | } 126 | 127 | private void Clear () 128 | { 129 | if (_edges != null) { 130 | _edges.Clear (); 131 | _edges = null; 132 | } 133 | if (_edgeOrientations != null) { 134 | _edgeOrientations.Clear (); 135 | _edgeOrientations = null; 136 | } 137 | if (_region != null) { 138 | _region.Clear (); 139 | _region = null; 140 | } 141 | } 142 | 143 | public void AddEdge (Edge edge) 144 | { 145 | _edges.Add (edge); 146 | } 147 | 148 | public Edge NearestEdge () 149 | { 150 | _edges.Sort (delegate (Edge a, Edge b) { 151 | return Edge.CompareSitesDistances (a, b); 152 | }); 153 | return _edges [0]; 154 | } 155 | 156 | public List NeighborSites () 157 | { 158 | if (_edges == null || _edges.Count == 0) { 159 | return new List (); 160 | } 161 | if (_edgeOrientations == null) { 162 | ReorderEdges (); 163 | } 164 | List list = new List (); 165 | Edge edge; 166 | for (int i = 0; i < _edges.Count; i++) { 167 | edge = _edges [i]; 168 | list.Add (NeighborSite (edge)); 169 | } 170 | return list; 171 | } 172 | 173 | private Site NeighborSite (Edge edge) 174 | { 175 | if (this == edge.leftSite) { 176 | return edge.rightSite; 177 | } 178 | if (this == edge.rightSite) { 179 | return edge.leftSite; 180 | } 181 | return null; 182 | } 183 | 184 | internal List Region (Rect clippingBounds) 185 | { 186 | if (_edges == null || _edges.Count == 0) { 187 | return new List (); 188 | } 189 | if (_edgeOrientations == null) { 190 | ReorderEdges (); 191 | _region = ClipToBounds (clippingBounds); 192 | if ((new Polygon (_region)).Winding () == Winding.CLOCKWISE) { 193 | _region.Reverse (); 194 | } 195 | } 196 | return _region; 197 | } 198 | 199 | private void ReorderEdges () 200 | { 201 | //trace("_edges:", _edges); 202 | EdgeReorderer reorderer = new EdgeReorderer (_edges, VertexOrSite.VERTEX); 203 | _edges = reorderer.edges; 204 | //trace("reordered:", _edges); 205 | _edgeOrientations = reorderer.edgeOrientations; 206 | reorderer.Dispose (); 207 | } 208 | 209 | private List ClipToBounds (Rect bounds) 210 | { 211 | List points = new List (); 212 | int n = _edges.Count; 213 | int i = 0; 214 | Edge edge; 215 | while (i < n && ((_edges[i] as Edge).visible == false)) { 216 | ++i; 217 | } 218 | 219 | if (i == n) { 220 | // no edges visible 221 | return new List (); 222 | } 223 | edge = _edges [i]; 224 | Side orientation = _edgeOrientations [i]; 225 | 226 | if (edge.clippedEnds [orientation] == null) { 227 | Debug.LogError ("XXX: Null detected when there should be a Vector2!"); 228 | } 229 | if (edge.clippedEnds [SideHelper.Other (orientation)] == null) { 230 | Debug.LogError ("XXX: Null detected when there should be a Vector2!"); 231 | } 232 | points.Add ((Vector2)edge.clippedEnds [orientation]); 233 | points.Add ((Vector2)edge.clippedEnds [SideHelper.Other (orientation)]); 234 | 235 | for (int j = i + 1; j < n; ++j) { 236 | edge = _edges [j]; 237 | if (edge.visible == false) { 238 | continue; 239 | } 240 | Connect (points, j, bounds); 241 | } 242 | // close up the polygon by adding another corner point of the bounds if needed: 243 | Connect (points, i, bounds, true); 244 | 245 | return points; 246 | } 247 | 248 | private void Connect (List points, int j, Rect bounds, bool closingUp = false) 249 | { 250 | Vector2 rightPoint = points [points.Count - 1]; 251 | Edge newEdge = _edges [j] as Edge; 252 | Side newOrientation = _edgeOrientations [j]; 253 | // the point that must be connected to rightPoint: 254 | if (newEdge.clippedEnds [newOrientation] == null) { 255 | Debug.LogError ("XXX: Null detected when there should be a Vector2!"); 256 | } 257 | Vector2 newPoint = (Vector2)newEdge.clippedEnds [newOrientation]; 258 | if (!CloseEnough (rightPoint, newPoint)) { 259 | // The points do not coincide, so they must have been clipped at the bounds; 260 | // see if they are on the same border of the bounds: 261 | if (rightPoint.x != newPoint.x 262 | && rightPoint.y != newPoint.y) { 263 | // They are on different borders of the bounds; 264 | // insert one or two corners of bounds as needed to hook them up: 265 | // (NOTE this will not be correct if the region should take up more than 266 | // half of the bounds rect, for then we will have gone the wrong way 267 | // around the bounds and included the smaller part rather than the larger) 268 | int rightCheck = BoundsCheck.Check (rightPoint, bounds); 269 | int newCheck = BoundsCheck.Check (newPoint, bounds); 270 | float px, py; 271 | if ((rightCheck & BoundsCheck.RIGHT) != 0) { 272 | px = bounds.xMax; 273 | if ((newCheck & BoundsCheck.BOTTOM) != 0) { 274 | py = bounds.yMax; 275 | points.Add (new Vector2 (px, py)); 276 | } else if ((newCheck & BoundsCheck.TOP) != 0) { 277 | py = bounds.yMin; 278 | points.Add (new Vector2 (px, py)); 279 | } else if ((newCheck & BoundsCheck.LEFT) != 0) { 280 | if (rightPoint.y - bounds.y + newPoint.y - bounds.y < bounds.height) { 281 | py = bounds.yMin; 282 | } else { 283 | py = bounds.yMax; 284 | } 285 | points.Add (new Vector2 (px, py)); 286 | points.Add (new Vector2 (bounds.xMin, py)); 287 | } 288 | } else if ((rightCheck & BoundsCheck.LEFT) != 0) { 289 | px = bounds.xMin; 290 | if ((newCheck & BoundsCheck.BOTTOM) != 0) { 291 | py = bounds.yMax; 292 | points.Add (new Vector2 (px, py)); 293 | } else if ((newCheck & BoundsCheck.TOP) != 0) { 294 | py = bounds.yMin; 295 | points.Add (new Vector2 (px, py)); 296 | } else if ((newCheck & BoundsCheck.RIGHT) != 0) { 297 | if (rightPoint.y - bounds.y + newPoint.y - bounds.y < bounds.height) { 298 | py = bounds.yMin; 299 | } else { 300 | py = bounds.yMax; 301 | } 302 | points.Add (new Vector2 (px, py)); 303 | points.Add (new Vector2 (bounds.xMax, py)); 304 | } 305 | } else if ((rightCheck & BoundsCheck.TOP) != 0) { 306 | py = bounds.yMin; 307 | if ((newCheck & BoundsCheck.RIGHT) != 0) { 308 | px = bounds.xMax; 309 | points.Add (new Vector2 (px, py)); 310 | } else if ((newCheck & BoundsCheck.LEFT) != 0) { 311 | px = bounds.xMin; 312 | points.Add (new Vector2 (px, py)); 313 | } else if ((newCheck & BoundsCheck.BOTTOM) != 0) { 314 | if (rightPoint.x - bounds.x + newPoint.x - bounds.x < bounds.width) { 315 | px = bounds.xMin; 316 | } else { 317 | px = bounds.xMax; 318 | } 319 | points.Add (new Vector2 (px, py)); 320 | points.Add (new Vector2 (px, bounds.yMax)); 321 | } 322 | } else if ((rightCheck & BoundsCheck.BOTTOM) != 0) { 323 | py = bounds.yMax; 324 | if ((newCheck & BoundsCheck.RIGHT) != 0) { 325 | px = bounds.xMax; 326 | points.Add (new Vector2 (px, py)); 327 | } else if ((newCheck & BoundsCheck.LEFT) != 0) { 328 | px = bounds.xMin; 329 | points.Add (new Vector2 (px, py)); 330 | } else if ((newCheck & BoundsCheck.TOP) != 0) { 331 | if (rightPoint.x - bounds.x + newPoint.x - bounds.x < bounds.width) { 332 | px = bounds.xMin; 333 | } else { 334 | px = bounds.xMax; 335 | } 336 | points.Add (new Vector2 (px, py)); 337 | points.Add (new Vector2 (px, bounds.yMin)); 338 | } 339 | } 340 | } 341 | if (closingUp) { 342 | // newEdge's ends have already been added 343 | return; 344 | } 345 | points.Add (newPoint); 346 | } 347 | if (newEdge.clippedEnds [SideHelper.Other (newOrientation)] == null) { 348 | Debug.LogError ("XXX: Null detected when there should be a Vector2!"); 349 | } 350 | Vector2 newRightPoint = (Vector2)newEdge.clippedEnds [SideHelper.Other (newOrientation)]; 351 | if (!CloseEnough (points [0], newRightPoint)) { 352 | points.Add (newRightPoint); 353 | } 354 | } 355 | 356 | public float x { 357 | get { return _coord.x;} 358 | } 359 | internal float y { 360 | get { return _coord.y;} 361 | } 362 | 363 | public float Dist (ICoord p) 364 | { 365 | return Vector2.Distance (p.Coord, this._coord); 366 | } 367 | 368 | } 369 | } 370 | 371 | // class PrivateConstructorEnforcer {} 372 | 373 | // import flash.geom.Point; 374 | // import flash.geom.Rectangle; 375 | 376 | static class BoundsCheck 377 | { 378 | public static readonly int TOP = 1; 379 | public static readonly int BOTTOM = 2; 380 | public static readonly int LEFT = 4; 381 | public static readonly int RIGHT = 8; 382 | 383 | /** 384 | * 385 | * @param point 386 | * @param bounds 387 | * @return an int with the appropriate bits set if the Point lies on the corresponding bounds lines 388 | * 389 | */ 390 | public static int Check (Vector2 point, Rect bounds) 391 | { 392 | int value = 0; 393 | if (point.x == bounds.xMin) { 394 | value |= LEFT; 395 | } 396 | if (point.x == bounds.xMax) { 397 | value |= RIGHT; 398 | } 399 | if (point.y == bounds.yMin) { 400 | value |= TOP; 401 | } 402 | if (point.y == bounds.yMax) { 403 | value |= BOTTOM; 404 | } 405 | return value; 406 | } 407 | } -------------------------------------------------------------------------------- /Assets/Delaunay/Unity-delaunay/Delaunay/Site.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: fa5d818389dce40d29f97fb47bf83081 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/Delaunay/Unity-delaunay/Delaunay/SiteList.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System; 3 | using System.Collections.Generic; 4 | using Delaunay.Geo; 5 | using Delaunay.Utils; 6 | 7 | namespace Delaunay 8 | { 9 | 10 | public sealed class SiteList: Utils.IDisposable 11 | { 12 | private List _sites; 13 | private int _currentIndex; 14 | 15 | private bool _sorted; 16 | 17 | public SiteList () 18 | { 19 | _sites = new List (); 20 | _sorted = false; 21 | } 22 | 23 | public void Dispose () 24 | { 25 | if (_sites != null) { 26 | for (int i = 0; i < _sites.Count; i++) { 27 | Site site = _sites [i]; 28 | site.Dispose (); 29 | } 30 | _sites.Clear (); 31 | _sites = null; 32 | } 33 | } 34 | 35 | public int Add (Site site) 36 | { 37 | _sorted = false; 38 | _sites.Add (site); 39 | return _sites.Count; 40 | } 41 | 42 | public int Count { 43 | get { return _sites.Count;} 44 | } 45 | 46 | public Site Next () 47 | { 48 | if (_sorted == false) { 49 | UnityEngine.Debug.LogError ("SiteList::next(): sites have not been sorted"); 50 | } 51 | if (_currentIndex < _sites.Count) { 52 | return _sites [_currentIndex++]; 53 | } else { 54 | return null; 55 | } 56 | } 57 | 58 | internal Rect GetSitesBounds () 59 | { 60 | if (_sorted == false) { 61 | Site.SortSites (_sites); 62 | _currentIndex = 0; 63 | _sorted = true; 64 | } 65 | float xmin, xmax, ymin, ymax; 66 | if (_sites.Count == 0) { 67 | return new Rect (0, 0, 0, 0); 68 | } 69 | xmin = float.MaxValue; 70 | xmax = float.MinValue; 71 | for (int i = 0; i<_sites.Count; i++) { 72 | Site site = _sites [i]; 73 | if (site.x < xmin) { 74 | xmin = site.x; 75 | } 76 | if (site.x > xmax) { 77 | xmax = site.x; 78 | } 79 | } 80 | // here's where we assume that the sites have been sorted on y: 81 | ymin = _sites [0].y; 82 | ymax = _sites [_sites.Count - 1].y; 83 | 84 | return new Rect (xmin, ymin, xmax - xmin, ymax - ymin); 85 | } 86 | 87 | public List SiteColors (/*BitmapData referenceImage = null*/) 88 | { 89 | List colors = new List (); 90 | Site site; 91 | for (int i = 0; i< _sites.Count; i++) { 92 | site = _sites [i]; 93 | colors.Add (/*referenceImage ? referenceImage.getPixel(site.x, site.y) :*/site.color); 94 | } 95 | return colors; 96 | } 97 | 98 | public List SiteCoords () 99 | { 100 | List coords = new List (); 101 | Site site; 102 | for (int i = 0; i<_sites.Count; i++) { 103 | site = _sites [i]; 104 | coords.Add (site.Coord); 105 | } 106 | return coords; 107 | } 108 | 109 | /** 110 | * 111 | * @return the largest circle centered at each site that fits in its region; 112 | * if the region is infinite, return a circle of radius 0. 113 | * 114 | */ 115 | public List Circles () 116 | { 117 | List circles = new List (); 118 | Site site; 119 | for (int i = 0; i<_sites.Count; i++) { 120 | site = _sites [i]; 121 | float radius = 0f; 122 | Edge nearestEdge = site.NearestEdge (); 123 | 124 | if (!nearestEdge.IsPartOfConvexHull ()) { 125 | radius = nearestEdge.SitesDistance () * 0.5f; 126 | } 127 | circles.Add (new Circle (site.x, site.y, radius)); 128 | } 129 | return circles; 130 | } 131 | 132 | public List> Regions (Rect plotBounds) 133 | { 134 | List> regions = new List> (); 135 | Site site; 136 | for (int i = 0; i< _sites.Count; i++) { 137 | site = _sites [i]; 138 | regions.Add (site.Region (plotBounds)); 139 | } 140 | return regions; 141 | } 142 | 143 | /** 144 | * 145 | * @param proximityMap a BitmapData whose regions are filled with the site index values; see PlanePointsCanvas::fillRegions() 146 | * @param x 147 | * @param y 148 | * @return coordinates of nearest Site to (x, y) 149 | * 150 | */ 151 | public Nullable NearestSitePoint (/*proximityMap:BitmapData,*/float x, float y) 152 | { 153 | // uint index = proximityMap.getPixel(x, y); 154 | // if (index > _sites.length - 1) 155 | // { 156 | return null; 157 | // } 158 | // return _sites[index].coord; 159 | } 160 | 161 | } 162 | } -------------------------------------------------------------------------------- /Assets/Delaunay/Unity-delaunay/Delaunay/SiteList.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d11fa694a445f4fbb9c6ef8f51d7d549 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/Delaunay/Unity-delaunay/Delaunay/Triangle.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using Delaunay.Utils; 3 | 4 | namespace Delaunay 5 | { 6 | 7 | public sealed class Triangle: IDisposable 8 | { 9 | private List _sites; 10 | public List sites { 11 | get { return this._sites; } 12 | } 13 | 14 | public Triangle (Site a, Site b, Site c) 15 | { 16 | _sites = new List () { a, b, c }; 17 | } 18 | 19 | public void Dispose () 20 | { 21 | _sites.Clear (); 22 | _sites = null; 23 | } 24 | 25 | } 26 | } -------------------------------------------------------------------------------- /Assets/Delaunay/Unity-delaunay/Delaunay/Triangle.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c86ee3287678f413e99d8256fcbbbd6f 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/Delaunay/Unity-delaunay/Delaunay/Vertex.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System; 3 | using System.Collections.Generic; 4 | using Delaunay.LR; 5 | 6 | namespace Delaunay 7 | { 8 | 9 | public sealed class Vertex: ICoord 10 | { 11 | public static readonly Vertex VERTEX_AT_INFINITY = new Vertex (float.NaN, float.NaN); 12 | 13 | private static Stack _pool = new Stack (); 14 | private static Vertex Create (float x, float y) 15 | { 16 | if (float.IsNaN (x) || float.IsNaN (y)) { 17 | return VERTEX_AT_INFINITY; 18 | } 19 | if (_pool.Count > 0) { 20 | return _pool.Pop ().Init (x, y); 21 | } else { 22 | return new Vertex (x, y); 23 | } 24 | } 25 | 26 | 27 | private static int _nvertices = 0; 28 | 29 | private Vector2 _coord; 30 | public Vector2 Coord { 31 | get { return _coord;} 32 | } 33 | private int _vertexIndex; 34 | public int vertexIndex { 35 | get { return _vertexIndex;} 36 | } 37 | 38 | public Vertex (float x, float y) 39 | { 40 | Init (x, y); 41 | } 42 | 43 | private Vertex Init (float x, float y) 44 | { 45 | _coord = new Vector2 (x, y); 46 | return this; 47 | } 48 | 49 | public void Dispose () 50 | { 51 | _pool.Push (this); 52 | } 53 | 54 | public void SetIndex () 55 | { 56 | _vertexIndex = _nvertices++; 57 | } 58 | 59 | public override string ToString () 60 | { 61 | return "Vertex (" + _vertexIndex + ")"; 62 | } 63 | 64 | /** 65 | * This is the only way to make a Vertex 66 | * 67 | * @param halfedge0 68 | * @param halfedge1 69 | * @return 70 | * 71 | */ 72 | public static Vertex Intersect (Halfedge halfedge0, Halfedge halfedge1) 73 | { 74 | Edge edge0, edge1, edge; 75 | Halfedge halfedge; 76 | float determinant, intersectionX, intersectionY; 77 | bool rightOfSite; 78 | 79 | edge0 = halfedge0.edge; 80 | edge1 = halfedge1.edge; 81 | if (edge0 == null || edge1 == null) { 82 | return null; 83 | } 84 | if (edge0.rightSite == edge1.rightSite) { 85 | return null; 86 | } 87 | 88 | determinant = edge0.a * edge1.b - edge0.b * edge1.a; 89 | if (-1.0e-10 < determinant && determinant < 1.0e-10) { 90 | // the edges are parallel 91 | return null; 92 | } 93 | 94 | intersectionX = (edge0.c * edge1.b - edge1.c * edge0.b) / determinant; 95 | intersectionY = (edge1.c * edge0.a - edge0.c * edge1.a) / determinant; 96 | 97 | if (Voronoi.CompareByYThenX (edge0.rightSite, edge1.rightSite) < 0) { 98 | halfedge = halfedge0; 99 | edge = edge0; 100 | } else { 101 | halfedge = halfedge1; 102 | edge = edge1; 103 | } 104 | rightOfSite = intersectionX >= edge.rightSite.x; 105 | if ((rightOfSite && halfedge.leftRight == Side.LEFT) 106 | || (!rightOfSite && halfedge.leftRight == Side.RIGHT)) { 107 | return null; 108 | } 109 | 110 | return Vertex.Create (intersectionX, intersectionY); 111 | } 112 | 113 | public float x { 114 | get { return _coord.x;} 115 | } 116 | public float y { 117 | get{ return _coord.y;} 118 | } 119 | 120 | } 121 | } -------------------------------------------------------------------------------- /Assets/Delaunay/Unity-delaunay/Delaunay/Vertex.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 16e154efbeed043e1865a7d95f623368 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/Delaunay/Unity-delaunay/Delaunay/Voronoi.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * The author of this software is Steven Fortune. Copyright (c) 1994 by AT&T 3 | * Bell Laboratories. 4 | * Permission to use, copy, modify, and distribute this software for any 5 | * purpose without fee is hereby granted, provided that this entire notice 6 | * is included in all copies of any software which is or includes a copy 7 | * or modification of this software and in all copies of the supporting 8 | * documentation for such software. 9 | * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED 10 | * WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR AT&T MAKE ANY 11 | * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY 12 | * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. 13 | */ 14 | 15 | using UnityEngine; 16 | using System; 17 | using System.Collections.Generic; 18 | using Delaunay.Geo; 19 | using Delaunay.Utils; 20 | using Delaunay.LR; 21 | 22 | namespace Delaunay 23 | { 24 | public sealed class Voronoi: Utils.IDisposable 25 | { 26 | private SiteList _sites; 27 | private Dictionary _sitesIndexedByLocation; 28 | private List _triangles; 29 | private List _edges; 30 | 31 | 32 | // TODO generalize this so it doesn't have to be a rectangle; 33 | // then we can make the fractal voronois-within-voronois 34 | private Rect _plotBounds; 35 | public Rect plotBounds { 36 | get { return _plotBounds;} 37 | } 38 | 39 | public void Dispose () 40 | { 41 | int i, n; 42 | if (_sites != null) { 43 | _sites.Dispose (); 44 | _sites = null; 45 | } 46 | if (_triangles != null) { 47 | n = _triangles.Count; 48 | for (i = 0; i < n; ++i) { 49 | _triangles [i].Dispose (); 50 | } 51 | _triangles.Clear (); 52 | _triangles = null; 53 | } 54 | if (_edges != null) { 55 | n = _edges.Count; 56 | for (i = 0; i < n; ++i) { 57 | _edges [i].Dispose (); 58 | } 59 | _edges.Clear (); 60 | _edges = null; 61 | } 62 | // _plotBounds = null; 63 | _sitesIndexedByLocation = null; 64 | } 65 | 66 | public Voronoi (List points, List colors, Rect plotBounds) 67 | { 68 | _sites = new SiteList (); 69 | _sitesIndexedByLocation = new Dictionary (); // XXX: Used to be Dictionary(true) -- weak refs. 70 | AddSites (points, colors); 71 | _plotBounds = plotBounds; 72 | _triangles = new List (); 73 | _edges = new List (); 74 | FortunesAlgorithm (); 75 | } 76 | 77 | private void AddSites (List points, List colors) 78 | { 79 | int length = points.Count; 80 | for (int i = 0; i < length; ++i) { 81 | AddSite (points [i], (colors != null) ? colors [i] : 0, i); 82 | } 83 | } 84 | 85 | private void AddSite (Vector2 p, uint color, int index) 86 | { 87 | if (_sitesIndexedByLocation.ContainsKey (p)) 88 | return; // Prevent duplicate site! (Adapted from https://github.com/nodename/as3delaunay/issues/1) 89 | float weight = UnityEngine.Random.value * 100f; 90 | Site site = Site.Create (p, (uint)index, weight, color); 91 | _sites.Add (site); 92 | _sitesIndexedByLocation [p] = site; 93 | } 94 | 95 | public List Edges () 96 | { 97 | return _edges; 98 | } 99 | 100 | public List Region (Vector2 p) 101 | { 102 | Site site = _sitesIndexedByLocation [p]; 103 | if (site == null) { 104 | return new List (); 105 | } 106 | return site.Region (_plotBounds); 107 | } 108 | 109 | // TODO: bug: if you call this before you call region(), something goes wrong :( 110 | public List NeighborSitesForSite (Vector2 coord) 111 | { 112 | List points = new List (); 113 | Site site = _sitesIndexedByLocation [coord]; 114 | if (site == null) { 115 | return points; 116 | } 117 | List sites = site.NeighborSites (); 118 | Site neighbor; 119 | for (int nIndex =0; nIndex Circles () 127 | { 128 | return _sites.Circles (); 129 | } 130 | 131 | public List VoronoiBoundaryForSite (Vector2 coord) 132 | { 133 | return DelaunayHelpers.VisibleLineSegments (DelaunayHelpers.SelectEdgesForSitePoint (coord, _edges)); 134 | } 135 | 136 | public List DelaunayLinesForSite (Vector2 coord) 137 | { 138 | return DelaunayHelpers.DelaunayLinesForEdges (DelaunayHelpers.SelectEdgesForSitePoint (coord, _edges)); 139 | } 140 | 141 | public List VoronoiDiagram () 142 | { 143 | return DelaunayHelpers.VisibleLineSegments (_edges); 144 | } 145 | 146 | public List DelaunayTriangulation (/*BitmapData keepOutMask = null*/) 147 | { 148 | return DelaunayHelpers.DelaunayLinesForEdges (DelaunayHelpers.SelectNonIntersectingEdges (/*keepOutMask,*/_edges)); 149 | } 150 | 151 | public List Hull () 152 | { 153 | return DelaunayHelpers.DelaunayLinesForEdges (HullEdges ()); 154 | } 155 | 156 | private List HullEdges () 157 | { 158 | return _edges.FindAll (delegate (Edge edge) { 159 | return (edge.IsPartOfConvexHull ()); 160 | }); 161 | } 162 | 163 | public List HullPointsInOrder () 164 | { 165 | List hullEdges = HullEdges (); 166 | 167 | List points = new List (); 168 | if (hullEdges.Count == 0) { 169 | return points; 170 | } 171 | 172 | EdgeReorderer reorderer = new EdgeReorderer (hullEdges, VertexOrSite.SITE); 173 | hullEdges = reorderer.edges; 174 | List orientations = reorderer.edgeOrientations; 175 | reorderer.Dispose (); 176 | 177 | Side orientation; 178 | 179 | int n = hullEdges.Count; 180 | for (int i = 0; i < n; ++i) { 181 | Edge edge = hullEdges [i]; 182 | orientation = orientations [i]; 183 | points.Add (edge.Site (orientation).Coord); 184 | } 185 | return points; 186 | } 187 | 188 | public List SpanningTree (KruskalType type = KruskalType.MINIMUM/*, BitmapData keepOutMask = null*/) 189 | { 190 | List edges = DelaunayHelpers.SelectNonIntersectingEdges (/*keepOutMask,*/_edges); 191 | List segments = DelaunayHelpers.DelaunayLinesForEdges (edges); 192 | return DelaunayHelpers.Kruskal (segments, type); 193 | } 194 | 195 | public List> Regions () 196 | { 197 | return _sites.Regions (_plotBounds); 198 | } 199 | 200 | public List SiteColors (/*BitmapData referenceImage = null*/) 201 | { 202 | return _sites.SiteColors (/*referenceImage*/); 203 | } 204 | 205 | /** 206 | * 207 | * @param proximityMap a BitmapData whose regions are filled with the site index values; see PlanePointsCanvas::fillRegions() 208 | * @param x 209 | * @param y 210 | * @return coordinates of nearest Site to (x, y) 211 | * 212 | */ 213 | public Nullable NearestSitePoint (/*BitmapData proximityMap,*/float x, float y) 214 | { 215 | return _sites.NearestSitePoint (/*proximityMap,*/x, y); 216 | } 217 | 218 | public List SiteCoords () 219 | { 220 | return _sites.SiteCoords (); 221 | } 222 | 223 | private Site fortunesAlgorithm_bottomMostSite; 224 | private void FortunesAlgorithm () 225 | { 226 | Site newSite, bottomSite, topSite, tempSite; 227 | Vertex v, vertex; 228 | Vector2 newintstar = Vector2.zero; //Because the compiler doesn't know that it will have a value - Julian 229 | Side leftRight; 230 | Halfedge lbnd, rbnd, llbnd, rrbnd, bisector; 231 | Edge edge; 232 | 233 | Rect dataBounds = _sites.GetSitesBounds (); 234 | 235 | int sqrt_nsites = (int)(Mathf.Sqrt (_sites.Count + 4)); 236 | HalfedgePriorityQueue heap = new HalfedgePriorityQueue (dataBounds.y, dataBounds.height, sqrt_nsites); 237 | EdgeList edgeList = new EdgeList (dataBounds.x, dataBounds.width, sqrt_nsites); 238 | List halfEdges = new List (); 239 | List vertices = new List (); 240 | 241 | fortunesAlgorithm_bottomMostSite = _sites.Next (); 242 | newSite = _sites.Next (); 243 | 244 | for (;;) { 245 | if (heap.Empty () == false) { 246 | newintstar = heap.Min (); 247 | } 248 | 249 | if (newSite != null 250 | && (heap.Empty () || CompareByYThenX (newSite, newintstar) < 0)) { 251 | /* new site is smallest */ 252 | //trace("smallest: new site " + newSite); 253 | 254 | // Step 8: 255 | lbnd = edgeList.EdgeListLeftNeighbor (newSite.Coord); // the Halfedge just to the left of newSite 256 | //trace("lbnd: " + lbnd); 257 | rbnd = lbnd.edgeListRightNeighbor; // the Halfedge just to the right 258 | //trace("rbnd: " + rbnd); 259 | bottomSite = FortunesAlgorithm_rightRegion (lbnd); // this is the same as leftRegion(rbnd) 260 | // this Site determines the region containing the new site 261 | //trace("new Site is in region of existing site: " + bottomSite); 262 | 263 | // Step 9: 264 | edge = Edge.CreateBisectingEdge (bottomSite, newSite); 265 | //trace("new edge: " + edge); 266 | _edges.Add (edge); 267 | 268 | bisector = Halfedge.Create (edge, Side.LEFT); 269 | halfEdges.Add (bisector); 270 | // inserting two Halfedges into edgeList constitutes Step 10: 271 | // insert bisector to the right of lbnd: 272 | edgeList.Insert (lbnd, bisector); 273 | 274 | // first half of Step 11: 275 | if ((vertex = Vertex.Intersect (lbnd, bisector)) != null) { 276 | vertices.Add (vertex); 277 | heap.Remove (lbnd); 278 | lbnd.vertex = vertex; 279 | lbnd.ystar = vertex.y + newSite.Dist (vertex); 280 | heap.Insert (lbnd); 281 | } 282 | 283 | lbnd = bisector; 284 | bisector = Halfedge.Create (edge, Side.RIGHT); 285 | halfEdges.Add (bisector); 286 | // second Halfedge for Step 10: 287 | // insert bisector to the right of lbnd: 288 | edgeList.Insert (lbnd, bisector); 289 | 290 | // second half of Step 11: 291 | if ((vertex = Vertex.Intersect (bisector, rbnd)) != null) { 292 | vertices.Add (vertex); 293 | bisector.vertex = vertex; 294 | bisector.ystar = vertex.y + newSite.Dist (vertex); 295 | heap.Insert (bisector); 296 | } 297 | 298 | newSite = _sites.Next (); 299 | } else if (heap.Empty () == false) { 300 | /* intersection is smallest */ 301 | lbnd = heap.ExtractMin (); 302 | llbnd = lbnd.edgeListLeftNeighbor; 303 | rbnd = lbnd.edgeListRightNeighbor; 304 | rrbnd = rbnd.edgeListRightNeighbor; 305 | bottomSite = FortunesAlgorithm_leftRegion (lbnd); 306 | topSite = FortunesAlgorithm_rightRegion (rbnd); 307 | // these three sites define a Delaunay triangle 308 | // (not actually using these for anything...) 309 | //_triangles.push(new Triangle(bottomSite, topSite, rightRegion(lbnd))); 310 | 311 | v = lbnd.vertex; 312 | v.SetIndex (); 313 | lbnd.edge.SetVertex ((Side)lbnd.leftRight, v); 314 | rbnd.edge.SetVertex ((Side)rbnd.leftRight, v); 315 | edgeList.Remove (lbnd); 316 | heap.Remove (rbnd); 317 | edgeList.Remove (rbnd); 318 | leftRight = Side.LEFT; 319 | if (bottomSite.y > topSite.y) { 320 | tempSite = bottomSite; 321 | bottomSite = topSite; 322 | topSite = tempSite; 323 | leftRight = Side.RIGHT; 324 | } 325 | edge = Edge.CreateBisectingEdge (bottomSite, topSite); 326 | _edges.Add (edge); 327 | bisector = Halfedge.Create (edge, leftRight); 328 | halfEdges.Add (bisector); 329 | edgeList.Insert (llbnd, bisector); 330 | edge.SetVertex (SideHelper.Other (leftRight), v); 331 | if ((vertex = Vertex.Intersect (llbnd, bisector)) != null) { 332 | vertices.Add (vertex); 333 | heap.Remove (llbnd); 334 | llbnd.vertex = vertex; 335 | llbnd.ystar = vertex.y + bottomSite.Dist (vertex); 336 | heap.Insert (llbnd); 337 | } 338 | if ((vertex = Vertex.Intersect (bisector, rrbnd)) != null) { 339 | vertices.Add (vertex); 340 | bisector.vertex = vertex; 341 | bisector.ystar = vertex.y + bottomSite.Dist (vertex); 342 | heap.Insert (bisector); 343 | } 344 | } else { 345 | break; 346 | } 347 | } 348 | 349 | // heap should be empty now 350 | heap.Dispose (); 351 | edgeList.Dispose (); 352 | 353 | for (int hIndex = 0; hIndex s2.y) 395 | return 1; 396 | if (s1.x < s2.x) 397 | return -1; 398 | if (s1.x > s2.x) 399 | return 1; 400 | return 0; 401 | } 402 | 403 | public static int CompareByYThenX (Site s1, Vector2 s2) 404 | { 405 | if (s1.y < s2.y) 406 | return -1; 407 | if (s1.y > s2.y) 408 | return 1; 409 | if (s1.x < s2.x) 410 | return -1; 411 | if (s1.x > s2.x) 412 | return 1; 413 | return 0; 414 | } 415 | 416 | } 417 | } -------------------------------------------------------------------------------- /Assets/Delaunay/Unity-delaunay/Delaunay/Voronoi.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 8a659b037ca774ad4b255ac68dbe65ae 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/Delaunay/Unity-delaunay/geom.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 2ee5f0dcc71544e1dade82ac72f7fc3d 3 | folderAsset: yes 4 | DefaultImporter: 5 | userData: 6 | -------------------------------------------------------------------------------- /Assets/Delaunay/Unity-delaunay/geom/Circle.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System; 3 | 4 | namespace Delaunay 5 | { 6 | namespace Geo 7 | { 8 | public sealed class Circle 9 | { 10 | public Vector2 center; 11 | public float radius; 12 | 13 | public Circle (float centerX, float centerY, float radius) 14 | { 15 | this.center = new Vector2 (centerX, centerY); 16 | this.radius = radius; 17 | } 18 | 19 | public override string ToString () 20 | { 21 | return "Circle (center: " + center.ToString () + "; radius: " + radius.ToString () + ")"; 22 | } 23 | 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /Assets/Delaunay/Unity-delaunay/geom/Circle.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e5300884d68b94e1c958b6328944dcca 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/Delaunay/Unity-delaunay/geom/LineSegment.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System; 3 | 4 | namespace Delaunay 5 | { 6 | namespace Geo 7 | { 8 | public sealed class LineSegment 9 | { 10 | public static int CompareLengths_MAX (LineSegment segment0, LineSegment segment1) 11 | { 12 | float length0 = Vector2.Distance ((Vector2)segment0.p0, (Vector2)segment0.p1); 13 | float length1 = Vector2.Distance ((Vector2)segment1.p0, (Vector2)segment1.p1); 14 | if (length0 < length1) { 15 | return 1; 16 | } 17 | if (length0 > length1) { 18 | return -1; 19 | } 20 | return 0; 21 | } 22 | 23 | public static int CompareLengths (LineSegment edge0, LineSegment edge1) 24 | { 25 | return - CompareLengths_MAX (edge0, edge1); 26 | } 27 | 28 | public Nullable p0; 29 | public Nullable p1; 30 | 31 | public LineSegment (Nullable p0, Nullable p1) 32 | { 33 | this.p0 = p0; 34 | this.p1 = p1; 35 | } 36 | 37 | } 38 | } 39 | } -------------------------------------------------------------------------------- /Assets/Delaunay/Unity-delaunay/geom/LineSegment.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 76312350a2abb4fa9a9926fc7da2287d 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/Delaunay/Unity-delaunay/geom/Polygon.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System.Collections.Generic; 3 | 4 | namespace Delaunay 5 | { 6 | namespace Geo 7 | { 8 | public sealed class Polygon 9 | { 10 | private List _vertices; 11 | 12 | public Polygon (List vertices) 13 | { 14 | _vertices = vertices; 15 | } 16 | 17 | public float Area () 18 | { 19 | return Mathf.Abs (SignedDoubleArea () * 0.5f); // XXX: I'm a bit nervous about this; not sure what the * 0.5 is for, bithacking? 20 | } 21 | 22 | public Winding Winding () 23 | { 24 | float signedDoubleArea = SignedDoubleArea (); 25 | if (signedDoubleArea < 0) { 26 | return Geo.Winding.CLOCKWISE; 27 | } 28 | if (signedDoubleArea > 0) { 29 | return Geo.Winding.COUNTERCLOCKWISE; 30 | } 31 | return Geo.Winding.NONE; 32 | } 33 | 34 | private float SignedDoubleArea () // XXX: I'm a bit nervous about this because Actionscript represents everything as doubles, not floats 35 | { 36 | int index, nextIndex; 37 | int n = _vertices.Count; 38 | Vector2 point, next; 39 | float signedDoubleArea = 0; // Losing lots of precision? 40 | for (index = 0; index < n; ++index) { 41 | nextIndex = (index + 1) % n; 42 | point = _vertices [index]; 43 | next = _vertices [nextIndex]; 44 | signedDoubleArea += point.x * next.y - next.x * point.y; 45 | } 46 | return signedDoubleArea; 47 | } 48 | } 49 | } 50 | } -------------------------------------------------------------------------------- /Assets/Delaunay/Unity-delaunay/geom/Polygon.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e59bb833c9cf045e992b44a5e23837cb 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/Delaunay/Unity-delaunay/geom/Winding.cs: -------------------------------------------------------------------------------- 1 | namespace Delaunay 2 | { 3 | namespace Geo { 4 | public enum Winding 5 | { 6 | NONE = 0, CLOCKWISE, COUNTERCLOCKWISE 7 | } 8 | } 9 | } -------------------------------------------------------------------------------- /Assets/Delaunay/Unity-delaunay/geom/Winding.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1a38f1425b42547898d3b2ef6c865e05 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/Delaunay/Unity-delaunay/utils.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6505f93572a1d41a38b2f1aeee65897b 3 | folderAsset: yes 4 | DefaultImporter: 5 | userData: 6 | -------------------------------------------------------------------------------- /Assets/Delaunay/Unity-delaunay/utils/IDisposable.cs: -------------------------------------------------------------------------------- 1 | namespace Delaunay 2 | { 3 | namespace Utils 4 | { 5 | public interface IDisposable 6 | { 7 | void Dispose (); 8 | } 9 | } 10 | } -------------------------------------------------------------------------------- /Assets/Delaunay/Unity-delaunay/utils/IDisposable.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 7cb01ead474dc485fa87ef0e202dcc6d 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/Delaunay/VoronoiDemo.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System.Collections.Generic; 3 | using Delaunay; 4 | using Delaunay.Geo; 5 | 6 | public class VoronoiDemo : MonoBehaviour 7 | { 8 | [SerializeField] 9 | private int 10 | m_pointCount = 300; 11 | 12 | private List m_points; 13 | private float m_mapWidth = 100; 14 | private float m_mapHeight = 50; 15 | private List m_edges = null; 16 | private List m_spanningTree; 17 | private List m_delaunayTriangulation; 18 | 19 | void Awake () 20 | { 21 | Demo (); 22 | } 23 | 24 | void Update () 25 | { 26 | if (Input.anyKeyDown) { 27 | Demo (); 28 | } 29 | } 30 | 31 | private void Demo () 32 | { 33 | 34 | List colors = new List (); 35 | m_points = new List (); 36 | 37 | for (int i = 0; i < m_pointCount; i++) { 38 | colors.Add (0); 39 | m_points.Add (new Vector2 ( 40 | UnityEngine.Random.Range (0, m_mapWidth), 41 | UnityEngine.Random.Range (0, m_mapHeight)) 42 | ); 43 | } 44 | Delaunay.Voronoi v = new Delaunay.Voronoi (m_points, colors, new Rect (0, 0, m_mapWidth, m_mapHeight)); 45 | m_edges = v.VoronoiDiagram (); 46 | 47 | m_spanningTree = v.SpanningTree (KruskalType.MINIMUM); 48 | m_delaunayTriangulation = v.DelaunayTriangulation (); 49 | } 50 | 51 | void OnDrawGizmos () 52 | { 53 | Gizmos.color = Color.red; 54 | if (m_points != null) { 55 | for (int i = 0; i < m_points.Count; i++) { 56 | Gizmos.DrawSphere (m_points [i], 0.2f); 57 | } 58 | } 59 | 60 | if (m_edges != null) { 61 | Gizmos.color = Color.white; 62 | for (int i = 0; i< m_edges.Count; i++) { 63 | Vector2 left = (Vector2)m_edges [i].p0; 64 | Vector2 right = (Vector2)m_edges [i].p1; 65 | Gizmos.DrawLine ((Vector3)left, (Vector3)right); 66 | } 67 | } 68 | 69 | Gizmos.color = Color.magenta; 70 | if (m_delaunayTriangulation != null) { 71 | for (int i = 0; i< m_delaunayTriangulation.Count; i++) { 72 | Vector2 left = (Vector2)m_delaunayTriangulation [i].p0; 73 | Vector2 right = (Vector2)m_delaunayTriangulation [i].p1; 74 | Gizmos.DrawLine ((Vector3)left, (Vector3)right); 75 | } 76 | } 77 | 78 | if (m_spanningTree != null) { 79 | Gizmos.color = Color.green; 80 | for (int i = 0; i< m_spanningTree.Count; i++) { 81 | LineSegment seg = m_spanningTree [i]; 82 | Vector2 left = (Vector2)seg.p0; 83 | Vector2 right = (Vector2)seg.p1; 84 | Gizmos.DrawLine ((Vector3)left, (Vector3)right); 85 | } 86 | } 87 | 88 | Gizmos.color = Color.yellow; 89 | Gizmos.DrawLine (new Vector2 (0, 0), new Vector2 (0, m_mapHeight)); 90 | Gizmos.DrawLine (new Vector2 (0, 0), new Vector2 (m_mapWidth, 0)); 91 | Gizmos.DrawLine (new Vector2 (m_mapWidth, 0), new Vector2 (m_mapWidth, m_mapHeight)); 92 | Gizmos.DrawLine (new Vector2 (0, m_mapHeight), new Vector2 (m_mapWidth, m_mapHeight)); 93 | } 94 | } -------------------------------------------------------------------------------- /Assets/Delaunay/VoronoiDemo.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6b8eb48d5779546089555c7b0bd5341e 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/DungeonGenerator.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 90f512d68696faa4a8f1cc3e6211098b 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/DungeonGenerator/Dungeon.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b42a34b8d4a369e47b50207fc734f008 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/DungeonGenerator/Dungeon/Nodes.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 9c8aa7f6c00b9264f804456eb342f917 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/DungeonGenerator/Dungeon/Nodes/DungeonNodes.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!114 &11400000 4 | MonoBehaviour: 5 | m_ObjectHideFlags: 0 6 | m_CorrespondingSourceObject: {fileID: 0} 7 | m_PrefabInternal: {fileID: 0} 8 | m_GameObject: {fileID: 0} 9 | m_Enabled: 1 10 | m_EditorHideFlags: 0 11 | m_Script: {fileID: 11500000, guid: 6603a91be1e92fc4ba44cb4a754b10b2, type: 3} 12 | m_Name: DungeonNodes 13 | m_EditorClassIdentifier: 14 | nodeCount: 10 15 | maxBranchCount: 3 16 | randomConnectEndBranch: 1 17 | chanceConnectEndBranch: 0.845 18 | nodes: 19 | - id: 0 20 | nodeConnections: 01000000 21 | rectPosition: 22 | serializedVersion: 2 23 | x: 0 24 | y: 180 25 | width: 60 26 | height: 60 27 | - id: 1 28 | nodeConnections: 02000000 29 | rectPosition: 30 | serializedVersion: 2 31 | x: 120 32 | y: 180 33 | width: 60 34 | height: 60 35 | - id: 2 36 | nodeConnections: 03000000 37 | rectPosition: 38 | serializedVersion: 2 39 | x: 240 40 | y: 180 41 | width: 60 42 | height: 60 43 | - id: 3 44 | nodeConnections: 0500000004000000 45 | rectPosition: 46 | serializedVersion: 2 47 | x: 360 48 | y: 180 49 | width: 60 50 | height: 60 51 | - id: 4 52 | nodeConnections: 06000000 53 | rectPosition: 54 | serializedVersion: 2 55 | x: 480 56 | y: 240 57 | width: 60 58 | height: 60 59 | - id: 5 60 | nodeConnections: 0800000007000000 61 | rectPosition: 62 | serializedVersion: 2 63 | x: 480 64 | y: 120 65 | width: 60 66 | height: 60 67 | - id: 6 68 | nodeConnections: 09000000 69 | rectPosition: 70 | serializedVersion: 2 71 | x: 600 72 | y: 240 73 | width: 60 74 | height: 60 75 | - id: 7 76 | nodeConnections: 08000000 77 | rectPosition: 78 | serializedVersion: 2 79 | x: 600 80 | y: 160 81 | width: 60 82 | height: 60 83 | - id: 8 84 | nodeConnections: 85 | rectPosition: 86 | serializedVersion: 2 87 | x: 600 88 | y: 80 89 | width: 60 90 | height: 60 91 | - id: 9 92 | nodeConnections: 93 | rectPosition: 94 | serializedVersion: 2 95 | x: 720 96 | y: 240 97 | width: 60 98 | height: 60 99 | -------------------------------------------------------------------------------- /Assets/DungeonGenerator/Dungeon/Nodes/DungeonNodes.asset.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 81078ab3c2b7c8941b508969ede0ebc6 3 | NativeFormatImporter: 4 | externalObjects: {} 5 | mainObjectFileID: 11400000 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/DungeonGenerator/Dungeon/Nodes/TilemapNodes.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!114 &11400000 4 | MonoBehaviour: 5 | m_ObjectHideFlags: 0 6 | m_CorrespondingSourceObject: {fileID: 0} 7 | m_PrefabInternal: {fileID: 0} 8 | m_GameObject: {fileID: 0} 9 | m_Enabled: 1 10 | m_EditorHideFlags: 0 11 | m_Script: {fileID: 11500000, guid: b70ea929cbbf1034787233db738824c2, type: 3} 12 | m_Name: TilemapNodes 13 | m_EditorClassIdentifier: 14 | nodeCount: 10 15 | maxBranchCount: 3 16 | randomConnectEndBranch: 1 17 | chanceConnectEndBranch: 0.869 18 | nodes: 19 | - id: 0 20 | parent: 0 21 | nodeConnections: 0200000001000000 22 | rectPosition: 23 | serializedVersion: 2 24 | x: 0 25 | y: 220 26 | width: 60 27 | height: 60 28 | - id: 1 29 | parent: 0 30 | nodeConnections: 0400000003000000 31 | rectPosition: 32 | serializedVersion: 2 33 | x: 120 34 | y: 320 35 | width: 60 36 | height: 60 37 | - id: 2 38 | parent: 0 39 | nodeConnections: 0600000005000000 40 | rectPosition: 41 | serializedVersion: 2 42 | x: 120 43 | y: 120 44 | width: 60 45 | height: 60 46 | - id: 3 47 | parent: 2 48 | nodeConnections: 090000000800000007000000 49 | rectPosition: 50 | serializedVersion: 2 51 | x: 240 52 | y: 400 53 | width: 60 54 | height: 60 55 | - id: 4 56 | parent: 2 57 | nodeConnections: 05000000 58 | rectPosition: 59 | serializedVersion: 2 60 | x: 240 61 | y: 240 62 | width: 60 63 | height: 60 64 | - id: 5 65 | parent: 4 66 | nodeConnections: 67 | rectPosition: 68 | serializedVersion: 2 69 | x: 240 70 | y: 160 71 | width: 60 72 | height: 60 73 | - id: 6 74 | parent: 4 75 | nodeConnections: 07000000 76 | rectPosition: 77 | serializedVersion: 2 78 | x: 240 79 | y: 80 80 | width: 60 81 | height: 60 82 | - id: 7 83 | parent: 6 84 | nodeConnections: 85 | rectPosition: 86 | serializedVersion: 2 87 | x: 360 88 | y: 480 89 | width: 60 90 | height: 60 91 | - id: 8 92 | parent: 6 93 | nodeConnections: 09000000 94 | rectPosition: 95 | serializedVersion: 2 96 | x: 360 97 | y: 400 98 | width: 60 99 | height: 60 100 | - id: 9 101 | parent: 6 102 | nodeConnections: 103 | rectPosition: 104 | serializedVersion: 2 105 | x: 360 106 | y: 320 107 | width: 60 108 | height: 60 109 | rooms: 110 | - {fileID: 8195094281449198356, guid: 396daedc3a63f504bb095d2ae0fbeb65, type: 2} 111 | - {fileID: 8195094280640835416, guid: 9c01816b132b834428911f90efd35140, type: 2} 112 | roomsIndexNodes: 01000000000000000100000000000000010000000100000000000000000000000100000001000000 113 | -------------------------------------------------------------------------------- /Assets/DungeonGenerator/Dungeon/Nodes/TilemapNodes.asset.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 02f7f0ff041534540ba3d6caa8daa70f 3 | NativeFormatImporter: 4 | externalObjects: {} 5 | mainObjectFileID: 11400000 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/DungeonGenerator/Scenes.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 92414caeffda7d2419962ca6640e1814 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/DungeonGenerator/Scenes/SampleScene.unity.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d2d3920bca26a8a4cb0e7c60ab61bc44 3 | DefaultImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Assets/DungeonGenerator/Scripts.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a4cd92624a49f6d4aa20ae099d69a0f5 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/DungeonGenerator/Scripts/Editor.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b5dfad7e05bf2434eba210dcb70a3e0f 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/DungeonGenerator/Scripts/Editor/BuiltInResourcesWindow.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using UnityEditor; 3 | using UnityEngine; 4 | using System.Collections.Generic; 5 | 6 | public class BuiltInResourcesWindow : EditorWindow 7 | { 8 | [MenuItem("Window/Built-in styles and icons")] 9 | public static void ShowWindow() 10 | { 11 | BuiltInResourcesWindow w = (BuiltInResourcesWindow)EditorWindow.GetWindow(); 12 | w.Show(); 13 | } 14 | 15 | private struct Drawing 16 | { 17 | public Rect Rect; 18 | public Action Draw; 19 | } 20 | 21 | private List Drawings; 22 | 23 | private List _objects; 24 | private float _scrollPos; 25 | private float _maxY; 26 | private Rect _oldPosition; 27 | 28 | private bool _showingStyles = true; 29 | private bool _showingIcons = false; 30 | 31 | private string _search = ""; 32 | 33 | void OnGUI() 34 | { 35 | if (position.width != _oldPosition.width && Event.current.type == EventType.Layout) 36 | { 37 | Drawings = null; 38 | _oldPosition = position; 39 | } 40 | 41 | GUILayout.BeginHorizontal(); 42 | 43 | if (GUILayout.Toggle(_showingStyles, "Styles", EditorStyles.toolbarButton) != _showingStyles) 44 | { 45 | _showingStyles = !_showingStyles; 46 | _showingIcons = !_showingStyles; 47 | Drawings = null; 48 | } 49 | 50 | if (GUILayout.Toggle(_showingIcons, "Icons", EditorStyles.toolbarButton) != _showingIcons) 51 | { 52 | _showingIcons = !_showingIcons; 53 | _showingStyles = !_showingIcons; 54 | Drawings = null; 55 | } 56 | 57 | GUILayout.EndHorizontal(); 58 | 59 | string newSearch = GUILayout.TextField(_search); 60 | if (newSearch != _search) 61 | { 62 | _search = newSearch; 63 | Drawings = null; 64 | } 65 | 66 | float top = 36; 67 | 68 | if (Drawings == null) 69 | { 70 | string lowerSearch = _search.ToLower(); 71 | 72 | Drawings = new List(); 73 | 74 | GUIContent inactiveText = new GUIContent("inactive"); 75 | GUIContent activeText = new GUIContent("active"); 76 | 77 | float x = 5.0f; 78 | float y = 5.0f; 79 | 80 | if (_showingStyles) 81 | { 82 | foreach (GUIStyle ss in GUI.skin.customStyles) 83 | { 84 | if (lowerSearch != "" && !ss.name.ToLower().Contains(lowerSearch)) 85 | continue; 86 | 87 | GUIStyle thisStyle = ss; 88 | 89 | Drawing draw = new Drawing(); 90 | 91 | float width = Mathf.Max( 92 | 100.0f, 93 | GUI.skin.button.CalcSize(new GUIContent(ss.name)).x, 94 | ss.CalcSize(inactiveText).x + ss.CalcSize(activeText).x 95 | ) + 16.0f; 96 | 97 | float height = 60.0f; 98 | 99 | if (x + width > position.width - 32 && x > 5.0f) 100 | { 101 | x = 5.0f; 102 | y += height + 10.0f; 103 | } 104 | 105 | draw.Rect = new Rect(x, y, width, height); 106 | 107 | width -= 8.0f; 108 | 109 | draw.Draw = () => 110 | { 111 | if (GUILayout.Button(thisStyle.name, GUILayout.Width(width))) 112 | CopyText("(GUIStyle)\"" + thisStyle.name + "\""); 113 | 114 | GUILayout.BeginHorizontal(); 115 | GUILayout.Toggle(false, inactiveText, thisStyle, GUILayout.Width(width / 2)); 116 | GUILayout.Toggle(false, activeText, thisStyle, GUILayout.Width(width / 2)); 117 | GUILayout.EndHorizontal(); 118 | }; 119 | 120 | x += width + 18.0f; 121 | 122 | Drawings.Add(draw); 123 | } 124 | } 125 | else if (_showingIcons) 126 | { 127 | if (_objects == null) 128 | { 129 | _objects = new List(Resources.FindObjectsOfTypeAll(typeof(Texture))); 130 | _objects.Sort((pA, pB) => System.String.Compare(pA.name, pB.name, System.StringComparison.OrdinalIgnoreCase)); 131 | } 132 | 133 | float rowHeight = 0.0f; 134 | 135 | foreach (UnityEngine.Object oo in _objects) 136 | { 137 | Texture texture = (Texture)oo; 138 | 139 | if (texture.name == "") 140 | continue; 141 | 142 | if (lowerSearch != "" && !texture.name.ToLower().Contains(lowerSearch)) 143 | continue; 144 | 145 | Drawing draw = new Drawing(); 146 | 147 | float width = Mathf.Max( 148 | GUI.skin.button.CalcSize(new GUIContent(texture.name)).x, 149 | texture.width 150 | ) + 8.0f; 151 | 152 | float height = texture.height + GUI.skin.button.CalcSize(new GUIContent(texture.name)).y + 8.0f; 153 | 154 | if (x + width > position.width - 32.0f) 155 | { 156 | x = 5.0f; 157 | y += rowHeight + 8.0f; 158 | rowHeight = 0.0f; 159 | } 160 | 161 | draw.Rect = new Rect(x, y, width, height); 162 | 163 | rowHeight = Mathf.Max(rowHeight, height); 164 | 165 | width -= 8.0f; 166 | 167 | draw.Draw = () => 168 | { 169 | if (GUILayout.Button(texture.name, GUILayout.Width(width))) 170 | CopyText("EditorGUIUtility.FindTexture( \"" + texture.name + "\" )"); 171 | 172 | Rect textureRect = GUILayoutUtility.GetRect(texture.width, texture.width, texture.height, texture.height, GUILayout.ExpandHeight(false), GUILayout.ExpandWidth(false)); 173 | EditorGUI.DrawTextureTransparent(textureRect, texture); 174 | }; 175 | 176 | x += width + 8.0f; 177 | 178 | Drawings.Add(draw); 179 | } 180 | } 181 | 182 | _maxY = y; 183 | } 184 | 185 | Rect r = position; 186 | r.y = top; 187 | r.height -= r.y; 188 | r.x = r.width - 16; 189 | r.width = 16; 190 | 191 | float areaHeight = position.height - top; 192 | _scrollPos = GUI.VerticalScrollbar(r, _scrollPos, areaHeight, 0.0f, _maxY); 193 | 194 | Rect area = new Rect(0, top, position.width - 16.0f, areaHeight); 195 | GUILayout.BeginArea(area); 196 | 197 | int count = 0; 198 | foreach (Drawing draw in Drawings) 199 | { 200 | Rect newRect = draw.Rect; 201 | newRect.y -= _scrollPos; 202 | 203 | if (newRect.y + newRect.height > 0 && newRect.y < areaHeight) 204 | { 205 | GUILayout.BeginArea(newRect, GUI.skin.textField); 206 | draw.Draw(); 207 | GUILayout.EndArea(); 208 | 209 | count++; 210 | } 211 | } 212 | 213 | GUILayout.EndArea(); 214 | } 215 | 216 | void CopyText(string pText) 217 | { 218 | TextEditor editor = new TextEditor(); 219 | 220 | //editor.content = new GUIContent(pText); // Unity 4.x code 221 | editor.text = pText; // Unity 5.x code 222 | 223 | editor.SelectAll(); 224 | editor.Copy(); 225 | } 226 | } -------------------------------------------------------------------------------- /Assets/DungeonGenerator/Scripts/Editor/BuiltInResourcesWindow.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 4730984487596e14b9bdbd9b8baff45a 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Assets/DungeonGenerator/Scripts/Editor/DungeonGeneratorEditor.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using UnityEngine; 4 | using UnityEditor; 5 | using System.Linq; 6 | 7 | namespace DI.DungeonGenerator { 8 | [CustomEditor(typeof(BSPDungeonGeneration), true)] 9 | public class BSPDungeonGeneratorEditor : DungeonGeneratorEditor 10 | { 11 | BSPDungeonGeneration drg { get { return (BSPDungeonGeneration)target; } } 12 | public override void OnInspectorGUI() 13 | { 14 | base.OnInspectorGUI(); 15 | if (GUILayout.Button("Triangulate Delaunay")) 16 | { 17 | drg.StartTriangulation(); 18 | } 19 | if (GUILayout.Button("Generate Straight Corridor Lib")) 20 | { 21 | drg.StartGenerateStraightConnectionLib(drg.rooms); 22 | } 23 | if (GUILayout.Button("Generate Straight Corridor")) 24 | { 25 | drg.StraightCorridorGeneration(); 26 | } 27 | if (GUILayout.Button("Generate L Corridor Lib")) 28 | { 29 | drg.StartGenerateLConnectionLib(drg.rooms); 30 | } 31 | if (GUILayout.Button("Generate L Corridor")) 32 | { 33 | drg.LCorridorGeneration(); 34 | } 35 | } 36 | } 37 | 38 | [CustomEditor(typeof(DungeonGenerator), true)] 39 | public class DungeonGeneratorEditor : Editor 40 | { 41 | DungeonGenerator dg { get { return (DungeonGenerator)target; } } 42 | 43 | public override void OnInspectorGUI() 44 | { 45 | if (GUILayout.Button("Generate")) 46 | { 47 | dg.StartRoomGeneration(); 48 | } 49 | if (GUILayout.Button("Toggle Gizmos")) 50 | { 51 | dg.drawGizmos = !dg.drawGizmos; 52 | } 53 | if(GUILayout.Button("Toggle Debug Mode")) 54 | { 55 | string definesString = PlayerSettings.GetScriptingDefineSymbolsForGroup(EditorUserBuildSettings.selectedBuildTargetGroup); 56 | List allDefines = definesString.Split(';').ToList(); 57 | if (allDefines.Contains("DEBUG_MODE")) 58 | { 59 | allDefines.Remove("DEBUG_MODE"); 60 | } 61 | else 62 | { 63 | allDefines.Add("DEBUG_MODE"); 64 | } 65 | PlayerSettings.SetScriptingDefineSymbolsForGroup( 66 | EditorUserBuildSettings.selectedBuildTargetGroup, 67 | string.Join(";", allDefines.ToArray())); 68 | } 69 | /* 70 | if (GUILayout.Button("Visualize With Collider")) 71 | { 72 | dg.CreateColliderVisual(); 73 | } 74 | if (GUILayout.Button("Remove All Collider Visualization")) 75 | { 76 | dg.DeleteAllColliderVisual(); 77 | }*/ 78 | base.OnInspectorGUI(); 79 | } 80 | 81 | } 82 | 83 | [CustomEditor(typeof(DungeonRoomsGenerator), true)] 84 | public class DungeonRoomGeneratorEditor : DungeonGeneratorEditor 85 | { 86 | DungeonRoomsGenerator drg { get { return (DungeonRoomsGenerator)target; } } 87 | public override void OnInspectorGUI() 88 | { 89 | base.OnInspectorGUI(); 90 | } 91 | } 92 | 93 | [CustomEditor(typeof(TilemapBSPDriver))] 94 | public class TilemapBSPDriverEditor : Editor 95 | { 96 | TilemapBSPDriver t { get { return (TilemapBSPDriver)target; } } 97 | 98 | public override void OnInspectorGUI() 99 | { 100 | if(GUILayout.Button("Apply Tile")) 101 | { 102 | t.ApplyTile(); 103 | } 104 | if(GUILayout.Button("Remove All Tile")) 105 | { 106 | t.RemoveTiles(); 107 | } 108 | base.OnInspectorGUI(); 109 | } 110 | } 111 | 112 | [CustomEditor(typeof(DelaunayDungeonGenerator))] 113 | public class DelaunayDungeonGeneratorEditor : Editor 114 | { 115 | DelaunayDungeonGenerator ddg { get { return (DelaunayDungeonGenerator)target; } } 116 | 117 | public override void OnInspectorGUI() 118 | { 119 | if (GUILayout.Button("Complete Actions")) 120 | { 121 | ddg.DoGeneration(); 122 | } 123 | if (GUILayout.Button("Triangulate Delaunay")) 124 | { 125 | ddg.StartTriangulation(); 126 | } 127 | if (GUILayout.Button("Create Corridors")) 128 | { 129 | ddg.dg.StartCorridorsGeneration(ddg.mainRooms); 130 | } 131 | if (GUILayout.Button("Generate Straight Corridor Lib")) 132 | { 133 | ddg.dg.StartGenerateStraightConnectionLib(ddg.mainRooms); 134 | } 135 | if (GUILayout.Button("Generate Straight Corridor")) 136 | { 137 | ddg.dg.StraightCorridorGeneration(); 138 | } 139 | if (GUILayout.Button("Generate L Corridor Lib")) 140 | { 141 | ddg.dg.StartGenerateLConnectionLib(ddg.mainRooms); 142 | } 143 | if (GUILayout.Button("Generate L Corridor")) 144 | { 145 | ddg.dg.LCorridorGeneration(); 146 | } 147 | base.OnInspectorGUI(); 148 | } 149 | } 150 | } 151 | -------------------------------------------------------------------------------- /Assets/DungeonGenerator/Scripts/Editor/DungeonGeneratorEditor.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 002838781bbb7294c9727e8cd6602803 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Assets/DungeonGenerator/Scripts/Editor/NodeGraphDungeonWindow.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using UnityEngine; 4 | using UnityEditor; 5 | 6 | namespace DI.DungeonGenerator 7 | { 8 | public class NodeGraphDungeonWindow : EditorWindow { 9 | 10 | private GUIStyle nodeStyle; 11 | 12 | private Vector2 offset; 13 | 14 | private INodeGraph ngp { 15 | get { 16 | if (Selection.activeObject != null) { 17 | if(Selection.activeObject.GetType().GetInterface("INodeGraph") == typeof(INodeGraph)) 18 | return Selection.activeObject as INodeGraph; 19 | } 20 | return null; 21 | } 22 | } 23 | public static NodeGraphDungeonWindow Instance 24 | { 25 | get { return GetWindow(); } 26 | } 27 | public static Rect GetSize 28 | { 29 | get { return Instance.position; } 30 | } 31 | 32 | [MenuItem("Window/Node Graph Dungeon Editor")] 33 | private static void OpenWindow() 34 | { 35 | NodeGraphDungeonWindow window = GetWindow(); 36 | window.titleContent = new GUIContent("Node Graph Dungeon Editor"); 37 | } 38 | 39 | private void OnEnable() 40 | { 41 | nodeStyle = new GUIStyle(); 42 | nodeStyle.normal.background = EditorGUIUtility.Load("builtin skins/darkskin/images/node1.png") as Texture2D; 43 | nodeStyle.border = new RectOffset(12, 12, 12, 12); 44 | } 45 | 46 | private void OnGUI() 47 | { 48 | DrawGrid(20, 0.2f, Color.gray); 49 | DrawGrid(100, 0.4f, Color.gray); 50 | //float toolbarHeight = EditorStyles.toolbar.CalcHeight(new GUIContent(""), 50); 51 | 52 | DrawNodes(); 53 | 54 | EditorGUILayout.LabelField("", EditorStyles.toolbar); 55 | ProcessEvents(Event.current); 56 | if (GUI.changed) 57 | Repaint(); 58 | } 59 | 60 | private void DrawNodes() 61 | { 62 | if (ngp == null) 63 | return; 64 | Debug.Log((NodeTilemap)ngp.GetNodes()[0]); 65 | foreach(Node n in ngp.GetNodes()) 66 | { 67 | GUI.Box(new Rect(n.rectPosition.position + offset, n.rectPosition.size), n.id.ToString(), nodeStyle); 68 | n.DrawConnection(ngp.GetNodes(), offset); 69 | } 70 | } 71 | 72 | private void ProcessEvents(Event e) 73 | { 74 | switch (e.type) 75 | { 76 | case EventType.MouseDrag: 77 | if (e.button == 2) 78 | { 79 | offset += e.delta; 80 | GUI.changed = true; 81 | } 82 | break; 83 | } 84 | } 85 | 86 | private void DrawGrid(float gridSpacing, float gridOpacity, Color gridColor) 87 | { 88 | int widthDivs = Mathf.CeilToInt(position.width / gridSpacing); 89 | int heightDivs = Mathf.CeilToInt(position.height / gridSpacing); 90 | 91 | Handles.BeginGUI(); 92 | Handles.color = new Color(gridColor.r, gridColor.g, gridColor.b, gridOpacity); 93 | 94 | Vector3 newOffset = new Vector3(offset.x % gridSpacing, offset.y % gridSpacing, 0); 95 | 96 | for (int i = 0; i < widthDivs; i++) 97 | { 98 | Handles.DrawLine(new Vector3(gridSpacing * i, -gridSpacing, 0) + newOffset, new Vector3(gridSpacing * i, position.height, 0f) + newOffset); 99 | } 100 | 101 | for (int j = 0; j < heightDivs; j++) 102 | { 103 | Handles.DrawLine(new Vector3(-gridSpacing, gridSpacing * j, 0) + newOffset, new Vector3(position.width, gridSpacing * j, 0f) + newOffset); 104 | } 105 | 106 | Handles.color = Color.white; 107 | Handles.EndGUI(); 108 | } 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /Assets/DungeonGenerator/Scripts/Editor/NodeGraphDungeonWindow.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ba8229ee9ba817940bda703a722fecff 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Assets/DungeonGenerator/Scripts/Editor/NodeGraphGeneratorEditor.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using UnityEngine; 4 | using UnityEditor; 5 | 6 | namespace DI.DungeonGenerator { 7 | [CustomEditor(typeof(NodeGraphGenerator), true)] 8 | public class NodeGraphGeneratorEditor : Editor 9 | { 10 | NodeGraphGenerator ngp { get { return (NodeGraphGenerator)target; } } 11 | 12 | public override void OnInspectorGUI() 13 | { 14 | if (GUILayout.Button("Generate Nodes")) 15 | { 16 | ngp.StartGenerationSequence(); 17 | EditorUtility.SetDirty(ngp); 18 | if(NodeGraphDungeonWindow.Instance != null) 19 | NodeGraphDungeonWindow.Instance.Repaint(); 20 | } 21 | base.OnInspectorGUI(); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Assets/DungeonGenerator/Scripts/Editor/NodeGraphGeneratorEditor.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a82ba15b62eb58a46aa07f242c54d433 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Assets/DungeonGenerator/Scripts/Math2D.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: efcf43567412dc549836ea2c32d7fe36 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/DungeonGenerator/Scripts/Math2D/Math2d.cs: -------------------------------------------------------------------------------- 1 | /** 2 | * This script originally from https://github.com/setchi/Unity-LineSegmentsIntersection/blob/master/Assets/LineSegmentIntersection/Scripts/Math2d.cs. It is MIT license 3 | */ 4 | 5 | using System.Collections; 6 | using System.Collections.Generic; 7 | using UnityEngine; 8 | 9 | namespace LineSegmentsIntersection 10 | { 11 | public static class Math2d 12 | { 13 | public static bool LineSegmentsIntersection(Vector2 p1, Vector2 p2, Vector2 p3, Vector3 p4, out Vector2 intersection) 14 | { 15 | intersection = Vector2.zero; 16 | 17 | var d = (p2.x - p1.x) * (p4.y - p3.y) - (p2.y - p1.y) * (p4.x - p3.x); 18 | 19 | if (d == 0.0f) 20 | { 21 | return false; 22 | } 23 | 24 | var u = ((p3.x - p1.x) * (p4.y - p3.y) - (p3.y - p1.y) * (p4.x - p3.x)) / d; 25 | var v = ((p3.x - p1.x) * (p2.y - p1.y) - (p3.y - p1.y) * (p2.x - p1.x)) / d; 26 | 27 | if (u < 0.0f || u > 1.0f || v < 0.0f || v > 1.0f) 28 | { 29 | return false; 30 | } 31 | 32 | intersection.x = p1.x + u * (p2.x - p1.x); 33 | intersection.y = p1.y + u * (p2.y - p1.y); 34 | 35 | return true; 36 | } 37 | } 38 | } -------------------------------------------------------------------------------- /Assets/DungeonGenerator/Scripts/Math2D/Math2d.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 02c4e76181a04ad4abf378e5283b1029 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Assets/DungeonGenerator/Scripts/ProceduralDungeonGenerator.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f374a566675bb6c4ab22d2072b565ce2 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/DungeonGenerator/Scripts/ProceduralDungeonGenerator/BSPDungeonGeneration.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using UnityEngine; 4 | using Delaunay; 5 | using Delaunay.Geo; 6 | using System.Linq; 7 | 8 | namespace DI.DungeonGenerator 9 | { 10 | /// 11 | /// Binary Space Partition Algorithm uses for room creation. The connection still using Delaunay Triangulation 12 | /// 13 | public class BSPDungeonGeneration : DungeonRoomsGenerator { 14 | [SerializeField] private Vector2Int boardSize = new Vector2Int(30, 30); 15 | [SerializeField] private int partitionCount = 10; 16 | [SerializeField] private MinMaxFloat sliceRange = new MinMaxFloat(0.3f, 0.5f); 17 | [SerializeField, Tooltip("After creating all partition, will resize all side with the marginRoom. This will decreasing the size of the room")] private int marginRoom = 2; 18 | [SerializeField] private MinMaxFloat roomScaleSize = new MinMaxFloat(0.4f, 0.85f); 19 | 20 | //Delaunay 21 | Delaunay.Voronoi v; 22 | private List m_spanningTree; 23 | private List m_delaunayTriangulation; 24 | [SerializeField, Range(0f, .3f)] private float keepConnection = 0.15f; 25 | 26 | public Room SliceRoom(Room origin) 27 | { 28 | Room result = new Room(new Vector2Int((int)origin.rect.position.x, (int)origin.rect.position.y), new Vector2Int((int)origin.rect.size.x, (int)origin.rect.size.y)); 29 | if (origin.rect.width > origin.rect.height) 30 | { 31 | result.rect.width = Mathf.RoundToInt(sliceRange.Random() * origin.rect.width); 32 | origin.rect.width -= result.rect.width; 33 | result.rect.x = origin.rect.position.x + origin.rect.width; 34 | } 35 | else 36 | { 37 | result.rect.height = Mathf.RoundToInt(sliceRange.Random() * origin.rect.height); 38 | origin.rect.height -= result.rect.height; 39 | result.rect.y = origin.rect.position.y + origin.rect.height; 40 | } 41 | return result; 42 | } 43 | 44 | public override void StartRoomGeneration() 45 | { 46 | StartPartitioning(); 47 | RoomGeneration(); 48 | StartTriangulation(); 49 | StartCorridorsGeneration(rooms); 50 | //DoorGeneration(); 51 | //StartCorridorsCreation(0); 52 | } 53 | 54 | void StartPartitioning() 55 | { 56 | rooms.Clear(); 57 | rooms.Add(new Room(new Vector2Int(), boardSize)); 58 | 59 | int i = 0; 60 | while (i < partitionCount - 1) 61 | { 62 | //Slice from the biggest 63 | int bigRoom = 0; 64 | for (int r = 1; r < rooms.Count; r++) 65 | { 66 | if (rooms[bigRoom].rect.size.sqrMagnitude < rooms[r].rect.size.sqrMagnitude) 67 | bigRoom = r; 68 | } 69 | Room ro = SliceRoom(rooms[bigRoom]); 70 | ro.id = i; 71 | rooms.Add(ro); 72 | i++; 73 | } 74 | } 75 | 76 | void RoomGeneration() 77 | { 78 | foreach(Room r in rooms) 79 | { 80 | //Add Margin 81 | r.rect.x += marginRoom; 82 | r.rect.y += marginRoom; 83 | r.rect.width -= (marginRoom*2); 84 | r.rect.height -= (marginRoom*2); 85 | 86 | Rect _rect = r.rect; 87 | 88 | _rect.width = Mathf.RoundToInt(_rect.width * roomScaleSize.Random()); 89 | _rect.height = Mathf.RoundToInt(_rect.height * roomScaleSize.Random()); 90 | _rect.x += Mathf.RoundToInt((r.rect.width - _rect.width) * Random.Range(0f, 1f)); 91 | _rect.y += Mathf.RoundToInt((r.rect.height - _rect.height) * Random.Range(0f, 1f)); 92 | r.rect = _rect; 93 | } 94 | } 95 | 96 | public void StartTriangulation() 97 | { 98 | List m_points = rooms.Select(o => o.rect.center).ToList(); 99 | List colors = new List(); 100 | foreach (Vector2 v in m_points) 101 | colors.Add(0); 102 | 103 | v = new Voronoi(m_points, colors, new Rect(0, 0, -999999, 999999)); 104 | 105 | m_delaunayTriangulation = v.DelaunayTriangulation(); 106 | m_spanningTree = v.SpanningTree(KruskalType.MINIMUM); 107 | 108 | List trisLeft = new List(); 109 | foreach (LineSegment d in m_delaunayTriangulation) 110 | { 111 | bool safeToAdd = true; 112 | foreach (LineSegment s in m_spanningTree) 113 | { 114 | if ((d.p0 == s.p0 && d.p1 == s.p1) || (d.p0 == s.p1 && d.p1 == s.p0)) 115 | { 116 | safeToAdd = false; 117 | break; 118 | } 119 | } 120 | if (safeToAdd) 121 | trisLeft.Add(d); 122 | } 123 | 124 | trisLeft = trisLeft.OrderBy(o => (Vector2.SqrMagnitude((Vector2)(o.p0 - o.p1)))).ToList(); 125 | for (int i = 0; i < (int)(trisLeft.Count * keepConnection); i++) 126 | { 127 | m_spanningTree.Add(trisLeft[i]); 128 | } 129 | 130 | roomConnection.Clear(); 131 | foreach (LineSegment l in m_spanningTree) 132 | { 133 | if (roomConnection.ContainsKey(l)) 134 | continue; 135 | 136 | Room r1 = null, r2 = null; 137 | foreach (Room r in rooms) 138 | { 139 | if (r.rect.center == l.p0) 140 | r1 = r; 141 | else if (r.rect.center == l.p1) 142 | r2 = r; 143 | } 144 | 145 | if (r1 == null || r2 == null) 146 | { 147 | Debug.Log("Dude, something doesn't right! Room is not detected in triangulation! Check here"); 148 | } 149 | else 150 | { 151 | roomConnection.Add(l, new List(2) { r1, r2 }); 152 | } 153 | } 154 | } 155 | } 156 | 157 | } 158 | -------------------------------------------------------------------------------- /Assets/DungeonGenerator/Scripts/ProceduralDungeonGenerator/BSPDungeonGeneration.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1638934f63a25464e8cc8930104cd77a 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Assets/DungeonGenerator/Scripts/ProceduralDungeonGenerator/DelaunayDungeonGenerator.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using UnityEngine; 4 | using System.Linq; 5 | using Delaunay; 6 | using Delaunay.Geo; 7 | 8 | namespace DI.DungeonGenerator 9 | { 10 | //this implementation need https://github.com/jceipek/Unity-delaunay. It is MIT license, project already imported. 11 | public class DelaunayDungeonGenerator : MonoBehaviour { 12 | 13 | public DungeonRoomsGenerator dg { get { if (m_dg == null) m_dg = GetComponent(); return m_dg; } } 14 | private DungeonRoomsGenerator m_dg; 15 | 16 | [SerializeField, Range(0f, 1f)] private float mainRoomSize = 0.5f; 17 | [SerializeField, Range(0f, .1f)] private float keepConnection = 0.05f; 18 | 19 | [HideInInspector]public List mainRooms = new List(); 20 | 21 | //Delaunay 22 | Delaunay.Voronoi v; 23 | private List m_spanningTree; 24 | private List m_delaunayTriangulation; 25 | #if DEBUG_MODE 26 | public bool drawTriangulation = true; 27 | public bool drawSpanningTree = true; 28 | #endif 29 | 30 | public void StartTriangulation() 31 | { 32 | if (dg == null) 33 | return; 34 | mainRooms.Clear(); 35 | float mean = dg.rooms.Average(o => o.rect.size.sqrMagnitude); 36 | var roomFromTheBiggest = dg.rooms.OrderBy(o => o.rect.size.sqrMagnitude).ToList(); 37 | roomFromTheBiggest.Reverse(); 38 | foreach(Room r in roomFromTheBiggest) 39 | { 40 | if(r.rect.size.sqrMagnitude >= mean) 41 | { 42 | mainRooms.Add(r); 43 | } 44 | if (mainRooms.Count >= dg.rooms.Count * mainRoomSize) 45 | break; 46 | } 47 | 48 | List m_points = mainRooms.Select(o => o.rect.center).ToList(); 49 | List colors = new List(); 50 | foreach (Vector2 v in m_points) 51 | colors.Add(0); 52 | 53 | v = new Voronoi(m_points, colors, new Rect(0, 0, -999999, 999999)); 54 | 55 | m_delaunayTriangulation = v.DelaunayTriangulation(); 56 | m_spanningTree = v.SpanningTree(KruskalType.MINIMUM); 57 | 58 | List trisLeft = new List(); 59 | foreach(LineSegment d in m_delaunayTriangulation) 60 | { 61 | bool safeToAdd = true; 62 | foreach(LineSegment s in m_spanningTree) 63 | { 64 | if ((d.p0 == s.p0 && d.p1 == s.p1) || (d.p0 == s.p1 && d.p1 == s.p0)) 65 | { 66 | safeToAdd = false; 67 | break; 68 | } 69 | } 70 | if(safeToAdd) 71 | trisLeft.Add(d); 72 | } 73 | 74 | trisLeft = trisLeft.OrderBy(o => (Vector2.SqrMagnitude((Vector2)(o.p0 - o.p1)))).ToList(); 75 | for(int i = 0; i < (int)(trisLeft.Count * keepConnection); i++) 76 | { 77 | m_spanningTree.Add(trisLeft[i]); 78 | } 79 | 80 | dg.roomConnection.Clear(); 81 | foreach(LineSegment l in m_spanningTree) 82 | { 83 | if (dg.roomConnection.ContainsKey(l)) 84 | continue; 85 | 86 | Room r1 = null, r2 = null; 87 | foreach(Room r in mainRooms) 88 | { 89 | if (r.rect.center == l.p0) 90 | r1 = r; 91 | else if (r.rect.center == l.p1) 92 | r2 = r; 93 | } 94 | 95 | if(r1 == null || r2 == null) 96 | { 97 | #if DEBUG_MODE 98 | Debug.Log("Dude, something doesn't right! Room is not detected in triangulation! Check here"); 99 | #endif 100 | } 101 | else 102 | { 103 | dg.roomConnection.Add(l, new List(2) { r1, r2 }); 104 | } 105 | } 106 | } 107 | 108 | public void DoGeneration() 109 | { 110 | dg.StartRoomGeneration(); 111 | StartTriangulation(); 112 | dg.StartCorridorsGeneration(mainRooms); 113 | } 114 | 115 | #if UNITY_EDITOR 116 | private void OnDrawGizmosSelected() 117 | { 118 | #if DEBUG_MODE 119 | Gizmos.color = Color.magenta; 120 | if (m_delaunayTriangulation != null && drawTriangulation) 121 | { 122 | for (int i = 0; i < m_delaunayTriangulation.Count; i++) 123 | { 124 | Vector2 left = (Vector2)m_delaunayTriangulation[i].p0; 125 | Vector2 right = (Vector2)m_delaunayTriangulation[i].p1; 126 | Gizmos.DrawLine((Vector3)left, (Vector3)right); 127 | } 128 | } 129 | if (m_spanningTree != null && drawSpanningTree) 130 | { 131 | Gizmos.color = Color.green; 132 | for (int i = 0; i < m_spanningTree.Count; i++) 133 | { 134 | LineSegment seg = m_spanningTree[i]; 135 | Vector2 left = (Vector2)seg.p0; 136 | Vector2 right = (Vector2)seg.p1; 137 | Gizmos.DrawLine((Vector3)left, (Vector3)right); 138 | } 139 | } 140 | for (int i = 0; i < mainRooms.Count; i++) 141 | { 142 | Gizmos.color = Color.magenta; 143 | Vector2 bottomLeft = mainRooms[i].rect.position; 144 | Vector2 topRight = mainRooms[i].rect.position + mainRooms[i].rect.size; 145 | Vector2 topLeft = bottomLeft + Vector2.up * mainRooms[i].rect.height; 146 | Vector2 bottomRight = bottomLeft + Vector2.right * mainRooms[i].rect.width; 147 | 148 | Gizmos.DrawLine(bottomLeft, bottomRight); 149 | Gizmos.DrawLine(bottomLeft, topLeft); 150 | Gizmos.DrawLine(topRight, topLeft); 151 | Gizmos.DrawLine(topRight, bottomRight); 152 | 153 | UnityEditor.Handles.Label(topLeft + Vector2.right, mainRooms[i].id.ToString()); 154 | 155 | Gizmos.color = Color.red; 156 | foreach(Door r in mainRooms[i].doorPositions) 157 | { 158 | Gizmos.color = Color.green; 159 | bottomLeft = r.position; 160 | topRight = r.position + r.size; 161 | topLeft = bottomLeft + Vector2.up * r.size.y; 162 | bottomRight = bottomLeft + Vector2.right * r.size.x; 163 | 164 | Gizmos.DrawLine(bottomLeft, bottomRight); 165 | Gizmos.DrawLine(bottomLeft, topLeft); 166 | Gizmos.DrawLine(topRight, topLeft); 167 | Gizmos.DrawLine(topRight, bottomRight); 168 | 169 | Gizmos.color = Color.red; 170 | bottomLeft = r.corridor.position; 171 | topRight = r.corridor.position + r.corridor.size; 172 | topLeft = bottomLeft + Vector2.up * r.corridor.height; 173 | bottomRight = bottomLeft + Vector2.right * r.corridor.width; 174 | 175 | Gizmos.DrawLine(bottomLeft, bottomRight); 176 | Gizmos.DrawLine(bottomLeft, topLeft); 177 | Gizmos.DrawLine(topRight, topLeft); 178 | Gizmos.DrawLine(topRight, bottomRight); 179 | } 180 | } 181 | #endif 182 | } 183 | #endif 184 | } 185 | } 186 | -------------------------------------------------------------------------------- /Assets/DungeonGenerator/Scripts/ProceduralDungeonGenerator/DelaunayDungeonGenerator.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: bdb211c4b97be564b8964a64cb3172a5 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Assets/DungeonGenerator/Scripts/ProceduralDungeonGenerator/DungeonGenerator.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using UnityEngine; 4 | 5 | namespace DI.DungeonGenerator 6 | { 7 | public class DungeonGenerator : MonoBehaviour { 8 | 9 | public virtual void StartRoomGeneration() { } 10 | [HideInInspector] public List rooms = new List(); 11 | //[HideInInspector] public List corridors = new List(); 12 | [SerializeField] protected int corridorWidth = 3; 13 | 14 | #region UNITY_EDITOR 15 | #if UNITY_EDITOR 16 | [HideInInspector]public bool drawGizmos = true; 17 | protected virtual void OnDrawGizmosSelected() 18 | { 19 | if (!drawGizmos) 20 | return; 21 | if(rooms == null) 22 | { 23 | print(rooms); 24 | return; 25 | } 26 | for (int i = 0; i < rooms.Count; i++) 27 | { 28 | 29 | Vector2 bottomLeft = (rooms)[i].rect.position; 30 | Vector2 topRight = (rooms)[i].rect.position + (rooms)[i].rect.size; 31 | Vector2 topLeft = bottomLeft + Vector2.up * (rooms)[i].rect.height; 32 | Vector2 bottomRight = bottomLeft + Vector2.right * (rooms)[i].rect.width; 33 | 34 | Gizmos.DrawLine(bottomLeft, bottomRight); 35 | Gizmos.DrawLine(bottomLeft, topLeft); 36 | Gizmos.DrawLine(topRight, topLeft); 37 | Gizmos.DrawLine(topRight, bottomRight); 38 | 39 | UnityEditor.Handles.Label(topLeft + Vector2.right, rooms[i].id.ToString()); 40 | 41 | } 42 | //foreach (Corridor r in corridors) 43 | //{ 44 | // foreach (Rect cr in r.ways) 45 | // Gizmos.DrawCube(cr.center, cr.size); 46 | //} 47 | } 48 | 49 | public void CreateColliderVisual() 50 | { 51 | int i = 0; 52 | foreach (Room r in (rooms)) 53 | { 54 | GameObject g = new GameObject(i.ToString()); 55 | var b = g.AddComponent(); 56 | b.size = r.rect.size; 57 | b.center = r.rect.center; 58 | g.transform.parent = transform; 59 | i++; 60 | } 61 | } 62 | public void DeleteAllColliderVisual() 63 | { 64 | for (int i = transform.childCount; i > 0; i--) 65 | { 66 | DestroyImmediate(transform.GetChild(i - 1).gameObject); 67 | } 68 | } 69 | #endif 70 | #endregion 71 | } 72 | 73 | [System.Serializable] 74 | public class MinMaxInt 75 | { 76 | [SerializeField] int min; 77 | [SerializeField] int max; 78 | 79 | public MinMaxInt(int min, int max) 80 | { 81 | this.min = min; 82 | this.max = max; 83 | } 84 | public int Random() 85 | { 86 | return UnityEngine.Random.Range(min, max + 1); 87 | } 88 | } 89 | 90 | [System.Serializable] 91 | public class MinMaxFloat 92 | { 93 | [SerializeField] float min; 94 | [SerializeField] float max; 95 | public MinMaxFloat(float min, float max) 96 | { 97 | this.min = min; 98 | this.max = max; 99 | } 100 | 101 | public float Random() 102 | { 103 | return UnityEngine.Random.Range(min, max); 104 | } 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /Assets/DungeonGenerator/Scripts/ProceduralDungeonGenerator/DungeonGenerator.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e266a49384d152b42bbf08165aeff77b 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Assets/DungeonGenerator/Scripts/ProceduralDungeonGenerator/DungeonRoomsGenerator.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e92ad669a53493a4899352b067ca9f6a 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Assets/DungeonGenerator/Scripts/ProceduralDungeonGenerator/Olds.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 4f49bb9798c65024ea39b98e637df64e 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/DungeonGenerator/Scripts/ProceduralDungeonGenerator/Olds/NodeGraphGenerator.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using UnityEngine; 4 | using System.Linq; 5 | 6 | #if UNITY_EDITOR 7 | using UnityEditor; 8 | #endif 9 | 10 | namespace DI.DungeonGenerator 11 | { 12 | public interface INodeGraph 13 | { 14 | Node[] GetNodes(); 15 | } 16 | 17 | [System.Serializable] 18 | [CreateAssetMenu(fileName = "DungeonNodes", menuName = "DI/Dungeon/Node")] 19 | public class NodeGraphGenerator : ScriptableObject, INodeGraph { 20 | 21 | [SerializeField] protected int nodeCount = 10; 22 | [SerializeField] int maxBranchCount = 3; 23 | [SerializeField] bool randomConnectEndBranch = false; 24 | [Range(0.0f, 1.0f), SerializeField] float chanceConnectEndBranch = 0.5f; 25 | public Node[] nodes; 26 | 27 | public virtual void StartGenerationSequence() 28 | { 29 | GenerateNodes(); 30 | Rect rect = new Rect(0, 0, 60, 60); 31 | nodes[0].CalculatePosition(ref rect, new Vector2Int(120, 80), nodes); 32 | AddRandomizeEndBranchConnection(); 33 | } 34 | 35 | public void GenerateNodes() 36 | { 37 | nodes = new Node[nodeCount]; 38 | for (int i = 0; i < nodeCount; i++) 39 | nodes[i] = new Node(i); 40 | 41 | int currentIdx = 0; 42 | int indexUsed = 0; 43 | while (indexUsed < nodeCount -1) 44 | { 45 | int branch = Random.Range(1, maxBranchCount + 1); 46 | if (branch + indexUsed >= nodeCount) 47 | branch = nodeCount - indexUsed - 1; 48 | int tempBranch = branch; 49 | while (branch > 0) { 50 | nodes[currentIdx].AddConnection(indexUsed + branch); 51 | nodes[indexUsed + branch].parent = indexUsed; 52 | branch--; 53 | } 54 | indexUsed += tempBranch; 55 | currentIdx++; 56 | } 57 | } 58 | 59 | public void AddRandomizeEndBranchConnection() 60 | { 61 | if (randomConnectEndBranch) 62 | { 63 | Node candidate = null; 64 | for (int i = 0; i < nodeCount; i++) 65 | { 66 | Node n = nodes[i]; 67 | if (n.nodeConnections.Count == 0) 68 | { 69 | if (candidate == null) 70 | { 71 | if (Random.Range(0.0f, 1.0f) <= chanceConnectEndBranch) 72 | candidate = n; 73 | } 74 | else 75 | { 76 | candidate.AddConnection(i); 77 | candidate = null; 78 | } 79 | } 80 | } 81 | } 82 | } 83 | 84 | public Node[] GetNodes() 85 | { 86 | return nodes; 87 | } 88 | } 89 | 90 | 91 | [System.Serializable] 92 | public class Node 93 | { 94 | public int id; 95 | public int parent; 96 | public List nodeConnections = new List(); 97 | 98 | public Node(){} 99 | public Node(int id) 100 | { 101 | this.id = id; 102 | } 103 | 104 | public bool AddConnection(int idx) 105 | { 106 | if (nodeConnections.IndexOf(idx) != -1) 107 | return false; 108 | nodeConnections.Add(idx); 109 | return true; 110 | } 111 | 112 | #if UNITY_EDITOR 113 | public Rect rectPosition; 114 | public void CalculatePosition(ref Rect rect, Vector2Int spacing, Node[] nodes) 115 | { 116 | ////Draw from the most far 117 | rect.x += spacing.x; 118 | foreach (int n in nodeConnections) 119 | { 120 | try 121 | { 122 | nodes[n].CalculatePosition(ref rect, spacing, nodes); 123 | } 124 | catch (System.Exception e) 125 | { 126 | Debug.Log(n); 127 | } 128 | } 129 | if (nodeConnections.Count == 0) 130 | rect.y += spacing.y; 131 | rect.x -= spacing.x; 132 | rectPosition = rect; 133 | if (nodeConnections.Count > 0) 134 | rectPosition.y = nodes[nodeConnections[0]].rectPosition.y + (nodes[nodeConnections[nodeConnections.Count - 1]].rectPosition.y - nodes[nodeConnections[0]].rectPosition.y) / 2; 135 | } 136 | public void DrawConnection(Node[] nodes, Vector2 offset) 137 | { 138 | foreach (int i in nodeConnections) 139 | { 140 | Node n = nodes[i]; 141 | Handles.DrawBezier(rectPosition.position + offset + new Vector2(rectPosition.width, rectPosition.height / 2), 142 | n.rectPosition.position + offset + new Vector2(0, n.rectPosition.height / 2), 143 | rectPosition.center + offset - Vector2.left * 50f, 144 | n.rectPosition.center + offset + Vector2.left * 50f, 145 | Color.white, 146 | null, 147 | 2f 148 | ); 149 | } 150 | } 151 | #endif 152 | } 153 | } 154 | -------------------------------------------------------------------------------- /Assets/DungeonGenerator/Scripts/ProceduralDungeonGenerator/Olds/NodeGraphGenerator.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6603a91be1e92fc4ba44cb4a754b10b2 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Assets/DungeonGenerator/Scripts/ProceduralDungeonGenerator/Olds/NodeTilemapDungeonGenerator.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using UnityEngine; 4 | using UnityEngine.Tilemaps; 5 | 6 | namespace DI.DungeonGenerator { 7 | [System.Serializable] 8 | [CreateAssetMenu(fileName = "DungeonNodes", menuName = "DI/Dungeon/Tilemap Node")] 9 | public class NodeTilemapDungeonGenerator : NodeGraphGenerator 10 | { 11 | public NodeTilemap[] nodes; 12 | public Tilemap[] rooms; 13 | //for determining nodes room using index from rooms variable 14 | public int[] roomsIndexNodes; 15 | 16 | public override void StartGenerationSequence() 17 | { 18 | base.StartGenerationSequence(); 19 | nodes = new NodeTilemap[nodeCount]; 20 | roomsIndexNodes = new int[nodeCount]; 21 | for(int i = 0; i < nodes.Length; i++) 22 | { 23 | nodes[i] = new NodeTilemap(base.nodes[i]); 24 | roomsIndexNodes[i] = Random.Range(0, rooms.Length); 25 | } 26 | } 27 | } 28 | 29 | public class NodeTilemap : Node 30 | { 31 | public Tilemap room; 32 | public NodeTilemap(Node copy) 33 | { 34 | this.id = copy.id; 35 | this.nodeConnections = copy.nodeConnections; 36 | this.parent = copy.parent; 37 | this.rectPosition = copy.rectPosition; 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /Assets/DungeonGenerator/Scripts/ProceduralDungeonGenerator/Olds/NodeTilemapDungeonGenerator.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b70ea929cbbf1034787233db738824c2 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Assets/DungeonGenerator/Scripts/ProceduralDungeonGenerator/Olds/TilemapDungeonGenerator.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using UnityEngine; 4 | using UnityEngine.Tilemaps; 5 | 6 | namespace DI.DungeonGenerator{ 7 | public class TilemapDungeonGenerator : MonoBehaviour { 8 | [SerializeField] NodeTilemapDungeonGenerator node; 9 | [SerializeField] Tilemap tilemap; 10 | [SerializeField] Tile tile; 11 | 12 | List dummyRooms = new List(); 13 | 14 | void Start(){ 15 | DrawTiles(tilemap, node.rooms[0], Vector3Int.zero); 16 | } 17 | 18 | public void StartGenerationSequence(){ 19 | if(tilemap == null || node == null || tile == null) 20 | return; 21 | 22 | for(int i = 0; i < node.nodes.Length; i++){ 23 | 24 | } 25 | } 26 | 27 | //private Vector3Int FindNextPosition(Vector3Int parentCenter, int index, Vector3Int moveDirection) 28 | //{ 29 | // int iter = 0; 30 | // while (true) 31 | // { 32 | // if (tilemap.GetTile(parentCenter + moveDirection * iter) == null) 33 | // { 34 | // if (index == 0) 35 | // dummyRooms.Add(new DummyTilemap(parentCenter, node.rooms[index])); 36 | // else { 37 | 38 | // } 39 | // break; 40 | // } 41 | // iter++; 42 | // } 43 | //} 44 | 45 | private void DrawTiles(Tilemap targetTilemap, Tilemap copy, Vector3Int offset){ 46 | for(int x = 0; x < copy.size.x; x++){ 47 | for(int y = 0; y < copy.size.y; y++){ 48 | targetTilemap.SetTile(new Vector3Int(x,y,0) + offset, tile); 49 | } 50 | } 51 | } 52 | 53 | private class DummyTilemap 54 | { 55 | public Vector3Int origin; 56 | public Vector3Int size; 57 | public Vector3Int center { get { return origin + new Vector3Int(size.x / 2, size.y / 2, size.z); } } 58 | public List tileCoordinateUsed = new List(); 59 | 60 | public DummyTilemap(Vector3Int origin, Tilemap tilemap) { 61 | this.origin = origin; 62 | this.size = tilemap.size; 63 | Vector3Int offset = origin - tilemap.origin; 64 | for (int x = 0; x < tilemap.size.x; x++) 65 | { 66 | for (int y = 0; y < tilemap.size.y; y++) 67 | { 68 | if (tilemap.GetTile(new Vector3Int(x, y, 0)) != null) { 69 | Vector3Int result = tilemap.origin + offset; 70 | result.x += x; 71 | result.y += y; 72 | tileCoordinateUsed.Add(result); 73 | } 74 | } 75 | } 76 | } 77 | } 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /Assets/DungeonGenerator/Scripts/ProceduralDungeonGenerator/Olds/TilemapDungeonGenerator.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 444bf4399ffc7654c803ab14ddbe8860 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Assets/DungeonGenerator/Scripts/ProceduralDungeonGenerator/Room.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using UnityEngine; 4 | using LineSegmentsIntersection; 5 | 6 | namespace DI.DungeonGenerator 7 | { 8 | [System.Serializable] 9 | public class Room 10 | { 11 | public int id; 12 | public Rect rect; 13 | public List doorPositions = new List(); 14 | 15 | public Room() { } 16 | public Room(Vector2Int position, Vector2Int size) 17 | { 18 | rect.size = size; 19 | rect.position = position; 20 | } 21 | 22 | public Vector2 size 23 | { 24 | get { return rect.size; } 25 | } 26 | 27 | public Vector2 position 28 | { 29 | get { return rect.position; } 30 | } 31 | 32 | public bool Overlap(Rect r) 33 | { 34 | return rect.Overlaps(r); 35 | } 36 | 37 | [System.Obsolete("Use Rect.Intersect()")] 38 | public bool Intersect(Vector2 p1, Vector2 p2, out List intersection) 39 | { 40 | intersection = new List(); 41 | Vector2 r; 42 | if(Math2d.LineSegmentsIntersection(p1, p2, rect.position, rect.position + Vector2.up * rect.height, out r)) 43 | intersection.Add(r); 44 | if (Math2d.LineSegmentsIntersection(p1, p2, rect.position, rect.position + Vector2.right * rect.width, out r)) 45 | intersection.Add(r); 46 | if (Math2d.LineSegmentsIntersection(p1, p2, rect.position + rect.size, rect.position + Vector2.up * rect.height, out r)) 47 | intersection.Add(r); 48 | if (Math2d.LineSegmentsIntersection(p1, p2, rect.position + rect.size, rect.position + Vector2.right * rect.width, out r)) 49 | intersection.Add(r); 50 | 51 | return intersection.Count != 0; 52 | } 53 | } 54 | 55 | [System.Serializable] 56 | public class Door 57 | { 58 | public Vector2Int position 59 | { 60 | get 61 | { 62 | return new Vector2Int((int)doorRect.position.x, (int)doorRect.position.y); 63 | } 64 | set 65 | { 66 | doorRect.position = value; 67 | } 68 | } 69 | public Vector2Int size 70 | { 71 | get { return new Vector2Int((int)doorRect.size.x, (int)doorRect.size.y); } 72 | set { doorRect.size = value; } 73 | } 74 | private Rect doorRect; 75 | public Rect corridor; 76 | //0 : no direction, 1 : vertical direction, 2 : horizontal direction 77 | public CorridorDir corridorDir = 0; 78 | } 79 | 80 | public static class RectExtension 81 | { 82 | public static bool Intersect(this Rect _r, Vector2 p1, Vector2 p2, out Vector2 point) 83 | { 84 | bool result = false; 85 | point = new Vector2(); 86 | if (Math2d.LineSegmentsIntersection(p1, p2, _r.position, _r.position + Vector2.up * _r.height, out point)) 87 | { 88 | result = true; 89 | p2 = point; 90 | } 91 | if (Math2d.LineSegmentsIntersection(p1, p2, _r.position, _r.position + Vector2.right * _r.width, out point)) 92 | { 93 | result = true; 94 | p2 = point; 95 | } 96 | if (Math2d.LineSegmentsIntersection(p1, p2, _r.position + Vector2.up * _r.height, _r.position + _r.size, out point)) 97 | { 98 | result = true; 99 | p2 = point; 100 | } 101 | if (Math2d.LineSegmentsIntersection(p1, p2, _r.position + Vector2.right * _r.width, _r.position + _r.size, out point)) 102 | { 103 | result = true; 104 | p2 = point; 105 | } 106 | point = p2; 107 | return result; 108 | } 109 | } 110 | 111 | /* 112 | [System.Serializable] 113 | public class Corridor 114 | { 115 | public Vector2Int startCorridor { get { return doorPosition[0]; } set { doorPosition[0] = value; } } 116 | public Vector2Int endCorridor { get { return doorPosition[1]; } set { doorPosition[1] = value; } } 117 | public Vector2Int[] doorPosition = new Vector2Int[2] { new Vector2Int(-1, -1), new Vector2Int(-1, -1) }; 118 | public List ways = new List(); 119 | 120 | public bool Intersect(Vector2 p1, Vector2 p2, out Vector2 point) 121 | { 122 | bool result = false; 123 | point = new Vector2(); 124 | foreach(Rect rect in ways) 125 | { 126 | Vector2 p = new Vector2(Mathf.Infinity, Mathf.Infinity); 127 | if (Math2d.LineSegmentsIntersection(p1, p2, rect.position, rect.position + Vector2.up * rect.height, out point)) 128 | { 129 | result = true; 130 | if (p.sqrMagnitude > point.sqrMagnitude) 131 | p = point; 132 | } 133 | if (Math2d.LineSegmentsIntersection(p1, p2, rect.position, rect.position + Vector2.right * rect.width, out point)) 134 | { 135 | result = true; 136 | if (p.sqrMagnitude > point.sqrMagnitude) 137 | p = point; 138 | } 139 | if (Math2d.LineSegmentsIntersection(p1, p2, rect.position + rect.size, rect.position + Vector2.up * rect.height, out point)) 140 | { 141 | result = true; 142 | if (p.sqrMagnitude > point.sqrMagnitude) 143 | p = point; 144 | } 145 | if (Math2d.LineSegmentsIntersection(p1, p2, rect.position + rect.size, rect.position + Vector2.right * rect.width, out point)) 146 | { 147 | result = true; 148 | if (p.sqrMagnitude > point.sqrMagnitude) 149 | p = point; 150 | } 151 | point = p; 152 | } 153 | return result; 154 | } 155 | }*/ 156 | 157 | } -------------------------------------------------------------------------------- /Assets/DungeonGenerator/Scripts/ProceduralDungeonGenerator/Room.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 221a248d7a1817749b683ca68277f9ed 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Assets/DungeonGenerator/Scripts/ProceduralDungeonGenerator/TilemapBSPDriver.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using UnityEngine; 4 | using UnityEngine.Tilemaps; 5 | 6 | namespace DI.DungeonGenerator 7 | { 8 | [RequireComponent(typeof(BSPDungeonGeneration))] 9 | public class TilemapBSPDriver : MonoBehaviour { 10 | [SerializeField] Tile tile; 11 | [SerializeField] Tilemap tilemap; 12 | BSPDungeonGeneration bspdungeon; 13 | 14 | private void Awake() 15 | { 16 | bspdungeon = GetComponent(); 17 | bspdungeon.StartRoomGeneration(); 18 | } 19 | 20 | private void Update() 21 | { 22 | if (Input.GetKeyDown(KeyCode.B)) 23 | { 24 | ApplyTile(); 25 | } 26 | } 27 | 28 | public void ApplyTile() 29 | { 30 | if (bspdungeon == null) 31 | bspdungeon = GetComponent(); 32 | foreach(Room r in bspdungeon.rooms) 33 | { 34 | int _x = 0; 35 | while(_x < Mathf.Abs(r.rect.width)) 36 | { 37 | int _y = 0; 38 | while(_y < Mathf.Abs(r.rect.height)) 39 | { 40 | Vector3Int v = new Vector3Int((int)(r.rect.x + _x * Mathf.Sign(r.rect.width) + (Mathf.Sign(r.rect.width) == -1 ? (-1) : 0)), (int)(r.rect.y + _y * Mathf.Sign(r.rect.height) + (Mathf.Sign(r.rect.height) == -1 ? (-1) : 0)), 0); 41 | tilemap.SetTile(v, tile); 42 | _y++; 43 | } 44 | _x++; 45 | } 46 | } 47 | //foreach(Corridor c in bspdungeon.corridors) 48 | //{ 49 | // foreach(Rect r in c.ways) 50 | // { 51 | // int _x = 0; 52 | // while (_x < Mathf.Abs(r.width)) 53 | // { 54 | // int _y = 0; 55 | // while (_y < Mathf.Abs(r.height)) 56 | // { 57 | // Vector3Int v = new Vector3Int((int)(r.x + _x * Mathf.Sign(r.width) + (Mathf.Sign(r.width) == -1 ? (-1) : 0)), (int)(r.y + _y * Mathf.Sign(r.height) + (Mathf.Sign(r.height) == -1 ? (-1) : 0)), 0); 58 | // tilemap.SetTile(v, tile); 59 | // _y++; 60 | // } 61 | // _x++; 62 | // } 63 | // } 64 | //} 65 | } 66 | 67 | public void RemoveTiles() 68 | { 69 | BoundsInt bounds = tilemap.cellBounds; 70 | print(bounds); 71 | for (int x = bounds.x; x < bounds.size.x; x++) { 72 | for(int y = bounds.y; y < bounds.size.y; y++) 73 | { 74 | tilemap.SetTile(new Vector3Int(x, y, 0), null); 75 | } 76 | } 77 | } 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /Assets/DungeonGenerator/Scripts/ProceduralDungeonGenerator/TilemapBSPDriver.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 98b8c9da5dd1a2d428b02db3ecdf8216 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright 2019 Damar Inderajati 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 8 | -------------------------------------------------------------------------------- /Packages/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "com.unity.2d.sprite": "1.0.0", 4 | "com.unity.2d.tilemap": "1.0.0", 5 | "com.unity.ads": "3.4.9", 6 | "com.unity.analytics": "3.3.5", 7 | "com.unity.collab-proxy": "1.2.16", 8 | "com.unity.ide.rider": "1.1.4", 9 | "com.unity.ide.vscode": "1.2.1", 10 | "com.unity.multiplayer-hlapi": "1.0.6", 11 | "com.unity.purchasing": "2.1.0", 12 | "com.unity.test-framework": "1.1.16", 13 | "com.unity.textmeshpro": "2.0.1", 14 | "com.unity.timeline": "1.2.6", 15 | "com.unity.ugui": "1.0.0", 16 | "com.unity.xr.legacyinputhelpers": "2.1.4", 17 | "com.unity.modules.ai": "1.0.0", 18 | "com.unity.modules.androidjni": "1.0.0", 19 | "com.unity.modules.animation": "1.0.0", 20 | "com.unity.modules.assetbundle": "1.0.0", 21 | "com.unity.modules.audio": "1.0.0", 22 | "com.unity.modules.cloth": "1.0.0", 23 | "com.unity.modules.director": "1.0.0", 24 | "com.unity.modules.imageconversion": "1.0.0", 25 | "com.unity.modules.imgui": "1.0.0", 26 | "com.unity.modules.jsonserialize": "1.0.0", 27 | "com.unity.modules.particlesystem": "1.0.0", 28 | "com.unity.modules.physics": "1.0.0", 29 | "com.unity.modules.physics2d": "1.0.0", 30 | "com.unity.modules.screencapture": "1.0.0", 31 | "com.unity.modules.terrain": "1.0.0", 32 | "com.unity.modules.terrainphysics": "1.0.0", 33 | "com.unity.modules.tilemap": "1.0.0", 34 | "com.unity.modules.ui": "1.0.0", 35 | "com.unity.modules.uielements": "1.0.0", 36 | "com.unity.modules.umbra": "1.0.0", 37 | "com.unity.modules.unityanalytics": "1.0.0", 38 | "com.unity.modules.unitywebrequest": "1.0.0", 39 | "com.unity.modules.unitywebrequestassetbundle": "1.0.0", 40 | "com.unity.modules.unitywebrequestaudio": "1.0.0", 41 | "com.unity.modules.unitywebrequesttexture": "1.0.0", 42 | "com.unity.modules.unitywebrequestwww": "1.0.0", 43 | "com.unity.modules.vehicles": "1.0.0", 44 | "com.unity.modules.video": "1.0.0", 45 | "com.unity.modules.vr": "1.0.0", 46 | "com.unity.modules.wind": "1.0.0", 47 | "com.unity.modules.xr": "1.0.0" 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /Packages/packages-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "com.unity.2d.sprite": { 4 | "version": "1.0.0", 5 | "depth": 0, 6 | "source": "builtin", 7 | "dependencies": {} 8 | }, 9 | "com.unity.2d.tilemap": { 10 | "version": "1.0.0", 11 | "depth": 0, 12 | "source": "builtin", 13 | "dependencies": {} 14 | }, 15 | "com.unity.ads": { 16 | "version": "3.4.9", 17 | "depth": 0, 18 | "source": "registry", 19 | "dependencies": { 20 | "com.unity.ugui": "1.0.0" 21 | }, 22 | "url": "https://packages.unity.com" 23 | }, 24 | "com.unity.analytics": { 25 | "version": "3.3.5", 26 | "depth": 0, 27 | "source": "registry", 28 | "dependencies": { 29 | "com.unity.ugui": "1.0.0" 30 | }, 31 | "url": "https://packages.unity.com" 32 | }, 33 | "com.unity.collab-proxy": { 34 | "version": "1.2.16", 35 | "depth": 0, 36 | "source": "registry", 37 | "dependencies": {}, 38 | "url": "https://packages.unity.com" 39 | }, 40 | "com.unity.ext.nunit": { 41 | "version": "1.0.0", 42 | "depth": 1, 43 | "source": "registry", 44 | "dependencies": {}, 45 | "url": "https://packages.unity.com" 46 | }, 47 | "com.unity.ide.rider": { 48 | "version": "1.1.4", 49 | "depth": 0, 50 | "source": "registry", 51 | "dependencies": { 52 | "com.unity.test-framework": "1.1.1" 53 | }, 54 | "url": "https://packages.unity.com" 55 | }, 56 | "com.unity.ide.vscode": { 57 | "version": "1.2.1", 58 | "depth": 0, 59 | "source": "registry", 60 | "dependencies": {}, 61 | "url": "https://packages.unity.com" 62 | }, 63 | "com.unity.multiplayer-hlapi": { 64 | "version": "1.0.6", 65 | "depth": 0, 66 | "source": "registry", 67 | "dependencies": { 68 | "nuget.mono-cecil": "0.1.6-preview" 69 | }, 70 | "url": "https://packages.unity.com" 71 | }, 72 | "com.unity.purchasing": { 73 | "version": "2.1.0", 74 | "depth": 0, 75 | "source": "registry", 76 | "dependencies": { 77 | "com.unity.ugui": "1.0.0" 78 | }, 79 | "url": "https://packages.unity.com" 80 | }, 81 | "com.unity.test-framework": { 82 | "version": "1.1.16", 83 | "depth": 0, 84 | "source": "registry", 85 | "dependencies": { 86 | "com.unity.ext.nunit": "1.0.0", 87 | "com.unity.modules.imgui": "1.0.0", 88 | "com.unity.modules.jsonserialize": "1.0.0" 89 | }, 90 | "url": "https://packages.unity.com" 91 | }, 92 | "com.unity.textmeshpro": { 93 | "version": "2.0.1", 94 | "depth": 0, 95 | "source": "registry", 96 | "dependencies": { 97 | "com.unity.ugui": "1.0.0" 98 | }, 99 | "url": "https://packages.unity.com" 100 | }, 101 | "com.unity.timeline": { 102 | "version": "1.2.6", 103 | "depth": 0, 104 | "source": "registry", 105 | "dependencies": {}, 106 | "url": "https://packages.unity.com" 107 | }, 108 | "com.unity.ugui": { 109 | "version": "1.0.0", 110 | "depth": 0, 111 | "source": "builtin", 112 | "dependencies": { 113 | "com.unity.modules.ui": "1.0.0", 114 | "com.unity.modules.imgui": "1.0.0" 115 | } 116 | }, 117 | "com.unity.xr.legacyinputhelpers": { 118 | "version": "2.1.4", 119 | "depth": 0, 120 | "source": "registry", 121 | "dependencies": {}, 122 | "url": "https://packages.unity.com" 123 | }, 124 | "nuget.mono-cecil": { 125 | "version": "0.1.6-preview", 126 | "depth": 1, 127 | "source": "registry", 128 | "dependencies": {}, 129 | "url": "https://packages.unity.com" 130 | }, 131 | "com.unity.modules.ai": { 132 | "version": "1.0.0", 133 | "depth": 0, 134 | "source": "builtin", 135 | "dependencies": {} 136 | }, 137 | "com.unity.modules.androidjni": { 138 | "version": "1.0.0", 139 | "depth": 0, 140 | "source": "builtin", 141 | "dependencies": {} 142 | }, 143 | "com.unity.modules.animation": { 144 | "version": "1.0.0", 145 | "depth": 0, 146 | "source": "builtin", 147 | "dependencies": {} 148 | }, 149 | "com.unity.modules.assetbundle": { 150 | "version": "1.0.0", 151 | "depth": 0, 152 | "source": "builtin", 153 | "dependencies": {} 154 | }, 155 | "com.unity.modules.audio": { 156 | "version": "1.0.0", 157 | "depth": 0, 158 | "source": "builtin", 159 | "dependencies": {} 160 | }, 161 | "com.unity.modules.cloth": { 162 | "version": "1.0.0", 163 | "depth": 0, 164 | "source": "builtin", 165 | "dependencies": { 166 | "com.unity.modules.physics": "1.0.0" 167 | } 168 | }, 169 | "com.unity.modules.director": { 170 | "version": "1.0.0", 171 | "depth": 0, 172 | "source": "builtin", 173 | "dependencies": { 174 | "com.unity.modules.audio": "1.0.0", 175 | "com.unity.modules.animation": "1.0.0" 176 | } 177 | }, 178 | "com.unity.modules.imageconversion": { 179 | "version": "1.0.0", 180 | "depth": 0, 181 | "source": "builtin", 182 | "dependencies": {} 183 | }, 184 | "com.unity.modules.imgui": { 185 | "version": "1.0.0", 186 | "depth": 0, 187 | "source": "builtin", 188 | "dependencies": {} 189 | }, 190 | "com.unity.modules.jsonserialize": { 191 | "version": "1.0.0", 192 | "depth": 0, 193 | "source": "builtin", 194 | "dependencies": {} 195 | }, 196 | "com.unity.modules.particlesystem": { 197 | "version": "1.0.0", 198 | "depth": 0, 199 | "source": "builtin", 200 | "dependencies": {} 201 | }, 202 | "com.unity.modules.physics": { 203 | "version": "1.0.0", 204 | "depth": 0, 205 | "source": "builtin", 206 | "dependencies": {} 207 | }, 208 | "com.unity.modules.physics2d": { 209 | "version": "1.0.0", 210 | "depth": 0, 211 | "source": "builtin", 212 | "dependencies": {} 213 | }, 214 | "com.unity.modules.screencapture": { 215 | "version": "1.0.0", 216 | "depth": 0, 217 | "source": "builtin", 218 | "dependencies": { 219 | "com.unity.modules.imageconversion": "1.0.0" 220 | } 221 | }, 222 | "com.unity.modules.subsystems": { 223 | "version": "1.0.0", 224 | "depth": 1, 225 | "source": "builtin", 226 | "dependencies": { 227 | "com.unity.modules.jsonserialize": "1.0.0" 228 | } 229 | }, 230 | "com.unity.modules.terrain": { 231 | "version": "1.0.0", 232 | "depth": 0, 233 | "source": "builtin", 234 | "dependencies": {} 235 | }, 236 | "com.unity.modules.terrainphysics": { 237 | "version": "1.0.0", 238 | "depth": 0, 239 | "source": "builtin", 240 | "dependencies": { 241 | "com.unity.modules.physics": "1.0.0", 242 | "com.unity.modules.terrain": "1.0.0" 243 | } 244 | }, 245 | "com.unity.modules.tilemap": { 246 | "version": "1.0.0", 247 | "depth": 0, 248 | "source": "builtin", 249 | "dependencies": { 250 | "com.unity.modules.physics2d": "1.0.0" 251 | } 252 | }, 253 | "com.unity.modules.ui": { 254 | "version": "1.0.0", 255 | "depth": 0, 256 | "source": "builtin", 257 | "dependencies": {} 258 | }, 259 | "com.unity.modules.uielements": { 260 | "version": "1.0.0", 261 | "depth": 0, 262 | "source": "builtin", 263 | "dependencies": { 264 | "com.unity.modules.imgui": "1.0.0", 265 | "com.unity.modules.jsonserialize": "1.0.0" 266 | } 267 | }, 268 | "com.unity.modules.umbra": { 269 | "version": "1.0.0", 270 | "depth": 0, 271 | "source": "builtin", 272 | "dependencies": {} 273 | }, 274 | "com.unity.modules.unityanalytics": { 275 | "version": "1.0.0", 276 | "depth": 0, 277 | "source": "builtin", 278 | "dependencies": { 279 | "com.unity.modules.unitywebrequest": "1.0.0", 280 | "com.unity.modules.jsonserialize": "1.0.0" 281 | } 282 | }, 283 | "com.unity.modules.unitywebrequest": { 284 | "version": "1.0.0", 285 | "depth": 0, 286 | "source": "builtin", 287 | "dependencies": {} 288 | }, 289 | "com.unity.modules.unitywebrequestassetbundle": { 290 | "version": "1.0.0", 291 | "depth": 0, 292 | "source": "builtin", 293 | "dependencies": { 294 | "com.unity.modules.assetbundle": "1.0.0", 295 | "com.unity.modules.unitywebrequest": "1.0.0" 296 | } 297 | }, 298 | "com.unity.modules.unitywebrequestaudio": { 299 | "version": "1.0.0", 300 | "depth": 0, 301 | "source": "builtin", 302 | "dependencies": { 303 | "com.unity.modules.unitywebrequest": "1.0.0", 304 | "com.unity.modules.audio": "1.0.0" 305 | } 306 | }, 307 | "com.unity.modules.unitywebrequesttexture": { 308 | "version": "1.0.0", 309 | "depth": 0, 310 | "source": "builtin", 311 | "dependencies": { 312 | "com.unity.modules.unitywebrequest": "1.0.0", 313 | "com.unity.modules.imageconversion": "1.0.0" 314 | } 315 | }, 316 | "com.unity.modules.unitywebrequestwww": { 317 | "version": "1.0.0", 318 | "depth": 0, 319 | "source": "builtin", 320 | "dependencies": { 321 | "com.unity.modules.unitywebrequest": "1.0.0", 322 | "com.unity.modules.unitywebrequestassetbundle": "1.0.0", 323 | "com.unity.modules.unitywebrequestaudio": "1.0.0", 324 | "com.unity.modules.audio": "1.0.0", 325 | "com.unity.modules.assetbundle": "1.0.0", 326 | "com.unity.modules.imageconversion": "1.0.0" 327 | } 328 | }, 329 | "com.unity.modules.vehicles": { 330 | "version": "1.0.0", 331 | "depth": 0, 332 | "source": "builtin", 333 | "dependencies": { 334 | "com.unity.modules.physics": "1.0.0" 335 | } 336 | }, 337 | "com.unity.modules.video": { 338 | "version": "1.0.0", 339 | "depth": 0, 340 | "source": "builtin", 341 | "dependencies": { 342 | "com.unity.modules.audio": "1.0.0", 343 | "com.unity.modules.ui": "1.0.0", 344 | "com.unity.modules.unitywebrequest": "1.0.0" 345 | } 346 | }, 347 | "com.unity.modules.vr": { 348 | "version": "1.0.0", 349 | "depth": 0, 350 | "source": "builtin", 351 | "dependencies": { 352 | "com.unity.modules.jsonserialize": "1.0.0", 353 | "com.unity.modules.physics": "1.0.0", 354 | "com.unity.modules.xr": "1.0.0" 355 | } 356 | }, 357 | "com.unity.modules.wind": { 358 | "version": "1.0.0", 359 | "depth": 0, 360 | "source": "builtin", 361 | "dependencies": {} 362 | }, 363 | "com.unity.modules.xr": { 364 | "version": "1.0.0", 365 | "depth": 0, 366 | "source": "builtin", 367 | "dependencies": { 368 | "com.unity.modules.physics": "1.0.0", 369 | "com.unity.modules.jsonserialize": "1.0.0", 370 | "com.unity.modules.subsystems": "1.0.0" 371 | } 372 | } 373 | } 374 | } 375 | -------------------------------------------------------------------------------- /ProjectSettings/AudioManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!11 &1 4 | AudioManager: 5 | m_ObjectHideFlags: 0 6 | m_Volume: 1 7 | Rolloff Scale: 1 8 | Doppler Factor: 1 9 | Default Speaker Mode: 2 10 | m_SampleRate: 0 11 | m_DSPBufferSize: 1024 12 | m_VirtualVoiceCount: 512 13 | m_RealVoiceCount: 32 14 | m_SpatializerPlugin: 15 | m_AmbisonicDecoderPlugin: 16 | m_DisableAudio: 0 17 | m_VirtualizeEffects: 1 18 | -------------------------------------------------------------------------------- /ProjectSettings/ClusterInputManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!236 &1 4 | ClusterInputManager: 5 | m_ObjectHideFlags: 0 6 | m_Inputs: [] 7 | -------------------------------------------------------------------------------- /ProjectSettings/DynamicsManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!55 &1 4 | PhysicsManager: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 7 7 | m_Gravity: {x: 0, y: -9.81, z: 0} 8 | m_DefaultMaterial: {fileID: 0} 9 | m_BounceThreshold: 2 10 | m_SleepThreshold: 0.005 11 | m_DefaultContactOffset: 0.01 12 | m_DefaultSolverIterations: 6 13 | m_DefaultSolverVelocityIterations: 1 14 | m_QueriesHitBackfaces: 0 15 | m_QueriesHitTriggers: 1 16 | m_EnableAdaptiveForce: 0 17 | m_ClothInterCollisionDistance: 0 18 | m_ClothInterCollisionStiffness: 0 19 | m_ContactsGeneration: 1 20 | m_LayerCollisionMatrix: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 21 | m_AutoSimulation: 1 22 | m_AutoSyncTransforms: 1 23 | m_ClothInterCollisionSettingsToggle: 0 24 | m_ContactPairsMode: 0 25 | m_BroadphaseType: 0 26 | m_WorldBounds: 27 | m_Center: {x: 0, y: 0, z: 0} 28 | m_Extent: {x: 250, y: 250, z: 250} 29 | m_WorldSubdivisions: 8 30 | -------------------------------------------------------------------------------- /ProjectSettings/EditorBuildSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!1045 &1 4 | EditorBuildSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 2 7 | m_Scenes: 8 | - enabled: 1 9 | path: Assets/Scenes/SampleScene.unity 10 | guid: 99c9720ab356a0642a771bea13969a05 11 | m_configObjects: {} 12 | -------------------------------------------------------------------------------- /ProjectSettings/EditorSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!159 &1 4 | EditorSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 9 7 | m_ExternalVersionControlSupport: Visible Meta Files 8 | m_SerializationMode: 2 9 | m_LineEndingsForNewScripts: 2 10 | m_DefaultBehaviorMode: 0 11 | m_PrefabRegularEnvironment: {fileID: 0} 12 | m_PrefabUIEnvironment: {fileID: 0} 13 | m_SpritePackerMode: 0 14 | m_SpritePackerPaddingPower: 1 15 | m_EtcTextureCompressorBehavior: 1 16 | m_EtcTextureFastCompressor: 1 17 | m_EtcTextureNormalCompressor: 2 18 | m_EtcTextureBestCompressor: 4 19 | m_ProjectGenerationIncludedExtensions: txt;xml;fnt;cd;asmref 20 | m_ProjectGenerationRootNamespace: 21 | m_CollabEditorSettings: 22 | inProgressEnabled: 1 23 | m_EnableTextureStreamingInEditMode: 1 24 | m_EnableTextureStreamingInPlayMode: 1 25 | m_AsyncShaderCompilation: 1 26 | m_EnterPlayModeOptionsEnabled: 0 27 | m_EnterPlayModeOptions: 3 28 | m_ShowLightmapResolutionOverlay: 1 29 | m_UseLegacyProbeSampleCount: 1 30 | m_AssetPipelineMode: 1 31 | m_CacheServerMode: 0 32 | m_CacheServerEndpoint: 33 | m_CacheServerNamespacePrefix: default 34 | m_CacheServerEnableDownload: 1 35 | m_CacheServerEnableUpload: 1 36 | -------------------------------------------------------------------------------- /ProjectSettings/GraphicsSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!30 &1 4 | GraphicsSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 12 7 | m_Deferred: 8 | m_Mode: 1 9 | m_Shader: {fileID: 69, guid: 0000000000000000f000000000000000, type: 0} 10 | m_DeferredReflections: 11 | m_Mode: 1 12 | m_Shader: {fileID: 74, guid: 0000000000000000f000000000000000, type: 0} 13 | m_ScreenSpaceShadows: 14 | m_Mode: 1 15 | m_Shader: {fileID: 64, guid: 0000000000000000f000000000000000, type: 0} 16 | m_LegacyDeferred: 17 | m_Mode: 1 18 | m_Shader: {fileID: 63, guid: 0000000000000000f000000000000000, type: 0} 19 | m_DepthNormals: 20 | m_Mode: 1 21 | m_Shader: {fileID: 62, guid: 0000000000000000f000000000000000, type: 0} 22 | m_MotionVectors: 23 | m_Mode: 1 24 | m_Shader: {fileID: 75, guid: 0000000000000000f000000000000000, type: 0} 25 | m_LightHalo: 26 | m_Mode: 1 27 | m_Shader: {fileID: 105, guid: 0000000000000000f000000000000000, type: 0} 28 | m_LensFlare: 29 | m_Mode: 1 30 | m_Shader: {fileID: 102, guid: 0000000000000000f000000000000000, type: 0} 31 | m_AlwaysIncludedShaders: 32 | - {fileID: 7, guid: 0000000000000000f000000000000000, type: 0} 33 | - {fileID: 15104, guid: 0000000000000000f000000000000000, type: 0} 34 | - {fileID: 15105, guid: 0000000000000000f000000000000000, type: 0} 35 | - {fileID: 15106, guid: 0000000000000000f000000000000000, type: 0} 36 | - {fileID: 10753, guid: 0000000000000000f000000000000000, type: 0} 37 | - {fileID: 10770, guid: 0000000000000000f000000000000000, type: 0} 38 | m_PreloadedShaders: [] 39 | m_SpritesDefaultMaterial: {fileID: 10754, guid: 0000000000000000f000000000000000, 40 | type: 0} 41 | m_CustomRenderPipeline: {fileID: 0} 42 | m_TransparencySortMode: 0 43 | m_TransparencySortAxis: {x: 0, y: 0, z: 1} 44 | m_DefaultRenderingPath: 1 45 | m_DefaultMobileRenderingPath: 1 46 | m_TierSettings: [] 47 | m_LightmapStripping: 0 48 | m_FogStripping: 0 49 | m_InstancingStripping: 0 50 | m_LightmapKeepPlain: 1 51 | m_LightmapKeepDirCombined: 1 52 | m_LightmapKeepDynamicPlain: 1 53 | m_LightmapKeepDynamicDirCombined: 1 54 | m_LightmapKeepShadowMask: 1 55 | m_LightmapKeepSubtractive: 1 56 | m_FogKeepLinear: 1 57 | m_FogKeepExp: 1 58 | m_FogKeepExp2: 1 59 | m_AlbedoSwatchInfos: [] 60 | m_LightsUseLinearIntensity: 0 61 | m_LightsUseColorTemperature: 0 62 | -------------------------------------------------------------------------------- /ProjectSettings/InputManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!13 &1 4 | InputManager: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 2 7 | m_Axes: 8 | - serializedVersion: 3 9 | m_Name: Horizontal 10 | descriptiveName: 11 | descriptiveNegativeName: 12 | negativeButton: left 13 | positiveButton: right 14 | altNegativeButton: a 15 | altPositiveButton: d 16 | gravity: 3 17 | dead: 0.001 18 | sensitivity: 3 19 | snap: 1 20 | invert: 0 21 | type: 0 22 | axis: 0 23 | joyNum: 0 24 | - serializedVersion: 3 25 | m_Name: Vertical 26 | descriptiveName: 27 | descriptiveNegativeName: 28 | negativeButton: down 29 | positiveButton: up 30 | altNegativeButton: s 31 | altPositiveButton: w 32 | gravity: 3 33 | dead: 0.001 34 | sensitivity: 3 35 | snap: 1 36 | invert: 0 37 | type: 0 38 | axis: 0 39 | joyNum: 0 40 | - serializedVersion: 3 41 | m_Name: Fire1 42 | descriptiveName: 43 | descriptiveNegativeName: 44 | negativeButton: 45 | positiveButton: left ctrl 46 | altNegativeButton: 47 | altPositiveButton: mouse 0 48 | gravity: 1000 49 | dead: 0.001 50 | sensitivity: 1000 51 | snap: 0 52 | invert: 0 53 | type: 0 54 | axis: 0 55 | joyNum: 0 56 | - serializedVersion: 3 57 | m_Name: Fire2 58 | descriptiveName: 59 | descriptiveNegativeName: 60 | negativeButton: 61 | positiveButton: left alt 62 | altNegativeButton: 63 | altPositiveButton: mouse 1 64 | gravity: 1000 65 | dead: 0.001 66 | sensitivity: 1000 67 | snap: 0 68 | invert: 0 69 | type: 0 70 | axis: 0 71 | joyNum: 0 72 | - serializedVersion: 3 73 | m_Name: Fire3 74 | descriptiveName: 75 | descriptiveNegativeName: 76 | negativeButton: 77 | positiveButton: left shift 78 | altNegativeButton: 79 | altPositiveButton: mouse 2 80 | gravity: 1000 81 | dead: 0.001 82 | sensitivity: 1000 83 | snap: 0 84 | invert: 0 85 | type: 0 86 | axis: 0 87 | joyNum: 0 88 | - serializedVersion: 3 89 | m_Name: Jump 90 | descriptiveName: 91 | descriptiveNegativeName: 92 | negativeButton: 93 | positiveButton: space 94 | altNegativeButton: 95 | altPositiveButton: 96 | gravity: 1000 97 | dead: 0.001 98 | sensitivity: 1000 99 | snap: 0 100 | invert: 0 101 | type: 0 102 | axis: 0 103 | joyNum: 0 104 | - serializedVersion: 3 105 | m_Name: Mouse X 106 | descriptiveName: 107 | descriptiveNegativeName: 108 | negativeButton: 109 | positiveButton: 110 | altNegativeButton: 111 | altPositiveButton: 112 | gravity: 0 113 | dead: 0 114 | sensitivity: 0.1 115 | snap: 0 116 | invert: 0 117 | type: 1 118 | axis: 0 119 | joyNum: 0 120 | - serializedVersion: 3 121 | m_Name: Mouse Y 122 | descriptiveName: 123 | descriptiveNegativeName: 124 | negativeButton: 125 | positiveButton: 126 | altNegativeButton: 127 | altPositiveButton: 128 | gravity: 0 129 | dead: 0 130 | sensitivity: 0.1 131 | snap: 0 132 | invert: 0 133 | type: 1 134 | axis: 1 135 | joyNum: 0 136 | - serializedVersion: 3 137 | m_Name: Mouse ScrollWheel 138 | descriptiveName: 139 | descriptiveNegativeName: 140 | negativeButton: 141 | positiveButton: 142 | altNegativeButton: 143 | altPositiveButton: 144 | gravity: 0 145 | dead: 0 146 | sensitivity: 0.1 147 | snap: 0 148 | invert: 0 149 | type: 1 150 | axis: 2 151 | joyNum: 0 152 | - serializedVersion: 3 153 | m_Name: Horizontal 154 | descriptiveName: 155 | descriptiveNegativeName: 156 | negativeButton: 157 | positiveButton: 158 | altNegativeButton: 159 | altPositiveButton: 160 | gravity: 0 161 | dead: 0.19 162 | sensitivity: 1 163 | snap: 0 164 | invert: 0 165 | type: 2 166 | axis: 0 167 | joyNum: 0 168 | - serializedVersion: 3 169 | m_Name: Vertical 170 | descriptiveName: 171 | descriptiveNegativeName: 172 | negativeButton: 173 | positiveButton: 174 | altNegativeButton: 175 | altPositiveButton: 176 | gravity: 0 177 | dead: 0.19 178 | sensitivity: 1 179 | snap: 0 180 | invert: 1 181 | type: 2 182 | axis: 1 183 | joyNum: 0 184 | - serializedVersion: 3 185 | m_Name: Fire1 186 | descriptiveName: 187 | descriptiveNegativeName: 188 | negativeButton: 189 | positiveButton: joystick button 0 190 | altNegativeButton: 191 | altPositiveButton: 192 | gravity: 1000 193 | dead: 0.001 194 | sensitivity: 1000 195 | snap: 0 196 | invert: 0 197 | type: 0 198 | axis: 0 199 | joyNum: 0 200 | - serializedVersion: 3 201 | m_Name: Fire2 202 | descriptiveName: 203 | descriptiveNegativeName: 204 | negativeButton: 205 | positiveButton: joystick button 1 206 | altNegativeButton: 207 | altPositiveButton: 208 | gravity: 1000 209 | dead: 0.001 210 | sensitivity: 1000 211 | snap: 0 212 | invert: 0 213 | type: 0 214 | axis: 0 215 | joyNum: 0 216 | - serializedVersion: 3 217 | m_Name: Fire3 218 | descriptiveName: 219 | descriptiveNegativeName: 220 | negativeButton: 221 | positiveButton: joystick button 2 222 | altNegativeButton: 223 | altPositiveButton: 224 | gravity: 1000 225 | dead: 0.001 226 | sensitivity: 1000 227 | snap: 0 228 | invert: 0 229 | type: 0 230 | axis: 0 231 | joyNum: 0 232 | - serializedVersion: 3 233 | m_Name: Jump 234 | descriptiveName: 235 | descriptiveNegativeName: 236 | negativeButton: 237 | positiveButton: joystick button 3 238 | altNegativeButton: 239 | altPositiveButton: 240 | gravity: 1000 241 | dead: 0.001 242 | sensitivity: 1000 243 | snap: 0 244 | invert: 0 245 | type: 0 246 | axis: 0 247 | joyNum: 0 248 | - serializedVersion: 3 249 | m_Name: Submit 250 | descriptiveName: 251 | descriptiveNegativeName: 252 | negativeButton: 253 | positiveButton: return 254 | altNegativeButton: 255 | altPositiveButton: joystick button 0 256 | gravity: 1000 257 | dead: 0.001 258 | sensitivity: 1000 259 | snap: 0 260 | invert: 0 261 | type: 0 262 | axis: 0 263 | joyNum: 0 264 | - serializedVersion: 3 265 | m_Name: Submit 266 | descriptiveName: 267 | descriptiveNegativeName: 268 | negativeButton: 269 | positiveButton: enter 270 | altNegativeButton: 271 | altPositiveButton: space 272 | gravity: 1000 273 | dead: 0.001 274 | sensitivity: 1000 275 | snap: 0 276 | invert: 0 277 | type: 0 278 | axis: 0 279 | joyNum: 0 280 | - serializedVersion: 3 281 | m_Name: Cancel 282 | descriptiveName: 283 | descriptiveNegativeName: 284 | negativeButton: 285 | positiveButton: escape 286 | altNegativeButton: 287 | altPositiveButton: joystick button 1 288 | gravity: 1000 289 | dead: 0.001 290 | sensitivity: 1000 291 | snap: 0 292 | invert: 0 293 | type: 0 294 | axis: 0 295 | joyNum: 0 296 | -------------------------------------------------------------------------------- /ProjectSettings/NavMeshAreas.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!126 &1 4 | NavMeshProjectSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 2 7 | areas: 8 | - name: Walkable 9 | cost: 1 10 | - name: Not Walkable 11 | cost: 1 12 | - name: Jump 13 | cost: 2 14 | - name: 15 | cost: 1 16 | - name: 17 | cost: 1 18 | - name: 19 | cost: 1 20 | - name: 21 | cost: 1 22 | - name: 23 | cost: 1 24 | - name: 25 | cost: 1 26 | - name: 27 | cost: 1 28 | - name: 29 | cost: 1 30 | - name: 31 | cost: 1 32 | - name: 33 | cost: 1 34 | - name: 35 | cost: 1 36 | - name: 37 | cost: 1 38 | - name: 39 | cost: 1 40 | - name: 41 | cost: 1 42 | - name: 43 | cost: 1 44 | - name: 45 | cost: 1 46 | - name: 47 | cost: 1 48 | - name: 49 | cost: 1 50 | - name: 51 | cost: 1 52 | - name: 53 | cost: 1 54 | - name: 55 | cost: 1 56 | - name: 57 | cost: 1 58 | - name: 59 | cost: 1 60 | - name: 61 | cost: 1 62 | - name: 63 | cost: 1 64 | - name: 65 | cost: 1 66 | - name: 67 | cost: 1 68 | - name: 69 | cost: 1 70 | - name: 71 | cost: 1 72 | m_LastAgentTypeID: -887442657 73 | m_Settings: 74 | - serializedVersion: 2 75 | agentTypeID: 0 76 | agentRadius: 0.5 77 | agentHeight: 2 78 | agentSlope: 45 79 | agentClimb: 0.75 80 | ledgeDropHeight: 0 81 | maxJumpAcrossDistance: 0 82 | minRegionArea: 2 83 | manualCellSize: 0 84 | cellSize: 0.16666667 85 | manualTileSize: 0 86 | tileSize: 256 87 | accuratePlacement: 0 88 | debug: 89 | m_Flags: 0 90 | m_SettingNames: 91 | - Humanoid 92 | -------------------------------------------------------------------------------- /ProjectSettings/NetworkManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!149 &1 4 | NetworkManager: 5 | m_ObjectHideFlags: 0 6 | m_DebugLevel: 0 7 | m_Sendrate: 15 8 | m_AssetToPrefab: {} 9 | -------------------------------------------------------------------------------- /ProjectSettings/Physics2DSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!19 &1 4 | Physics2DSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 3 7 | m_Gravity: {x: 0, y: -9.81} 8 | m_DefaultMaterial: {fileID: 0} 9 | m_VelocityIterations: 8 10 | m_PositionIterations: 3 11 | m_VelocityThreshold: 1 12 | m_MaxLinearCorrection: 0.2 13 | m_MaxAngularCorrection: 8 14 | m_MaxTranslationSpeed: 100 15 | m_MaxRotationSpeed: 360 16 | m_BaumgarteScale: 0.2 17 | m_BaumgarteTimeOfImpactScale: 0.75 18 | m_TimeToSleep: 0.5 19 | m_LinearSleepTolerance: 0.01 20 | m_AngularSleepTolerance: 2 21 | m_DefaultContactOffset: 0.01 22 | m_AutoSimulation: 1 23 | m_QueriesHitTriggers: 1 24 | m_QueriesStartInColliders: 1 25 | m_ChangeStopsCallbacks: 0 26 | m_CallbacksOnDisable: 1 27 | m_AutoSyncTransforms: 1 28 | m_AlwaysShowColliders: 0 29 | m_ShowColliderSleep: 1 30 | m_ShowColliderContacts: 0 31 | m_ShowColliderAABB: 0 32 | m_ContactArrowScale: 0.2 33 | m_ColliderAwakeColor: {r: 0.5686275, g: 0.95686275, b: 0.54509807, a: 0.7529412} 34 | m_ColliderAsleepColor: {r: 0.5686275, g: 0.95686275, b: 0.54509807, a: 0.36078432} 35 | m_ColliderContactColor: {r: 1, g: 0, b: 1, a: 0.6862745} 36 | m_ColliderAABBColor: {r: 1, g: 1, b: 0, a: 0.2509804} 37 | m_LayerCollisionMatrix: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 38 | -------------------------------------------------------------------------------- /ProjectSettings/PresetManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!1386491679 &1 4 | PresetManager: 5 | m_ObjectHideFlags: 0 6 | m_DefaultList: 7 | - type: 8 | m_NativeTypeID: 108 9 | m_ManagedTypePPtr: {fileID: 0} 10 | m_ManagedTypeFallback: 11 | defaultPresets: 12 | - m_Preset: {fileID: 2655988077585873504, guid: c1cf8506f04ef2c4a88b64b6c4202eea, 13 | type: 2} 14 | - type: 15 | m_NativeTypeID: 1020 16 | m_ManagedTypePPtr: {fileID: 0} 17 | m_ManagedTypeFallback: 18 | defaultPresets: 19 | - m_Preset: {fileID: 2655988077585873504, guid: 0cd792cc87e492d43b4e95b205fc5cc6, 20 | type: 2} 21 | - type: 22 | m_NativeTypeID: 1006 23 | m_ManagedTypePPtr: {fileID: 0} 24 | m_ManagedTypeFallback: 25 | defaultPresets: 26 | - m_Preset: {fileID: 2655988077585873504, guid: 7a99f8aa944efe94cb9bd74562b7d5f9, 27 | type: 2} 28 | -------------------------------------------------------------------------------- /ProjectSettings/ProjectVersion.txt: -------------------------------------------------------------------------------- 1 | m_EditorVersion: 2019.4.11f1 2 | m_EditorVersionWithRevision: 2019.4.11f1 (2d9804dddde7) 3 | -------------------------------------------------------------------------------- /ProjectSettings/QualitySettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!47 &1 4 | QualitySettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 5 7 | m_CurrentQuality: 4 8 | m_QualitySettings: 9 | - serializedVersion: 2 10 | name: Very Low 11 | pixelLightCount: 0 12 | shadows: 0 13 | shadowResolution: 0 14 | shadowProjection: 1 15 | shadowCascades: 1 16 | shadowDistance: 15 17 | shadowNearPlaneOffset: 3 18 | shadowCascade2Split: 0.33333334 19 | shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} 20 | shadowmaskMode: 0 21 | blendWeights: 1 22 | textureQuality: 1 23 | anisotropicTextures: 0 24 | antiAliasing: 0 25 | softParticles: 0 26 | softVegetation: 0 27 | realtimeReflectionProbes: 0 28 | billboardsFaceCameraPosition: 0 29 | vSyncCount: 0 30 | lodBias: 0.3 31 | maximumLODLevel: 0 32 | streamingMipmapsActive: 0 33 | streamingMipmapsAddAllCameras: 1 34 | streamingMipmapsMemoryBudget: 512 35 | streamingMipmapsRenderersPerFrame: 512 36 | streamingMipmapsMaxLevelReduction: 2 37 | streamingMipmapsMaxFileIORequests: 1024 38 | particleRaycastBudget: 4 39 | asyncUploadTimeSlice: 2 40 | asyncUploadBufferSize: 4 41 | resolutionScalingFixedDPIFactor: 1 42 | excludedTargetPlatforms: [] 43 | - serializedVersion: 2 44 | name: Low 45 | pixelLightCount: 0 46 | shadows: 0 47 | shadowResolution: 0 48 | shadowProjection: 1 49 | shadowCascades: 1 50 | shadowDistance: 20 51 | shadowNearPlaneOffset: 3 52 | shadowCascade2Split: 0.33333334 53 | shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} 54 | shadowmaskMode: 0 55 | blendWeights: 2 56 | textureQuality: 0 57 | anisotropicTextures: 0 58 | antiAliasing: 0 59 | softParticles: 0 60 | softVegetation: 0 61 | realtimeReflectionProbes: 0 62 | billboardsFaceCameraPosition: 0 63 | vSyncCount: 0 64 | lodBias: 0.4 65 | maximumLODLevel: 0 66 | streamingMipmapsActive: 0 67 | streamingMipmapsAddAllCameras: 1 68 | streamingMipmapsMemoryBudget: 512 69 | streamingMipmapsRenderersPerFrame: 512 70 | streamingMipmapsMaxLevelReduction: 2 71 | streamingMipmapsMaxFileIORequests: 1024 72 | particleRaycastBudget: 16 73 | asyncUploadTimeSlice: 2 74 | asyncUploadBufferSize: 4 75 | resolutionScalingFixedDPIFactor: 1 76 | excludedTargetPlatforms: [] 77 | - serializedVersion: 2 78 | name: Medium 79 | pixelLightCount: 1 80 | shadows: 1 81 | shadowResolution: 0 82 | shadowProjection: 1 83 | shadowCascades: 1 84 | shadowDistance: 20 85 | shadowNearPlaneOffset: 3 86 | shadowCascade2Split: 0.33333334 87 | shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} 88 | shadowmaskMode: 0 89 | blendWeights: 2 90 | textureQuality: 0 91 | anisotropicTextures: 1 92 | antiAliasing: 0 93 | softParticles: 0 94 | softVegetation: 0 95 | realtimeReflectionProbes: 0 96 | billboardsFaceCameraPosition: 0 97 | vSyncCount: 1 98 | lodBias: 0.7 99 | maximumLODLevel: 0 100 | streamingMipmapsActive: 0 101 | streamingMipmapsAddAllCameras: 1 102 | streamingMipmapsMemoryBudget: 512 103 | streamingMipmapsRenderersPerFrame: 512 104 | streamingMipmapsMaxLevelReduction: 2 105 | streamingMipmapsMaxFileIORequests: 1024 106 | particleRaycastBudget: 64 107 | asyncUploadTimeSlice: 2 108 | asyncUploadBufferSize: 4 109 | resolutionScalingFixedDPIFactor: 1 110 | excludedTargetPlatforms: [] 111 | - serializedVersion: 2 112 | name: High 113 | pixelLightCount: 2 114 | shadows: 2 115 | shadowResolution: 1 116 | shadowProjection: 1 117 | shadowCascades: 2 118 | shadowDistance: 40 119 | shadowNearPlaneOffset: 3 120 | shadowCascade2Split: 0.33333334 121 | shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} 122 | shadowmaskMode: 1 123 | blendWeights: 2 124 | textureQuality: 0 125 | anisotropicTextures: 1 126 | antiAliasing: 2 127 | softParticles: 0 128 | softVegetation: 1 129 | realtimeReflectionProbes: 1 130 | billboardsFaceCameraPosition: 1 131 | vSyncCount: 1 132 | lodBias: 1 133 | maximumLODLevel: 0 134 | streamingMipmapsActive: 0 135 | streamingMipmapsAddAllCameras: 1 136 | streamingMipmapsMemoryBudget: 512 137 | streamingMipmapsRenderersPerFrame: 512 138 | streamingMipmapsMaxLevelReduction: 2 139 | streamingMipmapsMaxFileIORequests: 1024 140 | particleRaycastBudget: 256 141 | asyncUploadTimeSlice: 2 142 | asyncUploadBufferSize: 4 143 | resolutionScalingFixedDPIFactor: 1 144 | excludedTargetPlatforms: [] 145 | - serializedVersion: 2 146 | name: Very High 147 | pixelLightCount: 3 148 | shadows: 2 149 | shadowResolution: 2 150 | shadowProjection: 1 151 | shadowCascades: 2 152 | shadowDistance: 40 153 | shadowNearPlaneOffset: 3 154 | shadowCascade2Split: 0.33333334 155 | shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} 156 | shadowmaskMode: 1 157 | blendWeights: 4 158 | textureQuality: 0 159 | anisotropicTextures: 0 160 | antiAliasing: 0 161 | softParticles: 1 162 | softVegetation: 1 163 | realtimeReflectionProbes: 1 164 | billboardsFaceCameraPosition: 1 165 | vSyncCount: 1 166 | lodBias: 1.5 167 | maximumLODLevel: 0 168 | streamingMipmapsActive: 0 169 | streamingMipmapsAddAllCameras: 1 170 | streamingMipmapsMemoryBudget: 512 171 | streamingMipmapsRenderersPerFrame: 512 172 | streamingMipmapsMaxLevelReduction: 2 173 | streamingMipmapsMaxFileIORequests: 1024 174 | particleRaycastBudget: 1024 175 | asyncUploadTimeSlice: 2 176 | asyncUploadBufferSize: 4 177 | resolutionScalingFixedDPIFactor: 1 178 | excludedTargetPlatforms: [] 179 | - serializedVersion: 2 180 | name: Ultra 181 | pixelLightCount: 4 182 | shadows: 2 183 | shadowResolution: 2 184 | shadowProjection: 1 185 | shadowCascades: 4 186 | shadowDistance: 150 187 | shadowNearPlaneOffset: 3 188 | shadowCascade2Split: 0.33333334 189 | shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} 190 | shadowmaskMode: 1 191 | blendWeights: 4 192 | textureQuality: 0 193 | anisotropicTextures: 1 194 | antiAliasing: 4 195 | softParticles: 1 196 | softVegetation: 1 197 | realtimeReflectionProbes: 1 198 | billboardsFaceCameraPosition: 1 199 | vSyncCount: 1 200 | lodBias: 2 201 | maximumLODLevel: 0 202 | streamingMipmapsActive: 0 203 | streamingMipmapsAddAllCameras: 1 204 | streamingMipmapsMemoryBudget: 512 205 | streamingMipmapsRenderersPerFrame: 512 206 | streamingMipmapsMaxLevelReduction: 2 207 | streamingMipmapsMaxFileIORequests: 1024 208 | particleRaycastBudget: 4096 209 | asyncUploadTimeSlice: 2 210 | asyncUploadBufferSize: 4 211 | resolutionScalingFixedDPIFactor: 1 212 | excludedTargetPlatforms: [] 213 | m_PerPlatformDefaultQuality: 214 | Android: 0 215 | Standalone: 0 216 | WebGL: 0 217 | -------------------------------------------------------------------------------- /ProjectSettings/TagManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!78 &1 4 | TagManager: 5 | serializedVersion: 2 6 | tags: [] 7 | layers: 8 | - Default 9 | - TransparentFX 10 | - Ignore Raycast 11 | - 12 | - Water 13 | - UI 14 | - 15 | - 16 | - PostProcessing 17 | - 18 | - 19 | - 20 | - 21 | - 22 | - 23 | - 24 | - 25 | - 26 | - 27 | - 28 | - 29 | - 30 | - 31 | - 32 | - 33 | - 34 | - 35 | - 36 | - 37 | - 38 | - 39 | - 40 | m_SortingLayers: 41 | - name: Default 42 | uniqueID: 0 43 | locked: 0 44 | -------------------------------------------------------------------------------- /ProjectSettings/TimeManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!5 &1 4 | TimeManager: 5 | m_ObjectHideFlags: 0 6 | Fixed Timestep: 0.02 7 | Maximum Allowed Timestep: 0.1 8 | m_TimeScale: 1 9 | Maximum Particle Timestep: 0.03 10 | -------------------------------------------------------------------------------- /ProjectSettings/UnityConnectSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!310 &1 4 | UnityConnectSettings: 5 | m_ObjectHideFlags: 0 6 | m_Enabled: 1 7 | m_TestMode: 0 8 | m_TestEventUrl: 9 | m_TestConfigUrl: 10 | m_TestInitMode: 0 11 | CrashReportingSettings: 12 | m_EventUrl: https://perf-events.cloud.unity3d.com/api/events/crashes 13 | m_NativeEventUrl: https://perf-events.cloud.unity3d.com/symbolicate 14 | m_Enabled: 0 15 | m_CaptureEditorExceptions: 1 16 | UnityPurchasingSettings: 17 | m_Enabled: 0 18 | m_TestMode: 0 19 | UnityAnalyticsSettings: 20 | m_Enabled: 1 21 | m_InitializeOnStartup: 1 22 | m_TestMode: 0 23 | m_TestEventUrl: 24 | m_TestConfigUrl: 25 | UnityAdsSettings: 26 | m_Enabled: 0 27 | m_InitializeOnStartup: 1 28 | m_TestMode: 0 29 | m_IosGameId: 30 | m_AndroidGameId: 31 | m_GameIds: {} 32 | m_GameId: 33 | PerformanceReportingSettings: 34 | m_Enabled: 0 35 | -------------------------------------------------------------------------------- /ProjectSettings/VFXManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!937362698 &1 4 | VFXManager: 5 | m_ObjectHideFlags: 0 6 | m_IndirectShader: {fileID: 0} 7 | m_CopyBufferShader: {fileID: 0} 8 | m_SortShader: {fileID: 0} 9 | m_StripUpdateShader: {fileID: 0} 10 | m_RenderPipeSettingsPath: 11 | m_FixedTimeStep: 0.016666668 12 | m_MaxDeltaTime: 0.05 13 | -------------------------------------------------------------------------------- /ProjectSettings/XRSettings.asset: -------------------------------------------------------------------------------- 1 | { 2 | "m_SettingKeys": [ 3 | "VR Device Disabled", 4 | "VR Device User Alert" 5 | ], 6 | "m_SettingValues": [ 7 | "False", 8 | "False" 9 | ] 10 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Unity-Dungeon-Generator 2 | Unity Dungeon Generator is a Procedural Generation for dungeon creation. It will result a bunch of data for your needs. 3 | 4 | ## Library 5 | Unity Dungeon Generator using Delaunay library from https://github.com/jceipek/Unity-delaunay, it is MIT License. In this project, the Delaunay already included. 6 | 7 | ## Feature 8 | There is 2 Algorithm in this package 9 | 1. Spreads Rooms automatically (for creating rooms) x Delaunay Triangulation (for connection each room) 10 | 11 | ![alt text](https://github.com/damarindra/Unity-Dungeon-Generator/blob/master/delaunay.gif "Delaunay") 12 | 13 | 2. Binary Space Partition (for creating rooms) x Delaunay Triangulation (for connection each room) 14 | 15 | ![alt text](https://github.com/damarindra/Unity-Dungeon-Generator/blob/master/bsp.gif "Binary Space Partition") 16 | 17 | ### Which one is better? 18 | IMO, the first one is the best. It will create natural looking dungeon. 19 | 20 | ## How to use it? 21 | ### Spreads Rooms automatically x Delaunay Triangulation 22 | 1. Create Empty GameObject, add **Dungeon Rooms Generator** Component and **Delaunay Dungeon Generator**. 23 | 2. Setup the value in inspector, for starter, this is my recommendation. 24 | 25 | ![alt text](https://github.com/damarindra/Unity-Dungeon-Generator/blob/master/delaunay.jpg "Delaunay") 26 | 27 | 3. Click the Complete Actions, it will automatically create the data for you dungeon. 28 | 29 | ### Binary Space Partition x Delaunay Triangulation 30 | 1. Create Empty GameObject, add **BSP Dungeon Generation** Component. 31 | 2. Setup the value in inspector, for starter, this is my recommendation. (Value option for Room Counts until Spread Distance is ignored, it only used when using spreads rooms) 32 | 33 | ![alt text](https://github.com/damarindra/Unity-Dungeon-Generator/blob/master/bsp.jpg "Binary Space Partition") 34 | 35 | 3. Click the Generate, it will automatically create the data for you dungeon. 36 | 37 | ### Then? 38 | You can implements the dungeon using **rooms** and **corridors** variable from DungeonGenerator.cs. ***Spreads Rooms automatically x Delaunay Triangulation*** will not using **rooms**, but mainRooms variable from DelaunayDungeonGenerator.cs. You can see TilemapBSPDriver.cs for how to implements it. 39 | 40 | # License 41 | It is MIT License. But if you create a game with this script, shoutout on your social account really appreciate!! 42 | -------------------------------------------------------------------------------- /bsp.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/damarindra/Unity-Dungeon-Generator/23b40e13df3db4b8a2b4fc269c02da2475033fac/bsp.gif -------------------------------------------------------------------------------- /bsp.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/damarindra/Unity-Dungeon-Generator/23b40e13df3db4b8a2b4fc269c02da2475033fac/bsp.jpg -------------------------------------------------------------------------------- /delaunay.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/damarindra/Unity-Dungeon-Generator/23b40e13df3db4b8a2b4fc269c02da2475033fac/delaunay.gif -------------------------------------------------------------------------------- /delaunay.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/damarindra/Unity-Dungeon-Generator/23b40e13df3db4b8a2b4fc269c02da2475033fac/delaunay.jpg --------------------------------------------------------------------------------