BL_ArmatureConstraint::BL_ArmatureConstraint(
	BL_ArmatureObject *armature,
	bPoseChannel *posechannel,
	bConstraint *constraint,
	KX_GameObject* target,
	KX_GameObject* subtarget)
	: PyObjectPlus(), m_constraint(constraint), m_posechannel(posechannel), m_armature(armature)
{
	m_target = target;
	m_blendtarget = (target) ? target->GetBlenderObject() : NULL;
	m_subtarget = subtarget;
	m_blendsubtarget = (subtarget) ? subtarget->GetBlenderObject() : NULL;
	m_pose = m_subpose = NULL;
	if (m_blendtarget) {
		copy_m4_m4(m_blendmat, m_blendtarget->obmat);
		if (m_blendtarget->type == OB_ARMATURE)
			m_pose = m_blendtarget->pose;
	}
	if (m_blendsubtarget) {
		copy_m4_m4(m_blendsubmat, m_blendsubtarget->obmat);
		if (m_blendsubtarget->type == OB_ARMATURE)
			m_subpose = m_blendsubtarget->pose;
	}
	if (m_target)
		m_target->RegisterObject(m_armature);
	if (m_subtarget)
		m_subtarget->RegisterObject(m_armature);
	BLI_snprintf(m_name, sizeof(m_name), "%s:%s", m_posechannel->name, m_constraint->name);
}
Example #2
0
static void copy_pose_channel_data(bPoseChannel *pchan, const bPoseChannel *chan)
{
	bConstraint *pcon, *con;
	
	copy_v3_v3(pchan->loc, chan->loc);
	copy_v3_v3(pchan->size, chan->size);
	copy_v3_v3(pchan->eul, chan->eul);
	copy_v3_v3(pchan->rotAxis, chan->rotAxis);
	pchan->rotAngle = chan->rotAngle;
	copy_qt_qt(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;
	
	pchan->roll1 = chan->roll1;
	pchan->roll2 = chan->roll2;
	pchan->curveInX = chan->curveInX;
	pchan->curveInY = chan->curveInY;
	pchan->curveOutX = chan->curveOutX;
	pchan->curveOutY = chan->curveOutY;
	pchan->scaleIn = chan->scaleIn;
	pchan->scaleOut = chan->scaleOut;
	
	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;
	}
}
Example #3
0
static DupliObject *new_dupli_object(ListBase *lb, Object *ob, float mat[4][4], int lay,
                                     int persistent_id[MAX_DUPLI_RECUR], int level, int index, int type, short flag)
{
	DupliObject *dob = MEM_callocN(sizeof(DupliObject), "dupliobject");
	int i;

	BLI_addtail(lb, dob);
	dob->ob = ob;
	copy_m4_m4(dob->mat, mat);
	copy_m4_m4(dob->omat, ob->obmat);
	dob->origlay = ob->lay;
	dob->type = type;
	dob->animated = (type == OB_DUPLIGROUP) && (flag & DUPLILIST_ANIMATED);
	ob->lay = lay;

	/* set persistent id, which is an array with a persistent index for each level
	 * (particle number, vertex number, ..). by comparing this we can find the same
	 * dupli object between frames, which is needed for motion blur. last level
	 * goes first in the array. */
	dob->persistent_id[0] = index;
	for (i = 1; i < level; i++)
		dob->persistent_id[i] = persistent_id[level - 1 - i];
	
	/* metaballs never draw in duplis, they are instead merged into one by the basis
	 * mball outside of the group. this does mean that if that mball is not in the
	 * scene, they will not show up at all, limitation that should be solved once. */
	if (ob->type == OB_MBALL)
		dob->no_draw = TRUE;
	
	return dob;
}
Example #4
0
DupliApplyData *duplilist_apply(Object *ob, Scene *scene, ListBase *duplilist)
{
	DupliApplyData *apply_data = NULL;
	int num_objects = BLI_listbase_count(duplilist);
	
	if (num_objects > 0) {
		DupliObject *dob;
		int i;
		apply_data = MEM_mallocN(sizeof(DupliApplyData), "DupliObject apply data");
		apply_data->num_objects = num_objects;
		apply_data->extra = MEM_mallocN(sizeof(DupliExtraData) * (size_t) num_objects,
		                                "DupliObject apply extra data");

		for (dob = duplilist->first, i = 0; dob; dob = dob->next, ++i) {
			/* copy obmat from duplis */
			copy_m4_m4(apply_data->extra[i].obmat, dob->ob->obmat);

			/* make sure derivedmesh is calculated once, before drawing */
			if (scene && !(dob->ob->transflag & OB_DUPLICALCDERIVED) && dob->ob->type == OB_MESH) {
				mesh_get_derived_final(scene, dob->ob, scene->customdata_mask);
				dob->ob->transflag |= OB_DUPLICALCDERIVED;
			}

			copy_m4_m4(dob->ob->obmat, dob->mat);
			
			/* copy layers from the main duplicator object */
			apply_data->extra[i].lay = dob->ob->lay;
			dob->ob->lay = ob->lay;
		}
	}
	return apply_data;
}
void env_rotate_scene(Render *re, float mat[4][4], int do_rotate)
{
	GroupObject *go;
	ObjectRen *obr;
	ObjectInstanceRen *obi;
	LampRen *lar = NULL;
	HaloRen *har = NULL;
	float imat[3][3], mat_inverse[4][4], smat[4][4], tmat[4][4], cmat[3][3], tmpmat[4][4];
	int a;
	
	if (do_rotate == 0) {
		invert_m4_m4(tmat, mat);
		copy_m3_m4(imat, tmat);
		
		copy_m4_m4(mat_inverse, mat);
	}
	else {
		copy_m4_m4(tmat, mat);
		copy_m3_m4(imat, mat);
		
		invert_m4_m4(mat_inverse, tmat);
	}

	for (obi = re->instancetable.first; obi; obi = obi->next) {
		/* append or set matrix depending on dupli */
		if (obi->flag & R_DUPLI_TRANSFORMED) {
			copy_m4_m4(tmpmat, obi->mat);
			mul_m4_m4m4(obi->mat, tmat, tmpmat);
		}
		else if (do_rotate == 1)
			copy_m4_m4(obi->mat, tmat);
		else
			unit_m4(obi->mat);

		copy_m3_m4(cmat, obi->mat);
		invert_m3_m3(obi->nmat, cmat);
		transpose_m3(obi->nmat);

		/* indicate the renderer has to use transform matrices */
		if (do_rotate == 0)
			obi->flag &= ~R_ENV_TRANSFORMED;
		else {
			obi->flag |= R_ENV_TRANSFORMED;
			copy_m4_m4(obi->imat, mat_inverse);
		}
	}
	

	for (obr = re->objecttable.first; obr; obr = obr->next) {
		for (a = 0; a < obr->tothalo; a++) {
			if ((a & 255) == 0) har = obr->bloha[a >> 8];
			else har++;
		
			mul_m4_v3(tmat, har->co);
		}

		/* imat_ren is needed for correct texture coordinates */
		mul_m4_m4m4(obr->ob->imat_ren, re->viewmat, obr->ob->obmat);
		invert_m4(obr->ob->imat_ren);
	}
Example #6
0
static void group_duplilist(ListBase *lb, Scene *scene, Object *ob, int persistent_id[MAX_DUPLI_RECUR],
                            int level, short flag)
{
	DupliObject *dob;
	Group *group;
	GroupObject *go;
	float mat[4][4], tmat[4][4], id;
	
	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... */
	if (flag & DUPLILIST_DO_UPDATE) {
		/* note: update is optional because we don't always need object
		 * transformations to be correct. Also fixes bug [#29616]. */
		group_handle_recalc_and_update(scene, ob, group);
	}

	if (group_is_animated(ob, group))
		flag |= DUPLILIST_ANIMATED;
	
	for (go = group->gobject.first, id = 0; go; go = go->next, id++) {
		/* 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, persistent_id, level, id, OB_DUPLIGROUP, flag);

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

			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, persistent_id, level + 1, id, flag);
				copy_m4_m4(dob->ob->obmat, dob->omat);
			}
		}
	}
}
Example #7
0
void mesh_deform_bind(Scene *scene, MeshDeformModifierData *mmd, float *vertexcos, int totvert, float cagemat[][4])
{
	MeshDeformBind mdb;
	MVert *mvert;
	int a;

	waitcursor(1);
	start_progress_bar();

	memset(&mdb, 0, sizeof(MeshDeformBind));

	/* get mesh and cage mesh */
	mdb.vertexcos= MEM_callocN(sizeof(float)*3*totvert, "MeshDeformCos");
	mdb.totvert= totvert;
	
	mdb.cagedm= mesh_create_derived_no_deform(scene, mmd->object, NULL, CD_MASK_BAREMESH);
	mdb.totcagevert= mdb.cagedm->getNumVerts(mdb.cagedm);
	mdb.cagecos= MEM_callocN(sizeof(*mdb.cagecos)*mdb.totcagevert, "MeshDeformBindCos");
	copy_m4_m4(mdb.cagemat, cagemat);

	mvert= mdb.cagedm->getVertArray(mdb.cagedm);
	for(a=0; a<mdb.totcagevert; a++)
		copy_v3_v3(mdb.cagecos[a], mvert[a].co);
	for(a=0; a<mdb.totvert; a++)
		mul_v3_m4v3(mdb.vertexcos[a], mdb.cagemat, vertexcos + a*3);

	/* solve */
#if 0
	if(mmd->mode == MOD_MDEF_VOLUME)
		harmonic_coordinates_bind(scene, mmd, &mdb);
	else
		heat_weighting_bind(scene, dm, mmd, &mdb);
#else
	harmonic_coordinates_bind(scene, mmd, &mdb);
#endif

	/* assign bind variables */
	mmd->bindcagecos= (float*)mdb.cagecos;
	mmd->totvert= mdb.totvert;
	mmd->totcagevert= mdb.totcagevert;
	copy_m4_m4(mmd->bindmat, mmd->object->obmat);

	/* transform bindcagecos to world space */
	for(a=0; a<mdb.totcagevert; a++)
		mul_m4_v3(mmd->object->obmat, mmd->bindcagecos+a*3);

	/* free */
	mdb.cagedm->release(mdb.cagedm);
	MEM_freeN(mdb.vertexcos);

	/* compact weights */
	modifier_mdef_compact_influences((ModifierData*)mmd);

	end_progress_bar();
	waitcursor(0);
}
Example #8
0
void ArmatureExporter::add_bone_transform(Object *ob_arm, Bone *bone, COLLADASW::Node &node)
{
  // bPoseChannel *pchan = BKE_pose_channel_find_name(ob_arm->pose, bone->name);

  float mat[4][4];
  float bone_rest_mat[4][4];   /* derived from bone->arm_mat */
  float parent_rest_mat[4][4]; /* derived from bone->parent->arm_mat */

  bool has_restmat = bc_get_property_matrix(bone, "rest_mat", mat);

  if (!has_restmat) {

    /* Have no restpose matrix stored, try old style <= Blender 2.78 */

    bc_create_restpose_mat(this->export_settings, bone, bone_rest_mat, bone->arm_mat, true);

    if (is_export_root(bone)) {
      copy_m4_m4(mat, bone_rest_mat);
    }
    else {
      Matrix parent_inverse;
      bc_create_restpose_mat(
          this->export_settings, bone->parent, parent_rest_mat, bone->parent->arm_mat, true);

      invert_m4_m4(parent_inverse, parent_rest_mat);
      mul_m4_m4m4(mat, parent_inverse, bone_rest_mat);
    }

    // OPEN_SIM_COMPATIBILITY

    if (export_settings.get_open_sim()) {
      // Remove rotations vs armature from transform
      // parent_rest_rot * mat * irest_rot
      Matrix workmat;
      copy_m4_m4(workmat, bone_rest_mat);

      workmat[3][0] = workmat[3][1] = workmat[3][2] = 0.0f;
      invert_m4(workmat);

      mul_m4_m4m4(mat, mat, workmat);

      if (!is_export_root(bone)) {
        copy_m4_m4(workmat, parent_rest_mat);
        workmat[3][0] = workmat[3][1] = workmat[3][2] = 0.0f;

        mul_m4_m4m4(mat, workmat, mat);
      }
    }
  }

  if (this->export_settings.get_limit_precision()) {
    bc_sanitize_mat(mat, LIMITTED_PRECISION);
  }

  TransformWriter::add_joint_transform(node, mat, NULL, this->export_settings, has_restmat);
}
Example #9
0
/* For the calculation of the effects of an Action at the given frame on an object 
 * This is currently only used for the Action Constraint 
 */
void what_does_obaction (Object *ob, Object *workob, bPose *pose, bAction *act, char groupname[], float cframe)
{
	bActionGroup *agrp= action_groups_find_named(act, groupname);
	
	/* clear workob */
	clear_workob(workob);
	
	/* init workob */
	copy_m4_m4(workob->obmat, ob->obmat);
	copy_m4_m4(workob->parentinv, ob->parentinv);
	copy_m4_m4(workob->constinv, ob->constinv);
	workob->parent= ob->parent;
	
	workob->rotmode= ob->rotmode;
	
	workob->trackflag= ob->trackflag;
	workob->upflag= ob->upflag;
	
	workob->partype= ob->partype;
	workob->par1= ob->par1;
	workob->par2= ob->par2;
	workob->par3= ob->par3;

	workob->constraints.first = ob->constraints.first;
	workob->constraints.last = ob->constraints.last;
	
	workob->pose= pose;	/* need to set pose too, since this is used for both types of Action Constraint */

	BLI_strncpy(workob->parsubstr, ob->parsubstr, sizeof(workob->parsubstr));
	BLI_strncpy(workob->id.name, "OB<ConstrWorkOb>", sizeof(workob->id.name)); /* we don't use real object name, otherwise RNA screws with the real thing */
	
	/* if we're given a group to use, it's likely to be more efficient (though a bit more dangerous) */
	if (agrp) {
		/* specifically evaluate this group only */
		PointerRNA id_ptr;
		
		/* get RNA-pointer for the workob's ID */
		RNA_id_pointer_create(&workob->id, &id_ptr);
		
		/* execute action for this group only */
		animsys_evaluate_action_group(&id_ptr, act, agrp, NULL, cframe);
	}
	else {
		AnimData adt= {NULL};
		
		/* init animdata, and attach to workob */
		workob->adt= &adt;
		
		adt.recalc= ADT_RECALC_ANIM;
		adt.action= act;
		
		/* execute effects of Action on to workob (or it's PoseChannels) */
		BKE_animsys_evaluate_animdata(NULL, &workob->id, &adt, cframe, ADT_RECALC_ANIM);
	}
}
Example #10
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);
			}
		}
	}
}
Example #11
0
static void bundle_midpoint(Scene *scene, Object *ob, float vec[3])
{
	MovieClip *clip = BKE_object_movieclip_get(scene, ob, false);
	MovieTracking *tracking;
	MovieTrackingObject *object;
	bool ok = false;
	float min[3], max[3], mat[4][4], pos[3], cammat[4][4];

	if (!clip)
		return;

	tracking = &clip->tracking;

	copy_m4_m4(cammat, ob->obmat);

	BKE_tracking_get_camera_object_matrix(scene, ob, mat);

	INIT_MINMAX(min, max);

	for (object = tracking->objects.first; object; object = object->next) {
		ListBase *tracksbase = BKE_tracking_object_get_tracks(tracking, object);
		MovieTrackingTrack *track = tracksbase->first;
		float obmat[4][4];

		if (object->flag & TRACKING_OBJECT_CAMERA) {
			copy_m4_m4(obmat, mat);
		}
		else {
			float imat[4][4];

			BKE_tracking_camera_get_reconstructed_interpolate(tracking, object, scene->r.cfra, imat);
			invert_m4(imat);

			mul_m4_m4m4(obmat, cammat, imat);
		}

		while (track) {
			if ((track->flag & TRACK_HAS_BUNDLE) && TRACK_SELECTED(track)) {
				ok = 1;
				mul_v3_m4v3(pos, obmat, track->bundle_pos);
				minmax_v3v3_v3(min, max, pos);
			}

			track = track->next;
		}
	}

	if (ok) {
		mid_v3_v3v3(vec, min, max);
	}
}
void BL_ArmatureConstraint::RestoreTarget()
{
	if (m_constraint && !(m_constraint->flag&CONSTRAINT_OFF) && (!m_blendtarget || m_target)) {
		if (m_blendtarget) {
			copy_m4_m4(m_blendtarget->obmat, m_blendmat);
			if (m_pose)
				m_blendtarget->pose = m_pose;
		}
		if (m_blendsubtarget && m_subtarget) {
			copy_m4_m4(m_blendsubtarget->obmat, m_blendsubmat);
			if (m_subpose)
				m_blendsubtarget->pose = m_subpose;
		}
	}
}
Example #13
0
/* 'rotmat' can be obedit->obmat when uv project is used.
 * 'winx' and 'winy' can be from scene->r.xsch/ysch */ 
