/* ----------------------------------------------------------------------------- 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 ----------------------------------------------------------------------------- */ /* Version : 1.0 First version : 16/05/2013 Author : Bourineau Bastien */ struct ObCursor = [ POBC_id : I, POBC_pos : [I I], POBC_vel : [I I], POBC_initPos : [I I], POBC_lifeTime : I, POBC_tips : SO3_WIDGET, POBC_lastAng : F, POBC_lastDist : I, POBC_velAcc : [I I], POBC_bHold : I ]mkObCursor;; struct PlugMultiTouch = [ PMTP_inst : PInstance, PMTP_lCursor : [[I ObCursor] r1], PMTP_lObject : [[I ObObject] r1], PMTP_bmpTip : AlphaBitmap, PMTP_bTips : I ]mkPlugMultiTouch;; fun cbAddCursor(inst, viewstr, id, x, y, obstr)= let (V3DgetDefaultViewport viewstr) -> viewportstr in let mkObCursor [id [x y] [0 0] [x y] _tickcount nil nil nil [0 0] 0] -> curobj in ( if (!obstr.PMTP_bTips) then nil else ( set curobj.POBC_tips = SO3BitmapWidgetCreate (V3DgetSession c3dXsession) viewportstr.V3D_viewport (strcatn (getPluginInstanceName obstr.PMTP_inst)::"_tip"::(itoa id)::nil) x-32 y-32 64 64 100000; SO3WidgetSetTransparency curobj.POBC_tips 1; SO3WidgetSetKeyboardEnable curobj.POBC_tips 0; SO3WidgetSetMouseEnable curobj.POBC_tips 0; SO3WidgetSetForeground curobj.POBC_tips 1; SO3BitmapWidgetBlitAlpha curobj.POBC_tips obstr.PMTP_bmpTip; ); set obstr.PMTP_lCursor = [id curobj]::obstr.PMTP_lCursor; SendPluginEvent obstr.PMTP_inst "Nb cursor" itoa (sizelist obstr.PMTP_lCursor) nil; ); 0;; fun cbUpdateCursor(inst, viewstr, id, x, y, vx, vy, obstr)= let switch obstr.PMTP_lCursor id -> curobj in let nth_list obstr.PMTP_lCursor (sizelist obstr.PMTP_lCursor) - 1 -> [_ lastobj] in let nth_list obstr.PMTP_lCursor (sizelist obstr.PMTP_lCursor) - 2 -> [_ secobj] in ( set curobj.POBC_pos = [x y]; set curobj.POBC_vel = [vx vy]; let curobj.POBC_velAcc -> [accx accy] in set curobj.POBC_velAcc = [accx + vx accy + vy]; if (!obstr.PMTP_bTips) then nil else SO3WidgetSetPosition curobj.POBC_tips x-32 y-32; let curobj.POBC_velAcc -> [nvx nvy] in if (((_tickcount - curobj.POBC_lifeTime) < 800) || curobj.POBC_bHold || (((abs nvx) >= 10) || ((abs nvy) >= 10))) then nil else ( set curobj.POBC_bHold = 1; SendPluginEvent obstr.PMTP_inst "Hold" strcatn (itoa x)::" "::(itoa y)::nil nil; ); if ((lastobj != curobj) && (secobj != curobj) || (secobj == nil)) then nil else ( let lastobj.POBC_pos -> [xa ya] in let secobj.POBC_pos -> [xb yb] in let [xb - xa yb - ya] -> [ax ay] in let SO3MathsRadianToDegree (-. atan2 (itof ax) (itof ay)) -> ang in let if ang == nil then 0.0 else ang -> ang in let ftoi (sqrt itof ((ax * ax) + (ay * ay))) -> dist in ( SendPluginEvent obstr.PMTP_inst "Angle" (ftoa ang) nil; SendPluginEvent obstr.PMTP_inst "Distance" (itoa dist) nil; if (secobj.POBC_lastAng == nil || secobj.POBC_lastDist == nil) then nil else let ang -. secobj.POBC_lastAng -> vang in let dist - secobj.POBC_lastDist -> vdist in ( SendPluginEvent obstr.PMTP_inst "Angle velocity" (ftoa vang) nil; SendPluginEvent obstr.PMTP_inst "Distance velocity" (itoa vdist) nil; ); set secobj.POBC_lastAng = ang; set secobj.POBC_lastDist = dist; ); ); ); 0;; fun cbRemoveCursor(inst, viewstr, id, obstr)= let switch obstr.PMTP_lCursor id -> curobj in let hd obstr.PMTP_lCursor -> [_ lastobj] in ( if (!obstr.PMTP_bTips) then nil else SO3WidgetDestroy curobj.POBC_tips; set obstr.PMTP_lCursor = remove_idx_from_list obstr.PMTP_lCursor id; SendPluginEvent obstr.PMTP_inst "Nb cursor" itoa (sizelist obstr.PMTP_lCursor) nil; // manage mouse with first point if (lastobj != curobj) then nil else ( if ((_tickcount - lastobj.POBC_lifeTime) > 200) then nil else // tap ( SendPluginEvent obstr.PMTP_inst "Tap" nil nil; ); if ((sizelist obstr.PMTP_lCursor) != 0) then nil else let curobj.POBC_velAcc -> [vx vy] in let (V3DgetDefaultViewport (V3DgetSessionView c3dXsession)) -> viewportstr in let SO3ViewportGetPixelPositionSize viewportstr.V3D_viewport -> [_ _ vw vh] in if (vw <= 0 || vh <= 0) then nil else ( let ((itof vx) /. (itof vw)) /. fVUIPIXELDENSITY -> xcoef in let ((itof vy) /. (itof vh)) /. fVUIPIXELDENSITY -> ycoef in if (xcoef <=. (-.0.25)) && ((absf ycoef) <=. 0.20) then SendPluginEvent obstr.PMTP_inst "Swipe left" nil nil else if (xcoef >=. 0.25) && ((absf ycoef) <=. 0.20) then SendPluginEvent obstr.PMTP_inst "Swipe right" nil nil else if (ycoef <=. (-.0.25)) && ((absf xcoef) <=. 0.20) then SendPluginEvent obstr.PMTP_inst "Swipe up" nil nil else if (ycoef >=. 0.25) && ((absf xcoef) <=. 0.20) then SendPluginEvent obstr.PMTP_inst "Swipe down" nil nil else nil; ); ); ); 0;; /*! \brief Callback on instance destruction * * Prototype: fun [PInstance SerialIO] I * * \param PInstance : destroyed plugIT instance * \param PlugMultiTouch : Tuio struct * * \return I : 0 **/ fun deleteOb(inst, obstr)= setPluginInstanceCbTouchPointAdd inst nil; setPluginInstanceCbTouchPointRemove inst nil; setPluginInstanceCbTouchPointUpdate inst nil; //remove all tips while (obstr.PMTP_lCursor != nil) do ( let hd obstr.PMTP_lCursor -> [_ curobj] in SO3WidgetDestroy curobj.POBC_tips; set obstr.PMTP_lCursor = tl obstr.PMTP_lCursor; ); _DSalphaBitmap obstr.PMTP_bmpTip; 0;; /*! \brief Callback on new plugIT instance * * Read the parameters from editor values and connect the serial port * * Prototype: fun [PInstance] I * * \param PInstance : plugIT instance * * \return I : 0 **/ fun newOb(inst)= let atoi (getPluginInstanceParam inst "tips") -> tips in let if tips == nil then 1 else tips -> tips in let mkPlugMultiTouch [inst nil nil nil tips] -> obstr in ( if (!obstr.PMTP_bTips) then nil else set obstr.PMTP_bmpTip = G2DloadAlphaBmp _channel strcatn (getPluginDirectory (getInstancePlugin inst))::"/res/tips.png"::nil; setPluginInstanceCbTouchPointAdd inst mkfun6 @cbAddCursor obstr; setPluginInstanceCbTouchPointRemove inst mkfun4 @cbRemoveCursor obstr; setPluginInstanceCbTouchPointUpdate inst mkfun8 @cbUpdateCursor obstr; setPluginInstanceCbDel inst mkfun2 @deleteOb obstr; ); 0;; /*! \brief Global plugIT function to initialize the plugIT callbacks * * Prototype: fun [S] I * * \param S : plugIT file path * * \return I : 0 **/ fun IniPlug(file)= PlugRegister @newOb nil; setPluginEditor @dynamicedit; 0;;