Exemple #1
0
void paint_get_tex_pixel_col(MTex *mtex, float u, float v, float rgba[4], struct ImagePool *pool, int thread, bool convert_to_linear, struct ColorSpace *colorspace)
{
	float co[3] = {u, v, 0.0f};
	int hasrgb;
	float intensity;

	hasrgb = externtex(mtex, co, &intensity,
	                   rgba, rgba + 1, rgba + 2, rgba + 3, thread, pool);
	if (!hasrgb) {
		rgba[0] = intensity;
		rgba[1] = intensity;
		rgba[2] = intensity;
		rgba[3] = 1.0f;
	}

	if (convert_to_linear)
		IMB_colormanagement_colorspace_to_scene_linear_v3(rgba, colorspace);

	linearrgb_to_srgb_v3_v3(rgba, rgba);

	CLAMP(rgba[0], 0.0f, 1.0f);
	CLAMP(rgba[1], 0.0f, 1.0f);
	CLAMP(rgba[2], 0.0f, 1.0f);
	CLAMP(rgba[3], 0.0f, 1.0f);
}
Exemple #2
0
/* Brush Sampling */
void brush_sample_tex(Brush *brush, float *xy, float *rgba, const int thread)
{
	MTex *mtex= &brush->mtex;

	if (mtex && mtex->tex) {
		float co[3], tin, tr, tg, tb, ta;
		int hasrgb;
		const int radius= brush_size(brush);

		co[0]= xy[0]/radius;
		co[1]= xy[1]/radius;
		co[2]= 0.0f;

		hasrgb= externtex(mtex, co, &tin, &tr, &tg, &tb, &ta, thread);

		if (hasrgb) {
			rgba[0]= tr;
			rgba[1]= tg;
			rgba[2]= tb;
			rgba[3]= ta;
		}
		else {
			rgba[0]= tin;
			rgba[1]= tin;
			rgba[2]= tin;
			rgba[3]= 1.0f;
		}
	}
	else if (rgba)
		rgba[0]= rgba[1]= rgba[2]= rgba[3]= 1.0f;
}
Exemple #3
0
/* Brush Sampling */
void BKE_brush_sample_tex(const Scene *scene, Brush *brush, const float xy[2], float rgba[4], const int thread)
{
    MTex *mtex = &brush->mtex;

    if (mtex && mtex->tex) {
        float co[3], tin, tr, tg, tb, ta;
        int hasrgb;
        const int radius = BKE_brush_size_get(scene, brush);

        co[0] = xy[0] / radius;
        co[1] = xy[1] / radius;
        co[2] = 0.0f;

        hasrgb = externtex(mtex, co, &tin, &tr, &tg, &tb, &ta, thread);

        if (hasrgb) {
            rgba[0] = tr;
            rgba[1] = tg;
            rgba[2] = tb;
            rgba[3] = ta;
        }
        else {
            rgba[0] = tin;
            rgba[1] = tin;
            rgba[2] = tin;
            rgba[3] = 1.0f;
        }
    }
    else {
        rgba[0] = rgba[1] = rgba[2] = rgba[3] = 1.0f;
    }
}
Exemple #4
0
/* TODO: should probably be unified with BrushPainter stuff? */
unsigned int *BKE_brush_gen_texture_cache(Brush *br, int half_side, bool use_secondary)
{
  unsigned int *texcache = NULL;
  MTex *mtex = (use_secondary) ? &br->mask_mtex : &br->mtex;
  float intensity;
  float rgba[4];
  int ix, iy;
  int side = half_side * 2;

  if (mtex->tex) {
    float x, y, step = 2.0 / side, co[3];

    texcache = MEM_callocN(sizeof(int) * side * side, "Brush texture cache");

    /* do normalized canonical view coords for texture */
    for (y = -1.0, iy = 0; iy < side; iy++, y += step) {
      for (x = -1.0, ix = 0; ix < side; ix++, x += step) {
        co[0] = x;
        co[1] = y;
        co[2] = 0.0f;

        /* This is copied from displace modifier code */
        /* TODO(sergey): brush are always caching with CM enabled for now. */
        externtex(mtex, co, &intensity, rgba, rgba + 1, rgba + 2, rgba + 3, 0, NULL, false, false);

        ((char *)texcache)[(iy * side + ix) * 4] = ((char *)texcache)[(iy * side + ix) * 4 + 1] =
            ((char *)texcache)[(iy * side + ix) * 4 + 2] = ((
                char *)texcache)[(iy * side + ix) * 4 + 3] = (char)(intensity * 255.0f);
      }
    }
  }

  return texcache;
}
Exemple #5
0
float paint_get_tex_pixel(MTex *mtex, float u, float v, struct ImagePool *pool, int thread)
{
	float intensity, rgba[4];
	float co[3] = {u, v, 0.0f};

	externtex(mtex, co, &intensity,
	          rgba, rgba + 1, rgba + 2, rgba + 3, thread, pool);

	return intensity;
}
void paint_get_tex_pixel_col(MTex *mtex, float u, float v, float rgba[4], struct ImagePool *pool)
{
	float co[3] = {u, v, 0.0f};
	int hasrgb;
	float intensity;

	hasrgb = externtex(mtex, co, &intensity,
		                   rgba, rgba + 1, rgba + 2, rgba + 3, 0, pool);

	if (!hasrgb) {
		rgba[0] = intensity;
		rgba[1] = intensity;
		rgba[2] = intensity;
		rgba[3] = 1.0f;
	}
	CLAMP(rgba[0], 0.0f, 1.0f);
	CLAMP(rgba[1], 0.0f, 1.0f);
	CLAMP(rgba[2], 0.0f, 1.0f);
	CLAMP(rgba[3], 0.0f, 1.0f);
}
Exemple #7
0
float BKE_brush_sample_masktex(const Scene *scene, Brush *br,
                               const float point[2],
                               const int thread,
                               struct ImagePool *pool)
{
	UnifiedPaintSettings *ups = &scene->toolsettings->unified_paint_settings;
	MTex *mtex = &br->mask_mtex;
	float rgba[4], intensity;

