Render instancing can now also handle the same object in multiple,
non-animated dupligroups.
This commit is contained in:
		@@ -46,7 +46,7 @@ typedef struct DupliObject {
 | 
			
		||||
	struct DupliObject *next, *prev;
 | 
			
		||||
	struct Object *ob;
 | 
			
		||||
	unsigned int origlay;
 | 
			
		||||
	int index, no_draw, type;
 | 
			
		||||
	int index, no_draw, type, animated;
 | 
			
		||||
	float mat[4][4], omat[4][4];
 | 
			
		||||
	float orco[3], uv[2];
 | 
			
		||||
} DupliObject;
 | 
			
		||||
 
 | 
			
		||||
@@ -47,6 +47,7 @@ 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, struct Group *group);
 | 
			
		||||
int			object_in_group(struct Object *ob, struct Group *group);
 | 
			
		||||
int			group_is_animated(struct Object *parent, struct Group *group);
 | 
			
		||||
 | 
			
		||||
void		group_tag_recalc(struct Group *group);
 | 
			
		||||
void		group_handle_recalc_and_update(struct Object *parent, struct Group *group);
 | 
			
		||||
 
 | 
			
		||||
@@ -76,7 +76,7 @@
 | 
			
		||||
#include <config.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
static void object_duplilist_recursive(ID *id, Object *ob, ListBase *duplilist, float par_space_mat[][4], int level);
 | 
			
		||||
static void object_duplilist_recursive(ID *id, Object *ob, ListBase *duplilist, float par_space_mat[][4], int level, int animated);
 | 
			
		||||
 | 
			
		||||
