<div dir="ltr"><div>I found bugs in my first implementation and spent another 4.5 days working through them;</div><div>Results:</div><div><a href="http://dug9.users.sourceforge.net/web3d/tests/sensors/DragCascade_MultitouchSensorII.mp4">http://dug9.users.sourceforge.net/web3d/tests/sensors/DragCascade_MultitouchSensorII.mp4</a>  <br></div><div><br></div><div>Method:</div><div>MultitouchSensor had output fields for rotation_changed, scale_changed, translation_changed</div><div>When computing the translation from 2 points you might end up with something like how Transform nodes are done - with a center point C for where you rotate and scale:</div><div>T x C x R x S x (-C)</div><div>And so to get a summary translation with no center, you need to solve:</div><div>TxRxS = TxCxRxSx(-C)</div><div>And I wasn't doing that properly. I found there are 2 ways:</div><div>1) matrix decompose - you can chain transforms together, then decompose the final transform</div><div><p class="MsoNormal" style="margin:0cm 0cm 0.0001pt;font-size:10pt;font-family:Verdana"><a href="https://webdocs.cs.ualberta.ca/~graphics/books/GraphicsGems/gemsiv/polar_decomp/" style="color:blue">https://webdocs.cs.ualberta.ca/~graphics/books/GraphicsGems/gemsiv/polar_decomp/</a>
</p>

<p class="MsoNormal" style="margin:0cm 0cm 0.0001pt;font-size:10pt;font-family:Verdana">- GraphicsGems IV matrix decomposer</p><p class="MsoNormal" style="margin:0cm 0cm 0.0001pt;font-size:10pt;font-family:Verdana">2) least squares similarity 2D solver - which solves for 4 params: rotation, scale, xy translation</p><p class="MsoNormal" style="margin:0cm 0cm 0.0001pt;font-size:10pt;font-family:Verdana"><a href="https://sourceforge.net/p/freewrl/git/ci/develop/tree/freex3d/src/lib/input/SensInterps.c">https://sourceforge.net/p/freewrl/git/ci/develop/tree/freex3d/src/lib/input/SensInterps.c</a>  </p><p class="MsoNormal" style="margin:0cm 0cm 0.0001pt;font-size:10pt;font-family:Verdana">- lines 1725 - 2063 are marked MIT Lic or equivalent, and have the matrix solver and 2D similarity solver</p><p class="MsoNormal" style="margin:0cm 0cm 0.0001pt;font-size:10pt;font-family:Verdana"><span style="font-size:10pt">I used a bit of both - least squares for computing the transform from 2 drags,</span><br></p><p class="MsoNormal" style="margin:0cm 0cm 0.0001pt;font-size:10pt;font-family:Verdana"><span style="font-size:10pt">and matrix decomposer for combining with previous offsets .offset (translation) rotationOffset, scaleOffset.</span></p><p class="MsoNormal" style="margin:0cm 0cm 0.0001pt;font-size:10pt;font-family:Verdana"><span style="font-size:10pt">Tout = Tcomputed_from_current_drags X Toffsets</span></p><p class="MsoNormal" style="margin:0cm 0cm 0.0001pt;font-size:10pt;font-family:Verdana"><span style="font-size:10pt">- then decomposing Tout to set the translation_changed, rotation_changed, scale_changed fields.</span></p><p class="MsoNormal" style="margin:0cm 0cm 0.0001pt;font-size:10pt;font-family:Verdana"><br></p><p class="MsoNormal" style="margin:0cm 0cm 0.0001pt;font-size:10pt;font-family:Verdana">A few days of my time were spent trying to diagnose freewrl-specific issues, primarily </p><p class="MsoNormal" style="margin:0cm 0cm 0.0001pt;font-size:10pt;font-family:Verdana">we 'freeze' the transform to the sensor while a button is down. For 2 buttons, what </p><p class="MsoNormal" style="margin:0cm 0cm 0.0001pt;font-size:10pt;font-family:Verdana">happens if you add a 3rd button, or remove one of 2 buttons. Having a way to update</p><p class="MsoNormal" style="margin:0cm 0cm 0.0001pt;font-size:10pt;font-family:Verdana">the transforms reliably took some time, and one thing that helped was rendering the touch/drag points</p><p class="MsoNormal" style="margin:0cm 0cm 0.0001pt;font-size:10pt;font-family:Verdana">in sensor space -by making it a renderable node, and rendering the drag ponits-</p><p class="MsoNormal" style="margin:0cm 0cm 0.0001pt;font-size:10pt;font-family:Verdana"> as well as screen / viewer space. Weird motions often made sense relative to</p><p class="MsoNormal" style="margin:0cm 0cm 0.0001pt;font-size:10pt;font-family:Verdana">the touch-down points in sensor space.</p><p class="MsoNormal" style="margin:0cm 0cm 0.0001pt;font-size:10pt;font-family:Verdana"><br></p><p class="MsoNormal" style="margin:0cm 0cm 0.0001pt;font-size:10pt;font-family:Verdana">Having a built-in emulator for multitouch helped a bit - didn't need to fiddle with other devices,</p><p class="MsoNormal" style="margin:0cm 0cm 0.0001pt;font-size:10pt;font-family:Verdana">- just mouse.</p><p class="MsoNormal" style="margin:0cm 0cm 0.0001pt;font-size:10pt;font-family:Verdana"><br></p><p class="MsoNormal" style="margin:0cm 0cm 0.0001pt;font-size:10pt;font-family:Verdana">Good luck - hope other x3d browsers are easier.</p><p class="MsoNormal" style="margin:0cm 0cm 0.0001pt;font-size:10pt;font-family:Verdana">-Doug</p><p class="MsoNormal" style="margin:0cm 0cm 0.0001pt;font-size:10pt;font-family:Verdana"><br></p></div><div class="gmail_quote"><div dir="ltr" class="gmail_attr"><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr">My experience implementing (v4 proposed) MultitouchSensor in freewrl:<div><br></div><div>Results:</div><div><p class="MsoNormal" style="margin:0cm 0cm 0.0001pt;font-size:10pt;font-family:Verdana"><a href="http://dug9.users.sourceforge.net/web3d/tests/sensors/DragCascade_MultitouchSensor.mp4" target="_blank">http://dug9.users.sourceforge.net/web3d/tests/sensors/DragCascade_MultitouchSensor.mp4</a></p>

