* Calculates a line trajectory, using bresenham algorithm in 3D. * @param origin Origin (voxel??). * @param target Target (also voxel??). * @param storeTrajectory True will store the whole trajectory - otherwise it just stores the last position. * @param trajectory A vector of positions in which the trajectory is stored. * @param excludeUnit Excludes this unit in the collision detection. * @
| 2018 | * @return the objectnumber(0-3) or unit(4) or out of map (5) or -1(hit nothing). |
| 2019 | */ |
| 2020 | int TileEngine::calculateLine(const Position& origin, const Position& target, bool storeTrajectory, std::vector<Position> *trajectory, BattleUnit *excludeUnit, bool doVoxelCheck, bool onlyVisible, BattleUnit *excludeAllBut) |
| 2021 | { |
| 2022 | int x, x0, x1, delta_x, step_x; |
| 2023 | int y, y0, y1, delta_y, step_y; |
| 2024 | int z, z0, z1, delta_z, step_z; |
| 2025 | int swap_xy, swap_xz; |
| 2026 | int drift_xy, drift_xz; |
| 2027 | int cx, cy, cz; |
| 2028 | Position lastPoint(origin); |
| 2029 | int result; |
| 2030 | |
| 2031 | //start and end points |
| 2032 | x0 = origin.x; x1 = target.x; |
| 2033 | y0 = origin.y; y1 = target.y; |
| 2034 | z0 = origin.z; z1 = target.z; |
| 2035 | |
| 2036 | //'steep' xy Line, make longest delta x plane |
| 2037 | swap_xy = abs(y1 - y0) > abs(x1 - x0); |
| 2038 | if (swap_xy) |
| 2039 | { |
| 2040 | std::swap(x0, y0); |
| 2041 | std::swap(x1, y1); |
| 2042 | } |
| 2043 | |
| 2044 | //do same for xz |
| 2045 | swap_xz = abs(z1 - z0) > abs(x1 - x0); |
| 2046 | if (swap_xz) |
| 2047 | { |
| 2048 | std::swap(x0, z0); |
| 2049 | std::swap(x1, z1); |
| 2050 | } |
| 2051 | |
| 2052 | //delta is Length in each plane |
| 2053 | delta_x = abs(x1 - x0); |
| 2054 | delta_y = abs(y1 - y0); |
| 2055 | delta_z = abs(z1 - z0); |
| 2056 | |
| 2057 | //drift controls when to step in 'shallow' planes |
| 2058 | //starting value keeps Line centred |
| 2059 | drift_xy = (delta_x / 2); |
| 2060 | drift_xz = (delta_x / 2); |
| 2061 | |
| 2062 | //direction of line |
| 2063 | step_x = 1; if (x0 > x1) { step_x = -1; } |
| 2064 | step_y = 1; if (y0 > y1) { step_y = -1; } |
| 2065 | step_z = 1; if (z0 > z1) { step_z = -1; } |
| 2066 | |
| 2067 | //starting point |
| 2068 | y = y0; |
| 2069 | z = z0; |
| 2070 | |
| 2071 | //step through longest delta (which we have swapped to x) |
| 2072 | for (x = x0; x != (x1+step_x); x += step_x) |
| 2073 | { |
| 2074 | //copy position |
| 2075 | cx = x; cy = y; cz = z; |
| 2076 | |
| 2077 | //unswap (in reverse) |
no test coverage detected