# Free movement around a planet

9 replies to this topic

### #1 TheSnidr

TheSnidr

Heavy metal viking dentist

• GMC Elder
• 3345 posts
• Version:GM:Studio

Posted 18 January 2012 - 04:48 PM

GM8.1

Multiplanetary gravity example (Basically just a slightly extended version of the other one with multiple planets)

This is a small example on how to do planetary gravity, it shows how to globally move around a sphere, as well as how to locally rotate the player, both completely without gimbal lock. It's well commented, but there's a reason to why I posted it here instead of the tutorials page - you need at least some basic knowledge of the following subjects to understand what's going on:
Orientation matrices
Quaternions
Vector math
Trigonometry
3D geometry in general
As such, this isn't a tutorial - I won't be explaining these subjects here, but know that the engine makes use of them, and it'd be wise to learn them if you want to use this for... anything.

Edited by TheSnidr, 04 May 2014 - 06:10 PM.

• 0

### #2 NikaB

NikaB

GMC Member

• New Member
• 111 posts
• Version:GM8

Posted 18 January 2012 - 08:13 PM

Quaternions. Not them again ! Going back to hell, it's better there, than with quaternions
Anyway, seems very interesting and very "educative"
• 0

### #3 mrpeanut188

mrpeanut188

GMC Member

• GMC Member
• 814 posts
• Version:GM8

Posted 19 January 2012 - 04:11 AM

Quaternions. Not them again ! Going back to hell, it's better there, than with quaternions
Anyway, seems very interesting and very "educative"

Somehow my comp doesn't work with GM8. When I used the GM8.1 to GM8 decompiler, I noticed the
```//Get the distance between the center of the planet and the player
l=point_distance_3d(0,0,0,obj_player.x,obj_player.y,obj_player.z)```
And that function is 8.1+. Do you know any other ways I could get this to work?
• 0

### #4 TheSnidr

TheSnidr

Heavy metal viking dentist

• GMC Elder
• 3345 posts
• Version:GM:Studio

Posted 19 January 2012 - 02:30 PM

You can add this script to make it work in 8.0:
```//point_distance_3d(argument0, argument1, argument2, argument3, argument4, argument5)
return sqrt( sqr(argument0 - argument3) + sqr(argument1 - argument4) + sqr(argument2-argument5))```

Edited by TheSnidr, 22 January 2012 - 12:59 AM.

• 0

### #5 hit172

hit172

GMC Member

• New Member
• 189 posts
• Version:GM8

Posted 19 January 2012 - 02:36 PM

Just paste this in place of that line.
`point_distance(0,point_distance(0,0,object_player.x,object_player.y),0,object_player.z);`

Edit: Ninja'd

Edited by hit172, 19 January 2012 - 02:36 PM.

• 0
Duct tape is like the force. It has a light side and a dark side and holds the universe together.
When life gives you lemons, make orange juice... and leave everyone wondering how the **** you did it.

### #6 slayer 64

slayer 64

Slayer of gingers

• GMC Member
• 4301 posts
• Version:GM:Studio

Posted 20 January 2012 - 01:27 AM

there's lots to learn here. looks good. it's a pretty simple example. i like it.
i think this is suppose to be min instead of max. to prevent diagonal motion from being faster than straight motion.
```h=keyboard_check(ord('D'))-keyboard_check(ord('A'))
v=keyboard_check(ord('W'))-keyboard_check(ord('S'))
m=max(point_distance(0,0,h,v),1)```
i think this piece of code should be broken apart so people learning can understand it better. it's doing a lot of stuff in one line
```xspd=xspd*0.85+(obj_camera.xup*v+xx*h)*0.3/m-xup
yspd=yspd*0.85+(obj_camera.yup*v+yy*h)*0.3/m-yup
zspd=zspd*0.85+(obj_camera.zup*v+zz*h)*0.3/m-zup```

• 0

### #7 mrpeanut188

mrpeanut188

GMC Member

• GMC Member
• 814 posts
• Version:GM8

Posted 20 January 2012 - 02:12 AM

I have tried various amounts of code; I can get the example to run with no errors, but the camera rotates very fast.

What I did besides changing the point_3d is that in obj_camera's step, I changed the _x=blah/1,
as it gave a "Division by 0" error. I would recommend making this in GM8, as it is hard to convert.
• 0

### #8 TheSnidr

TheSnidr

Heavy metal viking dentist

