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/bvh.cpp')
-rw-r--r--intern/cycles/bvh/bvh.cpp132
1 files changed, 106 insertions, 26 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;