diff options
Diffstat (limited to 'intern/cycles/blender/blender_mesh.cpp')
-rw-r--r-- | intern/cycles/blender/blender_mesh.cpp | 110 |
1 files changed, 84 insertions, 26 deletions
diff --git a/intern/cycles/blender/blender_mesh.cpp b/intern/cycles/blender/blender_mesh.cpp index b356537e971..9e11cc1ae0b 100644 --- a/intern/cycles/blender/blender_mesh.cpp +++ b/intern/cycles/blender/blender_mesh.cpp @@ -449,6 +449,7 @@ Mesh *BlenderSync::sync_mesh(BL::Object b_ob, bool object_updated, bool hide_tri Mesh *mesh; if(!mesh_map.sync(&mesh, key)) { + /* if transform was applied to mesh, need full update */ if(object_updated && mesh->transform_applied); /* test if shaders changed, these can be object level so mesh @@ -503,7 +504,7 @@ Mesh *BlenderSync::sync_mesh(BL::Object b_ob, bool object_updated, bool hide_tri } if(render_layer.use_hair) - sync_curves(mesh, b_mesh, b_ob, 0); + sync_curves(mesh, b_mesh, b_ob, false); /* free derived mesh */ b_data.meshes.remove(b_mesh); @@ -544,46 +545,103 @@ Mesh *BlenderSync::sync_mesh(BL::Object b_ob, bool object_updated, bool hide_tri return mesh; } -void BlenderSync::sync_mesh_motion(BL::Object b_ob, Mesh *mesh, int motion) +void BlenderSync::sync_mesh_motion(BL::Object b_ob, Object *object, float motion_time) { - /* todo: displacement, subdivision */ - size_t size = mesh->verts.size(); - - /* skip objects without deforming modifiers. this is not a totally reliable, - * would need a more extensive check to see which objects are animated */ - if(!size || !ccl::BKE_object_is_deform_modified(b_ob, b_scene, preview)) - return; - /* ensure we only sync instanced meshes once */ + Mesh *mesh = object->mesh; + if(mesh_motion_synced.find(mesh) != mesh_motion_synced.end()) return; mesh_motion_synced.insert(mesh); + /* for motion pass always compute, for motion blur it can be disabled */ + int time_index = 0; + + if(scene->need_motion() == Scene::MOTION_BLUR) { + /* see if this mesh needs motion data at this time */ + vector<float> object_times = object->motion_times(); + bool found = false; + + foreach(float object_time, object_times) { + if(motion_time == object_time) { + found = true; + break; + } + else + time_index++; + } + + if(!found) + return; + } + else { + if(motion_time == -1.0f) + time_index = 0; + else if(motion_time == 1.0f) + time_index = 1; + else + return; + } + + /* skip objects without deforming modifiers. this is not totally reliable, + * would need a more extensive check to see which objects are animated */ + size_t numverts = mesh->verts.size(); + size_t numkeys = mesh->curve_keys.size(); + + if((!numverts && !numkeys) || !ccl::BKE_object_is_deform_modified(b_ob, b_scene, preview)) + return; + /* get derived mesh */ BL::Mesh b_mesh = object_to_mesh(b_data, b_ob, b_scene, true, !preview, false); - if(b_mesh) { - BL::Mesh::vertices_iterator v; - AttributeStandard std = (motion == -1)? ATTR_STD_MOTION_PRE: ATTR_STD_MOTION_POST; - Attribute *attr_M = mesh->attributes.add(std); - float3 *M = attr_M->data_float3(), *cur_M; - size_t i = 0; + if(!b_mesh) + return; + + if(numverts) { + /* find attributes */ + Attribute *attr_mP = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION); + bool new_attribute = false; + + /* add new attributes if they don't exist already */ + if(!attr_mP) { + attr_mP = mesh->attributes.add(ATTR_STD_MOTION_VERTEX_POSITION); + + new_attribute = true; + } + + /* load vertex data from mesh */ + float3 *mP = attr_mP->data_float3() + time_index*numverts; - for(b_mesh.vertices.begin(v), cur_M = M; v != b_mesh.vertices.end() && i < size; ++v, cur_M++, i++) - *cur_M = get_float3(v->co()); + BL::Mesh::vertices_iterator v; + int i = 0; - /* if number of vertices changed, or if coordinates stayed the same, drop it */ - if(i != size || memcmp(M, &mesh->verts[0], sizeof(float3)*size) == 0) - mesh->attributes.remove(std); + for(b_mesh.vertices.begin(v); v != b_mesh.vertices.end() && i < numverts; ++v, ++i) + mP[i] = get_float3(v->co()); - /* hair motion */ - if(render_layer.use_hair) - sync_curves(mesh, b_mesh, b_ob, motion); + /* in case of new attribute, we verify if there really was any motion */ + if(new_attribute) { + if(i != numverts || memcmp(mP, &mesh->verts[0], sizeof(float3)*numverts) == 0) { + /* no motion, remove attributes again */ + mesh->attributes.remove(ATTR_STD_MOTION_VERTEX_POSITION); + } + else if(time_index > 0) { + /* motion, fill up previous steps that we might have skipped because + * they had no motion, but we need them anyway now */ + float3 *P = &mesh->verts[0]; - /* free derived mesh */ - b_data.meshes.remove(b_mesh); + for(int step = 0; step < time_index; step++) + memcpy(attr_mP->data_float3() + step*numverts, P, sizeof(float3)*numverts); + } + } } + + /* hair motion */ + if(numkeys) + sync_curves(mesh, b_mesh, b_ob, true, time_index); + + /* free derived mesh */ + b_data.meshes.remove(b_mesh); } CCL_NAMESPACE_END |