diff --git a/Assets/Maps/invalid_polyhedron_TB_bug_valve.map b/Assets/Maps/invalid_polyhedron_TB_bug_valve.map new file mode 100644 index 0000000..5a90d95 --- /dev/null +++ b/Assets/Maps/invalid_polyhedron_TB_bug_valve.map @@ -0,0 +1,20 @@ +// Game: Goake +// Format: Standard +// entity 0 +{ +"classname" "worldspawn" +"_tb_textures" "textures/common;textures/dev" +// brush 0 +{ +( 832 -0 -0 ) ( 832 0 -1 ) ( 832 1 -0 ) dev/dev_128_gray [ 1 0 0 0 ] [ 0 1 0 0 ] 0 1 1 +( 877.8181762695312 0 0 ) ( 877.8181762695312 -1 0 ) ( 877.8181762695312 0 1 ) dev/dev_128_gray [ 1 0 0 0 ] [ 0 1 0 0 ] 0 1 1 +( 0 -272 0 ) ( -1 -272 0 ) ( 0 -272 1 ) dev/dev_128_gray [ 1 0 0 0 ] [ 0 1 0 0 ] 0 1 1 +( -0 -256 -0 ) ( 0 -256 -1 ) ( 1 -256 0 ) dev/dev_128_gray [ 1 0 0 0 ] [ 0 1 0 0 ] 0 1 1 +( -0 -0 48 ) ( 0 -1 48 ) ( 1 -0 48 ) dev/dev_128_gray [ 1 0 0 0 ] [ 0 1 0 0 ] 0 1 1 +( 0 0 106.90908813476562 ) ( -1 0 106.90908813476562 ) ( 0 1 106.90908813476562 ) dev/dev_128_gray [ 1 0 0 0 ] [ 0 1 0 0 ] 0 1 1 +( 779.4157104492188 0 -179.8651580810547 ) ( 779.190850943327 0 -180.8395493030548 ) ( 779.4157104492188 0.9743912220001221 -179.8651580810547 ) dev/dev_128_gray [ 1 0 0 0 ] [ 0 1 0 0 ] 0 1 1 +( 132.8000030517578 -0 -265.6000061035156 ) ( 131.9055758714676 0 -266.04721969366074 ) ( 132.8000030517578 0.8944271802902222 -265.6000061035156 ) dev/dev_128_gray [ 1 0 0 0 ] [ 0 1 0 0 ] 0 1 1 +( 702.8965454101562 0 -301.2413635253906 ) ( 702.8965454101562 -0.9191450476646423 -301.2413635253906 ) ( 703.2904646992683 0 -300.322218477726 ) dev/dev_128_gray [ 1 0 0 0 ] [ 0 1 0 0 ] 0 1 1 +( 68.79999542236328 0 -206.39999389648438 ) ( 68.79999542236328 -0.9486833214759827 -206.39999389648438 ) ( 69.74867874383926 0 -206.08376613259315 ) dev/dev_128_gray [ 1 0 0 0 ] [ 0 1 0 0 ] 0 1 1 +} +} \ No newline at end of file diff --git a/Content/GameSettings.json b/Content/GameSettings.json index 8e3a32e..982a29f 100644 --- a/Content/GameSettings.json +++ b/Content/GameSettings.json @@ -1,11 +1,11 @@ { "ID": "3c7bc3854d42f9b1b0fea9ba0d7fa8e9", "TypeName": "FlaxEditor.Content.Settings.GameSettings", - "EngineBuild": 6225, + "EngineBuild": 6226, "Data": { "ProductName": "Goake", "CompanyName": "GoaLitiuM", - "CopyrightNotice": "ddc", + "CopyrightNotice": "", "Icon": null, "FirstScene": "194e05f445ece24ec5448d886e1334df", "NoSplashScreen": true, @@ -30,6 +30,7 @@ "XboxOnePlatform": null, "XboxScarlettPlatform": null, "AndroidPlatform": null, - "SwitchPlatform": null + "SwitchPlatform": null, + "PS5Platform": null } } \ No newline at end of file diff --git a/Content/Materials/Material 0.flax b/Content/Materials/Material 0.flax index 490e7a4..4da219b 100644 Binary files a/Content/Materials/Material 0.flax and b/Content/Materials/Material 0.flax differ diff --git a/Content/Materials/SimpleMapMaterial.flax b/Content/Materials/SimpleMapMaterial.flax index 74a8aba..1b46bc7 100644 Binary files a/Content/Materials/SimpleMapMaterial.flax and b/Content/Materials/SimpleMapMaterial.flax differ diff --git a/Content/Materials/dev_128.flax b/Content/Materials/dev_128.flax index 23c9a0a..0b55583 100644 Binary files a/Content/Materials/dev_128.flax and b/Content/Materials/dev_128.flax differ diff --git a/Content/Materials/dev_128_lit.flax b/Content/Materials/dev_128_lit.flax index 01658ae..4314c31 100644 Binary files a/Content/Materials/dev_128_lit.flax and b/Content/Materials/dev_128_lit.flax differ diff --git a/Content/Materials/missing.flax b/Content/Materials/missing.flax index b748545..83a5b75 100644 Binary files a/Content/Materials/missing.flax and b/Content/Materials/missing.flax differ diff --git a/Content/Materials/sky.flax b/Content/Materials/sky.flax index f5a31f6..0281231 100644 Binary files a/Content/Materials/sky.flax and b/Content/Materials/sky.flax differ diff --git a/Content/Scenes/AerowalkScene.scene b/Content/Scenes/AerowalkScene.scene index c19ec29..3880747 100644 --- a/Content/Scenes/AerowalkScene.scene +++ b/Content/Scenes/AerowalkScene.scene @@ -1,7 +1,7 @@ { "ID": "194e05f445ece24ec5448d886e1334df", "TypeName": "FlaxEngine.SceneAsset", - "EngineBuild": 6225, + "EngineBuild": 6226, "Data": [ { "ID": "194e05f445ece24ec5448d886e1334df", @@ -23,55 +23,6 @@ "ParentID": "194e05f445ece24ec5448d886e1334df", "V": {} }, - { - "ID": "6c66fa4a4a5de8998eb84388d1648317", - "PrefabID": "2d0e518b47d735c98312dd87cc42d6d7", - "PrefabObjectID": "999a202c47de967d2bdfd09abcc6df4e", - "ParentID": "194e05f445ece24ec5448d886e1334df" - }, - { - "ID": "d5c84d67417ddf09908c76b6f0582b43", - "PrefabID": "2d0e518b47d735c98312dd87cc42d6d7", - "PrefabObjectID": "b29a58f545071ca393afaab21faa83ad", - "ParentID": "6c66fa4a4a5de8998eb84388d1648317", - "V": {} - }, - { - "ID": "d1a76c334a514c99f8f5b2bd81abae2c", - "PrefabID": "2d0e518b47d735c98312dd87cc42d6d7", - "PrefabObjectID": "a67383834fc3f6f1106e8099e5557e32", - "ParentID": "6c66fa4a4a5de8998eb84388d1648317" - }, - { - "ID": "357077e9405b2a7ba50198bbed8bd5f9", - "PrefabID": "2d0e518b47d735c98312dd87cc42d6d7", - "PrefabObjectID": "b8fc420f4efe96fa2b4042bd98fd3e74", - "ParentID": "d1a76c334a514c99f8f5b2bd81abae2c" - }, - { - "ID": "905d23324e7f98c9f8287e8e49a83981", - "PrefabID": "2d0e518b47d735c98312dd87cc42d6d7", - "PrefabObjectID": "226bdb004e72848777178a9d1f207cbf", - "ParentID": "357077e9405b2a7ba50198bbed8bd5f9" - }, - { - "ID": "89c02cd64b640185d9947ab451453c4c", - "PrefabID": "2d0e518b47d735c98312dd87cc42d6d7", - "PrefabObjectID": "8bd80bca49ac35da66aabaa2e473851d", - "ParentID": "6c66fa4a4a5de8998eb84388d1648317" - }, - { - "ID": "eebdb91647732ad3dfc7528c978cd19c", - "PrefabID": "2d0e518b47d735c98312dd87cc42d6d7", - "PrefabObjectID": "d9d61d314ad79d49ba08059cef50f802", - "ParentID": "6c66fa4a4a5de8998eb84388d1648317" - }, - { - "ID": "3e0f83fe407b2d9ed7c734a62fad0826", - "PrefabID": "2d0e518b47d735c98312dd87cc42d6d7", - "PrefabObjectID": "b377cc03418270d87e8a5b92cb5374ea", - "ParentID": "6c66fa4a4a5de8998eb84388d1648317" - }, { "ID": "ff6b6db54b5aa08e7286ef86246149ef", "TypeName": "FlaxEngine.UICanvas", @@ -117,13 +68,13 @@ "Transform": { "Translation": { "X": 0.0, - "Y": 248.0, + "Y": 254.0, "Z": 0.0 } }, "Control": "FlaxEngine.GUI.Label", "Data": { - "Text": "eFPS: 719\nuFPS: 650\nrFPS: 650\npFPS: 30\nCon: NaNms\nDirectX11\nGC memory: 15.66632MB", + "Text": "eFPS: 15\nuFPS: 15\nrFPS: 15\npFPS: 30\nCon: NaNms\nDirectX11\nGC memory: 12.47396MB", "TextColor": { "R": 1.0, "G": 1.0, @@ -170,9 +121,9 @@ }, "Offsets": { "Left": 0.0, - "Right": 30948.0, + "Right": 143.0, "Top": -562.0, - "Bottom": 576.0 + "Bottom": 112.0 }, "Scale": { "X": 1.0, @@ -211,7 +162,7 @@ "Transform": { "Translation": { "X": 45644.0, - "Y": -1.0, + "Y": 2.0, "Z": 0.0 } }, @@ -306,6 +257,55 @@ }, "PostFxMaterials": {} } + }, + { + "ID": "6c66fa4a4a5de8998eb84388d1648317", + "PrefabID": "2d0e518b47d735c98312dd87cc42d6d7", + "PrefabObjectID": "999a202c47de967d2bdfd09abcc6df4e", + "ParentID": "194e05f445ece24ec5448d886e1334df" + }, + { + "ID": "d5c84d67417ddf09908c76b6f0582b43", + "PrefabID": "2d0e518b47d735c98312dd87cc42d6d7", + "PrefabObjectID": "b29a58f545071ca393afaab21faa83ad", + "ParentID": "6c66fa4a4a5de8998eb84388d1648317", + "V": {} + }, + { + "ID": "d1a76c334a514c99f8f5b2bd81abae2c", + "PrefabID": "2d0e518b47d735c98312dd87cc42d6d7", + "PrefabObjectID": "a67383834fc3f6f1106e8099e5557e32", + "ParentID": "6c66fa4a4a5de8998eb84388d1648317" + }, + { + "ID": "357077e9405b2a7ba50198bbed8bd5f9", + "PrefabID": "2d0e518b47d735c98312dd87cc42d6d7", + "PrefabObjectID": "b8fc420f4efe96fa2b4042bd98fd3e74", + "ParentID": "d1a76c334a514c99f8f5b2bd81abae2c" + }, + { + "ID": "905d23324e7f98c9f8287e8e49a83981", + "PrefabID": "2d0e518b47d735c98312dd87cc42d6d7", + "PrefabObjectID": "226bdb004e72848777178a9d1f207cbf", + "ParentID": "357077e9405b2a7ba50198bbed8bd5f9" + }, + { + "ID": "89c02cd64b640185d9947ab451453c4c", + "PrefabID": "2d0e518b47d735c98312dd87cc42d6d7", + "PrefabObjectID": "8bd80bca49ac35da66aabaa2e473851d", + "ParentID": "6c66fa4a4a5de8998eb84388d1648317" + }, + { + "ID": "eebdb91647732ad3dfc7528c978cd19c", + "PrefabID": "2d0e518b47d735c98312dd87cc42d6d7", + "PrefabObjectID": "d9d61d314ad79d49ba08059cef50f802", + "ParentID": "6c66fa4a4a5de8998eb84388d1648317" + }, + { + "ID": "3e0f83fe407b2d9ed7c734a62fad0826", + "PrefabID": "2d0e518b47d735c98312dd87cc42d6d7", + "PrefabObjectID": "b377cc03418270d87e8a5b92cb5374ea", + "ParentID": "6c66fa4a4a5de8998eb84388d1648317" } ] } \ No newline at end of file diff --git a/Content/Settings/EngineSettings/TimeSettings.json b/Content/Settings/EngineSettings/TimeSettings.json index 943fcda..692d208 100644 --- a/Content/Settings/EngineSettings/TimeSettings.json +++ b/Content/Settings/EngineSettings/TimeSettings.json @@ -1,11 +1,11 @@ { "ID": "a55dc3c04da4ea3744b7f1994565beac", "TypeName": "FlaxEditor.Content.Settings.TimeSettings", - "EngineBuild": 6224, + "EngineBuild": 6226, "Data": { - "UpdateFPS": 240.0, + "UpdateFPS": 120.0, "PhysicsFPS": 120.0, - "DrawFPS": 240.0, + "DrawFPS": 120.0, "TimeScale": 1.0, "MaxUpdateDeltaTime": 0.1 } diff --git a/Content/Settings/EngineSettings/WindowsPlatformSettings.json b/Content/Settings/EngineSettings/WindowsPlatformSettings.json index 3ed1e99..17f983a 100644 --- a/Content/Settings/EngineSettings/WindowsPlatformSettings.json +++ b/Content/Settings/EngineSettings/WindowsPlatformSettings.json @@ -1,7 +1,7 @@ { "ID": "4a5eec97484253fed72934860ae62c40", "TypeName": "FlaxEditor.Content.Settings.WindowsPlatformSettings", - "EngineBuild": 6225, + "EngineBuild": 6226, "Data": { "WindowMode": 0, "ScreenWidth": 1280, diff --git a/Source/Game/Cabrito/FpsScript.cs b/Source/Game/Cabrito/FpsScript.cs index 5b8bdca..6698eae 100644 --- a/Source/Game/Cabrito/FpsScript.cs +++ b/Source/Game/Cabrito/FpsScript.cs @@ -93,6 +93,7 @@ namespace Cabrito sb.Append("\nGC memory: " + (GC.GetTotalMemory(false) / 1000000.0f).ToString() + "MB"); //sb.Append("\nUpdate profiler: " + updateProfTime.ToString() + "ms"); + #if false #if BUILD_DEVELOPMENT var nameOffset = Marshal.OffsetOf(typeof(ProfilerCPU.Event), "Name0"); foreach (var eventsCpu in FlaxEngine.ProfilingTools.EventsCPU) @@ -119,6 +120,7 @@ namespace Cabrito } } +#endif #endif ((Label) control.Control).Text = sb.ToString(); diff --git a/Source/Game/PlayerInput.cs b/Source/Game/PlayerInput.cs new file mode 100644 index 0000000..0a85fc3 --- /dev/null +++ b/Source/Game/PlayerInput.cs @@ -0,0 +1,189 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Net; +using System.Runtime.InteropServices; +using FlaxEngine; + +namespace Game +{ + [StructLayout(LayoutKind.Sequential)] + public struct PlayerInputState + { + public float viewDeltaX, viewDeltaY; + public float moveForward; + public float moveRight; + public bool attacking; + public bool jumping; + } + + [StructLayout(LayoutKind.Sequential)] + public struct PlayerActorState + { + public Vector3 position; + public Vector3 velocity; + public Quaternion orientation; + public float viewYaw, viewPitch, viewRoll; + } + + [StructLayout(LayoutKind.Sequential)] + public struct PlayerState + { + public PlayerInputState input; + public PlayerActorState actor; + } + + public class PlayerInput + { + public PlayerState lastState; + public PlayerState currentState; + public int frame; + + private const byte DemoVer = 1; + + private List buffer = new List(); + + private bool demoPlayback = false; + private bool demoRecording = true; + + private string demoPath = @"C:\dev\GoakeFlax\testdemo.gdem"; + + public void OpenDemo() + { + if (!File.Exists(demoPath)) + return; + + T RawDeserialize(byte[] rawData, int position) + { + int rawsize = Marshal.SizeOf(typeof(T)); + if (rawsize > rawData.Length - position) + throw new ArgumentException("Not enough data to fill struct. Array length from position: "+(rawData.Length-position) + ", Struct length: "+rawsize); + IntPtr buffer = Marshal.AllocHGlobal(rawsize); + Marshal.Copy(rawData, position, buffer, rawsize); + T retobj = (T)Marshal.PtrToStructure(buffer, typeof(T)); + Marshal.FreeHGlobal(buffer); + return retobj; + } + + var stream = File.OpenRead(demoPath); + var ver = (int)stream.ReadByte(); + if (ver != DemoVer) + { + Console.WriteLine("demover doesn't match: " + ver + " != " + DemoVer); + stream.Close(); + return; + } + + while (true) + { + var expectedSize = Marshal.SizeOf(typeof(PlayerInputState)); + byte[] b = new byte[expectedSize]; + var readBytes = stream.Read(b, 0, b.Length); + if (readBytes < expectedSize) + break; + + buffer.Add(RawDeserialize(b, 0)); + } + + Console.WriteLine("demo numstates: " + buffer.Count); + + demoPlayback = true; + demoRecording = false; + } + + public void OnUpdate() + { + lastState = currentState; + + // Record camera angles here? + if (!demoPlayback) + { + currentState.input.viewDeltaX = InputManager.GetAxisRaw("Mouse X"); + currentState.input.viewDeltaY = InputManager.GetAxisRaw("Mouse Y"); + } + } + + public void OnFixedUpdate() + { + // Record intent here + + if (!demoPlayback) + { + currentState.input.moveForward = InputManager.GetAxis("Vertical"); + currentState.input.moveRight = InputManager.GetAxis("Horizontal"); + currentState.input.attacking = InputManager.GetAction("Attack"); + currentState.input.jumping = InputManager.GetAction("Jump"); + } + } + + public void OnEndFrame() + { + if (demoRecording) + buffer.Add(currentState.input); + + frame++; + + if (demoPlayback) + { + if (frame < buffer.Count) + { + //var actorState = currentState.actor; + currentState.input = buffer[frame]; + //currentState.actor = actorState; + } + else + { + Console.WriteLine("demo ended"); + demoPlayback = false; + } + } + } + + public void RecordCurrentActorState(PlayerActorState actorState) + { + currentState.actor = actorState; + } + + public PlayerInputState GetCurrentInputState() + { + return currentState.input; + } + + public PlayerActorState GetCurrentActorState() + { + return currentState.actor; + } + + public void Flush() + { + if (!demoRecording) + return; + + var stream = File.Open(demoPath, FileMode.Create, FileAccess.Write); + //stream.Position = 0; + //stream.SetLength(0); + stream.WriteByte(DemoVer); + + byte[] RawSerialize(object anything) + { + int rawSize = Marshal.SizeOf(anything); + IntPtr buffer = Marshal.AllocHGlobal(rawSize); + Marshal.StructureToPtr(anything, buffer, false); + byte[] rawDatas = new byte[rawSize]; + Marshal.Copy(buffer, rawDatas, 0, rawSize); + Marshal.FreeHGlobal(buffer); + return rawDatas; + } + + foreach (var state in buffer) + { + var bytes = RawSerialize(state); + stream.Write(bytes, 0, bytes.Length * sizeof(byte)); + } + + stream.Close(); + + Debug.Write(LogType.Info, "demo, wrote states: " + buffer.Count); + } + } +} \ No newline at end of file diff --git a/Source/Game/PlayerMovement.cs b/Source/Game/PlayerMovement.cs index c6d06eb..8d767de 100644 --- a/Source/Game/PlayerMovement.cs +++ b/Source/Game/PlayerMovement.cs @@ -5,6 +5,7 @@ using System.Diagnostics; using System.Threading.Tasks; using FlaxEngine.Assertions; using Console = Cabrito.Console; +using Debug = FlaxEngine.Debug; using Object = FlaxEngine.Object; namespace Game @@ -45,11 +46,14 @@ namespace Game private Actor rootActor; private RigidBody rigidBody; + private PlayerInput input; public override void OnAwake() { base.OnAwake(); + input = new PlayerInput(); + onExit.Triggered += () => { if (Console.IsSafeToQuit) @@ -62,6 +66,16 @@ namespace Game //rigidBody.CollisionEnter += OnCollisionEnter; //rigidBody.TriggerEnter += OnTriggerEnter; //rigidBody.TriggerExit += OnTriggerExit; + + input.OpenDemo(); + } + + public override void OnDisable() + { + base.OnDisable(); + + if (input != null) + input.Flush(); } private List touchingActors = new List(); @@ -103,6 +117,68 @@ namespace Game viewRoll = initialEulerAngles.Z; } + public override void OnUpdate() + { + input.OnUpdate(); + + if (input.frame > 0) + { + PlayerActorState actorState = input.GetCurrentActorState(); + Actor.Position = actorState.position; + currentVelocity = actorState.velocity; + viewYaw = actorState.viewYaw; + viewPitch = actorState.viewPitch; + viewRoll = actorState.viewRoll; + } + + PlayerInputState inputState = input.GetCurrentInputState(); + + // Update camera view + float xAxis = inputState.viewDeltaX; + float yAxis = inputState.viewDeltaY; + if (xAxis != 0.0f || yAxis != 0.0f) + { + var camera = rootActor.GetChild(); + + viewPitch = Mathf.Clamp(viewPitch + yAxis, -90.0f, 90.0f); + viewYaw += xAxis; + + + // root orientation must be set first + rootActor.Orientation = Quaternion.Euler(0, viewYaw, 0); + camera.Orientation = Quaternion.Euler(viewPitch, viewYaw, viewRoll); + } + + input.RecordCurrentActorState(new PlayerActorState() + { + position = Actor.Position, + velocity = currentVelocity, + viewYaw = viewYaw, + viewPitch = viewPitch, + viewRoll = viewRoll + }); + } + + public override void OnFixedUpdate() + { + input.OnFixedUpdate(); + PlayerInputState inputState = input.GetCurrentInputState(); + + SimulatePlayerMovement(inputState); + + input.RecordCurrentActorState(new PlayerActorState() + { + position = Actor.Position, + velocity = currentVelocity, + viewYaw = viewYaw, + viewPitch = viewPitch, + viewRoll = viewRoll + }); + input.OnEndFrame(); + } + + + private bool SweepPlayerCollider(Vector3 start, Vector3 end, out RayCastHit[] hits) { Vector3 delta = end - start; @@ -560,25 +636,6 @@ namespace Game return slideMoveHit; } - public override void OnUpdate() - { - float xAxis = InputManager.GetAxisRaw("Mouse X"); - float yAxis = InputManager.GetAxisRaw("Mouse Y"); - if (xAxis != 0.0f || yAxis != 0.0f) - { - var camera = rootActor.GetChild(); - - viewPitch += yAxis; - viewYaw += xAxis; - - viewPitch = Mathf.Clamp(viewPitch, -90.0f, 90.0f); - - // root orientation must be set first - rootActor.Orientation = Quaternion.Euler(0, viewYaw, 0); - camera.Orientation = Quaternion.Euler(viewPitch, viewYaw, viewRoll); - } - } - [ReadOnly] public bool onGround = false; /* @@ -643,12 +700,12 @@ namespace Game private Vector3 currentVelocity; - public override void OnFixedUpdate() + public void SimulatePlayerMovement(PlayerInputState inputState) { Transform rootTrans = rootActor.Transform; Vector3 inputDirection = - new Vector3(InputManager.GetAxis("Horizontal"), 0.0f, InputManager.GetAxis("Vertical")); + new Vector3(inputState.moveRight, 0.0f, inputState.moveForward); Vector3 moveDirection = rootTrans.TransformDirection(inputDirection); Vector3 position = rigidBody.Position; @@ -698,7 +755,7 @@ namespace Game // TODO: snap to ground here - bool jumpAction = InputManager.GetAction("Jump"); + bool jumpAction = inputState.jumping; if (jumped && !jumpAction) jumped = false; // jump released