static void motion(int x, int y, int button) { if(options.interactive) { Transform matrix = options.session->scene->camera->matrix; /* Translate */ if(button == 0) { float3 translate = make_float3(x * 0.01f, -(y * 0.01f), 0.0f); matrix = matrix * transform_translate(translate); } /* Rotate */ else if(button == 2) { float4 r1 = make_float4((float)x * 0.1f, 0.0f, 1.0f, 0.0f); matrix = matrix * transform_rotate(DEG2RADF(r1.x), make_float3(r1.y, r1.z, r1.w)); float4 r2 = make_float4(y * 0.1f, 1.0f, 0.0f, 0.0f); matrix = matrix * transform_rotate(DEG2RADF(r2.x), make_float3(r2.y, r2.z, r2.w)); } /* Update and Reset */ options.session->scene->camera->matrix = matrix; options.session->scene->camera->need_update = true; options.session->scene->camera->need_device_update = true; options.session->reset(session_buffer_params(), options.session_params.samples); } }
static int bb_render_glyph(void *backend_data, drawctx_t *context, source_t *source, sysarg_t ox, sysarg_t oy, glyph_id_t glyph_id) { bitmap_backend_data_t *data = (bitmap_backend_data_t *) backend_data; glyph_metrics_t glyph_metrics; int rc = bb_get_glyph_metrics(backend_data, glyph_id, &glyph_metrics); if (rc != EOK) return rc; surface_t *glyph_surface; rc = get_glyph_surface(data, glyph_id, &glyph_surface); if (rc != EOK) return rc; native_t x = ox + glyph_metrics.left_side_bearing; native_t y = oy - glyph_metrics.ascender; transform_t transform; transform_identity(&transform); transform_translate(&transform, x, y); source_set_transform(source, transform); source_set_mask(source, glyph_surface, false); drawctx_transfer(context, x, y, glyph_metrics.width, glyph_metrics.height); return EOK; }
static int get_glyph_surface(bitmap_backend_data_t *data, glyph_id_t glyph_id, surface_t **result) { if (glyph_id >= data->glyph_count) return ENOENT; if (data->glyph_cache[glyph_id].surface != NULL) { *result = data->glyph_cache[glyph_id].surface; return EOK; } surface_t *raw_surface; int rc = data->decoder->load_glyph_surface(data->decoder_data, glyph_id, &raw_surface); if (rc != EOK) return rc; sysarg_t w; sysarg_t h; surface_get_resolution(raw_surface, &w, &h); if (!data->scale) { *result = raw_surface; return EOK; } source_t source; source_init(&source); source_set_texture(&source, raw_surface, PIXELMAP_EXTEND_TRANSPARENT_BLACK); transform_t transform; transform_identity(&transform); transform_translate(&transform, 0.5, 0.5); transform_scale(&transform, data->scale_ratio, data->scale_ratio); source_set_transform(&source, transform); surface_coord_t scaled_width = (data->scale_ratio * ((double) w) + 0.5); surface_coord_t scaled_height = (data->scale_ratio * ((double) h) + 0.5); surface_t *scaled_surface = surface_create(scaled_width, scaled_height, NULL, 0); if (!scaled_surface) { surface_destroy(raw_surface); return ENOMEM; } drawctx_t context; drawctx_init(&context, scaled_surface); drawctx_set_source(&context, &source); drawctx_transfer(&context, 0, 0, scaled_width, scaled_height); surface_destroy(raw_surface); data->glyph_cache[glyph_id].surface = scaled_surface; *result = scaled_surface; return EOK; }
static void keyboard(unsigned char key) { /* Toggle help */ if(key == 'h') options.show_help = !(options.show_help); /* Reset */ else if(key == 'r') options.session->reset(session_buffer_params(), options.session_params.samples); /* Cancel */ else if(key == 27) // escape options.session->progress.set_cancel("Canceled"); /* Pause */ else if(key == 'p') { options.pause = !options.pause; options.session->set_pause(options.pause); } /* Interactive Mode */ else if(key == 'i') options.interactive = !(options.interactive); else if(options.interactive && (key == 'w' || key == 'a' || key == 's' || key == 'd')) { Transform matrix = options.session->scene->camera->matrix; float3 translate; if(key == 'w') translate = make_float3(0.0f, 0.0f, 0.1f); else if(key == 's') translate = make_float3(0.0f, 0.0f, -0.1f); else if(key == 'a') translate = make_float3(-0.1f, 0.0f, 0.0f); else if(key == 'd') translate = make_float3(0.1f, 0.0f, 0.0f); matrix = matrix * transform_translate(translate); /* Update and Reset */ options.session->scene->camera->matrix = matrix; options.session->scene->camera->need_update = true; options.session->scene->camera->need_device_update = true; options.session->reset(session_buffer_params(), options.session_params.samples); } }
static void create_mesh(Scene *scene, Mesh *mesh, BL::Mesh &b_mesh, const vector<Shader *> &used_shaders, bool subdivision = false, bool subdivide_uvs = true) { /* count vertices and faces */ int numverts = b_mesh.vertices.length(); int numfaces = (!subdivision) ? b_mesh.loop_triangles.length() : b_mesh.polygons.length(); int numtris = 0; int numcorners = 0; int numngons = 0; bool use_loop_normals = b_mesh.use_auto_smooth() && (mesh->subdivision_type != Mesh::SUBDIVISION_CATMULL_CLARK); /* If no faces, create empty mesh. */ if (numfaces == 0) { return; } if (!subdivision) { numtris = numfaces; } else { BL::Mesh::polygons_iterator p; for (b_mesh.polygons.begin(p); p != b_mesh.polygons.end(); ++p) { numngons += (p->loop_total() == 4) ? 0 : 1; numcorners += p->loop_total(); } } /* allocate memory */ mesh->reserve_mesh(numverts, numtris); mesh->reserve_subd_faces(numfaces, numngons, numcorners); /* create vertex coordinates and normals */ BL::Mesh::vertices_iterator v; for (b_mesh.vertices.begin(v); v != b_mesh.vertices.end(); ++v) mesh->add_vertex(get_float3(v->co())); AttributeSet &attributes = (subdivision) ? mesh->subd_attributes : mesh->attributes; Attribute *attr_N = attributes.add(ATTR_STD_VERTEX_NORMAL); float3 *N = attr_N->data_float3(); for (b_mesh.vertices.begin(v); v != b_mesh.vertices.end(); ++v, ++N) *N = get_float3(v->normal()); N = attr_N->data_float3(); /* create generated coordinates from undeformed coordinates */ const bool need_default_tangent = (subdivision == false) && (b_mesh.uv_layers.length() == 0) && (mesh->need_attribute(scene, ATTR_STD_UV_TANGENT)); if (mesh->need_attribute(scene, ATTR_STD_GENERATED) || need_default_tangent) { Attribute *attr = attributes.add(ATTR_STD_GENERATED); attr->flags |= ATTR_SUBDIVIDED; float3 loc, size; mesh_texture_space(b_mesh, loc, size); float3 *generated = attr->data_float3(); size_t i = 0; for (b_mesh.vertices.begin(v); v != b_mesh.vertices.end(); ++v) { generated[i++] = get_float3(v->undeformed_co()) * size - loc; } } /* create faces */ if (!subdivision) { BL::Mesh::loop_triangles_iterator t; for (b_mesh.loop_triangles.begin(t); t != b_mesh.loop_triangles.end(); ++t) { BL::MeshPolygon p = b_mesh.polygons[t->polygon_index()]; int3 vi = get_int3(t->vertices()); int shader = clamp(p.material_index(), 0, used_shaders.size() - 1); bool smooth = p.use_smooth() || use_loop_normals; if (use_loop_normals) { BL::Array<float, 9> loop_normals = t->split_normals(); for (int i = 0; i < 3; i++) { N[vi[i]] = make_float3( loop_normals[i * 3], loop_normals[i * 3 + 1], loop_normals[i * 3 + 2]); } } /* Create triangles. * * NOTE: Autosmooth is already taken care about. */ mesh->add_triangle(vi[0], vi[1], vi[2], shader, smooth); } } else { BL::Mesh::polygons_iterator p; vector<int> vi; for (b_mesh.polygons.begin(p); p != b_mesh.polygons.end(); ++p) { int n = p->loop_total(); int shader = clamp(p->material_index(), 0, used_shaders.size() - 1); bool smooth = p->use_smooth() || use_loop_normals; vi.resize(n); for (int i = 0; i < n; i++) { /* NOTE: Autosmooth is already taken care about. */ vi[i] = b_mesh.loops[p->loop_start() + i].vertex_index(); } /* create subd faces */ mesh->add_subd_face(&vi[0], n, shader, smooth); } } /* Create all needed attributes. * The calculate functions will check whether they're needed or not. */ attr_create_pointiness(scene, mesh, b_mesh, subdivision); attr_create_vertex_color(scene, mesh, b_mesh, subdivision); if (subdivision) { attr_create_subd_uv_map(scene, mesh, b_mesh, subdivide_uvs); } else { attr_create_uv_map(scene, mesh, b_mesh); } /* for volume objects, create a matrix to transform from object space to * mesh texture space. this does not work with deformations but that can * probably only be done well with a volume grid mapping of coordinates */ if (mesh->need_attribute(scene, ATTR_STD_GENERATED_TRANSFORM)) { Attribute *attr = mesh->attributes.add(ATTR_STD_GENERATED_TRANSFORM); Transform *tfm = attr->data_transform(); float3 loc, size; mesh_texture_space(b_mesh, loc, size); *tfm = transform_translate(-loc) * transform_scale(size); } }
static void create_mesh(Scene *scene, Mesh *mesh, BL::Mesh& b_mesh, const vector<uint>& used_shaders) { /* count vertices and faces */ int numverts = b_mesh.vertices.length(); int numfaces = b_mesh.tessfaces.length(); int numtris = 0; bool use_loop_normals = b_mesh.use_auto_smooth(); BL::Mesh::vertices_iterator v; BL::Mesh::tessfaces_iterator f; for(b_mesh.tessfaces.begin(f); f != b_mesh.tessfaces.end(); ++f) { int4 vi = get_int4(f->vertices_raw()); numtris += (vi[3] == 0)? 1: 2; } /* reserve memory */ mesh->reserve(numverts, numtris, 0, 0); /* create vertex coordinates and normals */ int i = 0; for(b_mesh.vertices.begin(v); v != b_mesh.vertices.end(); ++v, ++i) mesh->verts[i] = get_float3(v->co()); Attribute *attr_N = mesh->attributes.add(ATTR_STD_VERTEX_NORMAL); float3 *N = attr_N->data_float3(); for(b_mesh.vertices.begin(v); v != b_mesh.vertices.end(); ++v, ++N) *N = get_float3(v->normal()); N = attr_N->data_float3(); /* create generated coordinates from undeformed coordinates */ if(mesh->need_attribute(scene, ATTR_STD_GENERATED)) { Attribute *attr = mesh->attributes.add(ATTR_STD_GENERATED); float3 loc, size; mesh_texture_space(b_mesh, loc, size); float3 *generated = attr->data_float3(); size_t i = 0; for(b_mesh.vertices.begin(v); v != b_mesh.vertices.end(); ++v) generated[i++] = get_float3(v->undeformed_co())*size - loc; } /* Create needed vertex attributes. */ attr_create_pointiness(scene, mesh, b_mesh); /* create faces */ vector<int> nverts(numfaces); vector<int> face_flags(numfaces, FACE_FLAG_NONE); int fi = 0, ti = 0; for(b_mesh.tessfaces.begin(f); f != b_mesh.tessfaces.end(); ++f, ++fi) { int4 vi = get_int4(f->vertices_raw()); int n = (vi[3] == 0)? 3: 4; int mi = clamp(f->material_index(), 0, used_shaders.size()-1); int shader = used_shaders[mi]; bool smooth = f->use_smooth() || use_loop_normals; /* split vertices if normal is different * * note all vertex attributes must have been set here so we can split * and copy attributes in split_vertex without remapping later */ if(use_loop_normals) { BL::Array<float, 12> loop_normals = f->split_normals(); for(int i = 0; i < n; i++) { float3 loop_N = make_float3(loop_normals[i * 3], loop_normals[i * 3 + 1], loop_normals[i * 3 + 2]); if(N[vi[i]] != loop_N) { int new_vi = mesh->split_vertex(vi[i]); /* set new normal and vertex index */ N = attr_N->data_float3(); N[new_vi] = loop_N; vi[i] = new_vi; } } } /* create triangles */ if(n == 4) { if(is_zero(cross(mesh->verts[vi[1]] - mesh->verts[vi[0]], mesh->verts[vi[2]] - mesh->verts[vi[0]])) || is_zero(cross(mesh->verts[vi[2]] - mesh->verts[vi[0]], mesh->verts[vi[3]] - mesh->verts[vi[0]]))) { mesh->set_triangle(ti++, vi[0], vi[1], vi[3], shader, smooth); mesh->set_triangle(ti++, vi[2], vi[3], vi[1], shader, smooth); face_flags[fi] |= FACE_FLAG_DIVIDE_24; } else { mesh->set_triangle(ti++, vi[0], vi[1], vi[2], shader, smooth); mesh->set_triangle(ti++, vi[0], vi[2], vi[3], shader, smooth); face_flags[fi] |= FACE_FLAG_DIVIDE_13; } } else mesh->set_triangle(ti++, vi[0], vi[1], vi[2], shader, smooth); nverts[fi] = n; } /* Create all needed attributes. * The calculate functions will check whether they're needed or not. */ attr_create_vertex_color(scene, mesh, b_mesh, nverts, face_flags); attr_create_uv_map(scene, mesh, b_mesh, nverts, face_flags); /* for volume objects, create a matrix to transform from object space to * mesh texture space. this does not work with deformations but that can * probably only be done well with a volume grid mapping of coordinates */ if(mesh->need_attribute(scene, ATTR_STD_GENERATED_TRANSFORM)) { Attribute *attr = mesh->attributes.add(ATTR_STD_GENERATED_TRANSFORM); Transform *tfm = attr->data_transform(); float3 loc, size; mesh_texture_space(b_mesh, loc, size); *tfm = transform_translate(-loc)*transform_scale(size); } }
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::update() { if(!need_update) return; /* ndc to raster */ Transform screentocamera; Transform ndctoraster = transform_scale(width, height, 1.0f); /* raster to screen */ Transform screentondc = transform_scale(1.0f/(viewplane.right - viewplane.left), 1.0f/(viewplane.top - viewplane.bottom), 1.0f) * transform_translate(-viewplane.left, -viewplane.bottom, 0.0f); 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, 0, 0); dy = make_float3(0, 0, 0); } dx = transform_direction(&cameratoworld, dx); dy = transform_direction(&cameratoworld, dy); need_update = false; need_device_update = true; }
static void create_mesh(Scene *scene, Mesh *mesh, BL::Mesh b_mesh, const vector<uint>& used_shaders) { /* count vertices and faces */ int numverts = b_mesh.vertices.length(); int numfaces = b_mesh.tessfaces.length(); int numtris = 0; bool use_loop_normals = b_mesh.use_auto_smooth(); BL::Mesh::vertices_iterator v; BL::Mesh::tessfaces_iterator f; for(b_mesh.tessfaces.begin(f); f != b_mesh.tessfaces.end(); ++f) { int4 vi = get_int4(f->vertices_raw()); numtris += (vi[3] == 0)? 1: 2; } /* reserve memory */ mesh->reserve(numverts, numtris, 0, 0); /* create vertex coordinates and normals */ int i = 0; for(b_mesh.vertices.begin(v); v != b_mesh.vertices.end(); ++v, ++i) mesh->verts[i] = get_float3(v->co()); Attribute *attr_N = mesh->attributes.add(ATTR_STD_VERTEX_NORMAL); float3 *N = attr_N->data_float3(); for(b_mesh.vertices.begin(v); v != b_mesh.vertices.end(); ++v, ++N) *N = get_float3(v->normal()); N = attr_N->data_float3(); /* create generated coordinates from undeformed coordinates */ if(mesh->need_attribute(scene, ATTR_STD_GENERATED)) { Attribute *attr = mesh->attributes.add(ATTR_STD_GENERATED); float3 loc, size; mesh_texture_space(b_mesh, loc, size); float3 *generated = attr->data_float3(); size_t i = 0; for(b_mesh.vertices.begin(v); v != b_mesh.vertices.end(); ++v) generated[i++] = get_float3(v->undeformed_co())*size - loc; } /* create faces */ vector<int> nverts(numfaces); int fi = 0, ti = 0; for(b_mesh.tessfaces.begin(f); f != b_mesh.tessfaces.end(); ++f, ++fi) { int4 vi = get_int4(f->vertices_raw()); int n = (vi[3] == 0)? 3: 4; int mi = clamp(f->material_index(), 0, used_shaders.size()-1); int shader = used_shaders[mi]; bool smooth = f->use_smooth(); /* split vertices if normal is different * * note all vertex attributes must have been set here so we can split * and copy attributes in split_vertex without remapping later */ if(use_loop_normals) { BL::Array<float, 12> loop_normals = f->split_normals(); for(int i = 0; i < n; i++) { float3 loop_N = make_float3(loop_normals[i * 3], loop_normals[i * 3 + 1], loop_normals[i * 3 + 2]); if(N[vi[i]] != loop_N) { int new_vi = mesh->split_vertex(vi[i]); /* set new normal and vertex index */ N = attr_N->data_float3(); N[new_vi] = loop_N; vi[i] = new_vi; } } } /* create triangles */ if(n == 4) { if(is_zero(cross(mesh->verts[vi[1]] - mesh->verts[vi[0]], mesh->verts[vi[2]] - mesh->verts[vi[0]])) || is_zero(cross(mesh->verts[vi[2]] - mesh->verts[vi[0]], mesh->verts[vi[3]] - mesh->verts[vi[0]]))) { mesh->set_triangle(ti++, vi[0], vi[1], vi[3], shader, smooth); mesh->set_triangle(ti++, vi[2], vi[3], vi[1], shader, smooth); } else { mesh->set_triangle(ti++, vi[0], vi[1], vi[2], shader, smooth); mesh->set_triangle(ti++, vi[0], vi[2], vi[3], shader, smooth); } } else mesh->set_triangle(ti++, vi[0], vi[1], vi[2], shader, smooth); nverts[fi] = n; } /* create vertex color attributes */ { BL::Mesh::tessface_vertex_colors_iterator l; for(b_mesh.tessface_vertex_colors.begin(l); l != b_mesh.tessface_vertex_colors.end(); ++l) { if(!mesh->need_attribute(scene, ustring(l->name().c_str()))) continue; Attribute *attr = mesh->attributes.add( ustring(l->name().c_str()), TypeDesc::TypeColor, ATTR_ELEMENT_CORNER); BL::MeshColorLayer::data_iterator c; float3 *fdata = attr->data_float3(); size_t i = 0; for(l->data.begin(c); c != l->data.end(); ++c, ++i) { fdata[0] = color_srgb_to_scene_linear(get_float3(c->color1())); fdata[1] = color_srgb_to_scene_linear(get_float3(c->color2())); fdata[2] = color_srgb_to_scene_linear(get_float3(c->color3())); if(nverts[i] == 4) { fdata[3] = fdata[0]; fdata[4] = fdata[2]; fdata[5] = color_srgb_to_scene_linear(get_float3(c->color4())); fdata += 6; } else fdata += 3; } } } /* create uv map attributes */ { BL::Mesh::tessface_uv_textures_iterator l; for(b_mesh.tessface_uv_textures.begin(l); l != b_mesh.tessface_uv_textures.end(); ++l) { bool active_render = l->active_render(); AttributeStandard std = (active_render)? ATTR_STD_UV: ATTR_STD_NONE; ustring name = ustring(l->name().c_str()); /* UV map */ if(mesh->need_attribute(scene, name) || mesh->need_attribute(scene, std)) { Attribute *attr; if(active_render) attr = mesh->attributes.add(std, name); else attr = mesh->attributes.add(name, TypeDesc::TypePoint, ATTR_ELEMENT_CORNER); BL::MeshTextureFaceLayer::data_iterator t; float3 *fdata = attr->data_float3(); size_t i = 0; for(l->data.begin(t); t != l->data.end(); ++t, ++i) { fdata[0] = get_float3(t->uv1()); fdata[1] = get_float3(t->uv2()); fdata[2] = get_float3(t->uv3()); fdata += 3; if(nverts[i] == 4) { fdata[0] = get_float3(t->uv1()); fdata[1] = get_float3(t->uv3()); fdata[2] = get_float3(t->uv4()); fdata += 3; } } } /* UV tangent */ std = (active_render)? ATTR_STD_UV_TANGENT: ATTR_STD_NONE; name = ustring((string(l->name().c_str()) + ".tangent").c_str()); if(mesh->need_attribute(scene, name) || (active_render && mesh->need_attribute(scene, std))) { std = (active_render)? ATTR_STD_UV_TANGENT_SIGN: ATTR_STD_NONE; name = ustring((string(l->name().c_str()) + ".tangent_sign").c_str()); bool need_sign = (mesh->need_attribute(scene, name) || mesh->need_attribute(scene, std)); mikk_compute_tangents(b_mesh, *l, mesh, nverts, need_sign, active_render); } } } /* for volume objects, create a matrix to transform from object space to * mesh texture space. this does not work with deformations but that can * probably only be done well with a volume grid mapping of coordinates */ if(mesh->need_attribute(scene, ATTR_STD_GENERATED_TRANSFORM)) { Attribute *attr = mesh->attributes.add(ATTR_STD_GENERATED_TRANSFORM); Transform *tfm = attr->data_transform(); float3 loc, size; mesh_texture_space(b_mesh, loc, size); *tfm = transform_translate(-loc)*transform_scale(size); } }
static void keyboard(unsigned char key) { /* Toggle help */ if(key == 'h') options.show_help = !(options.show_help); /* Reset */ else if(key == 'r') options.session->reset(session_buffer_params(), options.session_params.samples); /* Cancel */ else if(key == 27) // escape options.session->progress.set_cancel("Canceled"); /* Pause */ else if(key == 'p') { options.pause = !options.pause; options.session->set_pause(options.pause); } /* Interactive Mode */ else if(key == 'i') options.interactive = !(options.interactive); /* Navigation */ else if(options.interactive && (key == 'w' || key == 'a' || key == 's' || key == 'd')) { Transform matrix = options.session->scene->camera->matrix; float3 translate; if(key == 'w') translate = make_float3(0.0f, 0.0f, 0.1f); else if(key == 's') translate = make_float3(0.0f, 0.0f, -0.1f); else if(key == 'a') translate = make_float3(-0.1f, 0.0f, 0.0f); else if(key == 'd') translate = make_float3(0.1f, 0.0f, 0.0f); matrix = matrix * transform_translate(translate); /* Update and Reset */ options.session->scene->camera->matrix = matrix; options.session->scene->camera->need_update = true; options.session->scene->camera->need_device_update = true; options.session->reset(session_buffer_params(), options.session_params.samples); } /* Set Max Bounces */ else if(options.interactive && (key == '0' || key == '1' || key == '2' || key == '3')) { int bounce; switch(key) { case '0': bounce = 0; break; case '1': bounce = 1; break; case '2': bounce = 2; break; case '3': bounce = 3; break; default: bounce = 0; break; } options.session->scene->integrator->max_bounce = bounce; /* Update and Reset */ options.session->scene->integrator->need_update = true; options.session->reset(session_buffer_params(), options.session_params.samples); } }
void write_glv_output(logdata_p logdata, char *out_filename) { int i, j, first_scan = 1; transform_t t; transform_point_t p; double angle; double d1, d2, d3, d4; carmen_FILE *out_fp; out_fp = carmen_fopen(out_filename, "w"); /* write path to glv file */ write_color_glv(out_fp, 255, 255, 0); for (i = 1; i < logdata->num_pos; i++) write_line_glv(out_fp, logdata->pos[i-1].x, logdata->pos[i-1].y, logdata->pos[i-1].z, logdata->pos[i].x, logdata->pos[i].y, logdata->pos[i].z); /* write scan to glv file */ for (i = 0; i < logdata->num_laser; i++) { if (!logdata->laser[i].ignore) { int num_readings = logdata->laser[i].num_readings; float local_x[num_readings]; point3D_t last_scan[num_readings], current_scan[num_readings]; char pointclass[num_readings], last_pointclass[num_readings]; if(i % 100 == 0) fprintf(stderr, "\rProjecting points... (%.0f%%) ", i/(float)logdata->num_laser*100.0); transform_init_identity(t); transform_rotate(t, logdata->laser[i].yaw, logdata->laser[i].pitch, logdata->laser[i].roll); transform_translate(t, logdata->laser[i].x, logdata->laser[i].y, logdata->laser[i].z); for (j = 0; j < num_readings; j++) { angle = logdata->laser[i].start_angle+ j/(float)num_readings*logdata->laser[i].fov; transform_point_init(&p, logdata->laser[i].range[j]*cos(angle), logdata->laser[i].range[j]*sin(angle), 0.0); transform_point(t, &p); pointclass[j] = TYPE_UNKNOWN; if (classify_points) { if (logdata->laser[i].range[j] > max_range) pointclass[j] = TYPE_IGNORE; else if (p.z > 0.0) pointclass[j] = TYPE_OBSTACLE; if (pointclass[j] == TYPE_UNKNOWN) local_x[j] = hypot(p.x-logdata->laser[i].x, p.y-logdata->laser[i].y); } last_scan[j] = current_scan[j]; last_pointclass[j] = pointclass[j]; current_scan[j].x = p.x; current_scan[j].y = p.y; current_scan[j].z = p.z; current_scan[j].meshed = 0; current_scan[j].range = logdata->laser[i].range[j]; } if (classify_points) classify_scan(num_readings, current_scan, local_x, pointclass); write_color_glv(out_fp, 255, 255, 255); for (j = 0; j < num_readings; j++) { if (generate_faces && !first_scan && j > 0) { d1 = logdata->laser[i].range[j-1]-logdata->laser[i-1].range[j-1]; d2 = logdata->laser[i].range[j]-logdata->laser[i].range[j-1]; d3 = logdata->laser[i-1].range[j]-logdata->laser[i].range[j]; d4 = logdata->laser[i-1].range[j-1]-logdata->laser[i-1].range[j]; if (fabs(d1) < connect_dist && fabs(d2) < connect_dist && fabs(d3) < connect_dist && fabs(d4) < connect_dist && logdata->laser[i].range[j-1] < max_range && logdata->laser[i-1].range[j-1] < max_range && logdata->laser[i].range[j] < max_range && logdata->laser[i-1].range[j] < max_range) { if (pointclass[j] == TYPE_OBSTACLE || pointclass[j-1] == TYPE_OBSTACLE) write_color_glv(out_fp, 100, 100, 255); else write_color_glv(out_fp, 255, 255, 255); write_face_glv(out_fp, last_scan[j-1].x, last_scan[j-1].y, last_scan[j-1].z, current_scan[j-1].x, current_scan[j-1].y, current_scan[j-1].z, current_scan[j].x, current_scan[j].y, current_scan[j].z); write_face_glv(out_fp, last_scan[j-1].x, last_scan[j-1].y, last_scan[j-1].z, current_scan[j].x, current_scan[j].y, current_scan[j].z, last_scan[j].x, last_scan[j].y, last_scan[j].z); last_scan[j].meshed = 1; last_scan[j-1].meshed = 1; current_scan[j].meshed = 1; current_scan[j-1].meshed = 1; } } } if (generate_faces) { write_color_glv(out_fp, 255, 255, 255); for (j = 0; j < num_readings; j++) { if (last_pointclass[j] == TYPE_SAFE && !last_scan[j].meshed && !first_scan && last_scan[j].range < max_range) write_point_glv(out_fp, last_scan[j].x, last_scan[j].y, last_scan[j].z); } write_color_glv(out_fp, 100, 100, 255); for (j = 0; j < num_readings; j++) { if (last_pointclass[j] == TYPE_OBSTACLE && !last_scan[j].meshed && !first_scan && last_scan[j].range < max_range) write_point_glv(out_fp, last_scan[j].x, last_scan[j].y, last_scan[j].z); } } else { write_color_glv(out_fp, 255, 255, 255); for (j = 0; j < num_readings; j++) { if ((pointclass[j] == TYPE_SAFE) || (pointclass[j] == TYPE_UNKNOWN)) write_point_glv(out_fp, current_scan[j].x, current_scan[j].y, current_scan[j].z); } write_color_glv(out_fp, 100, 100, 255); for (j = 0; j < num_readings; j++) { if (pointclass[j] == TYPE_OBSTACLE) write_point_glv(out_fp, current_scan[j].x, current_scan[j].y, current_scan[j].z); } } first_scan = 0; } } fprintf(stderr, "\rProjecting points... (100%%) \n"); carmen_fclose(out_fp); }
static void create_mesh(Scene *scene, Mesh *mesh, BL::Mesh& b_mesh, const vector<Shader*>& used_shaders, bool subdivision=false, bool subdivide_uvs=true) { /* count vertices and faces */ int numverts = b_mesh.vertices.length(); int numfaces = (!subdivision) ? b_mesh.tessfaces.length() : b_mesh.polygons.length(); int numtris = 0; int numcorners = 0; int numngons = 0; bool use_loop_normals = b_mesh.use_auto_smooth() && (mesh->subdivision_type != Mesh::SUBDIVISION_CATMULL_CLARK); BL::Mesh::vertices_iterator v; BL::Mesh::tessfaces_iterator f; BL::Mesh::polygons_iterator p; if(!subdivision) { for(b_mesh.tessfaces.begin(f); f != b_mesh.tessfaces.end(); ++f) { int4 vi = get_int4(f->vertices_raw()); numtris += (vi[3] == 0)? 1: 2; } } else { for(b_mesh.polygons.begin(p); p != b_mesh.polygons.end(); ++p) { numngons += (p->loop_total() == 4)? 0: 1; numcorners += p->loop_total(); } } /* allocate memory */ mesh->reserve_mesh(numverts, numtris); mesh->reserve_subd_faces(numfaces, numngons, numcorners); /* create vertex coordinates and normals */ for(b_mesh.vertices.begin(v); v != b_mesh.vertices.end(); ++v) mesh->add_vertex(get_float3(v->co())); AttributeSet& attributes = (subdivision)? mesh->subd_attributes: mesh->attributes; Attribute *attr_N = attributes.add(ATTR_STD_VERTEX_NORMAL); float3 *N = attr_N->data_float3(); for(b_mesh.vertices.begin(v); v != b_mesh.vertices.end(); ++v, ++N) *N = get_float3(v->normal()); N = attr_N->data_float3(); /* create generated coordinates from undeformed coordinates */ if(mesh->need_attribute(scene, ATTR_STD_GENERATED)) { Attribute *attr = attributes.add(ATTR_STD_GENERATED); attr->flags |= ATTR_SUBDIVIDED; float3 loc, size; mesh_texture_space(b_mesh, loc, size); float3 *generated = attr->data_float3(); size_t i = 0; for(b_mesh.vertices.begin(v); v != b_mesh.vertices.end(); ++v) generated[i++] = get_float3(v->undeformed_co())*size - loc; } /* Create needed vertex attributes. */ attr_create_pointiness(scene, mesh, b_mesh, subdivision); /* create faces */ vector<int> nverts(numfaces); vector<int> face_flags(numfaces, FACE_FLAG_NONE); int fi = 0; if(!subdivision) { for(b_mesh.tessfaces.begin(f); f != b_mesh.tessfaces.end(); ++f, ++fi) { int4 vi = get_int4(f->vertices_raw()); int n = (vi[3] == 0)? 3: 4; int shader = clamp(f->material_index(), 0, used_shaders.size()-1); bool smooth = f->use_smooth() || use_loop_normals; /* split vertices if normal is different * * note all vertex attributes must have been set here so we can split * and copy attributes in split_vertex without remapping later */ if(use_loop_normals) { BL::Array<float, 12> loop_normals = f->split_normals(); for(int i = 0; i < n; i++) { float3 loop_N = make_float3(loop_normals[i * 3], loop_normals[i * 3 + 1], loop_normals[i * 3 + 2]); if(N[vi[i]] != loop_N) { int new_vi = mesh->split_vertex(vi[i]); /* set new normal and vertex index */ N = attr_N->data_float3(); N[new_vi] = loop_N; vi[i] = new_vi; } } } /* create triangles */ if(n == 4) { if(is_zero(cross(mesh->verts[vi[1]] - mesh->verts[vi[0]], mesh->verts[vi[2]] - mesh->verts[vi[0]])) || is_zero(cross(mesh->verts[vi[2]] - mesh->verts[vi[0]], mesh->verts[vi[3]] - mesh->verts[vi[0]]))) { mesh->add_triangle(vi[0], vi[1], vi[3], shader, smooth); mesh->add_triangle(vi[2], vi[3], vi[1], shader, smooth); face_flags[fi] |= FACE_FLAG_DIVIDE_24; } else { mesh->add_triangle(vi[0], vi[1], vi[2], shader, smooth); mesh->add_triangle(vi[0], vi[2], vi[3], shader, smooth); face_flags[fi] |= FACE_FLAG_DIVIDE_13; } } else { mesh->add_triangle(vi[0], vi[1], vi[2], shader, smooth); } nverts[fi] = n; } } else { vector<int> vi; for(b_mesh.polygons.begin(p); p != b_mesh.polygons.end(); ++p) { int n = p->loop_total(); int shader = clamp(p->material_index(), 0, used_shaders.size()-1); bool smooth = p->use_smooth() || use_loop_normals; vi.reserve(n); for(int i = 0; i < n; i++) { vi[i] = b_mesh.loops[p->loop_start() + i].vertex_index(); /* split vertices if normal is different * * note all vertex attributes must have been set here so we can split * and copy attributes in split_vertex without remapping later */ if(use_loop_normals) { float3 loop_N = get_float3(b_mesh.loops[p->loop_start() + i].normal()); if(N[vi[i]] != loop_N) { int new_vi = mesh->split_vertex(vi[i]); /* set new normal and vertex index */ N = attr_N->data_float3(); N[new_vi] = loop_N; vi[i] = new_vi; } } } /* create subd faces */ mesh->add_subd_face(&vi[0], n, shader, smooth); } } /* Create all needed attributes. * The calculate functions will check whether they're needed or not. */ attr_create_vertex_color(scene, mesh, b_mesh, nverts, face_flags, subdivision); attr_create_uv_map(scene, mesh, b_mesh, nverts, face_flags, subdivision, subdivide_uvs); /* for volume objects, create a matrix to transform from object space to * mesh texture space. this does not work with deformations but that can * probably only be done well with a volume grid mapping of coordinates */ if(mesh->need_attribute(scene, ATTR_STD_GENERATED_TRANSFORM)) { Attribute *attr = mesh->attributes.add(ATTR_STD_GENERATED_TRANSFORM); Transform *tfm = attr->data_transform(); float3 loc, size; mesh_texture_space(b_mesh, loc, size); *tfm = transform_translate(-loc)*transform_scale(size); } }
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; }