Blender V2.61 - r43446
|
00001 /* 00002 * Copyright 2011, Blender Foundation. 00003 * 00004 * This program is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU General Public License 00006 * as published by the Free Software Foundation; either version 2 00007 * of the License, or (at your option) any later version. 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU General Public License 00015 * along with this program; if not, write to the Free Software Foundation, 00016 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00017 */ 00018 00019 #include "bvh.h" 00020 #include "bvh_build.h" 00021 00022 #include "device.h" 00023 #include "shader.h" 00024 #include "light.h" 00025 #include "mesh.h" 00026 #include "object.h" 00027 #include "scene.h" 00028 00029 #include "osl_globals.h" 00030 00031 #include "util_cache.h" 00032 #include "util_foreach.h" 00033 #include "util_progress.h" 00034 #include "util_set.h" 00035 00036 CCL_NAMESPACE_BEGIN 00037 00038 /* Mesh */ 00039 00040 Mesh::Mesh() 00041 : attributes(this) 00042 { 00043 need_update = true; 00044 transform_applied = false; 00045 transform_negative_scaled = false; 00046 displacement_method = DISPLACE_BUMP; 00047 00048 bvh = NULL; 00049 00050 tri_offset = 0; 00051 vert_offset = 0; 00052 } 00053 00054 Mesh::~Mesh() 00055 { 00056 delete bvh; 00057 } 00058 00059 void Mesh::reserve(int numverts, int numtris) 00060 { 00061 /* reserve space to add verts and triangles later */ 00062 verts.resize(numverts); 00063 triangles.resize(numtris); 00064 shader.resize(numtris); 00065 smooth.resize(numtris); 00066 attributes.reserve(numverts, numtris); 00067 } 00068 00069 void Mesh::clear() 00070 { 00071 /* clear all verts and triangles */ 00072 verts.clear(); 00073 triangles.clear(); 00074 shader.clear(); 00075 smooth.clear(); 00076 00077 attributes.clear(); 00078 used_shaders.clear(); 00079 00080 transform_applied = false; 00081 transform_negative_scaled = false; 00082 } 00083 00084 void Mesh::add_triangle(int v0, int v1, int v2, int shader_, bool smooth_) 00085 { 00086 Triangle t; 00087 t.v[0] = v0; 00088 t.v[1] = v1; 00089 t.v[2] = v2; 00090 00091 triangles.push_back(t); 00092 shader.push_back(shader_); 00093 smooth.push_back(smooth_); 00094 } 00095 00096 void Mesh::compute_bounds() 00097 { 00098 BoundBox bnds; 00099 size_t verts_size = verts.size(); 00100 00101 for(size_t i = 0; i < verts_size; i++) 00102 bnds.grow(verts[i]); 00103 00104 /* happens mostly on empty meshes */ 00105 if(!bnds.valid()) 00106 bnds.grow(make_float3(0.0f, 0.0f, 0.0f)); 00107 00108 bounds = bnds; 00109 } 00110 00111 void Mesh::add_face_normals() 00112 { 00113 /* don't compute if already there */ 00114 if(attributes.find(Attribute::STD_FACE_NORMAL)) 00115 return; 00116 00117 /* get attributes */ 00118 Attribute *attr_fN = attributes.add(Attribute::STD_FACE_NORMAL); 00119 float3 *fN = attr_fN->data_float3(); 00120 00121 /* compute face normals */ 00122 size_t triangles_size = triangles.size(); 00123 bool flip = transform_negative_scaled; 00124 00125 if(triangles_size) { 00126 float3 *verts_ptr = &verts[0]; 00127 Triangle *triangles_ptr = &triangles[0]; 00128 00129 for(size_t i = 0; i < triangles_size; i++) { 00130 Triangle t = triangles_ptr[i]; 00131 float3 v0 = verts_ptr[t.v[0]]; 00132 float3 v1 = verts_ptr[t.v[1]]; 00133 float3 v2 = verts_ptr[t.v[2]]; 00134 00135 fN[i] = normalize(cross(v1 - v0, v2 - v0)); 00136 00137 if(flip) 00138 fN[i] = -fN[i]; 00139 } 00140 } 00141 } 00142 00143 void Mesh::add_vertex_normals() 00144 { 00145 /* don't compute if already there */ 00146 if(attributes.find(Attribute::STD_VERTEX_NORMAL)) 00147 return; 00148 00149 /* get attributes */ 00150 Attribute *attr_fN = attributes.find(Attribute::STD_FACE_NORMAL); 00151 Attribute *attr_vN = attributes.add(Attribute::STD_VERTEX_NORMAL); 00152 00153 float3 *fN = attr_fN->data_float3(); 00154 float3 *vN = attr_vN->data_float3(); 00155 00156 /* compute vertex normals */ 00157 memset(vN, 0, verts.size()*sizeof(float3)); 00158 00159 size_t verts_size = verts.size(); 00160 size_t triangles_size = triangles.size(); 00161 bool flip = transform_negative_scaled; 00162 00163 if(triangles_size) { 00164 Triangle *triangles_ptr = &triangles[0]; 00165 00166 for(size_t i = 0; i < triangles_size; i++) 00167 for(size_t j = 0; j < 3; j++) 00168 vN[triangles_ptr[i].v[j]] += fN[i]; 00169 } 00170 00171 for(size_t i = 0; i < verts_size; i++) { 00172 vN[i] = normalize(vN[i]); 00173 if(flip) 00174 vN[i] = -vN[i]; 00175 } 00176 } 00177 00178 void Mesh::pack_normals(Scene *scene, float4 *normal, float4 *vnormal) 00179 { 00180 Attribute *attr_fN = attributes.find(Attribute::STD_FACE_NORMAL); 00181 Attribute *attr_vN = attributes.find(Attribute::STD_VERTEX_NORMAL); 00182 00183 float3 *fN = attr_fN->data_float3(); 00184 float3 *vN = attr_vN->data_float3(); 00185 int shader_id = 0; 00186 uint last_shader = -1; 00187 bool last_smooth = false; 00188 00189 size_t triangles_size = triangles.size(); 00190 uint *shader_ptr = (shader.size())? &shader[0]: NULL; 00191 00192 for(size_t i = 0; i < triangles_size; i++) { 00193 normal[i].x = fN[i].x; 00194 normal[i].y = fN[i].y; 00195 normal[i].z = fN[i].z; 00196 00197 /* stuff shader id in here too */ 00198 if(shader_ptr[i] != last_shader || last_smooth != smooth[i]) { 00199 last_shader = shader_ptr[i]; 00200 last_smooth = smooth[i]; 00201 shader_id = scene->shader_manager->get_shader_id(last_shader, this, last_smooth); 00202 } 00203 00204 normal[i].w = __int_as_float(shader_id); 00205 } 00206 00207 size_t verts_size = verts.size(); 00208 00209 for(size_t i = 0; i < verts_size; i++) 00210 vnormal[i] = make_float4(vN[i].x, vN[i].y, vN[i].z, 0.0f); 00211 } 00212 00213 void Mesh::pack_verts(float4 *tri_verts, float4 *tri_vindex, size_t vert_offset) 00214 { 00215 size_t verts_size = verts.size(); 00216 00217 if(verts_size) { 00218 float3 *verts_ptr = &verts[0]; 00219 00220 for(size_t i = 0; i < verts_size; i++) { 00221 float3 p = verts_ptr[i]; 00222 tri_verts[i] = make_float4(p.x, p.y, p.z, 0.0f); 00223 } 00224 } 00225 00226 size_t triangles_size = triangles.size(); 00227 00228 if(triangles_size) { 00229 Triangle *triangles_ptr = &triangles[0]; 00230 00231 for(size_t i = 0; i < triangles_size; i++) { 00232 Triangle t = triangles_ptr[i]; 00233 00234 tri_vindex[i] = make_float4( 00235 __int_as_float(t.v[0] + vert_offset), 00236 __int_as_float(t.v[1] + vert_offset), 00237 __int_as_float(t.v[2] + vert_offset), 00238 0); 00239 } 00240 } 00241 } 00242 00243 void Mesh::compute_bvh(SceneParams *params, Progress& progress) 00244 { 00245 Object object; 00246 object.mesh = this; 00247 00248 vector<Object*> objects; 00249 objects.push_back(&object); 00250 00251 if(bvh && !need_update_rebuild) { 00252 progress.set_substatus("Refitting BVH"); 00253 bvh->objects = objects; 00254 bvh->refit(progress); 00255 } 00256 else { 00257 progress.set_substatus("Building BVH"); 00258 00259 BVHParams bparams; 00260 bparams.use_cache = params->use_bvh_cache; 00261 bparams.use_spatial_split = params->use_bvh_spatial_split; 00262 bparams.use_qbvh = params->use_qbvh; 00263 00264 delete bvh; 00265 bvh = BVH::create(bparams, objects); 00266 bvh->build(progress); 00267 } 00268 } 00269 00270 void Mesh::tag_update(Scene *scene, bool rebuild) 00271 { 00272 need_update = true; 00273 00274 if(rebuild) { 00275 need_update_rebuild = true; 00276 scene->light_manager->need_update = true; 00277 } 00278 else { 00279 foreach(uint sindex, used_shaders) 00280 if(scene->shaders[sindex]->has_surface_emission) 00281 scene->light_manager->need_update = true; 00282 } 00283 00284 scene->mesh_manager->need_update = true; 00285 scene->object_manager->need_update = true; 00286 } 00287 00288 /* Mesh Manager */ 00289 00290 MeshManager::MeshManager() 00291 { 00292 bvh = NULL; 00293 need_update = true; 00294 } 00295 00296 MeshManager::~MeshManager() 00297 { 00298 delete bvh; 00299 } 00300 00301 void MeshManager::update_osl_attributes(Device *device, Scene *scene, vector<AttributeRequestSet>& mesh_attributes) 00302 { 00303 #ifdef WITH_OSL 00304 /* for OSL, a hash map is used to lookup the attribute by name. */ 00305 OSLGlobals *og = (OSLGlobals*)device->osl_memory(); 00306 00307 og->object_name_map.clear(); 00308 og->attribute_map.clear(); 00309 00310 og->attribute_map.resize(scene->objects.size()); 00311 00312 for(size_t i = 0; i < scene->objects.size(); i++) { 00313 /* set object name to object index map */ 00314 Object *object = scene->objects[i]; 00315 og->object_name_map[object->name] = i; 00316 00317 /* set object attributes */ 00318 foreach(ParamValue& attr, object->attributes) { 00319 OSLGlobals::Attribute osl_attr; 00320 00321 osl_attr.type = attr.type(); 00322 osl_attr.elem = ATTR_ELEMENT_VALUE; 00323 osl_attr.value = attr; 00324 00325 og->attribute_map[i][attr.name()] = osl_attr; 00326 } 00327 00328 /* find mesh attributes */ 00329 size_t j; 00330 00331 for(j = 0; j < scene->meshes.size(); j++) 00332 if(scene->meshes[j] == object->mesh) 00333 break; 00334 00335 AttributeRequestSet& attributes = mesh_attributes[j]; 00336 00337 /* set object attributes */ 00338 foreach(AttributeRequest& req, attributes.requests) { 00339 OSLGlobals::Attribute osl_attr; 00340 00341 osl_attr.elem = req.element; 00342 osl_attr.offset = req.offset; 00343 00344 if(req.type == TypeDesc::TypeFloat) 00345 osl_attr.type = TypeDesc::TypeFloat; 00346 else 00347 osl_attr.type = TypeDesc::TypeColor; 00348 00349 if(req.std != Attribute::STD_NONE) { 00350 /* if standard attribute, add lookup by std:: name convention */ 00351 ustring stdname = ustring(string("std::") + Attribute::standard_name(req.std).c_str()); 00352 og->attribute_map[i][stdname] = osl_attr; 00353 } 00354 else if(req.name != ustring()) { 00355 /* add lookup by mesh attribute name */ 00356 og->attribute_map[i][req.name] = osl_attr; 00357 } 00358 } 00359 } 00360 #endif 00361 } 00362 00363 void MeshManager::update_svm_attributes(Device *device, DeviceScene *dscene, Scene *scene, vector<AttributeRequestSet>& mesh_attributes) 00364 { 00365 /* for SVM, the attributes_map table is used to lookup the offset of an 00366 * attribute, based on a unique shader attribute id. */ 00367 00368 /* compute array stride */ 00369 int attr_map_stride = 0; 00370 00371 for(size_t i = 0; i < scene->meshes.size(); i++) 00372 attr_map_stride = max(attr_map_stride, mesh_attributes[i].size()); 00373 00374 if(attr_map_stride == 0) 00375 return; 00376 00377 /* create attribute map */ 00378 uint4 *attr_map = dscene->attributes_map.resize(attr_map_stride*scene->objects.size()); 00379 memset(attr_map, 0, dscene->attributes_map.size()*sizeof(uint)); 00380 00381 for(size_t i = 0; i < scene->objects.size(); i++) { 00382 Object *object = scene->objects[i]; 00383 00384 /* find mesh attributes */ 00385 size_t j; 00386 00387 for(j = 0; j < scene->meshes.size(); j++) 00388 if(scene->meshes[j] == object->mesh) 00389 break; 00390 00391 AttributeRequestSet& attributes = mesh_attributes[j]; 00392 00393 /* set object attributes */ 00394 j = 0; 00395 00396 foreach(AttributeRequest& req, attributes.requests) { 00397 int index = i*attr_map_stride + j; 00398 uint id; 00399 00400 if(req.std == Attribute::STD_NONE) 00401 id = scene->shader_manager->get_attribute_id(req.name); 00402 else 00403 id = scene->shader_manager->get_attribute_id(req.std); 00404 00405 attr_map[index].x = id; 00406 attr_map[index].y = req.element; 00407 attr_map[index].z = req.offset; 00408 00409 if(req.type == TypeDesc::TypeFloat) 00410 attr_map[index].w = NODE_ATTR_FLOAT; 00411 else 00412 attr_map[index].w = NODE_ATTR_FLOAT3; 00413 00414 j++; 00415 } 00416 } 00417 00418 /* copy to device */ 00419 dscene->data.bvh.attributes_map_stride = attr_map_stride; 00420 device->tex_alloc("__attributes_map", dscene->attributes_map); 00421 } 00422 00423 void MeshManager::device_update_attributes(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress) 00424 { 00425 progress.set_status("Updating Mesh", "Computing attributes"); 00426 00427 /* gather per mesh requested attributes. as meshes may have multiple 00428 * shaders assigned, this merges the requested attributes that have 00429 * been set per shader by the shader manager */ 00430 vector<AttributeRequestSet> mesh_attributes(scene->meshes.size()); 00431 00432 for(size_t i = 0; i < scene->meshes.size(); i++) { 00433 Mesh *mesh = scene->meshes[i]; 00434 00435 foreach(uint sindex, mesh->used_shaders) { 00436 Shader *shader = scene->shaders[sindex]; 00437 mesh_attributes[i].add(shader->attributes); 00438 } 00439 } 00440 00441 /* mesh attribute are stored in a single array per data type. here we fill 00442 * those arrays, and set the offset and element type to create attribute 00443 * maps next */ 00444 vector<float> attr_float; 00445 vector<float4> attr_float3; 00446 00447 for(size_t i = 0; i < scene->meshes.size(); i++) { 00448 Mesh *mesh = scene->meshes[i]; 00449 AttributeRequestSet& attributes = mesh_attributes[i]; 00450 00451 /* todo: we now store std and name attributes from requests even if 00452 they actually refer to the same mesh attributes, optimize */ 00453 foreach(AttributeRequest& req, attributes.requests) { 00454 Attribute *mattr = mesh->attributes.find(req); 00455 00456 /* todo: get rid of this exception */ 00457 if(!mattr && req.std == Attribute::STD_GENERATED) { 00458 mattr = mesh->attributes.add(Attribute::STD_GENERATED); 00459 if(mesh->verts.size()) 00460 memcpy(mattr->data_float3(), &mesh->verts[0], sizeof(float3)*mesh->verts.size()); 00461 } 00462 00463 /* attribute not found */ 00464 if(!mattr) { 00465 req.element = ATTR_ELEMENT_NONE; 00466 req.offset = 0; 00467 continue; 00468 } 00469 00470 /* we abuse AttributeRequest to pass on info like element and 00471 offset, it doesn't really make sense but is convenient */ 00472 00473 /* store element and type */ 00474 if(mattr->element == Attribute::VERTEX) 00475 req.element = ATTR_ELEMENT_VERTEX; 00476 else if(mattr->element == Attribute::FACE) 00477 req.element = ATTR_ELEMENT_FACE; 00478 else if(mattr->element == Attribute::CORNER) 00479 req.element = ATTR_ELEMENT_CORNER; 00480 00481 req.type = mattr->type; 00482 00483 /* store attribute data in arrays */ 00484 size_t size = mattr->element_size(mesh->verts.size(), mesh->triangles.size()); 00485 00486 if(mattr->type == TypeDesc::TypeFloat) { 00487 float *data = mattr->data_float(); 00488 req.offset = attr_float.size(); 00489 00490 for(size_t k = 0; k < size; k++) 00491 attr_float.push_back(data[k]); 00492 } 00493 else { 00494 float3 *data = mattr->data_float3(); 00495 req.offset = attr_float3.size(); 00496 00497 for(size_t k = 0; k < size; k++) { 00498 float3 f3 = data[k]; 00499 float4 f4 = make_float4(f3.x, f3.y, f3.z, 0.0f); 00500 00501 attr_float3.push_back(f4); 00502 } 00503 } 00504 00505 /* mesh vertex/triangle index is global, not per object, so we sneak 00506 a correction for that in here */ 00507 if(req.element == ATTR_ELEMENT_VERTEX) 00508 req.offset -= mesh->vert_offset; 00509 else if(mattr->element == Attribute::FACE) 00510 req.offset -= mesh->tri_offset; 00511 else if(mattr->element == Attribute::CORNER) 00512 req.offset -= 3*mesh->tri_offset; 00513 00514 if(progress.get_cancel()) return; 00515 } 00516 } 00517 00518 /* create attribute lookup maps */ 00519 if(scene->params.shadingsystem == SceneParams::OSL) 00520 update_osl_attributes(device, scene, mesh_attributes); 00521 else 00522 update_svm_attributes(device, dscene, scene, mesh_attributes); 00523 00524 if(progress.get_cancel()) return; 00525 00526 /* copy to device */ 00527 progress.set_status("Updating Mesh", "Copying Attributes to device"); 00528 00529 if(attr_float.size()) { 00530 dscene->attributes_float.copy(&attr_float[0], attr_float.size()); 00531 device->tex_alloc("__attributes_float", dscene->attributes_float); 00532 } 00533 if(attr_float3.size()) { 00534 dscene->attributes_float3.copy(&attr_float3[0], attr_float3.size()); 00535 device->tex_alloc("__attributes_float3", dscene->attributes_float3); 00536 } 00537 } 00538 00539 void MeshManager::device_update_mesh(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress) 00540 { 00541 /* count and update offsets */ 00542 size_t vert_size = 0; 00543 size_t tri_size = 0; 00544 00545 foreach(Mesh *mesh, scene->meshes) { 00546 mesh->vert_offset = vert_size; 00547 mesh->tri_offset = tri_size; 00548 00549 vert_size += mesh->verts.size(); 00550 tri_size += mesh->triangles.size(); 00551 } 00552 00553 if(tri_size == 0) 00554 return; 00555 00556 /* normals */ 00557 progress.set_status("Updating Mesh", "Computing normals"); 00558 00559 float4 *normal = dscene->tri_normal.resize(tri_size); 00560 float4 *vnormal = dscene->tri_vnormal.resize(vert_size); 00561 float4 *tri_verts = dscene->tri_verts.resize(vert_size); 00562 float4 *tri_vindex = dscene->tri_vindex.resize(tri_size); 00563 00564 foreach(Mesh *mesh, scene->meshes) { 00565 mesh->pack_normals(scene, &normal[mesh->tri_offset], &vnormal[mesh->vert_offset]); 00566 mesh->pack_verts(&tri_verts[mesh->vert_offset], &tri_vindex[mesh->tri_offset], mesh->vert_offset); 00567 00568 if(progress.get_cancel()) return; 00569 } 00570 00571 /* vertex coordinates */ 00572 progress.set_status("Updating Mesh", "Copying Mesh to device"); 00573 00574 device->tex_alloc("__tri_normal", dscene->tri_normal); 00575 device->tex_alloc("__tri_vnormal", dscene->tri_vnormal); 00576 device->tex_alloc("__tri_verts", dscene->tri_verts); 00577 device->tex_alloc("__tri_vindex", dscene->tri_vindex); 00578 } 00579 00580 void MeshManager::device_update_bvh(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress) 00581 { 00582 /* bvh build */ 00583 progress.set_status("Updating Scene BVH", "Building"); 00584 00585 BVHParams bparams; 00586 bparams.top_level = true; 00587 bparams.use_qbvh = scene->params.use_qbvh; 00588 bparams.use_spatial_split = scene->params.use_bvh_spatial_split; 00589 bparams.use_cache = scene->params.use_bvh_cache; 00590 00591 delete bvh; 00592 bvh = BVH::create(bparams, scene->objects); 00593 bvh->build(progress); 00594 00595 if(progress.get_cancel()) return; 00596 00597 /* copy to device */ 00598 progress.set_status("Updating Scene BVH", "Copying BVH to device"); 00599 00600 PackedBVH& pack = bvh->pack; 00601 00602 if(pack.nodes.size()) { 00603 dscene->bvh_nodes.reference((float4*)&pack.nodes[0], pack.nodes.size()); 00604 device->tex_alloc("__bvh_nodes", dscene->bvh_nodes); 00605 } 00606 if(pack.object_node.size()) { 00607 dscene->object_node.reference((uint*)&pack.object_node[0], pack.object_node.size()); 00608 device->tex_alloc("__object_node", dscene->object_node); 00609 } 00610 if(pack.tri_woop.size()) { 00611 dscene->tri_woop.reference(&pack.tri_woop[0], pack.tri_woop.size()); 00612 device->tex_alloc("__tri_woop", dscene->tri_woop); 00613 } 00614 if(pack.prim_visibility.size()) { 00615 dscene->prim_visibility.reference((uint*)&pack.prim_visibility[0], pack.prim_visibility.size()); 00616 device->tex_alloc("__prim_visibility", dscene->prim_visibility); 00617 } 00618 if(pack.prim_index.size()) { 00619 dscene->prim_index.reference((uint*)&pack.prim_index[0], pack.prim_index.size()); 00620 device->tex_alloc("__prim_index", dscene->prim_index); 00621 } 00622 if(pack.prim_object.size()) { 00623 dscene->prim_object.reference((uint*)&pack.prim_object[0], pack.prim_object.size()); 00624 device->tex_alloc("__prim_object", dscene->prim_object); 00625 } 00626 00627 dscene->data.bvh.root = pack.root_index; 00628 } 00629 00630 void MeshManager::device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress) 00631 { 00632 if(!need_update) 00633 return; 00634 00635 /* update normals */ 00636 foreach(Mesh *mesh, scene->meshes) { 00637 foreach(uint shader, mesh->used_shaders) 00638 if(scene->shaders[shader]->need_update_attributes) 00639 mesh->need_update = true; 00640 00641 if(mesh->need_update) { 00642 mesh->add_face_normals(); 00643 mesh->add_vertex_normals(); 00644 00645 if(progress.get_cancel()) return; 00646 } 00647 } 00648 00649 /* device update */ 00650 device_free(device, dscene); 00651 00652 device_update_mesh(device, dscene, scene, progress); 00653 if(progress.get_cancel()) return; 00654 00655 device_update_attributes(device, dscene, scene, progress); 00656 if(progress.get_cancel()) return; 00657 00658 /* update displacement */ 00659 bool displacement_done = false; 00660 00661 foreach(Mesh *mesh, scene->meshes) 00662 if(mesh->need_update && displace(device, scene, mesh, progress)) 00663 displacement_done = true; 00664 00665 /* todo: properly handle cancel halfway displacement */ 00666 if(progress.get_cancel()) return; 00667 00668 /* device re-update after displacement */ 00669 if(displacement_done) { 00670 device_free(device, dscene); 00671 00672 device_update_mesh(device, dscene, scene, progress); 00673 if(progress.get_cancel()) return; 00674 00675 device_update_attributes(device, dscene, scene, progress); 00676 if(progress.get_cancel()) return; 00677 } 00678 00679 /* update bvh */ 00680 size_t i = 0, num_instance_bvh = 0; 00681 00682 foreach(Mesh *mesh, scene->meshes) 00683 if(mesh->need_update && !mesh->transform_applied) 00684 num_instance_bvh++; 00685 00686 foreach(Mesh *mesh, scene->meshes) { 00687 if(mesh->need_update) { 00688 mesh->compute_bounds(); 00689 00690 if(!mesh->transform_applied) { 00691 string msg = "Updating Mesh BVH "; 00692 if(mesh->name == "") 00693 msg += string_printf("%u/%u", (uint)(i+1), (uint)num_instance_bvh); 00694 else 00695 msg += string_printf("%s %u/%u", mesh->name.c_str(), (uint)(i+1), (uint)num_instance_bvh); 00696 progress.set_status(msg, "Building BVH"); 00697 00698 mesh->compute_bvh(&scene->params, progress); 00699 } 00700 00701 if(progress.get_cancel()) return; 00702 00703 mesh->need_update = false; 00704 mesh->need_update_rebuild = false; 00705 } 00706 00707 i++; 00708 } 00709 00710 foreach(Shader *shader, scene->shaders) 00711 shader->need_update_attributes = false; 00712 00713 foreach(Object *object, scene->objects) 00714 object->compute_bounds(); 00715 00716 if(progress.get_cancel()) return; 00717 00718 device_update_bvh(device, dscene, scene, progress); 00719 00720 need_update = false; 00721 } 00722 00723 void MeshManager::device_free(Device *device, DeviceScene *dscene) 00724 { 00725 device->tex_free(dscene->bvh_nodes); 00726 device->tex_free(dscene->object_node); 00727 device->tex_free(dscene->tri_woop); 00728 device->tex_free(dscene->prim_visibility); 00729 device->tex_free(dscene->prim_index); 00730 device->tex_free(dscene->prim_object); 00731 device->tex_free(dscene->tri_normal); 00732 device->tex_free(dscene->tri_vnormal); 00733 device->tex_free(dscene->tri_vindex); 00734 device->tex_free(dscene->tri_verts); 00735 device->tex_free(dscene->attributes_map); 00736 device->tex_free(dscene->attributes_float); 00737 device->tex_free(dscene->attributes_float3); 00738 00739 dscene->bvh_nodes.clear(); 00740 dscene->object_node.clear(); 00741 dscene->tri_woop.clear(); 00742 dscene->prim_visibility.clear(); 00743 dscene->prim_index.clear(); 00744 dscene->prim_object.clear(); 00745 dscene->tri_normal.clear(); 00746 dscene->tri_vnormal.clear(); 00747 dscene->tri_vindex.clear(); 00748 dscene->tri_verts.clear(); 00749 dscene->attributes_map.clear(); 00750 dscene->attributes_float.clear(); 00751 dscene->attributes_float3.clear(); 00752 } 00753 00754 void MeshManager::tag_update(Scene *scene) 00755 { 00756 need_update = true; 00757 scene->object_manager->need_update = true; 00758 } 00759 00760 CCL_NAMESPACE_END 00761