1 module main;
2 
3 import std.stdio;
4 import derelict.glfw3.glfw3;
5 import Engine.all;
6 import derelict.opengl3.gl;
7 import std.conv;
8 import std.random;
9 import Engine.Material;
10 import Engine.UI.all;
11 import std.math;
12 import std.variant;
13 import Engine.math;
14 
15 
16 Shader shader;
17 Camera camera; 
18 Texture ballTexture;
19 
20 import std.parallelism;
21 
22 class GravitySystem : System {
23     GravityMouse[] components;
24 
25     override void start() {
26         components = new GravityMouse[1000];
27         components.length = 0;    
28     }
29 
30     override void process() {
31 		auto bounds = camera.bounds();
32 		auto mpos = vec3(camera.MouseWorldPosition(),0);
33 		auto delta = Core.DeltaTime;
34 		auto force = GravityMouse.force;
35         foreach(c ; parallel(components)) {
36            c.Step(mpos,force,delta,bounds);
37         }
38     } 
39 
40     override void onEntityEnter(Entity e) {
41         foreach(c ; e.Components) {
42             auto g = (cast(Component)c).Cast!GravityMouse();
43 			if (g)
44 				components ~= g;
45         }
46     }
47 	override void onEntityLeave(Entity e) {
48 		for(int i=0;i<components.length;) {
49             if (components[i].entity == e)
50 			{
51 				components[i] = components[components.length-1];
52 				components.length--;
53 			}
54 			i++;
55         }
56     }
57 }
58 
59 class GravityMouse  {
60 	 mixin ComponentBase;
61 	 vec3 v = vec3(0,0,0);
62 	 static shared float force = 6.674*10e-6;
63 
64 	 enum m1 = 100000;
65 	 enum m2 = 100;
66 			
67 	 void _Update() {
68 		 auto bounds = camera.bounds();
69 		 auto mpos = vec3(camera.MouseWorldPosition(),0);
70 		 auto delta = Core.DeltaTime;
71 		 Step(mpos,force,delta,bounds);
72 	 }
73 
74 	 void Step(vec3 mpos, float mforce, float delta, recti bounds) {
75 		 auto dir = (mpos - transform.position);
76 		 auto dis = (dir.x*dir.x)+(dir.y*dir.y);
77 		 dir.normalize();
78 		 if (dis > 1000) {
79 			v += dir * ((m1/dis) * m2 * mforce);
80 		 } else {
81 			v += dir * ((m1/1000) * m2 * mforce);
82 		 }		
83 
84 		 auto pos = transform.position;
85 		 auto min = bounds.min;
86 		 auto max = bounds.max;
87 
88 		 if (pos.x < min.x) {
89 			 v.x = -v.x/8;
90 			 pos.x = min.x;
91 		 } else if (pos.x > max.x) {
92 			 v.x = -v.x/8;
93 			 pos.x = max.x;
94 		 }
95 		 if (pos.y < min.y) {
96 			 v.y = -v.y/8;
97 			 pos.y = min.y;
98 		 } else if (pos.y > max.y) {
99 			 v.y = -v.y/8;
100 			 pos.y = max.y;
101 		 }
102 		 transform.position = pos;
103 
104 		 transform.position += v  * delta;
105 		 auto sprite = entity.sprite;
106 		 auto v2 = v;
107 		 if (v2.x < 0) v2.x = -v2.x;
108 		 if (v2.y < 0) v2.y = -v2.y;
109 
110 		 if (sprite !is null) {
111 			 sprite.color = vec4((v2.y+2*v2.x)/50, v2.x/50,v2.y/60,1);
112 		 } //else {
113 			// transform.rotation.z = atan2(v.x, v.y) * 180f/PI;
114 		// transform.scale.x = (v2.x+v2.y)/20 + 5;
115 		// transform.scale.y = transform.scale.x;
116 	 }
117 }
118 
119 class InputHandle : Component {
120 	override void Update() {
121 		if (Input.MouseScroll().y > 0)  {
122 			Core.camera.size += 3*Core.DeltaTime;
123 			Core.camera.UpdateResolution();
124 		}	
125 		if (Input.MouseScroll().y < 0) {
126 			Core.camera.size -= 3*Core.DeltaTime;
127 			Core.camera.UpdateResolution();
128 		}
129 		if (Input.KeyDown(Key.A)) {
130 			Core.camera.transform.rotation.y = Core.camera.transform.rotation.y - Core.DeltaTime;
131 		}
132 		if (Input.KeyDown(Key.S)) {
133 			Core.camera.transform.rotation.y = Core.camera.transform.rotation.y - Core.DeltaTime;
134 		}
135 		if (Input.KeyDown(Key.E)) {
136 			GravityMouse.force += GravityMouse.force*Core.DeltaTime*2;
137 		}	
138 		if (Input.KeyDown(Key.R)) {
139 			GravityMouse.force -= GravityMouse.force*Core.DeltaTime*2;
140 		}
141 		if (Input.KeyDown(Key.MOUSE_BUTTON_1)) {
142 		{
143 			auto mpos = vec3(Core.camera.MouseWorldPosition(),0);
144 			for (int i=0;i<20;i++) {
145 				auto ship = new Entity();
146 				ship.AddComponent!(Sprite)(ballTexture);
147 				ship.AddComponent!GravityMouse();
148 				//ship.AddComponent(new GameOfLife());
149 				Core.AddEntity(ship);
150 				ship.transform.scale.x = 10;
151 				ship.transform.scale.y = 10;
152 				ship.transform.rotation = vec3(0,0,0);
153 				ship.transform.position = mpos + vec3(-5+i/2,-5+i/2,0) ;
154 				//ship.transform.position += vec3(0,10000,0);
155 				//ship.transform.position = vec3(uniform(0,Core.width),uniform(0,Core.height),0);
156 				ship.transform.scale = vec3(4, 4, 1);
157 			}		
158 		}
159 		}
160 	}
161 }
162 
163 void main(string[] args) {
164 	try {
165 		run();
166 	}
167 	catch (Exception e) {
168 		writeln(e.msg);
169 		scanf("\n");
170 	}
171 }
172 
173 void run() {
174 	Core.Start();
175 
176 	Font t = new Font("./public/arial.ttf\0", 32, Font.ASCII);
177 	ballTexture = new Texture("./public/sprite.png\0");
178 	ballTexture.SetFiltering(GL_LINEAR,GL_LINEAR);
179 
180 	Core.AddSystem(new GravitySystem());
181 
182 	auto mmouse = new Entity();
183 	//mmouse.AddComponent!(Sprite)(ballTexture);
184 	mmouse.transform.scale = vec3(100, 100, 1);
185 					
186 	float entities = 100000/3;
187 	float m = sqrt(entities/(Core.width*Core.height));
188 	for (int x=0;x<Core.width*m;x++) {
189 		for (int y=0;y<Core.height*m;y++) {
190 			auto ship = new Entity();
191 			ship.AddComponent!(Sprite)(ballTexture);
192 			ship.AddComponent!(GravityMouse)();
193 			ship.name = to!string(x);
194 			ship.transform.position = vec3(x/m,y/m,0);
195 			ship.transform.scale = vec3(4, 4, 1);
196 			Core.AddEntity(ship);
197 		}
198 	}
199 
200 	for (int i=0;i<10;i++) {
201 		auto e2 = new Entity();
202 		e2.transform.scale.x = 32;
203 		e2.transform.scale.y = 32;
204 		e2.AddComponent!GravityMouse();
205 		e2.transform.position = vec3(((i%100)*10)%Core.width,(i*25)%Core.height,0);
206 		e2.AddComponent!Label(t,to!string(i));
207 		Core.AddEntity(e2);	
208 	}
209 
210 	auto cam = new Entity();
211 	camera = cam.AddComponent(new Camera());
212 	cam.AddComponent(new InputHandle());
213 	Core.AddEntity(cam);
214 	Core.camera = cam.GetComponent!Camera();
215 
216 	cam.transform.position = vec3(Core.width/2,+Core.height/2,0);
217 	
218 	auto e3 = new Entity();
219 	e3.transform.scale.x = 32;
220 	e3.transform.scale.y = 32;
221 	e3.transform.position = vec3(100,Core.height-50,0);
222 	auto fps = e3.AddComponent!Label(t,"FPS");
223 	Core.AddEntity(e3);	
224 
225 	StartCoroutine( {
226 		float time = 0;
227 		int frames = 0;
228 		while (true) {
229 			time += Core.DeltaTime;
230 			frames++;
231 			if (time >= 1) {
232 				fps.SetText("FPS: " ~ to!string(frames) ~ " Entities:" ~ to!string(Core.EntitiesCount) );
233 				writeln(to!string(frames));
234 				time -= 1;
235 				frames = 0;
236 			}	
237 			auto camRect = Core.camera.bounds();
238 			fps.entity.transform.position = vec3((camRect.max.x+camRect.min.x) / 2, camRect.max.y - 50*Core.camera.size,0);
239 			fps.entity.transform.scale = vec3(1,1,1) * Core.camera.size * 34;
240 			mmouse.transform.position = vec3(Core.camera.MouseWorldPosition(),0);
241 
242 			Coroutine.yield();
243 		}
244 	});
245 	/*
246 	StartCoroutine( {
247 		auto sprite = mmouse.GetComponent!Sprite();
248 		auto dTexture = new DynamicTexture(sprite.material.texture);
249 		float t = 0;
250 		while (true) {
251 			if (sprite.color.r > 1)
252 				sprite.color.r = 0;
253 
254 			alias Vector!(ubyte,4) color;
255 
256 			dTexture.Update!(color)((pixels){
257 				for (int i=0;i<pixels.length;i++) {
258 					pixels[i].r = cast(ubyte)(i + t);
259 					pixels[i].g = cast(ubyte)(i + t);
260 					pixels[i].b = 0xff;
261 					pixels[i].a = 0xff;
262 				}
263 			});
264 			t += Core.DeltaTime*1000;
265 			//sprite.color.r += 0.1;
266 			Coroutine.yield();
267 		}
268 	});
269 	*/
270 
271 	Core.Run();
272 }