• GMC Elder
• 3345 posts
• Version:GM:Studio

Posted 20 January 2012 - 12:01 PM

there's lots to learn here. looks good. it's a pretty simple example. i like it.
i think this is suppose to be min instead of max. to prevent diagonal motion from being faster than straight motion.

```h=keyboard_check(ord('D'))-keyboard_check(ord('A'))
v=keyboard_check(ord('W'))-keyboard_check(ord('S'))
m=max(point_distance(0,0,h,v),1)```
i think this piece of code should be broken apart so people learning can understand it better. it's doing a lot of stuff in one line
```xspd=xspd*0.85+(obj_camera.xup*v+xx*h)*0.3/m-xup
yspd=yspd*0.85+(obj_camera.yup*v+yy*h)*0.3/m-yup
zspd=zspd*0.85+(obj_camera.zup*v+zz*h)*0.3/m-zup```

Thanks!
Your first suggestion is wrong, but your second suggestion explains why - doing a lot in a single line makes it confusing. So I've reuploaded the example and split the equation apart, giving each line its own comment.
Let me explain why it should be max:
```//Normalize the keys pressed
m=max(point_distance(0,0,h,v),1)
h/=m
v/=m```
When both keys are pressed, m=sqrt(2). Dividing the variables by that makes the whole vector have a length of 1. If one key is pressed, m=1, and it won't change anything. When no keys are pressed, m is still 1 to prevent division by 0, yet since no keys are pressed, both variables will be 0, and what is 0/1?

mrpreanut1888:
I just tried adding the script I posted to gm8.0, and it worked flawlessly here... I'll upload that one too then.
http://www.host-a.ne...ingOnSphere.gmk
• 0

### #9 Gamer3D

Gamer3D

Human* me = this;

• GMC Member
• 1819 posts
• Version:GM:Studio

Posted 22 January 2012 - 12:34 AM

The example is really simple, but this comment you made got me thinking:

You can add this script to make it work in 8.0:

```/*
point_distance_3d(argument0,argument1,argument2,argument3,argument4,argument5)
*/
return sqrt(sqr(argument0-argument3)+sqr(argument1-argument4)+sqr(argument2-argument5))```

It got me thinking about what scripts could be made to maximise GM8.0's compatibility with GM8.1. So here are some functions which replicate GM8.1 functionality.

```///point_distance_3d(x1, y1, z1, x2, y2, z2)
return sqrt(sqr(argument0 - argument3) + sqr(argument1 - argument4) + sqr(argument2 - argument5));```
```///dot_product_3d(x1, y1, z1, x2, y2, z2)
return (argument0 * argument3 + argument1 * argument4 + argument2 * argument5) / sqrt((argument0 * argument0 + argument1 * argument1 + argument2 * argument2) * (argument3 * argument3 + argument4 * argument4 + argument5 * argument5));```
```///dot_product(x1, y1, x2, y2)
return (argument0 * argument3 + argument1 * argument4) / sqrt((argument0 * argument0 + argument1 * argument1) * (argument3 * argument3 + argument4 * argument4));```
```///draw_self()
draw_sprite_ext(sprite_index, image_index, x, y, image_xscale, image_yscale, image_angle, image_blend,  image_alpha);```
```///clamp(val, min, max)
return median(argument0, argument1, argument2);```
```///lerp(val1, val2, amount)
return argument0 + (argument1 - argument0) * argument2;```
```///string_byte_length(str)
return string_length(argument0);```
```///string_byte_at(str, index)
return string_char_at(argument0, argument1);```
```///ansi_char(index)
return chr(index);```

And to remove errors (but not replicate its function):
```///d3d_light_define_ambient(color)
return argument0;```
```///d3d_set_zwriteenable(enable)
return argument0;```
```///get_function_address()
show_error("get_function_address called. No good workaround for this in GM8.0.", true);
return 0;```
```///display_reset(aa)
return argument0;```
```//message_text_charset(type,charset)
return argument0 * argument1;```

• 1
Fast Priority Queues - Game Maker's priority queues are O(n). Mine do everything that Game Maker's do, but in O(log n) time.
Dual-Quaternion Skinning - Modifying vertexes in GM is slow. This simple vertex shader does the job both quickly and well.

### #10 abinashn1

abinashn1

GMC Member

• Banned Users
• 21 posts
• Version:GM:Studio

Posted 04 May 2014 - 06:01 PM

Good work on camera movement!!