More help with rotations...

BlitzMax Forums/MiniB3D Module/More help with rotations...

jkrankie(Posted 2011) [#1]
Hi all,

I've been trying to simulate the movement physics in mario galaxy, where you can run around the surfaces of planetoids of various shapes and sizes. So far, it's going ok (i've been using the mario galaxy demystified thing as a basic guide), but i'm getting a bit stuck getting the player to face the direction he is supposed to.

I've posted my code so far below. It needs Warner's version of minib3d, which you can grab from here: http://www.blitzbasic.com/codearcs/codearcs.php?code=2498 (zip link towards the bottom of the page).

What i'm trying to do, is have the player face the direction you are entering on the keyboard/joystick at all times. The movement works in this way, but i don't really know how to make the rotations do the same. You'll notice if you run the program that it starts off rotating correctly, but the more you move around the more the angles get offset. this is most obvious on the cube planetoids is you spin around the corners.

here's the code:

controls are arrows/joystick to move, space of joystick button 1 to jump. change planet by clicking on anther one.



so, what can i do to get the rotation of the player correct? so that i always faces the direction you are pressing regardless of the cameras orientation?

Last edited 2011

Last edited 2011


Warner(Posted 2011) [#2]
I think, as a first step, try to get it upright allways, ie:
	TFormVector 0, 1, 0, cam, Null
	AlignToVector2 p1.mesh, TFormedX(), TFormedY(), TFormedZ(), 2, 1

Then, maybe attach a child mesh and rotate that.


jkrankie(Posted 2011) [#3]
Ah, thanks! I'd been trying that, but using the z parameter of tformvector. still haven't quite got my head around this. I'm getting there though.

Anyway, that seems to work, but there seems to be some strange behaviour when you rotate to around the 180 degree mark. things get wobbly!

Here's some updated code. The wobbly stuff was not terribly obvious using just the keyboard, so i've added on a value to the angle in MQ_Turn so you can see it. Pressing up will make the player's direction wobble, whereas left, down and right all appear to work as expected. Is this more gimbal lock?



Additionally, i haven't added a child mesh as you suggested (i don't really understand what you mean?), but instead just rotated the cone in place. What would the purpose of the child mesh be?

Cheers
Charlie


Warner(Posted 2011) [#4]
It seems that the wobbeling is caused by the +187 degrees turn.
I think the object's orientation affects the phyics that is used to keep the player aligned to the planetoids. Ie. LinePick being based on the rotation of the object.
Change line 122 to:
p1.mesh.MQ_Turn(playerang+180, 0, 0, 1)
And the wobbeling seems to be gone.
Either RotateMesh the cone by 7 degrees, or replace the cone by a pivot and attach another cone as a child mesh that is rotated by 7 degrees to it to still achieve this +187 angle.


jkrankie(Posted 2011) [#5]
I put the 187 in to demonstrate the wobbling. It's still there at 180, but not so obvious. If you've got a joystick, you'll notice that any angle between ~160 and 210 are wobbly.

I'll try the pivot thing and see if that helps.

Cheers
Charlie


jkrankie(Posted 2011) [#6]
Right, got it!

replaced the p1.mesh with a pivot, added a child cone entity, align the pivot to the camera and MQ_turn the child. This seems to get round the linepick induced wobbliness!

Thanks for your help!

Next job: let the player shoot in the direction they are facing!

Cheers
Charlie


Warner(Posted 2011) [#7]
Ah, well that will be peanuts now. :)


jkrankie(Posted 2011) [#8]
It wasn't too hard making something that worked. Actually, i came up with two different methods for letting the player shoot, neither of which i'm too happy with. They are both pretty slow.

The first uses a line pick, similar to how the player moves. The second uses collisions. Both are super slow when you turn the number of bullets up. i'm getting about ~20-30 fps with only 250 or so entities being rendered. With the line pick/collisions off i get about 150fps.

Chances are there's a much simpler method for moving the bullets around the various shapes, so any advice for alternatives is much appreciated! What i think i need is to be able to get the normal of the nearest surface of any given mesh, so i don't need the expensive line pick operation, or have to rely on collisions. But i can't work out how to do it :(

The bullet code is at the top of the while loop.


Cheers
Charlie


Warner(Posted 2011) [#9]
Well, you are now using EntityPickmode 2, which is slower than EntityPickmode 1 or 3. Maybe you can use them instead?
Line 33/34:
		EntityPickMode ast[i].mesh, 1
		EntityRadius ast[i].mesh, 1

Alternatively, you could investigate if you can keep an object on a planet by using maths only.
To elaborate a bit on that idea, the following projects lat/long coords onto a sphere. There might be much more suitable solutions for this, but unf. it is as far as my math skills go:


Last edited 2011


jkrankie(Posted 2011) [#10]
I'm familiar with the spherical coordinate calculation you've put here (i've used it lots in the past, most recently to make and animate a massive jellyfish!), and you're right, it's fine for spheres. However, the planets are not exclusively spherical, if you click your mouse on one of the cubes or cylinders in the background and fly to that planet, the bullets will need to track round the cube, so it's not always a spherical motion. In fact, you can, in theory, load any mesh you like and use that as a planet. Try it!

What i'm trying to avoid is to have to come up with different methods for moving things round each planetoid shape. The linepick method i have works exactly how i want it to (i.e, it works on every shape i've tried, and a few different meshes i've loaded in), but it's super slow, and even when i've played around with the different pick modes the speed up is minimal/unnoticeable.

If i stay with aligning bullets to the normals of a mesh, i'll need to find a faster way of determining the closest surface to the bullet is. I know you can get the surface data from a mesh object, but it's working out the fastest way to get the right surface, and then the normal from it...

Cheers
Charlie

Last edited 2011


Warner(Posted 2011) [#11]
And are you enabling/disabling pick modes for objects that don't need to be tested? Because I believe 'picking' loops through every pickable object.
You might benefit from customizing the picking routines. It uses a List to emulate the Blitz3D behaviour, but it doesn't need to. You could also modify it to check on only a single object instead.
If your meshes are built in a certain predefined way, it might be easier to optimize the routine further. Say, if you convert your players xyz coords to lon/lat coords, you could do a 2d rectsoverlap or point-in-triangle test.
First you could divide your mesh into 'areas' (I mean quad shaped groups of triangles), determine in which 'area' the player is and then perform a search to find the closest triangle within that certain group.
I wish I could say something more genius, but nope .. Hopefully someone else has this marvel suggestion.


Paul "Taiphoz"(Posted 2011) [#12]
Stupid question but iv downloaded the latest minib3d and tried to compile the above code but I get an unkown on the function aligntovector2.

am I missing some module or something ?


ima747(Posted 2011) [#13]
aligntovector2 is not part of standard minib3d, the above code is using the variant of minib3d linked in the first post, developed by Warner.


Paul "Taiphoz"(Posted 2011) [#14]
oh.. hmm wondering now which I should use why was there a need to have another version ?


jkrankie(Posted 2011) [#15]
Warner's version uses quaternion rotations, so it doesn't suffer from gimbal lock like the standard Minib3d does. I understand it's slightly slower though, on account of quaternion maths being more CPU intensive.

Cheers
Charlie