From e4b6657df3d655ba81722a174ff6e33bb7b3907d Mon Sep 17 00:00:00 2001 From: praydog Date: Wed, 23 Feb 2022 01:33:24 -0800 Subject: [PATCH 01/45] VR: Initial commit of WIP RE7 script --- scripts/re7_vr.lua | 1396 +++++++++++++++++++++++++++++++++++++++ scripts/utility/RE7.lua | 122 ++++ 2 files changed, 1518 insertions(+) create mode 100644 scripts/re7_vr.lua create mode 100644 scripts/utility/RE7.lua diff --git a/scripts/re7_vr.lua b/scripts/re7_vr.lua new file mode 100644 index 000000000..10dd2673b --- /dev/null +++ b/scripts/re7_vr.lua @@ -0,0 +1,1396 @@ +local statics = require("utility/Statics") +local re7 = require("utility/RE7") +local GameObject = require("utility/GameObject") + +local renderer = sdk.get_native_singleton("via.render.Renderer") +local renderer_type = sdk.find_type_definition("via.render.Renderer") + +local GamePadButton = statics.generate("via.hid.GamePadButton") + +local last_camera_matrix = Matrix4x4f.new() +local last_right_hand_rotation = Quaternion.new(0.0, 0.0, 0.0, 0.0) +local last_right_hand_position = Vector3f.new(0.0, 0.0, 0.0) +local last_left_hand_rotation = Quaternion.new(0.0, 0.0, 0.0, 0.0) +local last_left_hand_position = Vector3f.new(0.0, 0.0, 0.0) +local left_hand_rotation_vec = Vector3f.new(-0.105 + 0.2, 2.43, 1.16) -- pitch yaw roll? +local right_hand_rotation_vec = Vector3f.new(-0.105, -2.43, -1.16) -- pitch yaw roll? +local left_hand_rotation_offset = Quaternion.new(left_hand_rotation_vec):normalized() +local right_hand_rotation_offset = Quaternion.new(right_hand_rotation_vec):normalized() +local left_hand_position_offset = Vector4f.new(-0.025, 0.075, 0.155, 0.0) +local right_hand_position_offset = Vector4f.new(0.025, 0.075, 0.155, 0.0) + +local ray_typedef = sdk.find_type_definition("via.Ray") + +local transform_get_position = sdk.find_type_definition("via.Transform"):get_method("get_Position") +local transform_get_rotation = sdk.find_type_definition("via.Transform"):get_method("get_Rotation") +local transform_set_position = sdk.find_type_definition("via.Transform"):get_method("set_Position") +local transform_set_rotation = sdk.find_type_definition("via.Transform"):get_method("set_Rotation") +local transform_get_joints = sdk.find_type_definition("via.Transform"):get_method("get_Joints") + +local joint_get_position = sdk.find_type_definition("via.Joint"):get_method("get_Position") +local joint_get_rotation = sdk.find_type_definition("via.Joint"):get_method("get_Rotation") +local joint_set_position = sdk.find_type_definition("via.Joint"):get_method("set_Position") +local joint_set_rotation = sdk.find_type_definition("via.Joint"):get_method("set_Rotation") + +local component_get_gameobject = sdk.find_type_definition("via.Component"):get_method("get_GameObject") +local gameobject_get_transform = sdk.find_type_definition("via.GameObject"):get_method("get_Transform") + +local cfg_path = "re7_vr/main_config.json" + +local cfg = { + movement_shake = false, + all_camera_shake = true +} + +local function load_cfg() + local loaded_cfg = json.load_file(cfg_path) + + if loaded_cfg == nil then + json.dump_file(cfg_path, cfg) + return + end + + for k, v in pairs(loaded_cfg) do + cfg[k] = v + end +end + +load_cfg() + +statics.generate_global("via.hid.GamePadButton") +statics.generate_global("via.hid.MouseButton") +statics.generate_global("app.HIDManager.InputMode") + +local via_hid_mouse_typedef = sdk.find_type_definition("via.hid.Mouse") +local via_hid_mouse = sdk.get_native_singleton("via.hid.Mouse") + +local function get_mouse_device() + return sdk.call_native_func(via_hid_mouse, via_hid_mouse_typedef, "get_Device") +end + +local function set_inputmode(mode) + local hid_manager = sdk.get_managed_singleton(sdk.game_namespace("HIDManager")) + + if hid_manager then + hid_manager:call("set_inputMode", mode) + end +end + +local function update_pad_device(device) + if not vrmod:is_hmd_active() then + return + end + + local raw_left_stick_axis = vrmod:get_left_stick_axis() + + --local vr_left_stick_axis = last_camera_matrix:to_quat() * Vector4f.new(raw_left_stick_axis.x, raw_left_stick_axis.y, 0.0, 0.0) + local vr_left_stick_axis = vrmod:get_left_stick_axis() + local vr_right_stick_axis = vrmod:get_right_stick_axis() + + local cur_button = device:call("get_Button") + + device:call("set_AxisL", vr_left_stick_axis) + device:call("set_RawAxisR", vr_right_stick_axis) + device:call("set_AxisR", vr_right_stick_axis) + + -- we have these via.hid.GamePadButton values for the right stick + -- EmuRup + -- EmuRright + -- EmuRdown + -- EmuRleft + + -- set cur_button | according to the right stick axis + if vr_right_stick_axis.x > 0.1 then + --cur_button = cur_button | via.hid.GamePadButton.RRight + elseif vr_right_stick_axis.x < -0.1 then + --cur_button = cur_button | via.hid.GamePadButton.RLeft + end + + if vr_right_stick_axis.y > 0.1 then + --cur_button = cur_button | via.hid.GamePadButton.RUp + elseif vr_right_stick_axis.y < -0.1 then + --cur_button = cur_button | via.hid.GamePadButton.RDown + end + + if vr_left_stick_axis.x > 0.1 then + --cur_button = cur_button | via.hid.GamePadButton.LRight + elseif vr_left_stick_axis.x < -0.1 then + --cur_button = cur_button | via.hid.GamePadButton.LLeft + end + + if vr_left_stick_axis.y > 0.1 then + --cur_button = cur_button | via.hid.GamePadButton.LUp + elseif vr_left_stick_axis.y < -0.1 then + --cur_button = cur_button | via.hid.GamePadButton.LDown + end + + local action_trigger = vrmod:get_action_trigger() + local action_grip = vrmod:get_action_grip() + local action_a_button = vrmod:get_action_a_button() + local action_b_button = vrmod:get_action_b_button() + local action_joystick_click = vrmod:get_action_joystick_click() + + local right_joystick = vrmod:get_right_joystick() + local left_joystick = vrmod:get_left_joystick() + + if vrmod:is_action_active(action_trigger, right_joystick) then + device:call("set_AnalogR", 1.0) + cur_button = cur_button | via.hid.GamePadButton.RTrigBottom + end + + -- gripping right joystick causes "left trigger" to be pressed (aiming) + if vrmod:is_action_active(action_grip, right_joystick) then + cur_button = cur_button | via.hid.GamePadButton.LTrigBottom + device:call("set_AnalogL", 1.0) + end + + if vrmod:is_action_active(action_trigger, left_joystick) then + -- DPad mimickry + if vr_left_stick_axis.y >= 0.9 then + cur_button = cur_button | via.hid.GamePadButton.LUp + elseif vr_left_stick_axis.y <= -0.9 then + cur_button = cur_button | via.hid.GamePadButton.LDown + end + + if vr_left_stick_axis.x >= 0.9 then + cur_button = cur_button | via.hid.GamePadButton.LRight + elseif vr_left_stick_axis.x <= -0.9 then + cur_button = cur_button | via.hid.GamePadButton.LLeft + end + + -- set right bumper instead of left trigger + cur_button = cur_button | via.hid.GamePadButton.LTrigTop + + -- set right bumper (heal) if holding both trigger and grip + if vrmod:is_action_active(action_grip, left_joystick) then + cur_button = cur_button | via.hid.GamePadButton.RTrigTop + end + end + + if re7.wants_block then + cur_button = cur_button | via.hid.GamePadButton.LTrigTop + end + + if vrmod:is_action_active(action_a_button, right_joystick) then + cur_button = cur_button | via.hid.GamePadButton.Decide | via.hid.GamePadButton.RDown + end + + if vrmod:is_action_active(action_b_button, right_joystick) then + cur_button = cur_button | via.hid.GamePadButton.RLeft + end + + if vrmod:is_action_active(action_a_button, left_joystick) then + cur_button = cur_button | via.hid.GamePadButton.Cancel | via.hid.GamePadButton.RRight + end + + if vrmod:is_action_active(action_b_button, left_joystick) then + cur_button = cur_button | via.hid.GamePadButton.RUp + end + + if vrmod:is_action_active(action_joystick_click, right_joystick) then + cur_button = cur_button | via.hid.GamePadButton.RStickPush + end + + if vrmod:is_action_active(action_joystick_click, left_joystick) then + cur_button = cur_button | via.hid.GamePadButton.LStickPush + end + + device:call("set_Button", cur_button) + device:call("set_ButtonDown", cur_button) +end + +local function update_padman(padman) + if not vrmod:is_hmd_active() or not vrmod:is_using_controllers() then + return + end + + local merged_pad = padman:call("get_mergedPad") + + if not merged_pad then + return + end + + --padman:call("set_activePad", merged_pad) + + local device = merged_pad:get_field("Device") + + if not device then + return + end + + update_pad_device(device) + --merged_pad:call("updateStick") + --merged_pad:call("updateButton") + + set_inputmode(app.HIDManager.InputMode.Pad) +end + +local function on_pre_app_pad_update(args) + if not vrmod:is_hmd_active() or not vrmod:is_using_controllers() then + return + end + + local pad = sdk.to_managed_object(args[2]) + + local padman = sdk.get_managed_singleton(sdk.game_namespace("PadManager")) + + if not padman then + return + end + + local merged_pad = padman:call("get_mergedPad") + + if not merged_pad or merged_pad ~= pad then + return + end + + local device = merged_pad:get_field("Device") + + if not device then + return + end + + update_pad_device(device) + --merged_pad:call("updateStick") + --merged_pad:call("updateButton") + + set_inputmode(app.HIDManager.InputMode.Pad) +end + +local function on_post_app_pad_update(retval) + return retval +end + +sdk.hook( + sdk.find_type_definition("app.Pad"):get_method("update"), + on_pre_app_pad_update, + on_post_app_pad_update +) + +local function on_pre_try_guard_start(args) + if not vrmod:is_hmd_active() or not vrmod:is_using_controllers() then + return + end + + -- this will only allow blocking by physically holding your hands up. + if not re7.wants_block then + return sdk.PreHookResult.SKIP_ORIGINAL + end +end + +local function on_post_try_guard_start(retval) + if not vrmod:is_hmd_active() or not vrmod:is_using_controllers() or re7.wants_block then + return retval + end + + return sdk.to_ptr(0) +end + +sdk.hook( + sdk.find_type_definition("app.PlayerBase"):get_method("tryGuardStart"), + on_pre_try_guard_start, + on_post_try_guard_start +) + +local function calculate_tpose_world(joint, depth) + if not depth then + depth = 1 + end + + local original_positions = {} + local original_rotations = {} + local current_positions = {} + + local player_transform = re7.transform + local player_pos = transform_get_position:call(player_transform) + local player_rot = transform_get_rotation:call(player_transform) + + local joints = {} + + local cur_joint = joint + + for i=0, depth do + local parent = cur_joint:call("get_Parent") + table.insert(joints, parent) + cur_joint = parent + end +end + +local function set_hand_joints_to_tpose(hand_ik) + local hashes = { + hand_ik:get_field("HashJoint0"), + hand_ik:get_field("HashJoint1"), + hand_ik:get_field("HashJoint2"), + hand_ik:get_field("HashJoint3") + } + + local original_positions = {} + local original_rotations = {} + local current_positions = {} + + local player_transform = re7.transform + local player_pos = transform_get_position:call(player_transform) + local player_rot = transform_get_rotation:call(player_transform) + + local joints = {} + + for i, hash in ipairs(hashes) do + if hash and hash ~= 0 then + local joint = player_transform:call("getJointByHash", hash) + + if joint then + table.insert(joints, joint:call("get_Parent")) + end + end + end + + if #joints > 0 and joints[1] ~= nil then + table.insert(joints, 1, joints[1]:call("get_Parent")) + table.insert(joints, 1, joints[1]:call("get_Parent")) + table.insert(joints, 1, joints[1]:call("get_Parent")) + end + + for i, joint in ipairs(joints) do + local base_transform = player_transform:calculate_base_transform(joint) + original_positions[i] = player_pos + (player_rot * base_transform[3]) + original_rotations[i] = player_rot * base_transform:to_quat() + current_positions[i] = joint_get_position:call(joint) + end + + -- second pass + for i, joint in ipairs(joints) do + if joint then + local next_joint = joints[i + 1] + + if next_joint ~= nil then + local diff = original_positions[i + 1] - original_positions[i] + local updated_pos = current_positions[i] + diff + + joint_set_position:call(next_joint, updated_pos) + joint_set_rotation:call(next_joint, original_rotations[i+1]) + + current_positions[i + 1] = updated_pos + end + end + end +end + +local function update_hand_ik() + if not re7.player then return end + if not vrmod:is_hmd_active() or not vrmod:is_using_controllers() then return end + + local controllers = vrmod:get_controllers() + + if #controllers == 0 then + return + end + + if not re7.left_hand_ik or not re7.right_hand_ik then + return + end + + if re7.is_in_cutscene then return end + + local left_controller_transform = vrmod:get_transform(controllers[1]) + local right_controller_transform = vrmod:get_transform(controllers[2]) + local left_controller_rotation = left_controller_transform:to_quat() + local right_controller_rotation = right_controller_transform:to_quat() + + local hmd_transform = vrmod:get_transform(0) + --local hmd_rotation = (vrmod:get_rotation_offset() * hmd_transform:to_quat()):normalized() + + local left_controller_offset = left_controller_transform[3] - hmd_transform[3] + local right_controller_offset = right_controller_transform[3] - hmd_transform[3] + + local camera = sdk.get_primary_camera() + local camera_rotation = last_camera_matrix:to_quat() + + local original_camera_matrix = camera:call("get_WorldMatrix") + local original_camera_rotation_pre = original_camera_matrix:to_quat() + local original_camera_rotation = (original_camera_rotation_pre * vrmod:get_rotation_offset()):normalized() + + local fake_quat = Quaternion.new(original_camera_rotation_pre.w, original_camera_rotation_pre.x, original_camera_rotation_pre.y, original_camera_rotation_pre.z) + local updated_camera_pos = original_camera_matrix[3] + + vrmod:apply_hmd_transform(fake_quat, updated_camera_pos) + + local new_rotation = original_camera_rotation * left_controller_rotation * left_hand_rotation_offset + local new_pos = updated_camera_pos + + ((original_camera_rotation * left_controller_offset) + + ((original_camera_rotation * left_controller_rotation):normalized() * left_hand_position_offset)) + + last_left_hand_position = new_pos + last_left_hand_rotation = new_rotation + + set_hand_joints_to_tpose(re7.left_hand_ik) + + transform_set_position:call(re7.left_hand_ik_transform, new_pos) + transform_set_rotation:call(re7.left_hand_ik_transform, new_rotation) + re7.left_hand_ik:set_field("Transition", 1.0) + re7.left_hand_ik:call("calc") + + --re7.transform:call("getJointByHash", re7.left_hand_ik:get_field("HashJoint2")):call("set_Position", new_pos) + + new_rotation = original_camera_rotation * right_controller_rotation * right_hand_rotation_offset + new_pos = updated_camera_pos + + ((original_camera_rotation * right_controller_offset) + + ((original_camera_rotation * right_controller_rotation):normalized() * right_hand_position_offset)) + + last_right_hand_position = new_pos + last_right_hand_rotation = new_rotation + + set_hand_joints_to_tpose(re7.right_hand_ik) + + transform_set_position:call(re7.right_hand_ik_transform, new_pos) + transform_set_rotation:call(re7.right_hand_ik_transform, new_rotation) + re7.right_hand_ik:set_field("Transition", 1.0) + re7.right_hand_ik:call("calc") + + --re7.transform:call("getJointByHash", re7.right_hand_ik:get_field("HashJoint2")):call("set_Position", new_pos) +end + +local last_real_camera_rotation = Quaternion.new(1, 0, 0, 0) +local last_real_camera_joint_rotation = Quaternion.new(1, 0, 0, 0) +local last_real_camera_joint_pos = Vector3f.new(0, 0, 0) + +local neg_forward_identity = Matrix4x4f.new(-1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, -1, 0, + 0, 0, 0, 1):to_quat() + +local head_hash = nil +local center_hash = nil +local chest_hash = nil + +local known_hashes = {} + +local function get_joint_hash(transform, motion, name) + if not known_hashes[transform] then + known_hashes[transform] = {} + end + + local hash = known_hashes[transform][name] + + if hash then + return hash + end + + local joint = transform:call("getJointByName", name) + + if not joint then + log.debug("Failed to get " .. name .. " joint") + return nil + end + + hash = joint:call("get_NameHash") + log.info(name .. " hash: " .. string.format("%x", hash)) + + known_hashes[transform][name] = hash + + return hash +end + +local zero_vec = Vector3f.new(0, 0, 0) + +local function update_body_ik(camera_rotation, camera_pos) + if not re7.player then return end + + local player = re7.player + local ik_leg = player:call("getComponent(System.Type)", sdk.typeof("via.motion.IkLeg")) + + if not ik_leg then + ik_leg = player:call("createComponent(System.Type)", sdk.typeof("via.motion.IkLeg")) + + if not ik_leg then + log.error("Failed to create IK leg component") + return + end + end + + if re7.is_in_cutscene or not vrmod:is_hmd_active() then + --ik_leg:call("set_Enabled", false) + ik_leg:call("set_CenterOffset", Vector3f.new(0, 0, 0)) + return + else + ik_leg:call("set_Enabled", true) + end + + local motion = player:call("getComponent(System.Type)", sdk.typeof("via.motion.Motion")) + + if not motion then + log.error("Failed to get motion component") + return + end + + local transform = player:call("get_Transform") + + if not head_hash then + head_hash = get_joint_hash(transform, motion, "Head") + end + + if not chest_hash then + chest_hash = get_joint_hash(transform, motion, "Chest") + end + + if not center_hash then + center_hash = get_joint_hash(transform, motion, "Hip") + end + + local transform_rot = transform:call("get_Rotation") + local transform_pos = transform:call("get_Position") + + --local head_joint = transform:call("getJointByHash", head_hash) + --local chest_joint = transform:call("getJointByHash", chest_hash) + + local head_index = motion:call("getJointIndexByNameHash", head_hash) + --chest_index = motion:call("getJointIndexByNameHash", chest_hash) + local original_head_pos = motion:call("getWorldPosition", head_index) + --local original_chest_pos = motion:call("getWorldPosition", chest_index) + + original_head_pos = transform_rot * original_head_pos + --original_chest_pos = transform_rot * original_chest_pos + + --original_head_pos.x = original_chest_pos.x + --original_head_pos.z = original_chest_pos.z + + --[[local center_index = motion:call("getJointIndexByNameHash", center_hash) + local original_center_pos = motion:call("getWorldPosition", center_index) + + original_center_pos = transform_rot * original_center_pos + + local current_center_pos = transform:call("getJointByHash", center_hash):call("get_Position") + local center_diff = (original_center_pos * -1.0) + center_diff.y = 0.0]] + + --local current_head_pos = transform:call("getJointByName", "Head"):call("get_Position") + + --[[local center_joint = transform:call("getJointByName", "Hip") + + local center_pos = center_joint:call("get_Position") + local transform_pos = transform:call("get_Position")]] + + local diff_to_camera = ((camera_pos - transform_pos) - original_head_pos) + + --ik_leg:call("set_CenterJointName", "Hip") + ik_leg:call("set_CenterOffset", diff_to_camera) + ik_leg:call("setCenterAdjust", 0) + --ik_leg:call("set_UpdateTiming", 2) -- ConstraintsBegin +end + +local function on_pre_shoot(args) + if not vrmod:is_hmd_active() or not vrmod:is_using_controllers() then + return + end + + update_hand_ik() + + local weapon = sdk.to_managed_object(args[2]) + local ray = args[3] + + local muzzle_joint = weapon:call("get_muzzleJoint") + + if muzzle_joint then + local muzzle_pos = joint_get_position:call(muzzle_joint) + local muzzle_forward = joint_get_rotation:call(muzzle_joint) * Vector3f.new(0, 0, 1) + + -- nudge the start position slightly forward because + -- apparently the bullets can collide with the weapon.... wtf + sdk.set_native_field(ray, ray_typedef, "from", muzzle_pos + (muzzle_forward * 0.01)) + sdk.set_native_field(ray, ray_typedef, "dir", muzzle_forward) + else + log.info("No muzzle joint found") + end + + --sdk.call_native_func(ray, ray_typedef, ".ctor(via.vec3, via.vec3)", last_muzzle_pos, last_muzzle_forward) +end + +local function on_post_shoot(retval) + return retval +end + +sdk.hook(sdk.find_type_definition("app.WeaponGun"):get_method("shoot"), on_pre_shoot, on_post_shoot) + +local old_camera_rot = nil +local old_camera_pos = nil + +-- let player look at interaction elements with the camera +local function on_pre_interact_manager_lateupdate(args) + if not vrmod:is_hmd_active() then + return + end + + local camera = sdk.get_primary_camera() + local camera_gameobject = component_get_gameobject:call(camera) + local camera_transform = gameobject_get_transform:call(camera_gameobject) + + local joint = transform_get_joints:call(camera_transform)[0] + + old_camera_rot = joint_get_rotation:call(joint) + old_camera_pos = joint_get_position:call(joint) + + joint_set_rotation:call(joint, last_camera_matrix:to_quat()) + joint_set_position:call(joint, last_camera_matrix[3]) +end + +local function on_post_interact_manager_lateupdate(retval) + if not vrmod:is_hmd_active() then + return + end + + local camera = sdk.get_primary_camera() + local camera_gameobject = component_get_gameobject:call(camera) + local camera_transform = gameobject_get_transform:call(camera_gameobject) + + local joint = transform_get_joints:call(camera_transform)[0] + + joint_set_rotation:call(joint, old_camera_rot) + joint_set_position:call(joint, old_camera_pos) + + return retval +end + +sdk.hook( + sdk.find_type_definition("app.InteractManager"):get_method("doLateUpdate"), + on_pre_interact_manager_lateupdate, + on_post_interact_manager_lateupdate +) + +local was_vert_limited = false + +local last_gui_quat = Quaternion.identity() +local last_gui_dot = 0.0 +local last_gui_forced_slerp = os.clock() +local needs_cutscene_recenter = false + +-- force the gui to recenter when opening the inventory +sdk.hook( + sdk.find_type_definition("app.MenuManager"):get_method("openInventoryMenu"), + function(args) + last_gui_forced_slerp = os.clock() + end, + function(retval) + return retval + end +) + +local last_camera_update_args = nil + +local function fix_player_camera(player_camera) + if not vrmod:is_hmd_active() then + -- so the camera doesnt go wacky + if needs_cutscene_recenter then + -- disables the body IK component + update_body_ik(nil, nil) + + vrmod:set_gui_rotation_offset(Quaternion.identity()) + vrmod:recenter_view() + + needs_cutscene_recenter = false + end + + -- Restore the vertical camera movement after taking headset off/not using controllers + if was_vert_limited then + --local player_camera = sdk.to_managed_object(args[2]) + local base_transform_solver = player_camera:get_field("BaseTransSolver") + + if base_transform_solver then + local camera_controller = base_transform_solver:get_field("CurrentController") + + -- Stop the player from rotating the camera vertically + if camera_controller then + camera_controller:set_field("IsVerticalRotateLimited", false) + end + end + + was_vert_limited = false + end + + last_real_camera_rotation = nil + last_real_camera_joint_rotation = nil + + return retval + end + + if re7.is_in_cutscene and needs_cutscene_recenter then + vrmod:set_gui_rotation_offset(Quaternion.identity()) + vrmod:recenter_view() + + -- force the gui to be recentered when we exit the cutscene + last_gui_forced_slerp = os.clock() + needs_cutscene_recenter = false + end + + local camera = sdk.get_primary_camera() + + -- apply the camera rot to the real camera + local camera_gameobject = camera:call("get_GameObject") + local camera_transform = camera_gameobject:call("get_Transform") + --last_real_camera_rotation = camera_transform:call("get_Rotation") + --last_real_camera_joint_rotation = camera_transform:call("get_Joints")[0]:call("get_Rotation") + + local camera_rot = transform_get_rotation:call(camera_transform) + local camera_pos = transform_get_position:call(camera_transform) + + local camera_rot_pre_hmd = Quaternion.new(camera_rot.w, camera_rot.x, camera_rot.y, camera_rot.z) + local camera_pos_pre_hmd = Vector3f.new(camera_pos.x, camera_pos.y, camera_pos.z) + + --camera_rot = (neg_forward_identity * camera_rot):normalized() + --camera_rot = neg_forward_identity * camera_rot + + --[[local forward = camera_rot * Vector3f.new(0, 0, 1) + forward.y = 0.0 + forward:normalize()]] + + --local camera_rot = (forward * -1.0):to_quat() + + vrmod:apply_hmd_transform(camera_rot, camera_pos) + + --local neg_camera_rot = (neg_forward_identity * camera_rot):normalized() + + local camera_joint = camera_transform:call("get_Joints")[0] + + -- Transform is used for things like Ethan's light + -- and determining where the player is looking + transform_set_position:call(camera_transform, camera_pos) + transform_set_rotation:call(camera_transform, camera_rot) + + last_real_camera_joint_rotation = camera_rot_pre_hmd + last_real_camera_joint_pos = camera_pos_pre_hmd + + --joint_set_position:call(camera_joint, camera_pos) + --joint_set_rotation:call(camera_joint, neg_camera_rot) + + -- Joint is used for the actual final rendering of the game world + joint_set_position:call(camera_joint, camera_pos_pre_hmd) + joint_set_rotation:call(camera_joint, camera_rot_pre_hmd) + + -- just update the body IK right after we update the camera. + update_body_ik(camera_rot_pre_hmd, camera_pos) + + -- Slerp the gui around + if not re7.is_in_cutscene then + local new_gui_quat = camera_rot_pre_hmd * camera_rot:inverse() + last_gui_dot = last_gui_quat:dot(new_gui_quat) + local dot_dist = 1.0 - math.abs(last_gui_dot) + local dot_ang = math.acos(math.abs(last_gui_dot)) * (180.0 / math.pi) + last_gui_dot = dot_ang + + local now = os.clock() + + -- trigger gui slerp + if dot_ang >= 20 then + last_gui_forced_slerp = os.clock() + end + + local slerp_time_diff = now - last_gui_forced_slerp + + if slerp_time_diff <= 1.5 then + if dot_ang >= 10 then + last_gui_forced_slerp = now + end + + last_gui_quat = last_gui_quat:slerp(new_gui_quat, dot_dist * math.max((1.5 - slerp_time_diff), 0.0)) + vrmod:recenter_gui(last_gui_quat) + end + + needs_cutscene_recenter = true + end + + --[[local fixed_dir = camera_rot * Vector3f.new(0, 0, 1) + fixed_dir.y = fixed_dir.y * -1.0 + fixed_dir:normalize() + local fixed_rot = fixed_dir:to_quat()]] + + local fixed_rot = neg_forward_identity * camera_rot + local fixed_dir = fixed_rot * Vector3f.new(0, 0, 1) + + player_camera:set_field("k__BackingField", fixed_rot) + player_camera:set_field("k__BackingField", camera_pos) + + player_camera:set_field("CameraRotationWithMovementShake", fixed_rot) + player_camera:set_field("CameraPositionWithMovementShake", camera_pos) + player_camera:set_field("CameraRotationWithCameraShake", fixed_rot) + player_camera:set_field("CameraPositionWithCameraShake", camera_pos) + player_camera:set_field("PrevCameraRotation", fixed_rot) + + local camera_controller_param = player_camera:get_field("CameraCtrlParam") + + if camera_controller_param then + camera_controller_param:set_field("CameraRotation", fixed_rot) + end + + local base_transform_solver = player_camera:get_field("BaseTransSolver") + + if base_transform_solver then + local camera_controller = base_transform_solver:get_field("CurrentController") + + -- Stop the player from rotating the camera vertically + if camera_controller then + local camera_controller_rot = camera_controller:get_field("k__BackingField") + local controller_forward = camera_controller_rot * Vector3f.new(0.0, 0.0, 1.0) + controller_forward.y = 0.0 + controller_forward:normalize() + camera_controller_rot = controller_forward:to_quat() + base_transform_solver:set_field("k__BackingField", camera_controller_rot) + camera_controller:set_field("k__BackingField", camera_controller_rot) + camera_controller:set_field("IsVerticalRotateLimited", true) + was_vert_limited = true + end + end + + -- stops the camera from pivoting around the player + -- so we can use VR to look around without the body sticking out + if vrmod:is_using_controllers() then + local param_container = player_camera:get_field("_CurrentParamContainer") + + if param_container ~= nil then + local posture_param = param_container:get_field("PostureParam") + + if posture_param ~= nil then + local current_camera_offset = posture_param:get_field("CameraOffset") + current_camera_offset.x = 0.0 + current_camera_offset.z = 0.0 + + posture_param:set_field("CameraOffset", current_camera_offset) + end + end + end + + local look_ray_offset = player_camera:get_type_definition():get_field("LookRay"):get_offset_from_base() + local shoot_ray_offset = player_camera:get_type_definition():get_field("ShootRay"):get_offset_from_base() + local look_ray = player_camera:get_address() + look_ray_offset + local shoot_ray = player_camera:get_address() + shoot_ray_offset + + --local new_dir = Vector4f.new(0.0, 0.0, 0.0, 1.0) + local new_pos = Vector4f.new(camera_pos.x, camera_pos.y, camera_pos.z, 1.0) + + sdk.set_native_field(sdk.to_ptr(look_ray), ray_typedef, "from", camera_pos) + sdk.set_native_field(sdk.to_ptr(look_ray), ray_typedef, "dir", fixed_dir) + sdk.set_native_field(sdk.to_ptr(shoot_ray), ray_typedef, "from", camera_pos) + sdk.set_native_field(sdk.to_ptr(shoot_ray), ray_typedef, "dir", fixed_dir) + --look_ray:set_field("from", camera_pos) + --look_ray:set_field("dir", new_dir) + + --player_camera:set_field("LookRay", look_ray) + + --look_ray:set_field("from", new_pos) + --look_ray:set_field("dir", new_dir) + --player_camera:set_field("ShootRay", look_ray) +end + +local function on_pre_player_camera_update(args) + last_camera_update_args = args + + if not vrmod:is_hmd_active() then + return + end + + --local player_camera = sdk.to_managed_object(args[2]) + --fix_player_camera(player_camera) + + --[[local player_camera = sdk.to_managed_object(args[2]) + + local camera = sdk.get_primary_camera() + local camera_gameobject = camera:call("get_GameObject") + local camera_transform = camera_gameobject:call("get_Transform")]] + --last_real_camera_rotation = camera_transform:call("get_Rotation") + --last_real_camera_joint_rotation = camera_transform:call("get_Joints")[0]:call("get_Rotation") + + --return sdk.PreHookResult.SKIP_ORIGINAL +end + +local function on_post_player_camera_update(retval) + local args = last_camera_update_args + + local player_camera = sdk.to_managed_object(args[2]) + fix_player_camera(player_camera) + + return retval +end + +-- Normal Ethan camera +sdk.hook( + sdk.find_type_definition("app.PlayerCamera"):get_method("lateUpdate"), + on_pre_player_camera_update, + on_post_player_camera_update +) + +-- Not a hero camera +sdk.hook( + sdk.find_type_definition("app.CH8PlayerCamera"):get_method("lateUpdate"), + on_pre_player_camera_update, + on_post_player_camera_update +) + +-- idk the other DLC? +sdk.hook( + sdk.find_type_definition("app.CH9PlayerCamera"):get_method("lateUpdate"), + on_pre_player_camera_update, + on_post_player_camera_update +) + +-- Zero out the camera shake +sdk.hook( + sdk.find_type_definition("app.PlayerCamera"):get_method("updateCameraShakeValue"), + function(args) + if not cfg.all_camera_shake then + return sdk.PreHookResult.SKIP_ORIGINAL + end + end, + function(retval) + if not vrmod:is_hmd_active() or not vrmod:is_using_controllers() then + return retval + end + + local args = last_camera_update_args + if args == nil then return retval end + + local player_camera = sdk.to_managed_object(args[2]) + + local zero_quat = Quaternion.new(1, 0, 0, 0) + local zero_vec = Vector3f.new(0, 0, 0) + + if not cfg.movement_shake then + player_camera:set_field("MovementShakePosition", zero_vec) + player_camera:set_field("MovementShakeRotation", zero_quat) + end + + return retval + end +) + +local function on_pre_upper_vertical_update(args) + if not vrmod:is_hmd_active() or not vrmod:is_using_controllers() then + return + end + + --[[local upper_vertical = sdk.to_managed_object(args[2]) + + if not last_camera_update_args then return end + local player_camera = sdk.to_managed_object(last_camera_update_args[2]) + + local camera_rot = player_camera:get_field("k__BackingField") + local camera_pos = player_camera:get_field("k__BackingField") + + vrmod:apply_hmd_transform(camera_rot, camera_pos) + + player_camera:set_field("k__BackingField", camera_rot) + player_camera:set_field("k__BackingField", camera_pos) + + player_camera:set_field("CameraRotationWithMovementShake", camera_rot) + player_camera:set_field("CameraPositionWithMovementShake", camera_pos) + player_camera:set_field("CameraRotationWithCameraShake", camera_rot) + player_camera:set_field("CameraPositionWithCameraShake", camera_pos)]] + --player_camera:set_field("OtherShakeRotation", camera_rot) + --player_camera:set_field("OtherShakePosition", camera_pos) +end + +local function on_post_upper_vertical_update(retval) + return retval +end + +sdk.hook( + sdk.find_type_definition("app.PlayerUpperVerticalRotate"):get_method("doLateUpdate"), + on_pre_upper_vertical_update, + on_post_upper_vertical_update +) + +local function check_player_hands_up() + local player = re7.player + + if not player then + re7.wants_block = false + return + end + + local right_hand_up = false + local left_hand_up = false + + + local controllers = vrmod:get_controllers() + if #controllers < 2 then + re7.wants_block = false + return + end + + local hmd = vrmod:get_transform(0) + local left_hand = vrmod:get_transform(controllers[1]) + local right_hand = vrmod:get_transform(controllers[2]) + + local delta_to_left = left_hand[3] - hmd[3] + local delta_to_right = right_hand[3] - hmd[3] + local dir_to_left = delta_to_left:normalized() + local dir_to_right = delta_to_right:normalized() + + local hmd_forward = hmd[2] + + local left_hand_dot = math.abs(hmd_forward:dot(dir_to_left)) + local right_hand_dot = math.abs(hmd_forward:dot(dir_to_right)) + + local left_hand_in_front = left_hand_dot >= 0.8 + local right_hand_in_front = right_hand_dot >= 0.8 + + local first_test = left_hand_in_front and right_hand_in_front + + if not first_test then + re7.wants_block = false + return + end + + -- now we need to check if the hands are facing up + local left_hand_up_dot = math.abs(hmd_forward:dot(left_hand[0])) + local right_hand_up_dot = math.abs(hmd_forward:dot(right_hand[0])) + + left_hand_up = left_hand_up_dot >= 0.5 + right_hand_up = right_hand_up_dot >= 0.5 + + re7.wants_block = left_hand_up and right_hand_up + + --log.info("left hand dot: " .. tostring(left_hand_dot)) + --log.info("right hand dot: " .. tostring(right_hand_dot)) +end + +local should_reset_view_no_player = false + +re.on_pre_application_entry("UpdateBehavior", function() + check_player_hands_up() + + if not re7.player then + if should_reset_view_no_player then + vrmod:recenter_view() + vrmod:set_gui_rotation_offset(Quaternion.identity()) + should_reset_view_no_player = false + end + else + should_reset_view_no_player = true + end +end) + +re.on_pre_application_entry("PrepareRendering", function() + update_hand_ik() +end) + +re.on_application_entry("UpdateMotion", function() + --[[local camera = sdk.get_primary_camera() + + -- apply the camera rot to the real camera + local camera_gameobject = camera:call("get_GameObject") + local camera_transform = camera_gameobject:call("get_Transform") + + local camera_rot = camera_transform:call("get_Rotation") + local camera_pos = camera_transform:call("get_Position") + + local camera_rot_pre_hmd = Quaternion.new(camera_rot.w, camera_rot.x, camera_rot.y, camera_rot.z) + + vrmod:apply_hmd_transform(neg_forward_identity * camera_rot, camera_pos) + + update_body_ik(camera_rot_pre_hmd, camera_pos)]] + + update_hand_ik() +end) + +--[[re.on_pre_application_entry("LateUpdateBehavior", function() + update_hand_ik() +end)]] + +re.on_application_entry("LateUpdateBehavior", function() + update_hand_ik() +end) + +re.on_application_entry("UpdateHID", function() + --[[local padman = sdk.get_managed_singleton(sdk.game_namespace("PadManager")) + + if padman then + update_padman(padman) + end]] +end) + +re.on_application_entry("LockScene", function() + --[[if not vrmod:is_hmd_active() then return end + local camera = sdk.get_primary_camera() + + if camera ~= nil and last_real_camera_joint_rotation ~= nil then + local camera_gameobject = camera:call("get_GameObject") + local camera_transform = camera_gameobject:call("get_Transform") + local camera_joint = camera_transform:call("get_Joints")[0] + + joint_set_position:call(camera_joint, last_real_camera_joint_pos) + joint_set_rotation:call(camera_joint, last_real_camera_joint_rotation) + end]] +end) + +re.on_pre_application_entry("UnlockScene", function() + if not vrmod:is_hmd_active() then return end + if not re7.transform then return end + if not last_camera_matrix then return end + if re7.is_in_cutscene then return end + + local standing_origin = vrmod:get_standing_origin() + local hmd_pos = vrmod:get_position(0) + + hmd_pos.y = 0.0 + standing_origin.y = 0.0 + + if (hmd_pos - standing_origin):length() >= 0.01 then + standing_origin = vrmod:get_standing_origin() + hmd_pos.y = standing_origin.y + + local old_standing_origin = Vector4f.new(standing_origin.x, standing_origin.y, standing_origin.z, standing_origin.w) + + standing_origin = standing_origin:lerp(hmd_pos, (hmd_pos - standing_origin):length() * 0.1) + + local standing_diff = standing_origin - old_standing_origin + + vrmod:set_standing_origin(standing_origin) + + local player_pos = transform_get_position:call(re7.transform) + local lerp_to = Vector3f.new(last_camera_matrix[3].x, player_pos.y, last_camera_matrix[3].z) + + player_pos = player_pos + ((lerp_to - player_pos):normalized() * standing_diff:length()) + --player_pos:lerp(lerp_to, 0.1) + --player_pos.x = last_camera_matrix[3].x + --player_pos.z = last_camera_matrix[3].z + + --transform_set_position:call(re7.transform, player_pos) + re7.transform:set_position(player_pos, true) -- NO DIRTY + end +end) + +re.on_application_entry("BeginRendering", function() + if not vrmod:is_hmd_active() then return end + local camera = sdk.get_primary_camera() + + if camera ~= nil then + --local camera_gameobject = camera:call("get_GameObject") + --[[local camera_transform = camera_gameobject:call("get_Transform") + local camera_joint = camera_transform:call("get_Joints")[0] + + last_camera_matrix = joint_get_rotation:call(camera_joint):to_mat4() + last_camera_matrix[3] = joint_get_position:call(camera_joint)]] + + last_camera_matrix = camera:call("get_WorldMatrix") + end +end) + +re.on_config_save(function() + json.dump_file(cfg_path, cfg) +end) + +local type_to_table = function(obj) +end + +local function obj_to_table(obj, seen_objects) + seen_objects = seen_objects or {} + + if obj == nil or seen_objects[obj] ~= nil and seen_objects[obj] > 0 then + return { __null = true } + end + + if tostring(type(obj)) ~= "userdata" then + --log.debug(tostring(obj)) + return obj + end + + local out = {} + + local readable_type_name = tostring(getmetatable(obj).__name) + + --log.debug(readable_type_name) + + if readable_type_name:find("glm::mat<4,4") then + out = { + { x = obj[0][0], y = obj[0][1], z = obj[0][2], w = obj[0][3]}, + { x = obj[1][0], y = obj[1][1], z = obj[1][2], w = obj[1][3]}, + { x = obj[2][0], y = obj[2][1], z = obj[2][2], w = obj[2][3]}, + { x = obj[3][0], y = obj[3][1], z = obj[3][2], w = obj[3][3]}, + } + + return out + elseif readable_type_name:find("glm::vec<4") or readable_type_name:find("glm::qua<") then + out = { + x = obj.x, + y = obj.y, + z = obj.z, + w = obj.w + } + + return out + elseif readable_type_name:find("glm::vec<3") then + out = { + x = obj.x, + y = obj.y, + z = obj.z + } + + return out + elseif readable_type_name:find("glm::vec<2") then + out = { + x = obj.x, + y = obj.y + } + + return out + end + + if seen_objects[obj] ~= nil then + seen_objects[obj] = seen_objects[obj] + 1 + else + seen_objects[obj] = 1 + end + + if getmetatable(obj).get_type_definition == nil then + out = { __REFRAMEWORK_UNIMPLEMENTED_TYPE = getmetatable(obj).__name } + + return out + end + + out["__type"] = obj:get_type_definition():get_full_name() + + if obj:get_type_definition():is_a("via.GameObject") then + local components = obj:call("get_Components") + components = components and components:get_elements() or {} + + out["__components"] = { __num = #components } + + for i, component in ipairs(components) do + out["__components"][tostring(i)] = obj_to_table(component, seen_objects) + end + end + + --log.debug(tostring(type(obj))) + --log.debug(tostring(obj) .. ": " .. tostring(getmetatable(obj).__name)) + local fields = obj:get_type_definition():get_fields() + + for i, field in ipairs(fields) do + if not field:is_static() then + local field_type = field:get_type() + --log.debug("field: " .. field:get_name() .. " " .. field_type:get_full_name()) + local ok, value = pcall(obj.get_field, obj, field:get_name()) + + --log.debug(" " .. tostring(ok)) + + if not ok then + log.debug("error on field: " .. obj:get_type_definition():get_full_name() .. "." .. field:get_name()) + end + + if not ok then goto continue end + + --log.debug(field:get_name()) + local type_definition = nil + + if value ~= nil and tostring(type(value)) == "userdata" and getmetatable(value).get_type_definition ~= nil then + type_definition = value:get_type_definition() + end + + if type_definition and type_definition:is_array() and tostring(type(value)) == "userdata" then + local array = {} + local array_elems = value ~= nil and value:get_elements() or {} + + for i, elem in ipairs(array_elems) do + --array[i] = obj_to_table(elem) + end + + out[field:get_name()] = array + elseif field_type:is_primitive() or field_type:is_enum() then + --out[field:get_name()] = value + elseif not field_type:is_value_type() then + if tostring(type(value)) == "userdata" then + --log.debug(tostring(value) .. ": " .. tostring(getmetatable(value).__name)) + out[field:get_name()] = obj_to_table(value, seen_objects) + else + --out[field:get_name()] = value + end + else -- value type + --out[field:get_name()] = obj_to_table(value, seen_objects) + end + + ::continue:: + end + end + + seen_objects[obj] = seen_objects[obj] - 1 + + return out +end + +--[[local tbl = obj_to_table(__object_explorer_object) +json.dump_file("object_explorer/" .. __object_explorer_object_path .. ".json", tbl) + +collectgarbage("collect")]] -- force a GC to free up the memory + +re.on_draw_ui(function() + local changed = false + + changed, cfg.movement_shake = imgui.checkbox("Movement Shake", cfg.movement_shake) + changed, cfg.all_camera_shake = imgui.checkbox("All Other Camera Shakes", cfg.all_camera_shake) + + changed, left_hand_rotation_vec = imgui.drag_float3("Left Hand Rotation Offset", left_hand_rotation_vec, 0.005, -5.0, 5.0) + + if changed then + left_hand_rotation_offset = Quaternion.new(left_hand_rotation_vec):normalized() + end + + changed, right_hand_rotation_vec = imgui.drag_float3("Right Hand Rotation Offset", right_hand_rotation_vec, 0.005, -5.0, 5.0) + + if changed then + right_hand_rotation_offset = Quaternion.new(right_hand_rotation_vec):normalized() + end + + changed, left_hand_position_offset = imgui.drag_float4("Left Hand Position Offset", left_hand_position_offset, 0.005, -5.0, 5.0) + changed, right_hand_position_offset = imgui.drag_float4("Right Hand Position Offset", right_hand_position_offset, 0.005, -5.0, 5.0) + + if imgui.tree_node("Debug") then + imgui.text("Last GUI Dot: " .. tostring(last_gui_dot)) + end + + if imgui.tree_node("Right Hand IK") then + local right_hand_ik = re7.right_hand_ik + + object_explorer:handle_address(right_hand_ik) + + imgui.tree_pop() + end + + if imgui.tree_node("Left Hand IK") then + local left_hand_ik = re7.left_hand_ik + + object_explorer:handle_address(left_hand_ik) + + imgui.tree_pop() + end + + if imgui.button("test dump") then + local d = function(name) + local obj = sdk.get_managed_singleton(name) + + if obj then + local tbl2 = obj_to_table(obj, {}) + json.dump_file("object_explorer/" .. obj:get_type_definition():get_full_name() .. ".json", tbl2) + end + end + + --d("app.VrGuiManager") + --d("app.vr.VrManager") + --d("app.GameManager") + d("app.ObjectManager") + end +end) + +re.on_pre_gui_draw_element(function(element, context) + if not vrmod:is_hmd_active() then return true end + + local game_object = element:call("get_GameObject") + if game_object == nil then return true end + + local name = game_object:call("get_Name") + + --log.info("drawing element: " .. name) + + if name == "ReticleGUI" then + if vrmod:is_using_controllers() then + return false + end + end + + return true +end) \ No newline at end of file diff --git a/scripts/utility/RE7.lua b/scripts/utility/RE7.lua new file mode 100644 index 000000000..ecc215b94 --- /dev/null +++ b/scripts/utility/RE7.lua @@ -0,0 +1,122 @@ +if _RE7Lib ~= nil then + return _RE7Lib +end + +local RE7 = { + player = nil, + transform = nil, + weapon = nil, + weapon_gameobject = nil, + inventory = nil, + hand_touch = nil, + right_hand_ik = nil, + left_hand_ik = nil, + is_in_cutscene = false, + game_event_action_controller = nil, + wants_block = false, +} + +local known_typeofs = {} + +local function get_component(game_object, type_name) + local t = known_typeofs[type_name] or sdk.typeof(type_name) + + if t == nil then + return nil + end + + known_typeofs[type_name] = t + return game_object:call("getComponent(System.Type)", t) +end + +function RE7.get_localplayer() + local object_man = sdk.get_managed_singleton("app.ObjectManager") + + if not object_man then + return nil + end + + return object_man:get_field("PlayerObj") +end + +function RE7.get_weapon_object(player) + return nil, nil +end + +re.on_pre_application_entry("UpdateBehavior", function() + RE7.player = RE7.get_localplayer() + local player = RE7.player + + if player == nil then + RE7.weapon = nil + RE7.weapon_gameobject = nil + return + end + + RE7.transform = player:call("get_Transform") + RE7.inventory = get_component(player, "app.Inventory") + RE7.hand_touch = get_component(player, "app.PlayerHandTouch") + RE7.game_event_action_controller = get_component(player, "app.GameEventActionController") + + if RE7.hand_touch == nil then + re7.right_hand_ik = nil + re7.left_hand_ik = nil + else + local hand_ik = RE7.hand_touch:get_field("HandIK"):get_elements() + + if #hand_ik < 2 then + log.info("no hand ik") + RE7.right_hand_ik = nil + RE7.left_hand_ik = nil + else + --log.info("IK: " .. tostring(hand_ik)) + + RE7.right_hand_ik = hand_ik[1] + RE7.left_hand_ik = hand_ik[2] + + if RE7.right_hand_ik and RE7.left_hand_ik then + RE7.right_hand_ik_object = RE7.right_hand_ik:get_field("TargetGameObject") + RE7.left_hand_ik_object = RE7.left_hand_ik:get_field("TargetGameObject") + RE7.right_hand_ik_transform = RE7.right_hand_ik:get_field("Target") + RE7.left_hand_ik_transform = RE7.left_hand_ik:get_field("Target") + end + + RE7.is_in_cutscene = false + end + end + + RE7.event_action_controller = get_component(player, "app.EventActionController") + + if RE7.event_action_controller ~= nil then + local current_task = RE7.event_action_controller:get_field("CurrentTask") + + if current_task ~= nil then + RE7.is_in_cutscene = true + else + RE7.is_in_cutscene = false + end + else + RE7.is_in_cutscene = false + end + + if RE7.inventory == nil then + RE7.weapon = nil + RE7.weapon_gameobject = nil + return + end + + local weapon_gameobject, weapon = RE7.get_weapon_object(player) + + if weapon_gameobject == nil or weapon == nil then + RE7.weapon = nil + RE7.weapon_gameobject = nil + return + end + + RE7.weapon = weapon + RE7.weapon_gameobject = weapon_gameobject +end) + +_RE7Lib = RE7 + +return RE7 \ No newline at end of file From 8f3efe12274f256d24055cbc53d3c98f32bf7ade Mon Sep 17 00:00:00 2001 From: praydog Date: Wed, 2 Mar 2022 11:55:36 -0800 Subject: [PATCH 02/45] VR: RE7 script improvements (mainly cutscene jank) --- scripts/re7_vr.lua | 232 +++++++++++++++++++++++++++------------ scripts/utility/RE7.lua | 237 +++++++++++++++++++++++++++++++++------- 2 files changed, 358 insertions(+), 111 deletions(-) diff --git a/scripts/re7_vr.lua b/scripts/re7_vr.lua index 10dd2673b..b7a7507b1 100644 --- a/scripts/re7_vr.lua +++ b/scripts/re7_vr.lua @@ -12,12 +12,12 @@ local last_right_hand_rotation = Quaternion.new(0.0, 0.0, 0.0, 0.0) local last_right_hand_position = Vector3f.new(0.0, 0.0, 0.0) local last_left_hand_rotation = Quaternion.new(0.0, 0.0, 0.0, 0.0) local last_left_hand_position = Vector3f.new(0.0, 0.0, 0.0) -local left_hand_rotation_vec = Vector3f.new(-0.105 + 0.2, 2.43, 1.16) -- pitch yaw roll? -local right_hand_rotation_vec = Vector3f.new(-0.105, -2.43, -1.16) -- pitch yaw roll? +local left_hand_rotation_vec = Vector3f.new(-0.105 + 0.2, 2.28, 1.08) -- pitch yaw roll? +local right_hand_rotation_vec = Vector3f.new(-0.105, -2.28, -1.08) -- pitch yaw roll? local left_hand_rotation_offset = Quaternion.new(left_hand_rotation_vec):normalized() local right_hand_rotation_offset = Quaternion.new(right_hand_rotation_vec):normalized() -local left_hand_position_offset = Vector4f.new(-0.025, 0.075, 0.155, 0.0) -local right_hand_position_offset = Vector4f.new(0.025, 0.075, 0.155, 0.0) +local left_hand_position_offset = Vector4f.new(-0.025, 0.045, 0.155, 0.0) +local right_hand_position_offset = Vector4f.new(0.025, 0.045, 0.155, 0.0) local ray_typedef = sdk.find_type_definition("via.Ray") @@ -37,6 +37,8 @@ local gameobject_get_transform = sdk.find_type_definition("via.GameObject"):get_ local cfg_path = "re7_vr/main_config.json" +local queue_recenter = false + local cfg = { movement_shake = false, all_camera_shake = true @@ -389,7 +391,8 @@ local function update_hand_ik() return end - if re7.is_in_cutscene then return end + --if re7.is_in_cutscene then return end + if re7.is_arm_jacked then return end local left_controller_transform = vrmod:get_transform(controllers[1]) local right_controller_transform = vrmod:get_transform(controllers[2]) @@ -458,6 +461,11 @@ local neg_forward_identity = Matrix4x4f.new(-1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 1):to_quat() +local neg_identity = Matrix4x4f.new(-1, 0, 0, 0, + 0, -1, 0, 0, + 0, 0, -1, 0, + 0, 0, 0, -1):to_quat() + local head_hash = nil local center_hash = nil local chest_hash = nil @@ -711,20 +719,27 @@ local function fix_player_camera(player_camera) return retval end + local camera = sdk.get_primary_camera() + + -- apply the camera rot to the real camera + local camera_gameobject = camera:call("get_GameObject") + local camera_transform = camera_gameobject:call("get_Transform") + + local did_recenter = false + if re7.is_in_cutscene and needs_cutscene_recenter then - vrmod:set_gui_rotation_offset(Quaternion.identity()) - vrmod:recenter_view() + --vrmod:recenter_view() -- force the gui to be recentered when we exit the cutscene last_gui_forced_slerp = os.clock() + last_gui_quat = Quaternion.identity() needs_cutscene_recenter = false - end + did_recenter = true + queue_recenter = true - local camera = sdk.get_primary_camera() + vrmod:recenter_gui(last_gui_quat) + end - -- apply the camera rot to the real camera - local camera_gameobject = camera:call("get_GameObject") - local camera_transform = camera_gameobject:call("get_Transform") --last_real_camera_rotation = camera_transform:call("get_Rotation") --last_real_camera_joint_rotation = camera_transform:call("get_Joints")[0]:call("get_Rotation") @@ -744,7 +759,7 @@ local function fix_player_camera(player_camera) --local camera_rot = (forward * -1.0):to_quat() vrmod:apply_hmd_transform(camera_rot, camera_pos) - + --local neg_camera_rot = (neg_forward_identity * camera_rot):normalized() local camera_joint = camera_transform:call("get_Joints")[0] @@ -761,8 +776,13 @@ local function fix_player_camera(player_camera) --joint_set_rotation:call(camera_joint, neg_camera_rot) -- Joint is used for the actual final rendering of the game world - joint_set_position:call(camera_joint, camera_pos_pre_hmd) - joint_set_rotation:call(camera_joint, camera_rot_pre_hmd) + if not did_recenter then + joint_set_position:call(camera_joint, camera_pos_pre_hmd) + joint_set_rotation:call(camera_joint, camera_rot_pre_hmd) + else + joint_set_position:call(camera_joint, camera_pos_pre_hmd) + joint_set_rotation:call(camera_joint, camera_rot_pre_hmd) + end -- just update the body IK right after we update the camera. update_body_ik(camera_rot_pre_hmd, camera_pos) @@ -778,7 +798,7 @@ local function fix_player_camera(player_camera) local now = os.clock() -- trigger gui slerp - if dot_ang >= 20 then + if dot_ang >= 20 or did_recenter then last_gui_forced_slerp = os.clock() end @@ -790,28 +810,28 @@ local function fix_player_camera(player_camera) end last_gui_quat = last_gui_quat:slerp(new_gui_quat, dot_dist * math.max((1.5 - slerp_time_diff), 0.0)) + vrmod:recenter_gui(last_gui_quat) end needs_cutscene_recenter = true end - - --[[local fixed_dir = camera_rot * Vector3f.new(0, 0, 1) - fixed_dir.y = fixed_dir.y * -1.0 - fixed_dir:normalize() - local fixed_rot = fixed_dir:to_quat()]] + local fixed_dir = camera_rot * Vector3f.new(0, 0, -1) local fixed_rot = neg_forward_identity * camera_rot - local fixed_dir = fixed_rot * Vector3f.new(0, 0, 1) player_camera:set_field("k__BackingField", fixed_rot) player_camera:set_field("k__BackingField", camera_pos) player_camera:set_field("CameraRotationWithMovementShake", fixed_rot) - player_camera:set_field("CameraPositionWithMovementShake", camera_pos) + --player_camera:set_field("CameraPositionWithMovementShake", camera_pos) player_camera:set_field("CameraRotationWithCameraShake", fixed_rot) - player_camera:set_field("CameraPositionWithCameraShake", camera_pos) + --player_camera:set_field("CameraPositionWithCameraShake", camera_pos) player_camera:set_field("PrevCameraRotation", fixed_rot) + --player_camera:set_field("OldCameraRotation", fixed_rot) + --player_camera:set_field("InterpRotationStart", fixed_rot) + --player_camera:set_field("k__BackingField", fixed_rot) + --player_camera:set_field("k__BackingField", fixed_rot) local camera_controller_param = player_camera:get_field("CameraCtrlParam") @@ -827,12 +847,32 @@ local function fix_player_camera(player_camera) -- Stop the player from rotating the camera vertically if camera_controller then local camera_controller_rot = camera_controller:get_field("k__BackingField") - local controller_forward = camera_controller_rot * Vector3f.new(0.0, 0.0, 1.0) - controller_forward.y = 0.0 - controller_forward:normalize() - camera_controller_rot = controller_forward:to_quat() - base_transform_solver:set_field("k__BackingField", camera_controller_rot) - camera_controller:set_field("k__BackingField", camera_controller_rot) + + if did_recenter then + camera_controller_rot = Quaternion.new(fixed_rot.w, fixed_rot.x, fixed_rot.y, fixed_rot.z) + --vrmod:recenter_view() + end + + if did_recenter or not re7.is_in_cutscene then + local controller_forward = camera_controller_rot * Vector3f.new(0.0, 0.0, 1.0) + + --if not did_recenter then + controller_forward.y = 0.0 + --end + + camera_controller_rot = controller_forward:normalized():to_quat():normalized() + + base_transform_solver:set_field("k__BackingField", camera_controller_rot) + camera_controller:set_field("k__BackingField", camera_controller_rot) + end + + + if did_recenter then + --player_camera:call("lateUpdate") + base_transform_solver:call("update") + camera_controller:call("updateOperatedCameraAngle") + end + camera_controller:set_field("IsVerticalRotateLimited", true) was_vert_limited = true end @@ -840,7 +880,7 @@ local function fix_player_camera(player_camera) -- stops the camera from pivoting around the player -- so we can use VR to look around without the body sticking out - if vrmod:is_using_controllers() then + --if vrmod:is_using_controllers() then local param_container = player_camera:get_field("_CurrentParamContainer") if param_container ~= nil then @@ -854,7 +894,7 @@ local function fix_player_camera(player_camera) posture_param:set_field("CameraOffset", current_camera_offset) end end - end + --end local look_ray_offset = player_camera:get_type_definition():get_field("LookRay"):get_offset_from_base() local shoot_ray_offset = player_camera:get_type_definition():get_field("ShootRay"):get_offset_from_base() @@ -868,14 +908,10 @@ local function fix_player_camera(player_camera) sdk.set_native_field(sdk.to_ptr(look_ray), ray_typedef, "dir", fixed_dir) sdk.set_native_field(sdk.to_ptr(shoot_ray), ray_typedef, "from", camera_pos) sdk.set_native_field(sdk.to_ptr(shoot_ray), ray_typedef, "dir", fixed_dir) - --look_ray:set_field("from", camera_pos) - --look_ray:set_field("dir", new_dir) - --player_camera:set_field("LookRay", look_ray) - - --look_ray:set_field("from", new_pos) - --look_ray:set_field("dir", new_dir) - --player_camera:set_field("ShootRay", look_ray) + if did_recenter then + player_camera:call("lateUpdate") + end end local function on_pre_player_camera_update(args) @@ -908,6 +944,47 @@ local function on_post_player_camera_update(retval) return retval end +local function on_pre_player_interp_rotation(args) + local player_camera = sdk.to_managed_object(args[2]) + + local camera = sdk.get_primary_camera() + local camera_gameobject = camera:call("get_GameObject") + local camera_transform = camera_gameobject:call("get_Transform") + + --[[if re7.is_in_cutscene and needs_cutscene_recenter then + vrmod:set_gui_rotation_offset(Quaternion.identity()) + vrmod:recenter_view() + + transform_set_rotation:call(camera_transform, last_camera_matrix:to_quat()) + + local camera_joint = camera_transform:call("get_Joints")[0] + + joint_set_rotation:call(camera_joint, last_camera_matrix:to_quat()) + + -- force the gui to be recentered when we exit the cutscene + last_gui_forced_slerp = os.clock() + needs_cutscene_recenter = false + end]] + + re7.is_in_cutscene = true + needs_cutscene_recenter = true + + if needs_cutscene_recenter then + fix_player_camera(player_camera) + end +end + +local function on_post_player_interp_rotation(retval) + return retval +end + +-- Normal Ethan camera +--[[sdk.hook( + sdk.find_type_definition("app.PlayerCamera"):get_method("interpRotation"), + on_pre_player_interp_rotation, + on_post_player_interp_rotation +)]] + -- Normal Ethan camera sdk.hook( sdk.find_type_definition("app.PlayerCamera"):get_method("lateUpdate"), @@ -1119,11 +1196,20 @@ re.on_application_entry("LockScene", function() end]] end) +local last_roomscale_failure = os.clock() + re.on_pre_application_entry("UnlockScene", function() - if not vrmod:is_hmd_active() then return end - if not re7.transform then return end - if not last_camera_matrix then return end - if re7.is_in_cutscene then return end + if queue_recenter then + vrmod:recenter_view() + queue_recenter = false + end + + if not vrmod:is_hmd_active() then last_roomscale_failure = os.clock() return end + if not re7.player or not re7.transform then last_roomscale_failure = os.clock() return end + if not last_camera_matrix then last_roomscale_failure = os.clock() return end + if re7.is_in_cutscene then last_roomscale_failure = os.clock() return end + + if os.clock() - last_roomscale_failure < 1.0 then return end local standing_origin = vrmod:get_standing_origin() local hmd_pos = vrmod:get_position(0) @@ -1341,38 +1427,46 @@ re.on_draw_ui(function() if imgui.tree_node("Debug") then imgui.text("Last GUI Dot: " .. tostring(last_gui_dot)) - end - - if imgui.tree_node("Right Hand IK") then - local right_hand_ik = re7.right_hand_ik - - object_explorer:handle_address(right_hand_ik) - - imgui.tree_pop() - end - if imgui.tree_node("Left Hand IK") then - local left_hand_ik = re7.left_hand_ik + if imgui.tree_node("Player") then + object_explorer:handle_address(re7.player) - object_explorer:handle_address(left_hand_ik) - - imgui.tree_pop() - end - - if imgui.button("test dump") then - local d = function(name) - local obj = sdk.get_managed_singleton(name) + imgui.tree_pop() + end - if obj then - local tbl2 = obj_to_table(obj, {}) - json.dump_file("object_explorer/" .. obj:get_type_definition():get_full_name() .. ".json", tbl2) + if imgui.tree_node("Right Hand IK") then + local right_hand_ik = re7.right_hand_ik + + object_explorer:handle_address(right_hand_ik) + + imgui.tree_pop() + end + + if imgui.tree_node("Left Hand IK") then + local left_hand_ik = re7.left_hand_ik + + object_explorer:handle_address(left_hand_ik) + + imgui.tree_pop() + end + + if imgui.button("test dump") then + local d = function(name) + local obj = sdk.get_managed_singleton(name) + + if obj then + local tbl2 = obj_to_table(obj, {}) + json.dump_file("object_explorer/" .. obj:get_type_definition():get_full_name() .. ".json", tbl2) + end end + + --d("app.VrGuiManager") + --d("app.vr.VrManager") + --d("app.GameManager") + d("app.ObjectManager") end - --d("app.VrGuiManager") - --d("app.vr.VrManager") - --d("app.GameManager") - d("app.ObjectManager") + imgui.tree_pop() end end) diff --git a/scripts/utility/RE7.lua b/scripts/utility/RE7.lua index ecc215b94..ee7ac63e2 100644 --- a/scripts/utility/RE7.lua +++ b/scripts/utility/RE7.lua @@ -1,8 +1,55 @@ -if _RE7Lib ~= nil then - return _RE7Lib +if _re7lib ~= nil then + return _re7lib end -local RE7 = { +local CallbackList = { + callbacks = {}, + + new = function(self, o) + o = o or {} + + self.__index = self + return setmetatable(o, self) + end, + + add = function(self, callback) + table.insert(self.callbacks, callback) + end, + + dispatch = function(self, args) + for i, callback in ipairs(self.callbacks) do + callback(args) + end + end +} + +local CallbackManager = { + callback_lists = {}, + + new = function(self, o) + o = o or {} + + return setmetatable(o, self) + end, + + __index = function(self, key) + local rawval = rawget(self, key) or rawget(getmetatable(self), key) + + if rawval ~= nil then + return rawval + end + + if not self.callback_lists[key] then + self.callback_lists[key] = CallbackList:new() + end + + return self.callback_lists[key] + end, +} + +local callbacks = CallbackManager:new() + +local re7 = { player = nil, transform = nil, weapon = nil, @@ -12,8 +59,11 @@ local RE7 = { right_hand_ik = nil, left_hand_ik = nil, is_in_cutscene = false, - game_event_action_controller = nil, + is_arm_jacked = false, + event_action_controller = nil, wants_block = false, + num_active_tasks = 0, + active_tasks = {} } local known_typeofs = {} @@ -29,7 +79,7 @@ local function get_component(game_object, type_name) return game_object:call("getComponent(System.Type)", t) end -function RE7.get_localplayer() +function re7.get_localplayer() local object_man = sdk.get_managed_singleton("app.ObjectManager") if not object_man then @@ -39,84 +89,187 @@ function RE7.get_localplayer() return object_man:get_field("PlayerObj") end -function RE7.get_weapon_object(player) +function re7.get_weapon_object(player) return nil, nil end re.on_pre_application_entry("UpdateBehavior", function() - RE7.player = RE7.get_localplayer() - local player = RE7.player + re7.player = re7.get_localplayer() + local player = re7.player if player == nil then - RE7.weapon = nil - RE7.weapon_gameobject = nil + re7.weapon = nil + re7.weapon_gameobject = nil + re7.event_action_controller = nil + re7.is_in_cutscene = false + re7.num_active_tasks = 0 + re7.active_tasks = {} return end - RE7.transform = player:call("get_Transform") - RE7.inventory = get_component(player, "app.Inventory") - RE7.hand_touch = get_component(player, "app.PlayerHandTouch") - RE7.game_event_action_controller = get_component(player, "app.GameEventActionController") + re7.transform = player:call("get_Transform") + re7.inventory = get_component(player, "app.Inventory") + re7.hand_touch = get_component(player, "app.PlayerHandTouch") - if RE7.hand_touch == nil then + if re7.hand_touch == nil then re7.right_hand_ik = nil re7.left_hand_ik = nil else - local hand_ik = RE7.hand_touch:get_field("HandIK"):get_elements() + local hand_ik = re7.hand_touch:get_field("HandIK"):get_elements() if #hand_ik < 2 then log.info("no hand ik") - RE7.right_hand_ik = nil - RE7.left_hand_ik = nil + re7.right_hand_ik = nil + re7.left_hand_ik = nil else --log.info("IK: " .. tostring(hand_ik)) - RE7.right_hand_ik = hand_ik[1] - RE7.left_hand_ik = hand_ik[2] + re7.right_hand_ik = hand_ik[1] + re7.left_hand_ik = hand_ik[2] - if RE7.right_hand_ik and RE7.left_hand_ik then - RE7.right_hand_ik_object = RE7.right_hand_ik:get_field("TargetGameObject") - RE7.left_hand_ik_object = RE7.left_hand_ik:get_field("TargetGameObject") - RE7.right_hand_ik_transform = RE7.right_hand_ik:get_field("Target") - RE7.left_hand_ik_transform = RE7.left_hand_ik:get_field("Target") + if re7.right_hand_ik and re7.left_hand_ik then + re7.right_hand_ik_object = re7.right_hand_ik:get_field("TargetGameObject") + re7.left_hand_ik_object = re7.left_hand_ik:get_field("TargetGameObject") + re7.right_hand_ik_transform = re7.right_hand_ik:get_field("Target") + re7.left_hand_ik_transform = re7.left_hand_ik:get_field("Target") end - RE7.is_in_cutscene = false + --re7.is_in_cutscene = false end end - RE7.event_action_controller = get_component(player, "app.EventActionController") + re7.event_action_controller = get_component(player, "app.EventActionController") - if RE7.event_action_controller ~= nil then - local current_task = RE7.event_action_controller:get_field("CurrentTask") + if re7.event_action_controller ~= nil then + local current_task = re7.event_action_controller:get_field("CurrentTask") if current_task ~= nil then - RE7.is_in_cutscene = true + --re7.is_in_cutscene = true else - RE7.is_in_cutscene = false + --re7.is_in_cutscene = false end else - RE7.is_in_cutscene = false + re7.is_in_cutscene = false end - if RE7.inventory == nil then - RE7.weapon = nil - RE7.weapon_gameobject = nil + if re7.inventory == nil then + re7.weapon = nil + re7.weapon_gameobject = nil return end - local weapon_gameobject, weapon = RE7.get_weapon_object(player) + local weapon_gameobject, weapon = re7.get_weapon_object(player) if weapon_gameobject == nil or weapon == nil then - RE7.weapon = nil - RE7.weapon_gameobject = nil + re7.weapon = nil + re7.weapon_gameobject = nil return end - RE7.weapon = weapon - RE7.weapon_gameobject = weapon_gameobject + re7.weapon = weapon + re7.weapon_gameobject = weapon_gameobject end) -_RE7Lib = RE7 +local event_action_controller_type = sdk.find_type_definition("app.EventActionController") +local request_task_method = event_action_controller_type:get_method("requestTask") + +local function on_pre_event_request_task(args) + if re7.event_action_controller == nil or sdk.to_ptr(args[2]) == nil or sdk.to_int64(args[2]) ~= re7.event_action_controller:get_address() then + return sdk.PreHookResult.CALL_ORIGINAL + end + + local controller = sdk.to_managed_object(args[2]) + local task = sdk.to_managed_object(args[3]) + + if task == nil then + log.debug("No task!") + return sdk.PreHookResult.CALL_ORIGINAL + end + + if not re7.active_tasks[task] then + re7.num_active_tasks = re7.num_active_tasks + 1 + end + + re7.is_in_cutscene = true + re7.active_tasks[task] = true + + callbacks["event_task_create"]:dispatch(args) +end + +local function on_post_event_request_task(retval) + return retval +end + +sdk.hook(request_task_method, on_pre_event_request_task, on_post_event_request_task) + +local event_action_task_type = sdk.find_type_definition("app.EventActionTask") +local terminate_method = event_action_task_type:get_method("terminate") + +local function on_pre_task_terminate(args) + local task = sdk.to_managed_object(args[2]) + + if task == nil or not re7.active_tasks[task] then + return + end + + if re7.active_tasks[task] then + re7.num_active_tasks = re7.num_active_tasks - 1 + re7.active_tasks[task] = nil + end + + if re7.num_active_tasks < 0 then + re7.num_active_tasks = 0 + end + + re7.is_in_cutscene = re7.num_active_tasks > 0 or not re7.has_postural_camera_control or re7.is_arm_jacked + + callbacks["event_task_terminate"]:dispatch(args) +end + +local function on_post_task_terminate(retval) + return retval +end + +sdk.hook(terminate_method, on_pre_task_terminate, on_post_task_terminate) + +local player_motion_controller_type = sdk.find_type_definition("app.PlayerMotionController") +local update_postural_camera_motion_method = player_motion_controller_type:get_method("updatePosturalCameraMotion") +local ch8_player_motion_controller_type = sdk.find_type_definition("app.CH8PlayerMotionController") +local ch8_update_postural_camera_motion_method = ch8_player_motion_controller_type:get_method("updatePosturalCameraMotion") + +local postural_camera_motion_args = nil + +local function on_pre_update_postural_camera_motion(args) + postural_camera_motion_args = args +end + +local function on_post_update_postural_camera_motion(retval) + local args = postural_camera_motion_args + local controller = sdk.to_managed_object(args[2]) + local game_object = controller:call("get_GameObject") + + if game_object ~= re7.player then + return retval + end + + re7.is_arm_jacked = controller:get_field("IsRArmJacked") + re7.has_postural_camera_control = controller:get_field("IsPosturalCameraControl") + re7.is_in_cutscene = re7.num_active_tasks > 0 or not re7.has_postural_camera_control or re7.is_arm_jacked + + return retval +end + +sdk.hook(update_postural_camera_motion_method, on_pre_update_postural_camera_motion, on_post_update_postural_camera_motion) +sdk.hook(ch8_update_postural_camera_motion_method, on_pre_update_postural_camera_motion, on_post_update_postural_camera_motion) + +function re7.notify_event_task_created(callback) + callbacks["event_task_create"]:add(callback) +end + +function re7.notify_event_task_terminated(callback) + callbacks["event_task_terminate"]:add(callback) +end + +_re7lib = re7 -return RE7 \ No newline at end of file +return re7 \ No newline at end of file From 17fe5a59327970a03e3f5fb3c1af41c027b208df Mon Sep 17 00:00:00 2001 From: praydog Date: Sat, 5 Mar 2022 10:58:51 -0800 Subject: [PATCH 03/45] VR: RE7 improvements (GUI/Cutscenes/Camera improvements) --- scripts/re7_vr.lua | 236 +++++++++++++++++++++------------------- scripts/utility/RE7.lua | 86 +++++++++++---- 2 files changed, 190 insertions(+), 132 deletions(-) diff --git a/scripts/re7_vr.lua b/scripts/re7_vr.lua index b7a7507b1..0fe8f9412 100644 --- a/scripts/re7_vr.lua +++ b/scripts/re7_vr.lua @@ -12,8 +12,8 @@ local last_right_hand_rotation = Quaternion.new(0.0, 0.0, 0.0, 0.0) local last_right_hand_position = Vector3f.new(0.0, 0.0, 0.0) local last_left_hand_rotation = Quaternion.new(0.0, 0.0, 0.0, 0.0) local last_left_hand_position = Vector3f.new(0.0, 0.0, 0.0) -local left_hand_rotation_vec = Vector3f.new(-0.105 + 0.2, 2.28, 1.08) -- pitch yaw roll? -local right_hand_rotation_vec = Vector3f.new(-0.105, -2.28, -1.08) -- pitch yaw roll? +local left_hand_rotation_vec = Vector3f.new(-0.105 + 0.2, 2.37, 1.10) -- pitch yaw roll? +local right_hand_rotation_vec = Vector3f.new(-0.105, -2.37, -1.10) -- pitch yaw roll? local left_hand_rotation_offset = Quaternion.new(left_hand_rotation_vec):normalized() local right_hand_rotation_offset = Quaternion.new(right_hand_rotation_vec):normalized() local left_hand_position_offset = Vector4f.new(-0.025, 0.045, 0.155, 0.0) @@ -38,6 +38,13 @@ local gameobject_get_transform = sdk.find_type_definition("via.GameObject"):get_ local cfg_path = "re7_vr/main_config.json" local queue_recenter = false +local was_vert_limited = false + +local last_gui_offset = Quaternion.identity() +local last_gui_quat = Quaternion.identity() +local last_gui_dot = 0.0 +local last_gui_forced_slerp = os.clock() +local needs_cutscene_recenter = false local cfg = { movement_shake = false, @@ -547,8 +554,9 @@ local function update_body_ik(camera_rotation, camera_pos) local transform_rot = transform:call("get_Rotation") local transform_pos = transform:call("get_Position") - --local head_joint = transform:call("getJointByHash", head_hash) + local head_joint = transform:call("getJointByHash", head_hash) --local chest_joint = transform:call("getJointByHash", chest_hash) + local hip_joint = transform:call("getJointByHash", center_hash) local head_index = motion:call("getJointIndexByNameHash", head_hash) --chest_index = motion:call("getJointIndexByNameHash", chest_hash) @@ -556,6 +564,8 @@ local function update_body_ik(camera_rotation, camera_pos) --local original_chest_pos = motion:call("getWorldPosition", chest_index) original_head_pos = transform_rot * original_head_pos + --original_head_pos = transform:call("getJointByName", "root"):call("get_Rotation") * original_head_pos + --original_head_pos = transform_rot * transform:calculate_base_transform(head_joint)[3] --original_chest_pos = transform_rot * original_chest_pos --original_head_pos.x = original_chest_pos.x @@ -663,13 +673,6 @@ sdk.hook( on_post_interact_manager_lateupdate ) -local was_vert_limited = false - -local last_gui_quat = Quaternion.identity() -local last_gui_dot = 0.0 -local last_gui_forced_slerp = os.clock() -local needs_cutscene_recenter = false - -- force the gui to recenter when opening the inventory sdk.hook( sdk.find_type_definition("app.MenuManager"):get_method("openInventoryMenu"), @@ -682,18 +685,57 @@ sdk.hook( ) local last_camera_update_args = nil +local last_cutscene_state = false +local last_time_not_maximum_controllable = 0.0 +local GUI_MAX_SLERP_TIME = 1.5 + +local function slerp_gui(new_gui_quat) + if re7.movement_speed_rate > 0.0 then + last_gui_forced_slerp = os.clock() - ((1.0 - re7.movement_speed_rate)) + end + + last_gui_dot = last_gui_quat:dot(new_gui_quat) + local dot_dist = 1.0 - math.abs(last_gui_dot) + local dot_ang = math.acos(math.abs(last_gui_dot)) * (180.0 / math.pi) + last_gui_dot = dot_ang + + local now = os.clock() + + -- trigger gui slerp + if dot_ang >= 20 or re7.is_in_cutscene then + last_gui_forced_slerp = now + end + + local slerp_time_diff = now - last_gui_forced_slerp + + if slerp_time_diff <= GUI_MAX_SLERP_TIME then + if dot_ang >= 10 then + last_gui_forced_slerp = now + end + + last_gui_quat = last_gui_quat:slerp(new_gui_quat, dot_dist * math.max((GUI_MAX_SLERP_TIME - slerp_time_diff) * re7.delta_time, 0.0)) + end + + if re7.is_in_cutscene then + vrmod:recenter_gui(last_gui_quat) + else + vrmod:recenter_gui(last_gui_quat * new_gui_quat:inverse()) + end +end + +local last_hmd_active_state = false local function fix_player_camera(player_camera) if not vrmod:is_hmd_active() then -- so the camera doesnt go wacky - if needs_cutscene_recenter then + if last_hmd_active_state then -- disables the body IK component update_body_ik(nil, nil) vrmod:set_gui_rotation_offset(Quaternion.identity()) vrmod:recenter_view() - needs_cutscene_recenter = false + last_hmd_active_state = false end -- Restore the vertical camera movement after taking headset off/not using controllers @@ -719,29 +761,48 @@ local function fix_player_camera(player_camera) return retval end + last_hmd_active_state = true + + local base_transform_solver = player_camera:get_field("BaseTransSolver") + local is_maximum_controllable = true + + if base_transform_solver then + if base_transform_solver:get_field("k__BackingField") ~= 0 then -- MaximumOperatable + re7.is_in_cutscene = true + is_maximum_controllable = false + last_time_not_maximum_controllable = os.clock() + else + if os.clock() - last_time_not_maximum_controllable <= 1.0 then + re7.is_in_cutscene = true + end + end + end + local camera = sdk.get_primary_camera() -- apply the camera rot to the real camera local camera_gameobject = camera:call("get_GameObject") local camera_transform = camera_gameobject:call("get_Transform") - local did_recenter = false + local wants_recenter = false - if re7.is_in_cutscene and needs_cutscene_recenter then + if re7.is_in_cutscene and not last_cutscene_state then --vrmod:recenter_view() -- force the gui to be recentered when we exit the cutscene last_gui_forced_slerp = os.clock() last_gui_quat = Quaternion.identity() - needs_cutscene_recenter = false - did_recenter = true - queue_recenter = true + wants_recenter = true + --queue_recenter = true vrmod:recenter_gui(last_gui_quat) - end + elseif not re7.is_in_cutscene and last_cutscene_state then + last_gui_forced_slerp = os.clock() + last_gui_quat = vrmod:get_rotation(0):to_quat():inverse() + wants_recenter = true - --last_real_camera_rotation = camera_transform:call("get_Rotation") - --last_real_camera_joint_rotation = camera_transform:call("get_Joints")[0]:call("get_Rotation") + vrmod:recenter_gui(vrmod:get_rotation(0):to_quat()) + end local camera_rot = transform_get_rotation:call(camera_transform) local camera_pos = transform_get_position:call(camera_transform) @@ -749,19 +810,12 @@ local function fix_player_camera(player_camera) local camera_rot_pre_hmd = Quaternion.new(camera_rot.w, camera_rot.x, camera_rot.y, camera_rot.z) local camera_pos_pre_hmd = Vector3f.new(camera_pos.x, camera_pos.y, camera_pos.z) - --camera_rot = (neg_forward_identity * camera_rot):normalized() - --camera_rot = neg_forward_identity * camera_rot - - --[[local forward = camera_rot * Vector3f.new(0, 0, 1) - forward.y = 0.0 - forward:normalize()]] - - --local camera_rot = (forward * -1.0):to_quat() + -- So the camera doesn't spin uncontrollably when attacking or the camera moves outside of player control. + local camera_rot_no_shake = player_camera:get_field("k__BackingField") + vrmod:apply_hmd_transform(camera_rot_no_shake, Vector3f.new(0, 0, 0)) vrmod:apply_hmd_transform(camera_rot, camera_pos) - --local neg_camera_rot = (neg_forward_identity * camera_rot):normalized() - local camera_joint = camera_transform:call("get_Joints")[0] -- Transform is used for things like Ethan's light @@ -772,53 +826,32 @@ local function fix_player_camera(player_camera) last_real_camera_joint_rotation = camera_rot_pre_hmd last_real_camera_joint_pos = camera_pos_pre_hmd - --joint_set_position:call(camera_joint, camera_pos) - --joint_set_rotation:call(camera_joint, neg_camera_rot) - -- Joint is used for the actual final rendering of the game world - if not did_recenter then + --if not wants_recenter then + if re7.is_in_cutscene then joint_set_position:call(camera_joint, camera_pos_pre_hmd) joint_set_rotation:call(camera_joint, camera_rot_pre_hmd) else + local rot_delta = camera_rot_pre_hmd:inverse() * camera_rot + + local forward = rot_delta * Vector3f.new(0, 0, 1) + forward = Vector3f.new(forward.x, 0.0, forward.z):normalized() + joint_set_position:call(camera_joint, camera_pos_pre_hmd) - joint_set_rotation:call(camera_joint, camera_rot_pre_hmd) + joint_set_rotation:call(camera_joint, camera_rot_pre_hmd * forward:to_quat()) end + --last_gui_offset = last_gui_offset * (camera_rot:inverse() * camera_rot_pre_hmd) + -- just update the body IK right after we update the camera. update_body_ik(camera_rot_pre_hmd, camera_pos) -- Slerp the gui around - if not re7.is_in_cutscene then - local new_gui_quat = camera_rot_pre_hmd * camera_rot:inverse() - last_gui_dot = last_gui_quat:dot(new_gui_quat) - local dot_dist = 1.0 - math.abs(last_gui_dot) - local dot_ang = math.acos(math.abs(last_gui_dot)) * (180.0 / math.pi) - last_gui_dot = dot_ang - - local now = os.clock() - - -- trigger gui slerp - if dot_ang >= 20 or did_recenter then - last_gui_forced_slerp = os.clock() - end + slerp_gui(re7.is_in_cutscene and (camera_rot_pre_hmd * camera_rot:inverse()) or vrmod:get_rotation(0):to_quat():inverse()) - local slerp_time_diff = now - last_gui_forced_slerp - - if slerp_time_diff <= 1.5 then - if dot_ang >= 10 then - last_gui_forced_slerp = now - end - - last_gui_quat = last_gui_quat:slerp(new_gui_quat, dot_dist * math.max((1.5 - slerp_time_diff), 0.0)) - - vrmod:recenter_gui(last_gui_quat) - end - - needs_cutscene_recenter = true - end - - local fixed_dir = camera_rot * Vector3f.new(0, 0, -1) - local fixed_rot = neg_forward_identity * camera_rot + local fixed_dir = ((neg_forward_identity * camera_rot_no_shake) * Vector3f.new(0, 0, -1)):normalized() + local fixed_rot = fixed_dir:to_quat() + --local fixed_rot = neg_forward_identity * camera_rot player_camera:set_field("k__BackingField", fixed_rot) player_camera:set_field("k__BackingField", camera_pos) @@ -846,33 +879,41 @@ local function fix_player_camera(player_camera) -- Stop the player from rotating the camera vertically if camera_controller then - local camera_controller_rot = camera_controller:get_field("k__BackingField") + local camera_controller_rot = Quaternion.identity() - if did_recenter then + if re7.is_in_cutscene then + camera_controller_rot = camera_controller:get_field("k__BackingField") + else camera_controller_rot = Quaternion.new(fixed_rot.w, fixed_rot.x, fixed_rot.y, fixed_rot.z) - --vrmod:recenter_view() end - if did_recenter or not re7.is_in_cutscene then - local controller_forward = camera_controller_rot * Vector3f.new(0.0, 0.0, 1.0) - - --if not did_recenter then - controller_forward.y = 0.0 - --end + local controller_forward = camera_controller_rot * Vector3f.new(0.0, 0.0, 1.0) + controller_forward.y = 0.0 - camera_controller_rot = controller_forward:normalized():to_quat():normalized() + camera_controller_rot = controller_forward:normalized():to_quat() - base_transform_solver:set_field("k__BackingField", camera_controller_rot) + --if wants_recenter or not re7.is_in_cutscene then + if not re7.is_in_cutscene or is_maximum_controllable then + if not re7.is_in_cutscene then + vrmod:recenter_view() + end + camera_controller:set_field("k__BackingField", camera_controller_rot) end - - if did_recenter then - --player_camera:call("lateUpdate") - base_transform_solver:call("update") - camera_controller:call("updateOperatedCameraAngle") - end + base_transform_solver:set_field("k__BackingField", camera_controller_rot) + + --[[for i, controller in ipairs(base_transform_solver:get_field("CameraControllers"):get_elements()) do + controller:set_field("k__BackingField", camera_controller_rot) + controller:set_field("RelativeCamRotAtEndOfMotion", camera_controller_rot) + end]] + + --[[local maximum_operatable_controller = base_transform_solver:get_field("CameraControllers")[0] + if maximum_operatable_controller ~= camera_controller then + maximum_operatable_controller:set_field("k__BackingField", camera_controller_rot) + end]] + camera_controller:set_field("IsVerticalRotateLimited", true) was_vert_limited = true end @@ -881,6 +922,7 @@ local function fix_player_camera(player_camera) -- stops the camera from pivoting around the player -- so we can use VR to look around without the body sticking out --if vrmod:is_using_controllers() then + if not re7.is_in_cutscene then local param_container = player_camera:get_field("_CurrentParamContainer") if param_container ~= nil then @@ -894,24 +936,19 @@ local function fix_player_camera(player_camera) posture_param:set_field("CameraOffset", current_camera_offset) end end - --end + end local look_ray_offset = player_camera:get_type_definition():get_field("LookRay"):get_offset_from_base() local shoot_ray_offset = player_camera:get_type_definition():get_field("ShootRay"):get_offset_from_base() local look_ray = player_camera:get_address() + look_ray_offset local shoot_ray = player_camera:get_address() + shoot_ray_offset - --local new_dir = Vector4f.new(0.0, 0.0, 0.0, 1.0) - local new_pos = Vector4f.new(camera_pos.x, camera_pos.y, camera_pos.z, 1.0) - sdk.set_native_field(sdk.to_ptr(look_ray), ray_typedef, "from", camera_pos) sdk.set_native_field(sdk.to_ptr(look_ray), ray_typedef, "dir", fixed_dir) sdk.set_native_field(sdk.to_ptr(shoot_ray), ray_typedef, "from", camera_pos) sdk.set_native_field(sdk.to_ptr(shoot_ray), ray_typedef, "dir", fixed_dir) - if did_recenter then - player_camera:call("lateUpdate") - end + last_cutscene_state = re7.is_in_cutscene end local function on_pre_player_camera_update(args) @@ -951,27 +988,8 @@ local function on_pre_player_interp_rotation(args) local camera_gameobject = camera:call("get_GameObject") local camera_transform = camera_gameobject:call("get_Transform") - --[[if re7.is_in_cutscene and needs_cutscene_recenter then - vrmod:set_gui_rotation_offset(Quaternion.identity()) - vrmod:recenter_view() - - transform_set_rotation:call(camera_transform, last_camera_matrix:to_quat()) - - local camera_joint = camera_transform:call("get_Joints")[0] - - joint_set_rotation:call(camera_joint, last_camera_matrix:to_quat()) - - -- force the gui to be recentered when we exit the cutscene - last_gui_forced_slerp = os.clock() - needs_cutscene_recenter = false - end]] - re7.is_in_cutscene = true - needs_cutscene_recenter = true - - if needs_cutscene_recenter then - fix_player_camera(player_camera) - end + fix_player_camera(player_camera) end local function on_post_player_interp_rotation(retval) diff --git a/scripts/utility/RE7.lua b/scripts/utility/RE7.lua index ee7ac63e2..7bb3f2e2d 100644 --- a/scripts/utility/RE7.lua +++ b/scripts/utility/RE7.lua @@ -49,22 +49,33 @@ local CallbackManager = { local callbacks = CallbackManager:new() -local re7 = { - player = nil, - transform = nil, - weapon = nil, - weapon_gameobject = nil, - inventory = nil, - hand_touch = nil, - right_hand_ik = nil, - left_hand_ik = nil, - is_in_cutscene = false, - is_arm_jacked = false, - event_action_controller = nil, - wants_block = false, - num_active_tasks = 0, - active_tasks = {} -} +local function initialize_re7(re7) + re7 = re7 or {} + + re7.player = nil + re7.transform = nil + re7.weapon = nil + re7.weapon_gameobject = nil + re7.inventory = nil + re7.hand_touch = nil + re7.right_hand_ik = nil + re7.left_hand_ik = nil + re7.is_in_cutscene = false + re7.is_arm_jacked = false + re7.event_action_controller = nil + re7.wants_block = false + re7.movement_speed_rate = 0.0 + re7.movement_speed_vector = Vector3f.new(0, 0, 0) + re7.num_active_tasks = 0 + re7.active_tasks = {} + re7.application = sdk.get_native_singleton("via.Application") + re7.application_type = sdk.find_type_definition("via.Application") + re7.delta_time = 0.0 + + return re7 +end + +local re7 = initialize_re7() local known_typeofs = {} @@ -97,19 +108,15 @@ re.on_pre_application_entry("UpdateBehavior", function() re7.player = re7.get_localplayer() local player = re7.player - if player == nil then - re7.weapon = nil - re7.weapon_gameobject = nil - re7.event_action_controller = nil - re7.is_in_cutscene = false - re7.num_active_tasks = 0 - re7.active_tasks = {} + if player == nil or not re7.application then + initialize_re7(re7) return end re7.transform = player:call("get_Transform") re7.inventory = get_component(player, "app.Inventory") re7.hand_touch = get_component(player, "app.PlayerHandTouch") + re7.delta_time = sdk.call_native_func(re7.application, re7.application_type, "get_DeltaTime") if re7.hand_touch == nil then re7.right_hand_ik = nil @@ -236,6 +243,8 @@ local player_motion_controller_type = sdk.find_type_definition("app.PlayerMotion local update_postural_camera_motion_method = player_motion_controller_type:get_method("updatePosturalCameraMotion") local ch8_player_motion_controller_type = sdk.find_type_definition("app.CH8PlayerMotionController") local ch8_update_postural_camera_motion_method = ch8_player_motion_controller_type:get_method("updatePosturalCameraMotion") +local ch9_player_motion_controller_type = sdk.find_type_definition("app.CH9PlayerMotionController") +local ch9_update_postural_camera_motion_method = ch9_player_motion_controller_type:get_method("updatePosturalCameraMotion") local postural_camera_motion_args = nil @@ -259,8 +268,39 @@ local function on_post_update_postural_camera_motion(retval) return retval end +-- ethan sdk.hook(update_postural_camera_motion_method, on_pre_update_postural_camera_motion, on_post_update_postural_camera_motion) +-- chris sdk.hook(ch8_update_postural_camera_motion_method, on_pre_update_postural_camera_motion, on_post_update_postural_camera_motion) +-- ch9 (end of zoe?) +sdk.hook(ch9_update_postural_camera_motion_method, on_pre_update_postural_camera_motion, on_post_update_postural_camera_motion) + +local player_movement_type = sdk.find_type_definition("app.PlayerMovement") +local player_movement_late_update_method = player_movement_type:get_method("doLateUpdate") +local ch8_player_movement_type = sdk.find_type_definition("app.CH8PlayerMovement") +local ch8_player_movement_late_update_method = ch8_player_movement_type:get_method("doLateUpdate") +local ch9_player_movement_type = sdk.find_type_definition("app.CH9PlayerMovement") +local ch9_player_movement_late_update_method = ch9_player_movement_type:get_method("doLateUpdate") + +local player_movement_args = nil + +local function on_pre_player_movement_late_update(args) + player_movement_args = args +end + +local function on_post_player_movement_late_update(retval) + local args = player_movement_args + local movement = sdk.to_managed_object(args[2]) + + re7.movement_speed_rate = movement:get_field("_SpeedRate") + re7.movement_speed_vector = movement:get_field("_MoveSpeedVector") + + return retval +end + +sdk.hook(player_movement_late_update_method, on_pre_player_movement_late_update, on_post_player_movement_late_update) +sdk.hook(ch8_player_movement_late_update_method, on_pre_player_movement_late_update, on_post_player_movement_late_update) +sdk.hook(ch9_player_movement_late_update_method, on_pre_player_movement_late_update, on_post_player_movement_late_update) function re7.notify_event_task_created(callback) callbacks["event_task_create"]:add(callback) From 70709ae079bd90228d14d6694ee54f0426101081 Mon Sep 17 00:00:00 2001 From: praydog Date: Thu, 10 Mar 2022 04:03:23 -0800 Subject: [PATCH 04/45] VR: More bindings for RE7 --- scripts/re7_vr.lua | 31 +++++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/scripts/re7_vr.lua b/scripts/re7_vr.lua index 0fe8f9412..2d2fc1dde 100644 --- a/scripts/re7_vr.lua +++ b/scripts/re7_vr.lua @@ -89,6 +89,14 @@ local function update_pad_device(device) if not vrmod:is_hmd_active() then return end + + local menu_manager = sdk.get_managed_singleton("app.MenuManager") + local is_inventory_open = false + + if menu_manager ~= nil then + is_inventory_open = menu_manager:call("isOpenInventoryMenu") + is_inventory_open = is_inventory_open or menu_manager:call("isOpenItemBoxMenu") + end local raw_left_stick_axis = vrmod:get_left_stick_axis() @@ -138,6 +146,9 @@ local function update_pad_device(device) local action_a_button = vrmod:get_action_a_button() local action_b_button = vrmod:get_action_b_button() local action_joystick_click = vrmod:get_action_joystick_click() + local action_weapon_dial = vrmod:get_action_weapon_dial() + local action_minimap = vrmod:get_action_minimap() + local action_block = vrmod:get_action_block() local right_joystick = vrmod:get_right_joystick() local left_joystick = vrmod:get_left_joystick() @@ -145,6 +156,10 @@ local function update_pad_device(device) if vrmod:is_action_active(action_trigger, right_joystick) then device:call("set_AnalogR", 1.0) cur_button = cur_button | via.hid.GamePadButton.RTrigBottom + + if is_inventory_open then + cur_button = cur_button | via.hid.GamePadButton.RTrigTop + end end -- gripping right joystick causes "left trigger" to be pressed (aiming) @@ -153,7 +168,7 @@ local function update_pad_device(device) device:call("set_AnalogL", 1.0) end - if vrmod:is_action_active(action_trigger, left_joystick) then + if vrmod:is_action_active(action_weapon_dial, left_joystick) or vrmod:is_action_active(action_weapon_dial, right_joystick) then -- DPad mimickry if vr_left_stick_axis.y >= 0.9 then cur_button = cur_button | via.hid.GamePadButton.LUp @@ -166,9 +181,12 @@ local function update_pad_device(device) elseif vr_left_stick_axis.x <= -0.9 then cur_button = cur_button | via.hid.GamePadButton.LLeft end + end - -- set right bumper instead of left trigger - cur_button = cur_button | via.hid.GamePadButton.LTrigTop + if vrmod:is_action_active(action_trigger, left_joystick) then + if is_inventory_open then + cur_button = cur_button | via.hid.GamePadButton.LTrigTop + end -- set right bumper (heal) if holding both trigger and grip if vrmod:is_action_active(action_grip, left_joystick) then @@ -176,8 +194,9 @@ local function update_pad_device(device) end end - if re7.wants_block then + if re7.wants_block or vrmod:is_action_active(action_block, left_joystick) or vrmod:is_action_active(action_block, right_joystick) then cur_button = cur_button | via.hid.GamePadButton.LTrigTop + re7.wants_block = true end if vrmod:is_action_active(action_a_button, right_joystick) then @@ -204,6 +223,10 @@ local function update_pad_device(device) cur_button = cur_button | via.hid.GamePadButton.LStickPush end + if vrmod:is_action_active(action_minimap, right_joystick) or vrmod:is_action_active(action_minimap, left_joystick) then + cur_button = cur_button | via.hid.GamePadButton.CLeft + end + device:call("set_Button", cur_button) device:call("set_ButtonDown", cur_button) end From 74dd5578ed30b09674d7c5cc0b643353b649eeaf Mon Sep 17 00:00:00 2001 From: praydog Date: Fri, 11 Mar 2022 12:59:38 -0800 Subject: [PATCH 05/45] VR: Body IK stability improvements for RE7 --- scripts/re7_vr.lua | 47 +++++++++++++++++++++++++++++++++-------- scripts/utility/RE7.lua | 7 ++++++ 2 files changed, 45 insertions(+), 9 deletions(-) diff --git a/scripts/re7_vr.lua b/scripts/re7_vr.lua index 2d2fc1dde..6b1e16223 100644 --- a/scripts/re7_vr.lua +++ b/scripts/re7_vr.lua @@ -341,11 +341,29 @@ local function calculate_tpose_world(joint, depth) local cur_joint = joint - for i=0, depth do - local parent = cur_joint:call("get_Parent") - table.insert(joints, parent) - cur_joint = parent + for i=1, depth do + cur_joint = cur_joint:call("get_Parent") + table.insert(joints, cur_joint) end + + local parent_pos = joint_get_position:call(cur_joint) + local parent_rot = joint_get_rotation:call(cur_joint) + local original_parent_pos = player_pos + (player_rot * player_transform:calculate_base_transform(cur_joint)[3]) + + for i=1, depth do + local joint = joints[depth-i] + + local original_pos = player_pos + (player_rot * player_transform:calculate_base_transform(joint)[3]) + local diff = original_pos - original_parent_pos + local updated_pos = parent_pos + diff + + original_parent_pos = original_pos + parent_pos = updated_pos + end + + local original_pos = player_pos + (player_rot * player_transform:calculate_base_transform(joint)[3]) + local diff = original_pos - original_parent_pos + return parent_pos + diff end local function set_hand_joints_to_tpose(hand_ik) @@ -378,8 +396,11 @@ local function set_hand_joints_to_tpose(hand_ik) if #joints > 0 and joints[1] ~= nil then table.insert(joints, 1, joints[1]:call("get_Parent")) - table.insert(joints, 1, joints[1]:call("get_Parent")) - table.insert(joints, 1, joints[1]:call("get_Parent")) + + if not re7.is_grapple_aim then + table.insert(joints, 1, joints[1]:call("get_Parent")) + table.insert(joints, 1, joints[1]:call("get_Parent")) + end end for i, joint in ipairs(joints) do @@ -586,7 +607,15 @@ local function update_body_ik(camera_rotation, camera_pos) local original_head_pos = motion:call("getWorldPosition", head_index) --local original_chest_pos = motion:call("getWorldPosition", chest_index) - original_head_pos = transform_rot * original_head_pos + local normal_dir = camera_rotation * Vector3f.new(0, 0, 1) + local flattened_dir = camera_rotation * Vector3f.new(0, 0, 1) + flattened_dir.y = 0.0 + flattened_dir:normalize() + + original_head_pos = calculate_tpose_world(head_joint, 4) + original_head_pos = original_head_pos + (flattened_dir * (math.abs(normal_dir.y) * -0.1)) + (flattened_dir * 0.025) + + --original_head_pos = transform_rot * original_head_pos --original_head_pos = transform:call("getJointByName", "root"):call("get_Rotation") * original_head_pos --original_head_pos = transform_rot * transform:calculate_base_transform(head_joint)[3] --original_chest_pos = transform_rot * original_chest_pos @@ -610,7 +639,7 @@ local function update_body_ik(camera_rotation, camera_pos) local center_pos = center_joint:call("get_Position") local transform_pos = transform:call("get_Position")]] - local diff_to_camera = ((camera_pos - transform_pos) - original_head_pos) + local diff_to_camera = ((camera_pos) - original_head_pos) --ik_leg:call("set_CenterJointName", "Hip") ik_leg:call("set_CenterOffset", diff_to_camera) @@ -867,7 +896,7 @@ local function fix_player_camera(player_camera) --last_gui_offset = last_gui_offset * (camera_rot:inverse() * camera_rot_pre_hmd) -- just update the body IK right after we update the camera. - update_body_ik(camera_rot_pre_hmd, camera_pos) + update_body_ik(camera_rot, camera_pos) -- Slerp the gui around slerp_gui(re7.is_in_cutscene and (camera_rot_pre_hmd * camera_rot:inverse()) or vrmod:get_rotation(0):to_quat():inverse()) diff --git a/scripts/utility/RE7.lua b/scripts/utility/RE7.lua index 7bb3f2e2d..bac0aa1e0 100644 --- a/scripts/utility/RE7.lua +++ b/scripts/utility/RE7.lua @@ -58,10 +58,12 @@ local function initialize_re7(re7) re7.weapon_gameobject = nil re7.inventory = nil re7.hand_touch = nil + re7.order = nil re7.right_hand_ik = nil re7.left_hand_ik = nil re7.is_in_cutscene = false re7.is_arm_jacked = false + re7.is_grapple_aim = false re7.event_action_controller = nil re7.wants_block = false re7.movement_speed_rate = 0.0 @@ -116,8 +118,13 @@ re.on_pre_application_entry("UpdateBehavior", function() re7.transform = player:call("get_Transform") re7.inventory = get_component(player, "app.Inventory") re7.hand_touch = get_component(player, "app.PlayerHandTouch") + re7.order = get_component(player, "app.PlayerOrder") re7.delta_time = sdk.call_native_func(re7.application, re7.application_type, "get_DeltaTime") + if re7.order ~= nil then + re7.is_grapple_aim = re7.order:get_field("IsGrappleAimEnable") + end + if re7.hand_touch == nil then re7.right_hand_ik = nil re7.left_hand_ik = nil From 46322d06730abce09fb9f4c17edbedbb8610bf98 Mon Sep 17 00:00:00 2001 From: praydog Date: Wed, 16 Mar 2022 13:27:13 -0700 Subject: [PATCH 06/45] VR: Port RE7 features to RE8; re8_vr.lua now compatible with RE7 and RE8 --- scripts/re8_vr.lua | 1666 +++++++++++++++++++++++++++++++-------- scripts/utility/RE8.lua | 394 +++++++++ 2 files changed, 1743 insertions(+), 317 deletions(-) create mode 100644 scripts/utility/RE8.lua diff --git a/scripts/re8_vr.lua b/scripts/re8_vr.lua index 6f4df7cce..c421260d0 100644 --- a/scripts/re8_vr.lua +++ b/scripts/re8_vr.lua @@ -1,110 +1,94 @@ -if reframework:get_game_name() ~= "re8" then - return -end - --- Trim the "userdata: " off of a string --- todo: FIX IT so we don't need to do this -local function get_raw_userdata(ud) - return tonumber("0x"..string.sub(tostring(ud), 11)) -end - -local system_object_type = sdk.find_type_definition("System.Object") -local system_type = sdk.find_type_definition("System.RuntimeType") -local system_array_type = sdk.find_type_definition("System.Array") -local system_single = sdk.find_type_definition("System.Single") -local system_activator_type = sdk.find_type_definition("System.Activator") - -local function get_gameobject(component) - return component:call("get_GameObject") -end - -local function get_component(game_object, type_name) - local t = sdk.typeof(type_name) +local game_name = reframework:get_game_name() +local is_re7 = game_name == "re7" +local is_re8 = game_name == "re8" - if t == nil then - return nil - end - - return game_object:call("getComponent(System.Type)", t) -end - -local function get_components(game_object) - local transform = game_object:call("get_Transform") - - if not transform then - return {} - end - - return game_object:call("get_Components"):get_elements() +if not is_re7 and not is_re8 then + msg("Error: Game is not RE7 or RE8.") + return end -local propsman = sdk.get_managed_singleton(sdk.game_namespace("PropsManager")) +local statics = require("utility/Statics") +local re8 = require("utility/RE8") +local GameObject = require("utility/GameObject") -local function get_localplayer() - if not propsman then - propsman = sdk.get_managed_singleton(sdk.game_namespace("PropsManager")) - end +local renderer = sdk.get_native_singleton("via.render.Renderer") +local renderer_type = sdk.find_type_definition("via.render.Renderer") - return propsman:call("get_Player") -end +local GamePadButton = statics.generate("via.hid.GamePadButton") -local player_data = {} local last_camera_matrix = Matrix4x4f.new() - -local left_hand_rotation_offset = Quaternion.new(Vector3f.new(0.4, 2.4, 1.7)):normalized() -local right_hand_rotation_offset = Quaternion.new(Vector3f.new(0.2, -2.5, -1.7)):normalized() - -local left_hand_position_offset = Vector4f.new(-0.05, 0.05, 0.15, 0.0) -local right_hand_position_offset = Vector4f.new( 0.05, 0.05, 0.15, 0.0) - -local ray_typedef = sdk.find_type_definition("via.Ray") -local last_muzzle_pos = Vector3f.new(0.0, 0.0, 0.0) -local last_muzzle_rot = Quaternion.new(0.0, 0.0, 0.0, 0.0) -local last_muzzle_forward = Vector3f.new(0.0, 0.0, 0.0) - local last_right_hand_rotation = Quaternion.new(0.0, 0.0, 0.0, 0.0) local last_right_hand_position = Vector3f.new(0.0, 0.0, 0.0) local last_left_hand_rotation = Quaternion.new(0.0, 0.0, 0.0, 0.0) local last_left_hand_position = Vector3f.new(0.0, 0.0, 0.0) +local left_hand_rotation_vec = Vector3f.new(-0.105 + 0.2, 2.37, 1.10) -- pitch yaw roll? +local right_hand_rotation_vec = Vector3f.new(-0.105, -2.37, -1.10) -- pitch yaw roll? +local left_hand_rotation_offset = Quaternion.new(left_hand_rotation_vec):normalized() +local right_hand_rotation_offset = Quaternion.new(right_hand_rotation_vec):normalized() +local left_hand_position_offset = Vector4f.new(-0.025, 0.045, 0.155, 0.0) +local right_hand_position_offset = Vector4f.new(0.025, 0.045, 0.155, 0.0) -local via_motion_ik = sdk.find_type_definition("via.motion.ik") -local via_hid_gamepad = sdk.find_type_definition("via.hid.GamePad") - -local via = { - hid = { - GamePadButton = {} - } -} - -local app = { - HIDInputMode = {} +local ray_typedef = sdk.find_type_definition("via.Ray") +local last_muzzle_pos = Vector4f.new(0.0, 0.0, 0.0, 1.0) +local last_muzzle_rot = Quaternion.new(0.0, 0.0, 0.0, 0.0) +local last_muzzle_forward = Vector4f.new(0.0, 0.0, 0.0, 1.0) + +local transform_get_position = sdk.find_type_definition("via.Transform"):get_method("get_Position") +local transform_get_rotation = sdk.find_type_definition("via.Transform"):get_method("get_Rotation") +local transform_set_position = sdk.find_type_definition("via.Transform"):get_method("set_Position") +local transform_set_rotation = sdk.find_type_definition("via.Transform"):get_method("set_Rotation") +local transform_get_joints = sdk.find_type_definition("via.Transform"):get_method("get_Joints") + +local joint_get_position = sdk.find_type_definition("via.Joint"):get_method("get_Position") +local joint_get_rotation = sdk.find_type_definition("via.Joint"):get_method("get_Rotation") +local joint_set_position = sdk.find_type_definition("via.Joint"):get_method("set_Position") +local joint_set_rotation = sdk.find_type_definition("via.Joint"):get_method("set_Rotation") +local joint_get_parent = sdk.find_type_definition("via.Joint"):get_method("get_Parent") + +local component_get_gameobject = sdk.find_type_definition("via.Component"):get_method("get_GameObject") +local gameobject_get_transform = sdk.find_type_definition("via.GameObject"):get_method("get_Transform") + +local cfg_path = "re7_vr/main_config.json" + +local queue_recenter = false +local was_vert_limited = false + +local last_gui_offset = Quaternion.identity() +local last_gui_quat = Quaternion.identity() +local last_gui_dot = 0.0 +local last_gui_forced_slerp = os.clock() +local needs_cutscene_recenter = false +local last_inventory_open_time = 0.0 + +local cfg = { + movement_shake = false, + all_camera_shake = true } -local function generate_enum(typename) - local t = sdk.find_type_definition(typename) - if not t then return {} end +local function load_cfg() + local loaded_cfg = json.load_file(cfg_path) - local fields = t:get_fields() - local enum = {} + if loaded_cfg == nil then + json.dump_file(cfg_path, cfg) + return + end - for i, field in ipairs(fields) do - if field:is_static() then - local name = field:get_name() - local raw_value = field:get_data(nil) + for k, v in pairs(loaded_cfg) do + cfg[k] = v + end +end - log.info(name .. " = " .. tostring(raw_value)) +load_cfg() - enum[name] = raw_value - end - end +statics.generate_global("via.hid.GamePadButton") +statics.generate_global("via.hid.MouseButton") - return enum +if is_re7 then + statics.generate_global("app.HIDManager.InputMode") +elseif is_re8 then + statics.generate_global("app.HIDInputMode") end -via.hid.GamePadButton = generate_enum("via.hid.GamePadButton") -via.hid.MouseButton = generate_enum("via.hid.MouseButton") -app.HIDInputMode = generate_enum("app.HIDInputMode") - local via_hid_mouse_typedef = sdk.find_type_definition("via.hid.Mouse") local via_hid_mouse = sdk.get_native_singleton("via.hid.Mouse") @@ -120,17 +104,25 @@ local function set_inputmode(mode) end end -local last_padman_args = nil +local is_inventory_open = false local function update_pad_device(device) if not vrmod:is_hmd_active() then return end - local raw_left_stick_axis = vrmod:get_left_stick_axis() + if is_re7 then + local menu_manager = sdk.get_managed_singleton("app.MenuManager") - local forward_dir = Vector4f.new(raw_left_stick_axis.x, 0.0, raw_left_stick_axis.y, 0.0) + if menu_manager ~= nil then + is_inventory_open = menu_manager:call("isOpenInventoryMenu") + end + elseif is_re8 then + is_inventory_open = (os.clock() - last_inventory_open_time) < 0.25 + end + local raw_left_stick_axis = vrmod:get_left_stick_axis() + --local vr_left_stick_axis = last_camera_matrix:to_quat() * Vector4f.new(raw_left_stick_axis.x, raw_left_stick_axis.y, 0.0, 0.0) local vr_left_stick_axis = vrmod:get_left_stick_axis() local vr_right_stick_axis = vrmod:get_right_stick_axis() @@ -148,28 +140,30 @@ local function update_pad_device(device) -- EmuRleft -- set cur_button | according to the right stick axis - if vr_right_stick_axis.x > 0.1 then - cur_button = cur_button | via.hid.GamePadButton.EmuRright - elseif vr_right_stick_axis.x < -0.1 then - cur_button = cur_button | via.hid.GamePadButton.EmuRleft - end - - if vr_right_stick_axis.y > 0.1 then - cur_button = cur_button | via.hid.GamePadButton.EmuRup - elseif vr_right_stick_axis.y < -0.1 then - cur_button = cur_button | via.hid.GamePadButton.EmuRdown - end - - if vr_left_stick_axis.x > 0.1 then - cur_button = cur_button | via.hid.GamePadButton.EmuLright - elseif vr_left_stick_axis.x < -0.1 then - cur_button = cur_button | via.hid.GamePadButton.EmuLleft - end - - if vr_left_stick_axis.y > 0.1 then - cur_button = cur_button | via.hid.GamePadButton.EmuLup - elseif vr_left_stick_axis.y < -0.1 then - cur_button = cur_button | via.hid.GamePadButton.EmuLdown + if is_re8 then + if vr_right_stick_axis.x > 0.1 then + cur_button = cur_button | via.hid.GamePadButton.EmuRright + elseif vr_right_stick_axis.x < -0.1 then + cur_button = cur_button | via.hid.GamePadButton.EmuRleft + end + + if vr_right_stick_axis.y > 0.1 then + cur_button = cur_button | via.hid.GamePadButton.EmuRup + elseif vr_right_stick_axis.y < -0.1 then + cur_button = cur_button | via.hid.GamePadButton.EmuRdown + end + + if vr_left_stick_axis.x > 0.1 then + cur_button = cur_button | via.hid.GamePadButton.EmuLright + elseif vr_left_stick_axis.x < -0.1 then + cur_button = cur_button | via.hid.GamePadButton.EmuLleft + end + + if vr_left_stick_axis.y > 0.1 then + cur_button = cur_button | via.hid.GamePadButton.EmuLup + elseif vr_left_stick_axis.y < -0.1 then + cur_button = cur_button | via.hid.GamePadButton.EmuLdown + end end local action_trigger = vrmod:get_action_trigger() @@ -177,6 +171,9 @@ local function update_pad_device(device) local action_a_button = vrmod:get_action_a_button() local action_b_button = vrmod:get_action_b_button() local action_joystick_click = vrmod:get_action_joystick_click() + local action_weapon_dial = vrmod:get_action_weapon_dial() + local action_minimap = vrmod:get_action_minimap() + local action_block = vrmod:get_action_block() local right_joystick = vrmod:get_right_joystick() local left_joystick = vrmod:get_left_joystick() @@ -184,6 +181,10 @@ local function update_pad_device(device) if vrmod:is_action_active(action_trigger, right_joystick) then device:call("set_AnalogR", 1.0) cur_button = cur_button | via.hid.GamePadButton.RTrigBottom + + if is_inventory_open then + cur_button = cur_button | via.hid.GamePadButton.RTrigTop + end end -- gripping right joystick causes "left trigger" to be pressed (aiming) @@ -192,9 +193,25 @@ local function update_pad_device(device) device:call("set_AnalogL", 1.0) end + if vrmod:is_action_active(action_weapon_dial, left_joystick) or vrmod:is_action_active(action_weapon_dial, right_joystick) then + -- DPad mimickry + if vr_left_stick_axis.y >= 0.9 then + cur_button = cur_button | via.hid.GamePadButton.LUp + elseif vr_left_stick_axis.y <= -0.9 then + cur_button = cur_button | via.hid.GamePadButton.LDown + end + + if vr_left_stick_axis.x >= 0.9 then + cur_button = cur_button | via.hid.GamePadButton.LRight + elseif vr_left_stick_axis.x <= -0.9 then + cur_button = cur_button | via.hid.GamePadButton.LLeft + end + end + if vrmod:is_action_active(action_trigger, left_joystick) then - -- set right bumper instead of left trigger - cur_button = cur_button | via.hid.GamePadButton.LTrigTop + if is_inventory_open then + cur_button = cur_button | via.hid.GamePadButton.LTrigTop + end -- set right bumper (heal) if holding both trigger and grip if vrmod:is_action_active(action_grip, left_joystick) then @@ -202,8 +219,9 @@ local function update_pad_device(device) end end - if player_data.wants_block then + if re8.wants_block or vrmod:is_action_active(action_block, left_joystick) or vrmod:is_action_active(action_block, right_joystick) then cur_button = cur_button | via.hid.GamePadButton.LTrigTop + re8.wants_block = true end if vrmod:is_action_active(action_a_button, right_joystick) then @@ -230,12 +248,16 @@ local function update_pad_device(device) cur_button = cur_button | via.hid.GamePadButton.LStickPush end + if vrmod:is_action_active(action_minimap, right_joystick) or vrmod:is_action_active(action_minimap, left_joystick) then + cur_button = cur_button | via.hid.GamePadButton.CLeft + end + device:call("set_Button", cur_button) device:call("set_ButtonDown", cur_button) end local function update_padman(padman) - if not vrmod:is_hmd_active() then + if not vrmod:is_hmd_active() or not vrmod:is_using_controllers() then return end @@ -245,6 +267,8 @@ local function update_padman(padman) return end + --padman:call("set_activePad", merged_pad) + local device = merged_pad:get_field("Device") if not device then @@ -255,9 +279,14 @@ local function update_padman(padman) --merged_pad:call("updateStick") --merged_pad:call("updateButton") - set_inputmode(app.HIDInputMode.Pad) + if is_re7 then + set_inputmode(app.HIDManager.InputMode.Pad) + elseif is_re8 then + set_inputmode(app.HIDInputMode.Pad) + end end +-- RE8 only. local function on_pre_hid_padman_update(args) last_padman_args = args @@ -281,51 +310,212 @@ local function on_post_hid_padman_update(retval) return retval end -sdk.hook(sdk.find_type_definition(sdk.game_namespace("HIDPadManager")):get_method("doUpdate"), on_pre_hid_padman_update, on_post_hid_padman_update) +local function on_pre_app_pad_update(args) + if not vrmod:is_hmd_active() or not vrmod:is_using_controllers() then + return + end + + local pad = sdk.to_managed_object(args[2]) -local function on_pre_is_satisfy(args) - update_padman(sdk.to_managed_object(last_padman_args[2])) - local padman = sdk.to_managed_object(last_padman_args[2]) + local padman = sdk.get_managed_singleton(sdk.game_namespace("PadManager")) + + if not padman then + return + end local merged_pad = padman:call("get_mergedPad") - if not merged_pad then + if not merged_pad or merged_pad ~= pad then return end - local stick_right_vertical = merged_pad:get_field("_StickRightVertical") - --merged_pad:set_field("_StickRightVertical", 1.0) + local device = merged_pad:get_field("Device") - log.info(tostring(stick_right_vertical)) -end + if not device then + return + end -local function on_post_is_satisfy(retval) - return sdk.to_ptr(1) + update_pad_device(device) + --merged_pad:call("updateStick") + --merged_pad:call("updateButton") + + if is_re7 then + set_inputmode(app.HIDManager.InputMode.Pad) + elseif is_re8 then + set_inputmode(app.HIDInputMode.Pad) + end end ---sdk.hook(sdk.find_type_definition("app.Input.StickChecker"):get_method("isSatisfy(app.HIDPad)"), on_pre_is_satisfy, on_post_is_satisfy) +local function on_post_app_pad_update(retval) + return retval +end -local inside_transform_count = 0 +if is_re7 then + sdk.hook( + sdk.find_type_definition("app.Pad"):get_method("update"), + on_pre_app_pad_update, + on_post_app_pad_update + ) +elseif is_re8 then + sdk.hook(sdk.find_type_definition(sdk.game_namespace("HIDPadManager")):get_method("doUpdate"), on_pre_hid_padman_update, on_post_hid_padman_update) +end -local function on_pre_update_player_transform(transform) - if inside_transform_count > 0 or player_data.is_in_cutscene then +local function on_pre_try_guard_start(args) + if not vrmod:is_hmd_active() or not vrmod:is_using_controllers() then return end - inside_transform_count = inside_transform_count + 1 + -- this will only allow blocking by physically holding your hands up. + if not re8.wants_block then + return sdk.PreHookResult.SKIP_ORIGINAL + end +end + +local function on_post_try_guard_start(retval) + if not vrmod:is_hmd_active() or not vrmod:is_using_controllers() or re8.wants_block then + return retval + end + + return sdk.to_ptr(0) +end + +sdk.hook( + sdk.find_type_definition("app.PlayerBase"):get_method("tryGuardStart"), + on_pre_try_guard_start, + on_post_try_guard_start +) + +local function calculate_tpose_world(joint, depth) + if not depth then + depth = 1 + end + + local original_positions = {} + local original_rotations = {} + local current_positions = {} + + local player_transform = re8.transform + local player_pos = transform_get_position:call(player_transform) + local player_rot = transform_get_rotation:call(player_transform) + + local joints = {} + + local cur_joint = joint + + for i=1, depth do + cur_joint = joint_get_parent:call(cur_joint) + table.insert(joints, cur_joint) + end + + local parent_pos = joint_get_position:call(cur_joint) + local parent_rot = joint_get_rotation:call(cur_joint) + local original_parent_pos = player_pos + (player_rot * player_transform:calculate_base_transform(cur_joint)[3]) + + for i=1, depth do + local joint = joints[depth-i] + + local original_pos = player_pos + (player_rot * player_transform:calculate_base_transform(joint)[3]) + local diff = original_pos - original_parent_pos + local updated_pos = parent_pos + diff + + original_parent_pos = original_pos + parent_pos = updated_pos + end + + local original_pos = player_pos + (player_rot * player_transform:calculate_base_transform(joint)[3]) + local diff = original_pos - original_parent_pos + return parent_pos + diff +end + +local function set_hand_joints_to_tpose(hand_ik) + local hashes = { + } + + if is_re7 then + hashes = { + hand_ik:get_field("HashJoint0"), + hand_ik:get_field("HashJoint1"), + hand_ik:get_field("HashJoint2"), + hand_ik:get_field("HashJoint3") + } + elseif is_re8 then + hashes = { + hand_ik:get_field("k__BackingField"), + hand_ik:get_field("k__BackingField"), + hand_ik:get_field("k__BackingField") + } + end + + local original_positions = {} + local original_rotations = {} + local current_positions = {} + + local player_transform = re8.transform + local player_pos = transform_get_position:call(player_transform) + local player_rot = transform_get_rotation:call(player_transform) + + local joints = {} + + for i, hash in ipairs(hashes) do + if hash and hash ~= 0 then + local joint = player_transform:call("getJointByHash", hash) + + if joint then + table.insert(joints, joint_get_parent:call(joint)) + end + end + end + + if #joints > 0 and joints[1] ~= nil then + table.insert(joints, 1, joint_get_parent:call(joints[1])) + + if not re8.is_grapple_aim then + table.insert(joints, 1, joint_get_parent:call(joints[1])) + table.insert(joints, 1, joint_get_parent:call(joints[1])) + end + end + + for i, joint in ipairs(joints) do + local base_transform = player_transform:calculate_base_transform(joint) + original_positions[i] = player_pos + (player_rot * base_transform[3]) + original_rotations[i] = player_rot * base_transform:to_quat() + current_positions[i] = joint_get_position:call(joint) + end + + -- second pass + for i, joint in ipairs(joints) do + if joint then + local next_joint = joints[i + 1] + + if next_joint ~= nil then + local diff = original_positions[i + 1] - original_positions[i] + local updated_pos = current_positions[i] + diff + + joint_set_position:call(next_joint, updated_pos) + joint_set_rotation:call(next_joint, original_rotations[i+1]) + + current_positions[i + 1] = updated_pos + end + end + end +end + +local function update_hand_ik() + if not re8.player then return end + if not vrmod:is_hmd_active() or not vrmod:is_using_controllers() then return end local controllers = vrmod:get_controllers() if #controllers == 0 then - inside_transform_count = inside_transform_count - 1 return end - --log.info("Muzzle rotation: " .. tostring(muzzle_rotation.x) .. " " .. tostring(muzzle_rotation.y) .. " " .. tostring(muzzle_rotation.z) .. " " .. tostring(muzzle_rotation.w)) + if not re8.left_hand_ik or not re8.right_hand_ik then + return + end - local joints = transform:call("get_Joints"):get_elements() - local rotation = transform:call("get_Rotation") - local position = transform:call("get_Position") + --if re8.is_in_cutscene then return end + if re8.is_arm_jacked then return end local left_controller_transform = vrmod:get_transform(controllers[1]) local right_controller_transform = vrmod:get_transform(controllers[2]) @@ -333,180 +523,239 @@ local function on_pre_update_player_transform(transform) local right_controller_rotation = right_controller_transform:to_quat() local hmd_transform = vrmod:get_transform(0) - local hmd_rotation = hmd_transform:to_quat() + --local hmd_rotation = (vrmod:get_rotation_offset() * hmd_transform:to_quat()):normalized() local left_controller_offset = left_controller_transform[3] - hmd_transform[3] local right_controller_offset = right_controller_transform[3] - hmd_transform[3] local camera = sdk.get_primary_camera() local camera_rotation = last_camera_matrix:to_quat() - local original_camera_rotation = camera:call("get_WorldMatrix"):to_quat() - --log.info("num joints: " .. tostring(#joints)) + local original_camera_matrix = camera:call("get_WorldMatrix") + local original_camera_rotation_pre = original_camera_matrix:to_quat() + local original_camera_rotation = (original_camera_rotation_pre * vrmod:get_rotation_offset()):normalized() - for i, joint in ipairs(joints) do - local joint_name = joint:call("get_Name") - --log.info(joint_name) + local fake_quat = Quaternion.new(original_camera_rotation_pre.w, original_camera_rotation_pre.x, original_camera_rotation_pre.y, original_camera_rotation_pre.z) + local updated_camera_pos = original_camera_matrix[3] - --[[local constraint_joint = joint:call("get_ConstraintJoint") + vrmod:apply_hmd_transform(fake_quat, updated_camera_pos) - if constraint_joint then - --log.info(" Constraint: " .. constraint_joint:call("get_Name")) - end + local new_rotation = original_camera_rotation * left_controller_rotation * left_hand_rotation_offset + local new_pos = updated_camera_pos + + ((original_camera_rotation * left_controller_offset) + + ((original_camera_rotation * left_controller_rotation):normalized() * left_hand_position_offset)) - local parent = joint:call("get_Parent") + last_left_hand_position = new_pos + last_left_hand_rotation = new_rotation - if parent then - --log.info(" Parent: " .. parent:call("get_Name")) - end]] + set_hand_joints_to_tpose(re8.left_hand_ik) - if joint_name == "L_Hand" or joint_name == "R_Hand" then - local joint_position = joint:call("get_Position") - local new_pos = nil - local new_rotation = nil + transform_set_position:call(re8.left_hand_ik_transform, new_pos) + transform_set_rotation:call(re8.left_hand_ik_transform, new_rotation) + re8.left_hand_ik:set_field("Transition", 1.0) + re8.left_hand_ik:call("calc") - if joint_name == "L_Hand" then - new_rotation = original_camera_rotation * left_controller_rotation * left_hand_rotation_offset - new_pos = last_camera_matrix[3] - + ((original_camera_rotation * left_controller_offset) - + ((original_camera_rotation * left_controller_rotation):normalized() * left_hand_position_offset)) + --re8.transform:call("getJointByHash", re8.left_hand_ik:get_field("HashJoint2")):call("set_Position", new_pos) - last_left_hand_position = new_pos - last_left_hand_rotation = new_rotation + new_rotation = original_camera_rotation * right_controller_rotation * right_hand_rotation_offset + new_pos = updated_camera_pos + + ((original_camera_rotation * right_controller_offset) + + ((original_camera_rotation * right_controller_rotation):normalized() * right_hand_position_offset)) + + last_right_hand_position = new_pos + last_right_hand_rotation = new_rotation - player_data.left_hand_ik_transform:call("set_Position", last_left_hand_position) - player_data.left_hand_ik_transform:call("set_Rotation", last_left_hand_rotation) - player_data.left_hand_ik:set_field("Transition", 1.0) - player_data.left_hand_ik:call("calc") - else - new_rotation = original_camera_rotation * right_controller_rotation * right_hand_rotation_offset - new_pos = last_camera_matrix[3] - + ((original_camera_rotation * right_controller_offset) - + ((original_camera_rotation * right_controller_rotation):normalized() * right_hand_position_offset)) + set_hand_joints_to_tpose(re8.right_hand_ik) + + transform_set_position:call(re8.right_hand_ik_transform, new_pos) + transform_set_rotation:call(re8.right_hand_ik_transform, new_rotation) + re8.right_hand_ik:set_field("Transition", 1.0) + re8.right_hand_ik:call("calc") - last_right_hand_position = new_pos - last_right_hand_rotation = new_rotation + --re8.transform:call("getJointByHash", re8.right_hand_ik:get_field("HashJoint2")):call("set_Position", new_pos) +end - player_data.right_hand_ik_transform:call("set_Position", last_right_hand_position) - player_data.right_hand_ik_transform:call("set_Rotation", last_right_hand_rotation) - player_data.right_hand_ik:set_field("Transition", 1.0) - player_data.right_hand_ik:call("calc") +local last_real_camera_rotation = Quaternion.new(1, 0, 0, 0) +local last_real_camera_joint_rotation = Quaternion.new(1, 0, 0, 0) +local last_real_camera_joint_pos = Vector3f.new(0, 0, 0) - --[[local forearm = joint:call("get_Parent") - local upper_arm = forearm:call("get_Parent") +local neg_forward_identity = Matrix4x4f.new(-1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, -1, 0, + 0, 0, 0, 1):to_quat() - local w2 = transform:calculate_base_transform(joint) - local w1 = transform:calculate_base_transform(forearm) - local w0 = transform:calculate_base_transform(upper_arm) +local neg_identity = Matrix4x4f.new(-1, 0, 0, 0, + 0, -1, 0, 0, + 0, 0, -1, 0, + 0, 0, 0, -1):to_quat() - sdk.call_native_func(nil, via_motion_ik, "calculate2BoneCCDIK(via.mat4, via.mat4, via.mat4, via.vec3, via.motion.AxisDirection, via.motion.AxisDirection)", - w0, w1, w2, last_right_hand_position - position, 262147, 196610) +local head_hash = nil +local center_hash = nil +local chest_hash = nil - local world_matrix = transform:call("get_WorldMatrix") +local known_hashes = {} - w0 = world_matrix * w0 - w1 = world_matrix * w1 - w2 = world_matrix * w2 +local function get_joint_hash(transform, motion, name) + if not known_hashes[transform] then + known_hashes[transform] = {} + end - joint:call("set_Position", w0[3]) - joint:call("set_Rotation", w0:to_quat()) + local hash = known_hashes[transform][name] - forearm:call("set_Position", w1[3]) - forearm:call("set_Rotation", w1:to_quat()) + if hash then + return hash + end - upper_arm:call("set_Position", w2[3]) - upper_arm:call("set_Rotation", w2:to_quat())]] - end + local joint = transform:call("getJointByName", name) - --joint:call("set_Position", new_pos) - --joint:call("set_Rotation", new_rotation) - end + if not joint then + log.debug("Failed to get " .. name .. " joint") + return nil end - inside_transform_count = inside_transform_count - 1 -end + hash = joint:call("get_NameHash") + log.info(name .. " hash: " .. string.format("%x", hash)) ---[[local function left_hand_ik_update(transform) - --player_data.left_hand_ik_transform:call("set_Position", last_left_hand_position) - --player_data.left_hand_ik:get_field("Joint2"):call("set_Position", last_left_hand_position) + known_hashes[transform][name] = hash + + return hash end -local function right_hand_ik_update(transform) - --player_data.right_hand_ik_transform:call("set_Position", last_right_hand_position) -end]] +local zero_vec = Vector3f.new(0, 0, 0) -local function update_player_data() - if not player or player ~= get_localplayer() then - player = get_localplayer() - else - return - end +local function update_body_ik(camera_rotation, camera_pos) + if not re8.player then return end - log.info("updating player data") - player_data = {} + local player = re8.player + local ik_leg = player:call("getComponent(System.Type)", sdk.typeof("via.motion.IkLeg")) - if not player then - log.info("no player") - return - end + if not ik_leg then + ik_leg = player:call("createComponent(System.Type)", sdk.typeof("via.motion.IkLeg")) - player_data.transform = player:call("get_Transform") - player_data.updater = get_component(player, "app.PlayerUpdater") - player_data.hand_touch = get_component(player, "app.PlayerHandTouch") - player_data.game_event_action_controller = get_component(player, "app.GameEventActionController") + if not ik_leg then + log.error("Failed to create IK leg component") + return + end + end - if not player_data.updater or not player_data.hand_touch or not player_data.game_event_action_controller then - log.info("no player updater or hand touch") - player = nil - player_data = {} + if re8.is_in_cutscene or not vrmod:is_hmd_active() then + --ik_leg:call("set_Enabled", false) + ik_leg:call("set_CenterOffset", Vector3f.new(0, 0, 0)) return + else + ik_leg:call("set_Enabled", true) end - player_data.reference = player_data.updater:get_field("playerContainer") + local motion = player:call("getComponent(System.Type)", sdk.typeof("via.motion.Motion")) - if not player_data.reference then - log.info("no player reference") - player = nil - player_data = {} + if not motion then + log.error("Failed to get motion component") return end + local transform = player:call("get_Transform") - local hand_ik = player_data.hand_touch:get_field("HandIK"):get_elements() - --local hand_ik = { player_data.reference:get_field("k__BackingField"), player_data.reference:get_field("k__BackingField") } + if not head_hash then + head_hash = get_joint_hash(transform, motion, "Head") + end - if #hand_ik < 2 then - log.info("no hand ik") - player = nil - player_data = {} - return + --[[if not chest_hash then + chest_hash = get_joint_hash(transform, motion, "Chest") + end]] + + if not center_hash then + center_hash = get_joint_hash(transform, motion, "Hip") end - player_data.right_hand_ik = hand_ik[1] - player_data.left_hand_ik = hand_ik[2] - player_data.right_hand_ik_object = player_data.right_hand_ik:get_field("TargetGameObject") - player_data.left_hand_ik_object = player_data.left_hand_ik:get_field("TargetGameObject") - player_data.right_hand_ik_transform = player_data.right_hand_ik:get_field("Target") - player_data.left_hand_ik_transform = player_data.left_hand_ik:get_field("Target") - player_data.is_in_cutscene = false + local transform_rot = transform:call("get_Rotation") + local transform_pos = transform:call("get_Position") + + local head_joint = transform:call("getJointByHash", head_hash) + --local chest_joint = transform:call("getJointByHash", chest_hash) + local hip_joint = transform:call("getJointByHash", center_hash) + + --local head_index = motion:call("getJointIndexByNameHash", head_hash) + --chest_index = motion:call("getJointIndexByNameHash", chest_hash) + --local original_head_pos = motion:call("getWorldPosition", head_index) + --local original_chest_pos = motion:call("getWorldPosition", chest_index) + + local normal_dir = camera_rotation * Vector3f.new(0, 0, 1) + local flattened_dir = camera_rotation * Vector3f.new(0, 0, 1) + flattened_dir.y = 0.0 + flattened_dir:normalize() + + local original_head_pos = calculate_tpose_world(head_joint, 4) + (flattened_dir * (math.abs(normal_dir.y) * -0.1)) + (flattened_dir * 0.025) + + --original_head_pos = transform_rot * original_head_pos + --original_head_pos = transform:call("getJointByName", "root"):call("get_Rotation") * original_head_pos + --original_head_pos = transform_rot * transform:calculate_base_transform(head_joint)[3] + --original_chest_pos = transform_rot * original_chest_pos + + --original_head_pos.x = original_chest_pos.x + --original_head_pos.z = original_chest_pos.z + + --[[local center_index = motion:call("getJointIndexByNameHash", center_hash) + local original_center_pos = motion:call("getWorldPosition", center_index) + + original_center_pos = transform_rot * original_center_pos + + local current_center_pos = transform:call("getJointByHash", center_hash):call("get_Position") + local center_diff = (original_center_pos * -1.0) + center_diff.y = 0.0]] + + --local current_head_pos = transform:call("getJointByName", "Head"):call("get_Position") + + --[[local center_joint = transform:call("getJointByName", "Hip") - log.info("SETTING TRANFORM!!!") + local center_pos = center_joint:call("get_Position") + local transform_pos = transform:call("get_Position")]] - re.on_pre_update_transform(player_data.transform, on_pre_update_player_transform) - --re.on_pre_update_transform(player_data.right_hand_ik_transform, right_hand_ik_update) - --re.on_pre_update_transform(player_data.left_hand_ik_transform, left_hand_ik_update) + local diff_to_camera = ((camera_pos) - original_head_pos) + + --ik_leg:call("set_CenterJointName", "Hip") + ik_leg:call("set_CenterOffset", diff_to_camera) + ik_leg:call("setCenterAdjust", 0) + ik_leg:call("set_CenterPositionCtrl", 2) -- world offset + ik_leg:call("set_GroundContactUpDistance", 0.0) -- Fixes the whole player being jarringly moved upwards. + --ik_leg:call("set_UpdateTiming", 2) -- ConstraintsBegin end local function on_pre_shoot(args) - if not vrmod:is_hmd_active() then + if not vrmod:is_hmd_active() or not vrmod:is_using_controllers() then return end + update_hand_ik() + local weapon = sdk.to_managed_object(args[2]) local ray = args[3] - sdk.set_native_field(ray, ray_typedef, "from", last_muzzle_pos) - sdk.set_native_field(ray, ray_typedef, "dir", last_muzzle_forward) + if is_re7 then + local muzzle_joint = weapon:call("get_muzzleJoint") + + if muzzle_joint then + local muzzle_pos = joint_get_position:call(muzzle_joint) + local muzzle_forward = joint_get_rotation:call(muzzle_joint) * Vector3f.new(0, 0, 1) + + local pos = muzzle_pos + (muzzle_forward * 0.01) + local from = Vector4f.new(pos.x, pos.y, pos.z, 1.0) + local dir = Vector4f.new(forward.x, forward.y, forward.z, 0.0) + + -- nudge the start position slightly forward because + -- apparently the bullets can collide with the weapon.... wtf + sdk.set_native_field(ray, ray_typedef, "from", from) + sdk.set_native_field(ray, ray_typedef, "dir", dir) + else + log.info("No muzzle joint found") + end + elseif is_re8 then + local pos = last_muzzle_pos + (last_muzzle_forward * 0.01) + local from = Vector4f.new(pos.x, pos.y, pos.z, 1.0) + local dir = Vector4f.new(last_muzzle_forward.x, last_muzzle_forward.y, last_muzzle_forward.z, 0.0) + + sdk.set_native_field(ray, ray_typedef, "from", pos) + sdk.set_native_field(ray, ray_typedef, "dir", dir) + end --sdk.call_native_func(ray, ray_typedef, ".ctor(via.vec3, via.vec3)", last_muzzle_pos, last_muzzle_forward) end @@ -515,72 +764,523 @@ local function on_post_shoot(retval) return retval end -sdk.hook(sdk.find_type_definition("app.WeaponGunCore"):get_method("shoot"), on_pre_shoot, on_post_shoot) +if is_re7 then + sdk.hook(sdk.find_type_definition("app.WeaponGun"):get_method("shoot"), on_pre_shoot, on_post_shoot) +elseif is_re8 then + sdk.hook(sdk.find_type_definition("app.WeaponGunCore"):get_method("shoot"), on_pre_shoot, on_post_shoot) +end local old_camera_rot = nil local old_camera_pos = nil ---[[local function on_pre_playercamera_lateupdate(args) +-- let player look at interaction elements with the camera +local function on_pre_interact_manager_lateupdate(args) + if not vrmod:is_hmd_active() then + return + end + local camera = sdk.get_primary_camera() - local camera_gameobject = camera:call("get_GameObject") - local camera_transform = camera_gameobject:call("get_Transform") + local camera_gameobject = component_get_gameobject:call(camera) + local camera_transform = gameobject_get_transform:call(camera_gameobject) - local hmd_transform = vrmod:get_transform(0) - local hmd_rotation = hmd_transform:to_quat() + local joint = transform_get_joints:call(camera_transform)[0] - old_camera_rot = camera_transform:call("get_Rotation") - camera_transform:call("set_Rotation", last_camera_matrix:to_quat()) + old_camera_rot = joint_get_rotation:call(joint) + old_camera_pos = joint_get_position:call(joint) + + joint_set_rotation:call(joint, last_camera_matrix:to_quat()) + joint_set_position:call(joint, last_camera_matrix[3]) end -local function on_post_playercamera_lateupdate(retval) +local function on_post_interact_manager_lateupdate(retval) + if not vrmod:is_hmd_active() then + return + end local camera = sdk.get_primary_camera() - local camera_gameobject = camera:call("get_GameObject") - local camera_transform = camera_gameobject:call("get_Transform") + local camera_gameobject = component_get_gameobject:call(camera) + local camera_transform = gameobject_get_transform:call(camera_gameobject) + + local joint = transform_get_joints:call(camera_transform)[0] - --camera_transform:call("set_Rotation", old_camera_rot) + joint_set_rotation:call(joint, old_camera_rot) + joint_set_position:call(joint, old_camera_pos) return retval end -sdk.hook(sdk.find_type_definition("app.PlayerCamera"):get_method("lateUpdate"), on_pre_playercamera_lateupdate, on_post_playercamera_lateupdate)]] +sdk.hook( + sdk.find_type_definition("app.InteractManager"):get_method("doLateUpdate"), + on_pre_interact_manager_lateupdate, + on_post_interact_manager_lateupdate +) + +-- force the gui to recenter when opening the inventory +if is_re7 then + sdk.hook( + sdk.find_type_definition("app.MenuManager"):get_method("openInventoryMenu"), + function(args) + last_gui_forced_slerp = os.clock() + end, + function(retval) + return retval + end + ) +elseif is_re8 then + sdk.hook( + sdk.find_type_definition("app.GUIInventory"):get_method("openInventory"), + function(args) + last_gui_forced_slerp = os.clock() + end, + function(retval) + return retval + end + ) +end + +local last_camera_update_args = nil +local last_cutscene_state = false +local last_time_not_maximum_controllable = 0.0 +local GUI_MAX_SLERP_TIME = 1.5 + +local function slerp_gui(new_gui_quat) + if re8.movement_speed_rate > 0.0 then + last_gui_forced_slerp = os.clock() - ((1.0 - re8.movement_speed_rate)) + end + + last_gui_dot = last_gui_quat:dot(new_gui_quat) + local dot_dist = 1.0 - math.abs(last_gui_dot) + local dot_ang = math.acos(math.abs(last_gui_dot)) * (180.0 / math.pi) + last_gui_dot = dot_ang + + local now = os.clock() + + -- trigger gui slerp + if dot_ang >= 20 or re8.is_in_cutscene then + last_gui_forced_slerp = now + end + + local slerp_time_diff = now - last_gui_forced_slerp + + if slerp_time_diff <= GUI_MAX_SLERP_TIME then + if dot_ang >= 10 then + last_gui_forced_slerp = now + end + + last_gui_quat = last_gui_quat:slerp(new_gui_quat, dot_dist * math.max((GUI_MAX_SLERP_TIME - slerp_time_diff) * re8.delta_time, 0.0)) + end + + if re8.is_in_cutscene then + vrmod:recenter_gui(last_gui_quat) + else + vrmod:recenter_gui(last_gui_quat * new_gui_quat:inverse()) + end +end + +local last_hmd_active_state = false + +local function fix_player_camera(player_camera) + if not vrmod:is_hmd_active() then + -- so the camera doesnt go wacky + if last_hmd_active_state then + -- disables the body IK component + update_body_ik(nil, nil) + + vrmod:set_gui_rotation_offset(Quaternion.identity()) + vrmod:recenter_view() + + last_hmd_active_state = false + end + + -- Restore the vertical camera movement after taking headset off/not using controllers + if was_vert_limited then + --local player_camera = sdk.to_managed_object(args[2]) + local base_transform_solver = player_camera:get_field("BaseTransSolver") + + if base_transform_solver then + local camera_controller = base_transform_solver:get_field("CurrentController") + + -- Stop the player from rotating the camera vertically + if camera_controller then + camera_controller:set_field("IsVerticalRotateLimited", false) + end + end + + was_vert_limited = false + end + + last_real_camera_rotation = nil + last_real_camera_joint_rotation = nil + + return retval + end + + last_hmd_active_state = true + + local base_transform_solver = player_camera:get_field("BaseTransSolver") + local is_maximum_controllable = true + + if base_transform_solver then + local current_type = base_transform_solver:get_field("k__BackingField") + + if is_re8 then + current_type = current_type:get_field("Value") + end + + if current_type ~= 0 then -- MaximumOperatable + re8.is_in_cutscene = true + is_maximum_controllable = false + last_time_not_maximum_controllable = os.clock() + else + if os.clock() - last_time_not_maximum_controllable <= 1.0 then + re8.is_in_cutscene = true + end + end + end -local function on_pre_interact_manager_lateupdate(args) local camera = sdk.get_primary_camera() + + -- apply the camera rot to the real camera local camera_gameobject = camera:call("get_GameObject") local camera_transform = camera_gameobject:call("get_Transform") - local hmd_transform = vrmod:get_transform(0) - local hmd_rotation = hmd_transform:to_quat() + local wants_recenter = false + + if re8.is_in_cutscene and not last_cutscene_state then + --vrmod:recenter_view() + + -- force the gui to be recentered when we exit the cutscene + last_gui_forced_slerp = os.clock() + last_gui_quat = Quaternion.identity() + wants_recenter = true + --queue_recenter = true + + vrmod:recenter_gui(last_gui_quat) + elseif not re8.is_in_cutscene and last_cutscene_state then + last_gui_forced_slerp = os.clock() + last_gui_quat = vrmod:get_rotation(0):to_quat():inverse() + wants_recenter = true + + vrmod:recenter_gui(vrmod:get_rotation(0):to_quat()) + end + + local camera_rot = transform_get_rotation:call(camera_transform) + local camera_pos = transform_get_position:call(camera_transform) + + local camera_rot_pre_hmd = Quaternion.new(camera_rot.w, camera_rot.x, camera_rot.y, camera_rot.z) + local camera_pos_pre_hmd = Vector3f.new(camera_pos.x, camera_pos.y, camera_pos.z) + + -- So the camera doesn't spin uncontrollably when attacking or the camera moves outside of player control. + local camera_rot_no_shake = player_camera:get_field("k__BackingField") + + vrmod:apply_hmd_transform(camera_rot_no_shake, Vector3f.new(0, 0, 0)) + vrmod:apply_hmd_transform(camera_rot, camera_pos) + + local camera_joint = camera_transform:call("get_Joints")[0] + + -- Transform is used for things like Ethan's light + -- and determining where the player is looking + transform_set_position:call(camera_transform, camera_pos) + transform_set_rotation:call(camera_transform, camera_rot) + + last_real_camera_joint_rotation = camera_rot_pre_hmd + last_real_camera_joint_pos = camera_pos_pre_hmd + + -- Joint is used for the actual final rendering of the game world + --if not wants_recenter then + if re8.is_in_cutscene then + joint_set_position:call(camera_joint, camera_pos_pre_hmd) + joint_set_rotation:call(camera_joint, camera_rot_pre_hmd) + else + local rot_delta = camera_rot_pre_hmd:inverse() * camera_rot + + local forward = rot_delta * Vector3f.new(0, 0, 1) + forward = Vector3f.new(forward.x, 0.0, forward.z):normalized() + + joint_set_position:call(camera_joint, camera_pos_pre_hmd) + joint_set_rotation:call(camera_joint, camera_rot_pre_hmd * forward:to_quat()) + end + + --last_gui_offset = last_gui_offset * (camera_rot:inverse() * camera_rot_pre_hmd) + + -- just update the body IK right after we update the camera. + update_body_ik(camera_rot, camera_pos) + + -- Slerp the gui around + slerp_gui(re8.is_in_cutscene and (camera_rot_pre_hmd * camera_rot:inverse()) or vrmod:get_rotation(0):to_quat():inverse()) + + local fixed_dir = ((neg_forward_identity * camera_rot_no_shake) * Vector3f.new(0, 0, -1)):normalized() + local fixed_rot = fixed_dir:to_quat() + --local fixed_rot = neg_forward_identity * camera_rot + + player_camera:set_field("k__BackingField", fixed_rot) + player_camera:set_field("k__BackingField", camera_pos) + + player_camera:set_field("CameraRotationWithMovementShake", fixed_rot) + --player_camera:set_field("CameraPositionWithMovementShake", camera_pos) + player_camera:set_field("CameraRotationWithCameraShake", fixed_rot) + --player_camera:set_field("CameraPositionWithCameraShake", camera_pos) + player_camera:set_field("PrevCameraRotation", fixed_rot) + --player_camera:set_field("OldCameraRotation", fixed_rot) + --player_camera:set_field("InterpRotationStart", fixed_rot) + --player_camera:set_field("k__BackingField", fixed_rot) + --player_camera:set_field("k__BackingField", fixed_rot) + + local camera_controller_param = player_camera:get_field("CameraCtrlParam") + + if camera_controller_param then + camera_controller_param:set_field("CameraRotation", fixed_rot) + end + + local base_transform_solver = player_camera:get_field("BaseTransSolver") + + if base_transform_solver then + local camera_controller = base_transform_solver:get_field("CurrentController") + + if not camera_controller then + camera_controller = base_transform_solver:get_field("k__BackingField") + end + + -- Stop the player from rotating the camera vertically + if camera_controller then + local camera_controller_rot = Quaternion.identity() - old_camera_rot = camera_transform:call("get_Rotation") - old_camera_pos = camera_transform:call("get_Position") - camera_transform:call("set_Rotation", last_camera_matrix:to_quat()) - camera_transform:call("set_Position", last_camera_matrix[3]) + if re8.is_in_cutscene then + if is_re7 then + camera_controller_rot = camera_controller:get_field("k__BackingField") + elseif is_re8 then + camera_controller_rot = camera_controller:get_field("k__BackingField") + end + else + camera_controller_rot = Quaternion.new(fixed_rot.w, fixed_rot.x, fixed_rot.y, fixed_rot.z) + end + + local controller_forward = camera_controller_rot * Vector3f.new(0.0, 0.0, 1.0) + controller_forward.y = 0.0 + + camera_controller_rot = controller_forward:normalized():to_quat() + + --if wants_recenter or not re8.is_in_cutscene then + if not re8.is_in_cutscene or is_maximum_controllable then + if not re8.is_in_cutscene then + vrmod:recenter_view() + end + + if is_re7 then + camera_controller:set_field("k__BackingField", camera_controller_rot) + elseif is_re8 then + camera_controller:set_field("k__BackingField", camera_controller_rot) + end + end + + base_transform_solver:set_field("k__BackingField", camera_controller_rot) + + --[[for i, controller in ipairs(base_transform_solver:get_field("CameraControllers"):get_elements()) do + controller:set_field("k__BackingField", camera_controller_rot) + controller:set_field("RelativeCamRotAtEndOfMotion", camera_controller_rot) + end]] + + --[[local maximum_operatable_controller = base_transform_solver:get_field("CameraControllers")[0] + + if maximum_operatable_controller ~= camera_controller then + maximum_operatable_controller:set_field("k__BackingField", camera_controller_rot) + end]] + + camera_controller:set_field("IsVerticalRotateLimited", true) + was_vert_limited = true + end + end + + -- stops the camera from pivoting around the player + -- so we can use VR to look around without the body sticking out + --if vrmod:is_using_controllers() then + if not re8.is_in_cutscene then + local param_container = player_camera:get_field("_CurrentParamContainer") + + if param_container == nil then + param_container = player_camera:get_field("CurrentParamContainer") + end + + if param_container ~= nil then + local posture_param = param_container:get_field("PostureParam") + + if posture_param ~= nil then + local current_camera_offset = posture_param:get_field("CameraOffset") + current_camera_offset.x = 0.0 + current_camera_offset.z = 0.0 + + posture_param:set_field("CameraOffset", current_camera_offset) + end + end + end + + local look_ray_offset = player_camera:get_type_definition():get_field("LookRay"):get_offset_from_base() + local shoot_ray_offset = player_camera:get_type_definition():get_field("ShootRay"):get_offset_from_base() + local look_ray = player_camera:get_address() + look_ray_offset + local shoot_ray = player_camera:get_address() + shoot_ray_offset + + sdk.set_native_field(sdk.to_ptr(look_ray), ray_typedef, "from", camera_pos) + sdk.set_native_field(sdk.to_ptr(look_ray), ray_typedef, "dir", fixed_dir) + sdk.set_native_field(sdk.to_ptr(shoot_ray), ray_typedef, "from", camera_pos) + sdk.set_native_field(sdk.to_ptr(shoot_ray), ray_typedef, "dir", fixed_dir) + + last_cutscene_state = re8.is_in_cutscene end -local function on_post_interact_manager_lateupdate(retval) +local function on_pre_player_camera_update(args) + last_camera_update_args = args + + if not vrmod:is_hmd_active() then + return + end + + --local player_camera = sdk.to_managed_object(args[2]) + --fix_player_camera(player_camera) + + --[[local player_camera = sdk.to_managed_object(args[2]) + + local camera = sdk.get_primary_camera() + local camera_gameobject = camera:call("get_GameObject") + local camera_transform = camera_gameobject:call("get_Transform")]] + --last_real_camera_rotation = camera_transform:call("get_Rotation") + --last_real_camera_joint_rotation = camera_transform:call("get_Joints")[0]:call("get_Rotation") + + --return sdk.PreHookResult.SKIP_ORIGINAL +end + +local function on_post_player_camera_update(retval) + local args = last_camera_update_args + + local player_camera = sdk.to_managed_object(args[2]) + fix_player_camera(player_camera) + + return retval +end + +local function on_pre_player_interp_rotation(args) + local player_camera = sdk.to_managed_object(args[2]) + local camera = sdk.get_primary_camera() local camera_gameobject = camera:call("get_GameObject") local camera_transform = camera_gameobject:call("get_Transform") - camera_transform:call("set_Rotation", old_camera_rot) - camera_transform:call("set_Position", old_camera_pos) + re8.is_in_cutscene = true + fix_player_camera(player_camera) +end +local function on_post_player_interp_rotation(retval) return retval end -sdk.hook(sdk.find_type_definition("app.InteractManager"):get_method("doLateUpdate"), on_pre_interact_manager_lateupdate, on_post_interact_manager_lateupdate) +-- Normal Ethan camera +--[[sdk.hook( + sdk.find_type_definition("app.PlayerCamera"):get_method("interpRotation"), + on_pre_player_interp_rotation, + on_post_player_interp_rotation +)]] + +-- Normal Ethan camera +sdk.hook( + sdk.find_type_definition("app.PlayerCamera"):get_method("lateUpdate"), + on_pre_player_camera_update, + on_post_player_camera_update +) + +if is_re7 then + -- Not a hero camera + sdk.hook( + sdk.find_type_definition("app.CH8PlayerCamera"):get_method("lateUpdate"), + on_pre_player_camera_update, + on_post_player_camera_update + ) + + -- idk the other DLC? + sdk.hook( + sdk.find_type_definition("app.CH9PlayerCamera"):get_method("lateUpdate"), + on_pre_player_camera_update, + on_post_player_camera_update + ) +end ---re.on_pre_application_entry("UpdateBehavior", on_pre_interact_manager_lateupdate) ---re.on_application_entry("LateUpdateBehavior", on_post_interact_manager_lateupdate) +-- Zero out the camera shake +sdk.hook( + sdk.find_type_definition("app.PlayerCamera"):get_method("updateCameraShakeValue"), + function(args) + if not cfg.all_camera_shake then + return sdk.PreHookResult.SKIP_ORIGINAL + end + end, + function(retval) + if not vrmod:is_hmd_active() or not vrmod:is_using_controllers() then + return retval + end + + local args = last_camera_update_args + if args == nil then return retval end + + local player_camera = sdk.to_managed_object(args[2]) + + local zero_quat = Quaternion.new(1, 0, 0, 0) + local zero_vec = Vector3f.new(0, 0, 0) + + if not cfg.movement_shake then + player_camera:set_field("MovementShakePosition", zero_vec) + player_camera:set_field("MovementShakeRotation", zero_quat) + end + + return retval + end +) + +local function on_pre_upper_vertical_update(args) + if not vrmod:is_hmd_active() or not vrmod:is_using_controllers() then + return + end + + --[[local upper_vertical = sdk.to_managed_object(args[2]) + + if not last_camera_update_args then return end + local player_camera = sdk.to_managed_object(last_camera_update_args[2]) + + local camera_rot = player_camera:get_field("k__BackingField") + local camera_pos = player_camera:get_field("k__BackingField") + + vrmod:apply_hmd_transform(camera_rot, camera_pos) + + player_camera:set_field("k__BackingField", camera_rot) + player_camera:set_field("k__BackingField", camera_pos) + + player_camera:set_field("CameraRotationWithMovementShake", camera_rot) + player_camera:set_field("CameraPositionWithMovementShake", camera_pos) + player_camera:set_field("CameraRotationWithCameraShake", camera_rot) + player_camera:set_field("CameraPositionWithCameraShake", camera_pos)]] + --player_camera:set_field("OtherShakeRotation", camera_rot) + --player_camera:set_field("OtherShakePosition", camera_pos) +end + +local function on_post_upper_vertical_update(retval) + return retval +end + +if is_re7 then + sdk.hook( + sdk.find_type_definition("app.PlayerUpperVerticalRotate"):get_method("doLateUpdate"), + on_pre_upper_vertical_update, + on_post_upper_vertical_update + ) +elseif is_re8 then + sdk.hook( + sdk.find_type_definition("app.PlayerUpperVerticalRotate"):get_method("lateUpdate"), + on_pre_upper_vertical_update, + on_post_upper_vertical_update + ) +end --- function to check if the player's hands are facing generally up and in front of the camera --- so we can press the "LB" button in-game to block local function check_player_hands_up() - update_player_data() + local player = re8.player + if not player then - player_data.wants_block = false + re8.wants_block = false return end @@ -590,7 +1290,7 @@ local function check_player_hands_up() local controllers = vrmod:get_controllers() if #controllers < 2 then - player_data.wants_block = false + re8.wants_block = false return end @@ -614,7 +1314,7 @@ local function check_player_hands_up() local first_test = left_hand_in_front and right_hand_in_front if not first_test then - player_data.wants_block = false + re8.wants_block = false return end @@ -625,71 +1325,399 @@ local function check_player_hands_up() left_hand_up = left_hand_up_dot >= 0.5 right_hand_up = right_hand_up_dot >= 0.5 - player_data.wants_block = left_hand_up and right_hand_up + re8.wants_block = left_hand_up and right_hand_up --log.info("left hand dot: " .. tostring(left_hand_dot)) --log.info("right hand dot: " .. tostring(right_hand_dot)) end +local should_reset_view_no_player = false + +re.on_pre_application_entry("UpdateBehavior", function() + check_player_hands_up() + + if not re8.player then + if should_reset_view_no_player then + vrmod:recenter_view() + vrmod:set_gui_rotation_offset(Quaternion.identity()) + should_reset_view_no_player = false + end + else + should_reset_view_no_player = true + end +end) + +re.on_pre_application_entry("PrepareRendering", function() + update_hand_ik() +end) + +re.on_application_entry("UpdateMotion", function() + --[[local camera = sdk.get_primary_camera() + + -- apply the camera rot to the real camera + local camera_gameobject = camera:call("get_GameObject") + local camera_transform = camera_gameobject:call("get_Transform") + + local camera_rot = camera_transform:call("get_Rotation") + local camera_pos = camera_transform:call("get_Position") + + local camera_rot_pre_hmd = Quaternion.new(camera_rot.w, camera_rot.x, camera_rot.y, camera_rot.z) + + vrmod:apply_hmd_transform(neg_forward_identity * camera_rot, camera_pos) + + update_body_ik(camera_rot_pre_hmd, camera_pos)]] + + update_hand_ik() +end) + +--[[re.on_pre_application_entry("LateUpdateBehavior", function() + update_hand_ik() +end)]] + +re.on_application_entry("LateUpdateBehavior", function() + update_hand_ik() +end) + re.on_application_entry("UpdateHID", function() + --[[local padman = sdk.get_managed_singleton(sdk.game_namespace("PadManager")) + + if padman then + update_padman(padman) + end]] end) -re.on_application_entry("BeginRendering", function() - update_player_data() - if not player then return end +re.on_application_entry("LockScene", function() + + --[[if not vrmod:is_hmd_active() then return end + local camera = sdk.get_primary_camera() - --on_pre_update_player_transform(player_data.transform) + if camera ~= nil and last_real_camera_joint_rotation ~= nil then + local camera_gameobject = camera:call("get_GameObject") + local camera_transform = camera_gameobject:call("get_Transform") + local camera_joint = camera_transform:call("get_Joints")[0] - check_player_hands_up() + joint_set_position:call(camera_joint, last_real_camera_joint_pos) + joint_set_rotation:call(camera_joint, last_real_camera_joint_rotation) + end]] +end) + +local last_roomscale_failure = os.clock() + +re.on_pre_application_entry("UnlockScene", function() + if queue_recenter then + vrmod:recenter_view() + queue_recenter = false + end + + if not vrmod:is_hmd_active() then last_roomscale_failure = os.clock() return end + if not re8.player or not re8.transform then last_roomscale_failure = os.clock() return end + if not last_camera_matrix then last_roomscale_failure = os.clock() return end + if re8.is_in_cutscene then last_roomscale_failure = os.clock() return end + + if os.clock() - last_roomscale_failure < 1.0 then return end + + local standing_origin = vrmod:get_standing_origin() + local hmd_pos = vrmod:get_position(0) + + hmd_pos.y = 0.0 + standing_origin.y = 0.0 + + if (hmd_pos - standing_origin):length() >= 0.01 then + standing_origin = vrmod:get_standing_origin() + hmd_pos.y = standing_origin.y + local old_standing_origin = Vector4f.new(standing_origin.x, standing_origin.y, standing_origin.z, standing_origin.w) + + standing_origin = standing_origin:lerp(hmd_pos, (hmd_pos - standing_origin):length() * 0.1) + + local standing_diff = standing_origin - old_standing_origin + + vrmod:set_standing_origin(standing_origin) + + local player_pos = transform_get_position:call(re8.transform) + local lerp_to = Vector3f.new(last_camera_matrix[3].x, player_pos.y, last_camera_matrix[3].z) + + player_pos = player_pos + ((lerp_to - player_pos):normalized() * standing_diff:length()) + --player_pos:lerp(lerp_to, 0.1) + --player_pos.x = last_camera_matrix[3].x + --player_pos.z = last_camera_matrix[3].z + + --transform_set_position:call(re8.transform, player_pos) + re8.transform:set_position(player_pos, true) -- NO DIRTY + end +end) + +re.on_application_entry("BeginRendering", function() + if not vrmod:is_hmd_active() then return end local camera = sdk.get_primary_camera() if camera ~= nil then + --local camera_gameobject = camera:call("get_GameObject") + --[[local camera_transform = camera_gameobject:call("get_Transform") + local camera_joint = camera_transform:call("get_Joints")[0] + + last_camera_matrix = joint_get_rotation:call(camera_joint):to_mat4() + last_camera_matrix[3] = joint_get_position:call(camera_joint)]] + last_camera_matrix = camera:call("get_WorldMatrix") end - local game_event_action = player_data.game_event_action_controller:get_field("_GameEventAction") - - if game_event_action ~= nil then - local is_motion_play = player_data.game_event_action_controller:get_field("_isMotionPlay") + if is_re8 and re8.weapon then + -- for some reason calling get_muzzleJoint causes lua to randomly freak out + -- so we're just going to directly grab the field instead + local muzzle_joint = re8.weapon:get_field("MuzzleJoint") - if is_motion_play then - player_data.is_in_cutscene = true - else - player_data.is_in_cutscene = false + if muzzle_joint then + local muzzle_position = muzzle_joint:call("get_Position") + local muzzle_rotation = muzzle_joint:call("get_Rotation") + + last_muzzle_pos = muzzle_position + last_muzzle_rot = muzzle_rotation + last_muzzle_forward = muzzle_joint:call("get_AxisZ") end + end +end) + +re.on_config_save(function() + json.dump_file(cfg_path, cfg) +end) + +local type_to_table = function(obj) +end + +local function obj_to_table(obj, seen_objects) + seen_objects = seen_objects or {} + + if obj == nil or seen_objects[obj] ~= nil and seen_objects[obj] > 0 then + return { __null = true } + end + + if tostring(type(obj)) ~= "userdata" then + --log.debug(tostring(obj)) + return obj + end + + local out = {} + + local readable_type_name = tostring(getmetatable(obj).__name) + + --log.debug(readable_type_name) + + if readable_type_name:find("glm::mat<4,4") then + out = { + { x = obj[0][0], y = obj[0][1], z = obj[0][2], w = obj[0][3]}, + { x = obj[1][0], y = obj[1][1], z = obj[1][2], w = obj[1][3]}, + { x = obj[2][0], y = obj[2][1], z = obj[2][2], w = obj[2][3]}, + { x = obj[3][0], y = obj[3][1], z = obj[3][2], w = obj[3][3]}, + } + + return out + elseif readable_type_name:find("glm::vec<4") or readable_type_name:find("glm::qua<") then + out = { + x = obj.x, + y = obj.y, + z = obj.z, + w = obj.w + } + + return out + elseif readable_type_name:find("glm::vec<3") then + out = { + x = obj.x, + y = obj.y, + z = obj.z + } + + return out + elseif readable_type_name:find("glm::vec<2") then + out = { + x = obj.x, + y = obj.y + } + + return out + end + + if seen_objects[obj] ~= nil then + seen_objects[obj] = seen_objects[obj] + 1 else - player_data.is_in_cutscene = false + seen_objects[obj] = 1 end - local player_gun = player_data.updater:call("get_playerGun") + if getmetatable(obj).get_type_definition == nil then + out = { __REFRAMEWORK_UNIMPLEMENTED_TYPE = getmetatable(obj).__name } - if not player_gun then - return + return out end - local equipped_weapon = player_gun:call("get_equipWeaponObject") + out["__type"] = obj:get_type_definition():get_full_name() - if not equipped_weapon then - return + if obj:get_type_definition():is_a("via.GameObject") then + local components = obj:call("get_Components") + components = components and components:get_elements() or {} + + out["__components"] = { __num = #components } + + for i, component in ipairs(components) do + out["__components"][tostring(i)] = obj_to_table(component, seen_objects) + end end - -- for some reason calling get_muzzleJoint causes lua to randomly freak out - -- so we're just going to directly grab the field instead - local muzzle_joint = equipped_weapon:get_field("MuzzleJoint") + --log.debug(tostring(type(obj))) + --log.debug(tostring(obj) .. ": " .. tostring(getmetatable(obj).__name)) + local fields = obj:get_type_definition():get_fields() - if not muzzle_joint then - return + for i, field in ipairs(fields) do + if not field:is_static() then + local field_type = field:get_type() + --log.debug("field: " .. field:get_name() .. " " .. field_type:get_full_name()) + local ok, value = pcall(obj.get_field, obj, field:get_name()) + + --log.debug(" " .. tostring(ok)) + + if not ok then + log.debug("error on field: " .. obj:get_type_definition():get_full_name() .. "." .. field:get_name()) + end + + if not ok then goto continue end + + --log.debug(field:get_name()) + local type_definition = nil + + if value ~= nil and tostring(type(value)) == "userdata" and getmetatable(value).get_type_definition ~= nil then + type_definition = value:get_type_definition() + end + + if type_definition and type_definition:is_array() and tostring(type(value)) == "userdata" then + local array = {} + local array_elems = value ~= nil and value:get_elements() or {} + + for i, elem in ipairs(array_elems) do + --array[i] = obj_to_table(elem) + end + + out[field:get_name()] = array + elseif field_type:is_primitive() or field_type:is_enum() then + --out[field:get_name()] = value + elseif not field_type:is_value_type() then + if tostring(type(value)) == "userdata" then + --log.debug(tostring(value) .. ": " .. tostring(getmetatable(value).__name)) + out[field:get_name()] = obj_to_table(value, seen_objects) + else + --out[field:get_name()] = value + end + else -- value type + --out[field:get_name()] = obj_to_table(value, seen_objects) + end + + ::continue:: + end + end + + seen_objects[obj] = seen_objects[obj] - 1 + + return out +end + +--[[local tbl = obj_to_table(__object_explorer_object) +json.dump_file("object_explorer/" .. __object_explorer_object_path .. ".json", tbl) + +collectgarbage("collect")]] -- force a GC to free up the memory + +re.on_draw_ui(function() + local changed = false + + changed, cfg.movement_shake = imgui.checkbox("Movement Shake", cfg.movement_shake) + changed, cfg.all_camera_shake = imgui.checkbox("All Other Camera Shakes", cfg.all_camera_shake) + + changed, left_hand_rotation_vec = imgui.drag_float3("Left Hand Rotation Offset", left_hand_rotation_vec, 0.005, -5.0, 5.0) + + if changed then + left_hand_rotation_offset = Quaternion.new(left_hand_rotation_vec):normalized() + end + + changed, right_hand_rotation_vec = imgui.drag_float3("Right Hand Rotation Offset", right_hand_rotation_vec, 0.005, -5.0, 5.0) + + if changed then + right_hand_rotation_offset = Quaternion.new(right_hand_rotation_vec):normalized() end - local muzzle_position = muzzle_joint:call("get_Position") - local muzzle_rotation = muzzle_joint:call("get_Rotation") + changed, left_hand_position_offset = imgui.drag_float4("Left Hand Position Offset", left_hand_position_offset, 0.005, -5.0, 5.0) + changed, right_hand_position_offset = imgui.drag_float4("Right Hand Position Offset", right_hand_position_offset, 0.005, -5.0, 5.0) - last_muzzle_pos = muzzle_position - last_muzzle_rot = muzzle_rotation - last_muzzle_forward = muzzle_joint:call("get_AxisZ") + if imgui.tree_node("Debug") then + imgui.text("Last GUI Dot: " .. tostring(last_gui_dot)) + + if imgui.tree_node("Player") then + object_explorer:handle_address(re8.player) + + imgui.tree_pop() + end + + if imgui.tree_node("Right Hand IK") then + local right_hand_ik = re8.right_hand_ik + + object_explorer:handle_address(right_hand_ik) + + imgui.tree_pop() + end + + if imgui.tree_node("Left Hand IK") then + local left_hand_ik = re8.left_hand_ik + + object_explorer:handle_address(left_hand_ik) + + imgui.tree_pop() + end + + if imgui.button("test dump") then + local d = function(name) + local obj = sdk.get_managed_singleton(name) + + if obj then + local tbl2 = obj_to_table(obj, {}) + json.dump_file("object_explorer/" .. obj:get_type_definition():get_full_name() .. ".json", tbl2) + end + end + + --d("app.VrGuiManager") + --d("app.vr.VrManager") + --d("app.GameManager") + d("app.ObjectManager") + end + + imgui.text("Num tasks: " .. tostring(re8.num_active_tasks)) + imgui.text("Has postural camera control: " .. tostring(re8.has_postural_camera_control)) + imgui.text("Is arm jacked: " .. tostring(re8.is_arm_jacked)) + imgui.text("Is motion play: " .. tostring(re8.is_motion_play)) + imgui.text("Is in cutscene: " .. tostring(re8.is_in_cutscene)) + + imgui.tree_pop() + end end) +local re8_inventory_names = { + "GUIInventory", + "GUIInventoryMenu", + "GUIInventoryTreasure", + "GUIInventoryCraft", + "GUIInventoryKeyItem", + "GUIMap" +} + +for i, v in ipairs(re8_inventory_names) do + re8_inventory_names[v] = true +end + +local reticle_names = { + "ReticleGUI", + "GUIReticle" +} + +for i, v in ipairs(reticle_names) do + reticle_names[v] = true +end + re.on_pre_gui_draw_element(function(element, context) if not vrmod:is_hmd_active() then return true end @@ -698,13 +1726,17 @@ re.on_pre_gui_draw_element(function(element, context) local name = game_object:call("get_Name") - log.info("drawing element: " .. name) + --log.info("drawing element: " .. name) - if name == "GUIReticle" then + if reticle_names[name] then if vrmod:is_using_controllers() then return false end end + if re8_inventory_names[name] then + last_inventory_open_time = os.clock() + end + return true end) \ No newline at end of file diff --git a/scripts/utility/RE8.lua b/scripts/utility/RE8.lua new file mode 100644 index 000000000..c117df553 --- /dev/null +++ b/scripts/utility/RE8.lua @@ -0,0 +1,394 @@ +if _re8lib ~= nil then + return _re8lib +end + +local game_name = reframework:get_game_name() +local is_re7 = game_name == "re7" +local is_re8 = game_name == "re8" + +if not is_re7 and not is_re8 then + error("Unsupported game: " .. game_name) +end + +local CallbackList = { + callbacks = {}, + + new = function(self, o) + o = o or {} + + self.__index = self + return setmetatable(o, self) + end, + + add = function(self, callback) + table.insert(self.callbacks, callback) + end, + + dispatch = function(self, args) + for i, callback in ipairs(self.callbacks) do + callback(args) + end + end +} + +local CallbackManager = { + callback_lists = {}, + + new = function(self, o) + o = o or {} + + return setmetatable(o, self) + end, + + __index = function(self, key) + local rawval = rawget(self, key) or rawget(getmetatable(self), key) + + if rawval ~= nil then + return rawval + end + + if not self.callback_lists[key] then + self.callback_lists[key] = CallbackList:new() + end + + return self.callback_lists[key] + end, +} + +local callbacks = CallbackManager:new() + +local function initialize_re8(re8) + re8 = re8 or {} + + re8.player = nil + re8.transform = nil + re8.weapon = nil + re8.weapon_gameobject = nil + re8.inventory = nil + re8.hand_touch = nil + re8.order = nil + re8.right_hand_ik = nil + re8.left_hand_ik = nil + re8.is_in_cutscene = false + re8.is_arm_jacked = false + re8.is_grapple_aim = false + re8.is_motion_play = false + re8.has_postural_camera_control = true + re8.updater = nil + re8.event_action_controller = nil + re8.game_event_action_controller = nil + re8.wants_block = false + re8.movement_speed_rate = 0.0 + re8.movement_speed_vector = Vector3f.new(0, 0, 0) + re8.num_active_tasks = 0 + re8.active_tasks = {} + re8.application = sdk.get_native_singleton("via.Application") + re8.application_type = sdk.find_type_definition("via.Application") + re8.delta_time = 0.0 + + return re8 +end + +local re8 = initialize_re8() + +local known_typeofs = {} +local known_invalids = {} + +local function get_component(game_object, type_name) + if known_invalids[type_name] then + return nil + end + + local t = known_typeofs[type_name] or sdk.typeof(type_name) + + if t == nil then + known_invalids[type_name] = true + return nil + end + + known_typeofs[type_name] = t + return game_object:call("getComponent(System.Type)", t) +end + +if is_re7 then + re8.get_localplayer = function() + local object_man = sdk.get_managed_singleton("app.ObjectManager") + + if not object_man then + return nil + end + + return object_man:get_field("PlayerObj") + end +elseif is_re8 then + re8.get_localplayer = function() + local propsman = sdk.get_managed_singleton("app.PropsManager") + + if not propsman then + return nil + end + + return propsman:get_field("k__BackingField") + end +end + +function re8.get_weapon_object(player) + if is_re7 then + return nil + elseif is_re8 then + if not re8.updater then + return nil + end + + local player_gun = re8.updater:call("get_playerGun") + + if not player_gun then + return nil + end + + local equipped_weapon = player_gun:call("get_equipWeaponObject") + + if not equipped_weapon then + return nil + end + + return equipped_weapon + end + + return nil +end + +function re8.update_in_cutscene_state() + re8.is_in_cutscene = re8.num_active_tasks > 0 or not re8.has_postural_camera_control or re8.is_arm_jacked or re8.is_motion_play +end + +re.on_pre_application_entry("UpdateBehavior", function() + re8.player = re8.get_localplayer() + local player = re8.player + + if player == nil or not re8.application then + initialize_re8(re8) + return + end + + re8.transform = player:call("get_Transform") + re8.inventory = get_component(player, "app.Inventory") + re8.hand_touch = get_component(player, "app.PlayerHandTouch") + re8.order = get_component(player, "app.PlayerOrder") + re8.updater = get_component(player, "app.PlayerUpdater") + re8.delta_time = sdk.call_native_func(re8.application, re8.application_type, "get_DeltaTime") + + if re8.order ~= nil then + re8.is_grapple_aim = re8.order:get_field("IsGrappleAimEnable") + end + + if re8.hand_touch == nil then + re8.right_hand_ik = nil + re8.left_hand_ik = nil + else + local hand_ik = re8.hand_touch:get_field("HandIK"):get_elements() + + if #hand_ik < 2 then + log.info("no hand ik") + re8.right_hand_ik = nil + re8.left_hand_ik = nil + else + re8.right_hand_ik = hand_ik[1] + re8.left_hand_ik = hand_ik[2] + + if re8.right_hand_ik and re8.left_hand_ik then + re8.right_hand_ik_object = re8.right_hand_ik:get_field("TargetGameObject") + re8.left_hand_ik_object = re8.left_hand_ik:get_field("TargetGameObject") + re8.right_hand_ik_transform = re8.right_hand_ik:get_field("Target") + re8.left_hand_ik_transform = re8.left_hand_ik:get_field("Target") + end + end + end + + re8.event_action_controller = get_component(player, "app.EventActionController") + re8.game_event_action_controller = get_component(player, "app.GameEventActionController") + + if is_re8 and re8.game_event_action_controller ~= nil then + re8.is_motion_play = re8.game_event_action_controller:get_field("_isMotionPlay") + else + re8.is_motion_play = false + end + + local weapon = re8.get_weapon_object(player) + + if weapon == nil then + re8.weapon = nil + return + end + + re8.weapon = weapon + + re8.update_in_cutscene_state() +end) + +local event_action_controller_type = sdk.find_type_definition("app.EventActionController") +local request_task_method = event_action_controller_type:get_method("requestTask") + +local function on_pre_event_request_task(args) + if re8.event_action_controller == nil or sdk.to_ptr(args[2]) == nil or sdk.to_int64(args[2]) ~= re8.event_action_controller:get_address() then + return sdk.PreHookResult.CALL_ORIGINAL + end + + local controller = sdk.to_managed_object(args[2]) + local task = sdk.to_managed_object(args[3]) + + if task == nil then + log.debug("No task!") + return sdk.PreHookResult.CALL_ORIGINAL + end + + if not re8.active_tasks[task] then + re8.num_active_tasks = re8.num_active_tasks + 1 + end + + re8.active_tasks[task] = true + re8.update_in_cutscene_state() + + callbacks["event_task_create"]:dispatch(args) +end + +local function on_post_event_request_task(retval) + return retval +end + +if is_re7 then + sdk.hook(request_task_method, on_pre_event_request_task, on_post_event_request_task) +end + +local event_action_task_type = sdk.find_type_definition("app.EventActionTask") +local terminate_method = event_action_task_type:get_method("terminate") + +local function on_pre_task_terminate(args) + local task = sdk.to_managed_object(args[2]) + + if task == nil or not re8.active_tasks[task] then + return + end + + if re8.active_tasks[task] then + re8.num_active_tasks = re8.num_active_tasks - 1 + re8.active_tasks[task] = nil + end + + if re8.num_active_tasks < 0 then + re8.num_active_tasks = 0 + end + + re8.update_in_cutscene_state() + + callbacks["event_task_terminate"]:dispatch(args) +end + +local function on_post_task_terminate(retval) + return retval +end + +if is_re7 then + sdk.hook(terminate_method, on_pre_task_terminate, on_post_task_terminate) +end + +local postural_camera_motion_args = nil + +local function on_pre_update_postural_camera_motion(args) + postural_camera_motion_args = args +end + +local function on_post_update_postural_camera_motion(retval) + local args = postural_camera_motion_args + local controller = sdk.to_managed_object(args[2]) + local game_object = controller:call("get_GameObject") + + if game_object ~= re8.player then + return retval + end + + re8.is_arm_jacked = controller:get_field("IsRArmJacked") + re8.has_postural_camera_control = controller:get_field("IsPosturalCameraControl") + re8.update_in_cutscene_state() + + return retval +end + +local player_motion_controller_type = sdk.find_type_definition("app.PlayerMotionController") +local update_postural_camera_motion_method = player_motion_controller_type:get_method("updatePosturalCameraMotion") + +-- ethan +sdk.hook(update_postural_camera_motion_method, on_pre_update_postural_camera_motion, on_post_update_postural_camera_motion) + +if is_re7 then + local ch8_player_motion_controller_type = sdk.find_type_definition("app.CH8PlayerMotionController") + local ch8_update_postural_camera_motion_method = ch8_player_motion_controller_type:get_method("updatePosturalCameraMotion") + local ch9_player_motion_controller_type = sdk.find_type_definition("app.CH9PlayerMotionController") + local ch9_update_postural_camera_motion_method = ch9_player_motion_controller_type:get_method("updatePosturalCameraMotion") + + -- chris + sdk.hook(ch8_update_postural_camera_motion_method, on_pre_update_postural_camera_motion, on_post_update_postural_camera_motion) + -- ch9 (end of zoe?) + sdk.hook(ch9_update_postural_camera_motion_method, on_pre_update_postural_camera_motion, on_post_update_postural_camera_motion) +end + +local player_movement_args = nil + +local function on_pre_player_movement_late_update(args) + player_movement_args = args +end + +local function re7_on_post_player_movement_late_update(retval) + local args = player_movement_args + local movement = sdk.to_managed_object(args[2]) + + re8.movement_speed_rate = movement:get_field("_SpeedRate") + re8.movement_speed_vector = movement:get_field("_MoveSpeedVector") + + return retval +end + +local function re8_on_post_player_movement_late_update(retval) + local args = player_movement_args + local movement = sdk.to_managed_object(args[2]) + + re8.movement_speed_rate = movement:get_field("SpeedRate") + re8.movement_speed_vector = movement:get_field("MoveSpeedVector") + + return retval +end + +local player_movement_type = sdk.find_type_definition("app.PlayerMovement") +local player_movement_late_update_method = player_movement_type:get_method("doLateUpdate") + +if player_movement_late_update_method == nil then + player_movement_late_update_method = player_movement_type:get_method("lateUpdate") +end + +if is_re7 then + sdk.hook(player_movement_late_update_method, on_pre_player_movement_late_update, re7_on_post_player_movement_late_update) +else + sdk.hook(player_movement_late_update_method, on_pre_player_movement_late_update, re8_on_post_player_movement_late_update) +end + +if is_re7 then + local ch8_player_movement_type = sdk.find_type_definition("app.CH8PlayerMovement") + local ch8_player_movement_late_update_method = ch8_player_movement_type:get_method("doLateUpdate") + local ch9_player_movement_type = sdk.find_type_definition("app.CH9PlayerMovement") + local ch9_player_movement_late_update_method = ch9_player_movement_type:get_method("doLateUpdate") + + sdk.hook(ch8_player_movement_late_update_method, on_pre_player_movement_late_update, on_post_player_movement_late_update) + sdk.hook(ch9_player_movement_late_update_method, on_pre_player_movement_late_update, on_post_player_movement_late_update) +end + +function re8.notify_event_task_created(callback) + callbacks["event_task_create"]:add(callback) +end + +function re8.notify_event_task_terminated(callback) + callbacks["event_task_terminate"]:add(callback) +end + +_re8lib = re8 + +return re8 \ No newline at end of file From 8f3fb486be68e3c3f84f03a7c74004fb2893fe70 Mon Sep 17 00:00:00 2001 From: praydog Date: Sat, 19 Mar 2022 03:31:57 -0700 Subject: [PATCH 07/45] VR (RE7/8): Improvements to cutscene jank (when parented to head) --- scripts/re8_vr.lua | 131 +++++++++++++++++++++++++++++++++------- scripts/utility/RE8.lua | 23 ++++++- 2 files changed, 130 insertions(+), 24 deletions(-) diff --git a/scripts/re8_vr.lua b/scripts/re8_vr.lua index c421260d0..42c859ae6 100644 --- a/scripts/re8_vr.lua +++ b/scripts/re8_vr.lua @@ -38,6 +38,7 @@ local transform_get_rotation = sdk.find_type_definition("via.Transform"):get_met local transform_set_position = sdk.find_type_definition("via.Transform"):get_method("set_Position") local transform_set_rotation = sdk.find_type_definition("via.Transform"):get_method("set_Rotation") local transform_get_joints = sdk.find_type_definition("via.Transform"):get_method("get_Joints") +local transform_get_joint_by_hash = sdk.find_type_definition("via.Transform"):get_method("getJointByHash") local joint_get_position = sdk.find_type_definition("via.Joint"):get_method("get_Position") local joint_get_rotation = sdk.find_type_definition("via.Joint"):get_method("get_Rotation") @@ -59,6 +60,7 @@ local last_gui_dot = 0.0 local last_gui_forced_slerp = os.clock() local needs_cutscene_recenter = false local last_inventory_open_time = 0.0 +local head_hash = nil local cfg = { movement_shake = false, @@ -458,7 +460,7 @@ local function set_hand_joints_to_tpose(hand_ik) for i, hash in ipairs(hashes) do if hash and hash ~= 0 then - local joint = player_transform:call("getJointByHash", hash) + local joint = transform_get_joint_by_hash:call(player_transform, hash) if joint then table.insert(joints, joint_get_parent:call(joint)) @@ -502,7 +504,7 @@ end local function update_hand_ik() if not re8.player then return end - if not vrmod:is_hmd_active() or not vrmod:is_using_controllers() then return end + if not vrmod:is_hmd_active() then return end local controllers = vrmod:get_controllers() @@ -515,7 +517,37 @@ local function update_hand_ik() end --if re8.is_in_cutscene then return end - if re8.is_arm_jacked then return end + if not re8.can_use_hands then return end + + if not vrmod:is_using_controllers() then + --[[set_hand_joints_to_tpose(re8.left_hand_ik) + set_hand_joints_to_tpose(re8.right_hand_ik) + re8.left_hand_ik:call("calc") + re8.right_hand_ik:call("calc")]] + return + end + + local player = re8.player + local original_head_rotation = nil + local head_joint = nil + local motion = player:call("getComponent(System.Type)", sdk.typeof("via.motion.Motion")) + + -- the Point of this is to fix the head rotation during cutscenes + -- because the camera seems to be parented to the head during these events + -- so modifying the joint when we set the tpose won't cause some extremely jarring movement + if motion then + local transform = re8.transform + + if not head_hash then + head_hash = get_joint_hash(transform, motion, "Head") + end + + head_joint = transform_get_joint_by_hash:call(transform, head_hash) + + if head_joint then + original_head_rotation = joint_get_rotation:call(head_joint) + end + end local left_controller_transform = vrmod:get_transform(controllers[1]) local right_controller_transform = vrmod:get_transform(controllers[2]) @@ -573,6 +605,10 @@ local function update_hand_ik() re8.right_hand_ik:call("calc") --re8.transform:call("getJointByHash", re8.right_hand_ik:get_field("HashJoint2")):call("set_Position", new_pos) + + if head_joint ~= nil and original_head_rotation ~= nil then + joint_set_rotation:call(head_joint, original_head_rotation) + end end local last_real_camera_rotation = Quaternion.new(1, 0, 0, 0) @@ -589,7 +625,6 @@ local neg_identity = Matrix4x4f.new(-1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, -1):to_quat() -local head_hash = nil local center_hash = nil local chest_hash = nil @@ -630,6 +665,10 @@ local function update_body_ik(camera_rotation, camera_pos) local ik_leg = player:call("getComponent(System.Type)", sdk.typeof("via.motion.IkLeg")) if not ik_leg then + if not vrmod:is_using_controllers() then + return + end + ik_leg = player:call("createComponent(System.Type)", sdk.typeof("via.motion.IkLeg")) if not ik_leg then @@ -638,9 +677,17 @@ local function update_body_ik(camera_rotation, camera_pos) end end - if re8.is_in_cutscene or not vrmod:is_hmd_active() then + if re8.is_in_cutscene or not vrmod:is_hmd_active() or not vrmod:is_using_controllers() then --ik_leg:call("set_Enabled", false) ik_leg:call("set_CenterOffset", Vector3f.new(0, 0, 0)) + ik_leg:call("setCenterAdjust", 0) + ik_leg:call("set_CenterPositionCtrl", 2) -- world offset + ik_leg:call("set_GroundContactUpDistance", 0.0) -- Fixes the whole player being jarringly moved upwards. + + if not vrmod:is_using_controllers() then + ik_leg:call("destroy", ik_leg) + end + return else ik_leg:call("set_Enabled", true) @@ -670,9 +717,9 @@ local function update_body_ik(camera_rotation, camera_pos) local transform_rot = transform:call("get_Rotation") local transform_pos = transform:call("get_Position") - local head_joint = transform:call("getJointByHash", head_hash) + local head_joint = transform_get_joint_by_hash:call(transform, head_hash) --local chest_joint = transform:call("getJointByHash", chest_hash) - local hip_joint = transform:call("getJointByHash", center_hash) + --local hip_joint = transform:call("getJointByHash", center_hash) --local head_index = motion:call("getJointIndexByNameHash", head_hash) --chest_index = motion:call("getJointIndexByNameHash", chest_hash) @@ -686,6 +733,10 @@ local function update_body_ik(camera_rotation, camera_pos) local original_head_pos = calculate_tpose_world(head_joint, 4) + (flattened_dir * (math.abs(normal_dir.y) * -0.1)) + (flattened_dir * 0.025) + --[[if not vrmod:is_using_controllers() then + original_head_pos = joint_get_position:call(head_joint) + (flattened_dir * (math.abs(normal_dir.y) * -0.1)) + (flattened_dir * 0.025) + end]] + --original_head_pos = transform_rot * original_head_pos --original_head_pos = transform:call("getJointByName", "root"):call("get_Rotation") * original_head_pos --original_head_pos = transform_rot * transform:calculate_base_transform(head_joint)[3] @@ -878,6 +929,12 @@ local function slerp_gui(new_gui_quat) end local last_hmd_active_state = false +local wants_posture_param_restore = false +local modified_posture_param = nil +local original_posture_camera_offset = Vector3f.new(0.0, 0.0, 0.0) + +local function pre_fix_player_camera(player_camera) +end local function fix_player_camera(player_camera) if not vrmod:is_hmd_active() then @@ -900,6 +957,10 @@ local function fix_player_camera(player_camera) if base_transform_solver then local camera_controller = base_transform_solver:get_field("CurrentController") + if not camera_controller then + camera_controller = base_transform_solver:get_field("k__BackingField") + end + -- Stop the player from rotating the camera vertically if camera_controller then camera_controller:set_field("IsVerticalRotateLimited", false) @@ -915,6 +976,8 @@ local function fix_player_camera(player_camera) return retval end + re8.upper_body_transform_rate = player_camera:get_field("k__BackingField") + last_hmd_active_state = true local base_transform_solver = player_camera:get_field("BaseTransSolver") @@ -938,12 +1001,6 @@ local function fix_player_camera(player_camera) end end - local camera = sdk.get_primary_camera() - - -- apply the camera rot to the real camera - local camera_gameobject = camera:call("get_GameObject") - local camera_transform = camera_gameobject:call("get_Transform") - local wants_recenter = false if re8.is_in_cutscene and not last_cutscene_state then @@ -964,11 +1021,37 @@ local function fix_player_camera(player_camera) vrmod:recenter_gui(vrmod:get_rotation(0):to_quat()) end + local camera = sdk.get_primary_camera() + + -- apply the camera rot to the real camera + local camera_gameobject = camera:call("get_GameObject") + local camera_transform = camera_gameobject:call("get_Transform") + local camera_rot = transform_get_rotation:call(camera_transform) local camera_pos = transform_get_position:call(camera_transform) - local camera_rot_pre_hmd = Quaternion.new(camera_rot.w, camera_rot.x, camera_rot.y, camera_rot.z) - local camera_pos_pre_hmd = Vector3f.new(camera_pos.x, camera_pos.y, camera_pos.z) + -- fix camera position. + if is_maximum_controllable and vrmod:is_using_controllers() then + local param_container = player_camera:get_field("_CurrentParamContainer") + + if param_container == nil then + param_container = player_camera:get_field("CurrentParamContainer") + end + + if param_container ~= nil then + local posture_param = param_container:get_field("PostureParam") + + if posture_param ~= nil then + local current_camera_offset = posture_param:get_field("CameraOffset") + + current_camera_offset.y = 0.0 + camera_pos = camera_pos + (camera_rot * current_camera_offset) + end + end + end + + local camera_rot_pre_hmd = camera_rot:clone() + local camera_pos_pre_hmd = camera_pos:clone() -- So the camera doesn't spin uncontrollably when attacking or the camera moves outside of player control. local camera_rot_no_shake = player_camera:get_field("k__BackingField") @@ -1016,6 +1099,10 @@ local function fix_player_camera(player_camera) player_camera:set_field("k__BackingField", fixed_rot) player_camera:set_field("k__BackingField", camera_pos) + if is_re8 then + player_camera:set_field("FixedAimRotation", fixed_rot) -- RE8 + end + player_camera:set_field("CameraRotationWithMovementShake", fixed_rot) --player_camera:set_field("CameraPositionWithMovementShake", camera_pos) player_camera:set_field("CameraRotationWithCameraShake", fixed_rot) @@ -1056,10 +1143,9 @@ local function fix_player_camera(player_camera) end local controller_forward = camera_controller_rot * Vector3f.new(0.0, 0.0, 1.0) - controller_forward.y = 0.0 - + controller_forward.y = 0.0 camera_controller_rot = controller_forward:normalized():to_quat() - + --if wants_recenter or not re8.is_in_cutscene then if not re8.is_in_cutscene or is_maximum_controllable then if not re8.is_in_cutscene then @@ -1086,7 +1172,7 @@ local function fix_player_camera(player_camera) maximum_operatable_controller:set_field("k__BackingField", camera_controller_rot) end]] - camera_controller:set_field("IsVerticalRotateLimited", true) + camera_controller:set_field("IsVerticalRotateLimited", is_maximum_controllable) was_vert_limited = true end end @@ -1094,7 +1180,7 @@ local function fix_player_camera(player_camera) -- stops the camera from pivoting around the player -- so we can use VR to look around without the body sticking out --if vrmod:is_using_controllers() then - if not re8.is_in_cutscene then + --[[if not re8.is_in_cutscene then local param_container = player_camera:get_field("_CurrentParamContainer") if param_container == nil then @@ -1112,7 +1198,7 @@ local function fix_player_camera(player_camera) posture_param:set_field("CameraOffset", current_camera_offset) end end - end + end]] local look_ray_offset = player_camera:get_type_definition():get_field("LookRay"):get_offset_from_base() local shoot_ray_offset = player_camera:get_type_definition():get_field("ShootRay"):get_offset_from_base() @@ -1134,6 +1220,8 @@ local function on_pre_player_camera_update(args) return end + pre_fix_player_camera(sdk.to_managed_object(args[2])) + --local player_camera = sdk.to_managed_object(args[2]) --fix_player_camera(player_camera) @@ -1691,6 +1779,7 @@ re.on_draw_ui(function() imgui.text("Is arm jacked: " .. tostring(re8.is_arm_jacked)) imgui.text("Is motion play: " .. tostring(re8.is_motion_play)) imgui.text("Is in cutscene: " .. tostring(re8.is_in_cutscene)) + imgui.text("Can use hands: " .. tostring(re8.can_use_hands)) imgui.tree_pop() end diff --git a/scripts/utility/RE8.lua b/scripts/utility/RE8.lua index c117df553..2b83fba71 100644 --- a/scripts/utility/RE8.lua +++ b/scripts/utility/RE8.lua @@ -74,6 +74,7 @@ local function initialize_re8(re8) re8.is_grapple_aim = false re8.is_motion_play = false re8.has_postural_camera_control = true + re8.can_use_hands = true re8.updater = nil re8.event_action_controller = nil re8.game_event_action_controller = nil @@ -160,6 +161,7 @@ end function re8.update_in_cutscene_state() re8.is_in_cutscene = re8.num_active_tasks > 0 or not re8.has_postural_camera_control or re8.is_arm_jacked or re8.is_motion_play + re8.can_use_hands = not re8.is_arm_jacked and not re8.is_motion_play end re.on_pre_application_entry("UpdateBehavior", function() @@ -301,10 +303,25 @@ end local function on_post_update_postural_camera_motion(retval) local args = postural_camera_motion_args local controller = sdk.to_managed_object(args[2]) - local game_object = controller:call("get_GameObject") - if game_object ~= re8.player then - return retval + if is_re7 then + local game_object = controller:call("get_GameObject") + + if game_object ~= re8.player then + return retval + end + else + local motion = controller:get_field("Motion") + + if motion == nil then + return retval + end + + local game_object = motion:call("get_GameObject") + + if game_object ~= re8.player then + return retval + end end re8.is_arm_jacked = controller:get_field("IsRArmJacked") From a570095282006a97421588f7937c3b14b46999bc Mon Sep 17 00:00:00 2001 From: praydog Date: Mon, 21 Mar 2022 16:56:44 -0700 Subject: [PATCH 08/45] VR (RE7/8): Weapon two-handing, improved reload anims, improved shop GUI --- scripts/re8_vr.lua | 181 ++++++++++++++++++++++++++++++++++------ scripts/utility/RE8.lua | 28 ++++++- 2 files changed, 181 insertions(+), 28 deletions(-) diff --git a/scripts/re8_vr.lua b/scripts/re8_vr.lua index 42c859ae6..9beeb5fd9 100644 --- a/scripts/re8_vr.lua +++ b/scripts/re8_vr.lua @@ -60,6 +60,7 @@ local last_gui_dot = 0.0 local last_gui_forced_slerp = os.clock() local needs_cutscene_recenter = false local last_inventory_open_time = 0.0 +local last_shop_open_time = 0.0 local head_hash = nil local cfg = { @@ -110,6 +111,7 @@ local is_inventory_open = false local function update_pad_device(device) if not vrmod:is_hmd_active() then + re8.is_holding_left_grip = false return end @@ -220,6 +222,8 @@ local function update_pad_device(device) cur_button = cur_button | via.hid.GamePadButton.RTrigTop end end + + re8.is_holding_left_grip = vrmod:is_action_active(action_grip, left_joystick) if re8.wants_block or vrmod:is_action_active(action_block, left_joystick) or vrmod:is_action_active(action_block, right_joystick) then cur_button = cur_button | via.hid.GamePadButton.LTrigTop @@ -260,6 +264,7 @@ end local function update_padman(padman) if not vrmod:is_hmd_active() or not vrmod:is_using_controllers() then + re8.is_holding_left_grip = false return end @@ -520,6 +525,8 @@ local function update_hand_ik() if not re8.can_use_hands then return end if not vrmod:is_using_controllers() then + re8.was_gripping_weapon = false + re8.is_holding_left_grip = false --[[set_hand_joints_to_tpose(re8.left_hand_ik) set_hand_joints_to_tpose(re8.right_hand_ik) re8.left_hand_ik:call("calc") @@ -532,6 +539,12 @@ local function update_hand_ik() local head_joint = nil local motion = player:call("getComponent(System.Type)", sdk.typeof("via.motion.Motion")) + local original_right_rot = Quaternion.identity() + local original_left_rot_relative = Quaternion.identity() + local original_left_pos_relative = Vector3f.new(0, 0, 0) + local original_right_rot_relative = Quaternion.identity() + local original_right_pos_relative = Vector3f.new(0, 0, 0) + -- the Point of this is to fix the head rotation during cutscenes -- because the camera seems to be parented to the head during these events -- so modifying the joint when we set the tpose won't cause some extremely jarring movement @@ -547,6 +560,32 @@ local function update_hand_ik() if head_joint then original_head_rotation = joint_get_rotation:call(head_joint) end + + local left_hash = nil + local right_hash = nil + + if is_re7 then + left_hash = re8.left_hand_ik:get_field("HashJoint2") + right_hash = re8.right_hand_ik:get_field("HashJoint2") + elseif is_re8 then + left_hash = re8.left_hand_ik:get_field("k__BackingField") + right_hash = re8.right_hand_ik:get_field("k__BackingField") + end + + + local left_index = motion:call("getJointIndexByNameHash", left_hash) + local right_index = motion:call("getJointIndexByNameHash", right_hash) + + local original_left_pos = motion:call("getWorldPosition", left_index) + local original_right_pos = motion:call("getWorldPosition", right_index) + local original_left_rot = motion:call("getWorldRotation", left_index) + original_right_rot = motion:call("getWorldRotation", right_index) + + original_left_pos_relative = original_right_rot:inverse() * (original_left_pos - original_right_pos) + original_left_rot_relative = original_right_rot:inverse() * original_left_rot + + original_right_pos_relative = original_left_rot:inverse() * (original_right_pos - original_left_pos) + original_right_rot_relative = original_left_rot:inverse() * original_right_rot end local left_controller_transform = vrmod:get_transform(controllers[1]) @@ -572,40 +611,80 @@ local function update_hand_ik() vrmod:apply_hmd_transform(fake_quat, updated_camera_pos) - local new_rotation = original_camera_rotation * left_controller_rotation * left_hand_rotation_offset - local new_pos = updated_camera_pos + local rh_rotation = original_camera_rotation * right_controller_rotation * right_hand_rotation_offset + local rh_pos = updated_camera_pos + + ((original_camera_rotation * right_controller_offset) + + ((original_camera_rotation * right_controller_rotation):normalized() * right_hand_position_offset)) + + rh_pos.w = 1.0 + + local lh_grip_position = rh_pos + (rh_rotation:normalized() * original_left_pos_relative) + lh_grip_position.w = 1.0 + + local lh_rotation = original_camera_rotation * left_controller_rotation * left_hand_rotation_offset + local lh_pos = updated_camera_pos + ((original_camera_rotation * left_controller_offset) + ((original_camera_rotation * left_controller_rotation):normalized() * left_hand_position_offset)) + + lh_pos.w = 1.0 - last_left_hand_position = new_pos - last_left_hand_rotation = new_rotation + local lh_delta_to_rh = (lh_pos - rh_pos) + local lh_grip_delta_to_rh = (lh_grip_position - rh_pos) + local lh_grip_delta = (lh_grip_position - lh_pos) + local lh_grip_distance = lh_grip_delta:length() + + -- Lets the player hold their left hand near the original (grip) position of the weapon + if lh_grip_distance <= 0.1 or (re8.was_gripping_weapon and re8.is_holding_left_grip) then + local original_grip_rot = lh_grip_delta_to_rh:normalized():to_quat() + local current_grip_rot = lh_delta_to_rh:normalized():to_quat() + + local grip_rot_delta = (current_grip_rot * original_grip_rot:inverse()):normalized() + + -- Adjust the right hand rotation + rh_rotation = (grip_rot_delta * rh_rotation):normalized() + + -- Adjust the grip position + lh_grip_position = rh_pos + (rh_rotation * original_left_pos_relative) + lh_grip_position.w = 1.0 + + -- Set the left hand position and rotation to the grip position + lh_pos = lh_grip_position + lh_rotation = rh_rotation * original_left_rot_relative + + re8.was_gripping_weapon = true + else + re8.was_gripping_weapon = false + + if re8.is_reloading then + lh_pos = lh_grip_position + lh_rotation = rh_rotation * original_left_rot_relative + else + lh_pos = lh_pos + lh_rotation = lh_rotation + end + end + + last_left_hand_position = lh_pos:clone() + last_left_hand_rotation = lh_rotation:clone() set_hand_joints_to_tpose(re8.left_hand_ik) - transform_set_position:call(re8.left_hand_ik_transform, new_pos) - transform_set_rotation:call(re8.left_hand_ik_transform, new_rotation) + re8.left_hand_ik_transform:set_position(lh_pos) + re8.left_hand_ik_transform:set_rotation(lh_rotation) re8.left_hand_ik:set_field("Transition", 1.0) re8.left_hand_ik:call("calc") - --re8.transform:call("getJointByHash", re8.left_hand_ik:get_field("HashJoint2")):call("set_Position", new_pos) + set_hand_joints_to_tpose(re8.right_hand_ik) - new_rotation = original_camera_rotation * right_controller_rotation * right_hand_rotation_offset - new_pos = updated_camera_pos - + ((original_camera_rotation * right_controller_offset) - + ((original_camera_rotation * right_controller_rotation):normalized() * right_hand_position_offset)) - - last_right_hand_position = new_pos - last_right_hand_rotation = new_rotation + last_right_hand_position = rh_pos:clone() + last_right_hand_rotation = rh_rotation:clone() + last_right_hand_position.w = 1.0 - set_hand_joints_to_tpose(re8.right_hand_ik) - - transform_set_position:call(re8.right_hand_ik_transform, new_pos) - transform_set_rotation:call(re8.right_hand_ik_transform, new_rotation) + re8.right_hand_ik_transform:set_position(rh_pos) + re8.right_hand_ik_transform:set_rotation(rh_rotation) re8.right_hand_ik:set_field("Transition", 1.0) re8.right_hand_ik:call("calc") - --re8.transform:call("getJointByHash", re8.right_hand_ik:get_field("HashJoint2")):call("set_Position", new_pos) - if head_joint ~= nil and original_head_rotation ~= nil then joint_set_rotation:call(head_joint, original_head_rotation) end @@ -781,7 +860,7 @@ local function on_pre_shoot(args) local weapon = sdk.to_managed_object(args[2]) local ray = args[3] - if is_re7 then + --[[if is_re7 then local muzzle_joint = weapon:call("get_muzzleJoint") if muzzle_joint then @@ -799,14 +878,14 @@ local function on_pre_shoot(args) else log.info("No muzzle joint found") end - elseif is_re8 then + elseif is_re8 then]] local pos = last_muzzle_pos + (last_muzzle_forward * 0.01) local from = Vector4f.new(pos.x, pos.y, pos.z, 1.0) - local dir = Vector4f.new(last_muzzle_forward.x, last_muzzle_forward.y, last_muzzle_forward.z, 0.0) + local dir = Vector4f.new(last_muzzle_forward.x, last_muzzle_forward.y, last_muzzle_forward.z, 1.0) sdk.set_native_field(ray, ray_typedef, "from", pos) sdk.set_native_field(ray, ray_typedef, "dir", dir) - end + --end --sdk.call_native_func(ray, ray_typedef, ".ctor(via.vec3, via.vec3)", last_muzzle_pos, last_muzzle_forward) end @@ -1207,8 +1286,18 @@ local function fix_player_camera(player_camera) sdk.set_native_field(sdk.to_ptr(look_ray), ray_typedef, "from", camera_pos) sdk.set_native_field(sdk.to_ptr(look_ray), ray_typedef, "dir", fixed_dir) - sdk.set_native_field(sdk.to_ptr(shoot_ray), ray_typedef, "from", camera_pos) - sdk.set_native_field(sdk.to_ptr(shoot_ray), ray_typedef, "dir", fixed_dir) + + if vrmod:is_using_controllers() then + local pos = last_muzzle_pos + (last_muzzle_forward * 0.01) + local from = Vector4f.new(pos.x, pos.y, pos.z, 1.0) + local dir = Vector4f.new(last_muzzle_forward.x, last_muzzle_forward.y, last_muzzle_forward.z, 1.0) + + sdk.set_native_field(sdk.to_ptr(shoot_ray), ray_typedef, "from", from) + sdk.set_native_field(sdk.to_ptr(shoot_ray), ray_typedef, "dir", dir) + else + sdk.set_native_field(sdk.to_ptr(shoot_ray), ray_typedef, "from", camera_pos) + sdk.set_native_field(sdk.to_ptr(shoot_ray), ray_typedef, "dir", fixed_dir) + end last_cutscene_state = re8.is_in_cutscene end @@ -1550,7 +1639,7 @@ re.on_application_entry("BeginRendering", function() last_camera_matrix = camera:call("get_WorldMatrix") end - if is_re8 and re8.weapon then + if re8.weapon then -- for some reason calling get_muzzleJoint causes lua to randomly freak out -- so we're just going to directly grab the field instead local muzzle_joint = re8.weapon:get_field("MuzzleJoint") @@ -1757,6 +1846,14 @@ re.on_draw_ui(function() imgui.tree_pop() end + + if imgui.tree_node("Weapon") then + local weapon = re8.weapon + + object_explorer:handle_address(weapon) + + imgui.tree_pop() + end if imgui.button("test dump") then local d = function(name) @@ -1807,6 +1904,14 @@ for i, v in ipairs(reticle_names) do reticle_names[v] = true end +local shop_names = { + "GUIShopBg", +} + +for i, v in ipairs(shop_names) do + shop_names[v] = true +end + re.on_pre_gui_draw_element(function(element, context) if not vrmod:is_hmd_active() then return true end @@ -1827,5 +1932,27 @@ re.on_pre_gui_draw_element(function(element, context) last_inventory_open_time = os.clock() end + if shop_names[name] then + vrmod:set_gui_rotation_offset(Quaternion.identity()) + last_shop_open_time = os.clock() + + local transform = game_object:call("get_Transform") + local old_pos = transform:get_position() + + local camera_pos = sdk.get_primary_camera():call("get_WorldMatrix")[3] + local camera_forward = sdk.get_primary_camera():call("get_WorldMatrix")[2] + + local old_distance = (old_pos - camera_pos):length() + + camera_forward.y = 0.0 + camera_forward = camera_forward:normalized() + + local new_pos = (camera_pos - (camera_forward * old_distance)) + local new_rot = camera_forward:to_quat() + + transform:set_position(new_pos, true) + transform:set_rotation(new_rot, true) + end + return true end) \ No newline at end of file diff --git a/scripts/utility/RE8.lua b/scripts/utility/RE8.lua index 2b83fba71..8fb6221bf 100644 --- a/scripts/utility/RE8.lua +++ b/scripts/utility/RE8.lua @@ -69,13 +69,17 @@ local function initialize_re8(re8) re8.order = nil re8.right_hand_ik = nil re8.left_hand_ik = nil + re8.right_hand_ik_transform = nil + re8.left_hand_ik_transform = nil re8.is_in_cutscene = false re8.is_arm_jacked = false re8.is_grapple_aim = false re8.is_motion_play = false + re8.is_reloading = false re8.has_postural_camera_control = true re8.can_use_hands = true re8.updater = nil + re8.status = nil re8.event_action_controller = nil re8.game_event_action_controller = nil re8.wants_block = false @@ -135,7 +139,19 @@ end function re8.get_weapon_object(player) if is_re7 then - return nil + local player_gun = get_component(re8.player, "app.PlayerGun") + + if not player_gun then + return nil + end + + local equipped_weapon = player_gun:get_field("WeaponGun") + + if not equipped_weapon then + return nil + end + + return equipped_weapon elseif is_re8 then if not re8.updater then return nil @@ -180,6 +196,16 @@ re.on_pre_application_entry("UpdateBehavior", function() re8.updater = get_component(player, "app.PlayerUpdater") re8.delta_time = sdk.call_native_func(re8.application, re8.application_type, "get_DeltaTime") + if is_re7 then + re8.status = get_component(player, "app.PlayerStatus") + elseif re8.updater ~= nil then + re8.status = re8.updater:call("get_playerstatus") + end + + if re8.status ~= nil then + re8.is_reloading = re8.status:call("get_isReload") + end + if re8.order ~= nil then re8.is_grapple_aim = re8.order:get_field("IsGrappleAimEnable") end From 75580f5a59c38755de3685d250fcf4878b49354a Mon Sep 17 00:00:00 2001 From: praydog Date: Thu, 24 Mar 2022 19:37:14 -0700 Subject: [PATCH 09/45] VR (RE7/8): Add Controller vibration, gripping improvements, UI improvements --- scripts/re8_vr.lua | 95 ++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 80 insertions(+), 15 deletions(-) diff --git a/scripts/re8_vr.lua b/scripts/re8_vr.lua index 9beeb5fd9..2f0b60065 100644 --- a/scripts/re8_vr.lua +++ b/scripts/re8_vr.lua @@ -514,15 +514,20 @@ local function update_hand_ik() local controllers = vrmod:get_controllers() if #controllers == 0 then + re8.was_gripping_weapon = false return end if not re8.left_hand_ik or not re8.right_hand_ik then + re8.was_gripping_weapon = false return end --if re8.is_in_cutscene then return end - if not re8.can_use_hands then return end + if not re8.can_use_hands then + re8.was_gripping_weapon = false + return + end if not vrmod:is_using_controllers() then re8.was_gripping_weapon = false @@ -633,28 +638,28 @@ local function update_hand_ik() local lh_grip_delta = (lh_grip_position - lh_pos) local lh_grip_distance = lh_grip_delta:length() + re8.was_gripping_weapon = lh_grip_distance <= 0.1 or (re8.was_gripping_weapon and re8.is_holding_left_grip) + -- Lets the player hold their left hand near the original (grip) position of the weapon - if lh_grip_distance <= 0.1 or (re8.was_gripping_weapon and re8.is_holding_left_grip) then - local original_grip_rot = lh_grip_delta_to_rh:normalized():to_quat() - local current_grip_rot = lh_delta_to_rh:normalized():to_quat() + if re8.was_gripping_weapon and not re8.is_reloading then + if original_left_pos_relative:length() >= 0.1 then + local original_grip_rot = lh_grip_delta_to_rh:normalized():to_quat() + local current_grip_rot = lh_delta_to_rh:normalized():to_quat() - local grip_rot_delta = (current_grip_rot * original_grip_rot:inverse()):normalized() + local grip_rot_delta = (current_grip_rot * original_grip_rot:inverse()):normalized() - -- Adjust the right hand rotation - rh_rotation = (grip_rot_delta * rh_rotation):normalized() + -- Adjust the right hand rotation + rh_rotation = (grip_rot_delta * rh_rotation):normalized() - -- Adjust the grip position - lh_grip_position = rh_pos + (rh_rotation * original_left_pos_relative) - lh_grip_position.w = 1.0 + -- Adjust the grip position + lh_grip_position = rh_pos + (rh_rotation * original_left_pos_relative) + lh_grip_position.w = 1.0 + end -- Set the left hand position and rotation to the grip position lh_pos = lh_grip_position lh_rotation = rh_rotation * original_left_rot_relative - - re8.was_gripping_weapon = true else - re8.was_gripping_weapon = false - if re8.is_reloading then lh_pos = lh_grip_position lh_rotation = rh_rotation * original_left_rot_relative @@ -1801,6 +1806,64 @@ json.dump_file("object_explorer/" .. __object_explorer_object_path .. ".json", t collectgarbage("collect")]] -- force a GC to free up the memory +local function on_pre_order_vibration(args) + if not vrmod:is_using_controllers() then + return + end + + local task = sdk.to_managed_object(args[3]) + + local left_power = task:get_field("MotorPower_0") + local right_power = task:get_field("MotorPower_1") + local duration = task:get_field("TimeSeconds") + + if left_power > 0 then + local left_joystick = vrmod:get_left_joystick() + vrmod:trigger_haptic_vibration(0.0, duration, 1, left_power, left_joystick) + elseif re8.was_gripping_weapon then + local left_joystick = vrmod:get_left_joystick() + vrmod:trigger_haptic_vibration(0.0, duration, 1, right_power, left_joystick) + end + + if right_power > 0 then + local right_joystick = vrmod:get_right_joystick() + vrmod:trigger_haptic_vibration(0.0, duration, 1, right_power, right_joystick) + end +end + +local function on_post_order_vibration(retval) + return retval +end + +local vibrationmanager_t = sdk.find_type_definition("app.HIDVibrationManager") +sdk.hook(vibrationmanager_t:get_method("OrderVibration(app.VibrationTask)"), on_pre_order_vibration, on_post_order_vibration) + +local function on_pre_order_vibration2(args) + if not vrmod:is_using_controllers() then + return + end + + local left_power = sdk.to_float(args[4]) + local duration = sdk.to_float(args[3]) + + if left_power > 0 then + local left_joystick = vrmod:get_left_joystick() + vrmod:trigger_haptic_vibration(0.0, duration, 1, left_power, left_joystick) + end + + --if right_power > 0 then + local right_joystick = vrmod:get_right_joystick() + vrmod:trigger_haptic_vibration(0.0, duration, 1, left_power, right_joystick) + --end +end + +local function on_post_order_vibration2(retval) + return retval +end + +local vibmethod2 = vibrationmanager_t:get_method("OrderVibration(System.Single, System.Single, System.Single, System.Boolean, System.Int32, System.Boolean, System.Single, System.Single, via.GameObject, System.Single, System.Single)") +sdk.hook(vibmethod2, on_pre_order_vibration2, on_post_order_vibration2) + re.on_draw_ui(function() local changed = false @@ -1882,13 +1945,15 @@ re.on_draw_ui(function() end end) +-- GUI elements that require usage of LB RB local re8_inventory_names = { "GUIInventory", "GUIInventoryMenu", "GUIInventoryTreasure", "GUIInventoryCraft", "GUIInventoryKeyItem", - "GUIMap" + "GUIMap", + "GUIShopBg" } for i, v in ipairs(re8_inventory_names) do From ccea6fccf5644c6fece6d34a6e785d68c5357922 Mon Sep 17 00:00:00 2001 From: praydog Date: Thu, 24 Mar 2022 21:30:34 -0700 Subject: [PATCH 10/45] VR (RE7/8): Fix haptic vibrations in RE7 --- scripts/re7_vr.lua | 1560 -------------------------------------------- scripts/re8_vr.lua | 47 +- 2 files changed, 39 insertions(+), 1568 deletions(-) delete mode 100644 scripts/re7_vr.lua diff --git a/scripts/re7_vr.lua b/scripts/re7_vr.lua deleted file mode 100644 index 6b1e16223..000000000 --- a/scripts/re7_vr.lua +++ /dev/null @@ -1,1560 +0,0 @@ -local statics = require("utility/Statics") -local re7 = require("utility/RE7") -local GameObject = require("utility/GameObject") - -local renderer = sdk.get_native_singleton("via.render.Renderer") -local renderer_type = sdk.find_type_definition("via.render.Renderer") - -local GamePadButton = statics.generate("via.hid.GamePadButton") - -local last_camera_matrix = Matrix4x4f.new() -local last_right_hand_rotation = Quaternion.new(0.0, 0.0, 0.0, 0.0) -local last_right_hand_position = Vector3f.new(0.0, 0.0, 0.0) -local last_left_hand_rotation = Quaternion.new(0.0, 0.0, 0.0, 0.0) -local last_left_hand_position = Vector3f.new(0.0, 0.0, 0.0) -local left_hand_rotation_vec = Vector3f.new(-0.105 + 0.2, 2.37, 1.10) -- pitch yaw roll? -local right_hand_rotation_vec = Vector3f.new(-0.105, -2.37, -1.10) -- pitch yaw roll? -local left_hand_rotation_offset = Quaternion.new(left_hand_rotation_vec):normalized() -local right_hand_rotation_offset = Quaternion.new(right_hand_rotation_vec):normalized() -local left_hand_position_offset = Vector4f.new(-0.025, 0.045, 0.155, 0.0) -local right_hand_position_offset = Vector4f.new(0.025, 0.045, 0.155, 0.0) - -local ray_typedef = sdk.find_type_definition("via.Ray") - -local transform_get_position = sdk.find_type_definition("via.Transform"):get_method("get_Position") -local transform_get_rotation = sdk.find_type_definition("via.Transform"):get_method("get_Rotation") -local transform_set_position = sdk.find_type_definition("via.Transform"):get_method("set_Position") -local transform_set_rotation = sdk.find_type_definition("via.Transform"):get_method("set_Rotation") -local transform_get_joints = sdk.find_type_definition("via.Transform"):get_method("get_Joints") - -local joint_get_position = sdk.find_type_definition("via.Joint"):get_method("get_Position") -local joint_get_rotation = sdk.find_type_definition("via.Joint"):get_method("get_Rotation") -local joint_set_position = sdk.find_type_definition("via.Joint"):get_method("set_Position") -local joint_set_rotation = sdk.find_type_definition("via.Joint"):get_method("set_Rotation") - -local component_get_gameobject = sdk.find_type_definition("via.Component"):get_method("get_GameObject") -local gameobject_get_transform = sdk.find_type_definition("via.GameObject"):get_method("get_Transform") - -local cfg_path = "re7_vr/main_config.json" - -local queue_recenter = false -local was_vert_limited = false - -local last_gui_offset = Quaternion.identity() -local last_gui_quat = Quaternion.identity() -local last_gui_dot = 0.0 -local last_gui_forced_slerp = os.clock() -local needs_cutscene_recenter = false - -local cfg = { - movement_shake = false, - all_camera_shake = true -} - -local function load_cfg() - local loaded_cfg = json.load_file(cfg_path) - - if loaded_cfg == nil then - json.dump_file(cfg_path, cfg) - return - end - - for k, v in pairs(loaded_cfg) do - cfg[k] = v - end -end - -load_cfg() - -statics.generate_global("via.hid.GamePadButton") -statics.generate_global("via.hid.MouseButton") -statics.generate_global("app.HIDManager.InputMode") - -local via_hid_mouse_typedef = sdk.find_type_definition("via.hid.Mouse") -local via_hid_mouse = sdk.get_native_singleton("via.hid.Mouse") - -local function get_mouse_device() - return sdk.call_native_func(via_hid_mouse, via_hid_mouse_typedef, "get_Device") -end - -local function set_inputmode(mode) - local hid_manager = sdk.get_managed_singleton(sdk.game_namespace("HIDManager")) - - if hid_manager then - hid_manager:call("set_inputMode", mode) - end -end - -local function update_pad_device(device) - if not vrmod:is_hmd_active() then - return - end - - local menu_manager = sdk.get_managed_singleton("app.MenuManager") - local is_inventory_open = false - - if menu_manager ~= nil then - is_inventory_open = menu_manager:call("isOpenInventoryMenu") - is_inventory_open = is_inventory_open or menu_manager:call("isOpenItemBoxMenu") - end - - local raw_left_stick_axis = vrmod:get_left_stick_axis() - - --local vr_left_stick_axis = last_camera_matrix:to_quat() * Vector4f.new(raw_left_stick_axis.x, raw_left_stick_axis.y, 0.0, 0.0) - local vr_left_stick_axis = vrmod:get_left_stick_axis() - local vr_right_stick_axis = vrmod:get_right_stick_axis() - - local cur_button = device:call("get_Button") - - device:call("set_AxisL", vr_left_stick_axis) - device:call("set_RawAxisR", vr_right_stick_axis) - device:call("set_AxisR", vr_right_stick_axis) - - -- we have these via.hid.GamePadButton values for the right stick - -- EmuRup - -- EmuRright - -- EmuRdown - -- EmuRleft - - -- set cur_button | according to the right stick axis - if vr_right_stick_axis.x > 0.1 then - --cur_button = cur_button | via.hid.GamePadButton.RRight - elseif vr_right_stick_axis.x < -0.1 then - --cur_button = cur_button | via.hid.GamePadButton.RLeft - end - - if vr_right_stick_axis.y > 0.1 then - --cur_button = cur_button | via.hid.GamePadButton.RUp - elseif vr_right_stick_axis.y < -0.1 then - --cur_button = cur_button | via.hid.GamePadButton.RDown - end - - if vr_left_stick_axis.x > 0.1 then - --cur_button = cur_button | via.hid.GamePadButton.LRight - elseif vr_left_stick_axis.x < -0.1 then - --cur_button = cur_button | via.hid.GamePadButton.LLeft - end - - if vr_left_stick_axis.y > 0.1 then - --cur_button = cur_button | via.hid.GamePadButton.LUp - elseif vr_left_stick_axis.y < -0.1 then - --cur_button = cur_button | via.hid.GamePadButton.LDown - end - - local action_trigger = vrmod:get_action_trigger() - local action_grip = vrmod:get_action_grip() - local action_a_button = vrmod:get_action_a_button() - local action_b_button = vrmod:get_action_b_button() - local action_joystick_click = vrmod:get_action_joystick_click() - local action_weapon_dial = vrmod:get_action_weapon_dial() - local action_minimap = vrmod:get_action_minimap() - local action_block = vrmod:get_action_block() - - local right_joystick = vrmod:get_right_joystick() - local left_joystick = vrmod:get_left_joystick() - - if vrmod:is_action_active(action_trigger, right_joystick) then - device:call("set_AnalogR", 1.0) - cur_button = cur_button | via.hid.GamePadButton.RTrigBottom - - if is_inventory_open then - cur_button = cur_button | via.hid.GamePadButton.RTrigTop - end - end - - -- gripping right joystick causes "left trigger" to be pressed (aiming) - if vrmod:is_action_active(action_grip, right_joystick) then - cur_button = cur_button | via.hid.GamePadButton.LTrigBottom - device:call("set_AnalogL", 1.0) - end - - if vrmod:is_action_active(action_weapon_dial, left_joystick) or vrmod:is_action_active(action_weapon_dial, right_joystick) then - -- DPad mimickry - if vr_left_stick_axis.y >= 0.9 then - cur_button = cur_button | via.hid.GamePadButton.LUp - elseif vr_left_stick_axis.y <= -0.9 then - cur_button = cur_button | via.hid.GamePadButton.LDown - end - - if vr_left_stick_axis.x >= 0.9 then - cur_button = cur_button | via.hid.GamePadButton.LRight - elseif vr_left_stick_axis.x <= -0.9 then - cur_button = cur_button | via.hid.GamePadButton.LLeft - end - end - - if vrmod:is_action_active(action_trigger, left_joystick) then - if is_inventory_open then - cur_button = cur_button | via.hid.GamePadButton.LTrigTop - end - - -- set right bumper (heal) if holding both trigger and grip - if vrmod:is_action_active(action_grip, left_joystick) then - cur_button = cur_button | via.hid.GamePadButton.RTrigTop - end - end - - if re7.wants_block or vrmod:is_action_active(action_block, left_joystick) or vrmod:is_action_active(action_block, right_joystick) then - cur_button = cur_button | via.hid.GamePadButton.LTrigTop - re7.wants_block = true - end - - if vrmod:is_action_active(action_a_button, right_joystick) then - cur_button = cur_button | via.hid.GamePadButton.Decide | via.hid.GamePadButton.RDown - end - - if vrmod:is_action_active(action_b_button, right_joystick) then - cur_button = cur_button | via.hid.GamePadButton.RLeft - end - - if vrmod:is_action_active(action_a_button, left_joystick) then - cur_button = cur_button | via.hid.GamePadButton.Cancel | via.hid.GamePadButton.RRight - end - - if vrmod:is_action_active(action_b_button, left_joystick) then - cur_button = cur_button | via.hid.GamePadButton.RUp - end - - if vrmod:is_action_active(action_joystick_click, right_joystick) then - cur_button = cur_button | via.hid.GamePadButton.RStickPush - end - - if vrmod:is_action_active(action_joystick_click, left_joystick) then - cur_button = cur_button | via.hid.GamePadButton.LStickPush - end - - if vrmod:is_action_active(action_minimap, right_joystick) or vrmod:is_action_active(action_minimap, left_joystick) then - cur_button = cur_button | via.hid.GamePadButton.CLeft - end - - device:call("set_Button", cur_button) - device:call("set_ButtonDown", cur_button) -end - -local function update_padman(padman) - if not vrmod:is_hmd_active() or not vrmod:is_using_controllers() then - return - end - - local merged_pad = padman:call("get_mergedPad") - - if not merged_pad then - return - end - - --padman:call("set_activePad", merged_pad) - - local device = merged_pad:get_field("Device") - - if not device then - return - end - - update_pad_device(device) - --merged_pad:call("updateStick") - --merged_pad:call("updateButton") - - set_inputmode(app.HIDManager.InputMode.Pad) -end - -local function on_pre_app_pad_update(args) - if not vrmod:is_hmd_active() or not vrmod:is_using_controllers() then - return - end - - local pad = sdk.to_managed_object(args[2]) - - local padman = sdk.get_managed_singleton(sdk.game_namespace("PadManager")) - - if not padman then - return - end - - local merged_pad = padman:call("get_mergedPad") - - if not merged_pad or merged_pad ~= pad then - return - end - - local device = merged_pad:get_field("Device") - - if not device then - return - end - - update_pad_device(device) - --merged_pad:call("updateStick") - --merged_pad:call("updateButton") - - set_inputmode(app.HIDManager.InputMode.Pad) -end - -local function on_post_app_pad_update(retval) - return retval -end - -sdk.hook( - sdk.find_type_definition("app.Pad"):get_method("update"), - on_pre_app_pad_update, - on_post_app_pad_update -) - -local function on_pre_try_guard_start(args) - if not vrmod:is_hmd_active() or not vrmod:is_using_controllers() then - return - end - - -- this will only allow blocking by physically holding your hands up. - if not re7.wants_block then - return sdk.PreHookResult.SKIP_ORIGINAL - end -end - -local function on_post_try_guard_start(retval) - if not vrmod:is_hmd_active() or not vrmod:is_using_controllers() or re7.wants_block then - return retval - end - - return sdk.to_ptr(0) -end - -sdk.hook( - sdk.find_type_definition("app.PlayerBase"):get_method("tryGuardStart"), - on_pre_try_guard_start, - on_post_try_guard_start -) - -local function calculate_tpose_world(joint, depth) - if not depth then - depth = 1 - end - - local original_positions = {} - local original_rotations = {} - local current_positions = {} - - local player_transform = re7.transform - local player_pos = transform_get_position:call(player_transform) - local player_rot = transform_get_rotation:call(player_transform) - - local joints = {} - - local cur_joint = joint - - for i=1, depth do - cur_joint = cur_joint:call("get_Parent") - table.insert(joints, cur_joint) - end - - local parent_pos = joint_get_position:call(cur_joint) - local parent_rot = joint_get_rotation:call(cur_joint) - local original_parent_pos = player_pos + (player_rot * player_transform:calculate_base_transform(cur_joint)[3]) - - for i=1, depth do - local joint = joints[depth-i] - - local original_pos = player_pos + (player_rot * player_transform:calculate_base_transform(joint)[3]) - local diff = original_pos - original_parent_pos - local updated_pos = parent_pos + diff - - original_parent_pos = original_pos - parent_pos = updated_pos - end - - local original_pos = player_pos + (player_rot * player_transform:calculate_base_transform(joint)[3]) - local diff = original_pos - original_parent_pos - return parent_pos + diff -end - -local function set_hand_joints_to_tpose(hand_ik) - local hashes = { - hand_ik:get_field("HashJoint0"), - hand_ik:get_field("HashJoint1"), - hand_ik:get_field("HashJoint2"), - hand_ik:get_field("HashJoint3") - } - - local original_positions = {} - local original_rotations = {} - local current_positions = {} - - local player_transform = re7.transform - local player_pos = transform_get_position:call(player_transform) - local player_rot = transform_get_rotation:call(player_transform) - - local joints = {} - - for i, hash in ipairs(hashes) do - if hash and hash ~= 0 then - local joint = player_transform:call("getJointByHash", hash) - - if joint then - table.insert(joints, joint:call("get_Parent")) - end - end - end - - if #joints > 0 and joints[1] ~= nil then - table.insert(joints, 1, joints[1]:call("get_Parent")) - - if not re7.is_grapple_aim then - table.insert(joints, 1, joints[1]:call("get_Parent")) - table.insert(joints, 1, joints[1]:call("get_Parent")) - end - end - - for i, joint in ipairs(joints) do - local base_transform = player_transform:calculate_base_transform(joint) - original_positions[i] = player_pos + (player_rot * base_transform[3]) - original_rotations[i] = player_rot * base_transform:to_quat() - current_positions[i] = joint_get_position:call(joint) - end - - -- second pass - for i, joint in ipairs(joints) do - if joint then - local next_joint = joints[i + 1] - - if next_joint ~= nil then - local diff = original_positions[i + 1] - original_positions[i] - local updated_pos = current_positions[i] + diff - - joint_set_position:call(next_joint, updated_pos) - joint_set_rotation:call(next_joint, original_rotations[i+1]) - - current_positions[i + 1] = updated_pos - end - end - end -end - -local function update_hand_ik() - if not re7.player then return end - if not vrmod:is_hmd_active() or not vrmod:is_using_controllers() then return end - - local controllers = vrmod:get_controllers() - - if #controllers == 0 then - return - end - - if not re7.left_hand_ik or not re7.right_hand_ik then - return - end - - --if re7.is_in_cutscene then return end - if re7.is_arm_jacked then return end - - local left_controller_transform = vrmod:get_transform(controllers[1]) - local right_controller_transform = vrmod:get_transform(controllers[2]) - local left_controller_rotation = left_controller_transform:to_quat() - local right_controller_rotation = right_controller_transform:to_quat() - - local hmd_transform = vrmod:get_transform(0) - --local hmd_rotation = (vrmod:get_rotation_offset() * hmd_transform:to_quat()):normalized() - - local left_controller_offset = left_controller_transform[3] - hmd_transform[3] - local right_controller_offset = right_controller_transform[3] - hmd_transform[3] - - local camera = sdk.get_primary_camera() - local camera_rotation = last_camera_matrix:to_quat() - - local original_camera_matrix = camera:call("get_WorldMatrix") - local original_camera_rotation_pre = original_camera_matrix:to_quat() - local original_camera_rotation = (original_camera_rotation_pre * vrmod:get_rotation_offset()):normalized() - - local fake_quat = Quaternion.new(original_camera_rotation_pre.w, original_camera_rotation_pre.x, original_camera_rotation_pre.y, original_camera_rotation_pre.z) - local updated_camera_pos = original_camera_matrix[3] - - vrmod:apply_hmd_transform(fake_quat, updated_camera_pos) - - local new_rotation = original_camera_rotation * left_controller_rotation * left_hand_rotation_offset - local new_pos = updated_camera_pos - + ((original_camera_rotation * left_controller_offset) - + ((original_camera_rotation * left_controller_rotation):normalized() * left_hand_position_offset)) - - last_left_hand_position = new_pos - last_left_hand_rotation = new_rotation - - set_hand_joints_to_tpose(re7.left_hand_ik) - - transform_set_position:call(re7.left_hand_ik_transform, new_pos) - transform_set_rotation:call(re7.left_hand_ik_transform, new_rotation) - re7.left_hand_ik:set_field("Transition", 1.0) - re7.left_hand_ik:call("calc") - - --re7.transform:call("getJointByHash", re7.left_hand_ik:get_field("HashJoint2")):call("set_Position", new_pos) - - new_rotation = original_camera_rotation * right_controller_rotation * right_hand_rotation_offset - new_pos = updated_camera_pos - + ((original_camera_rotation * right_controller_offset) - + ((original_camera_rotation * right_controller_rotation):normalized() * right_hand_position_offset)) - - last_right_hand_position = new_pos - last_right_hand_rotation = new_rotation - - set_hand_joints_to_tpose(re7.right_hand_ik) - - transform_set_position:call(re7.right_hand_ik_transform, new_pos) - transform_set_rotation:call(re7.right_hand_ik_transform, new_rotation) - re7.right_hand_ik:set_field("Transition", 1.0) - re7.right_hand_ik:call("calc") - - --re7.transform:call("getJointByHash", re7.right_hand_ik:get_field("HashJoint2")):call("set_Position", new_pos) -end - -local last_real_camera_rotation = Quaternion.new(1, 0, 0, 0) -local last_real_camera_joint_rotation = Quaternion.new(1, 0, 0, 0) -local last_real_camera_joint_pos = Vector3f.new(0, 0, 0) - -local neg_forward_identity = Matrix4x4f.new(-1, 0, 0, 0, - 0, 1, 0, 0, - 0, 0, -1, 0, - 0, 0, 0, 1):to_quat() - -local neg_identity = Matrix4x4f.new(-1, 0, 0, 0, - 0, -1, 0, 0, - 0, 0, -1, 0, - 0, 0, 0, -1):to_quat() - -local head_hash = nil -local center_hash = nil -local chest_hash = nil - -local known_hashes = {} - -local function get_joint_hash(transform, motion, name) - if not known_hashes[transform] then - known_hashes[transform] = {} - end - - local hash = known_hashes[transform][name] - - if hash then - return hash - end - - local joint = transform:call("getJointByName", name) - - if not joint then - log.debug("Failed to get " .. name .. " joint") - return nil - end - - hash = joint:call("get_NameHash") - log.info(name .. " hash: " .. string.format("%x", hash)) - - known_hashes[transform][name] = hash - - return hash -end - -local zero_vec = Vector3f.new(0, 0, 0) - -local function update_body_ik(camera_rotation, camera_pos) - if not re7.player then return end - - local player = re7.player - local ik_leg = player:call("getComponent(System.Type)", sdk.typeof("via.motion.IkLeg")) - - if not ik_leg then - ik_leg = player:call("createComponent(System.Type)", sdk.typeof("via.motion.IkLeg")) - - if not ik_leg then - log.error("Failed to create IK leg component") - return - end - end - - if re7.is_in_cutscene or not vrmod:is_hmd_active() then - --ik_leg:call("set_Enabled", false) - ik_leg:call("set_CenterOffset", Vector3f.new(0, 0, 0)) - return - else - ik_leg:call("set_Enabled", true) - end - - local motion = player:call("getComponent(System.Type)", sdk.typeof("via.motion.Motion")) - - if not motion then - log.error("Failed to get motion component") - return - end - - local transform = player:call("get_Transform") - - if not head_hash then - head_hash = get_joint_hash(transform, motion, "Head") - end - - if not chest_hash then - chest_hash = get_joint_hash(transform, motion, "Chest") - end - - if not center_hash then - center_hash = get_joint_hash(transform, motion, "Hip") - end - - local transform_rot = transform:call("get_Rotation") - local transform_pos = transform:call("get_Position") - - local head_joint = transform:call("getJointByHash", head_hash) - --local chest_joint = transform:call("getJointByHash", chest_hash) - local hip_joint = transform:call("getJointByHash", center_hash) - - local head_index = motion:call("getJointIndexByNameHash", head_hash) - --chest_index = motion:call("getJointIndexByNameHash", chest_hash) - local original_head_pos = motion:call("getWorldPosition", head_index) - --local original_chest_pos = motion:call("getWorldPosition", chest_index) - - local normal_dir = camera_rotation * Vector3f.new(0, 0, 1) - local flattened_dir = camera_rotation * Vector3f.new(0, 0, 1) - flattened_dir.y = 0.0 - flattened_dir:normalize() - - original_head_pos = calculate_tpose_world(head_joint, 4) - original_head_pos = original_head_pos + (flattened_dir * (math.abs(normal_dir.y) * -0.1)) + (flattened_dir * 0.025) - - --original_head_pos = transform_rot * original_head_pos - --original_head_pos = transform:call("getJointByName", "root"):call("get_Rotation") * original_head_pos - --original_head_pos = transform_rot * transform:calculate_base_transform(head_joint)[3] - --original_chest_pos = transform_rot * original_chest_pos - - --original_head_pos.x = original_chest_pos.x - --original_head_pos.z = original_chest_pos.z - - --[[local center_index = motion:call("getJointIndexByNameHash", center_hash) - local original_center_pos = motion:call("getWorldPosition", center_index) - - original_center_pos = transform_rot * original_center_pos - - local current_center_pos = transform:call("getJointByHash", center_hash):call("get_Position") - local center_diff = (original_center_pos * -1.0) - center_diff.y = 0.0]] - - --local current_head_pos = transform:call("getJointByName", "Head"):call("get_Position") - - --[[local center_joint = transform:call("getJointByName", "Hip") - - local center_pos = center_joint:call("get_Position") - local transform_pos = transform:call("get_Position")]] - - local diff_to_camera = ((camera_pos) - original_head_pos) - - --ik_leg:call("set_CenterJointName", "Hip") - ik_leg:call("set_CenterOffset", diff_to_camera) - ik_leg:call("setCenterAdjust", 0) - --ik_leg:call("set_UpdateTiming", 2) -- ConstraintsBegin -end - -local function on_pre_shoot(args) - if not vrmod:is_hmd_active() or not vrmod:is_using_controllers() then - return - end - - update_hand_ik() - - local weapon = sdk.to_managed_object(args[2]) - local ray = args[3] - - local muzzle_joint = weapon:call("get_muzzleJoint") - - if muzzle_joint then - local muzzle_pos = joint_get_position:call(muzzle_joint) - local muzzle_forward = joint_get_rotation:call(muzzle_joint) * Vector3f.new(0, 0, 1) - - -- nudge the start position slightly forward because - -- apparently the bullets can collide with the weapon.... wtf - sdk.set_native_field(ray, ray_typedef, "from", muzzle_pos + (muzzle_forward * 0.01)) - sdk.set_native_field(ray, ray_typedef, "dir", muzzle_forward) - else - log.info("No muzzle joint found") - end - - --sdk.call_native_func(ray, ray_typedef, ".ctor(via.vec3, via.vec3)", last_muzzle_pos, last_muzzle_forward) -end - -local function on_post_shoot(retval) - return retval -end - -sdk.hook(sdk.find_type_definition("app.WeaponGun"):get_method("shoot"), on_pre_shoot, on_post_shoot) - -local old_camera_rot = nil -local old_camera_pos = nil - --- let player look at interaction elements with the camera -local function on_pre_interact_manager_lateupdate(args) - if not vrmod:is_hmd_active() then - return - end - - local camera = sdk.get_primary_camera() - local camera_gameobject = component_get_gameobject:call(camera) - local camera_transform = gameobject_get_transform:call(camera_gameobject) - - local joint = transform_get_joints:call(camera_transform)[0] - - old_camera_rot = joint_get_rotation:call(joint) - old_camera_pos = joint_get_position:call(joint) - - joint_set_rotation:call(joint, last_camera_matrix:to_quat()) - joint_set_position:call(joint, last_camera_matrix[3]) -end - -local function on_post_interact_manager_lateupdate(retval) - if not vrmod:is_hmd_active() then - return - end - - local camera = sdk.get_primary_camera() - local camera_gameobject = component_get_gameobject:call(camera) - local camera_transform = gameobject_get_transform:call(camera_gameobject) - - local joint = transform_get_joints:call(camera_transform)[0] - - joint_set_rotation:call(joint, old_camera_rot) - joint_set_position:call(joint, old_camera_pos) - - return retval -end - -sdk.hook( - sdk.find_type_definition("app.InteractManager"):get_method("doLateUpdate"), - on_pre_interact_manager_lateupdate, - on_post_interact_manager_lateupdate -) - --- force the gui to recenter when opening the inventory -sdk.hook( - sdk.find_type_definition("app.MenuManager"):get_method("openInventoryMenu"), - function(args) - last_gui_forced_slerp = os.clock() - end, - function(retval) - return retval - end -) - -local last_camera_update_args = nil -local last_cutscene_state = false -local last_time_not_maximum_controllable = 0.0 -local GUI_MAX_SLERP_TIME = 1.5 - -local function slerp_gui(new_gui_quat) - if re7.movement_speed_rate > 0.0 then - last_gui_forced_slerp = os.clock() - ((1.0 - re7.movement_speed_rate)) - end - - last_gui_dot = last_gui_quat:dot(new_gui_quat) - local dot_dist = 1.0 - math.abs(last_gui_dot) - local dot_ang = math.acos(math.abs(last_gui_dot)) * (180.0 / math.pi) - last_gui_dot = dot_ang - - local now = os.clock() - - -- trigger gui slerp - if dot_ang >= 20 or re7.is_in_cutscene then - last_gui_forced_slerp = now - end - - local slerp_time_diff = now - last_gui_forced_slerp - - if slerp_time_diff <= GUI_MAX_SLERP_TIME then - if dot_ang >= 10 then - last_gui_forced_slerp = now - end - - last_gui_quat = last_gui_quat:slerp(new_gui_quat, dot_dist * math.max((GUI_MAX_SLERP_TIME - slerp_time_diff) * re7.delta_time, 0.0)) - end - - if re7.is_in_cutscene then - vrmod:recenter_gui(last_gui_quat) - else - vrmod:recenter_gui(last_gui_quat * new_gui_quat:inverse()) - end -end - -local last_hmd_active_state = false - -local function fix_player_camera(player_camera) - if not vrmod:is_hmd_active() then - -- so the camera doesnt go wacky - if last_hmd_active_state then - -- disables the body IK component - update_body_ik(nil, nil) - - vrmod:set_gui_rotation_offset(Quaternion.identity()) - vrmod:recenter_view() - - last_hmd_active_state = false - end - - -- Restore the vertical camera movement after taking headset off/not using controllers - if was_vert_limited then - --local player_camera = sdk.to_managed_object(args[2]) - local base_transform_solver = player_camera:get_field("BaseTransSolver") - - if base_transform_solver then - local camera_controller = base_transform_solver:get_field("CurrentController") - - -- Stop the player from rotating the camera vertically - if camera_controller then - camera_controller:set_field("IsVerticalRotateLimited", false) - end - end - - was_vert_limited = false - end - - last_real_camera_rotation = nil - last_real_camera_joint_rotation = nil - - return retval - end - - last_hmd_active_state = true - - local base_transform_solver = player_camera:get_field("BaseTransSolver") - local is_maximum_controllable = true - - if base_transform_solver then - if base_transform_solver:get_field("k__BackingField") ~= 0 then -- MaximumOperatable - re7.is_in_cutscene = true - is_maximum_controllable = false - last_time_not_maximum_controllable = os.clock() - else - if os.clock() - last_time_not_maximum_controllable <= 1.0 then - re7.is_in_cutscene = true - end - end - end - - local camera = sdk.get_primary_camera() - - -- apply the camera rot to the real camera - local camera_gameobject = camera:call("get_GameObject") - local camera_transform = camera_gameobject:call("get_Transform") - - local wants_recenter = false - - if re7.is_in_cutscene and not last_cutscene_state then - --vrmod:recenter_view() - - -- force the gui to be recentered when we exit the cutscene - last_gui_forced_slerp = os.clock() - last_gui_quat = Quaternion.identity() - wants_recenter = true - --queue_recenter = true - - vrmod:recenter_gui(last_gui_quat) - elseif not re7.is_in_cutscene and last_cutscene_state then - last_gui_forced_slerp = os.clock() - last_gui_quat = vrmod:get_rotation(0):to_quat():inverse() - wants_recenter = true - - vrmod:recenter_gui(vrmod:get_rotation(0):to_quat()) - end - - local camera_rot = transform_get_rotation:call(camera_transform) - local camera_pos = transform_get_position:call(camera_transform) - - local camera_rot_pre_hmd = Quaternion.new(camera_rot.w, camera_rot.x, camera_rot.y, camera_rot.z) - local camera_pos_pre_hmd = Vector3f.new(camera_pos.x, camera_pos.y, camera_pos.z) - - -- So the camera doesn't spin uncontrollably when attacking or the camera moves outside of player control. - local camera_rot_no_shake = player_camera:get_field("k__BackingField") - - vrmod:apply_hmd_transform(camera_rot_no_shake, Vector3f.new(0, 0, 0)) - vrmod:apply_hmd_transform(camera_rot, camera_pos) - - local camera_joint = camera_transform:call("get_Joints")[0] - - -- Transform is used for things like Ethan's light - -- and determining where the player is looking - transform_set_position:call(camera_transform, camera_pos) - transform_set_rotation:call(camera_transform, camera_rot) - - last_real_camera_joint_rotation = camera_rot_pre_hmd - last_real_camera_joint_pos = camera_pos_pre_hmd - - -- Joint is used for the actual final rendering of the game world - --if not wants_recenter then - if re7.is_in_cutscene then - joint_set_position:call(camera_joint, camera_pos_pre_hmd) - joint_set_rotation:call(camera_joint, camera_rot_pre_hmd) - else - local rot_delta = camera_rot_pre_hmd:inverse() * camera_rot - - local forward = rot_delta * Vector3f.new(0, 0, 1) - forward = Vector3f.new(forward.x, 0.0, forward.z):normalized() - - joint_set_position:call(camera_joint, camera_pos_pre_hmd) - joint_set_rotation:call(camera_joint, camera_rot_pre_hmd * forward:to_quat()) - end - - --last_gui_offset = last_gui_offset * (camera_rot:inverse() * camera_rot_pre_hmd) - - -- just update the body IK right after we update the camera. - update_body_ik(camera_rot, camera_pos) - - -- Slerp the gui around - slerp_gui(re7.is_in_cutscene and (camera_rot_pre_hmd * camera_rot:inverse()) or vrmod:get_rotation(0):to_quat():inverse()) - - local fixed_dir = ((neg_forward_identity * camera_rot_no_shake) * Vector3f.new(0, 0, -1)):normalized() - local fixed_rot = fixed_dir:to_quat() - --local fixed_rot = neg_forward_identity * camera_rot - - player_camera:set_field("k__BackingField", fixed_rot) - player_camera:set_field("k__BackingField", camera_pos) - - player_camera:set_field("CameraRotationWithMovementShake", fixed_rot) - --player_camera:set_field("CameraPositionWithMovementShake", camera_pos) - player_camera:set_field("CameraRotationWithCameraShake", fixed_rot) - --player_camera:set_field("CameraPositionWithCameraShake", camera_pos) - player_camera:set_field("PrevCameraRotation", fixed_rot) - --player_camera:set_field("OldCameraRotation", fixed_rot) - --player_camera:set_field("InterpRotationStart", fixed_rot) - --player_camera:set_field("k__BackingField", fixed_rot) - --player_camera:set_field("k__BackingField", fixed_rot) - - local camera_controller_param = player_camera:get_field("CameraCtrlParam") - - if camera_controller_param then - camera_controller_param:set_field("CameraRotation", fixed_rot) - end - - local base_transform_solver = player_camera:get_field("BaseTransSolver") - - if base_transform_solver then - local camera_controller = base_transform_solver:get_field("CurrentController") - - -- Stop the player from rotating the camera vertically - if camera_controller then - local camera_controller_rot = Quaternion.identity() - - if re7.is_in_cutscene then - camera_controller_rot = camera_controller:get_field("k__BackingField") - else - camera_controller_rot = Quaternion.new(fixed_rot.w, fixed_rot.x, fixed_rot.y, fixed_rot.z) - end - - local controller_forward = camera_controller_rot * Vector3f.new(0.0, 0.0, 1.0) - controller_forward.y = 0.0 - - camera_controller_rot = controller_forward:normalized():to_quat() - - --if wants_recenter or not re7.is_in_cutscene then - if not re7.is_in_cutscene or is_maximum_controllable then - if not re7.is_in_cutscene then - vrmod:recenter_view() - end - - camera_controller:set_field("k__BackingField", camera_controller_rot) - end - - base_transform_solver:set_field("k__BackingField", camera_controller_rot) - - --[[for i, controller in ipairs(base_transform_solver:get_field("CameraControllers"):get_elements()) do - controller:set_field("k__BackingField", camera_controller_rot) - controller:set_field("RelativeCamRotAtEndOfMotion", camera_controller_rot) - end]] - - --[[local maximum_operatable_controller = base_transform_solver:get_field("CameraControllers")[0] - - if maximum_operatable_controller ~= camera_controller then - maximum_operatable_controller:set_field("k__BackingField", camera_controller_rot) - end]] - - camera_controller:set_field("IsVerticalRotateLimited", true) - was_vert_limited = true - end - end - - -- stops the camera from pivoting around the player - -- so we can use VR to look around without the body sticking out - --if vrmod:is_using_controllers() then - if not re7.is_in_cutscene then - local param_container = player_camera:get_field("_CurrentParamContainer") - - if param_container ~= nil then - local posture_param = param_container:get_field("PostureParam") - - if posture_param ~= nil then - local current_camera_offset = posture_param:get_field("CameraOffset") - current_camera_offset.x = 0.0 - current_camera_offset.z = 0.0 - - posture_param:set_field("CameraOffset", current_camera_offset) - end - end - end - - local look_ray_offset = player_camera:get_type_definition():get_field("LookRay"):get_offset_from_base() - local shoot_ray_offset = player_camera:get_type_definition():get_field("ShootRay"):get_offset_from_base() - local look_ray = player_camera:get_address() + look_ray_offset - local shoot_ray = player_camera:get_address() + shoot_ray_offset - - sdk.set_native_field(sdk.to_ptr(look_ray), ray_typedef, "from", camera_pos) - sdk.set_native_field(sdk.to_ptr(look_ray), ray_typedef, "dir", fixed_dir) - sdk.set_native_field(sdk.to_ptr(shoot_ray), ray_typedef, "from", camera_pos) - sdk.set_native_field(sdk.to_ptr(shoot_ray), ray_typedef, "dir", fixed_dir) - - last_cutscene_state = re7.is_in_cutscene -end - -local function on_pre_player_camera_update(args) - last_camera_update_args = args - - if not vrmod:is_hmd_active() then - return - end - - --local player_camera = sdk.to_managed_object(args[2]) - --fix_player_camera(player_camera) - - --[[local player_camera = sdk.to_managed_object(args[2]) - - local camera = sdk.get_primary_camera() - local camera_gameobject = camera:call("get_GameObject") - local camera_transform = camera_gameobject:call("get_Transform")]] - --last_real_camera_rotation = camera_transform:call("get_Rotation") - --last_real_camera_joint_rotation = camera_transform:call("get_Joints")[0]:call("get_Rotation") - - --return sdk.PreHookResult.SKIP_ORIGINAL -end - -local function on_post_player_camera_update(retval) - local args = last_camera_update_args - - local player_camera = sdk.to_managed_object(args[2]) - fix_player_camera(player_camera) - - return retval -end - -local function on_pre_player_interp_rotation(args) - local player_camera = sdk.to_managed_object(args[2]) - - local camera = sdk.get_primary_camera() - local camera_gameobject = camera:call("get_GameObject") - local camera_transform = camera_gameobject:call("get_Transform") - - re7.is_in_cutscene = true - fix_player_camera(player_camera) -end - -local function on_post_player_interp_rotation(retval) - return retval -end - --- Normal Ethan camera ---[[sdk.hook( - sdk.find_type_definition("app.PlayerCamera"):get_method("interpRotation"), - on_pre_player_interp_rotation, - on_post_player_interp_rotation -)]] - --- Normal Ethan camera -sdk.hook( - sdk.find_type_definition("app.PlayerCamera"):get_method("lateUpdate"), - on_pre_player_camera_update, - on_post_player_camera_update -) - --- Not a hero camera -sdk.hook( - sdk.find_type_definition("app.CH8PlayerCamera"):get_method("lateUpdate"), - on_pre_player_camera_update, - on_post_player_camera_update -) - --- idk the other DLC? -sdk.hook( - sdk.find_type_definition("app.CH9PlayerCamera"):get_method("lateUpdate"), - on_pre_player_camera_update, - on_post_player_camera_update -) - --- Zero out the camera shake -sdk.hook( - sdk.find_type_definition("app.PlayerCamera"):get_method("updateCameraShakeValue"), - function(args) - if not cfg.all_camera_shake then - return sdk.PreHookResult.SKIP_ORIGINAL - end - end, - function(retval) - if not vrmod:is_hmd_active() or not vrmod:is_using_controllers() then - return retval - end - - local args = last_camera_update_args - if args == nil then return retval end - - local player_camera = sdk.to_managed_object(args[2]) - - local zero_quat = Quaternion.new(1, 0, 0, 0) - local zero_vec = Vector3f.new(0, 0, 0) - - if not cfg.movement_shake then - player_camera:set_field("MovementShakePosition", zero_vec) - player_camera:set_field("MovementShakeRotation", zero_quat) - end - - return retval - end -) - -local function on_pre_upper_vertical_update(args) - if not vrmod:is_hmd_active() or not vrmod:is_using_controllers() then - return - end - - --[[local upper_vertical = sdk.to_managed_object(args[2]) - - if not last_camera_update_args then return end - local player_camera = sdk.to_managed_object(last_camera_update_args[2]) - - local camera_rot = player_camera:get_field("k__BackingField") - local camera_pos = player_camera:get_field("k__BackingField") - - vrmod:apply_hmd_transform(camera_rot, camera_pos) - - player_camera:set_field("k__BackingField", camera_rot) - player_camera:set_field("k__BackingField", camera_pos) - - player_camera:set_field("CameraRotationWithMovementShake", camera_rot) - player_camera:set_field("CameraPositionWithMovementShake", camera_pos) - player_camera:set_field("CameraRotationWithCameraShake", camera_rot) - player_camera:set_field("CameraPositionWithCameraShake", camera_pos)]] - --player_camera:set_field("OtherShakeRotation", camera_rot) - --player_camera:set_field("OtherShakePosition", camera_pos) -end - -local function on_post_upper_vertical_update(retval) - return retval -end - -sdk.hook( - sdk.find_type_definition("app.PlayerUpperVerticalRotate"):get_method("doLateUpdate"), - on_pre_upper_vertical_update, - on_post_upper_vertical_update -) - -local function check_player_hands_up() - local player = re7.player - - if not player then - re7.wants_block = false - return - end - - local right_hand_up = false - local left_hand_up = false - - - local controllers = vrmod:get_controllers() - if #controllers < 2 then - re7.wants_block = false - return - end - - local hmd = vrmod:get_transform(0) - local left_hand = vrmod:get_transform(controllers[1]) - local right_hand = vrmod:get_transform(controllers[2]) - - local delta_to_left = left_hand[3] - hmd[3] - local delta_to_right = right_hand[3] - hmd[3] - local dir_to_left = delta_to_left:normalized() - local dir_to_right = delta_to_right:normalized() - - local hmd_forward = hmd[2] - - local left_hand_dot = math.abs(hmd_forward:dot(dir_to_left)) - local right_hand_dot = math.abs(hmd_forward:dot(dir_to_right)) - - local left_hand_in_front = left_hand_dot >= 0.8 - local right_hand_in_front = right_hand_dot >= 0.8 - - local first_test = left_hand_in_front and right_hand_in_front - - if not first_test then - re7.wants_block = false - return - end - - -- now we need to check if the hands are facing up - local left_hand_up_dot = math.abs(hmd_forward:dot(left_hand[0])) - local right_hand_up_dot = math.abs(hmd_forward:dot(right_hand[0])) - - left_hand_up = left_hand_up_dot >= 0.5 - right_hand_up = right_hand_up_dot >= 0.5 - - re7.wants_block = left_hand_up and right_hand_up - - --log.info("left hand dot: " .. tostring(left_hand_dot)) - --log.info("right hand dot: " .. tostring(right_hand_dot)) -end - -local should_reset_view_no_player = false - -re.on_pre_application_entry("UpdateBehavior", function() - check_player_hands_up() - - if not re7.player then - if should_reset_view_no_player then - vrmod:recenter_view() - vrmod:set_gui_rotation_offset(Quaternion.identity()) - should_reset_view_no_player = false - end - else - should_reset_view_no_player = true - end -end) - -re.on_pre_application_entry("PrepareRendering", function() - update_hand_ik() -end) - -re.on_application_entry("UpdateMotion", function() - --[[local camera = sdk.get_primary_camera() - - -- apply the camera rot to the real camera - local camera_gameobject = camera:call("get_GameObject") - local camera_transform = camera_gameobject:call("get_Transform") - - local camera_rot = camera_transform:call("get_Rotation") - local camera_pos = camera_transform:call("get_Position") - - local camera_rot_pre_hmd = Quaternion.new(camera_rot.w, camera_rot.x, camera_rot.y, camera_rot.z) - - vrmod:apply_hmd_transform(neg_forward_identity * camera_rot, camera_pos) - - update_body_ik(camera_rot_pre_hmd, camera_pos)]] - - update_hand_ik() -end) - ---[[re.on_pre_application_entry("LateUpdateBehavior", function() - update_hand_ik() -end)]] - -re.on_application_entry("LateUpdateBehavior", function() - update_hand_ik() -end) - -re.on_application_entry("UpdateHID", function() - --[[local padman = sdk.get_managed_singleton(sdk.game_namespace("PadManager")) - - if padman then - update_padman(padman) - end]] -end) - -re.on_application_entry("LockScene", function() - --[[if not vrmod:is_hmd_active() then return end - local camera = sdk.get_primary_camera() - - if camera ~= nil and last_real_camera_joint_rotation ~= nil then - local camera_gameobject = camera:call("get_GameObject") - local camera_transform = camera_gameobject:call("get_Transform") - local camera_joint = camera_transform:call("get_Joints")[0] - - joint_set_position:call(camera_joint, last_real_camera_joint_pos) - joint_set_rotation:call(camera_joint, last_real_camera_joint_rotation) - end]] -end) - -local last_roomscale_failure = os.clock() - -re.on_pre_application_entry("UnlockScene", function() - if queue_recenter then - vrmod:recenter_view() - queue_recenter = false - end - - if not vrmod:is_hmd_active() then last_roomscale_failure = os.clock() return end - if not re7.player or not re7.transform then last_roomscale_failure = os.clock() return end - if not last_camera_matrix then last_roomscale_failure = os.clock() return end - if re7.is_in_cutscene then last_roomscale_failure = os.clock() return end - - if os.clock() - last_roomscale_failure < 1.0 then return end - - local standing_origin = vrmod:get_standing_origin() - local hmd_pos = vrmod:get_position(0) - - hmd_pos.y = 0.0 - standing_origin.y = 0.0 - - if (hmd_pos - standing_origin):length() >= 0.01 then - standing_origin = vrmod:get_standing_origin() - hmd_pos.y = standing_origin.y - - local old_standing_origin = Vector4f.new(standing_origin.x, standing_origin.y, standing_origin.z, standing_origin.w) - - standing_origin = standing_origin:lerp(hmd_pos, (hmd_pos - standing_origin):length() * 0.1) - - local standing_diff = standing_origin - old_standing_origin - - vrmod:set_standing_origin(standing_origin) - - local player_pos = transform_get_position:call(re7.transform) - local lerp_to = Vector3f.new(last_camera_matrix[3].x, player_pos.y, last_camera_matrix[3].z) - - player_pos = player_pos + ((lerp_to - player_pos):normalized() * standing_diff:length()) - --player_pos:lerp(lerp_to, 0.1) - --player_pos.x = last_camera_matrix[3].x - --player_pos.z = last_camera_matrix[3].z - - --transform_set_position:call(re7.transform, player_pos) - re7.transform:set_position(player_pos, true) -- NO DIRTY - end -end) - -re.on_application_entry("BeginRendering", function() - if not vrmod:is_hmd_active() then return end - local camera = sdk.get_primary_camera() - - if camera ~= nil then - --local camera_gameobject = camera:call("get_GameObject") - --[[local camera_transform = camera_gameobject:call("get_Transform") - local camera_joint = camera_transform:call("get_Joints")[0] - - last_camera_matrix = joint_get_rotation:call(camera_joint):to_mat4() - last_camera_matrix[3] = joint_get_position:call(camera_joint)]] - - last_camera_matrix = camera:call("get_WorldMatrix") - end -end) - -re.on_config_save(function() - json.dump_file(cfg_path, cfg) -end) - -local type_to_table = function(obj) -end - -local function obj_to_table(obj, seen_objects) - seen_objects = seen_objects or {} - - if obj == nil or seen_objects[obj] ~= nil and seen_objects[obj] > 0 then - return { __null = true } - end - - if tostring(type(obj)) ~= "userdata" then - --log.debug(tostring(obj)) - return obj - end - - local out = {} - - local readable_type_name = tostring(getmetatable(obj).__name) - - --log.debug(readable_type_name) - - if readable_type_name:find("glm::mat<4,4") then - out = { - { x = obj[0][0], y = obj[0][1], z = obj[0][2], w = obj[0][3]}, - { x = obj[1][0], y = obj[1][1], z = obj[1][2], w = obj[1][3]}, - { x = obj[2][0], y = obj[2][1], z = obj[2][2], w = obj[2][3]}, - { x = obj[3][0], y = obj[3][1], z = obj[3][2], w = obj[3][3]}, - } - - return out - elseif readable_type_name:find("glm::vec<4") or readable_type_name:find("glm::qua<") then - out = { - x = obj.x, - y = obj.y, - z = obj.z, - w = obj.w - } - - return out - elseif readable_type_name:find("glm::vec<3") then - out = { - x = obj.x, - y = obj.y, - z = obj.z - } - - return out - elseif readable_type_name:find("glm::vec<2") then - out = { - x = obj.x, - y = obj.y - } - - return out - end - - if seen_objects[obj] ~= nil then - seen_objects[obj] = seen_objects[obj] + 1 - else - seen_objects[obj] = 1 - end - - if getmetatable(obj).get_type_definition == nil then - out = { __REFRAMEWORK_UNIMPLEMENTED_TYPE = getmetatable(obj).__name } - - return out - end - - out["__type"] = obj:get_type_definition():get_full_name() - - if obj:get_type_definition():is_a("via.GameObject") then - local components = obj:call("get_Components") - components = components and components:get_elements() or {} - - out["__components"] = { __num = #components } - - for i, component in ipairs(components) do - out["__components"][tostring(i)] = obj_to_table(component, seen_objects) - end - end - - --log.debug(tostring(type(obj))) - --log.debug(tostring(obj) .. ": " .. tostring(getmetatable(obj).__name)) - local fields = obj:get_type_definition():get_fields() - - for i, field in ipairs(fields) do - if not field:is_static() then - local field_type = field:get_type() - --log.debug("field: " .. field:get_name() .. " " .. field_type:get_full_name()) - local ok, value = pcall(obj.get_field, obj, field:get_name()) - - --log.debug(" " .. tostring(ok)) - - if not ok then - log.debug("error on field: " .. obj:get_type_definition():get_full_name() .. "." .. field:get_name()) - end - - if not ok then goto continue end - - --log.debug(field:get_name()) - local type_definition = nil - - if value ~= nil and tostring(type(value)) == "userdata" and getmetatable(value).get_type_definition ~= nil then - type_definition = value:get_type_definition() - end - - if type_definition and type_definition:is_array() and tostring(type(value)) == "userdata" then - local array = {} - local array_elems = value ~= nil and value:get_elements() or {} - - for i, elem in ipairs(array_elems) do - --array[i] = obj_to_table(elem) - end - - out[field:get_name()] = array - elseif field_type:is_primitive() or field_type:is_enum() then - --out[field:get_name()] = value - elseif not field_type:is_value_type() then - if tostring(type(value)) == "userdata" then - --log.debug(tostring(value) .. ": " .. tostring(getmetatable(value).__name)) - out[field:get_name()] = obj_to_table(value, seen_objects) - else - --out[field:get_name()] = value - end - else -- value type - --out[field:get_name()] = obj_to_table(value, seen_objects) - end - - ::continue:: - end - end - - seen_objects[obj] = seen_objects[obj] - 1 - - return out -end - ---[[local tbl = obj_to_table(__object_explorer_object) -json.dump_file("object_explorer/" .. __object_explorer_object_path .. ".json", tbl) - -collectgarbage("collect")]] -- force a GC to free up the memory - -re.on_draw_ui(function() - local changed = false - - changed, cfg.movement_shake = imgui.checkbox("Movement Shake", cfg.movement_shake) - changed, cfg.all_camera_shake = imgui.checkbox("All Other Camera Shakes", cfg.all_camera_shake) - - changed, left_hand_rotation_vec = imgui.drag_float3("Left Hand Rotation Offset", left_hand_rotation_vec, 0.005, -5.0, 5.0) - - if changed then - left_hand_rotation_offset = Quaternion.new(left_hand_rotation_vec):normalized() - end - - changed, right_hand_rotation_vec = imgui.drag_float3("Right Hand Rotation Offset", right_hand_rotation_vec, 0.005, -5.0, 5.0) - - if changed then - right_hand_rotation_offset = Quaternion.new(right_hand_rotation_vec):normalized() - end - - changed, left_hand_position_offset = imgui.drag_float4("Left Hand Position Offset", left_hand_position_offset, 0.005, -5.0, 5.0) - changed, right_hand_position_offset = imgui.drag_float4("Right Hand Position Offset", right_hand_position_offset, 0.005, -5.0, 5.0) - - if imgui.tree_node("Debug") then - imgui.text("Last GUI Dot: " .. tostring(last_gui_dot)) - - if imgui.tree_node("Player") then - object_explorer:handle_address(re7.player) - - imgui.tree_pop() - end - - if imgui.tree_node("Right Hand IK") then - local right_hand_ik = re7.right_hand_ik - - object_explorer:handle_address(right_hand_ik) - - imgui.tree_pop() - end - - if imgui.tree_node("Left Hand IK") then - local left_hand_ik = re7.left_hand_ik - - object_explorer:handle_address(left_hand_ik) - - imgui.tree_pop() - end - - if imgui.button("test dump") then - local d = function(name) - local obj = sdk.get_managed_singleton(name) - - if obj then - local tbl2 = obj_to_table(obj, {}) - json.dump_file("object_explorer/" .. obj:get_type_definition():get_full_name() .. ".json", tbl2) - end - end - - --d("app.VrGuiManager") - --d("app.vr.VrManager") - --d("app.GameManager") - d("app.ObjectManager") - end - - imgui.tree_pop() - end -end) - -re.on_pre_gui_draw_element(function(element, context) - if not vrmod:is_hmd_active() then return true end - - local game_object = element:call("get_GameObject") - if game_object == nil then return true end - - local name = game_object:call("get_Name") - - --log.info("drawing element: " .. name) - - if name == "ReticleGUI" then - if vrmod:is_using_controllers() then - return false - end - end - - return true -end) \ No newline at end of file diff --git a/scripts/re8_vr.lua b/scripts/re8_vr.lua index 2f0b60065..13ec3841e 100644 --- a/scripts/re8_vr.lua +++ b/scripts/re8_vr.lua @@ -1806,7 +1806,7 @@ json.dump_file("object_explorer/" .. __object_explorer_object_path .. ".json", t collectgarbage("collect")]] -- force a GC to free up the memory -local function on_pre_order_vibration(args) +local function re8_on_pre_order_vibration(args) if not vrmod:is_using_controllers() then return end @@ -1831,14 +1831,16 @@ local function on_pre_order_vibration(args) end end -local function on_post_order_vibration(retval) +local function re8_on_post_order_vibration(retval) return retval end -local vibrationmanager_t = sdk.find_type_definition("app.HIDVibrationManager") -sdk.hook(vibrationmanager_t:get_method("OrderVibration(app.VibrationTask)"), on_pre_order_vibration, on_post_order_vibration) +if is_re8 then + local vibrationmanager_t = sdk.find_type_definition("app.HIDVibrationManager") + sdk.hook(vibrationmanager_t:get_method("OrderVibration(app.VibrationTask)"), re8_on_pre_order_vibration, re8_on_post_order_vibration) +end -local function on_pre_order_vibration2(args) +local function re8_on_pre_order_vibration2(args) if not vrmod:is_using_controllers() then return end @@ -1857,12 +1859,41 @@ local function on_pre_order_vibration2(args) --end end -local function on_post_order_vibration2(retval) +local function re8_on_post_order_vibration2(retval) return retval end -local vibmethod2 = vibrationmanager_t:get_method("OrderVibration(System.Single, System.Single, System.Single, System.Boolean, System.Int32, System.Boolean, System.Single, System.Single, via.GameObject, System.Single, System.Single)") -sdk.hook(vibmethod2, on_pre_order_vibration2, on_post_order_vibration2) +if is_re8 then + local vibrationmanager_t = sdk.find_type_definition("app.HIDVibrationManager") + local vibmethod2 = vibrationmanager_t:get_method("OrderVibration(System.Single, System.Single, System.Single, System.Boolean, System.Int32, System.Boolean, System.Single, System.Single, via.GameObject, System.Single, System.Single)") + sdk.hook(vibmethod2, re8_on_pre_order_vibration2, re8_on_post_order_vibration2) +end + +local function re7_on_pre_request_add_vibration(args) + if not vrmod:is_using_controllers() then + return + end + + local param = sdk.to_managed_object(args[3]) + local duration = sdk.to_float(args[4]) + + local power = param:get_field("HighMotorPower") + + local left_joystick = vrmod:get_left_joystick() + vrmod:trigger_haptic_vibration(0.0, duration, 1, power, left_joystick) + + local right_joystick = vrmod:get_right_joystick() + vrmod:trigger_haptic_vibration(0.0, duration, 1, power, right_joystick) +end + +local function re7_on_post_request_add_vibration(retval) + return retval +end + +if is_re7 then + local vibrationmanager_t = sdk.find_type_definition("app.VibrationManager") + sdk.hook(vibrationmanager_t:get_method("requestAdd(app.VibrationParam, System.Single)"), re7_on_pre_request_add_vibration, re7_on_post_request_add_vibration) +end re.on_draw_ui(function() local changed = false From 41b6be8beb93740c97fd0181b3290120ed7041d0 Mon Sep 17 00:00:00 2001 From: praydog Date: Tue, 29 Mar 2022 04:28:02 -0700 Subject: [PATCH 11/45] VR (RE7/8): Fix grenade launcher, add world-space crosshair, fix scopes --- scripts/re8_vr.lua | 238 ++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 222 insertions(+), 16 deletions(-) diff --git a/scripts/re8_vr.lua b/scripts/re8_vr.lua index 13ec3841e..da60eec05 100644 --- a/scripts/re8_vr.lua +++ b/scripts/re8_vr.lua @@ -3,7 +3,7 @@ local is_re7 = game_name == "re7" local is_re8 = game_name == "re8" if not is_re7 and not is_re8 then - msg("Error: Game is not RE7 or RE8.") + re.msg("Error: Game is not RE7 or RE8.") return end @@ -49,6 +49,12 @@ local joint_get_parent = sdk.find_type_definition("via.Joint"):get_method("get_P local component_get_gameobject = sdk.find_type_definition("via.Component"):get_method("get_GameObject") local gameobject_get_transform = sdk.find_type_definition("via.GameObject"):get_method("get_Transform") +local motion_get_joint_index_by_name_hash = sdk.find_type_definition("via.motion.Motion"):get_method("getJointIndexByNameHash") +local motion_get_world_position = sdk.find_type_definition("via.motion.Motion"):get_method("getWorldPosition") +local motion_get_world_rotation = sdk.find_type_definition("via.motion.Motion"):get_method("getWorldRotation") + +local cast_ray_method = sdk.find_type_definition("via.physics.System"):get_method("castRay(via.physics.CastRayQuery, via.physics.CastRayResult)") + local cfg_path = "re7_vr/main_config.json" local queue_recenter = false @@ -61,11 +67,13 @@ local last_gui_forced_slerp = os.clock() local needs_cutscene_recenter = false local last_inventory_open_time = 0.0 local last_shop_open_time = 0.0 +local last_scope_time = 0.0 local head_hash = nil local cfg = { movement_shake = false, - all_camera_shake = true + all_camera_shake = true, + disable_crosshair = false } local function load_cfg() @@ -86,6 +94,14 @@ load_cfg() statics.generate_global("via.hid.GamePadButton") statics.generate_global("via.hid.MouseButton") +local CollisionLayer = nil + +if is_re8 then + CollisionLayer = statics.generate("app.CollisionManager.Layer") +elseif is_re7 then + CollisionLayer = statics.generate("app.Collision.CollisionSystem.Layer") +end + if is_re7 then statics.generate_global("app.HIDManager.InputMode") elseif is_re8 then @@ -578,13 +594,13 @@ local function update_hand_ik() end - local left_index = motion:call("getJointIndexByNameHash", left_hash) - local right_index = motion:call("getJointIndexByNameHash", right_hash) + local left_index = motion_get_joint_index_by_name_hash(motion, left_hash) + local right_index = motion_get_joint_index_by_name_hash(motion, right_hash) - local original_left_pos = motion:call("getWorldPosition", left_index) - local original_right_pos = motion:call("getWorldPosition", right_index) - local original_left_rot = motion:call("getWorldRotation", left_index) - original_right_rot = motion:call("getWorldRotation", right_index) + local original_left_pos = motion_get_world_position(motion, left_index) + local original_right_pos = motion_get_world_position(motion, right_index) + local original_left_rot = motion_get_world_rotation(motion, left_index) + original_right_rot = motion_get_world_rotation(motion, right_index) original_left_pos_relative = original_right_rot:inverse() * (original_left_pos - original_right_pos) original_left_rot_relative = original_right_rot:inverse() * original_left_rot @@ -884,11 +900,11 @@ local function on_pre_shoot(args) log.info("No muzzle joint found") end elseif is_re8 then]] - local pos = last_muzzle_pos + (last_muzzle_forward * 0.01) + local pos = last_muzzle_pos + (last_muzzle_forward * 0.02) local from = Vector4f.new(pos.x, pos.y, pos.z, 1.0) local dir = Vector4f.new(last_muzzle_forward.x, last_muzzle_forward.y, last_muzzle_forward.z, 1.0) - sdk.set_native_field(ray, ray_typedef, "from", pos) + sdk.set_native_field(ray, ray_typedef, "from", from) sdk.set_native_field(ray, ray_typedef, "dir", dir) --end @@ -973,6 +989,70 @@ elseif is_re8 then ) end +local function cast_ray(start_pos, end_pos) + local via_physics_system = sdk.get_native_singleton("via.physics.System") + local ray_query = sdk.create_instance("via.physics.CastRayQuery") + local ray_result = sdk.create_instance("via.physics.CastRayResult") + + ray_query:call("setRay(via.vec3, via.vec3)", start_pos, end_pos) + ray_query:call("clearOptions") + ray_query:call("enableAllHits") + ray_query:call("enableNearSort") + --ray_query:call("enableFrontFacingTriangleHits") + --ray_query:call("disableBackFacingTriangleHits") + local filter_info = ray_query:call("get_FilterInfo") + filter_info:call("set_Group", 0) + filter_info:call("set_MaskBits", 0xFFFFFFFF & ~1) -- everything except the player. + + local target_layers = { + CollisionLayer.Attack, + CollisionLayer.Bullet + } + + for i=1, 2 do + filter_info:call("set_Layer", target_layers[i]) + ray_query:call("set_FilterInfo", filter_info) + cast_ray_method:call(via_physics_system, ray_query, ray_result) + + if ray_result:call("get_NumContactPoints") > 0 then + break + end + end + + return ray_result +end + +local function update_crosshair_world_pos(start_pos, end_pos) + if not vrmod:is_hmd_active() then return end + + if os.clock() - last_scope_time > 0.2 then + if vrmod:is_using_controllers() and cfg.disable_crosshair then + return + end + end + + local ray_result = cast_ray(start_pos, end_pos) + + if ray_result:call("get_NumContactPoints") > 0 then + local contact_point = ray_result:call("getContactPoint(System.UInt32)", 0) + + if contact_point then + re8.crosshair_dir = (end_pos - start_pos):normalized() + re8.crosshair_pos = contact_point:get_field("Position") + re8.crosshair_normal = contact_point:get_field("Normal") + re8.crosshair_distance = contact_point:get_field("Distance") + end + else + re8.crosshair_dir = (end_pos - start_pos):normalized() + if re8.crosshair_distance then + re8.crosshair_pos = start_pos + (re8.crosshair_dir * re8.crosshair_distance) + else + re8.crosshair_pos = start_pos + (re8.crosshair_dir * 10.0) + re8.crosshair_distance = 10.0 + end + end +end + local last_camera_update_args = nil local last_cutscene_state = false local last_time_not_maximum_controllable = 0.0 @@ -1293,15 +1373,21 @@ local function fix_player_camera(player_camera) sdk.set_native_field(sdk.to_ptr(look_ray), ray_typedef, "dir", fixed_dir) if vrmod:is_using_controllers() then - local pos = last_muzzle_pos + (last_muzzle_forward * 0.01) + local pos = last_muzzle_pos + (last_muzzle_forward * 0.02) + --local scooted_pos = last_muzzle_pos - (last_muzzle_forward * 2) + --local scooted_from = Vector4f.new(scooted_pos.x, scooted_pos.y, scooted_pos.z, 1.0) local from = Vector4f.new(pos.x, pos.y, pos.z, 1.0) local dir = Vector4f.new(last_muzzle_forward.x, last_muzzle_forward.y, last_muzzle_forward.z, 1.0) sdk.set_native_field(sdk.to_ptr(shoot_ray), ray_typedef, "from", from) sdk.set_native_field(sdk.to_ptr(shoot_ray), ray_typedef, "dir", dir) + + update_crosshair_world_pos(pos, pos + (last_muzzle_forward * 1000.0)) else sdk.set_native_field(sdk.to_ptr(shoot_ray), ray_typedef, "from", camera_pos) sdk.set_native_field(sdk.to_ptr(shoot_ray), ray_typedef, "dir", fixed_dir) + + update_crosshair_world_pos(camera_pos, camera_pos + (fixed_dir * 1000.0)) end last_cutscene_state = re8.is_in_cutscene @@ -1629,6 +1715,11 @@ re.on_pre_application_entry("UnlockScene", function() end end) +local via_murmur_hash = sdk.find_type_definition("via.murmur_hash") +local via_murmur_hash_calc32 = via_murmur_hash:get_method("calc32") +local vfx_muzzle1_hash = via_murmur_hash_calc32:call(nil, "vfx_muzzle1") +local vfx_muzzle2_hash = via_murmur_hash_calc32:call(nil, "vfx_muzzle2") + re.on_application_entry("BeginRendering", function() if not vrmod:is_hmd_active() then return end local camera = sdk.get_primary_camera() @@ -1649,9 +1740,31 @@ re.on_application_entry("BeginRendering", function() -- so we're just going to directly grab the field instead local muzzle_joint = re8.weapon:get_field("MuzzleJoint") + if muzzle_joint == nil then + local weapon_gameobject = nil + + if is_re7 then + weapon_gameobject = re8.weapon:call("get_GameObject") + elseif is_re8 then + weapon_gameobject = re8.weapon:get_field("k__BackingField") + end + + if weapon_gameobject ~= nil then + local transform = gameobject_get_transform(weapon_gameobject) + + if transform ~= nil then + muzzle_joint = transform_get_joint_by_hash(transform, vfx_muzzle1_hash) + + if not muzzle_joint then + muzzle_joint = transform_get_joint_by_hash(transform, vfx_muzzle2_hash) + end + end + end + end + if muzzle_joint then - local muzzle_position = muzzle_joint:call("get_Position") - local muzzle_rotation = muzzle_joint:call("get_Rotation") + local muzzle_position = joint_get_position(muzzle_joint) + local muzzle_rotation = joint_get_rotation(muzzle_joint) last_muzzle_pos = muzzle_position last_muzzle_rot = muzzle_rotation @@ -1895,11 +2008,24 @@ if is_re7 then sdk.hook(vibrationmanager_t:get_method("requestAdd(app.VibrationParam, System.Single)"), re7_on_pre_request_add_vibration, re7_on_post_request_add_vibration) end +local cached_contact_pos = nil + +re.on_frame(function() + if cached_contact_pos then + local screen = draw.world_to_screen(cached_contact_pos) + + if screen then + draw.filled_rect(screen.x - 10, screen.y - 10, 5, 5, 0xFFFFFFFF) + end + end +end) + re.on_draw_ui(function() local changed = false changed, cfg.movement_shake = imgui.checkbox("Movement Shake", cfg.movement_shake) changed, cfg.all_camera_shake = imgui.checkbox("All Other Camera Shakes", cfg.all_camera_shake) + changed, cfg.disable_crosshair = imgui.checkbox("Disable Crosshair", cfg.disable_crosshair) changed, left_hand_rotation_vec = imgui.drag_float3("Left Hand Rotation Offset", left_hand_rotation_vec, 0.005, -5.0, 5.0) @@ -1919,6 +2045,22 @@ re.on_draw_ui(function() if imgui.tree_node("Debug") then imgui.text("Last GUI Dot: " .. tostring(last_gui_dot)) + if imgui.button("Cast ray") then + local camera = sdk.get_primary_camera() + local start_pos = camera:call("get_WorldMatrix")[3] + local end_pos = start_pos - (camera:call("get_WorldMatrix")[2] * 1000.0) + + log.debug("Casting from " .. tostring(start_pos.x) .. tostring(start_pos.y) .. tostring(start_pos.z)) + + local ray_result = cast_ray(start_pos, end_pos) + local contact_point = ray_result:call("getContactPoint(System.UInt32)", 0) + local contact_pos = contact_point:get_field("Position") + + cached_contact_pos = contact_pos + + log.debug("hit: " .. tostring(contact_pos.x) .. ", " .. tostring(contact_pos.y) .. ", " .. tostring(contact_pos.z)) + end + if imgui.tree_node("Player") then object_explorer:handle_address(re8.player) @@ -2000,6 +2142,14 @@ for i, v in ipairs(reticle_names) do reticle_names[v] = true end +local scope_names = { + "GUIScope" +} + +for i, v in ipairs(scope_names) do + scope_names[v] = true +end + local shop_names = { "GUIShopBg", } @@ -2008,6 +2158,17 @@ for i, v in ipairs(shop_names) do shop_names[v] = true end +local function read_vec4(obj, offset) + return Vector4f.new(obj:read_float(offset), obj:read_float(offset + 4), obj:read_float(offset + 8), obj:read_float(offset + 12)) +end + +local function write_vec4(obj, vec, offset) + obj:write_float(offset, vec.x) + obj:write_float(offset + 4, vec.y) + obj:write_float(offset + 8, vec.z) + obj:write_float(offset + 12, vec.w) +end + re.on_pre_gui_draw_element(function(element, context) if not vrmod:is_hmd_active() then return true end @@ -2019,11 +2180,55 @@ re.on_pre_gui_draw_element(function(element, context) --log.info("drawing element: " .. name) if reticle_names[name] then - if vrmod:is_using_controllers() then + if cfg.disable_crosshair and vrmod:is_using_controllers() then return false end end + if scope_names[name] then + last_scope_time = os.clock() + end + + -- set the world position of the crosshair/reticle to the trace end position + -- also fixes scopes. + if reticle_names[name] or scope_names[name] then + if re8.crosshair_pos then + local transform = game_object:call("get_Transform") + + if transform then + --[[if transform.set_position ~= nil then + transform:set_position(re8.crosshair_pos, true) + else + transform_set_position(transform, re8.crosshair_pos) + end]] + + local new_mat = re8.crosshair_dir:to_quat():to_mat4() + local distance = re8.crosshair_distance * 0.1 + if distance > 10 then + distance = 10 + end + + if distance < 0.3 then + distance = 0.3 + end + + local crosshair_pos = Vector4f.new(re8.crosshair_pos.x, re8.crosshair_pos.y, re8.crosshair_pos.z, 1.0) + + if is_re8 then + write_vec4(transform, new_mat[0] * distance, 0x80) + write_vec4(transform, new_mat[1] * distance, 0x90) + write_vec4(transform, new_mat[2] * distance, 0xA0) + write_vec4(transform, crosshair_pos, 0xB0) + elseif is_re7 then + write_vec4(transform, new_mat[0] * distance, 0x90) + write_vec4(transform, new_mat[1] * distance, 0xA0) + write_vec4(transform, new_mat[2] * distance, 0xB0) + write_vec4(transform, crosshair_pos, 0xC0) + end + end + end + end + if re8_inventory_names[name] then last_inventory_open_time = os.clock() end @@ -2035,8 +2240,9 @@ re.on_pre_gui_draw_element(function(element, context) local transform = game_object:call("get_Transform") local old_pos = transform:get_position() - local camera_pos = sdk.get_primary_camera():call("get_WorldMatrix")[3] - local camera_forward = sdk.get_primary_camera():call("get_WorldMatrix")[2] + local camera = sdk.get_primary_camera() + local camera_pos = camera:call("get_WorldMatrix")[3] + local camera_forward = camera:call("get_WorldMatrix")[2] local old_distance = (old_pos - camera_pos):length() From d42e8916a230485bf348dd00abad3cf1f7dec15f Mon Sep 17 00:00:00 2001 From: praydog Date: Tue, 29 Mar 2022 05:50:36 -0700 Subject: [PATCH 12/45] VR (RE7): Fix turrets shooting at the wrong spot --- scripts/re8_vr.lua | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/scripts/re8_vr.lua b/scripts/re8_vr.lua index da60eec05..ebeaf88e7 100644 --- a/scripts/re8_vr.lua +++ b/scripts/re8_vr.lua @@ -876,9 +876,15 @@ local function on_pre_shoot(args) return end + local weapon = sdk.to_managed_object(args[2]) + + -- this happens in RE7 with the turrets. + if weapon ~= re8.weapon then + return + end + update_hand_ik() - local weapon = sdk.to_managed_object(args[2]) local ray = args[3] --[[if is_re7 then From 3193cb702a5f7c91a31d6dc79160dfa947d816a7 Mon Sep 17 00:00:00 2001 From: praydog Date: Wed, 6 Apr 2022 02:15:01 -0700 Subject: [PATCH 13/45] VR (RE7/8): Add DPad actions --- scripts/re8_vr.lua | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/scripts/re8_vr.lua b/scripts/re8_vr.lua index ebeaf88e7..2aa0d0c31 100644 --- a/scripts/re8_vr.lua +++ b/scripts/re8_vr.lua @@ -194,6 +194,10 @@ local function update_pad_device(device) local action_weapon_dial = vrmod:get_action_weapon_dial() local action_minimap = vrmod:get_action_minimap() local action_block = vrmod:get_action_block() + local action_dpad_up = vrmod:get_action_dpad_up() + local action_dpad_down = vrmod:get_action_dpad_down() + local action_dpad_left = vrmod:get_action_dpad_left() + local action_dpad_right = vrmod:get_action_dpad_right() local right_joystick = vrmod:get_right_joystick() local left_joystick = vrmod:get_left_joystick() @@ -226,6 +230,22 @@ local function update_pad_device(device) elseif vr_left_stick_axis.x <= -0.9 then cur_button = cur_button | via.hid.GamePadButton.LLeft end + else + if vrmod:is_action_active(action_dpad_up, left_joystick) then + cur_button = cur_button | via.hid.GamePadButton.LUp + end + + if vrmod:is_action_active(action_dpad_down, left_joystick) then + cur_button = cur_button | via.hid.GamePadButton.LDown + end + + if vrmod:is_action_active(action_dpad_left, left_joystick) then + cur_button = cur_button | via.hid.GamePadButton.LLeft + end + + if vrmod:is_action_active(action_dpad_right, left_joystick) then + cur_button = cur_button | via.hid.GamePadButton.LRight + end end if vrmod:is_action_active(action_trigger, left_joystick) then From 059d6a6cee4bd5d3ef4a937428170d361aa53a37 Mon Sep 17 00:00:00 2001 From: praydog Date: Wed, 6 Apr 2022 02:15:46 -0700 Subject: [PATCH 14/45] VR (RE7/8): Reduce world-space crosshair latency --- scripts/re8_vr.lua | 120 +++++++++++++++++++++++++-------------------- 1 file changed, 67 insertions(+), 53 deletions(-) diff --git a/scripts/re8_vr.lua b/scripts/re8_vr.lua index 2aa0d0c31..8555efa94 100644 --- a/scripts/re8_vr.lua +++ b/scripts/re8_vr.lua @@ -32,6 +32,8 @@ local ray_typedef = sdk.find_type_definition("via.Ray") local last_muzzle_pos = Vector4f.new(0.0, 0.0, 0.0, 1.0) local last_muzzle_rot = Quaternion.new(0.0, 0.0, 0.0, 0.0) local last_muzzle_forward = Vector4f.new(0.0, 0.0, 0.0, 1.0) +local last_shoot_pos = Vector4f.new(0.0, 0.0, 0.0, 1.0) +local last_shoot_dir = Vector4f.new(0.0, 0.0, 0.0, 1.0) local transform_get_position = sdk.find_type_definition("via.Transform"):get_method("get_Position") local transform_get_rotation = sdk.find_type_definition("via.Transform"):get_method("get_Rotation") @@ -125,6 +127,50 @@ end local is_inventory_open = false +local function update_muzzle_data() + if re8.weapon then + -- for some reason calling get_muzzleJoint causes lua to randomly freak out + -- so we're just going to directly grab the field instead + local muzzle_joint = re8.weapon:get_field("MuzzleJoint") + + if muzzle_joint == nil then + local weapon_gameobject = nil + + if is_re7 then + weapon_gameobject = re8.weapon:call("get_GameObject") + elseif is_re8 then + weapon_gameobject = re8.weapon:get_field("k__BackingField") + end + + if weapon_gameobject ~= nil then + local transform = gameobject_get_transform(weapon_gameobject) + + if transform ~= nil then + muzzle_joint = transform_get_joint_by_hash(transform, vfx_muzzle1_hash) + + if not muzzle_joint then + muzzle_joint = transform_get_joint_by_hash(transform, vfx_muzzle2_hash) + end + end + end + end + + if muzzle_joint then + local muzzle_position = joint_get_position(muzzle_joint) + local muzzle_rotation = joint_get_rotation(muzzle_joint) + + last_muzzle_pos = muzzle_position + last_muzzle_rot = muzzle_rotation + last_muzzle_forward = muzzle_joint:call("get_AxisZ") + + if vrmod:is_using_controllers() then + last_shoot_dir = last_muzzle_forward + last_shoot_pos = last_muzzle_pos + end + end + end +end + local function update_pad_device(device) if not vrmod:is_hmd_active() then re8.is_holding_left_grip = false @@ -1408,12 +1454,17 @@ local function fix_player_camera(player_camera) sdk.set_native_field(sdk.to_ptr(shoot_ray), ray_typedef, "from", from) sdk.set_native_field(sdk.to_ptr(shoot_ray), ray_typedef, "dir", dir) - update_crosshair_world_pos(pos, pos + (last_muzzle_forward * 1000.0)) + -- called in LockScene + --update_crosshair_world_pos(pos, pos + (last_muzzle_forward * 1000.0)) else + last_shoot_pos = camera_pos + last_shoot_dir = fixed_dir + sdk.set_native_field(sdk.to_ptr(shoot_ray), ray_typedef, "from", camera_pos) sdk.set_native_field(sdk.to_ptr(shoot_ray), ray_typedef, "dir", fixed_dir) - update_crosshair_world_pos(camera_pos, camera_pos + (fixed_dir * 1000.0)) + -- called in LockScene + --update_crosshair_world_pos(camera_pos, camera_pos + (fixed_dir * 1000.0)) end last_cutscene_state = re8.is_in_cutscene @@ -1681,6 +1732,14 @@ re.on_application_entry("UpdateHID", function() end) re.on_application_entry("LockScene", function() + if not vrmod:is_hmd_active() then return end + + update_muzzle_data() + + if last_shoot_pos then + local pos = last_shoot_pos + (last_shoot_dir * 0.02) + update_crosshair_world_pos(pos, pos + (last_shoot_dir * 1000.0)) + end --[[if not vrmod:is_hmd_active() then return end local camera = sdk.get_primary_camera() @@ -1704,7 +1763,11 @@ re.on_pre_application_entry("UnlockScene", function() end if not vrmod:is_hmd_active() then last_roomscale_failure = os.clock() return end + + last_camera_matrix = vrmod:get_last_render_matrix() + if not re8.player or not re8.transform then last_roomscale_failure = os.clock() return end + if not re8.status then last_roomscale_failure = os.clock() return end -- in the main menu or something. if not last_camera_matrix then last_roomscale_failure = os.clock() return end if re8.is_in_cutscene then last_roomscale_failure = os.clock() return end @@ -1746,58 +1809,9 @@ local via_murmur_hash_calc32 = via_murmur_hash:get_method("calc32") local vfx_muzzle1_hash = via_murmur_hash_calc32:call(nil, "vfx_muzzle1") local vfx_muzzle2_hash = via_murmur_hash_calc32:call(nil, "vfx_muzzle2") -re.on_application_entry("BeginRendering", function() - if not vrmod:is_hmd_active() then return end - local camera = sdk.get_primary_camera() - - if camera ~= nil then - --local camera_gameobject = camera:call("get_GameObject") - --[[local camera_transform = camera_gameobject:call("get_Transform") - local camera_joint = camera_transform:call("get_Joints")[0] - - last_camera_matrix = joint_get_rotation:call(camera_joint):to_mat4() - last_camera_matrix[3] = joint_get_position:call(camera_joint)]] - - last_camera_matrix = camera:call("get_WorldMatrix") - end - - if re8.weapon then - -- for some reason calling get_muzzleJoint causes lua to randomly freak out - -- so we're just going to directly grab the field instead - local muzzle_joint = re8.weapon:get_field("MuzzleJoint") - - if muzzle_joint == nil then - local weapon_gameobject = nil - - if is_re7 then - weapon_gameobject = re8.weapon:call("get_GameObject") - elseif is_re8 then - weapon_gameobject = re8.weapon:get_field("k__BackingField") - end - - if weapon_gameobject ~= nil then - local transform = gameobject_get_transform(weapon_gameobject) - - if transform ~= nil then - muzzle_joint = transform_get_joint_by_hash(transform, vfx_muzzle1_hash) - - if not muzzle_joint then - muzzle_joint = transform_get_joint_by_hash(transform, vfx_muzzle2_hash) - end - end - end - end +--[[re.on_application_entry("BeginRendering", function() - if muzzle_joint then - local muzzle_position = joint_get_position(muzzle_joint) - local muzzle_rotation = joint_get_rotation(muzzle_joint) - - last_muzzle_pos = muzzle_position - last_muzzle_rot = muzzle_rotation - last_muzzle_forward = muzzle_joint:call("get_AxisZ") - end - end -end) +end)]] re.on_config_save(function() json.dump_file(cfg_path, cfg) From 9fcbee9bca2d03c761000f9dd687b471c05eb557 Mon Sep 17 00:00:00 2001 From: praydog Date: Wed, 6 Apr 2022 07:51:07 -0700 Subject: [PATCH 15/45] VR (RE7/8): Fix grenade launcher regression after previous commit --- scripts/re8_vr.lua | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/scripts/re8_vr.lua b/scripts/re8_vr.lua index 8555efa94..476f6c8a1 100644 --- a/scripts/re8_vr.lua +++ b/scripts/re8_vr.lua @@ -127,6 +127,11 @@ end local is_inventory_open = false +local via_murmur_hash = sdk.find_type_definition("via.murmur_hash") +local via_murmur_hash_calc32 = via_murmur_hash:get_method("calc32") +local vfx_muzzle1_hash = via_murmur_hash_calc32:call(nil, "vfx_muzzle1") +local vfx_muzzle2_hash = via_murmur_hash_calc32:call(nil, "vfx_muzzle2") + local function update_muzzle_data() if re8.weapon then -- for some reason calling get_muzzleJoint causes lua to randomly freak out @@ -1804,11 +1809,6 @@ re.on_pre_application_entry("UnlockScene", function() end end) -local via_murmur_hash = sdk.find_type_definition("via.murmur_hash") -local via_murmur_hash_calc32 = via_murmur_hash:get_method("calc32") -local vfx_muzzle1_hash = via_murmur_hash_calc32:call(nil, "vfx_muzzle1") -local vfx_muzzle2_hash = via_murmur_hash_calc32:call(nil, "vfx_muzzle2") - --[[re.on_application_entry("BeginRendering", function() end)]] From e03b9dab54eda1aeb0d9d43c5666f5b2c3d99918 Mon Sep 17 00:00:00 2001 From: praydog Date: Wed, 6 Apr 2022 07:51:37 -0700 Subject: [PATCH 16/45] VR (RE7/8): Make use of heal action --- scripts/re8_vr.lua | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/scripts/re8_vr.lua b/scripts/re8_vr.lua index 476f6c8a1..0f1f01db1 100644 --- a/scripts/re8_vr.lua +++ b/scripts/re8_vr.lua @@ -249,6 +249,7 @@ local function update_pad_device(device) local action_dpad_down = vrmod:get_action_dpad_down() local action_dpad_left = vrmod:get_action_dpad_left() local action_dpad_right = vrmod:get_action_dpad_right() + local action_heal = vrmod:get_action_heal() local right_joystick = vrmod:get_right_joystick() local left_joystick = vrmod:get_left_joystick() @@ -305,9 +306,13 @@ local function update_pad_device(device) end -- set right bumper (heal) if holding both trigger and grip - if vrmod:is_action_active(action_grip, left_joystick) then + --[[if vrmod:is_action_active(action_grip, left_joystick) then cur_button = cur_button | via.hid.GamePadButton.RTrigTop - end + end]] + end + + if vrmod:is_action_active(action_heal, left_joystick) or vrmod:is_action_active(action_heal, right_joystick) then + cur_button = cur_button | via.hid.GamePadButton.RTrigTop end re8.is_holding_left_grip = vrmod:is_action_active(action_grip, left_joystick) From 33c98fe201158b4aeaa2cf890d2da3e69970b991 Mon Sep 17 00:00:00 2001 From: praydog Date: Wed, 6 Apr 2022 07:52:37 -0700 Subject: [PATCH 17/45] VR (RE7/8): Fix upper body T-Pose causing softlock in RE7 DLC --- scripts/re8_vr.lua | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/scripts/re8_vr.lua b/scripts/re8_vr.lua index 0f1f01db1..db15de456 100644 --- a/scripts/re8_vr.lua +++ b/scripts/re8_vr.lua @@ -527,6 +527,10 @@ local function calculate_tpose_world(joint, depth) end local function set_hand_joints_to_tpose(hand_ik) + -- fixes an instance in not a hero where + -- chris is supposed to jump down something without tripping a laser + if re8.is_in_cutscene then return end + local hashes = { } @@ -841,7 +845,7 @@ local function update_body_ik(camera_rotation, camera_pos) local ik_leg = player:call("getComponent(System.Type)", sdk.typeof("via.motion.IkLeg")) if not ik_leg then - if not vrmod:is_using_controllers() then + if not vrmod:is_using_controllers() or re8.is_in_cutscene then return end From b693a1a353ba489e049385e7339582a8ffbdf357 Mon Sep 17 00:00:00 2001 From: praydog Date: Thu, 7 Apr 2022 04:03:27 -0700 Subject: [PATCH 18/45] VR (RE7/8): Improve hand IK with decoupled camera pitch --- scripts/re8_vr.lua | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/scripts/re8_vr.lua b/scripts/re8_vr.lua index db15de456..b3b4c4a5e 100644 --- a/scripts/re8_vr.lua +++ b/scripts/re8_vr.lua @@ -682,11 +682,13 @@ local function update_hand_ik() local original_left_rot = motion_get_world_rotation(motion, left_index) original_right_rot = motion_get_world_rotation(motion, right_index) - original_left_pos_relative = original_right_rot:inverse() * (original_left_pos - original_right_pos) - original_left_rot_relative = original_right_rot:inverse() * original_left_rot + local right_rot_inverse = original_right_rot:inverse() + original_left_pos_relative = right_rot_inverse * (original_left_pos - original_right_pos) + original_left_rot_relative = right_rot_inverse * original_left_rot - original_right_pos_relative = original_left_rot:inverse() * (original_right_pos - original_left_pos) - original_right_rot_relative = original_left_rot:inverse() * original_right_rot + local left_rot_inverse = original_left_rot:inverse() + original_right_pos_relative = left_rot_inverse * (original_right_pos - original_left_pos) + original_right_rot_relative = left_rot_inverse * original_right_rot end local left_controller_transform = vrmod:get_transform(controllers[1]) @@ -704,13 +706,13 @@ local function update_hand_ik() local camera_rotation = last_camera_matrix:to_quat() local original_camera_matrix = camera:call("get_WorldMatrix") - local original_camera_rotation_pre = original_camera_matrix:to_quat() - local original_camera_rotation = (original_camera_rotation_pre * vrmod:get_rotation_offset()):normalized() - - local fake_quat = Quaternion.new(original_camera_rotation_pre.w, original_camera_rotation_pre.x, original_camera_rotation_pre.y, original_camera_rotation_pre.z) + local original_camera_rotation = original_camera_matrix:to_quat() local updated_camera_pos = original_camera_matrix[3] - vrmod:apply_hmd_transform(fake_quat, updated_camera_pos) + vrmod:apply_hmd_transform(original_camera_rotation, updated_camera_pos) + + -- Handles decoupled camera pitch + original_camera_rotation = (original_camera_rotation * hmd_transform:to_quat():inverse()):normalized() local rh_rotation = original_camera_rotation * right_controller_rotation * right_hand_rotation_offset local rh_pos = updated_camera_pos From 155946d966d269ad039a65e201a681ad3c57b93c Mon Sep 17 00:00:00 2001 From: praydog Date: Thu, 7 Apr 2022 04:04:08 -0700 Subject: [PATCH 19/45] VR (RE7/8): Initial physically thrown grenades --- scripts/re8_vr.lua | 125 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 120 insertions(+), 5 deletions(-) diff --git a/scripts/re8_vr.lua b/scripts/re8_vr.lua index b3b4c4a5e..c5ab0cf66 100644 --- a/scripts/re8_vr.lua +++ b/scripts/re8_vr.lua @@ -16,6 +16,7 @@ local renderer_type = sdk.find_type_definition("via.render.Renderer") local GamePadButton = statics.generate("via.hid.GamePadButton") +local last_original_right_hand_rotation = Quaternion.new(0.0, 0.0, 0.0, 0.0) local last_camera_matrix = Matrix4x4f.new() local last_right_hand_rotation = Quaternion.new(0.0, 0.0, 0.0, 0.0) local last_right_hand_position = Vector3f.new(0.0, 0.0, 0.0) @@ -72,6 +73,12 @@ local last_shop_open_time = 0.0 local last_scope_time = 0.0 local head_hash = nil + +local neg_forward_identity = Matrix4x4f.new(-1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, -1, 0, + 0, 0, 0, 1):to_quat() + local cfg = { movement_shake = false, all_camera_shake = true, @@ -172,6 +179,16 @@ local function update_muzzle_data() last_shoot_dir = last_muzzle_forward last_shoot_pos = last_muzzle_pos end + elseif vrmod:is_using_controllers() then + last_muzzle_pos = last_right_hand_position + last_muzzle_rot = last_camera_matrix:to_quat() + last_muzzle_forward = (last_muzzle_rot * Vector3f.new(0, 0, -1)):normalized() + + last_shoot_dir = last_muzzle_forward + last_shoot_pos = last_muzzle_pos + else + last_muzzle_pos = last_shoot_pos + last_muzzle_forward = last_shoot_dir end end end @@ -783,6 +800,8 @@ local function update_hand_ik() last_right_hand_rotation = rh_rotation:clone() last_right_hand_position.w = 1.0 + last_original_right_hand_rotation = (last_right_hand_rotation * right_hand_rotation_offset:inverse()):normalized() + re8.right_hand_ik_transform:set_position(rh_pos) re8.right_hand_ik_transform:set_rotation(rh_rotation) re8.right_hand_ik:set_field("Transition", 1.0) @@ -797,11 +816,6 @@ local last_real_camera_rotation = Quaternion.new(1, 0, 0, 0) local last_real_camera_joint_rotation = Quaternion.new(1, 0, 0, 0) local last_real_camera_joint_pos = Vector3f.new(0, 0, 0) -local neg_forward_identity = Matrix4x4f.new(-1, 0, 0, 0, - 0, 1, 0, 0, - 0, 0, -1, 0, - 0, 0, 0, 1):to_quat() - local neg_identity = Matrix4x4f.new(-1, 0, 0, 0, 0, -1, 0, 0, 0, 0, -1, 0, @@ -1009,6 +1023,107 @@ elseif is_re8 then sdk.hook(sdk.find_type_definition("app.WeaponGunCore"):get_method("shoot"), on_pre_shoot, on_post_shoot) end +local throwable_was_right_grip_down = false +local throw_ray = ValueType.new(sdk.find_type_definition("via.Ray")) +local inside_throw = false +local last_throwable_update = os.clock() + +local function on_pre_throwable_late_update(args) + if not vrmod:is_hmd_active() or not vrmod:is_using_controllers() then return end + + local weapon = sdk.to_managed_object(args[2]) + if weapon ~= re8.weapon then return end + + if os.clock() - last_throwable_update > 1.0 then + throwable_was_right_grip_down = false + end + + local action_grip = vrmod:get_action_grip() + local right_joystick = vrmod:get_right_joystick() + --local left_joystick = vrmod:get_left_joystick() + local is_grip_down = vrmod:is_action_active(action_grip, right_joystick) + + if not is_grip_down and throwable_was_right_grip_down then + local vel_norm = Vector3f.new(0.0, 1.0, 0.0):normalized() + local from = Vector3f.new(last_right_hand_position.x, last_right_hand_position.y, last_right_hand_position.z) + + from = Vector4f.new(from.x, from.y, from.z, 1.0) + vel_norm = Vector4f.new(vel_norm.x, vel_norm.y, vel_norm.z, 1.0) + + -- some BS to just throw it + -- we will fix it inside on_post_bomb_activate_throwable + -- by modifying the rigid body's velocity + throw_ray:set_field("from", from) + throw_ray:set_field("dir", vel_norm) + + inside_throw = true + pcall(weapon.call, weapon, "throwWeapon", throw_ray) + inside_throw = false + end + + throwable_was_right_grip_down = is_grip_down +end + +local function on_post_throwable_late_update(retval) + return retval +end + +local bomb_args = nil + +local function on_pre_bomb_activate_throwable(args) + if not inside_throw then return end + + bomb_args = args +end + +local function on_post_bomb_activate_throwable(retval) + if not inside_throw or bomb_args == nil then + return retval + end + + local bomb = sdk.to_managed_object(bomb_args[2]) + local physics_rigid_body = bomb:get_field("k__BackingField") + + if physics_rigid_body == nil then + return retval + end + + local rigid_body = physics_rigid_body:get_field("RigidBodySet") + + if rigid_body == nil then + return retval + end + + -- Physical throwing logic + local controllers = vrmod:get_controllers() + local right_velocity = vrmod:get_velocity(controllers[2]) + local right_angular_velocity = vrmod:get_angular_velocity(controllers[2]) + + local original_camera_rotation = last_camera_matrix:to_quat() + + local hmd_transform = vrmod:get_transform(0) + local hmd_rotation = hmd_transform:to_quat() + + local rotation = (original_camera_rotation * hmd_rotation:inverse()):normalized() + right_velocity = rotation * right_velocity + + rigid_body:call("setLinearVelocity", 0, right_velocity) + rigid_body:call("setAngularVelocity", 0, rotation * right_angular_velocity) + + log.info("Thrown bomb!!!!") + + bomb_args = nil + + return retval +end + +if is_re7 then + --sdk.hook(sdk.find_type_definition("app.WeaponThrowable"):get_method("lateUpdate"), on_pre_throwable_late_update, on_post_throwable_late_update) +else + sdk.hook(sdk.find_type_definition("app.WeaponThrowableCore"):get_method("lateUpdate"), on_pre_throwable_late_update, on_post_throwable_late_update) + sdk.hook(sdk.find_type_definition("app.BombDefault"):get_method("activateThrowable"), on_pre_bomb_activate_throwable, on_post_bomb_activate_throwable) +end + local old_camera_rot = nil local old_camera_pos = nil From 57fdc6824e4f4119fb86f5e697266a3b67a67084 Mon Sep 17 00:00:00 2001 From: praydog Date: Thu, 7 Apr 2022 09:02:16 -0700 Subject: [PATCH 20/45] VR (RE7/8): Fix for the grenades --- scripts/re8_vr.lua | 2 ++ 1 file changed, 2 insertions(+) diff --git a/scripts/re8_vr.lua b/scripts/re8_vr.lua index c5ab0cf66..7f643f06e 100644 --- a/scripts/re8_vr.lua +++ b/scripts/re8_vr.lua @@ -1038,6 +1038,8 @@ local function on_pre_throwable_late_update(args) throwable_was_right_grip_down = false end + last_throwable_update = os.clock() + local action_grip = vrmod:get_action_grip() local right_joystick = vrmod:get_right_joystick() --local left_joystick = vrmod:get_left_joystick() From 559d664dbcc9c773dca35e9db89c75fb9a784d3f Mon Sep 17 00:00:00 2001 From: praydog Date: Fri, 8 Apr 2022 11:06:04 -0700 Subject: [PATCH 21/45] VR (RE8): Fix grenade count not getting decremented --- scripts/re8_vr.lua | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/scripts/re8_vr.lua b/scripts/re8_vr.lua index 7f643f06e..1b82611e1 100644 --- a/scripts/re8_vr.lua +++ b/scripts/re8_vr.lua @@ -1061,6 +1061,17 @@ local function on_pre_throwable_late_update(args) inside_throw = true pcall(weapon.call, weapon, "throwWeapon", throw_ray) inside_throw = false + + local inventory = re8.updater:get_field("References"):call("get_inventory") + + -- Decrement the grenade count + if inventory ~= nil then + local work = re8.weapon:call("get_work") + + if work ~= nil then + inventory:call("reduceItem(app.ItemCore.InstanceWork, System.Int32, System.Boolean)", work, 1, false) + end + end end throwable_was_right_grip_down = is_grip_down From 86ed798070436ad3dbe2f875a7f28b647b7b4a92 Mon Sep 17 00:00:00 2001 From: praydog Date: Sat, 9 Apr 2022 02:02:33 -0700 Subject: [PATCH 22/45] VR (RE8): Fix mine counts being decremented as grenades --- scripts/re8_vr.lua | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/scripts/re8_vr.lua b/scripts/re8_vr.lua index 1b82611e1..a154cae53 100644 --- a/scripts/re8_vr.lua +++ b/scripts/re8_vr.lua @@ -1026,6 +1026,7 @@ end local throwable_was_right_grip_down = false local throw_ray = ValueType.new(sdk.find_type_definition("via.Ray")) local inside_throw = false +local threw_bomb = false local last_throwable_update = os.clock() local function on_pre_throwable_late_update(args) @@ -1065,13 +1066,15 @@ local function on_pre_throwable_late_update(args) local inventory = re8.updater:get_field("References"):call("get_inventory") -- Decrement the grenade count - if inventory ~= nil then + if threw_bomb and inventory ~= nil then local work = re8.weapon:call("get_work") if work ~= nil then inventory:call("reduceItem(app.ItemCore.InstanceWork, System.Int32, System.Boolean)", work, 1, false) end end + + threw_bomb = false end throwable_was_right_grip_down = is_grip_down @@ -1122,10 +1125,9 @@ local function on_post_bomb_activate_throwable(retval) rigid_body:call("setLinearVelocity", 0, right_velocity) rigid_body:call("setAngularVelocity", 0, rotation * right_angular_velocity) - - log.info("Thrown bomb!!!!") - + bomb_args = nil + threw_bomb = true return retval end From 747adc8745d2e0691ddb487d6eace6efb113619f Mon Sep 17 00:00:00 2001 From: praydog Date: Sun, 10 Apr 2022 12:09:46 -0700 Subject: [PATCH 23/45] VR (RE7/8): Performance increase with async raycasts --- scripts/re8_vr.lua | 85 +++++++++++++++++++++++++++++++++++----------- 1 file changed, 66 insertions(+), 19 deletions(-) diff --git a/scripts/re8_vr.lua b/scripts/re8_vr.lua index a154cae53..b9583c71d 100644 --- a/scripts/re8_vr.lua +++ b/scripts/re8_vr.lua @@ -57,6 +57,7 @@ local motion_get_world_position = sdk.find_type_definition("via.motion.Motion"): local motion_get_world_rotation = sdk.find_type_definition("via.motion.Motion"):get_method("getWorldRotation") local cast_ray_method = sdk.find_type_definition("via.physics.System"):get_method("castRay(via.physics.CastRayQuery, via.physics.CastRayResult)") +local cast_ray_async_method = sdk.find_type_definition("via.physics.System"):get_method("castRayAsync(via.physics.CastRayQuery, via.physics.CastRayResult)") local cfg_path = "re7_vr/main_config.json" @@ -104,11 +105,14 @@ statics.generate_global("via.hid.GamePadButton") statics.generate_global("via.hid.MouseButton") local CollisionLayer = nil +local CollisionFilter = nil if is_re8 then CollisionLayer = statics.generate("app.CollisionManager.Layer") + CollisionFilter = statics.generate("app.CollisionManager.Filter") elseif is_re7 then CollisionLayer = statics.generate("app.Collision.CollisionSystem.Layer") + CollisionFilter = statics.generate("app.Collision.CollisionSystem.Filter") end if is_re7 then @@ -1125,7 +1129,7 @@ local function on_post_bomb_activate_throwable(retval) rigid_body:call("setLinearVelocity", 0, right_velocity) rigid_body:call("setAngularVelocity", 0, rotation * right_angular_velocity) - + bomb_args = nil threw_bomb = true @@ -1207,7 +1211,14 @@ elseif is_re8 then ) end -local function cast_ray(start_pos, end_pos) +local crosshair_bullet_ray_result = nil +local crosshair_attack_ray_result = nil + +local function cast_ray(start_pos, end_pos, layer) + if layer == nil then + layer = CollisionLayer.Bullet + end + local via_physics_system = sdk.get_native_singleton("via.physics.System") local ray_query = sdk.create_instance("via.physics.CastRayQuery") local ray_result = sdk.create_instance("via.physics.CastRayResult") @@ -1218,25 +1229,40 @@ local function cast_ray(start_pos, end_pos) ray_query:call("enableNearSort") --ray_query:call("enableFrontFacingTriangleHits") --ray_query:call("disableBackFacingTriangleHits") - local filter_info = ray_query:call("get_FilterInfo") + local filter_info = ray_query:call("get_FilterInfo") filter_info:call("set_Group", 0) filter_info:call("set_MaskBits", 0xFFFFFFFF & ~1) -- everything except the player. - - local target_layers = { - CollisionLayer.Attack, - CollisionLayer.Bullet - } - for i=1, 2 do - filter_info:call("set_Layer", target_layers[i]) - ray_query:call("set_FilterInfo", filter_info) - cast_ray_method:call(via_physics_system, ray_query, ray_result) + filter_info:call("set_Layer", layer) + ray_query:call("set_FilterInfo", filter_info) + cast_ray_method:call(via_physics_system, ray_query, ray_result) - if ray_result:call("get_NumContactPoints") > 0 then - break - end + return ray_result +end + +local function cast_ray_async(ray_result, start_pos, end_pos, layer) + if layer == nil then + layer = CollisionLayer.Bullet end + local via_physics_system = sdk.get_native_singleton("via.physics.System") + local ray_query = sdk.create_instance("via.physics.CastRayQuery") + local ray_result = ray_result or sdk.create_instance("via.physics.CastRayResult") + + ray_query:call("setRay(via.vec3, via.vec3)", start_pos, end_pos) + ray_query:call("clearOptions") + ray_query:call("enableAllHits") + ray_query:call("enableNearSort") + --ray_query:call("enableFrontFacingTriangleHits") + --ray_query:call("disableBackFacingTriangleHits") + local filter_info = ray_query:call("get_FilterInfo") + filter_info:call("set_Group", 0) + filter_info:call("set_MaskBits", 0xFFFFFFFF & ~1) -- everything except the player. + + filter_info:call("set_Layer", layer) + ray_query:call("set_FilterInfo", filter_info) + cast_ray_async_method:call(via_physics_system, ray_query, ray_result) + return ray_result end @@ -1249,19 +1275,34 @@ local function update_crosshair_world_pos(start_pos, end_pos) end end - local ray_result = cast_ray(start_pos, end_pos) + -- asynchronous raycast + if crosshair_attack_ray_result == nil or crosshair_bullet_ray_result == nil then + crosshair_attack_ray_result = cast_ray_async(crosshair_ray_result, start_pos, end_pos, CollisionLayer.Attack) + crosshair_bullet_ray_result = cast_ray_async(crosshair_ray_result, start_pos, end_pos, CollisionLayer.Bullet) + crosshair_attack_ray_result:add_ref() + crosshair_bullet_ray_result:add_ref() + end + + local finished = crosshair_attack_ray_result:call("get_Finished") == true and crosshair_bullet_ray_result:call("get_Finished") + local attack_hit = finished and crosshair_attack_ray_result:call("get_NumContactPoints") > 0 + local any_hit = finished and (attack_hit or crosshair_bullet_ray_result:call("get_NumContactPoints") > 0) - if ray_result:call("get_NumContactPoints") > 0 then - local contact_point = ray_result:call("getContactPoint(System.UInt32)", 0) + if finished and any_hit then + local best_result = attack_hit and crosshair_attack_ray_result or crosshair_bullet_ray_result + local contact_point = best_result:call("getContactPoint(System.UInt32)", 0) if contact_point then re8.crosshair_dir = (end_pos - start_pos):normalized() - re8.crosshair_pos = contact_point:get_field("Position") re8.crosshair_normal = contact_point:get_field("Normal") re8.crosshair_distance = contact_point:get_field("Distance") + + --re8.crosshair_pos = contact_point:get_field("Position") -- We don't use the position because the cast was asynchronous + -- instead we get the distance to the impact and add it to the current position + re8.crosshair_pos = start_pos + (re8.crosshair_dir * re8.crosshair_distance) end else re8.crosshair_dir = (end_pos - start_pos):normalized() + if re8.crosshair_distance then re8.crosshair_pos = start_pos + (re8.crosshair_dir * re8.crosshair_distance) else @@ -1269,6 +1310,12 @@ local function update_crosshair_world_pos(start_pos, end_pos) re8.crosshair_distance = 10.0 end end + + if finished then + -- restart it. + cast_ray_async(crosshair_attack_ray_result, start_pos, end_pos, CollisionLayer.Attack) + cast_ray_async(crosshair_bullet_ray_result, start_pos, end_pos, CollisionLayer.Bullet) + end end local last_camera_update_args = nil From a652801608ac804a2d41f42a5628f0c1aee756bc Mon Sep 17 00:00:00 2001 From: praydog Date: Sat, 30 Apr 2022 03:05:28 -0700 Subject: [PATCH 24/45] VR (RE7/8): Update controller offsets for OpenXR --- scripts/re8_vr.lua | 90 +++++++++++++++++++++++++++++++++++++++-- scripts/utility/RE8.lua | 16 +++++++- 2 files changed, 101 insertions(+), 5 deletions(-) diff --git a/scripts/re8_vr.lua b/scripts/re8_vr.lua index b9583c71d..055bd6d5f 100644 --- a/scripts/re8_vr.lua +++ b/scripts/re8_vr.lua @@ -3,7 +3,6 @@ local is_re7 = game_name == "re7" local is_re8 = game_name == "re8" if not is_re7 and not is_re8 then - re.msg("Error: Game is not RE7 or RE8.") return end @@ -16,19 +15,41 @@ local renderer_type = sdk.find_type_definition("via.render.Renderer") local GamePadButton = statics.generate("via.hid.GamePadButton") +local openxr = { + left_hand_rotation_vec = Vector3f.new(0.186417 + 0.2, 2.820591, 1.221779), -- pitch yaw roll? + right_hand_rotation_vec = Vector3f.new(0.186417, -2.820591, -1.221779), -- pitch yaw roll? + left_hand_position_offset = Vector4f.new(-0.036934, 0.069525, 0.017501, 0.0), + right_hand_position_offset = Vector4f.new(0.036934, 0.069525, 0.017501, 0.0) +} + +local is_openxr = vrmod:is_openxr_loaded() + local last_original_right_hand_rotation = Quaternion.new(0.0, 0.0, 0.0, 0.0) local last_camera_matrix = Matrix4x4f.new() local last_right_hand_rotation = Quaternion.new(0.0, 0.0, 0.0, 0.0) local last_right_hand_position = Vector3f.new(0.0, 0.0, 0.0) local last_left_hand_rotation = Quaternion.new(0.0, 0.0, 0.0, 0.0) local last_left_hand_position = Vector3f.new(0.0, 0.0, 0.0) + local left_hand_rotation_vec = Vector3f.new(-0.105 + 0.2, 2.37, 1.10) -- pitch yaw roll? local right_hand_rotation_vec = Vector3f.new(-0.105, -2.37, -1.10) -- pitch yaw roll? + +if is_openxr then + left_hand_rotation_vec = openxr.left_hand_rotation_vec:clone() + right_hand_rotation_vec = openxr.right_hand_rotation_vec:clone() +end + local left_hand_rotation_offset = Quaternion.new(left_hand_rotation_vec):normalized() local right_hand_rotation_offset = Quaternion.new(right_hand_rotation_vec):normalized() + local left_hand_position_offset = Vector4f.new(-0.025, 0.045, 0.155, 0.0) local right_hand_position_offset = Vector4f.new(0.025, 0.045, 0.155, 0.0) +if is_openxr then + left_hand_position_offset = openxr.left_hand_position_offset:clone() + right_hand_position_offset = openxr.right_hand_position_offset:clone() +end + local ray_typedef = sdk.find_type_definition("via.Ray") local last_muzzle_pos = Vector4f.new(0.0, 0.0, 0.0, 1.0) local last_muzzle_rot = Quaternion.new(0.0, 0.0, 0.0, 0.0) @@ -575,8 +596,8 @@ local function set_hand_joints_to_tpose(hand_ik) local current_positions = {} local player_transform = re8.transform - local player_pos = transform_get_position:call(player_transform) - local player_rot = transform_get_rotation:call(player_transform) + local player_pos = player_transform:get_position() + local player_rot = player_transform:get_rotation() local joints = {} @@ -2156,7 +2177,7 @@ local function re8_on_pre_order_vibration(args) local left_power = task:get_field("MotorPower_0") local right_power = task:get_field("MotorPower_1") - local duration = task:get_field("TimeSeconds") + local duration = task:get_field("TimeSecond") if left_power > 0 then local left_joystick = vrmod:get_left_joystick() @@ -2248,6 +2269,8 @@ re.on_frame(function() end end) +local debug_adjust_hand_offset = false + re.on_draw_ui(function() local changed = false @@ -2271,6 +2294,59 @@ re.on_draw_ui(function() changed, right_hand_position_offset = imgui.drag_float4("Right Hand Position Offset", right_hand_position_offset, 0.005, -5.0, 5.0) if imgui.tree_node("Debug") then + changed, debug_adjust_hand_offset = imgui.checkbox("Adjust Hand Offset", debug_adjust_hand_offset) + + if debug_adjust_hand_offset then + local left_axis = vrmod:get_left_stick_axis() + local right_axis = vrmod:get_right_stick_axis() + local right_joystick = vrmod:get_right_joystick() + local left_joystick = vrmod:get_left_joystick() + local action_grip = vrmod:get_action_grip() + local action_trigger = vrmod:get_action_trigger() + + local is_right_grip_active = vrmod:is_action_active(action_grip, right_joystick) + local is_left_grip_active = vrmod:is_action_active(action_grip, left_joystick) + local is_right_trigger_active = vrmod:is_action_active(action_trigger, right_joystick) + local is_left_trigger_active = vrmod:is_action_active(action_trigger, left_joystick) + + -- adjust the rotation offset based on how the user is moving the controller + if not is_right_trigger_active then + if not is_right_grip_active then + right_hand_rotation_vec.x = right_hand_rotation_vec.x + (right_axis.y * 0.001) + right_hand_rotation_vec.y = right_hand_rotation_vec.y + (right_axis.x * 0.001) + else + right_hand_rotation_vec.z = right_hand_rotation_vec.z + ((right_axis.y + right_axis.x) * 0.001) + end + else + if not is_right_grip_active then + right_hand_position_offset.x = right_hand_position_offset.x + (right_axis.y * 0.001) + right_hand_position_offset.y = right_hand_position_offset.y + (right_axis.x * 0.001) + else + right_hand_position_offset.z = right_hand_position_offset.z + ((right_axis.y + right_axis.x) * 0.001) + end + end + + right_hand_rotation_offset = Quaternion.new(right_hand_rotation_vec):normalized() + + if not is_left_trigger_active then + if not is_left_grip_active then + left_hand_rotation_vec.x = left_hand_rotation_vec.x + (left_axis.y * 0.001) + left_hand_rotation_vec.y = left_hand_rotation_vec.y + (left_axis.x * 0.001) + else + left_hand_rotation_vec.z = left_hand_rotation_vec.z + ((left_axis.y + left_axis.x) * 0.001) + end + else + if not is_left_grip_active then + left_hand_position_offset.x = left_hand_position_offset.x + (left_axis.y * 0.001) + left_hand_position_offset.y = left_hand_position_offset.y + (left_axis.x * 0.001) + else + left_hand_position_offset.z = left_hand_position_offset.z + ((left_axis.y + left_axis.x) * 0.001) + end + end + + left_hand_rotation_offset = Quaternion.new(left_hand_rotation_vec):normalized() + end + imgui.text("Last GUI Dot: " .. tostring(last_gui_dot)) if imgui.button("Cast ray") then @@ -2295,6 +2371,12 @@ re.on_draw_ui(function() imgui.tree_pop() end + if imgui.tree_node("Inventory") then + object_explorer:handle_address(re8.inventory) + + imgui.tree_pop() + end + if imgui.tree_node("Right Hand IK") then local right_hand_ik = re8.right_hand_ik diff --git a/scripts/utility/RE8.lua b/scripts/utility/RE8.lua index 8fb6221bf..8638673b5 100644 --- a/scripts/utility/RE8.lua +++ b/scripts/utility/RE8.lua @@ -190,10 +190,24 @@ re.on_pre_application_entry("UpdateBehavior", function() end re8.transform = player:call("get_Transform") - re8.inventory = get_component(player, "app.Inventory") re8.hand_touch = get_component(player, "app.PlayerHandTouch") re8.order = get_component(player, "app.PlayerOrder") re8.updater = get_component(player, "app.PlayerUpdater") + + if is_re7 then + re8.inventory = get_component(player, "app.Inventory") + elseif re8.updater ~= nil then + local container = re8.updater:get_field("playerContainer") + + if container then + re8.inventory = container:call("get_inventory") + else + re8.inventory = nil + end + else + re8.inventory = nil + end + re8.delta_time = sdk.call_native_func(re8.application, re8.application_type, "get_DeltaTime") if is_re7 then From c8ec5883926ae87d104a04a31e199616dc0451b5 Mon Sep 17 00:00:00 2001 From: praydog Date: Sat, 30 Apr 2022 13:26:02 -0700 Subject: [PATCH 25/45] VR (RE8): Initial implementation of physical melee attacks --- scripts/re8_vr.lua | 187 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 187 insertions(+) diff --git a/scripts/re8_vr.lua b/scripts/re8_vr.lua index 055bd6d5f..40351dc0b 100644 --- a/scripts/re8_vr.lua +++ b/scripts/re8_vr.lua @@ -1933,10 +1933,184 @@ end) update_hand_ik() end)]] +local last_melee = os.clock() +local known_colliders = {} + +local ContinuousCapsuleShape = sdk.find_type_definition("via.physics.ContinuousCapsuleShape") +local CapsuleShape = sdk.find_type_definition("via.physics.CapsuleShape") + +local shape_set_capsule = CapsuleShape:get_method("set_Capsule") +local shape_get_capsule = CapsuleShape:get_method("get_Capsule") +local continuous_shape_set_capsule = ContinuousCapsuleShape:get_method("set_Capsule") +local continuous_shape_get_capsule = ContinuousCapsuleShape:get_method("get_Capsule") +local continuous_shape_get_previous_capsule = ContinuousCapsuleShape:get_method("get_PreviousCapsule") + +local function hijack_capsules(weapon_pos, weapon_rotation, collidable) + if collidable == nil then return end + + local transformed_shape = collidable:call("get_TransformedShape") + + if transformed_shape ~= nil and transformed_shape:get_type_definition() == ContinuousCapsuleShape then + local untransformed_shape = collidable:call("get_Shape") + local untransformed_capsule = continuous_shape_get_capsule(untransformed_shape) + + local transformed_capsule = continuous_shape_get_capsule(transformed_shape) + + if untransformed_capsule ~= nil and transformed_capsule ~= nil then + local utp0 = untransformed_capsule:get_field("p0") + local utp1 = untransformed_capsule:get_field("p1") + + local p0 = transformed_capsule:get_field("p0") + local p1 = transformed_capsule:get_field("p1") + local r = transformed_capsule:get_field("r") + + local delta = utp1 - utp0 + local dir = delta:normalized() + + --original_capsules[collidable] = { p0, p1, r } + + local new_p0 = weapon_pos:clone() + local new_p1 = override_capsule_end + + --if new_p1 == nil then + new_p1 = weapon_pos + (weapon_rotation * Vector3f.new(0, 0, delta:length())) + --end + + log.info(string.format("%x", transformed_shape:get_address())) + log.info(tostring(p0.x) .. " " .. tostring(p0.y) .. " " .. tostring(p0.z)) + log.info(" " .. tostring(weapon_pos.x) .. " " .. tostring(weapon_pos.y) .. " " .. tostring(weapon_pos.z)) + + --new_p0 = Vector4f.new(new_p0.x, new_p0.y, new_p0.z, 1) + --new_p1 = Vector4f.new(new_p1.x, new_p1.y, new_p1.z, 1) + + transformed_capsule:set_field("p0", new_p0) + transformed_capsule:set_field("p1", new_p1) + transformed_capsule:set_field("r", 0.01) + + --table.insert(capsule_origins, { new_p0, new_p1 }) + + --untransformed_capsule:set_field("p1", (last_weapon_rotation * Vector3f.new(0, 0, 1.0))) + + --transformed_shape:call("set_Capsule", transformed_capsule) + --untransformed_shape:call("set_Capsule", untransformed_capsule) + + local sz = ContinuousCapsuleShape:get_valuetype_size() + + for i=0, sz/4 do + --transformed_shape:write_float(0x60 + (i * 4), transformed_capsule:read_float(i * 4)) + transformed_shape:write_float(0x90 + (i * 4), transformed_capsule:read_float(i * 4)) + end + --transformed_shape:write_float(0xC8, 0.0) + --continuous_shape_set_capsule(transformed_shape, transformed_capsule) + + collidable:call("set_UpdateShape", true) + end + end +end + +local function melee_attack() + if not vrmod:is_hmd_active() or not vrmod:is_using_controllers() then return end + + local right_controller = vrmod:get_controllers()[2] + local right_controller_velocity = vrmod:get_velocity(right_controller) + local right_controller_speed = right_controller_velocity:length() + + if right_controller_speed < 2.5 then return end + + local now = os.clock() + + if now - last_melee < 0.1 then + return + end + + last_melee = now + + if not re8.weapon then + return + end + + local hit_controller = re8.weapon:call("get_hitController") + + if not hit_controller then + return + end + + local rcol = hit_controller:get_field("RequestSetCollider") + + if not rcol then + return + end + + local collider_handler = hit_controller:get_field("RequestedColliderHandler") + local registered_collider_handler = hit_controller:get_field("RegisteredColliderHandler") + + if not collider_handler or not registered_collider_handler then + return + end + + local resource_id = hit_controller:get_field("RequestSetResourceIndex") + local num_request_sets = rcol:call("getNumRequestSets(System.UInt32)", resource_id) + local owner = hit_controller:call("get_AttackOwner") + local weapon_gameobject = hit_controller:call("get_GameObject") + local weapon_transform = weapon_gameobject:call("get_Transform") + local weapon_position = weapon_transform:get_position() + local weapon_rotation = weapon_transform:get_rotation() + + rcol:call("updatePose") + + for i=0, num_request_sets - 1 do + local num_collidables = rcol:call("getNumCollidables(System.UInt32, System.UInt32)", resource_id, i) + local userdata = rcol:call("getRequestSetUserData(System.UInt32, System.UInt32)", resource_id, i) + + if userdata:get_type_definition():is_a("app.ContactUserData") then + for j=0, num_collidables - 1 do + local collidable = rcol:call("getCollidable(System.UInt32, System.UInt32, System.UInt32)", resource_id, i, j) + known_colliders[collidable] = true + + collidable:call("set_Enabled", true) + collidable:call("enable") + collidable:call("set_UpdateShape", true) + + --hit_controller:call("clearUserData") + --hit_controller:call("clearBuffer", userdata) + + collider_handler:call("Invoke", userdata, collidable, j, owner) + + hit_controller:call("setManualRequest", i) + + --hit_controller:call("testAttack", userdata, collidable, j, owner) + + --hit_controller:call("calcDisplacement", userdata, collidable, j, owner) + --hit_controller:call("hitEnvironment", userdata, collidable, j, owner) + + --local userdata = collidable:call("get_UserData") + + --log.info(userdata:get_type_definition():get_full_name()) + --log.info(string.format("%i %i %i 0x%x", resource_id, i, j, collidable:get_address())) + end + end + end + + --hit_controller:get_field("ProcAttack"):call("update") + + + --log.info(tostring(num_collidables)) + + --hit_controller:call("updateRequestedCollider") +end + +--sdk.hook(sdk.find_type_definition("app.ProcCollider"):get_method("update"), function(args) melee_attack() end, nil) + re.on_application_entry("LateUpdateBehavior", function() update_hand_ik() end) +re.on_application_entry("UpdateBehavior", function() + melee_attack() +end) + +local do_once = true + re.on_application_entry("UpdateHID", function() --[[local padman = sdk.get_managed_singleton(sdk.game_namespace("PadManager")) @@ -2400,6 +2574,19 @@ re.on_draw_ui(function() imgui.tree_pop() end + + if imgui.tree_node("Weapon Colliders") then + local i = 0 + for collider, _ in pairs(known_colliders) do + if imgui.tree_node(tostring(i)) then + object_explorer:handle_address(collider) + imgui.tree_pop() + end + i = i + 1 + end + + imgui.tree_pop() + end if imgui.button("test dump") then local d = function(name) From 3baad4767386e43d4ce4f6a718dbb2ca6149beb8 Mon Sep 17 00:00:00 2001 From: praydog Date: Sun, 1 May 2022 14:40:21 -0700 Subject: [PATCH 26/45] VR (RE7/8): Disable melee code in RE7 until proper support is added --- scripts/re8_vr.lua | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/scripts/re8_vr.lua b/scripts/re8_vr.lua index 40351dc0b..ec4125323 100644 --- a/scripts/re8_vr.lua +++ b/scripts/re8_vr.lua @@ -279,6 +279,8 @@ local function update_pad_device(device) end end + --cur_button = cur_button | via.hid.GamePadButton.CRight + local action_trigger = vrmod:get_action_trigger() local action_grip = vrmod:get_action_grip() local action_a_button = vrmod:get_action_a_button() @@ -2009,6 +2011,7 @@ local function hijack_capsules(weapon_pos, weapon_rotation, collidable) end local function melee_attack() + if not is_re8 then return end --TODO: RE7 if not vrmod:is_hmd_active() or not vrmod:is_using_controllers() then return end local right_controller = vrmod:get_controllers()[2] @@ -2092,11 +2095,6 @@ local function melee_attack() end --hit_controller:get_field("ProcAttack"):call("update") - - - --log.info(tostring(num_collidables)) - - --hit_controller:call("updateRequestedCollider") end --sdk.hook(sdk.find_type_definition("app.ProcCollider"):get_method("update"), function(args) melee_attack() end, nil) From d09260a4da179e9e4e5744c9fdd49d995aa912da Mon Sep 17 00:00:00 2001 From: praydog Date: Mon, 2 May 2022 01:38:39 -0700 Subject: [PATCH 27/45] VR (RE7): Fix haptics not working correctly sometimes --- scripts/re8_vr.lua | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/scripts/re8_vr.lua b/scripts/re8_vr.lua index ec4125323..b7a48f7b0 100644 --- a/scripts/re8_vr.lua +++ b/scripts/re8_vr.lua @@ -2411,6 +2411,10 @@ local function re7_on_pre_request_add_vibration(args) local param = sdk.to_managed_object(args[3]) local duration = sdk.to_float(args[4]) + if duration == 0 then + duration = 0.1 + end + local power = param:get_field("HighMotorPower") local left_joystick = vrmod:get_left_joystick() From f02078d0e6550b4fc4efd76a958dbc644a572e1e Mon Sep 17 00:00:00 2001 From: praydog Date: Mon, 2 May 2022 10:06:22 -0700 Subject: [PATCH 28/45] VR (RE7/8): RE7 melee support, more consistent melee attacks, haptics --- scripts/re8_vr.lua | 217 ++++++++++++++++++---------------------- scripts/utility/RE8.lua | 12 +-- 2 files changed, 98 insertions(+), 131 deletions(-) diff --git a/scripts/re8_vr.lua b/scripts/re8_vr.lua index b7a48f7b0..e56b20a47 100644 --- a/scripts/re8_vr.lua +++ b/scripts/re8_vr.lua @@ -1936,105 +1936,46 @@ end) end)]] local last_melee = os.clock() -local known_colliders = {} +local last_melee_request_state = false -local ContinuousCapsuleShape = sdk.find_type_definition("via.physics.ContinuousCapsuleShape") -local CapsuleShape = sdk.find_type_definition("via.physics.CapsuleShape") - -local shape_set_capsule = CapsuleShape:get_method("set_Capsule") -local shape_get_capsule = CapsuleShape:get_method("get_Capsule") -local continuous_shape_set_capsule = ContinuousCapsuleShape:get_method("set_Capsule") -local continuous_shape_get_capsule = ContinuousCapsuleShape:get_method("get_Capsule") -local continuous_shape_get_previous_capsule = ContinuousCapsuleShape:get_method("get_PreviousCapsule") - -local function hijack_capsules(weapon_pos, weapon_rotation, collidable) - if collidable == nil then return end - - local transformed_shape = collidable:call("get_TransformedShape") - - if transformed_shape ~= nil and transformed_shape:get_type_definition() == ContinuousCapsuleShape then - local untransformed_shape = collidable:call("get_Shape") - local untransformed_capsule = continuous_shape_get_capsule(untransformed_shape) - - local transformed_capsule = continuous_shape_get_capsule(transformed_shape) - - if untransformed_capsule ~= nil and transformed_capsule ~= nil then - local utp0 = untransformed_capsule:get_field("p0") - local utp1 = untransformed_capsule:get_field("p1") - - local p0 = transformed_capsule:get_field("p0") - local p1 = transformed_capsule:get_field("p1") - local r = transformed_capsule:get_field("r") - - local delta = utp1 - utp0 - local dir = delta:normalized() - - --original_capsules[collidable] = { p0, p1, r } - - local new_p0 = weapon_pos:clone() - local new_p1 = override_capsule_end - - --if new_p1 == nil then - new_p1 = weapon_pos + (weapon_rotation * Vector3f.new(0, 0, delta:length())) - --end - - log.info(string.format("%x", transformed_shape:get_address())) - log.info(tostring(p0.x) .. " " .. tostring(p0.y) .. " " .. tostring(p0.z)) - log.info(" " .. tostring(weapon_pos.x) .. " " .. tostring(weapon_pos.y) .. " " .. tostring(weapon_pos.z)) - - --new_p0 = Vector4f.new(new_p0.x, new_p0.y, new_p0.z, 1) - --new_p1 = Vector4f.new(new_p1.x, new_p1.y, new_p1.z, 1) - - transformed_capsule:set_field("p0", new_p0) - transformed_capsule:set_field("p1", new_p1) - transformed_capsule:set_field("r", 0.01) - - --table.insert(capsule_origins, { new_p0, new_p1 }) - - --untransformed_capsule:set_field("p1", (last_weapon_rotation * Vector3f.new(0, 0, 1.0))) - - --transformed_shape:call("set_Capsule", transformed_capsule) - --untransformed_shape:call("set_Capsule", untransformed_capsule) +local function melee_attack(hit_controller) + if not vrmod:is_hmd_active() or not vrmod:is_using_controllers() then return end + if re8.is_in_cutscene or not re8.can_use_hands then return end - local sz = ContinuousCapsuleShape:get_valuetype_size() + if not re8.weapon then + return + end - for i=0, sz/4 do - --transformed_shape:write_float(0x60 + (i * 4), transformed_capsule:read_float(i * 4)) - transformed_shape:write_float(0x90 + (i * 4), transformed_capsule:read_float(i * 4)) - end - --transformed_shape:write_float(0xC8, 0.0) - --continuous_shape_set_capsule(transformed_shape, transformed_capsule) + local real_hit_controller = re8.weapon:call("get_hitController") - collidable:call("set_UpdateShape", true) - end + if not real_hit_controller then + return + end + + -- RE7 + if hit_controller ~= nil and hit_controller ~= real_hit_controller then + return end -end - -local function melee_attack() - if not is_re8 then return end --TODO: RE7 - if not vrmod:is_hmd_active() or not vrmod:is_using_controllers() then return end local right_controller = vrmod:get_controllers()[2] local right_controller_velocity = vrmod:get_velocity(right_controller) + local right_controller_angular_velocity = vrmod:get_angular_velocity(right_controller) local right_controller_speed = right_controller_velocity:length() + local right_controller_angular_speed = right_controller_angular_velocity:length() - if right_controller_speed < 2.5 then return end - - local now = os.clock() - - if now - last_melee < 0.1 then - return + if right_controller_speed < 2.2 and right_controller_angular_speed < 20 then + last_melee_request_state = false + return end - last_melee = now - - if not re8.weapon then - return - end + local action_grip = vrmod:get_action_grip() + local right_joystick = vrmod:get_right_joystick() + local is_stab = vrmod:is_action_active(action_grip, right_joystick) - local hit_controller = re8.weapon:call("get_hitController") + local cooldown_time = is_stab and 1.0 or 0.5 + local now = os.clock() - if not hit_controller then + if not last_melee_request_state and now - last_melee < cooldown_time then return end @@ -2044,67 +1985,99 @@ local function melee_attack() return end - local collider_handler = hit_controller:get_field("RequestedColliderHandler") - local registered_collider_handler = hit_controller:get_field("RegisteredColliderHandler") + local collider_handler = is_re8 and hit_controller:get_field("RequestedColliderHandler") + local registered_collider_handler = is_re8 and hit_controller:get_field("RegisteredColliderHandler") - if not collider_handler or not registered_collider_handler then - return + if is_re8 then + if not collider_handler or not registered_collider_handler then + return + end end - local resource_id = hit_controller:get_field("RequestSetResourceIndex") - local num_request_sets = rcol:call("getNumRequestSets(System.UInt32)", resource_id) - local owner = hit_controller:call("get_AttackOwner") - local weapon_gameobject = hit_controller:call("get_GameObject") - local weapon_transform = weapon_gameobject:call("get_Transform") - local weapon_position = weapon_transform:get_position() - local weapon_rotation = weapon_transform:get_rotation() + local resource_id = is_re8 and hit_controller:get_field("RequestSetResourceIndex") + local num_request_sets = is_re8 and rcol:call("getNumRequestSets(System.UInt32)", resource_id) or rcol:call("get_NumRequestSets") rcol:call("updatePose") + last_melee_request_state = true + last_melee = now + for i=0, num_request_sets - 1 do - local num_collidables = rcol:call("getNumCollidables(System.UInt32, System.UInt32)", resource_id, i) - local userdata = rcol:call("getRequestSetUserData(System.UInt32, System.UInt32)", resource_id, i) - - if userdata:get_type_definition():is_a("app.ContactUserData") then - for j=0, num_collidables - 1 do - local collidable = rcol:call("getCollidable(System.UInt32, System.UInt32, System.UInt32)", resource_id, i, j) - known_colliders[collidable] = true + if is_re7 then + local num_collidables = rcol:call("getNumCollidablesFromIndex", i) + local userdata = rcol:call("getRequestSetUserDataFromIndex", i) - collidable:call("set_Enabled", true) - collidable:call("enable") - collidable:call("set_UpdateShape", true) + if userdata ~= nil and userdata:get_type_definition():is_a("app.Collision.ContactBaseUserData") then + for j=0, num_collidables - 1 do + local collidable = rcol:call("getCollidableFromIndex", i, j) - --hit_controller:call("clearUserData") - --hit_controller:call("clearBuffer", userdata) + collidable:call("set_Enabled", true) + collidable:call("enable") + --collidable:call("set_UpdateShape", true) + end + end - collider_handler:call("Invoke", userdata, collidable, j, owner) + if not is_stab then + hit_controller:call("addManualRequest", 0) + elseif i > 0 then + hit_controller:call("addManualRequest", i) + end + else + local num_collidables = rcol:call("getNumCollidables(System.UInt32, System.UInt32)", resource_id, i) + local userdata = rcol:call("getRequestSetUserData(System.UInt32, System.UInt32)", resource_id, i) + + if userdata:get_type_definition():is_a("app.ContactUserData") then + for j=0, num_collidables - 1 do + local collidable = rcol:call("getCollidable(System.UInt32, System.UInt32, System.UInt32)", resource_id, i, j) + --known_colliders[collidable] = true + + collidable:call("set_Enabled", true) + collidable:call("enable") + collidable:call("set_UpdateShape", true) + + if not is_stab then + hit_controller:call("setManualRequest", 0) + elseif i > 0 then + hit_controller:call("setManualRequest", i) + end + end + end + end + end - hit_controller:call("setManualRequest", i) + if is_stab then + vrmod:trigger_haptic_vibration(0.0, 0.1, 1, 5, vrmod:get_right_joystick()) + else + vrmod:trigger_haptic_vibration(0.0, 0.1, 1, 0.5, vrmod:get_right_joystick()) + end +end - --hit_controller:call("testAttack", userdata, collidable, j, owner) +local hit_controller_args = nil - --hit_controller:call("calcDisplacement", userdata, collidable, j, owner) - --hit_controller:call("hitEnvironment", userdata, collidable, j, owner) +local function on_pre_hit_controller_update(args) + hit_controller_args = args +end - --local userdata = collidable:call("get_UserData") +local function on_post_hit_controller_update(args) + if not vrmod:is_hmd_active() or not vrmod:is_using_controllers() then return end + if re8.is_in_cutscene or not re8.can_use_hands then return end - --log.info(userdata:get_type_definition():get_full_name()) - --log.info(string.format("%i %i %i 0x%x", resource_id, i, j, collidable:get_address())) - end - end - end + local hit_controller = sdk.to_managed_object(hit_controller_args[2]) - --hit_controller:get_field("ProcAttack"):call("update") + melee_attack(hit_controller) end ---sdk.hook(sdk.find_type_definition("app.ProcCollider"):get_method("update"), function(args) melee_attack() end, nil) +if is_re7 then + sdk.hook(sdk.find_type_definition("app.Collision.HitController"):get_method("update"), on_pre_hit_controller_update, on_post_hit_controller_update) +else + sdk.hook(sdk.find_type_definition("app.HitController"):get_method("update"), on_pre_hit_controller_update, on_post_hit_controller_update) +end re.on_application_entry("LateUpdateBehavior", function() update_hand_ik() end) re.on_application_entry("UpdateBehavior", function() - melee_attack() end) local do_once = true diff --git a/scripts/utility/RE8.lua b/scripts/utility/RE8.lua index 8638673b5..603f7a5ad 100644 --- a/scripts/utility/RE8.lua +++ b/scripts/utility/RE8.lua @@ -139,19 +139,13 @@ end function re8.get_weapon_object(player) if is_re7 then - local player_gun = get_component(re8.player, "app.PlayerGun") + local equip_manager = get_component(player, "app.EquipManager") - if not player_gun then + if not equip_manager then return nil end - local equipped_weapon = player_gun:get_field("WeaponGun") - - if not equipped_weapon then - return nil - end - - return equipped_weapon + return equip_manager:call("get_equipWeaponRight") elseif is_re8 then if not re8.updater then return nil From 22d098cdb0884fd8fbdb1d93f65f2a1b1c25e379 Mon Sep 17 00:00:00 2001 From: praydog Date: Mon, 2 May 2022 10:50:12 -0700 Subject: [PATCH 29/45] VR (RE7/8): Better cooldown timing for melee attacks --- scripts/re8_vr.lua | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/scripts/re8_vr.lua b/scripts/re8_vr.lua index e56b20a47..b79cb2c61 100644 --- a/scripts/re8_vr.lua +++ b/scripts/re8_vr.lua @@ -1999,8 +1999,11 @@ local function melee_attack(hit_controller) rcol:call("updatePose") + if not last_melee_request_state then + last_melee = now + end + last_melee_request_state = true - last_melee = now for i=0, num_request_sets - 1 do if is_re7 then From c7d353d214713549ceb69f3f7df60c6318d17370 Mon Sep 17 00:00:00 2001 From: praydog Date: Mon, 2 May 2022 11:14:22 -0700 Subject: [PATCH 30/45] VR (RE7/8): Add No Melee Cooldown cheat --- scripts/re8_vr.lua | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/scripts/re8_vr.lua b/scripts/re8_vr.lua index b79cb2c61..a67556827 100644 --- a/scripts/re8_vr.lua +++ b/scripts/re8_vr.lua @@ -104,7 +104,8 @@ local neg_forward_identity = Matrix4x4f.new(-1, 0, 0, 0, local cfg = { movement_shake = false, all_camera_shake = true, - disable_crosshair = false + disable_crosshair = false, + no_melee_cooldown = false, } local function load_cfg() @@ -1975,8 +1976,10 @@ local function melee_attack(hit_controller) local cooldown_time = is_stab and 1.0 or 0.5 local now = os.clock() - if not last_melee_request_state and now - last_melee < cooldown_time then - return + if not cfg.no_melee_cooldown then + if not last_melee_request_state and now - last_melee < cooldown_time then + return + end end local rcol = hit_controller:get_field("RequestSetCollider") @@ -2430,6 +2433,12 @@ re.on_draw_ui(function() changed, cfg.all_camera_shake = imgui.checkbox("All Other Camera Shakes", cfg.all_camera_shake) changed, cfg.disable_crosshair = imgui.checkbox("Disable Crosshair", cfg.disable_crosshair) + if imgui.tree_node("Cheats") then + changed, cfg.no_melee_cooldown = imgui.checkbox("No Melee Cooldown", cfg.no_melee_cooldown) + + imgui.tree_pop() + end + changed, left_hand_rotation_vec = imgui.drag_float3("Left Hand Rotation Offset", left_hand_rotation_vec, 0.005, -5.0, 5.0) if changed then From 527a0fef5bae3ce17cb4d48895e5c01fdac38e16 Mon Sep 17 00:00:00 2001 From: praydog Date: Tue, 3 May 2022 07:05:03 -0700 Subject: [PATCH 31/45] VR (RE7): Add punching support in End of Zoe --- scripts/re8_vr.lua | 275 +++++++++++++++++++++++++++++++--------- scripts/utility/RE8.lua | 13 +- 2 files changed, 226 insertions(+), 62 deletions(-) diff --git a/scripts/re8_vr.lua b/scripts/re8_vr.lua index a67556827..22ed64e0f 100644 --- a/scripts/re8_vr.lua +++ b/scripts/re8_vr.lua @@ -229,7 +229,7 @@ local function update_pad_device(device) local menu_manager = sdk.get_managed_singleton("app.MenuManager") if menu_manager ~= nil then - is_inventory_open = menu_manager:call("isOpenInventoryMenu") + is_inventory_open = menu_manager:call("isOpenInventoryMenu") or (os.clock() - last_inventory_open_time) < 0.25 end elseif is_re8 then is_inventory_open = (os.clock() - last_inventory_open_time) < 0.25 @@ -1838,7 +1838,7 @@ elseif is_re8 then ) end -local function check_player_hands_up() +local function update_player_gestures() local player = re8.player if not player then @@ -1896,7 +1896,7 @@ end local should_reset_view_no_player = false re.on_pre_application_entry("UpdateBehavior", function() - check_player_hands_up() + update_player_gestures() if not re8.player then if should_reset_view_no_player then @@ -1936,8 +1936,10 @@ end) update_hand_ik() end)]] -local last_melee = os.clock() -local last_melee_request_state = false +local last_melee = {os.clock(), os.clock()} +local last_melee_request_state = {false, false} +local swing_history = { 0, 0, 0, 0 } +local swing_index = 0 local function melee_attack(hit_controller) if not vrmod:is_hmd_active() or not vrmod:is_using_controllers() then return end @@ -1947,15 +1949,23 @@ local function melee_attack(hit_controller) return end - local real_hit_controller = re8.weapon:call("get_hitController") + local is_end_of_zoe_melee = is_re7 and re8.weapon:get_type_definition():is_a("app.CH9WeaponMelee") - if not real_hit_controller then - return - end - - -- RE7 - if hit_controller ~= nil and hit_controller ~= real_hit_controller then - return + if not is_end_of_zoe_melee then + local real_hit_controller = re8.weapon:call("get_hitController") + + if not real_hit_controller then + return + end + + -- RE7 + if hit_controller ~= nil and hit_controller ~= real_hit_controller then + return + end + else + if re8.hit_controller ~= hit_controller then + return + end end local right_controller = vrmod:get_controllers()[2] @@ -1964,21 +1974,61 @@ local function melee_attack(hit_controller) local right_controller_speed = right_controller_velocity:length() local right_controller_angular_speed = right_controller_angular_velocity:length() - if right_controller_speed < 2.2 and right_controller_angular_speed < 20 then - last_melee_request_state = false + local left_controller = vrmod:get_controllers()[1] + local left_controller_velocity = vrmod:get_velocity(left_controller) + local left_controller_angular_velocity = vrmod:get_angular_velocity(left_controller) + local left_controller_speed = left_controller_velocity:length() + local left_controller_angular_speed = left_controller_angular_velocity:length() + + local is_right_swing = right_controller_speed >= 2.2 or right_controller_angular_speed >= 20 + local is_left_swing = is_end_of_zoe_melee and left_controller_speed >= 2.2 or left_controller_angular_speed >= 20 + + if not is_left_swing then + last_melee_request_state[1] = false + end + + if not is_right_swing then + last_melee_request_state[2] = false + end + + if not is_right_swing and not is_left_swing then return end + -- only end of zoe can left swing + if not is_right_swing and is_left_swing then + if not is_end_of_zoe_melee then + return + end + end + local action_grip = vrmod:get_action_grip() local right_joystick = vrmod:get_right_joystick() local is_stab = vrmod:is_action_active(action_grip, right_joystick) - local cooldown_time = is_stab and 1.0 or 0.5 + local light_cooldown_time = is_end_of_zoe_melee and 0.5 or 0.5 + local cooldown_time = (is_stab and not is_end_of_zoe_melee) and 1.0 or light_cooldown_time local now = os.clock() if not cfg.no_melee_cooldown then - if not last_melee_request_state and now - last_melee < cooldown_time then - return + if is_left_swing then + if not last_melee_request_state[1] and now - last_melee[1] < cooldown_time then + if not is_end_of_zoe_melee then + return + else + is_left_swing = false + end + end + end + + if is_right_swing then + if not last_melee_request_state[2] and now - last_melee[2] < cooldown_time then + if not is_end_of_zoe_melee then + return + else + is_right_swing = false + end + end end end @@ -2002,59 +2052,89 @@ local function melee_attack(hit_controller) rcol:call("updatePose") - if not last_melee_request_state then - last_melee = now + if is_left_swing then + if not last_melee_request_state[1] then + last_melee[1] = now + end + + last_melee_request_state[1] = true end - last_melee_request_state = true + if is_right_swing then + if not last_melee_request_state[2] then + last_melee[2] = now + end + + last_melee_request_state[2] = true + end - for i=0, num_request_sets - 1 do - if is_re7 then - local num_collidables = rcol:call("getNumCollidablesFromIndex", i) - local userdata = rcol:call("getRequestSetUserDataFromIndex", i) + if not is_end_of_zoe_melee then + for i=0, num_request_sets - 1 do + if is_re7 then + local num_collidables = rcol:call("getNumCollidablesFromIndex", i) + local userdata = rcol:call("getRequestSetUserDataFromIndex", i) + + if userdata ~= nil and userdata:get_type_definition():is_a("app.Collision.ContactBaseUserData") then + for j=0, num_collidables - 1 do + local collidable = rcol:call("getCollidableFromIndex", i, j) - if userdata ~= nil and userdata:get_type_definition():is_a("app.Collision.ContactBaseUserData") then - for j=0, num_collidables - 1 do - local collidable = rcol:call("getCollidableFromIndex", i, j) + collidable:call("set_Enabled", true) + collidable:call("enable") + --collidable:call("set_UpdateShape", true) + end - collidable:call("set_Enabled", true) - collidable:call("enable") - --collidable:call("set_UpdateShape", true) + log.info(tostring(i) .. ": " ..userdata:get_type_definition():get_full_name()) end - end - if not is_stab then - hit_controller:call("addManualRequest", 0) - elseif i > 0 then - hit_controller:call("addManualRequest", i) - end - else - local num_collidables = rcol:call("getNumCollidables(System.UInt32, System.UInt32)", resource_id, i) - local userdata = rcol:call("getRequestSetUserData(System.UInt32, System.UInt32)", resource_id, i) - - if userdata:get_type_definition():is_a("app.ContactUserData") then - for j=0, num_collidables - 1 do - local collidable = rcol:call("getCollidable(System.UInt32, System.UInt32, System.UInt32)", resource_id, i, j) - --known_colliders[collidable] = true - - collidable:call("set_Enabled", true) - collidable:call("enable") - collidable:call("set_UpdateShape", true) - - if not is_stab then - hit_controller:call("setManualRequest", 0) - elseif i > 0 then - hit_controller:call("setManualRequest", i) + if not is_stab then + hit_controller:call("addManualRequest", 0) + elseif i > 0 then + hit_controller:call("addManualRequest", i) + end + else + local num_collidables = rcol:call("getNumCollidables(System.UInt32, System.UInt32)", resource_id, i) + local userdata = rcol:call("getRequestSetUserData(System.UInt32, System.UInt32)", resource_id, i) + + if userdata:get_type_definition():is_a("app.ContactUserData") then + for j=0, num_collidables - 1 do + local collidable = rcol:call("getCollidable(System.UInt32, System.UInt32, System.UInt32)", resource_id, i, j) + --known_colliders[collidable] = true + + collidable:call("set_Enabled", true) + collidable:call("enable") + collidable:call("set_UpdateShape", true) + + if not is_stab then + hit_controller:call("setManualRequest", 0) + elseif i > 0 then + hit_controller:call("setManualRequest", i) + end end end end end + else + --hit_controller:call("addManualRequest", 25) -- fucking SUPER punch!!! + + if is_right_swing then + hit_controller:call("addManualRequest", 16) + end + + if is_left_swing then + hit_controller:call("addManualRequest", 11) + end end - if is_stab then - vrmod:trigger_haptic_vibration(0.0, 0.1, 1, 5, vrmod:get_right_joystick()) - else - vrmod:trigger_haptic_vibration(0.0, 0.1, 1, 0.5, vrmod:get_right_joystick()) + if is_right_swing then + if is_stab or is_end_of_zoe_melee then + vrmod:trigger_haptic_vibration(0.0, 0.1, 1, 5, vrmod:get_right_joystick()) + else + vrmod:trigger_haptic_vibration(0.0, 0.1, 1, 0.5, vrmod:get_right_joystick()) + end + end + + if is_left_swing then + vrmod:trigger_haptic_vibration(0.0, 0.1, 1, 5, vrmod:get_left_joystick()) end end @@ -2425,6 +2505,7 @@ re.on_frame(function() end) local debug_adjust_hand_offset = false +local debug_hit_controller = false re.on_draw_ui(function() local changed = false @@ -2562,6 +2643,66 @@ re.on_draw_ui(function() imgui.tree_pop() end + if imgui.tree_node("Left Weapon") then + local left_weapon = re8.left_weapon + + object_explorer:handle_address(left_weapon) + + imgui.tree_pop() + end + + if imgui.tree_node("Hit Controller") then + local hit_controller = re8.hit_controller + + changed, debug_hit_controller = imgui.checkbox("Debug hit controller", debug_hit_controller) + + if debug_hit_controller then + local rcol = hit_controller:get_field("RequestSetCollider") + + if not rcol then + return + end + + local num_request_sets = is_re8 and rcol:call("getNumRequestSets(System.UInt32)", resource_id) or rcol:call("get_NumRequestSets") + + + for i=0, num_request_sets - 1 do + if is_re7 then + + local num_collidables = rcol:call("getNumCollidablesFromIndex", i) + local userdata = rcol:call("getRequestSetUserDataFromIndex", i) + + if userdata ~= nil and userdata:get_type_definition():is_a("app.Collision.ContactBaseUserData") then + for j=0, num_collidables - 1 do + local collidable = rcol:call("getCollidableFromIndex", i, j) + + if collidable then + local shape = collidable:call("get_TransformedShape") + + if imgui.button(tostring(i) .. ", " .. tostring(j) .. ": " .. shape:get_type_definition():get_full_name()) then + hit_controller:call("addManualRequest", i) + end + + if shape:get_type_definition():is_a("via.physics.CapsuleShape") then + local pos = shape:call("get_PosA") + local pos_screen = draw.world_to_screen(pos) + + if pos_screen then + draw.text(tostring(i), pos_screen.x, pos_screen.y, 0xffffffff) + end + end + end + end + end + end + end + end + + object_explorer:handle_address(hit_controller) + + imgui.tree_pop() + end + if imgui.tree_node("Weapon Colliders") then local i = 0 for collider, _ in pairs(known_colliders) do @@ -2613,12 +2754,28 @@ local re8_inventory_names = { "GUIShopBg" } +local re7_inventory_names = { + "CH9PauseMenu", + "CH9MapMaskGUI", + "CH9MultiSubMenu", + "PauseMenu", + "MapMaskGUI", + "MultiSubMenu", + "FileMenu", +} + for i, v in ipairs(re8_inventory_names) do re8_inventory_names[v] = true end +for i, v in ipairs(re7_inventory_names) do + re7_inventory_names[v] = true +end + local reticle_names = { "ReticleGUI", + "CH8ReticleGUI", + "CH9ReticleGUI", "GUIReticle" } @@ -2713,7 +2870,7 @@ re.on_pre_gui_draw_element(function(element, context) end end - if re8_inventory_names[name] then + if re8_inventory_names[name] or re7_inventory_names[name] then last_inventory_open_time = os.clock() end diff --git a/scripts/utility/RE8.lua b/scripts/utility/RE8.lua index 603f7a5ad..8430c7786 100644 --- a/scripts/utility/RE8.lua +++ b/scripts/utility/RE8.lua @@ -63,7 +63,7 @@ local function initialize_re8(re8) re8.player = nil re8.transform = nil re8.weapon = nil - re8.weapon_gameobject = nil + re8.left_weapon = nil re8.inventory = nil re8.hand_touch = nil re8.order = nil @@ -82,6 +82,7 @@ local function initialize_re8(re8) re8.status = nil re8.event_action_controller = nil re8.game_event_action_controller = nil + re8.hit_controller = nil re8.wants_block = false re8.movement_speed_rate = 0.0 re8.movement_speed_vector = Vector3f.new(0, 0, 0) @@ -145,7 +146,7 @@ function re8.get_weapon_object(player) return nil end - return equip_manager:call("get_equipWeaponRight") + return equip_manager:call("get_equipWeaponRight"), equip_manager:call("get_equipWeaponLeft") elseif is_re8 then if not re8.updater then return nil @@ -250,14 +251,20 @@ re.on_pre_application_entry("UpdateBehavior", function() re8.is_motion_play = false end - local weapon = re8.get_weapon_object(player) + local weapon, left_weapon = re8.get_weapon_object(player) if weapon == nil then re8.weapon = nil + re8.left_weapon = nil return end re8.weapon = weapon + re8.left_weapon = left_weapon + + if is_re7 then + re8.hit_controller = get_component(player, "app.Collision.HitController") + end re8.update_in_cutscene_state() end) From 8c8465234c8e7d0ca339af713c711ffd98f76909 Mon Sep 17 00:00:00 2001 From: praydog Date: Sat, 7 May 2022 14:45:08 -0700 Subject: [PATCH 32/45] VR (RE7/8): Make use of the native implementations of some functions --- scripts/re8_vr.lua | 525 ++++------------------------------------ scripts/utility/RE8.lua | 67 ++--- 2 files changed, 82 insertions(+), 510 deletions(-) diff --git a/scripts/re8_vr.lua b/scripts/re8_vr.lua index 22ed64e0f..7957fd791 100644 --- a/scripts/re8_vr.lua +++ b/scripts/re8_vr.lua @@ -26,10 +26,6 @@ local is_openxr = vrmod:is_openxr_loaded() local last_original_right_hand_rotation = Quaternion.new(0.0, 0.0, 0.0, 0.0) local last_camera_matrix = Matrix4x4f.new() -local last_right_hand_rotation = Quaternion.new(0.0, 0.0, 0.0, 0.0) -local last_right_hand_position = Vector3f.new(0.0, 0.0, 0.0) -local last_left_hand_rotation = Quaternion.new(0.0, 0.0, 0.0, 0.0) -local last_left_hand_position = Vector3f.new(0.0, 0.0, 0.0) local left_hand_rotation_vec = Vector3f.new(-0.105 + 0.2, 2.37, 1.10) -- pitch yaw roll? local right_hand_rotation_vec = Vector3f.new(-0.105, -2.37, -1.10) -- pitch yaw roll? @@ -50,6 +46,11 @@ if is_openxr then right_hand_position_offset = openxr.right_hand_position_offset:clone() end +re8vr.left_hand_rotation_offset = left_hand_rotation_offset +re8vr.right_hand_rotation_offset = right_hand_rotation_offset +re8vr.left_hand_position_offset = left_hand_position_offset +re8vr.right_hand_position_offset = right_hand_position_offset + local ray_typedef = sdk.find_type_definition("via.Ray") local last_muzzle_pos = Vector4f.new(0.0, 0.0, 0.0, 1.0) local last_muzzle_rot = Quaternion.new(0.0, 0.0, 0.0, 0.0) @@ -206,7 +207,7 @@ local function update_muzzle_data() last_shoot_pos = last_muzzle_pos end elseif vrmod:is_using_controllers() then - last_muzzle_pos = last_right_hand_position + last_muzzle_pos = re8vr.last_right_hand_position last_muzzle_rot = last_camera_matrix:to_quat() last_muzzle_forward = (last_muzzle_rot * Vector3f.new(0, 0, -1)):normalized() @@ -221,7 +222,7 @@ end local function update_pad_device(device) if not vrmod:is_hmd_active() then - re8.is_holding_left_grip = false + re8vr.is_holding_left_grip = false return end @@ -360,7 +361,7 @@ local function update_pad_device(device) cur_button = cur_button | via.hid.GamePadButton.RTrigTop end - re8.is_holding_left_grip = vrmod:is_action_active(action_grip, left_joystick) + re8vr.is_holding_left_grip = vrmod:is_action_active(action_grip, left_joystick) if re8.wants_block or vrmod:is_action_active(action_block, left_joystick) or vrmod:is_action_active(action_block, right_joystick) then cur_button = cur_button | via.hid.GamePadButton.LTrigTop @@ -401,7 +402,7 @@ end local function update_padman(padman) if not vrmod:is_hmd_active() or not vrmod:is_using_controllers() then - re8.is_holding_left_grip = false + re8vr.is_holding_left_grip = false return end @@ -529,315 +530,8 @@ sdk.hook( on_post_try_guard_start ) -local function calculate_tpose_world(joint, depth) - if not depth then - depth = 1 - end - - local original_positions = {} - local original_rotations = {} - local current_positions = {} - - local player_transform = re8.transform - local player_pos = transform_get_position:call(player_transform) - local player_rot = transform_get_rotation:call(player_transform) - - local joints = {} - - local cur_joint = joint - - for i=1, depth do - cur_joint = joint_get_parent:call(cur_joint) - table.insert(joints, cur_joint) - end - - local parent_pos = joint_get_position:call(cur_joint) - local parent_rot = joint_get_rotation:call(cur_joint) - local original_parent_pos = player_pos + (player_rot * player_transform:calculate_base_transform(cur_joint)[3]) - - for i=1, depth do - local joint = joints[depth-i] - - local original_pos = player_pos + (player_rot * player_transform:calculate_base_transform(joint)[3]) - local diff = original_pos - original_parent_pos - local updated_pos = parent_pos + diff - - original_parent_pos = original_pos - parent_pos = updated_pos - end - - local original_pos = player_pos + (player_rot * player_transform:calculate_base_transform(joint)[3]) - local diff = original_pos - original_parent_pos - return parent_pos + diff -end - -local function set_hand_joints_to_tpose(hand_ik) - -- fixes an instance in not a hero where - -- chris is supposed to jump down something without tripping a laser - if re8.is_in_cutscene then return end - - local hashes = { - } - - if is_re7 then - hashes = { - hand_ik:get_field("HashJoint0"), - hand_ik:get_field("HashJoint1"), - hand_ik:get_field("HashJoint2"), - hand_ik:get_field("HashJoint3") - } - elseif is_re8 then - hashes = { - hand_ik:get_field("k__BackingField"), - hand_ik:get_field("k__BackingField"), - hand_ik:get_field("k__BackingField") - } - end - - local original_positions = {} - local original_rotations = {} - local current_positions = {} - - local player_transform = re8.transform - local player_pos = player_transform:get_position() - local player_rot = player_transform:get_rotation() - - local joints = {} - - for i, hash in ipairs(hashes) do - if hash and hash ~= 0 then - local joint = transform_get_joint_by_hash:call(player_transform, hash) - - if joint then - table.insert(joints, joint_get_parent:call(joint)) - end - end - end - - if #joints > 0 and joints[1] ~= nil then - table.insert(joints, 1, joint_get_parent:call(joints[1])) - - if not re8.is_grapple_aim then - table.insert(joints, 1, joint_get_parent:call(joints[1])) - table.insert(joints, 1, joint_get_parent:call(joints[1])) - end - end - - for i, joint in ipairs(joints) do - local base_transform = player_transform:calculate_base_transform(joint) - original_positions[i] = player_pos + (player_rot * base_transform[3]) - original_rotations[i] = player_rot * base_transform:to_quat() - current_positions[i] = joint_get_position:call(joint) - end - - -- second pass - for i, joint in ipairs(joints) do - if joint then - local next_joint = joints[i + 1] - - if next_joint ~= nil then - local diff = original_positions[i + 1] - original_positions[i] - local updated_pos = current_positions[i] + diff - - joint_set_position:call(next_joint, updated_pos) - joint_set_rotation:call(next_joint, original_rotations[i+1]) - - current_positions[i + 1] = updated_pos - end - end - end -end - local function update_hand_ik() - if not re8.player then return end - if not vrmod:is_hmd_active() then return end - - local controllers = vrmod:get_controllers() - - if #controllers == 0 then - re8.was_gripping_weapon = false - return - end - - if not re8.left_hand_ik or not re8.right_hand_ik then - re8.was_gripping_weapon = false - return - end - - --if re8.is_in_cutscene then return end - if not re8.can_use_hands then - re8.was_gripping_weapon = false - return - end - - if not vrmod:is_using_controllers() then - re8.was_gripping_weapon = false - re8.is_holding_left_grip = false - --[[set_hand_joints_to_tpose(re8.left_hand_ik) - set_hand_joints_to_tpose(re8.right_hand_ik) - re8.left_hand_ik:call("calc") - re8.right_hand_ik:call("calc")]] - return - end - - local player = re8.player - local original_head_rotation = nil - local head_joint = nil - local motion = player:call("getComponent(System.Type)", sdk.typeof("via.motion.Motion")) - - local original_right_rot = Quaternion.identity() - local original_left_rot_relative = Quaternion.identity() - local original_left_pos_relative = Vector3f.new(0, 0, 0) - local original_right_rot_relative = Quaternion.identity() - local original_right_pos_relative = Vector3f.new(0, 0, 0) - - -- the Point of this is to fix the head rotation during cutscenes - -- because the camera seems to be parented to the head during these events - -- so modifying the joint when we set the tpose won't cause some extremely jarring movement - if motion then - local transform = re8.transform - - if not head_hash then - head_hash = get_joint_hash(transform, motion, "Head") - end - - head_joint = transform_get_joint_by_hash:call(transform, head_hash) - - if head_joint then - original_head_rotation = joint_get_rotation:call(head_joint) - end - - local left_hash = nil - local right_hash = nil - - if is_re7 then - left_hash = re8.left_hand_ik:get_field("HashJoint2") - right_hash = re8.right_hand_ik:get_field("HashJoint2") - elseif is_re8 then - left_hash = re8.left_hand_ik:get_field("k__BackingField") - right_hash = re8.right_hand_ik:get_field("k__BackingField") - end - - - local left_index = motion_get_joint_index_by_name_hash(motion, left_hash) - local right_index = motion_get_joint_index_by_name_hash(motion, right_hash) - - local original_left_pos = motion_get_world_position(motion, left_index) - local original_right_pos = motion_get_world_position(motion, right_index) - local original_left_rot = motion_get_world_rotation(motion, left_index) - original_right_rot = motion_get_world_rotation(motion, right_index) - - local right_rot_inverse = original_right_rot:inverse() - original_left_pos_relative = right_rot_inverse * (original_left_pos - original_right_pos) - original_left_rot_relative = right_rot_inverse * original_left_rot - - local left_rot_inverse = original_left_rot:inverse() - original_right_pos_relative = left_rot_inverse * (original_right_pos - original_left_pos) - original_right_rot_relative = left_rot_inverse * original_right_rot - end - - local left_controller_transform = vrmod:get_transform(controllers[1]) - local right_controller_transform = vrmod:get_transform(controllers[2]) - local left_controller_rotation = left_controller_transform:to_quat() - local right_controller_rotation = right_controller_transform:to_quat() - - local hmd_transform = vrmod:get_transform(0) - --local hmd_rotation = (vrmod:get_rotation_offset() * hmd_transform:to_quat()):normalized() - - local left_controller_offset = left_controller_transform[3] - hmd_transform[3] - local right_controller_offset = right_controller_transform[3] - hmd_transform[3] - - local camera = sdk.get_primary_camera() - local camera_rotation = last_camera_matrix:to_quat() - - local original_camera_matrix = camera:call("get_WorldMatrix") - local original_camera_rotation = original_camera_matrix:to_quat() - local updated_camera_pos = original_camera_matrix[3] - - vrmod:apply_hmd_transform(original_camera_rotation, updated_camera_pos) - - -- Handles decoupled camera pitch - original_camera_rotation = (original_camera_rotation * hmd_transform:to_quat():inverse()):normalized() - - local rh_rotation = original_camera_rotation * right_controller_rotation * right_hand_rotation_offset - local rh_pos = updated_camera_pos - + ((original_camera_rotation * right_controller_offset) - + ((original_camera_rotation * right_controller_rotation):normalized() * right_hand_position_offset)) - - rh_pos.w = 1.0 - - local lh_grip_position = rh_pos + (rh_rotation:normalized() * original_left_pos_relative) - lh_grip_position.w = 1.0 - - local lh_rotation = original_camera_rotation * left_controller_rotation * left_hand_rotation_offset - local lh_pos = updated_camera_pos - + ((original_camera_rotation * left_controller_offset) - + ((original_camera_rotation * left_controller_rotation):normalized() * left_hand_position_offset)) - - lh_pos.w = 1.0 - - local lh_delta_to_rh = (lh_pos - rh_pos) - local lh_grip_delta_to_rh = (lh_grip_position - rh_pos) - local lh_grip_delta = (lh_grip_position - lh_pos) - local lh_grip_distance = lh_grip_delta:length() - - re8.was_gripping_weapon = lh_grip_distance <= 0.1 or (re8.was_gripping_weapon and re8.is_holding_left_grip) - - -- Lets the player hold their left hand near the original (grip) position of the weapon - if re8.was_gripping_weapon and not re8.is_reloading then - if original_left_pos_relative:length() >= 0.1 then - local original_grip_rot = lh_grip_delta_to_rh:normalized():to_quat() - local current_grip_rot = lh_delta_to_rh:normalized():to_quat() - - local grip_rot_delta = (current_grip_rot * original_grip_rot:inverse()):normalized() - - -- Adjust the right hand rotation - rh_rotation = (grip_rot_delta * rh_rotation):normalized() - - -- Adjust the grip position - lh_grip_position = rh_pos + (rh_rotation * original_left_pos_relative) - lh_grip_position.w = 1.0 - end - - -- Set the left hand position and rotation to the grip position - lh_pos = lh_grip_position - lh_rotation = rh_rotation * original_left_rot_relative - else - if re8.is_reloading then - lh_pos = lh_grip_position - lh_rotation = rh_rotation * original_left_rot_relative - else - lh_pos = lh_pos - lh_rotation = lh_rotation - end - end - - last_left_hand_position = lh_pos:clone() - last_left_hand_rotation = lh_rotation:clone() - - set_hand_joints_to_tpose(re8.left_hand_ik) - - re8.left_hand_ik_transform:set_position(lh_pos) - re8.left_hand_ik_transform:set_rotation(lh_rotation) - re8.left_hand_ik:set_field("Transition", 1.0) - re8.left_hand_ik:call("calc") - - set_hand_joints_to_tpose(re8.right_hand_ik) - - last_right_hand_position = rh_pos:clone() - last_right_hand_rotation = rh_rotation:clone() - last_right_hand_position.w = 1.0 - - last_original_right_hand_rotation = (last_right_hand_rotation * right_hand_rotation_offset:inverse()):normalized() - - re8.right_hand_ik_transform:set_position(rh_pos) - re8.right_hand_ik_transform:set_rotation(rh_rotation) - re8.right_hand_ik:set_field("Transition", 1.0) - re8.right_hand_ik:call("calc") - - if head_joint ~= nil and original_head_rotation ~= nil then - joint_set_rotation:call(head_joint, original_head_rotation) - end + re8vr:update_hand_ik() end local last_real_camera_rotation = Quaternion.new(1, 0, 0, 0) @@ -883,116 +577,7 @@ end local zero_vec = Vector3f.new(0, 0, 0) local function update_body_ik(camera_rotation, camera_pos) - if not re8.player then return end - - local player = re8.player - local ik_leg = player:call("getComponent(System.Type)", sdk.typeof("via.motion.IkLeg")) - - if not ik_leg then - if not vrmod:is_using_controllers() or re8.is_in_cutscene then - return - end - - ik_leg = player:call("createComponent(System.Type)", sdk.typeof("via.motion.IkLeg")) - - if not ik_leg then - log.error("Failed to create IK leg component") - return - end - end - - if re8.is_in_cutscene or not vrmod:is_hmd_active() or not vrmod:is_using_controllers() then - --ik_leg:call("set_Enabled", false) - ik_leg:call("set_CenterOffset", Vector3f.new(0, 0, 0)) - ik_leg:call("setCenterAdjust", 0) - ik_leg:call("set_CenterPositionCtrl", 2) -- world offset - ik_leg:call("set_GroundContactUpDistance", 0.0) -- Fixes the whole player being jarringly moved upwards. - - if not vrmod:is_using_controllers() then - ik_leg:call("destroy", ik_leg) - end - - return - else - ik_leg:call("set_Enabled", true) - end - - local motion = player:call("getComponent(System.Type)", sdk.typeof("via.motion.Motion")) - - if not motion then - log.error("Failed to get motion component") - return - end - - local transform = player:call("get_Transform") - - if not head_hash then - head_hash = get_joint_hash(transform, motion, "Head") - end - - --[[if not chest_hash then - chest_hash = get_joint_hash(transform, motion, "Chest") - end]] - - if not center_hash then - center_hash = get_joint_hash(transform, motion, "Hip") - end - - local transform_rot = transform:call("get_Rotation") - local transform_pos = transform:call("get_Position") - - local head_joint = transform_get_joint_by_hash:call(transform, head_hash) - --local chest_joint = transform:call("getJointByHash", chest_hash) - --local hip_joint = transform:call("getJointByHash", center_hash) - - --local head_index = motion:call("getJointIndexByNameHash", head_hash) - --chest_index = motion:call("getJointIndexByNameHash", chest_hash) - --local original_head_pos = motion:call("getWorldPosition", head_index) - --local original_chest_pos = motion:call("getWorldPosition", chest_index) - - local normal_dir = camera_rotation * Vector3f.new(0, 0, 1) - local flattened_dir = camera_rotation * Vector3f.new(0, 0, 1) - flattened_dir.y = 0.0 - flattened_dir:normalize() - - local original_head_pos = calculate_tpose_world(head_joint, 4) + (flattened_dir * (math.abs(normal_dir.y) * -0.1)) + (flattened_dir * 0.025) - - --[[if not vrmod:is_using_controllers() then - original_head_pos = joint_get_position:call(head_joint) + (flattened_dir * (math.abs(normal_dir.y) * -0.1)) + (flattened_dir * 0.025) - end]] - - --original_head_pos = transform_rot * original_head_pos - --original_head_pos = transform:call("getJointByName", "root"):call("get_Rotation") * original_head_pos - --original_head_pos = transform_rot * transform:calculate_base_transform(head_joint)[3] - --original_chest_pos = transform_rot * original_chest_pos - - --original_head_pos.x = original_chest_pos.x - --original_head_pos.z = original_chest_pos.z - - --[[local center_index = motion:call("getJointIndexByNameHash", center_hash) - local original_center_pos = motion:call("getWorldPosition", center_index) - - original_center_pos = transform_rot * original_center_pos - - local current_center_pos = transform:call("getJointByHash", center_hash):call("get_Position") - local center_diff = (original_center_pos * -1.0) - center_diff.y = 0.0]] - - --local current_head_pos = transform:call("getJointByName", "Head"):call("get_Position") - - --[[local center_joint = transform:call("getJointByName", "Hip") - - local center_pos = center_joint:call("get_Position") - local transform_pos = transform:call("get_Position")]] - - local diff_to_camera = ((camera_pos) - original_head_pos) - - --ik_leg:call("set_CenterJointName", "Hip") - ik_leg:call("set_CenterOffset", diff_to_camera) - ik_leg:call("setCenterAdjust", 0) - ik_leg:call("set_CenterPositionCtrl", 2) -- world offset - ik_leg:call("set_GroundContactUpDistance", 0.0) -- Fixes the whole player being jarringly moved upwards. - --ik_leg:call("set_UpdateTiming", 2) -- ConstraintsBegin + re8vr:update_body_ik(camera_rotation, camera_pos) end local function on_pre_shoot(args) @@ -1011,33 +596,12 @@ local function on_pre_shoot(args) local ray = args[3] - --[[if is_re7 then - local muzzle_joint = weapon:call("get_muzzleJoint") - - if muzzle_joint then - local muzzle_pos = joint_get_position:call(muzzle_joint) - local muzzle_forward = joint_get_rotation:call(muzzle_joint) * Vector3f.new(0, 0, 1) - - local pos = muzzle_pos + (muzzle_forward * 0.01) - local from = Vector4f.new(pos.x, pos.y, pos.z, 1.0) - local dir = Vector4f.new(forward.x, forward.y, forward.z, 0.0) - - -- nudge the start position slightly forward because - -- apparently the bullets can collide with the weapon.... wtf - sdk.set_native_field(ray, ray_typedef, "from", from) - sdk.set_native_field(ray, ray_typedef, "dir", dir) - else - log.info("No muzzle joint found") - end - elseif is_re8 then]] - local pos = last_muzzle_pos + (last_muzzle_forward * 0.02) - local from = Vector4f.new(pos.x, pos.y, pos.z, 1.0) - local dir = Vector4f.new(last_muzzle_forward.x, last_muzzle_forward.y, last_muzzle_forward.z, 1.0) - - sdk.set_native_field(ray, ray_typedef, "from", from) - sdk.set_native_field(ray, ray_typedef, "dir", dir) - --end + local pos = last_muzzle_pos + (last_muzzle_forward * 0.02) + local from = Vector4f.new(pos.x, pos.y, pos.z, 1.0) + local dir = Vector4f.new(last_muzzle_forward.x, last_muzzle_forward.y, last_muzzle_forward.z, 1.0) + sdk.set_native_field(ray, ray_typedef, "from", from) + sdk.set_native_field(ray, ray_typedef, "dir", dir) --sdk.call_native_func(ray, ray_typedef, ".ctor(via.vec3, via.vec3)", last_muzzle_pos, last_muzzle_forward) end @@ -1076,9 +640,8 @@ local function on_pre_throwable_late_update(args) if not is_grip_down and throwable_was_right_grip_down then local vel_norm = Vector3f.new(0.0, 1.0, 0.0):normalized() - local from = Vector3f.new(last_right_hand_position.x, last_right_hand_position.y, last_right_hand_position.z) + local from = re8vr.last_right_hand_position - from = Vector4f.new(from.x, from.y, from.z, 1.0) vel_norm = Vector4f.new(vel_norm.x, vel_norm.y, vel_norm.z, 1.0) -- some BS to just throw it @@ -1360,7 +923,7 @@ local function slerp_gui(new_gui_quat) local now = os.clock() -- trigger gui slerp - if dot_ang >= 20 or re8.is_in_cutscene then + if dot_ang >= 20 or re8vr.is_in_cutscene then last_gui_forced_slerp = now end @@ -1374,7 +937,7 @@ local function slerp_gui(new_gui_quat) last_gui_quat = last_gui_quat:slerp(new_gui_quat, dot_dist * math.max((GUI_MAX_SLERP_TIME - slerp_time_diff) * re8.delta_time, 0.0)) end - if re8.is_in_cutscene then + if re8vr.is_in_cutscene then vrmod:recenter_gui(last_gui_quat) else vrmod:recenter_gui(last_gui_quat * new_gui_quat:inverse()) @@ -1444,19 +1007,19 @@ local function fix_player_camera(player_camera) end if current_type ~= 0 then -- MaximumOperatable - re8.is_in_cutscene = true + re8vr.is_in_cutscene = true is_maximum_controllable = false last_time_not_maximum_controllable = os.clock() else if os.clock() - last_time_not_maximum_controllable <= 1.0 then - re8.is_in_cutscene = true + re8vr.is_in_cutscene = true end end end local wants_recenter = false - if re8.is_in_cutscene and not last_cutscene_state then + if re8vr.is_in_cutscene and not last_cutscene_state then --vrmod:recenter_view() -- force the gui to be recentered when we exit the cutscene @@ -1466,7 +1029,7 @@ local function fix_player_camera(player_camera) --queue_recenter = true vrmod:recenter_gui(last_gui_quat) - elseif not re8.is_in_cutscene and last_cutscene_state then + elseif not re8vr.is_in_cutscene and last_cutscene_state then last_gui_forced_slerp = os.clock() last_gui_quat = vrmod:get_rotation(0):to_quat():inverse() wants_recenter = true @@ -1524,7 +1087,7 @@ local function fix_player_camera(player_camera) -- Joint is used for the actual final rendering of the game world --if not wants_recenter then - if re8.is_in_cutscene then + if re8vr.is_in_cutscene then joint_set_position:call(camera_joint, camera_pos_pre_hmd) joint_set_rotation:call(camera_joint, camera_rot_pre_hmd) else @@ -1543,7 +1106,7 @@ local function fix_player_camera(player_camera) update_body_ik(camera_rot, camera_pos) -- Slerp the gui around - slerp_gui(re8.is_in_cutscene and (camera_rot_pre_hmd * camera_rot:inverse()) or vrmod:get_rotation(0):to_quat():inverse()) + slerp_gui(re8vr.is_in_cutscene and (camera_rot_pre_hmd * camera_rot:inverse()) or vrmod:get_rotation(0):to_quat():inverse()) local fixed_dir = ((neg_forward_identity * camera_rot_no_shake) * Vector3f.new(0, 0, -1)):normalized() local fixed_rot = fixed_dir:to_quat() @@ -1585,7 +1148,7 @@ local function fix_player_camera(player_camera) if camera_controller then local camera_controller_rot = Quaternion.identity() - if re8.is_in_cutscene then + if re8vr.is_in_cutscene then if is_re7 then camera_controller_rot = camera_controller:get_field("k__BackingField") elseif is_re8 then @@ -1599,9 +1162,9 @@ local function fix_player_camera(player_camera) controller_forward.y = 0.0 camera_controller_rot = controller_forward:normalized():to_quat() - --if wants_recenter or not re8.is_in_cutscene then - if not re8.is_in_cutscene or is_maximum_controllable then - if not re8.is_in_cutscene then + --if wants_recenter or not re8vr.is_in_cutscene then + if not re8vr.is_in_cutscene or is_maximum_controllable then + if not re8vr.is_in_cutscene then vrmod:recenter_view() end @@ -1633,7 +1196,7 @@ local function fix_player_camera(player_camera) -- stops the camera from pivoting around the player -- so we can use VR to look around without the body sticking out --if vrmod:is_using_controllers() then - --[[if not re8.is_in_cutscene then + --[[if not re8vr.is_in_cutscene then local param_container = player_camera:get_field("_CurrentParamContainer") if param_container == nil then @@ -1684,7 +1247,7 @@ local function fix_player_camera(player_camera) --update_crosshair_world_pos(camera_pos, camera_pos + (fixed_dir * 1000.0)) end - last_cutscene_state = re8.is_in_cutscene + last_cutscene_state = re8vr.is_in_cutscene end local function on_pre_player_camera_update(args) @@ -1726,7 +1289,7 @@ local function on_pre_player_interp_rotation(args) local camera_gameobject = camera:call("get_GameObject") local camera_transform = camera_gameobject:call("get_Transform") - re8.is_in_cutscene = true + re8vr.is_in_cutscene = true fix_player_camera(player_camera) end @@ -1839,7 +1402,7 @@ elseif is_re8 then end local function update_player_gestures() - local player = re8.player + local player = re8vr.player if not player then re8.wants_block = false @@ -1898,7 +1461,7 @@ local should_reset_view_no_player = false re.on_pre_application_entry("UpdateBehavior", function() update_player_gestures() - if not re8.player then + if not re8vr.player then if should_reset_view_no_player then vrmod:recenter_view() vrmod:set_gui_rotation_offset(Quaternion.identity()) @@ -1943,7 +1506,7 @@ local swing_index = 0 local function melee_attack(hit_controller) if not vrmod:is_hmd_active() or not vrmod:is_using_controllers() then return end - if re8.is_in_cutscene or not re8.can_use_hands then return end + if re8vr.is_in_cutscene or not re8vr.can_use_hands then return end if not re8.weapon then return @@ -2146,7 +1709,7 @@ end local function on_post_hit_controller_update(args) if not vrmod:is_hmd_active() or not vrmod:is_using_controllers() then return end - if re8.is_in_cutscene or not re8.can_use_hands then return end + if re8vr.is_in_cutscene or not re8vr.can_use_hands then return end local hit_controller = sdk.to_managed_object(hit_controller_args[2]) @@ -2211,10 +1774,10 @@ re.on_pre_application_entry("UnlockScene", function() last_camera_matrix = vrmod:get_last_render_matrix() - if not re8.player or not re8.transform then last_roomscale_failure = os.clock() return end + if not re8vr.player or not re8.transform then last_roomscale_failure = os.clock() return end if not re8.status then last_roomscale_failure = os.clock() return end -- in the main menu or something. if not last_camera_matrix then last_roomscale_failure = os.clock() return end - if re8.is_in_cutscene then last_roomscale_failure = os.clock() return end + if re8vr.is_in_cutscene then last_roomscale_failure = os.clock() return end if os.clock() - last_roomscale_failure < 1.0 then return end @@ -2413,7 +1976,7 @@ local function re8_on_pre_order_vibration(args) if left_power > 0 then local left_joystick = vrmod:get_left_joystick() vrmod:trigger_haptic_vibration(0.0, duration, 1, left_power, left_joystick) - elseif re8.was_gripping_weapon then + elseif re8vr.was_gripping_weapon then local left_joystick = vrmod:get_left_joystick() vrmod:trigger_haptic_vibration(0.0, duration, 1, right_power, left_joystick) end @@ -2608,7 +2171,7 @@ re.on_draw_ui(function() end if imgui.tree_node("Player") then - object_explorer:handle_address(re8.player) + object_explorer:handle_address(re8vr.player) imgui.tree_pop() end @@ -2620,7 +2183,7 @@ re.on_draw_ui(function() end if imgui.tree_node("Right Hand IK") then - local right_hand_ik = re8.right_hand_ik + local right_hand_ik = re8vr.right_hand_ik object_explorer:handle_address(right_hand_ik) @@ -2628,7 +2191,7 @@ re.on_draw_ui(function() end if imgui.tree_node("Left Hand IK") then - local left_hand_ik = re8.left_hand_ik + local left_hand_ik = re8vr.left_hand_ik object_explorer:handle_address(left_hand_ik) @@ -2736,8 +2299,8 @@ re.on_draw_ui(function() imgui.text("Has postural camera control: " .. tostring(re8.has_postural_camera_control)) imgui.text("Is arm jacked: " .. tostring(re8.is_arm_jacked)) imgui.text("Is motion play: " .. tostring(re8.is_motion_play)) - imgui.text("Is in cutscene: " .. tostring(re8.is_in_cutscene)) - imgui.text("Can use hands: " .. tostring(re8.can_use_hands)) + imgui.text("Is in cutscene: " .. tostring(re8vr.is_in_cutscene)) + imgui.text("Can use hands: " .. tostring(re8vr.can_use_hands)) imgui.tree_pop() end diff --git a/scripts/utility/RE8.lua b/scripts/utility/RE8.lua index 8430c7786..134a390b2 100644 --- a/scripts/utility/RE8.lua +++ b/scripts/utility/RE8.lua @@ -60,24 +60,24 @@ local callbacks = CallbackManager:new() local function initialize_re8(re8) re8 = re8 or {} - re8.player = nil + re8vr.player = nil re8.transform = nil re8.weapon = nil re8.left_weapon = nil re8.inventory = nil re8.hand_touch = nil re8.order = nil - re8.right_hand_ik = nil - re8.left_hand_ik = nil - re8.right_hand_ik_transform = nil - re8.left_hand_ik_transform = nil - re8.is_in_cutscene = false + re8vr.right_hand_ik = nil + re8vr.left_hand_ik = nil + re8vr.right_hand_ik_transform = nil + re8vr.left_hand_ik_transform = nil + re8vr.is_in_cutscene = false re8.is_arm_jacked = false - re8.is_grapple_aim = false + re8vr.is_grapple_aim = false re8.is_motion_play = false - re8.is_reloading = false + re8vr.is_reloading = false re8.has_postural_camera_control = true - re8.can_use_hands = true + re8vr.can_use_hands = true re8.updater = nil re8.status = nil re8.event_action_controller = nil @@ -171,13 +171,13 @@ function re8.get_weapon_object(player) end function re8.update_in_cutscene_state() - re8.is_in_cutscene = re8.num_active_tasks > 0 or not re8.has_postural_camera_control or re8.is_arm_jacked or re8.is_motion_play - re8.can_use_hands = not re8.is_arm_jacked and not re8.is_motion_play + re8vr.is_in_cutscene = re8.num_active_tasks > 0 or not re8.has_postural_camera_control or re8.is_arm_jacked or re8.is_motion_play + re8vr.can_use_hands = not re8.is_arm_jacked and not re8.is_motion_play end re.on_pre_application_entry("UpdateBehavior", function() - re8.player = re8.get_localplayer() - local player = re8.player + re8vr.player = re8.get_localplayer() + local player = re8vr.player if player == nil or not re8.application then initialize_re8(re8) @@ -212,32 +212,41 @@ re.on_pre_application_entry("UpdateBehavior", function() end if re8.status ~= nil then - re8.is_reloading = re8.status:call("get_isReload") + re8vr.is_reloading = re8.status:call("get_isReload") + re8vr.is_reloading = re8vr.is_reloading end if re8.order ~= nil then - re8.is_grapple_aim = re8.order:get_field("IsGrappleAimEnable") + re8vr.is_grapple_aim = re8.order:get_field("IsGrappleAimEnable") end if re8.hand_touch == nil then - re8.right_hand_ik = nil - re8.left_hand_ik = nil + re8vr.right_hand_ik = nil + re8vr.left_hand_ik = nil + re8vr.right_hand_ik_object = nil + re8vr.left_hand_ik_object = nil + re8vr.right_hand_ik_transform = nil + re8vr.left_hand_ik_transform = nil else local hand_ik = re8.hand_touch:get_field("HandIK"):get_elements() if #hand_ik < 2 then log.info("no hand ik") - re8.right_hand_ik = nil - re8.left_hand_ik = nil + re8vr.right_hand_ik = nil + re8vr.left_hand_ik = nil + re8vr.right_hand_ik_object = nil + re8vr.left_hand_ik_object = nil + re8vr.right_hand_ik_transform = nil + re8vr.left_hand_ik_transform = nil else - re8.right_hand_ik = hand_ik[1] - re8.left_hand_ik = hand_ik[2] - - if re8.right_hand_ik and re8.left_hand_ik then - re8.right_hand_ik_object = re8.right_hand_ik:get_field("TargetGameObject") - re8.left_hand_ik_object = re8.left_hand_ik:get_field("TargetGameObject") - re8.right_hand_ik_transform = re8.right_hand_ik:get_field("Target") - re8.left_hand_ik_transform = re8.left_hand_ik:get_field("Target") + re8vr.right_hand_ik = hand_ik[1] + re8vr.left_hand_ik = hand_ik[2] + + if re8vr.right_hand_ik and re8vr.left_hand_ik then + re8vr.right_hand_ik_object = re8vr.right_hand_ik:get_field("TargetGameObject") + re8vr.left_hand_ik_object = re8vr.left_hand_ik:get_field("TargetGameObject") + re8vr.right_hand_ik_transform = re8vr.right_hand_ik:get_field("Target") + re8vr.left_hand_ik_transform = re8vr.left_hand_ik:get_field("Target") end end end @@ -348,7 +357,7 @@ local function on_post_update_postural_camera_motion(retval) if is_re7 then local game_object = controller:call("get_GameObject") - if game_object ~= re8.player then + if game_object ~= re8vr.player then return retval end else @@ -360,7 +369,7 @@ local function on_post_update_postural_camera_motion(retval) local game_object = motion:call("get_GameObject") - if game_object ~= re8.player then + if game_object ~= re8vr.player then return retval end end From be7f3c37f5ff483b9c6380bf3b9cc5f112001123 Mon Sep 17 00:00:00 2001 From: praydog Date: Sun, 8 May 2022 18:04:41 -0700 Subject: [PATCH 33/45] VR (RE7/8): Migrate more to native code --- scripts/re8_vr.lua | 408 +++++++++++++++++++++++++++++++++++----- scripts/utility/RE8.lua | 35 ++-- 2 files changed, 377 insertions(+), 66 deletions(-) diff --git a/scripts/re8_vr.lua b/scripts/re8_vr.lua index 7957fd791..7b3dcf097 100644 --- a/scripts/re8_vr.lua +++ b/scripts/re8_vr.lua @@ -167,18 +167,18 @@ local vfx_muzzle1_hash = via_murmur_hash_calc32:call(nil, "vfx_muzzle1") local vfx_muzzle2_hash = via_murmur_hash_calc32:call(nil, "vfx_muzzle2") local function update_muzzle_data() - if re8.weapon then + if re8vr.weapon then -- for some reason calling get_muzzleJoint causes lua to randomly freak out -- so we're just going to directly grab the field instead - local muzzle_joint = re8.weapon:get_field("MuzzleJoint") + local muzzle_joint = re8vr.weapon:get_field("MuzzleJoint") if muzzle_joint == nil then local weapon_gameobject = nil if is_re7 then - weapon_gameobject = re8.weapon:call("get_GameObject") + weapon_gameobject = re8vr.weapon:call("get_GameObject") elseif is_re8 then - weapon_gameobject = re8.weapon:get_field("k__BackingField") + weapon_gameobject = re8vr.weapon:get_field("k__BackingField") end if weapon_gameobject ~= nil then @@ -357,15 +357,16 @@ local function update_pad_device(device) end]] end - if vrmod:is_action_active(action_heal, left_joystick) or vrmod:is_action_active(action_heal, right_joystick) then + if re8vr.wants_heal or vrmod:is_action_active(action_heal, left_joystick) or vrmod:is_action_active(action_heal, right_joystick) then cur_button = cur_button | via.hid.GamePadButton.RTrigTop + re8vr.wants_heal = false end re8vr.is_holding_left_grip = vrmod:is_action_active(action_grip, left_joystick) - if re8.wants_block or vrmod:is_action_active(action_block, left_joystick) or vrmod:is_action_active(action_block, right_joystick) then + if re8vr.wants_block or vrmod:is_action_active(action_block, left_joystick) or vrmod:is_action_active(action_block, right_joystick) then cur_button = cur_button | via.hid.GamePadButton.LTrigTop - re8.wants_block = true + re8vr.wants_block = true end if vrmod:is_action_active(action_a_button, right_joystick) then @@ -511,13 +512,13 @@ local function on_pre_try_guard_start(args) end -- this will only allow blocking by physically holding your hands up. - if not re8.wants_block then + if not re8vr.wants_block then return sdk.PreHookResult.SKIP_ORIGINAL end end local function on_post_try_guard_start(retval) - if not vrmod:is_hmd_active() or not vrmod:is_using_controllers() or re8.wants_block then + if not vrmod:is_hmd_active() or not vrmod:is_using_controllers() or re8vr.wants_block then return retval end @@ -588,7 +589,7 @@ local function on_pre_shoot(args) local weapon = sdk.to_managed_object(args[2]) -- this happens in RE7 with the turrets. - if weapon ~= re8.weapon then + if weapon ~= re8vr.weapon then return end @@ -625,7 +626,7 @@ local function on_pre_throwable_late_update(args) if not vrmod:is_hmd_active() or not vrmod:is_using_controllers() then return end local weapon = sdk.to_managed_object(args[2]) - if weapon ~= re8.weapon then return end + if weapon ~= re8vr.weapon then return end if os.clock() - last_throwable_update > 1.0 then throwable_was_right_grip_down = false @@ -654,11 +655,11 @@ local function on_pre_throwable_late_update(args) pcall(weapon.call, weapon, "throwWeapon", throw_ray) inside_throw = false - local inventory = re8.updater:get_field("References"):call("get_inventory") + local inventory = re8vr.updater:get_field("References"):call("get_inventory") -- Decrement the grenade count if threw_bomb and inventory ~= nil then - local work = re8.weapon:call("get_work") + local work = re8vr.weapon:call("get_work") if work ~= nil then inventory:call("reduceItem(app.ItemCore.InstanceWork, System.Int32, System.Boolean)", work, 1, false) @@ -1098,6 +1099,8 @@ local function fix_player_camera(player_camera) joint_set_position:call(camera_joint, camera_pos_pre_hmd) joint_set_rotation:call(camera_joint, camera_rot_pre_hmd * forward:to_quat()) + + --camera_rot = camera_rot_pre_hmd * forward:to_quat() end --last_gui_offset = last_gui_offset * (camera_rot:inverse() * camera_rot_pre_hmd) @@ -1401,11 +1404,31 @@ elseif is_re8 then ) end +local heal_gesture = { + --[[last_bottom_time = 0, + last_top_time = 0, + heal_bounds_lo = Vector3f.new(-0.2, 0.0, -0.2), + heal_bounds_hi = Vector3f.new(0.2, 0.1, 0.2)]] + was_grip_down = false, + was_trigger_down = false, + last_grip_weapon = nil, + last_grab_time = 0, +} + local function update_player_gestures() + re8vr:update_player_gestures() + + if true then + return + end + local player = re8vr.player if not player then - re8.wants_block = false + re8vr.wants_block = false + re8vr.wants_heal = false + heal_gesture.was_grip_down = false + heal_gesture.was_trigger_down = false return end @@ -1415,7 +1438,10 @@ local function update_player_gestures() local controllers = vrmod:get_controllers() if #controllers < 2 then - re8.wants_block = false + re8vr.wants_block = false + re8vr.wants_heal = false + heal_gesture.was_grip_down = false + heal_gesture.was_trigger_down = false return end @@ -1425,32 +1451,297 @@ local function update_player_gestures() local delta_to_left = left_hand[3] - hmd[3] local delta_to_right = right_hand[3] - hmd[3] + delta_to_left.w = 0 + delta_to_right.w = 0 local dir_to_left = delta_to_left:normalized() local dir_to_right = delta_to_right:normalized() local hmd_forward = hmd[2] + local flattened_forward = Vector3f.new(hmd_forward.x, 0, hmd_forward.z):normalized() - local left_hand_dot = math.abs(hmd_forward:dot(dir_to_left)) - local right_hand_dot = math.abs(hmd_forward:dot(dir_to_right)) + local right_hand_dot_flat_raw = flattened_forward:dot(dir_to_right) - local left_hand_in_front = left_hand_dot >= 0.8 - local right_hand_in_front = right_hand_dot >= 0.8 + local left_hand_dot_raw = hmd_forward:dot(dir_to_left) + local right_hand_dot_raw = hmd_forward:dot(dir_to_right) - local first_test = left_hand_in_front and right_hand_in_front + local left_hand_dot = math.abs(left_hand_dot_raw) + local right_hand_dot = math.abs(right_hand_dot_raw) - if not first_test then - re8.wants_block = false - return - end + local check_hands_up = function() + local left_hand_in_front = left_hand_dot >= 0.8 + local right_hand_in_front = right_hand_dot >= 0.8 + + local first_test = left_hand_in_front and right_hand_in_front + + if not first_test then + re8vr.wants_block = false + return + end + + -- now we need to check if the hands are facing up + local left_hand_up_dot = math.abs(hmd_forward:dot(left_hand[0])) + local right_hand_up_dot = math.abs(hmd_forward:dot(right_hand[0])) + + left_hand_up = left_hand_up_dot >= 0.5 + right_hand_up = right_hand_up_dot >= 0.5 + + re8vr.wants_block = left_hand_up and right_hand_up + end + + -- this one will check whether the user is + -- shaking their right hand over their left hand + -- to initiate a heal + local check_heal_gesture = function() + if re8vr.was_gripping_weapon or re8vr.is_reloading then + re8vr.wants_heal = false + heal_gesture.was_grip_down = false + heal_gesture.was_trigger_down = false + heal_gesture.last_grip_weapon = nil + return + end + + local right_hand_behind = right_hand_dot_flat_raw >= 0.2 + + --[[local left_hand_pos = re8vr.last_left_hand_position + local right_hand_pos = re8vr.last_right_hand_position + + -- we will have one intersection box near the hand + -- and then another above the hand + -- the user must shake their hands between these two boxes to initiate a heal + local bottom_start = left_hand_pos + heal_gesture.heal_bounds_lo + local bottom_end = left_hand_pos + heal_gesture.heal_bounds_hi + + --local top_start = left_hand_pos + Vector3f.new(0, heal_gesture.heal_bounds_hi.y + 0.1, 0) + heal_gesture.heal_bounds_lo + --local top_end = left_hand_pos + Vector3f.new(0, heal_gesture.heal_bounds_hi.y + 0.1, 0) + heal_gesture.heal_bounds_hi + + local now = os.clock() + local is_in_bottom_box = false + + -- check if right hand is within the bottom intersection box + if right_hand_pos.x >= bottom_start.x and right_hand_pos.x <= bottom_end.x + and right_hand_pos.y >= bottom_start.y and right_hand_pos.y <= bottom_end.y + and right_hand_pos.z >= bottom_start.z and right_hand_pos.z <= bottom_end.z then + heal_gesture.last_bottom_time = now + is_in_bottom_box = true + end]] + + -- check if right hand is within the top intersection box + --[[if right_hand_pos.x >= top_start.x and right_hand_pos.x <= top_end.x + and right_hand_pos.y >= top_start.y and right_hand_pos.y <= top_end.y + and right_hand_pos.z >= top_start.z and right_hand_pos.z <= top_end.z then + heal_gesture.last_top_time = now + end]] - -- now we need to check if the hands are facing up - local left_hand_up_dot = math.abs(hmd_forward:dot(left_hand[0])) - local right_hand_up_dot = math.abs(hmd_forward:dot(right_hand[0])) + --[[if now - heal_gesture.last_bottom_time > 0.1 then + re8vr.wants_heal = false + return + end]] + + --[[if now - heal_gesture.last_top_time > 0.5 then + re8vr.wants_heal = false + return + end]] + + local right_joystick = vrmod:get_right_joystick() + local action_trigger = vrmod:get_action_trigger() + local action_grip = vrmod:get_action_grip() + local is_trigger_down = vrmod:is_action_active(action_trigger, right_joystick) + local is_grip_down = vrmod:is_action_active(action_grip, right_joystick) + + --[[if is_b_button_down then + re8vr.wants_heal = true + end]] + + local items_list = is_re8 and re8vr.inventory:get_field("k__BackingField") + local weapon_change = is_re8 and re8vr.updater:call("get_playerWeaponChange") + local mesh_controller = is_re8 and re8vr.updater:call("get_playerMeshController") + + if is_re7 then + items_list = re8vr.inventory:get_field("_ItemList") + weapon_change = GameObject.get_component(re8vr.player, "app.PlayerWeaponChange") + mesh_controller = GameObject.get_component(re8vr.player, "app.PlayerMeshController") + end + + local now = os.clock() + + if items_list then + local items = items_list:get_field("mItems"):get_elements() + + for i, item in ipairs(items) do + local is_medicine = is_re8 and item:get_type_definition():is_a("app.MedicineCore") + + if is_re7 then + local item_internal = item:get_field("Item") + + if item_internal then + is_medicine = item_internal:get_field("ItemDataID"):find("Remedy") ~= nil + end + end + + if is_medicine then + local item_internal = is_re7 and item:get_field("Item") or item + local owner = is_re8 and item:get_field("k__BackingField") or item:get_field("Owner") + + if weapon_change and mesh_controller then + local current_mesh = mesh_controller:get_field("WeaponMesh") + local item_mesh = GameObject.get_component(owner, "via.render.Mesh") + local is_same_mesh = current_mesh == item_mesh + local owner_transform = owner:call("get_Transform") + + if current_mesh == nil then + heal_gesture.was_grip_down = false + heal_gesture.was_trigger_down = false + end + + -- just keep "switching" to it, fixes some bugs + --[[if (is_same_mesh and owner_transform:call("get_Parent") ~= re8.transform) then + vrmod:trigger_haptic_vibration(0.0, 0.1, 1, 5, vrmod:get_right_joystick()) + + if is_re8 then + weapon_change:call("equipOtherObject", owner) + item:call("setActive", true) + else + --weapon_change:call("removeWeapon") + --weapon_change:call("equipWeapon", item_internal, item_internal:get_field("k__BackingField")) + --item_internal:get_field("k__BackingField"):call("onEquip", re8vr.player, 0) + end + end]] - left_hand_up = left_hand_up_dot >= 0.5 - right_hand_up = right_hand_up_dot >= 0.5 + local dequip_item = function() + if is_re7 then + local equip_manager = GameObject.get_component(re8vr.player, "app.EquipManager") + if not equip_manager then return end - re8.wants_block = left_hand_up and right_hand_up + weapon_change:call("removeWeapon") + mesh_controller:call("onEquipWeaponChanged", nil, item_internal:get_field("k__BackingField")) + + local current_equipped_right = equip_manager:get_field("k__BackingField") + local item_weapon = item_internal:get_field("k__BackingField") + + if current_equipped_right == item_weapon then + if current_equipped_right ~= nil then + current_equipped_right:force_release() + end + + equip_manager:set_field("k__BackingField", nil) + end + else + local equip_manager = re8vr.updater:call("get_equipController") + if not equip_manager then return end + + weapon_change:call("removeWeaponWithNoAction") + + local current_equipped_right = equip_manager:get_field("k__BackingField") + + if current_equipped_right ~= nil then + current_equipped_right:force_release() + equip_manager:set_field("k__BackingField", nil) + end + end + end + + if not is_same_mesh then + if (right_hand_behind and not heal_gesture.was_grip_down and delta_to_right:length() <= 1.0) or (now - heal_gesture.last_grab_time) < 0.5 then + vrmod:trigger_haptic_vibration(0.0, 0.1, 1, 5, vrmod:get_right_joystick()) + + if is_grip_down then + if is_re8 then + local equip_manager = re8vr.updater:call("get_equipController") + + item:call("setActive", true) + weapon_change:call("removeWeaponWithNoAction") + + if equip_manager then + equip_manager:call("equipObject", owner) + end + + --weapon_change:call("equipOtherObject", owner) + + heal_gesture.last_grab_time = now + else + local equip_manager = GameObject.get_component(re8vr.player, "app.EquipManager") + local current_equipped_right = equip_manager:get_field("k__BackingField") + local item_weapon = item_internal:get_field("k__BackingField") + + weapon_change:call("removeWeapon") + equip_manager:call("equipWeapon(app.Weapon, app.CharacterDefine.Hand)", item_internal:get_field("k__BackingField"), 0) + weapon_change:call("equipWeapon", item_internal, item_weapon) + + if re8vr.weapon then + mesh_controller:call("onEquipWeaponChanged", item_weapon, re8vr.weapon) + end + + if current_equipped_right ~= item_weapon then + if current_equipped_right ~= nil then + current_equipped_right:force_release() + end + + equip_manager:set_field("k__BackingField", item_weapon:add_ref_permanent()) + end + + heal_gesture.last_grab_time = now + + --equip_manager:call("equipWeapon(app.Weapon, app.CharacterDefine.Hand)", item_internal:get_field("k__BackingField"), 0) + --mesh_controller:call("onEquipWeaponChanged", item_internal:get_field("k__BackingField"), re8vr.weapon) + --equip_manager:set_field("k__BackingField", item_internal:get_field("k__BackingField")) + --item_internal:get_field("k__BackingField"):call("onEquip", re8vr.player, 0) + end + + --owner_transform:set_rotation(re8vr.last_right_hand_rotation) + end + end + elseif is_trigger_down then + --re8vr.wants_heal = true + if is_re7 and not heal_gesture.was_trigger_down then + --item_internal:call("useItem", re8vr.player) + if weapon_change then + local item_weapon = item_internal:get_field("k__BackingField") + + dequip_item() + --weapon_change:call("requestUseItem", item_internal, true) + weapon_change:call("useItem", item_internal, item_weapon) + end + elseif is_re8 and not heal_gesture.was_trigger_down then + if weapon_change then + weapon_change:call("requestUseItem", item, false, false) + end + end + elseif not is_grip_down then + -- todo: restore old weapon? + if is_re7 and is_same_mesh then + --dequip_item() + weapon_change:call("removeWeapon") + mesh_controller:call("onEquipWeaponChanged", nil, item_internal:get_field("k__BackingField")) + elseif is_re8 and is_same_mesh then + weapon_change:call("removeWeaponWithNoAction") + item:call("setActive", false) + end + end + + -- if usingEffect is not null, the item is currently being used + if not is_trigger_down and item:get_field("usingEffect") == nil then + if not is_re7 then + owner_transform:call("set_LocalRotation", Quaternion.new(0.728, 0.409, 0.222, 0.504)) + end + end + else + log.info("no weapon change") + end + + break + end + end + else + log.info("no items") + end + + heal_gesture.was_grip_down = is_grip_down and heal_gesture.last_grip_weapon == re8vr.weapon + heal_gesture.was_trigger_down = is_trigger_down and heal_gesture.last_grip_weapon == re8vr.weapon + heal_gesture.last_grip_weapon = re8vr.weapon + end + + check_hands_up() + check_heal_gesture() --log.info("left hand dot: " .. tostring(left_hand_dot)) --log.info("right hand dot: " .. tostring(right_hand_dot)) @@ -1508,14 +1799,14 @@ local function melee_attack(hit_controller) if not vrmod:is_hmd_active() or not vrmod:is_using_controllers() then return end if re8vr.is_in_cutscene or not re8vr.can_use_hands then return end - if not re8.weapon then + if not re8vr.weapon then return end - local is_end_of_zoe_melee = is_re7 and re8.weapon:get_type_definition():is_a("app.CH9WeaponMelee") + local is_end_of_zoe_melee = is_re7 and re8vr.weapon:get_type_definition():is_a("app.CH9WeaponMelee") if not is_end_of_zoe_melee then - local real_hit_controller = re8.weapon:call("get_hitController") + local real_hit_controller = re8vr.weapon:call("get_hitController") if not real_hit_controller then return @@ -2069,6 +2360,24 @@ end) local debug_adjust_hand_offset = false local debug_hit_controller = false +local debug_hands = false + +re.on_frame(function() + if debug_hands and vrmod:is_using_controllers() then + local controllers = vrmod:get_controllers() + local left_index = controllers[1] + local right_index = controllers[2] + + local left_transform = re8vr.last_left_hand_rotation:to_mat4() + local right_transform = re8vr.last_right_hand_rotation:to_mat4() + + left_transform[3] = re8vr.last_left_hand_position + right_transform[3] = re8vr.last_right_hand_position + + draw.matrix44(left_transform) + draw.matrix44(right_transform) + end +end) re.on_draw_ui(function() local changed = false @@ -2100,6 +2409,7 @@ re.on_draw_ui(function() if imgui.tree_node("Debug") then changed, debug_adjust_hand_offset = imgui.checkbox("Adjust Hand Offset", debug_adjust_hand_offset) + changed, debug_hands = imgui.checkbox("Debug Hands", debug_hands) if debug_adjust_hand_offset then local left_axis = vrmod:get_left_stick_axis() @@ -2117,39 +2427,39 @@ re.on_draw_ui(function() -- adjust the rotation offset based on how the user is moving the controller if not is_right_trigger_active then if not is_right_grip_active then - right_hand_rotation_vec.x = right_hand_rotation_vec.x + (right_axis.y * 0.001) - right_hand_rotation_vec.y = right_hand_rotation_vec.y + (right_axis.x * 0.001) + re8vr.right_hand_rotation_vec.x = right_hand_rotation_vec.x + (right_axis.y * 0.001) + re8vr.right_hand_rotation_vec.y = right_hand_rotation_vec.y + (right_axis.x * 0.001) else - right_hand_rotation_vec.z = right_hand_rotation_vec.z + ((right_axis.y + right_axis.x) * 0.001) + re8vr.right_hand_rotation_vec.z = right_hand_rotation_vec.z + ((right_axis.y + right_axis.x) * 0.001) end else if not is_right_grip_active then - right_hand_position_offset.x = right_hand_position_offset.x + (right_axis.y * 0.001) - right_hand_position_offset.y = right_hand_position_offset.y + (right_axis.x * 0.001) + re8vr.right_hand_position_offset.x = right_hand_position_offset.x + (right_axis.y * 0.001) + re8vr.right_hand_position_offset.y = right_hand_position_offset.y + (right_axis.x * 0.001) else - right_hand_position_offset.z = right_hand_position_offset.z + ((right_axis.y + right_axis.x) * 0.001) + re8vr.right_hand_position_offset.z = right_hand_position_offset.z + ((right_axis.y + right_axis.x) * 0.001) end end - right_hand_rotation_offset = Quaternion.new(right_hand_rotation_vec):normalized() + re8vr.right_hand_rotation_offset = Quaternion.new(right_hand_rotation_vec):normalized() if not is_left_trigger_active then if not is_left_grip_active then - left_hand_rotation_vec.x = left_hand_rotation_vec.x + (left_axis.y * 0.001) - left_hand_rotation_vec.y = left_hand_rotation_vec.y + (left_axis.x * 0.001) + re8vr.left_hand_rotation_vec.x = left_hand_rotation_vec.x + (left_axis.y * 0.001) + re8vr.left_hand_rotation_vec.y = left_hand_rotation_vec.y + (left_axis.x * 0.001) else - left_hand_rotation_vec.z = left_hand_rotation_vec.z + ((left_axis.y + left_axis.x) * 0.001) + re8vr.left_hand_rotation_vec.z = left_hand_rotation_vec.z + ((left_axis.y + left_axis.x) * 0.001) end else if not is_left_grip_active then - left_hand_position_offset.x = left_hand_position_offset.x + (left_axis.y * 0.001) - left_hand_position_offset.y = left_hand_position_offset.y + (left_axis.x * 0.001) + re8vr.left_hand_position_offset.x = left_hand_position_offset.x + (left_axis.y * 0.001) + re8vr.left_hand_position_offset.y = left_hand_position_offset.y + (left_axis.x * 0.001) else - left_hand_position_offset.z = left_hand_position_offset.z + ((left_axis.y + left_axis.x) * 0.001) + re8vr.left_hand_position_offset.z = left_hand_position_offset.z + ((left_axis.y + left_axis.x) * 0.001) end end - left_hand_rotation_offset = Quaternion.new(left_hand_rotation_vec):normalized() + re8vr.left_hand_rotation_offset = Quaternion.new(left_hand_rotation_vec):normalized() end imgui.text("Last GUI Dot: " .. tostring(last_gui_dot)) @@ -2177,7 +2487,7 @@ re.on_draw_ui(function() end if imgui.tree_node("Inventory") then - object_explorer:handle_address(re8.inventory) + object_explorer:handle_address(re8vr.inventory) imgui.tree_pop() end @@ -2199,7 +2509,7 @@ re.on_draw_ui(function() end if imgui.tree_node("Weapon") then - local weapon = re8.weapon + local weapon = re8vr.weapon object_explorer:handle_address(weapon) diff --git a/scripts/utility/RE8.lua b/scripts/utility/RE8.lua index 134a390b2..68973338a 100644 --- a/scripts/utility/RE8.lua +++ b/scripts/utility/RE8.lua @@ -62,9 +62,9 @@ local function initialize_re8(re8) re8vr.player = nil re8.transform = nil - re8.weapon = nil + re8vr.weapon = nil re8.left_weapon = nil - re8.inventory = nil + re8vr.inventory = nil re8.hand_touch = nil re8.order = nil re8vr.right_hand_ik = nil @@ -78,12 +78,13 @@ local function initialize_re8(re8) re8vr.is_reloading = false re8.has_postural_camera_control = true re8vr.can_use_hands = true - re8.updater = nil + re8vr.updater = nil re8.status = nil re8.event_action_controller = nil re8.game_event_action_controller = nil re8.hit_controller = nil - re8.wants_block = false + re8vr.wants_block = false + re8vr.wants_heal = false re8.movement_speed_rate = 0.0 re8.movement_speed_vector = Vector3f.new(0, 0, 0) re8.num_active_tasks = 0 @@ -148,11 +149,11 @@ function re8.get_weapon_object(player) return equip_manager:call("get_equipWeaponRight"), equip_manager:call("get_equipWeaponLeft") elseif is_re8 then - if not re8.updater then + if not re8vr.updater then return nil end - local player_gun = re8.updater:call("get_playerGun") + local player_gun = re8vr.updater:call("get_playerGun") if not player_gun then return nil @@ -187,28 +188,28 @@ re.on_pre_application_entry("UpdateBehavior", function() re8.transform = player:call("get_Transform") re8.hand_touch = get_component(player, "app.PlayerHandTouch") re8.order = get_component(player, "app.PlayerOrder") - re8.updater = get_component(player, "app.PlayerUpdater") + re8vr.updater = get_component(player, "app.PlayerUpdater") if is_re7 then - re8.inventory = get_component(player, "app.Inventory") - elseif re8.updater ~= nil then - local container = re8.updater:get_field("playerContainer") + re8vr.inventory = get_component(player, "app.Inventory") + elseif re8vr.updater ~= nil then + local container = re8vr.updater:get_field("playerContainer") if container then - re8.inventory = container:call("get_inventory") + re8vr.inventory = container:call("get_inventory") else - re8.inventory = nil + re8vr.inventory = nil end else - re8.inventory = nil + re8vr.inventory = nil end re8.delta_time = sdk.call_native_func(re8.application, re8.application_type, "get_DeltaTime") if is_re7 then re8.status = get_component(player, "app.PlayerStatus") - elseif re8.updater ~= nil then - re8.status = re8.updater:call("get_playerstatus") + elseif re8vr.updater ~= nil then + re8.status = re8vr.updater:call("get_playerstatus") end if re8.status ~= nil then @@ -263,12 +264,12 @@ re.on_pre_application_entry("UpdateBehavior", function() local weapon, left_weapon = re8.get_weapon_object(player) if weapon == nil then - re8.weapon = nil + re8vr.weapon = nil re8.left_weapon = nil return end - re8.weapon = weapon + re8vr.weapon = weapon re8.left_weapon = left_weapon if is_re7 then From 42a23bc70b9f453abad567277083f5dda92cd04e Mon Sep 17 00:00:00 2001 From: praydog Date: Sun, 8 May 2022 20:10:02 -0700 Subject: [PATCH 34/45] VR (RE7/8): Remove some unused code --- scripts/re8_vr.lua | 328 --------------------------------------------- 1 file changed, 328 deletions(-) diff --git a/scripts/re8_vr.lua b/scripts/re8_vr.lua index 7b3dcf097..73495600a 100644 --- a/scripts/re8_vr.lua +++ b/scripts/re8_vr.lua @@ -1417,334 +1417,6 @@ local heal_gesture = { local function update_player_gestures() re8vr:update_player_gestures() - - if true then - return - end - - local player = re8vr.player - - if not player then - re8vr.wants_block = false - re8vr.wants_heal = false - heal_gesture.was_grip_down = false - heal_gesture.was_trigger_down = false - return - end - - local right_hand_up = false - local left_hand_up = false - - - local controllers = vrmod:get_controllers() - if #controllers < 2 then - re8vr.wants_block = false - re8vr.wants_heal = false - heal_gesture.was_grip_down = false - heal_gesture.was_trigger_down = false - return - end - - local hmd = vrmod:get_transform(0) - local left_hand = vrmod:get_transform(controllers[1]) - local right_hand = vrmod:get_transform(controllers[2]) - - local delta_to_left = left_hand[3] - hmd[3] - local delta_to_right = right_hand[3] - hmd[3] - delta_to_left.w = 0 - delta_to_right.w = 0 - local dir_to_left = delta_to_left:normalized() - local dir_to_right = delta_to_right:normalized() - - local hmd_forward = hmd[2] - local flattened_forward = Vector3f.new(hmd_forward.x, 0, hmd_forward.z):normalized() - - local right_hand_dot_flat_raw = flattened_forward:dot(dir_to_right) - - local left_hand_dot_raw = hmd_forward:dot(dir_to_left) - local right_hand_dot_raw = hmd_forward:dot(dir_to_right) - - local left_hand_dot = math.abs(left_hand_dot_raw) - local right_hand_dot = math.abs(right_hand_dot_raw) - - local check_hands_up = function() - local left_hand_in_front = left_hand_dot >= 0.8 - local right_hand_in_front = right_hand_dot >= 0.8 - - local first_test = left_hand_in_front and right_hand_in_front - - if not first_test then - re8vr.wants_block = false - return - end - - -- now we need to check if the hands are facing up - local left_hand_up_dot = math.abs(hmd_forward:dot(left_hand[0])) - local right_hand_up_dot = math.abs(hmd_forward:dot(right_hand[0])) - - left_hand_up = left_hand_up_dot >= 0.5 - right_hand_up = right_hand_up_dot >= 0.5 - - re8vr.wants_block = left_hand_up and right_hand_up - end - - -- this one will check whether the user is - -- shaking their right hand over their left hand - -- to initiate a heal - local check_heal_gesture = function() - if re8vr.was_gripping_weapon or re8vr.is_reloading then - re8vr.wants_heal = false - heal_gesture.was_grip_down = false - heal_gesture.was_trigger_down = false - heal_gesture.last_grip_weapon = nil - return - end - - local right_hand_behind = right_hand_dot_flat_raw >= 0.2 - - --[[local left_hand_pos = re8vr.last_left_hand_position - local right_hand_pos = re8vr.last_right_hand_position - - -- we will have one intersection box near the hand - -- and then another above the hand - -- the user must shake their hands between these two boxes to initiate a heal - local bottom_start = left_hand_pos + heal_gesture.heal_bounds_lo - local bottom_end = left_hand_pos + heal_gesture.heal_bounds_hi - - --local top_start = left_hand_pos + Vector3f.new(0, heal_gesture.heal_bounds_hi.y + 0.1, 0) + heal_gesture.heal_bounds_lo - --local top_end = left_hand_pos + Vector3f.new(0, heal_gesture.heal_bounds_hi.y + 0.1, 0) + heal_gesture.heal_bounds_hi - - local now = os.clock() - local is_in_bottom_box = false - - -- check if right hand is within the bottom intersection box - if right_hand_pos.x >= bottom_start.x and right_hand_pos.x <= bottom_end.x - and right_hand_pos.y >= bottom_start.y and right_hand_pos.y <= bottom_end.y - and right_hand_pos.z >= bottom_start.z and right_hand_pos.z <= bottom_end.z then - heal_gesture.last_bottom_time = now - is_in_bottom_box = true - end]] - - -- check if right hand is within the top intersection box - --[[if right_hand_pos.x >= top_start.x and right_hand_pos.x <= top_end.x - and right_hand_pos.y >= top_start.y and right_hand_pos.y <= top_end.y - and right_hand_pos.z >= top_start.z and right_hand_pos.z <= top_end.z then - heal_gesture.last_top_time = now - end]] - - --[[if now - heal_gesture.last_bottom_time > 0.1 then - re8vr.wants_heal = false - return - end]] - - --[[if now - heal_gesture.last_top_time > 0.5 then - re8vr.wants_heal = false - return - end]] - - local right_joystick = vrmod:get_right_joystick() - local action_trigger = vrmod:get_action_trigger() - local action_grip = vrmod:get_action_grip() - local is_trigger_down = vrmod:is_action_active(action_trigger, right_joystick) - local is_grip_down = vrmod:is_action_active(action_grip, right_joystick) - - --[[if is_b_button_down then - re8vr.wants_heal = true - end]] - - local items_list = is_re8 and re8vr.inventory:get_field("k__BackingField") - local weapon_change = is_re8 and re8vr.updater:call("get_playerWeaponChange") - local mesh_controller = is_re8 and re8vr.updater:call("get_playerMeshController") - - if is_re7 then - items_list = re8vr.inventory:get_field("_ItemList") - weapon_change = GameObject.get_component(re8vr.player, "app.PlayerWeaponChange") - mesh_controller = GameObject.get_component(re8vr.player, "app.PlayerMeshController") - end - - local now = os.clock() - - if items_list then - local items = items_list:get_field("mItems"):get_elements() - - for i, item in ipairs(items) do - local is_medicine = is_re8 and item:get_type_definition():is_a("app.MedicineCore") - - if is_re7 then - local item_internal = item:get_field("Item") - - if item_internal then - is_medicine = item_internal:get_field("ItemDataID"):find("Remedy") ~= nil - end - end - - if is_medicine then - local item_internal = is_re7 and item:get_field("Item") or item - local owner = is_re8 and item:get_field("k__BackingField") or item:get_field("Owner") - - if weapon_change and mesh_controller then - local current_mesh = mesh_controller:get_field("WeaponMesh") - local item_mesh = GameObject.get_component(owner, "via.render.Mesh") - local is_same_mesh = current_mesh == item_mesh - local owner_transform = owner:call("get_Transform") - - if current_mesh == nil then - heal_gesture.was_grip_down = false - heal_gesture.was_trigger_down = false - end - - -- just keep "switching" to it, fixes some bugs - --[[if (is_same_mesh and owner_transform:call("get_Parent") ~= re8.transform) then - vrmod:trigger_haptic_vibration(0.0, 0.1, 1, 5, vrmod:get_right_joystick()) - - if is_re8 then - weapon_change:call("equipOtherObject", owner) - item:call("setActive", true) - else - --weapon_change:call("removeWeapon") - --weapon_change:call("equipWeapon", item_internal, item_internal:get_field("k__BackingField")) - --item_internal:get_field("k__BackingField"):call("onEquip", re8vr.player, 0) - end - end]] - - local dequip_item = function() - if is_re7 then - local equip_manager = GameObject.get_component(re8vr.player, "app.EquipManager") - if not equip_manager then return end - - weapon_change:call("removeWeapon") - mesh_controller:call("onEquipWeaponChanged", nil, item_internal:get_field("k__BackingField")) - - local current_equipped_right = equip_manager:get_field("k__BackingField") - local item_weapon = item_internal:get_field("k__BackingField") - - if current_equipped_right == item_weapon then - if current_equipped_right ~= nil then - current_equipped_right:force_release() - end - - equip_manager:set_field("k__BackingField", nil) - end - else - local equip_manager = re8vr.updater:call("get_equipController") - if not equip_manager then return end - - weapon_change:call("removeWeaponWithNoAction") - - local current_equipped_right = equip_manager:get_field("k__BackingField") - - if current_equipped_right ~= nil then - current_equipped_right:force_release() - equip_manager:set_field("k__BackingField", nil) - end - end - end - - if not is_same_mesh then - if (right_hand_behind and not heal_gesture.was_grip_down and delta_to_right:length() <= 1.0) or (now - heal_gesture.last_grab_time) < 0.5 then - vrmod:trigger_haptic_vibration(0.0, 0.1, 1, 5, vrmod:get_right_joystick()) - - if is_grip_down then - if is_re8 then - local equip_manager = re8vr.updater:call("get_equipController") - - item:call("setActive", true) - weapon_change:call("removeWeaponWithNoAction") - - if equip_manager then - equip_manager:call("equipObject", owner) - end - - --weapon_change:call("equipOtherObject", owner) - - heal_gesture.last_grab_time = now - else - local equip_manager = GameObject.get_component(re8vr.player, "app.EquipManager") - local current_equipped_right = equip_manager:get_field("k__BackingField") - local item_weapon = item_internal:get_field("k__BackingField") - - weapon_change:call("removeWeapon") - equip_manager:call("equipWeapon(app.Weapon, app.CharacterDefine.Hand)", item_internal:get_field("k__BackingField"), 0) - weapon_change:call("equipWeapon", item_internal, item_weapon) - - if re8vr.weapon then - mesh_controller:call("onEquipWeaponChanged", item_weapon, re8vr.weapon) - end - - if current_equipped_right ~= item_weapon then - if current_equipped_right ~= nil then - current_equipped_right:force_release() - end - - equip_manager:set_field("k__BackingField", item_weapon:add_ref_permanent()) - end - - heal_gesture.last_grab_time = now - - --equip_manager:call("equipWeapon(app.Weapon, app.CharacterDefine.Hand)", item_internal:get_field("k__BackingField"), 0) - --mesh_controller:call("onEquipWeaponChanged", item_internal:get_field("k__BackingField"), re8vr.weapon) - --equip_manager:set_field("k__BackingField", item_internal:get_field("k__BackingField")) - --item_internal:get_field("k__BackingField"):call("onEquip", re8vr.player, 0) - end - - --owner_transform:set_rotation(re8vr.last_right_hand_rotation) - end - end - elseif is_trigger_down then - --re8vr.wants_heal = true - if is_re7 and not heal_gesture.was_trigger_down then - --item_internal:call("useItem", re8vr.player) - if weapon_change then - local item_weapon = item_internal:get_field("k__BackingField") - - dequip_item() - --weapon_change:call("requestUseItem", item_internal, true) - weapon_change:call("useItem", item_internal, item_weapon) - end - elseif is_re8 and not heal_gesture.was_trigger_down then - if weapon_change then - weapon_change:call("requestUseItem", item, false, false) - end - end - elseif not is_grip_down then - -- todo: restore old weapon? - if is_re7 and is_same_mesh then - --dequip_item() - weapon_change:call("removeWeapon") - mesh_controller:call("onEquipWeaponChanged", nil, item_internal:get_field("k__BackingField")) - elseif is_re8 and is_same_mesh then - weapon_change:call("removeWeaponWithNoAction") - item:call("setActive", false) - end - end - - -- if usingEffect is not null, the item is currently being used - if not is_trigger_down and item:get_field("usingEffect") == nil then - if not is_re7 then - owner_transform:call("set_LocalRotation", Quaternion.new(0.728, 0.409, 0.222, 0.504)) - end - end - else - log.info("no weapon change") - end - - break - end - end - else - log.info("no items") - end - - heal_gesture.was_grip_down = is_grip_down and heal_gesture.last_grip_weapon == re8vr.weapon - heal_gesture.was_trigger_down = is_trigger_down and heal_gesture.last_grip_weapon == re8vr.weapon - heal_gesture.last_grip_weapon = re8vr.weapon - end - - check_hands_up() - check_heal_gesture() - - --log.info("left hand dot: " .. tostring(left_hand_dot)) - --log.info("right hand dot: " .. tostring(right_hand_dot)) end local should_reset_view_no_player = false From fac8fc424b71fdeea34608b76bf919bb4239bdcc Mon Sep 17 00:00:00 2001 From: praydog Date: Mon, 9 May 2022 01:42:17 -0700 Subject: [PATCH 35/45] VR (RE7/8): Migrate more to native code again --- scripts/re8_vr.lua | 41 +++------- scripts/utility/RE8.lua | 173 ++++------------------------------------ 2 files changed, 28 insertions(+), 186 deletions(-) diff --git a/scripts/re8_vr.lua b/scripts/re8_vr.lua index 73495600a..905980327 100644 --- a/scripts/re8_vr.lua +++ b/scripts/re8_vr.lua @@ -107,6 +107,7 @@ local cfg = { all_camera_shake = true, disable_crosshair = false, no_melee_cooldown = false, + roomscale_movement = true, } local function load_cfg() @@ -935,7 +936,7 @@ local function slerp_gui(new_gui_quat) last_gui_forced_slerp = now end - last_gui_quat = last_gui_quat:slerp(new_gui_quat, dot_dist * math.max((GUI_MAX_SLERP_TIME - slerp_time_diff) * re8.delta_time, 0.0)) + last_gui_quat = last_gui_quat:slerp(new_gui_quat, dot_dist * math.max((GUI_MAX_SLERP_TIME - slerp_time_diff) * re8vr.delta_time, 0.0)) end if re8vr.is_in_cutscene then @@ -1404,17 +1405,6 @@ elseif is_re8 then ) end -local heal_gesture = { - --[[last_bottom_time = 0, - last_top_time = 0, - heal_bounds_lo = Vector3f.new(-0.2, 0.0, -0.2), - heal_bounds_hi = Vector3f.new(0.2, 0.1, 0.2)]] - was_grip_down = false, - was_trigger_down = false, - last_grip_weapon = nil, - last_grab_time = 0, -} - local function update_player_gestures() re8vr:update_player_gestures() end @@ -1489,7 +1479,7 @@ local function melee_attack(hit_controller) return end else - if re8.hit_controller ~= hit_controller then + if re8vr.hit_controller ~= hit_controller then return end end @@ -1737,8 +1727,8 @@ re.on_pre_application_entry("UnlockScene", function() last_camera_matrix = vrmod:get_last_render_matrix() - if not re8vr.player or not re8.transform then last_roomscale_failure = os.clock() return end - if not re8.status then last_roomscale_failure = os.clock() return end -- in the main menu or something. + if not re8vr.player or not re8vr.transform then last_roomscale_failure = os.clock() return end + if not re8vr.status then last_roomscale_failure = os.clock() return end -- in the main menu or something. if not last_camera_matrix then last_roomscale_failure = os.clock() return end if re8vr.is_in_cutscene then last_roomscale_failure = os.clock() return end @@ -1750,7 +1740,7 @@ re.on_pre_application_entry("UnlockScene", function() hmd_pos.y = 0.0 standing_origin.y = 0.0 - if (hmd_pos - standing_origin):length() >= 0.01 then + if (hmd_pos - standing_origin):length() >= 0.01 and cfg.roomscale_movement then standing_origin = vrmod:get_standing_origin() hmd_pos.y = standing_origin.y @@ -1762,7 +1752,7 @@ re.on_pre_application_entry("UnlockScene", function() vrmod:set_standing_origin(standing_origin) - local player_pos = transform_get_position:call(re8.transform) + local player_pos = transform_get_position:call(re8vr.transform) local lerp_to = Vector3f.new(last_camera_matrix[3].x, player_pos.y, last_camera_matrix[3].z) player_pos = player_pos + ((lerp_to - player_pos):normalized() * standing_diff:length()) @@ -1770,8 +1760,8 @@ re.on_pre_application_entry("UnlockScene", function() --player_pos.x = last_camera_matrix[3].x --player_pos.z = last_camera_matrix[3].z - --transform_set_position:call(re8.transform, player_pos) - re8.transform:set_position(player_pos, true) -- NO DIRTY + --transform_set_position:call(re8vr.transform, player_pos) + re8vr.transform:set_position(player_pos, true) -- NO DIRTY end end) @@ -2057,6 +2047,7 @@ re.on_draw_ui(function() changed, cfg.movement_shake = imgui.checkbox("Movement Shake", cfg.movement_shake) changed, cfg.all_camera_shake = imgui.checkbox("All Other Camera Shakes", cfg.all_camera_shake) changed, cfg.disable_crosshair = imgui.checkbox("Disable Crosshair", cfg.disable_crosshair) + changed, cfg.roomscale_movement = imgui.checkbox("Roomscale Movement", cfg.roomscale_movement) if imgui.tree_node("Cheats") then changed, cfg.no_melee_cooldown = imgui.checkbox("No Melee Cooldown", cfg.no_melee_cooldown) @@ -2188,16 +2179,8 @@ re.on_draw_ui(function() imgui.tree_pop() end - if imgui.tree_node("Left Weapon") then - local left_weapon = re8.left_weapon - - object_explorer:handle_address(left_weapon) - - imgui.tree_pop() - end - if imgui.tree_node("Hit Controller") then - local hit_controller = re8.hit_controller + local hit_controller = re8vr.hit_controller changed, debug_hit_controller = imgui.checkbox("Debug hit controller", debug_hit_controller) @@ -2280,7 +2263,7 @@ re.on_draw_ui(function() imgui.text("Num tasks: " .. tostring(re8.num_active_tasks)) imgui.text("Has postural camera control: " .. tostring(re8.has_postural_camera_control)) imgui.text("Is arm jacked: " .. tostring(re8.is_arm_jacked)) - imgui.text("Is motion play: " .. tostring(re8.is_motion_play)) + imgui.text("Is motion play: " .. tostring(re8vr.is_motion_play)) imgui.text("Is in cutscene: " .. tostring(re8vr.is_in_cutscene)) imgui.text("Can use hands: " .. tostring(re8vr.can_use_hands)) diff --git a/scripts/utility/RE8.lua b/scripts/utility/RE8.lua index 68973338a..d8cdf6604 100644 --- a/scripts/utility/RE8.lua +++ b/scripts/utility/RE8.lua @@ -61,12 +61,11 @@ local function initialize_re8(re8) re8 = re8 or {} re8vr.player = nil - re8.transform = nil + re8vr.transform = nil re8vr.weapon = nil - re8.left_weapon = nil re8vr.inventory = nil - re8.hand_touch = nil - re8.order = nil + re8vr.hand_touch = nil + re8vr.order = nil re8vr.right_hand_ik = nil re8vr.left_hand_ik = nil re8vr.right_hand_ik_transform = nil @@ -74,15 +73,15 @@ local function initialize_re8(re8) re8vr.is_in_cutscene = false re8.is_arm_jacked = false re8vr.is_grapple_aim = false - re8.is_motion_play = false + re8vr.is_motion_play = false re8vr.is_reloading = false re8.has_postural_camera_control = true re8vr.can_use_hands = true re8vr.updater = nil - re8.status = nil - re8.event_action_controller = nil - re8.game_event_action_controller = nil - re8.hit_controller = nil + re8vr.status = nil + re8vr.event_action_controller = nil + re8vr.game_event_action_controller = nil + re8vr.hit_controller = nil re8vr.wants_block = false re8vr.wants_heal = false re8.movement_speed_rate = 0.0 @@ -91,7 +90,7 @@ local function initialize_re8(re8) re8.active_tasks = {} re8.application = sdk.get_native_singleton("via.Application") re8.application_type = sdk.find_type_definition("via.Application") - re8.delta_time = 0.0 + re8vr.delta_time = 0.0 return re8 end @@ -117,165 +116,25 @@ local function get_component(game_object, type_name) return game_object:call("getComponent(System.Type)", t) end -if is_re7 then - re8.get_localplayer = function() - local object_man = sdk.get_managed_singleton("app.ObjectManager") - - if not object_man then - return nil - end - - return object_man:get_field("PlayerObj") - end -elseif is_re8 then - re8.get_localplayer = function() - local propsman = sdk.get_managed_singleton("app.PropsManager") - - if not propsman then - return nil - end - - return propsman:get_field("k__BackingField") - end +function re8.get_localplayer() + return re8vr:get_localplayer() end function re8.get_weapon_object(player) - if is_re7 then - local equip_manager = get_component(player, "app.EquipManager") - - if not equip_manager then - return nil - end - - return equip_manager:call("get_equipWeaponRight"), equip_manager:call("get_equipWeaponLeft") - elseif is_re8 then - if not re8vr.updater then - return nil - end - - local player_gun = re8vr.updater:call("get_playerGun") - - if not player_gun then - return nil - end - - local equipped_weapon = player_gun:call("get_equipWeaponObject") - - if not equipped_weapon then - return nil - end - - return equipped_weapon - end - - return nil + return re8vr:get_weapon_object(player) end function re8.update_in_cutscene_state() - re8vr.is_in_cutscene = re8.num_active_tasks > 0 or not re8.has_postural_camera_control or re8.is_arm_jacked or re8.is_motion_play - re8vr.can_use_hands = not re8.is_arm_jacked and not re8.is_motion_play + re8vr.is_in_cutscene = re8.num_active_tasks > 0 or not re8.has_postural_camera_control or re8.is_arm_jacked or re8vr.is_motion_play + re8vr.can_use_hands = not re8.is_arm_jacked and not re8vr.is_motion_play end re.on_pre_application_entry("UpdateBehavior", function() - re8vr.player = re8.get_localplayer() - local player = re8vr.player - - if player == nil or not re8.application then + if not re8vr:update_pointers() or not re8.application then initialize_re8(re8) return end - re8.transform = player:call("get_Transform") - re8.hand_touch = get_component(player, "app.PlayerHandTouch") - re8.order = get_component(player, "app.PlayerOrder") - re8vr.updater = get_component(player, "app.PlayerUpdater") - - if is_re7 then - re8vr.inventory = get_component(player, "app.Inventory") - elseif re8vr.updater ~= nil then - local container = re8vr.updater:get_field("playerContainer") - - if container then - re8vr.inventory = container:call("get_inventory") - else - re8vr.inventory = nil - end - else - re8vr.inventory = nil - end - - re8.delta_time = sdk.call_native_func(re8.application, re8.application_type, "get_DeltaTime") - - if is_re7 then - re8.status = get_component(player, "app.PlayerStatus") - elseif re8vr.updater ~= nil then - re8.status = re8vr.updater:call("get_playerstatus") - end - - if re8.status ~= nil then - re8vr.is_reloading = re8.status:call("get_isReload") - re8vr.is_reloading = re8vr.is_reloading - end - - if re8.order ~= nil then - re8vr.is_grapple_aim = re8.order:get_field("IsGrappleAimEnable") - end - - if re8.hand_touch == nil then - re8vr.right_hand_ik = nil - re8vr.left_hand_ik = nil - re8vr.right_hand_ik_object = nil - re8vr.left_hand_ik_object = nil - re8vr.right_hand_ik_transform = nil - re8vr.left_hand_ik_transform = nil - else - local hand_ik = re8.hand_touch:get_field("HandIK"):get_elements() - - if #hand_ik < 2 then - log.info("no hand ik") - re8vr.right_hand_ik = nil - re8vr.left_hand_ik = nil - re8vr.right_hand_ik_object = nil - re8vr.left_hand_ik_object = nil - re8vr.right_hand_ik_transform = nil - re8vr.left_hand_ik_transform = nil - else - re8vr.right_hand_ik = hand_ik[1] - re8vr.left_hand_ik = hand_ik[2] - - if re8vr.right_hand_ik and re8vr.left_hand_ik then - re8vr.right_hand_ik_object = re8vr.right_hand_ik:get_field("TargetGameObject") - re8vr.left_hand_ik_object = re8vr.left_hand_ik:get_field("TargetGameObject") - re8vr.right_hand_ik_transform = re8vr.right_hand_ik:get_field("Target") - re8vr.left_hand_ik_transform = re8vr.left_hand_ik:get_field("Target") - end - end - end - - re8.event_action_controller = get_component(player, "app.EventActionController") - re8.game_event_action_controller = get_component(player, "app.GameEventActionController") - - if is_re8 and re8.game_event_action_controller ~= nil then - re8.is_motion_play = re8.game_event_action_controller:get_field("_isMotionPlay") - else - re8.is_motion_play = false - end - - local weapon, left_weapon = re8.get_weapon_object(player) - - if weapon == nil then - re8vr.weapon = nil - re8.left_weapon = nil - return - end - - re8vr.weapon = weapon - re8.left_weapon = left_weapon - - if is_re7 then - re8.hit_controller = get_component(player, "app.Collision.HitController") - end - re8.update_in_cutscene_state() end) @@ -283,7 +142,7 @@ local event_action_controller_type = sdk.find_type_definition("app.EventActionCo local request_task_method = event_action_controller_type:get_method("requestTask") local function on_pre_event_request_task(args) - if re8.event_action_controller == nil or sdk.to_ptr(args[2]) == nil or sdk.to_int64(args[2]) ~= re8.event_action_controller:get_address() then + if re8vr.event_action_controller == nil or sdk.to_ptr(args[2]) == nil or sdk.to_int64(args[2]) ~= re8vr.event_action_controller:get_address() then return sdk.PreHookResult.CALL_ORIGINAL end From 305f98d9d41dedc04d03d8790790cb000e1c3822 Mon Sep 17 00:00:00 2001 From: praydog Date: Tue, 10 May 2022 21:44:55 -0700 Subject: [PATCH 36/45] VR (RE7): Fix motion controls in RE7 demo --- scripts/re8_vr.lua | 30 +++++++++++++++++++----------- scripts/utility/RE8.lua | 33 +++++++++++++++++++++++---------- 2 files changed, 42 insertions(+), 21 deletions(-) diff --git a/scripts/re8_vr.lua b/scripts/re8_vr.lua index 905980327..d7c86da99 100644 --- a/scripts/re8_vr.lua +++ b/scripts/re8_vr.lua @@ -104,7 +104,7 @@ local neg_forward_identity = Matrix4x4f.new(-1, 0, 0, 0, local cfg = { movement_shake = false, - all_camera_shake = true, + all_camera_shake = false, disable_crosshair = false, no_melee_cooldown = false, roomscale_movement = true, @@ -1316,19 +1316,27 @@ sdk.hook( ) if is_re7 then + local ch8pcam = sdk.find_type_definition("app.CH8PlayerCamera") + -- Not a hero camera - sdk.hook( - sdk.find_type_definition("app.CH8PlayerCamera"):get_method("lateUpdate"), - on_pre_player_camera_update, - on_post_player_camera_update - ) + if ch8pcam ~= nil then + sdk.hook( + ch8pcam:get_method("lateUpdate"), + on_pre_player_camera_update, + on_post_player_camera_update + ) + end + + local ch9pcam = sdk.find_type_definition("app.CH9PlayerCamera") -- idk the other DLC? - sdk.hook( - sdk.find_type_definition("app.CH9PlayerCamera"):get_method("lateUpdate"), - on_pre_player_camera_update, - on_post_player_camera_update - ) + if ch9pcam ~= nil then + sdk.hook( + ch9pcam:get_method("lateUpdate"), + on_pre_player_camera_update, + on_post_player_camera_update + ) + end end -- Zero out the camera shake diff --git a/scripts/utility/RE8.lua b/scripts/utility/RE8.lua index d8cdf6604..cbccf3926 100644 --- a/scripts/utility/RE8.lua +++ b/scripts/utility/RE8.lua @@ -249,14 +249,20 @@ sdk.hook(update_postural_camera_motion_method, on_pre_update_postural_camera_mot if is_re7 then local ch8_player_motion_controller_type = sdk.find_type_definition("app.CH8PlayerMotionController") - local ch8_update_postural_camera_motion_method = ch8_player_motion_controller_type:get_method("updatePosturalCameraMotion") local ch9_player_motion_controller_type = sdk.find_type_definition("app.CH9PlayerMotionController") - local ch9_update_postural_camera_motion_method = ch9_player_motion_controller_type:get_method("updatePosturalCameraMotion") - -- chris - sdk.hook(ch8_update_postural_camera_motion_method, on_pre_update_postural_camera_motion, on_post_update_postural_camera_motion) - -- ch9 (end of zoe?) - sdk.hook(ch9_update_postural_camera_motion_method, on_pre_update_postural_camera_motion, on_post_update_postural_camera_motion) + if ch8_player_motion_controller_type then + local ch8_update_postural_camera_motion_method = ch8_player_motion_controller_type:get_method("updatePosturalCameraMotion") + -- chris + sdk.hook(ch8_update_postural_camera_motion_method, on_pre_update_postural_camera_motion, on_post_update_postural_camera_motion) + end + + if ch9_player_motion_controller_type ~= nil then + local ch9_update_postural_camera_motion_method = ch9_player_motion_controller_type:get_method("updatePosturalCameraMotion") + + -- ch9 (end of zoe?) + sdk.hook(ch9_update_postural_camera_motion_method, on_pre_update_postural_camera_motion, on_post_update_postural_camera_motion) + end end local player_movement_args = nil @@ -300,12 +306,19 @@ end if is_re7 then local ch8_player_movement_type = sdk.find_type_definition("app.CH8PlayerMovement") - local ch8_player_movement_late_update_method = ch8_player_movement_type:get_method("doLateUpdate") + + if ch8_player_movement_type ~= nil then + local ch8_player_movement_late_update_method = ch8_player_movement_type:get_method("doLateUpdate") + sdk.hook(ch8_player_movement_late_update_method, on_pre_player_movement_late_update, on_post_player_movement_late_update) + end + local ch9_player_movement_type = sdk.find_type_definition("app.CH9PlayerMovement") - local ch9_player_movement_late_update_method = ch9_player_movement_type:get_method("doLateUpdate") - sdk.hook(ch8_player_movement_late_update_method, on_pre_player_movement_late_update, on_post_player_movement_late_update) - sdk.hook(ch9_player_movement_late_update_method, on_pre_player_movement_late_update, on_post_player_movement_late_update) + if ch8_player_movement_type ~= nil then + local ch9_player_movement_late_update_method = ch9_player_movement_type:get_method("doLateUpdate") + + sdk.hook(ch9_player_movement_late_update_method, on_pre_player_movement_late_update, on_post_player_movement_late_update) + end end function re8.notify_event_task_created(callback) From ab5f4189435f98ba2c368c4376ef477a9a03a0b7 Mon Sep 17 00:00:00 2001 From: praydog Date: Thu, 12 May 2022 09:37:29 -0700 Subject: [PATCH 37/45] VR (RE8): Fix for mouse showing up on screen --- scripts/re8_vr.lua | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/scripts/re8_vr.lua b/scripts/re8_vr.lua index d7c86da99..22b5ff9c4 100644 --- a/scripts/re8_vr.lua +++ b/scripts/re8_vr.lua @@ -156,6 +156,12 @@ local function set_inputmode(mode) local hid_manager = sdk.get_managed_singleton(sdk.game_namespace("HIDManager")) if hid_manager then + local current_mode = hid_manager:call("get_InputMode") + + if is_re8 and current_mode ~= mode then + hid_manager:set_field("k__BackingField", false) + end + hid_manager:call("set_inputMode", mode) end end From 9306f275312e17887ec0810352d32f3ad0742ea9 Mon Sep 17 00:00:00 2001 From: praydog Date: Thu, 12 May 2022 09:37:47 -0700 Subject: [PATCH 38/45] VR (RE7/8): More menu fixes --- scripts/re8_vr.lua | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/scripts/re8_vr.lua b/scripts/re8_vr.lua index 22b5ff9c4..2b5ce42bb 100644 --- a/scripts/re8_vr.lua +++ b/scripts/re8_vr.lua @@ -2293,7 +2293,14 @@ local re8_inventory_names = { "GUIInventoryCraft", "GUIInventoryKeyItem", "GUIMap", - "GUIShopBg" + "GUIShopBg", + "GUIFigureList", + "GUIBonusMenu", + "GUIMainMenu", + "GUIPhotoMode", + "GUIPause", + "GUISaveLoad", + "GUIBinder" } local re7_inventory_names = { @@ -2412,7 +2419,7 @@ re.on_pre_gui_draw_element(function(element, context) end end - if re8_inventory_names[name] or re7_inventory_names[name] then + if re8vr.player == nil or re8_inventory_names[name] or re7_inventory_names[name] then last_inventory_open_time = os.clock() end From 6410f03c9f7378e602682c8fc480fa276771df15 Mon Sep 17 00:00:00 2001 From: praydog Date: Fri, 13 May 2022 16:19:31 -0700 Subject: [PATCH 39/45] VR (RE7/8): Partial fix to player shadow --- scripts/re8_vr.lua | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/scripts/re8_vr.lua b/scripts/re8_vr.lua index 2b5ce42bb..ae40be91f 100644 --- a/scripts/re8_vr.lua +++ b/scripts/re8_vr.lua @@ -1380,6 +1380,13 @@ local function on_pre_upper_vertical_update(args) return end + -- updating the hand IK here fixes shadows. + re8vr:update_hand_ik() + + if not re8vr.is_in_cutscene and re8vr.can_use_hands and not re8vr.is_grapple_aim then + return sdk.PreHookResult.SKIP_ORIGINAL + end + --[[local upper_vertical = sdk.to_managed_object(args[2]) if not last_camera_update_args then return end @@ -2193,6 +2200,26 @@ re.on_draw_ui(function() imgui.tree_pop() end + if imgui.tree_node("Shadow") then + --if not vrmod:is_using_controllers() then return end + + if is_re7 then + local mesh_controller = re8vr.player and GameObject.get_component(re8vr.player, "app.PlayerMeshController") or nil + + if mesh_controller then + local upper_shadow_mesh = mesh_controller:get_field("UpperBodyShadowMesh") + + if upper_shadow_mesh then + + local shadow_body_gameobject = upper_shadow_mesh:call("get_GameObject") + if shadow_body_gameobject then + object_explorer:handle_address(shadow_body_gameobject) + end + end + end + end + end + if imgui.tree_node("Hit Controller") then local hit_controller = re8vr.hit_controller @@ -2280,6 +2307,7 @@ re.on_draw_ui(function() imgui.text("Is motion play: " .. tostring(re8vr.is_motion_play)) imgui.text("Is in cutscene: " .. tostring(re8vr.is_in_cutscene)) imgui.text("Can use hands: " .. tostring(re8vr.can_use_hands)) + imgui.text("Is grapple aim: " .. tostring(re8vr.is_grapple_aim)) imgui.tree_pop() end From 8bfa74c4ef7acb45b6568761866fd30ca2b1ddc7 Mon Sep 17 00:00:00 2001 From: praydog Date: Sat, 14 May 2022 16:57:24 -0700 Subject: [PATCH 40/45] VR (RE7/8): Fixes --- scripts/re8_vr.lua | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/scripts/re8_vr.lua b/scripts/re8_vr.lua index ae40be91f..b85a6bc17 100644 --- a/scripts/re8_vr.lua +++ b/scripts/re8_vr.lua @@ -1381,11 +1381,11 @@ local function on_pre_upper_vertical_update(args) end -- updating the hand IK here fixes shadows. - re8vr:update_hand_ik() + --[[re8vr:update_hand_ik() if not re8vr.is_in_cutscene and re8vr.can_use_hands and not re8vr.is_grapple_aim then return sdk.PreHookResult.SKIP_ORIGINAL - end + end]] --[[local upper_vertical = sdk.to_managed_object(args[2]) @@ -1737,6 +1737,7 @@ re.on_application_entry("LockScene", function() end) local last_roomscale_failure = os.clock() +local last_seen_player = nil re.on_pre_application_entry("UnlockScene", function() if queue_recenter then @@ -1752,6 +1753,12 @@ re.on_pre_application_entry("UnlockScene", function() if not re8vr.status then last_roomscale_failure = os.clock() return end -- in the main menu or something. if not last_camera_matrix then last_roomscale_failure = os.clock() return end if re8vr.is_in_cutscene then last_roomscale_failure = os.clock() return end + if re8vr.is_grapple_aim then last_roomscale_failure = os.clock() return end + + if re8vr.player ~= last_seen_player then + last_roomscale_failure = os.clock() + last_seen_player = re8vr.player + end if os.clock() - last_roomscale_failure < 1.0 then return end From f8e00428221de8bfb8654e9980b1cbfecf95d1a5 Mon Sep 17 00:00:00 2001 From: praydog Date: Sun, 15 May 2022 03:26:59 -0700 Subject: [PATCH 41/45] VR (RE7): Fix bomb being treated as a melee weapon --- scripts/re8_vr.lua | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/scripts/re8_vr.lua b/scripts/re8_vr.lua index b85a6bc17..5f917aa7e 100644 --- a/scripts/re8_vr.lua +++ b/scripts/re8_vr.lua @@ -1486,6 +1486,16 @@ local function melee_attack(hit_controller) return end + if is_re7 then + local go = re8vr.weapon:call("get_GameObject") + + if go ~= nil then + if go:call("get_Name"):find("Timebomb") ~= nil then + return + end + end + end + local is_end_of_zoe_melee = is_re7 and re8vr.weapon:get_type_definition():is_a("app.CH9WeaponMelee") if not is_end_of_zoe_melee then From 1a11b9dff247cf3d868fc370f0a43b57e4385829 Mon Sep 17 00:00:00 2001 From: praydog Date: Sun, 15 May 2022 13:57:30 -0700 Subject: [PATCH 42/45] Update readme --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index ffa12f516..9eaa50eed 100644 --- a/README.md +++ b/README.md @@ -7,10 +7,10 @@ The last stable build can be downloaded from the [Releases](https://github.com/p For newer builds, check out the [Nightly Developer Builds](https://github.com/praydog/REFramework-nightly/releases) ### Non-VR -* Extract the whole zip file except `openvr_api.dll` into your corresponding game folder. +* Extract the whole zip file except `openvr_api.dll` and `openxr_loader.dll` into your corresponding game folder. ### VR -* Install SteamVR +* Install SteamVR (unless you're using OpenXR on a supported headset) * Extract the whole zip file into your corresponding game folder. [VR Troubleshooting/FAQ](https://github.com/praydog/REFramework/wiki/VR-Troubleshooting) @@ -23,7 +23,7 @@ Supports both DirectX 11 and DirectX 12. * Lua Scripting API (All games) * VR * Generic 6DOF VR support for all games - * Motion controls for RE2/RE3 (RE7 and RE8 motion controls are still WIP!) + * Motion controls for RE2/RE3/RE7/RE8 * First Person (RE2, RE3) * Free Camera (All games) * Scene Timescale (All games) From 9636f7ac1b0eb43cbba4f3f56e502a492c23718c Mon Sep 17 00:00:00 2001 From: praydog Date: Sun, 15 May 2022 19:54:51 -0700 Subject: [PATCH 43/45] VR (RE8): Fix left/right not working in book menus --- scripts/re8_vr.lua | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/scripts/re8_vr.lua b/scripts/re8_vr.lua index 5f917aa7e..f732743a4 100644 --- a/scripts/re8_vr.lua +++ b/scripts/re8_vr.lua @@ -92,6 +92,7 @@ local last_gui_dot = 0.0 local last_gui_forced_slerp = os.clock() local needs_cutscene_recenter = false local last_inventory_open_time = 0.0 +local last_book_open_time = 0.0 local last_shop_open_time = 0.0 local last_scope_time = 0.0 local head_hash = nil @@ -263,6 +264,8 @@ local function update_pad_device(device) -- set cur_button | according to the right stick axis if is_re8 then + local is_book_open = os.clock() - last_book_open_time < 0.25 + if vr_right_stick_axis.x > 0.1 then cur_button = cur_button | via.hid.GamePadButton.EmuRright elseif vr_right_stick_axis.x < -0.1 then @@ -276,14 +279,30 @@ local function update_pad_device(device) end if vr_left_stick_axis.x > 0.1 then + if is_book_open then + cur_button = cur_button | via.hid.GamePadButton.LRight + end + cur_button = cur_button | via.hid.GamePadButton.EmuLright elseif vr_left_stick_axis.x < -0.1 then + if is_book_open then + cur_button = cur_button | via.hid.GamePadButton.LLeft + end + cur_button = cur_button | via.hid.GamePadButton.EmuLleft end if vr_left_stick_axis.y > 0.1 then + if is_book_open then + cur_button = cur_button | via.hid.GamePadButton.LUp + end + cur_button = cur_button | via.hid.GamePadButton.EmuLup elseif vr_left_stick_axis.y < -0.1 then + if is_book_open then + cur_button = cur_button | via.hid.GamePadButton.LDown + end + cur_button = cur_button | via.hid.GamePadButton.EmuLdown end end @@ -2358,6 +2377,10 @@ local re7_inventory_names = { "FileMenu", } +local re8_book_names = { + "GUIBook" +} + for i, v in ipairs(re8_inventory_names) do re8_inventory_names[v] = true end @@ -2366,6 +2389,10 @@ for i, v in ipairs(re7_inventory_names) do re7_inventory_names[v] = true end +for i, v in ipairs(re8_book_names) do + re8_book_names[v] = true +end + local reticle_names = { "ReticleGUI", "CH8ReticleGUI", @@ -2468,6 +2495,10 @@ re.on_pre_gui_draw_element(function(element, context) last_inventory_open_time = os.clock() end + if is_re8 and re8_book_names[name] then + last_book_open_time = os.clock() + end + if shop_names[name] then vrmod:set_gui_rotation_offset(Quaternion.identity()) last_shop_open_time = os.clock() From 47e9c46314ac4c0141478feb82ad7cc6ce02b859 Mon Sep 17 00:00:00 2001 From: praydog Date: Mon, 16 May 2022 06:02:54 -0700 Subject: [PATCH 44/45] VR (RE8): Vehicle, endgame, and map fixes --- scripts/re8_vr.lua | 79 ++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 73 insertions(+), 6 deletions(-) diff --git a/scripts/re8_vr.lua b/scripts/re8_vr.lua index f732743a4..c149b2dc3 100644 --- a/scripts/re8_vr.lua +++ b/scripts/re8_vr.lua @@ -96,7 +96,7 @@ local last_book_open_time = 0.0 local last_shop_open_time = 0.0 local last_scope_time = 0.0 local head_hash = nil - +local in_re8_end_game_event = false local neg_forward_identity = Matrix4x4f.new(-1, 0, 0, 0, 0, 1, 0, 0, @@ -323,6 +323,8 @@ local function update_pad_device(device) local action_dpad_right = vrmod:get_action_dpad_right() local action_heal = vrmod:get_action_heal() + local is_minimap_active = vrmod:is_action_active(action_minimap, right_joystick) or vrmod:is_action_active(action_minimap, left_joystick) + local right_joystick = vrmod:get_right_joystick() local left_joystick = vrmod:get_left_joystick() @@ -407,7 +409,7 @@ local function update_pad_device(device) cur_button = cur_button | via.hid.GamePadButton.Cancel | via.hid.GamePadButton.RRight end - if vrmod:is_action_active(action_b_button, left_joystick) then + if not is_minimap_active and vrmod:is_action_active(action_b_button, left_joystick) then cur_button = cur_button | via.hid.GamePadButton.RUp end @@ -419,7 +421,7 @@ local function update_pad_device(device) cur_button = cur_button | via.hid.GamePadButton.LStickPush end - if vrmod:is_action_active(action_minimap, right_joystick) or vrmod:is_action_active(action_minimap, left_joystick) then + if is_minimap_active then cur_button = cur_button | via.hid.GamePadButton.CLeft end @@ -558,6 +560,8 @@ sdk.hook( ) local function update_hand_ik() + if in_re8_end_game_event then return end + re8vr:update_hand_ik() end @@ -604,6 +608,8 @@ end local zero_vec = Vector3f.new(0, 0, 0) local function update_body_ik(camera_rotation, camera_pos) + if in_re8_end_game_event then return end + re8vr:update_body_ik(camera_rotation, camera_pos) end @@ -975,6 +981,21 @@ local last_hmd_active_state = false local wants_posture_param_restore = false local modified_posture_param = nil local original_posture_camera_offset = Vector3f.new(0.0, 0.0, 0.0) +local re8_end_game_events = { + "c32e390_01", + "c32e390_02", + "c32e390_03", + "c32e390_04", + "c32e390_05", + "c32e390_06", + "c32e390_07", + "c32e390_08", + "c32e390_09", +} + +for i, v in ipairs(re8_end_game_events) do + re8_end_game_events[v] = true +end local function pre_fix_player_camera(player_camera) end @@ -1019,6 +1040,23 @@ local function fix_player_camera(player_camera) return retval end + in_re8_end_game_event = false + + -- Check whether we're in the event at the end of RE8 + -- and return early if we are. + if is_re8 and re8vr.is_in_cutscene and re8vr.game_event_action_controller ~= nil then + local event_action = re8vr.game_event_action_controller:get_field("_GameEventAction") + + if event_action ~= nil then + local event_name = event_action:get_field("_EventName") + + if re8_end_game_events[event_name] ~= nil then + in_re8_end_game_event = true + return + end + end + end + re8.upper_body_transform_rate = player_camera:get_field("k__BackingField") last_hmd_active_state = true @@ -1031,9 +1069,12 @@ local function fix_player_camera(player_camera) if is_re8 then current_type = current_type:get_field("Value") + re8vr.has_vehicle = player_camera:get_field("RideVehicleObject") ~= nil + + if re8vr.has_vehicle and re8.is_arm_jacked then return end end - if current_type ~= 0 then -- MaximumOperatable + if current_type ~= 0 and not re8vr.has_vehicle then -- MaximumOperatable re8vr.is_in_cutscene = true is_maximum_controllable = false last_time_not_maximum_controllable = os.clock() @@ -1041,6 +1082,10 @@ local function fix_player_camera(player_camera) if os.clock() - last_time_not_maximum_controllable <= 1.0 then re8vr.is_in_cutscene = true end + + if re8vr.has_vehicle then + re8vr.is_in_cutscene = false + end end end @@ -1108,7 +1153,6 @@ local function fix_player_camera(player_camera) -- and determining where the player is looking transform_set_position:call(camera_transform, camera_pos) transform_set_rotation:call(camera_transform, camera_rot) - last_real_camera_joint_rotation = camera_rot_pre_hmd last_real_camera_joint_pos = camera_pos_pre_hmd @@ -1253,7 +1297,7 @@ local function fix_player_camera(player_camera) sdk.set_native_field(sdk.to_ptr(look_ray), ray_typedef, "from", camera_pos) sdk.set_native_field(sdk.to_ptr(look_ray), ray_typedef, "dir", fixed_dir) - if vrmod:is_using_controllers() then + if not re8vr.has_vehicle and vrmod:is_using_controllers() and re8vr.weapon ~= nil then local pos = last_muzzle_pos + (last_muzzle_forward * 0.02) --local scooted_pos = last_muzzle_pos - (last_muzzle_forward * 2) --local scooted_from = Vector4f.new(scooted_pos.x, scooted_pos.y, scooted_pos.z, 1.0) @@ -1279,6 +1323,28 @@ local function fix_player_camera(player_camera) last_cutscene_state = re8vr.is_in_cutscene end +if is_re8 then + local on_pre_cannon_calcShootPosRot = function(args) + if not vrmod:is_hmd_active() then + return + end + + if re8.is_arm_jacked then + return + end + + -- Causes the bullet to come out of the player's face + -- Not ideal, but it fixes being unable to aim downwards during the tank fight. + return sdk.PreHookResult.SKIP_ORIGINAL + end + + local on_post_cannon_calcShootPosRot = function(retval) + return retval + end + + sdk.hook(sdk.find_type_definition("app.CannonRoaderCore"):get_method("calcShootPosRot"), on_pre_cannon_calcShootPosRot, on_post_cannon_calcShootPosRot) +end + local function on_pre_player_camera_update(args) last_camera_update_args = args @@ -2344,6 +2410,7 @@ re.on_draw_ui(function() imgui.text("Is in cutscene: " .. tostring(re8vr.is_in_cutscene)) imgui.text("Can use hands: " .. tostring(re8vr.can_use_hands)) imgui.text("Is grapple aim: " .. tostring(re8vr.is_grapple_aim)) + imgui.text("In RE8 end game event: " .. tostring(in_re8_end_game_event)) imgui.tree_pop() end From 57a40966a0da5cbafdd20124f18343bbcb0a3c4e Mon Sep 17 00:00:00 2001 From: praydog Date: Mon, 16 May 2022 16:38:27 -0700 Subject: [PATCH 45/45] VR (RE7/8): More migration to native code --- scripts/re8_vr.lua | 87 +++++++++++++++++++---------------------- scripts/utility/RE8.lua | 14 +++---- 2 files changed, 48 insertions(+), 53 deletions(-) diff --git a/scripts/re8_vr.lua b/scripts/re8_vr.lua index c149b2dc3..771413f61 100644 --- a/scripts/re8_vr.lua +++ b/scripts/re8_vr.lua @@ -52,11 +52,7 @@ re8vr.left_hand_position_offset = left_hand_position_offset re8vr.right_hand_position_offset = right_hand_position_offset local ray_typedef = sdk.find_type_definition("via.Ray") -local last_muzzle_pos = Vector4f.new(0.0, 0.0, 0.0, 1.0) local last_muzzle_rot = Quaternion.new(0.0, 0.0, 0.0, 0.0) -local last_muzzle_forward = Vector4f.new(0.0, 0.0, 0.0, 1.0) -local last_shoot_pos = Vector4f.new(0.0, 0.0, 0.0, 1.0) -local last_shoot_dir = Vector4f.new(0.0, 0.0, 0.0, 1.0) local transform_get_position = sdk.find_type_definition("via.Transform"):get_method("get_Position") local transform_get_rotation = sdk.find_type_definition("via.Transform"):get_method("get_Rotation") @@ -96,7 +92,6 @@ local last_book_open_time = 0.0 local last_shop_open_time = 0.0 local last_scope_time = 0.0 local head_hash = nil -local in_re8_end_game_event = false local neg_forward_identity = Matrix4x4f.new(-1, 0, 0, 0, 0, 1, 0, 0, @@ -206,24 +201,24 @@ local function update_muzzle_data() local muzzle_position = joint_get_position(muzzle_joint) local muzzle_rotation = joint_get_rotation(muzzle_joint) - last_muzzle_pos = muzzle_position + re8vr.last_muzzle_pos = muzzle_position last_muzzle_rot = muzzle_rotation - last_muzzle_forward = muzzle_joint:call("get_AxisZ") + re8vr.last_muzzle_forward = muzzle_joint:call("get_AxisZ") if vrmod:is_using_controllers() then - last_shoot_dir = last_muzzle_forward - last_shoot_pos = last_muzzle_pos + re8vr.last_shoot_dir = re8vr.last_muzzle_forward + re8vr.last_shoot_pos = re8vr.last_muzzle_pos end elseif vrmod:is_using_controllers() then - last_muzzle_pos = re8vr.last_right_hand_position + re8vr.last_muzzle_pos = re8vr.last_right_hand_position last_muzzle_rot = last_camera_matrix:to_quat() - last_muzzle_forward = (last_muzzle_rot * Vector3f.new(0, 0, -1)):normalized() + re8vr.last_muzzle_forward = (last_muzzle_rot * Vector3f.new(0, 0, -1)):normalized() - last_shoot_dir = last_muzzle_forward - last_shoot_pos = last_muzzle_pos + re8vr.last_shoot_dir = re8vr.last_muzzle_forward + re8vr.last_shoot_pos = re8vr.last_muzzle_pos else - last_muzzle_pos = last_shoot_pos - last_muzzle_forward = last_shoot_dir + re8vr.last_muzzle_pos = re8vr.last_shoot_pos + re8vr.last_muzzle_forward = re8vr.last_shoot_dir end end end @@ -560,7 +555,7 @@ sdk.hook( ) local function update_hand_ik() - if in_re8_end_game_event then return end + if re8vr.in_re8_end_game_event then return end re8vr:update_hand_ik() end @@ -608,7 +603,7 @@ end local zero_vec = Vector3f.new(0, 0, 0) local function update_body_ik(camera_rotation, camera_pos) - if in_re8_end_game_event then return end + if re8vr.in_re8_end_game_event then return end re8vr:update_body_ik(camera_rotation, camera_pos) end @@ -629,13 +624,13 @@ local function on_pre_shoot(args) local ray = args[3] - local pos = last_muzzle_pos + (last_muzzle_forward * 0.02) + local pos = re8vr.last_muzzle_pos + (re8vr.last_muzzle_forward * 0.02) local from = Vector4f.new(pos.x, pos.y, pos.z, 1.0) - local dir = Vector4f.new(last_muzzle_forward.x, last_muzzle_forward.y, last_muzzle_forward.z, 1.0) + local dir = Vector4f.new(re8vr.last_muzzle_forward.x, re8vr.last_muzzle_forward.y, re8vr.last_muzzle_forward.z, 1.0) sdk.set_native_field(ray, ray_typedef, "from", from) sdk.set_native_field(ray, ray_typedef, "dir", dir) - --sdk.call_native_func(ray, ray_typedef, ".ctor(via.vec3, via.vec3)", last_muzzle_pos, last_muzzle_forward) + --sdk.call_native_func(ray, ray_typedef, ".ctor(via.vec3, via.vec3)", re8vr.last_muzzle_pos, re8vr.last_muzzle_forward) end local function on_post_shoot(retval) @@ -944,8 +939,8 @@ local last_time_not_maximum_controllable = 0.0 local GUI_MAX_SLERP_TIME = 1.5 local function slerp_gui(new_gui_quat) - if re8.movement_speed_rate > 0.0 then - last_gui_forced_slerp = os.clock() - ((1.0 - re8.movement_speed_rate)) + if re8vr.movement_speed_rate > 0.0 then + last_gui_forced_slerp = os.clock() - ((1.0 - re8vr.movement_speed_rate)) end last_gui_dot = last_gui_quat:dot(new_gui_quat) @@ -1001,6 +996,11 @@ local function pre_fix_player_camera(player_camera) end local function fix_player_camera(player_camera) + if true then + re8vr:fix_player_camera(player_camera) + return + end + if not vrmod:is_hmd_active() then -- so the camera doesnt go wacky if last_hmd_active_state then @@ -1034,13 +1034,10 @@ local function fix_player_camera(player_camera) was_vert_limited = false end - last_real_camera_rotation = nil - last_real_camera_joint_rotation = nil - return retval end - in_re8_end_game_event = false + re8vr.in_re8_end_game_event = false -- Check whether we're in the event at the end of RE8 -- and return early if we are. @@ -1051,14 +1048,12 @@ local function fix_player_camera(player_camera) local event_name = event_action:get_field("_EventName") if re8_end_game_events[event_name] ~= nil then - in_re8_end_game_event = true + re8vr.in_re8_end_game_event = true return end end end - re8.upper_body_transform_rate = player_camera:get_field("k__BackingField") - last_hmd_active_state = true local base_transform_solver = player_camera:get_field("BaseTransSolver") @@ -1071,7 +1066,7 @@ local function fix_player_camera(player_camera) current_type = current_type:get_field("Value") re8vr.has_vehicle = player_camera:get_field("RideVehicleObject") ~= nil - if re8vr.has_vehicle and re8.is_arm_jacked then return end + if re8vr.has_vehicle and re8vr.is_arm_jacked then return end end if current_type ~= 0 and not re8vr.has_vehicle then -- MaximumOperatable @@ -1153,8 +1148,6 @@ local function fix_player_camera(player_camera) -- and determining where the player is looking transform_set_position:call(camera_transform, camera_pos) transform_set_rotation:call(camera_transform, camera_rot) - last_real_camera_joint_rotation = camera_rot_pre_hmd - last_real_camera_joint_pos = camera_pos_pre_hmd -- Joint is used for the actual final rendering of the game world --if not wants_recenter then @@ -1193,10 +1186,10 @@ local function fix_player_camera(player_camera) end player_camera:set_field("CameraRotationWithMovementShake", fixed_rot) - --player_camera:set_field("CameraPositionWithMovementShake", camera_pos) player_camera:set_field("CameraRotationWithCameraShake", fixed_rot) - --player_camera:set_field("CameraPositionWithCameraShake", camera_pos) player_camera:set_field("PrevCameraRotation", fixed_rot) + --player_camera:set_field("CameraPositionWithMovementShake", camera_pos) + --player_camera:set_field("CameraPositionWithCameraShake", camera_pos) --player_camera:set_field("OldCameraRotation", fixed_rot) --player_camera:set_field("InterpRotationStart", fixed_rot) --player_camera:set_field("k__BackingField", fixed_rot) @@ -1298,20 +1291,20 @@ local function fix_player_camera(player_camera) sdk.set_native_field(sdk.to_ptr(look_ray), ray_typedef, "dir", fixed_dir) if not re8vr.has_vehicle and vrmod:is_using_controllers() and re8vr.weapon ~= nil then - local pos = last_muzzle_pos + (last_muzzle_forward * 0.02) - --local scooted_pos = last_muzzle_pos - (last_muzzle_forward * 2) + local pos = re8vr.last_muzzle_pos + (re8vr.last_muzzle_forward * 0.02) + --local scooted_pos = re8vr.last_muzzle_pos - (re8vr.last_muzzle_forward * 2) --local scooted_from = Vector4f.new(scooted_pos.x, scooted_pos.y, scooted_pos.z, 1.0) local from = Vector4f.new(pos.x, pos.y, pos.z, 1.0) - local dir = Vector4f.new(last_muzzle_forward.x, last_muzzle_forward.y, last_muzzle_forward.z, 1.0) + local dir = Vector4f.new(re8vr.last_muzzle_forward.x, re8vr.last_muzzle_forward.y, re8vr.last_muzzle_forward.z, 1.0) sdk.set_native_field(sdk.to_ptr(shoot_ray), ray_typedef, "from", from) sdk.set_native_field(sdk.to_ptr(shoot_ray), ray_typedef, "dir", dir) -- called in LockScene - --update_crosshair_world_pos(pos, pos + (last_muzzle_forward * 1000.0)) + --update_crosshair_world_pos(pos, pos + (re8vr.last_muzzle_forward * 1000.0)) else - last_shoot_pos = camera_pos - last_shoot_dir = fixed_dir + re8vr.last_shoot_pos = camera_pos + re8vr.last_shoot_dir = fixed_dir sdk.set_native_field(sdk.to_ptr(shoot_ray), ray_typedef, "from", camera_pos) sdk.set_native_field(sdk.to_ptr(shoot_ray), ray_typedef, "dir", fixed_dir) @@ -1329,7 +1322,7 @@ if is_re8 then return end - if re8.is_arm_jacked then + if re8vr.is_arm_jacked then return end @@ -1813,9 +1806,9 @@ re.on_application_entry("LockScene", function() update_muzzle_data() - if last_shoot_pos then - local pos = last_shoot_pos + (last_shoot_dir * 0.02) - update_crosshair_world_pos(pos, pos + (last_shoot_dir * 1000.0)) + if re8vr.last_shoot_pos then + local pos = re8vr.last_shoot_pos + (re8vr.last_shoot_dir * 0.02) + update_crosshair_world_pos(pos, pos + (re8vr.last_shoot_dir * 1000.0)) end --[[if not vrmod:is_hmd_active() then return end @@ -2405,12 +2398,14 @@ re.on_draw_ui(function() imgui.text("Num tasks: " .. tostring(re8.num_active_tasks)) imgui.text("Has postural camera control: " .. tostring(re8.has_postural_camera_control)) - imgui.text("Is arm jacked: " .. tostring(re8.is_arm_jacked)) + imgui.text("Is arm jacked: " .. tostring(re8vr.is_arm_jacked)) imgui.text("Is motion play: " .. tostring(re8vr.is_motion_play)) imgui.text("Is in cutscene: " .. tostring(re8vr.is_in_cutscene)) imgui.text("Can use hands: " .. tostring(re8vr.can_use_hands)) imgui.text("Is grapple aim: " .. tostring(re8vr.is_grapple_aim)) - imgui.text("In RE8 end game event: " .. tostring(in_re8_end_game_event)) + imgui.text("In RE8 end game event: " .. tostring(re8vr.in_re8_end_game_event)) + imgui.text("Has vehicle: " .. tostring(re8vr.has_vehicle)) + imgui.tree_pop() end diff --git a/scripts/utility/RE8.lua b/scripts/utility/RE8.lua index cbccf3926..948cff063 100644 --- a/scripts/utility/RE8.lua +++ b/scripts/utility/RE8.lua @@ -71,7 +71,7 @@ local function initialize_re8(re8) re8vr.right_hand_ik_transform = nil re8vr.left_hand_ik_transform = nil re8vr.is_in_cutscene = false - re8.is_arm_jacked = false + re8vr.is_arm_jacked = false re8vr.is_grapple_aim = false re8vr.is_motion_play = false re8vr.is_reloading = false @@ -84,7 +84,7 @@ local function initialize_re8(re8) re8vr.hit_controller = nil re8vr.wants_block = false re8vr.wants_heal = false - re8.movement_speed_rate = 0.0 + re8vr.movement_speed_rate = 0.0 re8.movement_speed_vector = Vector3f.new(0, 0, 0) re8.num_active_tasks = 0 re8.active_tasks = {} @@ -125,8 +125,8 @@ function re8.get_weapon_object(player) end function re8.update_in_cutscene_state() - re8vr.is_in_cutscene = re8.num_active_tasks > 0 or not re8.has_postural_camera_control or re8.is_arm_jacked or re8vr.is_motion_play - re8vr.can_use_hands = not re8.is_arm_jacked and not re8vr.is_motion_play + re8vr.is_in_cutscene = re8.num_active_tasks > 0 or not re8.has_postural_camera_control or re8vr.is_arm_jacked or re8vr.is_motion_play + re8vr.can_use_hands = not re8vr.is_arm_jacked and not re8vr.is_motion_play end re.on_pre_application_entry("UpdateBehavior", function() @@ -234,7 +234,7 @@ local function on_post_update_postural_camera_motion(retval) end end - re8.is_arm_jacked = controller:get_field("IsRArmJacked") + re8vr.is_arm_jacked = controller:get_field("IsRArmJacked") re8.has_postural_camera_control = controller:get_field("IsPosturalCameraControl") re8.update_in_cutscene_state() @@ -275,7 +275,7 @@ local function re7_on_post_player_movement_late_update(retval) local args = player_movement_args local movement = sdk.to_managed_object(args[2]) - re8.movement_speed_rate = movement:get_field("_SpeedRate") + re8vr.movement_speed_rate = movement:get_field("_SpeedRate") re8.movement_speed_vector = movement:get_field("_MoveSpeedVector") return retval @@ -285,7 +285,7 @@ local function re8_on_post_player_movement_late_update(retval) local args = player_movement_args local movement = sdk.to_managed_object(args[2]) - re8.movement_speed_rate = movement:get_field("SpeedRate") + re8vr.movement_speed_rate = movement:get_field("SpeedRate") re8.movement_speed_vector = movement:get_field("MoveSpeedVector") return retval