From 09f9b5ee204caffff3a888224d3f360f84c2d7bc Mon Sep 17 00:00:00 2001 From: Tanasart Date: Sun, 5 May 2024 09:03:07 +0700 Subject: [PATCH] - [3D Object] Fix euler angle interpolation. --- scripts/BBMOD_Quaternion/BBMOD_Quaternion.gml | 73 +++++++++++++++++++ scripts/globals/globals.gml | 6 +- scripts/node_keyframe/node_keyframe.gml | 18 +---- .../node_strand_create/node_strand_create.gml | 2 +- scripts/quarternionBox/quarternionBox.gml | 18 ++--- 5 files changed, 88 insertions(+), 29 deletions(-) diff --git a/scripts/BBMOD_Quaternion/BBMOD_Quaternion.gml b/scripts/BBMOD_Quaternion/BBMOD_Quaternion.gml index 5282c7ba4..f02f8b414 100644 --- a/scripts/BBMOD_Quaternion/BBMOD_Quaternion.gml +++ b/scripts/BBMOD_Quaternion/BBMOD_Quaternion.gml @@ -667,3 +667,76 @@ function BBMOD_Quaternion(_x=0.0, _y=0.0, _z=0.0, _w=1.0) constructor return _dest; }; } + + +function quarternionArraySlerp(_q0, _q1, _s) { + INLINE + + var _q10 = _q0[0]; + var _q11 = _q0[1]; + var _q12 = _q0[2]; + var _q13 = _q0[3]; + + var _q20 = _q1[0]; + var _q21 = _q1[1]; + var _q22 = _q1[2]; + var _q23 = _q1[3]; + + var _norm; + + _norm = 1.0 / sqrt(_q10 * _q10 + + _q11 * _q11 + + _q12 * _q12 + + _q13 * _q13); + + _q10 *= _norm; + _q11 *= _norm; + _q12 *= _norm; + _q13 *= _norm; + + _norm = sqrt(_q20 * _q20 + + _q21 * _q21 + + _q22 * _q22 + + _q23 * _q23); + + _q20 *= _norm; + _q21 *= _norm; + _q22 *= _norm; + _q23 *= _norm; + + var _dot = _q10 * _q20 + + _q11 * _q21 + + _q12 * _q22 + + _q13 * _q23; + + if (_dot < 0.0) { + _dot = -_dot; + _q20 *= -1.0; + _q21 *= -1.0; + _q22 *= -1.0; + _q23 *= -1.0; + } + + if (_dot > 0.9995) + return [ + lerp(_q10, _q20, _s), + lerp(_q11, _q21, _s), + lerp(_q12, _q22, _s), + lerp(_q13, _q23, _s) + ]; + + var _theta0 = arccos(_dot); + var _theta = _theta0 * _s; + var _sinTheta = sin(_theta); + var _sinTheta0 = sin(_theta0); + + var _s2 = _sinTheta / _sinTheta0; + var _s1 = cos(_theta) - (_dot * _s2); + + return [ + (_q10 * _s1) + (_q20 * _s2), + (_q11 * _s1) + (_q21 * _s2), + (_q12 * _s1) + (_q22 * _s2), + (_q13 * _s1) + (_q23 * _s2) + ]; +}; \ No newline at end of file diff --git a/scripts/globals/globals.gml b/scripts/globals/globals.gml index c727384d1..0a20ed383 100644 --- a/scripts/globals/globals.gml +++ b/scripts/globals/globals.gml @@ -36,10 +36,10 @@ globalvar VERSION, SAVE_VERSION, VERSION_STRING, BUILD_NUMBER, LATEST_VERSION; LATEST_VERSION = 11600; - VERSION = 11700; + VERSION = 11701; SAVE_VERSION = 11690; - VERSION_STRING = "1.17"; - BUILD_NUMBER = 11706; + VERSION_STRING = "1.17.0.1"; + BUILD_NUMBER = 11707; globalvar HOTKEYS, HOTKEY_CONTEXT; HOTKEYS = ds_map_create(); diff --git a/scripts/node_keyframe/node_keyframe.gml b/scripts/node_keyframe/node_keyframe.gml index 846c483f1..f8296e386 100644 --- a/scripts/node_keyframe/node_keyframe.gml +++ b/scripts/node_keyframe/node_keyframe.gml @@ -205,22 +205,8 @@ function valueAnimator(_val, _prop, _sep_axis = false) constructor { return _f.lerpTo(_t, _lrp); } - if(prop.display_type == VALUE_DISPLAY.d3quarternion) { - if(prop.display_data.angle_display == 0) { - var _qf = new BBMOD_Quaternion(_f[0], _f[1], _f[2], _f[3]); - var _qt = new BBMOD_Quaternion(_t[0], _t[1], _t[2], _t[3]); - var _ql = _qf.Slerp(_qt, _lrp); - - return _ql.ToArray(); - } else { - return [ - lerp(_f[0], _t[0], _lrp), - lerp(_f[1], _t[1], _lrp), - lerp(_f[2], _t[2], _lrp), - 0, - ]; - } - } + if(prop.display_type == VALUE_DISPLAY.d3quarternion) + return quarternionArraySlerp(_f, _t, _lrp); if(prop.type == VALUE_TYPE.color) { if(is_array(_f) && is_array(_t)) { diff --git a/scripts/node_strand_create/node_strand_create.gml b/scripts/node_strand_create/node_strand_create.gml index b8d5e1735..eb73af6d6 100644 --- a/scripts/node_strand_create/node_strand_create.gml +++ b/scripts/node_strand_create/node_strand_create.gml @@ -15,7 +15,7 @@ function Node_Strand_Create(_x, _y, _group = noone) : Node(_x, _y, _group) const inputs[| 2] = nodeValue("Length", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, [ 4, 4 ]) .setDisplay(VALUE_DISPLAY.vector); - inputs[| 3] = nodeValue("Segment", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, 4); + inputs[| 3] = nodeValue("Segment", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 4); inputs[| 4] = nodeValue("Elasticity", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, 0.05, "Length preservation, the higher the value the easier it is to stretch each segment.") .setDisplay(VALUE_DISPLAY.slider); diff --git a/scripts/quarternionBox/quarternionBox.gml b/scripts/quarternionBox/quarternionBox.gml index ca59a1b1f..68abbf409 100644 --- a/scripts/quarternionBox/quarternionBox.gml +++ b/scripts/quarternionBox/quarternionBox.gml @@ -94,6 +94,15 @@ function quarternionBox(_onModify) : widget() constructor { var _bs = min(_h, ui(32)); var _disp = struct_try_get(_display_data, "angle_display"); + if(_display_data.angle_display == QUARTERNION_DISPLAY.quarterion || (!tb[0].sliding && !tb[1].sliding && !tb[2].sliding)) { + current_value[0] = _data[0]; + current_value[1] = _data[1]; + current_value[2] = _data[2]; + + if(_display_data.angle_display == QUARTERNION_DISPLAY.quarterion) + current_value[3] = _data[3]; + } + if((_w - _bs) / 2 > ui(64)) { var bx = _x + _w - _bs; var by = _y + _h / 2 - _bs / 2; @@ -107,15 +116,6 @@ function quarternionBox(_onModify) : widget() constructor { } current_unit = _display_data.angle_display; - - if(current_unit == QUARTERNION_DISPLAY.quarterion || (!tb[0].sliding && !tb[1].sliding && !tb[2].sliding)) { - current_value[0] = _data[0]; - current_value[1] = _data[1]; - current_value[2] = _data[2]; - - if(current_unit == QUARTERNION_DISPLAY.quarterion) - current_value[3] = _data[3]; - } size = _disp? 3 : 4; var ww = _w / size;