[Bf-blender-cvs] [e2184c6] master: Cycles: add support for curve deformation motion blur.
Brecht Van Lommel
noreply at git.blender.org
Sat Mar 29 15:33:04 CET 2014
Commit: e2184c653e1f2cc7e05cf9a42a87d23ea3050eac
Author: Brecht Van Lommel
Date: Sat Mar 29 13:03:47 2014 +0100
https://developer.blender.org/rBe2184c653e1f2cc7e05cf9a42a87d23ea3050eac
Cycles: add support for curve deformation motion blur.
===================================================================
M intern/cycles/bvh/bvh.cpp
M intern/cycles/bvh/bvh_build.cpp
M intern/cycles/kernel/CMakeLists.txt
M intern/cycles/kernel/geom/geom_bvh.h
M intern/cycles/kernel/geom/geom_bvh_traversal.h
M intern/cycles/kernel/geom/geom_curve.h
A intern/cycles/kernel/geom/geom_motion_curve.h
M intern/cycles/render/mesh.cpp
M intern/cycles/render/object.cpp
===================================================================
diff --git a/intern/cycles/bvh/bvh.cpp b/intern/cycles/bvh/bvh.cpp
index 92ad3cd..770393c 100644
--- a/intern/cycles/bvh/bvh.cpp
+++ b/intern/cycles/bvh/bvh.cpp
@@ -238,7 +238,6 @@ void BVH::refit(Progress& progress)
void BVH::pack_triangle(int idx, float4 woop[3])
{
- /* create Woop triangle */
int tob = pack.prim_object[idx];
const Mesh *mesh = objects[tob]->mesh;
@@ -642,6 +641,20 @@ void RegularBVH::refit_node(int idx, bool leaf, BoundBox& bbox, uint& visibility
curve.bounds_grow(k, &mesh->curve_keys[0], bbox);
visibility |= PATH_RAY_CURVE;
+
+ /* motion curves */
+ if(mesh->use_motion_blur) {
+ Attribute *attr = mesh->curve_attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
+
+ if(attr) {
+ size_t mesh_size = mesh->curve_keys.size();
+ size_t steps = mesh->motion_steps - 1;
+ float4 *key_steps = attr->data_float4();
+
+ for (size_t i = 0; i < steps; i++)
+ curve.bounds_grow(k, key_steps + i*mesh_size, bbox);
+ }
+ }
}
else {
/* triangles */
diff --git a/intern/cycles/bvh/bvh_build.cpp b/intern/cycles/bvh/bvh_build.cpp
index f52626d..814fbf2 100644
--- a/intern/cycles/bvh/bvh_build.cpp
+++ b/intern/cycles/bvh/bvh_build.cpp
@@ -101,6 +101,11 @@ void BVHBuild::add_reference_mesh(BoundBox& root, BoundBox& center, Mesh *mesh,
}
}
+ Attribute *curve_attr_mP = NULL;
+
+ if(mesh->has_motion_blur())
+ curve_attr_mP = mesh->curve_attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
+
for(uint j = 0; j < mesh->curves.size(); j++) {
Mesh::Curve curve = mesh->curves[j];
PrimitiveType type = PRIMITIVE_CURVE;
@@ -109,6 +114,18 @@ void BVHBuild::add_reference_mesh(BoundBox& root, BoundBox& center, Mesh *mesh,
BoundBox bounds = BoundBox::empty;
curve.bounds_grow(k, &mesh->curve_keys[0], bounds);
+ /* motion curve */
+ if(curve_attr_mP) {
+ size_t mesh_size = mesh->curve_keys.size();
+ size_t steps = mesh->motion_steps - 1;
+ float4 *key_steps = curve_attr_mP->data_float4();
+
+ for (size_t i = 0; i < steps; i++)
+ curve.bounds_grow(k, key_steps + i*mesh_size, bounds);
+
+ type = PRIMITIVE_MOTION_CURVE;
+ }
+
if(bounds.valid()) {
int packed_type = PRIMITIVE_PACK_SEGMENT(type, k);
diff --git a/intern/cycles/kernel/CMakeLists.txt b/intern/cycles/kernel/CMakeLists.txt
index 7e9b0c5..5fa027b 100644
--- a/intern/cycles/kernel/CMakeLists.txt
+++ b/intern/cycles/kernel/CMakeLists.txt
@@ -113,6 +113,7 @@ set(SRC_GEOM_HEADERS
geom/geom_bvh_subsurface.h
geom/geom_bvh_traversal.h
geom/geom_curve.h
+ geom/geom_motion_curve.h
geom/geom_motion_triangle.h
geom/geom_object.h
geom/geom_triangle.h
diff --git a/intern/cycles/kernel/geom/geom_bvh.h b/intern/cycles/kernel/geom/geom_bvh.h
index 20c3c7c..73bf019 100644
--- a/intern/cycles/kernel/geom/geom_bvh.h
+++ b/intern/cycles/kernel/geom/geom_bvh.h
@@ -41,9 +41,10 @@
#endif
#include "geom_object.h"
-#include "geom_curve.h"
#include "geom_triangle.h"
#include "geom_motion_triangle.h"
+#include "geom_motion_curve.h"
+#include "geom_curve.h"
CCL_NAMESPACE_BEGIN
diff --git a/intern/cycles/kernel/geom/geom_bvh_traversal.h b/intern/cycles/kernel/geom/geom_bvh_traversal.h
index 1fd0772..e838fba 100644
--- a/intern/cycles/kernel/geom/geom_bvh_traversal.h
+++ b/intern/cycles/kernel/geom/geom_bvh_traversal.h
@@ -261,7 +261,8 @@ ccl_device bool BVH_FUNCTION_NAME
break;
}
#if FEATURE(BVH_HAIR)
- case PRIMITIVE_CURVE: {
+ case PRIMITIVE_CURVE:
+ case PRIMITIVE_MOTION_CURVE: {
#if FEATURE(BVH_HAIR_MINIMUM_WIDTH)
if(kernel_data.curve.curveflags & CURVE_KN_INTERPOLATE)
hit = bvh_cardinal_curve_intersect(kg, isect, P, idir, visibility, object, primAddr, ray->time, type, lcg_state, difl, extmax);
diff --git a/intern/cycles/kernel/geom/geom_curve.h b/intern/cycles/kernel/geom/geom_curve.h
index 484f3ae..f13f92e 100644
--- a/intern/cycles/kernel/geom/geom_curve.h
+++ b/intern/cycles/kernel/geom/geom_curve.h
@@ -103,9 +103,17 @@ ccl_device float curve_thickness(KernelGlobals *kg, ShaderData *sd)
int k0 = __float_as_int(curvedata.x) + PRIMITIVE_UNPACK_SEGMENT(sd->type);
int k1 = k0 + 1;
- float4 P1 = kernel_tex_fetch(__curve_keys, k0);
- float4 P2 = kernel_tex_fetch(__curve_keys, k1);
- r = (P2.w - P1.w) * sd->u + P1.w;
+ float4 P_curve[2];
+
+ if(sd->type & PRIMITIVE_CURVE) {
+ P_curve[0]= kernel_tex_fetch(__curve_keys, k0);
+ P_curve[1]= kernel_tex_fetch(__curve_keys, k1);
+ }
+ else {
+ motion_curve_keys(kg, sd->object, sd->prim, sd->time, k0, k1, P_curve);
+ }
+
+ r = (P_curve[1].w - P_curve[0].w) * sd->u + P_curve[0].w;
}
return r*2.0f;
@@ -226,10 +234,16 @@ ccl_device_inline bool bvh_cardinal_curve_intersect(KernelGlobals *kg, Intersect
__m128 P_curve[4];
- P_curve[0] = _mm_load_ps(&kg->__curve_keys.data[ka].x);
- P_curve[1] = _mm_load_ps(&kg->__curve_keys.data[k0].x);
- P_curve[2] = _mm_load_ps(&kg->__curve_keys.data[k1].x);
- P_curve[3] = _mm_load_ps(&kg->__curve_keys.data[kb].x);
+ if(type & PRIMITIVE_CURVE) {
+ P_curve[0] = _mm_load_ps(&kg->__curve_keys.data[ka].x);
+ P_curve[1] = _mm_load_ps(&kg->__curve_keys.data[k0].x);
+ P_curve[2] = _mm_load_ps(&kg->__curve_keys.data[k1].x);
+ P_curve[3] = _mm_load_ps(&kg->__curve_keys.data[kb].x);
+ }
+ else {
+ int fobject = (object == ~0)? kernel_tex_fetch(__prim_object, curveAddr): object;
+ motion_cardinal_curve_keys(kg, fobject, prim, time, ka, k0, k1, kb, (float4*)&P_curve);
+ }
__m128 rd_sgn = set_sign_bit<0, 1, 1, 1>(broadcast<0>(rd_ss));
__m128 mul_zxxy = _mm_mul_ps(shuffle<2, 0, 0, 1>(vdir), rd_sgn);
@@ -287,10 +301,16 @@ ccl_device_inline bool bvh_cardinal_curve_intersect(KernelGlobals *kg, Intersect
float4 P_curve[4];
- P_curve[0] = kernel_tex_fetch(__curve_keys, ka);
- P_curve[1] = kernel_tex_fetch(__curve_keys, k0);
- P_curve[2] = kernel_tex_fetch(__curve_keys, k1);
- P_curve[3] = kernel_tex_fetch(__curve_keys, kb);
+ if(type & PRIMITIVE_CURVE) {
+ P_curve[0] = kernel_tex_fetch(__curve_keys, ka);
+ P_curve[1] = kernel_tex_fetch(__curve_keys, k0);
+ P_curve[2] = kernel_tex_fetch(__curve_keys, k1);
+ P_curve[3] = kernel_tex_fetch(__curve_keys, kb);
+ }
+ else {
+ int fobject = (object == ~0)? kernel_tex_fetch(__prim_object, curveAddr): object;
+ motion_cardinal_curve_keys(kg, fobject, prim, time, ka, k0, k1, kb, P_curve);
+ }
float3 p0 = transform_point(&htfm, float4_to_float3(P_curve[0]) - P);
float3 p1 = transform_point(&htfm, float4_to_float3(P_curve[1]) - P);
@@ -593,8 +613,14 @@ ccl_device_inline bool bvh_curve_intersect(KernelGlobals *kg, Intersection *isec
#ifndef __KERNEL_SSE2__
float4 P_curve[2];
- P_curve[0]= kernel_tex_fetch(__curve_keys, k0);
- P_curve[1]= kernel_tex_fetch(__curve_keys, k1);
+ if(type & PRIMITIVE_CURVE) {
+ P_curve[0]= kernel_tex_fetch(__curve_keys, k0);
+ P_curve[1]= kernel_tex_fetch(__curve_keys, k1);
+ }
+ else {
+ int fobject = (object == ~0)? kernel_tex_fetch(__prim_object, curveAddr): object;
+ motion_curve_keys(kg, fobject, prim, time, k0, k1, P_curve);
+ }
float or1 = P_curve[0].w;
float or2 = P_curve[1].w;
@@ -620,14 +646,23 @@ ccl_device_inline bool bvh_curve_intersect(KernelGlobals *kg, Intersection *isec
float sphere_b_tmp = dot3(dir, sphere_dif1);
float3 sphere_dif2 = sphere_dif1 - sphere_b_tmp * dir;
#else
- const __m128 p1 = _mm_load_ps(&kg->__curve_keys.data[k0].x);
- const __m128 p2 = _mm_load_ps(&kg->__curve_keys.data[k1].x);
- const __m128 or12 = shuffle<3, 3, 3, 3>(p1, p2);
+ __m128 P_curve[2];
+
+ if(type & PRIMITIVE_CURVE) {
+ P_curve[0] = _mm_load_ps(&kg->__curve_keys.data[k0].x);
+ P_curve[1] = _mm_load_ps(&kg->__curve_keys.data[k1].x);
+ }
+ else {
+ int fobject = (object == ~0)? kernel_tex_fetch(__prim_object, curveAddr): object;
+ motion_curve_keys(kg, fobject, prim, time, k0, k1, (float4*)&P_curve);
+ }
+
+ const __m128 or12 = shuffle<3, 3, 3, 3>(P_curve[0], P_curve[1]);
__m128 r12 = or12;
const __m128 vP = load_m128(P);
- const __m128 dif = _mm_sub_ps(vP, p1);
- const __m128 dif_second = _mm_sub_ps(vP, p2);
+ const __m128 dif = _mm_sub_ps(vP, P_curve[0]);
+ const __m128 dif_second = _mm_sub_ps(vP, P_curve[1]);
if(difl != 0.0f) {
const __m128 len1_sq = len3_squared_splat(dif);
const __m128 len2_sq = len3_squared_splat(dif_second);
@@ -639,7 +674,7 @@ ccl_device_inline bool bvh_curve_intersect(KernelGlobals *kg, Intersection *isec
float r1 = _mm_cvtss_f32(r12), r2 = _mm_cvtss_f32(broadcast<2>(r12));
const __m128 dir = _mm_div_ps(_mm_set1_ps(1.0f), load_m128(idir));
- const __m128 p21_diff = _mm_sub_ps(p2, p1);
+ const __m128 p21_diff = _mm_sub_ps(P_curve[1], P_curve[0]);
const __m128 sphere_dif1 = _mm_mul_ps(_mm_add_ps(dif, dif_second), _mm_set1_ps(0.5f));
const __m128 sphere_b_tmp = dot3_splat(dir, sphere_dif1);
const __m128 sphere_dif2 = fnma(sphere_b_tmp, dir, sphere_dif1);
@@ -854,10 +889,15 @@ ccl_device_inline float3 bvh_curve_refine(KernelGlobals *kg, ShaderData *sd, con
float4 P_curve[4];
- P_curve[0] = kernel_tex_fetch(__curve_keys, ka);
- P_curve[1] = kernel_tex_fetch(__curve_keys, k0);
- P_curve[2] = kernel_tex_fetch(__curve_keys, k1);
- P_curve[3] = kernel_tex_fetch(__curve_keys, kb);
+ if(sd->type & PRIMITIVE_CURVE) {
+ P_curve[0] = kernel_tex_fetch(__curve_keys, ka);
+ P_curve[1] = kernel_tex_fetch(__curve_keys, k0);
+ P_curve[2] = kernel_tex_fetch(__curve_keys, k1);
+ P_curve[3] = kernel_tex_fetch(__curve_keys, kb);
+ }
+ else {
+ motion_cardinal_curve_keys(kg, sd->object, sd->prim, sd->time, ka, k0, k1, kb, P_curve);
+ }
float l = 1.0f;
tg = normalize_len(float4_to_float3(P_curve[2] - P_curve[1]), &l);
@@ -893,8 +933,13 @@ ccl_device_inline float3 bvh_curve_refine(KernelGlobals *kg, ShaderData *sd, con
else {
float4 P_curve[2];
- P_curve[0]= kernel_tex_fetch(__curve_keys, k0);
- P_curve[1]= kernel_tex_fetch(__curve_keys, k1);
+ if(sd->type & PRIMITIVE_CURVE) {
+ P_curve[0]= kernel_tex_fetch(__curve_keys, k0);
+ P_curve[1]= kernel_tex_fetch(__curve_keys, k1);
+ }
+ else {
+ motion_curve_keys(kg, sd->object, sd->prim, sd->time, k0, k1, P_curve);
+ }
float l = 1.0f;
tg = norma
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list