rage 0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,91 @@
1
+ # Input handler constructs and methods
2
+ #
3
+ # Copyright (C) 2010 Mohammed Morsi <movitto@yahoo.com>
4
+ # Licensed under the GPLv3+ http://www.gnu.org/licenses/gpl.txt
5
+
6
+ module RAGE
7
+
8
+ # FIXME turn into callback interface
9
+
10
+ # Handles and redirects user events to registered callbacks.
11
+ class InputHandler
12
+
13
+ # Invoked during main game execution cycle to handle any SDL input events
14
+ def self.handle(event)
15
+
16
+ @@left_button_pressed = false unless defined? @@left_button_pressed
17
+ @@right_button_pressed = false unless defined? @@right_button_pressed
18
+
19
+ case event
20
+ when SDL::Event2::Quit
21
+ exit
22
+
23
+ when SDL::Event2::KeyDown
24
+ case event.sym
25
+ when SDL::Key::Q, SDL::Key::ESCAPE
26
+ exit
27
+ when SDL::Key::W
28
+ Game.wireframe_mode= !Game.wireframe_mode
29
+ end
30
+
31
+ when SDL::Event::MouseMotion
32
+ # get state of mouse buttons
33
+ left_pressed = ((event.state & SDL::Mouse::BUTTON_LMASK) != 0)
34
+ right_pressed = ((event.state & SDL::Mouse::BUTTON_RMASK) != 0)
35
+
36
+ # if left button is down, rotate camera
37
+ if left_pressed
38
+ xpos, ypos, zpos = to_3d_coordinates(event.x, event.y)
39
+ oxpos, oypos, ozpos = to_3d_coordinates(event.x-event.xrel, event.y-event.yrel)
40
+
41
+ if xpos > oxpos
42
+ Game.current_viewport.camera.xrotate += 1
43
+ elsif xpos < oxpos
44
+ Game.current_viewport.camera.xrotate -= 1
45
+ end
46
+
47
+ if ypos > oypos
48
+ Game.current_viewport.camera.yrotate += 1
49
+ elsif ypos < oypos
50
+ Game.current_viewport.camera.yrotate -= 1
51
+ end
52
+
53
+ if zpos > ozpos
54
+ Game.current_viewport.camera.zrotate += 1
55
+ elsif zpos < ozpos
56
+ Game.current_viewport.camera.zrotate -= 1
57
+ end
58
+
59
+ # if right is down pan camera
60
+ elsif right_pressed
61
+ if event.xrel > 0
62
+ Game.current_viewport.camera.pos[0] -= 1
63
+ elsif event.xrel < 0
64
+ Game.current_viewport.camera.pos[0] += 1
65
+ end
66
+
67
+ if event.yrel > 0
68
+ Game.current_viewport.camera.pos[1] += 1
69
+ elsif event.yrel < 0
70
+ Game.current_viewport.camera.pos[1] -= 1
71
+ end
72
+
73
+ end
74
+
75
+ when SDL::Event::MouseButtonDown
76
+ # zoom out the camera
77
+ if event.button == 5 # wheeldown
78
+ Game.current_viewport.camera.pos[2] += 1
79
+ end
80
+
81
+ when SDL::Event::MouseButtonUp
82
+ # zoom in the camera
83
+ if event.button == 4 # wheel up
84
+ Game.current_viewport.camera.pos[2] -= 1
85
+ end
86
+
87
+ end
88
+ end
89
+ end
90
+
91
+ end
@@ -0,0 +1,33 @@
1
+ # RAGE resource loader
2
+ #
3
+ # Copyright (C) 2010 Mohammed Morsi <movitto@yahoo.com>
4
+ # Licensed under the GPLv3+ http://www.gnu.org/licenses/gpl.txt
5
+
6
+ require 'uri' # use uri to parse sources
7
+ require 'net/http' # get http:// based resources
8
+
9
+ module RAGE
10
+
11
+ # Loads resources from uris
12
+ class Loader
13
+
14
+ # Loads and return text resource from specified source uri
15
+ def self.load(source_uri)
16
+ Logger.info "loading resource from uri #{source_uri}"
17
+ data = nil
18
+ uri = URI.parse(source_uri)
19
+ if uri.scheme == "file"
20
+ data = File.read_all uri.path
21
+ elsif uri.scheme == "http"
22
+ data = Net::HTTP.get_response(uri.host, uri.path).body
23
+ # elsif FIXME support other uri types
24
+ end
25
+
26
+ return data
27
+
28
+ rescue URI::InvalidURIError
29
+ raise Exceptions::InvalidResourceUri
30
+ end
31
+
32
+ end # class loader
33
+ end # module RXSD
@@ -0,0 +1,141 @@
1
+ # Location related constructs
2
+ #
3
+ # Copyright (C) 2010 Mohammed Morsi <movitto@yahoo.com>
4
+ # Licensed under the GPLv3+ http://www.gnu.org/licenses/gpl.txt
5
+
6
+ module RAGE
7
+
8
+ # Location w/ coordinates in the 3D system.
9
+ # Various entities may be associated with Location to be drawn.
10
+ class Location
11
+ # x, y, z coordinates of the location,
12
+ attr_reader :x, :y, :z
13
+
14
+ # Mesh which to draw at location
15
+ attr_reader :mesh
16
+
17
+ # TODO lights, other entities to draw at locations
18
+
19
+ # Initialize Location with argument hash, which may include
20
+ # * :x location coordinate
21
+ # * :y location coordinate
22
+ # * :z location coordinate
23
+ # * :mesh resource to draw at location
24
+ def initialize(args = {})
25
+ @x = args.has_key?(:x) ? args[:x] : 0
26
+ @y = args.has_key?(:y) ? args[:y] : 0
27
+ @z = args.has_key?(:z) ? args[:z] : 0
28
+ @mesh = args[:mesh]
29
+ end
30
+
31
+ # Update location w/ args, which may include
32
+ # * :x location coordinate
33
+ # * :y location coordinate
34
+ # * :z location coordinate
35
+ def update(args = {})
36
+ @x = args[:x] if args.has_key?(:x)
37
+ @y = args[:y] if args.has_key?(:y)
38
+ @z = args[:z] if args.has_key?(:z)
39
+ end
40
+
41
+ # Return location boundaries. This is generated by determining maxima/minima
42
+ # local coordinates of entity associated w/ location and adding those to
43
+ # the location's coordinates. Return value is an array of six values as follows
44
+ # max_x, max_y, max_z, min_x, min_y, min_z
45
+ def boundaries
46
+ max_x = max_y = max_z = min_x = min_y = min_z = 0
47
+ unless mesh.nil?
48
+ max_x, max_y, max_z, min_x, min_y, min_z = mesh.boundaries
49
+ end
50
+ return x + max_x, y + max_y, z + max_z, x + min_x, y + min_y, z + min_z
51
+ end
52
+
53
+
54
+ # Invoked during draw cycle to draw location & entity associated w/ it
55
+ def draw
56
+ Gl.glPushMatrix();
57
+
58
+ # translate coordinate system to location's coordinates
59
+ Gl.glTranslatef(x, y, z)
60
+
61
+ # draw mesh
62
+ mesh.draw
63
+
64
+ Gl.glPopMatrix();
65
+ end
66
+ end
67
+
68
+ # Singleton class managing all locations
69
+ class LocationsManager
70
+ include Singleton
71
+
72
+ # Array of locations being managed
73
+ attr_accessor :locations
74
+
75
+ def initialize
76
+ @locations = []
77
+ end
78
+
79
+ # Add location to be managed
80
+ def add(location)
81
+ @locations.push location unless @locations.include? location
82
+ end
83
+
84
+ # Empty the array of managed locations
85
+ def clear
86
+ @locations.clear
87
+ end
88
+
89
+ # Return the maxima and minima of the x,y,z coordinate values for all the
90
+ # locations being managed. Return value is an array of six values as follows
91
+ # max_x, max_y, max_z, min_x, min_y, min_z
92
+ # This method essentially gives you the "box" in which all locations being managed are in
93
+ def boundaries
94
+ max_x = max_y = max_z = min_x = min_y = min_z = 0
95
+ @locations.each { |loc|
96
+ locb = loc.boundaries
97
+ max_x = locb[0] if locb[0] > max_x
98
+ max_y = locb[1] if locb[1] > max_y
99
+ max_z = locb[2] if locb[2] > max_z
100
+ min_x = locb[3] if locb[3] < min_x
101
+ min_y = locb[4] if locb[4] < min_y
102
+ min_z = locb[5] if locb[5] < min_z
103
+ }
104
+ return max_x, max_y, max_z, min_x, min_y, min_z
105
+ end
106
+
107
+ # Return the center coordinate of location system.
108
+ # Must specify the metric which to generate center, which may be either
109
+ # * :avg - compute and return bounaries averages
110
+ # * :mean - compute and return mean of all coords
111
+ def center(metric = :mean)
112
+ if metric == :mean
113
+ ls = @locations.size
114
+ mx = my = mz = 0
115
+ @locations.each { |lm|
116
+ mx += lm.x / ls
117
+ my += lm.y / ls
118
+ mz += lm.z / ls
119
+ }
120
+ return mx,my,mz
121
+
122
+ elsif metric == :avg
123
+ b = self.boundaries
124
+ return (b[0] + b[3]) / 2, (b[1] + b[4]) / 2, (b[2] + b[5]) / 2
125
+
126
+ end
127
+ end
128
+
129
+ end
130
+
131
+ # Helper method to get 3d coords cooresponding to 2d ones via OPENGL unprojection
132
+ def to_3d_coordinates(x2, y2)
133
+ model_view = Gl.glGetDoublev Gl::GL_MODELVIEW_MATRIX
134
+ projection = Gl.glGetDoublev Gl::GL_PROJECTION_MATRIX
135
+ viewport = Gl.glGetIntegerv Gl::GL_VIEWPORT
136
+ depth = Gl.glReadPixels x2, y2, 1, 1, Gl::GL_DEPTH_COMPONENT, Gl::GL_FLOAT
137
+ x3, y3, z3 = Glu.gluUnProject x2, y2, depth[0], model_view, projection, viewport
138
+ return [x3, y3, z3]
139
+ end
140
+
141
+ end
@@ -0,0 +1,147 @@
1
+ # Mesh Resource
2
+ #
3
+ # Currently manages X3D meshes
4
+ #
5
+ # Copyright (C) 2010 Mohammed Morsi <movitto@yahoo.com>
6
+ # Licensed under the GPLv3+ http://www.gnu.org/licenses/gpl.txt
7
+
8
+ # use rxsd to load x3d xsd schema, declare xsd classes, instantiate scenes
9
+ require 'rxsd'
10
+
11
+ module RAGE
12
+
13
+ # 3D mesh to be displayed on the screen.
14
+ # Contains geometry and visual properties.
15
+ # Currently implements certain parts of the X3D graphics schema.
16
+ # http://en.wikipedia.org/wiki/X3D
17
+ class Mesh
18
+ # Optional transformation params, set these to
19
+ # transformations to be factored in if needed
20
+ attr_accessor :op_translation, :op_scale, :op_rotation
21
+
22
+ # X3D schema for shared access
23
+ class_attr :x3d_schema
24
+
25
+ # X3D schema classes for shared access
26
+ class_attr :x3d_schema_classes
27
+
28
+
29
+ # Create new mesh from raw X3D mesh
30
+ def initialize(data)
31
+ # set default attributes
32
+ @op_translation = [0,0,0]
33
+ @op_scale = [1,1,1]
34
+
35
+ # load the x3d xsd schema and classes if not already done so
36
+ unless defined? @@x3d_schema
37
+ @@x3d_schema = RXSD::Parser.parse_xsd :uri => 'http://www.web3d.org/specifications/x3d-3.0.xsd' # TODO allow location which this is pulled from to be configured
38
+ @@x3d_schema_classes = @@x3d_schema.to :ruby_classes
39
+ end
40
+
41
+ # load the scene from the x3d schema instance
42
+ objs = RXSD::Parser.parse_xml(:raw => data).to(:ruby_objects, :schema => @@x3d_schema)
43
+ @scene = objs[0].scene
44
+
45
+ # FIXME get all transformations (and groups of) under scene
46
+ @tf = @scene.collision.transform
47
+ @translation = @tf.translation.to_a :type => XSDFloat
48
+ @scale = @tf.scale.to_a :type => XSDFloat
49
+ #diffuse = tf.shape.appearance.material.diffuse_color.split.collect { |c| c.to_f }
50
+ #specular = tf.shape.appearance.material.specular_color.split.collect { |c| c.to_f }
51
+ #emissive = tf.shape.appearance.material.emissive_color.split.collect { |c| c.to_f }
52
+ @coord_index = @tf.shape.indexed_face_set.coord_index.
53
+ to_a(:type => String, :delim => ",").
54
+ collect { |coords| a = coords.to_a(:type => XSDInteger); a[0...a.size-1]}.flatten # cut off the last -1
55
+ @coord_point = @tf.shape.indexed_face_set.coordinate.point.
56
+ to_a(:type => String, :delim => ",").
57
+ collect { |coords| coords.to_a :type => XSDFloat }.flatten
58
+ end
59
+
60
+ # Create location w/ specified args, associated mesh w/ it and add it to the LocationsManager
61
+ def show_at(args = {})
62
+ # XXX not a huge fan of storing location interally,
63
+ # but this is best way to do this for now
64
+ if ! defined? @location
65
+ args[:mesh] = self
66
+ @location = Location.new(args)
67
+ LocationsManager.instance.add @location
68
+ else
69
+ @location.update args
70
+ end
71
+ return @location
72
+ end
73
+
74
+
75
+ # Return center point of mesh from mesh translation provided in mesh
76
+ # and op_translation
77
+ def center
78
+ return @op_translation[0] + @translation[0],
79
+ @op_translation[1] + @translation[1],
80
+ @op_translation[2] + @translation[2]
81
+ end
82
+
83
+ # Return factor which mesh should scale to
84
+ def scale
85
+ return @scale[0] * @op_scale[0],
86
+ @scale[1] * @op_scale[1],
87
+ @scale[2] * @op_scale[2]
88
+ end
89
+
90
+ # Return mesh boundaries. This is generated by determining the maxima/minima
91
+ # coordinate points. Return value is an array of six values as follows
92
+ # max_x, max_y, max_z, min_x, min_y, min_z
93
+ def boundaries
94
+ centerx, centery, centerz = *center
95
+ max_x = max_y = max_z = min_x = min_y = min_z = 0
96
+ @coord_point.each_index { |cpi|
97
+ if cpi % 3 == 0
98
+ adjx = centerx + @coord_point[cpi]
99
+ if adjx > max_x
100
+ max_x = adjx
101
+ elsif adjx < min_x
102
+ min_x = adjx
103
+ end
104
+ elsif cpi % 3 == 1
105
+ adjy = centery + @coord_point[cpi]
106
+ if adjy > max_y
107
+ max_y = adjy
108
+ elsif adjy < min_y
109
+ min_y = adjy
110
+ end
111
+ else
112
+ adjz = centerz + @coord_point[cpi]
113
+ if adjz > max_z
114
+ max_z = adjz
115
+ elsif adjz < min_z
116
+ min_z = adjz
117
+ end
118
+ end
119
+ }
120
+ return max_x, max_y, max_z, min_x, min_y, min_z
121
+ end
122
+
123
+
124
+ # Invoked during draw cycle to draw mesh
125
+ def draw
126
+ # FIXME mesh material
127
+ #Gl.glMaterial(Gl::GL_FRONT, Gl::GL_DIFFUSE, diffuse)
128
+ #Gl.glMaterial(Gl::GL_FRONT, Gl::GL_SPECULAR, specular)
129
+ #Gl.glMaterial(Gl::GL_FRONT, Gl::GL_EMISSIVE, emissive)
130
+
131
+ # translate coordinate system to center position of mesh
132
+ Gl.glTranslatef(*center)
133
+
134
+ # scale as specified
135
+ Gl.glScalef(*scale)
136
+
137
+ # FIXME rotate according to mesh and optional params
138
+
139
+ # draw mesh
140
+ Gl.glEnableClientState(Gl::GL_VERTEX_ARRAY);
141
+ Gl.glVertexPointer(3, Gl::GL_FLOAT, 0, @coord_point);
142
+ Gl.glDrawElements(Gl::GL_QUADS, @coord_index.size, Gl::GL_UNSIGNED_INT, @coord_index);
143
+ Gl.glDisableClientState(Gl::GL_VERTEX_ARRAY);
144
+ end
145
+ end
146
+
147
+ end
@@ -0,0 +1,49 @@
1
+ # Resources constructs and methods
2
+ #
3
+ # Copyright (C) 2010 Mohammed Morsi <movitto@yahoo.com>
4
+ # Licensed under the GPLv3+ http://www.gnu.org/licenses/gpl.txt
5
+
6
+ require 'singleton'
7
+
8
+ module RAGE
9
+
10
+ # Singleton class managing all RAGE resources.
11
+ # Resources should be loaded here instead as opposed to creating them manually
12
+ # so as to mantain a central management repository during game execution.
13
+ class ResourcesManager
14
+ include Singleton
15
+
16
+ # Hash of ids -> resources we are managing
17
+ attr_accessor :resources
18
+
19
+ def initialize
20
+ @resources = {}
21
+ end
22
+
23
+ # Load resource from specified args and add to manager. Args may include
24
+ # * :type type of resource to load
25
+ # * :id unique identifier to give resource
26
+ # * :uri uri of resource if appropriate
27
+ # * :color resource color if appropriate
28
+ def load_resource(args = {})
29
+ type = args[:type]
30
+ id = args[:id]
31
+
32
+ resource = nil
33
+
34
+ if type == :mesh
35
+ uri = args[:uri]
36
+ data = Loader.load uri
37
+ resource = Mesh.new(data)
38
+ elsif type == :color
39
+ color = args[:color]
40
+ resource = Color.new(:rgb => color)
41
+ # elsif other resource types
42
+ end
43
+
44
+ @resources[id] = resource
45
+ return resource
46
+ end
47
+ end
48
+
49
+ end