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:
authorTon Roosendaal <ton@blender.org>2005-07-03 21:35:38 +0400
committerTon Roosendaal <ton@blender.org>2005-07-03 21:35:38 +0400
commit28a1e8277be15fc455c816bed50e21423eb7e95a (patch)
treeaedb7afdda133681cd6b997947daeb92eb9a86cb /source/blender/blenkernel
parent99a8747e8246f8eabc8c60a850f2e2651995f8a1 (diff)
Result of 2 weeks of quiet coding work in Greece :)
Aim was to get a total refresh of the animation system. This is needed because; - we need to upgrade it with 21st century features - current code is spaghetti/hack combo, and hides good design - it should become lag-free with using dependency graphs A full log, with complete code API/structure/design explanation will follow, that's a load of work... so here below the list with hot changes; - The entire object update system (matrices, geometry) is now centralized. Calls to where_is_object and makeDispList are forbidden, instead we tag objects 'changed' and let the depgraph code sort it out - Removed all old "Ika" code - Depgraph is aware of all relationships, including meta balls, constraints, bevelcurve, and so on. - Made depgraph aware of relation types and layers, to do smart flushing of 'changed' events. Nothing gets calculated too often! - Transform uses depgraph to detect changes - On frame-advance, depgraph flushes animated changes Armatures; Almost all armature related code has been fully built from scratch. It now reveils the original design much better, with a very clean implementation, lag free without even calculating each Bone more than once. Result is quite a speedup yes! Important to note is; 1) Armature is data containing the 'rest position' 2) Pose is the changes of rest position, and always on object level. That way more Objects can use same Pose. Also constraints are in Pose 3) Actions only contain the Ipos to change values in Poses. - Bones draw unrotated now - Drawing bones speedup enormously (10-20 times) - Bone selecting in EditMode, selection state is saved for PoseMode, and vice-versa - Undo in editmode - Bone renaming does vertexgroups, constraints, posechannels, actions, for all users of Armature in entire file - Added Bone renaming in NKey panel - Nkey PoseMode shows eulers now - EditMode and PoseMode now have 'active' bone too (last clicked) - Parenting in EditMode' CTRL+P, ALT+P, with nice options! - Pose is added in Outliner now, with showing that constraints are in the Pose, not Armature - Disconnected IK solving from constraints. It's a separate phase now, on top of the full Pose calculations - Pose itself has a dependency graph too, so evaluation order is lag free. TODO NOW; - Rotating in Posemode has incorrect inverse transform (Martin will fix) - Python Bone/Armature/Pose API disabled... needs full recode too (wait for my doc!) - Game engine will need upgrade too - Depgraph code needs revision, cleanup, can be much faster! (But, compliments for Jean-Luc, it works like a charm!) - IK changed, it now doesnt use previous position to advance to next position anymore. That system looks nice (no flips) but is not well suited for NLA and background render. TODO LATER; We now can do loadsa new nifty features as well; like: - Kill PoseMode (can be option for armatures itself) - Make B-Bones (Bezier, Bspline, like for spines) - Move all silly button level edit to 3d window (like CTRL+I = add IK) - Much better & informative drawing - Fix action/nla editors - Put all ipos in Actions (object, mesh key, lamp color) - Add hooks - Null bones - Much more advanced constraints... Bugfixes; - OGL render (view3d header) had wrong first frame on anim render - Ipo 'recording' mode had wrong playback speed - Vertex-key mode now sticks to show 'active key', until frame change -Ton-
Diffstat (limited to 'source/blender/blenkernel')
-rw-r--r--source/blender/blenkernel/BKE_action.h67
-rw-r--r--source/blender/blenkernel/BKE_armature.h47
-rw-r--r--source/blender/blenkernel/BKE_constraint.h8
-rw-r--r--source/blender/blenkernel/BKE_depsgraph.h55
-rw-r--r--source/blender/blenkernel/BKE_displist.h1
-rw-r--r--source/blender/blenkernel/BKE_global.h2
-rw-r--r--source/blender/blenkernel/BKE_ika.h60
-rw-r--r--source/blender/blenkernel/BKE_ipo.h2
-rw-r--r--source/blender/blenkernel/BKE_key.h5
-rw-r--r--source/blender/blenkernel/BKE_main.h1
-rw-r--r--source/blender/blenkernel/BKE_object.h4
-rw-r--r--source/blender/blenkernel/BKE_scene.h6
-rw-r--r--source/blender/blenkernel/SConscript1
-rw-r--r--source/blender/blenkernel/depsgraph_private.h12
-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
33 files changed, 2475 insertions, 3459 deletions
diff --git a/source/blender/blenkernel/BKE_action.h b/source/blender/blenkernel/BKE_action.h
index 2f3af8ca103..5b8c8c1a929 100644
--- a/source/blender/blenkernel/BKE_action.h
+++ b/source/blender/blenkernel/BKE_action.h
@@ -28,9 +28,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 *****
*/
@@ -55,25 +53,16 @@ struct Object;
extern "C" {
#endif
-/**
- * Allocate a new pose channel on the heap and binary copy the
- * contents of the src pose channel.
- */
-struct bPoseChannel *copy_pose_channel(const struct bPoseChannel *src);
-
+
/**
* Removes and deallocates all channels from a pose.
* Does not free the pose itself.
*/
-void clear_pose(struct bPose *pose);
-
-/* Sets the value of a pose channel */
-struct bPoseChannel *set_pose_channel(struct bPose *pose,
- struct bPoseChannel *chan);
+void free_pose_channels(struct bPose *pose);
/**
* Allocate a new pose on the heap, and copy the src pose and it's channels
- * into the new pose. *dst is set to the newly allocated structure.
+ * into the new pose. *dst is set to the newly allocated structure, and assumed to be NULL.
*/
void copy_pose(struct bPose **dst, struct bPose *src,
int copyconstraints);
@@ -104,6 +93,9 @@ struct bPoseChannel *get_pose_channel(const struct bPose *pose,
struct bPoseChannel *verify_pose_channel(struct bPose* pose,
const char* name);
+/* sets constraint flags */
+void update_pose_constraint_flags(struct bPose *pose);
+
/**
* Allocate a new bAction on the heap and copy
* the contents of src into it. If src is NULL NULL is returned.
@@ -119,31 +111,12 @@ float calc_action_start(const struct bAction *act);
float calc_action_end(const struct bAction *act);
/**
- * Evaluate the pose from the given action.
- * If the pose does not exist, a new one is created.
- * Some deep calls into blender are made here.
+ * Set the pose channels from the given action.
*/
-void get_pose_from_action(struct bPose **pose, struct bAction *act,
+void extract_pose_from_action(struct bPose *pose, struct bAction *act,
float ctime);
/**
- * I think this duplicates the src into *pose.
- * If the pose does not exist, a new one is created.
- * If the pose does not contain channels from src
- * new channels are created.
- */
-void get_pose_from_pose(struct bPose **pose, const struct bPose *src);
-
-void clear_pose_constraint_status(struct Object *ob);
-
-/**
- * Blends the common subset of channels from dst and src.
- * and writes result to dst.
- */
-void blend_poses(struct bPose *dst, const struct bPose *src,
- float srcweight, short mode);
-
-/**
* Iterate through the action channels of the action
* and return the channel with the given name.
* Returns NULL if no channel.
@@ -151,30 +124,20 @@ void blend_poses(struct bPose *dst, const struct bPose *src,
struct bActionChannel *get_named_actionchannel(struct bAction *act,
const char *name);
+// exported for game engine
+void blend_poses(struct bPose *dst, const struct bPose *src, float srcweight, short mode);
+void extract_pose_from_pose(struct bPose *pose, const struct bPose *src);
+
+
#ifdef __cplusplus
};
#endif
+/* nla strip flag */
enum {
POSE_BLEND = 0,
POSE_ADD
};
-enum {
- POSE_KEY = 0x10000000,
- POSE_LOC = 0x00000001,
- POSE_ROT = 0x00000002,
- POSE_SIZE = 0x00000004,
- POSE_UNUSED1 = 0x00000008,
- POSE_UNUSED2 = 0x00000010,
- POSE_UNUSED3 = 0x00000020,
- POSE_UNUSED4 = 0x00000040,
- POSE_UNUSED5 = 0x00000080,
- POSE_OBMAT = 0x00000100,
- POSE_PARMAT = 0x00000200,
- PCHAN_DONE = 0x00000400,
- PCHAN_TRANS_UPDATE = 0x00000800
-};
-
#endif
diff --git a/source/blender/blenkernel/BKE_armature.h b/source/blender/blenkernel/BKE_armature.h
index 1f9725a4f41..3b924b56c47 100644
--- a/source/blender/blenkernel/BKE_armature.h
+++ b/source/blender/blenkernel/BKE_armature.h
@@ -38,6 +38,8 @@ struct Bone;
struct Main;
struct bArmature;
struct bPose;
+struct bPoseChannel;
+struct bConstraint;
struct Object;
struct MDeformVert;
struct Mesh;
@@ -46,10 +48,12 @@ struct ListBase;
typedef struct PoseChain
{
- struct PoseChain *next, *prev;
- struct Bone *root;
- struct Bone *target;
+ struct PoseChain *next, *prev; // hurms
+ struct bPoseChannel **pchanchain;
+ struct bConstraint *con;
+ struct Bone *root, *target;
struct bPose *pose;
+ int totchannel;
float goal[3];
float tolerance;
int iterations;
@@ -68,42 +72,27 @@ void unlink_armature(struct bArmature *arm);
void free_armature(struct bArmature *arm);
void make_local_armature(struct bArmature *arm);
struct bArmature *copy_armature(struct bArmature *arm);
-void apply_pose_armature (struct bArmature* arm, struct bPose* pose, int doit);
+
void calc_armature_deform (struct Object *ob, float *co, int index);
-int verify_boneptr (struct bArmature *arm, struct Bone *tBone);
+
void init_armature_deform(struct Object *parent, struct Object *ob);
struct bArmature* get_armature (struct Object* ob);
struct Bone *get_named_bone (struct bArmature *arm, const char *name);
-struct Bone *get_indexed_bone (struct bArmature *arm, int index);
-void make_displists_by_armature (struct Object *ob);
-void calc_bone_deform (struct Bone *bone, float weight, float *vec, float *co, float *contrib);
+struct Bone *get_indexed_bone (struct Object *ob, int index);
+
float dist_to_bone (float vec[3], float b1[3], float b2[3]);
-void where_is_armature_time (struct Object *ob, float ctime);
-void where_is_armature (struct Object *ob);
-void where_is_bone1_time (struct Object *ob, struct Bone *bone, float ctime);
-
-/* Handy bone matrix functions */
-void bone_to_mat4(struct Bone *bone, float mat[][4]);
-void bone_to_mat3(struct Bone *bone, float mat[][3]);
-void make_boneMatrixvr (float outmatrix[][4],float delta[3], float roll);
-void make_boneMatrix (float outmatrix[][4], struct Bone *bone);
-void get_bone_root_pos (struct Bone* bone, float vec[3], int posed);
-void get_bone_tip_pos (struct Bone* bone, float vec[3], int posed);
-float get_bone_length (struct Bone *bone);
+void where_is_armature (struct bArmature *arm);
+void where_is_armature_bone(struct Bone *bone, struct Bone *prevbone);
+void armature_rebuild_pose(struct Object *ob, struct bArmature *arm);
+void where_is_pose (struct Object *ob);
+
void get_objectspace_bone_matrix (struct Bone* bone, float M_accumulatedMatrix[][4], int root, int posed);
-void precalc_bone_irestmat (struct Bone *bone);
-void precalc_armature_posemats (struct bArmature *arm);
-void precalc_bonelist_irestmats (struct ListBase* bonelist);
-void apply_bonemat(struct Bone *bone);
+void vec_roll_to_mat3(float *vec, float roll, float mat[][3]);
-/* void make_armatureParentMatrices (struct bArmature *arm); */
-void precalc_bone_defmat (struct Bone *bone);
-void rebuild_bone_parent_matrix (struct Bone *bone);
/* Animation functions */
-void where_is_bone_time (struct Object *ob, struct Bone *bone, float ctime);
-void where_is_bone (struct Object *ob, struct Bone *bone);
+
struct PoseChain *ik_chain_to_posechain (struct Object *ob, struct Bone *bone);
void solve_posechain (PoseChain *chain);
void free_posechain (PoseChain *chain);
diff --git a/source/blender/blenkernel/BKE_constraint.h b/source/blender/blenkernel/BKE_constraint.h
index cc2e5498fb4..8fdc63bef60 100644
--- a/source/blender/blenkernel/BKE_constraint.h
+++ b/source/blender/blenkernel/BKE_constraint.h
@@ -50,9 +50,7 @@ void *copy_constraint_channels (ListBase *dst, ListBase *src);
struct bConstraintChannel *clone_constraint_channels (struct ListBase *dst, struct ListBase *src, struct bConstraintChannel *oldact);
void relink_constraints (struct ListBase *list);
void free_constraint_data (struct bConstraint *con);
-void clear_object_constraint_status (struct Object *ob);
-void clear_all_constraints(void);
-void rebuild_all_armature_displists(void);
+
void do_constraint_channels (struct ListBase *conbase, struct ListBase *chanbase, float ctime);
short get_constraint_target_matrix (struct bConstraint *con, short ownertype, void *ownerdata, float mat[][4], float size[3], float time);
struct bConstraintChannel *find_constraint_channel (ListBase *list, const char *name);
@@ -61,7 +59,9 @@ void free_constraint_channels (ListBase *chanbase);
/* Gemeric functions */
char constraint_has_target (struct bConstraint *con);
-struct Object *get_constraint_target(struct bConstraint *con);
+struct Object *get_constraint_target(struct bConstraint *con, char **subtarget);
+void set_constraint_target(struct bConstraint *con, struct Object *ob);
+
/* Constraint target/owner types */
#define TARGET_OBJECT 1 // string is ""
diff --git a/source/blender/blenkernel/BKE_depsgraph.h b/source/blender/blenkernel/BKE_depsgraph.h
index 06eea7a5e98..0c592364d72 100644
--- a/source/blender/blenkernel/BKE_depsgraph.h
+++ b/source/blender/blenkernel/BKE_depsgraph.h
@@ -40,31 +40,26 @@ struct DagNodeQueue;
struct DagForest;
struct DagNode;
-typedef enum {
- DAG_RL_SCENE = 1,
- DAG_RL_DATA = 2,
- DAG_RL_PARENT = 4,
- DAG_RL_TRACK = 8,
- DAG_RL_PATH = 16,
- DAG_RL_CONSTRAINT = 32,
- DAG_RL_HOOK = 64,
- DAG_RL_DATA_CONSTRAINT = 128,
- DAG_NO_RELATION = 256
-} dag_rel_type;
-
-
-typedef enum {
- DAG_RL_SCENE_MASK = 1,
- DAG_RL_DATA_MASK = 2,
- DAG_RL_PARENT_MASK = 4,
- DAG_RL_TRACK_MASK = 8,
- DAG_RL_PATH_MASK = 16,
- DAG_RL_CONSTRAINT_MASK = 32,
- DAG_RL_HOOK_MASK = 64,
- DAG_RL_DATA_CONSTRAINT_MASK = 128,
- DAG_RL_ALL_BUT_DATA_MASK = 253,
- DAG_RL_ALL_MASK = 255
-} dag_rel_type_mask;
+/* **** DAG relation types *** */
+
+ /* scene link to object */
+#define DAG_RL_SCENE 1
+ /* object link to data */
+#define DAG_RL_DATA 2
+
+ /* object changes object (parent, track, constraints) */
+#define DAG_RL_OB_OB 4
+ /* object changes obdata (hooks, constraints) */
+#define DAG_RL_OB_DATA 8
+ /* data changes object (vertex parent) */
+#define DAG_RL_DATA_OB 16
+ /* data changes data (deformers) */
+#define DAG_RL_DATA_DATA 32
+
+#define DAG_NO_RELATION 64
+#define DAG_RL_ALL 63
+#define DAG_RL_ALL_BUT_DATA 61
+
typedef void (*graph_action_func)(void * ob, void **data);
@@ -91,13 +86,19 @@ int pre_and_post_source_DFS(struct DagForest *dag, short mask, struct DagNode *s
struct DagNodeQueue *get_obparents(struct DagForest *dag, void *ob);
struct DagNodeQueue *get_first_ancestors(struct DagForest *dag, void *ob);
struct DagNodeQueue *get_all_childs(struct DagForest *dag, void *ob); //
-dag_rel_type are_obs_related(struct DagForest *dag, void *ob1, void *ob2);
+short are_obs_related(struct DagForest *dag, void *ob1, void *ob2);
int is_acyclic(struct DagForest *dag); //
//int get_cycles(struct DagForest *dag, struct DagNodeQueue **queues, int *count); //
-void topo_sort_baselist(struct Scene *sce);
void boundbox_deps(void);
void draw_all_deps(void);
+/* ********** API *************** */
+
+void DAG_scene_sort(struct Scene *sce);
+void DAG_scene_update_flags(struct Scene *sce, unsigned int lay);
+void DAG_scene_flush_update(struct Scene *sce);
+void DAG_object_flush_update(struct Scene *sce, struct Object *ob, short flag);
+void DAG_pose_sort(struct Object *ob);
#endif
diff --git a/source/blender/blenkernel/BKE_displist.h b/source/blender/blenkernel/BKE_displist.h
index ca08b5454a3..0a79d8e8daa 100644
--- a/source/blender/blenkernel/BKE_displist.h
+++ b/source/blender/blenkernel/BKE_displist.h
@@ -148,7 +148,6 @@ void freefastshade(void);
void boundbox_displist(struct Object *ob);
void imagestodisplist(void);
void reshadeall_displist(void);
-void test_all_displists(void);
void filldisplist(struct ListBase *dispbase, struct ListBase *to);
#endif
diff --git a/source/blender/blenkernel/BKE_global.h b/source/blender/blenkernel/BKE_global.h
index 848f82c78b5..211280fae71 100644
--- a/source/blender/blenkernel/BKE_global.h
+++ b/source/blender/blenkernel/BKE_global.h
@@ -88,7 +88,7 @@ typedef struct Global {
char ima[160], sce[160], lib[160];
/* totals */
- short totobj, totlamp, totobjsel, totcurve, totmesh, totmat;
+ short totobj, totlamp, totobjsel, totcurve, totmesh, totbone, totbonesel;
int totvert, totedge, totface, totvertsel, totedgesel, totfacesel;
short machine, afbreek, moving, colact, zbuf;
diff --git a/source/blender/blenkernel/BKE_ika.h b/source/blender/blenkernel/BKE_ika.h
deleted file mode 100644
index 93856c31374..00000000000
--- a/source/blender/blenkernel/BKE_ika.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/**
- * blenlib/BKE_ika.h (mar-2001 nzc)
- *
- * $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 *****
- */
-#ifndef BKE_IKA_H
-#define BKE_IKA_H
-
-struct Ika;
-struct Limb;
-struct Object;
-
-void unlink_ika(struct Ika *ika);
-void free_ika(struct Ika *ika);
-struct Ika *add_ika(void);
-struct Ika *copy_ika(struct Ika *ika);
-void make_local_ika(struct Ika *ika);
-int count_limbs(struct Object *ob);
-void calc_limb(struct Limb *li);
-void calc_ika(struct Ika *ika, struct Limb *li);
-void init_defstate_ika(struct Object *ob);
-void itterate_limb(struct Ika *ika, struct Limb *li);
-void rotate_ika(struct Object *ob, struct Ika *ika);
-void rotate_ika_xy(struct Object *ob, struct Ika *ika);
-void itterate_ika(struct Object *ob);
-void do_all_ikas(void);
-void do_all_visible_ikas(void);
-void init_skel_deform(struct Object *par, struct Object *ob);
-void calc_skel_deform(struct Ika *ika, float *co);
-
-#endif
-
diff --git a/source/blender/blenkernel/BKE_ipo.h b/source/blender/blenkernel/BKE_ipo.h
index c25163063cc..e0c7fd787bb 100644
--- a/source/blender/blenkernel/BKE_ipo.h
+++ b/source/blender/blenkernel/BKE_ipo.h
@@ -82,7 +82,7 @@ void do_mat_ipo(struct Material *ma);
void do_ob_ipo(struct Object *ob);
void do_seq_ipo(struct Sequence *seq);
int has_ipo_code(struct Ipo *ipo, int code);
-void do_all_ipos(void);
+void do_all_data_ipos(void);
int calc_ipo_spec(struct Ipo *ipo, int adrcode, float *ctime);
void clear_delta_obipo(struct Ipo *ipo);
void add_to_cfra_elem(struct ListBase *lb, struct BezTriple *bezt);
diff --git a/source/blender/blenkernel/BKE_key.h b/source/blender/blenkernel/BKE_key.h
index 481c08cee69..b46f02cf81b 100644
--- a/source/blender/blenkernel/BKE_key.h
+++ b/source/blender/blenkernel/BKE_key.h
@@ -62,9 +62,10 @@ void do_cu_key(struct Curve *cu, struct KeyBlock **k, float *t);
void do_rel_cu_key(struct Curve *cu, float ctime);
void do_curve_key(struct Curve *cu);
void do_latt_key(struct Lattice *lt);
-void do_all_keys(void);
void do_ob_key(struct Object *ob);
void do_spec_key(struct Key *key);
-
+
+void unlock_all_keys(void);
+
#endif
diff --git a/source/blender/blenkernel/BKE_main.h b/source/blender/blenkernel/BKE_main.h
index 058ac3f0a28..9a37f91a023 100644
--- a/source/blender/blenkernel/BKE_main.h
+++ b/source/blender/blenkernel/BKE_main.h
@@ -59,7 +59,6 @@ typedef struct Main {
ListBase mat;
ListBase tex;
ListBase image;
- ListBase ika;
ListBase wave;
ListBase latt;
ListBase lamp;
diff --git a/source/blender/blenkernel/BKE_object.h b/source/blender/blenkernel/BKE_object.h
index 775b2057551..1fadaa161eb 100644
--- a/source/blender/blenkernel/BKE_object.h
+++ b/source/blender/blenkernel/BKE_object.h
@@ -88,13 +88,15 @@ int during_scriptlink(void);
void where_is_object_time(struct Object *ob, float ctime);
void where_is_object(struct Object *ob);
void where_is_object_simul(struct Object *ob);
-void what_does_parent1(struct Object *par, int partype, int par1, int par2, int par3);
+
void what_does_parent(struct Object *ob);
struct BoundBox *unit_boundbox(void);
void minmax_object(struct Object *ob, float *min, float *max);
void solve_tracking (struct Object *ob, float targetmat[][4]);
void solve_constraints (struct Object *ob, short obtype, void *obdata, float ctime);
+void object_handle_update(struct Object *ob);
+
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/blenkernel/BKE_scene.h b/source/blender/blenkernel/BKE_scene.h
index 538912a1f40..1313ad251e7 100644
--- a/source/blender/blenkernel/BKE_scene.h
+++ b/source/blender/blenkernel/BKE_scene.h
@@ -57,12 +57,14 @@ struct QuicktimeCodecData;
void free_avicodecdata(struct AviCodecData *acd);
void free_qtcodecdata(struct QuicktimeCodecData *acd);
+
void free_scene(struct Scene *me);
struct Scene *add_scene(char *name);
int object_in_scene(struct Object *ob, struct Scene *sce);
-void sort_baselist(struct Scene *sce);
+
void set_scene_bg(struct Scene *sce);
void set_scene_name(char *name);
+
int next_object(int val, struct Base **base, struct Object **ob);
struct Object *scene_find_camera(struct Scene *sc);
@@ -70,5 +72,7 @@ struct Base *scene_add_base(struct Scene *sce, struct Object *ob);
void scene_deselect_all(struct Scene *sce);
void scene_select_base(struct Scene *sce, struct Base *selbase);
+void scene_update_for_newframe(struct Scene *sce, unsigned int lay);
+
#endif
diff --git a/source/blender/blenkernel/SConscript b/source/blender/blenkernel/SConscript
index 0b6bf520bc4..a30c6488e05 100644
--- a/source/blender/blenkernel/SConscript
+++ b/source/blender/blenkernel/SConscript
@@ -12,7 +12,6 @@ source_files = ['intern/constraint.c',
'intern/sca.c',
'intern/world.c',
'intern/curve.c',
- 'intern/ika.c',
'intern/mball.c',
'intern/scene.c',
'intern/writeavi.c',
diff --git a/source/blender/blenkernel/depsgraph_private.h b/source/blender/blenkernel/depsgraph_private.h
index d6d74f75bb6..6b29de2d5b4 100644
--- a/source/blender/blenkernel/depsgraph_private.h
+++ b/source/blender/blenkernel/depsgraph_private.h
@@ -51,8 +51,9 @@ enum {
typedef struct DagAdjList
{
struct DagNode *node;
- dag_rel_type type;
- int count; // number of identical arcs
+ short type;
+ int count; // number of identical arcs
+ unsigned int lay; // for flushing redraw/rebuild events
struct DagAdjList *next;
} DagAdjList;
@@ -64,7 +65,9 @@ typedef struct DagNode
float x, y, k;
void * ob;
void * first_ancestor;
- int ancestor_count;
+ int ancestor_count;
+ int lay; // accumulated layers of its relations + itself
+ int lasttime; // if lasttime != DagForest->time, this node was not evaluated yet for flushing
int BFS_dist; // BFS distance
int DFS_dist; // DFS distance
int DFS_dvtm; // DFS discovery time
@@ -93,6 +96,7 @@ typedef struct DagForest
ListBase DagNode;
int numNodes;
int is_acyclic;
+ int time; // for flushing/tagging, compare with node->lasttime
} DagForest;
@@ -112,7 +116,7 @@ DagNode * dag_find_node (DagForest *forest,void * fob);
DagNode * dag_add_node (DagForest *forest,void * fob);
DagNode * dag_get_node (DagForest *forest,void * fob);
DagNode * dag_get_sub_node (DagForest *forest,void * fob);
-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);
void graph_bfs(void);
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++;
+ }
+}