bool Form::touchEventInternal(Touch::TouchEvent evt, int x, int y, unsigned int contactIndex) { // Check for a collision with each Form in __forms. // Pass the event on. bool eventConsumed = false; size_t size = __forms.size(); for (size_t i = 0; i < size; ++i) { Form* form = __forms[i]; GP_ASSERT(form); if (form->isEnabled()) { if (form->_node) { Vector3 point; if (form->projectPoint(x, y, &point)) { const Rectangle& bounds = form->getBounds(); if (form->getState() == Control::FOCUS || (evt == Touch::TOUCH_PRESS && point.x >= bounds.x && point.x <= bounds.x + bounds.width && point.y >= bounds.y && point.y <= bounds.y + bounds.height)) { eventConsumed |= form->touchEvent(evt, point.x - bounds.x, bounds.height - point.y - bounds.y, contactIndex); } } } else { // Simply compare with the form's bounds. const Rectangle& bounds = form->getBounds(); if (form->getState() == Control::FOCUS || (evt == Touch::TOUCH_PRESS && x >= bounds.x && x <= bounds.x + bounds.width && y >= bounds.y && y <= bounds.y + bounds.height)) { // Pass on the event's position relative to the form. eventConsumed |= form->touchEvent(evt, x - bounds.x, y - bounds.y, contactIndex); } } } } return eventConsumed; }
bool Form::touchEventInternal(Touch::TouchEvent evt, int x, int y, unsigned int contactIndex) { // Check for a collision with each Form in __forms. // Pass the event on. size_t size = __forms.size(); for (size_t i = 0; i < size; ++i) { Form* form = __forms[i]; GP_ASSERT(form); if (form->isEnabled() && form->isVisible()) { if (form->_node) { Vector3 point; if (form->projectPoint(x, y, &point)) { const Rectangle& bounds = form->getBounds(); if (shouldPropagateTouchEvent(form->getState(), evt, bounds, point.x, point.y)) { if (form->touchEvent(evt, point.x - bounds.x, bounds.height - point.y - bounds.y, contactIndex)) return true; } } } else { // Simply compare with the form's bounds. const Rectangle& bounds = form->getBounds(); if (shouldPropagateTouchEvent(form->getState(), evt, bounds, x, y)) { // Pass on the event's position relative to the form. if (form->touchEvent(evt, x - bounds.x, y - bounds.y, contactIndex)) return true; } } } } return false; }
bool Form::touchEventInternal(Touch::TouchEvent evt, int x, int y, unsigned int contactIndex) { // Check for a collision with each Form in __forms. // Pass the event on. std::vector<Form*>::const_iterator it; for (it = __forms.begin(); it < __forms.end(); it++) { Form* form = *it; if (form->isEnabled()) { Node* node = form->_node; if (node) { Scene* scene = node->getScene(); Camera* camera = scene->getActiveCamera(); if (camera) { // Get info about the form's position. Matrix m = node->getMatrix(); Vector3 min(0, 0, 0); m.transformPoint(&min); // Unproject point into world space. Ray ray; camera->pickRay(Game::getInstance()->getViewport(), x, y, &ray); // Find the quad's plane. // We know its normal is the quad's forward vector. Vector3 normal = node->getForwardVectorWorld(); // To get the plane's distance from the origin, // we'll find the distance from the plane defined // by the quad's forward vector and one of its points // to the plane defined by the same vector and the origin. const float& a = normal.x; const float& b = normal.y; const float& c = normal.z; const float d = -(a*min.x) - (b*min.y) - (c*min.z); const float distance = abs(d) / sqrt(a*a + b*b + c*c); Plane plane(normal, -distance); // Check for collision with plane. float collisionDistance = ray.intersects(plane); if (collisionDistance != Ray::INTERSECTS_NONE) { // Multiply the ray's direction vector by collision distance // and add that to the ray's origin. Vector3 point = ray.getOrigin() + collisionDistance*ray.getDirection(); // Project this point into the plane. m.invert(); m.transformPoint(&point); // Pass the touch event on. const Rectangle& bounds = form->getClipBounds(); if (form->getState() == Control::FOCUS || (evt == Touch::TOUCH_PRESS && point.x >= bounds.x && point.x <= bounds.x + bounds.width && point.y >= bounds.y && point.y <= bounds.y + bounds.height)) { if (form->touchEvent(evt, point.x - bounds.x, bounds.height - point.y - bounds.y, contactIndex)) { return true; } } } } } else { // Simply compare with the form's bounds. const Rectangle& bounds = form->getClipBounds(); if (form->getState() == Control::FOCUS || (evt == Touch::TOUCH_PRESS && x >= bounds.x && x <= bounds.x + bounds.width && y >= bounds.y && y <= bounds.y + bounds.height)) { // Pass on the event's position relative to the form. if (form->touchEvent(evt, x - bounds.x, y - bounds.y, contactIndex)) { return true; } } } } } return false; }