eb1e7241d09c46a3b901ad5e8f95f4320c6f5d76.svn-base (7680B)
1 #include "ActorCollision.h" 2 3 bool SpatialMonitor::PartitionCells(int worldH, int worldW) 4 { 5 int cellW = (worldW / CELLS_X); 6 int cellH = (worldH / CELLS_Y); 7 8 for (int i = 0; i < CELLS_Y; i++) 9 { 10 for (int j = 0; j < CELLS_X; j++) 11 { 12 Cell new_cell; 13 new_cell.GetCellRect()->w = cellW; 14 new_cell.GetCellRect()->h = cellH; 15 new_cell.GetCellRect()->x = cellW * j; 16 new_cell.GetCellRect()->y = cellH * i; 17 18 mCells[i*CELLS_X + j] = new_cell; 19 20 } 21 } 22 return true; 23 } 24 25 bool SpatialMonitor::LogActor(int id) 26 { 27 //mActors[mActorCount] = &act; 28 //mActors.Insert(act.GetHandle(), &act); 29 //act.SetSpatID(mActorCount); 30 UpdateActorCell(id); 31 return true; 32 } 33 34 bool SpatialMonitor::ClearActorCell(int id) 35 { 36 if ((id == 7) | (id == 8)) 37 { 38 gCons->ConsPrintf("seal updates cell\n"); 39 } 40 if (id == 9) 41 { 42 gCons->ConsPrintf("player updates cell\n"); 43 } 44 45 if (GetActorCell(id) != -1) 46 { 47 //mCells[GetActorCell(id)].GetActorTree()->Search(id)->Delete(); 48 mCells[GetActorCell(id)].GetActorTree()->DeleteNode(id); 49 return true; 50 } 51 return false; 52 } 53 54 55 int SpatialMonitor::UpdateActorCell(int id) 56 { 57 //if (id == 7) 58 //{ 59 // gCons->ConsPrintf("seal updates cell\n"); 60 //} 61 Actor* act = (mAHM->GetActorAddress(id)); 62 for (int i = 0; i < CELL_COUNT; i++) 63 { 64 if (DetectCenterPointIntersect( mCells[i].GetCellRect(), act->GetPosition() ) ) 65 { 66 //gCons->ConsPrintf("Actor entering cell %i\n", i); 67 68 if (i != act->GetSpatCell()) 69 { 70 mCells[i].GetActorTree()->Insert(id, NULL); 71 ClearActorCell(id); 72 act->SetSpatCell(i); 73 } 74 75 return i; 76 } 77 } 78 gCons->ConsPrintf("Could not find Actor cell\n"); 79 return -1; 80 } 81 82 int SpatialMonitor::GetAdjacentCells(int cellnum, Cell* cells[9]) 83 { 84 cells[0] = GetCell((cellnum - CELLS_X - 1)); 85 cells[1] = GetCell((cellnum - CELLS_X)); 86 cells[2] = GetCell((cellnum - CELLS_X + 1)); 87 88 cells[3] = GetCell((cellnum - 1)); 89 cells[4] = GetCell((cellnum)); 90 cells[5] = GetCell((cellnum + 1)); 91 92 cells[6] = GetCell((cellnum + CELLS_X - 1)); 93 cells[7] = GetCell((cellnum + CELLS_X)); 94 cells[8] = GetCell((cellnum + CELLS_X + 1)); 95 96 return 0; 97 } 98 99 //bool SpatialMonitor::GetActorsInCell(int cellnum) //uneeded now. Use Cell.GetActorTree() 100 //{ 101 // for (int i = 0; i < MAX_ACTORS; i++) //this is very bad. Basically defeats the function of cells by check each actor 102 // { 103 // if (mActorCells[i] == cellnum) 104 // { 105 // //gCons->ConsPrintf("Actor %i is in adjacent cell\n", i); 106 // mAdjacentActorIDs[mAdjacentActorCount] = i; 107 // mAdjacentActorCount++; 108 // } 109 // } 110 // return true; 111 //} 112 113 //bool SpatialMonitor::GetAdjacentActors(int cellnum) 114 //{ 115 // mAdjacentActorCount = 0; 116 // mAdjacentActorIDs[MAX_ACTORS] = { 0 }; 117 // 118 // int cells[9]; 119 // GetAdjacentCells(cellnum, cells); 120 // 121 // for (int i = 0; i < 9; i++) 122 // { 123 // GetActorsInCell(cells[i]); 124 // //gDiagDraw->LogDiagRect(mCells[cells[i]]); 125 // } 126 // return true; 127 //} 128 129 bool SpatialMonitor::DetectActorCollision(int id1, int id2) 130 { 131 if (id1 != id2) 132 { 133 //gDiagDraw->LogDiagRect(*mActors[id2]->GetPosition()); 134 return DetectRectIntersect(mAHM->GetActorAddress(id1)->GetPosition(), mAHM->GetActorAddress(id2)->GetPosition()); 135 } 136 else 137 { 138 //gCons->ConsPrintf("Attempted to check actor collision with itself\n"); 139 return false; 140 } 141 } 142 143 bool SpatialMonitor::DetectRectSensors(SDL_Rect* sensor, int DetectorID, int foreignID) 144 { 145 if (DetectorID != foreignID) 146 { 147 //gDiagDraw->LogDiagRect(*sensor); 148 //gDiagDraw->LogDiagRect(*mActors[foreignID]->GetPosition()); 149 return DetectRectIntersect(sensor, mAHM->GetActorAddress(foreignID)->GetPosition()); 150 } 151 else 152 { 153 //gCons->ConsPrintf("Attempted to check actor collision with itself\n"); 154 return false; 155 } 156 } 157 158 bool SpatialMonitor::HandleCollisions(int CallerID) 159 { 160 161 int CallerCell = GetActorCell(CallerID); 162 163 Cell* AdjecentCellIndex[9]; 164 GetAdjacentCells(CallerCell, AdjecentCellIndex); 165 166 for (int i = 0; i < 9; i++) 167 { 168 if (AdjecentCellIndex[i] != NULL) 169 { 170 int array_size = AdjecentCellIndex[i]->GetActorTree()->Size(); 171 if (array_size != -1) 172 { 173 //Node** ActorTreeArray = NULL; 174 Node** ActorTreeArray = new Node*[array_size]; 175 ActorTreeArray = (AdjecentCellIndex[i]->GetActorTree())->Dump(); 176 for (int j = 0; j < (array_size); j++) 177 { 178 if (ActorTreeArray[j] == (Node*)(0xcdcdcdcd)) 179 { 180 gCons->ConsPrintf("uninitialized memory\n"); 181 AdjecentCellIndex[i]->GetActorTree()->Dump(); 182 } 183 assert(j <= array_size); 184 //gCons->ConsPrintf("index: %i, item: %i\n", j, ActorTreeArray[j]->GetItem()); 185 int size = sizeof(ActorTreeArray); 186 187 if (ActorTreeArray[j] == NULL) 188 { 189 gCons->ConsPrintf("Error: invalid index into actor tree, Cell: %i", i); 190 } 191 if (DetectActorCollision(CallerID, ActorTreeArray[j]->GetItem()) == true) 192 { 193 mAHM->GetActorAddress(CallerID)->EventProcess(Event(ACTOR_COLLISION, ActorTreeArray[j]->GetItem())); 194 } 195 } 196 } 197 else 198 { 199 //gCons->ConsPrintf("Cell is empty/n"); 200 } 201 } 202 else 203 { 204 //Cell does not exist. do nothing 205 } 206 } 207 208 return true; 209 } 210 211 bool SpatialMonitor::HandleRectSensors(SDL_Rect* sensor, int CallerID, SensorType SeType) 212 { 213 214 int CallerCell = GetActorCell(CallerID); 215 216 Cell* AdjecentCellIndex[9]; 217 GetAdjacentCells(CallerCell, AdjecentCellIndex); 218 219 for (int i = 0; i < 9; i++) 220 { 221 if (AdjecentCellIndex[i] != NULL) 222 { 223 int array_size = AdjecentCellIndex[i]->GetActorTree()->Size(); 224 if (array_size != -1) 225 { 226 //Node** ActorTreeArray = NULL; 227 Node** ActorTreeArray = new Node*[array_size]; 228 ActorTreeArray = (AdjecentCellIndex[i]->GetActorTree())->Dump(); 229 for (int j = 0; j < (array_size); j++) 230 { 231 assert(j <= array_size); 232 //gCons->ConsPrintf("index: %i, item: %i\n", j, ActorTreeArray[j]->GetItem()); 233 234 if (ActorTreeArray[j] == NULL) 235 { 236 gCons->ConsPrintf("Error: invalid index into actor tree, Cell: %i", i); 237 } 238 if (DetectRectSensors(sensor, CallerID, ActorTreeArray[j]->GetItem()) == true) 239 { 240 mAHM->GetActorAddress(CallerID)->EventProcess(Event(SENSOR_COLLISION, SeType, ActorTreeArray[j]->GetItem())); //Used to pass actor* now passed ID number. receiver functions need to be updated 241 } 242 } 243 } 244 else 245 { 246 //gCons->ConsPrintf("Cell is empty/n"); 247 } 248 } 249 else 250 { 251 //Cell does not exist. do nothing 252 } 253 } 254 return true; 255 } 256 257 bool SpatialMonitor::TestBlockers(SDL_Rect* sensor, int CallerID) 258 { 259 int CallerCell = GetActorCell(CallerID); 260 261 Cell* AdjecentCellIndex[9]; 262 GetAdjacentCells(CallerCell, AdjecentCellIndex); 263 264 for (int i = 0; i < 9; i++) 265 { 266 if (AdjecentCellIndex[i] != NULL) 267 { 268 Node** ActorTreeArray = ((AdjecentCellIndex[i]->GetActorTree())->Dump()); 269 if (ActorTreeArray != NULL) 270 { 271 for (int j = 0; j < (AdjecentCellIndex[i]->GetActorTree())->Size(); j++) 272 { 273 if (DetectRectSensors(sensor, CallerID, ActorTreeArray[j]->GetItem()) == true) 274 { 275 if (mAHM->GetActorAddress(ActorTreeArray[j]->GetItem())->IsBlocking() == true) 276 { 277 return true; 278 } 279 } 280 } 281 } 282 else 283 { 284 //gCons->ConsPrintf("Cell is empty/n"); 285 } 286 } 287 else 288 { 289 //Cell does not exist. do nothing 290 } 291 } 292 return false; 293 } 294 295 bool SpatialMonitor::EventProcess(Event eve) 296 { 297 switch (*eve.GetEventType()) 298 { 299 case MOVED_THIS_FRAME: 300 UpdateActorCell(eve.GetEventData()->i); 301 HandleCollisions(eve.GetEventData()->i); 302 return true; 303 break; 304 case CHECK_RECT_SENSOR: 305 HandleRectSensors(eve.GetEventData()->sd.sensor, eve.GetEventData()->sd.id, eve.GetEventData()->sd.st); 306 return true; 307 break; 308 case CHECK_BLOCKERS: 309 return TestBlockers(eve.GetEventData()->sd.sensor, eve.GetEventData()->sd.id); 310 break; 311 default: 312 gCons->ConsPrintf("Spatial Monitor Received Invalid Event Type\n"); 313 return false; 314 break; 315 } 316 }