# Free movement around a planet

9 replies to this topic

### #1 TheSnidr

TheSnidr

That guy

• Global Moderators
• 2439 posts
• Version:GM:Studio

Posted 18 January 2012 - 04:34 PM

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, 24 January 2012 - 08:52 PM.

• 0

### #2 NikaB

NikaB

GMC Member

• New Member
• 111 posts
• Version:GM8

Posted 18 January 2012 - 07:59 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
• 811 posts
• Version:GM8

Posted 19 January 2012 - 03:57 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

That guy

• Global Moderators
• 2439 posts
• Version:GM:Studio

Posted 19 January 2012 - 02:16 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:45 AM.

• 0

### #5 hit172

hit172

GMC Member

• New Member
• 189 posts
• Version:GM8

Posted 19 January 2012 - 02:22 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:22 PM.

• 0

### #6 slayer 64

slayer 64

GMC Member

• GMC Member
• 3278 posts
• Version:GM8.1

Posted 20 January 2012 - 01:13 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
• 811 posts
• Version:GM8

Posted 20 January 2012 - 01:58 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

That guy

• Global Moderators
• 2439 posts
• Version:GM:Studio

Posted 20 January 2012 - 11:47 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```

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.net/u/playway/MovingOnSphere.gmk
• 0

### #9 Gamer3D

Gamer3D

Human* me = this;

• GMC Member
• 1590 posts
• Version:GM8.1

Posted 22 January 2012 - 12:20 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

### #10 Robert3DG+

Robert3DG+

VR Games

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

Posted 23 January 2012 - 11:12 PM

Very well programmed. Nice work.
• 0

#### 0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users