[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [21835] branches/soc-2009-yukishiro/source /blender: ray intersection doesn't work right.

Jingyuan Huang jingyuan.huang at gmail.com
Fri Jul 24 03:56:00 CEST 2009


Revision: 21835
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=21835
Author:   yukishiro
Date:     2009-07-24 03:55:58 +0200 (Fri, 24 Jul 2009)

Log Message:
-----------
ray intersection doesn't work right. I tried to find out the problem for a long time and there is no success.

Modified Paths:
--------------
    branches/soc-2009-yukishiro/source/blender/editors/sculpt_paint/paint_light.c
    branches/soc-2009-yukishiro/source/blender/sh/intern/compute.c

Modified: branches/soc-2009-yukishiro/source/blender/editors/sculpt_paint/paint_light.c
===================================================================
--- branches/soc-2009-yukishiro/source/blender/editors/sculpt_paint/paint_light.c	2009-07-24 00:04:23 UTC (rev 21834)
+++ branches/soc-2009-yukishiro/source/blender/editors/sculpt_paint/paint_light.c	2009-07-24 01:55:58 UTC (rev 21835)
@@ -110,6 +110,7 @@
 	if (sj->scene->lightenv == NULL) 
 		sj->scene->lightenv = add_lightenv("LightEnv");
 
+	//SH_computeSceneCoefficients(sj->scene, sj->mask, 1, sj->recompute);
 	SH_computeSceneCoefficients(sj->scene, sj->mask, 0, sj->recompute);
 }
 
@@ -268,12 +269,7 @@
 		toggle_paint_cursor(C);
 		brush_check_exists(&scene->toolsettings->lpaint->brush);
 
-		//light_paint_compute(C, 0);
-		if (scene->lightenv == NULL) 
-			scene->lightenv = add_lightenv("LightEnv");
-		SH_computeSceneCoefficients(scene, 
-			get_viewedit_datamask(CTX_wm_screen(C)), 0, 0);
-		WM_event_add_notifier(C, NC_LIGHTENV|ND_SH_RESULT, NULL);
+		light_paint_compute(C, 0);
 	}
 	
 	ED_area_tag_redraw(CTX_wm_area(C));

Modified: branches/soc-2009-yukishiro/source/blender/sh/intern/compute.c
===================================================================
--- branches/soc-2009-yukishiro/source/blender/sh/intern/compute.c	2009-07-24 00:04:23 UTC (rev 21834)
+++ branches/soc-2009-yukishiro/source/blender/sh/intern/compute.c	2009-07-24 01:55:58 UTC (rev 21835)
@@ -442,68 +442,103 @@
         }
 }
 
+typedef struct ShFace {
+	DerivedMesh *dm;
+	MFace *mface;
+} ShFace;
+
+typedef struct ShRenderInfo {
+	RayTree *tree;
+	ShFace ***shfaces;
+	ShFace ***faces_map;
+} ShRenderInfo;
+
+
 static void ray_coords_func(RayFace *face, float **v1, float **v2, float **v3, float **v4)
 {
-	//MFace *mface= (MFace*)face;
-	//float (*verts)[3]= HeatSys->heat.verts;
+	ShFace *shface = (ShFace*)face;
+	MFace *mface = shface->mface;
+	MVert *verts = shface->dm->getVertArray(shface->dm);
 
-	//*v1= verts[mface->v1];
-	//*v2= verts[mface->v2];
-	//*v3= verts[mface->v3];
-	//*v4= (mface->v4)? verts[mface->v4]: NULL;
+	*v1= verts[mface->v1].co;
+	*v2= verts[mface->v2].co;
+	*v3= verts[mface->v3].co;
+	*v4= (mface->v4) ? verts[mface->v4].co : NULL;
 }
 
 static int ray_check_func(Isect *is, int ob, RayFace *face)
 {
-	//float *v1, *v2, *v3, *v4, nor[3];
-
-	///* don't intersect if the ray faces along the face normal */
-	//heat_ray_coords_func(face, &v1, &v2, &v3, &v4);
-
-	//if(v4) CalcNormFloat4(v1, v2, v3, v4, nor);
-	//else CalcNormFloat(v1, v2, v3, nor);
-
-	//return (INPR(nor, is->vec) < 0);
-	return 0;
+	return 1;
 }
 
 static float *ray_get_transform(void *userdata, int i)
 {
-	//ObjectInstanceRen *obi= RAY_OBJECT_GET((Render*)userdata, i);
+	Scene *scene = (Scene*)userdata;
+	Base *base = NULL;
+	Object *ob = NULL;
+	int offset = 0;
 
-	//return (obi->flag & R_TRANSFORMED)? (float*)obi->mat: NULL;
+	i -= RE_RAY_TRANSFORM_OFFS;
+
+	for (base = scene->base.first; base; base = base->next, offset++) {
+		ob = base->object;
+		if (get_mesh(ob) == NULL) continue;
+
+		if (offset == i) return ob->obmat;
+	}
+
 	return NULL;
 }
 
