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:
authorBrecht Van Lommel <brechtvanlommel@gmail.com>2014-03-29 16:03:46 +0400
committerBrecht Van Lommel <brechtvanlommel@gmail.com>2014-03-29 16:03:46 +0400
commit8f33538fabe9b2485478b7ce0167c15396bdb355 (patch)
tree2ad971354ba58047cfbab6d9c23749a475d42df1 /intern/cycles
parent99f59930885ed69890967f8864a3aa0626249d86 (diff)
Cycles code refactor: add motion sampled normals attribute.
Diffstat (limited to 'intern/cycles')
-rw-r--r--intern/cycles/blender/blender_mesh.cpp17
-rw-r--r--intern/cycles/kernel/kernel_types.h1
-rw-r--r--intern/cycles/render/attribute.cpp5
-rw-r--r--intern/cycles/render/mesh.cpp106
-rw-r--r--intern/cycles/render/scene.cpp2
5 files changed, 95 insertions, 36 deletions
diff --git a/intern/cycles/blender/blender_mesh.cpp b/intern/cycles/blender/blender_mesh.cpp
index 9e11cc1ae0b..ed19fb2672b 100644
--- a/intern/cycles/blender/blender_mesh.cpp
+++ b/intern/cycles/blender/blender_mesh.cpp
@@ -601,37 +601,50 @@ void BlenderSync::sync_mesh_motion(BL::Object b_ob, Object *object, float motion
if(numverts) {
/* find attributes */
Attribute *attr_mP = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
+ Attribute *attr_mN = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_NORMAL);
+ Attribute *attr_N = mesh->attributes.find(ATTR_STD_VERTEX_NORMAL);
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);
+ if(attr_N)
+ attr_mN = mesh->attributes.add(ATTR_STD_MOTION_VERTEX_NORMAL);
new_attribute = true;
}
/* load vertex data from mesh */
float3 *mP = attr_mP->data_float3() + time_index*numverts;
+ float3 *mN = (attr_mN)? attr_mN->data_float3() + time_index*numverts: NULL;
BL::Mesh::vertices_iterator v;
int i = 0;
- for(b_mesh.vertices.begin(v); v != b_mesh.vertices.end() && i < numverts; ++v, ++i)
+ for(b_mesh.vertices.begin(v); v != b_mesh.vertices.end() && i < numverts; ++v, ++i) {
mP[i] = get_float3(v->co());
+ if(mN)
+ mN[i] = get_float3(v->normal());
+ }
/* 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);
+ if(attr_mN)
+ mesh->attributes.remove(ATTR_STD_MOTION_VERTEX_NORMAL);
}
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];
+ float3 *N = (attr_N)? attr_N->data_float3(): NULL;
- for(int step = 0; step < time_index; step++)
+ for(int step = 0; step < time_index; step++) {
memcpy(attr_mP->data_float3() + step*numverts, P, sizeof(float3)*numverts);
+ memcpy(attr_mN->data_float3() + step*numverts, N, sizeof(float3)*numverts);
+ }
}
}
}
diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h
index f708f019912..2590717d378 100644
--- a/intern/cycles/kernel/kernel_types.h
+++ b/intern/cycles/kernel/kernel_types.h
@@ -471,6 +471,7 @@ typedef enum AttributeStandard {
ATTR_STD_POSITION_UNDEFORMED,
ATTR_STD_POSITION_UNDISPLACED,
ATTR_STD_MOTION_VERTEX_POSITION,
+ ATTR_STD_MOTION_VERTEX_NORMAL,
ATTR_STD_PARTICLE,
ATTR_STD_CURVE_INTERCEPT,
ATTR_STD_PTEX_FACE_ID,
diff --git a/intern/cycles/render/attribute.cpp b/intern/cycles/render/attribute.cpp
index e730cab0c60..f524a9fa3bc 100644
--- a/intern/cycles/render/attribute.cpp
+++ b/intern/cycles/render/attribute.cpp
@@ -165,6 +165,8 @@ const char *Attribute::standard_name(AttributeStandard std)
return "undisplaced";
else if(std == ATTR_STD_MOTION_VERTEX_POSITION)
return "motion_P";
+ else if(std == ATTR_STD_MOTION_VERTEX_NORMAL)
+ return "motion_N";
else if(std == ATTR_STD_PARTICLE)
return "particle";
else if(std == ATTR_STD_CURVE_INTERCEPT)
@@ -275,6 +277,9 @@ Attribute *AttributeSet::add(AttributeStandard std, ustring name)
case ATTR_STD_MOTION_VERTEX_POSITION:
attr = add(name, TypeDesc::TypePoint, ATTR_ELEMENT_VERTEX_MOTION);
break;
+ case ATTR_STD_MOTION_VERTEX_NORMAL:
+ attr = add(name, TypeDesc::TypeNormal, ATTR_ELEMENT_VERTEX_MOTION);
+ break;
case ATTR_STD_PTEX_FACE_ID:
attr = add(name, TypeDesc::TypeFloat, ATTR_ELEMENT_FACE);
break;
diff --git a/intern/cycles/render/mesh.cpp b/intern/cycles/render/mesh.cpp
index 0d09328119c..8e2cc97eba0 100644
--- a/intern/cycles/render/mesh.cpp
+++ b/intern/cycles/render/mesh.cpp
@@ -242,6 +242,21 @@ void Mesh::compute_bounds()
bounds = bnds;
}
+static float3 compute_face_normal(const Mesh::Triangle& t, float3 *verts)
+{
+ float3 v0 = verts[t.v[0]];
+ float3 v1 = verts[t.v[1]];
+ float3 v2 = verts[t.v[2]];
+
+ float3 norm = cross(v1 - v0, v2 - v0);
+ float normlen = len(norm);
+
+ if(normlen == 0.0f)
+ return make_float3(0.0f, 0.0f, 0.0f);
+
+ return norm / normlen;
+}
+
void Mesh::add_face_normals()
{
/* don't compute if already there */
@@ -261,17 +276,7 @@ void Mesh::add_face_normals()
Triangle *triangles_ptr = &triangles[0];
for(size_t i = 0; i < triangles_size; i++) {
- Triangle t = triangles_ptr[i];
- float3 v0 = verts_ptr[t.v[0]];
- float3 v1 = verts_ptr[t.v[1]];
- float3 v2 = verts_ptr[t.v[2]];
-
- float3 norm = cross(v1 - v0, v2 - v0);
- float normlen = len(norm);
- if(normlen == 0.0f)
- fN[i] = make_float3(0.0f, 0.0f, 0.0f);
- else
- fN[i] = norm / normlen;
+ fN[i] = compute_face_normal(triangles_ptr[i], verts_ptr);
if(flip)
fN[i] = -fN[i];
@@ -289,36 +294,69 @@ void Mesh::add_face_normals()
void Mesh::add_vertex_normals()
{
- /* don't compute if already there */
- if(attributes.find(ATTR_STD_VERTEX_NORMAL))
- return;
-
- /* get attributes */
- Attribute *attr_fN = attributes.find(ATTR_STD_FACE_NORMAL);
- Attribute *attr_vN = attributes.add(ATTR_STD_VERTEX_NORMAL);
+ bool flip = transform_negative_scaled;
+ size_t verts_size = verts.size();
+ size_t triangles_size = triangles.size();
- float3 *fN = attr_fN->data_float3();
- float3 *vN = attr_vN->data_float3();
+ /* static vertex normals */
+ if(!attributes.find(ATTR_STD_VERTEX_NORMAL)) {
+ /* get attributes */
+ Attribute *attr_fN = attributes.find(ATTR_STD_FACE_NORMAL);
+ Attribute *attr_vN = attributes.add(ATTR_STD_VERTEX_NORMAL);
- /* compute vertex normals */
- memset(vN, 0, verts.size()*sizeof(float3));
+ float3 *fN = attr_fN->data_float3();
+ float3 *vN = attr_vN->data_float3();
- size_t verts_size = verts.size();
- size_t triangles_size = triangles.size();
- bool flip = transform_negative_scaled;
+ /* compute vertex normals */
+ memset(vN, 0, verts.size()*sizeof(float3));
- if(triangles_size) {
- Triangle *triangles_ptr = &triangles[0];
+ if(triangles_size) {
+ Triangle *triangles_ptr = &triangles[0];
- for(size_t i = 0; i < triangles_size; i++)
- for(size_t j = 0; j < 3; j++)
- vN[triangles_ptr[i].v[j]] += fN[i];
+ for(size_t i = 0; i < triangles_size; i++)
+ for(size_t j = 0; j < 3; j++)
+ vN[triangles_ptr[i].v[j]] += fN[i];
+ }
+
+ for(size_t i = 0; i < verts_size; i++) {
+ vN[i] = normalize(vN[i]);
+ if(flip)
+ vN[i] = -vN[i];
+ }
}
- for(size_t i = 0; i < verts_size; i++) {
- vN[i] = normalize(vN[i]);
- if(flip)
- vN[i] = -vN[i];
+ /* motion vertex normals */
+ Attribute *attr_mP = attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
+ Attribute *attr_mN = attributes.find(ATTR_STD_MOTION_VERTEX_NORMAL);
+
+ if(false && !attr_mN) {
+ /* create attribute */
+ attr_mN = attributes.add(ATTR_STD_MOTION_VERTEX_NORMAL);
+
+ for(int step = 0; step < motion_steps - 1; step++) {
+ float3 *mP = attr_mP->data_float3() + step*verts.size();
+ float3 *mN = attr_mN->data_float3() + step*verts.size();
+
+ /* compute */
+ memset(mN, 0, verts.size()*sizeof(float3));
+
+ if(triangles_size) {
+ Triangle *triangles_ptr = &triangles[0];
+
+ for(size_t i = 0; i < triangles_size; i++) {
+ for(size_t j = 0; j < 3; j++) {
+ float3 fN = compute_face_normal(triangles_ptr[i], mP);
+ mN[triangles_ptr[i].v[j]] += fN;
+ }
+ }
+ }
+
+ for(size_t i = 0; i < verts_size; i++) {
+ mN[i] = normalize(mN[i]);
+ if(flip)
+ mN[i] = -mN[i];
+ }
+ }
}
}
diff --git a/intern/cycles/render/scene.cpp b/intern/cycles/render/scene.cpp
index f7d2f2d0a8e..2ed4efe7f2b 100644
--- a/intern/cycles/render/scene.cpp
+++ b/intern/cycles/render/scene.cpp
@@ -228,6 +228,8 @@ bool Scene::need_global_attribute(AttributeStandard std)
return Pass::contains(film->passes, PASS_UV);
if(std == ATTR_STD_MOTION_VERTEX_POSITION)
return need_motion() != MOTION_NONE;
+ if(std == ATTR_STD_MOTION_VERTEX_NORMAL)
+ return need_motion() == MOTION_BLUR;
return false;
}