Fix #33113: cycles not rendering motion blur correct with dying particles.
There were a bunch of other issues with dupli motion blur and syncing, the problem being that there was no proper way to detect corresponding duplis between frames or updates. As a solution, a persistent_id was added to the DupliObject. It's an extension of the previous index value, with one index for each dupli level. This can be used to reliably find matching dupli objects between frames. Works with nested duplis, multiple particle systems, etc.
This commit is contained in:
@@ -284,6 +284,12 @@ public:
|
||||
return recalc;
|
||||
}
|
||||
|
||||
bool is_used(const K& key)
|
||||
{
|
||||
T *data = find(key);
|
||||
return (data)? used_set.find(data) != used_set.end(): NULL;
|
||||
}
|
||||
|
||||
void used(T *data)
|
||||
{
|
||||
/* tag data as still in use */
|
||||
@@ -343,27 +349,49 @@ protected:
|
||||
|
||||
/* Object Key */
|
||||
|
||||
enum { OBJECT_PERSISTENT_ID_SIZE = 8 };
|
||||
|
||||
struct ObjectKey {
|
||||
void *parent;
|
||||
int index;
|
||||
int id[OBJECT_PERSISTENT_ID_SIZE];
|
||||
void *ob;
|
||||
|
||||
ObjectKey(void *parent_, int index_, void *ob_)
|
||||
: parent(parent_), index(index_), ob(ob_) {}
|
||||
ObjectKey(void *parent_, int id_[OBJECT_PERSISTENT_ID_SIZE], void *ob_)
|
||||
: parent(parent_), ob(ob_)
|
||||
{
|
||||
if(id_)
|
||||
memcpy(id, id_, sizeof(id));
|
||||
else
|
||||
memset(id, 0, sizeof(id));
|
||||
}
|
||||
|
||||
bool operator<(const ObjectKey& k) const
|
||||
{ return (parent < k.parent || (parent == k.parent && (index < k.index || (index == k.index && ob < k.ob)))); }
|
||||
{
|
||||
return (parent < k.parent) ||
|
||||
(parent == k.parent && (memcmp(id, k.id, sizeof(id)) < 0)) ||
|
||||
(memcmp(id, k.id, sizeof(id)) == 0 && ob < k.ob);
|
||||
}
|
||||
};
|
||||
|
||||
struct ParticleSystemKey {
|
||||
void *ob;
|
||||
void *psys;
|
||||
int id[OBJECT_PERSISTENT_ID_SIZE];
|
||||
|
||||
ParticleSystemKey(void *ob_, void *psys_)
|
||||
: ob(ob_), psys(psys_) {}
|
||||
ParticleSystemKey(void *ob_, int id_[OBJECT_PERSISTENT_ID_SIZE])
|
||||
: ob(ob_)
|
||||
{
|
||||
if(id_)
|
||||
memcpy(id, id_, sizeof(id));
|
||||
else
|
||||
memset(id, 0, sizeof(id));
|
||||
}
|
||||
|
||||
bool operator<(const ParticleSystemKey& k) const
|
||||
{ return (ob < k.ob && psys < k.psys); }
|
||||
{
|
||||
/* first id is particle index, we don't compare that */
|
||||
return (ob < k.ob) ||
|
||||
(ob == k.ob && (memcmp(id+1, k.id+1, sizeof(int)*(OBJECT_PERSISTENT_ID_SIZE-1)) < 0));
|
||||
}
|
||||
};
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
||||
Reference in New Issue
Block a user