Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions code/io/mouse.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@ int Mouse_dx = 0;
int Mouse_dy = 0;
int Mouse_dz = 0;

// Mouse wheel delta tracking movement not position. Resets every frame.
int Mouse_wheel_dx = 0;
int Mouse_wheel_dy = 0;

int Mouse_sensitivity = 4;

static auto MouseSensitivityOption __UNUSED = options::OptionBuilder<int>("Input.MouseSensitivity",
Expand Down Expand Up @@ -523,6 +527,14 @@ void mouse_get_delta(int *dx, int *dy, int *dz)
*dz = Mouse_dz;
}

void mouse_get_wheel_delta(int* dx, int* dy)
{
if (dx)
*dx = Mouse_wheel_dx;
if (dy)
*dy = Mouse_wheel_dy;
}

// Forces the actual windows cursor to be at (x,y). This may be independent of our tracked (x,y) mouse pos.
void mouse_force_pos(int x, int y)
{
Expand All @@ -535,6 +547,7 @@ void mouse_force_pos(int x, int y)
void mouse_reset_deltas()
{
Mouse_dx = Mouse_dy = Mouse_dz = 0;
Mouse_wheel_dx = Mouse_wheel_dy = 0;
}

void mouse_event(int x, int y, int dx, int dy)
Expand Down Expand Up @@ -635,6 +648,9 @@ void mousewheel_motion(int x, int y, bool reversed) {

Mouse_wheel_x += x;
Mouse_wheel_y += y;
// Used for tracking the actual movement of the wheel, not just the current position
Mouse_wheel_dx += x;
Mouse_wheel_dy += y;

// These nested if's should take care of all edge cases.
// Since x and y's magnitudes can be larger than 1, it is possible to ignore the idle state
Expand Down
3 changes: 2 additions & 1 deletion code/io/mouse.h
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,8 @@ int mouse_down(const CC_bind& bind, bool must_be_wheel = false);
int mouse_down(int btn, bool must_be_wheel = false);

void mouse_reset_deltas();
void mouse_get_delta(int *dx = NULL, int *dy = NULL, int *dz = NULL);
void mouse_get_delta(int* dx = nullptr, int* dy = nullptr, int* dz = nullptr);
void mouse_get_wheel_delta(int* dx = nullptr, int* dy = nullptr);

void mouse_event(int x, int y, int dx, int dy);

Expand Down
81 changes: 80 additions & 1 deletion code/lab/dialogs/lab_ui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,45 @@
#include "weapon/weapon.h"
#include "mission/missionload.h"
#include "prop/prop.h"
#include "controlconfig/controlsconfig.h"

using namespace ImGui;

namespace {
SCP_string get_binding_text(int action_id)
{
const auto& action = Control_config[action_id];

if (!action.first.empty() && !action.second.empty()) {
return action.first.textify() + " or " + action.second.textify();
}

if (!action.first.empty()) {
return action.first.textify();
}

if (!action.second.empty()) {
return action.second.textify();
}

return "Unbound";
}

void controls_reference_entry(const char* label, const SCP_string& description)
{
Bullet();
SameLine();
TextWrapped("%s: %s", label, description.c_str());
}

void controls_reference_entry(const char* label, const char* description)
{
Bullet();
SameLine();
TextWrapped("%s: %s", label, description);
}
} // namespace

std::map<animation::ModelAnimationTriggerType, std::map<SCP_string, bool>> manual_animation_triggers = {};
std::map<animation::ModelAnimationTriggerType, bool> manual_animations = {};

Expand Down Expand Up @@ -269,6 +305,8 @@ void LabUi::build_options_menu()
MenuItem("Object selector", nullptr, &show_object_selection_dialog);
MenuItem("Background selector", nullptr, &show_background_selection_dialog);
MenuItem("Object options", nullptr, &show_object_options_dialog);
MenuItem("Controls reference", nullptr, &show_controls_reference_dialog);
MenuItem("Reset View", nullptr, &reset_view);
MenuItem("Close lab", "ESC", &close_lab);
}
}
Expand All @@ -280,6 +318,11 @@ void LabUi::build_toolbar_entries()
build_options_menu();
}

if (reset_view) {
getLabManager()->Renderer->resetView();
reset_view = false;
}

if (close_lab) {
getLabManager()->notify_close();
close_lab = false;
Expand Down Expand Up @@ -330,9 +373,45 @@ void LabUi::create_ui()
if (show_object_selection_dialog)
show_object_selector();

if (show_controls_reference_dialog)
show_controls_reference();

rebuild_after_object_change = false;
}

