X-Git-Url: http://git.localhorst.tv/?a=blobdiff_plain;f=src%2Fui%2Fui.cpp;h=5ff408be5fddc4f615eb2122230603b6b8cc6516;hb=f1f8941a3f682fb589cf3c620fc7e7602cfc0f7f;hp=bd529d555aab44fb972429029089815c4a480fa2;hpb=6a3227ca747d0598711f7354cd39897184e9fe6a;p=blank.git diff --git a/src/ui/ui.cpp b/src/ui/ui.cpp index bd529d5..5ff408b 100644 --- a/src/ui/ui.cpp +++ b/src/ui/ui.cpp @@ -29,6 +29,7 @@ #include #include #include +#include #include #include @@ -53,8 +54,8 @@ PlayerController::~PlayerController() { } void PlayerController::SetMovement(const glm::vec3 &m) noexcept { - if (dot(m, m) > 1.0f) { - move_dir = normalize(m); + if (glm::dot(m, m) > 1.0f) { + move_dir = glm::normalize(m); } else { move_dir = m; } @@ -98,7 +99,6 @@ void PlayerController::UpdatePlayer() noexcept { if (aim_world && aim_entity) { // got both, pick the closest one if (aim_world.depth < aim_entity.depth) { - // FIXME: somehow this can get stuck on an entity? aim_entity = EntityCollision(); } else { aim_world = WorldCollision(); @@ -108,8 +108,8 @@ void PlayerController::UpdatePlayer() noexcept { if (!iszero(move_dir)) { // scale input by max velocity, apply yaw, and transform to world space steering.SetTargetVelocity(glm::vec3( - glm::vec4(rotateY(move_dir * entity.MaxVelocity(), entity.Yaw()), 0.0f) - * transpose(entity.Transform()) + glm::vec4(glm::rotateY(move_dir * entity.MaxVelocity(), entity.Yaw()), 0.0f) + * glm::transpose(entity.Transform()) )); steering.Enable(Steering::TARGET_VELOCITY); steering.Disable(Steering::HALT); @@ -183,14 +183,59 @@ void DirectInput::PickBlock() { } void DirectInput::PlaceBlock() { + // update block focus UpdatePlayer(); + // do nothing if not looking at any block if (!BlockFocus()) return; + // determine block adjacent to the face the player is looking at BlockLookup next_block(BlockFocus().chunk, BlockFocus().BlockPos(), Block::NormalFace(BlockFocus().normal)); + // abort if it's unavailable if (!next_block) { return; } - manip.SetBlock(next_block.GetChunk(), next_block.GetBlockIndex(), Block(InventorySlot() + 1)); + + // "can replace" check + // this prevents players from replacing solid blocks e.g. by looking through slabs + // simple for now, should be expanded to include things like + // entities in the way or replacable blocks like water and stuff + if (next_block.GetBlock().type != 0) { + return; + } + + Block new_block(InventorySlot() + 1); + + // block's up vector + // align with player's up + const glm::vec3 player_up(GetPlayer().GetEntity().Up()); + new_block.SetFace(Block::NormalFace(player_up)); + // to align with player's local up/down look (like stairs in minecraft), just invert + // it if pitch is positive + // or, align with focus normal (like logs in minecraft) + + // determine block's turn (local rotation about up axis) + // when aligned with player's up (first mode, and currently the only one implemented) + // project the player's view forward onto his entity's XZ plane and + // use the closest cardinal direction it's pointing in + const glm::vec3 view_forward(-GetPlayer().GetEntity().ViewTransform(GetPlayer().GetEntity().ChunkCoords())[2]); + // if view is straight up or down, this will be a null vector (NaN after normalization) + // in that case maybe the model forward should be used? + // the current implementation implicitly falls back to TURN_NONE which is -Z + const glm::vec3 local_forward(glm::normalize(view_forward - glm::proj(view_forward, player_up))); + // FIXME: I suspect this only works when player_up is positive Y + if (local_forward.x > 0.707f) { + new_block.SetTurn(Block::TURN_RIGHT); + } else if (local_forward.z > 0.707f) { + new_block.SetTurn(Block::TURN_AROUND); + } else if (local_forward.x < -0.707f) { + new_block.SetTurn(Block::TURN_LEFT); + } + // for mode two ("minecraft stairs") it should work the same, but I haven't properly + // thought that through (well, that's also true about the whole face/turn thing, but oh well) + // mode three I have absoloutely no clue. that placement would be appropriate for pipe-like + // blocks, where turn shouldn't make a difference, but what if it does? + + manip.SetBlock(next_block.GetChunk(), next_block.GetBlockIndex(), new_block); Invalidate(); } @@ -296,7 +341,7 @@ HUD::HUD(Environment &env, Config &config, const Player &player) buf.indices = std::vector({ 0, 1, 2, 3 }); - buf.colors.resize(4, { 10.0f, 10.0f, 10.0f, 1.0f }); + buf.colors.resize(4, { 255, 255, 255, 255 }); crosshair.Update(buf); }