1e9e815a80a89d81879d36b8f1bfd91a90c50357.svn-base (4625B)
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 SDL_Rect cell; 13 cell.w = cellW; 14 cell.h = cellH; 15 cell.x = cellW * j; 16 cell.y = cellH * i; 17 18 mCells[i*CELLS_X + j] = cell; 19 20 } 21 } 22 return true; 23 } 24 25 bool SpatialMonitor::LogActor(Actor& act) 26 { 27 if (mActorCount < MAX_ACTORS) 28 { 29 mActors[mActorCount] = &act; 30 act.SetSpatID(mActorCount); 31 UpdateActorCell(mActorCount); 32 mActorCount += 1; 33 return true; 34 } 35 else 36 { 37 gCons->ConsPrintf("Failed to Log Actor. Spatial Monitor actor capacity reached! \n"); 38 return false; 39 } 40 } 41 42 int SpatialMonitor::UpdateActorCell(int id) 43 { 44 for (int i = 0; i < CELL_COUNT; i++) 45 { 46 if (DetectCenterPointIntersect(&mCells[i], mActors[id]->GetPosition())) 47 { 48 //gCons->ConsPrintf("Actor entering cell %i\n", i); 49 mActorCells[id] = i; 50 return i; 51 } 52 } 53 gCons->ConsPrintf("Could not find Actor cell\n"); 54 return -1; 55 } 56 57 int* SpatialMonitor::GetAdjacentCells(int cellnum, int cells[9]) 58 { 59 cells[0] = (cellnum - CELLS_X - 1); 60 cells[1] = (cellnum - CELLS_X); 61 cells[2] = (cellnum - CELLS_X + 1); 62 63 cells[3] = (cellnum - 1); 64 cells[4] = (cellnum); 65 cells[5] = (cellnum + 1); 66 67 cells[6] = (cellnum + CELLS_X - 1); 68 cells[7] = (cellnum + CELLS_X); 69 cells[8] = (cellnum + CELLS_X + 1); 70 71 return cells; 72 } 73 74 bool SpatialMonitor::GetActorsInCell(int cellnum) 75 { 76 for (int i = 0; i < MAX_ACTORS; i++) 77 { 78 if (mActorCells[i] == cellnum) 79 { 80 //gCons->ConsPrintf("Actor %i is in adjacent cell\n", i); 81 mAdjacentActorIDs[mAdjacentActorCount] = i; 82 mAdjacentActorCount++; 83 } 84 } 85 return true; 86 } 87 88 bool SpatialMonitor::GetAdjacentActors(int cellnum) 89 { 90 mAdjacentActorCount = 0; 91 mAdjacentActorIDs[MAX_ACTORS] = { 0 }; 92 93 int cells[9]; 94 GetAdjacentCells(cellnum, cells); 95 96 for (int i = 0; i < 9; i++) 97 { 98 GetActorsInCell(cells[i]); 99 //gDiagDraw->LogDiagRect(mCells[cells[i]]); 100 } 101 return true; 102 } 103 104 bool SpatialMonitor::DetectActorCollision(int id1, int id2) 105 { 106 if (id1 != id2) 107 { 108 //gDiagDraw->LogDiagRect(*mActors[id2]->GetPosition()); 109 return DetectRectIntersect(mActors[id1]->GetPosition(), mActors[id2]->GetPosition()); 110 } 111 else 112 { 113 //gCons->ConsPrintf("Attempted to check actor collision with itself\n"); 114 return false; 115 } 116 } 117 118 bool SpatialMonitor::DetectRectSensors(SDL_Rect* sensor, int DetectorID, int foreignID) 119 { 120 if (DetectorID != foreignID) 121 { 122 //gDiagDraw->LogDiagRect(*sensor); 123 //gDiagDraw->LogDiagRect(*mActors[foreignID]->GetPosition()); 124 return DetectRectIntersect(sensor, mActors[foreignID]->GetPosition()); 125 } 126 else 127 { 128 //gCons->ConsPrintf("Attempted to check actor collision with itself\n"); 129 return false; 130 } 131 } 132 133 bool SpatialMonitor::HandleCollisions(int CallerID) 134 { 135 int CallerCell = GetActorCell(CallerID); 136 GetAdjacentActors(CallerCell); 137 138 for (int i = 0; i < mAdjacentActorCount; i++) 139 { 140 if (DetectActorCollision(CallerID, mAdjacentActorIDs[i]) == true) //i is the wrong value 141 { 142 mActors[CallerID]->EventProcess(Event(ACTOR_COLLISION, mActors[mAdjacentActorIDs[i]])); 143 } 144 } 145 return true; 146 } 147 148 bool SpatialMonitor::HandleRectSensors(SDL_Rect* sensor, int CallerID, SensorType SeType) 149 { 150 int CallerCell = GetActorCell(CallerID); 151 GetAdjacentActors(CallerCell); 152 153 for (int i = 0; i < mAdjacentActorCount; i++) 154 { 155 if (DetectRectSensors(sensor, CallerID, mAdjacentActorIDs[i]) == true) 156 { 157 mActors[CallerID]->EventProcess(Event(SENSOR_COLLISION, SeType, mActors[mAdjacentActorIDs[i]])); 158 } 159 } 160 return true; 161 } 162 163 bool SpatialMonitor::TestBlockers(SDL_Rect* sensor, int CallerID) 164 { 165 int CallerCell = GetActorCell(CallerID); 166 GetAdjacentActors(CallerCell); 167 168 for (int i = 0; i < mAdjacentActorCount; i++) 169 { 170 if (DetectRectSensors(sensor, CallerID, mAdjacentActorIDs[i]) == true) 171 { 172 if (mActors[mAdjacentActorIDs[i]]->IsBlocking() == true) 173 { 174 return true; 175 } 176 //mActors[CallerID]->EventProcess(Event(SENSOR_COLLISION, SeType, mActors[i])); 177 } 178 } 179 return false; 180 } 181 182 bool SpatialMonitor::EventProcess(Event eve) 183 { 184 switch (*eve.GetEventType()) 185 { 186 case MOVED_THIS_FRAME: 187 UpdateActorCell(eve.GetEventData()->i); 188 HandleCollisions(eve.GetEventData()->i); 189 return true; 190 break; 191 case CHECK_RECT_SENSOR: 192 HandleRectSensors(eve.GetEventData()->sd.sensor, eve.GetEventData()->sd.ID, eve.GetEventData()->sd.st); 193 return true; 194 break; 195 case CHECK_BLOCKERS: 196 return TestBlockers(eve.GetEventData()->sd.sensor, eve.GetEventData()->sd.ID); 197 break; 198 default: 199 gCons->ConsPrintf("Spatial Monitor Received Invalid Event Type\n"); 200 return false; 201 break; 202 } 203 }