Added new pose to blend with the animation
This commit is contained in:
parent
b7a1685166
commit
4284ebb0e1
|
@ -18,17 +18,25 @@ namespace client {
|
|||
}
|
||||
}
|
||||
|
||||
void Walker::ApplyControl(const BoneControlIn &bone_control) {
|
||||
GetEpisode().Lock()->ApplyBoneControlToWalker(*this, bone_control);
|
||||
}
|
||||
|
||||
Walker::Control Walker::GetWalkerControl() const {
|
||||
return GetEpisode().Lock()->GetActorSnapshot(*this).state.walker_control;
|
||||
}
|
||||
|
||||
// Walker::Control Walker::GetBonesTransform() const {
|
||||
Walker::BoneControlOut Walker::GetBonesTransform() {
|
||||
return GetEpisode().Lock()->GetBonesTransform(*this);
|
||||
}
|
||||
|
||||
void Walker::SetBonesTransform(const Walker::BoneControlIn &bones) {
|
||||
return GetEpisode().Lock()->SetBonesTransform(*this, bones);
|
||||
}
|
||||
|
||||
void Walker::BlendPose(float blend) {
|
||||
return GetEpisode().Lock()->BlendPose(*this, blend);
|
||||
}
|
||||
|
||||
void Walker::GetPoseFromAnimation() {
|
||||
return GetEpisode().Lock()->GetPoseFromAnimation(*this);
|
||||
}
|
||||
|
||||
} // namespace client
|
||||
} // namespace carla
|
||||
|
|
|
@ -26,16 +26,18 @@ namespace client {
|
|||
/// Apply @a control to this Walker.
|
||||
void ApplyControl(const Control &control);
|
||||
|
||||
void ApplyControl(const BoneControlIn &bone_control);
|
||||
|
||||
/// Return the control last applied to this Walker.
|
||||
///
|
||||
/// @note This function does not call the simulator, it returns the Control
|
||||
/// received in the last tick.
|
||||
Control GetWalkerControl() const;
|
||||
|
||||
// Walker::Control GetBonesTransform() const;
|
||||
BoneControlOut GetBonesTransform();
|
||||
void SetBonesTransform(const BoneControlIn &bones);
|
||||
void BlendPose(float blend);
|
||||
void ShowPose() { BlendPose(1.0f); };
|
||||
void HidePose() { BlendPose(0.0f); };
|
||||
void GetPoseFromAnimation();
|
||||
|
||||
private:
|
||||
|
||||
|
|
|
@ -436,15 +436,23 @@ namespace detail {
|
|||
_pimpl->AsyncCall("apply_control_to_walker", walker, control);
|
||||
}
|
||||
|
||||
void Client::ApplyBoneControlToWalker(rpc::ActorId walker, const rpc::WalkerBoneControlIn &control) {
|
||||
_pimpl->AsyncCall("apply_bone_control_to_walker", walker, control);
|
||||
}
|
||||
|
||||
rpc::WalkerBoneControlOut Client::GetBonesTransform(rpc::ActorId walker) {
|
||||
auto res = _pimpl->CallAndWait<rpc::WalkerBoneControlOut>("get_bones_transform", walker);
|
||||
return res;
|
||||
}
|
||||
|
||||
void Client::SetBonesTransform(rpc::ActorId walker, const rpc::WalkerBoneControlIn &bones) {
|
||||
_pimpl->AsyncCall("set_bones_transform", walker, bones);
|
||||
}
|
||||
|
||||
void Client::BlendPose(rpc::ActorId walker, float blend) {
|
||||
_pimpl->AsyncCall("blend_pose", walker, blend);
|
||||
}
|
||||
|
||||
void Client::GetPoseFromAnimation(rpc::ActorId walker) {
|
||||
_pimpl->AsyncCall("get_pose_from_animation", walker);
|
||||
}
|
||||
|
||||
void Client::SetTrafficLightState(
|
||||
rpc::ActorId traffic_light,
|
||||
const rpc::TrafficLightState traffic_light_state) {
|
||||
|
|
|
@ -268,13 +268,20 @@ namespace detail {
|
|||
rpc::ActorId walker,
|
||||
const rpc::WalkerControl &control);
|
||||
|
||||
void ApplyBoneControlToWalker(
|
||||
rpc::ActorId walker,
|
||||
const rpc::WalkerBoneControlIn &control);
|
||||
|
||||
rpc::WalkerBoneControlOut GetBonesTransform(
|
||||
rpc::ActorId walker);
|
||||
|
||||
void SetBonesTransform(
|
||||
rpc::ActorId walker,
|
||||
const rpc::WalkerBoneControlIn &bones);
|
||||
|
||||
void BlendPose(
|
||||
rpc::ActorId walker,
|
||||
float blend);
|
||||
|
||||
void GetPoseFromAnimation(
|
||||
rpc::ActorId walker);
|
||||
|
||||
void SetTrafficLightState(
|
||||
rpc::ActorId traffic_light,
|
||||
const rpc::TrafficLightState trafficLightState);
|
||||
|
|
|
@ -457,14 +457,22 @@ namespace detail {
|
|||
_client.ApplyControlToWalker(walker.GetId(), control);
|
||||
}
|
||||
|
||||
void ApplyBoneControlToWalker(Walker &walker, const rpc::WalkerBoneControlIn &control) {
|
||||
_client.ApplyBoneControlToWalker(walker.GetId(), control);
|
||||
}
|
||||
|
||||
rpc::WalkerBoneControlOut GetBonesTransform(Walker &walker) {
|
||||
return _client.GetBonesTransform(walker.GetId());
|
||||
}
|
||||
|
||||
void SetBonesTransform(Walker &walker, const rpc::WalkerBoneControlIn &bones) {
|
||||
return _client.SetBonesTransform(walker.GetId(), bones);
|
||||
}
|
||||
|
||||
void BlendPose(Walker &walker, float blend) {
|
||||
return _client.BlendPose(walker.GetId(), blend);
|
||||
}
|
||||
|
||||
void GetPoseFromAnimation(Walker &walker) {
|
||||
return _client.GetPoseFromAnimation(walker.GetId());
|
||||
}
|
||||
|
||||
void ApplyPhysicsControlToVehicle(Vehicle &vehicle, const rpc::VehiclePhysicsControl &physicsControl) {
|
||||
_client.ApplyPhysicsControlToVehicle(vehicle.GetId(), physicsControl);
|
||||
}
|
||||
|
|
|
@ -191,6 +191,11 @@ void export_actor() {
|
|||
.def("apply_control", &ApplyControl<cr::WalkerBoneControlIn>, (arg("control")))
|
||||
.def("get_control", &cc::Walker::GetWalkerControl)
|
||||
.def("get_bones", &cc::Walker::GetBonesTransform)
|
||||
.def("set_bones", &cc::Walker::SetBonesTransform, (arg("bones")))
|
||||
.def("blend_pose", &cc::Walker::BlendPose, (arg("blend")))
|
||||
.def("show_pose", &cc::Walker::ShowPose)
|
||||
.def("hide_pose", &cc::Walker::HidePose)
|
||||
.def("get_pose_from_animation", &cc::Walker::GetPoseFromAnimation)
|
||||
.def(self_ns::str(self_ns::self))
|
||||
;
|
||||
|
||||
|
|
|
@ -1248,29 +1248,6 @@ ECarlaServerResponse FWalkerActor::ApplyControlToWalker(
|
|||
return ECarlaServerResponse::Success;
|
||||
}
|
||||
|
||||
ECarlaServerResponse FWalkerActor::ApplyBoneControlToWalker(
|
||||
const FWalkerBoneControlIn& Control)
|
||||
{
|
||||
if (IsDormant())
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
auto Pawn = Cast<APawn>(GetActor());
|
||||
if (Pawn == nullptr)
|
||||
{
|
||||
return ECarlaServerResponse::NotAWalker;
|
||||
}
|
||||
auto Controller = Cast<AWalkerController>(Pawn->GetController());
|
||||
if (Controller == nullptr)
|
||||
{
|
||||
return ECarlaServerResponse::WalkerIncompatibleController;
|
||||
}
|
||||
Controller->ApplyWalkerControl(Control);
|
||||
}
|
||||
return ECarlaServerResponse::Success;
|
||||
}
|
||||
|
||||
ECarlaServerResponse FWalkerActor::GetBonesTransform(FWalkerBoneControlOut& Bones)
|
||||
{
|
||||
if (IsDormant())
|
||||
|
@ -1292,3 +1269,69 @@ ECarlaServerResponse FWalkerActor::GetBonesTransform(FWalkerBoneControlOut& Bone
|
|||
}
|
||||
return ECarlaServerResponse::Success;
|
||||
}
|
||||
|
||||
ECarlaServerResponse FWalkerActor::SetBonesTransform(const FWalkerBoneControlIn& Bones)
|
||||
{
|
||||
if (IsDormant())
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
auto Pawn = Cast<APawn>(GetActor());
|
||||
if (Pawn == nullptr)
|
||||
{
|
||||
return ECarlaServerResponse::NotAWalker;
|
||||
}
|
||||
auto Controller = Cast<AWalkerController>(Pawn->GetController());
|
||||
if (Controller == nullptr)
|
||||
{
|
||||
return ECarlaServerResponse::WalkerIncompatibleController;
|
||||
}
|
||||
Controller->SetBonesTransform(Bones);
|
||||
}
|
||||
return ECarlaServerResponse::Success;
|
||||
}
|
||||
|
||||
ECarlaServerResponse FWalkerActor::BlendPose(float Blend)
|
||||
{
|
||||
if (IsDormant())
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
auto Pawn = Cast<APawn>(GetActor());
|
||||
if (Pawn == nullptr)
|
||||
{
|
||||
return ECarlaServerResponse::NotAWalker;
|
||||
}
|
||||
auto Controller = Cast<AWalkerController>(Pawn->GetController());
|
||||
if (Controller == nullptr)
|
||||
{
|
||||
return ECarlaServerResponse::WalkerIncompatibleController;
|
||||
}
|
||||
Controller->BlendPose(Blend);
|
||||
}
|
||||
return ECarlaServerResponse::Success;
|
||||
}
|
||||
|
||||
ECarlaServerResponse FWalkerActor::GetPoseFromAnimation()
|
||||
{
|
||||
if (IsDormant())
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
auto Pawn = Cast<APawn>(GetActor());
|
||||
if (Pawn == nullptr)
|
||||
{
|
||||
return ECarlaServerResponse::NotAWalker;
|
||||
}
|
||||
auto Controller = Cast<AWalkerController>(Pawn->GetController());
|
||||
if (Controller == nullptr)
|
||||
{
|
||||
return ECarlaServerResponse::WalkerIncompatibleController;
|
||||
}
|
||||
Controller->GetPoseFromAnimation();
|
||||
}
|
||||
return ECarlaServerResponse::Success;
|
||||
}
|
||||
|
|
|
@ -367,12 +367,22 @@ public:
|
|||
return ECarlaServerResponse::ActorTypeMismatch;
|
||||
}
|
||||
|
||||
virtual ECarlaServerResponse ApplyBoneControlToWalker(const FWalkerBoneControlIn&)
|
||||
virtual ECarlaServerResponse GetBonesTransform(FWalkerBoneControlOut&)
|
||||
{
|
||||
return ECarlaServerResponse::ActorTypeMismatch;
|
||||
}
|
||||
|
||||
virtual ECarlaServerResponse GetBonesTransform(FWalkerBoneControlOut&)
|
||||
virtual ECarlaServerResponse SetBonesTransform(const FWalkerBoneControlIn&)
|
||||
{
|
||||
return ECarlaServerResponse::ActorTypeMismatch;
|
||||
}
|
||||
|
||||
virtual ECarlaServerResponse BlendPose(float Blend)
|
||||
{
|
||||
return ECarlaServerResponse::ActorTypeMismatch;
|
||||
}
|
||||
|
||||
virtual ECarlaServerResponse GetPoseFromAnimation()
|
||||
{
|
||||
return ECarlaServerResponse::ActorTypeMismatch;
|
||||
}
|
||||
|
@ -553,9 +563,13 @@ public:
|
|||
|
||||
virtual ECarlaServerResponse GetWalkerControl(FWalkerControl&) final;
|
||||
|
||||
virtual ECarlaServerResponse ApplyBoneControlToWalker(const FWalkerBoneControlIn&) final;
|
||||
|
||||
virtual ECarlaServerResponse GetBonesTransform(FWalkerBoneControlOut&) final;
|
||||
|
||||
virtual ECarlaServerResponse SetBonesTransform(const FWalkerBoneControlIn&) final;
|
||||
|
||||
virtual ECarlaServerResponse BlendPose(float Blend);
|
||||
|
||||
virtual ECarlaServerResponse GetPoseFromAnimation();
|
||||
};
|
||||
|
||||
class FOtherActor : public FCarlaActor
|
||||
|
|
|
@ -1290,31 +1290,6 @@ void FCarlaServer::FPimpl::BindActions()
|
|||
return R<void>::Success();
|
||||
};
|
||||
|
||||
BIND_SYNC(apply_bone_control_to_walker) << [this](
|
||||
cr::ActorId ActorId,
|
||||
cr::WalkerBoneControlIn Control) -> R<void>
|
||||
{
|
||||
REQUIRE_CARLA_EPISODE();
|
||||
FCarlaActor* CarlaActor = Episode->FindCarlaActor(ActorId);
|
||||
if (!CarlaActor)
|
||||
{
|
||||
return RespondError(
|
||||
"apply_bone_control_to_walker",
|
||||
ECarlaServerResponse::ActorNotFound,
|
||||
" Actor Id: " + FString::FromInt(ActorId));
|
||||
}
|
||||
ECarlaServerResponse Response =
|
||||
CarlaActor->ApplyBoneControlToWalker(Control);
|
||||
if (Response != ECarlaServerResponse::Success)
|
||||
{
|
||||
return RespondError(
|
||||
"apply_bone_control_to_walker",
|
||||
Response,
|
||||
" Actor Id: " + FString::FromInt(ActorId));
|
||||
}
|
||||
return R<void>::Success();
|
||||
};
|
||||
|
||||
BIND_SYNC(get_bones_transform) << [this](
|
||||
cr::ActorId ActorId) -> R<cr::WalkerBoneControlOut>
|
||||
{
|
||||
|
@ -1352,6 +1327,84 @@ void FCarlaServer::FPimpl::BindActions()
|
|||
return carla::rpc::WalkerBoneControlOut(BoneData);
|
||||
};
|
||||
|
||||
BIND_SYNC(set_bones_transform) << [this](
|
||||
cr::ActorId ActorId,
|
||||
carla::rpc::WalkerBoneControlIn Bones) -> R<void>
|
||||
{
|
||||
REQUIRE_CARLA_EPISODE();
|
||||
FCarlaActor* CarlaActor = Episode->FindCarlaActor(ActorId);
|
||||
if (!CarlaActor)
|
||||
{
|
||||
return RespondError(
|
||||
"set_bones_transform",
|
||||
ECarlaServerResponse::ActorNotFound,
|
||||
" Actor Id: " + FString::FromInt(ActorId));
|
||||
}
|
||||
|
||||
FWalkerBoneControlIn Bones2 = FWalkerBoneControlIn(Bones);
|
||||
ECarlaServerResponse Response = CarlaActor->SetBonesTransform(Bones2);
|
||||
if (Response != ECarlaServerResponse::Success)
|
||||
{
|
||||
return RespondError(
|
||||
"set_bones_transform",
|
||||
Response,
|
||||
" Actor Id: " + FString::FromInt(ActorId));
|
||||
}
|
||||
|
||||
return R<void>::Success();
|
||||
};
|
||||
|
||||
BIND_SYNC(blend_pose) << [this](
|
||||
cr::ActorId ActorId,
|
||||
float Blend) -> R<void>
|
||||
{
|
||||
REQUIRE_CARLA_EPISODE();
|
||||
FCarlaActor* CarlaActor = Episode->FindCarlaActor(ActorId);
|
||||
if (!CarlaActor)
|
||||
{
|
||||
return RespondError(
|
||||
"blend_pose",
|
||||
ECarlaServerResponse::ActorNotFound,
|
||||
" Actor Id: " + FString::FromInt(ActorId));
|
||||
}
|
||||
|
||||
ECarlaServerResponse Response = CarlaActor->BlendPose(Blend);
|
||||
if (Response != ECarlaServerResponse::Success)
|
||||
{
|
||||
return RespondError(
|
||||
"blend_pose",
|
||||
Response,
|
||||
" Actor Id: " + FString::FromInt(ActorId));
|
||||
}
|
||||
|
||||
return R<void>::Success();
|
||||
};
|
||||
|
||||
BIND_SYNC(get_pose_from_animation) << [this](
|
||||
cr::ActorId ActorId) -> R<void>
|
||||
{
|
||||
REQUIRE_CARLA_EPISODE();
|
||||
FCarlaActor* CarlaActor = Episode->FindCarlaActor(ActorId);
|
||||
if (!CarlaActor)
|
||||
{
|
||||
return RespondError(
|
||||
"get_pose_from_animation",
|
||||
ECarlaServerResponse::ActorNotFound,
|
||||
" Actor Id: " + FString::FromInt(ActorId));
|
||||
}
|
||||
|
||||
ECarlaServerResponse Response = CarlaActor->GetPoseFromAnimation();
|
||||
if (Response != ECarlaServerResponse::Success)
|
||||
{
|
||||
return RespondError(
|
||||
"get_pose_from_animation",
|
||||
Response,
|
||||
" Actor Id: " + FString::FromInt(ActorId));
|
||||
}
|
||||
|
||||
return R<void>::Success();
|
||||
};
|
||||
|
||||
BIND_SYNC(set_actor_autopilot) << [this](
|
||||
cr::ActorId ActorId,
|
||||
bool bEnabled) -> R<void>
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
// Copyright (c) 2021 Computer Vision Center (CVC) at the Universitat Autonoma
|
||||
// de Barcelona (UAB).
|
||||
//
|
||||
// This work is licensed under the terms of the MIT license.
|
||||
// For a copy, see <https://opensource.org/licenses/MIT>.
|
||||
|
||||
#include "WalkerAnim.h"
|
|
@ -0,0 +1,26 @@
|
|||
// Copyright (c) 2021 Computer Vision Center (CVC) at the Universitat Autonoma
|
||||
// de Barcelona (UAB).
|
||||
//
|
||||
// This work is licensed under the terms of the MIT license.
|
||||
// For a copy, see <https://opensource.org/licenses/MIT>.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Animation/AnimInstance.h"
|
||||
|
||||
#include "WalkerAnim.generated.h"
|
||||
|
||||
UCLASS()
|
||||
class CARLA_API UWalkerAnim : public UAnimInstance
|
||||
{
|
||||
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
|
||||
UPROPERTY(Category="Walker Anim", BlueprintReadWrite, EditAnywhere)
|
||||
float Blend = 0.0;
|
||||
|
||||
UPROPERTY(Category="Walker Anim", BlueprintReadWrite, EditAnywhere)
|
||||
FPoseSnapshot Snap;
|
||||
};
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
#include "Carla.h"
|
||||
#include "Carla/Walker/WalkerController.h"
|
||||
#include "Carla/Walker/WalkerAnim.h"
|
||||
|
||||
#include "Components/PoseableMeshComponent.h"
|
||||
#include "Components/PrimitiveComponent.h"
|
||||
|
@ -44,141 +45,137 @@ void AWalkerController::OnPossess(APawn *InPawn)
|
|||
Character->JumpMaxCount = 2;
|
||||
}
|
||||
|
||||
UPoseableMeshComponent *AddNewBoneComponent(AActor *InActor, FVector inLocation, FRotator inRotator)
|
||||
{
|
||||
UPoseableMeshComponent *NewComp = NewObject<UPoseableMeshComponent>(InActor,
|
||||
UPoseableMeshComponent::StaticClass());
|
||||
if (NewComp)
|
||||
{
|
||||
NewComp->RegisterComponent();
|
||||
NewComp->SetWorldLocation(inLocation);
|
||||
NewComp->SetWorldRotation(inRotator);
|
||||
NewComp->AttachToComponent(InActor->GetRootComponent(), FAttachmentTransformRules::KeepRelativeTransform);
|
||||
}
|
||||
return NewComp;
|
||||
}
|
||||
|
||||
void AWalkerController::ApplyWalkerControl(const FWalkerControl &InControl)
|
||||
{
|
||||
Control = InControl;
|
||||
if (bManualBones)
|
||||
{
|
||||
SetManualBones(false);
|
||||
}
|
||||
}
|
||||
|
||||
void AWalkerController::ApplyWalkerControl(const FWalkerBoneControlIn &InBoneControl)
|
||||
{
|
||||
Control = InBoneControl;
|
||||
if (!bManualBones)
|
||||
{
|
||||
SetManualBones(true);
|
||||
}
|
||||
}
|
||||
|
||||
void AWalkerController::SetManualBones(const bool bIsEnabled)
|
||||
{
|
||||
bManualBones = bIsEnabled;
|
||||
|
||||
auto *Character = GetCharacter();
|
||||
TArray<UPoseableMeshComponent *> PoseableMeshes;
|
||||
TArray<USkeletalMeshComponent *> SkeletalMeshes;
|
||||
Character->GetComponents<UPoseableMeshComponent>(PoseableMeshes, false);
|
||||
Character->GetComponents<USkeletalMeshComponent>(SkeletalMeshes, false);
|
||||
USkeletalMeshComponent *SkeletalMesh = SkeletalMeshes.IsValidIndex(0) ? SkeletalMeshes[0] : nullptr;
|
||||
if (SkeletalMesh)
|
||||
{
|
||||
if (bManualBones)
|
||||
{
|
||||
UPoseableMeshComponent *PoseableMesh =
|
||||
PoseableMeshes.IsValidIndex(0) ? PoseableMeshes[0] : AddNewBoneComponent(Character,
|
||||
SkeletalMesh->GetRelativeTransform().GetLocation(),
|
||||
SkeletalMesh->GetRelativeTransform().GetRotation().Rotator());
|
||||
PoseableMesh->SetSkeletalMesh(SkeletalMesh->SkeletalMesh);
|
||||
PoseableMesh->SetVisibility(true);
|
||||
SkeletalMesh->SetVisibility(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
UPoseableMeshComponent *PoseableMesh = PoseableMeshes.IsValidIndex(0) ? PoseableMeshes[0] : nullptr;
|
||||
if (PoseableMesh)
|
||||
PoseableMesh->SetVisibility(false);
|
||||
SkeletalMesh->SetVisibility(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AWalkerController::GetBonesTransform(FWalkerBoneControlOut &WalkerBones)
|
||||
{
|
||||
auto *Character = GetCharacter();
|
||||
TArray<UPoseableMeshComponent *> PoseableMeshes;
|
||||
if (!Character) return;
|
||||
|
||||
TArray<USkeletalMeshComponent *> SkeletalMeshes;
|
||||
Character->GetComponents<UPoseableMeshComponent>(PoseableMeshes, false);
|
||||
Character->GetComponents<USkeletalMeshComponent>(SkeletalMeshes, false);
|
||||
USkeletalMeshComponent *SkeletalMesh = SkeletalMeshes.IsValidIndex(0) ? SkeletalMeshes[0] : nullptr;
|
||||
if (!SkeletalMesh) return;
|
||||
|
||||
UPoseableMeshComponent *PoseableMesh =
|
||||
PoseableMeshes.IsValidIndex(0) ? PoseableMeshes[0] : AddNewBoneComponent(Character,
|
||||
SkeletalMesh->GetRelativeTransform().GetLocation(),
|
||||
SkeletalMesh->GetRelativeTransform().GetRotation().Rotator());
|
||||
PoseableMesh->SetSkeletalMesh(SkeletalMesh->SkeletalMesh);
|
||||
PoseableMesh->SetVisibility(false);
|
||||
PoseableMesh->CopyPoseFromSkeletalComponent(SkeletalMesh);
|
||||
|
||||
FPoseSnapshot Snap;
|
||||
SkeletalMesh->SnapshotPose(Snap);
|
||||
for (int i=0; i<Snap.BoneNames.Num(); ++i)
|
||||
// get the walker animation class
|
||||
auto *AnimInst = SkeletalMesh->GetAnimInstance();
|
||||
if (!AnimInst) return;
|
||||
UWalkerAnim *WalkerAnim = Cast<UWalkerAnim>(AnimInst);
|
||||
if (!WalkerAnim) return;
|
||||
|
||||
// get current pose
|
||||
FPoseSnapshot TempSnapshot;
|
||||
SkeletalMesh->SnapshotPose(TempSnapshot);
|
||||
|
||||
// copy pose
|
||||
// WalkerAnim->Snap = TempSnapshot;
|
||||
|
||||
for (int i=0; i<TempSnapshot.BoneNames.Num(); ++i)
|
||||
{
|
||||
FWalkerBoneControlOutData Transforms;
|
||||
Transforms.World = PoseableMesh->GetBoneTransformByName(Snap.BoneNames[i], EBoneSpaces::WorldSpace);
|
||||
Transforms.Component = PoseableMesh->GetBoneTransformByName(Snap.BoneNames[i], EBoneSpaces::ComponentSpace);
|
||||
Transforms.Relative = Snap.LocalTransforms[i];
|
||||
WalkerBones.BoneTransforms.Add(Snap.BoneNames[i].ToString(), Transforms);
|
||||
// FVector Loc = SkeletalMesh->GetBoneLocation(Snap.BoneNames[i], EBoneSpaces::WorldSpace);
|
||||
// Trans = Snap.LocalTransforms[i];
|
||||
// Trans.SetLocation(Loc);
|
||||
// FTransform TransRel = Snap.LocalTransforms[i];
|
||||
// if (i == 0)
|
||||
// {
|
||||
// UE_LOG(LogCarla, Log, TEXT("World (%f, %f, %f), Relative (%f, %f, %f), Component (%f, %f, %f)"), Trans.GetLocation().X, Trans.GetLocation().Y, Trans.GetLocation().Z, TransRel.GetLocation().X, TransRel.GetLocation().Y, TransRel.GetLocation().Z, TransComp.GetLocation().X, TransComp.GetLocation().Y, TransComp.GetLocation().Z);
|
||||
// UE_LOG(LogCarla, Log, TEXT("World (%f, %f, %f), Relative (%f, %f, %f), Component (%f, %f, %f)"), Trans.GetLocation().X, Trans.GetLocation().Y, Trans.GetLocation().Z, TransRel.GetLocation().X, TransRel.GetLocation().Y, TransRel.GetLocation().Z, TransComp.GetLocation().X, TransComp.GetLocation().Y, TransComp.GetLocation().Z);
|
||||
// }
|
||||
Transforms.World = SkeletalMesh->GetSocketTransform(TempSnapshot.BoneNames[i], ERelativeTransformSpace::RTS_World);
|
||||
Transforms.Component = SkeletalMesh->GetSocketTransform(TempSnapshot.BoneNames[i], ERelativeTransformSpace::RTS_Actor);
|
||||
Transforms.Relative = SkeletalMesh->GetSocketTransform(TempSnapshot.BoneNames[i], ERelativeTransformSpace::RTS_ParentBoneSpace);
|
||||
// Transforms.Relative = TempSnapshot.LocalTransforms[i];
|
||||
|
||||
WalkerBones.BoneTransforms.Add(TempSnapshot.BoneNames[i].ToString(), Transforms);
|
||||
}
|
||||
}
|
||||
|
||||
void AWalkerController::SetBonesTransform(const FWalkerBoneControlIn &WalkerBones)
|
||||
{
|
||||
auto *Character = GetCharacter();
|
||||
if (!Character) return;
|
||||
|
||||
TArray<USkeletalMeshComponent *> SkeletalMeshes;
|
||||
Character->GetComponents<USkeletalMeshComponent>(SkeletalMeshes, false);
|
||||
USkeletalMeshComponent *SkeletalMesh = SkeletalMeshes.IsValidIndex(0) ? SkeletalMeshes[0] : nullptr;
|
||||
if (!SkeletalMesh) return;
|
||||
|
||||
// get the walker animation class
|
||||
auto *AnimInst = SkeletalMesh->GetAnimInstance();
|
||||
if (!AnimInst) return;
|
||||
UWalkerAnim *WalkerAnim = Cast<UWalkerAnim>(AnimInst);
|
||||
if (!WalkerAnim) return;
|
||||
|
||||
// if pose is empty, then get a first version
|
||||
if (WalkerAnim->Snap.BoneNames.Num() == 0)
|
||||
{
|
||||
// get current pose
|
||||
SkeletalMesh->SnapshotPose(WalkerAnim->Snap);
|
||||
}
|
||||
|
||||
TMap<FName, FTransform> BonesMap;
|
||||
for (const TPair<FString, FTransform> &pair : WalkerBones.BoneTransforms)
|
||||
{
|
||||
FName BoneName = FName(*pair.Key);
|
||||
BonesMap.Add(BoneName, pair.Value);
|
||||
}
|
||||
|
||||
// assign common bones
|
||||
for (int i=0; i<WalkerAnim->Snap.BoneNames.Num(); ++i)
|
||||
{
|
||||
FTransform *Trans = BonesMap.Find(WalkerAnim->Snap.BoneNames[i]);
|
||||
if (Trans)
|
||||
{
|
||||
WalkerAnim->Snap.LocalTransforms[i] = *Trans;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AWalkerController::BlendPose(float Blend)
|
||||
{
|
||||
auto *Character = GetCharacter();
|
||||
if (!Character) return;
|
||||
|
||||
TArray<USkeletalMeshComponent *> SkeletalMeshes;
|
||||
Character->GetComponents<USkeletalMeshComponent>(SkeletalMeshes, false);
|
||||
USkeletalMeshComponent *SkeletalMesh = SkeletalMeshes.IsValidIndex(0) ? SkeletalMeshes[0] : nullptr;
|
||||
if (!SkeletalMesh) return;
|
||||
|
||||
// get the walker animation class
|
||||
auto *AnimInst = SkeletalMesh->GetAnimInstance();
|
||||
if (!AnimInst) return;
|
||||
UWalkerAnim *WalkerAnim = Cast<UWalkerAnim>(AnimInst);
|
||||
if (!WalkerAnim) return;
|
||||
|
||||
// set current pose
|
||||
WalkerAnim->Blend = Blend;
|
||||
}
|
||||
|
||||
void AWalkerController::GetPoseFromAnimation()
|
||||
{
|
||||
auto *Character = GetCharacter();
|
||||
if (!Character) return;
|
||||
|
||||
TArray<USkeletalMeshComponent *> SkeletalMeshes;
|
||||
Character->GetComponents<USkeletalMeshComponent>(SkeletalMeshes, false);
|
||||
USkeletalMeshComponent *SkeletalMesh = SkeletalMeshes.IsValidIndex(0) ? SkeletalMeshes[0] : nullptr;
|
||||
if (!SkeletalMesh) return;
|
||||
|
||||
// get the walker animation class
|
||||
auto *AnimInst = SkeletalMesh->GetAnimInstance();
|
||||
if (!AnimInst) return;
|
||||
UWalkerAnim *WalkerAnim = Cast<UWalkerAnim>(AnimInst);
|
||||
if (!WalkerAnim) return;
|
||||
|
||||
// get current pose
|
||||
SkeletalMesh->SnapshotPose(WalkerAnim->Snap);
|
||||
}
|
||||
|
||||
void AWalkerController::ControlTickVisitor::operator()(const FWalkerControl &WalkerControl)
|
||||
{
|
||||
auto *Character = Controller->GetCharacter();
|
||||
if (Character != nullptr)
|
||||
{
|
||||
Character->AddMovementInput(WalkerControl.Direction,
|
||||
WalkerControl.Speed / Controller->GetMaximumWalkSpeed());
|
||||
if (WalkerControl.Jump)
|
||||
{
|
||||
Character->Jump();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!Character) return;
|
||||
|
||||
void AWalkerController::ControlTickVisitor::operator()(FWalkerBoneControlIn &WalkerBoneControlIn)
|
||||
{
|
||||
auto *Character = Controller->GetCharacter();
|
||||
if (Character == nullptr)
|
||||
Character->AddMovementInput(WalkerControl.Direction,
|
||||
WalkerControl.Speed / Controller->GetMaximumWalkSpeed());
|
||||
if (WalkerControl.Jump)
|
||||
{
|
||||
return;
|
||||
}
|
||||
TArray<UPoseableMeshComponent *> PoseableMeshes;
|
||||
Character->GetComponents<UPoseableMeshComponent>(PoseableMeshes, false);
|
||||
UPoseableMeshComponent *PoseableMesh = PoseableMeshes.IsValidIndex(0) ? PoseableMeshes[0] : nullptr;
|
||||
if (PoseableMesh)
|
||||
{
|
||||
for (const TPair<FString, FTransform> &pair : WalkerBoneControlIn.BoneTransforms)
|
||||
{
|
||||
FName BoneName = FName(*pair.Key);
|
||||
PoseableMesh->SetBoneTransformByName(BoneName, pair.Value, EBoneSpaces::Type::ComponentSpace);
|
||||
}
|
||||
WalkerBoneControlIn.BoneTransforms.Empty();
|
||||
Character->Jump();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -36,8 +36,6 @@ private:
|
|||
|
||||
void operator()(const FWalkerControl &WalkerControl);
|
||||
|
||||
void operator()(FWalkerBoneControlIn &WalkerBoneControlIn);
|
||||
|
||||
private:
|
||||
|
||||
AWalkerController *Controller;
|
||||
|
@ -61,29 +59,25 @@ public:
|
|||
UFUNCTION(BlueprintCallable)
|
||||
void ApplyWalkerControl(const FWalkerControl &InControl);
|
||||
|
||||
void ApplyWalkerControl(const FWalkerBoneControlIn &InBoneControl);
|
||||
|
||||
UFUNCTION(BlueprintCallable)
|
||||
const FWalkerControl GetWalkerControl() const
|
||||
{
|
||||
return Control.which() == 0u ? boost::get<FWalkerControl>(Control) : FWalkerControl{};
|
||||
}
|
||||
|
||||
UFUNCTION(BlueprintCallable)
|
||||
const FWalkerBoneControlIn GetBoneWalkerControl() const
|
||||
{
|
||||
return Control.which() == 1u ? boost::get<FWalkerBoneControlIn>(Control) : FWalkerBoneControlIn{};
|
||||
}
|
||||
|
||||
UFUNCTION(BlueprintCallable)
|
||||
void SetManualBones(const bool bIsEnabled);
|
||||
|
||||
UFUNCTION(BlueprintCallable)
|
||||
void GetBonesTransform(FWalkerBoneControlOut &WalkerBones);
|
||||
|
||||
UFUNCTION(BlueprintCallable)
|
||||
void SetBonesTransform(const FWalkerBoneControlIn &WalkerBones);
|
||||
|
||||
UFUNCTION(BlueprintCallable)
|
||||
void BlendPose(float Blend);
|
||||
|
||||
UFUNCTION(BlueprintCallable)
|
||||
void GetPoseFromAnimation();
|
||||
|
||||
private:
|
||||
|
||||
boost::variant<FWalkerControl, FWalkerBoneControlIn> Control;
|
||||
|
||||
bool bManualBones;
|
||||
boost::variant<FWalkerControl> Control;
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue