1 /**
2  * Copyright:       Copyright (C) 2018 Gabriel Gheorghe, All Rights Reserved
3  * Authors:         $(Gabriel Gheorghe)
4  * License:         $(LINK2 https://www.gnu.org/licenses/gpl-3.0.txt, GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007)
5  * Source
6  * Documentation:
7  * Coverage:
8  */
9 module liberty.core.scenegraph.scene;
10 import liberty.core.engine: CoreEngine;
11 import liberty.core.scenegraph.services: Startable, Updatable, Processable;
12 import liberty.core.scenegraph.node: Node, Root;
13 import liberty.core.scenegraph.camera: Camera;
14 import liberty.graphics.renderer: Renderable;
15 import liberty.math.vector: Vector3F;
16 ///
17 struct SceneSettings {
18 	///
19 	Vector3F startPoint;
20 }
21 ///
22 final class Scene {
23 	public {
24 	    Startable[string] startList;
25 	    Updatable[string] updateList;
26 	    Processable[string] processList;
27 	    Renderable[string] renderList;
28 	    static Renderable[string] shaderList;
29 	}
30     package {
31         bool[string] _ids;
32     }
33     private {
34         string _id;
35         SceneSettings _settings;
36         Node _tree;
37         Camera _activeCamera;
38         Camera[string] _cameras;
39         bool _registered;
40     }
41     /// Default contrctor.
42     this(string id) {
43         CoreEngine.get.activeScene = this;
44         _tree = new Root();
45         _id = id;
46     }
47     /// Returns scene ID.
48     string id() pure nothrow const {
49         return _id;
50     }
51     /// Returns if scene is ready to run.
52     bool isRegistered() pure nothrow const {
53         return _registered;
54     }
55     /// Returns scene settings.
56     ref const(SceneSettings) settings() pure nothrow const {
57         return _settings;
58     }
59     /// Returns a scene tree reference.
60     Node tree() pure nothrow {
61         return _tree;
62     }
63     ///
64     //T node(T: Node)(string id) {
65     //    return cast(T)_nodeList[id];
66     //}
67     ///
68     //Node node(string id) {
69     //    return _nodeList[id];
70     //}
71     /// Releases all scene tree nodes.
72     void resetTree() {
73         _tree = new Root();
74     }
75     /// Sets the current camera using its reference.
76     void activeCamera(Camera camera) @property {
77         _activeCamera = camera;
78     }
79     /// Sets the current camera using its ID.
80 	void activeCamera(string id) @property {
81 	    //_activeCamera = node!Camera(id);
82 	}
83 	/// Returns the current camera.
84 	Camera activeCamera() @property {
85 	    return _activeCamera;
86 	}
87 	/// Change view from a camera to another using their references.
88 	void toggleBetweenCameras(Camera camera1, Camera camera2) {
89         if (_activeCamera.id == camera1.id) {
90             _activeCamera = camera2;
91         } else {
92             _activeCamera = camera1;
93         }
94     }
95 	/// Change view from a camera to another using their IDs.
96 	void toggleBetweenCameras(string id1, string id2) {
97 	    if (_activeCamera.id == id1) {
98 	        _activeCamera = _cameras[id2];
99 	    } else {
100 	        _activeCamera = _cameras[id1];
101 	    }
102 	}
103 	///
104 	package void registerCamera(Camera camera) {
105 		_cameras[camera.id] = camera;
106 	}
107 	///
108 	package void clearCamera(Camera camera) {
109 		_cameras.remove(camera.id);
110 		//camera.destroy();
111 		//camera = null;
112 	}
113 	/// Register scene to the CoreEngine.
114 	/// Invoke start for all Startable objects that have an start() method.
115 	void register() {
116 		_registered = true;
117 		foreach (node; startList) {
118 			node.start();
119 		}
120 		if (_activeCamera is null) {
121 			_activeCamera = tree.spawn!Camera("DefaultCamera");
122 		}
123 	}
124 	/// Updates all Updatable objects that have an update() method.
125 	/// It's called every frame.
126 	void update(in float deltaTime) {
127         foreach (node; updateList) {
128             node.update(deltaTime);
129         }
130     }
131     /// Process all Processable objects that have a process() method.
132     /// It's synchronized with PhysicsCoreEngine.
133     void process() {
134         foreach (node; processList) {
135             node.process();
136         }
137     }
138     /// Render all Renderable objects that have a render() method.
139     void render() {
140         foreach (shader; shaderList) {
141             shader.render();
142         }
143         foreach(node; renderList) {
144             node.render();
145         }
146     }
147 }