Commit: db333d9ea4881d9f48e3cc4b1ec59b4dafb27cc0
Author: Brecht Van Lommel
Date:   Thu Mar 8 04:04:52 2018 +0100
Branches: master
https://developer.blender.org/rBdb333d9ea4881d9f48e3cc4b1ec59b4dafb27cc0

Cycles: support arbitrary number of motion blur steps for objects.

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

M       intern/cycles/blender/addon/properties.py
M       intern/cycles/blender/blender_camera.cpp
M       intern/cycles/blender/blender_object.cpp
M       intern/cycles/blender/blender_util.h
M       intern/cycles/kernel/geom/geom_object.h
M       intern/cycles/kernel/kernel_light.h
M       intern/cycles/kernel/kernel_textures.h
M       intern/cycles/kernel/kernel_types.h
M       intern/cycles/render/object.cpp
M       intern/cycles/render/object.h
M       intern/cycles/render/scene.cpp
M       intern/cycles/render/scene.h
M       intern/cycles/render/session.cpp
M       intern/cycles/util/util_transform.h

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

diff --git a/intern/cycles/blender/addon/properties.py 
b/intern/cycles/blender/addon/properties.py
index 62aea8790af..1b95c365616 100644
--- a/intern/cycles/blender/addon/properties.py
+++ b/intern/cycles/blender/addon/properties.py
@@ -1088,7 +1088,7 @@ class CyclesObjectSettings(bpy.types.PropertyGroup):
 
         cls.motion_steps = IntProperty(
                 name="Motion Steps",
-                description="Control accuracy of deformation motion blur, more 
steps gives more memory usage (actual number of steps is 2^(steps - 1))",
+                description="Control accuracy of motion blur, more steps gives 
more memory usage (actual number of steps is 2^(steps - 1))",
                 min=1, soft_max=8,
                 default=1,
                 )
