コード例 #1
0
ファイル: editcurve_paint.c プロジェクト: UPBGE/blender
static bool stroke_elem_project_fallback(
        const struct CurveDrawData *cdd,
        const int mval_i[2], const float mval_fl[2],
        const float surface_offset, const float radius,
        const float location_fallback_depth[3],
        float r_location_world[3], float r_location_local[3],
        float r_normal_world[3], float r_normal_local[3])
{
	bool is_depth_found = stroke_elem_project(
	        cdd, mval_i, mval_fl,
	        surface_offset, radius,
	        r_location_world, r_normal_world);
	if (is_depth_found == false) {
		ED_view3d_win_to_3d(cdd->vc.v3d, cdd->vc.ar, location_fallback_depth, mval_fl, r_location_world);
		zero_v3(r_normal_local);
	}
	mul_v3_m4v3(r_location_local, cdd->vc.obedit->imat, r_location_world);

	if (!is_zero_v3(r_normal_world)) {
		copy_v3_v3(r_normal_local, r_normal_world);
		mul_transposed_mat3_m4_v3(cdd->vc.obedit->obmat, r_normal_local);
		normalize_v3(r_normal_local);
	}
	else {
		zero_v3(r_normal_local);
	}

	return is_depth_found;
}
コード例 #2
0
/**
 * This function returns the coordinate and normal of a barycentric u,v for a face defined by the primitive_id index.
 * The returned coordinate is extruded along the normal by cage_extrusion
 */
static void calc_point_from_barycentric_extrusion(
        TriTessFace *triangles,
        float mat[4][4], float imat[4][4],
        int primitive_id, float u, float v,
        float cage_extrusion,
        float r_co[3], float r_dir[3],
        const bool is_cage)
{
	float data[3][3];
	float coord[3];
	float dir[3];
	float cage[3];
	bool is_smooth;

	TriTessFace *triangle = &triangles[primitive_id];
	is_smooth = triangle->is_smooth || is_cage;

	copy_v3_v3(data[0], triangle->mverts[0]->co);
	copy_v3_v3(data[1], triangle->mverts[1]->co);
	copy_v3_v3(data[2], triangle->mverts[2]->co);

	interp_barycentric_tri_v3(data, u, v, coord);

	if (is_smooth) {
		normal_short_to_float_v3(data[0], triangle->mverts[0]->no);
		normal_short_to_float_v3(data[1], triangle->mverts[1]->no);
		normal_short_to_float_v3(data[2], triangle->mverts[2]->no);

		interp_barycentric_tri_v3(data, u, v, dir);
		normalize_v3(dir);
	}
	else {
		copy_v3_v3(dir, triangle->normal);
	}

	mul_v3_v3fl(cage, dir, cage_extrusion);
	add_v3_v3(coord, cage);

	normalize_v3(dir);
	negate_v3(dir);

	/* convert from local to world space */
	mul_m4_v3(mat, coord);
	mul_transposed_mat3_m4_v3(imat, dir);
	normalize_v3(dir);

	copy_v3_v3(r_co, coord);
	copy_v3_v3(r_dir, dir);
}
コード例 #3
0
/**
 * This function converts an object space normal map to a tangent space normal map for a given low poly mesh
 */
void RE_bake_normal_world_to_tangent(
        const BakePixel pixel_array[], const size_t num_pixels, const int depth,
        float result[], Mesh *me, const BakeNormalSwizzle normal_swizzle[3],
        float mat[4][4])
{
	size_t i;

	TriTessFace *triangles;

	DerivedMesh *dm = CDDM_from_mesh(me);

	triangles = MEM_mallocN(sizeof(TriTessFace) * (me->totface * 2), "MVerts Mesh");
	mesh_calc_tri_tessface(triangles, me, true, dm);

	BLI_assert(num_pixels >= 3);

	for (i = 0; i < num_pixels; i++) {
		TriTessFace *triangle;
		float tangents[3][3];
		float normals[3][3];
		float signs[3];
		int j;

		float tangent[3];
		float normal[3];
		float binormal[3];
		float sign;
		float u, v, w;

		float tsm[3][3]; /* tangent space matrix */
		float itsm[3][3];

		size_t offset;
		float nor[3]; /* texture normal */

		bool is_smooth;

		int primitive_id = pixel_array[i].primitive_id;

		offset = i * depth;

		if (primitive_id == -1) {
			copy_v3_fl3(&result[offset], 0.5f, 0.5f, 1.0f);
			continue;
		}

		triangle = &triangles[primitive_id];
		is_smooth = triangle->is_smooth;

		for (j = 0; j < 3; j++) {
			const TSpace *ts;

			if (is_smooth)
				normal_short_to_float_v3(normals[j], triangle->mverts[j]->no);
			else
				normal[j] = triangle->normal[j];

			ts = triangle->tspace[j];
			copy_v3_v3(tangents[j], ts->tangent);
			signs[j] = ts->sign;
		}

		u = pixel_array[i].uv[0];
		v = pixel_array[i].uv[1];
		w = 1.0f - u - v;

		/* normal */
		if (is_smooth)
			interp_barycentric_tri_v3(normals, u, v, normal);

		/* tangent */
		interp_barycentric_tri_v3(tangents, u, v, tangent);

		/* sign */
		/* The sign is the same at all face vertices for any non degenerate face.
		 * Just in case we clamp the interpolated value though. */
		sign = (signs[0]  * u + signs[1]  * v + signs[2] * w) < 0 ? (-1.0f) : 1.0f;

		/* binormal */
		/* B = sign * cross(N, T)  */
		cross_v3_v3v3(binormal, normal, tangent);
		mul_v3_fl(binormal, sign);

		/* populate tangent space matrix */
		copy_v3_v3(tsm[0], tangent);
		copy_v3_v3(tsm[1], binormal);
		copy_v3_v3(tsm[2], normal);

		/* texture values */
		normal_uncompress(nor, &result[offset]);

		/* converts from world space to local space */
		mul_transposed_mat3_m4_v3(mat, nor);

		invert_m3_m3(itsm, tsm);
		mul_m3_v3(itsm, nor);
		normalize_v3(nor);

		/* save back the values */
		normal_compress(&result[offset], nor, normal_swizzle);
	}

	/* garbage collection */
	MEM_freeN(triangles);

	if (dm)
		dm->release(dm);
}