Cycles code refactor: add motion sampled normals attribute.
This commit is contained in:
@@ -601,37 +601,50 @@ void BlenderSync::sync_mesh_motion(BL::Object b_ob, Object *object, float motion
|
|||||||
if(numverts) {
|
if(numverts) {
|
||||||
/* find attributes */
|
/* find attributes */
|
||||||
Attribute *attr_mP = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
|
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;
|
bool new_attribute = false;
|
||||||
|
|
||||||
/* add new attributes if they don't exist already */
|
/* add new attributes if they don't exist already */
|
||||||
if(!attr_mP) {
|
if(!attr_mP) {
|
||||||
attr_mP = mesh->attributes.add(ATTR_STD_MOTION_VERTEX_POSITION);
|
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;
|
new_attribute = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* load vertex data from mesh */
|
/* load vertex data from mesh */
|
||||||
float3 *mP = attr_mP->data_float3() + time_index*numverts;
|
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;
|
BL::Mesh::vertices_iterator v;
|
||||||
int i = 0;
|
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());
|
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 */
|
/* in case of new attribute, we verify if there really was any motion */
|
||||||
if(new_attribute) {
|
if(new_attribute) {
|
||||||
if(i != numverts || memcmp(mP, &mesh->verts[0], sizeof(float3)*numverts) == 0) {
|
if(i != numverts || memcmp(mP, &mesh->verts[0], sizeof(float3)*numverts) == 0) {
|
||||||
/* no motion, remove attributes again */
|
/* no motion, remove attributes again */
|
||||||
mesh->attributes.remove(ATTR_STD_MOTION_VERTEX_POSITION);
|
mesh->attributes.remove(ATTR_STD_MOTION_VERTEX_POSITION);
|
||||||
|
if(attr_mN)
|
||||||
|
mesh->attributes.remove(ATTR_STD_MOTION_VERTEX_NORMAL);
|
||||||
}
|
}
|
||||||
else if(time_index > 0) {
|
else if(time_index > 0) {
|
||||||
/* motion, fill up previous steps that we might have skipped because
|
/* motion, fill up previous steps that we might have skipped because
|
||||||
* they had no motion, but we need them anyway now */
|
* they had no motion, but we need them anyway now */
|
||||||
float3 *P = &mesh->verts[0];
|
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_mP->data_float3() + step*numverts, P, sizeof(float3)*numverts);
|
||||||
|
memcpy(attr_mN->data_float3() + step*numverts, N, sizeof(float3)*numverts);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -471,6 +471,7 @@ typedef enum AttributeStandard {
|
|||||||
ATTR_STD_POSITION_UNDEFORMED,
|
ATTR_STD_POSITION_UNDEFORMED,
|
||||||
ATTR_STD_POSITION_UNDISPLACED,
|
ATTR_STD_POSITION_UNDISPLACED,
|
||||||
ATTR_STD_MOTION_VERTEX_POSITION,
|
ATTR_STD_MOTION_VERTEX_POSITION,
|
||||||
|
ATTR_STD_MOTION_VERTEX_NORMAL,
|
||||||
ATTR_STD_PARTICLE,
|
ATTR_STD_PARTICLE,
|
||||||
ATTR_STD_CURVE_INTERCEPT,
|
ATTR_STD_CURVE_INTERCEPT,
|
||||||
ATTR_STD_PTEX_FACE_ID,
|
ATTR_STD_PTEX_FACE_ID,
|
||||||
|
@@ -165,6 +165,8 @@ const char *Attribute::standard_name(AttributeStandard std)
|
|||||||
return "undisplaced";
|
return "undisplaced";
|
||||||
else if(std == ATTR_STD_MOTION_VERTEX_POSITION)
|
else if(std == ATTR_STD_MOTION_VERTEX_POSITION)
|
||||||
return "motion_P";
|
return "motion_P";
|
||||||
|
else if(std == ATTR_STD_MOTION_VERTEX_NORMAL)
|
||||||
|
return "motion_N";
|
||||||
else if(std == ATTR_STD_PARTICLE)
|
else if(std == ATTR_STD_PARTICLE)
|
||||||
return "particle";
|
return "particle";
|
||||||
else if(std == ATTR_STD_CURVE_INTERCEPT)
|
else if(std == ATTR_STD_CURVE_INTERCEPT)
|
||||||
@@ -275,6 +277,9 @@ Attribute *AttributeSet::add(AttributeStandard std, ustring name)
|
|||||||
case ATTR_STD_MOTION_VERTEX_POSITION:
|
case ATTR_STD_MOTION_VERTEX_POSITION:
|
||||||
attr = add(name, TypeDesc::TypePoint, ATTR_ELEMENT_VERTEX_MOTION);
|
attr = add(name, TypeDesc::TypePoint, ATTR_ELEMENT_VERTEX_MOTION);
|
||||||
break;
|
break;
|
||||||
|
case ATTR_STD_MOTION_VERTEX_NORMAL:
|
||||||
|
attr = add(name, TypeDesc::TypeNormal, ATTR_ELEMENT_VERTEX_MOTION);
|
||||||
|
break;
|
||||||
case ATTR_STD_PTEX_FACE_ID:
|
case ATTR_STD_PTEX_FACE_ID:
|
||||||
attr = add(name, TypeDesc::TypeFloat, ATTR_ELEMENT_FACE);
|
attr = add(name, TypeDesc::TypeFloat, ATTR_ELEMENT_FACE);
|
||||||
break;
|
break;
|
||||||
|
@@ -242,6 +242,21 @@ void Mesh::compute_bounds()
|
|||||||
bounds = bnds;
|
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()
|
void Mesh::add_face_normals()
|
||||||
{
|
{
|
||||||
/* don't compute if already there */
|
/* don't compute if already there */
|
||||||
@@ -261,17 +276,7 @@ void Mesh::add_face_normals()
|
|||||||
Triangle *triangles_ptr = &triangles[0];
|
Triangle *triangles_ptr = &triangles[0];
|
||||||
|
|
||||||
for(size_t i = 0; i < triangles_size; i++) {
|
for(size_t i = 0; i < triangles_size; i++) {
|
||||||
Triangle t = triangles_ptr[i];
|
fN[i] = compute_face_normal(triangles_ptr[i], verts_ptr);
|
||||||
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;
|
|
||||||
|
|
||||||
if(flip)
|
if(flip)
|
||||||
fN[i] = -fN[i];
|
fN[i] = -fN[i];
|
||||||
@@ -289,36 +294,69 @@ void Mesh::add_face_normals()
|
|||||||
|
|
||||||
void Mesh::add_vertex_normals()
|
void Mesh::add_vertex_normals()
|
||||||
{
|
{
|
||||||
/* don't compute if already there */
|
bool flip = transform_negative_scaled;
|
||||||
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);
|
|
||||||
|
|
||||||
float3 *fN = attr_fN->data_float3();
|
|
||||||
float3 *vN = attr_vN->data_float3();
|
|
||||||
|
|
||||||
/* compute vertex normals */
|
|
||||||
memset(vN, 0, verts.size()*sizeof(float3));
|
|
||||||
|
|
||||||
size_t verts_size = verts.size();
|
size_t verts_size = verts.size();
|
||||||
size_t triangles_size = triangles.size();
|
size_t triangles_size = triangles.size();
|
||||||
bool flip = transform_negative_scaled;
|
|
||||||
|
|
||||||
if(triangles_size) {
|
/* static vertex normals */
|
||||||
Triangle *triangles_ptr = &triangles[0];
|
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);
|
||||||
|
|
||||||
for(size_t i = 0; i < triangles_size; i++)
|
float3 *fN = attr_fN->data_float3();
|
||||||
for(size_t j = 0; j < 3; j++)
|
float3 *vN = attr_vN->data_float3();
|
||||||
vN[triangles_ptr[i].v[j]] += fN[i];
|
|
||||||
|
/* compute vertex normals */
|
||||||
|
memset(vN, 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++)
|
||||||
|
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++) {
|
/* motion vertex normals */
|
||||||
vN[i] = normalize(vN[i]);
|
Attribute *attr_mP = attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
|
||||||
if(flip)
|
Attribute *attr_mN = attributes.find(ATTR_STD_MOTION_VERTEX_NORMAL);
|
||||||
vN[i] = -vN[i];
|
|
||||||
|
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];
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -228,6 +228,8 @@ bool Scene::need_global_attribute(AttributeStandard std)
|
|||||||
return Pass::contains(film->passes, PASS_UV);
|
return Pass::contains(film->passes, PASS_UV);
|
||||||
if(std == ATTR_STD_MOTION_VERTEX_POSITION)
|
if(std == ATTR_STD_MOTION_VERTEX_POSITION)
|
||||||
return need_motion() != MOTION_NONE;
|
return need_motion() != MOTION_NONE;
|
||||||
|
if(std == ATTR_STD_MOTION_VERTEX_NORMAL)
|
||||||
|
return need_motion() == MOTION_BLUR;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user