mirror of
https://github.com/IgorTimofeev/MineOS.git
synced 2025-12-20 02:59:20 +01:00
Sphere wallpaper
This commit is contained in:
parent
726bd8f679
commit
19d3726220
BIN
Wallpapers/Sphere.wlp/Icon.pic
Normal file
BIN
Wallpapers/Sphere.wlp/Icon.pic
Normal file
Binary file not shown.
207
Wallpapers/Sphere.wlp/Main.lua
Normal file
207
Wallpapers/Sphere.wlp/Main.lua
Normal file
@ -0,0 +1,207 @@
|
||||
local screen = require("Screen")
|
||||
local color = require("Color")
|
||||
local filesystem = require("Filesystem")
|
||||
local system = require("System")
|
||||
local GUI = require("GUI")
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
local workspace, wallpaper = select(1, ...), select(2, ...)
|
||||
|
||||
local configPath = filesystem.path(system.getCurrentScript()) .. "Config.cfg"
|
||||
|
||||
local config = {
|
||||
backgroundColor = 0x000000,
|
||||
|
||||
sphereRadius = 20,
|
||||
sphereColor = 0xFFFFFF,
|
||||
spherePos = {20, 0, 0},
|
||||
|
||||
lightColor = 0xFFFF40,
|
||||
diffuseIntensity = 12,
|
||||
ambientIntensity = 0.1,
|
||||
specularIntensity = 0.5,
|
||||
specularPower = 1,
|
||||
|
||||
speed = 5
|
||||
}
|
||||
|
||||
if filesystem.exists(configPath) then
|
||||
for key, value in pairs(filesystem.readTable(configPath)) do
|
||||
config[key] = value
|
||||
end
|
||||
end
|
||||
|
||||
local function saveConfig()
|
||||
filesystem.writeTable(configPath, config)
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
local function vecNormalize(vec)
|
||||
local length = (vec[1]^2 + vec[2]^2 + vec[3]^2)^0.5
|
||||
if length < 0.00001 then
|
||||
length = 0.00001
|
||||
end
|
||||
|
||||
return {
|
||||
vec[1] / length,
|
||||
vec[2] / length,
|
||||
vec[3] / length
|
||||
}
|
||||
end
|
||||
|
||||
local function vecSubtract(a, b)
|
||||
return {a[1] - b[1], a[2] - b[2], a[3] - b[3]}
|
||||
end
|
||||
|
||||
local function vecAdd(a, b)
|
||||
return {a[1] + b[1], a[2] + b[2], a[3] + b[3]}
|
||||
end
|
||||
|
||||
local function vecScalarProduct(vec, scalar)
|
||||
return {vec[1] * scalar, vec[2] * scalar, vec[3] * scalar}
|
||||
end
|
||||
|
||||
local function vecHadamardProduct(a, b)
|
||||
return {a[1] * b[1], a[2] * b[2], a[3] * b[3]}
|
||||
end
|
||||
|
||||
local function vecDotProduct(a, b)
|
||||
return a[1] * b[1] + a[2] * b[2] + a[3] * b[3]
|
||||
end
|
||||
|
||||
local function vecSqrDistance(a, b)
|
||||
return (a[1] - b[1])^2 + (a[2] - b[2])^2 + (a[3] - b[3])^2
|
||||
end
|
||||
|
||||
local function vecIntegerToRGB(integer)
|
||||
local r, g, b = color.integerToRGB(integer)
|
||||
return {
|
||||
r / 0xFF,
|
||||
g / 0xFF,
|
||||
b / 0xFF
|
||||
}
|
||||
end
|
||||
|
||||
local function vecRGBToInteger(vec)
|
||||
return color.RGBToInteger(
|
||||
math.floor(vec[1] * 0xFF),
|
||||
math.floor(vec[2] * 0xFF),
|
||||
math.floor(vec[3] * 0xFF)
|
||||
)
|
||||
end
|
||||
|
||||
local function clamp(value, min, max)
|
||||
if value < min then return min end
|
||||
if value > max then return max end
|
||||
return value
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
local lightSpinRadius, sphereRadiusSqr, lightColorVec, sphereColorVec, colorProduct, viewPos, startTime
|
||||
|
||||
local function precalculateValues()
|
||||
lightSpinRadius = config.sphereRadius + 5
|
||||
sphereRadiusSqr = config.sphereRadius^2
|
||||
lightColorVec = vecIntegerToRGB(config.lightColor)
|
||||
sphereColorVec = vecIntegerToRGB(config.sphereColor)
|
||||
colorProduct = vecHadamardProduct(lightColorVec, sphereColorVec)
|
||||
viewPos = {0, 0, 500}
|
||||
startTime = computer.uptime()
|
||||
end
|
||||
|
||||
precalculateValues()
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
wallpaper.draw = function(wallpaper)
|
||||
local t = config.speed * (computer.uptime() - startTime) / 10
|
||||
|
||||
local lightPos = {lightSpinRadius * math.cos(t), lightSpinRadius * 0.5 * math.cos(t), lightSpinRadius * math.sin(t)}
|
||||
local cx, cy = math.floor(wallpaper.width / 2), wallpaper.height
|
||||
|
||||
screen.drawRectangle(wallpaper.x, wallpaper.y, wallpaper.width, wallpaper.height, config.backgroundColor, 0, " ")
|
||||
|
||||
for x = -config.sphereRadius, config.sphereRadius do
|
||||
for y = -config.sphereRadius, config.sphereRadius do
|
||||
if x^2 + y^2 <= sphereRadiusSqr then
|
||||
local fragPos = {x, y, (config.sphereRadius^2 - x^2 - y^2)^0.5}
|
||||
|
||||
local L = vecNormalize(vecSubtract(lightPos, fragPos))
|
||||
local N = vecNormalize(fragPos)
|
||||
local V = vecNormalize(vecSubtract(viewPos, fragPos))
|
||||
local LN = vecDotProduct(L, N)
|
||||
local Lr = vecNormalize(vecSubtract(vecScalarProduct(N, 2 * LN), L))
|
||||
|
||||
local distance = vecSqrDistance(lightPos, fragPos)
|
||||
|
||||
local diffuse = clamp((LN / distance) * config.diffuseIntensity, 0, 1)
|
||||
local specular = clamp(vecDotProduct(Lr, V), 0, 1)^config.specularPower * config.specularIntensity
|
||||
|
||||
local fragColor = vecScalarProduct(colorProduct, diffuse)
|
||||
fragColor = vecAdd(fragColor, vecScalarProduct(colorProduct, config.ambientIntensity))
|
||||
fragColor = vecAdd(fragColor, vecScalarProduct(lightColorVec, specular))
|
||||
|
||||
screen.semiPixelSet(cx + x, cy + y, vecRGBToInteger(fragColor))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if lightPos[1]^2 + lightPos[2]^2 > sphereRadiusSqr or lightPos[3] > (config.sphereRadius^2 - lightPos[1]^2 - lightPos[2]^2)^0.5 then
|
||||
screen.semiPixelSet(cx + math.floor(lightPos[1]), cy + math.floor(lightPos[2]), config.lightColor)
|
||||
end
|
||||
end
|
||||
|
||||
wallpaper.configure = function(layout)
|
||||
local function addColorSelector(configValue, title)
|
||||
layout:addChild(GUI.colorSelector(1, 1, 36, 3, config[configValue], title)).onColorSelected = function(_, object)
|
||||
config[configValue] = object.color
|
||||
saveConfig()
|
||||
precalculateValues()
|
||||
end
|
||||
end
|
||||
|
||||
local function addSlider(configValue, title, minValue, maxValue, roundValues)
|
||||
local slider = layout:addChild(
|
||||
GUI.slider(
|
||||
1, 1,
|
||||
36,
|
||||
0x66DB80,
|
||||
0xE1E1E1,
|
||||
0xFFFFFF,
|
||||
0xA5A5A5,
|
||||
minValue, maxValue,
|
||||
config[configValue],
|
||||
false,
|
||||
title
|
||||
)
|
||||
)
|
||||
|
||||
slider.roundValues = roundValues
|
||||
slider.onValueChanged = function()
|
||||
if roundValues then
|
||||
config[configValue] = math.floor(slider.value)
|
||||
else
|
||||
config[configValue] = slider.value
|
||||
end
|
||||
|
||||
saveConfig()
|
||||
precalculateValues()
|
||||
end
|
||||
end
|
||||
|
||||
addColorSelector("backgroundColor", "Background color")
|
||||
addColorSelector("sphereColor", "Sphere color" )
|
||||
addColorSelector("lightColor", "Light color" )
|
||||
|
||||
addSlider("sphereRadius", "Sphere radius: ", 5, 50, true )
|
||||
addSlider("diffuseIntensity", "Diffuse intensity: ", 0, 50, false)
|
||||
addSlider("ambientIntensity", "Ambient intensity: ", 0, 1, false)
|
||||
addSlider("specularIntensity", "Specular intensity: ", 0, 5, false)
|
||||
addSlider("specularPower", "Specular power: ", 1, 50, true )
|
||||
addSlider("speed", "Speed: ", 1, 10, false)
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
Loading…
x
Reference in New Issue
Block a user