|
|
@ -3,42 +3,57 @@ |
|
|
|
|
|
|
|
|
|
|
|
#include "Robot.h" |
|
|
|
#include "Robot.h" |
|
|
|
|
|
|
|
|
|
|
|
#include "util.h" |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ARobot::ARobot(){ |
|
|
|
ARobot::ARobot(){ |
|
|
|
PrimaryActorTick.bCanEverTick = true; |
|
|
|
PrimaryActorTick.bCanEverTick = true; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void ARobot::BeginPlay(){ |
|
|
|
void ARobot::BeginPlay(){ |
|
|
|
Super::BeginPlay(); |
|
|
|
Super::BeginPlay(); |
|
|
|
|
|
|
|
|
|
|
|
GetComponents<ULink>(Parts); |
|
|
|
for (auto* Link : Links) |
|
|
|
for (auto* Link : Parts){ |
|
|
|
|
|
|
|
Link->Setup(); |
|
|
|
Link->Setup(); |
|
|
|
if (Link->PrevJoint) |
|
|
|
ResetPositionAndOrientation(); |
|
|
|
Joints.Add(Link->PrevJoint); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void ARobot::ResetPositionAndOrientation(){ |
|
|
|
|
|
|
|
for (const auto* Joint : Joints){ |
|
|
|
|
|
|
|
const ULink* L1 = Joint->FirstLink; |
|
|
|
|
|
|
|
ULink* L2 = Joint->SecondLink; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Vector3d ConnectPosL1 = L1->Position + Joint->GetFirstWorldDirection(); |
|
|
|
|
|
|
|
const Vector3d Correction = ConnectPosL1 - Joint->GetSecondWorldDirection(); |
|
|
|
|
|
|
|
L2->Position = Correction; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Example: 3 Parts are connected with 2 Joints
|
|
|
|
|
|
|
|
assert(Parts.Num() == Joints.Num() + 1); |
|
|
|
void ARobot::Connect(ULink* L1, ULink* L2){ |
|
|
|
|
|
|
|
Links.AddUnique(L1); |
|
|
|
|
|
|
|
Links.Add(L2); |
|
|
|
|
|
|
|
UJoint* Joint = NewObject<UJoint>(this); |
|
|
|
|
|
|
|
Joint->FirstLink = L1; |
|
|
|
|
|
|
|
Joint->SecondLink = L2; |
|
|
|
|
|
|
|
L1->NextJoint = Joint; |
|
|
|
|
|
|
|
L2->PrevJoint = Joint; |
|
|
|
|
|
|
|
Joints.Add(Joint); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void ARobot::Tick(const float DeltaTime){ |
|
|
|
void ARobot::Tick(const float DeltaTime){ |
|
|
|
Super::Tick(DeltaTime); |
|
|
|
Super::Tick(DeltaTime); |
|
|
|
|
|
|
|
|
|
|
|
constexpr int SubSteps = 30; |
|
|
|
constexpr int SubSteps = 50; |
|
|
|
const double h = DeltaTime / SubSteps; |
|
|
|
const double h = DeltaTime / SubSteps; |
|
|
|
for (int i = 0; i < SubSteps; i++){ |
|
|
|
for (int i = 0; i < SubSteps; i++){ |
|
|
|
for (auto* Link : Parts) |
|
|
|
for (auto* Link : Links) |
|
|
|
Link->Update(h); |
|
|
|
Link->Update(h); |
|
|
|
for (const auto* Joint : Joints) |
|
|
|
for (const auto* Joint : Joints) |
|
|
|
Joint->SolvePosition(h); |
|
|
|
Joint->SolvePosition(h); |
|
|
|
for (auto* Link : Parts) |
|
|
|
for (auto* Link : Links) |
|
|
|
Link->Integrate(h); |
|
|
|
Link->Integrate(h); |
|
|
|
for (const auto* Joint : Joints) |
|
|
|
for (const auto* Joint : Joints) |
|
|
|
Joint->SolveVelocity(h); |
|
|
|
Joint->SolveVelocity(h); |
|
|
|
} |
|
|
|
} |
|
|
|
for (auto* Link : Parts) |
|
|
|
for (auto* Link : Links) |
|
|
|
Link->UpdateInternalTransform(); |
|
|
|
Link->UpdateInternalTransform(); |
|
|
|
} |
|
|
|
} |
|
|
|