Skip to content

Commit cf4dba5

Browse files
committed
Move a StraightTrajectory’s function to PhobosTrajectoryType
- Function: `GetCellsInProximityRadius` with `GetCellsInRectangle`. - Removed three redundant undefined functions.
1 parent 033dbf0 commit cf4dba5

File tree

4 files changed

+283
-283
lines changed

4 files changed

+283
-283
lines changed

src/Ext/Bullet/Trajectories/PhobosTrajectory.cpp

Lines changed: 277 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,283 @@ bool TrajectoryPointer::Save(PhobosStreamWriter& Stm) const
139139

140140
// ------------------------------------------------------------------------------ //
141141

142+
// A rectangular shape with a custom width from the current frame to the next frame in length.
143+
std::vector<CellClass*> PhobosTrajectoryType::GetCellsInProximityRadius(BulletClass* pBullet, Leptons trajectoryProximityRange)
144+
{
145+
// Seems like the y-axis is reversed, but it's okay.
146+
const CoordStruct walkCoord { static_cast<int>(pBullet->Velocity.X), static_cast<int>(pBullet->Velocity.Y), 0 };
147+
const auto sideMult = trajectoryProximityRange / walkCoord.Magnitude();
148+
149+
const CoordStruct cor1Coord { static_cast<int>(walkCoord.Y * sideMult), static_cast<int>((-walkCoord.X) * sideMult), 0 };
150+
const CoordStruct cor4Coord { static_cast<int>((-walkCoord.Y) * sideMult), static_cast<int>(walkCoord.X * sideMult), 0 };
151+
const auto thisCell = CellClass::Coord2Cell(pBullet->Location);
152+
153+
auto cor1Cell = CellClass::Coord2Cell((pBullet->Location + cor1Coord));
154+
auto cor4Cell = CellClass::Coord2Cell((pBullet->Location + cor4Coord));
155+
156+
const auto off1Cell = cor1Cell - thisCell;
157+
const auto off4Cell = cor4Cell - thisCell;
158+
const auto nextCell = CellClass::Coord2Cell((pBullet->Location + walkCoord));
159+
160+
auto cor2Cell = nextCell + off1Cell;
161+
auto cor3Cell = nextCell + off4Cell;
162+
163+
// Arrange the vertices of the rectangle in order from bottom to top.
164+
int cornerIndex = 0;
165+
CellStruct corner[4] = { cor1Cell, cor2Cell, cor3Cell, cor4Cell };
166+
167+
for (int i = 1; i < 4; ++i)
168+
{
169+
if (corner[cornerIndex].Y > corner[i].Y)
170+
cornerIndex = i;
171+
}
172+
173+
cor1Cell = corner[cornerIndex];
174+
++cornerIndex %= 4;
175+
cor2Cell = corner[cornerIndex];
176+
++cornerIndex %= 4;
177+
cor3Cell = corner[cornerIndex];
178+
++cornerIndex %= 4;
179+
cor4Cell = corner[cornerIndex];
180+
181+
std::vector<CellStruct> recCells = PhobosTrajectoryType::GetCellsInRectangle(cor1Cell, cor4Cell, cor2Cell, cor3Cell);
182+
std::vector<CellClass*> recCellClass;
183+
recCellClass.reserve(recCells.size());
184+
185+
for (const auto& pCells : recCells)
186+
{
187+
if (CellClass* pRecCell = MapClass::Instance->TryGetCellAt(pCells))
188+
recCellClass.push_back(pRecCell);
189+
}
190+
191+
return recCellClass;
192+
}
193+
194+
// Can ONLY fill RECTANGLE. Record cells in the order of "draw left boundary, draw right boundary, fill middle, and move up one level".
195+
std::vector<CellStruct> PhobosTrajectoryType::GetCellsInRectangle(CellStruct bottomStaCell, CellStruct leftMidCell, CellStruct rightMidCell, CellStruct topEndCell)
196+
{
197+
std::vector<CellStruct> recCells;
198+
const auto cellNums = (std::abs(topEndCell.Y - bottomStaCell.Y) + 1) * (std::abs(rightMidCell.X - leftMidCell.X) + 1);
199+
recCells.reserve(cellNums);
200+
recCells.push_back(bottomStaCell);
201+
202+
if (bottomStaCell == leftMidCell || bottomStaCell == rightMidCell) // A straight line
203+
{
204+
auto middleCurCell = bottomStaCell;
205+
206+
const auto middleTheDist = topEndCell - bottomStaCell;
207+
const CellStruct middleTheUnit { static_cast<short>(Math::sgn(middleTheDist.X)), static_cast<short>(Math::sgn(middleTheDist.Y)) };
208+
const CellStruct middleThePace { static_cast<short>(middleTheDist.X * middleTheUnit.X), static_cast<short>(middleTheDist.Y * middleTheUnit.Y) };
209+
auto mTheCurN = static_cast<float>((middleThePace.Y - middleThePace.X) / 2.0);
210+
211+
while (middleCurCell != topEndCell)
212+
{
213+
if (mTheCurN > 0)
214+
{
215+
mTheCurN -= middleThePace.X;
216+
middleCurCell.Y += middleTheUnit.Y;
217+
recCells.push_back(middleCurCell);
218+
}
219+
else if (mTheCurN < 0)
220+
{
221+
mTheCurN += middleThePace.Y;
222+
middleCurCell.X += middleTheUnit.X;
223+
recCells.push_back(middleCurCell);
224+
}
225+
else
226+
{
227+
mTheCurN += middleThePace.Y - middleThePace.X;
228+
middleCurCell.X += middleTheUnit.X;
229+
recCells.push_back(middleCurCell);
230+
middleCurCell.X -= middleTheUnit.X;
231+
middleCurCell.Y += middleTheUnit.Y;
232+
recCells.push_back(middleCurCell);
233+
middleCurCell.X += middleTheUnit.X;
234+
recCells.push_back(middleCurCell);
235+
}
236+
}
237+
}
238+
else // Complete rectangle
239+
{
240+
auto leftCurCell = bottomStaCell;
241+
auto rightCurCell = bottomStaCell;
242+
auto middleCurCell = bottomStaCell;
243+
244+
bool leftNext = false;
245+
bool rightNext = false;
246+
bool leftSkip = false;
247+
bool rightSkip = false;
248+
bool leftContinue = false;
249+
bool rightContinue = false;
250+
251+
const auto left1stDist = leftMidCell - bottomStaCell;
252+
const CellStruct left1stUnit { static_cast<short>(Math::sgn(left1stDist.X)), static_cast<short>(Math::sgn(left1stDist.Y)) };
253+
const CellStruct left1stPace { static_cast<short>(left1stDist.X * left1stUnit.X), static_cast<short>(left1stDist.Y * left1stUnit.Y) };
254+
auto left1stCurN = static_cast<float>((left1stPace.Y - left1stPace.X) / 2.0);
255+
256+
const auto left2ndDist = topEndCell - leftMidCell;
257+
const CellStruct left2ndUnit { static_cast<short>(Math::sgn(left2ndDist.X)), static_cast<short>(Math::sgn(left2ndDist.Y)) };
258+
const CellStruct left2ndPace { static_cast<short>(left2ndDist.X * left2ndUnit.X), static_cast<short>(left2ndDist.Y * left2ndUnit.Y) };
259+
auto left2ndCurN = static_cast<float>((left2ndPace.Y - left2ndPace.X) / 2.0);
260+
261+
const auto right1stDist = rightMidCell - bottomStaCell;
262+
const CellStruct right1stUnit { static_cast<short>(Math::sgn(right1stDist.X)), static_cast<short>(Math::sgn(right1stDist.Y)) };
263+
const CellStruct right1stPace { static_cast<short>(right1stDist.X * right1stUnit.X), static_cast<short>(right1stDist.Y * right1stUnit.Y) };
264+
auto right1stCurN = static_cast<float>((right1stPace.Y - right1stPace.X) / 2.0);
265+
266+
const auto right2ndDist = topEndCell - rightMidCell;
267+
const CellStruct right2ndUnit { static_cast<short>(Math::sgn(right2ndDist.X)), static_cast<short>(Math::sgn(right2ndDist.Y)) };
268+
const CellStruct right2ndPace { static_cast<short>(right2ndDist.X * right2ndUnit.X), static_cast<short>(right2ndDist.Y * right2ndUnit.Y) };
269+
auto right2ndCurN = static_cast<float>((right2ndPace.Y - right2ndPace.X) / 2.0);
270+
271+
while (leftCurCell != topEndCell || rightCurCell != topEndCell)
272+
{
273+
while (leftCurCell != topEndCell) // Left
274+
{
275+
if (!leftNext) // Bottom Left Side
276+
{
277+
if (left1stCurN > 0)
278+
{
279+
left1stCurN -= left1stPace.X;
280+
leftCurCell.Y += left1stUnit.Y;
281+
282+
if (leftCurCell == leftMidCell)
283+
{
284+
leftNext = true;
285+
}
286+
else
287+
{
288+
recCells.push_back(leftCurCell);
289+
break;
290+
}
291+
}
292+
else
293+
{
294+
left1stCurN += left1stPace.Y;
295+
leftCurCell.X += left1stUnit.X;
296+
297+
if (leftCurCell == leftMidCell)
298+
{
299+
leftNext = true;
300+
leftSkip = true;
301+
}
302+
}
303+
}
304+
else // Top Left Side
305+
{
306+
if (left2ndCurN >= 0)
307+
{
308+
if (leftSkip)
309+
{
310+
leftSkip = false;
311+
left2ndCurN -= left2ndPace.X;
312+
leftCurCell.Y += left2ndUnit.Y;
313+
}
314+
else
315+
{
316+
leftContinue = true;
317+
break;
318+
}
319+
}
320+
else
321+
{
322+
left2ndCurN += left2ndPace.Y;
323+
leftCurCell.X += left2ndUnit.X;
324+
}
325+
}
326+
327+
if (leftCurCell != rightCurCell) // Avoid double counting cells.
328+
recCells.push_back(leftCurCell);
329+
}
330+
331+
while (rightCurCell != topEndCell) // Right
332+
{
333+
if (!rightNext) // Bottom Right Side
334+
{
335+
if (right1stCurN > 0)
336+
{
337+
right1stCurN -= right1stPace.X;
338+
rightCurCell.Y += right1stUnit.Y;
339+
340+
if (rightCurCell == rightMidCell)
341+
{
342+
rightNext = true;
343+
}
344+
else
345+
{
346+
recCells.push_back(rightCurCell);
347+
break;
348+
}
349+
}
350+
else
351+
{
352+
right1stCurN += right1stPace.Y;
353+
rightCurCell.X += right1stUnit.X;
354+
355+
if (rightCurCell == rightMidCell)
356+
{
357+
rightNext = true;
358+
rightSkip = true;
359+
}
360+
}
361+
}
362+
else // Top Right Side
363+
{
364+
if (right2ndCurN >= 0)
365+
{
366+
if (rightSkip)
367+
{
368+
rightSkip = false;
369+
right2ndCurN -= right2ndPace.X;
370+
rightCurCell.Y += right2ndUnit.Y;
371+
}
372+
else
373+
{
374+
rightContinue = true;
375+
break;
376+
}
377+
}
378+
else
379+
{
380+
right2ndCurN += right2ndPace.Y;
381+
rightCurCell.X += right2ndUnit.X;
382+
}
383+
}
384+
385+
if (rightCurCell != leftCurCell) // Avoid double counting cells.
386+
recCells.push_back(rightCurCell);
387+
}
388+
389+
middleCurCell = leftCurCell;
390+
middleCurCell.X += 1;
391+
392+
while (middleCurCell.X < rightCurCell.X) // Center
393+
{
394+
recCells.push_back(middleCurCell);
395+
middleCurCell.X += 1;
396+
}
397+
398+
if (leftContinue) // Continue Top Left Side
399+
{
400+
leftContinue = false;
401+
left2ndCurN -= left2ndPace.X;
402+
leftCurCell.Y += left2ndUnit.Y;
403+
recCells.push_back(leftCurCell);
404+
}
405+
406+
if (rightContinue) // Continue Top Right Side
407+
{
408+
rightContinue = false;
409+
right2ndCurN -= right2ndPace.X;
410+
rightCurCell.Y += right2ndUnit.Y;
411+
recCells.push_back(rightCurCell);
412+
}
413+
}
414+
}
415+
416+
return recCells;
417+
}
418+
142419
bool PhobosTrajectoryType::Load(PhobosStreamReader& Stm, bool RegisterForChange)
143420
{
144421
Stm

src/Ext/Bullet/Trajectories/PhobosTrajectory.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,11 @@ class PhobosTrajectoryType
3232
virtual void Read(CCINIClass* const pINI, const char* pSection) = 0;
3333
[[nodiscard]] virtual std::unique_ptr<PhobosTrajectory> CreateInstance() const = 0;
3434

35+
static std::vector<CellClass*> GetCellsInProximityRadius(BulletClass* pBullet, Leptons trajectoryProximityRange);
36+
private:
37+
static std::vector<CellStruct> GetCellsInRectangle(CellStruct bottomStaCell, CellStruct leftMidCell, CellStruct rightMidCell, CellStruct topEndCell);
38+
39+
public:
3540
Valueable<double> Trajectory_Speed { 100.0 };
3641
};
3742

0 commit comments

Comments
 (0)