Created by Nexity#3200
Features:
- CUSTOM 3D RENDERING ENGINE
- CONTROLS
- T – move forward
G – move backwards
F – move left
H – move right
R – move up
Y – move down - Z – rotate to the right
X – rotate to the left
C – pitch down
V – pitch up
- T – move forward
local function divide(a, b)
if b == 0 or a == 0 then
return 0
else
return a / b
end
end
function rotate(wireframe, c, yaw, pitch) -- function generated by chatgpt, god bless chatgpt for saving this project
local yaw = math.rad(yaw)
local pitch = math.rad(pitch)
local cos_yaw = math.cos(yaw)
local sin_yaw = math.sin(yaw)
local cos_pitch = math.cos(pitch)
local sin_pitch = math.sin(pitch)
local rotated_points = {}
for _, point in pairs(wireframe) do
if type(point) == "table" then
local x = point[1] - c[1]
local y = point[2] - c[2]
local z = point[3] - c[3]
local x_ = x * cos_yaw - z * sin_yaw
local z_ = x * sin_yaw + z * cos_yaw
local y_ = y * cos_pitch - z_ * sin_pitch
local z__ = y * sin_pitch + z_ * cos_pitch
x = x_ + c[1]
y = y_ + c[2]
z = z__ + c[3]
table.insert(rotated_points, {x, y, z})
end
end
return rotated_points
end
local function getcube(x, y, z, size, offset)
local offset_x, offset_y, offset_z = unpack(offset)
return {
"cube",
{x + offset_x, y + offset_y, z + offset_z},
{x + offset_x, y + offset_y, z + size + offset_z},
{x + offset_x, y + size + offset_y, z + offset_z},
{x + offset_x, y + size + offset_y, z + size + offset_z},
{x + size + offset_x, y + offset_y, z + offset_z},
{x + size + offset_x, y + offset_y, z + size + offset_z},
{x + size + offset_x, y + size + offset_y, z + offset_z},
{x + size + offset_x, y + size + offset_y, z + size + offset_z},
}
end
local function rotatewireframes(wireframes, rotation, center)
local wireframetoreturn = {}
for _, wireframe in pairs(wireframes) do
local afterrotated = rotate(wireframe, center, rotation[1], rotation[2])
if wireframe[1] == "cube" then
local edges = {
{afterrotated[1], afterrotated[2]},
{afterrotated[1], afterrotated[3]},
{afterrotated[2], afterrotated[4]},
{afterrotated[3], afterrotated[4]},
{afterrotated[5], afterrotated[6]},
{afterrotated[5], afterrotated[7]},
{afterrotated[6], afterrotated[8]},
{afterrotated[7], afterrotated[8]},
{afterrotated[1], afterrotated[5]},
{afterrotated[2], afterrotated[6]},
{afterrotated[3], afterrotated[7]},
{afterrotated[4], afterrotated[8]},
}
table.insert(wireframetoreturn, edges)
end
end
return wireframetoreturn
end
local function raycast(points, focal_length, camera)
local toreturn = {}
for _, point in pairs(points) do
local z1 = math.max(1, point[1][3])
local z2 = math.max(1, point[2][3])
local xp1 = (focal_length * point[1][1] / z1) + camera[1]
local yp1 = (focal_length * point[1][2] / z1) + camera[2]
local xp2 = (focal_length * point[2][1] / z2) + camera[1]
local yp2 = (focal_length * point[2][2] / z2) + camera[2]
table.insert(toreturn, {{xp1, yp1}, {xp2, yp2}})
end
return toreturn
end
local function dda(x1, y1, x2, y2)
local dx = x2 - x1
local dy = y2 - y1
local steps
if math.abs(dx) > math.abs(dy) then
steps = math.abs(dx)
else
steps = math.abs(dy)
end
local x_inc = dx / steps
local y_inc = dy / steps
local x = x1
local y = y1
local points = {}
for i = 0, math.floor(steps) do
if math.max(x1, x2) >= x and x >= math.min(x1, x2) and math.max(y1, y2) >= y and y >= math.min(y1, y2) then
table.insert(points, {math.round(x), math.round(y)})
x = x + x_inc
y = y + y_inc
end
end
return points
end
local function renderthewireframes(wireframes, focal_length, camera, rotation)
local timages = {}
for y=1, 33, 1 do
local temp_list = {}
for x=1, 60, 1 do
table.insert(temp_list, 0)
end
table.insert(timages, temp_list)
end
for _, wireframe in pairs(wireframes) do
local afterrendered = raycast(wireframe, focal_length, camera)
for _, edge in pairs(afterrendered) do
local x1, y1, x2, y2 = edge[1][1], edge[1][2], edge[2][1], edge[2][2]
local line_points = dda(x1, y1, x2, y2)
for _, point in pairs(line_points) do
if 60 >= point[1] and point[1] > 0 and 33 >= point[2] and point[2] > 0 then
timages[point[2]][point[1]] = 1
end
end
end
end
--print(dump(timages))
local finalstring = "\n"
for y=1, 33, 1 do
local temp_str = ""
for x=1, 60, 1 do
if timages[y][x] == 1 then
temp_str = temp_str .. "?"
else
temp_str = temp_str .. "?"
end
end
finalstring = finalstring .. temp_str .. "\n"
end
return finalstring
end
local updateremote = game:GetService("ReplicatedStorage").CustomiseBooth
function update(text)
local args = {
[1] = "Update",
[2] = {
["DescriptionText"] = text,
["ImageId"] = 0
}
}
updateremote:FireServer(unpack(args))
end
local size = 30
local focal_length = 70
local camera_position = {25, 25, 0}
local translate_position = {-10, -40, 0}
local camera_rotation = {0, 0}
local UIS = game:GetService("UserInputService")
local buttonsDown = {}
UIS.InputBegan:Connect(function(input, gameProcessedEvent)
if gameProcessedEvent then return end
local initTick = tick()
while UIS:IsKeyDown(input.KeyCode) do
buttonsDown[input.KeyCode] = true
task.wait()
end
buttonsDown[input.KeyCode] = nil
end)
local function kbp(key)
return buttonsDown[key] == true
end
_G.Enabled = true
while _G.Enabled do
--print(translate_position[1], translate_position[2], translate_position[3])
local angle = math.rad(camera_rotation[1]) -- movement relative to camera generated by chatgpt
local x, y = math.cos(angle), math.sin(angle)
if kbp(Enum.KeyCode.T) then
translate_position = {translate_position[1] - (y * 1), translate_position[2], translate_position[3] - (x * 1)}
elseif kbp(Enum.KeyCode.G) then
translate_position = {translate_position[1] + (y * 1), translate_position[2], translate_position[3] + (x * 1)}
elseif kbp(Enum.KeyCode.F) then
translate_position = {translate_position[1] + (x * 1), translate_position[2], translate_position[3] - (y * 1)}
elseif kbp(Enum.KeyCode.H) then
translate_position = {translate_position[1] - (x * 1), translate_position[2], translate_position[3] + (y * 1)}
elseif kbp(Enum.KeyCode.R) then
translate_position = {translate_position[1], translate_position[2] + 1, translate_position[3]}
elseif kbp(Enum.KeyCode.Y) then
translate_position = {translate_position[1], translate_position[2] - 1, translate_position[3]}
elseif kbp(Enum.KeyCode.Z) then
camera_rotation = {camera_rotation[1] + 1, camera_rotation[2]}
elseif kbp(Enum.KeyCode.X) then
camera_rotation = {camera_rotation[1] - 1, camera_rotation[2]}
elseif kbp(Enum.KeyCode.C) then
camera_rotation = {camera_rotation[1], camera_rotation[2] + 1}
elseif kbp(Enum.KeyCode.V) then
camera_rotation = {camera_rotation[1], camera_rotation[2] - 1}
end
local s = math.round(size / 2)
local wireframes = {
getcube(0, 25 - s, 0, size, translate_position),
getcube(size * 2, 25 - s, 0, size, translate_position),
getcube(0, 25 - s, size * 2, size, translate_position),
getcube(size * 2, 25 - s, size * 2, size, translate_position),
}
--[[
local wireframes = {
getcube(25 - s, 25 - s, 0, size, translate_position),
getcube(25 - s, 25 - s, size, size, translate_position),
getcube(25 - s, 25 - s, size * 2, size, translate_position),
getcube(25 - s, 25 - s, size * 3, size, translate_position),
getcube(25 - s, 25 - s, size * 4, size, translate_position),
getcube(25 - s, 25 - s, size * 5, size, translate_position),
getcube(25 - s, 25 - s, size * 6, size, translate_position),
getcube(25 - s, 25 - s, size * 7, size, translate_position)
}]]
local rotated = rotatewireframes(wireframes, camera_rotation, camera_position)
local rendered = renderthewireframes(rotated, focal_length, camera_position, camera_rotation[1])
--print(rendered)
coroutine.wrap(update)(rendered)
task.wait(0.033)
end