/*
-----------------------------------------------------------------------------
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) -> xcoef in
let (itof vy) /. (itof vh) -> 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;;