teien 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
@@ -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