{
case 0: // Load bvh from url
{
- animDef = LoadBvh(TEST_RESOURCE_DIR "/test.bvh", "testBvh");
+ animDef = LoadBvh(TEST_RESOURCE_DIR "/test.bvh", "testBvh", false);
break;
}
case 1: // Load bvh from buffer stream.
{
std::string rawString = ReadBufferFromFile(TEST_RESOURCE_DIR "/test.bvh");
- animDef = LoadBvhFromBuffer(reinterpret_cast<uint8_t*>(rawString.data()), static_cast<int>(rawString.length()), "testBvh");
+ animDef = LoadBvhFromBuffer(reinterpret_cast<uint8_t*>(rawString.data()), static_cast<int>(rawString.length()), "testBvh", false);
break;
}
}
{
TestApplication application;
- AnimationDefinition animDef = LoadBvh("/nothing.bvh", "testBvh");
+ AnimationDefinition animDef = LoadBvh("/nothing.bvh", "testBvh", false);
DALI_TEST_EQUALS(0u, animDef.GetPropertyCount(), TEST_LOCATION);
END_TEST;
}
{
TestApplication application;
- AnimationDefinition animDef = LoadBvhFromBuffer(nullptr, 0, "testBvh");
+ AnimationDefinition animDef = LoadBvhFromBuffer(nullptr, 0, "testBvh", false);
DALI_TEST_EQUALS(0u, animDef.GetPropertyCount(), TEST_LOCATION);
END_TEST;
}
tet_printf("Parse error for hierarchy %u\n", tc);
std::ostringstream oss;
oss << TEST_RESOURCE_DIR << "/test-invalid-hierarchy" << tc << ".bvh";
- AnimationDefinition animDef = LoadBvh(oss.str(), "testBvh");
+ AnimationDefinition animDef = LoadBvh(oss.str(), "testBvh", false);
DALI_TEST_EQUALS(0u, animDef.GetPropertyCount(), TEST_LOCATION);
}
tet_printf("Parse error for motion %u\n", tc);
std::ostringstream oss;
oss << TEST_RESOURCE_DIR << "/test-invalid-motion" << tc << ".bvh";
- AnimationDefinition animDef = LoadBvh(oss.str(), "testBvh");
+ AnimationDefinition animDef = LoadBvh(oss.str(), "testBvh", false);
DALI_TEST_EQUALS(0u, animDef.GetPropertyCount(), TEST_LOCATION);
}
{
tet_infoline("empty file");
- AnimationDefinition animDef = LoadBvh(TEST_RESOURCE_DIR "/test-empty.bvh", "testBvh");
+ AnimationDefinition animDef = LoadBvh(TEST_RESOURCE_DIR "/test-empty.bvh", "testBvh", false);
DALI_TEST_EQUALS(0u, animDef.GetPropertyCount(), TEST_LOCATION);
}
END_TEST;
DALI_TEST_EQUALS(gLoadCompleted, false, TEST_LOCATION);
END_TEST;
+}
+
+int UtcDaliMotionDataLoadBvhUseRootTranslationOnly(void)
+{
+ ToolkitTestApplication application;
+
+ MotionData motionDataAllTranslation = MotionData::New();
+ motionDataAllTranslation.LoadBvh(TEST_BVH_FILE_NAME, false, Vector3::ONE, true);
+
+ DALI_TEST_EQUALS(motionDataAllTranslation.GetMotionCount(), 4, TEST_LOCATION);
+
+ MotionData motionDataOnlyRootTranslation = MotionData::New();
+ motionDataOnlyRootTranslation.LoadBvh(TEST_BVH_FILE_NAME, true, Vector3::ONE, true);
+
+ DALI_TEST_EQUALS(motionDataOnlyRootTranslation.GetMotionCount(), 3, TEST_LOCATION);
+
+ END_TEST;
+}
+
+int UtcDaliMotionDataLoadBvhFromBufferUseRootTranslationOnly(void)
+{
+ ToolkitTestApplication application;
+
+ std::string rawString = ReadBufferFromFile(TEST_BVH_FILE_NAME);
+
+ MotionData motionDataAllTranslation = MotionData::New();
+ motionDataAllTranslation.LoadBvhFromBuffer(reinterpret_cast<uint8_t*>(rawString.data()), static_cast<int>(rawString.length()), false, Vector3::ONE, true);
+
+ DALI_TEST_EQUALS(motionDataAllTranslation.GetMotionCount(), 4, TEST_LOCATION);
+
+ MotionData motionDataOnlyRootTranslation = MotionData::New();
+ motionDataOnlyRootTranslation.LoadBvhFromBuffer(reinterpret_cast<uint8_t*>(rawString.data()), static_cast<int>(rawString.length()), true, Vector3::ONE, true);
+
+ DALI_TEST_EQUALS(motionDataOnlyRootTranslation.GetMotionCount(), 3, TEST_LOCATION);
+
+ END_TEST;
}
\ No newline at end of file
return mDurationSeconds;
}
-void MotionData::LoadBvh(const std::string& path, const Vector3& scale, bool synchronousLoad)
+void MotionData::LoadBvh(const std::string& path, bool useRootTranslationOnly, const Vector3& scale, bool synchronousLoad)
{
CancelMotionDataLoad();
- mMotionDataLoadTask = new MotionDataLoadTask(path, scale, MakeCallback(this, &MotionData::OnLoadCompleted));
+ mMotionDataLoadTask = new MotionDataLoadTask(path, useRootTranslationOnly, scale, MakeCallback(this, &MotionData::OnLoadCompleted));
RequestMotionDataLoad(synchronousLoad);
}
-void MotionData::LoadBvhFromBuffer(const uint8_t* rawBuffer, int rawBufferLength, const Vector3& scale, bool synchronousLoad)
+void MotionData::LoadBvhFromBuffer(const uint8_t* rawBuffer, int rawBufferLength, bool useRootTranslationOnly, const Vector3& scale, bool synchronousLoad)
{
CancelMotionDataLoad();
- mMotionDataLoadTask = new MotionDataLoadTask(rawBuffer, rawBufferLength, scale, MakeCallback(this, &MotionData::OnLoadCompleted));
+ mMotionDataLoadTask = new MotionDataLoadTask(rawBuffer, rawBufferLength, useRootTranslationOnly, scale, MakeCallback(this, &MotionData::OnLoadCompleted));
RequestMotionDataLoad(synchronousLoad);
}
/**
* @copydoc Dali::Scene3D::MotionData::LoadBvh()
*/
- void LoadBvh(const std::string& path, const Vector3& scale = Vector3::ONE, bool synchronousLoad = false);
+ void LoadBvh(const std::string& path, bool useRootTranslationOnly, const Vector3& scale = Vector3::ONE, bool synchronousLoad = false);
/**
* @copydoc Dali::Scene3D::MotionData::LoadBvhFromBuffer()
*/
- void LoadBvhFromBuffer(const uint8_t* rawBuffer, int rawBufferLength, const Vector3& scale = Vector3::ONE, bool synchronousLoad = false);
+ void LoadBvhFromBuffer(const uint8_t* rawBuffer, int rawBufferLength, bool useRootTranslationOnly, const Vector3& scale = Vector3::ONE, bool synchronousLoad = false);
/**
* @copydoc Dali::Scene3D::MotionData::LoadFacialAnimation()
{
namespace Internal
{
-MotionDataLoadTask::MotionDataLoadTask(const std::string& path, const Vector3& scale, CallbackBase* callback)
+MotionDataLoadTask::MotionDataLoadTask(const std::string& path, bool useRootTranslationOnly, const Vector3& scale, CallbackBase* callback)
: AsyncTask(callback),
mFileUrl(path),
mRawBuffer(nullptr),
mRawBufferLength(0),
mScale(scale),
+ mUseRootTranslationOnly(useRootTranslationOnly),
mAnimationDefinition{},
mLoadMethod(MotionDataLoadTask::LoadMethod::BVH_FILE)
{
}
-MotionDataLoadTask::MotionDataLoadTask(const uint8_t* rawBuffer, int rawBufferLength, const Vector3& scale, CallbackBase* callback)
+MotionDataLoadTask::MotionDataLoadTask(const uint8_t* rawBuffer, int rawBufferLength, bool useRootTranslationOnly, const Vector3& scale, CallbackBase* callback)
: AsyncTask(callback),
mFileUrl(),
mRawBuffer(nullptr),
mRawBufferLength(rawBufferLength),
mScale(scale),
+ mUseRootTranslationOnly(useRootTranslationOnly),
mAnimationDefinition{},
mLoadMethod(MotionDataLoadTask::LoadMethod::BVH_BUFFER)
{
mRawBuffer(nullptr),
mRawBufferLength(0),
mScale(),
+ mUseRootTranslationOnly(false),
mAnimationDefinition{},
mLoadMethod(MotionDataLoadTask::LoadMethod::FACIAL_FILE)
{
mRawBuffer(nullptr),
mRawBufferLength(rawBufferLength),
mScale(),
+ mUseRootTranslationOnly(false),
mAnimationDefinition{},
mLoadMethod(MotionDataLoadTask::LoadMethod::FACIAL_BUFFER)
{
{
case LoadMethod::BVH_FILE:
{
- mAnimationDefinition = std::move(Loader::LoadBvh(mFileUrl, "LoadedBvhMotionData", mScale));
+ mAnimationDefinition = std::move(Loader::LoadBvh(mFileUrl, "LoadedBvhMotionData", mUseRootTranslationOnly, mScale));
break;
}
case LoadMethod::BVH_BUFFER:
{
- mAnimationDefinition = std::move(Loader::LoadBvhFromBuffer(mRawBuffer, mRawBufferLength, "LoadedBvhMotionData", mScale));
+ mAnimationDefinition = std::move(Loader::LoadBvhFromBuffer(mRawBuffer, mRawBufferLength, "LoadedBvhMotionData", mUseRootTranslationOnly, mScale));
break;
}
case LoadMethod::FACIAL_FILE:
/**
* Constructor for load bvh from file.
*/
- MotionDataLoadTask(const std::string& path, const Vector3& scale, CallbackBase* callback);
+ MotionDataLoadTask(const std::string& path, bool useRootTranslationOnly, const Vector3& scale, CallbackBase* callback);
/**
* Constructor for load bvh from buffer.
*/
- MotionDataLoadTask(const uint8_t* rawBuffer, int rawBufferLength, const Vector3& scale, CallbackBase* callback);
+ MotionDataLoadTask(const uint8_t* rawBuffer, int rawBufferLength, bool useRootTranslationOnly, const Vector3& scale, CallbackBase* callback);
/**
* Constructor for load facial from file.
uint8_t* mRawBuffer;
int mRawBufferLength;
Vector3 mScale;
+ bool mUseRootTranslationOnly;
Scene3D::Loader::AnimationDefinition mAnimationDefinition;
LoadMethod mLoadMethod;
return parseHierarchy && parseMotion;
}
-AnimationDefinition GenerateAnimation(const std::string& animationName, std::shared_ptr<Joint>& hierarchy, uint32_t frameCount, float frameTime, const Vector3& scale)
+AnimationDefinition GenerateAnimation(const std::string& animationName, std::shared_ptr<Joint>& hierarchy, uint32_t frameCount, float frameTime, bool useRootTranslationOnly, const Vector3& scale)
{
AnimationDefinition animationDefinition;
if(!jointList.empty())
{
- animationDefinition.ReserveSize(jointList.size() * 2u); // translation and rotation
+ uint32_t animationSize = jointList.size();
+ animationSize = (useRootTranslationOnly) ? (animationSize + 1u) : (animationSize * 2u);
+ animationDefinition.ReserveSize(animationSize);
+ uint32_t animationIndex = 0u;
for(uint32_t i = 0; i < jointList.size(); ++i)
{
AnimatedProperty translationProperty;
- translationProperty.mTimePeriod = Dali::TimePeriod(animationDefinition.GetDuration());
- translationProperty.mNodeName = jointList[i]->name;
- translationProperty.mPropertyName = PROPERTY_NAME_POSITION.data();
+ if(!useRootTranslationOnly || i == 0)
+ {
+ translationProperty.mTimePeriod = Dali::TimePeriod(animationDefinition.GetDuration());
+ translationProperty.mNodeName = jointList[i]->name;
+ translationProperty.mPropertyName = PROPERTY_NAME_POSITION.data();
+ }
AnimatedProperty rotationProperty;
rotationProperty.mTimePeriod = Dali::TimePeriod(animationDefinition.GetDuration());
rotationProperty.mKeyFrames = Dali::KeyFrames::New();
for(uint32_t j = 0; j < frameCount; ++j)
{
- translationProperty.mKeyFrames.Add(static_cast<float>(j) * keyFrameInterval, (jointList[i]->translations[j] * scale));
+ if(!useRootTranslationOnly || i == 0)
+ {
+ translationProperty.mKeyFrames.Add(static_cast<float>(j) * keyFrameInterval, (jointList[i]->translations[j] * scale));
+ }
rotationProperty.mKeyFrames.Add(static_cast<float>(j) * keyFrameInterval, jointList[i]->rotations[j]);
}
- animationDefinition.SetProperty(i * 2u, std::move(translationProperty));
- animationDefinition.SetProperty(i * 2u + 1, std::move(rotationProperty));
+ if(!useRootTranslationOnly || i == 0)
+ {
+ animationDefinition.SetProperty(animationIndex++, std::move(translationProperty));
+ }
+ animationDefinition.SetProperty(animationIndex++, std::move(rotationProperty));
}
}
return animationDefinition;
}
-AnimationDefinition LoadBvhInternal(std::istream& stream, const std::string& animationName, const Vector3& scale)
+AnimationDefinition LoadBvhInternal(std::istream& stream, const std::string& animationName, bool useRootTranslationOnly, const Vector3& scale)
{
uint32_t frameCount = 0;
float frameTime = 0.0f;
return animationDefinition;
}
- return GenerateAnimation(animationName, rootJoint, frameCount, frameTime, scale);
+ return GenerateAnimation(animationName, rootJoint, frameCount, frameTime, useRootTranslationOnly, scale);
}
} // namespace
-AnimationDefinition LoadBvh(const std::string& path, const std::string& animationName, const Vector3& scale)
+AnimationDefinition LoadBvh(const std::string& path, const std::string& animationName, bool useRootTranslationOnly, const Vector3& scale)
{
Dali::FileStream fileStream(path);
std::iostream& stream = fileStream.GetStream();
return animationDefinition;
}
- return LoadBvhInternal(stream, animationName, scale);
+ return LoadBvhInternal(stream, animationName, useRootTranslationOnly, scale);
}
-AnimationDefinition LoadBvhFromBuffer(const uint8_t* rawBuffer, int rawBufferLength, const std::string& animationName, const Vector3& scale)
+AnimationDefinition LoadBvhFromBuffer(const uint8_t* rawBuffer, int rawBufferLength, const std::string& animationName, bool useRootTranslationOnly, const Vector3& scale)
{
if(rawBuffer == nullptr || rawBufferLength == 0)
{
return animationDefinition;
}
- return LoadBvhInternal(stream, animationName, scale);
+ return LoadBvhInternal(stream, animationName, useRootTranslationOnly, scale);
}
} // namespace Dali::Scene3D::Loader
\ No newline at end of file
* @SINCE_2_1.32
* @param[in] path The file path.
* @param[in] animationName Name of the motion capture animation
+ * @param[in] useRootTranslationOnly True to use only root translation with rotation animation.
* @param[in] scale The scale factor to set on the position property manually.
* @return AnimationDefinition that includes joint animation information.
*/
-DALI_SCENE3D_API AnimationDefinition LoadBvh(const std::string& path, const std::string& animationName, const Vector3& scale = Vector3::ONE);
+DALI_SCENE3D_API AnimationDefinition LoadBvh(const std::string& path, const std::string& animationName, bool useRootTranslationOnly, const Vector3& scale = Vector3::ONE);
/**
* @brief Loads motion capture data from bvh data stream.
* @param[in] rawBuffer The bvh buffer.
* @param[in] rawBufferLength The length of buffer.
* @param[in] animationName Name of the motion capture animation
+ * @param[in] useRootTranslationOnly True to use only root translation with rotation animation.
* @param[in] scale The scale factor to set on the position property manually.
* @return AnimationDefinition that includes joint animation information.
*/
-DALI_SCENE3D_API AnimationDefinition LoadBvhFromBuffer(const uint8_t* rawBuffer, int rawBufferLength, const std::string& animationName, const Vector3& scale = Vector3::ONE);
+DALI_SCENE3D_API AnimationDefinition LoadBvhFromBuffer(const uint8_t* rawBuffer, int rawBufferLength, const std::string& animationName, bool useRootTranslationOnly, const Vector3& scale = Vector3::ONE);
} // namespace Dali::Scene3D::Loader
void MotionData::LoadBvh(const std::string& path, const Vector3& scale, bool synchronousLoad)
{
- GetImplementation(*this).LoadBvh(path, scale, synchronousLoad);
+ GetImplementation(*this).LoadBvh(path, false, scale, synchronousLoad);
+}
+
+void MotionData::LoadBvh(const std::string& path, bool useRootTranslationOnly, const Vector3& scale, bool synchronousLoad)
+{
+ GetImplementation(*this).LoadBvh(path, useRootTranslationOnly, scale, synchronousLoad);
}
void MotionData::LoadBvhFromBuffer(const uint8_t* rawBuffer, int rawBufferLength, const Vector3& scale, bool synchronousLoad)
{
- GetImplementation(*this).LoadBvhFromBuffer(rawBuffer, rawBufferLength, scale, synchronousLoad);
+ GetImplementation(*this).LoadBvhFromBuffer(rawBuffer, rawBufferLength, false, scale, synchronousLoad);
+}
+
+void MotionData::LoadBvhFromBuffer(const uint8_t* rawBuffer, int rawBufferLength, bool useRootTranslationOnly, const Vector3& scale, bool synchronousLoad)
+{
+ GetImplementation(*this).LoadBvhFromBuffer(rawBuffer, rawBufferLength, useRootTranslationOnly, scale, synchronousLoad);
}
void MotionData::LoadFacialAnimation(const std::string& url, bool synchronousLoad)
void LoadBvh(const std::string& path, const Vector3& scale = Vector3::ONE, bool synchronousLoad = false);
/**
+ * @brief Load MotionData from bvh file.
+ * It will use Dali::Scene3D::Loader::LoadBvh() internally.
+ * LoadCompleteSignal() will be emitted after load completed.
+ *
+ * @SINCE_2_2.34
+ * @param[in] path The file path.
+ * @param[in] scale The scale factor to set on the position property manually.
+ * @param[in] useRootTranslationOnly True to use only root translation with rotation animation.
+ * @param[in] synchronousLoad True if we want to load result synchronously. Default is false.
+ */
+ void LoadBvh(const std::string& path, bool useRootTranslationOnly, const Vector3& scale = Vector3::ONE, bool synchronousLoad = false);
+
+ /**
* @brief Load MotionData from bvh buffer.
* It will use Dali::Scene3D::Loader::LoadBvhFromBuffer() internally.
* LoadCompleteSignal() will be emitted after load completed.
void LoadBvhFromBuffer(const uint8_t* rawBuffer, int rawBufferLength, const Vector3& scale = Vector3::ONE, bool synchronousLoad = false);
/**
+ * @brief Load MotionData from bvh buffer.
+ * It will use Dali::Scene3D::Loader::LoadBvhFromBuffer() internally.
+ * LoadCompleteSignal() will be emitted after load completed.
+ *
+ * @SINCE_2_2.34
+ * @param[in] rawBuffer The bvh buffer containing the facial animation as bvh format string.
+ * @param[in] rawBufferLength The length of buffer.
+ * @param[in] useRootTranslationOnly True to use only root translation with rotation animation.
+ * @param[in] scale The scale factor to set on the position property manually.
+ * @param[in] synchronousLoad True if we want to load result synchronously. Default is false.
+ */
+ void LoadBvhFromBuffer(const uint8_t* rawBuffer, int rawBufferLength, bool useRootTranslationOnly, const Vector3& scale = Vector3::ONE, bool synchronousLoad = false);
+
+ /**
* @brief Load MotionData from facial defined json file.
* It will use Dali::Scene3D::Loader::LoadFacialAnimation() internally.
* LoadCompleteSignal() will be emitted after load completed.