Chris Paulson Posted January 7, 2010 Share Posted January 7, 2010 Hi, I've started looking a footplacement of an NPC so it's feet are on the ground instead of floating. I've tried modifying a foot bone position (using EntityPosition) believing LE had IK to sort out all the other bone positions/rotations, however what I saw was the mesh messed up. I'm I doing something wrong? Has LE really got IK? Quote Link to comment Share on other sites More sharing options...
TylerH Posted January 7, 2010 Share Posted January 7, 2010 No, it doesn't. It has forward kinematics (higher bones influence lower bones), but not IK. I am just getting to this now too, as we have an animated main character who has floating feet as well. 1 1 Quote nVidia 530M Intel Core i7 - 2.3Ghz 8GB DDR3 RAM Windows 7 Ultimate (64x)----- Visual Studio 2010 Ultimate Google Chrome Creative Suite 5 FL Studio 10 Office 15 ----- Expert Professional Expert BMX Programmer ----- Link to comment Share on other sites More sharing options...
Chris Paulson Posted January 7, 2010 Author Share Posted January 7, 2010 So to move a foot up I'll have to rotate the hip and knee joint? I presume doing rotations like this are the only option. I guessing the maths for the rotations are going to be tricky! Quote Link to comment Share on other sites More sharing options...
TylerH Posted January 7, 2010 Share Posted January 7, 2010 The maths for those rotations are in fact what an Inverse Kinematics Solver would do. What is does, is determine how much you have to rotate and move the parents of a given bone in order to move it to where you are trying to, and give it proper influence. 1 Quote nVidia 530M Intel Core i7 - 2.3Ghz 8GB DDR3 RAM Windows 7 Ultimate (64x)----- Visual Studio 2010 Ultimate Google Chrome Creative Suite 5 FL Studio 10 Office 15 ----- Expert Professional Expert BMX Programmer ----- Link to comment Share on other sites More sharing options...
TylerH Posted January 7, 2010 Share Posted January 7, 2010 For anyone unsure: http://en.wikipedia.org/wiki/Inverse_kinematics Explains it well in terms of the physics terms. Quote nVidia 530M Intel Core i7 - 2.3Ghz 8GB DDR3 RAM Windows 7 Ultimate (64x)----- Visual Studio 2010 Ultimate Google Chrome Creative Suite 5 FL Studio 10 Office 15 ----- Expert Professional Expert BMX Programmer ----- Link to comment Share on other sites More sharing options...
Niosop Posted January 7, 2010 Share Posted January 7, 2010 If trying to implement your own IK solver turns out to be a pain you could take a look at trying to integrate havok animation. It has a lot of nice features, including IK solvers. Quote Windows 7 x64 - Q6700 @ 2.66GHz - 4GB RAM - 8800 GTX ZBrush - Blender Link to comment Share on other sites More sharing options...
TylerH Posted January 7, 2010 Share Posted January 7, 2010 Havok Animation is something I have been wanting to try out in Leadwerks, but it seems like it will be a pain to get it working. Quote nVidia 530M Intel Core i7 - 2.3Ghz 8GB DDR3 RAM Windows 7 Ultimate (64x)----- Visual Studio 2010 Ultimate Google Chrome Creative Suite 5 FL Studio 10 Office 15 ----- Expert Professional Expert BMX Programmer ----- Link to comment Share on other sites More sharing options...
Josh Posted January 7, 2010 Share Posted January 7, 2010 I'm sure you could use a couple of static bodies for the feet, a static body for the pelvis, and a body with mass for the knees. Connect the knees to the pelvis with a ball joint with limits, and the feet to the knees with a hinge. Move the feet wherever you want them to be, and the knees will follow. Parent the knee bones to the knee bodies, and you have IK animation. Quote My job is to make tools you love, with the features you want, and performance you can't live without. Link to comment Share on other sites More sharing options...
TylerH Posted January 8, 2010 Share Posted January 8, 2010 Yeah, today a good physics ragdoll setup would simulate the IK better than a solver may. Quote nVidia 530M Intel Core i7 - 2.3Ghz 8GB DDR3 RAM Windows 7 Ultimate (64x)----- Visual Studio 2010 Ultimate Google Chrome Creative Suite 5 FL Studio 10 Office 15 ----- Expert Professional Expert BMX Programmer ----- Link to comment Share on other sites More sharing options...
Chris Paulson Posted January 8, 2010 Author Share Posted January 8, 2010 I'm sure you could use a couple of static bodies for the feet, a static body for the pelvis, and a body with mass for the knees. Connect the knees to the pelvis with a ball joint with limits, and the feet to the knees with a hinge. Move the feet wherever you want them to be, and the knees will follow. Parent the knee bones to the knee bodies, and you have IK animation. Great idea however bit confused by combination of bodies etc. I would have thought: - Ball joint - parented to hip pivot Body box for thigh Ball joint for knee Body box for shin Hinge for ankle Body box for foot To give:- . | . | .- but I'm probably wrong as I haven't done this before. Quote Link to comment Share on other sites More sharing options...
TylerH Posted January 9, 2010 Share Posted January 9, 2010 As always you are correct. That setup seems great actually Quote nVidia 530M Intel Core i7 - 2.3Ghz 8GB DDR3 RAM Windows 7 Ultimate (64x)----- Visual Studio 2010 Ultimate Google Chrome Creative Suite 5 FL Studio 10 Office 15 ----- Expert Professional Expert BMX Programmer ----- Link to comment Share on other sites More sharing options...
wailingmonkey Posted January 9, 2010 Share Posted January 9, 2010 hmm...think you might want to change the ball-joint in knee to a hinge joint, and the hinge joint in the ankle to a ball-joint... in traditional DCC packages you'd also have an 'up-vector' object controlling the alignment of where the knee/hinge joint should be directed. but I'm no animation expert </legal clause> Quote Vista Ultimate SP1 64bit | Q6600 2.40 GHZ | 8GB RAM | 320MB Nvidia 8800GTS Link to comment Share on other sites More sharing options...
Chris Paulson Posted January 10, 2010 Author Share Posted January 10, 2010 Your right about the hinges etc. I'm struggling though, you can't get the rotation of a hinge/joint and you can't get it's position. If I do any of the mentioned calls LE GPFs. So I am having to try and work out these values which kind of defeats the object of using it as an easy replacement for an IK solver. Quote Link to comment Share on other sites More sharing options...
Chris Paulson Posted January 10, 2010 Author Share Posted January 10, 2010 After a lot of fiddling I have got this working. Here's a blitz example: - Strict Framework leadwerks.engine Graphics 800,600 RegisterAbstractPath AppDir 'RegisterAbstractPath ".." If Not CreateWorld() RuntimeError "Failed to create world." Local cam:TCamera=CreateCamera() MoveEntity cam,Vec3(-0.2,0,-1) 'Local mesh:TMesh=CreateCube() 'Local sphere:TMesh=CreateSphere() Local hip:TBody = CreateBodyPivot( ) PositionEntity(hip,Vec3(0)) Local thigh:TBody = CreateBodyBox( 0.001, 0.2, 0.001 ) Local shin:TBody = CreateBodyBox( 0.001, 0.2, 0.001 ) Local foot:TBody = CreateBodyBox( 0.08, 0.02, 0.001 ) EntityType(thigh,1) EntityType(shin,1) EntityType(foot,1) Collisions(1,1,0) SetBodyDamping( thigh, 0, 0 ) SetBodyDamping( shin, 0, 0 ) SetBodyDamping( foot, 0, 0 ) MoveEntity(hip,Vec3(0,0.1,0)) MoveEntity(shin,Vec3(0,-0.2,0)) MoveEntity(foot,Vec3(0,-0.3,0)) SetBodyMass(thigh,10) SetBodyMass(shin,10) SetBodyMass(foot,10) SetBodyGravityMode( thigh,0) SetBodyGravityMode( shin,0) SetBodyGravityMode( foot,0) SetBodyFriction( thigh,0,0) SetBodyFriction( shin,0,0) SetBodyFriction( foot,0,0) Local knee:TBody = CreateBodyPivot( ) MoveEntity(knee,Vec3(0,-0.1,0)) EntityParent( knee, thigh ) SetBodyDamping( knee, 0, 0 ) Local kneeorb:TEntity = CreateSphere( 8, knee ) ScaleEntity( kneeorb, Vec3(0.01) ) Local ankle:TBody = CreateBodyPivot() MoveEntity(ankle,Vec3(0,-0.3,0),1) EntityParent( ankle, shin ) 'SetBodyMass(ankle,1) Local footorb:TEntity = CreateSphere( 8, ankle ) PositionEntity(footorb, Vec3(0,-0.3,0),1) ScaleEntity( footorb, Vec3(0.01) ) ''EntityParent( foot, shin ) Local ballhip:TJoint = CreateJointBall( hip, thigh, Vec3(0,0.1,0) ) SetBallJointLimits( ballhip, Vec3(0,0,0), 150, 1) 'Local ballhip:TJoint = CreateJointHinge( hip, thigh, Vec3(0,-0.1,0), Vec3(1,0,0) ) 'SetHingeJointLimits( ballhip, -90, 90 ) Local ballknee:TJoint = CreateJointHinge( thigh, shin, Vec3(0,-0.1,0), Vec3(0,0,1) ) SetHingeJointLimits( ballknee, -100, -5 ) 'Local ballknee:TJoint = CreateJointBall( thigh, shin, Vec3(0,-0.1,0) ) Local ballankle:TJoint = CreateJointHinge( shin, foot, Vec3(0,-0.3,0), Vec3(0,0,1) ) SetHingeJointLimits( ballankle, -40, 40 ) SetJointCollisionMode(ballhip,0) SetJointCollisionMode(ballknee,0) SetJointCollisionMode(ballankle,0) Local position:TVec3 Local lastposition:TVec3 = vec3(0,0,0) DebugPhysics(True) While Not KeyHit(KEY_ESCAPE) position=CameraProject(cam,vec3(MouseX(),MouseY(),1)) PositionEntity( foot, position) SetBodyVelocity(foot, vec3(0)) ' This is needed to make stuff solve IK at decent speed lastposition = EntityPosition(footorb,1) SetBodyVelocity(foot, vec3((position.x - lastposition.x) *5, (position.y - lastposition.y)*5, (position.z - lastposition.z)*5)) lastposition = position UpdateWorld( AppSpeed() ) ' UpdateWorld(100 ) RenderWorld DrawText "Move the mouse around.",0,0 Flip Wend Quote Link to comment Share on other sites More sharing options...
TylerH Posted January 11, 2010 Share Posted January 11, 2010 Pretty interesting. I had to remove the Vec3(0,0,0) from SetBallJointLimits for it to compile though. Quote nVidia 530M Intel Core i7 - 2.3Ghz 8GB DDR3 RAM Windows 7 Ultimate (64x)----- Visual Studio 2010 Ultimate Google Chrome Creative Suite 5 FL Studio 10 Office 15 ----- Expert Professional Expert BMX Programmer ----- Link to comment Share on other sites More sharing options...
Chris Paulson Posted January 12, 2010 Author Share Posted January 12, 2010 The good news:- I got a animated model moving it's limbs in sync with the physics bodies. The bad news:- I think this is a dead end as the physics solves the IK too slow and if you try to speed it up it oscillates. I think I need to write a proper IK solves, it will probably be easier than flogging the physics to death. Quote Link to comment Share on other sites More sharing options...
TylerH Posted January 12, 2010 Share Posted January 12, 2010 It isn't done, but this will IK solve hella-fast: void IKSimple::Solve(std::vector<Transform> bones, Vector3 target) { float num6; float num7; Transform transform = bones[bones.size() - 1]; std::vector<Vector3> vectorArray; std::vector<float> numArray; std::vector<Quaternion> quaternionArray; for (int i = 0; i < (bones.size() - 2); i++) { vectorArray[i] = (bones[i + 1].position - bones[i].position).Cross(bones[i + 2].position - bones[i + 1].position); vectorArray[i] = (Vector3) ((bones[i].rotation.Inverse()) * vectorArray[i]); vectorArray[i].Normalize(); numArray[i] = (bones[i + 1].position - bones[i].position).Angle(bones[i + 1].position - bones[i + 2].position); quaternionArray[i] = bones[i + 1].localRotation; } std::vector<float> numArray2; float num2 = 0.0f; for (int j = 0; j < (bones.size() - 1); j++) { Vector3 vector = bones[j + 1].position - bones[j].position; numArray2[j] = vector.Magnitude(); num2 += numArray2[j]; } this->positionAccuracy = num2 * 0.001f; Vector3 vector2 = transform.position - bones[0].position; float magnitude = vector2.Magnitude(); Vector3 vector3 = target - bones[0].position; float num5 = vector3.Magnitude(); bool flag = false; bool flag2 = false; if (num5 > magnitude) { flag = true; num7 = 1.0f; num6 = 0.0f; } else { flag2 = true; num7 = 1.0f; num6 = 0.0f; } int num8 = 0; while ((abs((float) (magnitude - num5)) > this->positionAccuracy) && (num8 < this->maxIterations)) { float num9; num8++; if (!flag) { num9 = num7; } else { num9 = (num6 + num7) / 2.0f; } for (int k = 0; k < (bones.size() - 2); k++) { float num11; if (!flag2) { num11 = math::Lerp(180.0f, numArray[k], num9); } else { num11 = (numArray[k] * (1.0f - num9)) + ((numArray[k] - 30.0f) * num9); } float angle = numArray[k] - num11; Quaternion quaternion2 = Quaternion::Quaternion(vectorArray[k],angle) * quaternionArray[k]; bones[k + 1].localRotation = quaternion2; } Vector3 vector4 = transform.position - bones[0].position; magnitude = vector4.Magnitude(); if (num5 > magnitude) { flag = true; } if (flag) { if (num5 > magnitude) { num7 = num9; } else { num6 = num9; } if (num7 >= 0.01f) { continue; } break; } num6 = num7; num7++; } bones[0].rotation = Quaternion::Quaternion(AngleAxis::AngleAxis((transform.position - bones[0].position).Cross(target - bones[0].position), (transform.position - bones[0].position).Angle(target - bones[0].position))) * bones[0].rotation; } Quote nVidia 530M Intel Core i7 - 2.3Ghz 8GB DDR3 RAM Windows 7 Ultimate (64x)----- Visual Studio 2010 Ultimate Google Chrome Creative Suite 5 FL Studio 10 Office 15 ----- Expert Professional Expert BMX Programmer ----- Link to comment Share on other sites More sharing options...
TylerH Posted January 12, 2010 Share Posted January 12, 2010 You need the Transform struct as well: #include "SVector3.h" #include "SQuaternion.h" struct Transform { Transform(TEntity entity) { this->entity = entity; TVec3 v; v = EntityPosition(entity,1); this->position = Vector3(v.X,v.Y,v.Z); v = EntityPosition(entity,0); this->localPosition = Vector3(v.X,v.Y,v.Z); v = EntityScale(entity); this->scale = Vector3(v.X,v.Y,v.Z); v = Vec3(0,1,0); v = TFormVector(v, entity, NULL); this->up = Vector3(v.X,v.Y,v.Z); v = Vec3(0,0,1); v = TFormVector(v, entity, NULL); this->forward = Vector3(v.X,v.Y,v.Z); v = Vec3(1,0,0); v = TFormVector(v, entity, NULL); this->right = Vector3(v.X,v.Y,v.Z); v = EntityRotation(entity,1); this->rotation = Quaternion(Vector3(v.X,v.Y,v.Z)); v = EntityRotation(entity,0); this->localRotation = Quaternion(Vector3(v.X,v.Y,v.Z)); } TEntity entity; Vector3 position; Vector3 localPosition; Vector3 scale; Vector3 up; Vector3 forward; Vector3 right; Quaternion rotation; Quaternion localRotation; }; And the math classes too. So if you don't have any, let me know and I will zip them up for you. Quote nVidia 530M Intel Core i7 - 2.3Ghz 8GB DDR3 RAM Windows 7 Ultimate (64x)----- Visual Studio 2010 Ultimate Google Chrome Creative Suite 5 FL Studio 10 Office 15 ----- Expert Professional Expert BMX Programmer ----- Link to comment Share on other sites More sharing options...
Chris Paulson Posted January 12, 2010 Author Share Posted January 12, 2010 It isn't done, but this will IK solve hella-fast: I recognise that code.... Looks like your getting there before me. Your using classes like Vector3 etc where do they come from? Could I put my begging bowl out and ask for a code share... Quote Link to comment Share on other sites More sharing options...
Chris Paulson Posted January 12, 2010 Author Share Posted January 12, 2010 Yes please for the zip. I must have be replying when you did the seconds post. Quote Link to comment Share on other sites More sharing options...
TylerH Posted January 13, 2010 Share Posted January 13, 2010 Attached is the ZIP with all the code. Locomotion.zip Quote nVidia 530M Intel Core i7 - 2.3Ghz 8GB DDR3 RAM Windows 7 Ultimate (64x)----- Visual Studio 2010 Ultimate Google Chrome Creative Suite 5 FL Studio 10 Office 15 ----- Expert Professional Expert BMX Programmer ----- Link to comment Share on other sites More sharing options...
Chris Paulson Posted January 13, 2010 Author Share Posted January 13, 2010 Thanks, I'll try this out tonight against my model. I guess the bones I pass in as transforms are: - Hip, Knee, Foot(Ankle) PS I wish I was better at math , you make it look easy. Quote Link to comment Share on other sites More sharing options...
Davaris Posted January 13, 2010 Share Posted January 13, 2010 Thanks for posting this TylerH. I hope you don't mind if I try it out as well. Quote Win 7 Pro 64 bit AMD Phenom II X3 720 2.8GHz GeForce 9800 GTX/9800 GTX+ 4 GB RAM Link to comment Share on other sites More sharing options...
Chris Paulson Posted January 13, 2010 Author Share Posted January 13, 2010 I'm struggling to get this to work. My code is:- void ikRanger( TVec3 position, TModel npc ) { TEntity lhip = FindChild( npc, "Frame3_figure_v05_Layer35"); TEntity lknee = FindChild( npc, "R_Knee"); TEntity lfoot = FindChild( npc, "R_Foot"); Transform thip( lhip ); Transform tknee( lknee ); Transform tfoot( lfoot ); vector<Transform> bones; bones.push_back( thip ); bones.push_back( tknee ); bones.push_back( tfoot ); IKSimple iknpc; iknpc.Solve( bones, Vector3( position.X, position.Y, position.Z )); Vector3 rot = thip.localRotation.ToAngleAxis().Axis; RotateEntity( lhip, Vec3( rot.X, rot.Y, rot.Z ) ); rot = tknee.localRotation.ToAngleAxis().Axis; RotateEntity( lknee, Vec3( rot.X, rot.Y, rot.Z ) ); rot = tfoot.localRotation.ToAngleAxis().Axis; RotateEntity( lfoot, Vec3( rot.X, rot.Y, rot.Z ) ); /* RotateEntity( lhip, Vec3( rad2deg(rot.X), rad2deg(rot.Y), rad2deg(rot.Z) ) ); rot = tknee.localRotation.ToAngleAxis().Axis; RotateEntity( lknee, Vec3( rad2deg(rot.X), rad2deg(rot.Y), rad2deg(rot.Z) ) ); rot = tfoot.localRotation.ToAngleAxis().Axis; RotateEntity( lfoot, Vec3( rad2deg(rot.X), rad2deg(rot.Y), rad2deg(rot.Z) ) ); */ } Is "thip.localRotation.ToAngleAxis().Axis" the correct thing to get back the rotations with? The transform class does: - v = EntityRotation(entity,1); this->rotation = Quaternion(Vector3(v.X,v.Y,v.Z)); Isn't EntityRotation in degrees and Quaternion in rads? Should there not be a conversion? Pity thrown at someone as bad at maths as me would be appreciated. Quote Link to comment Share on other sites More sharing options...
Chris Paulson Posted January 18, 2010 Author Share Posted January 18, 2010 Thought I'd post a progress update on this as I'm still trying to get this to work... The quaternion class did need to convert to/from radian/degrees. The class needed a new method for converting the quaternion to eualer angles. I wish you could get/set quaternions in LE (at present there's only a get). Somewhere in the code there is a math error because it's not IK'ing properly. If anyone is best mates with Pythagoras or his brother Trig feel free to pitch in... Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.