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.
This commit is contained in:
parent
682c4dcd1e
commit
ccd8353d58
|
@ -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;
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Reference in New Issue