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-12-11 16:23:30 +0300
committerTon Roosendaal <ton@blender.org>2005-12-11 16:23:30 +0300
commitd7bee8c1172f5d1f27fa51c740b0ae2d29996caf (patch)
tree3f9546167324da0880bab5c7daec1e853575f242 /source/blender/blenkernel
parent485dd1d37673d229db9062d8cad98e624d79c8ec (diff)
Big commit with work on Groups & Libraries:
-> Any Group Duplicate now can get local timing and local NLA override. This enables to control the entire animation system of the Group. Two methods for this have been implemented. 1) The quick way: just give the duplicator a "Startframe" offset. 2) Advanced: in the NLA Editor you can add ActionStrips to the duplicator to override NLA/action of any Grouped Object. For "Group NLA" to work, an ActionStrip needs to know which Object in a group it controls. On adding a strip, the code checks if an Action was already used by an Object in the Group, and assigns it automatic to that Object. You can also set this in the Nkey "Properties" panel for the strip. Change in NLA: the SHIFT+A "Add strip" command now always adds strips to the active Object. (It used to check where mouse was). This allows to add NLA strips to Objects that didn't have actions/nla yet. Important note: In Blender, duplicates are fully procedural and generated on the fly for each redraw. This means that redraw speed equals to stepping through frames, when using animated Duplicated Groups. -> Recoded entire duplicator system The old method was antique and clumsy, using globals and full temporal copies of Object. The new system is nicer in control, faster, and since it doesn't use temporal object copies anymore, it works better with Derived Mesh and DisplayList and rendering. By centralizing the code for duplicating, more options can be easier added. Features to note: - Duplicates now draw selected/unselected based on its Duplicator setting. - Same goes for the drawtype (wire, solid, selection outline, etc) - Duplicated Groups can be normally selected too Bonus goodie: SHIFT+A (Toolbox) now has entry "Add group" too, with a listing of all groups, allowing to add Group instances immediate. -> Library System - SHIFT+F4 data browse now shows the entire path for linked data - Outliner draws Library Icons to denote linked data - Outliner operation added: "Make Local" for library data. - Outliner now also draws Groups in regular view, allowing to unlink too. -> Fixes - depsgraph missed signal update for bone-parented Objects - on reading file, the entire database was tagged to "recalc" fully, causing unnecessary slowdown on reading. Might have missed stuff... :)
Diffstat (limited to 'source/blender/blenkernel')
-rw-r--r--source/blender/blenkernel/BKE_anim.h10
-rw-r--r--source/blender/blenkernel/BKE_depsgraph.h2
-rw-r--r--source/blender/blenkernel/BKE_displist.h3
-rw-r--r--source/blender/blenkernel/BKE_font.h9
-rw-r--r--source/blender/blenkernel/BKE_group.h17
-rw-r--r--source/blender/blenkernel/intern/DerivedMesh.c2
-rw-r--r--source/blender/blenkernel/intern/action.c3
-rw-r--r--source/blender/blenkernel/intern/anim.c217
-rw-r--r--source/blender/blenkernel/intern/depsgraph.c23
-rw-r--r--source/blender/blenkernel/intern/displist.c19
-rw-r--r--source/blender/blenkernel/intern/font.c89
-rw-r--r--source/blender/blenkernel/intern/group.c151
-rw-r--r--source/blender/blenkernel/intern/mball.c8
-rw-r--r--source/blender/blenkernel/intern/nla.c3
-rw-r--r--source/blender/blenkernel/intern/object.c23
-rw-r--r--source/blender/blenkernel/intern/scene.c39
16 files changed, 383 insertions, 235 deletions
diff --git a/source/blender/blenkernel/BKE_anim.h b/source/blender/blenkernel/BKE_anim.h
index e4cd8e39aca..69fb83aac30 100644
--- a/source/blender/blenkernel/BKE_anim.h
+++ b/source/blender/blenkernel/BKE_anim.h
@@ -39,12 +39,18 @@ struct Object;
struct PartEff;
struct Scene;
+typedef struct DupliObject {
+ struct DupliObject *next, *prev;
+ struct Object *ob;
+ float mat[4][4], omat[4][4];
+} DupliObject;
+
void free_path(struct Path *path);
void calc_curvepath(struct Object *ob);
int interval_test(int min, int max, int p1, int cycl);
int where_on_path(struct Object *ob, float ctime, float *vec, float *dir);
-void free_duplilist(void);
-void make_duplilist(struct Scene *sce, struct Object *ob);
+
+ListBase *object_duplilist(struct Scene *sce, struct Object *ob);
int count_duplilist(struct Object *ob);
#endif
diff --git a/source/blender/blenkernel/BKE_depsgraph.h b/source/blender/blenkernel/BKE_depsgraph.h
index 5dd820d5a79..294f61e54bd 100644
--- a/source/blender/blenkernel/BKE_depsgraph.h
+++ b/source/blender/blenkernel/BKE_depsgraph.h
@@ -109,5 +109,5 @@ void DAG_scene_flush_update(struct Scene *sce, unsigned int lay);
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 2dcf4bfe1be..05a1cfc5376 100644
--- a/source/blender/blenkernel/BKE_displist.h
+++ b/source/blender/blenkernel/BKE_displist.h
@@ -75,6 +75,7 @@ if( (cyclv) && a==sizev-1) { \
/* prototypes */
+struct Base;
struct Object;
struct Curve;
struct ListBase;
@@ -144,7 +145,7 @@ extern void makeDispListMesh(struct Object *ob);
extern void makeDispListSurf(struct Object *ob, struct ListBase *dispbase, int forRender);
extern void makeDispListCurveTypes(struct Object *ob, int forOrco);
extern void makeDispListMBall(struct Object *ob);
-extern void shadeDispList(struct Object *ob);
+extern void shadeDispList(struct Base *base);
void freefastshade(void);
void imagestodisplist(void);
void reshadeall_displist(void);
diff --git a/source/blender/blenkernel/BKE_font.h b/source/blender/blenkernel/BKE_font.h
index 00a994672be..05621a4d9b2 100644
--- a/source/blender/blenkernel/BKE_font.h
+++ b/source/blender/blenkernel/BKE_font.h
@@ -41,6 +41,13 @@ struct Object;
struct Curve;
struct objfnt;
+struct chartrans {
+ float xof, yof;
+ float rot;
+ short linenr,charnr;
+ char dobreak;
+};
+
typedef struct SelBox {
float x, y, w, h;
} SelBox;
@@ -55,7 +62,7 @@ struct VFont *load_vfont(char *name);
struct chartrans *text_to_curve(struct Object *ob, int mode);
int style_to_sel(int style, int toggle);
int mat_to_sel(void);
-void font_duplilist(struct Object *par);
+
int getselection(int *start, int *end);
void chtoutf8(unsigned long c, char *o);
diff --git a/source/blender/blenkernel/BKE_group.h b/source/blender/blenkernel/BKE_group.h
index 2d42a9e284c..db4c83040a8 100644
--- a/source/blender/blenkernel/BKE_group.h
+++ b/source/blender/blenkernel/BKE_group.h
@@ -37,15 +37,20 @@
struct Group;
struct GroupObject;
struct Object;
+struct bAction;
-void free_group_object(struct GroupObject *go);
-void free_group(struct Group *group);
+void free_group_object(struct GroupObject *go);
+void free_group(struct Group *group);
+void unlink_group(struct Group *group);
struct Group *add_group(void);
-void add_to_group(struct Group *group, struct Object *ob);
-void rem_from_group(struct Group *group, struct Object *ob);
+void add_to_group(struct Group *group, struct Object *ob);
+void rem_from_group(struct Group *group, struct Object *ob);
struct Group *find_group(struct Object *ob);
-int object_in_group(struct Object *ob, struct Group *group);
-void group_tag_recalc(struct Group *group);
+int object_in_group(struct Object *ob, struct Group *group);
+
+void group_tag_recalc(struct Group *group);
+void group_handle_recalc_and_update(struct Object *parent, struct Group *group);
+struct Object *group_get_member_with_action(struct Group *group, struct bAction *act);
#endif
diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c
index 04c4d180927..a0713d3a7dd 100644
--- a/source/blender/blenkernel/intern/DerivedMesh.c
+++ b/source/blender/blenkernel/intern/DerivedMesh.c
@@ -1823,8 +1823,6 @@ static void mesh_build_data(Object *ob)
Mesh *me = ob->data;
float min[3], max[3];
- if(ob->flag&OB_FROMDUPLI) return;
-
clear_mesh_caches(ob);
if(ob!=G.obedit) {
diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c
index d5fa6958dff..211e552f493 100644
--- a/source/blender/blenkernel/intern/action.c
+++ b/source/blender/blenkernel/intern/action.c
@@ -816,7 +816,7 @@ static void do_nla(Object *ob, int blocktype)
actlength = strip->actend-strip->actstart;
striptime = (G.scene->r.cfra-(strip->start)) / length;
stripframe = (G.scene->r.cfra-(strip->start)) ;
-
+
if (striptime>=0.0){
if(blocktype==ID_AR)
@@ -979,6 +979,7 @@ void do_all_pose_actions(Object *ob)
void do_all_object_actions(Object *ob)
{
if(ob==NULL) return;
+ if(ob->dup_group) return; /* prevent conflicts, might add smarter check later */
/* Do local action */
if(ob->action && ((ob->nlaflag & OB_NLA_OVERRIDE)==0 || ob->nlastrips.first==NULL) ) {
diff --git a/source/blender/blenkernel/intern/anim.c b/source/blender/blenkernel/intern/anim.c
index 5b5f1fabdf2..5700be0fcbc 100644
--- a/source/blender/blenkernel/intern/anim.c
+++ b/source/blender/blenkernel/intern/anim.c
@@ -49,17 +49,20 @@
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
#include "DNA_view3d_types.h"
+#include "DNA_vfont_types.h"
+#include "BKE_anim.h"
#include "BKE_DerivedMesh.h"
+#include "BKE_displist.h"
+#include "BKE_effect.h"
+#include "BKE_font.h"
+#include "BKE_group.h"
#include "BKE_global.h"
-#include "BKE_utildefines.h"
-#include "BKE_anim.h"
#include "BKE_ipo.h"
-#include "BKE_object.h"
-#include "BKE_displist.h"
#include "BKE_key.h"
-#include "BKE_font.h"
-#include "BKE_effect.h"
+#include "BKE_main.h"
+#include "BKE_object.h"
+#include "BKE_utildefines.h"
#include "BKE_bad_level_calls.h"
@@ -272,53 +275,40 @@ int where_on_path(Object *ob, float ctime, float *vec, float *dir) /* returns OK
return 1;
}
-static Object *new_dupli_object(ListBase *lb, Object *ob, Object *par, int clearpar)
-{
- Object *newob;
-
- newob= MEM_mallocN(sizeof(Object), "newobj dupli");
-
- memcpy(newob, ob, sizeof(Object));
- newob->flag |= OB_FROMDUPLI;
- newob->id.newid= (ID *)par; /* store duplicator */
-
- /* only basis-ball gets displist */
- if(newob->type==OB_MBALL) newob->disp.first= newob->disp.last= NULL;
+/* ****************** DUPLICATOR ************** */
- if(clearpar) { // dupliverts, particle
- newob->parent= NULL;
- newob->track= NULL;
- }
- BLI_addtail(lb, newob);
-
- return newob;
+static void new_dupli_object(ListBase *lb, Object *ob, float mat[][4])
+{
+ DupliObject *dob= MEM_mallocN(sizeof(DupliObject), "dupliobject");
+ BLI_addtail(lb, dob);
+ dob->ob= ob;
+ Mat4CpyMat4(dob->mat, mat);
+ Mat4CpyMat4(dob->omat, ob->obmat);
}
-static void group_duplilist(Object *ob)
+static void group_duplilist(ListBase *lb, Object *ob)
{
- Object *newob;
GroupObject *go;
float mat[4][4];
if(ob->dup_group==NULL) return;
+ /* handles animated groups, and */
+ /* we need to check update for objects that are not in scene... */
+ group_handle_recalc_and_update(ob, ob->dup_group);
+
for(go= ob->dup_group->gobject.first; go; go= go->next) {
if(go->ob!=ob) {
- /* we need to check update for objects that are not in scene... */
- if(go->ob->recalc)
- object_handle_update(go->ob); // bke_object.h
-
- newob= new_dupli_object(&duplilist, go->ob, ob, 0);
- Mat4CpyMat4(mat, newob->obmat);
- Mat4MulMat4(newob->obmat, mat, ob->obmat);
+ Mat4MulMat4(mat, go->ob->obmat, ob->obmat);
+ new_dupli_object(lb, go->ob, mat);
}
}
}
-static void frames_duplilist(Object *ob)
+static void frames_duplilist(ListBase *lb, Object *ob)
{
extern int enable_cu_speed; /* object.c */
- Object *newob, copyob;
+ Object copyob;
int cfrao, ok;
cfrao= G.scene->r.cfra;
@@ -337,10 +327,9 @@ static void frames_duplilist(Object *ob)
else ok= 0;
}
if(ok) {
- newob= new_dupli_object(&duplilist, ob, ob, 0);
-
- do_ob_ipo(newob);
- where_is_object_time(newob, (float)G.scene->r.cfra);
+ do_ob_ipo(ob);
+ where_is_object_time(ob, (float)G.scene->r.cfra);
+ new_dupli_object(lb, ob, ob->obmat);
}
}
@@ -350,6 +339,7 @@ static void frames_duplilist(Object *ob)
}
struct vertexDupliData {
+ ListBase *lb;
float pmat[4][4];
Object *ob, *par;
};
@@ -357,16 +347,15 @@ struct vertexDupliData {
static void vertex_dupli__mapFunc(void *userData, int index, float *co, float *no_f, short *no_s)
{
struct vertexDupliData *vdd= userData;
- Object *newob;
- float vec[3], *q2, mat[3][3], tmat[4][4];
+ float vec[3], *q2, mat[3][3], tmat[4][4], obmat[4][4];
VECCOPY(vec, co);
Mat4MulVecfl(vdd->pmat, vec);
VecSubf(vec, vec, vdd->pmat[3]);
VecAddf(vec, vec, vdd->ob->obmat[3]);
- newob= new_dupli_object(&duplilist, vdd->ob, vdd->par, 1);
- VECCOPY(newob->obmat[3], vec);
+ Mat4CpyMat4(obmat, vdd->ob->obmat);
+ VECCOPY(obmat[3], vec);
if(vdd->par->transflag & OB_DUPLIROT) {
@@ -375,13 +364,13 @@ static void vertex_dupli__mapFunc(void *userData, int index, float *co, float *n
q2= vectoquat(vec, vdd->ob->trackflag, vdd->ob->upflag);
QuatToMat3(q2, mat);
- Mat4CpyMat4(tmat, newob->obmat);
- Mat4MulMat43(newob->obmat, tmat, mat);
+ Mat4CpyMat4(tmat, obmat);
+ Mat4MulMat43(obmat, tmat, mat);
}
-
+ new_dupli_object(vdd->lb, vdd->ob, obmat);
}
-static void vertex_duplilist(Scene *sce, Object *par)
+static void vertex_duplilist(ListBase *lb, Scene *sce, Object *par)
{
Object *ob;
Base *base;
@@ -411,6 +400,7 @@ static void vertex_duplilist(Scene *sce, Object *par)
struct vertexDupliData vdd;
ob= base->object;
+ vdd.lb= lb;
vdd.ob= ob;
vdd.par= par;
Mat4CpyMat4(vdd.pmat, pmat);
@@ -442,9 +432,9 @@ static void vertex_duplilist(Scene *sce, Object *par)
dm->release(dm);
}
-static void particle_duplilist(Scene *sce, Object *par, PartEff *paf)
+static void particle_duplilist(ListBase *lb, Scene *sce, Object *par, PartEff *paf)
{
- Object *ob, *newob;
+ Object *ob, copyob;
Base *base;
Particle *pa;
float ctime, vec1[3];
@@ -460,21 +450,20 @@ static void particle_duplilist(Scene *sce, Object *par, PartEff *paf)
}
ctime= bsystem_time(par, 0, (float)G.scene->r.cfra, 0.0);
-
+
lay= G.scene->lay;
- base= sce->base.first;
- while(base) {
-
+ for(base= sce->base.first; base; base= base->next) {
if(base->object->type>0 && (base->lay & lay) && G.obedit!=base->object) {
ob= base->object->parent;
while(ob) {
if(ob==par) {
ob= base->object;
+ /* temp copy, to have ipos etc to work OK */
+ copyob= *ob;
- pa= paf->keys;
- for(a=0; a<paf->totpart; a++, pa+=paf->totkey) {
+ for(a=0, pa= paf->keys; a<paf->totpart; a++, pa+=paf->totkey) {
if(paf->flag & PAF_STATIC) {
float mtime;
@@ -483,13 +472,12 @@ static void particle_duplilist(Scene *sce, Object *par, PartEff *paf)
mtime= pa->time+pa->lifetime;
for(ctime= pa->time; ctime<mtime; ctime+=paf->staticstep) {
- newob= new_dupli_object(&duplilist, ob, par, 1);
/* make sure hair grows until the end.. */
if(ctime>pa->time+pa->lifetime) ctime= pa->time+pa->lifetime;
/* to give ipos in object correct offset */
- where_is_object_time(newob, ctime-pa->time);
+ where_is_object_time(ob, ctime-pa->time);
where_is_particle(paf, pa, ctime, vec); // makes sure there's always a vec
Mat4MulVecfl(par->obmat, vec);
@@ -502,11 +490,12 @@ static void particle_duplilist(Scene *sce, Object *par, PartEff *paf)
q2= vectoquat(vec1, ob->trackflag, ob->upflag);
QuatToMat3(q2, mat);
- Mat4CpyMat4(tmat, newob->obmat);
- Mat4MulMat43(newob->obmat, tmat, mat);
+ Mat4CpyMat4(tmat, ob->obmat);
+ Mat4MulMat43(ob->obmat, tmat, mat);
}
- VECCOPY(newob->obmat[3], vec);
+ VECCOPY(ob->obmat[3], vec);
+ new_dupli_object(lb, ob, ob->obmat);
}
}
else { // non static particles
@@ -515,10 +504,9 @@ static void particle_duplilist(Scene *sce, Object *par, PartEff *paf)
if((paf->flag & PAF_DIED)==0 && ctime > pa->time+pa->lifetime) continue;
//if(ctime < pa->time+pa->lifetime) {
- newob= new_dupli_object(&duplilist, ob, par, 1);
/* to give ipos in object correct offset */
- where_is_object_time(newob, ctime-pa->time);
+ where_is_object_time(ob, ctime-pa->time);
where_is_particle(paf, pa, ctime, vec);
if(paf->stype==PAF_VECT) {
@@ -528,56 +516,129 @@ static void particle_duplilist(Scene *sce, Object *par, PartEff *paf)
q2= vectoquat(vec1, ob->trackflag, ob->upflag);
QuatToMat3(q2, mat);
- Mat4CpyMat4(tmat, newob->obmat);
- Mat4MulMat43(newob->obmat, tmat, mat);
+ Mat4CpyMat4(tmat, ob->obmat);
+ Mat4MulMat43(ob->obmat, tmat, mat);
}
- VECCOPY(newob->obmat[3], vec);
+ VECCOPY(ob->obmat[3], vec);
+ new_dupli_object(lb, ob, ob->obmat);
}
}
+ /* temp copy, to have ipos etc to work OK */
+ *ob= copyob;
+
break;
}
ob= ob->parent;
}
}
- base= base->next;
}
}
-void free_duplilist()
+static Object *find_family_object(Object **obar, char *family, char ch)
{
Object *ob;
+ int flen;
+
+ if( obar[ch] ) return obar[ch];
- while( (ob= duplilist.first) ) {
- BLI_remlink(&duplilist, ob);
- MEM_freeN(ob);
+ flen= strlen(family);
+
+ ob= G.main->object.first;
+ while(ob) {
+ if( ob->id.name[flen+2]==ch ) {
+ if( strncmp(ob->id.name+2, family, flen)==0 ) break;
+ }
+ ob= ob->id.next;
}
+ obar[ch]= ob;
+
+ return ob;
}
-void make_duplilist(Scene *sce, Object *ob)
+
+static void font_duplilist(ListBase *lb, Object *par)
{
- PartEff *paf;
+ Object *ob, *obar[256];
+ Curve *cu;
+ struct chartrans *ct, *chartransdata;
+ float vec[3], obmat[4][4], pmat[4][4], fsize, xof, yof;
+ int slen, a;
+
+ Mat4CpyMat4(pmat, par->obmat);
+
+ /* in par the family name is stored, use this to find the other objects */
+
+ chartransdata= text_to_curve(par, FO_DUPLI);
+ if(chartransdata==0) return;
+
+ memset(obar, 0, 256*sizeof(void *));
+
+ cu= par->data;
+ slen= strlen(cu->str);
+ fsize= cu->fsize;
+ xof= cu->xof;
+ yof= cu->yof;
+
+ ct= chartransdata;
+
+ for(a=0; a<slen; a++, ct++) {
+
+ ob= find_family_object(obar, cu->family, cu->str[a]);
+ if(ob) {
+ vec[0]= fsize*(ct->xof - xof);
+ vec[1]= fsize*(ct->yof - yof);
+ vec[2]= 0.0;
+
+ Mat4MulVecfl(pmat, vec);
+
+ Mat4CpyMat4(obmat, par->obmat);
+ VECCOPY(obmat[3], vec);
+
+ new_dupli_object(lb, ob, obmat);
+ }
+
+ }
+
+ MEM_freeN(chartransdata);
+}
+
+/* ***************************** */
+ListBase *object_duplilist(Scene *sce, Object *ob)
+{
+ static ListBase duplilist={NULL, NULL};
+
+ if(duplilist.first) {
+ printf("wrong call to object_duplilist\n");
+ return &duplilist;
+ }
+ duplilist.first= duplilist.last= NULL;
+
if(ob->transflag & OB_DUPLI) {
if(ob->transflag & OB_DUPLIVERTS) {
if(ob->type==OB_MESH) {
if(ob->transflag & OB_DUPLIVERTS) {
- if( (paf=give_parteff(ob)) ) particle_duplilist(sce, ob, paf);
- else vertex_duplilist(sce, ob);
+ PartEff *paf;
+ if( (paf=give_parteff(ob)) ) particle_duplilist(&duplilist, sce, ob, paf);
+ else vertex_duplilist(&duplilist, sce, ob);
}
}
else if(ob->type==OB_FONT) {
- font_duplilist(ob);
+ font_duplilist(&duplilist, ob);
}
}
else if(ob->transflag & OB_DUPLIFRAMES)
- frames_duplilist(ob);
+ frames_duplilist(&duplilist, ob);
else if(ob->transflag & OB_DUPLIGROUP)
- group_duplilist(ob);
+ group_duplilist(&duplilist, ob);
}
+
+ return &duplilist;
}
+
int count_duplilist(Object *ob)
{
if(ob->transflag & OB_DUPLI) {
diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c
index 36071d39207..18c8de24feb 100644
--- a/source/blender/blenkernel/intern/depsgraph.c
+++ b/source/blender/blenkernel/intern/depsgraph.c
@@ -1546,14 +1546,15 @@ static int exists_channel(Object *ob, char *name)
return 0;
}
-static void object_time_update_flags(Object *ob)
+static void dag_object_time_update_flags(Object *ob)
{
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;
+ /* motion path or bone child */
+ if(ob->parent->type==OB_CURVE || ob->parent->type==OB_ARMATURE) ob->recalc |= OB_RECALC_OB;
}
if(ob->action || ob->nlastrips.first) {
@@ -1632,7 +1633,7 @@ void DAG_scene_update_flags(Scene *sce, unsigned int lay)
/* now if DagNode were part of base, the node->lay could be checked... */
/* we do all now, since the scene_flush checks layers and clears recalc flags even */
- object_time_update_flags(ob);
+ dag_object_time_update_flags(ob);
/* handled in next loop */
if(ob->dup_group)
@@ -1640,16 +1641,28 @@ void DAG_scene_update_flags(Scene *sce, unsigned int lay)
}
+ /* we do groups each once */
for(group= G.main->group.first; group; group= group->id.next) {
if(group->id.flag & LIB_DOIT) {
for(go= group->gobject.first; go; go= go->next) {
- object_time_update_flags(go->ob);
+ dag_object_time_update_flags(go->ob);
}
- group->id.flag &= ~LIB_DOIT;
}
}
DAG_scene_flush_update(sce, lay);
+
+ /* and store the info in groubobject */
+ for(group= G.main->group.first; group; group= group->id.next) {
+ if(group->id.flag & LIB_DOIT) {
+ for(go= group->gobject.first; go; go= go->next) {
+ go->recalc= go->ob->recalc;
+// printf("ob %s recalc %d\n", go->ob->id.name, go->recalc);
+ }
+ group->id.flag &= ~LIB_DOIT;
+ }
+ }
+
}
/* for depgraph updating, all layers visible in a screen */
diff --git a/source/blender/blenkernel/intern/displist.c b/source/blender/blenkernel/intern/displist.c
index 219ef69d6d2..c27245fc11e 100644
--- a/source/blender/blenkernel/intern/displist.c
+++ b/source/blender/blenkernel/intern/displist.c
@@ -840,8 +840,10 @@ void mesh_create_shadedColors(Object *ob, int onlyForMesh, unsigned int **col1_r
}
-void shadeDispList(Object *ob)
+/* has base pointer, to check for layer */
+void shadeDispList(Base *base)
{
+ Object *ob= base->object;
DispList *dl, *dlob;
Material *ma = NULL;
Curve *cu;
@@ -850,8 +852,6 @@ void shadeDispList(Object *ob)
unsigned int *col1;
int a;
- if(ob->flag & OB_FROMDUPLI) return;
-
dl = find_displist(&ob->disp, DL_VERTCOL);
if (dl) {
BLI_remlink(&ob->disp, dl);
@@ -986,16 +986,13 @@ void reshadeall_displist(void)
freefastshade();
- base= G.scene->base.first;
- while(base) {
+ for(base= G.scene->base.first; base; base= base->next) {
+ ob= base->object;
+ freedisplist(&ob->disp);
if(base->lay & G.scene->lay) {
- ob= base->object;
-
/* Metaballs have standard displist at the Object */
- if(ob->type==OB_MBALL) shadeDispList(ob);
- else freedisplist(&ob->disp);
+ if(ob->type==OB_MBALL) shadeDispList(base);
}
- base= base->next;
}
}
@@ -1388,7 +1385,7 @@ static float calc_taper(Object *taperobj, int cur, int tot)
void makeDispListMBall(Object *ob)
{
- if(!ob || (ob->flag&OB_FROMDUPLI) || ob->type!=OB_MBALL) return;
+ if(!ob || ob->type!=OB_MBALL) return;
freedisplist(&(ob->disp));
diff --git a/source/blender/blenkernel/intern/font.c b/source/blender/blenkernel/intern/font.c
index 2ab13fe328a..b5ed7fb3688 100644
--- a/source/blender/blenkernel/intern/font.c
+++ b/source/blender/blenkernel/intern/font.c
@@ -73,13 +73,6 @@
struct SelBox *selboxes= NULL;
-struct chartrans {
- float xof, yof;
- float rot;
- short linenr,charnr;
- char dobreak;
-};
-
/* UTF-8 <-> wchar transformations */
void
chtoutf8(unsigned long c, char *o)
@@ -1190,86 +1183,4 @@ struct chartrans *text_to_curve(Object *ob, int mode)
return 0;
}
-/* ***************** DUPLI ***************** */
-
-static Object *find_family_object(Object **obar, char *family, char ch)
-{
- Object *ob;
- int flen;
-
- if( obar[ch] ) return obar[ch];
-
- flen= strlen(family);
-
- ob= G.main->object.first;
- while(ob) {
- if( ob->id.name[flen+2]==ch ) {
- if( strncmp(ob->id.name+2, family, flen)==0 ) break;
- }
- ob= ob->id.next;
- }
-
- obar[ch]= ob;
-
- return ob;
-}
-
-
-void font_duplilist(Object *par)
-{
- extern ListBase duplilist;
- Object *ob, *newob, *obar[256];
- Curve *cu;
- struct chartrans *ct, *chartransdata;
- float vec[3], pmat[4][4], fsize, xof, yof;
- int slen, a;
-
- Mat4CpyMat4(pmat, par->obmat);
-
- /* in par the family name is stored, use this to find the other objects */
-
- chartransdata= text_to_curve(par, FO_DUPLI);
- if(chartransdata==0) return;
-
- memset(obar, 0, 256*4);
-
- cu= par->data;
- slen= strlen(cu->str);
- fsize= cu->fsize;
- xof= cu->xof;
- yof= cu->yof;
-
- ct= chartransdata;
-
- for(a=0; a<slen; a++, ct++) {
-
- ob= find_family_object(obar, cu->family, cu->str[a]);
- if(ob) {
- /* not clear if this free line here is still needed */
- freedisplist(&ob->disp);
-
- vec[0]= fsize*(ct->xof - xof);
- vec[1]= fsize*(ct->yof - yof);
- vec[2]= 0.0;
-
- Mat4MulVecfl(pmat, vec);
-
- newob= MEM_mallocN(sizeof(Object), "newobj dupli");
- memcpy(newob, ob, sizeof(Object));
- newob->flag |= OB_FROMDUPLI;
- newob->id.newid= (ID *)par; /* keep duplicator */
- newob->totcol= par->totcol; /* for give_current_material */
-
- Mat4CpyMat4(newob->obmat, par->obmat);
- VECCOPY(newob->obmat[3], vec);
-
- newob->parent= 0;
- newob->track= 0;
-
- BLI_addtail(&duplilist, newob);
- }
-
- }
- MEM_freeN(chartransdata);
-}
diff --git a/source/blender/blenkernel/intern/group.c b/source/blender/blenkernel/intern/group.c
index 0ae6208c9de..5e2d0d6fc6d 100644
--- a/source/blender/blenkernel/intern/group.c
+++ b/source/blender/blenkernel/intern/group.c
@@ -32,19 +32,24 @@
#include "MEM_guardedalloc.h"
-#include "DNA_ID.h"
+#include "DNA_action_types.h"
+#include "DNA_effect_types.h"
#include "DNA_group_types.h"
-#include "DNA_object_types.h"
+#include "DNA_ID.h"
#include "DNA_ipo_types.h"
+#include "DNA_material_types.h"
+#include "DNA_object_types.h"
+#include "DNA_nla_types.h"
+#include "DNA_scene_types.h"
#include "BLI_blenlib.h"
-#include "BKE_global.h"
-#include "BKE_main.h"
-#include "BKE_library.h"
+#include "BKE_global.h"
#include "BKE_group.h"
-#include "BKE_object.h"
#include "BKE_ipo.h"
+#include "BKE_library.h"
+#include "BKE_main.h"
+#include "BKE_object.h"
#ifdef HAVE_CONFIG_H
#include <config.h>
@@ -68,6 +73,34 @@ void free_group(Group *group)
}
}
+void unlink_group(Group *group)
+{
+ Material *ma;
+ Object *ob;
+
+ for(ma= G.main->mat.first; ma; ma= ma->id.next) {
+ if(ma->group==group)
+ ma->group= NULL;
+ }
+ for(ob= G.main->object.first; ob; ob= ob->id.next) {
+ bActionStrip *strip;
+ PartEff *paf;
+
+ if(ob->dup_group==group)
+ ob->dup_group= NULL;
+ for(strip= ob->nlastrips.first; strip; strip= strip->next) {
+ if(strip->object==ob)
+ strip->object= NULL;
+ }
+ for(paf= ob->effect.first; paf; paf= paf->next) {
+ if(paf->type==EFF_PARTICLE) {
+ if(paf->group)
+ paf->group= NULL;
+ }
+ }
+ }
+}
+
Group *add_group()
{
Group *group;
@@ -150,3 +183,109 @@ void group_tag_recalc(Group *group)
}
}
+/* only replaces object strips or action when parent nla instructs it */
+/* keep checking nla.c though, in case internal structure of strip changes */
+static void group_replaces_nla(Object *parent, Object *target, char mode)
+{
+ static ListBase nlastrips={NULL, NULL};
+ static bAction *action= NULL;
+ static int done= 0;
+ bActionStrip *strip, *nstrip;
+
+ if(mode=='s') {
+
+ for(strip= parent->nlastrips.first; strip; strip= strip->next) {
+ if(strip->object==target) {
+ if(done==0) {
+ /* clear nla & action from object */
+ nlastrips= target->nlastrips;
+ target->nlastrips.first= target->nlastrips.last= NULL;
+ action= target->action;
+ target->action= NULL;
+ target->nlaflag |= OB_NLA_OVERRIDE;
+ done= 1;
+ }
+ nstrip= MEM_dupallocN(strip);
+ BLI_addtail(&target->nlastrips, nstrip);
+ }
+ }
+ }
+ else if(mode=='e') {
+ if(done) {
+ BLI_freelistN(&target->nlastrips);
+ target->nlastrips= nlastrips;
+ target->action= action;
+
+ nlastrips.first= nlastrips.last= NULL; /* not needed, but yah... :) */
+ action= NULL;
+ done= 0;
+ }
+ }
+}
+
+
+/* puts all group members in local timing system, after this call
+you can draw everything, leaves tags in objects to signal it needs further updating */
+void group_handle_recalc_and_update(Object *parent, Group *group)
+{
+ GroupObject *go;
+
+ /* if animated group... */
+ if(parent->sf != 0.0f || parent->nlastrips.first) {
+ int cfrao;
+
+ /* switch to local time */
+ cfrao= G.scene->r.cfra;
+ G.scene->r.cfra -= (int)parent->sf;
+
+ /* we need a DAG per group... */
+ for(go= group->gobject.first; go; go= go->next) {
+ if(go->ob && go->recalc) {
+ go->ob->recalc= go->recalc;
+
+ group_replaces_nla(parent, go->ob, 's');
+ object_handle_update(go->ob);
+ group_replaces_nla(parent, go->ob, 'e');
+
+ /* leave recalc tags in case group members are in normal scene */
+ go->ob->recalc= go->recalc;
+ }
+ }
+
+ /* restore */
+ G.scene->r.cfra= cfrao;
+ }
+ else {
+ /* only do existing tags, as set by regular depsgraph */
+ for(go= group->gobject.first; go; go= go->next) {
+ if(go->ob) {
+ if(go->ob->recalc) {
+ object_handle_update(go->ob);
+ }
+ }
+ }
+ }
+}
+
+Object *group_get_member_with_action(Group *group, bAction *act)
+{
+ GroupObject *go;
+
+ if(group==NULL || act==NULL) return NULL;
+
+ for(go= group->gobject.first; go; go= go->next) {
+ if(go->ob) {
+ if(go->ob->action==act)
+ return go->ob;
+ if(go->ob->nlastrips.first) {
+ bActionStrip *strip;
+
+ for(strip= go->ob->nlastrips.first; strip; strip= strip->next) {
+ if(strip->act==act)
+ return go->ob;
+ }
+ }
+ }
+ }
+ return NULL;
+}
diff --git a/source/blender/blenkernel/intern/mball.c b/source/blender/blenkernel/intern/mball.c
index ea1608d8a18..09408e4a220 100644
--- a/source/blender/blenkernel/intern/mball.c
+++ b/source/blender/blenkernel/intern/mball.c
@@ -1437,11 +1437,12 @@ float init_meta(Object *ob) /* return totsize */
Object *bob;
MetaBall *mb;
MetaElem *ml;
- float size, totsize, (*mat)[4] = NULL, (*imat)[4] = NULL, obinv[4][4], vec[3];
+ float size, totsize, (*mat)[4] = NULL, (*imat)[4] = NULL, obinv[4][4], obmat[4][4], vec[3];
float temp1[4][4], temp2[4][4], temp3[4][4]; //max=0.0;
int a, obnr, zero_size=0;
char obname[32];
+ Mat4CpyMat4(obmat, ob->obmat); /* to cope with duplicators from next_object */
Mat4Invert(obinv, ob->obmat);
a= 0;
@@ -1456,7 +1457,7 @@ float init_meta(Object *ob) /* return totsize */
zero_size= 0;
ml= NULL;
- if(bob==ob) {
+ if(bob==ob && (base->flag & OB_FROMDUPLI)==0) {
mat= imat= 0;
mb= ob->data;
@@ -1471,7 +1472,6 @@ float init_meta(Object *ob) /* return totsize */
splitIDname(bob->id.name+2, name, &nr);
if( strcmp(obname, name)==0 ) {
mb= bob->data;
-
if(G.obedit && G.obedit->type==OB_MBALL && G.obedit->data==mb)
ml= editelems.first;
else ml= mb->elems.first;
@@ -1535,7 +1535,7 @@ float init_meta(Object *ob) /* return totsize */
imat= new_pgn_element(4*4*sizeof(float));
/* mat is the matrix to transform from mball into the basis-mball */
- Mat4Invert(obinv, ob->obmat);
+ Mat4Invert(obinv, obmat);
Mat4MulMat4(temp2, bob->obmat, obinv);
/* MetaBall transformation */
Mat4MulMat4(mat, temp1, temp2);
diff --git a/source/blender/blenkernel/intern/nla.c b/source/blender/blenkernel/intern/nla.c
index 5adde76accc..5fefc41f77c 100644
--- a/source/blender/blenkernel/intern/nla.c
+++ b/source/blender/blenkernel/intern/nla.c
@@ -46,6 +46,9 @@
#include <config.h>
#endif
+/* NOTE: in group.c the strips get copied for group-nla override, this assumes
+ that strips are one single block, without additional data to be copied */
+
void copy_actionstrip (bActionStrip **dst, bActionStrip **src){
bActionStrip *dstrip;
bActionStrip *sstrip = *src;
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index 7af6ef21e32..e7cf3577a99 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -208,6 +208,7 @@ void free_object(Object *ob)
ob->path= 0;
if(ob->ipo) ob->ipo->id.us--;
if(ob->action) ob->action->id.us--;
+ if(ob->dup_group) ob->dup_group->id.us--;
if(ob->defbase.first)
BLI_freelistN(&ob->defbase);
if(ob->pose) {
@@ -255,6 +256,7 @@ void unlink_object(Object *ob)
Ipo *ipo;
Group *group;
bConstraint *con;
+ bActionStrip *strip;
int a;
char *str;
@@ -315,6 +317,7 @@ void unlink_object(Object *ob)
obt->recalc |= OB_RECALC_OB;
}
}
+
/* object is deflector or field */
if(ob->pd) {
if(give_parteff(obt))
@@ -322,6 +325,12 @@ void unlink_object(Object *ob)
else if(obt->soft)
obt->recalc |= OB_RECALC_DATA;
}
+
+ /* strips */
+ for(strip= ob->nlastrips.first; strip; strip= strip->next) {
+ if(strip->object==ob)
+ strip->object= NULL;
+ }
}
obt= obt->id.next;
}
@@ -999,15 +1008,10 @@ float bsystem_time(Object *ob, Object *par, float cfra, float ofs)
if(R.r.mode & R_FIELDSTILL); else cfra+= .5;
}
+ cfra+= bluroffs;
- if(ob && (ob->flag & OB_FROMDUPLI));
- else {
- /* motion blur */
- cfra+= bluroffs;
-
- /* global time */
- cfra*= G.scene->r.framelen;
- }
+ /* global time */
+ cfra*= G.scene->r.framelen;
if(no_speed_curve==0) if(ob && ob->ipo) cfra= calc_ipo_time(ob->ipo, cfra);
@@ -1522,9 +1526,6 @@ void solve_tracking (Object *ob, float targetmat[][4])
void where_is_object(Object *ob)
{
- /* these have been mem copied */
- if(ob->flag & OB_FROMDUPLI) return;
-
where_is_object_time(ob, (float)G.scene->r.cfra);
}
diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c
index fd0a6288dbe..df9e626abbf 100644
--- a/source/blender/blenkernel/intern/scene.c
+++ b/source/blender/blenkernel/intern/scene.c
@@ -76,7 +76,7 @@
#include "BKE_utildefines.h"
#include "BPY_extern.h"
-
+#include "BLI_arithb.h"
#include "BLI_blenlib.h"
#include "nla.h"
@@ -277,13 +277,10 @@ void set_scene_bg(Scene *sce)
ob->flag= base->flag;
- ob->recalc= OB_RECALC;
- if(ob->dup_group) group_tag_recalc(ob->dup_group); /* for lib-linked stuff */
-
ob->ctime= -1234567.0; /* force ipo to be calculated later */
base= base->next;
}
- // full update
+ // full animation update
scene_update_for_newframe(sce, sce->lay);
/* do we need FRAMECHANGED in set_scene? */
@@ -309,23 +306,21 @@ void set_scene_name(char *name)
*/
int next_object(int val, Base **base, Object **ob)
{
- extern ListBase duplilist;
- static Object *dupob;
+ static ListBase *duplilist= NULL;
+ static DupliObject *dupob;
static int fase;
int run_again=1;
/* init */
if(val==0) {
fase= F_START;
- dupob= 0;
+ dupob= NULL;
}
else {
/* run_again is set when a duplilist has been ended */
while(run_again) {
run_again= 0;
-
-
/* the first base */
if(fase==F_START) {
@@ -360,30 +355,40 @@ int next_object(int val, Base **base, Object **ob)
}
}
- if(*base == 0) fase= F_START;
+ if(*base == NULL) fase= F_START;
else {
if(fase!=F_DUPLI) {
if( (*base)->object->transflag & OB_DUPLI) {
- make_duplilist(G.scene, (*base)->object);
- dupob= duplilist.first;
+ duplilist= object_duplilist(G.scene, (*base)->object);
+
+ dupob= duplilist->first;
}
}
/* handle dupli's */
if(dupob) {
- *ob= dupob;
+ Mat4CpyMat4(dupob->ob->obmat, dupob->mat);
+
+ (*base)->flag |= OB_FROMDUPLI;
+ *ob= dupob->ob;
fase= F_DUPLI;
- dupob= dupob->id.next;
+ dupob= dupob->next;
}
else if(fase==F_DUPLI) {
fase= F_SCENE;
- free_duplilist();
+ (*base)->flag &= ~OB_FROMDUPLI;
+
+ for(dupob= duplilist->first; dupob; dupob= dupob->next) {
+ Mat4CpyMat4(dupob->ob->obmat, dupob->omat);
+ }
+
+ BLI_freelistN(duplilist);
+ duplilist= NULL;
run_again= 1;
}
-
}
}
}