	if (!mtex->tex) {
		return 1.0f;
	}
	if (mtex->brush_map_mode == MTEX_MAP_MODE_STENCIL) {
		float rotation = -mtex->rot;
		float point_2d[2] = {point[0], point[1]};
		float x, y;
		float co[3];

		x = point_2d[0] - br->mask_stencil_pos[0];
		y = point_2d[1] - br->mask_stencil_pos[1];

		if (rotation > 0.001f || rotation < -0.001f) {
			const float angle    = atan2f(y, x) + rotation;
			const float flen     = sqrtf(x * x + y * y);

			x = flen * cosf(angle);
			y = flen * sinf(angle);
		}

		if (fabsf(x) > br->mask_stencil_dimension[0] || fabsf(y) > br->mask_stencil_dimension[1]) {
			zero_v4(rgba);
			return 0.0f;
		}
		x /= (br->mask_stencil_dimension[0]);
		y /= (br->mask_stencil_dimension[1]);

		co[0] = x;
		co[1] = y;
		co[2] = 0.0f;

		externtex(mtex, co, &intensity,
		          rgba, rgba + 1, rgba + 2, rgba + 3, thread, pool, false, false);
	}
	else {
		float rotation = -mtex->rot;
		float point_2d[2] = {point[0], point[1]};
		float x = 0.0f, y = 0.0f; /* Quite warnings */
		float invradius = 1.0f; /* Quite warnings */
		float co[3];

		if (mtex->brush_map_mode == MTEX_MAP_MODE_VIEW) {
			/* keep coordinates relative to mouse */

			rotation += ups->brush_rotation_sec;

			x = point_2d[0] - ups->mask_tex_mouse[0];
			y = point_2d[1] - ups->mask_tex_mouse[1];

			/* use pressure adjusted size for fixed mode */
			invradius = 1.0f / ups->pixel_radius;
		}
		else if (mtex->brush_map_mode == MTEX_MAP_MODE_TILED) {
			/* leave the coordinates relative to the screen */

			/* use unadjusted size for tiled mode */
			invradius = 1.0f / BKE_brush_size_get(scene, br);

			x = point_2d[0];
			y = point_2d[1];
		}
		else if (mtex->brush_map_mode == MTEX_MAP_MODE_RANDOM) {
			rotation += ups->brush_rotation_sec;
			/* these contain a random coordinate */
			x = point_2d[0] - ups->mask_tex_mouse[0];
			y = point_2d[1] - ups->mask_tex_mouse[1];

			invradius = 1.0f / ups->pixel_radius;
		}

		x *= invradius;
		y *= invradius;

		/* it is probably worth optimizing for those cases where
		 * the texture is not rotated by skipping the calls to
		 * atan2, sqrtf, sin, and cos. */
		if (rotation > 0.001f || rotation < -0.001f) {
			const float angle    = atan2f(y, x) + rotation;
			const float flen     = sqrtf(x * x + y * y);

			x = flen * cosf(angle);
			y = flen * sinf(angle);
		}

		co[0] = x;
		co[1] = y;
		co[2] = 0.0f;

		externtex(mtex, co, &intensity,
		          rgba, rgba + 1, rgba + 2, rgba + 3, thread, pool, false, false);
	}