<p class="MsoNormal" style="margin:0cm 0cm 0.0001pt;font-size:10pt;font-family:Verdana"><a href="http://dug9.users.sourceforge.net/web3d/tests/sensors/DragCascade_MultitouchSensor.x3d" target="_blank">http://dug9.users.sourceforge.net/web3d/tests/sensors/DragCascade_MultitouchSensor.x3d</a></p><p class="MsoNormal" style="margin:0cm 0cm 0.0001pt;font-size:10pt;font-family:Verdana"><br></p></div><div>Method:</div><div>freewrl has had a multitouch emulator built in for serveral years.</div><div>- a command line option turns it on, then it uses the mouse differently</div><div>-- a RMB click creates a new drag -with a touchID</div><div>-- a LMB click near an existing drag will grab it, and LMB drag will drag it</div><div>-- another RMB click on an existing drag will delete it</div><div>- and then whereever we are passing around mouse coordinates and button status, we pass an additional touchID.</div><div>-- I verified the touch emulator approach with another emulator that puts touches into the windows desktop from a 2nd computer, and inhales the touches via windows events.</div><div>But all we did was drag 2 separate dragsensors with 2 separate touches. <br></div><div><br></div><div>This new spec node adds a node that will take 2+ touches and do something interesting - output a rotation and scale, along with the usual planesensor type translation.<br></div><div>So I started by copying the Planesensor and hacking it to count active drags, and when it has only one, it acts like a PlaneSensor, and when it has 2+ it uses the first 2 to compute rotation and scale </div><div><br></div><div>Time:</div><div>Took 2.5 days. fiddly hard to understand code in freewrl. Hope other browsers are more organized.</div><div><br></div><div>And of the 2.5 days I spent 1/2 day reviewing a least_squares option which I didn't use, but could be used with 3+ points to compute a best-fit affine (6 parameter - 2 scales, 1 shear, 1 rotation, and xy 2 translations)</div><div><br></div><div>-Doug</div></div>
</blockquote></div></div>