static void blender_camera_from_view(BlenderCamera *bcam, BL::RenderEngine b_engine, BL::Scene b_scene, BL::SpaceView3D b_v3d, BL::RegionView3D b_rv3d, int width, int height, bool skip_panorama = false) { /* 3d view parameters */ bcam->nearclip = b_v3d.clip_start(); bcam->farclip = b_v3d.clip_end(); bcam->lens = b_v3d.lens(); bcam->shuttertime = b_scene.render().motion_blur_shutter(); curvemapping_to_array(b_scene.render().motion_blur_shutter_curve(), bcam->shutter_curve, RAMP_TABLE_SIZE); if(b_rv3d.view_perspective() == BL::RegionView3D::view_perspective_CAMERA) { /* camera view */ BL::Object b_ob = (b_v3d.lock_camera_and_layers())? b_scene.camera(): b_v3d.camera(); if(b_ob) { blender_camera_from_object(bcam, b_engine, b_ob, skip_panorama); if(!skip_panorama && bcam->type == CAMERA_PANORAMA) { /* in panorama camera view, we map viewplane to camera border */ BoundBox2D view_box, cam_box; blender_camera_view_subset(b_engine, b_scene.render(), b_scene, b_ob, b_v3d, b_rv3d, width, height, &view_box, &cam_box); bcam->pano_viewplane = view_box.make_relative_to(cam_box); } else { /* magic zoom formula */ bcam->zoom = (float)b_rv3d.view_camera_zoom(); bcam->zoom = (1.41421f + bcam->zoom/50.0f); bcam->zoom *= bcam->zoom; bcam->zoom = 2.0f/bcam->zoom; /* offset */ bcam->offset = get_float2(b_rv3d.view_camera_offset()); } } } else if(b_rv3d.view_perspective() == BL::RegionView3D::view_perspective_ORTHO) { /* orthographic view */ bcam->farclip *= 0.5f; bcam->nearclip = -bcam->farclip; float sensor_size; if(bcam->sensor_fit == BlenderCamera::VERTICAL) sensor_size = bcam->sensor_height; else sensor_size = bcam->sensor_width; bcam->type = CAMERA_ORTHOGRAPHIC; bcam->ortho_scale = b_rv3d.view_distance() * sensor_size / b_v3d.lens(); } bcam->zoom *= 2.0f; /* 3d view transform */ bcam->matrix = transform_inverse(get_transform(b_rv3d.view_matrix())); }
static float blender_camera_focal_distance(BL::Object b_ob, BL::Camera b_camera) { BL::Object b_dof_object = b_camera.dof_object(); if(!b_dof_object) return b_camera.dof_distance(); /* for dof object, return distance along camera Z direction */ Transform obmat = transform_clear_scale(get_transform(b_ob.matrix_world())); Transform dofmat = get_transform(b_dof_object.matrix_world()); Transform mat = transform_inverse(obmat) * dofmat; return fabsf(transform_get_column(&mat, 3).z); }
static float blender_camera_focal_distance(BL::RenderEngine b_engine, BL::Object b_ob, BL::Camera b_camera) { BL::Object b_dof_object = b_camera.dof_object(); if(!b_dof_object) return b_camera.dof_distance(); /* for dof object, return distance along camera Z direction */ BL::Array<float, 16> b_ob_matrix; b_engine.camera_model_matrix(b_ob, b_ob_matrix); Transform obmat = get_transform(b_ob_matrix); Transform dofmat = get_transform(b_dof_object.matrix_world()); Transform mat = transform_inverse(obmat) * dofmat; return fabsf(transform_get_column(&mat, 3).z); }
void Camera::device_update(Device *device, DeviceScene *dscene, Scene *scene) { Scene::MotionType need_motion = scene->need_motion(device->info.advanced_shading); update(); if(previous_need_motion != need_motion) { /* scene's motion model could have been changed since previous device * camera update this could happen for example in case when one render * layer has got motion pass and another not */ need_device_update = true; } if(!need_device_update) return; KernelCamera *kcam = &dscene->data.cam; /* store matrices */ kcam->screentoworld = screentoworld; kcam->rastertoworld = rastertoworld; kcam->rastertocamera = rastertocamera; kcam->cameratoworld = cameratoworld; kcam->worldtocamera = worldtocamera; kcam->worldtoscreen = worldtoscreen; kcam->worldtoraster = worldtoraster; kcam->worldtondc = worldtondc; /* camera motion */ kcam->have_motion = 0; if(need_motion == Scene::MOTION_PASS) { if(type == CAMERA_PANORAMA) { if(use_motion) { kcam->motion.pre = transform_inverse(motion.pre); kcam->motion.post = transform_inverse(motion.post); } else { kcam->motion.pre = kcam->worldtocamera; kcam->motion.post = kcam->worldtocamera; } } else { if(use_motion) { kcam->motion.pre = cameratoraster * transform_inverse(motion.pre); kcam->motion.post = cameratoraster * transform_inverse(motion.post); } else { kcam->motion.pre = worldtoraster; kcam->motion.post = worldtoraster; } } } #ifdef __CAMERA_MOTION__ else if(need_motion == Scene::MOTION_BLUR) { if(use_motion) { transform_motion_decompose((DecompMotionTransform*)&kcam->motion, &motion, &matrix); kcam->have_motion = 1; } } #endif /* depth of field */ kcam->aperturesize = aperturesize; kcam->focaldistance = focaldistance; kcam->blades = (blades < 3)? 0.0f: blades; kcam->bladesrotation = bladesrotation; /* motion blur */ #ifdef __CAMERA_MOTION__ kcam->shuttertime = (need_motion == Scene::MOTION_BLUR) ? shuttertime: -1.0f; #else kcam->shuttertime = -1.0f; #endif /* type */ kcam->type = type; /* anamorphic lens bokeh */ kcam->inv_aperture_ratio = 1.0f / aperture_ratio; /* panorama */ kcam->panorama_type = panorama_type; kcam->fisheye_fov = fisheye_fov; kcam->fisheye_lens = fisheye_lens; kcam->equirectangular_range = make_float4(longitude_min - longitude_max, -longitude_min, latitude_min - latitude_max, -latitude_min + M_PI_2_F); /* sensor size */ kcam->sensorwidth = sensorwidth; kcam->sensorheight = sensorheight; /* render size */ kcam->width = width; kcam->height = height; kcam->resolution = resolution; /* store differentials */ kcam->dx = float3_to_float4(dx); kcam->dy = float3_to_float4(dy); /* clipping */ kcam->nearclip = nearclip; kcam->cliplength = (farclip == FLT_MAX)? FLT_MAX: farclip - nearclip; /* Camera in volume. */ kcam->is_inside_volume = 0; previous_need_motion = need_motion; }
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()
static ShaderNode *add_node(Scene *scene, BL::RenderEngine b_engine, BL::BlendData b_data, BL::Scene b_scene, const bool background, ShaderGraph *graph, BL::ShaderNodeTree b_ntree, BL::ShaderNode b_node) { ShaderNode *node = NULL; /* existing blender nodes */ if(b_node.is_a(&RNA_ShaderNodeRGBCurve)) { BL::ShaderNodeRGBCurve b_curve_node(b_node); BL::CurveMapping mapping(b_curve_node.mapping()); RGBCurvesNode *curves = new RGBCurvesNode(); curvemapping_color_to_array(mapping, curves->curves, RAMP_TABLE_SIZE, true); curvemapping_minmax(mapping, true, &curves->min_x, &curves->max_x); node = curves; } if(b_node.is_a(&RNA_ShaderNodeVectorCurve)) { BL::ShaderNodeVectorCurve b_curve_node(b_node); BL::CurveMapping mapping(b_curve_node.mapping()); VectorCurvesNode *curves = new VectorCurvesNode(); curvemapping_color_to_array(mapping, curves->curves, RAMP_TABLE_SIZE, false); curvemapping_minmax(mapping, false, &curves->min_x, &curves->max_x); node = curves; } else if(b_node.is_a(&RNA_ShaderNodeValToRGB)) { RGBRampNode *ramp = new RGBRampNode(); BL::ShaderNodeValToRGB b_ramp_node(b_node); colorramp_to_array(b_ramp_node.color_ramp(), ramp->ramp, RAMP_TABLE_SIZE); ramp->interpolate = b_ramp_node.color_ramp().interpolation() != BL::ColorRamp::interpolation_CONSTANT; node = ramp; } else if(b_node.is_a(&RNA_ShaderNodeRGB)) { ColorNode *color = new ColorNode(); color->value = get_node_output_rgba(b_node, "Color"); node = color; } else if(b_node.is_a(&RNA_ShaderNodeValue)) { ValueNode *value = new ValueNode(); value->value = get_node_output_value(b_node, "Value"); node = value; } else if(b_node.is_a(&RNA_ShaderNodeCameraData)) { node = new CameraNode(); } else if(b_node.is_a(&RNA_ShaderNodeInvert)) { node = new InvertNode(); } else if(b_node.is_a(&RNA_ShaderNodeGamma)) { node = new GammaNode(); } else if(b_node.is_a(&RNA_ShaderNodeBrightContrast)) { node = new BrightContrastNode(); } else if(b_node.is_a(&RNA_ShaderNodeMixRGB)) { BL::ShaderNodeMixRGB b_mix_node(b_node); MixNode *mix = new MixNode(); mix->type = MixNode::type_enum[b_mix_node.blend_type()]; /* Tag if it's Mix */ if(b_mix_node.blend_type() == 0) mix->special_type = SHADER_SPECIAL_TYPE_MIX_RGB; mix->use_clamp = b_mix_node.use_clamp(); node = mix; } else if(b_node.is_a(&RNA_ShaderNodeSeparateRGB)) { node = new SeparateRGBNode(); } else if(b_node.is_a(&RNA_ShaderNodeCombineRGB)) { node = new CombineRGBNode(); } else if(b_node.is_a(&RNA_ShaderNodeSeparateHSV)) { node = new SeparateHSVNode(); } else if(b_node.is_a(&RNA_ShaderNodeCombineHSV)) { node = new CombineHSVNode(); } else if(b_node.is_a(&RNA_ShaderNodeSeparateXYZ)) { node = new SeparateXYZNode(); } else if(b_node.is_a(&RNA_ShaderNodeCombineXYZ)) { node = new CombineXYZNode(); } else if(b_node.is_a(&RNA_ShaderNodeHueSaturation)) { node = new HSVNode(); } else if(b_node.is_a(&RNA_ShaderNodeRGBToBW)) { node = new ConvertNode(SHADER_SOCKET_COLOR, SHADER_SOCKET_FLOAT); } else if(b_node.is_a(&RNA_ShaderNodeMath)) { BL::ShaderNodeMath b_math_node(b_node); MathNode *math = new MathNode(); math->type = MathNode::type_enum[b_math_node.operation()]; math->use_clamp = b_math_node.use_clamp(); node = math; } else if(b_node.is_a(&RNA_ShaderNodeVectorMath)) { BL::ShaderNodeVectorMath b_vector_math_node(b_node); VectorMathNode *vmath = new VectorMathNode(); vmath->type = VectorMathNode::type_enum[b_vector_math_node.operation()]; node = vmath; } else if(b_node.is_a(&RNA_ShaderNodeVectorTransform)) { BL::ShaderNodeVectorTransform b_vector_transform_node(b_node); VectorTransformNode *vtransform = new VectorTransformNode(); vtransform->type = VectorTransformNode::type_enum[b_vector_transform_node.vector_type()]; vtransform->convert_from = VectorTransformNode::convert_space_enum[b_vector_transform_node.convert_from()]; vtransform->convert_to = VectorTransformNode::convert_space_enum[b_vector_transform_node.convert_to()]; node = vtransform; } else if(b_node.is_a(&RNA_ShaderNodeNormal)) { BL::Node::outputs_iterator out_it; b_node.outputs.begin(out_it); NormalNode *norm = new NormalNode(); norm->direction = get_node_output_vector(b_node, "Normal"); node = norm; } else if(b_node.is_a(&RNA_ShaderNodeMapping)) { BL::ShaderNodeMapping b_mapping_node(b_node); MappingNode *mapping = new MappingNode(); get_tex_mapping(&mapping->tex_mapping, b_mapping_node); node = mapping; } else if(b_node.is_a(&RNA_ShaderNodeFresnel)) { node = new FresnelNode(); } else if(b_node.is_a(&RNA_ShaderNodeLayerWeight)) { node = new LayerWeightNode(); } else if(b_node.is_a(&RNA_ShaderNodeAddShader)) { node = new AddClosureNode(); } else if(b_node.is_a(&RNA_ShaderNodeMixShader)) { node = new MixClosureNode(); } else if(b_node.is_a(&RNA_ShaderNodeAttribute)) { BL::ShaderNodeAttribute b_attr_node(b_node); AttributeNode *attr = new AttributeNode(); attr->attribute = b_attr_node.attribute_name(); node = attr; } else if(b_node.is_a(&RNA_ShaderNodeBackground)) { node = new BackgroundNode(); } else if(b_node.is_a(&RNA_ShaderNodeHoldout)) { node = new HoldoutNode(); } else if(b_node.is_a(&RNA_ShaderNodeBsdfAnisotropic)) { BL::ShaderNodeBsdfAnisotropic b_aniso_node(b_node); AnisotropicBsdfNode *aniso = new AnisotropicBsdfNode(); switch(b_aniso_node.distribution()) { case BL::ShaderNodeBsdfAnisotropic::distribution_BECKMANN: aniso->distribution = ustring("Beckmann"); break; case BL::ShaderNodeBsdfAnisotropic::distribution_GGX: aniso->distribution = ustring("GGX"); break; case BL::ShaderNodeBsdfAnisotropic::distribution_ASHIKHMIN_SHIRLEY: aniso->distribution = ustring("Ashikhmin-Shirley"); break; } node = aniso; } else if(b_node.is_a(&RNA_ShaderNodeBsdfDiffuse)) { node = new DiffuseBsdfNode(); } else if(b_node.is_a(&RNA_ShaderNodeSubsurfaceScattering)) { BL::ShaderNodeSubsurfaceScattering b_subsurface_node(b_node); SubsurfaceScatteringNode *subsurface = new SubsurfaceScatteringNode(); switch(b_subsurface_node.falloff()) { case BL::ShaderNodeSubsurfaceScattering::falloff_CUBIC: subsurface->closure = CLOSURE_BSSRDF_CUBIC_ID; break; case BL::ShaderNodeSubsurfaceScattering::falloff_GAUSSIAN: subsurface->closure = CLOSURE_BSSRDF_GAUSSIAN_ID; break; } node = subsurface; } else if(b_node.is_a(&RNA_ShaderNodeBsdfGlossy)) { BL::ShaderNodeBsdfGlossy b_glossy_node(b_node); GlossyBsdfNode *glossy = new GlossyBsdfNode(); switch(b_glossy_node.distribution()) { case BL::ShaderNodeBsdfGlossy::distribution_SHARP: glossy->distribution = ustring("Sharp"); break; case BL::ShaderNodeBsdfGlossy::distribution_BECKMANN: glossy->distribution = ustring("Beckmann"); break; case BL::ShaderNodeBsdfGlossy::distribution_GGX: glossy->distribution = ustring("GGX"); break; case BL::ShaderNodeBsdfGlossy::distribution_ASHIKHMIN_SHIRLEY: glossy->distribution = ustring("Ashikhmin-Shirley"); break; } node = glossy; } else if(b_node.is_a(&RNA_ShaderNodeBsdfGlass)) { BL::ShaderNodeBsdfGlass b_glass_node(b_node); GlassBsdfNode *glass = new GlassBsdfNode(); switch(b_glass_node.distribution()) { case BL::ShaderNodeBsdfGlass::distribution_SHARP: glass->distribution = ustring("Sharp"); break; case BL::ShaderNodeBsdfGlass::distribution_BECKMANN: glass->distribution = ustring("Beckmann"); break; case BL::ShaderNodeBsdfGlass::distribution_GGX: glass->distribution = ustring("GGX"); break; } node = glass; } else if(b_node.is_a(&RNA_ShaderNodeBsdfRefraction)) { BL::ShaderNodeBsdfRefraction b_refraction_node(b_node); RefractionBsdfNode *refraction = new RefractionBsdfNode(); switch(b_refraction_node.distribution()) { case BL::ShaderNodeBsdfRefraction::distribution_SHARP: refraction->distribution = ustring("Sharp"); break; case BL::ShaderNodeBsdfRefraction::distribution_BECKMANN: refraction->distribution = ustring("Beckmann"); break; case BL::ShaderNodeBsdfRefraction::distribution_GGX: refraction->distribution = ustring("GGX"); break; } node = refraction; } else if(b_node.is_a(&RNA_ShaderNodeBsdfToon)) { BL::ShaderNodeBsdfToon b_toon_node(b_node); ToonBsdfNode *toon = new ToonBsdfNode(); switch(b_toon_node.component()) { case BL::ShaderNodeBsdfToon::component_DIFFUSE: toon->component = ustring("Diffuse"); break; case BL::ShaderNodeBsdfToon::component_GLOSSY: toon->component = ustring("Glossy"); break; } node = toon; } else if(b_node.is_a(&RNA_ShaderNodeBsdfHair)) { BL::ShaderNodeBsdfHair b_hair_node(b_node); HairBsdfNode *hair = new HairBsdfNode(); switch(b_hair_node.component()) { case BL::ShaderNodeBsdfHair::component_Reflection: hair->component = ustring("Reflection"); break; case BL::ShaderNodeBsdfHair::component_Transmission: hair->component = ustring("Transmission"); break; } node = hair; } else if(b_node.is_a(&RNA_ShaderNodeBsdfTranslucent)) { node = new TranslucentBsdfNode(); } else if(b_node.is_a(&RNA_ShaderNodeBsdfTransparent)) { node = new TransparentBsdfNode(); } else if(b_node.is_a(&RNA_ShaderNodeBsdfVelvet)) { node = new VelvetBsdfNode(); } else if(b_node.is_a(&RNA_ShaderNodeEmission)) { node = new EmissionNode(); } else if(b_node.is_a(&RNA_ShaderNodeAmbientOcclusion)) { node = new AmbientOcclusionNode(); } else if(b_node.is_a(&RNA_ShaderNodeVolumeScatter)) { node = new ScatterVolumeNode(); } else if(b_node.is_a(&RNA_ShaderNodeVolumeAbsorption)) { node = new AbsorptionVolumeNode(); } else if(b_node.is_a(&RNA_ShaderNodeNewGeometry)) { node = new GeometryNode(); } else if(b_node.is_a(&RNA_ShaderNodeWireframe)) { BL::ShaderNodeWireframe b_wireframe_node(b_node); WireframeNode *wire = new WireframeNode(); wire->use_pixel_size = b_wireframe_node.use_pixel_size(); node = wire; } else if(b_node.is_a(&RNA_ShaderNodeWavelength)) { node = new WavelengthNode(); } else if(b_node.is_a(&RNA_ShaderNodeBlackbody)) { node = new BlackbodyNode(); } else if(b_node.is_a(&RNA_ShaderNodeLightPath)) { node = new LightPathNode(); } else if(b_node.is_a(&RNA_ShaderNodeLightFalloff)) { node = new LightFalloffNode(); } else if(b_node.is_a(&RNA_ShaderNodeObjectInfo)) { node = new ObjectInfoNode(); } else if(b_node.is_a(&RNA_ShaderNodeParticleInfo)) { node = new ParticleInfoNode(); } else if(b_node.is_a(&RNA_ShaderNodeHairInfo)) { node = new HairInfoNode(); } else if(b_node.is_a(&RNA_ShaderNodeBump)) { BL::ShaderNodeBump b_bump_node(b_node); BumpNode *bump = new BumpNode(); bump->invert = b_bump_node.invert(); node = bump; } else if(b_node.is_a(&RNA_ShaderNodeScript)) { #ifdef WITH_OSL if(scene->shader_manager->use_osl()) { /* create script node */ BL::ShaderNodeScript b_script_node(b_node); OSLScriptNode *script_node = new OSLScriptNode(); OSLShaderManager *manager = (OSLShaderManager*)scene->shader_manager; string bytecode_hash = b_script_node.bytecode_hash(); /* Gather additional information from the shader, such as * input/output type info needed for proper node construction. */ OSL::OSLQuery query; #if OSL_LIBRARY_VERSION_CODE >= 10701 if(!bytecode_hash.empty()) { query.open_bytecode(b_script_node.bytecode()); } else { !OSLShaderManager::osl_query(query, b_script_node.filepath()); } /* TODO(sergey): Add proper query info error parsing. */ #endif /* Generate inputs/outputs from node sockets * * Note: the node sockets are generated from OSL parameters, * so the names match those of the corresponding parameters exactly. * * Note 2: ShaderInput/ShaderOutput store shallow string copies only! * Socket names must be stored in the extra lists instead. */ BL::Node::inputs_iterator b_input; for(b_script_node.inputs.begin(b_input); b_input != b_script_node.inputs.end(); ++b_input) { script_node->input_names.push_back(ustring(b_input->name())); ShaderInput *input = script_node->add_input(script_node->input_names.back().c_str(), convert_osl_socket_type(query, *b_input)); set_default_value(input, *b_input, b_data, b_ntree); } BL::Node::outputs_iterator b_output; for(b_script_node.outputs.begin(b_output); b_output != b_script_node.outputs.end(); ++b_output) { script_node->output_names.push_back(ustring(b_output->name())); script_node->add_output(script_node->output_names.back().c_str(), convert_osl_socket_type(query, *b_output)); } /* load bytecode or filepath */ if(!bytecode_hash.empty()) { /* loaded bytecode if not already done */ if(!manager->shader_test_loaded(bytecode_hash)) manager->shader_load_bytecode(bytecode_hash, b_script_node.bytecode()); script_node->bytecode_hash = bytecode_hash; } else { /* set filepath */ script_node->filepath = blender_absolute_path(b_data, b_ntree, b_script_node.filepath()); } node = script_node; } #else (void)b_data; (void)b_ntree; #endif } else if(b_node.is_a(&RNA_ShaderNodeTexImage)) { BL::ShaderNodeTexImage b_image_node(b_node); BL::Image b_image(b_image_node.image()); ImageTextureNode *image = new ImageTextureNode(); if(b_image) { /* builtin images will use callback-based reading because * they could only be loaded correct from blender side */ bool is_builtin = b_image.packed_file() || b_image.source() == BL::Image::source_GENERATED || b_image.source() == BL::Image::source_MOVIE || b_engine.is_preview(); if(is_builtin) { /* for builtin images we're using image datablock name to find an image to * read pixels from later * * also store frame number as well, so there's no differences in handling * builtin names for packed images and movies */ int scene_frame = b_scene.frame_current(); int image_frame = image_user_frame_number(b_image_node.image_user(), scene_frame); image->filename = b_image.name() + "@" + string_printf("%d", image_frame); image->builtin_data = b_image.ptr.data; } else { image->filename = image_user_file_path(b_image_node.image_user(), b_image, b_scene.frame_current()); image->builtin_data = NULL; } image->animated = b_image_node.image_user().use_auto_refresh(); image->use_alpha = b_image.use_alpha(); /* TODO(sergey): Does not work properly when we change builtin type. */ if(b_image.is_updated()) { scene->image_manager->tag_reload_image( image->filename, image->builtin_data, (InterpolationType)b_image_node.interpolation(), (ExtensionType)b_image_node.extension()); } } image->color_space = ImageTextureNode::color_space_enum[(int)b_image_node.color_space()]; image->projection = ImageTextureNode::projection_enum[(int)b_image_node.projection()]; image->interpolation = (InterpolationType)b_image_node.interpolation(); image->extension = (ExtensionType)b_image_node.extension(); image->projection_blend = b_image_node.projection_blend(); get_tex_mapping(&image->tex_mapping, b_image_node.texture_mapping()); node = image; } else if(b_node.is_a(&RNA_ShaderNodeTexEnvironment)) { BL::ShaderNodeTexEnvironment b_env_node(b_node); BL::Image b_image(b_env_node.image()); EnvironmentTextureNode *env = new EnvironmentTextureNode(); if(b_image) { bool is_builtin = b_image.packed_file() || b_image.source() == BL::Image::source_GENERATED || b_image.source() == BL::Image::source_MOVIE || b_engine.is_preview(); if(is_builtin) { int scene_frame = b_scene.frame_current(); int image_frame = image_user_frame_number(b_env_node.image_user(), scene_frame); env->filename = b_image.name() + "@" + string_printf("%d", image_frame); env->builtin_data = b_image.ptr.data; } else { env->filename = image_user_file_path(b_env_node.image_user(), b_image, b_scene.frame_current()); env->animated = b_env_node.image_user().use_auto_refresh(); env->builtin_data = NULL; } env->use_alpha = b_image.use_alpha(); /* TODO(sergey): Does not work properly when we change builtin type. */ if(b_image.is_updated()) { scene->image_manager->tag_reload_image(env->filename, env->builtin_data, (InterpolationType)b_env_node.interpolation(), EXTENSION_REPEAT); } } env->color_space = EnvironmentTextureNode::color_space_enum[(int)b_env_node.color_space()]; env->interpolation = (InterpolationType)b_env_node.interpolation(); env->projection = EnvironmentTextureNode::projection_enum[(int)b_env_node.projection()]; get_tex_mapping(&env->tex_mapping, b_env_node.texture_mapping()); node = env; } else if(b_node.is_a(&RNA_ShaderNodeTexGradient)) { BL::ShaderNodeTexGradient b_gradient_node(b_node); GradientTextureNode *gradient = new GradientTextureNode(); gradient->type = GradientTextureNode::type_enum[(int)b_gradient_node.gradient_type()]; get_tex_mapping(&gradient->tex_mapping, b_gradient_node.texture_mapping()); node = gradient; } else if(b_node.is_a(&RNA_ShaderNodeTexVoronoi)) { BL::ShaderNodeTexVoronoi b_voronoi_node(b_node); VoronoiTextureNode *voronoi = new VoronoiTextureNode(); voronoi->coloring = VoronoiTextureNode::coloring_enum[(int)b_voronoi_node.coloring()]; get_tex_mapping(&voronoi->tex_mapping, b_voronoi_node.texture_mapping()); node = voronoi; } else if(b_node.is_a(&RNA_ShaderNodeTexMagic)) { BL::ShaderNodeTexMagic b_magic_node(b_node); MagicTextureNode *magic = new MagicTextureNode(); magic->depth = b_magic_node.turbulence_depth(); get_tex_mapping(&magic->tex_mapping, b_magic_node.texture_mapping()); node = magic; } else if(b_node.is_a(&RNA_ShaderNodeTexWave)) { BL::ShaderNodeTexWave b_wave_node(b_node); WaveTextureNode *wave = new WaveTextureNode(); wave->type = WaveTextureNode::type_enum[(int)b_wave_node.wave_type()]; get_tex_mapping(&wave->tex_mapping, b_wave_node.texture_mapping()); node = wave; } else if(b_node.is_a(&RNA_ShaderNodeTexChecker)) { BL::ShaderNodeTexChecker b_checker_node(b_node); CheckerTextureNode *checker = new CheckerTextureNode(); get_tex_mapping(&checker->tex_mapping, b_checker_node.texture_mapping()); node = checker; } else if(b_node.is_a(&RNA_ShaderNodeTexBrick)) { BL::ShaderNodeTexBrick b_brick_node(b_node); BrickTextureNode *brick = new BrickTextureNode(); brick->offset = b_brick_node.offset(); brick->offset_frequency = b_brick_node.offset_frequency(); brick->squash = b_brick_node.squash(); brick->squash_frequency = b_brick_node.squash_frequency(); get_tex_mapping(&brick->tex_mapping, b_brick_node.texture_mapping()); node = brick; } else if(b_node.is_a(&RNA_ShaderNodeTexNoise)) { BL::ShaderNodeTexNoise b_noise_node(b_node); NoiseTextureNode *noise = new NoiseTextureNode(); get_tex_mapping(&noise->tex_mapping, b_noise_node.texture_mapping()); node = noise; } else if(b_node.is_a(&RNA_ShaderNodeTexMusgrave)) { BL::ShaderNodeTexMusgrave b_musgrave_node(b_node); MusgraveTextureNode *musgrave = new MusgraveTextureNode(); musgrave->type = MusgraveTextureNode::type_enum[(int)b_musgrave_node.musgrave_type()]; get_tex_mapping(&musgrave->tex_mapping, b_musgrave_node.texture_mapping()); node = musgrave; } else if(b_node.is_a(&RNA_ShaderNodeTexCoord)) { BL::ShaderNodeTexCoord b_tex_coord_node(b_node); TextureCoordinateNode *tex_coord = new TextureCoordinateNode(); tex_coord->from_dupli = b_tex_coord_node.from_dupli(); if(b_tex_coord_node.object()) { tex_coord->use_transform = true; tex_coord->ob_tfm = get_transform(b_tex_coord_node.object().matrix_world()); } node = tex_coord; } else if(b_node.is_a(&RNA_ShaderNodeTexSky)) { BL::ShaderNodeTexSky b_sky_node(b_node); SkyTextureNode *sky = new SkyTextureNode(); sky->type = SkyTextureNode::type_enum[(int)b_sky_node.sky_type()]; sky->sun_direction = normalize(get_float3(b_sky_node.sun_direction())); sky->turbidity = b_sky_node.turbidity(); sky->ground_albedo = b_sky_node.ground_albedo(); get_tex_mapping(&sky->tex_mapping, b_sky_node.texture_mapping()); node = sky; } else if(b_node.is_a(&RNA_ShaderNodeNormalMap)) { BL::ShaderNodeNormalMap b_normal_map_node(b_node); NormalMapNode *nmap = new NormalMapNode(); nmap->space = NormalMapNode::space_enum[(int)b_normal_map_node.space()]; nmap->attribute = b_normal_map_node.uv_map(); node = nmap; } else if(b_node.is_a(&RNA_ShaderNodeTangent)) { BL::ShaderNodeTangent b_tangent_node(b_node); TangentNode *tangent = new TangentNode(); tangent->direction_type = TangentNode::direction_type_enum[(int)b_tangent_node.direction_type()]; tangent->axis = TangentNode::axis_enum[(int)b_tangent_node.axis()]; tangent->attribute = b_tangent_node.uv_map(); node = tangent; } else if(b_node.is_a(&RNA_ShaderNodeUVMap)) { BL::ShaderNodeUVMap b_uvmap_node(b_node); UVMapNode *uvm = new UVMapNode(); uvm->attribute = b_uvmap_node.uv_map(); uvm->from_dupli = b_uvmap_node.from_dupli(); node = uvm; } else if(b_node.is_a(&RNA_ShaderNodeTexPointDensity)) { BL::ShaderNodeTexPointDensity b_point_density_node(b_node); PointDensityTextureNode *point_density = new PointDensityTextureNode(); point_density->filename = b_point_density_node.name(); point_density->space = PointDensityTextureNode::space_enum[(int)b_point_density_node.space()]; point_density->interpolation = (InterpolationType)b_point_density_node.interpolation(); point_density->builtin_data = b_point_density_node.ptr.data; /* Transformation form world space to texture space. */ BL::Object b_ob(b_point_density_node.object()); if(b_ob) { float3 loc, size; point_density_texture_space(b_point_density_node, loc, size); point_density->tfm = transform_translate(-loc) * transform_scale(size) * transform_inverse(get_transform(b_ob.matrix_world())); } /* TODO(sergey): Use more proper update flag. */ if(true) { int settings = background ? 1 : 0; /* 1 - render settings, 0 - vewport settings. */ b_point_density_node.cache_point_density(b_scene, settings); scene->image_manager->tag_reload_image( point_density->filename, point_density->builtin_data, point_density->interpolation, EXTENSION_CLIP); } node = point_density; } if(node) graph->add(node); return node; }
void Camera::device_update(Device *device, DeviceScene *dscene, Scene *scene) { Scene::MotionType need_motion = scene->need_motion(device->info.advanced_shading); update(); if(previous_need_motion != need_motion) { /* scene's motion model could have been changed since previous device * camera update this could happen for example in case when one render * layer has got motion pass and another not */ need_device_update = true; } if(!need_device_update) return; KernelCamera *kcam = &dscene->data.cam; /* store matrices */ kcam->screentoworld = screentoworld; kcam->rastertoworld = rastertoworld; kcam->rastertocamera = rastertocamera; kcam->cameratoworld = cameratoworld; kcam->worldtocamera = worldtocamera; kcam->worldtoscreen = worldtoscreen; kcam->worldtoraster = worldtoraster; kcam->worldtondc = worldtondc; /* camera motion */ kcam->have_motion = 0; kcam->have_perspective_motion = 0; if(need_motion == Scene::MOTION_PASS) { /* TODO(sergey): Support perspective (zoom, fov) motion. */ if(type == CAMERA_PANORAMA) { if(use_motion) { kcam->motion.pre = transform_inverse(motion.pre); kcam->motion.post = transform_inverse(motion.post); } else { kcam->motion.pre = kcam->worldtocamera; kcam->motion.post = kcam->worldtocamera; } } else { if(use_motion) { kcam->motion.pre = cameratoraster * transform_inverse(motion.pre); kcam->motion.post = cameratoraster * transform_inverse(motion.post); } else { kcam->motion.pre = worldtoraster; kcam->motion.post = worldtoraster; } } } #ifdef __CAMERA_MOTION__ else if(need_motion == Scene::MOTION_BLUR) { if(use_motion) { transform_motion_decompose((DecompMotionTransform*)&kcam->motion, &motion, &matrix); kcam->have_motion = 1; } if(use_perspective_motion) { kcam->perspective_motion = perspective_motion; kcam->have_perspective_motion = 1; } } #endif /* depth of field */ kcam->aperturesize = aperturesize; kcam->focaldistance = focaldistance; kcam->blades = (blades < 3)? 0.0f: blades; kcam->bladesrotation = bladesrotation; /* motion blur */ #ifdef __CAMERA_MOTION__ kcam->shuttertime = (need_motion == Scene::MOTION_BLUR) ? shuttertime: -1.0f; if(need_motion == Scene::MOTION_BLUR) { vector<float> shutter_table; util_cdf_inverted(SHUTTER_TABLE_SIZE, 0.0f, 1.0f, function_bind(shutter_curve_eval, _1, shutter_curve), false, shutter_table); shutter_table_offset = scene->lookup_tables->add_table(dscene, shutter_table); kcam->shutter_table_offset = (int)shutter_table_offset; } else if(shutter_table_offset != TABLE_OFFSET_INVALID) { scene->lookup_tables->remove_table(shutter_table_offset); shutter_table_offset = TABLE_OFFSET_INVALID; } #else kcam->shuttertime = -1.0f; #endif /* type */ kcam->type = type; /* anamorphic lens bokeh */ kcam->inv_aperture_ratio = 1.0f / aperture_ratio; /* panorama */ kcam->panorama_type = panorama_type; kcam->fisheye_fov = fisheye_fov; kcam->fisheye_lens = fisheye_lens; kcam->equirectangular_range = make_float4(longitude_min - longitude_max, -longitude_min, latitude_min - latitude_max, -latitude_min + M_PI_2_F); switch(stereo_eye) { case STEREO_LEFT: kcam->interocular_offset = -interocular_distance * 0.5f; break; case STEREO_RIGHT: kcam->interocular_offset = interocular_distance * 0.5f; break; case STEREO_NONE: default: kcam->interocular_offset = 0.0f; break; } kcam->convergence_distance = convergence_distance; /* sensor size */ kcam->sensorwidth = sensorwidth; kcam->sensorheight = sensorheight; /* render size */ kcam->width = width; kcam->height = height; kcam->resolution = resolution; /* store differentials */ kcam->dx = float3_to_float4(dx); kcam->dy = float3_to_float4(dy); /* clipping */ kcam->nearclip = nearclip; kcam->cliplength = (farclip == FLT_MAX)? FLT_MAX: farclip - nearclip; /* Camera in volume. */ kcam->is_inside_volume = 0; /* Rolling shutter effect */ kcam->rolling_shutter_type = rolling_shutter_type; kcam->rolling_shutter_duration = rolling_shutter_duration; previous_need_motion = need_motion; }
static ShaderNode *add_node(Scene *scene, BL::RenderEngine& b_engine, BL::BlendData& b_data, BL::Scene& b_scene, const bool background, ShaderGraph *graph, BL::ShaderNodeTree& b_ntree, BL::ShaderNode& b_node) { ShaderNode *node = NULL; /* existing blender nodes */ if(b_node.is_a(&RNA_ShaderNodeRGBCurve)) { BL::ShaderNodeRGBCurve b_curve_node(b_node); BL::CurveMapping mapping(b_curve_node.mapping()); RGBCurvesNode *curves = new RGBCurvesNode(); curvemapping_color_to_array(mapping, curves->curves, RAMP_TABLE_SIZE, true); curvemapping_minmax(mapping, true, &curves->min_x, &curves->max_x); node = curves; } if(b_node.is_a(&RNA_ShaderNodeVectorCurve)) { BL::ShaderNodeVectorCurve b_curve_node(b_node); BL::CurveMapping mapping(b_curve_node.mapping()); VectorCurvesNode *curves = new VectorCurvesNode(); curvemapping_color_to_array(mapping, curves->curves, RAMP_TABLE_SIZE, false); curvemapping_minmax(mapping, false, &curves->min_x, &curves->max_x); node = curves; } else if(b_node.is_a(&RNA_ShaderNodeValToRGB)) { RGBRampNode *ramp = new RGBRampNode(); BL::ShaderNodeValToRGB b_ramp_node(b_node); BL::ColorRamp b_color_ramp(b_ramp_node.color_ramp()); colorramp_to_array(b_color_ramp, ramp->ramp, ramp->ramp_alpha, RAMP_TABLE_SIZE); ramp->interpolate = b_color_ramp.interpolation() != BL::ColorRamp::interpolation_CONSTANT; node = ramp; } else if(b_node.is_a(&RNA_ShaderNodeRGB)) { ColorNode *color = new ColorNode(); color->value = get_node_output_rgba(b_node, "Color"); node = color; } else if(b_node.is_a(&RNA_ShaderNodeValue)) { ValueNode *value = new ValueNode(); value->value = get_node_output_value(b_node, "Value"); node = value; } else if(b_node.is_a(&RNA_ShaderNodeCameraData)) { node = new CameraNode(); } else if(b_node.is_a(&RNA_ShaderNodeInvert)) { node = new InvertNode(); } else if(b_node.is_a(&RNA_ShaderNodeGamma)) { node = new GammaNode(); } else if(b_node.is_a(&RNA_ShaderNodeBrightContrast)) { node = new BrightContrastNode(); } else if(b_node.is_a(&RNA_ShaderNodeMixRGB)) { BL::ShaderNodeMixRGB b_mix_node(b_node); MixNode *mix = new MixNode(); mix->type = (NodeMix)b_mix_node.blend_type(); mix->use_clamp = b_mix_node.use_clamp(); node = mix; } else if(b_node.is_a(&RNA_ShaderNodeSeparateRGB)) { node = new SeparateRGBNode(); } else if(b_node.is_a(&RNA_ShaderNodeCombineRGB)) { node = new CombineRGBNode(); } else if(b_node.is_a(&RNA_ShaderNodeSeparateHSV)) { node = new SeparateHSVNode(); } else if(b_node.is_a(&RNA_ShaderNodeCombineHSV)) { node = new CombineHSVNode(); } else if(b_node.is_a(&RNA_ShaderNodeSeparateXYZ)) { node = new SeparateXYZNode(); } else if(b_node.is_a(&RNA_ShaderNodeCombineXYZ)) { node = new CombineXYZNode(); } else if(b_node.is_a(&RNA_ShaderNodeHueSaturation)) { node = new HSVNode(); } else if(b_node.is_a(&RNA_ShaderNodeRGBToBW)) { node = new RGBToBWNode(); } else if(b_node.is_a(&RNA_ShaderNodeMath)) { BL::ShaderNodeMath b_math_node(b_node); MathNode *math = new MathNode(); math->type = (NodeMath)b_math_node.operation(); math->use_clamp = b_math_node.use_clamp(); node = math; } else if(b_node.is_a(&RNA_ShaderNodeVectorMath)) { BL::ShaderNodeVectorMath b_vector_math_node(b_node); VectorMathNode *vmath = new VectorMathNode(); vmath->type = (NodeVectorMath)b_vector_math_node.operation(); node = vmath; } else if(b_node.is_a(&RNA_ShaderNodeVectorTransform)) { BL::ShaderNodeVectorTransform b_vector_transform_node(b_node); VectorTransformNode *vtransform = new VectorTransformNode(); vtransform->type = (NodeVectorTransformType)b_vector_transform_node.vector_type(); vtransform->convert_from = (NodeVectorTransformConvertSpace)b_vector_transform_node.convert_from(); vtransform->convert_to = (NodeVectorTransformConvertSpace)b_vector_transform_node.convert_to(); node = vtransform; } else if(b_node.is_a(&RNA_ShaderNodeNormal)) { BL::Node::outputs_iterator out_it; b_node.outputs.begin(out_it); NormalNode *norm = new NormalNode(); norm->direction = get_node_output_vector(b_node, "Normal"); node = norm; } else if(b_node.is_a(&RNA_ShaderNodeMapping)) { BL::ShaderNodeMapping b_mapping_node(b_node); MappingNode *mapping = new MappingNode(); get_tex_mapping(&mapping->tex_mapping, b_mapping_node); node = mapping; } else if(b_node.is_a(&RNA_ShaderNodeFresnel)) { node = new FresnelNode(); } else if(b_node.is_a(&RNA_ShaderNodeLayerWeight)) { node = new LayerWeightNode(); } else if(b_node.is_a(&RNA_ShaderNodeAddShader)) { node = new AddClosureNode(); } else if(b_node.is_a(&RNA_ShaderNodeMixShader)) { node = new MixClosureNode(); } else if(b_node.is_a(&RNA_ShaderNodeAttribute)) { BL::ShaderNodeAttribute b_attr_node(b_node); AttributeNode *attr = new AttributeNode(); attr->attribute = b_attr_node.attribute_name(); node = attr; } else if(b_node.is_a(&RNA_ShaderNodeBackground)) { node = new BackgroundNode(); } else if(b_node.is_a(&RNA_ShaderNodeHoldout)) { node = new HoldoutNode(); } else if(b_node.is_a(&RNA_ShaderNodeBsdfAnisotropic)) { BL::ShaderNodeBsdfAnisotropic b_aniso_node(b_node); AnisotropicBsdfNode *aniso = new AnisotropicBsdfNode(); switch(b_aniso_node.distribution()) { case BL::ShaderNodeBsdfAnisotropic::distribution_BECKMANN: aniso->distribution = CLOSURE_BSDF_MICROFACET_BECKMANN_ANISO_ID; break; case BL::ShaderNodeBsdfAnisotropic::distribution_GGX: aniso->distribution = CLOSURE_BSDF_MICROFACET_GGX_ANISO_ID; break; case BL::ShaderNodeBsdfAnisotropic::distribution_ASHIKHMIN_SHIRLEY: aniso->distribution = CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ANISO_ID; break; } node = aniso; } else if(b_node.is_a(&RNA_ShaderNodeBsdfDiffuse)) { node = new DiffuseBsdfNode(); } else if(b_node.is_a(&RNA_ShaderNodeSubsurfaceScattering)) { BL::ShaderNodeSubsurfaceScattering b_subsurface_node(b_node); SubsurfaceScatteringNode *subsurface = new SubsurfaceScatteringNode(); switch(b_subsurface_node.falloff()) { case BL::ShaderNodeSubsurfaceScattering::falloff_CUBIC: subsurface->falloff = CLOSURE_BSSRDF_CUBIC_ID; break; case BL::ShaderNodeSubsurfaceScattering::falloff_GAUSSIAN: subsurface->falloff = CLOSURE_BSSRDF_GAUSSIAN_ID; break; case BL::ShaderNodeSubsurfaceScattering::falloff_BURLEY: subsurface->falloff = CLOSURE_BSSRDF_BURLEY_ID; break; } node = subsurface; } else if(b_node.is_a(&RNA_ShaderNodeBsdfGlossy)) { BL::ShaderNodeBsdfGlossy b_glossy_node(b_node); GlossyBsdfNode *glossy = new GlossyBsdfNode(); switch(b_glossy_node.distribution()) { case BL::ShaderNodeBsdfGlossy::distribution_SHARP: glossy->distribution = CLOSURE_BSDF_REFLECTION_ID; break; case BL::ShaderNodeBsdfGlossy::distribution_BECKMANN: glossy->distribution = CLOSURE_BSDF_MICROFACET_BECKMANN_ID; break; case BL::ShaderNodeBsdfGlossy::distribution_GGX: glossy->distribution = CLOSURE_BSDF_MICROFACET_GGX_ID; break; case BL::ShaderNodeBsdfGlossy::distribution_ASHIKHMIN_SHIRLEY: glossy->distribution = CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ANISO_ID; break; } node = glossy; } else if(b_node.is_a(&RNA_ShaderNodeBsdfGlass)) { BL::ShaderNodeBsdfGlass b_glass_node(b_node); GlassBsdfNode *glass = new GlassBsdfNode(); switch(b_glass_node.distribution()) { case BL::ShaderNodeBsdfGlass::distribution_SHARP: glass->distribution = CLOSURE_BSDF_SHARP_GLASS_ID; break; case BL::ShaderNodeBsdfGlass::distribution_BECKMANN: glass->distribution = CLOSURE_BSDF_MICROFACET_BECKMANN_GLASS_ID; break; case BL::ShaderNodeBsdfGlass::distribution_GGX: glass->distribution = CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID; break; } node = glass; } else if(b_node.is_a(&RNA_ShaderNodeBsdfRefraction)) { BL::ShaderNodeBsdfRefraction b_refraction_node(b_node); RefractionBsdfNode *refraction = new RefractionBsdfNode(); switch(b_refraction_node.distribution()) { case BL::ShaderNodeBsdfRefraction::distribution_SHARP: refraction->distribution = CLOSURE_BSDF_REFRACTION_ID; break; case BL::ShaderNodeBsdfRefraction::distribution_BECKMANN: refraction->distribution = CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID; break; case BL::ShaderNodeBsdfRefraction::distribution_GGX: refraction->distribution = CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID; break; } node = refraction; } else if(b_node.is_a(&RNA_ShaderNodeBsdfToon)) { BL::ShaderNodeBsdfToon b_toon_node(b_node); ToonBsdfNode *toon = new ToonBsdfNode(); switch(b_toon_node.component()) { case BL::ShaderNodeBsdfToon::component_DIFFUSE: toon->component = CLOSURE_BSDF_DIFFUSE_TOON_ID; break; case BL::ShaderNodeBsdfToon::component_GLOSSY: toon->component = CLOSURE_BSDF_GLOSSY_TOON_ID; break; } node = toon; } else if(b_node.is_a(&RNA_ShaderNodeBsdfHair)) { BL::ShaderNodeBsdfHair b_hair_node(b_node); HairBsdfNode *hair = new HairBsdfNode(); switch(b_hair_node.component()) { case BL::ShaderNodeBsdfHair::component_Reflection: hair->component = CLOSURE_BSDF_HAIR_REFLECTION_ID; break; case BL::ShaderNodeBsdfHair::component_Transmission: hair->component = CLOSURE_BSDF_HAIR_TRANSMISSION_ID; break; } node = hair; } else if(b_node.is_a(&RNA_ShaderNodeBsdfTranslucent)) { node = new TranslucentBsdfNode(); } else if(b_node.is_a(&RNA_ShaderNodeBsdfTransparent)) { node = new TransparentBsdfNode(); } else if(b_node.is_a(&RNA_ShaderNodeBsdfVelvet)) { node = new VelvetBsdfNode(); } else if(b_node.is_a(&RNA_ShaderNodeEmission)) { node = new EmissionNode(); } else if(b_node.is_a(&RNA_ShaderNodeAmbientOcclusion)) { node = new AmbientOcclusionNode(); } else if(b_node.is_a(&RNA_ShaderNodeVolumeScatter)) { node = new ScatterVolumeNode(); } else if(b_node.is_a(&RNA_ShaderNodeVolumeAbsorption)) { node = new AbsorptionVolumeNode(); } else if(b_node.is_a(&RNA_ShaderNodeNewGeometry)) { node = new GeometryNode(); } else if(b_node.is_a(&RNA_ShaderNodeWireframe)) { BL::ShaderNodeWireframe b_wireframe_node(b_node); WireframeNode *wire = new WireframeNode(); wire->use_pixel_size = b_wireframe_node.use_pixel_size(); node = wire; } else if(b_node.is_a(&RNA_ShaderNodeWavelength)) { node = new WavelengthNode(); } else if(b_node.is_a(&RNA_ShaderNodeBlackbody)) { node = new BlackbodyNode(); } else if(b_node.is_a(&RNA_ShaderNodeLightPath)) { node = new LightPathNode(); } else if(b_node.is_a(&RNA_ShaderNodeLightFalloff)) { node = new LightFalloffNode(); } else if(b_node.is_a(&RNA_ShaderNodeObjectInfo)) { node = new ObjectInfoNode(); } else if(b_node.is_a(&RNA_ShaderNodeParticleInfo)) { node = new ParticleInfoNode(); } else if(b_node.is_a(&RNA_ShaderNodeHairInfo)) { node = new HairInfoNode(); } else if(b_node.is_a(&RNA_ShaderNodeBump)) { BL::ShaderNodeBump b_bump_node(b_node); BumpNode *bump = new BumpNode(); bump->invert = b_bump_node.invert(); node = bump; } else if(b_node.is_a(&RNA_ShaderNodeScript)) { #ifdef WITH_OSL if(scene->shader_manager->use_osl()) { /* create script node */ BL::ShaderNodeScript b_script_node(b_node); OSLShaderManager *manager = (OSLShaderManager*)scene->shader_manager; string bytecode_hash = b_script_node.bytecode_hash(); if(!bytecode_hash.empty()) { node = manager->osl_node("", bytecode_hash, b_script_node.bytecode()); } else { string absolute_filepath = blender_absolute_path(b_data, b_ntree, b_script_node.filepath()); node = manager->osl_node(absolute_filepath, ""); } } #else (void)b_data; (void)b_ntree; #endif } else if(b_node.is_a(&RNA_ShaderNodeTexImage)) { BL::ShaderNodeTexImage b_image_node(b_node); BL::Image b_image(b_image_node.image()); BL::ImageUser b_image_user(b_image_node.image_user()); ImageTextureNode *image = new ImageTextureNode(); if(b_image) { /* builtin images will use callback-based reading because * they could only be loaded correct from blender side */ bool is_builtin = b_image.packed_file() || b_image.source() == BL::Image::source_GENERATED || b_image.source() == BL::Image::source_MOVIE || b_engine.is_preview(); if(is_builtin) { /* for builtin images we're using image datablock name to find an image to * read pixels from later * * also store frame number as well, so there's no differences in handling * builtin names for packed images and movies */ int scene_frame = b_scene.frame_current(); int image_frame = image_user_frame_number(b_image_user, scene_frame); image->filename = b_image.name() + "@" + string_printf("%d", image_frame); image->builtin_data = b_image.ptr.data; } else { image->filename = image_user_file_path(b_image_user, b_image, b_scene.frame_current()); image->builtin_data = NULL; } image->animated = b_image_node.image_user().use_auto_refresh(); image->use_alpha = b_image.use_alpha(); /* TODO(sergey): Does not work properly when we change builtin type. */ if(b_image.is_updated()) { scene->image_manager->tag_reload_image( image->filename.string(), image->builtin_data, get_image_interpolation(b_image_node), get_image_extension(b_image_node)); } } image->color_space = (NodeImageColorSpace)b_image_node.color_space(); image->projection = (NodeImageProjection)b_image_node.projection(); image->interpolation = get_image_interpolation(b_image_node); image->extension = get_image_extension(b_image_node); image->projection_blend = b_image_node.projection_blend(); BL::TexMapping b_texture_mapping(b_image_node.texture_mapping()); get_tex_mapping(&image->tex_mapping, b_texture_mapping); node = image; } else if(b_node.is_a(&RNA_ShaderNodeTexEnvironment)) { BL::ShaderNodeTexEnvironment b_env_node(b_node); BL::Image b_image(b_env_node.image()); BL::ImageUser b_image_user(b_env_node.image_user()); EnvironmentTextureNode *env = new EnvironmentTextureNode(); if(b_image) { bool is_builtin = b_image.packed_file() || b_image.source() == BL::Image::source_GENERATED || b_image.source() == BL::Image::source_MOVIE || b_engine.is_preview(); if(is_builtin) { int scene_frame = b_scene.frame_current(); int image_frame = image_user_frame_number(b_image_user, scene_frame); env->filename = b_image.name() + "@" + string_printf("%d", image_frame); env->builtin_data = b_image.ptr.data; } else { env->filename = image_user_file_path(b_image_user, b_image, b_scene.frame_current()); env->builtin_data = NULL; } env->animated = b_env_node.image_user().use_auto_refresh(); env->use_alpha = b_image.use_alpha(); /* TODO(sergey): Does not work properly when we change builtin type. */ if(b_image.is_updated()) { scene->image_manager->tag_reload_image( env->filename.string(), env->builtin_data, get_image_interpolation(b_env_node), EXTENSION_REPEAT); } } env->color_space = (NodeImageColorSpace)b_env_node.color_space(); env->interpolation = get_image_interpolation(b_env_node); env->projection = (NodeEnvironmentProjection)b_env_node.projection(); BL::TexMapping b_texture_mapping(b_env_node.texture_mapping()); get_tex_mapping(&env->tex_mapping, b_texture_mapping); node = env; } else if(b_node.is_a(&RNA_ShaderNodeTexGradient)) { BL::ShaderNodeTexGradient b_gradient_node(b_node); GradientTextureNode *gradient = new GradientTextureNode(); gradient->type = (NodeGradientType)b_gradient_node.gradient_type(); BL::TexMapping b_texture_mapping(b_gradient_node.texture_mapping()); get_tex_mapping(&gradient->tex_mapping, b_texture_mapping); node = gradient; } else if(b_node.is_a(&RNA_ShaderNodeTexVoronoi)) { BL::ShaderNodeTexVoronoi b_voronoi_node(b_node); VoronoiTextureNode *voronoi = new VoronoiTextureNode(); voronoi->coloring = (NodeVoronoiColoring)b_voronoi_node.coloring(); BL::TexMapping b_texture_mapping(b_voronoi_node.texture_mapping()); get_tex_mapping(&voronoi->tex_mapping, b_texture_mapping); node = voronoi; } else if(b_node.is_a(&RNA_ShaderNodeTexMagic)) { BL::ShaderNodeTexMagic b_magic_node(b_node); MagicTextureNode *magic = new MagicTextureNode(); magic->depth = b_magic_node.turbulence_depth(); BL::TexMapping b_texture_mapping(b_magic_node.texture_mapping()); get_tex_mapping(&magic->tex_mapping, b_texture_mapping); node = magic; } else if(b_node.is_a(&RNA_ShaderNodeTexWave)) { BL::ShaderNodeTexWave b_wave_node(b_node); WaveTextureNode *wave = new WaveTextureNode(); wave->type = (NodeWaveType)b_wave_node.wave_type(); wave->profile = (NodeWaveProfile)b_wave_node.wave_profile(); BL::TexMapping b_texture_mapping(b_wave_node.texture_mapping()); get_tex_mapping(&wave->tex_mapping, b_texture_mapping); node = wave; } else if(b_node.is_a(&RNA_ShaderNodeTexChecker)) { BL::ShaderNodeTexChecker b_checker_node(b_node); CheckerTextureNode *checker = new CheckerTextureNode(); BL::TexMapping b_texture_mapping(b_checker_node.texture_mapping()); get_tex_mapping(&checker->tex_mapping, b_texture_mapping); node = checker; } else if(b_node.is_a(&RNA_ShaderNodeTexBrick)) { BL::ShaderNodeTexBrick b_brick_node(b_node); BrickTextureNode *brick = new BrickTextureNode(); brick->offset = b_brick_node.offset(); brick->offset_frequency = b_brick_node.offset_frequency(); brick->squash = b_brick_node.squash(); brick->squash_frequency = b_brick_node.squash_frequency(); BL::TexMapping b_texture_mapping(b_brick_node.texture_mapping()); get_tex_mapping(&brick->tex_mapping, b_texture_mapping); node = brick; } else if(b_node.is_a(&RNA_ShaderNodeTexNoise)) { BL::ShaderNodeTexNoise b_noise_node(b_node); NoiseTextureNode *noise = new NoiseTextureNode(); BL::TexMapping b_texture_mapping(b_noise_node.texture_mapping()); get_tex_mapping(&noise->tex_mapping, b_texture_mapping); node = noise; } else if(b_node.is_a(&RNA_ShaderNodeTexMusgrave)) { BL::ShaderNodeTexMusgrave b_musgrave_node(b_node); MusgraveTextureNode *musgrave = new MusgraveTextureNode(); musgrave->type = (NodeMusgraveType)b_musgrave_node.musgrave_type(); BL::TexMapping b_texture_mapping(b_musgrave_node.texture_mapping()); get_tex_mapping(&musgrave->tex_mapping, b_texture_mapping); node = musgrave; } else if(b_node.is_a(&RNA_ShaderNodeTexCoord)) { BL::ShaderNodeTexCoord b_tex_coord_node(b_node); TextureCoordinateNode *tex_coord = new TextureCoordinateNode(); tex_coord->from_dupli = b_tex_coord_node.from_dupli(); if(b_tex_coord_node.object()) { tex_coord->use_transform = true; tex_coord->ob_tfm = get_transform(b_tex_coord_node.object().matrix_world()); } node = tex_coord; } else if(b_node.is_a(&RNA_ShaderNodeTexSky)) { BL::ShaderNodeTexSky b_sky_node(b_node); SkyTextureNode *sky = new SkyTextureNode(); sky->type = (NodeSkyType)b_sky_node.sky_type(); sky->sun_direction = normalize(get_float3(b_sky_node.sun_direction())); sky->turbidity = b_sky_node.turbidity(); sky->ground_albedo = b_sky_node.ground_albedo(); BL::TexMapping b_texture_mapping(b_sky_node.texture_mapping()); get_tex_mapping(&sky->tex_mapping, b_texture_mapping); node = sky; } else if(b_node.is_a(&RNA_ShaderNodeNormalMap)) { BL::ShaderNodeNormalMap b_normal_map_node(b_node); NormalMapNode *nmap = new NormalMapNode(); nmap->space = (NodeNormalMapSpace)b_normal_map_node.space(); nmap->attribute = b_normal_map_node.uv_map(); node = nmap; } else if(b_node.is_a(&RNA_ShaderNodeTangent)) { BL::ShaderNodeTangent b_tangent_node(b_node); TangentNode *tangent = new TangentNode(); tangent->direction_type = (NodeTangentDirectionType)b_tangent_node.direction_type(); tangent->axis = (NodeTangentAxis)b_tangent_node.axis(); tangent->attribute = b_tangent_node.uv_map(); node = tangent; } else if(b_node.is_a(&RNA_ShaderNodeUVMap)) { BL::ShaderNodeUVMap b_uvmap_node(b_node); UVMapNode *uvm = new UVMapNode(); uvm->attribute = b_uvmap_node.uv_map(); uvm->from_dupli = b_uvmap_node.from_dupli(); node = uvm; } else if(b_node.is_a(&RNA_ShaderNodeTexPointDensity)) { BL::ShaderNodeTexPointDensity b_point_density_node(b_node); PointDensityTextureNode *point_density = new PointDensityTextureNode(); point_density->filename = b_point_density_node.name(); point_density->space = (NodeTexVoxelSpace)b_point_density_node.space(); point_density->interpolation = get_image_interpolation(b_point_density_node); point_density->builtin_data = b_point_density_node.ptr.data; /* 1 - render settings, 0 - vewport settings. */ int settings = background ? 1 : 0; /* TODO(sergey): Use more proper update flag. */ if(true) { b_point_density_node.cache_point_density(b_scene, settings); scene->image_manager->tag_reload_image( point_density->filename.string(), point_density->builtin_data, point_density->interpolation, EXTENSION_CLIP); } node = point_density; /* Transformation form world space to texture space. * * NOTE: Do this after the texture is cached, this is because getting * min/max will need to access this cache. */ BL::Object b_ob(b_point_density_node.object()); if(b_ob) { float3 loc, size; point_density_texture_space(b_scene, b_point_density_node, settings, loc, size); point_density->tfm = transform_translate(-loc) * transform_scale(size) * transform_inverse(get_transform(b_ob.matrix_world())); } } if(node) graph->add(node); return node; }