/** * Generated by Verge3D Puzzles v.4.1.1 * Tue, 01 Nov 2022 06:09:12 GMT * Prefer not editing this file as your changes may get overridden once Puzzles are saved. * Check out https://www.soft8soft.com/docs/manual/en/introduction/Using-JavaScript.html * for the information on how to add your own JavaScript to Verge3D apps. */ 'use strict'; (function() { // global variables/constants used by puzzles' functions var LIST_NONE = ''; var _pGlob = {}; _pGlob.objCache = {}; _pGlob.fadeAnnotations = true; _pGlob.pickedObject = ''; _pGlob.hoveredObject = ''; _pGlob.mediaElements = {}; _pGlob.loadedFile = ''; _pGlob.states = []; _pGlob.percentage = 0; _pGlob.openedFile = ''; _pGlob.openedFileMeta = {}; _pGlob.xrSessionAcquired = false; _pGlob.xrSessionCallbacks = []; _pGlob.screenCoords = new v3d.Vector2(); _pGlob.intervalTimers = {}; _pGlob.customEvents = new v3d.EventDispatcher(); _pGlob.AXIS_X = new v3d.Vector3(1, 0, 0); _pGlob.AXIS_Y = new v3d.Vector3(0, 1, 0); _pGlob.AXIS_Z = new v3d.Vector3(0, 0, 1); _pGlob.MIN_DRAG_SCALE = 10e-4; _pGlob.SET_OBJ_ROT_EPS = 1e-8; _pGlob.vec2Tmp = new v3d.Vector2(); _pGlob.vec2Tmp2 = new v3d.Vector2(); _pGlob.vec3Tmp = new v3d.Vector3(); _pGlob.vec3Tmp2 = new v3d.Vector3(); _pGlob.vec3Tmp3 = new v3d.Vector3(); _pGlob.vec3Tmp4 = new v3d.Vector3(); _pGlob.eulerTmp = new v3d.Euler(); _pGlob.eulerTmp2 = new v3d.Euler(); _pGlob.quatTmp = new v3d.Quaternion(); _pGlob.quatTmp2 = new v3d.Quaternion(); _pGlob.colorTmp = new v3d.Color(); _pGlob.mat4Tmp = new v3d.Matrix4(); _pGlob.planeTmp = new v3d.Plane(); _pGlob.raycasterTmp = new v3d.Raycaster(); var PL = v3d.PL = v3d.PL || {}; // a more readable alias for PL (stands for "Puzzle Logic") v3d.puzzles = PL; PL.procedures = PL.procedures || {}; PL.execInitPuzzles = function(options) { // always null, should not be available in "init" puzzles var appInstance = null; // app is more conventional than appInstance (used in exec script and app templates) var app = null; var _initGlob = {}; _initGlob.percentage = 0; _initGlob.output = { initOptions: { fadeAnnotations: true, useBkgTransp: false, preserveDrawBuf: false, useCompAssets: false, useFullscreen: true, useCustomPreloader: false, preloaderStartCb: function() {}, preloaderProgressCb: function() {}, preloaderEndCb: function() {}, } } // provide the container's id to puzzles that need access to the container _initGlob.container = options !== undefined && 'container' in options ? options.container : ""; // initSettings puzzle _initGlob.output.initOptions.fadeAnnotations = true; _initGlob.output.initOptions.useBkgTransp = true; _initGlob.output.initOptions.preserveDrawBuf = false; _initGlob.output.initOptions.useCompAssets = false; _initGlob.output.initOptions.useFullscreen = true; return _initGlob.output; } PL.init = function(appInstance, initOptions) { // app is more conventional than appInstance (used in exec script and app templates) var app = appInstance; initOptions = initOptions || {}; if ('fadeAnnotations' in initOptions) { _pGlob.fadeAnnotations = initOptions.fadeAnnotations; } this.procedures["EquipmentClick"] = EquipmentClick; var Cliclk, flag, Logo, modetype; // utility function envoked by almost all V3D-specific puzzles // filter off some non-mesh types function notIgnoredObj(obj) { return obj.type !== 'AmbientLight' && obj.name !== '' && !(obj.isMesh && obj.isMaterialGeneratedMesh) && !obj.isAuxClippingMesh; } // utility function envoked by almost all V3D-specific puzzles // find first occurence of the object by its name function getObjectByName(objName) { var objFound; var runTime = _pGlob !== undefined; objFound = runTime ? _pGlob.objCache[objName] : null; if (objFound && objFound.name === objName) return objFound; if (appInstance.scene) { appInstance.scene.traverse(function(obj) { if (!objFound && notIgnoredObj(obj) && (obj.name == objName)) { objFound = obj; if (runTime) { _pGlob.objCache[objName] = objFound; } } }); } return objFound; } // utility function envoked by almost all V3D-specific puzzles // retrieve all objects on the scene function getAllObjectNames() { var objNameList = []; appInstance.scene.traverse(function(obj) { if (notIgnoredObj(obj)) objNameList.push(obj.name) }); return objNameList; } // utility function envoked by almost all V3D-specific puzzles // retrieve all objects which belong to the group function getObjectNamesByGroupName(targetGroupName) { var objNameList = []; appInstance.scene.traverse(function(obj){ if (notIgnoredObj(obj)) { var groupNames = obj.groupNames; if (!groupNames) return; for (var i = 0; i < groupNames.length; i++) { var groupName = groupNames[i]; if (groupName == targetGroupName) { objNameList.push(obj.name); } } } }); return objNameList; } // utility function envoked by almost all V3D-specific puzzles // process object input, which can be either single obj or array of objects, or a group function retrieveObjectNames(objNames) { var acc = []; retrieveObjectNamesAcc(objNames, acc); return acc.filter(function(name) { return name; }); } function retrieveObjectNamesAcc(currObjNames, acc) { if (typeof currObjNames == "string") { acc.push(currObjNames); } else if (Array.isArray(currObjNames) && currObjNames[0] == "GROUP") { var newObj = getObjectNamesByGroupName(currObjNames[1]); for (var i = 0; i < newObj.length; i++) acc.push(newObj[i]); } else if (Array.isArray(currObjNames) && currObjNames[0] == "ALL_OBJECTS") { var newObj = getAllObjectNames(); for (var i = 0; i < newObj.length; i++) acc.push(newObj[i]); } else if (Array.isArray(currObjNames)) { for (var i = 0; i < currObjNames.length; i++) retrieveObjectNamesAcc(currObjNames[i], acc); } } // updateTextObject puzzle function updateTextObj(objSelector, text) { var objNames = retrieveObjectNames(objSelector); for (var i = 0; i < objNames.length; i++) { var objName = objNames[i]; if (!objName) continue; var obj = getObjectByName(objName); if (!obj || !obj.geometry || !obj.geometry.cloneWithText) continue; obj.geometry = obj.geometry.cloneWithText(String(text)); } } // setActiveCamera puzzle function setActiveCamera(camName) { var camera = getObjectByName(camName); if (!camera || !camera.isCamera || appInstance.getCamera() == camera) return; appInstance.setCamera(camera); } // setCameraParam puzzle function setCameraParam(type, objSelector, param) { var objNames = retrieveObjectNames(objSelector); objNames.forEach(function(objName) { if (!objName) return; var obj = getObjectByName(objName); if (!obj || !obj.isCamera) return; if (!(obj.isPerspectiveCamera || obj.isOrthographicCamera)) { console.error('setCameraParam: Incompatible camera type, have to be perspective or orthographic'); return; } let isSetOrbitParam = false; switch (type) { case 'ORBIT_MIN_DISTANCE_PERSP': case 'ORBIT_MAX_DISTANCE_PERSP': case 'ORBIT_MIN_ZOOM_ORTHO': case 'ORBIT_MAX_ZOOM_ORTHO': case 'ORBIT_MIN_VERTICAL_ANGLE': case 'ORBIT_MAX_VERTICAL_ANGLE': case 'ORBIT_MIN_HORIZONTAL_ANGLE': case 'ORBIT_MAX_HORIZONTAL_ANGLE': case 'ORBIT_ALLOW_TURNOVER': isSetOrbitParam = true; break; } let isSetControlsParam = (['ROTATION_SPEED', 'MOVEMENT_SPEED', 'ALLOW_PANNING', 'ALLOW_ZOOM', 'KEYBOARD_CONTROLS'].includes(type) || isSetOrbitParam); if (isSetControlsParam) { if (!obj.controls) { console.error('setCameraParam: The "' + objName +'" camera has no controller'); return; } else if (isSetOrbitParam && obj.controls.type != 'ORBIT') { console.error('setCameraParam: Incompatible camera controller'); return; } } switch (type) { case 'FIELD_OF_VIEW': if (obj.isPerspectiveCamera) { obj.fov = param; obj.updateProjectionMatrix(); } else { console.error('setCameraParam: Incompatible camera type, have to be perspective'); return; } break; case 'ORTHO_SCALE': if (obj.isOrthographicCamera) { obj.zoom = param; obj.updateProjectionMatrix(); } else { console.error('setCameraParam: Incompatible camera type, have to be orthographic'); return; } break; case 'ROTATION_SPEED': obj.controls.rotateSpeed = param; break; case 'MOVEMENT_SPEED': obj.controls.moveSpeed = param; break; case 'ALLOW_PANNING': obj.controls.enablePan = param; break; case 'ALLOW_ZOOM': obj.controls.enableZoom = param; break; case 'KEYBOARD_CONTROLS': obj.controls.enableKeys = param; break; case 'ORBIT_MIN_DISTANCE_PERSP': if (obj.isPerspectiveCamera) { obj.controls.orbitMinDistance = param; } else { console.error('setCameraParam: Incompatible camera type, have to be perspective'); return; } break; case 'ORBIT_MAX_DISTANCE_PERSP': if (obj.isPerspectiveCamera) { obj.controls.orbitMaxDistance = param; } else { console.error('setCameraParam: Incompatible camera type, have to be perspective'); return; } break; case 'ORBIT_MIN_ZOOM_ORTHO': if (obj.isOrthographicCamera) { obj.controls.orbitMinZoom = param; } else { console.error('setCameraParam: Incompatible camera type, have to be orthographic'); return; } break; case 'ORBIT_MAX_ZOOM_ORTHO': if (obj.isOrthographicCamera) { obj.controls.orbitMaxZoom = param; } else { console.error('setCameraParam: Incompatible camera type, have to be orthographic'); return; } break; case 'ORBIT_MIN_VERTICAL_ANGLE': obj.controls.orbitMinPolarAngle = v3d.MathUtils.degToRad(param); break; case 'ORBIT_MAX_VERTICAL_ANGLE': obj.controls.orbitMaxPolarAngle = v3d.MathUtils.degToRad(param); break; case 'ORBIT_MIN_HORIZONTAL_ANGLE': obj.controls.orbitMinAzimuthAngle = v3d.MathUtils.degToRad(param); break; case 'ORBIT_MAX_HORIZONTAL_ANGLE': obj.controls.orbitMaxAzimuthAngle = v3d.MathUtils.degToRad(param); break; case 'ORBIT_ALLOW_TURNOVER': obj.controls.orbitEnableTurnover = param; break; case 'CLIP_START': obj.near = param; obj.updateProjectionMatrix(); break; case 'CLIP_END': obj.far = param; obj.updateProjectionMatrix(); break; } if (isSetControlsParam) appInstance.enableControls(); }); } /** * mesh or multi-material object */ function isMeshObj(obj) { if (obj.isMesh) return true; for (var i = 0; i < obj.children.length; i++) { var child = obj.children[i]; if (child.isMesh && child.isMaterialGeneratedMesh) return true; } return false; } function getObjectsFromCollect(obj, type, out) { if (!notIgnoredObj(obj)) return; switch (type) { case 'ALL': if (out.indexOf(obj.name) < 0) out.push(obj.name); break; case 'ANNOTATION': if (obj.isAnnotation && out.indexOf(obj.name) < 0) out.push(obj.name); break; case 'BONE': if (obj.isBone && out.indexOf(obj.name) < 0) out.push(obj.name); break; case 'CAMERA': if (obj.isCamera && out.indexOf(obj.name) < 0) out.push(obj.name); break; case 'EMPTY': if (!obj.isAnnotationControl && !obj.isBone && !obj.isCamera && !obj.isGroup && !obj.isLine && !obj.isLOD && !obj.isLight && !isMeshObj(obj) && !obj.isPoints && !obj.isScene && !obj.isSprite && out.indexOf(obj.name) < 0) out.push(obj.name); break; case 'LIGHT': if (obj.isLight && out.indexOf(obj.name) < 0) out.push(obj.name); break; case 'MESH': if (isMeshObj(obj) && out.indexOf(obj.name) < 0) out.push(obj.name); break; default: console.error('getObjectsFrom: Unknown object type: ' + type); break; } for (var i = 0; i < obj.children.length; i++) { var child = obj.children[i]; getObjectsFromCollect(child, type, out); } } // getObjectsFrom puzzle function getObjectsFrom(objSelector, type) { var out = []; var objNames = retrieveObjectNames(objSelector); for (var i = 0; i < objNames.length; i++) { var objName = objNames[i] if (!objName) continue; var obj = getObjectByName(objName); if (!obj) continue; getObjectsFromCollect(obj, type, out); } return out; } // show and hide puzzles function changeVis(objSelector, bool) { var objNames = retrieveObjectNames(objSelector); for (var i = 0; i < objNames.length; i++) { var objName = objNames[i] if (!objName) continue; var obj = getObjectByName(objName); if (!obj) continue; obj.visible = bool; obj.resolveMultiMaterial().forEach(function(objR) { objR.visible = bool; }); } } // utility functions envoked by the HTML puzzles function getElements(ids, isParent) { var elems = []; if (Array.isArray(ids) && ids[0] != 'CONTAINER' && ids[0] != 'WINDOW' && ids[0] != 'DOCUMENT' && ids[0] != 'BODY' && ids[0] != 'QUERYSELECTOR') { for (var i = 0; i < ids.length; i++) elems.push(getElement(ids[i], isParent)); } else { elems.push(getElement(ids, isParent)); } return elems; } function getElement(id, isParent) { var elem; if (Array.isArray(id) && id[0] == 'CONTAINER') { if (appInstance !== null) { elem = appInstance.container; } else if (typeof _initGlob !== 'undefined') { // if we are on the initialization stage, we still can have access // to the container element var id = _initGlob.container; if (isParent) { elem = parent.document.getElementById(id); } else { elem = document.getElementById(id); } } } else if (Array.isArray(id) && id[0] == 'WINDOW') { if (isParent) elem = parent; else elem = window; } else if (Array.isArray(id) && id[0] == 'DOCUMENT') { if (isParent) elem = parent.document; else elem = document; } else if (Array.isArray(id) && id[0] == 'BODY') { if (isParent) elem = parent.document.body; else elem = document.body; } else if (Array.isArray(id) && id[0] == 'QUERYSELECTOR') { if (isParent) elem = parent.document.querySelector(id); else elem = document.querySelector(id); } else { if (isParent) elem = parent.document.getElementById(id); else elem = document.getElementById(id); } return elem; } // setHTMLElemAttribute puzzle function setHTMLElemAttribute(attr, value, ids, isParent) { var elems = getElements(ids, isParent); for (var i = 0; i < elems.length; i++) { var elem = elems[i]; if (!elem) continue; if ((attr == 'href' || attr == 'src') && value instanceof Promise) { // resolve promise value for url-based attributes value.then(function(response) { elem[attr] = response; }); } else { elem[attr] = value; } } } // getEntityByName puzzle function getEntityByName(name, getWhat) { switch (getWhat) { case 'OBJECT': case 'ANIMATION': case 'MATERIAL': return name; case 'GROUP': return ['GROUP', name]; } } // Describe this function... function EquipmentClick(Cliclk) { flag = !flag; if (flag) { setHTMLElemAttribute('rel', _pGlob.hoveredObject, 'V3DData', true); changeVis(getEntityByName(String(_pGlob.hoveredObject) + '-Text', 'OBJECT'), true); changeVis(getEntityByName(String(_pGlob.hoveredObject) + '-Num', 'OBJECT'), true); } else { setHTMLElemAttribute('rel', _pGlob.hoveredObject, 'V3DData', true); changeVis(getEntityByName(String(_pGlob.hoveredObject) + '-Text', 'OBJECT'), false); changeVis(getEntityByName(String(_pGlob.hoveredObject) + '-Num', 'OBJECT'), false); } } // outline puzzle function outline(objSelector, doWhat) { var objNames = retrieveObjectNames(objSelector); if (!appInstance.postprocessing || !appInstance.postprocessing.outlinePass) return; var outlineArray = appInstance.postprocessing.outlinePass.selectedObjects; for (var i = 0; i < objNames.length; i++) { var objName = objNames[i]; var obj = getObjectByName(objName); if (!obj) continue; if (doWhat == "ENABLE") { if (outlineArray.indexOf(obj) == -1) outlineArray.push(obj); } else { var index = outlineArray.indexOf(obj); if (index > -1) outlineArray.splice(index, 1); } } } // utility function used by the whenClicked, whenHovered and whenDraggedOver puzzles function initObjectPicking(callback, eventType, mouseDownUseTouchStart, mouseButtons) { var elem = appInstance.renderer.domElement; elem.addEventListener(eventType, pickListener); if (v3d.PL.editorEventListeners) v3d.PL.editorEventListeners.push([elem, eventType, pickListener]); if (eventType == 'mousedown') { var touchEventName = mouseDownUseTouchStart ? 'touchstart' : 'touchend'; elem.addEventListener(touchEventName, pickListener); if (v3d.PL.editorEventListeners) v3d.PL.editorEventListeners.push([elem, touchEventName, pickListener]); } else if (eventType == 'dblclick') { var prevTapTime = 0; function doubleTapCallback(event) { var now = new Date().getTime(); var timesince = now - prevTapTime; if (timesince < 600 && timesince > 0) { pickListener(event); prevTapTime = 0; return; } prevTapTime = new Date().getTime(); } var touchEventName = mouseDownUseTouchStart ? 'touchstart' : 'touchend'; elem.addEventListener(touchEventName, doubleTapCallback); if (v3d.PL.editorEventListeners) v3d.PL.editorEventListeners.push([elem, touchEventName, doubleTapCallback]); } var raycaster = new v3d.Raycaster(); function pickListener(event) { // to handle unload in loadScene puzzle if (!appInstance.getCamera()) return; event.preventDefault(); var xNorm = 0, yNorm = 0; if (event instanceof MouseEvent) { if (mouseButtons && mouseButtons.indexOf(event.button) == -1) return; xNorm = event.offsetX / elem.clientWidth; yNorm = event.offsetY / elem.clientHeight; } else if (event instanceof TouchEvent) { var rect = elem.getBoundingClientRect(); xNorm = (event.changedTouches[0].clientX - rect.left) / rect.width; yNorm = (event.changedTouches[0].clientY - rect.top) / rect.height; } _pGlob.screenCoords.x = xNorm * 2 - 1; _pGlob.screenCoords.y = -yNorm * 2 + 1; raycaster.setFromCamera(_pGlob.screenCoords, appInstance.getCamera(true)); var objList = []; appInstance.scene.traverse(function(obj){objList.push(obj);}); var intersects = raycaster.intersectObjects(objList, false); callback(intersects, event); } } function objectsIncludeObj(objNames, testedObjName) { if (!testedObjName) return false; for (var i = 0; i < objNames.length; i++) { if (testedObjName == objNames[i]) { return true; } else { // also check children which are auto-generated for multi-material objects var obj = getObjectByName(objNames[i]); if (obj && obj.type == "Group") { for (var j = 0; j < obj.children.length; j++) { if (testedObjName == obj.children[j].name) { return true; } } } } } return false; } // utility function used by the whenClicked, whenHovered, whenDraggedOver, and raycast puzzles function getPickedObjectName(obj) { // auto-generated from a multi-material object, use parent name instead if (obj.isMesh && obj.isMaterialGeneratedMesh && obj.parent) { return obj.parent.name; } else { return obj.name; } } // whenHovered puzzle initObjectPicking(function(intersects, event) { var prevHovered = _pGlob.hoveredObject; var currHovered = ''; // the event might happen before hover registration _pGlob.objHoverInfo = _pGlob.objHoverInfo || []; // search for closest hovered object var lastIntersectIndex = Infinity; _pGlob.objHoverInfo.forEach(function(el) { var maxIntersects = el.xRay ? intersects.length : Math.min(1, intersects.length); for (var i = 0; i < maxIntersects; i++) { var obj = intersects[i].object; var objName = getPickedObjectName(obj); if (objectsIncludeObj(retrieveObjectNames(el.objSelector), objName) && i <= lastIntersectIndex) { currHovered = objName; lastIntersectIndex = i; } } }); if (prevHovered == currHovered) return; // first - all "out" callbacks, then - all "over" _pGlob.objHoverInfo.forEach(function(el) { if (objectsIncludeObj(retrieveObjectNames(el.objSelector), prevHovered)) { // ensure the correct value of the hoveredObject block _pGlob.hoveredObject = prevHovered; el.callbacks[1](event); } }); _pGlob.objHoverInfo.forEach(function(el) { if (objectsIncludeObj(retrieveObjectNames(el.objSelector), currHovered)) { // ensure the correct value of the hoveredObject block _pGlob.hoveredObject = currHovered; el.callbacks[0](event); } }); _pGlob.hoveredObject = currHovered; }, 'mousemove', false); // whenHovered puzzle function registerOnHover(objSelector, xRay, cbOver, cbOut) { _pGlob.objHoverInfo = _pGlob.objHoverInfo || []; _pGlob.objHoverInfo.push({ objSelector: objSelector, callbacks: [cbOver, cbOut], xRay: xRay }); } // whenClicked puzzle function registerOnClick(objSelector, xRay, doubleClick, mouseButtons, cbDo, cbIfMissedDo) { // for AR/VR _pGlob.objClickInfo = _pGlob.objClickInfo || []; _pGlob.objClickInfo.push({ objSelector: objSelector, callbacks: [cbDo, cbIfMissedDo] }); initObjectPicking(function(intersects, event) { var isPicked = false; var maxIntersects = xRay ? intersects.length : Math.min(1, intersects.length); for (var i = 0; i < maxIntersects; i++) { var obj = intersects[i].object; var objName = getPickedObjectName(obj); var objNames = retrieveObjectNames(objSelector); if (objectsIncludeObj(objNames, objName)) { // save the object for the pickedObject block _pGlob.pickedObject = objName; isPicked = true; cbDo(event); } } if (!isPicked) { _pGlob.pickedObject = ''; cbIfMissedDo(event); } }, doubleClick ? 'dblclick' : 'mousedown', false, mouseButtons); } updateTextObj('C1-2-Num', '100'); /* 限制摄像机 */ setActiveCamera('摄像机1'); setCameraParam('ALLOW_PANNING', '摄像机1', false); setCameraParam('KEYBOARD_CONTROLS', '摄像机1', false); setCameraParam('ROTATION_SPEED', '摄像机1', 0); setCameraParam('FIELD_OF_VIEW', '摄像机1', 10); Logo = getObjectsFrom(['GROUP', 'heighLight'], 'ALL'); modetype = 'free'; changeVis(['GROUP', 'RouteAndLogo'], false); changeVis(['GROUP', 'EditNumber'], false); registerOnHover(Logo, false, function() { outline(_pGlob.hoveredObject, 'ENABLE'); }, function() { outline(_pGlob.hoveredObject, 'DISABLE'); }); registerOnClick(Logo, false, false, [0,1,2], function() { EquipmentClick(_pGlob.pickedObject); }, function() {}); if (modetype == 'Free') { } if (modetype == 'Free') { } } // end of PL.init function })(); // end of closure /* ================================ end of code ============================= */