void UAnimSequenceBase::VerifyCurveNames(USkeleton* Skeleton, const FName& NameContainer, TArray<DataType>& CurveList) { FSmartNameMapping* NameMapping = Skeleton->SmartNames.GetContainer(NameContainer); // since this is verify function that makes sure it exists after loaded // we should add it if it doesn't exist if (!NameMapping) { // if it doens't exists, we should add it Skeleton->Modify(true); Skeleton->SmartNames.AddContainer(NameContainer); NameMapping = Skeleton->SmartNames.GetContainer(NameContainer); check(NameMapping); } TArray<DataType*> UnlinkedCurves; for(DataType& Curve : CurveList) { if(!NameMapping->Exists(Curve.LastObservedName)) { // The skeleton doesn't know our name. Use the last observed name that was saved with the // curve to create a new name. This can happen if a user saves an animation but not a skeleton // either when updating the assets or editing the curves within. UnlinkedCurves.Add(&Curve); } } for(DataType* Curve : UnlinkedCurves) { NameMapping->AddOrFindName(Curve->LastObservedName, Curve->CurveUid); } }
/** * Since we don't care about blending, we just change this decoration to OutCurves * @TODO : Fix this if we're saving vectorcurves and blending */ void FRawCurveTracks::EvaluateTransformCurveData(USkeleton * Skeleton, TMap<FName, FTransform>&OutCurves, float CurrentTime, float BlendWeight) const { check (Skeleton); // evaluate the curve data at the CurrentTime and add to Instance for(auto CurveIter = TransformCurves.CreateConstIterator(); CurveIter; ++CurveIter) { const FTransformCurve& Curve = *CurveIter; // if disabled, do not handle if (Curve.GetCurveTypeFlag(ACF_Disabled)) { continue; } FSmartNameMapping* NameMapping = Skeleton->SmartNames.GetContainer(USkeleton::AnimTrackCurveMappingName); // Add or retrieve curve FName CurveName; // make sure it was added if (ensure (NameMapping->GetName(Curve.CurveUid, CurveName))) { // note we're not checking Curve.GetCurveTypeFlags() yet FTransform & Value = OutCurves.FindOrAdd(CurveName); Value = Curve.Evaluate(CurrentTime, BlendWeight); } } }
void USkeleton::RemoveSmartnameAndModify(FName ContainerName, FSmartNameMapping::UID Uid) { FSmartNameMapping* RequestedMapping = SmartNames.GetContainer(ContainerName); if(RequestedMapping) { if(RequestedMapping->Exists(Uid)) { Modify(); RequestedMapping->Remove(Uid); } } }
void UAnimPreviewInstance::RefreshCurveBoneControllers() { // go through all curves and see if it has Transform Curve // if so, find what bone that belong to and create BoneMOdifier for them UAnimSequence* CurrentSequence = Cast<UAnimSequence>(CurrentAsset); CurveBoneControllers.Empty(); // do not apply if BakedAnimation is on if(CurrentSequence) { // make sure if this needs source update if ( !CurrentSequence->DoesContainTransformCurves() ) { return; } RequiredBones.SetUseSourceData(true); TArray<FTransformCurve>& Curves = CurrentSequence->RawCurveData.TransformCurves; FSmartNameMapping* NameMapping = CurrentSkeleton->SmartNames.GetContainer(USkeleton::AnimTrackCurveMappingName); for (auto& Curve : Curves) { // skip if disabled if (Curve.GetCurveTypeFlag(ACF_Disabled)) { continue; } // add bone modifier FName CurveName; NameMapping->GetName(Curve.CurveUid, CurveName); // @TODO: this is going to be issue. If they don't save skeleton with it, we don't have name at all? if (CurveName == NAME_None) { FSmartNameMapping::UID NewUID; NameMapping->AddOrFindName(Curve.LastObservedName, NewUID); Curve.CurveUid = NewUID; CurveName = Curve.LastObservedName; } FName BoneName = CurveName; if (BoneName != NAME_None && CurrentSkeleton->GetReferenceSkeleton().FindBoneIndex(BoneName) != INDEX_NONE) { ModifyBone(BoneName, true); } } } }
void UAnimSequenceBase::PostLoad() { Super::PostLoad(); // Convert Notifies to new data if( GIsEditor && Notifies.Num() > 0 ) { if(GetLinkerUE4Version() < VER_UE4_CLEAR_NOTIFY_TRIGGERS) { for(FAnimNotifyEvent Notify : Notifies) { if(Notify.Notify) { // Clear end triggers for notifies that are not notify states Notify.EndTriggerTimeOffset = 0.0f; } } } } // Ensure notifies are sorted. SortNotifies(); #if WITH_EDITOR InitializeNotifyTrack(); UpdateAnimNotifyTrackCache(); #endif if(USkeleton* Skeleton = GetSkeleton()) { // Fix up the existing curves to work with smartnames if(GetLinkerUE4Version() < VER_UE4_SKELETON_ADD_SMARTNAMES) { // Get the name mapping object for curves FSmartNameMapping* NameMapping = Skeleton->SmartNames.GetContainer(USkeleton::AnimCurveMappingName); for(FFloatCurve& Curve : RawCurveData.FloatCurves) { // Add the names of the curves into the smartname mapping and store off the curve uid which will be saved next time the sequence saves. NameMapping->AddOrFindName(Curve.LastObservedName, Curve.CurveUid); } } else { VerifyCurveNames<FFloatCurve>(Skeleton, USkeleton::AnimCurveMappingName, RawCurveData.FloatCurves); } #if WITH_EDITOR VerifyCurveNames<FTransformCurve>(Skeleton, USkeleton::AnimTrackCurveMappingName, RawCurveData.TransformCurves); #endif } }
bool USkeleton::AddSmartnameAndModify(FName ContainerName, FName NewName, FSmartNameMapping::UID& NewUid) { bool Successful = false; FSmartNameMapping* RequestedMapping = SmartNames.GetContainer(ContainerName); if(RequestedMapping) { if(RequestedMapping->AddName(NewName, NewUid)) { Modify(true); Successful = true; } } return Successful; }
bool USkeleton::RenameSmartnameAndModify(FName ContainerName, FSmartNameMapping::UID Uid, FName NewName) { bool Successful = false; FSmartNameMapping* RequestedMapping = SmartNames.GetContainer(ContainerName); if(RequestedMapping) { FName CurrentName; RequestedMapping->GetName(Uid, CurrentName); if(CurrentName != NewName) { Modify(); Successful = RequestedMapping->Rename(Uid, NewName); } } return Successful; }
/** Called to get the name of a curve back from the animation skeleton */ virtual FText GetCurveName(USkeleton::AnimCurveUID Uid) const { if(BaseSequence.IsValid()) { FSmartNameMapping* NameMapping = BaseSequence.Get()->GetSkeleton()->SmartNames.GetContainer(USkeleton::AnimCurveMappingName); if(NameMapping) { FName CurveName; if(NameMapping->GetName(Uid, CurveName)) { return FText::FromName(CurveName); } } } return FText::GetEmpty(); }
/** Called to get the name of a curve back from the animation skeleton */ virtual FText GetCurveName(USkeleton::AnimCurveUID Uid) const { if(BaseSequence.IsValid()) { FSmartNameMapping* NameMapping = BaseSequence.Get()->GetSkeleton()->SmartNames.GetContainer(USkeleton::AnimTrackCurveMappingName); if(NameMapping) { FName CurveName; if(NameMapping->GetName(Uid, CurveName)) { FName DisplayName = CurveName; return FText::FromString(FString::Printf(TEXT("%s(%c)"), *DisplayName.ToString(), GetCurveTypeCharacter())); } } } return FText::GetEmpty(); }
bool UnFbx::FFbxImporter::ImportCurveToAnimSequence(class UAnimSequence * TargetSequence, const FString& CurveName, const FbxAnimCurve* FbxCurve, int32 CurveFlags,const FbxTimeSpan AnimTimeSpan, const float ValueScale/*=1.f*/) const { if (TargetSequence && FbxCurve) { FName Name = *CurveName; USkeleton* Skeleton = TargetSequence->GetSkeleton(); FSmartNameMapping* NameMapping = Skeleton->SmartNames.GetContainer(USkeleton::AnimCurveMappingName); // Add or retrieve curve USkeleton::AnimCurveUID Uid; if (!NameMapping->Exists(Name)) { // mark skeleton dirty Skeleton->Modify(); } NameMapping->AddOrFindName(Name, Uid); FFloatCurve * CurveToImport = static_cast<FFloatCurve *>(TargetSequence->RawCurveData.GetCurveData(Uid, FRawCurveTracks::FloatType)); if(CurveToImport==NULL) { if(TargetSequence->RawCurveData.AddCurveData(Uid, CurveFlags)) { CurveToImport = static_cast<FFloatCurve *> (TargetSequence->RawCurveData.GetCurveData(Uid, FRawCurveTracks::FloatType)); } else { // this should not happen, we already checked before adding ensureMsgf(0, TEXT("FBX Import: Critical error: no memory?")); } } else { CurveToImport->FloatCurve.Reset(); } return ImportCurve(FbxCurve, CurveToImport, AnimTimeSpan, ValueScale); } return false; }
void UAnimSequenceBase::VerifyCurveNames(USkeleton* Skeleton, const FName& NameContainer, TArray<DataType>& CurveList) { FSmartNameMapping* NameMapping = Skeleton->SmartNames.GetContainer(NameContainer); // since this is verify function that makes sure it exists after loaded // we should add it if it doesn't exist if (!NameMapping) { // if it doens't exists, we should add it Skeleton->Modify(true); Skeleton->SmartNames.AddContainer(NameContainer); NameMapping = Skeleton->SmartNames.GetContainer(NameContainer); check(NameMapping); } TArray<DataType*> UnlinkedCurves; for(DataType& Curve : CurveList) { const FSmartNameMapping::UID* UID = NameMapping->FindUID(Curve.LastObservedName); if(!UID) { // The skeleton doesn't know our name. Use the last observed name that was saved with the // curve to create a new name. This can happen if a user saves an animation but not a skeleton // either when updating the assets or editing the curves within. UnlinkedCurves.Add(&Curve); } else if (Curve.CurveUid != *UID)// we verify if UID is correct { // if UID doesn't match, this is suspicious // because same name but different UID is not idea // so we'll fix up UID Curve.CurveUid = *UID; } } for(DataType* Curve : UnlinkedCurves) { NameMapping->AddOrFindName(Curve->LastObservedName, Curve->CurveUid); } }