Bugfixes 4082 4112 4172 4232
Each report was about a different failure with Particles, all related to weak handling of animation systems and the depsgraph. Fix has 2 parts; depsgraph now signals "object recalc" to be for time changes; this then is used to bypass particle-building (since that's baked). Other part is better object caching while makig particles.
This commit is contained in:
		@@ -1948,8 +1948,8 @@ void makeDispListMesh(Object *ob)
 | 
			
		||||
		editmesh_build_data();
 | 
			
		||||
	} else {
 | 
			
		||||
		mesh_build_data(ob);
 | 
			
		||||
 | 
			
		||||
		build_particle_system(ob);
 | 
			
		||||
		if((ob->recalc & OB_RECALC_TIME)==0)
 | 
			
		||||
			build_particle_system(ob);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1692,8 +1692,6 @@ static void dag_object_time_update_flags(Object *ob)
 | 
			
		||||
						ob->recalc |= OB_RECALC_DATA;
 | 
			
		||||
					else if(paf && paf->keys==NULL)
 | 
			
		||||
						ob->recalc |= OB_RECALC_DATA;
 | 
			
		||||
					else if((paf->flag & PAF_STATIC)==0)
 | 
			
		||||
						ob->recalc &= ~OB_RECALC;	/* NOTE! this is because particles are baked... depsgraph doesnt understand it */
 | 
			
		||||
				}
 | 
			
		||||
				if((ob->fluidsimFlag & OB_FLUIDSIM_ENABLE) && (ob->fluidsimSettings)) {
 | 
			
		||||
					// fluidsimSettings might not be initialized during load...
 | 
			
		||||
@@ -1766,6 +1764,13 @@ void DAG_scene_update_flags(Scene *sce, unsigned int lay)
 | 
			
		||||
	
 | 
			
		||||
	DAG_scene_flush_update(sce, lay);
 | 
			
		||||
	
 | 
			
		||||
	/* test: set time flag, to disable baked systems to update */
 | 
			
		||||
	for(base= sce->base.first; base; base= base->next) {
 | 
			
		||||
		ob= base->object;
 | 
			
		||||
		if(ob->recalc)
 | 
			
		||||
			ob->recalc |= OB_RECALC_TIME;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/* hrmf... an exception to look at once, for invisible camera object we do it over */
 | 
			
		||||
	if(sce->camera)
 | 
			
		||||
		dag_object_time_update_flags(sce->camera);
 | 
			
		||||
 
 | 
			
		||||
@@ -85,7 +85,7 @@
 | 
			
		||||
#include "BKE_utildefines.h"
 | 
			
		||||
 | 
			
		||||
#include "PIL_time.h"
 | 
			
		||||
 | 
			
		||||
#include "elbeem.h"
 | 
			
		||||
#include "RE_render_ext.h"
 | 
			
		||||
 | 
			
		||||
/* temporal struct, used for reading return of mesh_get_mapped_verts_nors() */
 | 
			
		||||
@@ -1523,10 +1523,12 @@ typedef struct pMatrixCache {
 | 
			
		||||
	float imat[3][3];
 | 
			
		||||
} pMatrixCache;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* WARN: this function stores data in ob->id.idnew! */
 | 
			
		||||
static pMatrixCache *cache_object_matrices(Object *ob, int start, int end)
 | 
			
		||||
{
 | 
			
		||||
	pMatrixCache *mcache, *mc;
 | 
			
		||||
	Object ob_store;
 | 
			
		||||
	Object *obcopy;
 | 
			
		||||
	Base *base;
 | 
			
		||||
	float framelenold, cfrao;
 | 
			
		||||
	
 | 
			
		||||
@@ -1535,15 +1537,21 @@ static pMatrixCache *cache_object_matrices(Object *ob, int start, int end)
 | 
			
		||||
	framelenold= G.scene->r.framelen;
 | 
			
		||||
	G.scene->r.framelen= 1.0f;
 | 
			
		||||
	cfrao= G.scene->r.cfra;
 | 
			
		||||
	ob_store= *ob;	/* quick copy of all settings */
 | 
			
		||||
	ob->sf= 0.0f;
 | 
			
		||||
	
 | 
			
		||||
	/* clear storage */
 | 
			
		||||
	for(obcopy= G.main->object.first; obcopy; obcopy= obcopy->id.next) 
 | 
			
		||||
		obcopy->id.newid= NULL;
 | 
			
		||||
	
 | 
			
		||||
	/* all objects get tagged recalc that influence this object */
 | 
			
		||||
	DAG_object_update_flags(G.scene, ob, G.scene->lay);
 | 
			
		||||
	
 | 
			
		||||
	for(G.scene->r.cfra= start; G.scene->r.cfra<=end; G.scene->r.cfra++, mc++) {
 | 
			
		||||
		for(base= G.scene->base.first; base; base= base->next) {
 | 
			
		||||
			if(base->object->recalc) {
 | 
			
		||||
				if(base->object->id.newid==NULL)
 | 
			
		||||
					base->object->id.newid= MEM_dupallocN(base->object);
 | 
			
		||||
				
 | 
			
		||||
				where_is_object(base->object);
 | 
			
		||||
				
 | 
			
		||||
				do_ob_key(base->object);
 | 
			
		||||
@@ -1554,34 +1562,26 @@ static pMatrixCache *cache_object_matrices(Object *ob, int start, int end)
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
//		par= ob;
 | 
			
		||||
//		while(par) {
 | 
			
		||||
//			par->ctime= -1234567.0;		/* hrms? */
 | 
			
		||||
//			do_ob_key(par);
 | 
			
		||||
//			if(par->type==OB_ARMATURE) {
 | 
			
		||||
//				do_all_pose_actions(par);	// only does this object actions
 | 
			
		||||
//				where_is_pose(par);
 | 
			
		||||
//			}
 | 
			
		||||
//			par= par->parent;
 | 
			
		||||
//		}
 | 
			
		||||
		
 | 
			
		||||
//		where_is_object(ob);
 | 
			
		||||
		
 | 
			
		||||
		Mat4CpyMat4(mc->obmat, ob->obmat);
 | 
			
		||||
		Mat4Invert(ob->imat, ob->obmat);
 | 
			
		||||
		Mat3CpyMat4(mc->imat, ob->imat);
 | 
			
		||||
		Mat3Transp(mc->imat);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	
 | 
			
		||||
	/* restore */
 | 
			
		||||
	G.scene->r.cfra= cfrao;
 | 
			
		||||
	G.scene->r.framelen= framelenold;
 | 
			
		||||
	*ob= ob_store;
 | 
			
		||||
 | 
			
		||||
	for(base= G.scene->base.first; base; base= base->next) {
 | 
			
		||||
		where_is_object(base->object);
 | 
			
		||||
		if(base->object->recalc) {
 | 
			
		||||
			
 | 
			
		||||
			if(base->object->id.newid) {
 | 
			
		||||
				obcopy= (Object *)base->object->id.newid;
 | 
			
		||||
				*(base->object) = *(obcopy); 
 | 
			
		||||
				MEM_freeN(obcopy);
 | 
			
		||||
				base->object->id.newid= NULL;
 | 
			
		||||
			}
 | 
			
		||||
			
 | 
			
		||||
			do_ob_key(base->object);
 | 
			
		||||
			if(base->object->type==OB_ARMATURE) {
 | 
			
		||||
				do_all_pose_actions(base->object);	// only does this object actions
 | 
			
		||||
@@ -1590,20 +1590,6 @@ static pMatrixCache *cache_object_matrices(Object *ob, int start, int end)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	
 | 
			
		||||
	/* restore hierarchy, weak code destroying potential depgraph stuff... */
 | 
			
		||||
//	par= ob;
 | 
			
		||||
//	while(par) {
 | 
			
		||||
		/* do not do ob->ipo: keep insertkey */
 | 
			
		||||
//		do_ob_key(par);
 | 
			
		||||
		
 | 
			
		||||
//		if(par->type==OB_ARMATURE) {
 | 
			
		||||
//			do_all_pose_actions(par);	// only does this object actions
 | 
			
		||||
//			where_is_pose(par);
 | 
			
		||||
//		}
 | 
			
		||||
//		par= par->parent;
 | 
			
		||||
//	}
 | 
			
		||||
	
 | 
			
		||||
	return mcache;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -1644,6 +1630,8 @@ void build_particle_system(Object *ob)
 | 
			
		||||
	if(paf->keys) MEM_freeN(paf->keys);	/* free as early as possible, for returns */
 | 
			
		||||
	paf->keys= NULL;
 | 
			
		||||
	
 | 
			
		||||
	printf("build particles\n");
 | 
			
		||||
	
 | 
			
		||||
	// FSPARTICLE all own created...
 | 
			
		||||
	if( (1) && (ob->fluidsimFlag & OB_FLUIDSIM_ENABLE) && 
 | 
			
		||||
	    (ob->fluidsimSettings) && 
 | 
			
		||||
 
 | 
			
		||||
@@ -345,8 +345,9 @@ extern Object workob;
 | 
			
		||||
/* ob->recalc (flag bits!) */
 | 
			
		||||
#define OB_RECALC_OB		1
 | 
			
		||||
#define OB_RECALC_DATA		2
 | 
			
		||||
#define OB_RECALC			3
 | 
			
		||||
 | 
			
		||||
		/* time flag is set when time changes need recalc, so baked systems can ignore it */
 | 
			
		||||
#define OB_RECALC_TIME		4
 | 
			
		||||
#define OB_RECALC			7
 | 
			
		||||
 | 
			
		||||
/* ob->gameflag */
 | 
			
		||||
#define OB_DYNAMIC		1
 | 
			
		||||
 
 | 
			
		||||
@@ -2660,6 +2660,7 @@ void common_insertkey(void)
 | 
			
		||||
 						insertmatrixkey(id, ID_OB, actname, NULL, OB_ROT_Y, eul[1]*(5.72958));
 | 
			
		||||
 						insertmatrixkey(id, ID_OB, actname, NULL, OB_ROT_Z, eul[2]*(5.72958));
 | 
			
		||||
 					}
 | 
			
		||||
					base->object->recalc |= OB_RECALC_OB;
 | 
			
		||||
				}
 | 
			
		||||
				base= base->next;
 | 
			
		||||
			}
 | 
			
		||||
@@ -2674,6 +2675,8 @@ void common_insertkey(void)
 | 
			
		||||
		else if(event==7) BIF_undo_push("Insert Vertex Key");
 | 
			
		||||
		else if(event==9) BIF_undo_push("Insert Avail Key");
 | 
			
		||||
		
 | 
			
		||||
		DAG_scene_flush_update(G.scene, screen_view3d_layers());
 | 
			
		||||
		
 | 
			
		||||
		allspace(REMAKEIPO, 0);
 | 
			
		||||
		allqueue(REDRAWIPO, 0);
 | 
			
		||||
		allqueue(REDRAWVIEW3D, 0);
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user