├── Assets ├── Textures │ ├── SH.png │ ├── Grid.png │ ├── H-shape.png │ ├── O-shape.png │ ├── Khrushchyovka.png │ ├── Transparent.png │ ├── Grid-transparent.png │ ├── Khrushchyovka-specular.png │ ├── SH.png.meta │ ├── Grid.png.meta │ ├── H-shape.png.meta │ ├── O-shape.png.meta │ ├── Khrushchyovka.png.meta │ ├── Transparent.png.meta │ ├── Grid-transparent.png.meta │ └── Khrushchyovka-specular.png.meta ├── Materials │ ├── Grid.mat │ ├── Plane.mat │ ├── Back side.mat │ ├── Floor plan.mat │ ├── Front side.mat │ ├── Grid.mat.meta │ ├── Khrushchyovka.mat │ ├── Plane.mat.meta │ ├── Back side.mat.meta │ ├── Floor plan.mat.meta │ ├── Front side.mat.meta │ ├── Khrushchyovka back.mat │ ├── Khrushchyovka.mat.meta │ └── Khrushchyovka back.mat.meta ├── Models │ ├── Roof.blend │ ├── Attic25.blend │ ├── Attic30.blend │ ├── Socle25.blend │ ├── Socle30.blend │ ├── Wall25.blend │ ├── Wall30.blend │ ├── Window25.blend │ ├── Window30.blend │ ├── Balcony25.blend │ ├── Balcony30.blend │ ├── Entrance25.blend │ ├── Entrance30.blend │ ├── RoofGabled.blend │ ├── RoofHipped.blend │ ├── Balcony25Glazed.blend │ ├── Balcony30Glazed.blend │ ├── EntranceWall25.blend │ ├── EntranceWall30.blend │ ├── Subdivided cube.blend │ ├── Entrance25Roofed.blend │ ├── Entrance30Roofed.blend │ ├── EntranceWallLast25.blend │ ├── EntranceWallLast30.blend │ ├── Balcony25.blend.meta │ ├── Window30.blend.meta │ ├── Subdivided cube.blend.meta │ ├── Balcony30.blend.meta │ ├── Wall30.blend.meta │ ├── Balcony30Glazed.blend.meta │ ├── Roof.blend.meta │ ├── Wall25.blend.meta │ ├── Balcony25Glazed.blend.meta │ ├── RoofHipped.blend.meta │ ├── Socle25.blend.meta │ ├── Window25.blend.meta │ ├── Entrance25.blend.meta │ ├── Socle30.blend.meta │ ├── RoofGabled.blend.meta │ ├── Entrance30.blend.meta │ ├── EntranceWall25.blend.meta │ ├── EntranceWallLast25.blend.meta │ ├── EntranceWall30.blend.meta │ ├── Attic25.blend.meta │ ├── Entrance30Roofed.blend.meta │ ├── EntranceWallLast30.blend.meta │ ├── Attic30.blend.meta │ └── Entrance25Roofed.blend.meta ├── Scenes │ ├── Floor Plan.unity │ ├── Khrushchyovka.unity │ ├── PG geometry.unity │ ├── Floor Plan.unity.meta │ ├── PG geometry.unity.meta │ └── Khrushchyovka.unity.meta ├── Prefabs │ ├── Khrushchyovka.prefab │ └── Khrushchyovka.prefab.meta ├── Materials.meta ├── Models.meta ├── Prefabs.meta ├── Scenes.meta ├── Scripts.meta ├── Shaders.meta ├── Textures.meta ├── Scripts │ ├── PGMesh.meta │ ├── Floor plan.meta │ ├── Khrushchyovka.meta │ ├── Triangulator.meta │ ├── Twist.js.meta │ ├── MouseOrbit.js.meta │ ├── MeshExtrusion.cs.meta │ ├── PGMesh │ │ ├── PGMesh.cs.meta │ │ ├── SpinMotor.cs.meta │ │ ├── TriangleCloud.cs.meta │ │ ├── ProceduralGeneratedMesh.cs.meta │ │ ├── SpinMotor.cs │ │ ├── TriangleCloud.cs │ │ ├── ProceduralGeneratedMesh.cs │ │ └── PGMesh.cs │ ├── ScreenshotMaker.cs.meta │ ├── Triangulator │ │ ├── Triangulator.cs.meta │ │ ├── PolygonTester.cs.meta │ │ ├── PolygonTester.cs │ │ └── Triangulator.cs │ ├── Floor plan │ │ ├── FloorPlanGenerator.cs.meta │ │ └── FloorPlanGenerator.cs │ ├── Khrushchyovka │ │ ├── Khrushchyovka.cs.meta │ │ ├── KhrushchyovkaSpawner.cs.meta │ │ ├── KhrushchyovkaSpawner.cs │ │ └── Khrushchyovka.cs │ ├── ScreenshotMaker.cs │ ├── MouseOrbit.js │ ├── Twist.js │ └── MeshExtrusion.cs └── Shaders │ ├── BackSide.shader.meta │ ├── FrontSide.shader.meta │ ├── Khrushchyovka.shader.meta │ ├── FrontSide.shader │ ├── BackSide.shader │ └── Khrushchyovka.shader ├── ProjectSettings ├── TagManager.asset ├── TimeManager.asset ├── AudioManager.asset ├── InputManager.asset ├── NavMeshLayers.asset ├── DynamicsManager.asset ├── EditorSettings.asset ├── GraphicsSettings.asset ├── NetworkManager.asset ├── ProjectSettings.asset ├── QualitySettings.asset └── EditorBuildSettings.asset ├── .gitattributes ├── .gitignore ├── LICENSE.md └── README.md /Assets/Textures/SH.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BasmanovDaniil/ProceduralExperiments/HEAD/Assets/Textures/SH.png -------------------------------------------------------------------------------- /Assets/Materials/Grid.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BasmanovDaniil/ProceduralExperiments/HEAD/Assets/Materials/Grid.mat -------------------------------------------------------------------------------- /Assets/Models/Roof.blend: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BasmanovDaniil/ProceduralExperiments/HEAD/Assets/Models/Roof.blend -------------------------------------------------------------------------------- /Assets/Textures/Grid.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BasmanovDaniil/ProceduralExperiments/HEAD/Assets/Textures/Grid.png -------------------------------------------------------------------------------- /Assets/Materials/Plane.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BasmanovDaniil/ProceduralExperiments/HEAD/Assets/Materials/Plane.mat -------------------------------------------------------------------------------- /Assets/Models/Attic25.blend: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BasmanovDaniil/ProceduralExperiments/HEAD/Assets/Models/Attic25.blend -------------------------------------------------------------------------------- /Assets/Models/Attic30.blend: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BasmanovDaniil/ProceduralExperiments/HEAD/Assets/Models/Attic30.blend -------------------------------------------------------------------------------- /Assets/Models/Socle25.blend: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BasmanovDaniil/ProceduralExperiments/HEAD/Assets/Models/Socle25.blend -------------------------------------------------------------------------------- /Assets/Models/Socle30.blend: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BasmanovDaniil/ProceduralExperiments/HEAD/Assets/Models/Socle30.blend -------------------------------------------------------------------------------- /Assets/Models/Wall25.blend: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BasmanovDaniil/ProceduralExperiments/HEAD/Assets/Models/Wall25.blend -------------------------------------------------------------------------------- /Assets/Models/Wall30.blend: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BasmanovDaniil/ProceduralExperiments/HEAD/Assets/Models/Wall30.blend -------------------------------------------------------------------------------- /Assets/Models/Window25.blend: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BasmanovDaniil/ProceduralExperiments/HEAD/Assets/Models/Window25.blend -------------------------------------------------------------------------------- /Assets/Models/Window30.blend: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BasmanovDaniil/ProceduralExperiments/HEAD/Assets/Models/Window30.blend -------------------------------------------------------------------------------- /Assets/Textures/H-shape.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BasmanovDaniil/ProceduralExperiments/HEAD/Assets/Textures/H-shape.png -------------------------------------------------------------------------------- /Assets/Textures/O-shape.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BasmanovDaniil/ProceduralExperiments/HEAD/Assets/Textures/O-shape.png -------------------------------------------------------------------------------- /Assets/Materials/Back side.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BasmanovDaniil/ProceduralExperiments/HEAD/Assets/Materials/Back side.mat -------------------------------------------------------------------------------- /Assets/Models/Balcony25.blend: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BasmanovDaniil/ProceduralExperiments/HEAD/Assets/Models/Balcony25.blend -------------------------------------------------------------------------------- /Assets/Models/Balcony30.blend: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BasmanovDaniil/ProceduralExperiments/HEAD/Assets/Models/Balcony30.blend -------------------------------------------------------------------------------- /Assets/Models/Entrance25.blend: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BasmanovDaniil/ProceduralExperiments/HEAD/Assets/Models/Entrance25.blend -------------------------------------------------------------------------------- /Assets/Models/Entrance30.blend: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BasmanovDaniil/ProceduralExperiments/HEAD/Assets/Models/Entrance30.blend -------------------------------------------------------------------------------- /Assets/Models/RoofGabled.blend: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BasmanovDaniil/ProceduralExperiments/HEAD/Assets/Models/RoofGabled.blend -------------------------------------------------------------------------------- /Assets/Models/RoofHipped.blend: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BasmanovDaniil/ProceduralExperiments/HEAD/Assets/Models/RoofHipped.blend -------------------------------------------------------------------------------- /Assets/Scenes/Floor Plan.unity: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BasmanovDaniil/ProceduralExperiments/HEAD/Assets/Scenes/Floor Plan.unity -------------------------------------------------------------------------------- /Assets/Materials/Floor plan.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BasmanovDaniil/ProceduralExperiments/HEAD/Assets/Materials/Floor plan.mat -------------------------------------------------------------------------------- /Assets/Materials/Front side.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BasmanovDaniil/ProceduralExperiments/HEAD/Assets/Materials/Front side.mat -------------------------------------------------------------------------------- /Assets/Scenes/Khrushchyovka.unity: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BasmanovDaniil/ProceduralExperiments/HEAD/Assets/Scenes/Khrushchyovka.unity -------------------------------------------------------------------------------- /Assets/Scenes/PG geometry.unity: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BasmanovDaniil/ProceduralExperiments/HEAD/Assets/Scenes/PG geometry.unity -------------------------------------------------------------------------------- /Assets/Textures/Khrushchyovka.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BasmanovDaniil/ProceduralExperiments/HEAD/Assets/Textures/Khrushchyovka.png -------------------------------------------------------------------------------- /Assets/Textures/Transparent.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BasmanovDaniil/ProceduralExperiments/HEAD/Assets/Textures/Transparent.png -------------------------------------------------------------------------------- /ProjectSettings/TagManager.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BasmanovDaniil/ProceduralExperiments/HEAD/ProjectSettings/TagManager.asset -------------------------------------------------------------------------------- /ProjectSettings/TimeManager.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BasmanovDaniil/ProceduralExperiments/HEAD/ProjectSettings/TimeManager.asset -------------------------------------------------------------------------------- /Assets/Materials/Grid.mat.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 5ab1a6e06f6faa840b08a11498c09a1a 3 | NativeFormatImporter: 4 | userData: 5 | -------------------------------------------------------------------------------- /Assets/Materials/Khrushchyovka.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BasmanovDaniil/ProceduralExperiments/HEAD/Assets/Materials/Khrushchyovka.mat -------------------------------------------------------------------------------- /Assets/Materials/Plane.mat.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 3865fa02966b09447b26792512d151af 3 | NativeFormatImporter: 4 | userData: 5 | -------------------------------------------------------------------------------- /Assets/Models/Balcony25Glazed.blend: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BasmanovDaniil/ProceduralExperiments/HEAD/Assets/Models/Balcony25Glazed.blend -------------------------------------------------------------------------------- /Assets/Models/Balcony30Glazed.blend: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BasmanovDaniil/ProceduralExperiments/HEAD/Assets/Models/Balcony30Glazed.blend -------------------------------------------------------------------------------- /Assets/Models/EntranceWall25.blend: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BasmanovDaniil/ProceduralExperiments/HEAD/Assets/Models/EntranceWall25.blend -------------------------------------------------------------------------------- /Assets/Models/EntranceWall30.blend: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BasmanovDaniil/ProceduralExperiments/HEAD/Assets/Models/EntranceWall30.blend -------------------------------------------------------------------------------- /Assets/Models/Subdivided cube.blend: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BasmanovDaniil/ProceduralExperiments/HEAD/Assets/Models/Subdivided cube.blend -------------------------------------------------------------------------------- /Assets/Prefabs/Khrushchyovka.prefab: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BasmanovDaniil/ProceduralExperiments/HEAD/Assets/Prefabs/Khrushchyovka.prefab -------------------------------------------------------------------------------- /Assets/Scenes/Floor Plan.unity.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b5b1975ba2fe65646b3352764bc79f80 3 | DefaultImporter: 4 | userData: 5 | -------------------------------------------------------------------------------- /Assets/Scenes/PG geometry.unity.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a6e8f729f8b77214098cd30f37b662c8 3 | DefaultImporter: 4 | userData: 5 | -------------------------------------------------------------------------------- /ProjectSettings/AudioManager.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BasmanovDaniil/ProceduralExperiments/HEAD/ProjectSettings/AudioManager.asset -------------------------------------------------------------------------------- /ProjectSettings/InputManager.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BasmanovDaniil/ProceduralExperiments/HEAD/ProjectSettings/InputManager.asset -------------------------------------------------------------------------------- /ProjectSettings/NavMeshLayers.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BasmanovDaniil/ProceduralExperiments/HEAD/ProjectSettings/NavMeshLayers.asset -------------------------------------------------------------------------------- /Assets/Materials.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 2a42dd41f4fbfe549aaeb2a6b5316cec 3 | folderAsset: yes 4 | DefaultImporter: 5 | userData: 6 | -------------------------------------------------------------------------------- /Assets/Materials/Back side.mat.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 9bc1f2033c7744e47a004af60b54646a 3 | NativeFormatImporter: 4 | userData: 5 | -------------------------------------------------------------------------------- /Assets/Materials/Floor plan.mat.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ef00fbb3ed3e90e4292923f70ad9083a 3 | NativeFormatImporter: 4 | userData: 5 | -------------------------------------------------------------------------------- /Assets/Materials/Front side.mat.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 4bb50ce5ce4df884da27be25a969ca20 3 | NativeFormatImporter: 4 | userData: 5 | -------------------------------------------------------------------------------- /Assets/Models.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6b5a052963cd1fd4583a812401659e31 3 | folderAsset: yes 4 | DefaultImporter: 5 | userData: 6 | -------------------------------------------------------------------------------- /Assets/Models/Entrance25Roofed.blend: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BasmanovDaniil/ProceduralExperiments/HEAD/Assets/Models/Entrance25Roofed.blend -------------------------------------------------------------------------------- /Assets/Models/Entrance30Roofed.blend: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BasmanovDaniil/ProceduralExperiments/HEAD/Assets/Models/Entrance30Roofed.blend -------------------------------------------------------------------------------- /Assets/Models/EntranceWallLast25.blend: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BasmanovDaniil/ProceduralExperiments/HEAD/Assets/Models/EntranceWallLast25.blend -------------------------------------------------------------------------------- /Assets/Models/EntranceWallLast30.blend: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BasmanovDaniil/ProceduralExperiments/HEAD/Assets/Models/EntranceWallLast30.blend -------------------------------------------------------------------------------- /Assets/Prefabs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 4aa3575d403e0d846b39458152549405 3 | folderAsset: yes 4 | DefaultImporter: 5 | userData: 6 | -------------------------------------------------------------------------------- /Assets/Scenes.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6c351394a26c925459b1a24c79cc339e 3 | folderAsset: yes 4 | DefaultImporter: 5 | userData: 6 | -------------------------------------------------------------------------------- /Assets/Scenes/Khrushchyovka.unity.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 2ea4d94a4667a4045aa4945a3bcc706c 3 | DefaultImporter: 4 | userData: 5 | -------------------------------------------------------------------------------- /Assets/Scripts.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 73b1f4707ec2ec44084bfa3a9734ac08 3 | folderAsset: yes 4 | DefaultImporter: 5 | userData: 6 | -------------------------------------------------------------------------------- /Assets/Shaders.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 04c89e2f4c40f5a479e4fef811ec0865 3 | folderAsset: yes 4 | DefaultImporter: 5 | userData: 6 | -------------------------------------------------------------------------------- /Assets/Textures.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 416eced4354e6814bbf848706a971d60 3 | folderAsset: yes 4 | DefaultImporter: 5 | userData: 6 | -------------------------------------------------------------------------------- /Assets/Textures/Grid-transparent.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BasmanovDaniil/ProceduralExperiments/HEAD/Assets/Textures/Grid-transparent.png -------------------------------------------------------------------------------- /ProjectSettings/DynamicsManager.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BasmanovDaniil/ProceduralExperiments/HEAD/ProjectSettings/DynamicsManager.asset -------------------------------------------------------------------------------- /ProjectSettings/EditorSettings.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BasmanovDaniil/ProceduralExperiments/HEAD/ProjectSettings/EditorSettings.asset -------------------------------------------------------------------------------- /ProjectSettings/GraphicsSettings.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BasmanovDaniil/ProceduralExperiments/HEAD/ProjectSettings/GraphicsSettings.asset -------------------------------------------------------------------------------- /ProjectSettings/NetworkManager.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BasmanovDaniil/ProceduralExperiments/HEAD/ProjectSettings/NetworkManager.asset -------------------------------------------------------------------------------- /ProjectSettings/ProjectSettings.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BasmanovDaniil/ProceduralExperiments/HEAD/ProjectSettings/ProjectSettings.asset -------------------------------------------------------------------------------- /ProjectSettings/QualitySettings.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BasmanovDaniil/ProceduralExperiments/HEAD/ProjectSettings/QualitySettings.asset -------------------------------------------------------------------------------- /Assets/Materials/Khrushchyovka back.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BasmanovDaniil/ProceduralExperiments/HEAD/Assets/Materials/Khrushchyovka back.mat -------------------------------------------------------------------------------- /Assets/Materials/Khrushchyovka.mat.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 9a238ec9a9970cf4a8d00f31db670d58 3 | NativeFormatImporter: 4 | userData: 5 | -------------------------------------------------------------------------------- /Assets/Prefabs/Khrushchyovka.prefab.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b6fd3931cddf71347bcebc2f861daa94 3 | NativeFormatImporter: 4 | userData: 5 | -------------------------------------------------------------------------------- /Assets/Scripts/PGMesh.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ad866d82168472e4ca0320e7220d842b 3 | folderAsset: yes 4 | DefaultImporter: 5 | userData: 6 | -------------------------------------------------------------------------------- /Assets/Materials/Khrushchyovka back.mat.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e17691310322dd74293945f6aba6ea28 3 | NativeFormatImporter: 4 | userData: 5 | -------------------------------------------------------------------------------- /Assets/Scripts/Floor plan.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 97b40de4dee3278419044b9125d54c30 3 | folderAsset: yes 4 | DefaultImporter: 5 | userData: 6 | -------------------------------------------------------------------------------- /Assets/Textures/Khrushchyovka-specular.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BasmanovDaniil/ProceduralExperiments/HEAD/Assets/Textures/Khrushchyovka-specular.png -------------------------------------------------------------------------------- /ProjectSettings/EditorBuildSettings.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BasmanovDaniil/ProceduralExperiments/HEAD/ProjectSettings/EditorBuildSettings.asset -------------------------------------------------------------------------------- /Assets/Scripts/Khrushchyovka.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: be8643c15f15cb74ea87fce313a74a44 3 | folderAsset: yes 4 | DefaultImporter: 5 | userData: 6 | -------------------------------------------------------------------------------- /Assets/Scripts/Triangulator.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ddc3ffb117bc2ce418d92f64164c34c7 3 | folderAsset: yes 4 | DefaultImporter: 5 | userData: 6 | -------------------------------------------------------------------------------- /Assets/Shaders/BackSide.shader.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 0e1fe8be4495069438e1f1e5ee4c629a 3 | ShaderImporter: 4 | defaultTextures: [] 5 | userData: 6 | -------------------------------------------------------------------------------- /Assets/Shaders/FrontSide.shader.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 2d1020d8f2ae6354c94ba1e099b01d25 3 | ShaderImporter: 4 | defaultTextures: [] 5 | userData: 6 | -------------------------------------------------------------------------------- /Assets/Shaders/Khrushchyovka.shader.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a5ac4dfb8c6948c44b8b72dbc09427b5 3 | ShaderImporter: 4 | defaultTextures: [] 5 | userData: 6 | -------------------------------------------------------------------------------- /Assets/Scripts/Twist.js.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 28d6019ead11c33fd000a93a8d76c639 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/Scripts/MouseOrbit.js.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 27acebc9ad1110f6d00074c88d76c639 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/Scripts/MeshExtrusion.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d8a05eabbd11f8d4d000995b8d76c639 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/Scripts/PGMesh/PGMesh.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1d6b0032865b99e42951d5be3b7570e2 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/Scripts/ScreenshotMaker.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 4e06294606a8db64c85db727c8100b45 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/Scripts/PGMesh/SpinMotor.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 18927c97139f9da449b088f8c02661a9 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/Scripts/PGMesh/TriangleCloud.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 83c5fa4a1cf59154a94daae460be7147 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/Scripts/Triangulator/Triangulator.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c97e9e34a6f772a478c820163bb57b49 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/Scripts/Floor plan/FloorPlanGenerator.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ecf90664789b6e841837b97a74155007 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/Scripts/Khrushchyovka/Khrushchyovka.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d35618105edd66f498f8a059e7738539 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/Scripts/PGMesh/ProceduralGeneratedMesh.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 8f15cf56fd02b93408e872b4316c3c8e 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/Scripts/Triangulator/PolygonTester.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b699d6b446ee1394c8df6e59c1961b05 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/Scripts/Khrushchyovka/KhrushchyovkaSpawner.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d4ea1d9b384d1d747a6e3564660af6fc 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/Scripts/PGMesh/SpinMotor.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | public class SpinMotor : MonoBehaviour 4 | { 5 | public Vector3 speed = new Vector3(0, 0.5f, 0); 6 | 7 | private Transform tr; 8 | 9 | void Start() 10 | { 11 | tr = transform; 12 | } 13 | 14 | void Update() 15 | { 16 | tr.rotation *= Quaternion.Euler(speed*Time.deltaTime); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | *.sln merge=union 7 | *.csproj merge=union 8 | *.vbproj merge=union 9 | *.fsproj merge=union 10 | *.dbproj merge=union 11 | 12 | # Standard to msysgit 13 | *.doc diff=astextplain 14 | *.DOC diff=astextplain 15 | *.docx diff=astextplain 16 | *.DOCX diff=astextplain 17 | *.dot diff=astextplain 18 | *.DOT diff=astextplain 19 | *.pdf diff=astextplain 20 | *.PDF diff=astextplain 21 | *.rtf diff=astextplain 22 | *.RTF diff=astextplain 23 | -------------------------------------------------------------------------------- /Assets/Scripts/ScreenshotMaker.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | public class ScreenshotMaker : MonoBehaviour 4 | { 5 | public float repeatRate; 6 | 7 | private bool capture; 8 | private int count; 9 | 10 | void Start () 11 | { 12 | InvokeRepeating("Capture", 0, repeatRate); 13 | } 14 | 15 | void Update () 16 | { 17 | if (!Input.GetKeyDown(KeyCode.Space)) return; 18 | capture = !capture; 19 | if (capture) count = 0; 20 | } 21 | 22 | void Capture() 23 | { 24 | if (!capture) return; 25 | Application.CaptureScreenshot(count + ".png"); 26 | count++; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled source # 2 | ################### 3 | *.com 4 | *.class 5 | *.dll 6 | *.exe 7 | *.o 8 | *.so 9 | 10 | # Packages # 11 | ############ 12 | *.7z 13 | *.dmg 14 | *.gz 15 | *.iso 16 | *.jar 17 | *.rar 18 | *.tar 19 | *.zip 20 | 21 | # Logs and databases # 22 | ###################### 23 | *.log 24 | *.sql 25 | *.sqlite 26 | 27 | # OS generated files # 28 | ###################### 29 | .DS_Store 30 | .DS_Store? 31 | ._* 32 | .Spotlight-V100 33 | .Trashes 34 | Icon? 35 | ehthumbs.db 36 | Thumbs.db 37 | 38 | # Unity # 39 | ######### 40 | [Ll]ibrary 41 | [Tt]emp 42 | [Bb]uilds 43 | *.unityproj 44 | 45 | # Visual Studio # 46 | ################# 47 | [Oo]bj 48 | *.sln 49 | *.csproj 50 | *.suo 51 | *.userprefs 52 | *.pidb 53 | -------------------------------------------------------------------------------- /Assets/Shaders/FrontSide.shader: -------------------------------------------------------------------------------- 1 | Shader "Custom/FrontSide" { 2 | Properties { 3 | _Color ("Main Color", Color) = (1,1,1,1) 4 | _MainTex ("Base (RGB)", 2D) = "white" {} 5 | } 6 | SubShader { 7 | Tags { "RenderType"="Opaque" } 8 | Cull Back 9 | LOD 200 10 | 11 | CGPROGRAM 12 | #pragma surface surf Lambert 13 | 14 | sampler2D _MainTex; 15 | fixed4 _Color; 16 | 17 | struct Input { 18 | float2 uv_MainTex; 19 | }; 20 | 21 | void surf(Input IN, inout SurfaceOutput o) { 22 | half4 c = tex2D(_MainTex, IN.uv_MainTex) * _Color; 23 | o.Albedo = c.rgb; 24 | o.Alpha = c.a; 25 | } 26 | ENDCG 27 | } 28 | FallBack "Diffuse" 29 | } -------------------------------------------------------------------------------- /Assets/Textures/SH.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 0773b5cf4efa4854abfaa701a38f7104 3 | TextureImporter: 4 | serializedVersion: 2 5 | mipmaps: 6 | mipMapMode: 0 7 | enableMipMap: 1 8 | linearTexture: 0 9 | correctGamma: 0 10 | fadeOut: 0 11 | borderMipMap: 0 12 | mipMapFadeDistanceStart: 1 13 | mipMapFadeDistanceEnd: 3 14 | bumpmap: 15 | convertToNormalMap: 0 16 | externalNormalMap: 0 17 | heightScale: .25 18 | normalMapFilter: 0 19 | isReadable: 1 20 | grayScaleToAlpha: 0 21 | generateCubemap: 0 22 | seamlessCubemap: 0 23 | textureFormat: -3 24 | maxTextureSize: 128 25 | textureSettings: 26 | filterMode: 0 27 | aniso: -1 28 | mipBias: -1 29 | wrapMode: -1 30 | nPOTScale: 1 31 | lightmap: 0 32 | compressionQuality: 50 33 | alphaIsTransparency: 0 34 | textureType: 5 35 | buildTargetSettings: [] 36 | userData: 37 | -------------------------------------------------------------------------------- /Assets/Textures/Grid.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 02e2922e2a3f8874dbfa5846beb2364c 3 | TextureImporter: 4 | serializedVersion: 2 5 | mipmaps: 6 | mipMapMode: 0 7 | enableMipMap: 1 8 | linearTexture: 0 9 | correctGamma: 0 10 | fadeOut: 0 11 | borderMipMap: 0 12 | mipMapFadeDistanceStart: 1 13 | mipMapFadeDistanceEnd: 3 14 | bumpmap: 15 | convertToNormalMap: 0 16 | externalNormalMap: 0 17 | heightScale: .25 18 | normalMapFilter: 0 19 | isReadable: 0 20 | grayScaleToAlpha: 0 21 | generateCubemap: 0 22 | seamlessCubemap: 0 23 | textureFormat: -1 24 | maxTextureSize: 1024 25 | textureSettings: 26 | filterMode: -1 27 | aniso: -1 28 | mipBias: -1 29 | wrapMode: -1 30 | nPOTScale: 1 31 | lightmap: 0 32 | compressionQuality: 50 33 | alphaIsTransparency: 0 34 | textureType: -1 35 | buildTargetSettings: [] 36 | userData: 37 | -------------------------------------------------------------------------------- /Assets/Textures/H-shape.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d5ff43396fff8c042a6fed2a2bfd8772 3 | TextureImporter: 4 | serializedVersion: 2 5 | mipmaps: 6 | mipMapMode: 0 7 | enableMipMap: 1 8 | linearTexture: 0 9 | correctGamma: 0 10 | fadeOut: 0 11 | borderMipMap: 0 12 | mipMapFadeDistanceStart: 1 13 | mipMapFadeDistanceEnd: 3 14 | bumpmap: 15 | convertToNormalMap: 0 16 | externalNormalMap: 0 17 | heightScale: .25 18 | normalMapFilter: 0 19 | isReadable: 1 20 | grayScaleToAlpha: 0 21 | generateCubemap: 0 22 | seamlessCubemap: 0 23 | textureFormat: -3 24 | maxTextureSize: 128 25 | textureSettings: 26 | filterMode: 0 27 | aniso: -1 28 | mipBias: -1 29 | wrapMode: -1 30 | nPOTScale: 1 31 | lightmap: 0 32 | compressionQuality: 50 33 | alphaIsTransparency: 0 34 | textureType: 5 35 | buildTargetSettings: [] 36 | userData: 37 | -------------------------------------------------------------------------------- /Assets/Textures/O-shape.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1e586f225ce49fa49a8d1bc7c2f573aa 3 | TextureImporter: 4 | serializedVersion: 2 5 | mipmaps: 6 | mipMapMode: 0 7 | enableMipMap: 1 8 | linearTexture: 0 9 | correctGamma: 0 10 | fadeOut: 0 11 | borderMipMap: 0 12 | mipMapFadeDistanceStart: 1 13 | mipMapFadeDistanceEnd: 3 14 | bumpmap: 15 | convertToNormalMap: 0 16 | externalNormalMap: 0 17 | heightScale: .25 18 | normalMapFilter: 0 19 | isReadable: 1 20 | grayScaleToAlpha: 0 21 | generateCubemap: 0 22 | seamlessCubemap: 0 23 | textureFormat: -3 24 | maxTextureSize: 128 25 | textureSettings: 26 | filterMode: 0 27 | aniso: -1 28 | mipBias: -1 29 | wrapMode: -1 30 | nPOTScale: 1 31 | lightmap: 0 32 | compressionQuality: 50 33 | alphaIsTransparency: 0 34 | textureType: 5 35 | buildTargetSettings: [] 36 | userData: 37 | -------------------------------------------------------------------------------- /Assets/Textures/Khrushchyovka.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 9e84f89a52ad468468107871d61a827c 3 | TextureImporter: 4 | serializedVersion: 2 5 | mipmaps: 6 | mipMapMode: 0 7 | enableMipMap: 1 8 | linearTexture: 0 9 | correctGamma: 0 10 | fadeOut: 0 11 | borderMipMap: 0 12 | mipMapFadeDistanceStart: 1 13 | mipMapFadeDistanceEnd: 3 14 | bumpmap: 15 | convertToNormalMap: 0 16 | externalNormalMap: 0 17 | heightScale: .25 18 | normalMapFilter: 0 19 | isReadable: 0 20 | grayScaleToAlpha: 0 21 | generateCubemap: 0 22 | seamlessCubemap: 0 23 | textureFormat: -1 24 | maxTextureSize: 1024 25 | textureSettings: 26 | filterMode: 2 27 | aniso: 9 28 | mipBias: -1 29 | wrapMode: 0 30 | nPOTScale: 1 31 | lightmap: 0 32 | compressionQuality: 50 33 | alphaIsTransparency: 0 34 | textureType: 0 35 | buildTargetSettings: [] 36 | userData: 37 | -------------------------------------------------------------------------------- /Assets/Textures/Transparent.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d75a3ec76b8e3304f8aa5d3867becc36 3 | TextureImporter: 4 | serializedVersion: 2 5 | mipmaps: 6 | mipMapMode: 0 7 | enableMipMap: 1 8 | linearTexture: 0 9 | correctGamma: 0 10 | fadeOut: 0 11 | borderMipMap: 0 12 | mipMapFadeDistanceStart: 1 13 | mipMapFadeDistanceEnd: 3 14 | bumpmap: 15 | convertToNormalMap: 0 16 | externalNormalMap: 0 17 | heightScale: .25 18 | normalMapFilter: 0 19 | isReadable: 1 20 | grayScaleToAlpha: 0 21 | generateCubemap: 0 22 | seamlessCubemap: 0 23 | textureFormat: -3 24 | maxTextureSize: 128 25 | textureSettings: 26 | filterMode: 0 27 | aniso: -1 28 | mipBias: -1 29 | wrapMode: -1 30 | nPOTScale: 1 31 | lightmap: 0 32 | compressionQuality: 50 33 | alphaIsTransparency: 1 34 | textureType: 5 35 | buildTargetSettings: [] 36 | userData: 37 | -------------------------------------------------------------------------------- /Assets/Textures/Grid-transparent.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6b6469462e5a2d64fbae0f54efba9a81 3 | TextureImporter: 4 | serializedVersion: 2 5 | mipmaps: 6 | mipMapMode: 0 7 | enableMipMap: 1 8 | linearTexture: 0 9 | correctGamma: 0 10 | fadeOut: 0 11 | borderMipMap: 0 12 | mipMapFadeDistanceStart: 1 13 | mipMapFadeDistanceEnd: 3 14 | bumpmap: 15 | convertToNormalMap: 0 16 | externalNormalMap: 0 17 | heightScale: .25 18 | normalMapFilter: 0 19 | isReadable: 0 20 | grayScaleToAlpha: 0 21 | generateCubemap: 0 22 | seamlessCubemap: 0 23 | textureFormat: -1 24 | maxTextureSize: 1024 25 | textureSettings: 26 | filterMode: 2 27 | aniso: 9 28 | mipBias: -1 29 | wrapMode: -1 30 | nPOTScale: 1 31 | lightmap: 0 32 | compressionQuality: 50 33 | alphaIsTransparency: 1 34 | textureType: -1 35 | buildTargetSettings: [] 36 | userData: 37 | -------------------------------------------------------------------------------- /Assets/Textures/Khrushchyovka-specular.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: cb3183e7f8a305941bf7aef777361be5 3 | TextureImporter: 4 | serializedVersion: 2 5 | mipmaps: 6 | mipMapMode: 0 7 | enableMipMap: 1 8 | linearTexture: 0 9 | correctGamma: 0 10 | fadeOut: 0 11 | borderMipMap: 0 12 | mipMapFadeDistanceStart: 1 13 | mipMapFadeDistanceEnd: 3 14 | bumpmap: 15 | convertToNormalMap: 0 16 | externalNormalMap: 0 17 | heightScale: .25 18 | normalMapFilter: 0 19 | isReadable: 0 20 | grayScaleToAlpha: 0 21 | generateCubemap: 0 22 | seamlessCubemap: 0 23 | textureFormat: -1 24 | maxTextureSize: 1024 25 | textureSettings: 26 | filterMode: 2 27 | aniso: 9 28 | mipBias: -1 29 | wrapMode: -1 30 | nPOTScale: 1 31 | lightmap: 0 32 | compressionQuality: 50 33 | alphaIsTransparency: 0 34 | textureType: -1 35 | buildTargetSettings: [] 36 | userData: 37 | -------------------------------------------------------------------------------- /Assets/Shaders/BackSide.shader: -------------------------------------------------------------------------------- 1 | Shader "Custom/BackSide" { 2 | Properties { 3 | _Color ("Main Color", Color) = (1,1,1,1) 4 | _MainTex ("Base (RGB)", 2D) = "white" {} 5 | } 6 | SubShader { 7 | Tags { "RenderType"="Opaque" } 8 | Cull Front 9 | LOD 200 10 | 11 | CGPROGRAM 12 | #pragma surface surf Lambert vertex:vert 13 | 14 | sampler2D _MainTex; 15 | fixed4 _Color; 16 | 17 | struct Input { 18 | float2 uv_MainTex; 19 | }; 20 | 21 | void vert (inout appdata_full v, out Input o) { 22 | UNITY_INITIALIZE_OUTPUT(Input, o); 23 | v.normal = -v.normal; 24 | } 25 | 26 | void surf(Input IN, inout SurfaceOutput o) { 27 | half4 c = tex2D(_MainTex, IN.uv_MainTex) * _Color; 28 | o.Albedo = c.rgb; 29 | o.Alpha = c.a; 30 | } 31 | ENDCG 32 | } 33 | FallBack "Diffuse" 34 | } 35 | -------------------------------------------------------------------------------- /Assets/Shaders/Khrushchyovka.shader: -------------------------------------------------------------------------------- 1 | Shader "Custom/Khrushchyovka" { 2 | Properties { 3 | _Color ("Main Color", Color) = (1,1,1,1) 4 | _MainTex ("Base (RGBA)", 2D) = "white" {} 5 | _GlassColor ("Glass Color", Color) = (0.5, 0.5, 0.5, 1) 6 | _Shininess ("Shininess", Range (0.01, 1)) = 0.078125 7 | _SpecColor ("Specular Color", Color) = (0.5, 0.5, 0.5, 1) 8 | _SpecTex ("Specular (RGB)", 2D) = "gray" {} 9 | } 10 | SubShader { 11 | Tags { "RenderType"="Opaque" } 12 | LOD 200 13 | 14 | CGPROGRAM 15 | #pragma surface surf BlinnPhong 16 | 17 | sampler2D _MainTex, _SpecTex; 18 | fixed4 _Color, _GlassColor; 19 | half _Shininess; 20 | 21 | struct Input { 22 | float2 uv_MainTex; 23 | }; 24 | 25 | void surf (Input IN, inout SurfaceOutput o) { 26 | half4 main = tex2D (_MainTex, IN.uv_MainTex); 27 | half4 spec = tex2D(_SpecTex, IN.uv_MainTex); 28 | o.Albedo = main.rgb * _Color.rgb + spec.rgb * _GlassColor.rgb; 29 | o.Gloss = spec.rgb; 30 | o.Specular = _Shininess; 31 | } 32 | ENDCG 33 | } 34 | FallBack "Diffuse" 35 | } 36 | -------------------------------------------------------------------------------- /Assets/Scripts/PGMesh/TriangleCloud.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using PGToolkit; 3 | 4 | [RequireComponent(typeof(MeshFilter))] 5 | [RequireComponent(typeof(MeshRenderer))] 6 | public class TriangleCloud : MonoBehaviour 7 | { 8 | public int count = 200; 9 | public int radius = 10; 10 | public float speed = 0.5f; 11 | 12 | private MeshFilter meshFilter; 13 | 14 | void Start () 15 | { 16 | meshFilter = GetComponent(); 17 | 18 | var combine = new CombineInstance[count]; 19 | 20 | for (int i = 0; i < count; i++) 21 | { 22 | var offset = Random.onUnitSphere * radius; 23 | combine[i].mesh = PGMesh.Triangle(offset + Random.onUnitSphere, offset + Random.onUnitSphere, offset + Random.onUnitSphere); 24 | } 25 | 26 | var mesh = new Mesh(); 27 | mesh.CombineMeshes(combine, true, false); 28 | meshFilter.sharedMesh = mesh; 29 | } 30 | 31 | void Update() 32 | { 33 | if (Input.GetKeyDown(KeyCode.Escape)) Application.Quit(); 34 | transform.rotation *= Quaternion.Euler(0, speed, 0); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /Assets/Scripts/MouseOrbit.js: -------------------------------------------------------------------------------- 1 | var target : Transform; 2 | var distance = 10.0; 3 | 4 | var xSpeed = 250.0; 5 | var ySpeed = 120.0; 6 | 7 | var yMinLimit = -20; 8 | var yMaxLimit = 80; 9 | 10 | private var x = 0.0; 11 | private var y = 0.0; 12 | 13 | @script AddComponentMenu("Camera-Control/Mouse Orbit") 14 | 15 | function Start () { 16 | var angles = transform.eulerAngles; 17 | x = angles.y; 18 | y = angles.x; 19 | 20 | // Make the rigid body not change rotation 21 | if (rigidbody) 22 | rigidbody.freezeRotation = true; 23 | } 24 | 25 | function LateUpdate () { 26 | if (target) { 27 | x += Input.GetAxis("Mouse X") * xSpeed * 0.02; 28 | y -= Input.GetAxis("Mouse Y") * ySpeed * 0.02; 29 | 30 | y = ClampAngle(y, yMinLimit, yMaxLimit); 31 | 32 | var rotation = Quaternion.Euler(y, x, 0); 33 | var position = rotation * Vector3(0.0, 0.0, -distance) + target.position; 34 | 35 | transform.rotation = rotation; 36 | transform.position = position; 37 | } 38 | } 39 | 40 | static function ClampAngle (angle : float, min : float, max : float) { 41 | if (angle < -360) 42 | angle += 360; 43 | if (angle > 360) 44 | angle -= 360; 45 | return Mathf.Clamp (angle, min, max); 46 | } -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | This is free and unencumbered software released into the public domain. 2 | 3 | Anyone is free to copy, modify, publish, use, compile, sell, or 4 | distribute this software, either in source code form or as a compiled 5 | binary, for any purpose, commercial or non-commercial, and by any 6 | means. 7 | 8 | In jurisdictions that recognize copyright laws, the author or authors 9 | of this software dedicate any and all copyright interest in the 10 | software to the public domain. We make this dedication for the benefit 11 | of the public at large and to the detriment of our heirs and 12 | successors. We intend this dedication to be an overt act of 13 | relinquishment in perpetuity of all present and future rights to this 14 | software under copyright law. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | 24 | For more information, please refer to 25 | -------------------------------------------------------------------------------- /Assets/Scripts/Twist.js: -------------------------------------------------------------------------------- 1 | // This script is placed in public domain. The author takes no responsibility for any possible harm. 2 | 3 | // twist a mesh by this amount 4 | var twist = 1.0; 5 | 6 | var inputSensitivity = 1.5; 7 | 8 | private var baseVertices : Vector3[]; 9 | private var baseNormals : Vector3[]; 10 | 11 | function Update () 12 | { 13 | twist += Input.GetAxis("Horizontal") * inputSensitivity * Time.deltaTime; 14 | 15 | var mesh : Mesh = GetComponent(MeshFilter).mesh; 16 | 17 | if (baseVertices == null) 18 | baseVertices = mesh.vertices; 19 | if (baseNormals == null) 20 | baseNormals = mesh.normals; 21 | 22 | var vertices = new Vector3[baseVertices.Length]; 23 | var normals = new Vector3[baseVertices.Length]; 24 | 25 | for (var i=0;i(); 15 | switch (shape) 16 | { 17 | case PGMesh.Shape.Triangle: 18 | meshFilter.sharedMesh = PGMesh.Triangle(Vector3.left / 2 + Vector3.down / 2, Vector3.up, Vector3.right / 2 + Vector3.down / 2); 19 | break; 20 | case PGMesh.Shape.Quad: 21 | meshFilter.sharedMesh = PGMesh.Quad(Vector3.left / 2 + Vector3.down / 2, Vector3.right, Vector3.up); 22 | break; 23 | case PGMesh.Shape.Plane: 24 | meshFilter.sharedMesh = PGMesh.Plane(Vector3.left / 2 + Vector3.down / 2, Vector3.right, Vector3.up, 1, 3); 25 | break; 26 | case PGMesh.Shape.Tetrahedron: 27 | meshFilter.sharedMesh = PGMesh.Tetrahedron(1); 28 | break; 29 | case PGMesh.Shape.Cube: 30 | meshFilter.sharedMesh = PGMesh.Cube(1); 31 | break; 32 | case PGMesh.Shape.Octahedron: 33 | meshFilter.sharedMesh = PGMesh.Octahedron(1); 34 | break; 35 | case PGMesh.Shape.Icosahedron: 36 | meshFilter.sharedMesh = PGMesh.Icosahedron(1); 37 | break; 38 | } 39 | } 40 | } -------------------------------------------------------------------------------- /Assets/Scripts/Triangulator/PolygonTester.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | public class PolygonTester : MonoBehaviour 4 | { 5 | void Start() 6 | { 7 | // Create Vector2 vertices 8 | Vector2[] vertices2D = new Vector2[] { 9 | new Vector2(0,0), 10 | new Vector2(0,50), 11 | new Vector2(50,50), 12 | new Vector2(50,100), 13 | new Vector2(0,100), 14 | new Vector2(0,150), 15 | new Vector2(150,150), 16 | new Vector2(150,100), 17 | new Vector2(100,100), 18 | new Vector2(100,50), 19 | new Vector2(150,50), 20 | new Vector2(150,0), 21 | }; 22 | 23 | // Use the triangulator to get indices for creating triangles 24 | Triangulator tr = new Triangulator(vertices2D); 25 | int[] indices = tr.Triangulate(); 26 | 27 | // Create the Vector3 vertices 28 | Vector3[] vertices = new Vector3[vertices2D.Length]; 29 | for (int i = 0; i < vertices.Length; i++) 30 | { 31 | vertices[i] = new Vector3(vertices2D[i].x, vertices2D[i].y, 0); 32 | } 33 | 34 | // Create the mesh 35 | Mesh msh = new Mesh(); 36 | msh.vertices = vertices; 37 | msh.triangles = indices; 38 | msh.RecalculateNormals(); 39 | msh.RecalculateBounds(); 40 | 41 | // Set up game object with mesh; 42 | gameObject.AddComponent(typeof(MeshRenderer)); 43 | MeshFilter filter = gameObject.AddComponent(typeof(MeshFilter)) as MeshFilter; 44 | filter.mesh = msh; 45 | } 46 | } -------------------------------------------------------------------------------- /Assets/Scripts/Khrushchyovka/KhrushchyovkaSpawner.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | public class KhrushchyovkaSpawner : MonoBehaviour 4 | { 5 | public int x; 6 | public int y; 7 | public GameObject prefab; 8 | 9 | private Transform tr; 10 | 11 | void Start() 12 | { 13 | tr = transform; 14 | var position = new Vector3(-x*30+30, 0, -y*30+30); 15 | for (int i = 0; i < x; i++) 16 | { 17 | for (int j = 0; j < y; j++) 18 | { 19 | var clone = (GameObject)Instantiate(prefab, position, Quaternion.identity); 20 | clone.transform.parent = tr; 21 | position.x += 60; 22 | } 23 | position.x = -x * 30; 24 | position.z += 60; 25 | } 26 | } 27 | 28 | void Update() 29 | { 30 | if (Input.GetKeyDown(KeyCode.Escape)) Application.Quit(); 31 | if (Input.GetMouseButtonDown(0)) 32 | { 33 | foreach (Transform clone in transform) 34 | { 35 | Destroy(clone.gameObject); 36 | } 37 | 38 | var position = new Vector3(-x * 30 + 30, 0, -y * 30 + 30); 39 | for (int i = 0; i < x; i++) 40 | { 41 | for (int j = 0; j < y; j++) 42 | { 43 | var clone = (GameObject)Instantiate(prefab, position, Quaternion.identity); 44 | clone.transform.parent = tr; 45 | position.x += 60; 46 | } 47 | position.x = -x * 30; 48 | position.z += 60; 49 | } 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /Assets/Models/Balcony25.blend.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6da5733675758904a9e7d395ff0fbed7 3 | ModelImporter: 4 | serializedVersion: 15 5 | fileIDToRecycleName: 6 | 100000: //RootNode 7 | 400000: //RootNode 8 | 2300000: //RootNode 9 | 3300000: //RootNode 10 | 4300000: Balcony25 11 | 7400000: Default Take 12 | 9500000: //RootNode 13 | materials: 14 | importMaterials: 0 15 | materialName: 0 16 | materialSearch: 1 17 | animations: 18 | legacyGenerateAnimations: 4 19 | bakeSimulation: 0 20 | animationCompression: 1 21 | animationRotationError: .5 22 | animationPositionError: .5 23 | animationScaleError: .5 24 | animationWrapMode: 0 25 | clipAnimations: [] 26 | isReadable: 1 27 | meshes: 28 | lODScreenPercentages: [] 29 | globalScale: 1 30 | meshCompression: 0 31 | addColliders: 0 32 | importBlendShapes: 1 33 | swapUVChannels: 0 34 | generateSecondaryUV: 0 35 | useFileUnits: 1 36 | optimizeMeshForGPU: 1 37 | weldVertices: 1 38 | secondaryUVAngleDistortion: 8 39 | secondaryUVAreaDistortion: 15.000001 40 | secondaryUVHardAngle: 88 41 | secondaryUVPackMargin: 4 42 | tangentSpace: 43 | normalSmoothAngle: 60 44 | splitTangentsAcrossUV: 1 45 | normalImportMode: 1 46 | tangentImportMode: 1 47 | importAnimation: 1 48 | copyAvatar: 0 49 | humanDescription: 50 | human: [] 51 | skeleton: [] 52 | handles: [] 53 | armTwist: .5 54 | foreArmTwist: .5 55 | upperLegTwist: .5 56 | legTwist: .5 57 | armStretch: .0500000007 58 | legStretch: .0500000007 59 | feetSpacing: 0 60 | rootMotionBoneName: 61 | lastHumanDescriptionAvatarSource: {instanceID: 0} 62 | additionalBone: 1 63 | animationType: 0 64 | userData: 65 | -------------------------------------------------------------------------------- /Assets/Models/Window30.blend.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 4d4b41255f2986644b9e523ed432f8a8 3 | ModelImporter: 4 | serializedVersion: 15 5 | fileIDToRecycleName: 6 | 100000: //RootNode 7 | 400000: //RootNode 8 | 2300000: //RootNode 9 | 3300000: //RootNode 10 | 4300000: Window30 11 | 7400000: Default Take 12 | 9500000: //RootNode 13 | materials: 14 | importMaterials: 0 15 | materialName: 0 16 | materialSearch: 1 17 | animations: 18 | legacyGenerateAnimations: 4 19 | bakeSimulation: 0 20 | animationCompression: 1 21 | animationRotationError: .5 22 | animationPositionError: .5 23 | animationScaleError: .5 24 | animationWrapMode: 0 25 | clipAnimations: [] 26 | isReadable: 1 27 | meshes: 28 | lODScreenPercentages: [] 29 | globalScale: 1 30 | meshCompression: 0 31 | addColliders: 0 32 | importBlendShapes: 1 33 | swapUVChannels: 0 34 | generateSecondaryUV: 0 35 | useFileUnits: 1 36 | optimizeMeshForGPU: 1 37 | weldVertices: 1 38 | secondaryUVAngleDistortion: 8 39 | secondaryUVAreaDistortion: 15.000001 40 | secondaryUVHardAngle: 88 41 | secondaryUVPackMargin: 4 42 | tangentSpace: 43 | normalSmoothAngle: 60 44 | splitTangentsAcrossUV: 1 45 | normalImportMode: 1 46 | tangentImportMode: 1 47 | importAnimation: 1 48 | copyAvatar: 0 49 | humanDescription: 50 | human: [] 51 | skeleton: [] 52 | handles: [] 53 | armTwist: .5 54 | foreArmTwist: .5 55 | upperLegTwist: .5 56 | legTwist: .5 57 | armStretch: .0500000007 58 | legStretch: .0500000007 59 | feetSpacing: 0 60 | rootMotionBoneName: 61 | lastHumanDescriptionAvatarSource: {instanceID: 0} 62 | additionalBone: 1 63 | animationType: 0 64 | userData: 65 | -------------------------------------------------------------------------------- /Assets/Models/Subdivided cube.blend.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 5720b8d3dc89af74a8f614137d1afd5b 3 | ModelImporter: 4 | serializedVersion: 15 5 | fileIDToRecycleName: 6 | 100000: //RootNode 7 | 400000: //RootNode 8 | 2300000: //RootNode 9 | 3300000: //RootNode 10 | 4300000: Cube 11 | 7400000: Default Take 12 | 9500000: //RootNode 13 | materials: 14 | importMaterials: 0 15 | materialName: 0 16 | materialSearch: 1 17 | animations: 18 | legacyGenerateAnimations: 4 19 | bakeSimulation: 0 20 | animationCompression: 1 21 | animationRotationError: .5 22 | animationPositionError: .5 23 | animationScaleError: .5 24 | animationWrapMode: 0 25 | clipAnimations: [] 26 | isReadable: 1 27 | meshes: 28 | lODScreenPercentages: [] 29 | globalScale: 1 30 | meshCompression: 0 31 | addColliders: 0 32 | importBlendShapes: 1 33 | swapUVChannels: 0 34 | generateSecondaryUV: 0 35 | useFileUnits: 1 36 | optimizeMeshForGPU: 1 37 | weldVertices: 1 38 | secondaryUVAngleDistortion: 8 39 | secondaryUVAreaDistortion: 15.000001 40 | secondaryUVHardAngle: 88 41 | secondaryUVPackMargin: 4 42 | tangentSpace: 43 | normalSmoothAngle: 60 44 | splitTangentsAcrossUV: 1 45 | normalImportMode: 1 46 | tangentImportMode: 1 47 | importAnimation: 1 48 | copyAvatar: 0 49 | humanDescription: 50 | human: [] 51 | skeleton: [] 52 | handles: [] 53 | armTwist: .5 54 | foreArmTwist: .5 55 | upperLegTwist: .5 56 | legTwist: .5 57 | armStretch: .0500000007 58 | legStretch: .0500000007 59 | feetSpacing: 0 60 | rootMotionBoneName: 61 | lastHumanDescriptionAvatarSource: {instanceID: 0} 62 | additionalBone: 1 63 | animationType: 0 64 | userData: 65 | -------------------------------------------------------------------------------- /Assets/Models/Balcony30.blend.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6ab159a584e789c43a6bb034daf826da 3 | ModelImporter: 4 | serializedVersion: 15 5 | fileIDToRecycleName: 6 | 100000: //RootNode 7 | 400000: //RootNode 8 | 2300000: //RootNode 9 | 3300000: //RootNode 10 | 4300000: Cube 11 | 4300002: Balcony 12 | 4300004: Balcony_3 13 | 4300006: Balcony30 14 | 7400000: Default Take 15 | 9500000: //RootNode 16 | materials: 17 | importMaterials: 0 18 | materialName: 0 19 | materialSearch: 1 20 | animations: 21 | legacyGenerateAnimations: 4 22 | bakeSimulation: 0 23 | animationCompression: 1 24 | animationRotationError: .5 25 | animationPositionError: .5 26 | animationScaleError: .5 27 | animationWrapMode: 0 28 | clipAnimations: [] 29 | isReadable: 1 30 | meshes: 31 | lODScreenPercentages: [] 32 | globalScale: 1 33 | meshCompression: 0 34 | addColliders: 0 35 | importBlendShapes: 1 36 | swapUVChannels: 0 37 | generateSecondaryUV: 0 38 | useFileUnits: 1 39 | optimizeMeshForGPU: 1 40 | weldVertices: 1 41 | secondaryUVAngleDistortion: 8 42 | secondaryUVAreaDistortion: 15.000001 43 | secondaryUVHardAngle: 88 44 | secondaryUVPackMargin: 4 45 | tangentSpace: 46 | normalSmoothAngle: 60 47 | splitTangentsAcrossUV: 1 48 | normalImportMode: 1 49 | tangentImportMode: 1 50 | importAnimation: 1 51 | copyAvatar: 0 52 | humanDescription: 53 | human: [] 54 | skeleton: [] 55 | handles: [] 56 | armTwist: .5 57 | foreArmTwist: .5 58 | upperLegTwist: .5 59 | legTwist: .5 60 | armStretch: .0500000007 61 | legStretch: .0500000007 62 | feetSpacing: 0 63 | rootMotionBoneName: 64 | lastHumanDescriptionAvatarSource: {instanceID: 0} 65 | additionalBone: 1 66 | animationType: 0 67 | userData: 68 | -------------------------------------------------------------------------------- /Assets/Models/Wall30.blend.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 999a42dcc1146554ea834988126242fb 3 | ModelImporter: 4 | serializedVersion: 15 5 | fileIDToRecycleName: 6 | 100000: //RootNode 7 | 400000: //RootNode 8 | 2300000: //RootNode 9 | 3300000: //RootNode 10 | 4300000: Cube 11 | 4300002: Balcony 12 | 4300004: Balcony_3 13 | 4300006: Wall_3 14 | 4300008: Wall30 15 | 7400000: Default Take 16 | 9500000: //RootNode 17 | materials: 18 | importMaterials: 0 19 | materialName: 0 20 | materialSearch: 1 21 | animations: 22 | legacyGenerateAnimations: 4 23 | bakeSimulation: 0 24 | animationCompression: 1 25 | animationRotationError: .5 26 | animationPositionError: .5 27 | animationScaleError: .5 28 | animationWrapMode: 0 29 | clipAnimations: [] 30 | isReadable: 1 31 | meshes: 32 | lODScreenPercentages: [] 33 | globalScale: 1 34 | meshCompression: 0 35 | addColliders: 0 36 | importBlendShapes: 1 37 | swapUVChannels: 0 38 | generateSecondaryUV: 0 39 | useFileUnits: 1 40 | optimizeMeshForGPU: 1 41 | weldVertices: 1 42 | secondaryUVAngleDistortion: 8 43 | secondaryUVAreaDistortion: 15.000001 44 | secondaryUVHardAngle: 88 45 | secondaryUVPackMargin: 4 46 | tangentSpace: 47 | normalSmoothAngle: 60 48 | splitTangentsAcrossUV: 1 49 | normalImportMode: 1 50 | tangentImportMode: 1 51 | importAnimation: 1 52 | copyAvatar: 0 53 | humanDescription: 54 | human: [] 55 | skeleton: [] 56 | handles: [] 57 | armTwist: .5 58 | foreArmTwist: .5 59 | upperLegTwist: .5 60 | legTwist: .5 61 | armStretch: .0500000007 62 | legStretch: .0500000007 63 | feetSpacing: 0 64 | rootMotionBoneName: 65 | lastHumanDescriptionAvatarSource: {instanceID: 0} 66 | additionalBone: 1 67 | animationType: 0 68 | userData: 69 | -------------------------------------------------------------------------------- /Assets/Models/Balcony30Glazed.blend.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d8f5d47cbabd7a74b8c9ddacefaa7a5e 3 | ModelImporter: 4 | serializedVersion: 15 5 | fileIDToRecycleName: 6 | 100000: //RootNode 7 | 400000: //RootNode 8 | 2300000: //RootNode 9 | 3300000: //RootNode 10 | 4300000: Cube 11 | 4300002: Balcony 12 | 4300004: Balcony_3 13 | 4300006: Balcony30 14 | 4300008: Balcony30Glazed 15 | 7400000: Default Take 16 | 9500000: //RootNode 17 | materials: 18 | importMaterials: 0 19 | materialName: 0 20 | materialSearch: 1 21 | animations: 22 | legacyGenerateAnimations: 4 23 | bakeSimulation: 0 24 | animationCompression: 1 25 | animationRotationError: .5 26 | animationPositionError: .5 27 | animationScaleError: .5 28 | animationWrapMode: 0 29 | clipAnimations: [] 30 | isReadable: 1 31 | meshes: 32 | lODScreenPercentages: [] 33 | globalScale: 1 34 | meshCompression: 0 35 | addColliders: 0 36 | importBlendShapes: 1 37 | swapUVChannels: 0 38 | generateSecondaryUV: 0 39 | useFileUnits: 1 40 | optimizeMeshForGPU: 1 41 | weldVertices: 1 42 | secondaryUVAngleDistortion: 8 43 | secondaryUVAreaDistortion: 15.000001 44 | secondaryUVHardAngle: 88 45 | secondaryUVPackMargin: 4 46 | tangentSpace: 47 | normalSmoothAngle: 60 48 | splitTangentsAcrossUV: 1 49 | normalImportMode: 1 50 | tangentImportMode: 1 51 | importAnimation: 1 52 | copyAvatar: 0 53 | humanDescription: 54 | human: [] 55 | skeleton: [] 56 | handles: [] 57 | armTwist: .5 58 | foreArmTwist: .5 59 | upperLegTwist: .5 60 | legTwist: .5 61 | armStretch: .0500000007 62 | legStretch: .0500000007 63 | feetSpacing: 0 64 | rootMotionBoneName: 65 | lastHumanDescriptionAvatarSource: {instanceID: 0} 66 | additionalBone: 1 67 | animationType: 0 68 | userData: 69 | -------------------------------------------------------------------------------- /Assets/Models/Roof.blend.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d9e7ff422b811cb4386c831949af38b7 3 | ModelImporter: 4 | serializedVersion: 15 5 | fileIDToRecycleName: 6 | 100000: //RootNode 7 | 400000: //RootNode 8 | 2300000: //RootNode 9 | 3300000: //RootNode 10 | 4300000: Cube 11 | 4300002: Balcony 12 | 4300004: Balcony_3 13 | 4300006: Wall_3 14 | 4300008: Wall30 15 | 4300010: Roof 16 | 7400000: Default Take 17 | 9500000: //RootNode 18 | materials: 19 | importMaterials: 0 20 | materialName: 0 21 | materialSearch: 1 22 | animations: 23 | legacyGenerateAnimations: 4 24 | bakeSimulation: 0 25 | animationCompression: 1 26 | animationRotationError: .5 27 | animationPositionError: .5 28 | animationScaleError: .5 29 | animationWrapMode: 0 30 | clipAnimations: [] 31 | isReadable: 1 32 | meshes: 33 | lODScreenPercentages: [] 34 | globalScale: 1 35 | meshCompression: 0 36 | addColliders: 0 37 | importBlendShapes: 1 38 | swapUVChannels: 0 39 | generateSecondaryUV: 0 40 | useFileUnits: 1 41 | optimizeMeshForGPU: 1 42 | weldVertices: 1 43 | secondaryUVAngleDistortion: 8 44 | secondaryUVAreaDistortion: 15.000001 45 | secondaryUVHardAngle: 88 46 | secondaryUVPackMargin: 4 47 | tangentSpace: 48 | normalSmoothAngle: 60 49 | splitTangentsAcrossUV: 1 50 | normalImportMode: 1 51 | tangentImportMode: 1 52 | importAnimation: 1 53 | copyAvatar: 0 54 | humanDescription: 55 | human: [] 56 | skeleton: [] 57 | handles: [] 58 | armTwist: .5 59 | foreArmTwist: .5 60 | upperLegTwist: .5 61 | legTwist: .5 62 | armStretch: .0500000007 63 | legStretch: .0500000007 64 | feetSpacing: 0 65 | rootMotionBoneName: 66 | lastHumanDescriptionAvatarSource: {instanceID: 0} 67 | additionalBone: 1 68 | animationType: 0 69 | userData: 70 | -------------------------------------------------------------------------------- /Assets/Models/Wall25.blend.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ff4586b46052c1a4bb6ec435a679e404 3 | ModelImporter: 4 | serializedVersion: 15 5 | fileIDToRecycleName: 6 | 100000: //RootNode 7 | 400000: //RootNode 8 | 2300000: //RootNode 9 | 3300000: //RootNode 10 | 4300000: Cube 11 | 4300002: Balcony 12 | 4300004: Balcony_3 13 | 4300006: Wall_3 14 | 4300008: Wall_2_5 15 | 4300010: Wall25 16 | 7400000: Default Take 17 | 9500000: //RootNode 18 | materials: 19 | importMaterials: 0 20 | materialName: 0 21 | materialSearch: 1 22 | animations: 23 | legacyGenerateAnimations: 4 24 | bakeSimulation: 0 25 | animationCompression: 1 26 | animationRotationError: .5 27 | animationPositionError: .5 28 | animationScaleError: .5 29 | animationWrapMode: 0 30 | clipAnimations: [] 31 | isReadable: 1 32 | meshes: 33 | lODScreenPercentages: [] 34 | globalScale: 1 35 | meshCompression: 0 36 | addColliders: 0 37 | importBlendShapes: 1 38 | swapUVChannels: 0 39 | generateSecondaryUV: 0 40 | useFileUnits: 1 41 | optimizeMeshForGPU: 1 42 | weldVertices: 1 43 | secondaryUVAngleDistortion: 8 44 | secondaryUVAreaDistortion: 15.000001 45 | secondaryUVHardAngle: 88 46 | secondaryUVPackMargin: 4 47 | tangentSpace: 48 | normalSmoothAngle: 60 49 | splitTangentsAcrossUV: 1 50 | normalImportMode: 1 51 | tangentImportMode: 1 52 | importAnimation: 1 53 | copyAvatar: 0 54 | humanDescription: 55 | human: [] 56 | skeleton: [] 57 | handles: [] 58 | armTwist: .5 59 | foreArmTwist: .5 60 | upperLegTwist: .5 61 | legTwist: .5 62 | armStretch: .0500000007 63 | legStretch: .0500000007 64 | feetSpacing: 0 65 | rootMotionBoneName: 66 | lastHumanDescriptionAvatarSource: {instanceID: 0} 67 | additionalBone: 1 68 | animationType: 0 69 | userData: 70 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # This repository is obsolete. Latest version can be found in [ProceduralToolkit](https://github.com/Syomus/ProceduralToolkit). 2 | 3 | # Этот репозиторий устарел. Последнюю версию смотрите в [ProceduralToolkit](https://github.com/Syomus/ProceduralToolkit). 4 | 5 | ProceduralExperiments 6 | ===================== 7 | Эксперименты с процедурной генерацией на Unity3d 8 | 9 | Khrushchyovka.cs 10 | ========= 11 | ![](http://habrastorage.org/storage3/89c/fff/2e1/89cfff2e16ab381631314d16c708c72b.gif)![](http://habrastorage.org/storage3/fde/d2f/3ed/fded2f3ed9e9cfcf44189cc5d904dfb2.gif) 12 | 13 | http://basmanovdaniil.github.io/ProceduralExperiments/Khrushchyovka.html 14 | 15 | Процедурный генератор хрущёвок 16 | 17 | Левая кнопка мыши — новое здание 18 | 19 | Esc — Выход 20 | 21 | PGMesh.cs 22 | ========= 23 | ![](http://habrastorage.org/storage3/7f0/31f/a43/7f031fa43c1e01f86e8cff846d7b374c.gif) 24 | 25 | http://basmanovdaniil.github.io/ProceduralExperiments/Web%20PGMesh.html 26 | 27 | Процедурный генератор моделей 28 | 29 | Esc — Выход 30 | 31 | FloorPlanGenerator.cs 32 | ===================== 33 | ![](http://habrastorage.org/storage3/892/79b/f71/89279bf71aa5805035cef1971384688c.gif)![](http://habrastorage.org/storage3/98f/adf/25b/98fadf25b287a1a94ed5dc37317ce33c.gif)![](http://habrastorage.org/storage3/a3d/29e/999/a3d29e9990f722f9626780f786300d17.gif) 34 | 35 | http://basmanovdaniil.github.io/ProceduralExperiments/index.html 36 | 37 | Процедурный генератор планов помещений на Unity3d. 38 | 39 | Shift — Создаёт случайные внешние стены со случайными комнатами 40 | 41 | Ctrl — Загрузить тестовую текстуру со случайными комнатами 42 | 43 | Enter — Убрать все комнаты и загрузить тестовую текстуру 44 | 45 | Пробел — Остановить рост комнат 46 | 47 | Единица на алфавитной клавиатуре — Включить визуализацию поиска свободных клеток 48 | 49 | Левая кнопка мыши на свободной области — Добавить комнату 50 | 51 | Esc — Выход 52 | 53 | 54 | -------------------------------------------------------------------------------- /Assets/Models/Balcony25Glazed.blend.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 72d1dce8d1cb5554390625e165940eec 3 | ModelImporter: 4 | serializedVersion: 15 5 | fileIDToRecycleName: 6 | 100000: //RootNode 7 | 400000: //RootNode 8 | 2300000: //RootNode 9 | 3300000: //RootNode 10 | 4300000: Cube 11 | 4300002: Balcony 12 | 4300004: Balcony_3 13 | 4300006: Balcony30 14 | 4300008: Balcony30Glazed 15 | 4300010: Balcony25Glazed 16 | 7400000: Default Take 17 | 9500000: //RootNode 18 | materials: 19 | importMaterials: 0 20 | materialName: 0 21 | materialSearch: 1 22 | animations: 23 | legacyGenerateAnimations: 4 24 | bakeSimulation: 0 25 | animationCompression: 1 26 | animationRotationError: .5 27 | animationPositionError: .5 28 | animationScaleError: .5 29 | animationWrapMode: 0 30 | clipAnimations: [] 31 | isReadable: 1 32 | meshes: 33 | lODScreenPercentages: [] 34 | globalScale: 1 35 | meshCompression: 0 36 | addColliders: 0 37 | importBlendShapes: 1 38 | swapUVChannels: 0 39 | generateSecondaryUV: 0 40 | useFileUnits: 1 41 | optimizeMeshForGPU: 1 42 | weldVertices: 1 43 | secondaryUVAngleDistortion: 8 44 | secondaryUVAreaDistortion: 15.000001 45 | secondaryUVHardAngle: 88 46 | secondaryUVPackMargin: 4 47 | tangentSpace: 48 | normalSmoothAngle: 60 49 | splitTangentsAcrossUV: 1 50 | normalImportMode: 1 51 | tangentImportMode: 1 52 | importAnimation: 1 53 | copyAvatar: 0 54 | humanDescription: 55 | human: [] 56 | skeleton: [] 57 | handles: [] 58 | armTwist: .5 59 | foreArmTwist: .5 60 | upperLegTwist: .5 61 | legTwist: .5 62 | armStretch: .0500000007 63 | legStretch: .0500000007 64 | feetSpacing: 0 65 | rootMotionBoneName: 66 | lastHumanDescriptionAvatarSource: {instanceID: 0} 67 | additionalBone: 1 68 | animationType: 0 69 | userData: 70 | -------------------------------------------------------------------------------- /Assets/Models/RoofHipped.blend.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6ae1d070abc030a4f9ba71fe4ecb23fd 3 | ModelImporter: 4 | serializedVersion: 15 5 | fileIDToRecycleName: 6 | 100000: //RootNode 7 | 400000: //RootNode 8 | 2300000: //RootNode 9 | 3300000: //RootNode 10 | 4300000: Cube 11 | 4300002: Balcony 12 | 4300004: Balcony_3 13 | 4300006: Wall_3 14 | 4300008: Wall30 15 | 4300010: Roof 16 | 4300012: RoofHipped 17 | 7400000: Default Take 18 | 9500000: //RootNode 19 | materials: 20 | importMaterials: 0 21 | materialName: 0 22 | materialSearch: 1 23 | animations: 24 | legacyGenerateAnimations: 4 25 | bakeSimulation: 0 26 | animationCompression: 1 27 | animationRotationError: .5 28 | animationPositionError: .5 29 | animationScaleError: .5 30 | animationWrapMode: 0 31 | clipAnimations: [] 32 | isReadable: 1 33 | meshes: 34 | lODScreenPercentages: [] 35 | globalScale: 1 36 | meshCompression: 0 37 | addColliders: 0 38 | importBlendShapes: 1 39 | swapUVChannels: 0 40 | generateSecondaryUV: 0 41 | useFileUnits: 1 42 | optimizeMeshForGPU: 1 43 | weldVertices: 1 44 | secondaryUVAngleDistortion: 8 45 | secondaryUVAreaDistortion: 15.000001 46 | secondaryUVHardAngle: 88 47 | secondaryUVPackMargin: 4 48 | tangentSpace: 49 | normalSmoothAngle: 60 50 | splitTangentsAcrossUV: 1 51 | normalImportMode: 1 52 | tangentImportMode: 1 53 | importAnimation: 1 54 | copyAvatar: 0 55 | humanDescription: 56 | human: [] 57 | skeleton: [] 58 | handles: [] 59 | armTwist: .5 60 | foreArmTwist: .5 61 | upperLegTwist: .5 62 | legTwist: .5 63 | armStretch: .0500000007 64 | legStretch: .0500000007 65 | feetSpacing: 0 66 | rootMotionBoneName: 67 | lastHumanDescriptionAvatarSource: {instanceID: 0} 68 | additionalBone: 1 69 | animationType: 0 70 | userData: 71 | -------------------------------------------------------------------------------- /Assets/Models/Socle25.blend.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 8e8b5a9ffb4b7394c9a310c918434b9c 3 | ModelImporter: 4 | serializedVersion: 15 5 | fileIDToRecycleName: 6 | 100000: //RootNode 7 | 400000: //RootNode 8 | 2300000: //RootNode 9 | 3300000: //RootNode 10 | 4300000: Cube 11 | 4300002: Balcony 12 | 4300004: Balcony_3 13 | 4300006: Wall_3 14 | 4300008: Wall_2_5 15 | 4300010: Socle_2_5 16 | 4300012: Socle25 17 | 7400000: Default Take 18 | 9500000: //RootNode 19 | materials: 20 | importMaterials: 0 21 | materialName: 0 22 | materialSearch: 1 23 | animations: 24 | legacyGenerateAnimations: 4 25 | bakeSimulation: 0 26 | animationCompression: 1 27 | animationRotationError: .5 28 | animationPositionError: .5 29 | animationScaleError: .5 30 | animationWrapMode: 0 31 | clipAnimations: [] 32 | isReadable: 1 33 | meshes: 34 | lODScreenPercentages: [] 35 | globalScale: 1 36 | meshCompression: 0 37 | addColliders: 0 38 | importBlendShapes: 1 39 | swapUVChannels: 0 40 | generateSecondaryUV: 0 41 | useFileUnits: 1 42 | optimizeMeshForGPU: 1 43 | weldVertices: 1 44 | secondaryUVAngleDistortion: 8 45 | secondaryUVAreaDistortion: 15.000001 46 | secondaryUVHardAngle: 88 47 | secondaryUVPackMargin: 4 48 | tangentSpace: 49 | normalSmoothAngle: 60 50 | splitTangentsAcrossUV: 1 51 | normalImportMode: 1 52 | tangentImportMode: 1 53 | importAnimation: 1 54 | copyAvatar: 0 55 | humanDescription: 56 | human: [] 57 | skeleton: [] 58 | handles: [] 59 | armTwist: .5 60 | foreArmTwist: .5 61 | upperLegTwist: .5 62 | legTwist: .5 63 | armStretch: .0500000007 64 | legStretch: .0500000007 65 | feetSpacing: 0 66 | rootMotionBoneName: 67 | lastHumanDescriptionAvatarSource: {instanceID: 0} 68 | additionalBone: 1 69 | animationType: 0 70 | userData: 71 | -------------------------------------------------------------------------------- /Assets/Models/Window25.blend.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 119e0c314fb7f5143991fb54ec244d78 3 | ModelImporter: 4 | serializedVersion: 15 5 | fileIDToRecycleName: 6 | 100000: //RootNode 7 | 400000: //RootNode 8 | 2300000: //RootNode 9 | 3300000: //RootNode 10 | 4300000: Cube 11 | 4300002: Balcony 12 | 4300004: Balcony_3 13 | 4300006: Wall_3 14 | 4300008: Wall_2_5 15 | 4300010: Window_2_5 16 | 4300012: Window25 17 | 7400000: Default Take 18 | 9500000: //RootNode 19 | materials: 20 | importMaterials: 0 21 | materialName: 0 22 | materialSearch: 1 23 | animations: 24 | legacyGenerateAnimations: 4 25 | bakeSimulation: 0 26 | animationCompression: 1 27 | animationRotationError: .5 28 | animationPositionError: .5 29 | animationScaleError: .5 30 | animationWrapMode: 0 31 | clipAnimations: [] 32 | isReadable: 1 33 | meshes: 34 | lODScreenPercentages: [] 35 | globalScale: 1 36 | meshCompression: 0 37 | addColliders: 0 38 | importBlendShapes: 1 39 | swapUVChannels: 0 40 | generateSecondaryUV: 0 41 | useFileUnits: 1 42 | optimizeMeshForGPU: 1 43 | weldVertices: 1 44 | secondaryUVAngleDistortion: 8 45 | secondaryUVAreaDistortion: 15.000001 46 | secondaryUVHardAngle: 88 47 | secondaryUVPackMargin: 4 48 | tangentSpace: 49 | normalSmoothAngle: 60 50 | splitTangentsAcrossUV: 1 51 | normalImportMode: 1 52 | tangentImportMode: 1 53 | importAnimation: 1 54 | copyAvatar: 0 55 | humanDescription: 56 | human: [] 57 | skeleton: [] 58 | handles: [] 59 | armTwist: .5 60 | foreArmTwist: .5 61 | upperLegTwist: .5 62 | legTwist: .5 63 | armStretch: .0500000007 64 | legStretch: .0500000007 65 | feetSpacing: 0 66 | rootMotionBoneName: 67 | lastHumanDescriptionAvatarSource: {instanceID: 0} 68 | additionalBone: 1 69 | animationType: 0 70 | userData: 71 | -------------------------------------------------------------------------------- /Assets/Models/Entrance25.blend.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f49c89b43c6b1c74fb7fe994ae50040f 3 | ModelImporter: 4 | serializedVersion: 15 5 | fileIDToRecycleName: 6 | 100000: //RootNode 7 | 400000: //RootNode 8 | 2300000: //RootNode 9 | 3300000: //RootNode 10 | 4300000: Cube 11 | 4300002: Balcony 12 | 4300004: Balcony_3 13 | 4300006: Wall_3 14 | 4300008: Wall_2_5 15 | 4300010: Entrance_2_5 16 | 4300012: Entrance25 17 | 7400000: Default Take 18 | 9500000: //RootNode 19 | materials: 20 | importMaterials: 0 21 | materialName: 0 22 | materialSearch: 1 23 | animations: 24 | legacyGenerateAnimations: 4 25 | bakeSimulation: 0 26 | animationCompression: 1 27 | animationRotationError: .5 28 | animationPositionError: .5 29 | animationScaleError: .5 30 | animationWrapMode: 0 31 | clipAnimations: [] 32 | isReadable: 1 33 | meshes: 34 | lODScreenPercentages: [] 35 | globalScale: 1 36 | meshCompression: 0 37 | addColliders: 0 38 | importBlendShapes: 1 39 | swapUVChannels: 0 40 | generateSecondaryUV: 0 41 | useFileUnits: 1 42 | optimizeMeshForGPU: 1 43 | weldVertices: 1 44 | secondaryUVAngleDistortion: 8 45 | secondaryUVAreaDistortion: 15.000001 46 | secondaryUVHardAngle: 88 47 | secondaryUVPackMargin: 4 48 | tangentSpace: 49 | normalSmoothAngle: 60 50 | splitTangentsAcrossUV: 1 51 | normalImportMode: 1 52 | tangentImportMode: 1 53 | importAnimation: 1 54 | copyAvatar: 0 55 | humanDescription: 56 | human: [] 57 | skeleton: [] 58 | handles: [] 59 | armTwist: .5 60 | foreArmTwist: .5 61 | upperLegTwist: .5 62 | legTwist: .5 63 | armStretch: .0500000007 64 | legStretch: .0500000007 65 | feetSpacing: 0 66 | rootMotionBoneName: 67 | lastHumanDescriptionAvatarSource: {instanceID: 0} 68 | additionalBone: 1 69 | animationType: 0 70 | userData: 71 | -------------------------------------------------------------------------------- /Assets/Models/Socle30.blend.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 9a36a5536ff00734eac8e5bd88007d7d 3 | ModelImporter: 4 | serializedVersion: 15 5 | fileIDToRecycleName: 6 | 100000: //RootNode 7 | 400000: //RootNode 8 | 2300000: //RootNode 9 | 3300000: //RootNode 10 | 4300000: Cube 11 | 4300002: Balcony 12 | 4300004: Balcony_3 13 | 4300006: Wall_3 14 | 4300008: Wall_2_5 15 | 4300010: Socle_2_5 16 | 4300012: Socle_3 17 | 4300014: Socle30 18 | 7400000: Default Take 19 | 9500000: //RootNode 20 | materials: 21 | importMaterials: 0 22 | materialName: 0 23 | materialSearch: 1 24 | animations: 25 | legacyGenerateAnimations: 4 26 | bakeSimulation: 0 27 | animationCompression: 1 28 | animationRotationError: .5 29 | animationPositionError: .5 30 | animationScaleError: .5 31 | animationWrapMode: 0 32 | clipAnimations: [] 33 | isReadable: 1 34 | meshes: 35 | lODScreenPercentages: [] 36 | globalScale: 1 37 | meshCompression: 0 38 | addColliders: 0 39 | importBlendShapes: 1 40 | swapUVChannels: 0 41 | generateSecondaryUV: 0 42 | useFileUnits: 1 43 | optimizeMeshForGPU: 1 44 | weldVertices: 1 45 | secondaryUVAngleDistortion: 8 46 | secondaryUVAreaDistortion: 15.000001 47 | secondaryUVHardAngle: 88 48 | secondaryUVPackMargin: 4 49 | tangentSpace: 50 | normalSmoothAngle: 60 51 | splitTangentsAcrossUV: 1 52 | normalImportMode: 1 53 | tangentImportMode: 1 54 | importAnimation: 1 55 | copyAvatar: 0 56 | humanDescription: 57 | human: [] 58 | skeleton: [] 59 | handles: [] 60 | armTwist: .5 61 | foreArmTwist: .5 62 | upperLegTwist: .5 63 | legTwist: .5 64 | armStretch: .0500000007 65 | legStretch: .0500000007 66 | feetSpacing: 0 67 | rootMotionBoneName: 68 | lastHumanDescriptionAvatarSource: {instanceID: 0} 69 | additionalBone: 1 70 | animationType: 0 71 | userData: 72 | -------------------------------------------------------------------------------- /Assets/Models/RoofGabled.blend.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a51daf9a2963b8641903770312b009b8 3 | ModelImporter: 4 | serializedVersion: 15 5 | fileIDToRecycleName: 6 | 100000: //RootNode 7 | 400000: //RootNode 8 | 2300000: //RootNode 9 | 3300000: //RootNode 10 | 4300000: Cube 11 | 4300002: Balcony 12 | 4300004: Balcony_3 13 | 4300006: Wall_3 14 | 4300008: Wall30 15 | 4300010: Roof 16 | 4300012: RoofHipped 17 | 4300014: RoofGabled 18 | 7400000: Default Take 19 | 9500000: //RootNode 20 | materials: 21 | importMaterials: 0 22 | materialName: 0 23 | materialSearch: 1 24 | animations: 25 | legacyGenerateAnimations: 4 26 | bakeSimulation: 0 27 | animationCompression: 1 28 | animationRotationError: .5 29 | animationPositionError: .5 30 | animationScaleError: .5 31 | animationWrapMode: 0 32 | clipAnimations: [] 33 | isReadable: 1 34 | meshes: 35 | lODScreenPercentages: [] 36 | globalScale: 1 37 | meshCompression: 0 38 | addColliders: 0 39 | importBlendShapes: 1 40 | swapUVChannels: 0 41 | generateSecondaryUV: 0 42 | useFileUnits: 1 43 | optimizeMeshForGPU: 1 44 | weldVertices: 1 45 | secondaryUVAngleDistortion: 8 46 | secondaryUVAreaDistortion: 15.000001 47 | secondaryUVHardAngle: 88 48 | secondaryUVPackMargin: 4 49 | tangentSpace: 50 | normalSmoothAngle: 60 51 | splitTangentsAcrossUV: 1 52 | normalImportMode: 1 53 | tangentImportMode: 1 54 | importAnimation: 1 55 | copyAvatar: 0 56 | humanDescription: 57 | human: [] 58 | skeleton: [] 59 | handles: [] 60 | armTwist: .5 61 | foreArmTwist: .5 62 | upperLegTwist: .5 63 | legTwist: .5 64 | armStretch: .0500000007 65 | legStretch: .0500000007 66 | feetSpacing: 0 67 | rootMotionBoneName: 68 | lastHumanDescriptionAvatarSource: {instanceID: 0} 69 | additionalBone: 1 70 | animationType: 0 71 | userData: 72 | -------------------------------------------------------------------------------- /Assets/Models/Entrance30.blend.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 3c7275262f8e93c42bda870429b8265d 3 | ModelImporter: 4 | serializedVersion: 15 5 | fileIDToRecycleName: 6 | 100000: //RootNode 7 | 400000: //RootNode 8 | 2300000: //RootNode 9 | 3300000: //RootNode 10 | 4300000: Cube 11 | 4300002: Balcony 12 | 4300004: Balcony_3 13 | 4300006: Wall_3 14 | 4300008: Wall_2_5 15 | 4300010: Entrance_2_5 16 | 4300012: Entrance_3 17 | 4300014: Entrance30 18 | 7400000: Default Take 19 | 9500000: //RootNode 20 | materials: 21 | importMaterials: 0 22 | materialName: 0 23 | materialSearch: 1 24 | animations: 25 | legacyGenerateAnimations: 4 26 | bakeSimulation: 0 27 | animationCompression: 1 28 | animationRotationError: .5 29 | animationPositionError: .5 30 | animationScaleError: .5 31 | animationWrapMode: 0 32 | clipAnimations: [] 33 | isReadable: 1 34 | meshes: 35 | lODScreenPercentages: [] 36 | globalScale: 1 37 | meshCompression: 0 38 | addColliders: 0 39 | importBlendShapes: 1 40 | swapUVChannels: 0 41 | generateSecondaryUV: 0 42 | useFileUnits: 1 43 | optimizeMeshForGPU: 1 44 | weldVertices: 1 45 | secondaryUVAngleDistortion: 8 46 | secondaryUVAreaDistortion: 15.000001 47 | secondaryUVHardAngle: 88 48 | secondaryUVPackMargin: 4 49 | tangentSpace: 50 | normalSmoothAngle: 60 51 | splitTangentsAcrossUV: 1 52 | normalImportMode: 1 53 | tangentImportMode: 1 54 | importAnimation: 1 55 | copyAvatar: 0 56 | humanDescription: 57 | human: [] 58 | skeleton: [] 59 | handles: [] 60 | armTwist: .5 61 | foreArmTwist: .5 62 | upperLegTwist: .5 63 | legTwist: .5 64 | armStretch: .0500000007 65 | legStretch: .0500000007 66 | feetSpacing: 0 67 | rootMotionBoneName: 68 | lastHumanDescriptionAvatarSource: {instanceID: 0} 69 | additionalBone: 1 70 | animationType: 0 71 | userData: 72 | -------------------------------------------------------------------------------- /Assets/Models/EntranceWall25.blend.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 417e68a68f651df4e8108734d482caea 3 | ModelImporter: 4 | serializedVersion: 15 5 | fileIDToRecycleName: 6 | 100000: //RootNode 7 | 400000: //RootNode 8 | 2300000: //RootNode 9 | 3300000: //RootNode 10 | 4300000: Cube 11 | 4300002: Balcony 12 | 4300004: Balcony_3 13 | 4300006: Wall_3 14 | 4300008: Wall_2_5 15 | 4300010: Window_2_5 16 | 4300012: Window25 17 | 4300014: EntranceWall25 18 | 7400000: Default Take 19 | 9500000: //RootNode 20 | materials: 21 | importMaterials: 0 22 | materialName: 0 23 | materialSearch: 1 24 | animations: 25 | legacyGenerateAnimations: 4 26 | bakeSimulation: 0 27 | animationCompression: 1 28 | animationRotationError: .5 29 | animationPositionError: .5 30 | animationScaleError: .5 31 | animationWrapMode: 0 32 | clipAnimations: [] 33 | isReadable: 1 34 | meshes: 35 | lODScreenPercentages: [] 36 | globalScale: 1 37 | meshCompression: 0 38 | addColliders: 0 39 | importBlendShapes: 1 40 | swapUVChannels: 0 41 | generateSecondaryUV: 0 42 | useFileUnits: 1 43 | optimizeMeshForGPU: 1 44 | weldVertices: 1 45 | secondaryUVAngleDistortion: 8 46 | secondaryUVAreaDistortion: 15.000001 47 | secondaryUVHardAngle: 88 48 | secondaryUVPackMargin: 4 49 | tangentSpace: 50 | normalSmoothAngle: 60 51 | splitTangentsAcrossUV: 1 52 | normalImportMode: 1 53 | tangentImportMode: 1 54 | importAnimation: 1 55 | copyAvatar: 0 56 | humanDescription: 57 | human: [] 58 | skeleton: [] 59 | handles: [] 60 | armTwist: .5 61 | foreArmTwist: .5 62 | upperLegTwist: .5 63 | legTwist: .5 64 | armStretch: .0500000007 65 | legStretch: .0500000007 66 | feetSpacing: 0 67 | rootMotionBoneName: 68 | lastHumanDescriptionAvatarSource: {instanceID: 0} 69 | additionalBone: 1 70 | animationType: 0 71 | userData: 72 | -------------------------------------------------------------------------------- /Assets/Models/EntranceWallLast25.blend.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a2d951f3c83bd634689ccef5c083d09e 3 | ModelImporter: 4 | serializedVersion: 15 5 | fileIDToRecycleName: 6 | 100000: //RootNode 7 | 400000: //RootNode 8 | 2300000: //RootNode 9 | 3300000: //RootNode 10 | 4300000: Cube 11 | 4300002: Balcony 12 | 4300004: Balcony_3 13 | 4300006: Wall_3 14 | 4300008: Wall_2_5 15 | 4300010: Socle_2_5 16 | 4300012: Entrance_Wall_Last_2_5 17 | 4300014: EntranceWallLast25 18 | 7400000: Default Take 19 | 9500000: //RootNode 20 | materials: 21 | importMaterials: 0 22 | materialName: 0 23 | materialSearch: 1 24 | animations: 25 | legacyGenerateAnimations: 4 26 | bakeSimulation: 0 27 | animationCompression: 1 28 | animationRotationError: .5 29 | animationPositionError: .5 30 | animationScaleError: .5 31 | animationWrapMode: 0 32 | clipAnimations: [] 33 | isReadable: 1 34 | meshes: 35 | lODScreenPercentages: [] 36 | globalScale: 1 37 | meshCompression: 0 38 | addColliders: 0 39 | importBlendShapes: 1 40 | swapUVChannels: 0 41 | generateSecondaryUV: 0 42 | useFileUnits: 1 43 | optimizeMeshForGPU: 1 44 | weldVertices: 1 45 | secondaryUVAngleDistortion: 8 46 | secondaryUVAreaDistortion: 15.000001 47 | secondaryUVHardAngle: 88 48 | secondaryUVPackMargin: 4 49 | tangentSpace: 50 | normalSmoothAngle: 60 51 | splitTangentsAcrossUV: 1 52 | normalImportMode: 1 53 | tangentImportMode: 1 54 | importAnimation: 1 55 | copyAvatar: 0 56 | humanDescription: 57 | human: [] 58 | skeleton: [] 59 | handles: [] 60 | armTwist: .5 61 | foreArmTwist: .5 62 | upperLegTwist: .5 63 | legTwist: .5 64 | armStretch: .0500000007 65 | legStretch: .0500000007 66 | feetSpacing: 0 67 | rootMotionBoneName: 68 | lastHumanDescriptionAvatarSource: {instanceID: 0} 69 | additionalBone: 1 70 | animationType: 0 71 | userData: 72 | -------------------------------------------------------------------------------- /Assets/Models/EntranceWall30.blend.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 206b54576d5a81a41b655d502d0ff8e2 3 | ModelImporter: 4 | serializedVersion: 15 5 | fileIDToRecycleName: 6 | 100000: //RootNode 7 | 400000: //RootNode 8 | 2300000: //RootNode 9 | 3300000: //RootNode 10 | 4300000: Cube 11 | 4300002: Balcony 12 | 4300004: Balcony_3 13 | 4300006: Wall_3 14 | 4300008: Wall_2_5 15 | 4300010: Window_2_5 16 | 4300012: Window25 17 | 4300014: EntranceWall25 18 | 4300016: EntranceWall30 19 | 7400000: Default Take 20 | 9500000: //RootNode 21 | materials: 22 | importMaterials: 0 23 | materialName: 0 24 | materialSearch: 1 25 | animations: 26 | legacyGenerateAnimations: 4 27 | bakeSimulation: 0 28 | animationCompression: 1 29 | animationRotationError: .5 30 | animationPositionError: .5 31 | animationScaleError: .5 32 | animationWrapMode: 0 33 | clipAnimations: [] 34 | isReadable: 1 35 | meshes: 36 | lODScreenPercentages: [] 37 | globalScale: 1 38 | meshCompression: 0 39 | addColliders: 0 40 | importBlendShapes: 1 41 | swapUVChannels: 0 42 | generateSecondaryUV: 0 43 | useFileUnits: 1 44 | optimizeMeshForGPU: 1 45 | weldVertices: 1 46 | secondaryUVAngleDistortion: 8 47 | secondaryUVAreaDistortion: 15.000001 48 | secondaryUVHardAngle: 88 49 | secondaryUVPackMargin: 4 50 | tangentSpace: 51 | normalSmoothAngle: 60 52 | splitTangentsAcrossUV: 1 53 | normalImportMode: 1 54 | tangentImportMode: 1 55 | importAnimation: 1 56 | copyAvatar: 0 57 | humanDescription: 58 | human: [] 59 | skeleton: [] 60 | handles: [] 61 | armTwist: .5 62 | foreArmTwist: .5 63 | upperLegTwist: .5 64 | legTwist: .5 65 | armStretch: .0500000007 66 | legStretch: .0500000007 67 | feetSpacing: 0 68 | rootMotionBoneName: 69 | lastHumanDescriptionAvatarSource: {instanceID: 0} 70 | additionalBone: 1 71 | animationType: 0 72 | userData: 73 | -------------------------------------------------------------------------------- /Assets/Models/Attic25.blend.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 49925369ed3ad1f4d90fb4d56be15d1b 3 | ModelImporter: 4 | serializedVersion: 15 5 | fileIDToRecycleName: 6 | 100000: //RootNode 7 | 400000: //RootNode 8 | 2300000: //RootNode 9 | 3300000: //RootNode 10 | 4300000: Cube 11 | 4300002: Balcony 12 | 4300004: Balcony_3 13 | 4300006: Wall_3 14 | 4300008: Wall_2_5 15 | 4300010: Socle_2_5 16 | 4300012: Entrance_Wall_Last_2_5 17 | 4300014: EntranceWallLast25 18 | 4300016: Attic25 19 | 7400000: Default Take 20 | 9500000: //RootNode 21 | materials: 22 | importMaterials: 0 23 | materialName: 0 24 | materialSearch: 1 25 | animations: 26 | legacyGenerateAnimations: 4 27 | bakeSimulation: 0 28 | animationCompression: 1 29 | animationRotationError: .5 30 | animationPositionError: .5 31 | animationScaleError: .5 32 | animationWrapMode: 0 33 | clipAnimations: [] 34 | isReadable: 1 35 | meshes: 36 | lODScreenPercentages: [] 37 | globalScale: 1 38 | meshCompression: 0 39 | addColliders: 0 40 | importBlendShapes: 1 41 | swapUVChannels: 0 42 | generateSecondaryUV: 0 43 | useFileUnits: 1 44 | optimizeMeshForGPU: 1 45 | weldVertices: 1 46 | secondaryUVAngleDistortion: 8 47 | secondaryUVAreaDistortion: 15.000001 48 | secondaryUVHardAngle: 88 49 | secondaryUVPackMargin: 4 50 | tangentSpace: 51 | normalSmoothAngle: 60 52 | splitTangentsAcrossUV: 1 53 | normalImportMode: 1 54 | tangentImportMode: 1 55 | importAnimation: 1 56 | copyAvatar: 0 57 | humanDescription: 58 | human: [] 59 | skeleton: [] 60 | handles: [] 61 | armTwist: .5 62 | foreArmTwist: .5 63 | upperLegTwist: .5 64 | legTwist: .5 65 | armStretch: .0500000007 66 | legStretch: .0500000007 67 | feetSpacing: 0 68 | rootMotionBoneName: 69 | lastHumanDescriptionAvatarSource: {instanceID: 0} 70 | additionalBone: 1 71 | animationType: 0 72 | userData: 73 | -------------------------------------------------------------------------------- /Assets/Models/Entrance30Roofed.blend.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: bc142bd928b4c334c8a576eed4dd1bd2 3 | ModelImporter: 4 | serializedVersion: 15 5 | fileIDToRecycleName: 6 | 100000: //RootNode 7 | 400000: //RootNode 8 | 2300000: //RootNode 9 | 3300000: //RootNode 10 | 4300000: Cube 11 | 4300002: Balcony 12 | 4300004: Balcony_3 13 | 4300006: Wall_3 14 | 4300008: Wall_2_5 15 | 4300010: Entrance_2_5 16 | 4300012: Entrance_3 17 | 4300014: Entrance30 18 | 4300016: Entrance30Roofed 19 | 7400000: Default Take 20 | 9500000: //RootNode 21 | materials: 22 | importMaterials: 0 23 | materialName: 0 24 | materialSearch: 1 25 | animations: 26 | legacyGenerateAnimations: 4 27 | bakeSimulation: 0 28 | animationCompression: 1 29 | animationRotationError: .5 30 | animationPositionError: .5 31 | animationScaleError: .5 32 | animationWrapMode: 0 33 | clipAnimations: [] 34 | isReadable: 1 35 | meshes: 36 | lODScreenPercentages: [] 37 | globalScale: 1 38 | meshCompression: 0 39 | addColliders: 0 40 | importBlendShapes: 1 41 | swapUVChannels: 0 42 | generateSecondaryUV: 0 43 | useFileUnits: 1 44 | optimizeMeshForGPU: 1 45 | weldVertices: 1 46 | secondaryUVAngleDistortion: 8 47 | secondaryUVAreaDistortion: 15.000001 48 | secondaryUVHardAngle: 88 49 | secondaryUVPackMargin: 4 50 | tangentSpace: 51 | normalSmoothAngle: 60 52 | splitTangentsAcrossUV: 1 53 | normalImportMode: 1 54 | tangentImportMode: 1 55 | importAnimation: 1 56 | copyAvatar: 0 57 | humanDescription: 58 | human: [] 59 | skeleton: [] 60 | handles: [] 61 | armTwist: .5 62 | foreArmTwist: .5 63 | upperLegTwist: .5 64 | legTwist: .5 65 | armStretch: .0500000007 66 | legStretch: .0500000007 67 | feetSpacing: 0 68 | rootMotionBoneName: 69 | lastHumanDescriptionAvatarSource: {instanceID: 0} 70 | additionalBone: 1 71 | animationType: 0 72 | userData: 73 | -------------------------------------------------------------------------------- /Assets/Models/EntranceWallLast30.blend.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d180a514a42558748a4b2026a05a2417 3 | ModelImporter: 4 | serializedVersion: 15 5 | fileIDToRecycleName: 6 | 100000: //RootNode 7 | 400000: //RootNode 8 | 2300000: //RootNode 9 | 3300000: //RootNode 10 | 4300000: Cube 11 | 4300002: Balcony 12 | 4300004: Balcony_3 13 | 4300006: Wall_3 14 | 4300008: Wall_2_5 15 | 4300010: Socle_2_5 16 | 4300012: Socle_3 17 | 4300014: Entrance_Wall_Last_3 18 | 4300016: EntranceWallLast30 19 | 7400000: Default Take 20 | 9500000: //RootNode 21 | materials: 22 | importMaterials: 0 23 | materialName: 0 24 | materialSearch: 1 25 | animations: 26 | legacyGenerateAnimations: 4 27 | bakeSimulation: 0 28 | animationCompression: 1 29 | animationRotationError: .5 30 | animationPositionError: .5 31 | animationScaleError: .5 32 | animationWrapMode: 0 33 | clipAnimations: [] 34 | isReadable: 1 35 | meshes: 36 | lODScreenPercentages: [] 37 | globalScale: 1 38 | meshCompression: 0 39 | addColliders: 0 40 | importBlendShapes: 1 41 | swapUVChannels: 0 42 | generateSecondaryUV: 0 43 | useFileUnits: 1 44 | optimizeMeshForGPU: 1 45 | weldVertices: 1 46 | secondaryUVAngleDistortion: 8 47 | secondaryUVAreaDistortion: 15.000001 48 | secondaryUVHardAngle: 88 49 | secondaryUVPackMargin: 4 50 | tangentSpace: 51 | normalSmoothAngle: 60 52 | splitTangentsAcrossUV: 1 53 | normalImportMode: 1 54 | tangentImportMode: 1 55 | importAnimation: 1 56 | copyAvatar: 0 57 | humanDescription: 58 | human: [] 59 | skeleton: [] 60 | handles: [] 61 | armTwist: .5 62 | foreArmTwist: .5 63 | upperLegTwist: .5 64 | legTwist: .5 65 | armStretch: .0500000007 66 | legStretch: .0500000007 67 | feetSpacing: 0 68 | rootMotionBoneName: 69 | lastHumanDescriptionAvatarSource: {instanceID: 0} 70 | additionalBone: 1 71 | animationType: 0 72 | userData: 73 | -------------------------------------------------------------------------------- /Assets/Models/Attic30.blend.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1e46e44f396cdae46ab9598bc4695026 3 | ModelImporter: 4 | serializedVersion: 15 5 | fileIDToRecycleName: 6 | 100000: //RootNode 7 | 400000: //RootNode 8 | 2300000: //RootNode 9 | 3300000: //RootNode 10 | 4300000: Cube 11 | 4300002: Balcony 12 | 4300004: Balcony_3 13 | 4300006: Wall_3 14 | 4300008: Wall_2_5 15 | 4300010: Socle_2_5 16 | 4300012: Entrance_Wall_Last_2_5 17 | 4300014: EntranceWallLast25 18 | 4300016: Attic25 19 | 4300018: Attic30 20 | 7400000: Default Take 21 | 9500000: //RootNode 22 | materials: 23 | importMaterials: 0 24 | materialName: 0 25 | materialSearch: 1 26 | animations: 27 | legacyGenerateAnimations: 4 28 | bakeSimulation: 0 29 | animationCompression: 1 30 | animationRotationError: .5 31 | animationPositionError: .5 32 | animationScaleError: .5 33 | animationWrapMode: 0 34 | clipAnimations: [] 35 | isReadable: 1 36 | meshes: 37 | lODScreenPercentages: [] 38 | globalScale: 1 39 | meshCompression: 0 40 | addColliders: 0 41 | importBlendShapes: 1 42 | swapUVChannels: 0 43 | generateSecondaryUV: 0 44 | useFileUnits: 1 45 | optimizeMeshForGPU: 1 46 | weldVertices: 1 47 | secondaryUVAngleDistortion: 8 48 | secondaryUVAreaDistortion: 15.000001 49 | secondaryUVHardAngle: 88 50 | secondaryUVPackMargin: 4 51 | tangentSpace: 52 | normalSmoothAngle: 60 53 | splitTangentsAcrossUV: 1 54 | normalImportMode: 1 55 | tangentImportMode: 1 56 | importAnimation: 1 57 | copyAvatar: 0 58 | humanDescription: 59 | human: [] 60 | skeleton: [] 61 | handles: [] 62 | armTwist: .5 63 | foreArmTwist: .5 64 | upperLegTwist: .5 65 | legTwist: .5 66 | armStretch: .0500000007 67 | legStretch: .0500000007 68 | feetSpacing: 0 69 | rootMotionBoneName: 70 | lastHumanDescriptionAvatarSource: {instanceID: 0} 71 | additionalBone: 1 72 | animationType: 0 73 | userData: 74 | -------------------------------------------------------------------------------- /Assets/Models/Entrance25Roofed.blend.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 941404291936bfe41abaa2fb77b277bc 3 | ModelImporter: 4 | serializedVersion: 15 5 | fileIDToRecycleName: 6 | 100000: //RootNode 7 | 400000: //RootNode 8 | 2300000: //RootNode 9 | 3300000: //RootNode 10 | 4300000: Cube 11 | 4300002: Balcony 12 | 4300004: Balcony_3 13 | 4300006: Wall_3 14 | 4300008: Wall_2_5 15 | 4300010: Entrance_2_5 16 | 4300012: Entrance_3 17 | 4300014: Entrance30 18 | 4300016: Entrance30Roofed 19 | 4300018: EntranceWall30 20 | 4300020: EntranceWall25Roofed 21 | 4300022: Entrance25Roofed 22 | 7400000: Default Take 23 | 9500000: //RootNode 24 | materials: 25 | importMaterials: 0 26 | materialName: 0 27 | materialSearch: 1 28 | animations: 29 | legacyGenerateAnimations: 4 30 | bakeSimulation: 0 31 | animationCompression: 1 32 | animationRotationError: .5 33 | animationPositionError: .5 34 | animationScaleError: .5 35 | animationWrapMode: 0 36 | clipAnimations: [] 37 | isReadable: 1 38 | meshes: 39 | lODScreenPercentages: [] 40 | globalScale: 1 41 | meshCompression: 0 42 | addColliders: 0 43 | importBlendShapes: 1 44 | swapUVChannels: 0 45 | generateSecondaryUV: 0 46 | useFileUnits: 1 47 | optimizeMeshForGPU: 1 48 | weldVertices: 1 49 | secondaryUVAngleDistortion: 8 50 | secondaryUVAreaDistortion: 15.000001 51 | secondaryUVHardAngle: 88 52 | secondaryUVPackMargin: 4 53 | tangentSpace: 54 | normalSmoothAngle: 60 55 | splitTangentsAcrossUV: 1 56 | normalImportMode: 1 57 | tangentImportMode: 1 58 | importAnimation: 1 59 | copyAvatar: 0 60 | humanDescription: 61 | human: [] 62 | skeleton: [] 63 | handles: [] 64 | armTwist: .5 65 | foreArmTwist: .5 66 | upperLegTwist: .5 67 | legTwist: .5 68 | armStretch: .0500000007 69 | legStretch: .0500000007 70 | feetSpacing: 0 71 | rootMotionBoneName: 72 | lastHumanDescriptionAvatarSource: {instanceID: 0} 73 | additionalBone: 1 74 | animationType: 0 75 | userData: 76 | -------------------------------------------------------------------------------- /Assets/Scripts/Triangulator/Triangulator.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System.Collections.Generic; 3 | 4 | public class Triangulator 5 | { 6 | private List m_points = new List(); 7 | 8 | public Triangulator(Vector2[] points) 9 | { 10 | m_points = new List(points); 11 | } 12 | 13 | public int[] Triangulate() 14 | { 15 | List indices = new List(); 16 | 17 | int n = m_points.Count; 18 | if (n < 3) 19 | return indices.ToArray(); 20 | 21 | int[] V = new int[n]; 22 | if (Area() > 0) 23 | { 24 | for (int v = 0; v < n; v++) 25 | V[v] = v; 26 | } 27 | else 28 | { 29 | for (int v = 0; v < n; v++) 30 | V[v] = (n - 1) - v; 31 | } 32 | 33 | int nv = n; 34 | int count = 2 * nv; 35 | for (int m = 0, v = nv - 1; nv > 2; ) 36 | { 37 | if ((count--) <= 0) 38 | return indices.ToArray(); 39 | 40 | int u = v; 41 | if (nv <= u) 42 | u = 0; 43 | v = u + 1; 44 | if (nv <= v) 45 | v = 0; 46 | int w = v + 1; 47 | if (nv <= w) 48 | w = 0; 49 | 50 | if (Snip(u, v, w, nv, V)) 51 | { 52 | int a, b, c, s, t; 53 | a = V[u]; 54 | b = V[v]; 55 | c = V[w]; 56 | indices.Add(a); 57 | indices.Add(b); 58 | indices.Add(c); 59 | m++; 60 | for (s = v, t = v + 1; t < nv; s++, t++) 61 | V[s] = V[t]; 62 | nv--; 63 | count = 2 * nv; 64 | } 65 | } 66 | 67 | indices.Reverse(); 68 | return indices.ToArray(); 69 | } 70 | 71 | private float Area() 72 | { 73 | int n = m_points.Count; 74 | float A = 0.0f; 75 | for (int p = n - 1, q = 0; q < n; p = q++) 76 | { 77 | Vector2 pval = m_points[p]; 78 | Vector2 qval = m_points[q]; 79 | A += pval.x * qval.y - qval.x * pval.y; 80 | } 81 | return (A * 0.5f); 82 | } 83 | 84 | private bool Snip(int u, int v, int w, int n, int[] V) 85 | { 86 | int p; 87 | Vector2 A = m_points[V[u]]; 88 | Vector2 B = m_points[V[v]]; 89 | Vector2 C = m_points[V[w]]; 90 | if (Mathf.Epsilon > (((B.x - A.x) * (C.y - A.y)) - ((B.y - A.y) * (C.x - A.x)))) 91 | return false; 92 | for (p = 0; p < n; p++) 93 | { 94 | if ((p == u) || (p == v) || (p == w)) 95 | continue; 96 | Vector2 P = m_points[V[p]]; 97 | if (InsideTriangle(A, B, C, P)) 98 | return false; 99 | } 100 | return true; 101 | } 102 | 103 | private bool InsideTriangle(Vector2 A, Vector2 B, Vector2 C, Vector2 P) 104 | { 105 | float ax, ay, bx, by, cx, cy, apx, apy, bpx, bpy, cpx, cpy; 106 | float cCROSSap, bCROSScp, aCROSSbp; 107 | 108 | ax = C.x - B.x; ay = C.y - B.y; 109 | bx = A.x - C.x; by = A.y - C.y; 110 | cx = B.x - A.x; cy = B.y - A.y; 111 | apx = P.x - A.x; apy = P.y - A.y; 112 | bpx = P.x - B.x; bpy = P.y - B.y; 113 | cpx = P.x - C.x; cpy = P.y - C.y; 114 | 115 | aCROSSbp = ax * bpy - ay * bpx; 116 | cCROSSap = cx * apy - cy * apx; 117 | bCROSScp = bx * cpy - by * cpx; 118 | 119 | return ((aCROSSbp >= 0.0f) && (bCROSScp >= 0.0f) && (cCROSSap >= 0.0f)); 120 | } 121 | } -------------------------------------------------------------------------------- /Assets/Scripts/MeshExtrusion.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System.Collections; 3 | 4 | /* 5 | * An algorithm to extrude an arbitrary mesh along a number of sections. 6 | 7 | The mesh extrusion has 2 steps: 8 | 9 | 1. Extracting an edge representation from an arbitrary mesh 10 | - A general edge extraction algorithm is employed. (Same algorithm as traditionally used for stencil shadows) Once all unique edges are found, all edges that connect to only one triangle are extracted. 11 | Thus we end up with the outline of the mesh. 12 | 13 | 2. extruding the mesh from the edge representation. 14 | We simply generate a segments joining the edges 15 | 16 | 17 | 18 | 19 | */ 20 | 21 | public class MeshExtrusion 22 | { 23 | public class Edge 24 | { 25 | // The indiex to each vertex 26 | public int[] vertexIndex = new int[2]; 27 | // The index into the face. 28 | // (faceindex[0] == faceindex[1] means the edge connects to only one triangle) 29 | public int[] faceIndex = new int[2]; 30 | } 31 | 32 | public static void ExtrudeMesh (Mesh srcMesh, Mesh extrudedMesh, Matrix4x4[] extrusion, bool invertFaces) 33 | { 34 | Edge[] edges = BuildManifoldEdges(srcMesh); 35 | ExtrudeMesh(srcMesh, extrudedMesh, extrusion, edges, invertFaces); 36 | } 37 | 38 | public static void ExtrudeMesh (Mesh srcMesh, Mesh extrudedMesh, Matrix4x4[] extrusion, Edge[] edges, bool invertFaces) 39 | { 40 | int extrudedVertexCount = edges.Length * 2 * extrusion.Length; 41 | int triIndicesPerStep = edges.Length * 6; 42 | int extrudedTriIndexCount = triIndicesPerStep * (extrusion.Length -1); 43 | 44 | Vector3[] inputVertices = srcMesh.vertices; 45 | Vector2[] inputUV = srcMesh.uv; 46 | int[] inputTriangles = srcMesh.triangles; 47 | 48 | Vector3[] vertices = new Vector3[extrudedVertexCount + srcMesh.vertexCount * 2]; 49 | Vector2[] uvs = new Vector2[vertices.Length]; 50 | int[] triangles = new int[extrudedTriIndexCount + inputTriangles.Length * 2]; 51 | 52 | // Build extruded vertices 53 | int v = 0; 54 | for (int i=0;i i2) 253 | { 254 | bool foundEdge = false; 255 | for (int edgeIndex = firstEdge[i2]; edgeIndex != -1;edgeIndex = firstEdge[nextEdge + edgeIndex]) 256 | { 257 | Edge edge = edgeArray[edgeIndex]; 258 | if ((edge.vertexIndex[1] == i1) && (edge.faceIndex[0] == edge.faceIndex[1])) 259 | { 260 | edgeArray[edgeIndex].faceIndex[1] = a; 261 | foundEdge = true; 262 | break; 263 | } 264 | } 265 | 266 | if (!foundEdge) 267 | { 268 | Edge newEdge = new Edge(); 269 | newEdge.vertexIndex[0] = i1; 270 | newEdge.vertexIndex[1] = i2; 271 | newEdge.faceIndex[0] = a; 272 | newEdge.faceIndex[1] = a; 273 | edgeArray[edgeCount] = newEdge; 274 | edgeCount++; 275 | } 276 | } 277 | 278 | i1 = i2; 279 | } 280 | } 281 | 282 | Edge[] compactedEdges = new Edge[edgeCount]; 283 | for (int e=0;e balcony25; 18 | public List balcony30; 19 | public List wall25; 20 | public List wall30; 21 | public List window25; 22 | public List window30; 23 | public List socle25; 24 | public List socle30; 25 | public List entrance25; 26 | public List entrance30; 27 | public List entranceWall25; 28 | public List entranceWall30; 29 | public List entranceWallLast25; 30 | public List entranceWallLast30; 31 | public List attic25; 32 | public List attic30; 33 | public List roofFlat; 34 | public List roofGabled; 35 | public List roofHipped; 36 | 37 | private MeshFilter meshFilter; 38 | private float height; 39 | private float[] panels = {3, 2.5f}; 40 | private System.Random random; 41 | private float socleHeight = 1; 42 | private float ceilingHeight = 3; 43 | private int entranceMeshIndex = 0; 44 | private int entranceWallMeshIndex = 0; 45 | private int entranceWallLastMeshIndex = 0; 46 | 47 | public enum RoofType 48 | { 49 | Flat, 50 | FlatOverhang, 51 | Gabled, 52 | Hipped, 53 | } 54 | 55 | public enum PanelType 56 | { 57 | Wall, 58 | Window, 59 | Balcony, 60 | Entrance, 61 | EntranceWall, 62 | EntranceWallLast, 63 | Socle, 64 | Attic, 65 | }; 66 | 67 | void Start() 68 | { 69 | meshFilter = GetComponent(); 70 | random = new System.Random(); 71 | GenerateBuilding(); 72 | } 73 | 74 | void GenerateBuilding() 75 | { 76 | width = random.Next(10, 13); 77 | length = random.Next(30, 55); 78 | floors = random.Next(1, 7); 79 | entrances = (int)(length/10 - 1); 80 | height = ceilingHeight * floors + socleHeight; 81 | entranceMeshIndex = random.Next(entrance25.Count); 82 | entranceWallMeshIndex = random.Next(entranceWall25.Count); 83 | entranceWallLastMeshIndex = random.Next(entranceWallLast25.Count); 84 | attic = Random.value > 0.5f; 85 | var roofHeight = Vector3.up * height; 86 | if (attic) 87 | { 88 | roofHeight += Vector3.up; 89 | } 90 | roofType = RandomItem(new List {RoofType.Flat, RoofType.FlatOverhang, RoofType.Gabled, RoofType.Hipped}); 91 | 92 | var corner0 = Vector3.back * width / 2 + Vector3.left * length / 2; 93 | var corner1 = Vector3.forward * width / 2 + Vector3.left * length / 2; 94 | var corner2 = Vector3.forward * width / 2 + Vector3.right * length / 2; 95 | var corner3 = Vector3.back * width / 2 + Vector3.right * length / 2; 96 | 97 | var wallSizes0 = ExteriorWallSizes(width); 98 | var panelPattern0 = FacadePattern(wallSizes0.Count, floors, attic); 99 | var wallSizes1 = ExteriorWallSizes(length); 100 | var panelPattern1 = FacadePattern(wallSizes1.Count, floors, attic, true); 101 | var wallSizes2 = ExteriorWallSizes(width); 102 | var panelPattern2 = FacadePattern(wallSizes2.Count, floors, attic); 103 | var wallSizes3 = ExteriorWallSizes(length); 104 | var panelPattern3 = FacadePattern(wallSizes3.Count, floors, attic, true, entrances); 105 | 106 | var combine = new List(); 107 | var matrices = new List(); 108 | 109 | combine.Add(Facade(corner0, Vector3.forward, wallSizes0, panelPattern0)); 110 | matrices.Add(Matrix4x4.identity); 111 | combine.Add(Facade(corner1, Vector3.right, wallSizes1, panelPattern1)); 112 | matrices.Add(Matrix4x4.identity); 113 | combine.Add(Facade(corner2, Vector3.back, wallSizes2, panelPattern2)); 114 | matrices.Add(Matrix4x4.identity); 115 | combine.Add(Facade(corner3, Vector3.left, wallSizes3, panelPattern3)); 116 | matrices.Add(Matrix4x4.identity); 117 | switch (roofType) 118 | { 119 | case RoofType.Flat: 120 | combine.Add(RandomItem(roofFlat)); 121 | matrices.Add(Matrix4x4.TRS(roofHeight, Quaternion.identity, new Vector3(length, 1, width))); 122 | break; 123 | case RoofType.FlatOverhang: 124 | combine.Add(RandomItem(roofFlat)); 125 | matrices.Add(Matrix4x4.TRS(roofHeight, Quaternion.identity, new Vector3(length + 1, 1, width + 1))); 126 | break; 127 | case RoofType.Gabled: 128 | combine.Add(RandomItem(roofGabled)); 129 | matrices.Add(Matrix4x4.TRS(roofHeight, Quaternion.identity, new Vector3(length, 1, width + 1))); 130 | break; 131 | case RoofType.Hipped: 132 | combine.Add(RandomItem(roofHipped)); 133 | matrices.Add(Matrix4x4.TRS(roofHeight, Quaternion.identity, new Vector3(length + 1, 1, width + 1))); 134 | break; 135 | } 136 | 137 | meshFilter.mesh.Clear(); 138 | meshFilter.mesh = PGMesh.CombineMeshes(combine, matrices); 139 | meshFilter.mesh.RecalculateBounds(); 140 | meshFilter.mesh.Optimize(); 141 | renderer.material.color = new Color(Random.value, Random.value, Random.value); 142 | } 143 | 144 | Mesh WindowPanel(Vector3 vertex0, Vector3 vertex1, Vector3 vertex2, Vector3 vertex3) 145 | { 146 | var normal = Vector3.Cross((vertex1 - vertex0), (vertex2 - vertex0)).normalized; 147 | var window0 = vertex0 + (vertex3 - vertex0) * 0.25f + (vertex1 - vertex0) * 0.25f; 148 | var window1 = vertex0 + (vertex3 - vertex0) * 0.25f + (vertex1 - vertex0) * 0.75f; 149 | var window2 = vertex0 + (vertex3 - vertex0) * 0.75f + (vertex1 - vertex0) * 0.75f; 150 | var window3 = vertex0 + (vertex3 - vertex0) * 0.75f + (vertex1 - vertex0) * 0.25f; 151 | 152 | var mesh = new Mesh 153 | { 154 | vertices = new[] {vertex0, vertex1, vertex2, vertex3, window0, window1, window2, window3, 155 | window0, window1, window2, window3}, 156 | normals = new[] { normal, normal, normal, normal, normal, normal, normal, normal, normal, normal, normal, normal }, 157 | uv = new[] {new Vector2(0, 0), new Vector2(0, 1), new Vector2(1, 1), new Vector2(1, 0), 158 | new Vector2(0.25f, 0.25f), new Vector2(0.25f, 0.75f), new Vector2(0.75f, 0.75f), new Vector2(0.75f, 0.25f), 159 | new Vector2(0, 0), new Vector2(0, 1), new Vector2(1, 1), new Vector2(1, 0)}, 160 | triangles = new[] 161 | { 162 | 0, 1, 4, 163 | 4, 1, 5, 164 | 1, 2, 5, 165 | 5, 2, 6, 166 | 2, 3, 6, 167 | 6, 3, 7, 168 | 3, 0, 7, 169 | 7, 0, 4, 170 | 171 | 8, 9, 10, 172 | 10, 11, 8}, 173 | subMeshCount = 2 174 | }; 175 | mesh.SetTriangles(new[] { 0, 1, 4, 176 | 4, 1, 5, 177 | 1, 2, 5, 178 | 5, 2, 6, 179 | 2, 3, 6, 180 | 6, 3, 7, 181 | 3, 0, 7, 182 | 7, 0, 4}, 0); 183 | mesh.SetTriangles(new[] { 8, 9, 10, 10, 11, 8 }, 1); 184 | return mesh; 185 | } 186 | 187 | Mesh EntrancePanel(Vector3 vertex0, Vector3 vertex1, Vector3 vertex2, Vector3 vertex3) 188 | { 189 | var normal = Vector3.Cross((vertex1 - vertex0), (vertex2 - vertex0)).normalized; 190 | var window0 = vertex0 + (vertex3 - vertex0) * 0.25f + (vertex1 - vertex0) * 0.25f; 191 | var window1 = vertex0 + (vertex3 - vertex0) * 0.25f + (vertex1 - vertex0) * 0.75f; 192 | var window2 = vertex0 + (vertex3 - vertex0) * 0.75f + (vertex1 - vertex0) * 0.75f; 193 | var window3 = vertex0 + (vertex3 - vertex0) * 0.75f + (vertex1 - vertex0) * 0.25f; 194 | 195 | var mesh = new Mesh 196 | { 197 | vertices = new[] {vertex0, vertex1, vertex2, vertex3, 198 | window0, window1, window2, window3, 199 | window0, window1, window2, window3}, 200 | normals = new[] { normal, normal, normal, normal, 201 | normal, normal, normal, normal, 202 | normal, normal, normal, normal }, 203 | uv = new[] {new Vector2(0, 0), new Vector2(0, 1), new Vector2(1, 1), new Vector2(1, 0), 204 | new Vector2(0.25f, 0.25f), new Vector2(0.25f, 0.75f), 205 | new Vector2(0.75f, 0.75f), new Vector2(0.75f, 0.25f), 206 | new Vector2(0, 0), new Vector2(0, 1), new Vector2(1, 1), new Vector2(1, 0)}, 207 | triangles = new[] 208 | { 209 | 0, 1, 4, 210 | 4, 1, 5, 211 | 1, 2, 5, 212 | 5, 2, 6, 213 | 2, 3, 6, 214 | 6, 3, 7, 215 | 3, 0, 7, 216 | 7, 0, 4, 217 | 218 | 8, 9, 10, 219 | 10, 11, 8}, 220 | subMeshCount = 2 221 | }; 222 | mesh.SetTriangles(new[] { 0, 1, 4, 223 | 4, 1, 5, 224 | 1, 2, 5, 225 | 5, 2, 6, 226 | 2, 3, 6, 227 | 6, 3, 7, 228 | 3, 0, 7, 229 | 7, 0, 4}, 0); 230 | mesh.SetTriangles(new[] { 8, 9, 10, 10, 11, 8 }, 1); 231 | return mesh; 232 | } 233 | 234 | Mesh BalconyPanel(Vector3 v0, Vector3 v1, Vector3 v2, Vector3 v3) 235 | { 236 | var normal = Vector3.Cross((v1 - v0), (v3 - v0)).normalized; 237 | var v4 = v0 + (v1 - v0) * 0.4f; 238 | var v5 = v3 + (v2 - v3) * 0.4f; 239 | 240 | var combine = new List(); 241 | var submeshMask = new List>(); 242 | combine.Add(PGMesh.Quad(v0, v4, v4 + normal, v0 + normal)); 243 | submeshMask.Add(new List { 0 }); 244 | combine.Add(PGMesh.Quad(v0 + normal, v4 + normal, v5 + normal, v3 + normal)); 245 | submeshMask.Add(new List { 0 }); 246 | combine.Add(PGMesh.Quad(v3 + normal, v5 + normal, v5, v3)); 247 | submeshMask.Add(new List { 0 }); 248 | combine.Add(PGMesh.Quad(v0, v0 + normal, v3 + normal, v3)); 249 | submeshMask.Add(new List { 0 }); 250 | 251 | combine.Add(PGMesh.Quad(v4, v1, v1 + normal, v4 + normal)); 252 | submeshMask.Add(new List { 1 }); 253 | combine.Add(PGMesh.Quad(v4 + normal, v1 + normal, v2 + normal, v5 + normal)); 254 | submeshMask.Add(new List { 1 }); 255 | combine.Add(PGMesh.Quad(v5 + normal, v2 + normal, v2, v5)); 256 | submeshMask.Add(new List { 1 }); 257 | 258 | combine.Add(PGMesh.Quad(v2, v2 + normal, v1 + normal, v1)); 259 | submeshMask.Add(new List { 0 }); 260 | 261 | return PGMesh.CombineMeshes(combine); 262 | } 263 | 264 | Mesh Facade(Vector3 origin, Vector3 direction, List wallSizes, List> panelPattern) 265 | { 266 | var floorMeshes = new List(); 267 | var facadeMeshes = new List(); 268 | var matrices = new List(); 269 | var panelOrigin = origin; 270 | 271 | for (var i = 0; i < panelPattern.Count; i++) 272 | { 273 | for (var j = 0; j < panelPattern[i].Count; j++) 274 | { 275 | if (Mathf.Abs(wallSizes[j] - 2.5f) < Mathf.Epsilon) 276 | { 277 | switch (panelPattern[i][j]) 278 | { 279 | case PanelType.Window: 280 | floorMeshes.Add(RandomItem(window25)); 281 | matrices.Add(Matrix4x4.TRS(panelOrigin, Quaternion.LookRotation(Vector3.Cross(direction, Vector3.up)), Vector3.one)); 282 | break; 283 | case PanelType.Balcony: 284 | floorMeshes.Add(RandomItem(balcony25)); 285 | matrices.Add(Matrix4x4.TRS(panelOrigin, Quaternion.LookRotation(Vector3.Cross(direction, Vector3.up)), Vector3.one)); 286 | break; 287 | case PanelType.Wall: 288 | floorMeshes.Add(RandomItem(wall25)); 289 | matrices.Add(Matrix4x4.TRS(panelOrigin, Quaternion.LookRotation(Vector3.Cross(direction, Vector3.up)), Vector3.one)); 290 | break; 291 | case PanelType.Socle: 292 | floorMeshes.Add(RandomItem(socle25)); 293 | matrices.Add(Matrix4x4.TRS(panelOrigin, Quaternion.LookRotation(Vector3.Cross(direction, Vector3.up)), Vector3.one)); 294 | break; 295 | case PanelType.Entrance: 296 | floorMeshes.Add(entrance25[entranceMeshIndex]); 297 | matrices.Add(Matrix4x4.TRS(panelOrigin, Quaternion.LookRotation(Vector3.Cross(direction, Vector3.up)), Vector3.one)); 298 | break; 299 | case PanelType.EntranceWall: 300 | floorMeshes.Add(entranceWall25[entranceWallMeshIndex]); 301 | matrices.Add(Matrix4x4.TRS(panelOrigin + Vector3.up * (ceilingHeight - socleHeight), Quaternion.LookRotation(Vector3.Cross(direction, Vector3.up)), Vector3.one)); 302 | break; 303 | case PanelType.EntranceWallLast: 304 | floorMeshes.Add(entranceWallLast25[entranceWallLastMeshIndex]); 305 | matrices.Add(Matrix4x4.TRS(panelOrigin + Vector3.up * (ceilingHeight - socleHeight), Quaternion.LookRotation(Vector3.Cross(direction, Vector3.up)), Vector3.one)); 306 | break; 307 | case PanelType.Attic: 308 | floorMeshes.Add(RandomItem(attic25)); 309 | matrices.Add(Matrix4x4.TRS(panelOrigin, Quaternion.LookRotation(Vector3.Cross(direction, Vector3.up)), Vector3.one)); 310 | break; 311 | } 312 | } 313 | else 314 | { 315 | switch (panelPattern[i][j]) 316 | { 317 | case PanelType.Window: 318 | floorMeshes.Add(RandomItem(window30)); 319 | matrices.Add(Matrix4x4.TRS(panelOrigin, Quaternion.LookRotation(Vector3.Cross(direction, Vector3.up)), Vector3.one)); 320 | break; 321 | case PanelType.Balcony: 322 | floorMeshes.Add(RandomItem(balcony30)); 323 | matrices.Add(Matrix4x4.TRS(panelOrigin, Quaternion.LookRotation(Vector3.Cross(direction, Vector3.up)), Vector3.one)); 324 | break; 325 | case PanelType.Wall: 326 | floorMeshes.Add(RandomItem(wall30)); 327 | matrices.Add(Matrix4x4.TRS(panelOrigin, Quaternion.LookRotation(Vector3.Cross(direction, Vector3.up)), Vector3.one)); 328 | break; 329 | case PanelType.Socle: 330 | floorMeshes.Add(RandomItem(socle30)); 331 | matrices.Add(Matrix4x4.TRS(panelOrigin, Quaternion.LookRotation(Vector3.Cross(direction, Vector3.up)), Vector3.one)); 332 | break; 333 | case PanelType.Entrance: 334 | floorMeshes.Add(entrance30[entranceMeshIndex]); 335 | matrices.Add(Matrix4x4.TRS(panelOrigin, Quaternion.LookRotation(Vector3.Cross(direction, Vector3.up)), Vector3.one)); 336 | break; 337 | case PanelType.EntranceWall: 338 | floorMeshes.Add(entranceWall30[entranceWallMeshIndex]); 339 | matrices.Add(Matrix4x4.TRS(panelOrigin + Vector3.up * (ceilingHeight - socleHeight), Quaternion.LookRotation(Vector3.Cross(direction, Vector3.up)), Vector3.one)); 340 | break; 341 | case PanelType.EntranceWallLast: 342 | floorMeshes.Add(entranceWallLast30[entranceWallLastMeshIndex]); 343 | matrices.Add(Matrix4x4.TRS(panelOrigin + Vector3.up * (ceilingHeight - socleHeight), Quaternion.LookRotation(Vector3.Cross(direction, Vector3.up)), Vector3.one)); 344 | break; 345 | case PanelType.Attic: 346 | floorMeshes.Add(RandomItem(attic30)); 347 | matrices.Add(Matrix4x4.TRS(panelOrigin, Quaternion.LookRotation(Vector3.Cross(direction, Vector3.up)), Vector3.one)); 348 | break; 349 | } 350 | } 351 | panelOrigin += direction * wallSizes[j]; 352 | } 353 | facadeMeshes.Add(PGMesh.CombineMeshes(floorMeshes, matrices)); 354 | floorMeshes.Clear(); 355 | matrices.Clear(); 356 | panelOrigin = origin + Vector3.up * (i * ceilingHeight + socleHeight); 357 | } 358 | 359 | return PGMesh.CombineMeshes(facadeMeshes); 360 | } 361 | 362 | List ExteriorWallSizes(float wallLength) 363 | { 364 | var draft = ExteriorWallSizesDraft(wallLength); 365 | var wallSizes = new List(); 366 | for (var i = 0; i < draft.Length; i++) 367 | { 368 | for (var j = 0; j < draft[i]; j++) 369 | { 370 | wallSizes.Add(panels[i]); 371 | } 372 | } 373 | wallSizes.Shuffle(); 374 | return wallSizes; 375 | } 376 | 377 | int[] ExteriorWallSizesDraft(float remainder, int[] draft = null, int startIndex = 0) 378 | { 379 | if (draft == null) 380 | { 381 | draft = new int[panels.Length]; 382 | for (int i = 0; i < draft.Length; i++) 383 | { 384 | draft[i] = 0; 385 | } 386 | } 387 | if (remainder < panels[panels.Length - 1]) 388 | { 389 | draft[draft.Length - 1] = 1; 390 | return draft; 391 | } 392 | for (var i = startIndex; i < panels.Length; i++) 393 | { 394 | draft[i] += (int)(remainder / panels[i]); 395 | remainder %= panels[i]; 396 | } 397 | if (remainder > 0) 398 | { 399 | for (var i = 0; i < draft.Length; i++) 400 | { 401 | if (draft[i] != 0) 402 | { 403 | if (i == draft.Length - 1) 404 | { 405 | return draft; 406 | } 407 | draft[i]--; 408 | remainder += panels[i]; 409 | startIndex = i+1; 410 | break; 411 | } 412 | } 413 | draft = ExteriorWallSizesDraft(remainder, draft, startIndex); 414 | } 415 | return draft; 416 | } 417 | 418 | List> FacadePattern(int panelCount, int floorCount, bool haveAttic=false, bool longFacade=false, int entrancesCount=0) 419 | { 420 | var panelPattern = new List>(); 421 | var entranceIndex = panelCount / (entrances + 1); 422 | var entranceCount = 1; 423 | 424 | for (var i = 0; i < floorCount+1; i++) 425 | { 426 | panelPattern.Add(new List()); 427 | for (var j = 0; j < panelCount; j++) 428 | { 429 | if (i == 0) 430 | { 431 | if (entrancesCount > 0 && j == entranceIndex && entranceCount <= entrances) 432 | { 433 | panelPattern[0].Add(PanelType.Entrance); 434 | entranceCount++; 435 | entranceIndex = panelCount*entranceCount/(entrances + 1); 436 | } 437 | else 438 | { 439 | panelPattern[0].Add(PanelType.Socle); 440 | } 441 | } 442 | else if (i == 1) 443 | { 444 | if (panelPattern[0][j] == PanelType.Entrance) 445 | { 446 | panelPattern[1].Add(PanelType.EntranceWall); 447 | } 448 | else if (longFacade) 449 | { 450 | panelPattern[1].Add(PanelType.Window); 451 | } 452 | else 453 | { 454 | panelPattern[1].Add(PanelType.Wall); 455 | } 456 | } 457 | else 458 | { 459 | panelPattern[i].Add(panelPattern[i - 1][j]); 460 | } 461 | if (i == floorCount) 462 | { 463 | if (panelPattern[i - 1][j] == PanelType.Entrance || panelPattern[i - 1][j] == PanelType.EntranceWall) 464 | { 465 | panelPattern[i][j] = PanelType.EntranceWallLast; 466 | } 467 | } 468 | } 469 | if (i == 1 && !longFacade) 470 | { 471 | for (int j = 0; j <= panelPattern[1].Count / 2; j++) 472 | { 473 | if (j != 0 && j != panelCount - 1 && Random.value > 0.5f) 474 | { 475 | panelPattern[1][j] = PanelType.Window; 476 | panelPattern[1][panelPattern[1].Count - 1 - j] = PanelType.Window; 477 | } 478 | } 479 | } 480 | if (i == 2) 481 | { 482 | for (int j = 0; j <= panelPattern[2].Count/2; j++) 483 | { 484 | if (panelPattern[2][j] == PanelType.Window && panelPattern[2][panelPattern[2].Count - 1 - j] == PanelType.Window && Random.value > 0.5f) 485 | { 486 | panelPattern[2][j] = PanelType.Balcony; 487 | panelPattern[2][panelPattern[2].Count - 1 - j] = PanelType.Balcony; 488 | } 489 | } 490 | } 491 | } 492 | if (haveAttic) 493 | { 494 | panelPattern.Add(new List()); 495 | for (var j = 0; j < panelCount; j++) 496 | { 497 | panelPattern[panelPattern.Count-1].Add(PanelType.Attic); 498 | } 499 | } 500 | return panelPattern; 501 | } 502 | 503 | T RandomItem(IList itemList) 504 | { 505 | return itemList[random.Next(itemList.Count)]; 506 | } 507 | } 508 | 509 | static class MyExtensions 510 | { 511 | public static void Shuffle(this IList list) 512 | { 513 | var random = new System.Random(); 514 | int n = list.Count; 515 | while (n > 1) 516 | { 517 | n--; 518 | int k = random.Next(n + 1); 519 | T value = list[k]; 520 | list[k] = list[n]; 521 | list[n] = value; 522 | } 523 | } 524 | } 525 | -------------------------------------------------------------------------------- /Assets/Scripts/PGMesh/PGMesh.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using UnityEngine; 3 | 4 | namespace PGToolkit 5 | { 6 | public class PGMesh 7 | { 8 | public enum Shape 9 | { 10 | Triangle, 11 | Quad, 12 | Plane, 13 | Tetrahedron, 14 | Cube, 15 | Octahedron, 16 | Icosahedron, 17 | }; 18 | 19 | public static Mesh Triangle(Vector3 vertex0, Vector3 vertex1, Vector3 vertex2) 20 | { 21 | var normal = Vector3.Cross((vertex1 - vertex0), (vertex2 - vertex0)).normalized; 22 | var mesh = new Mesh 23 | { 24 | vertices = new[] { vertex0, vertex1, vertex2 }, 25 | normals = new[] { normal, normal, normal }, 26 | uv = new[] { new Vector2(0, 0), new Vector2(0, 1), new Vector2(1, 1) }, 27 | triangles = new[] { 0, 1, 2 } 28 | }; 29 | return mesh; 30 | } 31 | 32 | public static Mesh Quad(Vector3 origin, Vector3 width, Vector3 length) 33 | { 34 | var normal = Vector3.Cross(length, width).normalized; 35 | var mesh = new Mesh 36 | { 37 | vertices = new[] { origin, origin + length, origin + length + width, origin + width }, 38 | normals = new[] { normal, normal, normal, normal }, 39 | uv = new[] { new Vector2(0, 0), new Vector2(0, 1), new Vector2(1, 1), new Vector2(1, 0) }, 40 | triangles = new[] { 0, 1, 2, 41 | 0, 2, 3} 42 | }; 43 | return mesh; 44 | } 45 | 46 | public static Mesh Quad(Vector3 vertex0, Vector3 vertex1, Vector3 vertex2, Vector3 vertex3) 47 | { 48 | var normal = Vector3.Cross((vertex1 - vertex0), (vertex2 - vertex0)).normalized; 49 | var mesh = new Mesh 50 | { 51 | vertices = new[] { vertex0, vertex1, vertex2, vertex3}, 52 | normals = new[] { normal, normal, normal, normal }, 53 | uv = new[] { new Vector2(0, 0), new Vector2(0, 1), new Vector2(1, 1), new Vector2(1, 0) }, 54 | triangles = new[] { 0, 1, 2, 55 | 0, 2, 3} 56 | }; 57 | return mesh; 58 | } 59 | 60 | public static Mesh Plane(Vector3 origin, Vector3 width, Vector3 length, int widthCount, int lengthCount) 61 | { 62 | var combine = new CombineInstance[widthCount * lengthCount]; 63 | 64 | var i = 0; 65 | for (var x = 0; x < widthCount; x++) 66 | { 67 | for (var y = 0; y < lengthCount; y++) 68 | { 69 | combine[i].mesh = Quad(origin + width * x + length * y, width, length); 70 | i++; 71 | } 72 | } 73 | 74 | var mesh = new Mesh(); 75 | mesh.CombineMeshes(combine, true, false); 76 | return mesh; 77 | } 78 | 79 | //public static Mesh Tetrahedron(float radius) 80 | //{ 81 | // var v0 = new Vector3(0, radius, 0); 82 | // var v1 = new Vector3(0, -radius * 0.333f, radius * 0.943f); 83 | // var v2 = new Vector3(radius * 0.816f, -radius * 0.333f, -radius * 0.471f); 84 | // var v3 = new Vector3(-radius * 0.816f, -radius * 0.333f, -radius * 0.471f); 85 | 86 | // var combine = new CombineInstance[4]; 87 | // combine[0].mesh = Triangle(v0, v1, v2); 88 | // combine[1].mesh = Triangle(v1, v3, v2); 89 | // combine[2].mesh = Triangle(v0, v2, v3); 90 | // combine[3].mesh = Triangle(v0, v3, v1); 91 | 92 | // var mesh = new Mesh(); 93 | // mesh.CombineMeshes(combine, true, false); 94 | // return mesh; 95 | //} 96 | 97 | public static Mesh Tetrahedron(float radius) 98 | { 99 | var tetrahedralAngle = Mathf.PI * 109.4712f / 180; 100 | var segmentAngle = Mathf.PI * 2 / 3; 101 | var currentAngle = 0f; 102 | 103 | var v = new Vector3[4]; 104 | v[0] = new Vector3(0, radius, 0); 105 | for (var i = 1; i <= 3; i++) 106 | { 107 | v[i] = new Vector3(radius * Mathf.Sin(currentAngle) * Mathf.Sin(tetrahedralAngle), 108 | radius * Mathf.Cos(tetrahedralAngle), 109 | radius * Mathf.Cos(currentAngle) * Mathf.Sin(tetrahedralAngle)); 110 | currentAngle = currentAngle + segmentAngle; 111 | } 112 | 113 | var combine = new CombineInstance[4]; 114 | combine[0].mesh = Triangle(v[0], v[1], v[2]); 115 | combine[1].mesh = Triangle(v[1], v[3], v[2]); 116 | combine[2].mesh = Triangle(v[0], v[2], v[3]); 117 | combine[3].mesh = Triangle(v[0], v[3], v[1]); 118 | 119 | var mesh = new Mesh(); 120 | mesh.CombineMeshes(combine, true, false); 121 | return mesh; 122 | } 123 | 124 | public static Mesh BaselessPyramid(Vector3 baseCenter, Vector3 apex, float radius, int segments, bool inverted = false) 125 | { 126 | var segmentAngle = Mathf.PI * 2 / segments; 127 | var currentAngle = 0f; 128 | 129 | var v = new Vector3[segments + 1]; 130 | v[0] = apex; 131 | for (var i = 1; i <= segments; i++) 132 | { 133 | v[i] = new Vector3(radius * Mathf.Sin(currentAngle), 0, 134 | radius * Mathf.Cos(currentAngle)) + baseCenter; 135 | if (inverted) currentAngle -= segmentAngle; 136 | else currentAngle += segmentAngle; 137 | } 138 | 139 | var combine = new CombineInstance[segments]; 140 | for (var i = 0; i < segments - 1; i++) 141 | { 142 | combine[i].mesh = Triangle(v[0], v[i + 1], v[i + 2]); 143 | } 144 | combine[combine.Length - 1].mesh = Triangle(v[0], v[v.Length - 1], v[1]); 145 | 146 | var mesh = new Mesh(); 147 | mesh.CombineMeshes(combine, true, false); 148 | return mesh; 149 | } 150 | 151 | public static Mesh BaselessPyramid(float radius, int segments, float heignt, bool inverted = false) 152 | { 153 | if (inverted) return BaselessPyramid(Vector3.zero, Vector3.down * heignt, radius, segments, true); 154 | return BaselessPyramid(Vector3.zero, Vector3.up * heignt, radius, segments); 155 | } 156 | 157 | public static Mesh TriangleFan(Vector3 center, float radius, int segments, bool inverted = false) 158 | { 159 | return BaselessPyramid(center, center, radius, segments, inverted); 160 | } 161 | 162 | public static Mesh Pyramid(float radius, int segments, float heignt, bool grounded = false) 163 | { 164 | var combine = new CombineInstance[2]; 165 | combine[0].mesh = BaselessPyramid(radius, segments, heignt); 166 | combine[1].mesh = TriangleFan(Vector3.zero, radius, segments, true); 167 | 168 | var mesh = new Mesh(); 169 | mesh.CombineMeshes(combine, true, false); 170 | return mesh; 171 | } 172 | 173 | public static Mesh BiPyramid(float radius, int segments, float heignt) 174 | { 175 | var combine = new CombineInstance[2]; 176 | combine[0].mesh = BaselessPyramid(radius, segments, heignt); 177 | combine[1].mesh = BaselessPyramid(radius, segments, heignt, true); 178 | 179 | var mesh = new Mesh(); 180 | mesh.CombineMeshes(combine, true, false); 181 | return mesh; 182 | } 183 | 184 | public static Mesh Cube(float edge) 185 | { 186 | return Parallelepiped(Vector3.right*edge, Vector3.forward*edge, Vector3.up*edge); 187 | } 188 | 189 | public static Mesh Parallelepiped(Vector3 width, Vector3 length, Vector3 height) 190 | { 191 | var corner0 = -width/2 - length/2 - height/2; 192 | var corner1 = width/2 + length/2 + height/2; 193 | 194 | var combine = new CombineInstance[6]; 195 | combine[0].mesh = Quad(corner0, length, width); 196 | combine[1].mesh = Quad(corner0, width, height); 197 | combine[2].mesh = Quad(corner0, height, length); 198 | combine[3].mesh = Quad(corner1, -width, -length); 199 | combine[4].mesh = Quad(corner1, -height, -width); 200 | combine[5].mesh = Quad(corner1, -length, -height); 201 | 202 | var mesh = new Mesh(); 203 | mesh.CombineMeshes(combine, true, false); 204 | return mesh; 205 | } 206 | 207 | //public static Mesh Octahedron(float radius) 208 | //{ 209 | // var v = new Vector3[6]; 210 | // v[0] = new Vector3(0, -radius, 0); 211 | // v[1] = new Vector3(-radius, 0, 0); 212 | // v[2] = new Vector3(0, 0, -radius); 213 | // v[3] = new Vector3(+radius, 0, 0); 214 | // v[4] = new Vector3(0, 0, +radius); 215 | // v[5] = new Vector3(0, radius, 0); 216 | 217 | // var mesh = new Mesh 218 | // { 219 | // vertices = v, 220 | // triangles = new[] { 0, 1, 2, 221 | // 0, 2, 3, 222 | // 0, 3, 4, 223 | // 0, 4, 1, 224 | // 5, 2, 1, 225 | // 5, 3, 2, 226 | // 5, 4, 3, 227 | // 5, 1, 4} 228 | // }; 229 | // mesh.RecalculateNormals(); 230 | // return mesh; 231 | //} 232 | 233 | //public static Mesh Octahedron(float radius) 234 | //{ 235 | // var v0 = new Vector3(0, -radius, 0); 236 | // var v1 = new Vector3(-radius, 0, 0); 237 | // var v2 = new Vector3(0, 0, -radius); 238 | // var v3 = new Vector3(+radius, 0, 0); 239 | // var v4 = new Vector3(0, 0, +radius); 240 | // var v5 = new Vector3(0, radius, 0); 241 | 242 | // var combine = new CombineInstance[8]; 243 | // combine[0].mesh = Triangle(v0, v1, v2); 244 | // combine[1].mesh = Triangle(v0, v2, v3); 245 | // combine[2].mesh = Triangle(v0, v3, v4); 246 | // combine[3].mesh = Triangle(v0, v4, v1); 247 | // combine[4].mesh = Triangle(v5, v2, v1); 248 | // combine[5].mesh = Triangle(v5, v3, v2); 249 | // combine[6].mesh = Triangle(v5, v4, v3); 250 | // combine[7].mesh = Triangle(v5, v1, v4); 251 | 252 | // var mesh = new Mesh(); 253 | // mesh.CombineMeshes(combine, true, false); 254 | // return mesh; 255 | //} 256 | 257 | public static Mesh Octahedron(float radius) 258 | { 259 | return BiPyramid(1, 4, 1); 260 | } 261 | 262 | //public static Mesh Icosahedron(float radius) 263 | //{ 264 | // float a = 1; 265 | // float b = (1 + Mathf.Sqrt(5)) / 2; 266 | // float c = 0; 267 | // float scale = radius / Mathf.Sqrt(a * a + b * b + c * c); 268 | // a = a * scale; 269 | // b = b * scale; 270 | // c = c * scale; 271 | 272 | // var v0 = new Vector3(-a, b, c); 273 | // var v1 = new Vector3(a, b, c); 274 | // var v2 = new Vector3(-a, -b, c); 275 | // var v3 = new Vector3(a, -b, c); 276 | // var v4 = new Vector3(c, -a, b); 277 | // var v5 = new Vector3(c, a, b); 278 | // var v6 = new Vector3(c, -a, -b); 279 | // var v7 = new Vector3(c, a, -b); 280 | // var v8 = new Vector3(b, c, -a); 281 | // var v9 = new Vector3(b, c, a); 282 | // var v10 = new Vector3(-b, c, -a); 283 | // var v11 = new Vector3(-b, c, a); 284 | 285 | // var combine = new CombineInstance[20]; 286 | // combine[0].mesh = Triangle(v0, v11, v5); 287 | // combine[1].mesh = Triangle(v0, v5, v1); 288 | // combine[2].mesh = Triangle(v0, v1, v7); 289 | // combine[3].mesh = Triangle(v0, v7, v10); 290 | // combine[4].mesh = Triangle(v0, v10, v11); 291 | // combine[5].mesh = Triangle(v1, v5, v9); 292 | // combine[6].mesh = Triangle(v5, v11, v4); 293 | // combine[7].mesh = Triangle(v11, v10, v2); 294 | // combine[8].mesh = Triangle(v10, v7, v6); 295 | // combine[9].mesh = Triangle(v7, v1, v8); 296 | // combine[10].mesh = Triangle(v3, v9, v4); 297 | // combine[11].mesh = Triangle(v3, v4, v2); 298 | // combine[12].mesh = Triangle(v3, v2, v6); 299 | // combine[13].mesh = Triangle(v3, v6, v8); 300 | // combine[14].mesh = Triangle(v3, v8, v9); 301 | // combine[15].mesh = Triangle(v4, v9, v5); 302 | // combine[16].mesh = Triangle(v2, v4, v11); 303 | // combine[17].mesh = Triangle(v6, v2, v10); 304 | // combine[18].mesh = Triangle(v8, v6, v7); 305 | // combine[19].mesh = Triangle(v9, v8, v1); 306 | 307 | // var mesh = new Mesh(); 308 | // mesh.CombineMeshes(combine, true, false); 309 | // return mesh; 310 | //} 311 | 312 | public static Mesh Icosahedron(float radius) 313 | { 314 | var magicAngle = Mathf.PI*26.565f/180; 315 | var segmentAngle = Mathf.PI * 72 / 180; 316 | var currentAngle = 0f; 317 | 318 | var v = new Vector3[12]; 319 | v[0] = new Vector3(0, radius, 0); 320 | v[11] = new Vector3(0, -radius, 0); 321 | 322 | for(var i=1; i<6; i++) 323 | { 324 | v[i] = new Vector3(radius * Mathf.Sin(currentAngle) * Mathf.Cos(magicAngle), 325 | radius * Mathf.Sin(magicAngle), 326 | radius * Mathf.Cos(currentAngle) * Mathf.Cos(magicAngle)); 327 | currentAngle += segmentAngle; 328 | } 329 | currentAngle = Mathf.PI*36/180; 330 | for(var i=6; i<11; i++) 331 | { 332 | v[i] = new Vector3(radius * Mathf.Sin(currentAngle) * Mathf.Cos(-magicAngle), 333 | radius * Mathf.Sin(-magicAngle), 334 | radius * Mathf.Cos(currentAngle) * Mathf.Cos(-magicAngle)); 335 | currentAngle += segmentAngle; 336 | } 337 | 338 | var combine = new CombineInstance[20]; 339 | combine[0].mesh = Triangle(v[0], v[1], v[2]); 340 | combine[1].mesh = Triangle(v[0], v[2], v[3]); 341 | combine[2].mesh = Triangle(v[0], v[3], v[4]); 342 | combine[3].mesh = Triangle(v[0], v[4], v[5]); 343 | combine[4].mesh = Triangle(v[0], v[5], v[1]); 344 | 345 | combine[5].mesh = Triangle(v[11], v[7], v[6]); 346 | combine[6].mesh = Triangle(v[11], v[8], v[7]); 347 | combine[7].mesh = Triangle(v[11], v[9], v[8]); 348 | combine[8].mesh = Triangle(v[11], v[10], v[9]); 349 | combine[9].mesh = Triangle(v[11], v[6], v[10]); 350 | 351 | combine[10].mesh = Triangle(v[2], v[1], v[6]); 352 | combine[11].mesh = Triangle(v[3], v[2], v[7]); 353 | combine[12].mesh = Triangle(v[4], v[3], v[8]); 354 | combine[13].mesh = Triangle(v[5], v[4], v[9]); 355 | combine[14].mesh = Triangle(v[1], v[5], v[10]); 356 | 357 | combine[15].mesh = Triangle(v[6], v[7], v[2]); 358 | combine[16].mesh = Triangle(v[7], v[8], v[3]); 359 | combine[17].mesh = Triangle(v[8], v[9], v[4]); 360 | combine[18].mesh = Triangle(v[9], v[10], v[5]); 361 | combine[19].mesh = Triangle(v[10], v[6], v[1]); 362 | 363 | var mesh = new Mesh(); 364 | mesh.CombineMeshes(combine, true, false); 365 | return mesh; 366 | } 367 | 368 | //public static Mesh Cylinder(Vector3 origin, Vector3 width, Vector3 length, int widthCount, int lengthCount) 369 | //{ 370 | // var combine = new CombineInstance[widthCount * lengthCount]; 371 | 372 | // var i = 0; 373 | // for (var x = 0; x < widthCount; x++) 374 | // { 375 | // for (var y = 0; y < widthCount; y++) 376 | // { 377 | // combine[i].mesh = Quad(origin + width * x + length * y, width, length); 378 | // i++; 379 | // } 380 | // } 381 | 382 | // var mesh = new Mesh(); 383 | // mesh.CombineMeshes(combine, true, false); 384 | // return mesh; 385 | //} 386 | 387 | //public static Mesh Ring(int segmentCount, Vector3 centre, float radius, float v, bool buildTriangles) 388 | //{ 389 | // var vertices = new List(); 390 | // var uv = new List(); 391 | // var normals = new List(); 392 | // var triangles = new List(); 393 | 394 | // float angleInc = (Mathf.PI * 2.0f) / segmentCount; 395 | 396 | // for (int i = 0; i <= segmentCount; i++) 397 | // { 398 | // float angle = angleInc * i; 399 | 400 | // var unitPosition = Vector3.zero; 401 | // unitPosition.x = Mathf.Cos(angle); 402 | // unitPosition.z = Mathf.Sin(angle); 403 | 404 | // vertices.Add(centre + unitPosition * radius); 405 | // normals.Add(unitPosition); 406 | // uv.Add(new Vector2((float)i / segmentCount, v)); 407 | 408 | // if (i > 0 && buildTriangles) 409 | // { 410 | // int baseIndex = vertices.Count - 1; 411 | 412 | // int vertsPerRow = segmentCount + 1; 413 | 414 | // int index0 = baseIndex; 415 | // int index1 = baseIndex - 1; 416 | // int index2 = baseIndex - vertsPerRow; 417 | // int index3 = baseIndex - vertsPerRow - 1; 418 | 419 | // triangles.AddRange(new [] {index0, index2, index1}); 420 | // triangles.AddRange(new [] {index2, index3, index1}); 421 | // } 422 | // } 423 | // var mesh = new Mesh 424 | // { 425 | // vertices = vertices.ToArray(), 426 | // normals = normals.ToArray(), 427 | // uv = uv.ToArray(), 428 | // triangles = triangles.ToArray() 429 | // }; 430 | 431 | // return mesh; 432 | //} 433 | 434 | public static Mesh Spherify(Mesh mesh, float radius = 1) 435 | { 436 | var vertices = mesh.vertices; 437 | var normals = mesh.normals; 438 | var center = Vector3.zero; 439 | for (var i = 0; i < vertices.Length; i++) 440 | { 441 | center += vertices[i]; 442 | } 443 | center /= vertices.Length; 444 | 445 | for (var i = 0; i < vertices.Length; i++) 446 | { 447 | normals[i] = (vertices[i] - center).normalized; 448 | vertices[i] = normals[i] * radius; 449 | 450 | } 451 | mesh.vertices = vertices; 452 | mesh.normals = normals; 453 | return mesh; 454 | } 455 | 456 | public static Vector3 MiddleVector(Vector3 vertex0, Vector3 vertex1) 457 | { 458 | return (vertex0 + vertex1) * 0.5f; 459 | } 460 | 461 | public static Mesh Subdivide(Mesh mesh) 462 | { 463 | var oldTriangles = mesh.triangles; 464 | var vertices = new List(mesh.vertices); 465 | var normals = new List(mesh.normals); 466 | var uv = new List(mesh.uv); 467 | var triangles = new List(); 468 | 469 | for (var i = 0; i < oldTriangles.Length - 2; i += 3) 470 | { 471 | var v0 = oldTriangles[i]; 472 | var v1 = oldTriangles[i + 1]; 473 | var v2 = oldTriangles[i + 2]; 474 | 475 | vertices.Add(MiddleVector(vertices[v0], vertices[v1])); 476 | vertices.Add(MiddleVector(vertices[v1], vertices[v2])); 477 | vertices.Add(MiddleVector(vertices[v2], vertices[v0])); 478 | 479 | normals.Add(MiddleVector(normals[v0], normals[v1])); 480 | normals.Add(MiddleVector(normals[v1], normals[v2])); 481 | normals.Add(MiddleVector(normals[v2], normals[v0])); 482 | 483 | uv.Add(MiddleVector(uv[v0], uv[v1])); 484 | uv.Add(MiddleVector(uv[v1], uv[v2])); 485 | uv.Add(MiddleVector(uv[v2], uv[v0])); 486 | 487 | var v01 = vertices.Count - 3; 488 | var v12 = vertices.Count - 2; 489 | var v20 = vertices.Count - 1; 490 | 491 | triangles.AddRange(new[] { v0, v01, v20 }); 492 | triangles.AddRange(new[] { v1, v12, v01 }); 493 | triangles.AddRange(new[] { v2, v20, v12 }); 494 | triangles.AddRange(new[] { v01, v12, v20 }); 495 | } 496 | mesh.vertices = vertices.ToArray(); 497 | mesh.normals = normals.ToArray(); 498 | mesh.uv = uv.ToArray(); 499 | mesh.triangles = triangles.ToArray(); 500 | return mesh; 501 | } 502 | 503 | public static Mesh CombineMeshes(List meshes, List matrices = null) 504 | { 505 | var combine = new CombineInstance[meshes.Count]; 506 | for (var i = 0; i < meshes.Count; i++) 507 | { 508 | combine[i].mesh = meshes[i]; 509 | if (matrices != null) 510 | { 511 | combine[i].transform = matrices[i]; 512 | } 513 | } 514 | 515 | var mesh = new Mesh(); 516 | if (matrices != null) 517 | { 518 | mesh.CombineMeshes(combine, true, true); 519 | } 520 | else 521 | { 522 | mesh.CombineMeshes(combine, true, false); 523 | } 524 | return mesh; 525 | } 526 | 527 | public static Mesh CombineMeshesWithSubMeshes(List meshes, List> submeshMask = null) 528 | { 529 | var vertices = new List(); 530 | var normals = new List(); 531 | var uv = new List(); 532 | var triangles = new List(); 533 | var submeshes = new List>(); 534 | 535 | for (var i = 0; i < 100; i++) 536 | { 537 | submeshes.Add(new List()); 538 | } 539 | 540 | for (var i = 0; i < meshes.Count; i++) 541 | { 542 | for (var j = 0; j < meshes[i].subMeshCount; j++) 543 | { 544 | var newSubmesh = meshes[i].GetTriangles(j); 545 | for (var k = 0; k < newSubmesh.Length; k++) 546 | { 547 | newSubmesh[k] += vertices.Count; 548 | } 549 | 550 | if (submeshMask != null) 551 | { 552 | submeshes[submeshMask[i][j]].AddRange(newSubmesh); 553 | } 554 | else 555 | { 556 | submeshes[j].AddRange(newSubmesh); 557 | } 558 | } 559 | var newTriangles = meshes[i].triangles; 560 | for (var j = 0; j < newTriangles.Length; j++) 561 | { 562 | triangles.Add(newTriangles[j] + vertices.Count); 563 | } 564 | vertices.AddRange(meshes[i].vertices); 565 | normals.AddRange(meshes[i].normals); 566 | uv.AddRange(meshes[i].uv); 567 | } 568 | 569 | var mesh = new Mesh 570 | { 571 | vertices = vertices.ToArray(), 572 | normals = normals.ToArray(), 573 | uv = uv.ToArray(), 574 | triangles = triangles.ToArray(), 575 | subMeshCount = submeshes.Count 576 | }; 577 | for (var i = 0; i < submeshes.Count; i++) 578 | { 579 | mesh.SetTriangles(submeshes[i].ToArray(), i); 580 | } 581 | return mesh; 582 | } 583 | } 584 | } 585 | -------------------------------------------------------------------------------- /Assets/Scripts/Floor plan/FloorPlanGenerator.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using UnityEngine; 5 | using Random = UnityEngine.Random; 6 | 7 | 8 | public class GridVector 9 | { 10 | public static GridVector plusX = new GridVector(1, 0); 11 | public static GridVector minusX = new GridVector(-1, 0); 12 | public static GridVector plusY = new GridVector(0, 1); 13 | public static GridVector minusY = new GridVector(0, -1); 14 | public static GridVector zero = new GridVector(0, 0); 15 | 16 | public int x; 17 | public int y; 18 | 19 | public GridVector minimized 20 | { 21 | get 22 | { 23 | var m = new GridVector(this); 24 | if (m.x > 0) m.x = 1; 25 | if (m.x < 0) m.x = -1; 26 | if (m.y > 0) m.y = 1; 27 | if (m.y < 0) m.y = -1; 28 | return m; 29 | } 30 | } 31 | 32 | public GridVector(int x, int y) 33 | { 34 | this.x = x; 35 | this.y = y; 36 | } 37 | 38 | public GridVector(GridVector point) 39 | { 40 | x = point.x; 41 | y = point.y; 42 | } 43 | 44 | public static GridVector operator +(GridVector a, GridVector b) 45 | { 46 | return new GridVector(a.x + b.x, a.y + b.y); 47 | } 48 | 49 | public static GridVector operator -(GridVector a, GridVector b) 50 | { 51 | return new GridVector(a.x - b.x, a.y - b.y); 52 | } 53 | 54 | public static GridVector operator /(GridVector a, int b) 55 | { 56 | return new GridVector(a.x / b, a.y / b); 57 | } 58 | 59 | public static GridVector operator *(GridVector a, int b) 60 | { 61 | return new GridVector(a.x * b, a.y * b); 62 | } 63 | 64 | public static bool operator ==(GridVector a, GridVector b) 65 | { 66 | if (System.Object.ReferenceEquals(a, b)) 67 | { 68 | return true; 69 | } 70 | if ((object)a == null || (object)b == null) 71 | { 72 | return false; 73 | } 74 | return a.x == b.x && a.y == b.y; 75 | } 76 | 77 | public static bool operator !=(GridVector a, GridVector b) 78 | { 79 | return !(a == b); 80 | } 81 | 82 | public override string ToString() 83 | { 84 | return "(" + x + ", " + y + ")"; 85 | } 86 | } 87 | 88 | public class RoomWall 89 | { 90 | public bool canGrow; 91 | public GridVector start; 92 | public GridVector end; 93 | 94 | public GridVector outwards 95 | { 96 | get { return new GridVector(-direction.y, direction.x); } 97 | } 98 | 99 | public GridVector direction 100 | { 101 | get { return end - start; } 102 | } 103 | 104 | public int length 105 | { 106 | get { return Math.Abs(end.x - start.x) + Math.Abs(end.y - start.y); } 107 | } 108 | 109 | public RoomWall() 110 | { 111 | } 112 | 113 | public RoomWall(GridVector start, GridVector end) 114 | { 115 | this.start = start; 116 | this.end = end; 117 | } 118 | 119 | public RoomWall(RoomWall wall) 120 | { 121 | start = wall.start; 122 | end = wall.end; 123 | } 124 | 125 | public static int CompareByLength(RoomWall a, RoomWall b) 126 | { 127 | if (a.length > b.length) return 1; 128 | if (a.length == b.length) return 0; 129 | return -1; 130 | } 131 | 132 | public static RoomWall operator +(RoomWall a, GridVector b) 133 | { 134 | var result = new RoomWall(a); 135 | result.start += b; 136 | result.end += b; 137 | return result; 138 | } 139 | 140 | public static RoomWall operator -(RoomWall a, GridVector b) 141 | { 142 | var result = new RoomWall(a); 143 | result.start -= b; 144 | result.end -= b; 145 | return result; 146 | } 147 | } 148 | 149 | 150 | public class Room 151 | { 152 | // Примыкающие стены и углы считаются по часовой стрелке, если смотреть из центра комнаты 153 | public List corners; 154 | public Color color; 155 | public bool canSpawn = false; 156 | public List walls 157 | { 158 | get 159 | { 160 | var roomWalls = new List(); 161 | for (var i = 0; i < corners.Count; i++) 162 | { 163 | roomWalls.Add(new RoomWall(corners[i], i == corners.Count - 1 ? corners[0] : corners[i + 1])); 164 | } 165 | return roomWalls; 166 | } 167 | } 168 | public int perimeter 169 | { 170 | get 171 | { 172 | var p = 0; 173 | foreach (var wall in walls) 174 | { 175 | p += wall.length; 176 | } 177 | return p; 178 | } 179 | } 180 | 181 | public Room(Color color, List corners) 182 | { 183 | this.color = color; 184 | this.corners = corners; 185 | SortCorners(); 186 | } 187 | 188 | public GridVector SortCorners() 189 | { 190 | // Ищем границы комнаты 191 | var minX = corners[0].x; 192 | var maxX = corners[0].x; 193 | var minY = corners[0].y; 194 | var maxY = corners[0].y; 195 | foreach (var corner in corners) 196 | { 197 | if (corner.x < minX) minX = corner.x; 198 | if (corner.x > maxX) maxX = corner.x; 199 | if (corner.y < minY) minY = corner.y; 200 | if (corner.y > maxY) maxY = corner.y; 201 | } 202 | 203 | // Сортируем углы комнаты 204 | var oldC = new List(corners); 205 | var newC = new List(); 206 | bool parallelX = false; 207 | while (oldC.Count > 1) 208 | { 209 | // Ищем первый угол 210 | if (newC.Count == 0) 211 | { 212 | if (ScanUp(ref oldC, ref newC, minX, minY, maxY)) continue; 213 | if (ScanRight(ref oldC, ref newC, minX, minY, maxX)) continue; 214 | if (ScanDown(ref oldC, ref newC, minX, minY, minY)) continue; 215 | if (!ScanLeft(ref oldC, ref newC, minX, minY, minX)) 216 | { 217 | Debug.Log("Error on start"); 218 | return null; 219 | } 220 | } 221 | // Ищем остальные углы 222 | else 223 | { 224 | var last = newC[newC.Count - 1]; 225 | if (parallelX) 226 | { 227 | if (ScanRight(ref oldC, ref newC, last.x, last.y, maxX)) 228 | { 229 | parallelX = false; 230 | continue; 231 | } 232 | if (ScanLeft(ref oldC, ref newC, last.x, last.y, minX)) 233 | { 234 | parallelX = false; 235 | continue; 236 | } 237 | } 238 | else 239 | { 240 | if (ScanUp(ref oldC, ref newC, last.x, last.y, maxY)) 241 | { 242 | parallelX = true; 243 | continue; 244 | } 245 | if (ScanDown(ref oldC, ref newC, last.x, last.y, minY)) 246 | { 247 | parallelX = true; 248 | continue; 249 | } 250 | } 251 | Debug.Log("Error -------------------------------------------------"); 252 | Debug.Log("Corners: " + corners.Count); 253 | Debug.Log("OldC: " + oldC.Count); 254 | Debug.Log("NewC: " + newC.Count); 255 | Debug.Log(last); 256 | color = Color.red; 257 | return last; 258 | } 259 | } 260 | // Добавляем последний оставшийся угол 261 | newC.Add(oldC[0]); 262 | corners = newC; 263 | return null; 264 | } 265 | 266 | bool ScanLeft(ref List oldC, ref List newC, int startX, int startY, int minX) 267 | { 268 | for (var x = startX; x >= minX; x--) 269 | { 270 | var index = oldC.FindIndex(gv => gv.x == x && gv.y == startY); 271 | if (index > -1) 272 | { 273 | newC.Add(oldC[index]); 274 | oldC.RemoveAt(index); 275 | return true; 276 | } 277 | } 278 | return false; 279 | } 280 | 281 | bool ScanUp(ref List oldC, ref List newC, int startX, int startY, int maxY) 282 | { 283 | for (var y = startY; y <= maxY; y++) 284 | { 285 | var index = oldC.FindIndex(gv => gv.x == startX && gv.y == y); 286 | if (index > -1) 287 | { 288 | newC.Add(oldC[index]); 289 | oldC.RemoveAt(index); 290 | return true; 291 | } 292 | } 293 | return false; 294 | } 295 | 296 | bool ScanRight(ref List oldC, ref List newC, int startX, int startY, int maxX) 297 | { 298 | for (var x = startX; x <= maxX; x++) 299 | { 300 | var index = oldC.FindIndex(gv => gv.x == x && gv.y == startY); 301 | if (index > -1) 302 | { 303 | newC.Add(oldC[index]); 304 | oldC.RemoveAt(index); 305 | return true; 306 | } 307 | } 308 | return false; 309 | } 310 | 311 | bool ScanDown(ref List oldC, ref List newC, int startX, int startY, int minY) 312 | { 313 | for (var y = startY; y >= minY; y--) 314 | { 315 | var index = oldC.FindIndex(gv => gv.x == startX && gv.y == y); 316 | if (index > -1) 317 | { 318 | newC.Add(oldC[index]); 319 | oldC.RemoveAt(index); 320 | return true; 321 | } 322 | } 323 | return false; 324 | } 325 | 326 | public void GrowWall(RoomWall wall) 327 | { 328 | for (var i = 0; i < corners.Count; i++) 329 | { 330 | if (i < corners.Count - 1) 331 | { 332 | if (corners[i] == wall.start && corners[i + 1] == wall.end) 333 | { 334 | corners[i] += wall.outwards.minimized; 335 | corners[i + 1] += wall.outwards.minimized; 336 | return; 337 | } 338 | if (corners[i] == wall.end && corners[i + 1] == wall.start) 339 | { 340 | corners[i] -= wall.outwards.minimized; 341 | corners[i + 1] -= wall.outwards.minimized; 342 | return; 343 | } 344 | } 345 | else 346 | { 347 | if (corners[i] == wall.start && corners[0] == wall.end) 348 | { 349 | corners[i] += wall.outwards.minimized; 350 | corners[0] += wall.outwards.minimized; 351 | return; 352 | } 353 | if (corners[i] == wall.end && corners[0] == wall.start) 354 | { 355 | corners[i] -= wall.outwards.minimized; 356 | corners[0] -= wall.outwards.minimized; 357 | return; 358 | } 359 | } 360 | } 361 | } 362 | 363 | public void AddWall(RoomWall wall) 364 | { 365 | for (var i = 0; i < corners.Count; i++) 366 | { 367 | if (corners[i] == wall.start) 368 | { 369 | corners.Add(wall.end); 370 | corners.Add(wall.end); 371 | SortCorners(); 372 | return; 373 | } 374 | if (corners[i] == wall.end) 375 | { 376 | corners.Add(wall.start); 377 | corners.Add(wall.start); 378 | SortCorners(); 379 | return; 380 | } 381 | } 382 | corners.Add(wall.start); 383 | corners.Add(wall.start); 384 | corners.Add(wall.end); 385 | corners.Add(wall.end); 386 | SortCorners(); 387 | } 388 | 389 | public static int CompareByPerimeter(Room a, Room b) 390 | { 391 | if (a.perimeter > b.perimeter) return 1; 392 | if (a.perimeter == b.perimeter) return 0; 393 | return -1; 394 | } 395 | } 396 | 397 | 398 | public class FloorPlanGenerator : MonoBehaviour 399 | { 400 | public Texture2D testWalls; 401 | public Texture2D transparent; 402 | public Renderer scanRenderer; 403 | public bool growCorners; 404 | public bool growCenters; 405 | public bool capture = true; 406 | public bool paused; 407 | 408 | private Texture2D texture; 409 | private Texture2D scanTexture; 410 | private Transform tr; 411 | private Camera cam; 412 | private RaycastHit selected; 413 | private System.Random random; 414 | private List rooms; 415 | private int growableRooms; 416 | private int growableCorners; 417 | private int bigCorner; 418 | private int bigCenter; 419 | private int screenshotCount; 420 | private Room bigCornerRoom; 421 | private Room bigCenterRoom; 422 | private List growableWalls; 423 | private List cornerSegments; 424 | private List segments; 425 | private List centerSegments; 426 | 427 | void Start() 428 | { 429 | tr = transform; 430 | cam = Camera.main; 431 | random = new System.Random(DateTime.Now.Millisecond); 432 | rooms = new List(); 433 | growableWalls = new List(); 434 | cornerSegments = new List(); 435 | segments = new List(); 436 | centerSegments = new List(); 437 | texture = new Texture2D(testWalls.width, testWalls.height) { filterMode = FilterMode.Point }; 438 | scanTexture = new Texture2D(transparent.width, transparent.height) { filterMode = FilterMode.Point }; 439 | ResetTexture(); 440 | ResetDebugTexture(); 441 | RandomRooms(); 442 | //InvokeRepeating("TakeScreenshot", 0, 0.1f); 443 | } 444 | 445 | void TakeScreenshot() 446 | { 447 | Application.CaptureScreenshot(screenshotCount + ".png"); 448 | screenshotCount++; 449 | } 450 | 451 | void Update() 452 | { 453 | if (Input.GetKeyDown(KeyCode.Escape)) 454 | { 455 | Application.Quit(); 456 | } 457 | if (Input.GetKeyDown(KeyCode.Alpha1)) 458 | { 459 | scanRenderer.enabled = !scanRenderer.enabled; 460 | } 461 | if (Input.GetKeyDown(KeyCode.Return)) 462 | { 463 | ResetTexture(); 464 | ResetDebugTexture(); 465 | } 466 | if (Input.GetKeyDown(KeyCode.LeftShift) || Input.GetKeyDown(KeyCode.RightShift)) 467 | { 468 | RandomWalls(); 469 | RandomRooms(); 470 | ResetDebugTexture(); 471 | } 472 | if (Input.GetKeyDown(KeyCode.LeftControl) || Input.GetKeyDown(KeyCode.RightControl)) 473 | { 474 | ResetTexture(); 475 | RandomRooms(); 476 | ResetDebugTexture(); 477 | } 478 | if (Input.GetMouseButtonDown(0)) 479 | { 480 | if (Physics.Raycast(cam.ScreenPointToRay(Input.mousePosition), out selected) && selected.transform == tr) 481 | { 482 | var x = (int)(selected.textureCoord.x * texture.width); 483 | var y = (int)(selected.textureCoord.y * texture.height); 484 | 485 | if (!CheckRect(x - 1, y - 1, x + 1, y + 1, Color.white, Color.white)) return; 486 | 487 | var color = new Color(Random.value * 0.6f + 0.1f, Random.value * 0.6f + 0.1f, 488 | Random.value * 0.6f + 0.1f); 489 | rooms.Add(new Room(color, 490 | new List 491 | { 492 | new GridVector(x - 1, y - 1), 493 | new GridVector(x - 1, y + 1), 494 | new GridVector(x + 1, y + 1), 495 | new GridVector(x + 1, y - 1) 496 | })); 497 | DrawRoom(rooms[rooms.Count - 1]); 498 | } 499 | } 500 | 501 | ResetDebugTexture(); 502 | foreach (var room in rooms) 503 | { 504 | foreach (var wall in room.walls) 505 | { 506 | BresenhamLine(wall, room.color); 507 | } 508 | } 509 | texture.Apply(); 510 | 511 | if (Input.GetKeyDown(KeyCode.Space)) 512 | { 513 | paused = !paused; 514 | } 515 | if (!paused) 516 | { 517 | growableRooms = 0; 518 | growableCorners = 0; 519 | bigCorner = 0; 520 | bigCenter = 0; 521 | foreach (var room in rooms) 522 | { 523 | segments.Clear(); 524 | growableWalls.Clear(); 525 | cornerSegments.Clear(); 526 | centerSegments.Clear(); 527 | 528 | FindCandidates(room); 529 | 530 | if (cornerSegments.Count > 0) 531 | { 532 | var l = LongWall(cornerSegments).length; 533 | if (bigCorner < l && !room.canSpawn) 534 | { 535 | bigCornerRoom = room; 536 | bigCorner = l; 537 | } 538 | } 539 | if (centerSegments.Count > 0) 540 | { 541 | var l = LongWall(centerSegments).length; 542 | if (bigCenter < l) 543 | { 544 | bigCenterRoom = room; 545 | bigCenter = l; 546 | } 547 | } 548 | 549 | GrowRoom(room); 550 | foreach (var wall in room.walls) 551 | { 552 | BresenhamLine(wall, room.color); 553 | } 554 | texture.Apply(); 555 | scanTexture.Apply(); 556 | } 557 | if (growableRooms == 0) 558 | { 559 | if (growableCorners > 0) 560 | { 561 | growCorners = true; 562 | bigCornerRoom.canSpawn = true; 563 | } 564 | else 565 | { 566 | growCorners = false; 567 | growCenters = true; 568 | bigCenterRoom.canSpawn = true; 569 | } 570 | } 571 | } 572 | 573 | renderer.material.mainTexture = texture; 574 | scanRenderer.material.mainTexture = scanTexture; 575 | } 576 | 577 | void FindCandidates(Room room) 578 | { 579 | foreach (var wall in room.walls) 580 | { 581 | segments.AddRange(FindSegments(wall, Color.white, room.color)); 582 | foreach (var segment in segments) 583 | { 584 | if ((segment.start == wall.start && segment.end == wall.end) || 585 | (segment.start == wall.end && segment.end == wall.start)) 586 | { 587 | growableWalls.Add(segment); 588 | } 589 | else if (segment.start == wall.start || segment.end == wall.end || 590 | segment.start == wall.end || segment.end == wall.start) 591 | { 592 | cornerSegments.Add(segment); 593 | growableCorners++; 594 | } 595 | else 596 | { 597 | centerSegments.Add(segment); 598 | } 599 | } 600 | } 601 | } 602 | 603 | void GrowRoom(Room room) 604 | { 605 | if (growableWalls.Count > 0) 606 | { 607 | room.GrowWall(LongWall(growableWalls)); 608 | growableRooms++; 609 | } 610 | else if (growCorners) 611 | { 612 | if (cornerSegments.Count > 0 && room.canSpawn) 613 | { 614 | var wall = LongWall(cornerSegments); 615 | room.AddWall(wall); 616 | room.GrowWall(wall); 617 | room.canSpawn = false; 618 | } 619 | } 620 | else if (growCenters) 621 | { 622 | if (cornerSegments.Count > 0) 623 | { 624 | var wall = LongWall(cornerSegments); 625 | room.AddWall(wall); 626 | room.GrowWall(wall); 627 | } 628 | else if (centerSegments.Count > 0) 629 | { 630 | var wall = LongWall(centerSegments); 631 | room.AddWall(wall); 632 | room.GrowWall(wall); 633 | } 634 | } 635 | } 636 | 637 | List FindSegments(RoomWall wall, Color freeColor, Color roomColor) 638 | { 639 | var moved = wall + wall.outwards.minimized; 640 | var x0 = moved.start.x; 641 | var y0 = moved.start.y; 642 | var x1 = moved.end.x; 643 | var y1 = moved.end.y; 644 | var segments = new List(); 645 | GridVector start = null; 646 | GridVector end = null; 647 | 648 | bool steep = Math.Abs(y1 - y0) > Math.Abs(x1 - x0); 649 | if (steep) 650 | { 651 | Swap(ref x0, ref y0); 652 | Swap(ref x1, ref y1); 653 | } 654 | if (x0 > x1) 655 | { 656 | Swap(ref x0, ref x1); 657 | Swap(ref y0, ref y1); 658 | } 659 | for (int x = x0; x <= x1; x++) 660 | { 661 | for (int y = y0; y <= y1; y++) 662 | { 663 | int coordX = steep ? y : x; 664 | int coordY = steep ? x : y; 665 | Color color = texture.GetPixel(coordX, coordY); 666 | if (color != freeColor && color != roomColor) 667 | { 668 | if (end != null && start != null) 669 | { 670 | var segment = new RoomWall(start, end); 671 | segment -= wall.outwards.minimized; 672 | segments.Add(segment); 673 | start = null; 674 | end = null; 675 | } 676 | scanTexture.SetPixel(coordX, coordY, Color.red); 677 | } 678 | else 679 | { 680 | if (start == null) 681 | { 682 | start = new GridVector(coordX, coordY); 683 | } 684 | end = new GridVector(coordX, coordY); 685 | scanTexture.SetPixel(coordX, coordY, Color.green); 686 | } 687 | } 688 | } 689 | if (end != null && start != null) 690 | { 691 | var segment = new RoomWall(start, end); 692 | segment -= wall.outwards.minimized; 693 | segments.Add(segment); 694 | } 695 | return segments; 696 | } 697 | 698 | bool CheckRect(int x0, int y0, int x1, int y1, Color freeColor, Color roomColor) 699 | { 700 | bool steep = Math.Abs(y1 - y0) > Math.Abs(x1 - x0); 701 | if (steep) 702 | { 703 | Swap(ref x0, ref y0); 704 | Swap(ref x1, ref y1); 705 | } 706 | if (x0 > x1) 707 | { 708 | Swap(ref x0, ref x1); 709 | Swap(ref y0, ref y1); 710 | } 711 | for (int x = x0; x <= x1; x++) 712 | { 713 | for (int y = y0; y <= y1; y++) 714 | { 715 | Color color = texture.GetPixel(steep ? y : x, steep ? x : y); 716 | if (color != freeColor && color != roomColor) return false; 717 | } 718 | } 719 | return true; 720 | } 721 | 722 | bool CheckRect(GridVector start, GridVector end, Color freeColor, Color roomColor) 723 | { 724 | return CheckRect(start.x, start.y, end.x, end.y, freeColor, roomColor); 725 | } 726 | 727 | bool CheckRect(RoomWall wall, Color freeColor, Color roomColor) 728 | { 729 | return CheckRect(wall.start, wall.end, freeColor, roomColor); 730 | } 731 | 732 | void Swap(ref T lhs, ref T rhs) 733 | { 734 | T temp = lhs; 735 | lhs = rhs; 736 | rhs = temp; 737 | } 738 | 739 | void BresenhamLine(int x0, int y0, int x1, int y1, Color color, Texture2D tex = null) 740 | { 741 | if (tex == null) tex = texture; 742 | bool steep = Math.Abs(y1 - y0) > Math.Abs(x1 - x0); 743 | if (steep) 744 | { 745 | Swap(ref x0, ref y0); 746 | Swap(ref x1, ref y1); 747 | } 748 | if (x0 > x1) 749 | { 750 | Swap(ref x0, ref x1); 751 | Swap(ref y0, ref y1); 752 | } 753 | int dx = x1 - x0; 754 | int dy = Math.Abs(y1 - y0); 755 | int error = dx/2; 756 | int ystep = (y0 < y1) ? 1 : -1; 757 | int y = y0; 758 | for (int x = x0; x <= x1; x++) 759 | { 760 | tex.SetPixel(steep ? y : x, steep ? x : y, color); 761 | error -= dy; 762 | if (error < 0) 763 | { 764 | y += ystep; 765 | error += dx; 766 | } 767 | } 768 | } 769 | 770 | void BresenhamLine(GridVector start, GridVector end, Color color, Texture2D tex = null) 771 | { 772 | BresenhamLine(start.x, start.y, end.x, end.y, color, tex); 773 | } 774 | 775 | void BresenhamLine(RoomWall wall, Color color, Texture2D tex = null) 776 | { 777 | BresenhamLine(wall.start, wall.end, color, tex); 778 | } 779 | 780 | RoomWall LongWall(List walls) 781 | { 782 | walls.Sort(RoomWall.CompareByLength); 783 | var longWalls = new List(); 784 | foreach (var line in walls) 785 | { 786 | if (line.length == walls[walls.Count - 1].length) 787 | { 788 | longWalls.Add(line); 789 | } 790 | } 791 | random = new System.Random(DateTime.Now.Millisecond); 792 | return longWalls[random.Next(longWalls.Count - 1)]; 793 | } 794 | 795 | void ResetTexture() 796 | { 797 | rooms.Clear(); 798 | growCorners = false; 799 | growCenters = false; 800 | screenshotCount = 0; 801 | texture.SetPixels(testWalls.GetPixels(0, 0, testWalls.width, testWalls.height)); 802 | texture.Apply(); 803 | renderer.material.mainTexture = texture; 804 | } 805 | void ResetDebugTexture() 806 | { 807 | scanTexture.SetPixels(transparent.GetPixels(0, 0, transparent.width, transparent.height)); 808 | scanTexture.Apply(); 809 | scanRenderer.material.mainTexture = scanTexture; 810 | } 811 | 812 | void DrawRoom(Room room) 813 | { 814 | foreach (var wall in room.walls) 815 | { 816 | BresenhamLine(wall, room.color); 817 | } 818 | texture.Apply(); 819 | } 820 | 821 | void RandomWalls() 822 | { 823 | rooms.Clear(); 824 | growCorners = false; 825 | growCenters = false; 826 | screenshotCount = 0; 827 | texture.SetPixels(transparent.GetPixels(0, 0, transparent.width, transparent.height)); 828 | var r = new List(); 829 | for (var i = 0; i < 3; i++) 830 | { 831 | r.Add(new GridVector(random.Next(16, texture.width / 3), random.Next(16, texture.height / 3))); 832 | r.Add(new GridVector(random.Next(texture.width / 3 * 2, texture.width - 16), random.Next(texture.height / 3 * 2, texture.height - 16))); 833 | } 834 | for (var i = 0; i < r.Count; i += 2) 835 | { 836 | for (var x = r[i].x; x < r[i+1].x; x++) 837 | { 838 | for (var y = r[i].y; y < r[i+1].y; y++) 839 | { 840 | texture.SetPixel(x, y, Color.black); 841 | } 842 | } 843 | } 844 | for (var i = 0; i < r.Count; i += 2) 845 | { 846 | for (int x = r[i].x + 1; x < r[i + 1].x - 1; x++) 847 | { 848 | for (int y = r[i].y + 1; y < r[i + 1].y - 1; y++) 849 | { 850 | texture.SetPixel(x, y, Color.white); 851 | } 852 | } 853 | } 854 | texture.Apply(); 855 | renderer.material.mainTexture = texture; 856 | } 857 | 858 | void RandomRooms() 859 | { 860 | for (int i = 0; i < 10; i++) 861 | { 862 | int x = random.Next(0, texture.width); 863 | int y = random.Next(0, texture.height); 864 | if (CheckRect(x - 1, y - 1, x + 1, y + 1, Color.white, Color.white)) 865 | { 866 | var color = new Color(Random.value*0.7f + 0.1f, Random.value*0.7f + 0.1f, 867 | Random.value*0.7f + 0.1f); 868 | rooms.Add(new Room(color, 869 | new List 870 | { 871 | new GridVector(x - 1, y - 1), 872 | new GridVector(x - 1, y + 1), 873 | new GridVector(x + 1, y + 1), 874 | new GridVector(x + 1, y - 1) 875 | })); 876 | DrawRoom(rooms[rooms.Count - 1]); 877 | } 878 | } 879 | } 880 | } --------------------------------------------------------------------------------