├── .gitattributes ├── .gitignore ├── .vsconfig ├── Assets ├── Prefabs.meta ├── Prefabs │ ├── UncollapsedTile.prefab │ ├── UncollapsedTile.prefab.meta │ ├── UncollapsedTileMaterial 1.mat │ ├── UncollapsedTileMaterial 1.mat.meta │ ├── UncollapsedTileMaterial.mat │ └── UncollapsedTileMaterial.mat.meta ├── Scene.meta ├── Scene │ ├── TestOverlappingModel 2.unity │ ├── TestOverlappingModel 2.unity.meta │ ├── TestOverlappingModel.unity │ ├── TestOverlappingModel.unity.meta │ ├── TestSimpleTIledModel 1.unity │ ├── TestSimpleTIledModel 1.unity.meta │ ├── TestSimpleTIledModel.unity │ ├── TestSimpleTIledModel.unity.meta │ ├── TestSimpleTIledModel3d.unity │ ├── TestSimpleTIledModel3d.unity.meta │ ├── TestSimpleTIledModel3d_streets.unity │ └── TestSimpleTIledModel3d_streets.unity.meta ├── Scripts.meta ├── Scripts │ ├── Core.meta │ └── Core │ │ ├── Data.meta │ │ ├── Data │ │ ├── CellState.cs │ │ ├── CellState.cs.meta │ │ ├── ITile.cs │ │ ├── ITile.cs.meta │ │ ├── OverlappingModel.meta │ │ ├── OverlappingModel │ │ │ ├── InputOverlappingData.cs │ │ │ ├── InputOverlappingData.cs.meta │ │ │ ├── OverlappingModelParams.cs │ │ │ ├── OverlappingModelParams.cs.meta │ │ │ ├── OverlappingModelTile.cs │ │ │ └── OverlappingModelTile.cs.meta │ │ ├── SimpleTiledModel.meta │ │ ├── SimpleTiledModel │ │ │ ├── InputSimpleTiledModelData.cs │ │ │ ├── InputSimpleTiledModelData.cs.meta │ │ │ ├── NeighborData.cs │ │ │ ├── NeighborData.cs.meta │ │ │ ├── SimpleTiledModelParams.cs │ │ │ ├── SimpleTiledModelParams.cs.meta │ │ │ ├── SimpleTiledModelTile.cs │ │ │ ├── SimpleTiledModelTile.cs.meta │ │ │ ├── SimpleTiledModelTileConfig.cs │ │ │ ├── SimpleTiledModelTileConfig.cs.meta │ │ │ ├── SymmetryType.cs │ │ │ └── SymmetryType.cs.meta │ │ ├── Tile.cs │ │ ├── Tile.cs.meta │ │ ├── TileConfig.cs │ │ ├── TileConfig.cs.meta │ │ ├── TileConfigData.cs │ │ ├── TileConfigData.cs.meta │ │ ├── WaveFunctionCollapseModelParams.cs │ │ └── WaveFunctionCollapseModelParams.cs.meta │ │ ├── GeneratorSceneViewButtons.cs │ │ ├── GeneratorSceneViewButtons.cs.meta │ │ ├── Helpers.meta │ │ ├── Helpers │ │ ├── ScriptableObjectUtility.cs │ │ ├── ScriptableObjectUtility.cs.meta │ │ ├── Tuple.cs │ │ ├── Tuple.cs.meta │ │ ├── Tuple2.cs │ │ ├── Tuple2.cs.meta │ │ ├── Tuple3.cs │ │ ├── Tuple3.cs.meta │ │ ├── Tuple4.cs │ │ └── Tuple4.cs.meta │ │ ├── InputProviders.meta │ │ ├── InputProviders │ │ ├── IInputDataProvider.cs │ │ ├── IInputDataProvider.cs.meta │ │ ├── InputDataProvider.cs │ │ ├── InputDataProvider.cs.meta │ │ ├── SymmetrySetsScriptableObject.cs │ │ ├── SymmetrySetsScriptableObject.cs.meta │ │ ├── TilePainterInputDataProvider.cs │ │ ├── TilePainterInputDataProvider.cs.meta │ │ ├── YuMEInputDataProvider.cs │ │ └── YuMEInputDataProvider.cs.meta │ │ ├── Model.meta │ │ ├── Model │ │ ├── IModel.cs │ │ ├── IModel.cs.meta │ │ ├── Model.cs │ │ ├── Model.cs.meta │ │ ├── ModelHelper.cs │ │ ├── ModelHelper.cs.meta │ │ ├── New.meta │ │ ├── New │ │ │ ├── IModel3d.cs │ │ │ ├── IModel3d.cs.meta │ │ │ ├── Model2d.cs │ │ │ ├── Model2d.cs.meta │ │ │ ├── Model3d.cs │ │ │ ├── Model3d.cs.meta │ │ │ ├── NewSimpleTiledModel.cs │ │ │ ├── NewSimpleTiledModel.cs.meta │ │ │ ├── OvelappingModel2dWrapper.cs │ │ │ ├── OvelappingModel2dWrapper.cs.meta │ │ │ ├── OverlappingModel2d.cs │ │ │ ├── OverlappingModel2d.cs.meta │ │ │ ├── SimpleTiledMode3d.cs │ │ │ └── SimpleTiledMode3d.cs.meta │ │ ├── OverlappingModel.cs │ │ ├── OverlappingModel.cs.meta │ │ ├── SimpleTiledModel.cs │ │ └── SimpleTiledModel.cs.meta │ │ ├── TilePainter.cs │ │ ├── TilePainter.cs.meta │ │ ├── UncollapsedTileView.cs │ │ ├── UncollapsedTileView.cs.meta │ │ ├── WaveFunctionCollapseGenerator.cs │ │ ├── WaveFunctionCollapseGenerator.cs.meta │ │ ├── WaveFunctionCollapseRenderer.cs │ │ └── WaveFunctionCollapseRenderer.cs.meta ├── Settings.meta └── Settings │ ├── TilePainter_tilesSymmetry.asset │ ├── TilePainter_tilesSymmetry.asset.meta │ ├── YuME_tilesData.asset │ └── YuME_tilesData.asset.meta ├── 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 ├── PackageManagerSettings.asset ├── Physics2DSettings.asset ├── PresetManager.asset ├── ProjectSettings.asset ├── ProjectVersion.txt ├── QualitySettings.asset ├── TagManager.asset ├── TimeManager.asset ├── UnityConnectSettings.asset ├── VFXManager.asset └── VersionControlSettings.asset └── README.md /.gitattributes: -------------------------------------------------------------------------------- 1 | "* text=auto" 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # This .gitignore file should be placed at the root of your Unity project directory 2 | # 3 | # Get latest from https://github.com/github/gitignore/blob/main/Unity.gitignore 4 | # 5 | /[Ll]ibrary/ 6 | /[Tt]emp/ 7 | /[Oo]bj/ 8 | /[Bb]uild/ 9 | /[Bb]uilds/ 10 | /[Ll]ogs/ 11 | /[Uu]ser[Ss]ettings/ 12 | 13 | # MemoryCaptures can get excessive in size. 14 | # They also could contain extremely sensitive data 15 | /[Mm]emoryCaptures/ 16 | 17 | # Recordings can get excessive in size 18 | /[Rr]ecordings/ 19 | 20 | # Uncomment this line if you wish to ignore the asset store tools plugin 21 | # /[Aa]ssets/AssetStoreTools* 22 | 23 | # Autogenerated Jetbrains Rider plugin 24 | /[Aa]ssets/Plugins/Editor/JetBrains* 25 | 26 | # Visual Studio cache directory 27 | .vs/ 28 | 29 | # Gradle cache directory 30 | .gradle/ 31 | 32 | # Autogenerated VS/MD/Consulo solution and project files 33 | ExportedObj/ 34 | .consulo/ 35 | *.csproj 36 | *.unityproj 37 | *.sln 38 | *.suo 39 | *.tmp 40 | *.user 41 | *.userprefs 42 | *.pidb 43 | *.booproj 44 | *.svd 45 | *.pdb 46 | *.mdb 47 | *.opendb 48 | *.VC.db 49 | 50 | # Unity3D generated meta files 51 | *.pidb.meta 52 | *.pdb.meta 53 | *.mdb.meta 54 | 55 | # Unity3D generated file on crash reports 56 | sysinfo.txt 57 | 58 | # Builds 59 | *.apk 60 | *.aab 61 | *.unitypackage 62 | *.app 63 | 64 | # Crashlytics generated file 65 | crashlytics-build.properties 66 | 67 | # Packed Addressables 68 | /[Aa]ssets/[Aa]ddressable[Aa]ssets[Dd]ata/*/*.bin* 69 | 70 | # Temporary auto-generated Android Assets 71 | /[Aa]ssets/[Ss]treamingAssets/aa.meta 72 | /[Aa]ssets/[Ss]treamingAssets/aa/* -------------------------------------------------------------------------------- /.vsconfig: -------------------------------------------------------------------------------- 1 | { 2 | "version": "1.0", 3 | "components": [ 4 | "Microsoft.VisualStudio.Workload.ManagedGame" 5 | ] 6 | } 7 | -------------------------------------------------------------------------------- /Assets/Prefabs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 63f5f1ba8a52c402480445da7c05f8dd 3 | folderAsset: yes 4 | timeCreated: 1522425514 5 | licenseType: Pro 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/Prefabs/UncollapsedTile.prefab: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!1001 &100100000 4 | Prefab: 5 | m_ObjectHideFlags: 1 6 | serializedVersion: 2 7 | m_Modification: 8 | m_TransformParent: {fileID: 0} 9 | m_Modifications: [] 10 | m_RemovedComponents: [] 11 | m_ParentPrefab: {fileID: 0} 12 | m_RootGameObject: {fileID: 1481428656759136} 13 | m_IsPrefabParent: 1 14 | --- !u!1 &1481428656759136 15 | GameObject: 16 | m_ObjectHideFlags: 0 17 | m_PrefabParentObject: {fileID: 0} 18 | m_PrefabInternal: {fileID: 100100000} 19 | serializedVersion: 5 20 | m_Component: 21 | - component: {fileID: 4804073428298916} 22 | - component: {fileID: 114520008546260906} 23 | m_Layer: 0 24 | m_Name: UncollapsedTile 25 | m_TagString: Untagged 26 | m_Icon: {fileID: 0} 27 | m_NavMeshLayer: 0 28 | m_StaticEditorFlags: 0 29 | m_IsActive: 1 30 | --- !u!1 &1496340147977636 31 | GameObject: 32 | m_ObjectHideFlags: 0 33 | m_PrefabParentObject: {fileID: 0} 34 | m_PrefabInternal: {fileID: 100100000} 35 | serializedVersion: 5 36 | m_Component: 37 | - component: {fileID: 4710333312755234} 38 | - component: {fileID: 33029892551751776} 39 | - component: {fileID: 135837778726507804} 40 | - component: {fileID: 23488743950512328} 41 | m_Layer: 0 42 | m_Name: Sphere 43 | m_TagString: Untagged 44 | m_Icon: {fileID: 0} 45 | m_NavMeshLayer: 0 46 | m_StaticEditorFlags: 0 47 | m_IsActive: 1 48 | --- !u!4 &4710333312755234 49 | Transform: 50 | m_ObjectHideFlags: 1 51 | m_PrefabParentObject: {fileID: 0} 52 | m_PrefabInternal: {fileID: 100100000} 53 | m_GameObject: {fileID: 1496340147977636} 54 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 55 | m_LocalPosition: {x: 0, y: 0, z: 0} 56 | m_LocalScale: {x: 1, y: 1, z: 1} 57 | m_Children: [] 58 | m_Father: {fileID: 4804073428298916} 59 | m_RootOrder: 0 60 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 61 | --- !u!4 &4804073428298916 62 | Transform: 63 | m_ObjectHideFlags: 1 64 | m_PrefabParentObject: {fileID: 0} 65 | m_PrefabInternal: {fileID: 100100000} 66 | m_GameObject: {fileID: 1481428656759136} 67 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 68 | m_LocalPosition: {x: 10.705393, y: -2.7684019, z: 4.158086} 69 | m_LocalScale: {x: 1, y: 1, z: 1} 70 | m_Children: 71 | - {fileID: 4710333312755234} 72 | m_Father: {fileID: 0} 73 | m_RootOrder: 0 74 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 75 | --- !u!23 &23488743950512328 76 | MeshRenderer: 77 | m_ObjectHideFlags: 1 78 | m_PrefabParentObject: {fileID: 0} 79 | m_PrefabInternal: {fileID: 100100000} 80 | m_GameObject: {fileID: 1496340147977636} 81 | m_Enabled: 1 82 | m_CastShadows: 1 83 | m_ReceiveShadows: 1 84 | m_MotionVectors: 1 85 | m_LightProbeUsage: 1 86 | m_ReflectionProbeUsage: 1 87 | m_Materials: 88 | - {fileID: 2100000, guid: 2f0ae7f30462e4c1d96d00570c5de759, type: 2} 89 | m_StaticBatchInfo: 90 | firstSubMesh: 0 91 | subMeshCount: 0 92 | m_StaticBatchRoot: {fileID: 0} 93 | m_ProbeAnchor: {fileID: 0} 94 | m_LightProbeVolumeOverride: {fileID: 0} 95 | m_ScaleInLightmap: 1 96 | m_PreserveUVs: 1 97 | m_IgnoreNormalsForChartDetection: 0 98 | m_ImportantGI: 0 99 | m_SelectedEditorRenderState: 3 100 | m_MinimumChartSize: 4 101 | m_AutoUVMaxDistance: 0.5 102 | m_AutoUVMaxAngle: 89 103 | m_LightmapParameters: {fileID: 0} 104 | m_SortingLayerID: 0 105 | m_SortingLayer: 0 106 | m_SortingOrder: 0 107 | --- !u!33 &33029892551751776 108 | MeshFilter: 109 | m_ObjectHideFlags: 1 110 | m_PrefabParentObject: {fileID: 0} 111 | m_PrefabInternal: {fileID: 100100000} 112 | m_GameObject: {fileID: 1496340147977636} 113 | m_Mesh: {fileID: 10207, guid: 0000000000000000e000000000000000, type: 0} 114 | --- !u!114 &114520008546260906 115 | MonoBehaviour: 116 | m_ObjectHideFlags: 1 117 | m_PrefabParentObject: {fileID: 0} 118 | m_PrefabInternal: {fileID: 100100000} 119 | m_GameObject: {fileID: 1481428656759136} 120 | m_Enabled: 1 121 | m_EditorHideFlags: 0 122 | m_Script: {fileID: 11500000, guid: f4807aee4e0241ff872a48fe4c283d44, type: 3} 123 | m_Name: 124 | m_EditorClassIdentifier: 125 | sphere: {fileID: 4710333312755234} 126 | --- !u!135 &135837778726507804 127 | SphereCollider: 128 | m_ObjectHideFlags: 1 129 | m_PrefabParentObject: {fileID: 0} 130 | m_PrefabInternal: {fileID: 100100000} 131 | m_GameObject: {fileID: 1496340147977636} 132 | m_Material: {fileID: 0} 133 | m_IsTrigger: 0 134 | m_Enabled: 1 135 | serializedVersion: 2 136 | m_Radius: 0.5 137 | m_Center: {x: 0, y: 0, z: 0} 138 | -------------------------------------------------------------------------------- /Assets/Prefabs/UncollapsedTile.prefab.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 8d2d52d36f96a4f4f80746a493cf59e5 3 | timeCreated: 1522425584 4 | licenseType: Pro 5 | NativeFormatImporter: 6 | mainObjectFileID: 100100000 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/Prefabs/UncollapsedTileMaterial 1.mat: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!21 &2100000 4 | Material: 5 | serializedVersion: 6 6 | m_ObjectHideFlags: 0 7 | m_PrefabParentObject: {fileID: 0} 8 | m_PrefabInternal: {fileID: 0} 9 | m_Name: UncollapsedTileMaterial 1 10 | m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0} 11 | m_ShaderKeywords: _ALPHAPREMULTIPLY_ON _GLOSSYREFLECTIONS_OFF _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A 12 | _SPECULARHIGHLIGHTS_OFF 13 | m_LightmapFlags: 4 14 | m_EnableInstancingVariants: 0 15 | m_DoubleSidedGI: 0 16 | m_CustomRenderQueue: 3000 17 | stringTagMap: 18 | RenderType: Transparent 19 | disabledShaderPasses: [] 20 | m_SavedProperties: 21 | serializedVersion: 3 22 | m_TexEnvs: 23 | - _BumpMap: 24 | m_Texture: {fileID: 0} 25 | m_Scale: {x: 1, y: 1} 26 | m_Offset: {x: 0, y: 0} 27 | - _DetailAlbedoMap: 28 | m_Texture: {fileID: 0} 29 | m_Scale: {x: 1, y: 1} 30 | m_Offset: {x: 0, y: 0} 31 | - _DetailMask: 32 | m_Texture: {fileID: 0} 33 | m_Scale: {x: 1, y: 1} 34 | m_Offset: {x: 0, y: 0} 35 | - _DetailNormalMap: 36 | m_Texture: {fileID: 0} 37 | m_Scale: {x: 1, y: 1} 38 | m_Offset: {x: 0, y: 0} 39 | - _EmissionMap: 40 | m_Texture: {fileID: 0} 41 | m_Scale: {x: 1, y: 1} 42 | m_Offset: {x: 0, y: 0} 43 | - _MainTex: 44 | m_Texture: {fileID: 0} 45 | m_Scale: {x: 1, y: 1} 46 | m_Offset: {x: 0, y: 0} 47 | - _MetallicGlossMap: 48 | m_Texture: {fileID: 0} 49 | m_Scale: {x: 1, y: 1} 50 | m_Offset: {x: 0, y: 0} 51 | - _OcclusionMap: 52 | m_Texture: {fileID: 0} 53 | m_Scale: {x: 1, y: 1} 54 | m_Offset: {x: 0, y: 0} 55 | - _ParallaxMap: 56 | m_Texture: {fileID: 0} 57 | m_Scale: {x: 1, y: 1} 58 | m_Offset: {x: 0, y: 0} 59 | m_Floats: 60 | - _BumpScale: 1 61 | - _Cutoff: 0.5 62 | - _DetailNormalMapScale: 1 63 | - _DstBlend: 10 64 | - _GlossMapScale: 0 65 | - _Glossiness: 0.646 66 | - _GlossyReflections: 0 67 | - _Metallic: 0 68 | - _Mode: 3 69 | - _OcclusionStrength: 1 70 | - _Parallax: 0.02 71 | - _SmoothnessTextureChannel: 1 72 | - _SpecularHighlights: 0 73 | - _SrcBlend: 1 74 | - _UVSec: 0 75 | - _ZWrite: 0 76 | m_Colors: 77 | - _Color: {r: 1, g: 1, b: 1, a: 0.097} 78 | - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} 79 | -------------------------------------------------------------------------------- /Assets/Prefabs/UncollapsedTileMaterial 1.mat.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 0b3e399eaffba4b2294fe72d1780d558 3 | timeCreated: 1522430605 4 | licenseType: Pro 5 | NativeFormatImporter: 6 | mainObjectFileID: 2100000 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/Prefabs/UncollapsedTileMaterial.mat: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!21 &2100000 4 | Material: 5 | serializedVersion: 6 6 | m_ObjectHideFlags: 0 7 | m_PrefabParentObject: {fileID: 0} 8 | m_PrefabInternal: {fileID: 0} 9 | m_Name: UncollapsedTileMaterial 10 | m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0} 11 | m_ShaderKeywords: _ALPHAPREMULTIPLY_ON 12 | m_LightmapFlags: 4 13 | m_EnableInstancingVariants: 0 14 | m_DoubleSidedGI: 0 15 | m_CustomRenderQueue: 3000 16 | stringTagMap: 17 | RenderType: Transparent 18 | disabledShaderPasses: [] 19 | m_SavedProperties: 20 | serializedVersion: 3 21 | m_TexEnvs: 22 | - _BumpMap: 23 | m_Texture: {fileID: 0} 24 | m_Scale: {x: 1, y: 1} 25 | m_Offset: {x: 0, y: 0} 26 | - _DetailAlbedoMap: 27 | m_Texture: {fileID: 0} 28 | m_Scale: {x: 1, y: 1} 29 | m_Offset: {x: 0, y: 0} 30 | - _DetailMask: 31 | m_Texture: {fileID: 0} 32 | m_Scale: {x: 1, y: 1} 33 | m_Offset: {x: 0, y: 0} 34 | - _DetailNormalMap: 35 | m_Texture: {fileID: 0} 36 | m_Scale: {x: 1, y: 1} 37 | m_Offset: {x: 0, y: 0} 38 | - _EmissionMap: 39 | m_Texture: {fileID: 0} 40 | m_Scale: {x: 1, y: 1} 41 | m_Offset: {x: 0, y: 0} 42 | - _MainTex: 43 | m_Texture: {fileID: 0} 44 | m_Scale: {x: 1, y: 1} 45 | m_Offset: {x: 0, y: 0} 46 | - _MetallicGlossMap: 47 | m_Texture: {fileID: 0} 48 | m_Scale: {x: 1, y: 1} 49 | m_Offset: {x: 0, y: 0} 50 | - _OcclusionMap: 51 | m_Texture: {fileID: 0} 52 | m_Scale: {x: 1, y: 1} 53 | m_Offset: {x: 0, y: 0} 54 | - _ParallaxMap: 55 | m_Texture: {fileID: 0} 56 | m_Scale: {x: 1, y: 1} 57 | m_Offset: {x: 0, y: 0} 58 | m_Floats: 59 | - _BumpScale: 1 60 | - _Cutoff: 0.5 61 | - _DetailNormalMapScale: 1 62 | - _DstBlend: 10 63 | - _GlossMapScale: 1 64 | - _Glossiness: 0 65 | - _GlossyReflections: 1 66 | - _Metallic: 0 67 | - _Mode: 3 68 | - _OcclusionStrength: 1 69 | - _Parallax: 0.02 70 | - _SmoothnessTextureChannel: 0 71 | - _SpecularHighlights: 1 72 | - _SrcBlend: 1 73 | - _UVSec: 0 74 | - _ZWrite: 0 75 | m_Colors: 76 | - _Color: {r: 0.03287197, g: 0.5588235, b: 0.05826278, a: 0} 77 | - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} 78 | -------------------------------------------------------------------------------- /Assets/Prefabs/UncollapsedTileMaterial.mat.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 2f0ae7f30462e4c1d96d00570c5de759 3 | timeCreated: 1522430605 4 | licenseType: Pro 5 | NativeFormatImporter: 6 | mainObjectFileID: 2100000 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/Scene.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ae402aea3764d4f87b56b59fb79ff213 3 | folderAsset: yes 4 | timeCreated: 1521056543 5 | licenseType: Pro 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/Scene/TestOverlappingModel 2.unity.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 244dbefc6a24a4114819b99d344c342b 3 | timeCreated: 1521056534 4 | licenseType: Pro 5 | DefaultImporter: 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/Scene/TestOverlappingModel.unity.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6e980641a85d24188a89c24937d00564 3 | timeCreated: 1521056534 4 | licenseType: Pro 5 | DefaultImporter: 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/Scene/TestSimpleTIledModel 1.unity.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 3a573f30c93604a2fa2565abdfa50f1c 3 | timeCreated: 1521056534 4 | licenseType: Pro 5 | DefaultImporter: 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/Scene/TestSimpleTIledModel.unity.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 96cdd4c7dfb804fbba9cd223a559eab3 3 | timeCreated: 1521056534 4 | licenseType: Pro 5 | DefaultImporter: 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/Scene/TestSimpleTIledModel3d.unity.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a40150a7fc5e84fe2a06aca1f5f400ae 3 | timeCreated: 1521056534 4 | licenseType: Pro 5 | DefaultImporter: 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/Scene/TestSimpleTIledModel3d_streets.unity.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: cb0d8d4a016be4666bac9bd91e7ee97c 3 | timeCreated: 1521056534 4 | licenseType: Pro 5 | DefaultImporter: 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/Scripts.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: fc198dee5a49844f593714593e7c5615 3 | folderAsset: yes 4 | timeCreated: 1519759489 5 | licenseType: Pro 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/Scripts/Core.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 65eaa191c4da5489eb2b5ab655f7fba2 3 | folderAsset: yes 4 | timeCreated: 1520355919 5 | licenseType: Pro 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/Scripts/Core/Data.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 15fc6adc9669464789085b979e907d2e 3 | timeCreated: 1520416447 -------------------------------------------------------------------------------- /Assets/Scripts/Core/Data/CellState.cs: -------------------------------------------------------------------------------- 1 | namespace Core.Data 2 | { 3 | public class CellState 4 | { 5 | public double EntropyLevel { get; private set; } 6 | 7 | /// 8 | /// Going to be null if Entropy level is more than 0 9 | /// 10 | public ITile Tile { get; private set; } 11 | 12 | public CellState(double entropyLevel, ITile tileIndex) 13 | { 14 | EntropyLevel = entropyLevel; 15 | Tile = tileIndex; 16 | } 17 | 18 | public bool Collapsed 19 | { 20 | get { return Tile != null; } 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /Assets/Scripts/Core/Data/CellState.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 3b98d89f99e3400d9bfc7c4d9f4236f8 3 | timeCreated: 1521928773 -------------------------------------------------------------------------------- /Assets/Scripts/Core/Data/ITile.cs: -------------------------------------------------------------------------------- 1 | namespace Core.Data 2 | { 3 | public interface ITile 4 | { 5 | int Rotation { get; } 6 | 7 | TileConfig Config { get; } 8 | } 9 | } -------------------------------------------------------------------------------- /Assets/Scripts/Core/Data/ITile.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: aea227775f074a0dacf3bd0d0419771c 3 | timeCreated: 1522961005 -------------------------------------------------------------------------------- /Assets/Scripts/Core/Data/OverlappingModel.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 46a729344113481e88ef5f04266684b9 3 | timeCreated: 1522693865 -------------------------------------------------------------------------------- /Assets/Scripts/Core/Data/OverlappingModel/InputOverlappingData.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using UnityEngine; 3 | 4 | namespace Core.Data.OverlappingModel 5 | { 6 | public class InputOverlappingData 7 | { 8 | public readonly int Width; 9 | public readonly int Depth; 10 | 11 | public OverlappingModelTile[,] tiles; 12 | public byte[,] tilesIndexIds; 13 | 14 | public List TilesSortedByIds = new List(); 15 | private TileConfigData tileConfigData; 16 | 17 | public InputOverlappingData(TileConfigData tileConfigData, int width, int depth) 18 | { 19 | this.tileConfigData = tileConfigData; 20 | Width = width; 21 | Depth = depth; 22 | 23 | tiles = new OverlappingModelTile[width, depth]; 24 | 25 | for (int x = 0; x < width; x++) 26 | { 27 | for (int z = 0; z < depth; z++) 28 | { 29 | tiles[x, z] = OverlappingModelTile.Empty; 30 | } 31 | } 32 | } 33 | 34 | public byte[,] GetSampleMatrix() 35 | { 36 | tilesIndexIds = new byte[Width, Depth]; 37 | 38 | TilesSortedByIds.Clear(); 39 | 40 | for (var z = 0; z < Depth; z++) 41 | for (var x = 0; x < Width; x++) 42 | { 43 | var tile = tiles[x, z]; 44 | 45 | int i; 46 | for (i = 0; i < TilesSortedByIds.Count; i++) 47 | { 48 | if (TilesSortedByIds[i].Id == tile.Id) break; 49 | } 50 | 51 | if (i == TilesSortedByIds.Count) 52 | { 53 | TilesSortedByIds.Add(tile); 54 | } 55 | tilesIndexIds[x, z] = (byte) i; 56 | } 57 | 58 | return tilesIndexIds; 59 | } 60 | 61 | public OverlappingModelTile GetTileById(byte id) 62 | { 63 | if (id < TilesSortedByIds.Count) 64 | { 65 | return TilesSortedByIds[id]; 66 | } 67 | 68 | return null; 69 | } 70 | 71 | public void SetTile(TileConfig tileConfig, int x, int z, int rotation) 72 | { 73 | var tile = new OverlappingModelTile(tileConfig, rotation); 74 | tiles[x, z] = tile; 75 | } 76 | 77 | public OverlappingModelTile GetTileAt(int x, int z) 78 | { 79 | return tiles[x, z]; 80 | } 81 | } 82 | } -------------------------------------------------------------------------------- /Assets/Scripts/Core/Data/OverlappingModel/InputOverlappingData.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 767d9ab3fd27492591e6731a4b1dd6fe 3 | timeCreated: 1520360123 -------------------------------------------------------------------------------- /Assets/Scripts/Core/Data/OverlappingModel/OverlappingModelParams.cs: -------------------------------------------------------------------------------- 1 | namespace Core.Data.OverlappingModel 2 | { 3 | public class OverlappingModelParams : WaveFunctionCollapseModelParams 4 | { 5 | /// 6 | /// Represents the width & height of the patterns that the overlap model breaks the input into. 7 | /// As it solves, it attempts to match up these subpatterns with each other. 8 | /// A higher pattern size will capture bigger features of the input, but is computationally more intensive, 9 | /// and may require a larger input sample to achieve reliable solutions. 10 | /// 11 | public int PatternSize { get; private set; } 12 | 13 | /// 14 | /// Represents which additional symmetries of the input pattern are digested. 0 is just the original input, 15 | /// 1-8 adds mirrored and rotated variations. These variations can help flesh out the patterns in your input, 16 | /// but aren't necessary. They also only work with unidirectional tiles, and are undesirable 17 | /// when your final game tiles have direction dependent graphics or functionality. 18 | /// 19 | public int Symmetry { get; set; } 20 | 21 | /// 22 | /// Represents whether the input pattern is tiling. If true, when WFC digests the input into N pattern chunks 23 | /// it will create patterns connecting the right & bottom edges to the left & top. 24 | /// If you use this setting, you'll need to make sure your input "makes sense" accross these edges. 25 | /// 26 | public bool PeriodicInput { get; set; } 27 | 28 | /// 29 | /// Determines if the output solutions are tilable. It's usefull for creating things like tileable textures, 30 | /// but also has a surprising influence on the output. When working with WFC, it's often a good idea to toggle 31 | /// Periodic Output on and off, checking if either setting influences the results in a favorable way. 32 | /// 33 | public bool PeriodicOutput { get; set; } 34 | 35 | /// 36 | /// When not 0, this assigns a pattern for the bottom row of the output. 37 | /// It's mainly useful for "vertical" worlds, where you want a distinct ground and sky separation. 38 | /// The value corresponds to the overlap models internal pattern indexes, 39 | /// so some experimentation is needed to figure out a suitable value. 40 | /// 41 | public int Ground { get; set; } 42 | 43 | public OverlappingModelParams(int width, int height, int depth, int patternSize) : base(width, height, depth) 44 | { 45 | this.PatternSize = patternSize; 46 | } 47 | } 48 | } -------------------------------------------------------------------------------- /Assets/Scripts/Core/Data/OverlappingModel/OverlappingModelParams.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f601efa2e9b74915b4224ece74a20513 3 | timeCreated: 1521494101 -------------------------------------------------------------------------------- /Assets/Scripts/Core/Data/OverlappingModel/OverlappingModelTile.cs: -------------------------------------------------------------------------------- 1 | namespace Core.Data.OverlappingModel 2 | { 3 | public class OverlappingModelTile : Tile 4 | { 5 | public static OverlappingModelTile Empty = new OverlappingModelTile(new TileConfig(null), 0); 6 | 7 | public string Id { get; private set; } 8 | 9 | public OverlappingModelTile(TileConfig tileConfig, int rotation) : base(tileConfig, rotation) 10 | { 11 | Id = Config.Id + "|" + Rotation; 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /Assets/Scripts/Core/Data/OverlappingModel/OverlappingModelTile.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 56013de6c492443081e6b6ea39a37bdf 3 | timeCreated: 1520360360 -------------------------------------------------------------------------------- /Assets/Scripts/Core/Data/SimpleTiledModel.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 631e9784467e481aa78a3f3b49dcc097 3 | timeCreated: 1522693875 -------------------------------------------------------------------------------- /Assets/Scripts/Core/Data/SimpleTiledModel/InputSimpleTiledModelData.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace Core.Data.SimpleTiledModel 4 | { 5 | public class InputSimpleTiledModelData 6 | { 7 | public TileConfigData TileConfigData { get; private set; } 8 | 9 | public InputSimpleTiledModelData(TileConfigData tileConfigData) 10 | { 11 | TileConfigData = tileConfigData; 12 | } 13 | 14 | public List NeighborDatas { get; private set; } 15 | 16 | public byte[] tilesConfigIds; 17 | 18 | public List GetSubset(string subsetName) 19 | { 20 | if (subsetName == SimpleTiledModelParams.DEFAULT_SUBSET) 21 | { 22 | return null; 23 | } 24 | 25 | return null; 26 | } 27 | 28 | public void SetNeighbors(List neighborDatas) 29 | { 30 | NeighborDatas = neighborDatas; 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /Assets/Scripts/Core/Data/SimpleTiledModel/InputSimpleTiledModelData.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 84558509cf6349788e3004ea22c1da2e 3 | timeCreated: 1520374058 -------------------------------------------------------------------------------- /Assets/Scripts/Core/Data/SimpleTiledModel/NeighborData.cs: -------------------------------------------------------------------------------- 1 | namespace Core.Data.SimpleTiledModel 2 | { 3 | public class NeighborData 4 | { 5 | public TileConfig LeftNeighborConfig { get; private set; } 6 | public TileConfig RightNeighborConfig { get; private set; } 7 | public int LeftRotation { get; private set; } 8 | public int RightRotation { get; private set; } 9 | 10 | public bool Horizontal { get; private set; } 11 | 12 | public NeighborData(TileConfig leftNeighborConfig, TileConfig rightNeighborConfig, int leftRotation, int rightRotation, bool horizontal = true) 13 | { 14 | LeftNeighborConfig = leftNeighborConfig; 15 | RightNeighborConfig = rightNeighborConfig; 16 | LeftRotation = leftRotation; 17 | RightRotation = rightRotation; 18 | Horizontal = horizontal; 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /Assets/Scripts/Core/Data/SimpleTiledModel/NeighborData.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 25d80cbf2fe5438ca15b006dfcecb590 3 | timeCreated: 1520416453 -------------------------------------------------------------------------------- /Assets/Scripts/Core/Data/SimpleTiledModel/SimpleTiledModelParams.cs: -------------------------------------------------------------------------------- 1 | namespace Core.Data.SimpleTiledModel 2 | { 3 | public class SimpleTiledModelParams : WaveFunctionCollapseModelParams 4 | { 5 | public const string DEFAULT_SUBSET = "Default"; 6 | 7 | /// 8 | /// Determines if the output solutions are tilable. It's usefull for creating things like tileable textures, 9 | /// but also has a surprising influence on the output. When working with WFC, it's often a good idea to toggle 10 | /// Periodic Output on and off, checking if either setting influences the results in a favorable way. 11 | /// 12 | public bool Periodic { get; private set; } 13 | 14 | /// 15 | /// Defines which subset of tiles to use from Input data 16 | /// 17 | public string SubsetName { get; private set; } 18 | 19 | public bool Black { get; set; } 20 | 21 | public SimpleTiledModelParams(int width, int height, int depth, bool periodic = false, string subsetName = DEFAULT_SUBSET) : base(width, height, depth) 22 | { 23 | Periodic = periodic; 24 | SubsetName = subsetName; 25 | Black = false; 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /Assets/Scripts/Core/Data/SimpleTiledModel/SimpleTiledModelParams.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 7afceea9a801482f98a92050a15d5bca 3 | timeCreated: 1521494691 -------------------------------------------------------------------------------- /Assets/Scripts/Core/Data/SimpleTiledModel/SimpleTiledModelTile.cs: -------------------------------------------------------------------------------- 1 | namespace Core.Data.SimpleTiledModel 2 | { 3 | public class SimpleTiledModelTile : Tile 4 | { 5 | public SimpleTiledModelTile(SimpleTiledModelTileConfig config, int rotation) : base(config, rotation) 6 | { 7 | } 8 | 9 | public override string ToString() 10 | { 11 | return Config.Id + " " + Rotation; 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /Assets/Scripts/Core/Data/SimpleTiledModel/SimpleTiledModelTile.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f583859aa93a4119a9e1e00c1a6e0169 3 | timeCreated: 1520356429 -------------------------------------------------------------------------------- /Assets/Scripts/Core/Data/SimpleTiledModel/SimpleTiledModelTileConfig.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | namespace Core.Data.SimpleTiledModel 4 | { 5 | public class SimpleTiledModelTileConfig : TileConfig 6 | { 7 | public double Weight { get; set; } 8 | public SymmetryType Symmetry { get; set; } 9 | 10 | public SimpleTiledModelTileConfig(GameObject prefab, SymmetryType symmetry) : base(prefab) 11 | { 12 | Weight = 1; 13 | Symmetry = symmetry; 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /Assets/Scripts/Core/Data/SimpleTiledModel/SimpleTiledModelTileConfig.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b9aa63e762684f8488d6e78707e85dbc 3 | timeCreated: 1521399083 -------------------------------------------------------------------------------- /Assets/Scripts/Core/Data/SimpleTiledModel/SymmetryType.cs: -------------------------------------------------------------------------------- 1 | namespace Core.Data.SimpleTiledModel 2 | { 3 | public enum SymmetryType 4 | { 5 | X, 6 | L, 7 | T, 8 | I, 9 | Slash 10 | } 11 | } -------------------------------------------------------------------------------- /Assets/Scripts/Core/Data/SimpleTiledModel/SymmetryType.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 4ce8db49367642ce926aaaaed30ee3cf 3 | timeCreated: 1520376953 -------------------------------------------------------------------------------- /Assets/Scripts/Core/Data/Tile.cs: -------------------------------------------------------------------------------- 1 | namespace Core.Data 2 | { 3 | public abstract class Tile : ITile where T:TileConfig 4 | { 5 | protected Tile(T config, int rotation) 6 | { 7 | Rotation = rotation; 8 | Config = config; 9 | } 10 | 11 | public int Rotation { get; private set; } 12 | public TileConfig Config { get; private set; } 13 | } 14 | } -------------------------------------------------------------------------------- /Assets/Scripts/Core/Data/Tile.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a5b6850a9af544b9acf48e28d427c12e 3 | timeCreated: 1522013129 -------------------------------------------------------------------------------- /Assets/Scripts/Core/Data/TileConfig.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | namespace Core.Data 4 | { 5 | public class TileConfig 6 | { 7 | public string Id { get; private set; } 8 | public GameObject Prefab { get; private set; } 9 | 10 | public TileConfig(GameObject prefab) 11 | { 12 | Prefab = prefab; 13 | if (prefab == null) 14 | { 15 | Id = "Empty"; 16 | } 17 | else 18 | { 19 | Id = prefab.name; 20 | } 21 | } 22 | 23 | public override string ToString() 24 | { 25 | return Id; 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /Assets/Scripts/Core/Data/TileConfig.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d3edf5fa49294bad81f640ae90ff9372 3 | timeCreated: 1521400797 -------------------------------------------------------------------------------- /Assets/Scripts/Core/Data/TileConfigData.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace Core.Data 4 | { 5 | public class TileConfigData where T : TileConfig 6 | { 7 | private readonly Dictionary ConfigsMap = new Dictionary(); 8 | 9 | public TileConfigData() 10 | { 11 | ConfigsList = new List(); 12 | } 13 | 14 | public List ConfigsList { get; private set; } 15 | 16 | public T GetConfig(string configId) 17 | { 18 | if (ConfigsMap.ContainsKey(configId)) 19 | { 20 | return ConfigsMap[configId]; 21 | } 22 | 23 | return null; 24 | } 25 | 26 | public void AddConfig(T config) 27 | { 28 | ConfigsMap.Add(config.Id, config); 29 | ConfigsList.Add(config); 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /Assets/Scripts/Core/Data/TileConfigData.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 953efdbdbbbe44febcf841ed20fb218b 3 | timeCreated: 1522699109 -------------------------------------------------------------------------------- /Assets/Scripts/Core/Data/WaveFunctionCollapseModelParams.cs: -------------------------------------------------------------------------------- 1 | namespace Core.Data 2 | { 3 | public class WaveFunctionCollapseModelParams 4 | { 5 | public WaveFunctionCollapseModelParams(int width, int height, int depth) 6 | { 7 | Width = width; 8 | Height = height; 9 | Depth = depth; 10 | } 11 | 12 | /// 13 | /// X dimension of the output data 14 | /// 15 | public int Width { get; private set; } 16 | 17 | /// 18 | /// Y dimension of the output data 19 | /// 20 | public int Height { get; private set; } 21 | 22 | /// 23 | /// Z dimension of the output data 24 | /// 25 | public int Depth { get; private set; } 26 | } 27 | } -------------------------------------------------------------------------------- /Assets/Scripts/Core/Data/WaveFunctionCollapseModelParams.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 3713e8e8dbff4cc5b5010ad1260243b2 3 | timeCreated: 1521494008 -------------------------------------------------------------------------------- /Assets/Scripts/Core/GeneratorSceneViewButtons.cs: -------------------------------------------------------------------------------- 1 | using UnityEditor; 2 | using UnityEngine; 3 | 4 | namespace Core 5 | { 6 | [InitializeOnLoad] 7 | public static class GeneratorSceneViewButtons { 8 | 9 | static GeneratorSceneViewButtons() 10 | { 11 | SceneView.duringSceneGui -= OnSceneGUI; 12 | SceneView.duringSceneGui += OnSceneGUI; 13 | } 14 | 15 | static void OnSceneGUI(SceneView sceneView) 16 | { 17 | var generator = Object.FindObjectOfType(); 18 | if (generator == null) 19 | { 20 | return; 21 | } 22 | 23 | Handles.BeginGUI(); 24 | 25 | GUILayout.BeginArea(new Rect(sceneView.position.width - 190, sceneView.position.height - 110, 180, 100)); 26 | 27 | if(GUILayout.Button("Generate Overlapping output")){ 28 | generator.GenerateOverlappingOutput(); 29 | } 30 | if(GUILayout.Button("Generate Simple tiled output")){ 31 | generator.GenerateSimpleTiledOutput(); 32 | } 33 | if(GUILayout.Button("Abort and Clear")){ 34 | generator.Abort(); 35 | } 36 | 37 | GUILayout.EndArea(); 38 | 39 | Handles.EndGUI(); 40 | } 41 | } 42 | } -------------------------------------------------------------------------------- /Assets/Scripts/Core/GeneratorSceneViewButtons.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 290179dd62674ea3834fd88a60c56011 3 | timeCreated: 1523305424 -------------------------------------------------------------------------------- /Assets/Scripts/Core/Helpers.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 80042e3d7b6f4b0f93de150f008fbb78 3 | timeCreated: 1522694658 -------------------------------------------------------------------------------- /Assets/Scripts/Core/Helpers/ScriptableObjectUtility.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | using UnityEditor; 3 | using UnityEngine; 4 | 5 | namespace Core.Helpers 6 | { 7 | public static class ScriptableObjectUtility 8 | { 9 | /// 10 | // This makes it easy to create, name and place unique new ScriptableObject asset files. 11 | /// 12 | public static void CreateAsset () where T : ScriptableObject 13 | { 14 | T asset = ScriptableObject.CreateInstance (); 15 | 16 | string path = AssetDatabase.GetAssetPath (Selection.activeObject); 17 | if (path == "") 18 | { 19 | path = "Assets"; 20 | } 21 | else if (Path.GetExtension (path) != "") 22 | { 23 | path = path.Replace (Path.GetFileName (AssetDatabase.GetAssetPath (Selection.activeObject)), ""); 24 | } 25 | 26 | string assetPathAndName = AssetDatabase.GenerateUniqueAssetPath (path + "/New " + typeof(T).ToString() + ".asset"); 27 | 28 | AssetDatabase.CreateAsset (asset, assetPathAndName); 29 | 30 | AssetDatabase.SaveAssets (); 31 | AssetDatabase.Refresh(); 32 | EditorUtility.FocusProjectWindow (); 33 | Selection.activeObject = asset; 34 | } 35 | } 36 | } -------------------------------------------------------------------------------- /Assets/Scripts/Core/Helpers/ScriptableObjectUtility.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b8aa4ded44c841ecbbf9f7fe819e6a1a 3 | timeCreated: 1522694668 -------------------------------------------------------------------------------- /Assets/Scripts/Core/Helpers/Tuple.cs: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------------- 2 | // Tuple structs for use in .NET Not-Quite-3.5 (e.g. Unity3D). 3 | // 4 | // Used Chapter 3 in http://functional-programming.net/ as a starting point. 5 | // 6 | // Note: .NET 4.0 Tuples are immutable classes so they're *slightly* different. 7 | // ---------------------------------------------------------------------------- 8 | 9 | using System; 10 | 11 | namespace Eppy 12 | { 13 | /// 14 | /// Utility class that simplifies cration of tuples by using 15 | /// method calls instead of constructor calls 16 | /// 17 | public static class Tuple 18 | { 19 | /// 20 | /// Creates a new tuple value with the specified elements. The method 21 | /// can be used without specifying the generic parameters, because C# 22 | /// compiler can usually infer the actual types. 23 | /// 24 | /// First element of the tuple 25 | /// Second element of the tuple 26 | /// A newly created tuple 27 | public static Tuple Create(T1 item1, T2 second) 28 | { 29 | return new Tuple(item1, second); 30 | } 31 | 32 | /// 33 | /// Creates a new tuple value with the specified elements. The method 34 | /// can be used without specifying the generic parameters, because C# 35 | /// compiler can usually infer the actual types. 36 | /// 37 | /// First element of the tuple 38 | /// Second element of the tuple 39 | /// Third element of the tuple 40 | /// A newly created tuple 41 | public static Tuple Create(T1 item1, T2 second, T3 third) 42 | { 43 | return new Tuple(item1, second, third); 44 | } 45 | 46 | /// 47 | /// Creates a new tuple value with the specified elements. The method 48 | /// can be used without specifying the generic parameters, because C# 49 | /// compiler can usually infer the actual types. 50 | /// 51 | /// First element of the tuple 52 | /// Second element of the tuple 53 | /// Third element of the tuple 54 | /// Fourth element of the tuple 55 | /// A newly created tuple 56 | public static Tuple Create(T1 item1, T2 second, T3 third, T4 fourth) 57 | { 58 | return new Tuple(item1, second, third, fourth); 59 | } 60 | 61 | 62 | /// 63 | /// Extension method that provides a concise utility for unpacking 64 | /// tuple components into specific out parameters. 65 | /// 66 | /// the tuple to unpack from 67 | /// the out parameter that will be assigned tuple.Item1 68 | /// the out parameter that will be assigned tuple.Item2 69 | public static void Unpack(this Tuple tuple, out T1 ref1, out T2 ref2) 70 | { 71 | ref1 = tuple.Item1; 72 | ref2 = tuple.Item2; 73 | } 74 | 75 | /// 76 | /// Extension method that provides a concise utility for unpacking 77 | /// tuple components into specific out parameters. 78 | /// 79 | /// the tuple to unpack from 80 | /// the out parameter that will be assigned tuple.Item1 81 | /// the out parameter that will be assigned tuple.Item2 82 | /// the out parameter that will be assigned tuple.Item3 83 | public static void Unpack(this Tuple tuple, out T1 ref1, out T2 ref2, T3 ref3) 84 | { 85 | ref1 = tuple.Item1; 86 | ref2 = tuple.Item2; 87 | ref3 = tuple.Item3; 88 | } 89 | 90 | /// 91 | /// Extension method that provides a concise utility for unpacking 92 | /// tuple components into specific out parameters. 93 | /// 94 | /// the tuple to unpack from 95 | /// the out parameter that will be assigned tuple.Item1 96 | /// the out parameter that will be assigned tuple.Item2 97 | /// the out parameter that will be assigned tuple.Item3 98 | /// the out parameter that will be assigned tuple.Item4 99 | public static void Unpack(this Tuple tuple, out T1 ref1, out T2 ref2, T3 ref3, T4 ref4) 100 | { 101 | ref1 = tuple.Item1; 102 | ref2 = tuple.Item2; 103 | ref3 = tuple.Item3; 104 | ref4 = tuple.Item4; 105 | } 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /Assets/Scripts/Core/Helpers/Tuple.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 3645eb32634f64c9ba8c6920c0a75767 3 | timeCreated: 1523141446 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/Scripts/Core/Helpers/Tuple2.cs: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------------- 2 | // Tuple structs for use in .NET Not-Quite-3.5 (e.g. Unity3D). 3 | // 4 | // Used Chapter 3 in http://functional-programming.net/ as a starting point. 5 | // 6 | // Note: .NET 4.0 Tuples are immutable classes so they're *slightly* different. 7 | // ---------------------------------------------------------------------------- 8 | 9 | using System; 10 | 11 | namespace Eppy 12 | { 13 | /// 14 | /// Represents a functional tuple that can be used to store 15 | /// two values of different types inside one object. 16 | /// 17 | /// The type of the first element 18 | /// The type of the second element 19 | public sealed class Tuple 20 | { 21 | private readonly T1 item1; 22 | private readonly T2 item2; 23 | 24 | /// 25 | /// Retyurns the first element of the tuple 26 | /// 27 | public T1 Item1 28 | { 29 | get { return item1; } 30 | } 31 | 32 | /// 33 | /// Returns the second element of the tuple 34 | /// 35 | public T2 Item2 36 | { 37 | get { return item2; } 38 | } 39 | 40 | /// 41 | /// Create a new tuple value 42 | /// 43 | /// First element of the tuple 44 | /// Second element of the tuple 45 | public Tuple(T1 item1, T2 item2) 46 | { 47 | this.item1 = item1; 48 | this.item2 = item2; 49 | } 50 | 51 | public override string ToString() 52 | { 53 | return string.Format("Tuple({0}, {1})", Item1, Item2); 54 | } 55 | 56 | public override int GetHashCode() 57 | { 58 | int hash = 17; 59 | hash = hash * 23 + (item1 == null ? 0 : item1.GetHashCode()); 60 | hash = hash * 23 + (item2 == null ? 0 : item2.GetHashCode()); 61 | return hash; 62 | } 63 | 64 | public override bool Equals(object o) 65 | { 66 | if (!(o is Tuple)) { 67 | return false; 68 | } 69 | 70 | var other = (Tuple) o; 71 | 72 | return this == other; 73 | } 74 | 75 | public bool Equals(Tuple other) 76 | { 77 | return this == other; 78 | } 79 | 80 | public static bool operator==(Tuple a, Tuple b) 81 | { 82 | if (object.ReferenceEquals(a, null)) { 83 | return object.ReferenceEquals(b, null); 84 | } 85 | if (a.item1 == null && b.item1 != null) return false; 86 | if (a.item2 == null && b.item2 != null) return false; 87 | return 88 | a.item1.Equals(b.item1) && 89 | a.item2.Equals(b.item2); 90 | } 91 | 92 | public static bool operator!=(Tuple a, Tuple b) 93 | { 94 | return !(a == b); 95 | } 96 | 97 | public void Unpack(Action unpackerDelegate) 98 | { 99 | unpackerDelegate(Item1, Item2); 100 | } 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /Assets/Scripts/Core/Helpers/Tuple2.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 4f3a15857ddff47929b8eac8b5005193 3 | timeCreated: 1523141447 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/Scripts/Core/Helpers/Tuple3.cs: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------------- 2 | // Tuple structs for use in .NET Not-Quite-3.5 (e.g. Unity3D). 3 | // 4 | // Used Chapter 3 in http://functional-programming.net/ as a starting point. 5 | // 6 | // Note: .NET 4.0 Tuples are immutable classes so they're *slightly* different. 7 | // ---------------------------------------------------------------------------- 8 | 9 | using System; 10 | 11 | namespace Eppy 12 | { 13 | /// 14 | /// Represents a functional tuple that can be used to store 15 | /// two values of different types inside one object. 16 | /// 17 | /// The type of the first element 18 | /// The type of the second element 19 | /// The type of the third element 20 | public sealed class Tuple 21 | { 22 | private readonly T1 item1; 23 | private readonly T2 item2; 24 | private readonly T3 item3; 25 | 26 | /// 27 | /// Retyurns the first element of the tuple 28 | /// 29 | public T1 Item1 30 | { 31 | get { return item1; } 32 | } 33 | 34 | /// 35 | /// Returns the second element of the tuple 36 | /// 37 | public T2 Item2 38 | { 39 | get { return item2; } 40 | } 41 | 42 | /// 43 | /// Returns the second element of the tuple 44 | /// 45 | public T3 Item3 46 | { 47 | get { return item3; } 48 | } 49 | 50 | /// 51 | /// Create a new tuple value 52 | /// 53 | /// First element of the tuple 54 | /// Second element of the tuple 55 | /// Third element of the tuple 56 | public Tuple(T1 item1, T2 item2, T3 item3) 57 | { 58 | this.item1 = item1; 59 | this.item2 = item2; 60 | this.item3 = item3; 61 | } 62 | 63 | public override int GetHashCode() 64 | { 65 | int hash = 17; 66 | hash = hash * 23 + (item1 == null ? 0 : item1.GetHashCode()); 67 | hash = hash * 23 + (item2 == null ? 0 : item2.GetHashCode()); 68 | hash = hash * 23 + (item3 == null ? 0 : item3.GetHashCode()); 69 | return hash; 70 | } 71 | 72 | public override bool Equals(object o) 73 | { 74 | if (!(o is Tuple)) { 75 | return false; 76 | } 77 | 78 | var other = (Tuple)o; 79 | 80 | return this == other; 81 | } 82 | 83 | public static bool operator==(Tuple a, Tuple b) 84 | { 85 | if (object.ReferenceEquals(a, null)) { 86 | return object.ReferenceEquals(b, null); 87 | } 88 | if (a.item1 == null && b.item1 != null) return false; 89 | if (a.item2 == null && b.item2 != null) return false; 90 | if (a.item3 == null && b.item3 != null) return false; 91 | return 92 | a.item1.Equals(b.item1) && 93 | a.item2.Equals(b.item2) && 94 | a.item3.Equals(b.item3); 95 | } 96 | 97 | public static bool operator!=(Tuple a, Tuple b) 98 | { 99 | return !(a == b); 100 | } 101 | 102 | public void Unpack(Action unpackerDelegate) 103 | { 104 | unpackerDelegate(Item1, Item2, Item3); 105 | } 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /Assets/Scripts/Core/Helpers/Tuple3.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 4cbf3f33754c740e58eed892f852c2cb 3 | timeCreated: 1523141447 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/Scripts/Core/Helpers/Tuple4.cs: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------------- 2 | // Tuple structs for use in .NET Not-Quite-3.5 (e.g. Unity3D). 3 | // 4 | // Used Chapter 3 in http://functional-programming.net/ as a starting point. 5 | // 6 | // Note: .NET 4.0 Tuples are immutable classes so they're *slightly* different. 7 | // ---------------------------------------------------------------------------- 8 | 9 | using System; 10 | 11 | namespace Eppy 12 | { 13 | /// 14 | /// Represents a functional tuple that can be used to store 15 | /// two values of different types inside one object. 16 | /// 17 | /// The type of the first element 18 | /// The type of the second element 19 | /// The type of the third element 20 | /// The type of the fourth element 21 | public sealed class Tuple 22 | { 23 | private readonly T1 item1; 24 | private readonly T2 item2; 25 | private readonly T3 item3; 26 | private readonly T4 item4; 27 | 28 | /// 29 | /// Retyurns the first element of the tuple 30 | /// 31 | public T1 Item1 32 | { 33 | get { return item1; } 34 | } 35 | 36 | /// 37 | /// Returns the second element of the tuple 38 | /// 39 | public T2 Item2 40 | { 41 | get { return item2; } 42 | } 43 | 44 | /// 45 | /// Returns the second element of the tuple 46 | /// 47 | public T3 Item3 48 | { 49 | get { return item3; } 50 | } 51 | 52 | /// 53 | /// Returns the second element of the tuple 54 | /// 55 | public T4 Item4 56 | { 57 | get { return item4; } 58 | } 59 | 60 | /// 61 | /// Create a new tuple value 62 | /// 63 | /// First element of the tuple 64 | /// Second element of the tuple 65 | /// Third element of the tuple 66 | /// Fourth element of the tuple 67 | public Tuple(T1 item1, T2 item2, T3 item3, T4 item4) 68 | { 69 | this.item1 = item1; 70 | this.item2 = item2; 71 | this.item3 = item3; 72 | this.item4 = item4; 73 | } 74 | 75 | public override int GetHashCode() 76 | { 77 | int hash = 17; 78 | hash = hash * 23 + (item1 == null ? 0 : item1.GetHashCode()); 79 | hash = hash * 23 + (item2 == null ? 0 : item2.GetHashCode()); 80 | hash = hash * 23 + (item3 == null ? 0 : item3.GetHashCode()); 81 | hash = hash * 23 + (item4 == null ? 0 : item4.GetHashCode()); 82 | return hash; 83 | } 84 | 85 | public override bool Equals(object o) 86 | { 87 | if (o.GetType() != typeof(Tuple)) { 88 | return false; 89 | } 90 | 91 | var other = (Tuple)o; 92 | 93 | return this == other; 94 | } 95 | 96 | public static bool operator==(Tuple a, Tuple b) 97 | { 98 | if (object.ReferenceEquals(a, null)) { 99 | return object.ReferenceEquals(b, null); 100 | } 101 | if (a.item1 == null && b.item1 != null) return false; 102 | if (a.item2 == null && b.item2 != null) return false; 103 | if (a.item3 == null && b.item3 != null) return false; 104 | if (a.item4 == null && b.item4 != null) return false; 105 | return 106 | a.item1.Equals(b.item1) && 107 | a.item2.Equals(b.item2) && 108 | a.item3.Equals(b.item3) && 109 | a.item4.Equals(b.item4); 110 | } 111 | 112 | public static bool operator!=(Tuple a, Tuple b) 113 | { 114 | return !(a == b); 115 | } 116 | 117 | public void Unpack(Action unpackerDelegate) 118 | { 119 | unpackerDelegate(Item1, Item2, Item3, Item4); 120 | } 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /Assets/Scripts/Core/Helpers/Tuple4.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 023f6edf83c88452ab5df85cf4e19ee0 3 | timeCreated: 1523141446 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/Scripts/Core/InputProviders.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 59f4d5fe66f14883ab3c2a266f4cb1ca 3 | timeCreated: 1521056879 -------------------------------------------------------------------------------- /Assets/Scripts/Core/InputProviders/IInputDataProvider.cs: -------------------------------------------------------------------------------- 1 | using Core.Data; 2 | using Core.Data.OverlappingModel; 3 | using Core.Data.SimpleTiledModel; 4 | 5 | namespace Core.InputProviders 6 | { 7 | public interface IInputDataProvider 8 | { 9 | InputOverlappingData GetInputOverlappingData(); 10 | InputSimpleTiledModelData GetInputSimpleTiledData(); 11 | } 12 | } -------------------------------------------------------------------------------- /Assets/Scripts/Core/InputProviders/IInputDataProvider.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b685e7c35cd74fd78a6779e1bea86f7c 3 | timeCreated: 1520542530 -------------------------------------------------------------------------------- /Assets/Scripts/Core/InputProviders/InputDataProvider.cs: -------------------------------------------------------------------------------- 1 | using Core.Data.OverlappingModel; 2 | using Core.Data.SimpleTiledModel; 3 | using UnityEngine; 4 | 5 | namespace Core.InputProviders 6 | { 7 | public abstract class InputDataProvider : MonoBehaviour, IInputDataProvider 8 | { 9 | public abstract InputOverlappingData GetInputOverlappingData(); 10 | 11 | public abstract InputSimpleTiledModelData GetInputSimpleTiledData(); 12 | } 13 | } -------------------------------------------------------------------------------- /Assets/Scripts/Core/InputProviders/InputDataProvider.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 46003b03a9034556a473881ce5becffa 3 | timeCreated: 1523305502 -------------------------------------------------------------------------------- /Assets/Scripts/Core/InputProviders/SymmetrySetsScriptableObject.cs: -------------------------------------------------------------------------------- 1 | using Core.Data.SimpleTiledModel; 2 | using Core.Helpers; 3 | using UnityEditor; 4 | using UnityEngine; 5 | 6 | namespace Core.InputProviders 7 | { 8 | public class SymmetrySetsScriptableObject : ScriptableObject 9 | { 10 | [SerializeField] 11 | public GameObject[] SymmetryX; 12 | 13 | [SerializeField] 14 | public GameObject[] SymmetryL; 15 | 16 | [SerializeField] 17 | public GameObject[] SymmetryT; 18 | 19 | [SerializeField] 20 | public GameObject[] SymmetryI; 21 | 22 | [SerializeField] 23 | public GameObject[] SymmetrySlash; 24 | 25 | [MenuItem("Assets/Create/SymmetrySetsScriptableObject")] 26 | public static void CreateAsset () 27 | { 28 | ScriptableObjectUtility.CreateAsset(); 29 | } 30 | 31 | public SymmetryType GetSymmetryByTileName(string name) 32 | { 33 | if (Find(SymmetryX, name)) return SymmetryType.X; 34 | if (Find(SymmetryL, name)) return SymmetryType.L; 35 | if (Find(SymmetryT, name)) return SymmetryType.T; 36 | if (Find(SymmetryI, name)) return SymmetryType.I; 37 | if (Find(SymmetrySlash, name)) return SymmetryType.Slash; 38 | 39 | return SymmetryType.X; 40 | } 41 | 42 | private bool Find(GameObject[] set, string name) 43 | { 44 | foreach (var gameObject in set) 45 | { 46 | if (gameObject.name == name) 47 | { 48 | return true; 49 | } 50 | } 51 | 52 | return false; 53 | } 54 | } 55 | } -------------------------------------------------------------------------------- /Assets/Scripts/Core/InputProviders/SymmetrySetsScriptableObject.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1923b6bdd0a346ecafb5d8f590b6ab38 3 | timeCreated: 1522694145 -------------------------------------------------------------------------------- /Assets/Scripts/Core/InputProviders/TilePainterInputDataProvider.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using Core.Data; 5 | using Core.Data.OverlappingModel; 6 | using Core.Data.SimpleTiledModel; 7 | using UnityEngine; 8 | 9 | namespace Core.InputProviders 10 | { 11 | public class TilePainterInputDataProvider : InputDataProvider 12 | { 13 | [SerializeField] 14 | private int width; 15 | 16 | [SerializeField] 17 | private int height; 18 | 19 | [SerializeField] 20 | private int depth; 21 | 22 | [SerializeField] 23 | private TilePainter tilePainter; 24 | 25 | [SerializeField] 26 | private GameObject tilesParent; 27 | 28 | [SerializeField] 29 | private GameObject[] tilesPrefabs; 30 | 31 | [SerializeField] 32 | private SymmetrySetsScriptableObject symmetrySets; 33 | 34 | private Dictionary tilesPrefabMap; 35 | 36 | private void Awake() 37 | { 38 | FillPrefabMap(); 39 | } 40 | 41 | public override InputOverlappingData GetInputOverlappingData() 42 | { 43 | if (Application.isPlaying == false) 44 | { 45 | FillPrefabMap(); 46 | } 47 | 48 | var tileConfigData = CreateTileConfigData(tilePrefab => new TileConfig(tilePrefab)); 49 | 50 | var inputData = new InputOverlappingData(tileConfigData, width, depth); 51 | 52 | ExecuteForEachTile((tile, pos, rotation) => 53 | { 54 | inputData.SetTile(tileConfigData.GetConfig(tile.name), (int)pos.x, (int)pos.z, rotation); 55 | }); 56 | 57 | return inputData; 58 | } 59 | 60 | public override InputSimpleTiledModelData GetInputSimpleTiledData() 61 | { 62 | if (Application.isPlaying == false) 63 | { 64 | FillPrefabMap(); 65 | } 66 | 67 | var tileConfigsData = CreateTileConfigData(tilePrefab => 68 | { 69 | var symmetry = symmetrySets.GetSymmetryByTileName(tilePrefab.name); 70 | Debug.Log(tilePrefab.name + " " + symmetry); 71 | var config = new SimpleTiledModelTileConfig(tilePrefab, symmetry); 72 | 73 | return config; 74 | }); 75 | 76 | var inputData = new InputSimpleTiledModelData(tileConfigsData); 77 | var tiles = new SimpleTiledModelTile[width, height, depth]; 78 | 79 | ExecuteForEachTile((tileGo, pos, rotation) => 80 | { 81 | tiles[(int)pos.x, (int)pos.y, (int)pos.z] = new SimpleTiledModelTile(tileConfigsData.GetConfig(tileGo.name), rotation); 82 | }); 83 | 84 | var neighbors = new Dictionary(); 85 | 86 | for (int x = 0; x < width; x++) 87 | for (int y = 0; y < height; y++) 88 | for (int z = 0; z < depth; z++) 89 | { 90 | var currentTile = tiles[x, y, z]; 91 | if (currentTile == null) continue; 92 | 93 | SimpleTiledModelTile nextTile; 94 | string key; 95 | 96 | for (var offset = 0; offset < 2; offset++){ 97 | var rx = x + 1 - offset; 98 | var rz = z + offset; 99 | if (rx >= width || rz >= depth) continue; 100 | 101 | var currentTileRotation = Card(currentTile.Rotation + offset); 102 | nextTile = tiles[rx, y, rz]; 103 | 104 | if (nextTile == null) continue; 105 | 106 | var nextTileRotation = Card(nextTile.Rotation + offset); 107 | 108 | key = currentTile.Config.Id + "." + currentTileRotation + " | " + nextTile.Config.Id + "." + nextTileRotation ; 109 | 110 | if (neighbors.ContainsKey(key)) continue; 111 | Debug.Log(key); 112 | 113 | neighbors.Add(key, new NeighborData(currentTile.Config, nextTile.Config, currentTileRotation, nextTileRotation)); 114 | DrawDebugLine(new Vector3(x, y - 0.5f, z), new Vector3(rx, y - 0.5f, rz)); 115 | } 116 | 117 | if(y == 0) continue; 118 | nextTile = tiles[x, y - 1, z]; 119 | if (nextTile == null) continue; 120 | 121 | key = currentTile.Config.Id + "." + currentTile.Rotation + " | " + nextTile.Config.Id + "." + nextTile.Rotation + " |vertical" ; 122 | if (neighbors.ContainsKey(key)) continue; 123 | Debug.Log(key); 124 | 125 | neighbors.Add(key, new NeighborData(currentTile.Config, nextTile.Config, currentTile.Rotation, nextTile.Rotation, false)); 126 | DrawDebugLine(new Vector3(x, y, z), new Vector3(x, y - 1, z )); 127 | } 128 | 129 | 130 | inputData.SetNeighbors(neighbors.Values.ToList()); 131 | 132 | return inputData; 133 | } 134 | 135 | public int Card(int n){ 136 | return (n%4 + 4)%4; 137 | } 138 | 139 | private void DrawDebugLine(Vector3 start, Vector3 target) 140 | { 141 | Debug.DrawLine(transform.TransformPoint(start), transform.TransformPoint(target), Color.red, 9.0f, false); 142 | } 143 | 144 | private TileConfigData CreateTileConfigData(Func creator) where T : TileConfig 145 | { 146 | var tileConfigData = new TileConfigData(); 147 | ExecuteForEachTile((tile, pos, rotation) => 148 | { 149 | var tileConfig = tileConfigData.GetConfig(tile.name); 150 | if (tileConfig == null) 151 | { 152 | tileConfigData.AddConfig(creator(GetPrefab(tile.name))); 153 | } 154 | }); 155 | return tileConfigData; 156 | } 157 | 158 | private void ExecuteForEachTile(Action action) 159 | { 160 | foreach (Transform child in tilesParent.transform) 161 | { 162 | var x = Mathf.RoundToInt(child.localPosition.x); 163 | var y = Mathf.RoundToInt(child.localPosition.y); 164 | var z = Mathf.RoundToInt(child.localPosition.z); 165 | int rotation = (int)((360 + Mathf.Round(child.localEulerAngles.y))/90); 166 | rotation = rotation % 4; 167 | 168 | action(child.gameObject, new Vector3(x, y, z), rotation); 169 | } 170 | } 171 | 172 | private GameObject GetPrefab(string name) 173 | { 174 | foreach (var tilePrefab in tilesPrefabs) 175 | { 176 | if (tilePrefab.name == name) 177 | { 178 | return tilePrefab; 179 | } 180 | } 181 | return null; 182 | } 183 | 184 | private void FillPrefabMap() 185 | { 186 | tilesPrefabMap = new Dictionary(); 187 | foreach (var tilePrefab in tilesPrefabs) 188 | { 189 | tilesPrefabMap.Add(tilePrefab.name, tilePrefab); 190 | } 191 | } 192 | 193 | private void OnDrawGizmos(){ 194 | Gizmos.color = Color.cyan; 195 | Gizmos.matrix = transform.localToWorldMatrix; 196 | Gizmos.DrawWireCube(new Vector3(-0.5f + width/2, 0f, -0.5f + depth/2), 197 | new Vector3(width, 1, depth)); 198 | } 199 | } 200 | } -------------------------------------------------------------------------------- /Assets/Scripts/Core/InputProviders/TilePainterInputDataProvider.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e51ccc3ab24604467a87a38bc6d5772b 3 | timeCreated: 1523219539 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/Scripts/Core/InputProviders/YuMEInputDataProvider.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using Core.Data; 5 | using Core.Data.OverlappingModel; 6 | using Core.Data.SimpleTiledModel; 7 | using UnityEngine; 8 | 9 | namespace Core.InputProviders 10 | { 11 | public class YuMEInputDataProvider : InputDataProvider 12 | { 13 | [SerializeField] 14 | private int width; 15 | 16 | [SerializeField] 17 | private int height; 18 | 19 | [SerializeField] 20 | private int depth; 21 | 22 | [SerializeField] 23 | private GameObject[] levelsList; 24 | 25 | [SerializeField] 26 | private GameObject[] tilesPrefabs; 27 | 28 | [SerializeField] 29 | private SymmetrySetsScriptableObject symmetrySets; 30 | 31 | private Dictionary tilesPrefabMap; 32 | 33 | private void Awake() 34 | { 35 | FillPrefabMap(); 36 | } 37 | 38 | public override InputOverlappingData GetInputOverlappingData() 39 | { 40 | if (Application.isPlaying == false) 41 | { 42 | FillPrefabMap(); 43 | } 44 | 45 | var tileConfigData = CreateTileConfigData(tilePrefab => new TileConfig(tilePrefab)); 46 | 47 | var inputData = new InputOverlappingData(tileConfigData, width, depth); 48 | 49 | ExecuteForEachTile((tile, pos, rotation) => 50 | { 51 | inputData.SetTile(tileConfigData.GetConfig(tile.name), (int)pos.x, (int)pos.z, rotation); 52 | }); 53 | 54 | return inputData; 55 | } 56 | 57 | public override InputSimpleTiledModelData GetInputSimpleTiledData() 58 | { 59 | if (Application.isPlaying == false) 60 | { 61 | FillPrefabMap(); 62 | } 63 | 64 | var tileConfigsData = CreateTileConfigData(tilePrefab => 65 | { 66 | var symmetry = symmetrySets.GetSymmetryByTileName(tilePrefab.name); 67 | Debug.Log(tilePrefab.name + " " + symmetry); 68 | var config = new SimpleTiledModelTileConfig(tilePrefab, symmetry); 69 | 70 | return config; 71 | }); 72 | 73 | var inputData = new InputSimpleTiledModelData(tileConfigsData); 74 | var tiles = new SimpleTiledModelTile[width, height, depth]; 75 | 76 | ExecuteForEachTile((tileGo, pos, rotation) => 77 | { 78 | tiles[(int)pos.x, (int)pos.y, (int)pos.z] = new SimpleTiledModelTile(tileConfigsData.GetConfig(tileGo.name), rotation); 79 | }); 80 | 81 | var neighbors = new Dictionary(); 82 | 83 | for (int x = 0; x < width; x++) 84 | for (int y = 0; y < height; y++) 85 | for (int z = 0; z < depth; z++) 86 | { 87 | var currentTile = tiles[x, y, z]; 88 | if (currentTile == null) continue; 89 | 90 | SimpleTiledModelTile nextTile; 91 | string key; 92 | 93 | for (var offset = 0; offset < 2; offset++){ 94 | var rx = x + 1 - offset; 95 | var rz = z + offset; 96 | if (rx >= width || rz >= depth) continue; 97 | 98 | var currentTileRotation = Card(currentTile.Rotation + offset); 99 | nextTile = tiles[rx, y, rz]; 100 | 101 | if (nextTile == null) continue; 102 | 103 | var nextTileRotation = Card(nextTile.Rotation + offset); 104 | 105 | key = currentTile.Config.Id + "." + currentTileRotation + " | " + nextTile.Config.Id + "." + nextTileRotation ; 106 | 107 | if (neighbors.ContainsKey(key)) continue; 108 | Debug.Log(key); 109 | 110 | neighbors.Add(key, new NeighborData(currentTile.Config, nextTile.Config, currentTileRotation, nextTileRotation)); 111 | DrawDebugLine(new Vector3(x, y - 0.5f, z), new Vector3(rx, y - 0.5f, rz)); 112 | } 113 | 114 | if(y == 0) continue; 115 | nextTile = tiles[x, y - 1, z]; 116 | if (nextTile == null) continue; 117 | 118 | key = currentTile.Config.Id + "." + currentTile.Rotation + " | " + nextTile.Config.Id + "." + nextTile.Rotation + " |vertical" ; 119 | if (neighbors.ContainsKey(key)) continue; 120 | Debug.Log(key); 121 | 122 | neighbors.Add(key, new NeighborData(currentTile.Config, nextTile.Config, currentTile.Rotation, nextTile.Rotation, false)); 123 | DrawDebugLine(new Vector3(x, y, z), new Vector3(x, y - 1, z )); 124 | } 125 | 126 | 127 | inputData.SetNeighbors(neighbors.Values.ToList()); 128 | 129 | return inputData; 130 | } 131 | 132 | public int Card(int n){ 133 | return (n%4 + 4)%4; 134 | } 135 | 136 | private void DrawDebugLine(Vector3 start, Vector3 target) 137 | { 138 | var offsetWidth = Mathf.CeilToInt(width / 2); 139 | var offsetDepth = Mathf.CeilToInt(depth / 2); 140 | 141 | start.x -= offsetWidth; 142 | start.z -= offsetDepth; 143 | 144 | target.x -= offsetWidth; 145 | target.z -= offsetDepth; 146 | 147 | Debug.DrawLine(transform.TransformPoint(start), transform.TransformPoint(target), Color.red, 9.0f, false); 148 | } 149 | 150 | private TileConfigData CreateTileConfigData(Func creator) where T : TileConfig 151 | { 152 | var tileConfigData = new TileConfigData(); 153 | ExecuteForEachTile((tile, pos, rotation) => 154 | { 155 | var tileConfig = tileConfigData.GetConfig(tile.name); 156 | if (tileConfig == null) 157 | { 158 | tileConfigData.AddConfig(creator(GetPrefab(tile.name))); 159 | } 160 | }); 161 | return tileConfigData; 162 | } 163 | 164 | private void ExecuteForEachTile(Action action) 165 | { 166 | var offsetWidth = Mathf.CeilToInt(width / 2); 167 | var offsetDepth = Mathf.CeilToInt(depth / 2); 168 | 169 | foreach (var levelContainer in levelsList) 170 | { 171 | foreach (Transform child in levelContainer.transform) 172 | { 173 | var x = Mathf.RoundToInt(child.localPosition.x) + offsetWidth; 174 | var y = Mathf.RoundToInt(child.localPosition.y); 175 | var z = Mathf.RoundToInt(child.localPosition.z) + offsetDepth; 176 | int rotation = (int)((360 + Mathf.Round(child.localEulerAngles.y))/90); 177 | rotation = rotation % 4; 178 | 179 | action(child.gameObject, new Vector3(x, y, z), rotation); 180 | } 181 | } 182 | } 183 | 184 | private GameObject GetPrefab(string name) 185 | { 186 | foreach (var tilePrefab in tilesPrefabs) 187 | { 188 | if (tilePrefab.name == name) 189 | { 190 | return tilePrefab; 191 | } 192 | } 193 | 194 | return null; 195 | } 196 | 197 | private void FillPrefabMap() 198 | { 199 | tilesPrefabMap = new Dictionary(); 200 | foreach (var tilePrefab in tilesPrefabs) 201 | { 202 | tilesPrefabMap.Add(tilePrefab.name, tilePrefab); 203 | } 204 | } 205 | 206 | private void OnDrawGizmos(){ 207 | Gizmos.color = Color.cyan; 208 | Gizmos.matrix = transform.localToWorldMatrix; 209 | Gizmos.DrawWireCube(new Vector3(-0.5f, 0f, -0.5f), 210 | new Vector3(width, 1, depth)); 211 | } 212 | } 213 | } -------------------------------------------------------------------------------- /Assets/Scripts/Core/InputProviders/YuMEInputDataProvider.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 9d066cd3e4f44e6da998e5501abe41e1 3 | timeCreated: 1520542643 -------------------------------------------------------------------------------- /Assets/Scripts/Core/Model.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: cc519e4b1c3d4872b560c4abd877236f 3 | timeCreated: 1521494181 -------------------------------------------------------------------------------- /Assets/Scripts/Core/Model/IModel.cs: -------------------------------------------------------------------------------- 1 | using Core.Data; 2 | 3 | namespace Core.Model 4 | { 5 | public interface IModel 6 | { 7 | CellState GetCellStateAt(int x, int y); 8 | 9 | WaveFunctionCollapseModelParams ModelParam { get; } 10 | } 11 | } -------------------------------------------------------------------------------- /Assets/Scripts/Core/Model/IModel.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a4a4db79fa67495f96dab28a302491c0 3 | timeCreated: 1522959550 -------------------------------------------------------------------------------- /Assets/Scripts/Core/Model/Model.cs: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License(MIT) 3 | Copyright(c) mxgmn 2016. 4 | 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: 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 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. 7 | */ 8 | 9 | using System; 10 | using System.Collections; 11 | using Core.Data; 12 | using UnityEngine; 13 | using Random = System.Random; 14 | 15 | namespace Core.Model 16 | { 17 | public abstract class Model : IModel where PARAM : WaveFunctionCollapseModelParams 18 | { 19 | protected bool[][] wave; 20 | protected double[] stationary; 21 | protected int[] observed; 22 | 23 | protected bool[] changes; 24 | protected int[] stack; 25 | protected int stacksize; 26 | 27 | protected System.Random random; 28 | protected int FMX, FMY, T; 29 | 30 | /// 31 | /// Whether the input data wraps around an axis. 32 | /// 33 | protected bool periodic; 34 | 35 | private double[] logProb; 36 | private double logT; 37 | private PARAM modelParam; 38 | 39 | /// 40 | /// Amount of all possible patterns 41 | /// 42 | public int PatternsAmount 43 | { 44 | get { return T; } 45 | } 46 | 47 | public WaveFunctionCollapseModelParams ModelParam 48 | { 49 | get { return modelParam; } 50 | } 51 | 52 | protected Model(PARAM modelParam) 53 | { 54 | this.modelParam = modelParam; 55 | FMX = modelParam.Width; 56 | FMY = modelParam.Depth; 57 | 58 | wave = new bool[FMX * FMY][]; 59 | changes = new bool[FMX * FMY]; 60 | 61 | stack = new int[FMX * FMY]; 62 | stacksize = 0; 63 | } 64 | 65 | 66 | /// 67 | /// Run model to generate output 68 | /// 69 | /// All internal random values are derived from this seed, providing 0 results in a random number. 70 | /// How many iterations to run, providing 0 will run until completion or a contradiction. 71 | /// 72 | public bool Run(int seed, int limit) 73 | { 74 | Init(seed); 75 | 76 | for (int l = 0; l < limit || limit == 0; l++) 77 | { 78 | bool? result = Observe(); 79 | if (result != null) return result.Value; 80 | Propagate(); 81 | } 82 | 83 | return true; 84 | } 85 | 86 | /// 87 | /// Run model as Enumerator to generate output 88 | /// 89 | /// All internal random values are derived from this seed, providing 0 results in a random number. 90 | /// How many iterations to run, providing 0 will run until completion or a contradiction. 91 | /// 92 | public IEnumerator RunViaEnumerator(int seed, int limit, Action resultCallback, Action iterationCallback) 93 | { 94 | Init(seed); 95 | 96 | for (int iteration = 0; iteration < limit || limit == 0; iteration++) 97 | { 98 | bool? result = Observe(); 99 | if (result != null) 100 | { 101 | resultCallback(result.Value); 102 | break; 103 | } 104 | Debug.Log("Propagate, iteration: " + iteration); 105 | Propagate(); 106 | iterationCallback(wave); 107 | yield return null; 108 | } 109 | } 110 | 111 | private void Init(int seed) 112 | { 113 | logT = Math.Log(T); 114 | logProb = new double[T]; 115 | for (int t = 0; t < T; t++) 116 | { 117 | logProb[t] = Math.Log(stationary[t]); 118 | } 119 | 120 | Clear(); 121 | 122 | random = new Random(seed); 123 | if (seed == 0) 124 | { 125 | random = new Random(); 126 | } 127 | } 128 | 129 | protected abstract void Propagate(); 130 | 131 | protected void InitWave() 132 | { 133 | for (var i = 0; i < wave.Length; i++) wave[i] = new bool[T]; 134 | } 135 | 136 | bool? Observe() 137 | { 138 | Debug.Log("Observe state"); 139 | int? indexWithLowestEntropy = FindCellWithLowestEntropy(); 140 | 141 | //There is the cell with no possible values which means that we found a contradiction 142 | if (indexWithLowestEntropy == null) return false; 143 | 144 | Debug.Log("Cell with lowest entropy : " + indexWithLowestEntropy); 145 | // All values has collapsed, fill result in observed function 146 | if (indexWithLowestEntropy == -1) 147 | { 148 | FillGeneratedResult(); 149 | return true; 150 | } 151 | 152 | //collapse cell value to one of possiblities randomly based on their weight 153 | double[] distribution = new double[T]; 154 | for (int t = 0; t < T; t++) 155 | { 156 | distribution[t] = wave[indexWithLowestEntropy.Value][t] ? stationary[t] : 0; 157 | } 158 | int r = distribution.Random(random.NextDouble()); 159 | for (int t = 0; t < T; t++) 160 | { 161 | wave[indexWithLowestEntropy.Value][t] = t == r; 162 | } 163 | Change(indexWithLowestEntropy.Value); 164 | 165 | return null; 166 | } 167 | 168 | private int? FindCellWithLowestEntropy() 169 | { 170 | double min = 1E+3; 171 | int indexWithLowestEntropy = -1; 172 | 173 | for (int i = 0; i < wave.Length; i++) 174 | { 175 | if (OnBoundary(i)) continue; 176 | 177 | bool[] waveValuesForCurrentIndex = wave[i]; 178 | int amount = 0; 179 | double sum = 0; 180 | 181 | for (int t = 0; t < T; t++) 182 | { 183 | if (waveValuesForCurrentIndex[t] == false) continue; 184 | amount += 1; 185 | sum += stationary[t]; 186 | } 187 | 188 | if (sum == 0) 189 | { 190 | return null; 191 | } 192 | 193 | double noise = 1E-6 * random.NextDouble(); 194 | 195 | double entropy = CalculateEntropy(amount, sum, waveValuesForCurrentIndex); 196 | 197 | if (entropy > 0 && entropy + noise < min) 198 | { 199 | min = entropy + noise; 200 | indexWithLowestEntropy = i; 201 | } 202 | } 203 | 204 | return indexWithLowestEntropy; 205 | } 206 | 207 | private void FillGeneratedResult() 208 | { 209 | observed = new int[FMX * FMY]; 210 | for (int i = 0; i < wave.Length; i++) 211 | { 212 | for (int t = 0; t < T; t++) 213 | { 214 | if (wave[i][t]) 215 | { 216 | observed[i] = t; 217 | break; 218 | } 219 | } 220 | } 221 | } 222 | 223 | public abstract CellState GetCellStateAt(int x, int y); 224 | 225 | protected void CalculateEntropyAndPatternIdAt(int x, int y, out float entropy, out int? patternId) 226 | { 227 | int indexInWave = x + y * FMX; 228 | int amount = 0; 229 | patternId = null; 230 | var possiblePatternsFlags = wave[indexInWave]; 231 | for (int t = 0; t < T; t++) 232 | { 233 | if (possiblePatternsFlags[t]) 234 | { 235 | amount += 1; 236 | patternId = t; 237 | } 238 | } 239 | 240 | if (amount != 1) 241 | { 242 | patternId = null; 243 | } 244 | 245 | entropy = (float)amount / T; 246 | } 247 | 248 | private double CalculateEntropy(int amount, double sum, bool[] waveValuesForCurrentIndex) 249 | { 250 | if (amount == 1) 251 | { 252 | return 0; 253 | } 254 | if (amount == T) 255 | { 256 | return logT; 257 | } 258 | 259 | double mainSum = 0; 260 | double logSum = Math.Log(sum); 261 | for (int t = 0; t < T; t++) 262 | { 263 | if (waveValuesForCurrentIndex[t]) 264 | { 265 | mainSum += stationary[t] * logProb[t]; 266 | } 267 | } 268 | 269 | return logSum - mainSum / sum; 270 | } 271 | 272 | protected void Change(int i) 273 | { 274 | if (changes[i]) return; 275 | 276 | stack[stacksize] = i; 277 | stacksize++; 278 | changes[i] = true; 279 | } 280 | 281 | protected virtual void Clear() 282 | { 283 | for (int i = 0; i < wave.Length; i++) 284 | { 285 | for (int t = 0; t < T; t++) wave[i][t] = true; 286 | changes[i] = false; 287 | } 288 | } 289 | 290 | public abstract bool OnBoundary(int i); 291 | } 292 | } 293 | -------------------------------------------------------------------------------- /Assets/Scripts/Core/Model/Model.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1f4c2f81339c148b496c5362f257d574 3 | timeCreated: 1520355919 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/Scripts/Core/Model/ModelHelper.cs: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License(MIT) 3 | Copyright(c) mxgmn 2016. 4 | 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: 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 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. 7 | */ 8 | 9 | using System.Linq; 10 | 11 | namespace Core.Model 12 | { 13 | static class ModelHelper 14 | { 15 | public static int Random(this double[] a, double r) 16 | { 17 | double sum = a.Sum(); 18 | 19 | if (sum == 0) 20 | { 21 | for (int j = 0; j < a.Count(); j++) a[j] = 1; 22 | sum = a.Sum(); 23 | } 24 | 25 | for (int j = 0; j < a.Count(); j++) a[j] /= sum; 26 | 27 | int i = 0; 28 | double x = 0; 29 | 30 | while (i < a.Count()) 31 | { 32 | x += a[i]; 33 | if (r <= x) return i; 34 | i++; 35 | } 36 | 37 | return 0; 38 | } 39 | 40 | public static long Power(int a, int n) 41 | { 42 | long product = 1; 43 | for (int i = 0; i < n; i++) product *= a; 44 | return product; 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /Assets/Scripts/Core/Model/ModelHelper.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 24acf13cfa8d34822ad2a2d092f91a17 3 | timeCreated: 1520355919 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/Scripts/Core/Model/New.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e3d7e787b30af4c039bd6c9916717e24 3 | folderAsset: yes 4 | timeCreated: 1523140960 5 | licenseType: Pro 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/Scripts/Core/Model/New/IModel3d.cs: -------------------------------------------------------------------------------- 1 | using Core.Data; 2 | 3 | namespace Core.Model 4 | { 5 | public interface IModel3d 6 | { 7 | CellState GetCellStateAt(int x, int y, int z); 8 | 9 | WaveFunctionCollapseModelParams ModelParam { get; } 10 | } 11 | } -------------------------------------------------------------------------------- /Assets/Scripts/Core/Model/New/IModel3d.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 9a81d6f3216584851af3efe9fa676c81 3 | timeCreated: 1523190176 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/Scripts/Core/Model/New/Model2d.cs: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License(MIT) 3 | Copyright(c) mxgmn 2016. 4 | 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: 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 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. 7 | */ 8 | 9 | using System; 10 | using System.Collections; 11 | using Core.Data; 12 | using Core.Model; 13 | using Eppy; 14 | using UnityEngine; 15 | using Random = System.Random; 16 | 17 | public abstract class Model2d : IModel where PARAM : WaveFunctionCollapseModelParams 18 | { 19 | protected bool[][] wave; 20 | 21 | protected int[][][] propagator; 22 | int[][][] compatible; 23 | protected int[] observed; 24 | 25 | Eppy.Tuple[] stack; 26 | int stacksize; 27 | 28 | protected Random random; 29 | protected int FMX, FMY, T; 30 | protected bool periodic; 31 | 32 | protected double[] weights; 33 | double[] weightLogWeights; 34 | 35 | int[] sumsOfOnes; 36 | double sumOfWeights, sumOfWeightLogWeights, startingEntropy; 37 | double[] sumsOfWeights, sumsOfWeightLogWeights, entropies; 38 | 39 | public WaveFunctionCollapseModelParams ModelParam { get; private set; } 40 | 41 | protected Model2d(PARAM modelParam) 42 | { 43 | this.ModelParam = modelParam; 44 | 45 | FMX = modelParam.Width; 46 | FMY = modelParam.Depth; 47 | } 48 | 49 | public bool Run(int seed, int limit) 50 | { 51 | if (wave == null) Init(); 52 | 53 | Clear(); 54 | random = new Random(seed); 55 | 56 | for (int l = 0; l < limit || limit == 0; l++) 57 | { 58 | bool? result = Observe(); 59 | if (result != null) return (bool)result; 60 | Propagate(); 61 | } 62 | 63 | return true; 64 | } 65 | 66 | public IEnumerator RunViaEnumerator(int seed, int limit, Action resultCallback, Action iterationCallback) 67 | { 68 | if (wave == null) Init(); 69 | 70 | Clear(); 71 | if (seed != 0) 72 | { 73 | random = new Random(seed); 74 | } 75 | else 76 | { 77 | random = new Random(); 78 | } 79 | 80 | for (int l = 0; l < limit || limit == 0; l++) 81 | { 82 | bool? result = Observe(); 83 | if (result != null) 84 | { 85 | resultCallback(result.Value); 86 | break; 87 | } 88 | Debug.Log("Propagate, iteration: " + l); 89 | Propagate(); 90 | iterationCallback(wave); 91 | yield return null; 92 | } 93 | } 94 | 95 | private void Init() 96 | { 97 | wave = new bool[FMX * FMY][]; 98 | compatible = new int[wave.Length][][]; 99 | for (int i = 0; i < wave.Length; i++) 100 | { 101 | wave[i] = new bool[T]; 102 | compatible[i] = new int[T][]; 103 | for (int t = 0; t < T; t++) compatible[i][t] = new int[4]; 104 | } 105 | 106 | weightLogWeights = new double[T]; 107 | sumOfWeights = 0; 108 | sumOfWeightLogWeights = 0; 109 | 110 | for (int t = 0; t < T; t++) 111 | { 112 | weightLogWeights[t] = weights[t] * Math.Log(weights[t]); 113 | sumOfWeights += weights[t]; 114 | sumOfWeightLogWeights += weightLogWeights[t]; 115 | } 116 | 117 | startingEntropy = Math.Log(sumOfWeights) - sumOfWeightLogWeights / sumOfWeights; 118 | 119 | sumsOfOnes = new int[FMX * FMY]; 120 | sumsOfWeights = new double[FMX * FMY]; 121 | sumsOfWeightLogWeights = new double[FMX * FMY]; 122 | entropies = new double[FMX * FMY]; 123 | 124 | stack = new Eppy.Tuple[wave.Length * T]; 125 | stacksize = 0; 126 | } 127 | 128 | bool? Observe() 129 | { 130 | double min = 1E+3; 131 | int argmin = -1; 132 | 133 | for (int i = 0; i < wave.Length; i++) 134 | { 135 | if (OnBoundary(i % FMX, i / FMX)) continue; 136 | 137 | int amount = sumsOfOnes[i]; 138 | if (amount == 0) return false; 139 | 140 | double entropy = entropies[i]; 141 | if (amount > 1 && entropy <= min) 142 | { 143 | double noise = 1E-6 * random.NextDouble(); 144 | if (entropy + noise < min) 145 | { 146 | min = entropy + noise; 147 | argmin = i; 148 | } 149 | } 150 | } 151 | 152 | if (argmin == -1) 153 | { 154 | observed = new int[FMX * FMY]; 155 | for (int i = 0; i < wave.Length; i++) for (int t = 0; t < T; t++) if (wave[i][t]) { observed[i] = t; break; } 156 | return true; 157 | } 158 | 159 | double[] distribution = new double[T]; 160 | for (int t = 0; t < T; t++) distribution[t] = wave[argmin][t] ? weights[t] : 0; 161 | int r = distribution.Random(random.NextDouble()); 162 | 163 | bool[] w = wave[argmin]; 164 | for (int t = 0; t < T; t++) if (w[t] != (t == r)) Ban(argmin, t); 165 | 166 | return null; 167 | } 168 | 169 | protected void Propagate() 170 | { 171 | while (stacksize > 0) 172 | { 173 | var e1 = stack[stacksize - 1]; 174 | stacksize--; 175 | 176 | int i1 = e1.Item1; 177 | int x1 = i1 % FMX, y1 = i1 / FMX; 178 | bool[] w1 = wave[i1]; 179 | 180 | for (int d = 0; d < 4; d++) 181 | { 182 | int dx = DX[d], dy = DY[d]; 183 | int x2 = x1 + dx, y2 = y1 + dy; 184 | if (OnBoundary(x2, y2)) continue; 185 | 186 | if (x2 < 0) x2 += FMX; 187 | else if (x2 >= FMX) x2 -= FMX; 188 | if (y2 < 0) y2 += FMY; 189 | else if (y2 >= FMY) y2 -= FMY; 190 | 191 | int i2 = x2 + y2 * FMX; 192 | int[] p = propagator[d][e1.Item2]; 193 | int[][] compat = compatible[i2]; 194 | 195 | for (int l = 0; l < p.Length; l++) 196 | { 197 | int t2 = p[l]; 198 | int[] comp = compat[t2]; 199 | 200 | comp[d]--; 201 | if (comp[d] == 0) Ban(i2, t2); 202 | } 203 | } 204 | } 205 | } 206 | 207 | protected void Ban(int i, int t) 208 | { 209 | wave[i][t] = false; 210 | 211 | int[] comp = compatible[i][t]; 212 | for (int d = 0; d < 4; d++) comp[d] = 0; 213 | stack[stacksize] = new Eppy.Tuple(i, t); 214 | stacksize++; 215 | 216 | double sum = sumsOfWeights[i]; 217 | entropies[i] += sumsOfWeightLogWeights[i] / sum - Math.Log(sum); 218 | 219 | sumsOfOnes[i] -= 1; 220 | sumsOfWeights[i] -= weights[t]; 221 | sumsOfWeightLogWeights[i] -= weightLogWeights[t]; 222 | 223 | sum = sumsOfWeights[i]; 224 | entropies[i] -= sumsOfWeightLogWeights[i] / sum - Math.Log(sum); 225 | } 226 | 227 | protected virtual void Clear() 228 | { 229 | for (int i = 0; i < wave.Length; i++) 230 | { 231 | for (int t = 0; t < T; t++) 232 | { 233 | wave[i][t] = true; 234 | for (int d = 0; d < 4; d++) compatible[i][t][d] = propagator[opposite[d]][t].Length; 235 | } 236 | 237 | sumsOfOnes[i] = weights.Length; 238 | sumsOfWeights[i] = sumOfWeights; 239 | sumsOfWeightLogWeights[i] = sumOfWeightLogWeights; 240 | entropies[i] = startingEntropy; 241 | } 242 | } 243 | 244 | protected void CalculateEntropyAndPatternIdAt(int x, int y, out double entropy, out int? patternId) 245 | { 246 | int indexInWave = x + y * FMX; 247 | int amount = 0; 248 | patternId = null; 249 | var possiblePatternsFlags = wave[indexInWave]; 250 | for (int t = 0; t < T; t++) 251 | { 252 | if (possiblePatternsFlags[t]) 253 | { 254 | amount += 1; 255 | patternId = t; 256 | } 257 | } 258 | 259 | if (amount != 1) 260 | { 261 | patternId = null; 262 | } 263 | 264 | entropy = entropies[indexInWave] / startingEntropy; 265 | } 266 | 267 | protected abstract bool OnBoundary(int x, int y); 268 | 269 | public abstract CellState GetCellStateAt(int x, int y); 270 | 271 | protected static int[] DX = { -1, 0, 1, 0 }; 272 | protected static int[] DY = { 0, 1, 0, -1 }; 273 | static int[] opposite = { 2, 3, 0, 1 }; 274 | 275 | } 276 | -------------------------------------------------------------------------------- /Assets/Scripts/Core/Model/New/Model2d.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e79b50d6e29204a2f8bad53668f3e04d 3 | timeCreated: 1523142111 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/Scripts/Core/Model/New/Model3d.cs: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License(MIT) 3 | Copyright(c) mxgmn 2016. 4 | 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: 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 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. 7 | */ 8 | 9 | using System; 10 | using System.Collections; 11 | using Core.Data; 12 | using Core.Model; 13 | using Eppy; 14 | using UnityEngine; 15 | using Random = System.Random; 16 | 17 | public abstract class Model3d : IModel3d where PARAM : WaveFunctionCollapseModelParams 18 | { 19 | public const int DIRECTIONS_AMOUNT = 6; 20 | 21 | protected bool[][] wave; 22 | 23 | protected int[][][] propagator; 24 | int[][][] compatible; 25 | protected int[] observed; 26 | 27 | Eppy.Tuple[] stack; 28 | int stacksize; 29 | 30 | protected Random random; 31 | protected readonly int FMX; 32 | protected readonly int FMY; 33 | protected readonly int FMZ; 34 | protected int T; 35 | protected bool periodic; 36 | 37 | protected double[] weights; 38 | double[] weightLogWeights; 39 | 40 | int[] sumsOfOnes; 41 | double sumOfWeights, sumOfWeightLogWeights, startingEntropy; 42 | double[] sumsOfWeights, sumsOfWeightLogWeights, entropies; 43 | 44 | public WaveFunctionCollapseModelParams ModelParam { get; private set; } 45 | 46 | protected Model3d(PARAM modelParam) 47 | { 48 | this.ModelParam = modelParam; 49 | 50 | FMX = modelParam.Width; 51 | FMY = modelParam.Height; 52 | FMZ = modelParam.Depth; 53 | } 54 | 55 | public bool Run(int seed, int limit) 56 | { 57 | if (wave == null) Init(); 58 | 59 | Clear(); 60 | random = new Random(seed); 61 | 62 | for (int l = 0; l < limit || limit == 0; l++) 63 | { 64 | bool? result = Observe(); 65 | if (result != null) return (bool)result; 66 | Propagate(); 67 | } 68 | 69 | return true; 70 | } 71 | 72 | public IEnumerator RunViaEnumerator(int seed, int limit, Action resultCallback, Action iterationCallback) 73 | { 74 | if (wave == null) Init(); 75 | 76 | Clear(); 77 | if (seed != 0) 78 | { 79 | random = new Random(seed); 80 | } 81 | else 82 | { 83 | random = new Random(); 84 | } 85 | 86 | 87 | for (int l = 0; l < limit || limit == 0; l++) 88 | { 89 | bool? result = Observe(); 90 | if (result != null) 91 | { 92 | resultCallback(result.Value); 93 | break; 94 | } 95 | Debug.Log("Propagate, iteration: " + l); 96 | Propagate(); 97 | iterationCallback(wave); 98 | yield return null; 99 | } 100 | } 101 | 102 | private void Init() 103 | { 104 | wave = new bool[FMX * FMY * FMZ][]; 105 | compatible = new int[wave.Length][][]; 106 | for (int i = 0; i < wave.Length; i++) 107 | { 108 | wave[i] = new bool[T]; 109 | compatible[i] = new int[T][]; 110 | for (int t = 0; t < T; t++) compatible[i][t] = new int[DIRECTIONS_AMOUNT]; 111 | } 112 | 113 | weightLogWeights = new double[T]; 114 | sumOfWeights = 0; 115 | sumOfWeightLogWeights = 0; 116 | 117 | for (int t = 0; t < T; t++) 118 | { 119 | weightLogWeights[t] = weights[t] * Math.Log(weights[t]); 120 | sumOfWeights += weights[t]; 121 | sumOfWeightLogWeights += weightLogWeights[t]; 122 | } 123 | 124 | startingEntropy = Math.Log(sumOfWeights) - sumOfWeightLogWeights / sumOfWeights; 125 | 126 | sumsOfOnes = new int[FMX * FMY * FMZ]; 127 | sumsOfWeights = new double[FMX * FMY * FMZ]; 128 | sumsOfWeightLogWeights = new double[FMX * FMY * FMZ]; 129 | entropies = new double[FMX * FMY * FMZ]; 130 | 131 | stack = new Eppy.Tuple[wave.Length * T]; 132 | stacksize = 0; 133 | } 134 | 135 | bool? Observe() 136 | { 137 | double min = 1E+3; 138 | int argmin = -1; 139 | 140 | for (int i = 0; i < wave.Length; i++) 141 | { 142 | int x, y, z; 143 | To3D(i, out x, out y, out z); 144 | if (OnBoundary(x, y, z)) continue; 145 | 146 | int amount = sumsOfOnes[i]; 147 | if (amount == 0) return false; 148 | 149 | double entropy = entropies[i]; 150 | if (amount > 1 && entropy <= min) 151 | { 152 | double noise = 1E-6 * random.NextDouble(); 153 | if (entropy + noise < min) 154 | { 155 | min = entropy + noise; 156 | argmin = i; 157 | } 158 | } 159 | } 160 | 161 | if (argmin == -1) 162 | { 163 | observed = new int[FMX * FMY * FMZ]; 164 | for (int i = 0; i < wave.Length; i++) 165 | { 166 | for (int t = 0; t < T; t++) 167 | { 168 | if (wave[i][t]) 169 | { 170 | observed[i] = t; break; 171 | } 172 | } 173 | } 174 | return true; 175 | } 176 | 177 | double[] distribution = new double[T]; 178 | for (int t = 0; t < T; t++) distribution[t] = wave[argmin][t] ? weights[t] : 0; 179 | int r = distribution.Random(random.NextDouble()); 180 | 181 | bool[] w = wave[argmin]; 182 | for (int t = 0; t < T; t++) if (w[t] != (t == r)) Ban(argmin, t); 183 | 184 | return null; 185 | } 186 | 187 | protected void Propagate() 188 | { 189 | while (stacksize > 0) 190 | { 191 | var e1 = stack[stacksize - 1]; 192 | stacksize--; 193 | 194 | int i1 = e1.Item1; 195 | int x1, y1, z1; 196 | To3D(i1, out x1, out y1, out z1); 197 | bool[] w1 = wave[i1]; 198 | 199 | for (int d = 0; d < DIRECTIONS_AMOUNT; d++) 200 | { 201 | int dx = DX[d], dy = DY[d], dz = DZ[d]; 202 | int x2 = x1 + dx, y2 = y1 + dy, z2 = z1 + dz; 203 | if (OnBoundary(x2, y2, z2)) continue; 204 | 205 | if (x2 < 0) x2 += FMX; 206 | else if (x2 >= FMX) x2 -= FMX; 207 | if (y2 < 0) y2 += FMY; 208 | else if (y2 >= FMY) y2 -= FMY; 209 | if (z2 < 0) z2 += FMY; 210 | else if (z2 >= FMZ) z2 -= FMZ; 211 | 212 | int i2 = To1D(x2, y2, z2); 213 | int[] p = propagator[d][e1.Item2]; 214 | int[][] compat = compatible[i2]; 215 | 216 | for (int l = 0; l < p.Length; l++) 217 | { 218 | int t2 = p[l]; 219 | int[] comp = compat[t2]; 220 | 221 | comp[d]--; 222 | if (comp[d] == 0) 223 | { 224 | Ban(i2, t2); 225 | } 226 | } 227 | } 228 | } 229 | } 230 | 231 | protected void Ban(int i, int t) 232 | { 233 | wave[i][t] = false; 234 | 235 | int[] comp = compatible[i][t]; 236 | for (int d = 0; d < DIRECTIONS_AMOUNT; d++) comp[d] = 0; 237 | stack[stacksize] = new Eppy.Tuple(i, t); 238 | stacksize++; 239 | 240 | double sum = sumsOfWeights[i]; 241 | entropies[i] += sumsOfWeightLogWeights[i] / sum - Math.Log(sum); 242 | 243 | sumsOfOnes[i] -= 1; 244 | sumsOfWeights[i] -= weights[t]; 245 | sumsOfWeightLogWeights[i] -= weightLogWeights[t]; 246 | 247 | sum = sumsOfWeights[i]; 248 | entropies[i] -= sumsOfWeightLogWeights[i] / sum - Math.Log(sum); 249 | } 250 | 251 | protected virtual void Clear() 252 | { 253 | for (int i = 0; i < wave.Length; i++) 254 | { 255 | for (int t = 0; t < T; t++) 256 | { 257 | wave[i][t] = true; 258 | for (int d = 0; d < DIRECTIONS_AMOUNT; d++) compatible[i][t][d] = propagator[opposite[d]][t].Length; 259 | } 260 | 261 | sumsOfOnes[i] = weights.Length; 262 | sumsOfWeights[i] = sumOfWeights; 263 | sumsOfWeightLogWeights[i] = sumOfWeightLogWeights; 264 | entropies[i] = startingEntropy; 265 | } 266 | } 267 | 268 | protected void CalculateEntropyAndPatternIdAt(int x, int y, int z, out double entropy, out int? patternId) 269 | { 270 | int indexInWave = To1D(x, y, z); 271 | int amount = 0; 272 | patternId = null; 273 | var possiblePatternsFlags = wave[indexInWave]; 274 | for (int t = 0; t < T; t++) 275 | { 276 | if (possiblePatternsFlags[t]) 277 | { 278 | amount += 1; 279 | patternId = t; 280 | } 281 | } 282 | 283 | if (amount != 1) 284 | { 285 | patternId = null; 286 | } 287 | 288 | entropy = entropies[indexInWave] / startingEntropy; 289 | } 290 | 291 | protected int To1D( int x, int y, int z ) { 292 | return z * FMX * FMY + y * FMX + x; 293 | } 294 | 295 | protected void To3D(int index, out int x, out int y, out int z) { 296 | z = index / (FMX * FMY); 297 | index -= z * FMX * FMY; 298 | y = index / FMX; 299 | x = index % FMX; 300 | } 301 | 302 | protected abstract bool OnBoundary(int x, int y, int z); 303 | 304 | public abstract CellState GetCellStateAt(int x, int y, int z); 305 | 306 | protected static int[] DX = { -1, 0, 1, 0, 0, 0 }; 307 | protected static int[] DY = { 0, 0, 0, 0, -1, 1 }; 308 | protected static int[] DZ = { 0, 1, 0, -1, 0, 0 }; 309 | static int[] opposite = { 2, 3, 0, 1, 5, 4 }; 310 | 311 | } 312 | -------------------------------------------------------------------------------- /Assets/Scripts/Core/Model/New/Model3d.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 63be51f2cabfd4dc780232789923ee2f 3 | timeCreated: 1523184993 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/Scripts/Core/Model/New/NewSimpleTiledModel.cs: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License(MIT) 3 | Copyright(c) mxgmn 2016. 4 | 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: 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 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. 7 | */ 8 | 9 | using System; 10 | using System.Linq; 11 | using System.Xml.Linq; 12 | using System.Collections.Generic; 13 | using Core.Data; 14 | using Core.Data.SimpleTiledModel; 15 | using UnityEngine; 16 | 17 | class NewSimpleTiledModel : Model2d 18 | { 19 | List tiles; 20 | List tilenames; 21 | int tilesize; 22 | bool black; 23 | 24 | public NewSimpleTiledModel(InputSimpleTiledModelData inputData, SimpleTiledModelParams modelParams) : base(modelParams) 25 | { 26 | this.periodic = modelParams.Periodic; 27 | this.black = modelParams.Black; 28 | 29 | tilesize = 1; 30 | 31 | List subset = null; 32 | /* 33 | if (subsetName != default(string)) 34 | { 35 | XElement xsubset = xroot.Element("subsets").Elements("subset").FirstOrDefault(x => x.Get("name") == subsetName); 36 | if (xsubset == null) Console.WriteLine($"ERROR: subset {subsetName} is not found"); 37 | else subset = xsubset.Elements("tile").Select(x => x.Get("name")).ToList(); 38 | } 39 | 40 | 41 | Color[] tile (Func f) 42 | { 43 | Color[] result = new Color[tilesize * tilesize]; 44 | for (int y = 0; y < tilesize; y++) 45 | for (int x = 0; x < tilesize; x++) result[x + y * tilesize] = f(x, y); 46 | return result; 47 | }; 48 | 49 | Color[] rotate(Color[] array) => tile((x, y) => array[tilesize - 1 - y + x * tilesize]); 50 | */ 51 | 52 | tiles = new List(); 53 | tilenames = new List(); 54 | var tempStationary = new List(); 55 | 56 | List action = new List(); 57 | Dictionary firstOccurrence = new Dictionary(); 58 | 59 | foreach (var tileConfig in inputData.TileConfigData.ConfigsList) 60 | { 61 | if (subset != null && !subset.Contains(tileConfig.Id)) continue; 62 | 63 | Func a, b; 64 | int cardinality; 65 | 66 | var sym = tileConfig.Symmetry; 67 | if (sym == SymmetryType.L) 68 | { 69 | cardinality = 4; 70 | a = i => (i + 1) % 4; 71 | b = i => i % 2 == 0 ? i + 1 : i - 1; 72 | } 73 | else if (sym == SymmetryType.T) 74 | { 75 | cardinality = 4; 76 | a = i => (i + 1) % 4; 77 | b = i => i % 2 == 0 ? i : 4 - i; 78 | } 79 | else if (sym == SymmetryType.I) 80 | { 81 | cardinality = 2; 82 | a = i => 1 - i; 83 | b = i => i; 84 | } 85 | else if (sym == SymmetryType.Slash) 86 | { 87 | cardinality = 2; 88 | a = i => 1 - i; 89 | b = i => 1 - i; 90 | } 91 | else 92 | { 93 | cardinality = 1; 94 | a = i => i; 95 | b = i => i; 96 | } 97 | 98 | T = action.Count; 99 | firstOccurrence.Add(tileConfig.Id, T); 100 | 101 | int[][] map = new int[cardinality][]; 102 | for (int t = 0; t < cardinality; t++) 103 | { 104 | map[t] = new int[8]; 105 | 106 | map[t][0] = t; 107 | map[t][1] = a(t); 108 | map[t][2] = a(a(t)); 109 | map[t][3] = a(a(a(t))); 110 | map[t][4] = b(t); 111 | map[t][5] = b(a(t)); 112 | map[t][6] = b(a(a(t))); 113 | map[t][7] = b(a(a(a(t)))); 114 | 115 | for (int s = 0; s < 8; s++) map[t][s] += T; 116 | 117 | action.Add(map[t]); 118 | } 119 | 120 | 121 | tiles.Add(new SimpleTiledModelTile(tileConfig, 0)); 122 | tilenames.Add(tileConfig.Id + " 0"); 123 | 124 | for (int t = 1; t < cardinality; t++) 125 | { 126 | //tiles.Add(rotate(tiles[T + t - 1])); 127 | //tilenames.Add($"{tilename} {t}"); 128 | tiles.Add(new SimpleTiledModelTile(tileConfig, t)); 129 | tilenames.Add(tileConfig.Id + " " + t); 130 | } 131 | 132 | 133 | for (int t = 0; t < cardinality; t++) 134 | { 135 | tempStationary.Add(tileConfig.Weight); 136 | } 137 | } 138 | 139 | T = action.Count; 140 | weights = tempStationary.ToArray(); 141 | 142 | propagator = new int[4][][]; 143 | var tempPropagator = new bool[4][][]; 144 | for (int d = 0; d < 4; d++) 145 | { 146 | tempPropagator[d] = new bool[T][]; 147 | propagator[d] = new int[T][]; 148 | for (int t = 0; t < T; t++) tempPropagator[d][t] = new bool[T]; 149 | } 150 | 151 | foreach (NeighborData neighborData in inputData.NeighborDatas) 152 | { 153 | var leftNeighbor = neighborData.LeftNeighborConfig.Id; 154 | var rightNeighbor = neighborData.RightNeighborConfig.Id; 155 | if (subset != null && (!subset.Contains(leftNeighbor) || !subset.Contains(rightNeighbor))) continue; 156 | 157 | int L = action[firstOccurrence[leftNeighbor]][neighborData.LeftRotation], D = action[L][1]; 158 | int R = action[firstOccurrence[rightNeighbor]][neighborData.RightRotation], U = action[R][1]; 159 | 160 | tempPropagator[0][R][L] = true; 161 | tempPropagator[0][action[R][6]][action[L][6]] = true; 162 | tempPropagator[0][action[L][4]][action[R][4]] = true; 163 | tempPropagator[0][action[L][2]][action[R][2]] = true; 164 | 165 | tempPropagator[1][U][D] = true; 166 | tempPropagator[1][action[D][6]][action[U][6]] = true; 167 | tempPropagator[1][action[U][4]][action[D][4]] = true; 168 | tempPropagator[1][action[D][2]][action[U][2]] = true; 169 | } 170 | 171 | for (int t2 = 0; t2 < T; t2++) 172 | for (int t1 = 0; t1 < T; t1++) 173 | { 174 | tempPropagator[2][t2][t1] = tempPropagator[0][t1][t2]; 175 | tempPropagator[3][t2][t1] = tempPropagator[1][t1][t2]; 176 | } 177 | 178 | List[][] sparsePropagator = new List[4][]; 179 | for (int d = 0; d < 4; d++) 180 | { 181 | sparsePropagator[d] = new List[T]; 182 | for (int t = 0; t < T; t++) 183 | { 184 | sparsePropagator[d][t] = new List(); 185 | } 186 | } 187 | 188 | for (int d = 0; d < 4; d++) 189 | { 190 | for (int t1 = 0; t1 < T; t1++) 191 | { 192 | List sp = sparsePropagator[d][t1]; 193 | bool[] tp = tempPropagator[d][t1]; 194 | 195 | for (int t2 = 0; t2 < T; t2++) 196 | { 197 | if (tp[t2]) sp.Add(t2); 198 | } 199 | 200 | int ST = sp.Count; 201 | propagator[d][t1] = new int[ST]; 202 | for (int st = 0; st < ST; st++) 203 | { 204 | propagator[d][t1][st] = sp[st]; 205 | } 206 | } 207 | } 208 | } 209 | 210 | protected override bool OnBoundary(int x, int y) 211 | { 212 | return !periodic && (x < 0 || y < 0 || x >= FMX || y >= FMY); 213 | } 214 | 215 | public override CellState GetCellStateAt(int x, int y) 216 | { 217 | bool[] a = wave[x + y * FMX]; 218 | 219 | double entropy; 220 | int? collapsedPatternId; 221 | CalculateEntropyAndPatternIdAt(x, y, out entropy, out collapsedPatternId); 222 | 223 | ITile tile = null; 224 | if (collapsedPatternId != null) 225 | { 226 | tile = tiles[collapsedPatternId.Value]; 227 | } 228 | 229 | return new CellState(entropy, tile); 230 | } 231 | 232 | /* 233 | public override Bitmap Graphics() 234 | { 235 | Bitmap result = new Bitmap(FMX * tilesize, FMY * tilesize); 236 | int[] bitmapData = new int[result.Height * result.Width]; 237 | 238 | if (observed != null) 239 | { 240 | for (int x = 0; x < FMX; x++) for (int y = 0; y < FMY; y++) 241 | { 242 | Color[] tile = tiles[observed[x + y * FMX]]; 243 | for (int yt = 0; yt < tilesize; yt++) for (int xt = 0; xt < tilesize; xt++) 244 | { 245 | Color c = tile[xt + yt * tilesize]; 246 | bitmapData[x * tilesize + xt + (y * tilesize + yt) * FMX * tilesize] = 247 | unchecked((int)0xff000000 | (c.R << 16) | (c.G << 8) | c.B); 248 | } 249 | } 250 | } 251 | else 252 | { 253 | for (int x = 0; x < FMX; x++) for (int y = 0; y < FMY; y++) 254 | { 255 | bool[] a = wave[x + y * FMX]; 256 | int amount = (from b in a where b select 1).Sum(); 257 | double lambda = 1.0 / (from t in Enumerable.Range(0, T) where a[t] select weights[t]).Sum(); 258 | 259 | for (int yt = 0; yt < tilesize; yt++) for (int xt = 0; xt < tilesize; xt++) 260 | { 261 | if (black && amount == T) bitmapData[x * tilesize + xt + (y * tilesize + yt) * FMX * tilesize] = unchecked((int)0xff000000); 262 | else 263 | { 264 | double r = 0, g = 0, b = 0; 265 | for (int t = 0; t < T; t++) if (wave[x + y * FMX][t]) 266 | { 267 | Color c = tiles[t][xt + yt * tilesize]; 268 | r += (double)c.R * weights[t] * lambda; 269 | g += (double)c.G * weights[t] * lambda; 270 | b += (double)c.B * weights[t] * lambda; 271 | } 272 | 273 | bitmapData[x * tilesize + xt + (y * tilesize + yt) * FMX * tilesize] = 274 | unchecked((int)0xff000000 | ((int)r << 16) | ((int)g << 8) | (int)b); 275 | } 276 | } 277 | } 278 | } 279 | 280 | var bits = result.LockBits(new Rectangle(0, 0, result.Width, result.Height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb); 281 | System.Runtime.InteropServices.Marshal.Copy(bitmapData, 0, bits.Scan0, bitmapData.Length); 282 | result.UnlockBits(bits); 283 | 284 | return result; 285 | } 286 | 287 | 288 | public string TextOutput() 289 | { 290 | var result = new System.Text.StringBuilder(); 291 | 292 | for (int y = 0; y < FMY; y++) 293 | { 294 | for (int x = 0; x < FMX; x++) result.Append($"{tilenames[observed[x + y * FMX]]}, "); 295 | result.Append(Environment.NewLine); 296 | } 297 | 298 | return result.ToString(); 299 | } 300 | */ 301 | } 302 | -------------------------------------------------------------------------------- /Assets/Scripts/Core/Model/New/NewSimpleTiledModel.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 0761d770da1d949fe8c5edee79b1d42e 3 | timeCreated: 1523142111 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/Scripts/Core/Model/New/OvelappingModel2dWrapper.cs: -------------------------------------------------------------------------------- 1 | using Core.Data; 2 | using Core.Data.OverlappingModel; 3 | 4 | namespace Core.Model.New 5 | { 6 | public class OvelappingModel2dWrapper : IModel3d 7 | { 8 | public OverlappingModel2d Model { get; private set; } 9 | public WaveFunctionCollapseModelParams ModelParam { get; private set; } 10 | 11 | public OvelappingModel2dWrapper(InputOverlappingData inputData, OverlappingModelParams modelParam) 12 | { 13 | ModelParam = modelParam; 14 | Model = new OverlappingModel2d(inputData, modelParam); 15 | } 16 | 17 | public CellState GetCellStateAt(int x, int y, int z) 18 | { 19 | return Model.GetCellStateAt(x, z); 20 | } 21 | 22 | } 23 | } -------------------------------------------------------------------------------- /Assets/Scripts/Core/Model/New/OvelappingModel2dWrapper.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d6e6f585ae654107a417547037d4ba8b 3 | timeCreated: 1523209687 -------------------------------------------------------------------------------- /Assets/Scripts/Core/Model/New/OverlappingModel2d.cs: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License(MIT) 3 | Copyright(c) mxgmn 2016. 4 | 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: 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 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. 7 | */ 8 | 9 | using System; 10 | using System.Collections.Generic; 11 | using Core.Data; 12 | using Core.Data.OverlappingModel; 13 | 14 | namespace Core.Model.New 15 | { 16 | public class OverlappingModel2d : Model2d 17 | { 18 | int N; 19 | byte[][] patterns; 20 | int ground; 21 | 22 | public InputOverlappingData InputData { get; private set; } 23 | 24 | public OverlappingModel2d(InputOverlappingData inputData, OverlappingModelParams modelParams) 25 | : base(modelParams) 26 | { 27 | InputData = inputData; 28 | 29 | N = modelParams.PatternSize; 30 | periodic = modelParams.PeriodicInput; 31 | bool periodicInput = modelParams.PeriodicInput; 32 | int symmetry = modelParams.Symmetry; 33 | int ground = modelParams.Ground; 34 | 35 | int SMX = inputData.Width, SMY = inputData.Depth; 36 | 37 | var sample = inputData.GetSampleMatrix(); 38 | 39 | int C = inputData.TilesSortedByIds.Count; 40 | long W = ModelHelper.Power(C, N * N); 41 | 42 | Func, byte[]> pattern = (f) => 43 | { 44 | byte[] result = new byte[N * N]; 45 | for (int y = 0; y < N; y++) 46 | { 47 | for (int x = 0; x < N; x++) 48 | { 49 | result[x + y * N] = f(x, y); 50 | } 51 | } 52 | 53 | return result; 54 | }; 55 | 56 | Func patternFromSample = (x, y) => 57 | { 58 | return pattern((dx, dy) => sample[(x + dx) % SMX, (y + dy) % SMY]); 59 | }; 60 | Func rotate = (p) => 61 | { 62 | return pattern((x, y) => p[N - 1 - y + x * N]); 63 | }; 64 | Func reflect = (p) => 65 | { 66 | return pattern((x, y) => p[N - 1 - x + y * N]); 67 | }; 68 | 69 | Func GenerateUniqueIndex = p => 70 | { 71 | long result = 0, power = 1; 72 | for (int i = 0; i < p.Length; i++) 73 | { 74 | result += p[p.Length - 1 - i] * power; 75 | power *= C; 76 | } 77 | 78 | return result; 79 | }; 80 | 81 | Func patternFromIndex = ind => 82 | { 83 | long residue = ind, power = W; 84 | byte[] result = new byte[N * N]; 85 | 86 | for (int i = 0; i < result.Length; i++) 87 | { 88 | power /= C; 89 | int count = 0; 90 | 91 | while (residue >= power) 92 | { 93 | residue -= power; 94 | count++; 95 | } 96 | 97 | result[i] = (byte) count; 98 | } 99 | 100 | return result; 101 | }; 102 | 103 | Dictionary weights = new Dictionary(); 104 | List ordering = new List(); 105 | 106 | for (int y = 0; y < (periodicInput ? SMY : SMY - N + 1); y++) 107 | for (int x = 0; x < (periodicInput ? SMX : SMX - N + 1); x++) 108 | { 109 | byte[][] ps = new byte[8][]; 110 | 111 | ps[0] = patternFromSample(x, y); 112 | ps[1] = reflect(ps[0]); 113 | ps[2] = rotate(ps[0]); 114 | ps[3] = reflect(ps[2]); 115 | ps[4] = rotate(ps[2]); 116 | ps[5] = reflect(ps[4]); 117 | ps[6] = rotate(ps[4]); 118 | ps[7] = reflect(ps[6]); 119 | 120 | for (int k = 0; k < symmetry; k++) 121 | { 122 | long ind = GenerateUniqueIndex(ps[k]); 123 | if (weights.ContainsKey(ind)) weights[ind]++; 124 | else 125 | { 126 | weights.Add(ind, 1); 127 | ordering.Add(ind); 128 | } 129 | } 130 | } 131 | 132 | T = weights.Count; 133 | this.ground = (ground + T) % T; 134 | patterns = new byte[T][]; 135 | base.weights = new double[T]; 136 | 137 | int counter = 0; 138 | foreach (long w in ordering) 139 | { 140 | patterns[counter] = patternFromIndex(w); 141 | base.weights[counter] = weights[w]; 142 | counter++; 143 | } 144 | 145 | propagator = new int[4][][]; 146 | for (int d = 0; d < 4; d++) 147 | { 148 | propagator[d] = new int[T][]; 149 | for (int t = 0; t < T; t++) 150 | { 151 | List list = new List(); 152 | for (int t2 = 0; t2 < T; t2++) if (Agrees(patterns[t], patterns[t2], DX[d], DY[d])) list.Add(t2); 153 | propagator[d][t] = new int[list.Count]; 154 | for (int c = 0; c < list.Count; c++) propagator[d][t][c] = list[c]; 155 | } 156 | } 157 | } 158 | 159 | protected override bool OnBoundary(int x, int y) 160 | { 161 | return !periodic && (x + N > FMX || y + N > FMY || x < 0 || y < 0); 162 | } 163 | 164 | public override CellState GetCellStateAt(int x, int y) 165 | { 166 | int dy = y < FMY - N + 1 ? 0 : N - 1; 167 | int dx = x < FMX - N + 1 ? 0 : N - 1; 168 | 169 | int? collapsedPatternId; 170 | double entropy; 171 | CalculateEntropyAndPatternIdAt(x - dx, y - dy, out entropy, out collapsedPatternId); 172 | 173 | ITile tile = null; 174 | if (collapsedPatternId != null) 175 | { 176 | tile = InputData.GetTileById(patterns[collapsedPatternId.Value][dx + dy * N]); 177 | } 178 | 179 | return new CellState(entropy, tile); 180 | } 181 | 182 | private bool Agrees(byte[] p1, byte[] p2, int dx, int dy) 183 | { 184 | int xmin = dx < 0 ? 0 : dx; 185 | int xmax = dx < 0 ? dx + N : N; 186 | int ymin = dy < 0 ? 0 : dy; 187 | int ymax = dy < 0 ? dy + N : N; 188 | 189 | for (int y = ymin; y < ymax; y++) 190 | for (int x = xmin; x < xmax; x++) 191 | { 192 | if (p1[x + N * y] != p2[x - dx + N * (y - dy)]) return false; 193 | } 194 | return true; 195 | } 196 | 197 | /* 198 | public override Bitmap Graphics() 199 | { 200 | Bitmap result = new Bitmap(FMX, FMY); 201 | int[] bitmapData = new int[result.Height * result.Width]; 202 | 203 | if (observed != null) 204 | { 205 | for (int y = 0; y < FMY; y++) 206 | { 207 | int dy = y < FMY - N + 1 ? 0 : N - 1; 208 | for (int x = 0; x < FMX; x++) 209 | { 210 | int dx = x < FMX - N + 1 ? 0 : N - 1; 211 | Color c = colors[patterns[observed[x - dx + (y - dy) * FMX]][dx + dy * N]]; 212 | bitmapData[x + y * FMX] = unchecked((int)0xff000000 | (c.R << 16) | (c.G << 8) | c.B); 213 | } 214 | } 215 | } 216 | else 217 | { 218 | for (int i = 0; i < wave.Length; i++) 219 | { 220 | int contributors = 0, r = 0, g = 0, b = 0; 221 | int x = i % FMX, y = i / FMX; 222 | 223 | for (int dy = 0; dy < N; dy++) for (int dx = 0; dx < N; dx++) 224 | { 225 | int sx = x - dx; 226 | if (sx < 0) sx += FMX; 227 | 228 | int sy = y - dy; 229 | if (sy < 0) sy += FMY; 230 | 231 | int s = sx + sy * FMX; 232 | if (OnBoundary(sx, sy)) continue; 233 | for (int t = 0; t < T; t++) if (wave[s][t]) 234 | { 235 | contributors++; 236 | Color color = colors[patterns[t][dx + dy * N]]; 237 | r += color.R; 238 | g += color.G; 239 | b += color.B; 240 | } 241 | } 242 | 243 | bitmapData[i] = unchecked((int)0xff000000 | ((r / contributors) << 16) | ((g / contributors) << 8) | b / contributors); 244 | } 245 | } 246 | 247 | var bits = result.LockBits(new Rectangle(0, 0, result.Width, result.Height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb); 248 | System.Runtime.InteropServices.Marshal.Copy(bitmapData, 0, bits.Scan0, bitmapData.Length); 249 | result.UnlockBits(bits); 250 | 251 | return result; 252 | } 253 | */ 254 | 255 | protected override void Clear() 256 | { 257 | base.Clear(); 258 | 259 | if (ground != 0) 260 | { 261 | for (int x = 0; x < FMX; x++) 262 | { 263 | for (int t = 0; t < T; t++) if (t != ground) Ban(x + (FMY - 1) * FMX, t); 264 | for (int y = 0; y < FMY - 1; y++) Ban(x + y * FMX, ground); 265 | } 266 | 267 | Propagate(); 268 | } 269 | } 270 | } 271 | } 272 | -------------------------------------------------------------------------------- /Assets/Scripts/Core/Model/New/OverlappingModel2d.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 54069f257c6794abe930e87d65a36bec 3 | timeCreated: 1523142111 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/Scripts/Core/Model/New/SimpleTiledMode3d.cs: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License(MIT) 3 | Copyright(c) mxgmn 2016. 4 | 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: 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 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. 7 | */ 8 | 9 | using System; 10 | using System.Linq; 11 | using System.Xml.Linq; 12 | using System.Collections.Generic; 13 | using Core.Data; 14 | using Core.Data.SimpleTiledModel; 15 | using UnityEngine; 16 | 17 | public class SimpleTiledMode3d : Model3d 18 | { 19 | List tiles; 20 | List tilenames; 21 | int tilesize; 22 | bool black; 23 | 24 | public SimpleTiledMode3d(InputSimpleTiledModelData inputData, SimpleTiledModelParams modelParams) : base(modelParams) 25 | { 26 | this.periodic = modelParams.Periodic; 27 | this.black = modelParams.Black; 28 | 29 | tilesize = 1; 30 | 31 | List subset = null; 32 | 33 | tiles = new List(); 34 | tilenames = new List(); 35 | var tempStationary = new List(); 36 | 37 | List action = new List(); 38 | Dictionary firstOccurrence = new Dictionary(); 39 | 40 | foreach (var tileConfig in inputData.TileConfigData.ConfigsList) 41 | { 42 | if (subset != null && !subset.Contains(tileConfig.Id)) continue; 43 | 44 | Func a, b; 45 | int cardinality; 46 | 47 | var sym = tileConfig.Symmetry; 48 | if (sym == SymmetryType.L) 49 | { 50 | cardinality = 4; 51 | a = i => (i + 1) % 4; 52 | b = i => i % 2 == 0 ? i + 1 : i - 1; 53 | } 54 | else if (sym == SymmetryType.T) 55 | { 56 | cardinality = 4; 57 | a = i => (i + 1) % 4; 58 | b = i => i % 2 == 0 ? i : 4 - i; 59 | } 60 | else if (sym == SymmetryType.I) 61 | { 62 | cardinality = 2; 63 | a = i => 1 - i; 64 | b = i => i; 65 | } 66 | else if (sym == SymmetryType.Slash) 67 | { 68 | cardinality = 2; 69 | a = i => 1 - i; 70 | b = i => 1 - i; 71 | } 72 | else 73 | { 74 | cardinality = 1; 75 | a = i => i; 76 | b = i => i; 77 | } 78 | 79 | T = action.Count; 80 | firstOccurrence.Add(tileConfig.Id, T); 81 | 82 | int[][] map = new int[cardinality][]; 83 | for (int t = 0; t < cardinality; t++) 84 | { 85 | map[t] = new int[8]; 86 | 87 | map[t][0] = t; 88 | map[t][1] = a(t); 89 | map[t][2] = a(a(t)); 90 | map[t][3] = a(a(a(t))); 91 | map[t][4] = b(t); 92 | map[t][5] = b(a(t)); 93 | map[t][6] = b(a(a(t))); 94 | map[t][7] = b(a(a(a(t)))); 95 | 96 | for (int s = 0; s < 8; s++) map[t][s] += T; 97 | 98 | action.Add(map[t]); 99 | } 100 | 101 | 102 | tiles.Add(new SimpleTiledModelTile(tileConfig, 0)); 103 | tilenames.Add(tileConfig.Id + " 0"); 104 | 105 | for (int t = 1; t < cardinality; t++) 106 | { 107 | //tiles.Add(rotate(tiles[T + t - 1])); 108 | //tilenames.Add($"{tilename} {t}"); 109 | tiles.Add(new SimpleTiledModelTile(tileConfig, t)); 110 | tilenames.Add(tileConfig.Id + " " + t); 111 | } 112 | 113 | 114 | for (int t = 0; t < cardinality; t++) 115 | { 116 | tempStationary.Add(tileConfig.Weight); 117 | } 118 | } 119 | 120 | T = action.Count; 121 | weights = tempStationary.ToArray(); 122 | 123 | propagator = new int[DIRECTIONS_AMOUNT][][]; 124 | var tempPropagator = new bool[DIRECTIONS_AMOUNT][][]; 125 | for (int d = 0; d < DIRECTIONS_AMOUNT; d++) 126 | { 127 | tempPropagator[d] = new bool[T][]; 128 | propagator[d] = new int[T][]; 129 | for (int t = 0; t < T; t++) 130 | { 131 | tempPropagator[d][t] = new bool[T]; 132 | } 133 | } 134 | 135 | foreach (NeighborData neighborData in inputData.NeighborDatas) 136 | { 137 | var leftNeighbor = neighborData.LeftNeighborConfig.Id; 138 | var rightNeighbor = neighborData.RightNeighborConfig.Id; 139 | if (subset != null && (!subset.Contains(leftNeighbor) || !subset.Contains(rightNeighbor))) continue; 140 | 141 | int L = action[firstOccurrence[leftNeighbor]][neighborData.LeftRotation], D = action[L][1]; 142 | int R = action[firstOccurrence[rightNeighbor]][neighborData.RightRotation], U = action[R][1]; 143 | 144 | if (neighborData.Horizontal) 145 | { 146 | tempPropagator[0][R][L] = true; 147 | tempPropagator[0][action[R][6]][action[L][6]] = true; 148 | tempPropagator[0][action[L][4]][action[R][4]] = true; 149 | tempPropagator[0][action[L][2]][action[R][2]] = true; 150 | 151 | tempPropagator[1][U][D] = true; 152 | tempPropagator[1][action[D][6]][action[U][6]] = true; 153 | tempPropagator[1][action[U][4]][action[D][4]] = true; 154 | tempPropagator[1][action[D][2]][action[U][2]] = true; 155 | } 156 | else 157 | { 158 | // for vertical neighbours 159 | for (int g = 0; g < 8; g++) 160 | { 161 | tempPropagator[4][action[L][g]][action[R][g]] = true; 162 | } 163 | } 164 | } 165 | 166 | for (int t2 = 0; t2 < T; t2++) 167 | for (int t1 = 0; t1 < T; t1++) 168 | { 169 | tempPropagator[2][t2][t1] = tempPropagator[0][t1][t2]; 170 | tempPropagator[3][t2][t1] = tempPropagator[1][t1][t2]; 171 | tempPropagator[5][t2][t1] = tempPropagator[4][t1][t2]; 172 | } 173 | 174 | List[][] sparsePropagator = new List[DIRECTIONS_AMOUNT][]; 175 | for (int d = 0; d < DIRECTIONS_AMOUNT; d++) 176 | { 177 | sparsePropagator[d] = new List[T]; 178 | for (int t = 0; t < T; t++) 179 | { 180 | sparsePropagator[d][t] = new List(); 181 | } 182 | } 183 | 184 | for (int d = 0; d < DIRECTIONS_AMOUNT; d++) 185 | { 186 | for (int t1 = 0; t1 < T; t1++) 187 | { 188 | List sp = sparsePropagator[d][t1]; 189 | bool[] tp = tempPropagator[d][t1]; 190 | 191 | for (int t2 = 0; t2 < T; t2++) 192 | { 193 | if (tp[t2]) sp.Add(t2); 194 | } 195 | 196 | int ST = sp.Count; 197 | propagator[d][t1] = new int[ST]; 198 | for (int st = 0; st < ST; st++) 199 | { 200 | propagator[d][t1][st] = sp[st]; 201 | } 202 | } 203 | } 204 | } 205 | 206 | protected override bool OnBoundary(int x, int y, int z) 207 | { 208 | return !periodic && (x < 0 || y < 0 || z < 0 || x >= FMX || y >= FMY || z >= FMZ); 209 | } 210 | 211 | public override CellState GetCellStateAt(int x, int y, int z) 212 | { 213 | bool[] a = wave[To1D(x,y,z)]; 214 | 215 | double entropy; 216 | int? collapsedPatternId; 217 | CalculateEntropyAndPatternIdAt(x, y, z, out entropy, out collapsedPatternId); 218 | 219 | ITile tile = null; 220 | if (collapsedPatternId != null) 221 | { 222 | tile = tiles[collapsedPatternId.Value]; 223 | } 224 | 225 | return new CellState(entropy, tile); 226 | } 227 | 228 | /* 229 | public override Bitmap Graphics() 230 | { 231 | Bitmap result = new Bitmap(FMX * tilesize, FMY * tilesize); 232 | int[] bitmapData = new int[result.Height * result.Width]; 233 | 234 | if (observed != null) 235 | { 236 | for (int x = 0; x < FMX; x++) for (int y = 0; y < FMY; y++) 237 | { 238 | Color[] tile = tiles[observed[x + y * FMX]]; 239 | for (int yt = 0; yt < tilesize; yt++) for (int xt = 0; xt < tilesize; xt++) 240 | { 241 | Color c = tile[xt + yt * tilesize]; 242 | bitmapData[x * tilesize + xt + (y * tilesize + yt) * FMX * tilesize] = 243 | unchecked((int)0xff000000 | (c.R << 16) | (c.G << 8) | c.B); 244 | } 245 | } 246 | } 247 | else 248 | { 249 | for (int x = 0; x < FMX; x++) for (int y = 0; y < FMY; y++) 250 | { 251 | bool[] a = wave[x + y * FMX]; 252 | int amount = (from b in a where b select 1).Sum(); 253 | double lambda = 1.0 / (from t in Enumerable.Range(0, T) where a[t] select weights[t]).Sum(); 254 | 255 | for (int yt = 0; yt < tilesize; yt++) for (int xt = 0; xt < tilesize; xt++) 256 | { 257 | if (black && amount == T) bitmapData[x * tilesize + xt + (y * tilesize + yt) * FMX * tilesize] = unchecked((int)0xff000000); 258 | else 259 | { 260 | double r = 0, g = 0, b = 0; 261 | for (int t = 0; t < T; t++) if (wave[x + y * FMX][t]) 262 | { 263 | Color c = tiles[t][xt + yt * tilesize]; 264 | r += (double)c.R * weights[t] * lambda; 265 | g += (double)c.G * weights[t] * lambda; 266 | b += (double)c.B * weights[t] * lambda; 267 | } 268 | 269 | bitmapData[x * tilesize + xt + (y * tilesize + yt) * FMX * tilesize] = 270 | unchecked((int)0xff000000 | ((int)r << 16) | ((int)g << 8) | (int)b); 271 | } 272 | } 273 | } 274 | } 275 | 276 | var bits = result.LockBits(new Rectangle(0, 0, result.Width, result.Height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb); 277 | System.Runtime.InteropServices.Marshal.Copy(bitmapData, 0, bits.Scan0, bitmapData.Length); 278 | result.UnlockBits(bits); 279 | 280 | return result; 281 | } 282 | 283 | 284 | public string TextOutput() 285 | { 286 | var result = new System.Text.StringBuilder(); 287 | 288 | for (int y = 0; y < FMY; y++) 289 | { 290 | for (int x = 0; x < FMX; x++) result.Append($"{tilenames[observed[x + y * FMX]]}, "); 291 | result.Append(Environment.NewLine); 292 | } 293 | 294 | return result.ToString(); 295 | } 296 | */ 297 | } 298 | -------------------------------------------------------------------------------- /Assets/Scripts/Core/Model/New/SimpleTiledMode3d.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 790fa6d12fc9d48c1b9ecd41c41186d5 3 | timeCreated: 1523184993 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/Scripts/Core/Model/OverlappingModel.cs: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License(MIT) 3 | Copyright(c) mxgmn 2016. 4 | 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: 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 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. 7 | */ 8 | 9 | using System; 10 | using System.Collections.Generic; 11 | using Core.Data; 12 | using Core.Data.OverlappingModel; 13 | 14 | namespace Core.Model 15 | { 16 | public class OverlappingModel : Model 17 | { 18 | int[][][][] propagator; 19 | int N; 20 | 21 | byte[][] patterns; 22 | int ground; 23 | 24 | public OverlappingModel(InputOverlappingData inputData, OverlappingModelParams modelParams) 25 | : base(modelParams) 26 | { 27 | InputData = inputData; 28 | N = modelParams.PatternSize; 29 | 30 | bool periodicInput = modelParams.PeriodicInput; 31 | int symmetry = modelParams.Symmetry; 32 | int ground = modelParams.Ground; 33 | 34 | periodic = modelParams.PeriodicOutput; 35 | 36 | int SMX = inputData.Width, SMY = inputData.Depth; 37 | 38 | var sample = inputData.GetSampleMatrix(); 39 | 40 | int C = inputData.TilesSortedByIds.Count; 41 | long W = ModelHelper.Power(C, N * N); 42 | 43 | Func, byte[]> pattern = (f) => 44 | { 45 | byte[] result = new byte[N * N]; 46 | for (int y = 0; y < N; y++) 47 | { 48 | for (int x = 0; x < N; x++) 49 | { 50 | result[x + y * N] = f(x, y); 51 | } 52 | } 53 | 54 | return result; 55 | }; 56 | 57 | Func patternFromSample = (x, y) => 58 | { 59 | return pattern((dx, dy) => sample[(x + dx) % SMX, (y + dy) % SMY]); 60 | }; 61 | Func rotate = (p) => 62 | { 63 | return pattern((x, y) => p[N - 1 - y + x * N]); 64 | }; 65 | Func reflect = (p) => 66 | { 67 | return pattern((x, y) => p[N - 1 - x + y * N]); 68 | }; 69 | 70 | Func GenerateUniqueIndex = p => 71 | { 72 | long result = 0, power = 1; 73 | for (int i = 0; i < p.Length; i++) 74 | { 75 | result += p[p.Length - 1 - i] * power; 76 | power *= C; 77 | } 78 | 79 | return result; 80 | }; 81 | 82 | Func patternFromIndex = ind => 83 | { 84 | long residue = ind, power = W; 85 | byte[] result = new byte[N * N]; 86 | 87 | for (int i = 0; i < result.Length; i++) 88 | { 89 | power /= C; 90 | int count = 0; 91 | 92 | while (residue >= power) 93 | { 94 | residue -= power; 95 | count++; 96 | } 97 | 98 | result[i] = (byte) count; 99 | } 100 | 101 | return result; 102 | }; 103 | 104 | Dictionary weights = new Dictionary(); 105 | List ordering = new List(); 106 | 107 | for (int y = 0; y < (periodicInput ? SMY : SMY - N + 1); y++) 108 | for (int x = 0; x < (periodicInput ? SMX : SMX - N + 1); x++) 109 | { 110 | byte[][] ps = new byte[8][]; 111 | 112 | ps[0] = patternFromSample(x, y); 113 | ps[1] = reflect(ps[0]); 114 | ps[2] = rotate(ps[0]); 115 | ps[3] = reflect(ps[2]); 116 | ps[4] = rotate(ps[2]); 117 | ps[5] = reflect(ps[4]); 118 | ps[6] = rotate(ps[4]); 119 | ps[7] = reflect(ps[6]); 120 | 121 | for (int k = 0; k < symmetry; k++) 122 | { 123 | long ind = GenerateUniqueIndex(ps[k]); 124 | if (weights.ContainsKey(ind)) weights[ind]++; 125 | else 126 | { 127 | weights.Add(ind, 1); 128 | ordering.Add(ind); 129 | } 130 | } 131 | } 132 | 133 | T = weights.Count; 134 | this.ground = (ground + T) % T; 135 | 136 | patterns = new byte[T][]; 137 | stationary = new double[T]; 138 | propagator = new int[2 * N - 1][][][]; 139 | 140 | int counter = 0; 141 | foreach (long w in ordering) 142 | { 143 | patterns[counter] = patternFromIndex(w); 144 | stationary[counter] = weights[w]; 145 | counter++; 146 | } 147 | 148 | InitWave(); 149 | 150 | Func agrees = (p1, p2, dx, dy) => 151 | { 152 | int xmin = dx < 0 ? 0 : dx, xmax = dx < 0 ? dx + N : N, ymin = dy < 0 ? 0 : dy, ymax = dy < 0 ? dy + N : N; 153 | for (int y = ymin; y < ymax; y++) 154 | for (int x = xmin; x < xmax; x++) 155 | if (p1[x + N * y] != p2[x - dx + N * (y - dy)]) 156 | return false; 157 | return true; 158 | }; 159 | 160 | for (int x = 0; x < 2 * N - 1; x++) 161 | { 162 | propagator[x] = new int[2 * N - 1][][]; 163 | for (int y = 0; y < 2 * N - 1; y++) 164 | { 165 | propagator[x][y] = new int[T][]; 166 | for (int t = 0; t < T; t++) 167 | { 168 | List list = new List(); 169 | for (int t2 = 0; t2 < T; t2++) 170 | { 171 | if (agrees(patterns[t], patterns[t2], x - N + 1, y - N + 1)) 172 | list.Add(t2); 173 | } 174 | 175 | propagator[x][y][t] = new int[list.Count]; 176 | for (int c = 0; c < list.Count; c++) 177 | { 178 | propagator[x][y][t][c] = list[c]; 179 | } 180 | } 181 | } 182 | } 183 | } 184 | 185 | public InputOverlappingData InputData { get; private set; } 186 | 187 | public override bool OnBoundary(int i) 188 | { 189 | return !periodic && (i % FMX + N > FMX || i / FMX + N > FMY); 190 | } 191 | 192 | protected override void Propagate() 193 | { 194 | while (stacksize > 0) 195 | { 196 | int i1 = stack[stacksize - 1]; 197 | stacksize--; 198 | changes[i1] = false; 199 | 200 | bool[] w1 = wave[i1]; 201 | int x1 = i1 % FMX, y1 = i1 / FMX; 202 | 203 | //reduce entropy in surrounding cells on pattern distance 204 | for (int dx = -N + 1; dx < N; dx++) 205 | for (int dy = -N + 1; dy < N; dy++) 206 | { 207 | int x2 = x1 + dx; 208 | if (x2 < 0) x2 += FMX; 209 | else if (x2 >= FMX) x2 -= FMX; 210 | 211 | int y2 = y1 + dy; 212 | if (y2 < 0) y2 += FMY; 213 | else if (y2 >= FMY) y2 -= FMY; 214 | 215 | if (!periodic && (x2 + N > FMX || y2 + N > FMY)) continue; 216 | 217 | int i2 = x2 + y2 * FMX; 218 | bool[] w2 = wave[i2]; 219 | int[][] prop = propagator[N - 1 - dx][N - 1 - dy]; 220 | 221 | for (int t2 = 0; t2 < T; t2++) 222 | if (w2[t2]) 223 | { 224 | bool b = false; 225 | int[] p = prop[t2]; 226 | for (int l = 0; l < p.Length && !b; l++) 227 | { 228 | b = w1[p[l]]; 229 | } 230 | 231 | if (!b) 232 | { 233 | Change(i2); 234 | w2[t2] = false; 235 | } 236 | } 237 | } 238 | } 239 | } 240 | 241 | public override CellState GetCellStateAt(int x, int y) 242 | { 243 | int dy = y < FMY - N + 1 ? 0 : N - 1; 244 | int dx = x < FMX - N + 1 ? 0 : N - 1; 245 | 246 | int? collapsedPatternId; 247 | float entropy; 248 | CalculateEntropyAndPatternIdAt(x - dx, y - dy, out entropy, out collapsedPatternId); 249 | 250 | ITile tile = null; 251 | if (collapsedPatternId != null) 252 | { 253 | tile = InputData.GetTileById(patterns[collapsedPatternId.Value][dx + dy * N]); 254 | } 255 | 256 | return new CellState(entropy, tile); 257 | } 258 | 259 | /* 260 | public override Bitmap Graphics() 261 | { 262 | Bitmap result = new Bitmap(FMX, FMY); 263 | int[] bitmapData = new int[result.Height * result.Width]; 264 | 265 | if (observed != null) 266 | { 267 | for (int y = 0; y < FMY; y++) 268 | { 269 | int dy = y < FMY - N + 1 ? 0 : N - 1; 270 | for (int x = 0; x < FMX; x++) 271 | { 272 | int dx = x < FMX - N + 1 ? 0 : N - 1; 273 | Color c = tilesConfigs[patterns[observed[x - dx + (y - dy) * FMX]][dx + dy * N]]; 274 | bitmapData[x + y * FMX] = unchecked((int)0xff000000 | (c.R << 16) | (c.G << 8) | c.B); 275 | } 276 | } 277 | } 278 | else 279 | { 280 | for (int i = 0; i < wave.Length; i++) 281 | { 282 | int contributors = 0, r = 0, g = 0, b = 0; 283 | int x = i % FMX, y = i / FMX; 284 | 285 | for (int dy = 0; dy < N; dy++) for (int dx = 0; dx < N; dx++) 286 | { 287 | int sx = x - dx; 288 | if (sx < 0) sx += FMX; 289 | 290 | int sy = y - dy; 291 | if (sy < 0) sy += FMY; 292 | 293 | int s = sx + sy * FMX; 294 | if (OnBoundary(s)) continue; 295 | for (int t = 0; t < T; t++) if (wave[s][t]) 296 | { 297 | contributors++; 298 | Color color = tilesConfigs[patterns[t][dx + dy * N]]; 299 | r += color.R; 300 | g += color.G; 301 | b += color.B; 302 | } 303 | } 304 | 305 | bitmapData[i] = unchecked((int)0xff000000 | ((r / contributors) << 16) | ((g / contributors) << 8) | b / contributors); 306 | } 307 | } 308 | 309 | var bits = result.LockBits(new Rectangle(0, 0, result.Width, result.Height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb); 310 | System.Runtime.InteropServices.Marshal.Copy(bitmapData, 0, bits.Scan0, bitmapData.Length); 311 | result.UnlockBits(bits); 312 | 313 | return result; 314 | } 315 | */ 316 | 317 | protected override void Clear() 318 | { 319 | base.Clear(); 320 | 321 | if (ground != 0) 322 | { 323 | for (int x = 0; x < FMX; x++) 324 | { 325 | for (int t = 0; t < T; t++) 326 | if (t != ground) 327 | wave[x + (FMY - 1) * FMX][t] = false; 328 | Change(x + (FMY - 1) * FMX); 329 | 330 | for (int y = 0; y < FMY - 1; y++) 331 | { 332 | wave[x + y * FMX][ground] = false; 333 | Change(x + y * FMX); 334 | } 335 | } 336 | 337 | Propagate(); 338 | } 339 | } 340 | } 341 | } 342 | -------------------------------------------------------------------------------- /Assets/Scripts/Core/Model/OverlappingModel.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 3279da2e3a74c4138a5722de9b63f06f 3 | timeCreated: 1520355919 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/Scripts/Core/Model/SimpleTiledModel.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 654f69ec91a0d42828c2d15b50a76351 3 | timeCreated: 1520355919 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/Scripts/Core/TilePainter.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ebb1a6bd3e47b419a9b1fc3765f3c6bf 3 | timeCreated: 1523220424 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/Scripts/Core/UncollapsedTileView.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using UnityEngine; 3 | 4 | namespace Core 5 | { 6 | public class UncollapsedTileView : MonoBehaviour 7 | { 8 | [SerializeField] 9 | private Transform sphere; 10 | 11 | public void UpdateState(double entropyLevel) 12 | { 13 | float entropy = (float)entropyLevel; 14 | if (entropy > 0) 15 | { 16 | sphere.gameObject.SetActive(true); 17 | sphere.localScale = new Vector3(entropy, entropy, entropy); 18 | } 19 | else 20 | { 21 | sphere.gameObject.SetActive(false); 22 | } 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /Assets/Scripts/Core/UncollapsedTileView.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f4807aee4e0241ff872a48fe4c283d44 3 | timeCreated: 1522091502 -------------------------------------------------------------------------------- /Assets/Scripts/Core/WaveFunctionCollapseGenerator.cs: -------------------------------------------------------------------------------- 1 | using Core.Data; 2 | using Core.Data.OverlappingModel; 3 | using Core.Data.SimpleTiledModel; 4 | using Core.InputProviders; 5 | using Core.Model; 6 | using Core.Model.New; 7 | using UnityEditor; 8 | using UnityEngine; 9 | 10 | namespace Core 11 | { 12 | public class WaveFunctionCollapseGenerator : MonoBehaviour 13 | { 14 | [SerializeField] 15 | private InputDataProvider dataProvider; 16 | 17 | [SerializeField] 18 | private WaveFunctionCollapseRenderer renderer; 19 | 20 | [SerializeField] 21 | private int width; 22 | 23 | [SerializeField] 24 | private int height; 25 | 26 | [SerializeField] 27 | private int depth; 28 | 29 | [SerializeField] 30 | private int patternSize; 31 | 32 | [SerializeField] 33 | private bool periodicInput = false; 34 | 35 | [SerializeField] 36 | private bool periodicOutput = false; 37 | 38 | [SerializeField] 39 | private int symmetry = 1; 40 | 41 | [SerializeField] 42 | private int foundation = 0; 43 | 44 | [SerializeField] 45 | private int iterations = 0; 46 | 47 | private OvelappingModel2dWrapper overlappingModel; 48 | private SimpleTiledMode3d simpleTiledModel; 49 | private InputOverlappingData inputOverlappingData; 50 | private Coroutine runningCoroutine; 51 | 52 | public void GenerateOverlappingOutput() 53 | { 54 | inputOverlappingData = dataProvider.GetInputOverlappingData(); 55 | var modelParams = new OverlappingModelParams(width, height, depth, patternSize); 56 | modelParams.PeriodicInput = periodicInput; 57 | modelParams.PeriodicOutput = periodicOutput; 58 | modelParams.Symmetry = symmetry; 59 | modelParams.Ground = foundation; 60 | 61 | overlappingModel = new OvelappingModel2dWrapper(inputOverlappingData, modelParams); 62 | renderer.Init(overlappingModel); 63 | 64 | runningCoroutine = StartCoroutine(overlappingModel.Model.RunViaEnumerator(0, iterations, OnResult, OnIteration)); 65 | } 66 | 67 | public void GenerateSimpleTiledOutput() 68 | { 69 | var inputData = dataProvider.GetInputSimpleTiledData(); 70 | var modelParams = new SimpleTiledModelParams(width, height, depth, periodicOutput); 71 | 72 | simpleTiledModel = new SimpleTiledMode3d(inputData, modelParams); 73 | renderer.Init(simpleTiledModel); 74 | 75 | runningCoroutine = StartCoroutine(simpleTiledModel.RunViaEnumerator(0, iterations, OnResult, OnIteration)); 76 | } 77 | 78 | private void OnIteration(bool[][] wave) 79 | { 80 | renderer.UpdateStates(); 81 | } 82 | 83 | private void OnResult(bool result) 84 | { 85 | Debug.Log("Result is : " + result); 86 | } 87 | 88 | public void Abort() 89 | { 90 | StopCoroutine(runningCoroutine); 91 | renderer.Clear(); 92 | } 93 | } 94 | 95 | #if UNITY_EDITOR 96 | [CustomEditor (typeof(WaveFunctionCollapseGenerator))] 97 | public class WaveFunctionCollapseGeneratorEditor : Editor { 98 | public override void OnInspectorGUI () { 99 | WaveFunctionCollapseGenerator generator = (WaveFunctionCollapseGenerator)target; 100 | if(GUILayout.Button("Generate Overlapping output")){ 101 | generator.GenerateOverlappingOutput(); 102 | } 103 | if(GUILayout.Button("Generate Simple tiled output")){ 104 | generator.GenerateSimpleTiledOutput(); 105 | } 106 | if(GUILayout.Button("Abort and Clear")){ 107 | generator.Abort(); 108 | } 109 | DrawDefaultInspector (); 110 | } 111 | } 112 | #endif 113 | } -------------------------------------------------------------------------------- /Assets/Scripts/Core/WaveFunctionCollapseGenerator.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 281c1d44cffc4b6c98b0e8e1b3857f45 3 | timeCreated: 1521061779 -------------------------------------------------------------------------------- /Assets/Scripts/Core/WaveFunctionCollapseRenderer.cs: -------------------------------------------------------------------------------- 1 | using Core.Data; 2 | using Core.Model; 3 | using UnityEngine; 4 | 5 | namespace Core 6 | { 7 | public class WaveFunctionCollapseRenderer : MonoBehaviour 8 | { 9 | [SerializeField] 10 | private GameObject uncollapsedTilePrefab; 11 | 12 | private int width; 13 | private int height; 14 | private int depth; 15 | private float gridSize = 1f; 16 | private IModel3d model; 17 | private GameObject[,,] tiles; 18 | 19 | public void Init(IModel3d model) 20 | { 21 | this.model = model; 22 | Clear(); 23 | depth = model.ModelParam.Depth; 24 | height = model.ModelParam.Height; 25 | width = model.ModelParam.Width; 26 | 27 | tiles = new GameObject[width, height, depth]; 28 | } 29 | 30 | public void UpdateStates() 31 | { 32 | Debug.Log("Update states"); 33 | for (var x = 0; x < width; x++) 34 | for (var y = 0; y < height; y++) 35 | for (var z = 0; z < depth; z++) 36 | { 37 | var cellState = model.GetCellStateAt(x, y, z); 38 | var tileGameObject = tiles[x, y, z]; 39 | if (tileGameObject != null) 40 | { 41 | var uncollapsedTileView = tileGameObject.GetComponent(); 42 | if (uncollapsedTileView != null) 43 | { 44 | uncollapsedTileView.UpdateState(cellState.EntropyLevel); 45 | if (cellState.Collapsed) 46 | { 47 | if (Application.isPlaying) 48 | { 49 | Destroy(tileGameObject); 50 | } 51 | else 52 | { 53 | DestroyImmediate(tileGameObject); 54 | } 55 | tileGameObject = null; 56 | } 57 | } 58 | } 59 | 60 | if (tileGameObject == null) 61 | { 62 | tiles[x, y, z] = CreateTile(x, y, z, cellState); 63 | } 64 | } 65 | } 66 | 67 | public void Clear() 68 | { 69 | for (int i = 0; i < transform.childCount; i++){ 70 | GameObject go = transform.GetChild(i).gameObject; 71 | if (Application.isPlaying) 72 | { 73 | Destroy(go); 74 | } 75 | else 76 | { 77 | DestroyImmediate(go); 78 | } 79 | } 80 | } 81 | 82 | private GameObject CreateTile(int x, int y, int z, CellState cellState) 83 | { 84 | GameObject tileObject; 85 | if (cellState.Collapsed) 86 | { 87 | var tile = cellState.Tile; 88 | if (tile.Config.Prefab == null) 89 | { 90 | return null; 91 | } 92 | tileObject = Instantiate(tile.Config.Prefab, transform); 93 | tileObject.transform.localPosition = new Vector3(x, y, z); 94 | Debug.Log("Rotation " + tile.Rotation); 95 | var oldRot = tileObject.transform.localEulerAngles; 96 | oldRot.y = tile.Rotation * 90; 97 | tileObject.transform.localEulerAngles = oldRot; 98 | return tileObject; 99 | } 100 | 101 | tileObject = Instantiate(uncollapsedTilePrefab, transform); 102 | tileObject.transform.localPosition = new Vector3(x, y, z); 103 | return tileObject; 104 | } 105 | 106 | private void OnDrawGizmos(){ 107 | Gizmos.color = Color.cyan; 108 | Gizmos.matrix = transform.localToWorldMatrix; 109 | Gizmos.DrawWireCube(new Vector3(width*gridSize/2f-gridSize*0.5f, height*gridSize/2f-gridSize*0.5f, depth*gridSize/2f-gridSize*0.5f), 110 | new Vector3(width*gridSize, height*gridSize, depth*gridSize)); 111 | } 112 | } 113 | } -------------------------------------------------------------------------------- /Assets/Scripts/Core/WaveFunctionCollapseRenderer.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 432a0e37ef324cbb90e2db480b29bffe 3 | timeCreated: 1521493816 -------------------------------------------------------------------------------- /Assets/Settings.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 33bf35c28ec1d40c0b98249eb7e68927 3 | folderAsset: yes 4 | timeCreated: 1523100993 5 | licenseType: Pro 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/Settings/TilePainter_tilesSymmetry.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!114 &11400000 4 | MonoBehaviour: 5 | m_ObjectHideFlags: 0 6 | m_PrefabParentObject: {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: 1923b6bdd0a346ecafb5d8f590b6ab38, type: 3} 12 | m_Name: TilePainter_tilesSymmetry 13 | m_EditorClassIdentifier: 14 | SymmetryX: 15 | - {fileID: 1000010014209402, guid: f60283944539343ab93f9a620a1f6a78, type: 2} 16 | - {fileID: 1000011400876510, guid: 54e885b0c66864527bf354b63b647ec2, type: 2} 17 | - {fileID: 1000010663199542, guid: 33fe361bdb6e2488f8778703d4686a17, type: 2} 18 | - {fileID: 1000011279982584, guid: 43c058248d2ca411290f0fece0bd41c6, type: 2} 19 | - {fileID: 1000011711363582, guid: 87ad8583bf4704265a19a5896536b43e, type: 2} 20 | SymmetryL: 21 | - {fileID: 1000011919750164, guid: 6c74cfbe185e1413d9429f16f30511f8, type: 2} 22 | - {fileID: 1085761803039498, guid: a3fbd43933eb14a67a85df8f33f3d4ed, type: 2} 23 | - {fileID: 1862029139750828, guid: 8a3e50e9aee704099982dd4f6b075e02, type: 2} 24 | SymmetryT: 25 | - {fileID: 1000011458013394, guid: d2aa0e07fd23d42288357f34511f3798, type: 2} 26 | - {fileID: 1000012809223666, guid: da7b0f86a78bd4df5a1a8223e8533d43, type: 2} 27 | - {fileID: 1060547455079178, guid: a72e4e111a5644e5cbff9f3dbb98e12a, type: 2} 28 | - {fileID: 1231064433434622, guid: dd2602834ed064fd1a44d64ef2cfe131, type: 2} 29 | - {fileID: 1548553041272110, guid: 8751679bf4d4e424691f91ea490034f8, type: 2} 30 | SymmetryI: 31 | - {fileID: 1000010818573026, guid: 5a55dab19af0a4a48b255131734b17f8, type: 2} 32 | - {fileID: 1000012711865864, guid: eb4ddedd6b77947dca0ed156428f2b32, type: 2} 33 | - {fileID: 1000012117554692, guid: cb5cada03fcb3435bb7ba29a2dedc053, type: 2} 34 | - {fileID: 1000012768675812, guid: bdfa1bbe5e4c6436ea2e9abbf6e8e321, type: 2} 35 | - {fileID: 1000011220840842, guid: 6960a41176479467eadb37fedebf611c, type: 2} 36 | - {fileID: 1000013667857060, guid: a9eb77e96c9e04c0ba966bbbe08e1da1, type: 2} 37 | SymmetrySlash: [] 38 | -------------------------------------------------------------------------------- /Assets/Settings/TilePainter_tilesSymmetry.asset.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a00ea91c44639465d98f1e6983ef3711 3 | timeCreated: 1522694754 4 | licenseType: Pro 5 | NativeFormatImporter: 6 | mainObjectFileID: 11400000 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/Settings/YuME_tilesData.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!114 &11400000 4 | MonoBehaviour: 5 | m_ObjectHideFlags: 0 6 | m_PrefabParentObject: {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: 1923b6bdd0a346ecafb5d8f590b6ab38, type: 3} 12 | m_Name: YuME_tilesData 13 | m_EditorClassIdentifier: 14 | SymmetryX: 15 | - {fileID: 195650, guid: 4322256955695a94a84fec782ec10d7a, type: 2} 16 | - {fileID: 132138, guid: fa911294c080ba947bd5abaf4b8d9670, type: 2} 17 | - {fileID: 103346, guid: b91147827ce16b34abac85b60a64583c, type: 2} 18 | - {fileID: 113162, guid: cd00fcff2e059af4384f71f397f4bc86, type: 2} 19 | - {fileID: 107076, guid: a5ac0b3853a16744ab510b9a3f5d8c16, type: 2} 20 | - {fileID: 182142, guid: c0e8baa35ad595945b33060be012d85f, type: 2} 21 | - {fileID: 132410, guid: a13bbee944664ef4ba585af046e7e44c, type: 2} 22 | - {fileID: 123044, guid: e9f71fbb2180dad45a9d66c715b657b8, type: 2} 23 | - {fileID: 118360, guid: 6eacdce3fa9060b4498508536d1414e7, type: 2} 24 | SymmetryL: 25 | - {fileID: 176490, guid: 4f29514a127955646a6cb15306f851a1, type: 2} 26 | - {fileID: 138098, guid: d5bde9e99b7aa9344a7f8d6049cb7c64, type: 2} 27 | - {fileID: 140668, guid: b87a0e34870d67c42aead4a981c2de59, type: 2} 28 | - {fileID: 177136, guid: af261c83bca2aaf4f924fe55e44a7735, type: 2} 29 | - {fileID: 169638, guid: f75948054f750d24786167e1f703a172, type: 2} 30 | - {fileID: 118166, guid: 30246b1895fa2554dabd18f570585b03, type: 2} 31 | - {fileID: 109072, guid: de0af26bba7e3924592f3387d5766203, type: 2} 32 | - {fileID: 159662, guid: 72b9fbf00e213644fa2583b3c94789bd, type: 2} 33 | - {fileID: 164600, guid: 2b766c801d18988418c5c8afa51be0a5, type: 2} 34 | - {fileID: 172836, guid: 6cdb506b2750aea4c8dfeadb13546525, type: 2} 35 | SymmetryT: 36 | - {fileID: 156722, guid: dd65960330d8c7a4ca6d67202dbd1d7c, type: 2} 37 | - {fileID: 157390, guid: d7be12575c1d845498108a6fafcf195b, type: 2} 38 | - {fileID: 108930, guid: 2ddaf67cea161f34a932e666264b2a75, type: 2} 39 | - {fileID: 155070, guid: 30ad53a9f3d02724987b3dd7e71da001, type: 2} 40 | - {fileID: 111424, guid: 4bd0cb26b2b48e244833225ac39dcc9a, type: 2} 41 | - {fileID: 121182, guid: 948aa054aef2381438d26a3e4e6e57a6, type: 2} 42 | - {fileID: 168784, guid: 7ff2be065a47436438d0aba020472f82, type: 2} 43 | SymmetryI: 44 | - {fileID: 111108, guid: 3c6d8fa93876a7340af4c1148db1adba, type: 2} 45 | - {fileID: 123422, guid: 373cf4116bb1d5449b6baf4636e07ad5, type: 2} 46 | SymmetrySlash: [] 47 | -------------------------------------------------------------------------------- /Assets/Settings/YuME_tilesData.asset.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 46a6b155929ac4802946941418bb95f5 3 | timeCreated: 1522694754 4 | licenseType: Pro 5 | NativeFormatImporter: 6 | mainObjectFileID: 11400000 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Packages/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "com.unity.collab-proxy": "1.15.7", 4 | "com.unity.ide.rider": "2.0.7", 5 | "com.unity.ide.visualstudio": "2.0.12", 6 | "com.unity.ide.vscode": "1.2.4", 7 | "com.unity.test-framework": "1.1.29", 8 | "com.unity.textmeshpro": "3.0.6", 9 | "com.unity.timeline": "1.4.8", 10 | "com.unity.ugui": "1.0.0", 11 | "com.unity.modules.ai": "1.0.0", 12 | "com.unity.modules.androidjni": "1.0.0", 13 | "com.unity.modules.animation": "1.0.0", 14 | "com.unity.modules.assetbundle": "1.0.0", 15 | "com.unity.modules.audio": "1.0.0", 16 | "com.unity.modules.cloth": "1.0.0", 17 | "com.unity.modules.director": "1.0.0", 18 | "com.unity.modules.imageconversion": "1.0.0", 19 | "com.unity.modules.imgui": "1.0.0", 20 | "com.unity.modules.jsonserialize": "1.0.0", 21 | "com.unity.modules.particlesystem": "1.0.0", 22 | "com.unity.modules.physics": "1.0.0", 23 | "com.unity.modules.physics2d": "1.0.0", 24 | "com.unity.modules.screencapture": "1.0.0", 25 | "com.unity.modules.terrain": "1.0.0", 26 | "com.unity.modules.terrainphysics": "1.0.0", 27 | "com.unity.modules.tilemap": "1.0.0", 28 | "com.unity.modules.ui": "1.0.0", 29 | "com.unity.modules.uielements": "1.0.0", 30 | "com.unity.modules.umbra": "1.0.0", 31 | "com.unity.modules.unityanalytics": "1.0.0", 32 | "com.unity.modules.unitywebrequest": "1.0.0", 33 | "com.unity.modules.unitywebrequestassetbundle": "1.0.0", 34 | "com.unity.modules.unitywebrequestaudio": "1.0.0", 35 | "com.unity.modules.unitywebrequesttexture": "1.0.0", 36 | "com.unity.modules.unitywebrequestwww": "1.0.0", 37 | "com.unity.modules.vehicles": "1.0.0", 38 | "com.unity.modules.video": "1.0.0", 39 | "com.unity.modules.vr": "1.0.0", 40 | "com.unity.modules.wind": "1.0.0", 41 | "com.unity.modules.xr": "1.0.0" 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /Packages/packages-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "com.unity.collab-proxy": { 4 | "version": "1.15.7", 5 | "depth": 0, 6 | "source": "registry", 7 | "dependencies": { 8 | "com.unity.nuget.newtonsoft-json": "2.0.0", 9 | "com.unity.services.core": "1.0.1" 10 | }, 11 | "url": "https://packages.unity.com" 12 | }, 13 | "com.unity.ext.nunit": { 14 | "version": "1.0.6", 15 | "depth": 1, 16 | "source": "registry", 17 | "dependencies": {}, 18 | "url": "https://packages.unity.com" 19 | }, 20 | "com.unity.ide.rider": { 21 | "version": "2.0.7", 22 | "depth": 0, 23 | "source": "registry", 24 | "dependencies": { 25 | "com.unity.test-framework": "1.1.1" 26 | }, 27 | "url": "https://packages.unity.com" 28 | }, 29 | "com.unity.ide.visualstudio": { 30 | "version": "2.0.12", 31 | "depth": 0, 32 | "source": "registry", 33 | "dependencies": { 34 | "com.unity.test-framework": "1.1.9" 35 | }, 36 | "url": "https://packages.unity.com" 37 | }, 38 | "com.unity.ide.vscode": { 39 | "version": "1.2.4", 40 | "depth": 0, 41 | "source": "registry", 42 | "dependencies": {}, 43 | "url": "https://packages.unity.com" 44 | }, 45 | "com.unity.nuget.newtonsoft-json": { 46 | "version": "2.0.0", 47 | "depth": 1, 48 | "source": "registry", 49 | "dependencies": {}, 50 | "url": "https://packages.unity.com" 51 | }, 52 | "com.unity.services.core": { 53 | "version": "1.0.1", 54 | "depth": 1, 55 | "source": "registry", 56 | "dependencies": { 57 | "com.unity.modules.unitywebrequest": "1.0.0" 58 | }, 59 | "url": "https://packages.unity.com" 60 | }, 61 | "com.unity.test-framework": { 62 | "version": "1.1.29", 63 | "depth": 0, 64 | "source": "registry", 65 | "dependencies": { 66 | "com.unity.ext.nunit": "1.0.6", 67 | "com.unity.modules.imgui": "1.0.0", 68 | "com.unity.modules.jsonserialize": "1.0.0" 69 | }, 70 | "url": "https://packages.unity.com" 71 | }, 72 | "com.unity.textmeshpro": { 73 | "version": "3.0.6", 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.timeline": { 82 | "version": "1.4.8", 83 | "depth": 0, 84 | "source": "registry", 85 | "dependencies": { 86 | "com.unity.modules.director": "1.0.0", 87 | "com.unity.modules.animation": "1.0.0", 88 | "com.unity.modules.audio": "1.0.0", 89 | "com.unity.modules.particlesystem": "1.0.0" 90 | }, 91 | "url": "https://packages.unity.com" 92 | }, 93 | "com.unity.ugui": { 94 | "version": "1.0.0", 95 | "depth": 0, 96 | "source": "builtin", 97 | "dependencies": { 98 | "com.unity.modules.ui": "1.0.0", 99 | "com.unity.modules.imgui": "1.0.0" 100 | } 101 | }, 102 | "com.unity.modules.ai": { 103 | "version": "1.0.0", 104 | "depth": 0, 105 | "source": "builtin", 106 | "dependencies": {} 107 | }, 108 | "com.unity.modules.androidjni": { 109 | "version": "1.0.0", 110 | "depth": 0, 111 | "source": "builtin", 112 | "dependencies": {} 113 | }, 114 | "com.unity.modules.animation": { 115 | "version": "1.0.0", 116 | "depth": 0, 117 | "source": "builtin", 118 | "dependencies": {} 119 | }, 120 | "com.unity.modules.assetbundle": { 121 | "version": "1.0.0", 122 | "depth": 0, 123 | "source": "builtin", 124 | "dependencies": {} 125 | }, 126 | "com.unity.modules.audio": { 127 | "version": "1.0.0", 128 | "depth": 0, 129 | "source": "builtin", 130 | "dependencies": {} 131 | }, 132 | "com.unity.modules.cloth": { 133 | "version": "1.0.0", 134 | "depth": 0, 135 | "source": "builtin", 136 | "dependencies": { 137 | "com.unity.modules.physics": "1.0.0" 138 | } 139 | }, 140 | "com.unity.modules.director": { 141 | "version": "1.0.0", 142 | "depth": 0, 143 | "source": "builtin", 144 | "dependencies": { 145 | "com.unity.modules.audio": "1.0.0", 146 | "com.unity.modules.animation": "1.0.0" 147 | } 148 | }, 149 | "com.unity.modules.imageconversion": { 150 | "version": "1.0.0", 151 | "depth": 0, 152 | "source": "builtin", 153 | "dependencies": {} 154 | }, 155 | "com.unity.modules.imgui": { 156 | "version": "1.0.0", 157 | "depth": 0, 158 | "source": "builtin", 159 | "dependencies": {} 160 | }, 161 | "com.unity.modules.jsonserialize": { 162 | "version": "1.0.0", 163 | "depth": 0, 164 | "source": "builtin", 165 | "dependencies": {} 166 | }, 167 | "com.unity.modules.particlesystem": { 168 | "version": "1.0.0", 169 | "depth": 0, 170 | "source": "builtin", 171 | "dependencies": {} 172 | }, 173 | "com.unity.modules.physics": { 174 | "version": "1.0.0", 175 | "depth": 0, 176 | "source": "builtin", 177 | "dependencies": {} 178 | }, 179 | "com.unity.modules.physics2d": { 180 | "version": "1.0.0", 181 | "depth": 0, 182 | "source": "builtin", 183 | "dependencies": {} 184 | }, 185 | "com.unity.modules.screencapture": { 186 | "version": "1.0.0", 187 | "depth": 0, 188 | "source": "builtin", 189 | "dependencies": { 190 | "com.unity.modules.imageconversion": "1.0.0" 191 | } 192 | }, 193 | "com.unity.modules.subsystems": { 194 | "version": "1.0.0", 195 | "depth": 1, 196 | "source": "builtin", 197 | "dependencies": { 198 | "com.unity.modules.jsonserialize": "1.0.0" 199 | } 200 | }, 201 | "com.unity.modules.terrain": { 202 | "version": "1.0.0", 203 | "depth": 0, 204 | "source": "builtin", 205 | "dependencies": {} 206 | }, 207 | "com.unity.modules.terrainphysics": { 208 | "version": "1.0.0", 209 | "depth": 0, 210 | "source": "builtin", 211 | "dependencies": { 212 | "com.unity.modules.physics": "1.0.0", 213 | "com.unity.modules.terrain": "1.0.0" 214 | } 215 | }, 216 | "com.unity.modules.tilemap": { 217 | "version": "1.0.0", 218 | "depth": 0, 219 | "source": "builtin", 220 | "dependencies": { 221 | "com.unity.modules.physics2d": "1.0.0" 222 | } 223 | }, 224 | "com.unity.modules.ui": { 225 | "version": "1.0.0", 226 | "depth": 0, 227 | "source": "builtin", 228 | "dependencies": {} 229 | }, 230 | "com.unity.modules.uielements": { 231 | "version": "1.0.0", 232 | "depth": 0, 233 | "source": "builtin", 234 | "dependencies": { 235 | "com.unity.modules.ui": "1.0.0", 236 | "com.unity.modules.imgui": "1.0.0", 237 | "com.unity.modules.jsonserialize": "1.0.0", 238 | "com.unity.modules.uielementsnative": "1.0.0" 239 | } 240 | }, 241 | "com.unity.modules.uielementsnative": { 242 | "version": "1.0.0", 243 | "depth": 1, 244 | "source": "builtin", 245 | "dependencies": { 246 | "com.unity.modules.ui": "1.0.0", 247 | "com.unity.modules.imgui": "1.0.0", 248 | "com.unity.modules.jsonserialize": "1.0.0" 249 | } 250 | }, 251 | "com.unity.modules.umbra": { 252 | "version": "1.0.0", 253 | "depth": 0, 254 | "source": "builtin", 255 | "dependencies": {} 256 | }, 257 | "com.unity.modules.unityanalytics": { 258 | "version": "1.0.0", 259 | "depth": 0, 260 | "source": "builtin", 261 | "dependencies": { 262 | "com.unity.modules.unitywebrequest": "1.0.0", 263 | "com.unity.modules.jsonserialize": "1.0.0" 264 | } 265 | }, 266 | "com.unity.modules.unitywebrequest": { 267 | "version": "1.0.0", 268 | "depth": 0, 269 | "source": "builtin", 270 | "dependencies": {} 271 | }, 272 | "com.unity.modules.unitywebrequestassetbundle": { 273 | "version": "1.0.0", 274 | "depth": 0, 275 | "source": "builtin", 276 | "dependencies": { 277 | "com.unity.modules.assetbundle": "1.0.0", 278 | "com.unity.modules.unitywebrequest": "1.0.0" 279 | } 280 | }, 281 | "com.unity.modules.unitywebrequestaudio": { 282 | "version": "1.0.0", 283 | "depth": 0, 284 | "source": "builtin", 285 | "dependencies": { 286 | "com.unity.modules.unitywebrequest": "1.0.0", 287 | "com.unity.modules.audio": "1.0.0" 288 | } 289 | }, 290 | "com.unity.modules.unitywebrequesttexture": { 291 | "version": "1.0.0", 292 | "depth": 0, 293 | "source": "builtin", 294 | "dependencies": { 295 | "com.unity.modules.unitywebrequest": "1.0.0", 296 | "com.unity.modules.imageconversion": "1.0.0" 297 | } 298 | }, 299 | "com.unity.modules.unitywebrequestwww": { 300 | "version": "1.0.0", 301 | "depth": 0, 302 | "source": "builtin", 303 | "dependencies": { 304 | "com.unity.modules.unitywebrequest": "1.0.0", 305 | "com.unity.modules.unitywebrequestassetbundle": "1.0.0", 306 | "com.unity.modules.unitywebrequestaudio": "1.0.0", 307 | "com.unity.modules.audio": "1.0.0", 308 | "com.unity.modules.assetbundle": "1.0.0", 309 | "com.unity.modules.imageconversion": "1.0.0" 310 | } 311 | }, 312 | "com.unity.modules.vehicles": { 313 | "version": "1.0.0", 314 | "depth": 0, 315 | "source": "builtin", 316 | "dependencies": { 317 | "com.unity.modules.physics": "1.0.0" 318 | } 319 | }, 320 | "com.unity.modules.video": { 321 | "version": "1.0.0", 322 | "depth": 0, 323 | "source": "builtin", 324 | "dependencies": { 325 | "com.unity.modules.audio": "1.0.0", 326 | "com.unity.modules.ui": "1.0.0", 327 | "com.unity.modules.unitywebrequest": "1.0.0" 328 | } 329 | }, 330 | "com.unity.modules.vr": { 331 | "version": "1.0.0", 332 | "depth": 0, 333 | "source": "builtin", 334 | "dependencies": { 335 | "com.unity.modules.jsonserialize": "1.0.0", 336 | "com.unity.modules.physics": "1.0.0", 337 | "com.unity.modules.xr": "1.0.0" 338 | } 339 | }, 340 | "com.unity.modules.wind": { 341 | "version": "1.0.0", 342 | "depth": 0, 343 | "source": "builtin", 344 | "dependencies": {} 345 | }, 346 | "com.unity.modules.xr": { 347 | "version": "1.0.0", 348 | "depth": 0, 349 | "source": "builtin", 350 | "dependencies": { 351 | "com.unity.modules.physics": "1.0.0", 352 | "com.unity.modules.jsonserialize": "1.0.0", 353 | "com.unity.modules.subsystems": "1.0.0" 354 | } 355 | } 356 | } 357 | } 358 | -------------------------------------------------------------------------------- /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: 0 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: 3 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_EnablePCM: 1 18 | m_LayerCollisionMatrix: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 19 | m_AutoSimulation: 1 20 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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: 4 7 | m_ExternalVersionControlSupport: Visible Meta Files 8 | m_SerializationMode: 2 9 | m_DefaultBehaviorMode: 0 10 | m_SpritePackerMode: 0 11 | m_SpritePackerPaddingPower: 1 12 | m_ProjectGenerationIncludedExtensions: txt;xml;fnt;cd 13 | m_ProjectGenerationRootNamespace: 14 | m_UserGeneratedProjectSuffix: 15 | m_CollabEditorSettings: 16 | inProgressEnabled: 1 17 | -------------------------------------------------------------------------------- /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 | m_SettingNames: 89 | - Humanoid 90 | -------------------------------------------------------------------------------- /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/PackageManagerSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!114 &1 4 | MonoBehaviour: 5 | m_ObjectHideFlags: 61 6 | m_CorrespondingSourceObject: {fileID: 0} 7 | m_PrefabInstance: {fileID: 0} 8 | m_PrefabAsset: {fileID: 0} 9 | m_GameObject: {fileID: 0} 10 | m_Enabled: 1 11 | m_EditorHideFlags: 0 12 | m_Script: {fileID: 13964, guid: 0000000000000000e000000000000000, type: 0} 13 | m_Name: 14 | m_EditorClassIdentifier: 15 | m_EnablePreviewPackages: 0 16 | m_EnablePackageDependencies: 0 17 | m_AdvancedSettingsExpanded: 1 18 | m_ScopedRegistriesSettingsExpanded: 1 19 | oneTimeWarningShown: 0 20 | m_Registries: 21 | - m_Id: main 22 | m_Name: 23 | m_Url: https://packages.unity.com 24 | m_Scopes: [] 25 | m_IsDefault: 1 26 | m_Capabilities: 7 27 | m_UserSelectedRegistryName: 28 | m_UserAddingNewScopedRegistry: 0 29 | m_RegistryInfoDraft: 30 | m_ErrorMessage: 31 | m_Original: 32 | m_Id: 33 | m_Name: 34 | m_Url: 35 | m_Scopes: [] 36 | m_IsDefault: 0 37 | m_Capabilities: 0 38 | m_Modified: 0 39 | m_Name: 40 | m_Url: 41 | m_Scopes: 42 | - 43 | m_SelectedScopeIndex: 0 44 | -------------------------------------------------------------------------------- /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_AlwaysShowColliders: 0 28 | m_ShowColliderSleep: 1 29 | m_ShowColliderContacts: 0 30 | m_ShowColliderAABB: 0 31 | m_ContactArrowScale: 0.2 32 | m_ColliderAwakeColor: {r: 0.5686275, g: 0.95686275, b: 0.54509807, a: 0.7529412} 33 | m_ColliderAsleepColor: {r: 0.5686275, g: 0.95686275, b: 0.54509807, a: 0.36078432} 34 | m_ColliderContactColor: {r: 1, g: 0, b: 1, a: 0.6862745} 35 | m_ColliderAABBColor: {r: 1, g: 1, b: 0, a: 0.2509804} 36 | m_LayerCollisionMatrix: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 37 | -------------------------------------------------------------------------------- /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 | serializedVersion: 2 7 | m_DefaultPresets: {} 8 | -------------------------------------------------------------------------------- /ProjectSettings/ProjectVersion.txt: -------------------------------------------------------------------------------- 1 | m_EditorVersion: 2020.3.26f1 2 | m_EditorVersionWithRevision: 2020.3.26f1 (7298b473bc1a) 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: 5 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 | particleRaycastBudget: 4 33 | asyncUploadTimeSlice: 2 34 | asyncUploadBufferSize: 4 35 | resolutionScalingFixedDPIFactor: 1 36 | excludedTargetPlatforms: [] 37 | - serializedVersion: 2 38 | name: Low 39 | pixelLightCount: 0 40 | shadows: 0 41 | shadowResolution: 0 42 | shadowProjection: 1 43 | shadowCascades: 1 44 | shadowDistance: 20 45 | shadowNearPlaneOffset: 3 46 | shadowCascade2Split: 0.33333334 47 | shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} 48 | shadowmaskMode: 0 49 | blendWeights: 2 50 | textureQuality: 0 51 | anisotropicTextures: 0 52 | antiAliasing: 0 53 | softParticles: 0 54 | softVegetation: 0 55 | realtimeReflectionProbes: 0 56 | billboardsFaceCameraPosition: 0 57 | vSyncCount: 0 58 | lodBias: 0.4 59 | maximumLODLevel: 0 60 | particleRaycastBudget: 16 61 | asyncUploadTimeSlice: 2 62 | asyncUploadBufferSize: 4 63 | resolutionScalingFixedDPIFactor: 1 64 | excludedTargetPlatforms: [] 65 | - serializedVersion: 2 66 | name: Medium 67 | pixelLightCount: 1 68 | shadows: 1 69 | shadowResolution: 0 70 | shadowProjection: 1 71 | shadowCascades: 1 72 | shadowDistance: 20 73 | shadowNearPlaneOffset: 3 74 | shadowCascade2Split: 0.33333334 75 | shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} 76 | shadowmaskMode: 0 77 | blendWeights: 2 78 | textureQuality: 0 79 | anisotropicTextures: 1 80 | antiAliasing: 0 81 | softParticles: 0 82 | softVegetation: 0 83 | realtimeReflectionProbes: 0 84 | billboardsFaceCameraPosition: 0 85 | vSyncCount: 1 86 | lodBias: 0.7 87 | maximumLODLevel: 0 88 | particleRaycastBudget: 64 89 | asyncUploadTimeSlice: 2 90 | asyncUploadBufferSize: 4 91 | resolutionScalingFixedDPIFactor: 1 92 | excludedTargetPlatforms: [] 93 | - serializedVersion: 2 94 | name: High 95 | pixelLightCount: 2 96 | shadows: 2 97 | shadowResolution: 1 98 | shadowProjection: 1 99 | shadowCascades: 2 100 | shadowDistance: 40 101 | shadowNearPlaneOffset: 3 102 | shadowCascade2Split: 0.33333334 103 | shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} 104 | shadowmaskMode: 1 105 | blendWeights: 2 106 | textureQuality: 0 107 | anisotropicTextures: 1 108 | antiAliasing: 0 109 | softParticles: 0 110 | softVegetation: 1 111 | realtimeReflectionProbes: 1 112 | billboardsFaceCameraPosition: 1 113 | vSyncCount: 1 114 | lodBias: 1 115 | maximumLODLevel: 0 116 | particleRaycastBudget: 256 117 | asyncUploadTimeSlice: 2 118 | asyncUploadBufferSize: 4 119 | resolutionScalingFixedDPIFactor: 1 120 | excludedTargetPlatforms: [] 121 | - serializedVersion: 2 122 | name: Very High 123 | pixelLightCount: 3 124 | shadows: 2 125 | shadowResolution: 2 126 | shadowProjection: 1 127 | shadowCascades: 2 128 | shadowDistance: 70 129 | shadowNearPlaneOffset: 3 130 | shadowCascade2Split: 0.33333334 131 | shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} 132 | shadowmaskMode: 1 133 | blendWeights: 4 134 | textureQuality: 0 135 | anisotropicTextures: 2 136 | antiAliasing: 2 137 | softParticles: 1 138 | softVegetation: 1 139 | realtimeReflectionProbes: 1 140 | billboardsFaceCameraPosition: 1 141 | vSyncCount: 1 142 | lodBias: 1.5 143 | maximumLODLevel: 0 144 | particleRaycastBudget: 1024 145 | asyncUploadTimeSlice: 2 146 | asyncUploadBufferSize: 4 147 | resolutionScalingFixedDPIFactor: 1 148 | excludedTargetPlatforms: [] 149 | - serializedVersion: 2 150 | name: Ultra 151 | pixelLightCount: 4 152 | shadows: 2 153 | shadowResolution: 2 154 | shadowProjection: 1 155 | shadowCascades: 4 156 | shadowDistance: 150 157 | shadowNearPlaneOffset: 3 158 | shadowCascade2Split: 0.33333334 159 | shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} 160 | shadowmaskMode: 1 161 | blendWeights: 4 162 | textureQuality: 0 163 | anisotropicTextures: 2 164 | antiAliasing: 2 165 | softParticles: 1 166 | softVegetation: 1 167 | realtimeReflectionProbes: 1 168 | billboardsFaceCameraPosition: 1 169 | vSyncCount: 1 170 | lodBias: 2 171 | maximumLODLevel: 0 172 | particleRaycastBudget: 4096 173 | asyncUploadTimeSlice: 2 174 | asyncUploadBufferSize: 4 175 | resolutionScalingFixedDPIFactor: 1 176 | excludedTargetPlatforms: [] 177 | m_PerPlatformDefaultQuality: 178 | Android: 2 179 | Nintendo 3DS: 5 180 | Nintendo Switch: 5 181 | PS4: 5 182 | PSM: 5 183 | PSP2: 2 184 | Samsung TV: 2 185 | Standalone: 5 186 | Tizen: 2 187 | Web: 5 188 | WebGL: 3 189 | WiiU: 5 190 | Windows Store Apps: 5 191 | XboxOne: 5 192 | iPhone: 2 193 | tvOS: 2 194 | -------------------------------------------------------------------------------- /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 | - YuME_TileMap 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.33333334 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: 0 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_Enabled: 0 14 | m_CaptureEditorExceptions: 1 15 | UnityPurchasingSettings: 16 | m_Enabled: 0 17 | m_TestMode: 0 18 | UnityAnalyticsSettings: 19 | m_Enabled: 1 20 | m_InitializeOnStartup: 1 21 | m_TestMode: 0 22 | m_TestEventUrl: 23 | m_TestConfigUrl: 24 | UnityAdsSettings: 25 | m_Enabled: 0 26 | m_InitializeOnStartup: 1 27 | m_TestMode: 0 28 | m_EnabledPlatforms: 4294967295 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 | m_CompiledVersion: 0 14 | m_RuntimeVersion: 0 15 | -------------------------------------------------------------------------------- /ProjectSettings/VersionControlSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!890905787 &1 4 | VersionControlSettings: 5 | m_ObjectHideFlags: 0 6 | m_Mode: Visible Meta Files 7 | m_CollabEditorSettings: 8 | inProgressEnabled: 1 9 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Wave Function Collapse content generator for Unity 2 | Unity plugin for procedural generation of levels, environments or 3d models based on Wave Function Collapse algorithm. Wave Function Collapse algorithm is employed to assemble 2d and 3d tile-based visually impressive levels, dioramas, buildings, etc from handcrafted tilesets. 3 | 4 | There are two models 5 | * **Overlapping model** breaks an input pattern up into pattern chunks. And arrange them in output with constraint of local similarity (You can read more about this in [original repo](https://github.com/mxgmn/WaveFunctionCollapse)). In simple words, it produces output which looks similar to input. 6 | * **Simple Tiled model** takes input and creates neigbor constraints (legal adjacencies for different tiles) for the tiles based on information if in input tile were located next to each other. 7 | 8 | **Overlapping model output example (input on the left, generated output on the right)** 9 |

