layout
This commit is contained in:
parent
f1b2984f61
commit
83a19eec27
|
@ -1452,20 +1452,6 @@ var replpanel = Object.copy(inputpanel, {
|
||||||
guibody() {
|
guibody() {
|
||||||
this.win.selectable = true;
|
this.win.selectable = true;
|
||||||
var log = console.transcript;
|
var log = console.transcript;
|
||||||
return [
|
|
||||||
Mum.text({
|
|
||||||
str: log,
|
|
||||||
anchor: [0, 0],
|
|
||||||
offset: [0, -300].sub(this.scrolloffset),
|
|
||||||
selectable: true,
|
|
||||||
}),
|
|
||||||
Mum.text({
|
|
||||||
str: this.value,
|
|
||||||
color: Color.green,
|
|
||||||
offset: [0, -290],
|
|
||||||
caret: this.caret,
|
|
||||||
}),
|
|
||||||
];
|
|
||||||
},
|
},
|
||||||
prevmark: -1,
|
prevmark: -1,
|
||||||
prevthis: [],
|
prevthis: [],
|
||||||
|
@ -1608,109 +1594,6 @@ replpanel.inputs.pgdown = function () {
|
||||||
};
|
};
|
||||||
replpanel.inputs.pgdown.rep = true;
|
replpanel.inputs.pgdown.rep = true;
|
||||||
|
|
||||||
var objectexplorer = Object.copy(inputpanel, {
|
|
||||||
title: "object explorer",
|
|
||||||
obj: undefined,
|
|
||||||
previous: [],
|
|
||||||
start() {
|
|
||||||
this.previous = [];
|
|
||||||
},
|
|
||||||
|
|
||||||
goto_obj(obj) {
|
|
||||||
if (obj === this.obj) return;
|
|
||||||
this.previous.push(this.obj);
|
|
||||||
this.obj = obj;
|
|
||||||
},
|
|
||||||
|
|
||||||
prev_obj() {
|
|
||||||
this.obj = this.previous.pop();
|
|
||||||
},
|
|
||||||
|
|
||||||
guibody() {
|
|
||||||
var items = [];
|
|
||||||
items.push(Mum.text({ str: "Examining " + this.obj.toString() + " entity" }));
|
|
||||||
items.push(Mum.text({ str: JSON.stringify(this.obj, undefined, 1) }));
|
|
||||||
return items;
|
|
||||||
|
|
||||||
var n = 0;
|
|
||||||
var curobj = this.obj;
|
|
||||||
while (curobj) {
|
|
||||||
n++;
|
|
||||||
curobj = curobj.__proto__;
|
|
||||||
}
|
|
||||||
|
|
||||||
n--;
|
|
||||||
curobj = this.obj.__proto__;
|
|
||||||
while (curobj) {
|
|
||||||
items.push(Mum.text({ str: curobj.toString(), action: this.goto_obj(curobj) }));
|
|
||||||
curobj = curobj.__proto__;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!Object.empty(this.previous))
|
|
||||||
items.push(
|
|
||||||
Mum.text({
|
|
||||||
str: "prev: " + this.previous.last(),
|
|
||||||
action: this.prev_obj,
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
|
|
||||||
Object.getOwnPropertyNames(this.obj).forEach(key => {
|
|
||||||
var descriptor = Object.getOwnPropertyDescriptor(this.obj, key);
|
|
||||||
if (!descriptor) return;
|
|
||||||
var hidden = !descriptor.enumerable;
|
|
||||||
var writable = descriptor.writable;
|
|
||||||
var configurable = descriptor.configurable;
|
|
||||||
|
|
||||||
if (!descriptor.configurable) return;
|
|
||||||
if (hidden) return;
|
|
||||||
|
|
||||||
var name = (hidden ? "[hidden] " : "") + key;
|
|
||||||
var val = this.obj[key];
|
|
||||||
|
|
||||||
switch (typeof val) {
|
|
||||||
case "object":
|
|
||||||
if (val) {
|
|
||||||
items.push(Mum.text({ str: name }));
|
|
||||||
items.push(
|
|
||||||
Mum.text({
|
|
||||||
str: val.toString(),
|
|
||||||
action: this.goto_obj.bind(val),
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "function":
|
|
||||||
items.push(Mum.text({ str: name }));
|
|
||||||
items.push(Mum.text({ str: "function" }));
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
items.push(Mum.text({ str: name }));
|
|
||||||
items.push(Mum.text({ str: val.toString() }));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
items.push(Mum.text({ str: "Properties that can be pulled in ..." }));
|
|
||||||
var pullprops = [];
|
|
||||||
for (var key in this.obj.__proto__) {
|
|
||||||
if (!this.obj.hasOwn(key)) {
|
|
||||||
if (typeof this.obj[key] === "object" || typeof this.obj[key] === "function") continue;
|
|
||||||
pullprops.push(key);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pullprops = pullprops.sort();
|
|
||||||
|
|
||||||
pullprops.forEach(function (key) {
|
|
||||||
items.push(Mum.text({ str: key }));
|
|
||||||
});
|
|
||||||
|
|
||||||
return items;
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
var openlevelpanel = Object.copy(inputpanel, {
|
var openlevelpanel = Object.copy(inputpanel, {
|
||||||
title: "open entity",
|
title: "open entity",
|
||||||
action() {
|
action() {
|
||||||
|
@ -1720,8 +1603,6 @@ var openlevelpanel = Object.copy(inputpanel, {
|
||||||
assets: [],
|
assets: [],
|
||||||
allassets: [],
|
allassets: [],
|
||||||
|
|
||||||
mumlist: {},
|
|
||||||
|
|
||||||
submit_check() {
|
submit_check() {
|
||||||
if (this.assets.length === 0) return false;
|
if (this.assets.length === 0) return false;
|
||||||
|
|
||||||
|
@ -1739,32 +1620,15 @@ var openlevelpanel = Object.copy(inputpanel, {
|
||||||
this.submit();
|
this.submit();
|
||||||
};
|
};
|
||||||
click_ur = click_ur.bind(this);
|
click_ur = click_ur.bind(this);
|
||||||
|
|
||||||
this.mumlist = [];
|
|
||||||
this.assets.forEach(function (x) {
|
|
||||||
this.mumlist[x] = Mum.text({
|
|
||||||
str: x,
|
|
||||||
action: click_ur,
|
|
||||||
color: Color.blue,
|
|
||||||
hovered: { color: Color.red },
|
|
||||||
selectable: true,
|
|
||||||
});
|
|
||||||
}, this);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
keycb() {
|
keycb() {
|
||||||
if (this.value) this.assets = this.allassets.filter(x => x.startsWith(this.value));
|
if (this.value) this.assets = this.allassets.filter(x => x.startsWith(this.value));
|
||||||
else this.assets = this.allassets.slice();
|
else this.assets = this.allassets.slice();
|
||||||
for (var m in this.mumlist) this.mumlist[m].hide = true;
|
|
||||||
this.assets.forEach(function (x) {
|
|
||||||
this.mumlist[x].hide = false;
|
|
||||||
}, this);
|
}, this);
|
||||||
},
|
},
|
||||||
|
|
||||||
guibody() {
|
guibody() {
|
||||||
var a = [Mum.text({ str: this.value, color: Color.green, caret: this.caret })];
|
|
||||||
var b = a.concat(Object.values(this.mumlist));
|
|
||||||
return Mum.column({ items: b, offset: [0, -10] });
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1789,17 +1653,6 @@ var groupsaveaspanel = Object.copy(inputpanel, {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
var quitpanel = Object.copy(inputpanel, {
|
|
||||||
title: "really quit?",
|
|
||||||
action() {
|
|
||||||
os.quit();
|
|
||||||
},
|
|
||||||
|
|
||||||
guibody() {
|
|
||||||
return Mum.text({ str: "Really quit?" });
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
var allfiles = [];
|
var allfiles = [];
|
||||||
allfiles.push(Resources.scripts, Resources.images, Resources.sounds);
|
allfiles.push(Resources.scripts, Resources.images, Resources.sounds);
|
||||||
allfiles = allfiles.flat();
|
allfiles = allfiles.flat();
|
||||||
|
@ -1815,26 +1668,6 @@ var assetexplorer = Object.copy(openlevelpanel, {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
var componentexplorer = Object.copy(inputpanel, {
|
|
||||||
title: "component menu",
|
|
||||||
assets: ["sprite", "model", "edge2d", "polygon2d", "circle2d"],
|
|
||||||
click(name) {
|
|
||||||
if (editor.selectlist.length !== 1) return;
|
|
||||||
editor.selectlist[0].add_component(component[name]);
|
|
||||||
},
|
|
||||||
guibody() {
|
|
||||||
return componentexplorer.assets.map(x =>
|
|
||||||
Mum.text({
|
|
||||||
str: x,
|
|
||||||
action: this.click,
|
|
||||||
color: Color.blue,
|
|
||||||
hovered: { Color: Color.red },
|
|
||||||
selectable: true,
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
var entitylistpanel = Object.copy(inputpanel, {
|
var entitylistpanel = Object.copy(inputpanel, {
|
||||||
title: "Level object list",
|
title: "Level object list",
|
||||||
level: {},
|
level: {},
|
||||||
|
|
|
@ -104,6 +104,8 @@ prosperon.textinput = function (c) {
|
||||||
player[0].raw_input("char", "pressed", c);
|
player[0].raw_input("char", "pressed", c);
|
||||||
};
|
};
|
||||||
prosperon.mousemove = function (pos, dx) {
|
prosperon.mousemove = function (pos, dx) {
|
||||||
|
pos.y *= -1;
|
||||||
|
dx.y *= -1;
|
||||||
mousepos = pos;
|
mousepos = pos;
|
||||||
player[0].mouse_input("move", pos, dx);
|
player[0].mouse_input("move", pos, dx);
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,24 +1,258 @@
|
||||||
layout.flag = {};
|
// Layout code
|
||||||
layout.flag.row = 0x002;
|
// Contain is for how it will treat its children. If they should be laid out as a row, or column, or in a flex style, etc.
|
||||||
layout.flag.column = 0x003;
|
layout.contain = {};
|
||||||
layout.flag.layout = 0x000;
|
layout.contain.row = 0x002;
|
||||||
layout.flag.flex = 0x002;
|
layout.contain.column = 0x003;
|
||||||
layout.flag.nowrap = 0x000;
|
layout.contain.layout = 0x000;
|
||||||
layout.flag.wrap = 0x004;
|
layout.contain.flex = 0x002;
|
||||||
layout.flag.start = 0x008;
|
layout.contain.nowrap = 0x000;
|
||||||
layout.flag.middle = 0x000;
|
layout.contain.wrap = 0x004;
|
||||||
layout.flag.end = 0x010;
|
layout.contain.start = 0x008;
|
||||||
layout.flag.justify = 0x018;
|
layout.contain.middle = 0x000;
|
||||||
|
layout.contain.end = 0x010;
|
||||||
|
layout.contain.justify = 0x018;
|
||||||
|
|
||||||
layout.flag.left = 0x020;
|
// Behave is for how it behaves to its parent. How it should be aligned, directions it should fill, etc.
|
||||||
layout.flag.top = 0x040;
|
layout.behave = {};
|
||||||
layout.flag.right = 0x080;
|
layout.behave.left = 0x020;
|
||||||
layout.flag.bottom = 0x100;
|
layout.behave.top = 0x040;
|
||||||
layout.flag.hfill = 0x0a0;
|
layout.behave.right = 0x080;
|
||||||
layout.flag.vfill = 0x140;
|
layout.behave.bottom = 0x100;
|
||||||
layout.flag.hcenter = 0x000;
|
layout.behave.hfill = 0x0a0;
|
||||||
layout.flag.vcenter = 0x000;
|
layout.behave.vfill = 0x140;
|
||||||
layout.flag.center = 0x000;
|
layout.behave.hcenter = 0x000;
|
||||||
layout.flag.fill = 0x1e0;
|
layout.behave.vcenter = 0x000;
|
||||||
layout.flag.break = 0x200;
|
layout.behave.center = 0x000;
|
||||||
|
layout.behave.fill = 0x1e0;
|
||||||
|
layout.behave.break = 0x200;
|
||||||
|
|
||||||
|
var clay_base = {
|
||||||
|
font: undefined,
|
||||||
|
background_image: undefined,
|
||||||
|
slice: 0,
|
||||||
|
font: 'smalle.16',
|
||||||
|
font_size: undefined,
|
||||||
|
color: [1,1,1,1],
|
||||||
|
spacing:0,
|
||||||
|
padding:0,
|
||||||
|
margin:0,
|
||||||
|
offset:[0,0],
|
||||||
|
size:[0,0]
|
||||||
|
};
|
||||||
|
|
||||||
|
var root_item;
|
||||||
|
var root_config;
|
||||||
|
var boxes = [];
|
||||||
|
globalThis.clay = {};
|
||||||
|
|
||||||
|
clay.normalizeSpacing = function(spacing) {
|
||||||
|
if (typeof spacing === 'number') {
|
||||||
|
return {l: spacing, r: spacing, t: spacing, b: spacing};
|
||||||
|
} else if (Array.isArray(spacing)) {
|
||||||
|
if (spacing.length === 2) {
|
||||||
|
return {l: spacing[0], r: spacing[0], t: spacing[1], b: spacing[1]};
|
||||||
|
} else if (spacing.length === 4) {
|
||||||
|
return {l: spacing[0], r: spacing[1], t: spacing[2], b: spacing[3]};
|
||||||
|
}
|
||||||
|
} else if (typeof spacing === 'object') {
|
||||||
|
return {l: spacing.l || 0, r: spacing.r || 0, t: spacing.t || 0, b: spacing.b || 0};
|
||||||
|
} else {
|
||||||
|
return {l:0, r:0, t:0, b:0};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
clay.draw = function(size, fn, )
|
||||||
|
{
|
||||||
|
layout.reset();
|
||||||
|
boxes = [];
|
||||||
|
var root = layout.item({
|
||||||
|
size:size,
|
||||||
|
contain: layout.contain.row,
|
||||||
|
});
|
||||||
|
root_item = root;
|
||||||
|
root_config = Object.assign({}, clay_base);
|
||||||
|
boxes.push({
|
||||||
|
id:root,
|
||||||
|
config:root_config
|
||||||
|
});
|
||||||
|
fn();
|
||||||
|
layout.run();
|
||||||
|
|
||||||
|
// Adjust bounding boxes for padding
|
||||||
|
for (var i = 0; i < boxes.length; i++) {
|
||||||
|
var box = boxes[i];
|
||||||
|
box.content = layout.get_rect(box.id);
|
||||||
|
box.boundingbox = Object.assign({}, box.content);
|
||||||
|
|
||||||
|
var padding = clay.normalizeSpacing(box.config.padding || 0);
|
||||||
|
if (padding.l || padding.r || padding.t || padding.b) {
|
||||||
|
// Adjust the boundingbox to include the padding
|
||||||
|
box.boundingbox.x -= padding.l;
|
||||||
|
box.boundingbox.y -= padding.t;
|
||||||
|
box.boundingbox.width += padding.l + padding.r;
|
||||||
|
box.boundingbox.height += padding.t + padding.b;
|
||||||
|
}
|
||||||
|
box.marginbox = Object.assign({}, box.content);
|
||||||
|
var margin = clay.normalizeSpacing(box.config.margin || 0);
|
||||||
|
box.marginbox.x -= margin.l;
|
||||||
|
box.marginbox.y -= margin.t;
|
||||||
|
box.marginbox.width += margin.l+margin.r;
|
||||||
|
box.marginbox.height += margin.t+margin.b;
|
||||||
|
box.content.y *= -1;
|
||||||
|
box.boundingbox.y *= -1
|
||||||
|
box.content.anchor_y = 1;
|
||||||
|
box.boundingbox.anchor_y = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return boxes;
|
||||||
|
}
|
||||||
|
|
||||||
|
var last_config;
|
||||||
|
|
||||||
|
function create_view_fn(base_config)
|
||||||
|
{
|
||||||
|
var base = Object.assign(Object.create(clay_base), base_config);
|
||||||
|
return function(config = {}, fn) {
|
||||||
|
config.__proto__ = base;
|
||||||
|
var item = add_item(config);
|
||||||
|
|
||||||
|
var prev_item = root_item;
|
||||||
|
var prev_config = root_config;
|
||||||
|
root_item = item;
|
||||||
|
root_config = config;
|
||||||
|
root_config._childIndex = 0; // Initialize child index
|
||||||
|
fn?.();
|
||||||
|
root_item = prev_item;
|
||||||
|
root_config = prev_config;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
clay.vstack = create_view_fn({
|
||||||
|
contain: layout.contain.column | layout.contain.start,
|
||||||
|
});
|
||||||
|
|
||||||
|
clay.hstack = create_view_fn({
|
||||||
|
contain: layout.contain.row | layout.contain.start,
|
||||||
|
});
|
||||||
|
|
||||||
|
clay.spacer = create_view_fn({
|
||||||
|
behave: layout.behave.hfill | layout.behave.vfill
|
||||||
|
});
|
||||||
|
|
||||||
|
function image_size(img)
|
||||||
|
{
|
||||||
|
return [img.rect[2]*img.texture.width, img.rect[3]*img.texture.height];
|
||||||
|
}
|
||||||
|
|
||||||
|
var add_item = function(config)
|
||||||
|
{
|
||||||
|
// Normalize the child's margin
|
||||||
|
var margin = clay.normalizeSpacing(config.margin || 0);
|
||||||
|
var padding = clay.normalizeSpacing(config.padding || 0);
|
||||||
|
var childGap = root_config.child_gap || 0;
|
||||||
|
|
||||||
|
// Adjust for child_gap
|
||||||
|
if (root_config._childIndex > 0) {
|
||||||
|
var parentContain = root_config.contain || 0;
|
||||||
|
var isVStack = (parentContain & layout.contain.column) !== 0;
|
||||||
|
var isHStack = (parentContain & layout.contain.row) !== 0;
|
||||||
|
|
||||||
|
if (isVStack) {
|
||||||
|
margin.t += childGap;
|
||||||
|
} else if (isHStack) {
|
||||||
|
margin.l += childGap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var use_config = Object.create(config);
|
||||||
|
|
||||||
|
use_config.margin = {
|
||||||
|
t: margin.t+padding.t,
|
||||||
|
b: margin.b+padding.b,
|
||||||
|
r:margin.r+padding.r,
|
||||||
|
l:margin.l+padding.l
|
||||||
|
};
|
||||||
|
|
||||||
|
var item = layout.item(use_config);
|
||||||
|
boxes.push({
|
||||||
|
id:item,
|
||||||
|
config:use_config
|
||||||
|
});
|
||||||
|
layout.insert(root_item,item);
|
||||||
|
|
||||||
|
// Increment the parent's child index
|
||||||
|
root_config._childIndex++;
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
clay.image = function(path, config = {})
|
||||||
|
{
|
||||||
|
config.__proto__ = clay_base;
|
||||||
|
config.image = path;
|
||||||
|
var image = game.texture(path);
|
||||||
|
config.size ??= [image.texture.width, image.texture.height];
|
||||||
|
add_item(config);
|
||||||
|
}
|
||||||
|
|
||||||
|
clay.text = function(str, config = {})
|
||||||
|
{
|
||||||
|
config.__proto__ = clay_base;
|
||||||
|
var tsize = render.text_size(str, config.font);
|
||||||
|
config.size = config.size.map((x,i) => Math.max(x, tsize[i]));
|
||||||
|
add_item(config);
|
||||||
|
config.text = str;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
For a given size,
|
||||||
|
the layout engine should "see" size + margin
|
||||||
|
but its interior content should "see" size - padding
|
||||||
|
hence, the layout box should be size-padding, with margin of margin+padding
|
||||||
|
*/
|
||||||
|
|
||||||
|
var button_base = Object.assign(Object.create(clay_base), {
|
||||||
|
padding:0,
|
||||||
|
hovered:{
|
||||||
|
}
|
||||||
|
});
|
||||||
|
clay.button = function(str, action, config = {})
|
||||||
|
{
|
||||||
|
config.__proto__ = button_base;
|
||||||
|
config.size = render.text_size(str,config.font);
|
||||||
|
add_item(config);
|
||||||
|
config.text = str;
|
||||||
|
config.action = action;
|
||||||
|
}
|
||||||
|
|
||||||
|
layout.draw_commands = function(cmds, pos = [0,0])
|
||||||
|
{
|
||||||
|
var mousepos = input.mouse.screenpos();
|
||||||
|
for (var cmd of cmds) {
|
||||||
|
cmd.boundingbox.x += pos.x;
|
||||||
|
cmd.boundingbox.y += pos.y;
|
||||||
|
cmd.content.x += pos.x;
|
||||||
|
cmd.content.y += pos.y;
|
||||||
|
var config = cmd.config;
|
||||||
|
if (config.hovered && geometry.rect_point_inside(cmd.content, mousepos)) {
|
||||||
|
config.hovered.__proto__ = config;
|
||||||
|
config = config.hovered;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (config.background_image)
|
||||||
|
if (render.slice)
|
||||||
|
render.slice9(config.background_image, cmd.boundingbox, config.slice, config.background_color);
|
||||||
|
else
|
||||||
|
render.image(config.background_image, cmd.boundingbox, 0, config.color);
|
||||||
|
else if (config.background_color)
|
||||||
|
render.rectangle(cmd.boundingbox, config.background_color);
|
||||||
|
|
||||||
|
if (config.text)
|
||||||
|
render.text(config.text, cmd.content, config.font, config.font_size, config.color);
|
||||||
|
if (config.image)
|
||||||
|
render.image(config.image, cmd.content, 0, config.color);
|
||||||
|
|
||||||
|
render.rectangle(cmd.content, [1,0,0,0]);
|
||||||
|
// render.rectangle(cmd.boundingbox, [0,1,0,0.1]);
|
||||||
|
// render.rectangle(cmd.marginbox, [0,0,1,0.1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
this.hud = function () {
|
this.hud = function () {
|
||||||
mum.label("No game yet! Make game.js to get started!", {
|
layout.draw_commands(clay.draw([], _ => {
|
||||||
pos: game.size.scale(0.5),
|
clay.text("No game yet! Make game.js to get started!");
|
||||||
anchor: [0.5, 0.5],
|
}));
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -76,20 +76,6 @@ game.engine_start = function (s) {
|
||||||
camera.size = game.size;
|
camera.size = game.size;
|
||||||
gamestate.camera = camera;
|
gamestate.camera = camera;
|
||||||
|
|
||||||
prosperon.hudcam = prosperon.make_camera();
|
|
||||||
var hudcam = prosperon.hudcam;
|
|
||||||
hudcam.near = 0;
|
|
||||||
hudcam.size = camera.size;
|
|
||||||
hudcam.mode = "keep";
|
|
||||||
hudcam.break = "fit";
|
|
||||||
|
|
||||||
prosperon.appcam = prosperon.make_camera();
|
|
||||||
var appcam = prosperon.appcam;
|
|
||||||
appcam.near = 0;
|
|
||||||
appcam.size = window.size;
|
|
||||||
appcam.transform.pos = [window.size.x, window.size.y, -100];
|
|
||||||
prosperon.screencolor = render.screencolor();
|
|
||||||
|
|
||||||
globalThis.imgui = render.imgui_init();
|
globalThis.imgui = render.imgui_init();
|
||||||
|
|
||||||
s();
|
s();
|
||||||
|
@ -110,22 +96,6 @@ game.engine_start = function (s) {
|
||||||
count: 6,
|
count: 6,
|
||||||
};
|
};
|
||||||
|
|
||||||
shape.flipquad = {
|
|
||||||
pos: os.make_buffer([
|
|
||||||
0, 0, 0,
|
|
||||||
0, 1, 0,
|
|
||||||
1, 0, 0,
|
|
||||||
1, 1, 0], 0),
|
|
||||||
verts: 4,
|
|
||||||
uv: os.make_buffer([
|
|
||||||
0, 1,
|
|
||||||
0, 0,
|
|
||||||
1, 1,
|
|
||||||
1, 0], 2),
|
|
||||||
index: os.make_buffer([0, 1, 2, 2, 1, 3], 1),
|
|
||||||
count: 6,
|
|
||||||
};
|
|
||||||
|
|
||||||
shape.triangle = {
|
shape.triangle = {
|
||||||
pos: os.make_buffer([0, 0, 0, 0.5, 1, 0, 1, 0, 0], 0),
|
pos: os.make_buffer([0, 0, 0, 0.5, 1, 0, 1, 0, 0], 0),
|
||||||
uv: os.make_buffer([0, 0, 0.5, 1, 1, 0], 2),
|
uv: os.make_buffer([0, 0, 0.5, 1, 1, 0], 2),
|
||||||
|
@ -254,7 +224,7 @@ var sheetsize = 1024;
|
||||||
function pack_into_sheet(images)
|
function pack_into_sheet(images)
|
||||||
{
|
{
|
||||||
if (!Array.isArray(images)) images = [images];
|
if (!Array.isArray(images)) images = [images];
|
||||||
if (images[0].texture.width > 300 && images[0].texture.height > 300) return;
|
if (images[0].texture.width > 1 && images[0].texture.height > 1) return;
|
||||||
sheet_frames = sheet_frames.concat(images);
|
sheet_frames = sheet_frames.concat(images);
|
||||||
var sizes = sheet_frames.map(x => [x.rect[2]*x.texture.width, x.rect[3]*x.texture.height]);
|
var sizes = sheet_frames.map(x => [x.rect[2]*x.texture.width, x.rect[3]*x.texture.height]);
|
||||||
var pos = os.rectpack(sheetsize, sheetsize, sizes);
|
var pos = os.rectpack(sheetsize, sheetsize, sizes);
|
||||||
|
@ -483,10 +453,13 @@ var Register = {
|
||||||
|
|
||||||
if (!flush) {
|
if (!flush) {
|
||||||
prosperon[name] = function (...args) {
|
prosperon[name] = function (...args) {
|
||||||
|
profile.report(name);
|
||||||
fns.forEach(fn => fn(...args));
|
fns.forEach(fn => fn(...args));
|
||||||
|
profile.endreport(name);
|
||||||
};
|
};
|
||||||
} else
|
} else
|
||||||
prosperon[name] = function (...args) {
|
prosperon[name] = function (...args) {
|
||||||
|
profile.report(name);
|
||||||
var layer = undefined;
|
var layer = undefined;
|
||||||
for (var fn of fns) {
|
for (var fn of fns) {
|
||||||
if (layer !== fn.layer) {
|
if (layer !== fn.layer) {
|
||||||
|
@ -495,6 +468,7 @@ var Register = {
|
||||||
}
|
}
|
||||||
fn();
|
fn();
|
||||||
}
|
}
|
||||||
|
profile.endreport(name);
|
||||||
};
|
};
|
||||||
|
|
||||||
prosperon[name].fns = fns;
|
prosperon[name].fns = fns;
|
||||||
|
@ -516,6 +490,7 @@ Register.add_cb("gui", true);
|
||||||
Register.add_cb("hud", true, render.flush);
|
Register.add_cb("hud", true, render.flush);
|
||||||
Register.add_cb("draw", true, render.flush);
|
Register.add_cb("draw", true, render.flush);
|
||||||
Register.add_cb("imgui", true, render.flush);
|
Register.add_cb("imgui", true, render.flush);
|
||||||
|
Register.add_cb("app", true, render.flush);
|
||||||
|
|
||||||
var Event = {
|
var Event = {
|
||||||
events: {},
|
events: {},
|
||||||
|
@ -596,8 +571,7 @@ function world_start() {
|
||||||
}
|
}
|
||||||
|
|
||||||
global.mixin("scripts/physics");
|
global.mixin("scripts/physics");
|
||||||
global.mixin("scripts/widget");
|
global.mixin("scripts/layout");
|
||||||
global.mixin("scripts/mum");
|
|
||||||
|
|
||||||
window.title = `Prosperon v${prosperon.version}`;
|
window.title = `Prosperon v${prosperon.version}`;
|
||||||
window.size = [500, 500];
|
window.size = [500, 500];
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
var unit_transform = os.make_transform();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Anatomy of rendering an image
|
Anatomy of rendering an image
|
||||||
render.image(path)
|
render.image(path)
|
||||||
|
@ -222,16 +224,10 @@ render.face_map = face_map;
|
||||||
render.compare = compare;
|
render.compare = compare;
|
||||||
render.blendfactor = blendfactor;
|
render.blendfactor = blendfactor;
|
||||||
|
|
||||||
render.use_pipeline = function use_pipeline(pipeline)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
var pipe_shaders = new WeakMap();
|
var pipe_shaders = new WeakMap();
|
||||||
|
|
||||||
// Uses the shader with the specified pipeline. If none specified, uses the base pipeline
|
// Uses the shader with the specified pipeline. If none specified, uses the base pipeline
|
||||||
render.use_shader = function use_shader(shader, pipeline) {
|
render.use_shader = function use_shader(shader, pipeline = base_pipeline) {
|
||||||
pipeline ??= base_pipeline;
|
|
||||||
if (typeof shader === "string") shader = make_shader(shader);
|
if (typeof shader === "string") shader = make_shader(shader);
|
||||||
if (cur.shader === shader) return;
|
if (cur.shader === shader) return;
|
||||||
|
|
||||||
|
@ -352,16 +348,6 @@ function set_global_uni(uni, stage) {
|
||||||
uni_globals[uni.name]?.(stage, uni.slot);
|
uni_globals[uni.name]?.(stage, uni.slot);
|
||||||
}
|
}
|
||||||
|
|
||||||
var setcam = render.set_camera;
|
|
||||||
render.set_camera = function (cam) {
|
|
||||||
if (nextflush) {
|
|
||||||
nextflush();
|
|
||||||
nextflush = undefined;
|
|
||||||
}
|
|
||||||
delete cur.shader;
|
|
||||||
setcam(cam);
|
|
||||||
};
|
|
||||||
|
|
||||||
var shader_cache = {};
|
var shader_cache = {};
|
||||||
var shader_times = {};
|
var shader_times = {};
|
||||||
|
|
||||||
|
@ -531,11 +517,11 @@ var shader_unisize = {
|
||||||
|
|
||||||
function shader_globals(shader) {
|
function shader_globals(shader) {
|
||||||
for (var p in shader.vs.unimap) set_global_uni(shader.vs.unimap[p], 0);
|
for (var p in shader.vs.unimap) set_global_uni(shader.vs.unimap[p], 0);
|
||||||
|
|
||||||
for (var p in shader.fs.unimap) set_global_uni(shader.fs.unimap[p], 1);
|
for (var p in shader.fs.unimap) set_global_uni(shader.fs.unimap[p], 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
function shader_apply_material(shader, material = {}, old = {}) {
|
function shader_apply_material(shader, material = {}, old = {}) {
|
||||||
|
render.setpipeline(cur.pipeline);
|
||||||
for (var p in shader.vs.unimap) {
|
for (var p in shader.vs.unimap) {
|
||||||
if (!(p in material)) continue;
|
if (!(p in material)) continue;
|
||||||
if (material[p] === old[p]) continue;
|
if (material[p] === old[p]) continue;
|
||||||
|
@ -719,6 +705,7 @@ render.draw_gizmos = true;
|
||||||
|
|
||||||
render.buckets = [];
|
render.buckets = [];
|
||||||
render.sprites = function render_sprites() {
|
render.sprites = function render_sprites() {
|
||||||
|
profile.report("sprites");
|
||||||
profile.report("drawing");
|
profile.report("drawing");
|
||||||
render.use_shader(spritessboshader);
|
render.use_shader(spritessboshader);
|
||||||
var buckets = component.sprite_buckets();
|
var buckets = component.sprite_buckets();
|
||||||
|
@ -734,6 +721,7 @@ render.sprites = function render_sprites() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
profile.endreport("drawing");
|
profile.endreport("drawing");
|
||||||
|
profile.endreport("sprites");
|
||||||
};
|
};
|
||||||
|
|
||||||
render.circle = function render_circle(pos, radius, color, inner_radius = 1) {
|
render.circle = function render_circle(pos, radius, color, inner_radius = 1) {
|
||||||
|
@ -783,6 +771,7 @@ render.forceflush = function()
|
||||||
{
|
{
|
||||||
if (nextflush) nextflush();
|
if (nextflush) nextflush();
|
||||||
nextflush = undefined;
|
nextflush = undefined;
|
||||||
|
cur.shader = undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
var poly_cache = [];
|
var poly_cache = [];
|
||||||
|
@ -821,7 +810,7 @@ render.line = function render_line(points, color = Color.white, thickness = 1) {
|
||||||
var poly = poly_e();
|
var poly = poly_e();
|
||||||
var dist = vector.distance(a, b);
|
var dist = vector.distance(a, b);
|
||||||
poly.transform.move(vector.midpoint(a, b));
|
poly.transform.move(vector.midpoint(a, b));
|
||||||
poly.transform.rotate([0, 0, -1], vector.angle([b.x - a.x, b.y - a.y]));
|
poly.transform.rotate([0, 0, 1], vector.angle([b.x - a.x, b.y - a.y]));
|
||||||
poly.transform.scale = [dist, thickness, 1];
|
poly.transform.scale = [dist, thickness, 1];
|
||||||
poly.color = color;
|
poly.color = color;
|
||||||
}
|
}
|
||||||
|
@ -854,17 +843,15 @@ render.coordinate = function render_coordinate(pos, size, color) {
|
||||||
render.point(pos, 2, color);
|
render.point(pos, 2, color);
|
||||||
};
|
};
|
||||||
|
|
||||||
render.boundingbox = function render_boundingbox(bb, color = Color.white) {
|
|
||||||
render.line(bbox.topoints(bb).wrapped(1), color);
|
|
||||||
};
|
|
||||||
|
|
||||||
var queued_shader;
|
var queued_shader;
|
||||||
var queued_pipe;
|
var queued_pipe;
|
||||||
render.rectangle = function render_rectangle(lowerleft, upperright, color, shader = polyssboshader, pipe = base_pipeline) {
|
render.rectangle = function render_rectangle(rect, color, shader = polyssboshader, pipe = base_pipeline) {
|
||||||
var transform = os.make_transform();
|
var transform = os.make_transform();
|
||||||
var wh = [upperright.x - lowerleft.x, upperright.y - lowerleft.y];
|
var wh = [rect.width, rect.height];
|
||||||
var poly = poly_e();
|
var poly = poly_e();
|
||||||
poly.transform.move(vector.midpoint(lowerleft, upperright));
|
var pos = [rect.x,rect.y].add([rect.width,rect.height].scale(0.5));
|
||||||
|
pos = pos.sub([rect.width,rect.height].scale([rect.anchor_x,rect.anchor_y]));
|
||||||
|
poly.transform.move(pos);
|
||||||
poly.transform.scale = [wh.x, wh.y, 1];
|
poly.transform.scale = [wh.x, wh.y, 1];
|
||||||
poly.color = color;
|
poly.color = color;
|
||||||
|
|
||||||
|
@ -873,23 +860,6 @@ render.rectangle = function render_rectangle(lowerleft, upperright, color, shade
|
||||||
check_flush(flush_poly);
|
check_flush(flush_poly);
|
||||||
};
|
};
|
||||||
|
|
||||||
// brect is x,y,width,height, with x,y in the upper left corner
|
|
||||||
render.brect = function(brect, color = Color.white)
|
|
||||||
{
|
|
||||||
render.rectangle([brect.x,brect.y], [brect.x+brect.width, brect.y+brect.height], color);
|
|
||||||
}
|
|
||||||
|
|
||||||
// brect is x,y,width,height, with x,y in the upper left corner
|
|
||||||
render.urect = function(brect, color = Color.white)
|
|
||||||
{
|
|
||||||
render.rectangle([brect.x,brect.y], [brect.x+brect.width, brect.y], color);
|
|
||||||
}
|
|
||||||
|
|
||||||
render.rect = function(rect, color, shader, pipe)
|
|
||||||
{
|
|
||||||
render.rectangle([rect.x-rect.w/2, rect.y-rect.h/2], [rect.x+rect.w/2, rect.y+rect.h/2], color, shader, pipe);
|
|
||||||
}
|
|
||||||
|
|
||||||
render.box = function render_box(pos, wh, color = Color.white) {
|
render.box = function render_box(pos, wh, color = Color.white) {
|
||||||
var poly = poly_e();
|
var poly = poly_e();
|
||||||
poly.transform.move(pos);
|
poly.transform.move(pos);
|
||||||
|
@ -902,11 +872,15 @@ render.window = function render_window(pos, wh, color) {
|
||||||
render.box(pos.add(wh.scale(0.5)), wh, color);
|
render.box(pos.add(wh.scale(0.5)), wh, color);
|
||||||
};
|
};
|
||||||
|
|
||||||
render.text = function (str, pos, font = cur_font, size = 0, color = Color.white, wrap = -1) {
|
render.text = function (str, rect, font = cur_font, size = 0, color = Color.white, wrap = -1, ) {
|
||||||
if (typeof font === 'string')
|
if (typeof font === 'string')
|
||||||
font = render.get_font(font);
|
font = render.get_font(font);
|
||||||
|
|
||||||
if (!font) return;
|
if (!font) return;
|
||||||
|
var pos = [rect.x,rect.y];
|
||||||
|
pos.y -= font.descent;
|
||||||
|
if (rect.anchor_y)
|
||||||
|
pos.y -= rect.anchor_y*(font.ascent-font.descent);
|
||||||
gui.text(str, pos, size, color, wrap, font); // this puts text into buffer
|
gui.text(str, pos, size, color, wrap, font); // this puts text into buffer
|
||||||
cur_font = font;
|
cur_font = font;
|
||||||
check_flush(render.flush_text);
|
check_flush(render.flush_text);
|
||||||
|
@ -1008,38 +982,38 @@ render.invertmask = function()
|
||||||
render.draw(shape.quad);
|
render.draw(shape.quad);
|
||||||
}
|
}
|
||||||
|
|
||||||
render.mask = function mask(tex, pos, scale, rotation = 0, ref = 1)
|
render.mask = function mask(image, pos, scale, rotation = 0, ref = 1)
|
||||||
{
|
{
|
||||||
if (typeof tex === 'string')
|
if (typeof image === 'string')
|
||||||
tex = game.texture(tex);
|
image = game.texture(image);
|
||||||
|
|
||||||
|
var tex = image.texture;
|
||||||
|
|
||||||
|
if (scale) scale = sacle.div([tex.width,tex.height]);
|
||||||
|
else scale = vector.v3one;
|
||||||
|
|
||||||
var pipe = stencil_writer(ref);
|
var pipe = stencil_writer(ref);
|
||||||
render.use_shader('shaders/sprite.cg', pipe);
|
render.use_shader('shaders/sprite.cg', pipe);
|
||||||
var t = os.make_transform();
|
var t = os.make_transform();
|
||||||
t.pos = pos;
|
t.trs(pos, undefined,scale);
|
||||||
t.scale = scale.div(tex.dimensions);
|
|
||||||
set_model(t);
|
set_model(t);
|
||||||
render.use_mat({
|
render.use_mat({
|
||||||
diffuse:tex.texture,
|
diffuse:image.texture,
|
||||||
rect: tex.rect,
|
rect: image.rect,
|
||||||
shade: Color.white
|
shade: Color.white
|
||||||
});
|
});
|
||||||
render.draw(shape.quad);
|
render.draw(shape.quad);
|
||||||
}
|
}
|
||||||
|
|
||||||
render.image = function image(image, pos, scale, rotation = 0, color = Color.white) {
|
render.image = function image(image, rect = [0,0], rotation = 0, color = Color.white) {
|
||||||
if (typeof image === "string")
|
if (typeof image === "string")
|
||||||
image = game.texture(image);
|
image = game.texture(image);
|
||||||
|
|
||||||
var tex = image.texture;
|
var tex = image.texture;
|
||||||
|
|
||||||
if (scale)
|
|
||||||
scale = scale.div([tex.width, tex.height]);
|
|
||||||
else
|
|
||||||
scale = vector.v3one;
|
|
||||||
|
|
||||||
if (!tex) return;
|
if (!tex) return;
|
||||||
|
|
||||||
|
var size = [rect.width ? rect.width : tex.width, rect.height ? rect.height : tex.height];
|
||||||
|
|
||||||
if (!lasttex) {
|
if (!lasttex) {
|
||||||
check_flush(flush_img);
|
check_flush(flush_img);
|
||||||
lasttex = tex;
|
lasttex = tex;
|
||||||
|
@ -1051,30 +1025,26 @@ render.image = function image(image, pos, scale, rotation = 0, color = Color.whi
|
||||||
}
|
}
|
||||||
|
|
||||||
var e = img_e();
|
var e = img_e();
|
||||||
e.transform.trs(pos, undefined, scale);
|
var pos = [rect.x,rect.y].sub(size.scale([rect.anchor_x, rect.anchor_y]));
|
||||||
|
e.transform.trs(pos, undefined, size.div([tex.width,tex.height]));
|
||||||
e.image = image;
|
e.image = image;
|
||||||
e.shade = color;
|
e.shade = color;
|
||||||
|
|
||||||
return;
|
return;
|
||||||
var bb = {};
|
|
||||||
bb.b = pos.y;
|
|
||||||
bb.l = pos.x;
|
|
||||||
bb.t = pos.y + tex.height * scale;
|
|
||||||
bb.r = pos.x + tex.width * scale;
|
|
||||||
return bb;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// pos is the lower left corner, scale is the width and height
|
// pos is the lower left corner, scale is the width and height
|
||||||
render.slice9 = function (image, pos, bb, scale = [tex.width, tex.height], color = Color.white) {
|
render.slice9 = function (image, rect = [0,0], slice = 0, color = Color.white) {
|
||||||
if (typeof image === 'string')
|
if (typeof image === 'string')
|
||||||
image = game.texture(image);
|
image = game.texture(image);
|
||||||
|
|
||||||
var tex = image.texture;
|
var tex = image.texture;
|
||||||
|
var size = [rect.width ? rect.width : tex.width, rect.height ? rect.height : tex.height];
|
||||||
var t = os.make_transform();
|
var t = os.make_transform();
|
||||||
t.pos = pos;
|
t.pos = pos;
|
||||||
t.scale = [scale.x / tex.width, scale.y / tex.height, 1];
|
t.scale = size.div([tex.width,tex.height]);
|
||||||
var border;
|
slice = clay.normalizeSpacing(slice);
|
||||||
if (typeof bb === "number") border = [bb / tex.width, bb / tex.height, bb / tex.width, bb / tex.height];
|
var border = [slice.l / tex.width, slice.b / tex.height, slice.r / tex.width, slice.t / tex.height];
|
||||||
else border = [bb.l / tex.width, bb.b / tex.height, bb.r / tex.width, bb.t / tex.height];
|
|
||||||
|
|
||||||
render.use_shader(slice9shader);
|
render.use_shader(slice9shader);
|
||||||
set_model(t);
|
set_model(t);
|
||||||
|
@ -1083,7 +1053,7 @@ render.slice9 = function (image, pos, bb, scale = [tex.width, tex.height], color
|
||||||
diffuse: tex,
|
diffuse: tex,
|
||||||
rect: [0, 0, 1, 1],
|
rect: [0, 0, 1, 1],
|
||||||
border: border,
|
border: border,
|
||||||
scale: [scale.x / tex.width, scale.y / tex.height],
|
scale: [size.x / tex.width, size.y / tex.height],
|
||||||
});
|
});
|
||||||
|
|
||||||
render.draw(shape.quad);
|
render.draw(shape.quad);
|
||||||
|
@ -1142,8 +1112,7 @@ render.draw = function render_draw(mesh, ssbo, inst = 1, e_start = 0) {
|
||||||
profile.endreport("gpu_draw");
|
profile.endreport("gpu_draw");
|
||||||
};
|
};
|
||||||
|
|
||||||
// Returns an array in the form of [left, bottom, right, top] in pixels of the camera to render to
|
// Camera viewport is a rectangle with the bottom left corner defined as x,y. Units are pixels on the window.
|
||||||
// Camera viewport is [left,bottom,width,height] in relative values
|
|
||||||
function camviewport() {
|
function camviewport() {
|
||||||
var aspect = (((this.viewport[2] - this.viewport[0]) / (this.viewport[3] - this.viewport[1])) * window.size.x) / window.size.y;
|
var aspect = (((this.viewport[2] - this.viewport[0]) / (this.viewport[3] - this.viewport[1])) * window.size.x) / window.size.y;
|
||||||
var raspect = this.size.x / this.size.y;
|
var raspect = this.size.x / this.size.y;
|
||||||
|
@ -1162,20 +1131,45 @@ function camviewport() {
|
||||||
switch (usemode) {
|
switch (usemode) {
|
||||||
case "stretch":
|
case "stretch":
|
||||||
case "expand":
|
case "expand":
|
||||||
return [0, 0, window.size.x, window.size.y];
|
return {
|
||||||
|
x: 0,
|
||||||
|
y: 0,
|
||||||
|
width: window.size.x,
|
||||||
|
height: window.size.y
|
||||||
|
};
|
||||||
case "keep":
|
case "keep":
|
||||||
return [left, bottom, left + this.size.x, bottom + this.size.y];
|
return {
|
||||||
|
x: left,
|
||||||
|
y: bottom,
|
||||||
|
width:left+this.size.x,
|
||||||
|
height:bottom+this.size.y
|
||||||
|
}
|
||||||
case "height":
|
case "height":
|
||||||
var ret = [left, 0, this.size.x * (window.size.y / this.size.y), window.size.y];
|
var ret = {
|
||||||
ret[0] = (window.size.x - (ret[2] - ret[0])) / 2;
|
x:left,
|
||||||
|
y:0,
|
||||||
|
width:this.size.x*(window.size.y/this.size.y),
|
||||||
|
height:window.size.y
|
||||||
|
};
|
||||||
|
ret.x = (window.size.x - (ret.width-ret.x))/2;
|
||||||
return ret;
|
return ret;
|
||||||
case "width":
|
case "width":
|
||||||
var ret = [0, bottom, window.size.x, this.size.y * (window.size.x / this.size.x)];
|
var ret = {
|
||||||
ret[1] = (window.size.y - (ret[3] - ret[1])) / 2;
|
x:0,
|
||||||
|
y:bottom,
|
||||||
|
width:window.size.x,
|
||||||
|
height:this.size.y*(window.size.x/this.size.x)
|
||||||
|
};
|
||||||
|
ret.y = (window.size.y - (ret.height-ret.y))/2;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
return [0, 0, window.size.x, window.size.y];
|
return {
|
||||||
|
x:0,
|
||||||
|
y:0,
|
||||||
|
width:window.size.x,
|
||||||
|
height:window.size.y
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// pos is pixels on the screen, lower left[0,0]
|
// pos is pixels on the screen, lower left[0,0]
|
||||||
|
@ -1183,8 +1177,8 @@ function camscreen2world(pos) {
|
||||||
var view = this.screen2cam(pos);
|
var view = this.screen2cam(pos);
|
||||||
view.x *= this.size.x;
|
view.x *= this.size.x;
|
||||||
view.y *= this.size.y;
|
view.y *= this.size.y;
|
||||||
view = view.sub([this.size.x / 2, this.size.y / 2]);
|
|
||||||
view = view.add(this.pos.xy);
|
view = view.add(this.pos.xy);
|
||||||
|
view = view.scale(this.transform.scale);
|
||||||
return view;
|
return view;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1197,11 +1191,12 @@ camscreen2world.doc = "Convert a view position for a camera to world.";
|
||||||
|
|
||||||
// return camera coordinates given a screen position
|
// return camera coordinates given a screen position
|
||||||
function screen2cam(pos) {
|
function screen2cam(pos) {
|
||||||
|
var winsize = window.size.slice();
|
||||||
var viewport = this.view();
|
var viewport = this.view();
|
||||||
var width = viewport[2];
|
var viewpos = pos.sub([viewport.x,viewport.y]);
|
||||||
var height = viewport[3];
|
viewpos = viewpos.div([viewport.width,viewport.height]);
|
||||||
var viewpos = pos.sub([viewport[0], viewport[1]]);
|
viewpos.y += 1;
|
||||||
return viewpos.div([width, height]);
|
return viewpos;
|
||||||
}
|
}
|
||||||
|
|
||||||
function camextents() {
|
function camextents() {
|
||||||
|
@ -1224,21 +1219,17 @@ prosperon.gizmos = function () {
|
||||||
|
|
||||||
prosperon.make_camera = function () {
|
prosperon.make_camera = function () {
|
||||||
var cam = world.spawn();
|
var cam = world.spawn();
|
||||||
cam.near = -1;
|
cam.near = 1;
|
||||||
cam.far = 1000;
|
cam.far = -1000;
|
||||||
cam.ortho = true;
|
cam.ortho = true;
|
||||||
cam.viewport = [0, 0, 1, 1];
|
cam.viewport = [0, 0, 1, 1]; // normalized screen coordinates of where to draw
|
||||||
cam.size = window.size.slice(); // The render size of this camera in pixels
|
cam.size = window.size.slice(); // The render size of this camera in pixels
|
||||||
// In ortho mode, this determines how many pixels it will see
|
// In ortho mode, this determines how many pixels it will see
|
||||||
cam.mode = "stretch";
|
cam.mode = "stretch";
|
||||||
cam.screen2world = camscreen2world;
|
cam.screen2world = camscreen2world;
|
||||||
cam.screen2cam = screen2cam;
|
cam.screen2cam = screen2cam;
|
||||||
cam.extents = camextents;
|
cam.extents = camextents;
|
||||||
cam.mousepos = function () {
|
|
||||||
return this.screen2world(input.mouse.screenpos());
|
|
||||||
};
|
|
||||||
cam.view = camviewport;
|
cam.view = camviewport;
|
||||||
cam.offscreen = false;
|
|
||||||
return cam;
|
return cam;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1323,13 +1314,8 @@ var imgui_fn = function () {
|
||||||
render.imgui_end();
|
render.imgui_end();
|
||||||
};
|
};
|
||||||
|
|
||||||
prosperon.postvals = {};
|
|
||||||
prosperon.postvals.offset_amt = 300;
|
|
||||||
prosperon.render = function () {
|
|
||||||
profile.report("world");
|
|
||||||
render.set_camera(prosperon.camera);
|
|
||||||
// figure out the highest resolution we can render at that's an integer
|
// figure out the highest resolution we can render at that's an integer
|
||||||
var basesize = prosperon.camera.size.slice();
|
/* var basesize = prosperon.camera.size.slice();
|
||||||
var baseview = prosperon.camera.view();
|
var baseview = prosperon.camera.view();
|
||||||
var wh = [baseview[2]-baseview[0], baseview[3]-baseview[1]];
|
var wh = [baseview[2]-baseview[0], baseview[3]-baseview[1]];
|
||||||
var mult = 1;
|
var mult = 1;
|
||||||
|
@ -1342,65 +1328,52 @@ prosperon.render = function () {
|
||||||
mult--;
|
mult--;
|
||||||
|
|
||||||
prosperon.window_render(basesize.scale(mult));
|
prosperon.window_render(basesize.scale(mult));
|
||||||
profile.report("sprites");
|
*/
|
||||||
|
|
||||||
|
prosperon.render = function () {
|
||||||
|
render.glue_pass();
|
||||||
|
render.set_view(prosperon.camera.transform);
|
||||||
|
render.set_projection_ortho({
|
||||||
|
l:-prosperon.camera.size.x/2,
|
||||||
|
r:prosperon.camera.size.x/2,
|
||||||
|
b:-prosperon.camera.size.y/2,
|
||||||
|
t:prosperon.camera.size.y/2
|
||||||
|
}, prosperon.camera.near,prosperon.camera.far);
|
||||||
|
render.viewport(prosperon.camera.view(), false);
|
||||||
|
|
||||||
if (render.draw_sprites) render.sprites();
|
if (render.draw_sprites) render.sprites();
|
||||||
if (render.draw_particles) draw_emitters();
|
if (render.draw_particles) draw_emitters();
|
||||||
profile.endreport("sprites");
|
|
||||||
profile.report("draws");
|
|
||||||
prosperon.draw();
|
prosperon.draw();
|
||||||
profile.endreport("draws");
|
|
||||||
profile.endreport("world");
|
|
||||||
render.fillmask(0);
|
render.fillmask(0);
|
||||||
prosperon.hudcam.size = prosperon.camera.size.slice();
|
render.forceflush();
|
||||||
prosperon.hudcam.transform.pos = [prosperon.hudcam.size.x / 2, prosperon.hudcam.size.y / 2, -100];
|
|
||||||
prosperon.hudcam.size.y *= -1;
|
|
||||||
render.set_camera(prosperon.hudcam);
|
|
||||||
|
|
||||||
profile.report("hud");
|
|
||||||
if (render.draw_hud) prosperon.hud();
|
|
||||||
render.flush_text();
|
|
||||||
|
|
||||||
render.set_camera(prosperon.camera);
|
|
||||||
//if (render.draw_gizmos && prosperon.gizmos) prosperon.gizmos();
|
|
||||||
render.flush_text();
|
|
||||||
|
|
||||||
render.end_pass();
|
|
||||||
|
|
||||||
profile.endreport("hud");
|
|
||||||
/* draw the image of the game world first */
|
|
||||||
render.glue_pass();
|
|
||||||
profile.report("frame");
|
|
||||||
profile.report("render");
|
|
||||||
profile.report("post process");
|
|
||||||
render.viewport(...prosperon.camera.view());
|
|
||||||
render.use_shader(render.postshader);
|
|
||||||
prosperon.postvals.diffuse = prosperon.screencolor;
|
|
||||||
|
|
||||||
render.use_mat(prosperon.postvals);
|
render.set_projection_ortho({
|
||||||
render.draw(shape.quad);
|
l:0,
|
||||||
//render.draw((os.backend() === "directx" || os.backend() === 'metal') ? shape.flipquad : shape.quad);
|
r:prosperon.camera.size.x,
|
||||||
|
b:-prosperon.camera.size.y,
|
||||||
|
t:0
|
||||||
|
},-1,1);
|
||||||
|
|
||||||
|
render.set_view(unit_transform);
|
||||||
|
if (render.draw_hud) prosperon.hud();
|
||||||
|
render.forceflush();
|
||||||
|
|
||||||
profile.endreport("post process");
|
render.set_projection_ortho({
|
||||||
|
l:0,
|
||||||
profile.report("app");
|
r:window.size.x,
|
||||||
|
b:-window.size.y,
|
||||||
// Flush & render
|
t:0
|
||||||
prosperon.appcam.transform.pos = [window.size.x / 2, window.size.y / 2, -100];
|
},-1,1);
|
||||||
prosperon.appcam.size = window.size.slice();
|
render.viewport({
|
||||||
|
t:0,
|
||||||
render.set_camera(prosperon.appcam);
|
height:window.size.y,
|
||||||
render.viewport(...prosperon.appcam.view());
|
width:window.size.x,
|
||||||
// Call gui functions
|
l:0
|
||||||
if (render.draw_gui) prosperon.gui();
|
}, false);
|
||||||
|
prosperon.app();
|
||||||
check_flush();
|
|
||||||
|
|
||||||
profile.endreport("app");
|
|
||||||
|
|
||||||
profile.report("imgui");
|
profile.report("imgui");
|
||||||
|
|
||||||
if (debug.show) imgui_fn();
|
if (debug.show) imgui_fn();
|
||||||
|
|
||||||
profile.endreport("imgui");
|
profile.endreport("imgui");
|
||||||
|
|
||||||
render.end_pass();
|
render.end_pass();
|
||||||
|
|
|
@ -68,7 +68,7 @@ var texteditor = Object.copy(inputpanel, {
|
||||||
src: "NEW FILE",
|
src: "NEW FILE",
|
||||||
|
|
||||||
guibody() {
|
guibody() {
|
||||||
return [Mum.text({ str: `EDITING ${this.src}` }), Mum.text({ str: this.value, caret: this.cursor, offset: [0, -16] })];
|
// TODO: new render here
|
||||||
},
|
},
|
||||||
|
|
||||||
insert_char(char) {
|
insert_char(char) {
|
||||||
|
|
|
@ -1,210 +0,0 @@
|
||||||
var inputpanel = {
|
|
||||||
title: "untitled",
|
|
||||||
toString() {
|
|
||||||
return this.title;
|
|
||||||
},
|
|
||||||
value: "",
|
|
||||||
on: false,
|
|
||||||
pos: [20, window.size.y - 20],
|
|
||||||
wh: [100, 100],
|
|
||||||
anchor: [0, 1],
|
|
||||||
padding: [5, -15],
|
|
||||||
|
|
||||||
gui() {
|
|
||||||
this.win ??= Mum.window({
|
|
||||||
width: this.wh.x,
|
|
||||||
height: this.wh.y,
|
|
||||||
color: Color.black.alpha(0.1),
|
|
||||||
anchor: this.anchor,
|
|
||||||
padding: this.padding,
|
|
||||||
});
|
|
||||||
var itms = this.guibody();
|
|
||||||
if (!Array.isArray(itms)) itms = [itms];
|
|
||||||
if (this.title) this.win.items = [Mum.column({ items: [Mum.text({ str: this.title }), ...itms] })];
|
|
||||||
else this.win.items = itms;
|
|
||||||
|
|
||||||
this.win.draw([100, window.size.y - 50]);
|
|
||||||
},
|
|
||||||
|
|
||||||
guibody() {
|
|
||||||
return [Mum.text({ str: this.value, color: Color.green }), Mum.button({ str: "SUBMIT", action: this.submit.bind(this) })];
|
|
||||||
},
|
|
||||||
|
|
||||||
open() {
|
|
||||||
this.on = true;
|
|
||||||
this.value = "";
|
|
||||||
this.start();
|
|
||||||
this.keycb();
|
|
||||||
},
|
|
||||||
|
|
||||||
start() {},
|
|
||||||
|
|
||||||
close() {
|
|
||||||
player[0].uncontrol(this);
|
|
||||||
this.on = false;
|
|
||||||
if ("on_close" in this) this.on_close();
|
|
||||||
},
|
|
||||||
|
|
||||||
action() {},
|
|
||||||
|
|
||||||
closeonsubmit: true,
|
|
||||||
submit() {
|
|
||||||
if (!this.submit_check()) return;
|
|
||||||
this.action();
|
|
||||||
if (this.closeonsubmit) this.close();
|
|
||||||
},
|
|
||||||
|
|
||||||
submit_check() {
|
|
||||||
return true;
|
|
||||||
},
|
|
||||||
|
|
||||||
keycb() {},
|
|
||||||
|
|
||||||
caret: 0,
|
|
||||||
|
|
||||||
reset_value() {
|
|
||||||
this.value = "";
|
|
||||||
this.caret = 0;
|
|
||||||
},
|
|
||||||
|
|
||||||
input_backspace_pressrep() {
|
|
||||||
this.value = this.value.slice(0, -1);
|
|
||||||
this.keycb();
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
inputpanel.inputs = {};
|
|
||||||
inputpanel.inputs.block = true;
|
|
||||||
|
|
||||||
inputpanel.inputs.post = function () {
|
|
||||||
this.keycb();
|
|
||||||
};
|
|
||||||
|
|
||||||
inputpanel.inputs.char = function (c) {
|
|
||||||
this.value = this.value.slice(0, this.caret) + c + this.value.slice(this.caret);
|
|
||||||
this.caret++;
|
|
||||||
};
|
|
||||||
inputpanel.inputs["C-d"] = function () {
|
|
||||||
this.value = this.value.slice(0, this.caret) + this.value.slice(this.caret + 1);
|
|
||||||
};
|
|
||||||
inputpanel.inputs["C-d"].rep = true;
|
|
||||||
inputpanel.inputs.tab = function () {
|
|
||||||
this.value = input.tabcomplete(this.value, this.assets);
|
|
||||||
this.caret = this.value.length;
|
|
||||||
};
|
|
||||||
inputpanel.inputs.escape = function () {
|
|
||||||
this.close();
|
|
||||||
};
|
|
||||||
inputpanel.inputs["C-b"] = function () {
|
|
||||||
if (this.caret === 0) return;
|
|
||||||
this.caret--;
|
|
||||||
};
|
|
||||||
inputpanel.inputs["C-b"].rep = true;
|
|
||||||
inputpanel.inputs["C-u"] = function () {
|
|
||||||
this.value = this.value.slice(this.caret);
|
|
||||||
this.caret = 0;
|
|
||||||
};
|
|
||||||
inputpanel.inputs["C-f"] = function () {
|
|
||||||
if (this.caret === this.value.length) return;
|
|
||||||
this.caret++;
|
|
||||||
};
|
|
||||||
inputpanel.inputs["C-f"].rep = true;
|
|
||||||
inputpanel.inputs["C-a"] = function () {
|
|
||||||
this.caret = 0;
|
|
||||||
};
|
|
||||||
inputpanel.inputs["C-e"] = function () {
|
|
||||||
this.caret = this.value.length;
|
|
||||||
};
|
|
||||||
inputpanel.inputs.backspace = function () {
|
|
||||||
if (this.caret === 0) return;
|
|
||||||
this.value = this.value.slice(0, this.caret - 1) + this.value.slice(this.caret);
|
|
||||||
this.caret--;
|
|
||||||
};
|
|
||||||
inputpanel.inputs.backspace.rep = true;
|
|
||||||
inputpanel.inputs.enter = function () {
|
|
||||||
this.submit();
|
|
||||||
};
|
|
||||||
|
|
||||||
inputpanel.inputs["C-k"] = function () {
|
|
||||||
this.value = this.value.slice(0, this.caret);
|
|
||||||
};
|
|
||||||
|
|
||||||
inputpanel.inputs.lm = function () {
|
|
||||||
gui.controls.check_submit();
|
|
||||||
};
|
|
||||||
|
|
||||||
var notifypanel = Object.copy(inputpanel, {
|
|
||||||
title: "notification",
|
|
||||||
msg: "Refusing to save. File already exists.",
|
|
||||||
action() {
|
|
||||||
this.close();
|
|
||||||
},
|
|
||||||
|
|
||||||
guibody() {
|
|
||||||
return Mum.column({
|
|
||||||
items: [Mum.text({ str: this.msg }), Mum.button({ str: "OK", action: this.close.bind(this) })],
|
|
||||||
});
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
var gen_notify = function (val, fn) {
|
|
||||||
var panel = Object.create(notifypanel);
|
|
||||||
panel.msg = val;
|
|
||||||
panel.yes = fn;
|
|
||||||
panel.inputs = {};
|
|
||||||
panel.inputs.y = function () {
|
|
||||||
panel.yes();
|
|
||||||
panel.close();
|
|
||||||
};
|
|
||||||
panel.inputs.y.doc = "Confirm yes.";
|
|
||||||
panel.inputs.enter = function () {
|
|
||||||
panel.close();
|
|
||||||
};
|
|
||||||
panel.inputs.enter.doc = "Close.";
|
|
||||||
return panel;
|
|
||||||
};
|
|
||||||
|
|
||||||
var listpanel = Object.copy(inputpanel, {
|
|
||||||
assets: [],
|
|
||||||
allassets: [],
|
|
||||||
mumlist: {},
|
|
||||||
|
|
||||||
submit_check() {
|
|
||||||
if (this.assets.length === 0) return false;
|
|
||||||
|
|
||||||
this.value = this.assets[0];
|
|
||||||
return true;
|
|
||||||
},
|
|
||||||
|
|
||||||
start() {
|
|
||||||
this.assets = this.allassets.slice();
|
|
||||||
this.caret = 0;
|
|
||||||
this.mumlist = [];
|
|
||||||
this.assets.forEach(function (x) {
|
|
||||||
this.mumlist[x] = Mum.text({
|
|
||||||
str: x,
|
|
||||||
action: this.action,
|
|
||||||
color: Color.blue,
|
|
||||||
hovered: { color: Color.red },
|
|
||||||
selectable: true,
|
|
||||||
});
|
|
||||||
}, this);
|
|
||||||
},
|
|
||||||
|
|
||||||
keycb() {
|
|
||||||
if (this.value) this.assets = this.allassets.filter(x => x.startsWith(this.value));
|
|
||||||
else this.assets = this.allassets.slice();
|
|
||||||
for (var m in this.mumlist) this.mumlist[m].hide = true;
|
|
||||||
this.assets.forEach(function (x) {
|
|
||||||
this.mumlist[x].hide = false;
|
|
||||||
}, this);
|
|
||||||
},
|
|
||||||
|
|
||||||
guibody() {
|
|
||||||
var a = [Mum.text({ str: this.value, color: Color.green, caret: this.caret })];
|
|
||||||
var b = a.concat(Object.values(this.mumlist));
|
|
||||||
return Mum.column({ items: b, offset: [0, -10] });
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
return { inputpanel, gen_notify, notifypanel, listpanel };
|
|
|
@ -12,8 +12,8 @@ const HMM_Vec3 vZ = {0.0,0.0,1.0};
|
||||||
|
|
||||||
const HMM_Vec3 vUP = {0,1,0};
|
const HMM_Vec3 vUP = {0,1,0};
|
||||||
const HMM_Vec3 vDOWN = {0,-1,0};
|
const HMM_Vec3 vDOWN = {0,-1,0};
|
||||||
const HMM_Vec3 vFWD = {0,0,1};
|
const HMM_Vec3 vFWD = {0,0,-1};
|
||||||
const HMM_Vec3 vBKWD = {0,0,-1};
|
const HMM_Vec3 vBKWD = {0,0,1};
|
||||||
const HMM_Vec3 vLEFT = {-1,0,0};
|
const HMM_Vec3 vLEFT = {-1,0,0};
|
||||||
const HMM_Vec3 vRIGHT = {1,0,0};
|
const HMM_Vec3 vRIGHT = {1,0,0};
|
||||||
|
|
||||||
|
@ -1231,11 +1231,9 @@ HMM_Mat4 HMM_Orthographic_DX(float l, float r, float b, float t, float near, flo
|
||||||
|
|
||||||
HMM_Mat4 HMM_Orthographic_GL(float l, float r, float b, float t, float near, float far)
|
HMM_Mat4 HMM_Orthographic_GL(float l, float r, float b, float t, float near, float far)
|
||||||
{
|
{
|
||||||
// return HMM_MulM4(HMM_Orthographic_LH_NO(l,r,b,t,near,far), HMM_Scale((HMM_Vec3){1,-1,1}));
|
|
||||||
return HMM_Orthographic_LH_NO(l,r,b,t,near,far);
|
return HMM_Orthographic_LH_NO(l,r,b,t,near,far);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
HMM_Mat4 HMM_Orthographic_Metal(float l, float r, float b, float t, float near, float far)
|
HMM_Mat4 HMM_Orthographic_Metal(float l, float r, float b, float t, float near, float far)
|
||||||
{
|
{
|
||||||
HMM_Mat4 adjust = {0};
|
HMM_Mat4 adjust = {0};
|
||||||
|
@ -1774,6 +1772,7 @@ HMM_Mat4 HMM_QToM4(HMM_Quat Left) {
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// this is right handed
|
||||||
HMM_Mat4 HMM_M4TRS(HMM_Vec3 t, HMM_Quat q, HMM_Vec3 s)
|
HMM_Mat4 HMM_M4TRS(HMM_Vec3 t, HMM_Quat q, HMM_Vec3 s)
|
||||||
{
|
{
|
||||||
HMM_Mat4 l;
|
HMM_Mat4 l;
|
||||||
|
@ -1802,7 +1801,6 @@ HMM_Mat4 HMM_M4TRS(HMM_Vec3 t, HMM_Quat q, HMM_Vec3 s)
|
||||||
return l;
|
return l;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// This method taken from Mike Day at Insomniac Games.
|
// This method taken from Mike Day at Insomniac Games.
|
||||||
// https://d3cw3dd2w32x2b.cloudfront.net/wp-content/uploads/2015/01/matrix-to-quat.pdf
|
// https://d3cw3dd2w32x2b.cloudfront.net/wp-content/uploads/2015/01/matrix-to-quat.pdf
|
||||||
//
|
//
|
||||||
|
|
|
@ -7,6 +7,17 @@
|
||||||
#include "sokol/sokol_args.h"
|
#include "sokol/sokol_args.h"
|
||||||
#include "sokol/sokol_gfx.h"
|
#include "sokol/sokol_gfx.h"
|
||||||
#include "sokol/sokol_app.h"
|
#include "sokol/sokol_app.h"
|
||||||
|
#include "sokol/util/sokol_gl.h"
|
||||||
|
|
||||||
|
#define LAY_FLOAT 1
|
||||||
|
#define LAY_IMPLEMENTATION
|
||||||
|
#include "layout.h"
|
||||||
|
|
||||||
|
#define STB_PERLIN_IMPLEMENTATION
|
||||||
|
#include "stb_perlin.h"
|
||||||
|
|
||||||
|
#define STB_RECT_PACK_IMPLEMENTATION
|
||||||
|
#include "stb_rect_pack.h"
|
||||||
|
|
||||||
#define MSF_GIF_IMPL
|
#define MSF_GIF_IMPL
|
||||||
#include "msf_gif.h"
|
#include "msf_gif.h"
|
||||||
|
|
|
@ -121,8 +121,8 @@ struct sFont *MakeFont(const char *fontfile, int height) {
|
||||||
struct rect r;
|
struct rect r;
|
||||||
r.x = (glyph.x0) / (float)packsize;
|
r.x = (glyph.x0) / (float)packsize;
|
||||||
r.w = (glyph.x1-glyph.x0) / (float)packsize;
|
r.w = (glyph.x1-glyph.x0) / (float)packsize;
|
||||||
r.y = (glyph.y0) / (float)packsize;
|
r.y = (glyph.y1) / (float)packsize;
|
||||||
r.h = (glyph.y1-glyph.y0) / (float)packsize;
|
r.h = (glyph.y0-glyph.y1) / (float)packsize;
|
||||||
|
|
||||||
newfont->Characters[c].size = (HMM_Vec2){
|
newfont->Characters[c].size = (HMM_Vec2){
|
||||||
.x = glyph.x1-glyph.x0,
|
.x = glyph.x1-glyph.x0,
|
||||||
|
@ -132,7 +132,7 @@ struct sFont *MakeFont(const char *fontfile, int height) {
|
||||||
newfont->Characters[c].Advance = glyph.xadvance; /* x distance from this char to the next */
|
newfont->Characters[c].Advance = glyph.xadvance; /* x distance from this char to the next */
|
||||||
newfont->Characters[c].leftbearing = glyph.xoff;
|
newfont->Characters[c].leftbearing = glyph.xoff;
|
||||||
// printf("char %c: ascent %g, yoff %g, yoff2 %g\n", c, newfont->ascent, glyph.yoff, glyph.yoff2);
|
// printf("char %c: ascent %g, yoff %g, yoff2 %g\n", c, newfont->ascent, glyph.yoff, glyph.yoff2);
|
||||||
newfont->Characters[c].topbearing = newfont->ascent + glyph.yoff;
|
newfont->Characters[c].topbearing = -glyph.yoff2;//newfont->ascent - glyph.yoff;
|
||||||
newfont->Characters[c].rect = r;
|
newfont->Characters[c].rect = r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -216,6 +216,7 @@ HMM_Vec2 measure_text(const char *text, font *f, float size, float letterSpacing
|
||||||
float maxWidth = 0; // max width of any line
|
float maxWidth = 0; // max width of any line
|
||||||
float lineWidth = 0; // current line width
|
float lineWidth = 0; // current line width
|
||||||
float scale = size/f->height;
|
float scale = size/f->height;
|
||||||
|
scale = 1;
|
||||||
float lineHeight = f->ascent - f->descent;
|
float lineHeight = f->ascent - f->descent;
|
||||||
lineHeight *= scale;
|
lineHeight *= scale;
|
||||||
letterSpacing *= scale;
|
letterSpacing *= scale;
|
||||||
|
@ -244,6 +245,7 @@ void renderText(const char *text, HMM_Vec2 pos, font *f, float scale, struct rgb
|
||||||
|
|
||||||
HMM_Vec2 cursor = pos;
|
HMM_Vec2 cursor = pos;
|
||||||
float lineHeight = f->ascent - f->descent;
|
float lineHeight = f->ascent - f->descent;
|
||||||
|
float lineWidth = 0;
|
||||||
|
|
||||||
for (char *c = text; *c != 0; c++) {
|
for (char *c = text; *c != 0; c++) {
|
||||||
if (*c == '\n') {
|
if (*c == '\n') {
|
||||||
|
@ -294,7 +296,6 @@ void renderText(const char *text, HMM_Vec2 pos, font *f, float scale, struct rgb
|
||||||
if (*wordstart == '\e')
|
if (*wordstart == '\e')
|
||||||
wordstart = esc_color(wordstart, &usecolor, color);
|
wordstart = esc_color(wordstart, &usecolor, color);
|
||||||
|
|
||||||
//sdrawCharacter(f->Characters[*wordstart], HMM_AddV2(cursor, HMM_MulV2F((HMM_Vec2){1,-1},scale)), scale, (rgba){0,0,0,255});
|
|
||||||
sdrawCharacter(f->Characters[*wordstart], cursor, scale, usecolor);
|
sdrawCharacter(f->Characters[*wordstart], cursor, scale, usecolor);
|
||||||
|
|
||||||
cursor.X += f->Characters[*wordstart].Advance * scale;
|
cursor.X += f->Characters[*wordstart].Advance * scale;
|
||||||
|
|
|
@ -5,6 +5,13 @@
|
||||||
#include "render.h"
|
#include "render.h"
|
||||||
#include "HandmadeMath.h"
|
#include "HandmadeMath.h"
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
LEFT,
|
||||||
|
RIGHT,
|
||||||
|
CENTER,
|
||||||
|
JUSTIFY
|
||||||
|
} ALIGN;
|
||||||
|
|
||||||
struct shader;
|
struct shader;
|
||||||
struct window;
|
struct window;
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,6 @@
|
||||||
#include "datastream.h"
|
#include "datastream.h"
|
||||||
#include "sound.h"
|
#include "sound.h"
|
||||||
#include "stb_ds.h"
|
#include "stb_ds.h"
|
||||||
#define STB_RECT_PACK_IMPLEMENTATION
|
|
||||||
#include "stb_rect_pack.h"
|
#include "stb_rect_pack.h"
|
||||||
#include "string.h"
|
#include "string.h"
|
||||||
#include "window.h"
|
#include "window.h"
|
||||||
|
@ -34,7 +33,6 @@
|
||||||
#include "par/par_streamlines.h"
|
#include "par/par_streamlines.h"
|
||||||
#include "par/par_shapes.h"
|
#include "par/par_shapes.h"
|
||||||
#include "sokol_glue.h"
|
#include "sokol_glue.h"
|
||||||
#define SOKOL_GL_IMPL
|
|
||||||
#include "sokol/util/sokol_gl.h"
|
#include "sokol/util/sokol_gl.h"
|
||||||
#include <chipmunk/chipmunk_unsafe.h>
|
#include <chipmunk/chipmunk_unsafe.h>
|
||||||
#include <chipmunk/chipmunk_structs.h>
|
#include <chipmunk/chipmunk_structs.h>
|
||||||
|
@ -43,14 +41,12 @@
|
||||||
#include "timer.h"
|
#include "timer.h"
|
||||||
|
|
||||||
#define LAY_FLOAT 1
|
#define LAY_FLOAT 1
|
||||||
#define LAY_IMPLEMENTATION
|
|
||||||
#include "layout.h"
|
#include "layout.h"
|
||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
#include <sys/resource.h>
|
#include <sys/resource.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define STB_PERLIN_IMPLEMENTATION
|
|
||||||
#include "stb_perlin.h"
|
#include "stb_perlin.h"
|
||||||
|
|
||||||
#if (defined(_WIN32) || defined(__WIN32__))
|
#if (defined(_WIN32) || defined(__WIN32__))
|
||||||
|
@ -58,8 +54,26 @@
|
||||||
#define mkdir(x,y) _mkdir(x)
|
#define mkdir(x,y) _mkdir(x)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static JSValue globalThis;
|
struct lrtb {
|
||||||
|
float l;
|
||||||
|
float r;
|
||||||
|
float t;
|
||||||
|
float b;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct lrtb lrtb;
|
||||||
|
|
||||||
|
lrtb js2lrtb(JSValue v)
|
||||||
|
{
|
||||||
|
lrtb ret = {0};
|
||||||
|
ret.l = js2number(js_getpropstr(v,"l"));
|
||||||
|
ret.b = js2number(js_getpropstr(v,"b"));
|
||||||
|
ret.t = js2number(js_getpropstr(v,"t"));
|
||||||
|
ret.r = js2number(js_getpropstr(v,"r"));
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static JSValue globalThis;
|
||||||
JSValue str2js(const char *c, ...) {
|
JSValue str2js(const char *c, ...) {
|
||||||
if (!c) return JS_UNDEFINED;
|
if (!c) return JS_UNDEFINED;
|
||||||
char *result = NULL;
|
char *result = NULL;
|
||||||
|
@ -600,6 +614,12 @@ struct rect js2rect(JSValue v) {
|
||||||
rect.y = js2number(js_getpropstr(v, "y"));
|
rect.y = js2number(js_getpropstr(v, "y"));
|
||||||
rect.w = js2number(js_getpropstr(v, "width"));
|
rect.w = js2number(js_getpropstr(v, "width"));
|
||||||
rect.h = js2number(js_getpropstr(v, "height"));
|
rect.h = js2number(js_getpropstr(v, "height"));
|
||||||
|
float anchor_x = js2number(js_getpropstr(v, "anchor_x"));
|
||||||
|
float anchor_y = js2number(js_getpropstr(v, "anchor_y"));
|
||||||
|
|
||||||
|
rect.y -= anchor_y*rect.h;
|
||||||
|
rect.x -= anchor_x*rect.w;
|
||||||
|
|
||||||
return rect;
|
return rect;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -781,7 +801,8 @@ JSC_CCALL(render_glue_pass,
|
||||||
|
|
||||||
// Set the portion of the window to be rendered to
|
// Set the portion of the window to be rendered to
|
||||||
JSC_CCALL(render_viewport,
|
JSC_CCALL(render_viewport,
|
||||||
sg_apply_viewportf(js2number(argv[0]), js2number(argv[1]), js2number(argv[2]), js2number(argv[3]), 0);
|
rect view = js2rect(argv[0]);
|
||||||
|
sg_apply_viewportf(view.x, view.y,view.w,view.h, js2boolean(argv[1]));
|
||||||
)
|
)
|
||||||
|
|
||||||
JSC_CCALL(render_commit, sg_commit())
|
JSC_CCALL(render_commit, sg_commit())
|
||||||
|
@ -790,33 +811,9 @@ JSC_CCALL(render_end_pass, sg_end_pass())
|
||||||
HMM_Mat4 transform2view(transform *t)
|
HMM_Mat4 transform2view(transform *t)
|
||||||
{
|
{
|
||||||
HMM_Vec3 look = HMM_AddV3(t->pos, transform_direction(t, vFWD));
|
HMM_Vec3 look = HMM_AddV3(t->pos, transform_direction(t, vFWD));
|
||||||
return HMM_LookAt_LH(t->pos, look, vUP);
|
HMM_Mat4 ret = HMM_LookAt_RH(t->pos, look, vUP);
|
||||||
}
|
ret = HMM_MulM4(ret, HMM_Scale(t->scale));
|
||||||
|
return ret;
|
||||||
HMM_Mat4 camera2projection(JSValue cam) {
|
|
||||||
int ortho = js2boolean(js_getpropstr(cam, "ortho"));
|
|
||||||
float near = js2number(js_getpropstr(cam, "near"));
|
|
||||||
float far = js2number(js_getpropstr(cam, "far"));
|
|
||||||
float fov = js2number(js_getpropstr(cam, "fov"))*HMM_DegToRad;
|
|
||||||
HMM_Vec2 size = js2vec2(js_getpropstr(cam,"size"));
|
|
||||||
|
|
||||||
if (ortho)
|
|
||||||
#ifdef SOKOL_GLCORE
|
|
||||||
return HMM_Orthographic_GL(
|
|
||||||
#elifdef SOKOL_D3D11
|
|
||||||
return HMM_Orthographic_DX(
|
|
||||||
#else
|
|
||||||
return HMM_Orthographic_Metal(
|
|
||||||
#endif
|
|
||||||
-size.x/2,
|
|
||||||
size.x/2,
|
|
||||||
-size.y/2,
|
|
||||||
size.y/2,
|
|
||||||
near,
|
|
||||||
far
|
|
||||||
);
|
|
||||||
else
|
|
||||||
return HMM_Perspective_Metal(fov, size.x/size.y, near, far);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
JSC_CCALL(render_camera_screen2world,
|
JSC_CCALL(render_camera_screen2world,
|
||||||
|
@ -826,8 +823,27 @@ JSC_CCALL(render_camera_screen2world,
|
||||||
return vec42js(HMM_MulM4V4(view, p));
|
return vec42js(HMM_MulM4V4(view, p));
|
||||||
)
|
)
|
||||||
|
|
||||||
JSC_CCALL(render_set_projection,
|
JSC_CCALL(render_set_projection_ortho,
|
||||||
globalview.p = camera2projection(argv[0]);
|
lrtb extents = js2lrtb(argv[0]);
|
||||||
|
float near = js2number(argv[1]);
|
||||||
|
float far = js2number(argv[2]);
|
||||||
|
globalview.p = HMM_Orthographic_RH_NO(
|
||||||
|
extents.l,
|
||||||
|
extents.r,
|
||||||
|
extents.b,
|
||||||
|
extents.t,
|
||||||
|
near,
|
||||||
|
far
|
||||||
|
);
|
||||||
|
globalview.vp = HMM_MulM4(globalview.p, globalview.v);
|
||||||
|
)
|
||||||
|
|
||||||
|
JSC_CCALL(render_set_projection_perspective,
|
||||||
|
float fov = js2number(argv[0]);
|
||||||
|
float aspect = js2number(argv[1]);
|
||||||
|
float near = js2number(argv[2]);
|
||||||
|
float far = js2number(argv[3]);
|
||||||
|
globalview.p = HMM_Perspective_RH_NO(fov, aspect, near, far);
|
||||||
globalview.vp = HMM_MulM4(globalview.p, globalview.v);
|
globalview.vp = HMM_MulM4(globalview.p, globalview.v);
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -836,13 +852,6 @@ JSC_CCALL(render_set_view,
|
||||||
globalview.vp = HMM_MulM4(globalview.p, globalview.v);
|
globalview.vp = HMM_MulM4(globalview.p, globalview.v);
|
||||||
)
|
)
|
||||||
|
|
||||||
JSC_CCALL(render_set_camera,
|
|
||||||
JSValue cam = argv[0];
|
|
||||||
globalview.p = camera2projection(argv[0]);
|
|
||||||
globalview.v = transform2view(js2transform(js_getpropstr(cam, "transform")));
|
|
||||||
globalview.vp = HMM_MulM4(globalview.p, globalview.v);
|
|
||||||
)
|
|
||||||
|
|
||||||
sg_shader_uniform_block_desc js2uniform_block(JSValue v)
|
sg_shader_uniform_block_desc js2uniform_block(JSValue v)
|
||||||
{
|
{
|
||||||
sg_shader_uniform_block_desc desc = {0};
|
sg_shader_uniform_block_desc desc = {0};
|
||||||
|
@ -1250,13 +1259,6 @@ JSC_CCALL(render_spdraw,
|
||||||
)
|
)
|
||||||
|
|
||||||
JSC_CCALL(render_setpipeline, sg_apply_pipeline(*js2sg_pipeline(argv[0]));)
|
JSC_CCALL(render_setpipeline, sg_apply_pipeline(*js2sg_pipeline(argv[0]));)
|
||||||
|
|
||||||
JSC_CCALL(render_screencolor,
|
|
||||||
texture *t = calloc(sizeof(*t), 1);
|
|
||||||
t->id = screencolor;
|
|
||||||
return texture2js(&screencolor)
|
|
||||||
)
|
|
||||||
|
|
||||||
JSC_CCALL(render_imgui_new, gui_newframe(js2number(argv[0]),js2number(argv[1]),js2number(argv[2])); )
|
JSC_CCALL(render_imgui_new, gui_newframe(js2number(argv[0]),js2number(argv[1]),js2number(argv[2])); )
|
||||||
JSC_CCALL(render_imgui_end, gui_endframe())
|
JSC_CCALL(render_imgui_end, gui_endframe())
|
||||||
|
|
||||||
|
@ -1280,8 +1282,8 @@ static const JSCFunctionListEntry js_render_funcs[] = {
|
||||||
MIST_FUNC_DEF(render, commit, 0),
|
MIST_FUNC_DEF(render, commit, 0),
|
||||||
MIST_FUNC_DEF(render, glue_pass, 0),
|
MIST_FUNC_DEF(render, glue_pass, 0),
|
||||||
MIST_FUNC_DEF(render, text_size, 5),
|
MIST_FUNC_DEF(render, text_size, 5),
|
||||||
MIST_FUNC_DEF(render, set_camera, 1),
|
MIST_FUNC_DEF(render, set_projection_ortho, 3),
|
||||||
MIST_FUNC_DEF(render, set_projection, 1),
|
MIST_FUNC_DEF(render, set_projection_perspective, 4),
|
||||||
MIST_FUNC_DEF(render, set_view, 1),
|
MIST_FUNC_DEF(render, set_view, 1),
|
||||||
MIST_FUNC_DEF(render, make_pipeline, 1),
|
MIST_FUNC_DEF(render, make_pipeline, 1),
|
||||||
MIST_FUNC_DEF(render, setuniv3, 2),
|
MIST_FUNC_DEF(render, setuniv3, 2),
|
||||||
|
@ -1296,7 +1298,6 @@ static const JSCFunctionListEntry js_render_funcs[] = {
|
||||||
MIST_FUNC_DEF(render, setuniv2, 2),
|
MIST_FUNC_DEF(render, setuniv2, 2),
|
||||||
MIST_FUNC_DEF(render, setuniv4, 2),
|
MIST_FUNC_DEF(render, setuniv4, 2),
|
||||||
MIST_FUNC_DEF(render, setpipeline, 1),
|
MIST_FUNC_DEF(render, setpipeline, 1),
|
||||||
MIST_FUNC_DEF(render, screencolor, 0),
|
|
||||||
MIST_FUNC_DEF(render, imgui_new, 3),
|
MIST_FUNC_DEF(render, imgui_new, 3),
|
||||||
MIST_FUNC_DEF(render, imgui_end, 0),
|
MIST_FUNC_DEF(render, imgui_end, 0),
|
||||||
MIST_FUNC_DEF(render, imgui_init, 0),
|
MIST_FUNC_DEF(render, imgui_init, 0),
|
||||||
|
@ -2188,15 +2189,15 @@ JSC_CCALL(transform_move, transform_move(js2transform(self), js2vec3(argv[0]));
|
||||||
JSC_CCALL(transform_lookat,
|
JSC_CCALL(transform_lookat,
|
||||||
HMM_Vec3 point = js2vec3(argv[0]);
|
HMM_Vec3 point = js2vec3(argv[0]);
|
||||||
transform *go = js2transform(self);
|
transform *go = js2transform(self);
|
||||||
HMM_Mat4 m = HMM_LookAt_LH(go->pos, point, vUP);
|
HMM_Mat4 m = HMM_LookAt_RH(go->pos, point, vUP);
|
||||||
go->rotation = HMM_M4ToQ_LH(m);
|
go->rotation = HMM_M4ToQ_RH(m);
|
||||||
go->dirty = true;
|
go->dirty = true;
|
||||||
)
|
)
|
||||||
|
|
||||||
JSC_CCALL(transform_rotate,
|
JSC_CCALL(transform_rotate,
|
||||||
HMM_Vec3 axis = js2vec3(argv[0]);
|
HMM_Vec3 axis = js2vec3(argv[0]);
|
||||||
transform *t = js2transform(self);
|
transform *t = js2transform(self);
|
||||||
HMM_Quat rot = HMM_QFromAxisAngle_LH(axis, js2angle(argv[1]));
|
HMM_Quat rot = HMM_QFromAxisAngle_RH(axis, js2angle(argv[1]));
|
||||||
t->rotation = HMM_MulQ(t->rotation,rot);
|
t->rotation = HMM_MulQ(t->rotation,rot);
|
||||||
t->dirty = true;
|
t->dirty = true;
|
||||||
)
|
)
|
||||||
|
@ -2221,7 +2222,7 @@ JSC_CCALL(transform_phys2d,
|
||||||
float av = js2number(argv[1]);
|
float av = js2number(argv[1]);
|
||||||
float dt = js2number(argv[2]);
|
float dt = js2number(argv[2]);
|
||||||
transform_move(t, (HMM_Vec3){v.x*dt,v.y*dt,0});
|
transform_move(t, (HMM_Vec3){v.x*dt,v.y*dt,0});
|
||||||
HMM_Quat rot = HMM_QFromAxisAngle_LH((HMM_Vec3){0,0,1}, av*dt);
|
HMM_Quat rot = HMM_QFromAxisAngle_RH((HMM_Vec3){0,0,1}, av*dt);
|
||||||
t->rotation = HMM_MulQ(t->rotation, rot);
|
t->rotation = HMM_MulQ(t->rotation, rot);
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -2837,10 +2838,14 @@ static const JSCFunctionListEntry js_timer_funcs[] = {
|
||||||
|
|
||||||
JSC_GETSET(font, linegap, number)
|
JSC_GETSET(font, linegap, number)
|
||||||
JSC_GET(font, height, number)
|
JSC_GET(font, height, number)
|
||||||
|
JSC_GET(font, ascent, number)
|
||||||
|
JSC_GET(font, descent, number)
|
||||||
|
|
||||||
static const JSCFunctionListEntry js_font_funcs[] = {
|
static const JSCFunctionListEntry js_font_funcs[] = {
|
||||||
CGETSET_ADD(font, linegap),
|
CGETSET_ADD(font, linegap),
|
||||||
MIST_GET(font, height),
|
MIST_GET(font, height),
|
||||||
|
MIST_GET(font, ascent),
|
||||||
|
MIST_GET(font, descent)
|
||||||
};
|
};
|
||||||
|
|
||||||
const char *STRTEST = "TEST STRING";
|
const char *STRTEST = "TEST STRING";
|
||||||
|
@ -2903,7 +2908,7 @@ JSC_CCALL(geometry_rect_random,
|
||||||
JSC_CCALL(geometry_rect_point_inside,
|
JSC_CCALL(geometry_rect_point_inside,
|
||||||
rect a = js2rect(argv[0]);
|
rect a = js2rect(argv[0]);
|
||||||
HMM_Vec2 p = js2vec2(argv[1]);
|
HMM_Vec2 p = js2vec2(argv[1]);
|
||||||
return boolean2js(p.x >= a.x && p.x <= a.x+a.w && p.y <= a.y+a.h && p.y >= a.y-a.h);
|
return boolean2js(p.x >= a.x && p.x <= a.x+a.w && p.y <= a.y+a.h && p.y >= a.y);
|
||||||
)
|
)
|
||||||
|
|
||||||
JSC_CCALL(geometry_cwh2rect,
|
JSC_CCALL(geometry_cwh2rect,
|
||||||
|
@ -3712,25 +3717,6 @@ static const JSCFunctionListEntry js_os_funcs[] = {
|
||||||
|
|
||||||
static lay_context lay_ctx;
|
static lay_context lay_ctx;
|
||||||
|
|
||||||
struct lrtb {
|
|
||||||
float l;
|
|
||||||
float r;
|
|
||||||
float t;
|
|
||||||
float b;
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef struct lrtb lrtb;
|
|
||||||
|
|
||||||
lrtb js2lrtb(JSValue v)
|
|
||||||
{
|
|
||||||
lrtb ret = {0};
|
|
||||||
ret.l = js2number(js_getpropstr(v,"l"));
|
|
||||||
ret.b = js2number(js_getpropstr(v,"b"));
|
|
||||||
ret.t = js2number(js_getpropstr(v,"t"));
|
|
||||||
ret.r = js2number(js_getpropstr(v,"r"));
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
JSC_CCALL(layout_item,
|
JSC_CCALL(layout_item,
|
||||||
lay_id item = lay_item(&lay_ctx);
|
lay_id item = lay_item(&lay_ctx);
|
||||||
HMM_Vec2 size = js2vec2(js_getpropstr(argv[0], "size"));
|
HMM_Vec2 size = js2vec2(js_getpropstr(argv[0], "size"));
|
||||||
|
|
|
@ -77,6 +77,7 @@ struct boundingbox {
|
||||||
float l;
|
float l;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// rectangles are always defined with [x,y] in the bottom left
|
||||||
struct rect {
|
struct rect {
|
||||||
float x,y,w,h;
|
float x,y,w,h;
|
||||||
};
|
};
|
||||||
|
|
|
@ -175,6 +175,8 @@ struct texture *texture_from_file(const char *path) {
|
||||||
|
|
||||||
struct texture *tex = calloc(1, sizeof(*tex));
|
struct texture *tex = calloc(1, sizeof(*tex));
|
||||||
|
|
||||||
|
stbi_set_flip_vertically_on_load(1);
|
||||||
|
|
||||||
int n;
|
int n;
|
||||||
|
|
||||||
char *ext = strrchr(path, '.');
|
char *ext = strrchr(path, '.');
|
||||||
|
|
|
@ -57,6 +57,11 @@ HMM_Vec3 mat3_t_dir(HMM_Mat4 m, HMM_Vec3 dir)
|
||||||
|
|
||||||
HMM_Mat4 transform2mat(transform *t) {
|
HMM_Mat4 transform2mat(transform *t) {
|
||||||
return HMM_M4TRS(t->pos, t->rotation, t->scale);
|
return HMM_M4TRS(t->pos, t->rotation, t->scale);
|
||||||
|
HMM_Mat4 scale = HMM_Scale(t->scale);
|
||||||
|
HMM_Mat4 rot = HMM_QToM4(t->rotation);
|
||||||
|
HMM_Mat4 pos = HMM_Translate(t->pos);
|
||||||
|
return HMM_MulM4(pos, HMM_MulM4(rot, scale));
|
||||||
|
|
||||||
|
|
||||||
if (t->dirty) {
|
if (t->dirty) {
|
||||||
t->cache = HMM_M4TRS(t->pos, t->rotation, t->scale);
|
t->cache = HMM_M4TRS(t->pos, t->rotation, t->scale);
|
||||||
|
@ -68,7 +73,7 @@ HMM_Mat4 transform2mat(transform *t) {
|
||||||
|
|
||||||
HMM_Quat angle2rotation(float angle)
|
HMM_Quat angle2rotation(float angle)
|
||||||
{
|
{
|
||||||
return HMM_QFromAxisAngle_LH(vBKWD, angle);
|
return HMM_QFromAxisAngle_RH(vBKWD, angle);
|
||||||
}
|
}
|
||||||
|
|
||||||
transform mat2transform(HMM_Mat4 m)
|
transform mat2transform(HMM_Mat4 m)
|
||||||
|
@ -79,6 +84,6 @@ transform mat2transform(HMM_Mat4 m)
|
||||||
t.scale.Elements[i] = HMM_LenV3(m.Columns[i].xyz);
|
t.scale.Elements[i] = HMM_LenV3(m.Columns[i].xyz);
|
||||||
// for (int i = 0; i < 2; i++)
|
// for (int i = 0; i < 2; i++)
|
||||||
// m.Columns[i].xyz = HMM_MulV3(m.Columns[i].xyz, t.scale.Elements[i]);
|
// m.Columns[i].xyz = HMM_MulV3(m.Columns[i].xyz, t.scale.Elements[i]);
|
||||||
t.rotation = HMM_M4ToQ_LH(m);
|
t.rotation = HMM_M4ToQ_RH(m);
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
|
@ -115,7 +115,7 @@ void c_event(const sapp_event *e)
|
||||||
switch (e->type) {
|
switch (e->type) {
|
||||||
case SAPP_EVENTTYPE_MOUSE_MOVE:
|
case SAPP_EVENTTYPE_MOUSE_MOVE:
|
||||||
if (gui_wantmouse()) return;
|
if (gui_wantmouse()) return;
|
||||||
script_evalf("prosperon.mousemove([%g, %g], [%g, %g]);", e->mouse_x, e->mouse_y, e->mouse_dx, -e->mouse_dy);
|
script_evalf("prosperon.mousemove([%g, %g], [%g, %g]);", e->mouse_x, e->mouse_y, e->mouse_dx, e->mouse_dy);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SAPP_EVENTTYPE_MOUSE_SCROLL:
|
case SAPP_EVENTTYPE_MOUSE_SCROLL:
|
||||||
|
|
Loading…
Reference in a new issue