Object.assign(pc, function () {
var targetX, targetY;
var vecA = new pc.Vec3();
var vecB = new pc.Vec3();
var _pq = new pc.Vec3();
var _pa = new pc.Vec3();
var _pb = new pc.Vec3();
var _pc = new pc.Vec3();
var _pd = new pc.Vec3();
var _m = new pc.Vec3();
var _sct = new pc.Vec3();
var _accumulatedScale = new pc.Vec2();
var _paddingTop = new pc.Vec3();
var _paddingBottom = new pc.Vec3();
var _paddingLeft = new pc.Vec3();
var _paddingRight = new pc.Vec3();
var _cornerBottomLeft = new pc.Vec3();
var _cornerBottomRight = new pc.Vec3();
var _cornerTopRight = new pc.Vec3();
var _cornerTopLeft = new pc.Vec3();
var ZERO_VEC4 = new pc.Vec4();
// pi x p2 * p3
var scalarTriple = function (p1, p2, p3) {
return _sct.cross(p1, p2).dot(p3);
};
// Given line pq and ccw corners of a quad, return whether the line
// intersects it. (from Real-Time Collision Detection book)
var intersectLineQuad = function (p, q, corners) {
_pq.sub2(q, p);
_pa.sub2(corners[0], p);
_pb.sub2(corners[1], p);
_pc.sub2(corners[2], p);
// Determine which triangle to test against by testing against diagonal first
_m.cross(_pc, _pq);
var v = _pa.dot(_m);
if (v >= 0) {
// Test intersection against triangle abc
if (-_pb.dot(_m) < 0)
return false;
if (scalarTriple(_pq, _pb, _pa) < 0)
return false;
} else {
// Test intersection against triangle dac
_pd.sub2(corners[3], p);
if (_pd.dot(_m) < 0)
return false;
if (scalarTriple(_pq, _pa, _pd) < 0)
return false;
}
// The algorithm above doesn't work if all the corners are the same
// So do that test here by checking if the diagonals are 0 (since these are rectangles we're checking against)
if (_pq.sub2(corners[0], corners[2]).lengthSq() < 0.0001 * 0.0001) return false;
if (_pq.sub2(corners[1], corners[3]).lengthSq() < 0.0001 * 0.0001) return false;
return true;
};
/**
* @constructor
* @name pc.ElementInputEvent
* @classdesc Represents an input event fired on a {@link pc.ElementComponent}. When an event is raised
* on an ElementComponent it bubbles up to its parent ElementComponents unless we call stopPropagation().
* @description Create an instance of a pc.ElementInputEvent.
* @param {MouseEvent|TouchEvent} event The MouseEvent or TouchEvent that was originally raised.
* @param {pc.ElementComponent} element The ElementComponent that this event was originally raised on.
* @param {pc.CameraComponent} camera The CameraComponent that this event was originally raised via.
* @property {MouseEvent|TouchEvent} event The MouseEvent or TouchEvent that was originally raised.
* @property {pc.ElementComponent} element The ElementComponent that this event was originally raised on.
*/
var ElementInputEvent = function (event, element, camera) {
this.event = event;
this.element = element;
this.camera = camera;
this._stopPropagation = false;
};
Object.assign(ElementInputEvent.prototype, {
/**
* @function
* @name pc.ElementInputEvent#stopPropagation
* @description Stop propagation of the event to parent {@link pc.ElementComponent}s. This also stops propagation of the event to other event listeners of the original DOM Event.
*/
stopPropagation: function () {
this._stopPropagation = true;
this.event.stopImmediatePropagation();
this.event.stopPropagation();
}
});
/**
* @constructor
* @name pc.ElementMouseEvent
* @classdesc Represents a Mouse event fired on a {@link pc.ElementComponent}.
* @extends pc.ElementInputEvent
* @description Create an instance of a pc.ElementMouseEvent.
* @param {MouseEvent} event The MouseEvent that was originally raised.
* @param {pc.ElementComponent} element The ElementComponent that this event was originally raised on.
* @param {pc.CameraComponent} camera The CameraComponent that this event was originally raised via.
* @param {Number} x The x coordinate
* @param {Number} y The y coordinate
* @param {Number} lastX The last x coordinate
* @param {Number} lastY The last y coordinate
* @property {Boolean} ctrlKey Whether the ctrl key was pressed
* @property {Boolean} altKey Whether the alt key was pressed
* @property {Boolean} shiftKey Whether the shift key was pressed
* @property {Boolean} metaKey Whether the meta key was pressed
* @property {Number} button The mouse button
* @property {Number} dx The amount of horizontal movement of the cursor
* @property {Number} dy The amount of vertical movement of the cursor
* @property {Number} wheel The amount of the wheel movement
*/
var ElementMouseEvent = function (event, element, camera, x, y, lastX, lastY) {
ElementInputEvent.call(this, event, element, camera);
this.x = x;
this.y = y;
this.ctrlKey = event.ctrlKey || false;
this.altKey = event.altKey || false;
this.shiftKey = event.shiftKey || false;
this.metaKey = event.metaKey || false;
this.button = event.button;
if (pc.Mouse.isPointerLocked()) {
this.dx = event.movementX || event.webkitMovementX || event.mozMovementX || 0;
this.dy = event.movementY || event.webkitMovementY || event.mozMovementY || 0;
} else {
this.dx = x - lastX;
this.dy = y - lastY;
}
// FF uses 'detail' and returns a value in 'no. of lines' to scroll
// WebKit and Opera use 'wheelDelta', WebKit goes in multiples of 120 per wheel notch
if (event.detail) {
this.wheel = -1 * event.detail;
} else if (event.wheelDelta) {
this.wheel = event.wheelDelta / 120;
} else {
this.wheel = 0;
}
};
ElementMouseEvent.prototype = Object.create(ElementInputEvent.prototype);
ElementMouseEvent.prototype.constructor = ElementMouseEvent;
/**
* @constructor
* @name pc.ElementTouchEvent
* @classdesc Represents a TouchEvent fired on a {@link pc.ElementComponent}.
* @extends pc.ElementInputEvent
* @description Create an instance of a pc.ElementTouchEvent.
* @param {TouchEvent} event The TouchEvent that was originally raised.
* @param {pc.ElementComponent} element The ElementComponent that this event was originally raised on.
* @param {pc.CameraComponent} camera The CameraComponent that this event was originally raised via.
* @param {Number} x The x coordinate of the touch that triggered the event
* @param {Number} y The y coordinate of the touch that triggered the event
* @param {pc.ElementInput} input The pc.ElementInput instance
* @property {Touch[]} touches The Touch objects representing all current points of contact with the surface, regardless of target or changed status.
* @property {Touch[]} changedTouches The Touch objects representing individual points of contact whose states changed between the previous touch event and this one.
*/
var ElementTouchEvent = function (event, element, camera, x, y, input) {
ElementInputEvent.call(this, event, element, camera);
this.touches = event.touches;
this.changedTouches = event.changedTouches;
this.x = x;
this.y = y;
};
ElementTouchEvent.prototype = Object.create(ElementInputEvent.prototype);
ElementTouchEvent.prototype.constructor = ElementTouchEvent;
/**
* @constructor
* @name pc.ElementInput
* @classdesc Handles mouse and touch events for {@link pc.ElementComponent}s. When input events
* occur on an ElementComponent this fires the appropriate events on the ElementComponent.
* @description Create a new pc.ElementInput instance.
* @param {Element} domElement The DOM element
* @param {Object} [options] Optional arguments
* @param {Object} [options.useMouse] Whether to allow mouse input. Defaults to true.
* @param {Object} [options.useTouch] Whether to allow touch input. Defaults to true.
*/
var ElementInput = function (domElement, options) {
this._app = null;
this._attached = false;
this._target = null;
// force disable all element input events
this._enabled = true;
this._lastX = 0;
this._lastY = 0;
this._upHandler = this._handleUp.bind(this);
this._downHandler = this._handleDown.bind(this);
this._moveHandler = this._handleMove.bind(this);
this._wheelHandler = this._handleWheel.bind(this);
this._touchstartHandler = this._handleTouchStart.bind(this);
this._touchendHandler = this._handleTouchEnd.bind(this);
this._touchcancelHandler = this._touchendHandler;
this._touchmoveHandler = this._handleTouchMove.bind(this);
this._sortHandler = this._sortElements.bind(this);
this._elements = [];
this._hoveredElement = null;
this._pressedElement = null;
this._touchedElements = {};
this._touchesForWhichTouchLeaveHasFired = {};
this._useMouse = !options || options.useMouse !== false;
this._useTouch = !options || options.useTouch !== false;
if (pc.platform.touch) {
this._clickedEntities = {};
}
this.attach(domElement, options);
};
Object.assign(ElementInput.prototype, {
/**
* @function
* @name pc.ElementInput#attach
* @description Attach mouse and touch events to a DOM element.
* @param {Element} domElement The DOM element
*/
attach: function (domElement) {
if (this._attached) {
this._attached = false;
this.detach();
}
this._target = domElement;
this._attached = true;
if (this._useMouse) {
window.addEventListener('mouseup', this._upHandler, { passive: true });
window.addEventListener('mousedown', this._downHandler, { passive: true });
window.addEventListener('mousemove', this._moveHandler, { passive: true });
window.addEventListener('mousewheel', this._wheelHandler, { passive: true });
window.addEventListener('DOMMouseScroll', this._wheelHandler, { passive: true });
}
if (this._useTouch && pc.platform.touch) {
this._target.addEventListener('touchstart', this._touchstartHandler, { passive: true });
// Passive is not used for the touchend event because some components need to be
// able to call preventDefault(). See notes in button/component.js for more details.
this._target.addEventListener('touchend', this._touchendHandler, false);
this._target.addEventListener('touchmove', this._touchmoveHandler, false);
this._target.addEventListener('touchcancel', this._touchcancelHandler, false);
}
},
/**
* @function
* @name pc.ElementInput#detach
* @description Remove mouse and touch events from the DOM element that it is attached to
*/
detach: function () {
if (!this._attached) return;
this._attached = false;
if (this._useMouse) {
window.removeEventListener('mouseup', this._upHandler, false);
window.removeEventListener('mousedown', this._downHandler, false);
window.removeEventListener('mousemove', this._moveHandler, false);
window.removeEventListener('mousewheel', this._wheelHandler, false);
window.removeEventListener('DOMMouseScroll', this._wheelHandler, false);
}
if (this._useTouch) {
this._target.removeEventListener('touchstart', this._touchstartHandler, false);
this._target.removeEventListener('touchend', this._touchendHandler, false);
this._target.removeEventListener('touchmove', this._touchmoveHandler, false);
this._target.removeEventListener('touchcancel', this._touchcancelHandler, false);
}
this._target = null;
},
/**
* @function
* @name pc.ElementInput#addElement
* @description Add a {@link pc.ElementComponent} to the internal list of ElementComponents that are being checked for input.
* @param {pc.ElementComponent} element The ElementComponent
*/
addElement: function (element) {
if (this._elements.indexOf(element) === -1)
this._elements.push(element);
},
/**
* @function
* @name pc.ElementInput#removeElement
* @description Remove a {@link pc.ElementComponent} from the internal list of ElementComponents that are being checked for input.
* @param {pc.ElementComponent} element The ElementComponent
*/
removeElement: function (element) {
var idx = this._elements.indexOf(element);
if (idx !== -1)
this._elements.splice(idx, 1);
},
_handleUp: function (event) {
if (!this._enabled) return;
if (pc.Mouse.isPointerLocked())
return;
this._calcMouseCoords(event);
if (targetX === null)
return;
this._onElementMouseEvent(event);
},
_handleDown: function (event) {
if (!this._enabled) return;
if (pc.Mouse.isPointerLocked())
return;
this._calcMouseCoords(event);
if (targetX === null)
return;
this._onElementMouseEvent(event);
},
_handleMove: function (event) {
if (!this._enabled) return;
this._calcMouseCoords(event);
if (targetX === null)
return;
this._onElementMouseEvent(event);
this._lastX = targetX;
this._lastY = targetY;
},
_handleWheel: function (event) {
if (!this._enabled) return;
this._calcMouseCoords(event);
if (targetX === null)
return;
this._onElementMouseEvent(event);
},
_determineTouchedElements: function (event) {
var touchedElements = {};
var cameras = this.app.systems.camera.cameras;
var i, j, len;
// check cameras from last to front
// so that elements that are drawn above others
// receive events first
for (i = cameras.length - 1; i >= 0; i--) {
var camera = cameras[i];
var done = 0;
for (j = 0, len = event.changedTouches.length; j < len; j++) {
if (touchedElements[event.changedTouches[j].identifier]) {
done++;
continue;
}
var coords = this._calcTouchCoords(event.changedTouches[j]);
var element = this._getTargetElement(camera, coords.x, coords.y);
if (element) {
done++;
touchedElements[event.changedTouches[j].identifier] = {
element: element,
camera: camera,
x: coords.x,
y: coords.y
};
}
}
if (done === len) {
break;
}
}
return touchedElements;
},
_handleTouchStart: function (event) {
if (!this._enabled) return;
var newTouchedElements = this._determineTouchedElements(event);
for (var i = 0, len = event.changedTouches.length; i < len; i++) {
var touch = event.changedTouches[i];
var newTouchInfo = newTouchedElements[touch.identifier];
var oldTouchInfo = this._touchedElements[touch.identifier];
if (newTouchInfo && (!oldTouchInfo || newTouchInfo.element !== oldTouchInfo.element)) {
this._fireEvent(event.type, new ElementTouchEvent(event, newTouchInfo.element, newTouchInfo.camera, newTouchInfo.x, newTouchInfo.y, this));
this._touchesForWhichTouchLeaveHasFired[touch.identifier] = false;
}
}
for (var touchId in newTouchedElements) {
this._touchedElements[touchId] = newTouchedElements[touchId];
}
},
_handleTouchEnd: function (event) {
if (!this._enabled) return;
var cameras = this.app.systems.camera.cameras;
// clear clicked entities first then store each clicked entity
// in _clickedEntities so that we don't fire another click
// on it in this handler or in the mouseup handler which is
// fired later
for (var key in this._clickedEntities) {
delete this._clickedEntities[key];
}
for (var i = 0, len = event.changedTouches.length; i < len; i++) {
var touch = event.changedTouches[i];
var touchInfo = this._touchedElements[touch.identifier];
if (!touchInfo)
continue;
var element = touchInfo.element;
var camera = touchInfo.camera;
var x = touchInfo.x;
var y = touchInfo.y;
delete this._touchedElements[touch.identifier];
delete this._touchesForWhichTouchLeaveHasFired[touch.identifier];
this._fireEvent(event.type, new ElementTouchEvent(event, element, camera, x, y, this));
// check if touch was released over previously touch
// element in order to fire click event
if (event.touches.length === 0) {
var coords = this._calcTouchCoords(touch);
for (var c = cameras.length - 1; c >= 0; c--) {
var hovered = this._getTargetElement(cameras[c], coords.x, coords.y);
if (hovered === element) {
if (!this._clickedEntities[element.entity.getGuid()]) {
this._fireEvent('click', new ElementTouchEvent(event, element, camera, x, y, this));
this._clickedEntities[element.entity.getGuid()] = true;
}
}
}
}
}
},
_handleTouchMove: function (event) {
// call preventDefault to avoid issues in Chrome Android:
// http://wilsonpage.co.uk/touch-events-in-chrome-android/
event.preventDefault();
if (!this._enabled) return;
var newTouchedElements = this._determineTouchedElements(event);
for (var i = 0, len = event.changedTouches.length; i < len; i++) {
var touch = event.changedTouches[i];
var newTouchInfo = newTouchedElements[touch.identifier];
var oldTouchInfo = this._touchedElements[touch.identifier];
if (oldTouchInfo) {
var coords = this._calcTouchCoords(touch);
// Fire touchleave if we've left the previously touched element
if ((!newTouchInfo || newTouchInfo.element !== oldTouchInfo.element) && !this._touchesForWhichTouchLeaveHasFired[touch.identifier]) {
this._fireEvent('touchleave', new ElementTouchEvent(event, oldTouchInfo.element, oldTouchInfo.camera, coords.x, coords.y, this));
// Flag that touchleave has been fired for this touch, so that we don't
// re-fire it on the next touchmove. This is required because touchmove
// events keep on firing for the same element until the touch ends, even
// if the touch position moves away from the element. Touchleave, on the
// other hand, should fire once when the touch position moves away from
// the element and then not re-fire again within the same touch session.
this._touchesForWhichTouchLeaveHasFired[touch.identifier] = true;
}
this._fireEvent('touchmove', new ElementTouchEvent(event, oldTouchInfo.element, oldTouchInfo.camera, coords.x, coords.y, this));
}
}
},
_onElementMouseEvent: function (event) {
var element;
var hovered = this._hoveredElement;
this._hoveredElement = null;
var cameras = this.app.systems.camera.cameras;
var camera;
// check cameras from last to front
// so that elements that are drawn above others
// receive events first
for (var i = cameras.length - 1; i >= 0; i--) {
camera = cameras[i];
element = this._getTargetElement(camera, targetX, targetY);
if (element)
break;
}
// fire mouse event
if (element) {
this._fireEvent(event.type, new ElementMouseEvent(event, element, camera, targetX, targetY, this._lastX, this._lastY));
this._hoveredElement = element;
if (event.type === pc.EVENT_MOUSEDOWN) {
this._pressedElement = element;
}
}
if (hovered !== this._hoveredElement) {
// mouseleave event
if (hovered) {
this._fireEvent('mouseleave', new ElementMouseEvent(event, hovered, camera, targetX, targetY, this._lastX, this._lastY));
}
// mouseenter event
if (this._hoveredElement) {
this._fireEvent('mouseenter', new ElementMouseEvent(event, this._hoveredElement, camera, targetX, targetY, this._lastX, this._lastY));
}
}
if (event.type === pc.EVENT_MOUSEUP && this._pressedElement) {
// click event
if (this._pressedElement === this._hoveredElement) {
this._pressedElement = null;
// fire click event if it hasn't been fired already by the touchup handler
if (!this._clickedEntities || !this._clickedEntities[this._hoveredElement.entity.getGuid()]) {
this._fireEvent('click', new ElementMouseEvent(event, this._hoveredElement, camera, targetX, targetY, this._lastX, this._lastY));
}
} else {
this._pressedElement = null;
}
}
},
_fireEvent: function (name, evt) {
var element = evt.element;
while (true) {
element.fire(name, evt);
if (evt._stopPropagation)
break;
if (!element.entity.parent)
break;
element = element.entity.parent.element;
if (!element)
break;
}
},
_calcMouseCoords: function (event) {
var rect = this._target.getBoundingClientRect();
var left = Math.floor(rect.left);
var top = Math.floor(rect.top);
// mouse is outside of canvas
if (event.clientX < left ||
event.clientX >= left + this._target.clientWidth ||
event.clientY < top ||
event.clientY >= top + this._target.clientHeight) {
targetX = null;
targetY = null;
} else {
// calculate coords and scale them to the graphicsDevice size
targetX = (event.clientX - left);
targetY = (event.clientY - top);
}
},
_calcTouchCoords: function (touch) {
var totalOffsetX = 0;
var totalOffsetY = 0;
var target = touch.target;
while (!(target instanceof HTMLElement)) {
target = target.parentNode;
}
var currentElement = target;
do {
totalOffsetX += currentElement.offsetLeft - currentElement.scrollLeft;
totalOffsetY += currentElement.offsetTop - currentElement.scrollTop;
currentElement = currentElement.offsetParent;
} while (currentElement);
// calculate coords and scale them to the graphicsDevice size
return {
x: (touch.pageX - totalOffsetX),
y: (touch.pageY - totalOffsetY)
};
},
_sortElements: function (a, b) {
var layerOrder = this.app.scene.layers.sortTransparentLayers(a.layers, b.layers);
if (layerOrder !== 0) return layerOrder;
if (a.screen && !b.screen)
return -1;
if (!a.screen && b.screen)
return 1;
if (!a.screen && !b.screen)
return 0;
if (a.screen.screen.screenSpace && !b.screen.screen.screenSpace)
return -1;
if (b.screen.screen.screenSpace && !a.screen.screen.screenSpace)
return 1;
return b.drawOrder - a.drawOrder;
},
_getTargetElement: function (camera, x, y) {
var result = null;
// sort elements
this._elements.sort(this._sortHandler);
for (var i = 0, len = this._elements.length; i < len; i++) {
var element = this._elements[i];
// scale x, y based on the camera's rect
if (element.screen && element.screen.screen.screenSpace) {
// 2D screen
if (this._checkElement2d(x, y, element, camera)) {
result = element;
break;
}
} else {
// 3d
if (this._checkElement3d(x, y, element, camera)) {
result = element;
break;
}
}
}
return result;
},
// In most cases the corners used for hit testing will just be the element's
// screen corners. However, in cases where the element has additional hit
// padding specified, we need to expand the screenCorners to incorporate the
// padding.
_buildHitCorners: function (element, screenOrWorldCorners, scaleX, scaleY) {
var hitCorners = screenOrWorldCorners;
var button = element.entity && element.entity.button;
if (button) {
var hitPadding = element.entity.button.hitPadding || ZERO_VEC4;
_paddingTop.copy(element.entity.up);
_paddingBottom.copy(_paddingTop).scale(-1);
_paddingRight.copy(element.entity.right);
_paddingLeft.copy(_paddingRight).scale(-1);
_paddingTop.scale(hitPadding.w * scaleY);
_paddingBottom.scale(hitPadding.y * scaleY);
_paddingRight.scale(hitPadding.z * scaleX);
_paddingLeft.scale(hitPadding.x * scaleX);
_cornerBottomLeft.copy(hitCorners[0]).add(_paddingBottom).add(_paddingLeft);
_cornerBottomRight.copy(hitCorners[1]).add(_paddingBottom).add(_paddingRight);
_cornerTopRight.copy(hitCorners[2]).add(_paddingTop).add(_paddingRight);
_cornerTopLeft.copy(hitCorners[3]).add(_paddingTop).add(_paddingLeft);
hitCorners = [_cornerBottomLeft, _cornerBottomRight, _cornerTopRight, _cornerTopLeft];
}
return hitCorners;
},
_calculateScaleToScreen: function (element) {
var current = element.entity;
var screenScale = element.screen.screen.scale;
_accumulatedScale.set(screenScale, screenScale);
while (current && !current.screen) {
_accumulatedScale.mul(current.getLocalScale());
current = current.parent;
}
return _accumulatedScale;
},
_checkElement2d: function (x, y, element, camera) {
// ensure click is contained by any mask first
if (element.maskedBy) {
var result = this._checkElement2d(x, y, element.maskedBy.element, camera);
if (!result) return false;
}
var sw = this.app.graphicsDevice.width;
var sh = this.app.graphicsDevice.height;
var cameraWidth = camera.rect.z * sw;
var cameraHeight = camera.rect.w * sh;
var cameraLeft = camera.rect.x * sw;
var cameraRight = cameraLeft + cameraWidth;
// camera bottom (origin is bottom left of window)
var cameraBottom = (1 - camera.rect.y) * sh;
var cameraTop = cameraBottom - cameraHeight;
var _x = x * sw / this._target.clientWidth;
var _y = y * sh / this._target.clientHeight;
// check window coords are within camera rect
if (_x >= cameraLeft && _x <= cameraRight &&
_y <= cameraBottom && _y >= cameraTop) {
// limit window coords to camera rect coords
_x = sw * (_x - cameraLeft) / cameraWidth;
_y = sh * (_y - cameraTop) / cameraHeight;
// reverse _y
_y = sh - _y;
var scale = this._calculateScaleToScreen(element);
var hitCorners = this._buildHitCorners(element, element.screenCorners, scale.x, scale.y);
vecA.set(_x, _y, 1);
vecB.set(_x, _y, -1);
if (intersectLineQuad(vecA, vecB, hitCorners)) {
return true;
}
}
return false;
},
_checkElement3d: function (x, y, element, camera) {
// ensure click is contained by any mask first
if (element.maskedBy) {
var result = this._checkElement3d(x, y, element.maskedBy.element, camera);
if (!result) return false;
}
var sw = this._target.clientWidth;
var sh = this._target.clientHeight;
var cameraWidth = camera.rect.z * sw;
var cameraHeight = camera.rect.w * sh;
var cameraLeft = camera.rect.x * sw;
var cameraRight = cameraLeft + cameraWidth;
// camera bottom - origin is bottom left of window
var cameraBottom = (1 - camera.rect.y) * sh;
var cameraTop = cameraBottom - cameraHeight;
var _x = x;
var _y = y;
// check window coords are within camera rect
if (x >= cameraLeft && x <= cameraRight &&
y <= cameraBottom && _y >= cameraTop) {
// limit window coords to camera rect coords
_x = sw * (_x - cameraLeft) / cameraWidth;
_y = sh * (_y - (cameraTop)) / cameraHeight;
// 3D screen
var scale = element.entity.getWorldTransform().getScale();
var worldCorners = this._buildHitCorners(element, element.worldCorners, scale.x, scale.y);
var start = vecA;
var end = vecB;
camera.screenToWorld(_x, _y, camera.nearClip, start);
camera.screenToWorld(_x, _y, camera.farClip, end);
if (intersectLineQuad(start, end, worldCorners)) {
return true;
}
}
return false;
}
});
Object.defineProperty(ElementInput.prototype, 'enabled', {
get: function () {
return this._enabled;
},
set: function (value) {
this._enabled = value;
}
});
Object.defineProperty(ElementInput.prototype, 'app', {
get: function () {
return this._app || pc.app;
},
set: function (value) {
this._app = value;
}
});
return {
ElementInput: ElementInput,
ElementInputEvent: ElementInputEvent,
ElementMouseEvent: ElementMouseEvent,
ElementTouchEvent: ElementTouchEvent
};
}());