Arma Reforger Explorer 1.7.0.54
Arma Reforger Code Explorer by Zeroy - Thanks to MisterOutofTime
Loading...
Searching...
No Matches
SCR_WorldTools.c
Go to the documentation of this file.
2{
3 //------------------------------------------------------------------------------------------------
14 static bool TraceCylinder(vector pos, float radius = 0.5, float height = 2, TraceFlags flags = TraceFlags.ENTS | TraceFlags.OCEAN, BaseWorld world = null)
15 {
16 if (!world)
17 world = GetGame().GetWorld();
18
19 float heightHalf = height * 0.5;
20
21 autoptr TraceParam trace = new TraceParam();
22 trace.Flags = flags;
23
24 vector dir = Vector(radius, heightHalf, 0);
25 trace.Start = pos + dir;
26 trace.End = pos - dir;
27 if (world.TraceMove(trace, null) < 1)
28 return false;
29
30 dir = Vector(-radius, heightHalf, 0);
31 trace.Start = pos + dir;
32 trace.End = pos - dir;
33 if (world.TraceMove(trace, null) < 1)
34 return false;
35
36 dir = Vector(0, heightHalf, radius);
37 trace.Start = pos + dir;
38 trace.End = pos - dir;
39 if (world.TraceMove(trace, null) < 1)
40 return false;
41
42 dir = Vector(0, heightHalf, -radius);
43 trace.Start = pos + dir;
44 trace.End = pos - dir;
45 if (world.TraceMove(trace, null) < 1)
46 return false;
47
48 return true;
49 }
50
51 //------------------------------------------------------------------------------------------------
64 static bool FindEmptyTerrainPosition(out vector outPosition, vector areaCenter, float areaRadius, float cylinderRadius = 0.5, float cylinderHeight = 2, TraceFlags flags = TraceFlags.ENTS | TraceFlags.OCEAN, BaseWorld world = null)
65 {
66 //--- Incorrect params
67 if (areaRadius <= 0 || cylinderRadius <= 0 || cylinderHeight <= 0)
68 {
69 outPosition = areaCenter;
70 return false;
71 }
72
73 if (!world)
74 world = GetGame().GetWorld();
75
76 //--- Precalculate vars
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));
81 TraceParam trace = new TraceParam();
82 trace.Flags = flags | TraceFlags.WORLD;
83 vector traceOffset = {0, 10, 0};
84 TraceParam traceUp = new TraceParam();
85 traceUp.Flags = flags | TraceFlags.WORLD;
86 vector traceUpOffset = {0, 10, 0};
87 float maxDist = areaRadius - cylinderRadius;
88 float maxDistSq = maxDist * maxDist;
89 float posX, posY;
90 int yMin, yMax, yStep;
91 float traceCoef;
92 for (int r; r < rMax; r++)
93 {
94 for (int x = -r; x <= r; x++)
95 {
96 posX = cellW * x;
97 posY = cellH * (x - SCR_Math.fmod(x, 1)) * 0.5;
98
99 yMin = Math.Max(-r - x, -r);
100 yMax = Math.Min(r - x, r);
101 if (Math.AbsInt(x) == r)
102 yStep = 1;
103 else
104 yStep = yMax - yMin;
105
106 for (int y = yMin; y <= yMax; y += yStep)
107 {
108 outPosition = areaCenter + {posX, 0, posY + cellH * y};
109 if (vector.DistanceSqXZ(outPosition, areaCenter) > maxDistSq)
110 continue;
111
112 //--- Find nearest surface below (make sure it's not underground)
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]));
117
118 //--- Check if postion is inside the rock
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))
123 continue;
124
125 if (TraceCylinder(outPosition + cylinderVectorOffset, cylinderRadius, cylinderHeight, flags, world))
126 return true;
127 }
128 }
129 }
130 outPosition = areaCenter;
131 return false;
132 }
133
134 //------------------------------------------------------------------------------------------------
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)
149 {
150 //--- Incorrect params
151 if (areaRadius <= 0 || cylinderRadius <= 0 || cylinderHeight <= 0)
152 return 0;
153
154 if (!world)
155 world = GetGame().GetWorld();
156
157 //--- Precalculate vars
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));
162
163 TraceParam trace = new TraceParam();
164 trace.Flags = flags | TraceFlags.WORLD;
165 vector traceOffset = Vector(0, 10, 0);
166
168 float posX, posY;
169 int yMin, yMax, yStep;
170 float traceCoef;
171 for (int r; r < rMax; r++)
172 {
173 for (int x = -r; x <= r; x++)
174 {
175 posX = cellW * x;
176 posY = cellH * (x - SCR_Math.fmod(x, 1)) * 0.5;
177
178 yMin = Math.Max(-r - x, -r);
179 yMax = Math.Min(r - x, r);
180 if (Math.AbsInt(x) == r)
181 yStep = 1;
182 else
183 yStep = yMax - yMin;
184
185 for (int y = yMin; y <= yMax; y += yStep)
186 {
187 position = areaCenter + Vector(posX, 0, posY + cellH * y);
188 if (vector.DistanceXZ(position, areaCenter) > areaRadius - cylinderRadius)
189 continue;
190
191 //--- Find nearest surface below (make sure it's not underground)
192 trace.Start = position;
193 trace.End = position - traceOffset;
194 traceCoef = world.TraceMove(trace, null);
195 position[1] = Math.Max(trace.Start[1] - traceCoef * traceOffset[1] + 0.01, world.GetSurfaceY(position[0], position[2]));
196
197 if (TraceCylinder(position + cylinderVectorOffset, cylinderRadius, cylinderHeight, flags, world))
198 outPositions.Insert(position);
199 }
200
201 if (maxResults > -1 && outPositions.Count() >= maxResults)
202 break;
203 }
204 }
205 return outPositions.Count();
206 }
207
208 //------------------------------------------------------------------------------------------------
217 static bool IsObjectUnderwater(notnull IEntity object, vector position = vector.Zero, int boneID = -1, out float depth = -1)
218 {
219 BaseWorld world = object.GetWorld();
220 position = object.CoordToParent(position);
221
222 if (boneID >= 0)
223 {
224 Physics physics = object.GetPhysics();
225 if (physics)
226 position += physics.GetGeomPosition(boneID);
227 }
228
229 vector outWaterSurfacePoint;
230 EWaterSurfaceType outType;
231 vector transformWS[4];
232 vector obbExtents;
233
234 bool isUnderwater = ChimeraWorldUtils.TryGetWaterSurface(world, position, outWaterSurfacePoint, outType, transformWS, obbExtents);
235 if (isUnderwater)
236 depth = vector.Distance(outWaterSurfacePoint, position);
237
238 return isUnderwater;
239 }
240
241 //------------------------------------------------------------------------------------------------
242 static float GetWaterSurfaceY(BaseWorld world, vector worldPos, out EWaterSurfaceType waterSurfaceType, out float lakeArea)
243 {
244 vector waterSurfacePos;
245 vector transformWS[4];
246 vector obbExtents;
247
248 ChimeraWorldUtils.TryGetWaterSurface(world, worldPos, waterSurfacePos, waterSurfaceType, transformWS, obbExtents);
249 lakeArea = obbExtents[0] * obbExtents[2];
250
251 return waterSurfacePos[1];
252 }
253};
SCR_EAIThreatSectorFlags flags
EWaterSurfaceType
ArmaReforgerScripted GetGame()
Definition game.c:1398
vector position
Definition Math.c:13
static float fmod(float dividend, float divisor)
Definition SCR_Math.c:114
proto native vector Vector(float x, float y, float z)
TraceFlags
Definition TraceFlags.c:13