UNPKG

react-xrplayer

Version:

An excellent xr player for react

237 lines (178 loc) 8.27 kB
"use strict"; function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var THREE = _interopRequireWildcard(require("three")); function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function _getRequireWildcardCache() { return cache; }; return cache; } function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } var StereoEffect = function StereoEffect(renderer) { var _this = this; _classCallCheck(this, StereoEffect); _defineProperty(this, "setEyeSeparation", function (eyeSep) { _this.stereoCamera.eyeSep = eyeSep; }); _defineProperty(this, "setSize", function (width, height) { _this.renderer.setSize(width, height); }); _defineProperty(this, "render", function (scene, camera) { scene.updateMatrixWorld(); var size = _this.size; if (camera.parent === null) camera.updateMatrixWorld(); _this.stereoCamera.update(camera); _this.renderer.getSize(_this.size); if (_this.renderer.autoClear) _this.renderer.clear(); _this.renderer.setScissorTest(true); _this.renderer.setScissor(0, 0, size.width / 2, size.height); _this.renderer.setViewport(0, 0, size.width / 2, size.height); _this.renderer.render(scene, _this.stereoCamera.cameraL); _this.renderer.setScissor(size.width / 2, 0, size.width / 2, size.height); _this.renderer.setViewport(size.width / 2, 0, size.width / 2, size.height); _this.renderer.render(scene, _this.stereoCamera.cameraR); _this.renderer.setScissorTest(false); }); this.renderer = renderer; this.stereoCamera = new THREE.StereoCamera(); this.stereoCamera.aspect = 0.5; this.size = new THREE.Vector2(); }; var VRHelper = function VRHelper(renderer, _camera) { var _this2 = this; _classCallCheck(this, VRHelper); _defineProperty(this, "setSize", function (width, height) { _this2.effect && _this2.effect.setSize(width, height); }); _defineProperty(this, "initCursor", function () { var cursorColors = new Uint8Array([64, 64, 64, 64, // dark gray 255, 255, 255, 255 // white ]); _this2.cursorTexture = _this2.makeDataTexture(cursorColors, 2, 1); var cursorGeometry = new THREE.TorusBufferGeometry(1, 0.1, 4, 64); var cursorMaterial = new THREE.MeshBasicMaterial({ color: 'white', map: _this2.cursorTexture, transparent: true, depthTest: false, blending: THREE.CustomBlending, blendSrc: THREE.OneMinusDstColorFactor, blendDst: THREE.OneMinusSrcColorFactor }); var cursor = new THREE.Mesh(cursorGeometry, cursorMaterial); _this2.camera.add(cursor); cursor.position.z = -500; var scale = 25; cursor.scale.set(scale, scale, scale); _this2.cursor = cursor; cursor.visible = false; }); _defineProperty(this, "makeDataTexture", function (data, width, height) { var texture = new THREE.DataTexture(data, width, height, THREE.RGBAFormat); texture.minFilter = THREE.NearestFilter; texture.magFilter = THREE.NearestFilter; texture.needsUpdate = true; return texture; }); _defineProperty(this, "initCone", function () { var coneGeometry = new THREE.ConeGeometry(0.8, 1.2, 3, 1); var coneMaterial = new THREE.MeshBasicMaterial({ color: 'white', transparent: true, depthTest: false, wireframe: true }); var cone = new THREE.Mesh(coneGeometry, coneMaterial); _this2.cone = cone; cone.position.z = -500; var scale = 25; cone.scale.set(scale, scale, scale); cone.rotation.x = Math.PI / 2; _this2.camera.add(cone); cone.visible = false; }); _defineProperty(this, "pick", function (normalizedPosition, camera, time, objects) { if (!!!objects || _this2.vrStatus === false) { _this2.pickedObject = undefined; return undefined; } var elapsedTime = time - _this2.lastTime; _this2.lastTime = time; var lastPickedObject = _this2.pickedObject; // restore the color if there is a picked object if (_this2.pickedObject) { _this2.pickedObject = undefined; } // cast a ray through the frustum _this2.raycaster.setFromCamera(normalizedPosition, camera); // get the list of objects the ray intersected var intersectedObjects = _this2.raycaster.intersectObjects(objects); if (intersectedObjects.length) { // pick the first object. It's the closest one _this2.pickedObject = intersectedObjects[0].object; } // show or hide cursor _this2.cursor.visible = !!_this2.pickedObject; var selected = false; // if we're looking at the same object as before // increment time select timer if (_this2.pickedObject && lastPickedObject === _this2.pickedObject) { _this2.selectTimer += elapsedTime; if (_this2.selectTimer >= _this2.selectDuration) { _this2.selectTimer = 0; selected = true; } } else { _this2.selectTimer = 0; } // set cursor material to show the timer state var fromStart = 0; var fromEnd = _this2.selectDuration; var toStart = -0.5; var toEnd = 0.5; _this2.cursorTexture.offset.x = THREE.MathUtils.mapLinear(_this2.selectTimer, fromStart, fromEnd, toStart, toEnd); return selected ? _this2.pickedObject : undefined; }); _defineProperty(this, "setObjectInteractionHandler", function (callback) { _this2.onObjectInteractionHandler = callback; }); _defineProperty(this, "updateInteractionObjects", function (objs, time) { _this2.objects = objs; _this2.time = time; }); _defineProperty(this, "render", function (scene, camera) { if (_this2.vrStatus) { _this2.effect.render(scene, camera); var pickedObject = _this2.pick({ x: 0, y: 0 }, camera, _this2.time, Array.from(_this2.objects)); if (!!pickedObject) { _this2.onObjectInteractionHandler && _this2.onObjectInteractionHandler(pickedObject); } } }); _defineProperty(this, "enable", function () { _this2.vrStatus = true; _this2.cursor.visible = true; _this2.cone.visible = true; }); _defineProperty(this, "disable", function () { _this2.vrStatus = false; _this2.cursor.visible = false; _this2.cone.visible = false; }); this.renderer = renderer; this.camera = _camera; this.effect = new StereoEffect(renderer); this.vrStatus = false; this.cursor = null; this.cone = null; this.raycaster = new THREE.Raycaster(); this.pickedObject = null; this.initCursor(); this.initCone(); this.selectTimer = 0; this.selectDuration = 2; this.lastTime = 0; this.objects = []; // 可交互object this.time = 0; // 热点触发计时器 this.onObjectInteractionHandler = null; }; var _default = VRHelper; exports.default = _default;