/*
-----------------------------------------------------------------------------
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 : [F F],
POBC_initPos : [I I],
POBC_lifeTime : I,
POBC_tips : SO3_WIDGET,
POBC_lastAng : F,
POBC_lastDist : I,
POBC_velAcc : [F F],
POBC_bClick : I
]mkObCursor;;
struct ObObject = [
POBO_id : I,
POBO_pos : [I I],
POBO_vel : [F F],
POBO_ang : F,
POBO_angVel : F
]mkObObject;;
struct PlugTUIO = [
PTUIO_inst : PInstance,
PTUIO_obj : ObjTUIO,
PTUIO_lCursor : [[I ObCursor] r1],
PTUIO_lObject : [[I ObObject] r1],
PTUIO_bmpTip : AlphaBitmap,
PTUIO_bMouse : I,
PTUIO_bTips : I
]mkPlugTUIO;;
fun cbAddCursor(tuioObj, obstr, id, fx, fy, vx, vy)=
let (V3DgetSessionView c3dXsession) -> viewstr in
let (V3DgetDefaultViewport viewstr) -> viewportstr in
let _GETscreenSize -> [sw sh] in
let [(itof sw) (itof sh)] -> [fw fh] in
let ftoi (fw *. fx) -> x in
let ftoi (fh *. fy) -> y in
let nth_list obstr.PTUIO_lCursor (sizelist obstr.PTUIO_lCursor) - 1 -> [_ lastobj] in
let mkObCursor [id [x y] [vx vy] [x y] _tickcount nil nil nil [vx vy] 0] -> curobj in
(
if (!obstr.PTUIO_bTips) then nil else
(
set curobj.POBC_tips = SO3BitmapWidgetCreate (V3DgetSession c3dXsession) viewportstr.V3D_viewport (strcatn (getPluginInstanceName obstr.PTUIO_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.PTUIO_bmpTip;
);
set obstr.PTUIO_lCursor = [id curobj]::obstr.PTUIO_lCursor;
SendPluginEvent obstr.PTUIO_inst "Nb cursor" itoa (sizelist obstr.PTUIO_lCursor) nil;
if (!obstr.PTUIO_bMouse || (sizelist obstr.PTUIO_lCursor) > 1) then nil else
(
_RMTCTRL_MouseMove x y RMTCTRL_ABSOLUTEMOVE;
);
);
0;;
fun cbUpdateCursor(tuioObj, obstr, id, fx, fy, vx, vy)=
let _GETscreenSize -> [sw sh] in
let [(itof sw) (itof sh)] -> [fw fh] in
let ftoi (fw *. fx) -> x in
let ftoi (fh *. fy) -> y in
let switch obstr.PTUIO_lCursor id -> curobj in
let nth_list obstr.PTUIO_lCursor (sizelist obstr.PTUIO_lCursor) - 1 -> [_ lastobj] in
let nth_list obstr.PTUIO_lCursor (sizelist obstr.PTUIO_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.PTUIO_bTips) then nil else
SO3WidgetSetPosition curobj.POBC_tips x-32 y-32;
// manage mouse with first point
if (lastobj != curobj || !obstr.PTUIO_bMouse) then nil else
(
_RMTCTRL_MouseMove x y RMTCTRL_ABSOLUTEMOVE;
// hold for click down
let curobj.POBC_velAcc -> [accx accy] in
if (((absf accx) <. 2.0) && ((absf accy) <. 2.0) && ((_tickcount - lastobj.POBC_lifeTime) > 500) && !lastobj.POBC_bClick) then
(
set lastobj.POBC_bClick = 1;
_RMTCTRL_MouseClick 1;
)
else 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.PTUIO_inst "Angle" (ftoa ang) nil;
SendPluginEvent obstr.PTUIO_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.PTUIO_inst "Angle velocity" (ftoa vang) nil;
SendPluginEvent obstr.PTUIO_inst "Distance velocity" (itoa vdist) nil;
);
set secobj.POBC_lastAng = ang;
set secobj.POBC_lastDist = dist;
);
);
);
0;;
fun cbRemoveCursor(tuioObj, obstr, id)=
let switch obstr.PTUIO_lCursor id -> curobj in
let nth_list obstr.PTUIO_lCursor (sizelist obstr.PTUIO_lCursor) - 1 -> [_ lastobj] in
(
if (!obstr.PTUIO_bTips) then nil else
SO3WidgetDestroy curobj.POBC_tips;
set obstr.PTUIO_lCursor = remove_idx_from_list obstr.PTUIO_lCursor id;
SendPluginEvent obstr.PTUIO_inst "Nb cursor" itoa (sizelist obstr.PTUIO_lCursor) nil;
// manage mouse with first point
if (lastobj != curobj) then nil else
(
if ((_tickcount - lastobj.POBC_lifeTime) > 500) then
(
// unclick
if (!obstr.PTUIO_bMouse || !lastobj.POBC_bClick) then nil else
_RMTCTRL_MouseUnClick 1;
)
else // tap
(
if (!obstr.PTUIO_bMouse) then nil else
(
_RMTCTRL_MouseClick 1;
_RMTCTRL_MouseUnClick 1;
);
SendPluginEvent obstr.PTUIO_inst "Tap" nil nil;
);
if ((sizelist obstr.PTUIO_lCursor) != 0) then nil else
let curobj.POBC_velAcc -> [vx vy] in
(
if (vx <=. -.10.0) && ((absf vy) <=. 5.0) then
SendPluginEvent obstr.PTUIO_inst "Swipe left" nil nil
else if (vx >=. 10.0) && ((absf vy) <=. 5.0) then
SendPluginEvent obstr.PTUIO_inst "Swipe right" nil nil
else if (vy <=. -.10.0) && ((absf vx) <=. 5.0) then
SendPluginEvent obstr.PTUIO_inst "Swipe up" nil nil
else if (vy >=. 10.0) && ((absf vx) <=. 5.0) then
SendPluginEvent obstr.PTUIO_inst "Swipe down" nil nil
else nil;
);
);
);
0;;
/*! \brief Callback on instance destruction
*
* Prototype: fun [PInstance SerialIO] I
*
* \param PInstance : destroyed plugIT instance
* \param PlugTUIO : Tuio struct
*
* \return I : 0
**/
fun deleteOb(inst, obstr)=
_DSTuioClient obstr.PTUIO_obj;
//remove all tips
while (obstr.PTUIO_lCursor != nil) do
(
let hd obstr.PTUIO_lCursor -> [_ curobj] in
SO3WidgetDestroy curobj.POBC_tips;
set obstr.PTUIO_lCursor = tl obstr.PTUIO_lCursor;
);
_DSalphaBitmap obstr.PTUIO_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 "port") -> sport in
let if sport == nil then 3333 else sport -> sport in
let atoi (getPluginInstanceParam inst "mouse") -> mouse in
let if mouse == nil then 1 else mouse -> mouse in
let atoi (getPluginInstanceParam inst "tips") -> tips in
let if tips == nil then 1 else tips -> tips in
let _CRTuioClient _channel sport -> tuioObj in
let mkPlugTUIO [inst tuioObj nil nil nil mouse tips] -> obstr in
(
if (!obstr.PTUIO_bTips) then nil else
set obstr.PTUIO_bmpTip = G2DloadAlphaBmp _channel strcatn (getPluginDirectory (getInstancePlugin inst))::"/res/tips.png"::nil;
_CBTuioAddCursor tuioObj @cbAddCursor obstr;
_CBTuioRemoveCursor tuioObj @cbRemoveCursor obstr;
_CBTuioUpdateCursor tuioObj @cbUpdateCursor obstr;
_CONNECTTuioClient tuioObj;
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;;