1 module physlayer;
2 
3 import derelict.sdl.sdl;
4 
5 import dlib.math.vector;
6 import dlib.image.color;
7 
8 import dgl.core.event;
9 import dgl.core.layer;
10 import dgl.core.drawable;
11 import dgl.graphics.shapes;
12 import dgl.graphics.material;
13 import dgl.scene.tbcamera;
14 
15 import dmech.world;
16 import dmech.rigidbody;
17 import dmech.geometry;
18 
19 import physobject;
20 
21 class PhysicsLayer: Layer
22 {
23     PhysicsWorld world;
24     RigidBody activeBody;
25 
26     TrackballCamera camera;
27 
28     this(uint w, uint h, int depth)
29     {
30         super(0, 0, w, h, LayerType.Layer3D, depth);
31         alignToWindow = true;
32 
33         world = new PhysicsWorld();
34         auto geomFloorBox = new GeomBox(Vector3f(100, 1, 100));
35         RigidBody bFloor = world.addStaticBody(Vector3f(0, -1, 0));
36         world.addShapeComponent(bFloor, geomFloorBox, Vector3f(0, 0, 0), 1);
37 
38         auto geomSphere1 = new GeomSphere(1.0f);
39         RigidBody bSphere = world.addDynamicBody(Vector3f(0, 3, 5));
40         world.addShapeComponent(bSphere, geomSphere1, Vector3f(0, 0, 0), 1.0f);
41         activeBody = bSphere;
42         auto sSphere1 = new ShapeSphere(1.0f);
43         auto pobj1 = new PhysicsObject();
44         pobj1.drawable = sSphere1;
45         pobj1.shape = bSphere.shapes[0];
46         addDrawable(pobj1);
47 
48         buildPyramid(5);
49     }
50 
51     override void onUpdate(EventManager emngr)
52     {
53         processInput(emngr);
54         world.update(1.0 / 60.0);
55     }
56 
57     void processInput(EventManager emngr)
58     {
59         if (camera is null)
60             camera = emngr.getGlobal!TrackballCamera("camera");
61 
62         float forceMagnitude = 40.0f;
63     
64         if (emngr.key_pressed[SDLK_PAGEUP])
65             activeBody.applyForce(Vector3f(0.0f, forceMagnitude, 0.0f));
66         if (emngr.key_pressed[SDLK_PAGEDOWN])
67             activeBody.applyForce(Vector3f(0.0f, -forceMagnitude, 0.0f));
68 
69         Vector3f right;
70         if (camera !is null) 
71             right = camera.getRightVector;
72         else
73             right = Vector3f(1.0f, 0.0f, 0.0f);
74         Vector3f forward = cross(Vector3f(0.0f, 1.0f, 0.0f), right);
75 
76         if (emngr.key_pressed[SDLK_LEFT])
77             activeBody.applyForce(-right * forceMagnitude);
78         if (emngr.key_pressed[SDLK_RIGHT])
79             activeBody.applyForce( right * forceMagnitude);
80             
81         if (emngr.key_pressed[SDLK_DOWN])
82             activeBody.applyForce(-forward * forceMagnitude);
83         if (emngr.key_pressed[SDLK_UP])
84             activeBody.applyForce( forward * forceMagnitude);
85     }
86 
87     void buildPyramid(uint pyramidSize)
88     {
89         float size = 1.0f;
90 
91         float cubeHeight = 2.0f;
92 
93         auto box = new ShapeBox(Vector3f(size, cubeHeight * 0.5f, size));
94         auto cyl = new ShapeCylinder(2.0f, 1.0f);
95         auto con = new ShapeCone(2.0f, 1.0f);
96         auto sph = new ShapeSphere(1.0f);
97 
98         float width = size * 2.0f;
99         float height = cubeHeight;
100         float horizontal_spacing = 0.1f;
101         float veritcal_spacing = 0.1f;
102 
103         enum pyramidGeom = 0;
104 
105         auto geomBox = new GeomBox(Vector3f(size, cubeHeight * 0.5f, size));
106         auto geomCylinder = new GeomCylinder(2.0f, 1.0f); 
107         auto geomSphere = new GeomSphere(size); 
108         auto geomCone = new GeomCone(2.0f, 1.0f); 
109 
110         foreach(i; 0..pyramidSize)
111         foreach(e; i..pyramidSize)
112         {
113             auto position = Vector3f(
114                 (e - i * 0.5f) * (width + horizontal_spacing) - ((width + horizontal_spacing) * 5), 
115                 6.0f + (height + veritcal_spacing * 0.5f) + i * height + 0.26f,
116                 0.0f);
117 
118             Geometry g;
119             Drawable gobj;
120 
121             switch(pyramidGeom)
122             {
123                 case 0:
124                     g = geomBox;
125                     gobj = box;
126                     break;
127                 case 1:
128                     g = geomCylinder;
129                     gobj = cyl;
130                     break;
131                 case 2:
132                     g = geomSphere; 
133                     gobj = sph;
134                     break;
135                 case 4:
136                     g = geomCone;
137                     gobj = con;
138                     break;
139                 default:
140                     assert(0);
141             }
142 
143             auto b = world.addDynamicBody(position, 0);
144             world.addShapeComponent(b, g, Vector3f(0, 0, 0), 1);
145 
146             auto gameObj = new PhysicsObject();
147             gameObj.drawable = gobj; 
148             gameObj.shape = b.shapes[0];
149 
150             Material mat = new Material();
151             auto col = Color4f((randomUnitVector3!float + 0.5f).normalized);
152             mat.ambientColor = col;
153             mat.diffuseColor = col;
154             gameObj.material = mat;
155 
156             addDrawable(gameObj);
157         }
158     }
159 }
160