Пример #1
0
static bool depth_read_normal(
        const ViewContext *vc, const bglMats *mats, const int mval[2],
        float r_normal[3])
{
	/* pixels surrounding */
	bool  depths_valid[9] = {false};
	float coords[9][3] = {{0}};

	ARegion *ar = vc->ar;
	const ViewDepths *depths = vc->rv3d->depths;

	for (int x = 0, i = 0; x < 2; x++) {
		for (int y = 0; y < 2; y++) {
			const int mval_ofs[2] = {mval[0] + (x - 1), mval[1] + (y - 1)};

			const double depth = (double)depth_read_zbuf(vc, mval_ofs[0], mval_ofs[1]);
			if ((depth > depths->depth_range[0]) && (depth < depths->depth_range[1])) {
				if (depth_unproject(ar, mats, mval_ofs, depth, coords[i])) {
					depths_valid[i] = true;
				}
			}
			i++;
		}
	}

	const int edges[2][6][2] = {
	    /* x edges */
	    {{0, 1}, {1, 2},
	     {3, 4}, {4, 5},
	     {6, 7}, {7, 8}},
	    /* y edges */
	    {{0, 3}, {3, 6},
	     {1, 4}, {4, 7},
	     {2, 5}, {5, 8}},
	};

	float cross[2][3] = {{0.0f}};

	for (int i = 0; i < 6; i++) {
		for (int axis = 0; axis < 2; axis++) {
			if (depths_valid[edges[axis][i][0]] && depths_valid[edges[axis][i][1]]) {
				float delta[3];
				sub_v3_v3v3(delta, coords[edges[axis][i][0]], coords[edges[axis][i][1]]);
				add_v3_v3(cross[axis], delta);
			}
		}
	}

	cross_v3_v3v3(r_normal, cross[0], cross[1]);

	if (normalize_v3(r_normal) != 0.0f) {
		return true;
	}
	else {
		return false;
	}
}
Пример #2
0
void BLI_mirrorAlongAxis(float v[3], float center[3], float axis[3])
{
	float dv[3], pv[3];
	
	sub_v3_v3v3(dv, v, center);
	project_v3_v3v3(pv, dv, axis);
	mul_v3_fl(pv, -2);
	add_v3_v3(v, pv);
}
Пример #3
0
static int rule_separate(BoidRule *UNUSED(rule), BoidBrainData *bbd, BoidValues *val, ParticleData *pa)
{
	KDTreeNearest *ptn = NULL;
	ParticleTarget *pt;
	float len = 2.0f * val->personal_space * pa->size + 1.0f;
	float vec[3] = {0.0f, 0.0f, 0.0f};
	int neighbors = BLI_kdtree_range_search(
	            bbd->sim->psys->tree, pa->prev_state.co,
	            &ptn, 2.0f * val->personal_space * pa->size);
	int ret = 0;

	if (neighbors > 1 && ptn[1].dist!=0.0f) {
		sub_v3_v3v3(vec, pa->prev_state.co, bbd->sim->psys->particles[ptn[1].index].state.co);
		mul_v3_fl(vec, (2.0f * val->personal_space * pa->size - ptn[1].dist) / ptn[1].dist);
		add_v3_v3(bbd->wanted_co, vec);
		bbd->wanted_speed = val->max_speed;
		len = ptn[1].dist;
		ret = 1;
	}
	if (ptn) { MEM_freeN(ptn); ptn=NULL; }

	/* check other boid systems */
	for (pt=bbd->sim->psys->targets.first; pt; pt=pt->next) {
		ParticleSystem *epsys = psys_get_target_system(bbd->sim->ob, pt);

		if (epsys) {
			neighbors = BLI_kdtree_range_search(
			        epsys->tree, pa->prev_state.co,
			        &ptn, 2.0f * val->personal_space * pa->size);
			
			if (neighbors > 0 && ptn[0].dist < len) {
				sub_v3_v3v3(vec, pa->prev_state.co, ptn[0].co);
				mul_v3_fl(vec, (2.0f * val->personal_space * pa->size - ptn[0].dist) / ptn[1].dist);
				add_v3_v3(bbd->wanted_co, vec);
				bbd->wanted_speed = val->max_speed;
				len = ptn[0].dist;
				ret = 1;
			}

			if (ptn) { MEM_freeN(ptn); ptn=NULL; }
		}
	}
	return ret;
}
Пример #4
0
/* this makes sure we can extend for non-cyclic.
 *
 * returns OK: 1/0
 */
