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