[Bf-committers] Alpha faces: Kester?

Kester Maddock bf-committers@blender.org
Sat, 24 Jul 2004 21:34:53 +1200


--Boundary-00=_90iABueY4EfYdFE
Content-Type: text/plain;
  charset="utf-8"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

OK, here's a quick patch that should do the job. (patch -p0 in the root of 
blender source.)

It uses the object centre as the sort key, and ZTransp in Material buttons to 
identify transparent objects.

Also, Blender currently draws selected objects after (in front of) non 
selected objects.  Is this intentional?  Desirable?  This patch draws solid, 
selected solid, transparent, then transparent selected, since it looks much 
better when you draw transparent after solid.  Dupliverts aren't sorted.

I haven't really tested enough for commit yet, but it should provide a good 
starting point.

Kester

On Friday 23 July 2004 08:19, Jakub Steiner wrote:
> On Thu, 2004-07-22 at 21:58 +0200, Alexander Ewering wrote:
> > If the code for the 3d views is too different from the game engine, don't
> > bother, of course.
>
> I have to second that. I love using blender as a 3d compositor and
> having more precise realitime preview would be greatly appreciated.
>
> cheers

--Boundary-00=_90iABueY4EfYdFE
Content-Type: text/x-diff;
  charset="utf-8";
  name="zsort.patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
	filename="zsort.patch"

Index: source/blender/src/drawview.c
===================================================================
RCS file: /cvsroot/bf-blender/blender/source/blender/src/drawview.c,v
retrieving revision 1.78
diff -u -r1.78 drawview.c
--- source/blender/src/drawview.c	21 Jul 2004 17:44:44 -0000	1.78
+++ source/blender/src/drawview.c	24 Jul 2004 09:32:44 -0000
@@ -34,6 +34,7 @@
 
 #include <math.h>
 #include <string.h>
+#include <stdlib.h>
 
 #ifdef HAVE_CONFIG_H
 #include <config.h>
@@ -62,6 +63,7 @@
 #include "DNA_group_types.h"
 #include "DNA_image_types.h"
 #include "DNA_lattice_types.h"
+#include "DNA_material_types.h"
 #include "DNA_mesh_types.h"
 #include "DNA_meta_types.h"
 #include "DNA_object_types.h"
@@ -1676,11 +1678,44 @@
 
 }
 
