| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394 | //  Struct for individual benchmark locations class BenchmarkLocation{	bool m_IsDummyTeleport;	bool m_IsDummyWait;	float m_CamSpeedMultiplier = 1;	string m_Name;	vector m_StartPos;	vector m_StartLookAtPos;		void BenchmarkLocation(string name)	{		m_Name = name;	}		void SetPosition(vector start)	{		m_StartPos = start + "0 2.5 0"; // raise to head level	}		// note that vector[1] (height) is ignored during interpolation and setting it has no effect	void SetLookAtPosition(vector start)	{		m_StartLookAtPos = start;	}		void SetCameraSpeedMultiplier(float multiplier)	{		m_CamSpeedMultiplier = multiplier;	}		void SetDummyTeleport()	{		m_IsDummyTeleport = true;	}		void SetDummyWait()	{		m_IsDummyWait = true;	}}// Global settings of benchmark class BenchmarkConfig{	bool m_LogToRPT;	bool m_DoDevPrints;	int m_PreloadLength = 5;	float m_TimeMultiplier = 1;	string m_CSVName;		ref array<ref BenchmarkLocation> m_Locations = new array<ref BenchmarkLocation>();		void AddLocation(notnull BenchmarkLocation loc)	{		m_Locations.Insert(loc);	}		void AddQuickLocation(string name, vector pos, vector lookAtPos)	{		BenchmarkLocation loc = new BenchmarkLocation(name);		loc.SetPosition(pos);		loc.SetLookAtPosition(lookAtPos);				m_Locations.Insert(loc);	}		void AddTeleport()	{		BenchmarkLocation loc = new BenchmarkLocation("Teleport");		loc.SetDummyTeleport();		m_Locations.Insert(loc);	}		void AddWait()	{		BenchmarkLocation loc = new BenchmarkLocation("Wait");		loc.SetDummyWait();		m_Locations.Insert(loc);	}		// false = csv, true = rpt	void LogToRPT(bool logRPT)	{		m_LogToRPT = logRPT;	}		void DoDevPrints(bool doPrints)	{		m_DoDevPrints = doPrints;	}			// Preload time of individual locations after teleport	void SetPreloadLengthTime(int seconds)	{		m_PreloadLength = seconds;	}		// Time multiplier for quickly testing flypath 	void SetTestTimeMultiplier(float multiplier)	{		m_TimeMultiplier = multiplier;	}		void SetCSVName(string name)	{		m_CSVName = name;	}}class MissionBenchmark : MissionGameplay{		protected const int 		INITIAL_PRELOAD = 5; // seconds, extra preload seconds to compensate for the game launching	protected const float 		STEP_INTERVAL = 1; 	// seconds, how much time passes between steps (fps measurements)		protected bool 				m_InitialLoadDone;	// extra time is added to first preload to make up for intial loading of the game 	protected bool 				m_IsPreloading;		// preload time between location measurements	protected bool 				m_LocationDone;		// finished measuring current location	protected int 				m_LocIndex;	protected int 				m_MeasuringStep;	protected float			 	m_MeasureStepTimer = 1;	protected float 			m_SumFPS;	protected float 			m_TimeCounter;	protected float				m_MeasureLength;	protected float				m_StepDistance;		protected FileHandle 		m_CSVLog;	protected BenchmarkLocation m_CurrentLocation;	protected BenchmarkLocation m_NextLocation;		protected ref BenchmarkConfig m_Config;		protected static MissionBenchmark m_Instance;			void MissionBenchmark()	{		m_Instance = this;	}		void ~MissionBenchmark()	{		m_Instance = null;	}		static MissionBenchmark GetInstance()	{		return m_Instance;	}		BenchmarkConfig GetConfig()	{		if (!m_Config)			m_Config = new BenchmarkConfig();				return m_Config;	}		void Start()	{				if (!m_Config || m_Config.m_Locations.Count() <= 1)		{			OnBenchmarkEnd("Not enough locations defined");			return;		}				if (!m_Config.m_LogToRPT)			CreateCSVLog();						m_IsPreloading = true;				OnLocationSwitch();	}			override void OnUpdate(float timeslice)	{		super.OnUpdate(timeslice);		m_TimeCounter += timeslice * m_Config.m_TimeMultiplier;				if (!m_CurrentLocation)			return;		else if (m_IsPreloading)			PreloadUpdate();		else 			MeasureUpdate(timeslice);	}		// Update logic which runs when location is being preloaded	protected void PreloadUpdate()	{		if (!m_InitialLoadDone)		{			if (m_TimeCounter >= (m_Config.m_PreloadLength + INITIAL_PRELOAD)) // end preload				m_InitialLoadDone = true;		}		else if (m_TimeCounter >= m_Config.m_PreloadLength * (1 / m_Config.m_TimeMultiplier)) // end preload		{			m_TimeCounter = 0;			m_IsPreloading = false;		}	}		// Update logic which runs when measurement is in progress	protected void MeasureUpdate(float timeSlice)	{				m_MeasureStepTimer += timeSlice;		if (m_MeasureStepTimer >= STEP_INTERVAL)		{			float avgFps = GetGame().GetFps();						if (m_Config.m_DoDevPrints)				Print( string.Format("Measure step: %1 | FPS: %2" , m_MeasuringStep + 1, 1/avgFps) );			/*if (m_MeasuringStep >= m_MeasureLength)	// end of steps			{	}			else*/	// next step						m_MeasureStepTimer = 0;								m_SumFPS += ( 1/avgFps );			m_MeasuringStep++;			GetGame().GetPlayer().SetPosition(FreeDebugCamera.GetInstance().GetPosition() - "0 2.5 0");		}				LerpCamera();		}	 	protected void AdvanceLocation()	{		if (m_NextLocation.m_IsDummyWait && m_MeasuringStep < 5)			return;				string locationName = m_NextLocation.m_Name;		FPSLog(locationName, m_SumFPS/m_MeasuringStep);				if (m_Config.m_DoDevPrints)					Print( string.Format("%1 | Measurements: %2 | Average FPS: %3 | Elapsed time: %4 seconds" ,locationName, m_MeasuringStep, m_SumFPS/m_MeasuringStep ,m_TimeCounter) );							m_LocIndex++;		OnLocationSwitch();	}		// logic for interpolating camera between location points	protected void LerpCamera()	{		float lerpX, lerpZ, lerpY;				vector target = m_NextLocation.m_StartPos;		float camSpeedAdjust = m_CurrentLocation.m_CamSpeedMultiplier * 5 * m_TimeCounter * 1/m_StepDistance;				lerpX = Math.Lerp(m_CurrentLocation.m_StartPos[0], target[0], camSpeedAdjust);		lerpZ = Math.Lerp(m_CurrentLocation.m_StartPos[1], target[1], camSpeedAdjust);		lerpY = Math.Lerp(m_CurrentLocation.m_StartPos[2], target[2], camSpeedAdjust);				if (camSpeedAdjust >= 1 || m_NextLocation.m_IsDummyWait)		{			AdvanceLocation();			return;		}						FreeDebugCamera.GetInstance().SetPosition( Vector(lerpX, lerpZ, lerpY) );							target = m_NextLocation.m_StartLookAtPos;				lerpX = Math.Lerp(m_CurrentLocation.m_StartLookAtPos[0], target[0], camSpeedAdjust);		//lerpZ = Math.Lerp(m_CurrentLocation.m_StartLookAtPos[1], target[1], camSpeedAdjust); // ignored as it causes issues with lerping between look at points		lerpY = Math.Lerp(m_CurrentLocation.m_StartLookAtPos[2], target[2], camSpeedAdjust);		FreeDebugCamera.GetInstance().LookAt( Vector(lerpX, lerpZ, lerpY) );			}		protected void OnLocationSwitch()	{				if (m_LocIndex >= (m_Config.m_Locations.Count() - 1))		{			OnBenchmarkEnd("Test finished!");			return;		}				m_MeasureStepTimer = 1; // tick first measurement straight after preload		m_SumFPS = 0;		m_MeasuringStep = 0;		m_TimeCounter = 0;			m_CurrentLocation = m_Config.m_Locations[m_LocIndex];		m_NextLocation = m_Config.m_Locations[m_LocIndex+1];		m_StepDistance = vector.Distance(m_CurrentLocation.m_StartPos, m_NextLocation.m_StartPos);				if (!GetGame().GetPlayer())		{			CreatePlayer();			TeleportToPos(m_CurrentLocation);		}					if (m_NextLocation.m_IsDummyTeleport)	// flycam teleport		{			m_LocIndex += 2;			if (m_LocIndex >= (m_Config.m_Locations.Count() - 1))			{				OnBenchmarkEnd("Test finished!");				return;			}			else 			{				m_CurrentLocation = m_Config.m_Locations[m_LocIndex];				m_NextLocation = m_Config.m_Locations[m_LocIndex+1];				m_StepDistance = vector.Distance(m_CurrentLocation.m_StartPos, m_NextLocation.m_StartPos);				TeleportToPos(m_CurrentLocation);			}		}					if (m_NextLocation.m_IsDummyWait)		{			m_NextLocation.m_Name = m_CurrentLocation.m_Name + " Wait";			m_NextLocation.m_StartPos = m_CurrentLocation.m_StartPos;			m_NextLocation.m_StartLookAtPos = m_CurrentLocation.m_StartLookAtPos;		}				if (m_Config.m_DoDevPrints)		{			Print(string.Format("================"));			Print(string.Format("%1 test begin" , m_CurrentLocation.m_Name + " -> " + m_NextLocation.m_Name));		}	}		protected void TeleportToPos(BenchmarkLocation loc)	{		FreeDebugCamera.GetInstance().SetPosition(loc.m_StartPos);		vector lookAtPos = loc.m_StartLookAtPos;		lookAtPos[1] = loc.m_StartPos[1];		FreeDebugCamera.GetInstance().LookAt(lookAtPos);				GetGame().GetPlayer().SetPosition(m_CurrentLocation.m_StartPos - "0 2.5 0");		m_IsPreloading = true;	}		protected void OnBenchmarkEnd(string reason)	{		if (!m_Config.m_LogToRPT)		{			CloseFile( m_CSVLog );						if (m_Config.m_DoDevPrints)				Print( "Benchmark CSV file closed" );		}				if (m_Config.m_DoDevPrints)			Print(string.Format("%1", reason));				FreeDebugCamera.GetInstance().SetActive(false);		GetGame().RequestExit( IDC_MAIN_QUIT );	// does not work on consoles ?	}		protected void CreatePlayer()	{		Entity playerEnt = GetGame().CreatePlayer(NULL, "SurvivorF_Eva", m_CurrentLocation.m_StartPos - "0 2.5 0", 0, "NONE");		PlayerBase player = PlayerBase.Cast(playerEnt);		GetGame().SelectPlayer(NULL, player);				player.GetStatWater().Set(3000);		player.GetStatEnergy().Set(3000);		player.SetAllowDamage(false);		player.SetCanBeDestroyed(false);				FreeDebugCamera.GetInstance().SetFOV(0.72);		FreeDebugCamera.GetInstance().SetActive(true);	}		protected void CreateCSVLog()	{		string fileName = "benchmark";		if (m_Config.m_CSVName != string.Empty)			fileName = m_Config.m_CSVName;				m_CSVLog = OpenFile("$profile:" + fileName + ".csv", FileMode.WRITE);		if ( m_CSVLog == 0 )				OnBenchmarkEnd("Failed to create benchmark .csv");				if (m_Config.m_DoDevPrints)			Print("Benchmark .csv created");				FPrintln(m_CSVLog, "Location,FPS,Time");	}		protected void FPSLog( string position, float frames )	{		int year, month, day, hour, minute, second;		GetYearMonthDay(year, month, day);		GetHourMinuteSecondUTC(hour, minute, second);		string timestamp = string.Format( "%1-%2-%3-%4-%5-%6", year, month, day, hour, minute, second );		if (m_Config.m_LogToRPT)			PrintToRPT("Average FPS: " + frames);		else 			FPrintln( m_CSVLog, position + "," + frames + "," + timestamp );	}}
 |