Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'intern/cycles/bvh')
-rw-r--r--intern/cycles/bvh/bvh.cpp132
-rw-r--r--intern/cycles/bvh/bvh.h9
-rw-r--r--intern/cycles/bvh/bvh_build.cpp37
-rw-r--r--intern/cycles/bvh/bvh_build.h2
-rw-r--r--intern/cycles/bvh/bvh_params.h5
-rw-r--r--intern/cycles/bvh/bvh_sort.cpp2
-rw-r--r--intern/cycles/bvh/bvh_split.cpp55
7 files changed, 196 insertions, 46 deletions
diff --git a/intern/cycles/bvh/bvh.cpp b/intern/cycles/bvh/bvh.cpp
index b58a34f9942..102414e4a3d 100644
--- a/intern/cycles/bvh/bvh.cpp
+++ b/intern/cycles/bvh/bvh.cpp
@@ -75,6 +75,10 @@ bool BVH::cache_read(CacheData& key)
foreach(Object *ob, objects) {
key.add(ob->mesh->verts);
key.add(ob->mesh->triangles);
+ key.add(ob->mesh->curve_keys);
+ key.add(ob->mesh->curve_keysCD);
+ key.add(ob->mesh->curve_segs);
+ key.add(ob->mesh->curve_attrib);
key.add(&ob->bounds, sizeof(ob->bounds));
key.add(&ob->visibility, sizeof(ob->visibility));
key.add(&ob->mesh->transform_applied, sizeof(bool));
@@ -91,6 +95,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_visibility);
value.read(pack.prim_index);
value.read(pack.prim_object);
@@ -112,6 +117,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_visibility);
value.add(pack.prim_index);
value.add(pack.prim_object);
@@ -157,10 +163,11 @@ void BVH::build(Progress& progress)
}
/* build nodes */
+ vector<int> prim_type;
vector<int> prim_index;
vector<int> prim_object;
- BVHBuild bvh_build(objects, prim_index, prim_object, params, progress);
+ BVHBuild bvh_build(objects, prim_type, prim_index, prim_object, params, progress);
BVHNode *root = bvh_build.run();
if(progress.get_cancel()) {
@@ -169,6 +176,7 @@ void BVH::build(Progress& progress)
}
/* todo: get rid of this copy */
+ pack.prim_type = prim_type;
pack.prim_index = prim_index;
pack.prim_object = prim_object;
@@ -182,8 +190,8 @@ void BVH::build(Progress& progress)
}
/* pack triangles */
- progress.set_substatus("Packing BVH triangles");
- pack_triangles();
+ progress.set_substatus("Packing BVH triangles and strands");
+ pack_primitives();
if(progress.get_cancel()) {
root->deleteSubtree();
@@ -215,8 +223,8 @@ void BVH::build(Progress& progress)
void BVH::refit(Progress& progress)
{
- progress.set_substatus("Packing BVH triangles");
- pack_triangles();
+ progress.set_substatus("Packing BVH primitives");
+ pack_primitives();
if(progress.get_cancel()) return;
@@ -263,7 +271,50 @@ void BVH::pack_triangle(int idx, float4 woop[3])
}
}
-void BVH::pack_triangles()
+/* Curves*/
+
+void BVH::pack_curve_seg(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_segs[tidx].v[0]].loc;
+ float3 v1 = mesh->curve_keys[mesh->curve_segs[tidx].v[1]].loc;
+ float t0 = mesh->curve_keys[mesh->curve_segs[tidx].v[0]].time;
+ float t1 = mesh->curve_keys[mesh->curve_segs[tidx].v[1]].time;
+
+ float3 d0 = v1 - v0;
+ float l = len(d0);
+
+ float u = mesh->curve_attrib[mesh->curve_segs[tidx].curve].uv[0];
+ float v = mesh->curve_attrib[mesh->curve_segs[tidx].curve].uv[1];
+
+ /*Plan
+ *Transform tfm = make_transform(
+ * location <3> , l,
+ * extra curve data <3> , StrID,
+ * nextkey, flags/tip?, r, t);
+ */
+ float3 tg1 = make_float3(1.0f,0.0f,0.0f);
+ float3 tg2 = make_float3(1.0f,0.0f,0.0f);
+ if(mesh->curve_keysCD.size()) {
+ tg1 = mesh->curve_keysCD[mesh->curve_segs[tidx].v[0]].tg;
+ tg2 = mesh->curve_keysCD[mesh->curve_segs[tidx].v[1]].tg;
+ }
+
+ Transform tfm = make_transform(
+ tg1.x, tg1.y, tg1.z, l,
+ tg2.x, tg2.y, tg2.z, 0,
+ t0, t1, u, v,
+ 0, 0, 0, 1);
+
+ woop[0] = tfm.x;
+ woop[1] = tfm.y;
+ woop[2] = tfm.z;
+
+}
+
+void BVH::pack_primitives()
{
int nsize = TRI_NODE_SIZE;
size_t tidx_size = pack.prim_index.size();
@@ -277,7 +328,11 @@ void BVH::pack_triangles()
if(pack.prim_index[i] != -1) {
float4 woop[3];
- pack_triangle(i, woop);
+ if(pack.prim_type[i])
+ pack_curve_seg(i, woop);
+ else
+ pack_triangle(i, woop);
+
memcpy(&pack.tri_woop[i * nsize], woop, sizeof(float4)*3);
int tob = pack.prim_object[i];
@@ -300,11 +355,15 @@ void BVH::pack_instances(size_t nodes_size)
/* adjust primitive index to point to the triangle in the global array, for
* 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)
- pack.prim_index[i] += objects[pack.prim_object[i]]->mesh->tri_offset;
+ if(pack.prim_index[i] != -1) {
+ if(pack.prim_type[i])
+ pack.prim_index[i] += objects[pack.prim_object[i]]->mesh->curveseg_offset;
+ else
+ pack.prim_index[i] += objects[pack.prim_object[i]]->mesh->tri_offset;
+ }
/* track offsets of instanced BVH data in global array */
- size_t tri_offset = pack.prim_index.size();
+ size_t prim_offset = pack.prim_index.size();
size_t nodes_offset = nodes_size;
/* clear array that gives the node indexes for instanced objects */
@@ -339,6 +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_object.resize(prim_index_size);
pack.prim_visibility.resize(prim_index_size);
pack.tri_woop.resize(tri_woop_size);
@@ -346,6 +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_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;
@@ -376,6 +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;
/* fill in node indexes for instances */
if((bvh->pack.is_leaf.size() != 0) && bvh->pack.is_leaf[0])
@@ -389,10 +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];
uint *bvh_prim_visibility = &bvh->pack.prim_visibility[0];
for(size_t i = 0; i < bvh_prim_index_size; i++) {
- pack_prim_index[pack_prim_index_offset] = bvh_prim_index[i] + mesh_tri_offset;
+ if(bvh->pack.prim_type[i])
+ 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_visibility[pack_prim_index_offset] = bvh_prim_visibility[i];
pack_prim_object[pack_prim_index_offset] = 0; // unused for instances
pack_prim_index_offset++;
@@ -401,7 +469,7 @@ void BVH::pack_instances(size_t nodes_size)
/* merge triangle intersection data */
if(bvh->pack.tri_woop.size()) {
- memcpy(pack_tri_woop+pack_tri_woop_offset, &bvh->pack.tri_woop[0],
+ memcpy(pack_tri_woop + pack_tri_woop_offset, &bvh->pack.tri_woop[0],
bvh->pack.tri_woop.size()*sizeof(float4));
pack_tri_woop_offset += bvh->pack.tri_woop.size();
}
@@ -420,8 +488,8 @@ void BVH::pack_instances(size_t nodes_size)
int4 data = bvh_nodes[i + nsize_bbox];
if(bvh_is_leaf && bvh_is_leaf[j]) {
- data.x += tri_offset;
- data.y += tri_offset;
+ data.x += prim_offset;
+ data.y += prim_offset;
}
else {
data.x += (data.x < 0)? -noffset: noffset;
@@ -443,7 +511,7 @@ void BVH::pack_instances(size_t nodes_size)
}
nodes_offset += bvh->pack.nodes.size();
- tri_offset += bvh->pack.prim_index.size();
+ prim_offset += bvh->pack.prim_index.size();
}
}
@@ -544,25 +612,37 @@ void RegularBVH::refit_node(int idx, bool leaf, BoundBox& bbox, uint& visibility
if(leaf) {
/* refit leaf node */
- for(int tri = c0; tri < c1; tri++) {
- int tidx = pack.prim_index[tri];
- int tob = pack.prim_object[tri];
+ for(int prim = c0; prim < c1; prim++) {
+ int pidx = pack.prim_index[prim];
+ int tob = pack.prim_object[prim];
Object *ob = objects[tob];
- if(tidx == -1) {
+ if(pidx == -1) {
/* object instance */
bbox.grow(ob->bounds);
}
else {
- /* triangles */
+ /* primitives */
const Mesh *mesh = ob->mesh;
- int tri_offset = (params.top_level)? mesh->tri_offset: 0;
- const int *vidx = mesh->triangles[tidx - tri_offset].v;
- const float3 *vpos = &mesh->verts[0];
- bbox.grow(vpos[vidx[0]]);
- bbox.grow(vpos[vidx[1]]);
- bbox.grow(vpos[vidx[2]]);
+ if(pack.prim_type[prim]) {
+ /* strands */
+ int str_offset = (params.top_level)? mesh->curveseg_offset: 0;
+ const int *hidx = mesh->curve_segs[pidx - str_offset].v;
+
+ bbox.grow(mesh->curve_keys[hidx[0]].loc, mesh->curve_keys[hidx[0]].radius);
+ bbox.grow(mesh->curve_keys[hidx[1]].loc, mesh->curve_keys[hidx[1]].radius);
+ }
+ else {
+ /* triangles */
+ int tri_offset = (params.top_level)? mesh->tri_offset: 0;
+ const int *vidx = mesh->triangles[pidx - tri_offset].v;
+ const float3 *vpos = &mesh->verts[0];
+
+ bbox.grow(vpos[vidx[0]]);
+ bbox.grow(vpos[vidx[1]]);
+ bbox.grow(vpos[vidx[2]]);
+ }
}
visibility |= ob->visibility;
diff --git a/intern/cycles/bvh/bvh.h b/intern/cycles/bvh/bvh.h
index 549f1e3ac1d..d81bb312148 100644
--- a/intern/cycles/bvh/bvh.h
+++ b/intern/cycles/bvh/bvh.h
@@ -51,7 +51,9 @@ struct PackedBVH {
/* object index to BVH node index mapping for instances */
array<int> object_node;
/* precomputed triangle intersection data, one triangle is 4x float4 */
- array<float4> tri_woop;
+ array<float4> tri_woop;
+ /* primitive type - triangle or strand (should be moved to flag?) */
+ array<int> prim_type;
/* visibility visibilitys for primitives */
array<uint> prim_visibility;
/* mapping from BVH primitive index to true primitive index, as primitives
@@ -101,9 +103,10 @@ protected:
bool cache_read(CacheData& key);
void cache_write(CacheData& key);
- /* triangles */
- void pack_triangles();
+ /* triangles and strands*/
+ void pack_primitives();
void pack_triangle(int idx, float4 woop[3]);
+ void pack_curve_seg(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 705b805a3a9..cdd94324f53 100644
--- a/intern/cycles/bvh/bvh_build.cpp
+++ b/intern/cycles/bvh/bvh_build.cpp
@@ -48,9 +48,10 @@ public:
/* Constructor / Destructor */
BVHBuild::BVHBuild(const vector<Object*>& objects_,
- vector<int>& prim_index_, vector<int>& prim_object_,
+ vector<int>& prim_type_, vector<int>& prim_index_, vector<int>& prim_object_,
const BVHParams& params_, Progress& progress_)
: objects(objects_),
+ prim_type(prim_type_),
prim_index(prim_index_),
prim_object(prim_object_),
params(params_),
@@ -78,7 +79,23 @@ void BVHBuild::add_reference_mesh(BoundBox& root, BoundBox& center, Mesh *mesh,
}
if(bounds.valid()) {
- references.push_back(BVHReference(bounds, j, i));
+ references.push_back(BVHReference(bounds, j, i, false));
+ root.grow(bounds);
+ center.grow(bounds.center2());
+ }
+ }
+
+ for(uint j = 0; j < mesh->curve_segs.size(); j++) {
+ Mesh::CurveSeg s = mesh->curve_segs[j];
+ BoundBox bounds = BoundBox::empty;
+
+ for(int k = 0; k < 2; k++) {
+ float3 pt = mesh->curve_keys[s.v[k]].loc;
+ bounds.grow(pt, mesh->curve_keys[s.v[k]].radius);
+ }
+
+ if(bounds.valid()) {
+ references.push_back(BVHReference(bounds, j, i, true));
root.grow(bounds);
center.grow(bounds.center2());
}
@@ -87,7 +104,7 @@ void BVHBuild::add_reference_mesh(BoundBox& root, BoundBox& center, Mesh *mesh,
void BVHBuild::add_reference_object(BoundBox& root, BoundBox& center, Object *ob, int i)
{
- references.push_back(BVHReference(ob->bounds, -1, i));
+ references.push_back(BVHReference(ob->bounds, -1, i, false));
root.grow(ob->bounds);
center.grow(ob->bounds.center2());
}
@@ -99,13 +116,17 @@ void BVHBuild::add_references(BVHRange& root)
foreach(Object *ob, objects) {
if(params.top_level) {
- if(ob->mesh->transform_applied)
+ if(ob->mesh->transform_applied) {
num_alloc_references += ob->mesh->triangles.size();
+ num_alloc_references += ob->mesh->curve_segs.size();
+ }
else
num_alloc_references++;
}
- else
+ else {
num_alloc_references += ob->mesh->triangles.size();
+ num_alloc_references += ob->mesh->curve_segs.size();
+ }
}
references.reserve(num_alloc_references);
@@ -162,6 +183,7 @@ BVHNode* BVHBuild::run()
progress_total = references.size();
progress_original_total = progress_total;
+ prim_type.resize(references.size());
prim_index.resize(references.size());
prim_object.resize(references.size());
@@ -319,10 +341,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_index.push_back(ref->prim_index());
prim_object.push_back(ref->prim_object());
}
else {
+ prim_type[start] = ref->prim_type();
prim_index[start] = ref->prim_index();
prim_object[start] = ref->prim_object();
}
@@ -345,6 +369,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_index = prim_index;
vector<int>& p_object = prim_object;
BoundBox bounds = BoundBox::empty;
@@ -358,10 +383,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_index.push_back(ref.prim_index());
p_object.push_back(ref.prim_object());
}
else {
+ p_type[range.start() + num] = ref.prim_type();
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 44ef918b326..ba10eb49412 100644
--- a/intern/cycles/bvh/bvh_build.h
+++ b/intern/cycles/bvh/bvh_build.h
@@ -44,6 +44,7 @@ public:
/* Constructor/Destructor */
BVHBuild(
const vector<Object*>& objects,
+ vector<int>& prim_type,
vector<int>& prim_index,
vector<int>& prim_object,
const BVHParams& params,
@@ -87,6 +88,7 @@ protected:
int num_original_references;
/* output primitive indexes and objects */
+ vector<int>& prim_type;
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 a78496d841d..7a1555ae548 100644
--- a/intern/cycles/bvh/bvh_params.h
+++ b/intern/cycles/bvh/bvh_params.h
@@ -98,19 +98,22 @@ class BVHReference
public:
__forceinline BVHReference() {}
- __forceinline BVHReference(const BoundBox& bounds_, int prim_index_, int prim_object_)
+ __forceinline BVHReference(const BoundBox& bounds_, int prim_index_, int prim_object_, int prim_type)
: rbounds(bounds_)
{
rbounds.min.w = __int_as_float(prim_index_);
rbounds.max.w = __int_as_float(prim_object_);
+ type = prim_type;
}
__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; }
protected:
BoundBox rbounds;
+ uint type;
};
/* BVH Range
diff --git a/intern/cycles/bvh/bvh_sort.cpp b/intern/cycles/bvh/bvh_sort.cpp
index bef384be592..9a8961c8b15 100644
--- a/intern/cycles/bvh/bvh_sort.cpp
+++ b/intern/cycles/bvh/bvh_sort.cpp
@@ -43,6 +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;
return false;
}
diff --git a/intern/cycles/bvh/bvh_split.cpp b/intern/cycles/bvh/bvh_split.cpp
index 263c5834428..860e2c8d7df 100644
--- a/intern/cycles/bvh/bvh_split.cpp
+++ b/intern/cycles/bvh/bvh_split.cpp
@@ -252,14 +252,41 @@ void BVHSpatialSplit::split_reference(BVHBuild *builder, BVHReference& left, BVH
/* loop over vertices/edges. */
Object *ob = builder->objects[ref.prim_object()];
const Mesh *mesh = ob->mesh;
- const int *inds = mesh->triangles[ref.prim_index()].v;
- const float3 *verts = &mesh->verts[0];
- const float3* v1 = &verts[inds[2]];
-
- for(int i = 0; i < 3; i++) {
- const float3* v0 = v1;
- int vindex = inds[i];
- v1 = &verts[vindex];
+
+ if (!ref.prim_type()) {
+ const int *inds = mesh->triangles[ref.prim_index()].v;
+ const float3 *verts = &mesh->verts[0];
+ const float3* v1 = &verts[inds[2]];
+
+ for(int i = 0; i < 3; i++) {
+ const float3* v0 = v1;
+ int vindex = inds[i];
+ v1 = &verts[vindex];
+ float v0p = (*v0)[dim];
+ float v1p = (*v1)[dim];
+
+ /* insert vertex to the boxes it belongs to. */
+ if(v0p <= pos)
+ left_bounds.grow(*v0);
+
+ if(v0p >= pos)
+ right_bounds.grow(*v0);
+
+ /* edge intersects the plane => insert intersection to both boxes. */
+ if((v0p < pos && v1p > pos) || (v0p > pos && v1p < pos)) {
+ float3 t = lerp(*v0, *v1, clamp((pos - v0p) / (v1p - v0p), 0.0f, 1.0f));
+ left_bounds.grow(t);
+ right_bounds.grow(t);
+ }
+ }
+ }
+ else {
+ /* Strand split: NOTE - Currently ignores strand width and needs to be fixed.*/
+
+ const int *inds = mesh->curve_segs[ref.prim_index()].v;
+ const float3* v0 = &mesh->curve_keys[inds[0]].loc;
+ const float3* v1 = &mesh->curve_keys[inds[1]].loc;
+
float v0p = (*v0)[dim];
float v1p = (*v1)[dim];
@@ -270,6 +297,12 @@ void BVHSpatialSplit::split_reference(BVHBuild *builder, BVHReference& left, BVH
if(v0p >= pos)
right_bounds.grow(*v0);
+ if(v1p <= pos)
+ left_bounds.grow(*v1);
+
+ if(v1p >= pos)
+ right_bounds.grow(*v1);
+
/* edge intersects the plane => insert intersection to both boxes. */
if((v0p < pos && v1p > pos) || (v0p > pos && v1p < pos)) {
float3 t = lerp(*v0, *v1, clamp((pos - v0p) / (v1p - v0p), 0.0f, 1.0f));
@@ -284,9 +317,9 @@ void BVHSpatialSplit::split_reference(BVHBuild *builder, BVHReference& left, BVH
left_bounds.intersect(ref.bounds());
right_bounds.intersect(ref.bounds());
- /* set referecnes */
- left = BVHReference(left_bounds, ref.prim_index(), ref.prim_object());
- right = BVHReference(right_bounds, ref.prim_index(), ref.prim_object());
+ /* 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());
}
CCL_NAMESPACE_END