16
|
1
|
|
2 // written in the D programming language
|
|
3
|
|
4 module samples.Query;
|
|
5
|
|
6 import chipmunkd.chipmunk;
|
|
7
|
|
8 import samples.ChipmunkDemo;
|
|
9 import gameApp;
|
|
10
|
|
11 import std.math;
|
|
12
|
|
13 //extern cpVect mousePos;
|
|
14
|
|
15 static cpSpace *space;
|
|
16
|
|
17 static cpShape *querySeg = null;
|
|
18
|
|
19
|
|
20 static void
|
|
21 update(int ticks)
|
|
22 {
|
|
23 //messageString[0] = '\0';
|
|
24
|
|
25 cpVect start = cpvzero;
|
|
26 cpVect end = /*cpv(0, 85);//*/mousePos;
|
|
27 cpVect lineEnd = end;
|
|
28
|
|
29 //{
|
|
30 // char infoString[1024];
|
|
31 // sprintf(infoString, "Query: Dist(%f) Point%s, ", cpvdist(start, end), cpvstr(end));
|
|
32 // strcat(messageString, infoString);
|
|
33 //}
|
|
34
|
|
35 cpSegmentQueryInfo info = {};
|
|
36 if(cpSpaceSegmentQueryFirst(space, start, end, CP_ALL_LAYERS, CP_NO_GROUP, &info)){
|
|
37 cpVect point = cpSegmentQueryHitPoint(start, end, info);
|
|
38 lineEnd = cpvadd(point, cpvzero);//cpvmult(info.n, 4.0f));
|
|
39
|
|
40 //char infoString[1024];
|
|
41 //sprintf(infoString, "Segment Query: Dist(%f) Normal%s", cpSegmentQueryHitDist(start, end, info), cpvstr(info.n));
|
|
42 //strcat(messageString, infoString);
|
|
43 } else {
|
|
44 //strcat(messageString, "Segment Query (None)");
|
|
45 }
|
|
46
|
|
47 cpSegmentShapeSetEndpoints(querySeg, start, lineEnd);
|
|
48 cpShapeCacheBB(querySeg); // force it to update it's collision detection data so it will draw
|
|
49
|
|
50 // normal other stuff.
|
|
51 int steps = 1;
|
|
52 cpFloat dt = 1.0f/60.0f/cast(cpFloat)steps;
|
|
53
|
|
54 for(int i=0; i<steps; i++){
|
|
55 cpSpaceStep(space, dt);
|
|
56 }
|
|
57 }
|
|
58
|
|
59 static cpSpace *
|
|
60 init()
|
|
61 {
|
|
62 cpResetShapeIdCounter();
|
|
63
|
|
64 space = cpSpaceNew();
|
|
65 space.elasticIterations = 0;
|
|
66 space.iterations = 5;
|
|
67
|
|
68 cpSpaceResizeStaticHash(space, 40.0f, 999);
|
|
69 cpSpaceResizeActiveHash(space, 30.0f, 2999);
|
|
70
|
|
71 cpBody *staticBody = &space.staticBody;
|
|
72 cpShape *shape;
|
|
73
|
|
74 // add a non-collidable segment as a quick and dirty way to draw the query line
|
|
75 shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpvzero, cpv(100.0f, 0.0f), 4.0f));
|
|
76 shape.layers = 0;
|
|
77 querySeg = shape;
|
|
78
|
|
79 { // add a fat segment
|
|
80 cpFloat mass = 1.0f;
|
|
81 cpFloat length = 100.0f;
|
|
82 cpVect a = cpv(-length/2.0f, 0.0f), b = cpv(length/2.0f, 0.0f);
|
|
83
|
|
84 cpBody *_body = cpSpaceAddBody(space, cpBodyNew(mass, cpMomentForSegment(mass, a, b)));
|
|
85 _body.p = cpv(0.0f, 100.0f);
|
|
86
|
|
87 cpSpaceAddShape(space, cpSegmentShapeNew(_body, a, b, 20.0f));
|
|
88 }
|
|
89
|
|
90 { // add a static segment
|
|
91 cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(0, 300), cpv(300, 0), 0.0f));
|
|
92 }
|
|
93
|
|
94 { // add a pentagon
|
|
95 cpFloat mass = 1.0f;
|
|
96 const int NUM_VERTS = 5;
|
|
97
|
|
98 cpVect verts[NUM_VERTS];
|
|
99 for(int i=0; i<NUM_VERTS; i++){
|
|
100 cpFloat angle = -2*PI*i/(cast(cpFloat) NUM_VERTS);
|
|
101 verts[i] = cpv(30*cos(angle), 30*sin(angle));
|
|
102 }
|
|
103
|
|
104 cpBody *_body = cpSpaceAddBody(space, cpBodyNew(mass, cpMomentForPoly(mass, NUM_VERTS, verts.ptr, cpvzero)));
|
|
105 _body.p = cpv(50.0f, 50.0f);
|
|
106
|
|
107 cpSpaceAddShape(space, cpPolyShapeNew(_body, NUM_VERTS, verts.ptr, cpvzero));
|
|
108 }
|
|
109
|
|
110 { // add a circle
|
|
111 cpFloat mass = 1.0f;
|
|
112 cpFloat r = 20.0f;
|
|
113
|
|
114 cpBody *_body = cpSpaceAddBody(space, cpBodyNew(mass, cpMomentForCircle(mass, 0.0f, r, cpvzero)));
|
|
115 _body.p = cpv(100.0f, 100.0f);
|
|
116
|
|
117 cpSpaceAddShape(space, cpCircleShapeNew(_body, r, cpvzero));
|
|
118 }
|
|
119
|
|
120 return space;
|
|
121 }
|
|
122
|
|
123 static void
|
|
124 destroy()
|
|
125 {
|
|
126 cpSpaceFreeChildren(space);
|
|
127 cpSpaceFree(space);
|
|
128 }
|
|
129
|
|
130 chipmunkDemo Query = {
|
|
131 "Segment Query",
|
|
132 null,
|
|
133 &init,
|
|
134 &update,
|
|
135 &destroy,
|
|
136 };
|