	CLAMP(intensity, 0.0f, 1.0f);

	switch (br->mask_pressure) {
		case BRUSH_MASK_PRESSURE_CUTOFF:
			intensity  = ((1.0f - intensity) < ups->size_pressure_value) ? 1.0f : 0.0f;
			break;
		case BRUSH_MASK_PRESSURE_RAMP:
			intensity = ups->size_pressure_value + intensity * (1.0f - ups->size_pressure_value);
			break;
		default:
			break;
	}

	return intensity;
}
Exemple #8
0
/* Generic texture sampler for 3D painting systems. point has to be either in
 * region space mouse coordinates, or 3d world coordinates for 3D mapping.
 *
 * rgba outputs straight alpha. */
float BKE_brush_sample_tex_3D(const Scene *scene, Brush *br,
                              const float point[3],
                              float rgba[4], const int thread,
                              struct ImagePool *pool)
{
	UnifiedPaintSettings *ups = &scene->toolsettings->unified_paint_settings;
	MTex *mtex = &br->mtex;
	float intensity = 1.0;
	bool hasrgb = false;

	if (!mtex->tex) {
		intensity = 1;
	}
	else if (mtex->brush_map_mode == MTEX_MAP_MODE_3D) {
		/* Get strength by feeding the vertex
		 * location directly into a texture */
		hasrgb = externtex(mtex, point, &intensity,
		                   rgba, rgba + 1, rgba + 2, rgba + 3, thread, pool, false, false);
	}
	else if (mtex->brush_map_mode == MTEX_MAP_MODE_STENCIL) {
		float rotation = -mtex->rot;
		float point_2d[2] = {point[0], point[1]};
		float x, y;
		float co[3];

		x = point_2d[0] - br->stencil_pos[0];
		y = point_2d[1] - br->stencil_pos[1];

		if (rotation > 0.001f || rotation < -0.001f) {
			const float angle    = atan2f(y, x) + rotation;
			const float flen     = sqrtf(x * x + y * y);

			x = flen * cosf(angle);
			y = flen * sinf(angle);
		}

		if (fabsf(x) > br->stencil_dimension[0] || fabsf(y) > br->stencil_dimension[1]) {
			zero_v4(rgba);
			return 0.0f;
		}
		x /= (br->stencil_dimension[0]);
		y /= (br->stencil_dimension[1]);

		co[0] = x;
		co[1] = y;
		co[2] = 0.0f;

		hasrgb = externtex(mtex, co, &intensity,
		                   rgba, rgba + 1, rgba + 2, rgba + 3, thread, pool, false, false);
	}
	else {
		float rotation = -mtex->rot;
		float point_2d[2] = {point[0], point[1]};
		float x = 0.0f, y = 0.0f; /* Quite warnings */
		float invradius = 1.0f; /* Quite warnings */
		float co[3];

		if (mtex->brush_map_mode == MTEX_MAP_MODE_VIEW) {
			/* keep coordinates relative to mouse */

			rotation += ups->brush_rotation;

			x = point_2d[0] - ups->tex_mouse[0];
			y = point_2d[1] - ups->tex_mouse[1];

			/* use pressure adjusted size for fixed mode */
			invradius = 1.0f / ups->pixel_radius;
		}
		else if (mtex->brush_map_mode == MTEX_MAP_MODE_TILED) {
			/* leave the coordinates relative to the screen */

			/* use unadjusted size for tiled mode */
			invradius = 1.0f / BKE_brush_size_get(scene, br);

			x = point_2d[0];
			y = point_2d[1];
		}
		else if (mtex->brush_map_mode == MTEX_MAP_MODE_RANDOM) {
			rotation += ups->brush_rotation;
			/* these contain a random coordinate */
			x = point_2d[0] - ups->tex_mouse[0];
			y = point_2d[1] - ups->tex_mouse[1];

			invradius = 1.0f / ups->pixel_radius;
		}

		x *= invradius;
		y *= invradius;

		/* it is probably worth optimizing for those cases where
		 * the texture is not rotated by skipping the calls to
		 * atan2, sqrtf, sin, and cos. */
		if (rotation > 0.001f || rotation < -0.001f) {
			const float angle    = atan2f(y, x) + rotation;
			const float flen     = sqrtf(x * x + y * y);

			x = flen * cosf(angle);
			y = flen * sinf(angle);
		}

		co[0] = x;
		co[1] = y;
		co[2] = 0.0f;

		hasrgb = externtex(mtex, co, &intensity,
		                   rgba, rgba + 1, rgba + 2, rgba + 3, thread, pool, false, false);
	}

