3 protected static const float MAX_TRACE_LENGTH = 100;
14 static float GetTerrainY(vector pos, BaseWorld world =
null,
bool noUnderwater =
false, TraceParam trace =
null)
25 trace.End = Vector(pos[0], pos[1] - MAX_TRACE_LENGTH, pos[2]);
28 trace.Flags = TraceFlags.WORLD | TraceFlags.ENTS;
30 float traceCoef = world.TraceMove(trace,
null);
32 surfaceY = trace.Start[1] - (trace.Start[1] - trace.End[1]) * traceCoef;
36 surfaceY = world.GetSurfaceY(pos[0], pos[2]);
39 surfaceY = Math.Max(surfaceY, 0);
53 static float GetHeightAboveTerrain(vector pos, BaseWorld world =
null,
bool noUnderwater =
false, TraceParam trace =
null)
55 return pos[1] - GetTerrainY(pos, world, noUnderwater, trace);
67 static vector GetTerrainNormal(inout vector pos, BaseWorld world =
null,
bool noUnderwater =
false, TraceParam trace =
null)
80 pos[1] = Math.Max(pos[1], world.GetSurfaceY(pos[0], pos[2]) + 0.01);
83 trace.End = Vector(pos[0], pos[1] - MAX_TRACE_LENGTH, pos[2]);
86 trace.Flags = TraceFlags.WORLD | TraceFlags.ENTS;
88 float traceCoef = world.TraceMove(trace,
null);
91 pos[1] = trace.Start[1] - (trace.Start[1] - trace.End[1]) * traceCoef;
92 if (noUnderwater && pos[1] < world.GetOceanBaseHeight())
95 pos[1] = Math.Max(pos[1], world.GetOceanBaseHeight());
98 return trace.TraceNorm;
104 float surfaceY = world.GetSurfaceY(pos[0], pos[2]);
105 if (noUnderwater && surfaceY < world.GetOceanBaseHeight())
107 pos[1] = Math.Max(surfaceY, world.GetOceanBaseHeight());
113 TraceParam traceRef =
new TraceParam();
114 traceRef.Start = pos + vector.Up;
115 traceRef.End = pos - vector.Up;
116 traceRef.Flags = TraceFlags.WORLD;
117 world.TraceMove(traceRef,
null);
119 return traceRef.TraceNorm;
132 static bool GetTerrainBasis(vector pos, out vector result[4], BaseWorld world =
null,
bool noUnderwater =
false, TraceParam trace =
null)
134 vector normal = GetTerrainNormal(pos, world, noUnderwater, trace);
135 if (normal == vector.Zero)
139 vector perpend = normal.Perpend();
140 Math3D.DirectionAndUpMatrix(perpend, normal, result);
144 Math3D.AnglesToMatrix(Vector(-perpend.VectorToAngles()[0], 0, 0), basis);
145 Math3D.MatrixMultiply3(result, basis, result);
162 static bool SnapToTerrain(out vector transform[4], BaseWorld world =
null,
bool noUnderwater =
false, TraceParam trace =
null)
172 vector surfaceBasis[4];
173 if (!GetTerrainBasis(transform[3], surfaceBasis, world, noUnderwater, trace))
177 transform[3] = surfaceBasis[3];
190 static bool OrientToTerrain(out vector transform[4], BaseWorld world =
null,
bool noUnderwater =
false, TraceParam trace =
null)
200 vector surfaceBasis[4];
201 if (!GetTerrainBasis(transform[3], surfaceBasis, world, noUnderwater, trace))
209 Math3D.MatrixMultiply3(surfaceBasis, transform, transform);
223 static bool SnapAndOrientToTerrain(out vector transform[4], BaseWorld world =
null,
bool noUnderwater =
false, TraceParam trace =
null)
233 vector surfaceBasis[4];
234 if (!GetTerrainBasis(transform[3], surfaceBasis, world, noUnderwater, trace))
238 transform[3] = surfaceBasis[3];
245 Math3D.MatrixMultiply3(surfaceBasis, transform, transform);