diff options
author | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2013-01-03 16:09:09 +0400 |
---|---|---|
committer | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2013-01-03 16:09:09 +0400 |
commit | bf25f1ea96d01b513907cf3067e8e2dd3c7e41b4 (patch) | |
tree | 822c28fa6ecf5e08c051e5eb7a05f6bc6e2e8742 /intern/cycles/render | |
parent | 57cf48e7c6fd04f864072c21433a822907774f78 (diff) |
Cycles Hair: refactoring to store curves with the index of the first key and the
number of keys in the curve, rather than curve segments with the indices of two
keys. ShaderData.segment now stores the segment number in the curve.
Diffstat (limited to 'intern/cycles/render')
-rw-r--r-- | intern/cycles/render/attribute.cpp | 10 | ||||
-rw-r--r-- | intern/cycles/render/light.cpp | 73 | ||||
-rw-r--r-- | intern/cycles/render/mesh.cpp | 99 | ||||
-rw-r--r-- | intern/cycles/render/mesh.h | 17 | ||||
-rw-r--r-- | intern/cycles/render/object.cpp | 41 | ||||
-rw-r--r-- | intern/cycles/render/scene.h | 4 |
6 files changed, 131 insertions, 113 deletions
diff --git a/intern/cycles/render/attribute.cpp b/intern/cycles/render/attribute.cpp index 758e4e5e820..b6f6ba47fe8 100644 --- a/intern/cycles/render/attribute.cpp +++ b/intern/cycles/render/attribute.cpp @@ -80,7 +80,7 @@ size_t Attribute::element_size(int numverts, int numtris, int numcurves, int num return numtris; else if(element == ATTR_ELEMENT_CORNER) return numtris*3; - else if(element == ATTR_ELEMENT_CURVE_SEGMENT) + else if(element == ATTR_ELEMENT_CURVE) return numcurves; else if(element == ATTR_ELEMENT_CURVE_KEY) return numkeys; @@ -176,7 +176,7 @@ Attribute *AttributeSet::add(ustring name, TypeDesc type, AttributeElement eleme if(triangle_mesh) attr->reserve(triangle_mesh->verts.size(), triangle_mesh->triangles.size(), 0, 0); if(curve_mesh) - attr->reserve(0, 0, curve_mesh->curve_segments.size(), curve_mesh->curve_keys.size()); + attr->reserve(0, 0, curve_mesh->curves.size(), curve_mesh->curve_keys.size()); return attr; } @@ -239,9 +239,9 @@ Attribute *AttributeSet::add(AttributeStandard std, ustring name) } else if(curve_mesh) { if(std == ATTR_STD_UV) - attr = add(name, TypeDesc::TypePoint, ATTR_ELEMENT_CURVE_SEGMENT); + attr = add(name, TypeDesc::TypePoint, ATTR_ELEMENT_CURVE); else if(std == ATTR_STD_GENERATED) - attr = add(name, TypeDesc::TypePoint, ATTR_ELEMENT_CURVE_SEGMENT); + attr = add(name, TypeDesc::TypePoint, ATTR_ELEMENT_CURVE); else if(std == ATTR_STD_MOTION_PRE) attr = add(name, TypeDesc::TypePoint, ATTR_ELEMENT_CURVE_KEY); else if(std == ATTR_STD_MOTION_POST) @@ -298,7 +298,7 @@ void AttributeSet::reserve() if(triangle_mesh) attr.reserve(triangle_mesh->verts.size(), triangle_mesh->triangles.size(), 0, 0); if(curve_mesh) - attr.reserve(0, 0, curve_mesh->curve_segments.size(), curve_mesh->curve_keys.size()); + attr.reserve(0, 0, curve_mesh->curves.size(), curve_mesh->curve_keys.size()); } } diff --git a/intern/cycles/render/light.cpp b/intern/cycles/render/light.cpp index cab6008dd7c..c8e3e94ec98 100644 --- a/intern/cycles/render/light.cpp +++ b/intern/cycles/render/light.cpp @@ -171,13 +171,14 @@ void LightManager::device_update_distribution(Device *device, DeviceScene *dscen num_triangles++; } - /* disabled for strands*/ - /*for(size_t i = 0; i < mesh->curve_segments.size(); i++) { - * Shader *shader = scene->shaders[mesh->curve_segments[i].shader]; - * - * if(shader->sample_as_light && shader->has_surface_emission) - * num_curve_segments++; - }*/ + /* disabled for curves */ +#if 0 + foreach(Mesh::Curve& curve, mesh->curves) { + Shader *shader = scene->shaders[curve.shader]; + + if(shader->sample_as_light && shader->has_surface_emission) + num_curve_segments += curve.num_segments(); +#endif } } @@ -225,7 +226,7 @@ void LightManager::device_update_distribution(Device *device, DeviceScene *dscen if(shader->sample_as_light && shader->has_surface_emission) { distribution[offset].x = totarea; distribution[offset].y = __int_as_float(i + mesh->tri_offset); - distribution[offset].z = 1.0f; + distribution[offset].z = __int_as_float(~0); distribution[offset].w = __int_as_float(object_id); offset++; @@ -245,30 +246,38 @@ void LightManager::device_update_distribution(Device *device, DeviceScene *dscen } /*sample as light disabled for strands*/ - /*for(size_t i = 0; i < mesh->curve_segments.size(); i++) { - * Shader *shader = scene->shaders[mesh->curve_segments[i].shader]; - * - * if(shader->sample_as_light && shader->has_surface_emission) { - * distribution[offset].x = totarea; - * distribution[offset].y = __int_as_float(i + mesh->curveseg_offset); - * distribution[offset].z = 0.0f; - * distribution[offset].w = __int_as_float(object_id); - * offset++; - * - * Mesh::CurveSeg s = mesh->curve_segments[i]; - * float3 p1 = mesh->curve_keys[s.v[0]].loc; - * float r1 = mesh->curve_keys[s.v[0]].radius; - * float3 p2 = mesh->curve_keys[s.v[1]].loc; - * float r2 = mesh->curve_keys[s.v[1]].radius; - * - * if(!transform_applied) { - * p1 = transform_point(&tfm, p1); - * p2 = transform_point(&tfm, p2); - * } - * - * totarea += M_PI_F * (r1 + r2) * len(p1 - p2); - * } - }*/ +#if 0 + size_t i = 0; + + foreach(Mesh::Curve& curve, mesh->curves) { + Shader *shader = scene->shaders[curve.shader]; + int first_key = curve.first_key; + + if(shader->sample_as_light && shader->has_surface_emission) { + for(int j = 0; j < curve.num_segments(); j++) { + distribution[offset].x = totarea; + distribution[offset].y = __int_as_float(i + mesh->curve_offset); // XXX fix kernel code + distribution[offset].z = __int_as_float(j); + distribution[offset].w = __int_as_float(object_id); + offset++; + + float3 p1 = mesh->curve_keys[first_key + j].loc; + float r1 = mesh->curve_keys[first_key + j].radius; + float3 p2 = mesh->curve_keys[first_key + j + 1].loc; + float r2 = mesh->curve_keys[first_key + j + 1].radius; + + if(!transform_applied) { + p1 = transform_point(&tfm, p1); + p2 = transform_point(&tfm, p2); + } + + totarea += M_PI_F * (r1 + r2) * len(p1 - p2); + } + } + + i++; + } +#endif } if(progress.get_cancel()) return; diff --git a/intern/cycles/render/mesh.cpp b/intern/cycles/render/mesh.cpp index 53cae53ef69..d4619dcff55 100644 --- a/intern/cycles/render/mesh.cpp +++ b/intern/cycles/render/mesh.cpp @@ -51,7 +51,7 @@ Mesh::Mesh() tri_offset = 0; vert_offset = 0; - curveseg_offset = 0; + curve_offset = 0; curvekey_offset = 0; attributes.triangle_mesh = this; @@ -71,7 +71,7 @@ void Mesh::reserve(int numverts, int numtris, int numcurves, int numcurvekeys) shader.resize(numtris); smooth.resize(numtris); curve_keys.resize(numcurvekeys); - curve_segments.resize(numcurves); + curves.resize(numcurves); attributes.reserve(); curve_attributes.reserve(); @@ -86,7 +86,7 @@ void Mesh::clear() smooth.clear(); curve_keys.clear(); - curve_segments.clear(); + curves.clear(); attributes.clear(); curve_attributes.clear(); @@ -98,34 +98,33 @@ void Mesh::clear() void Mesh::add_triangle(int v0, int v1, int v2, int shader_, bool smooth_) { - Triangle t; - t.v[0] = v0; - t.v[1] = v1; - t.v[2] = v2; + Triangle tri; + tri.v[0] = v0; + tri.v[1] = v1; + tri.v[2] = v2; - triangles.push_back(t); + triangles.push_back(tri); shader.push_back(shader_); smooth.push_back(smooth_); } void Mesh::add_curve_key(float3 co, float radius) { - CurveKey ck; - ck.co = co; - ck.radius = radius; + CurveKey key; + key.co = co; + key.radius = radius; - curve_keys.push_back(ck); + curve_keys.push_back(key); } -void Mesh::add_curve_segment(int v0, int v1, int shader, int curveid) +void Mesh::add_curve(int first_key, int num_keys, int shader) { - CurveSegment s; - s.v[0] = v0; - s.v[1] = v1; - s.shader = shader; - s.curve = curveid; + Curve curve; + curve.first_key = first_key; + curve.num_keys = num_keys; + curve.shader = shader; - curve_segments.push_back(s); + curves.push_back(curve); } void Mesh::compute_bounds() @@ -284,7 +283,7 @@ void Mesh::pack_verts(float4 *tri_verts, float4 *tri_vindex, size_t vert_offset) } } -void Mesh::pack_curves(Scene *scene, float4 *curve_key_co, float4 *curve_seg_keys, size_t curvekey_offset) +void Mesh::pack_curves(Scene *scene, float4 *curve_key_co, float4 *curve_data, size_t curvekey_offset) { size_t curve_keys_size = curve_keys.size(); CurveKey *keys_ptr = NULL; @@ -302,25 +301,21 @@ void Mesh::pack_curves(Scene *scene, float4 *curve_key_co, float4 *curve_seg_key } /* pack curve segments */ - size_t curve_seg_num = curve_segments.size(); + size_t curve_num = curves.size(); - if(curve_seg_num) { - CurveSegment *curve_ptr = &curve_segments[0]; + if(curve_num) { + Curve *curve_ptr = &curves[0]; int shader_id = 0; - for(size_t i = 0; i < curve_seg_num; i++) { - CurveSegment s = curve_ptr[i]; - shader_id = scene->shader_manager->get_shader_id(s.shader, this, false); + for(size_t i = 0; i < curve_num; i++) { + Curve curve = curve_ptr[i]; + shader_id = scene->shader_manager->get_shader_id(curve.shader, this, false); - float3 p1 = keys_ptr[s.v[0]].co; - float3 p2 = keys_ptr[s.v[1]].co; - float length = len(p2 - p1); - - curve_seg_keys[i] = make_float4( - __int_as_float(s.v[0] + curvekey_offset), - __int_as_float(s.v[1] + curvekey_offset), + curve_data[i] = make_float4( + __int_as_float(curve.first_key + curvekey_offset), + __int_as_float(curve.num_keys), __int_as_float(shader_id), - length); + 0.0f); } } } @@ -541,7 +536,7 @@ void MeshManager::update_svm_attributes(Device *device, DeviceScene *dscene, Sce index++; - if(mesh->curve_segments.size()) { + if(mesh->curves.size()) { attr_map[index].x = id; attr_map[index].y = req.curve_element; attr_map[index].z = as_uint(req.curve_offset); @@ -588,7 +583,7 @@ static void update_attribute_element_offset(Mesh *mesh, vector<float>& attr_floa size_t size = mattr->element_size( mesh->verts.size(), mesh->triangles.size(), - mesh->curve_segments.size(), + mesh->curves.size(), mesh->curve_keys.size()); if(mattr->type == TypeDesc::TypeFloat) { @@ -618,8 +613,8 @@ static void update_attribute_element_offset(Mesh *mesh, vector<float>& attr_floa offset -= mesh->tri_offset; else if(element == ATTR_ELEMENT_CORNER) offset -= 3*mesh->tri_offset; - else if(element == ATTR_ELEMENT_CURVE_SEGMENT) - offset -= mesh->curveseg_offset; + else if(element == ATTR_ELEMENT_CURVE) + offset -= mesh->curve_offset; else if(element == ATTR_ELEMENT_CURVE_KEY) offset -= mesh->curvekey_offset; } @@ -713,20 +708,20 @@ void MeshManager::device_update_mesh(Device *device, DeviceScene *dscene, Scene size_t tri_size = 0; size_t curve_key_size = 0; - size_t curve_seg_keys = 0; + size_t curve_size = 0; foreach(Mesh *mesh, scene->meshes) { mesh->vert_offset = vert_size; mesh->tri_offset = tri_size; mesh->curvekey_offset = curve_key_size; - mesh->curveseg_offset = curve_seg_keys; + mesh->curve_offset = curve_size; vert_size += mesh->verts.size(); tri_size += mesh->triangles.size(); curve_key_size += mesh->curve_keys.size(); - curve_seg_keys += mesh->curve_segments.size(); + curve_size += mesh->curves.size(); } if(tri_size != 0) { @@ -754,19 +749,19 @@ void MeshManager::device_update_mesh(Device *device, DeviceScene *dscene, Scene device->tex_alloc("__tri_vindex", dscene->tri_vindex); } - if(curve_seg_keys != 0) { + if(curve_size != 0) { progress.set_status("Updating Mesh", "Copying Strands to device"); float4 *curve_keys = dscene->curve_keys.resize(curve_key_size); - float4 *curve_segments = dscene->curve_segments.resize(curve_seg_keys); + float4 *curves = dscene->curves.resize(curve_size); foreach(Mesh *mesh, scene->meshes) { - mesh->pack_curves(scene, &curve_keys[mesh->curvekey_offset], &curve_segments[mesh->curveseg_offset], mesh->curvekey_offset); + mesh->pack_curves(scene, &curve_keys[mesh->curvekey_offset], &curves[mesh->curve_offset], mesh->curvekey_offset); if(progress.get_cancel()) return; } device->tex_alloc("__curve_keys", dscene->curve_keys); - device->tex_alloc("__curve_segments", dscene->curve_segments); + device->tex_alloc("__curves", dscene->curves); } } @@ -804,9 +799,9 @@ void MeshManager::device_update_bvh(Device *device, DeviceScene *dscene, Scene * dscene->tri_woop.reference(&pack.tri_woop[0], pack.tri_woop.size()); device->tex_alloc("__tri_woop", dscene->tri_woop); } - if(pack.prim_type.size()) { - dscene->prim_type.reference((uint*)&pack.prim_type[0], pack.prim_type.size()); - device->tex_alloc("__prim_type", dscene->prim_type); + if(pack.prim_segment.size()) { + dscene->prim_segment.reference((uint*)&pack.prim_segment[0], pack.prim_segment.size()); + device->tex_alloc("__prim_segment", dscene->prim_segment); } if(pack.prim_visibility.size()) { dscene->prim_visibility.reference((uint*)&pack.prim_visibility[0], pack.prim_visibility.size()); @@ -917,7 +912,7 @@ void MeshManager::device_free(Device *device, DeviceScene *dscene) device->tex_free(dscene->bvh_nodes); device->tex_free(dscene->object_node); device->tex_free(dscene->tri_woop); - device->tex_free(dscene->prim_type); + device->tex_free(dscene->prim_segment); device->tex_free(dscene->prim_visibility); device->tex_free(dscene->prim_index); device->tex_free(dscene->prim_object); @@ -925,7 +920,7 @@ void MeshManager::device_free(Device *device, DeviceScene *dscene) device->tex_free(dscene->tri_vnormal); device->tex_free(dscene->tri_vindex); device->tex_free(dscene->tri_verts); - device->tex_free(dscene->curve_segments); + device->tex_free(dscene->curves); device->tex_free(dscene->curve_keys); device->tex_free(dscene->attributes_map); device->tex_free(dscene->attributes_float); @@ -934,7 +929,7 @@ void MeshManager::device_free(Device *device, DeviceScene *dscene) dscene->bvh_nodes.clear(); dscene->object_node.clear(); dscene->tri_woop.clear(); - dscene->prim_type.clear(); + dscene->prim_segment.clear(); dscene->prim_visibility.clear(); dscene->prim_index.clear(); dscene->prim_object.clear(); @@ -942,7 +937,7 @@ void MeshManager::device_free(Device *device, DeviceScene *dscene) dscene->tri_vnormal.clear(); dscene->tri_vindex.clear(); dscene->tri_verts.clear(); - dscene->curve_segments.clear(); + dscene->curves.clear(); dscene->curve_keys.clear(); dscene->attributes_map.clear(); dscene->attributes_float.clear(); diff --git a/intern/cycles/render/mesh.h b/intern/cycles/render/mesh.h index ca8c755671f..b83752ad8df 100644 --- a/intern/cycles/render/mesh.h +++ b/intern/cycles/render/mesh.h @@ -51,10 +51,13 @@ public: }; /* Mesh Curve */ - struct CurveSegment { - int v[2]; + struct Curve { + int first_key; + int num_keys; uint shader; - int curve; + uint pad; + + int num_segments() { return num_keys - 1; } }; struct CurveKey { @@ -78,7 +81,7 @@ public: vector<bool> smooth; vector<CurveKey> curve_keys; - vector<CurveSegment> curve_segments; + vector<Curve> curves; vector<uint> used_shaders; AttributeSet attributes; @@ -98,7 +101,7 @@ public: size_t tri_offset; size_t vert_offset; - size_t curveseg_offset; + size_t curve_offset; size_t curvekey_offset; /* Functions */ @@ -109,7 +112,7 @@ public: void clear(); void add_triangle(int v0, int v1, int v2, int shader, bool smooth); void add_curve_key(float3 loc, float radius); - void add_curve_segment(int v0, int v1, int shader, int curveid); + void add_curve(int first_key, int num_keys, int shader); void compute_bounds(); void add_face_normals(); @@ -117,7 +120,7 @@ public: void pack_normals(Scene *scene, float4 *normal, float4 *vnormal); void pack_verts(float4 *tri_verts, float4 *tri_vindex, size_t vert_offset); - void pack_curves(Scene *scene, float4 *curve_key_co, float4 *curve_seg_keys, size_t curvekey_offset); + void pack_curves(Scene *scene, float4 *curve_key_co, float4 *curve_data, size_t curvekey_offset); void compute_bvh(SceneParams *params, Progress *progress, int n, int total); bool need_attribute(Scene *scene, AttributeStandard std); diff --git a/intern/cycles/render/object.cpp b/intern/cycles/render/object.cpp index 4862b47c342..a89f8afd251 100644 --- a/intern/cycles/render/object.cpp +++ b/intern/cycles/render/object.cpp @@ -203,14 +203,18 @@ void ObjectManager::device_update_transforms(Device *device, DeviceScene *dscene surface_area += triangle_area(p1, p2, p3); } - foreach(Mesh::CurveSegment& t, mesh->curve_segments) { - float3 p1 = mesh->curve_keys[t.v[0]].co; - float r1 = mesh->curve_keys[t.v[0]].radius; - float3 p2 = mesh->curve_keys[t.v[1]].co; - float r2 = mesh->curve_keys[t.v[1]].radius; - - /* currently ignores segment overlaps*/ - surface_area += M_PI_F *(r1 + r2) * len(p1 - p2); + foreach(Mesh::Curve& curve, mesh->curves) { + int first_key = curve.first_key; + + for(int i = 0; i < curve.num_segments(); i++) { + float3 p1 = mesh->curve_keys[first_key + i].co; + float r1 = mesh->curve_keys[first_key + i].radius; + float3 p2 = mesh->curve_keys[first_key + i + 1].co; + float r2 = mesh->curve_keys[first_key + i + 1].radius; + + /* currently ignores segment overlaps*/ + surface_area += M_PI_F *(r1 + r2) * len(p1 - p2); + } } surface_area_map[mesh] = surface_area; @@ -229,14 +233,21 @@ void ObjectManager::device_update_transforms(Device *device, DeviceScene *dscene surface_area += triangle_area(p1, p2, p3); } - foreach(Mesh::CurveSegment& t, mesh->curve_segments) { - float3 p1 = mesh->curve_keys[t.v[0]].co; - float r1 = mesh->curve_keys[t.v[0]].radius; - float3 p2 = mesh->curve_keys[t.v[1]].co; - float r2 = mesh->curve_keys[t.v[1]].radius; + foreach(Mesh::Curve& curve, mesh->curves) { + int first_key = curve.first_key; + + for(int i = 0; i < curve.num_segments(); i++) { + float3 p1 = mesh->curve_keys[first_key + i].co; + float r1 = mesh->curve_keys[first_key + i].radius; + float3 p2 = mesh->curve_keys[first_key + i + 1].co; + float r2 = mesh->curve_keys[first_key + i + 1].radius; - /* currently ignores segment overlaps*/ - surface_area += M_PI_F *(r1 + r2) * len(p1 - p2); + p1 = transform_point(&tfm, p1); + p2 = transform_point(&tfm, p2); + + /* currently ignores segment overlaps*/ + surface_area += M_PI_F *(r1 + r2) * len(p1 - p2); + } } } diff --git a/intern/cycles/render/scene.h b/intern/cycles/render/scene.h index 9490fd96be0..f6e1daea80d 100644 --- a/intern/cycles/render/scene.h +++ b/intern/cycles/render/scene.h @@ -62,7 +62,7 @@ public: device_vector<float4> bvh_nodes; device_vector<uint> object_node; device_vector<float4> tri_woop; - device_vector<uint> prim_type; + device_vector<uint> prim_segment; device_vector<uint> prim_visibility; device_vector<uint> prim_index; device_vector<uint> prim_object; @@ -73,7 +73,7 @@ public: device_vector<float4> tri_vindex; device_vector<float4> tri_verts; - device_vector<float4> curve_segments; + device_vector<float4> curves; device_vector<float4> curve_keys; /* objects */ |