/*
-----------------------------------------------------------------------------
This source file is part of OpenSpace3D
For the latest info, see http://www.openspace3d.com
Copyright (c) 2012 I-maginer
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any later
version.
This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place - Suite 330, Boston, MA 02111-1307, USA, or go to
http://www.gnu.org/copyleft/lesser.txt
-----------------------------------------------------------------------------
*/
/*******************************************************************************
Plugin Kinect
Client part
Version: 1.0
Author: I-maginer
Date: 14/02/20011
Last update: 14/03/2011
*******************************************************************************/
var SKL_USE_GLOBAL_COORDS = 0;;
var fConfidence = 0.2;;
var iPosTime = 800;;
var iLPosTime = 500;;
var POSHX = 0;;
var POSLCLICK = 1;;
var POSRCLICK = 2;;
var POSLSWIPE = 3;;
var POSRSWIPE = 4;;
// set to 1 to enable training
var bPoseTrain = 0;;
var lPoseLabel = "T pose"::"Cross"::"Hands up"::"Stand"::"Show left"::"Show right"::nil;;
typeof lBonesBindNames = [[I [S r1]] r1];;
struct PlugKinectUserStr = [
KINU_Inst : PInstance,
KINU_Device : ObjKinect,
KINU_User : ObjKinectUser,
KINU_Mesh : [SO3_OBJECT [F F F] [F F F F]],
KINU_tScale : [F F F],
KINU_bFlipX : I,
KINU_tPmargin : [I I],
KINU_lJointsList : [[SO3_OBJECT [I [F F F] [F F F F] [F F F F] [F F F F]]] r1],
KINU_InitPos : [F F F],
KINU_iLeftHandFigure : I,
KINU_iRightHandFigure : I,
KINU_tRightHandFingers : [I I I],
KINU_tLeftHandFingers : [I I I],
KINU_tLeftHandPos : [F F F],
KINU_tRightHandPos : [F F F],
KINU_tLeftHandClickPos : [F F F],
KINU_tRightHandClickPos : [F F F],
KINU_tLastLeftHandTrans : [F F F],
KINU_tLastRightHandTrans : [F F F],
KINU_mlp : ObjMl,
KINU_sLastdetectedPose : S,
KINU_sLastHeadTracking : [[F F F] [F F F]],
KINU_iTrainingPos : I
] mkPlugKinectUserStr;;
fun resetBone(bone, kuserstr)=
let SO3ObjectGetChildren bone -> lchild in
let switch kuserstr.KINU_lJointsList bone -> [joint _ _ lquat _] in
(
SO3ObjectSetInheritOrientation bone 1;
SO3ObjectSetOrientation bone lquat;
while lchild != nil do
(
resetBone (hd lchild) kuserstr;
set lchild = tl lchild;
);
);
0;;
fun resetSkeleton(kuserstr)=
let kuserstr.KINU_Mesh -> [mesh ovec oquat] in
let SO3GetRootBoneFromMesh mesh -> rootbone in
(
SO3ObjectSetOrientation mesh oquat;
SO3ObjectSetPosition mesh ovec;
let switch kuserstr.KINU_lJointsList rootbone -> [joint vec _ _ _] in
SO3ObjectSetPosition rootbone vec;
if (rootbone == nil) then nil else
resetBone rootbone kuserstr;
);
set kuserstr.KINU_InitPos = nil;
0;;
fun updateBone(l, kuserstr)=
if l == nil then nil else
let hd l -> [bone p] in
let p -> [joint ovec oquat lquat lastquat] in
(
if (joint == USER_SKEL_L_HAND) || (joint == USER_SKEL_R_HAND) then nil else
// local joint quaternion in world
let _GETKinectUserJointOrientation kuserstr.KINU_User joint fConfidence -> jquat in
if (jquat == nil) then nil else
(
if (SKL_USE_GLOBAL_COORDS) then
(
//using global
let kuserstr.KINU_Mesh -> [mesh _ _] in
let (SO3ObjectGetGlobalOrientation mesh) -> mquat in
let SO3MathsQuatAdd mquat jquat -> jquat in
let SO3MathsQuatAdd jquat SO3MathsQuatAdd mquat oquat -> fquat in
//let if lastquat == nil then fquat else SO3MathsQuatInterpolate lastquat fquat 0.9 1 -> fquat in
(
SO3ObjectSetGlobalOrientation bone fquat;
mutate p <- [_ _ _ _ fquat];
);
)
else
(
//using local
SO3ObjectSetInheritOrientation bone 0;
SO3ObjectResetOrientation bone;
let SO3GetBoneLocalOrientation bone jquat -> quat in
let SO3MathsQuatAdd quat oquat -> fquat in
//let if lastquat == nil then fquat else SO3MathsQuatInterpolate lastquat fquat 0.9 1 -> fquat in
(
SO3ObjectSetOrientation bone fquat;
mutate p <- [_ _ _ _ fquat];
);
);
);
updateBone (tl l) kuserstr;
);
0;;
fun updateSkeleton(kuserstr)=
let kuserstr.KINU_Mesh -> [mesh ovec oquat] in
let SO3GetRootBoneFromMesh mesh -> rootbone in
(
if (rootbone == nil) then nil else
updateBone kuserstr.KINU_lJointsList kuserstr;
);
0;;
fun getBoneByJoint(kuserstr, joint)=
let nil -> bone in
(
let sizelist kuserstr.KINU_lJointsList -> size in
let 0 -> i in
while (i < size) && (bone == nil) do
(
let nth_list kuserstr.KINU_lJointsList i -> [ebone [jnt _ _ _ _]] in
if (joint != jnt) then nil else
set bone = ebone;
set i = i + 1;
);
bone;
);;
fun getAngParam(kuserstr, quat, joint)=
let kuserstr.KINU_tScale -> [xscale yscale zscale] in
let if (joint == USER_SKEL_HEAD) || (joint == USER_SKEL_L_HAND) || (joint == USER_SKEL_R_HAND) then
getBoneByJoint kuserstr joint
else
nil
-> bone in
let kuserstr.KINU_Mesh -> [mesh _ _] in
if (bone != nil) then
(
let SO3MathsQuatToEulerXYZ SO3ObjectGetGlobalOrientation bone -> [x y z] in
strcatn (ftoa SO3MathsRadianToDegree x)::" "::(ftoa SO3MathsRadianToDegree y)::" "::(ftoa SO3MathsRadianToDegree z)::nil;
)
else if (mesh != nil) then
(
let SO3ObjectGetGlobalOrientation mesh -> gquat in
let SO3MathsQuatToEulerXYZ (SO3MathsQuatAdd gquat quat) -> [x y z] in
strcatn (ftoa SO3MathsRadianToDegree x)::" "::(ftoa SO3MathsRadianToDegree y)::" "::(ftoa SO3MathsRadianToDegree z)::nil;
)
else
(
let SO3MathsQuatToEulerXYZ quat -> [x y z] in
strcatn (ftoa SO3MathsRadianToDegree x)::" "::(ftoa SO3MathsRadianToDegree y)::" "::(ftoa SO3MathsRadianToDegree z)::nil;
);;
fun getVecParam(kuserstr, vec, joint)=
let kuserstr.KINU_tScale -> [xscale yscale zscale] in
let vec -> [x y z] in
let if (joint == USER_SKEL_HEAD) || (joint == USER_SKEL_L_HAND) || (joint == USER_SKEL_R_HAND) then
getBoneByJoint kuserstr joint
else
nil
-> bone in
let kuserstr.KINU_Mesh -> [mesh _ _] in
if (bone != nil) then
(
let SO3ObjectGetGlobalPosition bone -> [x y z] in
strcatn (ftoa x)::" "::(ftoa y)::" "::(ftoa z)::nil;
)
else if (mesh != nil) then
(
let [(-.x) y (-.z)] -> vec in
let SO3ObjectGetGlobalPosition mesh -> gvec in
let SO3MathsQuatGetDirection (SO3ObjectGetGlobalOrientation mesh) vec -> dir in
let if (gvec == nil) then vec else addVectorF gvec (subVectorF dir gvec) -> [x y z] in
strcatn (ftoa (xscale *. x))::" "::(ftoa (yscale *. y))::" "::(ftoa (zscale *. z))::nil;
)
else
(
let [x y z] -> vec in
strcatn (ftoa (xscale *. (if kuserstr.KINU_bFlipX then -.x else x)))::" "::(ftoa (yscale *. y))::" "::(ftoa (zscale *. z))::nil;
);;
/*
fun getOrientationParam(kuserstr, quat, joint)=
let kuserstr.KINU_tScale -> [xscale yscale zscale] in
let if (joint == USER_SKEL_HEAD) || (joint == USER_SKEL_L_HAND) || (joint == USER_SKEL_R_HAND) then
getBoneByJoint kuserstr joint
else
nil
-> bone in
let kuserstr.KINU_Mesh -> [mesh _ _] in
if (bone != nil) then
(
let SO3ObjectGetGlobalOrientation bone -> gquat in
let SO3MathsQuatToEulerXYZ gquat -> [ax ay az] in
strcatn (ftoa SO3MathsRadianToDegree ax)::" "::(ftoa SO3MathsRadianToDegree ay)::" "::(ftoa SO3MathsRadianToDegree az)::nil;
)
else if (mesh != nil) then
(
let [(-.x) y (-.z)] -> vec in
let SO3MathsQuatAdd (SO3ObjectGetGlobalPosition mesh) quat -> gquat in
let SO3MathsQuatToEulerXYZ gquat -> [ax ay az] in
strcatn (ftoa SO3MathsRadianToDegree ax)::" "::(ftoa SO3MathsRadianToDegree ay)::" "::(ftoa SO3MathsRadianToDegree az)::nil;
)
else
//use the current camera if mesh is not set
(
let V3DgetDefaultCamera c3dXsession -> cam in
let SO3MathsQuatGetDirection (SO3ObjectGetGlobalOrientation cam) vec -> dir in
let if (gvec == nil) || ((joint != USER_SKEL_L_HAND) && (joint != USER_SKEL_R_HAND)) then vec else addVectorF gvec dir -> [x y z] in
strcatn (ftoa (xscale *. x))::" "::(ftoa (yscale *. y))::" "::(ftoa (zscale *. z))::nil;
);;
*/
fun detectFingersFigure(kuserstr, lvec, rvec, mirror)=
if (kuserstr.KINU_tLeftHandPos == nil) || (kuserstr.KINU_tRightHandPos == nil) then nil else
let _GETKinectDeviceSize kuserstr.KINU_Device -> [kwidth kheight] in
let lvec -> [glx gly glz] in
let rvec -> [grx gry grz] in
let kuserstr.KINU_tLeftHandPos -> [lx ly lz] in
let kuserstr.KINU_tRightHandPos -> [rx ry rz] in
let sqrt (sqr (lx -. glx) +. sqr (ly -. gly) +. sqr (lz -. glz)) -> lspeed in
let sqrt (sqr (rx -. grx) +. sqr (ry -. gry) +. sqr (rz -. grz)) -> rspeed in
let 1 -> nbframe in
let _GETKinectUserFingersPixelPosition kuserstr.KINU_User if !mirror then USER_SKEL_R_HAND else USER_SKEL_L_HAND -> lfp in
let _GETKinectUserFingersPixelPosition kuserstr.KINU_User if !mirror then USER_SKEL_L_HAND else USER_SKEL_R_HAND -> rfp in
let _GETKinectUserJointPixelPosition kuserstr.KINU_User if !mirror then USER_SKEL_R_HAND else USER_SKEL_L_HAND 0.7 -> [lpx lpy lpz] in
let _GETKinectUserJointPixelPosition kuserstr.KINU_User if !mirror then USER_SKEL_L_HAND else USER_SKEL_R_HAND 0.7 -> [rpx rpy rpz] in
let V3DgetSessionView c3dXsession -> viewstr in
let V3DgetDefaultViewport viewstr -> viewportstr in
let V3DgetViewportSize viewstr viewportstr -> [_ _ w h] in
(
let kuserstr.KINU_tLeftHandFingers -> [nb mb interv] in
if ((interv >= nbframe) && (nb != (mb / interv))) then
(
SendPluginEvent kuserstr.KINU_Inst "Left nb fingers" itoa (mb / interv) nil;
set kuserstr.KINU_tLeftHandFingers = [(mb / interv) 0 0];
if ((mb / interv) >= 2) || (!_GETKinectUserHandVisible kuserstr.KINU_User if !mirror then USER_SKEL_R_HAND else USER_SKEL_L_HAND) then
(
set kuserstr.KINU_tLeftHandClickPos = nil;
set kuserstr.KINU_tLastLeftHandTrans = [0.0 0.0 0.0];
if (kuserstr.KINU_iLeftHandFigure != 6) then nil else
(
//addLogMessage "Left finger unclick";
SendPluginEvent kuserstr.KINU_Inst "Left finger unclick" nil nil;
);
set kuserstr.KINU_iLeftHandFigure = 5;
)
else if ((mb / interv) <= 0) && ((absf lspeed) <=. 0.015) && (_GETKinectUserHandVisible kuserstr.KINU_User if !mirror then USER_SKEL_R_HAND else USER_SKEL_L_HAND) then
(
if (kuserstr.KINU_iLeftHandFigure == 5) then
(
set kuserstr.KINU_iLeftHandFigure = 6;
set kuserstr.KINU_tLeftHandClickPos = [glx gly glz];
let ftoi ((itof lpx) *. (itof w) /. (itof kwidth)) -> px in
let ftoi ((itof lpy) *. (itof h) /. (itof kheight)) -> py in
(
//addLogMessage "Left finger click";
SendPluginEvent kuserstr.KINU_Inst "Left finger click" strcatn (itoa px)::" "::(itoa py)::nil nil;
);
0;
)
else nil;
)
/*else if (kuserstr.KINU_iLeftHandFigure != 6) then
(
set kuserstr.KINU_iLeftHandFigure = 0;
)*/
else nil;
/*
if lfp == nil then nil else
addLogMessage strcat "Fingers on left : " itoa (sizelist lfp);
*/
0;
)
else
(
if (interv >= nbframe) then
mutate kuserstr.KINU_tLeftHandFingers <- [_ (if lfp == nil then 0 else (sizelist lfp)) 1]
else
mutate kuserstr.KINU_tLeftHandFingers <- [_ (mb + (if lfp == nil then 0 else (sizelist lfp))) /*(max mb (sizelist lfp))*/ (interv + 1)];
0;
);
let kuserstr.KINU_tRightHandFingers -> [nb mb interv] in
if ((interv >= nbframe) && (nb != (mb / interv))) then
(
SendPluginEvent kuserstr.KINU_Inst "Right nb fingers" itoa (mb / interv) nil;
set kuserstr.KINU_tRightHandFingers = [(mb / interv) 0 0];
if ((mb / interv) >= 2) || (!_GETKinectUserHandVisible kuserstr.KINU_User if !mirror then USER_SKEL_L_HAND else USER_SKEL_R_HAND) then
(
set kuserstr.KINU_tRightHandClickPos = nil;
set kuserstr.KINU_tLastRightHandTrans = [0.0 0.0 0.0];
if (kuserstr.KINU_iRightHandFigure != 6) then nil else
(
//addLogMessage "Right finger unclick";
SendPluginEvent kuserstr.KINU_Inst "Right finger unclick" nil nil;
);
set kuserstr.KINU_iRightHandFigure = 5;
)
else if ((mb / interv) <= 0) && ((absf rspeed) <=. 0.015) && (_GETKinectUserHandVisible kuserstr.KINU_User if !mirror then USER_SKEL_L_HAND else USER_SKEL_R_HAND) then
(
if (kuserstr.KINU_iRightHandFigure == 5) then
(
set kuserstr.KINU_iRightHandFigure = 6;
set kuserstr.KINU_tRightHandClickPos = [grx gry grz];
let ftoi ((itof rpx) *. (itof w) /. (itof kwidth)) -> px in
let ftoi ((itof rpy) *. (itof h) /. (itof kheight)) -> py in
(
//addLogMessage "Right finger click";
//addLogMessage strcat "R speed : " (ftoa (absf rspeed));
SendPluginEvent kuserstr.KINU_Inst "Right finger click" strcatn (itoa px)::" "::(itoa py)::nil nil;
);
0;
)
else nil;
)
/*else if (kuserstr.KINU_iRightHandFigure != 6) then
(
set kuserstr.KINU_iRightHandFigure = 0;
)*/
else nil;
/*
if rfp == nil then nil else
addLogMessage strcat "Fingers on right : " itoa (sizelist rfp);
*/
0;
)
else
(
if (interv >= nbframe) then
mutate kuserstr.KINU_tRightHandFingers <- [_ (if rfp == nil then 0 else (sizelist rfp)) 1]
else
mutate kuserstr.KINU_tRightHandFingers <- [_ (mb + (if rfp == nil then 0 else (sizelist rfp))) /*(max mb (sizelist rfp))*/ (interv + 1)];
0;
);
);
0;;
fun getShortestRot(ang)=
let ang -> [y p r] in
let if y >. 180.0 then y -. 360.0 else if y <. (-.180.0) then y +. 360.0 else y -> y in
let if p >. 180.0 then p -. 360.0 else if p <. (-.180.0) then p +. 360.0 else p -> p in
let if r >. 180.0 then r -. 360.0 else if r <. (-.180.0) then r +. 360.0 else r -> r in
[y p r];;
fun cbKinectData(inst, sessionstr, etime, kuserstr)=
updateSkeleton kuserstr;
let _GETKinectDeviceMirror kuserstr.KINU_Device -> mirror in
let _GETKinectUserJointPosition kuserstr.KINU_User USER_SKEL_HEAD fConfidence -> ghvec in
let _GETKinectUserJointOrientation kuserstr.KINU_User USER_SKEL_HEAD fConfidence -> hquat in
let _GETKinectUserJointPosition kuserstr.KINU_User USER_SKEL_TORSO fConfidence -> gwvec in
let _GETKinectUserJointOrientation kuserstr.KINU_User USER_SKEL_TORSO fConfidence -> thquat in
let _GETKinectUserJointPosition kuserstr.KINU_User if !mirror then USER_SKEL_R_HAND else USER_SKEL_L_HAND fConfidence -> glvec in
let _GETKinectUserJointPosition kuserstr.KINU_User if !mirror then USER_SKEL_L_HAND else USER_SKEL_R_HAND fConfidence -> grvec in
//convert to meter
let multiplyVectorF ghvec [0.01 0.01 0.01] -> hvec in
let multiplyVectorF gwvec [0.01 0.01 0.01] -> wvec in
let multiplyVectorF glvec [0.01 0.01 0.01] -> lvec in
let multiplyVectorF grvec [0.01 0.01 0.01] -> rvec in
let hvec -> [hx hy hz] in
let wvec -> [wx wy wz] in
let lvec -> [lx ly lz] in
let rvec -> [rx ry rz] in
let subVectorF lvec wvec -> tlvec in
let subVectorF rvec wvec -> trvec in
let kuserstr.KINU_tScale -> [xscale yscale zscale] in
let kuserstr.KINU_Mesh -> [mesh [_ oy _] _] in
let SO3GetRootBoneFromMesh mesh -> rootbone in
let [[0.0 0.0 0.0] [0.0 0.0 0.0]] -> hcontrol in
(
if (gwvec == nil) then nil else
(
if (kuserstr.KINU_InitPos != nil) then nil else
set kuserstr.KINU_InitPos = [(wx *. xscale) (wy *. yscale) (wz *. zscale)];
let kuserstr.KINU_InitPos -> [ix iy iz] in
let if iz == 0.0 then 0.0 else (iy /. iz) *. (wz *. zscale) -> cy in
let if (((wz *. zscale) +. cy) == 0.0) then wy else ((wy *. yscale) /. (wz *. zscale) +. cy) -> nby in
let switch kuserstr.KINU_lJointsList rootbone -> [joint [px py pz] boquat _ _] in
let SO3MathsQuatGetYaw thquat 0 -> yaw in
let SO3ObjectGetGlobalScale mesh -> [sx sy sz] in
(
SO3ObjectSetOrientation rootbone (SO3MathsQuatAdd thquat boquat);
SO3ObjectSetPosition mesh addVectorF [(wx *. xscale) 0.0 (wz *. zscale)] [0.0 oy 0.0];
SO3ObjectSetPosition rootbone [px (py +. (if (sy == 0.0) then 0.0 else (nby /. sy))) pz];
let SO3MathsQuatToEulerXYZ thquat -> [ax ay az] in
let strcatn (ftoa SO3MathsRadianToDegree ax)::" "::(ftoa SO3MathsRadianToDegree (if kuserstr.KINU_bFlipX then -.ay else ay))::" "::(ftoa SO3MathsRadianToDegree az)::nil -> la in
let getVecParam kuserstr wvec USER_SKEL_TORSO -> lp in
SendPluginEvent kuserstr.KINU_Inst "Torso" (strcatn lp::"\n"::la::nil) nil;
);
);
if (ghvec == nil) || (kuserstr.KINU_InitPos == nil) then nil else
let getAngParam kuserstr hquat USER_SKEL_HEAD -> la in
let getVecParam kuserstr hvec USER_SKEL_HEAD -> lp in
(
SendPluginEvent kuserstr.KINU_Inst "Head" (strcatn lp::"\n"::la::nil) nil;
if (kuserstr.KINU_sLastHeadTracking == nil) then nil else
(
let kuserstr.KINU_sLastHeadTracking -> [clvec clang] in
let subVectorF hvec clvec -> [px py pz] in
let SO3MathsQuatGetDirection thquat [px 0.0 pz] -> [ndx ndy ndz] in
let [ndx py ndz] -> [px py pz] in
let SO3MathsQuatToEulerDegreeYZX hquat -> nang in
let getShortestRot (subVectorF nang clang) -> [roll yaw pitch] in
//let [0.0 0.0 0.0] -> [roll yaw pitch] in
// last "\n 1" define an accumulator control, note simple 0 to 2 for override orientation
let strcatn (strcatnSep (ftoa px)::(ftoa py)::(ftoa pz)::nil " ")::"\n"::(strcatnSep (ftoa -.pitch)::(ftoa yaw)::(ftoa -.roll)::nil " ")::"\n"::"1"::nil -> spos in
SendPluginEvent kuserstr.KINU_Inst "Head tracker control" spos kuserstr.KINU_Inst.INST_sName;
);
let SO3MathsQuatToEulerDegreeYZX hquat -> ang in
set kuserstr.KINU_sLastHeadTracking = [hvec ang];
);
if (glvec == nil) then nil else
let _GETKinectUserJointPosition kuserstr.KINU_User USER_SKEL_L_ELBOW fConfidence -> [_ _ lez] in
(
let _GETKinectUserJointOrientation kuserstr.KINU_User (if !mirror then USER_SKEL_R_ELBOW else USER_SKEL_L_ELBOW) fConfidence -> quat in
let SO3MathsQuatToEulerXYZ quat -> [ax ay az] in
let getVecParam kuserstr lvec (if !mirror then USER_SKEL_R_HAND else USER_SKEL_L_HAND) -> lp in
let strcatn (ftoa SO3MathsRadianToDegree ax)::" "::(ftoa SO3MathsRadianToDegree (if kuserstr.KINU_bFlipX then -.ay else ay))::" "::(ftoa SO3MathsRadianToDegree az)::nil -> la in
(
if (kuserstr.KINU_tLeftHandClickPos == nil) then nil else
(
let subVectorF kuserstr.KINU_tLeftHandClickPos tlvec -> lhlv in
let subVectorF lhlv kuserstr.KINU_tLastLeftHandTrans -> [nx ny nz] in
let 180.0 *. -.nx -> fdx in
let 180.0 *. -.ny -> fdy in
let 180.0 *. nz -> fdz in
(
set kuserstr.KINU_tLastLeftHandTrans = lhlv;
mutate hcontrol <- [[fdx fdy fdz] _];
);
);
SendPluginEvent kuserstr.KINU_Inst "Left hand" (strcatn lp::"\n"::la::nil) nil;
);
);
if (grvec == nil) then nil else
let _GETKinectUserJointPosition kuserstr.KINU_User USER_SKEL_R_ELBOW fConfidence -> [_ _ rez] in
(
let _GETKinectUserJointOrientation kuserstr.KINU_User (if !mirror then USER_SKEL_L_ELBOW else USER_SKEL_R_ELBOW) fConfidence -> quat in
let SO3MathsQuatToEulerXYZ quat -> [ax ay az] in
let getVecParam kuserstr rvec (if !mirror then USER_SKEL_L_HAND else USER_SKEL_R_HAND) -> lp in
let strcatn (ftoa SO3MathsRadianToDegree ax)::" "::(ftoa SO3MathsRadianToDegree (if kuserstr.KINU_bFlipX then -.ay else ay))::" "::(ftoa SO3MathsRadianToDegree az)::nil -> la in
(
if (kuserstr.KINU_tRightHandClickPos == nil) then nil else
(
let subVectorF kuserstr.KINU_tRightHandClickPos trvec -> lhlv in
let subVectorF lhlv kuserstr.KINU_tLastRightHandTrans -> [nx ny nz] in
let 180.0 *. nx -> fdx in
let 180.0 *. ny -> fdy in
let 180.0 *. nz -> fdz in
(
set kuserstr.KINU_tLastRightHandTrans = lhlv;
mutate hcontrol <- [_ [fdx fdy fdz]];
);
);
SendPluginEvent kuserstr.KINU_Inst "Right hand" (strcatn lp::"\n"::la::nil) nil;
);
);
if ((glvec == nil) || (grvec == nil)) then nil else
(
let (absf(rx -. lx)) -> dx in
let (absf(ry -. ly)) -> dy in
let (absf(rz -. lz)) -> dz in
let strcatn (ftoa dx)::" "::(ftoa dy)::" "::(ftoa dz)::nil -> lv in
let 90.0 /. 0.40 -> coef in
let 0.0 -> ax in
let ((rz -. lz) *. coef) -> ay in
let ((ry -. ly) *. coef) -> az in
let strcatn (ftoa ax)::" "::(ftoa ay)::" "::(ftoa (-.az))::nil -> la in
(
SendPluginEvent kuserstr.KINU_Inst "Hands distance" lv nil;
SendPluginEvent kuserstr.KINU_Inst "Hands rotation" la nil;
);
);
detectFingersFigure kuserstr tlvec trvec mirror;
let hcontrol -> [[vx vy vz] [ax ay az]] in
SendPluginEvent inst "Hands control" (strbuild ((ftoa (if !mirror then -.vx else vx))::(ftoa vy)::(ftoa vz)::nil)::((ftoa -.ay)::(ftoa (if !mirror then -.ax else ax))::(ftoa az)::nil)::nil) inst.INST_sName;
set kuserstr.KINU_tLeftHandPos = tlvec;
set kuserstr.KINU_tRightHandPos = trvec;
);
// pose detection
if (bPoseTrain) then nil else
let _GETKinectUserJointOrientation kuserstr.KINU_User USER_SKEL_TORSO 0.1 -> tquat in
let USER_SKEL_L_SHOULDER::USER_SKEL_R_SHOULDER::USER_SKEL_L_ELBOW::USER_SKEL_R_ELBOW::nil -> lj in
let nil -> lout in
(
let sizelist lj -> size in
let 0 -> i in
while (lj != nil) do
(
let (_GETKinectUserJointOrientation kuserstr.KINU_User (hd lj) 0.1) -> quat in
let if (quat == nil) then [0.0 0.0 0.0] else SO3MathsQuatToEulerXYZ SO3MathsQuatSubstract quat tquat -> [x y z] in
set lout = [(SO3MathsRadianToDegree x) (SO3MathsRadianToDegree y) (SO3MathsRadianToDegree z)]::lout;
set lj = tl lj;
);
//if ((sizelist lout) != 4) then nil else
_MlAddDetectionData kuserstr.KINU_mlp revertlist lout;
);
0;;
/*! \brief Callback on "Calibration Started" dms action
*
* Get event when Kinect Calibration has started
*
* Prototype: fun [PInstance DMI S S I [F F F I]] I
*
* \param OBJKinect : KInect Instance
* \param PInstance : plugIT instance
*
* \return I : 0
**/
fun cbCalibrationStart(kuser, kuserstr)=
SendPluginEvent kuserstr.KINU_Inst "Calibration started" nil nil;
0;;
/*! \brief Callback on "Calibration Ended" dms action
*
* Get event when Kinect Calibration has ended
*
* Prototype: fun [PInstance DMI S S I [F F F I]] I
*
* \param OBJKinect : KInect Instance
* \param PInstance : plugIT instance
*
* \return I : 0
**/
fun cbCalibrationEnd(kuser, kuserstr)=
SendPluginEvent kuserstr.KINU_Inst "Calibration ended" nil nil;
0;;
/*! \brief Callback on "Pose Detected" dms action
*
* Get event when Kinect Pose detection has found
*
* Prototype: fun [PInstance DMI S S I [F F F I]] I
*
* \param OBJKinect : KInect Instance
* \param PInstance : plugIT instance
*
* \return I : 0
**/
fun cbCalibrationPoseDetected(kuser, kuserstr)=
SendPluginEvent kuserstr.KINU_Inst "Pose detected" nil nil;
0;;
/*! \brief Callback on "disconnected" dms action
*
* Get event when Kinect pose detection has lost
*
* Prototype: fun [PInstance DMI S S I [F F F I]] I
*
* \param OBJKinect : KInect Instance
* \param PInstance : plugIT instance
*
* \return I : 0
**/
fun cbCalibrationPoseLost(kuser, kuserstr)=
SendPluginEvent kuserstr.KINU_Inst "Pose lost" nil nil;
0;;
fun cbHandFound(kuser, kuserstr, hand)=
let _GETKinectDeviceMirror kuserstr.KINU_Device -> mirror in
if ((hand == USER_SKEL_R_HAND && !mirror) || (hand == USER_SKEL_L_HAND && mirror)) then
SendPluginEvent kuserstr.KINU_Inst "Left hand found" nil nil
else if ((hand == USER_SKEL_L_HAND && !mirror) || (hand == USER_SKEL_R_HAND && mirror)) then
SendPluginEvent kuserstr.KINU_Inst "Right hand found" nil nil
else nil;
0;;
fun cbHandLost(kuser, kuserstr, hand)=
let _GETKinectDeviceMirror kuserstr.KINU_Device -> mirror in
if ((hand == USER_SKEL_R_HAND && !mirror) || (hand == USER_SKEL_L_HAND && mirror)) then
(
if (kuserstr.KINU_iLeftHandFigure != 6) then nil else
(
SendPluginEvent kuserstr.KINU_Inst "Left finger unclick" nil nil;
set kuserstr.KINU_iLeftHandFigure = 5;
);
set kuserstr.KINU_tLeftHandClickPos = nil;
set kuserstr.KINU_tLastLeftHandTrans = [0.0 0.0 0.0];
SendPluginEvent kuserstr.KINU_Inst "Left hand lost" nil nil;
)
else if ((hand == USER_SKEL_L_HAND && !mirror) || (hand == USER_SKEL_R_HAND && mirror)) then
(
if (kuserstr.KINU_iRightHandFigure != 6) then nil else
(
SendPluginEvent kuserstr.KINU_Inst "Right finger unclick" nil nil;
set kuserstr.KINU_iRightHandFigure = 5;
);
set kuserstr.KINU_tRightHandClickPos = nil;
set kuserstr.KINU_tLastRightHandTrans = [0.0 0.0 0.0];
SendPluginEvent kuserstr.KINU_Inst "Right hand lost" nil nil;
)
else nil;
0;;
fun cbHandMove(kuser, kuserstr, hand, trans)=
let trans -> [x y z] in
let _GETKinectUserJointPixelPosition kuserstr.KINU_User hand 0.7 -> [px py pz] in
//let _GETKinectUserJointPixelPosition kuserstr.KINU_User USER_SKEL_TORSO 0.9 -> [tx ty tz] in
let V3DgetSessionView c3dXsession -> viewstr in
let V3DgetDefaultViewport viewstr -> viewportstr in
let V3DgetViewportSize viewstr viewportstr -> [_ _ w h] in
let _GETKinectDeviceMirror kuserstr.KINU_Device -> mirror in
let _GETKinectDeviceSize kuserstr.KINU_Device -> [kwidth kheight] in
let kuserstr.KINU_tPmargin -> [xm ym] in
let ftoi ((itof (px - (xm / 2))) *. (itof w) /. (itof (kwidth - xm))) -> px in
let ftoi ((itof (py - (ym / 2))) *. (itof h) /. (itof (kheight - ym))) -> py in
(
//addLogMessage strcatn "Hand move : "::(itoa x)::" "::(itoa y)::" "::(itoa z)::nil;
if ((hand == USER_SKEL_R_HAND && !mirror) || (hand == USER_SKEL_L_HAND && mirror)) then
SendPluginEvent kuserstr.KINU_Inst "Left hand move" strcatn (itoa px)::" "::(itoa py)::" "::(itoa pz)::nil nil
else if ((hand == USER_SKEL_L_HAND && !mirror) || (hand == USER_SKEL_R_HAND && mirror)) then
SendPluginEvent kuserstr.KINU_Inst "Right hand move" strcatn (itoa px)::" "::(itoa py)::" "::(itoa pz)::nil nil
else nil;
);
0;;
fun foundBoneType(name)=
let -1 -> type in
(
let sizelist lBonesBindNames -> size in
let 0 -> i in
while (i < size) && (type == -1) do
(
let nth_list lBonesBindNames i -> [ftype lnames] in
if (strfindiList lnames name) == nil then nil else
set type = ftype;
set i = i + 1;
);
type;
);;
fun linkBones(bone, kuserstr)=
let SO3ObjectGetName bone -> bonename in
let SO3ObjectGetChildren bone -> lchild in
(
let foundBoneType bonename -> type in
if (type == -1) then nil else
let SO3ObjectGetGlobalOrientation bone -> gquat in
let SO3ObjectGetOrientation bone -> lquat in
let SO3ObjectGetPosition bone -> vec in
let kuserstr.KINU_Mesh -> [mesh _ _] in
(
if (SKL_USE_GLOBAL_COORDS) then
set kuserstr.KINU_lJointsList = [bone [type vec gquat lquat nil]]::kuserstr.KINU_lJointsList
else
(
//for local use
SO3ObjectSetInheritOrientation bone 0;
SO3ObjectResetOrientation bone;
SO3ObjectSetOrientation bone SO3MathsQuatAdd (SO3ObjectGetGlobalOrientation mesh) gquat;
let SO3ObjectGetOrientation bone -> sklquat in
(
SO3ObjectSetInheritOrientation bone 1;
SO3ObjectSetOrientation bone lquat;
set kuserstr.KINU_lJointsList = [bone [type vec sklquat lquat nil]]::kuserstr.KINU_lJointsList;
);
);
);
while lchild != nil do
(
linkBones (hd lchild) kuserstr;
set lchild = tl lchild;
);
);
0;;
fun cbUserFound(kuser, kuserstr)=
SendPluginEvent kuserstr.KINU_Inst "User found" nil nil;
// force an update to be sure the model is correct in case of a reset or stop animation on user found
let V3DgetSessionView c3dXsession -> viewstr in
SO3BufferUpdate viewstr.V3D_buffer;
let kuserstr.KINU_Mesh -> [mesh _ _] in
let SO3GetRootBoneFromMesh mesh -> rootbone in
if (rootbone == nil) then nil else
(
SO3ObjectResetOrientation mesh;
SO3ObjectRotateYaw mesh (if (!_GETKinectDeviceMirror kuserstr.KINU_Device) then 0.0 else (SO3MathsDegreeToRadian 180.0)) SO3_LOCAL_TS;
let SO3ObjectGetOrientation rootbone -> lquat in
let SO3ObjectGetPosition rootbone -> vec in
set kuserstr.KINU_lJointsList = [rootbone [USER_SKEL_WAIST vec lquat lquat nil]]::kuserstr.KINU_lJointsList;
linkBones rootbone kuserstr;
set kuserstr.KINU_lJointsList = revertlist kuserstr.KINU_lJointsList;
);
0;;
fun cbUserLost(kuser, kuserstr)=
resetSkeleton kuserstr;
set kuserstr.KINU_sLastHeadTracking = nil;
SendPluginEvent kuserstr.KINU_Inst "User lost" nil nil;
0;;
fun cbPoseDetect(ml, kuserstr, catname)=
if (!strcmp catname kuserstr.KINU_sLastdetectedPose) then nil else
(
SendPluginEvent kuserstr.KINU_Inst catname nil nil;
SendPluginEvent kuserstr.KINU_Inst "Pose detected" catname nil;
set kuserstr.KINU_sLastdetectedPose = catname;
);
0;;
fun cbAddTrainData(inst, from, action, param, reply, kuserstr)=
let nth_list lPoseLabel kuserstr.KINU_iTrainingPos -> label in
(
addLogMessage strcat "KinectUser Train : " label;
let _GETKinectUserJointOrientation kuserstr.KINU_User USER_SKEL_TORSO 0.1 -> tquat in
let USER_SKEL_L_SHOULDER::USER_SKEL_R_SHOULDER::USER_SKEL_L_ELBOW::USER_SKEL_R_ELBOW::nil -> lj in
let nil -> lout in
(
let sizelist lj -> size in
let 0 -> i in
while (lj != nil) do
(
let (_GETKinectUserJointOrientation kuserstr.KINU_User (hd lj) 0.1) -> quat in
if (quat == nil) then nil else
let SO3MathsQuatToEulerXYZ SO3MathsQuatSubstract quat tquat -> [x y z] in
set lout = [(SO3MathsRadianToDegree x) (SO3MathsRadianToDegree y) (SO3MathsRadianToDegree z)]::lout;
set lj = tl lj;
);
if ((sizelist lout) != 4) then nil else
(
_MlAddTrainingData kuserstr.KINU_mlp revertlist lout label;
_MlSaveData kuserstr.KINU_mlp _getmodifypack strcat (getPluginDirectory (getInstancePlugin kuserstr.KINU_Inst)) "/res/kinposes.xlm";
addLogMessage strcatn "KinectUser save "::label::" to "::(strcat (getPluginDirectory (getInstancePlugin kuserstr.KINU_Inst)) "/res/kinposes.xlm")::nil;
set kuserstr.KINU_iTrainingPos = kuserstr.KINU_iTrainingPos + 1;
);
);
);
0;;
// Create Kinect Callback
fun Create(inst, from, action, param, reply, kuserstr)=
if (kuserstr.KINU_User != nil) then nil else
let if (atoi param) == nil then 0 else atoi param -> id in
let _GETKinectDeviceById id -> mKinect in
let _CRKinectUser _channel mKinect -> kuser in
(
set kuserstr.KINU_Device = mKinect;
set kuserstr.KINU_User = kuser;
_CBKinectUserFound kuser @cbUserFound kuserstr;
_CBKinectUserLost kuser @cbUserLost kuserstr;
_CBKinectUserCalibrationStart kuser @cbCalibrationStart kuserstr;
_CBKinectUserCalibrationEnd kuser @cbCalibrationEnd kuserstr;
_CBKinectUserPoseDetected kuser @cbCalibrationPoseDetected kuserstr;
_CBKinectUserPoseLost kuser @cbCalibrationPoseLost kuserstr;
_CBKinectUserHandFound kuser @cbHandFound kuserstr;
_CBKinectUserHandLost kuser @cbHandLost kuserstr;
_CBKinectUserHandMove kuser @cbHandMove kuserstr;
setPluginInstanceCbScenePreRender kuserstr.KINU_Inst mkfun4 @cbKinectData kuserstr;
);
0;;
fun deleteOb(inst, kuserstr) =
setPluginInstanceCbScenePreRender kuserstr.KINU_Inst nil;
resetSkeleton kuserstr;
_DSKinectUser kuserstr.KINU_User;
set kuserstr.KINU_User = nil;
_DSml kuserstr.KINU_mlp;
0;;
// Destroy Kinect Callback
fun Destroy(inst, from, action, param, reply, kuserstr)=
setPluginInstanceCbScenePreRender kuserstr.KINU_Inst nil;
resetSkeleton kuserstr;
_DSKinectUser kuserstr.KINU_User;
set kuserstr.KINU_User = nil;
set kuserstr.KINU_sLastdetectedPose = nil;
0;;
fun cbNewOb(inst)=
let (getPluginInstanceParam inst "object") -> objname in
let atof (getPluginInstanceParam inst "scaleX") -> ax in
let atof (getPluginInstanceParam inst "scaleY") -> ay in
let atof (getPluginInstanceParam inst "scaleZ") -> az in
let if ax == nil then 1.0 else ax -> ax in
let if ay == nil then 1.0 else ay -> ay in
let if az == nil then 1.0 else az -> az in
let atoi (getPluginInstanceParam inst "flipX") -> flipx in
let if flipx == nil then 0 else flipx -> flipx in
let atoi (getPluginInstanceParam inst "handXmargin") -> handxmargin in
let if handxmargin == nil then 0 else handxmargin -> handxmargin in
let atoi (getPluginInstanceParam inst "handYmargin") -> handymargin in
let if handymargin == nil then 0 else handymargin -> handymargin in
let SO3SceneGetObject (V3DgetSession c3dXsession) objname -> obj in
let SO3ObjectGetOrientation obj -> quat in
let SO3ObjectGetPosition obj -> vec in
let _CRml _channel 0 1 0.61 -> mlp in
let mkPlugKinectUserStr [inst nil nil [obj vec quat] [ax ay az] flipx [handxmargin handymargin] nil nil 0 0 [0 0 0] [0 0 0] nil nil nil nil [0.0 0.0 0.0] [0.0 0.0 0.0] mlp nil nil 0] -> kuserstr in
(
if (bPoseTrain) then nil else
(
_MlLoadData mlp (_checkpack strcat (getPluginDirectory (getInstancePlugin inst)) "/res/kinposes.xlm");
_CBMlDetect mlp @cbPoseDetect kuserstr;
);
PluginRegisterAction inst "Create" mkfun6 @Create kuserstr;
PluginRegisterAction inst "Destroy" mkfun6 @Destroy kuserstr;
if (!bPoseTrain) then nil else
PluginRegisterAction inst "Train pose" mkfun6 @cbAddTrainData kuserstr;
setPluginInstanceCbDel inst mkfun2 @deleteOb kuserstr;
);
0;;
fun IniPlug(file)=
set lBonesBindNames =
[USER_SKEL_HEAD "head"::"tête"::"tete"::nil]::
[USER_SKEL_NECK "neck"::"cou"::nil]::
[USER_SKEL_TORSO "chest"::"stomach"::"spine2"::"spine3"::"colonne1"::"colonne2"::nil]::
[USER_SKEL_WAIST "waist"::"pelvis"::"bassin"::"hips"::nil]::
[USER_SKEL_L_COLLAR nil]::
[USER_SKEL_R_COLLAR nil]::
[USER_SKEL_L_SHOULDER "humerus.l"::"l upperarm"::"l_upperarm"::"g membre supérieur du bras"::"leftarm"::nil]::
[USER_SKEL_R_SHOULDER "humerus.r"::"r upperarm"::"r_upperarm"::"d membre supérieur du bras"::"rightarm"::nil]::
[USER_SKEL_L_HAND "hand.l"::"l hand"::"l_hand"::"g main"::"lefthand"::nil]::
[USER_SKEL_R_HAND "hand.r"::"r hand"::"r_hand"::"d main"::"righthand"::nil]::
[USER_SKEL_L_FINGERTIP nil]::
[USER_SKEL_R_FINGERTIP nil]::
[USER_SKEL_L_WRIST nil]::
[USER_SKEL_R_WRIST nil]::
[USER_SKEL_L_ELBOW "ulna.l"::"l forearm"::"l_forearm"::"g avant bras"::"leftforearm"::nil]::
[USER_SKEL_R_ELBOW "ulna.r"::"r forearm"::"r_forearm"::"d avant bras"::"rightforearm"::nil]::
[USER_SKEL_L_HIP "thigh.l"::"l thigh"::"l_thigh"::"g cuisse"::"leftupleg"::nil]::
[USER_SKEL_R_HIP "thigh.r"::"r thigh"::"r_thigh"::"d cuisse"::"rightupleg"::nil]::
[USER_SKEL_L_KNEE "calf.l"::"l calf"::"l_calf"::"g mollet"::"leftleg"::nil]::
[USER_SKEL_R_KNEE "calf.r"::"r calf"::"r_calf"::"d mollet"::"rightleg"::nil]::
//[USER_SKEL_L_FOOT "foot.l"::"l foot"::"g pied"::"leftfoot"::nil]::
//[USER_SKEL_R_FOOT "foot.r"::"r foot"::"d pied"::"rightfoot"::nil]::
[USER_SKEL_L_ANKLE nil]::
[USER_SKEL_R_ANKLE nil]::
nil;
PlugRegister @cbNewOb nil;
setPluginEditor @dynamicedit;
0;;