Exemple #1
0
/* Calls multitex and copies the result to the outputs. Called by xxx_exec, which handles inputs. */
static void do_proc(float *result, TexParams *p, float *col1, float *col2, char is_normal, Tex *tex, short thread)
{
	TexResult texres;
	int textype;
	
	if(is_normal) {
		texres.nor = result;
	}
	else
		texres.nor = NULL;
	
	textype = multitex_nodes(tex, p->co, p->dxt, p->dyt, p->osatex,
		&texres, thread, 0, p->shi, p->mtex);
	
	if(is_normal)
		return;
	
	if(textype & TEX_RGB) {
		QUATCOPY(result, &texres.tr);
	}
	else {
		QUATCOPY(result, col1);
		ramp_blend(MA_RAMP_BLEND, result, result+1, result+2, texres.tin, col2);
	}
}
Exemple #2
0
static void do_copy_split_rgba(bNode *UNUSED(node), float *out, float *in1, float *in2, float *fac)
{
	if(*fac==0.0f) {
		QUATCOPY(out, in1);
	}
	else {
		QUATCOPY(out, in2);
	}
}
Exemple #3
0
static void do_zcombine(bNode *node, float *out, float *src1, float *z1, float *src2, float *z2)
{
	if(*z1 <= *z2) {
		QUATCOPY(out, src1);
	}
	else {
		QUATCOPY(out, src2);
		
		if(node->custom1)
			*z1= *z2;
	}
}
Exemple #4
0
static void do_filter_edge(CompBuf *out, CompBuf *in, float *filter, float fac)
{
	float *row1, *row2, *row3;
	float *fp, f1, f2, mfac= 1.0f-fac;
	int rowlen, x, y, c, pix= in->type;
	
	rowlen= in->x;
	
	for(y=0; y<in->y; y++) {
		/* setup rows */
		if(y==0) row1= in->rect;
		else row1= in->rect + pix*(y-1)*rowlen;
		
		row2= in->rect + y*pix*rowlen;
		
		if(y==in->y-1) row3= row2;
		else row3= row2 + pix*rowlen;
		
		fp= out->rect + pix*y*rowlen;
		
		if(pix==CB_RGBA) {
			QUATCOPY(fp, row2);
			fp+= pix;
			
			for(x=2; x<rowlen; x++) {
				for(c=0; c<3; c++) {
					f1= filter[0]*row1[0] + filter[1]*row1[4] + filter[2]*row1[8] + filter[3]*row2[0] + filter[4]*row2[4] + filter[5]*row2[8] + filter[6]*row3[0] + filter[7]*row3[4] + filter[8]*row3[8];
					f2= filter[0]*row1[0] + filter[3]*row1[4] + filter[6]*row1[8] + filter[1]*row2[0] + filter[4]*row2[4] + filter[7]*row2[8] + filter[2]*row3[0] + filter[5]*row3[4] + filter[8]*row3[8];
					fp[0]= mfac*row2[4] + fac*sqrt(f1*f1 + f2*f2);
					fp++; row1++; row2++; row3++;
				}
				fp[0]= row2[4];
				/* no alpha... will clear it completely */
				fp++; row1++; row2++; row3++;
			}
			QUATCOPY(fp, row2+4);
		}
		else if(pix==CB_VAL) {
			fp+= pix;
			for(x=2; x<rowlen; x++) {
				f1= filter[0]*row1[0] + filter[1]*row1[1] + filter[2]*row1[2] + filter[3]*row2[0] + filter[4]*row2[1] + filter[5]*row2[2] + filter[6]*row3[0] + filter[7]*row3[1] + filter[8]*row3[2];
				f2= filter[0]*row1[0] + filter[3]*row1[1] + filter[6]*row1[2] + filter[1]*row2[0] + filter[4]*row2[1] + filter[7]*row2[2] + filter[2]*row3[0] + filter[5]*row3[1] + filter[8]*row3[2];
				fp[0]= mfac*row2[1] + fac*sqrt(f1*f1 + f2*f2);
				fp++; row1++; row2++; row3++;
			}
		}
	}
}
Exemple #5
0
static void node_composit_exec_rgb(void *UNUSED(data), bNode *node, bNodeStack **UNUSED(in), bNodeStack **out)
{
	bNodeSocket *sock= node->outputs.first;
	float *col= ((bNodeSocketValueRGBA*)sock->default_value)->value;
	
	QUATCOPY(out[0]->vec, col);
}
Exemple #6
0
static void do_alphaover_premul(bNode *UNUSED(node), float *out, float *src, float *over, float *fac)
{
	
	if(over[3]<=0.0f) {
		QUATCOPY(out, src);
	}
	else if(fac[0]==1.0f && over[3]>=1.0f) {
		QUATCOPY(out, over);
	}
	else {
		float mul= 1.0f - fac[0]*over[3];

		out[0]= (mul*src[0]) + fac[0]*over[0];
		out[1]= (mul*src[1]) + fac[0]*over[1];
		out[2]= (mul*src[2]) + fac[0]*over[2];
		out[3]= (mul*src[3]) + fac[0]*over[3];
	}	
}
Exemple #7
0
/* result will be still premul, but the over part is premulled */
static void do_alphaover_mixed(bNode *node, float *out, float *src, float *over, float *fac)
{
	
	if(over[3]<=0.0f) {
		QUATCOPY(out, src);
	}
	else if(fac[0]==1.0f && over[3]>=1.0f) {
		QUATCOPY(out, over);
	}
	else {
		NodeTwoFloats *ntf= node->storage;
		float addfac= 1.0f - ntf->x + over[3]*ntf->x;
		float premul= fac[0]*addfac;
		float mul= 1.0f - fac[0]*over[3];
		
		out[0]= (mul*src[0]) + premul*over[0];
		out[1]= (mul*src[1]) + premul*over[1];
		out[2]= (mul*src[2]) + premul*over[2];
		out[3]= (mul*src[3]) + fac[0]*over[3];
	}
}
Exemple #8
0
static void colorfn(float *out, TexParams *p, bNode *node, bNodeStack **in, short thread)
{
	Tex *nodetex = (Tex *)node->id;
	static float red[] = {1,0,0,1};
	static float white[] = {1,1,1,1};
	float co[3], dxt[3], dyt[3];
	
	copy_v3_v3(co, p->co);
	copy_v3_v3(dxt, p->dxt);
	copy_v3_v3(dyt, p->dyt);
	
	if(node->custom2 || node->need_exec==0) {
		/* this node refers to its own texture tree! */
		QUATCOPY(out, (fabs(co[0] - co[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_nodes(nodetex, co, dxt, dyt, p->osatex,
			&texres, thread, 0, p->shi, p->mtex);
		
		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);
		}
	}
}
Exemple #9
0
/* helper for poseAnim_mapping_get() -> get the relevant F-Curves per PoseChannel */
static void fcurves_to_pchan_links_get (ListBase *pfLinks, Object *ob, bAction *act, bPoseChannel *pchan)
{
	ListBase curves = {NULL, NULL};
	int transFlags = action_get_item_transforms(act, ob, pchan, &curves);
	
	pchan->flag &= ~(POSE_LOC|POSE_ROT|POSE_SIZE);
	
	/* check if any transforms found... */
	if (transFlags) {
		/* make new linkage data */
		tPChanFCurveLink *pfl= MEM_callocN(sizeof(tPChanFCurveLink), "tPChanFCurveLink");
		PointerRNA ptr;
		
		pfl->fcurves= curves;
		pfl->pchan= pchan;
		
		/* get the RNA path to this pchan - this needs to be freed! */
		RNA_pointer_create((ID *)ob, &RNA_PoseBone, pchan, &ptr);
		pfl->pchan_path= RNA_path_from_ID_to_struct(&ptr);
		
		/* add linkage data to operator data */
		BLI_addtail(pfLinks, pfl);
		
		/* set pchan's transform flags */
		if (transFlags & ACT_TRANS_LOC)
			pchan->flag |= POSE_LOC;
		if (transFlags & ACT_TRANS_ROT)
			pchan->flag |= POSE_ROT;
		if (transFlags & ACT_TRANS_SCALE)
			pchan->flag |= POSE_SIZE;
			
		/* store current transforms */
		VECCOPY(pfl->oldloc, pchan->loc);
		VECCOPY(pfl->oldrot, pchan->eul);
		VECCOPY(pfl->oldscale, pchan->size);
		QUATCOPY(pfl->oldquat, pchan->quat);
		VECCOPY(pfl->oldaxis, pchan->rotAxis);
		pfl->oldangle = pchan->rotAngle;
		
		/* make copy of custom properties */
		if (pchan->prop && (transFlags & ACT_TRANS_PROP))
			pfl->oldprops = IDP_CopyProperty(pchan->prop);
	}
} 
Exemple #10
0
static void do_invert_fac(bNode *node, float *out, float *in, float *fac)
{
	float col[4], facm;

	do_invert(node, col, in);

	/* blend inverted result against original input with fac */
	facm = 1.0 - fac[0];

	if(node->custom1 & CMP_CHAN_RGB) {
		col[0] = fac[0]*col[0] + (facm*in[0]);
		col[1] = fac[0]*col[1] + (facm*in[1]);
		col[2] = fac[0]*col[2] + (facm*in[2]);
	}
	if(node->custom1 & CMP_CHAN_A)
		col[3] = fac[0]*col[3] + (facm*in[3]);
	
	QUATCOPY(out, col);
}
Exemple #11
0
static void colorfn(float *out, TexParams *p, bNode *node, bNodeStack **UNUSED(in), short UNUSED(thread))
{
	float x = p->co[0];
	float y = p->co[1];
	Image *ima= (Image *)node->id;
	ImageUser *iuser= (ImageUser *)node->storage;
	
	if( ima ) {
		ImBuf *ibuf = BKE_image_get_ibuf(ima, iuser);
		if( ibuf ) {
			float xsize, ysize;
			float xoff, yoff;
			int px, py;
			
			float *result;

			xsize = ibuf->x / 2;
			ysize = ibuf->y / 2;
			xoff = yoff = -1;
					
			px = (int)( (x-xoff) * xsize );
			py = (int)( (y-yoff) * ysize );
		
			if( (!xsize) || (!ysize) ) return;
			
			if( !ibuf->rect_float ) {
				BLI_lock_thread(LOCK_IMAGE);
				if( !ibuf->rect_float )
					IMB_float_from_rect(ibuf);
				BLI_unlock_thread(LOCK_IMAGE);
			}
			
			while( px < 0 ) px += ibuf->x;
			while( py < 0 ) py += ibuf->y;
			while( px >= ibuf->x ) px -= ibuf->x;
			while( py >= ibuf->y ) py -= ibuf->y;
			
			result = ibuf->rect_float + py*ibuf->x*4 + px*4;
			QUATCOPY( out, result );
		}
	}
}
Exemple #12
0
/* note: it would be possible to use CMP version for both nodes */
static void do_hue_sat_fac(bNode *UNUSED(node), float *out, float *hue, float *sat, float *val, float *in, float *fac)
{
	if(*fac!=0.0f && (*hue!=0.5f || *sat!=1.0f || *val!=1.0f)) {
		float col[3], hsv[3], mfac= 1.0f - *fac;
		
		rgb_to_hsv(in[0], in[1], in[2], hsv, hsv+1, hsv+2);
		hsv[0]+= (*hue - 0.5f);
		if(hsv[0]>1.0f) hsv[0]-=1.0f; else if(hsv[0]<0.0f) hsv[0]+= 1.0f;
		hsv[1]*= *sat;
		hsv[2]*= *val;
		hsv_to_rgb(hsv[0], hsv[1], hsv[2], col, col+1, col+2);
		
		out[0]= mfac*in[0] + *fac*col[0];
		out[1]= mfac*in[1] + *fac*col[1];
		out[2]= mfac*in[2] + *fac*col[2];
	}
	else {
		QUATCOPY(out, in);
	}
}
Exemple #13
0
static void copy_pose_channel_data(bPoseChannel *pchan, const bPoseChannel *chan)
{
	bConstraint *pcon, *con;
	
	VECCOPY(pchan->loc, chan->loc);
	VECCOPY(pchan->size, chan->size);
	VECCOPY(pchan->eul, chan->eul);
	VECCOPY(pchan->rotAxis, chan->rotAxis);
	pchan->rotAngle= chan->rotAngle;
	QUATCOPY(pchan->quat, chan->quat);
	pchan->rotmode= chan->rotmode;
	copy_m4_m4(pchan->chan_mat, (float(*)[4])chan->chan_mat);
	copy_m4_m4(pchan->pose_mat, (float(*)[4])chan->pose_mat);
	pchan->flag= chan->flag;
	
	con= chan->constraints.first;
	for(pcon= pchan->constraints.first; pcon && con; pcon= pcon->next, con= con->next) {
		pcon->enforce= con->enforce;
		pcon->headtail= con->headtail;
	}
}
Exemple #14
0
static void node_composit_exec_normalize(void *UNUSED(data), bNode *node, bNodeStack **in, bNodeStack **out)
{
	/* stack order in: valbuf */
	/* stack order out: valbuf */
	if(out[0]->hasoutput==0) return;

	/* Input has no image buffer? Then pass the value */
	if(in[0]->data==NULL) {
		QUATCOPY(out[0]->vec, in[0]->vec);
	}
	else {
		float min = 1.0f+BLENDER_ZMAX;
		float max = -1.0f-BLENDER_ZMAX;
		float mult = 1.0f;
		float *val;
		/* make output size of input image */
		CompBuf *cbuf= in[0]->data;
		int tot= cbuf->x*cbuf->y;
		CompBuf *stackbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_VAL, 1); /* allocs */

		for (val = cbuf->rect; tot; tot--, val++) {
			if ((*val > max) && (*val <= BLENDER_ZMAX)) {
				max = *val;
			}
			if ((*val < min) && (*val >= -BLENDER_ZMAX)) {
				min = *val;
			}
		}
		/* In the rare case of flat buffer, which would cause a divide by 0, just pass the input to the output */
		if ((max-min) != 0.0f) {
			mult = 1.0f/(max-min);
			composit3_pixel_processor(node, stackbuf, in[0]->data, in[0]->vec, NULL, &min, NULL, &mult, do_normalize, CB_VAL, CB_VAL, CB_VAL);
		} else {
			memcpy(stackbuf->rect, cbuf->rect, sizeof(float) * cbuf->x * cbuf->y);
		}

		out[0]->data= stackbuf;
	}
}
Exemple #15
0
static void do_hue_sat_fac(bNode *UNUSED(node), float *out, float hue, float sat, float val, float *in, float fac)
{
	if(fac != 0 && (hue != 0.5f || sat != 1 || val != 1)) {
		float col[3], hsv[3], mfac= 1.0f - fac;
		
		rgb_to_hsv(in[0], in[1], in[2], hsv, hsv+1, hsv+2);
		hsv[0]+= (hue - 0.5f);
		if(hsv[0]>1.0f) hsv[0]-=1.0f; else if(hsv[0]<0.0f) hsv[0]+= 1.0f;
		hsv[1]*= sat;
		if(hsv[1]>1.0f) hsv[1]= 1.0f; else if(hsv[1]<0.0f) hsv[1]= 0.0f;
		hsv[2]*= val;
		if(hsv[2]>1.0f) hsv[2]= 1.0f; else if(hsv[2]<0.0f) hsv[2]= 0.0f;
		hsv_to_rgb(hsv[0], hsv[1], hsv[2], col, col+1, col+2);
		
		out[0]= mfac*in[0] + fac*col[0];
		out[1]= mfac*in[1] + fac*col[1];
		out[2]= mfac*in[2] + fac*col[2];
	}
	else {
		QUATCOPY(out, in);
	}
}
Exemple #16
0
static void do_hue_sat_fac(bNode *node, float *out, float *in, float *fac)
{
	NodeHueSat *nhs= node->storage;
	
	if(*fac!=0.0f && (nhs->hue!=0.5f || nhs->sat!=1.0 || nhs->val!=1.0)) {
		float col[3], hsv[3], mfac= 1.0f - *fac;
		
		rgb_to_hsv(in[0], in[1], in[2], hsv, hsv+1, hsv+2);
		hsv[0]+= (nhs->hue - 0.5f);
		if(hsv[0]>1.0) hsv[0]-=1.0; else if(hsv[0]<0.0) hsv[0]+= 1.0;
		hsv[1]*= nhs->sat;
		hsv[2]*= nhs->val;
		hsv_to_rgb(hsv[0], hsv[1], hsv[2], col, col+1, col+2);
		
		out[0]= mfac*in[0] + *fac*col[0];
		out[1]= mfac*in[1] + *fac*col[1];
		out[2]= mfac*in[2] + *fac*col[2];
		out[3]= in[3];
	}
	else {
		QUATCOPY(out, in);
	}
}
Exemple #17
0
/* both poses should be in sync */
void copy_pose_result(bPose *to, bPose *from)
{
	bPoseChannel *pchanto, *pchanfrom;
	
	if(to==NULL || from==NULL) {
		printf("pose result copy error to:%p from:%p\n", (void *)to, (void *)from); // debug temp
		return;
	}

	if (to==from) {
		printf("copy_pose_result source and target are the same\n");
		return;
	}


	for(pchanfrom= from->chanbase.first; pchanfrom; pchanfrom= pchanfrom->next) {
		pchanto= get_pose_channel(to, pchanfrom->name);
		if(pchanto) {
			copy_m4_m4(pchanto->pose_mat, pchanfrom->pose_mat);
			copy_m4_m4(pchanto->chan_mat, pchanfrom->chan_mat);
			
			/* used for local constraints */
			VECCOPY(pchanto->loc, pchanfrom->loc);
			QUATCOPY(pchanto->quat, pchanfrom->quat);
			VECCOPY(pchanto->eul, pchanfrom->eul);
			VECCOPY(pchanto->size, pchanfrom->size);
			
			VECCOPY(pchanto->pose_head, pchanfrom->pose_head);
			VECCOPY(pchanto->pose_tail, pchanfrom->pose_tail);
			
			pchanto->rotmode= pchanfrom->rotmode;
			pchanto->flag= pchanfrom->flag;
			pchanto->protectflag= pchanfrom->protectflag;
		}
	}
}
Exemple #18
0
/* draw grease-pencil datablock */
static void gp_draw_data (bGPdata *gpd, int offsx, int offsy, int winx, int winy, int cfra, int dflag)
{
	bGPDlayer *gpl, *actlay=NULL;
	
	/* reset line drawing style (in case previous user didn't reset) */
	setlinestyle(0);
	
	/* turn on smooth lines (i.e. anti-aliasing) */
	glEnable(GL_LINE_SMOOTH);
	
	/* turn on alpha-blending */
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	glEnable(GL_BLEND);
		
	/* loop over layers, drawing them */
	for (gpl= gpd->layers.first; gpl; gpl= gpl->next) {
		bGPDframe *gpf;
		
		short debug = (gpl->flag & GP_LAYER_DRAWDEBUG) ? 1 : 0;
		short lthick= gpl->thickness;
		float color[4], tcolor[4];
		
		/* don't draw layer if hidden */
		if (gpl->flag & GP_LAYER_HIDE) 
			continue;
		
		/* if layer is active one, store pointer to it */
		if (gpl->flag & GP_LAYER_ACTIVE)
			actlay= gpl;
		
		/* get frame to draw */
		gpf= gpencil_layer_getframe(gpl, cfra, 0);
		if (gpf == NULL) 
			continue;
		
		/* set color, stroke thickness, and point size */
		glLineWidth(lthick);
		QUATCOPY(color, gpl->color); // just for copying 4 array elements
		QUATCOPY(tcolor, gpl->color); // additional copy of color (for ghosting)
		glColor4f(color[0], color[1], color[2], color[3]);
		glPointSize((float)(gpl->thickness + 2));
		
		/* draw 'onionskins' (frame left + right) */
		if (gpl->flag & GP_LAYER_ONIONSKIN) {
			/* drawing method - only immediately surrounding (gstep = 0), or within a frame range on either side (gstep > 0)*/			
			if (gpl->gstep) {
				bGPDframe *gf;
				float fac;
				
				/* draw previous frames first */
				for (gf=gpf->prev; gf; gf=gf->prev) {
					/* check if frame is drawable */
					if ((gpf->framenum - gf->framenum) <= gpl->gstep) {
						/* alpha decreases with distance from curframe index */
						fac= (float)(gpf->framenum - gf->framenum) / (float)gpl->gstep;
						tcolor[3] = color[3] - fac;
						gp_draw_strokes(gf, offsx, offsy, winx, winy, dflag, debug, lthick, tcolor);
					}
					else 
						break;
				}
				
				/* now draw next frames */
				for (gf= gpf->next; gf; gf=gf->next) {
					/* check if frame is drawable */
					if ((gf->framenum - gpf->framenum) <= gpl->gstep) {
						/* alpha decreases with distance from curframe index */
						fac= (float)(gf->framenum - gpf->framenum) / (float)gpl->gstep;
						tcolor[3] = color[3] - fac;
						gp_draw_strokes(gf, offsx, offsy, winx, winy, dflag, debug, lthick, tcolor);
					}
					else 
						break;
				}	
				
				/* restore alpha */
				glColor4f(color[0], color[1], color[2], color[3]);
			}
			else {
				/* draw the strokes for the ghost frames (at half of the alpha set by user) */
				if (gpf->prev) {
					tcolor[3] = (color[3] / 7);
					gp_draw_strokes(gpf->prev, offsx, offsy, winx, winy, dflag, debug, lthick, tcolor);
				}
				
				if (gpf->next) {
					tcolor[3] = (color[3] / 4);
					gp_draw_strokes(gpf->next, offsx, offsy, winx, winy, dflag, debug, lthick, tcolor);
				}
				
				/* restore alpha */
				glColor4f(color[0], color[1], color[2], color[3]);
			}
		}
		
		/* draw the strokes already in active frame */
		tcolor[3]= color[3];
		gp_draw_strokes(gpf, offsx, offsy, winx, winy, dflag, debug, lthick, tcolor);
		
		/* Check if may need to draw the active stroke cache, only if this layer is the active layer
		 * that is being edited. (Stroke buffer is currently stored in gp-data)
		 */
		if ((G.f & G_GREASEPENCIL) && (gpl->flag & GP_LAYER_ACTIVE) &&
			(gpf->flag & GP_FRAME_PAINT)) 
		{
			/* Buffer stroke needs to be drawn with a different linestyle to help differentiate them from normal strokes. */
			gp_draw_stroke_buffer(gpd->sbuffer, gpd->sbuffer_size, lthick, dflag, gpd->sbuffer_sflag);
		}
	}
	
	/* turn off alpha blending, then smooth lines */
	glDisable(GL_BLEND); // alpha blending
	glDisable(GL_LINE_SMOOTH); // smooth lines
		
	/* restore initial gl conditions */
	glLineWidth(1.0);
	glPointSize(1.0);
	glColor4f(0, 0, 0, 1);
}
Exemple #19
0
/* clear rotation of object */
static void object_clear_rot(Object *ob)
{
	/* clear rotations that aren't locked */
	if (ob->protectflag & (OB_LOCK_ROTX|OB_LOCK_ROTY|OB_LOCK_ROTZ|OB_LOCK_ROTW)) {
		if (ob->protectflag & OB_LOCK_ROT4D) {
			/* perform clamping on a component by component basis */
			if (ob->rotmode == ROT_MODE_AXISANGLE) {
				if ((ob->protectflag & OB_LOCK_ROTW) == 0)
					ob->rotAngle= ob->drotAngle= 0.0f;
				if ((ob->protectflag & OB_LOCK_ROTX) == 0)
					ob->rotAxis[0]= ob->drotAxis[0]= 0.0f;
				if ((ob->protectflag & OB_LOCK_ROTY) == 0)
					ob->rotAxis[1]= ob->drotAxis[1]= 0.0f;
				if ((ob->protectflag & OB_LOCK_ROTZ) == 0)
					ob->rotAxis[2]= ob->drotAxis[2]= 0.0f;
					
				/* check validity of axis - axis should never be 0,0,0 (if so, then we make it rotate about y) */
				if (IS_EQ(ob->rotAxis[0], ob->rotAxis[1]) && IS_EQ(ob->rotAxis[1], ob->rotAxis[2]))
					ob->rotAxis[1] = 1.0f;
				if (IS_EQ(ob->drotAxis[0], ob->drotAxis[1]) && IS_EQ(ob->drotAxis[1], ob->drotAxis[2]))
					ob->drotAxis[1]= 1.0f;
			}
			else if (ob->rotmode == ROT_MODE_QUAT) {
				if ((ob->protectflag & OB_LOCK_ROTW) == 0)
					ob->quat[0]= ob->dquat[0]= 1.0f;
				if ((ob->protectflag & OB_LOCK_ROTX) == 0)
					ob->quat[1]= ob->dquat[1]= 0.0f;
				if ((ob->protectflag & OB_LOCK_ROTY) == 0)
					ob->quat[2]= ob->dquat[2]= 0.0f;
				if ((ob->protectflag & OB_LOCK_ROTZ) == 0)
					ob->quat[3]= ob->dquat[3]= 0.0f;
					
				// TODO: does this quat need normalising now?
			}
			else {
				/* the flag may have been set for the other modes, so just ignore the extra flag... */
				if ((ob->protectflag & OB_LOCK_ROTX) == 0)
					ob->rot[0]= ob->drot[0]= 0.0f;
				if ((ob->protectflag & OB_LOCK_ROTY) == 0)
					ob->rot[1]= ob->drot[1]= 0.0f;
				if ((ob->protectflag & OB_LOCK_ROTZ) == 0)
					ob->rot[2]= ob->drot[2]= 0.0f;
			}
		}
		else {
			/* perform clamping using euler form (3-components) */
			// FIXME: deltas are not handled for these cases yet...
			float eul[3], oldeul[3], quat1[4] = {0};
			
			if (ob->rotmode == ROT_MODE_QUAT) {
				QUATCOPY(quat1, ob->quat);
				quat_to_eul(oldeul, ob->quat);
			}
			else if (ob->rotmode == ROT_MODE_AXISANGLE) {
				axis_angle_to_eulO(oldeul, EULER_ORDER_DEFAULT, ob->rotAxis, ob->rotAngle);
			}
			else {
				copy_v3_v3(oldeul, ob->rot);
			}
			
			eul[0]= eul[1]= eul[2]= 0.0f;
			
			if (ob->protectflag & OB_LOCK_ROTX)
				eul[0]= oldeul[0];
			if (ob->protectflag & OB_LOCK_ROTY)
				eul[1]= oldeul[1];
			if (ob->protectflag & OB_LOCK_ROTZ)
				eul[2]= oldeul[2];
			
			if (ob->rotmode == ROT_MODE_QUAT) {
				eul_to_quat(ob->quat, eul);
				/* quaternions flip w sign to accumulate rotations correctly */
				if ((quat1[0]<0.0f && ob->quat[0]>0.0f) || (quat1[0]>0.0f && ob->quat[0]<0.0f)) {
					mul_qt_fl(ob->quat, -1.0f);
				}
			}
			else if (ob->rotmode == ROT_MODE_AXISANGLE) {
				eulO_to_axis_angle(ob->rotAxis, &ob->rotAngle,eul, EULER_ORDER_DEFAULT);
			}
			else {
				copy_v3_v3(ob->rot, eul);
			}
		}
	}						 // Duplicated in source/blender/editors/armature/editarmature.c
	else { 
		if (ob->rotmode == ROT_MODE_QUAT) {
			unit_qt(ob->quat);
			unit_qt(ob->dquat);
		}
		else if (ob->rotmode == ROT_MODE_AXISANGLE) {
			unit_axis_angle(ob->rotAxis, &ob->rotAngle);
			unit_axis_angle(ob->drotAxis, &ob->drotAngle);
		}
		else {
			zero_v3(ob->rot);
			zero_v3(ob->drot);
		}
	}
}
Exemple #20
0
/* ctime is normalized range <0-1> */
int where_on_path(Object *ob, float ctime, float *vec, float *dir, float *quat, float *radius)	/* returns OK */
{
	Curve *cu;
	Nurb *nu;
	BevList *bl;
	Path *path;
	PathPoint *pp, *p0, *p1, *p2, *p3;
	float fac;
	float data[4];
	int cycl=0, s0, s1, s2, s3;

	if(ob==NULL || ob->type != OB_CURVE) return 0;
	cu= ob->data;
	if(cu->path==NULL || cu->path->data==NULL) {
		printf("no path!\n");
		return 0;
	}
	path= cu->path;
	pp= path->data;
	
	/* test for cyclic */
	bl= cu->bev.first;
	if (!bl) return 0;
	if (!bl->nr) return 0;
	if(bl->poly> -1) cycl= 1;

	ctime *= (path->len-1);
	
	s1= (int)floor(ctime);
	fac= (float)(s1+1)-ctime;

	/* path->len is corected for cyclic */
	s0= interval_test(0, path->len-1-cycl, s1-1, cycl);
	s1= interval_test(0, path->len-1-cycl, s1, cycl);
	s2= interval_test(0, path->len-1-cycl, s1+1, cycl);
	s3= interval_test(0, path->len-1-cycl, s1+2, cycl);

	p0= pp + s0;
	p1= pp + s1;
	p2= pp + s2;
	p3= pp + s3;

	/* note, commented out for follow constraint */
	//if(cu->flag & CU_FOLLOW) {
		
		key_curve_tangent_weights(1.0f-fac, data, KEY_BSPLINE);
		
		dir[0]= data[0]*p0->vec[0] + data[1]*p1->vec[0] + data[2]*p2->vec[0] + data[3]*p3->vec[0] ;
		dir[1]= data[0]*p0->vec[1] + data[1]*p1->vec[1] + data[2]*p2->vec[1] + data[3]*p3->vec[1] ;
		dir[2]= data[0]*p0->vec[2] + data[1]*p1->vec[2] + data[2]*p2->vec[2] + data[3]*p3->vec[2] ;
		
		/* make compatible with vectoquat */
		dir[0]= -dir[0];
		dir[1]= -dir[1];
		dir[2]= -dir[2];
	//}
	
	nu= cu->nurb.first;

	/* make sure that first and last frame are included in the vectors here  */
	if(nu->type == CU_POLY) key_curve_position_weights(1.0f-fac, data, KEY_LINEAR);
	else if(nu->type == CU_BEZIER) key_curve_position_weights(1.0f-fac, data, KEY_LINEAR);
	else if(s0==s1 || p2==p3) key_curve_position_weights(1.0f-fac, data, KEY_CARDINAL);
	else key_curve_position_weights(1.0f-fac, data, KEY_BSPLINE);

	vec[0]= data[0]*p0->vec[0] + data[1]*p1->vec[0] + data[2]*p2->vec[0] + data[3]*p3->vec[0] ; /* X */
	vec[1]= data[0]*p0->vec[1] + data[1]*p1->vec[1] + data[2]*p2->vec[1] + data[3]*p3->vec[1] ; /* Y */
	vec[2]= data[0]*p0->vec[2] + data[1]*p1->vec[2] + data[2]*p2->vec[2] + data[3]*p3->vec[2] ; /* Z */
	vec[3]= data[0]*p0->vec[3] + data[1]*p1->vec[3] + data[2]*p2->vec[3] + data[3]*p3->vec[3] ; /* Tilt, should not be needed since we have quat still used */
	/* Need to verify the quat interpolation is correct - XXX */

	if (quat) {
		//float totfac, q1[4], q2[4];

		/* checks for totfac are needed when 'fac' is 1.0 key_curve_position_weights can assign zero
		 * to more then one index in data which can give divide by zero error */
/*
		totfac= data[0]+data[1];
		if(totfac>0.000001)	QuatInterpol(q1, p0->quat, p1->quat, data[0] / totfac);
		else				QUATCOPY(q1, p1->quat);

		NormalQuat(q1);

		totfac= data[2]+data[3];
		if(totfac>0.000001)	QuatInterpol(q2, p2->quat, p3->quat, data[2] / totfac);
		else				QUATCOPY(q1, p3->quat);
		NormalQuat(q2);

		totfac = data[0]+data[1]+data[2]+data[3];
		if(totfac>0.000001)	QuatInterpol(quat, q1, q2, (data[0]+data[1]) / totfac);
		else				QUATCOPY(quat, q2);
		NormalQuat(quat);
		*/
		// XXX - find some way to make quat interpolation work correctly, above code fails in rare but nasty cases.
		QUATCOPY(quat, p1->quat);
	}

	if(radius)
		*radius= data[0]*p0->radius + data[1]*p1->radius + data[2]*p2->radius + data[3]*p3->radius;

	return 1;
}
Exemple #21
0
static void do_filter3(CompBuf *out, CompBuf *in, float *filter, float fac)
{
	float *row1, *row2, *row3;
	float *fp, mfac= 1.0f-fac;
	int rowlen, x, y, c;
	int pixlen= in->type;
	
	rowlen= in->x;
	
	for(y=0; y<in->y; y++) {
		/* setup rows */
		if(y==0) row1= in->rect;
		else row1= in->rect + pixlen*(y-1)*rowlen;
		
		row2= in->rect + y*pixlen*rowlen;
		
		if(y==in->y-1) row3= row2;
		else row3= row2 + pixlen*rowlen;
		
		fp= out->rect + pixlen*(y)*rowlen;
		
		if(pixlen==1) {
			fp[0]= row2[0];
			fp+= 1;
			
			for(x=2; x<rowlen; x++) {
				fp[0]= mfac*row2[1] + fac*(filter[0]*row1[0] + filter[1]*row1[1] + filter[2]*row1[2] + filter[3]*row2[0] + filter[4]*row2[1] + filter[5]*row2[2] + filter[6]*row3[0] + filter[7]*row3[1] + filter[8]*row3[2]);
				fp++; row1++; row2++; row3++;
			}
			fp[0]= row2[1];
		}
		else if(pixlen==2) {
			fp[0]= row2[0];
			fp[1]= row2[1];
			fp+= 2;
			
			for(x=2; x<rowlen; x++) {
				for(c=0; c<2; c++) {
					fp[0]= mfac*row2[2] + fac*(filter[0]*row1[0] + filter[1]*row1[2] + filter[2]*row1[4] + filter[3]*row2[0] + filter[4]*row2[2] + filter[5]*row2[4] + filter[6]*row3[0] + filter[7]*row3[2] + filter[8]*row3[4]);
					fp++; row1++; row2++; row3++;
				}
			}
			fp[0]= row2[2];
			fp[1]= row2[3];
		}
		else if(pixlen==3) {
			VECCOPY(fp, row2);
			fp+= 3;
			
			for(x=2; x<rowlen; x++) {
				for(c=0; c<3; c++) {
					fp[0]= mfac*row2[3] + fac*(filter[0]*row1[0] + filter[1]*row1[3] + filter[2]*row1[6] + filter[3]*row2[0] + filter[4]*row2[3] + filter[5]*row2[6] + filter[6]*row3[0] + filter[7]*row3[3] + filter[8]*row3[6]);
					fp++; row1++; row2++; row3++;
				}
			}
			VECCOPY(fp, row2+3);
		}
		else {
			QUATCOPY(fp, row2);
			fp+= 4;
			
			for(x=2; x<rowlen; x++) {
				for(c=0; c<4; c++) {
					fp[0]= mfac*row2[4] + fac*(filter[0]*row1[0] + filter[1]*row1[4] + filter[2]*row1[8] + filter[3]*row2[0] + filter[4]*row2[4] + filter[5]*row2[8] + filter[6]*row3[0] + filter[7]*row3[4] + filter[8]*row3[8]);
					fp++; row1++; row2++; row3++;
				}
			}
			QUATCOPY(fp, row2+4);
		}
	}
}
Exemple #22
0
/* the main entry point for volume shading */
static void volume_trace(struct ShadeInput *shi, struct ShadeResult *shr, int inside_volume)
{
	float hitco[3], col[4] = {0.f,0.f,0.f,0.f};
	float *startco, *endco;
	int trace_behind = 1;
	const int ztransp= ((shi->depth==0) && (shi->mat->mode & MA_TRANSP) && (shi->mat->mode & MA_ZTRANSP));
	Isect is;

	/* check for shading an internal face a volume object directly */
	if (inside_volume == VOL_SHADE_INSIDE)
		trace_behind = 0;
	else if (inside_volume == VOL_SHADE_OUTSIDE) {
		if (shi->flippednor)
			inside_volume = VOL_SHADE_INSIDE;
	}
	
	if (ztransp && inside_volume == VOL_SHADE_INSIDE) {
		MatInside *mi;
		int render_this=0;
		
		/* don't render the backfaces of ztransp volume materials.
		 
		 * volume shading renders the internal volume from between the
		 * ' view intersection of the solid volume to the
		 * intersection on the other side, as part of the shading of
		 * the front face.
		 
		 * Because ztransp renders both front and back faces independently
		 * this will double up, so here we prevent rendering the backface as well, 
		 * which would otherwise render the volume in between the camera and the backface
		 * --matt */
		
		for (mi=R.render_volumes_inside.first; mi; mi=mi->next) {
			/* weak... */
			if (mi->ma == shi->mat) render_this=1;
		}
		if (!render_this) return;
	}
	

	if (inside_volume == VOL_SHADE_INSIDE)
	{
		startco = shi->camera_co;
		endco = shi->co;
		
		if (trace_behind) {
			if (!ztransp)
				/* trace behind the volume object */
				vol_trace_behind(shi, shi->vlr, endco, col);
		} else {
			/* we're tracing through the volume between the camera 
			 * and a solid surface, so use that pre-shaded radiance */
			QUATCOPY(col, shr->combined);
		}
		
		/* shade volume from 'camera' to 1st hit point */
		volumeintegrate(shi, col, startco, endco);
	}
	/* trace to find a backface, the other side bounds of the volume */
	/* (ray intersect ignores front faces here) */
	else if (vol_get_bounds(shi, shi->co, shi->view, hitco, &is, VOL_BOUNDS_DEPTH))
	{
		VlakRen *vlr = (VlakRen *)is.hit.face;
		
		startco = shi->co;
		endco = hitco;
		
		if (!ztransp) {
			/* if it's another face in the same material */
			if (vlr->mat == shi->mat) {
				/* trace behind the 2nd (raytrace) hit point */
				vol_trace_behind(shi, (VlakRen *)is.hit.face, endco, col);
			} else {
				shade_intersection(shi, col, &is);
			}
		}
		
		/* shade volume from 1st hit point to 2nd hit point */
		volumeintegrate(shi, col, startco, endco);
	}
	
	if (ztransp)
		col[3] = col[3]>1.f?1.f:col[3];
	else
		col[3] = 1.f;
	
	copy_v3_v3(shr->combined, col);
	shr->alpha = col[3];
	
	VECCOPY(shr->diff, shr->combined);
}