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
path: root/intern
diff options
context:
space:
mode:
authorBrecht Van Lommel <brechtvanlommel@pandora.be>2013-01-03 16:09:09 +0400
committerBrecht Van Lommel <brechtvanlommel@pandora.be>2013-01-03 16:09:09 +0400
commitbf25f1ea96d01b513907cf3067e8e2dd3c7e41b4 (patch)
tree822c28fa6ecf5e08c051e5eb7a05f6bc6e2e8742 /intern
parent57cf48e7c6fd04f864072c21433a822907774f78 (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')
-rw-r--r--intern/cycles/blender/blender_curves.cpp28
-rw-r--r--intern/cycles/bvh/bvh.cpp64
-rw-r--r--intern/cycles/bvh/bvh.h4
-rw-r--r--intern/cycles/bvh/bvh_build.cpp62
-rw-r--r--intern/cycles/bvh/bvh_build.h4
-rw-r--r--intern/cycles/bvh/bvh_params.h8
-rw-r--r--intern/cycles/bvh/bvh_sort.cpp4
-rw-r--r--intern/cycles/bvh/bvh_split.cpp16
-rw-r--r--intern/cycles/kernel/kernel_bvh.h47
-rw-r--r--intern/cycles/kernel/kernel_curve.h43
-rw-r--r--intern/cycles/kernel/kernel_emission.h2
-rw-r--r--intern/cycles/kernel/kernel_light.h26
-rw-r--r--intern/cycles/kernel/kernel_primitive.h8
-rw-r--r--intern/cycles/kernel/kernel_shader.h32
-rw-r--r--intern/cycles/kernel/kernel_textures.h4
-rw-r--r--intern/cycles/kernel/kernel_types.h7
-rw-r--r--intern/cycles/kernel/osl/osl_services.cpp12
-rw-r--r--intern/cycles/kernel/osl/osl_shader.cpp2
-rw-r--r--intern/cycles/kernel/svm/svm_attribute.h2
-rw-r--r--intern/cycles/kernel/svm/svm_geometry.h2
-rw-r--r--intern/cycles/render/attribute.cpp10
-rw-r--r--intern/cycles/render/light.cpp73
-rw-r--r--intern/cycles/render/mesh.cpp99
-rw-r--r--intern/cycles/render/mesh.h17
-rw-r--r--intern/cycles/render/object.cpp41
-rw-r--r--intern/cycles/render/scene.h4
26 files changed, 331 insertions, 290 deletions
diff --git a/intern/cycles/blender/blender_curves.cpp b/intern/cycles/blender/blender_curves.cpp
index 61628aae535..2e9a32f15f2 100644
--- a/intern/cycles/blender/blender_curves.cpp
+++ b/intern/cycles/blender/blender_curves.cpp
@@ -652,11 +652,10 @@ void ExportCurveTriangleGeometry(Mesh *mesh, ParticleCurveData *CData, int inter
void ExportCurveSegments(Mesh *mesh, ParticleCurveData *CData, int interpolation, int segments)
{
- int cks = 0;
- int curs = 0;
- int segs = 0;
+ int num_keys = 0;
+ int num_curves = 0;
- if(!(mesh->curve_segments.empty() && mesh->curve_keys.empty()))
+ if(!(mesh->curves.empty() && mesh->curve_keys.empty()))
return;
Attribute *attr_uv = mesh->curve_attributes.add(ATTR_STD_UV);
@@ -672,6 +671,8 @@ void ExportCurveSegments(Mesh *mesh, ParticleCurveData *CData, int interpolation
if(CData->curve_keynum[curve] <= 1)
continue;
+ size_t num_curve_keys = 0;
+
for( int curvekey = CData->curve_firstkey[curve]; curvekey < CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1; curvekey++) {
int subv = 1;
@@ -696,26 +697,23 @@ void ExportCurveSegments(Mesh *mesh, ParticleCurveData *CData, int interpolation
mesh->add_curve_key(ickey_loc, radius);
attr_intercept->add(time);
- if(subv != 0) {
- attr_uv->add(CData->curve_uv[curve]);
- mesh->add_curve_segment(cks - 1, cks, CData->psys_shader[sys], curs);
- segs++;
- }
-
- cks++;
+ num_curve_keys++;
}
}
- curs++;
+ mesh->add_curve(num_keys, num_curve_keys, CData->psys_shader[sys]);
+ attr_uv->add(CData->curve_uv[curve]);
+ num_keys += num_curve_keys;
+ num_curves++;
}
}
/* check allocation*/
- if((mesh->curve_keys.size() != cks) || (mesh->curve_segments.size() != segs)) {
+ if((mesh->curve_keys.size() != num_keys) || (mesh->curves.size() != num_curves)) {
/* allocation failed -> clear data */
mesh->curve_keys.clear();
- mesh->curve_segments.clear();
+ mesh->curves.clear();
mesh->curve_attributes.clear();
}
}
@@ -824,7 +822,7 @@ void BlenderSync::sync_curves(Mesh *mesh, BL::Mesh b_mesh, BL::Object b_ob, bool
{
/* Clear stored curve data */
mesh->curve_keys.clear();
- mesh->curve_segments.clear();
+ mesh->curves.clear();
mesh->curve_attributes.clear();
/* obtain general settings */
diff --git a/intern/cycles/bvh/bvh.cpp b/intern/cycles/bvh/bvh.cpp
index 0b43704b7b8..412b44031e6 100644
--- a/intern/cycles/bvh/bvh.cpp
+++ b/intern/cycles/bvh/bvh.cpp
@@ -76,7 +76,7 @@ bool BVH::cache_read(CacheData& key)
key.add(ob->mesh->verts);
key.add(ob->mesh->triangles);
key.add(ob->mesh->curve_keys);
- key.add(ob->mesh->curve_segments);
+ key.add(ob->mesh->curves);
key.add(&ob->bounds, sizeof(ob->bounds));
key.add(&ob->visibility, sizeof(ob->visibility));
key.add(&ob->mesh->transform_applied, sizeof(bool));
@@ -93,7 +93,7 @@ bool BVH::cache_read(CacheData& key)
value.read(pack.nodes);
value.read(pack.object_node);
value.read(pack.tri_woop);
- value.read(pack.prim_type);
+ value.read(pack.prim_segment);
value.read(pack.prim_visibility);
value.read(pack.prim_index);
value.read(pack.prim_object);
@@ -115,7 +115,7 @@ void BVH::cache_write(CacheData& key)
value.add(pack.nodes);
value.add(pack.object_node);
value.add(pack.tri_woop);
- value.add(pack.prim_type);
+ value.add(pack.prim_segment);
value.add(pack.prim_visibility);
value.add(pack.prim_index);
value.add(pack.prim_object);
@@ -161,11 +161,11 @@ void BVH::build(Progress& progress)
}
/* build nodes */
- vector<int> prim_type;
+ vector<int> prim_segment;
vector<int> prim_index;
vector<int> prim_object;
- BVHBuild bvh_build(objects, prim_type, prim_index, prim_object, params, progress);
+ BVHBuild bvh_build(objects, prim_segment, prim_index, prim_object, params, progress);
BVHNode *root = bvh_build.run();
if(progress.get_cancel()) {
@@ -174,7 +174,7 @@ void BVH::build(Progress& progress)
}
/* todo: get rid of this copy */
- pack.prim_type = prim_type;
+ pack.prim_segment = prim_segment;
pack.prim_index = prim_index;
pack.prim_object = prim_object;
@@ -271,13 +271,16 @@ void BVH::pack_triangle(int idx, float4 woop[3])
/* Curves*/
-void BVH::pack_curve_seg(int idx, float4 woop[3])
+void BVH::pack_curve_segment(int idx, float4 woop[3])
{
int tob = pack.prim_object[idx];
const Mesh *mesh = objects[tob]->mesh;
int tidx = pack.prim_index[idx];
- float3 v0 = mesh->curve_keys[mesh->curve_segments[tidx].v[0]].co;
- float3 v1 = mesh->curve_keys[mesh->curve_segments[tidx].v[1]].co;
+ int segment = pack.prim_segment[idx];
+ int k0 = mesh->curves[tidx].first_key + segment;
+ int k1 = mesh->curves[tidx].first_key + segment + 1;
+ float3 v0 = mesh->curve_keys[k0].co;
+ float3 v1 = mesh->curve_keys[k1].co;
float3 d0 = v1 - v0;
float l = len(d0);
@@ -289,19 +292,19 @@ void BVH::pack_curve_seg(int idx, float4 woop[3])
* nextkey, flags/tip?, 0, 0);
*/
Attribute *attr_tangent = mesh->curve_attributes.find(ATTR_STD_CURVE_TANGENT);
+ float3 tg0 = make_float3(1.0f, 0.0f, 0.0f);
float3 tg1 = make_float3(1.0f, 0.0f, 0.0f);
- float3 tg2 = make_float3(1.0f, 0.0f, 0.0f);
if(attr_tangent) {
const float3 *data_tangent = attr_tangent->data_float3();
- tg1 = data_tangent[mesh->curve_segments[tidx].v[0]];
- tg2 = data_tangent[mesh->curve_segments[tidx].v[1]];
+ tg0 = data_tangent[k0];
+ tg1 = data_tangent[k1];
}
Transform tfm = make_transform(
- tg1.x, tg1.y, tg1.z, l,
- tg2.x, tg2.y, tg2.z, 0,
+ tg0.x, tg0.y, tg0.z, l,
+ tg1.x, tg1.y, tg1.z, 0,
0, 0, 0, 0,
0, 0, 0, 1);
@@ -325,8 +328,8 @@ void BVH::pack_primitives()
if(pack.prim_index[i] != -1) {
float4 woop[3];
- if(pack.prim_type[i])
- pack_curve_seg(i, woop);
+ if(pack.prim_segment[i] != ~0)
+ pack_curve_segment(i, woop);
else
pack_triangle(i, woop);
@@ -353,8 +356,8 @@ void BVH::pack_instances(size_t nodes_size)
* meshes with transform applied and already in the top level BVH */
for(size_t i = 0; i < pack.prim_index.size(); i++)
if(pack.prim_index[i] != -1) {
- if(pack.prim_type[i])
- pack.prim_index[i] += objects[pack.prim_object[i]]->mesh->curveseg_offset;
+ if(pack.prim_segment[i] != ~0)
+ pack.prim_index[i] += objects[pack.prim_object[i]]->mesh->curve_offset;
else
pack.prim_index[i] += objects[pack.prim_object[i]]->mesh->tri_offset;
}
@@ -395,7 +398,7 @@ void BVH::pack_instances(size_t nodes_size)
mesh_map.clear();
pack.prim_index.resize(prim_index_size);
- pack.prim_type.resize(prim_index_size);
+ pack.prim_segment.resize(prim_index_size);
pack.prim_object.resize(prim_index_size);
pack.prim_visibility.resize(prim_index_size);
pack.tri_woop.resize(tri_woop_size);
@@ -403,7 +406,7 @@ void BVH::pack_instances(size_t nodes_size)
pack.object_node.resize(objects.size());
int *pack_prim_index = (pack.prim_index.size())? &pack.prim_index[0]: NULL;
- int *pack_prim_type = (pack.prim_type.size())? &pack.prim_type[0]: NULL;
+ int *pack_prim_segment = (pack.prim_segment.size())? &pack.prim_segment[0]: NULL;
int *pack_prim_object = (pack.prim_object.size())? &pack.prim_object[0]: NULL;
uint *pack_prim_visibility = (pack.prim_visibility.size())? &pack.prim_visibility[0]: NULL;
float4 *pack_tri_woop = (pack.tri_woop.size())? &pack.tri_woop[0]: NULL;
@@ -434,7 +437,7 @@ void BVH::pack_instances(size_t nodes_size)
int noffset = nodes_offset/nsize;
int mesh_tri_offset = mesh->tri_offset;
- int mesh_curve_offset = mesh->curveseg_offset;
+ int mesh_curve_offset = mesh->curve_offset;
/* fill in node indexes for instances */
if((bvh->pack.is_leaf.size() != 0) && bvh->pack.is_leaf[0])
@@ -448,16 +451,16 @@ void BVH::pack_instances(size_t nodes_size)
if(bvh->pack.prim_index.size()) {
size_t bvh_prim_index_size = bvh->pack.prim_index.size();
int *bvh_prim_index = &bvh->pack.prim_index[0];
- int *bvh_prim_type = &bvh->pack.prim_type[0];
+ int *bvh_prim_segment = &bvh->pack.prim_segment[0];
uint *bvh_prim_visibility = &bvh->pack.prim_visibility[0];
for(size_t i = 0; i < bvh_prim_index_size; i++) {
- if(bvh->pack.prim_type[i])
+ if(bvh->pack.prim_segment[i] != ~0)
pack_prim_index[pack_prim_index_offset] = bvh_prim_index[i] + mesh_curve_offset;
else
pack_prim_index[pack_prim_index_offset] = bvh_prim_index[i] + mesh_tri_offset;
- pack_prim_type[pack_prim_index_offset] = bvh_prim_type[i];
+ pack_prim_segment[pack_prim_index_offset] = bvh_prim_segment[i];
pack_prim_visibility[pack_prim_index_offset] = bvh_prim_visibility[i];
pack_prim_object[pack_prim_index_offset] = 0; // unused for instances
pack_prim_index_offset++;
@@ -622,13 +625,14 @@ void RegularBVH::refit_node(int idx, bool leaf, BoundBox& bbox, uint& visibility
/* primitives */
const Mesh *mesh = ob->mesh;
- if(pack.prim_type[prim]) {
- /* strands */
- int str_offset = (params.top_level)? mesh->curveseg_offset: 0;
- const int *hidx = mesh->curve_segments[pidx - str_offset].v;
+ if(pack.prim_segment[prim] != ~0) {
+ /* curves */
+ int str_offset = (params.top_level)? mesh->curve_offset: 0;
+ int k0 = mesh->curves[pidx - str_offset].first_key + pack.prim_segment[prim]; // XXX!
+ int k1 = k0 + 1;
- bbox.grow(mesh->curve_keys[hidx[0]].co, mesh->curve_keys[hidx[0]].radius);
- bbox.grow(mesh->curve_keys[hidx[1]].co, mesh->curve_keys[hidx[1]].radius);
+ bbox.grow(mesh->curve_keys[k0].co, mesh->curve_keys[k0].radius);
+ bbox.grow(mesh->curve_keys[k1].co, mesh->curve_keys[k1].radius);
}
else {
/* triangles */
diff --git a/intern/cycles/bvh/bvh.h b/intern/cycles/bvh/bvh.h
index d81bb312148..00c146143b8 100644
--- a/intern/cycles/bvh/bvh.h
+++ b/intern/cycles/bvh/bvh.h
@@ -53,7 +53,7 @@ struct PackedBVH {
/* precomputed triangle intersection data, one triangle is 4x float4 */
array<float4> tri_woop;
/* primitive type - triangle or strand (should be moved to flag?) */
- array<int> prim_type;
+ array<int> prim_segment;
/* visibility visibilitys for primitives */
array<uint> prim_visibility;
/* mapping from BVH primitive index to true primitive index, as primitives
@@ -106,7 +106,7 @@ protected:
/* triangles and strands*/
void pack_primitives();
void pack_triangle(int idx, float4 woop[3]);
- void pack_curve_seg(int idx, float4 woop[3]);
+ void pack_curve_segment(int idx, float4 woop[3]);
/* merge instance BVH's */
void pack_instances(size_t nodes_size);
diff --git a/intern/cycles/bvh/bvh_build.cpp b/intern/cycles/bvh/bvh_build.cpp
index 665c783b2d8..38fb1a15a13 100644
--- a/intern/cycles/bvh/bvh_build.cpp
+++ b/intern/cycles/bvh/bvh_build.cpp
@@ -48,10 +48,10 @@ public:
/* Constructor / Destructor */
BVHBuild::BVHBuild(const vector<Object*>& objects_,
- vector<int>& prim_type_, vector<int>& prim_index_, vector<int>& prim_object_,
+ vector<int>& prim_segment_, vector<int>& prim_index_, vector<int>& prim_object_,
const BVHParams& params_, Progress& progress_)
: objects(objects_),
- prim_type(prim_type_),
+ prim_segment(prim_segment_),
prim_index(prim_index_),
prim_object(prim_object_),
params(params_),
@@ -74,30 +74,34 @@ void BVHBuild::add_reference_mesh(BoundBox& root, BoundBox& center, Mesh *mesh,
BoundBox bounds = BoundBox::empty;
for(int k = 0; k < 3; k++) {
- float3 pt = mesh->verts[t.v[k]];
- bounds.grow(pt);
+ float3 co = mesh->verts[t.v[k]];
+ bounds.grow(co);
}
if(bounds.valid()) {
- references.push_back(BVHReference(bounds, j, i, false));
+ references.push_back(BVHReference(bounds, j, i, ~0));
root.grow(bounds);
center.grow(bounds.center2());
}
}
- for(uint j = 0; j < mesh->curve_segments.size(); j++) {
- Mesh::CurveSegment s = mesh->curve_segments[j];
- BoundBox bounds = BoundBox::empty;
+ for(uint j = 0; j < mesh->curves.size(); j++) {
+ Mesh::Curve curve = mesh->curves[j];
- for(int k = 0; k < 2; k++) {
- float3 pt = mesh->curve_keys[s.v[k]].co;
- bounds.grow(pt, mesh->curve_keys[s.v[k]].radius);
- }
+ for(int k = 0; k < curve.num_keys - 1; k++) {
+ BoundBox bounds = BoundBox::empty;
- if(bounds.valid()) {
- references.push_back(BVHReference(bounds, j, i, true));
- root.grow(bounds);
- center.grow(bounds.center2());
+ float3 co0 = mesh->curve_keys[curve.first_key + k].co;
+ float3 co1 = mesh->curve_keys[curve.first_key + k + 1].co;
+
+ bounds.grow(co0, mesh->curve_keys[curve.first_key + k].radius);
+ bounds.grow(co1, mesh->curve_keys[curve.first_key + k + 1].radius);
+
+ if(bounds.valid()) {
+ references.push_back(BVHReference(bounds, j, i, k));
+ root.grow(bounds);
+ center.grow(bounds.center2());
+ }
}
}
}
@@ -109,6 +113,16 @@ void BVHBuild::add_reference_object(BoundBox& root, BoundBox& center, Object *ob
center.grow(ob->bounds.center2());
}
+static size_t count_curve_segments(Mesh *mesh)
+{
+ size_t num = 0, num_curves = mesh->curves.size();
+
+ for(size_t i = 0; i < num_curves; i++)
+ num += mesh->curves[i].num_keys - 1;
+
+ return num;
+}
+
void BVHBuild::add_references(BVHRange& root)
{
/* reserve space for references */
@@ -118,14 +132,14 @@ void BVHBuild::add_references(BVHRange& root)
if(params.top_level) {
if(ob->mesh->transform_applied) {
num_alloc_references += ob->mesh->triangles.size();
- num_alloc_references += ob->mesh->curve_segments.size();
+ num_alloc_references += count_curve_segments(ob->mesh);
}
else
num_alloc_references++;
}
else {
num_alloc_references += ob->mesh->triangles.size();
- num_alloc_references += ob->mesh->curve_segments.size();
+ num_alloc_references += count_curve_segments(ob->mesh);
}
}
@@ -183,7 +197,7 @@ BVHNode* BVHBuild::run()
progress_total = references.size();
progress_original_total = progress_total;
- prim_type.resize(references.size());
+ prim_segment.resize(references.size());
prim_index.resize(references.size());
prim_object.resize(references.size());
@@ -341,12 +355,12 @@ BVHNode *BVHBuild::create_object_leaf_nodes(const BVHReference *ref, int start,
if(start == prim_index.size()) {
assert(params.use_spatial_split);
- prim_type.push_back(ref->prim_type());
+ prim_segment.push_back(ref->prim_segment());
prim_index.push_back(ref->prim_index());
prim_object.push_back(ref->prim_object());
}
else {
- prim_type[start] = ref->prim_type();
+ prim_segment[start] = ref->prim_segment();
prim_index[start] = ref->prim_index();
prim_object[start] = ref->prim_object();
}
@@ -369,7 +383,7 @@ BVHNode *BVHBuild::create_object_leaf_nodes(const BVHReference *ref, int start,
BVHNode* BVHBuild::create_leaf_node(const BVHRange& range)
{
- vector<int>& p_type = prim_type;
+ vector<int>& p_segment = prim_segment;
vector<int>& p_index = prim_index;
vector<int>& p_object = prim_object;
BoundBox bounds = BoundBox::empty;
@@ -383,12 +397,12 @@ BVHNode* BVHBuild::create_leaf_node(const BVHRange& range)
if(range.start() + num == prim_index.size()) {
assert(params.use_spatial_split);
- p_type.push_back(ref.prim_type());
+ p_segment.push_back(ref.prim_segment());
p_index.push_back(ref.prim_index());
p_object.push_back(ref.prim_object());
}
else {
- p_type[range.start() + num] = ref.prim_type();
+ p_segment[range.start() + num] = ref.prim_segment();
p_index[range.start() + num] = ref.prim_index();
p_object[range.start() + num] = ref.prim_object();
}
diff --git a/intern/cycles/bvh/bvh_build.h b/intern/cycles/bvh/bvh_build.h
index ba10eb49412..3df4da1739a 100644
--- a/intern/cycles/bvh/bvh_build.h
+++ b/intern/cycles/bvh/bvh_build.h
@@ -44,7 +44,7 @@ public:
/* Constructor/Destructor */
BVHBuild(
const vector<Object*>& objects,
- vector<int>& prim_type,
+ vector<int>& prim_segment,
vector<int>& prim_index,
vector<int>& prim_object,
const BVHParams& params,
@@ -88,7 +88,7 @@ protected:
int num_original_references;
/* output primitive indexes and objects */
- vector<int>& prim_type;
+ vector<int>& prim_segment;
vector<int>& prim_index;
vector<int>& prim_object;
diff --git a/intern/cycles/bvh/bvh_params.h b/intern/cycles/bvh/bvh_params.h
index 7a1555ae548..f7bc79f71e6 100644
--- a/intern/cycles/bvh/bvh_params.h
+++ b/intern/cycles/bvh/bvh_params.h
@@ -98,22 +98,22 @@ class BVHReference
public:
__forceinline BVHReference() {}
- __forceinline BVHReference(const BoundBox& bounds_, int prim_index_, int prim_object_, int prim_type)
+ __forceinline BVHReference(const BoundBox& bounds_, int prim_index_, int prim_object_, int prim_segment)
: rbounds(bounds_)
{
rbounds.min.w = __int_as_float(prim_index_);
rbounds.max.w = __int_as_float(prim_object_);
- type = prim_type;
+ segment = prim_segment;
}
__forceinline const BoundBox& bounds() const { return rbounds; }
__forceinline int prim_index() const { return __float_as_int(rbounds.min.w); }
__forceinline int prim_object() const { return __float_as_int(rbounds.max.w); }
- __forceinline int prim_type() const { return type; }
+ __forceinline int prim_segment() const { return segment; }
protected:
BoundBox rbounds;
- uint type;
+ uint segment;
};
/* BVH Range
diff --git a/intern/cycles/bvh/bvh_sort.cpp b/intern/cycles/bvh/bvh_sort.cpp
index 9a8961c8b15..91994be5b96 100644
--- a/intern/cycles/bvh/bvh_sort.cpp
+++ b/intern/cycles/bvh/bvh_sort.cpp
@@ -43,8 +43,8 @@ public:
else if(ra.prim_object() > rb.prim_object()) return false;
else if(ra.prim_index() < rb.prim_index()) return true;
else if(ra.prim_index() > rb.prim_index()) return false;
- else if(ra.prim_type() < rb.prim_type()) return true;
- else if(ra.prim_type() > rb.prim_type()) return false;
+ else if(ra.prim_segment() < rb.prim_segment()) return true;
+ else if(ra.prim_segment() > rb.prim_segment()) return false;
return false;
}
diff --git a/intern/cycles/bvh/bvh_split.cpp b/intern/cycles/bvh/bvh_split.cpp
index 67fdfd77657..03ff69d7b6d 100644
--- a/intern/cycles/bvh/bvh_split.cpp
+++ b/intern/cycles/bvh/bvh_split.cpp
@@ -253,7 +253,7 @@ void BVHSpatialSplit::split_reference(BVHBuild *builder, BVHReference& left, BVH
Object *ob = builder->objects[ref.prim_object()];
const Mesh *mesh = ob->mesh;
- if (!ref.prim_type()) {
+ if (ref.prim_segment() == ~0) {
const int *inds = mesh->triangles[ref.prim_index()].v;
const float3 *verts = &mesh->verts[0];
const float3* v1 = &verts[inds[2]];
@@ -281,11 +281,11 @@ void BVHSpatialSplit::split_reference(BVHBuild *builder, BVHReference& left, BVH
}
}
else {
- /* Strand split: NOTE - Currently ignores strand width and needs to be fixed.*/
-
- const int *inds = mesh->curve_segments[ref.prim_index()].v;
- const float3* v0 = &mesh->curve_keys[inds[0]].co;
- const float3* v1 = &mesh->curve_keys[inds[1]].co;
+ /* curve split: NOTE - Currently ignores curve width and needs to be fixed.*/
+ const int k0 = mesh->curves[ref.prim_index()].first_key + ref.prim_segment();
+ const int k1 = k0 + 1;
+ const float3* v0 = &mesh->curve_keys[k0].co;
+ const float3* v1 = &mesh->curve_keys[k1].co;
float v0p = (*v0)[dim];
float v1p = (*v1)[dim];
@@ -318,8 +318,8 @@ void BVHSpatialSplit::split_reference(BVHBuild *builder, BVHReference& left, BVH
right_bounds.intersect(ref.bounds());
/* set references */
- left = BVHReference(left_bounds, ref.prim_index(), ref.prim_object(), ref.prim_type());
- right = BVHReference(right_bounds, ref.prim_index(), ref.prim_object(), ref.prim_type());
+ left = BVHReference(left_bounds, ref.prim_index(), ref.prim_object(), ref.prim_segment());
+ right = BVHReference(right_bounds, ref.prim_index(), ref.prim_object(), ref.prim_segment());
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/kernel_bvh.h b/intern/cycles/kernel/kernel_bvh.h
index d32287f91e8..c811d83ad78 100644
--- a/intern/cycles/kernel/kernel_bvh.h
+++ b/intern/cycles/kernel/kernel_bvh.h
@@ -207,22 +207,22 @@ __device_inline void bvh_triangle_intersect(KernelGlobals *kg, Intersection *ise
#ifdef __HAIR__
__device_inline void bvh_curve_intersect(KernelGlobals *kg, Intersection *isect,
- float3 P, float3 idir, uint visibility, int object, int triAddr)
+ float3 P, float3 idir, uint visibility, int object, int curveAddr, int segment)
{
/* curve Intersection check */
int flags = kernel_data.curve_kernel_data.curveflags;
- int prim = kernel_tex_fetch(__prim_index, triAddr);
- float4 v00 = kernel_tex_fetch(__curve_segments, prim);
+ int prim = kernel_tex_fetch(__prim_index, curveAddr);
+ float4 v00 = kernel_tex_fetch(__curves, prim);
- int v1 = __float_as_int(v00.x);
- int v2 = __float_as_int(v00.y);
+ int k0 = __float_as_int(v00.x) + segment;
+ int k1 = k0 + 1;
- float4 P1 = kernel_tex_fetch(__curve_keys, v1);
- float4 P2 = kernel_tex_fetch(__curve_keys, v2);
+ float4 P1 = kernel_tex_fetch(__curve_keys, k0);
+ float4 P2 = kernel_tex_fetch(__curve_keys, k1);
- float l = v00.w;
+ float l = len(P2 - P1); // XXX slower
float r1 = P1.w;
float r2 = P2.w;
float mr = max(r1,r2);
@@ -329,14 +329,15 @@ __device_inline void bvh_curve_intersect(KernelGlobals *kg, Intersection *isect,
return;
}*/
- #ifdef __VISIBILITY_FLAG__
+#ifdef __VISIBILITY_FLAG__
/* visibility flag test. we do it here under the assumption
* that most triangles are culled by node flags */
- if(kernel_tex_fetch(__prim_visibility, triAddr) & visibility)
- #endif
+ if(kernel_tex_fetch(__prim_visibility, curveAddr) & visibility)
+#endif
{
/* record intersection */
- isect->prim = triAddr;
+ isect->prim = curveAddr;
+ isect->segment = segment;
isect->object = object;
isect->u = z/l;
isect->v = td/(4*a*a);
@@ -430,8 +431,9 @@ __device_inline bool bvh_intersect(KernelGlobals *kg, const Ray *ray, const uint
while(primAddr < primAddr2) {
/* intersect ray against primitive */
#ifdef __HAIR__
- if(kernel_tex_fetch(__prim_type, primAddr))
- bvh_curve_intersect(kg, isect, P, idir, visibility, object, primAddr);
+ uint segment = kernel_tex_fetch(__prim_segment, primAddr);
+ if(segment != ~0)
+ bvh_curve_intersect(kg, isect, P, idir, visibility, object, primAddr, segment);
else
#endif
bvh_triangle_intersect(kg, isect, P, idir, visibility, object, primAddr);
@@ -555,8 +557,9 @@ __device_inline bool bvh_intersect_motion(KernelGlobals *kg, const Ray *ray, con
while(primAddr < primAddr2) {
/* intersect ray against primitive */
#ifdef __HAIR__
- if(kernel_tex_fetch(__prim_type, primAddr))
- bvh_curve_intersect(kg, isect, P, idir, visibility, object, primAddr);
+ uint segment = kernel_tex_fetch(__prim_segment, primAddr);
+ if(segment != ~0)
+ bvh_curve_intersect(kg, isect, P, idir, visibility, object, primAddr, segment);
else
#endif
bvh_triangle_intersect(kg, isect, P, idir, visibility, object, primAddr);
@@ -720,14 +723,14 @@ __device_inline float3 bvh_curve_refine(KernelGlobals *kg, ShaderData *sd, const
}
int prim = kernel_tex_fetch(__prim_index, isect->prim);
- float4 v00 = kernel_tex_fetch(__curve_segments, prim);
+ float4 v00 = kernel_tex_fetch(__curves, prim);
- int v1 = __float_as_int(v00.x);
- int v2 = __float_as_int(v00.y);
+ int k0 = __float_as_int(v00.x) + isect->segment;
+ int k1 = k0 + 1;
- float4 P1 = kernel_tex_fetch(__curve_keys, v1);
- float4 P2 = kernel_tex_fetch(__curve_keys, v2);
- float l = v00.w;
+ float4 P1 = kernel_tex_fetch(__curve_keys, k0);
+ float4 P2 = kernel_tex_fetch(__curve_keys, k1);
+ float l = len(P2 - P1); // XXX slower
float r1 = P1.w;
float r2 = P2.w;
float3 tg = float4_to_float3(P2 - P1) / l;
diff --git a/intern/cycles/kernel/kernel_curve.h b/intern/cycles/kernel/kernel_curve.h
index fef1a48644d..e065717888c 100644
--- a/intern/cycles/kernel/kernel_curve.h
+++ b/intern/cycles/kernel/kernel_curve.h
@@ -24,19 +24,21 @@ CCL_NAMESPACE_BEGIN
__device float curve_attribute_float(KernelGlobals *kg, const ShaderData *sd, AttributeElement elem, int offset, float *dx, float *dy)
{
- if(elem == ATTR_ELEMENT_CURVE_SEGMENT) {
+ if(elem == ATTR_ELEMENT_CURVE) {
#ifdef __RAY_DIFFERENTIALS__
if(dx) *dx = 0.0f;
if(dy) *dy = 0.0f;
#endif
- return kernel_tex_fetch(__attributes_float, offset + sd->curve_seg);
+ return kernel_tex_fetch(__attributes_float, offset + sd->prim);
}
else if(elem == ATTR_ELEMENT_CURVE_KEY) {
- float4 segment = kernel_tex_fetch(__curve_segments, sd->curve_seg);
+ float4 curvedata = kernel_tex_fetch(__curves, sd->prim);
+ int k0 = __float_as_int(curvedata.x) + sd->segment;
+ int k1 = k0 + 1;
- float f0 = kernel_tex_fetch(__attributes_float, offset + __float_as_int(segment.x));
- float f1 = kernel_tex_fetch(__attributes_float, offset + __float_as_int(segment.y));
+ float f0 = kernel_tex_fetch(__attributes_float, offset + k0);
+ float f1 = kernel_tex_fetch(__attributes_float, offset + k1);
#ifdef __RAY_DIFFERENTIALS__
if(dx) *dx = sd->du.dx*(f1 - f0);
@@ -57,7 +59,7 @@ __device float curve_attribute_float(KernelGlobals *kg, const ShaderData *sd, At
__device float3 curve_attribute_float3(KernelGlobals *kg, const ShaderData *sd, AttributeElement elem, int offset, float3 *dx, float3 *dy)
{
- if(elem == ATTR_ELEMENT_CURVE_SEGMENT) {
+ if(elem == ATTR_ELEMENT_CURVE) {
/* idea: we can't derive any useful differentials here, but for tiled
* mipmap image caching it would be useful to avoid reading the highest
* detail level always. maybe a derivative based on the hair density
@@ -67,13 +69,15 @@ __device float3 curve_attribute_float3(KernelGlobals *kg, const ShaderData *sd,
if(dy) *dy = make_float3(0.0f, 0.0f, 0.0f);
#endif
- return float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + sd->curve_seg));
+ return float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + sd->prim));
}
else if(elem == ATTR_ELEMENT_CURVE_KEY) {
- float4 segment = kernel_tex_fetch(__curve_segments, sd->curve_seg);
+ float4 curvedata = kernel_tex_fetch(__curves, sd->prim);
+ int k0 = __float_as_int(curvedata.x) + sd->segment;
+ int k1 = k0 + 1;
- float3 f0 = float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + __float_as_int(segment.x)));
- float3 f1 = float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + __float_as_int(segment.y)));
+ float3 f0 = float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + k0));
+ float3 f1 = float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + k1));
#ifdef __RAY_DIFFERENTIALS__
if(dx) *dx = sd->du.dx*(f1 - f0);
@@ -96,19 +100,16 @@ __device float3 curve_attribute_float3(KernelGlobals *kg, const ShaderData *sd,
__device float curve_thickness(KernelGlobals *kg, ShaderData *sd)
{
- int prim = sd->curve_seg;
- float u = sd->u;
float r = 0.0f;
- if(prim != -1) {
- float4 v00 = kernel_tex_fetch(__curve_segments, prim);
+ if(sd->segment != ~0) {
+ float4 curvedata = kernel_tex_fetch(__curves, sd->prim);
+ int k0 = __float_as_int(curvedata.x) + sd->segment;
+ int k1 = k0 + 1;
- int v1 = __float_as_int(v00.x);
- int v2 = __float_as_int(v00.y);
-
- float4 P1 = kernel_tex_fetch(__curve_keys, v1);
- float4 P2 = kernel_tex_fetch(__curve_keys, v2);
- r = (P2.w - P1.w) * u + P1.w;
+ 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;
}
return r*2.0f;
@@ -118,7 +119,7 @@ __device float3 curve_tangent_normal(KernelGlobals *kg, ShaderData *sd)
{
float3 tgN = make_float3(0.0f,0.0f,0.0f);
- if(sd->curve_seg != ~0) {
+ if(sd->segment != ~0) {
float normalmix = kernel_data.curve_kernel_data.normalmix;
tgN = -(-sd->I - sd->dPdu * (dot(sd->dPdu,-sd->I) * normalmix / len_squared(sd->dPdu)));
diff --git a/intern/cycles/kernel/kernel_emission.h b/intern/cycles/kernel/kernel_emission.h
index adf7e8eca82..d5506ad1dd0 100644
--- a/intern/cycles/kernel/kernel_emission.h
+++ b/intern/cycles/kernel/kernel_emission.h
@@ -157,7 +157,7 @@ __device float3 indirect_emission(KernelGlobals *kg, ShaderData *sd, float t, in
float3 L = shader_emissive_eval(kg, sd);
#ifdef __HAIR__
- if(!(path_flag & PATH_RAY_MIS_SKIP) && (sd->flag & SD_SAMPLE_AS_LIGHT) && (sd->curve_seg == ~0)) {
+ if(!(path_flag & PATH_RAY_MIS_SKIP) && (sd->flag & SD_SAMPLE_AS_LIGHT) && (sd->segment == ~0)) {
#else
if(!(path_flag & PATH_RAY_MIS_SKIP) && (sd->flag & SD_SAMPLE_AS_LIGHT)) {
#endif
diff --git a/intern/cycles/kernel/kernel_light.h b/intern/cycles/kernel/kernel_light.h
index 09ee1f68e12..1561ddc9ddd 100644
--- a/intern/cycles/kernel/kernel_light.h
+++ b/intern/cycles/kernel/kernel_light.h
@@ -329,18 +329,20 @@ __device float triangle_light_pdf(KernelGlobals *kg,
#ifdef __HAIR__
/* Strand Light */
-__device void curve_seg_light_sample(KernelGlobals *kg, int prim, int object,
- float randu, float randv, float time, LightSample *ls)
+__device void curve_segment_light_sample(KernelGlobals *kg, int prim, int object,
+ int segment, float randu, float randv, float time, LightSample *ls)
{
/* this strand code needs completion */
- float4 v00 = kernel_tex_fetch(__curve_segments, prim);
+ float4 v00 = kernel_tex_fetch(__curves, prim);
+
+ int k0 = __float_as_int(v00.x) + segment;
+ int k1 = k0 + 1;
- int v1 = __float_as_int(v00.x);
- int v2 = __float_as_int(v00.y);
- float l = v00.w;
+ float4 P1 = kernel_tex_fetch(__curve_keys, k0);
+ float4 P2 = kernel_tex_fetch(__curve_keys, k1);
+
+ float l = len(P2 - P1); // XXX slower
- float4 P1 = kernel_tex_fetch(__curve_keys, v1);
- float4 P2 = kernel_tex_fetch(__curve_keys, v2);
float r1 = P1.w;
float r2 = P2.w;
float3 tg = float4_to_float3(P2 - P1) / l;
@@ -419,15 +421,15 @@ __device void light_sample(KernelGlobals *kg, float randt, float randu, float ra
float4 l = kernel_tex_fetch(__light_distribution, index);
int prim = __float_as_int(l.y);
#ifdef __HAIR__
-/* currently use l.z to indicate is strand sample which isn't ideal */
- bool is_curve = __float_as_int(l.z) == 0.0f;
+ int segment = __float_as_int(l.z);
#endif
if(prim >= 0) {
int object = __float_as_int(l.w);
+
#ifdef __HAIR__
- if (is_curve)
- curve_seg_light_sample(kg, prim, object, randu, randv, time, ls);
+ if (segment != ~0)
+ curve_segment_light_sample(kg, prim, object, segment, randu, randv, time, ls);
else
#endif
triangle_light_sample(kg, prim, object, randu, randv, time, ls);
diff --git a/intern/cycles/kernel/kernel_primitive.h b/intern/cycles/kernel/kernel_primitive.h
index 2296017c686..7538b7107d0 100644
--- a/intern/cycles/kernel/kernel_primitive.h
+++ b/intern/cycles/kernel/kernel_primitive.h
@@ -37,7 +37,7 @@ __device_inline int find_attribute(KernelGlobals *kg, ShaderData *sd, uint id, A
{
/* for SVM, find attribute by unique id */
uint attr_offset = sd->object*kernel_data.bvh.attributes_map_stride;
- attr_offset = (sd->curve_seg == ~0)? attr_offset: attr_offset + ATTR_PRIM_CURVE;
+ attr_offset = (sd->segment == ~0)? attr_offset: attr_offset + ATTR_PRIM_CURVE;
uint4 attr_map = kernel_tex_fetch(__attributes_map, attr_offset);
while(attr_map.x != id) {
@@ -55,7 +55,7 @@ __device_inline int find_attribute(KernelGlobals *kg, ShaderData *sd, uint id, A
__device float primitive_attribute_float(KernelGlobals *kg, const ShaderData *sd, AttributeElement elem, int offset, float *dx, float *dy)
{
#ifdef __HAIR__
- if(sd->curve_seg == ~0)
+ if(sd->segment == ~0)
#endif
return triangle_attribute_float(kg, sd, elem, offset, dx, dy);
#ifdef __HAIR__
@@ -67,7 +67,7 @@ __device float primitive_attribute_float(KernelGlobals *kg, const ShaderData *sd
__device float3 primitive_attribute_float3(KernelGlobals *kg, const ShaderData *sd, AttributeElement elem, int offset, float3 *dx, float3 *dy)
{
#ifdef __HAIR__
- if(sd->curve_seg == ~0)
+ if(sd->segment == ~0)
#endif
return triangle_attribute_float3(kg, sd, elem, offset, dx, dy);
#ifdef __HAIR__
@@ -92,7 +92,7 @@ __device float3 primitive_uv(KernelGlobals *kg, ShaderData *sd)
__device float3 primitive_tangent(KernelGlobals *kg, ShaderData *sd)
{
#ifdef __HAIR__
- if(sd->curve_seg != ~0)
+ if(sd->segment != ~0)
return normalize(sd->dPdu);
#endif
diff --git a/intern/cycles/kernel/kernel_shader.h b/intern/cycles/kernel/kernel_shader.h
index 49bbc5a74ab..0a5a2ab54b0 100644
--- a/intern/cycles/kernel/kernel_shader.h
+++ b/intern/cycles/kernel/kernel_shader.h
@@ -69,25 +69,22 @@ __device_inline void shader_setup_from_ray(KernelGlobals *kg, ShaderData *sd,
#endif
sd->prim = kernel_tex_fetch(__prim_index, isect->prim);
-#ifdef __HAIR__
- sd->curve_seg = ~0;
-#endif
sd->ray_length = isect->t;
#ifdef __HAIR__
- if(kernel_tex_fetch(__prim_type, isect->prim)) {
+ if(kernel_tex_fetch(__prim_segment, isect->prim) != ~0) {
/* Strand Shader setting*/
- float4 CurSeg = kernel_tex_fetch(__curve_segments, sd->prim);
- sd->shader = __float_as_int(CurSeg.z);
+ float4 curvedata = kernel_tex_fetch(__curves, sd->prim);
- sd->curve_seg = sd->prim;
- sd->prim = isect->prim;
+ sd->shader = __float_as_int(curvedata.z);
+ sd->segment = isect->segment;
float tcorr = isect->t;
if(kernel_data.curve_kernel_data.curveflags & CURVE_KN_POSTINTERSECTCORRECTION) {
tcorr = (isect->u < 0)? tcorr + sqrtf(isect->v) : tcorr - sqrtf(isect->v);
sd->ray_length = tcorr;
}
+
sd->P = bvh_curve_refine(kg, sd, isect, ray, tcorr);
}
else {
@@ -97,6 +94,10 @@ __device_inline void shader_setup_from_ray(KernelGlobals *kg, ShaderData *sd,
float3 Ng = make_float3(Ns.x, Ns.y, Ns.z);
sd->shader = __float_as_int(Ns.w);
+#ifdef __HAIR__
+ sd->segment = ~0;
+#endif
+
#ifdef __UV__
sd->u = isect->u;
sd->v = isect->v;
@@ -107,7 +108,6 @@ __device_inline void shader_setup_from_ray(KernelGlobals *kg, ShaderData *sd,
sd->Ng = Ng;
sd->N = Ng;
-
/* smooth normal */
if(sd->shader & SHADER_SMOOTH_NORMAL)
sd->N = triangle_smooth_normal(kg, sd->prim, sd->u, sd->v);
@@ -162,7 +162,7 @@ __device_inline void shader_setup_from_ray(KernelGlobals *kg, ShaderData *sd,
__device void shader_setup_from_sample(KernelGlobals *kg, ShaderData *sd,
const float3 P, const float3 Ng, const float3 I,
- int shader, int object, int prim, float u, float v, float t, float time, int curve = ~0)
+ int shader, int object, int prim, float u, float v, float t, float time, int segment = ~0)
{
/* vectors */
sd->P = P;
@@ -171,7 +171,7 @@ __device void shader_setup_from_sample(KernelGlobals *kg, ShaderData *sd,
sd->I = I;
sd->shader = shader;
#ifdef __HAIR__
- sd->curve_seg = curve;
+ sd->segment = segment;
#endif
/* primitive */
@@ -215,7 +215,7 @@ __device void shader_setup_from_sample(KernelGlobals *kg, ShaderData *sd,
/* smooth normal */
#ifdef __HAIR__
- if(sd->shader & SHADER_SMOOTH_NORMAL && sd->curve_seg == ~0) {
+ if(sd->shader & SHADER_SMOOTH_NORMAL && sd->segment == ~0) {
sd->N = triangle_smooth_normal(kg, sd->prim, sd->u, sd->v);
#else
if(sd->shader & SHADER_SMOOTH_NORMAL) {
@@ -231,7 +231,7 @@ __device void shader_setup_from_sample(KernelGlobals *kg, ShaderData *sd,
#ifdef __DPDU__
/* dPdu/dPdv */
#ifdef __HAIR__
- if(sd->prim == ~0 || sd->curve_seg != ~0) {
+ if(sd->prim == ~0 || sd->segment != ~0) {
sd->dPdu = make_float3(0.0f, 0.0f, 0.0f);
sd->dPdv = make_float3(0.0f, 0.0f, 0.0f);
}
@@ -323,7 +323,7 @@ __device_inline void shader_setup_from_background(KernelGlobals *kg, ShaderData
#endif
sd->prim = ~0;
#ifdef __HAIR__
- sd->curve_seg = ~0;
+ sd->segment = ~0;
#endif
#ifdef __UV__
sd->u = 0.0f;
@@ -781,14 +781,14 @@ __device bool shader_transparent_shadow(KernelGlobals *kg, Intersection *isect)
int shader = 0;
#ifdef __HAIR__
- if(!kernel_tex_fetch(__prim_type, isect->prim)) {
+ if(kernel_tex_fetch(__prim_segment, isect->prim) == ~0) {
#endif
float4 Ns = kernel_tex_fetch(__tri_normal, prim);
shader = __float_as_int(Ns.w);
#ifdef __HAIR__
}
else {
- float4 str = kernel_tex_fetch(__curve_segments, prim);
+ float4 str = kernel_tex_fetch(__curves, prim);
shader = __float_as_int(str.z);
}
#endif
diff --git a/intern/cycles/kernel/kernel_textures.h b/intern/cycles/kernel/kernel_textures.h
index 072df21a188..e27de95e7ab 100644
--- a/intern/cycles/kernel/kernel_textures.h
+++ b/intern/cycles/kernel/kernel_textures.h
@@ -27,7 +27,7 @@
/* bvh */
KERNEL_TEX(float4, texture_float4, __bvh_nodes)
KERNEL_TEX(float4, texture_float4, __tri_woop)
-KERNEL_TEX(uint, texture_uint, __prim_type)
+KERNEL_TEX(uint, texture_uint, __prim_segment)
KERNEL_TEX(uint, texture_uint, __prim_visibility)
KERNEL_TEX(uint, texture_uint, __prim_index)
KERNEL_TEX(uint, texture_uint, __prim_object)
@@ -44,7 +44,7 @@ KERNEL_TEX(float4, texture_float4, __tri_vindex)
KERNEL_TEX(float4, texture_float4, __tri_verts)
/* curves */
-KERNEL_TEX(float4, texture_float4, __curve_segments)
+KERNEL_TEX(float4, texture_float4, __curves)
KERNEL_TEX(float4, texture_float4, __curve_keys)
/* attributes */
diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h
index e80772bd4e2..2bd6b5859f3 100644
--- a/intern/cycles/kernel/kernel_types.h
+++ b/intern/cycles/kernel/kernel_types.h
@@ -344,6 +344,7 @@ typedef struct Intersection {
float t, u, v;
int prim;
int object;
+ int segment;
} Intersection;
/* Attributes */
@@ -357,7 +358,7 @@ typedef enum AttributeElement {
ATTR_ELEMENT_FACE,
ATTR_ELEMENT_VERTEX,
ATTR_ELEMENT_CORNER,
- ATTR_ELEMENT_CURVE_SEGMENT,
+ ATTR_ELEMENT_CURVE,
ATTR_ELEMENT_CURVE_KEY
} AttributeElement;
@@ -464,8 +465,8 @@ typedef struct ShaderData {
int prim;
#ifdef __HAIR__
- /* strand id if there is one, -1 otherwise */
- int curve_seg;
+ /* for curves, segment number in curve, ~0 for triangles */
+ int segment;
#endif
/* parametric coordinates
* - barycentric weights for triangles */
diff --git a/intern/cycles/kernel/osl/osl_services.cpp b/intern/cycles/kernel/osl/osl_services.cpp
index afa5211216b..28742d56e3b 100644
--- a/intern/cycles/kernel/osl/osl_services.cpp
+++ b/intern/cycles/kernel/osl/osl_services.cpp
@@ -605,7 +605,7 @@ bool OSLRenderServices::get_object_standard_attribute(KernelGlobals *kg, ShaderD
return set_attribute_int(3, type, derivatives, val);
}
else if ((name == u_geom_trianglevertices || name == u_geom_polyvertices)
- && sd->curve_seg == ~0) {
+ && sd->segment == ~0) {
float3 P[3];
triangle_vertices(kg, sd->prim, P);
@@ -625,7 +625,7 @@ bool OSLRenderServices::get_object_standard_attribute(KernelGlobals *kg, ShaderD
#ifdef __HAIR__
/* Hair Attributes */
else if (name == u_is_curve) {
- float f = !(sd->curve_seg == ~0);
+ float f = (sd->segment != ~0);
return set_attribute_float(f, type, derivatives, val);
}
else if (name == u_curve_thickness) {
@@ -659,7 +659,7 @@ bool OSLRenderServices::get_attribute(void *renderstate, bool derivatives, ustri
{
KernelGlobals *kg = kernel_globals;
ShaderData *sd = (ShaderData *)renderstate;
- int object, prim, curve_seg;
+ int object, prim, segment;
/* lookup of attribute on another object */
if (object_name != u_empty || sd == NULL) {
@@ -670,19 +670,19 @@ bool OSLRenderServices::get_attribute(void *renderstate, bool derivatives, ustri
object = it->second;
prim = ~0;
- curve_seg = ~0;
+ segment = ~0;
}
else {
object = sd->object;
prim = sd->prim;
- curve_seg = sd->curve_seg;
+ segment = sd->segment;
if (object == ~0)
return get_background_attribute(kg, sd, name, type, derivatives, val);
}
/* find attribute on object */
- object = object*ATTR_PRIM_TYPES + (curve_seg != ~0);
+ object = object*ATTR_PRIM_TYPES + (segment != ~0);
OSLGlobals::AttributeMap& attribute_map = kg->osl->attribute_map[object];
OSLGlobals::AttributeMap::iterator it = attribute_map.find(name);
diff --git a/intern/cycles/kernel/osl/osl_shader.cpp b/intern/cycles/kernel/osl/osl_shader.cpp
index 18486eba114..59e307bb408 100644
--- a/intern/cycles/kernel/osl/osl_shader.cpp
+++ b/intern/cycles/kernel/osl/osl_shader.cpp
@@ -457,7 +457,7 @@ float3 OSLShader::volume_eval_phase(const ShaderClosure *sc, const float3 omega_
int OSLShader::find_attribute(KernelGlobals *kg, const ShaderData *sd, uint id, AttributeElement *elem)
{
/* for OSL, a hash map is used to lookup the attribute by name. */
- int object = sd->object*ATTR_PRIM_TYPES + (sd->curve_seg != ~0);
+ int object = sd->object*ATTR_PRIM_TYPES + (sd->segment != ~0);
OSLGlobals::AttributeMap &attr_map = kg->osl->attribute_map[object];
ustring stdname(std::string("geom:") + std::string(Attribute::standard_name((AttributeStandard)id)));
OSLGlobals::AttributeMap::const_iterator it = attr_map.find(stdname);
diff --git a/intern/cycles/kernel/svm/svm_attribute.h b/intern/cycles/kernel/svm/svm_attribute.h
index f11b69138d1..ea0a31610f1 100644
--- a/intern/cycles/kernel/svm/svm_attribute.h
+++ b/intern/cycles/kernel/svm/svm_attribute.h
@@ -28,7 +28,7 @@ __device void svm_node_attr_init(KernelGlobals *kg, ShaderData *sd,
/* find attribute by unique id */
uint id = node.y;
uint attr_offset = sd->object*kernel_data.bvh.attributes_map_stride;
- attr_offset = (sd->curve_seg == ~0)? attr_offset: attr_offset + ATTR_PRIM_CURVE;
+ attr_offset = (sd->segment == ~0)? attr_offset: attr_offset + ATTR_PRIM_CURVE;
uint4 attr_map = kernel_tex_fetch(__attributes_map, attr_offset);
while(attr_map.x != id) {
diff --git a/intern/cycles/kernel/svm/svm_geometry.h b/intern/cycles/kernel/svm/svm_geometry.h
index db8bbabe0ec..a04f4ea0fa7 100644
--- a/intern/cycles/kernel/svm/svm_geometry.h
+++ b/intern/cycles/kernel/svm/svm_geometry.h
@@ -155,7 +155,7 @@ __device void svm_node_hair_info(KernelGlobals *kg, ShaderData *sd, float *stack
switch(type) {
case NODE_INFO_CURVE_IS_STRAND: {
- data = !(sd->curve_seg == ~0);
+ data = (sd->segment != ~0);
stack_store_float(stack, out_offset, data);
break;
}
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 */