GMLscripts.com

Discuss and collaborate on GML scripts
Invert

You are not logged in.

#1 2016-10-27 15:04:59

Juju
Member
Registered: 2015-10-01
Posts: 45

slerp_3d

Performs a linear interpolation between two points across the surface of a sphere.

Expand///slerp_3d( vector1, vector2, t )
//
//  Returns the spherical linear interpolation of two 3D vectors.
//
//      vector1    3D vector, 3-element array
//      vector2    3D vector, 3-element array
//      t          paramter, float, 0 <= t <= 1
//
//  Made by @jujuadams.
//
/// GMLscripts.com/license

var _a = argument0;
var _b = argument1;
var _t = argument2;

var _angle = arccos( dot_product_3d_normalised( _a[0], _a[1], _a[2],   _b[0], _b[1], _b[2] ) );

var _s0 = sin( _angle );

var _result;
if ( abs( _s0 ) < 0.001 ) {
    
    _result[0] = 0.5*_a[0] + 0.5*_b[0];
    _result[1] = 0.5*_a[1] + 0.5*_b[1];
    _result[2] = 0.5*_a[2] + 0.5*_b[2];
    
} else {
    
    var _s1 = sin( ( 1 - _t ) * _angle ) / _s0;
    var _s2 = sin( _t * _angle ) / _s0;
    
    _result[0] = _s1*_a[0] + _s2*_b[0];
    _result[1] = _s1*_a[1] + _s2*_b[1];
    _result[2] = _s1*_a[2] + _s2*_b[2];

}

return _result;

Last edited by Juju (2016-10-27 17:21:40)

Offline

#2 2016-10-27 15:26:13

Juju
Member
Registered: 2015-10-01
Posts: 45

Re: slerp_3d

For bonus points, here's how you do it with quaternions

Expand///quaternion_lerp( quaternion1, quaternion2, t )
//
//  Returns the spherical linear interpolation of two quaternions.
//
//      quaternion1    quaternion, 4-element array
//      quaternion2    quaternion, 4-element array
//      t              paramter, float, 0 <= t <= 1
//
//  Made by @jujuadams.
//
/// GMLscripts.com/license

var _a = argument0;
var _b = argument1;
var _t = argument2;

var _angle = abs( arccos( _a[0]*_b[0] + _a[1]*_b[1] + _a[2]*_b[2] + _a[3]*_b[3] ) );

var _s0 = sin( _angle );

var _result;
if ( abs( _s0 ) < 0.001 ) {
    
    _result[0] = 0.5*_a[0] + 0.5*_b[0];
    _result[1] = 0.5*_a[1] + 0.5*_b[1];
    _result[2] = 0.5*_a[2] + 0.5*_b[2];
    _result[3] = 0.5*_a[3] + 0.5*_b[3];
    
} else {
    
    var _s1 = sin( ( 1 - _t ) * _angle ) / _s0;
    var _s2 = sin( _t * _angle ) / _s0;
    
    _result[0] = _s1*_a[0] + _s2*_b[0];
    _result[1] = _s1*_a[1] + _s2*_b[1];
    _result[2] = _s1*_a[2] + _s2*_b[2];
    _result[3] = _s1*_a[3] + _s2*_b[3];
    
}

return _result;

Last edited by Juju (2016-10-27 17:22:01)

Offline

#3 2016-10-28 01:40:59

xot
Administrator
Registered: 2007-08-18
Posts: 1,240

Re: slerp_3d

Very nice, Juju. Thank you.


Abusing forum power since 1986.

Offline

Board footer

Powered by FluxBB