diff --git a/source/blender/collada/DocumentImporter.cpp b/source/blender/collada/DocumentImporter.cpp index eb2122dd382..256589faa18 100644 --- a/source/blender/collada/DocumentImporter.cpp +++ b/source/blender/collada/DocumentImporter.cpp @@ -1,36 +1,32 @@ -#include "COLLADAFWStableHeaders.h" +#include "COLLADAFWRoot.h" #include "COLLADAFWIWriter.h" -#include "COLLADAFWRoot.h" -#include "COLLADAFWNode.h" -#include "COLLADAFWVisualScene.h" -#include "COLLADAFWInstanceGeometry.h" -#include "COLLADAFWFileInfo.h" -#include "COLLADAFWRoot.h" -#include "COLLADAFWLight.h" -#include "COLLADAFWImage.h" -#include "COLLADAFWMaterial.h" -#include "COLLADAFWEffect.h" -#include "COLLADAFWGeometry.h" -#include "COLLADAFWMesh.h" -#include "COLLADAFWMeshPrimitive.h" -#include "COLLADAFWMeshVertexData.h" -#include "COLLADAFWFloatOrDoubleArray.h" -#include "COLLADAFWArrayPrimitiveType.h" -#include "COLLADAFWIndexList.h" -#include "COLLADAFWMeshPrimitiveWithFaceVertexCount.h" -#include "COLLADAFWPolygons.h" -#include "COLLADAFWTransformation.h" -#include "COLLADAFWTranslate.h" -#include "COLLADAFWScale.h" -#include "COLLADAFWRotate.h" +#include "COLLADAFWStableHeaders.h" #include "COLLADAFWAnimationCurve.h" #include "COLLADAFWAnimationList.h" -#include "COLLADAFWSkinController.h" -#include "COLLADAFWColorOrTexture.h" -#include "COLLADAFWSampler.h" -#include "COLLADAFWTypes.h" #include "COLLADAFWCamera.h" +#include "COLLADAFWColorOrTexture.h" +#include "COLLADAFWEffect.h" +#include "COLLADAFWFloatOrDoubleArray.h" +#include "COLLADAFWGeometry.h" +#include "COLLADAFWImage.h" +#include "COLLADAFWIndexList.h" +#include "COLLADAFWInstanceGeometry.h" #include "COLLADAFWLight.h" +#include "COLLADAFWMaterial.h" +#include "COLLADAFWMesh.h" +#include "COLLADAFWMeshPrimitiveWithFaceVertexCount.h" +#include "COLLADAFWNode.h" +#include "COLLADAFWPolygons.h" +#include "COLLADAFWRotate.h" +#include "COLLADAFWSampler.h" +#include "COLLADAFWScale.h" +#include "COLLADAFWSkinController.h" +#include "COLLADAFWTransformation.h" +#include "COLLADAFWTranslate.h" +#include "COLLADAFWTypes.h" +#include "COLLADAFWVisualScene.h" +#include "COLLADAFWFileInfo.h" +#include "COLLADAFWArrayPrimitiveType.h" #include "COLLADASaxFWLLoader.h" @@ -41,6 +37,8 @@ extern "C" #include "BKE_customdata.h" #include "BKE_library.h" #include "BKE_texture.h" +#include "ED_keyframing.h" +#include "BKE_fcurve.h" } #include "DNA_lamp_types.h" #include "BKE_mesh.h" @@ -51,15 +49,20 @@ extern "C" #include "BKE_material.h" #include "BLI_arithb.h" +#include "BLI_listbase.h" +#include "BLI_string.h" +#include "DNA_anim_types.h" +#include "DNA_curve_types.h" #include "DNA_texture_types.h" #include "DNA_camera_types.h" #include "DNA_object_types.h" #include "DNA_meshdata_types.h" #include "DNA_mesh_types.h" #include "DNA_material_types.h" +#include "DNA_scene_types.h" -//#include "DNA_texture_types.h" +#include "MEM_guardedalloc.h" #include "DocumentImporter.h" @@ -146,7 +149,8 @@ private: typedef std::map > MaterialIdPrimitiveArrayMap; // amazing name! std::map geom_uid_mat_mapping_map; - + // maps for animation + std::map > uid_fcurve_map; struct AnimatedTransform { Object *ob; // COLLADAFW::Node *node; @@ -196,10 +200,6 @@ private: void getUV(int uv_set_index, int uv_index[2], float *uv) { - //int uv_coords_index = mVData->getInputInfosArray()[uv_set_index]->getCount() * uv_set_index + uv_index * 2; - // int uv_coords_index = uv_index * 2; - //int uv_coords_index = mVData->getLength(uv_set_index) * uv_set_index + uv_index * 2; - switch(mVData->getType()) { case COLLADAFW::MeshVertexData::DATA_TYPE_FLOAT: { @@ -1049,8 +1049,8 @@ public: @return The writer should return true, if writing succeeded, false otherwise.*/ virtual bool writeCamera( const COLLADAFW::Camera* camera ) { - //std::string name = camera->getOriginalId(); - Camera *cam = (Camera*)add_camera("my_camera"); + std::string name = camera->getOriginalId(); + Camera *cam = (Camera*)add_camera((char*)name.c_str()); if (cam != NULL) this->uid_camera_map[camera->getUniqueId()] = cam; else fprintf(stderr, "Cannot create camera. \n"); @@ -1076,8 +1076,8 @@ public: @return The writer should return true, if writing succeeded, false otherwise.*/ virtual bool writeLight( const COLLADAFW::Light* light ) { - //std::string name = light->getOriginalId(); - Lamp *lamp = (Lamp*)add_lamp("my_lamp"); + std::string name = light->getOriginalId(); + Lamp *lamp = (Lamp*)add_lamp((char*)name.c_str()); COLLADAFW::Light::LightType type = light->getLightType(); switch(type) { case COLLADAFW::Light::AMBIENT_LIGHT: @@ -1114,13 +1114,112 @@ public: // XXX import light options*/ return true; } - + + float get_float(COLLADAFW::FloatOrDoubleArray array, int i) + { + switch(array.getType()) { + case COLLADAFW::MeshVertexData::DATA_TYPE_FLOAT: + { + COLLADAFW::ArrayPrimitiveType *values = array.getFloatValues(); + return (*values)[i]; + } + case COLLADAFW::MeshVertexData::DATA_TYPE_DOUBLE: + { + COLLADAFW::ArrayPrimitiveType *values = array.getDoubleValues(); + return (float)(*values)[i]; + } + } + } + + void write_curves(const COLLADAFW::Animation* anim, + COLLADAFW::AnimationCurve *curve, + COLLADAFW::FloatOrDoubleArray input, + COLLADAFW::FloatOrDoubleArray output, + COLLADAFW::FloatOrDoubleArray intan, + COLLADAFW::FloatOrDoubleArray outtan, size_t dim, float fps) + { + int i; + if (dim == 1) { + // create fcurve + FCurve *fcu = (FCurve*)MEM_callocN(sizeof(FCurve), "FCurve"); + if (!fcu) { + fprintf(stderr, "Cannot create fcurve. \n"); + return; + } + char *path = "location"; + fcu->flag = (FCURVE_VISIBLE|FCURVE_AUTO_HANDLES|FCURVE_SELECTED); + fcu->rna_path = BLI_strdupn(path, strlen(path)); + fcu->array_index = 0; + fcu->totvert = curve->getKeyCount(); + + // create beztriple for each key + for (i = 0; i < curve->getKeyCount(); i++) { + BezTriple bez; + memset(&bez, 0, sizeof(BezTriple)); + // intangent + bez.vec[0][0] = get_float(intan, i + i) * fps; + bez.vec[0][1] = get_float(intan, i + i + 1); + // input, output + bez.vec[1][0] = get_float(input, i) * fps; + bez.vec[1][1] = get_float(output, i); + // outtangent + bez.vec[2][0] = get_float(outtan, i + i) * fps; + bez.vec[2][1] = get_float(outtan, i + i + 1); + bez.ipo = U.ipo_new; /* use default interpolation mode here... */ + bez.f1 = bez.f2 = bez.f3 = SELECT; + bez.h1 = bez.h2 = HD_AUTO; + insert_bezt_fcurve(fcu, &bez); + calchandles_fcurve(fcu); + } + // map fcurve to animation's UID + this->uid_fcurve_map[anim->getUniqueId()].push_back(fcu); + } + else if(dim == 3) { + for (i = 0; i < dim; i++ ) { + // create fcurve + FCurve *fcu = (FCurve*)MEM_callocN(sizeof(FCurve), "FCurve"); + if (!fcu) { + fprintf(stderr, "Cannot create fcurve. \n"); + continue; + } + fcu->flag = (FCURVE_VISIBLE|FCURVE_AUTO_HANDLES|FCURVE_SELECTED); + fcu->rna_path = "location"; + fcu->array_index = 0; + fcu->totvert = curve->getKeyCount(); + + // create beztriple for each key + for (int j = 0; j < curve->getKeyCount(); j++) { + BezTriple bez; + memset(&bez, 0, sizeof(BezTriple)); + // intangent + bez.vec[0][0] = get_float(intan, j * 6 + i + i) * fps; + bez.vec[0][1] = get_float(intan, j * 6 + i + i + 1); + // input, output + bez.vec[1][0] = get_float(input, j) * fps; + bez.vec[1][1] = get_float(output, j * 3 + i); + // outtangent + bez.vec[2][0] = get_float(outtan, j * 6 + i + i) * fps; + bez.vec[2][1] = get_float(outtan, j * 6 + i + i + 1); + bez.ipo = U.ipo_new; /* use default interpolation mode here... */ + bez.f1 = bez.f2 = bez.f3 = SELECT; + bez.h1 = bez.h2 = HD_AUTO; + insert_bezt_fcurve(fcu, &bez); + calchandles_fcurve(fcu); + } + // map fcurve to animation's UID + this->uid_fcurve_map[anim->getUniqueId()].push_back(fcu); + + } + } + } + // this function is called only for animations that pass COLLADAFW::validate virtual bool writeAnimation( const COLLADAFW::Animation* anim ) { if (anim->getAnimationType() == COLLADAFW::Animation::ANIMATION_CURVE) { COLLADAFW::AnimationCurve *curve = (COLLADAFW::AnimationCurve*)anim; - + Scene *scene = CTX_data_scene(mContext); + float fps = (float)FPS; // I wonder how do we use this (Arystan) size_t dim = curve->getOutDimension(); @@ -1130,18 +1229,23 @@ public: fprintf(stderr, "Inputs physical dimension is not time. \n"); return true; } - + COLLADAFW::FloatOrDoubleArray input = curve->getInputValues(); + COLLADAFW::FloatOrDoubleArray output = curve->getOutputValues(); + COLLADAFW::FloatOrDoubleArray intan = curve->getInTangentValues(); + COLLADAFW::FloatOrDoubleArray outtan = curve->getOutTangentValues(); // a curve can have mixed interpolation type, // in this case curve->getInterpolationTypes returns a list of interpolation types per key COLLADAFW::AnimationCurve::InterpolationType interp = curve->getInterpolationType(); - + if (interp != COLLADAFW::AnimationCurve::INTERPOLATION_MIXED) { switch (interp) { case COLLADAFW::AnimationCurve::INTERPOLATION_LINEAR: // support this + write_curves(anim, curve, input, output, intan, outtan, dim, fps); break; case COLLADAFW::AnimationCurve::INTERPOLATION_BEZIER: // and this + write_curves(anim, curve, input, output, intan, outtan, dim, fps); break; case COLLADAFW::AnimationCurve::INTERPOLATION_CARDINAL: case COLLADAFW::AnimationCurve::INTERPOLATION_HERMITE: @@ -1162,40 +1266,90 @@ public: return true; } - - // called on post-process stage after writeVisualScenes - virtual bool writeAnimationList( const COLLADAFW::AnimationList* anim ) + + void change_fcurve(Object *ob, const COLLADAFW::UniqueId& anim_id, char *rna_path, int array_index) { - const COLLADAFW::UniqueId& anim_id = anim->getUniqueId(); + if (uid_fcurve_map.find(anim_id) == uid_fcurve_map.end()) { + fprintf(stderr, "Cannot find fcurves by UID.\n"); + return; + } + ID *id = &ob->id; + bAction *act; + if (!ob->adt || !ob->adt->action) + act = verify_adt_action(id, 1); + else + act = verify_adt_action(id, 0); + if (!ob->adt || !ob->adt->action) { + fprintf(stderr, "Cannot create anim data or action for this object. \n"); + return; + } + FCurve *fcu; + std::vector fcurves = uid_fcurve_map[anim_id]; + std::vector::iterator it; + int i = 0; + for (it = fcurves.begin(); it != fcurves.end(); it++) { + fcu = *it; + strcpy(fcu->rna_path, rna_path); + if (array_index == -1) + fcu->array_index = i; + else + fcu->array_index = array_index; + // convert degrees to radians for rotation + if (strcmp(rna_path, "rotation") == 0) { + for(int j = 0; j < fcu->totvert; j++) { + float rot_intan = fcu->bezt[j].vec[0][1]; + float rot_output = fcu->bezt[j].vec[1][1]; + float rot_outtan = fcu->bezt[j].vec[2][1]; + fcu->bezt[j].vec[0][1] = rot_intan * M_PI / 180.0f; + fcu->bezt[j].vec[1][1] = rot_output * M_PI / 180.0f; + fcu->bezt[j].vec[2][1] = rot_outtan * M_PI / 180.0f; + } + } + i++; + BLI_addtail(&act->curves, fcu); + } + } + + // called on post-process stage after writeVisualScenes + virtual bool writeAnimationList( const COLLADAFW::AnimationList* animationList ) + { + const COLLADAFW::UniqueId& anim_list_id = animationList->getUniqueId(); // possible in case we cannot interpret some transform - if (uid_animated_map.find(anim_id) == uid_animated_map.end()) { + if (uid_animated_map.find(anim_list_id) == uid_animated_map.end()) { return true; } - + // what does this AnimationList animate? - AnimatedTransform& animated = uid_animated_map[anim_id]; - - const COLLADAFW::AnimationList::AnimationBindings& bindings = anim->getAnimationBindings(); - + AnimatedTransform& animated = uid_animated_map[anim_list_id]; + char *loc = "location"; + char *rotate = "rotation"; + char *scale = "scale"; + Object *ob = animated.ob; + + const COLLADAFW::AnimationList::AnimationBindings& bindings = animationList->getAnimationBindings(); switch (animated.tm->getTransformationType()) { case COLLADAFW::Transformation::TRANSLATE: { for (int i = 0; i < bindings.getCount(); i++) { const COLLADAFW::AnimationList::AnimationBinding& binding = bindings[i]; - + COLLADAFW::UniqueId anim_uid = binding.animation; + switch (binding.animationClass) { case COLLADAFW::AnimationList::POSITION_X: + change_fcurve(ob, anim_uid, loc, 0); break; case COLLADAFW::AnimationList::POSITION_Y: + change_fcurve(ob, anim_uid, loc, 1); break; case COLLADAFW::AnimationList::POSITION_Z: + change_fcurve(ob, anim_uid, loc, 2); break; case COLLADAFW::AnimationList::POSITION_XYZ: + change_fcurve(ob, anim_uid, loc, -1); break; default: - fprintf(stderr, "AnimationClass %d is not supported for TRANSLATE transformation.\n", - binding.animationClass); + fprintf(stderr, "AnimationClass %d is not supported for TRANSLATE transformation.\n", binding.animationClass); } } } @@ -1204,20 +1358,21 @@ public: { COLLADAFW::Rotate* rot = (COLLADAFW::Rotate*)animated.tm; COLLADABU::Math::Vector3& axis = rot->getRotationAxis(); - + for (int i = 0; i < bindings.getCount(); i++) { const COLLADAFW::AnimationList::AnimationBinding& binding = bindings[i]; - + COLLADAFW::UniqueId anim_uid = binding.animation; + switch (binding.animationClass) { case COLLADAFW::AnimationList::ANGLE: if (COLLADABU::Math::Vector3::UNIT_X == axis) { - + change_fcurve(ob, anim_uid, rotate, 0); } else if (COLLADABU::Math::Vector3::UNIT_Y == axis) { - + change_fcurve(ob, anim_uid, rotate, 1); } else if (COLLADABU::Math::Vector3::UNIT_Z == axis) { - + change_fcurve(ob, anim_uid, rotate, 2); } break; case COLLADAFW::AnimationList::AXISANGLE: @@ -1231,7 +1386,30 @@ public: } break; case COLLADAFW::Transformation::SCALE: - // same as for TRANSLATE + { + // same as for TRANSLATE + for (int i = 0; i < bindings.getCount(); i++) { + const COLLADAFW::AnimationList::AnimationBinding& binding = bindings[i]; + COLLADAFW::UniqueId anim_uid = binding.animation; + + switch (binding.animationClass) { + case COLLADAFW::AnimationList::POSITION_X: + change_fcurve(ob, anim_uid, scale, 0); + break; + case COLLADAFW::AnimationList::POSITION_Y: + change_fcurve(ob, anim_uid, scale, 1); + break; + case COLLADAFW::AnimationList::POSITION_Z: + change_fcurve(ob, anim_uid, scale, 2); + break; + case COLLADAFW::AnimationList::POSITION_XYZ: + change_fcurve(ob, anim_uid, scale, -1); + break; + default: + fprintf(stderr, "AnimationClass %d is not supported for TRANSLATE transformation.\n", binding.animationClass); + } + } + } break; case COLLADAFW::Transformation::MATRIX: case COLLADAFW::Transformation::SKEW: @@ -1239,10 +1417,10 @@ public: fprintf(stderr, "Animation of MATRIX, SKEW and LOOKAT transformations is not supported yet.\n"); break; } - + return true; } - + /** When this method is called, the writer must write the skin controller data. @return The writer should return true, if writing succeeded, false otherwise.*/ virtual bool writeSkinControllerData( const COLLADAFW::SkinControllerData* skinControllerData ) diff --git a/source/blender/makesdna/DNA_anim_types.h b/source/blender/makesdna/DNA_anim_types.h index bf6b9bed5a1..a2e577c196b 100644 --- a/source/blender/makesdna/DNA_anim_types.h +++ b/source/blender/makesdna/DNA_anim_types.h @@ -40,7 +40,7 @@ typedef struct FModifier { /* Types of F-Curve modifier * WARNING: order here is important! */ -enum { +typedef enum eFModifier { FMODIFIER_TYPE_NULL = 0, FMODIFIER_TYPE_GENERATOR, FMODIFIER_TYPE_ENVELOPE, @@ -55,7 +55,7 @@ enum { } eFModifier_Types; /* F-Curve Modifier Settings */ -enum { +typedef enum eFModifier_Flags { /* modifier is not able to be evaluated for some reason, and should be skipped (internal) */ FMODIFIER_FLAG_DISABLED = (1<<0), /* modifier's data is expanded (in UI) */ @@ -88,7 +88,7 @@ typedef struct FMod_Generator { } FMod_Generator; /* generator modes */ -enum { +typedef enum eFMod_Generator_Modes { FCM_GENERATOR_POLYNOMIAL = 0, FCM_GENERATOR_POLYNOMIAL_FACTORISED, FCM_GENERATOR_FUNCTION, @@ -96,13 +96,13 @@ enum { } eFMod_Generator_Modes; /* generator flags */ -enum { +typedef enum eFMod_Generator_Flags { /* generator works in conjunction with other modifiers (i.e. doesn't replace those before it) */ FCM_GENERATOR_ADDITIVE = (1<<0), } eFMod_Generator_Flags; /* 'function' generator types */ -enum { +typedef enum eFMod_Generator_Functions { FCM_GENERATOR_FN_SIN = 0, FCM_GENERATOR_FN_COS, FCM_GENERATOR_FN_TAN, @@ -140,7 +140,7 @@ typedef struct FMod_Cycles { } FMod_Cycles; /* cycling modes */ -enum { +typedef enum eFMod_Cycling_Modes { FCM_EXTRAPOLATE_NONE = 0, /* don't do anything */ FCM_EXTRAPOLATE_CYCLIC, /* repeat keyframe range as-is */ FCM_EXTRAPOLATE_CYCLIC_OFFSET, /* repeat keyframe range, but with offset based on gradient between values */ @@ -163,7 +163,7 @@ typedef struct FMod_Limits { } FMod_Limits; /* limiting flags */ -enum { +typedef enum eFMod_Limit_Flags { FCM_LIMIT_XMIN = (1<<0), FCM_LIMIT_XMAX = (1<<1), FCM_LIMIT_YMIN = (1<<2), @@ -183,7 +183,7 @@ typedef struct FMod_Noise { } FMod_Noise; /* modification modes */ -enum { +typedef enum eFMod_Noise_Modifications { FCM_NOISE_MODIF_REPLACE = 0, /* Modify existing curve, matching it's shape */ FCM_NOISE_MODIF_ADD, /* Add noise to the curve */ FCM_NOISE_MODIF_SUBTRACT, /* Subtract noise from the curve */ @@ -239,7 +239,7 @@ typedef struct ChannelDriver { } ChannelDriver; /* driver type */ -enum { +typedef enum eDriver_Types { /* target values are averaged together */ DRIVER_TYPE_AVERAGE = 0, /* python expression/function relates targets */ @@ -249,7 +249,7 @@ enum { } eDriver_Types; /* driver flags */ -enum { +typedef enum eDriver_Flags { /* driver has invalid settings (internal flag) */ DRIVER_FLAG_INVALID = (1<<0), /* driver needs recalculation (set by depsgraph) */ @@ -305,7 +305,7 @@ typedef struct FCurve { /* user-editable flags/settings */ -enum { +typedef enum eFCurve_Flags { /* curve/keyframes are visible in editor */ FCURVE_VISIBLE = (1<<0), /* curve is selected for editing */ @@ -328,13 +328,13 @@ enum { } eFCurve_Flags; /* extrapolation modes (only simple value 'extending') */ -enum { +typedef enum eFCurve_Extend { FCURVE_EXTRAPOLATE_CONSTANT = 0, /* just extend min/max keyframe value */ FCURVE_EXTRAPOLATE_LINEAR, /* just extend gradient of segment between first segment keyframes */ } eFCurve_Extend; /* curve coloring modes */ -enum { +typedef enum eFCurve_Coloring { FCURVE_COLOR_AUTO_RAINBOW = 0, /* automatically determine color using rainbow (calculated at drawtime) */ FCURVE_COLOR_AUTO_RGB, /* automatically determine color using XYZ (array index) <-> RGB */ FCURVE_COLOR_CUSTOM, /* custom color */ @@ -442,7 +442,7 @@ typedef struct NlaStrip { } NlaStrip; /* NLA Strip Blending Mode */ -enum { +typedef enum eActStrip_Mode { NLASTRIPMODE_BLEND = 0, NLASTRIPMODE_ADD, NLASTRIPMODE_SUBTRACT, @@ -450,7 +450,7 @@ enum { /* NLA Strip Settings */ // TODO: check on which of these are still useful... -enum { +typedef enum eActionStrip_Flag { NLASTRIP_SELECT = (1<<0), NLASTRIP_USESTRIDE = (1<<1), NLASTRIP_BLENDTONEXT = (1<<2), /* Not implemented. Is not used anywhere */ @@ -487,7 +487,7 @@ typedef struct NlaTrack { } NlaTrack; /* settings for track */ -enum { +typedef enum eNlaTrack_Flag { /* track is the one that settings can be modified on (doesn't indicate * that it's for 'tweaking' though) */ @@ -538,13 +538,13 @@ typedef struct KS_Path { } KS_Path; /* KS_Path->flag */ -enum { +typedef enum eKSP_Settings { /* entire array (not just the specified index) gets keyframed */ KSP_FLAG_WHOLE_ARRAY = (1<<0), } eKSP_Settings; /* KS_Path->groupmode */ -enum { +typedef enum eKSP_Grouping { /* path should be grouped using group name stored in path */ KSP_GROUP_NAMED = 0, /* path should not be grouped at all */ @@ -564,7 +564,7 @@ enum { * enum here defines the flags which define which templates are * required by a path before it can be used */ -enum { +typedef enum eKSP_TemplateTypes { KSP_TEMPLATE_OBJECT = (1<<0), /* #obj - selected object */ KSP_TEMPLATE_PCHAN = (1<<1), /* #pch - selected posechannel */ KSP_TEMPLATE_CONSTRAINT = (1<<2), /* #con - active only */ @@ -595,7 +595,7 @@ typedef struct KeyingSet { } KeyingSet; /* KeyingSet settings */ -enum { +typedef enum eKS_Settings { /* keyingset cannot be removed (and doesn't need to be freed) */ KEYINGSET_BUILTIN = (1<<0), /* keyingset does not depend on context info (i.e. paths are absolute) */ @@ -603,7 +603,7 @@ enum { } eKS_Settings; /* Flags for use by keyframe creation/deletion calls */ -enum { +typedef enum eInsertKeyFlags { INSERTKEY_NEEDED = (1<<0), /* only insert keyframes where they're needed */ INSERTKEY_MATRIX = (1<<1), /* insert 'visual' keyframes where possible/needed */ INSERTKEY_FAST = (1<<2), /* don't recalculate handles,etc. after adding key */ @@ -671,7 +671,7 @@ typedef struct AnimData { } AnimData; /* Animation Data settings (mostly for NLA) */ -enum { +typedef enum eAnimData_Flag { /* only evaluate a single track in the NLA */ ADT_NLA_SOLO_TRACK = (1<<0), /* don't use NLA */ @@ -684,7 +684,7 @@ enum { } eAnimData_Flag; /* Animation Data recalculation settings (to be set by depsgraph) */ -enum { +typedef enum eAnimData_Recalc { ADT_RECALC_DRIVERS = (1<<0), ADT_RECALC_ANIM = (1<<1), ADT_RECALC_ALL = (ADT_RECALC_DRIVERS|ADT_RECALC_ANIM),