teien 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +17 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +34 -0
- data/Rakefile +1 -0
- data/bin/teien +49 -0
- data/lib/teien/animation_operator.rb +142 -0
- data/lib/teien/camera.rb +25 -0
- data/lib/teien/camera_mover.rb +193 -0
- data/lib/teien/garden.rb +203 -0
- data/lib/teien/garden_object.rb +314 -0
- data/lib/teien/light_object.rb +36 -0
- data/lib/teien/object_factory.rb +302 -0
- data/lib/teien/object_info.rb +171 -0
- data/lib/teien/physics.rb +150 -0
- data/lib/teien/physics_info.rb +23 -0
- data/lib/teien/smooth_mover.rb +108 -0
- data/lib/teien/tools.rb +261 -0
- data/lib/teien/ui_listener.rb +68 -0
- data/lib/teien/user_interface.rb +201 -0
- data/lib/teien/version.rb +3 -0
- data/lib/teien/view.rb +244 -0
- data/lib/teien.rb +40 -0
- data/sample/standalone/hello_garden/hello_garden.rb +155 -0
- data/sample/standalone/hello_garden/plugins.cfg +17 -0
- data/sample/standalone/hello_garden/resources.cfg +21 -0
- data/sample/standalone/hello_garden/run +5 -0
- data/teien.gemspec +22 -0
- metadata +107 -0
@@ -0,0 +1,171 @@
|
|
1
|
+
module Teien
|
2
|
+
|
3
|
+
class MeshBBObjectInfo
|
4
|
+
attr_accessor :mesh_path
|
5
|
+
attr_accessor :size # Loading mesh only: bounding box size
|
6
|
+
attr_accessor :scale # Loading mesh only: scales mesh
|
7
|
+
attr_accessor :view_offset # Loading mesh only: offset of Mesh
|
8
|
+
attr_accessor :view_rotation # Loading mesh only: rotation offset of Mesh
|
9
|
+
attr_accessor :physics_offset # Loading mesh only: offset of collision Box
|
10
|
+
attr_accessor :material_name
|
11
|
+
|
12
|
+
def initialize(mesh_path, size, scale = Vector3D.new(1, 1, 1),
|
13
|
+
view_offset = Vector3D.new(0, 0, 0),
|
14
|
+
view_rotation = Quaternion.new(0, 0, 0, 1.0),
|
15
|
+
physics_offset = Vector3D.new(0, 0, 0))
|
16
|
+
@size = size
|
17
|
+
@mesh_path = mesh_path
|
18
|
+
@scale = scale
|
19
|
+
@view_offset = view_offset
|
20
|
+
@view_rotation = view_rotation
|
21
|
+
@physics_offset = physics_offset
|
22
|
+
@material_name = nil
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
class MeshObjectInfo
|
27
|
+
attr_accessor :mesh_path
|
28
|
+
attr_accessor :scale # Loading mesh only: scales mesh
|
29
|
+
attr_accessor :view_offset # Loading mesh only: offset of Mesh
|
30
|
+
attr_accessor :view_rotation # Loading mesh only: rotation offset of Mesh
|
31
|
+
attr_accessor :physics_offset # Loading mesh only: offset of collision Box
|
32
|
+
attr_accessor :material_name
|
33
|
+
|
34
|
+
def initialize(mesh_path, scale = Vector3D.new(1, 1, 1),
|
35
|
+
view_offset = Vector3D.new(0, 0, 0),
|
36
|
+
view_rotation = Quaternion.new(0, 0, 0, 1.0),
|
37
|
+
physics_offset = Vector3D.new(0, 0, 0))
|
38
|
+
@mesh_path = mesh_path
|
39
|
+
@scale = scale
|
40
|
+
@view_offset = view_offset
|
41
|
+
@view_rotation = view_rotation
|
42
|
+
@physics_offset = physics_offset
|
43
|
+
@material_name = nil
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
class FloorObjectInfo
|
48
|
+
attr_accessor :width
|
49
|
+
attr_accessor :height
|
50
|
+
attr_accessor :depth
|
51
|
+
attr_accessor :num_seg_x
|
52
|
+
attr_accessor :num_seg_y
|
53
|
+
attr_accessor :u_tile
|
54
|
+
attr_accessor :v_tile
|
55
|
+
attr_accessor :material_name
|
56
|
+
|
57
|
+
def initialize(width, height, depth = 0.5, num_seg_x = 1, num_seg_y = 1, u_tile = 1.0, v_tile = 1.0)
|
58
|
+
@width = width
|
59
|
+
@height = height
|
60
|
+
@depth = depth
|
61
|
+
@num_seg_x = num_seg_x
|
62
|
+
@num_seg_y = num_seg_y
|
63
|
+
@u_tile = u_tile
|
64
|
+
@v_tile = v_tile
|
65
|
+
@material_name = nil
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
class BoxObjectInfo
|
70
|
+
attr_accessor :size
|
71
|
+
attr_accessor :num_seg_x
|
72
|
+
attr_accessor :num_seg_y
|
73
|
+
attr_accessor :num_seg_z
|
74
|
+
attr_accessor :u_tile
|
75
|
+
attr_accessor :v_tile
|
76
|
+
attr_accessor :material_name
|
77
|
+
|
78
|
+
def initialize(size, num_seg_x = 1, num_seg_y = 1, num_seg_z = 1, u_tile = 1.0, v_tile = 1.0)
|
79
|
+
@size = size
|
80
|
+
@num_seg_x = num_seg_x
|
81
|
+
@num_seg_y = num_seg_y
|
82
|
+
@num_seg_z = num_seg_z
|
83
|
+
@u_tile = u_tile
|
84
|
+
@v_tile = v_tile
|
85
|
+
@material_name = nil
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
class SphereObjectInfo
|
90
|
+
attr_accessor :radius
|
91
|
+
attr_accessor :num_rings
|
92
|
+
attr_accessor :num_segments
|
93
|
+
attr_accessor :u_tile
|
94
|
+
attr_accessor :v_tile
|
95
|
+
attr_accessor :material_name
|
96
|
+
|
97
|
+
def initialize(radius, num_rings = 16, num_segments = 16, u_tile = 1.0, v_tile = 1.0)
|
98
|
+
@radius = radius
|
99
|
+
@num_rings = num_rings
|
100
|
+
@num_segments = num_segments
|
101
|
+
@u_tile = u_tile
|
102
|
+
@v_tile = v_tile
|
103
|
+
@material_name = nil
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
class CapsuleObjectInfo
|
108
|
+
attr_accessor :radius
|
109
|
+
attr_accessor :height
|
110
|
+
attr_accessor :num_rings
|
111
|
+
attr_accessor :num_segments
|
112
|
+
attr_accessor :num_seg_height
|
113
|
+
attr_accessor :u_tile
|
114
|
+
attr_accessor :v_tile
|
115
|
+
attr_accessor :material_name
|
116
|
+
|
117
|
+
def initialize(radius, height, num_rings = 8, num_segments = 16, num_seg_height = 1, u_tile = 1.0, v_tile = 1.0)
|
118
|
+
@radius = radius
|
119
|
+
@height = height
|
120
|
+
@num_rings = num_rings
|
121
|
+
@num_segments = num_segments
|
122
|
+
@num_seg_height = num_seg_height
|
123
|
+
@u_tile = u_tile
|
124
|
+
@v_tile = v_tile
|
125
|
+
@material_name = nil
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
class ConeObjectInfo
|
130
|
+
attr_accessor :radius
|
131
|
+
attr_accessor :height
|
132
|
+
attr_accessor :num_seg_base
|
133
|
+
attr_accessor :num_seg_height
|
134
|
+
attr_accessor :u_tile
|
135
|
+
attr_accessor :v_tile
|
136
|
+
attr_accessor :material_name
|
137
|
+
|
138
|
+
def initialize(radius, height, num_seg_base = 16, num_seg_height = 1, u_tile = 1.0, v_tile = 1.0)
|
139
|
+
@radius = radius
|
140
|
+
@height = height
|
141
|
+
@num_seg_base = num_seg_base
|
142
|
+
@num_seg_height = num_seg_height
|
143
|
+
@u_tile = u_tile
|
144
|
+
@v_tile = v_tile
|
145
|
+
@material_name = nil
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
class CylinderObjectInfo
|
150
|
+
attr_accessor :radius
|
151
|
+
attr_accessor :height
|
152
|
+
attr_accessor :capped
|
153
|
+
attr_accessor :num_seg_base
|
154
|
+
attr_accessor :num_seg_height
|
155
|
+
attr_accessor :u_tile
|
156
|
+
attr_accessor :v_tile
|
157
|
+
attr_accessor :material_name
|
158
|
+
|
159
|
+
def initialize(radius, height, capped = true, num_seg_base = 16, num_seg_height = 1, u_tile = 1.0, v_tile = 1.0)
|
160
|
+
@radius = radius
|
161
|
+
@height = height
|
162
|
+
@capped = capped
|
163
|
+
@num_seg_base = num_seg_base
|
164
|
+
@num_seg_height = num_seg_height
|
165
|
+
@u_tile = u_tile
|
166
|
+
@v_tile = v_tile
|
167
|
+
@material_name = nil
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
end
|
@@ -0,0 +1,150 @@
|
|
1
|
+
module Teien
|
2
|
+
|
3
|
+
CollisionFilter = Struct.new(:group, :mask)
|
4
|
+
|
5
|
+
class ContactResult < Bullet::ContactResultCallback
|
6
|
+
def initialize
|
7
|
+
super
|
8
|
+
@isCollided = false
|
9
|
+
end
|
10
|
+
|
11
|
+
def collided?
|
12
|
+
return @isCollided
|
13
|
+
end
|
14
|
+
|
15
|
+
def addSingleResult(cp,
|
16
|
+
colObj0, partId0, index0,
|
17
|
+
colObj1, partId1, index1)
|
18
|
+
@isCollided = true
|
19
|
+
return 0
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
|
24
|
+
class Physics < Bullet::TickListener
|
25
|
+
attr_accessor :dynamics_world
|
26
|
+
attr_accessor :max_sub_steps
|
27
|
+
attr_accessor :fixed_time_step
|
28
|
+
# attr_accessor :softBodyWorldInfo
|
29
|
+
|
30
|
+
def initialize(garden)
|
31
|
+
super()
|
32
|
+
@garden = garden
|
33
|
+
|
34
|
+
@max_sub_steps = 1
|
35
|
+
@fixed_time_step = 1.0 / 60.0
|
36
|
+
|
37
|
+
@rigid_bodies = []
|
38
|
+
end
|
39
|
+
|
40
|
+
def setup
|
41
|
+
@collision_config = Bullet::BtDefaultCollisionConfiguration.new();
|
42
|
+
@collision_dispatcher = Bullet::BtCollisionDispatcher.new(@collision_config)
|
43
|
+
|
44
|
+
worldAabbMin = Bullet::BtVector3.new(-3000.0,-500.0, -3000.0)
|
45
|
+
worldAabbMax = Bullet::BtVector3.new(3000.0, 500.0, 3000.0)
|
46
|
+
maxProxies = 1024 * 4
|
47
|
+
@aabb_cache = Bullet::BtAxisSweep3.new( worldAabbMin, worldAabbMax, maxProxies )
|
48
|
+
|
49
|
+
@solver = Bullet::BtSequentialImpulseConstraintSolver.new();
|
50
|
+
|
51
|
+
@dynamics_world = Bullet::BtDiscreteDynamicsWorld.new(@collision_dispatcher, @aabb_cache,
|
52
|
+
@solver, @collision_config)
|
53
|
+
gravity = Bullet::BtVector3.new(0.0, -9.8, 0.0)
|
54
|
+
@dynamics_world.setGravity(gravity)
|
55
|
+
|
56
|
+
@dynamics_world.setInternalTickCallback(self, true);
|
57
|
+
@dynamics_world.setInternalTickCallback(self, false);
|
58
|
+
=begin
|
59
|
+
worldAabbCache->getOverlappingPairCache()->setInternalGhostPairCallback(new btGhostPairCallback());
|
60
|
+
=end
|
61
|
+
=begin
|
62
|
+
@softBodyWorldInfo = Bullet::BtSoftBodyWorldInfo.new
|
63
|
+
softBodyWorldInfo.m_dispatcher = @collisionDispatcher
|
64
|
+
softBodyWorldInfo.m_broadphase = @gardenAabbCache
|
65
|
+
softBodyWorldInfo.m_gravity.setValue(0, -9.8, 0)
|
66
|
+
# softBodyWorldInfo.m_sparsesdf.Initialize();
|
67
|
+
=end
|
68
|
+
end
|
69
|
+
|
70
|
+
def finalize
|
71
|
+
# clear all objects.
|
72
|
+
@rigid_bodies.each{|body|
|
73
|
+
@dynamics_world.removeRigidBody(body)
|
74
|
+
}
|
75
|
+
@rigid_bodies = []
|
76
|
+
|
77
|
+
# @dynamics_world.finalize()
|
78
|
+
end
|
79
|
+
|
80
|
+
def update(delta)
|
81
|
+
@dynamics_world.stepSimulation(delta, @max_sub_steps, @fixed_time_step)
|
82
|
+
return true
|
83
|
+
end
|
84
|
+
|
85
|
+
def frameRenderingQueued(evt)
|
86
|
+
# print "Physics::tick: ", evt.timeSinceLastFrame * 1000, "ms\n"
|
87
|
+
@dynamics_world.stepSimulation(evt.timeSinceLastFrame, @max_sub_steps, @fixed_time_step)
|
88
|
+
return true
|
89
|
+
end
|
90
|
+
|
91
|
+
def flush_pair_cache(rigid_body)
|
92
|
+
pair_cache = @dynamics_world.getBroadphase().getOverlappingPairCache()
|
93
|
+
pair_cache.removeOverlappingPairsContainingProxy(rigid_body.getBroadphaseHandle(),
|
94
|
+
@dynamics_world.getDispatcher())
|
95
|
+
end
|
96
|
+
|
97
|
+
def set_gravity(vec)
|
98
|
+
@dynamics_world.setGravity(vec)
|
99
|
+
end
|
100
|
+
|
101
|
+
=begin
|
102
|
+
def create_box_shape(size)
|
103
|
+
return Bullet::BtBoxShape.new(size)
|
104
|
+
end
|
105
|
+
|
106
|
+
def createSphereShape(radius)
|
107
|
+
return Bullet::BtSphereShape.new(radius)
|
108
|
+
end
|
109
|
+
=end
|
110
|
+
|
111
|
+
def create_rigid_body(mass, motionState, colObj, inertia)
|
112
|
+
rigid_body = Bullet::BtRigidBody.new(mass, motionState, colObj, inertia)
|
113
|
+
rigid_body.instance_variable_set(:@collision_shape, colObj) # prevent this colObj from GC.
|
114
|
+
return rigid_body
|
115
|
+
end
|
116
|
+
|
117
|
+
def add_rigid_body(rigid_body, collision_filter = nil)
|
118
|
+
@rigid_bodies.push(rigid_body)
|
119
|
+
if (collision_filter)
|
120
|
+
@dynamics_world.addRigidBody(rigid_body, collision_filter.group, collision_filter.mask)
|
121
|
+
else
|
122
|
+
@dynamics_world.addRigidBody(rigid_body)
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
def contact_pair_test(colObjA, colObjB)
|
127
|
+
result = ContactResult.new
|
128
|
+
@dynamics_world.contactPairTest(colObjA, colObjB, result)
|
129
|
+
return result
|
130
|
+
end
|
131
|
+
|
132
|
+
def preTickCallback(timeStep)
|
133
|
+
# print "preTickCallback: ", timeStep * 1000, "ms\n"
|
134
|
+
delta = Bullet::BtVector3.new(timeStep, timeStep, timeStep)
|
135
|
+
|
136
|
+
@garden.objects.each {|name, obj|
|
137
|
+
if (obj.get_mass() > 0)
|
138
|
+
newVel = obj.get_linear_velocity() + obj.get_acceleration() * delta
|
139
|
+
obj.set_linear_velocity(obj.limit_velocity(newVel))
|
140
|
+
lastVel = obj.get_linear_velocity()
|
141
|
+
end
|
142
|
+
}
|
143
|
+
end
|
144
|
+
|
145
|
+
def tickCallback(timeStep)
|
146
|
+
# print "tickCallback: ", timeStep * 1000, "ms\n"
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Teien
|
2
|
+
|
3
|
+
class PhysicsInfo
|
4
|
+
attr_accessor :mass
|
5
|
+
attr_accessor :angular_factor # rotate along Y axis if 1.0
|
6
|
+
attr_accessor :friction
|
7
|
+
attr_accessor :restitution
|
8
|
+
attr_accessor :linear_damping
|
9
|
+
attr_accessor :angular_damping
|
10
|
+
attr_accessor :collision_filter
|
11
|
+
|
12
|
+
def initialize(mass = 1.0)
|
13
|
+
@mass = mass
|
14
|
+
@angular_factor = 1.0
|
15
|
+
@restitution = 0.2
|
16
|
+
@friction = 1.0
|
17
|
+
@linear_damping = 0.0
|
18
|
+
@angular_damping = 0.0
|
19
|
+
@collision_filter = nil
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
@@ -0,0 +1,108 @@
|
|
1
|
+
class SmoothMover
|
2
|
+
ACCELERATION = 5.0
|
3
|
+
TURN_SPEED = 500.0
|
4
|
+
|
5
|
+
attr_accessor :acceleration
|
6
|
+
attr_accessor :turnSpeed
|
7
|
+
attr_accessor :movable
|
8
|
+
|
9
|
+
def initialize(targetObject)
|
10
|
+
@targetObject = targetObject
|
11
|
+
|
12
|
+
@acceleration = ACCELERATION
|
13
|
+
@turnSpeed = TURN_SPEED
|
14
|
+
|
15
|
+
clearAction()
|
16
|
+
|
17
|
+
@movable = true
|
18
|
+
|
19
|
+
@zeroVector = Bullet::BtVector3.new(0, 0, 0)
|
20
|
+
@moveDir = Ogre::Vector3.new(0, 0, 0)
|
21
|
+
@cameraDir = Ogre::Vector3.new(0, 0, 0)
|
22
|
+
end
|
23
|
+
|
24
|
+
def clearAction()
|
25
|
+
@forward = false
|
26
|
+
@backward = false
|
27
|
+
@left = false
|
28
|
+
@right = false
|
29
|
+
end
|
30
|
+
|
31
|
+
def isMove()
|
32
|
+
return (@forward || @backward || @left || @right)
|
33
|
+
end
|
34
|
+
|
35
|
+
def moveForward(bool)
|
36
|
+
@forward = bool
|
37
|
+
end
|
38
|
+
|
39
|
+
def moveBackward(bool)
|
40
|
+
@backward = bool
|
41
|
+
end
|
42
|
+
|
43
|
+
def moveLeft(bool)
|
44
|
+
@left = bool
|
45
|
+
end
|
46
|
+
|
47
|
+
def moveRight(bool)
|
48
|
+
@right = bool
|
49
|
+
end
|
50
|
+
|
51
|
+
#
|
52
|
+
# This direction is the forward.
|
53
|
+
#
|
54
|
+
def moveCameraDirection(cameraDir)
|
55
|
+
@cameraDir = cameraDir
|
56
|
+
end
|
57
|
+
|
58
|
+
def updateTarget(delta)
|
59
|
+
@moveDir.x = 0
|
60
|
+
@moveDir.y = 0
|
61
|
+
@moveDir.z = 0
|
62
|
+
|
63
|
+
# update target's acceleration
|
64
|
+
if (@forward)
|
65
|
+
@moveDir += Ogre::Vector3.new(@cameraDir.x, @cameraDir.y, @cameraDir.z)
|
66
|
+
end
|
67
|
+
if (@backward)
|
68
|
+
@moveDir += Ogre::Vector3.new(-@cameraDir.x, -@cameraDir.y, -@cameraDir.z)
|
69
|
+
end
|
70
|
+
if (@left)
|
71
|
+
@moveDir += Ogre::Vector3.new(@cameraDir.z, 0, -@cameraDir.x)
|
72
|
+
end
|
73
|
+
if (@right)
|
74
|
+
@moveDir += Ogre::Vector3.new(-@cameraDir.z, 0, @cameraDir.x)
|
75
|
+
end
|
76
|
+
|
77
|
+
@moveDir.y = 0
|
78
|
+
@moveDir.normalise()
|
79
|
+
|
80
|
+
if (@movable)
|
81
|
+
newAcc = @moveDir * @acceleration
|
82
|
+
@targetObject.setAcceleration(Vector3D::to_bullet(newAcc))
|
83
|
+
else
|
84
|
+
@targetObject.setAcceleration(@zeroVector)
|
85
|
+
end
|
86
|
+
|
87
|
+
# update target's direction
|
88
|
+
=begin
|
89
|
+
ogreDir = -@targetObject.pivotSceneNode.getOrientation().zAxis()
|
90
|
+
bulletDir = -@targetObject.getOrientation().zAxis()
|
91
|
+
puts "OgreDir: (#{ogreDir.x}, #{ogreDir.y}, #{ogreDir.z})"
|
92
|
+
puts "BulletDir: (#{bulletDir.x}, #{bulletDir.y}, #{bulletDir.z})"
|
93
|
+
=end
|
94
|
+
|
95
|
+
toGoal = Vector3D.to_ogre(-@targetObject.getOrientation().zAxis()).getRotationTo(@moveDir)
|
96
|
+
yawToGoal = toGoal.getYaw().valueDegrees()
|
97
|
+
yawAtSpeed = yawToGoal / yawToGoal.abs * delta * @turnSpeed
|
98
|
+
|
99
|
+
if (yawToGoal < 0)
|
100
|
+
yawToGoal = [0, [yawToGoal, yawAtSpeed].max].min
|
101
|
+
|
102
|
+
elsif (yawToGoal > 0)
|
103
|
+
yawToGoal = [0, [yawToGoal, yawAtSpeed].min].max
|
104
|
+
end
|
105
|
+
|
106
|
+
@targetObject.yaw(Ogre::Degree.new(yawToGoal).valueRadians())
|
107
|
+
end
|
108
|
+
end
|
data/lib/teien/tools.rb
ADDED
@@ -0,0 +1,261 @@
|
|
1
|
+
require 'matrix'
|
2
|
+
|
3
|
+
# deep copy
|
4
|
+
def deep_copy(object)
|
5
|
+
return Marshal.load(Marshal.dump(object))
|
6
|
+
end
|
7
|
+
|
8
|
+
module Teien
|
9
|
+
|
10
|
+
#
|
11
|
+
# 2d vector
|
12
|
+
#
|
13
|
+
class Vector2D
|
14
|
+
attr_accessor :x
|
15
|
+
attr_accessor :y
|
16
|
+
def initialize(x = 0.0, y = 0.0)
|
17
|
+
set(x, y)
|
18
|
+
end
|
19
|
+
|
20
|
+
def set(x, y)
|
21
|
+
@x = x
|
22
|
+
@y = y
|
23
|
+
end
|
24
|
+
|
25
|
+
def ==(o)
|
26
|
+
if o.is_a?(Vector2D)
|
27
|
+
return @x == o.x && @y == o.y
|
28
|
+
else
|
29
|
+
return false
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
#
|
35
|
+
# 3d vector
|
36
|
+
#
|
37
|
+
class Vector3D < Bullet::BtVector3
|
38
|
+
def self.to_ogre(bullet)
|
39
|
+
return Ogre::Vector3.new(bullet.x, bullet.y, bullet.z)
|
40
|
+
end
|
41
|
+
|
42
|
+
def self.to_bullet(ogre)
|
43
|
+
return Bullet::BtVector3.new(ogre.x, ogre.y, ogre.z)
|
44
|
+
end
|
45
|
+
|
46
|
+
def self.to_self(vec)
|
47
|
+
return Vector3D.new(vec.x, vec.y, vec.z)
|
48
|
+
end
|
49
|
+
|
50
|
+
def self.to_s(vec)
|
51
|
+
return sprintf("(%f, %f, %f)", vec.x, vec.y, vec.z)
|
52
|
+
end
|
53
|
+
|
54
|
+
def copy(vec)
|
55
|
+
setValue(vec.x, vec.y, vec.z)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
|
60
|
+
class Quaternion < Bullet::BtQuaternion
|
61
|
+
def self.to_ogre(bullet)
|
62
|
+
return Ogre::Quaternion.new(bullet.w, bullet.x, bullet.y, bullet.z)
|
63
|
+
end
|
64
|
+
|
65
|
+
def self.to_bullet(ogre)
|
66
|
+
return Bullet::BtQuaternion.new(ogre.x, ogre.y, ogre.z, ogre.w)
|
67
|
+
end
|
68
|
+
|
69
|
+
def self.to_self(qt)
|
70
|
+
return Quaternion.new(qt.x, qt.y, qt.z, qt.w)
|
71
|
+
end
|
72
|
+
|
73
|
+
def self.to_s(qt)
|
74
|
+
return sprintf("(%f, %f, %f, %f)", qt.x, qt.y, qt.z, qt.w)
|
75
|
+
end
|
76
|
+
|
77
|
+
def copy(qt)
|
78
|
+
setValue(qt.x, qt.y, qt.z, qt.w)
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|
82
|
+
|
83
|
+
class Color < Ogre::ColourValue
|
84
|
+
end
|
85
|
+
|
86
|
+
class Radian < Ogre::Radian
|
87
|
+
end
|
88
|
+
|
89
|
+
class Degree < Ogre::Degree
|
90
|
+
end
|
91
|
+
|
92
|
+
|
93
|
+
|
94
|
+
|
95
|
+
=begin
|
96
|
+
class Vector3D
|
97
|
+
attr_accessor :x
|
98
|
+
attr_accessor :y
|
99
|
+
attr_accessor :z
|
100
|
+
def initialize(x = 0.0, y = 0.0, z = 0.0)
|
101
|
+
set(x, y, z)
|
102
|
+
end
|
103
|
+
|
104
|
+
def set(x, y, z)
|
105
|
+
@x = x
|
106
|
+
@y = y
|
107
|
+
@z = z
|
108
|
+
end
|
109
|
+
|
110
|
+
def copy(vec)
|
111
|
+
set(vec.x, vec.y, vec.z)
|
112
|
+
end
|
113
|
+
|
114
|
+
def +(pt)
|
115
|
+
return Vector3D.new(@x + pt.x, @y + pt.y, @z + pt.z)
|
116
|
+
end
|
117
|
+
|
118
|
+
def -(pt)
|
119
|
+
return Vector3D.new(@x - pt.x, @y - pt.y, @z - pt.z)
|
120
|
+
end
|
121
|
+
|
122
|
+
def -@
|
123
|
+
return Vector3D.new(-@x, -@y, -@z)
|
124
|
+
end
|
125
|
+
|
126
|
+
def *(f)
|
127
|
+
if (f.class == Vector3D)
|
128
|
+
return Vector3D.new(@x * f.x, @y * f.y, @z * f.z)
|
129
|
+
else
|
130
|
+
return Vector3D.new(@x * f, @y * f, @z * f)
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
def /(f)
|
135
|
+
if (f.class == Vector3D)
|
136
|
+
return Vector3D.new(@x / f.x, @y / f.y, @z / f.z)
|
137
|
+
else
|
138
|
+
return Vector3D.new(@x / f, @y / f, @z / f)
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
def ==(pt)
|
143
|
+
return (((@x - pt.x).abs <= Float::EPSILON * [@x.abs, pt.x.abs].max) &&
|
144
|
+
((@y - pt.y).abs <= Float::EPSILON * [@y.abs, pt.y.abs].max) &&
|
145
|
+
((@z - pt.z).abs <= Float::EPSILON * [@z.abs, pt.z.abs].max))
|
146
|
+
end
|
147
|
+
|
148
|
+
def nearTo(pt)
|
149
|
+
return (((@x - pt.x).abs <= 0.000001) &&
|
150
|
+
((@y - pt.y).abs <= 0.000001) &&
|
151
|
+
((@z - pt.z).abs <= 0.000001))
|
152
|
+
end
|
153
|
+
|
154
|
+
def dot(pt)
|
155
|
+
return (@x * pt.x + @y * pt.y + @z * pt.z)
|
156
|
+
end
|
157
|
+
|
158
|
+
def len()
|
159
|
+
return Math.sqrt(@x * @x + @y * @y + @z * @z)
|
160
|
+
end
|
161
|
+
|
162
|
+
def lenSquared()
|
163
|
+
return @x * @x + @y * @y + @z * @z
|
164
|
+
end
|
165
|
+
|
166
|
+
|
167
|
+
def normalize(newLen = 1.0)
|
168
|
+
l = len();
|
169
|
+
if (l == 0)
|
170
|
+
@x = 0
|
171
|
+
@y = 0
|
172
|
+
@z = 0
|
173
|
+
return false
|
174
|
+
else
|
175
|
+
l = newLen / l
|
176
|
+
@x *= l
|
177
|
+
@y *= l
|
178
|
+
@z *= l
|
179
|
+
return true
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
def toString
|
184
|
+
return sprintf("(%f, %f, %f)", @x, @y, @z)
|
185
|
+
end
|
186
|
+
end
|
187
|
+
=end
|
188
|
+
|
189
|
+
|
190
|
+
#
|
191
|
+
# Now constructing =)
|
192
|
+
# It's only data.
|
193
|
+
#
|
194
|
+
|
195
|
+
#class Quaternion < Bullet::BtQuaternion
|
196
|
+
#end
|
197
|
+
|
198
|
+
=begin
|
199
|
+
class Quaternion
|
200
|
+
attr_accessor :x
|
201
|
+
attr_accessor :y
|
202
|
+
attr_accessor :z
|
203
|
+
attr_accessor :w
|
204
|
+
def initialize(x = 0.0, y = 0.0, z = 0.0, w = 0.0)
|
205
|
+
set(x, y, z, w)
|
206
|
+
end
|
207
|
+
|
208
|
+
def set(x, y, z, w)
|
209
|
+
@x = x
|
210
|
+
@y = y
|
211
|
+
@z = z
|
212
|
+
@w = w
|
213
|
+
end
|
214
|
+
|
215
|
+
def setYPR(yaw, pitch, roll)
|
216
|
+
halfYaw = yaw * 0.5;
|
217
|
+
halfPitch = pitch * 0.5;
|
218
|
+
halfRoll = roll * 0.5;
|
219
|
+
cosYaw = Math::cos(halfYaw);
|
220
|
+
sinYaw = Math::sin(halfYaw);
|
221
|
+
cosPitch = Math::cos(halfPitch);
|
222
|
+
sinPitch = Math::sin(halfPitch);
|
223
|
+
cosRoll = Math::cos(halfRoll);
|
224
|
+
sinRoll = Math::sin(halfRoll);
|
225
|
+
|
226
|
+
@x = cosRoll * sinPitch * cosYaw + sinRoll * cosPitch * sinYaw;
|
227
|
+
@y = cosRoll * cosPitch * sinYaw - sinRoll * sinPitch * cosYaw;
|
228
|
+
@z = sinRoll * cosPitch * cosYaw - cosRoll * sinPitch * sinYaw;
|
229
|
+
@w = cosRoll * cosPitch * cosYaw + sinRoll * sinPitch * sinYaw;
|
230
|
+
|
231
|
+
return self
|
232
|
+
end
|
233
|
+
|
234
|
+
def copy(quat)
|
235
|
+
set(quat.x, quat.y, quat.z, quat.w)
|
236
|
+
end
|
237
|
+
|
238
|
+
def +(pt)
|
239
|
+
return Quaternion.new(@x + pt.x, @y + pt.y, @z + pt.z, @w + pt.w);
|
240
|
+
end
|
241
|
+
|
242
|
+
def -(pt)
|
243
|
+
return Quaternion.new(@x - pt.x, @y - pt.y, @z - pt.z, @w - pt.w);
|
244
|
+
end
|
245
|
+
|
246
|
+
def *(f)
|
247
|
+
return Quaternion.new(@x * f, @y * f, @z * f, @w * f)
|
248
|
+
end
|
249
|
+
|
250
|
+
def dot(pt)
|
251
|
+
return (@x * pt.x + @y * pt.y + @z * pt.z + @w * pt.w);
|
252
|
+
end
|
253
|
+
|
254
|
+
def len()
|
255
|
+
return Math.sqrt(dot(self))
|
256
|
+
end
|
257
|
+
|
258
|
+
end
|
259
|
+
=end
|
260
|
+
|
261
|
+
end # module
|