-static void create_ray_tree(Scene *scene, unsigned int customdata_mask, RayTree *tree)
+static ShRenderInfo * create_render_info(Scene *scene, unsigned int customdata_mask)
 {
+	ShRenderInfo *ri;
         Base *base= NULL;
         Object *ob= NULL;
         Mesh *me= NULL;
         DerivedMesh *dm= NULL;
+	ShFace *shface= NULL;
 	MFace *faces= NULL;
+        int i, j;
+	int totobj = 0, num_faces= 0, totface= 0, obj_offset = 0;
+	float min[3], max[3];
 
-        int i, num_faces= 0, totface= 0;
-	float min[3], max[3];
 	INIT_MINMAX(min, max);
+	ri = MEM_mallocN(sizeof(ShRenderInfo), "ShRenderInfo");
 
+	// count number of mesh objects
         for (base = scene->base.first; base; base = base->next) {
                 ob = base->object;
                 me = get_mesh(ob);
                 if (me == NULL) continue;
 
+		totobj++;
+	}
+	ri->shfaces = MEM_mallocN(sizeof(ShFace**) * totobj, "ShFace obj array");
+	ri->faces_map = MEM_mallocN(sizeof(ShFace**) * totobj, "ShFace obj array");
+
+	// count total number of faces
+        for (base = scene->base.first, i = 0; base; base = base->next) {
+                ob = base->object;
+                me = get_mesh(ob);
+                if (me == NULL) continue;
+
                 dm = mesh_get_derived_final(scene, ob, customdata_mask);
 		dm->getMinMax(dm, min, max);
 
-		totface += dm->getNumFaces(dm);
+		num_faces = dm->getNumFaces(dm);
+		totface += num_faces;
+		
+		ri->shfaces[i] = MEM_mallocN(sizeof(ShFace*) * num_faces, "ShFace face array");
+		ri->faces_map[i++] = MEM_mallocN(sizeof(ShFace*) * dm->getNumVerts(dm), "ShFace vert array");
 	}
 
 	//XXX: 64 is constant... and cb functions...
-	tree= RE_ray_tree_create(64, totface, min, max,
-		ray_coords_func, ray_check_func, ray_get_transform, NULL);
+	ri->tree= RE_ray_tree_create(64, totface, min, max,
+			ray_coords_func, ray_check_func, ray_get_transform, scene);
 
 	// add faces
-	for (base = scene->base.first; base; base = base->next) {
+	for (base = scene->base.first, i = 0; base; base = base->next, obj_offset++) {
                 ob = base->object;
                 me = get_mesh(ob);
                 if (me == NULL) continue;
@@ -512,15 +547,58 @@
 		num_faces = dm->getNumFaces(dm);
 		faces = dm->getFaceArray(dm);
 
-		for (i = 0; i < num_faces; i++) {
-			RE_ray_tree_add_face(tree, 0, faces+i);
+		for (j = 0; j < num_faces; j++) {
+			shface = MEM_mallocN(sizeof(ShFace), "ShFace"); //TODO: free
+			shface->mface = faces+j;
+			shface->dm = dm;
+
+			RE_ray_tree_add_face(ri->tree, obj_offset + RE_RAY_TRANSFORM_OFFS, shface);
+
+			ri->shfaces[i][j] = shface;
+			ri->faces_map[i][shface->mface->v1] = shface;
+			ri->faces_map[i][shface->mface->v2] = shface;
+			ri->faces_map[i][shface->mface->v3] = shface;
+			if (shface->mface->v4) ri->faces_map[i][shface->mface->v4] = shface;
 		}
+		i++;
 	}
 
-	RE_ray_tree_done(tree);
+	RE_ray_tree_done(ri->tree);
+
+	return ri;
 }
 
+static void free_render_info(ShRenderInfo *ri, Scene *scene, unsigned int customdata_mask)
+{
+        Base *base= NULL;
+        Object *ob= NULL;
+        Mesh *me= NULL;
+        DerivedMesh *dm= NULL;
+	int num_faces, i, j;
 
+	RE_ray_tree_free(ri->tree);
+	
+	for (base = scene->base.first, i=0; base; base = base->next) {
+		ob = base->object;
+                me = get_mesh(ob);
+                if (me == NULL) continue;
+
+                dm = mesh_get_derived_final(scene, ob, customdata_mask);
+		num_faces = dm->getNumFaces(dm);
+
+		for (j = 0; j < num_faces; j++) {
+			MEM_freeN(ri->shfaces[i][j]);
+		}
+		MEM_freeN(ri->faces_map[i]);
+		MEM_freeN(ri->shfaces[i++]);
+	}
+	MEM_freeN(ri->faces_map);
+	MEM_freeN(ri->shfaces);
+
+	MEM_freeN(ri);
+}
+
+
 /* called on startup, in WM_init() */
 void SH_init()
 {
@@ -561,21 +639,21 @@
         DerivedMesh *dm= NULL;
         MShCoeffs *coeffs= NULL;
         MVert* verts= NULL;
-	RayTree *tree = NULL;
+	ShRenderInfo *ri = NULL;
 	LightEnv* env=scene->lightenv;
 
 	Isect isec;
-        int i, k, m, num_verts;
+        int i, j, k, m, num_verts;
         float no[3], N, *y_val;
 	int num_sh= (env->degree + 1) * (env->degree + 1);
         float weight= 4.0f/(float)NUM_SAMPLES;
-	int visible;
+	int offset = 0, visible;
 
 	if (compute_shadow) 
-		create_ray_tree(scene, customdata_mask, tree);
+		ri = create_render_info(scene, customdata_mask);
 
         // use derived mesh...
-        for (base = scene->base.first; base; base = base->next) {
+        for (base = scene->base.first, i=0; base; base = base->next, offset++) {
                 ob = base->object;
                 me = get_mesh(ob);
                 if (me == NULL) continue;
@@ -597,44 +675,51 @@
 			coeffs = CustomData_add_layer(&me->ddata, CD_MSHCOEFFS, CD_CALLOC, NULL, me->totderived);
 		}
 
-                for (i = 0; i < num_verts; i++) {
+                for (j = 0; j < num_verts; j++) {
                         for (k = 0; k < NUM_SAMPLES; k++) {
-				no[0] = verts[i].no[0] / 32767.0;
-				no[1] = verts[i].no[1] / 32767.0;
-				no[2] = verts[i].no[2] / 32767.0;
+				no[0] = verts[j].no[0] / 32767.0;
+				no[1] = verts[j].no[1] / 32767.0;
+				no[2] = verts[j].no[2] / 32767.0;
 				Mat4MulVecfl(ob->obmat, no); // XXX
 
                                 N = samples[k][0] * no[0] + samples[k][1] * no[1] + samples[k][2] * no[2];
 
                                 if (N > 0) {
 					if (compute_shadow) {
-						memset(&isec, 0, sizeof(isec));
 						isec.mode= RE_RAY_SHADOW;
 						isec.lay= -1;
 						isec.face_last= NULL;
-						//isec.faceorig= mface;
-						VECCOPY(isec.start, verts[i].co);
-						VECCOPY(isec.end, samples[k]);
+						isec.faceorig = ri->faces_map[i][j];
+						isec.oborig = offset + RE_RAY_TRANSFORM_OFFS;
 
-						visible= !RE_ray_tree_intersect(tree, &isec);
+						VECCOPY(isec.start, verts[j].co);
+						VECCOPY(isec.vec, samples[k]);
+						VECADD(isec.end, isec.start, samples[k]);
+
+						visible = !RE_ray_tree_intersect(ri->tree, &isec);
 					} 
 					else {
 						visible = 1;
 					}
+					//printf("visible: %d\n", visible);
 
 					if (visible) {
                                         	y_val = *(samples_Y[k]);
                                         	for (m = 0; m < num_sh; m++) {
-                                        	        coeffs[i].val[m] += N * y_val[m];
+                                        	        coeffs[j].val[m] += N * y_val[m];
                                         	}
 					}
                                 }
                         }
                         for (m = 0; m < num_sh; m++) {
-                                coeffs[i].val[m] *= weight;
+                                coeffs[j].val[m] *= weight;
                         }
                 }
+		i++;
         }
+
+	if (compute_shadow) 
+		free_render_info(ri, scene, customdata_mask);
 }
 
 void SH_computeMeshCoefficients(Scene *scene, Object *ob, unsigned int customdata_mask)





More information about the Bf-blender-cvs mailing list