diff options
Diffstat (limited to 'intern/cycles/bvh/bvh.cpp')
-rw-r--r-- | intern/cycles/bvh/bvh.cpp | 132 |
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; |