1 2 // written in the D programming language 3 4 module samples.TheoJansen; 5 6 import dchip.all; 7 8 import samples.ChipmunkDemo; 9 10 import gameApp; 11 12 import std.math; 13 14 enum M_PI = PI; 15 enum M_PI_2 = PI*0.5f; 16 17 static cpSpace *space; 18 19 static cpConstraint *motor; 20 21 static void 22 update(int ticks) 23 { 24 cpFloat coef = (2.0f + arrowDirection.y)/3.0f; 25 cpFloat rate = arrowDirection.x*10.0f*coef; 26 cpSimpleMotorSetRate(motor, rate); 27 motor.maxForce = (rate) ? 100000.0f : 0.0f; 28 29 enum int steps = 3; 30 enum cpFloat dt = 1.0f/60.0f/cast(cpFloat)steps; 31 32 for(int i=0; i<steps; i++){ 33 cpSpaceStep(space, dt); 34 } 35 } 36 37 static cpFloat seg_radius = 3.0f; 38 39 static void 40 make_leg(cpFloat side, cpFloat offset, cpBody *chassis, cpBody *crank, cpVect anchor) 41 { 42 cpVect a, b; 43 cpShape *shape; 44 45 cpFloat leg_mass = 1.0f; 46 47 // make leg 48 a = cpvzero, b = cpv(0.0f, side); 49 cpBody *upper_leg = cpBodyNew(leg_mass, cpMomentForSegment(leg_mass, a, b)); 50 upper_leg.p = cpv(offset, 0.0f); 51 cpSpaceAddBody(space, upper_leg); 52 cpSpaceAddShape(space, cpSegmentShapeNew(upper_leg, a, b, seg_radius)); 53 cpSpaceAddConstraint(space, cpPivotJointNew2(chassis, upper_leg, cpv(offset, 0.0f), cpvzero)); 54 55 // lower leg 56 a = cpvzero, b = cpv(0.0f, -1.0f*side); 57 cpBody *lower_leg = cpBodyNew(leg_mass, cpMomentForSegment(leg_mass, a, b)); 58 lower_leg.p = cpv(offset, -side); 59 cpSpaceAddBody(space, lower_leg); 60 shape = cpSegmentShapeNew(lower_leg, a, b, seg_radius); 61 shape.group = 1; 62 cpSpaceAddShape(space, shape); 63 shape = cpCircleShapeNew(lower_leg, seg_radius*2.0f, b); 64 shape.group = 1; 65 shape.e = 0.0f; shape.u = 1.0f; 66 cpSpaceAddShape(space, shape); 67 cpSpaceAddConstraint(space, cpPinJointNew(chassis, lower_leg, cpv(offset, 0.0f), cpvzero)); 68 69 cpSpaceAddConstraint(space, cpGearJointNew(upper_leg, lower_leg, 0.0f, 1.0f)); 70 71 cpConstraint *constraint; 72 cpFloat diag = cpfsqrt(side*side + offset*offset); 73 74 constraint = cpPinJointNew(crank, upper_leg, anchor, cpv(0.0f, side)); 75 cpPinJointSetDist(constraint, diag); 76 cpSpaceAddConstraint(space, constraint); 77 constraint = cpPinJointNew(crank, lower_leg, anchor, cpvzero); 78 cpPinJointSetDist(constraint, diag); 79 cpSpaceAddConstraint(space, constraint); 80 } 81 82 static cpSpace * 83 init() 84 { 85 space = cpSpaceNew(); 86 87 cpResetShapeIdCounter(); 88 89 space = cpSpaceNew(); 90 space.iterations = 20; 91 space.gravity = cpv(0,-500); 92 93 cpBody *staticBody = space.staticBody; 94 cpShape *shape; 95 cpVect a, b; 96 97 // Create segments around the edge of the screen. 98 shape = cpSegmentShapeNew(staticBody, cpv(-320,-240), cpv(-320,240), 0.0f); 99 shape.e = 1.0f; shape.u = 1.0f; 100 shape.layers = NOT_GRABABLE_MASK; 101 cpSpaceAddShape(space, shape); 102 103 shape = cpSegmentShapeNew(staticBody, cpv(320,-240), cpv(320,240), 0.0f); 104 shape.e = 1.0f; shape.u = 1.0f; 105 shape.layers = NOT_GRABABLE_MASK; 106 cpSpaceAddShape(space, shape); 107 108 shape = cpSegmentShapeNew(staticBody, cpv(-320,-240), cpv(320,-240), 0.0f); 109 shape.e = 1.0f; shape.u = 1.0f; 110 shape.layers = NOT_GRABABLE_MASK; 111 cpSpaceAddShape(space, shape); 112 113 cpFloat offset = 30.0f; 114 115 // make chassis 116 cpFloat chassis_mass = 2.0f; 117 a = cpv(-offset, 0.0f), b = cpv(offset, 0.0f); 118 cpBody *chassis = cpBodyNew(chassis_mass, cpMomentForSegment(chassis_mass, a, b)); 119 cpSpaceAddBody(space, chassis); 120 shape = cpSegmentShapeNew(chassis, a, b, seg_radius); 121 shape.group = 1; 122 cpSpaceAddShape(space, shape); 123 124 // make crank 125 cpFloat crank_mass = 1.0f; 126 cpFloat crank_radius = 13.0f; 127 cpBody *crank = cpBodyNew(crank_mass, cpMomentForCircle(crank_mass, crank_radius, 0.0f, cpvzero)); 128 cpSpaceAddBody(space, crank); 129 shape = cpCircleShapeNew(crank, crank_radius, cpvzero); 130 shape.group = 1; 131 cpSpaceAddShape(space, shape); 132 cpSpaceAddConstraint(space, cpPivotJointNew2(chassis, crank, cpvzero, cpvzero)); 133 134 cpFloat side = 30.0f; 135 136 int num_legs = 2; 137 for(int i=0; i<num_legs; i++){ 138 make_leg(side, offset, chassis, crank, cpvmult(cpvforangle(cast(cpFloat)(2*i+0)/cast(cpFloat)num_legs*M_PI), crank_radius)); 139 make_leg(side, -offset, chassis, crank, cpvmult(cpvforangle(cast(cpFloat)(2*i+1)/cast(cpFloat)num_legs*M_PI), crank_radius)); 140 } 141 142 motor = cpSimpleMotorNew(chassis, crank, 6.0f); 143 cpSpaceAddConstraint(space, motor); 144 145 return space; 146 } 147 148 static void 149 destroy() 150 { 151 ChipmunkDemoFreeSpaceChildren(space); 152 cpSpaceFree(space); 153 } 154 155 chipmunkDemo TheoJansen = { 156 "Theo Jansen Machine", 157 null, 158 &init, 159 &update, 160 &destroy, 161 };