The Game Engine  1
CollisionObject.cpp
Go to the documentation of this file.
1 #include "fns.h"
2 #include "CollisionObject.h"
3 #include "Game.h"
4 #include <algorithm>
11 void DrawCircle( const Point2D wPos, const Point2D pos, Uint32 color) {
12  glLoadIdentity();
13  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
14  glColor4d((color&0xFF)/255.0, (color&0xFF00)/255.0, (color&0xFF0000)/255.0, (color&0xFF000000)/255.0);
15  glLoadIdentity();
16  Point2D movePos=Game::game()->mCamera.pos;
17  glTranslated(-movePos.x, -movePos.y, 0);//move to position
18  glBegin(GL_POINTS);
19  glVertex2d( wPos.x + pos.x, wPos.y + pos.y );
20  glVertex2d( wPos.x - pos.x, wPos.y + pos.y );
21  glVertex2d( wPos.x + pos.x, wPos.y - pos.y );
22  glVertex2d( wPos.x - pos.x, wPos.y - pos.y );
23  glVertex2d( wPos.x + pos.y, wPos.y + pos.x );
24  glVertex2d( wPos.x - pos.y, wPos.y + pos.x );
25  glVertex2d( wPos.x + pos.y, wPos.y - pos.x );
26  glVertex2d( wPos.x - pos.y, wPos.y - pos.x );
27  glEnd();
28  glLoadIdentity();
29  glFinish();
30 }
31 
33  glLoadIdentity();
34  glBlendFunc(GL_ONE, GL_ONE);
35  glColor3f(1.0f, 1.0f, 1.0f);
36  glColor4d((color&0xFF)/255.0, (color&0xFF00)/255.0, (color&0xFF0000)/255.0, (color&0xFF000000)/255.0);
37  Point2D movePos=Game::game()->mCamera.pos;
38  glTranslated(-movePos.x, -movePos.y, 0);//move to position
39  glBegin(GL_LINE_LOOP);
40  Point2D nPos = pos + mPos;
41  //top
42  Point2D startPos = nPos + Point2D(-width/2, -height/2);
43  glVertex2d(startPos.x,startPos.y);
44  startPos = nPos + Point2D(width/2, -height/2);
45  glVertex2d(startPos.x,startPos.y);
46  startPos = nPos + Point2D(width/2, height/2);
47  glVertex2d(startPos.x,startPos.y);
48  startPos = nPos + Point2D(-width/2, height/2);
49  glVertex2d(startPos.x,startPos.y);
50  glEnd();
51  glLoadIdentity();
52  glFlush();
53 }
54 
55 void CollisionCircle::draw(const Point2D& pos) {
56  int x=0,y=(int)radius;
57  int midpt = 1-(int)radius;
58  //draw pts
59  DrawCircle( pos + mPos, Point2D(x,y), color);
60  //calculate other points
61  while(x<y) {
62  x++;
63  if(midpt<0)
64  midpt += 2 * x + 1;
65  else{
66  y--;
67  midpt += 2 * (x-y) + 1;
68  }
69  //draw pts
70  DrawCircle( pos + mPos, Point2D(x,y), color);
71  }
72 }
73 
74 bool CollisionObject::checkCollisions(const vector<CollisionObject*>& c, Point2D cPos, Point2D pos, vector<string> names){
75  int size = names.size();
76  for(unsigned int i=0; i < c.size(); i++) {
77  CollisionObject* col = c[i];
78  //if(size == 0 || find(names.begin(),names.end(),col->name)!=names.end())
79  // if(collision(col, cPos, pos))//if any are true return true then and there
80  // return true;/// \todo make this return actual values not just if there was a collision
81  }
82  return false;//if none were found then return false.
83 }
84 
85 pair<WorldObject*, CollisionObject*> CollisionRectangle::collision(const CollisionObject *c, WorldObject* wo, WorldObject* mObj) const {
86  switch(c->getType()){
87  case COLLISIONRECTANGLE:
88  {
89  const CollisionRectangle* rec = (const CollisionRectangle*)c;
90  Point2D pos = mObj->getPosition();
92  double r1Left = -width/2 + mPos.x + pos.x;
93  double r1Right = width/2 + mPos.x + pos.x;
94  double r1Top = -height/2 + mPos.y + pos.y;
95  double r1Bottom = height/2 + mPos.y + pos.y;
96 
97  Point2D cPos = wo->getPosition();
98  double r2Left = -rec->width/2 + rec->mPos.x + cPos.x;
99  double r2Right = rec->width/2 + rec->mPos.x + cPos.x;
100  double r2Top = -rec->height/2 + rec->mPos.y + cPos.y;
101  double r2Bottom = rec->height/2 + rec->mPos.y + cPos.y;
102 
103  bool outsideX = r1Right < r2Left || r1Left > r2Right;
104  bool outsideY = r1Bottom < r2Top || r1Top > r2Bottom;
105  return !(outsideY || outsideX) ? make_pair<WorldObject*, CollisionObject*>(wo, (CollisionObject*)c) : make_pair<WorldObject*, CollisionObject*>(NULL, NULL);
106  }
107  break;
108  case COLLISIONCIRCLE:
109  case COLLISIONSEGMENT:
110  {
111  return c->collision(this, wo, mObj);
112  }
113  break;
114  }
115 
116  return make_pair<WorldObject*, CollisionObject*>(NULL,NULL);
117 }
118 
119 pair<WorldObject*, CollisionObject*> CollisionCircle::collision(const CollisionObject *c, WorldObject* wo, WorldObject* mObj) const {
120  switch(c->getType()){
121  case COLLISIONRECTANGLE:
122  {
123  return collision((const CollisionRectangle*)c, wo, mObj);
124  }
125  break;
126  case COLLISIONCIRCLE:
127  {
128  const CollisionCircle* col = (const CollisionCircle*)c;
130  if(((col->mPos + wo->getPosition()) - (mPos + mObj->getPosition())).length() <= (col->radius + radius))
131  return make_pair<WorldObject*, CollisionObject*>(wo, (CollisionObject*)c);
132  else
133  return make_pair<WorldObject*, CollisionObject*>(NULL, NULL);
134  }
135  case COLLISIONSEGMENT:
136  {
137  return c->collision(this, wo, mObj);
138  }
139  break;
140  }
141 
142  return make_pair<WorldObject*, CollisionObject*>(NULL, NULL);
143 }
144 
145 pair<WorldObject*, CollisionObject*> CollisionCircle::collision(const CollisionRectangle* c, WorldObject* wo, WorldObject* mObj) const {
147  Point2D rectCent = wo->getPosition() + c->mPos;//center of rect
148  Point2D tl = rectCent + Point2D(-c->width/2,-c->height/2);//top left of rect
149  Point2D bl = rectCent + Point2D(-c->width/2, c->height/2);//bottom left of rect
150  Point2D tr = rectCent + Point2D( c->width/2,-c->height/2);//top right of rect
151  Point2D br = rectCent + Point2D( c->width/2, c->height/2);//bottom right of rect
152  //Are any of the points inside the circle?
153  if( ((tl.x - mPos.x)*(tl.x - mPos.x) + (tl.y - mPos.y)*(tl.y - mPos.y) - radius*radius) <= 0 ||
154  ((tr.x - mPos.x)*(tr.x - mPos.x) + (tr.y - mPos.y)*(tr.y - mPos.y) - radius*radius) <= 0 ||
155  ((bl.x - mPos.x)*(bl.x - mPos.x) + (bl.y - mPos.y)*(bl.y - mPos.y) - radius*radius) <= 0 ||
156  ((br.x - mPos.x)*(br.x - mPos.x) + (br.y - mPos.y)*(br.y - mPos.y) - radius*radius) <= 0 )
157  return make_pair<WorldObject*, CollisionObject*>(wo, (CollisionObject*)c);
158  //Is the circle inside the rectangle? (considers bounds)
159  else if( !(
160  mPos.x + radius < tl.x ||
161  mPos.x - radius > tr.x ||
162  mPos.y + radius < tl.y ||
163  mPos.y - radius > bl.y ))
164  return make_pair<WorldObject*, CollisionObject*>(wo, (CollisionObject*)c);
165  //It's not in there
166  return make_pair<WorldObject*, CollisionObject*>(NULL, NULL);
167 }
168 
169 double CollisionRectangle::getLeft(){ return mPos.x; }
170 
172 
173 double CollisionRectangle::getTop(){ return mPos.y; }
174 
176 
177 pair<WorldObject*, CollisionObject*> CollisionSegment::collision(const CollisionRectangle* c, WorldObject* wo, WorldObject* mObj) const {
179  Point2D rectCent = wo->getPosition() + c->mPos;//center of rect
180  Point2D tl = rectCent + Point2D(-c->width/2,-c->height/2);//top left of rect
181  Point2D bl = rectCent + Point2D(-c->width/2, c->height/2);//bottom left of rect
182  Point2D tr = rectCent + Point2D( c->width/2,-c->height/2);//top right of rect
183  Point2D br = rectCent + Point2D( c->width/2, c->height/2);//bottom right of rect
184 
186 
187 
188  //It's not in there
189  return make_pair<WorldObject*, CollisionObject*>(NULL, NULL);
190 }
191 
192 pair<WorldObject*, CollisionObject*> CollisionSegment::collision(const CollisionCircle *c, WorldObject* wo, WorldObject* mObj) const {
193 
194 
195  return make_pair<WorldObject*, CollisionObject*>(NULL, NULL);
196 }
197 
198 pair<WorldObject*, CollisionObject*> CollisionSegment::collision(const CollisionObject *c, WorldObject* wo, WorldObject* mObj) const {
199  switch(c->getType()){
200  case COLLISIONRECTANGLE:
201  {
202  return collision((const CollisionRectangle*)c, wo, mObj);
203  }
204  break;
205  case COLLISIONCIRCLE:
206  {
207  return collision((const CollisionCircle*)c, wo, mObj);
208  }
209  case COLLISIONSEGMENT:
210  {
212  //return segment on segment check
213  return c->collision(this, wo, mObj);
214  }
215  break;
216  }
217 
218  return make_pair<WorldObject*, CollisionObject*>(NULL, NULL);
219 }