Skip to content

SaxonRah/OpenMotion

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

6 Commits
 
 
 
 

Repository files navigation

OpenMotion

The goal is to create believable run time ready character interactions within a simulated game world.

We will explore Forward and Inverse Kinematics, Physical Animation, Procedural Animation, Motion Matching, and more.

Similar Projects

IKinema's Full Body IK

NaturalMotion's Morpheme, Endorphin and Euphoria.

Dynamic Animation and Control Environment (DANCE)- by Ari Shapiro, Victor Ng-Thow-Hing and Petros Faloutsos

Updated for UE 5.7 and New code!

I had some older code laying around I never added to the online repo. I don't remember how much of the FK, Physical Anim, and Motion Matching systems were implemented, and I don't remember what was broken/needs fixes. I am only going off local git history. It should be enough for anyone to understand each system and continue on from there.

I know there is a Demo Level in the Plugin Content FabrikDemoActor which had some tests like FK and Physical Anim, I don't remember where I was testing Motion Matching, it might be in another project and not in this one.

Added Base Project

Just a simple wrapper project. All Code/Content is inside the Plugin/Source and Plugin/Content, though some content like Manny may be referenced from Project conent into Plugin content.

Bug Fixes

FloatMax() comma operator the original code had return FLT_MAX, FLT_MAX, FLT_MAX which in C++ silently evaluates all three expressions left to right and returns only the last one. It accidentally returned the right value, but for the wrong reason. Fixed to just return FLT_MAX.

Null crash in FabrikDemoActor::Tick; every frame the demo actor called TargetActor->GetActorLocation() with no check that TargetActor was actually set. Dropping the actor into a level without assigning a target would immediately crash the editor. Added a guard.

"TODO" error messages; throughout the FABRIK code, error logs said things like "Bone TODO does not exist". The original Java port never filled these in. Replaced with proper FString::Printf formatting so you actually know which bone or chain caused the problem.

DebugDraw() stub; the body was completely empty. Implemented it to draw the full arm chain: shoulder position, upper/lower arm segments, hand effectors, and clavicle lines, using UE5's debug draw helpers.

GetDebugValues() stub; returned a zero vector unconditionally. Changed to return shoulder height, left elbow angle, and right elbow angle as a convenient single vector you can print or graph in Blueprint to understand what the solver is doing.

Uninitialized variable warnings; several demo functions and the debug circle drawer declared variables before a switch statement but only assigned them inside the cases. If the switch somehow didn't match (or the compiler couldn't prove it would), those variables were technically uninitialized. Added default values before each switch.

Forward Kinematics (UFKSolver)

The README listed FK as a goal but nothing was implemented. FK is the simpler half of the kinematics problem; given a set of joint rotations, compute where every bone ends up in world space. You start at the root and multiply each bone's local transform by its parent's result, walking down the hierarchy. That's the entire algorithm.

The solver stores a flat array of bones where each bone knows its parent's index. Solve() does a single forward pass through that array. Because UE4/5 reference skeletons always guarantee parents come before children in the array, one linear pass is all you need.

InitFromSkeletalMesh seeds the solver with the reference pose of any skeletal mesh so you don't have to build the hierarchy by hand. ApplyToMesh writes the results back to a UPoseableMeshComponent, which is the UE5 component designed for direct bone manipulation.

Physical Animation (UOpenMotionPhysicsComponent)

UE5 already has UPhysicalAnimationComponent built in, but its API is low level; you have to construct FPhysicalAnimationData structs manually for every bone. This wrapper adds a higher level interface on top.

The main addition is ApplyProfile(), which lets you set up common configurations in one call: fully animated (physics off), full ragdoll (animation provides almost no guidance), physics only below a named bone (useful for hair, cape, or lower body), and secondary motion (very light physics that adds natural lag and jiggle while still closely following the animation).

SetBoneBlendWeight() lets you dial a single bone between fully animated and fully simulated with a 0–1 float, which is useful for dynamic transitions like a character going limp after being hit.

Motion Matching (UMotionMatchingComponent)

Motion matching is the technique behind UE5's built in motion matching system and games like For Honor. Instead of playing hand authored animation state machines, you build a database of every frame from all your animation clips and every frame each frame searches that database for the pose that best matches the character's current state.

The component builds the database at BeginPlay by sampling each UAnimSequence at regular intervals. For each sampled frame it extracts a feature vector; the positions and velocities of five key bones (hips, feet, hands) in character local space, plus predicted future positions at three points along the character's trajectory.

At runtime, the current character state is described using the same feature format. The search finds the database frame with the lowest weighted cost against the query. Lower cost means the bones are in similar positions, moving at similar speeds, and heading in a similar direction. The component exposes MatchedSequence and MatchedTime as properties your Animation Blueprint reads to actually play the result.

The weights on each feature channel are tunable; trajectory matching is weighted higher by default because getting the direction of movement right matters more than exact bone positions when blending.

Blueprint Library (UOpenMotionLibrary)

The FABRIK system was C++ only despite being marked as UPROPERTY; there were no UFUNCTION wrappers so Blueprint couldn't construct or drive it. The library adds that: CreateSimpleChain builds a ready to use chain in one node, SolveFabrik drives it toward a target, and GetBoneSegments returns the bone data as arrays you can feed to a line draw loop for debugging.

TwoBoneIK is a standalone analytical two bone solver (upper arm, lower arm, hand) that takes a root, two segment lengths, a target, and a pole vector and returns the elbow position directly. It's faster and simpler than FABRIK for limbs where you know the exact chain topology.

PredictTrajectory takes a position and velocity and samples it at given time offsets, which feeds directly into the motion matching query.

RotateDirectionToward rotates a direction vector toward a target direction by at most a given number of degrees per call, useful for smooth character facing without Lerp overshooting.

License and Tool used

OpenMotion is an MIT license based Unreal Engine 4 Plugin and Demo Project.

Future Work

A topic which closely related is Russell L. Smith's Intelligent Motion Control with an Artificial Cerebellum.

If there is large interest in this project, or I'm asked specifically to, I'll see what I can't get going.

P.S.

If you know of an interesting project, idea, or research paper, please let the community know about it!

About

No description or website provided.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages