Changeset View
Changeset View
Standalone View
Standalone View
intern/cycles/bvh/bvh.cpp
| Show First 20 Lines • Show All 101 Lines • ▼ Show 20 Lines | bool BVH::cache_read(CacheData& key) | ||||
| if(Cache::global.lookup(key, value)) { | if(Cache::global.lookup(key, value)) { | ||||
| cache_filename = key.get_filename(); | cache_filename = key.get_filename(); | ||||
| if(!(value.read(pack.root_index) && | if(!(value.read(pack.root_index) && | ||||
| value.read(pack.SAH) && | value.read(pack.SAH) && | ||||
| value.read(pack.nodes) && | value.read(pack.nodes) && | ||||
| value.read(pack.object_node) && | value.read(pack.object_node) && | ||||
| value.read(pack.tri_woop) && | |||||
| value.read(pack.prim_type) && | value.read(pack.prim_type) && | ||||
| value.read(pack.prim_visibility) && | value.read(pack.prim_visibility) && | ||||
| value.read(pack.prim_index) && | value.read(pack.prim_index) && | ||||
| value.read(pack.prim_object) && | value.read(pack.prim_object) && | ||||
| value.read(pack.is_leaf))) | value.read(pack.is_leaf))) | ||||
| { | { | ||||
| /* Clear the pack if load failed. */ | /* Clear the pack if load failed. */ | ||||
| pack.root_index = 0; | pack.root_index = 0; | ||||
| pack.SAH = 0.0f; | pack.SAH = 0.0f; | ||||
| pack.nodes.clear(); | pack.nodes.clear(); | ||||
| pack.object_node.clear(); | pack.object_node.clear(); | ||||
| pack.tri_woop.clear(); | |||||
| pack.prim_type.clear(); | pack.prim_type.clear(); | ||||
| pack.prim_visibility.clear(); | pack.prim_visibility.clear(); | ||||
| pack.prim_index.clear(); | pack.prim_index.clear(); | ||||
| pack.prim_object.clear(); | pack.prim_object.clear(); | ||||
| pack.is_leaf.clear(); | pack.is_leaf.clear(); | ||||
| return false; | return false; | ||||
| } | } | ||||
| return true; | return true; | ||||
| } | } | ||||
| return false; | return false; | ||||
| } | } | ||||
| void BVH::cache_write(CacheData& key) | void BVH::cache_write(CacheData& key) | ||||
| { | { | ||||
| CacheData value; | CacheData value; | ||||
| value.add(pack.root_index); | value.add(pack.root_index); | ||||
| value.add(pack.SAH); | value.add(pack.SAH); | ||||
| value.add(pack.nodes); | value.add(pack.nodes); | ||||
| value.add(pack.object_node); | value.add(pack.object_node); | ||||
| value.add(pack.tri_woop); | |||||
| value.add(pack.prim_type); | value.add(pack.prim_type); | ||||
| value.add(pack.prim_visibility); | value.add(pack.prim_visibility); | ||||
| value.add(pack.prim_index); | value.add(pack.prim_index); | ||||
| value.add(pack.prim_object); | value.add(pack.prim_object); | ||||
| value.add(pack.is_leaf); | value.add(pack.is_leaf); | ||||
| Cache::global.insert(key, value); | Cache::global.insert(key, value); | ||||
| ▲ Show 20 Lines • Show All 101 Lines • ▼ Show 20 Lines | void BVH::refit(Progress& progress) | ||||
| if(progress.get_cancel()) return; | if(progress.get_cancel()) return; | ||||
| progress.set_substatus("Refitting BVH nodes"); | progress.set_substatus("Refitting BVH nodes"); | ||||
| refit_nodes(); | refit_nodes(); | ||||
| } | } | ||||
| /* Triangles */ | /* Triangles */ | ||||
| void BVH::pack_triangle(int idx, float4 woop[3]) | |||||
| { | |||||
| int tob = pack.prim_object[idx]; | |||||
| const Mesh *mesh = objects[tob]->mesh; | |||||
| if(mesh->has_motion_blur()) | |||||
| return; | |||||
| int tidx = pack.prim_index[idx]; | |||||
| const int *vidx = mesh->triangles[tidx].v; | |||||
| const float3* vpos = &mesh->verts[0]; | |||||
| float3 v0 = vpos[vidx[0]]; | |||||
| float3 v1 = vpos[vidx[1]]; | |||||
| float3 v2 = vpos[vidx[2]]; | |||||
| float3 r0 = v0 - v2; | |||||
| float3 r1 = v1 - v2; | |||||
| float3 r2 = cross(r0, r1); | |||||
| if(is_zero(r0) || is_zero(r1) || is_zero(r2)) { | |||||
| /* degenerate */ | |||||
| woop[0] = make_float4(0.0f, 0.0f, 0.0f, 0.0f); | |||||
| woop[1] = make_float4(0.0f, 0.0f, 0.0f, 0.0f); | |||||
| woop[2] = make_float4(0.0f, 0.0f, 0.0f, 0.0f); | |||||
| } | |||||
| else { | |||||
| Transform t = make_transform( | |||||
| r0.x, r1.x, r2.x, v2.x, | |||||
| r0.y, r1.y, r2.y, v2.y, | |||||
| r0.z, r1.z, r2.z, v2.z, | |||||
| 0.0f, 0.0f, 0.0f, 1.0f); | |||||
| t = transform_inverse(t); | |||||
| woop[0] = make_float4(t.z.x, t.z.y, t.z.z, -t.z.w); | |||||
| woop[1] = make_float4(t.x.x, t.x.y, t.x.z, t.x.w); | |||||
| woop[2] = make_float4(t.y.x, t.y.y, t.y.z, t.y.w); | |||||
| } | |||||
| } | |||||
| /* Curves*/ | |||||
| 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]; | |||||
| int segment = PRIMITIVE_UNPACK_SEGMENT(pack.prim_type[idx]); | |||||
| int k0 = mesh->curves[tidx].first_key + segment; | |||||
| int k1 = mesh->curves[tidx].first_key + segment + 1; | |||||
| float3 v0 = float4_to_float3(mesh->curve_keys[k0]); | |||||
| float3 v1 = float4_to_float3(mesh->curve_keys[k1]); | |||||
| float3 d0 = v1 - v0; | |||||
| float l = len(d0); | |||||
| /*Plan | |||||
| *Transform tfm = make_transform( | |||||
| * location <3> , l, | |||||
| * extra curve data <3> , StrID, | |||||
| * nextkey, flags/tip?, 0, 0); | |||||
| */ | |||||
| float3 tg0 = make_float3(1.0f, 0.0f, 0.0f); | |||||
| float3 tg1 = make_float3(1.0f, 0.0f, 0.0f); | |||||
| Transform tfm = make_transform( | |||||
| tg0.x, tg0.y, tg0.z, l, | |||||
| tg1.x, tg1.y, tg1.z, 0, | |||||
| 0, 0, 0, 0, | |||||
| 0, 0, 0, 1); | |||||
| woop[0] = tfm.x; | |||||
| woop[1] = tfm.y; | |||||
| woop[2] = tfm.z; | |||||
| } | |||||
| void BVH::pack_primitives() | void BVH::pack_primitives() | ||||
| { | { | ||||
| int nsize = TRI_NODE_SIZE; | |||||
| size_t tidx_size = pack.prim_index.size(); | size_t tidx_size = pack.prim_index.size(); | ||||
| pack.tri_woop.clear(); | |||||
| pack.tri_woop.resize(tidx_size * nsize); | |||||
| pack.prim_visibility.clear(); | pack.prim_visibility.clear(); | ||||
| pack.prim_visibility.resize(tidx_size); | pack.prim_visibility.resize(tidx_size); | ||||
| for(unsigned int i = 0; i < tidx_size; i++) { | for(unsigned int i = 0; i < tidx_size; i++) { | ||||
| if(pack.prim_index[i] != -1) { | if(pack.prim_index[i] != -1) { | ||||
| float4 woop[3]; | |||||
| if(pack.prim_type[i] & PRIMITIVE_ALL_CURVE) | |||||
| pack_curve_segment(i, woop); | |||||
| else | |||||
| pack_triangle(i, woop); | |||||
| memcpy(&pack.tri_woop[i * nsize], woop, sizeof(float4)*3); | |||||
| int tob = pack.prim_object[i]; | int tob = pack.prim_object[i]; | ||||
| Object *ob = objects[tob]; | Object *ob = objects[tob]; | ||||
| pack.prim_visibility[i] = ob->visibility; | pack.prim_visibility[i] = ob->visibility; | ||||
| if(pack.prim_type[i] & PRIMITIVE_ALL_CURVE) | if(pack.prim_type[i] & PRIMITIVE_ALL_CURVE) | ||||
| pack.prim_visibility[i] |= PATH_RAY_CURVE; | pack.prim_visibility[i] |= PATH_RAY_CURVE; | ||||
| } | } | ||||
| else { | else { | ||||
| memset(&pack.tri_woop[i * nsize], 0, sizeof(float4)*3); | |||||
| pack.prim_visibility[i] = 0; | pack.prim_visibility[i] = 0; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| /* Pack Instances */ | /* Pack Instances */ | ||||
| void BVH::pack_instances(size_t nodes_size) | void BVH::pack_instances(size_t nodes_size) | ||||
| Show All 18 Lines | void BVH::pack_instances(size_t nodes_size) | ||||
| size_t prim_offset = pack.prim_index.size(); | size_t prim_offset = pack.prim_index.size(); | ||||
| size_t nodes_offset = nodes_size; | size_t nodes_offset = nodes_size; | ||||
| /* clear array that gives the node indexes for instanced objects */ | /* clear array that gives the node indexes for instanced objects */ | ||||
| pack.object_node.clear(); | pack.object_node.clear(); | ||||
| /* reserve */ | /* reserve */ | ||||
| size_t prim_index_size = pack.prim_index.size(); | size_t prim_index_size = pack.prim_index.size(); | ||||
| size_t tri_woop_size = pack.tri_woop.size(); | |||||
| size_t pack_prim_index_offset = prim_index_size; | size_t pack_prim_index_offset = prim_index_size; | ||||
| size_t pack_tri_woop_offset = tri_woop_size; | |||||
| size_t pack_nodes_offset = nodes_size; | size_t pack_nodes_offset = nodes_size; | ||||
| size_t object_offset = 0; | size_t object_offset = 0; | ||||
| map<Mesh*, int> mesh_map; | map<Mesh*, int> mesh_map; | ||||
| foreach(Object *ob, objects) { | foreach(Object *ob, objects) { | ||||
| Mesh *mesh = ob->mesh; | Mesh *mesh = ob->mesh; | ||||
| BVH *bvh = mesh->bvh; | BVH *bvh = mesh->bvh; | ||||
| if(!mesh->transform_applied) { | if(!mesh->transform_applied) { | ||||
| if(mesh_map.find(mesh) == mesh_map.end()) { | if(mesh_map.find(mesh) == mesh_map.end()) { | ||||
| prim_index_size += bvh->pack.prim_index.size(); | prim_index_size += bvh->pack.prim_index.size(); | ||||
| tri_woop_size += bvh->pack.tri_woop.size(); | |||||
| nodes_size += bvh->pack.nodes.size()*nsize; | nodes_size += bvh->pack.nodes.size()*nsize; | ||||
| mesh_map[mesh] = 1; | mesh_map[mesh] = 1; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| mesh_map.clear(); | mesh_map.clear(); | ||||
| pack.prim_index.resize(prim_index_size); | pack.prim_index.resize(prim_index_size); | ||||
| pack.prim_type.resize(prim_index_size); | pack.prim_type.resize(prim_index_size); | ||||
| pack.prim_object.resize(prim_index_size); | pack.prim_object.resize(prim_index_size); | ||||
| pack.prim_visibility.resize(prim_index_size); | pack.prim_visibility.resize(prim_index_size); | ||||
| pack.tri_woop.resize(tri_woop_size); | |||||
| pack.nodes.resize(nodes_size); | pack.nodes.resize(nodes_size); | ||||
| pack.object_node.resize(objects.size()); | pack.object_node.resize(objects.size()); | ||||
| int *pack_prim_index = (pack.prim_index.size())? &pack.prim_index[0]: NULL; | 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_type = (pack.prim_type.size())? &pack.prim_type[0]: NULL; | ||||
| int *pack_prim_object = (pack.prim_object.size())? &pack.prim_object[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; | 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; | |||||
| int4 *pack_nodes = (pack.nodes.size())? &pack.nodes[0]: NULL; | int4 *pack_nodes = (pack.nodes.size())? &pack.nodes[0]: NULL; | ||||
| /* merge */ | /* merge */ | ||||
| foreach(Object *ob, objects) { | foreach(Object *ob, objects) { | ||||
| Mesh *mesh = ob->mesh; | Mesh *mesh = ob->mesh; | ||||
| /* if mesh transform is applied, that means it's already in the top | /* if mesh transform is applied, that means it's already in the top | ||||
| * level BVH, and we don't need to merge it in */ | * level BVH, and we don't need to merge it in */ | ||||
| ▲ Show 20 Lines • Show All 41 Lines • ▼ Show 20 Lines | if(bvh->pack.prim_index.size()) { | ||||
| pack_prim_type[pack_prim_index_offset] = bvh_prim_type[i]; | pack_prim_type[pack_prim_index_offset] = bvh_prim_type[i]; | ||||
| pack_prim_visibility[pack_prim_index_offset] = bvh_prim_visibility[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_object[pack_prim_index_offset] = 0; // unused for instances | ||||
| pack_prim_index_offset++; | pack_prim_index_offset++; | ||||
| } | } | ||||
| } | } | ||||
| /* merge triangle intersection data */ | |||||
| if(bvh->pack.tri_woop.size()) { | |||||
| 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(); | |||||
| } | |||||
| /* merge nodes */ | /* merge nodes */ | ||||
| if(bvh->pack.nodes.size()) { | if(bvh->pack.nodes.size()) { | ||||
| size_t nsize_bbox = (use_qbvh)? nsize-2: nsize-1; | size_t nsize_bbox = (use_qbvh)? nsize-2: nsize-1; | ||||
| int4 *bvh_nodes = &bvh->pack.nodes[0]; | int4 *bvh_nodes = &bvh->pack.nodes[0]; | ||||
| size_t bvh_nodes_size = bvh->pack.nodes.size(); | size_t bvh_nodes_size = bvh->pack.nodes.size(); | ||||
| int *bvh_is_leaf = (bvh->pack.is_leaf.size() != 0) ? &bvh->pack.is_leaf[0] : NULL; | int *bvh_is_leaf = (bvh->pack.is_leaf.size() != 0) ? &bvh->pack.is_leaf[0] : NULL; | ||||
| for(size_t i = 0, j = 0; i < bvh_nodes_size; i+=nsize, j++) { | for(size_t i = 0, j = 0; i < bvh_nodes_size; i+=nsize, j++) { | ||||
| ▲ Show 20 Lines • Show All 358 Lines • Show Last 20 Lines | |||||