void LabUi::show_controls_reference()
{
with_Window("Lab controls reference")
{
TextWrapped("Mouse controls");
controls_reference_entry("LMB + drag", "Orient the displayed object.");
controls_reference_entry("RMB + drag", "Rotate the camera.");
controls_reference_entry("Shift + RMB + drag", "Pan the camera on the X/Y plane.");
controls_reference_entry("Mouse wheel", "Zoom the camera in or out.");
TextWrapped("Rotation axis limits and rotation speed apply only to object orientation (LMB), not "
"camera controls (RMB).");

Separator();
TextWrapped("Keyboard shortcuts");
controls_reference_entry("R", "Cycle object orientation (LMB) axis mode (Yaw, Pitch, Roll, or Both).");
controls_reference_entry("S", "Cycle object orientation (LMB) speed.");
controls_reference_entry("V", "Reset camera view.");
controls_reference_entry("T / Y", "Cycle team color presets.");
controls_reference_entry("1-9", "Switch anti-aliasing presets.");
controls_reference_entry("M", "Export an environment map.");
controls_reference_entry("ESC", "Close the lab.");

if (getLabManager()->CurrentMode == LabMode::Ship) {
Separator();
TextWrapped("Ship-only controls (from current control bindings)");
// These don't work in the new lab yet
//controls_reference_entry("Increase throttle by 5%", get_binding_text(PLUS_5_PERCENT_THROTTLE));
//controls_reference_entry("Decrease throttle by 5%", get_binding_text(MINUS_5_PERCENT_THROTTLE));
controls_reference_entry("Afterburner", get_binding_text(AFTERBURNER));
}
}
}

