114 private string m_cameraEntityName;
117 private float m_FPSLimit;
119 [
Attribute(
"1.8",
UIWidgets.Slider,
"Distance between surface and camera on y-axis",
"0 20 0.1")]
120 private float m_HeightAboveSurface;
122 private float m_MovementSpeed;
124 [
Attribute(
"true",
UIWidgets.CheckBox,
"If true a path is generated otherwise the path is created from child waypoints")]
125 private bool m_GeneratePath;
126 [
Attribute(
"false",
UIWidgets.CheckBox,
"If true the generated path is drawn as a line - for debug purposes")]
127 private bool m_ShowGeneratePath;
128 [
Attribute(
"0.15",
UIWidgets.Slider,
"The scale of the generated path that is centered in the map center",
"0 1 0.01")]
129 private float m_GeneratedPathScale;
130 [
Attribute(
"10",
UIWidgets.Slider,
"Number of sectors for the generated path",
"1 100 1")]
131 private float m_GeneratedPathSectorsCount;
134 private Screenshot_Waypoint m_waypoint;
135 private string m_directory;
139 private ref array<Shape> m_CreatedLines;
141 private float m_fTimeToTravel = -1;
142 private float m_fTimeTraveled = 0;
144 private int m_iCurrentPointsI;
145 private ref array<vector> m_Points;
149 private ref Measurement m_MeasureFPS;
150 private ref Measurement m_MeasureMemory;
152 private ref array<ref Measurement> m_MeasurementMemory;
155 private string m_MotionZone;
163 m_CreatedLines =
new array<Shape>();
164 m_MeasureFPS =
new Measurement();
165 m_MeasureMemory =
new Measurement();
166 m_MeasurementMemory =
new array<ref Measurement>();
168 for (
int i = 0; i < mc; i++)
170 m_MeasurementMemory.Insert(
new Measurement());
175 System.GetCLIParam(
"autotest-output-dir", m_directory);
177 if (m_directory.Length() == 0)
179 m_directory =
"$logs:" +
GetName();
186 for (
int i = 0; i < m_CreatedLines.Count(); i++)
188 Shape s = m_CreatedLines[i];
192 delete m_CreatedLines;
197 void UpdateMeasurements()
199 int f = System.GetFPS();
201 m_MeasureFPS.AddValue(f);
202 m_MeasureMemory.AddValue(System.MemoryAllocationKB());
208 auto snapshot =
new MemoryStatsSnapshot();
209 int count = snapshot.GetStatsCount();
210 for (
int i = 0; i < count; i++)
212 int value = snapshot.GetStatValue(i);
213 m_MeasurementMemory[i].AddValue(value);
218 void CreateLines(array<vector> points,
int color)
220 for (
int i = 0; i < points.Count(); i++)
222 if (i + 1 < points.Count())
226 ppp[1] = points[i + 1];
228 m_CreatedLines.Insert(Shape.CreateLines(color,
ShapeFlags.VISIBLE, ppp, 2));
233 private void GeneratePathFromWaypoints()
235 m_Points =
new array<vector>();
257 private void GeneratePath()
259 if (m_MotionZoneInstance)
261 Print(
"Bouding Area of motion zone |" + m_MotionZoneInstance.m_Min +
"|" + m_MotionZoneInstance.m_Max);
263 Initialize(m_GeneratedPathScale, m_GeneratedPathSectorsCount, m_MotionZoneInstance.m_Min, m_MotionZoneInstance.m_Max);
271 Print(
"World Bouding box |" + mmin +
"|" + mmax);
273 Initialize(m_GeneratedPathScale, m_GeneratedPathSectorsCount, mmin, mmax);
277 override void EOnInit(
IEntity owner)
288 if (m_MotionZoneInstance != null)
290 m_MotionZoneInstance.Initialize();
300 GeneratePathFromWaypoints();
303 TransformCameraToWaypoint();
305 m_FPSWidget = TextWidget.Cast(
g_Game.
GetWorkspace().CreateWidgetInWorkspace(
WidgetType.TextWidgetTypeID, 16, 16, 512, 128,
WidgetFlags.VISIBLE,
new Color(0.0, 0.0, 0.0, 1.0), 1024));
306 m_FPSWidget.SetExactFontSize(64);
309 private void MakeSummeryFile(
string filename)
311 FileHandle descrFile = FileIO.OpenFile(filename,
FileMode.WRITE);
317 descrFile.WriteLine(
string.Format(
"MOTION AUTO TEST"));
318 descrFile.WriteLine(
string.Format(
"Resolution (px): %1x%2", sizeX, sizeY));
320 descrFile.WriteLine(
string.Format(
"Entering playmode time (s): %1",
g_Game.
GetLoadTime() / 1000));
322 descrFile.WriteLine(
string.Format(
"Load time (s): %1",
g_Game.
GetLoadTime() / 1000));
324 descrFile.WriteLine(
string.Format(
"Duration (s): %1",
m_timeFromStart));
326 descrFile.WriteLine(
string.Format(
"FPS average: %1", m_MeasureFPS.ComputeAverage()));
327 descrFile.WriteLine(
string.Format(
"FPS min: %1", m_MeasureFPS.m_Min));
328 descrFile.WriteLine(
string.Format(
"FPS max: %1", m_MeasureFPS.m_Max));
330 int count = MemoryStatsSnapshot.GetStatsCount();
331 for (
int i = 0; i < count; i++)
333 string name = MemoryStatsSnapshot.GetStatName(i);
334 descrFile.WriteLine(
string.Format(
"%1 average: %2", name, (
int)m_MeasurementMemory[i].
ComputeAverage()));
335 descrFile.WriteLine(
string.Format(
"%1 min: %2", name, (
int)m_MeasurementMemory[i].
m_Min));
336 descrFile.WriteLine(
string.Format(
"%1 max: %2", name, (
int)m_MeasurementMemory[i].
m_Max));
339 descrFile.WriteLine(
string.Format(
"Timestamp: %1", GetCurrentTimestamp()));
342 Print(
"Summary file successfully saved into " + filename);
346 private void MakeCSVFile(
string filename)
348 FileHandle descrFile = FileIO.OpenFile(filename,
FileMode.WRITE);
356 string CSVFormatString =
"Resolution (px),Load time (s),Duration (s),FPS average (s),FPS min (s),FPS max (s)";
357 string CSVResultString =
string.Format(
"%1x%2,%3,%4,%5,%6,%7", sizeX, sizeY,
g_Game.
GetLoadTime() * 0.001,
m_timeFromStart, m_MeasureFPS.ComputeAverage(), m_MeasureFPS.m_Min, m_MeasureFPS.m_Max);
359 int count = MemoryStatsSnapshot.GetStatsCount();
360 for (
int i = 0; i < count; i++)
362 CSVFormatString +=
string.Format(
",%1 average,%1 min,%1 max", MemoryStatsSnapshot.GetStatName(i));
363 CSVResultString +=
string.Format(
",%1,%2,%3", (
int)m_MeasurementMemory[i].
ComputeAverage(), (
int)m_MeasurementMemory[i].
m_Min, (
int)m_MeasurementMemory[i].
m_Max);
366 CSVFormatString +=
",Timestamp";
367 CSVResultString +=
string.Format(
",%1", GetCurrentTimestamp());
369 descrFile.WriteLine(CSVFormatString);
370 descrFile.WriteLine(CSVResultString);
373 Print(
"CSV file successfully saved into " + filename);
376 private string GetCurrentTimestamp()
378 int year, month, day;
379 System.GetYearMonthDay(year, month, day);
380 return string.Format(
"%1-%2-%3", year.ToString(4), month.ToString(2), day.ToString(2));
383 override void EOnFrame(
IEntity owner,
float timeSlice)
388 int fps = System.GetFPS();
389 m_FPSWidget.SetText(
"FPS " + fps);
390 if (fps < m_FPSLimit)
391 m_FPSWidget.SetColor(
new Color(1.0, 0.0, 0.0, 1.0));
393 m_FPSWidget.SetColor(
new Color(0.0, 1.0, 0.0, 1.0));
401 destination = output[0];
406 m_camera.SetOrigin(destination);
408 if (m_iCurrentPointsI > m_Points.Count())
410 FileIO.MakeDirectory(m_directory);
411 string summeryFilename =
string.Format(
"%1/%2", m_directory,
"summary.txt");
412 MakeSummeryFile(summeryFilename);
413 string csvFilename =
string.Format(
"%1/%2", m_directory,
"summary.csv");
414 MakeCSVFile(csvFilename);
415 Print(
"Autotest Finished; result in " + m_directory);
419 UpdateMeasurements();
426 float currentQuatCc[4];
427 bool onceOnly =
false;
434 vector pos = ComputePosition();
435 vector orientation = ComputeOrientation(quat);
438 output[1] = orientation;
440 if (onceOnly ==
false)
443 Math3D.QuatCopy(quat, prevQuatCc);
444 Math3D.QuatCopy(quat, currentQuatCc);
450 vector posNext = ComputePosition();
452 vector dir = posNext - pos;
453 float d = dir.NormalizeSize();
456 Math3D.DirectionAndUpMatrix(dir, vector.Up, mat);
459 Math3D.MatrixToQuat(mat, quat2);
461 if (CompareQuat(currentQuatCc, quat2) ==
false)
464 Math3D.QuatLerp(outQuat2, prevQuatCc, currentQuatCc, dCc);
467 Math3D.QuatCopy(outQuat2, prevQuatCc);
468 Math3D.QuatCopy(quat2, currentQuatCc);
472 Math3D.QuatLerp(outQuat, prevQuatCc, currentQuatCc, dCc);
474 output[1] = Math3D.QuatToAngles(outQuat);
476 dCc += 0.75 * timeSlice;
478 Math.Clamp(dCc, 0, 1);
482 private bool CompareQuat(
float q1[4],
float q2[4])
485 Math.AbsFloat(q1[0] - q2[0]) < 0.0001 &&
486 Math.AbsFloat(q1[1] - q2[1]) < 0.0001 &&
487 Math.AbsFloat(q1[2] - q2[2]) < 0.0001 &&
488 Math.AbsFloat(q1[3] - q2[3]) < 0.0001
497 private void UpdateState()
499 if (m_fTimeToTravel >= 0 && m_fTimeTraveled > m_fTimeToTravel)
504 if (m_iCurrentPointsI + 1 >= m_Points.Count())
509 if (m_fTimeToTravel < 0 || m_fTimeTraveled >= m_fTimeToTravel)
511 vector start = m_Points[m_iCurrentPointsI];
512 vector end = m_Points[m_iCurrentPointsI + 1];
514 float distance = (end - start).Length();
516 m_fTimeToTravel =
distance / m_MovementSpeed;
524 m_fTimeTraveled += timeDelta;
527 private vector ComputePosition()
529 if (m_iCurrentPointsI + 1 >= m_Points.Count())
532 return m_Points[m_Points.Count() - 1];
535 vector start = m_Points[m_iCurrentPointsI];
536 vector end = m_Points[m_iCurrentPointsI + 1];
538 vector dir = (end - start);
539 float t = m_fTimeTraveled / m_fTimeToTravel;
541 vector ret = start + t * dir;
542 ret[1] = GetYDistance(ret[0], ret[2]) + m_HeightAboveSurface;
547 private vector ComputeOrientation(out
float quatOrientationOut[4])
552 if (m_iCurrentPointsI + 1 >= m_Points.Count())
554 start = m_Points[m_Points.Count() - 2];
555 end = m_Points[m_Points.Count() - 1];
559 start = m_Points[m_iCurrentPointsI];
560 end = m_Points[m_iCurrentPointsI + 1];
563 vector dir = (end - start);
564 float t = m_fTimeTraveled / m_fTimeToTravel;
565 vector currentPosition = start + t * dir;
567 float d = dir.NormalizeSize();
569 Math3D.DirectionAndUpMatrix(dir, vector.Up, mat);
572 Math3D.MatrixToQuat(mat, quat);
573 quatOrientationOut = quat;
575 vector retDirAngles = Math3D.QuatToAngles(quat);
577 float dCurrent = (end - currentPosition).Length();
579 if (dCurrent < 0.1 * d && m_iCurrentPointsI < m_Points.Count() && m_iCurrentPointsI +2 < m_Points.Count())
581 start = m_Points[m_iCurrentPointsI + 1];
582 end = m_Points[m_iCurrentPointsI + 2];
587 Math3D.DirectionAndUpMatrix(dir, vector.Up, mat);
590 Math3D.MatrixToQuat(mat, quat2);
591 quatOrientationOut = quat2;
593 float ttt = (dCurrent / (0.1 * d));
596 Math3D.QuatLerp(outQuat, quat, quat2, 1 - ttt);
598 retDirAngles = Math3D.QuatToAngles(outQuat);
604 private string QuatToString(
float q[4])
606 return "(" + q[0] +
"," + q[1] +
"," + q[2] +
"," + q[3] +
")";
609 private void Initialize(
float scale,
int sectorCount, vector rectangleMin, vector rectangleMax)
611 m_Points =
new array<vector>();
613 float xx =
scale * rectangleMax[0] - rectangleMin[0];
614 float zz =
scale * rectangleMax[2] - rectangleMin[2];
616 float shiftx = 0.5 * ((rectangleMax[0] - rectangleMin[0]) - xx);
617 float shiftz = 0.5 * ((rectangleMax[2] - rectangleMin[2]) - zz);
622 zstep = zz / (sectorCount - 1);
625 for (
int i = 0; i < sectorCount; i++)
630 vector v =
Vector(shiftx, 0, shiftz) +
Vector(rectangleMin[0], 0.0, rectangleMin[2] + z);
631 v[1] = GetYDistance(v[0], v[2]) + m_HeightAboveSurface;
634 v =
Vector(shiftx, 0, shiftz) +
Vector(rectangleMin[0] + xx, 0.0, rectangleMin[2] + z);
635 v[1] = GetYDistance(v[0], v[2]) + m_HeightAboveSurface;
640 vector v =
Vector(shiftx, 0, shiftz) +
Vector(rectangleMin[0] + xx, 0.0, rectangleMin[2] + z);
641 v[1] = GetYDistance(v[0], v[2]) + m_HeightAboveSurface;
644 v =
Vector(shiftx, 0, shiftz) +
Vector(rectangleMin[0], 0.0, rectangleMin[2] + z);
645 v[1] = GetYDistance(v[0], v[2]) + m_HeightAboveSurface;
650 if (m_ShowGeneratePath ==
true)
652 CreateLines(m_Points,
ARGB(255, 255, 255, 255));
655 m_iCurrentPointsI = 0;
658 private float GetYDistance(
float x,
float z)
660 float wy =
GetWorld().GetSurfaceY(x, z);
664 oh =
GetWorld().GetOceanBaseHeight();
665 oh = Math.Ceil(Math.AbsFloat(oh));
677 private void TransformCameraToWaypoint()
679 if (m_waypoint && m_camera)
682 m_waypoint.GetTransform(mat);
683 m_camera.SetTransform(mat);
684 m_waypoint.EOnEnter();