Exemplo n.º 1
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);
	}
}
Exemplo n.º 2
0
static void face_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, float par_space_mat[][4], int level, int animated)
{
	Object *ob, *ob_iter;
	Base *base = NULL;
	DupliObject *dob;
	DerivedMesh *dm;
	Mesh *me= par->data;
	MLoopUV *mloopuv;
	MPoly *mpoly, *mp;
	MLoop *mloop;
	MVert *mvert;
	float pmat[4][4], imat[3][3], (*orco)[3] = NULL, w;
	int lay, oblay, totface, a;
	Scene *sce = NULL;
	Group *group = NULL;
	GroupObject *go = NULL;
	BMEditMesh *em;
	float ob__obmat[4][4]; /* needed for groups where the object matrix needs to be modified */
	
	/* simple preventing of too deep nested groups */
	if (level>MAX_DUPLI_RECUR) return;
	
	copy_m4_m4(pmat, par->obmat);
	em = me->edit_btmesh;

	if (em) {
		dm= editbmesh_get_derived_cage(scene, par, em, CD_MASK_BAREMESH);
	}
	else {
		dm = mesh_get_derived_deform(scene, par, CD_MASK_BAREMESH);
	}

	totface= dm->getNumPolys(dm);
	mpoly= dm->getPolyArray(dm);
	mloop= dm->getLoopArray(dm);
	mvert= dm->getVertArray(dm);

	if (G.rendering) {

		orco= (float(*)[3])get_mesh_orco_verts(par);
		transform_mesh_orco_verts(me, orco, me->totvert, 0);
		mloopuv= me->mloopuv;
	}
	else {
		orco= NULL;
		mloopuv= NULL;
	}
	
	/* having to loop on scene OR group objects is NOT FUN */
	if (GS(id->name) == ID_SCE) {
		sce = (Scene *)id;
		lay= sce->lay;
		base= sce->base.first;
	}
	else {
		group = (Group *)id;
		lay= group->layer;
		go = group->gobject.first;
	}
	
	/* Start looping on Scene OR Group objects */
	while (base || go) { 
		if (sce) {
			ob_iter= base->object;
			oblay = base->lay;
		}
		else {
			ob_iter= go->ob;
			oblay = ob_iter->lay;
		}
		
		if (lay & oblay && scene->obedit!=ob_iter) {
			ob=ob_iter->parent;
			while (ob) {
				if (ob==par) {
					ob = ob_iter;
	/* End Scene/Group object loop, below is generic */
					
					/* par_space_mat - only used for groups so we can modify the space dupli's are in
					 * when par_space_mat is NULL ob->obmat can be used instead of ob__obmat
					 */
					if (par_space_mat)
						mult_m4_m4m4(ob__obmat, par_space_mat, ob->obmat);
					else
						copy_m4_m4(ob__obmat, ob->obmat);
					
					copy_m3_m4(imat, ob->parentinv);
						
					/* mballs have a different dupli handling */
					if (ob->type!=OB_MBALL) ob->flag |= OB_DONE;	/* doesnt render */

					for (a=0, mp= mpoly; a<totface; a++, mp++) {
						int mv1;
						int mv2;
						int mv3;
						/* int mv4; */ /* UNUSED */
						float *v1;
						float *v2;
						float *v3;
						/* float *v4; */ /* UNUSED */
						float cent[3], quat[4], mat[3][3], mat3[3][3], tmat[4][4], obmat[4][4];
						MLoop *loopstart= mloop + mp->loopstart;

						if (mp->totloop < 3) {
							/* highly unlikely but to be safe */
							continue;
						}
						else {
							v1= mvert[(mv1= loopstart[0].v)].co;
							v2= mvert[(mv2= loopstart[1].v)].co;
							v3= mvert[(mv3= loopstart[2].v)].co;
#if 0
							if (mp->totloop > 3) {
								v4= mvert[(mv4= loopstart[3].v)].co;
							}
#endif
						}

						/* translation */
						mesh_calc_poly_center(mp, loopstart, mvert, cent);

						mul_m4_v3(pmat, cent);
						
						sub_v3_v3v3(cent, cent, pmat[3]);
						add_v3_v3(cent, ob__obmat[3]);
						
						copy_m4_m4(obmat, ob__obmat);
						
						copy_v3_v3(obmat[3], cent);
						
						/* rotation */
						tri_to_quat( quat,v1, v2, v3);
						quat_to_mat3( mat,quat);
						
						/* scale */
						if (par->transflag & OB_DUPLIFACES_SCALE) {
							float size= mesh_calc_poly_area(mp, loopstart, mvert, NULL);
							size= sqrtf(size) * par->dupfacesca;
							mul_m3_fl(mat, size);
						}
						
						copy_m3_m3(mat3, mat);
						mul_m3_m3m3(mat, imat, mat3);
						
						copy_m4_m4(tmat, obmat);
						mul_m4_m4m3(obmat, tmat, mat);
						
						dob= new_dupli_object(lb, ob, obmat, par->lay, a, OB_DUPLIFACES, animated);
						if (G.rendering) {
							w= 1.0f / (float)mp->totloop;

							if (orco) {
								int j;
								for (j = 0; j < mpoly->totloop; j++) {
									madd_v3_v3fl(dob->orco, orco[loopstart[j].v], w);
								}
							}

							if (mloopuv) {
								int j;
								for (j = 0; j < mpoly->totloop; j++) {
									madd_v2_v2fl(dob->orco, mloopuv[loopstart[j].v].uv, w);
								}
							}
						}
						
						if (ob->transflag & OB_DUPLI) {
							float tmpmat[4][4];
							copy_m4_m4(tmpmat, ob->obmat);
							copy_m4_m4(ob->obmat, obmat); /* pretend we are really this mat */
							object_duplilist_recursive((ID *)id, scene, ob, lb, ob->obmat, level+1, animated);
							copy_m4_m4(ob->obmat, tmpmat);
						}
					}
					
					break;
				}
				ob= ob->parent;
			}
		}
		if (sce)	base= base->next;	/* scene loop */
		else		go= go->next;		/* group loop */
	}

	if (orco)
		MEM_freeN(orco);
	
	dm->release(dm);
}
Exemplo n.º 3
0
static void set_axis(Scene *scene,
                     Object *ob,
                     MovieClip *clip,
                     MovieTrackingObject *tracking_object,
                     MovieTrackingTrack *track,
                     char axis)
{
  Object *camera = get_camera_with_movieclip(scene, clip);
  const bool is_camera = (tracking_object->flag & TRACKING_OBJECT_CAMERA) != 0;
  bool flip = false;
  float mat[4][4], vec[3], obmat[4][4], dvec[3];

  BKE_object_to_mat4(ob, obmat);

  BKE_tracking_get_camera_object_matrix(scene, camera, mat);
  mul_v3_m4v3(vec, mat, track->bundle_pos);
  copy_v3_v3(dvec, vec);

  if (!is_camera) {
    float imat[4][4];

    object_solver_inverted_matrix(scene, ob, imat);
    mul_v3_m4v3(vec, imat, vec);

    invert_m4_m4(imat, obmat);
    mul_v3_m4v3(dvec, imat, vec);

    sub_v3_v3(vec, obmat[3]);
  }

  if (len_squared_v2(vec) < (1e-3f * 1e-3f)) {
    return;
  }

  unit_m4(mat);

  if (axis == 'X') {
    if (fabsf(dvec[1]) < 1e-3f) {
      flip = true;

      mat[0][0] = -1.0f;
      mat[0][1] = 0.0f;
      mat[0][2] = 0.0f;
      mat[1][0] = 0.0f;
      mat[1][1] = -1.0f;
      mat[1][2] = 0.0f;
      mat[2][0] = 0.0f;
      mat[2][1] = 0.0f;
      mat[2][2] = 1.0f;
    }
    else {
      copy_v3_v3(mat[0], vec);

      if (is_camera || fabsf(vec[2]) < 1e-3f) {
        mat[0][2] = 0.0f;
        mat[2][0] = 0.0f;
        mat[2][1] = 0.0f;
        mat[2][2] = 1.0f;
        cross_v3_v3v3(mat[1], mat[2], mat[0]);
      }
      else {
        vec[2] = 0.0f;

        cross_v3_v3v3(mat[1], mat[0], vec);
        cross_v3_v3v3(mat[2], mat[0], mat[1]);
      }
    }
  }
  else {
    if (fabsf(dvec[0]) < 1e-3f) {
      flip = true;

      mat[0][0] = -1.0f;
      mat[0][1] = 0.0f;
      mat[0][2] = 0.0f;
      mat[1][0] = 0.0f;
      mat[1][1] = -1.0f;
      mat[1][2] = 0.0f;
      mat[2][0] = 0.0f;
      mat[2][1] = 0.0f;
      mat[2][2] = 1.0f;
    }
    else {
      copy_v3_v3(mat[1], vec);

      if (is_camera || fabsf(vec[2]) < 1e-3f) {
        mat[1][2] = 0.0f;
        mat[2][0] = 0.0f;
        mat[2][1] = 0.0f;
        mat[2][2] = 1.0f;
        cross_v3_v3v3(mat[0], mat[1], mat[2]);
      }
      else {
        vec[2] = 0.0f;

        cross_v3_v3v3(mat[0], vec, mat[1]);
        cross_v3_v3v3(mat[2], mat[0], mat[1]);
      }
    }
  }

  normalize_v3(mat[0]);
  normalize_v3(mat[1]);
  normalize_v3(mat[2]);

  if (is_camera) {
    invert_m4(mat);

    mul_m4_m4m4(mat, mat, obmat);
  }
  else {
    if (!flip) {
      float lmat[4][4], ilmat[4][4], rmat[3][3];

      BKE_object_rot_to_mat3(ob, rmat, true);
      invert_m3(rmat);
      mul_m4_m4m3(mat, mat, rmat);

      unit_m4(lmat);
      copy_v3_v3(lmat[3], obmat[3]);
      invert_m4_m4(ilmat, lmat);

      mul_m4_series(mat, lmat, mat, ilmat, obmat);
    }
    else {
      mul_m4_m4m4(mat, obmat, mat);
    }
  }

  BKE_object_apply_mat4(ob, mat, 0, 0);
}