Jump to content

Search the Community

Showing results for tags 'Animation IK'.

  • Search By Tags

    Type tags separated by commas.
  • Search By Author

Content Type


Blogs

  • Development Blog
  • Canardian's Blog
  • Beyond Civilization Blog Ext
  • Tyler's Blog
  • macklebee's Blog
  • B-Byrnes' Blog
  • Marleys Ghost's Blog
  • omid3098's Blog
  • Richardsimpo123456's Blog
  • DJDD's Blog
  • Rick's Blog
  • --
  • xtreampb's Blog
  • Economically Disadvantaged
  • klepto2's Blog
  • Old Blog
  • Chris Paulson's Blog
  • Davaris' Blog
  • nil
  • Rekindled Phoenix's Blog
  • Flexman's Blog
  • Kattemaksu Online
  • Marcousik's Creations Blog
  • EVE LBS Studio
  • Rendering puzzles
  • Screen Size Utility
  • Niosop's Blog
  • 1299 RTS Game Project
  • Blitzbat's Blog
  • gordonramp's Blog
  • Andy Gilbert's Blog
  • Marcus' Blog
  • JornAggror Blog
  • diedir's Blog
  • wayneg's Blog
  • Masterxilo's Blog
  • Dave Lee's Blog
  • peubuy's blog
  • OD Arts -Leadwerks Blog
  • The progression......
  • Ultra Software Company Blog
  • The Progression
  • Pancake's Blog
  • Test Blog
  • BLaBZ Blog
  • Pure³d's Blog
  • dreamhead Blog
  • RVL's Blog
  • DB's Blog
  • Toxin Games Development Blog
  • CombatHelo Blog (RSS Import)
  • Foolish's Blog
  • ZioRed's Corner
  • Toxin Games Twitter
  • Shard - Third Initiative
  • Shard's Blog
  • Soamp's Blog
  • Soamp's Blog
  • Laurens' Blog
  • JT`s warehouse district
  • Kennar's Blog
  • KiteFuchs' Blog
  • KiteFuchs' Blog
  • Rachel's Dev-Blog
  • Eagle's Blog
  • zaphos' Blog
  • please delete this blog
  • Afke's Blog
  • Richard Simpson
  • knowledgegranted's Blog
  • EdzUp(GD)'s Blog
  • aGameLife's Kelasel MMORPG Blog
  • tournamentdan's Blog
  • Beyond Civilization Blog
  • smashthewindow
  • AnniXa's Blog
  • AnniXa's Blog
  • Elemental Development
  • DigitalHax Blog
  • Aria's Blog
  • Strogg76's Blog
  • Clackdor's Blog
  • Leadwerks Project Status
  • simpleprogrammer's Blog
  • Pathfinding in LE.2.x
  • Naughty Alien's Blog
  • smashthewindow's Blog
  • Ali Salehi's Blog
  • Jardar's Blog
  • Chris Vossen's Development Blog
  • Scarlet Thread Studios' Blog
  • Kronos' Blog
  • Benton's Blog
  • ChrisV's Blog
  • tjheldna's Blog
  • shadmar's Blog
  • 3D Masons, LLC
  • Andy Gilbert's Enviro Models
  • ParaToxic's Blog
  • NarkLord's Blog
  • ChrisMAN's Blog
  • ChrisMAN's Blog
  • CGMan's Blog
  • The Game
  • Chris Tutorials
  • Leadwerks 3 Experience
  • An Alien Saga
  • klepto2 & Leadwerks 3
  • Inside the mind of eternal insomniac
  • josk's Blog
  • Shader Development in Leadwerks 3.1
  • 3D Coat : Column game making of
  • Einlander's Blog
  • Ginger George's Blog
  • I have a problem
  • Michael_J's Blog
  • nasamydifol's Blog
  • Digman's Blog
  • noesisGUI
  • SavageDogg38's Blog
  • Built from Ruins
  • Remaining Days
  • test_external_blog
  • The Hunt For Food Blog
  • Crazy Minnow Studio
  • CrazyMinnowStudio
  • Guppy's Blog
  • Playing Online
  • Evayr's Blog
  • DerRidda's Blog
  • Karl's Blog
  • whiterabbit's Blog
  • Tinyboss Games
  • abendkleider's Blog
  • sacguccireplica's Blog
  • Arena
  • Imchasinyou's Blog
  • xtom's Blog
  • Lua is better than you think.
  • mdgunn's Blog
  • Crime Closer
  • lxFirebal69xl's Blog
  • Wedmer's Blog
  • Lockdown, going forward.
  • Pump-Action Captain
  • Igor's Blog
  • Dead Anyway
  • Runenrise and more
  • reepblue's Blog
  • Slippy's Corner
  • LUA Musings
  • severjack's Blog
  • mikeporter's Blog
  • miko93's Blog
  • Megalocerous' Blog
  • lxFirebal69xl's Blog
  • aiaf's Blog
  • Lostghbear's Blog
  • echo $BLOG_NAME > blog_title.tmpl
  • johnadam111's Blog
  • Dwarf Beard
  • burgelkat's Blog
  • Charrua's Blog
  • peterpaul's Blog
  • joshmathews' Blog
  • Martin Kearl's Blog
  • Brutile's blog
  • tipforeveryone's Blog
  • Glushchenko Blog
  • Express Lab Games Blog
  • Blueapples' Blog
  • DooMAGE's Blog
  • Structura devblog
  • UltraEngine - Experiences, add-ons and other Stuff
  • martyj's Blog
  • Dragonfreak's Blog
  • Brutile's Blog
  • assigmenthelp
  • Case Study Assignment Help
  • How to deal with bad grade ?
  • How to deal with bad grade ?
  • GameDev Blog
  • devcjohnson's Blog
  • devcjohnson's Blog
  • THE WHAT? Blog
  • The Demurian Scribe
  • GUI Editor
  • GUI Tutorial
  • noob_shaders
  • The Seventh World
  • Phodex Games Blog
  • Leadwerks VS Source 2
  • Work in Progress - Scifi PBR Media
  • [C++] First Player game start
  • The Blog of Yue
  • Snowboarding Development Blog
  • Ocean: Rendering in Leadwerks 4
  • Game Ready Maps
  • Ultra App Kit (Advanced Custom Widgets)
  • Poking around
  • SALVATIONLAND
  • Blender tutorials
  • Usefull Scripts & Components
  • Thirsty Panther
  • Ultimate Action Game Controller

Forums

  • Software
    • General Discussion
    • Programming
    • Game Artwork
    • Showcase
    • Suggestion Box
    • Bug Reports
  • Addons
    • Extensions & Plugins
    • Components
    • Addon Development
  • Platforms
    • Windows
    • Linux
    • macOS

Categories

  • Streams and Events
  • Tutorials
  • Games
  • Work in Progress

Find results in...

Find results that contain...


Date Created

  • Start

    End


Last Updated

  • Start

    End


Filter by number of...

Joined

  • Start

    End


Group


Location

Found 1 result

  1. To get nice locomotion and not have NPC walking with feet stuck in the terrain or hovering in the air you need to place the feet to match the terrain, coping with slopes etc. Leadwerks has forward kinematics but not inverse (which is needed to do this). Because of this I have written (with help) an IK solver. Thanks to Tyler for supplying the code as a starting point. Here's a video of it working: - Here's the code (I actually ended up doing 2 solvers) #include "IKSimple.h" #include "engine.h" float IKSolver::positionAccuracy = 0.001f; int IKSimple::maxIterations = 100; float IKSimple::calcBonesLength() { boneLength.resize(bones.size()-1); float totalLength = 0.0f; for (int j = 0; j < (bones.size() - 1); j++) { Vector3 vector = bones[j + 1].localPosition() - bones[j].localPosition(); boneLength[j] = vector.Magnitude(); totalLength += boneLength[j]; } this->positionAccuracy = totalLength * 0.001f; return totalLength; } void IKSimple::Solve( TEntity entity, std::vector<Transform> pbones, Vector3 target) { /// Local Variables /////////////////////////////////////////////////////////// Vector3 rootPos,curEnd,desiredEnd,targetVector,curVector,crossResult; double cosAngle,turnAngle,turnDeg; int link,tries; Quaternion aquat; /////////////////////////////////////////////////////////////////////////////// // START AT THE LAST LINK IN THE CHAIN bones = pbones; startBone = &pbones[0]; endBone = &pbones[pbones.size() - 1]; link = pbones.size() - 1; tries = 0; // LOOP COUNTER SO I KNOW WHEN TO QUIT do { // THE COORDS OF THE X,Y,Z POSITION OF THE ROOT OF THIS BONE IS IN THE MATRIX // TRANSLATION PART WHICH IS IN THE 12,13,14 POSITION OF THE MATRIX rootPos = pbones[link].localPosition(); // POSITION OF THE END EFFECTOR curEnd = endBone->localPosition(); // DESIRED END EFFECTOR POSITION desiredEnd = target; // SEE IF I AM ALREADY CLOSE ENOUGH if ( curEnd.DistanceSquared(desiredEnd) > positionAccuracy) { // CREATE THE VECTOR TO THE CURRENT EFFECTOR POS curVector = curEnd - rootPos; // CREATE THE DESIRED EFFECTOR POSITION VECTOR targetVector = target - rootPos; // NORMALIZE THE VECTORS (EXPENSIVE, REQUIRES A SQRT) curVector.Normalize(); targetVector.Normalize(); // THE DOT PRODUCT GIVES ME THE COSINE OF THE DESIRED ANGLE cosAngle = targetVector.Dot( curVector); // IF THE DOT PRODUCT RETURNS 1.0, I DON'T NEED TO ROTATE AS IT IS 0 DEGREES if (cosAngle < 0.99999) { // USE THE CROSS PRODUCT TO CHECK WHICH WAY TO ROTATE crossResult = curVector.Cross(targetVector); crossResult.Normalize(); turnAngle = acos((float)cosAngle); // GET THE ANGLE turnDeg = rad2deg(turnAngle); // COVERT TO DEGREES // DAMPING turnDeg *= pbones[link].m_damper; aquat = Quaternion::Quaternion(crossResult, turnDeg ); aquat = pbones[link].boneLocalRotation() * aquat; pbones[link].setLocalRotation( aquat ); } if (--link < 0) link = pbones.size() - 1; // START OF THE CHAIN, RESTART } // QUIT IF I AM CLOSE ENOUGH OR BEEN RUNNING LONG ENOUGH } while (tries++ < maxIterations && curEnd.DistanceSquared( desiredEnd) > positionAccuracy); } void IKSimple::calcCurrentBones( ) { rotateArray.resize(bones.size()-2); angles.resize(bones.size()-2); quaternionArray.resize(bones.size()-2); // Work out where current bones are for (int i = 0; i < (bones.size() - 2); i++) { rotateArray[i] = (bones[i + 1].localPosition() - bones[i].localPosition()).Cross(bones[i + 2].localPosition() - bones[i + 1].localPosition()); rotateArray[i] = (Vector3) ((bones[i].localRotation().Inverse()) * rotateArray[i]); rotateArray[i].Normalize(); angles[i] = (bones[i + 1].localPosition() - bones[i].localPosition() ).Angle(bones[i + 1].localPosition() - bones[i + 2].localPosition() ); quaternionArray[i] = bones[i + 1].localRotation(); } } void IKSimple::SolveRelative( TEntity entity, std::vector<Transform> pbones, Vector3 target) { float doLow; float doHigh; bones = pbones; startBone = &bones[0]; endBone = &bones[bones.size() - 1]; // Work out length of bones float totalLength = calcBonesLength(); Vector3 curdis = endBone->localPosition() - startBone->localPosition(); float currentDistance = curdis.Magnitude(); Vector3 vtarget = target - startBone->localPosition(); float targetDistance = vtarget.Magnitude(); bool minFound = false; bool moreToDo = false; if (targetDistance > currentDistance) { minFound = true; doHigh = 1.0f; doLow = 0.0f; } else { moreToDo = true; doHigh = 1.0f; doLow = 0.0f; } int currentIter = 0; while ((abs((float) (currentDistance - targetDistance)) > this->positionAccuracy) && (currentIter < this->maxIterations)) { float newBend; currentIter++; if (!minFound) newBend = doHigh; else newBend = (doLow + doHigh) / 2.0f; for (int i = 0; i < (bones.size() - 2); i++) { float calcAngle; if (!moreToDo) { calcAngle = math::Lerp(180.0f, angles[i], newBend); } else { calcAngle = (angles[i] * (1.0f - newBend)) + ((angles[i] - 30.0f) * newBend); } float angleDiff = angles[i] - calcAngle; Quaternion newRot = Quaternion::Quaternion(rotateArray[i], angleDiff ); newRot = quaternionArray[i] * newRot; bones[i + 1].setLocalRotation( newRot ); } Vector3 totalLen = endBone->localPosition() - startBone->localPosition(); currentDistance = totalLen.Magnitude(); if (targetDistance > currentDistance) minFound = true; if (minFound) { if (targetDistance > currentDistance) doHigh = newBend; else doLow = newBend; if (doHigh < 0.01f) break; } else { doLow = doHigh; doHigh++; } } // Change master bone (if we was doing a leg this would be the hip) float hipAngle = (endBone->localPosition() - startBone->localPosition()).Angle(target - startBone->localPosition()); Vector3 hipAxis = (endBone->localPosition() - startBone->localPosition()).Cross(target - startBone->localPosition()); AngleAxis hipAngleAxis = AngleAxis( hipAxis, hipAngle ); Quaternion hipRot = startBone->localRotation() * Quaternion::Quaternion( hipAngleAxis ); startBone->setLocalRotation( hipRot ); } Here's the transform object which controls the bones. It was a little bit tricky to do because LE annoyingly does local rotation relative to the parent bone not relative to the model. #ifndef TRANSFORM_H #define TRANSFORM_H /// @file locomotion\tranform.h /// @brief This is the transform object which handles rotation/positioning of bones /// for the IK solver /// #include "SVector3.h" #include "SQuaternion.h" class Transform { public: Transform() {}; Transform(TEntity parent, TEntity entity) : m_parent(parent) { m_entity = entity; TVec3 v; v = EntityScale(entity); m_scale = Vector3(v.X,v.Y,v.Z); v = Vec3(0,1,0); v = TFormVector(v, entity, NULL); m_up = Vector3(v.X,v.Y,v.Z); v = Vec3(0,0,1); v = TFormVector(v, entity, NULL); m_forward = Vector3(v.X,v.Y,v.Z); v = Vec3(1,0,0); v = TFormVector(v, entity, NULL); m_right = Vector3(v.X,v.Y,v.Z); m_damper = 1; m_minRotation = Vector3(-360,-360,-360); m_maxRotation = Vector3(360,360,360); } inline Quaternion boneLocalRotation() { TVec3 v; v = EntityRotation(m_entity,0); Quaternion q = Quaternion( Vector3(v) ); return q; } inline Quaternion localRotation() { TVec3 v; TEntity par = GetParent( m_entity ); EntityParent( m_entity, m_parent ); v = EntityRotation(m_entity,0); EntityParent( m_entity, par ); Quaternion q = Quaternion( Vector3(v) ); return q; } inline Quaternion rotation() { TVec3 v; v = EntityRotation(m_entity,1); Quaternion q1 = Quaternion(Vector3(v)); return q1; } inline void alignToVector( Vector3 v, int axis = 3, int rate = 1, int roll = 0 ) { AlignToVector( m_entity, v.vec3(), axis, rate, 0); } inline void setLocalRotation( Quaternion rot ) { Vector3 vrot; vrot = rot.eulerAngles(); vrot.X = __max( vrot.X, m_minRotation.X ); vrot.Y = __max( vrot.Y, m_minRotation.Y ); vrot.Z = __max( vrot.Z, m_minRotation.Z ); vrot.X = __min( vrot.X, m_maxRotation.X ); vrot.Y = __min( vrot.Y, m_maxRotation.Y ); vrot.Z = __min( vrot.Z, m_maxRotation.Z ); RotateEntity( m_entity, vrot.vec3(), 0); } inline void setRotation( Quaternion rot ) { Vector3 vrot; vrot = rot.eulerAngles(); RotateEntity( m_entity, vrot.vec3(), 1); } inline Vector3 position() { TVec3 v; v = EntityPosition(m_entity,1); v = TFormPoint(v ,NULL, m_parent); return Vector3( v ); } inline Vector3 localPosition() { TVec3 v; v = EntityPosition(m_entity, 1); v = TFormPoint(v, NULL, m_parent); return Vector3( v ); } TEntity m_entity; Vector3 m_minRotation; Vector3 m_maxRotation; float m_damper; private: TEntity m_parent; Vector3 m_scale; Vector3 m_up; Vector3 m_forward; Vector3 m_right; }; #endif Just ask if you want me to supply the Vector3 and Quaternion math code if you need it.
×
×
  • Create New...