Compare commits

...

8 Commits

Author SHA1 Message Date
Sanjay Bhadra 681050139d Merge branch 'master' into rewrite-tevx 2020-05-27 15:00:47 -04:00
Sanjay Bhadra 89ff5aba45 Redesign to fit dashboard screen 2020-05-27 14:59:16 -04:00
Jay 1d42fdff0c apii dump 2020-05-24 00:49:25 +01:00
Jay 84a4da4bb8 0.21.0 api dump 2020-05-24 00:47:36 +01:00
Jay a828a079cb one file 2020-05-23 15:54:27 +01:00
Jay 75d3631741 Shaders and debug command 2020-05-23 13:50:17 +01:00
Jay 689966c3b8 Merge branch 'master' of https://github.com/teverse/teverse 2020-05-23 10:39:09 +01:00
Jay b5ee4a3b24 Shaders for TevX 2020-05-23 10:39:04 +01:00
21 changed files with 788 additions and 442 deletions

336
api.json
View File

@ -1,8 +1,8 @@
{
"os": "OSX",
"arch": "x64",
"version": "0.20.13",
"generatedAt": "10/05/2020 22:07:37",
"version": "0.21.0",
"generatedAt": "24/05/2020 00:46:08",
"sandbox": {
"coroutine": {
"status": "function",
@ -20,10 +20,10 @@
"xpcall": "function",
"_DEVICE_PAD_BOTTOM": 0,
"ipairs": "function",
"_TEV_BUILD": "02013",
"_TEV_BUILD": "0210",
"colour": "cdata",
"print": "function",
"_TEV_VERSION_MINOR": 20,
"_TEV_VERSION_MINOR": 21,
"pcall": "function",
"gcinfo": "function",
"loadstring": "function",
@ -45,11 +45,13 @@
"insert": "function"
},
"error": "function",
"_TEV_VERSION": "0.20.13",
"_TEV_VERSION": "0.21.0",
"quaternion": "cdata",
"_DEVICE": "Mac",
"require": "function",
"unpack": "function",
"_VERSION": "Lua 5.1",
"_TEV_VERSION_PATCH": 13,
"_TEV_VERSION_PATCH": 0,
"next": "function",
"math": {
"ceil": "function",
@ -83,7 +85,6 @@
"randomseed": "function",
"rad": "function"
},
"unpack": "function",
"os": {
"difftime": "function",
"date": "function",
@ -91,6 +92,7 @@
"clock": "function",
"parseISO8601": "function"
},
"vector3": "cdata",
"vector2": "cdata",
"select": "function",
"string": {
@ -419,6 +421,18 @@
"boolean"
],
"description": "Returns true if the provided key is down"
},
"isMouseButtonDown": {
"parameters": [
{
"type": "number",
"name": "code"
}
],
"returns": [
"boolean"
],
"description": "Returns true if the provided button is down, where code is 1, 2 or 3"
}
},
"className": "input",
@ -648,6 +662,39 @@
}
}
},
"sceneObject": {
"methods": [],
"className": "sceneObject",
"events": [],
"constructable": false,
"extends": "objectBase",
"properties": {
"absolutePosition": {
"hasGetter": true,
"type": "vector3",
"description": "",
"hasSetter": false
},
"rotation": {
"hasGetter": true,
"type": "quaternion",
"description": "",
"hasSetter": true
},
"position": {
"hasGetter": true,
"type": "vector3",
"description": "",
"hasSetter": true
},
"absoluteRotation": {
"hasGetter": true,
"type": "quaternion",
"description": "",
"hasSetter": false
}
}
},
"guiBase": {
"methods": {
"child": {
@ -666,11 +713,6 @@
"parameters": [],
"returns": [],
"description": "Destroys all children"
},
"destroy": {
"parameters": [],
"returns": [],
"description": "Destroys this object, further accessing this instance will error"
}
},
"className": "guiBase",
@ -1043,7 +1085,13 @@
}
},
"objectBase": {
"methods": [],
"methods": {
"destroy": {
"parameters": [],
"returns": [],
"description": "Destroys this object, further accessing this instance will error"
}
},
"className": "objectBase",
"events": [],
"constructable": false,
@ -1154,6 +1202,51 @@
"constructable": false,
"properties": []
},
"guiRichTextBox": {
"methods": {
"removeColour": {
"parameters": [
{
"type": "int",
"name": "index"
}
],
"returns": [],
"description": "Removes any set colour at the index provided"
},
"setColour": {
"parameters": [
{
"type": "int",
"name": "index"
},
{
"type": "colour",
"name": "colour"
}
],
"returns": [],
"description": "Sets the colour of text onwards from the provided index"
},
"clearColours": {
"parameters": [],
"returns": [],
"description": "Removes any set colours at all indexes"
}
},
"className": "guiRichTextBox",
"events": [],
"constructable": true,
"extends": "guiTextBox",
"properties": {
"colours": {
"hasGetter": true,
"type": "table",
"description": "Returns a table of {index, colour} (e.g: {{1, colour(1,0,0)}, {3, colour(0,1,0)}})",
"hasSetter": false
}
}
},
"guiLine": {
"methods": [],
"className": "guiLine",
@ -1199,6 +1292,66 @@
}
}
},
"tween": {
"methods": {
"begin": {
"parameters": [
{
"type": "variant",
"name": "object"
},
{
"type": "number",
"name": "duration"
},
{
"type": "table",
"name": "properties"
},
{
"type": "string",
"name": "easing"
},
{
"type": "function?",
"name": "tweenCallback"
}
],
"returns": [],
"description": "Creates and starts a tween"
},
"create": {
"parameters": [
{
"type": "variant",
"name": "object"
},
{
"type": "number",
"name": "duration"
},
{
"type": "table",
"name": "properties"
},
{
"type": "string",
"name": "easing"
},
{
"type": "function?",
"name": "tweenCallback"
}
],
"returns": [],
"description": "Creates a tween"
}
},
"className": "tween",
"events": [],
"constructable": false,
"properties": []
},
"guiFrame": {
"methods": [],
"className": "guiFrame",
@ -1325,47 +1478,39 @@
}
}
},
"guiRichTextBox": {
"scene": {
"methods": {
"removeColour": {
"child": {
"parameters": [
{
"type": "int",
"name": "index"
"type": "string",
"name": "name"
}
],
"returns": [],
"description": "Removes any set colour at the index provided"
},
"setColour": {
"parameters": [
{
"type": "int",
"name": "index"
},
{
"type": "colour",
"name": "colour"
}
"returns": [
"sceneObject"
],
"returns": [],
"description": "Sets the colour of text onwards from the provided index"
"description": "Returns nil if not found"
},
"clearColours": {
"destroyChildren": {
"parameters": [],
"returns": [],
"description": "Removes any set colours at all indexes"
"description": "Destroys all children"
}
},
"className": "guiRichTextBox",
"className": "scene",
"events": [],
"constructable": true,
"extends": "guiTextBox",
"constructable": false,
"properties": {
"colours": {
"camera": {
"hasGetter": true,
"type": "Undocumented",
"hasSetter": false
},
"children": {
"hasGetter": true,
"type": "table",
"description": "Returns a table of {index, colour} (e.g: {{1, colour(1,0,0)}, {3, colour(0,1,0)}})",
"description": "",
"hasSetter": false
}
}
@ -1645,42 +1790,52 @@
}
}
},
"scene": {
"light": {
"methods": [],
"className": "scene",
"className": "light",
"events": [],
"constructable": false,
"extends": "sceneObject",
"properties": {
"size": {
"colour": {
"hasGetter": true,
"type": "Undocumented",
"type": "colour",
"description": "",
"hasSetter": true
}
}
},
"block": {
"methods": {
"setShader": {
"parameters": [
{
"type": "string",
"name": "mesh"
}
],
"returns": [],
"description": "Sets mesh"
}
},
"methods": [],
"className": "block",
"events": [],
"constructable": true,
"extends": "sceneObject",
"properties": {
"position": {
"roughness": {
"hasGetter": true,
"type": "number",
"description": "",
"hasSetter": true
},
"scale": {
"hasGetter": true,
"type": "vector3",
"description": "",
"hasSetter": true
},
"colour": {
"hasGetter": true,
"type": "colour",
"description": "",
"hasSetter": true
},
"metalness": {
"hasGetter": true,
"type": "number",
"description": "",
"hasSetter": true
},
"mesh": {
"hasGetter": true,
"type": "string",
@ -1743,68 +1898,21 @@
"constructable": false,
"properties": []
},
"tween": {
"methods": {
"begin": {
"parameters": [
{
"type": "variant",
"name": "object"
},
{
"type": "number",
"name": "duration"
},
{
"type": "table",
"name": "properties"
},
{
"type": "string",
"name": "easing"
},
{
"type": "function?",
"name": "tweenCallback"
}
],
"returns": [],
"description": "Creates and starts a tween"
},
"create": {
"parameters": [
{
"type": "variant",
"name": "object"
},
{
"type": "number",
"name": "duration"
},
{
"type": "table",
"name": "properties"
},
{
"type": "string",
"name": "easing"
},
{
"type": "function?",
"name": "tweenCallback"
}
],
"returns": [],
"description": "Creates a tween"
}
},
"className": "tween",
"directionalLight": {
"methods": [],
"className": "directionalLight",
"events": [],
"constructable": false,
"constructable": true,
"extends": "light",
"properties": []
},
"dev": {
"methods": {
"reloadAllShaders": {
"parameters": [],
"returns": [],
"description": "Reloads all shaders."
},
"promptTevGit": {
"parameters": [],
"returns": [],
@ -1902,5 +2010,5 @@
"properties": []
}
},
"build": "02013"
"build": "0210"
}

39
core/3d/camera.lua Normal file
View File

@ -0,0 +1,39 @@
local keyMap = {
[tonumber(enums.keys.KEY_W)] = vector3(0, 0, 1),
[tonumber(enums.keys.KEY_S)] = vector3(0, 0, -1),
[tonumber(enums.keys.KEY_A)] = vector3(-1, 0, 0),
[tonumber(enums.keys.KEY_D)] = vector3(1, 0, 0),
[tonumber(enums.keys.KEY_Q)] = vector3(0, -1, 0),
[tonumber(enums.keys.KEY_E)] = vector3(0, 1, 0)
}
local moveStep = 0.3
local rotateStep = 0.01
local cam = teverse.scene.camera
local db = false
teverse.input:on("keyDown", function(key)
if db then return end
db = true
local mapped = keyMap[tonumber(key)]
if mapped then
while sleep() and teverse.input:isKeyDown(key) do
cam.position = cam.position + (cam.rotation * mapped * moveStep)
end
end
db = false
end)
teverse.input:on("mouseMoved", function( movement )
if teverse.input:isMouseButtonDown(3) then
local pitch = quaternion.euler(movement.y * rotateStep, 0, 0)
local yaw = quaternion.euler(0, movement.x * rotateStep, 0)
-- Applied seperately to avoid camera flipping on the wrong axis.
cam.rotation = yaw * cam.rotation;
cam.rotation = cam.rotation * pitch
end
end)

View File

@ -66,15 +66,10 @@ teverse.debug:on("print", function(msg)
end)
end)
if _TEV_VERSION_PATCH and _TEV_VERSION_PATCH >= 9 then
for _,v in pairs(teverse.debug:getOutputHistory()) do
addLog(v.message, v.time)
end
logContainer.canvasOffset = vector2(0, lastPos - 200)
else
print("History not supported")
end
return container

View File

@ -22,13 +22,21 @@ if teverse.dev.localTevGit then
textAlpha = 0.5,
backgroundAlpha = 0
})
elseif _TEV_VERSION_PATCH and _TEV_VERSION_PATCH >= 12 then
end
local debug = false
teverse.input:on("keyUp", function(key)
if key == "KEY_F1" and not teverse.dev.localTevGit and teverse.input:isKeyDown("KEY_LSHIFT") then
teverse.dev:promptTevGit()
elseif key == "KEY_F2" and teverse.input:isKeyDown("KEY_LSHIFT") then
print("Reload")
teverse.dev:reloadAllShaders()
elseif key == "KEY_F12" and teverse.input:isKeyDown("KEY_LSHIFT") then
print("Debug")
debug = not debug
teverse.graphics:setDebug(debug)
end
end)
end
local settingsButton = teverse.construct("guiIcon", {
parent = teverse.coreInterface,

View File

@ -0,0 +1,18 @@
$input v_texcoord0
#include <teverse.sh>
SAMPLER2D(sColour, 0);
SAMPLER2D(sLight, 1);
uniform vec4 uniformAmbientColour;
vec3 colourAt(vec2 coord){
vec4 colour = toLinear(texture2D(sColour, coord) );
vec4 light = toLinear(texture2D(sLight, coord) );
return toGamma((colour * light) + (colour * uniformAmbientColour)).xyz;
}
void main()
{
gl_FragColor = vec4(colourAt(v_texcoord0), 1.0);
}

View File

@ -0,0 +1,4 @@
vec2 v_texcoord0 : TEXCOORD0 = vec2(0.0, 0.0);
vec3 a_position : POSITION;
vec2 a_texcoord0 : TEXCOORD0;

10
shaders/combine/vertex.sc Normal file
View File

@ -0,0 +1,10 @@
$input a_position, a_texcoord0
$output v_texcoord0
#include <teverse.sh>
void main()
{
gl_Position = mul(u_modelViewProj, vec4(a_position, 1.0) );
v_texcoord0 = a_texcoord0;
}

View File

@ -1,12 +1,12 @@
$input v_worldPos, v_view, v_normal, v_tangent, v_bitangent, v_color0, v_color1
$input v_normal, v_colour, v_position, v_pbr
#include <teverse.sh>
#include <lighting.sh>
uniform vec4 u_lightRgbInnerR;
uniform vec4 u_camPos;
uniform vec4 uniformCameraPosition;
void main()
{
gl_FragColor = vec4(encodeNormalUint(v_normal), 0.0);
gl_FragData[0] = vec4(v_colour.xyz, v_pbr.x);
gl_FragData[1] = vec4(v_normal, v_pbr.y);
//gl_FragData[2] = vec4(v_position, 0.0);
}

View File

@ -1,6 +1,30 @@
#ifndef __LIGHTING_SH__
#define __LIGHTING_SH__
//
// Teverse will be rebuilding our PBR shaders shortly
// To optimise fully for Mobile and low end devices
//
float remapRoughness(float x)
{
return 2.0f * (1.0f / (1.0f - 0.5f + 0.001f) - 1.0f) * (pow(x, 2)) + 0.001f;
}
float schlick(float R0, float cos_theta)
{
float R = R0 + (1.0 - R0) * pow((1.0 - cos_theta), 5.0);
return R;
}
float roughSchlick2(float R0, float cos_theta, float roughness)
{
float area_under_curve = 1.0 / 6.0 * (5.0 * R0 + 1.0);
float new_area_under_curve = 1.0 / (6.0 * roughness + 6.0) * (5.0 * R0 + 1.0);
return schlick(R0, cos_theta) /
(1.0 + roughness) + (area_under_curve - new_area_under_curve);
}
const float PI = 3.1415;
@ -46,11 +70,11 @@ vec3 calcLight(vec3 _wpos, vec3 _normal, vec3 _view, vec3 _lightPos, float _ligh
float toClipSpaceDepth(float _depthTextureZ)
{
#if BGFX_SHADER_LANGUAGE_GLSL
#if GLSL
return _depthTextureZ * 2.0 - 1.0;
#else
return _depthTextureZ;
#endif // BGFX_SHADER_LANGUAGE_GLSL
#endif
}
vec3 clipToWorld(mat4 _invViewProj, vec3 _clipPos)
@ -70,7 +94,7 @@ float DistributionGGX(vec3 N, vec3 H, float roughness)
float denom = (NdotH2 * (a2 - 1.0) + 1.0);
denom = PI * denom * denom;
return num / denom;
return NdotH2;
}
float GeometrySchlickGGX(float NdotV, float roughness)

View File

@ -1,24 +1,13 @@
vec3 v_worldPos : TEXCOORD1 = vec3(0.0, 0.0, 0.0);
vec3 v_view : TEXCOORD2 = vec3(0.0, 0.0, 0.0);
vec3 v_position : TEXCOORD3 = vec3(0.0, 0.0, 0.0);
vec3 v_view : TEXCOORD1 = vec3(0.0, 0.0, 0.0);
vec3 v_position : TEXCOORD2 = vec3(0.0, 0.0, 0.0);
vec4 v_colour : TEXCOORD3 = vec4(0.0, 0.0, 0.0, 0.0);
vec4 v_pbr : TEXCOORD4 = vec4(0.0, 0.0, 0.0, 0.0);
vec3 v_normal : NORMAL = vec3(0.0, 0.0, 1.0);
vec3 v_tangent : TANGENT = vec3(1.0, 0.0, 0.0);
vec3 v_bitangent : BINORMAL = vec3(0.0, 1.0, 0.0);
vec4 v_color0 : COLOR0 = vec4(1.0, 0.0, 0.0, 1.0);
vec4 v_color1 : COLOR1 = vec4(1.0, 0.0, 0.0, 1.0);
vec2 v_texcoord0 : TEXCOORD0 = vec2(0.0, 0.0);
vec3 a_position : POSITION;
vec4 a_normal : NORMAL;
vec4 a_tangent : TANGENT;
vec2 a_texcoord0 : TEXCOORD0;
vec4 a_color0 : COLOR0;
vec4 i_data0 : TEXCOORD7;
vec4 i_data1 : TEXCOORD6;
vec4 i_data2 : TEXCOORD5;
vec4 i_data3 : TEXCOORD4;
vec4 i_data4 : TEXCOORD3;
vec4 a_texcoord2 : TEXCOORD2;
ivec4 a_indices : BLENDINDICES;
vec4 a_weight : BLENDWEIGHT;

View File

@ -1,5 +1,5 @@
$input a_position, a_normal, a_tangent, a_color0, i_data0, i_data1, i_data2, i_data3, i_data4, a_texcoord2
$output v_worldPos, v_view, v_normal, v_tangent, v_bitangent, v_color0, v_color1
$input a_position, a_normal, i_data0, i_data1, i_data2, i_data3, i_data4
$output v_normal, v_colour, v_position, v_pbr
/*
* Portions of this file may have been directly taken or adapted from the following open sourced projects:
@ -10,6 +10,7 @@ $output v_worldPos, v_view, v_normal, v_tangent, v_bitangent, v_color0, v_color1
*/
#include <teverse.sh>
BUFFER_RO(normalData, vec4, 2);
void main()
{
@ -19,29 +20,20 @@ void main()
model[2] = i_data2;
model[3] = i_data3;
// metalness, roughness, 0, 0
v_pbr = vec4(normalData[gl_InstanceID * 3].w, i_data4.w, 0.0, 0.0);
mat3 normalMatrix;
normalMatrix[0] = normalData[gl_InstanceID * 3].xyz;
normalMatrix[1] = normalData[gl_InstanceID * 3 + 1].xyz;
normalMatrix[2] = normalData[gl_InstanceID * 3 + 2].xyz;
vec3 wpos = instMul(model, vec4(a_position, 1.0) ).xyz;
gl_Position = mul(u_viewProj, vec4(wpos, 1.0) );
v_worldPos = wpos;
mat3 modelIT = calculateInverseTranspose(u_model[0]);
vec4 normal = a_normal * 2.0 - 1.0;
vec4 tangent = a_tangent * 2.0 - 1.0;
vec3 wnormal = normalize(mul(modelIT, normal.xyz ));
wnormal = instMul(model, vec4(wnormal, 1.0) ).xyz;
vec3 wtangent = normalize(mul(modelIT, tangent.xyz ));
vec3 view = mul(u_view, vec4(wpos, 0.0) ).xyz;
v_view = view; //mul(view, tbn);
v_normal = normalize(wnormal);
v_tangent = wtangent;
v_bitangent = vec3(0.0, 0.0, 0.0);
//v_position = a_position;
v_color0 = i_data4;
v_color1 = a_texcoord2;
vec3 normal = a_normal.xyz * 2.0 - 1.0;
vec3 wnormal = instMul(normalMatrix, vec4(normal.xyz, 0.0));
v_normal = encodeNormalUint(normalize(wnormal.xyz));
v_colour = i_data4;
v_position = gl_Position;
}

View File

@ -0,0 +1,114 @@
$input v_texcoord0, lightDirection, lightColour
//
// Teverse will be rebuilding our PBR shaders shortly
// To optimise fully for Mobile and low end devices
//
#include <teverse.sh>
#define PI 3.1415926535f
float toClipSpaceDepth(float _depthTextureZ)
{
#if GLSL
return _depthTextureZ * 2.0 - 1.0;
#else
return _depthTextureZ;
#endif
}
vec3 clipToWorld(mat4 _invViewProj, vec3 _clipPos)
{
vec4 wpos = mul(_invViewProj, vec4(_clipPos, 1.0) );
return wpos.xyz / wpos.w;
}
float DistributionGGX(vec3 N, vec3 H, float roughness)
{
float a = roughness*roughness;
float a2 = a*a;
float NdotH = max(dot(N, H), 0.0);
float NdotH2 = NdotH*NdotH;
float num = a2;
float denom = (NdotH2 * (a2 - 1.0) + 1.0);
denom = PI * denom * denom;
return NdotH2;
}
float GeometrySchlickGGX(float NdotV, float roughness)
{
float r = (roughness + 1.0);
float k = (r*r) / 8.0;
float num = NdotV;
float denom = NdotV * (1.0 - k) + k;
return num / denom;
}
float GeometrySmith(vec3 N, vec3 V, vec3 L, float roughness)
{
float NdotV = max(dot(N, V), 0.0);
float NdotL = max(dot(N, L), 0.0);
float ggx2 = GeometrySchlickGGX(NdotV, roughness);
float ggx1 = GeometrySchlickGGX(NdotL, roughness);
return ggx1 * ggx2;
}
vec3 fresnelSchlick(float cosTheta, vec3 F0)
{
return F0 + (1.0 - F0) * pow(1.0 - cosTheta, 5.0);
}
SAMPLER2D(sColour, 0);
SAMPLER2D(sNormal, 1);
SAMPLER2D(sDepth, 2);
uniform mat4 uniformMtx;
uniform vec4 uniformCameraPosition;
void main()
{
vec4 colour = texture2D(sColour, v_texcoord0);
vec4 normal = texture2D(sNormal, v_texcoord0);
normal.xyz = decodeNormalUint(normal.xyz);
float depth = toClipSpaceDepth(texture2D(sDepth, v_texcoord0).x);
vec3 lightDir = normalize(-lightDirection);
float metallic = colour.w;
float roughness = normal.w;
vec3 clip = vec3(v_texcoord0 * 2.0 - 1.0, depth);
#if !GLSL
clip.y = -clip.y;
#endif
vec3 wpos = clipToWorld(uniformMtx, clip);
vec3 V = normalize(uniformCameraPosition.xyz - wpos);
vec3 F0 = vec3(0.04);
F0 = mix(F0, colour, metallic);
vec3 L = lightDir;
vec3 H = normalize(V + L);
// cook-torrance brdf
float NDF = DistributionGGX(normal.xyz, H, roughness);
float G = GeometrySmith(normal.xyz, V, L, roughness);
vec3 F = fresnelSchlick(max(dot(H, V), 0.0), F0);
vec3 kS = F;
vec3 kD = vec3(1.0) - kS;
kD *= 1.0 - metallic;
vec3 numerator = NDF * G * F;
float denominator = 4.0 * max(dot(normal.xyz, V), 0.0) * max(dot(normal.xyz, L), 0.0);
vec3 specular = numerator / max(denominator, 0.001);
// add to outgoing radiance Lo
float NdotL = max(dot(normal.xyz, L), 0.0);
gl_FragColor = vec4(((kD * colour / PI + specular) * lightColour * NdotL), 1.0);
}

View File

@ -0,0 +1,8 @@
vec2 v_texcoord0 : TEXCOORD0 = vec2(0.0, 0.0);
vec3 lightDirection : TEXCOORD1 = vec3(0.0, 0.0, 0.0);
vec3 lightColour : TEXCOORD2 = vec3(0.0, 0.0, 0.0);
vec3 a_position : POSITION;
vec2 a_texcoord0 : TEXCOORD0;
vec4 i_data0 : TEXCOORD7;
vec4 i_data1 : TEXCOORD6;

View File

@ -0,0 +1,12 @@
$input a_position, a_texcoord0, i_data0, i_data1
$output v_texcoord0, lightDirection, lightColour
#include <teverse.sh>
void main()
{
gl_Position = mul(u_modelViewProj, vec4(a_position, 1.0) );
v_texcoord0 = a_texcoord0;
lightColour = i_data0.xyz;
lightDirection = i_data1.xyz;
}

0
shaders/ssao/fragment.sc Normal file
View File

View File

0
shaders/ssao/vertex.sc Normal file
View File

View File

@ -8,7 +8,8 @@ return {
sideBarPageDefault = nil, -- Holds the default sidebar page (view) as a string and is set in topbarInterface.lua
sideBarPageActive = nil, -- Holds the current active sidebar page (view) as a string and is set in topbarInterface.lua
defaultColours = { -- Default colors used for theming UI components (~\library\ui\components)
primary = colour.rgb(112, 112, 112),
--primary = colour.rgb(112, 112, 112),
primary = colour.rgb(52, 58, 64),
secondary = colour.rgb(239, 239, 239),
background = colour.rgb(33, 33, 33),
red = colour.rgb(255, 82, 82),
@ -17,6 +18,7 @@ return {
blue = colour.rgb(68, 138, 255),
orange = colour.rgb(255, 171, 64),
purple = colour.rgb(124, 77, 255),
white = colour.rgb(255, 255, 255)
white = colour.rgb(255, 255, 255),
black = colour(0, 0, 0)
}
}

View File

@ -18,154 +18,105 @@ return {
]]--
local data = {}
local count = 0
self = data
self.id = idValue -- Unique Indentifier
self.pages = {} -- Where we store our pages for sidebar
teverse.construct("guiFrame", {
parent = teverse.interface,
size = guiCoord(0, 40, 0, 10),
position = guiCoord(0, 0, 0, 40),
backgroundColour = globals.defaultColours.secondary,
})
teverse.construct("guiFrame", {
parent = teverse.interface,
size = guiCoord(0, 40, 0, 10),
position = guiCoord(0, 0, 0, 180),
backgroundColour = globals.defaultColours.secondary,
})
--self.pages = {} -- Where we store our pages for sidebar
--self.activeTool = nil
local toolsContainer = teverse.construct("guiFrame", {
parent = teverse.interface,
size = guiCoord(0, 40, 0, 130),
position = guiCoord(0, 0, 0, 50),
backgroundColour = globals.defaultColours.white,
})
local selectTool = teverse.construct("guiIcon", {
parent = toolsContainer,
size = guiCoord(0, 20, 0, 20),
position = guiCoord(0.25, 0, 0, 10),
iconId = "location-arrow",
iconType = "faSolid",
iconColour = globals.defaultColours.primary,
backgroundColour = globals.defaultColours.white,
})
local moveTool = teverse.construct("guiIcon", {
parent = toolsContainer,
size = guiCoord(0, 20, 0, 20),
position = guiCoord(0.25, 0, 0, 40),
iconId = "arrows-alt-h",
iconType = "faSolid",
iconColour = globals.defaultColours.primary,
backgroundColour = globals.defaultColours.white,
})
local rotateTool = teverse.construct("guiIcon", {
parent = toolsContainer,
size = guiCoord(0, 20, 0, 20),
position = guiCoord(0.25, 0, 0, 70),
iconId = "sync",
iconType = "faSolid",
iconColour = globals.defaultColours.primary,
backgroundColour = globals.defaultColours.white,
})
local sizeTool = teverse.construct("guiIcon", {
parent = toolsContainer,
size = guiCoord(0, 20, 0, 20),
position = guiCoord(0.25, 0, 0, 100),
iconId = "expand",
iconType = "faSolid",
iconColour = globals.defaultColours.primary,
backgroundColour = globals.defaultColours.white,
})
local moreToolsContainer = teverse.construct("guiFrame", {
parent = teverse.interface,
name = "moreToolsContainer",
size = guiCoord(0, 40, 1, -190),
position = guiCoord(0, 0, 0, 190),
backgroundColour = globals.defaultColours.white,
size = guiCoord(0, 50, 1, 0),
position = guiCoord(0, 0, 0, 40),
backgroundColour = globals.defaultColours.primary,
strokeAlpha = 0.1,
zIndex = 199
})
self.registerPage = function(pageName)
--[[
@Description
Registers page to sidebar instance.
Registers page instance.
@Params
String, pageName
@Returns
guiFrame, page
instance, page
]]--
local _count = 0
local metadata = {}
self = metadata
local zIndexRange
if pageName == "Default" then -- Default page zIndex is set lower than other pages
zIndexRange = 100
else
zIndexRange = 101
end
local iconContainer = teverse.construct("guiFrame", {
parent = moreToolsContainer,
local container = teverse.construct("guiFrame", {
parent = toolsContainer,
name = pageName,
size = guiCoord(1, 0, 1, 0),
position = guiCoord(0, 0, 0, 0),
backgroundColour = globals.defaultColours.white,
zIndex = zIndexRange,
visible = false
size = guiCoord(1, 0, 0, 600),
position = guiCoord(0, 0, 0, 200),
backgroundAlpha = 0,
})
return iconContainer
end
self.registerIcon = function(page, name, icon, tooltip, callback, ...)
--[[
@Description
Registers icon to page instance.
self.getContainer = function() return container end
@Params
Instance, page
String, name
String, icon
String, tooltip
Method, callback
{...}, overrides
@Returns
Void, null, nil
]]--
local args = {...} -- Holds overrides
local xPositionOverride = args[1] or 0 -- Override if specified, else 0
local positionToolTipOverride = args[2] or guiCoord(0, 0, 0, 0) -- Override if specified, else guiCoord(0, 0, 0, 0)
local iconImage = teverse.construct("guiIcon", {
parent = page,
self.registerIcon = function(name, icon, callback)
local _icon = teverse.construct("guiIcon", {
parent = container,
name = name,
size = guiCoord(0, 20, 0, 20),
position = guiCoord((0.25+xPositionOverride), 0, 0, 10 + (#page.children*30)), -- Shorthand positioning w/o a for-loop
size = guiCoord(0, 32, 0, 32),
position = guiCoord(-1, 9, 0, (_count*42)+9),
iconId = icon,
iconType = "faSolid",
iconColour = globals.defaultColours.primary,
backgroundColour = globals.defaultColours.white,
iconAlpha = 0.75,
iconMax = 16,
strokeRadius = 3,
--backgroundAlpha = 0.15
})
local _tooltip = toolTip.construct("horizontal", iconImage, tooltip, positionToolTipOverride) -- Initialize tooltip instance
--button:mouseLeftPressed(callback) -- When button is clicked, perform callback action
-- When mouse hovers over button, display tooltip
iconImage:on("mouseEnter", function()
_tooltip.display()
_icon:on("mouseEnter", function()
_icon.backgroundAlpha = 0.15
end)
-- When mouse leaves from button, hide tooltip
iconImage:on("mouseExit", function()
_tooltip.hide()
_icon:on("mouseExit", function()
_icon.backgroundAlpha = 0
end)
_icon:on("mouseLeftUp", function()
_icon.dropShadowAlpha = 0.2
end)
_count = _count + 1
end
return metadata
end
self.registerDefaultIcon = function(icon, callback)
local icon = teverse.construct("guiIcon", {
parent = toolsContainer,
size = guiCoord(0, 32, 0, 32),
position = guiCoord(0, 9, 0, (count*42)+9),
iconId = icon,
iconType = "faSolid",
backgroundColour = globals.defaultColours.white,
iconAlpha = 0.75,
iconMax = 16,
strokeRadius = 3,
})
icon:on("mouseEnter", function()
icon.backgroundAlpha = 0.15
end)
icon:on("mouseExit", function()
icon.backgroundAlpha = 0
end)
icon:on("mouseLeftUp", function()
icon.dropShadowAlpha = 0.2
end)
count = count + 1
end
return data

View File

@ -5,7 +5,7 @@ local globals = require("tevgit:workshop/library/globals.lua") -- globals; varia
local toolTip = require("tevgit:workshop/library/ui/components/toolTip.lua") -- UI component
return {
construct = function(idValue, titleIconValue, titleValue)
construct = function(idValue, nameValue)
--[[
@Description
Constructor method that initializes the topbar instance.
@ -20,148 +20,205 @@ return {
]]--
local data = {}
local count = 0
local _count = 0
local clicked = false
local pushed = false
self = data -- Ease of use
self.id = idValue
self.title = titleValue
self.titleIcon = titleIconValue
self.id = idValue -- Unique indentifier
self.name = nameValue -- Name of scene being edited / developed on
self.keys = {} -- Where item keys are stored
self.pages = {}
self.defaultPage = nil
self.currentPage = nil
local container = teverse.construct("guiFrame", {
parent = teverse.interface,
name = idValue,
size = guiCoord(1, 0, 0, 40),
position = guiCoord(0, 0, 0, 0),
backgroundColour = globals.defaultColours.white,
dropShadowAlpha = 0.4,
dropShadowBlur = 2,
dropShadowColour = colour.rgb(127, 127, 127),
dropShadowOffset = vector2(0.5, 1),
zIndex = 200
})
teverse.construct("guiIcon", {
local subContainer = teverse.construct("guiFrame", {
parent = container,
size = guiCoord(0, 28, 0, 28),
position = guiCoord(0.01, 0, 0.1, 0),
iconId = titleIconValue,
size = guiCoord(0, 140, 0.8, 0),
position = guiCoord(0, 8, 0, 4),
backgroundColour = globals.defaultColours.primary,
backgroundAlpha = 0.15,
strokeRadius = 3,
zIndex = 900
})
local menuContainer = teverse.construct("guiFrame", {
parent = container,
size = guiCoord(0, 140, 0.01, 0),
position = guiCoord(0, 8, 0, 35),
backgroundColour = globals.defaultColours.primary,
backgroundAlpha = 0,
strokeWidth = 1,
zIndex = 900
})
self.animate = function(page, pos)
teverse.tween:begin(page, 0.5, { position = pos }, "inOutQuad")
end
local headerIcon = teverse.construct("guiIcon", {
parent = subContainer,
size = guiCoord(0, 32, 0, 32),
position = guiCoord(0, 0, 0, 0),
iconId = "cloud",
iconType = "faSolid",
iconColour = globals.defaultColours.primary,
backgroundColour = globals.defaultColours.white,
active = false,
backgroundColour = globals.defaultColours.primary,
backgroundAlpha = 0.1,
iconAlpha = 0.75,
iconMax = 16,
strokeRadius = 3,
})
teverse.construct("guiTextBox", {
parent = container,
size = guiCoord(0.5, 0, 0.1, 0),
position = guiCoord(0.04, 0, 0.05, 0),
text = titleValue,
textColour = globals.defaultColours.primary,
local function buildTabMenu()
local itemCount = 0
if (#data.pages == 0) then return end
for _,v in pairs(data.pages) do
for key, value in pairs(v) do
-- Key = (String) name of label
-- Value = (Object(guiFrame)) instance page
local _itemContainer = teverse.construct("guiFrame", {
parent = menuContainer,
size = guiCoord(1, 0, 0.3, 0),
position = guiCoord(0, 0, 0, (itemCount*21)+0),
backgroundColour = globals.defaultColours.red,
backgroundAlpha = 0,
zIndex = 200
})
local _itemButton = teverse.construct("guiTextBox", {
parent = _itemContainer,
size = guiCoord(0.97, 0, 1, 0),
position = guiCoord(0.03, 0, 0, 0),
text = key,
textAlign = "middle",
textSize = 20,
textFont = "tevurl:fonts/openSansBold.ttf",
textSize = 30
textColour = globals.defaultColours.white,
backgroundColour = globals.defaultColours.primary,
backgroundAlpha = 1,
zIndex = 200
})
teverse.construct("guiTextBox", {
parent = container,
size = guiCoord(0.48, 0, 0.1, 0),
position = guiCoord(0.86, 0, 0.1, 0),
text = globals.user.name,
local _itemContainerShader = teverse.construct("guiFrame", {
parent = _itemContainer,
size = guiCoord(0.03, 0, 1, 0),
position = guiCoord(0, 0, 0, 0),
backgroundColour = globals.defaultColours.white,
backgroundAlpha = 0
})
_itemButton:on("mouseEnter", function()
_itemContainerShader.backgroundAlpha = 0.15
end)
_itemButton:on("mouseExit", function()
_itemContainerShader.backgroundAlpha = 0
end)
_itemButton:on("mouseLeftUp", function()
print("Clicked")
--[[data.animate(data.currentPage, guiCoord(-1, 0, 0, 200))
sleep(0.5)
data.animate(value, guiCoord(1, 0, 0, 200))
data.currentPage = page]]--
end)
itemCount = itemCount + 1
end
end
end
headerIcon:on("mouseLeftUp", function()
if (clicked) then
menuContainer.backgroundAlpha = 1
menuContainer.strokeAlpha = 0.15
teverse.tween:begin(menuContainer, 0.5, { size = guiCoord(0, 140, 2.2, 0) }, "inOutQuad", buildTabMenu())
end
if (not clicked) then
teverse.tween:begin(menuContainer, 0.5, { size = guiCoord(0, 140, 0.01, 0) }, "inOutQuad", menuContainer:destroyChildren())
sleep(0.5)
menuContainer.strokeAlpha = 0
menuContainer.backgroundAlpha = 0
end
clicked = (not clicked)
end)
local headerText = teverse.construct("guiTextBox", {
parent = subContainer,
size = guiCoord(1, 0, 0, 32),
position = guiCoord(0, 40, 0, 0),
text = " "..nameValue,
textAlign = "middleLeft",
textSize = 20,
textFont = "tevurl:fonts/openSansBold.ttf",
textColour = globals.defaultColours.primary,
textSize = 25
backgroundColour = globals.defaultColours.primary,
backgroundAlpha = 0,
strokeRadius = 3
})
local userIcon = teverse.construct("guiFrame", {
self.registerIcon = function(icon, callback)
local icon = teverse.construct("guiIcon", {
parent = container,
size = guiCoord(0, 32, 0, 32),
position = guiCoord(0.82, 0, 0, 0),
position = guiCoord(1, (count*-37)-37, 0, 4),
iconId = icon,
iconType = "faSolid",
iconColour = globals.defaultColours.primary,
backgroundColour = globals.defaultColours.primary,
strokeRadius = 100
iconAlpha = 0.75,
iconMax = 16,
strokeRadius = 3,
zIndex = 900
})
local statusIcon = teverse.construct("guiFrame", {
parent = container,
size = guiCoord(0, 16, 0, 16),
position = guiCoord(0.836, 0, 0.5, 0),
backgroundColour = globals.defaultColours.green,
strokeWidth = 2,
strokeColour = globals.defaultColours.white,
strokeAlpha = 1,
strokeRadius = 32,
zIndex = 100
})
icon:on("mouseEnter", function()
icon.backgroundAlpha = 0.15
end)
local undoButton = teverse.construct("guiIcon", {
parent = container,
size = guiCoord(0, 20, 0, 20),
position = guiCoord(0.92, 0, 0.2, 0),
iconId = "arrow-left",
iconType = "faSolid",
iconColour = globals.defaultColours.primary,
backgroundColour = globals.defaultColours.white,
})
icon:on("mouseExit", function()
icon.backgroundAlpha = 0
end)
local redoButton = teverse.construct("guiIcon", {
parent = container,
size = guiCoord(0, 20, 0, 20),
position = guiCoord(0.94, 0, 0.2, 0),
iconId = "arrow-right",
iconType = "faSolid",
iconColour = globals.defaultColours.primary,
backgroundColour = globals.defaultColours.white,
})
icon:on("mouseLeftUp", function()
icon.iconAlpha = 1.0
icon.dropShadowAlpha = 0.2
end)
local settingsButton = teverse.construct("guiIcon", {
parent = container,
size = guiCoord(0, 20, 0, 20),
position = guiCoord(0.97, 0, 0.2, 0),
iconId = "sliders-h",
iconType = "faSolid",
iconColour = globals.defaultColours.primary,
backgroundColour = globals.defaultColours.white,
})
local test = self
self.register = function(name, tooltip, page)
--[[
@Description
Register method that appends to the topbar instance.
@Params
String, name
String, tooltip
Instance, page
@Returns
Void, null, nil
]]--
table.insert(test.keys, {name})
local button = teverse.construct("guiTextBox", {
parent = container,
size = guiCoord(0.056, 0, 0.9, 0),
position = guiCoord(0.2+(#test.keys*0.07), 0, 0.05, 0),
text = name,
textColour = globals.defaultColours.primary,
textSize = 22,
textAlign = enums.align.middle,
zIndex = 100
})
local _tooltip = toolTip.construct("vertical", button, tooltip) -- Initialize tooltip instance
button:on("mouseLeftDown", function()
globals.sideBarPageActive.visible = (not globals.sideBarPageActive.visible) -- Unlist active page from view
if globals.sideBarPageActive == page then -- If the same page is clicked twice, unlist and replace with default page
globals.sideBarPageActive = globals.sideBarPageDefault
globals.sideBarPageDefault.visible = true
return -- Acts as a break
count = count + 1
end
globals.sideBarPageActive = page
page.visible = (not page.visible)
end)
-- When mouse hovers over button, display tooltip
button:on("mouseEnter", function()
_tooltip.display()
end)
-- When mouse leaves from button, hide tooltip
button:on("mouseExit", function()
_tooltip.hide()
end)
self.bindDefaultMenu = function(page)
self.defaultPage = page
self.currentPage = page
data.animate(page, guiCoord(1, 0, 0, 200))
end
self.bindMenu = function(name, page)
table.insert(data.pages, #data.pages+1, { [name] = page })
_count = _count + 1
end
--self.defaultPage = nil
--self.currentPage = nil
return data
end
}

View File

@ -2,54 +2,69 @@
-- This script is responsible for creating the workshop interface
local globals = require("tevgit:workshop/library/globals.lua") -- globals; variables or instances that can be shared between files
--local prompt = require("tevgit:workshop/library/ui/components/prompt.lua") -- UI Component
local topbarInterface = require("tevgit:workshop/library/ui/controllers/topbarInterface.lua") -- UI Controller
local sidebarInterface = require("tevgit:workshop/library/ui/controllers/sidebarInterface.lua") -- UI Controller
local topBar = topbarInterface.construct("horizontalNavbar", "cloud", "Test Place 1") -- Create initial topbar instance
local topBar = topbarInterface.construct("horizontalNavbar", "Test Place 1") -- Create initial topbar instance
local sideBar = sidebarInterface.construct("verticalNavbar") -- Create initial sidebar instance
-- Register default tools to topbar instance
topBar.registerIcon("sliders-h", nil)
topBar.registerIcon("arrow-right", nil)
topBar.registerIcon("arrow-left", nil)
-- Register default tools to sidebar instance
sideBar.registerDefaultIcon("location-arrow", nil)
sideBar.registerDefaultIcon("arrows-alt-h", nil)
sideBar.registerDefaultIcon("sync", nil)
sideBar.registerDefaultIcon("expand", nil)
local defaultPage = sideBar.registerPage("Default") -- Register default page to sidebar instance
sideBar.registerIcon(defaultPage, "openFolderIcon", "folder-open", "Open Folder", nil)
sideBar.registerIcon(defaultPage, "newFileIcon", "file", "Create new file", nil)
sideBar.registerIcon(defaultPage, "uploadFileIcon", "file-upload", "Upload current file", nil)
sideBar.registerIcon(defaultPage, "downloadFileIcon", "file-download", "Download current file", nil)
sideBar.registerIcon(defaultPage, "importFileIcon", "file-import", "Import a file", nil, -0.048, guiCoord(0.048, 0, 0, 0))
sideBar.registerIcon(defaultPage, "exportFileIcon", "file-export", "Export current file", nil, 0.048, guiCoord(-0.048, 0, 0, 0))
defaultPage.visible = true -- Set default sidebar page to visible
globals.sideBarPageDefault = defaultPage -- Set default sidebar page to default
globals.sideBarPageActive = defaultPage -- Set default sidebar page as active
local designPage = sideBar.registerPage("Design") -- Design default page to sidebar instance
sideBar.registerIcon(designPage, "screenContainerIcon", "tv", "Create a container instance", nil)
sideBar.registerIcon(designPage, "guiFrameIcon", "square-full", "Create a guiFrame instance", nil)
sideBar.registerIcon(designPage, "guiTextBoxIcon", "i-cursor", "Create a guiTextBox instance", nil)
sideBar.registerIcon(designPage, "guiImageIcon", "image", "Create a guiImage instance", nil)
defaultPage.registerIcon("openFolderIcon", "folder-open", nil)
defaultPage.registerIcon("newFileIcon", "file", nil)
defaultPage.registerIcon("uploadFileIcon", "file-upload", nil)
defaultPage.registerIcon("downloadFileIcon", "file-download", nil)
defaultPage.registerIcon("importFileIcon", "file-import", nil)
defaultPage.registerIcon("exportFileIcon", "file-export", nil)
--globals.sideBarPageDefault = defaultPage -- Set default sidebar page to default
--globals.sideBarPageActive = defaultPage -- Set default sidebar page as active
local designPage = sideBar.registerPage("Design") -- Register design page to sidebar instance
designPage.registerIcon("screenContainerIcon", "tv", nil)
designPage.registerIcon("guiFrameIcon", "square-full", nil)
designPage.registerIcon("guiTextBoxIcon", "i-cursor", nil)
designPage.registerIcon("guiImageIcon", "image", nil)
local modelPage = sideBar.registerPage("Model") -- Register model page to sidebar instance
sideBar.registerIcon(modelPage, "modelIcon", "shapes", "Group instance(s) together", nil)
modelPage.registerIcon("modelIcon", "shapes", nil)
local insertPage = sideBar.registerPage("Insert") -- Register insert page to sidebar instance
sideBar.registerIcon(insertPage, "blockIcon", "cube", "Create a cube instance", nil)
sideBar.registerIcon(insertPage, "circleIcon", "circle", "Create a cylinder instance", nil)
--sideBar.registerIcon(designPage, "triangleIcon", "i-cursor", nil, nil) -- Triangle / Wedge Icon doesn't exist
sideBar.registerIcon(insertPage, "scriptIcon", "code", "Create a script instance", nil)
sideBar.registerIcon(insertPage, "lightIcon", "lightbulb", "Create a light instance", nil)
insertPage.registerIcon("blockIcon", "cube", nil)
insertPage.registerIcon("circleIcon", "circle", nil)
insertPage.registerIcon("scriptIcon", "code", nil)
insertPage.registerIcon("lightIcon", "lightbulb", nil)
local testPage = sideBar.registerPage("Test") -- Register test page to sidebar instance
sideBar.registerIcon(testPage, "consoleIcon", "terminal", " Open console window", nil)
sideBar.registerIcon(testPage, "playIcon", "play", "Play scene", nil)
sideBar.registerIcon(testPage, "serverIcon", "server", "Configure server", nil)
sideBar.registerIcon(testPage, "fullScreenIcon", "expand-alt", "Toggle full screen", nil)
testPage.registerIcon("consoleIcon", "terminal", nil)
testPage.registerIcon("playIcon", "play", nil)
testPage.registerIcon("serverIcon", "server", nil)
testPage.registerIcon("fullScreenIcon", "expand-alt", nil)
-- Bind pages to labels in menu
topBar.bindDefaultMenu(defaultPage.getContainer())
topBar.bindMenu("Design", designPage.getContainer())
topBar.bindMenu("Model", modelPage.getContainer())
topBar.bindMenu("Insert", insertPage.getContainer())
topBar.bindMenu("Test", testPage.getContainer())
--[[
-- Register topbar button (name labels) to topbar instance
topBar.register("Design", "Design your guis", designPage)
topBar.register("Model", "Model your scene", modelPage)
topBar.register("Insert", "Insert an instance to your scene", insertPage)
topBar.register("Test", "Test your scene", testPage)
]]--