void TextureBaseOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler)
{
	TexResult texres = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0, NULL};
	float textureSize[4];
	float textureOffset[4];
	float vec[3];
	int retval;
	const float cx = this->getWidth() / 2;
	const float cy = this->getHeight() / 2;
	const float u = (x - cx) / this->getWidth() * 2;
	const float v = (y - cy) / this->getHeight() * 2;

	this->m_inputSize->readSampled(textureSize, x, y, sampler);
	this->m_inputOffset->readSampled(textureOffset, x, y, sampler);

	vec[0] = textureSize[0] * (u + textureOffset[0]);
	vec[1] = textureSize[1] * (v + textureOffset[1]);
	vec[2] = textureSize[2] * textureOffset[2];

	retval = multitex_ext(this->m_texture, vec, NULL, NULL, 0, &texres, m_pool, m_sceneColorManage);

	if (texres.talpha)
		output[3] = texres.ta;
	else
		output[3] = texres.tin;

	if ((retval & TEX_RGB)) {
		output[0] = texres.tr;
		output[1] = texres.tg;
		output[2] = texres.tb;
	}
	else {
		output[0] = output[1] = output[2] = output[3];
	}
}
void TextureBaseOperation::executePixel(float *color, float x, float y, PixelSampler sampler)
{
	TexResult texres = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0, NULL};
	float textureSize[4];
	float textureOffset[4];
	float vec[3];
	int retval;
	const float cx = this->getWidth() / 2;
	const float cy = this->getHeight() / 2;
	const float u = (cx - x) / this->getWidth() * 2;
	const float v = (cy - y) / this->getHeight() * 2;

	this->m_inputSize->read(textureSize, x, y, sampler);
	this->m_inputOffset->read(textureOffset, x, y, sampler);

	vec[0] = textureSize[0] * (u + textureOffset[0]);
	vec[1] = textureSize[1] * (v + textureOffset[1]);
	vec[2] = textureSize[2] * textureOffset[2];

	retval = multitex_ext(this->m_texture, vec, NULL, NULL, 0, &texres);

	if (texres.talpha)
		color[3] = texres.ta;
	else
		color[3] = texres.tin;

	if ((retval & TEX_RGB)) {
		color[0] = texres.tr;
		color[1] = texres.tg;
		color[2] = texres.tb;
	}
	else color[0] = color[1] = color[2] = color[3];
}
Exemplo n.º 3
0
void texture_evaluate(struct Tex *tex, float value[3], float color_r[3])
{
	TexResult texres= {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0, NULL};
	multitex_ext(tex, value, NULL, NULL, 1, &texres);

	color_r[0] = texres.tr;
	color_r[1] = texres.tg;
	color_r[2] = texres.tb;
	color_r[3] = texres.tin;
}
Exemplo n.º 4
0
static void texture_evaluate(struct Tex *tex, float value[3], float color_r[4])
{
	TexResult texres = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0, NULL};

	/* TODO(sergey): always use color management now.  */
	multitex_ext(tex, value, NULL, NULL, 1, &texres, NULL, true);

	color_r[0] = texres.tr;
	color_r[1] = texres.tg;
	color_r[2] = texres.tb;
	color_r[3] = texres.tin;
}
Exemplo n.º 5
0
void TextureBaseOperation::executePixelSampled(float output[4],
                                               float x,
                                               float y,
                                               PixelSampler sampler)
{
  TexResult texres = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0, NULL};
  float textureSize[4];
  float textureOffset[4];
  float vec[3];
  int retval;
  const float cx = this->getWidth() / 2;
  const float cy = this->getHeight() / 2;
  float u = (x - cx) / this->getWidth() * 2;
  float v = (y - cy) / this->getHeight() * 2;

  /* When no interpolation/filtering happens in multitex() foce nearest interpolation.
   * We do it here because (a) we can't easily say multitex() that we want nearest
   * interpolation and (b) in such configuration multitex() sinply floor's the value
   * which often produces artifacts.
   */
  if (m_texture != NULL && (m_texture->imaflag & TEX_INTERPOL) == 0) {
    u += 0.5f / cx;
    v += 0.5f / cy;
  }

  this->m_inputSize->readSampled(textureSize, x, y, sampler);
  this->m_inputOffset->readSampled(textureOffset, x, y, sampler);

  vec[0] = textureSize[0] * (u + textureOffset[0]);
  vec[1] = textureSize[1] * (v + textureOffset[1]);
  vec[2] = textureSize[2] * textureOffset[2];

  const int thread_id = WorkScheduler::current_thread_id();
  retval = multitex_ext(
      this->m_texture, vec, NULL, NULL, 0, &texres, thread_id, m_pool, m_sceneColorManage, false);

  if (texres.talpha) {
    output[3] = texres.ta;
  }
  else {
    output[3] = texres.tin;
  }

  if ((retval & TEX_RGB)) {
    output[0] = texres.tr;
    output[1] = texres.tg;
    output[2] = texres.tb;
  }
  else {
    output[0] = output[1] = output[2] = output[3];
  }
}
Exemplo n.º 6
0
float paint_get_tex_pixel(Brush* br, float u, float v)
{
	TexResult texres;
	float co[3];
	int hasrgb;

	co[0] = u;
	co[1] = v;
	co[2] = 0;

	memset(&texres, 0, sizeof(TexResult));
	hasrgb = multitex_ext(br->mtex.tex, co, NULL, NULL, 0, &texres);

	if (hasrgb & TEX_RGB)
		texres.tin = (0.35f*texres.tr + 0.45f*texres.tg + 0.2f*texres.tb)*texres.ta;

	return texres.tin;
}
Exemplo n.º 7
0
/* TODO: should probably be unified with BrushPainter stuff? */
unsigned int *brush_gen_texture_cache(Brush *br, int half_side)
{
	unsigned int *texcache = NULL;
	MTex *mtex = &br->mtex;
	TexResult texres= {0};
	int hasrgb, 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");

		BKE_image_get_ibuf(mtex->tex->ima, NULL);
		
		/*do normalized cannonical 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 */
				hasrgb = multitex_ext(mtex->tex, co, NULL, NULL, 0, &texres);
			
				/* if the texture gave an RGB value, we assume it didn't give a valid
				 * intensity, so calculate one (formula from do_material_tex).
				 * if the texture didn't give an RGB value, copy the intensity across
				 */
				if(hasrgb & TEX_RGB)
					texres.tin = (0.35f * texres.tr + 0.45f *
								  texres.tg + 0.2f * texres.tb);

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

	return texcache;
}
Exemplo n.º 8
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;
	TexResult texres = {0};
	int hasrgb, 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 cannonical 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 cacheing with CM enabled for now. */
				hasrgb = multitex_ext(mtex->tex, co, NULL, NULL, 0, &texres, NULL, true);

				/* if the texture gave an RGB value, we assume it didn't give a valid
				 * intensity, so calculate one (formula from do_material_tex).
				 * if the texture didn't give an RGB value, copy the intensity across
				 */
				if (hasrgb & TEX_RGB)
					texres.tin = rgb_to_grayscale(&texres.tr);

				((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)(texres.tin * 255.0f);
			}
		}
	}

	return texcache;
}
Exemplo n.º 9
0
static void colorfn(float *out, TexParams *p, bNode *node, bNodeStack **in, short thread)
{
	static float red[] = {1,0,0,1};
	static float white[] = {1,1,1,1};
	float *coord = p->coord;
	
	Tex *nodetex = (Tex *)node->id;
	
	if(node->custom2 || node->need_exec==0) {
		/* this node refers to its own texture tree! */
		QUATCOPY(
			out,
			(fabs(coord[0] - coord[1]) < .01) ? white : red 
		);
	}
	else if(nodetex) {
		TexResult texres;
		int textype;
		float nor[] = {0,0,0};
		float col1[4], col2[4];
		
		tex_input_rgba(col1, in[0], p, thread);
		tex_input_rgba(col2, in[1], p, thread);
		
		texres.nor = nor;
		textype = multitex_ext(nodetex, coord, 0, 0, 0, &texres);
		
		if(textype & TEX_RGB) {
			QUATCOPY(out, &texres.tr);
		}
		else {
			QUATCOPY(out, col1);
			ramp_blend(MA_RAMP_BLEND, out, out+1, out+2, texres.tin, col2);
		}
	}
}
Exemplo n.º 10
0
static void do_texture_effector(EffectorCache *eff, EffectorData *efd, EffectedPoint *point, float *total_force)
{
	TexResult result[4];
	float tex_co[3], strength, force[3];
	float nabla = eff->pd->tex_nabla;
	int hasrgb;
	short mode = eff->pd->tex_mode;
	bool scene_color_manage;

	if (!eff->pd->tex)
		return;

	result[0].nor = result[1].nor = result[2].nor = result[3].nor = NULL;

	strength= eff->pd->f_strength * efd->falloff;

	copy_v3_v3(tex_co, point->loc);

	if (eff->pd->flag & PFIELD_TEX_2D) {
		float fac=-dot_v3v3(tex_co, efd->nor);
		madd_v3_v3fl(tex_co, efd->nor, fac);
	}

	if (eff->pd->flag & PFIELD_TEX_OBJECT) {
		mul_m4_v3(eff->ob->imat, tex_co);
	}

	scene_color_manage = BKE_scene_check_color_management_enabled(eff->scene);

	hasrgb = multitex_ext(eff->pd->tex, tex_co, NULL, NULL, 0, result, NULL, scene_color_manage, false);

	if (hasrgb && mode==PFIELD_TEX_RGB) {
		force[0] = (0.5f - result->tr) * strength;
		force[1] = (0.5f - result->tg) * strength;
		force[2] = (0.5f - result->tb) * strength;
	}
	else {
		strength/=nabla;

		tex_co[0] += nabla;
		multitex_ext(eff->pd->tex, tex_co, NULL, NULL, 0, result+1, NULL, scene_color_manage, false);

		tex_co[0] -= nabla;
		tex_co[1] += nabla;
		multitex_ext(eff->pd->tex, tex_co, NULL, NULL, 0, result+2, NULL, scene_color_manage, false);

		tex_co[1] -= nabla;
		tex_co[2] += nabla;
		multitex_ext(eff->pd->tex, tex_co, NULL, NULL, 0, result+3, NULL, scene_color_manage, false);

		if (mode == PFIELD_TEX_GRAD || !hasrgb) { /* if we don't have rgb fall back to grad */
			/* generate intensity if texture only has rgb value */
			if (hasrgb & TEX_RGB) {
				int i;
				for (i=0; i<4; i++)
					result[i].tin = (1.0f / 3.0f) * (result[i].tr + result[i].tg + result[i].tb);
			}
			force[0] = (result[0].tin - result[1].tin) * strength;
			force[1] = (result[0].tin - result[2].tin) * strength;
			force[2] = (result[0].tin - result[3].tin) * strength;
		}
		else { /*PFIELD_TEX_CURL*/
			float dbdy, dgdz, drdz, dbdx, dgdx, drdy;

			dbdy = result[2].tb - result[0].tb;
			dgdz = result[3].tg - result[0].tg;
			drdz = result[3].tr - result[0].tr;
			dbdx = result[1].tb - result[0].tb;
			dgdx = result[1].tg - result[0].tg;
			drdy = result[2].tr - result[0].tr;

			force[0] = (dbdy - dgdz) * strength;
			force[1] = (drdz - dbdx) * strength;
			force[2] = (dgdx - drdy) * strength;
		}
	}

	if (eff->pd->flag & PFIELD_TEX_2D) {
		float fac = -dot_v3v3(force, efd->nor);
		madd_v3_v3fl(force, efd->nor, fac);
	}

	add_v3_v3(total_force, force);
}
Exemplo n.º 11
0
static void do_texture_effector(EffectorCache *eff, EffectorData *efd, EffectedPoint *point, float *total_force)
{
	TexResult result[4];
	float tex_co[3], strength, force[3];
	float nabla = eff->pd->tex_nabla;
	int hasrgb;
	short mode = eff->pd->tex_mode;

	if(!eff->pd->tex)
		return;

	result[0].nor = result[1].nor = result[2].nor = result[3].nor = NULL;

	strength= eff->pd->f_strength * efd->falloff;

	copy_v3_v3(tex_co,point->loc);

	if(eff->pd->flag & PFIELD_TEX_2D) {
		float fac=-dot_v3v3(tex_co, efd->nor);
		VECADDFAC(tex_co, tex_co, efd->nor, fac);
	}

	if(eff->pd->flag & PFIELD_TEX_OBJECT) {
		mul_m4_v3(eff->ob->imat, tex_co);
	}

	hasrgb = multitex_ext(eff->pd->tex, tex_co, NULL,NULL, 0, result);

	if(hasrgb && mode==PFIELD_TEX_RGB) {
		force[0] = (0.5f - result->tr) * strength;
		force[1] = (0.5f - result->tg) * strength;
		force[2] = (0.5f - result->tb) * strength;
	}
	else {
		strength/=nabla;

		tex_co[0] += nabla;
		multitex_ext(eff->pd->tex, tex_co, NULL, NULL, 0, result+1);

		tex_co[0] -= nabla;
		tex_co[1] += nabla;
		multitex_ext(eff->pd->tex, tex_co, NULL, NULL, 0, result+2);

		tex_co[1] -= nabla;
		tex_co[2] += nabla;
		multitex_ext(eff->pd->tex, tex_co, NULL, NULL, 0, result+3);

		if(mode == PFIELD_TEX_GRAD || !hasrgb) { /* if we dont have rgb fall back to grad */
			force[0] = (result[0].tin - result[1].tin) * strength;
			force[1] = (result[0].tin - result[2].tin) * strength;
			force[2] = (result[0].tin - result[3].tin) * strength;
		}
		else { /*PFIELD_TEX_CURL*/
			float dbdy, dgdz, drdz, dbdx, dgdx, drdy;

			dbdy = result[2].tb - result[0].tb;
			dgdz = result[3].tg - result[0].tg;
			drdz = result[3].tr - result[0].tr;
			dbdx = result[1].tb - result[0].tb;
			dgdx = result[1].tg - result[0].tg;
			drdy = result[2].tr - result[0].tr;

			force[0] = (dbdy - dgdz) * strength;
			force[1] = (drdz - dbdx) * strength;
			force[2] = (dgdx - drdy) * strength;
		}
	}

	if(eff->pd->flag & PFIELD_TEX_2D){
		float fac = -dot_v3v3(force, efd->nor);
		VECADDFAC(force, force, efd->nor, fac);
	}

	add_v3_v3(total_force, force);
}