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

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/blenkernel')
-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;
}
-
}
}
}