[Bf-blender-cvs] [ccd8353d58d] blender2.8: Object Engine: Fix multi user lamp data display bug.

Clément Foucault noreply at git.blender.org
Mon Apr 3 22:31:13 CEST 2017


Commit: ccd8353d58d769d435822e7dac25d8fdf317d6df
Author: Clément Foucault
Date:   Mon Apr 3 19:01:10 2017 +0200
Branches: blender2.8
https://developer.blender.org/rBccd8353d58d769d435822e7dac25d8fdf317d6df

Object Engine: Fix multi user lamp data display bug.

Objects that were using the same lamp data were having the same display matrices.
This is fixed by allowing engine to store a memory block inside the object itself.

===================================================================

M	source/blender/blenkernel/intern/object.c
M	source/blender/blenloader/intern/readfile.c
M	source/blender/draw/DRW_engine.h
M	source/blender/draw/intern/DRW_render.h
M	source/blender/draw/intern/draw_manager.c
M	source/blender/draw/modes/object_mode.c
M	source/blender/makesdna/DNA_lamp_types.h
M	source/blender/makesdna/DNA_object_types.h

===================================================================

diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index 7250fd279c7..5f1e47e0f5a 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -119,6 +119,8 @@
 #include "BKE_camera.h"
 #include "BKE_image.h"
 
+#include "DRW_engine.h"
+
 #ifdef WITH_MOD_FLUID
 #include "LBM_fluidsim.h"
 #endif
@@ -443,6 +445,8 @@ void BKE_object_free(Object *ob)
 	}
 	GPU_lamp_free(ob);
 
+	DRW_object_engine_data_free(ob);
+
 	BKE_sculptsession_free(ob);
 
 	BLI_freelistN(&ob->pc_ids);
@@ -1177,6 +1181,7 @@ Object *BKE_object_copy_ex(Main *bmain, Object *ob, bool copy_caches)
 
 	BLI_listbase_clear(&obn->gpulamp);
 	BLI_listbase_clear(&obn->pc_ids);
+	BLI_listbase_clear(&obn->drawdata);
 
 	obn->mpath = NULL;
 
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 2c9d1a47320..5f6663f4cc7 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -5587,6 +5587,7 @@ static void direct_link_object(FileData *fd, Object *ob)
 	ob->derivedDeform = NULL;
 	ob->derivedFinal = NULL;
 	BLI_listbase_clear(&ob->gpulamp);
+	BLI_listbase_clear(&ob->drawdata);
 	link_list(fd, &ob->pc_ids);
 
 	/* Runtime curve data  */
diff --git a/source/blender/draw/DRW_engine.h b/source/blender/draw/DRW_engine.h
index 669f7a24908..87cfa8e8e3b 100644
--- a/source/blender/draw/DRW_engine.h
+++ b/source/blender/draw/DRW_engine.h
@@ -52,6 +52,8 @@ void DRW_engine_register(struct DrawEngineType *draw_engine_type);
 
 void DRW_draw_view(const struct bContext *C);
 
+void DRW_object_engine_data_free(struct Object *ob);
+
 /* This is here because GPUViewport needs it */
 void DRW_pass_free(struct DRWPass *pass);
 
diff --git a/source/blender/draw/intern/DRW_render.h b/source/blender/draw/intern/DRW_render.h
index 13b10011dec..dcef328e4ce 100644
--- a/source/blender/draw/intern/DRW_render.h
+++ b/source/blender/draw/intern/DRW_render.h
@@ -247,6 +247,9 @@ bool DRW_viewport_cache_is_dirty(void);
 struct DefaultFramebufferList *DRW_viewport_framebuffer_list_get(void);
 struct DefaultTextureList     *DRW_viewport_texture_list_get(void);
 
+/* Objects */
+void **DRW_object_engine_data_get(Object *ob, DrawEngineType *det);
+
 /* Settings */
 bool DRW_is_object_renderable(struct Object *ob);
 
diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c
index a338c1f9f5f..a674c532310 100644
--- a/source/blender/draw/intern/draw_manager.c
+++ b/source/blender/draw/intern/draw_manager.c
@@ -1377,6 +1377,42 @@ DefaultTextureList *DRW_viewport_texture_list_get(void)
 	return GPU_viewport_texture_list_get(DST.viewport);
 }
 
