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.
- data/lib/shattered_controller.rb +3 -0
- data/lib/shattered_controller/actor/actor.rb +107 -0
- data/lib/shattered_controller/base.rb +108 -0
- data/lib/shattered_controller/keyboard_input/key_converter.rb +43 -0
- data/lib/shattered_controller/keyboard_input/keyboard_input.rb +106 -0
- data/lib/shattered_controller/mock_camera.rb +9 -0
- data/lib/shattered_controller/runner.rb +33 -0
- data/lib/shattered_controller/state.rb +59 -0
- data/lib/shattered_model.rb +3 -0
- data/lib/shattered_model/base.rb +24 -0
- data/lib/shattered_model/fuzzy_logic.rb +188 -0
- data/lib/shattered_model/linear_interpolator.rb +29 -0
- data/lib/shattered_pack.rb +11 -0
- data/lib/shattered_pack/base.rb +127 -0
- data/lib/shattered_pack/pre_initialize/pre_initialize.rb +105 -0
- data/lib/shattered_pack/runner.rb +11 -0
- data/lib/shattered_pack/timer/timed_event.rb +77 -0
- data/lib/shattered_pack/timer/timer.rb +75 -0
- data/lib/shattered_view.rb +7 -0
- data/lib/shattered_view/base.rb +151 -0
- data/lib/shattered_view/camera.rb +7 -0
- data/lib/shattered_view/extensions.rb +10 -0
- data/lib/shattered_view/light.rb +28 -0
- data/lib/shattered_view/mesh/animation.rb +20 -0
- data/lib/shattered_view/mesh/mesh.rb +135 -0
- data/lib/shattered_view/node.rb +113 -0
- data/lib/shattered_view/resources.rb +47 -0
- data/lib/shattered_view/rmaterial.rb +43 -0
- data/lib/shattered_view/runner.rb +48 -0
- data/lib/shattered_view/utilities.rb +7 -0
- data/lib/shattered_view/vector.rb +242 -0
- metadata +75 -0
@@ -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,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
|