This repository has been archived on 2023-10-09. You can view files and clone it, but cannot push or open issues or pull requests.
Files
blender-archive/source/blender/blenkernel/intern/armature.c

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

2951 lines
92 KiB
C
Raw Normal View History

/*
2002-10-12 11:37:38 +00:00
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
2002-10-12 11:37:38 +00:00
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
2010-02-12 13:34:04 +00:00
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
2002-10-12 11:37:38 +00:00
*
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*/
/** \file
* \ingroup bke
2011-02-27 20:40:57 +00:00
*/
#include <ctype.h>
#include <float.h>
2002-10-12 11:37:38 +00:00
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
2002-10-12 11:37:38 +00:00
#include "MEM_guardedalloc.h"
#include "BLI_alloca.h"
#include "BLI_ghash.h"
#include "BLI_listbase.h"
#include "BLI_math.h"
#include "BLI_string.h"
#include "BLI_utildefines.h"
#include "BLT_translation.h"
2002-10-12 11:37:38 +00:00
#include "DNA_defaults.h"
2002-10-12 11:37:38 +00:00
#include "DNA_armature_types.h"
#include "DNA_constraint_types.h"
#include "DNA_listBase.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
2002-10-12 11:37:38 +00:00
#include "BKE_action.h"
#include "BKE_anim_data.h"
#include "BKE_anim_visualization.h"
#include "BKE_armature.h"
#include "BKE_constraint.h"
#include "BKE_curve.h"
#include "BKE_idprop.h"
#include "BKE_idtype.h"
#include "BKE_lib_id.h"
#include "BKE_lib_query.h"
#include "BKE_main.h"
2002-10-12 11:37:38 +00:00
#include "BKE_object.h"
#include "BKE_scene.h"
#include "DEG_depsgraph_build.h"
Fix T76689: Armature layers not indicating the existence of bones From what I can see, there are two issues at play in {T76689} and its merged-in report {T76590}: - In Blender ≤ 2.79 the bone layer dots were updated in the draw code. This ensured the info was up to date before drawing. This is no longer possible, as the drawing code uses evaluated objects, and those should not be written to. This has been addressed in rB709f126e8143 by calling the update function explicitly in various places in the code. The problem is that this wasn't added to all necessary spots. - When in edit mode, changes are made to the edit bones but not to the 'actual' bones (this is synced when exiting edit mode). This causes undo to mess up the layer indicators. I think both issues can be addressed by having the dependency graph update the used layer info as part of the armature evaluation. This will make the undo system work properly, and allows the removal of some `BKE_armature_refresh_layer_used()` from various places. There is still the issue that there are two functions (`BKE_armature_refresh_layer_used()` and `ED_armature_edit_refresh_layer_used()`) that are both responsible for updating `bArmature::layer_used`. This is a trickier thing to solve, though, as the definition of the `EditBone` struct resides in the armature editor module. This means that blenkernel can't iterate over edit bones, but on the other hand the dependency graph shouldn't call any editor functions either. This is why I left the `ED_armature_edit_refresh_layer_used()` calls untouched. The downside of recalculating `layer_used` from the dependency graph (at least in the way that I did it now) is that it is called every time a user moves a bone in pose mode. This frequency of updates is not necessary. Differential Revision: https://developer.blender.org/D7709
2020-05-12 18:22:14 +02:00
#include "DEG_depsgraph_query.h"
#include "BIK_api.h"
2002-10-12 11:37:38 +00:00
#include "BLO_read_write.h"
#include "CLG_log.h"
static CLG_LogRef LOG = {"bke.armature"};
/* -------------------------------------------------------------------- */
/** \name Prototypes
* \{ */
static void copy_bonechildren(Bone *bone_dst,
const Bone *bone_src,
const Bone *bone_src_act,
Bone **r_bone_dst_act,
const int flag);
static void copy_bonechildren_custom_handles(Bone *bone_dst, bArmature *arm_dst);
/** \} */
/* -------------------------------------------------------------------- */
/** \name Armature Data-block
* \{ */
static void armature_init_data(ID *id)
{
bArmature *armature = (bArmature *)id;
BLI_assert(MEMCMP_STRUCT_AFTER_IS_ZERO(armature, id));
MEMCPY_STRUCT_AFTER(armature, DNA_struct_default_get(bArmature), id);
}
/**
* Only copy internal data of Armature ID from source
* to already allocated/initialized destination.
* You probably never want to use that directly,
* use #BKE_id_copy or #BKE_id_copy_ex for typical needs.
*
* WARNING! This function will not handle ID user count!
*
* \param flag: Copying options (see BKE_lib_id.h's LIB_ID_COPY_... flags for more).
*/
static void armature_copy_data(Main *UNUSED(bmain), ID *id_dst, const ID *id_src, const int flag)
{
bArmature *armature_dst = (bArmature *)id_dst;
const bArmature *armature_src = (const bArmature *)id_src;
Bone *bone_src, *bone_dst;
Bone *bone_dst_act = NULL;
/* We never handle usercount here for own data. */
const int flag_subdata = flag | LIB_ID_CREATE_NO_USER_REFCOUNT;
armature_dst->bonehash = NULL;
BLI_duplicatelist(&armature_dst->bonebase, &armature_src->bonebase);
/* Duplicate the childrens' lists */
bone_dst = armature_dst->bonebase.first;
for (bone_src = armature_src->bonebase.first; bone_src; bone_src = bone_src->next) {
bone_dst->parent = NULL;
copy_bonechildren(bone_dst, bone_src, armature_src->act_bone, &bone_dst_act, flag_subdata);
bone_dst = bone_dst->next;
}
armature_dst->act_bone = bone_dst_act;
BKE_armature_bone_hash_make(armature_dst);
/* Fix custom handle references. */
for (bone_dst = armature_dst->bonebase.first; bone_dst; bone_dst = bone_dst->next) {
copy_bonechildren_custom_handles(bone_dst, armature_dst);
}
armature_dst->edbo = NULL;
armature_dst->act_edbone = NULL;
}
/** Free (or release) any data used by this armature (does not free the armature itself). */
static void armature_free_data(struct ID *id)
{
bArmature *armature = (bArmature *)id;
BKE_armature_bone_hash_free(armature);
BKE_armature_bonelist_free(&armature->bonebase, false);
/* free editmode data */
if (armature->edbo) {
BKE_armature_editbonelist_free(armature->edbo, false);
MEM_freeN(armature->edbo);
armature->edbo = NULL;
}
}
static void armature_foreach_id_bone(Bone *bone, LibraryForeachIDData *data)
{
IDP_foreach_property(
bone->prop, IDP_TYPE_FILTER_ID, BKE_lib_query_idpropertiesForeachIDLink_callback, data);
LISTBASE_FOREACH (Bone *, curbone, &bone->childbase) {
armature_foreach_id_bone(curbone, data);
}
}
static void armature_foreach_id_editbone(EditBone *edit_bone, LibraryForeachIDData *data)
{
IDP_foreach_property(
edit_bone->prop, IDP_TYPE_FILTER_ID, BKE_lib_query_idpropertiesForeachIDLink_callback, data);
}
static void armature_foreach_id(ID *id, LibraryForeachIDData *data)
{
bArmature *arm = (bArmature *)id;
LISTBASE_FOREACH (Bone *, bone, &arm->bonebase) {
armature_foreach_id_bone(bone, data);
}
if (arm->edbo != NULL) {
LISTBASE_FOREACH (EditBone *, edit_bone, arm->edbo) {
armature_foreach_id_editbone(edit_bone, data);
}
}
}
static void write_bone(BlendWriter *writer, Bone *bone)
{
/* PATCH for upward compatibility after 2.37+ armature recode */
bone->size[0] = bone->size[1] = bone->size[2] = 1.0f;
/* Write this bone */
BLO_write_struct(writer, Bone, bone);
/* Write ID Properties -- and copy this comment EXACTLY for easy finding
* of library blocks that implement this.*/
if (bone->prop) {
IDP_BlendWrite(writer, bone->prop);
}
/* Write Children */
LISTBASE_FOREACH (Bone *, cbone, &bone->childbase) {
write_bone(writer, cbone);
}
}
static void armature_blend_write(BlendWriter *writer, ID *id, const void *id_address)
{
bArmature *arm = (bArmature *)id;
if (arm->id.us > 0 || BLO_write_is_undo(writer)) {
/* Clean up, important in undo case to reduce false detection of changed datablocks. */
arm->bonehash = NULL;
arm->edbo = NULL;
/* Must always be cleared (armatures don't have their own edit-data). */
arm->needs_flush_to_id = 0;
arm->act_edbone = NULL;
BLO_write_id_struct(writer, bArmature, id_address, &arm->id);
BKE_id_blend_write(writer, &arm->id);
if (arm->adt) {
BKE_animdata_blend_write(writer, arm->adt);
}
/* Direct data */
LISTBASE_FOREACH (Bone *, bone, &arm->bonebase) {
write_bone(writer, bone);
}
}
}
static void direct_link_bones(BlendDataReader *reader, Bone *bone)
{
BLO_read_data_address(reader, &bone->parent);
BLO_read_data_address(reader, &bone->prop);
IDP_BlendDataRead(reader, &bone->prop);
BLO_read_data_address(reader, &bone->bbone_next);
BLO_read_data_address(reader, &bone->bbone_prev);
bone->flag &= ~(BONE_DRAW_ACTIVE | BONE_DRAW_LOCKED_WEIGHT);
BLO_read_list(reader, &bone->childbase);
LISTBASE_FOREACH (Bone *, child, &bone->childbase) {
direct_link_bones(reader, child);
}
}
static void armature_blend_read_data(BlendDataReader *reader, ID *id)
{
bArmature *arm = (bArmature *)id;
BLO_read_list(reader, &arm->bonebase);
arm->bonehash = NULL;
arm->edbo = NULL;
/* Must always be cleared (armatures don't have their own edit-data). */
arm->needs_flush_to_id = 0;
BLO_read_data_address(reader, &arm->adt);
BKE_animdata_blend_read_data(reader, arm->adt);
LISTBASE_FOREACH (Bone *, bone, &arm->bonebase) {
direct_link_bones(reader, bone);
}
BLO_read_data_address(reader, &arm->act_bone);
arm->act_edbone = NULL;
BKE_armature_bone_hash_make(arm);
}
static void lib_link_bones(BlendLibReader *reader, Bone *bone)
{
IDP_BlendReadLib(reader, bone->prop);
LISTBASE_FOREACH (Bone *, curbone, &bone->childbase) {
lib_link_bones(reader, curbone);
}
}
static void armature_blend_read_lib(BlendLibReader *reader, ID *id)
{
bArmature *arm = (bArmature *)id;
LISTBASE_FOREACH (Bone *, curbone, &arm->bonebase) {
lib_link_bones(reader, curbone);
}
}
static void expand_bones(BlendExpander *expander, Bone *bone)
{
IDP_BlendReadExpand(expander, bone->prop);
LISTBASE_FOREACH (Bone *, curBone, &bone->childbase) {
expand_bones(expander, curBone);
}
}
static void armature_blend_read_expand(BlendExpander *expander, ID *id)
{
bArmature *arm = (bArmature *)id;
LISTBASE_FOREACH (Bone *, curBone, &arm->bonebase) {
expand_bones(expander, curBone);
}
}
IDTypeInfo IDType_ID_AR = {
.id_code = ID_AR,
.id_filter = FILTER_ID_AR,
.main_listbase_index = INDEX_ID_AR,
.struct_size = sizeof(bArmature),
.name = "Armature",
.name_plural = "armatures",
.translation_context = BLT_I18NCONTEXT_ID_ARMATURE,
.flags = 0,
.init_data = armature_init_data,
.copy_data = armature_copy_data,
.free_data = armature_free_data,
.make_local = NULL,
.foreach_id = armature_foreach_id,
.foreach_cache = NULL,
.blend_write = armature_blend_write,
.blend_read_data = armature_blend_read_data,
.blend_read_lib = armature_blend_read_lib,
.blend_read_expand = armature_blend_read_expand,
.blend_read_undo_preserve = NULL,
};
/** \} */
/* -------------------------------------------------------------------- */
/** \name Generic Data-Level Functions
* \{ */
2002-10-12 11:37:38 +00:00
bArmature *BKE_armature_add(Main *bmain, const char *name)
2002-10-12 11:37:38 +00:00
{
Result of 2 weeks of quiet coding work in Greece :) Aim was to get a total refresh of the animation system. This is needed because; - we need to upgrade it with 21st century features - current code is spaghetti/hack combo, and hides good design - it should become lag-free with using dependency graphs A full log, with complete code API/structure/design explanation will follow, that's a load of work... so here below the list with hot changes; - The entire object update system (matrices, geometry) is now centralized. Calls to where_is_object and makeDispList are forbidden, instead we tag objects 'changed' and let the depgraph code sort it out - Removed all old "Ika" code - Depgraph is aware of all relationships, including meta balls, constraints, bevelcurve, and so on. - Made depgraph aware of relation types and layers, to do smart flushing of 'changed' events. Nothing gets calculated too often! - Transform uses depgraph to detect changes - On frame-advance, depgraph flushes animated changes Armatures; Almost all armature related code has been fully built from scratch. It now reveils the original design much better, with a very clean implementation, lag free without even calculating each Bone more than once. Result is quite a speedup yes! Important to note is; 1) Armature is data containing the 'rest position' 2) Pose is the changes of rest position, and always on object level. That way more Objects can use same Pose. Also constraints are in Pose 3) Actions only contain the Ipos to change values in Poses. - Bones draw unrotated now - Drawing bones speedup enormously (10-20 times) - Bone selecting in EditMode, selection state is saved for PoseMode, and vice-versa - Undo in editmode - Bone renaming does vertexgroups, constraints, posechannels, actions, for all users of Armature in entire file - Added Bone renaming in NKey panel - Nkey PoseMode shows eulers now - EditMode and PoseMode now have 'active' bone too (last clicked) - Parenting in EditMode' CTRL+P, ALT+P, with nice options! - Pose is added in Outliner now, with showing that constraints are in the Pose, not Armature - Disconnected IK solving from constraints. It's a separate phase now, on top of the full Pose calculations - Pose itself has a dependency graph too, so evaluation order is lag free. TODO NOW; - Rotating in Posemode has incorrect inverse transform (Martin will fix) - Python Bone/Armature/Pose API disabled... needs full recode too (wait for my doc!) - Game engine will need upgrade too - Depgraph code needs revision, cleanup, can be much faster! (But, compliments for Jean-Luc, it works like a charm!) - IK changed, it now doesnt use previous position to advance to next position anymore. That system looks nice (no flips) but is not well suited for NLA and background render. TODO LATER; We now can do loadsa new nifty features as well; like: - Kill PoseMode (can be option for armatures itself) - Make B-Bones (Bezier, Bspline, like for spines) - Move all silly button level edit to 3d window (like CTRL+I = add IK) - Much better & informative drawing - Fix action/nla editors - Put all ipos in Actions (object, mesh key, lamp color) - Add hooks - Null bones - Much more advanced constraints... Bugfixes; - OGL render (view3d header) had wrong first frame on anim render - Ipo 'recording' mode had wrong playback speed - Vertex-key mode now sticks to show 'active key', until frame change -Ton-
2005-07-03 17:35:38 +00:00
bArmature *arm;
arm = BKE_id_new(bmain, ID_AR, name);
Result of 2 weeks of quiet coding work in Greece :) Aim was to get a total refresh of the animation system. This is needed because; - we need to upgrade it with 21st century features - current code is spaghetti/hack combo, and hides good design - it should become lag-free with using dependency graphs A full log, with complete code API/structure/design explanation will follow, that's a load of work... so here below the list with hot changes; - The entire object update system (matrices, geometry) is now centralized. Calls to where_is_object and makeDispList are forbidden, instead we tag objects 'changed' and let the depgraph code sort it out - Removed all old "Ika" code - Depgraph is aware of all relationships, including meta balls, constraints, bevelcurve, and so on. - Made depgraph aware of relation types and layers, to do smart flushing of 'changed' events. Nothing gets calculated too often! - Transform uses depgraph to detect changes - On frame-advance, depgraph flushes animated changes Armatures; Almost all armature related code has been fully built from scratch. It now reveils the original design much better, with a very clean implementation, lag free without even calculating each Bone more than once. Result is quite a speedup yes! Important to note is; 1) Armature is data containing the 'rest position' 2) Pose is the changes of rest position, and always on object level. That way more Objects can use same Pose. Also constraints are in Pose 3) Actions only contain the Ipos to change values in Poses. - Bones draw unrotated now - Drawing bones speedup enormously (10-20 times) - Bone selecting in EditMode, selection state is saved for PoseMode, and vice-versa - Undo in editmode - Bone renaming does vertexgroups, constraints, posechannels, actions, for all users of Armature in entire file - Added Bone renaming in NKey panel - Nkey PoseMode shows eulers now - EditMode and PoseMode now have 'active' bone too (last clicked) - Parenting in EditMode' CTRL+P, ALT+P, with nice options! - Pose is added in Outliner now, with showing that constraints are in the Pose, not Armature - Disconnected IK solving from constraints. It's a separate phase now, on top of the full Pose calculations - Pose itself has a dependency graph too, so evaluation order is lag free. TODO NOW; - Rotating in Posemode has incorrect inverse transform (Martin will fix) - Python Bone/Armature/Pose API disabled... needs full recode too (wait for my doc!) - Game engine will need upgrade too - Depgraph code needs revision, cleanup, can be much faster! (But, compliments for Jean-Luc, it works like a charm!) - IK changed, it now doesnt use previous position to advance to next position anymore. That system looks nice (no flips) but is not well suited for NLA and background render. TODO LATER; We now can do loadsa new nifty features as well; like: - Kill PoseMode (can be option for armatures itself) - Make B-Bones (Bezier, Bspline, like for spines) - Move all silly button level edit to 3d window (like CTRL+I = add IK) - Much better & informative drawing - Fix action/nla editors - Put all ipos in Actions (object, mesh key, lamp color) - Add hooks - Null bones - Much more advanced constraints... Bugfixes; - OGL render (view3d header) had wrong first frame on anim render - Ipo 'recording' mode had wrong playback speed - Vertex-key mode now sticks to show 'active key', until frame change -Ton-
2005-07-03 17:35:38 +00:00
return arm;
}
bArmature *BKE_armature_from_object(Object *ob)
{
if (ob->type == OB_ARMATURE) {
return (bArmature *)ob->data;
}
return NULL;
}
Result of 2 weeks of quiet coding work in Greece :) Aim was to get a total refresh of the animation system. This is needed because; - we need to upgrade it with 21st century features - current code is spaghetti/hack combo, and hides good design - it should become lag-free with using dependency graphs A full log, with complete code API/structure/design explanation will follow, that's a load of work... so here below the list with hot changes; - The entire object update system (matrices, geometry) is now centralized. Calls to where_is_object and makeDispList are forbidden, instead we tag objects 'changed' and let the depgraph code sort it out - Removed all old "Ika" code - Depgraph is aware of all relationships, including meta balls, constraints, bevelcurve, and so on. - Made depgraph aware of relation types and layers, to do smart flushing of 'changed' events. Nothing gets calculated too often! - Transform uses depgraph to detect changes - On frame-advance, depgraph flushes animated changes Armatures; Almost all armature related code has been fully built from scratch. It now reveils the original design much better, with a very clean implementation, lag free without even calculating each Bone more than once. Result is quite a speedup yes! Important to note is; 1) Armature is data containing the 'rest position' 2) Pose is the changes of rest position, and always on object level. That way more Objects can use same Pose. Also constraints are in Pose 3) Actions only contain the Ipos to change values in Poses. - Bones draw unrotated now - Drawing bones speedup enormously (10-20 times) - Bone selecting in EditMode, selection state is saved for PoseMode, and vice-versa - Undo in editmode - Bone renaming does vertexgroups, constraints, posechannels, actions, for all users of Armature in entire file - Added Bone renaming in NKey panel - Nkey PoseMode shows eulers now - EditMode and PoseMode now have 'active' bone too (last clicked) - Parenting in EditMode' CTRL+P, ALT+P, with nice options! - Pose is added in Outliner now, with showing that constraints are in the Pose, not Armature - Disconnected IK solving from constraints. It's a separate phase now, on top of the full Pose calculations - Pose itself has a dependency graph too, so evaluation order is lag free. TODO NOW; - Rotating in Posemode has incorrect inverse transform (Martin will fix) - Python Bone/Armature/Pose API disabled... needs full recode too (wait for my doc!) - Game engine will need upgrade too - Depgraph code needs revision, cleanup, can be much faster! (But, compliments for Jean-Luc, it works like a charm!) - IK changed, it now doesnt use previous position to advance to next position anymore. That system looks nice (no flips) but is not well suited for NLA and background render. TODO LATER; We now can do loadsa new nifty features as well; like: - Kill PoseMode (can be option for armatures itself) - Make B-Bones (Bezier, Bspline, like for spines) - Move all silly button level edit to 3d window (like CTRL+I = add IK) - Much better & informative drawing - Fix action/nla editors - Put all ipos in Actions (object, mesh key, lamp color) - Add hooks - Null bones - Much more advanced constraints... Bugfixes; - OGL render (view3d header) had wrong first frame on anim render - Ipo 'recording' mode had wrong playback speed - Vertex-key mode now sticks to show 'active key', until frame change -Ton-
2005-07-03 17:35:38 +00:00
int BKE_armature_bonelist_count(ListBase *lb)
{
int i = 0;
LISTBASE_FOREACH (Bone *, bone, lb) {
i += 1 + BKE_armature_bonelist_count(&bone->childbase);
}
return i;
}
void BKE_armature_bonelist_free(ListBase *lb, const bool do_id_user)
Result of 2 weeks of quiet coding work in Greece :) Aim was to get a total refresh of the animation system. This is needed because; - we need to upgrade it with 21st century features - current code is spaghetti/hack combo, and hides good design - it should become lag-free with using dependency graphs A full log, with complete code API/structure/design explanation will follow, that's a load of work... so here below the list with hot changes; - The entire object update system (matrices, geometry) is now centralized. Calls to where_is_object and makeDispList are forbidden, instead we tag objects 'changed' and let the depgraph code sort it out - Removed all old "Ika" code - Depgraph is aware of all relationships, including meta balls, constraints, bevelcurve, and so on. - Made depgraph aware of relation types and layers, to do smart flushing of 'changed' events. Nothing gets calculated too often! - Transform uses depgraph to detect changes - On frame-advance, depgraph flushes animated changes Armatures; Almost all armature related code has been fully built from scratch. It now reveils the original design much better, with a very clean implementation, lag free without even calculating each Bone more than once. Result is quite a speedup yes! Important to note is; 1) Armature is data containing the 'rest position' 2) Pose is the changes of rest position, and always on object level. That way more Objects can use same Pose. Also constraints are in Pose 3) Actions only contain the Ipos to change values in Poses. - Bones draw unrotated now - Drawing bones speedup enormously (10-20 times) - Bone selecting in EditMode, selection state is saved for PoseMode, and vice-versa - Undo in editmode - Bone renaming does vertexgroups, constraints, posechannels, actions, for all users of Armature in entire file - Added Bone renaming in NKey panel - Nkey PoseMode shows eulers now - EditMode and PoseMode now have 'active' bone too (last clicked) - Parenting in EditMode' CTRL+P, ALT+P, with nice options! - Pose is added in Outliner now, with showing that constraints are in the Pose, not Armature - Disconnected IK solving from constraints. It's a separate phase now, on top of the full Pose calculations - Pose itself has a dependency graph too, so evaluation order is lag free. TODO NOW; - Rotating in Posemode has incorrect inverse transform (Martin will fix) - Python Bone/Armature/Pose API disabled... needs full recode too (wait for my doc!) - Game engine will need upgrade too - Depgraph code needs revision, cleanup, can be much faster! (But, compliments for Jean-Luc, it works like a charm!) - IK changed, it now doesnt use previous position to advance to next position anymore. That system looks nice (no flips) but is not well suited for NLA and background render. TODO LATER; We now can do loadsa new nifty features as well; like: - Kill PoseMode (can be option for armatures itself) - Make B-Bones (Bezier, Bspline, like for spines) - Move all silly button level edit to 3d window (like CTRL+I = add IK) - Much better & informative drawing - Fix action/nla editors - Put all ipos in Actions (object, mesh key, lamp color) - Add hooks - Null bones - Much more advanced constraints... Bugfixes; - OGL render (view3d header) had wrong first frame on anim render - Ipo 'recording' mode had wrong playback speed - Vertex-key mode now sticks to show 'active key', until frame change -Ton-
2005-07-03 17:35:38 +00:00
{
Bone *bone;
for (bone = lb->first; bone; bone = bone->next) {
if (bone->prop) {
IDP_FreeProperty_ex(bone->prop, do_id_user);
Result of 2 weeks of quiet coding work in Greece :) Aim was to get a total refresh of the animation system. This is needed because; - we need to upgrade it with 21st century features - current code is spaghetti/hack combo, and hides good design - it should become lag-free with using dependency graphs A full log, with complete code API/structure/design explanation will follow, that's a load of work... so here below the list with hot changes; - The entire object update system (matrices, geometry) is now centralized. Calls to where_is_object and makeDispList are forbidden, instead we tag objects 'changed' and let the depgraph code sort it out - Removed all old "Ika" code - Depgraph is aware of all relationships, including meta balls, constraints, bevelcurve, and so on. - Made depgraph aware of relation types and layers, to do smart flushing of 'changed' events. Nothing gets calculated too often! - Transform uses depgraph to detect changes - On frame-advance, depgraph flushes animated changes Armatures; Almost all armature related code has been fully built from scratch. It now reveils the original design much better, with a very clean implementation, lag free without even calculating each Bone more than once. Result is quite a speedup yes! Important to note is; 1) Armature is data containing the 'rest position' 2) Pose is the changes of rest position, and always on object level. That way more Objects can use same Pose. Also constraints are in Pose 3) Actions only contain the Ipos to change values in Poses. - Bones draw unrotated now - Drawing bones speedup enormously (10-20 times) - Bone selecting in EditMode, selection state is saved for PoseMode, and vice-versa - Undo in editmode - Bone renaming does vertexgroups, constraints, posechannels, actions, for all users of Armature in entire file - Added Bone renaming in NKey panel - Nkey PoseMode shows eulers now - EditMode and PoseMode now have 'active' bone too (last clicked) - Parenting in EditMode' CTRL+P, ALT+P, with nice options! - Pose is added in Outliner now, with showing that constraints are in the Pose, not Armature - Disconnected IK solving from constraints. It's a separate phase now, on top of the full Pose calculations - Pose itself has a dependency graph too, so evaluation order is lag free. TODO NOW; - Rotating in Posemode has incorrect inverse transform (Martin will fix) - Python Bone/Armature/Pose API disabled... needs full recode too (wait for my doc!) - Game engine will need upgrade too - Depgraph code needs revision, cleanup, can be much faster! (But, compliments for Jean-Luc, it works like a charm!) - IK changed, it now doesnt use previous position to advance to next position anymore. That system looks nice (no flips) but is not well suited for NLA and background render. TODO LATER; We now can do loadsa new nifty features as well; like: - Kill PoseMode (can be option for armatures itself) - Make B-Bones (Bezier, Bspline, like for spines) - Move all silly button level edit to 3d window (like CTRL+I = add IK) - Much better & informative drawing - Fix action/nla editors - Put all ipos in Actions (object, mesh key, lamp color) - Add hooks - Null bones - Much more advanced constraints... Bugfixes; - OGL render (view3d header) had wrong first frame on anim render - Ipo 'recording' mode had wrong playback speed - Vertex-key mode now sticks to show 'active key', until frame change -Ton-
2005-07-03 17:35:38 +00:00
}
BKE_armature_bonelist_free(&bone->childbase, do_id_user);
Result of 2 weeks of quiet coding work in Greece :) Aim was to get a total refresh of the animation system. This is needed because; - we need to upgrade it with 21st century features - current code is spaghetti/hack combo, and hides good design - it should become lag-free with using dependency graphs A full log, with complete code API/structure/design explanation will follow, that's a load of work... so here below the list with hot changes; - The entire object update system (matrices, geometry) is now centralized. Calls to where_is_object and makeDispList are forbidden, instead we tag objects 'changed' and let the depgraph code sort it out - Removed all old "Ika" code - Depgraph is aware of all relationships, including meta balls, constraints, bevelcurve, and so on. - Made depgraph aware of relation types and layers, to do smart flushing of 'changed' events. Nothing gets calculated too often! - Transform uses depgraph to detect changes - On frame-advance, depgraph flushes animated changes Armatures; Almost all armature related code has been fully built from scratch. It now reveils the original design much better, with a very clean implementation, lag free without even calculating each Bone more than once. Result is quite a speedup yes! Important to note is; 1) Armature is data containing the 'rest position' 2) Pose is the changes of rest position, and always on object level. That way more Objects can use same Pose. Also constraints are in Pose 3) Actions only contain the Ipos to change values in Poses. - Bones draw unrotated now - Drawing bones speedup enormously (10-20 times) - Bone selecting in EditMode, selection state is saved for PoseMode, and vice-versa - Undo in editmode - Bone renaming does vertexgroups, constraints, posechannels, actions, for all users of Armature in entire file - Added Bone renaming in NKey panel - Nkey PoseMode shows eulers now - EditMode and PoseMode now have 'active' bone too (last clicked) - Parenting in EditMode' CTRL+P, ALT+P, with nice options! - Pose is added in Outliner now, with showing that constraints are in the Pose, not Armature - Disconnected IK solving from constraints. It's a separate phase now, on top of the full Pose calculations - Pose itself has a dependency graph too, so evaluation order is lag free. TODO NOW; - Rotating in Posemode has incorrect inverse transform (Martin will fix) - Python Bone/Armature/Pose API disabled... needs full recode too (wait for my doc!) - Game engine will need upgrade too - Depgraph code needs revision, cleanup, can be much faster! (But, compliments for Jean-Luc, it works like a charm!) - IK changed, it now doesnt use previous position to advance to next position anymore. That system looks nice (no flips) but is not well suited for NLA and background render. TODO LATER; We now can do loadsa new nifty features as well; like: - Kill PoseMode (can be option for armatures itself) - Make B-Bones (Bezier, Bspline, like for spines) - Move all silly button level edit to 3d window (like CTRL+I = add IK) - Much better & informative drawing - Fix action/nla editors - Put all ipos in Actions (object, mesh key, lamp color) - Add hooks - Null bones - Much more advanced constraints... Bugfixes; - OGL render (view3d header) had wrong first frame on anim render - Ipo 'recording' mode had wrong playback speed - Vertex-key mode now sticks to show 'active key', until frame change -Ton-
2005-07-03 17:35:38 +00:00
}
BLI_freelistN(lb);
Result of 2 weeks of quiet coding work in Greece :) Aim was to get a total refresh of the animation system. This is needed because; - we need to upgrade it with 21st century features - current code is spaghetti/hack combo, and hides good design - it should become lag-free with using dependency graphs A full log, with complete code API/structure/design explanation will follow, that's a load of work... so here below the list with hot changes; - The entire object update system (matrices, geometry) is now centralized. Calls to where_is_object and makeDispList are forbidden, instead we tag objects 'changed' and let the depgraph code sort it out - Removed all old "Ika" code - Depgraph is aware of all relationships, including meta balls, constraints, bevelcurve, and so on. - Made depgraph aware of relation types and layers, to do smart flushing of 'changed' events. Nothing gets calculated too often! - Transform uses depgraph to detect changes - On frame-advance, depgraph flushes animated changes Armatures; Almost all armature related code has been fully built from scratch. It now reveils the original design much better, with a very clean implementation, lag free without even calculating each Bone more than once. Result is quite a speedup yes! Important to note is; 1) Armature is data containing the 'rest position' 2) Pose is the changes of rest position, and always on object level. That way more Objects can use same Pose. Also constraints are in Pose 3) Actions only contain the Ipos to change values in Poses. - Bones draw unrotated now - Drawing bones speedup enormously (10-20 times) - Bone selecting in EditMode, selection state is saved for PoseMode, and vice-versa - Undo in editmode - Bone renaming does vertexgroups, constraints, posechannels, actions, for all users of Armature in entire file - Added Bone renaming in NKey panel - Nkey PoseMode shows eulers now - EditMode and PoseMode now have 'active' bone too (last clicked) - Parenting in EditMode' CTRL+P, ALT+P, with nice options! - Pose is added in Outliner now, with showing that constraints are in the Pose, not Armature - Disconnected IK solving from constraints. It's a separate phase now, on top of the full Pose calculations - Pose itself has a dependency graph too, so evaluation order is lag free. TODO NOW; - Rotating in Posemode has incorrect inverse transform (Martin will fix) - Python Bone/Armature/Pose API disabled... needs full recode too (wait for my doc!) - Game engine will need upgrade too - Depgraph code needs revision, cleanup, can be much faster! (But, compliments for Jean-Luc, it works like a charm!) - IK changed, it now doesnt use previous position to advance to next position anymore. That system looks nice (no flips) but is not well suited for NLA and background render. TODO LATER; We now can do loadsa new nifty features as well; like: - Kill PoseMode (can be option for armatures itself) - Make B-Bones (Bezier, Bspline, like for spines) - Move all silly button level edit to 3d window (like CTRL+I = add IK) - Much better & informative drawing - Fix action/nla editors - Put all ipos in Actions (object, mesh key, lamp color) - Add hooks - Null bones - Much more advanced constraints... Bugfixes; - OGL render (view3d header) had wrong first frame on anim render - Ipo 'recording' mode had wrong playback speed - Vertex-key mode now sticks to show 'active key', until frame change -Ton-
2005-07-03 17:35:38 +00:00
}
2002-10-12 11:37:38 +00:00
void BKE_armature_editbonelist_free(ListBase *lb, const bool do_id_user)
{
LISTBASE_FOREACH_MUTABLE (EditBone *, edit_bone, lb) {
if (edit_bone->prop) {
IDP_FreeProperty_ex(edit_bone->prop, do_id_user);
}
BLI_remlink_safe(lb, edit_bone);
MEM_freeN(edit_bone);
}
}
static void copy_bonechildren(Bone *bone_dst,
const Bone *bone_src,
const Bone *bone_src_act,
Bone **r_bone_dst_act,
const int flag)
Result of 2 weeks of quiet coding work in Greece :) Aim was to get a total refresh of the animation system. This is needed because; - we need to upgrade it with 21st century features - current code is spaghetti/hack combo, and hides good design - it should become lag-free with using dependency graphs A full log, with complete code API/structure/design explanation will follow, that's a load of work... so here below the list with hot changes; - The entire object update system (matrices, geometry) is now centralized. Calls to where_is_object and makeDispList are forbidden, instead we tag objects 'changed' and let the depgraph code sort it out - Removed all old "Ika" code - Depgraph is aware of all relationships, including meta balls, constraints, bevelcurve, and so on. - Made depgraph aware of relation types and layers, to do smart flushing of 'changed' events. Nothing gets calculated too often! - Transform uses depgraph to detect changes - On frame-advance, depgraph flushes animated changes Armatures; Almost all armature related code has been fully built from scratch. It now reveils the original design much better, with a very clean implementation, lag free without even calculating each Bone more than once. Result is quite a speedup yes! Important to note is; 1) Armature is data containing the 'rest position' 2) Pose is the changes of rest position, and always on object level. That way more Objects can use same Pose. Also constraints are in Pose 3) Actions only contain the Ipos to change values in Poses. - Bones draw unrotated now - Drawing bones speedup enormously (10-20 times) - Bone selecting in EditMode, selection state is saved for PoseMode, and vice-versa - Undo in editmode - Bone renaming does vertexgroups, constraints, posechannels, actions, for all users of Armature in entire file - Added Bone renaming in NKey panel - Nkey PoseMode shows eulers now - EditMode and PoseMode now have 'active' bone too (last clicked) - Parenting in EditMode' CTRL+P, ALT+P, with nice options! - Pose is added in Outliner now, with showing that constraints are in the Pose, not Armature - Disconnected IK solving from constraints. It's a separate phase now, on top of the full Pose calculations - Pose itself has a dependency graph too, so evaluation order is lag free. TODO NOW; - Rotating in Posemode has incorrect inverse transform (Martin will fix) - Python Bone/Armature/Pose API disabled... needs full recode too (wait for my doc!) - Game engine will need upgrade too - Depgraph code needs revision, cleanup, can be much faster! (But, compliments for Jean-Luc, it works like a charm!) - IK changed, it now doesnt use previous position to advance to next position anymore. That system looks nice (no flips) but is not well suited for NLA and background render. TODO LATER; We now can do loadsa new nifty features as well; like: - Kill PoseMode (can be option for armatures itself) - Make B-Bones (Bezier, Bspline, like for spines) - Move all silly button level edit to 3d window (like CTRL+I = add IK) - Much better & informative drawing - Fix action/nla editors - Put all ipos in Actions (object, mesh key, lamp color) - Add hooks - Null bones - Much more advanced constraints... Bugfixes; - OGL render (view3d header) had wrong first frame on anim render - Ipo 'recording' mode had wrong playback speed - Vertex-key mode now sticks to show 'active key', until frame change -Ton-
2005-07-03 17:35:38 +00:00
{
Bone *bone_src_child, *bone_dst_child;
if (bone_src == bone_src_act) {
*r_bone_dst_act = bone_dst;
}
if (bone_src->prop) {
bone_dst->prop = IDP_CopyProperty_ex(bone_src->prop, flag);
}
/* Copy this bone's list */
BLI_duplicatelist(&bone_dst->childbase, &bone_src->childbase);
/* For each child in the list, update its children */
for (bone_src_child = bone_src->childbase.first, bone_dst_child = bone_dst->childbase.first;
bone_src_child;
bone_src_child = bone_src_child->next, bone_dst_child = bone_dst_child->next) {
bone_dst_child->parent = bone_dst;
copy_bonechildren(bone_dst_child, bone_src_child, bone_src_act, r_bone_dst_act, flag);
Result of 2 weeks of quiet coding work in Greece :) Aim was to get a total refresh of the animation system. This is needed because; - we need to upgrade it with 21st century features - current code is spaghetti/hack combo, and hides good design - it should become lag-free with using dependency graphs A full log, with complete code API/structure/design explanation will follow, that's a load of work... so here below the list with hot changes; - The entire object update system (matrices, geometry) is now centralized. Calls to where_is_object and makeDispList are forbidden, instead we tag objects 'changed' and let the depgraph code sort it out - Removed all old "Ika" code - Depgraph is aware of all relationships, including meta balls, constraints, bevelcurve, and so on. - Made depgraph aware of relation types and layers, to do smart flushing of 'changed' events. Nothing gets calculated too often! - Transform uses depgraph to detect changes - On frame-advance, depgraph flushes animated changes Armatures; Almost all armature related code has been fully built from scratch. It now reveils the original design much better, with a very clean implementation, lag free without even calculating each Bone more than once. Result is quite a speedup yes! Important to note is; 1) Armature is data containing the 'rest position' 2) Pose is the changes of rest position, and always on object level. That way more Objects can use same Pose. Also constraints are in Pose 3) Actions only contain the Ipos to change values in Poses. - Bones draw unrotated now - Drawing bones speedup enormously (10-20 times) - Bone selecting in EditMode, selection state is saved for PoseMode, and vice-versa - Undo in editmode - Bone renaming does vertexgroups, constraints, posechannels, actions, for all users of Armature in entire file - Added Bone renaming in NKey panel - Nkey PoseMode shows eulers now - EditMode and PoseMode now have 'active' bone too (last clicked) - Parenting in EditMode' CTRL+P, ALT+P, with nice options! - Pose is added in Outliner now, with showing that constraints are in the Pose, not Armature - Disconnected IK solving from constraints. It's a separate phase now, on top of the full Pose calculations - Pose itself has a dependency graph too, so evaluation order is lag free. TODO NOW; - Rotating in Posemode has incorrect inverse transform (Martin will fix) - Python Bone/Armature/Pose API disabled... needs full recode too (wait for my doc!) - Game engine will need upgrade too - Depgraph code needs revision, cleanup, can be much faster! (But, compliments for Jean-Luc, it works like a charm!) - IK changed, it now doesnt use previous position to advance to next position anymore. That system looks nice (no flips) but is not well suited for NLA and background render. TODO LATER; We now can do loadsa new nifty features as well; like: - Kill PoseMode (can be option for armatures itself) - Make B-Bones (Bezier, Bspline, like for spines) - Move all silly button level edit to 3d window (like CTRL+I = add IK) - Much better & informative drawing - Fix action/nla editors - Put all ipos in Actions (object, mesh key, lamp color) - Add hooks - Null bones - Much more advanced constraints... Bugfixes; - OGL render (view3d header) had wrong first frame on anim render - Ipo 'recording' mode had wrong playback speed - Vertex-key mode now sticks to show 'active key', until frame change -Ton-
2005-07-03 17:35:38 +00:00
}
}
2002-10-12 11:37:38 +00:00
static void copy_bonechildren_custom_handles(Bone *bone_dst, bArmature *arm_dst)
{
Bone *bone_dst_child;
if (bone_dst->bbone_prev) {
bone_dst->bbone_prev = BKE_armature_find_bone_name(arm_dst, bone_dst->bbone_prev->name);
}
if (bone_dst->bbone_next) {
bone_dst->bbone_next = BKE_armature_find_bone_name(arm_dst, bone_dst->bbone_next->name);
}
for (bone_dst_child = bone_dst->childbase.first; bone_dst_child;
bone_dst_child = bone_dst_child->next) {
copy_bonechildren_custom_handles(bone_dst_child, arm_dst);
}
}
/** \} */
/* -------------------------------------------------------------------- */
/** \name Armature Transform Copy
* \{ */
static void copy_bone_transform(Bone *bone_dst, const Bone *bone_src)
{
bone_dst->roll = bone_src->roll;
copy_v3_v3(bone_dst->head, bone_src->head);
copy_v3_v3(bone_dst->tail, bone_src->tail);
copy_m3_m3(bone_dst->bone_mat, bone_src->bone_mat);
copy_v3_v3(bone_dst->arm_head, bone_src->arm_head);
copy_v3_v3(bone_dst->arm_tail, bone_src->arm_tail);
copy_m4_m4(bone_dst->arm_mat, bone_src->arm_mat);
bone_dst->arm_roll = bone_src->arm_roll;
}
void BKE_armature_copy_bone_transforms(bArmature *armature_dst, const bArmature *armature_src)
{
Bone *bone_dst = armature_dst->bonebase.first;
const Bone *bone_src = armature_src->bonebase.first;
while (bone_dst != NULL) {
BLI_assert(bone_src != NULL);
copy_bone_transform(bone_dst, bone_src);
bone_dst = bone_dst->next;
bone_src = bone_src->next;
}
}
/** \} */
/* -------------------------------------------------------------------- */
/** \name Armature Transform by 4x4 Matrix
*
* \see #ED_armature_edit_transform for the edit-mode version of this function.
* \{ */
/** Helper for #ED_armature_transform */
static void armature_transform_recurse(ListBase *bonebase,
const float mat[4][4],
const bool do_props,
/* Cached from 'mat'. */
const float mat3[3][3],
const float scale,
/* Child bones. */
const Bone *bone_parent,
const float arm_mat_parent_inv[4][4])
{
LISTBASE_FOREACH (Bone *, bone, bonebase) {
2019-11-29 14:57:07 +11:00
/* Store the initial bone roll in a matrix, this is needed even for child bones
* so any change in head/tail doesn't cause the roll to change.
*
* Logic here is different to edit-mode because
* this is calculated in relative to the parent. */
float roll_mat3_pre[3][3];
{
float delta[3];
sub_v3_v3v3(delta, bone->tail, bone->head);
vec_roll_to_mat3(delta, bone->roll, roll_mat3_pre);
if (bone->parent == NULL) {
mul_m3_m3m3(roll_mat3_pre, mat3, roll_mat3_pre);
}
}
2019-11-29 14:57:07 +11:00
/* Optional, use this for predictable results since the roll is re-calculated below anyway. */
bone->roll = 0.0f;
mul_m4_v3(mat, bone->arm_head);
mul_m4_v3(mat, bone->arm_tail);
/* Get the new head and tail */
if (bone_parent) {
sub_v3_v3v3(bone->head, bone->arm_head, bone_parent->arm_tail);
sub_v3_v3v3(bone->tail, bone->arm_tail, bone_parent->arm_tail);
mul_mat3_m4_v3(arm_mat_parent_inv, bone->head);
mul_mat3_m4_v3(arm_mat_parent_inv, bone->tail);
}
else {
copy_v3_v3(bone->head, bone->arm_head);
copy_v3_v3(bone->tail, bone->arm_tail);
}
2019-11-29 14:57:07 +11:00
/* Now the head/tail have been updated, set the roll back, matching 'roll_mat3_pre'. */
{
2019-11-29 14:57:07 +11:00
float roll_mat3_post[3][3], delta_mat3[3][3];
float delta[3];
sub_v3_v3v3(delta, bone->tail, bone->head);
2019-11-29 14:57:07 +11:00
vec_roll_to_mat3(delta, 0.0f, roll_mat3_post);
invert_m3(roll_mat3_post);
mul_m3_m3m3(delta_mat3, roll_mat3_post, roll_mat3_pre);
bone->roll = atan2f(delta_mat3[2][0], delta_mat3[2][2]);
}
BKE_armature_where_is_bone(bone, bone_parent, false);
{
float arm_mat3[3][3];
copy_m3_m4(arm_mat3, bone->arm_mat);
mat3_to_vec_roll(arm_mat3, NULL, &bone->arm_roll);
}
if (do_props) {
bone->rad_head *= scale;
bone->rad_tail *= scale;
bone->dist *= scale;
/* we could be smarter and scale by the matrix along the x & z axis */
bone->xwidth *= scale;
bone->zwidth *= scale;
}
if (!BLI_listbase_is_empty(&bone->childbase)) {
float arm_mat_inv[4][4];
invert_m4_m4(arm_mat_inv, bone->arm_mat);
armature_transform_recurse(&bone->childbase, mat, do_props, mat3, scale, bone, arm_mat_inv);
}
}
}
void BKE_armature_transform(bArmature *arm, const float mat[4][4], const bool do_props)
{
/* Store the scale of the matrix here to use on envelopes. */
float scale = mat4_to_scale(mat);
float mat3[3][3];
copy_m3_m4(mat3, mat);
normalize_m3(mat3);
armature_transform_recurse(&arm->bonebase, mat, do_props, mat3, scale, NULL, NULL);
}
/** \} */
/* -------------------------------------------------------------------- */
/** \name Armature Bone Find by Name
*
* Using fast #GHash lookups when available.
* \{ */
static Bone *get_named_bone_bonechildren(ListBase *lb, const char *name)
Result of 2 weeks of quiet coding work in Greece :) Aim was to get a total refresh of the animation system. This is needed because; - we need to upgrade it with 21st century features - current code is spaghetti/hack combo, and hides good design - it should become lag-free with using dependency graphs A full log, with complete code API/structure/design explanation will follow, that's a load of work... so here below the list with hot changes; - The entire object update system (matrices, geometry) is now centralized. Calls to where_is_object and makeDispList are forbidden, instead we tag objects 'changed' and let the depgraph code sort it out - Removed all old "Ika" code - Depgraph is aware of all relationships, including meta balls, constraints, bevelcurve, and so on. - Made depgraph aware of relation types and layers, to do smart flushing of 'changed' events. Nothing gets calculated too often! - Transform uses depgraph to detect changes - On frame-advance, depgraph flushes animated changes Armatures; Almost all armature related code has been fully built from scratch. It now reveils the original design much better, with a very clean implementation, lag free without even calculating each Bone more than once. Result is quite a speedup yes! Important to note is; 1) Armature is data containing the 'rest position' 2) Pose is the changes of rest position, and always on object level. That way more Objects can use same Pose. Also constraints are in Pose 3) Actions only contain the Ipos to change values in Poses. - Bones draw unrotated now - Drawing bones speedup enormously (10-20 times) - Bone selecting in EditMode, selection state is saved for PoseMode, and vice-versa - Undo in editmode - Bone renaming does vertexgroups, constraints, posechannels, actions, for all users of Armature in entire file - Added Bone renaming in NKey panel - Nkey PoseMode shows eulers now - EditMode and PoseMode now have 'active' bone too (last clicked) - Parenting in EditMode' CTRL+P, ALT+P, with nice options! - Pose is added in Outliner now, with showing that constraints are in the Pose, not Armature - Disconnected IK solving from constraints. It's a separate phase now, on top of the full Pose calculations - Pose itself has a dependency graph too, so evaluation order is lag free. TODO NOW; - Rotating in Posemode has incorrect inverse transform (Martin will fix) - Python Bone/Armature/Pose API disabled... needs full recode too (wait for my doc!) - Game engine will need upgrade too - Depgraph code needs revision, cleanup, can be much faster! (But, compliments for Jean-Luc, it works like a charm!) - IK changed, it now doesnt use previous position to advance to next position anymore. That system looks nice (no flips) but is not well suited for NLA and background render. TODO LATER; We now can do loadsa new nifty features as well; like: - Kill PoseMode (can be option for armatures itself) - Make B-Bones (Bezier, Bspline, like for spines) - Move all silly button level edit to 3d window (like CTRL+I = add IK) - Much better & informative drawing - Fix action/nla editors - Put all ipos in Actions (object, mesh key, lamp color) - Add hooks - Null bones - Much more advanced constraints... Bugfixes; - OGL render (view3d header) had wrong first frame on anim render - Ipo 'recording' mode had wrong playback speed - Vertex-key mode now sticks to show 'active key', until frame change -Ton-
2005-07-03 17:35:38 +00:00
{
Bone *curBone, *rbone;
for (curBone = lb->first; curBone; curBone = curBone->next) {
if (STREQ(curBone->name, name)) {
return curBone;
}
rbone = get_named_bone_bonechildren(&curBone->childbase, name);
if (rbone) {
Result of 2 weeks of quiet coding work in Greece :) Aim was to get a total refresh of the animation system. This is needed because; - we need to upgrade it with 21st century features - current code is spaghetti/hack combo, and hides good design - it should become lag-free with using dependency graphs A full log, with complete code API/structure/design explanation will follow, that's a load of work... so here below the list with hot changes; - The entire object update system (matrices, geometry) is now centralized. Calls to where_is_object and makeDispList are forbidden, instead we tag objects 'changed' and let the depgraph code sort it out - Removed all old "Ika" code - Depgraph is aware of all relationships, including meta balls, constraints, bevelcurve, and so on. - Made depgraph aware of relation types and layers, to do smart flushing of 'changed' events. Nothing gets calculated too often! - Transform uses depgraph to detect changes - On frame-advance, depgraph flushes animated changes Armatures; Almost all armature related code has been fully built from scratch. It now reveils the original design much better, with a very clean implementation, lag free without even calculating each Bone more than once. Result is quite a speedup yes! Important to note is; 1) Armature is data containing the 'rest position' 2) Pose is the changes of rest position, and always on object level. That way more Objects can use same Pose. Also constraints are in Pose 3) Actions only contain the Ipos to change values in Poses. - Bones draw unrotated now - Drawing bones speedup enormously (10-20 times) - Bone selecting in EditMode, selection state is saved for PoseMode, and vice-versa - Undo in editmode - Bone renaming does vertexgroups, constraints, posechannels, actions, for all users of Armature in entire file - Added Bone renaming in NKey panel - Nkey PoseMode shows eulers now - EditMode and PoseMode now have 'active' bone too (last clicked) - Parenting in EditMode' CTRL+P, ALT+P, with nice options! - Pose is added in Outliner now, with showing that constraints are in the Pose, not Armature - Disconnected IK solving from constraints. It's a separate phase now, on top of the full Pose calculations - Pose itself has a dependency graph too, so evaluation order is lag free. TODO NOW; - Rotating in Posemode has incorrect inverse transform (Martin will fix) - Python Bone/Armature/Pose API disabled... needs full recode too (wait for my doc!) - Game engine will need upgrade too - Depgraph code needs revision, cleanup, can be much faster! (But, compliments for Jean-Luc, it works like a charm!) - IK changed, it now doesnt use previous position to advance to next position anymore. That system looks nice (no flips) but is not well suited for NLA and background render. TODO LATER; We now can do loadsa new nifty features as well; like: - Kill PoseMode (can be option for armatures itself) - Make B-Bones (Bezier, Bspline, like for spines) - Move all silly button level edit to 3d window (like CTRL+I = add IK) - Much better & informative drawing - Fix action/nla editors - Put all ipos in Actions (object, mesh key, lamp color) - Add hooks - Null bones - Much more advanced constraints... Bugfixes; - OGL render (view3d header) had wrong first frame on anim render - Ipo 'recording' mode had wrong playback speed - Vertex-key mode now sticks to show 'active key', until frame change -Ton-
2005-07-03 17:35:38 +00:00
return rbone;
}
Result of 2 weeks of quiet coding work in Greece :) Aim was to get a total refresh of the animation system. This is needed because; - we need to upgrade it with 21st century features - current code is spaghetti/hack combo, and hides good design - it should become lag-free with using dependency graphs A full log, with complete code API/structure/design explanation will follow, that's a load of work... so here below the list with hot changes; - The entire object update system (matrices, geometry) is now centralized. Calls to where_is_object and makeDispList are forbidden, instead we tag objects 'changed' and let the depgraph code sort it out - Removed all old "Ika" code - Depgraph is aware of all relationships, including meta balls, constraints, bevelcurve, and so on. - Made depgraph aware of relation types and layers, to do smart flushing of 'changed' events. Nothing gets calculated too often! - Transform uses depgraph to detect changes - On frame-advance, depgraph flushes animated changes Armatures; Almost all armature related code has been fully built from scratch. It now reveils the original design much better, with a very clean implementation, lag free without even calculating each Bone more than once. Result is quite a speedup yes! Important to note is; 1) Armature is data containing the 'rest position' 2) Pose is the changes of rest position, and always on object level. That way more Objects can use same Pose. Also constraints are in Pose 3) Actions only contain the Ipos to change values in Poses. - Bones draw unrotated now - Drawing bones speedup enormously (10-20 times) - Bone selecting in EditMode, selection state is saved for PoseMode, and vice-versa - Undo in editmode - Bone renaming does vertexgroups, constraints, posechannels, actions, for all users of Armature in entire file - Added Bone renaming in NKey panel - Nkey PoseMode shows eulers now - EditMode and PoseMode now have 'active' bone too (last clicked) - Parenting in EditMode' CTRL+P, ALT+P, with nice options! - Pose is added in Outliner now, with showing that constraints are in the Pose, not Armature - Disconnected IK solving from constraints. It's a separate phase now, on top of the full Pose calculations - Pose itself has a dependency graph too, so evaluation order is lag free. TODO NOW; - Rotating in Posemode has incorrect inverse transform (Martin will fix) - Python Bone/Armature/Pose API disabled... needs full recode too (wait for my doc!) - Game engine will need upgrade too - Depgraph code needs revision, cleanup, can be much faster! (But, compliments for Jean-Luc, it works like a charm!) - IK changed, it now doesnt use previous position to advance to next position anymore. That system looks nice (no flips) but is not well suited for NLA and background render. TODO LATER; We now can do loadsa new nifty features as well; like: - Kill PoseMode (can be option for armatures itself) - Make B-Bones (Bezier, Bspline, like for spines) - Move all silly button level edit to 3d window (like CTRL+I = add IK) - Much better & informative drawing - Fix action/nla editors - Put all ipos in Actions (object, mesh key, lamp color) - Add hooks - Null bones - Much more advanced constraints... Bugfixes; - OGL render (view3d header) had wrong first frame on anim render - Ipo 'recording' mode had wrong playback speed - Vertex-key mode now sticks to show 'active key', until frame change -Ton-
2005-07-03 17:35:38 +00:00
}
Result of 2 weeks of quiet coding work in Greece :) Aim was to get a total refresh of the animation system. This is needed because; - we need to upgrade it with 21st century features - current code is spaghetti/hack combo, and hides good design - it should become lag-free with using dependency graphs A full log, with complete code API/structure/design explanation will follow, that's a load of work... so here below the list with hot changes; - The entire object update system (matrices, geometry) is now centralized. Calls to where_is_object and makeDispList are forbidden, instead we tag objects 'changed' and let the depgraph code sort it out - Removed all old "Ika" code - Depgraph is aware of all relationships, including meta balls, constraints, bevelcurve, and so on. - Made depgraph aware of relation types and layers, to do smart flushing of 'changed' events. Nothing gets calculated too often! - Transform uses depgraph to detect changes - On frame-advance, depgraph flushes animated changes Armatures; Almost all armature related code has been fully built from scratch. It now reveils the original design much better, with a very clean implementation, lag free without even calculating each Bone more than once. Result is quite a speedup yes! Important to note is; 1) Armature is data containing the 'rest position' 2) Pose is the changes of rest position, and always on object level. That way more Objects can use same Pose. Also constraints are in Pose 3) Actions only contain the Ipos to change values in Poses. - Bones draw unrotated now - Drawing bones speedup enormously (10-20 times) - Bone selecting in EditMode, selection state is saved for PoseMode, and vice-versa - Undo in editmode - Bone renaming does vertexgroups, constraints, posechannels, actions, for all users of Armature in entire file - Added Bone renaming in NKey panel - Nkey PoseMode shows eulers now - EditMode and PoseMode now have 'active' bone too (last clicked) - Parenting in EditMode' CTRL+P, ALT+P, with nice options! - Pose is added in Outliner now, with showing that constraints are in the Pose, not Armature - Disconnected IK solving from constraints. It's a separate phase now, on top of the full Pose calculations - Pose itself has a dependency graph too, so evaluation order is lag free. TODO NOW; - Rotating in Posemode has incorrect inverse transform (Martin will fix) - Python Bone/Armature/Pose API disabled... needs full recode too (wait for my doc!) - Game engine will need upgrade too - Depgraph code needs revision, cleanup, can be much faster! (But, compliments for Jean-Luc, it works like a charm!) - IK changed, it now doesnt use previous position to advance to next position anymore. That system looks nice (no flips) but is not well suited for NLA and background render. TODO LATER; We now can do loadsa new nifty features as well; like: - Kill PoseMode (can be option for armatures itself) - Make B-Bones (Bezier, Bspline, like for spines) - Move all silly button level edit to 3d window (like CTRL+I = add IK) - Much better & informative drawing - Fix action/nla editors - Put all ipos in Actions (object, mesh key, lamp color) - Add hooks - Null bones - Much more advanced constraints... Bugfixes; - OGL render (view3d header) had wrong first frame on anim render - Ipo 'recording' mode had wrong playback speed - Vertex-key mode now sticks to show 'active key', until frame change -Ton-
2005-07-03 17:35:38 +00:00
return NULL;
}
/**
* Walk the list until the bone is found (slow!),
* use #BKE_armature_bone_from_name_map for multiple lookups.
*/
Bone *BKE_armature_find_bone_name(bArmature *arm, const char *name)
Result of 2 weeks of quiet coding work in Greece :) Aim was to get a total refresh of the animation system. This is needed because; - we need to upgrade it with 21st century features - current code is spaghetti/hack combo, and hides good design - it should become lag-free with using dependency graphs A full log, with complete code API/structure/design explanation will follow, that's a load of work... so here below the list with hot changes; - The entire object update system (matrices, geometry) is now centralized. Calls to where_is_object and makeDispList are forbidden, instead we tag objects 'changed' and let the depgraph code sort it out - Removed all old "Ika" code - Depgraph is aware of all relationships, including meta balls, constraints, bevelcurve, and so on. - Made depgraph aware of relation types and layers, to do smart flushing of 'changed' events. Nothing gets calculated too often! - Transform uses depgraph to detect changes - On frame-advance, depgraph flushes animated changes Armatures; Almost all armature related code has been fully built from scratch. It now reveils the original design much better, with a very clean implementation, lag free without even calculating each Bone more than once. Result is quite a speedup yes! Important to note is; 1) Armature is data containing the 'rest position' 2) Pose is the changes of rest position, and always on object level. That way more Objects can use same Pose. Also constraints are in Pose 3) Actions only contain the Ipos to change values in Poses. - Bones draw unrotated now - Drawing bones speedup enormously (10-20 times) - Bone selecting in EditMode, selection state is saved for PoseMode, and vice-versa - Undo in editmode - Bone renaming does vertexgroups, constraints, posechannels, actions, for all users of Armature in entire file - Added Bone renaming in NKey panel - Nkey PoseMode shows eulers now - EditMode and PoseMode now have 'active' bone too (last clicked) - Parenting in EditMode' CTRL+P, ALT+P, with nice options! - Pose is added in Outliner now, with showing that constraints are in the Pose, not Armature - Disconnected IK solving from constraints. It's a separate phase now, on top of the full Pose calculations - Pose itself has a dependency graph too, so evaluation order is lag free. TODO NOW; - Rotating in Posemode has incorrect inverse transform (Martin will fix) - Python Bone/Armature/Pose API disabled... needs full recode too (wait for my doc!) - Game engine will need upgrade too - Depgraph code needs revision, cleanup, can be much faster! (But, compliments for Jean-Luc, it works like a charm!) - IK changed, it now doesnt use previous position to advance to next position anymore. That system looks nice (no flips) but is not well suited for NLA and background render. TODO LATER; We now can do loadsa new nifty features as well; like: - Kill PoseMode (can be option for armatures itself) - Make B-Bones (Bezier, Bspline, like for spines) - Move all silly button level edit to 3d window (like CTRL+I = add IK) - Much better & informative drawing - Fix action/nla editors - Put all ipos in Actions (object, mesh key, lamp color) - Add hooks - Null bones - Much more advanced constraints... Bugfixes; - OGL render (view3d header) had wrong first frame on anim render - Ipo 'recording' mode had wrong playback speed - Vertex-key mode now sticks to show 'active key', until frame change -Ton-
2005-07-03 17:35:38 +00:00
{
if (!arm) {
return NULL;
}
if (arm->bonehash) {
return BLI_ghash_lookup(arm->bonehash, name);
}
return get_named_bone_bonechildren(&arm->bonebase, name);
}
static void armature_bone_from_name_insert_recursive(GHash *bone_hash, ListBase *lb)
{
LISTBASE_FOREACH (Bone *, bone, lb) {
BLI_ghash_insert(bone_hash, bone->name, bone);
armature_bone_from_name_insert_recursive(bone_hash, &bone->childbase);
Result of 2 weeks of quiet coding work in Greece :) Aim was to get a total refresh of the animation system. This is needed because; - we need to upgrade it with 21st century features - current code is spaghetti/hack combo, and hides good design - it should become lag-free with using dependency graphs A full log, with complete code API/structure/design explanation will follow, that's a load of work... so here below the list with hot changes; - The entire object update system (matrices, geometry) is now centralized. Calls to where_is_object and makeDispList are forbidden, instead we tag objects 'changed' and let the depgraph code sort it out - Removed all old "Ika" code - Depgraph is aware of all relationships, including meta balls, constraints, bevelcurve, and so on. - Made depgraph aware of relation types and layers, to do smart flushing of 'changed' events. Nothing gets calculated too often! - Transform uses depgraph to detect changes - On frame-advance, depgraph flushes animated changes Armatures; Almost all armature related code has been fully built from scratch. It now reveils the original design much better, with a very clean implementation, lag free without even calculating each Bone more than once. Result is quite a speedup yes! Important to note is; 1) Armature is data containing the 'rest position' 2) Pose is the changes of rest position, and always on object level. That way more Objects can use same Pose. Also constraints are in Pose 3) Actions only contain the Ipos to change values in Poses. - Bones draw unrotated now - Drawing bones speedup enormously (10-20 times) - Bone selecting in EditMode, selection state is saved for PoseMode, and vice-versa - Undo in editmode - Bone renaming does vertexgroups, constraints, posechannels, actions, for all users of Armature in entire file - Added Bone renaming in NKey panel - Nkey PoseMode shows eulers now - EditMode and PoseMode now have 'active' bone too (last clicked) - Parenting in EditMode' CTRL+P, ALT+P, with nice options! - Pose is added in Outliner now, with showing that constraints are in the Pose, not Armature - Disconnected IK solving from constraints. It's a separate phase now, on top of the full Pose calculations - Pose itself has a dependency graph too, so evaluation order is lag free. TODO NOW; - Rotating in Posemode has incorrect inverse transform (Martin will fix) - Python Bone/Armature/Pose API disabled... needs full recode too (wait for my doc!) - Game engine will need upgrade too - Depgraph code needs revision, cleanup, can be much faster! (But, compliments for Jean-Luc, it works like a charm!) - IK changed, it now doesnt use previous position to advance to next position anymore. That system looks nice (no flips) but is not well suited for NLA and background render. TODO LATER; We now can do loadsa new nifty features as well; like: - Kill PoseMode (can be option for armatures itself) - Make B-Bones (Bezier, Bspline, like for spines) - Move all silly button level edit to 3d window (like CTRL+I = add IK) - Much better & informative drawing - Fix action/nla editors - Put all ipos in Actions (object, mesh key, lamp color) - Add hooks - Null bones - Much more advanced constraints... Bugfixes; - OGL render (view3d header) had wrong first frame on anim render - Ipo 'recording' mode had wrong playback speed - Vertex-key mode now sticks to show 'active key', until frame change -Ton-
2005-07-03 17:35:38 +00:00
}
}
/**
* Create a (name -> bone) map.
*
* \note typically #bPose.chanhash us used via #BKE_pose_channel_find_name
* this is for the cases we can't use pose channels.
*/
static GHash *armature_bone_from_name_map(bArmature *arm)
{
const int bones_count = BKE_armature_bonelist_count(&arm->bonebase);
GHash *bone_hash = BLI_ghash_str_new_ex(__func__, bones_count);
armature_bone_from_name_insert_recursive(bone_hash, &arm->bonebase);
return bone_hash;
2002-10-12 11:37:38 +00:00
}
void BKE_armature_bone_hash_make(bArmature *arm)
{
if (!arm->bonehash) {
arm->bonehash = armature_bone_from_name_map(arm);
}
}
void BKE_armature_bone_hash_free(bArmature *arm)
{
if (arm->bonehash) {
BLI_ghash_free(arm->bonehash, NULL, NULL);
arm->bonehash = NULL;
}
}
/** \} */
/* -------------------------------------------------------------------- */
/** \name Armature Bone Flags
* \{ */
bool BKE_armature_bone_flag_test_recursive(const Bone *bone, int flag)
{
if (bone->flag & flag) {
return true;
}
if (bone->parent) {
return BKE_armature_bone_flag_test_recursive(bone->parent, flag);
}
return false;
}
/** \} */
/* -------------------------------------------------------------------- */
/** \name Armature Layer Refresh Used
* \{ */
static void armature_refresh_layer_used_recursive(bArmature *arm, ListBase *bones)
{
LISTBASE_FOREACH (Bone *, bone, bones) {
arm->layer_used |= bone->layer;
armature_refresh_layer_used_recursive(arm, &bone->childbase);
}
}
Fix T76689: Armature layers not indicating the existence of bones From what I can see, there are two issues at play in {T76689} and its merged-in report {T76590}: - In Blender ≤ 2.79 the bone layer dots were updated in the draw code. This ensured the info was up to date before drawing. This is no longer possible, as the drawing code uses evaluated objects, and those should not be written to. This has been addressed in rB709f126e8143 by calling the update function explicitly in various places in the code. The problem is that this wasn't added to all necessary spots. - When in edit mode, changes are made to the edit bones but not to the 'actual' bones (this is synced when exiting edit mode). This causes undo to mess up the layer indicators. I think both issues can be addressed by having the dependency graph update the used layer info as part of the armature evaluation. This will make the undo system work properly, and allows the removal of some `BKE_armature_refresh_layer_used()` from various places. There is still the issue that there are two functions (`BKE_armature_refresh_layer_used()` and `ED_armature_edit_refresh_layer_used()`) that are both responsible for updating `bArmature::layer_used`. This is a trickier thing to solve, though, as the definition of the `EditBone` struct resides in the armature editor module. This means that blenkernel can't iterate over edit bones, but on the other hand the dependency graph shouldn't call any editor functions either. This is why I left the `ED_armature_edit_refresh_layer_used()` calls untouched. The downside of recalculating `layer_used` from the dependency graph (at least in the way that I did it now) is that it is called every time a user moves a bone in pose mode. This frequency of updates is not necessary. Differential Revision: https://developer.blender.org/D7709
2020-05-12 18:22:14 +02:00
void BKE_armature_refresh_layer_used(struct Depsgraph *depsgraph, struct bArmature *arm)
{
Fix T76689: Armature layers not indicating the existence of bones From what I can see, there are two issues at play in {T76689} and its merged-in report {T76590}: - In Blender ≤ 2.79 the bone layer dots were updated in the draw code. This ensured the info was up to date before drawing. This is no longer possible, as the drawing code uses evaluated objects, and those should not be written to. This has been addressed in rB709f126e8143 by calling the update function explicitly in various places in the code. The problem is that this wasn't added to all necessary spots. - When in edit mode, changes are made to the edit bones but not to the 'actual' bones (this is synced when exiting edit mode). This causes undo to mess up the layer indicators. I think both issues can be addressed by having the dependency graph update the used layer info as part of the armature evaluation. This will make the undo system work properly, and allows the removal of some `BKE_armature_refresh_layer_used()` from various places. There is still the issue that there are two functions (`BKE_armature_refresh_layer_used()` and `ED_armature_edit_refresh_layer_used()`) that are both responsible for updating `bArmature::layer_used`. This is a trickier thing to solve, though, as the definition of the `EditBone` struct resides in the armature editor module. This means that blenkernel can't iterate over edit bones, but on the other hand the dependency graph shouldn't call any editor functions either. This is why I left the `ED_armature_edit_refresh_layer_used()` calls untouched. The downside of recalculating `layer_used` from the dependency graph (at least in the way that I did it now) is that it is called every time a user moves a bone in pose mode. This frequency of updates is not necessary. Differential Revision: https://developer.blender.org/D7709
2020-05-12 18:22:14 +02:00
if (arm->edbo != NULL) {
/* Don't perform this update when the armature is in edit mode. In that case it should be
* handled by ED_armature_edit_refresh_layer_used(). */
return;
}
arm->layer_used = 0;
armature_refresh_layer_used_recursive(arm, &arm->bonebase);
Fix T76689: Armature layers not indicating the existence of bones From what I can see, there are two issues at play in {T76689} and its merged-in report {T76590}: - In Blender ≤ 2.79 the bone layer dots were updated in the draw code. This ensured the info was up to date before drawing. This is no longer possible, as the drawing code uses evaluated objects, and those should not be written to. This has been addressed in rB709f126e8143 by calling the update function explicitly in various places in the code. The problem is that this wasn't added to all necessary spots. - When in edit mode, changes are made to the edit bones but not to the 'actual' bones (this is synced when exiting edit mode). This causes undo to mess up the layer indicators. I think both issues can be addressed by having the dependency graph update the used layer info as part of the armature evaluation. This will make the undo system work properly, and allows the removal of some `BKE_armature_refresh_layer_used()` from various places. There is still the issue that there are two functions (`BKE_armature_refresh_layer_used()` and `ED_armature_edit_refresh_layer_used()`) that are both responsible for updating `bArmature::layer_used`. This is a trickier thing to solve, though, as the definition of the `EditBone` struct resides in the armature editor module. This means that blenkernel can't iterate over edit bones, but on the other hand the dependency graph shouldn't call any editor functions either. This is why I left the `ED_armature_edit_refresh_layer_used()` calls untouched. The downside of recalculating `layer_used` from the dependency graph (at least in the way that I did it now) is that it is called every time a user moves a bone in pose mode. This frequency of updates is not necessary. Differential Revision: https://developer.blender.org/D7709
2020-05-12 18:22:14 +02:00
if (depsgraph == NULL || DEG_is_active(depsgraph)) {
bArmature *arm_orig = (bArmature *)DEG_get_original_id(&arm->id);
arm_orig->layer_used = arm->layer_used;
}
}
/** \} */
/* -------------------------------------------------------------------- */
/** \name Armature Layer Refresh Used
* \{ */
/* Finds the best possible extension to the name on a particular axis. (For renaming, check for
* unique names afterwards) strip_number: removes number extensions (TODO: not used)
* axis: the axis to name on
* head/tail: the head/tail co-ordinate of the bone on the specified axis */
2020-09-09 10:44:46 +02:00
bool bone_autoside_name(
char name[MAXBONENAME], int UNUSED(strip_number), short axis, float head, float tail)
{
unsigned int len;
char basename[MAXBONENAME] = "";
char extension[5] = "";
len = strlen(name);
if (len == 0) {
2020-09-09 10:44:46 +02:00
return false;
}
BLI_strncpy(basename, name, sizeof(basename));
/* Figure out extension to append:
2018-11-14 12:53:15 +11:00
* - The extension to append is based upon the axis that we are working on.
* - If head happens to be on 0, then we must consider the tail position as well to decide
* which side the bone is on
* -> If tail is 0, then its bone is considered to be on axis, so no extension should be added
* -> Otherwise, extension is added from perspective of object based on which side tail goes to
* - If head is non-zero, extension is added from perspective of object based on side head is on
*/
if (axis == 2) {
/* z-axis - vertical (top/bottom) */
if (IS_EQF(head, 0.0f)) {
if (tail < 0) {
strcpy(extension, "Bot");
}
else if (tail > 0) {
strcpy(extension, "Top");
}
}
else {
if (head < 0) {
strcpy(extension, "Bot");
}
else {
strcpy(extension, "Top");
}
}
}
else if (axis == 1) {
/* y-axis - depth (front/back) */
if (IS_EQF(head, 0.0f)) {
if (tail < 0) {
strcpy(extension, "Fr");
}
else if (tail > 0) {
strcpy(extension, "Bk");
}
}
else {
if (head < 0) {
strcpy(extension, "Fr");
}
else {
strcpy(extension, "Bk");
}
}
}
else {
/* x-axis - horizontal (left/right) */
if (IS_EQF(head, 0.0f)) {
if (tail < 0) {
strcpy(extension, "R");
}
else if (tail > 0) {
strcpy(extension, "L");
}
}
else {
if (head < 0) {
strcpy(extension, "R");
/* XXX Shouldn't this be simple else, as for z and y axes? */
}
else if (head > 0) {
strcpy(extension, "L");
}
}
}
/* Simple name truncation
2018-11-14 12:53:15 +11:00
* - truncate if there is an extension and it wouldn't be able to fit
* - otherwise, just append to end
*/
if (extension[0]) {
bool changed = true;
while (changed) { /* remove extensions */
changed = false;
if (len > 2 && basename[len - 2] == '.') {
2020-11-06 12:30:59 +11:00
if (ELEM(basename[len - 1], 'L', 'R')) { /* L R */
basename[len - 2] = '\0';
len -= 2;
changed = true;
}
}
else if (len > 3 && basename[len - 3] == '.') {
if ((basename[len - 2] == 'F' && basename[len - 1] == 'r') || /* Fr */
(basename[len - 2] == 'B' && basename[len - 1] == 'k')) /* Bk */
{
basename[len - 3] = '\0';
len -= 3;
changed = true;
}
}
else if (len > 4 && basename[len - 4] == '.') {
if ((basename[len - 3] == 'T' && basename[len - 2] == 'o' &&
basename[len - 1] == 'p') || /* Top */
(basename[len - 3] == 'B' && basename[len - 2] == 'o' &&
basename[len - 1] == 't')) /* Bot */
{
basename[len - 4] = '\0';
len -= 4;
changed = true;
}
}
}
if ((MAXBONENAME - len) < strlen(extension) + 1) { /* add 1 for the '.' */
strncpy(name, basename, len - strlen(extension));
}
BLI_snprintf(name, MAXBONENAME, "%s.%s", basename, extension);
2020-09-09 10:44:46 +02:00
return true;
}
2020-09-09 10:44:46 +02:00
return false;
}
/** \} */
/* -------------------------------------------------------------------- */
/** \name Armature B-Bone Support
* \{ */
/* Compute a set of bezier parameter values that produce approximately equally spaced points. */
static void equalize_cubic_bezier(const float control[4][3],
int temp_segments,
int final_segments,
float *r_t_points)
{
float(*coords)[3] = BLI_array_alloca(coords, temp_segments + 1);
float *pdist = BLI_array_alloca(pdist, temp_segments + 1);
/* Compute the first pass of bezier point coordinates. */
for (int i = 0; i < 3; i++) {
BKE_curve_forward_diff_bezier(control[0][i],
control[1][i],
control[2][i],
control[3][i],
&coords[0][i],
temp_segments,
sizeof(*coords));
}
/* Calculate the length of the polyline at each point. */
pdist[0] = 0.0f;
for (int i = 0; i < temp_segments; i++) {
pdist[i + 1] = pdist[i] + len_v3v3(coords[i], coords[i + 1]);
}
/* Go over distances and calculate new parameter values. */
float dist_step = pdist[temp_segments] / final_segments;
r_t_points[0] = 0.0f;
for (int i = 1, nr = 1; i <= final_segments; i++) {
float dist = i * dist_step;
/* We're looking for location (distance) 'dist' in the array. */
while ((nr < temp_segments) && (dist >= pdist[nr])) {
nr++;
}
float fac = (pdist[nr] - dist) / (pdist[nr] - pdist[nr - 1]);
r_t_points[i] = (nr - fac) / temp_segments;
}
r_t_points[final_segments] = 1.0f;
}
/* Evaluate bezier position and tangent at a specific parameter value
* using the De Casteljau algorithm. */
static void evaluate_cubic_bezier(const float control[4][3],
float t,
float r_pos[3],
float r_tangent[3])
{
float layer1[3][3];
interp_v3_v3v3(layer1[0], control[0], control[1], t);
interp_v3_v3v3(layer1[1], control[1], control[2], t);
interp_v3_v3v3(layer1[2], control[2], control[3], t);
float layer2[2][3];
interp_v3_v3v3(layer2[0], layer1[0], layer1[1], t);
interp_v3_v3v3(layer2[1], layer1[1], layer1[2], t);
sub_v3_v3v3(r_tangent, layer2[1], layer2[0]);
madd_v3_v3v3fl(r_pos, layer2[0], r_tangent, t);
}
/* Get "next" and "prev" bones - these are used for handle calculations. */
2018-12-02 14:32:31 +11:00
void BKE_pchan_bbone_handles_get(bPoseChannel *pchan, bPoseChannel **r_prev, bPoseChannel **r_next)
{
if (pchan->bone->bbone_prev_type == BBONE_HANDLE_AUTO) {
/* Use connected parent. */
if (pchan->bone->flag & BONE_CONNECTED) {
*r_prev = pchan->parent;
}
else {
*r_prev = NULL;
}
}
else {
/* Use the provided bone as prev - leave blank to eliminate this effect altogether. */
*r_prev = pchan->bbone_prev;
}
if (pchan->bone->bbone_next_type == BBONE_HANDLE_AUTO) {
/* Use connected child. */
*r_next = pchan->child;
}
else {
/* Use the provided bone as next - leave blank to eliminate this effect altogether. */
*r_next = pchan->bbone_next;
}
}
/* Compute B-Bone spline parameters for the given channel. */
2018-12-02 14:32:31 +11:00
void BKE_pchan_bbone_spline_params_get(struct bPoseChannel *pchan,
const bool rest,
struct BBoneSplineParameters *param)
{
bPoseChannel *next, *prev;
Bone *bone = pchan->bone;
float imat[4][4], posemat[4][4];
float delta[3];
memset(param, 0, sizeof(*param));
param->segments = bone->segments;
param->length = bone->length;
if (!rest) {
float scale[3];
/* Check if we need to take non-uniform bone scaling into account. */
mat4_to_size(scale, pchan->pose_mat);
if (fabsf(scale[0] - scale[1]) > 1e-6f || fabsf(scale[1] - scale[2]) > 1e-6f) {
param->do_scale = true;
copy_v3_v3(param->scale, scale);
}
}
2018-12-02 14:32:31 +11:00
BKE_pchan_bbone_handles_get(pchan, &prev, &next);
/* Find the handle points, since this is inside bone space, the
2012-04-29 15:47:02 +00:00
* first point = (0, 0, 0)
* last point = (0, length, 0) */
if (rest) {
invert_m4_m4(imat, pchan->bone->arm_mat);
}
else if (param->do_scale) {
copy_m4_m4(posemat, pchan->pose_mat);
normalize_m4(posemat);
invert_m4_m4(imat, posemat);
}
else {
invert_m4_m4(imat, pchan->pose_mat);
}
if (prev) {
float h1[3];
bool done = false;
param->use_prev = true;
/* Transform previous point inside this bone space. */
if (bone->bbone_prev_type == BBONE_HANDLE_RELATIVE) {
/* Use delta movement (from restpose), and apply this relative to the current bone's head. */
Bendy Bones: Advanced B-Bones for Easier + Simple Rigging This commit/patch/branch brings a bunch of powerful new options for B-Bones and for working with B-Bones, making it easier for animators to create their own rigs, using fewer bones (which also means hopefully lighter + faster rigs ;) This functionality was first demoed by Daniel at BConf15 Some highlights from this patch include: * You can now directly control the shape of B-Bones using a series of properties instead of being restricted to trying to indirectly control them through the neighbouring bones. See the "Bendy Bones" panel... * B-Bones can be shaped in EditMode to define a "curved rest pose" for the bone. This is useful for things like eyebrows and mouths/eyelids * You can now make B-Bones use custom bones as their reference bone handles, instead of only using the parent/child bones. To do so, enable the "Use Custom Reference Handles" toggle. If none are specified, then the BBone will only use the Bendy Bone properties. * Constraints Head/Tail option can now slide along the B-Bone shape, instead of just linearly interpolating between the endpoints of the bone. For more details, see: * http://aligorith.blogspot.co.nz/2016/05/bendy-bones-dev-update.html * http://aligorith.blogspot.co.nz/2016/05/an-in-depth-look-at-how-b-bones-work.html -- Credits -- Original Idea: Daniel M Lara (pepeland) Original Patch/Research: Jose Molina Additional Development + Polish: Joshua Leung (aligorith) Testing/Feedback: Daniel M Lara (pepeland), Juan Pablo Bouza (jpbouza)
2016-05-18 03:19:06 +12:00
if (rest) {
/* In restpose, arm_head == pose_head */
zero_v3(param->prev_h);
done = true;
Bendy Bones: Advanced B-Bones for Easier + Simple Rigging This commit/patch/branch brings a bunch of powerful new options for B-Bones and for working with B-Bones, making it easier for animators to create their own rigs, using fewer bones (which also means hopefully lighter + faster rigs ;) This functionality was first demoed by Daniel at BConf15 Some highlights from this patch include: * You can now directly control the shape of B-Bones using a series of properties instead of being restricted to trying to indirectly control them through the neighbouring bones. See the "Bendy Bones" panel... * B-Bones can be shaped in EditMode to define a "curved rest pose" for the bone. This is useful for things like eyebrows and mouths/eyelids * You can now make B-Bones use custom bones as their reference bone handles, instead of only using the parent/child bones. To do so, enable the "Use Custom Reference Handles" toggle. If none are specified, then the BBone will only use the Bendy Bone properties. * Constraints Head/Tail option can now slide along the B-Bone shape, instead of just linearly interpolating between the endpoints of the bone. For more details, see: * http://aligorith.blogspot.co.nz/2016/05/bendy-bones-dev-update.html * http://aligorith.blogspot.co.nz/2016/05/an-in-depth-look-at-how-b-bones-work.html -- Credits -- Original Idea: Daniel M Lara (pepeland) Original Patch/Research: Jose Molina Additional Development + Polish: Joshua Leung (aligorith) Testing/Feedback: Daniel M Lara (pepeland), Juan Pablo Bouza (jpbouza)
2016-05-18 03:19:06 +12:00
}
else {
sub_v3_v3v3(delta, prev->pose_head, prev->bone->arm_head);
sub_v3_v3v3(h1, pchan->pose_head, delta);
}
}
else if (bone->bbone_prev_type == BBONE_HANDLE_TANGENT) {
/* Use bone direction by offsetting so that its tail meets current bone's head */
if (rest) {
sub_v3_v3v3(delta, prev->bone->arm_tail, prev->bone->arm_head);
sub_v3_v3v3(h1, bone->arm_head, delta);
}
else {
sub_v3_v3v3(delta, prev->pose_tail, prev->pose_head);
sub_v3_v3v3(h1, pchan->pose_head, delta);
}
}
Bendy Bones: Advanced B-Bones for Easier + Simple Rigging This commit/patch/branch brings a bunch of powerful new options for B-Bones and for working with B-Bones, making it easier for animators to create their own rigs, using fewer bones (which also means hopefully lighter + faster rigs ;) This functionality was first demoed by Daniel at BConf15 Some highlights from this patch include: * You can now directly control the shape of B-Bones using a series of properties instead of being restricted to trying to indirectly control them through the neighbouring bones. See the "Bendy Bones" panel... * B-Bones can be shaped in EditMode to define a "curved rest pose" for the bone. This is useful for things like eyebrows and mouths/eyelids * You can now make B-Bones use custom bones as their reference bone handles, instead of only using the parent/child bones. To do so, enable the "Use Custom Reference Handles" toggle. If none are specified, then the BBone will only use the Bendy Bone properties. * Constraints Head/Tail option can now slide along the B-Bone shape, instead of just linearly interpolating between the endpoints of the bone. For more details, see: * http://aligorith.blogspot.co.nz/2016/05/bendy-bones-dev-update.html * http://aligorith.blogspot.co.nz/2016/05/an-in-depth-look-at-how-b-bones-work.html -- Credits -- Original Idea: Daniel M Lara (pepeland) Original Patch/Research: Jose Molina Additional Development + Polish: Joshua Leung (aligorith) Testing/Feedback: Daniel M Lara (pepeland), Juan Pablo Bouza (jpbouza)
2016-05-18 03:19:06 +12:00
else {
/* Apply special handling for smoothly joining B-Bone chains */
param->prev_bbone = (prev->bone->segments > 1);
/* Use bone head as absolute position. */
copy_v3_v3(h1, rest ? prev->bone->arm_head : prev->pose_head);
}
if (!done) {
mul_v3_m4v3(param->prev_h, imat, h1);
}
if (!param->prev_bbone) {
/* Find the previous roll to interpolate. */
mul_m4_m4m4(param->prev_mat, imat, rest ? prev->bone->arm_mat : prev->pose_mat);
}
}
if (next) {
float h2[3];
bool done = false;
param->use_next = true;
/* Transform next point inside this bone space. */
if (bone->bbone_next_type == BBONE_HANDLE_RELATIVE) {
/* Use delta movement (from restpose), and apply this relative to the current bone's tail. */
if (rest) {
/* In restpose, arm_head == pose_head */
copy_v3_fl3(param->next_h, 0.0f, param->length, 0.0);
done = true;
}
else {
sub_v3_v3v3(delta, next->pose_head, next->bone->arm_head);
add_v3_v3v3(h2, pchan->pose_tail, delta);
}
}
else if (bone->bbone_next_type == BBONE_HANDLE_TANGENT) {
/* Use bone direction by offsetting so that its head meets current bone's tail */
if (rest) {
sub_v3_v3v3(delta, next->bone->arm_tail, next->bone->arm_head);
add_v3_v3v3(h2, bone->arm_tail, delta);
}
else {
sub_v3_v3v3(delta, next->pose_tail, next->pose_head);
add_v3_v3v3(h2, pchan->pose_tail, delta);
}
}
else {
/* Apply special handling for smoothly joining B-Bone chains */
param->next_bbone = (next->bone->segments > 1);
/* Use bone tail as absolute position. */
copy_v3_v3(h2, rest ? next->bone->arm_tail : next->pose_tail);
}
if (!done) {
mul_v3_m4v3(param->next_h, imat, h2);
}
/* Find the next roll to interpolate as well. */
mul_m4_m4m4(param->next_mat, imat, rest ? next->bone->arm_mat : next->pose_mat);
}
/* Add effects from bbone properties over the top
* - These properties allow users to hand-animate the
* bone curve/shape, without having to resort to using
* extra bones
* - The "bone" level offsets are for defining the restpose
* shape of the bone (e.g. for curved eyebrows for example).
* -> In the viewport, it's needed to define what the rest pose
* looks like
* -> For "rest == 0", we also still need to have it present
* so that we can "cancel out" this restpose when it comes
* time to deform some geometry, it won't cause double transforms.
* - The "pchan" level offsets are the ones that animators actually
* end up animating
*/
{
param->ease1 = bone->ease1 + (!rest ? pchan->ease1 : 0.0f);
param->ease2 = bone->ease2 + (!rest ? pchan->ease2 : 0.0f);
param->roll1 = bone->roll1 + (!rest ? pchan->roll1 : 0.0f);
param->roll2 = bone->roll2 + (!rest ? pchan->roll2 : 0.0f);
if (bone->flag & BONE_ADD_PARENT_END_ROLL) {
if (prev) {
if (prev->bone) {
param->roll1 += prev->bone->roll2;
}
if (!rest) {
param->roll1 += prev->roll2;
}
}
Bendy Bones: Advanced B-Bones for Easier + Simple Rigging This commit/patch/branch brings a bunch of powerful new options for B-Bones and for working with B-Bones, making it easier for animators to create their own rigs, using fewer bones (which also means hopefully lighter + faster rigs ;) This functionality was first demoed by Daniel at BConf15 Some highlights from this patch include: * You can now directly control the shape of B-Bones using a series of properties instead of being restricted to trying to indirectly control them through the neighbouring bones. See the "Bendy Bones" panel... * B-Bones can be shaped in EditMode to define a "curved rest pose" for the bone. This is useful for things like eyebrows and mouths/eyelids * You can now make B-Bones use custom bones as their reference bone handles, instead of only using the parent/child bones. To do so, enable the "Use Custom Reference Handles" toggle. If none are specified, then the BBone will only use the Bendy Bone properties. * Constraints Head/Tail option can now slide along the B-Bone shape, instead of just linearly interpolating between the endpoints of the bone. For more details, see: * http://aligorith.blogspot.co.nz/2016/05/bendy-bones-dev-update.html * http://aligorith.blogspot.co.nz/2016/05/an-in-depth-look-at-how-b-bones-work.html -- Credits -- Original Idea: Daniel M Lara (pepeland) Original Patch/Research: Jose Molina Additional Development + Polish: Joshua Leung (aligorith) Testing/Feedback: Daniel M Lara (pepeland), Juan Pablo Bouza (jpbouza)
2016-05-18 03:19:06 +12:00
}
param->scale_in_x = bone->scale_in_x * (!rest ? pchan->scale_in_x : 1.0f);
param->scale_in_y = bone->scale_in_y * (!rest ? pchan->scale_in_y : 1.0f);
param->scale_out_x = bone->scale_out_x * (!rest ? pchan->scale_out_x : 1.0f);
param->scale_out_y = bone->scale_out_y * (!rest ? pchan->scale_out_y : 1.0f);
/* Extra curve x / y */
param->curve_in_x = bone->curve_in_x + (!rest ? pchan->curve_in_x : 0.0f);
param->curve_in_y = bone->curve_in_y + (!rest ? pchan->curve_in_y : 0.0f);
param->curve_out_x = bone->curve_out_x + (!rest ? pchan->curve_out_x : 0.0f);
param->curve_out_y = bone->curve_out_y + (!rest ? pchan->curve_out_y : 0.0f);
}
}
/* Fills the array with the desired amount of bone->segments elements.
* This calculation is done within unit bone space. */
void BKE_pchan_bbone_spline_setup(bPoseChannel *pchan,
const bool rest,
const bool for_deform,
Mat4 *result_array)
{
BBoneSplineParameters param;
2018-12-02 14:32:31 +11:00
BKE_pchan_bbone_spline_params_get(pchan, rest, &param);
pchan->bone->segments = BKE_pchan_bbone_spline_compute(&param, for_deform, result_array);
}
/* Computes the bezier handle vectors and rolls coming from custom handles. */
2018-12-02 14:32:31 +11:00
void BKE_pchan_bbone_handles_compute(const BBoneSplineParameters *param,
float h1[3],
float *r_roll1,
float h2[3],
float *r_roll2,
bool ease,
bool offsets)
{
float mat3[3][3];
float length = param->length;
float epsilon = 1e-5 * length;
if (param->do_scale) {
length *= param->scale[1];
}
*r_roll1 = *r_roll2 = 0.0f;
if (param->use_prev) {
copy_v3_v3(h1, param->prev_h);
if (param->prev_bbone) {
/* If previous bone is B-bone too, use average handle direction. */
h1[1] -= length;
}
if (normalize_v3(h1) < epsilon) {
copy_v3_fl3(h1, 0.0f, -1.0f, 0.0f);
}
negate_v3(h1);
if (!param->prev_bbone) {
/* Find the previous roll to interpolate. */
copy_m3_m4(mat3, param->prev_mat);
mat3_vec_to_roll(mat3, h1, r_roll1);
}
}
else {
h1[0] = 0.0f;
h1[1] = 1.0;
h1[2] = 0.0f;
}
if (param->use_next) {
copy_v3_v3(h2, param->next_h);
/* If next bone is B-bone too, use average handle direction. */
if (param->next_bbone) {
2012-10-14 13:08:19 +00:00
/* pass */
}
else {
h2[1] -= length;
2012-10-14 13:08:19 +00:00
}
if (normalize_v3(h2) < epsilon) {
copy_v3_fl3(h2, 0.0f, 1.0f, 0.0f);
}
/* Find the next roll to interpolate as well. */
copy_m3_m4(mat3, param->next_mat);
mat3_vec_to_roll(mat3, h2, r_roll2);
}
else {
h2[0] = 0.0f;
h2[1] = 1.0f;
h2[2] = 0.0f;
}
if (ease) {
const float circle_factor = length * (cubic_tangent_factor_circle_v3(h1, h2) / 0.75f);
const float hlength1 = param->ease1 * circle_factor;
const float hlength2 = param->ease2 * circle_factor;
/* and only now negate h2 */
mul_v3_fl(h1, hlength1);
mul_v3_fl(h2, -hlength2);
}
Bendy Bones: Advanced B-Bones for Easier + Simple Rigging This commit/patch/branch brings a bunch of powerful new options for B-Bones and for working with B-Bones, making it easier for animators to create their own rigs, using fewer bones (which also means hopefully lighter + faster rigs ;) This functionality was first demoed by Daniel at BConf15 Some highlights from this patch include: * You can now directly control the shape of B-Bones using a series of properties instead of being restricted to trying to indirectly control them through the neighbouring bones. See the "Bendy Bones" panel... * B-Bones can be shaped in EditMode to define a "curved rest pose" for the bone. This is useful for things like eyebrows and mouths/eyelids * You can now make B-Bones use custom bones as their reference bone handles, instead of only using the parent/child bones. To do so, enable the "Use Custom Reference Handles" toggle. If none are specified, then the BBone will only use the Bendy Bone properties. * Constraints Head/Tail option can now slide along the B-Bone shape, instead of just linearly interpolating between the endpoints of the bone. For more details, see: * http://aligorith.blogspot.co.nz/2016/05/bendy-bones-dev-update.html * http://aligorith.blogspot.co.nz/2016/05/an-in-depth-look-at-how-b-bones-work.html -- Credits -- Original Idea: Daniel M Lara (pepeland) Original Patch/Research: Jose Molina Additional Development + Polish: Joshua Leung (aligorith) Testing/Feedback: Daniel M Lara (pepeland), Juan Pablo Bouza (jpbouza)
2016-05-18 03:19:06 +12:00
/* Add effects from bbone properties over the top
* - These properties allow users to hand-animate the
* bone curve/shape, without having to resort to using
* extra bones
2020-03-11 21:39:56 +11:00
* - The "bone" level offsets are for defining the rest-pose
Bendy Bones: Advanced B-Bones for Easier + Simple Rigging This commit/patch/branch brings a bunch of powerful new options for B-Bones and for working with B-Bones, making it easier for animators to create their own rigs, using fewer bones (which also means hopefully lighter + faster rigs ;) This functionality was first demoed by Daniel at BConf15 Some highlights from this patch include: * You can now directly control the shape of B-Bones using a series of properties instead of being restricted to trying to indirectly control them through the neighbouring bones. See the "Bendy Bones" panel... * B-Bones can be shaped in EditMode to define a "curved rest pose" for the bone. This is useful for things like eyebrows and mouths/eyelids * You can now make B-Bones use custom bones as their reference bone handles, instead of only using the parent/child bones. To do so, enable the "Use Custom Reference Handles" toggle. If none are specified, then the BBone will only use the Bendy Bone properties. * Constraints Head/Tail option can now slide along the B-Bone shape, instead of just linearly interpolating between the endpoints of the bone. For more details, see: * http://aligorith.blogspot.co.nz/2016/05/bendy-bones-dev-update.html * http://aligorith.blogspot.co.nz/2016/05/an-in-depth-look-at-how-b-bones-work.html -- Credits -- Original Idea: Daniel M Lara (pepeland) Original Patch/Research: Jose Molina Additional Development + Polish: Joshua Leung (aligorith) Testing/Feedback: Daniel M Lara (pepeland), Juan Pablo Bouza (jpbouza)
2016-05-18 03:19:06 +12:00
* shape of the bone (e.g. for curved eyebrows for example).
* -> In the viewport, it's needed to define what the rest pose
* looks like
* -> For "rest == 0", we also still need to have it present
2020-03-11 21:39:56 +11:00
* so that we can "cancel out" this rest-pose when it comes
Bendy Bones: Advanced B-Bones for Easier + Simple Rigging This commit/patch/branch brings a bunch of powerful new options for B-Bones and for working with B-Bones, making it easier for animators to create their own rigs, using fewer bones (which also means hopefully lighter + faster rigs ;) This functionality was first demoed by Daniel at BConf15 Some highlights from this patch include: * You can now directly control the shape of B-Bones using a series of properties instead of being restricted to trying to indirectly control them through the neighbouring bones. See the "Bendy Bones" panel... * B-Bones can be shaped in EditMode to define a "curved rest pose" for the bone. This is useful for things like eyebrows and mouths/eyelids * You can now make B-Bones use custom bones as their reference bone handles, instead of only using the parent/child bones. To do so, enable the "Use Custom Reference Handles" toggle. If none are specified, then the BBone will only use the Bendy Bone properties. * Constraints Head/Tail option can now slide along the B-Bone shape, instead of just linearly interpolating between the endpoints of the bone. For more details, see: * http://aligorith.blogspot.co.nz/2016/05/bendy-bones-dev-update.html * http://aligorith.blogspot.co.nz/2016/05/an-in-depth-look-at-how-b-bones-work.html -- Credits -- Original Idea: Daniel M Lara (pepeland) Original Patch/Research: Jose Molina Additional Development + Polish: Joshua Leung (aligorith) Testing/Feedback: Daniel M Lara (pepeland), Juan Pablo Bouza (jpbouza)
2016-05-18 03:19:06 +12:00
* time to deform some geometry, it won't cause double transforms.
* - The "pchan" level offsets are the ones that animators actually
* end up animating
*/
if (offsets) {
/* Add extra rolls. */
*r_roll1 += param->roll1;
*r_roll2 += param->roll2;
/* Extra curve x / y */
/* NOTE:
* Scale correction factors here are to compensate for some random floating-point glitches
* when scaling up the bone or its parent by a factor of approximately 8.15/6, which results
* in the bone length getting scaled up too (from 1 to 8), causing the curve to flatten out.
Bendy Bones: Advanced B-Bones for Easier + Simple Rigging This commit/patch/branch brings a bunch of powerful new options for B-Bones and for working with B-Bones, making it easier for animators to create their own rigs, using fewer bones (which also means hopefully lighter + faster rigs ;) This functionality was first demoed by Daniel at BConf15 Some highlights from this patch include: * You can now directly control the shape of B-Bones using a series of properties instead of being restricted to trying to indirectly control them through the neighbouring bones. See the "Bendy Bones" panel... * B-Bones can be shaped in EditMode to define a "curved rest pose" for the bone. This is useful for things like eyebrows and mouths/eyelids * You can now make B-Bones use custom bones as their reference bone handles, instead of only using the parent/child bones. To do so, enable the "Use Custom Reference Handles" toggle. If none are specified, then the BBone will only use the Bendy Bone properties. * Constraints Head/Tail option can now slide along the B-Bone shape, instead of just linearly interpolating between the endpoints of the bone. For more details, see: * http://aligorith.blogspot.co.nz/2016/05/bendy-bones-dev-update.html * http://aligorith.blogspot.co.nz/2016/05/an-in-depth-look-at-how-b-bones-work.html -- Credits -- Original Idea: Daniel M Lara (pepeland) Original Patch/Research: Jose Molina Additional Development + Polish: Joshua Leung (aligorith) Testing/Feedback: Daniel M Lara (pepeland), Juan Pablo Bouza (jpbouza)
2016-05-18 03:19:06 +12:00
*/
const float xscale_correction = (param->do_scale) ? param->scale[0] : 1.0f;
const float yscale_correction = (param->do_scale) ? param->scale[2] : 1.0f;
h1[0] += param->curve_in_x * xscale_correction;
h1[2] += param->curve_in_y * yscale_correction;
h2[0] += param->curve_out_x * xscale_correction;
h2[2] += param->curve_out_y * yscale_correction;
}
Bendy Bones: Advanced B-Bones for Easier + Simple Rigging This commit/patch/branch brings a bunch of powerful new options for B-Bones and for working with B-Bones, making it easier for animators to create their own rigs, using fewer bones (which also means hopefully lighter + faster rigs ;) This functionality was first demoed by Daniel at BConf15 Some highlights from this patch include: * You can now directly control the shape of B-Bones using a series of properties instead of being restricted to trying to indirectly control them through the neighbouring bones. See the "Bendy Bones" panel... * B-Bones can be shaped in EditMode to define a "curved rest pose" for the bone. This is useful for things like eyebrows and mouths/eyelids * You can now make B-Bones use custom bones as their reference bone handles, instead of only using the parent/child bones. To do so, enable the "Use Custom Reference Handles" toggle. If none are specified, then the BBone will only use the Bendy Bone properties. * Constraints Head/Tail option can now slide along the B-Bone shape, instead of just linearly interpolating between the endpoints of the bone. For more details, see: * http://aligorith.blogspot.co.nz/2016/05/bendy-bones-dev-update.html * http://aligorith.blogspot.co.nz/2016/05/an-in-depth-look-at-how-b-bones-work.html -- Credits -- Original Idea: Daniel M Lara (pepeland) Original Patch/Research: Jose Molina Additional Development + Polish: Joshua Leung (aligorith) Testing/Feedback: Daniel M Lara (pepeland), Juan Pablo Bouza (jpbouza)
2016-05-18 03:19:06 +12:00
}
static void make_bbone_spline_matrix(BBoneSplineParameters *param,
2019-09-14 08:10:50 +10:00
const float scalemats[2][4][4],
const float pos[3],
const float axis[3],
float roll,
float scalex,
float scaley,
float result[4][4])
{
float mat3[3][3];
vec_roll_to_mat3(axis, roll, mat3);
copy_m4_m3(result, mat3);
copy_v3_v3(result[3], pos);
if (param->do_scale) {
/* Correct for scaling when this matrix is used in scaled space. */
mul_m4_series(result, scalemats[0], result, scalemats[1]);
}
/* BBone scale... */
mul_v3_fl(result[0], scalex);
mul_v3_fl(result[2], scaley);
}
/* Fade from first to second derivative when the handle is very short. */
static void ease_handle_axis(const float deriv1[3], const float deriv2[3], float r_axis[3])
{
const float gap = 0.1f;
copy_v3_v3(r_axis, deriv1);
float len1 = len_squared_v3(deriv1), len2 = len_squared_v3(deriv2);
float ratio = len1 / len2;
if (ratio < gap * gap) {
madd_v3_v3fl(r_axis, deriv2, gap - sqrtf(ratio));
}
}
/* Fills the array with the desired amount of bone->segments elements.
* This calculation is done within unit bone space. */
int BKE_pchan_bbone_spline_compute(BBoneSplineParameters *param,
const bool for_deform,
Mat4 *result_array)
{
float scalemats[2][4][4];
float bezt_controls[4][3];
float h1[3], roll1, h2[3], roll2, prev[3], cur[3], axis[3];
float length = param->length;
if (param->do_scale) {
size_to_mat4(scalemats[1], param->scale);
invert_m4_m4(scalemats[0], scalemats[1]);
length *= param->scale[1];
}
2018-12-02 14:32:31 +11:00
BKE_pchan_bbone_handles_compute(param, h1, &roll1, h2, &roll2, true, true);
2018-06-17 17:05:51 +02:00
/* Make curve. */
CLAMP_MAX(param->segments, MAX_BBONE_SUBDIV);
copy_v3_fl3(bezt_controls[3], 0.0f, length, 0.0f);
add_v3_v3v3(bezt_controls[2], bezt_controls[3], h2);
copy_v3_v3(bezt_controls[1], h1);
zero_v3(bezt_controls[0]);
float bezt_points[MAX_BBONE_SUBDIV + 1];
equalize_cubic_bezier(bezt_controls, MAX_BBONE_SUBDIV, param->segments, bezt_points);
2018-06-17 17:05:51 +02:00
/* Deformation uses N+1 matrices computed at points between the segments. */
if (for_deform) {
/* Bezier derivatives. */
float bezt_deriv1[3][3], bezt_deriv2[2][3];
2018-06-17 17:05:51 +02:00
for (int i = 0; i < 3; i++) {
sub_v3_v3v3(bezt_deriv1[i], bezt_controls[i + 1], bezt_controls[i]);
}
for (int i = 0; i < 2; i++) {
sub_v3_v3v3(bezt_deriv2[i], bezt_deriv1[i + 1], bezt_deriv1[i]);
}
2018-06-17 17:05:51 +02:00
/* End points require special handling to fix zero length handles. */
ease_handle_axis(bezt_deriv1[0], bezt_deriv2[0], axis);
make_bbone_spline_matrix(param,
scalemats,
bezt_controls[0],
axis,
roll1,
param->scale_in_x,
param->scale_in_y,
result_array[0].mat);
2018-06-17 17:05:51 +02:00
for (int a = 1; a < param->segments; a++) {
evaluate_cubic_bezier(bezt_controls, bezt_points[a], cur, axis);
2018-06-17 17:05:51 +02:00
float fac = ((float)a) / param->segments;
float roll = interpf(roll2, roll1, fac);
float scalex = interpf(param->scale_out_x, param->scale_in_x, fac);
float scaley = interpf(param->scale_out_y, param->scale_in_y, fac);
2018-06-17 17:05:51 +02:00
make_bbone_spline_matrix(
param, scalemats, cur, axis, roll, scalex, scaley, result_array[a].mat);
}
2018-06-17 17:05:51 +02:00
negate_v3(bezt_deriv2[1]);
ease_handle_axis(bezt_deriv1[2], bezt_deriv2[1], axis);
make_bbone_spline_matrix(param,
scalemats,
bezt_controls[3],
axis,
roll2,
param->scale_out_x,
param->scale_out_y,
result_array[param->segments].mat);
}
/* Other code (e.g. display) uses matrices for the segments themselves. */
else {
zero_v3(prev);
for (int a = 0; a < param->segments; a++) {
evaluate_cubic_bezier(bezt_controls, bezt_points[a + 1], cur, axis);
2018-06-17 17:05:51 +02:00
sub_v3_v3v3(axis, cur, prev);
2018-06-17 17:05:51 +02:00
float fac = (a + 0.5f) / param->segments;
float roll = interpf(roll2, roll1, fac);
float scalex = interpf(param->scale_out_x, param->scale_in_x, fac);
float scaley = interpf(param->scale_out_y, param->scale_in_y, fac);
make_bbone_spline_matrix(
param, scalemats, prev, axis, roll, scalex, scaley, result_array[a].mat);
copy_v3_v3(prev, cur);
Bendy Bones: Advanced B-Bones for Easier + Simple Rigging This commit/patch/branch brings a bunch of powerful new options for B-Bones and for working with B-Bones, making it easier for animators to create their own rigs, using fewer bones (which also means hopefully lighter + faster rigs ;) This functionality was first demoed by Daniel at BConf15 Some highlights from this patch include: * You can now directly control the shape of B-Bones using a series of properties instead of being restricted to trying to indirectly control them through the neighbouring bones. See the "Bendy Bones" panel... * B-Bones can be shaped in EditMode to define a "curved rest pose" for the bone. This is useful for things like eyebrows and mouths/eyelids * You can now make B-Bones use custom bones as their reference bone handles, instead of only using the parent/child bones. To do so, enable the "Use Custom Reference Handles" toggle. If none are specified, then the BBone will only use the Bendy Bone properties. * Constraints Head/Tail option can now slide along the B-Bone shape, instead of just linearly interpolating between the endpoints of the bone. For more details, see: * http://aligorith.blogspot.co.nz/2016/05/bendy-bones-dev-update.html * http://aligorith.blogspot.co.nz/2016/05/an-in-depth-look-at-how-b-bones-work.html -- Credits -- Original Idea: Daniel M Lara (pepeland) Original Patch/Research: Jose Molina Additional Development + Polish: Joshua Leung (aligorith) Testing/Feedback: Daniel M Lara (pepeland), Juan Pablo Bouza (jpbouza)
2016-05-18 03:19:06 +12:00
}
}
return param->segments;
}
static void allocate_bbone_cache(bPoseChannel *pchan, int segments)
2002-10-12 11:37:38 +00:00
{
bPoseChannel_Runtime *runtime = &pchan->runtime;
if (runtime->bbone_segments != segments) {
BKE_pose_channel_free_bbone_cache(runtime);
runtime->bbone_segments = segments;
runtime->bbone_rest_mats = MEM_malloc_arrayN(
sizeof(Mat4), 1 + (uint)segments, "bPoseChannel_Runtime::bbone_rest_mats");
runtime->bbone_pose_mats = MEM_malloc_arrayN(
sizeof(Mat4), 1 + (uint)segments, "bPoseChannel_Runtime::bbone_pose_mats");
runtime->bbone_deform_mats = MEM_malloc_arrayN(
sizeof(Mat4), 2 + (uint)segments, "bPoseChannel_Runtime::bbone_deform_mats");
runtime->bbone_dual_quats = MEM_malloc_arrayN(
sizeof(DualQuat), 1 + (uint)segments, "bPoseChannel_Runtime::bbone_dual_quats");
}
}
/** Compute and cache the B-Bone shape in the channel runtime struct. */
2018-12-02 14:32:31 +11:00
void BKE_pchan_bbone_segments_cache_compute(bPoseChannel *pchan)
{
bPoseChannel_Runtime *runtime = &pchan->runtime;
Bone *bone = pchan->bone;
int segments = bone->segments;
BLI_assert(segments > 1);
/* Allocate the cache if needed. */
allocate_bbone_cache(pchan, segments);
/* Compute the shape. */
Mat4 *b_bone = runtime->bbone_pose_mats;
Mat4 *b_bone_rest = runtime->bbone_rest_mats;
Mat4 *b_bone_mats = runtime->bbone_deform_mats;
DualQuat *b_bone_dual_quats = runtime->bbone_dual_quats;
int a;
BKE_pchan_bbone_spline_setup(pchan, false, true, b_bone);
BKE_pchan_bbone_spline_setup(pchan, true, true, b_bone_rest);
/* Compute deform matrices. */
/* first matrix is the inverse arm_mat, to bring points in local bone space
* for finding out which segment it belongs to */
invert_m4_m4(b_bone_mats[0].mat, bone->arm_mat);
/* then we make the b_bone_mats:
* - first transform to local bone space
* - translate over the curve to the bbone mat space
* - transform with b_bone matrix
* - transform back into global space */
for (a = 0; a <= bone->segments; a++) {
float tmat[4][4];
invert_m4_m4(tmat, b_bone_rest[a].mat);
mul_m4_series(b_bone_mats[a + 1].mat,
pchan->chan_mat,
bone->arm_mat,
b_bone[a].mat,
tmat,
b_bone_mats[0].mat);
/* Compute the orthonormal object space rest matrix of the segment. */
mul_m4_m4m4(tmat, bone->arm_mat, b_bone_rest[a].mat);
normalize_m4(tmat);
mat4_to_dquat(&b_bone_dual_quats[a], tmat, b_bone_mats[a + 1].mat);
}
}
/** Copy cached B-Bone segments from one channel to another */
2018-12-02 14:32:31 +11:00
void BKE_pchan_bbone_segments_cache_copy(bPoseChannel *pchan, bPoseChannel *pchan_from)
{
bPoseChannel_Runtime *runtime = &pchan->runtime;
bPoseChannel_Runtime *runtime_from = &pchan_from->runtime;
int segments = runtime_from->bbone_segments;
if (segments <= 1) {
BKE_pose_channel_free_bbone_cache(&pchan->runtime);
}
else {
allocate_bbone_cache(pchan, segments);
memcpy(runtime->bbone_rest_mats, runtime_from->bbone_rest_mats, sizeof(Mat4) * (1 + segments));
memcpy(runtime->bbone_pose_mats, runtime_from->bbone_pose_mats, sizeof(Mat4) * (1 + segments));
memcpy(runtime->bbone_deform_mats,
runtime_from->bbone_deform_mats,
sizeof(Mat4) * (2 + segments));
memcpy(runtime->bbone_dual_quats,
runtime_from->bbone_dual_quats,
sizeof(DualQuat) * (1 + segments));
}
}
2002-10-12 11:37:38 +00:00
/**
* Calculate index and blend factor for the two B-Bone segment nodes
* affecting the point at 0 <= pos <= 1.
*/
void BKE_pchan_bbone_deform_segment_index(const bPoseChannel *pchan,
float pos,
int *r_index,
float *r_blend_next)
{
int segments = pchan->bone->segments;
2018-06-17 17:05:51 +02:00
CLAMP(pos, 0.0f, 1.0f);
/* Calculate the indices of the 2 affecting b_bone segments.
* Integer part is the first segment's index.
* Integer part plus 1 is the second segment's index.
* Fractional part is the blend factor. */
float pre_blend = pos * (float)segments;
int index = (int)floorf(pre_blend);
CLAMP(index, 0, segments - 1);
float blend = pre_blend - index;
CLAMP(blend, 0.0f, 1.0f);
2018-06-17 17:05:51 +02:00
*r_index = index;
*r_blend_next = blend;
}
/** \} */
/* -------------------------------------------------------------------- */
/** \name Bone Space to Space Conversion API
* \{ */
void get_objectspace_bone_matrix(struct Bone *bone,
float M_accumulatedMatrix[4][4],
int UNUSED(root),
int UNUSED(posed))
2002-10-12 11:37:38 +00:00
{
copy_m4_m4(M_accumulatedMatrix, bone->arm_mat);
2002-10-12 11:37:38 +00:00
}
/* Convert World-Space Matrix to Pose-Space Matrix */
void BKE_armature_mat_world_to_pose(Object *ob, const float inmat[4][4], float outmat[4][4])
{
float obmat[4][4];
/* prevent crashes */
if (ob == NULL) {
return;
}
/* get inverse of (armature) object's matrix */
invert_m4_m4(obmat, ob->obmat);
/* multiply given matrix by object's-inverse to find pose-space matrix */
mul_m4_m4m4(outmat, inmat, obmat);
}
/* Convert World-Space Location to Pose-Space Location
* NOTE: this cannot be used to convert to pose-space location of the supplied
* pose-channel into its local space (i.e. 'visual'-keyframing) */
void BKE_armature_loc_world_to_pose(Object *ob, const float inloc[3], float outloc[3])
{
float xLocMat[4][4];
float nLocMat[4][4];
/* build matrix for location */
unit_m4(xLocMat);
copy_v3_v3(xLocMat[3], inloc);
/* get bone-space cursor matrix and extract location */
BKE_armature_mat_world_to_pose(ob, xLocMat, nLocMat);
copy_v3_v3(outloc, nLocMat[3]);
}
/** \} */
/* -------------------------------------------------------------------- */
/** \name Bone Matrix Calculation API
* \{ */
/* Simple helper, computes the offset bone matrix.
* offs_bone = yoffs(b-1) + root(b) + bonemat(b). */
2018-12-20 17:30:04 +11:00
void BKE_bone_offset_matrix_get(const Bone *bone, float offs_bone[4][4])
{
BLI_assert(bone->parent != NULL);
/* Bone transform itself. */
copy_m4_m3(offs_bone, bone->bone_mat);
/* The bone's root offset (is in the parent's coordinate system). */
copy_v3_v3(offs_bone[3], bone->head);
/* Get the length translation of parent (length along y axis). */
offs_bone[3][1] += bone->parent->length;
}
/* Construct the matrices (rot/scale and loc)
* to apply the PoseChannels into the armature (object) space.
* I.e. (roughly) the "pose_mat(b-1) * yoffs(b-1) * d_root(b) * bone_mat(b)" in the
* pose_mat(b)= pose_mat(b-1) * yoffs(b-1) * d_root(b) * bone_mat(b) * chan_mat(b)
* ...function.
*
* This allows to get the transformations of a bone in its object space,
* *before* constraints (and IK) get applied (used by pose evaluation code).
* And reverse: to find pchan transformations needed to place a bone at a given loc/rot/scale
* in object space (used by interactive transform, and snapping code).
*
* Note that, with the HINGE/NO_SCALE/NO_LOCAL_LOCATION options, the location matrix
* will differ from the rotation/scale matrix...
*
* NOTE: This cannot be used to convert to pose-space transforms of the supplied
* pose-channel into its local space (i.e. 'visual'-keyframing).
* (note: I don't understand that, so I keep it :p --mont29).
*/
2018-12-20 17:30:04 +11:00
void BKE_bone_parent_transform_calc_from_pchan(const bPoseChannel *pchan,
BoneParentTransform *r_bpt)
{
2018-12-20 17:30:04 +11:00
const Bone *bone, *parbone;
const bPoseChannel *parchan;
/* set up variables for quicker access below */
bone = pchan->bone;
parbone = bone->parent;
parchan = pchan->parent;
if (parchan) {
float offs_bone[4][4];
/* yoffs(b-1) + root(b) + bonemat(b). */
2018-12-20 17:30:04 +11:00
BKE_bone_offset_matrix_get(bone, offs_bone);
Armature: add Inherit Scale options to remove shear or average the scale. As an inherent property of matrix-based transformation math, non- uniform scaling of a parent bone induces shear into the transform matrix of any rotated child. Such matrices cannot be cleanly decomposed into a combination of location/rotation/scale, which causes issues for rigging and animation tools. Blender bones have options to exclude rotation and/or scale from the inherited transformation, but don't have any support for removing the often undesired shear component. That goal requires replacing simple parenting with a combination of multiple bones and constraints. The same is true about the goal of inheriting some scale, but completely avoiding shear. This patch replaces the old Inherit Scale checkbox with a enum that supports multiple options: * Full: inherit all effects of scale, like with enabled Inherit Scale. * Fix Shear: removes shear from the final inherited transformation. The cleanup math is specifically designed to preserve the main axis of the bone, its length and total volume, and minimally affect roll on average. It however will not prevent reappearance of shear due to local rotation of the child or its children. * Average: inherit uniform scale that represents the parent volume. This is the simplest foolproof solution that will inherit some scale without ever causing shear. * None: completely remove scale and shear. * None (Legacy): old disabled Inherit Scale checkbox. This mode does not handle parent shear in any way, so the child is likely to end up having both scale and shear. It is retained for backward compatibility. Since many rigging-related addons access the use_inherit_scale property from Python, it is retained as a backward compatibility stub that provides the old functionality. As a side effect of reworking the code, this also fixes a matrix multiplication order bug in the Inherit Rotation code, which caused the parent local scale to be applied in world space. In rigger opinion this option is useless in production rigs, so this fix should not be a problem. Reviewers: brecht Differential Revision: https://developer.blender.org/D5588
2019-09-04 10:10:27 +03:00
BKE_bone_parent_transform_calc_from_matrices(bone->flag,
bone->inherit_scale_mode,
offs_bone,
parbone->arm_mat,
parchan->pose_mat,
r_bpt);
}
else {
Armature: add Inherit Scale options to remove shear or average the scale. As an inherent property of matrix-based transformation math, non- uniform scaling of a parent bone induces shear into the transform matrix of any rotated child. Such matrices cannot be cleanly decomposed into a combination of location/rotation/scale, which causes issues for rigging and animation tools. Blender bones have options to exclude rotation and/or scale from the inherited transformation, but don't have any support for removing the often undesired shear component. That goal requires replacing simple parenting with a combination of multiple bones and constraints. The same is true about the goal of inheriting some scale, but completely avoiding shear. This patch replaces the old Inherit Scale checkbox with a enum that supports multiple options: * Full: inherit all effects of scale, like with enabled Inherit Scale. * Fix Shear: removes shear from the final inherited transformation. The cleanup math is specifically designed to preserve the main axis of the bone, its length and total volume, and minimally affect roll on average. It however will not prevent reappearance of shear due to local rotation of the child or its children. * Average: inherit uniform scale that represents the parent volume. This is the simplest foolproof solution that will inherit some scale without ever causing shear. * None: completely remove scale and shear. * None (Legacy): old disabled Inherit Scale checkbox. This mode does not handle parent shear in any way, so the child is likely to end up having both scale and shear. It is retained for backward compatibility. Since many rigging-related addons access the use_inherit_scale property from Python, it is retained as a backward compatibility stub that provides the old functionality. As a side effect of reworking the code, this also fixes a matrix multiplication order bug in the Inherit Rotation code, which caused the parent local scale to be applied in world space. In rigger opinion this option is useless in production rigs, so this fix should not be a problem. Reviewers: brecht Differential Revision: https://developer.blender.org/D5588
2019-09-04 10:10:27 +03:00
BKE_bone_parent_transform_calc_from_matrices(
bone->flag, bone->inherit_scale_mode, bone->arm_mat, NULL, NULL, r_bpt);
}
}
/* Compute the parent transform using data decoupled from specific data structures.
*
* bone_flag: Bone->flag containing settings
* offs_bone: delta from parent to current arm_mat (or just arm_mat if no parent)
* parent_arm_mat, parent_pose_mat: arm_mat and pose_mat of parent, or NULL
* r_bpt: OUTPUT parent transform */
2018-12-20 17:30:04 +11:00
void BKE_bone_parent_transform_calc_from_matrices(int bone_flag,
Armature: add Inherit Scale options to remove shear or average the scale. As an inherent property of matrix-based transformation math, non- uniform scaling of a parent bone induces shear into the transform matrix of any rotated child. Such matrices cannot be cleanly decomposed into a combination of location/rotation/scale, which causes issues for rigging and animation tools. Blender bones have options to exclude rotation and/or scale from the inherited transformation, but don't have any support for removing the often undesired shear component. That goal requires replacing simple parenting with a combination of multiple bones and constraints. The same is true about the goal of inheriting some scale, but completely avoiding shear. This patch replaces the old Inherit Scale checkbox with a enum that supports multiple options: * Full: inherit all effects of scale, like with enabled Inherit Scale. * Fix Shear: removes shear from the final inherited transformation. The cleanup math is specifically designed to preserve the main axis of the bone, its length and total volume, and minimally affect roll on average. It however will not prevent reappearance of shear due to local rotation of the child or its children. * Average: inherit uniform scale that represents the parent volume. This is the simplest foolproof solution that will inherit some scale without ever causing shear. * None: completely remove scale and shear. * None (Legacy): old disabled Inherit Scale checkbox. This mode does not handle parent shear in any way, so the child is likely to end up having both scale and shear. It is retained for backward compatibility. Since many rigging-related addons access the use_inherit_scale property from Python, it is retained as a backward compatibility stub that provides the old functionality. As a side effect of reworking the code, this also fixes a matrix multiplication order bug in the Inherit Rotation code, which caused the parent local scale to be applied in world space. In rigger opinion this option is useless in production rigs, so this fix should not be a problem. Reviewers: brecht Differential Revision: https://developer.blender.org/D5588
2019-09-04 10:10:27 +03:00
int inherit_scale_mode,
2018-12-20 17:30:04 +11:00
const float offs_bone[4][4],
const float parent_arm_mat[4][4],
const float parent_pose_mat[4][4],
BoneParentTransform *r_bpt)
{
copy_v3_fl(r_bpt->post_scale, 1.0f);
if (parent_pose_mat) {
Armature: add Inherit Scale options to remove shear or average the scale. As an inherent property of matrix-based transformation math, non- uniform scaling of a parent bone induces shear into the transform matrix of any rotated child. Such matrices cannot be cleanly decomposed into a combination of location/rotation/scale, which causes issues for rigging and animation tools. Blender bones have options to exclude rotation and/or scale from the inherited transformation, but don't have any support for removing the often undesired shear component. That goal requires replacing simple parenting with a combination of multiple bones and constraints. The same is true about the goal of inheriting some scale, but completely avoiding shear. This patch replaces the old Inherit Scale checkbox with a enum that supports multiple options: * Full: inherit all effects of scale, like with enabled Inherit Scale. * Fix Shear: removes shear from the final inherited transformation. The cleanup math is specifically designed to preserve the main axis of the bone, its length and total volume, and minimally affect roll on average. It however will not prevent reappearance of shear due to local rotation of the child or its children. * Average: inherit uniform scale that represents the parent volume. This is the simplest foolproof solution that will inherit some scale without ever causing shear. * None: completely remove scale and shear. * None (Legacy): old disabled Inherit Scale checkbox. This mode does not handle parent shear in any way, so the child is likely to end up having both scale and shear. It is retained for backward compatibility. Since many rigging-related addons access the use_inherit_scale property from Python, it is retained as a backward compatibility stub that provides the old functionality. As a side effect of reworking the code, this also fixes a matrix multiplication order bug in the Inherit Rotation code, which caused the parent local scale to be applied in world space. In rigger opinion this option is useless in production rigs, so this fix should not be a problem. Reviewers: brecht Differential Revision: https://developer.blender.org/D5588
2019-09-04 10:10:27 +03:00
const bool use_rotation = (bone_flag & BONE_HINGE) == 0;
const bool full_transform = use_rotation && inherit_scale_mode == BONE_INHERIT_SCALE_FULL;
/* Compose the rotscale matrix for this bone. */
Armature: add Inherit Scale options to remove shear or average the scale. As an inherent property of matrix-based transformation math, non- uniform scaling of a parent bone induces shear into the transform matrix of any rotated child. Such matrices cannot be cleanly decomposed into a combination of location/rotation/scale, which causes issues for rigging and animation tools. Blender bones have options to exclude rotation and/or scale from the inherited transformation, but don't have any support for removing the often undesired shear component. That goal requires replacing simple parenting with a combination of multiple bones and constraints. The same is true about the goal of inheriting some scale, but completely avoiding shear. This patch replaces the old Inherit Scale checkbox with a enum that supports multiple options: * Full: inherit all effects of scale, like with enabled Inherit Scale. * Fix Shear: removes shear from the final inherited transformation. The cleanup math is specifically designed to preserve the main axis of the bone, its length and total volume, and minimally affect roll on average. It however will not prevent reappearance of shear due to local rotation of the child or its children. * Average: inherit uniform scale that represents the parent volume. This is the simplest foolproof solution that will inherit some scale without ever causing shear. * None: completely remove scale and shear. * None (Legacy): old disabled Inherit Scale checkbox. This mode does not handle parent shear in any way, so the child is likely to end up having both scale and shear. It is retained for backward compatibility. Since many rigging-related addons access the use_inherit_scale property from Python, it is retained as a backward compatibility stub that provides the old functionality. As a side effect of reworking the code, this also fixes a matrix multiplication order bug in the Inherit Rotation code, which caused the parent local scale to be applied in world space. In rigger opinion this option is useless in production rigs, so this fix should not be a problem. Reviewers: brecht Differential Revision: https://developer.blender.org/D5588
2019-09-04 10:10:27 +03:00
if (full_transform) {
/* Parent pose rotation and scale. */
mul_m4_m4m4(r_bpt->rotscale_mat, parent_pose_mat, offs_bone);
}
Armature: add Inherit Scale options to remove shear or average the scale. As an inherent property of matrix-based transformation math, non- uniform scaling of a parent bone induces shear into the transform matrix of any rotated child. Such matrices cannot be cleanly decomposed into a combination of location/rotation/scale, which causes issues for rigging and animation tools. Blender bones have options to exclude rotation and/or scale from the inherited transformation, but don't have any support for removing the often undesired shear component. That goal requires replacing simple parenting with a combination of multiple bones and constraints. The same is true about the goal of inheriting some scale, but completely avoiding shear. This patch replaces the old Inherit Scale checkbox with a enum that supports multiple options: * Full: inherit all effects of scale, like with enabled Inherit Scale. * Fix Shear: removes shear from the final inherited transformation. The cleanup math is specifically designed to preserve the main axis of the bone, its length and total volume, and minimally affect roll on average. It however will not prevent reappearance of shear due to local rotation of the child or its children. * Average: inherit uniform scale that represents the parent volume. This is the simplest foolproof solution that will inherit some scale without ever causing shear. * None: completely remove scale and shear. * None (Legacy): old disabled Inherit Scale checkbox. This mode does not handle parent shear in any way, so the child is likely to end up having both scale and shear. It is retained for backward compatibility. Since many rigging-related addons access the use_inherit_scale property from Python, it is retained as a backward compatibility stub that provides the old functionality. As a side effect of reworking the code, this also fixes a matrix multiplication order bug in the Inherit Rotation code, which caused the parent local scale to be applied in world space. In rigger opinion this option is useless in production rigs, so this fix should not be a problem. Reviewers: brecht Differential Revision: https://developer.blender.org/D5588
2019-09-04 10:10:27 +03:00
else {
float tmat[4][4], tscale[3];
Armature: add Inherit Scale options to remove shear or average the scale. As an inherent property of matrix-based transformation math, non- uniform scaling of a parent bone induces shear into the transform matrix of any rotated child. Such matrices cannot be cleanly decomposed into a combination of location/rotation/scale, which causes issues for rigging and animation tools. Blender bones have options to exclude rotation and/or scale from the inherited transformation, but don't have any support for removing the often undesired shear component. That goal requires replacing simple parenting with a combination of multiple bones and constraints. The same is true about the goal of inheriting some scale, but completely avoiding shear. This patch replaces the old Inherit Scale checkbox with a enum that supports multiple options: * Full: inherit all effects of scale, like with enabled Inherit Scale. * Fix Shear: removes shear from the final inherited transformation. The cleanup math is specifically designed to preserve the main axis of the bone, its length and total volume, and minimally affect roll on average. It however will not prevent reappearance of shear due to local rotation of the child or its children. * Average: inherit uniform scale that represents the parent volume. This is the simplest foolproof solution that will inherit some scale without ever causing shear. * None: completely remove scale and shear. * None (Legacy): old disabled Inherit Scale checkbox. This mode does not handle parent shear in any way, so the child is likely to end up having both scale and shear. It is retained for backward compatibility. Since many rigging-related addons access the use_inherit_scale property from Python, it is retained as a backward compatibility stub that provides the old functionality. As a side effect of reworking the code, this also fixes a matrix multiplication order bug in the Inherit Rotation code, which caused the parent local scale to be applied in world space. In rigger opinion this option is useless in production rigs, so this fix should not be a problem. Reviewers: brecht Differential Revision: https://developer.blender.org/D5588
2019-09-04 10:10:27 +03:00
/* If using parent pose rotation: */
if (use_rotation) {
copy_m4_m4(tmat, parent_pose_mat);
/* Normalize the matrix when needed. */
switch (inherit_scale_mode) {
case BONE_INHERIT_SCALE_FULL:
case BONE_INHERIT_SCALE_FIX_SHEAR:
/* Keep scale and shear. */
break;
case BONE_INHERIT_SCALE_NONE:
case BONE_INHERIT_SCALE_AVERAGE:
/* Remove scale and shear from parent. */
orthogonalize_m4_stable(tmat, 1, true);
break;
case BONE_INHERIT_SCALE_ALIGNED:
/* Remove shear and extract scale. */
orthogonalize_m4_stable(tmat, 1, false);
normalize_m4_ex(tmat, r_bpt->post_scale);
break;
Armature: add Inherit Scale options to remove shear or average the scale. As an inherent property of matrix-based transformation math, non- uniform scaling of a parent bone induces shear into the transform matrix of any rotated child. Such matrices cannot be cleanly decomposed into a combination of location/rotation/scale, which causes issues for rigging and animation tools. Blender bones have options to exclude rotation and/or scale from the inherited transformation, but don't have any support for removing the often undesired shear component. That goal requires replacing simple parenting with a combination of multiple bones and constraints. The same is true about the goal of inheriting some scale, but completely avoiding shear. This patch replaces the old Inherit Scale checkbox with a enum that supports multiple options: * Full: inherit all effects of scale, like with enabled Inherit Scale. * Fix Shear: removes shear from the final inherited transformation. The cleanup math is specifically designed to preserve the main axis of the bone, its length and total volume, and minimally affect roll on average. It however will not prevent reappearance of shear due to local rotation of the child or its children. * Average: inherit uniform scale that represents the parent volume. This is the simplest foolproof solution that will inherit some scale without ever causing shear. * None: completely remove scale and shear. * None (Legacy): old disabled Inherit Scale checkbox. This mode does not handle parent shear in any way, so the child is likely to end up having both scale and shear. It is retained for backward compatibility. Since many rigging-related addons access the use_inherit_scale property from Python, it is retained as a backward compatibility stub that provides the old functionality. As a side effect of reworking the code, this also fixes a matrix multiplication order bug in the Inherit Rotation code, which caused the parent local scale to be applied in world space. In rigger opinion this option is useless in production rigs, so this fix should not be a problem. Reviewers: brecht Differential Revision: https://developer.blender.org/D5588
2019-09-04 10:10:27 +03:00
case BONE_INHERIT_SCALE_NONE_LEGACY:
/* Remove only scale - bad legacy way. */
normalize_m4(tmat);
break;
default:
BLI_assert(false);
}
}
/* If removing parent pose rotation: */
else {
copy_m4_m4(tmat, parent_arm_mat);
/* Copy the parent scale when needed. */
switch (inherit_scale_mode) {
case BONE_INHERIT_SCALE_FULL:
/* Ignore effects of shear. */
mat4_to_size(tscale, parent_pose_mat);
rescale_m4(tmat, tscale);
break;
case BONE_INHERIT_SCALE_FIX_SHEAR:
/* Take the effects of parent shear into account to get exact volume. */
mat4_to_size_fix_shear(tscale, parent_pose_mat);
rescale_m4(tmat, tscale);
break;
case BONE_INHERIT_SCALE_ALIGNED:
mat4_to_size_fix_shear(r_bpt->post_scale, parent_pose_mat);
break;
Armature: add Inherit Scale options to remove shear or average the scale. As an inherent property of matrix-based transformation math, non- uniform scaling of a parent bone induces shear into the transform matrix of any rotated child. Such matrices cannot be cleanly decomposed into a combination of location/rotation/scale, which causes issues for rigging and animation tools. Blender bones have options to exclude rotation and/or scale from the inherited transformation, but don't have any support for removing the often undesired shear component. That goal requires replacing simple parenting with a combination of multiple bones and constraints. The same is true about the goal of inheriting some scale, but completely avoiding shear. This patch replaces the old Inherit Scale checkbox with a enum that supports multiple options: * Full: inherit all effects of scale, like with enabled Inherit Scale. * Fix Shear: removes shear from the final inherited transformation. The cleanup math is specifically designed to preserve the main axis of the bone, its length and total volume, and minimally affect roll on average. It however will not prevent reappearance of shear due to local rotation of the child or its children. * Average: inherit uniform scale that represents the parent volume. This is the simplest foolproof solution that will inherit some scale without ever causing shear. * None: completely remove scale and shear. * None (Legacy): old disabled Inherit Scale checkbox. This mode does not handle parent shear in any way, so the child is likely to end up having both scale and shear. It is retained for backward compatibility. Since many rigging-related addons access the use_inherit_scale property from Python, it is retained as a backward compatibility stub that provides the old functionality. As a side effect of reworking the code, this also fixes a matrix multiplication order bug in the Inherit Rotation code, which caused the parent local scale to be applied in world space. In rigger opinion this option is useless in production rigs, so this fix should not be a problem. Reviewers: brecht Differential Revision: https://developer.blender.org/D5588
2019-09-04 10:10:27 +03:00
case BONE_INHERIT_SCALE_NONE:
case BONE_INHERIT_SCALE_AVERAGE:
case BONE_INHERIT_SCALE_NONE_LEGACY:
/* Keep unscaled. */
break;
default:
BLI_assert(false);
}
}
Armature: add Inherit Scale options to remove shear or average the scale. As an inherent property of matrix-based transformation math, non- uniform scaling of a parent bone induces shear into the transform matrix of any rotated child. Such matrices cannot be cleanly decomposed into a combination of location/rotation/scale, which causes issues for rigging and animation tools. Blender bones have options to exclude rotation and/or scale from the inherited transformation, but don't have any support for removing the often undesired shear component. That goal requires replacing simple parenting with a combination of multiple bones and constraints. The same is true about the goal of inheriting some scale, but completely avoiding shear. This patch replaces the old Inherit Scale checkbox with a enum that supports multiple options: * Full: inherit all effects of scale, like with enabled Inherit Scale. * Fix Shear: removes shear from the final inherited transformation. The cleanup math is specifically designed to preserve the main axis of the bone, its length and total volume, and minimally affect roll on average. It however will not prevent reappearance of shear due to local rotation of the child or its children. * Average: inherit uniform scale that represents the parent volume. This is the simplest foolproof solution that will inherit some scale without ever causing shear. * None: completely remove scale and shear. * None (Legacy): old disabled Inherit Scale checkbox. This mode does not handle parent shear in any way, so the child is likely to end up having both scale and shear. It is retained for backward compatibility. Since many rigging-related addons access the use_inherit_scale property from Python, it is retained as a backward compatibility stub that provides the old functionality. As a side effect of reworking the code, this also fixes a matrix multiplication order bug in the Inherit Rotation code, which caused the parent local scale to be applied in world space. In rigger opinion this option is useless in production rigs, so this fix should not be a problem. Reviewers: brecht Differential Revision: https://developer.blender.org/D5588
2019-09-04 10:10:27 +03:00
/* Apply the average parent scale when needed. */
if (inherit_scale_mode == BONE_INHERIT_SCALE_AVERAGE) {
mul_mat3_m4_fl(tmat, cbrtf(fabsf(mat4_to_volume_scale(parent_pose_mat))));
}
mul_m4_m4m4(r_bpt->rotscale_mat, tmat, offs_bone);
Armature: add Inherit Scale options to remove shear or average the scale. As an inherent property of matrix-based transformation math, non- uniform scaling of a parent bone induces shear into the transform matrix of any rotated child. Such matrices cannot be cleanly decomposed into a combination of location/rotation/scale, which causes issues for rigging and animation tools. Blender bones have options to exclude rotation and/or scale from the inherited transformation, but don't have any support for removing the often undesired shear component. That goal requires replacing simple parenting with a combination of multiple bones and constraints. The same is true about the goal of inheriting some scale, but completely avoiding shear. This patch replaces the old Inherit Scale checkbox with a enum that supports multiple options: * Full: inherit all effects of scale, like with enabled Inherit Scale. * Fix Shear: removes shear from the final inherited transformation. The cleanup math is specifically designed to preserve the main axis of the bone, its length and total volume, and minimally affect roll on average. It however will not prevent reappearance of shear due to local rotation of the child or its children. * Average: inherit uniform scale that represents the parent volume. This is the simplest foolproof solution that will inherit some scale without ever causing shear. * None: completely remove scale and shear. * None (Legacy): old disabled Inherit Scale checkbox. This mode does not handle parent shear in any way, so the child is likely to end up having both scale and shear. It is retained for backward compatibility. Since many rigging-related addons access the use_inherit_scale property from Python, it is retained as a backward compatibility stub that provides the old functionality. As a side effect of reworking the code, this also fixes a matrix multiplication order bug in the Inherit Rotation code, which caused the parent local scale to be applied in world space. In rigger opinion this option is useless in production rigs, so this fix should not be a problem. Reviewers: brecht Differential Revision: https://developer.blender.org/D5588
2019-09-04 10:10:27 +03:00
/* Remove remaining shear when needed, preserving volume. */
if (inherit_scale_mode == BONE_INHERIT_SCALE_FIX_SHEAR) {
orthogonalize_m4_stable(r_bpt->rotscale_mat, 1, false);
}
}
/* Compose the loc matrix for this bone. */
/* NOTE: That version does not modify bone's loc when HINGE/NO_SCALE options are set. */
/* In this case, use the object's space *orientation*. */
if (bone_flag & BONE_NO_LOCAL_LOCATION) {
/* XXX I'm sure that code can be simplified! */
float bone_loc[4][4], bone_rotscale[3][3], tmat4[4][4], tmat3[3][3];
unit_m4(bone_loc);
unit_m4(r_bpt->loc_mat);
unit_m4(tmat4);
mul_v3_m4v3(bone_loc[3], parent_pose_mat, offs_bone[3]);
unit_m3(bone_rotscale);
copy_m3_m4(tmat3, parent_pose_mat);
mul_m3_m3m3(bone_rotscale, tmat3, bone_rotscale);
copy_m4_m3(tmat4, bone_rotscale);
mul_m4_m4m4(r_bpt->loc_mat, bone_loc, tmat4);
}
/* Those flags do not affect position, use plain parent transform space! */
Armature: add Inherit Scale options to remove shear or average the scale. As an inherent property of matrix-based transformation math, non- uniform scaling of a parent bone induces shear into the transform matrix of any rotated child. Such matrices cannot be cleanly decomposed into a combination of location/rotation/scale, which causes issues for rigging and animation tools. Blender bones have options to exclude rotation and/or scale from the inherited transformation, but don't have any support for removing the often undesired shear component. That goal requires replacing simple parenting with a combination of multiple bones and constraints. The same is true about the goal of inheriting some scale, but completely avoiding shear. This patch replaces the old Inherit Scale checkbox with a enum that supports multiple options: * Full: inherit all effects of scale, like with enabled Inherit Scale. * Fix Shear: removes shear from the final inherited transformation. The cleanup math is specifically designed to preserve the main axis of the bone, its length and total volume, and minimally affect roll on average. It however will not prevent reappearance of shear due to local rotation of the child or its children. * Average: inherit uniform scale that represents the parent volume. This is the simplest foolproof solution that will inherit some scale without ever causing shear. * None: completely remove scale and shear. * None (Legacy): old disabled Inherit Scale checkbox. This mode does not handle parent shear in any way, so the child is likely to end up having both scale and shear. It is retained for backward compatibility. Since many rigging-related addons access the use_inherit_scale property from Python, it is retained as a backward compatibility stub that provides the old functionality. As a side effect of reworking the code, this also fixes a matrix multiplication order bug in the Inherit Rotation code, which caused the parent local scale to be applied in world space. In rigger opinion this option is useless in production rigs, so this fix should not be a problem. Reviewers: brecht Differential Revision: https://developer.blender.org/D5588
2019-09-04 10:10:27 +03:00
else if (!full_transform) {
mul_m4_m4m4(r_bpt->loc_mat, parent_pose_mat, offs_bone);
}
/* Else (i.e. default, usual case),
* just use the same matrix for rotation/scaling, and location. */
else {
copy_m4_m4(r_bpt->loc_mat, r_bpt->rotscale_mat);
}
}
/* Root bones. */
else {
/* Rotation/scaling. */
copy_m4_m4(r_bpt->rotscale_mat, offs_bone);
/* Translation. */
if (bone_flag & BONE_NO_LOCAL_LOCATION) {
/* Translation of arm_mat, without the rotation. */
unit_m4(r_bpt->loc_mat);
copy_v3_v3(r_bpt->loc_mat[3], offs_bone[3]);
}
else {
copy_m4_m4(r_bpt->loc_mat, r_bpt->rotscale_mat);
}
}
}
2018-12-20 17:30:04 +11:00
void BKE_bone_parent_transform_clear(struct BoneParentTransform *bpt)
{
unit_m4(bpt->rotscale_mat);
unit_m4(bpt->loc_mat);
copy_v3_fl(bpt->post_scale, 1.0f);
}
2018-12-20 17:30:04 +11:00
void BKE_bone_parent_transform_invert(struct BoneParentTransform *bpt)
{
invert_m4(bpt->rotscale_mat);
invert_m4(bpt->loc_mat);
invert_v3(bpt->post_scale);
}
2018-12-20 17:30:04 +11:00
void BKE_bone_parent_transform_combine(const struct BoneParentTransform *in1,
const struct BoneParentTransform *in2,
struct BoneParentTransform *result)
{
mul_m4_m4m4(result->rotscale_mat, in1->rotscale_mat, in2->rotscale_mat);
mul_m4_m4m4(result->loc_mat, in1->loc_mat, in2->loc_mat);
mul_v3_v3v3(result->post_scale, in1->post_scale, in2->post_scale);
}
2018-12-20 17:30:04 +11:00
void BKE_bone_parent_transform_apply(const struct BoneParentTransform *bpt,
const float inmat[4][4],
float outmat[4][4])
{
/* in case inmat == outmat */
float tmploc[3];
copy_v3_v3(tmploc, inmat[3]);
mul_m4_m4m4(outmat, bpt->rotscale_mat, inmat);
mul_v3_m4v3(outmat[3], bpt->loc_mat, tmploc);
rescale_m4(outmat, bpt->post_scale);
}
/* Convert Pose-Space Matrix to Bone-Space Matrix.
* NOTE: this cannot be used to convert to pose-space transforms of the supplied
* pose-channel into its local space (i.e. 'visual'-keyframing) */
void BKE_armature_mat_pose_to_bone(bPoseChannel *pchan,
const float inmat[4][4],
float outmat[4][4])
{
BoneParentTransform bpt;
2018-12-20 17:30:04 +11:00
BKE_bone_parent_transform_calc_from_pchan(pchan, &bpt);
BKE_bone_parent_transform_invert(&bpt);
BKE_bone_parent_transform_apply(&bpt, inmat, outmat);
}
/* Convert Bone-Space Matrix to Pose-Space Matrix. */
void BKE_armature_mat_bone_to_pose(bPoseChannel *pchan,
const float inmat[4][4],
float outmat[4][4])
{
BoneParentTransform bpt;
2018-12-20 17:30:04 +11:00
BKE_bone_parent_transform_calc_from_pchan(pchan, &bpt);
BKE_bone_parent_transform_apply(&bpt, inmat, outmat);
}
/* Convert Pose-Space Location to Bone-Space Location
* NOTE: this cannot be used to convert to pose-space location of the supplied
* pose-channel into its local space (i.e. 'visual'-keyframing) */
void BKE_armature_loc_pose_to_bone(bPoseChannel *pchan, const float inloc[3], float outloc[3])
{
float xLocMat[4][4];
float nLocMat[4][4];
/* build matrix for location */
unit_m4(xLocMat);
copy_v3_v3(xLocMat[3], inloc);
/* get bone-space cursor matrix and extract location */
BKE_armature_mat_pose_to_bone(pchan, xLocMat, nLocMat);
copy_v3_v3(outloc, nLocMat[3]);
}
/** \} */
/* -------------------------------------------------------------------- */
/** \name Bone Matrix Read/Write API
*
* High level functions for transforming bones and reading the transform values.
* \{ */
void BKE_armature_mat_pose_to_bone_ex(struct Depsgraph *depsgraph,
Object *ob,
bPoseChannel *pchan,
const float inmat[4][4],
float outmat[4][4])
{
bPoseChannel work_pchan = *pchan;
/* recalculate pose matrix with only parent transformations,
* bone loc/sca/rot is ignored, scene and frame are not used. */
BKE_pose_where_is_bone(depsgraph, NULL, ob, &work_pchan, 0.0f, false);
/* find the matrix, need to remove the bone transforms first so this is
* calculated as a matrix to set rather than a difference ontop of what's
* already there. */
unit_m4(outmat);
BKE_pchan_apply_mat4(&work_pchan, outmat, false);
BKE_armature_mat_pose_to_bone(&work_pchan, inmat, outmat);
}
/**
* Same as #BKE_object_mat3_to_rot().
*/
void BKE_pchan_mat3_to_rot(bPoseChannel *pchan, const float mat[3][3], bool use_compat)
{
BLI_ASSERT_UNIT_M3(mat);
switch (pchan->rotmode) {
case ROT_MODE_QUAT:
mat3_normalized_to_quat(pchan->quat, mat);
break;
case ROT_MODE_AXISANGLE:
mat3_normalized_to_axis_angle(pchan->rotAxis, &pchan->rotAngle, mat);
break;
default: /* euler */
if (use_compat) {
mat3_normalized_to_compatible_eulO(pchan->eul, pchan->eul, pchan->rotmode, mat);
}
else {
mat3_normalized_to_eulO(pchan->eul, pchan->rotmode, mat);
}
break;
}
}
/**
* Same as #BKE_object_rot_to_mat3().
*/
void BKE_pchan_rot_to_mat3(const bPoseChannel *pchan, float r_mat[3][3])
{
/* rotations may either be quats, eulers (with various rotation orders), or axis-angle */
if (pchan->rotmode > 0) {
/* Euler rotations (will cause gimbal lock,
* but this can be alleviated a bit with rotation orders) */
eulO_to_mat3(r_mat, pchan->eul, pchan->rotmode);
}
else if (pchan->rotmode == ROT_MODE_AXISANGLE) {
/* axis-angle - not really that great for 3D-changing orientations */
axis_angle_to_mat3(r_mat, pchan->rotAxis, pchan->rotAngle);
}
else {
/* quats are normalized before use to eliminate scaling issues */
float quat[4];
/* NOTE: we now don't normalize the stored values anymore,
* since this was kindof evil in some cases but if this proves to be too problematic,
* switch back to the old system of operating directly on the stored copy. */
normalize_qt_qt(quat, pchan->quat);
quat_to_mat3(r_mat, quat);
}
}
/**
* Apply a 4x4 matrix to the pose bone,
* similar to #BKE_object_apply_mat4().
*/
void BKE_pchan_apply_mat4(bPoseChannel *pchan, const float mat[4][4], bool use_compat)
{
float rot[3][3];
mat4_to_loc_rot_size(pchan->loc, rot, pchan->size, mat);
BKE_pchan_mat3_to_rot(pchan, rot, use_compat);
}
/**
* Remove rest-position effects from pose-transform for obtaining
* 'visual' transformation of pose-channel.
* (used by the Visual-Keyframing stuff).
*/
void BKE_armature_mat_pose_to_delta(float delta_mat[4][4],
float pose_mat[4][4],
float arm_mat[4][4])
{
float imat[4][4];
invert_m4_m4(imat, arm_mat);
mul_m4_m4m4(delta_mat, imat, pose_mat);
}
/** \} */
/* -------------------------------------------------------------------- */
/** \name Rotation Mode Conversions
*
* Used for Objects and Pose Channels, since both can have multiple rotation representations.
* \{ */
/* Called from RNA when rotation mode changes
* - the result should be that the rotations given in the provided pointers have had conversions
* applied (as appropriate), such that the rotation of the element hasn't 'visually' changed */
void BKE_rotMode_change_values(
float quat[4], float eul[3], float axis[3], float *angle, short oldMode, short newMode)
{
/* check if any change - if so, need to convert data */
if (newMode > 0) { /* to euler */
if (oldMode == ROT_MODE_AXISANGLE) {
/* axis-angle to euler */
axis_angle_to_eulO(eul, newMode, axis, *angle);
}
else if (oldMode == ROT_MODE_QUAT) {
/* quat to euler */
normalize_qt(quat);
2012-04-29 15:47:02 +00:00
quat_to_eulO(eul, newMode, quat);
}
/* else { no conversion needed } */
}
else if (newMode == ROT_MODE_QUAT) { /* to quat */
if (oldMode == ROT_MODE_AXISANGLE) {
/* axis angle to quat */
axis_angle_to_quat(quat, axis, *angle);
}
else if (oldMode > 0) {
/* euler to quat */
eulO_to_quat(quat, eul, oldMode);
}
/* else { no conversion needed } */
}
else if (newMode == ROT_MODE_AXISANGLE) { /* to axis-angle */
if (oldMode > 0) {
/* euler to axis angle */
eulO_to_axis_angle(axis, angle, eul, oldMode);
}
else if (oldMode == ROT_MODE_QUAT) {
/* quat to axis angle */
normalize_qt(quat);
quat_to_axis_angle(axis, angle, quat);
}
/* When converting to axis-angle,
* we need a special exception for the case when there is no axis. */
if (IS_EQF(axis[0], axis[1]) && IS_EQF(axis[1], axis[2])) {
/* for now, rotate around y-axis then (so that it simply becomes the roll) */
axis[1] = 1.0f;
}
}
}
2002-10-12 11:37:38 +00:00
/** \} */
2002-10-12 11:37:38 +00:00
/* -------------------------------------------------------------------- */
/** \name Bone Vector, Roll Conversion
*
* Used for Objects and Pose Channels, since both can have multiple rotation representations.
*
* How it Works
* ============
*
* This is the bone transformation trick; they're hierarchical so each bone(b)
* is in the coord system of bone(b-1):
*
* arm_mat(b)= arm_mat(b-1) * yoffs(b-1) * d_root(b) * bone_mat(b)
*
* -> yoffs is just the y axis translation in parent's coord system
* -> d_root is the translation of the bone root, also in parent's coord system
*
* pose_mat(b)= pose_mat(b-1) * yoffs(b-1) * d_root(b) * bone_mat(b) * chan_mat(b)
*
* we then - in init deform - store the deform in chan_mat, such that:
*
* pose_mat(b)= arm_mat(b) * chan_mat(b)
*
* \{ */
/* Computes vector and roll based on a rotation.
* "mat" must contain only a rotation, and no scaling. */
void mat3_to_vec_roll(const float mat[3][3], float r_vec[3], float *r_roll)
{
if (r_vec) {
copy_v3_v3(r_vec, mat[1]);
}
2002-10-12 11:37:38 +00:00
if (r_roll) {
mat3_vec_to_roll(mat, mat[1], r_roll);
}
}
/* Computes roll around the vector that best approximates the matrix.
* If vec is the Y vector from purely rotational mat, result should be exact. */
void mat3_vec_to_roll(const float mat[3][3], const float vec[3], float *r_roll)
{
float vecmat[3][3], vecmatinv[3][3], rollmat[3][3], q[4];
/* Compute the orientation relative to the vector with zero roll. */
vec_roll_to_mat3(vec, 0.0f, vecmat);
invert_m3_m3(vecmatinv, vecmat);
mul_m3_m3m3(rollmat, vecmatinv, mat);
/* Extract the twist angle as the roll value. */
mat3_to_quat(q, rollmat);
*r_roll = quat_split_swing_and_twist(q, 1, NULL, NULL);
}
2002-10-12 11:37:38 +00:00
/* Calculates the rest matrix of a bone based on its vector and a roll around that vector. */
/**
* Given `v = (v.x, v.y, v.z)` our (normalized) bone vector, we want the rotation matrix M
* from the Y axis (so that `M * (0, 1, 0) = v`).
* - The rotation axis a lays on XZ plane, and it is orthonormal to v,
* hence to the projection of v onto XZ plane.
* - `a = (v.z, 0, -v.x)`
*
* We know a is eigenvector of M (so M * a = a).
* Finally, we have w, such that M * w = (0, 1, 0)
* (i.e. the vector that will be aligned with Y axis once transformed).
* We know w is symmetric to v by the Y axis.
* - `w = (-v.x, v.y, -v.z)`
*
* Solving this, we get (x, y and z being the components of v):
* <pre>
* (x^2 * y + z^2) / (x^2 + z^2), x, x * z * (y - 1) / (x^2 + z^2)
* M = x * (y^2 - 1) / (x^2 + z^2), y, z * (y^2 - 1) / (x^2 + z^2)
* x * z * (y - 1) / (x^2 + z^2), z, (x^2 + z^2 * y) / (x^2 + z^2)
* </pre>
*
* This is stable as long as v (the bone) is not too much aligned with +/-Y
* (i.e. x and z components are not too close to 0).
*
* Since v is normalized, we have `x^2 + y^2 + z^2 = 1`,
* hence `x^2 + z^2 = 1 - y^2 = (1 - y)(1 + y)`.
*
* This allows to simplifies M like this:
* <pre>
* 1 - x^2 / (1 + y), x, -x * z / (1 + y)
* M = -x, y, -z
* -x * z / (1 + y), z, 1 - z^2 / (1 + y)
* </pre>
*
* Written this way, we see the case v = +Y is no more a singularity.
* The only one
* remaining is the bone being aligned with -Y.
*
* Let's handle
* the asymptotic behavior when bone vector is reaching the limit of y = -1.
* Each of the four corner elements can vary from -1 to 1,
* depending on the axis a chosen for doing the rotation.
* And the "rotation" here is in fact established by mirroring XZ plane by that given axis,
* then inversing the Y-axis.
* For sufficiently small x and z, and with y approaching -1,
* all elements but the four corner ones of M will degenerate.
* So let's now focus on these corner elements.
*
* We rewrite M so that it only contains its four corner elements,
* and combine the `1 / (1 + y)` factor:
* <pre>
* 1 + y - x^2, -x * z
* M* = 1 / (1 + y) *
* -x * z, 1 + y - z^2
* </pre>
*
* When y is close to -1, computing 1 / (1 + y) will cause severe numerical instability,
* so we ignore it and normalize M instead.
* We know `y^2 = 1 - (x^2 + z^2)`, and `y < 0`, hence `y = -sqrt(1 - (x^2 + z^2))`.
*
* Since x and z are both close to 0, we apply the binomial expansion to the first order:
* `y = -sqrt(1 - (x^2 + z^2)) = -1 + (x^2 + z^2) / 2`. Which gives:
* <pre>
* z^2 - x^2, -2 * x * z
* M* = 1 / (x^2 + z^2) *
* -2 * x * z, x^2 - z^2
* </pre>
*/
void vec_roll_to_mat3_normalized(const float nor[3], const float roll, float r_mat[3][3])
2002-10-12 11:37:38 +00:00
{
const float THETA_SAFE = 1.0e-5f; /* theta above this value are always safe to use. */
const float THETA_CRITICAL = 1.0e-9f; /* above this is safe under certain conditions. */
const float x = nor[0];
const float y = nor[1];
const float z = nor[2];
const float theta = 1.0f + y;
const float theta_alt = x * x + z * z;
float rMatrix[3][3], bMatrix[3][3];
BLI_ASSERT_UNIT_V3(nor);
/* When theta is close to zero (nor is aligned close to negative Y Axis),
* we have to check we do have non-null X/Z components as well.
* Also, due to float precision errors, nor can be (0.0, -0.99999994, 0.0) which results
* in theta being close to zero. This will cause problems when theta is used as divisor.
*/
if (theta > THETA_SAFE || ((x || z) && theta > THETA_CRITICAL)) {
/* nor is *not* aligned to negative Y-axis (0,-1,0).
* We got these values for free... so be happy with it... ;)
*/
bMatrix[0][1] = -x;
bMatrix[1][0] = x;
bMatrix[1][1] = y;
bMatrix[1][2] = z;
bMatrix[2][1] = -z;
if (theta > THETA_SAFE) {
/* nor differs significantly from negative Y axis (0,-1,0): apply the general case. */
bMatrix[0][0] = 1 - x * x / theta;
bMatrix[2][2] = 1 - z * z / theta;
bMatrix[2][0] = bMatrix[0][2] = -x * z / theta;
}
else {
/* nor is close to negative Y axis (0,-1,0): apply the special case. */
bMatrix[0][0] = (x + z) * (x - z) / -theta_alt;
bMatrix[2][2] = -bMatrix[0][0];
bMatrix[2][0] = bMatrix[0][2] = 2.0f * x * z / theta_alt;
}
}
else {
/* nor is very close to negative Y axis (0,-1,0): use simple symmetry by Z axis. */
unit_m3(bMatrix);
bMatrix[0][0] = bMatrix[1][1] = -1.0;
}
/* Make Roll matrix */
axis_angle_normalized_to_mat3(rMatrix, nor, roll);
/* Combine and output result */
mul_m3_m3m3(r_mat, rMatrix, bMatrix);
2002-10-12 11:37:38 +00:00
}
void vec_roll_to_mat3(const float vec[3], const float roll, float r_mat[3][3])
{
float nor[3];
normalize_v3_v3(nor, vec);
vec_roll_to_mat3_normalized(nor, roll, r_mat);
}
2002-10-12 11:37:38 +00:00
/** \} */
/* -------------------------------------------------------------------- */
/** \name Armature Bone Matrix Calculation (Recursive)
* \{ */
2020-03-06 11:40:37 +11:00
/**
* Recursive part, calculates rest-position of entire tree of children.
* \note Used when exiting edit-mode too.
*/
void BKE_armature_where_is_bone(Bone *bone, const Bone *bone_parent, const bool use_recursion)
2002-10-12 11:37:38 +00:00
{
Result of 2 weeks of quiet coding work in Greece :) Aim was to get a total refresh of the animation system. This is needed because; - we need to upgrade it with 21st century features - current code is spaghetti/hack combo, and hides good design - it should become lag-free with using dependency graphs A full log, with complete code API/structure/design explanation will follow, that's a load of work... so here below the list with hot changes; - The entire object update system (matrices, geometry) is now centralized. Calls to where_is_object and makeDispList are forbidden, instead we tag objects 'changed' and let the depgraph code sort it out - Removed all old "Ika" code - Depgraph is aware of all relationships, including meta balls, constraints, bevelcurve, and so on. - Made depgraph aware of relation types and layers, to do smart flushing of 'changed' events. Nothing gets calculated too often! - Transform uses depgraph to detect changes - On frame-advance, depgraph flushes animated changes Armatures; Almost all armature related code has been fully built from scratch. It now reveils the original design much better, with a very clean implementation, lag free without even calculating each Bone more than once. Result is quite a speedup yes! Important to note is; 1) Armature is data containing the 'rest position' 2) Pose is the changes of rest position, and always on object level. That way more Objects can use same Pose. Also constraints are in Pose 3) Actions only contain the Ipos to change values in Poses. - Bones draw unrotated now - Drawing bones speedup enormously (10-20 times) - Bone selecting in EditMode, selection state is saved for PoseMode, and vice-versa - Undo in editmode - Bone renaming does vertexgroups, constraints, posechannels, actions, for all users of Armature in entire file - Added Bone renaming in NKey panel - Nkey PoseMode shows eulers now - EditMode and PoseMode now have 'active' bone too (last clicked) - Parenting in EditMode' CTRL+P, ALT+P, with nice options! - Pose is added in Outliner now, with showing that constraints are in the Pose, not Armature - Disconnected IK solving from constraints. It's a separate phase now, on top of the full Pose calculations - Pose itself has a dependency graph too, so evaluation order is lag free. TODO NOW; - Rotating in Posemode has incorrect inverse transform (Martin will fix) - Python Bone/Armature/Pose API disabled... needs full recode too (wait for my doc!) - Game engine will need upgrade too - Depgraph code needs revision, cleanup, can be much faster! (But, compliments for Jean-Luc, it works like a charm!) - IK changed, it now doesnt use previous position to advance to next position anymore. That system looks nice (no flips) but is not well suited for NLA and background render. TODO LATER; We now can do loadsa new nifty features as well; like: - Kill PoseMode (can be option for armatures itself) - Make B-Bones (Bezier, Bspline, like for spines) - Move all silly button level edit to 3d window (like CTRL+I = add IK) - Much better & informative drawing - Fix action/nla editors - Put all ipos in Actions (object, mesh key, lamp color) - Add hooks - Null bones - Much more advanced constraints... Bugfixes; - OGL render (view3d header) had wrong first frame on anim render - Ipo 'recording' mode had wrong playback speed - Vertex-key mode now sticks to show 'active key', until frame change -Ton-
2005-07-03 17:35:38 +00:00
float vec[3];
Result of 2 weeks of quiet coding work in Greece :) Aim was to get a total refresh of the animation system. This is needed because; - we need to upgrade it with 21st century features - current code is spaghetti/hack combo, and hides good design - it should become lag-free with using dependency graphs A full log, with complete code API/structure/design explanation will follow, that's a load of work... so here below the list with hot changes; - The entire object update system (matrices, geometry) is now centralized. Calls to where_is_object and makeDispList are forbidden, instead we tag objects 'changed' and let the depgraph code sort it out - Removed all old "Ika" code - Depgraph is aware of all relationships, including meta balls, constraints, bevelcurve, and so on. - Made depgraph aware of relation types and layers, to do smart flushing of 'changed' events. Nothing gets calculated too often! - Transform uses depgraph to detect changes - On frame-advance, depgraph flushes animated changes Armatures; Almost all armature related code has been fully built from scratch. It now reveils the original design much better, with a very clean implementation, lag free without even calculating each Bone more than once. Result is quite a speedup yes! Important to note is; 1) Armature is data containing the 'rest position' 2) Pose is the changes of rest position, and always on object level. That way more Objects can use same Pose. Also constraints are in Pose 3) Actions only contain the Ipos to change values in Poses. - Bones draw unrotated now - Drawing bones speedup enormously (10-20 times) - Bone selecting in EditMode, selection state is saved for PoseMode, and vice-versa - Undo in editmode - Bone renaming does vertexgroups, constraints, posechannels, actions, for all users of Armature in entire file - Added Bone renaming in NKey panel - Nkey PoseMode shows eulers now - EditMode and PoseMode now have 'active' bone too (last clicked) - Parenting in EditMode' CTRL+P, ALT+P, with nice options! - Pose is added in Outliner now, with showing that constraints are in the Pose, not Armature - Disconnected IK solving from constraints. It's a separate phase now, on top of the full Pose calculations - Pose itself has a dependency graph too, so evaluation order is lag free. TODO NOW; - Rotating in Posemode has incorrect inverse transform (Martin will fix) - Python Bone/Armature/Pose API disabled... needs full recode too (wait for my doc!) - Game engine will need upgrade too - Depgraph code needs revision, cleanup, can be much faster! (But, compliments for Jean-Luc, it works like a charm!) - IK changed, it now doesnt use previous position to advance to next position anymore. That system looks nice (no flips) but is not well suited for NLA and background render. TODO LATER; We now can do loadsa new nifty features as well; like: - Kill PoseMode (can be option for armatures itself) - Make B-Bones (Bezier, Bspline, like for spines) - Move all silly button level edit to 3d window (like CTRL+I = add IK) - Much better & informative drawing - Fix action/nla editors - Put all ipos in Actions (object, mesh key, lamp color) - Add hooks - Null bones - Much more advanced constraints... Bugfixes; - OGL render (view3d header) had wrong first frame on anim render - Ipo 'recording' mode had wrong playback speed - Vertex-key mode now sticks to show 'active key', until frame change -Ton-
2005-07-03 17:35:38 +00:00
/* Bone Space */
sub_v3_v3v3(vec, bone->tail, bone->head);
bone->length = len_v3(vec);
Result of 2 weeks of quiet coding work in Greece :) Aim was to get a total refresh of the animation system. This is needed because; - we need to upgrade it with 21st century features - current code is spaghetti/hack combo, and hides good design - it should become lag-free with using dependency graphs A full log, with complete code API/structure/design explanation will follow, that's a load of work... so here below the list with hot changes; - The entire object update system (matrices, geometry) is now centralized. Calls to where_is_object and makeDispList are forbidden, instead we tag objects 'changed' and let the depgraph code sort it out - Removed all old "Ika" code - Depgraph is aware of all relationships, including meta balls, constraints, bevelcurve, and so on. - Made depgraph aware of relation types and layers, to do smart flushing of 'changed' events. Nothing gets calculated too often! - Transform uses depgraph to detect changes - On frame-advance, depgraph flushes animated changes Armatures; Almost all armature related code has been fully built from scratch. It now reveils the original design much better, with a very clean implementation, lag free without even calculating each Bone more than once. Result is quite a speedup yes! Important to note is; 1) Armature is data containing the 'rest position' 2) Pose is the changes of rest position, and always on object level. That way more Objects can use same Pose. Also constraints are in Pose 3) Actions only contain the Ipos to change values in Poses. - Bones draw unrotated now - Drawing bones speedup enormously (10-20 times) - Bone selecting in EditMode, selection state is saved for PoseMode, and vice-versa - Undo in editmode - Bone renaming does vertexgroups, constraints, posechannels, actions, for all users of Armature in entire file - Added Bone renaming in NKey panel - Nkey PoseMode shows eulers now - EditMode and PoseMode now have 'active' bone too (last clicked) - Parenting in EditMode' CTRL+P, ALT+P, with nice options! - Pose is added in Outliner now, with showing that constraints are in the Pose, not Armature - Disconnected IK solving from constraints. It's a separate phase now, on top of the full Pose calculations - Pose itself has a dependency graph too, so evaluation order is lag free. TODO NOW; - Rotating in Posemode has incorrect inverse transform (Martin will fix) - Python Bone/Armature/Pose API disabled... needs full recode too (wait for my doc!) - Game engine will need upgrade too - Depgraph code needs revision, cleanup, can be much faster! (But, compliments for Jean-Luc, it works like a charm!) - IK changed, it now doesnt use previous position to advance to next position anymore. That system looks nice (no flips) but is not well suited for NLA and background render. TODO LATER; We now can do loadsa new nifty features as well; like: - Kill PoseMode (can be option for armatures itself) - Make B-Bones (Bezier, Bspline, like for spines) - Move all silly button level edit to 3d window (like CTRL+I = add IK) - Much better & informative drawing - Fix action/nla editors - Put all ipos in Actions (object, mesh key, lamp color) - Add hooks - Null bones - Much more advanced constraints... Bugfixes; - OGL render (view3d header) had wrong first frame on anim render - Ipo 'recording' mode had wrong playback speed - Vertex-key mode now sticks to show 'active key', until frame change -Ton-
2005-07-03 17:35:38 +00:00
vec_roll_to_mat3(vec, bone->roll, bone->bone_mat);
/* this is called on old file reading too... */
if (bone->xwidth == 0.0f) {
bone->xwidth = 0.1f;
bone->zwidth = 0.1f;
bone->segments = 1;
}
if (bone_parent) {
float offs_bone[4][4];
/* yoffs(b-1) + root(b) + bonemat(b) */
2018-12-20 17:30:04 +11:00
BKE_bone_offset_matrix_get(bone, offs_bone);
Result of 2 weeks of quiet coding work in Greece :) Aim was to get a total refresh of the animation system. This is needed because; - we need to upgrade it with 21st century features - current code is spaghetti/hack combo, and hides good design - it should become lag-free with using dependency graphs A full log, with complete code API/structure/design explanation will follow, that's a load of work... so here below the list with hot changes; - The entire object update system (matrices, geometry) is now centralized. Calls to where_is_object and makeDispList are forbidden, instead we tag objects 'changed' and let the depgraph code sort it out - Removed all old "Ika" code - Depgraph is aware of all relationships, including meta balls, constraints, bevelcurve, and so on. - Made depgraph aware of relation types and layers, to do smart flushing of 'changed' events. Nothing gets calculated too often! - Transform uses depgraph to detect changes - On frame-advance, depgraph flushes animated changes Armatures; Almost all armature related code has been fully built from scratch. It now reveils the original design much better, with a very clean implementation, lag free without even calculating each Bone more than once. Result is quite a speedup yes! Important to note is; 1) Armature is data containing the 'rest position' 2) Pose is the changes of rest position, and always on object level. That way more Objects can use same Pose. Also constraints are in Pose 3) Actions only contain the Ipos to change values in Poses. - Bones draw unrotated now - Drawing bones speedup enormously (10-20 times) - Bone selecting in EditMode, selection state is saved for PoseMode, and vice-versa - Undo in editmode - Bone renaming does vertexgroups, constraints, posechannels, actions, for all users of Armature in entire file - Added Bone renaming in NKey panel - Nkey PoseMode shows eulers now - EditMode and PoseMode now have 'active' bone too (last clicked) - Parenting in EditMode' CTRL+P, ALT+P, with nice options! - Pose is added in Outliner now, with showing that constraints are in the Pose, not Armature - Disconnected IK solving from constraints. It's a separate phase now, on top of the full Pose calculations - Pose itself has a dependency graph too, so evaluation order is lag free. TODO NOW; - Rotating in Posemode has incorrect inverse transform (Martin will fix) - Python Bone/Armature/Pose API disabled... needs full recode too (wait for my doc!) - Game engine will need upgrade too - Depgraph code needs revision, cleanup, can be much faster! (But, compliments for Jean-Luc, it works like a charm!) - IK changed, it now doesnt use previous position to advance to next position anymore. That system looks nice (no flips) but is not well suited for NLA and background render. TODO LATER; We now can do loadsa new nifty features as well; like: - Kill PoseMode (can be option for armatures itself) - Make B-Bones (Bezier, Bspline, like for spines) - Move all silly button level edit to 3d window (like CTRL+I = add IK) - Much better & informative drawing - Fix action/nla editors - Put all ipos in Actions (object, mesh key, lamp color) - Add hooks - Null bones - Much more advanced constraints... Bugfixes; - OGL render (view3d header) had wrong first frame on anim render - Ipo 'recording' mode had wrong playback speed - Vertex-key mode now sticks to show 'active key', until frame change -Ton-
2005-07-03 17:35:38 +00:00
/* Compose the matrix for this bone */
mul_m4_m4m4(bone->arm_mat, bone_parent->arm_mat, offs_bone);
Result of 2 weeks of quiet coding work in Greece :) Aim was to get a total refresh of the animation system. This is needed because; - we need to upgrade it with 21st century features - current code is spaghetti/hack combo, and hides good design - it should become lag-free with using dependency graphs A full log, with complete code API/structure/design explanation will follow, that's a load of work... so here below the list with hot changes; - The entire object update system (matrices, geometry) is now centralized. Calls to where_is_object and makeDispList are forbidden, instead we tag objects 'changed' and let the depgraph code sort it out - Removed all old "Ika" code - Depgraph is aware of all relationships, including meta balls, constraints, bevelcurve, and so on. - Made depgraph aware of relation types and layers, to do smart flushing of 'changed' events. Nothing gets calculated too often! - Transform uses depgraph to detect changes - On frame-advance, depgraph flushes animated changes Armatures; Almost all armature related code has been fully built from scratch. It now reveils the original design much better, with a very clean implementation, lag free without even calculating each Bone more than once. Result is quite a speedup yes! Important to note is; 1) Armature is data containing the 'rest position' 2) Pose is the changes of rest position, and always on object level. That way more Objects can use same Pose. Also constraints are in Pose 3) Actions only contain the Ipos to change values in Poses. - Bones draw unrotated now - Drawing bones speedup enormously (10-20 times) - Bone selecting in EditMode, selection state is saved for PoseMode, and vice-versa - Undo in editmode - Bone renaming does vertexgroups, constraints, posechannels, actions, for all users of Armature in entire file - Added Bone renaming in NKey panel - Nkey PoseMode shows eulers now - EditMode and PoseMode now have 'active' bone too (last clicked) - Parenting in EditMode' CTRL+P, ALT+P, with nice options! - Pose is added in Outliner now, with showing that constraints are in the Pose, not Armature - Disconnected IK solving from constraints. It's a separate phase now, on top of the full Pose calculations - Pose itself has a dependency graph too, so evaluation order is lag free. TODO NOW; - Rotating in Posemode has incorrect inverse transform (Martin will fix) - Python Bone/Armature/Pose API disabled... needs full recode too (wait for my doc!) - Game engine will need upgrade too - Depgraph code needs revision, cleanup, can be much faster! (But, compliments for Jean-Luc, it works like a charm!) - IK changed, it now doesnt use previous position to advance to next position anymore. That system looks nice (no flips) but is not well suited for NLA and background render. TODO LATER; We now can do loadsa new nifty features as well; like: - Kill PoseMode (can be option for armatures itself) - Make B-Bones (Bezier, Bspline, like for spines) - Move all silly button level edit to 3d window (like CTRL+I = add IK) - Much better & informative drawing - Fix action/nla editors - Put all ipos in Actions (object, mesh key, lamp color) - Add hooks - Null bones - Much more advanced constraints... Bugfixes; - OGL render (view3d header) had wrong first frame on anim render - Ipo 'recording' mode had wrong playback speed - Vertex-key mode now sticks to show 'active key', until frame change -Ton-
2005-07-03 17:35:38 +00:00
}
else {
copy_m4_m3(bone->arm_mat, bone->bone_mat);
copy_v3_v3(bone->arm_mat[3], bone->head);
Result of 2 weeks of quiet coding work in Greece :) Aim was to get a total refresh of the animation system. This is needed because; - we need to upgrade it with 21st century features - current code is spaghetti/hack combo, and hides good design - it should become lag-free with using dependency graphs A full log, with complete code API/structure/design explanation will follow, that's a load of work... so here below the list with hot changes; - The entire object update system (matrices, geometry) is now centralized. Calls to where_is_object and makeDispList are forbidden, instead we tag objects 'changed' and let the depgraph code sort it out - Removed all old "Ika" code - Depgraph is aware of all relationships, including meta balls, constraints, bevelcurve, and so on. - Made depgraph aware of relation types and layers, to do smart flushing of 'changed' events. Nothing gets calculated too often! - Transform uses depgraph to detect changes - On frame-advance, depgraph flushes animated changes Armatures; Almost all armature related code has been fully built from scratch. It now reveils the original design much better, with a very clean implementation, lag free without even calculating each Bone more than once. Result is quite a speedup yes! Important to note is; 1) Armature is data containing the 'rest position' 2) Pose is the changes of rest position, and always on object level. That way more Objects can use same Pose. Also constraints are in Pose 3) Actions only contain the Ipos to change values in Poses. - Bones draw unrotated now - Drawing bones speedup enormously (10-20 times) - Bone selecting in EditMode, selection state is saved for PoseMode, and vice-versa - Undo in editmode - Bone renaming does vertexgroups, constraints, posechannels, actions, for all users of Armature in entire file - Added Bone renaming in NKey panel - Nkey PoseMode shows eulers now - EditMode and PoseMode now have 'active' bone too (last clicked) - Parenting in EditMode' CTRL+P, ALT+P, with nice options! - Pose is added in Outliner now, with showing that constraints are in the Pose, not Armature - Disconnected IK solving from constraints. It's a separate phase now, on top of the full Pose calculations - Pose itself has a dependency graph too, so evaluation order is lag free. TODO NOW; - Rotating in Posemode has incorrect inverse transform (Martin will fix) - Python Bone/Armature/Pose API disabled... needs full recode too (wait for my doc!) - Game engine will need upgrade too - Depgraph code needs revision, cleanup, can be much faster! (But, compliments for Jean-Luc, it works like a charm!) - IK changed, it now doesnt use previous position to advance to next position anymore. That system looks nice (no flips) but is not well suited for NLA and background render. TODO LATER; We now can do loadsa new nifty features as well; like: - Kill PoseMode (can be option for armatures itself) - Make B-Bones (Bezier, Bspline, like for spines) - Move all silly button level edit to 3d window (like CTRL+I = add IK) - Much better & informative drawing - Fix action/nla editors - Put all ipos in Actions (object, mesh key, lamp color) - Add hooks - Null bones - Much more advanced constraints... Bugfixes; - OGL render (view3d header) had wrong first frame on anim render - Ipo 'recording' mode had wrong playback speed - Vertex-key mode now sticks to show 'active key', until frame change -Ton-
2005-07-03 17:35:38 +00:00
}
Result of 2 weeks of quiet coding work in Greece :) Aim was to get a total refresh of the animation system. This is needed because; - we need to upgrade it with 21st century features - current code is spaghetti/hack combo, and hides good design - it should become lag-free with using dependency graphs A full log, with complete code API/structure/design explanation will follow, that's a load of work... so here below the list with hot changes; - The entire object update system (matrices, geometry) is now centralized. Calls to where_is_object and makeDispList are forbidden, instead we tag objects 'changed' and let the depgraph code sort it out - Removed all old "Ika" code - Depgraph is aware of all relationships, including meta balls, constraints, bevelcurve, and so on. - Made depgraph aware of relation types and layers, to do smart flushing of 'changed' events. Nothing gets calculated too often! - Transform uses depgraph to detect changes - On frame-advance, depgraph flushes animated changes Armatures; Almost all armature related code has been fully built from scratch. It now reveils the original design much better, with a very clean implementation, lag free without even calculating each Bone more than once. Result is quite a speedup yes! Important to note is; 1) Armature is data containing the 'rest position' 2) Pose is the changes of rest position, and always on object level. That way more Objects can use same Pose. Also constraints are in Pose 3) Actions only contain the Ipos to change values in Poses. - Bones draw unrotated now - Drawing bones speedup enormously (10-20 times) - Bone selecting in EditMode, selection state is saved for PoseMode, and vice-versa - Undo in editmode - Bone renaming does vertexgroups, constraints, posechannels, actions, for all users of Armature in entire file - Added Bone renaming in NKey panel - Nkey PoseMode shows eulers now - EditMode and PoseMode now have 'active' bone too (last clicked) - Parenting in EditMode' CTRL+P, ALT+P, with nice options! - Pose is added in Outliner now, with showing that constraints are in the Pose, not Armature - Disconnected IK solving from constraints. It's a separate phase now, on top of the full Pose calculations - Pose itself has a dependency graph too, so evaluation order is lag free. TODO NOW; - Rotating in Posemode has incorrect inverse transform (Martin will fix) - Python Bone/Armature/Pose API disabled... needs full recode too (wait for my doc!) - Game engine will need upgrade too - Depgraph code needs revision, cleanup, can be much faster! (But, compliments for Jean-Luc, it works like a charm!) - IK changed, it now doesnt use previous position to advance to next position anymore. That system looks nice (no flips) but is not well suited for NLA and background render. TODO LATER; We now can do loadsa new nifty features as well; like: - Kill PoseMode (can be option for armatures itself) - Make B-Bones (Bezier, Bspline, like for spines) - Move all silly button level edit to 3d window (like CTRL+I = add IK) - Much better & informative drawing - Fix action/nla editors - Put all ipos in Actions (object, mesh key, lamp color) - Add hooks - Null bones - Much more advanced constraints... Bugfixes; - OGL render (view3d header) had wrong first frame on anim render - Ipo 'recording' mode had wrong playback speed - Vertex-key mode now sticks to show 'active key', until frame change -Ton-
2005-07-03 17:35:38 +00:00
/* and the kiddies */
if (use_recursion) {
bone_parent = bone;
for (bone = bone->childbase.first; bone; bone = bone->next) {
BKE_armature_where_is_bone(bone, bone_parent, use_recursion);
}
2002-10-12 11:37:38 +00:00
}
}
/* updates vectors and matrices on rest-position level, only needed
* after editing armature itself, now only on reading file */
void BKE_armature_where_is(bArmature *arm)
2002-10-12 11:37:38 +00:00
{
Result of 2 weeks of quiet coding work in Greece :) Aim was to get a total refresh of the animation system. This is needed because; - we need to upgrade it with 21st century features - current code is spaghetti/hack combo, and hides good design - it should become lag-free with using dependency graphs A full log, with complete code API/structure/design explanation will follow, that's a load of work... so here below the list with hot changes; - The entire object update system (matrices, geometry) is now centralized. Calls to where_is_object and makeDispList are forbidden, instead we tag objects 'changed' and let the depgraph code sort it out - Removed all old "Ika" code - Depgraph is aware of all relationships, including meta balls, constraints, bevelcurve, and so on. - Made depgraph aware of relation types and layers, to do smart flushing of 'changed' events. Nothing gets calculated too often! - Transform uses depgraph to detect changes - On frame-advance, depgraph flushes animated changes Armatures; Almost all armature related code has been fully built from scratch. It now reveils the original design much better, with a very clean implementation, lag free without even calculating each Bone more than once. Result is quite a speedup yes! Important to note is; 1) Armature is data containing the 'rest position' 2) Pose is the changes of rest position, and always on object level. That way more Objects can use same Pose. Also constraints are in Pose 3) Actions only contain the Ipos to change values in Poses. - Bones draw unrotated now - Drawing bones speedup enormously (10-20 times) - Bone selecting in EditMode, selection state is saved for PoseMode, and vice-versa - Undo in editmode - Bone renaming does vertexgroups, constraints, posechannels, actions, for all users of Armature in entire file - Added Bone renaming in NKey panel - Nkey PoseMode shows eulers now - EditMode and PoseMode now have 'active' bone too (last clicked) - Parenting in EditMode' CTRL+P, ALT+P, with nice options! - Pose is added in Outliner now, with showing that constraints are in the Pose, not Armature - Disconnected IK solving from constraints. It's a separate phase now, on top of the full Pose calculations - Pose itself has a dependency graph too, so evaluation order is lag free. TODO NOW; - Rotating in Posemode has incorrect inverse transform (Martin will fix) - Python Bone/Armature/Pose API disabled... needs full recode too (wait for my doc!) - Game engine will need upgrade too - Depgraph code needs revision, cleanup, can be much faster! (But, compliments for Jean-Luc, it works like a charm!) - IK changed, it now doesnt use previous position to advance to next position anymore. That system looks nice (no flips) but is not well suited for NLA and background render. TODO LATER; We now can do loadsa new nifty features as well; like: - Kill PoseMode (can be option for armatures itself) - Make B-Bones (Bezier, Bspline, like for spines) - Move all silly button level edit to 3d window (like CTRL+I = add IK) - Much better & informative drawing - Fix action/nla editors - Put all ipos in Actions (object, mesh key, lamp color) - Add hooks - Null bones - Much more advanced constraints... Bugfixes; - OGL render (view3d header) had wrong first frame on anim render - Ipo 'recording' mode had wrong playback speed - Vertex-key mode now sticks to show 'active key', until frame change -Ton-
2005-07-03 17:35:38 +00:00
Bone *bone;
Result of 2 weeks of quiet coding work in Greece :) Aim was to get a total refresh of the animation system. This is needed because; - we need to upgrade it with 21st century features - current code is spaghetti/hack combo, and hides good design - it should become lag-free with using dependency graphs A full log, with complete code API/structure/design explanation will follow, that's a load of work... so here below the list with hot changes; - The entire object update system (matrices, geometry) is now centralized. Calls to where_is_object and makeDispList are forbidden, instead we tag objects 'changed' and let the depgraph code sort it out - Removed all old "Ika" code - Depgraph is aware of all relationships, including meta balls, constraints, bevelcurve, and so on. - Made depgraph aware of relation types and layers, to do smart flushing of 'changed' events. Nothing gets calculated too often! - Transform uses depgraph to detect changes - On frame-advance, depgraph flushes animated changes Armatures; Almost all armature related code has been fully built from scratch. It now reveils the original design much better, with a very clean implementation, lag free without even calculating each Bone more than once. Result is quite a speedup yes! Important to note is; 1) Armature is data containing the 'rest position' 2) Pose is the changes of rest position, and always on object level. That way more Objects can use same Pose. Also constraints are in Pose 3) Actions only contain the Ipos to change values in Poses. - Bones draw unrotated now - Drawing bones speedup enormously (10-20 times) - Bone selecting in EditMode, selection state is saved for PoseMode, and vice-versa - Undo in editmode - Bone renaming does vertexgroups, constraints, posechannels, actions, for all users of Armature in entire file - Added Bone renaming in NKey panel - Nkey PoseMode shows eulers now - EditMode and PoseMode now have 'active' bone too (last clicked) - Parenting in EditMode' CTRL+P, ALT+P, with nice options! - Pose is added in Outliner now, with showing that constraints are in the Pose, not Armature - Disconnected IK solving from constraints. It's a separate phase now, on top of the full Pose calculations - Pose itself has a dependency graph too, so evaluation order is lag free. TODO NOW; - Rotating in Posemode has incorrect inverse transform (Martin will fix) - Python Bone/Armature/Pose API disabled... needs full recode too (wait for my doc!) - Game engine will need upgrade too - Depgraph code needs revision, cleanup, can be much faster! (But, compliments for Jean-Luc, it works like a charm!) - IK changed, it now doesnt use previous position to advance to next position anymore. That system looks nice (no flips) but is not well suited for NLA and background render. TODO LATER; We now can do loadsa new nifty features as well; like: - Kill PoseMode (can be option for armatures itself) - Make B-Bones (Bezier, Bspline, like for spines) - Move all silly button level edit to 3d window (like CTRL+I = add IK) - Much better & informative drawing - Fix action/nla editors - Put all ipos in Actions (object, mesh key, lamp color) - Add hooks - Null bones - Much more advanced constraints... Bugfixes; - OGL render (view3d header) had wrong first frame on anim render - Ipo 'recording' mode had wrong playback speed - Vertex-key mode now sticks to show 'active key', until frame change -Ton-
2005-07-03 17:35:38 +00:00
/* hierarchical from root to children */
for (bone = arm->bonebase.first; bone; bone = bone->next) {
BKE_armature_where_is_bone(bone, NULL, true);
Result of 2 weeks of quiet coding work in Greece :) Aim was to get a total refresh of the animation system. This is needed because; - we need to upgrade it with 21st century features - current code is spaghetti/hack combo, and hides good design - it should become lag-free with using dependency graphs A full log, with complete code API/structure/design explanation will follow, that's a load of work... so here below the list with hot changes; - The entire object update system (matrices, geometry) is now centralized. Calls to where_is_object and makeDispList are forbidden, instead we tag objects 'changed' and let the depgraph code sort it out - Removed all old "Ika" code - Depgraph is aware of all relationships, including meta balls, constraints, bevelcurve, and so on. - Made depgraph aware of relation types and layers, to do smart flushing of 'changed' events. Nothing gets calculated too often! - Transform uses depgraph to detect changes - On frame-advance, depgraph flushes animated changes Armatures; Almost all armature related code has been fully built from scratch. It now reveils the original design much better, with a very clean implementation, lag free without even calculating each Bone more than once. Result is quite a speedup yes! Important to note is; 1) Armature is data containing the 'rest position' 2) Pose is the changes of rest position, and always on object level. That way more Objects can use same Pose. Also constraints are in Pose 3) Actions only contain the Ipos to change values in Poses. - Bones draw unrotated now - Drawing bones speedup enormously (10-20 times) - Bone selecting in EditMode, selection state is saved for PoseMode, and vice-versa - Undo in editmode - Bone renaming does vertexgroups, constraints, posechannels, actions, for all users of Armature in entire file - Added Bone renaming in NKey panel - Nkey PoseMode shows eulers now - EditMode and PoseMode now have 'active' bone too (last clicked) - Parenting in EditMode' CTRL+P, ALT+P, with nice options! - Pose is added in Outliner now, with showing that constraints are in the Pose, not Armature - Disconnected IK solving from constraints. It's a separate phase now, on top of the full Pose calculations - Pose itself has a dependency graph too, so evaluation order is lag free. TODO NOW; - Rotating in Posemode has incorrect inverse transform (Martin will fix) - Python Bone/Armature/Pose API disabled... needs full recode too (wait for my doc!) - Game engine will need upgrade too - Depgraph code needs revision, cleanup, can be much faster! (But, compliments for Jean-Luc, it works like a charm!) - IK changed, it now doesnt use previous position to advance to next position anymore. That system looks nice (no flips) but is not well suited for NLA and background render. TODO LATER; We now can do loadsa new nifty features as well; like: - Kill PoseMode (can be option for armatures itself) - Make B-Bones (Bezier, Bspline, like for spines) - Move all silly button level edit to 3d window (like CTRL+I = add IK) - Much better & informative drawing - Fix action/nla editors - Put all ipos in Actions (object, mesh key, lamp color) - Add hooks - Null bones - Much more advanced constraints... Bugfixes; - OGL render (view3d header) had wrong first frame on anim render - Ipo 'recording' mode had wrong playback speed - Vertex-key mode now sticks to show 'active key', until frame change -Ton-
2005-07-03 17:35:38 +00:00
}
}
2002-10-12 11:37:38 +00:00
/** \} */
/* -------------------------------------------------------------------- */
/** \name Pose Rebuild
* \{ */
/* if bone layer is protected, copy the data from from->pose
* when used with linked libraries this copies from the linked pose into the local pose */
static void pose_proxy_sync(Object *ob, Object *from, int layer_protected)
{
bPose *pose = ob->pose, *frompose = from->pose;
bPoseChannel *pchan, *pchanp;
bConstraint *con;
int error = 0;
if (frompose == NULL) {
return;
}
/* in some cases when rigs change, we cant synchronize
* to avoid crashing check for possible errors here */
for (pchan = pose->chanbase.first; pchan; pchan = pchan->next) {
if (pchan->bone->layer & layer_protected) {
if (BKE_pose_channel_find_name(frompose, pchan->name) == NULL) {
CLOG_ERROR(&LOG,
"failed to sync proxy armature because '%s' is missing pose channel '%s'",
from->id.name,
pchan->name);
error = 1;
}
}
}
if (error) {
return;
}
/* clear all transformation values from library */
BKE_pose_rest(frompose, false);
/* copy over all of the proxy's bone groups */
/* TODO for later
* - implement 'local' bone groups as for constraints
* Note: this isn't trivial, as bones reference groups by index not by pointer,
* so syncing things correctly needs careful attention */
BLI_freelistN(&pose->agroups);
Merge of trunk into blender 2.5: svn merge https://svn.blender.org/svnroot/bf-blender/trunk/blender -r12987:17416 Issues: * GHOST/X11 had conflicting changes. Some code was added in 2.5, which was later added in trunk also, but reverted partially, specifically revision 16683. I have left out this reversion in the 2.5 branch since I think it is needed there. http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=16683 * Scons had various conflicting changes, I decided to go with trunk version for everything except priorities and some library renaming. * In creator.c, there were various fixes and fixes for fixes related to the -w -W and -p options. In 2.5 -w and -W is not coded yet, and -p is done differently. Since this is changed so much, and I don't think those fixes would be needed in 2.5, I've left them out. * Also in creator.c: there was code for a python bugfix where the screen was not initialized when running with -P. The code that initializes the screen there I had to disable, that can't work in 2.5 anymore but left it commented as a reminder. Further I had to disable some new function calls. using src/ and python/, as was done already in this branch, disabled function calls: * bpath.c: error reporting * BME_conversions.c: editmesh conversion functions. * SHD_dynamic: disabled almost completely, there is no python/. * KX_PythonInit.cpp and Ketsji/ build files: Mathutils is not there, disabled. * text.c: clipboard copy call. * object.c: OB_SUPPORT_MATERIAL. * DerivedMesh.c and subsurf_ccg, stipple_quarttone. Still to be done: * Go over files and functions that were moved to a different location but could still use changes that were done in trunk.
2008-11-12 21:16:53 +00:00
BLI_duplicatelist(&pose->agroups, &frompose->agroups);
pose->active_group = frompose->active_group;
for (pchan = pose->chanbase.first; pchan; pchan = pchan->next) {
pchanp = BKE_pose_channel_find_name(frompose, pchan->name);
if (UNLIKELY(pchanp == NULL)) {
/* happens for proxies that become invalid because of a missing link
2012-10-20 20:36:51 +00:00
* for regular cases it shouldn't happen at all */
}
else if (pchan->bone->layer & layer_protected) {
ListBase proxylocal_constraints = {NULL, NULL};
bPoseChannel pchanw;
/* copy posechannel to temp, but restore important pointers */
pchanw = *pchanp;
pchanw.bone = pchan->bone;
pchanw.prev = pchan->prev;
pchanw.next = pchan->next;
pchanw.parent = pchan->parent;
pchanw.child = pchan->child;
pchanw.custom_tx = pchan->custom_tx;
pchanw.bbone_prev = pchan->bbone_prev;
pchanw.bbone_next = pchan->bbone_next;
pchanw.mpath = pchan->mpath;
pchan->mpath = NULL;
/* Reset runtime data, we don't want to share that with the proxy. */
BKE_pose_channel_runtime_reset_on_copy(&pchanw.runtime);
/* this is freed so copy a copy, else undo crashes */
if (pchanw.prop) {
pchanw.prop = IDP_CopyProperty(pchanw.prop);
2014-10-29 14:11:19 +01:00
/* use the values from the existing props */
if (pchan->prop) {
IDP_SyncGroupValues(pchanw.prop, pchan->prop);
}
}
/* Constraints - proxy constraints are flushed... local ones are added after
* 1: extract constraints not from proxy (CONSTRAINT_PROXY_LOCAL) from pchan's constraints.
* 2: copy proxy-pchan's constraints on-to new.
* 3: add extracted local constraints back on top.
*
* Note for BKE_constraints_copy:
* When copying constraints, disable 'do_extern' otherwise
* we get the libs direct linked in this blend.
*/
BKE_constraints_proxylocal_extract(&proxylocal_constraints, &pchan->constraints);
BKE_constraints_copy(&pchanw.constraints, &pchanp->constraints, false);
BLI_movelisttolist(&pchanw.constraints, &proxylocal_constraints);
/* constraints - set target ob pointer to own object */
for (con = pchanw.constraints.first; con; con = con->next) {
2015-03-30 21:17:07 +11:00
const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con);
ListBase targets = {NULL, NULL};
bConstraintTarget *ct;
if (cti && cti->get_constraint_targets) {
cti->get_constraint_targets(con, &targets);
for (ct = targets.first; ct; ct = ct->next) {
if (ct->tar == from) {
ct->tar = ob;
}
}
if (cti->flush_constraint_targets) {
cti->flush_constraint_targets(con, &targets, 0);
}
}
}
/* free stuff from current channel */
BKE_pose_channel_free(pchan);
/* copy data in temp back over to the cleaned-out (but still allocated) original channel */
*pchan = pchanw;
if (pchan->custom) {
id_us_plus(&pchan->custom->id);
}
}
else {
/* always copy custom shape */
pchan->custom = pchanp->custom;
if (pchan->custom) {
id_us_plus(&pchan->custom->id);
}
if (pchanp->custom_tx) {
pchan->custom_tx = BKE_pose_channel_find_name(pose, pchanp->custom_tx->name);
}
/* ID-Property Syncing */
{
IDProperty *prop_orig = pchan->prop;
if (pchanp->prop) {
pchan->prop = IDP_CopyProperty(pchanp->prop);
if (prop_orig) {
/* copy existing values across when types match */
IDP_SyncGroupValues(pchan->prop, prop_orig);
}
}
else {
pchan->prop = NULL;
}
if (prop_orig) {
IDP_FreeProperty(prop_orig);
}
}
}
}
}
/**
* \param r_last_visited_bone_p: The last bone handled by the last call to this function.
*/
static int rebuild_pose_bone(
bPose *pose, Bone *bone, bPoseChannel *parchan, int counter, Bone **r_last_visited_bone_p)
Result of 2 weeks of quiet coding work in Greece :) Aim was to get a total refresh of the animation system. This is needed because; - we need to upgrade it with 21st century features - current code is spaghetti/hack combo, and hides good design - it should become lag-free with using dependency graphs A full log, with complete code API/structure/design explanation will follow, that's a load of work... so here below the list with hot changes; - The entire object update system (matrices, geometry) is now centralized. Calls to where_is_object and makeDispList are forbidden, instead we tag objects 'changed' and let the depgraph code sort it out - Removed all old "Ika" code - Depgraph is aware of all relationships, including meta balls, constraints, bevelcurve, and so on. - Made depgraph aware of relation types and layers, to do smart flushing of 'changed' events. Nothing gets calculated too often! - Transform uses depgraph to detect changes - On frame-advance, depgraph flushes animated changes Armatures; Almost all armature related code has been fully built from scratch. It now reveils the original design much better, with a very clean implementation, lag free without even calculating each Bone more than once. Result is quite a speedup yes! Important to note is; 1) Armature is data containing the 'rest position' 2) Pose is the changes of rest position, and always on object level. That way more Objects can use same Pose. Also constraints are in Pose 3) Actions only contain the Ipos to change values in Poses. - Bones draw unrotated now - Drawing bones speedup enormously (10-20 times) - Bone selecting in EditMode, selection state is saved for PoseMode, and vice-versa - Undo in editmode - Bone renaming does vertexgroups, constraints, posechannels, actions, for all users of Armature in entire file - Added Bone renaming in NKey panel - Nkey PoseMode shows eulers now - EditMode and PoseMode now have 'active' bone too (last clicked) - Parenting in EditMode' CTRL+P, ALT+P, with nice options! - Pose is added in Outliner now, with showing that constraints are in the Pose, not Armature - Disconnected IK solving from constraints. It's a separate phase now, on top of the full Pose calculations - Pose itself has a dependency graph too, so evaluation order is lag free. TODO NOW; - Rotating in Posemode has incorrect inverse transform (Martin will fix) - Python Bone/Armature/Pose API disabled... needs full recode too (wait for my doc!) - Game engine will need upgrade too - Depgraph code needs revision, cleanup, can be much faster! (But, compliments for Jean-Luc, it works like a charm!) - IK changed, it now doesnt use previous position to advance to next position anymore. That system looks nice (no flips) but is not well suited for NLA and background render. TODO LATER; We now can do loadsa new nifty features as well; like: - Kill PoseMode (can be option for armatures itself) - Make B-Bones (Bezier, Bspline, like for spines) - Move all silly button level edit to 3d window (like CTRL+I = add IK) - Much better & informative drawing - Fix action/nla editors - Put all ipos in Actions (object, mesh key, lamp color) - Add hooks - Null bones - Much more advanced constraints... Bugfixes; - OGL render (view3d header) had wrong first frame on anim render - Ipo 'recording' mode had wrong playback speed - Vertex-key mode now sticks to show 'active key', until frame change -Ton-
2005-07-03 17:35:38 +00:00
{
bPoseChannel *pchan = BKE_pose_channel_verify(pose, bone->name); /* verify checks and/or adds */
pchan->bone = bone;
pchan->parent = parchan;
2002-10-12 11:37:38 +00:00
/* We ensure the current pchan is immediately after the one we just generated/updated in the
* previous call to `rebuild_pose_bone`.
*
* It may be either the parent, the previous sibling, or the last
* (grand-(grand-(...)))-child (as processed by the recursive, depth-first nature of this
* function) of the previous sibling.
*
* Note: In most cases there is nothing to do here, but pose list may get out of order when some
* bones are added, removed or moved in the armature data. */
bPoseChannel *pchan_prev = pchan->prev;
const Bone *last_visited_bone = *r_last_visited_bone_p;
if ((pchan_prev == NULL && last_visited_bone != NULL) ||
(pchan_prev != NULL && pchan_prev->bone != last_visited_bone)) {
pchan_prev = last_visited_bone != NULL ?
BKE_pose_channel_find_name(pose, last_visited_bone->name) :
NULL;
BLI_remlink(&pose->chanbase, pchan);
BLI_insertlinkafter(&pose->chanbase, pchan_prev, pchan);
}
*r_last_visited_bone_p = pchan->bone;
Result of 2 weeks of quiet coding work in Greece :) Aim was to get a total refresh of the animation system. This is needed because; - we need to upgrade it with 21st century features - current code is spaghetti/hack combo, and hides good design - it should become lag-free with using dependency graphs A full log, with complete code API/structure/design explanation will follow, that's a load of work... so here below the list with hot changes; - The entire object update system (matrices, geometry) is now centralized. Calls to where_is_object and makeDispList are forbidden, instead we tag objects 'changed' and let the depgraph code sort it out - Removed all old "Ika" code - Depgraph is aware of all relationships, including meta balls, constraints, bevelcurve, and so on. - Made depgraph aware of relation types and layers, to do smart flushing of 'changed' events. Nothing gets calculated too often! - Transform uses depgraph to detect changes - On frame-advance, depgraph flushes animated changes Armatures; Almost all armature related code has been fully built from scratch. It now reveils the original design much better, with a very clean implementation, lag free without even calculating each Bone more than once. Result is quite a speedup yes! Important to note is; 1) Armature is data containing the 'rest position' 2) Pose is the changes of rest position, and always on object level. That way more Objects can use same Pose. Also constraints are in Pose 3) Actions only contain the Ipos to change values in Poses. - Bones draw unrotated now - Drawing bones speedup enormously (10-20 times) - Bone selecting in EditMode, selection state is saved for PoseMode, and vice-versa - Undo in editmode - Bone renaming does vertexgroups, constraints, posechannels, actions, for all users of Armature in entire file - Added Bone renaming in NKey panel - Nkey PoseMode shows eulers now - EditMode and PoseMode now have 'active' bone too (last clicked) - Parenting in EditMode' CTRL+P, ALT+P, with nice options! - Pose is added in Outliner now, with showing that constraints are in the Pose, not Armature - Disconnected IK solving from constraints. It's a separate phase now, on top of the full Pose calculations - Pose itself has a dependency graph too, so evaluation order is lag free. TODO NOW; - Rotating in Posemode has incorrect inverse transform (Martin will fix) - Python Bone/Armature/Pose API disabled... needs full recode too (wait for my doc!) - Game engine will need upgrade too - Depgraph code needs revision, cleanup, can be much faster! (But, compliments for Jean-Luc, it works like a charm!) - IK changed, it now doesnt use previous position to advance to next position anymore. That system looks nice (no flips) but is not well suited for NLA and background render. TODO LATER; We now can do loadsa new nifty features as well; like: - Kill PoseMode (can be option for armatures itself) - Make B-Bones (Bezier, Bspline, like for spines) - Move all silly button level edit to 3d window (like CTRL+I = add IK) - Much better & informative drawing - Fix action/nla editors - Put all ipos in Actions (object, mesh key, lamp color) - Add hooks - Null bones - Much more advanced constraints... Bugfixes; - OGL render (view3d header) had wrong first frame on anim render - Ipo 'recording' mode had wrong playback speed - Vertex-key mode now sticks to show 'active key', until frame change -Ton-
2005-07-03 17:35:38 +00:00
counter++;
for (bone = bone->childbase.first; bone; bone = bone->next) {
counter = rebuild_pose_bone(pose, bone, pchan, counter, r_last_visited_bone_p);
Integration of new IK lib features in Armature Poses. Best is to forget yesterday's commit and old docs. New docs are underway... Here's how IK works now; - IK chains can go all the way to the furthest parent Bone. Disregarding the old option "IK to Parent" and disgregarding whether a Bone has an offset to its parent (offsets now work for IK, so you can also make T-bones). - The old "IK to Parent" option now only does what it should do: it denotes whether a Bone is directly connected to a Parent Bone, or not. In the UI and in code this option is now called "Connected". - You can also define yourself which Bone will become the "Root" for an IK chain. This can be any Parent of the IK tip (where the IK constraint is). By default it goes all the way, unless you set a value for the new IK Constraint Panel option "Chain Lenght". - "Tree IK" now is detected automatic, when multiple IK Roots are on the same Bone, and when there's a branched structure. Multiple IK's on a single chain (no branches) is still executed as usual, doing the IK's sequentially. - Note: Branched structures, with _partial_ overlapping IK chains, that don't share the same Root will possibly disconnect branches. - When you select a Bone with IK, it now draws a yellow dashed line to its Root. - The IK options "Location Weight" and "Rotation Weight" are relative, in case there's a Tree IK structure. These weights cannot be set to zero. To animate or disable IK Targets, use the "Influence" slider. - This new IK is backwards and upwards compatible for Blender files. Of course, the new features won't show in older Blender binaries! :) Other changes & notes; - In PoseMode, the Constraint Panel now also draws in Editing Buttons, next to the Bones Panel. - IK Constraint Panel was redesigned... it's still a bit squished - Buttons "No X DoF" is now called "Lock X". This to follow convention to name options positive. - Added Undo push for Make/Clear Parent in Editmode Armature - Use CTRL+P "Make Parent" on a single selected Bone to make it become connected (ALT+P had already "Disconnect"). On todo next; Visualizing & review of Bone DoF limits and stiffness
2005-08-28 12:23:06 +00:00
/* for quick detecting of next bone in chain, only b-bone uses it now */
if (bone->flag & BONE_CONNECTED) {
pchan->child = BKE_pose_channel_find_name(pose, bone->name);
}
2002-10-12 11:37:38 +00:00
}
Result of 2 weeks of quiet coding work in Greece :) Aim was to get a total refresh of the animation system. This is needed because; - we need to upgrade it with 21st century features - current code is spaghetti/hack combo, and hides good design - it should become lag-free with using dependency graphs A full log, with complete code API/structure/design explanation will follow, that's a load of work... so here below the list with hot changes; - The entire object update system (matrices, geometry) is now centralized. Calls to where_is_object and makeDispList are forbidden, instead we tag objects 'changed' and let the depgraph code sort it out - Removed all old "Ika" code - Depgraph is aware of all relationships, including meta balls, constraints, bevelcurve, and so on. - Made depgraph aware of relation types and layers, to do smart flushing of 'changed' events. Nothing gets calculated too often! - Transform uses depgraph to detect changes - On frame-advance, depgraph flushes animated changes Armatures; Almost all armature related code has been fully built from scratch. It now reveils the original design much better, with a very clean implementation, lag free without even calculating each Bone more than once. Result is quite a speedup yes! Important to note is; 1) Armature is data containing the 'rest position' 2) Pose is the changes of rest position, and always on object level. That way more Objects can use same Pose. Also constraints are in Pose 3) Actions only contain the Ipos to change values in Poses. - Bones draw unrotated now - Drawing bones speedup enormously (10-20 times) - Bone selecting in EditMode, selection state is saved for PoseMode, and vice-versa - Undo in editmode - Bone renaming does vertexgroups, constraints, posechannels, actions, for all users of Armature in entire file - Added Bone renaming in NKey panel - Nkey PoseMode shows eulers now - EditMode and PoseMode now have 'active' bone too (last clicked) - Parenting in EditMode' CTRL+P, ALT+P, with nice options! - Pose is added in Outliner now, with showing that constraints are in the Pose, not Armature - Disconnected IK solving from constraints. It's a separate phase now, on top of the full Pose calculations - Pose itself has a dependency graph too, so evaluation order is lag free. TODO NOW; - Rotating in Posemode has incorrect inverse transform (Martin will fix) - Python Bone/Armature/Pose API disabled... needs full recode too (wait for my doc!) - Game engine will need upgrade too - Depgraph code needs revision, cleanup, can be much faster! (But, compliments for Jean-Luc, it works like a charm!) - IK changed, it now doesnt use previous position to advance to next position anymore. That system looks nice (no flips) but is not well suited for NLA and background render. TODO LATER; We now can do loadsa new nifty features as well; like: - Kill PoseMode (can be option for armatures itself) - Make B-Bones (Bezier, Bspline, like for spines) - Move all silly button level edit to 3d window (like CTRL+I = add IK) - Much better & informative drawing - Fix action/nla editors - Put all ipos in Actions (object, mesh key, lamp color) - Add hooks - Null bones - Much more advanced constraints... Bugfixes; - OGL render (view3d header) had wrong first frame on anim render - Ipo 'recording' mode had wrong playback speed - Vertex-key mode now sticks to show 'active key', until frame change -Ton-
2005-07-03 17:35:38 +00:00
return counter;
2002-10-12 11:37:38 +00:00
}
/**
* Clear pointers of object's pose
* (needed in remap case, since we cannot always wait for a complete pose rebuild).
*/
void BKE_pose_clear_pointers(bPose *pose)
{
LISTBASE_FOREACH (bPoseChannel *, pchan, &pose->chanbase) {
pchan->bone = NULL;
pchan->child = NULL;
}
}
void BKE_pose_remap_bone_pointers(bArmature *armature, bPose *pose)
{
LISTBASE_FOREACH (bPoseChannel *, pchan, &pose->chanbase) {
pchan->bone = BKE_armature_find_bone_name(armature, pchan->name);
}
}
/** Find the matching pose channel using the bone name, if not NULL. */
static bPoseChannel *pose_channel_find_bone(bPose *pose, Bone *bone)
{
return (bone != NULL) ? BKE_pose_channel_find_name(pose, bone->name) : NULL;
}
/** Update the links for the B-Bone handles from Bone data. */
void BKE_pchan_rebuild_bbone_handles(bPose *pose, bPoseChannel *pchan)
{
pchan->bbone_prev = pose_channel_find_bone(pose, pchan->bone->bbone_prev);
pchan->bbone_next = pose_channel_find_bone(pose, pchan->bone->bbone_next);
}
/**
* Only after leave editmode, duplicating, validating older files, library syncing.
*
* \note pose->flag is set for it.
*
2018-12-12 12:55:20 +11:00
* \param bmain: May be NULL, only used to tag depsgraph as being dirty...
*/
void BKE_pose_rebuild(Main *bmain, Object *ob, bArmature *arm, const bool do_id_user)
2002-10-12 11:37:38 +00:00
{
Result of 2 weeks of quiet coding work in Greece :) Aim was to get a total refresh of the animation system. This is needed because; - we need to upgrade it with 21st century features - current code is spaghetti/hack combo, and hides good design - it should become lag-free with using dependency graphs A full log, with complete code API/structure/design explanation will follow, that's a load of work... so here below the list with hot changes; - The entire object update system (matrices, geometry) is now centralized. Calls to where_is_object and makeDispList are forbidden, instead we tag objects 'changed' and let the depgraph code sort it out - Removed all old "Ika" code - Depgraph is aware of all relationships, including meta balls, constraints, bevelcurve, and so on. - Made depgraph aware of relation types and layers, to do smart flushing of 'changed' events. Nothing gets calculated too often! - Transform uses depgraph to detect changes - On frame-advance, depgraph flushes animated changes Armatures; Almost all armature related code has been fully built from scratch. It now reveils the original design much better, with a very clean implementation, lag free without even calculating each Bone more than once. Result is quite a speedup yes! Important to note is; 1) Armature is data containing the 'rest position' 2) Pose is the changes of rest position, and always on object level. That way more Objects can use same Pose. Also constraints are in Pose 3) Actions only contain the Ipos to change values in Poses. - Bones draw unrotated now - Drawing bones speedup enormously (10-20 times) - Bone selecting in EditMode, selection state is saved for PoseMode, and vice-versa - Undo in editmode - Bone renaming does vertexgroups, constraints, posechannels, actions, for all users of Armature in entire file - Added Bone renaming in NKey panel - Nkey PoseMode shows eulers now - EditMode and PoseMode now have 'active' bone too (last clicked) - Parenting in EditMode' CTRL+P, ALT+P, with nice options! - Pose is added in Outliner now, with showing that constraints are in the Pose, not Armature - Disconnected IK solving from constraints. It's a separate phase now, on top of the full Pose calculations - Pose itself has a dependency graph too, so evaluation order is lag free. TODO NOW; - Rotating in Posemode has incorrect inverse transform (Martin will fix) - Python Bone/Armature/Pose API disabled... needs full recode too (wait for my doc!) - Game engine will need upgrade too - Depgraph code needs revision, cleanup, can be much faster! (But, compliments for Jean-Luc, it works like a charm!) - IK changed, it now doesnt use previous position to advance to next position anymore. That system looks nice (no flips) but is not well suited for NLA and background render. TODO LATER; We now can do loadsa new nifty features as well; like: - Kill PoseMode (can be option for armatures itself) - Make B-Bones (Bezier, Bspline, like for spines) - Move all silly button level edit to 3d window (like CTRL+I = add IK) - Much better & informative drawing - Fix action/nla editors - Put all ipos in Actions (object, mesh key, lamp color) - Add hooks - Null bones - Much more advanced constraints... Bugfixes; - OGL render (view3d header) had wrong first frame on anim render - Ipo 'recording' mode had wrong playback speed - Vertex-key mode now sticks to show 'active key', until frame change -Ton-
2005-07-03 17:35:38 +00:00
Bone *bone;
bPose *pose;
bPoseChannel *pchan, *next;
int counter = 0;
Result of 2 weeks of quiet coding work in Greece :) Aim was to get a total refresh of the animation system. This is needed because; - we need to upgrade it with 21st century features - current code is spaghetti/hack combo, and hides good design - it should become lag-free with using dependency graphs A full log, with complete code API/structure/design explanation will follow, that's a load of work... so here below the list with hot changes; - The entire object update system (matrices, geometry) is now centralized. Calls to where_is_object and makeDispList are forbidden, instead we tag objects 'changed' and let the depgraph code sort it out - Removed all old "Ika" code - Depgraph is aware of all relationships, including meta balls, constraints, bevelcurve, and so on. - Made depgraph aware of relation types and layers, to do smart flushing of 'changed' events. Nothing gets calculated too often! - Transform uses depgraph to detect changes - On frame-advance, depgraph flushes animated changes Armatures; Almost all armature related code has been fully built from scratch. It now reveils the original design much better, with a very clean implementation, lag free without even calculating each Bone more than once. Result is quite a speedup yes! Important to note is; 1) Armature is data containing the 'rest position' 2) Pose is the changes of rest position, and always on object level. That way more Objects can use same Pose. Also constraints are in Pose 3) Actions only contain the Ipos to change values in Poses. - Bones draw unrotated now - Drawing bones speedup enormously (10-20 times) - Bone selecting in EditMode, selection state is saved for PoseMode, and vice-versa - Undo in editmode - Bone renaming does vertexgroups, constraints, posechannels, actions, for all users of Armature in entire file - Added Bone renaming in NKey panel - Nkey PoseMode shows eulers now - EditMode and PoseMode now have 'active' bone too (last clicked) - Parenting in EditMode' CTRL+P, ALT+P, with nice options! - Pose is added in Outliner now, with showing that constraints are in the Pose, not Armature - Disconnected IK solving from constraints. It's a separate phase now, on top of the full Pose calculations - Pose itself has a dependency graph too, so evaluation order is lag free. TODO NOW; - Rotating in Posemode has incorrect inverse transform (Martin will fix) - Python Bone/Armature/Pose API disabled... needs full recode too (wait for my doc!) - Game engine will need upgrade too - Depgraph code needs revision, cleanup, can be much faster! (But, compliments for Jean-Luc, it works like a charm!) - IK changed, it now doesnt use previous position to advance to next position anymore. That system looks nice (no flips) but is not well suited for NLA and background render. TODO LATER; We now can do loadsa new nifty features as well; like: - Kill PoseMode (can be option for armatures itself) - Make B-Bones (Bezier, Bspline, like for spines) - Move all silly button level edit to 3d window (like CTRL+I = add IK) - Much better & informative drawing - Fix action/nla editors - Put all ipos in Actions (object, mesh key, lamp color) - Add hooks - Null bones - Much more advanced constraints... Bugfixes; - OGL render (view3d header) had wrong first frame on anim render - Ipo 'recording' mode had wrong playback speed - Vertex-key mode now sticks to show 'active key', until frame change -Ton-
2005-07-03 17:35:38 +00:00
/* only done here */
if (ob->pose == NULL) {
/* create new pose */
ob->pose = MEM_callocN(sizeof(bPose), "new pose");
/* set default settings for animviz */
animviz_settings_init(&ob->pose->avs);
}
pose = ob->pose;
/* clear */
BKE_pose_clear_pointers(pose);
/* first step, check if all channels are there */
Bone *prev_bone = NULL;
for (bone = arm->bonebase.first; bone; bone = bone->next) {
counter = rebuild_pose_bone(pose, bone, NULL, counter, &prev_bone);
Result of 2 weeks of quiet coding work in Greece :) Aim was to get a total refresh of the animation system. This is needed because; - we need to upgrade it with 21st century features - current code is spaghetti/hack combo, and hides good design - it should become lag-free with using dependency graphs A full log, with complete code API/structure/design explanation will follow, that's a load of work... so here below the list with hot changes; - The entire object update system (matrices, geometry) is now centralized. Calls to where_is_object and makeDispList are forbidden, instead we tag objects 'changed' and let the depgraph code sort it out - Removed all old "Ika" code - Depgraph is aware of all relationships, including meta balls, constraints, bevelcurve, and so on. - Made depgraph aware of relation types and layers, to do smart flushing of 'changed' events. Nothing gets calculated too often! - Transform uses depgraph to detect changes - On frame-advance, depgraph flushes animated changes Armatures; Almost all armature related code has been fully built from scratch. It now reveils the original design much better, with a very clean implementation, lag free without even calculating each Bone more than once. Result is quite a speedup yes! Important to note is; 1) Armature is data containing the 'rest position' 2) Pose is the changes of rest position, and always on object level. That way more Objects can use same Pose. Also constraints are in Pose 3) Actions only contain the Ipos to change values in Poses. - Bones draw unrotated now - Drawing bones speedup enormously (10-20 times) - Bone selecting in EditMode, selection state is saved for PoseMode, and vice-versa - Undo in editmode - Bone renaming does vertexgroups, constraints, posechannels, actions, for all users of Armature in entire file - Added Bone renaming in NKey panel - Nkey PoseMode shows eulers now - EditMode and PoseMode now have 'active' bone too (last clicked) - Parenting in EditMode' CTRL+P, ALT+P, with nice options! - Pose is added in Outliner now, with showing that constraints are in the Pose, not Armature - Disconnected IK solving from constraints. It's a separate phase now, on top of the full Pose calculations - Pose itself has a dependency graph too, so evaluation order is lag free. TODO NOW; - Rotating in Posemode has incorrect inverse transform (Martin will fix) - Python Bone/Armature/Pose API disabled... needs full recode too (wait for my doc!) - Game engine will need upgrade too - Depgraph code needs revision, cleanup, can be much faster! (But, compliments for Jean-Luc, it works like a charm!) - IK changed, it now doesnt use previous position to advance to next position anymore. That system looks nice (no flips) but is not well suited for NLA and background render. TODO LATER; We now can do loadsa new nifty features as well; like: - Kill PoseMode (can be option for armatures itself) - Make B-Bones (Bezier, Bspline, like for spines) - Move all silly button level edit to 3d window (like CTRL+I = add IK) - Much better & informative drawing - Fix action/nla editors - Put all ipos in Actions (object, mesh key, lamp color) - Add hooks - Null bones - Much more advanced constraints... Bugfixes; - OGL render (view3d header) had wrong first frame on anim render - Ipo 'recording' mode had wrong playback speed - Vertex-key mode now sticks to show 'active key', until frame change -Ton-
2005-07-03 17:35:38 +00:00
}
2002-10-12 11:37:38 +00:00
Result of 2 weeks of quiet coding work in Greece :) Aim was to get a total refresh of the animation system. This is needed because; - we need to upgrade it with 21st century features - current code is spaghetti/hack combo, and hides good design - it should become lag-free with using dependency graphs A full log, with complete code API/structure/design explanation will follow, that's a load of work... so here below the list with hot changes; - The entire object update system (matrices, geometry) is now centralized. Calls to where_is_object and makeDispList are forbidden, instead we tag objects 'changed' and let the depgraph code sort it out - Removed all old "Ika" code - Depgraph is aware of all relationships, including meta balls, constraints, bevelcurve, and so on. - Made depgraph aware of relation types and layers, to do smart flushing of 'changed' events. Nothing gets calculated too often! - Transform uses depgraph to detect changes - On frame-advance, depgraph flushes animated changes Armatures; Almost all armature related code has been fully built from scratch. It now reveils the original design much better, with a very clean implementation, lag free without even calculating each Bone more than once. Result is quite a speedup yes! Important to note is; 1) Armature is data containing the 'rest position' 2) Pose is the changes of rest position, and always on object level. That way more Objects can use same Pose. Also constraints are in Pose 3) Actions only contain the Ipos to change values in Poses. - Bones draw unrotated now - Drawing bones speedup enormously (10-20 times) - Bone selecting in EditMode, selection state is saved for PoseMode, and vice-versa - Undo in editmode - Bone renaming does vertexgroups, constraints, posechannels, actions, for all users of Armature in entire file - Added Bone renaming in NKey panel - Nkey PoseMode shows eulers now - EditMode and PoseMode now have 'active' bone too (last clicked) - Parenting in EditMode' CTRL+P, ALT+P, with nice options! - Pose is added in Outliner now, with showing that constraints are in the Pose, not Armature - Disconnected IK solving from constraints. It's a separate phase now, on top of the full Pose calculations - Pose itself has a dependency graph too, so evaluation order is lag free. TODO NOW; - Rotating in Posemode has incorrect inverse transform (Martin will fix) - Python Bone/Armature/Pose API disabled... needs full recode too (wait for my doc!) - Game engine will need upgrade too - Depgraph code needs revision, cleanup, can be much faster! (But, compliments for Jean-Luc, it works like a charm!) - IK changed, it now doesnt use previous position to advance to next position anymore. That system looks nice (no flips) but is not well suited for NLA and background render. TODO LATER; We now can do loadsa new nifty features as well; like: - Kill PoseMode (can be option for armatures itself) - Make B-Bones (Bezier, Bspline, like for spines) - Move all silly button level edit to 3d window (like CTRL+I = add IK) - Much better & informative drawing - Fix action/nla editors - Put all ipos in Actions (object, mesh key, lamp color) - Add hooks - Null bones - Much more advanced constraints... Bugfixes; - OGL render (view3d header) had wrong first frame on anim render - Ipo 'recording' mode had wrong playback speed - Vertex-key mode now sticks to show 'active key', until frame change -Ton-
2005-07-03 17:35:38 +00:00
/* and a check for garbage */
for (pchan = pose->chanbase.first; pchan; pchan = next) {
next = pchan->next;
if (pchan->bone == NULL) {
BKE_pose_channel_free_ex(pchan, do_id_user);
BKE_pose_channels_hash_free(pose);
BLI_freelinkN(&pose->chanbase, pchan);
Result of 2 weeks of quiet coding work in Greece :) Aim was to get a total refresh of the animation system. This is needed because; - we need to upgrade it with 21st century features - current code is spaghetti/hack combo, and hides good design - it should become lag-free with using dependency graphs A full log, with complete code API/structure/design explanation will follow, that's a load of work... so here below the list with hot changes; - The entire object update system (matrices, geometry) is now centralized. Calls to where_is_object and makeDispList are forbidden, instead we tag objects 'changed' and let the depgraph code sort it out - Removed all old "Ika" code - Depgraph is aware of all relationships, including meta balls, constraints, bevelcurve, and so on. - Made depgraph aware of relation types and layers, to do smart flushing of 'changed' events. Nothing gets calculated too often! - Transform uses depgraph to detect changes - On frame-advance, depgraph flushes animated changes Armatures; Almost all armature related code has been fully built from scratch. It now reveils the original design much better, with a very clean implementation, lag free without even calculating each Bone more than once. Result is quite a speedup yes! Important to note is; 1) Armature is data containing the 'rest position' 2) Pose is the changes of rest position, and always on object level. That way more Objects can use same Pose. Also constraints are in Pose 3) Actions only contain the Ipos to change values in Poses. - Bones draw unrotated now - Drawing bones speedup enormously (10-20 times) - Bone selecting in EditMode, selection state is saved for PoseMode, and vice-versa - Undo in editmode - Bone renaming does vertexgroups, constraints, posechannels, actions, for all users of Armature in entire file - Added Bone renaming in NKey panel - Nkey PoseMode shows eulers now - EditMode and PoseMode now have 'active' bone too (last clicked) - Parenting in EditMode' CTRL+P, ALT+P, with nice options! - Pose is added in Outliner now, with showing that constraints are in the Pose, not Armature - Disconnected IK solving from constraints. It's a separate phase now, on top of the full Pose calculations - Pose itself has a dependency graph too, so evaluation order is lag free. TODO NOW; - Rotating in Posemode has incorrect inverse transform (Martin will fix) - Python Bone/Armature/Pose API disabled... needs full recode too (wait for my doc!) - Game engine will need upgrade too - Depgraph code needs revision, cleanup, can be much faster! (But, compliments for Jean-Luc, it works like a charm!) - IK changed, it now doesnt use previous position to advance to next position anymore. That system looks nice (no flips) but is not well suited for NLA and background render. TODO LATER; We now can do loadsa new nifty features as well; like: - Kill PoseMode (can be option for armatures itself) - Make B-Bones (Bezier, Bspline, like for spines) - Move all silly button level edit to 3d window (like CTRL+I = add IK) - Much better & informative drawing - Fix action/nla editors - Put all ipos in Actions (object, mesh key, lamp color) - Add hooks - Null bones - Much more advanced constraints... Bugfixes; - OGL render (view3d header) had wrong first frame on anim render - Ipo 'recording' mode had wrong playback speed - Vertex-key mode now sticks to show 'active key', until frame change -Ton-
2005-07-03 17:35:38 +00:00
}
}
BKE_pose_channels_hash_make(pose);
for (pchan = pose->chanbase.first; pchan; pchan = pchan->next) {
/* Find the custom B-Bone handles. */
BKE_pchan_rebuild_bbone_handles(pose, pchan);
/* Re-validate that we are still using a valid pchan form custom transform. */
/* Note that we could store pointers of freed pchan in a GSet to speed this up, however this is
* supposed to be a rarely used feature, so for now assuming that always building that GSet
* would be less optimal. */
if (pchan->custom_tx != NULL && BLI_findindex(&pose->chanbase, pchan->custom_tx) == -1) {
pchan->custom_tx = NULL;
}
Result of 2 weeks of quiet coding work in Greece :) Aim was to get a total refresh of the animation system. This is needed because; - we need to upgrade it with 21st century features - current code is spaghetti/hack combo, and hides good design - it should become lag-free with using dependency graphs A full log, with complete code API/structure/design explanation will follow, that's a load of work... so here below the list with hot changes; - The entire object update system (matrices, geometry) is now centralized. Calls to where_is_object and makeDispList are forbidden, instead we tag objects 'changed' and let the depgraph code sort it out - Removed all old "Ika" code - Depgraph is aware of all relationships, including meta balls, constraints, bevelcurve, and so on. - Made depgraph aware of relation types and layers, to do smart flushing of 'changed' events. Nothing gets calculated too often! - Transform uses depgraph to detect changes - On frame-advance, depgraph flushes animated changes Armatures; Almost all armature related code has been fully built from scratch. It now reveils the original design much better, with a very clean implementation, lag free without even calculating each Bone more than once. Result is quite a speedup yes! Important to note is; 1) Armature is data containing the 'rest position' 2) Pose is the changes of rest position, and always on object level. That way more Objects can use same Pose. Also constraints are in Pose 3) Actions only contain the Ipos to change values in Poses. - Bones draw unrotated now - Drawing bones speedup enormously (10-20 times) - Bone selecting in EditMode, selection state is saved for PoseMode, and vice-versa - Undo in editmode - Bone renaming does vertexgroups, constraints, posechannels, actions, for all users of Armature in entire file - Added Bone renaming in NKey panel - Nkey PoseMode shows eulers now - EditMode and PoseMode now have 'active' bone too (last clicked) - Parenting in EditMode' CTRL+P, ALT+P, with nice options! - Pose is added in Outliner now, with showing that constraints are in the Pose, not Armature - Disconnected IK solving from constraints. It's a separate phase now, on top of the full Pose calculations - Pose itself has a dependency graph too, so evaluation order is lag free. TODO NOW; - Rotating in Posemode has incorrect inverse transform (Martin will fix) - Python Bone/Armature/Pose API disabled... needs full recode too (wait for my doc!) - Game engine will need upgrade too - Depgraph code needs revision, cleanup, can be much faster! (But, compliments for Jean-Luc, it works like a charm!) - IK changed, it now doesnt use previous position to advance to next position anymore. That system looks nice (no flips) but is not well suited for NLA and background render. TODO LATER; We now can do loadsa new nifty features as well; like: - Kill PoseMode (can be option for armatures itself) - Make B-Bones (Bezier, Bspline, like for spines) - Move all silly button level edit to 3d window (like CTRL+I = add IK) - Much better & informative drawing - Fix action/nla editors - Put all ipos in Actions (object, mesh key, lamp color) - Add hooks - Null bones - Much more advanced constraints... Bugfixes; - OGL render (view3d header) had wrong first frame on anim render - Ipo 'recording' mode had wrong playback speed - Vertex-key mode now sticks to show 'active key', until frame change -Ton-
2005-07-03 17:35:38 +00:00
}
/* printf("rebuild pose %s, %d bones\n", ob->id.name, counter); */
/* synchronize protected layers with proxy */
/* HACK! To preserve 2.7x behavior that you always can pose even locked bones,
* do not do any restoration if this is a COW temp copy! */
/* Switched back to just NO_MAIN tag, for some reasons (c)
* using COW tag was working this morning, but not anymore... */
if (ob->proxy != NULL && (ob->id.tag & LIB_TAG_NO_MAIN) == 0) {
BKE_object_copy_proxy_drivers(ob, ob->proxy);
pose_proxy_sync(ob, ob->proxy, arm->layer_protected);
}
BKE_pose_update_constraint_flags(pose); /* for IK detection for example */
pose->flag &= ~POSE_RECALC;
pose->flag |= POSE_WAS_REBUILT;
/* Rebuilding poses forces us to also rebuild the dependency graph,
* since there is one node per pose/bone. */
if (bmain != NULL) {
DEG_relations_tag_update(bmain);
}
Result of 2 weeks of quiet coding work in Greece :) Aim was to get a total refresh of the animation system. This is needed because; - we need to upgrade it with 21st century features - current code is spaghetti/hack combo, and hides good design - it should become lag-free with using dependency graphs A full log, with complete code API/structure/design explanation will follow, that's a load of work... so here below the list with hot changes; - The entire object update system (matrices, geometry) is now centralized. Calls to where_is_object and makeDispList are forbidden, instead we tag objects 'changed' and let the depgraph code sort it out - Removed all old "Ika" code - Depgraph is aware of all relationships, including meta balls, constraints, bevelcurve, and so on. - Made depgraph aware of relation types and layers, to do smart flushing of 'changed' events. Nothing gets calculated too often! - Transform uses depgraph to detect changes - On frame-advance, depgraph flushes animated changes Armatures; Almost all armature related code has been fully built from scratch. It now reveils the original design much better, with a very clean implementation, lag free without even calculating each Bone more than once. Result is quite a speedup yes! Important to note is; 1) Armature is data containing the 'rest position' 2) Pose is the changes of rest position, and always on object level. That way more Objects can use same Pose. Also constraints are in Pose 3) Actions only contain the Ipos to change values in Poses. - Bones draw unrotated now - Drawing bones speedup enormously (10-20 times) - Bone selecting in EditMode, selection state is saved for PoseMode, and vice-versa - Undo in editmode - Bone renaming does vertexgroups, constraints, posechannels, actions, for all users of Armature in entire file - Added Bone renaming in NKey panel - Nkey PoseMode shows eulers now - EditMode and PoseMode now have 'active' bone too (last clicked) - Parenting in EditMode' CTRL+P, ALT+P, with nice options! - Pose is added in Outliner now, with showing that constraints are in the Pose, not Armature - Disconnected IK solving from constraints. It's a separate phase now, on top of the full Pose calculations - Pose itself has a dependency graph too, so evaluation order is lag free. TODO NOW; - Rotating in Posemode has incorrect inverse transform (Martin will fix) - Python Bone/Armature/Pose API disabled... needs full recode too (wait for my doc!) - Game engine will need upgrade too - Depgraph code needs revision, cleanup, can be much faster! (But, compliments for Jean-Luc, it works like a charm!) - IK changed, it now doesnt use previous position to advance to next position anymore. That system looks nice (no flips) but is not well suited for NLA and background render. TODO LATER; We now can do loadsa new nifty features as well; like: - Kill PoseMode (can be option for armatures itself) - Make B-Bones (Bezier, Bspline, like for spines) - Move all silly button level edit to 3d window (like CTRL+I = add IK) - Much better & informative drawing - Fix action/nla editors - Put all ipos in Actions (object, mesh key, lamp color) - Add hooks - Null bones - Much more advanced constraints... Bugfixes; - OGL render (view3d header) had wrong first frame on anim render - Ipo 'recording' mode had wrong playback speed - Vertex-key mode now sticks to show 'active key', until frame change -Ton-
2005-07-03 17:35:38 +00:00
}
2002-10-12 11:37:38 +00:00
/**
* Ensures object's pose is rebuilt if needed.
*
* \param bmain: May be NULL, only used to tag depsgraph as being dirty...
*/
void BKE_pose_ensure(Main *bmain, Object *ob, bArmature *arm, const bool do_id_user)
{
BLI_assert(!ELEM(NULL, arm, ob));
if (ob->type == OB_ARMATURE && ((ob->pose == NULL) || (ob->pose->flag & POSE_RECALC))) {
BLI_assert(GS(arm->id.name) == ID_AR);
BKE_pose_rebuild(bmain, ob, arm, do_id_user);
}
}
/** \} */
/* -------------------------------------------------------------------- */
/** \name Pose Solver
* \{ */
2002-10-12 11:37:38 +00:00
/**
* Convert the loc/rot/size to \a r_chanmat (typically #bPoseChannel.chan_mat).
*/
void BKE_pchan_to_mat4(const bPoseChannel *pchan, float r_chanmat[4][4])
2002-10-12 11:37:38 +00:00
{
Result of 2 weeks of quiet coding work in Greece :) Aim was to get a total refresh of the animation system. This is needed because; - we need to upgrade it with 21st century features - current code is spaghetti/hack combo, and hides good design - it should become lag-free with using dependency graphs A full log, with complete code API/structure/design explanation will follow, that's a load of work... so here below the list with hot changes; - The entire object update system (matrices, geometry) is now centralized. Calls to where_is_object and makeDispList are forbidden, instead we tag objects 'changed' and let the depgraph code sort it out - Removed all old "Ika" code - Depgraph is aware of all relationships, including meta balls, constraints, bevelcurve, and so on. - Made depgraph aware of relation types and layers, to do smart flushing of 'changed' events. Nothing gets calculated too often! - Transform uses depgraph to detect changes - On frame-advance, depgraph flushes animated changes Armatures; Almost all armature related code has been fully built from scratch. It now reveils the original design much better, with a very clean implementation, lag free without even calculating each Bone more than once. Result is quite a speedup yes! Important to note is; 1) Armature is data containing the 'rest position' 2) Pose is the changes of rest position, and always on object level. That way more Objects can use same Pose. Also constraints are in Pose 3) Actions only contain the Ipos to change values in Poses. - Bones draw unrotated now - Drawing bones speedup enormously (10-20 times) - Bone selecting in EditMode, selection state is saved for PoseMode, and vice-versa - Undo in editmode - Bone renaming does vertexgroups, constraints, posechannels, actions, for all users of Armature in entire file - Added Bone renaming in NKey panel - Nkey PoseMode shows eulers now - EditMode and PoseMode now have 'active' bone too (last clicked) - Parenting in EditMode' CTRL+P, ALT+P, with nice options! - Pose is added in Outliner now, with showing that constraints are in the Pose, not Armature - Disconnected IK solving from constraints. It's a separate phase now, on top of the full Pose calculations - Pose itself has a dependency graph too, so evaluation order is lag free. TODO NOW; - Rotating in Posemode has incorrect inverse transform (Martin will fix) - Python Bone/Armature/Pose API disabled... needs full recode too (wait for my doc!) - Game engine will need upgrade too - Depgraph code needs revision, cleanup, can be much faster! (But, compliments for Jean-Luc, it works like a charm!) - IK changed, it now doesnt use previous position to advance to next position anymore. That system looks nice (no flips) but is not well suited for NLA and background render. TODO LATER; We now can do loadsa new nifty features as well; like: - Kill PoseMode (can be option for armatures itself) - Make B-Bones (Bezier, Bspline, like for spines) - Move all silly button level edit to 3d window (like CTRL+I = add IK) - Much better & informative drawing - Fix action/nla editors - Put all ipos in Actions (object, mesh key, lamp color) - Add hooks - Null bones - Much more advanced constraints... Bugfixes; - OGL render (view3d header) had wrong first frame on anim render - Ipo 'recording' mode had wrong playback speed - Vertex-key mode now sticks to show 'active key', until frame change -Ton-
2005-07-03 17:35:38 +00:00
float smat[3][3];
float rmat[3][3];
float tmat[3][3];
/* get scaling matrix */
size_to_mat3(smat, pchan->size);
/* get rotation matrix */
BKE_pchan_rot_to_mat3(pchan, rmat);
/* calculate matrix of bone (as 3x3 matrix, but then copy the 4x4) */
mul_m3_m3m3(tmat, rmat, smat);
copy_m4_m3(r_chanmat, tmat);
Result of 2 weeks of quiet coding work in Greece :) Aim was to get a total refresh of the animation system. This is needed because; - we need to upgrade it with 21st century features - current code is spaghetti/hack combo, and hides good design - it should become lag-free with using dependency graphs A full log, with complete code API/structure/design explanation will follow, that's a load of work... so here below the list with hot changes; - The entire object update system (matrices, geometry) is now centralized. Calls to where_is_object and makeDispList are forbidden, instead we tag objects 'changed' and let the depgraph code sort it out - Removed all old "Ika" code - Depgraph is aware of all relationships, including meta balls, constraints, bevelcurve, and so on. - Made depgraph aware of relation types and layers, to do smart flushing of 'changed' events. Nothing gets calculated too often! - Transform uses depgraph to detect changes - On frame-advance, depgraph flushes animated changes Armatures; Almost all armature related code has been fully built from scratch. It now reveils the original design much better, with a very clean implementation, lag free without even calculating each Bone more than once. Result is quite a speedup yes! Important to note is; 1) Armature is data containing the 'rest position' 2) Pose is the changes of rest position, and always on object level. That way more Objects can use same Pose. Also constraints are in Pose 3) Actions only contain the Ipos to change values in Poses. - Bones draw unrotated now - Drawing bones speedup enormously (10-20 times) - Bone selecting in EditMode, selection state is saved for PoseMode, and vice-versa - Undo in editmode - Bone renaming does vertexgroups, constraints, posechannels, actions, for all users of Armature in entire file - Added Bone renaming in NKey panel - Nkey PoseMode shows eulers now - EditMode and PoseMode now have 'active' bone too (last clicked) - Parenting in EditMode' CTRL+P, ALT+P, with nice options! - Pose is added in Outliner now, with showing that constraints are in the Pose, not Armature - Disconnected IK solving from constraints. It's a separate phase now, on top of the full Pose calculations - Pose itself has a dependency graph too, so evaluation order is lag free. TODO NOW; - Rotating in Posemode has incorrect inverse transform (Martin will fix) - Python Bone/Armature/Pose API disabled... needs full recode too (wait for my doc!) - Game engine will need upgrade too - Depgraph code needs revision, cleanup, can be much faster! (But, compliments for Jean-Luc, it works like a charm!) - IK changed, it now doesnt use previous position to advance to next position anymore. That system looks nice (no flips) but is not well suited for NLA and background render. TODO LATER; We now can do loadsa new nifty features as well; like: - Kill PoseMode (can be option for armatures itself) - Make B-Bones (Bezier, Bspline, like for spines) - Move all silly button level edit to 3d window (like CTRL+I = add IK) - Much better & informative drawing - Fix action/nla editors - Put all ipos in Actions (object, mesh key, lamp color) - Add hooks - Null bones - Much more advanced constraints... Bugfixes; - OGL render (view3d header) had wrong first frame on anim render - Ipo 'recording' mode had wrong playback speed - Vertex-key mode now sticks to show 'active key', until frame change -Ton-
2005-07-03 17:35:38 +00:00
/* prevent action channels breaking chains */
/* need to check for bone here, CONSTRAINT_TYPE_ACTION uses this call */
if ((pchan->bone == NULL) || !(pchan->bone->flag & BONE_CONNECTED)) {
copy_v3_v3(r_chanmat[3], pchan->loc);
2002-10-12 11:37:38 +00:00
}
}
/* loc/rot/size to mat4 */
/* used in constraint.c too */
void BKE_pchan_calc_mat(bPoseChannel *pchan)
{
/* this is just a wrapper around the copy of this function which calculates the matrix
* and stores the result in any given channel
*/
BKE_pchan_to_mat4(pchan, pchan->chan_mat);
}
/* calculate tail of posechannel */
void BKE_pose_where_is_bone_tail(bPoseChannel *pchan)
{
float vec[3];
copy_v3_v3(vec, pchan->pose_mat[1]);
mul_v3_fl(vec, pchan->bone->length);
add_v3_v3v3(pchan->pose_tail, pchan->pose_head, vec);
}
Result of 2 weeks of quiet coding work in Greece :) Aim was to get a total refresh of the animation system. This is needed because; - we need to upgrade it with 21st century features - current code is spaghetti/hack combo, and hides good design - it should become lag-free with using dependency graphs A full log, with complete code API/structure/design explanation will follow, that's a load of work... so here below the list with hot changes; - The entire object update system (matrices, geometry) is now centralized. Calls to where_is_object and makeDispList are forbidden, instead we tag objects 'changed' and let the depgraph code sort it out - Removed all old "Ika" code - Depgraph is aware of all relationships, including meta balls, constraints, bevelcurve, and so on. - Made depgraph aware of relation types and layers, to do smart flushing of 'changed' events. Nothing gets calculated too often! - Transform uses depgraph to detect changes - On frame-advance, depgraph flushes animated changes Armatures; Almost all armature related code has been fully built from scratch. It now reveils the original design much better, with a very clean implementation, lag free without even calculating each Bone more than once. Result is quite a speedup yes! Important to note is; 1) Armature is data containing the 'rest position' 2) Pose is the changes of rest position, and always on object level. That way more Objects can use same Pose. Also constraints are in Pose 3) Actions only contain the Ipos to change values in Poses. - Bones draw unrotated now - Drawing bones speedup enormously (10-20 times) - Bone selecting in EditMode, selection state is saved for PoseMode, and vice-versa - Undo in editmode - Bone renaming does vertexgroups, constraints, posechannels, actions, for all users of Armature in entire file - Added Bone renaming in NKey panel - Nkey PoseMode shows eulers now - EditMode and PoseMode now have 'active' bone too (last clicked) - Parenting in EditMode' CTRL+P, ALT+P, with nice options! - Pose is added in Outliner now, with showing that constraints are in the Pose, not Armature - Disconnected IK solving from constraints. It's a separate phase now, on top of the full Pose calculations - Pose itself has a dependency graph too, so evaluation order is lag free. TODO NOW; - Rotating in Posemode has incorrect inverse transform (Martin will fix) - Python Bone/Armature/Pose API disabled... needs full recode too (wait for my doc!) - Game engine will need upgrade too - Depgraph code needs revision, cleanup, can be much faster! (But, compliments for Jean-Luc, it works like a charm!) - IK changed, it now doesnt use previous position to advance to next position anymore. That system looks nice (no flips) but is not well suited for NLA and background render. TODO LATER; We now can do loadsa new nifty features as well; like: - Kill PoseMode (can be option for armatures itself) - Make B-Bones (Bezier, Bspline, like for spines) - Move all silly button level edit to 3d window (like CTRL+I = add IK) - Much better & informative drawing - Fix action/nla editors - Put all ipos in Actions (object, mesh key, lamp color) - Add hooks - Null bones - Much more advanced constraints... Bugfixes; - OGL render (view3d header) had wrong first frame on anim render - Ipo 'recording' mode had wrong playback speed - Vertex-key mode now sticks to show 'active key', until frame change -Ton-
2005-07-03 17:35:38 +00:00
/* The main armature solver, does all constraints excluding IK */
/* pchan is validated, as having bone and parent pointer
* 'do_extra': when zero skips loc/size/rot, constraints and strip modifiers.
*/
void BKE_pose_where_is_bone(struct Depsgraph *depsgraph,
Scene *scene,
Object *ob,
bPoseChannel *pchan,
float ctime,
bool do_extra)
2002-10-12 11:37:38 +00:00
{
/* This gives a chan_mat with actions (ipos) results. */
if (do_extra) {
BKE_pchan_calc_mat(pchan);
}
else {
unit_m4(pchan->chan_mat);
}
/* Construct the posemat based on PoseChannels, that we do before applying constraints. */
/* pose_mat(b) = pose_mat(b-1) * yoffs(b-1) * d_root(b) * bone_mat(b) * chan_mat(b) */
BKE_armature_mat_bone_to_pose(pchan, pchan->chan_mat, pchan->pose_mat);
/* Only rootbones get the cyclic offset (unless user doesn't want that). */
/* XXX That could be a problem for snapping and other "reverse transform" features... */
if (!pchan->parent) {
if ((pchan->bone->flag & BONE_NO_CYCLICOFFSET) == 0) {
add_v3_v3(pchan->pose_mat[3], ob->pose->cyclic_offset);
}
Two wonderful new NLA & Armature editing features! - FORWARD CYCLING & MATCHING Up to no now, adding multiple actions in NLA with walkcycles required to animate them standing still, as if walking on a conveyor belt. The stride option then makes the object itself move forward, trying to keep the foot stuck on the floor (with poor results!). This option now allows to make walk cycles moving forward. By indicating a reference Offset Bone, the NLA system will use that bone to detect the correct offset for the Armature Pose to make it seamlessly going forward. Best of all, this option works as for cyclic Action Strips as well as for individual Action Strips. Note that for individual strips, you have to set the strip on "Hold". (Might become automatic detected later). Here's an example edit image for NLA: http://www.blender.org/bf/nla_match-cycle.jpg And the animation for it: http://download.blender.org/demo/test/2.43/0001_0150_match.avi Blender file: http://download.blender.org/demo/test/2.43/mancandy_matching.blend Using this kind of cycling works pretty straightforward, and is a lot easier to setup than Stride Bones. To be further tested: - Blending cycles - matching rotation for the bones as well. - ACTION MODIFIERS (motion deformors) The above option was actually required for this feature. Typically walk cycles are constructed with certain Bones to be the handles, controlling for example the torso or feet. An Action Modifier allows you to use a Curve Path to deform the motion of these controlling bones. This uses the existing Curve Deformation option. Modifiers can be added per Action Strip, each controlling a channel (bone) by choice, and even allows to layer multiple modifiers on top of each other (several paths deforming motion). This option is using the dependency graph, so editing the Curve will give realtime changes in the Armature. The previous walkcycle, controlled by two curves: http://download.blender.org/demo/test/2.43/0001_0150_deform.avi Blender file: http://download.blender.org/demo/test/2.43/mancandy_actiondeform.blend Action Modifiers can be added in the NLA Properties Panel. Per Modifier you have to indicate the channel and a Curve Object. You can copy modifiers from one strip to another using CTRL+C (only copies to active Object strips). Setting up a correct Curve Path has to be carefully done: - Use SHIFT+A "Curve Path" in top view, or ensure the path is not rotated. - make sure the center point of the Curve Object is at the center of the Armature (or above) - move the first point of the curve to the center point as well. - check if the path starts from this first point, you can change it using (in Curve EditMode) the option Wkey -> "Switch Direction" - Make sure alignment uses the correct axis; if the Armature walks into the negative Y direction, you have to set in Object Buttons, "Anim settings" Panel, the correct Track option. (Note; option will probably move to the Modifier later). This is a good reason to make such paths automatic (on a command). Is on the todo list. Also note this: - the Curve Path extends in beginning and ending, that's (for now) the default, and allows to use multiple paths. Make sure paths begin and end horizontal. - Moving the Curve in Object Mode will change the "mapping" (as if the landscape a character walks over moves). Moving the Curve in Edit Mode will change the actual position of the deformation. - Speed (Ipos) on paths is not supported yet, will be done. - The Curve "Stretch" deform option doesn't work. - Modifiers are executed *after* all actions in NLA are evaluated, there's no support yet for blending multiple strips with Modifiers. - This doesn't work yet for time-mapping... This commit is mostly for review by character animators... some details or working methods might change. This feature can also be used for other modifiers, such as noise (Perlin) or the mythical "Oomph" (frequency control) and of course Python. Special thanks to Bassam & Matt for research & design help. Have fun!
2006-10-31 15:51:57 +00:00
}
if (do_extra) {
/* Do constraints */
if (pchan->constraints.first) {
bConstraintOb *cob;
float vec[3];
/* make a copy of location of PoseChannel for later */
copy_v3_v3(vec, pchan->pose_mat[3]);
/* prepare PoseChannel for Constraint solving
* - makes a copy of matrix, and creates temporary struct to use
*/
cob = BKE_constraints_make_evalob(depsgraph, scene, ob, pchan, CONSTRAINT_OBTYPE_BONE);
/* Solve PoseChannel's Constraints */
/* ctime doesn't alter objects. */
BKE_constraints_solve(depsgraph, &pchan->constraints, cob, ctime);
/* cleanup after Constraint Solving
* - applies matrix back to pchan, and frees temporary struct used
*/
BKE_constraints_clear_evalob(cob);
/* prevent constraints breaking a chain */
if (pchan->bone->flag & BONE_CONNECTED) {
copy_v3_v3(pchan->pose_mat[3], vec);
== Constraints System == After just over a week of coding, I've finished doing a major refactor/cleanup of the constraints code. In the process, quite a few old kludges and ugly hacks have been removed. Also, some new features which will greatly benefit riggers have been implemented. === What's New === * The long-awaited ``ChildOf Constraint'': This allows you to animate parent influences, and choose which transformation channels the parent affects the child on (i.e. no translation/rotation/scaling). It should be noted that disabling some combinations may not totally work as expected. Also, the 'Set Inverse' and 'Clear Inverse' buttons at the bottom of this constraint's panel set/clear the inverse correction for the parent's effects. Use these to make the owner not stick/be glued to the parent. * Constraint/Target Evaluation Spaces: In some constraints, there are now 1-2 combo boxes at the bottom of their panel, which allows you to pick which `co-ordinate space' they are evaluated in. This is much more flexible than the old 'local' options for bones only were. * Action Constraint - Loc/Rot/Size Inputs The Action Constraint can finally use the target's location/rotation/scaling transforms as input, to control the owner of the constraint. This should work much more reliably than it used to. The target evaluation should now also be more accurate due to the new space conversion stuff. * Transform - No longer in Crazy Space (TM) Transforming objects/bones with constraints applied should no longer occur in Crazy Space. They are now correctly inverse-corrected. This also applies to old-style object tracking. === General Code Changes === * solve_constraints is now in constraints.c. I've removed the old `blend consecutive constraints of same type' junk, which made the code more complex than it needed to be. * evaluate_constraint is now only passed the constraint, and two matrices. A few unused variables have been removed from here. * A tempolary struct, bConstraintOb, is now passed to solve_constraints instead of relying on an ugly, static workobject in some cases. This works much better. * Made the formatting of constraint code consistent * There's a version patch for older files so that constraint settings are correctly converted to the new system. This is currently done for MajorVersion <= 244, and SubVersion < 3. I've bumped up the subversion to 3 for this purpose. However, with the imminent 2.45 release, this may need to be adjusted accordingly. * LocEulSizeToMat4 and LocQuatSizeToMat4 now work in the order Size, Rot, Location. I've also added a few other math functions. * Mat4BlendMat4 is now in arithb. I've modified it's method slightly, to use other arithb functions, instead of its crazy blending scheme. * Moved some of the RigidBodyJoint constraint's code out of blenkernel, and into src. It shouldn't be setting its target in its data initialisation function based + accessing scene stuff where it was doing so. === Future Work === * Geometry to act as targets for constraints. A space has been reserved for this already. * Tidy up UI buttons of constraints
2007-07-15 03:35:37 +00:00
}
}
2002-10-12 11:37:38 +00:00
}
Result of 2 weeks of quiet coding work in Greece :) Aim was to get a total refresh of the animation system. This is needed because; - we need to upgrade it with 21st century features - current code is spaghetti/hack combo, and hides good design - it should become lag-free with using dependency graphs A full log, with complete code API/structure/design explanation will follow, that's a load of work... so here below the list with hot changes; - The entire object update system (matrices, geometry) is now centralized. Calls to where_is_object and makeDispList are forbidden, instead we tag objects 'changed' and let the depgraph code sort it out - Removed all old "Ika" code - Depgraph is aware of all relationships, including meta balls, constraints, bevelcurve, and so on. - Made depgraph aware of relation types and layers, to do smart flushing of 'changed' events. Nothing gets calculated too often! - Transform uses depgraph to detect changes - On frame-advance, depgraph flushes animated changes Armatures; Almost all armature related code has been fully built from scratch. It now reveils the original design much better, with a very clean implementation, lag free without even calculating each Bone more than once. Result is quite a speedup yes! Important to note is; 1) Armature is data containing the 'rest position' 2) Pose is the changes of rest position, and always on object level. That way more Objects can use same Pose. Also constraints are in Pose 3) Actions only contain the Ipos to change values in Poses. - Bones draw unrotated now - Drawing bones speedup enormously (10-20 times) - Bone selecting in EditMode, selection state is saved for PoseMode, and vice-versa - Undo in editmode - Bone renaming does vertexgroups, constraints, posechannels, actions, for all users of Armature in entire file - Added Bone renaming in NKey panel - Nkey PoseMode shows eulers now - EditMode and PoseMode now have 'active' bone too (last clicked) - Parenting in EditMode' CTRL+P, ALT+P, with nice options! - Pose is added in Outliner now, with showing that constraints are in the Pose, not Armature - Disconnected IK solving from constraints. It's a separate phase now, on top of the full Pose calculations - Pose itself has a dependency graph too, so evaluation order is lag free. TODO NOW; - Rotating in Posemode has incorrect inverse transform (Martin will fix) - Python Bone/Armature/Pose API disabled... needs full recode too (wait for my doc!) - Game engine will need upgrade too - Depgraph code needs revision, cleanup, can be much faster! (But, compliments for Jean-Luc, it works like a charm!) - IK changed, it now doesnt use previous position to advance to next position anymore. That system looks nice (no flips) but is not well suited for NLA and background render. TODO LATER; We now can do loadsa new nifty features as well; like: - Kill PoseMode (can be option for armatures itself) - Make B-Bones (Bezier, Bspline, like for spines) - Move all silly button level edit to 3d window (like CTRL+I = add IK) - Much better & informative drawing - Fix action/nla editors - Put all ipos in Actions (object, mesh key, lamp color) - Add hooks - Null bones - Much more advanced constraints... Bugfixes; - OGL render (view3d header) had wrong first frame on anim render - Ipo 'recording' mode had wrong playback speed - Vertex-key mode now sticks to show 'active key', until frame change -Ton-
2005-07-03 17:35:38 +00:00
/* calculate head */
copy_v3_v3(pchan->pose_head, pchan->pose_mat[3]);
Result of 2 weeks of quiet coding work in Greece :) Aim was to get a total refresh of the animation system. This is needed because; - we need to upgrade it with 21st century features - current code is spaghetti/hack combo, and hides good design - it should become lag-free with using dependency graphs A full log, with complete code API/structure/design explanation will follow, that's a load of work... so here below the list with hot changes; - The entire object update system (matrices, geometry) is now centralized. Calls to where_is_object and makeDispList are forbidden, instead we tag objects 'changed' and let the depgraph code sort it out - Removed all old "Ika" code - Depgraph is aware of all relationships, including meta balls, constraints, bevelcurve, and so on. - Made depgraph aware of relation types and layers, to do smart flushing of 'changed' events. Nothing gets calculated too often! - Transform uses depgraph to detect changes - On frame-advance, depgraph flushes animated changes Armatures; Almost all armature related code has been fully built from scratch. It now reveils the original design much better, with a very clean implementation, lag free without even calculating each Bone more than once. Result is quite a speedup yes! Important to note is; 1) Armature is data containing the 'rest position' 2) Pose is the changes of rest position, and always on object level. That way more Objects can use same Pose. Also constraints are in Pose 3) Actions only contain the Ipos to change values in Poses. - Bones draw unrotated now - Drawing bones speedup enormously (10-20 times) - Bone selecting in EditMode, selection state is saved for PoseMode, and vice-versa - Undo in editmode - Bone renaming does vertexgroups, constraints, posechannels, actions, for all users of Armature in entire file - Added Bone renaming in NKey panel - Nkey PoseMode shows eulers now - EditMode and PoseMode now have 'active' bone too (last clicked) - Parenting in EditMode' CTRL+P, ALT+P, with nice options! - Pose is added in Outliner now, with showing that constraints are in the Pose, not Armature - Disconnected IK solving from constraints. It's a separate phase now, on top of the full Pose calculations - Pose itself has a dependency graph too, so evaluation order is lag free. TODO NOW; - Rotating in Posemode has incorrect inverse transform (Martin will fix) - Python Bone/Armature/Pose API disabled... needs full recode too (wait for my doc!) - Game engine will need upgrade too - Depgraph code needs revision, cleanup, can be much faster! (But, compliments for Jean-Luc, it works like a charm!) - IK changed, it now doesnt use previous position to advance to next position anymore. That system looks nice (no flips) but is not well suited for NLA and background render. TODO LATER; We now can do loadsa new nifty features as well; like: - Kill PoseMode (can be option for armatures itself) - Make B-Bones (Bezier, Bspline, like for spines) - Move all silly button level edit to 3d window (like CTRL+I = add IK) - Much better & informative drawing - Fix action/nla editors - Put all ipos in Actions (object, mesh key, lamp color) - Add hooks - Null bones - Much more advanced constraints... Bugfixes; - OGL render (view3d header) had wrong first frame on anim render - Ipo 'recording' mode had wrong playback speed - Vertex-key mode now sticks to show 'active key', until frame change -Ton-
2005-07-03 17:35:38 +00:00
/* calculate tail */
BKE_pose_where_is_bone_tail(pchan);
Result of 2 weeks of quiet coding work in Greece :) Aim was to get a total refresh of the animation system. This is needed because; - we need to upgrade it with 21st century features - current code is spaghetti/hack combo, and hides good design - it should become lag-free with using dependency graphs A full log, with complete code API/structure/design explanation will follow, that's a load of work... so here below the list with hot changes; - The entire object update system (matrices, geometry) is now centralized. Calls to where_is_object and makeDispList are forbidden, instead we tag objects 'changed' and let the depgraph code sort it out - Removed all old "Ika" code - Depgraph is aware of all relationships, including meta balls, constraints, bevelcurve, and so on. - Made depgraph aware of relation types and layers, to do smart flushing of 'changed' events. Nothing gets calculated too often! - Transform uses depgraph to detect changes - On frame-advance, depgraph flushes animated changes Armatures; Almost all armature related code has been fully built from scratch. It now reveils the original design much better, with a very clean implementation, lag free without even calculating each Bone more than once. Result is quite a speedup yes! Important to note is; 1) Armature is data containing the 'rest position' 2) Pose is the changes of rest position, and always on object level. That way more Objects can use same Pose. Also constraints are in Pose 3) Actions only contain the Ipos to change values in Poses. - Bones draw unrotated now - Drawing bones speedup enormously (10-20 times) - Bone selecting in EditMode, selection state is saved for PoseMode, and vice-versa - Undo in editmode - Bone renaming does vertexgroups, constraints, posechannels, actions, for all users of Armature in entire file - Added Bone renaming in NKey panel - Nkey PoseMode shows eulers now - EditMode and PoseMode now have 'active' bone too (last clicked) - Parenting in EditMode' CTRL+P, ALT+P, with nice options! - Pose is added in Outliner now, with showing that constraints are in the Pose, not Armature - Disconnected IK solving from constraints. It's a separate phase now, on top of the full Pose calculations - Pose itself has a dependency graph too, so evaluation order is lag free. TODO NOW; - Rotating in Posemode has incorrect inverse transform (Martin will fix) - Python Bone/Armature/Pose API disabled... needs full recode too (wait for my doc!) - Game engine will need upgrade too - Depgraph code needs revision, cleanup, can be much faster! (But, compliments for Jean-Luc, it works like a charm!) - IK changed, it now doesnt use previous position to advance to next position anymore. That system looks nice (no flips) but is not well suited for NLA and background render. TODO LATER; We now can do loadsa new nifty features as well; like: - Kill PoseMode (can be option for armatures itself) - Make B-Bones (Bezier, Bspline, like for spines) - Move all silly button level edit to 3d window (like CTRL+I = add IK) - Much better & informative drawing - Fix action/nla editors - Put all ipos in Actions (object, mesh key, lamp color) - Add hooks - Null bones - Much more advanced constraints... Bugfixes; - OGL render (view3d header) had wrong first frame on anim render - Ipo 'recording' mode had wrong playback speed - Vertex-key mode now sticks to show 'active key', until frame change -Ton-
2005-07-03 17:35:38 +00:00
}
2002-10-12 11:37:38 +00:00
Result of 2 weeks of quiet coding work in Greece :) Aim was to get a total refresh of the animation system. This is needed because; - we need to upgrade it with 21st century features - current code is spaghetti/hack combo, and hides good design - it should become lag-free with using dependency graphs A full log, with complete code API/structure/design explanation will follow, that's a load of work... so here below the list with hot changes; - The entire object update system (matrices, geometry) is now centralized. Calls to where_is_object and makeDispList are forbidden, instead we tag objects 'changed' and let the depgraph code sort it out - Removed all old "Ika" code - Depgraph is aware of all relationships, including meta balls, constraints, bevelcurve, and so on. - Made depgraph aware of relation types and layers, to do smart flushing of 'changed' events. Nothing gets calculated too often! - Transform uses depgraph to detect changes - On frame-advance, depgraph flushes animated changes Armatures; Almost all armature related code has been fully built from scratch. It now reveils the original design much better, with a very clean implementation, lag free without even calculating each Bone more than once. Result is quite a speedup yes! Important to note is; 1) Armature is data containing the 'rest position' 2) Pose is the changes of rest position, and always on object level. That way more Objects can use same Pose. Also constraints are in Pose 3) Actions only contain the Ipos to change values in Poses. - Bones draw unrotated now - Drawing bones speedup enormously (10-20 times) - Bone selecting in EditMode, selection state is saved for PoseMode, and vice-versa - Undo in editmode - Bone renaming does vertexgroups, constraints, posechannels, actions, for all users of Armature in entire file - Added Bone renaming in NKey panel - Nkey PoseMode shows eulers now - EditMode and PoseMode now have 'active' bone too (last clicked) - Parenting in EditMode' CTRL+P, ALT+P, with nice options! - Pose is added in Outliner now, with showing that constraints are in the Pose, not Armature - Disconnected IK solving from constraints. It's a separate phase now, on top of the full Pose calculations - Pose itself has a dependency graph too, so evaluation order is lag free. TODO NOW; - Rotating in Posemode has incorrect inverse transform (Martin will fix) - Python Bone/Armature/Pose API disabled... needs full recode too (wait for my doc!) - Game engine will need upgrade too - Depgraph code needs revision, cleanup, can be much faster! (But, compliments for Jean-Luc, it works like a charm!) - IK changed, it now doesnt use previous position to advance to next position anymore. That system looks nice (no flips) but is not well suited for NLA and background render. TODO LATER; We now can do loadsa new nifty features as well; like: - Kill PoseMode (can be option for armatures itself) - Make B-Bones (Bezier, Bspline, like for spines) - Move all silly button level edit to 3d window (like CTRL+I = add IK) - Much better & informative drawing - Fix action/nla editors - Put all ipos in Actions (object, mesh key, lamp color) - Add hooks - Null bones - Much more advanced constraints... Bugfixes; - OGL render (view3d header) had wrong first frame on anim render - Ipo 'recording' mode had wrong playback speed - Vertex-key mode now sticks to show 'active key', until frame change -Ton-
2005-07-03 17:35:38 +00:00
/* This only reads anim data from channels, and writes to channels */
/* This is the only function adding poses */
void BKE_pose_where_is(struct Depsgraph *depsgraph, Scene *scene, Object *ob)
2002-10-12 11:37:38 +00:00
{
Result of 2 weeks of quiet coding work in Greece :) Aim was to get a total refresh of the animation system. This is needed because; - we need to upgrade it with 21st century features - current code is spaghetti/hack combo, and hides good design - it should become lag-free with using dependency graphs A full log, with complete code API/structure/design explanation will follow, that's a load of work... so here below the list with hot changes; - The entire object update system (matrices, geometry) is now centralized. Calls to where_is_object and makeDispList are forbidden, instead we tag objects 'changed' and let the depgraph code sort it out - Removed all old "Ika" code - Depgraph is aware of all relationships, including meta balls, constraints, bevelcurve, and so on. - Made depgraph aware of relation types and layers, to do smart flushing of 'changed' events. Nothing gets calculated too often! - Transform uses depgraph to detect changes - On frame-advance, depgraph flushes animated changes Armatures; Almost all armature related code has been fully built from scratch. It now reveils the original design much better, with a very clean implementation, lag free without even calculating each Bone more than once. Result is quite a speedup yes! Important to note is; 1) Armature is data containing the 'rest position' 2) Pose is the changes of rest position, and always on object level. That way more Objects can use same Pose. Also constraints are in Pose 3) Actions only contain the Ipos to change values in Poses. - Bones draw unrotated now - Drawing bones speedup enormously (10-20 times) - Bone selecting in EditMode, selection state is saved for PoseMode, and vice-versa - Undo in editmode - Bone renaming does vertexgroups, constraints, posechannels, actions, for all users of Armature in entire file - Added Bone renaming in NKey panel - Nkey PoseMode shows eulers now - EditMode and PoseMode now have 'active' bone too (last clicked) - Parenting in EditMode' CTRL+P, ALT+P, with nice options! - Pose is added in Outliner now, with showing that constraints are in the Pose, not Armature - Disconnected IK solving from constraints. It's a separate phase now, on top of the full Pose calculations - Pose itself has a dependency graph too, so evaluation order is lag free. TODO NOW; - Rotating in Posemode has incorrect inverse transform (Martin will fix) - Python Bone/Armature/Pose API disabled... needs full recode too (wait for my doc!) - Game engine will need upgrade too - Depgraph code needs revision, cleanup, can be much faster! (But, compliments for Jean-Luc, it works like a charm!) - IK changed, it now doesnt use previous position to advance to next position anymore. That system looks nice (no flips) but is not well suited for NLA and background render. TODO LATER; We now can do loadsa new nifty features as well; like: - Kill PoseMode (can be option for armatures itself) - Make B-Bones (Bezier, Bspline, like for spines) - Move all silly button level edit to 3d window (like CTRL+I = add IK) - Much better & informative drawing - Fix action/nla editors - Put all ipos in Actions (object, mesh key, lamp color) - Add hooks - Null bones - Much more advanced constraints... Bugfixes; - OGL render (view3d header) had wrong first frame on anim render - Ipo 'recording' mode had wrong playback speed - Vertex-key mode now sticks to show 'active key', until frame change -Ton-
2005-07-03 17:35:38 +00:00
bArmature *arm;
Bone *bone;
bPoseChannel *pchan;
Result of 2 weeks of quiet coding work in Greece :) Aim was to get a total refresh of the animation system. This is needed because; - we need to upgrade it with 21st century features - current code is spaghetti/hack combo, and hides good design - it should become lag-free with using dependency graphs A full log, with complete code API/structure/design explanation will follow, that's a load of work... so here below the list with hot changes; - The entire object update system (matrices, geometry) is now centralized. Calls to where_is_object and makeDispList are forbidden, instead we tag objects 'changed' and let the depgraph code sort it out - Removed all old "Ika" code - Depgraph is aware of all relationships, including meta balls, constraints, bevelcurve, and so on. - Made depgraph aware of relation types and layers, to do smart flushing of 'changed' events. Nothing gets calculated too often! - Transform uses depgraph to detect changes - On frame-advance, depgraph flushes animated changes Armatures; Almost all armature related code has been fully built from scratch. It now reveils the original design much better, with a very clean implementation, lag free without even calculating each Bone more than once. Result is quite a speedup yes! Important to note is; 1) Armature is data containing the 'rest position' 2) Pose is the changes of rest position, and always on object level. That way more Objects can use same Pose. Also constraints are in Pose 3) Actions only contain the Ipos to change values in Poses. - Bones draw unrotated now - Drawing bones speedup enormously (10-20 times) - Bone selecting in EditMode, selection state is saved for PoseMode, and vice-versa - Undo in editmode - Bone renaming does vertexgroups, constraints, posechannels, actions, for all users of Armature in entire file - Added Bone renaming in NKey panel - Nkey PoseMode shows eulers now - EditMode and PoseMode now have 'active' bone too (last clicked) - Parenting in EditMode' CTRL+P, ALT+P, with nice options! - Pose is added in Outliner now, with showing that constraints are in the Pose, not Armature - Disconnected IK solving from constraints. It's a separate phase now, on top of the full Pose calculations - Pose itself has a dependency graph too, so evaluation order is lag free. TODO NOW; - Rotating in Posemode has incorrect inverse transform (Martin will fix) - Python Bone/Armature/Pose API disabled... needs full recode too (wait for my doc!) - Game engine will need upgrade too - Depgraph code needs revision, cleanup, can be much faster! (But, compliments for Jean-Luc, it works like a charm!) - IK changed, it now doesnt use previous position to advance to next position anymore. That system looks nice (no flips) but is not well suited for NLA and background render. TODO LATER; We now can do loadsa new nifty features as well; like: - Kill PoseMode (can be option for armatures itself) - Make B-Bones (Bezier, Bspline, like for spines) - Move all silly button level edit to 3d window (like CTRL+I = add IK) - Much better & informative drawing - Fix action/nla editors - Put all ipos in Actions (object, mesh key, lamp color) - Add hooks - Null bones - Much more advanced constraints... Bugfixes; - OGL render (view3d header) had wrong first frame on anim render - Ipo 'recording' mode had wrong playback speed - Vertex-key mode now sticks to show 'active key', until frame change -Ton-
2005-07-03 17:35:38 +00:00
float imat[4][4];
float ctime;
if (ob->type != OB_ARMATURE) {
return;
}
arm = ob->data;
if (ELEM(NULL, arm, scene)) {
return;
}
/* WARNING! passing NULL bmain here means we won't tag depsgraph's as dirty -
* hopefully this is OK. */
BKE_pose_ensure(NULL, ob, arm, true);
ctime = BKE_scene_frame_get(scene); /* not accurate... */
2020-03-06 11:40:37 +11:00
/* In edit-mode or rest-position we read the data from the bones. */
if (arm->edbo || (arm->flag & ARM_RESTPOS)) {
for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
bone = pchan->bone;
if (bone) {
copy_m4_m4(pchan->pose_mat, bone->arm_mat);
copy_v3_v3(pchan->pose_head, bone->arm_head);
copy_v3_v3(pchan->pose_tail, bone->arm_tail);
Result of 2 weeks of quiet coding work in Greece :) Aim was to get a total refresh of the animation system. This is needed because; - we need to upgrade it with 21st century features - current code is spaghetti/hack combo, and hides good design - it should become lag-free with using dependency graphs A full log, with complete code API/structure/design explanation will follow, that's a load of work... so here below the list with hot changes; - The entire object update system (matrices, geometry) is now centralized. Calls to where_is_object and makeDispList are forbidden, instead we tag objects 'changed' and let the depgraph code sort it out - Removed all old "Ika" code - Depgraph is aware of all relationships, including meta balls, constraints, bevelcurve, and so on. - Made depgraph aware of relation types and layers, to do smart flushing of 'changed' events. Nothing gets calculated too often! - Transform uses depgraph to detect changes - On frame-advance, depgraph flushes animated changes Armatures; Almost all armature related code has been fully built from scratch. It now reveils the original design much better, with a very clean implementation, lag free without even calculating each Bone more than once. Result is quite a speedup yes! Important to note is; 1) Armature is data containing the 'rest position' 2) Pose is the changes of rest position, and always on object level. That way more Objects can use same Pose. Also constraints are in Pose 3) Actions only contain the Ipos to change values in Poses. - Bones draw unrotated now - Drawing bones speedup enormously (10-20 times) - Bone selecting in EditMode, selection state is saved for PoseMode, and vice-versa - Undo in editmode - Bone renaming does vertexgroups, constraints, posechannels, actions, for all users of Armature in entire file - Added Bone renaming in NKey panel - Nkey PoseMode shows eulers now - EditMode and PoseMode now have 'active' bone too (last clicked) - Parenting in EditMode' CTRL+P, ALT+P, with nice options! - Pose is added in Outliner now, with showing that constraints are in the Pose, not Armature - Disconnected IK solving from constraints. It's a separate phase now, on top of the full Pose calculations - Pose itself has a dependency graph too, so evaluation order is lag free. TODO NOW; - Rotating in Posemode has incorrect inverse transform (Martin will fix) - Python Bone/Armature/Pose API disabled... needs full recode too (wait for my doc!) - Game engine will need upgrade too - Depgraph code needs revision, cleanup, can be much faster! (But, compliments for Jean-Luc, it works like a charm!) - IK changed, it now doesnt use previous position to advance to next position anymore. That system looks nice (no flips) but is not well suited for NLA and background render. TODO LATER; We now can do loadsa new nifty features as well; like: - Kill PoseMode (can be option for armatures itself) - Make B-Bones (Bezier, Bspline, like for spines) - Move all silly button level edit to 3d window (like CTRL+I = add IK) - Much better & informative drawing - Fix action/nla editors - Put all ipos in Actions (object, mesh key, lamp color) - Add hooks - Null bones - Much more advanced constraints... Bugfixes; - OGL render (view3d header) had wrong first frame on anim render - Ipo 'recording' mode had wrong playback speed - Vertex-key mode now sticks to show 'active key', until frame change -Ton-
2005-07-03 17:35:38 +00:00
}
}
}
else {
invert_m4_m4(ob->imat, ob->obmat); /* imat is needed */
/* 1. clear flags */
for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
pchan->flag &= ~(POSE_DONE | POSE_CHAIN | POSE_IKTREE | POSE_IKSPLINE);
Result of 2 weeks of quiet coding work in Greece :) Aim was to get a total refresh of the animation system. This is needed because; - we need to upgrade it with 21st century features - current code is spaghetti/hack combo, and hides good design - it should become lag-free with using dependency graphs A full log, with complete code API/structure/design explanation will follow, that's a load of work... so here below the list with hot changes; - The entire object update system (matrices, geometry) is now centralized. Calls to where_is_object and makeDispList are forbidden, instead we tag objects 'changed' and let the depgraph code sort it out - Removed all old "Ika" code - Depgraph is aware of all relationships, including meta balls, constraints, bevelcurve, and so on. - Made depgraph aware of relation types and layers, to do smart flushing of 'changed' events. Nothing gets calculated too often! - Transform uses depgraph to detect changes - On frame-advance, depgraph flushes animated changes Armatures; Almost all armature related code has been fully built from scratch. It now reveils the original design much better, with a very clean implementation, lag free without even calculating each Bone more than once. Result is quite a speedup yes! Important to note is; 1) Armature is data containing the 'rest position' 2) Pose is the changes of rest position, and always on object level. That way more Objects can use same Pose. Also constraints are in Pose 3) Actions only contain the Ipos to change values in Poses. - Bones draw unrotated now - Drawing bones speedup enormously (10-20 times) - Bone selecting in EditMode, selection state is saved for PoseMode, and vice-versa - Undo in editmode - Bone renaming does vertexgroups, constraints, posechannels, actions, for all users of Armature in entire file - Added Bone renaming in NKey panel - Nkey PoseMode shows eulers now - EditMode and PoseMode now have 'active' bone too (last clicked) - Parenting in EditMode' CTRL+P, ALT+P, with nice options! - Pose is added in Outliner now, with showing that constraints are in the Pose, not Armature - Disconnected IK solving from constraints. It's a separate phase now, on top of the full Pose calculations - Pose itself has a dependency graph too, so evaluation order is lag free. TODO NOW; - Rotating in Posemode has incorrect inverse transform (Martin will fix) - Python Bone/Armature/Pose API disabled... needs full recode too (wait for my doc!) - Game engine will need upgrade too - Depgraph code needs revision, cleanup, can be much faster! (But, compliments for Jean-Luc, it works like a charm!) - IK changed, it now doesnt use previous position to advance to next position anymore. That system looks nice (no flips) but is not well suited for NLA and background render. TODO LATER; We now can do loadsa new nifty features as well; like: - Kill PoseMode (can be option for armatures itself) - Make B-Bones (Bezier, Bspline, like for spines) - Move all silly button level edit to 3d window (like CTRL+I = add IK) - Much better & informative drawing - Fix action/nla editors - Put all ipos in Actions (object, mesh key, lamp color) - Add hooks - Null bones - Much more advanced constraints... Bugfixes; - OGL render (view3d header) had wrong first frame on anim render - Ipo 'recording' mode had wrong playback speed - Vertex-key mode now sticks to show 'active key', until frame change -Ton-
2005-07-03 17:35:38 +00:00
}
/* 2a. construct the IK tree (standard IK) */
BIK_init_tree(depsgraph, scene, ob, ctime);
/* 2b. construct the Spline IK trees
2018-11-14 12:53:15 +11:00
* - this is not integrated as an IK plugin, since it should be able
* to function in conjunction with standard IK
*/
BKE_pose_splineik_init_tree(scene, ob, ctime);
/* 3. the main loop, channels are already hierarchical sorted from root to children */
for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
/* 4a. if we find an IK root, we handle it separated */
if (pchan->flag & POSE_IKTREE) {
BIK_execute_tree(depsgraph, scene, ob, pchan, ctime);
Integration of new IK lib features in Armature Poses. Best is to forget yesterday's commit and old docs. New docs are underway... Here's how IK works now; - IK chains can go all the way to the furthest parent Bone. Disregarding the old option "IK to Parent" and disgregarding whether a Bone has an offset to its parent (offsets now work for IK, so you can also make T-bones). - The old "IK to Parent" option now only does what it should do: it denotes whether a Bone is directly connected to a Parent Bone, or not. In the UI and in code this option is now called "Connected". - You can also define yourself which Bone will become the "Root" for an IK chain. This can be any Parent of the IK tip (where the IK constraint is). By default it goes all the way, unless you set a value for the new IK Constraint Panel option "Chain Lenght". - "Tree IK" now is detected automatic, when multiple IK Roots are on the same Bone, and when there's a branched structure. Multiple IK's on a single chain (no branches) is still executed as usual, doing the IK's sequentially. - Note: Branched structures, with _partial_ overlapping IK chains, that don't share the same Root will possibly disconnect branches. - When you select a Bone with IK, it now draws a yellow dashed line to its Root. - The IK options "Location Weight" and "Rotation Weight" are relative, in case there's a Tree IK structure. These weights cannot be set to zero. To animate or disable IK Targets, use the "Influence" slider. - This new IK is backwards and upwards compatible for Blender files. Of course, the new features won't show in older Blender binaries! :) Other changes & notes; - In PoseMode, the Constraint Panel now also draws in Editing Buttons, next to the Bones Panel. - IK Constraint Panel was redesigned... it's still a bit squished - Buttons "No X DoF" is now called "Lock X". This to follow convention to name options positive. - Added Undo push for Make/Clear Parent in Editmode Armature - Use CTRL+P "Make Parent" on a single selected Bone to make it become connected (ALT+P had already "Disconnect"). On todo next; Visualizing & review of Bone DoF limits and stiffness
2005-08-28 12:23:06 +00:00
}
/* 4b. if we find a Spline IK root, we handle it separated too */
else if (pchan->flag & POSE_IKSPLINE) {
BKE_splineik_execute_tree(depsgraph, scene, ob, pchan, ctime);
}
/* 5. otherwise just call the normal solver */
else if (!(pchan->flag & POSE_DONE)) {
BKE_pose_where_is_bone(depsgraph, scene, ob, pchan, ctime, 1);
Result of 2 weeks of quiet coding work in Greece :) Aim was to get a total refresh of the animation system. This is needed because; - we need to upgrade it with 21st century features - current code is spaghetti/hack combo, and hides good design - it should become lag-free with using dependency graphs A full log, with complete code API/structure/design explanation will follow, that's a load of work... so here below the list with hot changes; - The entire object update system (matrices, geometry) is now centralized. Calls to where_is_object and makeDispList are forbidden, instead we tag objects 'changed' and let the depgraph code sort it out - Removed all old "Ika" code - Depgraph is aware of all relationships, including meta balls, constraints, bevelcurve, and so on. - Made depgraph aware of relation types and layers, to do smart flushing of 'changed' events. Nothing gets calculated too often! - Transform uses depgraph to detect changes - On frame-advance, depgraph flushes animated changes Armatures; Almost all armature related code has been fully built from scratch. It now reveils the original design much better, with a very clean implementation, lag free without even calculating each Bone more than once. Result is quite a speedup yes! Important to note is; 1) Armature is data containing the 'rest position' 2) Pose is the changes of rest position, and always on object level. That way more Objects can use same Pose. Also constraints are in Pose 3) Actions only contain the Ipos to change values in Poses. - Bones draw unrotated now - Drawing bones speedup enormously (10-20 times) - Bone selecting in EditMode, selection state is saved for PoseMode, and vice-versa - Undo in editmode - Bone renaming does vertexgroups, constraints, posechannels, actions, for all users of Armature in entire file - Added Bone renaming in NKey panel - Nkey PoseMode shows eulers now - EditMode and PoseMode now have 'active' bone too (last clicked) - Parenting in EditMode' CTRL+P, ALT+P, with nice options! - Pose is added in Outliner now, with showing that constraints are in the Pose, not Armature - Disconnected IK solving from constraints. It's a separate phase now, on top of the full Pose calculations - Pose itself has a dependency graph too, so evaluation order is lag free. TODO NOW; - Rotating in Posemode has incorrect inverse transform (Martin will fix) - Python Bone/Armature/Pose API disabled... needs full recode too (wait for my doc!) - Game engine will need upgrade too - Depgraph code needs revision, cleanup, can be much faster! (But, compliments for Jean-Luc, it works like a charm!) - IK changed, it now doesnt use previous position to advance to next position anymore. That system looks nice (no flips) but is not well suited for NLA and background render. TODO LATER; We now can do loadsa new nifty features as well; like: - Kill PoseMode (can be option for armatures itself) - Make B-Bones (Bezier, Bspline, like for spines) - Move all silly button level edit to 3d window (like CTRL+I = add IK) - Much better & informative drawing - Fix action/nla editors - Put all ipos in Actions (object, mesh key, lamp color) - Add hooks - Null bones - Much more advanced constraints... Bugfixes; - OGL render (view3d header) had wrong first frame on anim render - Ipo 'recording' mode had wrong playback speed - Vertex-key mode now sticks to show 'active key', until frame change -Ton-
2005-07-03 17:35:38 +00:00
}
}
/* 6. release the IK tree */
BIK_release_tree(scene, ob, ctime);
2002-10-12 11:37:38 +00:00
}
Result of 2 weeks of quiet coding work in Greece :) Aim was to get a total refresh of the animation system. This is needed because; - we need to upgrade it with 21st century features - current code is spaghetti/hack combo, and hides good design - it should become lag-free with using dependency graphs A full log, with complete code API/structure/design explanation will follow, that's a load of work... so here below the list with hot changes; - The entire object update system (matrices, geometry) is now centralized. Calls to where_is_object and makeDispList are forbidden, instead we tag objects 'changed' and let the depgraph code sort it out - Removed all old "Ika" code - Depgraph is aware of all relationships, including meta balls, constraints, bevelcurve, and so on. - Made depgraph aware of relation types and layers, to do smart flushing of 'changed' events. Nothing gets calculated too often! - Transform uses depgraph to detect changes - On frame-advance, depgraph flushes animated changes Armatures; Almost all armature related code has been fully built from scratch. It now reveils the original design much better, with a very clean implementation, lag free without even calculating each Bone more than once. Result is quite a speedup yes! Important to note is; 1) Armature is data containing the 'rest position' 2) Pose is the changes of rest position, and always on object level. That way more Objects can use same Pose. Also constraints are in Pose 3) Actions only contain the Ipos to change values in Poses. - Bones draw unrotated now - Drawing bones speedup enormously (10-20 times) - Bone selecting in EditMode, selection state is saved for PoseMode, and vice-versa - Undo in editmode - Bone renaming does vertexgroups, constraints, posechannels, actions, for all users of Armature in entire file - Added Bone renaming in NKey panel - Nkey PoseMode shows eulers now - EditMode and PoseMode now have 'active' bone too (last clicked) - Parenting in EditMode' CTRL+P, ALT+P, with nice options! - Pose is added in Outliner now, with showing that constraints are in the Pose, not Armature - Disconnected IK solving from constraints. It's a separate phase now, on top of the full Pose calculations - Pose itself has a dependency graph too, so evaluation order is lag free. TODO NOW; - Rotating in Posemode has incorrect inverse transform (Martin will fix) - Python Bone/Armature/Pose API disabled... needs full recode too (wait for my doc!) - Game engine will need upgrade too - Depgraph code needs revision, cleanup, can be much faster! (But, compliments for Jean-Luc, it works like a charm!) - IK changed, it now doesnt use previous position to advance to next position anymore. That system looks nice (no flips) but is not well suited for NLA and background render. TODO LATER; We now can do loadsa new nifty features as well; like: - Kill PoseMode (can be option for armatures itself) - Make B-Bones (Bezier, Bspline, like for spines) - Move all silly button level edit to 3d window (like CTRL+I = add IK) - Much better & informative drawing - Fix action/nla editors - Put all ipos in Actions (object, mesh key, lamp color) - Add hooks - Null bones - Much more advanced constraints... Bugfixes; - OGL render (view3d header) had wrong first frame on anim render - Ipo 'recording' mode had wrong playback speed - Vertex-key mode now sticks to show 'active key', until frame change -Ton-
2005-07-03 17:35:38 +00:00
/* calculating deform matrices */
for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
if (pchan->bone) {
invert_m4_m4(imat, pchan->bone->arm_mat);
mul_m4_m4m4(pchan->chan_mat, pchan->pose_mat, imat);
Result of 2 weeks of quiet coding work in Greece :) Aim was to get a total refresh of the animation system. This is needed because; - we need to upgrade it with 21st century features - current code is spaghetti/hack combo, and hides good design - it should become lag-free with using dependency graphs A full log, with complete code API/structure/design explanation will follow, that's a load of work... so here below the list with hot changes; - The entire object update system (matrices, geometry) is now centralized. Calls to where_is_object and makeDispList are forbidden, instead we tag objects 'changed' and let the depgraph code sort it out - Removed all old "Ika" code - Depgraph is aware of all relationships, including meta balls, constraints, bevelcurve, and so on. - Made depgraph aware of relation types and layers, to do smart flushing of 'changed' events. Nothing gets calculated too often! - Transform uses depgraph to detect changes - On frame-advance, depgraph flushes animated changes Armatures; Almost all armature related code has been fully built from scratch. It now reveils the original design much better, with a very clean implementation, lag free without even calculating each Bone more than once. Result is quite a speedup yes! Important to note is; 1) Armature is data containing the 'rest position' 2) Pose is the changes of rest position, and always on object level. That way more Objects can use same Pose. Also constraints are in Pose 3) Actions only contain the Ipos to change values in Poses. - Bones draw unrotated now - Drawing bones speedup enormously (10-20 times) - Bone selecting in EditMode, selection state is saved for PoseMode, and vice-versa - Undo in editmode - Bone renaming does vertexgroups, constraints, posechannels, actions, for all users of Armature in entire file - Added Bone renaming in NKey panel - Nkey PoseMode shows eulers now - EditMode and PoseMode now have 'active' bone too (last clicked) - Parenting in EditMode' CTRL+P, ALT+P, with nice options! - Pose is added in Outliner now, with showing that constraints are in the Pose, not Armature - Disconnected IK solving from constraints. It's a separate phase now, on top of the full Pose calculations - Pose itself has a dependency graph too, so evaluation order is lag free. TODO NOW; - Rotating in Posemode has incorrect inverse transform (Martin will fix) - Python Bone/Armature/Pose API disabled... needs full recode too (wait for my doc!) - Game engine will need upgrade too - Depgraph code needs revision, cleanup, can be much faster! (But, compliments for Jean-Luc, it works like a charm!) - IK changed, it now doesnt use previous position to advance to next position anymore. That system looks nice (no flips) but is not well suited for NLA and background render. TODO LATER; We now can do loadsa new nifty features as well; like: - Kill PoseMode (can be option for armatures itself) - Make B-Bones (Bezier, Bspline, like for spines) - Move all silly button level edit to 3d window (like CTRL+I = add IK) - Much better & informative drawing - Fix action/nla editors - Put all ipos in Actions (object, mesh key, lamp color) - Add hooks - Null bones - Much more advanced constraints... Bugfixes; - OGL render (view3d header) had wrong first frame on anim render - Ipo 'recording' mode had wrong playback speed - Vertex-key mode now sticks to show 'active key', until frame change -Ton-
2005-07-03 17:35:38 +00:00
}
}
}
/** \} */
/* -------------------------------------------------------------------- */
/** \name Calculate Bounding Box (Armature & Pose)
* \{ */
static int minmax_armature(Object *ob, float r_min[3], float r_max[3])
{
bPoseChannel *pchan;
/* For now, we assume BKE_pose_where_is has already been called
* (hence we have valid data in pachan). */
for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
minmax_v3v3_v3(r_min, r_max, pchan->pose_head);
minmax_v3v3_v3(r_min, r_max, pchan->pose_tail);
}
return (BLI_listbase_is_empty(&ob->pose->chanbase) == false);
}
static void boundbox_armature(Object *ob)
{
BoundBox *bb;
float min[3], max[3];
if (ob->runtime.bb == NULL) {
ob->runtime.bb = MEM_callocN(sizeof(BoundBox), "Armature boundbox");
}
bb = ob->runtime.bb;
INIT_MINMAX(min, max);
if (!minmax_armature(ob, min, max)) {
min[0] = min[1] = min[2] = -1.0f;
max[0] = max[1] = max[2] = 1.0f;
}
BKE_boundbox_init_from_minmax(bb, min, max);
bb->flag &= ~BOUNDBOX_DIRTY;
}
BoundBox *BKE_armature_boundbox_get(Object *ob)
{
boundbox_armature(ob);
return ob->runtime.bb;
}
bool BKE_pose_minmax(Object *ob, float r_min[3], float r_max[3], bool use_hidden, bool use_select)
{
bool changed = false;
if (ob->pose) {
bArmature *arm = ob->data;
bPoseChannel *pchan;
for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
/* XXX pchan->bone may be NULL for duplicated bones, see duplicateEditBoneObjects() comment
* (editarmature.c:2592)... Skip in this case too! */
if (pchan->bone && (!((use_hidden == false) && (PBONE_VISIBLE(arm, pchan->bone) == false)) &&
!((use_select == true) && ((pchan->bone->flag & BONE_SELECTED) == 0)))) {
bPoseChannel *pchan_tx = (pchan->custom && pchan->custom_tx) ? pchan->custom_tx : pchan;
BoundBox *bb_custom = ((pchan->custom) && !(arm->flag & ARM_NO_CUSTOM)) ?
BKE_object_boundbox_get(pchan->custom) :
NULL;
if (bb_custom) {
float mat[4][4], smat[4][4];
scale_m4_fl(smat, PCHAN_CUSTOM_DRAW_SIZE(pchan));
mul_m4_series(mat, ob->obmat, pchan_tx->pose_mat, smat);
BKE_boundbox_minmax(bb_custom, mat, r_min, r_max);
}
else {
float vec[3];
mul_v3_m4v3(vec, ob->obmat, pchan_tx->pose_head);
minmax_v3v3_v3(r_min, r_max, vec);
mul_v3_m4v3(vec, ob->obmat, pchan_tx->pose_tail);
minmax_v3v3_v3(r_min, r_max, vec);
}
changed = true;
}
}
}
return changed;
}
/** \} */
/* -------------------------------------------------------------------- */
/** \name Graph Evaluation
* \{ */
2015-05-13 06:10:49 +10:00
bPoseChannel *BKE_armature_ik_solver_find_root(bPoseChannel *pchan, bKinematicConstraint *data)
{
bPoseChannel *rootchan = pchan;
if (!(data->flag & CONSTRAINT_IK_TIP)) {
/* Exclude tip from chain. */
rootchan = rootchan->parent;
}
if (rootchan != NULL) {
int segcount = 0;
while (rootchan->parent) {
/* Continue up chain, until we reach target number of items. */
segcount++;
if (segcount == data->rootbone) {
break;
}
rootchan = rootchan->parent;
}
}
return rootchan;
}
2015-05-13 06:10:49 +10:00
bPoseChannel *BKE_armature_splineik_solver_find_root(bPoseChannel *pchan,
bSplineIKConstraint *data)
{
bPoseChannel *rootchan = pchan;
int segcount = 0;
BLI_assert(rootchan != NULL);
while (rootchan->parent) {
/* Continue up chain, until we reach target number of items. */
segcount++;
if (segcount == data->chainlen) {
break;
}
rootchan = rootchan->parent;
}
return rootchan;
}
/** \} */