void free_path(Path *path)
 | 
			
		||||
{
 | 
			
		||||
@@ -284,7 +284,7 @@ int where_on_path(Object *ob, float ctime, float *vec, float *dir)	/* returns OK
 | 
			
		||||
 | 
			
		||||
/* ****************** DUPLICATOR ************** */
 | 
			
		||||
 | 
			
		||||
static DupliObject *new_dupli_object(ListBase *lb, Object *ob, float mat[][4], int lay, int index, int type)
 | 
			
		||||
static DupliObject *new_dupli_object(ListBase *lb, Object *ob, float mat[][4], int lay, int index, int type, int animated)
 | 
			
		||||
{
 | 
			
		||||
	DupliObject *dob= MEM_callocN(sizeof(DupliObject), "dupliobject");
 | 
			
		||||
	
 | 
			
		||||
@@ -295,12 +295,13 @@ static DupliObject *new_dupli_object(ListBase *lb, Object *ob, float mat[][4], i
 | 
			
		||||
	dob->origlay= ob->lay;
 | 
			
		||||
	dob->index= index;
 | 
			
		||||
	dob->type= type;
 | 
			
		||||
	dob->animated= (type == OB_DUPLIGROUP) && animated;
 | 
			
		||||
	ob->lay= lay;
 | 
			
		||||
	
 | 
			
		||||
	return dob;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void group_duplilist(ListBase *lb, Object *ob, int level)
 | 
			
		||||
static void group_duplilist(ListBase *lb, Object *ob, int level, int animated)
 | 
			
		||||
{
 | 
			
		||||
	DupliObject *dob;
 | 
			
		||||
	Group *group;
 | 
			
		||||
@@ -316,25 +317,26 @@ static void group_duplilist(ListBase *lb, Object *ob, int level)
 | 
			
		||||
	/* handles animated groups, and */
 | 
			
		||||
	/* we need to check update for objects that are not in scene... */
 | 
			
		||||
	group_handle_recalc_and_update(ob, group);
 | 
			
		||||
	animated= animated || group_is_animated(ob, group);
 | 
			
		||||
	
 | 
			
		||||
	for(go= group->gobject.first; go; go= go->next) {
 | 
			
		||||
		/* note, if you check on layer here, render goes wrong... it still deforms verts and uses parent imat */
 | 
			
		||||
		if(go->ob!=ob) {
 | 
			
		||||
			
 | 
			
		||||
			Mat4MulMat4(mat, go->ob->obmat, ob->obmat);
 | 
			
		||||
			dob= new_dupli_object(lb, go->ob, mat, ob->lay, 0, OB_DUPLIGROUP);
 | 
			
		||||
			dob= new_dupli_object(lb, go->ob, mat, ob->lay, 0, OB_DUPLIGROUP, animated);
 | 
			
		||||
			dob->no_draw= (dob->origlay & group->layer)==0;
 | 
			
		||||
			
 | 
			
		||||
			if(go->ob->transflag & OB_DUPLI) {
 | 
			
		||||
				Mat4CpyMat4(dob->ob->obmat, dob->mat);
 | 
			
		||||
				object_duplilist_recursive((ID *)group, go->ob, lb, ob->obmat, level+1);
 | 
			
		||||
				object_duplilist_recursive((ID *)group, go->ob, lb, ob->obmat, level+1, animated);
 | 
			
		||||
				Mat4CpyMat4(dob->ob->obmat, dob->omat);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void frames_duplilist(ListBase *lb, Object *ob, int level)
 | 
			
		||||
static void frames_duplilist(ListBase *lb, Object *ob, int level, int animated)
 | 
			
		||||
{
 | 
			
		||||
	extern int enable_cu_speed;	/* object.c */
 | 
			
		||||
	Object copyob;
 | 
			
		||||
@@ -361,7 +363,7 @@ static void frames_duplilist(ListBase *lb, Object *ob, int level)
 | 
			
		||||
		if(ok) {
 | 
			
		||||
			do_ob_ipo(ob);
 | 
			
		||||
			where_is_object_time(ob, (float)G.scene->r.cfra);
 | 
			
		||||
			new_dupli_object(lb, ob, ob->obmat, ob->lay, G.scene->r.cfra, OB_DUPLIFRAMES);
 | 
			
		||||
			new_dupli_object(lb, ob, ob->obmat, ob->lay, G.scene->r.cfra, OB_DUPLIFRAMES, animated);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@@ -373,6 +375,7 @@ static void frames_duplilist(ListBase *lb, Object *ob, int level)
 | 
			
		||||
struct vertexDupliData {
 | 
			
		||||
	ID *id; /* scene or group, for recursive loops */
 | 
			
		||||
	int level;
 | 
			
		||||
	int animated;
 | 
			
		||||
	ListBase *lb;
 | 
			
		||||
	float pmat[4][4];
 | 
			
		||||
	float obmat[4][4]; /* Only used for dupliverts inside dupligroups, where the ob->obmat is modified */
 | 
			
		||||
@@ -408,7 +411,7 @@ static void vertex_dupli__mapFunc(void *userData, int index, float *co, float *n
 | 
			
		||||
		Mat4CpyMat4(tmat, obmat);
 | 
			
		||||
		Mat4MulMat43(obmat, tmat, mat);
 | 
			
		||||
	}
 | 
			
		||||
	dob= new_dupli_object(vdd->lb, vdd->ob, obmat, vdd->par->lay, index, OB_DUPLIVERTS);
 | 
			
		||||
	dob= new_dupli_object(vdd->lb, vdd->ob, obmat, vdd->par->lay, index, OB_DUPLIVERTS, vdd->animated);
 | 
			
		||||
	if(vdd->orco)
 | 
			
		||||
		VECCOPY(dob->orco, vdd->orco[index]);
 | 
			
		||||
	
 | 
			
		||||
@@ -416,12 +419,12 @@ static void vertex_dupli__mapFunc(void *userData, int index, float *co, float *n
 | 
			
		||||
		float tmpmat[4][4];
 | 
			
		||||
		Mat4CpyMat4(tmpmat, vdd->ob->obmat);
 | 
			
		||||
		Mat4CpyMat4(vdd->ob->obmat, obmat); /* pretend we are really this mat */
 | 
			
		||||
		object_duplilist_recursive((ID *)vdd->id, vdd->ob, vdd->lb, obmat, vdd->level+1);
 | 
			
		||||
		object_duplilist_recursive((ID *)vdd->id, vdd->ob, vdd->lb, obmat, vdd->level+1, vdd->animated);
 | 
			
		||||
		Mat4CpyMat4(vdd->ob->obmat, tmpmat);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void vertex_duplilist(ListBase *lb, ID *id, Object *par, float par_space_mat[][4], int level)
 | 
			
		||||
static void vertex_duplilist(ListBase *lb, ID *id, Object *par, float par_space_mat[][4], int level, int animated)
 | 
			
		||||
{
 | 
			
		||||
	Object *ob, *ob_iter;
 | 
			
		||||
	Mesh *me;
 | 
			
		||||
@@ -493,6 +496,7 @@ static void vertex_duplilist(ListBase *lb, ID *id, Object *par, float par_space_
 | 
			
		||||
 | 
			
		||||
					vdd.id= id;
 | 
			
		||||
					vdd.level= level;
 | 
			
		||||
					vdd.animated= animated;
 | 
			
		||||
					vdd.lb= lb;
 | 
			
		||||
					vdd.ob= ob;
 | 
			
		||||
					vdd.par= par;
 | 
			
		||||
@@ -527,7 +531,7 @@ static void vertex_duplilist(ListBase *lb, ID *id, Object *par, float par_space_
 | 
			
		||||
	dm->release(dm);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void face_duplilist(ListBase *lb, ID *id, Object *par, float par_space_mat[][4], int level)
 | 
			
		||||
static void face_duplilist(ListBase *lb, ID *id, Object *par, float par_space_mat[][4], int level, int animated)
 | 
			
		||||
{
 | 
			
		||||
	Object *ob, *ob_iter;
 | 
			
		||||
	Base *base = NULL;
 | 
			
		||||
@@ -663,7 +667,7 @@ static void face_duplilist(ListBase *lb, ID *id, Object *par, float par_space_ma
 | 
			
		||||
						Mat4CpyMat4(tmat, obmat);
 | 
			
		||||
						Mat4MulMat43(obmat, tmat, mat);
 | 
			
		||||
						
 | 
			
		||||
						dob= new_dupli_object(lb, ob, obmat, lay, a, OB_DUPLIFACES);
 | 
			
		||||
						dob= new_dupli_object(lb, ob, obmat, lay, a, OB_DUPLIFACES, animated);
 | 
			
		||||
						if(G.rendering) {
 | 
			
		||||
							w= (mv4)? 0.25f: 1.0f/3.0f;
 | 
			
		||||
 | 
			
		||||
@@ -694,7 +698,7 @@ static void face_duplilist(ListBase *lb, ID *id, Object *par, float par_space_ma
 | 
			
		||||
							float tmpmat[4][4];
 | 
			
		||||
							Mat4CpyMat4(tmpmat, ob->obmat);
 | 
			
		||||
							Mat4CpyMat4(ob->obmat, obmat); /* pretend we are really this mat */
 | 
			
		||||
							object_duplilist_recursive((ID *)id, ob, lb, ob->obmat, level+1);
 | 
			
		||||
							object_duplilist_recursive((ID *)id, ob, lb, ob->obmat, level+1, animated);
 | 
			
		||||
							Mat4CpyMat4(ob->obmat, tmpmat);
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
@@ -719,7 +723,7 @@ static void face_duplilist(ListBase *lb, ID *id, Object *par, float par_space_ma
 | 
			
		||||
	dm->release(dm);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void new_particle_duplilist(ListBase *lb, ID *id, Object *par, float par_space_mat[][4], ParticleSystem *psys, int level)
 | 
			
		||||
static void new_particle_duplilist(ListBase *lb, ID *id, Object *par, float par_space_mat[][4], ParticleSystem *psys, int level, int animated)
 | 
			
		||||
{
 | 
			
		||||
	GroupObject *go;
 | 
			
		||||
	Object *ob=0, **oblist=0;
 | 
			
		||||
@@ -868,7 +872,7 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Object *par, float par_
 | 
			
		||||
						else
 | 
			
		||||
							Mat4CpyMat4(mat, tmat);
 | 
			
		||||
 | 
			
		||||
						dob= new_dupli_object(lb, go->ob, mat, par->lay, counter, OB_DUPLIPARTS);
 | 
			
		||||
						dob= new_dupli_object(lb, go->ob, mat, par->lay, counter, OB_DUPLIPARTS, animated);
 | 
			
		||||
						if(G.rendering)
 | 
			
		||||
							psys_get_dupli_texture(par, part, psmd, pa, cpa, dob->uv, dob->orco);
 | 
			
		||||
					}
 | 
			
		||||
@@ -894,7 +898,7 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Object *par, float par_
 | 
			
		||||
					else
 | 
			
		||||
						Mat4CpyMat4(mat, tmat);
 | 
			
		||||
 | 
			
		||||
					dob= new_dupli_object(lb, ob, mat, par->lay, counter, OB_DUPLIPARTS);
 | 
			
		||||
					dob= new_dupli_object(lb, ob, mat, par->lay, counter, OB_DUPLIPARTS, animated);
 | 
			
		||||
					if(G.rendering)
 | 
			
		||||
						psys_get_dupli_texture(par, part, psmd, pa, cpa, dob->uv, dob->orco);
 | 
			
		||||
				}
 | 
			
		||||
@@ -935,7 +939,7 @@ static Object *find_family_object(Object **obar, char *family, char ch)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void font_duplilist(ListBase *lb, Object *par, int level)
 | 
			
		||||
static void font_duplilist(ListBase *lb, Object *par, int level, int animated)
 | 
			
		||||
{
 | 
			
		||||
	Object *ob, *obar[256];
 | 
			
		||||
	Curve *cu;
 | 
			
		||||
@@ -976,16 +980,15 @@ static void font_duplilist(ListBase *lb, Object *par, int level)
 | 
			
		||||
			Mat4CpyMat4(obmat, par->obmat);
 | 
			
		||||
			VECCOPY(obmat[3], vec);
 | 
			
		||||
			
 | 
			
		||||
			new_dupli_object(lb, ob, obmat, par->lay, a, OB_DUPLIVERTS);
 | 
			
		||||
			new_dupli_object(lb, ob, obmat, par->lay, a, OB_DUPLIVERTS, animated);
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	MEM_freeN(chartransdata);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* ***************************** */
 | 
			
		||||
static void object_duplilist_recursive(ID *id, Object *ob, ListBase *duplilist, float par_space_mat[][4], int level)
 | 
			
		||||
static void object_duplilist_recursive(ID *id, Object *ob, ListBase *duplilist, float par_space_mat[][4], int level, int animated)
 | 
			
		||||
{	
 | 
			
		||||
	if((ob->transflag & OB_DUPLI)==0)
 | 
			
		||||
		return;
 | 
			
		||||
@@ -1004,30 +1007,30 @@ static void object_duplilist_recursive(ID *id, Object *ob, ListBase *duplilist,
 | 
			
		||||
	if(ob->transflag & OB_DUPLIPARTS) {
 | 
			
		||||
		ParticleSystem *psys = ob->particlesystem.first;
 | 
			
		||||
		for(; psys; psys=psys->next)
 | 
			
		||||
			new_particle_duplilist(duplilist, id, ob, par_space_mat, psys, level+1);
 | 
			
		||||
			new_particle_duplilist(duplilist, id, ob, par_space_mat, psys, level+1, animated);
 | 
			
		||||
	}
 | 
			
		||||
	else if(ob->transflag & OB_DUPLIVERTS) {
 | 
			
		||||
		if(ob->type==OB_MESH) {
 | 
			
		||||
			vertex_duplilist(duplilist, id, ob, par_space_mat, level+1);
 | 
			
		||||
			vertex_duplilist(duplilist, id, ob, par_space_mat, level+1, animated);
 | 
			
		||||
		}
 | 
			
		||||
		else if(ob->type==OB_FONT) {
 | 
			
		||||
			if (GS(id->name)==ID_SCE) { /* TODO - support dupligroups */
 | 
			
		||||
				font_duplilist(duplilist, ob, level+1);
 | 
			
		||||
				font_duplilist(duplilist, ob, level+1, animated);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	else if(ob->transflag & OB_DUPLIFACES) {
 | 
			
		||||
		if(ob->type==OB_MESH)
 | 
			
		||||
			face_duplilist(duplilist, id, ob, par_space_mat, level+1);
 | 
			
		||||
			face_duplilist(duplilist, id, ob, par_space_mat, level+1, animated);
 | 
			
		||||
	}
 | 
			
		||||
	else if(ob->transflag & OB_DUPLIFRAMES) {
 | 
			
		||||
		if (GS(id->name)==ID_SCE) { /* TODO - support dupligroups */
 | 
			
		||||
			frames_duplilist(duplilist, ob, level+1);
 | 
			
		||||
			frames_duplilist(duplilist, ob, level+1, animated);
 | 
			
		||||
		}
 | 
			
		||||
	} else if(ob->transflag & OB_DUPLIGROUP) {
 | 
			
		||||
		DupliObject *dob;
 | 
			
		||||
		
 | 
			
		||||
		group_duplilist(duplilist, ob, level+1); /* now recursive */
 | 
			
		||||
		group_duplilist(duplilist, ob, level+1, animated); /* now recursive */
 | 
			
		||||
 | 
			
		||||
		if (level==0) {
 | 
			
		||||
			for(dob= duplilist->first; dob; dob= dob->next)
 | 
			
		||||
@@ -1042,7 +1045,7 @@ ListBase *object_duplilist(Scene *sce, Object *ob)
 | 
			
		||||
{
 | 
			
		||||
	ListBase *duplilist= MEM_mallocN(sizeof(ListBase), "duplilist");
 | 
			
		||||
	duplilist->first= duplilist->last= NULL;
 | 
			
		||||
	object_duplilist_recursive((ID *)sce, ob, duplilist, NULL, 0);
 | 
			
		||||
	object_duplilist_recursive((ID *)sce, ob, duplilist, NULL, 0, 0);
 | 
			
		||||
	return duplilist;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -191,6 +191,20 @@ void group_tag_recalc(Group *group)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int group_is_animated(Object *parent, Group *group)
 | 
			
		||||
{
 | 
			
		||||
	GroupObject *go;
 | 
			
		||||
 | 
			
		||||
	if(give_timeoffset(parent) != 0.0f || parent->nlastrips.first)
 | 
			
		||||
		return 1;
 | 
			
		||||
 | 
			
		||||
	for(go= group->gobject.first; go; go= go->next)
 | 
			
		||||
		if(go->ob && go->ob->proxy)
 | 
			
		||||
			return 1;
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* 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)
 | 
			
		||||
@@ -231,7 +245,6 @@ static void group_replaces_nla(Object *parent, Object *target, char mode)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* 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 */
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -244,7 +244,7 @@ typedef struct ObjectRen {
 | 
			
		||||
	struct ObjectRen *next, *prev;
 | 
			
		||||
	struct Object *ob, *par;
 | 
			
		||||
	struct Scene *sce;
 | 
			
		||||
	int index, psysindex;
 | 
			
		||||
	int index, psysindex, flag;
 | 
			
		||||
 | 
			
		||||
	int totvert, totvlak, totstrand, tothalo;
 | 
			
		||||
	int vertnodeslen, vlaknodeslen, strandnodeslen, blohalen;
 | 
			
		||||
@@ -257,6 +257,8 @@ typedef struct ObjectRen {
 | 
			
		||||
	char (*mtface)[32];
 | 
			
		||||
	char (*mcol)[32];
 | 
			
		||||
	int  actmtface, actmcol;
 | 
			
		||||
 | 
			
		||||
	float obmat[4][4];	/* only used in convertblender.c, for instancing */
 | 
			
		||||
} ObjectRen;
 | 
			
		||||
 | 
			
		||||
typedef struct ObjectInstanceRen {
 | 
			
		||||
@@ -487,10 +489,14 @@ typedef struct LampRen {
 | 
			
		||||
#define R_STRAND_BSPLINE	1
 | 
			
		||||
#define R_STRAND_B_UNITS	2
 | 
			
		||||
 | 
			
		||||
/* objectren->flag */
 | 
			
		||||
#define R_INSTANCEABLE		1
 | 
			
		||||
 | 
			
		||||
/* objectinstance->flag */
 | 
			
		||||
#define R_DUPLI_TRANSFORMED	1
 | 
			
		||||
#define R_ENV_TRANSFORMED	2
 | 
			
		||||
#define R_TRANSFORMED		(1|2)
 | 
			
		||||
#define R_DUPLI_ELEM		4
 | 
			
		||||
 | 
			
		||||
#endif /* RENDER_TYPES_H */
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -3896,7 +3896,7 @@ static void find_dupli_instances(Render *re, ObjectRen *obr)
 | 
			
		||||
	float imat[4][4], obmat[4][4], obimat[4][4], nmat[3][3];
 | 
			
		||||
	int first = 1;
 | 
			
		||||
 | 
			
		||||
	Mat4MulMat4(obmat, obr->ob->obmat, re->viewmat);
 | 
			
		||||
	Mat4MulMat4(obmat, obr->obmat, re->viewmat);
 | 
			
		||||
	Mat4Invert(imat, obmat);
 | 
			
		||||
 | 
			
		||||
	for(obi=re->instancetable.last; obi; obi=obi->prev) {
 | 
			
		||||
@@ -3923,6 +3923,40 @@ static void find_dupli_instances(Render *re, ObjectRen *obr)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void assign_dupligroup_dupli(Render *re, ObjectInstanceRen *obi, ObjectRen *obr)
 | 
			
		||||
{
 | 
			
		||||
	float imat[4][4], obmat[4][4], obimat[4][4], nmat[3][3];
 | 
			
		||||
 | 
			
		||||
	Mat4MulMat4(obmat, obr->obmat, re->viewmat);
 | 
			
		||||
	Mat4Invert(imat, obmat);
 | 
			
		||||
 | 
			
		||||
	obi->obr= obr;
 | 
			
		||||
 | 
			
		||||
	/* compute difference between object matrix and
 | 
			
		||||
	 * object matrix with dupli transform, in viewspace */
 | 
			
		||||
	Mat4CpyMat4(obimat, obi->mat);
 | 
			
		||||
	Mat4MulMat4(obi->mat, imat, obimat);
 | 
			
		||||
 | 
			
		||||
	Mat3CpyMat4(nmat, obi->mat);
 | 
			
		||||
	Mat3Inv(obi->imat, nmat);
 | 
			
		||||
 | 
			
		||||
	re->totvert += obr->totvert;
 | 
			
		||||
	re->totvlak += obr->totvlak;
 | 
			
		||||
	re->tothalo += obr->tothalo;
 | 
			
		||||
	re->totstrand += obr->totstrand;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static ObjectRen *find_dupligroup_dupli(Render *re, Object *ob, int psysindex)
 | 
			
		||||
{
 | 
			
		||||
	ObjectRen *obr;
 | 
			
		||||
 | 
			
		||||
	for(obr=re->objecttable.first; obr; obr=obr->next)
 | 
			
		||||
		if(obr->ob == ob && obr->psysindex == psysindex && (obr->flag & R_INSTANCEABLE))
 | 
			
		||||
			return obr;
 | 
			
		||||
	
 | 
			
		||||
	return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void init_render_object_data(Render *re, ObjectRen *obr, int only_verts)
 | 
			
		||||
{
 | 
			
		||||
	Object *ob= obr->ob;
 | 
			
		||||
@@ -3962,7 +3996,7 @@ static void init_render_object_data(Render *re, ObjectRen *obr, int only_verts)
 | 
			
		||||
	re->totstrand += obr->totstrand;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void add_render_object(Render *re, Object *ob, Object *par, int index, int only_verts)
 | 
			
		||||
static void add_render_object(Render *re, Object *ob, Object *par, int index, int only_verts, int instanceable)
 | 
			
		||||
{
 | 
			
		||||
	ObjectRen *obr;
 | 
			
		||||
	ParticleSystem *psys;
 | 
			
		||||
@@ -3985,6 +4019,10 @@ static void add_render_object(Render *re, Object *ob, Object *par, int index, in
 | 
			
		||||
	/* one render object for the data itself */
 | 
			
		||||
	if(allow_render) {
 | 
			
		||||
		obr= RE_addRenderObject(re, ob, par, index, 0);
 | 
			
		||||
		if(instanceable) {
 | 
			
		||||
			obr->flag |= R_INSTANCEABLE;
 | 
			
		||||
			Mat4CpyMat4(obr->obmat, ob->obmat);
 | 
			
		||||
		}
 | 
			
		||||
		init_render_object_data(re, obr, only_verts);
 | 
			
		||||
 | 
			
		||||
		/* only add instance for objects that have not been used for dupli */
 | 
			
		||||
@@ -3999,6 +4037,10 @@ static void add_render_object(Render *re, Object *ob, Object *par, int index, in
 | 
			
		||||
		psysindex= 1;
 | 
			
		||||
		for(psys=ob->particlesystem.first; psys; psys=psys->next, psysindex++) {
 | 
			
		||||
			obr= RE_addRenderObject(re, ob, par, index, psysindex);
 | 
			
		||||
			if(instanceable) {
 | 
			
		||||
				obr->flag |= R_INSTANCEABLE;
 | 
			
		||||
				Mat4CpyMat4(obr->obmat, ob->obmat);
 | 
			
		||||
			}
 | 
			
		||||
			init_render_object_data(re, obr, only_verts);
 | 
			
		||||
			psys_render_restore(ob, psys);
 | 
			
		||||
 | 
			
		||||
@@ -4013,7 +4055,7 @@ static void add_render_object(Render *re, Object *ob, Object *par, int index, in
 | 
			
		||||
 | 
			
		||||
/* par = pointer to duplicator parent, needed for object lookup table */
 | 
			
		||||
/* index = when duplicater copies same object (particle), the counter */
 | 
			
		||||
static void init_render_object(Render *re, Object *ob, Object *par, int index, int only_verts)
 | 
			
		||||
static void init_render_object(Render *re, Object *ob, Object *par, int index, int only_verts, int instanceable)
 | 
			
		||||
{
 | 
			
		||||
	static double lasttime= 0.0;
 | 
			
		||||
	double time;
 | 
			
		||||
@@ -4022,7 +4064,7 @@ static void init_render_object(Render *re, Object *ob, Object *par, int index, i
 | 
			
		||||
	if(ob->type==OB_LAMP)
 | 
			
		||||
		add_render_lamp(re, ob);
 | 
			
		||||
	else if(render_object_type(ob->type))
 | 
			
		||||
		add_render_object(re, ob, par, index, only_verts);
 | 
			
		||||
		add_render_object(re, ob, par, index, only_verts, instanceable);
 | 
			
		||||
	else {
 | 
			
		||||
		MTC_Mat4MulMat4(mat, ob->obmat, re->viewmat);
 | 
			
		||||
		MTC_Mat4Invert(ob->imat, mat);
 | 
			
		||||
@@ -4151,7 +4193,7 @@ static int allow_render_object(Object *ob, int nolamps, int onlyselected, Object
 | 
			
		||||
static int allow_render_dupli_instance(Render *re, DupliObject *dob, Object *obd)
 | 
			
		||||
{
 | 
			
		||||
	return (render_object_type(obd->type) &&
 | 
			
		||||
	        (!(dob->type == OB_DUPLIGROUP)) &&
 | 
			
		||||
	        (!(dob->type == OB_DUPLIGROUP) || !dob->animated) &&
 | 
			
		||||
	        !(re->r.mode & R_RADIO));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -4224,7 +4266,7 @@ static void database_init_objects(Render *re, unsigned int lay, int nolamps, int
 | 
			
		||||
		if(ob->flag & OB_DONE) {
 | 
			
		||||
			if(ob->transflag & OB_RENDER_DUPLI)
 | 
			
		||||
				if(allow_render_object(ob, nolamps, onlyselected, actob))
 | 
			
		||||
					init_render_object(re, ob, NULL, 0, only_verts);
 | 
			
		||||
					init_render_object(re, ob, NULL, 0, only_verts, 1);
 | 
			
		||||
		}
 | 
			
		||||
		else if((base->lay & lay) || (ob->type==OB_LAMP && (base->lay & re->scene->lay)) ) {
 | 
			
		||||
			if((ob->transflag & OB_DUPLI) && (ob->type!=OB_MBALL)) {
 | 
			
		||||
@@ -4255,38 +4297,60 @@ static void database_init_objects(Render *re, unsigned int lay, int nolamps, int
 | 
			
		||||
 | 
			
		||||
					if(allow_render_dupli_instance(re, dob, obd)) {
 | 
			
		||||
						ParticleSystem *psys;
 | 
			
		||||
						ObjectRen *obr = NULL;
 | 
			
		||||
						int psysindex;
 | 
			
		||||
						float mat[4][4];
 | 
			
		||||
 | 
			
		||||
						Mat4MulMat4(mat, dob->mat, re->viewmat);
 | 
			
		||||
						obi= RE_addRenderInstance(re, NULL, obd, ob, dob->index, 0, mat);
 | 
			
		||||
						VECCOPY(obi->dupliorco, dob->orco);
 | 
			
		||||
						obi->dupliuv[0]= dob->uv[0];
 | 
			
		||||
						obi->dupliuv[1]= dob->uv[1];
 | 
			
		||||
						if(dob->type != OB_DUPLIGROUP || (obr=find_dupligroup_dupli(re, obd, 0))) {
 | 
			
		||||
							Mat4MulMat4(mat, dob->mat, re->viewmat);
 | 
			
		||||
							obi= RE_addRenderInstance(re, NULL, obd, ob, dob->index, 0, mat);
 | 
			
		||||
 | 
			
		||||
							if(dob->type != OB_DUPLIGROUP) {
 | 
			
		||||
								VECCOPY(obi->dupliorco, dob->orco);
 | 
			
		||||
								obi->dupliuv[0]= dob->uv[0];
 | 
			
		||||
								obi->dupliuv[1]= dob->uv[1];
 | 
			
		||||
								obi->flag |= R_DUPLI_ELEM;
 | 
			
		||||
							}
 | 
			
		||||
							else
 | 
			
		||||
								assign_dupligroup_dupli(re, obi, obr);
 | 
			
		||||
						}
 | 
			
		||||
						else
 | 
			
		||||
							init_render_object(re, obd, ob, dob->index, only_verts, !dob->animated);
 | 
			
		||||
 | 
			
		||||
						psysindex= 1;
 | 
			
		||||
						for(psys=obd->particlesystem.first; psys; psys=psys->next) {
 | 
			
		||||
							RE_addRenderInstance(re, NULL, obd, ob, dob->index, psysindex++, mat);
 | 
			
		||||
							VECCOPY(obi->dupliorco, dob->orco);
 | 
			
		||||
							obi->dupliuv[0]= dob->uv[0];
 | 
			
		||||
							obi->dupliuv[1]= dob->uv[1];
 | 
			
		||||
							if(dob->type != OB_DUPLIGROUP || (obr=find_dupligroup_dupli(re, ob, psysindex))) {
 | 
			
		||||
								obi= RE_addRenderInstance(re, NULL, obd, ob, dob->index, psysindex++, mat);
 | 
			
		||||
								if(dob->type != OB_DUPLIGROUP) {
 | 
			
		||||
									VECCOPY(obi->dupliorco, dob->orco);
 | 
			
		||||
									obi->dupliuv[0]= dob->uv[0];
 | 
			
		||||
									obi->dupliuv[1]= dob->uv[1];
 | 
			
		||||
									obi->flag |= R_DUPLI_ELEM;
 | 
			
		||||
								}
 | 
			
		||||
								else
 | 
			
		||||
									assign_dupligroup_dupli(re, obi, obr);
 | 
			
		||||
							}
 | 
			
		||||
							else
 | 
			
		||||
								init_render_object(re, obd, ob, dob->index, only_verts, !dob->animated);
 | 
			
		||||
						}
 | 
			
		||||
						
 | 
			
		||||
						obd->flag |= OB_DONE;
 | 
			
		||||
						obd->transflag |= OB_RENDER_DUPLI;
 | 
			
		||||
						if(dob->type != OB_DUPLIGROUP) {
 | 
			
		||||
							obd->flag |= OB_DONE;
 | 
			
		||||
							obd->transflag |= OB_RENDER_DUPLI;
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
					else
 | 
			
		||||
						init_render_object(re, obd, ob, dob->index, only_verts);
 | 
			
		||||
						init_render_object(re, obd, ob, dob->index, only_verts, !dob->animated);
 | 
			
		||||
					
 | 
			
		||||
					if(re->test_break()) break;
 | 
			
		||||
				}
 | 
			
		||||
				free_object_duplilist(lb);
 | 
			
		||||
 | 
			
		||||
				if(allow_render_object(ob, nolamps, onlyselected, actob))
 | 
			
		||||
					init_render_object(re, ob, NULL, 0, only_verts);
 | 
			
		||||
					init_render_object(re, ob, NULL, 0, only_verts, 0);
 | 
			
		||||
			}
 | 
			
		||||
			else if(allow_render_object(ob, nolamps, onlyselected, actob))
 | 
			
		||||
				init_render_object(re, ob, NULL, 0, only_verts);
 | 
			
		||||
				init_render_object(re, ob, NULL, 0, only_verts, 0);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if(re->test_break()) break;
 | 
			
		||||
 
 | 
			
		||||
@@ -297,6 +297,7 @@ static void occ_face(const OccFace *face, float *co, float *normal, float *area)
 | 
			
		||||
{
 | 
			
		||||
	ObjectInstanceRen *obi;
 | 
			
		||||
	VlakRen *vlr;
 | 
			
		||||
	float v1[3], v2[3], v3[3], v4[3];
 | 
			
		||||
 | 
			
		||||
	obi= &R.objectinstance[face->obi];
 | 
			
		||||
	vlr= RE_findOrAddVlak(obi->obr, face->facenr);
 | 
			
		||||
@@ -330,11 +331,23 @@ static void occ_face(const OccFace *face, float *co, float *normal, float *area)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if(area) {
 | 
			
		||||
		VECCOPY(v1, vlr->v1->co);
 | 
			
		||||
		VECCOPY(v3, vlr->v2->co);
 | 
			
		||||
		VECCOPY(v3, vlr->v3->co);
 | 
			
		||||
		if(vlr->v4) VECCOPY(v4, vlr->v4->co);
 | 
			
		||||
 | 
			
		||||
		if(obi->flag & R_TRANSFORMED) {
 | 
			
		||||
			Mat4MulVecfl(obi->mat, v1);
 | 
			
		||||
			Mat4MulVecfl(obi->mat, v2);
 | 
			
		||||
			Mat4MulVecfl(obi->mat, v3);
 | 
			
		||||
			if(vlr->v4) Mat4MulVecfl(obi->mat, v4);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/* todo: correct area for instances */
 | 
			
		||||
		if(vlr->v4)
 | 
			
		||||
			*area= AreaQ3Dfl(vlr->v1->co, vlr->v2->co, vlr->v3->co, vlr->v4->co);
 | 
			
		||||
			*area= AreaQ3Dfl(v1, v2, v3, v4);
 | 
			
		||||
		else
 | 
			
		||||
			*area= AreaT3Dfl(vlr->v1->co, vlr->v2->co, vlr->v3->co);
 | 
			
		||||
			*area= AreaT3Dfl(v1, v2, v3);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -576,7 +589,7 @@ static OcclusionTree *occ_tree_build(Render *re)
 | 
			
		||||
	/* count */
 | 
			
		||||
	totface= 0;
 | 
			
		||||
	for(obi=re->instancetable.first; obi; obi=obi->next) {
 | 
			
		||||
		if(obi->flag & R_TRANSFORMED)
 | 
			
		||||
		if(obi->flag & R_DUPLI_ELEM)
 | 
			
		||||
			continue;
 | 
			
		||||
 | 
			
		||||
		obr= obi->obr;
 | 
			
		||||
@@ -612,7 +625,7 @@ static OcclusionTree *occ_tree_build(Render *re)
 | 
			
		||||
 | 
			
		||||
	/* make array of face pointers */
 | 
			
		||||
	for(b=0, c=0, obi=re->instancetable.first; obi; obi=obi->next, c++) {
 | 
			
		||||
		if(obi->flag & R_TRANSFORMED)
 | 
			
		||||
		if(obi->flag & R_DUPLI_ELEM)
 | 
			
		||||
			continue; /* temporary to avoid slow renders with loads of duplis */
 | 
			
		||||
 | 
			
		||||
		obr= obi->obr;
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user