TRACKING AN ENEMY BY POINTING AT IT. Bones transformations with lingo - the transform() object |
transform() by definition.... If I want to make the head or guns of my character look or point at an enemy whilst in range, the only code I can use in lingo to rotate a bone is; member("3d").model[1].bonesPlayer.bone[7].transform = ................ This is great
because only the bone that im manipulating stops animating! Most but not all transform rotations are inverted. All bones on my model are at transform.position.y zero. What I have
been doing: IDEAL edge would be: model[1].bonesPlayer.bone[7].transform = camera[1].transform see example movie no#1 hereThe next point.- a useful bit of code to be called when in range of enemy.... tP = model("enemy").transform.position Abra Cadabra - The camera rotates to face the enemy. Hmmm if only the head did too! What actually happens is... when I turn the camera null left the head faces right. When I turn the camera null upward the head faces downward. if I inverse() the transform I get other anomalies. Which made we wonder about editing the transform() object directly -- Welcome to Director -- put t[1] , t[16] --report
the 1st and 16th items in the list As I found, it is easy to target the different values in the transform() object I know that "transform.position's" always inhabit item no's. 13,14,15 in the list; X, Y, Z respectively. What I need to know is, where are the rotations in this list ? I did the following test... |
Created a new
transform() object;
| LIST POSITION | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |
| t
= transform() |
1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 |
Rotated 3 different
versions of this object on either the X, Y, or Z axis and tracked the changes.
| LIST POSITION | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |
| X axis rotation | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.2 | 0.9 | 0.0 | 0.0 | -0.9 | 0.2 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 |
| Y axis rotation | 0.2 | 0.0 | -0.9 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.9 | 0.0 | 0.2 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 |
| Z axis rotation | 0.2 | 0.9 | 0.0 | 0.0 | -0.9 | 0.2 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 |
Ok ! so that left 6 values untouched..... and each some overlapped with 2 others !
Lets look at scaling an object using another new transform()
t = transform()
t.scale(11,12,13)
| LIST POSITION | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |
| t.scale = (11,12,13) |
11.0 | 0.0 | 0.0 | 0.0 | 0.0 | 12.0 | 0.0 | 0.0 | 0.0 | 0.0 | 13.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 |
Hmmm.... these values also overlap the previous. I guess I cant change
these values by extracting and replacing the list values.
I'll have to try this....
-- Welcome to Director --
t = transform()
-- create a new transform
put t
-- transform(1.00000,0.00000,0.00000,0.00000, 0.00000,1.00000,0.00000,0.00000,
0.00000,0.00000,1.00000,0.00000, 0.00000,0.00000,0.00000,1.00000)
put t.rotation -- vector( 0.0, 0.0, 0.0 )
put t.position -- vector( 0.0, 0.0, 0.0 )
put t.scale -- vector( 1.0, 1.0, 1.0 )
put t.rotation.x
-- 0.0
Ok so I can target the Y transform.rotation this way. What I need to do next is
invert() only that information and pass it on to a transform which I can use to rotate the head correctly.
-- Welcome to Director --
t = transform() --create new transform
object
t.rotate(7,9,8) -- rotate it
put t -- report it
-- transform(0.97808,0.13746,-0.15643,0.00000, -0.11926,0.98554,0.12037,0.00000,
0.17072,-0.09907,0.98033,0.00000, 0.00000,0.00000,0.00000,1.00000)
t2 = t -- duplicate it
t2.invert() -- invert() the duplicate
t.rotation = t2.rotation -- change the original rotation
to an inverted rotation
put t -- report it ( notice the change ! )
-- transform(0.97808,-0.11926,0.17072,0.00000, 0.13746,0.98554,-0.09907,0.00000,
-0.15643,0.12037,0.98033,0.00000, 0.00000,0.00000,0.00000,1.00000)
I
could do this -->
t.rotation.y = t2.rotation.y
!
I
could also do this -->
t.rotation.y = t2.rotation.z !
In a word I thought - WHA-LAH ! Finally an answer - but it went deeper. the head now rotated side to side diagonally
Im
not going to explain why, but multiplying the results by pi (3.1416) returned
results twice the amount wanted
so it needed to be divided by 2, and the other result needed to be inverted
so I multiplied it by minus 1.
t.rotation.z = (( tx.rotation.x * pi ) * -1 ) / 2
t.rotation.x = ( tx.rotation.y * pi ) / 2
w.model[1].bonesPlayer.bone[14].transform = t
To save some frame rate for something more important ill find out that amount myself
-- Welcome to Director --
put (pi * - 1 ) / 2
-- -1.5708
The finished version;
on handler (me)
t = w.camera("head null").getworldtransform() -- get the transform()
of the camera null
tx = t -- duplicate it
t.rotation.z = tx.rotation.x * -1.5708 -- change thecurrent values to the desired
values
t.rotation.x = tx.rotation.y * 1.5708 -------------------------------------------------
w.model[1].bonesPlayer.bone[14].transform = t -- then apply them
end
The next step was to make the Camera Null pointat() the enemy,
NB:
I will have to set some limits so that if within a
certain distance the head will only track a certain degree relative to itself
otherwise it will look straight ahead as normal.