summaryrefslogtreecommitdiff
path: root/indra/llcharacter/lljointsolverrp3.h
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llcharacter/lljointsolverrp3.h')
-rw-r--r--indra/llcharacter/lljointsolverrp3.h158
1 files changed, 158 insertions, 0 deletions
diff --git a/indra/llcharacter/lljointsolverrp3.h b/indra/llcharacter/lljointsolverrp3.h
new file mode 100644
index 0000000000..d1507351b6
--- /dev/null
+++ b/indra/llcharacter/lljointsolverrp3.h
@@ -0,0 +1,158 @@
+/**
+ * @file lljointsolverrp3.h
+ * @brief Implementation of LLJointSolverRP3 class
+ *
+ * Copyright (c) 2001-$CurrentYear$, Linden Research, Inc.
+ * $License$
+ */
+
+#ifndef LL_LLJOINTSOLVERRP3_H
+#define LL_LLJOINTSOLVERRP3_H
+
+//-----------------------------------------------------------------------------
+// Header Files
+//-----------------------------------------------------------------------------
+#include "lljoint.h"
+
+/* -some compilers don't like line continuation chars-
+//-----------------------------------------------------------------------------
+// class LLJointSolverRP3
+//
+// This class is a "poor man's" IK for simple 3 joint kinematic chains.
+// It is modeled after the 'ikRPSolver' in Maya.
+// This class takes 4 LLJoints:
+// jointA
+// jointB
+// jointC
+// jointGoal
+//
+// Such that jointA is the parent of jointB, jointB is the parent of jointC.
+// When invoked, this class modifies the rotations of jointA and jointB such
+// that the position of the jointC attempts to reach the position of jointGoal.
+//
+// At object initialization time, the distances between jointA - jointB and
+// jointB - jointC are cached. During evaluation these bone lengths are
+// preserved.
+//
+// A A
+// | |
+// | |
+// B B---CG A---B---C...G
+// \
+// \
+// CG
+//
+//
+// In addition a "poleVector" is specified that does two things:
+//
+// a) defines the plane in which the solution occurs, thus
+// reducing an infinite number of solutions, down to 2.
+//
+// b) disambiguates the resulting two solutions as follows:
+//
+// A A A--->poleVector
+// | \ \
+// | \ \
+// B vs. B ==> B
+// \ | |
+// \ | |
+// CG CG CG
+//
+// A "twist" setting allows the solution plane to be rotated about the
+// line between A and C. A handy animation feature.
+//
+// For "smarter" results for non-coplanar limbs, specify the joints axis
+// of bend in the B's local frame (see setBAxis())
+//-----------------------------------------------------------------------------
+*/
+
+class LLJointSolverRP3
+{
+protected:
+ LLJoint *mJointA;
+ LLJoint *mJointB;
+ LLJoint *mJointC;
+ LLJoint *mJointGoal;
+
+ F32 mLengthAB;
+ F32 mLengthBC;
+
+ LLVector3 mPoleVector;
+ LLVector3 mBAxis;
+ BOOL mbUseBAxis;
+
+ F32 mTwist;
+
+ BOOL mFirstTime;
+ LLMatrix4 mSavedJointAMat;
+ LLMatrix4 mSavedInvPlaneMat;
+
+ LLQuaternion mJointABaseRotation;
+ LLQuaternion mJointBBaseRotation;
+
+public:
+ //-------------------------------------------------------------------------
+ // Constructor/Destructor
+ //-------------------------------------------------------------------------
+ LLJointSolverRP3();
+ virtual ~LLJointSolverRP3();
+
+ //-------------------------------------------------------------------------
+ // setupJoints()
+ // This must be called one time to setup the solver.
+ // This must be called AFTER the skeleton has been created, all parent/child
+ // relationships are established, and after the joints are placed in
+ // a valid configuration (as distances between them will be cached).
+ //-------------------------------------------------------------------------
+ void setupJoints( LLJoint* jointA,
+ LLJoint* jointB,
+ LLJoint* jointC,
+ LLJoint* jointGoal );
+
+ //-------------------------------------------------------------------------
+ // getPoleVector()
+ // Returns the current pole vector.
+ //-------------------------------------------------------------------------
+ const LLVector3& getPoleVector();
+
+ //-------------------------------------------------------------------------
+ // setPoleVector()
+ // Sets the pole vector.
+ // The pole vector is defined relative to (in the space of) jointA's parent.
+ // The default pole vector is (1,0,0), and this is used if this function
+ // is never called.
+ // This vector is normalized when set.
+ //-------------------------------------------------------------------------
+ void setPoleVector( const LLVector3& poleVector );
+
+ //-------------------------------------------------------------------------
+ // setBAxis()
+ // Sets the joint's axis in B's local frame, and enable "smarter" solve().
+ // This allows for smarter IK when for twisted limbs.
+ //-------------------------------------------------------------------------
+ void setBAxis( const LLVector3& bAxis );
+
+ //-------------------------------------------------------------------------
+ // getTwist()
+ // Returns the current twist in radians.
+ //-------------------------------------------------------------------------
+ F32 getTwist();
+
+ //-------------------------------------------------------------------------
+ // setTwist()
+ // Sets the twist value.
+ // The default is 0.0.
+ //-------------------------------------------------------------------------
+ void setTwist( F32 twist );
+
+ //-------------------------------------------------------------------------
+ // solve()
+ // This is the "work" function.
+ // When called, the rotations of jointA and jointB will be modified
+ // such that jointC attempts to reach jointGoal.
+ //-------------------------------------------------------------------------
+ void solve();
+};
+
+#endif // LL_LLJOINTSOLVERRP3_H
+