mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-23 13:10:02 +01:00
Merge pull request #53976 from nicbn/something-refactor
Makes cameras process transforms instead of reading mob angles
This commit is contained in:
+35
-18
@@ -1,3 +1,36 @@
|
||||
/// Datum which stores information about a matrix decomposed with decompose().
|
||||
/datum/decompose_matrix
|
||||
///?
|
||||
var/scale_x = 1
|
||||
///?
|
||||
var/scale_y = 1
|
||||
///?
|
||||
var/rotation = 0
|
||||
///?
|
||||
var/shift_x = 0
|
||||
///?
|
||||
var/shift_y = 0
|
||||
|
||||
/// Decomposes a matrix into scale, shift and rotation.
|
||||
///
|
||||
/// If other operations were applied on the matrix, such as shearing, the result
|
||||
/// will not be precise.
|
||||
///
|
||||
/// Negative scales are not supported.
|
||||
/matrix/proc/decompose()
|
||||
var/datum/decompose_matrix/decompose_matrix = new
|
||||
. = decompose_matrix
|
||||
decompose_matrix.scale_x = sqrt(a * a + d * d)
|
||||
decompose_matrix.scale_y = sqrt(b * b + e * e)
|
||||
decompose_matrix.shift_x = c
|
||||
decompose_matrix.shift_y = f
|
||||
if(!decompose_matrix.scale_x || !decompose_matrix.scale_y)
|
||||
return
|
||||
// If only translated, scaled and rotated, a/xs == e/ys and -d/xs == b/xy
|
||||
var/cossine = (a/decompose_matrix.scale_x + e/decompose_matrix.scale_y) / 2
|
||||
var/sine = (b/decompose_matrix.scale_y - d/decompose_matrix.scale_x) / 2
|
||||
decompose_matrix.rotation = arctan(cossine, sine)
|
||||
|
||||
/matrix/proc/TurnTo(old_angle, new_angle)
|
||||
. = new_angle - old_angle
|
||||
Turn(.) //BYOND handles cases such as -270, 360, 540 etc. DOES NOT HANDLE 180 TURNS WELL, THEY TWEEN AND LOOK LIKE SHIT
|
||||
@@ -55,30 +88,14 @@
|
||||
. += f
|
||||
. += 1
|
||||
|
||||
//The X pixel offset of this matrix
|
||||
///The X pixel offset of this matrix
|
||||
/matrix/proc/get_x_shift()
|
||||
. = c
|
||||
|
||||
//The Y pixel offset of this matrix
|
||||
///The Y pixel offset of this matrix
|
||||
/matrix/proc/get_y_shift()
|
||||
. = f
|
||||
|
||||
/matrix/proc/get_x_skew()
|
||||
. = b
|
||||
|
||||
/matrix/proc/get_y_skew()
|
||||
. = d
|
||||
|
||||
//Skews a matrix in a particular direction
|
||||
//Missing arguments are treated as no skew in that direction
|
||||
|
||||
//As Rotation is defined as a scale+skew, these procs will break any existing rotation
|
||||
//Unless the result is multiplied against the current matrix
|
||||
/matrix/proc/set_skew(x = 0, y = 0)
|
||||
b = x
|
||||
d = y
|
||||
|
||||
|
||||
/////////////////////
|
||||
// COLOUR MATRICES //
|
||||
/////////////////////
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
/obj/effect/appearance_clone
|
||||
var/turn_angle = 0
|
||||
|
||||
/obj/effect/appearance_clone/New(loc, atom/A) //Intentionally not Initialize(), to make sure the clone assumes the intended appearance in time for the camera getFlatIcon.
|
||||
if(istype(A))
|
||||
@@ -9,9 +8,6 @@
|
||||
var/atom/movable/AM = A
|
||||
step_x = AM.step_x
|
||||
step_y = AM.step_y
|
||||
if(iscarbon(A))
|
||||
var/mob/living/carbon/C = A
|
||||
UNLINT(turn_angle = C.lying_angle) // this is the only place its okay to read lying directly
|
||||
. = ..()
|
||||
|
||||
/obj/item/camera/proc/camera_get_icon(list/turfs, turf/center, psize_x = 96, psize_y = 96, datum/turf_reservation/clone_area, size_x, size_y, total_x, total_y)
|
||||
@@ -82,14 +78,29 @@
|
||||
else
|
||||
for(var/X in sorted) //these are clones
|
||||
var/obj/effect/appearance_clone/clone = X
|
||||
var/xo = (clone.x - center.x) * world.icon_size + clone.pixel_x + xcomp
|
||||
var/yo = (clone.y - center.y) * world.icon_size + clone.pixel_y + ycomp
|
||||
xo += clone.step_x
|
||||
yo += clone.step_y
|
||||
var/icon/img = getFlatIcon(clone, no_anim = TRUE)
|
||||
if(img)
|
||||
if(clone.turn_angle) //the cheapest (so best, considering cams don't need to be laggier) way of doing this, considering getFlatIcon doesn't give a snot about transforms.'
|
||||
img.Turn(clone.turn_angle)
|
||||
// Center of the image in X
|
||||
var/xo = (clone.x - center.x) * world.icon_size + clone.pixel_x + xcomp + clone.step_x
|
||||
// Center of the image in Y
|
||||
var/yo = (clone.y - center.y) * world.icon_size + clone.pixel_y + ycomp + clone.step_y
|
||||
|
||||
if(clone.transform) // getFlatIcon doesn't give a snot about transforms.
|
||||
var/datum/decompose_matrix/decompose = clone.transform.decompose()
|
||||
// Scale in X, Y
|
||||
if(decompose.scale_x != 1 || decompose.scale_y != 1)
|
||||
var/base_w = img.Width()
|
||||
var/base_h = img.Height()
|
||||
img.Scale(base_w * decompose.scale_x, base_h * decompose.scale_y)
|
||||
xo -= base_w * (decompose.scale_x - 1) / 2
|
||||
yo -= base_h * (decompose.scale_y - 1) / 2
|
||||
// Rotation
|
||||
if(decompose.rotation != 0)
|
||||
img.Turn(decompose.rotation)
|
||||
// Shift
|
||||
xo += decompose.shift_x
|
||||
yo += decompose.shift_y
|
||||
|
||||
res.Blend(img, blendMode2iconMode(clone.blend_mode), xo, yo)
|
||||
CHECK_TICK
|
||||
|
||||
|
||||
Reference in New Issue
Block a user