Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'intern/cycles/blender')
-rw-r--r--intern/cycles/blender/blender_camera.cpp12
-rw-r--r--intern/cycles/blender/blender_curves.cpp52
-rw-r--r--intern/cycles/blender/blender_mesh.cpp110
-rw-r--r--intern/cycles/blender/blender_object.cpp88
-rw-r--r--intern/cycles/blender/blender_sync.h12
5 files changed, 196 insertions, 78 deletions
diff --git a/intern/cycles/blender/blender_camera.cpp b/intern/cycles/blender/blender_camera.cpp
index 4c6b42a9cbc..6bbd4106a96 100644
--- a/intern/cycles/blender/blender_camera.cpp
+++ b/intern/cycles/blender/blender_camera.cpp
@@ -386,7 +386,7 @@ void BlenderSync::sync_camera(BL::RenderSettings b_render, BL::Object b_override
blender_camera_sync(cam, &bcam, width, height);
}
-void BlenderSync::sync_camera_motion(BL::Object b_ob, int motion)
+void BlenderSync::sync_camera_motion(BL::Object b_ob, float motion_time)
{
Camera *cam = scene->camera;
@@ -394,12 +394,14 @@ void BlenderSync::sync_camera_motion(BL::Object b_ob, int motion)
tfm = blender_camera_matrix(tfm, cam->type);
if(tfm != cam->matrix) {
- if(motion == -1)
+ if(motion_time == -1.0f) {
cam->motion.pre = tfm;
- else
+ cam->use_motion = true;
+ }
+ else if(motion_time == 1.0f) {
cam->motion.post = tfm;
-
- cam->use_motion = true;
+ cam->use_motion = true;
+ }
}
}
diff --git a/intern/cycles/blender/blender_curves.cpp b/intern/cycles/blender/blender_curves.cpp
index 4420a306e31..22de7b64273 100644
--- a/intern/cycles/blender/blender_curves.cpp
+++ b/intern/cycles/blender/blender_curves.cpp
@@ -612,16 +612,23 @@ void ExportCurveSegments(Scene *scene, Mesh *mesh, ParticleCurveData *CData)
}
}
-static void ExportCurveSegmentsMotion(Scene *scene, Mesh *mesh, ParticleCurveData *CData, int motion)
+static void ExportCurveSegmentsMotion(Scene *scene, Mesh *mesh, ParticleCurveData *CData, int time_index)
{
+ /* find attribute */
+ Attribute *attr_mP = mesh->curve_attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
+ bool new_attribute = false;
+
+ /* add new attribute if it doesn't exist already */
+ if(!attr_mP) {
+ attr_mP = mesh->curve_attributes.add(ATTR_STD_MOTION_VERTEX_POSITION);
+ new_attribute = true;
+ }
+
/* export motion vectors for curve keys */
- AttributeStandard std = (motion == -1)? ATTR_STD_MOTION_PRE: ATTR_STD_MOTION_POST;
- Attribute *attr_motion = mesh->curve_attributes.add(std);
- float4 *data_motion = attr_motion->data_float4();
- float4 *current_motion = data_motion;
- size_t size = mesh->curve_keys.size();
- size_t i = 0;
+ size_t numkeys = mesh->curve_keys.size();
+ float4 *mP = attr_mP->data_float4() + time_index*numkeys;
bool have_motion = false;
+ int i = 0;
for(int sys = 0; sys < CData->psys_firstcurve.size(); sys++) {
if(CData->psys_curvenum[sys] == 0)
@@ -640,16 +647,14 @@ static void ExportCurveSegmentsMotion(Scene *scene, Mesh *mesh, ParticleCurveDat
if(CData->psys_closetip[sys] && (curvekey == CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1))
radius = 0.0f;
- *current_motion = float3_to_float4(ickey_loc);
- current_motion->w = radius;
+ mP[i] = float3_to_float4(ickey_loc);
+ mP[i].w = radius;
/* unlike mesh coordinates, these tend to be slightly different
* between frames due to particle transforms into/out of object
* space, so we use an epsilon to detect actual changes */
- if(len_squared(*current_motion - mesh->curve_keys[i]) > 1e-5f*1e-5f)
+ if(len_squared(mP[i] - mesh->curve_keys[i]) > 1e-5f*1e-5f)
have_motion = true;
-
- current_motion++;
}
i++;
@@ -657,8 +662,23 @@ static void ExportCurveSegmentsMotion(Scene *scene, Mesh *mesh, ParticleCurveDat
}
}
- if(i != size || !have_motion)
- mesh->curve_attributes.remove(std);
+ /* in case of new attribute, we verify if there really was any motion */
+ if(new_attribute) {
+ if(i != numkeys || !have_motion) {
+ /* no motion, remove attributes again */
+ mesh->curve_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 */
+ for(int step = 0; step < time_index; step++) {
+ float4 *mP = attr_mP->data_float4() + step*numkeys;
+
+ for(int key = 0; key < numkeys; key++)
+ mP[key] = mesh->curve_keys[key];
+ }
+ }
+ }
}
void ExportCurveTriangleUV(Mesh *mesh, ParticleCurveData *CData, int vert_offset, int resol, float3 *uvdata)
@@ -804,7 +824,7 @@ void BlenderSync::sync_curve_settings()
curve_system_manager->tag_update(scene);
}
-void BlenderSync::sync_curves(Mesh *mesh, BL::Mesh b_mesh, BL::Object b_ob, int motion)
+void BlenderSync::sync_curves(Mesh *mesh, BL::Mesh b_mesh, BL::Object b_ob, bool motion, int time_index)
{
if(!motion) {
/* Clear stored curve data */
@@ -859,7 +879,7 @@ void BlenderSync::sync_curves(Mesh *mesh, BL::Mesh b_mesh, BL::Object b_ob, int
}
else {
if(motion)
- ExportCurveSegmentsMotion(scene, mesh, &CData, motion);
+ ExportCurveSegmentsMotion(scene, mesh, &CData, time_index);
else
ExportCurveSegments(scene, mesh, &CData);
}
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
diff --git a/intern/cycles/blender/blender_object.cpp b/intern/cycles/blender/blender_object.cpp
index 6ffc8c81ce6..f5945a68fc1 100644
--- a/intern/cycles/blender/blender_object.cpp
+++ b/intern/cycles/blender/blender_object.cpp
@@ -217,9 +217,11 @@ void BlenderSync::sync_background_light()
/* Object */
-Object *BlenderSync::sync_object(BL::Object b_parent, int persistent_id[OBJECT_PERSISTENT_ID_SIZE], BL::DupliObject b_dupli_ob, Transform& tfm, uint layer_flag, int motion, bool hide_tris)
+Object *BlenderSync::sync_object(BL::Object b_parent, int persistent_id[OBJECT_PERSISTENT_ID_SIZE], BL::DupliObject b_dupli_ob,
+ Transform& tfm, uint layer_flag, float motion_time, bool hide_tris)
{
BL::Object b_ob = (b_dupli_ob ? b_dupli_ob.object() : b_parent);
+ bool motion = motion_time != 0.0f;
/* light is handled separately */
if(object_is_light(b_ob)) {
@@ -243,18 +245,21 @@ Object *BlenderSync::sync_object(BL::Object b_parent, int persistent_id[OBJECT_P
object = object_map.find(key);
if(object) {
+ /* object transformation */
if(tfm != object->tfm) {
- if(motion == -1)
+ if(motion_time == -1.0f) {
object->motion.pre = tfm;
- else
+ object->use_motion = true;
+ }
+ else if(motion_time == 1.0f) {
object->motion.post = tfm;
-
- object->use_motion = true;
+ object->use_motion = true;
+ }
}
- /* mesh deformation blur not supported yet */
- if(!scene->integrator->motion_blur)
- sync_mesh_motion(b_ob, object->mesh, motion);
+ /* mesh deformation */
+ if(object->mesh)
+ sync_mesh_motion(b_ob, object, motion_time);
}
return object;
@@ -314,6 +319,20 @@ Object *BlenderSync::sync_object(BL::Object b_parent, int persistent_id[OBJECT_P
object->motion.post = tfm;
object->use_motion = false;
+ /* motion blur */
+ if(scene->need_motion() == Scene::MOTION_BLUR && object->mesh) {
+ Mesh *mesh = object->mesh;
+
+ if(true) {
+ if(true)
+ mesh->motion_steps = 3;
+
+ vector<float> times = object->motion_times();
+ foreach(float time, times)
+ motion_times.insert(time);
+ }
+ }
+
/* random number */
object->random_id = hash_string(object->name.c_str());
@@ -412,10 +431,11 @@ static bool object_render_hide_duplis(BL::Object b_ob)
/* Object Loop */
-void BlenderSync::sync_objects(BL::SpaceView3D b_v3d, int motion)
+void BlenderSync::sync_objects(BL::SpaceView3D b_v3d, float motion_time)
{
/* layer data */
uint scene_layer = render_layer.scene_layer;
+ bool motion = motion_time != 0.0f;
if(!motion) {
/* prepare for sync */
@@ -424,6 +444,7 @@ void BlenderSync::sync_objects(BL::SpaceView3D b_v3d, int motion)
object_map.pre_sync();
mesh_synced.clear();
particle_system_map.pre_sync();
+ motion_times.clear();
}
else {
mesh_motion_synced.clear();
@@ -468,7 +489,7 @@ void BlenderSync::sync_objects(BL::SpaceView3D b_v3d, int motion)
BL::Array<int, OBJECT_PERSISTENT_ID_SIZE> persistent_id = b_dup->persistent_id();
/* sync object and mesh or light data */
- Object *object = sync_object(*b_ob, persistent_id.data, *b_dup, tfm, ob_layer, motion, hide_tris);
+ Object *object = sync_object(*b_ob, persistent_id.data, *b_dup, tfm, ob_layer, motion_time, hide_tris);
/* sync possible particle data, note particle_id
* starts counting at 1, first is dummy particle */
@@ -488,7 +509,7 @@ void BlenderSync::sync_objects(BL::SpaceView3D b_v3d, int motion)
if(!object_render_hide(*b_ob, true, true, hide_tris)) {
/* object itself */
Transform tfm = get_transform(b_ob->matrix_world());
- sync_object(*b_ob, NULL, PointerRNA_NULL, tfm, ob_layer, motion, hide_tris);
+ sync_object(*b_ob, NULL, PointerRNA_NULL, tfm, ob_layer, motion_time, hide_tris);
}
}
@@ -528,31 +549,46 @@ void BlenderSync::sync_motion(BL::SpaceView3D b_v3d, BL::Object b_override, void
b_cam = b_override;
Camera prevcam = *(scene->camera);
-
- /* go back and forth one frame */
- int frame = b_scene.frame_current();
- for(int motion = -1; motion <= 1; motion += 2) {
- /* we need to set the python thread state again because this
- * function assumes it is being executed from python and will
- * try to save the thread state */
+ int frame_center = b_scene.frame_current();
+
+ /* always sample these times for camera motion */
+ motion_times.insert(-1.0f);
+ motion_times.insert(1.0f);
+
+ /* note iteration over motion_times set happens in sorted order */
+ foreach(float relative_time, motion_times) {
+ /* sync camera, only supports two times at the moment */
+ if(relative_time == -1.0f || relative_time == 1.0f)
+ sync_camera_motion(b_cam, relative_time);
+
+ /* fixed shutter time to get previous and next frame for motion pass */
+ float shuttertime;
+
+ if(scene->need_motion() == Scene::MOTION_PASS)
+ shuttertime = 2.0f;
+ else
+ shuttertime = scene->camera->shuttertime;
+
+ /* compute frame and subframe time */
+ float time = frame_center + relative_time * shuttertime * 0.5f;
+ int frame = (int)floorf(time);
+ float subframe = time - frame;
+
+ /* change frame */
python_thread_state_restore(python_thread_state);
- b_scene.frame_set(frame + motion, 0.0f);
+ b_scene.frame_set(frame, subframe);
python_thread_state_save(python_thread_state);
- /* camera object */
- if(b_cam)
- sync_camera_motion(b_cam, motion);
-
- /* mesh objects */
- sync_objects(b_v3d, motion);
+ /* sync object */
+ sync_objects(b_v3d, relative_time);
}
/* we need to set the python thread state again because this
* function assumes it is being executed from python and will
* try to save the thread state */
python_thread_state_restore(python_thread_state);
- b_scene.frame_set(frame, 0.0f);
+ b_scene.frame_set(frame_center, 0.0f);
python_thread_state_save(python_thread_state);
/* tag camera for motion update */
diff --git a/intern/cycles/blender/blender_sync.h b/intern/cycles/blender/blender_sync.h
index 205761ad302..9c4175ef690 100644
--- a/intern/cycles/blender/blender_sync.h
+++ b/intern/cycles/blender/blender_sync.h
@@ -71,7 +71,7 @@ private:
/* sync */
void sync_lamps(bool update_all);
void sync_materials(bool update_all);
- void sync_objects(BL::SpaceView3D b_v3d, int motion = 0);
+ void sync_objects(BL::SpaceView3D b_v3d, float motion_time = 0.0f);
void sync_motion(BL::SpaceView3D b_v3d, BL::Object b_override, void **python_thread_state);
void sync_film();
void sync_view();
@@ -81,12 +81,13 @@ private:
void sync_nodes(Shader *shader, BL::ShaderNodeTree b_ntree);
Mesh *sync_mesh(BL::Object b_ob, bool object_updated, bool hide_tris);
- void sync_curves(Mesh *mesh, BL::Mesh b_mesh, BL::Object b_ob, int motion);
- Object *sync_object(BL::Object b_parent, int persistent_id[OBJECT_PERSISTENT_ID_SIZE], BL::DupliObject b_dupli_object, Transform& tfm, uint layer_flag, int motion, bool hide_tris);
+ void sync_curves(Mesh *mesh, BL::Mesh b_mesh, BL::Object b_ob, bool motion, int time_index = 0);
+ Object *sync_object(BL::Object b_parent, int persistent_id[OBJECT_PERSISTENT_ID_SIZE], BL::DupliObject b_dupli_ob,
+ Transform& tfm, uint layer_flag, float motion_time, bool hide_tris);
void sync_light(BL::Object b_parent, int persistent_id[OBJECT_PERSISTENT_ID_SIZE], BL::Object b_ob, Transform& tfm);
void sync_background_light();
- void sync_mesh_motion(BL::Object b_ob, Mesh *mesh, int motion);
- void sync_camera_motion(BL::Object b_ob, int motion);
+ void sync_mesh_motion(BL::Object b_ob, Object *object, float motion_time);
+ void sync_camera_motion(BL::Object b_ob, float motion_time);
/* particles */
bool sync_dupli_particle(BL::Object b_ob, BL::DupliObject b_dup, Object *object);
@@ -109,6 +110,7 @@ private:
id_map<ParticleSystemKey, ParticleSystem> particle_system_map;
set<Mesh*> mesh_synced;
set<Mesh*> mesh_motion_synced;
+ std::set<float> motion_times;
void *world_map;
bool world_recalc;