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/bvh | |
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/bvh')
-rw-r--r-- | intern/cycles/bvh/bvh.cpp | 64 | ||||
-rw-r--r-- | intern/cycles/bvh/bvh.h | 4 | ||||
-rw-r--r-- | intern/cycles/bvh/bvh_build.cpp | 62 | ||||
-rw-r--r-- | intern/cycles/bvh/bvh_build.h | 4 | ||||
-rw-r--r-- | intern/cycles/bvh/bvh_params.h | 8 | ||||
-rw-r--r-- | intern/cycles/bvh/bvh_sort.cpp | 4 | ||||
-rw-r--r-- | intern/cycles/bvh/bvh_split.cpp | 16 |
7 files changed, 90 insertions, 72 deletions
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 |