1
0
Fork 0
auts/isotest/geom.v

223 lines
4.8 KiB
V

module main
import math
// TODO: add world_to_cell_pos, cell_to_world_pos (as an extra to screen versions)
// World pos to screen pos
fn world_to_screen_pos(x, y int) (int, int) {
sx := x + -game.viewport.shx
sy := y + -game.viewport.shy
return sx, sy
}
fn screen_to_world_pos(sx, sy int) (int, int) {
wx := sx + game.viewport.shx
wy := sy + game.viewport.shy
return wx, wy
}
// XXX returned value is top-left corner of cell
// use center version for cell's center
fn cell_to_world_pos(cx, cy int) (int, int) {
//wx := cx * c_cell_w
//wy := cy * c_cell_h
cell_size_z := 0
cz := 0
wx := (c_cell_w * cx) + ((cy&1) * (c_cell_w / 2))
wy := (c_cell_h * cy / 2) - cell_size_z * cz
return wx, wy
}
// XXX get center position of cell at cx, cy in world-space
fn cell_to_world_pos_center(cx, cy int) (int, int) {
wx, wy := cell_to_world_pos(cx, cy)
center_wx := wx + c_cell_w / 2
center_wy := wy + c_cell_h / 2
return center_wx, center_wy
}
fn cell_to_screen_pos(cx, cy int) (int, int) {
pan_x := 0
pan_y := 0
cell_size_z := 0
cz := 0
sx := pan_x + (c_cell_w * cx) + ((cy&1) * (c_cell_w / 2))
sy := pan_y + (c_cell_h * cy / 2) - cell_size_z * cz
return sx, sy
}
// XXX bad
fn cell_to_screen_pos2(cx, cy int) (int, int) {
scale_ := f32(1.0)
width_ := f32(c_cell_w)
height_ := f32(c_cell_h)
//width_ := f32(game.field.w * c_cell_w)
//height_ := f32(game.field.h * c_cell_h)
sw := scale_ * width_/2.0
sh := scale_ * height_/2.0
rx, ry := (cx - cy + f32(int(cy)&1)/2.0) * sw,
(cx + cy + f32(int(cy)&1)/2.0) * sh
rxi, ryi := int(rx), int(ry)
return rxi, ryi
}
/*
fn screen_to_cell_pos(sx, sy int) (int, int) {
pan_x := 0
pan_y := 0
cell_size_z := 0
mut cy := (2 * (sy - pan_y)) / c_cell_h
mut cx := (sx - pan_x - ((cy&1) * (c_cell_w / 2))) / c_cell_w
mut cz := 0
// Correction?
//mut xx, mut yy := cell_to_screen_pos(cx, cy, cz)
mut xx, mut yy := cell_to_screen_pos(cx, cy)
xx = sx - xx
mx0 := cx
yy = sy - yy
my0 := cy
if xx <= (c_cell_w / 2) {
if yy > xx * c_cell_h/c_cell_w {
cy++
if int(cy&1) != 0 {
cx--
}
}
} else {
if yy > (c_cell_w - xx) * c_cell_h/c_cell_w {
cy++
if int(cy&1) == 0 {
cx++
}
}
}
return cx, cy
}
*/
// XXX bad
fn screen_to_cell_pos2(sx, sy int) (int, int) {
px := f32(sx)
py := f32(sy)
//width := game.field.w * c_cell_w
//height := game.field.h * c_cell_h
//width := game.field.w
//height := game.field.h
width := c_cell_w
height := c_cell_h
mx := int(math.floor(px / width))
my := int(math.floor(py / height) * 2)
return mx, my
}
fn screen_to_cell_pos3(sx, sy int) (int, int) {
wx, wy := screen_to_world_pos(sx, sy)
return world_to_cell_pos3(wx, wy)
}
// XXX
// x is accurate +/-
// y is not very
//fn screen_to_cell_pos3(sx, sy int) (int, int) {
fn world_to_cell_pos3(wx, wy int) (int, int) {
// XXX name alias for world version
sx := wx
sy := wy
//y := f32(game.field.h) - 1.0 - f32(sy) * 2.0 / f32(c_cell_h)
//sy_ := ctx.vars.res_y - sy
//sy_ := game.field.height_px() - (f32(c_cell_h) * 1.5) - sy
//sy_ := sy
//sy_ := 1.0
//sy_ := f32(0.0)
//println("sy_: $sy_")
//y := f32(game.field.h) - f32(sy_) * 2.0 / f32(c_cell_h)
//y := f32(game.field.h) - 1.0 - f32(sy_) * 2.0 / f32(c_cell_h)
//mut y := f32(sy) / f32(c_cell_h)
//mut y := 0.0 - 1.0 - f32(sy_) * 2.0 / f32(c_cell_h)
mut y := f32(sy) * 2.0 / f32(c_cell_h) + 1.0
//mut y := f32(sy) * 2.0 / f32(c_cell_h)
mut x := f32(0.0)
y = (2 * (sy)) / c_cell_h
if int(y) % 2 == 0 {
x = f32(sx) / f32(c_cell_w)
} else {
//x = f32(sx) / f32(c_cell_w)
//x = (f32(sx) / f32(c_cell_w)) / 2.0
//x = (f32(sx) + f32(c_cell_w / 2)) / f32(c_cell_w)
x = ((f32(sx) / f32(c_cell_w))) - f32(0.5) // 0.5 is float rounding correction to the lower number
}
yi, xi := int(y), int(x)
return xi, yi
}
// XXX inaccurate
fn mouse_to_cell_pos(mx, my int) (int, int) {
// https://gamedev.stackexchange.com/questions/45103/staggered-isometric-map-calculate-map-coordinates-for-point-on-screen
px := f32(mx) - (c_cell_w / 2.0)
py := f32(my) - (c_cell_h / 2.0)
x := math.floor((px + (py - (c_cell_h / 2.0)) * 2.0) / c_cell_w)
y := math.floor((py - (px - (c_cell_w / 2.0)) * 0.5) / c_cell_h)
tx := math.floor((x - y) / 2.0) + 1.0 //+ this.camera.x;
ty := y + x + 2.0 //+ this.camera.y;
/*
tx := math.floor((x - y) / 2) + 1 + -(game.viewport.shx / c_tile_w)
ty := y + x + 2 + -(game.viewport.shy / c_tile_h)
*/
// XXX rounding errors?
mut txi := int(tx)
mut tyi := int(ty)
// XXX correct y by shift, fixme?
tyi = tyi - 1
/*
vp_shx_tiles := game.viewport.shx / c_tile_w
vp_shy_tiles := game.viewport.shy / c_tile_h
txi = txi + vp_shx_tiles
tyi = tyi + (vp_shy_tiles * 2)
*/
return txi, tyi
}