Example #1
0
/* calculate difference matrix */
void ED_gpencil_parent_location(bGPDlayer *gpl, float diff_mat[4][4])
{
	Object *ob = gpl->parent;

	if (ob == NULL) {
		unit_m4(diff_mat);
		return;
	}
	else {
		if ((gpl->partype == PAROBJECT) || (gpl->partype == PARSKEL)) {
			mul_m4_m4m4(diff_mat, ob->obmat, gpl->inverse);
			return;
		}
		else if (gpl->partype == PARBONE) {
			bPoseChannel *pchan = BKE_pose_channel_find_name(ob->pose, gpl->parsubstr);
			if (pchan) {
				float tmp_mat[4][4];
				mul_m4_m4m4(tmp_mat, ob->obmat, pchan->pose_mat);
				mul_m4_m4m4(diff_mat, tmp_mat, gpl->inverse);
			}
			else {
				mul_m4_m4m4(diff_mat, ob->obmat, gpl->inverse); /* if bone not found use object (armature) */
			}
			return;
		}
		else {
			unit_m4(diff_mat); /* not defined type */
		}
	}
}
Example #2
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();
  }
}
UnitConverter::UnitConverter() : unit(), up_axis(COLLADAFW::FileInfo::Z_UP)
{
	unit_m4(x_up_mat4);
	rotate_m4(x_up_mat4, 'Y', -0.5 * M_PI);

	unit_m4(y_up_mat4);
	rotate_m4(y_up_mat4, 'X', 0.5 * M_PI);

	unit_m4(z_up_mat4);
	unit_m4(scale_mat4);
}
/* 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];
		float center[3];
		int depth_test_enabled;

		UI_ThemeColor(TH_GRID);

		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);
		}

		glPushMatrix();

		copy_v3_v3(center, t->center);

		if ((t->spacetype == SPACE_VIEW3D) && t->obedit) {
			mul_m4_v3(t->obedit->obmat, center); /* because t->center is in local space */
		}
		else if (t->spacetype == SPACE_IMAGE) {
			float aspx, aspy;

			if (t->options & CTX_MASK) {
				/* untested - mask aspect is TODO */
				ED_space_image_get_aspect(t->sa->spacedata.first, &aspx, &aspy);
			}
			else {
				ED_space_image_get_uv_aspect(t->sa->spacedata.first, &aspx, &aspy);
			}
			glScalef(1.0f / aspx, 1.0f / aspy, 1.0);
		}

		depth_test_enabled = glIsEnabled(GL_DEPTH_TEST);
		if (depth_test_enabled)
			glDisable(GL_DEPTH_TEST);

		set_inverted_drawing(1);
		drawcircball(GL_LINE_LOOP, center, t->prop_size, imat);
		set_inverted_drawing(0);

		if (depth_test_enabled)
			glEnable(GL_DEPTH_TEST);

		glPopMatrix();
	}
}
/* 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;

		UI_ThemeColor(TH_GRID);

		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);
		}

		glPushMatrix();

		if (t->spacetype == SPACE_VIEW3D) {
			/* pass */
		}
		else if (t->spacetype == SPACE_IMAGE) {
			glScalef(1.0f / t->aspect[0], 1.0f / t->aspect[1], 1.0f);
		}
		else if (ELEM(t->spacetype, SPACE_IPO, 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);
			glScalef(1.0f, (ysize / xsize) * (xmask / ymask), 1.0f);
		}

		depth_test_enabled = glIsEnabled(GL_DEPTH_TEST);
		if (depth_test_enabled)
			glDisable(GL_DEPTH_TEST);

		set_inverted_drawing(1);
		drawcircball(GL_LINE_LOOP, t->center_global, t->prop_size, imat);
		set_inverted_drawing(0);

		if (depth_test_enabled)
			glEnable(GL_DEPTH_TEST);

		glPopMatrix();
	}
}
Example #6
0
/* returns standard diameter */
static float new_primitive_matrix(bContext *C, float *loc, float *rot, float primmat[][4])
{
	Object *obedit = CTX_data_edit_object(C);
	View3D *v3d = CTX_wm_view3d(C);
	float mat[3][3], rmat[3][3], cmat[3][3], imat[3][3];
	
	unit_m4(primmat);

	eul_to_mat3(rmat, rot);
	invert_m3(rmat);
	
	/* inverse transform for initial rotation and object */
	copy_m3_m4(mat, obedit->obmat);
	mul_m3_m3m3(cmat, rmat, mat);
	invert_m3_m3(imat, cmat);
	copy_m4_m3(primmat, imat);

	/* center */
	copy_v3_v3(primmat[3], loc);
	sub_v3_v3(primmat[3], obedit->obmat[3]);
	invert_m3_m3(imat, mat);
	mul_m3_v3(imat, primmat[3]);

	return v3d ? v3d->grid : 1.0f;
}
Example #7
0
static void rna_Scene_ray_cast(Scene *scene, float ray_start[3], float ray_end[3],
                               int *r_success, Object **r_ob, float r_obmat[16],
                               float r_location[3], float r_normal[3])
{
	float dummy_dist_px = 0;
	float ray_nor[3];
	float ray_dist;

	sub_v3_v3v3(ray_nor, ray_end, ray_start);
	ray_dist = normalize_v3(ray_nor);

	if (snapObjectsRayEx(scene, NULL, NULL, NULL, NULL, SCE_SNAP_MODE_FACE,
	                     r_ob, (float(*)[4])r_obmat,
	                     ray_start, ray_nor, &ray_dist,
	                     NULL, &dummy_dist_px, r_location, r_normal, SNAP_ALL))
	{
		*r_success = true;
	}
	else {
		unit_m4((float(*)[4])r_obmat);
		zero_v3(r_location);
		zero_v3(r_normal);

		*r_success = false;
	}
}
Example #8
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);
  }
}
Example #9
0
/* Init handling for space-conversion function (from passed-in parameters) */
void gp_point_conversion_init(bContext *C, GP_SpaceConversion *r_gsc)
{
	ScrArea *sa = CTX_wm_area(C);
	ARegion *ar = CTX_wm_region(C);
	
	/* zero out the storage (just in case) */
	memset(r_gsc, 0, sizeof(GP_SpaceConversion));
	unit_m4(r_gsc->mat);
	
	/* store settings */
	r_gsc->sa = sa;
	r_gsc->ar = ar;
	r_gsc->v2d = &ar->v2d;
	
	/* init region-specific stuff */
	if (sa->spacetype == SPACE_VIEW3D) {
		wmWindow *win = CTX_wm_window(C);
		Scene *scene = CTX_data_scene(C);
		View3D *v3d = (View3D *)CTX_wm_space_data(C);
		RegionView3D *rv3d = ar->regiondata;
		
		/* init 3d depth buffers */
		view3d_operator_needs_opengl(C);
		
		view3d_region_operator_needs_opengl(win, ar);
		ED_view3d_autodist_init(scene, ar, v3d, 0);
		
		/* for camera view set the subrect */
		if (rv3d->persp == RV3D_CAMOB) {
			ED_view3d_calc_camera_border(scene, ar, v3d, rv3d, &r_gsc->subrect_data, true); /* no shift */
			r_gsc->subrect = &r_gsc->subrect_data;
		}
	}
}
Example #10
0
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 #11
0
static void object_solver_inverted_matrix(Scene *scene, Object *ob, float invmat[4][4])
{
  bool found = false;
  for (bConstraint *con = ob->constraints.first; con != NULL; con = con->next) {
    const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con);
    if (cti == NULL) {
      continue;
    }
    if (cti->type == CONSTRAINT_TYPE_OBJECTSOLVER) {
      bObjectSolverConstraint *data = (bObjectSolverConstraint *)con->data;
      if (!found) {
        Object *cam = data->camera ? data->camera : scene->camera;
        BKE_object_where_is_calc_mat4(cam, invmat);
      }
      mul_m4_m4m4(invmat, invmat, data->invmat);
      found = true;
    }
  }
  if (found) {
    invert_m4(invmat);
  }
  else {
    unit_m4(invmat);
  }
}
Example #12
0
/* (currently used for action constraints and in rebuild_pose) */
bPoseChannel *verify_pose_channel(bPose *pose, const char *name)
{
	bPoseChannel *chan;
	
	if (pose == NULL)
		return NULL;
	
	/* See if this channel exists */
	chan= BLI_findstring(&pose->chanbase, name, offsetof(bPoseChannel, name));
	if(chan) {
		return chan;
	}

	/* If not, create it and add it */
	chan = MEM_callocN(sizeof(bPoseChannel), "verifyPoseChannel");
	
	BLI_strncpy(chan->name, name, sizeof(chan->name));
	/* init vars to prevent math errors */
	unit_qt(chan->quat);
	unit_axis_angle(chan->rotAxis, &chan->rotAngle);
	chan->size[0] = chan->size[1] = chan->size[2] = 1.0f;
	
	chan->limitmin[0]= chan->limitmin[1]= chan->limitmin[2]= -180.0f;
	chan->limitmax[0]= chan->limitmax[1]= chan->limitmax[2]= 180.0f;
	chan->stiffness[0]= chan->stiffness[1]= chan->stiffness[2]= 0.0f;
	chan->ikrotweight = chan->iklinweight = 0.0f;
	unit_m4(chan->constinv);
	
	chan->protectflag = OB_LOCK_ROT4D;	/* lock by components by default */
	
	BLI_addtail(&pose->chanbase, chan);
	free_pose_channels_hash(pose);
	
	return chan;
}
Example #13
0
/**
 * Calculate a rescale factor such that the imported scene's scale
 * is preserved. I.e. 1 meter in the import will also be
 * 1 meter in the current scene.
 * XXX : I am not sure if it is correct to map 1 Blender Unit
 * to 1 Meter for unit type NONE. But it looks reasonable to me.
 */
