pixelfaucet/examples/3d.cr

147 lines
3.8 KiB
Crystal
Raw Normal View History

2021-12-18 22:47:12 +01:00
require "../src/game"
require "../src/controller"
require "../src/sprite"
require "../src/pixel"
require "../src/vector"
require "../src/sprite"
2021-12-18 22:47:12 +01:00
require "../src/3d/*"
class ThreeDee < PF::Game
2021-12-20 05:17:51 +01:00
@projector : PF::Projector
2021-12-21 04:45:08 +01:00
@camera : PF::Camera
2021-12-18 22:47:12 +01:00
@paused = false
@speed = 10.0
@controller : PF::Controller(PF::Keys)
@depth_buffer : PF::DepthBuffer
2021-12-18 22:47:12 +01:00
2021-12-21 04:45:08 +01:00
def initialize(*args, **kwargs)
super
2021-12-18 22:47:12 +01:00
@projector = PF::Projector.new(width, height)
@depth_buffer = PF::DepthBuffer.new(width, height)
2021-12-20 05:17:51 +01:00
@camera = @projector.camera
2021-12-21 04:45:08 +01:00
@model = PF::Mesh.load_obj("./assets/pixelfaucet.obj")
@model.position.z = @model.position.z + 2.0
2021-12-18 22:47:12 +01:00
@cube_model = PF::Mesh.load_obj("./assets/cube.obj")
@cube_model.position.z = @cube_model.position.z + 2.5
@sprite = PF::Sprite.new("./assets/bricks.png")
@controller = PF::Controller(PF::Keys).new({
PF::Keys::RIGHT => "Rotate Right",
PF::Keys::LEFT => "Rotate Left",
PF::Keys::UP => "Up",
PF::Keys::DOWN => "Down",
PF::Keys::A => "Left",
PF::Keys::D => "Right",
PF::Keys::W => "Forward",
PF::Keys::S => "Backward",
PF::Keys::SPACE => "Pause",
2021-12-18 22:47:12 +01:00
})
plug_in @controller
end
def update(dt)
2021-12-18 22:47:12 +01:00
@paused = !@paused if @controller.pressed?("Pause")
2021-12-20 05:17:51 +01:00
forward = @camera.forward_vector
strafe = @camera.strafe_vector
2021-12-18 22:47:12 +01:00
if @controller.held?("Right")
@camera.position = @camera.position + (strafe * @speed * dt)
2021-12-18 22:47:12 +01:00
end
if @controller.held?("Left")
@camera.position = @camera.position - (strafe * @speed * dt)
2021-12-18 22:47:12 +01:00
end
if @controller.held?("Up")
2021-12-20 05:17:51 +01:00
@camera.position.y = @camera.position.y + @speed * dt
2021-12-18 22:47:12 +01:00
end
if @controller.held?("Down")
2021-12-20 05:17:51 +01:00
@camera.position.y = @camera.position.y - @speed * dt
2021-12-18 22:47:12 +01:00
end
# Control the camera pitch instead of elevation -
# TODO: this needs to account for where the camera is pointing
# if @controller.held?("Up")
# @camera.pitch = @camera.pitch + (@speed / 5) * dt
# end
#
# if @controller.held?("Down")
# @camera.pitch = @camera.pitch - (@speed / 5) * dt
# end
if @controller.held?("Rotate Left")
@camera.yaw = @camera.yaw - (@speed / 3) * dt
2021-12-18 22:47:12 +01:00
end
if @controller.held?("Rotate Right")
@camera.yaw = @camera.yaw + (@speed / 3) * dt
2021-12-18 22:47:12 +01:00
end
if @controller.held?("Forward")
2021-12-20 05:17:51 +01:00
@camera.position = @camera.position + (forward * @speed * dt)
2021-12-18 22:47:12 +01:00
end
if @controller.held?("Backward")
2021-12-20 05:17:51 +01:00
@camera.position = @camera.position - (forward * @speed * dt)
2021-12-18 22:47:12 +01:00
end
@model.rotation.x = @model.rotation.x + 1.0 * dt
2021-12-18 22:47:12 +01:00
end
def draw
# clear(25, 50, 25)
clear
@depth_buffer.clear
cube_tris = @projector.project(@cube_model.tris)
cube_tris.each do |tri|
fill_triangle(
tri.p1.to_i, tri.p2.to_i, tri.p3.to_i, # Points
tri.t1, tri.t2, tri.t3, # Texture Points
@sprite,
@depth_buffer,
tri.color
)
end
tris = @projector.project(@model.tris)
tris.each do |tri|
# Rasterize all triangles
fill_triangle(
PF::Vector[tri.p1.x.to_i, tri.p1.y.to_i],
PF::Vector[tri.p2.x.to_i, tri.p2.y.to_i],
PF::Vector[tri.p3.x.to_i, tri.p3.y.to_i],
pixel: tri.color # buffer: @depth_buffer
)
end
string = String.build do |io|
io << "Triangles: " << tris.size + cube_tris.size
io << "\nPosition: "
io << "x: " << @camera.position.x.round(2)
io << "y: " << @camera.position.y.round(2)
io << "z: " << @camera.position.z.round(2)
io << "\nRotation: "
io << "x: " << @camera.rotation.x.round(2)
io << "y: " << @camera.rotation.y.round(2)
io << "z: " << @camera.rotation.z.round(2)
end
draw_string(string, 3, 3)
2021-12-18 22:47:12 +01:00
end
end
# engine = ThreeDee.new(256, 240, 4)
engine = ThreeDee.new(256 * 2, 240 * 2, 2)
2021-12-18 22:47:12 +01:00
engine.run!