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