diff --git a/assets/blender/tablet.blend b/assets/blender/tablet.blend index 86acfa7..64d2cc2 100644 --- a/assets/blender/tablet.blend +++ b/assets/blender/tablet.blend @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9eaa1529a51ec918937646f594007cdf65ffb01f78ba2b575b5ce216f8c59096 -size 870165 +oid sha256:402add4afba117027fdb976005b5a0052c7d9ebf04be9d7f39cb0fca3666a1dd +size 870421 diff --git a/src/game/Gen.cpp b/src/game/Gen.cpp index 3398753..97c32c2 100644 --- a/src/game/Gen.cpp +++ b/src/game/Gen.cpp @@ -302,6 +302,24 @@ namespace Gen return out; } + Vec3 EulerFromRotation(const Mat4& rotation) + { + const float r32 = rotation.M[9]; + const float r33 = rotation.M[10]; + float x = bx::atan2(r32, r33); + float y = bx::atan2(-rotation.M[8], bx::sqrt(r32 * r32 + r33 * r33)); + float z = bx::atan2(rotation.M[4], rotation.M[0]); + return {x, y, z}; + } + + Mat4 RotationFromEuler(const Vec3& euler) + { + Mat4 mat; + bx::Quaternion quat = bx::fromEuler({euler.x, euler.y, euler.z}); + bx::mtxFromQuaternion(mat.M, quat); + return mat; + } + float Magnitude(const Vec4& vec) { return bx::sqrt(vec.x * vec.x + vec.y * vec.y + vec.z * vec.z + vec.w * vec.w); diff --git a/src/game/Gen.h b/src/game/Gen.h index 1d5b61d..5d2b46c 100644 --- a/src/game/Gen.h +++ b/src/game/Gen.h @@ -73,6 +73,9 @@ namespace Gen Mat4 Transpose(const Mat4& mat); Vec4 Mul(const Mat4& mat, const Vec4& vec); + Vec3 EulerFromRotation(const Mat4& rotation); + Mat4 RotationFromEuler(const Vec3& euler); + float DotProduct(Vec3 a, Vec3 b); Vec3 CrossProduct(Vec3 a, Vec3 b); Vec3 CrossProductFromPlane(Vec3 a, Vec3 b, Vec3 c); diff --git a/src/game/Instance.h b/src/game/Instance.h index 65c8926..afbcb07 100644 --- a/src/game/Instance.h +++ b/src/game/Instance.h @@ -26,6 +26,12 @@ namespace Game int64_t StartTime = 0; }; + // TODO: move to generated data and save + struct SavedPlayerConfig + { + Gen::SavedEntityRenderData TabletRenderData; + }; + struct PlayerData { Gen::Transform PlayerCamTransform; @@ -40,6 +46,7 @@ namespace Game InputMode InputM = InputMode::Game; float MouseSensitivity = 1.0f; float MovementSpeed = 10.0f; + SavedPlayerConfig Config; }; struct InstanceDebugData diff --git a/src/game/Level.cpp b/src/game/Level.cpp index 68de96d..2c8b06d 100644 --- a/src/game/Level.cpp +++ b/src/game/Level.cpp @@ -27,7 +27,7 @@ namespace Game void EntityRenderData::Render(const Model* models, const Material* materials, const Texture* textures) { if (models == nullptr || materials == nullptr || textures == nullptr) return; - if (!Gen::IsValid(ModelH) || MaterialHandle == EMaterial::UNDEFINED) return; + if (!Gen::IsValid(ModelH) || MaterialHandle >= EMaterial::EntryCount) return; if (!Visible) return; auto& rendering = GameRendering::Get(); @@ -74,6 +74,18 @@ namespace Game bgfx::submit(currentMaterial.ViewID, currentMaterial.Shader); } + void EntityRenderData::LoadFromSaved(const Gen::SavedEntityRenderData& saved) + { + DotColor = saved.HighlightColor; + BaseColor = saved.BaseColor; + Transform = saved.TF; + // TODO: fix handle indices + MaterialHandle = saved.Material; + TextureHandle = saved.Texture; + ModelH = saved.Model; + Visible = saved.Visible; + } + namespace { void UpdatePlayerInputMode() @@ -165,7 +177,7 @@ namespace Game Puzzles[i].Setup(); } } - LOG("Tiles: %u", PuzzleTiles.Count); + TabletHandle = UIQuads.New(); UpdatePlayerInputMode(); } @@ -229,6 +241,18 @@ namespace Game bx::mtxRotateXYZ(player.PlayerCamTransform.Rotation.M, player.WalkXRot, player.WalkYRot, 0.0f); } + // UI Tablet + if (IsValid(TabletHandle)) + { + auto& tablet = UIQuads.Get(TabletHandle); + tablet.EData.LoadFromSaved(player.Config.TabletRenderData); + UpdateMatrix(player.PlayerCamTransform); + tablet.EData.Transform.Rotation = player.PlayerCamTransform.Rotation; + Rotate(tablet.EData.Transform, {0.5f * bx::kPi, 0.0f, 0.0f}); + tablet.EData.Transform.Position = + player.PlayerCamTransform.Position + AxisForward(player.PlayerCamTransform.M) * 1.0f; + } + // Cubes for (uint16_t i = 0; i < Cubes.Count; ++i) { @@ -329,12 +353,10 @@ namespace Game UpdateMatrix(camTransform); Vec3 cameraPos = camTransform.Position; - Transform boardTransform; - boardTransform.Rotation = camTransform.Rotation; - Vec3 fw = {camTransform.M.M[8], camTransform.M.M[9], camTransform.M.M[10]}; - Vec3 pos = cameraPos; - pos += fw * 1.0f; - boardTransform.Position = pos; + Transform& boardTransform = level.UIQuads.Get(level.TabletHandle).EData.Transform; + Transform tileOriginTransform = boardTransform; + tileOriginTransform.Position += AxisForward(camTransform.M) * -0.01f; + UpdateMatrix(tileOriginTransform); Vec2 mousePos = GetMousePos(); mousePos.x = mousePos.x / window.WindowWidth; @@ -387,11 +409,13 @@ namespace Game quad.EData.DotColor = card.IsLocked ? Puzzle::GetStaticPuzzleData().Visuals.DisabledCardTint : Vec4{1.0f, 1.0f, 1.0f, 1.0f}; - quad.EData.Transform = boardTransform; + quad.EData.Transform.Position = tileOriginTransform.Position; + quad.EData.Transform.Rotation = camTransform.Rotation; TranslateLocal(quad.EData.Transform, - Vec3{(float)card.Position.X, (float)card.Position.Y, 0.0f} * UICardOffset); - quad.EData.Transform.Scale = {0.1f, 0.1f, 0.1f}; + Vec3{(float)card.Position.X, (float)card.Position.Y, 0.0f} * UICardOffset * + 0.1f); // no clue where the 0.1 comes from Rotate(quad.EData.Transform, Vec3{bx::kPi * 0.5f, 0.0f, (1.0f - card.Rotation * 0.5f) * bx::kPi}); + quad.EData.Transform.Scale = {UICardScale, UICardScale, UICardScale}; Vec3 quadPosWorld = quad.EData.Transform.Position; Vec3 quadXWorld = LocalToGlobalPoint(quad.EData.Transform, {1, 0, 0}); @@ -421,13 +445,13 @@ namespace Game if (DraggedCard.X == x && DraggedCard.Y == y) { Vec3 dragPos = intersectPos; - dragPos -= fw * 0.01f; + dragPos -= AxisForward(camTransform.M) * 0.01f; quad.EData.Transform.Position = dragPos; - Vec3 boardPos = GlobalToLocalPoint(boardTransform, intersectPos); + Vec3 boardPos = GlobalToLocalPoint(tileOriginTransform, intersectPos); Vec3 boardTilePos = boardPos / UICardOffset; int32_t xPos = (int32_t)bx::round(boardTilePos.x); - int32_t yPos = (int32_t)bx::round(boardTilePos.y); + int32_t yPos = (int32_t)bx::round(boardTilePos.z); Gen::PuzPos srcCardPos = {(int8_t)DraggedCard.X, (int8_t)DraggedCard.Y}; Gen::PlacedPuzzleCard& srcCard = Data.PlacedCards[srcCardPos.Y * Puzzle::Config::MaxPuzzleSizeCards + srcCardPos.X]; diff --git a/src/game/Level.h b/src/game/Level.h index 0cff257..77cefe2 100644 --- a/src/game/Level.h +++ b/src/game/Level.h @@ -23,12 +23,13 @@ namespace Game Gen::Vec4 DotColor{1.0f, 1.0f, 1.0f, 1.0f}; Gen::Vec4 BaseColor{0.0f, 0.0f, 0.0f, 1.0f}; Gen::Transform Transform; - EMaterial MaterialHandle = EMaterial::UNDEFINED; + Gen::EMaterial::Enum MaterialHandle = Gen::EMaterial::UI; Gen::TextureHandle TextureHandle; Gen::ModelHandle ModelH; bool Visible = true; void Render(const Model* models, const Material* materials, const Texture* textures); + void LoadFromSaved(const Gen::SavedEntityRenderData& saved); }; ENTITY_HANDLE(CubeHandle); @@ -142,6 +143,7 @@ namespace Game { static constexpr Gen::Vec2 WorldCardSize{10.0f, 10.0f}; static constexpr float UICardOffset = 0.21f; + static constexpr float UICardScale = 0.1f; Gen::PuzzleData Data; Gen::Vec3 WorldPosition; PuzzleTileEntityHandle TileHandles[Puzzle::Config::MaxCardsInPuzzle]; @@ -163,6 +165,7 @@ namespace Game EntityManager LevelEntities; CubeHandle PlayerOutsideViewCube; + UIQuadEntityHandle TabletHandle; public: Gen::StaticPuzzleData PuzzleData; diff --git a/src/game/Tools.cpp b/src/game/Tools.cpp index ee2b9f3..3c34698 100644 --- a/src/game/Tools.cpp +++ b/src/game/Tools.cpp @@ -6,6 +6,7 @@ #include "Tools.h" #include "bx/filepath.h" +#include "bx/math.h" #include "bx/timer.h" #include #include @@ -34,8 +35,22 @@ namespace Tools return "---"; } - void ModelDropdown(Gen::ModelHandle& modelHandle) + bool EntityDataSettings(Gen::SavedEntityRenderData& data) { + bool changed = false; + changed |= ModelDropdown(data.Model); + changed |= MaterialDropdown(data.Material); + changed |= TextureDropdown(data.Texture); + changed |= TransformUI(data.TF); + changed |= ImGui::Checkbox("Visible", &data.Visible); + changed |= ImGui::ColorEdit4("Color 1", &data.BaseColor.x); + changed |= ImGui::ColorEdit4("Color 2", &data.HighlightColor.x); + return changed; + } + + bool ModelDropdown(Gen::ModelHandle& modelHandle) + { + bool changed = false; auto& R = Game::GameRendering::Get(); const char* name = GetAssetPath(modelHandle.Asset); if (ImGui::BeginCombo("Model", name)) @@ -45,14 +60,17 @@ namespace Tools if (ImGui::Selectable(GetAssetPath(R.Models[i].Handle.Asset), i == modelHandle.ModelIdx)) { modelHandle = R.Models[i].Handle; + changed = true; } } ImGui::EndCombo(); } + return changed; } - void TextureDropdown(Gen::TextureHandle& texHandle) + bool TextureDropdown(Gen::TextureHandle& texHandle) { + bool changed = false; auto& R = Game::GameRendering::Get(); const char* name = GetAssetPath(texHandle.Asset); if (ImGui::BeginCombo("Texture", name)) @@ -65,6 +83,7 @@ namespace Tools if (ImGui::Selectable("", i == texHandle.TextureIdx, ImGuiSelectableFlags_AllowOverlap, {0, 64})) { texHandle = R.Textures[i].TexHandle; + changed = true; } ImGui::SetCursorScreenPos(pos); ImGui::Image(R.Textures[i].RenderHandle.idx, {64, 64}); @@ -74,7 +93,47 @@ namespace Tools } ImGui::EndCombo(); } + return changed; } + + bool MaterialDropdown(Gen::EMaterial::Enum& material) + { + bool changed = false; + const char* selectedText = "---"; + if (material < Gen::EMaterial::EntryCount) + { + selectedText = Gen::EMaterial::EntryNames[material]; + } + + if (ImGui::BeginCombo("Material", selectedText)) + { + for (int32_t i = 0; i < Gen::EMaterial::EntryCount; ++i) + { + if (ImGui::Selectable(Gen::EMaterial::EntryNames[i], i == material)) + { + material = (Gen::EMaterial::Enum)i; + changed = true; + } + } + ImGui::EndCombo(); + } + return changed; + } + + bool TransformUI(Gen::Transform& transform) + { + bool changed = false; + changed |= ImGui::DragFloat3("Pos", &transform.Position.x, 0.1f); + Vec3 euler = EulerFromRotation(transform.Rotation); + if (ImGui::DragFloat3("Rot", &euler.x, 0.1f)) + { + transform.Rotation = RotationFromEuler(euler); + changed = true; + } + changed |= ImGui::DragFloat3("Scale", &transform.Scale.x, 0.01f); + return changed; + } + void RenderDebugUI(Game::GameRendering& rendering) { auto& time = Game::GetInstance().Time; @@ -162,13 +221,22 @@ namespace Tools ImGui::Checkbox("Show ImGui Demo", &debug.ShowImguiDemo); ImGui::Checkbox("Show Stats", &debug.ShowStats); if (debug.ShowImguiDemo) ImGui::ShowDemoWindow(&debug.ShowImguiDemo); + ImGui::Separator(); + ImGui::Text("Entity Groups"); ImGui::Checkbox("Cubes", &level.Cubes.IsEnabled); ImGui::Checkbox("Tests", &level.Tests.IsEnabled); ImGui::Checkbox("PuzzleTiles", &level.PuzzleTiles.IsEnabled); ImGui::Checkbox("UIQuads", &level.UIQuads.IsEnabled); + ImGui::Separator(); + + ImGui::Text("Game Tablet"); + Tools::EntityDataSettings(player.Config.TabletRenderData); + + ImGui::Separator(); + if (ImGui::Button("Dithergen")) { DitherGen(rendering.DitherTextures, rendering.DitherRecursion); diff --git a/src/game/Tools.h b/src/game/Tools.h index 809a71c..7739b49 100644 --- a/src/game/Tools.h +++ b/src/game/Tools.h @@ -4,8 +4,11 @@ namespace Tools { - void ModelDropdown(Gen::ModelHandle& modelHandle); - void TextureDropdown(Gen::TextureHandle& texHandle); + bool EntityDataSettings(Gen::SavedEntityRenderData& data); + bool ModelDropdown(Gen::ModelHandle& modelHandle); + bool TextureDropdown(Gen::TextureHandle& texHandle); + bool MaterialDropdown(Gen::EMaterial::Enum& material); + bool TransformUI(Gen::Transform& transform); void RenderDebugUI(Game::GameRendering& rendering); void MeasureFrameEnd(); } // namespace Tools diff --git a/src/game/data/puzzles/0.pzl b/src/game/data/puzzles/0.pzl index 3731831..ac2cf50 100644 --- a/src/game/data/puzzles/0.pzl +++ b/src/game/data/puzzles/0.pzl @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5129bc993aa646404d766c424d8693bafc96457d4c055883c48fdaa830cd5dd5 +oid sha256:bdfe3c22160d79809d814dabf3e4ce06e2d217ca7c1075d9f502bf6c55a348ce size 5820 diff --git a/src/game/rendering/Rendering.cpp b/src/game/rendering/Rendering.cpp index c4f85ba..6e7b206 100644 --- a/src/game/rendering/Rendering.cpp +++ b/src/game/rendering/Rendering.cpp @@ -391,8 +391,8 @@ namespace Game void GameRendering::ReloadShaders() { - Materials[(uint16_t)EMaterial::Default] = Material::LoadFromShader("dither/vert", "dither/frag", MainViewID); - Materials[(uint16_t)EMaterial::UI] = Material::LoadFromShader("normal/vert", "normal/frag", MainViewID); + Materials[Gen::EMaterial::Default] = Material::LoadFromShader("dither/vert", "dither/frag", MainViewID); + Materials[Gen::EMaterial::UI] = Material::LoadFromShader("normal/vert", "normal/frag", MainViewID); } void GameRendering::Update() diff --git a/src/game/rendering/Rendering.h b/src/game/rendering/Rendering.h index 09d4ed4..d778fcc 100644 --- a/src/game/rendering/Rendering.h +++ b/src/game/rendering/Rendering.h @@ -64,13 +64,6 @@ namespace Game Debug, }; - enum class EMaterial : uint16_t - { - Default = 0, - UI = 1, - UNDEFINED = UINT16_MAX - }; - class GameRendering { public: diff --git a/src/models/tablet.glb b/src/models/tablet.glb index ddbe0e5..3cf8b1b 100644 --- a/src/models/tablet.glb +++ b/src/models/tablet.glb @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:22207711195047f5aaba2545b1f8713f37fee9e2b59f4ae42d4be9da9d7b6b12 -size 7048 +oid sha256:6b8721bec981d0f69867eb9560858d3d93edddb1972f50ba6cf4741bb6d1b864 +size 7052