├── Assets
├── Scenes
│ ├── city_scene.unity
│ └── main_scene.unity
├── Resources
│ └── Textures
│ │ ├── Door
│ │ ├── tex_door_1.png
│ │ ├── tex_door_2.png
│ │ ├── tex_door_3.png
│ │ ├── tex_door_4.png
│ │ ├── tex_door_5.png
│ │ ├── tex_door_6.png
│ │ ├── tex_door_7.png
│ │ ├── tex_door_8.png
│ │ └── tex_door_9.png
│ │ ├── Roof
│ │ ├── tex_roof_1.png
│ │ ├── tex_roof_10.png
│ │ ├── tex_roof_2.png
│ │ ├── tex_roof_3.png
│ │ ├── tex_roof_4.png
│ │ ├── tex_roof_6.png
│ │ ├── tex_roof_7.png
│ │ ├── tex_roof_8.png
│ │ └── tex_roof_9.png
│ │ ├── Shutter
│ │ ├── tex_shutter_1.png
│ │ ├── tex_shutter_2.png
│ │ ├── tex_shutter_3.png
│ │ ├── tex_shutter_4.png
│ │ ├── tex_shutter_5.png
│ │ ├── tex_shutter_6.png
│ │ └── tex_shutter_7.png
│ │ ├── RoofBase
│ │ ├── tex_roof_base_1.png
│ │ ├── tex_roof_base_2.png
│ │ ├── tex_roof_base_3.png
│ │ ├── tex_roof_base_4.png
│ │ └── tex_roof_base_5.png
│ │ ├── CompDecor
│ │ ├── tex_comp_decor_1.png
│ │ ├── tex_comp_decor_2.png
│ │ ├── tex_comp_decor_3.png
│ │ ├── tex_comp_decor_4.png
│ │ ├── tex_comp_decor_5.png
│ │ ├── tex_comp_decor_6.png
│ │ ├── tex_comp_decor_7.png
│ │ ├── tex_comp_decor_8.png
│ │ └── tex_comp_decor_9.png
│ │ ├── RoofDecor
│ │ ├── tex_roof_decor_1.png
│ │ ├── tex_roof_decor_2.png
│ │ ├── tex_roof_decor_3.png
│ │ └── tex_roof_decor_4.png
│ │ └── CompDecorSimple
│ │ └── tex_comp_decor_simple_1.png
├── Standard Assets
│ ├── Shutter
│ │ ├── ShutterSide.cs
│ │ └── Shuter.cs
│ ├── Roof
│ │ ├── RoofType.cs
│ │ ├── Roof.cs
│ │ ├── SinglePeakRoof.cs
│ │ ├── RoofBase.cs
│ │ ├── FlatRoof.cs
│ │ ├── RoofDecoration.cs
│ │ └── DoublePeakRoof.cs
│ ├── General
│ │ ├── BuildMode.cs
│ │ ├── ProceduralObject.cs
│ │ ├── ComponentCoordinate.cs
│ │ ├── TextureLine.cs
│ │ ├── FaceComponent.cs
│ │ ├── ComponentBody.cs
│ │ ├── ProceduralTexture.cs
│ │ ├── ComponentFrame.cs
│ │ ├── Util.cs
│ │ └── DrawableObject.cs
│ ├── Door
│ │ ├── DoorBody.cs
│ │ └── Door.cs
│ ├── Window
│ │ ├── WindowBody.cs
│ │ ├── Window.cs
│ │ └── WindowDecor.cs
│ ├── Balcony
│ │ ├── BalconyBody.cs
│ │ ├── BalconyFrame.cs
│ │ ├── BalconyFloor.cs
│ │ ├── Balcony.cs
│ │ └── BalconyRail.cs
│ ├── Interface
│ │ ├── ICombinable.cs
│ │ └── IDrawable.cs
│ ├── City
│ │ ├── Road.cs
│ │ ├── Sidewalk.cs
│ │ ├── Edge.cs
│ │ ├── BuildingLot.cs
│ │ └── Block.cs
│ ├── Managers
│ │ ├── ColorManager.cs
│ │ ├── CityMapManager.cs
│ │ ├── BuildingManager.cs
│ │ ├── MaterialManager.cs
│ │ └── TextureManager.cs
│ ├── Building
│ │ ├── Building.cs
│ │ ├── BuildingMesh.cs
│ │ └── Face.cs
│ └── Editor
│ │ └── Builder.cs
└── Scripts
│ ├── BuildingController.cs
│ ├── CityMapController.cs
│ └── CameraController.cs
├── ProjectSettings
├── AudioManager.asset
├── InputManager.asset
├── TagManager.asset
├── TimeManager.asset
├── EditorSettings.asset
├── NavMeshLayers.asset
├── NetworkManager.asset
├── DynamicsManager.asset
├── GraphicsSettings.asset
├── Physics2DSettings.asset
├── ProjectSettings.asset
├── QualitySettings.asset
└── EditorBuildSettings.asset
├── README.md
├── MIT-LICENSE
└── .gitignore
/Assets/Scenes/city_scene.unity:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tkaretsos/ProceduralBuildings/HEAD/Assets/Scenes/city_scene.unity
--------------------------------------------------------------------------------
/Assets/Scenes/main_scene.unity:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tkaretsos/ProceduralBuildings/HEAD/Assets/Scenes/main_scene.unity
--------------------------------------------------------------------------------
/ProjectSettings/AudioManager.asset:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tkaretsos/ProceduralBuildings/HEAD/ProjectSettings/AudioManager.asset
--------------------------------------------------------------------------------
/ProjectSettings/InputManager.asset:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tkaretsos/ProceduralBuildings/HEAD/ProjectSettings/InputManager.asset
--------------------------------------------------------------------------------
/ProjectSettings/TagManager.asset:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tkaretsos/ProceduralBuildings/HEAD/ProjectSettings/TagManager.asset
--------------------------------------------------------------------------------
/ProjectSettings/TimeManager.asset:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tkaretsos/ProceduralBuildings/HEAD/ProjectSettings/TimeManager.asset
--------------------------------------------------------------------------------
/ProjectSettings/EditorSettings.asset:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tkaretsos/ProceduralBuildings/HEAD/ProjectSettings/EditorSettings.asset
--------------------------------------------------------------------------------
/ProjectSettings/NavMeshLayers.asset:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tkaretsos/ProceduralBuildings/HEAD/ProjectSettings/NavMeshLayers.asset
--------------------------------------------------------------------------------
/ProjectSettings/NetworkManager.asset:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tkaretsos/ProceduralBuildings/HEAD/ProjectSettings/NetworkManager.asset
--------------------------------------------------------------------------------
/ProjectSettings/DynamicsManager.asset:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tkaretsos/ProceduralBuildings/HEAD/ProjectSettings/DynamicsManager.asset
--------------------------------------------------------------------------------
/ProjectSettings/GraphicsSettings.asset:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tkaretsos/ProceduralBuildings/HEAD/ProjectSettings/GraphicsSettings.asset
--------------------------------------------------------------------------------
/ProjectSettings/Physics2DSettings.asset:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tkaretsos/ProceduralBuildings/HEAD/ProjectSettings/Physics2DSettings.asset
--------------------------------------------------------------------------------
/ProjectSettings/ProjectSettings.asset:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tkaretsos/ProceduralBuildings/HEAD/ProjectSettings/ProjectSettings.asset
--------------------------------------------------------------------------------
/ProjectSettings/QualitySettings.asset:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tkaretsos/ProceduralBuildings/HEAD/ProjectSettings/QualitySettings.asset
--------------------------------------------------------------------------------
/ProjectSettings/EditorBuildSettings.asset:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tkaretsos/ProceduralBuildings/HEAD/ProjectSettings/EditorBuildSettings.asset
--------------------------------------------------------------------------------
/Assets/Resources/Textures/Door/tex_door_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tkaretsos/ProceduralBuildings/HEAD/Assets/Resources/Textures/Door/tex_door_1.png
--------------------------------------------------------------------------------
/Assets/Resources/Textures/Door/tex_door_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tkaretsos/ProceduralBuildings/HEAD/Assets/Resources/Textures/Door/tex_door_2.png
--------------------------------------------------------------------------------
/Assets/Resources/Textures/Door/tex_door_3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tkaretsos/ProceduralBuildings/HEAD/Assets/Resources/Textures/Door/tex_door_3.png
--------------------------------------------------------------------------------
/Assets/Resources/Textures/Door/tex_door_4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tkaretsos/ProceduralBuildings/HEAD/Assets/Resources/Textures/Door/tex_door_4.png
--------------------------------------------------------------------------------
/Assets/Resources/Textures/Door/tex_door_5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tkaretsos/ProceduralBuildings/HEAD/Assets/Resources/Textures/Door/tex_door_5.png
--------------------------------------------------------------------------------
/Assets/Resources/Textures/Door/tex_door_6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tkaretsos/ProceduralBuildings/HEAD/Assets/Resources/Textures/Door/tex_door_6.png
--------------------------------------------------------------------------------
/Assets/Resources/Textures/Door/tex_door_7.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tkaretsos/ProceduralBuildings/HEAD/Assets/Resources/Textures/Door/tex_door_7.png
--------------------------------------------------------------------------------
/Assets/Resources/Textures/Door/tex_door_8.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tkaretsos/ProceduralBuildings/HEAD/Assets/Resources/Textures/Door/tex_door_8.png
--------------------------------------------------------------------------------
/Assets/Resources/Textures/Door/tex_door_9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tkaretsos/ProceduralBuildings/HEAD/Assets/Resources/Textures/Door/tex_door_9.png
--------------------------------------------------------------------------------
/Assets/Resources/Textures/Roof/tex_roof_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tkaretsos/ProceduralBuildings/HEAD/Assets/Resources/Textures/Roof/tex_roof_1.png
--------------------------------------------------------------------------------
/Assets/Resources/Textures/Roof/tex_roof_10.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tkaretsos/ProceduralBuildings/HEAD/Assets/Resources/Textures/Roof/tex_roof_10.png
--------------------------------------------------------------------------------
/Assets/Resources/Textures/Roof/tex_roof_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tkaretsos/ProceduralBuildings/HEAD/Assets/Resources/Textures/Roof/tex_roof_2.png
--------------------------------------------------------------------------------
/Assets/Resources/Textures/Roof/tex_roof_3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tkaretsos/ProceduralBuildings/HEAD/Assets/Resources/Textures/Roof/tex_roof_3.png
--------------------------------------------------------------------------------
/Assets/Resources/Textures/Roof/tex_roof_4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tkaretsos/ProceduralBuildings/HEAD/Assets/Resources/Textures/Roof/tex_roof_4.png
--------------------------------------------------------------------------------
/Assets/Resources/Textures/Roof/tex_roof_6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tkaretsos/ProceduralBuildings/HEAD/Assets/Resources/Textures/Roof/tex_roof_6.png
--------------------------------------------------------------------------------
/Assets/Resources/Textures/Roof/tex_roof_7.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tkaretsos/ProceduralBuildings/HEAD/Assets/Resources/Textures/Roof/tex_roof_7.png
--------------------------------------------------------------------------------
/Assets/Resources/Textures/Roof/tex_roof_8.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tkaretsos/ProceduralBuildings/HEAD/Assets/Resources/Textures/Roof/tex_roof_8.png
--------------------------------------------------------------------------------
/Assets/Resources/Textures/Roof/tex_roof_9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tkaretsos/ProceduralBuildings/HEAD/Assets/Resources/Textures/Roof/tex_roof_9.png
--------------------------------------------------------------------------------
/Assets/Resources/Textures/Shutter/tex_shutter_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tkaretsos/ProceduralBuildings/HEAD/Assets/Resources/Textures/Shutter/tex_shutter_1.png
--------------------------------------------------------------------------------
/Assets/Resources/Textures/Shutter/tex_shutter_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tkaretsos/ProceduralBuildings/HEAD/Assets/Resources/Textures/Shutter/tex_shutter_2.png
--------------------------------------------------------------------------------
/Assets/Resources/Textures/Shutter/tex_shutter_3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tkaretsos/ProceduralBuildings/HEAD/Assets/Resources/Textures/Shutter/tex_shutter_3.png
--------------------------------------------------------------------------------
/Assets/Resources/Textures/Shutter/tex_shutter_4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tkaretsos/ProceduralBuildings/HEAD/Assets/Resources/Textures/Shutter/tex_shutter_4.png
--------------------------------------------------------------------------------
/Assets/Resources/Textures/Shutter/tex_shutter_5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tkaretsos/ProceduralBuildings/HEAD/Assets/Resources/Textures/Shutter/tex_shutter_5.png
--------------------------------------------------------------------------------
/Assets/Resources/Textures/Shutter/tex_shutter_6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tkaretsos/ProceduralBuildings/HEAD/Assets/Resources/Textures/Shutter/tex_shutter_6.png
--------------------------------------------------------------------------------
/Assets/Resources/Textures/Shutter/tex_shutter_7.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tkaretsos/ProceduralBuildings/HEAD/Assets/Resources/Textures/Shutter/tex_shutter_7.png
--------------------------------------------------------------------------------
/Assets/Resources/Textures/RoofBase/tex_roof_base_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tkaretsos/ProceduralBuildings/HEAD/Assets/Resources/Textures/RoofBase/tex_roof_base_1.png
--------------------------------------------------------------------------------
/Assets/Resources/Textures/RoofBase/tex_roof_base_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tkaretsos/ProceduralBuildings/HEAD/Assets/Resources/Textures/RoofBase/tex_roof_base_2.png
--------------------------------------------------------------------------------
/Assets/Resources/Textures/RoofBase/tex_roof_base_3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tkaretsos/ProceduralBuildings/HEAD/Assets/Resources/Textures/RoofBase/tex_roof_base_3.png
--------------------------------------------------------------------------------
/Assets/Resources/Textures/RoofBase/tex_roof_base_4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tkaretsos/ProceduralBuildings/HEAD/Assets/Resources/Textures/RoofBase/tex_roof_base_4.png
--------------------------------------------------------------------------------
/Assets/Resources/Textures/RoofBase/tex_roof_base_5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tkaretsos/ProceduralBuildings/HEAD/Assets/Resources/Textures/RoofBase/tex_roof_base_5.png
--------------------------------------------------------------------------------
/Assets/Resources/Textures/CompDecor/tex_comp_decor_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tkaretsos/ProceduralBuildings/HEAD/Assets/Resources/Textures/CompDecor/tex_comp_decor_1.png
--------------------------------------------------------------------------------
/Assets/Resources/Textures/CompDecor/tex_comp_decor_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tkaretsos/ProceduralBuildings/HEAD/Assets/Resources/Textures/CompDecor/tex_comp_decor_2.png
--------------------------------------------------------------------------------
/Assets/Resources/Textures/CompDecor/tex_comp_decor_3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tkaretsos/ProceduralBuildings/HEAD/Assets/Resources/Textures/CompDecor/tex_comp_decor_3.png
--------------------------------------------------------------------------------
/Assets/Resources/Textures/CompDecor/tex_comp_decor_4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tkaretsos/ProceduralBuildings/HEAD/Assets/Resources/Textures/CompDecor/tex_comp_decor_4.png
--------------------------------------------------------------------------------
/Assets/Resources/Textures/CompDecor/tex_comp_decor_5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tkaretsos/ProceduralBuildings/HEAD/Assets/Resources/Textures/CompDecor/tex_comp_decor_5.png
--------------------------------------------------------------------------------
/Assets/Resources/Textures/CompDecor/tex_comp_decor_6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tkaretsos/ProceduralBuildings/HEAD/Assets/Resources/Textures/CompDecor/tex_comp_decor_6.png
--------------------------------------------------------------------------------
/Assets/Resources/Textures/CompDecor/tex_comp_decor_7.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tkaretsos/ProceduralBuildings/HEAD/Assets/Resources/Textures/CompDecor/tex_comp_decor_7.png
--------------------------------------------------------------------------------
/Assets/Resources/Textures/CompDecor/tex_comp_decor_8.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tkaretsos/ProceduralBuildings/HEAD/Assets/Resources/Textures/CompDecor/tex_comp_decor_8.png
--------------------------------------------------------------------------------
/Assets/Resources/Textures/CompDecor/tex_comp_decor_9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tkaretsos/ProceduralBuildings/HEAD/Assets/Resources/Textures/CompDecor/tex_comp_decor_9.png
--------------------------------------------------------------------------------
/Assets/Resources/Textures/RoofDecor/tex_roof_decor_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tkaretsos/ProceduralBuildings/HEAD/Assets/Resources/Textures/RoofDecor/tex_roof_decor_1.png
--------------------------------------------------------------------------------
/Assets/Resources/Textures/RoofDecor/tex_roof_decor_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tkaretsos/ProceduralBuildings/HEAD/Assets/Resources/Textures/RoofDecor/tex_roof_decor_2.png
--------------------------------------------------------------------------------
/Assets/Resources/Textures/RoofDecor/tex_roof_decor_3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tkaretsos/ProceduralBuildings/HEAD/Assets/Resources/Textures/RoofDecor/tex_roof_decor_3.png
--------------------------------------------------------------------------------
/Assets/Resources/Textures/RoofDecor/tex_roof_decor_4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tkaretsos/ProceduralBuildings/HEAD/Assets/Resources/Textures/RoofDecor/tex_roof_decor_4.png
--------------------------------------------------------------------------------
/Assets/Standard Assets/Shutter/ShutterSide.cs:
--------------------------------------------------------------------------------
1 |
2 | namespace Thesis {
3 |
4 | public enum ShutterSide
5 | {
6 | Left,
7 | Right
8 | }
9 |
10 | } // namespace Thesis
11 |
--------------------------------------------------------------------------------
/Assets/Standard Assets/Roof/RoofType.cs:
--------------------------------------------------------------------------------
1 |
2 | namespace Thesis {
3 |
4 | public enum RoofType
5 | {
6 | Flat,
7 | SinglePeak,
8 | DoublePeak
9 | }
10 |
11 | } // namespace Thesis
--------------------------------------------------------------------------------
/Assets/Resources/Textures/CompDecorSimple/tex_comp_decor_simple_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tkaretsos/ProceduralBuildings/HEAD/Assets/Resources/Textures/CompDecorSimple/tex_comp_decor_simple_1.png
--------------------------------------------------------------------------------
/Assets/Standard Assets/General/BuildMode.cs:
--------------------------------------------------------------------------------
1 |
2 | namespace Thesis {
3 |
4 | public enum BuildMode
5 | {
6 | Many,
7 | Two,
8 | Three,
9 | Four,
10 | Five
11 | }
12 |
13 | } // namespace Thesis
--------------------------------------------------------------------------------
/Assets/Standard Assets/General/ProceduralObject.cs:
--------------------------------------------------------------------------------
1 |
2 | namespace Thesis {
3 |
4 | public abstract class ProceduralObject
5 | {
6 | public UnityEngine.GameObject gameObject;
7 | }
8 |
9 | } // namespace Thesis
10 |
--------------------------------------------------------------------------------
/Assets/Standard Assets/Door/DoorBody.cs:
--------------------------------------------------------------------------------
1 |
2 | namespace Thesis {
3 |
4 | public class DoorBody : ComponentBody
5 | {
6 | public DoorBody (Door parent)
7 | : base(parent)
8 | { }
9 | }
10 |
11 | } // namespace Thesis
--------------------------------------------------------------------------------
/Assets/Standard Assets/Window/WindowBody.cs:
--------------------------------------------------------------------------------
1 |
2 | namespace Thesis {
3 |
4 | public class WindowBody : ComponentBody
5 | {
6 | public WindowBody (Window parent)
7 | : base(parent)
8 | { }
9 | }
10 |
11 | } // namespace Thesis
--------------------------------------------------------------------------------
/Assets/Standard Assets/Balcony/BalconyBody.cs:
--------------------------------------------------------------------------------
1 |
2 | namespace Thesis {
3 |
4 | public class BalconyBody : ComponentBody
5 | {
6 | public BalconyBody (Balcony parent)
7 | : base(parent)
8 | { }
9 | }
10 |
11 | } // namespace Thesis
--------------------------------------------------------------------------------
/Assets/Standard Assets/General/ComponentCoordinate.cs:
--------------------------------------------------------------------------------
1 |
2 | namespace Thesis {
3 |
4 | public struct ComponentCoordinate
5 | {
6 | public int floor;
7 |
8 | public int component;
9 |
10 | public ComponentCoordinate (int floor, int component)
11 | {
12 | this.floor = floor;
13 | this.component = component;
14 | }
15 | }
16 |
17 | } // namespace Thesis
--------------------------------------------------------------------------------
/Assets/Standard Assets/Balcony/BalconyFrame.cs:
--------------------------------------------------------------------------------
1 |
2 | namespace Thesis {
3 |
4 | public class BalconyFrame : ComponentFrame
5 | {
6 | /*************** FIELDS ***************/
7 |
8 | public float width = 0.1f;
9 |
10 | /*************** CONSTRUCTORS ***************/
11 |
12 | public BalconyFrame (Balcony parent)
13 | : base(parent)
14 | { }
15 | }
16 |
17 | } // namespace Thesis
--------------------------------------------------------------------------------
/Assets/Standard Assets/Interface/ICombinable.cs:
--------------------------------------------------------------------------------
1 |
2 | namespace Thesis {
3 | namespace Interface {
4 |
5 | public interface ICombinable
6 | {
7 | UnityEngine.GameObject gameObject { get; }
8 |
9 | UnityEngine.MeshFilter meshFilter { get; }
10 |
11 | UnityEngine.Material material { get; }
12 |
13 | UnityEngine.Mesh mesh { get; }
14 | }
15 |
16 | } // namespace Interface
17 | } // namespace Thesis
--------------------------------------------------------------------------------
/Assets/Standard Assets/Interface/IDrawable.cs:
--------------------------------------------------------------------------------
1 |
2 | namespace Thesis {
3 | namespace Interface {
4 |
5 | public interface IDrawable : ICombinable
6 | {
7 | UnityEngine.Vector3[] vertices { get; }
8 |
9 | int[] triangles { get; }
10 |
11 | void FindVertices ();
12 |
13 | void FindTriangles ();
14 |
15 | void Draw ();
16 |
17 | void Destroy ();
18 | }
19 |
20 | } // namespace Interface
21 | } // namespace Thesis
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ## Description
2 | This is my thesis project, in which I try to reconstruct a part of the city of
3 | Athens (Greece) procedurally.
4 |
5 | ## Video
6 | http://youtu.be/dSGm_Tw1GA8
7 |
8 | ## Keybindings
9 | B - create buildings
10 | R - recreate the map (destroys the buildings as well)
11 | G - toggle the drawing of gizmos
12 | 1 - 5 - toggle the drawing of different gizmos (different colors)
13 |
--------------------------------------------------------------------------------
/Assets/Standard Assets/General/TextureLine.cs:
--------------------------------------------------------------------------------
1 | using UnityEngine;
2 |
3 | namespace Thesis {
4 |
5 | public struct TextureLine
6 | {
7 | public Vector2 start;
8 |
9 | public Vector2 end;
10 |
11 | public Color color;
12 |
13 | public int thickness;
14 |
15 | public TextureLine (Vector2 start, Vector2 end, Color color, int thickness)
16 | {
17 | this.start = start;
18 | this.end = end;
19 | this.color = color;
20 | this.thickness = thickness;
21 | }
22 |
23 | public TextureLine (int x1, int y1, int x2, int y2, Color color, int thickness)
24 | {
25 | this.start = new Vector2(x1, y1);
26 | this.end = new Vector2(x2, y2);
27 | this.color = color;
28 | this.thickness = thickness;
29 | }
30 | }
31 |
32 | } // namespace Thesis
--------------------------------------------------------------------------------
/Assets/Scripts/BuildingController.cs:
--------------------------------------------------------------------------------
1 | using Thesis;
2 | using UnityEngine;
3 |
4 | public class BuildingController : MonoBehaviour
5 | {
6 | void Update ()
7 | {
8 | if (Input.GetKeyUp(KeyCode.F5))
9 | {
10 | BuildingManager.Instance.DestroyBuildings();
11 | BuildingManager.Instance.CreateNeoclassical(BuildMode.Two);
12 | }
13 |
14 | if (Input.GetKeyUp(KeyCode.F6))
15 | {
16 | BuildingManager.Instance.DestroyBuildings();
17 | BuildingManager.Instance.CreateNeoclassical(BuildMode.Three);
18 | }
19 |
20 | if (Input.GetKeyUp(KeyCode.F7))
21 | {
22 | BuildingManager.Instance.DestroyBuildings();
23 | BuildingManager.Instance.CreateNeoclassical(BuildMode.Four);
24 | }
25 |
26 | if (Input.GetKeyUp(KeyCode.F8))
27 | {
28 | BuildingManager.Instance.DestroyBuildings();
29 | BuildingManager.Instance.CreateNeoclassical(BuildMode.Five);
30 | }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/Assets/Standard Assets/Roof/Roof.cs:
--------------------------------------------------------------------------------
1 | using UnityEngine;
2 |
3 | namespace Thesis {
4 |
5 | public class Roof : DrawableObject
6 | {
7 | public readonly BuildingMesh parentMesh;
8 |
9 | public RoofDecoration decor;
10 |
11 | public float width;
12 |
13 | public float height;
14 |
15 | public Roof (BuildingMesh parent)
16 | {
17 | parentMesh = parent;
18 | decor = null;
19 | }
20 |
21 | public override void Draw()
22 | {
23 | base.Draw();
24 |
25 | gameObject.transform.parent = parentMesh.parent.gameObject.transform;
26 | gameObject.transform.position = parentMesh.meshOrigin;
27 |
28 | if (decor != null)
29 | {
30 | decor.FindVertices();
31 | decor.FindTriangles();
32 | decor.Draw();
33 | }
34 | }
35 |
36 | public override void Destroy()
37 | {
38 | base.Destroy();
39 |
40 | if (decor != null)
41 | decor.Destroy();
42 | }
43 | }
44 |
45 | } // namespace Thesis
--------------------------------------------------------------------------------
/Assets/Standard Assets/General/FaceComponent.cs:
--------------------------------------------------------------------------------
1 | using UnityEngine;
2 |
3 | namespace Thesis {
4 |
5 | public class FaceComponent : DrawableObject
6 | {
7 | /*************** FIELDS ***************/
8 |
9 | public readonly Face parentFace;
10 |
11 | public readonly ComponentCoordinate position;
12 |
13 | public float height;
14 |
15 | public float depth;
16 |
17 | public float width;
18 |
19 | public ComponentFrame frame;
20 |
21 | public ComponentBody body;
22 |
23 | public BuildingMesh parentBuilding
24 | {
25 | get { return parentFace.parentBuilding; }
26 | }
27 |
28 | public Vector3 normal
29 | {
30 | get { return parentFace.normal; }
31 | }
32 |
33 | /*************** CONSTRUCTORS ***************/
34 |
35 | public FaceComponent (Face parent, ComponentCoordinate position)
36 | {
37 | parentFace = parent;
38 | this.position = position;
39 | }
40 |
41 | public override void Destroy()
42 | {
43 | base.Destroy();
44 |
45 | frame.Destroy();
46 | body.Destroy();
47 | }
48 | }
49 |
50 | } // namespace Thesis
--------------------------------------------------------------------------------
/MIT-LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2012 Thanasis Karetsos
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy
4 | of this software and associated documentation files (the "Software"), to deal
5 | in the Software without restriction, including without limitation the rights
6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 | copies of the Software, and to permit persons to whom the Software is
8 | furnished to do so, subject to the following conditions:
9 |
10 | The above copyright notice and this permission notice shall be included in
11 | all copies or substantial portions of the Software.
12 |
13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 | THE SOFTWARE.
20 |
--------------------------------------------------------------------------------
/Assets/Standard Assets/City/Road.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using UnityEngine;
3 |
4 | namespace Thesis {
5 |
6 | public sealed class Road : DrawableObject
7 | {
8 | public Road (Block parent)
9 | {
10 | boundaries = new Vector3[8];
11 | for (int i = 0; i < 4; ++i)
12 | {
13 | boundaries[i] = parent.edges[i].start;
14 | boundaries[i + 4] = parent.sidewalkVerts[i];
15 | }
16 | }
17 |
18 | public override void FindVertices()
19 | {
20 | vertices = boundaries;
21 | }
22 |
23 | public override void FindTriangles()
24 | {
25 | triangles = new int[24];
26 | int i = 0;
27 |
28 | triangles[i++] = 0;
29 | triangles[i++] = 1;
30 | triangles[i++] = 5;
31 |
32 | triangles[i++] = 0;
33 | triangles[i++] = 5;
34 | triangles[i++] = 4;
35 |
36 | triangles[i++] = 1;
37 | triangles[i++] = 2;
38 | triangles[i++] = 6;
39 |
40 | triangles[i++] = 1;
41 | triangles[i++] = 6;
42 | triangles[i++] = 5;
43 |
44 | triangles[i++] = 2;
45 | triangles[i++] = 3;
46 | triangles[i++] = 7;
47 |
48 | triangles[i++] = 2;
49 | triangles[i++] = 7;
50 | triangles[i++] = 6;
51 |
52 | triangles[i++] = 3;
53 | triangles[i++] = 0;
54 | triangles[i++] = 4;
55 |
56 | triangles[i++] = 3;
57 | triangles[i++] = 4;
58 | triangles[i++] = 7;
59 | }
60 | }
61 |
62 | } // namespace Thesis
--------------------------------------------------------------------------------
/Assets/Standard Assets/City/Sidewalk.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using UnityEngine;
3 |
4 | namespace Thesis {
5 |
6 | public sealed class Sidewalk : DrawableObject
7 | {
8 | public readonly List edges;
9 |
10 | public Sidewalk (Block parent)
11 | {
12 | boundaries = new Vector3[8];
13 | edges = new List();
14 | for (int i = 0; i < 4; ++i)
15 | {
16 | boundaries[i] = parent.sidewalkVerts[i];
17 | boundaries[i + 4] = parent.lotVerts[i];
18 | edges.Add(new Edge(parent.sidewalkVerts[i],
19 | parent.sidewalkVerts[(i + 1) % 4]));
20 | }
21 | }
22 |
23 | public override void FindVertices()
24 | {
25 | vertices = boundaries;
26 | }
27 |
28 | public override void FindTriangles()
29 | {
30 | triangles = new int[24];
31 | int i = 0;
32 |
33 | triangles[i++] = 0;
34 | triangles[i++] = 1;
35 | triangles[i++] = 5;
36 |
37 | triangles[i++] = 0;
38 | triangles[i++] = 5;
39 | triangles[i++] = 4;
40 |
41 | triangles[i++] = 1;
42 | triangles[i++] = 2;
43 | triangles[i++] = 6;
44 |
45 | triangles[i++] = 1;
46 | triangles[i++] = 6;
47 | triangles[i++] = 5;
48 |
49 | triangles[i++] = 2;
50 | triangles[i++] = 3;
51 | triangles[i++] = 7;
52 |
53 | triangles[i++] = 2;
54 | triangles[i++] = 7;
55 | triangles[i++] = 6;
56 |
57 | triangles[i++] = 3;
58 | triangles[i++] = 0;
59 | triangles[i++] = 4;
60 |
61 | triangles[i++] = 3;
62 | triangles[i++] = 4;
63 | triangles[i++] = 7;
64 | }
65 | }
66 |
67 | } // namespace Thesis
--------------------------------------------------------------------------------
/Assets/Standard Assets/Door/Door.cs:
--------------------------------------------------------------------------------
1 | using UnityEngine;
2 |
3 | namespace Thesis {
4 |
5 | public class Door : FaceComponent
6 | {
7 | public Building masterParent
8 | {
9 | get { return parentBuilding.parent; }
10 | }
11 |
12 | public Door (Face parent, Vector3 dr, Vector3 dl, ComponentCoordinate position)
13 | : base(parent, position)
14 | {
15 | height = parentBuilding.doorHeight;
16 | depth = 0.4f;
17 |
18 | float mod = 0.4f;
19 | if (masterParent.doorWidth > 0f)
20 | mod = (masterParent.doorWidth - (dr - dl).magnitude) / 2f;
21 |
22 | dr += mod * parentFace.right;
23 | dl -= mod * parentFace.right;
24 |
25 | var ul = new Vector3(dl.x, dl.y + height, dl.z);
26 | var ur = new Vector3(dr.x, dr.y + height, dr.z);
27 |
28 | boundaries = new Vector3[4];
29 | boundaries[0] = dr;
30 | boundaries[1] = dl;
31 | boundaries[2] = ul;
32 | boundaries[3] = ur;
33 |
34 | frame = new ComponentFrame(this);
35 | frame.name = "neo_door_frame";
36 | frame.material = MaterialManager.Instance.Get("ComponentFrame");
37 | parentBuilding.parent.AddCombinable(frame.material.name, frame);
38 |
39 | body = new DoorBody(this);
40 | body.name = "neo_door_body";
41 | body.material = parentBuilding.parent.doorMaterial;
42 | parentBuilding.parent.AddCombinable(body.material.name, body);
43 | }
44 |
45 | public override void Draw ()
46 | {
47 | frame.FindVertices();
48 | frame.FindTriangles();
49 | frame.Draw();
50 |
51 | body.FindVertices();
52 | body.FindTriangles();
53 | body.Draw();
54 | }
55 | }
56 |
57 | } // namespace Thesis
--------------------------------------------------------------------------------
/Assets/Standard Assets/City/Edge.cs:
--------------------------------------------------------------------------------
1 | using UnityEngine;
2 |
3 | namespace Thesis {
4 |
5 | public class Edge
6 | {
7 | private Vector3 _start;
8 | public Vector3 start
9 | {
10 | get { return _start; }
11 | set
12 | {
13 | _start = value;
14 | _length = Vector3.Distance(_start, _end);
15 | _middle = (_start + _end) / 2;
16 | _direction = (_end - _start).normalized;
17 | _right = Vector3.Cross(Vector3.up, _direction).normalized;
18 | }
19 | }
20 |
21 | private Vector3 _end;
22 | public Vector3 end
23 | {
24 | get { return _end; }
25 | set
26 | {
27 | _end = value;
28 | _length = Vector3.Distance(_start, _end);
29 | _middle = (_start + _end) / 2;
30 | _direction = (_end - _start).normalized;
31 | _right = Vector3.Cross(Vector3.up, _direction).normalized;
32 | }
33 | }
34 |
35 | private Vector3 _middle;
36 | public Vector3 middle
37 | {
38 | get { return _middle; }
39 | }
40 |
41 | private float _length;
42 | public float length
43 | {
44 | get { return _length; }
45 | }
46 |
47 | private Vector3 _direction;
48 | public Vector3 direction
49 | {
50 | get { return _direction; }
51 | }
52 |
53 | private Vector3 _right;
54 | public Vector3 right
55 | {
56 | get { return _right; }
57 | }
58 |
59 | private Edge () { }
60 |
61 | public Edge (Vector3 from, Vector3 to)
62 | {
63 | _start = from;
64 | _end = to;
65 | _length = Vector3.Distance(from, to);
66 | _middle = (from + to) / 2;
67 | _direction = (to - from).normalized;
68 | _right = Vector3.Cross(Vector3.up, _direction).normalized;
69 | }
70 |
71 | public bool Contains (Vector3 point)
72 | {
73 | var dist = Vector3.Distance(_start, point) + Vector3.Distance(point, _end);
74 | return Mathf.Abs(_length - dist) < 0.01f;
75 | }
76 | }
77 |
78 | } // namespace Thesis
--------------------------------------------------------------------------------
/Assets/Standard Assets/General/ComponentBody.cs:
--------------------------------------------------------------------------------
1 | using UnityEngine;
2 |
3 | namespace Thesis {
4 |
5 | public class ComponentBody : DrawableObject
6 | {
7 | /*************** FIELDS ***************/
8 |
9 | public readonly FaceComponent parentComponent;
10 |
11 | public Face parentFace
12 | {
13 | get { return parentComponent.parentFace; }
14 | }
15 |
16 | public BuildingMesh parentBuilding
17 | {
18 | get { return parentComponent.parentBuilding; }
19 | }
20 |
21 | /*************** CONSTRUCTORS ***************/
22 |
23 | public ComponentBody (FaceComponent parent)
24 | {
25 | parentComponent = parent;
26 |
27 | boundaries = new Vector3[4];
28 | for (var i = 0; i < parentComponent.boundaries.Length; ++i)
29 | boundaries[i] = parentComponent.boundaries[i] -
30 | parentComponent.depth * parentComponent.normal;
31 |
32 | FindMeshOrigin(boundaries[0],
33 | boundaries[2],
34 | boundaries[1],
35 | boundaries[3]);
36 |
37 | for (var i = 0; i < boundaries.Length; ++i)
38 | boundaries[i] -= meshOrigin;
39 | }
40 |
41 | /*************** METHODS ***************/
42 |
43 | public override void FindVertices ()
44 | {
45 | vertices = boundaries;
46 | }
47 |
48 | public override void FindTriangles ()
49 | {
50 | triangles = new int[] {
51 | 0, 1, 3,
52 | 1, 2, 3
53 | };
54 | }
55 |
56 | public override void Draw ()
57 | {
58 | base.Draw();
59 |
60 | var uvs = new Vector2[mesh.vertices.Length];
61 | uvs[1] = new Vector2(0f, 0f);
62 | uvs[0] = new Vector2(1f, 0f);
63 | uvs[2] = new Vector2(0f, 1f);
64 | uvs[3] = new Vector2(1f, 1f);
65 |
66 | mesh.uv = uvs;
67 |
68 | gameObject.transform.position = meshOrigin + parentBuilding.meshOrigin;
69 | gameObject.transform.parent = parentBuilding.parent.gameObject.transform;
70 | }
71 | }
72 |
73 | } // namespace Thesis
--------------------------------------------------------------------------------
/Assets/Standard Assets/City/BuildingLot.cs:
--------------------------------------------------------------------------------
1 | using UnityEngine;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 |
5 | namespace Thesis {
6 |
7 | public sealed class BuildingLot : DrawableObject
8 | {
9 | // edges[0] is _always_ adjacent to a street
10 | public readonly List edges = new List();
11 |
12 | // contains the indexes of the faces that are not
13 | // in contact with other walls or covered.
14 | public readonly List freeEdges = new List();
15 |
16 | // key -> index of edge
17 | // value -> percentage of length that is occupied
18 | public Dictionary occupied;
19 |
20 | // key -> index of edge
21 | // value -> list that contains all the points on that edge
22 | public Dictionary> pointsInEdge;
23 |
24 | public BuildingLot (Block parent)
25 | {
26 | var edgeList = new List();
27 | for (int i = 0; i < 4; ++i)
28 | edgeList.Add(new Edge(parent.lotVerts[i], parent.lotVerts[(i + 1) % 4]));
29 |
30 | int big = edgeList.FindIndex(delegate (Edge e) {
31 | return e.length == edgeList.Max(t => t.length);
32 | });
33 | for (int i = 0; i < 4; ++i)
34 | edges.Add(edgeList[(big + i) % 4]);
35 |
36 | occupied = new Dictionary();
37 | occupied.Add(0, 0f);
38 | occupied.Add(1, 0f);
39 | occupied.Add(2, 0f);
40 | occupied.Add(3, 0f);
41 |
42 | pointsInEdge = new Dictionary>();
43 | pointsInEdge.Add(0, new List());
44 | pointsInEdge.Add(1, new List());
45 | pointsInEdge.Add(2, new List());
46 | pointsInEdge.Add(3, new List());
47 | }
48 |
49 | public BuildingLot (Vector3 p1, Vector3 p2, Vector3 p3, Vector3 p4)
50 | {
51 | edges.Add(new Edge(p1, p2));
52 | edges.Add(new Edge(p2, p3));
53 | edges.Add(new Edge(p3, p4));
54 | edges.Add(new Edge(p4, p1));
55 | }
56 |
57 | public bool isFinal ()
58 | {
59 | float min = edges.Min(e => e.length);
60 |
61 | if (edges[0].length >= 2.5f * min)
62 | return false;
63 |
64 | if (edges[0].length < 16f && min < 16f)
65 | return true;
66 |
67 | return false;
68 | }
69 |
70 | public override void FindVertices()
71 | {
72 | vertices = new Vector3[4];
73 | for (int i = 0; i < 4; ++i)
74 | vertices[i] = edges[i].start - 0.01f * Vector3.up;
75 | }
76 |
77 | public override void FindTriangles()
78 | {
79 | triangles = new int[6];
80 | int i = 0;
81 |
82 | triangles[i++] = 0;
83 | triangles[i++] = 1;
84 | triangles[i++] = 2;
85 |
86 | triangles[i++] = 0;
87 | triangles[i++] = 2;
88 | triangles[i++] = 3;
89 | }
90 | }
91 |
92 | } // namespace Thesis
--------------------------------------------------------------------------------
/Assets/Standard Assets/General/ProceduralTexture.cs:
--------------------------------------------------------------------------------
1 | using UnityEngine;
2 | using System.Collections.Generic;
3 |
4 | namespace Thesis {
5 |
6 | public class ProceduralTexture
7 | {
8 | public Texture2D content;
9 |
10 | public List lines;
11 |
12 | public ProceduralTexture (int width = 256, int height = 128)
13 | {
14 | content = new Texture2D(width, height);
15 | lines = new List();
16 | }
17 |
18 | public ProceduralTexture (Texture2D texture)
19 | {
20 | content = texture;
21 | lines = new List();
22 | }
23 |
24 | public virtual void Draw ()
25 | {
26 | foreach (TextureLine line in lines)
27 | DrawLine(line.start, line.end, line.color, line.thickness);
28 |
29 | content.Apply();
30 | }
31 |
32 | public void Clear ()
33 | {
34 | for (var x = 0; x < content.width; ++x)
35 | for (var y = 0; y < content.height; ++y)
36 | content.SetPixel(x, y, Color.clear);
37 | }
38 |
39 | public void SetBackgroundColor (Color color)
40 | {
41 | for (var x = 0; x < content.width; ++x)
42 | for (var y = 0; y < content.height; ++y)
43 | content.SetPixel(x, y, color);
44 | }
45 |
46 | public void DrawLine (Vector2 p1, Vector2 p2, Color color, int thickness)
47 | {
48 | DrawLine(p1, p2, color);
49 | if (Mathf.Abs(p1.x - p2.x) > Mathf.Abs(p1.y - p2.y))
50 | for (var tk = 1; tk < Mathf.CeilToInt((1f * thickness) / 2); ++tk)
51 | {
52 | DrawLine(p1 + tk * Vector2.up, p2 + tk * Vector2.up, color);
53 | DrawLine(p1 - tk * Vector2.up, p2 - tk * Vector2.up, color);
54 | }
55 | else
56 | for (var tk = 1; tk < Mathf.CeilToInt((1f * thickness) / 2); ++tk)
57 | {
58 | DrawLine(p1 + tk * Vector2.right, p2 + tk * Vector2.right, color);
59 | DrawLine(p1 - tk * Vector2.right, p2 - tk * Vector2.right, color);
60 | }
61 | }
62 |
63 |
64 | ///
65 | /// Implementation of Besenham's line algorithm:
66 | /// http://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm#Simplification
67 | ///
68 | public void DrawLine (Vector2 p1, Vector2 p2, Color color)
69 | {
70 | int dx = Mathf.Abs((int) (p1.x - p2.x));
71 | int dy = Mathf.Abs((int) (p1.y - p2.y));
72 | int sx = (p1.x < p2.x) ? 1 : -1;
73 | int sy = (p1.y < p2.y) ? 1 : -1;
74 | int err = dx - dy;
75 | int err2;
76 |
77 | while (true)
78 | {
79 | content.SetPixel((int) p1.x, (int) p1.y, color);
80 | if (p1.x == p2.x && p1.y == p2.y) break;
81 | err2 = err << 1;
82 | if (err2 > -dy)
83 | {
84 | err -= dy;
85 | p1.x += sx;
86 | }
87 |
88 | if (err2 < dx)
89 | {
90 | err += dx;
91 | p1.y += sy;
92 | }
93 | }
94 | }
95 | }
96 |
97 | } // namespace Thesis
--------------------------------------------------------------------------------
/Assets/Standard Assets/General/ComponentFrame.cs:
--------------------------------------------------------------------------------
1 | using UnityEngine;
2 |
3 | namespace Thesis {
4 |
5 | public class ComponentFrame : DrawableObject
6 | {
7 | /*************** FIELDS ***************/
8 |
9 | public readonly FaceComponent parentComponent;
10 |
11 | public Face parentFace
12 | {
13 | get { return parentComponent.parentFace; }
14 | }
15 |
16 | public BuildingMesh parentBuilding
17 | {
18 | get { return parentFace.parentBuilding; }
19 | }
20 |
21 | /*************** CONSTRUCTORS ***************/
22 |
23 | public ComponentFrame (FaceComponent parent)
24 | {
25 | parentComponent = parent;
26 |
27 | boundaries = new Vector3[8];
28 | for (var i = 0; i < 4; ++i)
29 | {
30 | boundaries[i] = parentComponent.boundaries[i];
31 | // subtract a small amount to prevent overlaping triangles
32 | boundaries[i + 4] = boundaries[i] - parentComponent.depth * parentComponent.normal;
33 | }
34 |
35 | FindMeshOrigin(boundaries[0],
36 | boundaries[6],
37 | boundaries[2],
38 | boundaries[4]);
39 |
40 | for (var i = 0; i < boundaries.Length; ++i)
41 | boundaries[i] -= meshOrigin;
42 | }
43 |
44 | /*************** METHODS ***************/
45 |
46 | public override void FindVertices ()
47 | {
48 | vertices = new Vector3[boundaries.Length << 1];
49 | for (var i = 0; i < boundaries.Length; ++i)
50 | vertices[i] = vertices[i + 8] = boundaries[i];
51 | }
52 |
53 | public override void FindTriangles ()
54 | {
55 | triangles = new int[3 * boundaries.Length];
56 | var i = 0;
57 |
58 | // right
59 | triangles[i++] = 0;
60 | triangles[i++] = 4;
61 | triangles[i++] = 7;
62 |
63 | triangles[i++] = 0;
64 | triangles[i++] = 7;
65 | triangles[i++] = 3;
66 |
67 | // left
68 | triangles[i++] = 1;
69 | triangles[i++] = 2;
70 | triangles[i++] = 6;
71 |
72 | triangles[i++] = 1;
73 | triangles[i++] = 6;
74 | triangles[i++] = 5;
75 |
76 | // bottom
77 | triangles[i++] = 8; // 0 + 8;
78 | triangles[i++] = 9; // 1 + 8;
79 | triangles[i++] = 13; // 5 + 8;
80 |
81 | triangles[i++] = 8; // 0 + 8;
82 | triangles[i++] = 13; // 5 + 8;
83 | triangles[i++] = 12; // 4 + 8;
84 |
85 | // top
86 | triangles[i++] = 10; // 2 + 8;
87 | triangles[i++] = 11; // 3 + 8;
88 | triangles[i++] = 14; // 6 + 8;
89 |
90 | triangles[i++] = 14; // 6 + 8;
91 | triangles[i++] = 11; // 3 + 8;
92 | triangles[i++] = 15; // 7 + 8;
93 | }
94 |
95 | public override void Draw ()
96 | {
97 | base.Draw();
98 |
99 | gameObject.transform.position = meshOrigin + parentBuilding.meshOrigin;
100 | gameObject.transform.parent = parentBuilding.parent.gameObject.transform;
101 | }
102 | }
103 |
104 | } // namespace Thesis
--------------------------------------------------------------------------------
/Assets/Standard Assets/Roof/SinglePeakRoof.cs:
--------------------------------------------------------------------------------
1 | using UnityEngine;
2 |
3 | namespace Thesis {
4 |
5 | public class SinglePeakRoof : Roof
6 | {
7 | public SinglePeakRoof (BuildingMesh parent)
8 | : base(parent)
9 | {
10 | height = 1f;
11 | width = 0.2f;
12 |
13 | boundaries = new Vector3[5];
14 |
15 | for (int i = 0; i < 4; ++i)
16 | boundaries[i] = parentMesh.roofBase.boundaries[i + 4] +
17 | width * parentMesh.faces[i].normal +
18 | width * parentMesh.faces[(i + 3) % 4].normal;
19 |
20 | FindMeshOrigin(boundaries[0], boundaries[2],
21 | boundaries[1], boundaries[3]);
22 |
23 | boundaries[4] = new Vector3(meshOrigin.x,
24 | boundaries[0].y + height,
25 | meshOrigin.z);
26 | }
27 |
28 | public override void FindVertices()
29 | {
30 | vertices = new Vector3[boundaries.Length * 5];
31 | for (int i = 0; i < 5; ++i)
32 | System.Array.Copy(boundaries, 0, vertices, i * boundaries.Length, boundaries.Length);
33 | }
34 |
35 | public override void FindTriangles()
36 | {
37 | triangles = new int[18];
38 | int i = 0;
39 |
40 | triangles[i++] = 0;
41 | triangles[i++] = 1;
42 | triangles[i++] = 4;
43 |
44 | // +5
45 | triangles[i++] = 6;
46 | triangles[i++] = 7;
47 | triangles[i++] = 9;
48 |
49 | // +10
50 | triangles[i++] = 12;
51 | triangles[i++] = 13;
52 | triangles[i++] = 14;
53 |
54 | // +15
55 | triangles[i++] = 18;
56 | triangles[i++] = 15;
57 | triangles[i++] = 19;
58 |
59 | triangles[i++] = 20;
60 | triangles[i++] = 23;
61 | triangles[i++] = 22;
62 |
63 | triangles[i++] = 20;
64 | triangles[i++] = 22;
65 | triangles[i++] = 21;
66 | }
67 |
68 | public override void Draw()
69 | {
70 | base.Draw();
71 |
72 | var uvs = new Vector2[mesh.vertices.Length];
73 |
74 | float _wdiv = material.mainTexture.width / 128f;
75 | float _hdiv = material.mainTexture.height / 128f;
76 | float _dist01 = (boundaries[0] - boundaries[1]).magnitude;
77 | float _dist12 = (boundaries[1] - boundaries[2]).magnitude;
78 | float htimes = _dist01 / _wdiv;
79 | float vtimes = Mathf.Sqrt(Mathf.Pow(_dist12 / 2, 2) +
80 | Mathf.Pow(height, 2)) / _hdiv;
81 |
82 | uvs[1] = new Vector2(0f, 0f);
83 | uvs[4] = new Vector2(htimes / 2, vtimes);
84 | uvs[0] = new Vector2(htimes, 0f);
85 | uvs[13] = new Vector2(0f, 0f);
86 | uvs[14] = new Vector2(htimes / 2, vtimes);
87 | uvs[12] = new Vector2(htimes, 0f);
88 |
89 | htimes = _dist12 / _wdiv;
90 | vtimes = Mathf.Sqrt(Mathf.Pow(_dist01 / 2, 2) +
91 | Mathf.Pow(height, 2)) / _hdiv;
92 |
93 | uvs[7] = new Vector2(0f, 0f);
94 | uvs[9] = new Vector2(htimes / 2, vtimes);
95 | uvs[6] = new Vector2(htimes, 0f);
96 | uvs[15] = new Vector2(0f, 0f);
97 | uvs[19] = new Vector2(htimes / 2, vtimes);
98 | uvs[18] = new Vector2(htimes, 0f);
99 |
100 | mesh.uv = uvs;
101 | }
102 | }
103 |
104 | }
--------------------------------------------------------------------------------
/Assets/Standard Assets/Roof/RoofBase.cs:
--------------------------------------------------------------------------------
1 | using UnityEngine;
2 |
3 | namespace Thesis {
4 |
5 | public class RoofBase : DrawableObject
6 | {
7 | /*************** FIELDS ***************/
8 |
9 | public readonly BuildingMesh parentMesh;
10 |
11 | public float height;
12 |
13 | /*************** CONSTRUCTORS ***************/
14 |
15 | public RoofBase (BuildingMesh parent)
16 | {
17 | parentMesh = parent;
18 | height = 0.6f;
19 |
20 | boundaries = new Vector3[8];
21 |
22 | for (int i = 0; i < 4; ++i)
23 | {
24 | boundaries[i] = parentMesh.boundaries[i + 4];
25 | boundaries[i + 4] = boundaries[i] + height * Vector3.up;
26 | }
27 | }
28 |
29 | public override void FindVertices()
30 | {
31 | vertices = new Vector3[boundaries.Length * 2];
32 | for (int i = 0; i < 2; ++i)
33 | System.Array.Copy(boundaries, 0, vertices, i * boundaries.Length, boundaries.Length);
34 | }
35 |
36 | public override void FindTriangles()
37 | {
38 | triangles = new int[24];
39 | int i = 0;
40 |
41 | // front
42 | triangles[i++] = 0;
43 | triangles[i++] = 1;
44 | triangles[i++] = 5;
45 |
46 | triangles[i++] = 0;
47 | triangles[i++] = 5;
48 | triangles[i++] = 4;
49 |
50 | // back
51 | triangles[i++] = 3;
52 | triangles[i++] = 7;
53 | triangles[i++] = 6;
54 |
55 | triangles[i++] = 3;
56 | triangles[i++] = 6;
57 | triangles[i++] = 2;
58 |
59 | // left (+8)
60 | triangles[i++] = 9;
61 | triangles[i++] = 10;
62 | triangles[i++] = 14;
63 |
64 | triangles[i++] = 9;
65 | triangles[i++] = 14;
66 | triangles[i++] = 13;
67 |
68 | // right (+8)
69 | triangles[i++] = 8;
70 | triangles[i++] = 12;
71 | triangles[i++] = 15;
72 |
73 | triangles[i++] = 8;
74 | triangles[i++] = 15;
75 | triangles[i++] = 11;
76 | }
77 |
78 | public override void Draw()
79 | {
80 | base.Draw();
81 |
82 | var uvs = new Vector2[mesh.vertices.Length];
83 |
84 | float _wdiv = material.mainTexture.width / 128f;
85 | int times = Mathf.CeilToInt((boundaries[0] - boundaries[1]).magnitude / _wdiv);
86 |
87 | uvs[1] = new Vector2(0f, 0f);
88 | uvs[0] = new Vector2(times, 0f);
89 | uvs[5] = new Vector2(0f, 1f);
90 | uvs[4] = new Vector2(times, 1f);
91 |
92 | uvs[3] = new Vector2(0f, 0f);
93 | uvs[2] = new Vector2(times, 0f);
94 | uvs[7] = new Vector2(0f, 1f);
95 | uvs[6] = new Vector2(times, 1f);
96 |
97 | times = Mathf.CeilToInt((boundaries[2] - boundaries[1]).magnitude / _wdiv);
98 |
99 | uvs[10] = new Vector2(0f, 0f);
100 | uvs[9] = new Vector2(times, 0f);
101 | uvs[14] = new Vector2(0f, 1f);
102 | uvs[13] = new Vector2(times, 1f);
103 |
104 | uvs[8] = new Vector2(0f, 0f);
105 | uvs[11] = new Vector2(times, 0f);
106 | uvs[12] = new Vector2(0f, 1f);
107 | uvs[15] = new Vector2(times, 1f);
108 |
109 | mesh.uv = uvs;
110 |
111 | gameObject.transform.parent = parentMesh.parent.gameObject.transform;
112 | gameObject.transform.position = parentMesh.meshOrigin;
113 | }
114 | }
115 |
116 | } // namespace Thesis
--------------------------------------------------------------------------------
/Assets/Standard Assets/Roof/FlatRoof.cs:
--------------------------------------------------------------------------------
1 | using UnityEngine;
2 |
3 | namespace Thesis {
4 |
5 | public class FlatRoof : Roof
6 | {
7 | public FlatRoof (BuildingMesh parent)
8 | : base(parent)
9 | {
10 | width = 0.1f;
11 | height = 0.05f;
12 |
13 | boundaries = new Vector3[8];
14 |
15 | for (int i = 0; i < 4; ++i)
16 | {
17 | boundaries[i] = parentMesh.roofBase.boundaries[i + 4] +
18 | width * parentMesh.faces[i].normal +
19 | width * parentMesh.faces[(i + 3) % 4].normal;
20 |
21 | boundaries[i + 4] = boundaries[i] + height * Vector3.up;
22 | }
23 |
24 | decor = new RoofDecoration(this);
25 | if (parentMesh.parent.roofDecorMaterial == null)
26 | {
27 | var list = MaterialManager.Instance.GetCollection("mat_roof_decor");
28 | decor.material = list[Random.Range(0, list.Count)];
29 | }
30 | else
31 | decor.material = parentMesh.parent.roofDecorMaterial;
32 | parentMesh.parent.AddCombinable(decor.material.name, decor);
33 | }
34 |
35 | public override void FindVertices()
36 | {
37 | vertices = new Vector3[boundaries.Length * 3];
38 | for (int i = 0; i < 3; ++i)
39 | System.Array.Copy(boundaries, 0, vertices, i * boundaries.Length, boundaries.Length);
40 | }
41 |
42 | public override void FindTriangles()
43 | {
44 | triangles = new int[36];
45 | var i = 0;
46 |
47 | // front
48 | triangles[i++] = 0;
49 | triangles[i++] = 1;
50 | triangles[i++] = 5;
51 |
52 | triangles[i++] = 0;
53 | triangles[i++] = 5;
54 | triangles[i++] = 4;
55 |
56 | // back
57 | triangles[i++] = 2;
58 | triangles[i++] = 3;
59 | triangles[i++] = 6;
60 |
61 | triangles[i++] = 3;
62 | triangles[i++] = 7;
63 | triangles[i++] = 6;
64 |
65 | // right (+8)
66 | triangles[i++] = 11;
67 | triangles[i++] = 8;
68 | triangles[i++] = 15;
69 |
70 | triangles[i++] = 8;
71 | triangles[i++] = 12;
72 | triangles[i++] = 15;
73 |
74 | // left (+8)
75 | triangles[i++] = 9;
76 | triangles[i++] = 10;
77 | triangles[i++] = 14;
78 |
79 | triangles[i++] = 9;
80 | triangles[i++] = 14;
81 | triangles[i++] = 13;
82 |
83 | // bottom (+16)
84 | triangles[i++] = 16;
85 | triangles[i++] = 18;
86 | triangles[i++] = 17;
87 |
88 | triangles[i++] = 16;
89 | triangles[i++] = 19;
90 | triangles[i++] = 18;
91 |
92 | // top (+16)
93 | triangles[i++] = 20;
94 | triangles[i++] = 21;
95 | triangles[i++] = 22;
96 |
97 | triangles[i++] = 20;
98 | triangles[i++] = 22;
99 | triangles[i++] = 23;
100 | }
101 |
102 | public override void Draw()
103 | {
104 | base.Draw();
105 |
106 | float _wdiv = material.mainTexture.width / 128f;
107 | float _hdiv = material.mainTexture.height / 128f;
108 | float htimes = (boundaries[0] - boundaries[1]).magnitude / _wdiv;
109 | float vtimes = (boundaries[2] - boundaries[1]).magnitude / _hdiv;
110 |
111 | var uvs = new Vector2[mesh.vertices.Length];
112 |
113 | uvs[21] = new Vector2(0f, 0f);
114 | uvs[20] = new Vector2(htimes, 0f);
115 | uvs[22] = new Vector2(0f, vtimes);
116 | uvs[23] = new Vector2(htimes, vtimes);
117 |
118 | mesh.uv = uvs;
119 | }
120 | }
121 |
122 | } // namespace Thesis
--------------------------------------------------------------------------------
/Assets/Standard Assets/Roof/RoofDecoration.cs:
--------------------------------------------------------------------------------
1 | using UnityEngine;
2 |
3 | namespace Thesis {
4 |
5 | public class RoofDecoration : DrawableObject
6 | {
7 | public readonly Roof parentRoof;
8 |
9 | public float height;
10 |
11 | public RoofDecoration (Roof parent)
12 | {
13 | parentRoof = parent;
14 | height = 0.48f;
15 |
16 | boundaries = new Vector3[8];
17 |
18 | if (parentRoof.boundaries.Length < 8)
19 | for (int i = 0; i < 4; ++i)
20 | {
21 | boundaries[i] = parentRoof.boundaries[i];
22 | boundaries[i + 4] = boundaries[i] + height * Vector3.up;
23 | }
24 | else if (parentRoof.boundaries.Length == 8)
25 | for (int i = 0; i < 4; ++i)
26 | {
27 | boundaries[i] = parentRoof.boundaries[i + 4];
28 | boundaries[i + 4] = boundaries[i] + height * Vector3.up;
29 | }
30 | }
31 |
32 | public override void FindVertices()
33 | {
34 | vertices = new Vector3[boundaries.Length * 2];
35 | for (int i = 0; i < 2; ++i)
36 | System.Array.Copy(boundaries, 0, vertices, i * boundaries.Length, boundaries.Length);
37 | }
38 |
39 | public override void FindTriangles()
40 | {
41 | triangles = new int[24];
42 | int i = 0;
43 |
44 | // front
45 | triangles[i++] = 0;
46 | triangles[i++] = 1;
47 | triangles[i++] = 5;
48 |
49 | triangles[i++] = 0;
50 | triangles[i++] = 5;
51 | triangles[i++] = 4;
52 |
53 | // back
54 | triangles[i++] = 3;
55 | triangles[i++] = 7;
56 | triangles[i++] = 6;
57 |
58 | triangles[i++] = 3;
59 | triangles[i++] = 6;
60 | triangles[i++] = 2;
61 |
62 | // left (+8)
63 | triangles[i++] = 9;
64 | triangles[i++] = 10;
65 | triangles[i++] = 14;
66 |
67 | triangles[i++] = 9;
68 | triangles[i++] = 14;
69 | triangles[i++] = 13;
70 |
71 | // right (+8)
72 | triangles[i++] = 8;
73 | triangles[i++] = 12;
74 | triangles[i++] = 15;
75 |
76 | triangles[i++] = 8;
77 | triangles[i++] = 15;
78 | triangles[i++] = 11;
79 | }
80 |
81 | public override void Draw()
82 | {
83 | base.Draw();
84 |
85 | var uvs = new Vector2[mesh.vertices.Length];
86 |
87 | float _wdiv = material.mainTexture.width / 128f;
88 | int times = Mathf.CeilToInt((boundaries[0] - boundaries[1]).magnitude / _wdiv);
89 |
90 | uvs[1] = new Vector2(0f, 0f);
91 | uvs[0] = new Vector2(times, 0f);
92 | uvs[5] = new Vector2(0f, 1f);
93 | uvs[4] = new Vector2(times, 1f);
94 |
95 | uvs[3] = new Vector2(0f, 0f);
96 | uvs[2] = new Vector2(times, 0f);
97 | uvs[7] = new Vector2(0f, 1f);
98 | uvs[6] = new Vector2(times, 1f);
99 |
100 | times = Mathf.CeilToInt((boundaries[2] - boundaries[1]).magnitude / _wdiv);
101 |
102 | uvs[10] = new Vector2(0f, 0f);
103 | uvs[9] = new Vector2(times, 0f);
104 | uvs[14] = new Vector2(0f, 1f);
105 | uvs[13] = new Vector2(times, 1f);
106 |
107 | uvs[8] = new Vector2(0f, 0f);
108 | uvs[11] = new Vector2(times, 0f);
109 | uvs[12] = new Vector2(0f, 1f);
110 | uvs[15] = new Vector2(times, 1f);
111 |
112 | mesh.uv = uvs;
113 |
114 | gameObject.transform.parent = parentRoof.parentMesh.parent.gameObject.transform;
115 | gameObject.transform.position = parentRoof.parentMesh.meshOrigin;
116 | }
117 | }
118 |
119 | } // namespace Thesis
--------------------------------------------------------------------------------
/Assets/Standard Assets/Managers/ColorManager.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using UnityEngine;
4 |
5 | namespace Thesis {
6 |
7 | public sealed class ColorManager
8 | {
9 | private static readonly ColorManager _instance = new ColorManager();
10 | public static ColorManager Instance
11 | {
12 | get { return _instance; }
13 | }
14 |
15 | private static bool _isInitialized;
16 |
17 | private Dictionary _colors;
18 |
19 | private Dictionary> _collections;
20 |
21 | private ColorManager ()
22 | {
23 | _colors = new Dictionary();
24 | _collections = new Dictionary>();
25 | _isInitialized = false;
26 | }
27 |
28 | public void Init ()
29 | {
30 | if (!_isInitialized)
31 | {
32 | AddComponentColors();
33 | AddWallColors();
34 |
35 | _isInitialized = true;
36 | }
37 | }
38 |
39 | public void Unload ()
40 | {
41 | _colors.Clear();
42 | foreach (List l in _collections.Values)
43 | l.Clear();
44 | _collections.Clear();
45 | _isInitialized = false;
46 | }
47 |
48 | public void Add (string name, Color color)
49 | {
50 | if (!_colors.ContainsKey(name))
51 | _colors.Add(name, color);
52 | }
53 |
54 | public void AddToCollection (string name, Color color)
55 | {
56 | if (_collections.ContainsKey(name))
57 | {
58 | if (!_collections[name].Contains(color))
59 | _collections[name].Add(color);
60 | }
61 | else
62 | {
63 | var list = new List();
64 | list.Add(color);
65 | _collections.Add(name, list);
66 | }
67 | }
68 |
69 | public Color Get (string name)
70 | {
71 | return _colors.ContainsKey(name) ? _colors[name] : Color.clear;
72 | }
73 |
74 | public List GetCollection (string name)
75 | {
76 | return _collections.ContainsKey(name) ? _collections[name] : null;
77 | }
78 |
79 | private void AddComponentColors ()
80 | {
81 | var name = "col_components";
82 | AddToCollection(name, new Color32( 245, 245, 220, 255));
83 | AddToCollection(name, new Color32( 210, 180, 140, 255));
84 | AddToCollection(name, new Color32( 151, 105, 79, 255));
85 | AddToCollection(name, new Color32( 139, 105, 105, 255));
86 | AddToCollection(name, new Color32( 139, 90, 51, 255));
87 | AddToCollection(name, new Color32( 139, 69, 19, 255));
88 | AddToCollection(name, new Color32( 133, 99, 99, 255));
89 | AddToCollection(name, new Color32( 107, 66, 38, 255));
90 | AddToCollection(name, new Color32( 92, 64, 51, 255));
91 | AddToCollection(name, new Color32( 92, 51, 23, 255));
92 | }
93 |
94 | private void AddWallColors ()
95 | {
96 | var name = "col_walls";
97 | AddToCollection(name, new Color32( 166, 159, 141, 255));
98 | AddToCollection(name, new Color32( 231, 206, 165, 255));
99 | AddToCollection(name, new Color32( 173, 155, 155, 255));
100 | AddToCollection(name, new Color32( 135, 125, 115, 255));
101 | AddToCollection(name, new Color32( 155, 157, 143, 255));
102 | AddToCollection(name, new Color32( 225, 168, 151, 255));
103 | AddToCollection(name, new Color32( 224, 174, 125, 255));
104 | AddToCollection(name, new Color32( 216, 191, 150, 255));
105 | AddToCollection(name, new Color32( 205, 171, 110, 255));
106 | AddToCollection(name, new Color32( 165, 133, 118, 255));
107 | AddToCollection(name, new Color32( 190, 169, 164, 255));
108 | AddToCollection(name, new Color32( 194, 183, 181, 255));
109 | }
110 | }
111 |
112 | } // namespace Thesis
--------------------------------------------------------------------------------
/Assets/Standard Assets/General/Util.cs:
--------------------------------------------------------------------------------
1 | using UnityEngine;
2 |
3 | using Random = System.Random;
4 | using Exception = System.Exception;
5 | using CombinablesCollection = System.Collections.Generic.IList;
6 |
7 | namespace Thesis {
8 |
9 | public class Util
10 | {
11 | public static Random random = new Random();
12 |
13 | ///
14 | /// Rolls a weighted dice.
15 | ///
16 | ///
17 | /// The chances for each possible result.
18 | ///
19 | ///
20 | /// A set of the possible result values.
21 | ///
22 | ///
23 | /// The maximum of decimal digits that a number has.
24 | ///
25 | public static int RollDice (float[] chances, int[] numbers = null, int precision = 2)
26 | {
27 | if (numbers == null)
28 | {
29 | numbers = new int[chances.Length];
30 | for (var i = 0; i < chances.Length; ++i)
31 | numbers[i] = i + 1;
32 | }
33 |
34 | precision = (int) Mathf.Pow(10, precision);
35 |
36 | int[] expanded = new int[precision];
37 | int start = 0;
38 | int end = 0;
39 | for (var i = 0; i < chances.Length; ++i)
40 | {
41 | start = end;
42 | end += Mathf.FloorToInt(chances[i] * precision);
43 | for (var j = start; j < end; ++j)
44 | expanded[j] = numbers[i];
45 | }
46 |
47 | return expanded[random.Next(precision)];
48 | }
49 |
50 | public static GameObject CombineMeshes (string name,
51 | string materialName,
52 | CombinablesCollection objects,
53 | GameObject parent = null)
54 | {
55 | var gameObject = new GameObject(name);
56 | gameObject.SetActive(false);
57 | if (parent != null)
58 | gameObject.transform.parent = parent.transform;
59 | var meshFilter = gameObject.AddComponent();
60 | var meshRenderer = gameObject.AddComponent();
61 | meshRenderer.sharedMaterial = Resources.Load("Materials/" + materialName,
62 | typeof(Material)) as Material;
63 |
64 | MeshFilter[] meshFilters = new MeshFilter[objects.Count];
65 | for (var i = 0; i < objects.Count; ++i)
66 | {
67 | meshFilters[i] = objects[i].meshFilter;
68 | GameObject.Destroy(objects[i].gameObject);
69 | }
70 |
71 | CombineInstance[] combine = new CombineInstance[meshFilters.Length];
72 | for (var i = 0; i < meshFilters.Length; ++i)
73 | {
74 | combine[i].mesh = meshFilters[i].sharedMesh;
75 | combine[i].transform = meshFilters[i].transform.localToWorldMatrix;
76 | }
77 |
78 | meshFilter.mesh = new Mesh();
79 | meshFilter.mesh.CombineMeshes(combine);
80 |
81 | return gameObject;
82 | }
83 |
84 | public static Vector3 IntersectionPoint (Vector3 p1, Vector3 dir1,
85 | Vector3 p2, Vector3 dir2)
86 | {
87 | var dir_cross = Vector3.Cross(dir1, dir2);
88 | var tmp_cross = Vector3.Cross(p2 - p1, dir2);
89 |
90 | float c1;
91 | if (dir_cross.x != 0f)
92 | c1 = tmp_cross.x / dir_cross.x;
93 | else if (dir_cross.y != 0f)
94 | c1 = tmp_cross.y / dir_cross.y;
95 | else if (dir_cross.z != 0f)
96 | c1 = tmp_cross.z / dir_cross.z;
97 | else
98 | throw new System.DivideByZeroException("Result of cross product is Vector3(0,0,0)!");
99 |
100 | return p1 + c1 * dir1;
101 | }
102 |
103 | public static void PrintVector (string s, Vector3 v)
104 | {
105 | Debug.Log(s + " " + v.x + " " + v.y + " " + v.z);
106 | }
107 | }
108 |
109 | } // namespace Thesis
--------------------------------------------------------------------------------
/Assets/Standard Assets/General/DrawableObject.cs:
--------------------------------------------------------------------------------
1 | using UnityEngine;
2 | using Thesis.Interface;
3 |
4 | namespace Thesis {
5 |
6 | public class DrawableObject : ProceduralObject,
7 | IDrawable,
8 | ICombinable
9 | {
10 | /*************** FIELDS ***************/
11 |
12 | public string name;
13 |
14 | public Material material;
15 |
16 | public MeshFilter meshFilter;
17 |
18 | public Mesh mesh;
19 |
20 | public Vector3 meshOrigin;
21 |
22 | public Vector3[] boundaries;
23 |
24 | public Vector3[] vertices;
25 |
26 | public int[] triangles;
27 |
28 | /*************** CONSTRUCTORS ***************/
29 |
30 | public DrawableObject (string name = "drawableObject", string materialName = null)
31 | {
32 | this.name = name;
33 | if (materialName != null)
34 | this.material = MaterialManager.Instance.Get(materialName);
35 | }
36 |
37 | /*************** METHODS ***************/
38 |
39 | ///
40 | /// Calculates the intersection point of the lines formed by each two points in 3D space.
41 | /// Points a1 and a2 form the first line and points b1 and b2 form the second.
42 | /// Maths found here: http://mathforum.org/library/drmath/view/62814.html
43 | ///
44 | public virtual void FindMeshOrigin (Vector3 a1, Vector3 a2, Vector3 b1, Vector3 b2)
45 | {
46 | var a_dir = a1 - a2; // the direction vector of the first line
47 | var b_dir = b1 - b2; // the direction vector of the second line
48 | var dir_cross = Vector3.Cross(a_dir, b_dir);
49 | var tmp_cross = Vector3.Cross(b1 - a1, b_dir);
50 |
51 | float c1;
52 | if (dir_cross.x != 0f)
53 | c1 = tmp_cross.x / dir_cross.x;
54 | else if (dir_cross.y != 0f)
55 | c1 = tmp_cross.y / dir_cross.y;
56 | else if (dir_cross.z != 0f)
57 | c1 = tmp_cross.z / dir_cross.z;
58 | else
59 | throw new System.DivideByZeroException("Result of cross product is Vector3(0,0,0)!");
60 |
61 | meshOrigin = a1 + c1 * a_dir;
62 | }
63 |
64 | public virtual void FindVertices ()
65 | {
66 | throw new System.NotImplementedException();
67 | }
68 |
69 | public virtual void FindTriangles ()
70 | {
71 | throw new System.NotImplementedException();
72 | }
73 |
74 | public virtual void Draw ()
75 | {
76 | gameObject = new GameObject(name);
77 | meshFilter = gameObject.AddComponent();
78 | var renderer = gameObject.AddComponent();
79 |
80 | gameObject.SetActive(false);
81 | gameObject.isStatic = true;
82 | if (material != null)
83 | renderer.sharedMaterial = material;
84 |
85 | mesh = new Mesh();
86 | mesh.Clear();
87 | mesh.vertices = vertices;
88 | mesh.triangles = triangles;
89 | mesh.uv = new Vector2[mesh.vertices.Length];
90 | mesh.RecalculateNormals();
91 | mesh.Optimize();
92 | meshFilter.sharedMesh = mesh;
93 | }
94 |
95 | public virtual void Destroy ()
96 | {
97 | GameObject.DestroyImmediate(mesh);
98 | GameObject.DestroyImmediate(gameObject);
99 | }
100 |
101 | /*************** INTERFACE EXPLICIT IMPLEMENTATION ***************/
102 |
103 | Vector3[] IDrawable.vertices
104 | {
105 | get { return vertices; }
106 | }
107 |
108 | int[] IDrawable.triangles
109 | {
110 | get { return triangles; }
111 | }
112 |
113 | GameObject ICombinable.gameObject
114 | {
115 | get { return gameObject; }
116 | }
117 |
118 | MeshFilter ICombinable.meshFilter
119 | {
120 | get { return meshFilter; }
121 | }
122 |
123 | Material ICombinable.material
124 | {
125 | get { return material; }
126 | }
127 |
128 | Mesh ICombinable.mesh
129 | {
130 | get { return mesh; }
131 | }
132 | }
133 |
134 | } // namespace Thesis
--------------------------------------------------------------------------------
/Assets/Standard Assets/Balcony/BalconyFloor.cs:
--------------------------------------------------------------------------------
1 | using UnityEngine;
2 |
3 | namespace Thesis {
4 |
5 | public class BalconyFloor : DrawableObject
6 | {
7 | /*************** FIELDS ***************/
8 |
9 | public readonly Balcony parentBalcony;
10 |
11 | public float height;
12 |
13 | public float width;
14 |
15 | public float depth;
16 |
17 | public BuildingMesh parentBuilding
18 | {
19 | get { return parentBalcony.parentBuilding; }
20 | }
21 |
22 | /*************** CONSTRUCTORS ***************/
23 |
24 | public BalconyFloor (Balcony parent)
25 | {
26 | parentBalcony = parent;
27 |
28 | height = parentBuilding.balconyFloorHeight;
29 | width = parentBuilding.balconyFloorWidth;
30 | depth = parentBuilding.balconyFloorDepth;
31 |
32 | var tmp_right = parentBalcony.parentFace.right * width;
33 | var tmp_normal = parentBalcony.parentFace.normal * depth;
34 | var tmp_up = -(height - 0.01f) * Vector3.up;
35 |
36 | boundaries = new Vector3[8];
37 | boundaries[0] = parentBalcony.boundaries[0] + tmp_right + tmp_normal + tmp_up;
38 | boundaries[1] = parentBalcony.boundaries[1] - tmp_right + tmp_normal + tmp_up;
39 | boundaries[2] = parentBalcony.boundaries[1] - tmp_right - tmp_normal + tmp_up;
40 | boundaries[3] = parentBalcony.boundaries[0] + tmp_right - tmp_normal + tmp_up;
41 |
42 | for (var i = 0; i < 4; ++i)
43 | boundaries[i + 4] = boundaries[i] + Vector3.up * height;
44 |
45 | FindMeshOrigin(boundaries[0],
46 | boundaries[6],
47 | boundaries[2],
48 | boundaries[4]);
49 |
50 | for (var i = 0; i < boundaries.Length; ++i)
51 | boundaries[i] -= meshOrigin;
52 | }
53 |
54 | public override void FindVertices ()
55 | {
56 | vertices = new Vector3[boundaries.Length * 3];
57 | for (int i = 0; i < 3; ++i)
58 | System.Array.Copy(boundaries, 0, vertices, i * boundaries.Length, boundaries.Length);
59 | }
60 |
61 | public override void FindTriangles ()
62 | {
63 | triangles = new int[36];
64 |
65 | // bottom
66 | triangles[0] = 0;
67 | triangles[1] = 2;
68 | triangles[2] = 1;
69 |
70 | triangles[3] = 0;
71 | triangles[4] = 3;
72 | triangles[5] = 2;
73 |
74 | // top
75 | triangles[6] = 4;
76 | triangles[7] = 5;
77 | triangles[8] = 6;
78 |
79 | triangles[9] = 4;
80 | triangles[10] = 6;
81 | triangles[11] = 7;
82 |
83 | // left
84 | triangles[12] = 9; // 1 + 8
85 | triangles[13] = 10; // 2 + 8
86 | triangles[14] = 13; // 5 + 8
87 |
88 | triangles[15] = 10; // 2 + 8
89 | triangles[16] = 14; // 6 + 8
90 | triangles[17] = 13; // 5 + 8
91 |
92 | // right
93 | triangles[18] = 8; // 0 + 8
94 | triangles[19] = 12; // 4 + 8
95 | triangles[20] = 11; // 3 + 8
96 |
97 | triangles[21] = 11; // 3 + 8
98 | triangles[22] = 12; // 4 + 8
99 | triangles[23] = 15; // 7 + 8
100 |
101 | // front
102 | triangles[24] = 16; // 0 + 16
103 | triangles[25] = 17; // 1 + 16
104 | triangles[26] = 20; // 4 + 16
105 |
106 | triangles[27] = 17; // 1 + 16
107 | triangles[28] = 21; // 5 + 16
108 | triangles[29] = 20; // 4 + 16
109 |
110 | // back
111 | triangles[30] = 18; // 2 + 16
112 | triangles[31] = 19; // 3 + 16
113 | triangles[32] = 23; // 7 + 16
114 |
115 | triangles[33] = 18; // 2 + 16
116 | triangles[34] = 23; // 7 + 16
117 | triangles[35] = 22; // 6 + 16
118 | }
119 |
120 | public override void Draw ()
121 | {
122 | base.Draw();
123 |
124 | gameObject.transform.position = meshOrigin + parentBuilding.meshOrigin;
125 | gameObject.transform.parent = parentBuilding.parent.gameObject.transform;
126 | }
127 | }
128 |
129 | } // namespace Thesis
--------------------------------------------------------------------------------
/Assets/Standard Assets/Window/Window.cs:
--------------------------------------------------------------------------------
1 | using UnityEngine;
2 |
3 | namespace Thesis {
4 |
5 | public class Window : FaceComponent
6 | {
7 | /*************** FIELDS ***************/
8 |
9 | public Shutter rightShutter;
10 |
11 | public Shutter leftShutter;
12 |
13 | public ComponentDecor decor;
14 |
15 | public Building masterParent
16 | {
17 | get { return parentBuilding.parent; }
18 | }
19 |
20 | /*************** CONSTRUCTORS ***************/
21 |
22 | public Window (Face parent, Vector3 dr, Vector3 dl, ComponentCoordinate position)
23 | : base(parent, position)
24 | {
25 | height = parentBuilding.windowHeight;
26 | depth = 0.4f;
27 | width = (dr - dl).magnitude;
28 | float height_modifier = parentBuilding.floorHeight / 2.25f - height / 2;
29 |
30 | if (masterParent.windowWidth > 0f)
31 | {
32 | var mod = (masterParent.windowWidth - width) / 2f;
33 | width = masterParent.windowWidth;
34 | dr += mod * parentFace.right;
35 | dl -= mod * parentFace.right;
36 | }
37 |
38 | boundaries = new Vector3[4];
39 | boundaries[0] = new Vector3(dr.x, dr.y + height_modifier, dr.z);
40 | boundaries[1] = new Vector3(dl.x, dl.y + height_modifier, dl.z);
41 | boundaries[2] = new Vector3(dl.x, dl.y + height + height_modifier, dl.z);
42 | boundaries[3] = new Vector3(dr.x, dr.y + height + height_modifier, dr.z);
43 |
44 | frame = new ComponentFrame(this);
45 | frame.name = "neo_window_frame";
46 | frame.material = MaterialManager.Instance.Get("ComponentFrame");
47 | parentBuilding.parent.AddCombinable(frame.material.name, frame);
48 |
49 | body = new WindowBody(this);
50 | body.name = "neo_window_body";
51 | body.material = parentBuilding.parent.windowMaterial;
52 | parentBuilding.parent.AddCombinable(body.material.name, body);
53 |
54 | rightShutter = new Shutter(this, ShutterSide.Right);
55 | rightShutter.name = "right_shutter";
56 | rightShutter.material = parentBuilding.parent.shutterMaterial;
57 | parentBuilding.parent.AddCombinable(rightShutter.material.name, rightShutter);
58 |
59 | leftShutter = new Shutter(this, ShutterSide.Left);
60 | leftShutter.name = "left_shutter";
61 | leftShutter.material = parentBuilding.parent.shutterMaterial;
62 | parentBuilding.parent.AddCombinable(leftShutter.material.name, leftShutter);
63 |
64 | if (position.floor >= 1)
65 | {
66 | decor = new ComponentDecor(this);
67 | decor.name = "window_decor";
68 | decor.material = parentBuilding.parent.compDecorMaterial;
69 | parentBuilding.parent.AddCombinable(decor.material.name, decor);
70 | }
71 | else
72 | {
73 | decor = new ComponentDecor(this, true);
74 | decor.name = "window_decor";
75 | decor.material = parentBuilding.parent.simpleCompDecorMaterial;
76 | parentBuilding.parent.AddCombinable(decor.material.name, decor);
77 | }
78 | }
79 |
80 | /*************** METHODS ***************/
81 |
82 | public override void Draw ()
83 | {
84 | //base.Draw();
85 |
86 | frame.FindVertices();
87 | frame.FindTriangles();
88 | frame.Draw();
89 |
90 | body.FindVertices();
91 | body.FindTriangles();
92 | body.Draw();
93 |
94 | //Shutter.SetAngles();
95 |
96 | rightShutter.FindVertices();
97 | rightShutter.FindTriangles();
98 | rightShutter.Draw();
99 |
100 | leftShutter.FindVertices();
101 | leftShutter.FindTriangles();
102 | leftShutter.Draw();
103 |
104 | if (decor != null)
105 | {
106 | decor.FindVertices();
107 | decor.FindTriangles();
108 | decor.Draw();
109 | }
110 | }
111 |
112 | public override void Destroy()
113 | {
114 | base.Destroy();
115 |
116 | rightShutter.Destroy();
117 | leftShutter.Destroy();
118 |
119 | if (decor != null)
120 | decor.Destroy();
121 | }
122 | }
123 |
124 | } // namespace Thesis
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | #################
2 | ## Unity3D
3 | #################
4 |
5 | *.sln
6 | *.csproj
7 | *.unityproj
8 | *.suo
9 | Temp/*
10 | Library/*
11 | *.userprefs
12 |
13 |
14 | #################
15 | ## Eclipse
16 | #################
17 |
18 | *.pydevproject
19 | .project
20 | .metadata
21 | bin/
22 | tmp/
23 | *.tmp
24 | *.bak
25 | *.swp
26 | *~.nib
27 | local.properties
28 | .classpath
29 | .settings/
30 | .loadpath
31 |
32 | # External tool builders
33 | .externalToolBuilders/
34 |
35 | # Locally stored "Eclipse launch configurations"
36 | *.launch
37 |
38 | # CDT-specific
39 | .cproject
40 |
41 | # PDT-specific
42 | .buildpath
43 |
44 |
45 | #################
46 | ## Visual Studio
47 | #################
48 |
49 | ## Ignore Visual Studio temporary files, build results, and
50 | ## files generated by popular Visual Studio add-ons.
51 |
52 | # User-specific files
53 | *.suo
54 | *.user
55 | *.sln.docstates
56 |
57 | # Build results
58 |
59 | [Dd]ebug/
60 | [Rr]elease/
61 | x64/
62 | build/
63 | [Bb]in/
64 | [Oo]bj/
65 |
66 | # MSTest test Results
67 | [Tt]est[Rr]esult*/
68 | [Bb]uild[Ll]og.*
69 |
70 | *_i.c
71 | *_p.c
72 | *.ilk
73 | *.meta
74 | *.obj
75 | *.pch
76 | *.pdb
77 | *.pgc
78 | *.pgd
79 | *.rsp
80 | *.sbr
81 | *.tlb
82 | *.tli
83 | *.tlh
84 | *.tmp
85 | *.tmp_proj
86 | *.log
87 | *.vspscc
88 | *.vssscc
89 | .builds
90 | *.pidb
91 | *.log
92 | *.scc
93 |
94 | # Visual C++ cache files
95 | ipch/
96 | *.aps
97 | *.ncb
98 | *.opensdf
99 | *.sdf
100 | *.cachefile
101 |
102 | # Visual Studio profiler
103 | *.psess
104 | *.vsp
105 | *.vspx
106 |
107 | # Guidance Automation Toolkit
108 | *.gpState
109 |
110 | # ReSharper is a .NET coding add-in
111 | _ReSharper*/
112 | *.[Rr]e[Ss]harper
113 |
114 | # TeamCity is a build add-in
115 | _TeamCity*
116 |
117 | # DotCover is a Code Coverage Tool
118 | *.dotCover
119 |
120 | # NCrunch
121 | *.ncrunch*
122 | .*crunch*.local.xml
123 |
124 | # Installshield output folder
125 | [Ee]xpress/
126 |
127 | # DocProject is a documentation generator add-in
128 | DocProject/buildhelp/
129 | DocProject/Help/*.HxT
130 | DocProject/Help/*.HxC
131 | DocProject/Help/*.hhc
132 | DocProject/Help/*.hhk
133 | DocProject/Help/*.hhp
134 | DocProject/Help/Html2
135 | DocProject/Help/html
136 |
137 | # Click-Once directory
138 | publish/
139 |
140 | # Publish Web Output
141 | *.Publish.xml
142 | *.pubxml
143 |
144 | # NuGet Packages Directory
145 | ## TODO: If you have NuGet Package Restore enabled, uncomment the next line
146 | #packages/
147 |
148 | # Windows Azure Build Output
149 | csx
150 | *.build.csdef
151 |
152 | # Windows Store app package directory
153 | AppPackages/
154 |
155 | # Others
156 | sql/
157 | *.Cache
158 | ClientBin/
159 | [Ss]tyle[Cc]op.*
160 | ~$*
161 | *~
162 | *.dbmdl
163 | *.[Pp]ublish.xml
164 | *.pfx
165 | *.publishsettings
166 |
167 | # RIA/Silverlight projects
168 | Generated_Code/
169 |
170 | # Backup & report files from converting an old project file to a newer
171 | # Visual Studio version. Backup files are not needed, because we have git ;-)
172 | _UpgradeReport_Files/
173 | Backup*/
174 | UpgradeLog*.XML
175 | UpgradeLog*.htm
176 |
177 | # SQL Server files
178 | App_Data/*.mdf
179 | App_Data/*.ldf
180 |
181 | #############
182 | ## Windows detritus
183 | #############
184 |
185 | # Windows image file caches
186 | Thumbs.db
187 | ehthumbs.db
188 |
189 | # Folder config file
190 | Desktop.ini
191 |
192 | # Recycle Bin used on file shares
193 | $RECYCLE.BIN/
194 |
195 | # Mac crap
196 | .DS_Store
197 |
198 |
199 | #############
200 | ## Python
201 | #############
202 |
203 | *.py[co]
204 |
205 | # Packages
206 | *.egg
207 | *.egg-info
208 | dist/
209 | build/
210 | eggs/
211 | parts/
212 | var/
213 | sdist/
214 | develop-eggs/
215 | .installed.cfg
216 |
217 | # Installer logs
218 | pip-log.txt
219 |
220 | # Unit test / coverage reports
221 | .coverage
222 | .tox
223 |
224 | #Translations
225 | *.mo
226 |
227 | #Mr Developer
228 | .mr.developer.cfg
229 |
--------------------------------------------------------------------------------
/Assets/Scripts/CityMapController.cs:
--------------------------------------------------------------------------------
1 | using UnityEngine;
2 | using Thesis;
3 | using System.Linq;
4 |
5 | public class CityMapController : MonoBehaviour {
6 |
7 | private Block block;
8 |
9 | private bool _drawGizmos = true;
10 | private bool _drawFirstBlock = true;
11 | private bool _drawBlocks = true;
12 | private bool _drawSideWalk = true;
13 | private bool _drawFirstLot = true;
14 | private bool _drawLots = true;
15 |
16 | void Start ()
17 | {
18 | block = new Block();
19 | block.Bisect();
20 | }
21 |
22 | void Update ()
23 | {
24 | if (Input.GetKeyUp(KeyCode.B))
25 | {
26 | AddBuildings();
27 | CityMapManager.Instance.DrawRoads();
28 | CityMapManager.Instance.DrawSidewalks();
29 | CityMapManager.Instance.DrawLots();
30 | }
31 |
32 | if (Input.GetKeyUp(KeyCode.R))
33 | {
34 | BuildingManager.Instance.DestroyBuildings();
35 | block = new Block();
36 | block.Bisect();
37 | }
38 |
39 | if (Input.GetKeyUp(KeyCode.G))
40 | _drawGizmos = !_drawGizmos;
41 |
42 | if (Input.GetKeyUp(KeyCode.Alpha1))
43 | _drawFirstBlock = !_drawFirstBlock;
44 |
45 | if (Input.GetKeyUp(KeyCode.Alpha2))
46 | _drawBlocks = !_drawBlocks;
47 |
48 | if (Input.GetKeyUp(KeyCode.Alpha3))
49 | _drawSideWalk = !_drawSideWalk;
50 |
51 | if (Input.GetKeyUp(KeyCode.Alpha4))
52 | _drawFirstLot = !_drawFirstLot;
53 |
54 | if (Input.GetKeyUp(KeyCode.Alpha5))
55 | _drawLots = !_drawLots;
56 |
57 | if (Input.GetKeyUp(KeyCode.Alpha0))
58 | {
59 | _drawFirstBlock = false;
60 | _drawBlocks = false;
61 | _drawSideWalk = false;
62 | _drawFirstLot = false;
63 | _drawLots = false;
64 | }
65 | }
66 |
67 | private void AddBuildings ()
68 | {
69 | BuildingManager.Instance.DestroyBuildings();
70 | foreach (Block b in CityMapManager.Instance.blocks)
71 | foreach (BuildingLot l in b.finalLots)
72 | BuildingManager.Instance.Build(l);
73 | }
74 |
75 | void OnPostRender ()
76 | {
77 | if (_drawGizmos)
78 | {
79 | if (_drawFirstBlock)
80 | {
81 | MaterialManager.Instance.Get("line_block").SetPass(0);
82 | GL.Begin(GL.LINES);
83 | foreach (Edge e in block.edges)
84 | {
85 | GL.Vertex(e.start);
86 | GL.Vertex(e.end);
87 | }
88 | GL.End();
89 | }
90 |
91 | if (_drawBlocks)
92 | {
93 | MaterialManager.Instance.Get("line_block").SetPass(0);
94 | GL.Begin(GL.LINES);
95 | foreach (Block b in CityMapManager.Instance.blocks)
96 | foreach (Edge e in b.edges)
97 | {
98 | GL.Vertex(e.start);
99 | GL.Vertex(e.end);
100 | }
101 | GL.End();
102 | }
103 |
104 | if (_drawSideWalk)
105 | {
106 | MaterialManager.Instance.Get("line_sidewalk").SetPass(0);
107 | GL.Begin(GL.LINES);
108 | foreach (Sidewalk s in CityMapManager.Instance.sidewalks)
109 | foreach (Edge e in s.edges)
110 | {
111 | GL.Vertex(e.start);
112 | GL.Vertex(e.end);
113 | }
114 | GL.End();
115 | }
116 |
117 | if (_drawFirstLot)
118 | {
119 | MaterialManager.Instance.Get("line_lot").SetPass(0);
120 | GL.Begin(GL.LINES);
121 | foreach (Block b in CityMapManager.Instance.blocks)
122 | foreach (Edge e in b.initialLot.edges)
123 | {
124 | GL.Vertex(e.start);
125 | GL.Vertex(e.end);
126 | }
127 | GL.End();
128 | }
129 |
130 | if (_drawLots)
131 | {
132 | MaterialManager.Instance.Get("line_lot").SetPass(0);
133 | GL.Begin(GL.LINES);
134 | foreach (Block b in CityMapManager.Instance.blocks)
135 | foreach (BuildingLot l in b.finalLots)
136 | foreach (Edge e in l.edges)
137 | {
138 | GL.Vertex(e.start);
139 | GL.Vertex(e.end);
140 | }
141 | GL.End();
142 | }
143 | }
144 | }
145 | }
--------------------------------------------------------------------------------
/Assets/Standard Assets/Managers/CityMapManager.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using UnityEngine;
3 |
4 | namespace Thesis {
5 |
6 | public sealed class CityMapManager
7 | {
8 | private const float _tolerance = 5f;
9 |
10 | private static readonly CityMapManager _instance = new CityMapManager();
11 | public static CityMapManager Instance
12 | {
13 | get { return _instance; }
14 | }
15 |
16 | private List _blocks;
17 | public IList blocks
18 | {
19 | get { return _blocks.AsReadOnly(); }
20 | }
21 |
22 | private List _lots;
23 | public IList lots
24 | {
25 | get { return _lots.AsReadOnly(); }
26 | }
27 |
28 | private List _nodes;
29 | public IList nodes
30 | {
31 | get { return _nodes.AsReadOnly(); }
32 | }
33 |
34 | private List _roads;
35 | public IList roads
36 | {
37 | get { return _roads; }
38 | }
39 |
40 | private List _sidewalks;
41 | public IList sidewalks
42 | {
43 | get { return _sidewalks; }
44 | }
45 |
46 | private List _drawableLots;
47 | public IList drawableLots
48 | {
49 | get { return _drawableLots; }
50 | }
51 |
52 | private CityMapManager ()
53 | {
54 | _blocks = new List();
55 | _nodes = new List();
56 | _lots = new List();
57 | _roads = new List();
58 | _sidewalks = new List();
59 | _drawableLots = new List();
60 | }
61 |
62 | public void Add (Block block)
63 | {
64 | _blocks.Add(block);
65 | }
66 |
67 | public void Add (BuildingLot lot)
68 | {
69 | _lots.Add(lot);
70 | }
71 |
72 | public int Add (Vector3 node)
73 | {
74 | var n = _nodes.FindIndex(0, delegate (Vector3 v) {
75 | return (Mathf.Abs(v.x - node.x) <= _tolerance &&
76 | Mathf.Abs(v.z - node.z) <= _tolerance);
77 | });
78 | if (n == -1)
79 | _nodes.Add(node);
80 | return n;
81 | }
82 |
83 | public void AddRoad (Block block)
84 | {
85 | Road r = new Road(block);
86 | r.name = "road";
87 | r.material = MaterialManager.Instance.Get("mat_road");
88 | _roads.Add(r);
89 | }
90 |
91 | public void DrawRoads ()
92 | {
93 | foreach (Road r in _roads)
94 | {
95 | r.FindVertices();
96 | r.FindTriangles();
97 | r.Draw();
98 | r.gameObject.SetActive(true);
99 | }
100 | }
101 |
102 | public void DestroyRoads ()
103 | {
104 | foreach (Road r in _roads)
105 | r.Destroy();
106 | }
107 |
108 | public void AddSidewalk (Block block)
109 | {
110 | Sidewalk s = new Sidewalk(block);
111 | s.name = "sidewalk";
112 | s.material = MaterialManager.Instance.Get("mat_sidewalk");
113 | _sidewalks.Add(s);
114 | }
115 |
116 | public void DrawSidewalks ()
117 | {
118 | foreach (Sidewalk s in _sidewalks)
119 | {
120 | s.FindVertices();
121 | s.FindTriangles();
122 | s.Draw();
123 | s.gameObject.SetActive(true);
124 | }
125 | }
126 |
127 | public void DestroySidewalks ()
128 | {
129 | foreach (Sidewalk s in _sidewalks)
130 | s.Destroy();
131 | }
132 |
133 | public void AddDrawableLot (BuildingLot lot)
134 | {
135 | lot.name = "buildinglot";
136 | lot.material = MaterialManager.Instance.Get("mat_lot");
137 | _drawableLots.Add(lot);
138 | }
139 |
140 | public void DrawLots ()
141 | {
142 | foreach (BuildingLot lot in _drawableLots)
143 | {
144 | lot.FindVertices();
145 | lot.FindTriangles();
146 | lot.Draw();
147 | lot.gameObject.SetActive(true);
148 | }
149 | }
150 |
151 | public void DestroyLots ()
152 | {
153 | foreach (BuildingLot lot in _drawableLots)
154 | lot.Destroy();
155 | }
156 |
157 | public void Clear ()
158 | {
159 | _blocks.Clear();
160 | _lots.Clear();
161 | _nodes.Clear();
162 | DestroyRoads();
163 | _roads.Clear();
164 | DestroySidewalks();
165 | _sidewalks.Clear();
166 | DestroyLots();
167 | _drawableLots.Clear();
168 | }
169 | }
170 |
171 | } // namespace Thesis
--------------------------------------------------------------------------------
/Assets/Standard Assets/Balcony/Balcony.cs:
--------------------------------------------------------------------------------
1 | using UnityEngine;
2 |
3 | namespace Thesis {
4 |
5 | public class Balcony : FaceComponent
6 | {
7 | /*************** FIELDS ***************/
8 |
9 | public BalconyFloor balconyFloor;
10 |
11 | public BalconyRail balconyRail;
12 |
13 | public Shutter rightShutter;
14 |
15 | public Shutter leftShutter;
16 |
17 | public ComponentDecor decor;
18 |
19 | public Building masterParent
20 | {
21 | get { return parentBuilding.parent; }
22 | }
23 |
24 | /*************** CONSTRUCTORS ***************/
25 |
26 | public Balcony (Face parent, Vector3 dr, Vector3 dl, ComponentCoordinate position)
27 | : base(parent, position)
28 | {
29 | height = parentBuilding.balconyHeight;
30 | width = (dr - dl).magnitude;
31 | depth = 0.2f;
32 |
33 | if (masterParent.balconyWidth > 0f)
34 | {
35 | var mod = (masterParent.balconyWidth - width) / 2f;
36 | width = masterParent.balconyWidth;
37 | dr += mod * parentFace.right;
38 | dl -= mod * parentFace.right;
39 | }
40 |
41 | boundaries = new Vector3[4];
42 | boundaries[0] = dr;
43 | boundaries[1] = dl;
44 | boundaries[2] = new Vector3(dl.x, dl.y + height, dl.z);
45 | boundaries[3] = new Vector3(dr.x, dr.y + height, dr.z);
46 |
47 | frame = new BalconyFrame(this);
48 | frame.name = "neo_balcony_frame";
49 | frame.material = MaterialManager.Instance.Get("ComponentFrame");
50 | parentBuilding.parent.AddCombinable(frame.material.name, frame);
51 |
52 | body = new BalconyBody(this);
53 | body.name = "neo_balcony_body";
54 | body.material = parentBuilding.parent.balconyDoorMaterial;
55 | parentBuilding.parent.AddCombinable(body.material.name, body);
56 |
57 | balconyFloor = new BalconyFloor(this);
58 | balconyFloor.name = "neo_balcony_floor";
59 | balconyFloor.material = parentBuilding.material;
60 | parentBuilding.parent.AddCombinable(balconyFloor.material.name, balconyFloor);
61 |
62 | balconyRail = new BalconyRail(balconyFloor);
63 | balconyRail.name = "neo_balcony_rail";
64 | balconyRail.material = MaterialManager.Instance.Get("mat_balcony_rail");
65 | parentBuilding.parent.AddCombinable(balconyRail.material.name, balconyRail);
66 |
67 | rightShutter = new Shutter(this, ShutterSide.Right);
68 | rightShutter.name = "bal_right_shutter";
69 | rightShutter.material = parentBuilding.parent.shutterMaterial;
70 | parentBuilding.parent.AddCombinable(rightShutter.material.name, rightShutter);
71 |
72 | leftShutter = new Shutter(this, ShutterSide.Left);
73 | leftShutter.name = "bal_left_shutter";
74 | leftShutter.material = parentBuilding.parent.shutterMaterial;
75 | parentBuilding.parent.AddCombinable(leftShutter.material.name, leftShutter);
76 |
77 | if (position.floor >= 1)
78 | {
79 | decor = new ComponentDecor(this);
80 | decor.name = "window_decor";
81 | decor.material = parentBuilding.parent.compDecorMaterial;
82 | parentBuilding.parent.AddCombinable(decor.material.name, decor);
83 | }
84 | else
85 | {
86 | decor = new ComponentDecor(this, true);
87 | decor.name = "window_decor";
88 | decor.material = parentBuilding.parent.simpleCompDecorMaterial;
89 | parentBuilding.parent.AddCombinable(decor.material.name, decor);
90 | }
91 | }
92 |
93 | /*************** METHODS ***************/
94 |
95 | public override void Draw ()
96 | {
97 | //base.Draw();
98 |
99 | body.FindVertices();
100 | body.FindTriangles();
101 | body.Draw();
102 |
103 | frame.FindVertices();
104 | frame.FindTriangles();
105 | frame.Draw();
106 |
107 | balconyFloor.FindVertices();
108 | balconyFloor.FindTriangles();
109 | balconyFloor.Draw();
110 |
111 | balconyRail.FindVertices();
112 | balconyRail.FindTriangles();
113 | balconyRail.Draw();
114 |
115 | //Shutter.SetAngles();
116 |
117 | rightShutter.FindVertices();
118 | rightShutter.FindTriangles();
119 | rightShutter.Draw();
120 |
121 | leftShutter.FindVertices();
122 | leftShutter.FindTriangles();
123 | leftShutter.Draw();
124 |
125 | if (decor != null)
126 | {
127 | decor.FindVertices();
128 | decor.FindTriangles();
129 | decor.Draw();
130 | }
131 | }
132 |
133 | public override void Destroy()
134 | {
135 | base.Destroy();
136 |
137 | balconyFloor.Destroy();
138 | balconyRail.Destroy();
139 | rightShutter.Destroy();
140 | leftShutter.Destroy();
141 |
142 | if (decor != null)
143 | decor.Destroy();
144 | }
145 | }
146 |
147 | } // namespace Thesis
--------------------------------------------------------------------------------
/Assets/Standard Assets/Managers/BuildingManager.cs:
--------------------------------------------------------------------------------
1 | using UnityEngine;
2 | using System.Collections.Generic;
3 |
4 | namespace Thesis {
5 |
6 | public sealed class BuildingManager
7 | {
8 | private static readonly BuildingManager _instance = new BuildingManager();
9 | public static BuildingManager Instance
10 | {
11 | get { return _instance; }
12 | }
13 |
14 | private List _buildings;
15 | public IList buildings
16 | {
17 | get { return _buildings.AsReadOnly(); }
18 | }
19 |
20 | private BuildingManager ()
21 | {
22 | _buildings = new List();
23 | }
24 |
25 | public void Init () { }
26 |
27 | public void CreateNeoclassical (BuildMode mode)
28 | {
29 | switch (mode)
30 | {
31 | case BuildMode.Many:
32 | for (int i = 0; i < 25; ++i)
33 | {
34 | float x_mod = i * 30f;
35 | for (int j = 0; j < 25; ++j)
36 | {
37 | float z_mod = j * 15f;
38 | int dice = Util.RollDice(new float[] { 0.25f, 0.25f, 0.25f, 0.25f });
39 | switch (dice)
40 | {
41 | case 1:
42 | Build(new Vector3(x_mod + 9f, 0f, z_mod + 3.5f),
43 | new Vector3(x_mod + 9f, 0f, z_mod),
44 | new Vector3(x_mod, 0f, z_mod),
45 | new Vector3(x_mod, 0f, z_mod + 3.5f));
46 | break;
47 |
48 | case 2:
49 | Build(new Vector3(x_mod + 11f, 0f, z_mod + 4f),
50 | new Vector3(x_mod + 11f, 0f, z_mod),
51 | new Vector3(x_mod, 0f, z_mod),
52 | new Vector3(x_mod, 0f, z_mod + 4f));
53 | break;
54 |
55 | case 3:
56 | Build(new Vector3(x_mod + 15f, 0f, z_mod + 6f),
57 | new Vector3(x_mod + 15f, 0f, z_mod),
58 | new Vector3(x_mod, 0f, z_mod),
59 | new Vector3(x_mod, 0f, z_mod + 6f));
60 | break;
61 |
62 | case 4:
63 | Build(new Vector3(x_mod + 19f, 0f, z_mod + 8f),
64 | new Vector3(x_mod + 19f, 0f, z_mod),
65 | new Vector3(x_mod, 0f, z_mod),
66 | new Vector3(x_mod, 0f, z_mod + 8f));
67 | break;
68 | }
69 | }
70 | }
71 | break;
72 |
73 | case BuildMode.Two:
74 | Build(new Vector3(8f, 0f, 4f),
75 | new Vector3(8f, 0f, 0f),
76 | new Vector3(0f, 0f, 0f),
77 | new Vector3(0f, 0f, 4f));
78 | break;
79 |
80 | case BuildMode.Three:
81 | Build(new Vector3(11f, 0f, 4f),
82 | new Vector3(11f, 0f, 0f),
83 | new Vector3(0f, 0f, 0f),
84 | new Vector3(0f, 0f, 4f));
85 |
86 | //Build(new Vector3(20f, 0f, 4f),
87 | // new Vector3(37f, 0f, 4f),
88 | // new Vector3(37f, 0f, 0f),
89 | // new Vector3(20f, 0f, 0f));
90 | break;
91 |
92 | case BuildMode.Four:
93 | Build(new Vector3(15f, 0f, 6f),
94 | new Vector3(15f, 0f, 0f),
95 | new Vector3(0f, 0f, 0f),
96 | new Vector3(0f, 0f, 6f));
97 | break;
98 |
99 | case BuildMode.Five:
100 | Build(new Vector3(19f, 0f, 8f),
101 | new Vector3(19f, 0f, 0f),
102 | new Vector3(0f, 0f, 0f),
103 | new Vector3(0f, 0f, 8f));
104 | break;
105 | }
106 | }
107 |
108 | public void DestroyBuildings ()
109 | {
110 | foreach (Building n in _buildings)
111 | n.Destroy();
112 | _buildings.Clear();
113 | }
114 |
115 | public void Build (Vector3 p1, Vector3 p2, Vector3 p3, Vector3 p4)
116 | {
117 | var n = new Building(p1, p2, p3, p4);
118 | n.buildingMesh.FindVertices();
119 | n.buildingMesh.FindTriangles();
120 | n.buildingMesh.Draw();
121 | n.CombineSubmeshes();
122 | n.gameObject.SetActive(true);
123 | foreach (Transform t in n.gameObject.transform) {
124 | t.gameObject.SetActive(true);
125 | }
126 | _buildings.Add(n);
127 | }
128 |
129 | public void Build (BuildingLot lot)
130 | {
131 | var n = new Building(lot);
132 | n.buildingMesh.FindVertices();
133 | n.buildingMesh.FindTriangles();
134 | n.buildingMesh.Draw();
135 | n.CombineSubmeshes();
136 | n.gameObject.SetActive(true);
137 | foreach (Transform t in n.gameObject.transform) {
138 | t.gameObject.SetActive(true);
139 | }
140 | _buildings.Add(n);
141 | }
142 | }
143 |
144 | } // namespace Thesis
--------------------------------------------------------------------------------
/Assets/Standard Assets/Balcony/BalconyRail.cs:
--------------------------------------------------------------------------------
1 | using UnityEngine;
2 |
3 | namespace Thesis {
4 |
5 | public class BalconyRail : DrawableObject
6 | {
7 | /*************** FIELDS ***************/
8 |
9 | public readonly BalconyFloor parentFloor;
10 |
11 | public BuildingMesh parentBuilding
12 | {
13 | get { return parentFloor.parentBuilding; }
14 | }
15 |
16 | public Face parentFace
17 | {
18 | get { return parentFloor.parentBalcony.parentFace; }
19 | }
20 |
21 | public BalconyRail (BalconyFloor parent)
22 | : base("balcony_rail")
23 | {
24 | parentFloor = parent;
25 |
26 | var height = 1f;
27 | boundaries = new Vector3[8];
28 |
29 | boundaries[0] = parentFloor.boundaries[4];
30 | boundaries[1] = parentFloor.boundaries[5];
31 | boundaries[2] = boundaries[1] - parentFloor.depth * parentFace.normal;
32 | boundaries[3] = boundaries[0] - parentFloor.depth * parentFace.normal;
33 |
34 | for (var i = 0; i < 4; ++i)
35 | boundaries[i + 4] = boundaries[i] + height * Vector3.up;
36 |
37 | FindMeshOrigin(boundaries[0],
38 | boundaries[6],
39 | boundaries[2],
40 | boundaries[4]);
41 |
42 | for (var i = 0; i < boundaries.Length; ++i)
43 | boundaries[i] -= meshOrigin;
44 | }
45 |
46 | public override void FindVertices ()
47 | {
48 | // make length * 4 for inside sides of rails
49 | vertices = new Vector3[boundaries.Length * 2];
50 | for (int i = 0; i < 2; ++i)
51 | System.Array.Copy(boundaries, 0, vertices, i * boundaries.Length, boundaries.Length);
52 | }
53 |
54 | public override void FindTriangles ()
55 | {
56 | triangles = new int[18];
57 |
58 | // from outside
59 |
60 | // front
61 | triangles[0] = 0;
62 | triangles[1] = 1;
63 | triangles[2] = 4;
64 |
65 | triangles[3] = 1;
66 | triangles[4] = 5;
67 | triangles[5] = 4;
68 |
69 | //// left
70 | //triangles[6] = 1;
71 | //triangles[7] = 2;
72 | //triangles[8] = 5;
73 |
74 | //triangles[9] = 2;
75 | //triangles[10] = 6;
76 | //triangles[11] = 5;
77 |
78 | //// right
79 | //triangles[12] = 0;
80 | //triangles[13] = 4;
81 | //triangles[14] = 3;
82 |
83 | //triangles[15] = 3;
84 | //triangles[16] = 4;
85 | //triangles[17] = 7;
86 |
87 | // left
88 | triangles[6] = 9; // 1 + 8
89 | triangles[7] = 10; // 2 + 8
90 | triangles[8] = 13; // 5 + 8
91 |
92 | triangles[9] = 10; // 2 + 8
93 | triangles[10] = 14; // 6 + 8
94 | triangles[11] = 13; // 5 + 8
95 |
96 | // right
97 | triangles[12] = 8; // 0 + 8
98 | triangles[13] = 12; // 4 + 8
99 | triangles[14] = 11; // 3 + 8
100 |
101 | triangles[15] = 11; // 3 + 8
102 | triangles[16] = 12; // 4 + 8
103 | triangles[17] = 15; // 7 + 8
104 |
105 | // from inside are the previous tris in reverse order
106 |
107 | //var index = 18;
108 | //for (var i = 17; i >= 0; --i)
109 | // triangles[index++] = triangles[i] + 16;
110 | }
111 |
112 | public override void Draw ()
113 | {
114 | base.Draw();
115 |
116 | var uvs = new Vector2[mesh.vertices.Length];
117 | uvs[2 + 8] = new Vector2(.5f, 0f);
118 | uvs[6 + 8] = new Vector2(.5f, 1f);
119 | uvs[1 + 8] = new Vector2(1f, 0f);
120 | uvs[5 + 8] = new Vector2(1f, 1f);
121 |
122 | uvs[1] = new Vector2(0f, 0f);
123 | uvs[5] = new Vector2(0f, 1f);
124 | uvs[0] = new Vector2(1f, 0f);
125 | uvs[4] = new Vector2(1f, 1f);
126 |
127 | uvs[0 + 8] = new Vector2(1f, 0f);
128 | uvs[4 + 8] = new Vector2(1f, 1f);
129 | uvs[3 + 8] = new Vector2(.5f, 0f);
130 | uvs[7 + 8] = new Vector2(.5f, 1f);
131 |
132 | mesh.uv = uvs;
133 |
134 | gameObject.transform.position = meshOrigin + parentBuilding.meshOrigin + parentFloor.meshOrigin;
135 | gameObject.transform.parent = parentBuilding.parent.gameObject.transform;
136 | }
137 |
138 | private Texture2D CreateTexture ()
139 | {
140 | var tex = new Texture2D(256, 128);
141 | int y = -1;
142 | int x = -1;
143 |
144 | var thickness = 5;
145 |
146 | do
147 | {
148 | x = 0;
149 | do
150 | {
151 | tex.SetPixel(x, y, Color.black);
152 | //Debug.Log(y);
153 | } while (x++ < tex.width);
154 | } while (y++ < thickness - 1);
155 |
156 | do
157 | {
158 | x = 0;
159 | do
160 | {
161 | if ((x & y) == 0)
162 | tex.SetPixel(x, y, Color.black);
163 | else
164 | tex.SetPixel(x, y, Color.clear);
165 | } while (x++ < tex.width);
166 | } while (y++ < tex.height - thickness);
167 |
168 | do
169 | {
170 | x = 0;
171 | do
172 | {
173 | tex.SetPixel(x, y, Color.black);
174 | Debug.Log(y);
175 | } while (x++ < tex.width);
176 | } while (y++ < tex.height);
177 |
178 | tex.Apply();
179 |
180 | return tex;
181 | }
182 | }
183 |
184 | } // namespace Thesis
--------------------------------------------------------------------------------
/Assets/Scripts/CameraController.cs:
--------------------------------------------------------------------------------
1 | using UnityEngine;
2 | using Thesis;
3 |
4 | public class CameraController : MonoBehaviour {
5 |
6 | private enum CameraMode
7 | {
8 | Horizontal,
9 | Free
10 | }
11 |
12 | [SerializeField]
13 | private CameraMode _cameraMode = CameraMode.Horizontal;
14 |
15 | [SerializeField]
16 | private float _movementSpeed = 10f;
17 |
18 | [SerializeField]
19 | private float _rotationSpeed = 5f;
20 |
21 | private float _x_rotation;
22 | private float _y_rotation;
23 |
24 | private float _last_mouse_x;
25 | private float _last_mouse_y;
26 | private float _mouse_x;
27 | private float _mouse_y;
28 | private bool _follow_mouse = true;
29 |
30 | void Awake ()
31 | {
32 | ColorManager.Instance.Init();
33 | TextureManager.Instance.Init();
34 | MaterialManager.Instance.Init();
35 | BuildingManager.Instance.Init();
36 | }
37 |
38 | void Start ()
39 | {
40 | Screen.showCursor = false;
41 |
42 | _x_rotation = camera.transform.rotation.eulerAngles.x;
43 | _y_rotation = camera.transform.rotation.eulerAngles.y;
44 |
45 | _last_mouse_x = Input.GetAxis("Mouse X");
46 | _last_mouse_y = -Input.GetAxis("Mouse Y");
47 | _mouse_x = _last_mouse_x;
48 | _mouse_y = _last_mouse_y;
49 | }
50 |
51 | void Update ()
52 | {
53 | if (_follow_mouse)
54 | {
55 | _mouse_x = Input.GetAxis("Mouse X");
56 | _mouse_y = -Input.GetAxis("Mouse Y");
57 | _y_rotation += Mathf.Lerp(_last_mouse_x * _rotationSpeed, _mouse_x * _rotationSpeed, Time.smoothDeltaTime);
58 | _x_rotation += Mathf.Lerp(_last_mouse_y * _rotationSpeed, _mouse_y * _rotationSpeed, Time.smoothDeltaTime);
59 | _last_mouse_x = _mouse_x;
60 | _last_mouse_y = _mouse_y;
61 | }
62 |
63 | ClampCamera();
64 | camera.transform.eulerAngles = new Vector3(_x_rotation, _y_rotation, 0f);
65 |
66 | float moveSpeed = _movementSpeed;
67 | if (Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift))
68 | moveSpeed = 2 * _movementSpeed;
69 |
70 | if (Input.GetAxis("Vertical") != 0f)
71 | {
72 | if (_cameraMode == CameraMode.Horizontal)
73 | camera.transform.position += Vector3.Cross(camera.transform.right, Vector3.up) *
74 | Input.GetAxis("Vertical") *
75 | moveSpeed * Time.deltaTime;
76 | else
77 | camera.transform.position += camera.transform.forward *
78 | Input.GetAxis("Vertical") *
79 | moveSpeed * Time.deltaTime;
80 | }
81 |
82 | if (Input.GetAxis("Horizontal") != 0f)
83 | camera.transform.position += camera.transform.right *
84 | Input.GetAxis("Horizontal") *
85 | moveSpeed * Time.deltaTime;
86 |
87 | if (Input.GetKey(KeyCode.E))
88 | camera.transform.position += Vector3.up * moveSpeed * Time.deltaTime;
89 |
90 | if (Input.GetKey(KeyCode.C))
91 | camera.transform.position -= Vector3.up * moveSpeed * Time.deltaTime;
92 |
93 | if (Input.GetKeyUp(KeyCode.M))
94 | if (_cameraMode == CameraMode.Free)
95 | _cameraMode = CameraMode.Horizontal;
96 | else
97 | _cameraMode = CameraMode.Free;
98 |
99 | if (Input.GetMouseButtonUp(1))
100 | if (_follow_mouse)
101 | {
102 | _follow_mouse = false;
103 | Screen.showCursor = true;
104 | }
105 | else
106 | {
107 | _follow_mouse = true;
108 | Screen.showCursor = false;
109 | }
110 |
111 | if (Input.GetKey(KeyCode.Escape))
112 | Application.Quit();
113 |
114 | if (Input.GetKey(KeyCode.F1))
115 | Application.LoadLevel("main_scene");
116 |
117 | if (Input.GetKey(KeyCode.F2))
118 | Application.LoadLevel("city_scene");
119 | }
120 |
121 | public void OnGUI ()
122 | {
123 | GUILayout.Label("Camera controls:");
124 | GUILayout.Label("W - Forward");
125 | GUILayout.Label("S - Backward");
126 | GUILayout.Label("D - Right");
127 | GUILayout.Label("A - Left");
128 | GUILayout.Label("E - Up");
129 | GUILayout.Label("C - Down");
130 | GUILayout.Label("M - Change camera mode");
131 | GUILayout.Label("Shift - Speed boost");
132 |
133 | //#if UNITY_EDITOR
134 | // GUILayout.Label("All " + FindObjectsOfType(typeof(UnityEngine.Object)).Length);
135 | // GUILayout.Label("AudioClips " + FindObjectsOfType(typeof(AudioClip)).Length);
136 | // GUILayout.Label("Materials " + FindObjectsOfType(typeof(Material)).Length);
137 | // GUILayout.Label("Components " + FindObjectsOfType(typeof(Component)).Length);
138 | // GUILayout.Label("Textures " + FindObjectsOfType(typeof(Texture)).Length);
139 | // GUILayout.Label("Meshes " + FindObjectsOfType(typeof(Mesh)).Length);
140 | // GUILayout.Label("GameObjects " + FindObjectsOfType(typeof(GameObject)).Length);
141 | //#endif
142 | }
143 |
144 | private void ClampCamera (float horizontal = 360f, float vertical = 80f)
145 | {
146 | if (_y_rotation < -horizontal) _y_rotation += horizontal;
147 | if (_y_rotation > horizontal) _y_rotation -= horizontal;
148 |
149 | if (_x_rotation > vertical) _x_rotation = vertical;
150 | if (_x_rotation < -vertical) _x_rotation = -vertical;
151 | }
152 |
153 | void OnDestroy ()
154 | {
155 | BuildingManager.Instance.DestroyBuildings();
156 | }
157 | }
158 |
--------------------------------------------------------------------------------
/Assets/Standard Assets/Roof/DoublePeakRoof.cs:
--------------------------------------------------------------------------------
1 | using UnityEngine;
2 |
3 | namespace Thesis {
4 |
5 | public class DoublePeakRoof : Roof
6 | {
7 | private enum _Type { four, five }
8 | private _Type _type;
9 | private float _widthBig;
10 | private float _widthSmall;
11 | private float _heightBig;
12 | private float _heightSmall;
13 |
14 | public DoublePeakRoof (BuildingMesh parent)
15 | : base(parent)
16 | {
17 | width = 0.2f;
18 | boundaries = new Vector3[6];
19 |
20 | for (int i = 0; i < 4; ++i)
21 | boundaries[i] = parentMesh.roofBase.boundaries[i + 4]+
22 | width * parentMesh.faces[i].normal +
23 | width * parentMesh.faces[(i + 3) % 4].normal;
24 |
25 | FindMeshOrigin(boundaries[0], boundaries[2],
26 | boundaries[1], boundaries[3]);
27 |
28 | int index = Mathf.Max(parentMesh.sortedFaces[2], parentMesh.sortedFaces[3]);
29 | Face face = parentMesh.faces[index];
30 | height = 0.2f * face.width;
31 | var bi0 = (parentMesh.faces[(index + 3) % 4].right - face.right).normalized;
32 | var bi1 = (face.right - parentMesh.faces[(index + 1) % 4].right).normalized;
33 | var p = Util.IntersectionPoint(face.boundaries[0], bi0, face.boundaries[1], bi1);
34 |
35 | boundaries[4] = new Vector3(p.x,
36 | boundaries[0].y + height,
37 | p.z);
38 |
39 | index = Mathf.Min(parentMesh.sortedFaces[2], parentMesh.sortedFaces[3]);
40 | face = parentMesh.faces[index];
41 | bi0 = (parentMesh.faces[(index + 3) % 4].right - face.right).normalized;
42 | bi1 = (face.right - parentMesh.faces[(index + 1) % 4].right).normalized;
43 | p = Util.IntersectionPoint(face.boundaries[0], bi0, face.boundaries[1], bi1);
44 |
45 | boundaries[5] = new Vector3(p.x,
46 | boundaries[0].y + height,
47 | p.z);
48 |
49 | if ((boundaries[0] - boundaries[4]).magnitude <
50 | (boundaries[0] - boundaries[5]).magnitude)
51 | {
52 | _type = _Type.four;
53 | _widthBig = (boundaries[0] - boundaries[1]).magnitude;
54 | _widthSmall = (boundaries[1] - boundaries[2]).magnitude;
55 | _heightSmall = ((boundaries[1] + boundaries[2]) / 2 - boundaries[5]).magnitude;
56 | }
57 | else
58 | {
59 | _type = _Type.five;
60 | _widthBig = (boundaries[1] - boundaries[2]).magnitude;
61 | _widthSmall = (boundaries[1] - boundaries[0]).magnitude;
62 | _heightSmall = ((boundaries[1] + boundaries[0]) / 2 - boundaries[5]).magnitude;
63 | }
64 |
65 | _heightBig = Mathf.Sqrt(Mathf.Pow(_widthSmall / 2, 2) +
66 | Mathf.Pow(height, 2));
67 | }
68 |
69 | public override void FindVertices()
70 | {
71 | vertices = new Vector3[boundaries.Length * 4];
72 | for (int i = 0; i < 4; ++i)
73 | System.Array.Copy(boundaries, 0, vertices, i * boundaries.Length, boundaries.Length);
74 | }
75 |
76 | public override void FindTriangles()
77 | {
78 | triangles = new int[24];
79 | int i = 0;
80 |
81 | if (_type == _Type.five)
82 | {
83 | triangles[i++] = 0;
84 | triangles[i++] = 1;
85 | triangles[i++] = 5;
86 |
87 | triangles[i++] = 2;
88 | triangles[i++] = 3;
89 | triangles[i++] = 4;
90 |
91 | // +6
92 | triangles[i++] = 7;
93 | triangles[i++] = 8;
94 | triangles[i++] = 11;
95 |
96 | triangles[i++] = 8;
97 | triangles[i++] = 10;
98 | triangles[i++] = 11;
99 |
100 | // +12
101 | triangles[i++] = 12;
102 | triangles[i++] = 17;
103 | triangles[i++] = 16;
104 |
105 | triangles[i++] = 12;
106 | triangles[i++] = 16;
107 | triangles[i++] = 15;
108 | }
109 | else
110 | {
111 | triangles[i++] = 1;
112 | triangles[i++] = 2;
113 | triangles[i++] = 5;
114 |
115 | triangles[i++] = 0;
116 | triangles[i++] = 4;
117 | triangles[i++] = 3;
118 |
119 | // +6
120 | triangles[i++] = 6;
121 | triangles[i++] = 7;
122 | triangles[i++] = 11;
123 |
124 | triangles[i++] = 6;
125 | triangles[i++] = 11;
126 | triangles[i++] = 10;
127 |
128 | // +12
129 | triangles[i++] = 14;
130 | triangles[i++] = 15;
131 | triangles[i++] = 16;
132 |
133 | triangles[i++] = 14;
134 | triangles[i++] = 16;
135 | triangles[i++] = 17;
136 | }
137 |
138 | // +18
139 | triangles[i++] = 18;
140 | triangles[i++] = 21;
141 | triangles[i++] = 20;
142 |
143 | triangles[i++] = 18;
144 | triangles[i++] = 20;
145 | triangles[i++] = 19;
146 | }
147 |
148 | public override void Draw()
149 | {
150 | base.Draw();
151 |
152 | var uvs = new Vector2[mesh.vertices.Length];
153 |
154 | float _wdiv = material.mainTexture.width / 128f;
155 | float _hdiv = material.mainTexture.height / 128f;
156 | float htimes = _widthSmall / _wdiv;
157 | float vtimes = _heightSmall / _hdiv;
158 |
159 | uvs[1] = new Vector2(0f, 0f);
160 | uvs[0] = new Vector2(htimes, 0f);
161 | uvs[5] = new Vector2(htimes / 2, vtimes);
162 |
163 | uvs[3] = new Vector2(0f, 0f);
164 | uvs[2] = new Vector2(htimes, 0f);
165 | uvs[4] = new Vector2(htimes / 2, vtimes);
166 |
167 | htimes = _widthBig / _wdiv;
168 | vtimes = _heightBig / _hdiv;
169 | var _dist45 = (boundaries[4] - boundaries[5]).magnitude;
170 | var tmp = ((_widthBig - _dist45) / 2) / _wdiv;
171 | uvs[8] = new Vector2(0f, 0f);
172 | uvs[7] = new Vector2(htimes, 0f);
173 | uvs[10] = new Vector2(tmp, vtimes);
174 | uvs[11] = new Vector2(htimes - tmp, vtimes);
175 |
176 | uvs[12] = new Vector2(0f, 0f);
177 | uvs[15] = new Vector2(htimes, 0f);
178 | uvs[17] = new Vector2(tmp, vtimes);
179 | uvs[16] = new Vector2(htimes - tmp, vtimes);
180 |
181 | mesh.uv = uvs;
182 | }
183 | }
184 |
185 | } // namespace Thesis
--------------------------------------------------------------------------------
/Assets/Standard Assets/Shutter/Shuter.cs:
--------------------------------------------------------------------------------
1 | using UnityEngine;
2 |
3 | namespace Thesis {
4 |
5 | public class Shutter : DrawableObject
6 | {
7 | public readonly FaceComponent parent;
8 |
9 | public readonly ShutterSide side;
10 |
11 | static private int angles;
12 |
13 | public BuildingMesh parentBuilding
14 | {
15 | get { return parent.parentBuilding; }
16 | }
17 |
18 | /*************** CONSTRUCTORS ***************/
19 |
20 | public Shutter (FaceComponent parent, ShutterSide side)
21 | {
22 | this.parent = parent;
23 | this.side = side;
24 | angles = 0;
25 | boundaries = new Vector3[8];
26 |
27 | if (side == ShutterSide.Right)
28 | {
29 | boundaries[0] = Vector3.zero;
30 | boundaries[1] = - parent.parentFace.right * (parent.width / 2);
31 | boundaries[2] = boundaries[1] + Vector3.up * parent.height;
32 | boundaries[3] = Vector3.up * parent.height;
33 |
34 | meshOrigin = parent.boundaries[0];
35 | }
36 | else
37 | {
38 | boundaries[0] = parent.parentFace.right * (parent.width / 2);
39 | boundaries[1] = Vector3.zero;
40 | boundaries[2] = Vector3.up * parent.height;
41 | boundaries[3] = boundaries[0] + boundaries[2];
42 |
43 | meshOrigin = parent.boundaries[1];
44 | }
45 |
46 | for (var i = 0; i < 4; ++i)
47 | boundaries[i + 4] = boundaries[i] - parent.normal * parent.depth / 2;
48 | }
49 |
50 | public override void FindVertices()
51 | {
52 | vertices = new Vector3[boundaries.Length * 3];
53 | for (int i = 0; i < 3; ++i)
54 | System.Array.Copy(boundaries, 0, vertices, i * boundaries.Length, boundaries.Length);
55 | }
56 |
57 | public override void FindTriangles()
58 | {
59 | triangles = new int[36];
60 | int i = 0;
61 |
62 | // front
63 | triangles[i++] = 0;
64 | triangles[i++] = 1;
65 | triangles[i++] = 3;
66 |
67 | triangles[i++] = 1;
68 | triangles[i++] = 2;
69 | triangles[i++] = 3;
70 |
71 | // back
72 | triangles[i++] = 4;
73 | triangles[i++] = 7;
74 | triangles[i++] = 5;
75 |
76 | triangles[i++] = 5;
77 | triangles[i++] = 7;
78 | triangles[i++] = 6;
79 |
80 | // right (+8)
81 | triangles[i++] = 8;
82 | triangles[i++] = 11;
83 | triangles[i++] = 15;
84 |
85 | triangles[i++] = 8;
86 | triangles[i++] = 15;
87 | triangles[i++] = 12;
88 |
89 | // left (+8)
90 | triangles[i++] = 9;
91 | triangles[i++] = 13;
92 | triangles[i++] = 10;
93 |
94 | triangles[i++] = 13;
95 | triangles[i++] = 14;
96 | triangles[i++] = 10;
97 |
98 | // bottom (+16)
99 | triangles[i++] = 16;
100 | triangles[i++] = 20;
101 | triangles[i++] = 17;
102 |
103 | triangles[i++] = 17;
104 | triangles[i++] = 20;
105 | triangles[i++] = 21;
106 |
107 | // top (+16)
108 | triangles[i++] = 18;
109 | triangles[i++] = 22;
110 | triangles[i++] = 23;
111 |
112 | triangles[i++] = 18;
113 | triangles[i++] = 23;
114 | triangles[i++] = 19;
115 | }
116 |
117 | public override void Draw()
118 | {
119 | base.Draw();
120 | AssignUVs();
121 |
122 | if (side == ShutterSide.Right)
123 | gameObject.transform.RotateAround(meshOrigin, Vector3.up, -angles);
124 | else
125 | gameObject.transform.RotateAround(meshOrigin, Vector3.up, angles);
126 |
127 | gameObject.transform.position = meshOrigin + parent.meshOrigin +
128 | parentBuilding.meshOrigin - parent.normal * 0.15f;
129 | gameObject.transform.parent = parentBuilding.parent.gameObject.transform;
130 | }
131 |
132 | private void AssignUVs ()
133 | {
134 | var uvs = new Vector2[mesh.vertices.Length];
135 |
136 | if (parent.GetType().IsSubclassOf(typeof(Window)) &&
137 | side == ShutterSide.Left)
138 | {
139 | uvs[0] = new Vector2(.5f, .5f);
140 | uvs[1] = new Vector2( 0, .5f);
141 | uvs[2] = new Vector2( 0, 1);
142 | uvs[3] = new Vector2(.5f, 1);
143 | uvs[4] = new Vector2(.5f, .5f);
144 | uvs[5] = new Vector2( 0, .5f);
145 | uvs[6] = new Vector2( 0, 1);
146 | uvs[7] = new Vector2(.5f, 1);
147 | }
148 | else if (parent.GetType().IsSubclassOf(typeof(Window)) &&
149 | side == ShutterSide.Right)
150 | {
151 | uvs[0] = new Vector2( 0, .5f);
152 | uvs[1] = new Vector2(.5f, .5f);
153 | uvs[2] = new Vector2(.5f, 1);
154 | uvs[3] = new Vector2( 0, 1);
155 | uvs[4] = new Vector2( 0, .5f);
156 | uvs[5] = new Vector2(.5f, .5f);
157 | uvs[6] = new Vector2(.5f, 1);
158 | uvs[7] = new Vector2( 0, 1);
159 | }
160 | else if (parent.GetType().IsSubclassOf(typeof(Balcony)) &&
161 | side == ShutterSide.Left)
162 | {
163 | uvs[0] = new Vector2( 1, 0);
164 | uvs[1] = new Vector2(.5f, 0);
165 | uvs[2] = new Vector2(.5f, 1);
166 | uvs[3] = new Vector2( 1, 1);
167 | uvs[4] = new Vector2( 1, 0);
168 | uvs[5] = new Vector2(.5f, 0);
169 | uvs[6] = new Vector2(.5f, 1);
170 | uvs[7] = new Vector2( 1, 1);
171 | }
172 | else
173 | {
174 | uvs[0] = new Vector2(.5f, 0);
175 | uvs[1] = new Vector2( 1, 0);
176 | uvs[2] = new Vector2( 1, 1);
177 | uvs[3] = new Vector2(.5f, 1);
178 | uvs[4] = new Vector2(.5f, 0);
179 | uvs[5] = new Vector2( 1, 0);
180 | uvs[6] = new Vector2( 1, 1);
181 | uvs[7] = new Vector2(.5f, 1);
182 | }
183 |
184 | mesh.uv = uvs;
185 | }
186 |
187 | public static void SetAngles ()
188 | {
189 | switch (Util.RollDice(new float[] {0.33f, 0.33f, 0.34f}))
190 | {
191 | case 1:
192 | angles = 150;
193 | break;
194 |
195 | case 2:
196 | angles = Random.Range(130, 150);
197 | break;
198 |
199 | case 3:
200 | angles = 0;
201 | break;
202 | }
203 | }
204 | }
205 |
206 | } // Thesis
--------------------------------------------------------------------------------
/Assets/Standard Assets/Window/WindowDecor.cs:
--------------------------------------------------------------------------------
1 | using UnityEngine;
2 |
3 | namespace Thesis {
4 |
5 | public class ComponentDecor : DrawableObject
6 | {
7 | public readonly FaceComponent parentComponent;
8 |
9 | public float width;
10 |
11 | public Building allParent
12 | {
13 | get { return parentComponent.parentBuilding.parent; }
14 | }
15 |
16 | private readonly bool _parentIsWindow;
17 | private readonly bool _isSimple;
18 |
19 | public ComponentDecor (FaceComponent parent, bool isSimple = false)
20 | {
21 | parentComponent = parent;
22 | _isSimple = isSimple;
23 | _parentIsWindow = parent.GetType().Equals(typeof(Window)) ? true : false;
24 |
25 | if (_isSimple)
26 | initSimpleDecor();
27 | else
28 | initDecor();
29 | }
30 |
31 | private void initDecor ()
32 | {
33 | boundaries = new Vector3[16];
34 |
35 | for (int i = 0; i < 4; ++i)
36 | boundaries[i] = parentComponent.boundaries[i] +
37 | 0.01f * parentComponent.parentFace.normal;
38 |
39 | width = 0.3f;
40 | var dist = width * parentComponent.parentFace.right;
41 |
42 | boundaries[4] = boundaries[0] + dist;
43 | boundaries[5] = boundaries[1] - dist;
44 | boundaries[6] = boundaries[2] - dist;
45 | boundaries[7] = boundaries[3] + dist;
46 |
47 | boundaries[8] = boundaries[2] - 2 * dist;
48 | boundaries[9] = boundaries[8] + 2 * width * Vector3.up;
49 | boundaries[11] = boundaries[3] + 2 * dist;
50 | boundaries[10] = boundaries[11] + 2 * width * Vector3.up;
51 |
52 | boundaries[12] = boundaries[5] - 4 * width * Vector3.up;
53 | boundaries[13] = boundaries[5];
54 | boundaries[14] = boundaries[4];
55 | boundaries[15] = boundaries[4] - 4 * width * Vector3.up;
56 | }
57 |
58 | private void initSimpleDecor ()
59 | {
60 | boundaries = new Vector3[8];
61 | width = 0.15f;
62 |
63 | for (int i = 0; i < 4; ++i)
64 | boundaries[i] = parentComponent.boundaries[i] +
65 | 0.01f * parentComponent.parentFace.normal;
66 |
67 | var right = parentComponent.parentFace.right;
68 |
69 | boundaries[4] = boundaries[0] + width * right - width * Vector3.up;
70 | boundaries[5] = boundaries[1] - width * right - width * Vector3.up;
71 | boundaries[6] = boundaries[2] - width * right + width * Vector3.up;
72 | boundaries[7] = boundaries[3] + width * right + width * Vector3.up;
73 | }
74 |
75 | public override void FindVertices()
76 | {
77 | vertices = boundaries;
78 | }
79 |
80 | public override void FindTriangles()
81 | {
82 | triangles = new int[_parentIsWindow ? 24 : 18];
83 | if (_isSimple)
84 | findTrisSimple();
85 | else
86 | findTris();
87 | }
88 |
89 | private void findTris()
90 | {
91 | int i = 0;
92 |
93 | // left side
94 | triangles[i++] = 1;
95 | triangles[i++] = 5;
96 | triangles[i++] = 6;
97 |
98 | triangles[i++] = 1;
99 | triangles[i++] = 6;
100 | triangles[i++] = 2;
101 |
102 | // right side
103 | triangles[i++] = 0;
104 | triangles[i++] = 3;
105 | triangles[i++] = 7;
106 |
107 | triangles[i++] = 0;
108 | triangles[i++] = 7;
109 | triangles[i++] = 4;
110 |
111 | // top
112 | triangles[i++] = 8;
113 | triangles[i++] = 9;
114 | triangles[i++] = 10;
115 |
116 | triangles[i++] = 8;
117 | triangles[i++] = 10;
118 | triangles[i++] = 11;
119 |
120 | // bottom
121 | if (_parentIsWindow)
122 | {
123 | triangles[i++] = 12;
124 | triangles[i++] = 13;
125 | triangles[i++] = 14;
126 |
127 | triangles[i++] = 12;
128 | triangles[i++] = 14;
129 | triangles[i++] = 15;
130 | }
131 | }
132 |
133 | private void findTrisSimple()
134 | {
135 | int i = 0;
136 |
137 | // left
138 | triangles[i++] = 1;
139 | triangles[i++] = 5;
140 | triangles[i++] = 6;
141 |
142 | triangles[i++] = 1;
143 | triangles[i++] = 6;
144 | triangles[i++] = 2;
145 |
146 | // top
147 | triangles[i++] = 2;
148 | triangles[i++] = 6;
149 | triangles[i++] = 7;
150 |
151 | triangles[i++] = 2;
152 | triangles[i++] = 7;
153 | triangles[i++] = 3;
154 |
155 | // right
156 | triangles[i++] = 4;
157 | triangles[i++] = 0;
158 | triangles[i++] = 3;
159 |
160 | triangles[i++] = 4;
161 | triangles[i++] = 3;
162 | triangles[i++] = 7;
163 |
164 | if (_parentIsWindow)
165 | {
166 | // bottom
167 | triangles[i++] = 4;
168 | triangles[i++] = 5;
169 | triangles[i++] = 1;
170 |
171 | triangles[i++] = 4;
172 | triangles[i++] = 1;
173 | triangles[i++] = 0;
174 | }
175 | }
176 |
177 | public override void Draw()
178 | {
179 | base.Draw();
180 |
181 | if (_isSimple)
182 | findUvsSimple();
183 | else
184 | findUvs();
185 |
186 | gameObject.transform.parent = allParent.gameObject.transform;
187 | gameObject.transform.position = allParent.buildingMesh.meshOrigin;
188 | }
189 |
190 | private void findUvs()
191 | {
192 | var uvs = new Vector2[mesh.vertices.Length];
193 |
194 | // left
195 | uvs[5] = new Vector2(0f, 0f);
196 | uvs[1] = new Vector2(.125f, 0f);
197 | uvs[6] = new Vector2(0f, 1f);
198 | uvs[2] = new Vector2(.125f, 1f);
199 |
200 | // right
201 | uvs[0] = new Vector2(.125f, 0f);
202 | uvs[4] = new Vector2(.25f, 0f);
203 | uvs[3] = new Vector2(.125f, 1f);
204 | uvs[7] = new Vector2(.25f, 1f);
205 |
206 | // top
207 | uvs[8] = new Vector2(.25f, 1f);
208 | uvs[11] = new Vector2(.25f, 0f);
209 | uvs[9] = new Vector2(.5f, 1f);
210 | uvs[10] = new Vector2(.5f, 0f);
211 |
212 | // bottom
213 | if (_parentIsWindow)
214 | {
215 | uvs[15] = new Vector2(.5f, 0f);
216 | uvs[14] = new Vector2(1f, 0f);
217 | uvs[12] = new Vector2(.5f, 1f);
218 | uvs[13] = new Vector2(1f, 1f);
219 | }
220 |
221 | mesh.uv = uvs;
222 | }
223 |
224 | private void findUvsSimple()
225 | {
226 | var uvs = new Vector2[mesh.vertices.Length];
227 |
228 | // bottom
229 | uvs[4] = new Vector2(0f, 0f);
230 | uvs[0] = new Vector2(1f, 0f);
231 | uvs[5] = new Vector2(0f, 1f);
232 | uvs[1] = new Vector2(1f, 1f);
233 |
234 | // left
235 | uvs[5] = new Vector2(0f, 0f);
236 | uvs[1] = new Vector2(1f, 0f);
237 | uvs[6] = new Vector2(0f, 1f);
238 | uvs[2] = new Vector2(1f, 1f);
239 |
240 | // top
241 | uvs[6] = new Vector2(0f, 0f);
242 | uvs[2] = new Vector2(1f, 0f);
243 | uvs[7] = new Vector2(0f, 1f);
244 | uvs[3] = new Vector2(1f, 1f);
245 |
246 | // right
247 | uvs[7] = new Vector2(0f, 0f);
248 | uvs[3] = new Vector2(1f, 0f);
249 | uvs[4] = new Vector2(0f, 1f);
250 | uvs[0] = new Vector2(1f, 1f);
251 |
252 | mesh.uv = uvs;
253 | }
254 | }
255 |
256 | } // namespace Thesis
--------------------------------------------------------------------------------
/Assets/Standard Assets/Building/Building.cs:
--------------------------------------------------------------------------------
1 | using UnityEngine;
2 | using System;
3 | using System.Collections.Generic;
4 |
5 | using CombinablesCollection = System.Collections.Generic.IList;
6 | using Random = UnityEngine.Random;
7 |
8 | namespace Thesis {
9 |
10 | public class Building
11 | {
12 | // building dimensions
13 | // 0, 1 -> the indexes of faces
14 | public float width0 = 0f;
15 | public float width1 = 0f;
16 | public Vector3[] startingPoints;
17 | public float floorHeight = 0f;
18 | public int floorCount = 0;
19 |
20 | // component stuff
21 | public float componentDistance = 0f;
22 | public float windowHeight = 0f;
23 | public float windowWidth = 0f;
24 | public float doorWidth = 0f;
25 | public float doorHeight = 0f;
26 | public float balconyWidth = 0f;
27 | public float balconyHeight = 0f;
28 |
29 | // roof stuff
30 | public Type roofType;
31 | public Material roofDecorMaterial;
32 | public Material roofMaterial;
33 | public Material roofBaseMaterial;
34 |
35 | private Material _windowMaterial;
36 | public Material windowMaterial
37 | {
38 | get { return _windowMaterial; }
39 | }
40 |
41 | private Material _balconyDoorMaterial;
42 | public Material balconyDoorMaterial
43 | {
44 | get { return _balconyDoorMaterial; }
45 | }
46 |
47 | private Material _doorMaterial;
48 | public Material doorMaterial
49 | {
50 | get { return _doorMaterial; }
51 | }
52 |
53 | private Material _shutterMaterial;
54 | public Material shutterMaterial
55 | {
56 | get { return _shutterMaterial; }
57 | }
58 |
59 | private Material _compDecorMaterial;
60 | public Material compDecorMaterial
61 | {
62 | get { return _compDecorMaterial; }
63 | }
64 |
65 | private Material _simpleCompDecorMaterial;
66 | public Material simpleCompDecorMaterial
67 | {
68 | get { return _simpleCompDecorMaterial; }
69 | }
70 |
71 | public GameObject gameObject;
72 |
73 | public BuildingMesh buildingMesh;
74 |
75 | private Dictionary _combinables;
76 |
77 | private Dictionary _combiners;
78 |
79 | public Building () { Init(); }
80 |
81 | public Building (Vector3 p1, Vector3 p2, Vector3 p3, Vector3 p4)
82 | {
83 | Init();
84 |
85 | // must be _after_ the initialization of this object
86 | buildingMesh = new BuildingMesh(this, p1, p2, p3, p4);
87 | gameObject = new GameObject("Neoclassical");
88 | gameObject.transform.position = buildingMesh.meshOrigin;
89 | }
90 |
91 | public Building (BuildingLot lot)
92 | {
93 | Init();
94 |
95 | // must be _after_ the initialization of this object
96 | buildingMesh = new BuildingMesh(this, lot);
97 | gameObject = new GameObject("Neoclassical");
98 | gameObject.transform.position = buildingMesh.meshOrigin;
99 | }
100 |
101 | public void CreateBuilding ()
102 | {
103 | if (startingPoints == null)
104 | {
105 | startingPoints = new Vector3[4];
106 | if (width0 == 0f || width1 == 0f)
107 | {
108 | startingPoints[0] = new Vector3();
109 | startingPoints[1] = new Vector3(0f, 0f, 11f);
110 | startingPoints[2] = new Vector3(8f, 0f, 11f);
111 | startingPoints[3] = new Vector3(8f, 0f, 0f);
112 | }
113 | else
114 | {
115 | startingPoints[0] = new Vector3();
116 | startingPoints[1] = Vector3.forward * width0;
117 | startingPoints[3] = Vector3.right * width1;
118 | startingPoints[2] = startingPoints[1] + startingPoints[3];
119 | }
120 | }
121 |
122 | buildingMesh = new BuildingMesh(this, startingPoints[0],
123 | startingPoints[1],
124 | startingPoints[2],
125 | startingPoints[3]);
126 | gameObject = new GameObject("Neoclassical");
127 | gameObject.transform.position = buildingMesh.meshOrigin;
128 | }
129 |
130 | public void Init()
131 | {
132 | _combinables = new Dictionary();
133 | _combiners = new Dictionary();
134 |
135 | // find window material randomly
136 | var list = MaterialManager.Instance.GetCollection("mat_window");
137 | var num = Random.Range(0, list.Count);
138 | _windowMaterial = list[num];
139 |
140 | // balcony door material
141 | list = MaterialManager.Instance.GetCollection("mat_balcony_door");
142 | _balconyDoorMaterial = list[num];
143 |
144 | // door material
145 | list = MaterialManager.Instance.GetCollection("mat_door");
146 | num = Random.Range(0, list.Count);
147 | _doorMaterial = list[num];
148 |
149 | // shutter material
150 | // not randomly selected, depends on the door material
151 | // count and shutter material count, in order to match
152 | // colours
153 | list = MaterialManager.Instance.GetCollection("mat_shutter");
154 | var doorCount = MaterialManager.Instance.GetCollection("mat_door").Count;
155 | var shutCount = MaterialManager.Instance.GetCollection("mat_shutter").Count;
156 | _shutterMaterial = list[num * shutCount / doorCount];
157 |
158 | // component decor material
159 | list = MaterialManager.Instance.GetCollection("mat_comp_decor");
160 | num = Random.Range(0, list.Count);
161 | _compDecorMaterial = list[num];
162 | //compDecorMaterial = list[list.Count - 1];
163 |
164 | list = MaterialManager.Instance.GetCollection("mat_comp_decor_simple");
165 | num = Random.Range(0, list.Count);
166 | _simpleCompDecorMaterial = list[num];
167 | }
168 |
169 | public void AddCombinable(string materialName, Interface.ICombinable combinable)
170 | {
171 | if (!_combinables.ContainsKey(materialName))
172 | {
173 | CombinablesCollection temp = new List();
174 | temp.Add(combinable);
175 | _combinables.Add(materialName, temp);
176 | }
177 | else
178 | _combinables[materialName].Add(combinable);
179 | }
180 |
181 | public void CombineSubmeshes ()
182 | {
183 | foreach (string key in _combinables.Keys)
184 | {
185 | if (_combinables[key].Count < 2) continue;
186 |
187 | var gobject = new GameObject(key + "_combiner");
188 | gobject.SetActive(false);
189 | gobject.transform.parent = gameObject.transform;
190 | var filter = gobject.AddComponent();
191 | var renderer = gobject.AddComponent();
192 | renderer.sharedMaterial = _combinables[key][0].material;
193 |
194 | var filters = new MeshFilter[_combinables[key].Count];
195 | for (var i = 0; i < _combinables[key].Count; ++i)
196 | {
197 | filters[i] = _combinables[key][i].meshFilter;
198 | GameObject.Destroy(_combinables[key][i].mesh);
199 | GameObject.Destroy(_combinables[key][i].gameObject);
200 | }
201 |
202 | var combine = new CombineInstance[filters.Length];
203 | for (var i = 0; i < filters.Length; ++i)
204 | {
205 | combine[i].mesh = filters[i].sharedMesh;
206 | combine[i].transform = filters[i].transform.localToWorldMatrix;
207 | }
208 |
209 | //filter.mesh = new Mesh();
210 | filter.mesh.CombineMeshes(combine);
211 |
212 | if (_combiners.ContainsKey(key))
213 | _combiners[key] = gobject;
214 | else
215 | _combiners.Add(key, gobject);
216 | }
217 | _combinables.Clear();
218 | }
219 |
220 | public void Draw ()
221 | {
222 | buildingMesh.FindVertices();
223 | buildingMesh.FindTriangles();
224 | buildingMesh.Draw();
225 | gameObject.SetActive(true);
226 | }
227 |
228 | public void Destroy ()
229 | {
230 | GameObject.DestroyImmediate(gameObject);
231 |
232 | foreach (string key in _combinables.Keys)
233 | for (var i = 0; i < _combinables[key].Count; ++i)
234 | {
235 | GameObject.DestroyImmediate(_combinables[key][i].mesh);
236 | GameObject.DestroyImmediate(_combinables[key][i].gameObject);
237 | }
238 |
239 | foreach (GameObject go in _combiners.Values)
240 | {
241 | if (go != null)
242 | {
243 | GameObject.DestroyImmediate(go.GetComponent().mesh);
244 | GameObject.DestroyImmediate(go);
245 | }
246 | }
247 |
248 | _combinables.Clear();
249 | _combiners.Clear();
250 | if (buildingMesh != null)
251 | buildingMesh.Destroy();
252 | }
253 | }
254 |
255 | } // namespace Thesis
--------------------------------------------------------------------------------
/Assets/Standard Assets/Managers/MaterialManager.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using UnityEngine;
3 |
4 | using Object = UnityEngine.Object;
5 |
6 | namespace Thesis {
7 |
8 | public sealed class MaterialManager
9 | {
10 | private static readonly MaterialManager _instance = new MaterialManager();
11 | public static MaterialManager Instance
12 | {
13 | get { return _instance; }
14 | }
15 |
16 | private static bool _isInitialized;
17 |
18 | private Dictionary _materials;
19 |
20 | private Dictionary> _collections;
21 |
22 | private MaterialManager ()
23 | {
24 | _materials = new Dictionary();
25 | _collections = new Dictionary>();
26 | _isInitialized = false;
27 | }
28 |
29 | public void Init ()
30 | {
31 | if (!_isInitialized)
32 | {
33 | CreateDoorShutter();
34 | CreateWindowBalcony();
35 | CreateRoofRelated();
36 | CreateWalls();
37 | CreateCity();
38 |
39 | Material mat;
40 | foreach (ProceduralTexture tex
41 | in TextureManager.Instance.GetCollection("tex_comp_decor"))
42 | {
43 | mat = new Material(Shader.Find("Transparent/Cutout/Diffuse"));
44 | mat.mainTexture = tex.content;
45 | MaterialManager.Instance.AddToCollection("mat_comp_decor", mat);
46 | }
47 |
48 | foreach (ProceduralTexture tex
49 | in TextureManager.Instance.GetCollection("tex_comp_decor_simple"))
50 | {
51 | mat = new Material(Shader.Find("Diffuse"));
52 | mat.mainTexture = tex.content;
53 | MaterialManager.Instance.AddToCollection("mat_comp_decor_simple", mat);
54 | }
55 |
56 | mat = new Material(Shader.Find("Diffuse"));
57 | mat.name = "ComponentFrame";
58 | mat.color = new Color32(186, 189, 189, 255);
59 | Add(mat.name, mat);
60 |
61 | // lines
62 | mat = new Material(Shader.Find("VertexLit"));
63 | mat.name = "line_block";
64 | mat.SetColor("_Color", Color.green);
65 | mat.SetColor("_SpecColor", Color.green);
66 | mat.SetColor("_Emission", Color.green);
67 | Add(mat.name, mat);
68 |
69 | mat = new Material(Shader.Find("VertexLit"));
70 | mat.name = "line_lot";
71 | mat.SetColor("_Color", Color.cyan);
72 | mat.SetColor("_SpecColor", Color.cyan);
73 | mat.SetColor("_Emission", Color.cyan);
74 | Add(mat.name, mat);
75 |
76 | mat = new Material(Shader.Find("VertexLit"));
77 | mat.name = "line_sidewalk";
78 | mat.SetColor("_Color", Color.red);
79 | mat.SetColor("_SpecColor", Color.red);
80 | mat.SetColor("_Emission", Color.red);
81 | Add(mat.name, mat);
82 |
83 | //Testing();
84 | _isInitialized = true;
85 | }
86 | }
87 |
88 | public void Unload ()
89 | {
90 | foreach (Material m in _materials.Values)
91 | Object.DestroyImmediate(m, true);
92 | _materials.Clear();
93 | foreach (List l in _collections.Values)
94 | {
95 | foreach (Material m in l)
96 | Object.DestroyImmediate(m, true);
97 | l.Clear();
98 | }
99 | _collections.Clear();
100 | _isInitialized = false;
101 | }
102 |
103 | public void Add (string name, Material material)
104 | {
105 | if (!_materials.ContainsKey(name))
106 | {
107 | material.name = name;
108 | _materials.Add(name, material);
109 | }
110 | }
111 |
112 | public void AddToCollection (string name, Material material)
113 | {
114 | if (_collections.ContainsKey(name))
115 | {
116 | if (!_collections[name].Contains(material))
117 | {
118 | material.name = name;
119 | _collections[name].Add(material);
120 | }
121 | }
122 | else
123 | {
124 | var list = new List();
125 | material.name = name;
126 | list.Add(material);
127 | _collections.Add(name, list);
128 | }
129 | }
130 |
131 | public void Add (string name, string shaderName, ProceduralTexture texture)
132 | {
133 | if (!_materials.ContainsKey(name))
134 | {
135 | var mat = new Material(Shader.Find(shaderName));
136 | mat.name = name;
137 | mat.mainTexture = texture.content;
138 | _materials.Add(mat.name, mat);
139 | }
140 | }
141 |
142 | public void AddToCollection (string collectionName, string shaderName,
143 | ProceduralTexture texture)
144 | {
145 | var mat = new Material(Shader.Find(shaderName));
146 | mat.mainTexture = texture.content;
147 | if (_collections.ContainsKey(collectionName))
148 | {
149 | mat.name = collectionName + "_" + (_collections[collectionName].Count + 1).ToString();
150 | _collections[collectionName].Add(mat);
151 | }
152 | else
153 | {
154 | mat.name = collectionName + "_1";
155 | var list = new List();
156 | list.Add(mat);
157 | _collections.Add(collectionName, list);
158 | }
159 | }
160 |
161 | public void Set (string name, Material material)
162 | {
163 | if (_materials.ContainsKey(name))
164 | _materials[name] = material;
165 | }
166 |
167 | public Material FindByTextureName (string name)
168 | {
169 | foreach (Material m in _materials.Values)
170 | {
171 | if (m.mainTexture != null)
172 | if (m.mainTexture.name == name)
173 | return m;
174 | }
175 |
176 | foreach (List l in _collections.Values)
177 | foreach (Material m in l)
178 | {
179 | if (m.mainTexture != null)
180 | if (m.mainTexture.name == name)
181 | return m;
182 | }
183 |
184 | return null;
185 | }
186 |
187 | public Material Get (string name)
188 | {
189 | return _materials.ContainsKey(name) ? _materials[name] : null;
190 | }
191 |
192 | public List GetCollection (string name)
193 | {
194 | return _collections.ContainsKey(name) ? _collections[name] : null;
195 | }
196 |
197 | private void CreateDoorShutter ()
198 | {
199 | foreach (Color color in ColorManager.Instance.GetCollection("col_components"))
200 | {
201 | foreach (ProceduralTexture tex
202 | in TextureManager.Instance.GetCollection("tex_door"))
203 | {
204 | Material mat = new Material(Shader.Find("Diffuse"));
205 | mat.color = color;
206 | mat.mainTexture = tex.content;
207 | MaterialManager.Instance.AddToCollection("mat_door", mat);
208 | }
209 |
210 | foreach (ProceduralTexture tex
211 | in TextureManager.Instance.GetCollection("tex_shutter"))
212 | {
213 | Material mat = new Material(Shader.Find("Diffuse"));
214 | mat.color = color;
215 | mat.mainTexture = tex.content;
216 | MaterialManager.Instance.AddToCollection("mat_shutter", mat);
217 | }
218 | }
219 | }
220 |
221 | private void CreateWindowBalcony ()
222 | {
223 | foreach (ProceduralTexture tex in TextureManager.Instance.GetCollection("tex_window"))
224 | MaterialManager.Instance.AddToCollection("mat_window", "Diffuse", tex);
225 |
226 | foreach (ProceduralTexture tex in TextureManager.Instance.GetCollection("tex_balcony_door"))
227 | MaterialManager.Instance.AddToCollection("mat_balcony_door",
228 | "Diffuse", tex);
229 |
230 | MaterialManager.Instance.Add("mat_balcony_rail",
231 | "Transparent/Cutout/Diffuse",
232 | TextureManager.Instance.Get("tex_balcony"));
233 | }
234 |
235 | private void CreateRoofRelated()
236 | {
237 | if (TextureManager.Instance.GetCollection("tex_roof") != null)
238 | foreach (ProceduralTexture tex in TextureManager.Instance.GetCollection("tex_roof"))
239 | {
240 | Material mat = new Material(Shader.Find("Diffuse"));
241 | mat.mainTexture = tex.content;
242 | MaterialManager.Instance.AddToCollection("mat_roof", mat);
243 | }
244 |
245 | if (TextureManager.Instance.GetCollection("tex_roof_base") != null)
246 | foreach (ProceduralTexture tex in TextureManager.Instance.GetCollection("tex_roof_base"))
247 | {
248 | Material mat = new Material(Shader.Find("Diffuse"));
249 | mat.mainTexture = tex.content;
250 | MaterialManager.Instance.AddToCollection("mat_roof_base", mat);
251 | }
252 |
253 | if (TextureManager.Instance.GetCollection("tex_roof_decor") != null)
254 | foreach (ProceduralTexture tex in TextureManager.Instance.GetCollection("tex_roof_decor"))
255 | {
256 | Material mat = new Material(Shader.Find("Transparent/Cutout/Diffuse"));
257 | mat.mainTexture = tex.content;
258 | MaterialManager.Instance.AddToCollection("mat_roof_decor", mat);
259 | }
260 | }
261 |
262 | private void CreateWalls ()
263 | {
264 | Material mat;
265 | foreach (Color color in ColorManager.Instance.GetCollection("col_walls"))
266 | {
267 | mat = new Material(Shader.Find("Diffuse"));
268 | mat.color = color;
269 | AddToCollection("mat_walls", mat);
270 | }
271 | }
272 |
273 | private void CreateCity ()
274 | {
275 | Material mat = new Material(Shader.Find("Diffuse"));
276 | mat.color = new Color32(55, 55, 55, 255);
277 | _instance.Add("mat_road", mat);
278 |
279 | mat = new Material(Shader.Find("Diffuse"));
280 | mat.color = Color.gray;
281 | _instance.Add("mat_sidewalk", mat);
282 |
283 | mat = new Material(Shader.Find("Diffuse"));
284 | mat.color = new Color32(0, 55, 0, 255);
285 | _instance.Add("mat_lot", mat);
286 | }
287 |
288 | private void Testing ()
289 | {
290 | Material m = new Material(Shader.Find("Diffuse"));
291 | m.mainTexture = TextureManager.Instance.Get("tile3").content;
292 | MaterialManager.Instance.Add("mat_roof", m);
293 |
294 | Material n = new Material(Shader.Find("Diffuse"));
295 | n.mainTexture = TextureManager.Instance.Get("tex_roof_base").content;
296 | MaterialManager.Instance.Add("mat_roof_base", n);
297 |
298 | m = new Material(Shader.Find("Transparent/Cutout/Diffuse"));
299 | m.mainTexture = TextureManager.Instance.Get("decor").content;
300 | MaterialManager.Instance.Add("mat_decor", m);
301 | }
302 | }
303 |
304 | } // namespace Thesis
--------------------------------------------------------------------------------
/Assets/Standard Assets/Building/BuildingMesh.cs:
--------------------------------------------------------------------------------
1 | using UnityEngine;
2 | using System.Collections.Generic;
3 | using System.Reflection;
4 |
5 | namespace Thesis {
6 |
7 | public class BuildingMesh : DrawableObject
8 | {
9 | /*************** FIELDS ***************/
10 |
11 | public readonly Building parent;
12 |
13 | public List faces = new List();
14 |
15 | private int _floorCount = 0;
16 | public int floorCount
17 | {
18 | get { return _floorCount; }
19 | set
20 | {
21 | _floorCount = value;
22 | if (_floorHeight > 0f)
23 | height = _floorHeight * _floorCount;
24 | }
25 | }
26 |
27 | private float _floorHeight = 0f;
28 | public float floorHeight
29 | {
30 | get { return _floorHeight; }
31 | set
32 | {
33 | _floorHeight = value;
34 | if (_floorCount > 0)
35 | height = _floorHeight * _floorCount;
36 | }
37 | }
38 |
39 | public float height = 0f;
40 |
41 | ///
42 | /// Stores the indexes of faces in sorted order.
43 | ///
44 | public int[] sortedFaces;
45 |
46 | private const float _componentWidthMin = 1.1f;
47 | private const float _componentWidthMax = 1.25f;
48 | private const float _componentSpaceMin = 2f;
49 | private const float _componentSpaceMax = 2.25f;
50 |
51 | public float windowHeight;
52 |
53 | public float doorHeight;
54 |
55 | public float balconyHeight;
56 |
57 | public float balconyFloorHeight;
58 |
59 | public float balconyFloorWidth;
60 |
61 | public float balconyFloorDepth;
62 |
63 | public Roof roof;
64 |
65 | public RoofBase roofBase;
66 |
67 | /*************** CONSTRUCTORS ***************/
68 |
69 | public BuildingMesh (Building parent, Vector3 p1, Vector3 p2, Vector3 p3, Vector3 p4)
70 | {
71 | this.parent = parent;
72 | name = "neo_building_mesh";
73 | var list = MaterialManager.Instance.GetCollection("mat_walls");
74 | material = list[Random.Range(0, list.Count)];
75 |
76 | parent.AddCombinable(material.name, this);
77 |
78 | if (parent.floorHeight <= 0f)
79 | floorHeight = Random.Range(3.8f, 4f);
80 | else
81 | floorHeight = parent.floorHeight;
82 |
83 | if (parent.floorCount <= 0)
84 | floorCount = Util.RollDice(new float[] {0.15f, 0.7f, 0.15f});
85 | else
86 | floorCount = parent.floorCount;
87 |
88 | FindMeshOrigin(p1, p3, p2, p4);
89 |
90 | boundaries = new Vector3[8];
91 | boundaries[0] = p1 - meshOrigin;
92 | boundaries[1] = p2 - meshOrigin;
93 | boundaries[2] = p3 - meshOrigin;
94 | boundaries[3] = p4 - meshOrigin;
95 |
96 | for (int i = 0; i < 4; ++i)
97 | boundaries[i + 4] = boundaries[i] + height * Vector3.up;
98 |
99 | ConstructFaces();
100 | ConstructFaceComponents();
101 | ConstructRoof();
102 | }
103 |
104 | public BuildingMesh (Building parent, BuildingLot lot)
105 | {
106 | this.parent = parent;
107 | name = "neo_building_mesh";
108 | var list = MaterialManager.Instance.GetCollection("mat_walls");
109 | material = list[Random.Range(0, list.Count)];
110 |
111 | parent.AddCombinable(material.name, this);
112 |
113 | if (parent.floorHeight <= 0f)
114 | floorHeight = Random.Range(3.8f, 4f);
115 | else
116 | floorHeight = parent.floorHeight;
117 |
118 | if (parent.floorCount <= 0)
119 | floorCount = Util.RollDice(new float[] {0.15f, 0.7f, 0.15f});
120 | else
121 | floorCount = parent.floorCount;
122 |
123 | FindMeshOrigin(lot.edges[0].start, lot.edges[2].start,
124 | lot.edges[1].start, lot.edges[3].start);
125 |
126 | boundaries = new Vector3[8];
127 | boundaries[0] = lot.edges[0].start - meshOrigin;
128 | boundaries[1] = lot.edges[1].start - meshOrigin;
129 | boundaries[2] = lot.edges[2].start - meshOrigin;
130 | boundaries[3] = lot.edges[3].start - meshOrigin;
131 |
132 | for (int i = 0; i < 4; ++i)
133 | boundaries[i + 4] = boundaries[i] + height * Vector3.up;
134 |
135 | ConstructFaces(lot);
136 | ConstructFaceComponents();
137 | ConstructRoof();
138 | }
139 |
140 | /*************** METHODS ***************/
141 |
142 | public void ConstructFaces ()
143 | {
144 | faces.Add(new Face(this, boundaries[0], boundaries[1]));
145 | faces.Add(new Face(this, boundaries[1], boundaries[2]));
146 | faces.Add(new Face(this, boundaries[2], boundaries[3]));
147 | faces.Add(new Face(this, boundaries[3], boundaries[0]));
148 |
149 | SortFaces();
150 | }
151 |
152 | public void ConstructFaces (BuildingLot lot)
153 | {
154 | faces.Add(new Face(this, boundaries[0], boundaries[1],
155 | lot.freeEdges.Contains(0)));
156 | faces.Add(new Face(this, boundaries[1], boundaries[2],
157 | lot.freeEdges.Contains(1)));
158 | faces.Add(new Face(this, boundaries[2], boundaries[3],
159 | lot.freeEdges.Contains(2)));
160 | faces.Add(new Face(this, boundaries[3], boundaries[0],
161 | lot.freeEdges.Contains(3)));
162 |
163 | SortFaces();
164 | }
165 |
166 | public void ConstructFaceComponents ()
167 | {
168 | if (parent.windowHeight <= 0f)
169 | windowHeight = Random.Range(1.5f, 1.7f);
170 | else
171 | windowHeight = parent.windowHeight;
172 |
173 | if (parent.doorHeight <= 0f)
174 | doorHeight = Random.Range(2.8f, 3f);
175 | else
176 | doorHeight = parent.doorHeight;
177 |
178 | if (parent.balconyHeight <= 0f)
179 | if (parent.windowHeight <= 0f)
180 | balconyHeight = windowHeight / 2 + floorHeight / 2.25f;
181 | else
182 | balconyHeight = 0.66f * floorHeight;
183 | else
184 | balconyHeight = parent.balconyHeight;
185 |
186 | balconyFloorHeight = 0.2f;
187 | balconyFloorDepth = 1f;
188 | balconyFloorWidth = 0.6f;
189 |
190 | float component_width = Random.Range(_componentWidthMin, _componentWidthMax);
191 | float inbetween_space = Random.Range(_componentSpaceMin, _componentSpaceMax);
192 |
193 | foreach (Face face in faces)
194 | face.ConstructFaceComponents(component_width, inbetween_space);
195 | }
196 |
197 | private void ConstructRoof()
198 | {
199 | roofBase = new RoofBase(this);
200 |
201 | if (parent.roofBaseMaterial == null)
202 | {
203 | var list = MaterialManager.Instance.GetCollection("mat_roof_base");
204 | roofBase.material = list[Random.Range(0, list.Count - 1)];
205 | }
206 | else
207 | roofBase.material = parent.roofBaseMaterial;
208 | parent.AddCombinable(roofBase.material.name, roofBase);
209 |
210 | int maxcpf = Mathf.Max(faces[0].componentsPerFloor, faces[1].componentsPerFloor);
211 |
212 | if (parent.roofType == null)
213 | {
214 | int n = Util.RollDice(new float[] { 0.33f, 0.33f, 0.34f });
215 | if (n == 1)
216 | roof = new FlatRoof(this);
217 | else if (n == 2 && maxcpf <= 3)
218 | roof = new SinglePeakRoof(this);
219 | else
220 | roof = new DoublePeakRoof(this);
221 | }
222 | else
223 | {
224 | var ctors = parent.roofType.GetConstructors(BindingFlags.Instance |
225 | BindingFlags.Public);
226 | roof = (Roof) ctors[0].Invoke(new object[] { this });
227 | }
228 |
229 | if (parent.roofMaterial == null)
230 | {
231 | var list = MaterialManager.Instance.GetCollection("mat_roof");
232 | if (roof.GetType().Equals(typeof(FlatRoof)))
233 | roof.material = list[Random.Range(0, 2)];
234 | else
235 | roof.material = list[Random.Range(0, list.Count - 1)];
236 | }
237 | else
238 | roof.material = parent.roofMaterial;
239 | parent.AddCombinable(roof.material.name, roof);
240 | }
241 |
242 | public override void FindVertices ()
243 | {
244 | int vert_count = 0;
245 | for (int i = 0; i < 4; ++i)
246 | {
247 | faces[i].FindVertices();
248 | vert_count += faces[i].vertices.Length;
249 | }
250 |
251 | vertices = new Vector3[vert_count + 4];
252 |
253 | // add roof vertices first
254 | for (int i = 0; i < 4; ++i)
255 | vertices[i] = boundaries[i + 4];
256 |
257 | // copy the vertices of the faces to this.vertices
258 | // index starts from 4 because of roof vertices
259 | int index = 4;
260 | for (int i = 0; i < 4; ++i)
261 | {
262 | System.Array.Copy(faces[i].vertices, 0, vertices, index, faces[i].vertices.Length);
263 | index += faces[i].vertices.Length;
264 | }
265 | }
266 |
267 | public override void FindTriangles ()
268 | {
269 | int tris_count = 0;
270 | for (int i = 0; i < 4; ++i)
271 | if (faces[i].componentsPerFloor == 0)
272 | tris_count += 2;
273 | else
274 | tris_count += floorCount * (6 * faces[i].componentsPerFloor + 2);
275 |
276 | triangles = new int[tris_count * 3];
277 |
278 | // triangles index
279 | int trin = 0;
280 | int offset = 4;
281 |
282 | for (int face = 0; face < 4; ++face)
283 | {
284 | if (faces[face].componentsPerFloor == 0)
285 | {
286 | triangles[trin++] = offset;
287 | triangles[trin++] = offset + 1;
288 | triangles[trin++] = offset + 2;
289 |
290 | triangles[trin++] = offset;
291 | triangles[trin++] = offset + 2;
292 | triangles[trin++] = offset + 3;
293 | }
294 | else
295 | {
296 | for (int floor = 0; floor < floorCount; ++floor)
297 | {
298 | int fixedOffset = offset + faces[face].edgeVerticesCount +
299 | 8 * faces[face].componentsPerFloor * floor;
300 | int cpfX6 = 6 * faces[face].componentsPerFloor;
301 | int floorX2 = 2 * floor;
302 |
303 | triangles[trin++] = offset + floorX2;
304 | triangles[trin++] = fixedOffset;
305 | triangles[trin++] = offset + floorX2 + 2;
306 |
307 | triangles[trin++] = fixedOffset;
308 | triangles[trin++] = fixedOffset + cpfX6;
309 | triangles[trin++] = offset + floorX2 + 2;
310 |
311 | // wall between each component
312 | int index = fixedOffset + 1;
313 | for (int i = 1; i < faces[face].componentsPerFloor; ++i)
314 | {
315 | triangles[trin++] = index;
316 | triangles[trin++] = index + 1;
317 | triangles[trin++] = index + cpfX6;
318 |
319 | triangles[trin++] = index + 1;
320 | triangles[trin++] = index + cpfX6 + 1;
321 | triangles[trin++] = index + cpfX6;
322 |
323 | index += 2;
324 | }
325 |
326 | triangles[trin++] = index;
327 | triangles[trin++] = offset + floorX2 + 1;
328 | triangles[trin++] = index + cpfX6;
329 |
330 | triangles[trin++] = offset + floorX2 + 1;
331 | triangles[trin++] = offset + floorX2 + 3;
332 | triangles[trin++] = index + cpfX6;
333 |
334 | // wall over and under each component
335 | for (int i = 0; i < faces[face].componentsPerFloor; ++i)
336 | {
337 | int extOffset = fixedOffset + (i << 1);
338 |
339 | // under
340 | triangles[trin++] = extOffset;
341 | triangles[trin++] = extOffset + 1;
342 | triangles[trin++] = extOffset + 2 * faces[face].componentsPerFloor;
343 |
344 | triangles[trin++] = extOffset + 1;
345 | triangles[trin++] = extOffset + 2 * faces[face].componentsPerFloor + 1;
346 | triangles[trin++] = extOffset + 2 * faces[face].componentsPerFloor;
347 |
348 | // over
349 | triangles[trin++] = extOffset + 4 * faces[face].componentsPerFloor;
350 | triangles[trin++] = extOffset + 4 * faces[face].componentsPerFloor + 1;
351 | triangles[trin++] = extOffset + cpfX6;
352 |
353 | triangles[trin++] = extOffset + 4 * faces[face].componentsPerFloor + 1;
354 | triangles[trin++] = extOffset + cpfX6 + 1;
355 | triangles[trin++] = extOffset + cpfX6;
356 | }
357 | }
358 | }
359 |
360 | offset += faces[face].vertices.Length;
361 | }
362 | }
363 |
364 | public override void Draw ()
365 | {
366 | base.Draw();
367 |
368 | foreach (Face face in faces)
369 | foreach (FaceComponent component in face.faceComponents)
370 | component.Draw();
371 |
372 | gameObject.transform.position = meshOrigin;
373 | gameObject.transform.parent = parent.gameObject.transform;
374 |
375 | roof.FindVertices();
376 | roof.FindTriangles();
377 | roof.Draw();
378 |
379 | roofBase.FindVertices();
380 | roofBase.FindTriangles();
381 | roofBase.Draw();
382 | }
383 |
384 | ///
385 | /// Sorts the faces of the building by width.
386 | ///
387 | public void SortFaces (bool descending = true)
388 | {
389 | List> lkv = new List>();
390 | for (int i = 0; i < faces.Count; ++i)
391 | lkv.Add(new KeyValuePair(i, faces[i].width));
392 |
393 | if (descending)
394 | lkv.Sort(delegate (KeyValuePair x, KeyValuePair y)
395 | {
396 | return y.Value.CompareTo(x.Value);
397 | });
398 | else
399 | lkv.Sort(delegate (KeyValuePair x, KeyValuePair y)
400 | {
401 | return x.Value.CompareTo(y.Value);
402 | });
403 |
404 | sortedFaces = new int[lkv.Count];
405 | for (int i = 0; i < lkv.Count; ++i)
406 | sortedFaces[i] = lkv[i].Key;
407 | }
408 |
409 | public override void Destroy()
410 | {
411 | base.Destroy();
412 |
413 | foreach (Face face in faces)
414 | face.Destroy();
415 |
416 | roof.Destroy();
417 | roofBase.Destroy();
418 | }
419 | }
420 |
421 | } // namespace Thesis
--------------------------------------------------------------------------------
/Assets/Standard Assets/City/Block.cs:
--------------------------------------------------------------------------------
1 | using UnityEngine;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 |
5 | namespace Thesis {
6 |
7 | public class Block
8 | {
9 | /*************** FIELDS ***************/
10 |
11 | public readonly List edges;
12 |
13 | private bool _isFinal;
14 |
15 | private const float _divergence = 0.05f;
16 |
17 | public BuildingLot initialLot;
18 |
19 | public List finalLots = new List();
20 |
21 | public readonly float sidewalkWidth = 1.75f;
22 |
23 | public readonly float roadWidth = 2.25f;
24 |
25 | public Vector3[] sidewalkVerts;
26 |
27 | public Vector3[] lotVerts;
28 |
29 | public Road road;
30 |
31 | public Sidewalk sidewalk;
32 |
33 | /*************** CONSTRUCTORS ***************/
34 |
35 | // the point Vector3.zero must _not_ be used
36 | // as starting point and all 4 points must be
37 | // in the first quadrant
38 | public Block ()
39 | : this(new Vector3(1f, 0f, 0f),
40 | new Vector3(0f, 0f, 300f),
41 | new Vector3(500f, 0f, 300f),
42 | new Vector3(500f, 0f, 0f))
43 | {
44 | CityMapManager.Instance.Clear();
45 | }
46 |
47 | public Block (Vector3 p1, Vector3 p2, Vector3 p3, Vector3 p4)
48 | {
49 | int i = CityMapManager.Instance.Add(p1);
50 | if (i != -1)
51 | p1 = CityMapManager.Instance.nodes[i];
52 |
53 | i = CityMapManager.Instance.Add(p2);
54 | if (i != -1)
55 | p2 = CityMapManager.Instance.nodes[i];
56 |
57 | i = CityMapManager.Instance.Add(p3);
58 | if (i != -1)
59 | p3 = CityMapManager.Instance.nodes[i];
60 |
61 | i = CityMapManager.Instance.Add(p4);
62 | if (i != -1)
63 | p4 = CityMapManager.Instance.nodes[i];
64 |
65 | var edgeList = new List();
66 | edgeList.Add(new Edge(p1, p2));
67 | edgeList.Add(new Edge(p2, p3));
68 | edgeList.Add(new Edge(p3, p4));
69 | edgeList.Add(new Edge(p4, p1));
70 |
71 | // find index of longest edge
72 | i = edgeList.FindIndex(delegate (Edge edge) {
73 | return edge.length == edgeList.Max(e => e.length);
74 | });
75 |
76 | // put the edges in clockwise order starting from the biggest
77 | edges = new List();
78 | for (int j = 0; j < 4; ++j)
79 | edges.Add(edgeList[(i + j) % 4]);
80 |
81 | FindIfIsFinal();
82 | }
83 |
84 | public void Bisect ()
85 | {
86 | if (_isFinal)
87 | {
88 | FindSidewalkNLotVerts();
89 | CityMapManager.Instance.AddRoad(this);
90 | CityMapManager.Instance.AddSidewalk(this);
91 | initialLot = new BuildingLot(this);
92 | if (initialLot.isFinal())
93 | {
94 | initialLot.freeEdges.AddRange(new int[] { 0, 1, 2, 3 });
95 | finalLots.Add(initialLot);
96 | }
97 | else
98 | CreateBuildingLots();
99 |
100 | CityMapManager.Instance.Add(this);
101 | return;
102 | }
103 |
104 | var big_offset = Random.Range(0f, _divergence * edges[0].length) * edges[0].direction;
105 | if (Util.RollDice(new float[] { 0.5f, 0.5f }) == 1)
106 | big_offset *= -1;
107 | var opp_offset = Random.Range(0f, _divergence * edges[2].length) * edges[2].direction;
108 | if (Util.RollDice(new float[] { 0.5f, 0.5f }) == 1)
109 | opp_offset *= -1;
110 |
111 | Block b1 = new Block(edges[3].start, edges[3].end,
112 | edges[0].middle + big_offset, edges[2].middle + opp_offset);
113 | b1.Bisect();
114 | Block b2 = new Block(edges[1].start, edges[1].end,
115 | edges[2].middle + opp_offset, edges[0].middle + big_offset);
116 | b2.Bisect();
117 | }
118 |
119 | private void FindIfIsFinal ()
120 | {
121 | float min = edges.Min(e => e.length);
122 | if (min < 25f)
123 | {
124 | _isFinal = true;
125 | return;
126 | }
127 |
128 | if (edges[0].length > 63f)
129 | {
130 | _isFinal = false;
131 | return;
132 | }
133 |
134 | if (min < 35f && Util.RollDice(new float[] { 0.7f, 0.3f }) == 1)
135 | {
136 | _isFinal = true;
137 | return;
138 | }
139 |
140 | if (min < 45f && Util.RollDice(new float[] { 0.3f, 0.7f }) == 1)
141 | {
142 | _isFinal = true;
143 | return;
144 | }
145 |
146 | _isFinal = false;
147 | }
148 |
149 | private void CreateBuildingLots()
150 | {
151 | var es = initialLot.edges;
152 | var minLength = initialLot.edges.Min(e => e.length);
153 | BuildingLot lot;
154 |
155 | if (minLength <= 16f)
156 | {
157 | lot = new BuildingLot(es[0].start, es[0].middle, es[2].middle, es[2].end);
158 | lot.freeEdges.AddRange(new int[] { 0, 2, 3 });
159 | finalLots.Add(lot);
160 |
161 | lot = new BuildingLot(es[0].middle, es[0].end, es[2].start, es[2].middle);
162 | lot.freeEdges.AddRange(new int[] { 0, 1, 2 });
163 | finalLots.Add(lot);
164 | return;
165 | }
166 |
167 | if (minLength <= 27f && initialLot.edges[0].length <= 30f)
168 | {
169 | var r = Util.RollDice(new float[] { 0.5f, 0.5f });
170 | var pointBig = es[0].start + r / 3f * es[0].length * es[0].direction;
171 | var pointOpp = es[2].start + (3 - r) / 3f * es[2].length * es[2].direction;
172 | var pointMid = (pointBig + pointOpp) / 2;
173 |
174 | lot = new BuildingLot(es[1].start, es[1].middle, pointMid, pointBig);
175 | lot.freeEdges.AddRange(new int[] { 0, 3 });
176 | finalLots.Add(lot);
177 |
178 | lot = new BuildingLot(es[1].middle, es[1].end, pointOpp, pointMid);
179 | lot.freeEdges.AddRange(new int[] { 0, 1 });
180 | finalLots.Add(lot);
181 |
182 | lot = new BuildingLot(es[0].start, pointBig, pointMid, es[3].middle);
183 | lot.freeEdges.AddRange(new int[] { 0, 3 });
184 | finalLots.Add(lot);
185 |
186 | lot = new BuildingLot(pointOpp, es[2].end, es[3].middle, pointMid);
187 | lot.freeEdges.AddRange(new int[] { 0, 1 });
188 | finalLots.Add(lot);
189 | return;
190 | }
191 |
192 | if (minLength <= 27f && es[0].length <= 40f)
193 | {
194 | var bisector = new Edge(es[3].middle, es[1].middle);
195 | var r = Random.Range(11, 16);
196 |
197 | var p1big = es[0].start + r * es[0].direction;
198 | var p2big = p1big + Vector3.Distance(p1big, es[0].end) / 2 * es[0].direction;
199 | var p1mid = es[3].middle + r / es[0].length * bisector.length * bisector.direction;
200 | var p2mid = p1mid + Vector3.Distance(p1mid, bisector.end) / 2 * bisector.direction;
201 |
202 | lot = new BuildingLot(es[0].start, p1big, p1mid, bisector.start);
203 | lot.freeEdges.AddRange(new int[] { 0, 3 });
204 | finalLots.Add(lot);
205 |
206 | lot = new BuildingLot(p1big, p2big, p2mid, p1mid);
207 | lot.freeEdges.Add(0);
208 | finalLots.Add(lot);
209 |
210 | lot = new BuildingLot(p2big, es[0].end, bisector.end, p2mid);
211 | lot.freeEdges.AddRange(new int[] { 0, 1 });
212 | finalLots.Add(lot);
213 |
214 | var p1opp = es[2].start + r * es[2].direction;
215 | var p2opp = p1opp + Vector3.Distance(p1opp, es[2].end) / 2 * es[2].direction;
216 | var p3mid = es[1].middle - r / es[2].length * bisector.length * bisector.direction;
217 | var p4mid = p3mid - Vector3.Distance(p3mid, bisector.start) / 2 * bisector.direction;
218 |
219 | lot = new BuildingLot(es[2].start, p1opp, p3mid, es[1].middle);
220 | lot.freeEdges.AddRange(new int[] { 0, 3 });
221 | finalLots.Add(lot);
222 |
223 | lot = new BuildingLot(p1opp, p2opp, p4mid, p3mid);
224 | lot.freeEdges.Add(0);
225 | finalLots.Add(lot);
226 |
227 | lot = new BuildingLot(p2opp, es[2].end, es[3].middle, p4mid);
228 | lot.freeEdges.AddRange(new int[] { 0, 1 });
229 | finalLots.Add(lot);
230 |
231 | return;
232 | }
233 |
234 | // for initialLots larger than 40x27
235 |
236 | CityMapManager.Instance.AddDrawableLot(initialLot);
237 |
238 | // big face range -> 11 - 20
239 | // small face range -> 6 - 9
240 | // therefore small = (3big + 21) / 9
241 | float r1, r2;
242 | Vector3 p1, p2, p3, p4;
243 |
244 | for (int i = 0; i < 3; i+=2)
245 | while (es[i].length - initialLot.occupied[i] > 7f)
246 | {
247 | if (initialLot.pointsInEdge[i].Count == 0)
248 | {
249 | r1 = Random.Range(11, 20);
250 | r2 = (3 * r1 + 21) / 9f;
251 | p1 = es[i].start;
252 | p2 = p1 + r1 * es[i].direction;
253 | p4 = es[i].start - r2 * es[(i + 3) % 4].direction;
254 | p3 = Util.IntersectionPoint(p2, es[i].right, p4, es[i].direction);
255 |
256 | initialLot.pointsInEdge[i].Add(p2);
257 | initialLot.occupied[i] += r1;
258 | initialLot.pointsInEdge[(i + 3) % 4].Add(p4);
259 | initialLot.occupied[(i + 3) % 4] += r2;
260 |
261 | lot = new BuildingLot(p1, p2, p3, p4);
262 | lot.freeEdges.AddRange(new int[] { 0, 3 });
263 | finalLots.Add(lot);
264 | }
265 | else
266 | {
267 | r1 = es[i].length - initialLot.occupied[i];
268 | if (r1 > 31f)
269 | {
270 | r1 = Random.Range(11, 20);
271 | r2 = (3 * r1 + 21) / 9f;
272 |
273 | p1 = initialLot.pointsInEdge[i].Last();
274 | p2 = p1 + r1 * es[i].direction;
275 | p3 = p2 + r2 * es[i].right;
276 | p4 = p1 + r2 * es[i].right;
277 |
278 | initialLot.pointsInEdge[i].Add(p2);
279 | initialLot.occupied[i] += r1;
280 |
281 | lot = new BuildingLot(p1, p2, p3, p4);
282 | lot.freeEdges.Add(0);
283 | finalLots.Add(lot);
284 | }
285 | else if (25f <= r1 && r1 <= 31f)
286 | {
287 | r1 = r1 / 2;
288 | r2 = (3 * r1 + 21) / 9f;
289 |
290 | p1 = initialLot.pointsInEdge[i].Last();
291 | p2 = p1 + r1 * es[i].direction;
292 | p3 = p2 + r2 * es[i].right;
293 | p4 = p1 + r2 * es[i].right;
294 |
295 | initialLot.pointsInEdge[i].Add(p2);
296 | initialLot.occupied[i] += r1;
297 |
298 | lot = new BuildingLot(p1, p2, p3, p4);
299 | lot.freeEdges.Add(0);
300 | finalLots.Add(lot);
301 | }
302 | else if (19f <= r1 && r1 <= 25f)
303 | {
304 | r1 -= 7f;
305 | r2 = (3 * r1 + 21) / 9f;
306 |
307 | p1 = initialLot.pointsInEdge[i].Last();
308 | p2 = p1 + r1 * es[i].direction;
309 | p3 = p2 + r2 * es[(i + 1) % 4].direction;
310 | p4 = p1 + r2 * es[i].right;
311 |
312 | initialLot.pointsInEdge[i].Add(p2);
313 | initialLot.occupied[i] += r1;
314 |
315 | lot = new BuildingLot(p1, p2, p3, p4);
316 | lot.freeEdges.Add(0);
317 | finalLots.Add(lot);
318 | }
319 | else if (11f <= r1 && r1 <= 19f)
320 | {
321 | r2 = (3 * r1 + 21) / 9f;
322 |
323 | p1 = initialLot.pointsInEdge[i].Last();
324 | p2 = es[i].end;
325 | p3 = es[i].end + r2 * es[(i + 1) % 4].direction;
326 | p4 = Util.IntersectionPoint(p1, es[i].right, p3, es[i].direction);
327 |
328 | initialLot.pointsInEdge[(i + 1) % 4].Add(p3);
329 | initialLot.occupied[(i + 1) % 4] += r2;
330 | initialLot.occupied[i] += r1;
331 |
332 | lot = new BuildingLot(p1, p2, p3, p4);
333 | lot.freeEdges.AddRange(new int[] { 0, 1 });
334 | finalLots.Add(lot);
335 | }
336 | else
337 | break;
338 | }
339 | }
340 |
341 | for (int i = 1; i < 4; i+=2)
342 | {
343 | if (initialLot.pointsInEdge[i].Count == 2)
344 | {
345 | if (Vector3.Distance(es[i].start, initialLot.pointsInEdge[i][0]) >
346 | Vector3.Distance(es[i].start, initialLot.pointsInEdge[i][1]))
347 | initialLot.pointsInEdge[i].Reverse();
348 |
349 | r1 = Vector3.Distance(initialLot.pointsInEdge[i][0], initialLot.pointsInEdge[i][1]);
350 | if (r1 <= 12f)
351 | r2 = r1;
352 | else
353 | r2 = (3 * r1 + 21) / 9f;
354 |
355 | p1 = initialLot.pointsInEdge[i][0];
356 | p2 = initialLot.pointsInEdge[i][1];
357 | p3 = p2 + r2 * es[(i + 1) % 4].direction;
358 | p4 = p1 - r2 * es[(i + 3) % 4].direction;
359 |
360 | lot = new BuildingLot(p1, p2, p3, p4);
361 | lot.freeEdges.Add(0);
362 | finalLots.Add(lot);
363 | continue;
364 | }
365 |
366 | if (initialLot.pointsInEdge[i].Count == 1)
367 | {
368 | var dist = Vector3.Distance(es[i].start, initialLot.pointsInEdge[i][0]);
369 |
370 | if (dist < 22f)
371 | {
372 | p1 = es[i].start;
373 | p2 = initialLot.pointsInEdge[i][0];
374 | p4 = initialLot.pointsInEdge[(i + 3) % 4].Last();
375 | p3 = Util.IntersectionPoint(p4, es[i].direction,
376 | p2, es[(i + 1) % 4].direction);
377 |
378 | lot = new BuildingLot(p1, p2, p3, p4);
379 | lot.freeEdges.AddRange(new int[] { 0, 3 });
380 | finalLots.Add(lot);
381 | }
382 | else
383 | {
384 | r1 = dist / 2;
385 |
386 | p1 = es[i].start;
387 | p2 = p1 + r1 * es[i].direction;
388 | p4 = initialLot.pointsInEdge[(i + 3) % 4].Last();
389 | p3 = Util.IntersectionPoint(p4, es[(i + 0) % 4].direction,
390 | p2, es[i].right);
391 |
392 | lot = new BuildingLot(p1, p2, p3, p4);
393 | lot.freeEdges.AddRange(new int[] { 0, 3 });
394 | finalLots.Add(lot);
395 |
396 | r2 = (3 * r1 + 21) / 9f;
397 | p1 = p2;
398 | p2 = initialLot.pointsInEdge[i][0];
399 | p3 = p2 + r2 * es[(i + 1) % 4].direction;
400 | p4 = p1 + r2 * es[i].right;
401 |
402 | lot = new BuildingLot(p1, p2, p3, p4);
403 | lot.freeEdges.Add(0);
404 | finalLots.Add(lot);
405 | }
406 | }
407 | }
408 | }
409 |
410 | private void FindSidewalkNLotVerts ()
411 | {
412 | sidewalkVerts = new Vector3[4];
413 | lotVerts = new Vector3[4];
414 | float angle, dist, sin;
415 | Vector3 dir;
416 |
417 | for (int i = 0; i < 4; ++i)
418 | {
419 | angle = Vector3.Angle(edges[i].direction, -edges[(i + 3) % 4].direction);
420 | sin = Mathf.Sin(angle / 2 * Mathf.Deg2Rad);
421 | dir = (edges[i].direction - edges[(i + 3) % 4].direction).normalized;
422 |
423 | dist = roadWidth / sin;
424 | sidewalkVerts[i] = edges[i].start + dist * dir;
425 |
426 | dist = (roadWidth + sidewalkWidth) / sin;
427 | lotVerts[i] = edges[i].start + dist * dir;
428 | }
429 | }
430 | }
431 |
432 | } // namespace Thesis
--------------------------------------------------------------------------------
/Assets/Standard Assets/Editor/Builder.cs:
--------------------------------------------------------------------------------
1 | using UnityEngine;
2 | using UnityEditor;
3 | using Thesis;
4 | using System.Collections.Generic;
5 | using System;
6 |
7 | using Object = UnityEngine.Object;
8 |
9 | public class Builder : EditorWindow
10 | {
11 | // dimensions stuff
12 | private Vector2 _p1 = Vector2.zero;
13 | private Vector2 _p2 = Vector2.zero;
14 | private Vector2 _p3 = Vector2.zero;
15 | private Vector2 _p4 = Vector2.zero;
16 | private float _width = 0f, _depth = 0f, _height = 0f;
17 | private int _floors = 0;
18 |
19 | private enum Area { noChoice, dimensions, points }
20 | private Area choice1 = Area.noChoice;
21 |
22 | private enum Heights
23 | {
24 | noChoice,
25 | floorCount,
26 | floorHeight,
27 | floorCountAndHeight
28 | }
29 | private Heights choice2 = Heights.noChoice;
30 |
31 | // component stuff
32 | private bool inputCompCount = false;
33 | private float compDist = 0f;
34 | private bool windowFoldout = false;
35 | private float windowHeight = 0f;
36 | private float windowWidth = 0f;
37 | private bool setWindowWidth = false;
38 | private bool setWindowHeight = false;
39 | private bool doorFoldout = false;
40 | private float doorHeight = 0f;
41 | private float doorWidth = 0f;
42 | private bool setDoorWidth = false;
43 | private bool setDoorHeight = false;
44 | private bool balconyFoldout = false;
45 | private bool setBalconyWidth = false;
46 | private float balconyWidth = 0f;
47 | private bool setBalconyHeight = false;
48 | private float balconyHeight = 0f;
49 |
50 | // roof stuff
51 | private enum myRType
52 | {
53 | noChoice,
54 | Flat,
55 | SinglePeak,
56 | DoublePeak
57 | }
58 | private myRType rtype = myRType.noChoice;
59 | private bool inputRoofDecor = false;
60 | private Object roofDecorTexture;
61 | private bool inputRoof = false;
62 | private Object roofTexture;
63 | private bool inputRoofBase = false;
64 | private Object roofBaseTexture;
65 |
66 | private static Building _building;
67 |
68 | [MenuItem ("Window/Builder")]
69 | static void Init ()
70 | {
71 | ColorManager.Instance.Init();
72 | TextureManager.Instance.Init();
73 | MaterialManager.Instance.Init();
74 |
75 | _building = new Building();
76 |
77 | EditorWindow.GetWindow(typeof(Builder), false, "Builder");
78 | }
79 |
80 | void OnGUI ()
81 | {
82 | GUILayout.Space(20);
83 | EditorGUILayout.BeginHorizontal();
84 | if (GUILayout.Button("Destroy"))
85 | _building.Destroy();
86 |
87 | if (GUILayout.Button("Create"))
88 | {
89 | _building.Destroy();
90 | _building.Init();
91 | _building.CreateBuilding();
92 | _building.Draw();
93 | }
94 | EditorGUILayout.EndHorizontal();
95 |
96 | GUILayout.Space(20);
97 | BuildingDimensions();
98 | GUILayout.Space(10);
99 | ComponentParams();
100 | GUILayout.Space(10);
101 | RoofParams();
102 | }
103 |
104 | void OnDestroy ()
105 | {
106 | _building.Destroy();
107 | ColorManager.Instance.Unload();
108 | TextureManager.Instance.Unload();
109 | MaterialManager.Instance.Unload();
110 | }
111 |
112 | private void BuildingDimensions ()
113 | {
114 | EditorGUILayout.LabelField("Dimensions", EditorStyles.boldLabel);
115 |
116 | choice1 = (Area) EditorGUILayout.EnumPopup("Area", choice1);
117 | switch (choice1)
118 | {
119 | case Area.dimensions:
120 | _building.startingPoints = null;
121 |
122 | _width = EditorGUILayout.FloatField("Width", _width);
123 | _depth = EditorGUILayout.FloatField("Depth", _depth);
124 | _building.width0 = _width;
125 | _building.width1 = _depth;
126 | break;
127 |
128 | case Area.points:
129 | _building.width0 = 0f;
130 | _building.width1 = 0f;
131 |
132 | _p1 = EditorGUILayout.Vector2Field("point 1", _p1);
133 | _p2 = EditorGUILayout.Vector2Field("point 2", _p2);
134 | _p3 = EditorGUILayout.Vector2Field("point 3", _p3);
135 | _p4 = EditorGUILayout.Vector2Field("point 4", _p4);
136 |
137 | if (_p1 != _p2 && _p1 != _p3 && _p1 != _p4 && _p2 != _p3 &&
138 | _p2 != _p4 && _p3 != _p4)
139 | {
140 | _building.startingPoints = new Vector3[4];
141 | _building.startingPoints[0] = new Vector3(_p1.x, 0f, _p1.y);
142 | _building.startingPoints[1] = new Vector3(_p2.x, 0f, _p2.y);
143 | _building.startingPoints[2] = new Vector3(_p3.x, 0f, _p3.y);
144 | _building.startingPoints[3] = new Vector3(_p4.x, 0f, _p4.y);
145 | }
146 | break;
147 |
148 | default:
149 | _building.width0 = 0f;
150 | _building.width1 = 0f;
151 | _building.startingPoints = null;
152 | break;
153 | }
154 |
155 | choice2 = (Heights) EditorGUILayout.EnumPopup("Height", choice2);
156 | switch (choice2)
157 | {
158 | case Heights.floorCount:
159 | _floors = EditorGUILayout.IntField("Floor Count", _floors);
160 | _building.floorCount = _floors;
161 | _building.floorHeight = 0f;
162 | break;
163 |
164 | case Heights.floorHeight:
165 | _height = EditorGUILayout.FloatField("Floor Height", _height);
166 | _building.floorHeight = _height;
167 | _building.floorCount = 0;
168 | break;
169 |
170 | case Heights.floorCountAndHeight:
171 | _floors = EditorGUILayout.IntField("Floor Count", _floors);
172 | _height = EditorGUILayout.FloatField("Floor Height", _height);
173 | _building.floorHeight = _height;
174 | _building.floorCount = _floors;
175 | break;
176 |
177 | default:
178 | _building.floorHeight = 0f;
179 | _building.floorCount = 0;
180 | break;
181 | }
182 | }
183 |
184 | private void ComponentParams ()
185 | {
186 | EditorGUILayout.LabelField("Components", EditorStyles.boldLabel);
187 |
188 | EditorGUILayout.BeginHorizontal();
189 | EditorGUILayout.LabelField("Component distance");
190 | inputCompCount = EditorGUILayout.Toggle(inputCompCount);
191 | if (inputCompCount)
192 | {
193 | compDist = EditorGUILayout.FloatField(compDist, GUILayout.Width(30));
194 | _building.componentDistance = compDist;
195 | }
196 | else
197 | {
198 | compDist = 0;
199 | _building.componentDistance = 0;
200 | }
201 | EditorGUILayout.EndHorizontal();
202 |
203 | //EditorGUILayout.BeginHorizontal();
204 | //EditorGUILayout.LabelField("Component distance");
205 | //inputCompDistance = EditorGUILayout.Toggle(inputCompDistance);
206 | //if (inputCompDistance)
207 | //{
208 | // distance = EditorGUILayout.FloatField(distance, GUILayout.Width(25));
209 | // _building.distance = distance;
210 | //}
211 | //else
212 | //{
213 | // distance = 0f;
214 | // _building.distance = 0f;
215 | //}
216 | //EditorGUILayout.EndHorizontal();
217 |
218 | // Window
219 | windowFoldout = EditorGUILayout.Foldout(windowFoldout, "Window");
220 | if (windowFoldout)
221 | {
222 | // width
223 | EditorGUILayout.BeginHorizontal();
224 | EditorGUILayout.LabelField("Width");
225 | setWindowWidth = EditorGUILayout.Toggle(setWindowWidth);
226 | if (setWindowWidth)
227 | windowWidth = EditorGUILayout.FloatField(windowWidth, GUILayout.Width(30));
228 | else
229 | windowWidth = 0f;
230 | EditorGUILayout.EndHorizontal();
231 | _building.windowWidth = windowWidth;
232 |
233 | // height
234 | EditorGUILayout.BeginHorizontal();
235 | EditorGUILayout.LabelField("Height");
236 | setWindowHeight = EditorGUILayout.Toggle(setWindowHeight);
237 | if (setWindowHeight)
238 | windowHeight = EditorGUILayout.FloatField(windowHeight, GUILayout.Width(30));
239 | else
240 | windowHeight = 0f;
241 | EditorGUILayout.EndHorizontal();
242 | _building.windowHeight = windowHeight;
243 |
244 | // material
245 | //EditorGUILayout.BeginHorizontal();
246 | //EditorGUILayout.LabelField("Texture");
247 | //setWindowTexture = EditorGUILayout.Toggle(setWindowTexture);
248 | //if (setWindowTexture)
249 | // windowTexture = EditorGUILayout.ObjectField(windowTexture,
250 | // typeof(Texture),
251 | // false,
252 | // GUILayout.Height(55));
253 | //else
254 | // windowTexture = null;
255 | //EditorGUILayout.EndHorizontal();
256 | // find material by windowtexture name
257 | }
258 |
259 | // Door
260 | doorFoldout = EditorGUILayout.Foldout(doorFoldout, "Door");
261 | if (doorFoldout)
262 | {
263 | // width
264 | EditorGUILayout.BeginHorizontal();
265 | EditorGUILayout.LabelField("Width");
266 | setDoorWidth = EditorGUILayout.Toggle(setDoorWidth);
267 | if (setDoorWidth)
268 | doorWidth = EditorGUILayout.FloatField(doorWidth, GUILayout.Width(30));
269 | else
270 | doorWidth = 0f;
271 | EditorGUILayout.EndHorizontal();
272 | _building.doorWidth = doorWidth;
273 |
274 | // height
275 | EditorGUILayout.BeginHorizontal();
276 | EditorGUILayout.LabelField("Height");
277 | setDoorHeight = EditorGUILayout.Toggle(setDoorHeight);
278 | if (setDoorHeight)
279 | doorHeight = EditorGUILayout.FloatField(doorHeight, GUILayout.Width(30));
280 | else
281 | doorHeight = 0f;
282 | EditorGUILayout.EndHorizontal();
283 | _building.doorHeight = doorHeight;
284 |
285 | // material
286 | //EditorGUILayout.BeginHorizontal();
287 | //EditorGUILayout.LabelField("Texture");
288 | //setDoorTexture = EditorGUILayout.Toggle(setDoorTexture);
289 | //if (setDoorTexture)
290 | // doorTexture = EditorGUILayout.ObjectField(doorTexture,
291 | // typeof(Texture),
292 | // false,
293 | // GUILayout.Height(55));
294 | //else
295 | // doorTexture = null;
296 | //EditorGUILayout.EndHorizontal();
297 | // find material by windowtexture name
298 | }
299 |
300 | // balcony
301 | balconyFoldout = EditorGUILayout.Foldout(balconyFoldout, "Balcony");
302 | if (balconyFoldout)
303 | {
304 | // width
305 | EditorGUILayout.BeginHorizontal();
306 | EditorGUILayout.LabelField("Width");
307 | setBalconyWidth = EditorGUILayout.Toggle(setBalconyWidth);
308 | if (setBalconyWidth)
309 | balconyWidth = EditorGUILayout.FloatField(balconyWidth, GUILayout.Width(30));
310 | else
311 | balconyWidth = 0f;
312 | EditorGUILayout.EndHorizontal();
313 | _building.balconyWidth = balconyWidth;
314 |
315 | // height
316 | EditorGUILayout.BeginHorizontal();
317 | EditorGUILayout.LabelField("Height");
318 | setBalconyHeight = EditorGUILayout.Toggle(setBalconyHeight);
319 | if (setBalconyHeight)
320 | balconyHeight = EditorGUILayout.FloatField(balconyHeight, GUILayout.Width(30));
321 | else
322 | balconyHeight = 0f;
323 | EditorGUILayout.EndHorizontal();
324 | _building.balconyHeight = balconyHeight;
325 | }
326 | }
327 |
328 | private void RoofParams ()
329 | {
330 | EditorGUILayout.LabelField("Roof", EditorStyles.boldLabel);
331 |
332 | rtype = (myRType) EditorGUILayout.EnumPopup("Roof type", rtype);
333 | switch (rtype)
334 | {
335 | case myRType.Flat:
336 | _building.roofType = Type.GetType(GetFullType(myRType.Flat));
337 | EditorGUILayout.BeginHorizontal();
338 | EditorGUILayout.LabelField("Roof decor texture");
339 | inputRoofDecor = EditorGUILayout.Toggle(inputRoofDecor);
340 | if (inputRoofDecor)
341 | {
342 | roofDecorTexture = EditorGUILayout.ObjectField(roofDecorTexture,
343 | typeof(Texture),
344 | false,
345 | GUILayout.Height(55));
346 | if (roofDecorTexture != null)
347 | _building.roofDecorMaterial = MaterialManager.Instance.
348 | FindByTextureName(roofDecorTexture.name);
349 | }
350 | else
351 | {
352 | _building.roofDecorMaterial = null;
353 | roofDecorTexture = null;
354 | }
355 | EditorGUILayout.EndHorizontal();
356 | break;
357 |
358 | case myRType.SinglePeak:
359 | _building.roofType = Type.GetType(GetFullType(myRType.SinglePeak));
360 | inputRoofDecor = false;
361 | _building.roofDecorMaterial = null;
362 | break;
363 |
364 | case myRType.DoublePeak:
365 | _building.roofType = Type.GetType(GetFullType(myRType.DoublePeak));
366 | inputRoofDecor = false;
367 | _building.roofDecorMaterial = null;
368 | break;
369 |
370 | default:
371 | _building.roofType = null;
372 | inputRoofDecor = false;
373 | _building.roofDecorMaterial = null;
374 | break;
375 | }
376 |
377 | // roof texture
378 | EditorGUILayout.BeginHorizontal();
379 | EditorGUILayout.LabelField("Roof texture");
380 | inputRoof = EditorGUILayout.Toggle(inputRoof);
381 | if (inputRoof)
382 | {
383 | roofTexture = EditorGUILayout.ObjectField(roofTexture,
384 | typeof(Texture),
385 | false,
386 | GUILayout.Height(55));
387 | if (roofTexture != null)
388 | _building.roofMaterial = MaterialManager.Instance.
389 | FindByTextureName(roofTexture.name);
390 | }
391 | else
392 | {
393 | _building.roofMaterial = null;
394 | roofTexture = null;
395 | }
396 | EditorGUILayout.EndHorizontal();
397 |
398 | // roof base texture
399 | EditorGUILayout.BeginHorizontal();
400 | EditorGUILayout.LabelField("Roof base texture");
401 | inputRoofBase = EditorGUILayout.Toggle(inputRoofBase);
402 | if (inputRoofBase)
403 | {
404 | roofBaseTexture = EditorGUILayout.ObjectField(roofBaseTexture,
405 | typeof(Texture),
406 | false,
407 | GUILayout.Height(55));
408 | if (roofBaseTexture != null)
409 | _building.roofBaseMaterial = MaterialManager.Instance.
410 | FindByTextureName(roofBaseTexture.name);
411 | }
412 | else
413 | {
414 | _building.roofBaseMaterial = null;
415 | roofBaseTexture = null;
416 | }
417 | EditorGUILayout.EndHorizontal();
418 | }
419 |
420 | private string GetFullType (myRType t)
421 | {
422 | return "Thesis." + t.ToString() + "Roof,Assembly-CSharp-firstpass";
423 | }
424 | }
--------------------------------------------------------------------------------
/Assets/Standard Assets/Building/Face.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using UnityEngine;
3 | using System.Reflection;
4 | using System.Collections.Generic;
5 |
6 | namespace Thesis {
7 |
8 | public class Face : DrawableObject
9 | {
10 | /*************** FIELDS ***************/
11 |
12 | public readonly BuildingMesh parentBuilding;
13 |
14 | public Vector3 normal;
15 |
16 | public Vector3 right;
17 |
18 | public float width;
19 |
20 | ///
21 | /// A list containing all of the components attached to this face.
22 | ///
23 | public List faceComponents = new List();
24 |
25 | ///
26 | /// The number of the components on each floor.
27 | ///
28 | public int componentsPerFloor = 0;
29 |
30 | ///
31 | /// The sum of the components on each floor times two.
32 | /// Helps with the calculation of the vertices' indexes and triangles.
33 | ///
34 | public int verticesPerRow = 0;
35 |
36 | ///
37 | /// The number of vertices on the face's vertical edges, including
38 | /// the boundaries.
39 | ///
40 | public int edgeVerticesCount = 0;
41 |
42 | ///
43 | /// Maps the position (index) of one component to its type.
44 | /// The indexing starts from the bottom right corner and goes
45 | /// to the left and then up.
46 | ///
47 | public Dictionary pattern = new Dictionary();
48 |
49 | public List doorIndexes = new List();
50 |
51 | public List balconyIndexes = new List();
52 |
53 | private bool _isFree;
54 |
55 | public Building masterParent
56 | {
57 | get { return parentBuilding.parent; }
58 | }
59 |
60 | /*************** CONSTRUCTORS ***************/
61 |
62 | ///
63 | /// Initializes a new instance of the class from the given points,
64 | /// in clockwise order. The clockwise order is required so that the normal of this face
65 | /// is properly calculated.
66 | ///
67 | public Face (BuildingMesh parent, Vector3 dr, Vector3 dl, bool isFree = true)
68 | {
69 | parentBuilding = parent;
70 | _isFree = isFree;
71 |
72 | boundaries = new Vector3[4];
73 | boundaries[0] = dr;
74 | boundaries[1] = dl;
75 | boundaries[2] = new Vector3(dl.x, dl.y + parentBuilding.height, dl.z);
76 | boundaries[3] = new Vector3(dr.x, dr.y + parentBuilding.height, dr.z);
77 |
78 | right = new Vector3(boundaries[0].x - boundaries[1].x,
79 | 0f,
80 | boundaries[0].z - boundaries[1].z);
81 | width = right.magnitude;
82 | normal = Vector3.Cross(Vector3.up, right);
83 |
84 | right.Normalize();
85 | normal.Normalize();
86 | }
87 |
88 | /*************** METHODS ***************/
89 |
90 | public void ConstructFaceComponents (float component_width, float inbetween_space)
91 | {
92 | if (!_isFree)
93 | {
94 | componentsPerFloor = 0;
95 | return;
96 | }
97 |
98 | float lim = 1.75f;
99 | if (masterParent.componentDistance <= 0f)
100 | componentsPerFloor = Mathf.CeilToInt(width / (component_width + inbetween_space));
101 | else
102 | {
103 | componentsPerFloor = Mathf.CeilToInt(width / (component_width + masterParent.componentDistance));
104 | lim = masterParent.componentDistance;
105 | }
106 | float fixed_space = (width - componentsPerFloor * component_width) / (componentsPerFloor + 1);
107 | while (fixed_space < lim)
108 | {
109 | componentsPerFloor -= 1;
110 | fixed_space = (width - componentsPerFloor * component_width) / (componentsPerFloor + 1);
111 | }
112 |
113 | if (componentsPerFloor == 0)
114 | return;
115 |
116 | if (parentBuilding.faces[0] == this)
117 | FindDoorIndexes();
118 | FindBalconyIndexes();
119 |
120 | float offset;
121 | int index;
122 | Vector3 dr, dl;
123 | ConstructorInfo[] ctors;
124 | for (int floor = 0; floor < parentBuilding.floorCount; ++floor)
125 | {
126 | offset = fixed_space;
127 | for (int component = 0; component < componentsPerFloor; ++component)
128 | {
129 | index = floor * componentsPerFloor + component;
130 | dr = boundaries[0] - right * offset + floor * parentBuilding.floorHeight * Vector3.up;
131 | dl = dr - right * component_width;
132 | offset += component_width;
133 | if (!pattern.ContainsKey(index))
134 | pattern[index] = typeof(Window);
135 |
136 | ctors = pattern[index].GetConstructors(BindingFlags.Instance | BindingFlags.Public);
137 | faceComponents.Add((FaceComponent) ctors[0].Invoke(new object[] { this, dr, dl, IndexToCoordinate(index) }));
138 |
139 | offset += fixed_space;
140 | }
141 | }
142 | }
143 |
144 | public override void FindVertices ()
145 | {
146 | if (componentsPerFloor == 0)
147 | {
148 | edgeVerticesCount = boundaries.Length;
149 | vertices = boundaries;
150 | return;
151 | }
152 |
153 | edgeVerticesCount = 2 * (parentBuilding.floorCount + 1);
154 | vertices = new Vector3[8 * componentsPerFloor * parentBuilding.floorCount + edgeVerticesCount];
155 |
156 | for (int i = 0; i < edgeVerticesCount; i += 2)
157 | {
158 | vertices[i] = boundaries[0] + (i / 2) * parentBuilding.floorHeight * Vector3.up;
159 | vertices[i + 1] = boundaries[1] + (i / 2) * parentBuilding.floorHeight * Vector3.up;
160 | }
161 |
162 | int double_cpf = 2 * componentsPerFloor;
163 | for (var floor = 1; floor <= parentBuilding.floorCount; ++floor)
164 | for (var cp = 0; cp < componentsPerFloor; ++cp)
165 | {
166 | int cpn = cp + componentsPerFloor * (floor - 1);
167 | int indexModifier = 8 * componentsPerFloor * (floor - 1) + 2 * cp + edgeVerticesCount;
168 |
169 | vertices[indexModifier] = new Vector3(
170 | faceComponents[cpn].boundaries[0].x,
171 | parentBuilding.boundaries[0].y + (floor - 1) * parentBuilding.floorHeight,
172 | faceComponents[cpn].boundaries[0].z);
173 |
174 | vertices[indexModifier + 1] = new Vector3(
175 | faceComponents[cpn].boundaries[1].x,
176 | parentBuilding.boundaries[0].y + (floor - 1) * parentBuilding.floorHeight,
177 | faceComponents[cpn].boundaries[1].z);
178 |
179 | vertices[indexModifier + double_cpf] = faceComponents[cpn].boundaries[0];
180 |
181 | vertices[indexModifier + double_cpf + 1] = faceComponents[cpn].boundaries[1];
182 |
183 | vertices[indexModifier + 2 * double_cpf] = faceComponents[cpn].boundaries[3];
184 |
185 | vertices[indexModifier + 2 * double_cpf + 1] = faceComponents[cpn].boundaries[2];
186 |
187 | vertices[indexModifier + 3 * double_cpf] = new Vector3(
188 | faceComponents[cpn].boundaries[3].x,
189 | floor * parentBuilding.floorHeight - parentBuilding.meshOrigin.y,
190 | faceComponents[cpn].boundaries[3].z);
191 |
192 | vertices[indexModifier + 3 * double_cpf + 1] = new Vector3(
193 | faceComponents[cpn].boundaries[2].x,
194 | floor * parentBuilding.floorHeight - parentBuilding.meshOrigin.y,
195 | faceComponents[cpn].boundaries[2].z);
196 | }
197 | }
198 |
199 | private void FindDoorIndexes ()
200 | {
201 | switch (componentsPerFloor)
202 | {
203 | case 1:
204 | doorIndexes.Add(0);
205 | break;
206 |
207 | case 2:
208 | doorIndexes.Add(Util.RollDice(new float[] { 0.5f, 0.5f }, new int[] { 0, 1 }));
209 | break;
210 |
211 | case 3:
212 | doorIndexes.Add(1);
213 | break;
214 |
215 | case 4:
216 | doorIndexes.Add(Util.RollDice(new float[] { 0.5f, 0.5f }, new int[] { 0, 3 }));
217 | break;
218 |
219 | case 5:
220 | if (Util.RollDice(new float[] { 0.2f, 0.8f }, new int[] { 1, 2 }) == 1)
221 | doorIndexes.Add(2);
222 | else
223 | doorIndexes.AddRange(new int[] { 0, 4 });
224 | break;
225 |
226 | default:
227 | if (Util.RollDice(new float[] { 0.2f, 0.8f }, new int[] { 1, 2 }) == 1)
228 | {
229 | if (componentsPerFloor % 2 == 0)
230 | doorIndexes.Add(Util.RollDice(new float[] { 0.5f, 0.5f }, new int[] { 0, componentsPerFloor - 1 }));
231 | else
232 | doorIndexes.Add((componentsPerFloor - 1) / 2);
233 | }
234 | else
235 | doorIndexes.AddRange(new int[] { 0, componentsPerFloor - 1 });
236 | break;
237 | }
238 |
239 | foreach (int index in doorIndexes)
240 | pattern[index] = typeof(Door);
241 | }
242 |
243 | private void FindBalconyIndexes ()
244 | {
245 | int dice;
246 |
247 | switch (parentBuilding.floorCount)
248 | {
249 | // two floors
250 | case 2:
251 | switch (componentsPerFloor)
252 | {
253 | case 1:
254 | break;
255 |
256 | case 2:
257 | break;
258 |
259 | case 3:
260 | if (doorIndexes.Count > 0)
261 | balconyIndexes.Add(doorIndexes[0] + componentsPerFloor);
262 | else if (Util.RollDice(new float[] { 0.3f, 0.7f }) == 1)
263 | balconyIndexes.Add(4);
264 | break;
265 |
266 | case 4:
267 | dice = Util.RollDice(new float[] { 0.3f, 0.4f, 0.3f });
268 | if (dice == 1)
269 | balconyIndexes.AddRange(new int[] { 5, 6 });
270 | else if (dice == 2)
271 | balconyIndexes.AddRange(new int[] { 4, 7 });
272 | break;
273 |
274 | case 5:
275 | dice = Util.RollDice(new float[] { 0.25f, 0.25f, 0.25f, 0.25f });
276 | switch (dice)
277 | {
278 | case 1:
279 | balconyIndexes.AddRange(new int[] { 5, 7, 9 });
280 | break;
281 |
282 | case 2:
283 | balconyIndexes.AddRange(new int[] { 5, 9 });
284 | break;
285 |
286 | case 3:
287 | balconyIndexes.AddRange(new int[] { 6, 7, 8 });
288 | break;
289 |
290 | default:
291 | break;
292 | }
293 | break;
294 |
295 | case 6:
296 | balconyIndexes.AddRange(new int[] { 8, 9 });
297 | if (Util.RollDice(new float[] { 0.3f, 0.7f }) == 1)
298 | balconyIndexes.AddRange(new int[] { 6, 11 });
299 | break;
300 |
301 | case 7:
302 | balconyIndexes.AddRange(new int[] { 9, 10, 11 });
303 | if (Util.RollDice(new float[] { 0.3f, 0.7f }) == 1)
304 | balconyIndexes.AddRange(new int[] { 7, 13 });
305 | break;
306 |
307 | default:
308 | if (componentsPerFloor % 2 == 0)
309 | {
310 | var mid = componentsPerFloor + componentsPerFloor / 2 - 1;
311 | balconyIndexes.AddRange(new int[] { mid - 1, mid, mid + 1, mid + 2 });
312 | if (Util.RollDice(new float[] { 0.3f, 0.7f }) == 1)
313 | balconyIndexes.AddRange(new int[] { componentsPerFloor, 2 * componentsPerFloor - 1 });
314 | }
315 | else
316 | {
317 | var mid = componentsPerFloor + (componentsPerFloor - 1) / 2;
318 | balconyIndexes.AddRange(new int[] { mid - 1, mid, mid + 1 });
319 | if (Util.RollDice(new float[] { 0.5f, 0.5f }) == 1)
320 | balconyIndexes.AddRange(new int[] { mid - 2, mid + 2 });
321 | if (Util.RollDice(new float[] { 0.3f, 0.7f }) == 1)
322 | balconyIndexes.AddRange(new int[] { componentsPerFloor, 2 * componentsPerFloor - 1 });
323 | }
324 | break;
325 | }
326 | break;
327 |
328 | // three floors
329 | case 3:
330 | switch (componentsPerFloor)
331 | {
332 | case 1:
333 | break;
334 |
335 | case 2:
336 | break;
337 |
338 | case 3:
339 | dice = Util.RollDice(new float[] { 0.5f, 0.25f, 0.25f });
340 | if (doorIndexes.Count > 0)
341 | balconyIndexes.Add(4);
342 | switch (dice)
343 | {
344 | case 1:
345 | balconyIndexes.Add(7);
346 | break;
347 |
348 | case 2:
349 | balconyIndexes.AddRange(new int[] { 6, 8 });
350 | break;
351 |
352 | default:
353 | break;
354 | }
355 | break;
356 |
357 | case 4:
358 | dice = Util.RollDice(new float[] { 0.33f, 0.34f, 0.33f });
359 | switch (dice)
360 | {
361 | case 1:
362 | balconyIndexes.AddRange(new int[] { 5, 6 });
363 | break;
364 |
365 | case 2:
366 | balconyIndexes.AddRange(new int[] { 9, 10 });
367 | break;
368 |
369 | case 3:
370 | balconyIndexes.AddRange(new int[] { 5, 6, 9, 10 });
371 | break;
372 | }
373 | break;
374 |
375 | case 5:
376 | dice = Util.RollDice(new float[] { 0.2f, 0.2f, 0.2f, 0.2f, 0.2f });
377 | switch (dice)
378 | {
379 | case 1:
380 | balconyIndexes.AddRange(new int[] { 6, 7, 8 });
381 | break;
382 |
383 | case 2:
384 | balconyIndexes.AddRange(new int[] { 11, 12, 13 });
385 | break;
386 |
387 | case 3:
388 | balconyIndexes.AddRange(new int[] { 6, 7, 8, 11, 12, 13 });
389 | break;
390 |
391 | case 4:
392 | balconyIndexes.AddRange(new int[] { 6, 8, 11, 12, 13 });
393 | break;
394 |
395 | case 5:
396 | balconyIndexes.AddRange(new int[] { 5, 9, 11, 12, 13 });
397 | break;
398 | }
399 | break;
400 |
401 | case 6:
402 | balconyIndexes.AddRange(new int[] { 8, 9, 14, 15 });
403 | dice = Util.RollDice(new float[] { 0.3f, 0.3f, 0.4f });
404 | if (dice == 1)
405 | balconyIndexes.AddRange(new int[] { 6, 11 });
406 | if (dice == 2)
407 | balconyIndexes.AddRange(new int[] { 12, 13 });
408 | if (dice == 3)
409 | balconyIndexes.AddRange(new int[] { 6, 11, 12, 13 });
410 | break;
411 |
412 | case 7:
413 | balconyIndexes.AddRange(new int[] { 9, 10, 11, 16, 17, 18 });
414 | dice = Util.RollDice(new float[] { 0.3f, 0.7f });
415 | if (dice == 1)
416 | balconyIndexes.AddRange(new int[] { 7, 13 });
417 | if (dice == 2)
418 | balconyIndexes.AddRange(new int[] { 14, 20 });
419 | if (dice == 3)
420 | balconyIndexes.AddRange(new int[] { 7, 13, 14, 20 });
421 | break;
422 |
423 | default:
424 | break;
425 | }
426 | break;
427 |
428 | default:
429 | break;
430 | }
431 |
432 | foreach (int index in balconyIndexes)
433 | pattern[index] = typeof(Balcony);
434 | }
435 |
436 | public ComponentCoordinate IndexToCoordinate (int index)
437 | {
438 | return new ComponentCoordinate(index / componentsPerFloor,
439 | index % componentsPerFloor);
440 | }
441 |
442 | public override void Destroy()
443 | {
444 | base.Destroy();
445 |
446 | foreach (FaceComponent fc in faceComponents)
447 | fc.Destroy();
448 | }
449 | }
450 |
451 | } // namespace Thesis
--------------------------------------------------------------------------------
/Assets/Standard Assets/Managers/TextureManager.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using UnityEngine;
3 |
4 | using Object = UnityEngine.Object;
5 |
6 | namespace Thesis {
7 |
8 | public sealed class TextureManager
9 | {
10 | private static readonly TextureManager _instance = new TextureManager();
11 | public static TextureManager Instance
12 | {
13 | get { return _instance; }
14 | }
15 |
16 | private static bool _isInitialized;
17 |
18 | private Dictionary _textures;
19 |
20 | private Dictionary> _collections;
21 |
22 | private TextureManager ()
23 | {
24 | _textures = new Dictionary();
25 | _collections = new Dictionary>();
26 | _isInitialized = false;
27 | }
28 |
29 | public void Init ()
30 | {
31 | if (!_isInitialized)
32 | {
33 | Object[] texs = Resources.LoadAll("Textures/Door",
34 | typeof(Texture2D));
35 | for (var i = 0; i < texs.Length; ++i)
36 | AddToCollection("tex_door",
37 | new ProceduralTexture((Texture2D) texs[i]));
38 |
39 | texs = Resources.LoadAll("Textures/Shutter",
40 | typeof(Texture2D));
41 | for (var i = 0; i < texs.Length; ++i)
42 | AddToCollection("tex_shutter",
43 | new ProceduralTexture((Texture2D) texs[i]));
44 |
45 | texs = Resources.LoadAll("Textures/Roof",
46 | typeof(Texture2D));
47 | for (var i = 0; i < texs.Length; ++i)
48 | AddToCollection("tex_roof",
49 | new ProceduralTexture((Texture2D) texs[i]));
50 |
51 | texs = Resources.LoadAll("Textures/RoofBase",
52 | typeof(Texture2D));
53 | for (var i = 0; i < texs.Length; ++i)
54 | AddToCollection("tex_roof_base",
55 | new ProceduralTexture((Texture2D) texs[i]));
56 |
57 | texs = Resources.LoadAll("Textures/RoofDecor",
58 | typeof(Texture2D));
59 | for (var i = 0; i < texs.Length; ++i)
60 | AddToCollection("tex_roof_decor",
61 | new ProceduralTexture((Texture2D) texs[i]));
62 |
63 | texs = Resources.LoadAll("Textures/CompDecor",
64 | typeof(Texture2D));
65 | for (var i = 0; i < texs.Length; ++i)
66 | AddToCollection("tex_comp_decor",
67 | new ProceduralTexture((Texture2D) texs[i]));
68 |
69 | texs = Resources.LoadAll("Textures/CompDecorSimple",
70 | typeof(Texture2D));
71 | for (var i = 0; i < texs.Length; ++i)
72 | AddToCollection("tex_comp_decor_simple",
73 | new ProceduralTexture((Texture2D) texs[i]));
74 |
75 | CreateBalconyRailTexture();
76 | CreateWindowTextures();
77 | CreateBalconyBodyTextures();
78 |
79 | _isInitialized = true;
80 | }
81 | }
82 |
83 | public void Unload ()
84 | {
85 | _textures.Clear();
86 | foreach (List l in _collections.Values)
87 | l.Clear();
88 | _collections.Clear();
89 | _isInitialized = false;
90 | }
91 |
92 | public void Add (string name, ProceduralTexture texture)
93 | {
94 | if (!_textures.ContainsKey(name))
95 | {
96 | texture.content.name = name;
97 | _textures.Add(name, texture);
98 | }
99 | }
100 |
101 | public void AddToCollection (string name, ProceduralTexture texture)
102 | {
103 | if (_collections.ContainsKey(name))
104 | {
105 | texture.content.name = name + "_" + (_collections[name].Count + 1).ToString();
106 | _collections[name].Add(texture);
107 | }
108 | else
109 | {
110 | var list = new List();
111 | texture.content.name = name + "_1";
112 | list.Add(texture);
113 | _collections.Add(name, list);
114 | }
115 | }
116 |
117 | public void Set (string name, ProceduralTexture texture)
118 | {
119 | if (_textures.ContainsKey(name))
120 | _textures[name] = texture;
121 | }
122 |
123 | public ProceduralTexture Get (string name)
124 | {
125 | return _textures.ContainsKey(name) ? _textures[name] : null;
126 | }
127 |
128 | public List GetCollection (string name)
129 | {
130 | return _collections.ContainsKey(name) ? _collections[name] : null;
131 | }
132 |
133 | private void CreateBalconyRailTexture ()
134 | {
135 | var tex = new ProceduralTexture();
136 | tex.content = new Texture2D(1024, 512);
137 | tex.Clear();
138 |
139 | var ratio = 2f;
140 | var outBorderSize = 0.02f;
141 | var inBorderSize = 0.018f;
142 | var spaceBetweenBorders = 0.06f;
143 |
144 | int vOutBorderWidth = Mathf.FloorToInt(tex.content.width * outBorderSize);
145 | int topOutBorderWidth = Mathf.FloorToInt(tex.content.height * outBorderSize * 2 * ratio);
146 | int vInBorderWidth = Mathf.FloorToInt(tex.content.width * inBorderSize);
147 | int hInBorderWidth = Mathf.FloorToInt(tex.content.height * inBorderSize * ratio);
148 | int vInBorderOffset = Mathf.FloorToInt(tex.content.width * spaceBetweenBorders) +
149 | vOutBorderWidth;
150 | int botInBorderOffset = Mathf.FloorToInt(tex.content.height * spaceBetweenBorders * ratio);
151 |
152 | var halfWidth = tex.content.width >> 1;
153 |
154 | int topOutBorderY = tex.content.height - (topOutBorderWidth >> 1);
155 | int botInBorderY = botInBorderOffset + (hInBorderWidth >> 1);
156 | int topInBorderY = tex.content.height - botInBorderY - topOutBorderWidth;
157 | int leftOutBorderX = (vOutBorderWidth >> 1) - 1;
158 | int rightOutBorderX = tex.content.width - leftOutBorderX;
159 | int leftInBorderX = vInBorderOffset + (vInBorderWidth >> 1);
160 | int rightInBorderX = tex.content.width - leftInBorderX;
161 |
162 | // top out border
163 | tex.lines.Add(new TextureLine(0, topOutBorderY,
164 | tex.content.width, topOutBorderY,
165 | Color.black, topOutBorderWidth));
166 | // bot in border
167 | tex.lines.Add(new TextureLine(0, botInBorderY,
168 | tex.content.width, botInBorderY,
169 | Color.black, hInBorderWidth));
170 | // top in border
171 | tex.lines.Add(new TextureLine(0, topInBorderY,
172 | tex.content.width, topInBorderY,
173 | Color.black, hInBorderWidth));
174 | // left out border
175 | tex.lines.Add(new TextureLine(leftOutBorderX, 0,
176 | leftOutBorderX, tex.content.height,
177 | Color.black, vOutBorderWidth));
178 | // right out border
179 | tex.lines.Add(new TextureLine(rightOutBorderX, 0,
180 | rightOutBorderX, tex.content.height,
181 | Color.black, vOutBorderWidth));
182 | // left in border
183 | tex.lines.Add(new TextureLine(leftInBorderX, 0,
184 | leftInBorderX, tex.content.width,
185 | Color.black, vInBorderWidth));
186 | // right in border
187 | tex.lines.Add(new TextureLine(rightInBorderX, 0,
188 | rightInBorderX, tex.content.width,
189 | Color.black, vInBorderWidth));
190 | // middle border
191 | tex.lines.Add(new TextureLine(halfWidth, 0,
192 | halfWidth, tex.content.height,
193 | Color.black, vInBorderWidth));
194 | // left inner box
195 | tex.lines.Add(new TextureLine(leftInBorderX, botInBorderY + 2,
196 | halfWidth + 1, topInBorderY,
197 | Color.black, vInBorderWidth));
198 |
199 | tex.lines.Add(new TextureLine(leftInBorderX, topInBorderY - 1,
200 | halfWidth + 1, botInBorderY,
201 | Color.black, vInBorderWidth));
202 | // right inner box
203 | tex.lines.Add(new TextureLine(halfWidth + 1, botInBorderY,
204 | rightInBorderX, topInBorderY,
205 | Color.black, vInBorderWidth));
206 |
207 | tex.lines.Add(new TextureLine(halfWidth + 1, topInBorderY,
208 | rightInBorderX, botInBorderY,
209 | Color.black, vInBorderWidth));
210 |
211 | tex.Draw();
212 |
213 | TextureManager.Instance.Add("tex_balcony", tex);
214 | }
215 |
216 | private void CreateWindowTextures ()
217 | {
218 | var color = Color.white;
219 | var th = 22;
220 | ProceduralTexture tex;
221 | int h;
222 |
223 | // 1st texture
224 | tex = new ProceduralTexture(512, 1024);
225 | tex.SetBackgroundColor(new Color32(25, 0, 143, 255));
226 | AddBorders(ref tex, color, th);
227 | h = (tex.content.height * 3) >> 2;
228 | tex.lines.Add(new TextureLine(0, h, tex.content.width, h,
229 | color, th));
230 | tex.lines.Add(new TextureLine(tex.content.width >> 1, 0,
231 | tex.content.width >> 1, h,
232 | color, th << 1));
233 | tex.Draw();
234 | TextureManager.Instance.AddToCollection("tex_window", tex);
235 | // 1st texture
236 |
237 | // 2nd texture
238 | tex = new ProceduralTexture(512, 1024);
239 | tex.SetBackgroundColor(new Color32(25, 0, 143, 255));
240 | AddBorders(ref tex, color, th);
241 | h = (tex.content.height * 3) >> 2;
242 | tex.lines.Add(new TextureLine(0, h, tex.content.width, h,
243 | color, th));
244 | tex.lines.Add(new TextureLine(tex.content.width >> 1, 0,
245 | tex.content.width >> 1, h,
246 | color, th << 1));
247 | tex.lines.Add(new TextureLine(0, h >> 1, tex.content.width, h >> 1,
248 | color, th));
249 | tex.Draw();
250 | TextureManager.Instance.AddToCollection("tex_window", tex);
251 | // 2nd texture
252 |
253 | // 3rd texture
254 | tex = new ProceduralTexture(512, 1024);
255 | tex.SetBackgroundColor(new Color32(25, 0, 143, 255));
256 | AddBorders(ref tex, color, th);
257 | AddBalancedLines(ref tex, 2, color, th);
258 | tex.lines.Add(new TextureLine(tex.content.width >> 1, 0,
259 | tex.content.width >> 1, tex.content.height,
260 | color, th << 1));
261 | tex.Draw();
262 | TextureManager.Instance.AddToCollection("tex_window", tex);
263 | // 3rd texture
264 |
265 | // 4th texture
266 | tex = new ProceduralTexture(512, 1024);
267 | tex.SetBackgroundColor(new Color32(25, 0, 143, 255));
268 | AddBorders(ref tex, color, th);
269 | AddBalancedLines(ref tex, 3, color, th);
270 | tex.lines.Add(new TextureLine(tex.content.width >> 1, 0,
271 | tex.content.width >> 1, (tex.content.height * 3) >> 2,
272 | color, th << 1));
273 | tex.Draw();
274 | TextureManager.Instance.AddToCollection("tex_window", tex);
275 | // 4th texture
276 |
277 | // 5th texture
278 | tex = new ProceduralTexture(512, 1024);
279 | tex.SetBackgroundColor(new Color32(25, 0, 143, 255));
280 | AddBorders(ref tex, color, th);
281 | AddBalancedLines(ref tex, 3, color, th);
282 | tex.lines.Add(new TextureLine(tex.content.width >> 1, 0,
283 | tex.content.width >> 1, tex.content.height,
284 | color, th << 1));
285 | tex.Draw();
286 | TextureManager.Instance.AddToCollection("tex_window", tex);
287 | // 5th texture
288 | }
289 |
290 | private void CreateBalconyBodyTextures ()
291 | {
292 | var color = Color.white;
293 | var th = 22;
294 | ProceduralTexture tex;
295 | int h;
296 |
297 | // 1st texture
298 | tex = new ProceduralTexture(512, 1024);
299 | tex.SetBackgroundColor(new Color32(25, 0, 143, 255));
300 | AddBorders(ref tex, color, th);
301 | h = (tex.content.height * 3) >> 2;
302 | tex.lines.Add(new TextureLine(0, h, tex.content.width, h,
303 | color, th));
304 | tex.lines.Add(new TextureLine(tex.content.width >> 1, 0,
305 | tex.content.width >> 1, h,
306 | color, th << 1));
307 | tex.Draw();
308 | TextureManager.Instance.AddToCollection("tex_balcony_door", tex);
309 | // 1st texture
310 |
311 | // 2nd texture
312 | tex = new ProceduralTexture(512, 1024);
313 | tex.SetBackgroundColor(new Color32(25, 0, 143, 255));
314 | AddBorders(ref tex, color, th);
315 | h = (tex.content.height * 3) >> 2;
316 | tex.lines.Add(new TextureLine(0, h, tex.content.width, h,
317 | color, th));
318 | tex.lines.Add(new TextureLine(tex.content.width >> 1, 0,
319 | tex.content.width >> 1, h,
320 | color, th << 1));
321 | tex.lines.Add(new TextureLine(0, h >> 1, tex.content.width, h >> 1,
322 | color, th));
323 | tex.Draw();
324 | TextureManager.Instance.AddToCollection("tex_balcony_door", tex);
325 | // 2nd texture
326 |
327 | // 3rd texture
328 | tex = new ProceduralTexture(512, 1024);
329 | tex.SetBackgroundColor(new Color32(25, 0, 143, 255));
330 | AddBorders(ref tex, color, th);
331 | AddBalancedLines(ref tex, 3, color, th);
332 | tex.lines.Add(new TextureLine(tex.content.width >> 1, 0,
333 | tex.content.width >> 1, tex.content.height,
334 | color, th << 1));
335 | tex.Draw();
336 | TextureManager.Instance.AddToCollection("tex_balcony_door", tex);
337 | // 3rd texture
338 |
339 | // 4th texture
340 | tex = new ProceduralTexture(512, 1024);
341 | tex.SetBackgroundColor(new Color32(25, 0, 143, 255));
342 | AddBorders(ref tex, color, th);
343 | AddBalancedLines(ref tex, 4, color, th);
344 | tex.lines.Add(new TextureLine(tex.content.width >> 1, 0,
345 | tex.content.width >> 1, (tex.content.height << 2) / 5,
346 | color, th << 1));
347 | tex.Draw();
348 | TextureManager.Instance.AddToCollection("tex_balcony_door", tex);
349 | // 4th texture
350 |
351 | // 5th texture
352 | tex = new ProceduralTexture(512, 1024);
353 | tex.SetBackgroundColor(new Color32(25, 0, 143, 255));
354 | AddBorders(ref tex, color, th);
355 | AddBalancedLines(ref tex, 4, color, th);
356 | tex.lines.Add(new TextureLine(tex.content.width >> 1, 0,
357 | tex.content.width >> 1, tex.content.height,
358 | color, th << 1));
359 | tex.Draw();
360 | TextureManager.Instance.AddToCollection("tex_balcony_door", tex);
361 | // 5th texture
362 | }
363 |
364 | private void AddBorders (ref ProceduralTexture tex, Color color, int thickness)
365 | {
366 | tex.lines.Add(new TextureLine(thickness >> 1, 0,
367 | thickness >> 1, tex.content.height,
368 | color, thickness));
369 | tex.lines.Add(new TextureLine(0, thickness >> 1,
370 | tex.content.width, thickness >> 1,
371 | color, thickness));
372 | tex.lines.Add(new TextureLine(tex.content.width - (thickness >> 1), 0,
373 | tex.content.width - (thickness >> 1), tex.content.height,
374 | color, thickness));
375 | tex.lines.Add(new TextureLine(0, tex.content.height - (thickness >> 1),
376 | tex.content.width, tex.content.height - (thickness >> 1),
377 | color, thickness));
378 | }
379 |
380 | private void AddBalancedLines (ref ProceduralTexture tex, int count,
381 | Color color, int thickness)
382 | {
383 | int interval = tex.content.height / (count + 1);
384 | int h = 0;
385 | for (int i = 0; i < count; ++i)
386 | {
387 | h+= interval;
388 | tex.lines.Add(new TextureLine(0, h,
389 | tex.content.width, h,
390 | color, thickness));
391 | }
392 | }
393 | }
394 |
395 | } // namespace Thesis
--------------------------------------------------------------------------------