
вот наша функция для расчета смещения - работает вроде бы как надо, по крайней мере на вид (вызывается 3 раза для x, y и z соответственно)
Код:
static float ce_figfile_value_fig8(const float* params, //массив fig8 - 8 наборов смещений для расчето нужного по комплекции
size_t stride, //смещение - 3(x,y,z)
const ce_complection* complection) // собственно структура комплекции
{
float temp1 = params[0 * stride] +
(params[1 * stride] - params[0 * stride]) * complection->strength;
float temp2 = params[2 * stride] +
(params[3 * stride] - params[2 * stride]) * complection->strength;
float value = temp1 + (temp2 - temp1) * complection->dexterity;
temp1 = params[4 * stride] +
(params[5 * stride] - params[4 * stride]) * complection->strength;
temp2 = params[6 * stride] +
(params[7 * stride] - params[6 * stride]) * complection->strength;
temp1 += (temp2 - temp1) * complection->dexterity;
return value += (temp1 - value) * complection->height;
}
основная структура здесь будет выглядеть так
Код:
typedef struct ce_figbone ce_figbone;
struct ce_figbone {
ce_vec3 position; //смещение - сейчас считается из комплекции, надо из anm как поворот
ce_quat orientation; //поворот - считается через линейную интерполяцию двух ключевых кадров анимации (из anm)
ce_vec3 bone_position; //текущие смещения и поворот - с учетом родительской кости
ce_quat bone_orientation;
ce_anmstate* anmstate; //текущее состояние анимации - где именно между какими кадрами находимся и прочее
ce_figbone* parent; //родительская кость и потомки
ce_vector* childs;
};
так выглядит функция для расчета анимации сейчас - смещение из анимации не учитывается, подъем модели из земли получается через хардкод

Код:
static void ce_figbone_update_transform(ce_figbone* figbone,
ce_renderitem* renderitem)
{
// TODO: translations from anm file ???
// update binding pose
if (NULL == figbone->anmstate->anmfile) {
figbone->orientation = CE_QUAT_IDENTITY;
} else { // линейная интерполяция поворота кости между двумя ключевыми кадрами анимации
ce_quat q1, q2;
ce_quat_slerp(&figbone->orientation, figbone->anmstate->coef,
ce_quat_init_array(&q1, figbone->anmstate->anmfile->rotations +
(int)figbone->anmstate->prev_frame * 4),
ce_quat_init_array(&q2, figbone->anmstate->anmfile->rotations +
(int)figbone->anmstate->next_frame * 4));
}
// update bone pose
if (NULL == figbone->parent) { // для базовой (корневой?) кости - располагается обычно гдето в районе таза, поэтому без ее смещения модели по пояс в земле
// bone pose == binding pose
figbone->bone_position = figbone->position;
figbone->bone_orientation = figbone->orientation;
} else {
//поворачиваем смещение расчитанное в по комплекции - куда повернута родительская кость
ce_vec3_rot(&figbone->bone_position,
&figbone->position,
&figbone->parent->bone_orientation);
//добавляем к нему смещение родительской кости
ce_vec3_add(&figbone->bone_position,
&figbone->bone_position,
&figbone->parent->bone_position);
//тут считаем поворот текущей кости с учетом поворота родительской кости
ce_quat_mul(&figbone->bone_orientation,
&figbone->orientation,
&figbone->parent->bone_orientation);
}
//ну и все это засовываем как положение и поворот рендер итема
renderitem->position = figbone->bone_position;
renderitem->orientation = figbone->bone_orientation;
}
то, над чем я работаю
Код:
static void ce_figbone_update_transform(ce_figbone* figbone,
ce_renderitem* renderitem,
ce_complection* complection) // закинул сюда комплекцию на всякий случай
{
// update binding pose
if (NULL == figbone->anmstate->anmfile) {
figbone->orientation = CE_QUAT_IDENTITY;
figbone->position = CE_VEC3_ZERO;
} else { // линейная интерполяция поворота кости между двумя ключевыми кадрами анимации
ce_quat q1, q2;
ce_quat_slerp(&figbone->orientation, figbone->anmstate->coef,
ce_quat_init_array(&q1, figbone->anmstate->anmfile->rotations +
(int)figbone->anmstate->prev_frame * 4),
ce_quat_init_array(&q2, figbone->anmstate->anmfile->rotations +
(int)figbone->anmstate->next_frame * 4));
//здесь собственно интерполяция смещения кости по аналогии с поворотом
ce_vec3 v1, v2;
ce_vec3_lerp(&figbone->position, figbone->anmstate->coef,
ce_vec3_init_array(&v1,figbone->anmstate->anmfile->translations +
(int)figbone->anmstate->prev_frame * 3),
ce_vec3_init_array(&v2,figbone->anmstate->anmfile->translations +
(int)figbone->anmstate->next_frame * 3));
}
// update bone pose
if (NULL == figbone->parent) { // для базовой (корневой?) кости - располагается обычно гдето в районе таза, поэтому без ее смещения модели по пояс в земле
// bone pose == binding pose
figbone->bone_position = figbone->position;
figbone->bone_orientation = figbone->orientation;
} else {
//поворот смещения, куда повернута родительская кость - не нужен. смещения из anm расчитаны уже с учетом этого поворота
//добавляем к нему смещение родительской кости - дальше то же что и раньше
ce_vec3_add(&figbone->bone_position,
&figbone->position,
&figbone->parent->bone_position);
//тут считаем поворот текущей кости с учетом поворота родительской кости
ce_quat_mul(&figbone->bone_orientation,
&figbone->orientation,
&figbone->parent->bone_orientation);
}
//ну и все это засовываем как положение и поворот рендер итема
renderitem->position = figbone->bone_position;
renderitem->orientation = figbone->bone_orientation;
}
Ну собственно так это выглядит. тоесть берем просто выбираем смещения из ключевых кадров, интерполируем на текущее состояние анимации и получаем почти то, что нужно - включая смещение базовой кости. но - смещения должны быть подвергнуты корректировке в зависимости от комплекции юнита, как мне кажется именно поэтому у лягушки части находятся отдельно.
Так вот если смещения по комплекции у нас считаются - мы используем все 8 наборов fig8, а если нтерполируем смещение из anm, то совершенно непонятно как его пересчитать по комплекции - набор смещений у нас тут вроде как один.
PS v1s0r - если с описанием/комментами гдето ошибся - поправь
