OpenGL でごく単純なフライトシミュレータ
OpenGL の Ruby ミニライブラリ - Marginalia
require './miniopengl' L = 0.5 vertex = [[-L, -L, -L], [L, -L, -L], [L, L, -L], [-L, L, -L], [L, -L, L], [-L, -L, L], [-L, L, L], [L, L, L]] edge = [[0, 1], [1, 2], [2, 3], [3, 0], [4, 5], [5, 6], [6, 7], [7, 4], [0, 5], [1, 4], [2, 7], [3, 6]] Mesh = 20 v = View.new v.r = Vector[0, 10, 1] v.toward = Vector[0, -1, 0] v.up = Vector[0, 0, -1] MiniOpenGL.app width: 400, height: 400, buffering: :on do clear_color(0, 0, 0.3) draw do clear color(0.6, 0, 0) (-Mesh..Mesh).each do |i| line3(i, 0, Mesh, i, 0, -Mesh) line3(Mesh, 0, i, -Mesh, 0, i) end color(0, 1, 0) draw_elements(GL_LINES, 3, vertex.flatten, edge.flatten) swap_buffers end reshape do |w, h| clear viewport(0, 0, w, h) init_projection perspective(30, w / h.to_f, 0.1, 50) end repeat(100) do init_modelview look_at(v.r[0], v.r[1], v.r[2], v.target[0], v.target[1], v.target[2], v.up[0], v.up[1], v.up[2]) redisplay v.next end key_in do |key| th = 0.9 * PI / 180 case key when "u" #上 v.headup(th) when "d" #下 v.headup(-th) when "l" #左 v.turn(th) when "r" #右 v.turn(-th) when "z" #左回転 v.screw(th) when "x" #右回転 v.screw(-th) when " " #原点方向を向く r = v.r v.toward = -r / r.norm l = v.toward.cross(Vector[0, 1, 0]) v.laxs = l / l.norm v.up = v.laxs.cross(v.toward) when "\r" #決まった位置から再スタート v.r = Vector[0, 0.3, 10] v.toward = Vector[0, 0, -1] v.up = Vector[0, 1, 0] end end end
class View
class View def initialize @r = Vector[0, 0, 10.0] @up = Vector[0, 1.0, 0] @toward = Vector[0, 0, -1.0] @step = 0.1 cal_target last_axis end attr_accessor :r, :up, :toward, :target, :to, :step, :lax def cal_target @target = @r + @toward end private :cal_target def next(step = nil) @step = step if step @step @r = @r + @toward * @step cal_target end def last_axis @laxs = @toward.cross(@up) end private :last_axis def screw(th) @up, @laxs = @up * cos(th) + @laxs * sin(th), -@up * sin(th) + @laxs * cos(th) end def headup(th) @toward, @up = @toward * cos(th) + @up * sin(th), -@toward * sin(th) + @up * cos(th) cal_target last_axis end def turn(th) @laxs, @toward = @laxs * cos(th) + @toward * sin(th), -@laxs * sin(th) + @toward * cos(th) end end