: world(world)
, player(player)
, move_dir(0.0f)
-, pitch(0.0f)
-, yaw(0.0f)
, dirty(true)
, aim_world()
, aim_entity() {
-
+ player.GetEntity().SetController(*this);
}
void PlayerController::SetMovement(const glm::vec3 &m) noexcept {
Invalidate();
}
+glm::vec3 PlayerController::ControlForce(const EntityState &s) const {
+ glm::vec3 target(rotateY(move_dir * player.GetEntity().MaxVelocity(), s.yaw) - s.velocity);
+ return target * player.GetEntity().MaxControlForce();
+}
+
void PlayerController::TurnHead(float dp, float dy) noexcept {
- pitch += dp;
- if (pitch > PI / 2) {
- pitch = PI / 2;
- } else if (pitch < -PI / 2) {
- pitch = -PI / 2;
- }
- yaw += dy;
- if (yaw > PI) {
- yaw -= PI * 2;
- } else if (yaw < -PI) {
- yaw += PI * 2;
- }
- Invalidate();
+ player.GetEntity().TurnHead(dp, dy);
+}
+
+float PlayerController::GetPitch() const noexcept {
+ return player.GetEntity().Pitch();
+}
+
+float PlayerController::GetYaw() const noexcept {
+ return player.GetEntity().Yaw();
}
void PlayerController::SelectInventory(int i) noexcept {
}
void PlayerController::UpdatePlayer() noexcept {
- constexpr float max_vel = 0.005f;
if (dirty) {
- player.GetEntity().Orientation(glm::quat(glm::vec3(pitch, yaw, 0.0f)));
- player.GetEntity().Velocity(glm::rotateY(move_dir * max_vel, yaw));
-
Ray aim = player.Aim();
if (!world.Intersection(aim, glm::mat4(1.0f), player.GetEntity().ChunkCoords(), aim_world)) {
aim_world = WorldCollision();
DirectInput::DirectInput(World &world, Player &player, WorldManipulator &manip)
: PlayerController(world, player)
, manip(manip)
-, place_timer(256)
-, remove_timer(256) {
+, place_timer(0.25f)
+, remove_timer(0.25f) {
}
-void DirectInput::Update(int dt) {
+void DirectInput::Update(Entity &, float dt) {
Invalidate(); // world has changed in the meantime
UpdatePlayer();
// message box
, messages(env.assets.small_ui_font)
, msg_timer(5000)
+, msg_keep(false)
// crosshair
, crosshair() {
+ const float ls = env.assets.small_ui_font.LineSkip();
+
// "inventory"
block_transform = glm::translate(block_transform, glm::vec3(50.0f, 50.0f, 0.0f));
block_transform = glm::scale(block_transform, glm::vec3(50.0f));
counter_text.Position(glm::vec3(-25.0f, 25.0f, 0.0f), Gravity::NORTH_EAST);
counter_text.Foreground(glm::vec4(1.0f));
counter_text.Background(glm::vec4(0.5f));
- position_text.Position(glm::vec3(-25.0f, 25.0f + env.assets.small_ui_font.LineSkip(), 0.0f), Gravity::NORTH_EAST);
+ position_text.Position(glm::vec3(-25.0f, 25.0f + ls, 0.0f), Gravity::NORTH_EAST);
position_text.Foreground(glm::vec4(1.0f));
position_text.Background(glm::vec4(0.5f));
- orientation_text.Position(glm::vec3(-25.0f, 25.0f + 2 * env.assets.small_ui_font.LineSkip(), 0.0f), Gravity::NORTH_EAST);
+ orientation_text.Position(glm::vec3(-25.0f, 25.0f + 2 * ls, 0.0f), Gravity::NORTH_EAST);
orientation_text.Foreground(glm::vec4(1.0f));
orientation_text.Background(glm::vec4(0.5f));
- block_text.Position(glm::vec3(-25.0f, 25.0f + 4 * env.assets.small_ui_font.LineSkip(), 0.0f), Gravity::NORTH_EAST);
+ block_text.Position(glm::vec3(-25.0f, 25.0f + 4 * ls, 0.0f), Gravity::NORTH_EAST);
block_text.Foreground(glm::vec4(1.0f));
block_text.Background(glm::vec4(0.5f));
block_text.Set(env.assets.small_ui_font, "Block: none");
- entity_text.Position(glm::vec3(-25.0f, 25.0f + 4 * env.assets.small_ui_font.LineSkip(), 0.0f), Gravity::NORTH_EAST);
+ entity_text.Position(glm::vec3(-25.0f, 25.0f + 4 * ls, 0.0f), Gravity::NORTH_EAST);
entity_text.Foreground(glm::vec4(1.0f));
entity_text.Background(glm::vec4(0.5f));
entity_text.Set(env.assets.small_ui_font, "Entity: none");
// message box
- messages.Position(glm::vec3(25.0f, -25.0f, 0.0f), Gravity::SOUTH_WEST);
+ messages.Position(glm::vec3(25.0f, -25.0f - 2 * ls, 0.0f), Gravity::SOUTH_WEST);
messages.Foreground(glm::vec4(1.0f));
messages.Background(glm::vec4(0.5f));
// crosshair
- OutlineMesh::Buffer buf;
+ PrimitiveMesh::Buffer buf;
buf.vertices = std::vector<glm::vec3>({
{ -10.0f, 0.0f, 0.0f }, { 10.0f, 0.0f, 0.0f },
{ 0.0f, -10.0f, 0.0f }, { 0.0f, 10.0f, 0.0f },
});
- buf.indices = std::vector<OutlineMesh::Index>({
+ buf.indices = std::vector<PrimitiveMesh::Index>({
0, 1, 2, 3
});
- buf.colors.resize(4, { 10.0f, 10.0f, 10.0f });
+ buf.colors.resize(4, { 10.0f, 10.0f, 10.0f, 1.0f });
crosshair.Update(buf);
}
namespace {
-OutlineMesh::Buffer outl_buf;
+PrimitiveMesh::Buffer outl_buf;
}
const Block &block = chunk.BlockAt(index);
const BlockType &type = chunk.Type(index);
outl_buf.Clear();
- type.FillOutlineMesh(outl_buf);
+ type.OutlinePrimitiveMesh(outl_buf);
outline.Update(outl_buf);
outline_transform = chunk.Transform(player.GetEntity().ChunkCoords());
outline_transform *= chunk.ToTransform(Chunk::ToPos(index), index);
void HUD::Render(Viewport &viewport) noexcept {
// block focus
if (outline_visible && config.video.world) {
- PlainColor &outline_prog = viewport.WorldOutlineProgram();
+ PlainColor &outline_prog = viewport.WorldColorProgram();
outline_prog.SetM(outline_transform);
- outline.Draw();
+ outline.DrawLines();
}
// clear depth buffer so everything renders above the world
}
// message box
- if (msg_timer.Running()) {
+ if (msg_keep || msg_timer.Running()) {
messages.Render(viewport);
}
// crosshair
- PlainColor &outline_prog = viewport.HUDOutlineProgram();
+ PlainColor &outline_prog = viewport.HUDColorProgram();
viewport.EnableInvertBlending();
viewport.SetCursor(glm::vec3(0.0f), Gravity::CENTER);
outline_prog.SetM(viewport.Cursor());
- crosshair.Draw();
+ crosshair.DrawLines();
}
// debug overlay
, fwd(0)
, rev(0)
, slot(0)
-, num_slots(10) {
+, num_slots(10)
+, locked(false) {
}
+void Interface::Lock() {
+ fwd = glm::ivec3(0);
+ rev = glm::ivec3(0);
+ locked = true;
+}
+
+void Interface::Unlock() {
+ locked = false;
+}
void Interface::HandlePress(const SDL_KeyboardEvent &event) {
if (!config.input.keyboard) return;
}
void Interface::Handle(const SDL_MouseMotionEvent &event) {
- if (!config.input.mouse) return;
+ if (locked || !config.input.mouse) return;
player_ctrl.TurnHead(
event.yrel * config.input.pitch_sensitivity,
event.xrel * config.input.yaw_sensitivity);