static void set_default_value(ShaderInput *input, BL::Node b_node, BL::NodeSocket b_sock, BL::BlendData b_data, BL::ID b_id) { /* copy values for non linked inputs */ switch(input->type) { case SHADER_SOCKET_FLOAT: { input->set(get_float(b_sock.ptr, "default_value")); break; } case SHADER_SOCKET_INT: { input->set((float)get_int(b_sock.ptr, "default_value")); break; } case SHADER_SOCKET_COLOR: { input->set(float4_to_float3(get_float4(b_sock.ptr, "default_value"))); break; } case SHADER_SOCKET_NORMAL: case SHADER_SOCKET_POINT: case SHADER_SOCKET_VECTOR: { input->set(get_float3(b_sock.ptr, "default_value")); break; } case SHADER_SOCKET_STRING: { input->set((ustring)blender_absolute_path(b_data, b_id, get_string(b_sock.ptr, "default_value"))); break; } case SHADER_SOCKET_CLOSURE: case SHADER_SOCKET_UNDEFINED: break; } }
/* TODO(sergey): Not really optimal, consider approaches based on k-DOP in order * to reduce number of objects which are wrongly considered visible. */ bool BlenderObjectCulling::test_camera(Scene *scene, float3 bb[8]) { Camera *cam = scene->camera; const ProjectionTransform& worldtondc = cam->worldtondc; float3 bb_min = make_float3(FLT_MAX, FLT_MAX, FLT_MAX), bb_max = make_float3(-FLT_MAX, -FLT_MAX, -FLT_MAX); bool all_behind = true; for(int i = 0; i < 8; ++i) { float3 p = bb[i]; float4 b = make_float4(p.x, p.y, p.z, 1.0f); float4 c = make_float4(dot(worldtondc.x, b), dot(worldtondc.y, b), dot(worldtondc.z, b), dot(worldtondc.w, b)); p = float4_to_float3(c / c.w); if(c.z < 0.0f) { p.x = 1.0f - p.x; p.y = 1.0f - p.y; } if(c.z >= -camera_cull_margin_) { all_behind = false; } bb_min = min(bb_min, p); bb_max = max(bb_max, p); } if(all_behind) { return true; } return (bb_min.x >= 1.0f + camera_cull_margin_ || bb_min.y >= 1.0f + camera_cull_margin_ || bb_max.x <= -camera_cull_margin_ || bb_max.y <= -camera_cull_margin_); }
void BVHSpatialSplit::split_curve_primitive(const Mesh *mesh, const Transform *tfm, int prim_index, int segment_index, int dim, float pos, BoundBox& left_bounds, BoundBox& right_bounds) { /* curve split: NOTE - Currently ignores curve width and needs to be fixed.*/ const int k0 = mesh->curves[prim_index].first_key + segment_index; const int k1 = k0 + 1; const float4& key0 = mesh->curve_keys[k0]; const float4& key1 = mesh->curve_keys[k1]; float3 v0 = float4_to_float3(key0); float3 v1 = float4_to_float3(key1); if(tfm != NULL) { v0 = transform_point(tfm, v0); v1 = transform_point(tfm, v1); } float v0p = v0[dim]; float v1p = v1[dim]; /* insert vertex to the boxes it belongs to. */ if(v0p <= pos) left_bounds.grow(v0); if(v0p >= pos) right_bounds.grow(v0); if(v1p <= pos) left_bounds.grow(v1); if(v1p >= pos) right_bounds.grow(v1); /* edge intersects the plane => insert intersection to both boxes. */ if((v0p < pos && v1p > pos) || (v0p > pos && v1p < pos)) { float3 t = lerp(v0, v1, clamp((pos - v0p) / (v1p - v0p), 0.0f, 1.0f)); left_bounds.grow(t); right_bounds.grow(t); } }
/* TODO(sergey): Not really optimal, consider approaches based on k-DOP in order * to reduce number of objects which are wrongly considered visible. */ static bool object_boundbox_clip(Scene *scene, BL::Object& b_ob, Transform& tfm, float margin) { Camera *cam = scene->camera; Transform& worldtondc = cam->worldtondc; BL::Array<float, 24> boundbox = b_ob.bound_box(); float3 bb_min = make_float3(FLT_MAX, FLT_MAX, FLT_MAX), bb_max = make_float3(-FLT_MAX, -FLT_MAX, -FLT_MAX); bool all_behind = true; for(int i = 0; i < 8; ++i) { float3 p = make_float3(boundbox[3 * i + 0], boundbox[3 * i + 1], boundbox[3 * i + 2]); p = transform_point(&tfm, p); float4 b = make_float4(p.x, p.y, p.z, 1.0f); float4 c = make_float4(dot(worldtondc.x, b), dot(worldtondc.y, b), dot(worldtondc.z, b), dot(worldtondc.w, b)); p = float4_to_float3(c / c.w); if(c.z < 0.0f) { p.x = 1.0f - p.x; p.y = 1.0f - p.y; } if(c.z >= -margin) { all_behind = false; } bb_min = min(bb_min, p); bb_max = max(bb_max, p); } if(!all_behind) { if(bb_min.x >= 1.0f + margin || bb_min.y >= 1.0f + margin || bb_max.x <= -margin || bb_max.y <= -margin) { return true; } return false; } return true; }
static void set_default_value(ShaderInput *input, BL::NodeSocket& b_sock, BL::BlendData& b_data, BL::ID& b_id) { Node *node = input->parent; const SocketType& socket = input->socket_type; /* copy values for non linked inputs */ switch(input->type()) { case SocketType::FLOAT: { node->set(socket, get_float(b_sock.ptr, "default_value")); break; } case SocketType::INT: { node->set(socket, get_int(b_sock.ptr, "default_value")); break; } case SocketType::COLOR: { node->set(socket, float4_to_float3(get_float4(b_sock.ptr, "default_value"))); break; } case SocketType::NORMAL: case SocketType::POINT: case SocketType::VECTOR: { node->set(socket, get_float3(b_sock.ptr, "default_value")); break; } case SocketType::STRING: { node->set(socket, (ustring)blender_absolute_path(b_data, b_id, get_string(b_sock.ptr, "default_value"))); break; } default: break; } }
static void mikk_compute_tangents(BL::Mesh& b_mesh, BL::MeshTextureFaceLayer *b_layer, Mesh *mesh, const vector<int>& nverts, const vector<int>& face_flags, bool need_sign, bool active_render) { /* setup userdata */ MikkUserData userdata(b_mesh, b_layer, nverts.size()); /* setup interface */ SMikkTSpaceInterface sm_interface; memset(&sm_interface, 0, sizeof(sm_interface)); sm_interface.m_getNumFaces = mikk_get_num_faces; sm_interface.m_getNumVerticesOfFace = mikk_get_num_verts_of_face; sm_interface.m_getPosition = mikk_get_position; sm_interface.m_getTexCoord = mikk_get_texture_coordinate; sm_interface.m_getNormal = mikk_get_normal; sm_interface.m_setTSpaceBasic = mikk_set_tangent_space; /* setup context */ SMikkTSpaceContext context; memset(&context, 0, sizeof(context)); context.m_pUserData = &userdata; context.m_pInterface = &sm_interface; /* compute tangents */ genTangSpaceDefault(&context); /* create tangent attributes */ Attribute *attr; ustring name; if(b_layer != NULL) name = ustring((string(b_layer->name().c_str()) + ".tangent").c_str()); else name = ustring("orco.tangent"); if(active_render) attr = mesh->attributes.add(ATTR_STD_UV_TANGENT, name); else attr = mesh->attributes.add(name, TypeDesc::TypeVector, ATTR_ELEMENT_CORNER); float3 *tangent = attr->data_float3(); /* create bitangent sign attribute */ float *tangent_sign = NULL; if(need_sign) { Attribute *attr_sign; ustring name_sign; if(b_layer != NULL) name_sign = ustring((string(b_layer->name().c_str()) + ".tangent_sign").c_str()); else name_sign = ustring("orco.tangent_sign"); if(active_render) attr_sign = mesh->attributes.add(ATTR_STD_UV_TANGENT_SIGN, name_sign); else attr_sign = mesh->attributes.add(name_sign, TypeDesc::TypeFloat, ATTR_ELEMENT_CORNER); tangent_sign = attr_sign->data_float(); } for(int i = 0; i < nverts.size(); i++) { int tri_a[3], tri_b[3]; face_split_tri_indices(nverts[i], face_flags[i], tri_a, tri_b); tangent[0] = float4_to_float3(userdata.tangent[i*4 + tri_a[0]]); tangent[1] = float4_to_float3(userdata.tangent[i*4 + tri_a[1]]); tangent[2] = float4_to_float3(userdata.tangent[i*4 + tri_a[2]]); tangent += 3; if(tangent_sign) { tangent_sign[0] = userdata.tangent[i*4 + tri_a[0]].w; tangent_sign[1] = userdata.tangent[i*4 + tri_a[1]].w; tangent_sign[2] = userdata.tangent[i*4 + tri_a[2]].w; tangent_sign += 3; } if(nverts[i] == 4) { tangent[0] = float4_to_float3(userdata.tangent[i*4 + tri_b[0]]); tangent[1] = float4_to_float3(userdata.tangent[i*4 + tri_b[1]]); tangent[2] = float4_to_float3(userdata.tangent[i*4 + tri_b[2]]); tangent += 3; if(tangent_sign) { tangent_sign[0] = userdata.tangent[i*4 + tri_b[0]].w; tangent_sign[1] = userdata.tangent[i*4 + tri_b[1]].w; tangent_sign[2] = userdata.tangent[i*4 + tri_b[2]].w; tangent_sign += 3; } } } }