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/render/object.cpp')
-rw-r--r--intern/cycles/render/object.cpp83
1 files changed, 68 insertions, 15 deletions
diff --git a/intern/cycles/render/object.cpp b/intern/cycles/render/object.cpp
index 28645d856a8..ccc654965f1 100644
--- a/intern/cycles/render/object.cpp
+++ b/intern/cycles/render/object.cpp
@@ -38,15 +38,37 @@ Object::Object()
visibility = ~0;
pass_id = 0;
bounds = BoundBox::empty;
+ motion.pre = transform_identity();
+ motion.post = transform_identity();
+ use_motion = false;
}
Object::~Object()
{
}
-void Object::compute_bounds()
+void Object::compute_bounds(bool motion_blur)
{
- bounds = mesh->bounds.transformed(&tfm);
+ BoundBox mbounds = mesh->bounds;
+
+ if(motion_blur && use_motion) {
+ MotionTransform decomp;
+ transform_motion_decompose(&decomp, &motion);
+
+ 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
+ bounds = mbounds.transformed(&tfm);
}
void Object::apply_transform()
@@ -57,8 +79,8 @@ void Object::apply_transform()
for(size_t i = 0; i < mesh->verts.size(); i++)
mesh->verts[i] = transform_point(&tfm, mesh->verts[i]);
- Attribute *attr_fN = mesh->attributes.find(Attribute::STD_FACE_NORMAL);
- Attribute *attr_vN = mesh->attributes.find(Attribute::STD_VERTEX_NORMAL);
+ Attribute *attr_fN = mesh->attributes.find(ATTR_STD_FACE_NORMAL);
+ Attribute *attr_vN = mesh->attributes.find(ATTR_STD_VERTEX_NORMAL);
Transform ntfm = transform_transpose(transform_inverse(tfm));
@@ -83,7 +105,7 @@ void Object::apply_transform()
if(bounds.valid()) {
mesh->compute_bounds();
- compute_bounds();
+ compute_bounds(false);
}
tfm = transform_identity();
@@ -123,6 +145,7 @@ void ObjectManager::device_update_transforms(Device *device, DeviceScene *dscene
float4 *objects = dscene->objects.resize(OBJECT_SIZE*scene->objects.size());
int i = 0;
map<Mesh*, float> surface_area_map;
+ Scene::MotionType need_motion = scene->need_motion();
foreach(Object *ob, scene->objects) {
Mesh *mesh = ob->mesh;
@@ -130,7 +153,6 @@ void ObjectManager::device_update_transforms(Device *device, DeviceScene *dscene
/* compute transformations */
Transform tfm = ob->tfm;
Transform itfm = transform_inverse(tfm);
- Transform ntfm = transform_transpose(itfm);
/* compute surface area. for uniform scale we can do avoid the many
transform calls and share computation for instances */
@@ -171,10 +193,38 @@ void ObjectManager::device_update_transforms(Device *device, DeviceScene *dscene
/* pack in texture */
int offset = i*OBJECT_SIZE;
- memcpy(&objects[offset], &tfm, sizeof(float4)*4);
- memcpy(&objects[offset+4], &itfm, sizeof(float4)*4);
- memcpy(&objects[offset+8], &ntfm, sizeof(float4)*4);
- objects[offset+12] = make_float4(surface_area, pass_id, 0.0f, 0.0f);
+ memcpy(&objects[offset], &tfm, sizeof(float4)*3);
+ memcpy(&objects[offset+3], &itfm, sizeof(float4)*3);
+ objects[offset+6] = make_float4(surface_area, pass_id, 0.0f, 0.0f);
+
+ if(need_motion == Scene::MOTION_PASS) {
+ /* motion transformations, is world/object space depending if mesh
+ 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;
+
+ if(!mesh->attributes.find(ATTR_STD_MOTION_PRE))
+ mtfm_pre = mtfm_pre * itfm;
+ if(!mesh->attributes.find(ATTR_STD_MOTION_POST))
+ mtfm_post = mtfm_post * itfm;
+
+ memcpy(&objects[offset+8], &mtfm_pre, sizeof(float4)*4);
+ memcpy(&objects[offset+12], &mtfm_post, sizeof(float4)*4);
+ }
+ else if(need_motion == Scene::MOTION_BLUR) {
+ if(ob->use_motion) {
+ /* decompose transformations for interpolation */
+ MotionTransform decomp;
+
+ transform_motion_decompose(&decomp, &ob->motion);
+ memcpy(&objects[offset+8], &decomp, sizeof(float4)*8);
+ }
+ else {
+ float4 no_motion = make_float4(FLT_MAX);
+ memcpy(&objects[offset+8], &no_motion, sizeof(float4));
+ }
+ }
i++;
@@ -225,6 +275,7 @@ void ObjectManager::apply_static_transforms(Scene *scene, Progress& progress)
/* counter mesh users */
map<Mesh*, int> mesh_users;
+ bool motion_blur = scene->need_motion() == Scene::MOTION_BLUR;
foreach(Object *object, scene->objects) {
map<Mesh*, int>::iterator it = mesh_users.find(object->mesh);
@@ -240,12 +291,14 @@ void ObjectManager::apply_static_transforms(Scene *scene, Progress& progress)
/* apply transforms for objects with single user meshes */
foreach(Object *object, scene->objects) {
if(mesh_users[object->mesh] == 1) {
- if(!object->mesh->transform_applied) {
- object->apply_transform();
- object->mesh->transform_applied = true;
- }
+ if(!(motion_blur && object->use_motion)) {
+ if(!object->mesh->transform_applied) {
+ object->apply_transform();
+ object->mesh->transform_applied = true;
- if(progress.get_cancel()) return;
+ if(progress.get_cancel()) return;
+ }
+ }
}
}
}