19 float heightHalf = height * 0.5;
25 trace.Start = pos + dir;
26 trace.End = pos - dir;
27 if (world.TraceMove(trace, null) < 1)
30 dir =
Vector(-radius, heightHalf, 0);
31 trace.Start = pos + dir;
32 trace.End = pos - dir;
33 if (world.TraceMove(trace, null) < 1)
36 dir =
Vector(0, heightHalf, radius);
37 trace.Start = pos + dir;
38 trace.End = pos - dir;
39 if (world.TraceMove(trace, null) < 1)
42 dir =
Vector(0, heightHalf, -radius);
43 trace.Start = pos + dir;
44 trace.End = pos - dir;
45 if (world.TraceMove(trace, null) < 1)
67 if (areaRadius <= 0 || cylinderRadius <= 0 || cylinderHeight <= 0)
69 outPosition = areaCenter;
77 float cellW = cylinderRadius *
Math.Sqrt(3);
78 float cellH = cylinderRadius * 2;
79 vector cylinderVectorOffset = {0, cylinderHeight * 0.5, 0};
80 int rMax =
Math.Ceil(areaRadius / cylinderRadius /
Math.Sqrt(3));
83 vector traceOffset = {0, 10, 0};
86 vector traceUpOffset = {0, 10, 0};
87 float maxDist = areaRadius - cylinderRadius;
88 float maxDistSq = maxDist * maxDist;
90 int yMin, yMax, yStep;
92 for (
int r; r < rMax; r++)
94 for (
int x = -r; x <= r; x++)
99 yMin =
Math.Max(-r - x, -r);
100 yMax =
Math.Min(r - x, r);
101 if (
Math.AbsInt(x) == r)
106 for (
int y = yMin; y <= yMax; y += yStep)
108 outPosition = areaCenter + {posX, 0, posY + cellH * y};
109 if (
vector.DistanceSqXZ(outPosition, areaCenter) > maxDistSq)
113 trace.Start = outPosition;
114 trace.End = outPosition - traceOffset;
115 traceCoef = world.TraceMove(trace, null);
116 outPosition[1] =
Math.Max(trace.Start[1] - traceCoef * traceOffset[1] + 0.01, world.GetSurfaceY(outPosition[0], outPosition[2]));
119 traceUp.Start = outPosition +
Vector(0, 0.1, 0);
120 traceUp.End = traceUp.Start + traceUpOffset;
121 float traceUpCoef = world.TraceMove(traceUp, null);
122 if (traceUpCoef < 1.0 && traceUp.TraceEnt && traceUp.TraceEnt.IsInherited(SCR_IndestructibleEnvironmentalEntity))
125 if (TraceCylinder(outPosition + cylinderVectorOffset, cylinderRadius, cylinderHeight,
flags, world))
130 outPosition = areaCenter;
148 static int FindAllEmptyTerrainPositions(out notnull array<vector> outPositions,
vector areaCenter,
float areaRadius,
float cylinderRadius = 0.5,
float cylinderHeight = 2,
int maxResults = -1,
TraceFlags flags =
TraceFlags.ENTS |
TraceFlags.OCEAN,
BaseWorld world = null)
151 if (areaRadius <= 0 || cylinderRadius <= 0 || cylinderHeight <= 0)
158 float cellW = cylinderRadius *
Math.Sqrt(3);
159 float cellH = cylinderRadius * 2;
160 vector cylinderVectorOffset =
Vector(0, cylinderHeight * 0.5, 0);
161 int rMax =
Math.Ceil(areaRadius / cylinderRadius /
Math.Sqrt(3));
169 int yMin, yMax, yStep;
171 for (
int r; r < rMax; r++)
173 for (
int x = -r; x <= r; x++)
178 yMin =
Math.Max(-r - x, -r);
179 yMax =
Math.Min(r - x, r);
180 if (
Math.AbsInt(x) == r)
185 for (
int y = yMin; y <= yMax; y += yStep)
188 if (
vector.DistanceXZ(
position, areaCenter) > areaRadius - cylinderRadius)
194 traceCoef = world.TraceMove(trace, null);
197 if (TraceCylinder(
position + cylinderVectorOffset, cylinderRadius, cylinderHeight,
flags, world))
201 if (maxResults > -1 && outPositions.Count() >= maxResults)
205 return outPositions.Count();
224 Physics physics =
object.GetPhysics();
226 position += physics.GetGeomPosition(boneID);
229 vector outWaterSurfacePoint;
234 bool isUnderwater =
ChimeraWorldUtils.TryGetWaterSurface(world,
position, outWaterSurfacePoint, outType, transformWS, obbExtents);
248 ChimeraWorldUtils.TryGetWaterSurface(world, worldPos, waterSurfacePos, waterSurfaceType, transformWS, obbExtents);
249 lakeArea = obbExtents[0] * obbExtents[2];
251 return waterSurfacePos[1];