{LYN-2074} Add Animation data types Behavior for the scene graph (#253)

{LYN-2074} Add Animation data types Behavior for the scene graph  (#253)
* https://jira.agscollab.com/browse/LYN-2074

* moved scene API color to centeralized location
BlendShapeDataFace
BlendShapeData
This commit is contained in:
jackalbe
2021-04-26 12:08:43 -05:00
committed by GitHub
parent 2c437d7af4
commit a1685ecca9
8 changed files with 308 additions and 5 deletions
@@ -97,6 +97,9 @@ namespace AZ
};
} // DataTypes
} // SceneAPI
AZ_TYPE_INFO_SPECIALIZE(SceneAPI::DataTypes::Color, "{937E3BF8-5204-4D40-A8DA-C8F083C89F9F}");
} // AZ
namespace AZStd
@@ -11,6 +11,8 @@
*/
#include <SceneAPI/SceneData/GraphData/AnimationData.h>
#include <AzCore/Serialization/SerializeContext.h>
#include <AzCore/RTTI/BehaviorContext.h>
namespace AZ
{
@@ -18,6 +20,31 @@ namespace AZ
{
namespace GraphData
{
void AnimationData::Reflect(ReflectContext* context)
{
SerializeContext* serializeContext = azrtti_cast<SerializeContext*>(context);
if (serializeContext)
{
serializeContext->Class<AnimationData, SceneAPI::DataTypes::IAnimationData>()
->Version(1);
}
BehaviorContext* behaviorContext = azrtti_cast<BehaviorContext*>(context);
if (behaviorContext)
{
behaviorContext->Class<SceneAPI::DataTypes::IAnimationData>()
->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Common)
->Attribute(AZ::Script::Attributes::Module, "scene")
->Method("GetKeyFrameCount", &SceneAPI::DataTypes::IAnimationData::GetKeyFrameCount)
->Method("GetKeyFrame", &SceneAPI::DataTypes::IAnimationData::GetKeyFrame)
->Method("GetTimeStepBetweenFrames", &SceneAPI::DataTypes::IAnimationData::GetTimeStepBetweenFrames);
behaviorContext->Class<AnimationData>()
->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Common)
->Attribute(AZ::Script::Attributes::Module, "scene");
}
}
AnimationData::AnimationData()
: m_timeStepBetweenFrames(1.0/30.0) // default value
{
@@ -61,6 +88,32 @@ namespace AZ
}
void BlendShapeAnimationData::Reflect(ReflectContext* context)
{
SerializeContext* serializeContext = azrtti_cast<SerializeContext*>(context);
if (serializeContext)
{
serializeContext->Class<BlendShapeAnimationData, SceneAPI::DataTypes::IBlendShapeAnimationData>()
->Version(1);
}
BehaviorContext* behaviorContext = azrtti_cast<BehaviorContext*>(context);
if (behaviorContext)
{
behaviorContext->Class<SceneAPI::DataTypes::IBlendShapeAnimationData>()
->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Common)
->Attribute(AZ::Script::Attributes::Module, "scene")
->Method("GetBlendShapeName", &SceneAPI::DataTypes::IBlendShapeAnimationData::GetBlendShapeName)
->Method("GetKeyFrameCount", &SceneAPI::DataTypes::IBlendShapeAnimationData::GetKeyFrameCount)
->Method("GetKeyFrame", &SceneAPI::DataTypes::IBlendShapeAnimationData::GetKeyFrame)
->Method("GetTimeStepBetweenFrames", &SceneAPI::DataTypes::IBlendShapeAnimationData::GetTimeStepBetweenFrames);
behaviorContext->Class<BlendShapeAnimationData>()
->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Common)
->Attribute(AZ::Script::Attributes::Module, "scene");
}
}
BlendShapeAnimationData::BlendShapeAnimationData()
: m_timeStepBetweenFrames(1 / 30.0) // default value
{
@@ -30,6 +30,8 @@ namespace AZ
public:
AZ_RTTI(AnimationData, "{D350732E-4727-41C8-95E0-FBAF5F2AC074}", SceneAPI::DataTypes::IAnimationData);
static void Reflect(ReflectContext* context);
SCENE_DATA_API AnimationData();
SCENE_DATA_API ~AnimationData() override = default;
SCENE_DATA_API virtual void AddKeyFrame(const SceneAPI::DataTypes::MatrixType& keyFrameTransform);
@@ -53,6 +55,8 @@ namespace AZ
public:
AZ_RTTI(BlendShapeAnimationData, "{02766CCF-BDA7-46B6-9BB1-58A90C1AD6AA}", SceneAPI::DataTypes::IBlendShapeAnimationData);
static void Reflect(ReflectContext* context);
SCENE_DATA_API BlendShapeAnimationData();
SCENE_DATA_API ~BlendShapeAnimationData() override = default;
SCENE_DATA_API void CloneAttributesFrom(const IGraphObject* sourceObject) override;
@@ -12,9 +12,13 @@
#include <AzCore/Casting/numeric_cast.h>
#include <SceneAPI/SceneData/GraphData/BlendShapeData.h>
#include <AzCore/Serialization/SerializeContext.h>
#include <AzCore/RTTI/BehaviorContext.h>
namespace AZ
{
AZ_TYPE_INFO_SPECIALIZE(SceneAPI::DataTypes::IBlendShapeData::Face, "{C972EC9A-3A5C-47CD-9A92-ECB4C0C0451C}");
namespace SceneData
{
namespace GraphData
@@ -23,6 +27,82 @@ namespace AZ
BlendShapeData::~BlendShapeData() = default;
void BlendShapeData::Reflect(ReflectContext* context)
{
SerializeContext* serializeContext = azrtti_cast<SerializeContext*>(context);
if (serializeContext)
{
serializeContext->Class<BlendShapeData, SceneAPI::DataTypes::IBlendShapeData>()
->Version(1);
}
BehaviorContext* behaviorContext = azrtti_cast<BehaviorContext*>(context);
if (behaviorContext)
{
behaviorContext->Class<SceneAPI::DataTypes::IBlendShapeData>()
->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Common)
->Attribute(AZ::Script::Attributes::Module, "scene")
->Method("GetUsedControlPointCount", &SceneAPI::DataTypes::IBlendShapeData::GetUsedControlPointCount)
->Method("GetControlPointIndex", &SceneAPI::DataTypes::IBlendShapeData::GetControlPointIndex)
->Method("GetUsedPointIndexForControlPoint", &SceneAPI::DataTypes::IBlendShapeData::GetUsedPointIndexForControlPoint)
->Method("GetVertexCount", &SceneAPI::DataTypes::IBlendShapeData::GetVertexCount)
->Method("GetFaceCount", &SceneAPI::DataTypes::IBlendShapeData::GetFaceCount)
->Method("GetFaceInfo", &SceneAPI::DataTypes::IBlendShapeData::GetFaceInfo)
->Method("GetPosition", &SceneAPI::DataTypes::IBlendShapeData::GetPosition)
->Method("GetNormal", &SceneAPI::DataTypes::IBlendShapeData::GetNormal)
->Method("GetFaceVertexIndex", &SceneAPI::DataTypes::IBlendShapeData::GetFaceVertexIndex);
behaviorContext->Class<SceneAPI::DataTypes::IBlendShapeData::Face>("BlendShapeDataFace")
->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Common)
->Attribute(AZ::Script::Attributes::Module, "scene")
->Method("GetVertexIndex", [](const SceneAPI::DataTypes::IBlendShapeData::Face& self, int index)
{
if (index >= 0 && index < 3)
{
return self.vertexIndex[index];
}
return aznumeric_cast<unsigned int>(0);
});
behaviorContext->Class<BlendShapeData>()
->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Common)
->Attribute(AZ::Script::Attributes::Module, "scene")
->Method("GetUV", &BlendShapeData::GetUV)
->Method("GetTangent", [](const BlendShapeData& self, size_t index)
{
if (index < self.GetTangents().size())
{
return self.GetTangents().at(index);
}
AZ_Error("SceneGraphData", false, "Cannot get to tangent at index(%zu)", index);
return Vector4::CreateZero();
})
->Method("GetBitangent", [](const BlendShapeData& self, size_t index)
{
if (index < self.GetBitangents().size())
{
return self.GetBitangents().at(index);
}
AZ_Error("SceneGraphData", false, "Cannot get to bitangents at index(%zu)", index);
return Vector3::CreateZero();
})
->Method("GetColor", [](const BlendShapeData& self, AZ::u8 colorSetIndex, AZ::u8 colorIndex)
{
SceneAPI::DataTypes::Color color(0,0,0,0);
if (colorSetIndex < MaxNumColorSets)
{
const AZStd::vector<SceneAPI::DataTypes::Color>& colorChannel = self.GetColors(colorSetIndex);
if (colorIndex < colorChannel.size())
{
return colorChannel[colorIndex];
}
}
AZ_Error("SceneGraphData", false, "Cannot get to color setIndex(%d) at colorIndex(%d)", colorSetIndex, colorIndex);
return color;
});
}
}
void BlendShapeData::AddPosition(const Vector3& position)
{
m_positions.push_back(position);
@@ -31,6 +31,8 @@ namespace AZ
public:
AZ_RTTI(BlendShapeData, "{FF875C22-2E4F-4CE3-BA49-09BF78C70A09}", SceneAPI::DataTypes::IBlendShapeData)
SCENE_DATA_API static void Reflect(ReflectContext* context);
// Maximum number of color sets matches limitation set in assImp (AI_MAX_NUMBER_OF_COLOR_SETS)
static constexpr AZ::u8 MaxNumColorSets = 8;
// Maximum number of uv sets matches limitation set in assImp (AI_MAX_NUMBER_OF_TEXTURECOORDS)
@@ -16,8 +16,6 @@
namespace AZ
{
AZ_TYPE_INFO_SPECIALIZE(SceneAPI::DataTypes::Color, "{937E3BF8-5204-4D40-A8DA-C8F083C89F9F}");
namespace SceneData
{
namespace GraphData
@@ -40,7 +38,7 @@ namespace AZ
->Method("GetCount", &MeshVertexColorData::GetCount )
->Method("GetColor", &MeshVertexColorData::GetColor);
behaviorContext->Class<AZ::SceneAPI::DataTypes::Color>("MeshVertexColor")
behaviorContext->Class<AZ::SceneAPI::DataTypes::Color>("VertexColor")
->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Common)
->Attribute(AZ::Script::Attributes::Module, "scene")
->Property("red", BehaviorValueGetter(&AZ::SceneAPI::DataTypes::Color::red), nullptr)
@@ -81,8 +81,9 @@ namespace AZ
SceneData::SceneNodeSelectionList::Reflect(context);
// Graph objects
context->Class<AZ::SceneData::GraphData::AnimationData>()->Version(1);
context->Class<AZ::SceneData::GraphData::BlendShapeData>()->Version(1);
AZ::SceneData::GraphData::AnimationData::Reflect(context);
AZ::SceneData::GraphData::BlendShapeAnimationData::Reflect(context);
AZ::SceneData::GraphData::BlendShapeData::Reflect(context);
AZ::SceneData::GraphData::BoneData::Reflect(context);
AZ::SceneData::GraphData::MaterialData::Reflect(context);
AZ::SceneData::GraphData::MeshData::Reflect(context);
@@ -107,6 +108,9 @@ namespace AZ
AZ::SceneData::GraphData::MeshVertexUVData::Reflect(context);
AZ::SceneData::GraphData::MeshVertexTangentData::Reflect(context);
AZ::SceneData::GraphData::MeshVertexBitangentData::Reflect(context);
AZ::SceneData::GraphData::AnimationData::Reflect(context);
AZ::SceneData::GraphData::BlendShapeAnimationData::Reflect(context);
AZ::SceneData::GraphData::BlendShapeData::Reflect(context);
}
} // namespace SceneAPI
} // namespace AZ
@@ -29,6 +29,8 @@
#include <SceneAPI/SceneData/GraphData/MeshVertexColorData.h>
#include <SceneAPI/SceneData/GraphData/MeshVertexTangentData.h>
#include <SceneAPI/SceneData/GraphData/MeshVertexUVData.h>
#include <SceneAPI/SceneData/GraphData/AnimationData.h>
#include <SceneAPI/SceneData/GraphData/BlendShapeData.h>
namespace AZ
{
@@ -101,6 +103,53 @@ namespace AZ
tangentData->SetTangentSetIndex(2);
return true;
}
else if (data.get_type_info().m_id == azrtti_typeid<AZ::SceneData::GraphData::AnimationData>())
{
auto* animationData = AZStd::any_cast<AZ::SceneData::GraphData::AnimationData>(&data);
animationData->ReserveKeyFrames(3);
animationData->AddKeyFrame(DataTypes::MatrixType::CreateFromValue(1.0));
animationData->AddKeyFrame(DataTypes::MatrixType::CreateFromValue(2.0));
animationData->AddKeyFrame(DataTypes::MatrixType::CreateFromValue(3.0));
animationData->SetTimeStepBetweenFrames(4.0);
return true;
}
else if (data.get_type_info().m_id == azrtti_typeid<AZ::SceneData::GraphData::BlendShapeAnimationData>())
{
auto* blendShapeAnimationData = AZStd::any_cast<AZ::SceneData::GraphData::BlendShapeAnimationData>(&data);
blendShapeAnimationData->SetBlendShapeName("mockBlendShapeName");
blendShapeAnimationData->ReserveKeyFrames(3);
blendShapeAnimationData->AddKeyFrame(1.0);
blendShapeAnimationData->AddKeyFrame(2.0);
blendShapeAnimationData->AddKeyFrame(3.0);
blendShapeAnimationData->SetTimeStepBetweenFrames(4.0);
return true;
}
else if (data.get_type_info().m_id == azrtti_typeid<AZ::SceneData::GraphData::BlendShapeData>())
{
auto* blendShapeData = AZStd::any_cast<AZ::SceneData::GraphData::BlendShapeData>(&data);
blendShapeData->AddPosition({ 1.0, 2.0, 3.0 });
blendShapeData->AddPosition({ 2.0, 3.0, 4.0 });
blendShapeData->AddPosition({ 3.0, 4.0, 5.0 });
blendShapeData->AddNormal({ 0.1, 0.2, 0.3 });
blendShapeData->AddNormal({ 0.2, 0.3, 0.4 });
blendShapeData->AddNormal({ 0.3, 0.4, 0.5 });
blendShapeData->AddTangentAndBitangent(Vector4{ 0.1f, 0.2f, 0.3f, 0.4f }, { 0.0, 0.1, 0.2 });
blendShapeData->AddTangentAndBitangent(Vector4{ 0.2f, 0.3f, 0.4f, 0.5f }, { 0.1, 0.2, 0.3 });
blendShapeData->AddTangentAndBitangent(Vector4{ 0.3f, 0.4f, 0.5f, 0.6f }, { 0.2, 0.3, 0.4 });
blendShapeData->AddUV(Vector2{ 0.9, 0.8 }, 0);
blendShapeData->AddUV(Vector2{ 0.7, 0.7 }, 1);
blendShapeData->AddUV(Vector2{ 0.6, 0.6 }, 2);
blendShapeData->AddColor(DataTypes::Color{ 0.1, 0.2, 0.3, 0.4 }, 0);
blendShapeData->AddColor(DataTypes::Color{ 0.2, 0.3, 0.4, 0.5 }, 1);
blendShapeData->AddColor(DataTypes::Color{ 0.3, 0.4, 0.5, 0.6 }, 2);
blendShapeData->AddFace({ 0, 1, 2 });
blendShapeData->AddFace({ 1, 2, 0 });
blendShapeData->AddFace({ 2, 0, 1 });
blendShapeData->SetVertexIndexToControlPointIndexMap(0, 1);
blendShapeData->SetVertexIndexToControlPointIndexMap(1, 2);
blendShapeData->SetVertexIndexToControlPointIndexMap(2, 0);
return true;
}
return false;
}
@@ -296,6 +345,116 @@ namespace AZ
ExpectExecute("TestExpectIntegerEquals(meshVertexTangentData:GetTangentSetIndex(), 2)");
ExpectExecute("TestExpectTrue(meshVertexTangentData:GetTangentSpace(), MeshVertexTangentData.EMotionFX)");
}
TEST_F(GrapDatahBehaviorScriptTest, SceneGraph_AnimationData_AccessWorks)
{
ExpectExecute("animationData = AnimationData()");
ExpectExecute("TestExpectTrue(animationData ~= nil)");
ExpectExecute("MockGraphData.FillData(animationData)");
ExpectExecute("TestExpectIntegerEquals(animationData:GetKeyFrameCount(), 3)");
ExpectExecute("TestExpectFloatEquals(animationData:GetTimeStepBetweenFrames(), 4.0)");
ExpectExecute("TestExpectFloatEquals(animationData:GetKeyFrame(0).basisX.x, 1.0)");
ExpectExecute("TestExpectFloatEquals(animationData:GetKeyFrame(1).basisX.y, 2.0)");
ExpectExecute("TestExpectFloatEquals(animationData:GetKeyFrame(2).basisX.z, 3.0)");
}
TEST_F(GrapDatahBehaviorScriptTest, SceneGraph_BlendShapeAnimationData_AccessWorks)
{
ExpectExecute("blendShapeAnimationData = BlendShapeAnimationData()");
ExpectExecute("TestExpectTrue(blendShapeAnimationData ~= nil)");
ExpectExecute("MockGraphData.FillData(blendShapeAnimationData)");
ExpectExecute("TestExpectTrue(blendShapeAnimationData:GetBlendShapeName() == 'mockBlendShapeName')");
ExpectExecute("TestExpectIntegerEquals(blendShapeAnimationData:GetKeyFrameCount(), 3)");
ExpectExecute("TestExpectFloatEquals(blendShapeAnimationData:GetKeyFrame(0), 1.0)");
ExpectExecute("TestExpectFloatEquals(blendShapeAnimationData:GetKeyFrame(1), 2.0)");
ExpectExecute("TestExpectFloatEquals(blendShapeAnimationData:GetKeyFrame(2), 3.0)");
ExpectExecute("TestExpectFloatEquals(blendShapeAnimationData:GetTimeStepBetweenFrames(), 4.0)");
}
TEST_F(GrapDatahBehaviorScriptTest, SceneGraph_BlendShapeData_AccessWorks)
{
ExpectExecute("blendShapeData = BlendShapeData()");
ExpectExecute("TestExpectTrue(blendShapeData ~= nil)");
ExpectExecute("MockGraphData.FillData(blendShapeData)");
ExpectExecute("TestExpectIntegerEquals(blendShapeData:GetUsedControlPointCount(), 3)");
ExpectExecute("TestExpectIntegerEquals(blendShapeData:GetVertexCount(), 3)");
ExpectExecute("TestExpectIntegerEquals(blendShapeData:GetFaceCount(), 3)");
ExpectExecute("TestExpectIntegerEquals(blendShapeData:GetFaceVertexIndex(0, 2), 2)");
ExpectExecute("TestExpectIntegerEquals(blendShapeData:GetFaceVertexIndex(1, 0), 1)");
ExpectExecute("TestExpectIntegerEquals(blendShapeData:GetFaceVertexIndex(2, 1), 0)");
ExpectExecute("TestExpectIntegerEquals(blendShapeData:GetControlPointIndex(0), 1)");
ExpectExecute("TestExpectIntegerEquals(blendShapeData:GetControlPointIndex(1), 2)");
ExpectExecute("TestExpectIntegerEquals(blendShapeData:GetControlPointIndex(2), 0)");
ExpectExecute("TestExpectIntegerEquals(blendShapeData:GetUsedPointIndexForControlPoint(0), 2)");
ExpectExecute("TestExpectIntegerEquals(blendShapeData:GetUsedPointIndexForControlPoint(1), 0)");
ExpectExecute("TestExpectIntegerEquals(blendShapeData:GetUsedPointIndexForControlPoint(2), 1)");
ExpectExecute("TestExpectFloatEquals(blendShapeData:GetPosition(0).x, 1.0)");
ExpectExecute("TestExpectFloatEquals(blendShapeData:GetPosition(0).y, 2.0)");
ExpectExecute("TestExpectFloatEquals(blendShapeData:GetPosition(0).z, 3.0)");
ExpectExecute("TestExpectFloatEquals(blendShapeData:GetPosition(1).x, 2.0)");
ExpectExecute("TestExpectFloatEquals(blendShapeData:GetPosition(1).y, 3.0)");
ExpectExecute("TestExpectFloatEquals(blendShapeData:GetPosition(1).z, 4.0)");
ExpectExecute("TestExpectFloatEquals(blendShapeData:GetPosition(2).x, 3.0)");
ExpectExecute("TestExpectFloatEquals(blendShapeData:GetPosition(2).y, 4.0)");
ExpectExecute("TestExpectFloatEquals(blendShapeData:GetPosition(2).z, 5.0)");
ExpectExecute("TestExpectFloatEquals(blendShapeData:GetNormal(0).x, 0.1)");
ExpectExecute("TestExpectFloatEquals(blendShapeData:GetNormal(0).y, 0.2)");
ExpectExecute("TestExpectFloatEquals(blendShapeData:GetNormal(0).z, 0.3)");
ExpectExecute("TestExpectFloatEquals(blendShapeData:GetNormal(1).x, 0.2)");
ExpectExecute("TestExpectFloatEquals(blendShapeData:GetNormal(1).y, 0.3)");
ExpectExecute("TestExpectFloatEquals(blendShapeData:GetNormal(1).z, 0.4)");
ExpectExecute("TestExpectFloatEquals(blendShapeData:GetNormal(2).x, 0.3)");
ExpectExecute("TestExpectFloatEquals(blendShapeData:GetNormal(2).y, 0.4)");
ExpectExecute("TestExpectFloatEquals(blendShapeData:GetNormal(2).z, 0.5)");
ExpectExecute("TestExpectFloatEquals(blendShapeData:GetFaceInfo(0):GetVertexIndex(0), 0)");
ExpectExecute("TestExpectFloatEquals(blendShapeData:GetFaceInfo(0):GetVertexIndex(1), 1)");
ExpectExecute("TestExpectFloatEquals(blendShapeData:GetFaceInfo(0):GetVertexIndex(2), 2)");
ExpectExecute("TestExpectFloatEquals(blendShapeData:GetFaceInfo(1):GetVertexIndex(0), 1)");
ExpectExecute("TestExpectFloatEquals(blendShapeData:GetFaceInfo(1):GetVertexIndex(1), 2)");
ExpectExecute("TestExpectFloatEquals(blendShapeData:GetFaceInfo(1):GetVertexIndex(2), 0)");
ExpectExecute("TestExpectFloatEquals(blendShapeData:GetFaceInfo(2):GetVertexIndex(0), 2)");
ExpectExecute("TestExpectFloatEquals(blendShapeData:GetFaceInfo(2):GetVertexIndex(1), 0)");
ExpectExecute("TestExpectFloatEquals(blendShapeData:GetFaceInfo(2):GetVertexIndex(2), 1)");
ExpectExecute("TestExpectFloatEquals(blendShapeData:GetUV(0, 0).x, 0.9)");
ExpectExecute("TestExpectFloatEquals(blendShapeData:GetUV(0, 0).y, 0.8)");
ExpectExecute("TestExpectFloatEquals(blendShapeData:GetUV(0, 1).x, 0.7)");
ExpectExecute("TestExpectFloatEquals(blendShapeData:GetUV(0, 1).y, 0.7)");
ExpectExecute("TestExpectFloatEquals(blendShapeData:GetUV(0, 2).x, 0.6)");
ExpectExecute("TestExpectFloatEquals(blendShapeData:GetUV(0, 2).y, 0.6)");
ExpectExecute("TestExpectFloatEquals(blendShapeData:GetColor(0, 0).red, 0.1)");
ExpectExecute("TestExpectFloatEquals(blendShapeData:GetColor(0, 0).green, 0.2)");
ExpectExecute("TestExpectFloatEquals(blendShapeData:GetColor(0, 0).blue, 0.3)");
ExpectExecute("TestExpectFloatEquals(blendShapeData:GetColor(0, 0).alpha, 0.4)");
ExpectExecute("TestExpectFloatEquals(blendShapeData:GetColor(1, 0).red, 0.2)");
ExpectExecute("TestExpectFloatEquals(blendShapeData:GetColor(1, 0).green, 0.3)");
ExpectExecute("TestExpectFloatEquals(blendShapeData:GetColor(1, 0).blue, 0.4)");
ExpectExecute("TestExpectFloatEquals(blendShapeData:GetColor(1, 0).alpha, 0.5)");
ExpectExecute("TestExpectFloatEquals(blendShapeData:GetColor(2, 0).red, 0.3)");
ExpectExecute("TestExpectFloatEquals(blendShapeData:GetColor(2, 0).green, 0.4)");
ExpectExecute("TestExpectFloatEquals(blendShapeData:GetColor(2, 0).blue, 0.5)");
ExpectExecute("TestExpectFloatEquals(blendShapeData:GetColor(2, 0).alpha, 0.6)");
ExpectExecute("TestExpectFloatEquals(blendShapeData:GetTangent(0).x, 0.1)");
ExpectExecute("TestExpectFloatEquals(blendShapeData:GetTangent(0).y, 0.2)");
ExpectExecute("TestExpectFloatEquals(blendShapeData:GetTangent(0).z, 0.3)");
ExpectExecute("TestExpectFloatEquals(blendShapeData:GetTangent(0).w, 0.4)");
ExpectExecute("TestExpectFloatEquals(blendShapeData:GetTangent(1).x, 0.2)");
ExpectExecute("TestExpectFloatEquals(blendShapeData:GetTangent(1).y, 0.3)");
ExpectExecute("TestExpectFloatEquals(blendShapeData:GetTangent(1).z, 0.4)");
ExpectExecute("TestExpectFloatEquals(blendShapeData:GetTangent(1).w, 0.5)");
ExpectExecute("TestExpectFloatEquals(blendShapeData:GetTangent(2).x, 0.3)");
ExpectExecute("TestExpectFloatEquals(blendShapeData:GetTangent(2).y, 0.4)");
ExpectExecute("TestExpectFloatEquals(blendShapeData:GetTangent(2).z, 0.5)");
ExpectExecute("TestExpectFloatEquals(blendShapeData:GetTangent(2).w, 0.6)");
ExpectExecute("TestExpectFloatEquals(blendShapeData:GetBitangent(0).x, 0.0)");
ExpectExecute("TestExpectFloatEquals(blendShapeData:GetBitangent(0).y, 0.1)");
ExpectExecute("TestExpectFloatEquals(blendShapeData:GetBitangent(0).z, 0.2)");
ExpectExecute("TestExpectFloatEquals(blendShapeData:GetBitangent(1).x, 0.1)");
ExpectExecute("TestExpectFloatEquals(blendShapeData:GetBitangent(1).y, 0.2)");
ExpectExecute("TestExpectFloatEquals(blendShapeData:GetBitangent(1).z, 0.3)");
ExpectExecute("TestExpectFloatEquals(blendShapeData:GetBitangent(2).x, 0.2)");
ExpectExecute("TestExpectFloatEquals(blendShapeData:GetBitangent(2).y, 0.3)");
ExpectExecute("TestExpectFloatEquals(blendShapeData:GetBitangent(2).z, 0.4)");
}
}
}
}