float3 Camera::transform_raster_to_world(float raster_x, float raster_y) { float3 D, P; if(type == CAMERA_PERSPECTIVE) { D = transform_perspective(&rastertocamera, make_float3(raster_x, raster_y, 0.0f)); float3 Pclip = normalize(D); P = make_float3(0.0f, 0.0f, 0.0f); /* TODO(sergey): Aperture support? */ P = transform_point(&cameratoworld, P); D = normalize(transform_direction(&cameratoworld, D)); /* TODO(sergey): Clipping is conditional in kernel, and hence it could * be mistakes in here, currently leading to wrong camera-in-volume * detection. */ P += nearclip * D / Pclip.z; } else if(type == CAMERA_ORTHOGRAPHIC) { D = make_float3(0.0f, 0.0f, 1.0f); /* TODO(sergey): Aperture support? */ P = transform_perspective(&rastertocamera, make_float3(raster_x, raster_y, 0.0f)); P = transform_point(&cameratoworld, P); D = normalize(transform_direction(&cameratoworld, D)); } else { assert(!"unsupported camera type"); } return P; }
float Camera::world_to_raster_size(float3 P) { if(type == CAMERA_ORTHOGRAPHIC) { return min(len(full_dx), len(full_dy)); } else if(type == CAMERA_PERSPECTIVE) { /* Calculate as if point is directly ahead of the camera. */ float3 raster = make_float3(0.5f*width, 0.5f*height, 0.0f); float3 Pcamera = transform_perspective(&rastertocamera, raster); /* dDdx */ float3 Ddiff = transform_direction(&cameratoworld, Pcamera); float3 dx = len_squared(full_dx) < len_squared(full_dy) ? full_dx : full_dy; float3 dDdx = normalize(Ddiff + dx) - normalize(Ddiff); /* dPdx */ float dist = len(transform_point(&worldtocamera, P)); float3 D = normalize(Ddiff); return len(dist*dDdx - dot(dist*dDdx, D)*D); } else { // TODO(mai): implement for CAMERA_PANORAMA assert(!"pixel width calculation for panoramic projection not implemented yet"); } return 1.0f; }
// \en Calculates intersections. Stores intersection info to intersections and returns the number of intersections.\enden \ja 交点計算を行う。交点の情報はintersectionsに格納し、交点の数を返す。 \endja // \en The ray is defined as the starting point o and the normalized direction vector d as in o + td, 0.0 <= t.\enden \ja レイは始点位置ベクトルo、単位方向ベクトルdから成る、o + td, 0.0 <= t として指定される。 \endja int attribute_component::ray_intersection (const sxsdk::custom_element_info_base_class *info, sxsdk::shape_class &shape, const sxsdk::mat4 &lw, const sxsdk::mat4 &wl, int i, const sx::vec<float,3> &o, const sx::vec<float,3> &d, sxsdk::intersection_class intersections[], sxsdk::custom_element_info_base_class *per_thread, void *) { { custom_element_info__class *info = dynamic_cast<custom_element_info__class *>(per_thread); if (info) { for (int i = 0; i < 100; i++) info->data[i] = i; } } int n = 0; sxsdk::sphere_class &sphere = shape.get_sphere(); if (info) { // \en Fetch the data created in the new_custom_element_info function.\enden \ja new_custom_element_infoで作成したデータを取得する。 \endja const float size = dynamic_cast<const custom_size_class &>(*info).size; sxsdk::mat4 t = sphere.get_matrix(); for (int i = 0; i < 3; i++) for (int j = 0; j < 3; j++) t[i][j] *= size; t *= lw; sxsdk::mat4 itrans = inv(t); sx::vec<float,3> p2 = o * itrans; // \en Transform the starting point of the ray to the sphere primitive coordinates.\enden \ja レイの始点位置ベクトルを球プリミティブ座標系に変換する。 \endja sx::vec<float,3> d2 = transform_direction(d, itrans); // \en Transform the normalized direction vector of the ray to the sphere primitive coordinates.\enden \ja レイの単位方向ベクトルを球プリミティブ座標系に変換する。 \endja // \en Calculate the intersections between the sphere and the ray.\enden \ja 球とレイの交点計算。 \endja float a = d2.x * d2.x + d2.y * d2.y + d2.z * d2.z; float b = p2.x * d2.x + p2.y * d2.y + p2.z * d2.z; float c = p2.x * p2.x + p2.y * p2.y + p2.z * p2.z - 1.0f; float k = b*b - a*c; if (k <= 0.0f) ; else { k = sqrt(k); float t1 = (-b + k) / a; float t0 = (-b - k) / a; //sxassert(t0 <= t1); if (0.0f <= t0) { intersections[n].t = t0; sx::vec<float,3> normal = p2 + d2 * t0; intersections[n].normal = normalize(transform_normal(itrans, normal)); intersections[n].point = o + d * t0; // \en Merge Info.\enden \ja 融合情報 \endja if (shape.has_sis()) { intersections[n].number_of_shapes = 2; //sxassert(intersections[n].shape_mixes); intersections[n].shape_mixes[1] = sxsdk::shape_mix_class(0.5f, shape.get_sis()); intersections[n].shape_mixes[0] = sxsdk::shape_mix_class(0.5f, &shape); } n++; } if (0.0f <= t1) { intersections[n].t = t1; sx::vec<float,3> normal = p2 + d2 * t1; intersections[n].normal = normalize(transform_normal(itrans, normal)); intersections[n].point = o + d * t1; // \en Merge Info.\enden \ja 融合情報 \endja if (shape.has_sis()) { intersections[n].number_of_shapes = 2; //sxassert(intersections[n].shape_mixes); intersections[n].shape_mixes[1] = sxsdk::shape_mix_class(0.5f, shape.get_sis()); intersections[n].shape_mixes[0] = sxsdk::shape_mix_class(0.5f, &shape); } n++; } } } return n; }
void Camera::update() { if(!need_update) return; /* Full viewport to camera border in the viewport. */ Transform fulltoborder = transform_from_viewplane(viewport_camera_border); Transform bordertofull = transform_inverse(fulltoborder); /* ndc to raster */ Transform screentocamera; Transform ndctoraster = transform_scale(width, height, 1.0f) * bordertofull; /* raster to screen */ Transform screentondc = fulltoborder * transform_from_viewplane(viewplane); Transform screentoraster = ndctoraster * screentondc; Transform rastertoscreen = transform_inverse(screentoraster); /* screen to camera */ if(type == CAMERA_PERSPECTIVE) screentocamera = transform_inverse(transform_perspective(fov, nearclip, farclip)); else if(type == CAMERA_ORTHOGRAPHIC) screentocamera = transform_inverse(transform_orthographic(nearclip, farclip)); else screentocamera = transform_identity(); Transform cameratoscreen = transform_inverse(screentocamera); rastertocamera = screentocamera * rastertoscreen; cameratoraster = screentoraster * cameratoscreen; cameratoworld = matrix; screentoworld = cameratoworld * screentocamera; rastertoworld = cameratoworld * rastertocamera; ndctoworld = rastertoworld * ndctoraster; /* note we recompose matrices instead of taking inverses of the above, this * is needed to avoid inverting near degenerate matrices that happen due to * precision issues with large scenes */ worldtocamera = transform_inverse(matrix); worldtoscreen = cameratoscreen * worldtocamera; worldtondc = screentondc * worldtoscreen; worldtoraster = ndctoraster * worldtondc; /* differentials */ if(type == CAMERA_ORTHOGRAPHIC) { dx = transform_direction(&rastertocamera, make_float3(1, 0, 0)); dy = transform_direction(&rastertocamera, make_float3(0, 1, 0)); } else if(type == CAMERA_PERSPECTIVE) { dx = transform_perspective(&rastertocamera, make_float3(1, 0, 0)) - transform_perspective(&rastertocamera, make_float3(0, 0, 0)); dy = transform_perspective(&rastertocamera, make_float3(0, 1, 0)) - transform_perspective(&rastertocamera, make_float3(0, 0, 0)); } else { dx = make_float3(0.0f, 0.0f, 0.0f); dy = make_float3(0.0f, 0.0f, 0.0f); } dx = transform_direction(&cameratoworld, dx); dy = transform_direction(&cameratoworld, dy); need_update = false; need_device_update = true; need_flags_update = true; }
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Fill the Octane Camera properties from Blender View data ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void BlenderSync::load_camera_from_view(Camera* cam, BL::Scene b_scene, BL::SpaceView3D b_v3d, BL::RegionView3D b_rv3d, int width, int height, float2& offset, bool skip_panorama) { float zoom; if(b_rv3d.view_perspective() == BL::RegionView3D::view_perspective_CAMERA) { BL::Object b_ob = (b_v3d.lock_camera_and_layers()) ? b_scene.camera() : b_v3d.camera(); if(b_ob) { cam->matrix = scene->matrix * get_transform(b_ob.matrix_world()); // Magic zoom formula zoom = (float) b_rv3d.view_camera_zoom(); zoom = (1.41421f + zoom/50.0f); zoom *= zoom; zoom = 2.0f/zoom; zoom *= 2.0f; cam->zoom = zoom; offset = get_float2(b_rv3d.view_camera_offset()); load_camera_from_object(cam, b_ob, width, height, offset, skip_panorama); } } //if(b_rv3d.view_perspective() == BL::RegionView3D::view_perspective_CAMERA) else if(b_rv3d.view_perspective() == BL::RegionView3D::view_perspective_ORTHO || b_rv3d.view_perspective() == BL::RegionView3D::view_perspective_PERSP) { cam->zoom = 2.0f; cam->near_clip_depth = b_v3d.clip_start(); cam->far_clip_depth = b_v3d.clip_end(); cam->matrix = scene->matrix * transform_inverse(get_transform(b_rv3d.view_matrix())); cam->type = CAMERA_PERSPECTIVE; if(b_rv3d.view_perspective() == BL::RegionView3D::view_perspective_ORTHO) cam->ortho = true; else cam->ortho = false; PointerRNA oct_camera = RNA_pointer_get(&b_scene.ptr, "oct_view_cam"); get_cam_settings(cam, oct_camera, true); cam->lens_shift_x = 0; cam->lens_shift_y = 0; cam->sensorwidth = 32.0f; cam->sensorheight = 18.0f; cam->sensor_fit = Camera::AUTO; if(cam->ortho) { float ortho_scale; get_viewport_ortho_scale(cam, b_rv3d.view_distance(), b_v3d.lens(), width, height, &ortho_scale); cam->fov = ortho_scale * cam->zoom; } else { float sensor_size; get_camera_sensor_size(cam, width, height, &sensor_size); cam->fov = 2.0f * atanf((0.5f * sensor_size * cam->zoom) / b_v3d.lens()) *180.0f / M_PI_F; } // Position cam->look_at.x = cam->eye_point.x = cam->matrix.x.w; cam->look_at.y = cam->eye_point.y = cam->matrix.y.w; cam->look_at.z = cam->eye_point.z = cam->matrix.z.w; if(cam->ortho) { float3 dir = transform_direction(&cam->matrix, make_float3(0.0f, 0.0f, b_rv3d.view_distance())); cam->eye_point.x = cam->eye_point.x + dir.x; cam->eye_point.y = cam->eye_point.y + dir.y; cam->eye_point.z = cam->eye_point.z + dir.z; } else { float3 dir = transform_direction(&cam->matrix, make_float3(0.0f, 0.0f, -1.0f)); cam->look_at.x = cam->look_at.x + dir.x; cam->look_at.y = cam->look_at.y + dir.y; cam->look_at.z = cam->look_at.z + dir.z; } cam->up = normalize(transform_direction(&cam->matrix, make_float3(0.0f, 1.0f, 0.0f))); } //else if(b_rv3d.view_perspective() == BL::RegionView3D::view_perspective_ORTHO || b_rv3d.view_perspective() == BL::RegionView3D::view_perspective_PERSP) get_camera_border(cam, b_v3d, b_rv3d, width, height); } //load_camera_from_view()
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Fill the Octane Camera properties from Blender data ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void BlenderSync::load_camera_from_object(Camera* cam, BL::Object b_ob, int width, int height, float2& offset, bool skip_panorama) { BL::ID b_ob_data = b_ob.data(); if(b_ob_data.is_a(&RNA_Camera)) { BL::Camera b_camera(b_ob_data); PointerRNA oct_camera = RNA_pointer_get(&b_camera.ptr, "octane"); switch(b_camera.type()) { case BL::Camera::type_ORTHO: cam->type = CAMERA_PERSPECTIVE; cam->ortho = true; break; case BL::Camera::type_PANO: if(!skip_panorama) cam->type = CAMERA_PANORAMA; else cam->type = CAMERA_PERSPECTIVE; cam->ortho = false; break; case BL::Camera::type_PERSP: default: cam->type = CAMERA_PERSPECTIVE; cam->ortho = false; break; } cam->near_clip_depth = b_camera.clip_start(); cam->far_clip_depth = b_camera.clip_end(); cam->set_focal_depth(b_ob, b_camera); get_cam_settings(cam, oct_camera); cam->lens_shift_x = b_camera.shift_x() / cam->zoom; cam->lens_shift_y = b_camera.shift_y() / cam->zoom; cam->sensorwidth = b_camera.sensor_width(); cam->sensorheight = b_camera.sensor_height(); cam->offset_x = offset.x * 2.0f / cam->zoom; cam->offset_y = offset.y * 2.0f / cam->zoom; if(b_camera.sensor_fit() == BL::Camera::sensor_fit_AUTO) cam->sensor_fit = Camera::AUTO; else if(b_camera.sensor_fit() == BL::Camera::sensor_fit_HORIZONTAL) cam->sensor_fit = Camera::HORIZONTAL; else cam->sensor_fit = Camera::VERTICAL; if(cam->ortho) { float ortho_scale; get_camera_ortho_scale(cam, b_camera, width, height, &ortho_scale); cam->fov = ortho_scale * cam->zoom; } else { float sensor_size; get_camera_sensor_size(cam, width, height, &sensor_size); cam->fov = 2.0f * atanf((0.5f * sensor_size * cam->zoom) / b_camera.lens()) *180.0f / M_PI_F; } // Position cam->eye_point.x = cam->matrix.x.w; cam->eye_point.y = cam->matrix.y.w; cam->eye_point.z = cam->matrix.z.w; float3 dir = transform_direction(&cam->matrix, make_float3(0.0f, 0.0f, -1.0f)); cam->look_at.x = cam->eye_point.x + dir.x; cam->look_at.y = cam->eye_point.y + dir.y; cam->look_at.z = cam->eye_point.z + dir.z; cam->up = normalize(transform_direction(&cam->matrix, make_float3(0.0f, 1.0f, 0.0f))); } else { //TODO: Implement it for Lamp } } //camera_from_object()
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // 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()