| 26 | */ |
| 27 | |
| 28 | void Shape::SurfaceSplit(const Landscape* land, const Matrix4& toWorld, float y, float useOrigY) |
| 29 | { |
| 30 | // selection must be ingored: otherwise they would be invalidated |
| 31 | _sel.Clear(); |
| 32 | // start: fit all vertices to landscape |
| 33 | Matrix4 fromWorld(MInverseGeneral, toWorld); |
| 34 | |
| 35 | FaceArray splitFaces(_face.Size() * 3 + 16, false); |
| 36 | |
| 37 | // determine range of landscape squares polygon is in |
| 38 | Vector3 sNo(1, 0, 0); |
| 39 | Vector3 uNo(0, 0, 1); |
| 40 | Vector3 cNo(+H_SQRT2 / 2, 0, +H_SQRT2 / 2); |
| 41 | |
| 42 | Poly zTemp1, zTemp2; |
| 43 | Poly xTemp1, xTemp2; |
| 44 | Poly splitA, splitB; |
| 45 | for (Offset i = BeginFaces(), e = EndFaces(); i < e; NextFace(i)) |
| 46 | { |
| 47 | Poly source = Face(i); |
| 48 | |
| 49 | if (source.N() <= 0) |
| 50 | { |
| 51 | LOG_DEBUG(Graphics, "Invalid source?"); |
| 52 | continue; |
| 53 | } |
| 54 | |
| 55 | Vector3 pos(VFastTransform, toWorld, Pos(source.GetVertex(0))); |
| 56 | float xFMin = pos.X(), xFMax = xFMin; |
| 57 | float zFMin = pos.Z(), zFMax = zFMin; |
| 58 | for (int vi = 1; vi < source.N(); vi++) |
| 59 | { |
| 60 | Vector3 pos(VFastTransform, toWorld, Pos(source.GetVertex(vi))); |
| 61 | xFMin = floatMin(xFMin, pos.X()); |
| 62 | xFMax = floatMax(xFMax, pos.X()); |
| 63 | zFMin = floatMin(zFMin, pos.Z()); |
| 64 | zFMax = floatMax(zFMax, pos.Z()); |
| 65 | } |
| 66 | |
| 67 | int xMin = toIntFloor(xFMin * InvTerrainGrid); |
| 68 | int zMin = toIntFloor(zFMin * InvTerrainGrid); |
| 69 | int xMax = toIntFloor(xFMax * InvTerrainGrid); |
| 70 | int zMax = toIntFloor(zFMax * InvTerrainGrid); |
| 71 | |
| 72 | Poly* zRest = &source; |
| 73 | Poly* zSplit = &zTemp1; |
| 74 | Poly* zFree = &zTemp2; |
| 75 | for (int z = zMin; z <= zMax; z++) |
| 76 | { |
| 77 | float zT = z * TerrainGrid; |
| 78 | if (z < zMax) |
| 79 | { |
| 80 | float zB = (z + 1) * TerrainGrid; |
| 81 | Vector3 ptB = Vector3(0, 0, zB); |
| 82 | Plane bottom(-uNo, ptB); |
| 83 | // cut a part from zRest and use it for x-splitting |
| 84 | zRest->Split(toWorld, *this, *zSplit, *zFree, bottom.Normal(), bottom.D()); |
| 85 | zSplit->CopyProperties(*zRest); |
nothing calls this directly
no test coverage detected