budgie 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,59 @@
1
+ require 'opengl'
2
+
3
+ module Budgie; class DrawPalette
4
+ include GL
5
+
6
+ def initialize(palette, camera)
7
+ @palette = palette
8
+ @camera = camera
9
+ end
10
+
11
+ def fixed?
12
+ !!@fixed
13
+ end
14
+
15
+ def fix
16
+ @fixed = @camera.dup
17
+ @fixed.step = 10
18
+ @fixed.forward
19
+ end
20
+
21
+ def release
22
+ @fixed = nil
23
+ end
24
+
25
+ def draw
26
+ return unless @fixed
27
+
28
+ glMatrixMode GL_MODELVIEW
29
+ glPushMatrix
30
+
31
+ glTranslatef @fixed.x, @fixed.y, @fixed.z
32
+ glRotatef -@fixed.alpha, 0, 1, 0
33
+
34
+ draw!
35
+
36
+ glPopMatrix
37
+ end
38
+
39
+ private
40
+
41
+ def draw!
42
+ size = (Math.sqrt @palette.colors).floor
43
+ glTranslatef -size / 2, -size / 2, 0
44
+ glBegin GL_QUADS
45
+ size.times do |x|
46
+ size.times do |y|
47
+ index = 16 * x + y
48
+ @palette.rgb(index) do |r, g, b|
49
+ glColor3ub r, g, b
50
+ end
51
+ glVertex3f x, y, 0
52
+ glVertex3f x + 1, y, 0
53
+ glVertex3f x + 1, y + 1, 0
54
+ glVertex3f x, y + 1, 0
55
+ end
56
+ end
57
+ glEnd
58
+ end
59
+ end; end
@@ -0,0 +1,58 @@
1
+ require 'opengl'
2
+ require 'budgie/draw_cube'
3
+
4
+ module Budgie; class DrawPartial
5
+ include GL
6
+
7
+ def initialize(draw_map, x, y, z)
8
+ @draw_map = draw_map
9
+ @map = draw_map.map
10
+ @size = draw_map.partial_size
11
+ @x = x
12
+ @y = y
13
+ @z = z
14
+ @list = glGenLists 1
15
+ @cube = DrawCube.new
16
+ end
17
+
18
+ def draw
19
+ glCallList @list
20
+ end
21
+
22
+ def compile
23
+ dx = @x * @size
24
+ dy = @y * @size
25
+ dz = @z * @size
26
+
27
+ glNewList @list, GL_COMPILE
28
+ @size.times do |x|
29
+ @size.times do |y|
30
+ @size.times do |z|
31
+ cx = x + dx
32
+ cy = y + dy
33
+ cz = z + dz
34
+ index = @map[cx, cy, cz]
35
+ cube cx, cy, cz, index if index
36
+ end
37
+ end
38
+ end
39
+ glEndList
40
+ end
41
+
42
+ private
43
+
44
+ def cube(x, y, z, index)
45
+ @draw_map.cube_color x, y, z, index
46
+ glPushMatrix
47
+ glTranslatef x, y, z
48
+ @cube.draw do
49
+ @cube.front unless @map[x, y, z + 1]
50
+ @cube.back unless @map[x, y, z - 1]
51
+ @cube.right unless @map[x + 1, y, z]
52
+ @cube.left unless @map[x - 1, y, z]
53
+ @cube.top unless @map[x, y + 1, z]
54
+ @cube.bottom unless @map[x, y - 1, z]
55
+ end
56
+ glPopMatrix
57
+ end
58
+ end; end
@@ -0,0 +1,33 @@
1
+ require 'budgie/draw_cube'
2
+
3
+ module Budgie; class DrawPickerCube < DrawCube
4
+ def front
5
+ glColor3ub 2, 2, 3
6
+ super
7
+ end
8
+
9
+ def back
10
+ glColor3ub 2, 2, 1
11
+ super
12
+ end
13
+
14
+ def top
15
+ glColor3ub 2, 3, 2
16
+ super
17
+ end
18
+
19
+ def bottom
20
+ glColor3ub 2, 1, 2
21
+ super
22
+ end
23
+
24
+ def right
25
+ glColor3ub 3, 2, 2
26
+ super
27
+ end
28
+
29
+ def left
30
+ glColor3ub 1, 2, 2
31
+ super
32
+ end
33
+ end; end
@@ -0,0 +1,74 @@
1
+ require 'opengl'
2
+ require 'budgie/map'
3
+ require 'budgie/index'
4
+ require 'budgie/draw_partial'
5
+
6
+ # Splits map by 16x16x16 chunks and caches
7
+ # drawing commands for each of them
8
+ module Budgie; class DrawPickerMap
9
+ include GL
10
+
11
+ attr_reader :map, :partial_size
12
+
13
+ def initialize(map)
14
+ @map = map
15
+ @partial_size = 16
16
+ @partials = Map.new 1 + @map.max / @partial_size
17
+
18
+ compile
19
+ end
20
+
21
+ def update_partial(x, y, z)
22
+ x /= @partial_size
23
+ y /= @partial_size
24
+ z /= @partial_size
25
+ compile_partial x, y, z
26
+ # compile_partial x - 1, y, z
27
+ # compile_partial x + 1, y, z
28
+ # compile_partial x, y - 1, z
29
+ # compile_partial x, y + 1, z
30
+ # compile_partial x, y, z - 1
31
+ # compile_partial x, y, z + 1
32
+ end
33
+
34
+ def compile
35
+ @partials.each do |x, y, z|
36
+ compile_partial x, y, z
37
+ end
38
+ end
39
+
40
+ def draw
41
+ @partials.each do |x, y, z|
42
+ draw_partial x, y, z
43
+ end
44
+ end
45
+
46
+ def cube_color(x, y, z, index)
47
+ x = 1 + to_index(x)
48
+ y = 1 + to_index(y)
49
+ z = 1 + to_index(z)
50
+ glColor3ub x, y, z
51
+ end
52
+
53
+ private
54
+
55
+ include Index
56
+
57
+ def partial(x, y, z)
58
+ partial = @partials[x, y, z]
59
+ partial = @partials[x, y, z] = create_partial(x, y, z) unless partial
60
+ partial
61
+ end
62
+
63
+ def create_partial(x, y, z)
64
+ DrawPartial.new self, x, y, z
65
+ end
66
+
67
+ def compile_partial(x, y, z)
68
+ partial(x, y, z).compile
69
+ end
70
+
71
+ def draw_partial(x, y, z)
72
+ partial(x, y, z).draw
73
+ end
74
+ end; end
@@ -0,0 +1,25 @@
1
+ module Budgie; module Index
2
+ # Encodes negative values as positive ones
3
+ # 0 => 0
4
+ # 1 => 2
5
+ # 2 => 4
6
+ # -1 => 1
7
+ # -2 => 3
8
+ # etc
9
+ def to_index(value)
10
+ if value >= 0
11
+ 2 * value
12
+ else
13
+ -(1 + 2 * value)
14
+ end
15
+ end
16
+
17
+ # Reverses #to
18
+ def from_index(value)
19
+ if value % 2 == 0
20
+ value / 2
21
+ else
22
+ -(1 + value) / 2
23
+ end
24
+ end
25
+ end; end
data/lib/budgie/map.rb ADDED
@@ -0,0 +1,43 @@
1
+ require 'budgie/index'
2
+ require 'budgie/auto_array'
3
+
4
+ # Generic 3d array with negative indexes
5
+ # and auto-expand capability
6
+ module Budgie; class Map
7
+ attr_reader :max
8
+
9
+ def initialize(max = 0)
10
+ @max = max
11
+ @data = AutoArray.new { AutoArray.new { Array.new } }
12
+ end
13
+
14
+ def [](x, y, z)
15
+ @data[to_index x][to_index y][to_index z]
16
+ end
17
+
18
+ def []=(x, y, z, value)
19
+ self.max = x
20
+ self.max = y
21
+ self.max = z
22
+ @data[to_index x][to_index y][to_index z] = value
23
+ end
24
+
25
+ def each(&block)
26
+ (-@max).upto(@max) do |x|
27
+ (-@max).upto(@max) do |y|
28
+ (-@max).upto(@max) do |z|
29
+ yield x, y, z, self[x, y, z]
30
+ end
31
+ end
32
+ end
33
+ end
34
+
35
+ private
36
+
37
+ include Index
38
+
39
+ def max=(value)
40
+ value = value.abs
41
+ @max = value if value > @max
42
+ end
43
+ end; end
@@ -0,0 +1,37 @@
1
+ module Budgie; class Palette
2
+ attr_reader :colors
3
+
4
+ def initialize
5
+ @colors = 256
6
+ @red_colors = 8
7
+ @green_colors = 8
8
+ @blue_colors = 4
9
+ end
10
+
11
+ def white
12
+ @colors - 1
13
+ end
14
+
15
+ def rgb(index, &block)
16
+ index ||= 0
17
+ index %= @colors
18
+
19
+ r = index / @blue_colors / @green_colors
20
+ g = index / @blue_colors % @green_colors #/
21
+ b = index % @blue_colors
22
+
23
+ r = r * (@colors - 1) / (@red_colors - 1)
24
+ g = g * (@colors - 1) / (@green_colors - 1)
25
+ b = b * (@colors - 1) / (@blue_colors - 1)
26
+
27
+ yield r, g, b
28
+ end
29
+
30
+ def index(r, g, b)
31
+ r = r * @red_colors / @colors
32
+ g = g * @green_colors / @colors
33
+ b = b * @blue_colors / @colors
34
+
35
+ (r * @green_colors + g) * @blue_colors + b
36
+ end
37
+ end; end
@@ -0,0 +1,105 @@
1
+ require 'opengl'
2
+ require 'budgie/change_map'
3
+ require 'budgie/draw.rb'
4
+ require 'budgie/draw_map.rb'
5
+ require 'budgie/draw_palette'
6
+ require 'budgie/checker_texture'
7
+
8
+ module Budgie; class Scene
9
+ extend Forwardable
10
+ include GL
11
+
12
+ attr_reader :map, :palette, :camera, :selection, :draw_map, :draw_picker_map
13
+
14
+ def_delegators :@draw_palette, :fixed?, :fix, :release
15
+ def_delegators :@change_map, :place, :replace, :remove
16
+
17
+ def initialize(app)
18
+ @map = app.map
19
+ @camera = app.camera
20
+ @palette = app.palette
21
+ @selection = app.selection
22
+
23
+ @draw = Draw.new app
24
+ @draw_map = DrawMap.new @map, @palette
25
+ @draw_palette = DrawPalette.new @palette, @camera
26
+ @draw_picker_map = DrawPickerMap.new @map
27
+
28
+ @change_map = ChangeMap.new self
29
+ @checker_texture = CheckerTexture.new
30
+
31
+ glClearColor 0, 0, 0, 0
32
+ glClearDepth 1.0
33
+
34
+ glCullFace GL_FRONT
35
+ glDepthFunc GL_LEQUAL
36
+ glShadeModel GL_SMOOTH
37
+ glLightfv GL_LIGHT1, GL_AMBIENT, [0.25, 0.25, 0.25, 1.0]
38
+ glLightfv GL_LIGHT2, GL_DIFFUSE, [0.5, 0.5, 0.5, 1.0]
39
+ glLightfv GL_LIGHT3, GL_DIFFUSE, [0.25, 0.25, 0.25, 1.0]
40
+ end
41
+
42
+ def display
43
+ before_display
44
+
45
+ with GL_DEPTH_TEST, GL_CULL_FACE do
46
+ with GL_LIGHTING, GL_TEXTURE_2D, GL_COLOR_MATERIAL, GL_LIGHT1, GL_LIGHT2, GL_LIGHT3 do
47
+ @checker_texture.bind
48
+ @draw_map.draw
49
+ @checker_texture.unbind
50
+ end
51
+
52
+ with GL_POLYGON_OFFSET_FILL do
53
+ @draw.selection @selection
54
+ end
55
+ end
56
+
57
+ @draw_palette.draw
58
+ @draw.ortho { @draw.crosshair_with_outline }
59
+ end
60
+
61
+ def picker
62
+ before_display
63
+ with GL_DEPTH_TEST, GL_CULL_FACE do
64
+ @draw_picker_map.draw
65
+ end
66
+ end
67
+
68
+ def color_picker
69
+ before_display
70
+ with GL_DEPTH_TEST, GL_CULL_FACE do
71
+ @draw_map.draw
72
+ end
73
+ @draw_palette.draw
74
+ end
75
+
76
+ def normal_picker
77
+ before_display
78
+ with GL_DEPTH_TEST, GL_CULL_FACE do
79
+ @draw.picker_cube_at @selection.x, @selection.y, @selection.z
80
+ end
81
+ end
82
+
83
+ private
84
+
85
+ def before_display
86
+ glClear GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT
87
+
88
+ glMatrixMode GL_MODELVIEW
89
+ glLoadIdentity
90
+ glScalef 1, 1, -1
91
+
92
+ glRotatef @camera.beta, 1, 0, 0
93
+ glRotatef @camera.alpha, 0, 1, 0
94
+ glTranslatef -@camera.x, -@camera.y, -@camera.z
95
+
96
+ glLightfv GL_LIGHT2, GL_POSITION, [@camera.x, @map.max * @map.max, @camera.z, 1.0]
97
+ glLightfv GL_LIGHT3, GL_POSITION, [@camera.x, @camera.y, @camera.z, 1.0]
98
+ end
99
+
100
+ def with(*states, &block)
101
+ states.each { |state| glEnable state }
102
+ yield
103
+ states.each { |state| glDisable state }
104
+ end
105
+ end; end
@@ -0,0 +1,45 @@
1
+ require 'budgie/index'
2
+
3
+ module Budgie; class Selection
4
+ attr_accessor :x, :y, :z, :normal_x, :normal_y, :normal_z, :selected, :r, :g, :b
5
+
6
+ def initialize
7
+ @x = @y = @z = @normal_x = @normal_y = @normal_z = @r = @g = @b = 0
8
+ @selected = false
9
+ end
10
+
11
+ def new_x
12
+ @x + @normal_x
13
+ end
14
+
15
+ def new_y
16
+ @y + @normal_y
17
+ end
18
+
19
+ def new_z
20
+ @z + @normal_z
21
+ end
22
+
23
+ # Nothing is selected when color is [0, 0, 0]
24
+ # Everything else maps to [x, y, z] indexes of the map
25
+ def from_color(r, g, b)
26
+ @selected = r * g * b != 0
27
+ if @selected
28
+ @x = from_index(r - 1)
29
+ @y = from_index(g - 1)
30
+ @z = from_index(b - 1)
31
+ end
32
+ end
33
+
34
+ # Cube normals can be [-1|0|1, -1|0|1, -1|0|1]
35
+ # Normals are encoded like [1|2|3, 1|2|3, 1|2|3]
36
+ def normal_from_color(r, g, b)
37
+ @normal_x = r - 2
38
+ @normal_y = g - 2
39
+ @normal_z = b - 2
40
+ end
41
+
42
+ private
43
+
44
+ include Index
45
+ end; end
@@ -0,0 +1,17 @@
1
+ module Budgie; class Settings
2
+ attr_reader :keymap, :free_mouse_mode_key, :palette_key
3
+
4
+ def initialize
5
+ @keymap = {
6
+ "\e" => 'escape',
7
+ 'w' => 'forward',
8
+ 's' => 'backward',
9
+ 'a' => 'left',
10
+ 'd' => 'right',
11
+ ' ' => 'up',
12
+ 'c' => 'down'
13
+ }
14
+ @free_mouse_mode_key = 'f'
15
+ @palette_key = 'e'
16
+ end
17
+ end; end
@@ -0,0 +1,90 @@
1
+ require 'oily_png'
2
+ require 'budgie/map'
3
+
4
+ module Budgie; class StoreMap
5
+ def initialize(filename, palette)
6
+ @filename = filename
7
+ @palette = palette
8
+ end
9
+
10
+ def create
11
+ map = Map.new
12
+ map[0, 0, 0] = @palette.white
13
+ map
14
+ end
15
+
16
+ def load
17
+ return create unless file_exists?
18
+
19
+ png = load_png
20
+ size = png.width
21
+ max = size / 2
22
+
23
+ map = Map.new
24
+
25
+ size.times do |x|
26
+ size.times do |y|
27
+ size.times do |z|
28
+ png_x = x
29
+ png_y = size * (z + 1) - (y + 1)
30
+ color = png[png_x, png_y] rescue nil
31
+ color = color_to_index color
32
+ map[x - max, y - max, z - max] = color if color
33
+ end
34
+ end
35
+ end
36
+
37
+ return map
38
+ end
39
+
40
+ def save(map)
41
+ max = map.max
42
+ size = 2 * max + 1 # [-max, max] including boundaries
43
+
44
+ width = size
45
+ height = size * size
46
+ png = new_png width, height
47
+
48
+ map.each do |x, y, z, index|
49
+ x += max
50
+ y += max
51
+ z += max
52
+ png_x = x
53
+ png_y = width * (z + 1) - (y + 1)
54
+ png[png_x, png_y] = index_to_color index
55
+ end
56
+
57
+ png.save @filename
58
+ end
59
+
60
+ private
61
+
62
+ def file_exists?
63
+ File.exists? @filename
64
+ end
65
+
66
+ def new_png(width, height)
67
+ ChunkyPNG::Image.new(width, height, ChunkyPNG::Color::TRANSPARENT)
68
+ end
69
+
70
+ def load_png
71
+ ChunkyPNG::Image.from_file(@filename)
72
+ end
73
+
74
+ def index_to_color(index)
75
+ return ChunkyPNG::Color::TRANSPARENT unless index
76
+ @palette.rgb(index) do |r, g, b|
77
+ return ChunkyPNG::Color.rgba r, g, b, 0xff
78
+ end
79
+ end
80
+
81
+ def color_to_index(color)
82
+ return nil unless color
83
+ r = ChunkyPNG::Color.r color
84
+ g = ChunkyPNG::Color.g color
85
+ b = ChunkyPNG::Color.b color
86
+ a = ChunkyPNG::Color.a color
87
+ return nil unless a > 0
88
+ return @palette.index r, g, b
89
+ end
90
+ end; end
metadata ADDED
@@ -0,0 +1,120 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: budgie
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - 4r2r
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-04-26 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: opengl
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: glu
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: glut
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: oily_png
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - '>='
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ description: ''
70
+ email: arthrrr@gmail.com
71
+ executables:
72
+ - budgie
73
+ extensions: []
74
+ extra_rdoc_files: []
75
+ files:
76
+ - bin/budgie
77
+ - lib/budgie/draw_map.rb
78
+ - lib/budgie/draw_picker_cube.rb
79
+ - lib/budgie/camera.rb
80
+ - lib/budgie/index.rb
81
+ - lib/budgie/application.rb
82
+ - lib/budgie/auto_array.rb
83
+ - lib/budgie/palette.rb
84
+ - lib/budgie/draw_palette.rb
85
+ - lib/budgie/checker_texture.rb
86
+ - lib/budgie/settings.rb
87
+ - lib/budgie/draw_partial.rb
88
+ - lib/budgie/scene.rb
89
+ - lib/budgie/map.rb
90
+ - lib/budgie/draw_cube.rb
91
+ - lib/budgie/draw.rb
92
+ - lib/budgie/selection.rb
93
+ - lib/budgie/change_map.rb
94
+ - lib/budgie/draw_picker_map.rb
95
+ - lib/budgie/store_map.rb
96
+ homepage: https://github.com/4r2r/budgie
97
+ licenses:
98
+ - MIT
99
+ metadata: {}
100
+ post_install_message:
101
+ rdoc_options: []
102
+ require_paths:
103
+ - lib
104
+ required_ruby_version: !ruby/object:Gem::Requirement
105
+ requirements:
106
+ - - '>='
107
+ - !ruby/object:Gem::Version
108
+ version: '0'
109
+ required_rubygems_version: !ruby/object:Gem::Requirement
110
+ requirements:
111
+ - - '>='
112
+ - !ruby/object:Gem::Version
113
+ version: '0'
114
+ requirements: []
115
+ rubyforge_project:
116
+ rubygems_version: 2.0.3
117
+ signing_key:
118
+ specification_version: 4
119
+ summary: Voxel editor similar to creative mode from minecraft
120
+ test_files: []