34a277129fa2017d1255f92a059217545915c49a.svn-base (6652B)
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 (GetActorCell(id) != -1) 37 { 38 mCells[GetActorCell(id)].GetActorTree()->Search(id)->Delete(); 39 return true; 40 } 41 return false; 42 } 43 44 45 int SpatialMonitor::UpdateActorCell(int id) 46 { 47 Actor* act = (mAHM->GetActorAddress(id)); 48 for (int i = 0; i < CELL_COUNT; i++) 49 { 50 if (DetectCenterPointIntersect( mCells[i].GetCellRect(), act->GetPosition() ) ) 51 { 52 //gCons->ConsPrintf("Actor entering cell %i\n", i); 53 54 if (i != act->GetSpatCell()) 55 { 56 mCells[i].GetActorTree()->Insert(id, NULL); 57 ClearActorCell(id); //this is causing the crash, delete function sucks. 58 //mCells[GetActorCell(id)].GetActorTree()->Search(id)->Delete(); 59 act->SetSpatCell(i); 60 } 61 62 return i; 63 } 64 } 65 gCons->ConsPrintf("Could not find Actor cell\n"); 66 return -1; 67 } 68 69 int SpatialMonitor::GetAdjacentCells(int cellnum, Cell* cells[9]) 70 { 71 cells[0] = GetCell((cellnum - CELLS_X - 1)); 72 cells[1] = GetCell((cellnum - CELLS_X)); 73 cells[2] = GetCell((cellnum - CELLS_X + 1)); 74 75 cells[3] = GetCell((cellnum - 1)); 76 cells[4] = GetCell((cellnum)); 77 cells[5] = GetCell((cellnum + 1)); 78 79 cells[6] = GetCell((cellnum + CELLS_X - 1)); 80 cells[7] = GetCell((cellnum + CELLS_X)); 81 cells[8] = GetCell((cellnum + CELLS_X + 1)); 82 83 return 0; 84 } 85 86 //bool SpatialMonitor::GetActorsInCell(int cellnum) //uneeded now. Use Cell.GetActorTree() 87 //{ 88 // for (int i = 0; i < MAX_ACTORS; i++) //this is very bad. Basically defeats the function of cells by check each actor 89 // { 90 // if (mActorCells[i] == cellnum) 91 // { 92 // //gCons->ConsPrintf("Actor %i is in adjacent cell\n", i); 93 // mAdjacentActorIDs[mAdjacentActorCount] = i; 94 // mAdjacentActorCount++; 95 // } 96 // } 97 // return true; 98 //} 99 100 //bool SpatialMonitor::GetAdjacentActors(int cellnum) 101 //{ 102 // mAdjacentActorCount = 0; 103 // mAdjacentActorIDs[MAX_ACTORS] = { 0 }; 104 // 105 // int cells[9]; 106 // GetAdjacentCells(cellnum, cells); 107 // 108 // for (int i = 0; i < 9; i++) 109 // { 110 // GetActorsInCell(cells[i]); 111 // //gDiagDraw->LogDiagRect(mCells[cells[i]]); 112 // } 113 // return true; 114 //} 115 116 bool SpatialMonitor::DetectActorCollision(int id1, int id2) 117 { 118 if (id1 != id2) 119 { 120 //gDiagDraw->LogDiagRect(*mActors[id2]->GetPosition()); 121 return DetectRectIntersect(mAHM->GetActorAddress(id1)->GetPosition(), mAHM->GetActorAddress(id2)->GetPosition()); 122 } 123 else 124 { 125 //gCons->ConsPrintf("Attempted to check actor collision with itself\n"); 126 return false; 127 } 128 } 129 130 bool SpatialMonitor::DetectRectSensors(SDL_Rect* sensor, int DetectorID, int foreignID) 131 { 132 if (DetectorID != foreignID) 133 { 134 //gDiagDraw->LogDiagRect(*sensor); 135 //gDiagDraw->LogDiagRect(*mActors[foreignID]->GetPosition()); 136 return DetectRectIntersect(sensor, mAHM->GetActorAddress(foreignID)->GetPosition()); 137 } 138 else 139 { 140 //gCons->ConsPrintf("Attempted to check actor collision with itself\n"); 141 return false; 142 } 143 } 144 145 bool SpatialMonitor::HandleCollisions(int CallerID) 146 { 147 int CallerCell = GetActorCell(CallerID); 148 149 Cell* AdjecentCellIndex[9]; 150 GetAdjacentCells(CallerCell, AdjecentCellIndex); 151 152 for (int i = 0; i < 9; i++) 153 { 154 if (AdjecentCellIndex[i] != NULL) 155 { 156 Node** ActorTreeArray = (AdjecentCellIndex[i]->GetActorTree())->Dump(); 157 if (ActorTreeArray != NULL) 158 { 159 for (int j = 0; j < (AdjecentCellIndex[i]->GetActorTree())->Size(); j++) 160 { 161 if (DetectActorCollision(CallerID, ActorTreeArray[j]->GetItem()) == true) 162 { 163 mAHM->GetActorAddress(CallerID)->EventProcess(Event(ACTOR_COLLISION, ActorTreeArray[j]->GetItem())); 164 } 165 } 166 } 167 else 168 { 169 //gCons->ConsPrintf("Cell is empty/n"); 170 } 171 } 172 else 173 { 174 //Cell does not exist. do nothing 175 } 176 } 177 178 return true; 179 } 180 181 bool SpatialMonitor::HandleRectSensors(SDL_Rect* sensor, int CallerID, SensorType SeType) 182 { 183 int CallerCell = GetActorCell(CallerID); 184 185 Cell* AdjecentCellIndex[9]; 186 GetAdjacentCells(CallerCell, AdjecentCellIndex); 187 188 for (int i = 0; i < 9; i++) 189 { 190 if (AdjecentCellIndex[i] != NULL) 191 { 192 Node** ActorTreeArray = (AdjecentCellIndex[i]->GetActorTree())->Dump(); 193 194 if (ActorTreeArray != NULL) 195 { 196 for (int j = 0; j < (AdjecentCellIndex[i]->GetActorTree())->Size(); j++) 197 { 198 Node* debugtool = ActorTreeArray[j]; 199 if (DetectRectSensors(sensor, CallerID, ActorTreeArray[j]->GetItem()) == true) 200 { 201 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 202 } 203 } 204 } 205 else 206 { 207 //gCons->ConsPrintf("Cell is empty/n"); 208 } 209 } 210 else 211 { 212 //Cell does not exist. do nothing 213 } 214 } 215 return true; 216 } 217 218 bool SpatialMonitor::TestBlockers(SDL_Rect* sensor, int CallerID) 219 { 220 int CallerCell = GetActorCell(CallerID); 221 222 Cell* AdjecentCellIndex[9]; 223 GetAdjacentCells(CallerCell, AdjecentCellIndex); 224 225 for (int i = 0; i < 9; i++) 226 { 227 if (AdjecentCellIndex[i] != NULL) 228 { 229 Node** ActorTreeArray = ((AdjecentCellIndex[i]->GetActorTree())->Dump()); 230 if (ActorTreeArray != NULL) 231 { 232 for (int j = 0; j < (AdjecentCellIndex[i]->GetActorTree())->Size(); j++) 233 { 234 if (DetectRectSensors(sensor, CallerID, ActorTreeArray[j]->GetItem()) == true) 235 { 236 if (mAHM->GetActorAddress(ActorTreeArray[j]->GetItem())->IsBlocking() == true) 237 { 238 return true; 239 } 240 } 241 } 242 } 243 else 244 { 245 //gCons->ConsPrintf("Cell is empty/n"); 246 } 247 } 248 else 249 { 250 //Cell does not exist. do nothing 251 } 252 } 253 return false; 254 } 255 256 bool SpatialMonitor::EventProcess(Event eve) 257 { 258 switch (*eve.GetEventType()) 259 { 260 case MOVED_THIS_FRAME: 261 UpdateActorCell(eve.GetEventData()->i); 262 HandleCollisions(eve.GetEventData()->i); 263 return true; 264 break; 265 case CHECK_RECT_SENSOR: 266 HandleRectSensors(eve.GetEventData()->sd.sensor, eve.GetEventData()->sd.id, eve.GetEventData()->sd.st); 267 return true; 268 break; 269 case CHECK_BLOCKERS: 270 return TestBlockers(eve.GetEventData()->sd.sensor, eve.GetEventData()->sd.id); 271 break; 272 default: 273 gCons->ConsPrintf("Spatial Monitor Received Invalid Event Type\n"); 274 return false; 275 break; 276 } 277 }