UvCameraInfo *project_camera_info(Object *ob, float (*rotmat)[4], float winx, float winy)
{
	UvCameraInfo uci;
	Camera *camera= ob->data;

	uci.do_pano = (camera->flag & CAM_PANORAMA);
	uci.do_persp = (camera->type==CAM_PERSP);

	uci.camangle= lens_to_angle(camera->lens) / 2.0f;
	uci.camsize= uci.do_persp ? tanf(uci.camangle) : camera->ortho_scale;

	/* account for scaled cameras */
	copy_m4_m4(uci.caminv, ob->obmat);
	normalize_m4(uci.caminv);

	if (invert_m4(uci.caminv)) {
		UvCameraInfo *uci_pt;

		/* normal projection */
		if(rotmat) {
			copy_m4_m4(uci.rotmat, rotmat);
			uci.do_rotmat= 1;
		}
		else {
			uci.do_rotmat= 0;
		}

		/* also make aspect ratio adjustment factors */
		if (winx > winy) {
			uci.xasp= 1.0f;
			uci.yasp= winx / winy;
		}
		else {
			uci.xasp= winy / winx;
			uci.yasp= 1.0f;
		}
		
		/* include 0.5f here to move the UVs into the center */
		uci.shiftx = 0.5f - (camera->shiftx * uci.xasp);
		uci.shifty = 0.5f - (camera->shifty * uci.yasp);
		
		uci_pt= MEM_mallocN(sizeof(UvCameraInfo), "UvCameraInfo");
		*uci_pt= uci;
		return uci_pt;
	}

	return NULL;
}
Example #14
0
static void vertex_dupli__mapFunc(void *userData, int index, const float co[3],
                                  const float no_f[3], const short no_s[3])
{
	DupliObject *dob;
	vertexDupliData *vdd= userData;
	float vec[3], q2[4], mat[3][3], tmat[4][4], obmat[4][4];
	int origlay;
	
	mul_v3_m4v3(vec, vdd->pmat, co);
	sub_v3_v3(vec, vdd->pmat[3]);
	add_v3_v3(vec, vdd->obmat[3]);
	
	copy_m4_m4(obmat, vdd->obmat);
	copy_v3_v3(obmat[3], vec);
	
	if (vdd->par->transflag & OB_DUPLIROT) {
		if (no_f) {
			vec[0]= -no_f[0]; vec[1]= -no_f[1]; vec[2]= -no_f[2];
		}
		else if (no_s) {
			vec[0]= -no_s[0]; vec[1]= -no_s[1]; vec[2]= -no_s[2];
		}
		
		vec_to_quat( q2,vec, vdd->ob->trackflag, vdd->ob->upflag);
		
		quat_to_mat3( mat,q2);
		copy_m4_m4(tmat, obmat);
		mul_m4_m4m3(obmat, tmat, mat);
	}

	origlay = vdd->ob->lay;
	
	dob= new_dupli_object(vdd->lb, vdd->ob, obmat, vdd->par->lay, index, OB_DUPLIVERTS, vdd->animated);

	/* restore the original layer so that each dupli will have proper dob->origlay */
	vdd->ob->lay = origlay;

	if (vdd->orco)
		copy_v3_v3(dob->orco, vdd->orco[index]);
	
	if (vdd->ob->transflag & OB_DUPLI) {
		float tmpmat[4][4];
		copy_m4_m4(tmpmat, vdd->ob->obmat);
		copy_m4_m4(vdd->ob->obmat, obmat); /* pretend we are really this mat */
		object_duplilist_recursive((ID *)vdd->id, vdd->scene, vdd->ob, vdd->lb, obmat, vdd->level+1, vdd->animated);
		copy_m4_m4(vdd->ob->obmat, tmpmat);
	}
}
Example #15
0
/* Convert a given matrix from a space to another (using the object and/or a bone as reference). */
static void rna_Object_mat_convert_space(Object *ob,
                                         ReportList *reports,
                                         bPoseChannel *pchan,
                                         float *mat,
                                         float *mat_ret,
                                         int from,
                                         int to)
{
  copy_m4_m4((float(*)[4])mat_ret, (float(*)[4])mat);

  /* Error in case of invalid from/to values when pchan is NULL */
  if (pchan == NULL) {
    if (ELEM(from, CONSTRAINT_SPACE_POSE, CONSTRAINT_SPACE_PARLOCAL)) {
      const char *identifier = NULL;
      RNA_enum_identifier(space_items, from, &identifier);
      BKE_reportf(reports,
                  RPT_ERROR,
                  "'from_space' '%s' is invalid when no pose bone is given!",
                  identifier);
      return;
    }
    if (ELEM(to, CONSTRAINT_SPACE_POSE, CONSTRAINT_SPACE_PARLOCAL)) {
      const char *identifier = NULL;
      RNA_enum_identifier(space_items, to, &identifier);
      BKE_reportf(reports,
                  RPT_ERROR,
                  "'to_space' '%s' is invalid when no pose bone is given!",
                  identifier);
      return;
    }
  }

  BKE_constraint_mat_convertspace(ob, pchan, (float(*)[4])mat_ret, from, to, false);
}
Example #16
0
/* NOTE: based on solve_parenting(), but with the cruft stripped out */
void BKE_object_eval_parent(EvaluationContext *UNUSED(eval_ctx),
                            Scene *scene,
                            Object *ob)
{
	Object *par = ob->parent;

	float totmat[4][4];
	float tmat[4][4];
	float locmat[4][4];

	DEBUG_PRINT("%s on %s\n", __func__, ob->id.name);

	/* get local matrix (but don't calculate it, as that was done already!) */
	// XXX: redundant?
	copy_m4_m4(locmat, ob->obmat);

	/* get parent effect matrix */
	BKE_object_get_parent_matrix(scene, ob, par, totmat);

	/* total */
	mul_m4_m4m4(tmat, totmat, ob->parentinv);
	mul_m4_m4m4(ob->obmat, tmat, locmat);

	/* origin, for help line */
	if ((ob->partype & PARTYPE) == PARSKEL) {
		copy_v3_v3(ob->orig, par->obmat[3]);
	}
	else {
		copy_v3_v3(ob->orig, totmat[3]);
	}
}
void AnimationExporter::calc_ob_mat_at_time(Object *ob, float ctime , float mat[][4])
{
	ListBase *conlist = get_active_constraints(ob);
	bConstraint *con;
	for (con = (bConstraint *)conlist->first; con; con = con->next) {
		ListBase targets = {NULL, NULL};
		
		bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con);
		
		if (cti && cti->get_constraint_targets) {
			bConstraintTarget *ct;
			Object *obtar;
			cti->get_constraint_targets(con, &targets);
			for (ct = (bConstraintTarget *)targets.first; ct; ct = ct->next) {
				obtar = ct->tar;

				if (obtar) {
					BKE_animsys_evaluate_animdata(scene, &obtar->id, obtar->adt, ctime, ADT_RECALC_ANIM);
					BKE_object_where_is_calc_time(scene, obtar, ctime);
				}
			}

			if (cti->flush_constraint_targets)
				cti->flush_constraint_targets(con, &targets, 1);
		}
	}
	BKE_object_where_is_calc_time(scene, ob, ctime);
	copy_m4_m4(mat, ob->obmat);
}
Example #18
0
static DupliObject *new_dupli_object(ListBase *lb, Object *ob, float mat[][4], int lay, int index, int type, int animated)
{
	DupliObject *dob= MEM_callocN(sizeof(DupliObject), "dupliobject");
	
	BLI_addtail(lb, dob);
	dob->ob= ob;
	copy_m4_m4(dob->mat, mat);
	copy_m4_m4(dob->omat, ob->obmat);
	dob->origlay= ob->lay;
	dob->index= index;
	dob->type= type;
	dob->animated= (type == OB_DUPLIGROUP) && animated;
	ob->lay= lay;
	
	return dob;
}
Example #19
0
void TransformReader::get_node_mat(float mat[4][4],
                                   COLLADAFW::Node *node,
                                   std::map<COLLADAFW::UniqueId, Animation> *animation_map,
                                   Object *ob,
                                   float parent_mat[4][4])
{
  float cur[4][4];
  float copy[4][4];

  unit_m4(mat);

  for (unsigned int i = 0; i < node->getTransformations().getCount(); i++) {

    COLLADAFW::Transformation *tm = node->getTransformations()[i];
    COLLADAFW::Transformation::TransformationType type = tm->getTransformationType();

    switch (type) {
      case COLLADAFW::Transformation::MATRIX:
        // When matrix AND Trans/Rot/Scale are defined for a node,
        // then this is considered as redundant information.
        // So if we find a Matrix we use that and return.
        dae_matrix_to_mat4(tm, mat);
        if (parent_mat) {
          mul_m4_m4m4(mat, parent_mat, mat);
        }
        return;
      case COLLADAFW::Transformation::TRANSLATE:
        dae_translate_to_mat4(tm, cur);
        break;
      case COLLADAFW::Transformation::ROTATE:
        dae_rotate_to_mat4(tm, cur);
        break;
      case COLLADAFW::Transformation::SCALE:
        dae_scale_to_mat4(tm, cur);
        break;
      case COLLADAFW::Transformation::LOOKAT:
        fprintf(stderr, "|!     LOOKAT transformations are not supported yet.\n");
        break;
      case COLLADAFW::Transformation::SKEW:
        fprintf(stderr, "|!     SKEW transformations are not supported yet.\n");
        break;
    }

    copy_m4_m4(copy, mat);
    mul_m4_m4m4(mat, copy, cur);

    if (animation_map) {
      // AnimationList that drives this Transformation
      const COLLADAFW::UniqueId &anim_list_id = tm->getAnimationList();

      // store this so later we can link animation data with ob
      Animation anim = {ob, node, tm};
      (*animation_map)[anim_list_id] = anim;
    }
  }

  if (parent_mat) {
    mul_m4_m4m4(mat, parent_mat, mat);
  }
}
BL_SkinDeformer::BL_SkinDeformer(
	BL_DeformableGameObject *gameobj,
	struct Object *bmeshobj_old,	// Blender object that owns the new mesh
	struct Object *bmeshobj_new,	// Blender object that owns the original mesh
	class RAS_MeshObject *mesh,
	bool release_object,
	bool recalc_normal,
	BL_ArmatureObject* arma)	:	
		BL_MeshDeformer(gameobj, bmeshobj_old, mesh),
		m_armobj(arma),
		m_lastArmaUpdate(-1),
		//m_defbase(&bmeshobj_old->defbase),
		m_releaseobject(release_object),
		m_recalcNormal(recalc_normal),
		m_copyNormals(false),
		m_dfnrToPC(NULL)
	{
		// this is needed to ensure correct deformation of mesh:
		// the deformation is done with Blender's armature_deform_verts() function
		// that takes an object as parameter and not a mesh. The object matrice is used
		// in the calculation, so we must use the matrix of the original object to
		// simulate a pure replacement of the mesh.
		copy_m4_m4(m_obmat, bmeshobj_new->obmat);
		m_deformflags = get_deformflags(bmeshobj_new);
	}
