shattered_view 0.3

Sign up to get free protection for your applications and to get access to all the features.
data/lib/animation.rb ADDED
@@ -0,0 +1,17 @@
1
+ module ShatteredView
2
+ class Animation
3
+ def initialize(mesh, name)
4
+ @animation = mesh.getAnimation name
5
+ @animation.addAsFrameListener
6
+ end
7
+ def play
8
+ @animation.play
9
+ end
10
+ def loop=(looping)
11
+ @animation.setLoop(looping);
12
+ end
13
+ def time_scale=(scale)
14
+ @animation.setTimeScale(scale);
15
+ end
16
+ end
17
+ end
data/lib/base.rb ADDED
@@ -0,0 +1,199 @@
1
+
2
+ include ShatteredOgre
3
+ include ShatteredSupport
4
+
5
+ module ShatteredView
6
+
7
+ class Error < StandardError; end
8
+
9
+ def self.append_features(base)
10
+ super
11
+ base.extend(ClassMethods)
12
+ end
13
+
14
+ module ClassMethods
15
+ # Materials are parsed through erb as .rmaterials and parsed when a material
16
+ # metafunction is called.
17
+ #
18
+ # Example:
19
+ # material :wall_material, :template => 'normal_map', :texture => 'wall.png', :normal => 'brick_normals.png', :tangent_space => true
20
+ # mesh :wall, :material => :wall_material
21
+ #
22
+ # You must make sure that your material name is unique, or Ogre will fail.
23
+ #
24
+ # All rmaterial files are included within media/templates, you can add your own there.
25
+ # TODO: ruby script/generate material (?)
26
+ def material(name, options = {})
27
+ before_init_set "self", {:new_material => [name]}
28
+ before_init_set name, options
29
+ before_init_set name, {:create_ogre_material => []}
30
+ end
31
+
32
+ # This deserves a larger explanation
33
+ #
34
+ # options can include:
35
+ # - :animation => (not implemented yet)
36
+ # - - :speed => speed in game_seconds/animation_seconds
37
+ # - - :start_at => animation name to start the animation
38
+ # - - :loops => default for looping
39
+ def mesh(file, options = {})
40
+ name = file.underscore
41
+ before_init_set( "self", {:new_mesh => file })
42
+
43
+ define_method(name.to_sym) do
44
+ return instance_variable_get(:"@#{name}")
45
+ end
46
+
47
+ #What is this?
48
+ options = options.dup
49
+ options.delete :file
50
+ options.delete :name
51
+
52
+ before_init_set( name, options )
53
+ end
54
+
55
+ #
56
+ #
57
+ # options can include any function in animation.rb
58
+ # and :alias => :alias_name
59
+ def animation(name, options = {})
60
+ alias_option = options.delete(:alias)
61
+ before_init_set("animation(:#{name})", options)
62
+ before_init_set("self", {:new_animation => [name]})
63
+ if not alias_option.nil?
64
+ before_init_set("self", {:new_animation_alias => [name, alias_option]})
65
+ end
66
+ end
67
+
68
+
69
+ # Any view can create a light.
70
+ # There are 4 types of possible lights.
71
+ # Ambient Light - this type of light lights everything in the scene equally.
72
+ # Example: light :sun, :ambient => [1,1,1]
73
+ #
74
+ # Point Light - this type of light emanates from a point in space and lights all
75
+ # directions equally.
76
+ # Example: light :fireplace, :position => [0,-5,20], :diffuse => [1,0.5,0.5], :specular => [1,0,0], :attenuation => [8000,0,4,0.3]
77
+ # Parameters:
78
+ # :position: the x,y,z position or vector position
79
+ # :diffuse: the r,g,b value of the diffuse color
80
+ # :specular: the r,g,b value of the specular color
81
+ # :attenuation: arguments are range, constant, linear, quadratic
82
+ # range is how far the light will extend
83
+ # constant The constant factor in the attenuation formula: 1.0 means never attenuate, 0.0 is complete attenuation
84
+ # linear The linear factor in the attenuation formula: 1 means attenuate evenly over the distance
85
+ # quadratic The quadratic factor in the attenuation formula: adds a curvature to the attenuation formula.
86
+ #
87
+ # Directional Light - this light is like the positional light, except instead of position it has only direction
88
+ # Example: light :sun, :direction => [0,-1,-1], :diffuse => [1,1,1], :specular => [1,1,1]
89
+ # :direction: the direction light emanates from
90
+ # : other : same as point light above.
91
+ #
92
+ # Spotlight - this light has both a direction and a position, as well as other factors.
93
+ # Example: light :flashlight...
94
+ # TODO: This type of light is not currently implemented in shattered.
95
+
96
+ def light(name, options = {})
97
+ before_init_set "self", {:new_light => [name]}
98
+ before_init_set name, options
99
+ end
100
+
101
+ end
102
+
103
+ class Base < ShatteredSupport::Base
104
+ attr_reader :meshes
105
+
106
+ def unload!
107
+ meshes.each { |mesh| mesh.remove_from_scene }
108
+ end
109
+
110
+ #Note that this method is very similiar to ShatteredController::Actor.
111
+ #And that a common function can be refactored from both.
112
+ def method_missing(method, *args)
113
+ super(method,*args) if !method_defined?(method)
114
+ retv=nil
115
+ meshes.each do |mesh|
116
+ retv =mesh.send(method, *args) if mesh.method_defined? method
117
+ end
118
+
119
+ return retv
120
+ end
121
+
122
+ def method_defined?(method)
123
+ meshes.each { |mesh| return true if mesh.method_defined? method }
124
+ return super(method)
125
+ end
126
+
127
+ def mesh(file, options={})
128
+ self.class.mesh(file,options)
129
+ pre_initialize
130
+ retv = meshes[-1] # Return the last created mesh
131
+ return retv
132
+ end
133
+
134
+ def new_mesh=(file)
135
+ options = {}
136
+ options[:name]=file.underscore
137
+ options[:file]=file
138
+ name = options[:name]
139
+ mesh = Mesh.new(options)
140
+ eval("@#{name}=mesh")
141
+ #keep track of the meshes we create
142
+ meshes << mesh
143
+ end
144
+
145
+ def meshes
146
+ @meshes ||= []
147
+ end
148
+
149
+ def new_material=(name)
150
+ @materials ||= {}
151
+ name = name.to_sym
152
+ @materials[name] = RMaterial.new
153
+ @materials[name].name=name
154
+ self.class.send(:define_method, name) do
155
+ @materials[name]
156
+ end
157
+ end
158
+
159
+ def new_light=(name)
160
+ @lights ||= {}
161
+ @lights[name] = ShatteredView::Light.new
162
+ self.class.class_eval <<-EOF
163
+ define_method(:#{name}) do
164
+ @lights[name]
165
+ end
166
+ EOF
167
+ end
168
+
169
+ def new_animation=(name)
170
+ meshes.each do |mesh|
171
+ mesh.instance_eval <<-EOF
172
+ class << self
173
+ define_method(:#{name}) do
174
+ animation(:#{name})
175
+ end
176
+ end
177
+ EOF
178
+ end
179
+ end
180
+ def new_animation_alias=(name, alias_option)
181
+ self.class.class_eval <<-EOF
182
+ define_method(:#{alias_option}) do
183
+ meshes.each do |mesh|
184
+ mesh.#{name}.play
185
+ end
186
+ end
187
+ EOF
188
+ end
189
+
190
+ protected
191
+ def mesh_public_methods
192
+ methods=[]
193
+ meshes.each do |mesh|
194
+ methods |= mesh.public_methods
195
+ end
196
+ return methods
197
+ end
198
+ end
199
+ end
data/lib/camera.rb ADDED
@@ -0,0 +1,7 @@
1
+ module ShatteredView
2
+ class Camera < Mesh
3
+ def initialize( scene )
4
+ @scene_object = scene.getCamera
5
+ end
6
+ end
7
+ end
data/lib/extensions.rb ADDED
@@ -0,0 +1,7 @@
1
+ module ShatteredOgre
2
+ class Vector3
3
+ def to_a
4
+ Vector.new(x,y,z)
5
+ end
6
+ end
7
+ end
data/lib/game.rb ADDED
@@ -0,0 +1,42 @@
1
+ require 'ruby/utilities'
2
+ require 'view/View'
3
+ include View
4
+
5
+ class Game
6
+ @@instance = MockObject.new
7
+ def initialize( sceneType)
8
+ @renderer = Renderer.new
9
+ @scene = Scene.new sceneType
10
+ @camera = @scene.getCamera()
11
+ @camera.setDirection(Vector3.UNIT_Z)
12
+ @listeners = []
13
+ @timeScale = 1.0
14
+
15
+ @@instance = self
16
+ @@gameOver=false
17
+ end
18
+ def Game.end
19
+ @@gameOver = true
20
+ end
21
+ def Game.instance
22
+ return @@instance
23
+ end
24
+ def each_frame
25
+ while( !@@gameOver && @renderer.nextFrame ) do
26
+ @listeners.each do |listener|
27
+ listener.frameStarted @renderer.timeSinceLastFrame * timeScale
28
+ end
29
+ yield @renderer.timeSinceLastFrame * timeScale
30
+ end
31
+ end
32
+ def addFrameListener( instance )
33
+ @listeners << instance
34
+ end
35
+ def removeFrameListener( instance )
36
+ @listeners.delete instance
37
+ end
38
+
39
+ attr_reader :scene, :camera
40
+ attr_accessor :timeScale
41
+ end
42
+
data/lib/light.rb ADDED
@@ -0,0 +1,29 @@
1
+ module ShatteredView
2
+ class Light
3
+ def light
4
+ @light ||= Scene.getSingleton().createLight
5
+ end
6
+ def direction=(*direction)
7
+ light.setType(ShatteredOgre::Light::LT_DIRECTIONAL)
8
+ light.setDirection(direction.to_v)
9
+ end
10
+ def diffuse=(r,g,b)
11
+ light.setDiffuseColour(r,g,b)
12
+ end
13
+ def specular=(r,g,b)
14
+ light.setSpecularColour(r,g,b)
15
+ end
16
+ def position=(*pos)
17
+ light.setType(ShatteredOgre::Light::LT_POINT)
18
+ pos = pos[0] if pos.length < 3
19
+ light.setPosition(pos.to_v)
20
+ end
21
+ def ambient=(r,g,b)
22
+ Scene.getSingleton().setAmbientLight(r,g,b);
23
+ end
24
+ def attenuation=(range, const, linear, quad)
25
+ light.setType(ShatteredOgre::Light::LT_POINT)
26
+ light.setAttenuation(range, const, linear, quad)
27
+ end
28
+ end
29
+ end
data/lib/mesh.rb ADDED
@@ -0,0 +1,79 @@
1
+
2
+ module ShatteredView
3
+ class Mesh
4
+ def remove_from_scene
5
+ @scene_object.removeFromScene
6
+ end
7
+ def initialize( options = {} )
8
+ if options[:test] != true
9
+ puts "Loading Mesh: #{@scene_object} from #{options[:file]}.mesh"
10
+ @scene_object = Scene.getSingleton.createMesh( Vector3.new(0,0,0), "#{options[:file]}.mesh" )
11
+ populate_animations
12
+ else
13
+ @scene_object = MockObject.new
14
+ end
15
+ end
16
+ def populate_animations
17
+ @animations = {}
18
+ (0...@scene_object.getNumberOfAnimations).each do |idx|
19
+ name = @scene_object.getAnimationName(idx)
20
+ @animations[name.downcase.to_sym] = ShatteredView::Animation.new(@scene_object, name)
21
+ end
22
+ end
23
+ def position=( *array )
24
+ array = array[0] if(array.length == 1)
25
+ @scene_object.setPosition array.to_v
26
+ end
27
+ def looking_at=( *look_toward )
28
+ look_toward = look_toward[0] if(look_toward.length == 1)
29
+ look_at(look_toward)
30
+ end
31
+ def position
32
+ @scene_object.getPosition.to_a
33
+ end
34
+ def look_at( position )
35
+ if position.is_a?(Array)
36
+ @scene_object.lookAt(position.to_v)
37
+ elsif position.is_a?(ShatteredOgre::Vector3)
38
+ @scene_object.lookAt(position)
39
+ elsif(position.is_a?(Mesh) || position.is_a?(Actor))
40
+ @scene_object.lookAt(position.position.to_v)
41
+ elsif position.is_a?(ShatteredOgre::Vector3)
42
+ else
43
+ raise ArgumentError, "#{position.inspect} is not a Mesh, Actor, or Vector."
44
+ end
45
+ end
46
+ def rotate( axis, degrees )
47
+ @scene_object.rotate(axis.to_v, degrees)
48
+ end
49
+ def rotation=(axis, degrees)
50
+ rotate axis, degrees
51
+ end
52
+ def animation( animation )
53
+ return @animations[animation]
54
+ end
55
+ def scale=( *scale )
56
+ if(scale.length == 1)
57
+ scale=scale[0]
58
+ @scene_object.scale( [scale,scale,scale].to_v )
59
+ else
60
+ @scene_object.scale( scale.to_v )
61
+ end
62
+ end
63
+ def material=( material )
64
+ if material.is_a? RMaterial
65
+ @scene_object.generateTangents if material.tangent_space
66
+ material = material.name
67
+ end
68
+ @scene_object.setMaterial(material.to_s)
69
+ end
70
+ def visible=(visible)
71
+ @scene_object.setVisible(visible)
72
+ end
73
+ # This is overriden from ShatteredSupport's extension to Object
74
+ # missing alias's
75
+ def method_defined?( method )
76
+ return (super(method) or @animations.include?(method))
77
+ end
78
+ end
79
+ end
data/lib/resources.rb ADDED
@@ -0,0 +1,63 @@
1
+ require 'singleton'
2
+
3
+
4
+ module ShatteredView
5
+ # Resource Handler is the ruby binding around Ogre's resource handler
6
+ # It provides all types of shortcuts for finding files and adding new paths.
7
+ class Resources
8
+ include Singleton
9
+
10
+ # Instance Methods
11
+ attr_reader :resource_paths
12
+ def initialize
13
+ @resource_paths=[]
14
+ end
15
+
16
+ def add_resource_paths(*paths)
17
+ paths.each do |path|
18
+ path = SHATTERED_ROOT + path
19
+ @resource_paths << path
20
+ each_directory_in_path(path) do |sub_path|
21
+ ShatteredOgre::ResourceHandler.getSingleton.addResourcePath(sub_path)
22
+ end
23
+ end
24
+ end
25
+
26
+ def destroy_paths
27
+ @resource_paths = []
28
+ end
29
+
30
+ # This is useful for any extension wanting to load resource files:
31
+ #
32
+ # Usage:
33
+ # ResourceHandler.instance.find_files_by_extensions("ogg","mp3","wav")
34
+ def find_files_by_extensions(*extensions)
35
+ reg_exp = /\.(#{extensions.join("|")})$/
36
+ files = []
37
+ @resource_paths.each do |path|
38
+ each_file_in_path(path) do |filename|
39
+ files << filename if filename =~ reg_exp
40
+ end
41
+ end
42
+ return files
43
+ end
44
+
45
+ def each_file_in_path(path)
46
+ each_directory_in_path do |directory|
47
+ Dir.foreach( directory ) do |filename|
48
+ resource = directory + "/#{filename}"
49
+ yield(resource) if File.file? resource
50
+ end
51
+ end
52
+ end
53
+
54
+ def each_directory_in_path(path,&block)
55
+ Dir.foreach(path) do |directory|
56
+ next if directory =~ /\..*/
57
+ full_path = "#{path}/#{directory}"
58
+ yield full_path
59
+ each_directory_in_path(full_path, &block)
60
+ end
61
+ end
62
+ end
63
+ end
data/lib/rmaterial.rb ADDED
@@ -0,0 +1,41 @@
1
+ require 'erb'
2
+
3
+ module ShatteredView
4
+ class RMaterial
5
+ attr_reader :result
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(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
+ if name.to_s[-1].chr == "="
22
+ name = name.to_s[0...-1].to_sym
23
+ ivar = :"@#{ name }"
24
+ instance_variable_set(ivar, args[0])
25
+ else
26
+ begin
27
+ return eval("@#{name}")
28
+ rescue StandardError => bang
29
+ raise NoMethodError, "Rmaterial could not find the #{name} attribute: #{bang.message}"
30
+ end
31
+ end
32
+ end
33
+ def evaluate!(template)
34
+ evaluator = ERB.new(template)
35
+ return @result ||= evaluator.result(binding)
36
+ end
37
+ def tangent_space
38
+ false
39
+ end
40
+ end
41
+ end
data/lib/runner.rb ADDED
@@ -0,0 +1,24 @@
1
+
2
+ module ShatteredView
3
+ class Runner
4
+ def initialize(options = {})
5
+ Resources.instance.add_resource_paths("/app/views", "/media")
6
+ @renderer = ShatteredOgre::Renderer.new
7
+ raise Error, "Renderer failed to initialize Ogre" if @renderer.failed
8
+ @scene = ShatteredOgre::Scene.new(translate_to_scene_type(options[:scene_manager]))
9
+ end
10
+ def translate_to_scene_type( symbol )
11
+ return ShatteredOgre::Scene::Generic if(symbol == :general)
12
+ return ShatteredOgre::Scene::Terrain if(symbol == :terrain)
13
+ return ShatteredOgre::Scene::Nature if(symbol == :nature)
14
+ return ShatteredOgre::Scene::NaturePaging if(symbol == :paging)
15
+ return ShatteredOgre::Scene::Indoor if(symbol == :indoor)
16
+ end
17
+ def add_to_environment(environment)
18
+ environment[:scene]=@scene
19
+ environment[:renderer]=@renderer
20
+ environment[:camera]=Camera.new @scene
21
+ environment[:input]=ShatteredOgre::Input.new
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,22 @@
1
+ require "active_support"
2
+ ["shattered_support","shattered_ogre"].each do |dependency|
3
+ begin
4
+ # require File.dirname(__FILE__)+"/../../#{dependency}/lib/#{dependency}"
5
+ #shattered_ogre is not getting included????
6
+ require dependency
7
+ rescue MissingSourceFile
8
+ require 'rubygems'
9
+ require dependency
10
+ end
11
+ end
12
+
13
+
14
+ require File.dirname(__FILE__) + '/animation'
15
+ require File.dirname(__FILE__) + '/utilities'
16
+ require File.dirname(__FILE__) + '/mesh'
17
+ require File.dirname(__FILE__) + '/camera'
18
+ require File.dirname(__FILE__) + '/extensions'
19
+ require File.dirname(__FILE__) + '/runner'
20
+ require File.dirname(__FILE__) + '/base'
21
+ require File.dirname(__FILE__) + '/rmaterial'
22
+ require File.dirname(__FILE__) + '/resource_handler'
data/lib/utilities.rb ADDED
@@ -0,0 +1,58 @@
1
+
2
+ class Array
3
+ def shuffle; sort_by {rand}; end
4
+ def to_v;
5
+ raise StandardError, "vector #{self.inspect} does not have 3 elements" if self.length < 3
6
+ return Vector3.new(self[0],self[1],self[2]);
7
+ end
8
+ end
9
+
10
+ module ShatteredView
11
+ class Vector < Array
12
+ def initialize(*args)
13
+ raise ArgumentError, "Vector takes three inputs on initialize" if args.length != 3
14
+ args.each { |value| self << value }
15
+ end
16
+ def +(args)
17
+ return (self.to_v + args.to_v).to_a
18
+ end
19
+ def -(args)
20
+ return (self.to_v - args.to_v).to_a
21
+ end
22
+ def *(value)
23
+ return (self.to_v*value).to_a
24
+ end
25
+ def x
26
+ self[0]
27
+ end
28
+ def y
29
+ self[1]
30
+ end
31
+ def z
32
+ self[2]
33
+ end
34
+ # def x=(ix)
35
+ # self[0] = ix
36
+ # end
37
+ # def y=(iy)
38
+ # self[1] = iy
39
+ # end
40
+ # def z=(iz)
41
+ # self[2] = iz
42
+ # end
43
+ end
44
+ class MockObject
45
+ def method_missing(sym, *args)
46
+ MockObject.new
47
+ end
48
+ end
49
+
50
+
51
+ # class Vector3
52
+ # def to_s
53
+ # return "(#{x},#{y},#{z})"
54
+ # end
55
+ # end
56
+
57
+
58
+ end
metadata ADDED
@@ -0,0 +1,56 @@
1
+ --- !ruby/object:Gem::Specification
2
+ rubygems_version: 0.8.11
3
+ specification_version: 1
4
+ name: shattered_view
5
+ version: !ruby/object:Gem::Version
6
+ version: "0.3"
7
+ date: 2006-04-28 00:00:00 -05:00
8
+ summary: "Shattered View: Manipulates OGRE in a ruby-esque fashion."
9
+ require_paths:
10
+ - lib
11
+ email:
12
+ homepage: http://www.hastilymade.com
13
+ rubyforge_project:
14
+ description: Shattered View uses Ogre and Ruby to create an accessible interface to normally convoluted common game tasks.
15
+ autorequire: shattered_view
16
+ default_executable:
17
+ bindir: bin
18
+ has_rdoc: "true"
19
+ required_ruby_version: !ruby/object:Gem::Version::Requirement
20
+ requirements:
21
+ - - ">"
22
+ - !ruby/object:Gem::Version
23
+ version: 0.0.0
24
+ version:
25
+ platform: ruby
26
+ signing_key:
27
+ cert_chain:
28
+ authors: []
29
+
30
+ files:
31
+ - lib/animation.rb
32
+ - lib/base.rb
33
+ - lib/camera.rb
34
+ - lib/extensions.rb
35
+ - lib/game.rb
36
+ - lib/light.rb
37
+ - lib/mesh.rb
38
+ - lib/resources.rb
39
+ - lib/rmaterial.rb
40
+ - lib/runner.rb
41
+ - lib/shattered_view.rb
42
+ - lib/utilities.rb
43
+ test_files: []
44
+
45
+ rdoc_options: []
46
+
47
+ extra_rdoc_files: []
48
+
49
+ executables: []
50
+
51
+ extensions: []
52
+
53
+ requirements:
54
+ - Shattered View is reliant on OGRE.
55
+ dependencies: []
56
+