+/**
+ *  Sort function. (see qsort)
+ *
+ *  Return: < 0:  a is more distant than b
+ *          > 0:  a is closer than b
+ */
+static int backtofront(const void *a, const void *b)
+{
+	const Base *obj1 = *((const Base **)a);
+	const Base *obj2 = *((const Base **)b);
+	float za = G.vd->viewmat[0][2]*obj1->object->loc[0] + G.vd->viewmat[1][2]*obj1->object->loc[1] + G.vd->viewmat[2][2]*obj1->object->loc[2] + G.vd->viewmat[3][2];
+	float zb = G.vd->viewmat[0][2]*obj2->object->loc[0] + G.vd->viewmat[1][2]*obj2->object->loc[1] + G.vd->viewmat[2][2]*obj2->object->loc[2] + G.vd->viewmat[3][2];
+	/* View is along -z axis: */
+	return za < zb ? -1 : 1;
+}
+
+/**
+ *  Test an object for transparency.
+ *
+ *  Returns zero if the object is solid, nonzero if it is transparent, or has
+ *  no material.
+ */
+static int isTransparent(Base *base)
+{
+	Material *mat = give_current_material(base->object, 1);
+	if (mat)
+		return (mat->mode & MA_ZTRA) != 0;
+	return 0;
+}
+
 void drawview3dspace(ScrArea *sa, void *spacedata)
 {
-	extern void constline_callback(void);	// editobject.c helpline
+	extern void constline_callback(void);	/* editobject.c helpline */
 	Base *base;
 	Object *ob;
+	Base **objlist;
+	int numobj = 0;
+	int i;
 	
 	setwinmatrixview3d(0);	/* 0= no pick rect */
 	setviewmatrixview3d();
@@ -1784,15 +1819,20 @@
 	*/
 	base= G.scene->base.first;
 	while(base) {
-		if(G.vd->lay & base->lay) where_is_object(base->object);
+		if(G.vd->lay & base->lay) 
+		{
+			where_is_object(base->object);
+			if (isTransparent(base))
+				numobj ++;
+		}
 		base= base->next;
 	}
 	
-	/* then draw not selected and the duplis */
+	/* then draw not selected and the duplis / solid */
 	base= G.scene->base.first;
 	while(base) {
 		
-		if(G.vd->lay & base->lay) {
+		if((G.vd->lay & base->lay) && !isTransparent(base)) {
 			
 			/* dupli drawing temporal off here */
 			if(FALSE && base->object->transflag & OB_DUPLI) {
@@ -1827,24 +1867,25 @@
 		
 		base= base->next;
 	}
-	/* draw selected */
+	
+	/* draw selected / solid */
 	base= G.scene->base.first;
 	while(base) {
 		
-		if ( ((base)->flag & SELECT) && ((base)->lay & G.vd->lay) ) {
+		if ( ((base)->flag & SELECT) && ((base)->lay & G.vd->lay) && !isTransparent(base)) {
 			draw_object(base);
 		}
 		
 		base= base->next;
 	}
-
+	
 	if(G.moving) constline_callback();
 
-	/* duplis, draw as last to make sure the displists are ok */
+	/* duplis, draw as last to make sure the displists are ok / solid */
 	base= G.scene->base.first;
 	while(base) {
 		
-		if(G.vd->lay & base->lay) {
+		if((G.vd->lay & base->lay) && isTransparent(base)) {
 			if(base->object->transflag & OB_DUPLI) {
 				extern ListBase duplilist;
 				Base tbase;
@@ -1869,7 +1910,86 @@
 		}
 		base= base->next;
 	}
+	
+	/* ZSorted Transparent objects */
+	
+	objlist = MEM_callocN(sizeof(Base*)*numobj, "ZSort");
+	/* Copy the object list into an array */
+	i = 0;
+	base= G.scene->base.first;
+	while(base) {
+		if ((G.vd->lay & base->lay) && isTransparent(base))
+		{
+			objlist[i] = base;
+			i++;
+		}
+			
+		base = base->next;
+	}
+	
+	/* Sort by depth */
+	qsort(objlist, numobj, sizeof(Base*), backtofront);
+	
+	/* then draw not selected and the duplis / transparent*/
+	for (i = 0 ; i < numobj; i++) {
+		base = objlist[i];
+		/* dupli drawing temporal off here */
+		if(FALSE && base->object->transflag & OB_DUPLI) {
+			extern ListBase duplilist;
+			Base tbase;
+
+			/* draw original always first because of make_displist */
+			draw_object(base);
+
+			/* patch: color remains constant */ 
+			G.f |= G_PICKSEL;
+			cpack(0x404040);
+			
+			tbase.flag= OB_FROMDUPLI;
+			make_duplilist(G.scene, base->object);
+
+			ob= duplilist.first;
+			while(ob) {
+				tbase.object= ob;
+				draw_object(&tbase);
+				ob= ob->id.next;
+			}
+			free_duplilist();
+			
+			G.f &= ~G_PICKSEL;				
+		}
+		else {
+			draw_object(base);
+		}
+	}
+
+	/* duplis, draw as last to make sure the displists are ok */
+	for (i = 0 ; i < numobj; i++) {
+		base = objlist[i];
+		if(base->object->transflag & OB_DUPLI) {
+			extern ListBase duplilist;
+			Base tbase;
+
+			/* patch: color remains constant */ 
+			G.f |= G_PICKSEL;
+			cpack(0x404040);
+			
+			tbase.flag= OB_FROMDUPLI;
+			make_duplilist(G.scene, base->object);
+
+			ob= duplilist.first;
+			while(ob) {
+				tbase.object= ob;
+				draw_object(&tbase);
+				ob= ob->id.next;
+			}
+			free_duplilist();
+			
+			G.f &= ~G_PICKSEL;				
+		}
+	}
 
+	MEM_freeN(objlist);
 
 	if(G.scene->radio) RAD_drawall(G.vd->drawtype>=OB_SOLID);
 	

--Boundary-00=_90iABueY4EfYdFE--