static int where_on_path_deform(Object *ob, float ctime, float vec[4], float dir[3], float quat[4], float *radius)
{
	Curve *cu = ob->data;
	BevList *bl;
	float ctime1;
	int cycl = 0;
	
	/* test for cyclic */
	bl = cu->bev.first;
	if (!bl->nr) return 0;
	if (bl && bl->poly > -1) cycl = 1;

	if (cycl == 0) {
		ctime1 = CLAMPIS(ctime, 0.0f, 1.0f);
	}
	else ctime1 = ctime;
	
	/* vec needs 4 items */
	if (where_on_path(ob, ctime1, vec, dir, quat, radius, NULL)) {
		
		if (cycl == 0) {
			Path *path = cu->path;
			float dvec[3];
			
			if (ctime < 0.0f) {
				sub_v3_v3v3(dvec, path->data[1].vec, path->data[0].vec);
				mul_v3_fl(dvec, ctime * (float)path->len);
				add_v3_v3(vec, dvec);
				if (quat) copy_qt_qt(quat, path->data[0].quat);
				if (radius) *radius = path->data[0].radius;
			}
			else if (ctime > 1.0f) {
				sub_v3_v3v3(dvec, path->data[path->len - 1].vec, path->data[path->len - 2].vec);
				mul_v3_fl(dvec, (ctime - 1.0f) * (float)path->len);
				add_v3_v3(vec, dvec);
				if (quat) copy_qt_qt(quat, path->data[path->len - 1].quat);
				if (radius) *radius = path->data[path->len - 1].radius;
				/* weight - not used but could be added */
			}
		}
		return 1;
	}
	return 0;
}
Пример #5
0
static void bone_align_to_bone(ListBase *edbo, EditBone *selbone, EditBone *actbone)
{
	float selboneaxis[3], actboneaxis[3], length;

	sub_v3_v3v3(actboneaxis, actbone->tail, actbone->head);
	normalize_v3(actboneaxis);

	sub_v3_v3v3(selboneaxis, selbone->tail, selbone->head);
	length =  len_v3(selboneaxis);

	mul_v3_fl(actboneaxis, length);
	add_v3_v3v3(selbone->tail, selbone->head, actboneaxis);
	selbone->roll = actbone->roll;

	/* if the bone being aligned has connected descendants they must be moved
	 * according to their parent new position, otherwise they would be left
	 * in an inconsistent state: connected but away from the parent*/
	fix_editbone_connected_children(edbo, selbone);
}
Пример #6
0
void angle_quad_v3(float angles[4], const float v1[3], const float v2[3], const float v3[3], const float v4[3])
{
	float ed1[3], ed2[3], ed3[3], ed4[3];

	sub_v3_v3v3(ed1, v4, v1);
	sub_v3_v3v3(ed2, v1, v2);
	sub_v3_v3v3(ed3, v2, v3);
	sub_v3_v3v3(ed4, v3, v4);

	normalize_v3(ed1);
	normalize_v3(ed2);
	normalize_v3(ed3);
	normalize_v3(ed4);

	angles[0] = (float)M_PI - angle_normalized_v3v3(ed1, ed2);
	angles[1] = (float)M_PI - angle_normalized_v3v3(ed2, ed3);
	angles[2] = (float)M_PI - angle_normalized_v3v3(ed3, ed4);
	angles[3] = (float)M_PI - angle_normalized_v3v3(ed4, ed1);
}
Пример #7
0
/** ensure \a v1 is \a dist from \a v2 */
void dist_ensure_v3_v3fl(float v1[3], const float v2[3], const float dist)
{
	if (!equals_v3v3(v2, v1)) {
		float nor[3];

		sub_v3_v3v3(nor, v1, v2);
		normalize_v3(nor);
		madd_v3_v3v3fl(v1, v2, nor, dist);
	}
}
Пример #8
0
static void cyclic_offs_bone(Object *ob, bPose *pose, bActionStrip *strip, float time)
{
	/* only called when strip has cyclic, so >= 1.0f works... */
	if(time >= 1.0f) {
		bActionChannel *achan= get_action_channel(strip->act, strip->offs_bone);

		if(achan && achan->ipo) {
			IpoCurve *icu= NULL;
			Bone *bone;
			float min[3]={0.0f, 0.0f, 0.0f}, max[3]={0.0f, 0.0f, 0.0f};
			int index=0, foundvert= 0;
			
			/* calculate the min/max */
			for (icu=achan->ipo->curve.first; icu; icu=icu->next) {
				if(icu->totvert>1) {
					
					if(icu->adrcode==AC_LOC_X)
						index= 0;
					else if(icu->adrcode==AC_LOC_Y)
						index= 1;
					else if(icu->adrcode==AC_LOC_Z)
						index= 2;
					else
						continue;
				
					foundvert= 1;
					min[index]= icu->bezt[0].vec[1][1];
					max[index]= icu->bezt[icu->totvert-1].vec[1][1];
				}
			}
			if(foundvert) {
				/* bring it into armature space */
				sub_v3_v3v3(min, max, min);
				bone= get_named_bone(ob->data, strip->offs_bone);	/* weak */
				if(bone) {
					mul_mat3_m4_v3(bone->arm_mat, min);
					
					/* dominant motion, cyclic_offset was cleared in rest_pose */
					if (strip->flag & (ACTSTRIP_CYCLIC_USEX | ACTSTRIP_CYCLIC_USEY | ACTSTRIP_CYCLIC_USEZ)) {
						if (strip->flag & ACTSTRIP_CYCLIC_USEX) pose->cyclic_offset[0]= time*min[0];
						if (strip->flag & ACTSTRIP_CYCLIC_USEY) pose->cyclic_offset[1]= time*min[1];
						if (strip->flag & ACTSTRIP_CYCLIC_USEZ) pose->cyclic_offset[2]= time*min[2];
					} else {
						if( fabs(min[0]) >= fabs(min[1]) && fabs(min[0]) >= fabs(min[2]))
							pose->cyclic_offset[0]= time*min[0];
						else if( fabs(min[1]) >= fabs(min[0]) && fabs(min[1]) >= fabs(min[2]))
							pose->cyclic_offset[1]= time*min[1];
						else
							pose->cyclic_offset[2]= time*min[2];
					}
				}
			}
		}
	}
}
Пример #9
0
static MDefBoundIsect *meshdeform_ray_tree_intersect(MeshDeformBind *mdb, float *co1, float *co2)
{
	MDefBoundIsect *isect;
	MeshDeformIsect isec;
	float (*cagecos)[3];
	MFace *mface;
	float vert[4][3], len, end[3];
	static float epsilon[3]= {0, 0, 0}; //1e-4, 1e-4, 1e-4};

	/* setup isec */
	memset(&isec, 0, sizeof(isec));
	isec.labda= 1e10f;

	VECADD(isec.start, co1, epsilon);
	VECADD(end, co2, epsilon);
	sub_v3_v3v3(isec.vec, end, isec.start);

	if(meshdeform_intersect(mdb, &isec)) {
		len= isec.labda;
		mface=(MFace*)isec.face;

		/* create MDefBoundIsect */
		isect= BLI_memarena_alloc(mdb->memarena, sizeof(*isect));

		/* compute intersection coordinate */
		isect->co[0]= co1[0] + isec.vec[0]*len;
		isect->co[1]= co1[1] + isec.vec[1]*len;
		isect->co[2]= co1[2] + isec.vec[2]*len;

		isect->len= len_v3v3(co1, isect->co);
		if(isect->len < MESHDEFORM_LEN_THRESHOLD)
			isect->len= MESHDEFORM_LEN_THRESHOLD;

		isect->v[0]= mface->v1;
		isect->v[1]= mface->v2;
		isect->v[2]= mface->v3;
		isect->v[3]= mface->v4;
		isect->nvert= (mface->v4)? 4: 3;

		isect->facing= isec.isect;

		/* compute mean value coordinates for interpolation */
		cagecos= mdb->cagecos;
		copy_v3_v3(vert[0], cagecos[mface->v1]);
		copy_v3_v3(vert[1], cagecos[mface->v2]);
		copy_v3_v3(vert[2], cagecos[mface->v3]);
		if(mface->v4) copy_v3_v3(vert[3], cagecos[mface->v4]);
		interp_weights_poly_v3( isect->uvw,vert, isect->nvert, isect->co);

		return isect;
	}

	return NULL;
}
Пример #10
0
static void particle_system_minmax(Scene *scene,
                                   Object *object,
                                   ParticleSystem *psys,
                                   float radius,
                                   float min[3], float max[3])
{
	const float size[3] = {radius, radius, radius};
	const float cfra = BKE_scene_frame_get(scene);
	ParticleSettings *part = psys->part;
	ParticleSimulationData sim = {NULL};
	ParticleData *pa = NULL;
	int i;
	int total_particles;
	float mat[4][4], imat[4][4];

	INIT_MINMAX(min, max);
	if (part->type == PART_HAIR) {
		/* TOOD(sergey): Not supported currently. */
		return;
	}

	unit_m4(mat);
	psys_render_set(object, psys, mat, mat, 1, 1, 0);

	sim.scene = scene;
	sim.ob = object;
	sim.psys = psys;
	sim.psmd = psys_get_modifier(object, psys);

	invert_m4_m4(imat, object->obmat);
	total_particles = psys->totpart + psys->totchild;
	psys->lattice_deform_data = psys_create_lattice_deform_data(&sim);

	for (i = 0, pa = psys->particles; i < total_particles; i++, pa++) {
		float co_object[3], co_min[3], co_max[3];
		ParticleKey state;
		state.time = cfra;
		if (!psys_get_particle_state(&sim, i, &state, 0)) {
			continue;
		}
		mul_v3_m4v3(co_object, imat, state.co);
		sub_v3_v3v3(co_min, co_object, size);
		add_v3_v3v3(co_max, co_object, size);
		minmax_v3v3_v3(min, max, co_min);
		minmax_v3v3_v3(min, max, co_max);
	}

	if (psys->lattice_deform_data) {
		end_latt_deform(psys->lattice_deform_data);
		psys->lattice_deform_data = NULL;
	}

	psys_render_restore(object, psys);
}
Пример #11
0
/* helper to fix a ebone position if its parent has moved due to alignment*/
static void fix_connected_bone(EditBone *ebone)
{
	float diff[3];

	if (!(ebone->parent) || !(ebone->flag & BONE_CONNECTED) || equals_v3v3(ebone->parent->tail, ebone->head))
		return;

	/* if the parent has moved we translate child's head and tail accordingly */
	sub_v3_v3v3(diff, ebone->parent->tail, ebone->head);
	add_v3_v3(ebone->head, diff);
	add_v3_v3(ebone->tail, diff);
}
Пример #12
0
/* project a vector on a plane defined by normal and a plane point p */
void project_v3_plane(float v[3], const float n[3], const float p[3])
{
	float vector[3];
	float mul;

	sub_v3_v3v3(vector, v, p);
	mul = dot_v3v3(vector, n) / len_squared_v3(n);

	mul_v3_v3fl(vector, n, mul);

	sub_v3_v3(v, vector);
}
Пример #13
0
static float ResizeBetween(TransInfo *t, const float p1[3], const float p2[3])
{
	float d1[3], d2[3], len_d1;

	sub_v3_v3v3(d1, p1, t->center_global);
	sub_v3_v3v3(d2, p2, t->center_global);

	if (t->con.applyRot != NULL && (t->con.mode & CON_APPLY)) {
		mul_m3_v3(t->con.pmtx, d1);
		mul_m3_v3(t->con.pmtx, d2);
	}

	project_v3_v3v3(d1, d1, d2);
	
	len_d1 = len_v3(d1);

	/* Use 'invalid' dist when `center == p1` (after projecting),
	 * in this case scale will _never_ move the point in relation to the center,
	 * so it makes no sense to take it into account when scaling. see: T46503 */
	return len_d1 != 0.0f ? len_v3(d2) / len_d1 : TRANSFORM_DIST_INVALID;
}
Пример #14
0
static void group_duplilist(ListBase *lb, Scene *scene, Object *ob, int level, int animated)
{
	DupliObject *dob;
	Group *group;
	GroupObject *go;
	float mat[4][4], tmat[4][4];
	
	if (ob->dup_group==NULL) return;
	group= ob->dup_group;
	
	/* simple preventing of too deep nested groups */
	if (level>MAX_DUPLI_RECUR) return;
	
	/* handles animated groups, and */
	/* we need to check update for objects that are not in scene... */
	group_handle_recalc_and_update(scene, ob, group);
	animated= animated || group_is_animated(ob, group);
	
	for (go= group->gobject.first; go; go= go->next) {
		/* note, if you check on layer here, render goes wrong... it still deforms verts and uses parent imat */
		if (go->ob!=ob) {
			
			/* group dupli offset, should apply after everything else */
			if (!is_zero_v3(group->dupli_ofs)) {
				copy_m4_m4(tmat, go->ob->obmat);
				sub_v3_v3v3(tmat[3], tmat[3], group->dupli_ofs);
				mult_m4_m4m4(mat, ob->obmat, tmat);
			}
			else {
				mult_m4_m4m4(mat, ob->obmat, go->ob->obmat);
			}
			
			dob= new_dupli_object(lb, go->ob, mat, ob->lay, 0, OB_DUPLIGROUP, animated);

			/* check the group instance and object layers match, also that the object visible flags are ok. */
			if (	(dob->origlay & group->layer)==0 ||
				(G.rendering==0 && dob->ob->restrictflag & OB_RESTRICT_VIEW) ||
				(G.rendering && dob->ob->restrictflag & OB_RESTRICT_RENDER)
			) {
				dob->no_draw= 1;
			}
			else {
				dob->no_draw= 0;
			}

			if (go->ob->transflag & OB_DUPLI) {
				copy_m4_m4(dob->ob->obmat, dob->mat);
				object_duplilist_recursive(&group->id, scene, go->ob, lb, ob->obmat, level+1, animated);
				copy_m4_m4(dob->ob->obmat, dob->omat);
			}
		}
	}
}
Пример #15
0
static void cloth_hair_update_bending_rest_targets(ClothModifierData *clmd)
{
	Cloth *cloth = clmd->clothObject;
	LinkNode *search = NULL;
	float hair_frame[3][3], dir_old[3], dir_new[3];
	int prev_mn; /* to find hair roots */
	
	if (!clmd->hairdata)
		return;
	
	/* XXX Note: we need to propagate frames from the root up,
	 * but structural hair springs are stored in reverse order.
	 * The bending springs however are then inserted in the same
	 * order as vertices again ...
	 * This messy situation can be resolved when solver data is
	 * generated directly from a dedicated hair system.
	 */
	
	prev_mn = -1;
	for (search = cloth->springs; search; search = search->next) {
		ClothSpring *spring = search->link;
		ClothHairData *hair_ij, *hair_kl;
		bool is_root = spring->kl != prev_mn;
		
		if (spring->type != CLOTH_SPRING_TYPE_BENDING_ANG) {
			continue;
		}
		
		hair_ij = &clmd->hairdata[spring->ij];
		hair_kl = &clmd->hairdata[spring->kl];
		if (is_root) {
			/* initial hair frame from root orientation */
			copy_m3_m3(hair_frame, hair_ij->rot);
			/* surface normal is the initial direction,
			 * parallel transport then keeps it aligned to the hair direction
			 */
			copy_v3_v3(dir_new, hair_frame[2]);
		}
		
		copy_v3_v3(dir_old, dir_new);
		sub_v3_v3v3(dir_new, cloth->verts[spring->mn].xrest, cloth->verts[spring->kl].xrest);
		normalize_v3(dir_new);
		
		/* dir expressed in the hair frame defines the rest target direction */
		copy_v3_v3(hair_kl->rest_target, dir_new);
		mul_transposed_m3_v3(hair_frame, hair_kl->rest_target);
		
		/* move frame to next hair segment */
		cloth_parallel_transport_hair_frame(hair_frame, dir_old, dir_new);
		
		prev_mn = spring->mn;
	}
}
Пример #16
0
float distPointToSegmentSq(const float* point, const float* a, const float* b)
{
	float abx[3], dx[3];
	float d, t;

	sub_v3_v3v3(abx, b,a);
	sub_v3_v3v3(dx, point,a);

	d = abx[0]*abx[0]+abx[2]*abx[2];
	t = abx[0]*dx[0]+abx[2]*dx[2];

	if (d > 0)
		t /= d;
	if (t < 0)
		t = 0;
	else if (t > 1)
		t = 1;
	dx[0] = a[0] + t*abx[0] - point[0];
	dx[2] = a[2] + t*abx[2] - point[2];

	return dx[0]*dx[0] + dx[2]*dx[2];
}
/* XXX, could replace with #dist_to_line_segment_v3(), or add a squared version */
float distPointToSegmentSq(const float point[3], const float a[3], const float b[3])
{
	float abx[3], dx[3];
	float d, t;

	sub_v3_v3v3(abx, b, a);
	sub_v3_v3v3(dx, point, a);

	d = abx[0] * abx[0] + abx[2] * abx[2];
	t = abx[0] * dx[0] + abx[2] * dx[2];

	if (d > 0.0f)
		t /= d;
	if (t < 0.0f)
		t = 0.0f;
	else if (t > 1.0f)
		t = 1.0f;
	dx[0] = a[0] + t * abx[0] - point[0];
	dx[2] = a[2] + t * abx[2] - point[2];

	return dx[0] * dx[0] + dx[2] * dx[2];
}
Пример #18
0
static void do_twist(const ParticleChildModifierContext *modifier_ctx,
                     ParticleKey *state, const float time)
{
	ParticleThreadContext *thread_ctx = modifier_ctx->thread_ctx;
	ParticleSimulationData *sim = modifier_ctx->sim;
	ParticleTexture *ptex = modifier_ctx->ptex;
	ParticleSettings *part = sim->psys->part;
	/* Early output checks. */
	if (modifier_ctx->parent_keys == NULL) {
		/* Cannot get axis of rotation... */
		return;
	}
	if (part->childtype != PART_CHILD_PARTICLES) {
		/* Interpolated children behave weird with twist. */
		return;
	}
	if (part->twist == 0.0f) {
		/* No twist along the strand.  */
		return;
	}
	/* Dependent on whether it's threaded update or not, curve comes
	 * from different places.
	 */
	CurveMapping *twist_curve = NULL;
	if (part->child_flag & PART_CHILD_USE_TWIST_CURVE) {
		twist_curve = (thread_ctx != NULL) ? thread_ctx->twistcurve
		                                   : part->twistcurve;
	}
	/* Axis of rotation. */
	float axis[3];
	twist_get_axis(modifier_ctx, time, axis);
	/* Angle of rotation. */
	float angle = part->twist;
	if (ptex != NULL) {
		angle *= (ptex->twist - 0.5f) * 2.0f;
	}
	if (twist_curve != NULL) {
		const int num_segments = twist_num_segments(modifier_ctx);
		angle *= curvemapping_integrate_clamped(twist_curve,
		                                        0.0f, time,
		                                        1.0f / num_segments);
	}
	else {
		angle *= time;
	}
	/* Perform rotation around parent curve. */
	float vec[3];
	sub_v3_v3v3(vec, state->co, modifier_ctx->par_co);
	rotate_v3_v3v3fl(state->co, vec, axis, angle * 2.0f * M_PI);
	add_v3_v3(state->co, modifier_ctx->par_co);
}
Пример #19
0
/* tracing */
static float vol_get_shadow(ShadeInput *shi, LampRen *lar, const float co[3])
{
	float visibility = 1.f;
	
	if (lar->shb) {
		float dxco[3] = {0.f, 0.f, 0.f}, dyco[3] = {0.f, 0.f, 0.f};
		
		visibility = testshadowbuf(&R, lar->shb, co, dxco, dyco, 1.0, 0.0);
	}
	else if (lar->mode & LA_SHAD_RAY) {
		/* trace shadow manually, no good lamp api atm */
		Isect is;
		
		copy_v3_v3(is.start, co);
		if (lar->type == LA_SUN || lar->type == LA_HEMI) {
			is.dir[0] = -lar->vec[0];
			is.dir[1] = -lar->vec[1];
			is.dir[2] = -lar->vec[2];
			is.dist = R.maxdist;
		}
		else {
			sub_v3_v3v3(is.dir, lar->co, is.start);
			is.dist = normalize_v3(is.dir);
		}

		is.mode = RE_RAY_MIRROR;
		is.check = RE_CHECK_VLR_NON_SOLID_MATERIAL;
		is.skip = 0;
		
		if (lar->mode & (LA_LAYER | LA_LAYER_SHADOW))
			is.lay = lar->lay;
		else
			is.lay = -1;
			
		is.orig.ob = NULL;
		is.orig.face = NULL;
		is.last_hit = lar->last_hit[shi->thread];
		
		RE_instance_rotate_ray(shi->obi, &is);

		if (RE_rayobject_raycast(R.raytree, &is)) {
			RE_instance_rotate_ray_restore(shi->obi, &is);

			visibility = 0.f;
		}
		
		lar->last_hit[shi->thread] = is.last_hit;
	}
	return visibility;
}
Пример #20
0
static void rna_EditBone_matrix_get(PointerRNA *ptr, float *values)
{
	EditBone *ebone = (EditBone *)(ptr->data);

	float delta[3], tmat[3][3], mat[4][4];

	/* Find the current bone matrix */
	sub_v3_v3v3(delta, ebone->tail, ebone->head);
	vec_roll_to_mat3(delta, ebone->roll, tmat);
	copy_m4_m3(mat, tmat);
	copy_v3_v3(mat[3], ebone->head);

	memcpy(values, mat, 16 * sizeof(float));
}
Пример #21
0
static void flagAxialSymmetry(BNode *root_node, BNode *end_node, BArc *arc, int group)
{
	float vec[3];
	
	arc->symmetry_group = group;
	
	sub_v3_v3v3(vec, end_node->p, root_node->p);
	
	if (dot_v3v3(vec, root_node->symmetry_axis) < 0) {
		arc->symmetry_flag |= SYM_SIDE_NEGATIVE;
	}
	else {
		arc->symmetry_flag |= SYM_SIDE_POSITIVE;
	}
}
Пример #22
0
static bool check_path_length(int k, ParticleCacheKey *keys, ParticleCacheKey *key, float max_length, float step_length, float *cur_length, float dvec[3])
{
	if (*cur_length + step_length > max_length) {
		sub_v3_v3v3(dvec, key->co, (key-1)->co);
		mul_v3_fl(dvec, (max_length - *cur_length) / step_length);
		add_v3_v3v3(key->co, (key-1)->co, dvec);
		keys->segments = k;
		/* something over the maximum step value */
		return false;
	}
	else {
		*cur_length += step_length;
		return true;
	}
}
Пример #23
0
static float heat_source_distance(LaplacianSystem *sys, int vertex, int source)
{
	float closest[3], d[3], dist, cosine;
	
	/* compute euclidian distance */
	closest_to_line_segment_v3(closest, sys->heat.verts[vertex], sys->heat.root[source], sys->heat.tip[source]);

	sub_v3_v3v3(d, sys->heat.verts[vertex], closest);
	dist = normalize_v3(d);

	/* if the vertex normal does not point along the bone, increase distance */
	cosine = dot_v3v3(d, sys->heat.vnors[vertex]);

	return dist / (0.5f * (cosine + 1.001f));
}
Пример #24
0
BMFace *BKE_bmbvh_find_face_segment(BMBVHTree *bmtree, const float co_a[3], const float co_b[3],
                                    float *r_fac, float r_hitout[3], float r_cagehit[3])
{
	BVHTreeRayHit hit;
	struct SegmentUserData bmcb_data;
	const float dist = len_v3v3(co_a, co_b);
	float dir[3];

	if (bmtree->cos_cage) BLI_assert(!(bmtree->bm->elem_index_dirty & BM_VERT));

	sub_v3_v3v3(dir, co_b, co_a);

	hit.dist = dist;
	hit.index = -1;

	/* ok to leave 'uv' uninitialized */
	bmcb_data.looptris = (const BMLoop *(*)[3])bmtree->looptris;
	bmcb_data.cos_cage = (const float (*)[3])bmtree->cos_cage;
	bmcb_data.co_a = co_a;
	bmcb_data.co_b = co_b;

	BLI_bvhtree_ray_cast(bmtree->tree, co_a, dir, 0.0f, &hit, bmbvh_find_face_segment_cb, &bmcb_data);
	if (hit.index != -1 && hit.dist != dist) {
		/* duplicate of BKE_bmbvh_ray_cast() */
		if (r_hitout) {
			if (bmtree->flag & BMBVH_RETURN_ORIG) {
				BMLoop **ltri = bmtree->looptris[hit.index];
				interp_v3_v3v3v3_uv(r_hitout, ltri[0]->v->co, ltri[1]->v->co, ltri[2]->v->co, bmcb_data.uv);
			}
			else {
				copy_v3_v3(r_hitout, hit.co);
			}

			if (r_cagehit) {
				copy_v3_v3(r_cagehit, hit.co);
			}
		}
		/* end duplicate */

		if (r_fac) {
			*r_fac = hit.dist / dist;
		}

		return bmtree->looptris[hit.index][0]->f;
	}

	return NULL;
}
static void ApplySnapTranslation(TransInfo *t, float vec[3])
{
	float point[3];
	getSnapPoint(t, point);

	if (t->spacetype == SPACE_NODE) {
		char border = t->tsnap.snapNodeBorder;
		if (border & (NODE_LEFT | NODE_RIGHT))
			vec[0] = point[0] - t->tsnap.snapTarget[0];
		if (border & (NODE_BOTTOM | NODE_TOP))
			vec[1] = point[1] - t->tsnap.snapTarget[1];
	}
	else {
		sub_v3_v3v3(vec, point, t->tsnap.snapTarget);
	}
}
Пример #26
0
static void bone_connect_to_new_parent(ListBase *edbo, EditBone *selbone, EditBone *actbone, short mode)
{
	EditBone *ebone;
	float offset[3];
	
	if ((selbone->parent) && (selbone->flag & BONE_CONNECTED))
		selbone->parent->flag &= ~(BONE_TIPSEL);
	
	/* make actbone the parent of selbone */
	selbone->parent = actbone;
	
	/* in actbone tree we cannot have a loop */
	for (ebone = actbone->parent; ebone; ebone = ebone->parent) {
		if (ebone->parent == selbone) {
			ebone->parent = NULL;
			ebone->flag &= ~BONE_CONNECTED;
		}
	}
	
	if (mode == ARM_PAR_CONNECT) {
		/* Connected: Child bones will be moved to the parent tip */
		selbone->flag |= BONE_CONNECTED;
		sub_v3_v3v3(offset, actbone->tail, selbone->head);
		
		copy_v3_v3(selbone->head, actbone->tail);
		selbone->rad_head = actbone->rad_tail;
		
		add_v3_v3(selbone->tail, offset);
		
		/* offset for all its children */
		for (ebone = edbo->first; ebone; ebone = ebone->next) {
			EditBone *par;
			
			for (par = ebone->parent; par; par = par->parent) {
				if (par == selbone) {
					add_v3_v3(ebone->head, offset);
					add_v3_v3(ebone->tail, offset);
					break;
				}
			}
		}
	}
	else {
		/* Offset: Child bones will retain their distance from the parent tip */
		selbone->flag &= ~BONE_CONNECTED;
	}
}
Пример #27
0
static void multires_reshape_vertex_from_final_data(MultiresReshapeContext *ctx,
                                                    const int ptex_face_index,
                                                    const float corner_u,
                                                    const float corner_v,
                                                    const int coarse_poly_index,
                                                    const int coarse_corner,
                                                    const float final_P[3],
                                                    const float final_mask)
{
  Subdiv *subdiv = ctx->subdiv;
  const int grid_size = ctx->top_grid_size;
  const Mesh *coarse_mesh = ctx->coarse_mesh;
  const MPoly *coarse_mpoly = coarse_mesh->mpoly;
  const MPoly *coarse_poly = &coarse_mpoly[coarse_poly_index];
  const int loop_index = coarse_poly->loopstart + coarse_corner;
  /* Evaluate limit surface. */
  float P[3], dPdu[3], dPdv[3];
  multires_reshape_sample_surface(
      subdiv, coarse_poly, coarse_corner, corner_u, corner_v, ptex_face_index, P, dPdu, dPdv);
  /* Construct tangent matrix which matches orientation of the current
   * displacement grid. */
  float tangent_matrix[3][3], inv_tangent_matrix[3][3];
  multires_reshape_tangent_matrix_for_corner(
      coarse_poly, coarse_corner, dPdu, dPdv, tangent_matrix);
  invert_m3_m3(inv_tangent_matrix, tangent_matrix);
  /* Convert object coordinate to a tangent space of displacement grid. */
  float D[3];
  sub_v3_v3v3(D, final_P, P);
  float tangent_D[3];
  mul_v3_m3v3(tangent_D, inv_tangent_matrix, D);
  /* Calculate index of element within the grid. */
  float grid_u, grid_v;
  BKE_subdiv_ptex_face_uv_to_grid_uv(corner_u, corner_v, &grid_u, &grid_v);
  const int grid_x = (grid_u * (grid_size - 1) + 0.5f);
  const int grid_y = (grid_v * (grid_size - 1) + 0.5f);
  const int index = grid_y * grid_size + grid_x;
  /* Write tangent displacement. */
  MDisps *displacement_grid = &ctx->mdisps[loop_index];
  copy_v3_v3(displacement_grid->disps[index], tangent_D);
  /* Write mask grid. */
  if (ctx->grid_paint_mask != NULL) {
    GridPaintMask *grid_paint_mask = &ctx->grid_paint_mask[loop_index];
    BLI_assert(grid_paint_mask->level == displacement_grid->level);
    grid_paint_mask->data[index] = final_mask;
  }
}
Пример #28
0
/* get the camera's dof value, takes the dof object into account */
float BKE_camera_object_dof_distance(Object *ob)
{
	Camera *cam = (Camera *)ob->data;
	if (ob->type != OB_CAMERA)
		return 0.0f;
	if (cam->dof_ob) {
#if 0
		/* too simple, better to return the distance on the view axis only */
		return len_v3v3(ob->obmat[3], cam->dof_ob->obmat[3]);
#else
		float view_dir[3], dof_dir[3];
		normalize_v3_v3(view_dir, ob->obmat[2]);
		sub_v3_v3v3(dof_dir, ob->obmat[3], cam->dof_ob->obmat[3]);
		return fabsf(dot_v3v3(view_dir, dof_dir));
#endif
	}
	return cam->YF_dofdist;
}
Пример #29
0
static void boid_climb(BoidSettings *boids, ParticleData *pa, float *surface_co, float *surface_nor)
{
	BoidParticle *bpa = pa->boid;
	float nor[3], vel[3];
	copy_v3_v3(nor, surface_nor);

	/* gather apparent gravity */
	madd_v3_v3fl(bpa->gravity, surface_nor, -1.0f);
	normalize_v3(bpa->gravity);

	/* raise boid it's size from surface */
	mul_v3_fl(nor, pa->size * boids->height);
	add_v3_v3v3(pa->state.co, surface_co, nor);

	/* remove normal component from velocity */
	project_v3_v3v3(vel, pa->state.vel, surface_nor);
	sub_v3_v3v3(pa->state.vel, pa->state.vel, vel);
}
Пример #30
0
static void rigid_add_half_edge_to_rhs(LaplacianSystem *sys, EditVert *v1, EditVert *v2, float w)
{
	/* formula (8) */
	float Rsum[3][3], rhs[3];

	if (sys->vpinned[v1->tmp.l])
		return;

	add_m3_m3m3(Rsum, sys->rigid.R[v1->tmp.l], sys->rigid.R[v2->tmp.l]);
	transpose_m3(Rsum);

	sub_v3_v3v3(rhs, sys->rigid.origco[v1->tmp.l], sys->rigid.origco[v2->tmp.l]);
	mul_m3_v3(Rsum, rhs);
	mul_v3_fl(rhs, 0.5f);
	mul_v3_fl(rhs, w);

	add_v3_v3(sys->rigid.rhs[v1->tmp.l], rhs);
}