Example #21
0
/* unlike VIEW3D_OT_view_selected this is for framing a render and not
 * meant to take into account vertex/bone selection for eg. */
static int view3d_camera_to_view_selected_exec(bContext *C, wmOperator *UNUSED(op))
{
	Scene *scene= CTX_data_scene(C);
	View3D *v3d = CTX_wm_view3d(C);
	Object *camera_ob= v3d->camera;

	float r_co[3]; /* the new location to apply */

	/* this function does all the important stuff */
	if (camera_view_frame_fit_to_scene(scene, v3d, camera_ob, r_co)) {

		ObjectTfmProtectedChannels obtfm;
		float obmat_new[4][4];

		copy_m4_m4(obmat_new, camera_ob->obmat);
		copy_v3_v3(obmat_new[3], r_co);

		/* only touch location */
		object_tfm_protected_backup(camera_ob, &obtfm);
		object_apply_mat4(camera_ob, obmat_new, TRUE, TRUE);
		object_tfm_protected_restore(camera_ob, &obtfm, OB_LOCK_SCALE | OB_LOCK_ROT4D);

		/* notifiers */
		DAG_id_tag_update(&camera_ob->id, OB_RECALC_OB);
		WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, camera_ob);
		return OPERATOR_FINISHED;
	}
	else {
		return OPERATOR_CANCELLED;
	}
}
Example #22
0
static void envmap_transmatrix(float mat[4][4], int part)
{
	float tmat[4][4], eul[3], rotmat[4][4];
	
	eul[0] = eul[1] = eul[2] = 0.0;
	
	if (part == 0) {          /* neg z */
		/* pass */
	}
	else if (part == 1) { /* pos z */
		eul[0] = M_PI;
	}
	else if (part == 2) { /* pos y */
		eul[0] = M_PI / 2.0;
	}
	else if (part == 3) { /* neg x */
		eul[0] = M_PI / 2.0;
		eul[2] = M_PI / 2.0;
	}
	else if (part == 4) { /* neg y */
		eul[0] = M_PI / 2.0;
		eul[2] = M_PI;
	}
	else {              /* pos x */
		eul[0] = M_PI / 2.0;
		eul[2] = -M_PI / 2.0;
	}
	
	copy_m4_m4(tmat, mat);
	eul_to_mat4(rotmat, eul);
	mul_m4_m4m4(mat, tmat, rotmat);
}
Example #23
0
void BKE_object_eval_uber_transform(EvaluationContext *UNUSED(eval_ctx),
                                    Scene *UNUSED(scene),
                                    Object *ob)
{
	/* TODO(sergey): Currently it's a duplicate of logic in BKE_object_handle_update_ex(). */
	// XXX: it's almost redundant now...

	/* Handle proxy copy for target, */
	if (ob->id.lib && ob->proxy_from) {
		if (ob->proxy_from->proxy_group) {
			/* Transform proxy into group space. */
			Object *obg = ob->proxy_from->proxy_group;
			float imat[4][4];
			invert_m4_m4(imat, obg->obmat);
			mul_m4_m4m4(ob->obmat, imat, ob->proxy_from->obmat);
			/* Should always be true. */
			if (obg->dup_group) {
				add_v3_v3(ob->obmat[3], obg->dup_group->dupli_ofs);
			}
		}
		else
			copy_m4_m4(ob->obmat, ob->proxy_from->obmat);
	}

	ob->recalc &= ~(OB_RECALC_OB | OB_RECALC_TIME);
	if (ob->data == NULL) {
		ob->recalc &= ~OB_RECALC_DATA;
	}
}
Example #24
0
/* copy current render */
static Render *envmap_render_copy(Render *re, EnvMap *env)
{
	Render *envre;
	float viewscale;
	int cuberes;
	
	envre = RE_NewRender("Envmap");
	
	env->lastsize = re->r.size;
	cuberes = (env->cuberes * re->r.size) / 100;
	cuberes &= 0xFFFC;
	
	/* this flag has R_ZTRA in it for example */
	envre->flag = re->flag;
	
	/* set up renderdata */
	envre->r = re->r;
	envre->r.mode &= ~(R_BORDER | R_PANORAMA | R_ORTHO | R_MBLUR);
	envre->r.layers.first = envre->r.layers.last = NULL;
	envre->r.filtertype = 0;
	envre->r.tilex = envre->r.xsch / 2;
	envre->r.tiley = envre->r.ysch / 2;
	envre->r.size = 100;
	envre->r.yasp = envre->r.xasp = 1;
	
	RE_InitState(envre, NULL, &envre->r, NULL, cuberes, cuberes, NULL);
	envre->main = re->main;
	envre->scene = re->scene;    /* unsure about this... */
	envre->scene_color_manage = re->scene_color_manage;
	envre->lay = re->lay;

	/* view stuff in env render */
	viewscale = (env->type == ENV_PLANE) ? env->viewscale : 1.0f;
	RE_SetEnvmapCamera(envre, env->object, viewscale, env->clipsta, env->clipend);
	copy_m4_m4(envre->viewmat_orig, re->viewmat_orig);
	
	/* callbacks */
	envre->display_draw = re->display_draw;
	envre->ddh = re->ddh;
	envre->test_break = re->test_break;
	envre->tbh = re->tbh;
	
	/* and for the evil stuff; copy the database... */
	envre->totvlak = re->totvlak;
	envre->totvert = re->totvert;
	envre->tothalo = re->tothalo;
	envre->totstrand = re->totstrand;
	envre->totlamp = re->totlamp;
	envre->sortedhalos = re->sortedhalos;
	envre->lights = re->lights;
	envre->objecttable = re->objecttable;
	envre->customdata_names = re->customdata_names;
	envre->raytree = re->raytree;
	envre->totinstance = re->totinstance;
	envre->instancetable = re->instancetable;
	envre->objectinstance = re->objectinstance;
	envre->qmcsamplers = re->qmcsamplers;
	
	return envre;
}
Example #25
0
void BKE_pose_eval_bone(EvaluationContext *UNUSED(eval_ctx),
                        Scene *scene,
                        Object *ob,
                        bPoseChannel *pchan)
{
	DEG_debug_print_eval_subdata(
	        __func__, ob->id.name, ob, "pchan", pchan->name, pchan);
	BLI_assert(ob->type == OB_ARMATURE);
	bArmature *arm = (bArmature *)ob->data;
	if (arm->edbo || (arm->flag & ARM_RESTPOS)) {
		Bone *bone = pchan->bone;
		if (bone) {
			copy_m4_m4(pchan->pose_mat, bone->arm_mat);
			copy_v3_v3(pchan->pose_head, bone->arm_head);
			copy_v3_v3(pchan->pose_tail, bone->arm_tail);
		}
	}
	else {
		/* TODO(sergey): Currently if there are constraints full transform is being
		 * evaluated in BKE_pose_constraints_evaluate.
		 */
		if (pchan->constraints.first == NULL) {
			if (pchan->flag & POSE_IKTREE || pchan->flag & POSE_IKSPLINE) {
				/* pass */
			}
			else {
				if ((pchan->flag & POSE_DONE) == 0) {
					/* TODO(sergey): Use time source node for time. */
					float ctime = BKE_scene_frame_get(scene); /* not accurate... */
					BKE_pose_where_is_bone(scene, ob, pchan, ctime, 1);
				}
			}
		}
	}
}
void TransformWriter::add_node_transform(COLLADASW::Node& node, float mat[4][4], float parent_mat[4][4])
{
    float loc[3], rot[3], scale[3];
    float local[4][4];

    if (parent_mat) {
        float invpar[4][4];
        invert_m4_m4(invpar, parent_mat);
        mul_m4_m4m4(local, invpar, mat);
    }
    else {
        copy_m4_m4(local, mat);
    }

    double dmat[4][4];
    UnitConverter *converter = new UnitConverter();
    converter->mat4_to_dae_double(dmat, local);

    TransformBase::decompose(local, loc, rot, NULL, scale);

    if (node.getType() == COLLADASW::Node::JOINT) {
        // XXX Why are joints handled differently ?
        node.addMatrix("transform", dmat);
    }
    else {
        add_transform(node, loc, rot, scale);
    }
}
Example #27
0
/* Sync rigid body and object transformations */
void BKE_rigidbody_sync_transforms(RigidBodyWorld *rbw, Object *ob, float ctime)
{
	RigidBodyOb *rbo = ob->rigidbody_object;

	/* keep original transform for kinematic and passive objects */
	if (ELEM(NULL, rbw, rbo) || rbo->flag & RBO_FLAG_KINEMATIC || rbo->type == RBO_TYPE_PASSIVE)
		return;

	/* use rigid body transform after cache start frame if objects is not being transformed */
	if (BKE_rigidbody_check_sim_running(rbw, ctime) && !(ob->flag & SELECT && G.moving & G_TRANSFORM_OBJ)) {
		float mat[4][4], size_mat[4][4], size[3];

		normalize_qt(rbo->orn); // RB_TODO investigate why quaternion isn't normalized at this point
		quat_to_mat4(mat, rbo->orn);
		copy_v3_v3(mat[3], rbo->pos);

		mat4_to_size(size, ob->obmat);
		size_to_mat4(size_mat, size);
		mul_m4_m4m4(mat, mat, size_mat);

		copy_m4_m4(ob->obmat, mat);
	}
	/* otherwise set rigid body transform to current obmat */
	else {
		mat4_to_loc_quat(rbo->pos, rbo->orn, ob->obmat);
	}
}
Example #28
0
/* both poses should be in sync */
bool BKE_pose_copy_result(bPose *to, bPose *from)
{
	bPoseChannel *pchanto, *pchanfrom;
	
	if (to == NULL || from == NULL) {
		printf("Pose copy error, pose to:%p from:%p\n", (void *)to, (void *)from); /* debug temp */
		return false;
	}

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


	for (pchanfrom = from->chanbase.first; pchanfrom; pchanfrom = pchanfrom->next) {
		pchanto = BKE_pose_channel_find_name(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 */
			copy_v3_v3(pchanto->loc, pchanfrom->loc);
			copy_qt_qt(pchanto->quat, pchanfrom->quat);
			copy_v3_v3(pchanto->eul, pchanfrom->eul);
			copy_v3_v3(pchanto->size, pchanfrom->size);
			
			copy_v3_v3(pchanto->pose_head, pchanfrom->pose_head);
			copy_v3_v3(pchanto->pose_tail, pchanfrom->pose_tail);
			
			pchanto->roll1 = pchanfrom->roll1;
			pchanto->roll2 = pchanfrom->roll2;
			pchanto->curveInX = pchanfrom->curveInX;
			pchanto->curveInY = pchanfrom->curveInY;
			pchanto->curveOutX = pchanfrom->curveOutX;
			pchanto->curveOutY = pchanfrom->curveOutY;
			pchanto->scaleIn = pchanfrom->scaleIn;
			pchanto->scaleOut = pchanfrom->scaleOut;
			
			pchanto->rotmode = pchanfrom->rotmode;
			pchanto->flag = pchanfrom->flag;
			pchanto->protectflag = pchanfrom->protectflag;
			pchanto->bboneflag = pchanfrom->bboneflag;
		}
	}
	return true;
}
Example #29
0
/* called from drawview.c, as an extra per-window draw option */
void drawPropCircle(const struct bContext *C, TransInfo *t)
{
  if (t->flag & T_PROP_EDIT) {
    RegionView3D *rv3d = CTX_wm_region_view3d(C);
    float tmat[4][4], imat[4][4];
    int depth_test_enabled;

    if (t->spacetype == SPACE_VIEW3D && rv3d != NULL) {
      copy_m4_m4(tmat, rv3d->viewmat);
      invert_m4_m4(imat, tmat);
    }
    else {
      unit_m4(tmat);
      unit_m4(imat);
    }

    GPU_matrix_push();

    if (t->spacetype == SPACE_VIEW3D) {
      /* pass */
    }
    else if (t->spacetype == SPACE_IMAGE) {
      GPU_matrix_scale_2f(1.0f / t->aspect[0], 1.0f / t->aspect[1]);
    }
    else if (ELEM(t->spacetype, SPACE_GRAPH, SPACE_ACTION)) {
      /* only scale y */
      rcti *mask = &t->ar->v2d.mask;
      rctf *datamask = &t->ar->v2d.cur;
      float xsize = BLI_rctf_size_x(datamask);
      float ysize = BLI_rctf_size_y(datamask);
      float xmask = BLI_rcti_size_x(mask);
      float ymask = BLI_rcti_size_y(mask);
      GPU_matrix_scale_2f(1.0f, (ysize / xsize) * (xmask / ymask));
    }

    depth_test_enabled = GPU_depth_test_enabled();
    if (depth_test_enabled) {
      GPU_depth_test(false);
    }

    uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);

    immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
    immUniformThemeColor(TH_GRID);

    set_inverted_drawing(1);
    imm_drawcircball(t->center_global, t->prop_size, imat, pos);
    set_inverted_drawing(0);

    immUnbindProgram();

    if (depth_test_enabled) {
      GPU_depth_test(true);
    }

    GPU_matrix_pop();
  }
}
Example #30
0
static void font_duplilist(ListBase *lb, Scene *scene, Object *par, int level, int animated)
{
	Object *ob, *obar[256]= {NULL};
	Curve *cu;
	struct chartrans *ct, *chartransdata;
	float vec[3], obmat[4][4], pmat[4][4], fsize, xof, yof;
	int slen, a;
	
	/* simple preventing of too deep nested groups */
	if (level>MAX_DUPLI_RECUR) return;
	
	copy_m4_m4(pmat, par->obmat);
	
	/* in par the family name is stored, use this to find the other objects */
	
	chartransdata= BKE_text_to_curve(G.main, scene, par, FO_DUPLI);
	if (chartransdata==NULL) return;

	cu= par->data;
	slen= strlen(cu->str);
	fsize= cu->fsize;
	xof= cu->xof;
	yof= cu->yof;
	
	ct= chartransdata;
	
	for (a=0; a<slen; a++, ct++) {
		
		ob= find_family_object(obar, cu->family, cu->str[a]);
		if (ob) {
			vec[0]= fsize*(ct->xof - xof);
			vec[1]= fsize*(ct->yof - yof);
			vec[2]= 0.0;
			
			mul_m4_v3(pmat, vec);
			
			copy_m4_m4(obmat, par->obmat);
			copy_v3_v3(obmat[3], vec);
			
			new_dupli_object(lb, ob, obmat, par->lay, a, OB_DUPLIVERTS, animated);
		}
	}
	
	MEM_freeN(chartransdata);
}