Fix T97380 EEVEE: Weird motion-blur on curves

This was caused by the `mb_data->obmat[]` being wrong because they are
now shared between the particle system and the object.
But Hair need the dupli parent matrix instead of the object matrix.
Disabling `Show Emitter` option fixes the bug.

To avoid this problem, request a different `EEVEE_ObjectMotionData`
for particle systems using a different key pointer in the hash.
This is a bit dirty but there is less code polution using this workaround.

Differential Revision: https://developer.blender.org/D14911
This commit is contained in:
Clément Foucault
2022-05-11 01:22:28 +02:00
parent 6f5d172d6c
commit f5077e057b
3 changed files with 20 additions and 9 deletions

View File

@@ -114,7 +114,9 @@ void EEVEE_motion_blur_data_free(EEVEE_MotionBlurData *mb)
}
}
EEVEE_ObjectMotionData *EEVEE_motion_blur_object_data_get(EEVEE_MotionBlurData *mb, Object *ob)
EEVEE_ObjectMotionData *EEVEE_motion_blur_object_data_get(EEVEE_MotionBlurData *mb,
Object *ob,
bool is_psys)
{
if (mb->object == NULL) {
return NULL;
@@ -123,14 +125,16 @@ EEVEE_ObjectMotionData *EEVEE_motion_blur_object_data_get(EEVEE_MotionBlurData *
EEVEE_ObjectKey key, *key_p;
/* Assumes that all instances have the same object pointer. This is currently the case because
* instance objects are temporary objects on the stack. */
key.ob = ob;
/* WORKAROUND: Duplicate object key for particle system (hairs) to be able to store dupli offset
* matrix along with the emitter obmat. (see T97380) */
key.ob = (void *)((char *)ob + is_psys);
DupliObject *dup = DRW_object_get_dupli(ob);
if (dup) {
key.parent = DRW_object_get_dupli_parent(ob);
memcpy(key.id, dup->persistent_id, sizeof(key.id));
}
else {
key.parent = key.ob;
key.parent = ob;
memset(key.id, 0, sizeof(key.id));
}

View File

@@ -226,7 +226,8 @@ void EEVEE_motion_blur_hair_cache_populate(EEVEE_ViewLayerData *UNUSED(sldata),
}
/* For now we assume hair objects are always moving. */
EEVEE_ObjectMotionData *mb_data = EEVEE_motion_blur_object_data_get(&effects->motion_blur, ob);
EEVEE_ObjectMotionData *mb_data = EEVEE_motion_blur_object_data_get(
&effects->motion_blur, ob, true);
if (mb_data) {
int mb_step = effects->motion_blur_step;
@@ -283,7 +284,8 @@ void EEVEE_motion_blur_curves_cache_populate(EEVEE_ViewLayerData *UNUSED(sldata)
}
/* For now we assume curves objects are always moving. */
EEVEE_ObjectMotionData *mb_data = EEVEE_motion_blur_object_data_get(&effects->motion_blur, ob);
EEVEE_ObjectMotionData *mb_data = EEVEE_motion_blur_object_data_get(
&effects->motion_blur, ob, false);
if (mb_data == NULL) {
return;
}
@@ -354,7 +356,8 @@ void EEVEE_motion_blur_cache_populate(EEVEE_ViewLayerData *UNUSED(sldata),
return;
}
EEVEE_ObjectMotionData *mb_data = EEVEE_motion_blur_object_data_get(&effects->motion_blur, ob);
EEVEE_ObjectMotionData *mb_data = EEVEE_motion_blur_object_data_get(
&effects->motion_blur, ob, false);
if (mb_data) {
int mb_step = effects->motion_blur_step;

View File

@@ -644,8 +644,10 @@ typedef struct EEVEE_MotionBlurData {
} EEVEE_MotionBlurData;
typedef struct EEVEE_ObjectKey {
/** Object or source object for duplis */
struct Object *ob;
/** Object or source object for duplis. */
/** WORKAROUND: The pointer is different for particle systems and do not point to the real
* object. (See T97380) */
void *ob;
/** Parent object for duplis */
struct Object *parent;
/** Dupli objects recursive unique identifier */
@@ -1093,7 +1095,9 @@ EEVEE_ViewLayerData *EEVEE_view_layer_data_ensure_ex(struct ViewLayer *view_laye
EEVEE_ViewLayerData *EEVEE_view_layer_data_ensure(void);
EEVEE_ObjectEngineData *EEVEE_object_data_get(Object *ob);
EEVEE_ObjectEngineData *EEVEE_object_data_ensure(Object *ob);
EEVEE_ObjectMotionData *EEVEE_motion_blur_object_data_get(EEVEE_MotionBlurData *mb, Object *ob);
EEVEE_ObjectMotionData *EEVEE_motion_blur_object_data_get(EEVEE_MotionBlurData *mb,
Object *ob,
bool is_psys);
EEVEE_GeometryMotionData *EEVEE_motion_blur_geometry_data_get(EEVEE_ObjectMotionData *mb_data);
EEVEE_HairMotionData *EEVEE_motion_blur_hair_data_get(EEVEE_ObjectMotionData *mb_data, Object *ob);
EEVEE_HairMotionData *EEVEE_motion_blur_curves_data_get(EEVEE_ObjectMotionData *mb_data);