Because the work is busy, for a long time did not take notes, but sometimes found that still have to go through the previous notes to see, so still try to write down the memo.
About IK, read some paper, think of the previous translation of the article, Welman paper (http://graphics.ucsd.edu/courses/cse169_w04/welman.pdf selected passage:/http www.cnblogs.com/crazii/p/4662199.html) is very useful, getting started must read. After the introduction of the project can be combined to expand.
First, the analysis of a joint inside the CCD:
When the direction of PIC and PID coincide, the end device is closest to the target, so the pic rotates around the axis of rotation φ. Of course the axis of rotation has direction, φ also has direction (clockwise/counterclockwise).
If the spindle axis = PIC X pid is taken, the rotation angle equals ASIN (|axis|) if the PIC and PID are already flat.
In practice, it is possible to determine whether two vectors are in the same direction, and then rotate if the directions are inconsistent. The code can be simply represented as follows:
1 pic.normalize ();2 pid.normalize ();3Scalar Cosangle =pic.dotproduct (Pid);4 if(Cosangle <1.0f)//whether in same direction5 {6Vector3 axis =pic.crossproduct (Pid);7Scalar angle =Std::acos (cosangle);8 quaternion Rotation (axis, angle);9 //rotate the joint using rotationTen}
Here is the same idea as in Welman paper, but with subtle differences:
- In this case, the vector math of 3D is used to rotate the vectors, and Welman is modeled using geometric analysis, and then the extremum is obtained by using algebraic simplicity and derivative.
- Taking into account the multiple DOF of the joint (Dimensions of Freedom), axis is directly based on the PIC and PID two-directional cross product, so that axis can be in any direction, while the original is known to use a fixed hinge .
- The CCD in the original text is not singular, because the fixed hinge is used, but here the method is singular direction : When the pic and PID start in the same direction or in the opposite direction, (as in the original text, the Jacques than the singular direction of the transpose), there is no need to rotate. Moreover, the PIC x pid is a 0 vector, and the hinge is lost, resulting in gimbal lock. The problem is analyzed later.
Above is the basic algorithm of CCD problem, the following records some problems in actual use:
Constraint (constraints)
taking into account the DOF and the angle of rotation, you need to add the maximum and minimum values to the rotation angle of each joint. These limitations are local limits of the joint point, and when rotated with the CCD The rotation of the rotational process is independent of the volume of the axis, you can use a local rotation of the Euler angle.
This requires the above CCD to iterate the rotating joint, preferably in the local space of the joint. Of course, I have tried to calculate the CCD in model space (which can be equated to world space), but it must be converted to local space when applying constraints.
The establishment of the constraint angle can be defined according to the angle of the joint in the real world, such as "Elbow cannot go outward", to limit the rotation of the joint. It is important to note that the constraint angle is defined in the same space as the artist model.
For example, when modeling, the model faces toward the z+, then the knee axis is x, the corresponding Euler angle component is pitch. When the model faces toward the x+, the knee's hinge becomes z, corresponding to the roll. So if you want to configure the constraint angle, it should be consistent with the actual art specifications.
However, the blade angle constraint is obtained by analyzing the original FK animation and getting the range of motion of all joints as a constraint.
This is a quick reading of a paper found in the method, but because the paper too much to see, this method is only in the text of a sentence, so accidentally may not notice. There is also a inverse inverse kinematics method, but also analysis FK to solve IK, but not read.
This method is very simple and the disadvantage is that complex complete animations that require the original FK are valid. For example, a simple stand animation, the legs are never bent, the knee is not rotated, then the resulting constraint range is too small, resulting in IK can not be bent leg.
For the analysis of the original FK animation, Blade is to put it in the animation import/export, that is, when the animation file is generated, the way to extract all the key data, and saved in the Skeleton animation file.
The definition of constraints in Blade is as follows:
typedefstructikconstraints {FP32 mminx; FP32 Mmaxx; FP32 Mminy; FP32 Mmaxy; FP32 Mminz; FP32 Mmaxz; Inline ikconstraints () {Mminx= Mminy = Mminz =Flt_max; Mmaxx= Mmaxy = Mmaxz =-Flt_max; } inline Ikconstraints (Fp32 Minx, FP32 Maxx, Fp32 miny, Fp32 Maxy, Fp32 Minz, Fp32 maxz) {Mminx = Minx; Mmaxx =Maxx; Mminy= Miny; Mmaxy =Maxy; Mminz= Minz; MMAXZ =Maxz; } InlinevoidMergeConstsikconstraints&RHS) {Mminx=std::min (Mminx, Rhs.mminx); Mmaxx=Std::max (Mmaxx, Rhs.mmaxx); Mminy=std::min (Mminy, Rhs.mminy); Mmaxy=Std::max (Mmaxy, Rhs.mmaxy); Mminz=std::min (Mminz, Rhs.mminz); Mmaxz=Std::max (MMAXZ, rhs.mmaxz);}}ik_constraints;
You can see that the constraints contains the maximum and minimum values for the Yaw,pitch,roll as a valid range for rotation.
When creating a skeletal animation, the constraints information is extracted:
Vector<ik_constraints>constraints (Bonecount); size_t index=0; for(size_t i =0; i < Bonecount; ++i) {Scalar Initpitch=0, Inityaw =0, Initroll =0; for(size_t j =0; J < Keycountlist[i]; ++j) {Constbonedq& KEYDQ = keyframearray[index++].gettransform (); Scalar yaw, pitch, roll; KeyDQ.real.getYawPitchRoll (yaw, pitch, roll); Scalar Minpitch=std::min (pitch, Initpitch); Scalar Maxpitch=Std::max (pitch, Initpitch); Scalar Minyaw=std::min (Yaw, Inityaw); Scalar Maxyaw=Std::max (Yaw, Inityaw); Scalar Minroll=std::min (roll, initroll); Scalar Maxroll=Std::max (roll, initroll); Constraints[i].merge (Ik_constraints (Minpitch, Maxpitch, Minyaw, Maxyaw, Minroll, Maxroll)); }}
It is important to note that if you have offline tools that support skeleton file/animation merging, you will also need to merge these constraint angles.
These constraint angles are then applied to each CCD iteration. The constraint angle is the partial final pose of the joint: the angle of the state amount, not the constraint of the process quantity of the single rotation.
Therefore, the rotation calculated in the CCD is applied to the current pose of the joint point, and a quasi-final pose is obtained, and the final pose is constrained by the angle constraint:
1Vector3 T =localtransformcache[i].gettranslation ();2 //Apply Rotation3quaternion r = localtransformcache[i].getrotation () *quaternion (axis, angle);4 5 Constik_constraints& CONSTRAINTS =chain[i].getconstraints ();6 scalar yaw, pitch, roll;7 //get rotated Pose8 R.getyawpitchroll (Yaw, pitch, roll);9 Ten //Apply Constraints OnePitch =Math::clamp (pitch, Constraints.mminx, Constraints.mmaxx); AYaw =Math::clamp (Yaw, Constraints.mminy, Constraints.mmaxy); -Roll =math::clamp (Roll, Constraints.mminz, constraints.mmaxz); - the //Final Pose -Localtransformcache[i].Set(Quaternion (Yaw, pitch, roll), T);
In addition, because Blade recently redefined quaternion's operator* as Contatenate, the order is not the same as before.
Singularity problem and heuristic function based on constraint angle (singularity problem, and heuristic function based on constraints)
The singular problem of solving a CCD with a non-stationary shaft is mentioned earlier. Examples are as follows:
The position of the gizmo is the target position of the foot joint, but for the knee, the PIC and PID are already in the same direction (all facing down), Crossproduct (pic, pid) = vector 0 , so the Pid is a singular direction (singular direction), according to these two vectors can not get the hinge. So the legs don't bend. The solution could be to use the original solution of the Welman, that is, using a known fixed hinge, such as a fixed x-axis, to bend it (I did not try it for the following reasons:).
Welman mentioned that in the singular direction, the speed of convergence of the CCD will be slow.
Moreover, even with the solution of the Welman fixed shaft, the bending direction is still constrained by the restrained angle. For example, if there is no constraint, the use of a CCD to solve the leg may be "<" posture to achieve the goal, may also be ">" posture. In practice, however, the knee joint cannot be turned outward. The reasonable solution is ">". This is limited by the restraint angle,
But CCD in this problem, at the beginning of the iteration, may tend to outward, finally constrained, in fact, the iteration has been trying to outward, and the final result is not rotated.
For example: The target outward (middle to right) offset, this time is not a singular configuration, but the target point outside, and the CCD is more radical inspiration, is the end of the target "closer to the better", so the iteration, will try to turn the knee outward, to close to the target, but will be constrained angle limit, in fact, can not rotate /c0>, the parent node can only be rotated in a similar way. Finally, after several iterations, it becomes a singular direction, unable to achieve the goal, this situation also uses the fixed hinge:
And actually want the result is this (knee inward)
This time, if the constraint angle is added to the heuristic process: if it is found that a direction is constrained, it does not work, and how to iterate is meaningless, then try to move toward the direction of unconstrained angle .
This additional heuristic function prevents the joint from rotating in a meaningless direction. And he happens to be able to turn the singular direction without rotating, turning to a direction that is not constrained to constrain the angle.
1 //fix singular direction problem. and apply heuristic direction on constraints:if impossible (angle clamped) on one dire Ction, try the other.2 if(Pitch = = Constraints.mminx && constraints.mminx >-5e-2f )3Pitch = constraints.mmaxx*1e-2f;4 Else if(Pitch = = Constraints.mmaxx && Constraints.mmaxx <5e-2f )5Pitch = constraints.mminx*1e-2f;6 7 if(Yaw = = Constraints.mminy && constraints.mminy >-5e-2f )8Yaw = constraints.mmaxy*1e-2f;9 Else if(Yaw = = Constraints.mmaxy && Constraints.mmaxy <5e-2f )TenYaw = constraints.mminy*1e-2f; One A if(Roll = = Constraints.mminz && Constraints.mminz >-5e-2f ) -Roll = constraints.mmaxz*1e-2f; - Else if(Roll = = Constraints.mmaxz && Constraints.mmaxz <5e-2f ) theRoll = constraints.mminz*1e-2f;
This heuristic value is a very small offset value that, if not effective, is offset/ignored in later iterations. If it works, it will affect the subsequent iterations. At present, this heuristic in blade is more violent, directly hard code, but the principle is this.
Actual use (using IK in engine/application)
It is necessary to design the interface to set the target of iksover in practice. For example, by physics engine to get the position of the foot, the position as the leg IK chain target. The IK solving of blade is done based on the results of the FK animation after the FK animation, so no additional blending is required.
With regard to the generation of IK chain, Blade is built at runtime (at load time) based on the name of the bone, rather than offline generation.
In addition, Blade's IK pattern is divided into two types:
Simple IK mode: A skeleton contains multiple IK chain, such as legs and arms, 4 IK chain, but these IK chain are independent and do not affect the entire body posture. For example, two legs in the pelvic bone (pelvis) in the merger, then the pelvic bone as the leg two chain of the shared base, to this end. The pelvis does not participate in IK calculations, so the legs do not affect each other. This method is very simple and suitable for use with only the hand or foot positioning (foot placement).
Fullbody IK mode: The entire skeleton is a unique IK chain that contains multiple end effector. Each effector may affect the entire pose of the body, so it affects other effector, such as when the left foot is positioned, and the pelvic bone rotates, causing the right foot to be affected. online Many paper said CCD can only solve a single effector IK chain, for multiple effectors, CCD does not apply, in fact I tried is possible. The overall idea of the algorithm is to be Fabrik (forward and Inspired by backward reach inverse kinematics) . (Http://www.academia.edu/9165835/FABRIK_A_fast_iterative_solver_for_the_Inverse_Kinematics_problem pdf) Of course, the CCD solution is actually used here.
Fullbody IK is suitable for complex needs, such as my favorite < Tomb Raider > series, which is needed for climbing and jumping.
Points to note: Simple ik foot positioning can not affect the root node, so if you encounter rough ground, you need to find the lowest point, the whole character to the lowest point, and then calculate IK. Fullbody IK can theoretically automatically calculate the position of the body, but it is necessary to set the node as a displacement-type joint, rather than a rotational joint, to reposition the entire body, but the blade is not yet supported, and the time after that is added. and moving the body position is not universal, perhaps the most solve parameter is better, for example: When the hand reach is also moving the whole body, it may occur teleport. and the ground height difference is too big, perhaps to deal with. Wait, these specific logic will not unfold.
Other legacy issues: the current use of the hand/foot positioning, and the precise positioning of the finger/toe, sometimes need, this later slowly refinement.
Error control (Error tolerance)
The error currently used by Blade is 0.001 because the IK calculation is in model space and bone local space, so it is not necessary to consider the scale of the model. However, this 0.001 is based on the model/skeleton size as a reference, the reference value is 2.0 (m) height. For models of different sizes, this error value is scaled based on the reference value.
static const scalar reference_ Sizesq = (1.5f *1.5f ) + (2.0f *2.0f ) + (0.5f *0.5f ); static const scalar min_distance = ; static const scalar min_distancesq = (min_distance*min_distance)/ Reference_sizesq; const scalar tolerance = min_distancesq* (Mik->getsquaredsize ());
The actual model size can be obtained by the model's original size, or by the size of the skeleton's binding pose. Blade for animation and model as far as possible decoupling, using the entire bounding box radius of the skeleton.
Efficiency (performance)
The efficiency of the test results is fine, and subsequent optimizations may continue, followed by some small details of the optimization. At present, CPU i7 4770K, single-threaded calculation, solving a valid IK joint number is, end effecotor number of 4 full body IK, the maximum iteration number 20, the maximum time spent around ~0.4ms.
The simple IK solution time of 4 chain is approximately 0.1ms.
If you work with an animated Lod, it can be useful to selectively turn on IK, for example, if only the main character turns on IK, or near a character.
Remember so much feeling a little tired, back if there is time to continue to write a memo. IK's pit was going in last year, but the job was too busy. Currently Mile stone 2:model is already over, mile stone 3 is estimated to start by the end of next year, only this period of time a little free. And the work is very busy, oneself also need to rest. The plan behind deferred shading is to use Intz to do the depth pre pass to give full play to the early Z effect and then MRT to render normals and colors. Dx9 later APIs can read the depth buffer directly, so that it does not need to render the depth separately, and Nvidia graphics card from the G80 will also have Intz to expose the new API features, so you can use. This allows you to maximize earlyz, avoid overdraw, and also reduce g The size of the buffer.
Finally, compare the simple ik with the fullbody ik (the body will also tilt when fullbody). Another try to use fullbody ik positioning limbs, the stand animation into a climbing animation, is also feasible.
Engine design Tracking (nine. 14.2 final) Application of inverse KINEMATICS:CCD in blade