shattered_pack 0.3.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,113 @@
1
+ module ShatteredView
2
+ class Node
3
+ attr_reader :position
4
+ attr_accessor :scene_node
5
+
6
+ #Returns the SceneManager::RootNode wrapped in ShatteredView::Node
7
+ def Node.root
8
+ @@root ||= Node.new
9
+ @@root.scene_node = ShatteredOgre::Scene.getSingleton.getRootSceneNode
10
+ return @@root
11
+ end
12
+
13
+ #Everything attached to this object
14
+ def children
15
+ @children ||= []
16
+ end
17
+
18
+ def initialize(parent = nil)
19
+ @position = v(0,0,0)
20
+ # Create an empty unassociated node.
21
+ @scene_node = ShatteredOgre::Scene.getSingleton.createSceneNode
22
+ attach_to(parent)
23
+ end
24
+
25
+ # Use attach_to instead
26
+ def attach_child(child)
27
+ children << child
28
+ child.scene_node.attachTo(scene_node)
29
+ end
30
+
31
+ # Use attach_to on the child node (with nil if you want to clear the parent)
32
+ def remove_child(child)
33
+ @children.delete child
34
+ end
35
+
36
+ #Set a new parent node for the object
37
+ def attach_to(new_parent)
38
+ @parent.remove_child(self) unless @parent.nil?
39
+ @parent = new_parent
40
+ new_parent.attach_child(self) unless new_parent.nil?
41
+ end
42
+
43
+ # Move the node a certain amount
44
+ def translate(v)
45
+ @position += v
46
+ synchronize
47
+ end
48
+
49
+ def position=(v)
50
+ @position = v.to_v
51
+ synchronize
52
+ end
53
+
54
+ # uses #look_at
55
+ def looking_at=( *look_toward )
56
+ look_toward = look_toward[0] if(look_toward.length == 1)
57
+ look_at(look_toward)
58
+ end
59
+
60
+ alias_method :look_at=, :looking_at=
61
+
62
+ # look_at a Vector, Mesh, or Actor.
63
+ def look_at( position )
64
+ position = position.position unless position.is_a?(ShatteredOgre::Vector3) || position.is_a?(Vector) || position.is_a?(Array)
65
+ position = position.to_v3 unless position.is_a?(ShatteredOgre::Vector3)
66
+ scene_node.lookAt(position)
67
+ # raise ArgumentError, "#{position.inspect} is not a Mesh, Actor, or Vector."
68
+ end
69
+
70
+ # rotate along axis, degrees amount
71
+ def rotate( axis, degrees )
72
+ axis = axis.to_v.normalize
73
+ scene_node.rotate(axis.to_v3, degrees)
74
+ end
75
+
76
+ def rotation=(axis, degrees)
77
+ rotate axis, degrees
78
+ end
79
+
80
+ def scale=(*scale)
81
+ scale = scale[0] if scale.length == 1
82
+ scale = [scale, scale, scale].to_v if scale.kind_of?(Numeric)
83
+ scale = scale.to_v
84
+
85
+ scene_node.scale scale.to_v3
86
+ end
87
+
88
+ def scale(amount)
89
+ amount = amount.to_v3 unless amount.is_a? Fixnum
90
+ scene_node.scale amount
91
+ end
92
+
93
+ def material=( material )
94
+ if material.is_a? RMaterial
95
+ scene_node.generateTangents if material.tangent_space
96
+ material = material.name
97
+ end
98
+ scene_node.setMaterial(material.to_s)
99
+ end
100
+
101
+ def visible=(visible)
102
+ scene_node.setVisible(visible)
103
+ end
104
+
105
+ # Synchronize the position with C++, this is called every frame. However
106
+ # there are times where scene_node hasn't been initialized quite yet
107
+ # (such as right when a new actor is in the process of being created), so
108
+ # only synchronize if there's something to synchronize
109
+ def synchronize
110
+ @scene_node.setPosition(position.to_v3) unless @scene_node.nil?
111
+ end
112
+ end
113
+ end
@@ -0,0 +1,47 @@
1
+ require 'singleton'
2
+
3
+ module ShatteredView
4
+ # Resource Handler is the ruby binding around Ogre's resource handler
5
+ # It provides all types of shortcuts for finding files and adding new paths.
6
+ class Resources
7
+ include Singleton
8
+
9
+ # Instance Methods
10
+ attr_reader :resource_paths
11
+ def initialize
12
+ @resource_paths=[]
13
+ end
14
+
15
+ def add_resource_paths(*paths)
16
+ paths.each do |path|
17
+ path = SHATTERED_ROOT + "/"+path
18
+ @resource_paths << path
19
+ each_directory_in_path(path) do |sub_path|
20
+ ShatteredOgre::ResourceHandler.getSingleton.addResourcePath(sub_path) unless defined? TESTING
21
+ end
22
+ end
23
+ end
24
+
25
+ def destroy_paths
26
+ @resource_paths = []
27
+ end
28
+
29
+ # This is useful for any extension wanting to load resource files:
30
+ #
31
+ # Usage:
32
+ # Resources.instance.find_files_by_extensions("ogg","mp3","wav")
33
+ def find_files_by_extensions(*extensions)
34
+ File.find_by_extensions(@resource_paths,*extensions)
35
+ end
36
+
37
+ # This is deprecated in favor of File.each_in_path
38
+ def each_file_in_path(path, &block)
39
+ File.each_in_path(path, &block)
40
+ end
41
+
42
+ # This is deprecated in favor of Dir.each_in_path
43
+ def each_directory_in_path(path,&block)
44
+ Dir.each_in_path(path, &block)
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,43 @@
1
+ require 'erb'
2
+
3
+ module ShatteredView
4
+ class RMaterial
5
+ attr_reader :result, :name
6
+ def load!(file)
7
+ begin
8
+ evaluate!(File.open(file).readlines.join(''))
9
+ rescue Errno::ENOENT => bang
10
+ raise Errno::ENOENT, "RMaterial for #{name} not found: #{bang.message}"
11
+ end
12
+ end
13
+ def create_ogre_material!
14
+ ShatteredOgre::ResourceHandler.getSingleton.addCustomMaterial(name.to_s, result)
15
+ end
16
+ def create_ogre_material=(*args)
17
+ load!("#{SHATTERED_ROOT}/media/templates/#{template}.rmaterial")
18
+ create_ogre_material!
19
+ end
20
+ def method_missing(name, *args)
21
+ # Check if the method is a setter
22
+ if name.to_s[-1].chr == "="
23
+ name = name.to_s[0...-1].to_sym
24
+ # Set the instance variable to the sent variable
25
+ ivar = :"@#{ name }"
26
+ instance_variable_set(ivar, args[0])
27
+ else
28
+ begin
29
+ return eval("@#{name}")
30
+ rescue StandardError => bang
31
+ raise NoMethodError, "Rmaterial could not find the #{name} attribute: #{bang.message}"
32
+ end
33
+ end
34
+ end
35
+ def evaluate!(template)
36
+ evaluator = ERB.new(template)
37
+ return @result ||= evaluator.result(binding)
38
+ end
39
+ def tangent_space
40
+ false
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,48 @@
1
+ require 'erb'
2
+
3
+ module ShatteredView
4
+ class Runner #:nodoc:
5
+ def initialize(options = {})
6
+ generate_plugin_config
7
+ Resources.instance.add_resource_paths("/app/views", "/media")
8
+ @renderer = ShatteredOgre::Renderer.new
9
+ raise Error, "Renderer failed to initialize Ogre" if @renderer.failed
10
+ @scene = ShatteredOgre::Scene.new(translate_to_scene_type(options[:scene_manager]))
11
+ end
12
+ def generate_plugin_config
13
+ plugin_directory = SHATTERED_ROOT+"/config/"
14
+ generated_plugin = plugin_directory+ "plugins."
15
+ generator = plugin_directory + "ogre_plugins.rcfg"
16
+ if PLATFORM =~ /mswin/
17
+ generated_plugin += "win32"
18
+ elsif PLATFORM =~ /darwin/
19
+ generated_plugin += "darwin"
20
+ else
21
+ generated_plugin += "linux"
22
+ end
23
+ process_plugin(generator, generated_plugin+".cfg")
24
+ end
25
+ def process_plugin(base, generate_to)
26
+ puts "Generating #{generate_to} from #{base}, #{File.exists?(base)}"
27
+ return unless File.exists?(base)
28
+ generated_banner = "\n\r//=== This file is generated. Modify the .rcfg instead. ===\n\r\n\r"
29
+ to_write = generated_banner + ERB.new(File.open(base,"r").read).result + generated_banner
30
+ output = File.open(generate_to, "w")
31
+ output.syswrite(to_write)
32
+ output.close
33
+ end
34
+ def translate_to_scene_type( symbol )
35
+ return ShatteredOgre::Scene::Generic if(symbol == :general)
36
+ return ShatteredOgre::Scene::Terrain if(symbol == :terrain)
37
+ return ShatteredOgre::Scene::Nature if(symbol == :nature)
38
+ return ShatteredOgre::Scene::NaturePaging if(symbol == :paging)
39
+ return ShatteredOgre::Scene::Indoor if(symbol == :indoor)
40
+ end
41
+ def add_to_environment(environment)
42
+ environment[:scene]=@scene
43
+ environment[:renderer]=@renderer
44
+ environment[:camera]=Camera.new @scene
45
+ environment[:input]=ShatteredOgre::Input.new
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,7 @@
1
+ module ShatteredView
2
+ class MockObject
3
+ def method_missing(sym, *args)
4
+ MockObject.new
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,242 @@
1
+ class Object
2
+ # This is a shorthand to define vector object coordinates.
3
+ #
4
+ # Creates a vector object at coordinates x,y,z
5
+ def v(x, y, z)
6
+ Vector.new(x, y, z)
7
+ end
8
+ end
9
+
10
+ class SymbolToVectorError < StandardError #:nodoc:
11
+ end
12
+
13
+ class Symbol #:nodoc:
14
+ # Vectors in symbol form can be any of the following:
15
+ # :x => v(1,0,0)
16
+ # :y => v(0,1,0)
17
+ # :z => v(0,0,1),
18
+ # :up => v(0,1,0)
19
+ # :down => v(0,-1,0)
20
+ # :left => v(-1,0,0)
21
+ # :right => v(1,0,0)
22
+ # :forward => v(0,0,1)
23
+ # :backward => v(0,0,-1)
24
+ # :zero => v(0,0,0)
25
+ def to_v
26
+ @definitions ||= {:x => v(1,0,0),:y => v(0,1,0),:z => v(0,0,1),
27
+ :up => v(0,1,0),:down => v(0,-1,0),
28
+ :left => v(-1,0,0),:right => v(1,0,0),
29
+ :forward => v(0,0,1),:backward => v(0,0,-1),
30
+ :zero => v(0,0,0)}
31
+ return @definitions[self] unless @definitions[self].nil?
32
+ raise SymbolToVectorError, "Undefined vector for symbol #{self}"
33
+ end
34
+
35
+ # Multiplication defined for vectors carries over to their symbolic equivalence.
36
+ def *(number)
37
+ return to_v * number
38
+ end
39
+ end
40
+
41
+ class Array #:nodoc:
42
+ # Vector extensions for array. Allows for coersion of a 3 element Array into a vector.
43
+
44
+ # Randomize the order of an array
45
+ #
46
+ # [1, 2, 3].shuffle #=> [2, 3, 1]
47
+ #
48
+ def shuffle
49
+ sort_by {rand}
50
+ end
51
+
52
+ # Create a vector from an array.
53
+ #
54
+ # [1, 2, 3].to_v #=> same as Vector.new(1, 2, 3)
55
+ #
56
+ def to_v
57
+ raise StandardError, "vector #{self.inspect} does not have 3 elements" if self.length < 3
58
+ Vector.new self[0], self[1] ,self[2]
59
+ end
60
+
61
+ # Returns this Array as an Ogre vector object: Vector3. Should only be used internally by
62
+ # Shattered to communicate with the Ogre engine.
63
+ def to_v3
64
+ self.to_v.to_v3
65
+ end
66
+ end
67
+
68
+ # Vector is a three dimensional array, that allows for various operations on itself.
69
+ # To create a vector, use the shorthand:
70
+ # v(0,0,0) # Creates a zero vector
71
+ class Vector
72
+
73
+ attr_reader :x, :y, :z
74
+
75
+ # Create a new Vector object. It requires exactly 3 arguments: x, y and z. Any value that
76
+ # can be converted to a float is acceptable.
77
+ #
78
+ # *NOTE:* The recomended way to create Vector objects is to use the <tt>v(1,2,3)</tt> shorthand.
79
+ def initialize(x_val, y_val, z_val)
80
+ @x, @y, @z = [x_val, y_val, z_val].collect{ |x| x.to_f }
81
+ end
82
+
83
+ # Iterate through x, y and z with a block. The passed value is the value of each component of
84
+ # the vector.
85
+ def each(&block)
86
+ self.to_a.each do |component|
87
+ yield component
88
+ end
89
+ end
90
+
91
+ # Returns this Vector as an Ogre vector object: Vector3. Should only be used internally by
92
+ # Shattered to communicate with the Ogre engine.
93
+ def to_v3 # :nodoc:
94
+ ShatteredOgre::Vector3.new @x, @y, @z
95
+ end
96
+
97
+ # Returns self
98
+ def to_v
99
+ self
100
+ end
101
+
102
+ # Returns an array with x, y and z dumped into its elements.
103
+ # v(1, 2, 3).to_a #=> [1.0, 2.0, 3.0]
104
+ def to_a
105
+ [@x, @y, @z]
106
+ end
107
+
108
+ # Add 2 Vectors together.
109
+ # v(1,1,1) + v(1,2,3) #=> v(2,3,4)
110
+ def +(*args)
111
+ vector = convert_args_to_vector(args)
112
+ Vector.new(
113
+ self.x + vector.x,
114
+ self.y + vector.y,
115
+ self.z + vector.z
116
+ )
117
+ end
118
+
119
+ # Subtract one Vector from another.
120
+ # v(1,2,3) - v(1,1,1) #=> v(0,1,2)
121
+ def -(args)
122
+ vector = convert_args_to_vector(args)
123
+ Vector.new(
124
+ self.x - vector.x,
125
+ self.y - vector.y,
126
+ self.z - vector.z
127
+ )
128
+ end
129
+
130
+ # Multiply all components of a vector by a scalar amount.
131
+ # v(1,2,3) * 3 #=> v(3,6,9)
132
+ def *(value)
133
+ result = []
134
+ each do |i|
135
+ result << i * value
136
+ end
137
+ result.to_v
138
+ end
139
+
140
+ # Divide all components of a vector by a scalar amount
141
+ # v(5,10,15) / 5 #=> v(1,2,3)
142
+ def /(value)
143
+ result = Array.new
144
+ self.each do |i|
145
+ result << i/value.to_f
146
+ end
147
+ result.to_v
148
+ end
149
+
150
+ # Returns this Vector but normalized to a length of 1.
151
+ # v(9, 0, 0).normalize #=> v(1,0,0)
152
+ def normalize
153
+ self * (1 / length)
154
+ end
155
+ alias_method :normalise, :normalize
156
+
157
+ # Same as #normalize but modifies the receiver in place.
158
+ def normalize!
159
+ @x, @y, @z = normalize.to_a
160
+ end
161
+ alias_method :normalise!, :normalize!
162
+
163
+ # Return the value specified by bracket notation. Integers, Symbols or Strings
164
+ # are accepted as keys.
165
+ #
166
+ # vector = v(1,2,3)
167
+ # vector[:x] #=> 1
168
+ # vector['y'] #=> 2
169
+ # vector[2] #=> 3
170
+ def [](index)
171
+ case
172
+ when index == 0 || index == :x || index == 'x'
173
+ @x
174
+ when index == 1 || index == :y || index == 'y'
175
+ @y
176
+ when index == 2 || index == :z || index == 'z'
177
+ @z
178
+ end
179
+ end
180
+
181
+ # Set the value specified by bracket notation. Accepts the same keys as the #[]
182
+ # method.
183
+ def []=(index, value)
184
+ case
185
+ when index == 0 || index == :x || index == 'x'
186
+ @x = value.to_f
187
+ when index == 1 || index == :y || index == 'y'
188
+ @y = value.to_f
189
+ when index == 2 || index == :z || index == 'z'
190
+ @z = value.to_f
191
+ end
192
+ end
193
+
194
+ # Set the value of the X component.
195
+ def x=(value)
196
+ @x = value.to_f
197
+ end
198
+
199
+ # Set the value of the Y component.
200
+ def y=(value)
201
+ @y = value.to_f
202
+ end
203
+
204
+ # Set the value of the Z component.
205
+ def z=(value)
206
+ @z = value.to_f
207
+ end
208
+
209
+
210
+ # Returns the length of this vector.
211
+ # v(0,0,7).length #=> 7
212
+ def length
213
+ Math.sqrt(x**2 + y**2 + z**2)
214
+ end
215
+
216
+ # Converts the vector into an easily identifiable form. Mostly used for debugging
217
+ # and console output.
218
+ # v(1,2,3).to_s #=> "#<Vector [1.0, 2.0, 3.0]>"
219
+ def to_s
220
+ "#<Vector [#@x, #@y, #@z]>"
221
+ end
222
+
223
+ # Equality test. This method will return true if all components of both vectors are
224
+ # indentical.
225
+ def ==(vector)
226
+ vector.kind_of?(Vector) &&
227
+ x == vector.x &&
228
+ y == vector.y &&
229
+ z == vector.z
230
+ end
231
+
232
+ private
233
+
234
+ def convert_args_to_vector(*args)
235
+ args.flatten!
236
+ if args.first.is_a? Vector
237
+ args.first
238
+ else
239
+ args.to_v
240
+ end
241
+ end
242
+ end