void bc_match_scale(std::vector<Object *> *objects_done, 
                    Scene &sce,
                    UnitConverter &bc_unit)
{
	Object *ob = NULL;

	PointerRNA scene_ptr, unit_settings;
	PropertyRNA *system_ptr, *scale_ptr;
	RNA_id_pointer_create(&sce.id, &scene_ptr);

	unit_settings = RNA_pointer_get(&scene_ptr, "unit_settings");
	system_ptr = RNA_struct_find_property(&unit_settings, "system");
	scale_ptr = RNA_struct_find_property(&unit_settings, "scale_length");

	int   type  = RNA_property_enum_get(&unit_settings, system_ptr);

	float bl_scale;
	
	switch (type) {
		case USER_UNIT_NONE:
			bl_scale = 1.0; // map 1 Blender unit to 1 Meter
			break;

		case USER_UNIT_METRIC:
			bl_scale = RNA_property_float_get(&unit_settings, scale_ptr);
			break;

		default :
			bl_scale = RNA_property_float_get(&unit_settings, scale_ptr);
			// it looks like the conversion to Imperial is done implicitly.
			// So nothing to do here.
			break;
	}
	
	float scale_conv = bc_unit.getLinearMeter() / bl_scale;

	float rescale[3];
	rescale[0] = rescale[1] = rescale[2] = scale_conv;

	float size_mat4[4][4];

	float axis_mat4[4][4];
	unit_m4(axis_mat4);

	size_to_mat4(size_mat4, rescale);

	for (std::vector<Object *>::iterator it = objects_done->begin();
			it != objects_done->end();
			++it) 
	{
		ob = *it;
		mult_m4_m4m4(ob->obmat, size_mat4, ob->obmat);
		mult_m4_m4m4(ob->obmat, bc_unit.get_rotation(), ob->obmat);
		BKE_object_apply_mat4(ob, ob->obmat, 0, 0);
	}

}
Example #14
0
TexMapping *add_mapping(void)
{
	TexMapping *texmap= MEM_callocN(sizeof(TexMapping), "Tex map");
	
	texmap->size[0]= texmap->size[1]= texmap->size[2]= 1.0f;
	texmap->max[0]= texmap->max[1]= texmap->max[2]= 1.0f;
	unit_m4(texmap->mat);
	
	return texmap;
}
Example #15
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];
		float center[3];

		UI_ThemeColor(TH_GRID);

		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);
		}

		glPushMatrix();

		VECCOPY(center, t->center);

		if((t->spacetype == SPACE_VIEW3D) && t->obedit)
		{
			mul_m4_v3(t->obedit->obmat, center); /* because t->center is in local space */
		}
		else if(t->spacetype == SPACE_IMAGE)
		{
			float aspx, aspy;

			ED_space_image_uv_aspect(t->sa->spacedata.first, &aspx, &aspy);
			glScalef(1.0f/aspx, 1.0f/aspy, 1.0);
		}

		set_inverted_drawing(1);
		drawcircball(GL_LINE_LOOP, center, t->prop_size, imat);
		set_inverted_drawing(0);

		glPopMatrix();
	}
}
Example #16
0
/* Use 2D quad corners to create a matrix that set
 * a [-1..1] quad at the right position. */
