Пример #1
0
static int nlaedit_objects_add_exec(bContext *C, wmOperator *UNUSED(op))
{
	bAnimContext ac;
	SpaceNla *snla;
	
	/* get editor data */
	if (ANIM_animdata_get_context(C, &ac) == 0)
		return OPERATOR_CANCELLED;
	
	/* ensure that filters are set so that the effect will be immediately visible */
	snla = (SpaceNla *)ac.sl;
	if (snla && snla->ads) {
		snla->ads->filterflag &= ~ADS_FILTER_NLA_NOACT;
	}
	
	/* operate on selected objects... */	
	CTX_DATA_BEGIN (C, Object *, ob, selected_objects)
	{
		/* ensure that object has AnimData... that's all */
		BKE_animdata_add_id(&ob->id);
	}
Пример #2
0
/* Get (or add relevant data to be able to do so) F-Curve from the driver stack,
 * for the given Animation Data block. This assumes that all the destinations are valid.
 *
 * - add: 0 - don't add anything if not found,
 *        1 - add new Driver FCurve (with keyframes for visual tweaking),
 *        2 - add new Driver FCurve (with generator, for script backwards compatibility)
 *        -1 - add new Driver FCurve without driver stuff (for pasting)
 */
FCurve *verify_driver_fcurve(ID *id, const char rna_path[], const int array_index, short add)
{
  AnimData *adt;
  FCurve *fcu;

  /* sanity checks */
  if (ELEM(NULL, id, rna_path)) {
    return NULL;
  }

  /* init animdata if none available yet */
  adt = BKE_animdata_from_id(id);
  if ((adt == NULL) && (add)) {
    adt = BKE_animdata_add_id(id);
  }
  if (adt == NULL) {
    /* if still none (as not allowed to add, or ID doesn't have animdata for some reason) */
    return NULL;
  }

  /* try to find f-curve matching for this setting
   * - add if not found and allowed to add one
   * TODO: add auto-grouping support? how this works will need to be resolved
   */
  fcu = list_find_fcurve(&adt->drivers, rna_path, array_index);

  if ((fcu == NULL) && (add)) {
    /* use default settings to make a F-Curve */
    fcu = MEM_callocN(sizeof(FCurve), "FCurve");

    fcu->flag = (FCURVE_VISIBLE | FCURVE_SELECTED);
    fcu->auto_smoothing = FCURVE_SMOOTH_CONT_ACCEL;

    /* store path - make copy, and store that */
    fcu->rna_path = BLI_strdup(rna_path);
    fcu->array_index = array_index;

    /* If add is negative, don't init this data yet,
     * since it will be filled in by the pasted driver. */
    if (add > 0) {
      BezTriple *bezt;
      size_t i;

      /* add some new driver data */
      fcu->driver = MEM_callocN(sizeof(ChannelDriver), "ChannelDriver");

      /* F-Modifier or Keyframes? */
      // FIXME: replace these magic numbers with defines
      if (add == 2) {
        /* Python API Backwards compatibility hack:
         * Create FModifier so that old scripts won't break
         * for now before 2.7 series -- (September 4, 2013)
         */
        add_fmodifier(&fcu->modifiers, FMODIFIER_TYPE_GENERATOR, fcu);
      }
      else {
        /* add 2 keyframes so that user has something to work with
         * - These are configured to 0,0 and 1,1 to give a 1-1 mapping
         *   which can be easily tweaked from there.
         */
        insert_vert_fcurve(fcu, 0.0f, 0.0f, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_FAST);
        insert_vert_fcurve(fcu, 1.0f, 1.0f, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_FAST);

        /* configure this curve to extrapolate */
        for (i = 0, bezt = fcu->bezt; (i < fcu->totvert) && bezt; i++, bezt++) {
          bezt->h1 = bezt->h2 = HD_VECT;
        }

        fcu->extend = FCURVE_EXTRAPOLATE_LINEAR;
        calchandles_fcurve(fcu);
      }
    }

    /* just add F-Curve to end of driver list */
    BLI_addtail(&adt->drivers, fcu);
  }

  /* return the F-Curve */
  return fcu;
}
Пример #3
0
static AnimData * rna_ID_animation_data_create(ID *id, Main *bmain)
{
	AnimData *adt = BKE_animdata_add_id(id);
	DAG_relations_tag_update(bmain);
	return adt;
}
Пример #4
0
// this generates ipo curves for position, rotation, allowing to use game physics in animation
void KX_BlenderSceneConverter::WritePhysicsObjectToAnimationIpo(int frameNumber)
{
	KX_SceneList *scenes = m_ketsjiEngine->CurrentScenes();
	int numScenes = scenes->size();
	int i;
	for (i = 0; i < numScenes; i++) {
		KX_Scene *scene = scenes->at(i);
		//PHY_IPhysicsEnvironment* physEnv = scene->GetPhysicsEnvironment();
		CListValue *parentList = scene->GetObjectList();
		int numObjects = parentList->GetCount();
		int g;
		for (g = 0; g < numObjects; g++) {
			KX_GameObject *gameObj = (KX_GameObject *)parentList->GetValue(g);
			Object *blenderObject = gameObj->GetBlenderObject();
			if (blenderObject && blenderObject->parent == NULL && gameObj->IsRecordAnimation()) {
				if (blenderObject->adt == NULL)
					BKE_animdata_add_id(&blenderObject->id);

				if (blenderObject->adt) {
					const MT_Point3 &position = gameObj->NodeGetWorldPosition();
					//const MT_Vector3& scale = gameObj->NodeGetWorldScaling();
					const MT_Matrix3x3 &orn = gameObj->NodeGetWorldOrientation();

					position.getValue(blenderObject->loc);

					float tmat[3][3];
					for (int r = 0; r < 3; r++)
						for (int c = 0; c < 3; c++)
							tmat[r][c] = (float)orn[c][r];

					mat3_to_compatible_eul(blenderObject->rot, blenderObject->rot, tmat);

					insert_keyframe(NULL, &blenderObject->id, NULL, NULL, "location", -1, (float)frameNumber, INSERTKEY_FAST);
					insert_keyframe(NULL, &blenderObject->id, NULL, NULL, "rotation_euler", -1, (float)frameNumber, INSERTKEY_FAST);

#if 0
					const MT_Point3& position = gameObj->NodeGetWorldPosition();
					//const MT_Vector3& scale = gameObj->NodeGetWorldScaling();
					const MT_Matrix3x3& orn = gameObj->NodeGetWorldOrientation();
					
					float eulerAngles[3];
					float eulerAnglesOld[3] = {0.0f, 0.0f, 0.0f};
					float tmat[3][3];
					
					// XXX animato
					Ipo* ipo = blenderObject->ipo;

					//create the curves, if not existing, set linear if new

					IpoCurve *icu_lx = findIpoCurve((IpoCurve *)ipo->curve.first,"LocX");
					if (!icu_lx) {
						icu_lx = verify_ipocurve(&blenderObject->id, ipo->blocktype, NULL, NULL, NULL, OB_LOC_X, 1);
						if (icu_lx) icu_lx->ipo = IPO_LIN;
					}
					IpoCurve *icu_ly = findIpoCurve((IpoCurve *)ipo->curve.first,"LocY");
					if (!icu_ly) {
						icu_ly = verify_ipocurve(&blenderObject->id, ipo->blocktype, NULL, NULL, NULL, OB_LOC_Y, 1);
						if (icu_ly) icu_ly->ipo = IPO_LIN;
					}
					IpoCurve *icu_lz = findIpoCurve((IpoCurve *)ipo->curve.first,"LocZ");
					if (!icu_lz) {
						icu_lz = verify_ipocurve(&blenderObject->id, ipo->blocktype, NULL, NULL, NULL, OB_LOC_Z, 1);
						if (icu_lz) icu_lz->ipo = IPO_LIN;
					}
					IpoCurve *icu_rx = findIpoCurve((IpoCurve *)ipo->curve.first,"RotX");
					if (!icu_rx) {
						icu_rx = verify_ipocurve(&blenderObject->id, ipo->blocktype, NULL, NULL, NULL, OB_ROT_X, 1);
						if (icu_rx) icu_rx->ipo = IPO_LIN;
					}
					IpoCurve *icu_ry = findIpoCurve((IpoCurve *)ipo->curve.first,"RotY");
					if (!icu_ry) {
						icu_ry = verify_ipocurve(&blenderObject->id, ipo->blocktype, NULL, NULL, NULL, OB_ROT_Y, 1);
						if (icu_ry) icu_ry->ipo = IPO_LIN;
					}
					IpoCurve *icu_rz = findIpoCurve((IpoCurve *)ipo->curve.first,"RotZ");
					if (!icu_rz) {
						icu_rz = verify_ipocurve(&blenderObject->id, ipo->blocktype, NULL, NULL, NULL, OB_ROT_Z, 1);
						if (icu_rz) icu_rz->ipo = IPO_LIN;
					}
					
					if (icu_rx) eulerAnglesOld[0] = eval_icu( icu_rx, frameNumber - 1 ) / ((180 / 3.14159265f) / 10);
					if (icu_ry) eulerAnglesOld[1] = eval_icu( icu_ry, frameNumber - 1 ) / ((180 / 3.14159265f) / 10);
					if (icu_rz) eulerAnglesOld[2] = eval_icu( icu_rz, frameNumber - 1 ) / ((180 / 3.14159265f) / 10);
					
					// orn.getValue((float *)tmat); // uses the wrong ordering, cant use this
					for (int r = 0; r < 3; r++)
						for (int c = 0; c < 3; c++)
							tmat[r][c] = orn[c][r];
					
					// mat3_to_eul( eulerAngles,tmat); // better to use Mat3ToCompatibleEul
					mat3_to_compatible_eul( eulerAngles, eulerAnglesOld,tmat);
					
					//eval_icu
					for (int x = 0; x < 3; x++)
						eulerAngles[x] *= (float) ((180 / 3.14159265f) / 10.0);
					
					//fill the curves with data
					if (icu_lx) insert_vert_icu(icu_lx, frameNumber, position.x(), 1);
					if (icu_ly) insert_vert_icu(icu_ly, frameNumber, position.y(), 1);
					if (icu_lz) insert_vert_icu(icu_lz, frameNumber, position.z(), 1);
					if (icu_rx) insert_vert_icu(icu_rx, frameNumber, eulerAngles[0], 1);
					if (icu_ry) insert_vert_icu(icu_ry, frameNumber, eulerAngles[1], 1);
					if (icu_rz) insert_vert_icu(icu_rz, frameNumber, eulerAngles[2], 1);
					
					// Handles are corrected at the end, testhandles_ipocurve isn't needed yet
#endif
				}
			}
		}
	}
}