Instantly share code, notes, and snippets.

# Ivoah/3d.lua

Created Jul 8, 2015
3D Demo for PICO-8 (http://www.lexaloffle.com/pico-8.php) with comments
 --3demo --simple 3d demo -- Here is the data for the 3d model -- The first section is the 3d location -- of each point on the cube, and the -- second section is the lines that -- connect the points cube = {{{-1,-1,-1}, -- points {-1,-1,1}, {1,-1,1}, {1,-1,-1}, {-1,1,-1}, {-1,1,1}, {1,1,1}, {1,1,-1}, {-0.5,-0.5,-0.5}, -- inside {-0.5,-0.5,0.5}, {0.5,-0.5,0.5}, {0.5,-0.5,-0.5}, {-0.5,0.5,-0.5}, {-0.5,0.5,0.5}, {0.5,0.5,0.5}, {0.5,0.5,-0.5}}, {{1,2}, -- lines {2,3}, {3,4}, {4,1}, {5,6}, {6,7}, {7,8}, {8,5}, {1,5}, {2,6}, {3,7}, {4,8}, {8+1,8+2}, -- inside {8+2,8+3}, {8+3,8+4}, {8+4,8+1}, {8+5,8+6}, {8+6,8+7}, {8+7,8+8}, {8+8,8+5}, {8+1,8+5}, {8+2,8+6}, {8+3,8+7}, {8+4,8+8}, {1,9},-- {2,10}, {3,11}, {4,12}, {5,13}, {6,14}, {7,15}, {8,16}}} function _init() cam = {0,0,-2.5} -- Initilise the camera position mult = 64 -- View multiplier a = flr(rnd(3))+1 -- Angle for random rotation t = flr(rnd(50))+25 -- Time until next angle change end function _update() -- Handle the inputs if btn(0) then cam -= 0.1 end if btn(1) then cam += 0.1 end if btn(2) then cam += 0.1 end if btn(3) then cam -= 0.1 end if btn(4) then cam -= 0.1 end if btn(5) then cam += 0.1 end t -= 1 -- Decrease time until next angle change if t <= 0 then -- If t is 0 then change the random angle and restart the timer t = flr(rnd(50))+25 -- Restart timer a = flr(rnd(3))+1 -- Update angle end cube = rotate_shape(cube,a,0.01) -- Rotate our cube end function _draw() cls() -- Clear the screen print("t="..t,0,6*0) -- Print time until angle change print("x="..cam,0,6*1) -- Print x, y, and z location of the camera print("y="..cam,0,6*2) print("z="..cam,0,6*3) draw_shape(cube) -- Draw the cube end function draw_shape(s,c) for l in all(s) do -- For each line in the shape... draw_line(s[l], s[l], c) -- Draw the line end end function draw_line(p1,p2,c) x0, y0 = project(p1) -- Get the 2d location of the 3d points... x1, y1 = project(p2) line(x0, y0, x1, y1, c or 11) -- And draw a line between them end function draw_point(p,c) x, y = project(p) -- Get the 2d location of the 3d point... pset(x, y, c or 11) -- And draw the point end function project(p) x = (p-cam)*mult/(p-cam) + 127/2 -- Calculate x and center it y = -(p-cam)*mult/(p-cam) + 127/2 -- Calculate y and center it return x, y -- Return the two points end function translate_shape(s,t) ns = {{},s} -- Copy the shape, but zero out the points and keep the lines for p in all(s) do -- For each point in the original shape... add(ns,{p+t,p+t,p+t}) -- Add the displacement to the point and add it to our new shape end return ns -- Return the new shape end function rotate_shape(s,a,r) ns = {{},s} -- Copy the shape, but zero out the points and keep the lines for p in all(s) do -- For each point in the original shape... add(ns, rotate_point(p,a,r)) -- Rotate the point and add it to the new shape end return ns -- Return the new shape end function rotate_point(p,a,r) -- Figure out which axis we're rotating on if a==1 then x,y,z = 3,2,1 elseif a==2 then x,y,z = 1,3,2 elseif a==3 then x,y,z = 1,2,3 end _x = cos(r)*(p[x]) - sin(r) * (p[y]) -- Calculate the new x location _y = sin(r)*(p[x]) + cos(r) * (p[y]) -- Calculate the new y location np = {} -- Make new point and assign the new x and y to the correct axes np[x] = _x np[y] = _y np[z] = p[z] return np -- Return new point end

### kevinhamil commented Jun 7, 2016 • edited

 I'm attempting to adapt some of your demo code for a project, but I'm pretty new to this. Could you please explain what causes the shape to flip and mirror itself back into the view once the camera has moved past the object on the z axis? I want to avoid this, but I'm not sure what is causing it or what bit of code I need in order to prevent it. I appreciate it.