static void v2_quad_corners_to_mat4(float corners[4][2], float r_mat[4][4])
{
  unit_m4(r_mat);
  sub_v2_v2v2(r_mat[0], corners[1], corners[0]);
  sub_v2_v2v2(r_mat[1], corners[3], corners[0]);
  mul_v2_fl(r_mat[0], 0.5f);
  mul_v2_fl(r_mat[1], 0.5f);
  copy_v2_v2(r_mat[3], corners[0]);
  add_v2_v2(r_mat[3], r_mat[0]);
  add_v2_v2(r_mat[3], r_mat[1]);
}
Example #17
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);
}
Example #18
0
void TransformReader::dae_translate_to_mat4(COLLADAFW::Transformation *tm, float m[][4])
{
	COLLADAFW::Translate *tra = (COLLADAFW::Translate*)tm;
	COLLADABU::Math::Vector3& t = tra->getTranslation();

	unit_m4(m);

	m[3][0] = (float)t[0];
	m[3][1] = (float)t[1];
	m[3][2] = (float)t[2];
}
Example #19
0
void default_tex_mapping(TexMapping *texmap)
{
	memset(texmap, 0, sizeof(TexMapping));

	texmap->size[0] = texmap->size[1] = texmap->size[2] = 1.0f;
	texmap->max[0] = texmap->max[1] = texmap->max[2] = 1.0f;
	unit_m4(texmap->mat);

	texmap->projx = PROJ_X;
	texmap->projy = PROJ_Y;
	texmap->projz = PROJ_Z;
	texmap->mapping = MTEX_FLAT;
}
/* Get 4x4 transformation matrix which corresponds to
 * stabilization data and used for easy coordinate
 * transformation.
 *
 * NOTE: The reason it is 4x4 matrix is because it's
 *       used for OpenGL drawing directly.
 */
