#### Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

# 3D block engine

edited March 2014 Posts: 425

Here is a little 3D block engine I made, thanks @Ignatz for your excellent tutorial explaining the basic principles of 3D.

• Posts: 425
``````--# Main
-- 3D
displayMode(OVERLAY)

function setup()
Zangle = 0
FieldOfView=45
CamHeight=300
Angle=0
blocktypes={"Planet Cute:Stone Block","Planet Cute:Dirt Block","Planet Cute:Grass Block"}
blocks = {}
worldwidth = 20
worldlength = 20
worldheight = 5
for x = 1, worldwidth do
blocks[x]={}
for y = 1, worldlength do
blocks[x][y]={}
maxheight = math.random(worldheight-3,worldheight)
for z = 1,maxheight do
if z == maxheight and maxheight > 2 then
createblock(x,y,z,3)
-- grass
elseif z == 1 then
createblock(x,y,z,1)
-- stone
else
createblock(x,y,z,2)
-- dirt
end
end
end
end

ground = Floor(-101,-51,-101,
(worldwidth+1)*101,(worldlength+1)*101,"SpaceCute:Background")
camX,camY,camZ, camfocusX,camfocusY,camfocusZ = 0,(worldheight+10)*101,0,0,0,0
parameter.watch("FPS")
--[[
parameter.integer("camX",-worldwidth*101 ,worldwidth*101,0)
parameter.integer("camZ",-worldlength*101,worldlength*101,0)
--]]
print("Swipe to look around.")
end

function draw()
FPS=1/DeltaTime
background(0)
perspective(FieldOfView, WIDTH/HEIGHT)
camera(camX,camY,camZ, camfocusX, camfocusY, camfocusZ, 1, 0,0)
-- pushMatrix()
for x =1, #blocks do
for y =1, #blocks[x] do
for z =1, #blocks[x][y] do
blocks[x][y][z]:draw()
end
end
end
ground:draw()
end

function touched(touch)
camX = camX - touch.deltaY *4
camZ = camZ - touch.deltaX *4
end

function createblock(x,y,z,t)
blocks[x][y][z] =
Block(100.1*(x-worldwidth/2-1.5),100.1*(z-1),100.1*(y-worldlength/2-1.5),
100,100,100,blocktypes[t],
{0.03,0.24,0.97,0.69})
end

--# Block
Block = class()

function Block:init(x,y,z,w,h,d,t,r,o)
self.x = x
self.y = y
self.z = z
self.width = w -- width
self.height = h -- height
self.depth = d -- depth
self.texture = t
self.texR = r or {0,0,1,1}
self.opacity = o or 255
self.block = self:createblock()

end

function Block:createblock()
local w,h,d = self.width,self.height,self.depth
-- right = +
-- up = +
-- front = +
--table of the verticies of a cube
--x ,y, z
local v =
{
vec3(-0.5*w +self.x,-0.5*h +self.y,0.5*d +self.z), -- left  bottom front --+
vec3(0.5*w +self.x,-0.5*h +self.y,0.5*d +self.z), --  right bottom front +-+
vec3(0.5*w +self.x,0.5*h +self.y,0.5*d +self.z), --   right top    front +++
vec3(-0.5*w +self.x,0.5*h +self.y,0.5*d +self.z), --  left  top    front -++

vec3(-0.5*w +self.x,-0.5*h +self.y,-0.5*d +self.z), --left  bottom back  ---
vec3(0.5*w +self.x,-0.5*h +self.y,-0.5*d +self.z), -- right bottom back  +--
vec3(0.5*w +self.x,0.5*h +self.y,-0.5*d +self.z), --  right top    back  ++-
vec3(-0.5*w +self.x,0.5*h +self.y,-0.5*d +self.z), -- left  top    back  -+-
}

local cubeverts =
{
-- front face
v, v, v, v, v, v,

-- right face
v, v, v, v, v, v,

-- back face
v, v, v, v, v, v,

-- left face
v, v, v, v, v, v,

-- top face
v, v, v, v, v, v,

-- bottom face
v, v, v, v, v, v,
}

local BL=vec2(self.texR,self.texR) --bottom left
local BR=vec2(self.texR,self.texR) --bottom right
local TR=vec2(self.texR,self.texR) --top right
local TL=vec2(self.texR,self.texR) --top left

local cubetexCoords = {}
for i=1,6 do
table.insert(cubetexCoords,BL)
table.insert(cubetexCoords,BR)
table.insert(cubetexCoords,TR)
table.insert(cubetexCoords,BL)
table.insert(cubetexCoords,TR)
table.insert(cubetexCoords,TL)
end

local ms = mesh()
ms.vertices = cubeverts

ms.texture = self.texture
ms.texCoords = cubetexCoords
ms:setColors(255,255,255,self.opacity)
return ms
end

function Block:draw()
self.block:draw()
end

--# Floor
Floor = class()

function Floor:init(x,y,z,w,l,t)
self.x = x
self.y = y
self.z = z
self.width = w --x axis
self.length = l --z axis
self.texture = t
self.floor = self:createfloor()
end

function Floor:draw()
self.floor:draw()
end

function Floor:createfloor()
local x,y,z,w,l = self.x,self.y,self.z,self.width,self.length
local v =
{
vec3(x +0.5*w, y, z+0.5*l), --right front
vec3(x +-0.5*w, y,z+0.5*l), --left front
vec3(x +0.5*w, y, z+-0.5*l), -- right back
vec3(x +-0.5*w, y, z+-0.5*l) -- left back
}
local floorverts = --mesh is split from left front to right back
{
v,v,v,
v,v,v
}

local tcoords =
{
vec2(0,0),
vec2(1,0),
vec2(1,1),
vec2(0,0),
vec2(0,1),
vec2(1,1)
}

local r,g = color(255,0,0),color(0,255,0)

local floormesh = mesh()
floormesh.vertices =floorverts
floormesh:setColors(255,255,255,255)
floormesh.texture =self.texture
floormesh.texCoords = tcoords
return floormesh
end

``````
• Posts: 2,820

Very nice job!

• Posts: 425

@Zoyt thanks

• Posts: 3,295

• edited March 2014 Posts: 500

could something like maincraft be done in codea? I ask because the fps is already at 30... but maybe there are sone tricks to optimize. worth to try, isnt it? • Posts: 342

Terraria maybe, it seems like there's an FPS issue in MCPE as is, I don't think there's enough techno-sorcery here to make something of that scale work in codea. Then again, I've been surprised by the ingenuity (and crazy optimization tricks) of the codea user-base before, so I'm probably 100% wrong XD

• Posts: 425

I could make it faster by using one mesh for all the blocks rather than one mesh for each block.