+/* **************************************** OBJECTS *************************************** */
+
+typedef struct ObjectEngineData {
+	struct ObjectEngineData *next, *prev;
+	DrawEngineType *engine_type;
+	void *storage;
+} ObjectEngineData;
+
+void **DRW_object_engine_data_get(Object *ob, DrawEngineType *engine_type)
+{
+	ObjectEngineData *oed;
+
+	for (oed = ob->drawdata.first; oed; oed = oed->next) {
+		if (oed->engine_type == engine_type) {
+			return &oed->storage;
+		}
+	}
+
+	oed = MEM_callocN(sizeof(ObjectEngineData), "ObjectEngineData");
+
+	BLI_addtail(&ob->drawdata, oed);
+
+	return &oed->storage;
+}
+
+void DRW_object_engine_data_free(Object *ob)
+{
+	for (ObjectEngineData *oed = ob->drawdata.first; oed; oed = oed->next) {
+		if (oed->storage) {
+			MEM_freeN(oed->storage);
+		}
+	}
+
+	BLI_freelistN(&ob->drawdata);
+}
+
 /* **************************************** RENDERING ************************************** */
 
 #define TIMER_FALLOFF 0.1f
diff --git a/source/blender/draw/modes/object_mode.c b/source/blender/draw/modes/object_mode.c
index e301c3e4e8a..5920889a453 100644
--- a/source/blender/draw/modes/object_mode.c
+++ b/source/blender/draw/modes/object_mode.c
@@ -683,6 +683,16 @@ static void DRW_shgroup_lamp(OBJECT_StorageList *stl, Object *ob, SceneLayer *sl
 	int theme_id = DRW_object_wire_theme_get(ob, sl, &color);
 	static float zero = 0.0f;
 
+	float **la_mats = (float **)DRW_object_engine_data_get(ob, &draw_engine_object_type);
+	if (*la_mats == NULL) {
+		/* we need 2 matrices */
+		*la_mats = MEM_mallocN(sizeof(float) * 16 * 2, "Lamp Object Mode Matrices");
+	}
+
+	float (*shapemat)[4], (*spotblendmat)[4];
+	shapemat = (float (*)[4])*la_mats;
+	spotblendmat = (float (*)[4])*la_mats + 16;
+
 	/* Don't draw the center if it's selected or active */
 	if (theme_id == TH_GROUP)
 		DRW_shgroup_dynamic_call_add(stl->g_data->lamp_center_group, ob->obmat[3]);
@@ -704,7 +714,7 @@ static void DRW_shgroup_lamp(OBJECT_StorageList *stl, Object *ob, SceneLayer *sl
 		DRW_shgroup_dynamic_call_add(stl->g_data->lamp_distance, color, &zero, &la->dist, ob->obmat);
 	}
 
-	copy_m4_m4(la->shapemat, ob->obmat);
+	copy_m4_m4(shapemat, ob->obmat);
 
 	if (la->type == LA_SUN) {
 		DRW_shgroup_dynamic_call_add(stl->g_data->lamp_sunrays, ob->obmat[3], color);
@@ -718,42 +728,41 @@ static void DRW_shgroup_lamp(OBJECT_StorageList *stl, Object *ob, SceneLayer *sl
 		size[2] = cosf(la->spotsize * 0.5f) * la->dist;
 
 		size_to_mat4(sizemat, size);
-		mul_m4_m4m4(la->spotconemat, ob->obmat, sizemat);
+		mul_m4_m4m4(shapemat, ob->obmat, sizemat);
 
 		size[0] = size[1] = blend; size[2] = 1.0f;
 		size_to_mat4(sizemat, size);
 		translate_m4(sizemat, 0.0f, 0.0f, -1.0f);
 		rotate_m4(sizemat, 'X', M_PI / 2.0f);
-		mul_m4_m4m4(la->spotblendmat, la->spotconemat, sizemat);
+		mul_m4_m4m4(spotblendmat, shapemat, sizemat);
 
 		if (la->mode & LA_SQUARE) {
-			DRW_shgroup_dynamic_call_add(stl->g_data->lamp_spot_pyramid,    color, &one, la->spotconemat);
+			DRW_shgroup_dynamic_call_add(stl->g_data->lamp_spot_pyramid,    color, &one, shapemat);
 
 			/* hide line if it is zero size or overlaps with outer border,
 			 * previously it adjusted to always to show it but that seems
 			 * confusing because it doesn't show the actual blend size */
 			if (blend != 0.0f && blend != 1.0f) {
-				DRW_shgroup_dynamic_call_add(stl->g_data->lamp_spot_blend_rect, color, &one, la->spotblendmat);
+				DRW_shgroup_dynamic_call_add(stl->g_data->lamp_spot_blend_rect, color, &one, spotblendmat);
 			}
 		}
 		else {
-			DRW_shgroup_dynamic_call_add(stl->g_data->lamp_spot_cone,  color, la->spotconemat);
+			DRW_shgroup_dynamic_call_add(stl->g_data->lamp_spot_cone,  color, shapemat);
 
 			/* hide line if it is zero size or overlaps with outer border,
 			 * previously it adjusted to always to show it but that seems
 			 * confusing because it doesn't show the actual blend size */
 			if (blend != 0.0f && blend != 1.0f) {
-				DRW_shgroup_dynamic_call_add(stl->g_data->lamp_spot_blend, color, &one, la->spotblendmat);
+				DRW_shgroup_dynamic_call_add(stl->g_data->lamp_spot_blend, color, &one, spotblendmat);
 			}
 		}
 
-		normalize_m4(la->shapemat);
 		DRW_shgroup_dynamic_call_add(stl->g_data->lamp_buflimit,        color, &la->clipsta, &la->clipend, ob->obmat);
 		DRW_shgroup_dynamic_call_add(stl->g_data->lamp_buflimit_points, color, &la->clipsta, &la->clipend, ob->obmat);
 	}
 	else if (la->type == LA_HEMI) {
 		static float hemisize = 2.0f;
-		DRW_shgroup_dynamic_call_add(stl->g_data->lamp_hemi, color, &hemisize, la->shapemat);
+		DRW_shgroup_dynamic_call_add(stl->g_data->lamp_hemi, color, &hemisize, shapemat);
 	}
 	else if (la->type == LA_AREA) {
 		float size[3] = {1.0f, 1.0f, 1.0f}, sizemat[4][4];
@@ -761,10 +770,10 @@ static void DRW_shgroup_lamp(OBJECT_StorageList *stl, Object *ob, SceneLayer *sl
 		if (la->area_shape == LA_AREA_RECT) {
 			size[1] = la->area_sizey / la->area_size;
 			size_to_mat4(sizemat, size);
-			mul_m4_m4m4(la->shapemat, la->shapemat, sizemat);
+			mul_m4_m4m4(shapemat, shapemat, sizemat);
 		}
 
-		DRW_shgroup_dynamic_call_add(stl->g_data->lamp_area, color, &la->area_size, la->shapemat);
+		DRW_shgroup_dynamic_call_add(stl->g_data->lamp_area, color, &la->area_size, shapemat);
 	}
 
 	/* Line and point going to the ground */
diff --git a/source/blender/makesdna/DNA_lamp_types.h b/source/blender/makesdna/DNA_lamp_types.h
index 2393cbbf10d..a2e39f93875 100644
--- a/source/blender/makesdna/DNA_lamp_types.h
+++ b/source/blender/makesdna/DNA_lamp_types.h
@@ -106,10 +106,6 @@ typedef struct Lamp {
 	short pr_texture, use_nodes;
 	char pad6[4];
 
-	float shapemat[4][4]; /* runtime, for display only */
-	float spotconemat[4][4]; /* runtime, for display only */
-	float spotblendmat[4][4]; /* runtime, for display only */
-
 	/* preview */
 	struct PreviewImage *preview;
 
diff --git a/source/blender/makesdna/DNA_object_types.h b/source/blender/makesdna/DNA_object_types.h
index a0ed163a4cb..71d05e41c43 100644
--- a/source/blender/makesdna/DNA_object_types.h
+++ b/source/blender/makesdna/DNA_object_types.h
@@ -304,6 +304,8 @@ typedef struct Object {
 	struct PreviewImage *preview;
 
 	struct IDProperty *base_collection_properties; /* used by depsgraph, flushed from base */
+
+	ListBase drawdata;		/* runtime, for draw engine datas */
 } Object;
 
 /* Warning, this is not used anymore because hooks are now modifiers */




More information about the Bf-blender-cvs mailing list