overlapping model

10 | 11 | **Simple Tiled model output example** 12 |

simple tiled model

13 | 14 |

main gif

15 | 16 | Watch a video demonstration of plugin in action on YouTube: https://www.youtube.com/watch?v=Mkvh4rosiF0 and https://www.youtube.com/watch?v=JO8OW2zg0gY 17 | 18 | 19 | ### How to use 20 | There are two versions of algorithm: Overlapping Model and Simple Tiled Model 21 | For Overlapping model: 22 | * Implement IInputDataProvider class for your source or use existing implementation for TilePainterInputDataProvider 23 | * Create a game object and add to it your InputDataProvider, this object is going to be source of input for WFC model 24 | * Create a game object and add to it WaveFunctionCollapseRenderer, this object is goint to be a target for generated content 25 | * Create a game object and add to it WaveFunctionCollapseGenerator, this object starts generation. 26 | * Drag-and-drop InputDataProvider and WaveFunctionCollapseRenderer objects to corresponding fields in generator object 27 | * (*Only for simple tiled model*) Create SymmetrySetsScriptableObject and set up symmetries for your tile prefabs. Look below to read more about symmetries. 28 | * Set up parameters of a generator to required in your case. 29 | * Press "Generate Overlapping output" or "Generate Simple Tiled output" depending on your needs 30 | 31 | #### Symmetry system for SimpleTiledModel 32 | 33 | Lists of all the possible pairs of adjacent tiles in practical tilesets can be quite long, so mxmgn implemented a symmetry system for tiles to shorten the enumeration. In this system each tile should be assigned with its symmetry type. 34 | 35 | * X - for tile with all possible directions 36 | * L - for L shaped (like corners or L-turns), note that L-tile prefab should be located upside-down (Like 'Г') 37 | * T - for stairs, T-turns, etc 38 | * I - for part of the road or any tile which has same type of connection on opposite sides 39 | * / - for any tile which has same type of connection on two neighbours sides 40 | 41 | #### Explanation of parameters 42 | 43 | Model Constructor 44 | 45 | * `width,depth,height (int)` Dimensions of the output data. Height currently only supported for Simple Tiled model, for Overlapping use height equal 1. 46 | * `pattern size (int)` Represents the width & height of the patterns that the overlap model breaks the input into. As it solves, it attempts to match up these subpatterns with each other. A higher pattern size will capture bigger features of the input, but is computationally more intensive, and may require a larger input sample to achieve reliable solutions. 47 | * `periodic input (bool)` Represents whether the input pattern is tiling. If true, when WFC digests the input into N pattern chunks it will create patterns connecting the right & bottom edges to the left & top. If you use this setting, you'll need to make sure your input "makes sense" accross these edges. 48 | * `periodic output (bool)` Determines if the output solutions are tilable. It's usefull for creating things like tileable textures, but also has a surprising influence on the output. When working with WFC, it's often a good idea to toggle Periodic Output on and off, checking if either setting influences the results in a favorable way. 49 | * `symmetry (int)` Represents which additional symmetries of the input pattern are digested. 0 is just the original input, 1-8 adds mirrored and rotated variations. These variations can help flesh out the patterns in your input, but aren't necessary. They also only work with unidirectional tiles, and are undesirable when your final game tiles have direction dependent graphics or functionality. 50 | * `ground (int)` When not 0, this assigns a pattern for the bottom row of the output. It's mainly useful for "vertical" words, where you want a distinct ground and sky separation. The value corresponds to the overlap models internal pattern indexes, so some experimentation is needed to figure out a suitable value. 51 | 52 | ### Theory behind 53 | Constraint solving is neither a traditional nor well-known approach to procedural content generation (PCG). Nevertheless, this approach can be surprisingly effective for building controllable content generators.The goal of an algorithm for solving Constraint satisfaction problems (CSPs) (a solver) is to find a total assignment (an assignment for every variable) such that no constraints are violated. Algorithm works similar to Sudoku. Basically you can say that it's a Sudoku solver on steroids :) 54 | 55 | ### Based on 56 | Based on the [Wave Function Collapse algorithm](https://github.com/mxgmn/WaveFunctionCollapse) made by [mxgmn](https://github.com/mxgmn). You can find there more theory behind an algorithm and some impressive examples. 57 | 58 | ### Feature plans 59 | * Finish ready-to-use Unity plugin for quick level/content generation which can be super useful for rapid prototyping or game-jams and put it to Unity Asset Store 60 | * Add possibility to easily use additional heuristics to make generated results more hand-crafted or, for instance, make levels walkable 61 | * Add possibility to use additional constraints (like predefine some parts of output) 62 | * Add backtracking to resolve rare contradictions 63 | * Improved Editor support 64 | 65 | --------------------------------------------------------------------------------