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;
	}
}
Example #2
0
/* 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_);
}
Example #3
0
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);
	}
}
Example #4
0
/* 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;
	}
}
Example #6
0
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;
			}
		}
	}
}