Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/blenkernel/intern')
-rw-r--r--source/blender/blenkernel/intern/action.c1017
-rw-r--r--source/blender/blenkernel/intern/anim.c18
-rw-r--r--source/blender/blenkernel/intern/armature.c1622
-rw-r--r--source/blender/blenkernel/intern/blender.c9
-rw-r--r--source/blender/blenkernel/intern/constraint.c698
-rw-r--r--source/blender/blenkernel/intern/deform.c7
-rw-r--r--source/blender/blenkernel/intern/depsgraph.c802
-rw-r--r--source/blender/blenkernel/intern/displist.c187
-rw-r--r--source/blender/blenkernel/intern/effect.c4
-rw-r--r--source/blender/blenkernel/intern/exotic.c1
-rw-r--r--source/blender/blenkernel/intern/font.c4
-rw-r--r--source/blender/blenkernel/intern/ika.c596
-rw-r--r--source/blender/blenkernel/intern/ipo.c132
-rw-r--r--source/blender/blenkernel/intern/key.c31
-rw-r--r--source/blender/blenkernel/intern/lattice.c2
-rw-r--r--source/blender/blenkernel/intern/library.c50
-rw-r--r--source/blender/blenkernel/intern/material.c4
-rw-r--r--source/blender/blenkernel/intern/object.c274
-rw-r--r--source/blender/blenkernel/intern/scene.c205
19 files changed, 2389 insertions, 3274 deletions
diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c
index 4b1f47707af..911df2a5998 100644
--- a/source/blender/blenkernel/intern/action.c
+++ b/source/blender/blenkernel/intern/action.c
@@ -23,9 +23,7 @@
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
+ * Contributor(s): Full recode, Ton Roosendaal, Crete 2005
*
* ***** END GPL/BL DUAL LICENSE BLOCK *****
*/
@@ -39,50 +37,141 @@
#include <stdlib.h> /* for NULL */
#include "MEM_guardedalloc.h"
-#include "BLI_arithb.h"
-#include "BLI_blenlib.h"
-#include "BKE_action.h"
-#include "BKE_global.h"
-#include "BKE_main.h"
-#include "BKE_utildefines.h"
-
-#include "DNA_object_types.h"
-#include "DNA_ipo_types.h"
-#include "DNA_curve_types.h"
-#include "DNA_scene_types.h"
#include "DNA_action_types.h"
+#include "DNA_armature_types.h"
+#include "DNA_constraint_types.h"
+#include "DNA_curve_types.h"
+#include "DNA_ipo_types.h"
#include "DNA_nla_types.h"
+#include "DNA_object_types.h"
+#include "DNA_scene_types.h"
+#include "BKE_action.h"
+#include "BKE_anim.h"
+#include "BKE_armature.h"
#include "BKE_blender.h"
+#include "BKE_constraint.h"
+#include "BKE_global.h"
#include "BKE_ipo.h"
-#include "BKE_object.h"
#include "BKE_library.h"
-#include "BKE_anim.h"
-#include "BKE_armature.h"
+#include "BKE_main.h"
+#include "BKE_object.h"
+#include "BKE_utildefines.h"
+
+#include "BLI_arithb.h"
+#include "BLI_blenlib.h"
#include "nla.h"
-#include "BKE_constraint.h"
-#include "DNA_constraint_types.h"
+/* *********************** NOTE ON POSE AND ACTION **********************
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
+ - Pose is the local (object level) component of armature. The current
+ object pose is saved in files, and (will be) is presorted for dependency
+ - Actions have fewer (or other) channels, and write data to a Pose
+ - Currently ob->pose data is controlled in where_is_pose only. The (recalc)
+ event system takes care of calling that
+ - The NLA system (here too) uses Poses as interpolation format for Actions
+ - Therefore we assume poses to be static, and duplicates of poses have channels in
+ same order, for quick interpolation reasons
+
+ ****************************** (ton) ************************************ */
+
+/* ***************** Library data level operations on action ************** */
+
+void make_local_action(bAction *act)
+{
+ Object *ob;
+ bAction *actn;
+ int local=0, lib=0;
+
+ if(act->id.lib==0) return;
+ if(act->id.us==1) {
+ act->id.lib= 0;
+ act->id.flag= LIB_LOCAL;
+ new_id(0, (ID *)act, 0);
+ return;
+ }
+
+ ob= G.main->object.first;
+ while(ob) {
+ if(ob->action==act) {
+ if(ob->id.lib) lib= 1;
+ else local= 1;
+ }
+ ob= ob->id.next;
+ }
+
+ if(local && lib==0) {
+ act->id.lib= 0;
+ act->id.flag= LIB_LOCAL;
+ new_id(0, (ID *)act, 0);
+ }
+ else if(local && lib) {
+ actn= copy_action(act);
+ actn->id.us= 0;
+
+ ob= G.main->object.first;
+ while(ob) {
+ if(ob->action==act) {
+
+ if(ob->id.lib==0) {
+ ob->action = actn;
+ ob->activecon = NULL;
+ actn->id.us++;
+ act->id.us--;
+ }
+ }
+ ob= ob->id.next;
+ }
+ }
+}
-/* Local function prototypes */
-static void do_pose_constraint_channels(bPose *pose, bAction *act,
- float ctime);
+void free_action(bAction *act)
+{
+ bActionChannel *chan;
+
+ /* Free channels */
+ for (chan=act->chanbase.first; chan; chan=chan->next){
+ if (chan->ipo)
+ chan->ipo->id.us--;
+ free_constraint_channels(&chan->constraintChannels);
+ }
+
+ if (act->chanbase.first)
+ BLI_freelistN (&act->chanbase);
+}
+
+bAction* copy_action(bAction *src)
+{
+ bAction *dst = NULL;
+ bActionChannel *dchan, *schan;
+
+ if(!src) return NULL;
+
+ dst= copy_libblock(src);
+ duplicatelist(&(dst->chanbase), &(src->chanbase));
+
+ for (dchan=dst->chanbase.first, schan=src->chanbase.first; dchan; dchan=dchan->next, schan=schan->next){
+ dchan->ipo = copy_ipo(dchan->ipo);
+ copy_constraint_channels(&dchan->constraintChannels, &schan->constraintChannels);
+ }
+ dst->id.flag |= LIB_FAKEUSER;
+ dst->id.us++;
+ return dst;
+}
+
-static void rest_pose(bPose *pose, int clearflag);
-/* Implementation */
+/* ************************ Pose channels *************** */
bPoseChannel *get_pose_channel(const bPose *pose, const char *name)
{
bPoseChannel *chan;
+ if(pose==NULL) return NULL;
+
for (chan=pose->chanbase.first; chan; chan=chan->next){
if (!strcmp (chan->name, name))
return chan;
@@ -91,70 +180,132 @@ bPoseChannel *get_pose_channel(const bPose *pose, const char *name)
return NULL;
}
-static void rest_pose(bPose *pose, int clearflag)
+/* Use with care, not on Armature poses but for temporal ones */
+/* (currently used for action constraints and in rebuild_pose) */
+bPoseChannel *verify_pose_channel(bPose* pose, const char* name)
{
bPoseChannel *chan;
- int i;
+
+ if (!pose){
+ return NULL;
+ }
+
+ /* See if this channel exists */
+ for (chan=pose->chanbase.first; chan; chan=chan->next){
+ if (!strcmp (name, chan->name))
+ return chan;
+ }
+
+ /* If not, create it and add it */
+ chan = MEM_callocN(sizeof(bPoseChannel), "verifyPoseChannel");
+
+ strcpy (chan->name, name);
+ /* init vars to prevent mat errors */
+ chan->quat[0] = 1.0F;
+ chan->size[0] = chan->size[1] = chan->size[2] = 1.0F;
+ Mat3One(chan->ik_mat);
+
+ BLI_addtail (&pose->chanbase, chan);
+
+ return chan;
+}
- if (!pose)
+
+/* dst should be freed already, makes entire duplicate */
+void copy_pose(bPose **dst, bPose *src, int copycon)
+{
+ bPose *outPose;
+ bPoseChannel *pchan;
+ ListBase listb;
+
+ if (!src){
+ *dst=NULL;
return;
+ }
+
+ outPose= MEM_callocN(sizeof(bPose), "pose");
+
+ duplicatelist (&outPose->chanbase, &src->chanbase);
+
+ if (copycon) {
+ for (pchan=outPose->chanbase.first; pchan; pchan=pchan->next) {
+ copy_constraints(&listb, &pchan->constraints); // copy_constraints NULLs listb
+ pchan->constraints= listb;
+ }
+ }
+
+ *dst=outPose;
+}
- for (chan=pose->chanbase.first; chan; chan=chan->next){
- for (i=0; i<3; i++){
- chan->loc[i]=0.0;
- chan->quat[i+1]=0.0;
- chan->size[i]=1.0;
+void free_pose_channels(bPose *pose)
+{
+ bPoseChannel *chan;
+
+ if (pose->chanbase.first){
+ for (chan = pose->chanbase.first; chan; chan=chan->next){
+ free_constraints(&chan->constraints);
}
- chan->quat[0]=1.0;
- if (clearflag)
- chan->flag =0;
+ BLI_freelistN (&pose->chanbase);
}
}
-#ifdef __NLA_BLENDCON
-static void blend_constraints(ListBase *dst, const ListBase *src,
- float srcweight, short mode)
+static void copy_pose_channel_data(bPoseChannel *pchan, const bPoseChannel *chan)
{
- bConstraint *dcon;
- const bConstraint *scon;
- float dstweight = 0;
+ VECCOPY(pchan->loc, chan->loc);
+ VECCOPY(pchan->size, chan->size);
+ QUATCOPY(pchan->quat, chan->quat);
+ pchan->flag= chan->flag;
+}
- switch (mode){
- case POSE_BLEND:
- dstweight = 1.0F - srcweight;
- break;
- case POSE_ADD:
- dstweight = 1.0F;
- break;
+/* checks for IK constraint, can do more constraints flags later */
+/* pose should be entirely OK */
+void update_pose_constraint_flags(bPose *pose)
+{
+ bPoseChannel *pchan;
+ bConstraint *con;
+
+ /* clear */
+ for (pchan = pose->chanbase.first; pchan; pchan=pchan->next) {
+ pchan->constflag= 0;
}
-
- /* Blend constraints */
- for (dcon=dst->first; dcon; dcon=dcon->next){
- for (scon = src->first; scon; scon=scon->next){
- if (!strcmp(scon->name, dcon->name))
- break;
+ /* detect */
+ for (pchan = pose->chanbase.first; pchan; pchan=pchan->next) {
+ for(con= pchan->constraints.first; con; con= con->next) {
+ if(con->type==CONSTRAINT_TYPE_KINEMATIC) {
+ pchan->constflag |= PCHAN_HAS_IK;
+ }
+ else pchan->constflag |= PCHAN_HAS_CONST;
}
-
- if (scon){
- dcon->enforce = (dcon->enforce*dstweight) + (scon->enforce*srcweight);
- if (mode == POSE_BLEND)
- dcon->enforce/=2.0;
-
- if (dcon->enforce>1.0)
- dcon->enforce=1.0;
- if (dcon->enforce<0.0)
- dcon->enforce=0.0;
+ }
+}
- }
+
+/* ************************ END Pose channels *************** */
+
+bActionChannel *get_named_actionchannel(bAction *act, const char *name)
+{
+ bActionChannel *chan;
+
+ if (!act)
+ return NULL;
+
+ for (chan = act->chanbase.first; chan; chan=chan->next){
+ if (!strcmp (chan->name, name))
+ return chan;
}
+
+ return NULL;
}
-#endif
+/* ************************ Blending with NLA *************** */
+
+
+/* Only allowed for Poses with identical channels */
void blend_poses(bPose *dst, const bPose *src, float srcweight, short mode)
{
bPoseChannel *dchan;
const bPoseChannel *schan;
- float dquat[4], squat[4]; //, mat[3][3];
+ float dquat[4], squat[4];
float dstweight;
int i;
@@ -169,67 +320,35 @@ void blend_poses(bPose *dst, const bPose *src, float srcweight, short mode)
dstweight = 1.0F;
}
- for (dchan = dst->chanbase.first; dchan; dchan=dchan->next){
- schan = get_pose_channel(src, dchan->name);
- if (schan){
- if (schan->flag & (POSE_ROT|POSE_LOC|POSE_SIZE)){
-
- /* Convert both quats to matrices and then back again.
- * This prevents interpolation problems
- * This sucks because it is slow and stupid
- */
-
- //QuatToMat3(dchan->quat, mat);
- //Mat3ToQuat(mat, dquat);
- //QuatToMat3(schan->quat, mat);
- //Mat3ToQuat(mat, squat);
+ schan= src->chanbase.first;
+ for (dchan = dst->chanbase.first; dchan; dchan=dchan->next, schan= schan->next){
+ if (schan->flag & (POSE_ROT|POSE_LOC|POSE_SIZE)) {
+
+ /* replaced quat->matrix->quat conversion with decent quaternion interpol (ton) */
+
+ /* Do the transformation blend */
+ if (schan->flag & POSE_ROT) {
+ QUATCOPY(dquat, dchan->quat);
+ QUATCOPY(squat, schan->quat);
+ if(mode==POSE_BLEND)
+ QuatInterpol(dchan->quat, dquat, squat, srcweight);
+ else
+ QuatAdd(dchan->quat, dquat, squat, srcweight);
- /* replaced quat->matrix->quat conversion with decent quaternion interpol (ton) */
- /* Do the transformation blend */
- if (schan->flag & POSE_ROT) {
- QUATCOPY(dquat, dchan->quat);
- QUATCOPY(squat, schan->quat);
- if(mode==POSE_BLEND)
- QuatInterpol(dchan->quat, dquat, squat, srcweight);
- else
- QuatAdd(dchan->quat, dquat, squat, srcweight);
- NormalQuat (dchan->quat);
- }
+ NormalQuat (dchan->quat);
+ }
- for (i=0; i<3; i++){
- if (schan->flag & POSE_LOC)
- dchan->loc[i] = (dchan->loc[i]*dstweight) + (schan->loc[i]*srcweight);
- if (schan->flag & POSE_SIZE)
- dchan->size[i] = 1.0f + ((dchan->size[i]-1.0f)*dstweight) + ((schan->size[i]-1.0f)*srcweight);
- //if (schan->flag & POSE_ROT)
- // dchan->quat[i+1] = (dquat[i+1]*dstweight) + (squat[i+1]*srcweight);
- }
-
- /* Do one more iteration for the quaternions only and normalize the quaternion if needed */
- //if (schan->flag & POSE_ROT)
- // dchan->quat[0] = 1.0f + ((dquat[0]-1.0f)*dstweight) + ((squat[0]-1.0f)*srcweight);
- //if (mode==POSE_BLEND)
- // NormalQuat (dchan->quat);
-
- dchan->flag |= schan->flag;
+ for (i=0; i<3; i++){
+ if (schan->flag & POSE_LOC)
+ dchan->loc[i] = (dchan->loc[i]*dstweight) + (schan->loc[i]*srcweight);
+ if (schan->flag & POSE_SIZE)
+ dchan->size[i] = 1.0f + ((dchan->size[i]-1.0f)*dstweight) + ((schan->size[i]-1.0f)*srcweight);
}
+ dchan->flag |= schan->flag;
}
}
}
-void clear_pose_constraint_status(Object *ob)
-{
- bPoseChannel *chan;
-
- if (!ob)
- return;
- if (!ob->pose)
- return;
-
- for (chan = ob->pose->chanbase.first; chan; chan=chan->next){
- chan->flag &= ~PCHAN_DONE;
- }
-}
float calc_action_start(const bAction *act)
{
@@ -291,59 +410,60 @@ float calc_action_end(const bAction *act)
return size;
}
-bPoseChannel *verify_pose_channel(bPose* pose, const char* name)
+/* Copy the data from the action-pose (src) into the pose */
+/* both args are assumed to be valid */
+/* exported to game engine */
+void extract_pose_from_pose(bPose *pose, const bPose *src)
{
- bPoseChannel *chan;
-
- if (!pose){
- return NULL;
- }
+ const bPoseChannel *schan;
+ bPoseChannel *pchan= pose->chanbase.first;
- /* See if this channel exists */
- for (chan=pose->chanbase.first; chan; chan=chan->next){
- if (!strcmp (name, chan->name))
- return chan;
+ for (schan=src->chanbase.first; schan; schan=schan->next, pchan= pchan->next) {
+ copy_pose_channel_data(pchan, schan);
}
-
- /* If not, create it and add it */
- chan = MEM_callocN(sizeof(bPoseChannel), "verifyPoseChannel");
-
- strcpy (chan->name, name);
- chan->loc[0] = chan->loc[1] = chan->loc[2] = 0.0F;
- chan->quat[1] = chan->quat[2] = chan->quat[3] = 0.0F;
- chan->quat[0] = 1.0F;
- chan->size[0] = chan->size[1] = chan->size[2] = 1.0F;
-
- chan->flag |= POSE_ROT|POSE_SIZE|POSE_LOC;
-
- BLI_addtail (&pose->chanbase, chan);
-
- return chan;
}
-void get_pose_from_pose(bPose **pose, const bPose *src)
+/* seems to be disabled... (ton) */
+#ifdef __NLA_BLENDCON
+static void blend_constraints(ListBase *dst, const ListBase *src,
+ float srcweight, short mode)
{
- const bPoseChannel *pchan;
- bPoseChannel *newchan;
-
- if (!src)
- return;
- if (!pose)
- return;
-
- /* If there is no pose, create one */
- if (!*pose){
- *pose=MEM_callocN (sizeof(bPose), "pose");
+ bConstraint *dcon;
+ const bConstraint *scon;
+ float dstweight = 0;
+
+ switch (mode){
+ case POSE_BLEND:
+ dstweight = 1.0F - srcweight;
+ break;
+ case POSE_ADD:
+ dstweight = 1.0F;
+ break;
}
-
- /* Copy the data from the action into the pose */
- for (pchan=src->chanbase.first; pchan; pchan=pchan->next){
- newchan = copy_pose_channel(pchan);
- verify_pose_channel(*pose, pchan->name);
- set_pose_channel(*pose, newchan);
+
+ /* Blend constraints */
+ for (dcon=dst->first; dcon; dcon=dcon->next){
+ for (scon = src->first; scon; scon=scon->next){
+ if (!strcmp(scon->name, dcon->name))
+ break;
+ }
+
+ if (scon){
+ dcon->enforce = (dcon->enforce*dstweight) + (scon->enforce*srcweight);
+ if (mode == POSE_BLEND)
+ dcon->enforce/=2.0;
+
+ if (dcon->enforce>1.0)
+ dcon->enforce=1.0;
+ if (dcon->enforce<0.0)
+ dcon->enforce=0.0;
+
+ }
}
}
+#endif
+/* seems to be disabled... (ton) */
#ifdef __NLA_BLENDCON
static void get_constraint_influence_from_pose(bPose *dst, bPose *src)
{
@@ -364,72 +484,76 @@ static void get_constraint_influence_from_pose(bPose *dst, bPose *src)
}
#endif
-/* If the pose does not exist, a new one is created */
-
-void get_pose_from_action(bPose **pose, bAction *act, float ctime)
+/* Pose should exist, can have any number of channels too (used for constraint) */
+void extract_pose_from_action(bPose *pose, bAction *act, float ctime)
{
bActionChannel *achan;
bPoseChannel *pchan;
Ipo *ipo;
- IpoCurve *curve;
-
if (!act)
return;
if (!pose)
return;
- /* If there is no pose, create one */
- if (!*pose){
- *pose=MEM_callocN (sizeof(bPose), "pose");
- }
-
/* Copy the data from the action into the pose */
for (achan=act->chanbase.first; achan; achan=achan->next){
- act->achan= achan;
+ act->achan= achan; // for ipos
ipo = achan->ipo;
- if (ipo){
- pchan=MEM_callocN (sizeof(bPoseChannel), "gpfa_poseChannel");
- strcpy (pchan->name, achan->name);
-
- act->pchan=pchan;
- /* Evaluates and sets the internal ipo value */
- calc_ipo(ipo, ctime);
-
- /* Set the pchan flags */
- for (curve = achan->ipo->curve.first; curve; curve=curve->next){
- /* Skip empty curves */
- if (!curve->totvert)
- continue;
-
- switch (curve->adrcode){
- case AC_QUAT_X:
- case AC_QUAT_Y:
- case AC_QUAT_Z:
- case AC_QUAT_W:
- pchan->flag |= POSE_ROT;
- break;
- case AC_LOC_X:
- case AC_LOC_Y:
- case AC_LOC_Z:
- pchan->flag |= POSE_LOC;
- break;
- case AC_SIZE_X:
- case AC_SIZE_Y:
- case AC_SIZE_Z:
- pchan->flag |= POSE_SIZE;
- break;
- }
+ if (ipo) {
+ pchan= get_pose_channel(pose, achan->name);
+ if(pchan) {
+ act->pchan= pchan; // for ipos
+
+ /* Evaluates and sets the internal ipo value */
+ calc_ipo(ipo, ctime);
+
+ /* This call also sets the pchan flags */
+ execute_ipo((ID*)act, achan->ipo);
}
+ }
+ }
+}
- execute_ipo((ID*)act, achan->ipo);
-
- set_pose_channel(*pose, pchan);
+/* for do_all_actions, clears the pose */
+static void rest_pose(bPose *pose, int clearflag)
+{
+ bPoseChannel *chan;
+ int i;
+
+ if (!pose)
+ return;
+
+ for (chan=pose->chanbase.first; chan; chan=chan->next){
+ for (i=0; i<3; i++){
+ chan->loc[i]=0.0;
+ chan->quat[i+1]=0.0;
+ chan->size[i]=1.0;
}
+ chan->quat[0]=1.0;
+ if (clearflag)
+ chan->flag =0;
+ }
+}
+
+/* do constraint channels = execute the ipos */
+static void do_pose_constraint_channels(bPose *pose, bAction *act, float ctime)
+{
+ bPoseChannel *pchan;
+ bActionChannel *achan;
+
+ if (!pose || !act)
+ return;
+
+ for (pchan=pose->chanbase.first; pchan; pchan=pchan->next){
+ achan=get_named_actionchannel(act, pchan->name);
+ if (achan)
+ do_constraint_channels(&pchan->constraints, &achan->constraintChannels, ctime);
}
}
+
void do_all_actions(Object *only_this)
{
Base *base;
@@ -440,9 +564,11 @@ void do_all_actions(Object *only_this)
int doit;
float striptime, frametime, length, actlength;
float blendfac, stripframe;
-
int set;
+ //printf("do all actions disabled\n");
+ //return;
+
/* NEW: current scene ob ipo's */
base= G.scene->base.first;
set= 0;
@@ -453,150 +579,154 @@ void do_all_actions(Object *only_this)
else ob = base->object;
/* Retrieve data from the NLA */
- if(ob->type==OB_ARMATURE){
+ if(ob->type==OB_ARMATURE && ob->pose) {
+ bArmature *arm= ob->data;
- doit=0;
-
- /* Clear pose */
- if (apose){
- clear_pose(apose);
- MEM_freeN(apose);
- }
- /* Clear pose */
- if (tpose){
- clear_pose(tpose);
- MEM_freeN(tpose);
+ if(arm->flag & ARM_NO_ACTION) { // no action set while transform
+ ;
}
+ else {
+ doit=0;
- copy_pose(&apose, ob->pose, 1);
- copy_pose(&tpose, ob->pose, 1);
- rest_pose(apose, 1);
-
- if (ob->nlastrips.first){
- rest_pose(ob->pose, 0);
- }
+ /* Clear pose */
+ if (apose){
+ free_pose_channels(apose);
+ MEM_freeN(apose);
+ }
+ /* Clear pose */
+ if (tpose){
+ free_pose_channels(tpose);
+ MEM_freeN(tpose);
+ }
- for (strip=ob->nlastrips.first; strip; strip=strip->next){
- doit = 0;
- if (strip->act){
-
- /* Determine if the current frame is within the strip's range */
- length = strip->end-strip->start;
- actlength = strip->actend-strip->actstart;
- striptime = (G.scene->r.cfra-(strip->start)) / length;
- stripframe = (G.scene->r.cfra-(strip->start)) ;
-
-
- if (striptime>=0.0){
-
- rest_pose(tpose, 1);
-
- /* Handle path */
- if (strip->flag & ACTSTRIP_USESTRIDE){
- if (ob->parent && ob->parent->type==OB_CURVE){
- Curve *cu = ob->parent->data;
- float ctime, pdist;
-
- if (cu->flag & CU_PATH){
- /* Ensure we have a valid path */
- if(cu->path==0 || cu->path->data==0) calc_curvepath(ob->parent);
-
- /* Find the position on the path */
- ctime= bsystem_time(ob, ob->parent, (float)G.scene->r.cfra, 0.0);
-
- if(calc_ipo_spec(cu->ipo, CU_SPEED, &ctime)==0) {
- ctime /= cu->pathlen;
- CLAMP(ctime, 0.0, 1.0);
+ copy_pose(&apose, ob->pose, 1);
+ copy_pose(&tpose, ob->pose, 1);
+ rest_pose(apose, 1);
+
+ if (ob->nlastrips.first){
+ rest_pose(ob->pose, 0);
+ }
+
+ for (strip=ob->nlastrips.first; strip; strip=strip->next){
+ doit = 0;
+ if (strip->act){
+
+ /* Determine if the current frame is within the strip's range */
+ length = strip->end-strip->start;
+ actlength = strip->actend-strip->actstart;
+ striptime = (G.scene->r.cfra-(strip->start)) / length;
+ stripframe = (G.scene->r.cfra-(strip->start)) ;
+
+
+ if (striptime>=0.0){
+
+ rest_pose(tpose, 1);
+
+ /* Handle path */
+ if (strip->flag & ACTSTRIP_USESTRIDE){
+ if (ob->parent && ob->parent->type==OB_CURVE){
+ Curve *cu = ob->parent->data;
+ float ctime, pdist;
+
+ if (cu->flag & CU_PATH){
+ /* Ensure we have a valid path */
+ if(cu->path==NULL || cu->path->data==NULL) printf("action path error\n");
+ else {
+
+ /* Find the position on the path */
+ ctime= bsystem_time(ob, ob->parent, (float)G.scene->r.cfra, 0.0);
+
+ if(calc_ipo_spec(cu->ipo, CU_SPEED, &ctime)==0) {
+ ctime /= cu->pathlen;
+ CLAMP(ctime, 0.0, 1.0);
+ }
+ pdist = ctime*cu->path->totdist;
+
+ if (strip->stridelen)
+ striptime = pdist / strip->stridelen;
+ else
+ striptime = 0;
+
+ striptime = (float)fmod (striptime, 1.0);
+
+ frametime = (striptime * actlength) + strip->actstart;
+ extract_pose_from_action (tpose, strip->act, bsystem_time(ob, 0, frametime, 0.0));
+ #ifdef __NLA_BLENDCON
+ do_pose_constraint_channels(tpose, strip->act, bsystem_time(ob, 0, frametime, 0.0));
+ #endif
+ doit=1;
+ }
}
- pdist = ctime*cu->path->totdist;
-
- if (strip->stridelen)
- striptime = pdist / strip->stridelen;
- else
- striptime = 0;
-
- striptime = (float)fmod (striptime, 1.0);
-
- frametime = (striptime * actlength) + strip->actstart;
- get_pose_from_action (&tpose, strip->act, bsystem_time(ob, 0, frametime, 0.0));
-#ifdef __NLA_BLENDCON
- do_pose_constraint_channels(tpose, strip->act, bsystem_time(ob, 0, frametime, 0.0));
-#endif
- doit=1;
}
}
- }
- /* Handle repeat */
-
- else if (striptime < 1.0){
- /* Mod to repeat */
- striptime*=strip->repeat;
- striptime = (float)fmod (striptime, 1.0);
-
- frametime = (striptime * actlength) + strip->actstart;
- get_pose_from_action (&tpose, strip->act, bsystem_time(ob, 0, frametime, 0.0));
-#ifdef __NLA_BLENDCON
- do_pose_constraint_channels(tpose, strip->act, bsystem_time(ob, 0, frametime, 0.0));
-#endif
- doit=1;
- }
- /* Handle extend */
- else{
- if (strip->flag & ACTSTRIP_HOLDLASTFRAME){
- striptime = 1.0;
+ /* Handle repeat */
+
+ else if (striptime < 1.0){
+ /* Mod to repeat */
+ striptime*=strip->repeat;
+ striptime = (float)fmod (striptime, 1.0);
+
frametime = (striptime * actlength) + strip->actstart;
- get_pose_from_action (&tpose, strip->act, bsystem_time(ob, 0, frametime, 0.0));
-#ifdef __NLA_BLENDCON
+ extract_pose_from_action (tpose, strip->act, bsystem_time(ob, 0, frametime, 0.0));
+ #ifdef __NLA_BLENDCON
do_pose_constraint_channels(tpose, strip->act, bsystem_time(ob, 0, frametime, 0.0));
-#endif
+ #endif
doit=1;
}
- }
+ /* Handle extend */
+ else{
+ if (strip->flag & ACTSTRIP_HOLDLASTFRAME){
+ striptime = 1.0;
+ frametime = (striptime * actlength) + strip->actstart;
+ extract_pose_from_action (tpose, strip->act, bsystem_time(ob, 0, frametime, 0.0));
+ #ifdef __NLA_BLENDCON
+ do_pose_constraint_channels(tpose, strip->act, bsystem_time(ob, 0, frametime, 0.0));
+ #endif
+ doit=1;
+ }
+ }
- /* Handle blendin & blendout */
- if (doit){
- /* Handle blendin */
+ /* Handle blendin & blendout */
+ if (doit){
+ /* Handle blendin */
- if (strip->blendin>0.0 && stripframe<=strip->blendin && G.scene->r.cfra>=strip->start){
- blendfac = stripframe/strip->blendin;
- }
- else if (strip->blendout>0.0 && stripframe>=(length-strip->blendout) && G.scene->r.cfra<=strip->end){
- blendfac = (length-stripframe)/(strip->blendout);
+ if (strip->blendin>0.0 && stripframe<=strip->blendin && G.scene->r.cfra>=strip->start){
+ blendfac = stripframe/strip->blendin;
+ }
+ else if (strip->blendout>0.0 && stripframe>=(length-strip->blendout) && G.scene->r.cfra<=strip->end){
+ blendfac = (length-stripframe)/(strip->blendout);
+ }
+ else
+ blendfac = 1;
+
+ /* Blend this pose with the accumulated pose */
+ blend_poses (apose, tpose, blendfac, strip->mode);
+ #ifdef __NLA_BLENDCON
+ blend_constraints(&apose->chanbase, &tpose->chanbase, blendfac, strip->mode);
+ #endif
}
- else
- blendfac = 1;
-
- /* Blend this pose with the accumulated pose */
- blend_poses (apose, tpose, blendfac, strip->mode);
-#ifdef __NLA_BLENDCON
- blend_constraints(&apose->chanbase, &tpose->chanbase, blendfac, strip->mode);
-#endif
+ }
+ if (apose){
+ extract_pose_from_pose(ob->pose, apose);
+ #ifdef __NLA_BLENDCON
+ get_constraint_influence_from_pose(ob->pose, apose);
+ #endif
}
- }
- if (apose){
- get_pose_from_pose(&ob->pose, apose);
-#ifdef __NLA_BLENDCON
- get_constraint_influence_from_pose(ob->pose, apose);
-#endif
}
+
}
+
+ /* Do local action (always overrides the nla actions) */
+ /* At the moment, only constraint ipos on the local action have any effect */
+ if(ob->action) {
+ extract_pose_from_action (ob->pose, ob->action, bsystem_time(ob, 0, (float) G.scene->r.cfra, 0.0));
+ do_pose_constraint_channels(ob->pose, ob->action, bsystem_time(ob, 0, (float) G.scene->r.cfra, 0.0));
+ doit = 1;
+ }
}
-
- /* Do local action (always overrides the nla actions) */
- /* At the moment, only constraint ipos on the local action have any effect */
- if(ob->action) {
- get_pose_from_action (&ob->pose, ob->action, bsystem_time(ob, 0, (float) G.scene->r.cfra, 0.0));
- do_pose_constraint_channels(ob->pose, ob->action, bsystem_time(ob, 0, (float) G.scene->r.cfra, 0.0));
- doit = 1;
- }
-
- if (doit)
- apply_pose_armature(get_armature(ob), ob->pose, 1);
-
- }
-
+ }
if(only_this) break;
base= base->next;
@@ -608,222 +738,15 @@ void do_all_actions(Object *only_this)
}
if (apose){
- clear_pose(apose);
+ free_pose_channels(apose);
MEM_freeN(apose);
apose = NULL;
}
if (tpose){
- clear_pose(tpose);
+ free_pose_channels(tpose);
MEM_freeN(tpose);
apose = NULL;
}
}
-static void do_pose_constraint_channels(bPose *pose, bAction *act, float ctime)
-{
- bPoseChannel *pchan;
- bActionChannel *achan;
-
- if (!pose || !act)
- return;
-
- for (pchan=pose->chanbase.first; pchan; pchan=pchan->next){
- achan=get_named_actionchannel(act, pchan->name);
- if (achan)
- do_constraint_channels(&pchan->constraints, &achan->constraintChannels, ctime);
- }
-}
-
-bActionChannel *get_named_actionchannel(bAction *act, const char *name)
-{
- bActionChannel *chan;
-
- if (!act)
- return NULL;
-
- for (chan = act->chanbase.first; chan; chan=chan->next){
- if (!strcmp (chan->name, name))
- return chan;
- }
-
- return NULL;
-}
-
-void clear_pose(bPose *pose)
-{
- bPoseChannel *chan;
-
- if (pose->chanbase.first){
- for (chan = pose->chanbase.first; chan; chan=chan->next){
- free_constraints(&chan->constraints);
- }
- BLI_freelistN (&pose->chanbase);
- }
-}
-
-void make_local_action(bAction *act)
-{
- Object *ob;
- bAction *actn;
- int local=0, lib=0;
-
- if(act->id.lib==0) return;
- if(act->id.us==1) {
- act->id.lib= 0;
- act->id.flag= LIB_LOCAL;
- new_id(0, (ID *)act, 0);
- return;
- }
-
- ob= G.main->object.first;
- while(ob) {
- if(ob->action==act) {
- if(ob->id.lib) lib= 1;
- else local= 1;
- }
- ob= ob->id.next;
- }
-
- if(local && lib==0) {
- act->id.lib= 0;
- act->id.flag= LIB_LOCAL;
- new_id(0, (ID *)act, 0);
- }
- else if(local && lib) {
- actn= copy_action(act);
- actn->id.us= 0;
-
- ob= G.main->object.first;
- while(ob) {
- if(ob->action==act) {
-
- if(ob->id.lib==0) {
- ob->action = actn;
- ob->activecon = NULL;
- actn->id.us++;
- act->id.us--;
- }
- }
- ob= ob->id.next;
- }
- }
-}
-
-
-void free_action(bAction *act)
-{
- bActionChannel *chan;
-
- /* Free channels */
- for (chan=act->chanbase.first; chan; chan=chan->next){
- if (chan->ipo)
- chan->ipo->id.us--;
- free_constraint_channels(&chan->constraintChannels);
- }
-
- if (act->chanbase.first)
- BLI_freelistN (&act->chanbase);
-}
-
-bAction* copy_action(bAction *src)
-{
- bAction *dst = NULL;
- bActionChannel *dchan, *schan;
-
- if(!src) return NULL;
-
- dst= copy_libblock(src);
- duplicatelist(&(dst->chanbase), &(src->chanbase));
-
- for (dchan=dst->chanbase.first, schan=src->chanbase.first; dchan; dchan=dchan->next, schan=schan->next){
- dchan->ipo = copy_ipo(dchan->ipo);
- copy_constraint_channels(&dchan->constraintChannels, &schan->constraintChannels);
- }
- dst->id.flag |= LIB_FAKEUSER;
- dst->id.us++;
- return dst;
-}
-
-bPoseChannel *copy_pose_channel(const bPoseChannel* src)
-{
- bPoseChannel *dst;
-
- if (!src)
- return NULL;
-
- dst = MEM_callocN (sizeof(bPoseChannel), "copyPoseChannel");
- memcpy (dst, src, sizeof(bPoseChannel));
- dst->prev=dst->next=NULL;
-
- return dst;
-}
-
-void copy_pose(bPose **dst, bPose *src, int copycon)
-{
- bPose *outPose;
- bPose * inPose;
- bPoseChannel *newChan;
- bPoseChannel *curChan;
-
- inPose = src;
-
- if (!inPose){
- *dst=NULL;
- return;
- }
-
- outPose=MEM_callocN(sizeof(bPose), "pose");
-
- for (curChan=inPose->chanbase.first; curChan; curChan=curChan->next){
- newChan=MEM_callocN(sizeof(bPoseChannel), "copyposePoseChannel");
-
- strcpy (newChan->name, curChan->name);
- newChan->flag=curChan->flag;
-
- memcpy (newChan->loc, curChan->loc, sizeof (curChan->loc));
- memcpy (newChan->size, curChan->size, sizeof (curChan->size));
- memcpy (newChan->quat, curChan->quat, sizeof (curChan->quat));
- Mat4CpyMat4 (newChan->obmat, (void *)curChan->obmat);
-
- BLI_addtail (&outPose->chanbase, newChan);
- if (copycon){
- copy_constraints(&newChan->constraints, &curChan->constraints);
- }
- }
-
- *dst=outPose;
-}
-
-bPoseChannel *set_pose_channel(bPose *pose, bPoseChannel *chan)
-{
- /* chan is no longer valid for the calling function.
- and should not be used by that function after calling
- this one
- */
- bPoseChannel *curChan;
-
- /* Determine if an equivalent channel exists already */
- for (curChan=pose->chanbase.first; curChan; curChan=curChan->next){
- if (!strcmp (curChan->name, chan->name)){
- if (chan->flag & POSE_ROT)
- memcpy (curChan->quat, chan->quat, sizeof(chan->quat));
- if (chan->flag & POSE_SIZE)
- memcpy (curChan->size, chan->size, sizeof(chan->size));
- if (chan->flag & POSE_LOC)
- memcpy (curChan->loc, chan->loc, sizeof(chan->loc));
- if (chan->flag & PCHAN_DONE)
- Mat4CpyMat4 (curChan->obmat, chan->obmat);
-
- curChan->flag |= chan->flag;
- MEM_freeN (chan);
- return curChan;
- }
- }
-
- MEM_freeN (chan);
- return NULL;
- /* If an equivalent channel doesn't exist, then don't bother setting it. */
-}
-
-
diff --git a/source/blender/blenkernel/intern/anim.c b/source/blender/blenkernel/intern/anim.c
index f92294df3d1..9ff8abf0f2a 100644
--- a/source/blender/blenkernel/intern/anim.c
+++ b/source/blender/blenkernel/intern/anim.c
@@ -89,7 +89,7 @@ void calc_curvepath(Object *ob)
/* in a path vertices are with equal differences: path->len = number of verts */
/* NOW WITH BEVELCURVE!!! */
- if(ob==0 || ob->type != OB_CURVE) return;
+ if(ob==NULL || ob->type != OB_CURVE) return;
cu= ob->data;
if(ob==G.obedit) nu= editNurb.first;
else nu= cu->nurb.first;
@@ -98,10 +98,6 @@ void calc_curvepath(Object *ob)
cu->path= NULL;
bl= cu->bev.first;
- if(bl==NULL) {
- makeDispList(ob);
- bl= cu->bev.first;
- }
if(bl==NULL) return;
cu->path=path= MEM_callocN(sizeof(Path), "path");
@@ -213,11 +209,10 @@ int where_on_path(Object *ob, float ctime, float *vec, float *dir) /* returns OK
float data[4];
int cycl=0, s0, s1, s2, s3;
- if(ob==0 || ob->type != OB_CURVE) return 0;
+ if(ob==NULL || ob->type != OB_CURVE) return 0;
cu= ob->data;
- if(cu->path==0 || cu->path->data==0) {
- calc_curvepath(ob);
- if(cu->path==0 || cu->path->data==0) return 0;
+ if(cu->path==NULL || cu->path->data==NULL) {
+ printf("no path!\n");
}
path= cu->path;
fp= path->data;
@@ -242,7 +237,8 @@ int where_on_path(Object *ob, float ctime, float *vec, float *dir) /* returns OK
p2= fp + 4*s2;
p3= fp + 4*s3;
- if(cu->flag & CU_FOLLOW) {
+ /* note, commented out for follow constraint */
+ //if(cu->flag & CU_FOLLOW) {
set_afgeleide_four_ipo(1.0f-fac, data, KEY_BSPLINE);
@@ -254,7 +250,7 @@ int where_on_path(Object *ob, float ctime, float *vec, float *dir) /* returns OK
dir[0]= -dir[0];
dir[1]= -dir[1];
dir[2]= -dir[2];
- }
+ //}
nu= cu->nurb.first;
diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c
index 1f96b48df9b..61122610e50 100644
--- a/source/blender/blenkernel/intern/armature.c
+++ b/source/blender/blenkernel/intern/armature.c
@@ -6,10 +6,7 @@
* 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. The Blender
- * Foundation also sells licenses for use in proprietary software under
- * the Blender License. See http://www.blender.org/BL/ for information
- * about this.
+ * of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -23,9 +20,7 @@
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
+ * Contributor(s): Full recode, Ton Roosendaal, Crete 2005
*
* ***** END GPL/BL DUAL LICENSE BLOCK *****
*/
@@ -50,6 +45,7 @@
#include "DNA_view3d_types.h"
#include "DNA_constraint_types.h"
+#include "BKE_depsgraph.h"
#include "BKE_displist.h"
#include "BKE_global.h"
#include "BKE_main.h"
@@ -71,77 +67,192 @@
#include <config.h>
#endif
-/* Function prototypes */
-
-static void apply_pose_bonechildren (Bone* bone, bPose* pose, int doit);
-static Bone *get_named_bone_bonechildren (Bone *bone, const char *name);
-static Bone *get_indexed_bone_bonechildren (Bone *bone, int *index);
-/*void make_bone_parent_matrix (Bone* bone);*/
-static void copy_bonechildren (Bone* newBone, Bone* oldBone);
-static void calc_armature_deform_bonechildren (Bone *bone, float *vec, float *co, float *contrib, float obmat[][4]);
-static int verify_boneptr_children (Bone *cBone, Bone *tBone);
-static void where_is_bonelist_time (Object *ob, ListBase *base, float ctime);
-static Bone *get_last_ik_bone (Bone *bone);
-static void precalc_bonelist_posemats(ListBase *bonelist, float parlen);
-
-/* Globals */
+/* ugly Globals */
static float g_premat[4][4];
static float g_postmat[4][4];
static MDeformVert *g_dverts;
static ListBase *g_defbase;
-static bArmature *g_defarm;
+static Object *g_deform;
-/* Functions */
+/* **************** Generic Functions, data level *************** */
+
+bArmature *get_armature(Object *ob)
+{
+ if(ob==NULL) return NULL;
+ if(ob->type==OB_ARMATURE) return ob->data;
+ else return NULL;
+}
-float get_bone_length (Bone *bone)
+bArmature *add_armature()
{
- float result[3];
+ bArmature *arm;
+
+ arm= alloc_libblock (&G.main->armature, ID_AR, "Armature");
+ return arm;
+}
- VecSubf (result, bone->tail, bone->head);
- return (float)sqrt(result[0]*result[0] + result[1]*result[1] + result[2]*result[2]);
+void free_boneChildren(Bone *bone)
+{
+ Bone *child;
+
+ if (bone) {
+
+ child=bone->childbase.first;
+ if (child){
+ while (child){
+ free_boneChildren (child);
+ child=child->next;
+ }
+ BLI_freelistN (&bone->childbase);
+ }
+ }
}
-void apply_bonemat(Bone *bone)
+void free_bones (bArmature *arm)
{
- float mat[3][3], imat[3][3], tmat[3][3];
+ Bone *bone;
+ /* Free children (if any) */
+ bone= arm->bonebase.first;
+ if (bone) {
+ while (bone){
+ free_boneChildren (bone);
+ bone=bone->next;
+ }
+ }
+
- if(!bone)
+ BLI_freelistN(&arm->bonebase);
+}
+
+void free_armature(bArmature *arm)
+{
+ if (arm) {
+ /* unlink_armature(arm);*/
+ free_bones(arm);
+ }
+}
+
+void make_local_armature(bArmature *arm)
+{
+ int local=0, lib=0;
+ Object *ob;
+ bArmature *newArm;
+
+ if (arm->id.lib==0)
return;
+ if (arm->id.us==1) {
+ arm->id.lib= 0;
+ arm->id.flag= LIB_LOCAL;
+ new_id(0, (ID*)arm, 0);
+ return;
+ }
+
+ if(local && lib==0) {
+ arm->id.lib= 0;
+ arm->id.flag= LIB_LOCAL;
+ new_id(0, (ID *)arm, 0);
+ }
+ else if(local && lib) {
+ newArm= copy_armature(arm);
+ newArm->id.us= 0;
+
+ ob= G.main->object.first;
+ while(ob) {
+ if(ob->data==arm) {
+
+ if(ob->id.lib==0) {
+ ob->data= newArm;
+ newArm->id.us++;
+ arm->id.us--;
+ }
+ }
+ ob= ob->id.next;
+ }
+ }
+}
- Mat3CpyMat4(mat, bone->obmat);
+static void copy_bonechildren (Bone* newBone, Bone* oldBone)
+{
+ Bone *curBone, *newChildBone;
- VECCOPY(bone->loc, bone->obmat[3]);
+ /* Copy this bone's list*/
+ duplicatelist (&newBone->childbase, &oldBone->childbase);
+
+ /* For each child in the list, update it's children*/
+ newChildBone=newBone->childbase.first;
+ for (curBone=oldBone->childbase.first;curBone;curBone=curBone->next){
+ newChildBone->parent=newBone;
+ copy_bonechildren(newChildBone,curBone);
+ newChildBone=newChildBone->next;
+ }
+}
+
+bArmature *copy_armature(bArmature *arm)
+{
+ bArmature *newArm;
+ Bone *oldBone, *newBone;
+
+ newArm= copy_libblock (arm);
+ duplicatelist(&newArm->bonebase, &arm->bonebase);
+
+ /* Duplicate the childrens' lists*/
+ newBone=newArm->bonebase.first;
+ for (oldBone=arm->bonebase.first;oldBone;oldBone=oldBone->next){
+ newBone->parent=NULL;
+ copy_bonechildren (newBone, oldBone);
+ newBone=newBone->next;
+ };
- Mat3ToQuat(mat, bone->quat);
- QuatToMat3(bone->quat, tmat);
+ return newArm;
+}
- Mat3Inv(imat, tmat);
+static Bone *get_named_bone_bonechildren (Bone *bone, const char *name)
+{
+ Bone *curBone, *rbone;
- Mat3MulMat3(tmat, imat, mat);
+ if (!strcmp (bone->name, name))
+ return bone;
- bone->size[0]= tmat[0][0];
- bone->size[1]= tmat[1][1];
- bone->size[2]= tmat[2][2];
+ for (curBone=bone->childbase.first; curBone; curBone=curBone->next){
+ rbone=get_named_bone_bonechildren (curBone, name);
+ if (rbone)
+ return rbone;
+ }
+
+ return NULL;
+}
+
+Bone *get_named_bone (bArmature *arm, const char *name)
+/*
+ Walk the list until the bone is found
+ */
+{
+ Bone *bone=NULL, *curBone;
+
+ if (!arm) return NULL;
+
+ for (curBone=arm->bonebase.first; curBone; curBone=curBone->next){
+ bone = get_named_bone_bonechildren (curBone, name);
+ if (bone)
+ return bone;
+ }
+
+ return bone;
}
+/* ****************** Game Blender functions, called by engine ************** */
+
void GB_build_mats (float parmat[][4], float obmat[][4], float premat[][4], float postmat[][4])
{
float obinv[4][4];
-#if 0
- Mat4Invert(obinv, obmat);
- Mat4CpyMat4(premat, obmat);
- Mat4MulMat4(postmat, parmat, obinv);
- Mat4Invert (postmat, premat);
-#else
Mat4Invert(obinv, obmat);
Mat4CpyMat4(premat, obmat);
Mat4MulMat4(postmat, parmat, obinv);
Mat4Invert (premat, postmat);
-#endif
}
void GB_init_armature_deform(ListBase *defbase, float premat[][4], float postmat[][4])
@@ -176,7 +287,7 @@ void GB_calc_armature_deform (float *co, MDeformVert *dvert)
for (i=0; i<dvert->totweight; i++){
bone = dvert->dw[i].data;
- if (bone) calc_bone_deform (bone, dvert->dw[i].weight, vec, co, &contrib);
+// if (bone) calc_bone_deform (bone, dvert->dw[i].weight, vec, co, &contrib);
}
if (contrib){
@@ -189,207 +300,13 @@ void GB_calc_armature_deform (float *co, MDeformVert *dvert)
Mat4MulVecfl(g_postmat, co);
}
-static Bone *get_last_ik_bone (Bone *bone)
-{
- Bone *curBone;
-
- for (curBone = bone->childbase.first; curBone; curBone=curBone->next){
- if (curBone->flag & BONE_IK_TOPARENT){
- return get_last_ik_bone (curBone);
- }
- }
-
- return bone;
-}
-
-#if 0
-static Bone *get_first_ik_bone (Bone *bone)
-{
- Bone *curBone;
-
- for (curBone = bone; curBone; curBone=curBone->parent){
- if (!bone->parent)
- return curBone;
- if (!bone->flag & BONE_IK_TOPARENT)
- return curBone;
- }
-
- return bone;
-/* for (curBone = bone->childbase.first; curBone; curBone=curBone->next){
- if (curBone->flag & BONE_IK_TOPARENT){
- return get_last_ik_bone (curBone);
- }
- }
-*/
- return bone;
-
-}
-#endif
-
-void where_is_bone(Object *ob, Bone *bone)
-{
- where_is_bone_time (ob, bone, G.scene->r.cfra);
-}
-
-void where_is_bone_time (Object *ob, Bone *bone, float ctime)
-{
- where_is_bone1_time (ob, get_last_ik_bone(bone), ctime);
-}
-
-void rebuild_bone_parent_matrix (Bone *bone)
-{
- if (!bone)
- return;
-
- if (bone->parent)
- rebuild_bone_parent_matrix(bone->parent);
-
- /* Get the parent inverse */
- if (bone->parent)
- Mat4MulMat4(bone->parmat, bone->parent->obmat, bone->parent->parmat);
- else
- Mat4One (bone->parmat);
-
-}
-void where_is_bone1_time (Object *ob, Bone *bone, float ctime)
-/* Assumes the pose has already been retrieved from the action */
-/* Also assumes where_is_object has been called for owner */
-{
- bPose *pose;
- bPoseChannel *chan;
- bArmature *arm;
- float imat[4][4];
- float totmat[4][4];
- Object conOb;
-
- pose = ob->pose;
- if (!pose)
- return;
-
- arm = get_armature(ob);
-
- /* Ensure there is a channel for this bone*/
- chan = verify_pose_channel (pose, bone->name);
- if (!chan) return;
-
-#if 1
- /* If 1 attempt to use pose caching features */
- /* Bail out if we've been recalced recently */
- if (chan->flag & PCHAN_DONE){
- Mat4CpyMat4 (bone->obmat, chan->obmat);
- if (bone->parent){
- if ((bone->flag & BONE_IK_TOPARENT))
- where_is_bone1_time (ob, bone->parent, ctime);
- else
- where_is_bone_time (ob, bone->parent, ctime);
- }
- return;
- }
- else
- chan->flag |= PCHAN_DONE;
-#endif
-
-#if 1
- /* Ensure parents have been evaluated */
- if (bone->parent){
- if ((bone->flag & BONE_IK_TOPARENT))
- where_is_bone1_time (ob, bone->parent, ctime);
- else
- where_is_bone_time (ob, bone->parent, ctime);
- }
-
-#endif
-
- if (arm){
- if ((arm->flag & ARM_RESTPOS) || ((G.obedit && (ob->data == G.obedit->data)))){
- Mat4One (bone->obmat);
- Mat4One (chan->obmat);
- return;
- }
- }
-
- /* If the bone has been flagged as 'no calc', let's not
- * bother calculating it.
- */
- if (bone->flag & BONE_NOCALC) {
- return;
- }
-
- if (bone->flag & BONE_IK_TOPARENT){
- bone->loc[0]=bone->loc[1]=bone->loc[2]=0.0F;
- }
- bone_to_mat4(bone, bone->obmat);
-
- /* Do constraints */
- // clear_workob();
-
- memset(&conOb, 0, sizeof(Object));
- conOb.size[0]= conOb.size[1]= conOb.size[2]= 1.0;
-
- /* Collect the constraints from the pose */
- conOb.constraints.first = chan->constraints.first;
- conOb.constraints.last = chan->constraints.last;
-
- /* Totmat takes bone's obmat to worldspace */
-
- {
- float parmat[4][4];
- float temp[4][4];
-
- Mat4CpyMat4 (temp, bone->obmat);
- Mat4One (bone->obmat);
- get_objectspace_bone_matrix(bone, parmat, 1, 1);
- Mat4CpyMat4 (bone->obmat, temp);
- Mat4MulMat4 (totmat, parmat, ob->obmat);
- }
-
- /* Build a workob to pass the bone to the constraint solver */
- conOb.data = ob->data;
- conOb.type = ob->type;
- conOb.parent = ob;
- conOb.trackflag = ob->trackflag;
- conOb.upflag = ob->upflag;
-
- VECCOPY(conOb.size, bone->size);
-
- Mat4MulMat4 (conOb.obmat, bone->obmat, totmat);
-
- /* Solve */
- solve_constraints (&conOb, TARGET_BONE, (void*)bone, ctime);
-
- {
- float parmat[4][4];
- float temp[4][4];
-
- Mat4CpyMat4 (temp, bone->obmat);
- Mat4One (bone->obmat);
- get_objectspace_bone_matrix(bone, parmat, 1, 1);
- Mat4CpyMat4 (bone->obmat, temp);
- Mat4MulMat4 (totmat, parmat, ob->obmat);
- }
-
- VECCOPY(bone->size, conOb.size);
-
- /* Take out of worldspace */
- Mat4Invert (imat, totmat);
- Mat4MulMat4 (bone->obmat, conOb.obmat, imat);
- Mat4CpyMat4 (chan->obmat, bone->obmat);
-
-}
-
-
-bArmature *get_armature(Object *ob)
-{
- if(ob==NULL) return NULL;
- if(ob->type==OB_ARMATURE) return ob->data;
- else return NULL;
-}
+/* ****************** END Game Blender functions, called by engine ************** */
+/* ************ Armature Deform ******************* */
void init_armature_deform(Object *parent, Object *ob)
{
bArmature *arm;
bDeformGroup *dg;
- Bone *curBone;
MDeformVert *dvert;
int totverts;
float obinv[4][4];
@@ -399,18 +316,8 @@ void init_armature_deform(Object *parent, Object *ob)
if (!arm)
return;
- if (ob)
- where_is_object (ob);
-
-#if 1
- apply_pose_armature (arm, parent->pose, 1); /* Hopefully doit parameter can be set to 0 in future */
- where_is_armature (parent);
-#else
- apply_pose_armature (arm, parent->pose, 0);
-#endif
-
g_defbase = &ob->defbase;
- g_defarm = arm;
+ g_deform = parent;
Mat4Invert(obinv, ob->obmat);
Mat4CpyMat4(g_premat, ob->obmat);
@@ -428,17 +335,12 @@ void init_armature_deform(Object *parent, Object *ob)
totverts=0;
}
- /* Precalc bone defmats */
- precalc_armature_posemats (arm);
-
- for (curBone=arm->bonebase.first; curBone; curBone=curBone->next){
- precalc_bone_defmat(curBone);
- }
+ /* bone defmats are already in the channels, chan_mat */
- /* Validate bone data in bDeformGroups */
+ /* Validate channel data in bDeformGroups */
for (dg=g_defbase->first; dg; dg=dg->next)
- dg->data = (void*)get_named_bone(arm, dg->name);
+ dg->data = (void*)get_pose_channel(parent->pose, dg->name);
if (g_dverts){
for (j=0; j<totverts; j++){
@@ -456,114 +358,6 @@ void init_armature_deform(Object *parent, Object *ob)
}
}
-void get_bone_root_pos (Bone* bone, float vec[3], int posed)
-{
- Bone *curBone;
- float mat[4][4];
-
- get_objectspace_bone_matrix(bone, mat, 1, posed);
- VECCOPY (vec, mat[3]);
- return;
-
- rebuild_bone_parent_matrix(bone);
- if (posed){
-
- get_objectspace_bone_matrix(bone, mat, 1, posed);
- VECCOPY (vec, mat[3]);
- }
- else {
- vec[0]=vec[1]=vec[2]=0.0F;
- for (curBone=bone; curBone; curBone=curBone->parent){
- if (curBone==bone)
- VecAddf (vec, vec, curBone->head);
- else
- VecAddf (vec, vec, curBone->tail);
- }
- }
-}
-
-void get_bone_tip_pos (Bone* bone, float vec[3], int posed)
-{
- Bone *curBone;
- float mat[4][4], tmat[4][4], rmat[4][4], bmat[4][4], fmat[4][4];
-
- get_objectspace_bone_matrix(bone, mat, 0, posed);
- VECCOPY (vec, mat[3]);
- return;
-
- rebuild_bone_parent_matrix(bone);
- if (posed){
-
- Mat4One (mat);
-
- for (curBone = bone; curBone; curBone=curBone->parent){
- Mat4One (bmat);
- /* [BMAT] This bone's offset */
- VECCOPY (bmat[3], curBone->head);
- if (curBone==bone){
- Mat4One (tmat);
- VecSubf (tmat[3], curBone->tail, curBone->head);
- Mat4MulMat4 (bmat, tmat, curBone->obmat);
- VecAddf (bmat[3], bmat[3], curBone->head);
- }
- else
- VecAddf (bmat[3], bmat[3], curBone->obmat[3]); // Test
-
- /* [RMAT] Parent's bone length = parent rotmat * bone length */
- if (curBone->parent){
- Mat4One (tmat);
- VecSubf (tmat[3], curBone->parent->tail, curBone->parent->head);
- Mat4MulMat4 (rmat, tmat, curBone->parent->obmat);
- VecSubf (rmat[3], rmat[3], curBone->parent->obmat[3]);
- }
- else
- Mat4One (rmat);
-
- Mat4MulSerie (fmat, rmat, bmat, mat, 0, 0, 0, 0, 0);
- Mat4CpyMat4 (mat, fmat);
- }
-
- VECCOPY (vec, mat[3]);
- }
- else{
- vec[0]=vec[1]=vec[2]=0.0F;
- for (curBone=bone; curBone; curBone=curBone->parent){
- VecAddf (vec, vec, curBone->tail);
- }
- }
-}
-
-int verify_boneptr (bArmature *arm, Bone *bone)
-{
- /* Ensures that a given bone exists in an armature */
- Bone *curBone;
-
- if (!arm)
- return 0;
-
- for (curBone=arm->bonebase.first; curBone; curBone=curBone->next){
- if (verify_boneptr_children (curBone, bone))
- return 1;
- }
-
- return 0;
-}
-
-static int verify_boneptr_children (Bone *cBone, Bone *tBone)
-{
- Bone *curBone;
-
- if (cBone == tBone)
- return 1;
-
- for (curBone=cBone->childbase.first; curBone; curBone=curBone->next){
- if (verify_boneptr_children (curBone, tBone))
- return 1;
- }
- return 0;
-}
-
-
float dist_to_bone (float vec[3], float b1[3], float b2[3])
{
/* float dist=0; */
@@ -592,137 +386,41 @@ float dist_to_bone (float vec[3], float b1[3], float b2[3])
else {
return (hsqr - (a*a));
}
-
-
}
-static void calc_armature_deform_bonechildren (Bone *bone, float *vec, float *co, float *contrib, float obmat[][4])
+static float calc_armature_deform_bone(Bone *bone, bPoseChannel *pchan, float *vec, float *co)
{
- Bone *curBone;
- float root[3];
- float tip[3];
float dist, fac, ifac;
float cop[3];
- float bdsqr;
-
-
- get_bone_root_pos (bone, root, 0);
- get_bone_tip_pos (bone, tip, 0);
+ float bdsqr, contrib=0.0;
bdsqr = bone->dist*bone->dist;
VECCOPY (cop, co);
- dist = dist_to_bone(cop, root, tip);
+ dist = dist_to_bone(cop, bone->arm_head, bone->arm_tail);
if ((dist) <= bdsqr){
fac = (dist)/bdsqr;
ifac = 1.0F-fac;
ifac*=bone->weight;
-
- if (!vec)
- (*contrib) +=ifac;
- else{
- ifac*=(1.0F/(*contrib));
+ contrib= ifac;
+ if(contrib>0.0) {
VECCOPY (cop, co);
- Mat4MulVecfl(bone->defmat, cop);
+ Mat4MulVecfl(pchan->chan_mat, cop);
VecSubf (cop, cop, co); // Make this a delta from the base position
cop[0]*=ifac; cop[1]*=ifac; cop[2]*=ifac;
VecAddf (vec, vec, cop);
-
- }
- }
-
-// calc_bone_deform (bone, bone->weight, vec, co, contrib, obmat);
- for (curBone = bone->childbase.first; curBone; curBone=curBone->next)
- calc_armature_deform_bonechildren (curBone, vec, co, contrib, obmat);
-}
-
-void precalc_bone_irestmat (Bone *bone)
-{
- float restmat[4][4];
-
- get_objectspace_bone_matrix(bone, restmat, 1, 0);
- Mat4Invert (bone->irestmat, restmat);
-}
-
-static void precalc_bonelist_posemats(ListBase *bonelist, float parlen)
-{
- Bone *curBone;
- float length;
- float T_parlen[4][4];
- float T_root[4][4];
- float M_obmat[4][4];
- float R_bmat[4][4];
- float M_accumulatedMatrix[4][4];
- float delta[3];
-
- for (curBone = bonelist->first; curBone; curBone=curBone->next){
-
- /* Get the length translation (length along y axis) */
- length = get_bone_length(curBone);
-
- /* Get the bone's root offset (in the parent's coordinate system) */
- Mat4One (T_root);
- VECCOPY (T_root[3], curBone->head);
-
- /* Compose the restmat */
- VecSubf(delta, curBone->tail, curBone->head);
- make_boneMatrixvr(R_bmat, delta, curBone->roll);
-
- /* Retrieve the obmat (user transformation) */
- Mat4CpyMat4 (M_obmat, curBone->obmat);
-
- /* Compose the accumulated matrix (i.e. parent matrix * parent translation ) */
- if (curBone->parent){
- Mat4One (T_parlen);
- T_parlen[3][1] = parlen;
- Mat4MulMat4 (M_accumulatedMatrix, T_parlen, curBone->parent->posemat);
}
- else
- Mat4One (M_accumulatedMatrix);
-
- /* Compose the matrix for this bone */
- Mat4MulSerie (curBone->posemat, M_accumulatedMatrix, T_root, R_bmat, M_obmat, NULL, NULL, NULL, NULL);
-
- precalc_bonelist_posemats(&curBone->childbase, length);
}
-}
-
-void precalc_armature_posemats (bArmature *arm)
-{
- precalc_bonelist_posemats(&arm->bonebase, 0.0);
-}
-
-void precalc_bone_defmat (Bone *bone)
-{
- Bone *curBone;
-#if 0
- float restmat[4][4];
- float posemat[4][4];
- float imat[4][4];
- /* Store restmat and restmat inverse - Calculate once when leaving editmode */
- /* Store all bones' posemats - Do when applied */
-
- /* EXPENSIVE! Don't do this! */
- get_objectspace_bone_matrix(bone, restmat, 1, 0);
- get_objectspace_bone_matrix(bone, posemat, 1, 1);
- Mat4Invert (imat, restmat);
- Mat4MulMat4 (bone->defmat, imat, posemat);
- /* /EXPENSIVE */
-#else
- Mat4MulMat4 (bone->defmat, bone->irestmat, bone->posemat);
-#endif
- for (curBone = bone->childbase.first; curBone; curBone=curBone->next){
- precalc_bone_defmat(curBone);
- }
+ return contrib;
}
-void calc_bone_deform (Bone *bone, float weight, float *vec, float *co, float *contrib)
+void calc_bone_deform (bPoseChannel *pchan, float weight, float *vec, float *co, float *contrib)
{
float cop[3];
@@ -731,7 +429,7 @@ void calc_bone_deform (Bone *bone, float weight, float *vec, float *co, float *c
VECCOPY (cop, co);
- Mat4MulVecfl(bone->defmat, cop);
+ Mat4MulVecfl(pchan->chan_mat, cop);
vec[0]+=(cop[0]-co[0])*weight;
vec[1]+=(cop[1]-co[1])*weight;
@@ -742,540 +440,638 @@ void calc_bone_deform (Bone *bone, float weight, float *vec, float *co, float *c
void calc_armature_deform (Object *ob, float *co, int index)
{
- bArmature *arm;
- Bone *bone;
- Bone *curBone;
+ bPoseChannel *pchan;
+ MDeformVert *dvert = g_dverts+index;
float vec[3];
- float contrib=0;
+ float contrib=0.0;
int i;
- MDeformVert *dvert = g_dverts+index;
- arm=g_defarm;
vec[0]=vec[1]=vec[2]=0;
/* Apply the object's matrix */
Mat4MulVecfl(g_premat, co);
+ /* using deform vertex groups */
if (g_dverts){
+
for (i=0; i<dvert->totweight; i++){
- bone = dvert->dw[i].data;
- if (bone) calc_bone_deform (bone, dvert->dw[i].weight, vec, co, &contrib);
+ pchan = (bPoseChannel *)dvert->dw[i].data;
+ if (pchan) calc_bone_deform (pchan, dvert->dw[i].weight, vec, co, &contrib);
}
+ }
+ else { /* or use bone distances */
+ Bone *bone;
- if (contrib){
- vec[0]/=contrib;
- vec[1]/=contrib;
- vec[2]/=contrib;
+ for(pchan= g_deform->pose->chanbase.first; pchan; pchan= pchan->next) {
+ bone= pchan->bone;
+ if(bone) {
+ contrib+= calc_armature_deform_bone(bone, pchan, vec, co);
+ }
}
- VecAddf (co, vec, co);
- Mat4MulVecfl(g_postmat, co);
- return;
- }
-
- // Count the number of interested bones
- for (curBone = arm->bonebase.first; curBone; curBone=curBone->next)
- calc_armature_deform_bonechildren (curBone, NULL, co, &contrib, ob->obmat);
-
- // Do the deformation
- for (curBone = arm->bonebase.first; curBone; curBone=curBone->next)
- calc_armature_deform_bonechildren (curBone, vec, co, &contrib, ob->obmat);
+ }
+ if (contrib>0.0){
+ vec[0]/=contrib;
+ vec[1]/=contrib;
+ vec[2]/=contrib;
+ }
VecAddf (co, vec, co);
Mat4MulVecfl(g_postmat, co);
}
-void apply_pose_armature (bArmature* arm, bPose* pose, int doit)
-{
- Bone *curBone;
- for (curBone = arm->bonebase.first; curBone; curBone=curBone->next){
- apply_pose_bonechildren (curBone, pose, doit);
- }
-}
+/* ************ END Armature Deform ******************* */
-void where_is_armature (Object *ob)
+void get_objectspace_bone_matrix (struct Bone* bone, float M_accumulatedMatrix[][4], int root, int posed)
{
- where_is_object (ob);
- where_is_armature_time(ob, (float)G.scene->r.cfra);
+ Mat4CpyMat4(M_accumulatedMatrix, bone->arm_mat);
}
-void where_is_armature_time (Object *ob, float ctime)
+#if 0
+/* IK in the sense of; connected directly */
+static Bone *get_last_ik_bone (Bone *bone)
{
- bArmature *arm;
-
- arm = get_armature(ob);
- if (!arm)
- return;
+ Bone *curBone;
+
+ for (curBone = bone->childbase.first; curBone; curBone=curBone->next){
+ if (curBone->flag & BONE_IK_TOPARENT){
+ return get_last_ik_bone (curBone);
+ }
+ }
+
+ return bone;
+}
- where_is_bonelist_time (ob, &arm->bonebase, ctime);
+#endif
-}
+/* **************** The new & simple (but OK!) armature evaluation ********* */
-static void where_is_bonelist_time (Object *ob, ListBase *base, float ctime)
-{
- Bone *curBone;
+/* ****************** And how it works! ****************************************
- for (curBone=base->first; curBone; curBone=curBone->next){
- if (!curBone->childbase.first)
- where_is_bone1_time (ob, curBone, ctime);
+ This is the bone transformation trick; they're hierarchical so each bone(b)
+ is in the coord system of bone(b-1):
- where_is_bonelist_time(ob, &curBone->childbase, ctime);
- }
-}
-static void apply_pose_bonechildren (Bone* bone, bPose* pose, int doit)
-{
- Bone *curBone;
- bPoseChannel *chan;
+ 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
- if (!pose){
-
- bone->dsize[0]=bone->dsize[1]=bone->dsize[2]=1.0F;
- bone->size[0]=bone->size[1]=bone->size[2]=1.0F;
+ pose_mat(b)= pose_mat(b-1) * yoffs(b-1) * d_root(b) * bone_mat(b) * chan_mat(b)
- bone->dquat[0]=bone->dquat[1]=bone->dquat[2]=bone->dquat[3]=0;
- bone->quat[0]=bone->quat[1]=bone->quat[2]=bone->quat[3]=0.0F;
-
- bone->dloc[0]=bone->dloc[1]=bone->dloc[2]=0.0F;
- bone->loc[0]=bone->loc[1]=bone->loc[2]=0.0F;
- }
+ we then - in init deform - store the deform in chan_mat, such that:
- // Ensure there is a channel for this bone
- chan = verify_pose_channel (pose, bone->name);
+ pose_mat(b)= arm_mat(b) * chan_mat(b)
+
+ *************************************************************************** */
- /* Only do this crazy stuff if the no calc flag
- * is cleared for this bone.
- */
- if (chan && (~bone->flag & BONE_NOCALC)) {
- if (chan->flag & POSE_LOC)
- memcpy (bone->loc, chan->loc, sizeof (bone->loc));
- if (chan->flag & POSE_SIZE)
- memcpy (bone->size, chan->size, sizeof (bone->size));
- if (chan->flag & POSE_ROT)
- memcpy (bone->quat, chan->quat, sizeof (bone->quat));
-
- if (doit){
- bone_to_mat4(bone, bone->obmat);
- }
- else{
- Mat4CpyMat4 (bone->obmat, chan->obmat);
- }
- }
-
- for (curBone = bone->childbase.first; curBone; curBone=curBone->next){
- apply_pose_bonechildren (curBone, pose, doit);
- }
-}
-void make_boneMatrixvr (float outmatrix[][4],float delta[3], float roll)
/* Calculates the rest matrix of a bone based
On its vector and a roll around that vector */
+void vec_roll_to_mat3(float *vec, float roll, float mat[][3])
{
- float nor[3],axis[3],target[3]={0,1,0};
+ float nor[3], axis[3], target[3]={0,1,0};
float theta;
- float rMatrix[3][3], bMatrix[3][3], fMatrix[3][3];
-
- VECCOPY (nor,delta);
+ float rMatrix[3][3], bMatrix[3][3];
+
+ VECCOPY (nor, vec);
Normalise (nor);
-
+
/* Find Axis & Amount for bone matrix*/
Crossf (axis,target,nor);
-
+
if (Inpf(axis,axis) > 0.0000000000001) {
/* if nor is *not* a multiple of target ... */
Normalise (axis);
theta=(float) acos (Inpf (target,nor));
-
+
/* Make Bone matrix*/
VecRotToMat3(axis, theta, bMatrix);
}
else {
/* if nor is a multiple of target ... */
float updown;
-
+
/* point same direction, or opposite? */
updown = ( Inpf (target,nor) > 0 ) ? 1.0 : -1.0;
-
+
/* I think this should work ... */
bMatrix[0][0]=updown; bMatrix[0][1]=0.0; bMatrix[0][2]=0.0;
bMatrix[1][0]=0.0; bMatrix[1][1]=updown; bMatrix[1][2]=0.0;
bMatrix[2][0]=0.0; bMatrix[2][1]=0.0; bMatrix[2][2]=1.0;
}
-
+
/* Make Roll matrix*/
VecRotToMat3(nor, roll, rMatrix);
/* Combine and output result*/
- Mat3MulMat3 (fMatrix,rMatrix,bMatrix);
- Mat4CpyMat3 (outmatrix,fMatrix);
+ Mat3MulMat3 (mat, rMatrix, bMatrix);
}
-void make_boneMatrix (float outmatrix[][4], Bone *bone)
-/* Calculates the rest matrix of a bone based
- On its vector and a roll around that vector */
+
+/* recursive part, calculates restposition of entire tree of children */
+/* used by exiting editmode too */
+void where_is_armature_bone(Bone *bone, Bone *prevbone)
{
- float delta[3];
- float parmat[4][4], imat[4][4], obmat[4][4];
+ float vec[3];
+
+ /* Bone Space */
+ VecSubf (vec, bone->tail, bone->head);
+ vec_roll_to_mat3(vec, bone->roll, bone->bone_mat);
- if (bone->parent){
- VecSubf (delta, bone->parent->tail, bone->parent->head);
- make_boneMatrixvr(parmat, delta, bone->parent->roll);
+ bone->length= VecLenf(bone->head, bone->tail);
+
+ if(prevbone) {
+ float offs_bone[4][4]; // yoffs(b-1) + root(b) + bonemat(b)
+
+ /* bone transform itself */
+ Mat4CpyMat3(offs_bone, bone->bone_mat);
+
+ /* The bone's root offset (is in the parent's coordinate system) */
+ VECCOPY(offs_bone[3], bone->head);
+
+ /* Get the length translation of parent (length along y axis) */
+ offs_bone[3][1]+= prevbone->length;
+
+ /* Compose the matrix for this bone */
+ Mat4MulMat4(bone->arm_mat, offs_bone, prevbone->arm_mat);
}
- else{
- Mat4One (parmat);
+ else {
+ Mat4CpyMat3(bone->arm_mat, bone->bone_mat);
+ VECCOPY(bone->arm_mat[3], bone->head);
}
-
- Mat4Invert (imat, parmat);
- VecSubf (delta, bone->tail, bone->head);
- make_boneMatrixvr(obmat, delta, bone->roll);
-
- Mat4MulMat4(outmatrix, obmat, imat);
-
+ /* head */
+ VECCOPY(bone->arm_head, bone->arm_mat[3]);
+ /* tail is in current local coord system */
+ VECCOPY(vec, bone->arm_mat[1]);
+ VecMulf(vec, bone->length);
+ VecAddf(bone->arm_tail, bone->arm_head, vec);
+
+ /* and the kiddies */
+ prevbone= bone;
+ for(bone= bone->childbase.first; bone; bone= bone->next) {
+ where_is_armature_bone(bone, prevbone);
+ }
}
-
-bArmature *add_armature()
+/* updates vectors and matrices on rest-position level, only needed
+ after editing armature itself, now only on reading file */
+void where_is_armature (bArmature *arm)
{
- bArmature *arm;
-
- arm= alloc_libblock (&G.main->armature, ID_AR, "Armature");
-
- if(arm) {
-
+ Bone *bone;
+ /* hierarchical from root to children */
+ for(bone= arm->bonebase.first; bone; bone= bone->next) {
+ where_is_armature_bone(bone, NULL);
}
- return arm;
}
+static int rebuild_pose_bone(bPose *pose, Bone *bone, bPoseChannel *parchan, int depth, int counter)
+{
+ bPoseChannel *pchan = verify_pose_channel (pose, bone->name); // verify checks and/or adds
-void free_boneChildren(Bone *bone)
-{
- Bone *child;
-
- if (bone) {
-
- child=bone->childbase.first;
- if (child){
- while (child){
- free_boneChildren (child);
- child=child->next;
- }
- BLI_freelistN (&bone->childbase);
- }
+ pchan->bone= bone;
+ pchan->parent= parchan;
+ pchan->depth= depth;
+ counter++;
+
+ for(bone= bone->childbase.first; bone; bone= bone->next) {
+ counter= rebuild_pose_bone(pose, bone, pchan, depth+1, counter);
}
+
+ return counter;
}
-void free_bones (bArmature *arm)
+/* only after leave editmode, but also for validating older files */
+/* NOTE: pose->flag is set for it */
+void armature_rebuild_pose(Object *ob, bArmature *arm)
{
Bone *bone;
- /* Free children (if any) */
- bone= arm->bonebase.first;
- if (bone) {
- while (bone){
- free_boneChildren (bone);
- bone=bone->next;
+ bPose *pose;
+ bPoseChannel *pchan, *next;
+ int counter=0;
+
+ /* only done here */
+ if(ob->pose==NULL) ob->pose= MEM_callocN(sizeof(bPose), "new pose");
+ pose= ob->pose;
+
+ /* first step, check if all channels are there, also sets depth */
+ for(bone= arm->bonebase.first; bone; bone= bone->next) {
+ counter= rebuild_pose_bone(pose, bone, NULL, 0, counter);
+ }
+ /* sort channels on dependency order, so we can walk the channel list */
+
+ /* and a check for garbage */
+ for(pchan= pose->chanbase.first; pchan; pchan= next) {
+ next= pchan->next;
+ if(pchan->bone==NULL) {
+ BLI_freelinkN(&pose->chanbase, pchan); // constraints?
}
}
+ //printf("rebuild pose, %d bones\n", counter);
+ if(counter<2) return;
+ update_pose_constraint_flags(ob->pose); // for IK detection for example
- BLI_freelistN(&arm->bonebase);
+ /* the sorting */
+ DAG_pose_sort(ob);
+
+ ob->pose->flag &= ~POSE_RECALC;
}
-void free_armature(bArmature *arm)
-{
- if (arm) {
-/* unlink_armature(arm);*/
- free_bones(arm);
- }
-}
-void make_local_armature(bArmature *arm)
-{
- int local=0, lib=0;
- Object *ob;
- bArmature *newArm;
+/* ********************** THE IK SOLVER ******************* */
- if (arm->id.lib==0)
- return;
- if (arm->id.us==1) {
- arm->id.lib= 0;
- arm->id.flag= LIB_LOCAL;
- new_id(0, (ID*)arm, 0);
- return;
- }
- if(local && lib==0) {
- arm->id.lib= 0;
- arm->id.flag= LIB_LOCAL;
- new_id(0, (ID *)arm, 0);
+/* allocates PoseChain, and links that to root bone/channel */
+/* note; if we got this working, it can become static too? */
+static void initialize_posechain(struct Object *ob, bPoseChannel *pchan_tip)
+{
+ bPoseChannel *curchan, *pchan_root=NULL, *chanlist[256];
+ PoseChain *chain;
+ bConstraint *con;
+ bKinematicConstraint *data;
+ int a, segcount= 0;
+
+ /* find IK constraint, and validate it */
+ for(con= pchan_tip->constraints.first; con; con= con->next) {
+ if(con->type==CONSTRAINT_TYPE_KINEMATIC) break;
}
- else if(local && lib) {
- newArm= copy_armature(arm);
- newArm->id.us= 0;
-
- ob= G.main->object.first;
- while(ob) {
- if(ob->data==arm) {
-
- if(ob->id.lib==0) {
- ob->data= newArm;
- newArm->id.us++;
- arm->id.us--;
- }
- }
- ob= ob->id.next;
+ if(con==NULL) return;
+ if(con->flag & CONSTRAINT_DISABLE) return; // not sure...
+
+ data=(bKinematicConstraint*)con->data;
+ if(data->tar==NULL) return;
+
+ /* Find the chain's root & count the segments needed */
+ for (curchan = pchan_tip; curchan; curchan=curchan->parent){
+ pchan_root = curchan;
+ /* tip is not in the chain */
+ if (curchan!=pchan_tip){
+ chanlist[segcount]=curchan;
+ segcount++;
}
+ if(segcount>255) break; // also weak
+
+ if (!(curchan->bone->flag & BONE_IK_TOPARENT))
+ break;
+ }
+ if (!segcount) return;
+
+ /* setup the chain data */
+ chain = MEM_callocN(sizeof(PoseChain), "posechain");
+ chain->totchannel= segcount;
+ chain->solver = IK_CreateChain();
+ chain->con= con;
+
+ chain->iterations = data->iterations;
+ chain->tolerance = data->tolerance;
+
+ chain->pchanchain= MEM_callocN(segcount*sizeof(void *), "channel chain");
+ for(a=0; a<segcount; a++) {
+ chain->pchanchain[a]= chanlist[segcount-a-1];
}
+
+ /* AND! link the chain to the root */
+ BLI_addtail(&pchan_root->chain, chain);
}
-static void copy_bonechildren (Bone* newBone, Bone* oldBone)
+/* called from within the core where_is_pose loop, all animsystems and constraints
+were executed & assigned. Now as last we do an IK pass */
+static void execute_posechain(Object *ob, PoseChain *chain)
{
- Bone *curBone, *newChildBone;
-
- /* Copy this bone's list*/
- duplicatelist (&newBone->childbase, &oldBone->childbase);
-
- /* For each child in the list, update it's children*/
- newChildBone=newBone->childbase.first;
- for (curBone=oldBone->childbase.first;curBone;curBone=curBone->next){
- newChildBone->parent=newBone;
- copy_bonechildren(newChildBone,curBone);
- newChildBone=newChildBone->next;
+ IK_Segment_Extern *segs;
+ bPoseChannel *pchan;
+ float R_parmat[3][3];
+ float iR_parmat[3][3];
+ float R_bonemat[3][3];
+ float rootmat[4][4], imat[4][4];
+ float size[3];
+ int curseg;
+
+ /* first set the goal inverse transform, assuming the root of chain was done ok! */
+ pchan= chain->pchanchain[0];
+ Mat4One(rootmat);
+ VECCOPY(rootmat[3], pchan->pose_head);
+
+ Mat4MulMat4 (imat, rootmat, ob->obmat);
+ Mat4Invert (chain->goalinv, imat);
+
+ /* and set and transform goal */
+ get_constraint_target_matrix(chain->con, TARGET_BONE, NULL, rootmat, size, 1.0); // 1.0=ctime
+ VECCOPY (chain->goal, rootmat[3]);
+ Mat4MulVecfl (chain->goalinv, chain->goal);
+
+ /* Now we construct the IK segments */
+ segs = MEM_callocN (sizeof(IK_Segment_Extern)*chain->totchannel, "iksegments");
+
+ for (curseg=0; curseg<chain->totchannel; curseg++){
+
+ pchan= chain->pchanchain[curseg];
+
+ /* Get the matrix that transforms from prevbone into this bone */
+ Mat3CpyMat4(R_bonemat, pchan->pose_mat);
+
+ if (pchan->parent && (pchan->bone->flag & BONE_IK_TOPARENT)) {
+ Mat3CpyMat4(R_parmat, pchan->parent->pose_mat);
+ }
+ else
+ Mat3One (R_parmat);
+
+ Mat3Inv(iR_parmat, R_parmat);
+
+ /* Mult and Copy the matrix into the basis and transpose (IK lib likes it) */
+ Mat3MulMat3((void *)segs[curseg].basis, iR_parmat, R_bonemat);
+ Mat3Transp((void *)segs[curseg].basis);
+
+ /* Fill out the IK segment */
+ segs[curseg].length = pchan->bone->length;
}
+
+ /* Solve the chain */
+
+ IK_LoadChain(chain->solver, segs, chain->totchannel);
+
+ IK_SolveChain(chain->solver, chain->goal, chain->tolerance,
+ chain->iterations, 0.1f, chain->solver->segments);
+
+
+ /* not yet free! */
}
-bArmature *copy_armature(bArmature *arm)
-{
- bArmature *newArm;
- Bone *oldBone, *newBone;
- newArm= copy_libblock (arm);
- duplicatelist(&newArm->bonebase, &arm->bonebase);
+/* ********************** THE POSE SOLVER ******************* */
- /* Duplicate the childrens' lists*/
- newBone=newArm->bonebase.first;
- for (oldBone=arm->bonebase.first;oldBone;oldBone=oldBone->next){
- newBone->parent=NULL;
- copy_bonechildren (newBone, oldBone);
- newBone=newBone->next;
- };
- return newArm;
-}
-
-
-void bone_to_mat3(Bone *bone, float mat[][3]) /* no parent */
+/* loc/rot/size to mat4 */
+static void chan_calc_mat(bPoseChannel *chan)
{
float smat[3][3];
float rmat[3][3];
-/* float q1[4], vec[3];*/
-
- /* size */
-/* if(bone->ipo) {
- vec[0]= bone->size[0]+bone->dsize[0];
- vec[1]= bone->size[1]+bone->dsize[1];
- vec[2]= bone->size[2]+bone->dsize[2];
- SizeToMat3(vec, smat);
- }
- else
-*/ {
- SizeToMat3(bone->size, smat);
- }
-
- /* rot */
- /*if(bone->flag & BONE_QUATROT) {
- if(bone->ipo) {
- QuatMul(q1, bone->quat, bone->dquat);
- QuatToMat3(q1, rmat);
- }
- else
- */ {
- NormalQuat(bone->quat);
- QuatToMat3(bone->quat, rmat);
- }
-/* }
-*/
- Mat3MulMat3(mat, rmat, smat);
-}
-
-void bone_to_mat4(Bone *bone, float mat[][4])
-{
float tmat[3][3];
- bone_to_mat3(bone, tmat);
+ SizeToMat3(chan->size, smat);
+
+ NormalQuat(chan->quat);
+ QuatToMat3(chan->quat, rmat);
- Mat4CpyMat3(mat, tmat);
+ Mat3MulMat3(tmat, rmat, smat);
- VECCOPY(mat[3], bone->loc);
-// VecAddf(mat[3], mat[3], bone->loc);
-/* if(bone->ipo) {
- mat[3][0]+= bone->dloc[0];
- mat[3][1]+= bone->dloc[1];
- mat[3][2]+= bone->dloc[2];
+ Mat4CpyMat3(chan->chan_mat, tmat);
+
+ /* prevent action channels breaking chains */
+ if (!(chan->bone->flag & BONE_IK_TOPARENT)) {
+ VECCOPY(chan->chan_mat[3], chan->loc);
}
-*/
+
}
-Bone *get_indexed_bone (bArmature *arm, int index)
-/*
- Walk the list until the index is reached
-*/
+/* transform from bone(b) to bone(b+1), store in chan_mat */
+static void make_dmats(bPoseChannel *pchan)
{
- Bone *bone=NULL, *curBone;
- int ref=index;
-
- if (!arm)
- return NULL;
-
- for (curBone=arm->bonebase.first; curBone; curBone=curBone->next){
- bone = get_indexed_bone_bonechildren (curBone, &ref);
- if (bone)
- return bone;
+ if (pchan->parent) {
+ float iR_parmat[4][4];
+ Mat4Invert(iR_parmat, pchan->parent->pose_mat);
+ Mat4MulMat4(pchan->chan_mat, pchan->pose_mat, iR_parmat); // delta mat
}
-
- return bone;
+ else Mat4CpyMat4(pchan->chan_mat, pchan->pose_mat);
}
-Bone *get_named_bone (bArmature *arm, const char *name)
-/*
- Walk the list until the bone is found
-*/
+/* applies IK matrix to pchan, IK is done separated */
+/* formula: pose_mat(b) = pose_mat(b-1) * diffmat(b-1, b) * ik_mat(b) */
+/* to make this work, the diffmats have to be precalculated! Stored in chan_mat */
+static void where_is_ik_bone(bPoseChannel *pchan, float ik_mat[][3]) // nr = to detect if this is first bone
{
- Bone *bone=NULL, *curBone;
-
- if (!arm) return NULL;
+ float vec[3], ikmat[4][4];
+
+ Mat4CpyMat3(ikmat, ik_mat);
+
+ if (pchan->parent)
+ Mat4MulSerie(pchan->pose_mat, pchan->parent->pose_mat, pchan->chan_mat, ikmat, NULL, NULL, NULL, NULL, NULL);
+ else
+ Mat4MulMat4(pchan->pose_mat, ikmat, pchan->chan_mat);
- for (curBone=arm->bonebase.first; curBone; curBone=curBone->next){
- bone = get_named_bone_bonechildren (curBone, name);
- if (bone)
- return bone;
- }
+ /* calculate head */
+ VECCOPY(pchan->pose_head, pchan->pose_mat[3]);
+ /* calculate tail */
+ VECCOPY(vec, pchan->pose_mat[1]);
+ VecMulf(vec, pchan->bone->length);
+ VecAddf(pchan->pose_tail, pchan->pose_head, vec);
- return bone;
+ pchan->flag |= POSE_DONE;
}
-static Bone *get_indexed_bone_bonechildren (Bone *bone, int *index)
+/* The main armature solver, does all constraints excluding IK */
+/* pchan is validated, as having bone and parent pointer */
+static void where_is_pose_bone(Object *ob, bPoseChannel *pchan)
{
- Bone *curBone, *rbone;
-
- if (!*index)
- return bone;
-
- (*index)--;
-
- for (curBone=bone->childbase.first; curBone; curBone=curBone->next){
- rbone=get_indexed_bone_bonechildren (curBone, index);
- if (rbone)
- return rbone;
+ Bone *bone, *parbone;
+ bPoseChannel *parchan;
+ float vec[3], ctime= 1.0; // ctime todo
+
+ /* set up variables for quicker access below */
+ bone= pchan->bone;
+ parbone= bone->parent;
+ parchan= pchan->parent;
+
+ /* this gives a chan_mat with actions (ipos) results */
+ chan_calc_mat(pchan);
+
+ /* 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) */
+
+ if(parchan) {
+ float offs_bone[4][4]; // yoffs(b-1) + root(b) + bonemat(b)
+
+ /* bone transform itself */
+ Mat4CpyMat3(offs_bone, bone->bone_mat);
+
+ /* The bone's root offset (is in the parent's coordinate system) */
+ VECCOPY(offs_bone[3], bone->head);
+
+ /* Get the length translation of parent (length along y axis) */
+ offs_bone[3][1]+= parbone->length;
+
+ /* Compose the matrix for this bone */
+ Mat4MulSerie(pchan->pose_mat, parchan->pose_mat, offs_bone, pchan->chan_mat, NULL, NULL, NULL, NULL, NULL);
}
-
- return NULL;
+ else
+ Mat4MulMat4(pchan->pose_mat, pchan->chan_mat, bone->arm_mat);
+
+
+ /* Do constraints */
+ if(pchan->constraints.first) {
+ static Object conOb;
+ static int initialized= 0;
+
+ /* Build a workob to pass the bone to the constraint solver */
+ if(initialized==0) {
+ memset(&conOb, 0, sizeof(Object));
+ initialized= 1;
+ }
+ conOb.size[0]= conOb.size[1]= conOb.size[2]= 1.0;
+ conOb.data = ob->data;
+ conOb.type = ob->type;
+ conOb.parent = ob; // ik solver retrieves the armature that way !?!?!?!
+ conOb.pose= ob->pose; // needed for retrieving pchan
+ conOb.trackflag = ob->trackflag;
+ conOb.upflag = ob->upflag;
+
+ /* Collect the constraints from the pose (listbase copy) */
+ conOb.constraints = pchan->constraints;
+
+ /* conOb.obmat takes bone to worldspace */
+ Mat4MulMat4 (conOb.obmat, pchan->pose_mat, ob->obmat);
+
+ //VECCOPY(conOb.size, pchan->size); // stretchto constraint
+
+ /* Solve */
+ solve_constraints (&conOb, TARGET_BONE, (void*)bone, ctime); // ctime doesnt alter objects
+
+ //VECCOPY(bone->size, conOb.size); // stretchto constraint
+
+ /* Take out of worldspace */
+ Mat4MulMat4 (pchan->pose_mat, conOb.obmat, ob->imat);
+ }
+
+ /* calculate head */
+ VECCOPY(pchan->pose_head, pchan->pose_mat[3]);
+ /* calculate tail */
+ VECCOPY(vec, pchan->pose_mat[1]);
+ VecMulf(vec, bone->length);
+ VecAddf(pchan->pose_tail, pchan->pose_head, vec);
+
}
-static Bone *get_named_bone_bonechildren (Bone *bone, const char *name)
+/* This only reads anim data from channels, and writes to channels */
+/* This is the only function adding poses */
+void where_is_pose (Object *ob)
{
- Bone *curBone, *rbone;
-
- if (!strcmp (bone->name, name))
- return bone;
+ bArmature *arm;
+ Bone *bone;
+ bPoseChannel *pchan, *next;
+ float imat[4][4];
+// float ctime= (float)G.scene->r.cfra; /* time only applies constraint location on curve path (now) */
- for (curBone=bone->childbase.first; curBone; curBone=curBone->next){
- rbone=get_named_bone_bonechildren (curBone, name);
- if (rbone)
- return rbone;
+ arm = get_armature(ob);
+
+ if(arm==NULL) return;
+ if(ob->pose==NULL || (ob->pose->flag & POSE_RECALC))
+ armature_rebuild_pose(ob, arm);
+
+// printf("re-evaluate pose %s\n", ob->id.name);
+
+ /* In restposition we read the data from the bones */
+ if(arm->flag & ARM_RESTPOS) {
+
+ for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
+ bone= pchan->bone;
+ if(bone) {
+ Mat4CpyMat4(pchan->pose_mat, bone->arm_mat);
+ VECCOPY(pchan->pose_head, bone->arm_head);
+ VECCOPY(pchan->pose_tail, pchan->pose_head);
+ }
+ }
}
-
- return NULL;
-}
-
-void make_displists_by_armature (Object *ob)
-{
- Base *base;
-
- if (ob){
- if (ob->type != OB_ARMATURE) return;
- for (base= G.scene->base.first; base; base= base->next){
- if ((ob==base->object->parent) && (base->lay & G.scene->lay))
- if ((base->object->partype==PARSKEL) || (base->object->type==OB_MBALL))
- makeDispList(base->object);
+ else {
+ Mat4Invert(ob->imat, ob->obmat); // imat is needed
+
+//#if 0
+ /* 1. construct the PoseChains, clear flags */
+ for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
+ pchan->flag &= ~POSE_DONE;
+ if(pchan->constflag & PCHAN_HAS_IK) // flag is set on editing constraints
+ initialize_posechain(ob, pchan); // will attach it to root!
+ }
+
+ /* 2. the main loop, channels are already hierarchical sorted from root to children */
+ for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
+ if(!(pchan->flag & POSE_DONE)) {
+ /* 3. if we find an IK root, we handle it separated */
+ if(pchan->chain.first) {
+ while(pchan->chain.first) {
+ PoseChain *chain= pchan->chain.first;
+ int a;
+
+ /* 4. walk over the chain for regular solving */
+ for(a=0; a<chain->totchannel; a++) {
+ if(!(chain->pchanchain[a]->flag & POSE_DONE)) // successive chains can set the flag
+ where_is_pose_bone(ob, chain->pchanchain[a]);
+ }
+ /* 5. execute the IK solver */
+ execute_posechain(ob, chain); // calculates 3x3 difference matrices
+ /* 6. apply the differences to the channels, we calculate the original differences first */
+ for(a=0; a<chain->totchannel; a++)
+ make_dmats(chain->pchanchain[a]);
+ for(a=0; a<chain->totchannel; a++)
+ where_is_ik_bone(chain->pchanchain[a], (void *)chain->solver->segments[a].basis_change);
+ // (sets POSE_DONE)
+
+ /* 6. and free */
+ BLI_remlink(&pchan->chain, chain);
+ free_posechain(chain);
+ }
+ }
+ else where_is_pose_bone(ob, pchan);
+ }
}
+//#endif
}
-/*
-(ton) changed this; now a free displist is sufficient, drawobject.c will make disp
-(ton) changed it back... doesnt work yet, do it after release
-*/
-
-}
-
-void get_objectspace_bone_matrix (struct Bone* bone, float M_accumulatedMatrix[][4], int root, int posed)
-/* Gets matrix that transforms the bone to object space */
-/* This function is also used to compute the orientation of the bone for display */
-{
- Bone *curBone;
-
- Bone *bonelist[256];
- int bonecount=0, i;
- Mat4One (M_accumulatedMatrix);
-
- /* Build a list of bones from tip to root */
- for (curBone=bone; curBone; curBone=curBone->parent){
- bonelist[bonecount] = curBone;
- bonecount++;
+#if 0
+ doconstraints= 1;
+ for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
+ where_is_pose_bone(ob, pchan);
}
+ doconstraints= 0;
+ for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
+ where_is_pose_bone(ob, pchan);
+ pchan->flag &= ~POSE_IK_MAT;
+ }
+#endif
+
+ /* calculating deform matrices */
+ for(pchan= ob->pose->chanbase.first; pchan; pchan= next) {
+ next= pchan->next;
+
+ if(pchan->bone) {
+ Mat4Invert(imat, pchan->bone->arm_mat);
+ Mat4MulMat4(pchan->chan_mat, imat, pchan->pose_mat);
+ }
+ }
+}
- /* Count through the inverted list (i.e. iterate from root to tip)*/
- for (i=0; i<bonecount; i++){
- float T_root[4][4];
- float T_len[4][4];
- float R_bmat[4][4];
- float M_obmat[4][4];
- float M_boneMatrix[4][4];
- float delta[3];
-
- curBone = bonelist[bonecount-i-1];
-
- /* Get the length translation (length along y axis) */
- Mat4One (T_len);
- T_len[3][1] = get_bone_length(curBone);
-
- if ((curBone == bone) && (root))
- Mat4One (T_len);
-
- /* Get the bone's root offset (in the parent's coordinate system) */
- Mat4One (T_root);
- VECCOPY (T_root[3], curBone->head);
-
- /* Compose the restmat */
- VecSubf(delta, curBone->tail, curBone->head);
- make_boneMatrixvr(R_bmat, delta, curBone->roll);
+/* *************** helper for selection code ****************** */
- /* Retrieve the obmat (user transformation) */
- if (posed)
- Mat4CpyMat4 (M_obmat, curBone->obmat);
- else
- Mat4One (M_obmat);
- /* Compose the matrix for this bone */
-#if 0
- Mat4MulSerie (M_boneMatrix, M_accumulatedMatrix, T_root, M_obmat, R_bmat, T_len, NULL, NULL, NULL);
-#else
- Mat4MulSerie (M_boneMatrix, M_accumulatedMatrix, T_root, R_bmat, M_obmat, T_len, NULL, NULL, NULL);
-#endif
- Mat4CpyMat4 (M_accumulatedMatrix, M_boneMatrix);
+Bone *get_indexed_bone (Object *ob, int index)
+/*
+ Now using pose channel
+*/
+{
+ bPoseChannel *pchan;
+ int a= 0;
+
+ if(ob->pose==NULL) return NULL;
+
+ for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next, a++) {
+ if(a==index) return pchan->bone;
}
+ return NULL;
+}
-}
+/* *********************** Inverse Kinematics ************* */
+#if 0
void solve_posechain (PoseChain *chain)
{
float goal[3];
int i;
Bone *curBone;
- float M_obmat[4][4];
- float M_basischange[4][4];
+// float M_obmat[4][4];
+// float M_basischange[4][4];
bPoseChannel *chan;
if (!chain->solver) return;
@@ -1290,7 +1086,6 @@ void solve_posechain (PoseChain *chain)
VECCOPY (goal, chain->goal);
Mat4MulVecfl (chain->goalinv, goal);
-
/* Solve the chain */
IK_SolveChain(chain->solver,
@@ -1302,30 +1097,41 @@ void solve_posechain (PoseChain *chain)
/* Copy the results back into the bones */
for (i = chain->solver->num_segments-1, curBone=chain->target->parent; i>=0; i--, curBone=curBone->parent){
-
+// for (i = 0; i<chain->solver->num_segments; i++) {
+ //curBone= bonelist[i];
+
/* Retrieve the delta rotation from the solver */
- Mat4One(M_basischange);
- Mat4CpyMat3(M_basischange, (void *)chain->solver->segments[i].basis_change); //basis_change = array[9]
-
-
+// Mat4One(M_basischange);
+// Mat4CpyMat3(M_basischange, (void *)chain->solver->segments[i].basis_change); //basis_change = array[9]
+// printmatrix3(curBone->name, (void *)chain->solver->segments[i].basis_change);
/**
* Multiply the bone's usertransform by the
* basis change to get the new usertransform
*/
- Mat4CpyMat4 (M_obmat, curBone->obmat);
- Mat4MulMat4 (curBone->obmat, M_basischange, M_obmat);
-
+ //Mat4CpyMat4 (M_obmat, curBone->obmat);
+ //Mat4MulMat4 (curBone->obmat, M_basischange, M_obmat);
+ /* store in channel itself */
+
+ chan= get_pose_channel(chain->pose, curBone->name);
+ Mat3CpyMat3 (chan->ik_mat, (void *)chain->solver->segments[i].basis_change);
+ chan->flag |= POSE_IK_MAT;
+
/* Store the solve results on the childrens' channels */
- for (chan = chain->pose->chanbase.first; chan; chan=chan->next){
- if (!strcmp (chan->name, curBone->name)){
- Mat4CpyMat4 (chan->obmat, curBone->obmat);
- break;
- }
- }
-
+ //for (chan = chain->pose->chanbase.first; chan; chan=chan->next){
+ // if (!strcmp (chan->name, curBone->name)){
+ // Mat4CpyMat4 (chan->obmat, curBone->obmat);
+ // break;
+ // }
+ //}
}
+ /* WARNING! REMOVE LATER !!! */
+ /* flag chain target to recalculate too */
+ chan= get_pose_channel(chain->pose, chain->target->name);
+ Mat3One(chan->ik_mat);
+ chan->flag |= POSE_IK_MAT;
}
+#endif
void free_posechain (PoseChain *chain)
{
@@ -1334,9 +1140,13 @@ void free_posechain (PoseChain *chain)
chain->solver->segments = NULL;
IK_FreeChain(chain->solver);
}
- MEM_freeN (chain);
+ if(chain->pchanchain) MEM_freeN(chain->pchanchain);
+ MEM_freeN(chain);
}
+#if 0
+/* actually; bones to IK_solver data */
+/* Object is its own Armature object */
PoseChain *ik_chain_to_posechain (Object *ob, Bone *bone)
{
IK_Segment_Extern *segs;
@@ -1344,15 +1154,16 @@ PoseChain *ik_chain_to_posechain (Object *ob, Bone *bone)
Bone *curBone, *rootBone;
int segcount, curseg, icurseg;
float imat[4][4];
+ bPoseChannel *pchan;
Bone *bonelist[256];
float rootmat[4][4];
- float bonespace[4][4];
+// float bonespace[4][4];
/**
* Some interesting variables in this function:
*
* Bone->obmat Bone's user transformation;
- * It is initialized in where_is_bone1_time
+ * It is initialized in where_is_b one1_time
*
* rootmat Bone's coordinate system, computed by
* get_objectspace_bone_matrix. Takes all
@@ -1395,27 +1206,29 @@ PoseChain *ik_chain_to_posechain (Object *ob, Bone *bone)
/* Allocate some IK segments */
segs = MEM_callocN (sizeof(IK_Segment_Extern)*segcount, "iksegments");
-
+ //printf("segcount %d\n", segcount);
/**
* Remove the offset from the first bone in the chain and take the target to chainspace
*/
-
- get_objectspace_bone_matrix(rootBone, bonespace, 1, 1);
- Mat4One (rootmat);
- VECCOPY (rootmat[3], bonespace[3]);
+ //get_objectspace_bone_matrix(rootBone, bonespace, 1, 1);
+ //Mat4One (rootmat);
+ //VECCOPY (rootmat[3], bonespace[3]);
+ pchan= get_pose_channel(ob->pose, rootBone->name);
+ Mat4One(rootmat);
+ VECCOPY(rootmat[3], pchan->pose_head);
/* Take the target to bonespace */
+ /* (ton) I think it's the matrix to take a world coordinate into "chainspace" */
Mat4MulMat4 (imat, rootmat, ob->obmat);
Mat4Invert (chain->goalinv, imat);
-
/**
* Build matrices from the root to the tip
* We count backwards through the bone list (which is sorted tip to root)
* and forwards through the ik_segment list
*/
-
+ /* that we're going to recode! (ton) */
for (curseg = segcount-1; curseg>=0; curseg--){
float M_basismat[4][4];
float R_parmat[4][4];
@@ -1428,11 +1241,16 @@ PoseChain *ik_chain_to_posechain (Object *ob, Bone *bone)
/* Get the basis matrix */
Mat4One (R_parmat);
- get_objectspace_bone_matrix(curBone, R_bonemat, 1, 1);
+ //get_objectspace_bone_matrix(curBone, R_bonemat, 1, 1);
+ //R_bonemat[3][0]=R_bonemat[3][1]=R_bonemat[3][2]=0.0F;
+ pchan= get_pose_channel(ob->pose, curBone->name);
+ Mat4CpyMat4(R_bonemat, pchan->pose_mat);
R_bonemat[3][0]=R_bonemat[3][1]=R_bonemat[3][2]=0.0F;
- if (curBone->parent && (curBone->flag & BONE_IK_TOPARENT)){
- get_objectspace_bone_matrix(curBone->parent, R_parmat, 1, 1);
+ if (curBone->parent && (curBone->flag & BONE_IK_TOPARENT)) {
+ //get_objectspace_bone_matrix(curBone->parent, R_parmat, 1, 1);
+ Mat4CpyMat4(R_parmat, pchan->parent->pose_mat);
+
R_parmat[3][0]=R_parmat[3][1]=R_parmat[3][2]=0.0F;
}
@@ -1444,25 +1262,13 @@ PoseChain *ik_chain_to_posechain (Object *ob, Bone *bone)
Mat3Transp((void *)segs[icurseg].basis);
/* Fill out the IK segment */
- segs[icurseg].length = get_bone_length(curBone);
+ segs[icurseg].length = VecLenf(curBone->head, curBone->tail);
- };
+ }
IK_LoadChain(chain->solver, segs, segcount);
+
return chain;
}
-
-
-void precalc_bonelist_irestmats (ListBase* bonelist)
-{
- Bone *curbone;
-
- if (!bonelist)
- return;
-
- for (curbone = bonelist->first; curbone; curbone=curbone->next){
- precalc_bone_irestmat(curbone);
- precalc_bonelist_irestmats(&curbone->childbase);
- }
-}
+#endif
diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c
index 2b7a5b446e5..b0f84d8d844 100644
--- a/source/blender/blenkernel/intern/blender.c
+++ b/source/blender/blenkernel/intern/blender.c
@@ -392,15 +392,6 @@ static void setup_app_data(BlendFileData *bfd, char *filename)
}
}
- /* few DispLists, but do text_to_curve */
- // this should be removed!!! But first a better displist system (ton)
- for (ob= G.main->object.first; ob; ob= ob->id.next) {
- if(ob->type==OB_FONT) {
- Curve *cu= ob->data;
- if(cu->nurb.first==0) text_to_curve(ob, 0);
- }
- }
-
if (!G.background) {
setscreen(G.curscreen);
}
diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c
index dff98c87a6f..f373c7f9062 100644
--- a/source/blender/blenkernel/intern/constraint.c
+++ b/source/blender/blenkernel/intern/constraint.c
@@ -73,9 +73,178 @@ void Mat4BlendMat4(float [][4], float [][4], float [][4], float );
/* Local function prototypes */
-/* Functions */
+/* ********************* Data level ****************** */
-char constraint_has_target (bConstraint *con) {
+void free_constraint_data (bConstraint *con)
+{
+ if (con->data){
+ switch (con->type){
+ default:
+ break;
+ };
+
+ MEM_freeN (con->data);
+ }
+}
+
+void free_constraints (ListBase *conlist)
+{
+ bConstraint *con;
+
+ /* Do any specific freeing */
+ for (con=conlist->first; con; con=con->next)
+ {
+ free_constraint_data (con);
+ };
+
+ /* Free the whole list */
+ BLI_freelistN(conlist);
+}
+
+void free_constraint_channels (ListBase *chanbase)
+{
+ bConstraintChannel *chan;
+
+ for (chan=chanbase->first; chan; chan=chan->next)
+ {
+ if (chan->ipo){
+ chan->ipo->id.us--;
+ }
+ }
+
+ BLI_freelistN(chanbase);
+}
+
+void relink_constraints (struct ListBase *list)
+{
+ bConstraint *con;
+
+ for (con = list->first; con; con=con->next){
+ switch (con->type){
+ case CONSTRAINT_TYPE_KINEMATIC:
+ {
+ bKinematicConstraint *data;
+ data = con->data;
+
+ ID_NEW(data->tar);
+ }
+ break;
+ case CONSTRAINT_TYPE_NULL:
+ {
+ }
+ break;
+ case CONSTRAINT_TYPE_TRACKTO:
+ {
+ bTrackToConstraint *data;
+ data = con->data;
+
+ ID_NEW(data->tar);
+ }
+ break;
+ case CONSTRAINT_TYPE_LOCKTRACK:
+ {
+ bLockTrackConstraint *data;
+ data = con->data;
+
+ ID_NEW(data->tar);
+ }
+ break;
+ case CONSTRAINT_TYPE_ACTION:
+ {
+ bActionConstraint *data;
+ data = con->data;
+
+ ID_NEW(data->tar);
+ }
+ break;
+ case CONSTRAINT_TYPE_LOCLIKE:
+ {
+ bLocateLikeConstraint *data;
+ data = con->data;
+
+ ID_NEW(data->tar);
+ }
+ break;
+ case CONSTRAINT_TYPE_ROTLIKE:
+ {
+ bRotateLikeConstraint *data;
+ data = con->data;
+
+ ID_NEW(data->tar);
+ }
+ break;
+ case CONSTRAINT_TYPE_FOLLOWPATH:
+ {
+ bFollowPathConstraint *data;
+ data = con->data;
+
+ ID_NEW(data->tar);
+ }
+ break;
+ case CONSTRAINT_TYPE_STRETCHTO:
+ {
+ bStretchToConstraint *data;
+ data = con->data;
+
+ ID_NEW(data->tar);
+ }
+ break;
+
+ }
+ }
+}
+
+void *copy_constraint_channels (ListBase *dst, ListBase *src)
+{
+ bConstraintChannel *dchan, *schan;
+ bConstraintChannel *newact=NULL;
+
+ dst->first=dst->last=NULL;
+ duplicatelist(dst, src);
+
+ for (dchan=dst->first, schan=src->first; dchan; dchan=dchan->next, schan=schan->next){
+ dchan->ipo = copy_ipo(schan->ipo);
+ }
+
+ return newact;
+}
+
+bConstraintChannel *clone_constraint_channels (ListBase *dst, ListBase *src, bConstraintChannel *oldact)
+{
+ bConstraintChannel *dchan, *schan;
+ bConstraintChannel *newact=NULL;
+
+ dst->first=dst->last=NULL;
+ duplicatelist(dst, src);
+
+ for (dchan=dst->first, schan=src->first; dchan; dchan=dchan->next, schan=schan->next){
+ id_us_plus((ID *)dchan->ipo);
+ if (schan==oldact)
+ newact=dchan;
+ }
+
+ return newact;
+}
+
+void copy_constraints (ListBase *dst, ListBase *src)
+{
+ bConstraint *con;
+
+ dst->first= dst->last= NULL;
+
+ duplicatelist (dst, src);
+
+ for (con = dst->first; con; con=con->next) {
+ con->data = MEM_dupallocN (con->data);
+ /* removed a whole lot of useless code here (ton) */
+ }
+}
+
+
+/* **************** Editor Functions **************** */
+
+char constraint_has_target (bConstraint *con)
+{
switch (con->type){
case CONSTRAINT_TYPE_TRACKTO:
{
@@ -137,7 +306,7 @@ char constraint_has_target (bConstraint *con) {
return 0;
}
-Object *get_constraint_target(bConstraint *con)
+Object *get_constraint_target(bConstraint *con, char **subtarget)
{
/*
* If the target for this constraint is target, return a pointer
@@ -147,48 +316,56 @@ Object *get_constraint_target(bConstraint *con)
case CONSTRAINT_TYPE_ACTION:
{
bActionConstraint *data = con->data;
+ *subtarget= data->subtarget;
return data->tar;
}
break;
case CONSTRAINT_TYPE_LOCLIKE:
{
bLocateLikeConstraint *data = con->data;
+ *subtarget= data->subtarget;
return data->tar;
}
break;
case CONSTRAINT_TYPE_ROTLIKE:
{
bRotateLikeConstraint *data = con->data;
+ *subtarget= data->subtarget;
return data->tar;
}
break;
case CONSTRAINT_TYPE_KINEMATIC:
{
bKinematicConstraint *data = con->data;
+ *subtarget= data->subtarget;
return data->tar;
}
break;
case CONSTRAINT_TYPE_TRACKTO:
{
bTrackToConstraint *data = con->data;
+ *subtarget= data->subtarget;
return data->tar;
}
break;
case CONSTRAINT_TYPE_LOCKTRACK:
{
bLockTrackConstraint *data = con->data;
+ *subtarget= data->subtarget;
return data->tar;
}
break;
case CONSTRAINT_TYPE_FOLLOWPATH:
{
bFollowPathConstraint *data = con->data;
+ *subtarget= NULL;
return data->tar;
}
break;
case CONSTRAINT_TYPE_STRETCHTO:
{
bStretchToConstraint *data = con->data;
+ *subtarget= data->subtarget;
return (data->tar);
}
break;
@@ -197,7 +374,65 @@ Object *get_constraint_target(bConstraint *con)
return NULL;
}
-void unique_constraint_name (bConstraint *con, ListBase *list){
+void set_constraint_target(bConstraint *con, Object *ob)
+{
+ /*
+ * Set the target for this constraint
+ */
+ switch (con->type) {
+ case CONSTRAINT_TYPE_ACTION:
+ {
+ bActionConstraint *data = con->data;
+ data->tar= ob;
+ }
+ break;
+ case CONSTRAINT_TYPE_LOCLIKE:
+ {
+ bLocateLikeConstraint *data = con->data;
+ data->tar= ob;
+ }
+ break;
+ case CONSTRAINT_TYPE_ROTLIKE:
+ {
+ bRotateLikeConstraint *data = con->data;
+ data->tar= ob;
+ }
+ break;
+ case CONSTRAINT_TYPE_KINEMATIC:
+ {
+ bKinematicConstraint *data = con->data;
+ data->tar= ob;
+ }
+ break;
+ case CONSTRAINT_TYPE_TRACKTO:
+ {
+ bTrackToConstraint *data = con->data;
+ data->tar= ob;
+ }
+ break;
+ case CONSTRAINT_TYPE_LOCKTRACK:
+ {
+ bLockTrackConstraint *data = con->data;
+ data->tar= ob;
+ }
+ break;
+ case CONSTRAINT_TYPE_FOLLOWPATH:
+ {
+ bFollowPathConstraint *data = con->data;
+ data->tar= ob;
+ }
+ break;
+ case CONSTRAINT_TYPE_STRETCHTO:
+ {
+ bStretchToConstraint *data = con->data;
+ data->tar= ob;
+ }
+ break;
+ }
+}
+
+void unique_constraint_name (bConstraint *con, ListBase *list)
+{
char tempname[64];
int number;
char *dot;
@@ -241,9 +476,9 @@ void unique_constraint_name (bConstraint *con, ListBase *list){
}
}
-void *new_constraint_data (short type)
+void *new_constraint_data (short type)
{
- void *result;
+ void *result;
switch (type){
case CONSTRAINT_TYPE_KINEMATIC:
@@ -252,7 +487,7 @@ void *new_constraint_data (short type)
data = MEM_callocN(sizeof(bKinematicConstraint), "kinematicConstraint");
data->tolerance = (float)0.001;
- data->iterations = 500;
+ data->iterations = 50;
result = data;
}
@@ -344,23 +579,27 @@ void *new_constraint_data (short type)
return result;
}
-bConstraintChannel *find_constraint_channel (ListBase *list, const char *name){
+bConstraintChannel *find_constraint_channel (ListBase *list, const char *name)
+{
bConstraintChannel *chan;
- for (chan = list->first; chan; chan=chan->next){
- if (!strcmp(name, chan->name)){
+ for (chan = list->first; chan; chan=chan->next) {
+ if (!strcmp(name, chan->name)) {
return chan;
}
}
return NULL;
}
+/* ***************** Evaluating ********************* */
+
+/* does ipos only */
void do_constraint_channels (ListBase *conbase, ListBase *chanbase, float ctime)
{
bConstraint *con;
bConstraintChannel *chan;
- IpoCurve *icu;
-
+ IpoCurve *icu=NULL;
+
for (con=conbase->first; con; con=con->next){
chan = find_constraint_channel(chanbase, con->name);
if (chan && chan->ipo){
@@ -421,94 +660,33 @@ void Mat4BlendMat4(float out[][4], float dst[][4], float src[][4], float srcweig
static void constraint_target_to_mat4 (Object *ob, const char *substring, float mat[][4], float size[3], float ctime)
{
- /* Update the location of the target object */
- //where_is_object_time (ob, ctime);
-
/* Case OBJECT */
- if (!strlen(substring)){
+ if (!strlen(substring)) {
Mat4CpyMat4 (mat, ob->obmat);
- VECCOPY (size, ob->size);
- return;
+ VECCOPY (size, ob->size); // whats this for, hack! (ton)
}
-
/* Case BONE */
else {
- bArmature *arm;
- Bone *bone;
- float bmat[4][4];
+ bPoseChannel *pchan;
float bsize[3]={1, 1, 1};
- arm = get_armature(ob);
-
- /**
- * Locate the bone (if there is one)
- * Ensures that the bone's transformation is fully constrained
- * (Cyclical relationships are disallowed elsewhere)
- */
- bone = get_named_bone(arm, substring);
- if (bone){
- where_is_bone_time(ob, bone, ctime);
- get_objectspace_bone_matrix(bone, bmat, 1, 1);
- VECCOPY(bsize, bone->size);
+ pchan = get_pose_channel(ob->pose, substring);
+ if (pchan){
+ /**
+ * Multiply the objectspace bonematrix by the skeletons's global
+ * transform to obtain the worldspace transformation of the target
+ */
+ Mat4MulMat4 (mat, pchan->pose_mat, ob->obmat);
}
else
- Mat4One (bmat);
-
- /**
- * Multiply the objectspace bonematrix by the skeletons's global
- * transform to obtain the worldspace transformation of the target
- */
- VECCOPY(size, bsize);
- Mat4MulMat4 (mat, bmat, ob->obmat);
-
- return;
- }
-}
-
-void clear_object_constraint_status (Object *ob)
-{
- bConstraint *con;
+ Mat4CpyMat4 (mat, ob->obmat);
- if (!ob) return;
-
- /* Clear the object's constraints */
- for (con = ob->constraints.first; con; con=con->next){
- con->flag &= ~CONSTRAINT_DONE;
- }
-
- /* Clear the object's subdata constraints */
- switch (ob->type){
- case OB_ARMATURE:
- {
- clear_pose_constraint_status (ob);
- }
- break;
- default:
- break;
- }
-}
-
-void clear_all_constraints(void)
-{
- Base *base;
-
- /* Clear the constraint "done" flags -- this must be done
- * before displists are calculated for objects that are
- * deformed by armatures */
- for (base = G.scene->base.first; base; base=base->next){
- clear_object_constraint_status(base->object);
- }
-}
-
-void rebuild_all_armature_displists(void) {
- Base *base;
-
- for (base = G.scene->base.first; base; base=base->next){
- clear_object_constraint_status(base->object);
- make_displists_by_armature(base->object);
+ VECCOPY(size, bsize); // whats this for, hack! (ton)
}
}
+/* called during solve_constraints */
+/* also for make_parent, to find correct inverse of "follow path" */
short get_constraint_target_matrix (bConstraint *con, short ownertype, void* ownerdata, float mat[][4], float size[3], float ctime)
{
short valid=0;
@@ -531,13 +709,11 @@ short get_constraint_target_matrix (bConstraint *con, short ownertype, void* own
float s,t;
Bone *curBone;
Bone tbone;
- int i;
+// int i;
curBone = (Bone*)ownerdata;
if (data->tar){
- /* Update the location of the target object */
- where_is_object_time (data->tar, ctime);
constraint_target_to_mat4(data->tar, data->subtarget, tempmat, size, ctime);
valid=1;
}
@@ -582,26 +758,26 @@ short get_constraint_target_matrix (bConstraint *con, short ownertype, void* own
pose = MEM_callocN(sizeof(bPose), "pose");
verify_pose_channel(pose, curBone->name);
- get_pose_from_action (&pose, data->act, t);
+ extract_pose_from_action (pose, data->act, t);
/* Find the appropriate channel */
pchan = get_pose_channel(pose, curBone->name);
if (pchan){
memset(&tbone, 0x00, sizeof(Bone));
- VECCOPY (tbone.loc, pchan->loc);
- VECCOPY (tbone.size, pchan->size);
- for (i=0; i<4; i++)
- tbone.quat[i]=pchan->quat[i];
-
- bone_to_mat4(&tbone, mat);
+// VECCOPY (tbone.loc, pchan->loc);
+// VECCOPY (tbone.size, pchan->size);
+// for (i=0; i<4; i++)
+// tbone.quat[i]=pchan->quat[i];
+//
+// bone_to_mat4(&tbone, mat);
}
else{
Mat4One(mat);
}
/* Clean up */
- clear_pose(pose);
+ free_pose_channels(pose);
MEM_freeN(pose);
}
@@ -612,8 +788,6 @@ short get_constraint_target_matrix (bConstraint *con, short ownertype, void* own
bLocateLikeConstraint *data = (bLocateLikeConstraint*)con->data;
if (data->tar){
- /* Update the location of the target object */
- where_is_object_time (data->tar, ctime);
constraint_target_to_mat4(data->tar, data->subtarget, mat, size, ctime);
valid=1;
}
@@ -627,8 +801,6 @@ short get_constraint_target_matrix (bConstraint *con, short ownertype, void* own
data = (bRotateLikeConstraint*)con->data;
if (data->tar){
- /* Update the location of the target object */
- where_is_object_time (data->tar, ctime);
constraint_target_to_mat4(data->tar, data->subtarget, mat, size, ctime);
valid=1;
}
@@ -642,9 +814,6 @@ short get_constraint_target_matrix (bConstraint *con, short ownertype, void* own
data = (bTrackToConstraint*)con->data;
if (data->tar){
- // Refresh the object if it isn't a constraint loop
- if (!(con->flag & CONSTRAINT_NOREFRESH))
- where_is_object_time (data->tar, ctime);
constraint_target_to_mat4(data->tar, data->subtarget, mat, size, ctime);
valid=1;
}
@@ -654,12 +823,10 @@ short get_constraint_target_matrix (bConstraint *con, short ownertype, void* own
break;
case CONSTRAINT_TYPE_KINEMATIC:
{
- bTrackToConstraint *data;
- data = (bTrackToConstraint*)con->data;
+ bKinematicConstraint *data;
+ data = (bKinematicConstraint*)con->data;
if (data->tar){
- /* Update the location of the target object */
- where_is_object_time (data->tar, ctime);
constraint_target_to_mat4(data->tar, data->subtarget, mat, size, ctime);
valid=1;
}
@@ -673,10 +840,6 @@ short get_constraint_target_matrix (bConstraint *con, short ownertype, void* own
data = (bLockTrackConstraint*)con->data;
if (data->tar){
- // Refresh the object if it isn't a constraint loop
- if (!(con->flag & CONSTRAINT_NOREFRESH))
- where_is_object_time (data->tar, ctime);
-
constraint_target_to_mat4(data->tar, data->subtarget, mat, size, ctime);
valid=1;
}
@@ -690,33 +853,17 @@ short get_constraint_target_matrix (bConstraint *con, short ownertype, void* own
data = (bFollowPathConstraint*)con->data;
if (data->tar){
- short OldFlag;
Curve *cu;
float q[4], vec[4], dir[3], *quat, x1, totmat[4][4];
float curvetime;
- where_is_object_time (data->tar, ctime);
-
Mat4One (totmat);
Mat4One (mat);
cu= data->tar->data;
- OldFlag = cu->flag;
-
- if(data->followflag) {
- if(!(cu->flag & CU_FOLLOW)) cu->flag += CU_FOLLOW;
- }
- else {
- if(cu->flag & CU_FOLLOW) cu->flag -= CU_FOLLOW;
- }
-
- if(!(cu->flag & CU_PATH)) cu->flag += CU_PATH;
-
- if(cu->path==NULL)
- calc_curvepath(data->tar);
- else if (cu->path->data==NULL)
- calc_curvepath(data->tar);
+ /* note; when creating constraints that follow path, the curve gets the CU_PATH set now,
+ currently for paths to work it needs to go through the bevlist/displist system (ton) */
if(cu->path && cu->path->data) {
curvetime= bsystem_time(data->tar, data->tar->parent, (float)ctime, 0.0) - data->offset;
@@ -746,7 +893,6 @@ short get_constraint_target_matrix (bConstraint *con, short ownertype, void* own
Mat4MulSerie(mat, data->tar->obmat, totmat, NULL, NULL, NULL, NULL, NULL, NULL);
}
}
- cu->flag = OldFlag;
valid=1;
}
else
@@ -759,7 +905,6 @@ short get_constraint_target_matrix (bConstraint *con, short ownertype, void* own
data = (bStretchToConstraint*)con->data;
if (data->tar){
- where_is_object_time (data->tar, ctime);
constraint_target_to_mat4(data->tar, data->subtarget, mat, size, ctime);
valid = 1;
}
@@ -776,209 +921,10 @@ short get_constraint_target_matrix (bConstraint *con, short ownertype, void* own
return valid;
}
-void relink_constraints (struct ListBase *list)
-{
- bConstraint *con;
-
- for (con = list->first; con; con=con->next){
- switch (con->type){
- case CONSTRAINT_TYPE_KINEMATIC:
- {
- bKinematicConstraint *data;
- data = con->data;
-
- ID_NEW(data->tar);
- }
- break;
- case CONSTRAINT_TYPE_NULL:
- {
- }
- break;
- case CONSTRAINT_TYPE_TRACKTO:
- {
- bTrackToConstraint *data;
- data = con->data;
-
- ID_NEW(data->tar);
- }
- break;
- case CONSTRAINT_TYPE_LOCKTRACK:
- {
- bLockTrackConstraint *data;
- data = con->data;
-
- ID_NEW(data->tar);
- }
- break;
- case CONSTRAINT_TYPE_ACTION:
- {
- bActionConstraint *data;
- data = con->data;
-
- ID_NEW(data->tar);
- }
- break;
- case CONSTRAINT_TYPE_LOCLIKE:
- {
- bLocateLikeConstraint *data;
- data = con->data;
-
- ID_NEW(data->tar);
- }
- break;
- case CONSTRAINT_TYPE_ROTLIKE:
- {
- bRotateLikeConstraint *data;
- data = con->data;
-
- ID_NEW(data->tar);
- }
- break;
- case CONSTRAINT_TYPE_FOLLOWPATH:
- {
- bFollowPathConstraint *data;
- data = con->data;
-
- ID_NEW(data->tar);
- }
- break;
- case CONSTRAINT_TYPE_STRETCHTO:
- {
- bStretchToConstraint *data;
- data = con->data;
-
- ID_NEW(data->tar);
- }
- break;
-
- }
- }
-}
-
-void *copy_constraint_channels (ListBase *dst, ListBase *src)
-{
- bConstraintChannel *dchan, *schan;
- bConstraintChannel *newact=NULL;
-
- dst->first=dst->last=NULL;
- duplicatelist(dst, src);
-
- for (dchan=dst->first, schan=src->first; dchan; dchan=dchan->next, schan=schan->next){
- dchan->ipo = copy_ipo(schan->ipo);
- }
-
- return newact;
-}
-
-bConstraintChannel *clone_constraint_channels (ListBase *dst, ListBase *src, bConstraintChannel *oldact)
-{
- bConstraintChannel *dchan, *schan;
- bConstraintChannel *newact=NULL;
-
- dst->first=dst->last=NULL;
- duplicatelist(dst, src);
-
- for (dchan=dst->first, schan=src->first; dchan; dchan=dchan->next, schan=schan->next){
- id_us_plus((ID *)dchan->ipo);
- if (schan==oldact)
- newact=dchan;
- }
-
- return newact;
-}
-
-void copy_constraints (ListBase *dst, ListBase *src)
-{
- bConstraint *con;
-
- dst->first=dst->last=NULL;
-
- duplicatelist (dst, src);
-
- /* Update specific data */
- if (!dst->first)
- return;
-
- for (con = dst->first; con; con=con->next){
- switch (con->type){
- case CONSTRAINT_TYPE_ACTION:
- {
- bActionConstraint *data;
-
- con->data = MEM_dupallocN (con->data);
- data = (bActionConstraint*) con->data;
- }
- break;
- case CONSTRAINT_TYPE_LOCLIKE:
- {
- bLocateLikeConstraint *data;
-
- con->data = MEM_dupallocN (con->data);
- data = (bLocateLikeConstraint*) con->data;
- }
- break;
- case CONSTRAINT_TYPE_ROTLIKE:
- {
- bRotateLikeConstraint *data;
-
- con->data = MEM_dupallocN (con->data);
- data = (bRotateLikeConstraint*) con->data;
- }
- break;
- case CONSTRAINT_TYPE_NULL:
- {
- con->data = NULL;
- }
- break;
- case CONSTRAINT_TYPE_TRACKTO:
- {
- bTrackToConstraint *data;
-
- con->data = MEM_dupallocN (con->data);
- data = (bTrackToConstraint*) con->data;
- }
- break;
- case CONSTRAINT_TYPE_LOCKTRACK:
- {
- bLockTrackConstraint *data;
-
- con->data = MEM_dupallocN (con->data);
- data = (bLockTrackConstraint*) con->data;
- }
- break;
- case CONSTRAINT_TYPE_KINEMATIC:
- {
- bKinematicConstraint *data;
-
- con->data = MEM_dupallocN (con->data);
- data = (bKinematicConstraint*) con->data;
- }
- break;
- case CONSTRAINT_TYPE_FOLLOWPATH:
- {
- bFollowPathConstraint *data;
-
- con->data = MEM_dupallocN (con->data);
- data = (bFollowPathConstraint*) con->data;
- }
- break;
- case CONSTRAINT_TYPE_STRETCHTO:
- {
- bStretchToConstraint *data;
-
- con->data = MEM_dupallocN (con->data);
- data = (bStretchToConstraint*) con->data;
- }
- break;
- default:
- con->data = MEM_dupallocN (con->data);
- break;
- }
- }
-}
+/* only called during solve_constraints */
+/* bone constraints create a fake object to work on, then ob is a workob */
void evaluate_constraint (bConstraint *constraint, Object *ob, short ownertype, void *ownerdata, float targetmat[][4])
-/* ob is likely to be a workob */
{
float M_oldmat[4][4];
float M_identity[4][4];
@@ -988,11 +934,6 @@ void evaluate_constraint (bConstraint *constraint, Object *ob, short ownertype,
Mat4One (M_identity);
- /* We've already been calculated */
- if (constraint->flag & CONSTRAINT_DONE){
- return;
- }
-
switch (constraint->type){
case CONSTRAINT_TYPE_ACTION:
{
@@ -1088,6 +1029,7 @@ void evaluate_constraint (bConstraint *constraint, Object *ob, short ownertype,
break;
case CONSTRAINT_TYPE_KINEMATIC:
{
+#if 0
bKinematicConstraint *data;
float imat[4][4];
float temp[4][4];
@@ -1111,15 +1053,19 @@ void evaluate_constraint (bConstraint *constraint, Object *ob, short ownertype,
chain->tolerance = data->tolerance;
- {
+ if(0) {
+ bPoseChannel *pchan= get_pose_channel(armob->pose, curBone->name);
float parmat[4][4];
/* Take the obmat to objectspace */
- Mat4CpyMat4 (temp, curBone->obmat);
- Mat4One (curBone->obmat);
- get_objectspace_bone_matrix(curBone, parmat, 1, 1);
- Mat4CpyMat4 (curBone->obmat, temp);
- Mat4MulMat4 (totmat, parmat, ob->parent->obmat);
+
+// Mat4CpyMat4 (temp, curBone->obmat);
+// Mat4One (curBone->obmat);
+// get_objectspace_bone_matrix(curBone, parmat, 1, 1);
+ Mat4CpyMat4(parmat, pchan->pose_mat);
+
+// Mat4CpyMat4 (curBone->obmat, temp);
+ Mat4MulMat4 (totmat, parmat, armob->obmat);
Mat4Invert (imat, totmat);
@@ -1131,26 +1077,31 @@ void evaluate_constraint (bConstraint *constraint, Object *ob, short ownertype,
/* Solve it */
if (chain->solver){
VECCOPY (chain->goal, targetmat[3]);
- solve_posechain(chain);
+ solve_posechain(chain); // applies to bones/channels
}
free_posechain(chain);
- {
+ if(0) {
float parmat[4][4];
+ bPoseChannel *pchan= get_pose_channel(armob->pose, curBone->name);
/* Take the obmat to worldspace */
- Mat4CpyMat4 (temp, curBone->obmat);
- Mat4One (curBone->obmat);
- get_objectspace_bone_matrix(curBone, parmat, 1, 1);
- Mat4CpyMat4 (curBone->obmat, temp);
- Mat4MulMat4 (totmat, parmat, ob->parent->obmat);
+// Mat4CpyMat4 (temp, curBone->obmat);
+// Mat4One (curBone->obmat);
+
+// get_objectspace_bone_matrix(curBone, parmat, 1, 1);
+ Mat4CpyMat4(parmat, pchan->pose_mat);
+
+// Mat4CpyMat4 (curBone->obmat, temp);
+ Mat4MulMat4 (totmat, parmat, armob->obmat);
Mat4CpyMat4 (temp, ob->obmat);
Mat4MulMat4 (ob->obmat, temp, totmat);
}
}
+#endif
}
break;
case CONSTRAINT_TYPE_LOCKTRACK:
@@ -1481,7 +1432,7 @@ void evaluate_constraint (bConstraint *constraint, Object *ob, short ownertype,
data=(bFollowPathConstraint*)constraint->data;
if (data->tar) {
-
+ // weird, this is needed? doesnt work for workob (ton)
object_to_mat4(ob, obmat);
Mat4MulSerie(ob->obmat, targetmat, obmat, NULL, NULL, NULL, NULL, NULL, NULL);
@@ -1617,45 +1568,4 @@ void evaluate_constraint (bConstraint *constraint, Object *ob, short ownertype,
printf ("Error: Unknown constraint type\n");
break;
}
-
-}
-
-void free_constraint_data (bConstraint *con)
-{
- if (con->data){
- switch (con->type){
- default:
- break;
- };
-
- MEM_freeN (con->data);
- }
-}
-
-void free_constraints (ListBase *conlist)
-{
- bConstraint *con;
-
- /* Do any specific freeing */
- for (con=conlist->first; con; con=con->next)
- {
- free_constraint_data (con);
- };
-
- /* Free the whole list */
- BLI_freelistN(conlist);
-}
-
-void free_constraint_channels (ListBase *chanbase)
-{
- bConstraintChannel *chan;
-
- for (chan=chanbase->first; chan; chan=chan->next)
- {
- if (chan->ipo){
- chan->ipo->id.us--;
- }
- }
-
- BLI_freelistN(chanbase);
}
diff --git a/source/blender/blenkernel/intern/deform.c b/source/blender/blenkernel/intern/deform.c
index 226a1d602b7..7fe0ec626a4 100644
--- a/source/blender/blenkernel/intern/deform.c
+++ b/source/blender/blenkernel/intern/deform.c
@@ -54,6 +54,7 @@
#include "BKE_displist.h"
#include "BKE_effect.h"
#include "BKE_global.h"
+#include "BKE_key.h"
#include "BKE_lattice.h"
#include "BKE_object.h"
#include "BKE_softbody.h"
@@ -237,6 +238,8 @@ int mesh_modifier(Object *ob, char mode)
MVert *mv;
int a, done=0;
+ do_mesh_key(me);
+
/* conditions if it's needed */
if(ob->hooks.first);
else if(ob->effect.first); // weak... particles too
@@ -322,6 +325,8 @@ int curve_modifier(Object *ob, char mode)
BPoint *bp;
int a, index, done= 0;
+ do_curve_key(cu);
+
/* conditions if it's needed */
if(ob->hooks.first);
else if(ob->parent && ob->partype==PARSKEL);
@@ -390,6 +395,8 @@ int lattice_modifier(Object *ob, char mode)
BPoint *bp;
int a, index, done= 0;
+ do_latt_key(lt);
+
/* conditions if it's needed */
if(ob->hooks.first);
else if(ob->parent && ob->partype==PARSKEL);
diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c
index 668b18c0913..9f0501d54fc 100644
--- a/source/blender/blenkernel/intern/depsgraph.c
+++ b/source/blender/blenkernel/intern/depsgraph.c
@@ -41,17 +41,25 @@
#include "BLI_blenlib.h"
#include "BLI_arithb.h"
+#include "DNA_action_types.h"
+#include "DNA_armature_types.h"
+#include "DNA_curve_types.h"
#include "DNA_ID.h"
+#include "DNA_effect_types.h"
+#include "DNA_lattice_types.h"
+#include "DNA_mesh_types.h"
#include "DNA_object_types.h"
+#include "DNA_object_force.h"
#include "DNA_oops_types.h"
#include "DNA_scene_types.h"
-#include "DNA_action_types.h"
#include "DNA_screen_types.h"
#include "DNA_space_types.h"
#include "DNA_view2d_types.h"
-#include "BKE_utildefines.h"
+#include "BKE_action.h"
#include "BKE_global.h"
+#include "BKE_mball.h"
+#include "BKE_utildefines.h"
#include "MEM_guardedalloc.h"
#include "blendef.h"
@@ -272,18 +280,16 @@ int queue_count(struct DagNodeQueue *queue){
DagForest * dag_init()
{
DagForest *forest;
-
- forest = MEM_mallocN(sizeof(DagForest),"DAG root");
- forest->DagNode.first = NULL;
- forest->DagNode.last = NULL;
- forest->numNodes = 0;
+ /* use callocN to init all zero */
+ forest = MEM_callocN(sizeof(DagForest),"DAG root");
return forest;
}
-struct DagForest *build_dag(struct Scene *sce, short mask)
+struct DagForest *build_dag(struct Scene *sce, short mask)
{
Base *base;
Object *ob;
+ bConstraint *con;
DagNode * node;
DagNode * node2;
DagNode * node3;
@@ -299,130 +305,126 @@ struct DagForest *build_dag(struct Scene *sce, short mask)
sce->theDag = dag;
}
- // add base node for scene. scene is always the first node in DAG
+ /* add base node for scene. scene is always the first node in DAG */
scenenode = dag_add_node(dag, sce);
- /* targets in object struct yet to be added. should even they ?
- struct Ipo *ipo;
- ListBase nlastrips;
- ListBase hooks;
- */
-
-
- base = sce->base.first;
- while(base) { // add all objects in any case
+ for(base = sce->base.first; base; base= base->next) {
int addtoroot = 1;
ob= (Object *) base->object;
node = dag_get_node(dag,ob);
- if ((ob->data) && (mask&DAG_RL_DATA_MASK)) {
+ if ((ob->data) && (mask&DAG_RL_DATA)) {
node2 = dag_get_node(dag,ob->data);
dag_add_relation(dag,node,node2,DAG_RL_DATA);
node2->first_ancestor = ob;
node2->ancestor_count += 1;
- if ((ob->type == OB_ARMATURE) && (mask&DAG_RL_DATA_CONSTRAINT_MASK)) { // add armature constraints to datas
- if (ob->pose){
- bPoseChannel *pchan;
- bConstraint *con;
- Object * target;
-
- for (pchan = ob->pose->chanbase.first; pchan; pchan=pchan->next){
- for (con = pchan->constraints.first; con; con=con->next){
- if (constraint_has_target(con)) {
- target = get_constraint_target(con);
- if (strcmp(target->id.name, ob->id.name) != 0) {
- //fprintf(stderr,"armature target :%s \n", target->id.name);
- node3 = dag_get_node(dag,target);
- dag_add_relation(dag,node3,node2,DAG_RL_CONSTRAINT);
- }
- }
- }
- }
- }
- }
- if ((ob->hooks.first) && (mask&DAG_RL_HOOK)) {
- ObHook *hook;
+ }
+ if (ob->type == OB_ARMATURE) {
+ if (ob->pose){
+ bPoseChannel *pchan;
+ bConstraint *con;
+ Object * target;
+ char *subtarget;
- for(hook= ob->hooks.first; hook; hook= hook->next) {
- if(hook->parent) {
- node3 = dag_get_node(dag,hook->parent);
- dag_add_relation(dag,node3,node2,DAG_RL_HOOK);
- }
- }
- }
- } else { // add armature constraints to object itself
- if ((ob->type == OB_ARMATURE) && (mask&DAG_RL_DATA_CONSTRAINT_MASK)) {
- if (ob->pose){
- bPoseChannel *pchan;
- bConstraint *con;
- Object * target;
-
- for (pchan = ob->pose->chanbase.first; pchan; pchan=pchan->next){
- for (con = pchan->constraints.first; con; con=con->next){
- if (constraint_has_target(con)) {
- target = get_constraint_target(con);
- if (strcmp(target->id.name, ob->id.name) != 0) {
- //fprintf(stderr,"armature target :%s \n", target->id.name);
- node3 = dag_get_node(dag,target);
- dag_add_relation(dag,node3,node,DAG_RL_CONSTRAINT);
- }
+ for (pchan = ob->pose->chanbase.first; pchan; pchan=pchan->next){
+ for (con = pchan->constraints.first; con; con=con->next){
+ if (constraint_has_target(con)) {
+ target = get_constraint_target(con, &subtarget);
+ if (target!=ob) {
+ // fprintf(stderr,"armature %s target :%s \n", ob->id.name, target->id.name);
+ node3 = dag_get_node(dag, target);
+
+ dag_add_relation(dag,node3,node,DAG_RL_OB_DATA);
+
}
}
}
}
}
- if ((ob->hooks.first) && (mask&DAG_RL_HOOK)) {
- ObHook *hook;
-
- for(hook= ob->hooks.first; hook; hook= hook->next) {
- if(hook->parent) {
- node3 = dag_get_node(dag,hook->parent);
- dag_add_relation(dag,node3,node,DAG_RL_HOOK);
- }
+ }
+ if (ob->hooks.first) {
+ ObHook *hook;
+
+ for(hook= ob->hooks.first; hook; hook= hook->next) {
+ if(hook->parent) {
+ node3 = dag_get_node(dag,hook->parent);
+ dag_add_relation(dag,node3,node,DAG_RL_OB_DATA);
}
- }
+ }
}
-
- if ((ob->parent) && (mask&DAG_RL_PARENT_MASK)){
+ if (ob->parent) {
node2 = dag_get_node(dag,ob->parent);
- dag_add_relation(dag,node2,node,DAG_RL_PARENT);
+
+ switch(ob->partype) {
+ case PARSKEL:
+ dag_add_relation(dag,node2,node,DAG_RL_DATA_DATA|DAG_RL_OB_OB);
+ break;
+ case PARVERT1: case PARVERT3: case PARBONE:
+ dag_add_relation(dag,node2,node,DAG_RL_DATA_OB|DAG_RL_OB_OB);
+ break;
+ default:
+ if(ob->parent->type==OB_LATTICE)
+ dag_add_relation(dag,node2,node,DAG_RL_DATA_DATA|DAG_RL_OB_OB);
+ else if(ob->parent->type==OB_CURVE) {
+ Curve *cu= ob->parent->data;
+ if(cu->flag & CU_PATH)
+ dag_add_relation(dag,node2,node,DAG_RL_DATA_OB|DAG_RL_OB_OB);
+ else
+ dag_add_relation(dag,node2,node,DAG_RL_OB_OB);
+ }
+ else
+ dag_add_relation(dag,node2,node,DAG_RL_OB_OB);
+ }
addtoroot = 0;
}
- if ((ob->track) && (mask&DAG_RL_TRACK_MASK)){
+ if (ob->track) {
node2 = dag_get_node(dag,ob->track);
- dag_add_relation(dag,node2,node,DAG_RL_TRACK);
+ dag_add_relation(dag,node2,node,DAG_RL_OB_OB);
addtoroot = 0;
-
}
- if ((ob->path) && (mask&DAG_RL_PATH_MASK)){
- node2 = dag_get_node(dag,ob->track);
- dag_add_relation(dag,node2,node,DAG_RL_PATH);
- addtoroot = 0;
-
+ if (ob->type==OB_MBALL) {
+ Object *mom= find_basis_mball(ob);
+ if(mom!=ob) {
+ node2 = dag_get_node(dag, mom);
+ dag_add_relation(dag,node,node2,DAG_RL_DATA_DATA|DAG_RL_OB_DATA); // mom depends on children!
+ }
}
-
- /* Count constraints */
- if (mask & DAG_RL_CONSTRAINT_MASK) {
- bConstraint *con;
- for (con = ob->constraints.first; con; con=con->next){
- if (constraint_has_target(con)) {
- node2 = dag_get_node(dag,get_constraint_target(con));
- dag_add_relation(dag,node2,node,DAG_RL_CONSTRAINT);
- addtoroot = 0;
-
- }
+ else if (ob->type==OB_CURVE) {
+ Curve *cu= ob->data;
+ if(cu->bevobj) {
+ node2 = dag_get_node(dag, cu->bevobj);
+ dag_add_relation(dag,node2,node,DAG_RL_DATA_DATA|DAG_RL_OB_DATA);
}
- }
+ if(cu->taperobj) {
+ node2 = dag_get_node(dag, cu->taperobj);
+ dag_add_relation(dag,node2,node,DAG_RL_DATA_DATA|DAG_RL_OB_DATA);
+ }
+ }
+ else if(ob->type==OB_FONT) {
+ Curve *cu= ob->data;
+ if(cu->textoncurve) {
+ node2 = dag_get_node(dag, cu->textoncurve);
+ dag_add_relation(dag,node2,node,DAG_RL_DATA_DATA|DAG_RL_OB_DATA);
+ }
+ }
+ for (con = ob->constraints.first; con; con=con->next){
+ if (constraint_has_target(con)) {
+ char *str;
+ node2 = dag_get_node(dag, get_constraint_target(con, &str));
+ if(con->type==CONSTRAINT_TYPE_FOLLOWPATH)
+ dag_add_relation(dag, node2, node, DAG_RL_DATA_OB|DAG_RL_OB_OB);
+ else
+ dag_add_relation(dag, node2, node, DAG_RL_OB_OB);
+ addtoroot = 0;
+ }
+ }
if (addtoroot == 1 )
dag_add_relation(dag,scenenode,node,DAG_RL_SCENE);
-
- addtoroot = 1;
- base= base->next;
}
// cycle detection and solving
@@ -458,18 +460,20 @@ void free_forest(DagForest *Dag)
DagNode * dag_find_node (DagForest *forest,void * fob)
{
- DagNode *node = forest->DagNode.first;
-
- while (node) {
- if (node->ob == fob)
- return node;
- node = node->next;
- }
- return NULL;
+ DagNode *node = forest->DagNode.first;
+
+ while (node) {
+ if (node->ob == fob)
+ return node;
+ node = node->next;
+ }
+ return NULL;
}
+static int ugly_hack_sorry= 1; // prevent type check
+
/* no checking of existance, use dag_find_node first or dag_get_node */
-DagNode * dag_add_node (DagForest *forest,void * fob)
+DagNode * dag_add_node (DagForest *forest, void * fob)
{
DagNode *node;
@@ -486,7 +490,7 @@ DagNode * dag_add_node (DagForest *forest,void * fob)
node->first_ancestor = NULL;
node->ancestor_count = 0;
- node->type = GS(((ID *) fob)->name);
+ if(ugly_hack_sorry) node->type = GS(((ID *) fob)->name); // sorry, done for pose sorting
if (forest->numNodes) {
((DagNode *) forest->DagNode.last)->next = node;
forest->DagNode.last = node;
@@ -540,7 +544,7 @@ DagNode * dag_get_sub_node (DagForest *forest,void * fob)
return node;
}
-void dag_add_relation(DagForest *forest, DagNode *fob1, DagNode *fob2, dag_rel_type rel)
+void dag_add_relation(DagForest *forest, DagNode *fob1, DagNode *fob2, short rel)
{
DagAdjList *itA = fob1->child;
@@ -846,6 +850,7 @@ DagNodeQueue * graph_dfs(void)
return(retqueue);
}
+/* unused */
int pre_and_post_DFS(DagForest *dag, short mask, graph_action_func pre_func, graph_action_func post_func, void **data) {
DagNode *node;
@@ -933,84 +938,6 @@ int pre_and_post_source_DFS(DagForest *dag, short mask, DagNode *source, graph_a
return(retval);
}
-// sort the base list on place
-void topo_sort_baselist(struct Scene *sce){
- DagNode *node;
- DagNodeQueue *nqueue;
- DagAdjList *itA;
- int time;
- int skip = 0;
- ListBase tempbase;
- Base *base;
-
- tempbase.first= tempbase.last= 0;
-
- build_dag(sce,DAG_RL_ALL_BUT_DATA_MASK);
-
- nqueue = queue_create(DAGQUEUEALLOC);
-
- node = sce->theDag->DagNode.first;
- while(node) {
- node->color = DAG_WHITE;
- node = node->next;
- }
-
- time = 1;
-
- node = sce->theDag->DagNode.first;
-
- node->color = DAG_GRAY;
- time++;
- push_stack(nqueue,node);
-
- while(nqueue->count) {
-
- skip = 0;
- node = get_top_node_queue(nqueue);
-
- itA = node->child;
- while(itA != NULL) {
- if((itA->node->color == DAG_WHITE) ) {
- itA->node->DFS_dvtm = time;
- itA->node->color = DAG_GRAY;
-
- time++;
- push_stack(nqueue,itA->node);
- skip = 1;
- break;
- }
- itA = itA->next;
- }
-
- if (!skip) {
- if (node) {
- node = pop_queue(nqueue);
- if (node->ob == sce) // we are done
- break ;
- node->color = DAG_BLACK;
-
- time++;
- base = sce->base.first;
- while (base->object != node->ob)
- base = base->next;
- BLI_remlink(&sce->base,base);
- BLI_addhead(&tempbase,base);
- }
- }
- }
-
- // temporal correction for circular dependancies
- base = sce->base.first;
- while (base) {
- BLI_remlink(&sce->base,base);
- BLI_addhead(&tempbase,base);
- base = sce->base.first;
- }
-
- sce->base = tempbase;
- queue_delete(nqueue);
-}
-
// used to get the obs owning a datablock
struct DagNodeQueue *get_obparents(struct DagForest *dag, void *ob)
@@ -1020,7 +947,10 @@ struct DagNodeQueue *get_obparents(struct DagForest *dag, void *ob)
DagAdjList *itA;
node = dag_find_node(dag,ob);
- if (node->ancestor_count == 1) { // simple case
+ if(node==NULL) {
+ return NULL;
+ }
+ else if (node->ancestor_count == 1) { // simple case
nqueue = queue_create(1);
push_queue(nqueue,node);
} else { // need to go over the whole dag for adj list
@@ -1082,7 +1012,7 @@ struct DagNodeQueue *get_all_childs(struct DagForest *dag, void *ob)
int skip = 0;
nqueue = queue_create(DAGQUEUEALLOC);
- retqueue = queue_create(MainDag->numNodes);
+ retqueue = queue_create(dag->numNodes); // was MainDag... why? (ton)
node = dag->DagNode.first;
while(node) {
@@ -1092,45 +1022,47 @@ struct DagNodeQueue *get_all_childs(struct DagForest *dag, void *ob)
time = 1;
- node = dag_find_node(dag,ob);
-
- node->color = DAG_GRAY;
- time++;
- push_stack(nqueue,node);
-
- while(nqueue->count) {
+ node = dag_find_node(dag,ob); // could be done in loop above (ton)
+ if(node) { // can be null for newly added objects
- skip = 0;
- node = get_top_node_queue(nqueue);
-
- itA = node->child;
- while(itA != NULL) {
- if((itA->node->color == DAG_WHITE) ) {
- itA->node->DFS_dvtm = time;
- itA->node->color = DAG_GRAY;
-
- time++;
- push_stack(nqueue,itA->node);
- skip = 1;
- break;
- }
- itA = itA->next;
- }
+ node->color = DAG_GRAY;
+ time++;
+ push_stack(nqueue,node);
- if (!skip) {
- node = pop_queue(nqueue);
- node->color = DAG_BLACK;
+ while(nqueue->count) {
- time++;
- push_stack(retqueue,node);
+ skip = 0;
+ node = get_top_node_queue(nqueue);
+
+ itA = node->child;
+ while(itA != NULL) {
+ if((itA->node->color == DAG_WHITE) ) {
+ itA->node->DFS_dvtm = time;
+ itA->node->color = DAG_GRAY;
+
+ time++;
+ push_stack(nqueue,itA->node);
+ skip = 1;
+ break;
+ }
+ itA = itA->next;
+ }
+
+ if (!skip) {
+ node = pop_queue(nqueue);
+ node->color = DAG_BLACK;
+
+ time++;
+ push_stack(retqueue,node);
+ }
}
}
-
queue_delete(nqueue);
return(retqueue);
}
-dag_rel_type are_obs_related(struct DagForest *dag, void *ob1, void *ob2) {
+/* unused */
+short are_obs_related(struct DagForest *dag, void *ob1, void *ob2) {
DagNode * node;
DagAdjList *itA;
@@ -1211,4 +1143,434 @@ void graph_print_adj_list(void)
}
}
+/* ************************ API *********************** */
+
+/* sort the base list on dependency order */
+void DAG_scene_sort(struct Scene *sce)
+{
+ DagNode *node;
+ DagNodeQueue *nqueue;
+ DagAdjList *itA;
+ int time;
+ int skip = 0;
+ ListBase tempbase;
+ Base *base;
+
+ tempbase.first= tempbase.last= NULL;
+
+ build_dag(sce, DAG_RL_ALL_BUT_DATA);
+
+ nqueue = queue_create(DAGQUEUEALLOC);
+
+ node = sce->theDag->DagNode.first;
+ while(node) {
+ node->color = DAG_WHITE;
+ node = node->next;
+ }
+
+ time = 1;
+
+ node = sce->theDag->DagNode.first;
+
+ node->color = DAG_GRAY;
+ time++;
+ push_stack(nqueue,node);
+
+ while(nqueue->count) {
+
+ skip = 0;
+ node = get_top_node_queue(nqueue);
+
+ itA = node->child;
+ while(itA != NULL) {
+ if((itA->node->color == DAG_WHITE) ) {
+ itA->node->DFS_dvtm = time;
+ itA->node->color = DAG_GRAY;
+
+ time++;
+ push_stack(nqueue,itA->node);
+ skip = 1;
+ break;
+ }
+ itA = itA->next;
+ }
+
+ if (!skip) {
+ if (node) {
+ node = pop_queue(nqueue);
+ if (node->ob == sce) // we are done
+ break ;
+ node->color = DAG_BLACK;
+
+ time++;
+ base = sce->base.first;
+ while (base->object != node->ob)
+ base = base->next;
+ BLI_remlink(&sce->base,base);
+ BLI_addhead(&tempbase,base);
+ }
+ }
+ }
+
+ // temporal correction for circular dependancies
+ base = sce->base.first;
+ while (base) {
+ BLI_remlink(&sce->base,base);
+ BLI_addhead(&tempbase,base);
+ //if(G.f & G_DEBUG)
+ printf("cyclic %s\n", base->object->id.name);
+ base = sce->base.first;
+ }
+
+ sce->base = tempbase;
+ queue_delete(nqueue);
+
+ if(G.f & G_DEBUG) {
+ printf("\nordered\n");
+ for(base = sce->base.first; base; base= base->next) {
+ printf(" %s\n", base->object->id.name);
+ }
+ }
+}
+
+/* node was checked to have lasttime != curtime and is if type ID_OB */
+static void flush_update_node(DagNode *node, unsigned int layer, int curtime)
+{
+ DagAdjList *itA;
+ Object *ob, *obc;
+ int oldflag, changed=0;
+ unsigned int all_layer;
+
+ node->lasttime= curtime;
+
+ ob= node->ob;
+ if(ob->recalc & OB_RECALC) {
+ all_layer= ob->lay;
+ /* got an object node that changes, now check relations */
+ for(itA = node->child; itA; itA= itA->next) {
+ all_layer |= itA->lay;
+ /* the relationship is visible */
+ if(itA->lay & layer) {
+ if(itA->node->type==ID_OB) {
+ obc= itA->node->ob;
+ oldflag= obc->recalc;
+
+ /* got a ob->obc relation, now check if flag needs flush */
+ if(ob->recalc & OB_RECALC_OB) {
+ if(itA->type & DAG_RL_OB_OB) {
+ //printf("ob %s changes ob %s\n", ob->id.name, obc->id.name);
+ obc->recalc |= OB_RECALC_OB;
+ }
+ if(itA->type & DAG_RL_OB_DATA) {
+ //printf("ob %s changes obdata %s\n", ob->id.name, obc->id.name);
+ obc->recalc |= OB_RECALC_DATA;
+ }
+ }
+ if(ob->recalc & OB_RECALC_DATA) {
+ if(itA->type & DAG_RL_DATA_OB) {
+ //printf("obdata %s changes ob %s\n", ob->id.name, obc->id.name);
+ obc->recalc |= OB_RECALC_OB;
+ }
+ if(itA->type & DAG_RL_DATA_DATA) {
+ //printf("obdata %s changes obdata %s\n", ob->id.name, obc->id.name);
+ obc->recalc |= OB_RECALC_DATA;
+ }
+ }
+ if(oldflag!=obc->recalc) changed= 1;
+ }
+ }
+ }
+ /* even nicer, we can clear recalc flags... but we don't for armatures, these can have poses that need pointer checks (read old file issue) */
+ if(ob->type!=OB_ARMATURE)
+ if((all_layer & layer)==0)
+ ob->recalc &= ~OB_RECALC;
+ }
+ else{
+ /* Object has not RECALC flag */
+ /* check case where child changes and parent forcing obdata to change */
+ /* could merge this in with loop above... (ton) */
+ for(itA = node->child; itA; itA= itA->next) {
+ /* the relationship is visible */
+ if(itA->lay & layer) {
+ if(itA->node->type==ID_OB) {
+ obc= itA->node->ob;
+ /* child moves */
+ if((obc->recalc & OB_RECALC)==OB_RECALC_OB) {
+ /* parent has deforming info */
+ if(itA->type & (DAG_RL_OB_DATA|DAG_RL_DATA_DATA)) {
+ // printf("parent %s changes ob %s\n", ob->id.name, obc->id.name);
+ obc->recalc |= OB_RECALC_DATA;
+ }
+ }
+ }
+ }
+ }
+ }
+ /* we only go deeper if node not checked or something changed */
+ for(itA = node->child; itA; itA= itA->next) {
+ if(changed || itA->node->lasttime!=curtime)
+ flush_update_node(itA->node, layer, curtime);
+ }
+}
+
+/* node was checked to have lasttime != curtime , and is of type ID_OB */
+static unsigned int flush_layer_node(DagNode *node, int curtime)
+{
+ DagAdjList *itA;
+
+ node->lasttime= curtime;
+ node->lay= ((Object *)node->ob)->lay;
+
+ for(itA = node->child; itA; itA= itA->next) {
+ if(itA->node->type==ID_OB) {
+ if(itA->node->lasttime!=curtime) {
+ itA->lay= flush_layer_node(itA->node, curtime); // lay is only set once for each relation
+ //printf("layer %d for relation %s to %s\n", itA->lay, ((Object *)node->ob)->id.name, ((Object *)itA->node->ob)->id.name);
+ }
+ else itA->lay= itA->node->lay;
+
+ node->lay |= itA->lay;
+ }
+ }
+
+ return node->lay;
+}
+
+/* flushes all recalc flags in objects down the dependency tree */
+void DAG_scene_flush_update(Scene *sce)
+{
+ DagNode *firstnode;
+ DagAdjList *itA;
+ int lasttime;
+
+ firstnode= sce->theDag->DagNode.first; // always scene node
+
+ /* first we flush the layer flags */
+ sce->theDag->time++; // so we know which nodes were accessed
+ lasttime= sce->theDag->time;
+ for(itA = firstnode->child; itA; itA= itA->next) {
+ if(itA->node->lasttime!=lasttime && itA->node->type==ID_OB)
+ flush_layer_node(itA->node, lasttime);
+ }
+
+ /* then we use the relationships + layer info to flush update events */
+ sce->theDag->time++; // so we know which nodes were accessed
+ lasttime= sce->theDag->time;
+ for(itA = firstnode->child; itA; itA= itA->next) {
+ if(itA->node->lasttime!=lasttime && itA->node->type==ID_OB)
+ flush_update_node(itA->node, sce->lay, lasttime);
+ }
+}
+
+/* flag all objects that need recalc, for changes in time for example */
+void DAG_scene_update_flags(Scene *sce, unsigned int lay)
+{
+ Base *base;
+ Object *ob;
+
+ /* set ob flags where animated systems are */
+ for(base= sce->base.first; base; base= base->next) {
+
+ /* now if DagNode were part of base, the node->lay could be checked... */
+ /* we do all now, since the scene_flush checks layers */
+ //if((base->lay & lay)) {
+ ob= base->object;
+
+ if(ob->ipo) ob->recalc |= OB_RECALC_OB;
+ else if(ob->constraints.first) ob->recalc |= OB_RECALC_OB;
+ else if(ob->scriptlink.totscript) ob->recalc |= OB_RECALC_OB;
+ else if(ob->parent) {
+ if(ob->parent->type==OB_CURVE) ob->recalc |= OB_RECALC_OB;
+ }
+
+ if(ob->action) ob->recalc |= OB_RECALC_DATA;
+ else if(ob->nlastrips.first) ob->recalc |= OB_RECALC_DATA;
+ else if(ob->softflag & OB_SB_ENABLE) ob->recalc |= OB_RECALC_DATA;
+ else {
+ Mesh *me;
+ Curve *cu;
+ Lattice *lt;
+
+ switch(ob->type) {
+ case OB_MESH:
+ me= ob->data;
+ if(me->key) ob->recalc |= OB_RECALC_DATA;
+ else if(ob->effect.first) {
+ Effect *eff= ob->effect.first;
+ if(eff->type==EFF_WAVE) ob->recalc |= OB_RECALC_DATA;
+ }
+ break;
+ case OB_CURVE:
+ case OB_SURF:
+ cu= ob->data;
+ if(cu->key) ob->recalc |= OB_RECALC_DATA;
+ break;
+ case OB_LATTICE:
+ lt= ob->data;
+ if(lt->key) ob->recalc |= OB_RECALC_DATA;
+ break;
+ }
+ }
+ //}
+ }
+ DAG_scene_flush_update(sce);
+}
+
+/* flag this object and all its relations to recalc */
+/* if you need to do more objects, tag object yourself and
+ use DAG_scene_flush_update() in end */
+void DAG_object_flush_update(Scene *sce, Object *ob, short flag)
+{
+ Base *base;
+
+ if(ob==NULL) return;
+ ob->recalc |= flag;
+
+ /* all users of this ob->data should be checked */
+ if(flag & OB_RECALC_DATA) {
+ ID *id= ob->data;
+ if(id && id->us>1) {
+ for (base= sce->base.first; base; base= base->next) {
+ if (ob->data==base->object->data) {
+ base->object->recalc |= OB_RECALC_DATA;
+ }
+ }
+ }
+ }
+
+ DAG_scene_flush_update(sce);
+}
+
+/* ******************* DAG FOR ARMATURE POSE ***************** */
+
+/* we assume its an armature with pose */
+void DAG_pose_sort(Object *ob)
+{
+ bPose *pose= ob->pose;
+ bPoseChannel *pchan;
+ bConstraint *con;
+ DagNode *node;
+ DagNode *node2, *node3;
+ DagNode *rootnode;
+ DagForest *dag;
+ DagNodeQueue *nqueue;
+ DagAdjList *itA;
+ ListBase tempbase;
+ int skip = 0;
+
+ dag = dag_init();
+ ugly_hack_sorry= 0; // no ID structs
+
+ rootnode = dag_add_node(dag, NULL); // node->ob becomes NULL
+
+ /* we add the hierarchy and the constraints */
+ for(pchan = pose->chanbase.first; pchan; pchan= pchan->next) {
+ int addtoroot = 1;
+
+ node = dag_get_node(dag, pchan);
+
+ if(pchan->parent) {
+ node2 = dag_get_node(dag, pchan->parent);
+ dag_add_relation(dag, node2, node, 0);
+ addtoroot = 0;
+ }
+ for (con = pchan->constraints.first; con; con=con->next){
+ if (constraint_has_target(con)) {
+ char *subtarget;
+ Object *target = get_constraint_target(con, &subtarget);
+
+ if (target==ob && subtarget) {
+ bPoseChannel *target= get_pose_channel(ob->pose, subtarget);
+ if(target) {
+ node2= dag_get_node(dag, target);
+ dag_add_relation(dag, node2, node, 0);
+
+ if(con->type==CONSTRAINT_TYPE_KINEMATIC) {
+ bPoseChannel *par= pchan->parent;
+
+ while(par) {
+ node3= dag_get_node(dag, par);
+ dag_add_relation(dag, node2, node3, 0);
+
+ if(par->bone->flag & BONE_IK_TOPARENT)
+ par= par->parent;
+ else break;
+ }
+ }
+ }
+ }
+ }
+ }
+ if (addtoroot == 1 )
+ dag_add_relation(dag, rootnode, node, 0);
+ }
+
+ /* now we try to sort... */
+ tempbase.first= tempbase.last= NULL;
+
+ nqueue = queue_create(DAGQUEUEALLOC);
+
+ /* tag nodes unchecked */
+ for(node = dag->DagNode.first; node; node= node->next)
+ node->color = DAG_WHITE;
+
+ node = dag->DagNode.first;
+
+ node->color = DAG_GRAY;
+ push_stack(nqueue, node);
+
+ while(nqueue->count) {
+
+ skip = 0;
+ node = get_top_node_queue(nqueue);
+
+ itA = node->child;
+ while(itA != NULL) {
+ if((itA->node->color == DAG_WHITE) ) {
+ itA->node->color = DAG_GRAY;
+ push_stack(nqueue,itA->node);
+ skip = 1;
+ break;
+ }
+ itA = itA->next;
+ }
+
+ if (!skip) {
+ if (node) {
+ node = pop_queue(nqueue);
+ if (node->ob == NULL) // we are done
+ break ;
+ node->color = DAG_BLACK;
+
+ /* put node in new list */
+ BLI_remlink(&pose->chanbase, node->ob);
+ BLI_addhead(&tempbase, node->ob);
+ }
+ }
+ }
+
+ // temporal correction for circular dependancies
+ while(pose->chanbase.first) {
+ pchan= pose->chanbase.first;
+ BLI_remlink(&pose->chanbase, pchan);
+ BLI_addhead(&tempbase, pchan);
+
+ printf("cyclic %s\n", pchan->name);
+ }
+
+ pose->chanbase = tempbase;
+ queue_delete(nqueue);
+
+// printf("\nordered\n");
+// for(pchan = pose->chanbase.first; pchan; pchan= pchan->next) {
+// printf(" %s\n", pchan->name);
+// }
+
+ free_forest( dag );
+ MEM_freeN( dag );
+
+ ugly_hack_sorry= 1;
+}
+
+
diff --git a/source/blender/blenkernel/intern/displist.c b/source/blender/blenkernel/intern/displist.c
index 3e4c670dd04..b2876260c15 100644
--- a/source/blender/blenkernel/intern/displist.c
+++ b/source/blender/blenkernel/intern/displist.c
@@ -238,24 +238,6 @@ void freedisplist(ListBase *lb)
}
}
-static void freedisplist_object(Object *ob)
-{
- freedisplist(&ob->disp);
-
- if(ob->type==OB_MESH) {
- Mesh *me= ob->data;
- freedisplist(&me->disp);
- if (me->derived) {
- me->derived->release(me->derived);
- me->derived = NULL;
- }
- }
- else if(ob->type==OB_CURVE || ob->type==OB_SURF || ob->type==OB_FONT) {
- Curve *cu= ob->data;
- freedisplist(&cu->disp);
- }
-}
-
DispList *find_displist_create(ListBase *lb, int type)
{
DispList *dl;
@@ -1661,12 +1643,12 @@ void makeDispList(Object *ob)
if (ob!=G.obedit) mesh_modifier(ob, 'e');
}
else if(ob->type==OB_MBALL) {
- ob= find_basis_mball(ob);
+ if(ob==find_basis_mball(ob)) {
+ metaball_polygonize(ob);
+ tex_space_mball(ob);
- metaball_polygonize(ob);
- tex_space_mball(ob);
-
- object_deform(ob);
+ object_deform(ob);
+ }
}
else if(ob->type==OB_SURF) {
@@ -1760,6 +1742,7 @@ void makeDispList(Object *ob)
if(ob!=G.obedit) object_deform(ob);
}
else if ELEM(ob->type, OB_CURVE, OB_FONT) {
+ int obedit= (G.obedit && G.obedit->data==ob->data);
draw= ob->dt;
cu= ob->data;
@@ -1767,21 +1750,23 @@ void makeDispList(Object *ob)
if(dl_onlyzero && dispbase->first) return;
freedisplist(dispbase);
+ BLI_freelistN(&(cu->bev));
+
if(cu->path) free_path(cu->path);
- cu->path= 0;
+ cu->path= NULL;
- BLI_freelistN(&(cu->bev));
+ if(ob->type==OB_FONT) text_to_curve(ob, 0);
- if(ob!=G.obedit) curve_modifier(ob, 's');
+ if(!obedit) curve_modifier(ob, 's');
- if(ob==G.obedit) {
+ if(obedit) {
if(ob->type==OB_CURVE) curve_to_displist(&editNurb, dispbase);
else curve_to_displist(&cu->nurb, dispbase);
- if(cu->flag & CU_PATH) makeBevelList(ob);
+ makeBevelList(ob); // always needed, so calc_curvepath() can work
}
else if(cu->ext1==0.0 && cu->ext2==0.0 && cu->bevobj==NULL && cu->width==1.0) {
curve_to_displist(&cu->nurb, dispbase);
- if(cu->flag & CU_PATH) makeBevelList(ob);
+ makeBevelList(ob); // always needed, so calc_curvepath() can work
}
else {
@@ -1893,10 +1878,12 @@ void makeDispList(Object *ob)
freedisplist(&dlbev);
}
}
+ if(cu->flag & CU_PATH) calc_curvepath(ob);
- if(ob!=G.obedit) curve_modifier(ob, 'e');
- if(ob!=G.obedit) object_deform(ob);
-
+ if(!obedit) {
+ curve_modifier(ob, 'e');
+ object_deform(ob);
+ }
tex_space_curve(cu);
}
@@ -2203,142 +2190,6 @@ void imagestodisplist(void)
allqueue(REDRAWVIEW3D, 0);
}
-/* on frame change */
-/* new method: only frees displists, and relies on
- drawobject.c & convertscene.c to build it when needed
-*/
-void test_all_displists(void)
-{
- Base *base;
- Object *ob;
- unsigned int lay;
- int makedisp, freedisp;
-
- /* background */
- lay= G.scene->lay;
-
- /* clear flags, we use them because parent->parents are evaluated too */
- base= G.scene->base.first;
- while(base) {
- if(base->lay & lay) {
- base->object->flag &= ~(BA_DISP_UPDATE|BA_WHERE_UPDATE);
- }
- if(base->next==0 && G.scene->set && base==G.scene->base.last) base= G.scene->set->base.first;
- else base= base->next;
- }
-
- base= G.scene->base.first;
- while(base) {
- if(base->lay & lay) {
- ob= base->object;
- makedisp= freedisp= 0;
-
- if(ob->type==OB_MBALL && (ob->ipo || ob->parent)) {
- // find metaball object holding the displist
- // WARNING: if more metaballs have IPO's the displist
- // is recalculated to often... do we free the displist
- // and rely on the drawobject.c to build it again when needed
-
- if(ob->disp.first == NULL) {
- ob= find_basis_mball(ob);
- }
- makedisp= 1;
- }
- else if(ob->parent) {
-
- if (ob->parent->type == OB_LATTICE)
- freedisp= 1;
- else if ((ob->parent->type==OB_ARMATURE) && (ob->partype == PARSKEL))
- makedisp= 1;
- else if(ob->softflag & OB_SB_ENABLE)
- makedisp= 1;
- else if ((ob->parent->type==OB_CURVE) && (ob->partype == PARSKEL))
- freedisp= 1;
- else if(ob->partype==PARVERT1 || ob->partype==PARVERT3) {
- if(ob->parent->parent)
- ob->parent->flag |= BA_DISP_UPDATE;
- else if(ob->parent->effect.first) // stupid test for wave
- ob->parent->flag |= BA_DISP_UPDATE;
- }
- }
-
- if(ob->hooks.first) {
- ObHook *hook;
- for(hook= ob->hooks.first; hook; hook= hook->next) {
- if(hook->parent)
- freedisp= 1;
- break;
- }
- }
-
- if(ob->softflag & OB_SB_ENABLE) freedisplist_object(ob);
- /* warn, ob pointer changed in case of OB_MALL */
-
- if ELEM(ob->type, OB_CURVE, OB_SURF) {
- if(ob!=G.obedit) {
- Curve *cu= ob->data;
-
- if(cu->key ) makedisp= 1;
- if(cu->bevobj) {
- Curve *cu1= cu->bevobj->data;
- if(cu1->key ) freedisp= 1;
- }
- if(cu->taperobj) {
- Curve *cu1= cu->taperobj->data;
- if(cu1->key ) freedisp= 1;
- }
- }
- }
- else if(ob->type==OB_FONT) {
- Curve *cu= ob->data;
- if(cu->textoncurve) {
- if( ((Curve *)cu->textoncurve->data)->key ) {
- text_to_curve(ob, 0);
- freedisp= 1;
- }
- }
- }
- else if(ob->type==OB_MESH) {
- if(ob->effect.first) {
- Effect *eff= ob->effect.first;
- while(eff) {
- if(eff->type==EFF_WAVE) {
- freedisp= 1;
- break;
- }
- eff= eff->next;
- }
- }
- if(ob!=G.obedit) {
- if(( ((Mesh *)(ob->data))->key ))
- freedisp= 1;
- }
- }
- if(freedisp) ob->flag |= BA_WHERE_UPDATE;
- if(makedisp) ob->flag |= BA_DISP_UPDATE;
- }
- if(base->next==0 && G.scene->set && base==G.scene->base.last) base= G.scene->set->base.first;
- else base= base->next;
- }
-
- /* going over the flags to free or make displists */
- base= G.scene->base.first;
- while(base) {
- if(base->lay & lay) {
- ob= base->object;
- if(ob->flag & BA_DISP_UPDATE) {
- where_is_object(ob);
- makeDispList(ob);
- }
- else if(ob->flag & BA_WHERE_UPDATE) freedisplist_object(ob);
- }
- if(base->next==0 && G.scene->set && base==G.scene->base.last) base= G.scene->set->base.first;
- else base= base->next;
- }
-
-}
-
-
void boundbox_displist(Object *ob)
{
BoundBox *bb=0;
diff --git a/source/blender/blenkernel/intern/effect.c b/source/blender/blenkernel/intern/effect.c
index dc2594079f2..aca3d38a98e 100644
--- a/source/blender/blenkernel/intern/effect.c
+++ b/source/blender/blenkernel/intern/effect.c
@@ -1314,7 +1314,7 @@ void build_particle_system(Object *ob)
do_ob_key(par);
if(par->type==OB_ARMATURE) {
do_all_actions(par); // only does this object actions
- clear_object_constraint_status(par); // mysterious call, otherwise do_actions doesnt work???
+// clear_object_constraint_status(par); // mysterious call, otherwise do_actions doesnt work???
}
par= par->parent;
}
@@ -1394,7 +1394,7 @@ void build_particle_system(Object *ob)
if(par->type==OB_ARMATURE) {
do_all_actions(par); // only does this object actions
- clear_object_constraint_status(par); // mysterious call, otherwise do_actions doesnt work???
+// clear_object_constraint_status(par); // mysterious call, otherwise do_actions doesnt work???
}
par= par->parent;
}
diff --git a/source/blender/blenkernel/intern/exotic.c b/source/blender/blenkernel/intern/exotic.c
index a371edcf954..b49143ff48f 100644
--- a/source/blender/blenkernel/intern/exotic.c
+++ b/source/blender/blenkernel/intern/exotic.c
@@ -1028,7 +1028,6 @@ static void read_videoscape_nurbs(char *str)
}
}
fclose(fp);
- makeDispList(ob);
}
static void read_videoscape(char *str)
diff --git a/source/blender/blenkernel/intern/font.c b/source/blender/blenkernel/intern/font.c
index 5305dfb56ec..61869e47040 100644
--- a/source/blender/blenkernel/intern/font.c
+++ b/source/blender/blenkernel/intern/font.c
@@ -510,8 +510,6 @@ struct chartrans *text_to_curve(Object *ob, int mode)
ct++;
}
-
-
cu->lines= 1;
ct= chartransdata;
for (i= 0; i<=slen; i++, mem++, ct++) {
@@ -562,7 +560,7 @@ struct chartrans *text_to_curve(Object *ob, int mode)
oldflag= cucu->flag;
cucu->flag |= (CU_PATH+CU_FOLLOW);
- if(cucu->path==0) calc_curvepath(cu->textoncurve);
+ if(cucu->path==NULL) makeDispList(cu->textoncurve);
if(cucu->path) {
diff --git a/source/blender/blenkernel/intern/ika.c b/source/blender/blenkernel/intern/ika.c
deleted file mode 100644
index 32903590043..00000000000
--- a/source/blender/blenkernel/intern/ika.c
+++ /dev/null
@@ -1,596 +0,0 @@
-
-/* ika.c
- *
- *
- * $Id$
- *
- * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
- *
- * 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. The Blender
- * Foundation also sells licenses for use in proprietary software under
- * the Blender License. See http://www.blender.org/BL/ for information
- * about this.
- *
- * 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,
- * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
- *
- * ***** END GPL/BL DUAL LICENSE BLOCK *****
- */
-
-#include <math.h>
-#include <stdlib.h>
-
-#include "MEM_guardedalloc.h"
-
-/* types */
-#include "DNA_ika_types.h"
-#include "DNA_object_types.h"
-#include "DNA_scene_types.h"
-#include "DNA_view3d_types.h"
-
-#include "BLI_blenlib.h"
-#include "BLI_arithb.h"
-/* functions */
-#include "BKE_blender.h"
-#include "BKE_library.h"
-#include "BKE_global.h"
-#include "BKE_main.h"
-#include "BKE_object.h"
-#include "BKE_ika.h"
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-/* Let's go! */
-#define TOLER 0.000076
-#define CLAMP(a, b, c) if((a)<(b)) (a)=(b); else if((a)>(c)) (a)=(c)
-
-
-void unlink_ika(Ika *ika)
-{
-
-
-}
-
-/* do not free Ika itself */
-void free_ika(Ika *ika)
-{
-
- /* unimplemented!!! */
- unlink_ika(ika);
-
- BLI_freelistN(&ika->limbbase);
-
- if(ika->def) MEM_freeN(ika->def);
-}
-
-Ika *add_ika()
-{
- Ika *ika;
-
- ika= alloc_libblock(&G.main->ika, ID_IK, "Ika");
- ika->flag = IK_GRABEFF | IK_XYCONSTRAINT;
-
- ika->xyconstraint= 0.5f;
- ika->mem= 0.3f;
- ika->iter= 6;
-
- return ika;
-}
-
-Ika *copy_ika(Ika *ika)
-{
- Ika *ikan;
-
- ikan= copy_libblock(ika);
-
- duplicatelist(&ikan->limbbase, &ika->limbbase);
-
- ikan->def= MEM_dupallocN(ikan->def);
-
- return ikan;
-}
-
-void make_local_ika(Ika *ika)
-{
- Object *ob;
- Ika *ikan;
- int local=0, lib=0;
-
- /* - only lib users: dont do
- * - only local users: set flag
- * - mixed: copy
- */
-
- if(ika->id.lib==0) return;
- if(ika->id.us==1) {
- ika->id.lib= 0;
- ika->id.flag= LIB_LOCAL;
- new_id(0, (ID *)ika, 0);
- return;
- }
-
- ob= G.main->object.first;
- while(ob) {
- if(ob->data==ika) {
- if(ob->id.lib) lib= 1;
- else local= 1;
- }
- ob= ob->id.next;
- }
-
- if(local && lib==0) {
- ika->id.lib= 0;
- ika->id.flag= LIB_LOCAL;
- new_id(0, (ID *)ika, 0);
- }
- else if(local && lib) {
- ikan= copy_ika(ika);
- ikan->id.us= 0;
-
- ob= G.main->object.first;
- while(ob) {
- if(ob->data==ika) {
-
- if(ob->id.lib==0) {
- ob->data= ikan;
- ikan->id.us++;
- ika->id.us--;
- }
- }
- ob= ob->id.next;
- }
- }
-}
-
-int count_limbs(Object *ob)
-{
- int tot=0;
- Ika *ika;
- Limb *li;
-
- if(ob->type!=OB_IKA) return 0;
- ika= ob->data;
-
- li= ika->limbbase.first;
- while(li) {
- tot++;
- li= li->next;
- }
- return tot;
-}
-
-/* ************************************************** */
-
-
-/* using eff[ ] and len and alpha */
-void calc_limb(Limb *li)
-{
- Limb *prev= li;
- float vec[2], alpha= 0.0;
-
- /* alpha from 'parents' */
- while( (prev=prev->prev) ) {
- alpha+= prev->alpha;
- }
-
- if(li->prev) {
- vec[0]= -li->prev->eff[0];
- vec[1]= -li->prev->eff[1];
- }
- else vec[0]= vec[1]= 0.0;
-
- vec[0]+= li->eff[0];
- vec[1]+= li->eff[1];
-
- li->alpha= (float)atan2(vec[1], vec[0]) - alpha;
- li->len= (float)sqrt(vec[0]*vec[0] + vec[1]*vec[1]);
-
-}
-
-/* using len and alpha the endpoints are calculated */
-void calc_ika(Ika *ika, Limb *li)
-{
- float alpha=0.0, co, si;
-
- if(li) {
- Limb *prev= li;
- while((prev=prev->prev)) {
- alpha+= prev->alpha;
- }
- }
- else li= ika->limbbase.first;
-
- while(li) {
- if(li->alpha != li->alpha) li->alpha= 0.0f; /* NaN patch */
-
- alpha+= li->alpha;
-
- co= (float)cos(alpha);
- si= (float)sin(alpha);
-
- li->eff[0]= co*li->len;
- li->eff[1]= si*li->len;
-
- if(li->prev) {
- li->eff[0]+= li->prev->eff[0];
- li->eff[1]+= li->prev->eff[1];
- }
-
- if(li->next==0) {
- ika->eff[0]= li->eff[0];
- ika->eff[1]= li->eff[1];
- }
-
- li= li->next;
- }
-}
-
-void init_defstate_ika(Object *ob)
-{
- Ika *ika;
- Limb *li;
-
- ika= ob->data;
- ika->totx= 0.0;
- ika->toty= 0.0;
- li= ika->limbbase.first;
-
- calc_ika(ika, 0); /* correct endpoints */
-
- while(li) {
- li->alphao= li->alpha;
- li->leno= li->len;
-
- li= li->next;
- }
- ika->eff[2]= 0.0;
- VecMat4MulVecfl(ika->effg, ob->obmat, ika->eff);
-}
-
-void itterate_limb(Ika *ika, Limb *li)
-{
- float da, n1[2], n2[2], len1, len2;
-
- if(li->prev) {
- n1[0]= ika->eff[0] - li->prev->eff[0];
- n1[1]= ika->eff[1] - li->prev->eff[1];
- n2[0]= ika->effn[0] - li->prev->eff[0];
- n2[1]= ika->effn[1] - li->prev->eff[1];
- }
- else {
- n1[0]= ika->eff[0];
- n1[1]= ika->eff[1];
- n2[0]= ika->effn[0];
- n2[1]= ika->effn[1];
- }
- len1= (float)sqrt(n1[0]*n1[0] + n1[1]*n1[1]);
- len2= (float)sqrt(n2[0]*n2[0] + n2[1]*n2[1]);
-
- da= (1.0f-li->fac)*saacos( (n1[0]*n2[0]+n1[1]*n2[1])/(len1*len2) );
-
- if(n1[0]*n2[1] < n1[1]*n2[0]) da= -da;
-
- li->alpha+= da;
-
-}
-
-void rotate_ika(Object *ob, Ika *ika)
-{
- Limb *li;
- float len2, da, n1[2], n2[2];
-
- /* rotate back */
- euler_rot(ob->rot, -ika->toty, 'y');
- ika->toty= 0.0;
-
- where_is_object(ob);
-
- Mat4Invert(ob->imat, ob->obmat);
- VecMat4MulVecfl(ika->effn, ob->imat, ika->effg);
-
- li= ika->limbbase.last;
- if(li==0) return;
-
- n1[0]= ika->eff[0];
- n2[0]= ika->effn[0];
- n2[1]= ika->effn[2];
-
- len2= (float)sqrt(n2[0]*n2[0] + n2[1]*n2[1]);
-
- if(len2>TOLER) {
- da= (n2[0])/(len2);
- if(n1[0]<0.0) da= -da;
-
- /* when the x component is almost zero, this can happen */
- if(da<=-1.0+TOLER || da>=1.0) ;
- else {
-
- da= saacos( da );
- if(n1[0]*n2[1] > 0.0) da= -da;
-
- euler_rot(ob->rot, da, 'y');
- ika->toty= da;
- }
- }
-}
-
-void rotate_ika_xy(Object *ob, Ika *ika)
-{
- Limb *li;
- float ang, da, n1[3], n2[3], axis[3], quat[4];
-
- /* rotate back */
- euler_rot(ob->rot, -ika->toty, 'y');
- euler_rot(ob->rot, -ika->totx, 'x');
-
- where_is_object(ob);
-
- Mat4Invert(ob->imat, ob->obmat);
- VecMat4MulVecfl(ika->effn, ob->imat, ika->effg);
-
- li= ika->limbbase.last;
- if(li==0) return;
-
- /* ika->eff = old situation */
- /* ika->effn = desired situation */
-
- *(n1)= *(ika->effn);
- *(n1+1)= *(ika->effn+1);
- *(n1+2)= 0.0;
-
- *(n2)= *(ika->effn);
- *(n2+1)= *(ika->effn+1);
- *(n2+2)= *(ika->effn+2);
-
- Normalise(n1);
- Normalise(n2);
-
- ang= n1[0]*n2[0] + n1[1]*n2[1] + n1[2]*n2[2];
- ang= saacos(ang);
-
- if(ang<-0.0000001 || ang>0.00000001) {
- Crossf(axis, n1, n2);
- Normalise(axis);
- quat[0]= (float)cos(0.5*ang);
- da= (float)sin(0.5*ang);
- quat[1]= da*axis[0];
- quat[2]= da*axis[1];
- quat[3]= da*axis[2];
-
- QuatToEul(quat, axis);
-
- ika->totx= axis[0];
- CLAMP(ika->totx, -ika->xyconstraint, ika->xyconstraint);
- ika->toty= axis[1];
- CLAMP(ika->toty, -ika->xyconstraint, ika->xyconstraint);
- }
-
- euler_rot(ob->rot, ika->totx, 'x');
- euler_rot(ob->rot, ika->toty, 'y');
-}
-
-void itterate_ika(Object *ob)
-{
- Ika *ika;
- Limb *li;
- int it = 0;
-
- ika= ob->data;
- if((ika->flag & IK_GRABEFF)==0) return;
-
- disable_where_script(1);
- /* memory: handle large steps in time */
- it= abs(ika->lastfra - G.scene->r.cfra);
- ika->lastfra= G.scene->r.cfra;
- if(it>10) {
-
- /* one itteration extra */
- itterate_ika(ob);
- }
- else {
- li= ika->limbbase.first;
- while(li) {
- li->alpha= (1.0f-ika->mem)*li->alpha + ika->mem*li->alphao;
- li= li->next;
- }
- }
- calc_ika(ika, 0);
-
- /* effector has parent? */
- if(ika->parent) {
-
- if(ika->partype==PAROBJECT) {
- if(ika->parent->ctime != (float) G.scene->r.cfra) where_is_object(ika->parent);
- *(ika->effg)= *(ika->parent->obmat[3]);
- *(ika->effg+1)= *(ika->parent->obmat[3]+1);
- *(ika->effg+2)= *(ika->parent->obmat[3]+2);
- }
- else {
- what_does_parent1(ika->parent, ika->partype, ika->par1, 0, 0);
- *(ika->effg)= *(workob.obmat[3]);
- *(ika->effg+1)= *(workob.obmat[3]+1);
- *(ika->effg+2)= *(workob.obmat[3]+2);
- }
- }
-
-
- /* rotate y-as correctly */
- if(ika->flag & IK_XYCONSTRAINT)
- rotate_ika_xy(ob, ika);
- else
- rotate_ika(ob, ika);
-
- it= ika->iter;
- while(it--) {
-
- where_is_object(ob);
- Mat4Invert(ob->imat, ob->obmat);
- VecMat4MulVecfl(ika->effn, ob->imat, ika->effg);
- /* forward orfer: to do the first limbs as well */
- li= ika->limbbase.first;
- while(li) {
-
- itterate_limb(ika, li);
-
- /* zet je calc_ika() buiten deze lus: lange kettingen instabiel */
- calc_ika(ika, li);
-
- li= li->next;
- }
-
- where_is_object(ob);
- Mat4Invert(ob->imat, ob->obmat);
- VecMat4MulVecfl(ika->effn, ob->imat, ika->effg);
-
- /* backward */
- li= ika->limbbase.last;
- while(li) {
-
- itterate_limb(ika, li);
-
- /* when you put calc_ika() outside this loop: long chains get instable */
- calc_ika(ika, li);
-
- li= li->prev;
- }
- }
-
- disable_where_script(0);
-}
-
-
-void do_all_ikas()
-{
- Base *base = 0;
-
- base= G.scene->base.first;
- while(base) {
-
- if(base->object->type==OB_IKA) itterate_ika(base->object);
-
- base= base->next;
- }
-}
-
-void do_all_visible_ikas()
-{
- Base *base = 0;
-
- base= G.scene->base.first;
- while(base) {
- if(base->lay & G.scene->lay) {
- if(base->object->type==OB_IKA) itterate_ika(base->object);
- }
- base= base->next;
- }
-}
-
-/* ******************** DEFORM ************************ */
-
-
-void init_skel_deform(Object *par, Object *ob)
-{
- Deform *def;
- Ika *ika;
- int a;
-
- /* deform:
- *
- * ob_vec * ob_obmat * def_imat (weight fie) * def_obmat * ob_imat = ob_vec'
- *
- * <----- premat ----> <---- postmat ---->
- */
-
- if(par->type!=OB_IKA) return;
-
- Mat4Invert(ob->imat, ob->obmat);
-
- ika= par->data;
- a= ika->totdef;
- def= ika->def;
- while(a--) {
-
- what_does_parent1(def->ob, def->partype, def->par1, def->par2, def->par3);
-
- Mat4MulMat4(def->premat, ob->obmat, def->imat);
- Mat4MulMat4(def->postmat, workob.obmat, ob->imat);
-
- def++;
- }
-}
-
-
-void calc_skel_deform(Ika *ika, float *co)
-{
- Deform *def;
- int a;
- float totw=0.0, weight, fac, len, vec[3], totvec[3];
-
- def= ika->def;
- if(def==0) return;
- a= ika->totdef;
- totvec[0]=totvec[1]=totvec[2]= 0.0;
-
- while(a--) {
-
- VecMat4MulVecfl(vec, def->premat, co);
-
- len= (float)sqrt(vec[0]*vec[0] + vec[1]*vec[1] + vec[2]*vec[2]);
-
- if(def->vec[0]==0.0f) len= 2.0f*len;
- else len= len + (float)sqrt( (vec[0]+def->vec[0])*(vec[0]+def->vec[0]) + vec[1]*vec[1] + vec[2]*vec[2]);
-
- /* def->vec[0]= len limb */
-
- weight= 1.0f/(0.001f+len);
- weight*= weight;
- weight*= weight;
- weight*= def->fac;
-
- len -= def->vec[0];
-
- if(def->dist != 0.0) {
- if(len >= def->dist) {
- weight= 0.0;
- }
- else {
- fac= (def->dist - len)/def->dist;
- weight*= fac;
- }
- }
- if(weight > 0.0) {
- Mat4MulVecfl(def->postmat, vec);
-
- VecMulf(vec, weight);
- VecAddf(totvec, totvec, vec);
-
- totw+= weight;
- }
- def++;
- }
-
- if(totw==0.0) return;
-
- co[0]= totvec[0]/totw;
- co[1]= totvec[1]/totw;
- co[2]= totvec[2]/totw;
-
-}
diff --git a/source/blender/blenkernel/intern/ipo.c b/source/blender/blenkernel/intern/ipo.c
index 25c23b8480b..a03eb0e35c4 100644
--- a/source/blender/blenkernel/intern/ipo.c
+++ b/source/blender/blenkernel/intern/ipo.c
@@ -41,22 +41,21 @@
#include "MEM_guardedalloc.h"
-#include "DNA_ika_types.h"
-#include "DNA_sequence_types.h"
+#include "DNA_action_types.h"
+#include "DNA_curve_types.h"
#include "DNA_camera_types.h"
-#include "DNA_sound_types.h"
#include "DNA_lamp_types.h"
-#include "DNA_view3d_types.h"
+#include "DNA_ipo_types.h"
#include "DNA_key_types.h"
-#include "DNA_scene_types.h"
-#include "DNA_texture_types.h"
#include "DNA_material_types.h"
+#include "DNA_mesh_types.h"
#include "DNA_object_types.h"
#include "DNA_object_force.h"
-#include "DNA_mesh_types.h"
-#include "DNA_curve_types.h"
-#include "DNA_ipo_types.h"
-#include "DNA_action_types.h"
+#include "DNA_sequence_types.h"
+#include "DNA_scene_types.h"
+#include "DNA_sound_types.h"
+#include "DNA_texture_types.h"
+#include "DNA_view3d_types.h"
#include "BLI_blenlib.h"
#include "BLI_arithb.h"
@@ -64,15 +63,16 @@
#include "BKE_bad_level_calls.h"
#include "BKE_utildefines.h"
-#include "BKE_main.h"
-#include "BKE_global.h"
-#include "BKE_library.h"
-#include "BKE_curve.h"
-#include "BKE_object.h"
+#include "BKE_action.h"
#include "BKE_blender.h"
-#include "BKE_ipo.h"
+#include "BKE_curve.h"
#include "BKE_constraint.h"
+#include "BKE_global.h"
+#include "BKE_ipo.h"
+#include "BKE_library.h"
+#include "BKE_main.h"
#include "BKE_mesh.h"
+#include "BKE_object.h"
#define SMALL -1.0e-10
@@ -89,7 +89,7 @@ int ob_ar[OB_TOTIPO]= {
OB_LOC_X, OB_LOC_Y, OB_LOC_Z, OB_DLOC_X, OB_DLOC_Y, OB_DLOC_Z,
OB_ROT_X, OB_ROT_Y, OB_ROT_Z, OB_DROT_X, OB_DROT_Y, OB_DROT_Z,
OB_SIZE_X, OB_SIZE_Y, OB_SIZE_Z, OB_DSIZE_X, OB_DSIZE_Y, OB_DSIZE_Z,
- OB_LAY, OB_TIME, OB_EFF_X, OB_EFF_Y, OB_EFF_Z, OB_COL_A,
+ OB_LAY, OB_TIME, OB_COL_R, OB_COL_G, OB_COL_B, OB_COL_A,
OB_PD_FSTR, OB_PD_FFALL, OB_PD_SDAMP, OB_PD_RDAMP, OB_PD_PERM
};
@@ -1080,25 +1080,45 @@ void *get_ipo_poin(ID *id, IpoCurve *icu, int *type)
return NULL;
switch (icu->adrcode){
case AC_QUAT_W:
- poin= &(pchan->quat[0]); break;
+ poin= &(pchan->quat[0]);
+ pchan->flag |= POSE_ROT;
+ break;
case AC_QUAT_X:
- poin= &(pchan->quat[1]); break;
+ poin= &(pchan->quat[1]);
+ pchan->flag |= POSE_ROT;
+ break;
case AC_QUAT_Y:
- poin= &(pchan->quat[2]); break;
+ poin= &(pchan->quat[2]);
+ pchan->flag |= POSE_ROT;
+ break;
case AC_QUAT_Z:
- poin= &(pchan->quat[3]); break;
+ poin= &(pchan->quat[3]);
+ pchan->flag |= POSE_ROT;
+ break;
case AC_LOC_X:
- poin= &(pchan->loc[0]); break;
+ poin= &(pchan->loc[0]);
+ pchan->flag |= POSE_LOC;
+ break;
case AC_LOC_Y:
- poin= &(pchan->loc[1]); break;
+ poin= &(pchan->loc[1]);
+ pchan->flag |= POSE_LOC;
+ break;
case AC_LOC_Z:
- poin= &(pchan->loc[2]); break;
+ poin= &(pchan->loc[2]);
+ pchan->flag |= POSE_LOC;
+ break;
case AC_SIZE_X:
- poin= &(pchan->size[0]); break;
+ poin= &(pchan->size[0]);
+ pchan->flag |= POSE_SIZE;
+ break;
case AC_SIZE_Y:
- poin= &(pchan->size[1]); break;
+ poin= &(pchan->size[1]);
+ pchan->flag |= POSE_SIZE;
+ break;
case AC_SIZE_Z:
- poin= &(pchan->size[2]); break;
+ poin= &(pchan->size[2]);
+ pchan->flag |= POSE_SIZE;
+ break;
};
}
@@ -1800,9 +1820,8 @@ int has_ipo_code(Ipo *ipo, int code)
return 0;
}
-void do_all_ipos()
+void do_all_data_ipos()
{
- Base *base;
Material *ma;
Tex *tex;
World *wo;
@@ -1813,7 +1832,6 @@ void do_all_ipos()
Sequence *seq;
Editing *ed;
float ctime;
- int set;
ctime= frame_to_float(G.scene->r.cfra);
@@ -1825,27 +1843,6 @@ void do_all_ipos()
ipo= ipo->id.next;
}
- /* NEW: current scene ob ipo's */
- base= G.scene->base.first;
- set= 0;
- while(base) {
-
- /* Do object ipos */
- do_constraint_channels(&base->object->constraints, &base->object->constraintChannels, ctime);
-
- if(base->object->ipo) {
- /* do per object ipo the calc_ipo: because of possible timeoffs */
- do_ob_ipo(base->object);
- if(base->object->type==OB_MBALL) where_is_object(base->object);
- }
- base= base->next;
-
- if(base==0 && set==0 && G.scene->set) {
- set= 1;
- base= G.scene->set->base.first;
- }
- }
-
tex= G.main->tex.first;
while(tex) {
if(tex->ipo) execute_ipo((ID *)tex, tex->ipo);
@@ -1882,39 +1879,14 @@ void do_all_ipos()
snd= snd->id.next;
}
- /*just in case of... WATCH IT: 2x */
- base= G.scene->base.first;
- while(base) {
-
- /* only update layer when an ipo */
- if( has_ipo_code(base->object->ipo, OB_LAY) ) {
- base->lay= base->object->lay;
- }
-
- base= base->next;
- }
-
- /* just in case...*/
- if(G.scene->set) {
- base= G.scene->set->base.first;
- while(base) {
-
- /* only update layer when an ipo */
- if( has_ipo_code(base->object->ipo, OB_LAY) ) {
- base->lay= base->object->lay;
- }
-
- base= base->next;
- }
- }
-
- /* intrr: process FAC Ipos used as volume envelopes */
+ /* process FAC Ipos used as volume envelopes */
ed= G.scene->ed;
if (ed) {
seq= ed->seqbasep->first;
while(seq) {
- if ((seq->type == SEQ_SOUND) && (seq->ipo)
- &&(seq->startdisp<=G.scene->r.cfra+2) && (seq->enddisp>G.scene->r.cfra)) do_seq_ipo(seq);
+ if ((seq->type == SEQ_SOUND) && (seq->ipo) &&
+ (seq->startdisp<=G.scene->r.cfra+2) && (seq->enddisp>G.scene->r.cfra))
+ do_seq_ipo(seq);
seq= seq->next;
}
}
diff --git a/source/blender/blenkernel/intern/key.c b/source/blender/blenkernel/intern/key.c
index 3b54072bd12..966eadeb2d5 100644
--- a/source/blender/blenkernel/intern/key.c
+++ b/source/blender/blenkernel/intern/key.c
@@ -897,8 +897,6 @@ void do_key(int start, int end, int tot, char *poin, Key *key, KeyBlock **k, flo
}
}
-
-
void do_mesh_key(Mesh *me)
{
KeyBlock *k[4];
@@ -906,8 +904,9 @@ void do_mesh_key(Mesh *me)
int a, flag = 0, step;
if(me->totvert==0) return;
- if(me->key==0) return;
- if(me->key->block.first==0) return;
+ if(me->key==NULL) return;
+ if(me->key->flag & KEY_LOCKED) return;
+ if(me->key->block.first==NULL) return;
if(me->key->slurph && me->key->type!=KEY_RELATIVE ) {
delta= me->key->slurph;
@@ -981,6 +980,7 @@ void do_cu_key(Curve *cu, KeyBlock **k, float *t)
tot= count_curveverts(&cu->nurb);
nu= cu->nurb.first;
a= 0;
+
while(nu) {
if(nu->bp) {
@@ -1051,8 +1051,9 @@ void do_curve_key(Curve *cu)
tot= count_curveverts(&cu->nurb);
if(tot==0) return;
- if(cu->key==0) return;
- if(cu->key->block.first==0) return;
+ if(cu->key==NULL) return;
+ if(cu->key->flag & KEY_LOCKED) return;
+ if(cu->key->block.first==NULL) return;
if(cu->key->slurph) {
delta= cu->key->slurph;
@@ -1117,9 +1118,10 @@ void do_latt_key(Lattice *lt)
float delta, cfra, ctime, t[4];
int a, tot, flag;
- if(lt->key==0) return;
+ if(lt->key==NULL) return;
+ if(lt->key->flag & KEY_LOCKED) return;
if(lt->key->block.first==0) return;
-
+
tot= lt->pntsu*lt->pntsv*lt->pntsw;
if(lt->key->slurph) {
@@ -1172,21 +1174,14 @@ void do_latt_key(Lattice *lt)
}
-
-void do_all_keys()
+/* going to be removed */
+void unlock_all_keys()
{
Key *key;
- int idcode;
key= G.main->key.first;
while(key) {
- if(key->from) {
- idcode= GS(key->from->name);
-
- if(idcode==ID_ME) do_mesh_key( (Mesh *)key->from);
- else if(idcode==ID_CU) do_curve_key( (Curve *)key->from);
- else if(idcode==ID_LT) do_latt_key( (Lattice *)key->from);
- }
+ key->flag &= ~KEY_LOCKED;
key= key->id.next;
}
}
diff --git a/source/blender/blenkernel/intern/lattice.c b/source/blender/blenkernel/intern/lattice.c
index 3da60f99826..db5dee45d5d 100644
--- a/source/blender/blenkernel/intern/lattice.c
+++ b/source/blender/blenkernel/intern/lattice.c
@@ -51,7 +51,6 @@
#include "DNA_lattice_types.h"
#include "DNA_curve_types.h"
#include "DNA_key_types.h"
-#include "DNA_ika_types.h"
#include "BKE_anim.h"
#include "BKE_armature.h"
@@ -59,7 +58,6 @@
#include "BKE_deform.h"
#include "BKE_displist.h"
#include "BKE_global.h"
-#include "BKE_ika.h"
#include "BKE_key.h"
#include "BKE_lattice.h"
#include "BKE_library.h"
diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c
index 27d87ce9117..63524c47592 100644
--- a/source/blender/blenkernel/intern/library.c
+++ b/source/blender/blenkernel/intern/library.c
@@ -56,7 +56,6 @@
#include "DNA_meta_types.h"
#include "DNA_material_types.h"
#include "DNA_texture_types.h"
-#include "DNA_ika_types.h"
#include "DNA_image_types.h"
#include "DNA_wave_types.h"
#include "DNA_lamp_types.h"
@@ -91,7 +90,6 @@
#include "BKE_texture.h"
#include "BKE_scene.h"
#include "BKE_image.h"
-#include "BKE_ika.h"
#include "BKE_ipo.h"
#include "BKE_key.h"
#include "BKE_world.h"
@@ -149,8 +147,6 @@ ListBase *wich_libbase(Main *mainlib, short type)
return &(mainlib->tex);
case ID_IM:
return &(mainlib->image);
- case ID_IK:
- return &(mainlib->ika);
case ID_WV:
return &(mainlib->wave);
case ID_LT:
@@ -209,26 +205,26 @@ int set_listbasepointers(Main *main, ListBase **lb)
lb[8]= &(main->mesh);
lb[9]= &(main->curve);
lb[10]= &(main->mball);
- lb[11]= &(main->ika);
- lb[12]= &(main->wave);
- lb[13]= &(main->latt);
- lb[14]= &(main->lamp);
- lb[15]= &(main->camera);
-
- lb[16]= &(main->world);
- lb[17]= &(main->screen);
- lb[18]= &(main->object);
- lb[19]= &(main->scene);
- lb[20]= &(main->library);
- lb[21]= &(main->text);
- lb[22]= &(main->sound);
- lb[23]= &(main->group);
-
- lb[24]= samples;
- lb[25]= &(main->script);
- lb[26]=0;
-
- return 26;
+
+ lb[11]= &(main->wave);
+ lb[12]= &(main->latt);
+ lb[13]= &(main->lamp);
+ lb[14]= &(main->camera);
+
+ lb[15]= &(main->world);
+ lb[16]= &(main->screen);
+ lb[17]= &(main->object);
+ lb[18]= &(main->scene);
+ lb[19]= &(main->library);
+ lb[20]= &(main->text);
+ lb[21]= &(main->sound);
+ lb[22]= &(main->group);
+
+ lb[23]= samples;
+ lb[24]= &(main->script);
+ lb[25]= NULL;
+
+ return 25;
}
/* *********** ALLOC AND FREE *****************
@@ -273,9 +269,6 @@ static ID *alloc_libblock_notest(short type)
case ID_IM:
id= MEM_callocN(sizeof(Image), "image");
break;
- case ID_IK:
- id= MEM_callocN(sizeof(Ika), "ika");
- break;
case ID_WV:
id= MEM_callocN(sizeof(Wave), "wave");
break;
@@ -421,9 +414,6 @@ void free_libblock(ListBase *lb, void *idv)
case ID_IM:
free_image((Image *)id);
break;
- case ID_IK:
- free_ika((Ika *)id);
- break;
case ID_WV:
/* free_wave(id); */
break;
diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c
index bc3290aa0d4..3d7fba62b0b 100644
--- a/source/blender/blenkernel/intern/material.c
+++ b/source/blender/blenkernel/intern/material.c
@@ -737,7 +737,7 @@ void delete_material_index()
if(ob->type==OB_MESH) {
Mesh *me= get_mesh(ob);
mesh_delete_material_index(me, actcol-1);
- makeDispList(ob);
+ freedisplist(&ob->disp);
}
else if ELEM(ob->type, OB_CURVE, OB_SURF) {
cu= ob->data;
@@ -750,6 +750,6 @@ void delete_material_index()
}
nu= nu->next;
}
- makeDispList(ob);
+ freedisplist(&ob->disp);
}
}
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index fdb08813765..68aa863d22c 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -48,7 +48,6 @@
#include "DNA_constraint_types.h"
#include "DNA_curve_types.h"
#include "DNA_group_types.h"
-#include "DNA_ika_types.h"
#include "DNA_ipo_types.h"
#include "DNA_lamp_types.h"
#include "DNA_lattice_types.h"
@@ -81,24 +80,24 @@
#include "BKE_main.h"
#include "BKE_global.h"
-#include "BKE_object.h"
+#include "BKE_anim.h"
#include "BKE_blender.h"
-#include "BKE_screen.h"
+#include "BKE_constraint.h"
+#include "BKE_curve.h"
+#include "BKE_displist.h"
+#include "BKE_effect.h"
+#include "BKE_group.h"
#include "BKE_ipo.h"
-#include "BKE_ika.h"
+#include "BKE_key.h"
+#include "BKE_lattice.h"
#include "BKE_library.h"
#include "BKE_mesh.h"
-#include "BKE_curve.h"
#include "BKE_mball.h"
-#include "BKE_effect.h"
-#include "BKE_sca.h"
-#include "BKE_displist.h"
+#include "BKE_object.h"
#include "BKE_property.h"
-#include "BKE_anim.h"
-#include "BKE_group.h"
-#include "BKE_lattice.h"
-#include "BKE_constraint.h"
+#include "BKE_sca.h"
#include "BKE_scene.h"
+#include "BKE_screen.h"
#include "BKE_softbody.h"
#include "BPY_extern.h"
@@ -201,7 +200,7 @@ void free_object(Object *ob)
if(ob->defbase.first)
BLI_freelistN(&ob->defbase);
if(ob->pose) {
- clear_pose(ob->pose);
+ free_pose_channels(ob->pose);
MEM_freeN(ob->pose);
}
free_effects(&ob->effect);
@@ -237,8 +236,10 @@ void unlink_object(Object *ob)
Tex *tex;
ObHook *hook;
Group *group;
+ bConstraint *con;
int a;
-
+ char *str;
+
unlink_controllers(&ob->controllers);
unlink_actuators(&ob->actuators);
@@ -246,37 +247,48 @@ void unlink_object(Object *ob)
obt= G.main->object.first;
while(obt) {
if(obt->id.lib==NULL) {
+
if(obt->parent==ob) {
obt->parent= NULL;
- if(ob->type==OB_LATTICE) freedisplist(&obt->disp);
+ obt->recalc |= OB_RECALC;
}
- if(obt->track==ob) obt->track= NULL;
+
+ if(obt->track==ob) {
+ obt->track= NULL;
+ obt->recalc |= OB_RECALC_OB;
+ }
+
for(hook=obt->hooks.first; hook; hook= hook->next) {
- if(hook->parent==ob) hook->parent= NULL;
+ if(hook->parent==ob) {
+ hook->parent= NULL;
+ obt->recalc |= OB_RECALC;
+ }
}
+
if ELEM(obt->type, OB_CURVE, OB_FONT) {
cu= obt->data;
- if(cu->bevobj==ob) cu->bevobj= NULL;
- if(cu->taperobj==ob) cu->taperobj= NULL;
- if(cu->textoncurve==ob) cu->textoncurve= NULL;
- }
- if(obt->type==OB_IKA) {
- Ika *ika= obt->data;
- Deform *def= ika->def;
-
- if(ika->parent==ob) ika->parent= NULL;
- a= ika->totdef;
- while(a--) {
- if(def->ob==ob) {
- ika->totdef= 0;
- MEM_freeN(ika->def);
- ika->def= NULL;
- break;
- }
- def++;
+ if(cu->bevobj==ob) {
+ cu->bevobj= NULL;
+ obt->recalc |= OB_RECALC;
+ }
+ if(cu->taperobj==ob) {
+ cu->taperobj= NULL;
+ obt->recalc |= OB_RECALC;
+ }
+ if(cu->textoncurve==ob) {
+ cu->textoncurve= NULL;
+ obt->recalc |= OB_RECALC;
}
}
+
sca_remove_ob_poin(obt, ob);
+
+ for (con = obt->constraints.first; con; con=con->next) {
+ if(ob==get_constraint_target(con, &str)) {
+ set_constraint_target(con, NULL);
+ obt->recalc |= OB_RECALC_OB;
+ }
+ }
}
obt= obt->id.next;
}
@@ -625,7 +637,6 @@ static void *add_obdata_from_type(int type)
case OB_MBALL: return add_mball();
case OB_CAMERA: return add_camera();
case OB_LAMP: G.totlamp++; return add_lamp();
- case OB_IKA: return add_ika();
case OB_LATTICE: return add_lattice();
case OB_WAVE: return add_wave();
case OB_ARMATURE: return add_armature();
@@ -646,7 +657,6 @@ static char *get_obdata_defname(int type)
case OB_MBALL: return "Mball";
case OB_CAMERA: return "Camera";
case OB_LAMP: return "Lamp";
- case OB_IKA: return "Ika";
case OB_LATTICE: return "Lattice";
case OB_WAVE: return "Wave";
case OB_ARMATURE: return "Armature";
@@ -721,7 +731,8 @@ Object *add_object(int type)
base= scene_add_base(G.scene, ob);
scene_select_base(G.scene, base);
-
+ ob->recalc |= OB_RECALC;
+
return ob;
}
@@ -1071,57 +1082,31 @@ void ob_parcurve(Object *ob, Object *par, float mat[][4])
void ob_parbone(Object *ob, Object *par, float mat[][4])
{
- Bone *bone;
+ bPoseChannel *pchan;
bArmature *arm;
-
- Mat4One(mat);
+ float vec[3];
+
arm=get_armature(par);
- if (!arm)
+ if (!arm) {
+ Mat4One(mat);
return;
-
+ }
+
/* Make sure the bone is still valid */
- bone = get_named_bone(arm, ob->parsubstr);
- if (!bone){
+ pchan= get_pose_channel(par->pose, ob->parsubstr);
+ if (!pchan){
printf ("Lost bone %s\n", ob->parsubstr);
+ Mat4One(mat);
return;
}
- apply_pose_armature(arm, par->pose, 1); /* Hopefully can set doit parameter in the future */
- where_is_bone (par, bone);
+ /* get bone transform */
+ Mat4CpyMat4(mat, pchan->pose_mat);
- /* Translate by negative bone */
- get_objectspace_bone_matrix(bone, mat, 0, 1);
-
-}
-
-void ob_parlimb(Object *ob, Object *par, float mat[][4])
-{
- Ika *ika;
- Limb *li;
- float ang=0.0;
- int cur=0;
-
- /* in local ob space */
- Mat4One(mat);
-
- ika= par->data;
- li= ika->limbbase.first;
- while(li) {
- ang+= li->alpha;
- if(cur==ob->par1 || li->next==0) break;
-
- cur++;
- li= li->next;
- }
-
- mat[0][0]= (float)cos(ang);
- mat[1][0]= (float)-sin(ang);
- mat[0][1]= (float)sin(ang);
- mat[1][1]= (float)cos(ang);
-
- mat[3][0]= li->eff[0];
- mat[3][1]= li->eff[1];
-
+ /* but for backwards compatibility, the child has to move to the tail */
+ VECCOPY(vec, mat[1]);
+ VecMulf(vec, pchan->bone->length);
+ VecAddf(mat[3], mat[3], vec);
}
void give_parvert(Object *par, int nr, float *vec)
@@ -1141,7 +1126,7 @@ void give_parvert(Object *par, int nr, float *vec)
vec[0]=vec[1]=vec[2]= 0.0;
if(par->type==OB_MESH) {
- if(par==G.obedit) {
+ if(G.obedit && (par->data==G.obedit->data)) {
if(nr >= G.totvert) nr= 0;
count= 0;
@@ -1209,20 +1194,6 @@ void give_parvert(Object *par, int nr, float *vec)
}
}
- else if(par->type==OB_IKA) {
- Ika *ika= par->data;
- Limb *li= ika->limbbase.first;
- int cur= 1;
- if(nr) {
- while(li) {
- if(cur==nr || li->next==0) break;
- cur++;
- li= li->next;
- }
- vec[0]= li->eff[0];
- vec[1]= li->eff[1];
- }
- }
else return;
}
@@ -1309,13 +1280,9 @@ void where_is_object_time(Object *ob, float ctime)
calc_ipo(ob->ipo, stime);
execute_ipo((ID *)ob, ob->ipo);
- }
- }
-
-
- if(ob->type==OB_IKA) {
- Ika *ika= ob->data;
- if(ika->parent) where_is_object_time(ika->parent, ctime);
+ }
+ /* do constraint ipos ... what the heck is a channel for! */
+ do_constraint_channels(&ob->constraints, &ob->constraintChannels, ctime);
}
if(ob->parent) {
@@ -1323,6 +1290,7 @@ void where_is_object_time(Object *ob, float ctime)
if(ob->ipoflag & OB_OFFS_PARENT) ctime-= ob->sf;
+ /* hurms, code below conflicts with depgraph... (ton) */
pop= 0;
if(no_parent_ipo==0 && ctime != par->ctime) {
@@ -1410,11 +1378,6 @@ static void solve_parenting (Object *ob, Object *par, float slowmat[][4], int si
Mat4MulSerie(totmat, par->obmat, tmat,
NULL, NULL, NULL, NULL, NULL, NULL);
break;
- case PARLIMB:
- ob_parlimb(ob, par, tmat);
- Mat4MulSerie(totmat, par->obmat, tmat,
- NULL, NULL, NULL, NULL, NULL, NULL);
- break;
case PARVERT1:
Mat4One(totmat);
@@ -1569,24 +1532,29 @@ void solve_constraints (Object *ob, short obtype, void *obdata, float ctime)
float smat[3][3], rmat[3][3], mat[3][3];
float enf;
- for (con = ob->constraints.first; con; con=con->next){
+ for (con = ob->constraints.first; con; con=con->next) {
+ // inverse kinematics is solved seperate
+ if (con->type==CONSTRAINT_TYPE_KINEMATIC) continue;
+
/* Clear accumulators if necessary*/
- if (clear){
- clear=0;
- a=0;
- tot=0;
+ if (clear) {
+ clear= 0;
+ a= 0;
+ tot= 0;
memset(aquat, 0, sizeof(float)*4);
memset(aloc, 0, sizeof(float)*3);
memset(asize, 0, sizeof(float)*3);
}
/* Check this constraint only if it has some enforcement */
- if (!(con->flag & CONSTRAINT_DISABLE))
- {
- if (con->enforce==0)
+ if (!(con->flag & CONSTRAINT_DISABLE)) {
+ /* weird code was here (ton)
+ if (con->enforce==0.0)
enf = 0.001f;
enf = con->enforce;
-
+ */
+ enf = con->enforce;
+
/* Get the targetmat */
get_constraint_target_matrix(con, obtype, obdata, tmat, size, ctime);
@@ -1598,10 +1566,10 @@ void solve_constraints (Object *ob, short obtype, void *obdata, float ctime)
Mat3CpyMat4(mat, focusmat);
Mat3ToSize(mat, size);
- a+=enf;
+ a+= enf;
tot++;
- for(i=0; i<3; i++){
+ for(i=0; i<3; i++) {
aquat[i+1]+=(quat[i+1]) * enf;
aloc[i]+=(loc[i]) * enf;
asize[i]+=(size[i]-1.0f) * enf;
@@ -1612,16 +1580,15 @@ void solve_constraints (Object *ob, short obtype, void *obdata, float ctime)
/* If the next constraint is not the same type (or there isn't one),
* then evaluate the accumulator & request a clear */
- if ((!con->next)||(con->next && con->next->type!=con->type))
- {
- clear=1;
+ if ((!con->next)||(con->next && con->next->type!=con->type)) {
+ clear= 1;
Mat4CpyMat4(oldmat, ob->obmat);
/* If we have several inputs, do a blend of them */
- if (tot){
- if (tot>1){
- if (a){
- for (i=0; i<3; i++){
+ if (tot) {
+ if (tot>1) {
+ if (a) {
+ for (i=0; i<3; i++) {
asize[i]=1.0f + (asize[i]/(a));
aloc[i]=(aloc[i]/a);
}
@@ -1639,14 +1606,14 @@ void solve_constraints (Object *ob, short obtype, void *obdata, float ctime)
}
/* If we only have one, blend with the current obmat */
- else{
+ else {
float solution[4][4];
float delta[4][4];
float imat[4][4];
float identity[4][4];
float worldmat[4][4];
- if (con->type!=CONSTRAINT_TYPE_KINEMATIC){
+ if (con->type!=CONSTRAINT_TYPE_KINEMATIC) {
/* If we're not an IK constraint, solve the constraint then blend it to the previous one */
evaluate_constraint(con, ob, obtype, obdata, lastmat);
@@ -1665,7 +1632,7 @@ void solve_constraints (Object *ob, short obtype, void *obdata, float ctime)
}
else{
/* Interpolate the target between the chain's unconstrained endpoint and the effector loc */
- if (obtype==TARGET_BONE){
+ if (obtype==TARGET_BONE) {
get_objectspace_bone_matrix(obdata, oldmat, 1, 1);
Mat4MulMat4(worldmat, oldmat, ob->parent->obmat);
@@ -1681,28 +1648,7 @@ void solve_constraints (Object *ob, short obtype, void *obdata, float ctime)
}
}
-void what_does_parent1(Object *par, int partype, int par1, int par2, int par3)
-{
-
- clear_workob();
- Mat4One(workob.parentinv);
- workob.parent= par;
- if(par)
- workob.track= par->track; /* WATCH IT: THATS NOT NICE CODE */
- workob.partype= partype;
- workob.par1= par1;
- workob.par2= par2;
- workob.par3= par3;
-
- if (par){
- workob.constraints.first = par->constraints.first;
- workob.constraints.last = par->constraints.last;
- }
-
- where_is_object(&workob);
-}
-
-
+/* for calculation of the inverse parent transform, only used for editor */
void what_does_parent(Object *ob)
{
@@ -1800,4 +1746,32 @@ void minmax_object(Object *ob, float *min, float *max)
}
}
+/* the main object update call, for object matrix, constraints, keys and displist (modifiers) */
+/* requires flags to be set! */
+void object_handle_update(Object *ob)
+{
+ if(ob->recalc & OB_RECALC) {
+
+ if(ob->recalc & OB_RECALC_OB) where_is_object(ob);
+
+ if(ob->recalc & OB_RECALC_DATA) {
+
+ /* includes all keys and modifiers */
+ if(ob->type && ob->type<OB_LAMP) {
+// printf("recalcdata %s\n", ob->id.name+2);
+ makeDispList(ob);
+ }
+ else if(ob->type==OB_ARMATURE) {
+ /* this actually only happens for reading old files... */
+ if(ob->pose==NULL || (ob->pose->flag & POSE_RECALC))
+ armature_rebuild_pose(ob, ob->data);
+ do_all_actions(ob);
+ where_is_pose(ob);
+ }
+ }
+
+ ob->recalc &= ~OB_RECALC;
+ }
+}
+
diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c
index 5d73b24e8bb..255cdba9f6d 100644
--- a/source/blender/blenkernel/intern/scene.c
+++ b/source/blender/blenkernel/intern/scene.c
@@ -46,46 +46,39 @@
#endif
#include "MEM_guardedalloc.h"
-#include "nla.h" /* for __NLA : IMPORTANT Do not delete me yet! */
-#ifdef __NLA /* for __NLA : IMPORTANT Do not delete me yet! */
-#include "DNA_armature_types.h" /* for __NLA : IMPORTANT Do not delete me yet! */
-#include "BKE_armature.h" /* for __NLA : IMPORTANT Do not delete me yet! */
-#include "BKE_action.h" /* for __NLA : IMPORTANT Do not delete me yet! */
-#endif /* for __NLA : IMPORTANT Do not delete me yet! */
-
+#include "DNA_armature_types.h"
#include "DNA_constraint_types.h"
-#include "DNA_scene_types.h"
-#include "DNA_object_types.h"
-#include "DNA_scriptlink_types.h"
-#include "DNA_meta_types.h"
-#include "DNA_ika_types.h"
+#include "DNA_curve_types.h"
+#include "DNA_group_types.h"
#include "DNA_lamp_types.h"
#include "DNA_material_types.h"
-#include "DNA_group_types.h"
-#include "DNA_curve_types.h"
+#include "DNA_meta_types.h"
+#include "DNA_object_types.h"
+#include "DNA_scene_types.h"
+#include "DNA_scriptlink_types.h"
#include "DNA_userdef_types.h"
-#include "BLI_blenlib.h"
-
-#include "BKE_bad_level_calls.h"
-#include "BKE_utildefines.h"
-
-#include "BKE_global.h"
-#include "BKE_main.h"
+#include "BKE_action.h"
#include "BKE_anim.h"
+#include "BKE_armature.h"
+#include "BKE_bad_level_calls.h"
#include "BKE_constraint.h"
-
+#include "BKE_depsgraph.h"
+#include "BKE_global.h"
+#include "BKE_ipo.h"
+#include "BKE_key.h"
#include "BKE_library.h"
-
+#include "BKE_main.h"
+#include "BKE_object.h"
#include "BKE_scene.h"
#include "BKE_world.h"
-#include "BKE_ipo.h"
-#include "BKE_ika.h"
-#include "BKE_key.h"
+#include "BKE_utildefines.h"
#include "BPY_extern.h"
-#include "BKE_depsgraph.h"
+#include "BLI_blenlib.h"
+
+#include "nla.h"
#ifdef WIN32
#else
@@ -222,95 +215,6 @@ int object_in_scene(Object *ob, Scene *sce)
return 0;
}
-void sort_baselist(Scene *sce)
-{
- topo_sort_baselist(sce);
-}
-
-#if 0
-void old_sort_baselist(Scene *sce)
-{
- /* in order of parent and track */
- ListBase tempbase, noparentbase, notyetbase;
- Base *base, *test=NULL;
- Object *par;
- int doit, domore= 0, lastdomore=1;
-
- /* keep same order when nothing has changed! */
-
- while(domore!=lastdomore) {
-
- lastdomore= domore;
- domore= 0;
- tempbase.first= tempbase.last= 0;
- noparentbase.first= noparentbase.last= 0;
- notyetbase.first= notyetbase.last= 0;
-
- while( (base= sce->base.first) ) {
- BLI_remlink(&sce->base, base);
-
- par= 0;
- if(base->object->type==OB_IKA) {
- Ika *ika= base->object->data;
- par= ika->parent;
- }
-
- if(par || base->object->parent || base->object->track) {
-
- doit= 0;
- if(base->object->parent) doit++;
- if(base->object->track) doit++;
-
- /* Count constraints */
- {
- bConstraint *con;
- for (con = base->object->constraints.first; con; con=con->next){
- if (constraint_has_target(con))
- doit++;
- }
- }
-
- if(par) doit++;
-
- test= tempbase.first;
- while(test) {
-
- if(test->object==base->object->parent) doit--;
- if(test->object==base->object->track) doit--;
- if(test->object==par) doit--;
-
- /* Decrement constraints */
- {
- bConstraint *con;
- for (con = base->object->constraints.first; con; con=con->next){
- if (test->object == get_constraint_target(con) && test->object!=base->object)
- doit--;
- }
- }
-
- if(doit==0) break;
- test= test->next;
- }
-
- if(test) BLI_insertlink(&tempbase, test, base);
- else {
- BLI_addhead(&tempbase, base);
- domore++;
- }
-
- }
- else BLI_addtail(&noparentbase, base);
-
- }
- sce->base= noparentbase;
- addlisttolist(&sce->base, &tempbase);
- addlisttolist(&sce->base, &notyetbase);
-
- }
-
-}
-#endif
-
void set_scene_bg(Scene *sce)
{
Base *base;
@@ -340,37 +244,34 @@ void set_scene_bg(Scene *sce)
}
/* sort baselist */
- sort_baselist(sce);
+ DAG_scene_sort(sce);
/* copy layers and flags from bases to objects */
base= G.scene->base.first;
while(base) {
-
- base->object->lay= base->lay;
+ ob= base->object;
+ ob->lay= base->lay;
/* group patch... */
- base->flag &= ~OB_FROMGROUP;
- flag= base->object->flag & OB_FROMGROUP;
+ base->flag &= ~(OB_FROMGROUP);
+ flag= ob->flag & (OB_FROMGROUP);
base->flag |= flag;
- base->object->flag= base->flag;
+ ob->flag= base->flag;
+ ob->recalc= OB_RECALC;
- base->object->ctime= -1234567.0; /* force ipo to be calculated later */
+ ob->ctime= -1234567.0; /* force ipo to be calculated later */
base= base->next;
}
-
- do_all_ipos(); /* layers/materials */
-
+ // full update
+ scene_update_for_newframe(sce, sce->lay);
+
/* do we need FRAMECHANGED in set_scene? */
- if (G.f & G_DOSCRIPTLINKS) BPY_do_all_scripts(SCRIPT_FRAMECHANGED);
+// if (G.f & G_DOSCRIPTLINKS) BPY_do_all_scripts(SCRIPT_FRAMECHANGED);
- do_all_keys();
-#ifdef __NLA
- do_all_actions(NULL);
- rebuild_all_armature_displists();
-#endif
- do_all_ikas();
+// do_all_keys();
+// do_all_actions(NULL);
}
@@ -518,3 +419,41 @@ void scene_select_base(Scene *sce, Base *selbase)
sce->basact= selbase;
}
+
+/* applies changes right away */
+void scene_update_for_newframe(Scene *sce, unsigned int lay)
+{
+ Base *base;
+ int setcount=0;
+
+ /* object ipos are calculated in where_is_object */
+ do_all_data_ipos();
+
+ if (G.f & G_DOSCRIPTLINKS) BPY_do_all_scripts(SCRIPT_FRAMECHANGED);
+
+// do_all_actions(NULL);
+ /* so nice, better do it twice */
+// do_all_actions(NULL);
+
+ /* if keys were activated, disable the locks */
+ unlock_all_keys();
+
+ /* for time being; sets otherwise can be cyclic */
+ while(sce && setcount<2) {
+ if(sce->theDag==NULL)
+ DAG_scene_sort(sce);
+
+ DAG_scene_update_flags(sce, lay); // only stuff that moves
+
+ for(base= sce->base.first; base; base= base->next) {
+ object_handle_update(base->object); // bke_object.h
+
+ /* only update layer when an ipo */
+ if(base->object->ipo && has_ipo_code(base->object->ipo, OB_LAY) ) {
+ base->lay= base->object->lay;
+ }
+ }
+ sce= sce->set;
+ setcount++;
+ }
+}