void BKE_tracking_stabilization_data_to_mat4(int width, int height, float aspect,
                                             float translation[2], float scale, float angle,
                                             float mat[4][4])
{
	float translation_mat[4][4], rotation_mat[4][4], scale_mat[4][4],
	      center_mat[4][4], inv_center_mat[4][4],
	      aspect_mat[4][4], inv_aspect_mat[4][4];
	float scale_vector[3] = {scale, scale, scale};

	unit_m4(translation_mat);
	unit_m4(rotation_mat);
	unit_m4(scale_mat);
	unit_m4(center_mat);
	unit_m4(aspect_mat);

	/* aspect ratio correction matrix */
	aspect_mat[0][0] = 1.0f / aspect;
	invert_m4_m4(inv_aspect_mat, aspect_mat);

	/* image center as rotation center
	 *
	 * Rotation matrix is constructing in a way rotation happens around image center,
	 * and it's matter of calculating translation in a way, that applying translation
	 * after rotation would make it so rotation happens around median point of tracks
	 * used for translation stabilization.
	 */
	center_mat[3][0] = (float)width / 2.0f;
	center_mat[3][1] = (float)height / 2.0f;
	invert_m4_m4(inv_center_mat, center_mat);

	size_to_mat4(scale_mat, scale_vector);       /* scale matrix */
	add_v2_v2(translation_mat[3], translation);  /* translation matrix */
	rotate_m4(rotation_mat, 'Z', angle);         /* rotation matrix */

	/* compose transformation matrix */
	mul_serie_m4(mat, translation_mat, center_mat, aspect_mat, rotation_mat, inv_aspect_mat,
	             scale_mat, inv_center_mat, NULL);
}
Example #21
0
void BKE_texture_mapping_default(TexMapping *texmap, int type)
{
	memset(texmap, 0, sizeof(TexMapping));

	texmap->size[0] = texmap->size[1] = texmap->size[2] = 1.0f;
	texmap->max[0] = texmap->max[1] = texmap->max[2] = 1.0f;
	unit_m4(texmap->mat);

	texmap->projx = PROJ_X;
	texmap->projy = PROJ_Y;
	texmap->projz = PROJ_Z;
	texmap->mapping = MTEX_FLAT;
	texmap->type = type;
}
Example #22
0
/* OB_DUPLIGROUP */
static void make_duplis_group(const DupliContext *ctx)
{
	bool for_render = ctx->eval_ctx->for_render;
	Object *ob = ctx->object;
	Group *group;
	GroupObject *go;
	float group_mat[4][4];
	int id;
	bool animated, hide;

	if (ob->dup_group == NULL) return;
	group = ob->dup_group;

	/* combine group offset and obmat */
	unit_m4(group_mat);
	sub_v3_v3(group_mat[3], group->dupli_ofs);
	mul_m4_m4m4(group_mat, ob->obmat, group_mat);
	/* don't access 'ob->obmat' from now on. */

	/* handles animated groups */

	/* we need to check update for objects that are not in scene... */
	if (ctx->do_update) {
		/* note: update is optional because we don't always need object
		 * transformations to be correct. Also fixes bug [#29616]. */
		BKE_group_handle_recalc_and_update(ctx->eval_ctx, ctx->scene, ob, group);
	}

	animated = BKE_group_is_animated(group, ob);

	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) {
			float mat[4][4];

			/* group dupli offset, should apply after everything else */
			mul_m4_m4m4(mat, group_mat, go->ob->obmat);

			/* check the group instance and object layers match, also that the object visible flags are ok. */
			hide = (go->ob->lay & group->layer) == 0 ||
			       (for_render ? go->ob->restrictflag & OB_RESTRICT_RENDER : go->ob->restrictflag & OB_RESTRICT_VIEW);

			make_dupli(ctx, go->ob, mat, id, animated, hide);

			/* recursion */
			make_recursive_duplis(ctx, go->ob, group_mat, id, animated);
		}
	}
}
Example #23
0
void TransformReader::get_node_mat(float mat[4][4], COLLADAFW::Node *node, std::map<COLLADAFW::UniqueId, Animation> *animation_map, Object *ob)
{
	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:
				// XXX why does this return and discard all following transformations?
				dae_matrix_to_mat4(tm, 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:
			case COLLADAFW::Transformation::SKEW:
				fprintf(stderr, "LOOKAT and 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;
		}
	}
}
Example #24
0
static void object_warp_calc_view_matrix(float r_mat_view[4][4], float r_center_view[3],
                                         Object *obedit, float viewmat[4][4], const float center[3],
                                         const float offset_angle)
{
	float mat_offset[4][4];
	float viewmat_roll[4][4];

	/* apply the rotation offset by rolling the view */
	unit_m4(mat_offset);
	rotate_m4(mat_offset, 'Z', offset_angle);
	mul_m4_m4m4(viewmat_roll, mat_offset, viewmat);

	/* apply the view and the object matrix */
	mul_m4_m4m4(r_mat_view, viewmat_roll, obedit->obmat);

	/* get the view-space cursor */
	mul_v3_m4v3(r_center_view, viewmat_roll, center);
}
Example #25
0
/* mostly a copy from convertblender.c */
static void dupli_render_particle_set(Scene *scene, Object *ob, int level, int enable)
{
	/* ugly function, but we need to set particle systems to their render
	 * settings before calling object_duplilist, to get render level duplis */
	Group *group;
	GroupObject *go;
	ParticleSystem *psys;
	DerivedMesh *dm;
	float mat[4][4];

	unit_m4(mat);

	if (level >= MAX_DUPLI_RECUR)
		return;
	
	if (ob->transflag & OB_DUPLIPARTS) {
		for (psys = ob->particlesystem.first; psys; psys = psys->next) {
			if (ELEM(psys->part->ren_as, PART_DRAW_OB, PART_DRAW_GR)) {
				if (enable)
					psys_render_set(ob, psys, mat, mat, 1, 1, 0.f);
				else
					psys_render_restore(ob, psys);
			}
		}

		if (enable) {
			/* this is to make sure we get render level duplis in groups:
			 * the derivedmesh must be created before init_render_mesh,
			 * since object_duplilist does dupliparticles before that */
			dm = mesh_create_derived_render(scene, ob, CD_MASK_BAREMESH | CD_MASK_MLOOPUV | CD_MASK_MLOOPCOL);
			dm->release(dm);

			for (psys = ob->particlesystem.first; psys; psys = psys->next)
				psys_get_modifier(ob, psys)->flag &= ~eParticleSystemFlag_psys_updated;
		}
	}

	if (ob->dup_group == NULL) return;
	group = ob->dup_group;

	for (go = group->gobject.first; go; go = go->next)
		dupli_render_particle_set(scene, go->ob, level + 1, enable);
}
Example #26
0
/* create initial context for root object */
static void init_context(DupliContext *r_ctx, EvaluationContext *eval_ctx, Scene *scene, Object *ob, float space_mat[4][4], bool update)
{
	r_ctx->eval_ctx = eval_ctx;
	r_ctx->scene = scene;
	/* don't allow BKE_object_handle_update for viewport during render, can crash */
	r_ctx->do_update = update && !(G.is_rendering && eval_ctx->mode != DAG_EVAL_RENDER);
	r_ctx->animated = false;
	r_ctx->group = NULL;

	r_ctx->object = ob;
	if (space_mat)
		copy_m4_m4(r_ctx->space_mat, space_mat);
	else
		unit_m4(r_ctx->space_mat);
	r_ctx->lay = ob->lay;
	r_ctx->level = 0;

	r_ctx->gen = get_dupli_generator(r_ctx);

	r_ctx->duplilist = NULL;
}
Example #27
0
void init_tex_mapping(TexMapping *texmap)
{
	float smat[3][3], rmat[3][3], mat[3][3], proj[3][3];

	if (texmap->projx == PROJ_X && texmap->projy == PROJ_Y && texmap->projz == PROJ_Z &&
	    is_zero_v3(texmap->loc) && is_zero_v3(texmap->rot) && is_one_v3(texmap->size))
	{
		unit_m4(texmap->mat);

		texmap->flag |= TEXMAP_UNIT_MATRIX;
	}
	else {
		/* axis projection */
		zero_m3(proj);

		if (texmap->projx != PROJ_N)
			proj[texmap->projx - 1][0] = 1.0f;
		if (texmap->projy != PROJ_N)
			proj[texmap->projy - 1][1] = 1.0f;
		if (texmap->projz != PROJ_N)
			proj[texmap->projz - 1][2] = 1.0f;

		/* scale */
		size_to_mat3(smat, texmap->size);
		
		/* rotation */
		/* TexMapping rotation are now in radians. */
		eul_to_mat3(rmat, texmap->rot);
		
		/* compose it all */
		mul_m3_m3m3(mat, rmat, smat);
		mul_m3_m3m3(mat, proj, mat);
		
		/* translation */
		copy_m4_m3(texmap->mat, mat);
		copy_v3_v3(texmap->mat[3], texmap->loc);

		texmap->flag &= ~TEXMAP_UNIT_MATRIX;
	}
}
Example #28
0
void BKE_lattice_resize(Lattice *lt, int uNew, int vNew, int wNew, Object *ltOb)
{
	BPoint *bp;
	int i, u, v, w;
	float fu, fv, fw, uc, vc, wc, du = 0.0, dv = 0.0, dw = 0.0;
	float *co, (*vertexCos)[3] = NULL;
	
	/* vertex weight groups are just freed all for now */
	if (lt->dvert) {
		free_dverts(lt->dvert, lt->pntsu * lt->pntsv * lt->pntsw);
		lt->dvert = NULL;
	}
	
	while (uNew * vNew * wNew > 32000) {
		if (uNew >= vNew && uNew >= wNew) uNew--;
		else if (vNew >= uNew && vNew >= wNew) vNew--;
		else wNew--;
	}

	vertexCos = MEM_mallocN(sizeof(*vertexCos) * uNew * vNew * wNew, "tmp_vcos");

	calc_lat_fudu(lt->flag, uNew, &fu, &du);
	calc_lat_fudu(lt->flag, vNew, &fv, &dv);
	calc_lat_fudu(lt->flag, wNew, &fw, &dw);

	/* If old size is different then resolution changed in interface,
	 * try to do clever reinit of points. Pretty simply idea, we just
	 * deform new verts by old lattice, but scaling them to match old
	 * size first.
	 */
	if (ltOb) {
		if (uNew != 1 && lt->pntsu != 1) {
			fu = lt->fu;
			du = (lt->pntsu - 1) * lt->du / (uNew - 1);
		}

		if (vNew != 1 && lt->pntsv != 1) {
			fv = lt->fv;
			dv = (lt->pntsv - 1) * lt->dv / (vNew - 1);
		}

		if (wNew != 1 && lt->pntsw != 1) {
			fw = lt->fw;
			dw = (lt->pntsw - 1) * lt->dw / (wNew - 1);
		}
	}

	co = vertexCos[0];
	for (w = 0, wc = fw; w < wNew; w++, wc += dw) {
		for (v = 0, vc = fv; v < vNew; v++, vc += dv) {
			for (u = 0, uc = fu; u < uNew; u++, co += 3, uc += du) {
				co[0] = uc;
				co[1] = vc;
				co[2] = wc;
			}
		}
	}
	
	if (ltOb) {
		float mat[4][4];
		int typeu = lt->typeu, typev = lt->typev, typew = lt->typew;

		/* works best if we force to linear type (endpoints match) */
		lt->typeu = lt->typev = lt->typew = KEY_LINEAR;

		/* prevent using deformed locations */
		BKE_displist_free(&ltOb->disp);

		copy_m4_m4(mat, ltOb->obmat);
		unit_m4(ltOb->obmat);
		lattice_deform_verts(ltOb, NULL, NULL, vertexCos, uNew * vNew * wNew, NULL, 1.0f);
		copy_m4_m4(ltOb->obmat, mat);

		lt->typeu = typeu;
		lt->typev = typev;
		lt->typew = typew;
	}

	lt->fu = fu;
	lt->fv = fv;
	lt->fw = fw;
	lt->du = du;
	lt->dv = dv;
	lt->dw = dw;

	lt->pntsu = uNew;
	lt->pntsv = vNew;
	lt->pntsw = wNew;

	MEM_freeN(lt->def);
	lt->def = MEM_callocN(lt->pntsu * lt->pntsv * lt->pntsw * sizeof(BPoint), "lattice bp");
	
	bp = lt->def;
	
	for (i = 0; i < lt->pntsu * lt->pntsv * lt->pntsw; i++, bp++) {
		copy_v3_v3(bp->vec, vertexCos[i]);
	}

	MEM_freeN(vertexCos);
}
Example #29
0
static void make_duplis_font(const DupliContext *ctx)
{
	Object *par = ctx->object;
	GHash *family_gh;
	Object *ob;
	Curve *cu;
	struct CharTrans *ct, *chartransdata = NULL;
	float vec[3], obmat[4][4], pmat[4][4], fsize, xof, yof;
	int text_len, a;
	size_t family_len;
	const wchar_t *text = NULL;
	bool text_free = false;

	/* font dupliverts not supported inside groups */
	if (ctx->group)
		return;

	copy_m4_m4(pmat, par->obmat);

	/* in par the family name is stored, use this to find the other objects */

	BKE_vfont_to_curve_ex(G.main, par, FO_DUPLI, NULL,
	                      &text, &text_len, &text_free, &chartransdata);

	if (text == NULL || chartransdata == NULL) {
		return;
	}

	cu = par->data;
	fsize = cu->fsize;
	xof = cu->xof;
	yof = cu->yof;

	ct = chartransdata;

	/* cache result */
	family_len = strlen(cu->family);
	family_gh = BLI_ghash_int_new_ex(__func__, 256);

	/* advance matching BLI_strncpy_wchar_from_utf8 */
	for (a = 0; a < text_len; a++, ct++) {

		ob = find_family_object(cu->family, family_len, (unsigned int)text[a], family_gh);
		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);

			if (UNLIKELY(ct->rot != 0.0f)) {
				float rmat[4][4];

				zero_v3(obmat[3]);
				unit_m4(rmat);
				rotate_m4(rmat, 'Z', -ct->rot);
				mul_m4_m4m4(obmat, obmat, rmat);
			}

			copy_v3_v3(obmat[3], vec);

			make_dupli(ctx, ob, obmat, a, false, false);
		}
	}

	if (text_free) {
		MEM_freeN((void *)text);
	}

	BLI_ghash_free(family_gh, NULL, NULL);

	MEM_freeN(chartransdata);
}
Example #30
0
/* OB_DUPLIGROUP */
static void make_duplis_group(const DupliContext *ctx)
{
	bool for_render = (ctx->eval_ctx->mode == DAG_EVAL_RENDER);
	Object *ob = ctx->object;
	Group *group;
	GroupObject *go;
	float group_mat[4][4];
	int id;
	bool animated, hide;

	if (ob->dup_group == NULL) return;
	group = ob->dup_group;

	/* combine group offset and obmat */
	unit_m4(group_mat);
	sub_v3_v3(group_mat[3], group->dupli_ofs);
	mul_m4_m4m4(group_mat, ob->obmat, group_mat);
	/* don't access 'ob->obmat' from now on. */

	/* handles animated groups */

	/* we need to check update for objects that are not in scene... */
	if (ctx->do_update) {
		/* note: update is optional because we don't always need object
		 * transformations to be correct. Also fixes bug [#29616]. */
		BKE_group_handle_recalc_and_update(ctx->eval_ctx, ctx->scene, ob, group);
	}

	animated = BKE_group_is_animated(group, ob);

	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) {
			float mat[4][4];

			/* Special case for instancing dupli-groups, see: T40051
			 * this object may be instanced via dupli-verts/faces, in this case we don't want to render
			 * (blender convention), but _do_ show in the viewport.
			 *
			 * Regular objects work fine but not if we're instancing dupli-groups,
			 * because the rules for rendering aren't applied to objects they instance.
			 * We could recursively pass down the 'hide' flag instead, but that seems unnecessary.
			 */
			if (for_render && go->ob->parent && go->ob->parent->transflag & (OB_DUPLIVERTS | OB_DUPLIFACES)) {
				continue;
			}

			/* group dupli offset, should apply after everything else */
			mul_m4_m4m4(mat, group_mat, go->ob->obmat);

			/* check the group instance and object layers match, also that the object visible flags are ok. */
			hide = (go->ob->lay & group->layer) == 0 ||
			       (for_render ? go->ob->restrictflag & OB_RESTRICT_RENDER : go->ob->restrictflag & OB_RESTRICT_VIEW);

			make_dupli(ctx, go->ob, mat, id, animated, hide);

			/* recursion */
			make_recursive_duplis(ctx, go->ob, group_mat, id, animated);
		}
	}
}