905c7c275895c3e18a39223f5fdb1a01c9ce0629.svn-base (5861B)
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 != ((Collider*)(act))->GetSpatCell()) //not sure about all this casting, might be causing troubles 55 { 56 mCells[i].GetActorTree()->Insert(id, NULL); 57 ClearActorCell(id); 58 ((Collider*)(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::DetectActorCollision(int id1, int id2) 86 { 87 if (id1 != id2) 88 { 89 //gDiagDraw->LogDiagRect(*mActors[id2]->GetPosition()); 90 return DetectRectIntersect(mAHM->GetActorAddress(id1)->GetPosition(), mAHM->GetActorAddress(id2)->GetPosition()); 91 } 92 else 93 { 94 //gCons->ConsPrintf("Attempted to check actor collision with itself\n"); 95 return false; 96 } 97 } 98 99 bool SpatialMonitor::DetectRectSensors(SDL_Rect* sensor, int DetectorID, int foreignID) 100 { 101 if (DetectorID != foreignID) 102 { 103 //gDiagDraw->LogDiagRect(*sensor); 104 //gDiagDraw->LogDiagRect(*mActors[foreignID]->GetPosition()); 105 return DetectRectIntersect(sensor, mAHM->GetActorAddress(foreignID)->GetPosition()); 106 } 107 else 108 { 109 //gCons->ConsPrintf("Attempted to check actor collision with itself\n"); 110 return false; 111 } 112 } 113 114 bool SpatialMonitor::HandleCollisions(int CallerID) 115 { 116 int CallerCell = GetActorCell(CallerID); 117 118 Cell* AdjecentCellIndex[9]; 119 GetAdjacentCells(CallerCell, AdjecentCellIndex); 120 121 for (int i = 0; i < 9; i++) 122 { 123 if (AdjecentCellIndex[i] != NULL) 124 { 125 Node** ActorTreeArray = (AdjecentCellIndex[i]->GetActorTree())->Dump(); 126 if (ActorTreeArray != NULL) 127 { 128 for (int j = 0; j < (AdjecentCellIndex[i]->GetActorTree())->Size(); j++) 129 { 130 if (DetectActorCollision(CallerID, ActorTreeArray[j]->GetItem()) == true) 131 { 132 mAHM->GetActorAddress(CallerID)->EventProcess(Event(ACTOR_COLLISION, ActorTreeArray[j]->GetItem())); 133 } 134 } 135 } 136 else 137 { 138 //gCons->ConsPrintf("Cell is empty/n"); 139 } 140 } 141 else 142 { 143 //Cell does not exist. do nothing 144 } 145 } 146 147 return true; 148 } 149 150 bool SpatialMonitor::HandleRectSensors(SDL_Rect* sensor, int CallerID, SensorType SeType) 151 { 152 int CallerCell = GetActorCell(CallerID); 153 154 Cell* AdjecentCellIndex[9]; 155 GetAdjacentCells(CallerCell, AdjecentCellIndex); 156 157 for (int i = 0; i < 9; i++) 158 { 159 if (AdjecentCellIndex[i] != NULL) 160 { 161 Node** ActorTreeArray = (AdjecentCellIndex[i]->GetActorTree())->Dump(); 162 163 if (ActorTreeArray != NULL) 164 { 165 for (int j = 0; j < (AdjecentCellIndex[i]->GetActorTree())->Size(); j++) 166 { 167 Node* debugtool = ActorTreeArray[j]; 168 if (DetectRectSensors(sensor, CallerID, ActorTreeArray[j]->GetItem()) == true) 169 { 170 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 171 } 172 } 173 } 174 else 175 { 176 //gCons->ConsPrintf("Cell is empty/n"); 177 } 178 } 179 else 180 { 181 //Cell does not exist. do nothing 182 } 183 } 184 return true; 185 } 186 187 bool SpatialMonitor::TestBlockers(SDL_Rect* sensor, int CallerID) 188 { 189 int CallerCell = GetActorCell(CallerID); 190 191 Cell* AdjecentCellIndex[9]; 192 GetAdjacentCells(CallerCell, AdjecentCellIndex); 193 194 for (int i = 0; i < 9; i++) 195 { 196 if (AdjecentCellIndex[i] != NULL) 197 { 198 Node** ActorTreeArray = ((AdjecentCellIndex[i]->GetActorTree())->Dump()); 199 if (ActorTreeArray != NULL) 200 { 201 for (int j = 0; j < (AdjecentCellIndex[i]->GetActorTree())->Size(); j++) 202 { 203 if (DetectRectSensors(sensor, CallerID, ActorTreeArray[j]->GetItem()) == true) 204 { 205 if (mAHM->GetActorAddress(ActorTreeArray[j]->GetItem())->IsBlocking() == true) 206 { 207 return true; 208 } 209 } 210 } 211 } 212 else 213 { 214 //gCons->ConsPrintf("Cell is empty/n"); 215 } 216 } 217 else 218 { 219 //Cell does not exist. do nothing 220 } 221 } 222 return false; 223 } 224 225 bool SpatialMonitor::EventProcess(Event eve) 226 { 227 switch (*eve.GetEventType()) 228 { 229 case MOVED_THIS_FRAME: 230 UpdateActorCell(eve.GetEventData()->i); 231 HandleCollisions(eve.GetEventData()->i); 232 return true; 233 break; 234 case CHECK_RECT_SENSOR: 235 HandleRectSensors(eve.GetEventData()->sd.sensor, eve.GetEventData()->sd.id, eve.GetEventData()->sd.st); 236 return true; 237 break; 238 case CHECK_BLOCKERS: 239 return TestBlockers(eve.GetEventData()->sd.sensor, eve.GetEventData()->sd.id); 240 break; 241 default: 242 gCons->ConsPrintf("Spatial Monitor Received Invalid Event Type\n"); 243 return false; 244 break; 245 } 246 }