	intensity += br->texture_sample_bias;

	if (!hasrgb) {
		rgba[0] = intensity;
		rgba[1] = intensity;
		rgba[2] = intensity;
		rgba[3] = 1.0f;
	}
	/* For consistency, sampling always returns color in linear space */
	else if (ups->do_linear_conversion) {
		IMB_colormanagement_colorspace_to_scene_linear_v3(rgba, ups->colorspace);
	}

	return intensity;
}
HaloRen *RE_inithalo(Render *re, ObjectRen *obr, Material *ma,
                     const float vec[3], const float vec1[3],
                     const float *orco, float hasize, float vectsize, int seed)
{
	const bool skip_load_image = (re->r.scemode & R_NO_IMAGE_LOAD) != 0;
	HaloRen *har;
	MTex *mtex;
	float tin, tr, tg, tb, ta;
	float xn, yn, zn, texvec[3], hoco[4], hoco1[4];

	if (hasize==0.0f) return NULL;

	projectverto(vec, re->winmat, hoco);
	if (hoco[3]==0.0f) return NULL;
	if (vec1) {
		projectverto(vec1, re->winmat, hoco1);
		if (hoco1[3]==0.0f) return NULL;
	}

	har= RE_findOrAddHalo(obr, obr->tothalo++);
	copy_v3_v3(har->co, vec);
	har->hasize= hasize;

	/* actual projectvert is done in function project_renderdata() because of parts/border/pano */
	/* we do it here for sorting of halos */
	zn= hoco[3];
	har->xs= 0.5f*re->winx*(hoco[0]/zn);
	har->ys= 0.5f*re->winy*(hoco[1]/zn);
	har->zs= 0x7FFFFF*(hoco[2]/zn);
	
	har->zBufDist = 0x7FFFFFFF*(hoco[2]/zn); 
	
	/* halovect */
	if (vec1) {

		har->type |= HA_VECT;

		xn=  har->xs - 0.5f*re->winx*(hoco1[0]/hoco1[3]);
		yn=  har->ys - 0.5f*re->winy*(hoco1[1]/hoco1[3]);
		if (xn==0.0f || (xn==0.0f && yn==0.0f)) zn= 0.0f;
		else zn = atan2f(yn, xn);

		har->sin = sinf(zn);
		har->cos = cosf(zn);
		zn= len_v3v3(vec1, vec);

		har->hasize= vectsize*zn + (1.0f-vectsize)*hasize;
		
		sub_v3_v3v3(har->no, vec, vec1);
		normalize_v3(har->no);
	}

	if (ma->mode & MA_HALO_XALPHA) har->type |= HA_XALPHA;

	har->alfa= ma->alpha;
	har->r= ma->r;
	har->g= ma->g;
	har->b= ma->b;
	har->add= (255.0f*ma->add);
	har->mat= ma;
	har->hard= ma->har;
	har->seed= seed % 256;

	if (ma->mode & MA_STAR) har->starpoints= ma->starc;
	if (ma->mode & MA_HALO_LINES) har->linec= ma->linec;
	if (ma->mode & MA_HALO_RINGS) har->ringc= ma->ringc;
	if (ma->mode & MA_HALO_FLARE) har->flarec= ma->flarec;


	if (ma->mtex[0]) {

		if (ma->mode & MA_HALOTEX) {
			har->tex = 1;
		}
		else if (har->mat->septex & (1 << 0)) {
			/* only 1 level textures */
		}
		else {
			mtex= ma->mtex[0];
			copy_v3_v3(texvec, vec);

			if (mtex->texco & TEXCO_NORM) {
				;
			}
			else if (mtex->texco & TEXCO_OBJECT) {
				/* texvec[0]+= imatbase->ivec[0]; */
				/* texvec[1]+= imatbase->ivec[1]; */
				/* texvec[2]+= imatbase->ivec[2]; */
				/* mul_m3_v3(imatbase->imat, texvec); */
			}
			else {
				if (orco) {
					copy_v3_v3(texvec, orco);
				}
			}

			externtex(mtex, texvec, &tin, &tr, &tg, &tb, &ta, 0, re->pool, skip_load_image);

			yn= tin*mtex->colfac;
			//zn= tin*mtex->alphafac;

			if (mtex->mapto & MAP_COL) {
				zn= 1.0f-yn;
				har->r= (yn*tr+ zn*ma->r);
				har->g= (yn*tg+ zn*ma->g);
				har->b= (yn*tb+ zn*ma->b);
			}
			if (mtex->texco & TEXCO_UV) {
				har->alfa= tin;
			}
			if (mtex->mapto & MAP_ALPHA)
				har->alfa= tin;
		}
	}

	har->pool = re->pool;
	har->skip_load_image = (re->r.scemode & R_NO_IMAGE_LOAD) != 0;

	return har;
}
Exemple #10
0
HaloRen *RE_inithalo_particle(Render *re, ObjectRen *obr, DerivedMesh *dm, Material *ma,
                              const float vec[3], const float vec1[3],
                              const float *orco, const float *uvco, float hasize, float vectsize, int seed, const float pa_co[3])
{
	const bool skip_load_image = (re->r.scemode & R_NO_IMAGE_LOAD) != 0;
	HaloRen *har;
	MTex *mtex;
	float tin, tr, tg, tb, ta;
	float xn, yn, zn, texvec[3], hoco[4], hoco1[4], in[3], tex[3], out[3];
	int i, hasrgb;

	if (hasize==0.0f) return NULL;

	projectverto(vec, re->winmat, hoco);
	if (hoco[3]==0.0f) return NULL;
	if (vec1) {
		projectverto(vec1, re->winmat, hoco1);
		if (hoco1[3]==0.0f) return NULL;
	}

	har= RE_findOrAddHalo(obr, obr->tothalo++);
	copy_v3_v3(har->co, vec);
	har->hasize= hasize;

	/* actual projectvert is done in function project_renderdata() because of parts/border/pano */
	/* we do it here for sorting of halos */
	zn= hoco[3];
	har->xs= 0.5f*re->winx*(hoco[0]/zn);
	har->ys= 0.5f*re->winy*(hoco[1]/zn);
	har->zs= 0x7FFFFF*(hoco[2]/zn);
	
	har->zBufDist = 0x7FFFFFFF*(hoco[2]/zn); 
	
	/* halovect */
	if (vec1) {

		har->type |= HA_VECT;

		xn=  har->xs - 0.5f*re->winx*(hoco1[0]/hoco1[3]);
		yn=  har->ys - 0.5f*re->winy*(hoco1[1]/hoco1[3]);
		if (xn==0.0f || (xn==0.0f && yn==0.0f)) zn= 0.0;
		else zn = atan2f(yn, xn);

		har->sin = sinf(zn);
		har->cos = cosf(zn);
		zn= len_v3v3(vec1, vec)*0.5f;

		har->hasize= vectsize*zn + (1.0f-vectsize)*hasize;
		
		sub_v3_v3v3(har->no, vec, vec1);
		normalize_v3(har->no);
	}

	if (ma->mode & MA_HALO_XALPHA) har->type |= HA_XALPHA;

	har->alfa= ma->alpha;
	har->r= ma->r;
	har->g= ma->g;
	har->b= ma->b;
	har->add= (255.0f*ma->add);
	har->mat= ma;
	har->hard= ma->har;
	har->seed= seed % 256;

	if (ma->mode & MA_STAR) har->starpoints= ma->starc;
	if (ma->mode & MA_HALO_LINES) har->linec= ma->linec;
	if (ma->mode & MA_HALO_RINGS) har->ringc= ma->ringc;
	if (ma->mode & MA_HALO_FLARE) har->flarec= ma->flarec;

	if ((ma->mode & MA_HALOTEX) && ma->mtex[0])
		har->tex= 1;
	
	for (i=0; i<MAX_MTEX; i++)
		if (ma->mtex[i] && (ma->septex & (1<<i))==0) {
			mtex= ma->mtex[i];
			copy_v3_v3(texvec, vec);

			if (mtex->texco & TEXCO_NORM) {
				;
			}
			else if (mtex->texco & TEXCO_OBJECT) {
				if (mtex->object)
					mul_m4_v3(mtex->object->imat_ren, texvec);
			}
			else if (mtex->texco & TEXCO_GLOB) {
				copy_v3_v3(texvec, vec);
			}
			else if (mtex->texco & TEXCO_UV && uvco) {
				int uv_index=CustomData_get_named_layer_index(&dm->faceData, CD_MTFACE, mtex->uvname);
				if (uv_index<0)
					uv_index=CustomData_get_active_layer_index(&dm->faceData, CD_MTFACE);

				uv_index-=CustomData_get_layer_index(&dm->faceData, CD_MTFACE);

				texvec[0]=2.0f*uvco[2*uv_index]-1.0f;
				texvec[1]=2.0f*uvco[2*uv_index+1]-1.0f;
				texvec[2]=0.0f;
			}
			else if (mtex->texco & TEXCO_PARTICLE) {
				/* particle coordinates in range [0, 1] */
				texvec[0] = 2.f * pa_co[0] - 1.f;
				texvec[1] = 2.f * pa_co[1] - 1.f;
				texvec[2] = pa_co[2];
			}
			else if (orco) {
				copy_v3_v3(texvec, orco);
			}

			hasrgb = externtex(mtex, texvec, &tin, &tr, &tg, &tb, &ta, 0, re->pool, skip_load_image);

			//yn= tin*mtex->colfac;
			//zn= tin*mtex->alphafac;
			if (mtex->mapto & MAP_COL) {
				tex[0]=tr;
				tex[1]=tg;
				tex[2]=tb;
				out[0]=har->r;
				out[1]=har->g;
				out[2]=har->b;

				texture_rgb_blend(in, tex, out, tin, mtex->colfac, mtex->blendtype);
			//	zn= 1.0-yn;
				//har->r= (yn*tr+ zn*ma->r);
				//har->g= (yn*tg+ zn*ma->g);
				//har->b= (yn*tb+ zn*ma->b);
				har->r= in[0];
				har->g= in[1];
				har->b= in[2];
			}

			/* alpha returned, so let's use it instead of intensity */
			if (hasrgb)
				tin = ta;

			if (mtex->mapto & MAP_ALPHA)
				har->alfa = texture_value_blend(mtex->def_var, har->alfa, tin, mtex->alphafac, mtex->blendtype);
			if (mtex->mapto & MAP_HAR)
				har->hard = 1.0f+126.0f*texture_value_blend(mtex->def_var, ((float)har->hard)/127.0f, tin, mtex->hardfac, mtex->blendtype);
			if (mtex->mapto & MAP_RAYMIRR)
				har->hasize = 100.0f*texture_value_blend(mtex->def_var, har->hasize/100.0f, tin, mtex->raymirrfac, mtex->blendtype);
			if (mtex->mapto & MAP_TRANSLU) {
				float add = texture_value_blend(mtex->def_var, (float)har->add/255.0f, tin, mtex->translfac, mtex->blendtype);
				CLAMP(add, 0.f, 1.f);
				har->add = 255.0f*add;
			}
			/* now what on earth is this good for?? */
			//if (mtex->texco & 16) {
			//	har->alfa= tin;
			//}
		}

	har->pool = re->pool;
	har->skip_load_image = (re->r.scemode & R_NO_IMAGE_LOAD) != 0;

	return har;
}