From 2104ee5b3a489ad50ccc87abc93a639eb35f9b6e Mon Sep 17 00:00:00 2001 From: David Hibbitts Date: Tue, 23 Jan 2018 14:49:29 +0000 Subject: [PATCH] Added the ability to get all Animatable and Streamable properties for a given model. Vastly simplifies streaming logic --- Source/Public/StreamStore.h | 1 + Source/StreamObjects/CameraStreamObject.cpp | 30 +------- .../EditorActiveCameraStreamObject.cpp | 31 +------- Source/StreamObjects/LightStreamObject.cpp | 3 +- .../SkeletonHeirarchyStreamObject.cpp | 48 ++++++------ Source/StreamObjects/StreamObjectBase.cpp | 74 +++++++++++++++++++ 6 files changed, 106 insertions(+), 81 deletions(-) diff --git a/Source/Public/StreamStore.h b/Source/Public/StreamStore.h index 097434fc..8bd916d4 100644 --- a/Source/Public/StreamStore.h +++ b/Source/Public/StreamStore.h @@ -48,6 +48,7 @@ class StreamObjectBase static FTransform MobuTransformToUnreal(FBMatrix& MobuTransfrom); static FTransform UnrealTransformFromModel(FBModel* MobuModel, bool bIsGlobal = true); static FTransform UnrealTransformFromCamera(FBCamera* CameraModel); + static TArray GetAllAnimatableCurves(FBModel* MobuModel); protected: diff --git a/Source/StreamObjects/CameraStreamObject.cpp b/Source/StreamObjects/CameraStreamObject.cpp index 9b4d58f6..7e7b2ad3 100644 --- a/Source/StreamObjects/CameraStreamObject.cpp +++ b/Source/StreamObjects/CameraStreamObject.cpp @@ -27,37 +27,11 @@ void CameraStreamObject::GetStreamData() BoneTransforms.Emplace(UnrealTransformFromCamera(CameraModel)); TArray CurveData; + // If Streaming as Camera then get the Camera Properties if (StreamingMode == 0) { - CurveData.SetNum(9); - - CurveData[0].CurveName = FName(TEXT("FieldOfViewX")); - CurveData[0].CurveValue = CameraModel->FieldOfViewX; - - CurveData[1].CurveName = FName(TEXT("FieldOfViewY")); - CurveData[1].CurveValue = CameraModel->FieldOfViewY; - - CurveData[2].CurveName = FName(TEXT("FieldOfView")); - CurveData[2].CurveValue = CameraModel->FieldOfView; - - CurveData[3].CurveName = FName(TEXT("FocalLength")); - CurveData[3].CurveValue = CameraModel->FocalLength; - - CurveData[4].CurveName = FName(TEXT("FocusSpecificDistance")); - CurveData[4].CurveValue = CameraModel->FocusSpecificDistance; - - CurveData[5].CurveName = FName(TEXT("NearPlaneDistance")); - CurveData[5].CurveValue = CameraModel->NearPlaneDistance; - - CurveData[6].CurveName = FName(TEXT("FarPlaneDistance")); - CurveData[6].CurveValue = CameraModel->FarPlaneDistance; - - CurveData[7].CurveName = FName(TEXT("FilmSizeWidth")); - CurveData[7].CurveValue = CameraModel->FilmSizeWidth; - - CurveData[8].CurveName = FName(TEXT("FilmSizeHeight")); - CurveData[8].CurveValue = CameraModel->FilmSizeHeight; + CurveData = GetAllAnimatableCurves(CameraModel); } FBTime LocalTime = FBSystem().LocalTime; diff --git a/Source/StreamObjects/EditorActiveCameraStreamObject.cpp b/Source/StreamObjects/EditorActiveCameraStreamObject.cpp index 42b62303..89513891 100644 --- a/Source/StreamObjects/EditorActiveCameraStreamObject.cpp +++ b/Source/StreamObjects/EditorActiveCameraStreamObject.cpp @@ -34,36 +34,7 @@ void EditorActiveCameraStreamObject::GetStreamData() // Single Bone BoneTransforms.Emplace(UnrealTransformFromCamera(CameraModel)); - TArray CurveData; - - CurveData.SetNum(9); - - CurveData[0].CurveName = FName(TEXT("FieldOfViewX")); - CurveData[0].CurveValue = CameraModel->FieldOfViewX; - - CurveData[1].CurveName = FName(TEXT("FieldOfViewY")); - CurveData[1].CurveValue = CameraModel->FieldOfViewY; - - CurveData[2].CurveName = FName(TEXT("FieldOfView")); - CurveData[2].CurveValue = CameraModel->FieldOfView; - - CurveData[3].CurveName = FName(TEXT("FocalLength")); - CurveData[3].CurveValue = CameraModel->FocalLength; - - CurveData[4].CurveName = FName(TEXT("FocusSpecificDistance")); - CurveData[4].CurveValue = CameraModel->FocusSpecificDistance; - - CurveData[5].CurveName = FName(TEXT("NearPlaneDistance")); - CurveData[5].CurveValue = CameraModel->NearPlaneDistance; - - CurveData[6].CurveName = FName(TEXT("FarPlaneDistance")); - CurveData[6].CurveValue = CameraModel->FarPlaneDistance; - - CurveData[7].CurveName = FName(TEXT("FilmSizeWidth")); - CurveData[7].CurveValue = CameraModel->FilmSizeWidth; - - CurveData[8].CurveName = FName(TEXT("FilmSizeHeight")); - CurveData[8].CurveValue = CameraModel->FilmSizeHeight; + TArray CurveData = GetAllAnimatableCurves(CameraModel); FBTime LocalTime = FBSystem().LocalTime; Provider->UpdateSubjectFrame(SubjectName, BoneTransforms, CurveData, LocalTime.GetSecondDouble(), LocalTime.GetFrame()); diff --git a/Source/StreamObjects/LightStreamObject.cpp b/Source/StreamObjects/LightStreamObject.cpp index 3cdefc22..cc9dfc3c 100644 --- a/Source/StreamObjects/LightStreamObject.cpp +++ b/Source/StreamObjects/LightStreamObject.cpp @@ -30,7 +30,8 @@ void LightStreamObject::GetStreamData() // If Streaming as Light then get the Light Properties if (StreamingMode == 0) { - // TODO: Get Light Properties here + // TODO: Add any additional Light logic here. For now stream everything we can + CurveData = GetAllAnimatableCurves(LightModel); } FBTime LocalTime = FBSystem().LocalTime; diff --git a/Source/StreamObjects/SkeletonHeirarchyStreamObject.cpp b/Source/StreamObjects/SkeletonHeirarchyStreamObject.cpp index e73e56c9..d9ac8ba9 100644 --- a/Source/StreamObjects/SkeletonHeirarchyStreamObject.cpp +++ b/Source/StreamObjects/SkeletonHeirarchyStreamObject.cpp @@ -16,36 +16,40 @@ void SkeletonHeirarchyStreamObject::UpdateFromModel() BoneParents.Emplace(-1); BoneModels.Emplace(RootModel); - TArray> SearchList; - TArray> SearchListNext; - - SearchList.Emplace(0, (FBModel*)RootModel); - + // If Streaming as Hierarchy if (StreamingMode == 0) { - while (SearchList.Num() > 0) + TArray> SearchList; + TArray> SearchListNext; + + SearchList.Emplace(0, (FBModel*)RootModel); + + if (StreamingMode == 0) { - for (const auto& SearchPair : SearchList) + while (SearchList.Num() > 0) { - int ParentIdx = SearchPair.Key; - FBModel* SearchModel = SearchPair.Value; - int ChildCount = SearchModel->Children.GetCount(); // Yuck - - for (int ChildIdx = 0; ChildIdx < ChildCount; ++ChildIdx) + for (const auto& SearchPair : SearchList) { - FBModel* ChildModel = SearchModel->Children[ChildIdx]; + int ParentIdx = SearchPair.Key; + FBModel* SearchModel = SearchPair.Value; + int ChildCount = SearchModel->Children.GetCount(); // Yuck + + for (int ChildIdx = 0; ChildIdx < ChildCount; ++ChildIdx) + { + FBModel* ChildModel = SearchModel->Children[ChildIdx]; - if (ChildModel->GetTypeId() != FBModelSkeleton::TypeInfo) continue; // Only want joints + if (ChildModel->GetTypeId() != FBModelSkeleton::TypeInfo) continue; // Only want joints - BoneNames.Emplace(ChildModel->Name); - BoneParents.Emplace(ParentIdx); - BoneModels.Emplace(ChildModel); + BoneNames.Emplace(ChildModel->Name); + BoneParents.Emplace(ParentIdx); + BoneModels.Emplace(ChildModel); - SearchListNext.Emplace(BoneModels.Num() - 1, ChildModel); + SearchListNext.Emplace(BoneModels.Num() - 1, ChildModel); + } } + SearchList = SearchListNext; + SearchListNext.Empty(); } - SearchList = SearchListNext; - SearchListNext.Empty(); } } Provider->UpdateSubject(SubjectName, BoneNames, BoneParents); @@ -74,8 +78,8 @@ void SkeletonHeirarchyStreamObject::GetStreamData() } - // Generic Models have no special properties - TArray CurveData; + // Stream all properties on the root bone + TArray CurveData = GetAllAnimatableCurves((FBModel*)BoneModels[0]); FBTime LocalTime = FBSystem().LocalTime; Provider->UpdateSubjectFrame(SubjectName, BoneTransforms, CurveData, LocalTime.GetSecondDouble(), LocalTime.GetFrame()); diff --git a/Source/StreamObjects/StreamObjectBase.cpp b/Source/StreamObjects/StreamObjectBase.cpp index c75119de..5657e436 100644 --- a/Source/StreamObjects/StreamObjectBase.cpp +++ b/Source/StreamObjects/StreamObjectBase.cpp @@ -167,6 +167,80 @@ FTransform StreamObjectBase::UnrealTransformFromCamera(FBCamera* CameraModel) return CameraTransform; } +// Get all properties on a given model that are both Animatable and are of a Type we can stream +TArray StreamObjectBase::GetAllAnimatableCurves(FBModel* MobuModel) +{ + int PropertyCount = MobuModel->PropertyList.GetCount(); + + TArray LiveLinkCurves; + // Reserve enough memory for worst case + LiveLinkCurves.Reserve(PropertyCount); + + float PropertyValue; + FName PropertyName; + for (int i = 0; i < PropertyCount; ++i) + { + FBProperty* Property = MobuModel->PropertyList[i]; + if (Property->IsAnimatable()) + { + switch (Property->GetPropertyType()) + { + case kFBPT_bool: + { + bool bValue; + Property->GetData(&bValue, sizeof(bValue), nullptr); + PropertyValue = bValue ? 1.0f : 0.0f; + break; + } + case kFBPT_double: + { + double Value; + Property->GetData(&Value, sizeof(Value), nullptr); + PropertyValue = (float)Value; + break; + } + case kFBPT_float: + { + // PropertyValue is a float so retrieve it directly + Property->GetData(&PropertyValue, sizeof(PropertyValue), nullptr); + break; + } + case kFBPT_enum: // Enums are assumed to be ints. THIS MAY NOT BE A VALID ASSUMPTION + case kFBPT_int: + { + int Value; + Property->GetData(&Value, sizeof(Value), nullptr); + PropertyValue = (float)Value; + break; + } + case kFBPT_int64: + { + int64 Value; + Property->GetData(&Value, sizeof(Value), nullptr); + PropertyValue = (float)Value; + break; + } + case kFBPT_uint64: + { + uint64 Value; + Property->GetData(&Value, sizeof(Value), nullptr); + PropertyValue = (float)Value; + break; + } + default: + continue; + } + + FLiveLinkCurveElement NewCurveElement; + NewCurveElement.CurveName = FName(Property->GetName());; + NewCurveElement.CurveValue = PropertyValue; + + LiveLinkCurves.Emplace(NewCurveElement); + } + } + return LiveLinkCurves; +} +