void BVH::build(Progress& progress) { progress.set_substatus("Building BVH"); /* build nodes */ BVHBuild bvh_build(objects, pack.prim_type, pack.prim_index, pack.prim_object, params, progress); BVHNode *root = bvh_build.run(); if(progress.get_cancel()) { if(root) root->deleteSubtree(); return; } /* pack triangles */ progress.set_substatus("Packing BVH triangles and strands"); pack_primitives(); if(progress.get_cancel()) { root->deleteSubtree(); return; } /* pack nodes */ progress.set_substatus("Packing BVH nodes"); pack_nodes(root); /* free build nodes */ root->deleteSubtree(); }
void BVH::refit(Progress& progress) { progress.set_substatus("Packing BVH primitives"); pack_primitives(); if(progress.get_cancel()) return; progress.set_substatus("Refitting BVH nodes"); refit_nodes(); }
void ImageManager::device_update(Device *device, DeviceScene *dscene, Progress& progress) { if(!need_update) return; for(size_t slot = 0; slot < images.size(); slot++) { if(images[slot]) { if(images[slot]->users == 0) { device_free_image(device, dscene, slot); } else if(images[slot]->need_load) { string name = path_filename(images[slot]->filename); progress.set_status("Updating Images", "Loading " + name); device_load_image(device, dscene, slot); images[slot]->need_load = false; } if(progress.get_cancel()) return; } } for(size_t slot = 0; slot < float_images.size(); slot++) { if(float_images[slot]) { if(float_images[slot]->users == 0) { device_free_image(device, dscene, slot + TEX_IMAGE_FLOAT_START); } else if(float_images[slot]->need_load) { string name = path_filename(float_images[slot]->filename); progress.set_status("Updating Images", "Loading " + name); device_load_image(device, dscene, slot + TEX_IMAGE_FLOAT_START); float_images[slot]->need_load = false; } if(progress.get_cancel()) return; } } need_update = false; }
void CurveSystemManager::device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress) { if(!need_update) return; device_free(device, dscene); progress.set_status("Updating Hair settings", "Copying Hair settings to device"); KernelCurves *kcurve= &dscene->data.curve_kernel_data; kcurve->curveflags = 0; if(use_curves) { if(primitive == CURVE_SEGMENTS || primitive == CURVE_RIBBONS) kcurve->curveflags |= CURVE_KN_INTERPOLATE; if(primitive == CURVE_RIBBONS) kcurve->curveflags |= CURVE_KN_RIBBONS; if(line_method == CURVE_ACCURATE) kcurve->curveflags |= CURVE_KN_ACCURATE; if(line_method == CURVE_CORRECTED) kcurve->curveflags |= CURVE_KN_INTERSECTCORRECTION; if(line_method == CURVE_POSTCORRECTED) kcurve->curveflags |= CURVE_KN_POSTINTERSECTCORRECTION; if(use_tangent_normal) kcurve->curveflags |= CURVE_KN_TANGENTGNORMAL; if(use_tangent_normal_correction) kcurve->curveflags |= CURVE_KN_NORMALCORRECTION; if(use_tangent_normal_geometry) kcurve->curveflags |= CURVE_KN_TRUETANGENTGNORMAL; if(use_joined) kcurve->curveflags |= CURVE_KN_CURVEDATA; if(use_backfacing) kcurve->curveflags |= CURVE_KN_BACKFACING; if(use_encasing) kcurve->curveflags |= CURVE_KN_ENCLOSEFILTER; kcurve->normalmix = normalmix; kcurve->encasing_ratio = encasing_ratio; kcurve->subdivisions = subdivisions; } if(progress.get_cancel()) return; need_update = false; }
void Scene::device_update(Device *device_, Progress& progress) { if(!device) device = device_; /* The order of updates is important, because there's dependencies between * the different managers, using data computed by previous managers. * * - Background generates shader graph compiled by shader manager. * - Image manager uploads images used by shaders. * - Camera may be used for adapative subdivison. * - Displacement shader must have all shader data available. * - Light manager needs final mesh data to compute emission CDF. */ progress.set_status("Updating Background"); background->device_update(device, &dscene, this); if(progress.get_cancel()) return; progress.set_status("Updating Shaders"); shader_manager->device_update(device, &dscene, this, progress); if(progress.get_cancel()) return; progress.set_status("Updating Images"); image_manager->device_update(device, &dscene, progress); if(progress.get_cancel()) return; progress.set_status("Updating Camera"); camera->device_update(device, &dscene); if(progress.get_cancel()) return; progress.set_status("Updating Objects"); object_manager->device_update(device, &dscene, this, progress); if(progress.get_cancel()) return; progress.set_status("Updating Meshes"); mesh_manager->device_update(device, &dscene, this, progress); if(progress.get_cancel()) return; progress.set_status("Updating Lights"); light_manager->device_update(device, &dscene, this, progress); if(progress.get_cancel()) return; progress.set_status("Updating Filter"); filter->device_update(device, &dscene); if(progress.get_cancel()) return; progress.set_status("Updating Integrator"); integrator->device_update(device, &dscene); if(progress.get_cancel()) return; progress.set_status("Updating Film"); film->device_update(device, &dscene); if(progress.get_cancel()) return; progress.set_status("Updating Device", "Writing constant memory"); device->const_copy_to("__data", &dscene.data, sizeof(dscene.data)); }
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Update all (already compiled) scene meshes on render-server (finally sends one LOAD_MESH packet for global mesh and one for each scattered mesh) ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void MeshManager::server_update_mesh(::OctaneEngine::OctaneClient *server, Scene *scene, Progress& progress, uint32_t frame_idx, uint32_t total_frames) { if(!need_update) return; if(total_frames <= 1) need_update = false; progress.set_status("Loading Meshes to render-server", ""); uint64_t ulGlobalCnt = 0; uint64_t ulLocalCnt = 0; uint64_t ulLocalVdbCnt = 0; bool global_update = false; if(need_global_update) { global_update = need_global_update; need_global_update = false; } vector<Mesh*>::iterator it; for(it = scene->meshes.begin(); it != scene->meshes.end(); ++it) { Mesh *mesh = *it; if(mesh->empty) { if(mesh->need_update) mesh->need_update = false; continue; } else if(scene->meshes_type == Mesh::GLOBAL || (scene->meshes_type == Mesh::AS_IS && mesh->mesh_type == Mesh::GLOBAL)) { if(mesh->vdb_regular_grid) ++ulLocalVdbCnt; else if(total_frames <= 1 && (scene->first_frame || scene->anim_mode == FULL)) { ++ulGlobalCnt; if(mesh->need_update && !global_update) global_update = true; } continue; } if(!mesh->need_update || (!scene->first_frame && (scene->anim_mode == CAM_ONLY || (scene->anim_mode == MOVABLE_PROXIES && scene->meshes_type != Mesh::RESHAPABLE_PROXY && (scene->meshes_type != Mesh::AS_IS || mesh->mesh_type != Mesh::RESHAPABLE_PROXY))))) continue; if(mesh->vdb_regular_grid) ++ulLocalVdbCnt; else ++ulLocalCnt; if(progress.get_cancel()) return; } bool interrupted = false; if(ulLocalCnt) { char **mesh_names = new char*[ulLocalCnt]; uint64_t *used_shaders_size = new uint64_t[ulLocalCnt]; uint64_t *used_objects_size = new uint64_t[ulLocalCnt]; vector<string> *shader_names = new vector<string>[ulLocalCnt]; vector<string> *object_names = new vector<string>[ulLocalCnt]; float3 **points = new float3*[ulLocalCnt]; uint64_t *points_size = new uint64_t[ulLocalCnt]; float3 **normals = new float3*[ulLocalCnt]; uint64_t *normals_size = new uint64_t[ulLocalCnt]; int **points_indices = new int*[ulLocalCnt]; int **normals_indices = new int*[ulLocalCnt]; uint64_t *points_indices_size = new uint64_t[ulLocalCnt]; uint64_t *normals_indices_size = new uint64_t[ulLocalCnt]; int **vert_per_poly = new int*[ulLocalCnt]; uint64_t *vert_per_poly_size = new uint64_t[ulLocalCnt]; int **poly_mat_index = new int*[ulLocalCnt]; int **poly_obj_index = new int*[ulLocalCnt]; float3 **uvs = new float3*[ulLocalCnt]; uint64_t *uvs_size = new uint64_t[ulLocalCnt]; int **uv_indices = new int*[ulLocalCnt]; uint64_t *uv_indices_size = new uint64_t[ulLocalCnt]; bool *open_subd_enable = new bool[ulLocalCnt]; int32_t *open_subd_scheme = new int32_t[ulLocalCnt]; int32_t *open_subd_level = new int32_t[ulLocalCnt]; float *open_subd_sharpness = new float[ulLocalCnt]; int32_t *open_subd_bound_interp = new int32_t[ulLocalCnt]; uint64_t *open_subd_crease_indices_cnt = new uint64_t[ulLocalCnt]; int **open_subd_crease_indices = new int*[ulLocalCnt]; float **open_subd_crease_sharpnesses = new float*[ulLocalCnt]; float *general_vis = new float[ulLocalCnt]; bool *cam_vis = new bool[ulLocalCnt]; bool *shadow_vis = new bool[ulLocalCnt]; int32_t *rand_color_seed = new int32_t[ulLocalCnt]; bool *reshapable = new bool[ulLocalCnt]; int32_t *layer_number = new int32_t[ulLocalCnt]; int32_t *baking_group_id = new int32_t[ulLocalCnt]; float *max_smooth_angle = new float[ulLocalCnt]; float3 **hair_points = new float3*[ulLocalCnt]; uint64_t *hair_points_size = new uint64_t[ulLocalCnt]; uint64_t *hair_ws_size = new uint64_t[ulLocalCnt]; int32_t **vert_per_hair = new int32_t*[ulLocalCnt]; uint64_t *vert_per_hair_size = new uint64_t[ulLocalCnt]; float **hair_thickness = new float*[ulLocalCnt]; int32_t **hair_mat_indices = new int32_t*[ulLocalCnt]; float2 **hair_uvs = new float2*[ulLocalCnt]; float2 **hair_ws = new float2*[ulLocalCnt]; int32_t *hair_interpolation = new int32_t[ulLocalCnt]; uint64_t i = 0; vector<Mesh*>::iterator it; for(it = scene->meshes.begin(); it != scene->meshes.end(); ++it) { Mesh *mesh = *it; if(mesh->vdb_regular_grid) continue; if(mesh->empty || !mesh->need_update || (scene->meshes_type == Mesh::GLOBAL || (scene->meshes_type == Mesh::AS_IS && mesh->mesh_type == Mesh::GLOBAL)) || (!scene->first_frame && (scene->anim_mode == CAM_ONLY || (scene->anim_mode == MOVABLE_PROXIES && scene->meshes_type != Mesh::RESHAPABLE_PROXY && (scene->meshes_type != Mesh::AS_IS || mesh->mesh_type != Mesh::RESHAPABLE_PROXY))))) continue; if(scene->meshes_type == Mesh::SCATTER || (scene->meshes_type == Mesh::AS_IS && mesh->mesh_type == Mesh::SCATTER)) progress.set_status("Loading Meshes to render-server", string("Scatter: ") + mesh->nice_name.c_str()); else if(scene->meshes_type == Mesh::MOVABLE_PROXY || (scene->meshes_type == Mesh::AS_IS && mesh->mesh_type == Mesh::MOVABLE_PROXY)) progress.set_status("Loading Meshes to render-server", string("Movable: ") + mesh->nice_name.c_str()); else if(scene->meshes_type == Mesh::RESHAPABLE_PROXY || (scene->meshes_type == Mesh::AS_IS && mesh->mesh_type == Mesh::RESHAPABLE_PROXY)) progress.set_status("Loading Meshes to render-server", string("Reshapable: ") + mesh->nice_name.c_str()); used_shaders_size[i] = mesh->used_shaders.size(); for(size_t n=0; n<used_shaders_size[i]; ++n) { shader_names[i].push_back(scene->shaders[mesh->used_shaders[n]]->name); } used_objects_size[i] = 1; object_names[i].push_back("__" + mesh->name); mesh_names[i] = (char*)mesh->name.c_str(); points[i] = &mesh->points[0]; points_size[i] = mesh->points.size(); normals[i] = &mesh->normals[0]; normals_size[i] = mesh->normals.size(); points_indices[i] = &mesh->points_indices[0]; normals_indices[i] = &mesh->points_indices[0]; points_indices_size[i] = mesh->points_indices.size(); normals_indices_size[i] = 0;//mesh->points_indices.size(); vert_per_poly[i] = &mesh->vert_per_poly[0]; vert_per_poly_size[i] = mesh->vert_per_poly.size(); poly_mat_index[i] = &mesh->poly_mat_index[0]; poly_obj_index[i] = &mesh->poly_obj_index[0]; uvs[i] = &mesh->uvs[0]; uvs_size[i] = mesh->uvs.size(); uv_indices[i] = &mesh->uv_indices[0]; uv_indices_size[i] = mesh->uv_indices.size(); open_subd_enable[i] = mesh->open_subd_enable; open_subd_scheme[i] = mesh->open_subd_scheme; open_subd_level[i] = mesh->open_subd_level; open_subd_sharpness[i] = mesh->open_subd_sharpness; open_subd_bound_interp[i] = mesh->open_subd_bound_interp; open_subd_crease_indices_cnt[i] = mesh->open_subd_crease_indices.size() / 2; if(open_subd_crease_indices_cnt[i]) { open_subd_crease_indices[i] = &mesh->open_subd_crease_indices[0]; open_subd_crease_sharpnesses[i] = &mesh->open_subd_crease_sharpnesses[0]; } else { open_subd_crease_indices[i] = nullptr; open_subd_crease_sharpnesses[i] = nullptr; } general_vis[i] = mesh->vis_general; cam_vis[i] = mesh->vis_cam; shadow_vis[i] = mesh->vis_shadow; rand_color_seed[i] = mesh->rand_color_seed; reshapable[i] = (scene->meshes_type == Mesh::RESHAPABLE_PROXY || (scene->meshes_type == Mesh::AS_IS && mesh->mesh_type == Mesh::RESHAPABLE_PROXY)); layer_number[i] = (scene->kernel->oct_node->bLayersEnable ? mesh->layer_number : 1); baking_group_id[i] = mesh->baking_group_id; max_smooth_angle[i] = mesh->max_smooth_angle; hair_points_size[i] = mesh->hair_points.size(); hair_ws_size[i] = mesh->hair_interpolation == (int32_t)::Octane::HairInterpolationType::HAIR_INTERP_NONE ? mesh->hair_ws.size() : 0; hair_points[i] = hair_points_size[i] ? &mesh->hair_points[0] : 0; vert_per_hair_size[i] = mesh->vert_per_hair.size(); vert_per_hair[i] = vert_per_hair_size[i] ? &mesh->vert_per_hair[0] : 0; hair_thickness[i] = hair_points_size[i] ? &mesh->hair_thickness[0] : 0; hair_mat_indices[i] = vert_per_hair_size[i] ? &mesh->hair_mat_indices[0] : 0; hair_uvs[i] = vert_per_hair_size[i] ? &mesh->hair_uvs[0] : 0; hair_ws[i] = hair_ws_size[i] ? &mesh->hair_ws[0] : 0; hair_interpolation[i] = mesh->hair_interpolation == (int32_t)::Octane::HairInterpolationType::HAIR_INTERP_NONE ? (int32_t)::Octane::HairInterpolationType::HAIR_INTERP_DEFAULT : mesh->hair_interpolation; if(mesh->need_update && (total_frames <= 1 || !reshapable[i])) mesh->need_update = false; if(progress.get_cancel()) { interrupted = true; break; } ++i; } if(i && !interrupted) { progress.set_status("Loading Meshes to render-server", "Transferring..."); server->uploadMesh(false, frame_idx, total_frames, ulLocalCnt, mesh_names, used_shaders_size, used_objects_size, shader_names, object_names, (::OctaneEngine::float_3**)points, points_size, (::OctaneEngine::float_3**)normals, normals_size, points_indices, normals_indices, points_indices_size, normals_indices_size, vert_per_poly, vert_per_poly_size, poly_mat_index, poly_obj_index, (::OctaneEngine::float_3**)uvs, uvs_size, uv_indices, uv_indices_size, (::OctaneEngine::float_3**)hair_points, hair_points_size, hair_ws_size, vert_per_hair, vert_per_hair_size, hair_thickness, hair_mat_indices, (::OctaneEngine::float_2**)hair_uvs, (::OctaneEngine::float_2**)hair_ws, hair_interpolation, open_subd_enable, open_subd_scheme, open_subd_level, open_subd_sharpness, open_subd_bound_interp, open_subd_crease_indices_cnt, open_subd_crease_indices, open_subd_crease_sharpnesses, layer_number, baking_group_id, general_vis, cam_vis, shadow_vis, rand_color_seed, reshapable, max_smooth_angle); } delete[] mesh_names; delete[] used_shaders_size; delete[] used_objects_size; delete[] shader_names; delete[] object_names; delete[] points; delete[] points_size; delete[] normals; delete[] normals_size; delete[] points_indices; delete[] normals_indices; delete[] points_indices_size; delete[] normals_indices_size; delete[] vert_per_poly; delete[] vert_per_poly_size; delete[] poly_mat_index; delete[] poly_obj_index; delete[] uvs; delete[] uvs_size; delete[] uv_indices; delete[] uv_indices_size; delete[] open_subd_enable; delete[] open_subd_scheme; delete[] open_subd_level; delete[] open_subd_sharpness; delete[] open_subd_bound_interp; delete[] open_subd_crease_indices_cnt; delete[] open_subd_crease_indices; delete[] open_subd_crease_sharpnesses; delete[] general_vis; delete[] cam_vis; delete[] shadow_vis; delete[] rand_color_seed; delete[] reshapable; delete[] layer_number; delete[] baking_group_id; delete[] max_smooth_angle; delete[] hair_interpolation; delete[] hair_points_size; delete[] hair_ws_size; delete[] vert_per_hair_size; delete[] hair_points; delete[] vert_per_hair; delete[] hair_thickness; delete[] hair_mat_indices; delete[] hair_uvs; delete[] hair_ws; } if(ulLocalVdbCnt && !interrupted) { uint64_t i = 0; vector<Mesh*>::iterator it; for(it = scene->meshes.begin(); it != scene->meshes.end(); ++it) { Mesh *mesh = *it; if(!mesh->vdb_regular_grid) continue; if(mesh->empty || !mesh->need_update //|| (scene->meshes_type == Mesh::GLOBAL || (scene->meshes_type == Mesh::AS_IS && mesh->mesh_type == Mesh::GLOBAL)) || (!scene->first_frame && (scene->anim_mode == CAM_ONLY || (scene->anim_mode == MOVABLE_PROXIES && scene->meshes_type != Mesh::RESHAPABLE_PROXY && (scene->meshes_type != Mesh::AS_IS || mesh->mesh_type != Mesh::RESHAPABLE_PROXY))))) continue; if(scene->meshes_type == Mesh::SCATTER || scene->meshes_type == Mesh::GLOBAL || scene->meshes_type == Mesh::GLOBAL || (scene->meshes_type == Mesh::AS_IS && mesh->mesh_type == Mesh::SCATTER)) progress.set_status("Loading Volumes to render-server", string("Scatter: ") + mesh->nice_name.c_str()); else if(scene->meshes_type == Mesh::MOVABLE_PROXY || (scene->meshes_type == Mesh::AS_IS && mesh->mesh_type == Mesh::MOVABLE_PROXY)) progress.set_status("Loading Volumes to render-server", string("Movable: ") + mesh->nice_name.c_str()); else if(scene->meshes_type == Mesh::RESHAPABLE_PROXY || (scene->meshes_type == Mesh::AS_IS && mesh->mesh_type == Mesh::RESHAPABLE_PROXY)) progress.set_status("Loading Volumes to render-server", string("Reshapable: ") + mesh->nice_name.c_str()); ::OctaneEngine::OctaneVolume volume; volume.sName = mesh->name; volume.pfRegularGrid = mesh->vdb_regular_grid; volume.iGridSize = mesh->vdb_grid_size; volume.f3Resolution = {mesh->vdb_resolution.x, mesh->vdb_resolution.y, mesh->vdb_resolution.z}; volume.gridMatrix = mesh->vdb_grid_matrix; volume.fISO = mesh->vdb_iso; volume.iAbsorptionOffset = mesh->vdb_absorption_offset; volume.fAbsorptionScale = mesh->vdb_absorption_scale; volume.iEmissionOffset = mesh->vdb_emission_offset; volume.fEmissionScale = mesh->vdb_emission_scale; volume.iScatterOffset = mesh->vdb_scatter_offset; volume.fScatterScale = mesh->vdb_scatter_scale; volume.iVelocityOffsetX = mesh->vdb_velocity_x_offset; volume.iVelocityOffsetY = mesh->vdb_velocity_y_offset; volume.iVelocityOffsetZ = mesh->vdb_velocity_z_offset; volume.fVelocityScale = mesh->vdb_velocity_scale; volume.fGenVisibility = mesh->vis_general; volume.bCamVisibility = mesh->vis_cam; volume.bShadowVisibility = mesh->vis_shadow; volume.iRandomColorSeed = mesh->rand_color_seed; volume.iLayerNumber = (scene->kernel->oct_node->bLayersEnable ? mesh->layer_number : 1); volume.iBakingGroupId = mesh->baking_group_id; if(mesh->used_shaders.size()) volume.sMedium = scene->shaders[mesh->used_shaders[0]]->name; if(mesh->need_update && (total_frames <= 1 || !(scene->meshes_type == Mesh::RESHAPABLE_PROXY || (scene->meshes_type == Mesh::AS_IS && mesh->mesh_type == Mesh::RESHAPABLE_PROXY)))) mesh->need_update = false; if(progress.get_cancel()) { interrupted = true; break; } ++i; progress.set_status("Loading Volumes to render-server", "Transferring..."); server->uploadVolume(&volume); } } if(global_update && !interrupted) { progress.set_status("Loading global Mesh to render-server", ""); uint64_t obj_cnt = 0; for(map<std::string, vector<Object*> >::const_iterator obj_it = scene->objects.begin(); obj_it != scene->objects.end(); ++obj_it) { Mesh* mesh = obj_it->second.size() > 0 ? obj_it->second[0]->mesh : 0; if(mesh->vdb_regular_grid) continue; if(!mesh || mesh->empty || (!scene->first_frame && scene->anim_mode != FULL) || (scene->meshes_type == Mesh::SCATTER || scene->meshes_type == Mesh::MOVABLE_PROXY || scene->meshes_type == Mesh::RESHAPABLE_PROXY) || (scene->meshes_type == Mesh::AS_IS && mesh->mesh_type != Mesh::GLOBAL)) continue; for(vector<Object*>::const_iterator it = obj_it->second.begin(); it != obj_it->second.end(); ++it) { Object *mesh_object = *it; if(!mesh_object->visibility) continue; ++obj_cnt; } } char* name = "__global"; if(obj_cnt > 0) { uint64_t *used_shaders_size = new uint64_t[obj_cnt]; uint64_t *used_objects_size = new uint64_t[obj_cnt]; vector<string> *shader_names = new vector<string>[obj_cnt]; vector<string> *object_names = new vector<string>[obj_cnt]; float3 **points = new float3*[obj_cnt]; for(int k = 0; k < obj_cnt; ++k) points[k] = 0; uint64_t *points_size = new uint64_t[obj_cnt]; float3 **normals = new float3*[obj_cnt]; for(int k = 0; k < obj_cnt; ++k) normals[k] = 0; uint64_t *normals_size = new uint64_t[obj_cnt]; int **points_indices = new int*[obj_cnt]; int **normals_indices = new int*[obj_cnt]; uint64_t *points_indices_size = new uint64_t[obj_cnt]; uint64_t *normals_indices_size = new uint64_t[obj_cnt]; int **vert_per_poly = new int*[obj_cnt]; uint64_t *vert_per_poly_size = new uint64_t[obj_cnt]; int **poly_mat_index = new int*[obj_cnt]; int **poly_obj_index = new int*[obj_cnt]; float3 **uvs = new float3*[obj_cnt]; uint64_t *uvs_size = new uint64_t[obj_cnt]; int **uv_indices = new int*[obj_cnt]; uint64_t *uv_indices_size = new uint64_t[obj_cnt]; bool *open_subd_enable = new bool[obj_cnt]; int32_t *open_subd_scheme = new int32_t[obj_cnt]; int32_t *open_subd_level = new int32_t[obj_cnt]; float *open_subd_sharpness = new float[obj_cnt]; int32_t *open_subd_bound_interp = new int32_t[obj_cnt]; uint64_t *open_subd_crease_indices_cnt = new uint64_t[obj_cnt]; int **open_subd_crease_indices = new int*[obj_cnt]; float **open_subd_crease_sharpnesses = new float*[obj_cnt]; float *general_vis = new float[obj_cnt]; bool *cam_vis = new bool[obj_cnt]; bool *shadow_vis = new bool[obj_cnt]; int32_t *rand_color_seed = new int32_t[obj_cnt]; bool *reshapable = new bool[obj_cnt]; int32_t *layer_number = new int32_t[obj_cnt]; int32_t *baking_group_id = new int32_t[obj_cnt]; float *max_smooth_angle = new float[obj_cnt]; float3 **hair_points = new float3*[obj_cnt]; uint64_t *hair_points_size = new uint64_t[obj_cnt]; uint64_t *hair_ws_size = new uint64_t[obj_cnt]; int32_t **vert_per_hair = new int32_t*[obj_cnt]; uint64_t *vert_per_hair_size = new uint64_t[obj_cnt]; float **hair_thickness = new float*[obj_cnt]; int32_t **hair_mat_indices = new int32_t*[obj_cnt]; float2 **hair_uvs = new float2*[obj_cnt]; int32_t *hair_interpolation = new int32_t[obj_cnt]; float2 **hair_ws = new float2*[obj_cnt]; obj_cnt = 0; bool hair_present = false; for(map<std::string, vector<Object*> >::const_iterator obj_it = scene->objects.begin(); obj_it != scene->objects.end(); ++obj_it) { Mesh* mesh = obj_it->second.size() > 0 ? obj_it->second[0]->mesh : 0; if(mesh->vdb_regular_grid) continue; if(!mesh || mesh->empty || (!scene->first_frame && scene->anim_mode != FULL) || (scene->meshes_type == Mesh::SCATTER || scene->meshes_type == Mesh::MOVABLE_PROXY || scene->meshes_type == Mesh::RESHAPABLE_PROXY) || (scene->meshes_type == Mesh::AS_IS && mesh->mesh_type != oct::Mesh::GLOBAL)) continue; for(vector<Object*>::const_iterator it = obj_it->second.begin(); it != obj_it->second.end(); ++it) { Object *mesh_object = *it; if(!mesh_object->visibility) continue; Transform &tfm = mesh_object->tfm; used_shaders_size[obj_cnt] = mesh_object->used_shaders.size(); for(size_t n=0; n<used_shaders_size[obj_cnt]; ++n) { shader_names[obj_cnt].push_back(scene->shaders[mesh_object->used_shaders[n]]->name); } used_objects_size[obj_cnt] = 1; object_names[obj_cnt].push_back("__" + mesh->name); size_t points_cnt = mesh->points.size(); points[obj_cnt] = new float3[points_cnt]; float3 *p = &mesh->points[0]; for(size_t k=0; k<points_cnt; ++k) points[obj_cnt][k] = transform_point(&tfm, p[k]); points_size[obj_cnt] = points_cnt; size_t norm_cnt = mesh->normals.size(); normals[obj_cnt] = new float3[norm_cnt]; float3 *n = &mesh->normals[0]; for(size_t k=0; k<norm_cnt; ++k) normals[obj_cnt][k] = transform_direction(&tfm, n[k]); normals_size[obj_cnt] = norm_cnt; points_indices[obj_cnt] = &mesh->points_indices[0]; normals_indices[obj_cnt] = &mesh->points_indices[0]; points_indices_size[obj_cnt] = mesh->points_indices.size(); normals_indices_size[obj_cnt] = 0; vert_per_poly[obj_cnt] = &mesh->vert_per_poly[0]; vert_per_poly_size[obj_cnt] = mesh->vert_per_poly.size(); poly_mat_index[obj_cnt] = &mesh->poly_mat_index[0]; poly_obj_index[obj_cnt] = &mesh->poly_obj_index[0]; uvs[obj_cnt] = &mesh->uvs[0]; uvs_size[obj_cnt] = mesh->uvs.size(); uv_indices[obj_cnt] = &mesh->uv_indices[0]; uv_indices_size[obj_cnt] = mesh->uv_indices.size(); open_subd_enable[obj_cnt] = mesh->open_subd_enable; open_subd_scheme[obj_cnt] = mesh->open_subd_scheme; open_subd_level[obj_cnt] = mesh->open_subd_level; open_subd_sharpness[obj_cnt] = mesh->open_subd_sharpness; open_subd_bound_interp[obj_cnt] = mesh->open_subd_bound_interp; open_subd_crease_indices_cnt[obj_cnt] = mesh->open_subd_crease_indices.size() / 2; if(open_subd_crease_indices_cnt[obj_cnt]) { open_subd_crease_indices[obj_cnt] = &mesh->open_subd_crease_indices[0]; open_subd_crease_sharpnesses[obj_cnt] = &mesh->open_subd_crease_sharpnesses[0]; } else { open_subd_crease_indices[obj_cnt] = nullptr; open_subd_crease_sharpnesses[obj_cnt] = nullptr; } general_vis[obj_cnt] = mesh->vis_general; cam_vis[obj_cnt] = mesh->vis_cam; shadow_vis[obj_cnt] = mesh->vis_shadow; rand_color_seed[obj_cnt] = mesh->rand_color_seed; reshapable[obj_cnt] = false; layer_number[obj_cnt] = (scene->kernel->oct_node->bLayersEnable ? mesh->layer_number : 1); baking_group_id[obj_cnt] = mesh->baking_group_id; max_smooth_angle[obj_cnt] = mesh->max_smooth_angle; hair_points_size[obj_cnt] = mesh->hair_points.size(); hair_ws_size[obj_cnt] = mesh->hair_interpolation == (int32_t)::Octane::HairInterpolationType::HAIR_INTERP_NONE ? mesh->hair_ws.size() : 0; hair_points[obj_cnt] = hair_points_size[obj_cnt] ? &mesh->hair_points[0] : 0; vert_per_hair_size[obj_cnt] = mesh->vert_per_hair.size(); vert_per_hair[obj_cnt] = vert_per_hair_size[obj_cnt] ? &mesh->vert_per_hair[0] : 0; hair_thickness[obj_cnt] = hair_points_size[obj_cnt] ? &mesh->hair_thickness[0] : 0; hair_mat_indices[obj_cnt] = vert_per_hair_size[obj_cnt] ? &mesh->hair_mat_indices[0] : 0; hair_uvs[obj_cnt] = vert_per_hair_size[obj_cnt] ? &mesh->hair_uvs[0] : 0; hair_interpolation[obj_cnt] = mesh->hair_interpolation == (int32_t)::Octane::HairInterpolationType::HAIR_INTERP_NONE ? (int32_t)::Octane::HairInterpolationType::HAIR_INTERP_DEFAULT : mesh->hair_interpolation; hair_ws[obj_cnt] = hair_ws_size[obj_cnt] ? &mesh->hair_ws[0] : 0; if(mesh->need_update) mesh->need_update = false; if(progress.get_cancel()) { interrupted = true; break; } ++obj_cnt; if(!hair_present && mesh->hair_points.size()) hair_present = true; } } if(obj_cnt && !interrupted) { if(hair_present) fprintf(stderr, "Octane: WARNING: hair can't be rendered on \"Global\" mesh\n"); progress.set_status("Loading global Mesh to render-server", string("Transferring...")); server->uploadMesh(true, frame_idx, total_frames, obj_cnt, &name, used_shaders_size, used_objects_size, shader_names, object_names, (::OctaneEngine::float_3**)points, points_size, (::OctaneEngine::float_3**)normals, normals_size, points_indices, normals_indices, points_indices_size, normals_indices_size, vert_per_poly, vert_per_poly_size, poly_mat_index, poly_obj_index, (::OctaneEngine::float_3**)uvs, uvs_size, uv_indices, uv_indices_size, (::OctaneEngine::float_3**)hair_points, hair_points_size, hair_ws_size, vert_per_hair, vert_per_hair_size, hair_thickness, hair_mat_indices, (::OctaneEngine::float_2**)hair_uvs, (::OctaneEngine::float_2**)hair_ws, hair_interpolation, open_subd_enable, open_subd_scheme, open_subd_level, open_subd_sharpness, open_subd_bound_interp, open_subd_crease_indices_cnt, open_subd_crease_indices, open_subd_crease_sharpnesses, layer_number, baking_group_id, general_vis, cam_vis, shadow_vis, rand_color_seed, reshapable, max_smooth_angle); server->uploadLayerMap(true, "__global_lm", name, static_cast< ::OctaneEngine::int32_t>(obj_cnt), layer_number, baking_group_id, general_vis, cam_vis, shadow_vis, static_cast< ::OctaneEngine::int32_t*>(rand_color_seed)); } delete[] used_shaders_size; delete[] used_objects_size; delete[] shader_names; delete[] object_names; for(int k = 0; k < obj_cnt; ++k) { if(points[k]) delete[] points[k]; } delete[] points; delete[] points_size; for(int k = 0; k < obj_cnt; ++k) { if(normals[k]) delete[] normals[k]; } delete[] normals; delete[] normals_size; delete[] points_indices; delete[] normals_indices; delete[] points_indices_size; delete[] normals_indices_size; delete[] vert_per_poly; delete[] vert_per_poly_size; delete[] poly_mat_index; delete[] poly_obj_index; delete[] uvs; delete[] uvs_size; delete[] uv_indices; delete[] uv_indices_size; delete[] open_subd_enable; delete[] open_subd_scheme; delete[] open_subd_level; delete[] open_subd_sharpness; delete[] open_subd_bound_interp; delete[] open_subd_crease_indices_cnt; delete[] open_subd_crease_indices; delete[] open_subd_crease_sharpnesses; delete[] general_vis; delete[] cam_vis; delete[] shadow_vis; delete[] rand_color_seed; delete[] reshapable; delete[] layer_number; delete[] baking_group_id; delete[] max_smooth_angle; delete[] hair_points_size; delete[] hair_ws_size; delete[] vert_per_hair_size; delete[] hair_points; delete[] vert_per_hair; delete[] hair_thickness; delete[] hair_mat_indices; delete[] hair_uvs; delete[] hair_ws; delete[] hair_interpolation; } else ulGlobalCnt = 0; } std::string cur_name("__global"); if(!ulGlobalCnt && scene->anim_mode == FULL) server->deleteMesh(true, cur_name); //need_update = false; } //server_update_mesh()
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Load transforms to render-server ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void ObjectManager::server_update(::OctaneEngine::OctaneClient *server, Scene *scene, Progress& progress, uint32_t frame_idx, uint32_t total_frames) { if(!need_update) return; if(total_frames <= 1) need_update = false; if(scene->objects.size()) { progress.set_status("Updating Objects", "Copying Transformations to server"); if(progress.get_cancel()) return; for(map<std::string, vector<Object*> >::const_iterator mesh_it = scene->objects.begin(); mesh_it != scene->objects.end(); ++mesh_it) { uint64_t cur_size = mesh_it->second.size(); if(!cur_size) continue; Mesh* cur_mesh = mesh_it->second[0]->mesh; bool movable = (scene->meshes_type == Mesh::MOVABLE_PROXY || scene->meshes_type == Mesh::RESHAPABLE_PROXY || (scene->meshes_type == Mesh::AS_IS && (cur_mesh->mesh_type == Mesh::MOVABLE_PROXY || cur_mesh->mesh_type == Mesh::RESHAPABLE_PROXY))); if((scene->meshes_type == Mesh::GLOBAL || (scene->meshes_type == Mesh::AS_IS && cur_mesh->mesh_type == Mesh::GLOBAL)) || (!scene->first_frame && (scene->anim_mode == CAM_ONLY || (scene->anim_mode == MOVABLE_PROXIES && scene->meshes_type != Mesh::RESHAPABLE_PROXY && scene->meshes_type != Mesh::MOVABLE_PROXY && (scene->meshes_type != Mesh::AS_IS || (cur_mesh->mesh_type != Mesh::RESHAPABLE_PROXY && cur_mesh->mesh_type != Mesh::MOVABLE_PROXY)))))) continue; uint64_t particles_cnt = 0; map<int, Object*> particles_map; float* matrices = new float[12]; bool mesh_needs_update = false; for(vector<Object*>::const_iterator it = mesh_it->second.begin(); it != mesh_it->second.end(); ++it) { Object* object = *it; if(object->particle_id) { if(object->need_update && !mesh_needs_update) mesh_needs_update = true; ++particles_cnt; particles_map.insert(map<int, Object*>::value_type(object->particle_id, object)); continue; } if(object->need_update) { if(total_frames <= 1 || !movable) object->need_update = false; } else continue; vector<string> shader_names; shader_names.reserve(object->used_shaders.size()); for(vector<uint>::iterator it = object->used_shaders.begin(); it != object->used_shaders.end(); ++it) { shader_names.push_back(scene->shaders[*it]->name); } unsigned long i = 0; matrices[i++] = object->tfm.x.x; matrices[i++] = object->tfm.x.y; matrices[i++] = object->tfm.x.z; matrices[i++] = object->tfm.x.w; matrices[i++] = object->tfm.y.x; matrices[i++] = object->tfm.y.y; matrices[i++] = object->tfm.y.z; matrices[i++] = object->tfm.y.w; matrices[i++] = object->tfm.z.x; matrices[i++] = object->tfm.z.y; matrices[i++] = object->tfm.z.z; matrices[i++] = object->tfm.z.w; std::string cur_object_name(object->name.c_str()); cur_object_name = cur_object_name + "__" + cur_mesh->name.c_str(); std::string cur_mesh_name(cur_mesh->name.c_str()); if(object->visibility) server->uploadScatter(cur_object_name, cur_mesh_name, matrices, 1, movable, shader_names, frame_idx, total_frames); else { string scatter_name = cur_object_name + "_s__"; server->deleteScatter(scatter_name); } } //for(vector<Object*>::const_iterator it = mesh_it->second.begin(); it != mesh_it->second.end(); ++it) delete[] matrices; if(mesh_needs_update && particles_cnt) { float* matrices = new float[particles_cnt * 12]; vector<string> shader_names; shader_names.reserve(cur_mesh->used_shaders.size()); for(vector<uint>::iterator it = cur_mesh->used_shaders.begin(); it != cur_mesh->used_shaders.end(); ++it) { shader_names.push_back(scene->shaders[*it]->name); } bool visibility = true; unsigned long i = 0; for(map<int, Object*>::const_iterator it = particles_map.begin(); it != particles_map.end(); ++it) { Object* object = it->second; if(!object->particle_id) { continue; } if(object->need_update) { if(total_frames <= 1 || !movable) object->need_update = false; } if(!object->visibility && visibility) visibility = false; matrices[i++] = object->tfm.x.x; matrices[i++] = object->tfm.x.y; matrices[i++] = object->tfm.x.z; matrices[i++] = object->tfm.x.w; matrices[i++] = object->tfm.y.x; matrices[i++] = object->tfm.y.y; matrices[i++] = object->tfm.y.z; matrices[i++] = object->tfm.y.w; matrices[i++] = object->tfm.z.x; matrices[i++] = object->tfm.z.y; matrices[i++] = object->tfm.z.z; matrices[i++] = object->tfm.z.w; } //for(vector<Object*>::const_iterator it = mesh_it->second.begin(); it != mesh_it->second.end(); ++it) std::string cur_mesh_name(cur_mesh->name.c_str()); std::string cur_part_name = cur_mesh_name + "__part__"; if(visibility) server->uploadScatter(cur_part_name, cur_mesh_name, matrices, particles_cnt, movable, shader_names, frame_idx, total_frames); else { string scatter_name = cur_part_name + "_s__"; server->deleteScatter(scatter_name); } delete[] matrices; } //if(mesh_needs_update) server->load_scatter(scatter_names, string(cur_mesh->name.c_str()), matrices, shader_names); } //for(map<std::string, vector<Object*> >::const_iterator mesh_it = scene->objects.begin(); mesh_it != scene->objects.end(); ++mesh_it) } //if(scene->objects.size()) if(scene->light_objects.size()) { progress.set_status("Updating Lamp Objects", "Copying Transformations to server"); if(progress.get_cancel()) return; for(map<std::string, vector<Object*> >::const_iterator light_it = scene->light_objects.begin(); light_it != scene->light_objects.end(); ++light_it) { uint64_t cur_size = light_it->second.size(); if(!cur_size) continue; Light* cur_light = light_it->second[0]->light; if(cur_light->type != Light::LIGHT_AREA) continue; if((scene->meshes_type == Mesh::GLOBAL || (scene->meshes_type == Mesh::AS_IS && cur_light->mesh->mesh_type == Mesh::GLOBAL)) || (!scene->first_frame && (scene->anim_mode == CAM_ONLY || (scene->anim_mode == MOVABLE_PROXIES && scene->meshes_type != Mesh::RESHAPABLE_PROXY && scene->meshes_type != Mesh::MOVABLE_PROXY && (scene->meshes_type != Mesh::AS_IS || (cur_light->mesh->mesh_type != Mesh::RESHAPABLE_PROXY && cur_light->mesh->mesh_type != Mesh::MOVABLE_PROXY)))))) continue; size_t cnt = 0;//light_it->second.size(); float* matrices = new float[12]; vector<string> shader_names; shader_names.push_back("__" + cur_light->nice_name); bool movable = (scene->meshes_type == Mesh::MOVABLE_PROXY || scene->meshes_type == Mesh::RESHAPABLE_PROXY || (scene->meshes_type == Mesh::AS_IS && (cur_light->mesh->mesh_type == Mesh::MOVABLE_PROXY || cur_light->mesh->mesh_type == Mesh::RESHAPABLE_PROXY))); bool mesh_needs_update = false; for(vector<Object*>::const_iterator it = light_it->second.begin(); it != light_it->second.end(); ++it) { Object* object = *it; if(object->need_update) { if(total_frames <= 1 || !movable) object->need_update = false; if(!mesh_needs_update) mesh_needs_update = true; } unsigned long i = 0; matrices[i++] = object->tfm.x.x; matrices[i++] = object->tfm.x.y; matrices[i++] = object->tfm.x.z; matrices[i++] = object->tfm.x.w; matrices[i++] = object->tfm.y.x; matrices[i++] = object->tfm.y.y; matrices[i++] = object->tfm.y.z; matrices[i++] = object->tfm.y.w; matrices[i++] = object->tfm.z.x; matrices[i++] = object->tfm.z.y; matrices[i++] = object->tfm.z.z; matrices[i++] = object->tfm.z.w; std::string cur_scatter_name(object->name.c_str()); std::string cur_light_name(cur_light->name.c_str()); cur_scatter_name = cur_scatter_name + "__" + cur_light_name; if(mesh_needs_update && object->visibility) server->uploadScatter(cur_scatter_name, cur_light_name, matrices, 1, movable, shader_names, frame_idx, total_frames); else if(mesh_needs_update && !object->visibility) { string scatter_name = cur_scatter_name + "_s__"; server->deleteScatter(scatter_name); } } //for(vector<Object*>::const_iterator it = light_it->second.begin(); it != light_it->second.end(); ++it) //if(mesh_needs_update) server->load_scatter(scatter_names, string(cur_light->name.c_str()), matrices, particles_cnt, shader_names); delete[] matrices; } //for(map<std::string, vector<Object*> >::const_iterator light_it = scene->light_objects.begin(); light_it != scene->light_objects.end(); ++light_it) } //if(scene->light_objects.size()) //need_update = false; } //server_update()