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 = Object.create(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