From 741a4a073e406525665a2bf1fae450e8b53c8093 Mon Sep 17 00:00:00 2001 From: redoak <22959728+redoak@users.noreply.github.com> Date: Wed, 7 Feb 2024 17:18:06 +0100 Subject: [PATCH 1/7] Fixed mistake in assert message --- orthographic/camera.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/orthographic/camera.lua b/orthographic/camera.lua index bbdcbcf..48f52aa 100644 --- a/orthographic/camera.lua +++ b/orthographic/camera.lua @@ -603,7 +603,7 @@ end -- @param duration Duration of the recoil. Optional, default: 0.5s. function M.recoil(camera_id, offset, duration) camera_id = camera_id or camera_ids[1] - assert(camera_id, "You must provide a strength id") + assert(camera_id, "You must provide a camera id") cameras[camera_id].recoil = { offset = offset, duration = duration or 0.5, From 82404baf1ee09d617610e45ca031c6601c8771d2 Mon Sep 17 00:00:00 2001 From: redoak <22959728+redoak@users.noreply.github.com> Date: Wed, 7 Feb 2024 15:34:06 +0100 Subject: [PATCH 2/7] Moved camera.viewport update to before it's read during bounds application --- orthographic/camera.lua | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/orthographic/camera.lua b/orthographic/camera.lua index 48f52aa..06f0673 100644 --- a/orthographic/camera.lua +++ b/orthographic/camera.lua @@ -326,6 +326,21 @@ function M.update(camera_id, dt) return end + local viewport_top = go.get(camera.url, "viewport_top") + local viewport_left = go.get(camera.url, "viewport_left") + local viewport_bottom = go.get(camera.url, "viewport_bottom") + local viewport_right = go.get(camera.url, "viewport_right") + if viewport_top == 0 then + viewport_top = WINDOW_HEIGHT + end + if viewport_right == 0 then + viewport_right = WINDOW_WIDTH + end + camera.viewport.x = viewport_left + camera.viewport.y = viewport_bottom + camera.viewport.z = math.max(viewport_right - viewport_left, 1) + camera.viewport.w = math.max(viewport_top - viewport_bottom, 1) + update_window_size() local camera_world_pos = go.get_world_position(camera_id) @@ -408,21 +423,6 @@ function M.update(camera_id, dt) camera_world_pos = M.screen_to_world(camera_id, cp) end - local viewport_top = go.get(camera.url, "viewport_top") - local viewport_left = go.get(camera.url, "viewport_left") - local viewport_bottom = go.get(camera.url, "viewport_bottom") - local viewport_right = go.get(camera.url, "viewport_right") - if viewport_top == 0 then - viewport_top = WINDOW_HEIGHT - end - if viewport_right == 0 then - viewport_right = WINDOW_WIDTH - end - camera.viewport.x = viewport_left - camera.viewport.y = viewport_bottom - camera.viewport.z = math.max(viewport_right - viewport_left, 1) - camera.viewport.w = math.max(viewport_top - viewport_bottom, 1) - go.set_position(camera_world_pos + camera_world_to_local_diff, camera_id) From 1e9c7f69fcb74fcb3de31d3d55c210bfcb1f3647 Mon Sep 17 00:00:00 2001 From: redoak <22959728+redoak@users.noreply.github.com> Date: Wed, 7 Feb 2024 15:37:33 +0100 Subject: [PATCH 3/7] Write camera properties without dependencies first thing in update --- orthographic/camera.lua | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/orthographic/camera.lua b/orthographic/camera.lua index 06f0673..7c6a1c0 100644 --- a/orthographic/camera.lua +++ b/orthographic/camera.lua @@ -326,6 +326,11 @@ function M.update(camera_id, dt) return end + camera.projection_id = go.get(camera.url, "projection") + camera.near_z = go.get(camera.url, "near_z") + camera.far_z = go.get(camera.url, "far_z") + camera.zoom = go.get(camera.url, "zoom") + local viewport_top = go.get(camera.url, "viewport_top") local viewport_left = go.get(camera.url, "viewport_left") local viewport_bottom = go.get(camera.url, "viewport_bottom") @@ -463,10 +468,6 @@ function M.update(camera_id, dt) end camera.offset = offset - camera.projection_id = go.get(camera.url, "projection") - camera.near_z = go.get(camera.url, "near_z") - camera.far_z = go.get(camera.url, "far_z") - camera.zoom = go.get(camera.url, "zoom") camera.view = calculate_view(camera, camera_world_pos, offset) camera.projection = calculate_projection(camera) From 4c751e13698bfa634f4440dcc3d197456b7286a9 Mon Sep 17 00:00:00 2001 From: redoak <22959728+redoak@users.noreply.github.com> Date: Wed, 7 Feb 2024 11:26:07 +0100 Subject: [PATCH 4/7] Reduced allocations in the render script update --- .../render/orthographic.render_script | 57 +++++++++++-------- 1 file changed, 32 insertions(+), 25 deletions(-) diff --git a/orthographic/render/orthographic.render_script b/orthographic/render/orthographic.render_script index 671b381..bdac108 100644 --- a/orthographic/render/orthographic.render_script +++ b/orthographic/render/orthographic.render_script @@ -12,29 +12,33 @@ function init(self) self.text_pred = render.predicate({"text"}) self.particle_pred = render.predicate({"particle"}) - self.clear_color = vmath.vector4(0, 0, 0, 0) - self.clear_color.x = sys.get_config("render.clear_color_red", 0) - self.clear_color.y = sys.get_config("render.clear_color_green", 0) - self.clear_color.z = sys.get_config("render.clear_color_blue", 0) - self.clear_color.w = sys.get_config("render.clear_color_alpha", 0) + local clear_color = vmath.vector4() + clear_color.x = sys.get_config("render.clear_color_red", 0) + clear_color.y = sys.get_config("render.clear_color_green", 0) + clear_color.z = sys.get_config("render.clear_color_blue", 0) + clear_color.w = sys.get_config("render.clear_color_alpha", 0) + self.clear_buffers = {[render.BUFFER_COLOR_BIT] = clear_color, [render.BUFFER_DEPTH_BIT] = 1, [render.BUFFER_STENCIL_BIT] = 0} + + self.camera_draw_options = {frustum = vmath.matrix4()} + self.gui_draw_options = {frustum = vmath.matrix4_orthographic(0, render.get_window_width(), 0, render.get_window_height(), -1, 1)} end function update(self) -- clear color render.set_depth_mask(true) render.set_stencil_mask(0xff) - render.clear({[render.BUFFER_COLOR_BIT] = self.clear_color, [render.BUFFER_DEPTH_BIT] = 1, [render.BUFFER_STENCIL_BIT] = 0}) + render.clear(self.clear_buffers) render.set_depth_mask(false) - + -- set default blend state render.enable_state(render.STATE_BLEND) render.set_blend_func(render.BLEND_SRC_ALPHA, render.BLEND_ONE_MINUS_SRC_ALPHA) -- draw world per camera + local camera_draw_options = self.camera_draw_options + local tile_pred = self.tile_pred + local particle_pred = self.particle_pred local cameras = camera.get_cameras() - local frustum = nil - local view = nil - local proj = nil if #cameras > 0 then render.disable_state(render.STATE_DEPTH_TEST) render.disable_state(render.STATE_CULL_FACE) @@ -42,34 +46,37 @@ function update(self) for _,camera_id in ipairs(cameras) do local viewport = camera.get_viewport(camera_id) render.set_viewport(viewport.x, viewport.y, viewport.z, viewport.w) - view = camera.get_view(camera_id) + local view = camera.get_view(camera_id) render.set_view(view) - proj = camera.get_projection(camera_id) + local proj = camera.get_projection(camera_id) render.set_projection(proj) - frustum = proj * view - render.draw(self.tile_pred, {frustum = frustum}) - render.draw(self.particle_pred, {frustum = frustum}) + camera_draw_options.frustum = proj * view + render.draw(tile_pred, camera_draw_options) + render.draw(particle_pred, camera_draw_options) render.draw_debug3d() end end - + -- draw gui in screen space using an orthographic projection render.disable_state(render.STATE_DEPTH_TEST) render.disable_state(render.STATE_CULL_FACE) render.enable_state(render.STATE_STENCIL_TEST) - render.set_viewport(0, 0, render.get_window_width(), render.get_window_height()) - view = IDENTITY - render.set_view(view) - proj = vmath.matrix4_orthographic(0, render.get_window_width(), 0, render.get_window_height(), -1, 1) - render.set_projection(proj) - frustum = proj * view - render.draw(self.gui_pred, {frustum = frustum}) - render.draw(self.text_pred, {frustum = frustum}) + local window_width = render.get_window_width() + local window_height = render.get_window_height() + render.set_viewport(0, 0, window_width, window_height) + render.set_view(IDENTITY) + local gui_draw_options = self.gui_draw_options + local gui_proj = gui_draw_options.frustum + gui_proj.m00 = 2 / window_width + gui_proj.m11 = 2 / window_height + render.set_projection(gui_proj) + render.draw(self.gui_pred, gui_draw_options) + render.draw(self.text_pred, gui_draw_options) render.disable_state(render.STATE_STENCIL_TEST) end function on_message(self, message_id, message) if message_id == CLEAR_COLOR then - self.clear_color = message.color + self.clear_buffers[render.BUFFER_COLOR_BIT] = message.color end end From 4b9583e3a9aab532c5a398640142b492bbe95233 Mon Sep 17 00:00:00 2001 From: redoak <22959728+redoak@users.noreply.github.com> Date: Wed, 7 Feb 2024 11:28:44 +0100 Subject: [PATCH 5/7] Reduced allocations in the camera update --- orthographic/camera.lua | 171 ++++++++++++++++++++++++++----------- orthographic/camera.script | 5 +- 2 files changed, 124 insertions(+), 52 deletions(-) diff --git a/orthographic/camera.lua b/orthographic/camera.lua index 7c6a1c0..c9802f0 100644 --- a/orthographic/camera.lua +++ b/orthographic/camera.lua @@ -63,6 +63,7 @@ local v3_tmp = vmath.vector3() local cameras = {} local camera_ids = {} +local enabled_cameras = {} -- track if the cameras list has changed or not local cameras_dirty = true @@ -225,38 +226,76 @@ end local function calculate_view(camera, camera_world_pos, offset) local rot = go.get_world_rotation(camera.id) - local pos = camera_world_pos - vmath.rotate(rot, OFFSET) + local pos = vmath.rotate(rot, OFFSET) if offset then - pos = pos + offset + pos.x = camera_world_pos.x - pos.x + offset.x + pos.y = camera_world_pos.y - pos.y + offset.y + pos.z = camera_world_pos.z - pos.z + offset.z + else + pos.x = camera_world_pos.x - pos.x + pos.y = camera_world_pos.y - pos.y + pos.z = camera_world_pos.z - pos.z end - local look_at = pos + vmath.rotate(rot, VECTOR3_MINUS1_Z) + local look_at = vmath.rotate(rot, VECTOR3_MINUS1_Z) + look_at.x = look_at.x + pos.x + look_at.y = look_at.y + pos.y + look_at.z = look_at.z + pos.z local up = vmath.rotate(rot, VECTOR3_UP) local view = vmath.matrix4_look_at(pos, look_at, up) return view end +local function is_lesser_order(a, b) + return a.order < b.order +end + local function refresh_cameras() if cameras_dirty then cameras_dirty = false - local enabled_cameras = {} - for camera_id,camera in pairs(cameras) do + local old_cam_count = #enabled_cameras + local new_cam_count = 0 + for _, camera in pairs(cameras) do if camera.enabled then - enabled_cameras[#enabled_cameras + 1] = camera + new_cam_count = new_cam_count + 1 + enabled_cameras[new_cam_count] = camera end end - table.sort(enabled_cameras, function(a, b) - return b.order > a.order - end) - if #enabled_cameras ~= #camera_ids then - camera_ids = {} + for i = new_cam_count + 1, old_cam_count do + enabled_cameras[i] = nil + camera_ids[i] = nil end - for i=1,#enabled_cameras do + table.sort(enabled_cameras, is_lesser_order) + for i = 1, new_cam_count do camera_ids[i] = enabled_cameras[i].id end end end +local function world_to_screen_mutable(viewport_w, viewport_h, viewport_l, viewport_b, view_projection, world) + v4_tmp.x, v4_tmp.y, v4_tmp.z, v4_tmp.w = world.x, world.y, world.z, 1 + local wvp = view_projection * v4_tmp + world.x = ((wvp.x + 1) / 2) * DISPLAY_WIDTH + world.y = ((wvp.y + 1) / 2) * DISPLAY_HEIGHT + world.z = ((wvp.z + 0) / 2) + + world.x = viewport_l + world.x * (viewport_w / DISPLAY_WIDTH) + world.y = viewport_b + world.y * (viewport_h / DISPLAY_HEIGHT) +end + +local function screen_to_world_mutable(viewport_w, viewport_h, viewport_l, viewport_b, inverse_view_projection, screen) + local x = (screen.x - viewport_l) * (DISPLAY_WIDTH / viewport_w) + local y = (screen.y - viewport_b) * (DISPLAY_HEIGHT / viewport_h) + + local x = (2 * x / DISPLAY_WIDTH) - 1 + local y = (2 * y / DISPLAY_HEIGHT) - 1 + local z = (2 * screen.z) + local ivp = inverse_view_projection + screen.x = x * ivp.m00 + y * ivp.m01 + z * ivp.m02 + ivp.m03 + screen.y = x * ivp.m10 + y * ivp.m11 + z * ivp.m12 + ivp.m13 + screen.z = x * ivp.m20 + y * ivp.m21 + z * ivp.m22 + ivp.m23 +end + --- Initialize a camera -- Note: This is called automatically from the init() function of the camera.script -- @param camera_id @@ -349,7 +388,10 @@ function M.update(camera_id, dt) update_window_size() local camera_world_pos = go.get_world_position(camera_id) - local camera_world_to_local_diff = camera_world_pos - go.get_position(camera_id) + local camera_world_to_local_diff = go.get_position(camera_id) + camera_world_to_local_diff.x = camera_world_to_local_diff.x - camera_world_pos.x + camera_world_to_local_diff.y = camera_world_to_local_diff.y - camera_world_pos.y + camera_world_to_local_diff.z = camera_world_to_local_diff.z - camera_world_pos.z local follow_enabled = go.get(camera.url, "follow") if follow_enabled then local follow = go.get(camera.url, "follow_target") @@ -359,32 +401,34 @@ function M.update(camera_id, dt) local follow_horizontal = go.get(camera.url, "follow_horizontal") local follow_vertical = go.get(camera.url, "follow_vertical") local follow_offset = go.get(camera.url, "follow_offset") - local target_world_pos = go.get_world_position(follow) + follow_offset - local new_pos + local new_pos = go.get_world_position(follow) + new_pos.x = new_pos.x + follow_offset.x + new_pos.y = new_pos.y + follow_offset.y + new_pos.z = camera_world_pos.z local deadzone_top = go.get(camera.url, "deadzone_top") local deadzone_left = go.get(camera.url, "deadzone_left") local deadzone_right = go.get(camera.url, "deadzone_right") local deadzone_bottom = go.get(camera.url, "deadzone_bottom") if deadzone_top ~= 0 or deadzone_left ~= 0 or deadzone_right ~= 0 or deadzone_bottom ~= 0 then - new_pos = vmath.vector3(camera_world_pos) local left_edge = camera_world_pos.x - deadzone_left local right_edge = camera_world_pos.x + deadzone_right local top_edge = camera_world_pos.y + deadzone_top local bottom_edge = camera_world_pos.y - deadzone_bottom - if target_world_pos.x < left_edge then - new_pos.x = new_pos.x - (left_edge - target_world_pos.x) - elseif target_world_pos.x > right_edge then - new_pos.x = new_pos.x + (target_world_pos.x - right_edge) + if new_pos.x < left_edge then + new_pos.x = camera_world_pos.x - (left_edge - new_pos.x) + elseif new_pos.x > right_edge then + new_pos.x = camera_world_pos.x + (new_pos.x - right_edge) + else + new_pos.x = camera_world_pos.x end - if target_world_pos.y > top_edge then - new_pos.y = new_pos.y + (target_world_pos.y - top_edge) - elseif target_world_pos.y < bottom_edge then - new_pos.y = new_pos.y - (bottom_edge - target_world_pos.y) + if new_pos.y > top_edge then + new_pos.y = camera_world_pos.y + (new_pos.y - top_edge) + elseif new_pos.y < bottom_edge then + new_pos.y = camera_world_pos.y - (bottom_edge - new_pos.y) + else + new_pos.y = camera_world_pos.y end - else - new_pos = target_world_pos end - new_pos.z = camera_world_pos.z if not follow_vertical then new_pos.y = camera_world_pos.y end @@ -402,33 +446,48 @@ function M.update(camera_id, dt) local bounds_bottom = go.get(camera.url, "bounds_bottom") local bounds_right = go.get(camera.url, "bounds_right") if bounds_top ~= 0 or bounds_left ~= 0 or bounds_bottom ~= 0 or bounds_right ~= 0 then - local cp = M.world_to_screen(camera_id, vmath.vector3(camera_world_pos)) - local tr = M.world_to_screen(camera_id, vmath.vector3(bounds_right, bounds_top, 0)) - local bl = M.world_to_screen(camera_id, vmath.vector3(bounds_left, bounds_bottom, 0)) - - local tr_offset = tr - OFFSET - local bl_offset = bl + OFFSET - - local bounds_width = tr.x - bl.x + local viewport = camera.viewport + local viewport_w = viewport.z * DISPLAY_WIDTH / WINDOW_WIDTH + local viewport_h = viewport.w * DISPLAY_HEIGHT / WINDOW_HEIGHT + local viewport_l = viewport.x * DISPLAY_WIDTH / WINDOW_WIDTH + local viewport_b = viewport.y * DISPLAY_HEIGHT / WINDOW_HEIGHT + local view = camera.view or MATRIX4 + local projection = camera.projection or MATRIX4 + local view_projection = view * projection + + world_to_screen_mutable(viewport_w, viewport_h, viewport_l, viewport_b, view_projection, camera_world_pos) + + v3_tmp.x, v3_tmp.y, v3_tmp.z = bounds_right, bounds_top, 0 + world_to_screen_mutable(viewport_w, viewport_h, viewport_l, viewport_b, view_projection, v3_tmp) + local tr_x, tr_y = v3_tmp.x, v3_tmp.y + + v3_tmp.x, v3_tmp.y, v3_tmp.z = bounds_left, bounds_bottom, 0 + world_to_screen_mutable(viewport_w, viewport_h, viewport_l, viewport_b, view_projection, v3_tmp) + local bl_x, bl_y = v3_tmp.x, v3_tmp.y + + local bounds_width = tr_x - bl_x if bounds_width < DISPLAY_WIDTH then - cp.x = bl.x + bounds_width / 2 + camera_world_pos.x = bl_x + bounds_width / 2 else - cp.x = math.max(cp.x, bl_offset.x) - cp.x = math.min(cp.x, tr_offset.x) + camera_world_pos.x = math.max(camera_world_pos.x, bl_x + OFFSET.x) + camera_world_pos.x = math.min(camera_world_pos.x, tr_x - OFFSET.x) end - local bounds_height = tr.y - bl.y + local bounds_height = tr_y - bl_y if bounds_height < DISPLAY_HEIGHT then - cp.y = bl.y + bounds_height / 2 + camera_world_pos.y = bl_y + bounds_height / 2 else - cp.y = math.max(cp.y, bl_offset.y) - cp.y = math.min(cp.y, tr_offset.y) + camera_world_pos.y = math.max(camera_world_pos.y, bl_y + OFFSET.y) + camera_world_pos.y = math.min(camera_world_pos.y, tr_y - OFFSET.y) end - camera_world_pos = M.screen_to_world(camera_id, cp) + screen_to_world_mutable(viewport_w, viewport_h, viewport_l, viewport_b, vmath.inv(view_projection), camera_world_pos) end - go.set_position(camera_world_pos + camera_world_to_local_diff, camera_id) + v3_tmp.x = camera_world_pos.x + camera_world_to_local_diff.x + v3_tmp.y = camera_world_pos.y + camera_world_to_local_diff.y + v3_tmp.z = camera_world_pos.z + camera_world_to_local_diff.z + go.set_position(v3_tmp, camera_id) if camera.shake then @@ -456,19 +515,31 @@ function M.update(camera_id, dt) end end - local offset if camera.shake or camera.recoil then - offset = VECTOR3_ZERO + local offset = camera.offset + if offset then + offset.x = 0 + offset.y = 0 + offset.z = 0 + else + offset = vmath.vector3() + camera.offset = offset + end if camera.shake then - offset = offset + camera.shake.offset + offset.x = offset.x + camera.shake.offset.x + offset.y = offset.y + camera.shake.offset.y + offset.z = offset.z + camera.shake.offset.z end if camera.recoil then - offset = offset + camera.recoil.offset + offset.x = offset.x + camera.recoil.offset.x + offset.y = offset.y + camera.recoil.offset.y + offset.z = offset.z + camera.recoil.offset.z end + else + camera.offset = nil end - camera.offset = offset - camera.view = calculate_view(camera, camera_world_pos, offset) + camera.view = calculate_view(camera, camera_world_pos, camera.offset) camera.projection = calculate_projection(camera) refresh_cameras() diff --git a/orthographic/camera.script b/orthographic/camera.script index 9222f3d..e846d68 100644 --- a/orthographic/camera.script +++ b/orthographic/camera.script @@ -64,13 +64,14 @@ end function update(self, dt) -- update camera and view projection after all game objects have been updated -- will jitter otherwise - msg.post("#", camera.MSG_UPDATE_CAMERA, { dt = dt }) + self.last_dt = dt + msg.post("#", camera.MSG_UPDATE_CAMERA) end function on_message(self, message_id, message, sender) if message_id == camera.MSG_UPDATE_CAMERA then - camera.update(go.get_id(), message.dt) + camera.update(go.get_id(), message.dt or self.last_dt) if self.enabled then camera.send_view_projection(go.get_id()) end From 41ef9c07e9fc7b4e11eb0ab670d973540960be7a Mon Sep 17 00:00:00 2001 From: redoak <22959728+redoak@users.noreply.github.com> Date: Wed, 7 Feb 2024 16:06:34 +0100 Subject: [PATCH 6/7] Added local variables for camera's shake and recoil in update --- orthographic/camera.lua | 50 +++++++++++++++++++++-------------------- 1 file changed, 26 insertions(+), 24 deletions(-) diff --git a/orthographic/camera.lua b/orthographic/camera.lua index c9802f0..740bc8e 100644 --- a/orthographic/camera.lua +++ b/orthographic/camera.lua @@ -490,32 +490,34 @@ function M.update(camera_id, dt) go.set_position(v3_tmp, camera_id) - if camera.shake then - camera.shake.duration = camera.shake.duration - dt - if camera.shake.duration < 0 then - if camera.shake.cb then camera.shake.cb() end - camera.shake = nil + local shake = camera.shake + if shake then + shake.duration = shake.duration - dt + if shake.duration < 0 then + if shake.cb then shake.cb() end + camera.shake, shake = nil, nil else - if camera.shake.horizontal then - camera.shake.offset.x = (DISPLAY_WIDTH * camera.shake.intensity) * (math.random() - 0.5) + if shake.horizontal then + shake.offset.x = (DISPLAY_WIDTH * shake.intensity) * (math.random() - 0.5) end - if camera.shake.vertical then - camera.shake.offset.y = (DISPLAY_WIDTH * camera.shake.intensity) * (math.random() - 0.5) + if shake.vertical then + shake.offset.y = (DISPLAY_WIDTH * shake.intensity) * (math.random() - 0.5) end end end - if camera.recoil then - camera.recoil.time_left = camera.recoil.time_left - dt - if camera.recoil.time_left < 0 then - camera.recoil = nil + local recoil = camera.recoil + if recoil then + recoil.time_left = recoil.time_left - dt + if recoil.time_left < 0 then + camera.recoil, recoil = nil, nil else - local t = camera.recoil.time_left / camera.recoil.duration - camera.recoil.offset = vmath.lerp(t, VECTOR3_ZERO, camera.recoil.offset) + local t = recoil.time_left / recoil.duration + recoil.offset = vmath.lerp(t, VECTOR3_ZERO, recoil.offset) end end - if camera.shake or camera.recoil then + if shake or recoil then local offset = camera.offset if offset then offset.x = 0 @@ -525,15 +527,15 @@ function M.update(camera_id, dt) offset = vmath.vector3() camera.offset = offset end - if camera.shake then - offset.x = offset.x + camera.shake.offset.x - offset.y = offset.y + camera.shake.offset.y - offset.z = offset.z + camera.shake.offset.z + if shake then + offset.x = offset.x + shake.offset.x + offset.y = offset.y + shake.offset.y + offset.z = offset.z + shake.offset.z end - if camera.recoil then - offset.x = offset.x + camera.recoil.offset.x - offset.y = offset.y + camera.recoil.offset.y - offset.z = offset.z + camera.recoil.offset.z + if recoil then + offset.x = offset.x + recoil.offset.x + offset.y = offset.y + recoil.offset.y + offset.z = offset.z + recoil.offset.z end else camera.offset = nil From 19b53559f77368d44864149fb66660f1e3abb132 Mon Sep 17 00:00:00 2001 From: redoak <22959728+redoak@users.noreply.github.com> Date: Wed, 7 Feb 2024 16:08:02 +0100 Subject: [PATCH 7/7] Added local variable for camera's url in update --- orthographic/camera.lua | 49 +++++++++++++++++++++-------------------- 1 file changed, 25 insertions(+), 24 deletions(-) diff --git a/orthographic/camera.lua b/orthographic/camera.lua index 740bc8e..cfa9980 100644 --- a/orthographic/camera.lua +++ b/orthographic/camera.lua @@ -355,8 +355,9 @@ function M.update(camera_id, dt) return end - local enabled = go.get(camera.url, "enabled") - local order = go.get(camera.url, "order") + local camera_url = camera.url + local enabled = go.get(camera_url, "enabled") + local order = go.get(camera_url, "order") cameras_dirty = cameras_dirty or (camera.enabled ~= enabled) cameras_dirty = cameras_dirty or (camera.order ~= order) camera.enabled = enabled @@ -365,15 +366,15 @@ function M.update(camera_id, dt) return end - camera.projection_id = go.get(camera.url, "projection") - camera.near_z = go.get(camera.url, "near_z") - camera.far_z = go.get(camera.url, "far_z") - camera.zoom = go.get(camera.url, "zoom") + camera.projection_id = go.get(camera_url, "projection") + camera.near_z = go.get(camera_url, "near_z") + camera.far_z = go.get(camera_url, "far_z") + camera.zoom = go.get(camera_url, "zoom") - local viewport_top = go.get(camera.url, "viewport_top") - local viewport_left = go.get(camera.url, "viewport_left") - local viewport_bottom = go.get(camera.url, "viewport_bottom") - local viewport_right = go.get(camera.url, "viewport_right") + local viewport_top = go.get(camera_url, "viewport_top") + local viewport_left = go.get(camera_url, "viewport_left") + local viewport_bottom = go.get(camera_url, "viewport_bottom") + local viewport_right = go.get(camera_url, "viewport_right") if viewport_top == 0 then viewport_top = WINDOW_HEIGHT end @@ -392,23 +393,23 @@ function M.update(camera_id, dt) camera_world_to_local_diff.x = camera_world_to_local_diff.x - camera_world_pos.x camera_world_to_local_diff.y = camera_world_to_local_diff.y - camera_world_pos.y camera_world_to_local_diff.z = camera_world_to_local_diff.z - camera_world_pos.z - local follow_enabled = go.get(camera.url, "follow") + local follow_enabled = go.get(camera_url, "follow") if follow_enabled then - local follow = go.get(camera.url, "follow_target") + local follow = go.get(camera_url, "follow_target") if not check_game_object(follow) then log("Camera '%s' has a follow target '%s' that does not exist", tostring(camera_id), tostring(follow)) else - local follow_horizontal = go.get(camera.url, "follow_horizontal") - local follow_vertical = go.get(camera.url, "follow_vertical") - local follow_offset = go.get(camera.url, "follow_offset") + local follow_horizontal = go.get(camera_url, "follow_horizontal") + local follow_vertical = go.get(camera_url, "follow_vertical") + local follow_offset = go.get(camera_url, "follow_offset") local new_pos = go.get_world_position(follow) new_pos.x = new_pos.x + follow_offset.x new_pos.y = new_pos.y + follow_offset.y new_pos.z = camera_world_pos.z - local deadzone_top = go.get(camera.url, "deadzone_top") - local deadzone_left = go.get(camera.url, "deadzone_left") - local deadzone_right = go.get(camera.url, "deadzone_right") - local deadzone_bottom = go.get(camera.url, "deadzone_bottom") + local deadzone_top = go.get(camera_url, "deadzone_top") + local deadzone_left = go.get(camera_url, "deadzone_left") + local deadzone_right = go.get(camera_url, "deadzone_right") + local deadzone_bottom = go.get(camera_url, "deadzone_bottom") if deadzone_top ~= 0 or deadzone_left ~= 0 or deadzone_right ~= 0 or deadzone_bottom ~= 0 then local left_edge = camera_world_pos.x - deadzone_left local right_edge = camera_world_pos.x + deadzone_right @@ -435,16 +436,16 @@ function M.update(camera_id, dt) if not follow_horizontal then new_pos.x = camera_world_pos.x end - local follow_lerp = go.get(camera.url, "follow_lerp") + local follow_lerp = go.get(camera_url, "follow_lerp") camera_world_pos = lerp_with_dt(follow_lerp, dt, camera_world_pos, new_pos) camera_world_pos.z = new_pos.z end end - local bounds_top = go.get(camera.url, "bounds_top") - local bounds_left = go.get(camera.url, "bounds_left") - local bounds_bottom = go.get(camera.url, "bounds_bottom") - local bounds_right = go.get(camera.url, "bounds_right") + local bounds_top = go.get(camera_url, "bounds_top") + local bounds_left = go.get(camera_url, "bounds_left") + local bounds_bottom = go.get(camera_url, "bounds_bottom") + local bounds_right = go.get(camera_url, "bounds_right") if bounds_top ~= 0 or bounds_left ~= 0 or bounds_bottom ~= 0 or bounds_right ~= 0 then local viewport = camera.viewport local viewport_w = viewport.z * DISPLAY_WIDTH / WINDOW_WIDTH