const char* antialiasing_settings[] = {
"None",
"FXAA Low",
Expand Down Expand Up @@ -604,7 +683,7 @@ void LabUi::show_render_options()
getLabManager()->Renderer->setRenderFlag(LabRenderFlag::NoLighting, no_lighting);
getLabManager()->Renderer->setRenderFlag(LabRenderFlag::ShowFullDetail, show_full_detail);
getLabManager()->Renderer->setRenderFlag(LabRenderFlag::ShowThrusters, show_thrusters);
getLabManager()->Renderer->setRenderFlag(LabRenderFlag::ShowAfterburners, show_afterburners);
getLabManager()->Renderer->setRenderFlag(LabRenderFlag::ShowAfterburners, show_afterburners || getLabManager()->Lab_thrust_afterburn);
getLabManager()->Renderer->setRenderFlag(LabRenderFlag::ShowWeapons, show_weapons);
getLabManager()->Renderer->setRenderFlag(LabRenderFlag::ShowEmissiveLighting, show_emissive_lighting);
getLabManager()->Renderer->setRenderFlag(LabRenderFlag::MoveSubsystems, animate_subsystems);
Expand Down
5 changes: 5 additions & 0 deletions code/lab/dialogs/lab_ui.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ class LabUi {
static void build_background_list();
void show_render_options();
void show_object_options() const;
static void show_controls_reference();
void show_object_selector() const;
void show_background_selector() const;
void build_toolbar_entries();
Expand Down Expand Up @@ -88,6 +89,10 @@ class LabUi {
bool show_object_selection_dialog = true;
bool show_object_options_dialog = false;
bool show_background_selection_dialog = true;
bool show_controls_reference_dialog = false;

// used to track the "Reset View" function
bool reset_view = false;

// used to track the "Close Lab" function
bool close_lab = false;
Expand Down
24 changes: 17 additions & 7 deletions code/lab/manager/lab_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -123,9 +123,13 @@ void LabManager::onFrame(float frametime) {

int key = game_check_key();

int dx, dy;
int dx, dy, dz;
mouse_get_delta(&dx, &dy);
Renderer->getCurrentCamera()->handleInput(dx, dy, mouse_down(MOUSE_LEFT_BUTTON) != 0, mouse_down(MOUSE_RIGHT_BUTTON) != 0, key_get_shift_status());
mouse_get_wheel_delta(nullptr, &dz);
if (dz != 0 && ImGui::IsWindowHovered(ImGuiHoveredFlags_AnyWindow)) {
dz = 0;
}
Renderer->getCurrentCamera()->handleInput(dx, dy, dz, mouse_down(MOUSE_LEFT_BUTTON) != 0, mouse_down(MOUSE_RIGHT_BUTTON) != 0, key_get_shift_status());

if (!Renderer->getCurrentCamera()->handlesObjectPlacement()) {
if (mouse_down(MOUSE_LEFT_BUTTON)) {
Expand Down Expand Up @@ -162,6 +166,12 @@ void LabManager::onFrame(float frametime) {
}
}

if (CurrentMode == LabMode::Ship) {
Lab_thrust_afterburn = check_control(AFTERBURNER) != 0;
} else {
Lab_thrust_afterburn = false;
}

if (key != 0) {
// handle any key presses
switch (key) {
Expand Down Expand Up @@ -219,15 +229,15 @@ void LabManager::onFrame(float frametime) {
default:
// check for game-specific controls
if (CurrentMode == LabMode::Ship) {
if (check_control(PLUS_5_PERCENT_THROTTLE, key))
// These don't work because the lab is a lie and ships don't actually move
// Also the ships are AI and don't really respond to player input anyway so
// getting these working will be tricky
/*if (check_control(PLUS_5_PERCENT_THROTTLE, key))
Lab_thrust_len += 0.05f;
else if (check_control(MINUS_5_PERCENT_THROTTLE, key))
Lab_thrust_len -= 0.05f;

CLAMP(Lab_thrust_len, 0.0f, 1.0f);

if (check_control(AFTERBURNER, key))
Lab_thrust_afterburn = !Lab_thrust_afterburn;
CLAMP(Lab_thrust_len, 0.0f, 1.0f);*/
}
break;
}
Expand Down
4 changes: 2 additions & 2 deletions code/lab/manager/lab_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -148,13 +148,13 @@ class LabManager {
float RotationSpeedDivisor = 100.0f;
bool AllowWeaponDestruction = false;
bool ShowingTechModel = false;
bool Lab_thrust_afterburn = false;

flagset<ManagerFlags> Flags;

gfx_options graphicsSettings;
private:
float Lab_thrust_len = 0.0f;
bool Lab_thrust_afterburn = false;
//float Lab_thrust_len = 0.0f; // Unused
bool Weapons_loaded = false;
bool CloseThis = false;
LabUi labUi;
Expand Down
70 changes: 60 additions & 10 deletions code/lab/renderer/lab_cameras.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "globalincs/pstypes.h"
#include "io/key.h"
#include "io/mouse.h"
#include "lab/renderer/lab_cameras.h"
#include "lab/labv2_internal.h"

Expand All @@ -8,18 +9,53 @@ LabCamera::~LabCamera() {
cam_delete(FS_camera);
}

void OrbitCamera::handleInput(int dx, int dy, bool, bool rmbDown, int modifierKeys) {
if (dx == 0 && dy == 0)
void OrbitCamera::handleInput(int dx, int dy, int dz, bool, bool rmbDown, int modifierKeys) {
if (dx == 0 && dy == 0 && dz == 0)
return;

if (dz > 0) {
for (int i = 0; i < dz; ++i) {
distance *= 0.9f;
}
} else if (dz < 0) {
for (int i = 0; i < -dz; ++i) {
distance *= 1.1f;
}
}
CLAMP(distance, 1.0f, 10000000.0f);

if (rmbDown) {
if (modifierKeys & KEY_SHIFTED) {
distance *= 1.0f + (dy / 200.0f);
CLAMP(distance, 1.0f, 10000000.0f);
}
else {
theta += dx / 100.0f;
phi += dy / 100.0f;
const float pan_factor = distance / 500.0f;

vec3d camera_offset;
camera_offset.xyz.x = sinf(phi) * cosf(theta);
camera_offset.xyz.y = cosf(phi);
camera_offset.xyz.z = sinf(phi) * sinf(theta);

vec3d view_forward;
vm_vec_copy_scale(&view_forward, &camera_offset, -1.0f);

vec3d world_up = vmd_y_vector;
vec3d view_right;
vm_vec_cross(&view_right, &world_up, &view_forward);

if (vm_vec_mag_squared(&view_right) <= 1e-6f) {
world_up = vmd_x_vector;
vm_vec_cross(&view_right, &world_up, &view_forward);
}

vm_vec_normalize_safe(&view_right);

vec3d view_up;
vm_vec_cross(&view_up, &view_forward, &view_right);
vm_vec_normalize_safe(&view_up);

vm_vec_scale_add2(&pan_offset, &view_right, -dx * pan_factor);
vm_vec_scale_add2(&pan_offset, &view_up, dy * pan_factor);
} else {
theta -= dx / 100.0f;
phi -= dy / 100.0f;

CLAMP(phi, 0.01f, PI - 0.01f);
}
Expand All @@ -28,11 +64,24 @@ void OrbitCamera::handleInput(int dx, int dy, bool, bool rmbDown, int modifierKe
updateCamera();
}

void OrbitCamera::resetView()
{
phi = DEFAULT_PHI;
theta = DEFAULT_THETA;
distance = DEFAULT_DISTANCE;
pan_offset = vmd_zero_vector;

displayedObjectChanged();
}

void OrbitCamera::displayedObjectChanged() {
float distance_multiplier = 1.6f;

if (getLabManager()->CurrentObject != -1) {
object* obj = &Objects[getLabManager()->CurrentObject];

// Reset camera panning
pan_offset = vmd_zero_vector;

// Ships and Missiles use the object radius to get a camera distance
distance = obj->radius * distance_multiplier;
Expand Down Expand Up @@ -75,10 +124,11 @@ void OrbitCamera::updateCamera() {
vm_vec_copy_normalize(&forward, &obj->orient.vec.fvec);
vm_vec_scale_add2(&target, &forward, wip->laser_length * 0.5f);
}

vm_vec_add2(&new_position, &target);
}

vm_vec_add2(&target, &pan_offset);
vm_vec_add2(&new_position, &target);

cam->set_position(&new_position);

// If these are the same then that's not great so do nothing and use the last facing value
Expand Down
Loading