123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497 |
- //-----------------------------------------------------------------------------
- // Copyright (c) 2012 GarageGames, LLC
- //
- // Permission is hereby granted, free of charge, to any person obtaining a copy
- // of this software and associated documentation files (the "Software"), to
- // deal in the Software without restriction, including without limitation the
- // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- // sell copies of the Software, and to permit persons to whom the Software is
- // furnished to do so, subject to the following conditions:
- //
- // The above copyright notice and this permission notice shall be included in
- // all copies or substantial portions of the Software.
- //
- // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- // IN THE SOFTWARE.
- //-----------------------------------------------------------------------------
- #include "platform/input/leapMotion/leapMotionFrame.h"
- #include "platform/input/leapMotion/leapMotionUtil.h"
- #include "console/engineAPI.h"
- #include "math/mAngAxis.h"
- #include "math/mTransform.h"
- U32 LeapMotionFrame::smNextInternalFrameId = 0;
- IMPLEMENT_CONOBJECT(LeapMotionFrame);
- ImplementEnumType( LeapMotionFramePointableType,
- "Leap Motion pointable type.\n\n")
- { LeapMotionFrame::PT_UNKNOWN, "Unknown", "Unknown pointable type.\n" },
- { LeapMotionFrame::PT_FINGER, "Finger", "Finger pointable type.\n" },
- { LeapMotionFrame::PT_TOOL, "Tool", "Tool pointable type.\n" },
- EndImplementEnumType;
- LeapMotionFrame::LeapMotionFrame()
- {
- clear();
- }
- LeapMotionFrame::~LeapMotionFrame()
- {
- clear();
- }
- void LeapMotionFrame::initPersistFields()
- {
- Parent::initPersistFields();
- }
- bool LeapMotionFrame::onAdd()
- {
- if (!Parent::onAdd())
- return false;
- return true;
- }
- void LeapMotionFrame::onRemove()
- {
- Parent::onRemove();
- }
- void LeapMotionFrame::clear()
- {
- mFrameValid = false;
- mHandCount = 0;
- mHandValid.clear();
- mHandId.clear();
- mHandRawPos.clear();
- mHandPos.clear();
- mHandRot.clear();
- mHandRotQuat.clear();
- mHandRotAxis.clear();
- mHandPointablesCount.clear();
- mPointableCount = 0;
- mPointableValid.clear();
- mPointableId.clear();
- mPointableHandIndex.clear();
- mPointableType.clear();
- mPointableRawPos.clear();
- mPointablePos.clear();
- mPointableRot.clear();
- mPointableRotQuat.clear();
- mPointableLength.clear();
- mPointableWidth.clear();
- }
- void LeapMotionFrame::copyFromFrame(const Leap::Frame& frame, const F32& maxHandAxisRadius)
- {
- // This also resets all counters
- clear();
- // Retrieve frame information
- mFrameValid = frame.isValid();
- mFrameId = frame.id();
- mFrameTimeStamp = frame.timestamp();
- mFrameInternalId = smNextInternalFrameId;
- ++smNextInternalFrameId;
- mFrameSimTime = Sim::getCurrentTime();
- mFrameRealTime = Platform::getRealMilliseconds();
- if(!mFrameValid)
- {
- return;
- }
- // Retrieve hand information
- mHandCount = frame.hands().count();
- if(mHandCount > 0)
- {
- copyFromFrameHands(frame.hands(), maxHandAxisRadius);
- }
- // Retrieve pointable information
- mPointableCount = frame.pointables().count();
- if(mPointableCount > 0)
- {
- copyFromFramePointables(frame.pointables());
- }
- }
- void LeapMotionFrame::copyFromFrameHands(const Leap::HandList& hands, const F32& maxHandAxisRadius)
- {
- // Set up Vectors
- mHandValid.increment(mHandCount);
- mHandId.increment(mHandCount);
- mHandRawPos.increment(mHandCount);
- mHandPos.increment(mHandCount);
- mHandRot.increment(mHandCount);
- mHandRotQuat.increment(mHandCount);
- mHandRotAxis.increment(mHandCount);
- mHandPointablesCount.increment(mHandCount);
- // Copy data
- for(U32 i=0; i<mHandCount; ++i)
- {
- const Leap::Hand& hand = hands[i];
- mHandValid[i] = hand.isValid();
- mHandId[i] = hand.id();
-
- // Position
- LeapMotionUtil::convertPosition(hand.palmPosition(), mHandRawPos[i]);
- mHandPos[i].x = (S32)mFloor(mHandRawPos[i].x);
- mHandPos[i].y = (S32)mFloor(mHandRawPos[i].y);
- mHandPos[i].z = (S32)mFloor(mHandRawPos[i].z);
- // Rotation
- LeapMotionUtil::convertHandRotation(hand, mHandRot[i]);
- mHandRotQuat[i].set(mHandRot[i]);
- // Thumb stick axis rotation
- LeapMotionUtil::calculateHandAxisRotation(mHandRot[i], maxHandAxisRadius, mHandRotAxis[i]);
- // Pointables
- mHandPointablesCount[i] = hand.pointables().count();
- }
- }
- void LeapMotionFrame::copyFromFramePointables(const Leap::PointableList& pointables)
- {
- // Set up Vectors
- mPointableValid.increment(mPointableCount);
- mPointableId.increment(mPointableCount);
- mPointableHandIndex.increment(mPointableCount);
- mPointableType.increment(mPointableCount);
- mPointableRawPos.increment(mPointableCount);
- mPointablePos.increment(mPointableCount);
- mPointableRot.increment(mPointableCount);
- mPointableRotQuat.increment(mPointableCount);
- mPointableLength.increment(mPointableCount);
- mPointableWidth.increment(mPointableCount);
- // Copy data
- for(U32 i=0; i<mPointableCount; ++i)
- {
- const Leap::Pointable& pointable = pointables[i];
- mPointableValid[i] = pointable.isValid();
- mPointableId[i] = pointable.id();
- mPointableLength[i] = pointable.length();
- mPointableWidth[i] = pointable.width();
- mPointableType[i] = PT_UNKNOWN;
- if(pointable.isFinger())
- {
- mPointableType[i] = PT_FINGER;
- }
- else if(pointable.isTool())
- {
- mPointableType[i] = PT_TOOL;
- }
- // Which hand, if any
- const Leap::Hand& hand = pointable.hand();
- if(hand.isValid())
- {
- bool found = false;
- S32 handId = hand.id();
- for(U32 j=0; j<mHandCount; ++j)
- {
- if(mHandId[j] == handId)
- {
- mPointableHandIndex[i] = j;
- found = true;
- break;
- }
- }
- if(!found)
- {
- mPointableHandIndex[i] = -1;
- }
- }
- else
- {
- mPointableHandIndex[i] = -1;
- }
- // Position
- LeapMotionUtil::convertPosition(pointable.tipPosition(), mPointableRawPos[i]);
- mPointablePos[i].x = (S32)mFloor(mPointableRawPos[i].x);
- mPointablePos[i].y = (S32)mFloor(mPointableRawPos[i].y);
- mPointablePos[i].z = (S32)mFloor(mPointableRawPos[i].z);
- // Rotation
- LeapMotionUtil::convertPointableRotation(pointable, mPointableRot[i]);
- mPointableRotQuat[i].set(mPointableRot[i]);
- }
- }
- //-----------------------------------------------------------------------------
- DefineEngineMethod( LeapMotionFrame, isFrameValid, bool, ( ),,
- "@brief Checks if this frame is valid.\n\n"
- "@return True if the frame is valid.\n\n")
- {
- return object->isFrameValid();
- }
- DefineEngineMethod( LeapMotionFrame, getFrameInternalId, S32, ( ),,
- "@brief Provides the internal ID for this frame.\n\n"
- "@return Internal ID of this frame.\n\n")
- {
- return object->getFrameInternalId();
- }
- DefineEngineMethod( LeapMotionFrame, getFrameSimTime, S32, ( ),,
- "@brief Get the sim time that this frame was generated.\n\n"
- "@return Sim time of this frame in milliseconds.\n\n")
- {
- return object->getFrameSimTime();
- }
- DefineEngineMethod( LeapMotionFrame, getFrameRealTime, S32, ( ),,
- "@brief Get the real time that this frame was generated.\n\n"
- "@return Real time of this frame in milliseconds.\n\n")
- {
- return object->getFrameRealTime();
- }
- DefineEngineMethod( LeapMotionFrame, getHandCount, S32, ( ),,
- "@brief Get the number of hands defined in this frame.\n\n"
- "@return The number of defined hands.\n\n")
- {
- return object->getHandCount();
- }
- DefineEngineMethod( LeapMotionFrame, getHandValid, bool, ( S32 index ),,
- "@brief Check if the requested hand is valid.\n\n"
- "@param index The hand index to check.\n"
- "@return True if the hand is valid.\n\n")
- {
- return object->getHandValid(index);
- }
- DefineEngineMethod( LeapMotionFrame, getHandId, S32, ( S32 index ),,
- "@brief Get the ID of the requested hand.\n\n"
- "@param index The hand index to check.\n"
- "@return ID of the requested hand.\n\n")
- {
- return object->getHandId(index);
- }
- DefineEngineMethod( LeapMotionFrame, getHandRawPos, Point3F, ( S32 index ),,
- "@brief Get the raw position of the requested hand.\n\n"
- "The raw position is the hand's floating point position converted to "
- "Torque 3D coordinates (in millimeters).\n"
- "@param index The hand index to check.\n"
- "@return Raw position of the requested hand.\n\n")
- {
- return object->getHandRawPos(index);
- }
- DefineEngineMethod( LeapMotionFrame, getHandPos, Point3I, ( S32 index ),,
- "@brief Get the position of the requested hand.\n\n"
- "The position is the hand's integer position converted to "
- "Torque 3D coordinates (in millimeters).\n"
- "@param index The hand index to check.\n"
- "@return Integer position of the requested hand (in millimeters).\n\n")
- {
- return object->getHandPos(index);
- }
- DefineEngineMethod( LeapMotionFrame, getHandRot, AngAxisF, ( S32 index ),,
- "@brief Get the rotation of the requested hand.\n\n"
- "The Leap Motion hand rotation as converted into the Torque 3D"
- "coordinate system.\n"
- "@param index The hand index to check.\n"
- "@return Rotation of the requested hand.\n\n")
- {
- AngAxisF aa(object->getHandRot(index));
- return aa;
- }
- DefineEngineMethod( LeapMotionFrame, getHandRawTransform, TransformF, ( S32 index ),,
- "@brief Get the raw transform of the requested hand.\n\n"
- "@param index The hand index to check.\n"
- "@return The raw position and rotation of the requested hand (in Torque 3D coordinates).\n\n")
- {
- const Point3F& pos = object->getHandRawPos(index);
- const QuatF& qa = object->getHandRotQuat(index);
- AngAxisF aa(qa);
- aa.axis.normalize();
- TransformF trans(pos, aa);
- return trans;
- }
- DefineEngineMethod( LeapMotionFrame, getHandTransform, TransformF, ( S32 index ),,
- "@brief Get the transform of the requested hand.\n\n"
- "@param index The hand index to check.\n"
- "@return The position and rotation of the requested hand (in Torque 3D coordinates).\n\n")
- {
- const Point3I& pos = object->getHandPos(index);
- const QuatF& qa = object->getHandRotQuat(index);
- AngAxisF aa(qa);
- aa.axis.normalize();
- TransformF trans;
- trans.mPosition = Point3F(pos.x, pos.y, pos.z);
- trans.mOrientation = aa;
- return trans;
- }
- DefineEngineMethod( LeapMotionFrame, getHandRotAxis, Point2F, ( S32 index ),,
- "@brief Get the axis rotation of the requested hand.\n\n"
- "This is the axis rotation of the hand as if the hand were a gamepad thumb stick. "
- "Imagine a stick coming out the top of the hand and tilting the hand front, back, "
- "left and right controls that stick. The values returned along the x and y stick "
- "axis are normalized from -1.0 to 1.0 with the maximum hand tilt angle for these "
- "values as defined by $LeapMotion::MaximumHandAxisAngle.\n"
- "@param index The hand index to check.\n"
- "@return Axis rotation of the requested hand.\n\n"
- "@see LeapMotion::MaximumHandAxisAngle\n")
- {
- return object->getHandRotAxis(index);
- }
- DefineEngineMethod( LeapMotionFrame, getHandPointablesCount, S32, ( S32 index ),,
- "@brief Get the number of pointables associated with this hand.\n\n"
- "@param index The hand index to check.\n"
- "@return Number of pointables that belong with this hand.\n\n")
- {
- return object->getHandPointablesCount(index);
- }
- DefineEngineMethod( LeapMotionFrame, getPointablesCount, S32, ( ),,
- "@brief Get the number of pointables defined in this frame.\n\n"
- "@return The number of defined pointables.\n\n")
- {
- return object->getPointablesCount();
- }
- DefineEngineMethod( LeapMotionFrame, getPointableValid, bool, ( S32 index ),,
- "@brief Check if the requested pointable is valid.\n\n"
- "@param index The pointable index to check.\n"
- "@return True if the pointable is valid.\n\n")
- {
- return object->getPointableValid(index);
- }
- DefineEngineMethod( LeapMotionFrame, getPointableId, S32, ( S32 index ),,
- "@brief Get the ID of the requested pointable.\n\n"
- "@param index The pointable index to check.\n"
- "@return ID of the requested pointable.\n\n")
- {
- return object->getPointableId(index);
- }
- DefineEngineMethod( LeapMotionFrame, getPointableHandIndex, S32, ( S32 index ),,
- "@brief Get the index of the hand that this pointable belongs to, if any.\n\n"
- "@param index The pointable index to check.\n"
- "@return Index of the hand this pointable belongs to, or -1 if there is no associated hand.\n\n")
- {
- return object->getPointableHandIndex(index);
- }
- DefineEngineMethod( LeapMotionFrame, getPointableType, LeapMotionFramePointableType, ( S32 index ),,
- "@brief Get the type of the requested pointable.\n\n"
- "@param index The pointable index to check.\n"
- "@return Type of the requested pointable.\n\n")
- {
- return object->getPointableType(index);
- }
- DefineEngineMethod( LeapMotionFrame, getPointableRawPos, Point3F, ( S32 index ),,
- "@brief Get the raw position of the requested pointable.\n\n"
- "The raw position is the pointable's floating point position converted to "
- "Torque 3D coordinates (in millimeters).\n"
- "@param index The pointable index to check.\n"
- "@return Raw position of the requested pointable.\n\n")
- {
- return object->getPointableRawPos(index);
- }
- DefineEngineMethod( LeapMotionFrame, getPointablePos, Point3I, ( S32 index ),,
- "@brief Get the position of the requested pointable.\n\n"
- "The position is the pointable's integer position converted to "
- "Torque 3D coordinates (in millimeters).\n"
- "@param index The pointable index to check.\n"
- "@return Integer position of the requested pointable (in millimeters).\n\n")
- {
- return object->getPointablePos(index);
- }
- DefineEngineMethod( LeapMotionFrame, getPointableRot, AngAxisF, ( S32 index ),,
- "@brief Get the rotation of the requested pointable.\n\n"
- "The Leap Motion pointable rotation as converted into the Torque 3D"
- "coordinate system.\n"
- "@param index The pointable index to check.\n"
- "@return Rotation of the requested pointable.\n\n")
- {
- AngAxisF aa(object->getPointableRot(index));
- return aa;
- }
- DefineEngineMethod( LeapMotionFrame, getPointableRawTransform, TransformF, ( S32 index ),,
- "@brief Get the raw transform of the requested pointable.\n\n"
- "@param index The pointable index to check.\n"
- "@return The raw position and rotation of the requested pointable (in Torque 3D coordinates).\n\n")
- {
- const Point3F& pos = object->getPointableRawPos(index);
- const QuatF& qa = object->getPointableRotQuat(index);
- AngAxisF aa(qa);
- aa.axis.normalize();
- TransformF trans(pos, aa);
- return trans;
- }
- DefineEngineMethod( LeapMotionFrame, getPointableTransform, TransformF, ( S32 index ),,
- "@brief Get the transform of the requested pointable.\n\n"
- "@param index The pointable index to check.\n"
- "@return The position and rotation of the requested pointable (in Torque 3D coordinates).\n\n")
- {
- const Point3I& pos = object->getPointablePos(index);
- const QuatF& qa = object->getPointableRotQuat(index);
- AngAxisF aa(qa);
- aa.axis.normalize();
- TransformF trans;
- trans.mPosition = Point3F(pos.x, pos.y, pos.z);
- trans.mOrientation = aa;
- return trans;
- }
- DefineEngineMethod( LeapMotionFrame, getPointableLength, F32, ( S32 index ),,
- "@brief Get the length of the requested pointable.\n\n"
- "@param index The pointable index to check.\n"
- "@return Length of the requested pointable (in millimeters).\n\n")
- {
- return object->getPointableLength(index);
- }
- DefineEngineMethod( LeapMotionFrame, getPointableWidth, F32, ( S32 index ),,
- "@brief Get the width of the requested pointable.\n\n"
- "@param index The pointable index to check.\n"
- "@return Width of the requested pointable (in millimeters).\n\n")
- {
- return object->getPointableWidth(index);
- }
|