From 9e3b09f1f9dec6e3b701e3432210a01f959f5ff8 Mon Sep 17 00:00:00 2001 From: NGnius Date: Thu, 14 Nov 2019 12:20:30 -0500 Subject: [PATCH] Add block rotation command and fix grid --- extracommands/MoveBlocksCommandEngine.cs | 16 +- extracommands/RotateBlocksCommandEngine.cs | 171 +++++++++++++++++++++ 2 files changed, 184 insertions(+), 3 deletions(-) create mode 100644 extracommands/RotateBlocksCommandEngine.cs diff --git a/extracommands/MoveBlocksCommandEngine.cs b/extracommands/MoveBlocksCommandEngine.cs index 033242c..242bae7 100644 --- a/extracommands/MoveBlocksCommandEngine.cs +++ b/extracommands/MoveBlocksCommandEngine.cs @@ -37,11 +37,12 @@ namespace ExtraCommands.Building uREPL.Log.Error("Blocks can only be moved in Build Mode"); return; } - uint posCount, transCount, phyCount; + uint posCount, gridCount, transCount, phyCount; PositionEntityStruct[] posStructs = this.entitiesDB.QueryEntities(CommonExclusiveGroups.OWNED_BLOCKS_GROUP, out posCount); + GridRotationStruct[] gridStructs = this.entitiesDB.QueryEntities(CommonExclusiveGroups.OWNED_BLOCKS_GROUP, out gridCount); LocalTransformEntityStruct[] transStructs = this.entitiesDB.QueryEntities(CommonExclusiveGroups.OWNED_BLOCKS_GROUP, out transCount); UECSPhysicsEntityStruct[] phyStructs = this.entitiesDB.QueryEntities(CommonExclusiveGroups.OWNED_BLOCKS_GROUP, out phyCount); - if (posCount != transCount || transCount != phyCount) + if (posCount != gridCount || gridCount != transCount || transCount != phyCount) { uREPL.Log.Error("Block lists returned are not the same length!"); // they're arrays, not lists return; @@ -52,6 +53,10 @@ namespace ExtraCommands.Building posStruct.position.x += x; posStruct.position.y += y; posStruct.position.z += z; + ref GridRotationStruct gridStruct = ref gridStructs[i]; // main (persistent) position + gridStruct.position.x += x; + gridStruct.position.y += y; + gridStruct.position.z += z; ref LocalTransformEntityStruct transStruct = ref transStructs[i]; // rendered position transStruct.position.x += x; transStruct.position.y += y; @@ -74,8 +79,9 @@ namespace ExtraCommands.Building uREPL.Log.Error("Blocks can only be moved in Build Mode"); return; } - uint posCount, transCount, phyCount; + uint posCount, gridCount, transCount, phyCount; PositionEntityStruct[] posStructs = this.entitiesDB.QueryEntities(CommonExclusiveGroups.OWNED_BLOCKS_GROUP, out posCount); + GridRotationStruct[] gridStructs = this.entitiesDB.QueryEntities(CommonExclusiveGroups.OWNED_BLOCKS_GROUP, out gridCount); LocalTransformEntityStruct[] transStructs = this.entitiesDB.QueryEntities(CommonExclusiveGroups.OWNED_BLOCKS_GROUP, out transCount); UECSPhysicsEntityStruct[] phyStructs = this.entitiesDB.QueryEntities(CommonExclusiveGroups.OWNED_BLOCKS_GROUP, out phyCount); if (posCount == 0 || transCount == 0 || phyCount == 0) @@ -87,6 +93,10 @@ namespace ExtraCommands.Building posStruct.position.x += x; posStruct.position.y += y; posStruct.position.z += z; + ref GridRotationStruct gridStruct = ref gridStructs[gridCount-1]; // main (persistent) position + gridStruct.position.x += x; + gridStruct.position.y += y; + gridStruct.position.z += z; ref LocalTransformEntityStruct transStruct = ref transStructs[transCount-1]; // rendered position transStruct.position.x += x; transStruct.position.y += y; diff --git a/extracommands/RotateBlocksCommandEngine.cs b/extracommands/RotateBlocksCommandEngine.cs new file mode 100644 index 0000000..21d2f9d --- /dev/null +++ b/extracommands/RotateBlocksCommandEngine.cs @@ -0,0 +1,171 @@ +using System; +using System.Collections.Generic; +using RobocraftX.Multiplayer; +using RobocraftX.Common; +using Svelto.ECS; +using Svelto.ECS.EntityStructs; +using Unity.Entities; +using Svelto.Context; +using Svelto.Tasks; +using RobocraftX; +using RobocraftX.SimulationModeState; +using RobocraftX.UECS; +using Unity.Transforms; +using Unity.Mathematics; +using UnityEngine; + +namespace ExtraCommands.Building +{ + [CustomCommand("RotateBlocks", "Rotate all blocks (including ground) from their original position")] + [CustomCommand("RotateLastBlock", "Rotate last block from original position")] + class RotateBlocksCommandEngine : CustomCommandEngine + { + public RotateBlocksCommandEngine(UnityContext ctxHolder, EnginesRoot enginesRoot, World physW, Action reloadGame, MultiplayerInitParameters mpParams) : base(ctxHolder, enginesRoot, physW, reloadGame, mpParams) + { + } + + public override void Ready() + { + CustomCommandUtility.Register("RotateBlocks", RotateBlocksCommand, "Rotate all blocks (including ground) from their original position"); + CustomCommandUtility.Register("RotateLastBlock", RotateLastBlockCommand, "Rotate last block from original position"); + } + + // Move every block by vector (x,y,z) + private void RotateBlocksCommand(float x, float y, float z) + { + Vector3 eulerAngles = new Vector3(x, y, z); + ref SimulationModeStateEntityStruct simMode = ref this.entitiesDB.QueryUniqueEntity(SimulationModeStateExclusiveGroups.GAME_STATE_GROUP); + if (simMode.simulationMode != SimulationMode.Build) + { + uREPL.Log.Error("Blocks can only be moved in Build Mode"); + return; + } + uint rotCount, gridCount, transCount, phyCount; + RotationEntityStruct[] rotStructs = this.entitiesDB.QueryEntities(CommonExclusiveGroups.OWNED_BLOCKS_GROUP, out rotCount); + GridRotationStruct[] gridStructs = this.entitiesDB.QueryEntities(CommonExclusiveGroups.OWNED_BLOCKS_GROUP, out gridCount); + LocalTransformEntityStruct[] transStructs = this.entitiesDB.QueryEntities(CommonExclusiveGroups.OWNED_BLOCKS_GROUP, out transCount); + UECSPhysicsEntityStruct[] phyStructs = this.entitiesDB.QueryEntities(CommonExclusiveGroups.OWNED_BLOCKS_GROUP, out phyCount); + if (rotCount != transCount || transCount != phyCount) + { + uREPL.Log.Error("Block lists returned are not the same length!"); // they're arrays, not lists + return; + } + for (uint i = 0; i < rotCount; i++) + { + ref RotationEntityStruct rotStruct = ref rotStructs[i]; // main (persistent) rotation + Quaternion newRotation = (Quaternion)rotStruct.rotation; + newRotation.eulerAngles += eulerAngles; + rotStruct.rotation = (quaternion)newRotation; + ref GridRotationStruct gridStruct = ref gridStructs[i]; // placement grid rotation + Quaternion newGridRotation = (Quaternion)gridStruct.rotation; + newGridRotation.eulerAngles += eulerAngles; + gridStruct.rotation = (quaternion)newGridRotation; + ref LocalTransformEntityStruct transStruct = ref transStructs[i]; // rendered position + Quaternion newTransRotation = (Quaternion)rotStruct.rotation; + newTransRotation.eulerAngles += eulerAngles; + transStruct.rotation = newTransRotation; + ref UECSPhysicsEntityStruct phyStruct = ref phyStructs[i]; // collision position + this.physWorld.EntityManager.SetComponentData(phyStruct.uecsEntity, new Rotation + { + Value = rotStruct.rotation + }); + } + uREPL.Log.Output($"Moved {rotCount} blocks"); + } + + // Move block with highest index by vector (x,y,z) + private void RotateLastBlockCommand(float x, float y, float z) + { + Vector3 eulerAngles = new Vector3(x, y, z); + ref SimulationModeStateEntityStruct simMode = ref this.entitiesDB.QueryUniqueEntity(SimulationModeStateExclusiveGroups.GAME_STATE_GROUP); + if (simMode.simulationMode != SimulationMode.Build) + { + uREPL.Log.Error("Blocks can only be moved in Build Mode"); + return; + } + uint rotCount, gridCount, transCount, phyCount; + RotationEntityStruct[] rotStructs = this.entitiesDB.QueryEntities(CommonExclusiveGroups.OWNED_BLOCKS_GROUP, out rotCount); + GridRotationStruct[] gridStructs = this.entitiesDB.QueryEntities(CommonExclusiveGroups.OWNED_BLOCKS_GROUP, out gridCount); + LocalTransformEntityStruct[] transStructs = this.entitiesDB.QueryEntities(CommonExclusiveGroups.OWNED_BLOCKS_GROUP, out transCount); + UECSPhysicsEntityStruct[] phyStructs = this.entitiesDB.QueryEntities(CommonExclusiveGroups.OWNED_BLOCKS_GROUP, out phyCount); + if (rotCount == 0 || gridCount == 0 || transCount == 0 || phyCount == 0) + { + uREPL.Log.Error("No block found"); + return; + } + ref RotationEntityStruct rotStruct = ref rotStructs[rotCount-1]; // main (persistent) position + Quaternion newRotation = (Quaternion)rotStruct.rotation; + newRotation.eulerAngles += eulerAngles; + rotStruct.rotation = (quaternion)newRotation; + ref GridRotationStruct gridStruct = ref gridStructs[gridCount-1]; // placement grid rotation + Quaternion newGridRotation = (Quaternion)gridStruct.rotation; + newGridRotation.eulerAngles += eulerAngles; + gridStruct.rotation = (quaternion)newGridRotation; + ref LocalTransformEntityStruct transStruct = ref transStructs[transCount-1]; // rendered position + Quaternion newTransRotation = (Quaternion)rotStruct.rotation; + newTransRotation.eulerAngles += eulerAngles; + transStruct.rotation = newTransRotation; + ref UECSPhysicsEntityStruct phyStruct = ref phyStructs[phyCount-1]; // collision position + this.physWorld.EntityManager.SetComponentData(phyStruct.uecsEntity, new Rotation + { + Value = rotStruct.rotation + }); + uREPL.Log.Output($"Rotated block to ({rotStruct.rotation.value.x},{rotStruct.rotation.value.y},{rotStruct.rotation.value.z})"); + } + + // unused; for future reference + private void ToggleMode() + { + ref SimulationModeStateEntityStruct ptr = ref this.entitiesDB.QueryUniqueEntity(SimulationModeStateExclusiveGroups.GAME_STATE_GROUP); + ref SimulationFrameEntityStruct ptr2 = ref this.entitiesDB.QueryUniqueEntity(SimulationFrame.SimulationFrameGroup); + switch (ptr.simulationMode) + { + case SimulationMode.Build: + ptr.simulationMode = SimulationMode.SwitchToSim; + ptr.simulationModeChangeFrame = ptr2.simFrame; + return; + case SimulationMode.SwitchToSim: + case SimulationMode.SwitchToBuild: + return; + case SimulationMode.Simulation: + ptr.simulationMode = SimulationMode.SwitchToBuild; + ptr.simulationModeChangeFrame = ptr2.simFrame; + ptr.rigidBodiesCreated = false; + return; + default: + throw new ArgumentOutOfRangeException(); + } + } + + // unused; for future reference + private IEnumerator TriggerSwitchToSimTask() + { + this.ToggleMode(); + yield break; + } + + // unused; for future reference + private IEnumerator WaitThenTriggerSwitchToBuildTask() + { + while (true) + { + SimulationModeStateEntityStruct modeStruct = this.entitiesDB.QueryUniqueEntity(SimulationModeStateExclusiveGroups.GAME_STATE_GROUP); + if (modeStruct.simulationMode == SimulationMode.Simulation) + { + this.ToggleMode(); + break; + } else + { + yield return Yield.It; + } + } + yield break; + } + + public override void Dispose() + { + CustomCommandUtility.Unregister("MoveBlocks"); + CustomCommandUtility.Unregister("MoveLastBlock"); + } + } +}