- [3D Object] Fix euler angle interpolation.

This commit is contained in:
Tanasart 2024-05-05 09:03:07 +07:00
parent 9eadf0c979
commit 09f9b5ee20
5 changed files with 88 additions and 29 deletions

View file

@ -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)
];
};

View file

@ -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();

View file

@ -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)) {

View file

@ -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);

View file

@ -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;
@ -108,15 +117,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;
var bx = _x;