Fix T49163: let Cycles only hide particles with missing motion data, not regular objects.

This commit is contained in:
Brecht Van Lommel 2016-08-28 21:20:06 +02:00
parent 116bab702e
commit 8a02c5fc62
Notes: blender-bot 2023-02-14 07:39:47 +01:00
Referenced by issue #49252, Microdisplacement; Very recent builds crash when image textures are used (when the mode is set to 'true')
Referenced by issue #49193, GP and Uv image editor - Sculpt offset
Referenced by issue #49194, GP and Uv image editor - E shortcut conflict
Referenced by issue #49195, GP and Uv image editor - no Undo on GP during edit mode
Referenced by issue #49163, Animated object visibilty 1 frame off when turning on motion blur
3 changed files with 44 additions and 28 deletions

View File

@ -36,6 +36,8 @@ bool BlenderSync::sync_dupli_particle(BL::Object& b_ob,
if(!b_psys)
return false;
object->hide_on_missing_motion = true;
/* test if we need particle data */
if(!object->mesh->need_attribute(scene, ATTR_STD_PARTICLE))
return false;

View File

@ -45,6 +45,7 @@ NODE_DEFINE(Object)
SOCKET_UINT(random_id, "Random ID", 0);
SOCKET_INT(pass_id, "Pass ID", 0);
SOCKET_BOOLEAN(use_holdout, "Use Holdout", false);
SOCKET_BOOLEAN(hide_on_missing_motion, "Hide on Missing Motion", false);
SOCKET_POINT(dupli_generated, "Dupli Generated", make_float3(0.0f, 0.0f, 0.0f));
SOCKET_POINT2(dupli_uv, "Dupli UV", make_float2(0.0f, 0.0f));
@ -72,29 +73,42 @@ void Object::compute_bounds(bool motion_blur)
BoundBox mbounds = mesh->bounds;
if(motion_blur && use_motion) {
if(motion.pre == transform_empty() ||
motion.post == transform_empty()) {
MotionTransform mtfm = motion;
if(hide_on_missing_motion) {
/* Hide objects that have no valid previous or next transform, for
* example particle that stop existing. TODO: add support for this
* case in the kernel so we don't get render artifacts. */
bounds = BoundBox::empty;
}
else {
DecompMotionTransform decomp;
transform_motion_decompose(&decomp, &motion, &tfm);
bounds = BoundBox::empty;
/* todo: this is really terrible. according to pbrt there is a better
* way to find this iteratively, but did not find implementation yet
* or try to implement myself */
for(float t = 0.0f; t < 1.0f; t += (1.0f/128.0f)) {
Transform ttfm;
transform_motion_interpolate(&ttfm, &decomp, t);
bounds.grow(mbounds.transformed(&ttfm));
if(mtfm.pre == transform_empty() ||
mtfm.post == transform_empty()) {
bounds = BoundBox::empty;
return;
}
}
/* In case of missing motion information for previous/next frame,
* assume there is no motion. */
if(mtfm.pre == transform_empty()) {
mtfm.pre = tfm;
}
if(mtfm.post == transform_empty()) {
mtfm.post = tfm;
}
DecompMotionTransform decomp;
transform_motion_decompose(&decomp, &mtfm, &tfm);
bounds = BoundBox::empty;
/* todo: this is really terrible. according to pbrt there is a better
* way to find this iteratively, but did not find implementation yet
* or try to implement myself */
for(float t = 0.0f; t < 1.0f; t += (1.0f/128.0f)) {
Transform ttfm;
transform_motion_interpolate(&ttfm, &decomp, t);
bounds.grow(mbounds.transformed(&ttfm));
}
}
else {
if(mesh->transform_applied) {
@ -345,28 +359,27 @@ void ObjectManager::device_update_object_transform(UpdateObejctTransformState *s
* comes with deformed position in object space, or if we transform
* the shading point in world space.
*/
Transform mtfm_pre = ob->motion.pre;
Transform mtfm_post = ob->motion.post;
MotionTransform mtfm = ob->motion;
/* In case of missing motion information for previous/next frame,
* assume there is no motion. */
if(!ob->use_motion || mtfm_pre == transform_empty()) {
mtfm_pre = ob->tfm;
if(!ob->use_motion || mtfm.pre == transform_empty()) {
mtfm.pre = ob->tfm;
}
if(!ob->use_motion || mtfm_post == transform_empty()) {
mtfm_post = ob->tfm;
if(!ob->use_motion || mtfm.post == transform_empty()) {
mtfm.post = ob->tfm;
}
if(!mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION)) {
mtfm_pre = mtfm_pre * itfm;
mtfm_post = mtfm_post * itfm;
mtfm.pre = mtfm.pre * itfm;
mtfm.post = mtfm.post * itfm;
}
else {
flag |= SD_OBJECT_HAS_VERTEX_MOTION;
}
memcpy(&objects_vector[object_index*OBJECT_VECTOR_SIZE+0], &mtfm_pre, sizeof(float4)*3);
memcpy(&objects_vector[object_index*OBJECT_VECTOR_SIZE+3], &mtfm_post, sizeof(float4)*3);
memcpy(&objects_vector[object_index*OBJECT_VECTOR_SIZE+0], &mtfm.pre, sizeof(float4)*3);
memcpy(&objects_vector[object_index*OBJECT_VECTOR_SIZE+3], &mtfm.post, sizeof(float4)*3);
}
#ifdef __OBJECT_MOTION__
else if(state->need_motion == Scene::MOTION_BLUR) {

View File

@ -51,6 +51,7 @@ public:
uint visibility;
MotionTransform motion;
bool use_motion;
bool hide_on_missing_motion;
bool use_holdout;
float3 dupli_generated;