bool SceneService::onTouchEvent(const gameplay::Touch::TouchEvent& ev, int x, int y, unsigned contactIndex) { if (contactIndex != 0) return false; if (ev == gameplay::Touch::TOUCH_PRESS) { _touchStart.set(static_cast<float>(x), static_cast<float>(y)); _dragDetected = true; return true; } if (ev == gameplay::Touch::TOUCH_RELEASE && !_dragDetected) { float vpwidth = static_cast<float>(gameplay::Game::getInstance()->getWidth()); float vpheight = static_cast<float>(gameplay::Game::getInstance()->getHeight()); float sidebarWidth = getSettings()->getSidebarWidth(); gameplay::Ray ray; _camera->pickRay(gameplay::Rectangle(sidebarWidth, 0.0f, vpwidth - sidebarWidth, vpheight), _touchStart.x, _touchStart.y, &ray); return true; } if (ev == gameplay::Touch::TOUCH_MOVE) { gameplay::Vector2 touchPos(static_cast<float>(x), static_cast<float>(y)); gameplay::Vector2 delta(touchPos - _touchStart); if (_dragDetected) { _touchStart = touchPos; _cameraTheta = std::min(MATH_PIOVER2 * 0.99f, std::max(-MATH_PIOVER2 * 0.99f, _cameraTheta + MATH_PI * delta.y / gameplay::Game::getInstance()->getViewport().height)); _cameraPhi = fmodf(_cameraPhi - MATH_PI * delta.x / gameplay::Game::getInstance()->getViewport().width, MATH_PIX2); updateCamera(); } else if (delta.length() > gameplay::Game::getInstance()->getViewport().height * 0.01f) { _dragDetected = true; } return true; } return false; }
//------------------------------------------------- void ttControl::touchUp(int x, int y, int TouchId){ int counter =0; ofPoint touchPos(x,y); for (int i = 0; i<4; i++) { if (TouchId == touchID[i]) { bTouch[i]=false; } } for (int i = 0; i< 4; i++) { if (bTouch[i]) { counter ++; } } if (counter <4) { bAllTouch = false; } }
//------------------------------------------------ void ttControl::touchDown(int x, int y, int TouchId){ int counter =0; ofPoint touchPos(x,y); for (int i = 0; i<4; i++) { if (orgPos[i].distance(touchPos)<RAD) { bTouch[i]=true; touchID[i] = TouchId; } } for (int i = 0; i< 4; i++) { if (bTouch[i]) { counter ++; } } if (counter ==4) { bAllTouch = true; } }
JNIEXPORT void JNICALL Java_com_zjhlogo_libspank_GameEntry_touchEvent(JNIEnv* env, jobject obj, jint actionType, jfloat x, jfloat y) { glm::vec2 touchPos(x, y); g_pFrameworkAndroid->getTouchDelegateMgr()->handleTouchEvent((spank::ITouchDelegate::ACTION_TYPE_ID)actionType, touchPos); }
void TouchTracker::process(int) { if (!mpIn) return; const MLSignal& in(*mpIn); if (mNeedsClear) { mBackground.copy(in); mBackgroundFilter.clear(); mNeedsClear = false; return; } mFilteredInput.copy(in); if (mCalibrator.isCalibrating()) { int done = mCalibrator.addSample(mFilteredInput); if(done == 1) { // Tell the listener we have a new calibration. We still do the calibration here in the Tracker, // but the Model will be responsible for saving and restoring the calibration maps. if(mpListener) { mpListener->hasNewCalibration(mCalibrator.mCalibrateSignal, mCalibrator.mNormalizeMap, mCalibrator.mAvgDistance); } } } else { if(mDoNormalize) { mCalibrator.normalizeInput(mFilteredInput); } if(mMaxTouchesPerFrame > 0) { // smooth input float kc, ke, kk; kc = 4./16.; ke = 2./16.; kk=1./16.; mFilteredInput.convolve3x3r(kc, ke, kk); // build sum of currently tracked touches // mSumOfTouches.clear(); int numActiveTouches = 0; for(int i = 0; i < mMaxTouchesPerFrame; ++i) { const Touch& t(mTouches[i]); if(t.isActive()) { Vec2 touchPos(t.x, t.y); mTemplateScaled.clear(); mTemplateScaled.add2D(mCalibrator.getTemplate(touchPos), 0, 0); mTemplateScaled.scale(t.z*mCalibrator.getZAdjust(touchPos)); mSumOfTouches.add2D(mTemplateScaled, touchPos - Vec2(kTemplateRadius, kTemplateRadius)); numActiveTouches++; } } // to make sum of touches a bit bigger //mSumOfTouches.scale(1.5f); //mSumOfTouches.convolve3x3r(kc, ke, kk); // // TODO lots of optimization here in onepole, 2D filter // // TODO the mean of lowpass background can be its own control source that will // act like an accelerometer! tilt controls even. mBackgroundFilterFrequency.fill(mBackgroundFilterFreq); // build background: lowpass filter rest state. Filter freq. // is nonzero where there are no touches, 0 where there are touches. mTemp.copy(mSumOfTouches); mTemp.scale(100.f); mBackgroundFilterFrequency.subtract(mTemp); mBackgroundFilterFrequency.sigMax(0.); // TODO allow filter to move a little if touch template distance is near threshold // this will fix most stuck touches // filter background in up direction mBackgroundFilterFrequency2.fill(mBackgroundFilterFreq); mBackgroundFilter.setInputSignal(&mFilteredInput); mBackgroundFilter.setOutputSignal(&mBackground); // set asymmetric filter coeffs and get background mBackgroundFilter.setCoeffs(mBackgroundFilterFrequency, mBackgroundFilterFrequency2); mBackgroundFilter.process(1); } // subtract background from input // mInputMinusBackground.copy(mFilteredInput); mInputMinusBackground.subtract(mBackground); // move or remove and filter existing touches // updateTouches(mInputMinusBackground); // TODO can negative values be used to inhibit nearby touches? // this might prevent sticking touches when a lot of force is // applied then quickly released. // TODO look for retriggers here, touches not fallen to 0 but where // dz warrants a new note-on. The way to do this is keep a second, // separate set of key states that do not get cleared by current // touches. These can be used to get the dz values and using the exact // same math, velocities will match other note-ons. // // we can also look for a nearby release just beforehand when // retriggering. this will increase confidence in a retrigger as // opposed to simply moving the touch. // after update Touches, subtract sum of touches to get residual R // R = input - T. // This represents any pressure data not currently part of a touch. if(mMaxTouchesPerFrame > 0) { mInputMinusBackground.sigMax(0.); mResidual.copy(mInputMinusBackground); mResidual.subtract(mSumOfTouches); mResidual.sigMax(0.); } // get signals for viewer // TODO optimize: we only have to copy these each time a view is needed mCalibratedSignal.copy(mInputMinusBackground); mCookedSignal.copy(mSumOfTouches); mTestSignal.copy(mResidual); // get subpixel xyz peak from residual addPeakToKeyState(mResidual); // update key states for(int i=0; i<mNumKeys; ++i) { mKeyStates[i].tick(); } findTouches(); // filter touches // filter x and y for output // filter touches and write touch data to one frame of output signal. // MLSignal& out = *mpOut; for(int i = 0; i < mMaxTouchesPerFrame; ++i) { Touch& t = mTouches[i]; if(t.age > 1) { float xyc = 1.0f - powf(2.71828f, -kMLTwoPi * mLopass*0.1f / (float)mSampleRate); t.xf += (t.x - t.xf)*xyc; t.yf += (t.y - t.yf)*xyc; } else if(t.age == 1) { t.xf = t.x; t.yf = t.y; } out(xColumn, i) = t.xf; out(yColumn, i) = t.yf; out(zColumn, i) = (t.age > 0) ? t.zf : 0.; out(dzColumn, i) = t.dz; out(ageColumn, i) = t.age; out(dtColumn, i) = t.tDist; } } #if DEBUG // TEMP if (mCount++ > 1000) { mCount = 0; // dumpTouches(); } #endif }