diff --git a/intern/cycles/blender/blender_camera.cpp 
b/intern/cycles/blender/blender_camera.cpp
index 909db8d9449..f00ade320e7 100644
--- a/intern/cycles/blender/blender_camera.cpp
+++ b/intern/cycles/blender/blender_camera.cpp
@@ -229,9 +229,7 @@ static void blender_camera_from_object(BlenderCamera *bcam,
                else
                        bcam->sensor_fit = BlenderCamera::VERTICAL;
 
-               if(object_use_motion(b_ob, b_ob)) {
-                       bcam->motion_steps = object_motion_steps(b_ob);
-               }
+               bcam->motion_steps = object_motion_steps(b_ob, b_ob);
        }
        else {
                /* from lamp not implemented yet */
diff --git a/intern/cycles/blender/blender_object.cpp 
b/intern/cycles/blender/blender_object.cpp
index 45309292f0b..4b40f4d458b 100644
--- a/intern/cycles/blender/blender_object.cpp
+++ b/intern/cycles/blender/blender_object.cpp
@@ -327,22 +327,11 @@ Object *BlenderSync::sync_object(BL::Object& b_parent,
        if(motion) {
                object = object_map.find(key);
 
-               if(object && (scene->need_motion() == Scene::MOTION_PASS ||
-                             object_use_motion(b_parent, b_ob)))
-               {
-                       /* object transformation */
-                       if(tfm != object->tfm) {
-                               VLOG(1) << "Object " << b_ob.name() << " motion 
detected.";
-                               if(motion_time == -1.0f || motion_time == 1.0f) 
{
-                                       object->use_motion = true;
-                               }
-                       }
-
-                       if(motion_time == -1.0f) {
-                               object->motion.pre = tfm;
-                       }
-                       else if(motion_time == 1.0f) {
-                               object->motion.post = tfm;
+               if(object && object->use_motion()) {
+                       /* Set transform at matching motion time step. */
+                       int time_index = object->motion_step(motion_time);
+                       if(time_index >= 0) {
+                               object->motion[time_index] = tfm;
                        }
 
                        /* mesh deformation */
@@ -389,24 +378,34 @@ Object *BlenderSync::sync_object(BL::Object& b_parent,
                object->name = b_ob.name().c_str();
                object->pass_id = b_ob.pass_index();
                object->tfm = tfm;
-               object->motion.pre = transform_empty();
-               object->motion.post = transform_empty();
-               object->use_motion = false;
+               object->motion.clear();
 
                /* motion blur */
-               if(scene->need_motion() == Scene::MOTION_BLUR && object->mesh) {
+               Scene::MotionType need_motion = scene->need_motion();
+               if(need_motion != Scene::MOTION_NONE && object->mesh) {
                        Mesh *mesh = object->mesh;
                        mesh->use_motion_blur = false;
+                       mesh->motion_steps = 0;
 
-                       if(object_use_motion(b_parent, b_ob)) {
+                       uint motion_steps;
+
+                       if(scene->need_motion() == Scene::MOTION_BLUR) {
+                               motion_steps = object_motion_steps(b_parent, 
b_ob);
                                if(object_use_deform_motion(b_parent, b_ob)) {
-                                       mesh->motion_steps = 
object_motion_steps(b_ob);
+                                       mesh->motion_steps = motion_steps;
                                        mesh->use_motion_blur = true;
                                }
+                       }
+                       else {
+                               motion_steps = 3;
+                               mesh->motion_steps = motion_steps;
+                       }
 
-                               for(size_t step = 0; step < mesh->motion_steps 
- 1; step++) {
-                                       
motion_times.insert(mesh->motion_time(step));
-                               }
+                       object->motion.resize(motion_steps, transform_empty());
+                       object->motion[motion_steps/2] = tfm;
+
+                       for(size_t step = 0; step < motion_steps; step++) {
+                               motion_times.insert(object->motion_time(step));
                        }
                }
 
diff --git a/intern/cycles/blender/blender_util.h 
b/intern/cycles/blender/blender_util.h
index c4c45035b5a..c418b19a637 100644
--- a/intern/cycles/blender/blender_util.h
+++ b/intern/cycles/blender/blender_util.h
@@ -484,33 +484,34 @@ static inline void mesh_texture_space(BL::Mesh& b_mesh,
        loc = loc*size - make_float3(0.5f, 0.5f, 0.5f);
 }
 
-/* object used for motion blur */
-static inline bool object_use_motion(BL::Object& b_parent, BL::Object& b_ob)
+/* Object motion steps, returns 0 if no motion blur needed. */
+static inline uint object_motion_steps(BL::Object& b_parent, BL::Object& b_ob)
 {
+       /* Get motion enabled and steps from object itself. */
        PointerRNA cobject = RNA_pointer_get(&b_ob.ptr, "cycles");
        bool use_motion = get_boolean(cobject, "use_motion_blur");
-       /* If motion blur is enabled for the object we also check
-        * whether it's enabled for the parent object as well.
-        *
-        * This way we can control motion blur from the dupligroup
-        * duplicator much easier.
-        */
-       if(use_motion && b_parent.ptr.data != b_ob.ptr.data) {
+       if(!use_motion) {
+               return 0;
+       }
+
+       uint steps = max(1, get_int(cobject, "motion_steps"));
+
+       /* Also check parent object, so motion blur and steps can be
+        * controlled by dupligroup duplicator for linked groups. */
+       if(b_parent.ptr.data != b_ob.ptr.data) {
                PointerRNA parent_cobject = RNA_pointer_get(&b_parent.ptr, 
"cycles");
                use_motion &= get_boolean(parent_cobject, "use_motion_blur");
-       }
-       return use_motion;
-}
 
-/* object motion steps */
-static inline uint object_motion_steps(BL::Object& b_ob)
-{
-       PointerRNA cobject = RNA_pointer_get(&b_ob.ptr, "cycles");
-       uint steps = get_int(cobject, "motion_steps");
+               if(!use_motion) {
+                       return 0;
+               }
+
+               steps = max(steps, get_int(parent_cobject, "motion_steps"));
+       }
 
-       /* use uneven number of steps so we get one keyframe at the current 
frame,
-        * and ue 2^(steps - 1) so objects with more/fewer steps still have 
samples
-        * at the same times, to avoid sampling at many different times */
+       /* Use uneven number of steps so we get one keyframe at the current 
frame,
+        * and use 2^(steps - 1) so objects with more/fewer steps still have 
samples
+        * at the same times, to avoid sampling at many different times. */
        return (2 << (steps - 1)) + 1;
 }
 
diff --git a/intern/cycles/kernel/geom/geom_object.h 
b/intern/cycles/kernel/geom/geom_object.h
index 67d039e1bc7..800649abf38 100644
--- a/intern/cycles/kernel/geom/geom_object.h
+++ b/intern/cycles/kernel/geom/geom_object.h
@@ -40,18 +40,12 @@ enum ObjectVectorTransform {
 
 ccl_device_inline Transform object_fetch_transform(KernelGlobals *kg, int 
object, enum ObjectTransform type)
 {
-       Transform tfm;
        if(type == OBJECT_INVERSE_TRANSFORM) {
-               tfm.x = kernel_tex_fetch(__objects, object).tfm.mid.x;
-               tfm.y = kernel_tex_fetch(__objects, object).tfm.mid.y;
-               tfm.z = kernel_tex_fetch(__objects, object).tfm.mid.z;
+               return kernel_tex_fetch(__objects, object).itfm;
        }
        else {
-               tfm.x = kernel_tex_fetch(__objects, object).tfm.pre.x;
-               tfm.y = kernel_tex_fetch(__objects, object).tfm.pre.y;
-               tfm.z = kernel_tex_fetch(__objects, object).tfm.pre.z;
+               return kernel_tex_fetch(__objects, object).tfm;
        }
-       return tfm;
 }
 
 /* Lamp to world space transformation */
@@ -79,10 +73,12 @@ ccl_device_inline Transform 
object_fetch_motion_pass_transform(KernelGlobals *kg
 #ifdef __OBJECT_MOTION__
 ccl_device_inline Transform object_fetch_transform_motion(KernelGlobals *kg, 
int object, float time)
 {
-       const ccl_global DecomposedMotionTransform *motion = 
&kernel_tex_fetch(__objects, object).tfm;
+       const uint motion_offset = kernel_tex_fetch(__objects, 
object).motion_offset;
+       const ccl_global DecomposedTransform *motion = 
&kernel_tex_fetch(__object_motion, motion_offset);
+       const uint num_steps = kernel_tex_fetch(__objects, object).numsteps * 2 
+ 1;
 
        Transform tfm;
-       transform_motion_array_interpolate(&tfm, &motion->pre, 3, time);
+       transform_motion_array_interpolate(&tfm, motion, num_steps, time);
 
        return tfm;
 }
diff --git a/intern/cycles/kernel/kernel_light.h 
b/intern/cycles/kernel/kernel_light.h
index aaf7a7abdd4..efab69ee37d 100644
--- a/intern/cycles/kernel/kernel_light.h
+++ b/intern/cycles/kernel/kernel_light.h
@@ -792,7 +792,8 @@ ccl_device_inline bool 
triangle_world_space_vertices(KernelGlobals *kg, int obje
 #ifdef __INSTANCING__
        if(!(object_flag & SD_OBJECT_TRANSFORM_APPLIED)) {
 #  ifdef __OBJECT_MOTION__
-               Transform tfm = object_fetch_transform_motion_test(kg, object, 
time, NULL);
+               float object_time = (time >= 0.0f) ? time : 0.5f;
+               Transform tfm = object_fetch_transform_motion_test(kg, object, 
object_time, NULL);
 #  else
                Transform tfm = object_fetch_transform(kg, object, 
OBJECT_TRANSFORM);
 #  endif
diff --git a/intern/cycles/kernel/kernel_textures.h 
b/intern/cycles/kernel/kernel_textures.h
index 56de5b27605..9047b93a0b2 100644
--- a/intern/cycles/kernel/kernel_textures.h
+++ b/intern/cycles/kernel/kernel_textures.h
@@ -33,6 +33,7 @@ KERNEL_TEX(float2, __prim_time)
 /* objects */
 KERNEL_TEX(KernelObject, __objects)
 KERNEL_TEX(Transform, __object_motion_pass)
+KERNEL_TEX(DecomposedTransform, __object_motion)
 KERNEL_TEX(uint, __object_flag)
 
 /* cameras */
diff --git a/intern/cycles/kernel/kernel_types.h 
b/intern/cycles/kernel/kernel_types.h
index 2c3b7ba29a4..977ceac12ea 100644
--- a/intern/cycles/kernel/kernel_types.h
+++ b/intern/cycles/kernel/kernel_types.h
@@ -1433,7 +1433,8 @@ static_assert_align(KernelData, 16);
 /* Kernel data structures. */
 
 typedef struct KernelObject {
-       DecomposedMotionTransform tfm;
+       Transform tfm;
+       Transform itfm;
 
        float surface_area;
        float pass_id;
@@ -1449,7 +1450,8 @@ typedef struct KernelObject {
 
        uint patch_map_offset;
        uint attribute_map_offset;
-       uint pad1, pad2;
+       uint motion_offset;
+       uint pad;
 } KernelObject;;
 static_assert_align(KernelObject, 16);
 
diff --git a/intern/cycles/render/object.cpp b/intern/cycles/render/object.cpp
index bde340ae928..138de250c5f 100644
--- a/intern/cycles/render/object.cpp
+++ b/intern/cycles/render/object.cpp
@@ -54,6 +54,9 @@ struct UpdateObjectTransformState {
         */
        map<Mesh*, float> surface_area_map;
 
+       /* Motion offsets for each object. */
+       array<uint> motion_offset;
+
        /* Packed object arrays. Those will be filled in. */
        uint *object_flag;
        KernelObject *objects;
@@ -91,6 +94,7 @@ NODE_D

@@ Diff output truncated at 10240 characters. @@

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to