Files
prosperon/camera.cm
2025-12-17 00:48:19 -06:00

122 lines
2.6 KiB
Plaintext

var cam = {}
/*
presentation can be one of
letterbox
overscan
stretch
... or simply 'null' for no presentation
*/
var basecam = {
pos: [0,0], // where it is
ortho:true,
width: 100,
aspect_ratio: 16/9,
fov:50,
near_z:0,
far_z:1000,
anchor:[0.5,0.5],
rotation:[0,0,0,1],
presentation: "letterbox",
background: {r:1,g:1,b:1,a:0},
viewport: {x:0,y:0,width:1,height:1},
}
basecam.draw_rect = function(size)
{
var mode = this.presentation || "letterbox"
var vp = {
x:this.viewport.x,
y:1-this.viewport.y-this.viewport.height,
width:this.viewport.width,
height:this.viewport.height
}
var src_rect = {x:0,y:0,width:this.size.x,height:this.size.y}
var dst_rect = {x:vp.x*size.x,y:vp.y*size.y,width:vp.width*size.x,height:vp.height*size.y};
return mode_rect(src_rect,dst_rect,mode);
}
basecam.screen2camera = function(pos)
{
var draw_rect = this.draw_rect(prosperon.window.size);
var ret = [pos.x-draw_rect.x, pos.y - draw_rect.y];
ret.x /= draw_rect.width;
ret.y /= draw_rect.height;
ret.y = 1 - ret.y;
return ret;
}
basecam.screen2hud = function(pos)
{
var cam = this.screen2camera(pos);
cam.x *= this.size.x;
cam.y *= this.size.y;
return cam;
}
basecam.screen2world = function(pos)
{
var hud = this.screen2hud(pos);
hud.x += this.transform.pos.x - this.size.x/2;
hud.y += this.transform.pos.y - this.size.y/2;
return hud;
}
function mode_rect(src,dst,mode = "stretch")
{
var aspect_src = src.width/src.height;
var aspect_dst = dst.width/dst.height;
var out = {
x:dst.x,
y:dst.y,
width:dst.width,
height:dst.height
};
if (mode == "stretch") return out;
if (mode == "letterbox") {
if (aspect_src > aspect_dst) {
var scaled_h = out.width/aspect_src;
var off = (out.height - scaled_h) * 0.5;
out.y += off;
out.height = scaled_h;
} else {
var scaled_w =out.height * aspect_src;
var off = (out.width - scaled_w) * 0.5;
out.x += off;
out.width = scaled_w;
}
} else if (mode == "overscan"){
if (aspect_src > aspect_dst) {
var scaled_w = out.height * aspect_src;
var off = (out.width - scaled_w) * 0.5;
out.x += off;
out.width = scaled_w;
} else {
var scaled_h = out.width / aspect_src;
var off = (out.height - scaled_h) * 0.5;
out.y += off;
out.height = scaled_h;
}
}
return out;
}
cam.make = function()
{
var c = meme(basecam)
c.transform = new transform
c.transform.unit()
c.size = [640,360]
c.mode = 'keep'
c.viewport = {x:0,y:0,width:1,height:1}
c.fov = 45
c.type = 'ortho'
c.ortho = true
c.aspect = 16/9
return c
}
return cam