Interface für simulierte Qubits (repräsentiert as 3D-Vektor) https://www.victorgiers.com/qubeenee
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

visual_logic.js 31KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068
  1. /**
  2. * Generated by Verge3D Puzzles v.2.12.5
  3. * Sat Jun 08 2019 21:51:22 GMT+0200 (Mitteleuropäische Sommerzeit)
  4. * Do not edit this file - your changes may get overridden when Puzzles are saved.
  5. * Refer to https://www.soft8soft.com/docs/manual/en/introduction/Using-JavaScript.html
  6. * for information on how to add your own JavaScript to Verge3D apps.
  7. */
  8. "use strict";
  9. (function() {
  10. // global variables/constants used by puzzles' functions
  11. var _pGlob = {};
  12. _pGlob.objCache = {};
  13. _pGlob.fadeAnnotations = true;
  14. _pGlob.objClickCallbacks = [];
  15. _pGlob.pickedObject = '';
  16. _pGlob.objHoverCallbacks = [];
  17. _pGlob.hoveredObject = '';
  18. _pGlob.objMovementInfos = {};
  19. _pGlob.objDragOverCallbacks = [];
  20. _pGlob.objDragOverInfoByBlock = {}
  21. _pGlob.dragMoveOrigins = {};
  22. _pGlob.dragScaleOrigins = {};
  23. _pGlob.mediaElements = {};
  24. _pGlob.loadedFiles = {};
  25. _pGlob.loadedFile = '';
  26. _pGlob.animMixerCallbacks = [];
  27. _pGlob.arHitPoint = new v3d.Vector3(0, 0, 0);
  28. _pGlob.states = [];
  29. _pGlob.percentage = 0;
  30. _pGlob.animateParamUpdate = null;
  31. _pGlob.openedFile = '';
  32. _pGlob.xrSessionAcquired = false;
  33. _pGlob.xrSessionCallbacks = [];
  34. _pGlob.screenCoords = new v3d.Vector2();
  35. _pGlob.AXIS_X = new v3d.Vector3(1, 0, 0);
  36. _pGlob.AXIS_Y = new v3d.Vector3(0, 1, 0);
  37. _pGlob.AXIS_Z = new v3d.Vector3(0, 0, 1);
  38. _pGlob.MIN_DRAG_SCALE = 10e-4;
  39. _pGlob.vec2Tmp = new v3d.Vector2();
  40. _pGlob.vec2Tmp2 = new v3d.Vector2();
  41. _pGlob.vec3Tmp = new v3d.Vector3();
  42. _pGlob.vec3Tmp2 = new v3d.Vector3();
  43. _pGlob.quatTmp = new v3d.Quaternion();
  44. _pGlob.quatTmp2 = new v3d.Quaternion();
  45. _pGlob.mat4Tmp = new v3d.Matrix4();
  46. _pGlob.planeTmp = new v3d.Plane();
  47. _pGlob.raycasterTmp = new v3d.Raycaster();
  48. _pGlob.timers = {};
  49. var _pPhysics = {};
  50. _pPhysics.syncList = [];
  51. // internal info
  52. _pPhysics.collisionData = [];
  53. // goes to collision callback
  54. _pPhysics.collisionInfo = {
  55. objectA: '',
  56. objectB: '',
  57. distance: 0,
  58. positionOnA: [0, 0, 0],
  59. positionOnB: [0, 0, 0],
  60. normalOnB: [0, 0, 0]
  61. };
  62. var PL = v3d.PL = v3d.PL || {};
  63. PL.legacyMode = false;
  64. PL.execInitPuzzles = function() {
  65. var _initGlob = {};
  66. _initGlob.percentage = 0;
  67. _initGlob.output = {
  68. initOptions: {
  69. fadeAnnotations: true,
  70. useBkgTransp: false,
  71. preserveDrawBuf: false,
  72. useCompAssets: false,
  73. useFullscreen: true,
  74. useCustomPreloader: false,
  75. preloaderStartCb: function() {},
  76. preloaderProgressCb: function() {},
  77. preloaderEndCb: function() {},
  78. }
  79. }
  80. // utility functions envoked by the HTML puzzles
  81. function getElements(ids, isParent) {
  82. var elems = [];
  83. if (Array.isArray(ids) && ids[0] != "WINDOW" && ids[0] != "DOCUMENT" && ids[0] != "BODY") {
  84. for (var i = 0; i < ids.length; i++)
  85. elems.push(getElement(ids[i], isParent));
  86. } else {
  87. elems.push(getElement(ids, isParent));
  88. }
  89. return elems;
  90. }
  91. function getElement(id, isParent) {
  92. var elem;
  93. if (Array.isArray(id) && id[0] == "WINDOW") {
  94. if (isParent)
  95. elem = parent;
  96. else
  97. elem = window;
  98. } else if (Array.isArray(id) && id[0] == "DOCUMENT") {
  99. if (isParent)
  100. elem = parent.document;
  101. else
  102. elem = document;
  103. } else if (Array.isArray(id) && id[0] == "BODY") {
  104. if (isParent)
  105. elem = parent.document.body;
  106. else
  107. elem = document.body;
  108. } else {
  109. if (isParent)
  110. elem = parent.document.getElementById(id);
  111. else
  112. elem = document.getElementById(id);
  113. }
  114. return elem;
  115. }
  116. // setHTMLElemStyle puzzle
  117. function setHTMLElemStyle(prop, value, ids, isParent) {
  118. var elems = getElements(ids, isParent);
  119. for (var i = 0; i < elems.length; i++) {
  120. var elem = elems[i];
  121. if (!elem || !elem.style)
  122. continue;
  123. elem.style[prop] = value;
  124. }
  125. }
  126. // initSettings puzzle
  127. _initGlob.output.initOptions.fadeAnnotations = true;
  128. _initGlob.output.initOptions.useBkgTransp = true;
  129. _initGlob.output.initOptions.preserveDrawBuf = false;
  130. _initGlob.output.initOptions.useCompAssets = false;
  131. _initGlob.output.initOptions.useFullscreen = false;
  132. setHTMLElemStyle('backgroundColor', 'rgb(127,127,127)', ["BODY"], false);
  133. return _initGlob.output;
  134. }
  135. PL.init = function(appInstance, initOptions) {
  136. initOptions = initOptions || {};
  137. if ('fadeAnnotations' in initOptions) {
  138. _pGlob.fadeAnnotations = initOptions.fadeAnnotations;
  139. }
  140. var distZ, R, G, B, hue, dragging, distY, distX, inboundStepper, r_, maxDist, recordqubitstate, recordbitstate, bitstate, stepY, g_, sat, b_, value;
  141. // utility function envoked by almost all V3D-specific puzzles
  142. // process object input, which can be either single obj or array of objects, or a group
  143. function retrieveObjectNames(objNames) {
  144. var acc = [];
  145. retrieveObjectNamesAcc(objNames, acc);
  146. return acc;
  147. }
  148. function retrieveObjectNamesAcc(currObjNames, acc) {
  149. if (typeof currObjNames == "string") {
  150. acc.push(currObjNames);
  151. } else if (Array.isArray(currObjNames) && currObjNames[0] == "GROUP") {
  152. var newObj = getObjectNamesByGroupName(currObjNames[1]);
  153. for (var i = 0; i < newObj.length; i++)
  154. acc.push(newObj[i]);
  155. } else if (Array.isArray(currObjNames) && currObjNames[0] == "ALL_OBJECTS") {
  156. var newObj = getAllObjectNames();
  157. for (var i = 0; i < newObj.length; i++)
  158. acc.push(newObj[i]);
  159. } else if (Array.isArray(currObjNames)) {
  160. for (var i = 0; i < currObjNames.length; i++)
  161. retrieveObjectNamesAcc(currObjNames[i], acc);
  162. }
  163. }
  164. // utility function envoked by almost all V3D-specific puzzles
  165. // find first occurence of the object by its name
  166. function getObjectByName(objName) {
  167. var objFound;
  168. var runTime = typeof _pGlob != "undefined";
  169. objFound = runTime ? _pGlob.objCache[objName] : null;
  170. if (objFound && objFound.name == objName)
  171. return objFound;
  172. appInstance.scene.traverse(function(obj) {
  173. if (!objFound && notIgnoredObj(obj) && (obj.name == objName)) {
  174. objFound = obj;
  175. if (runTime)
  176. _pGlob.objCache[objName] = objFound;
  177. }
  178. });
  179. return objFound;
  180. }
  181. // utility function envoked by almost all V3D-specific puzzles
  182. // retrieve all objects which belong to the group
  183. function getObjectNamesByGroupName(targetGroupName) {
  184. var objNameList = [];
  185. appInstance.scene.traverse(function(obj){
  186. if (notIgnoredObj(obj)) {
  187. var groupNames = obj.groupNames;
  188. if (!groupNames)
  189. return;
  190. for (var i = 0; i < groupNames.length; i++) {
  191. var groupName = groupNames[i];
  192. if (groupName == targetGroupName) {
  193. objNameList.push(obj.name);
  194. }
  195. }
  196. }
  197. });
  198. return objNameList;
  199. }
  200. // utility function envoked by almost all V3D-specific puzzles
  201. // filter off some non-mesh types
  202. function notIgnoredObj(obj) {
  203. return (obj.type != "Scene" && obj.type != "AmbientLight" &&
  204. obj.name != "" && !(obj.isMesh && obj.isMaterialGeneratedMesh));
  205. }
  206. // utility function envoked by almost all V3D-specific puzzles
  207. // retrieve all objects on the scene
  208. function getAllObjectNames() {
  209. var objNameList = [];
  210. appInstance.scene.traverse(function(obj) {
  211. if (notIgnoredObj(obj))
  212. objNameList.push(obj.name)
  213. });
  214. return objNameList;
  215. }
  216. function swizzleValueSign(newAxis, value) {
  217. newAxis = newAxis.toLowerCase();
  218. if (newAxis == 'z') {
  219. if (typeof value == 'number')
  220. return -value
  221. else if (typeof value == 'string' && value != '' && value != "''" && value != '""')
  222. return String(-Number(value));
  223. else
  224. return value;
  225. } else
  226. return value;
  227. }
  228. function swizzleVec3(vec, isScale) {
  229. var dest = []
  230. dest[0] = vec[0];
  231. dest[1] = vec[2];
  232. dest[2] = isScale ? vec[1] : swizzleValueSign('z', vec[1])
  233. return dest;
  234. }
  235. function intersectPlaneCSS(plane, cssX, cssY, dest) {
  236. var coords = _pGlob.vec2Tmp;
  237. var rc = _pGlob.raycasterTmp;
  238. coords.x = (cssX / appInstance.getWidth()) * 2 - 1;
  239. coords.y = - (cssY / appInstance.getHeight()) * 2 + 1;
  240. rc.setFromCamera(coords, appInstance.camera);
  241. return rc.ray.intersectPlane(plane, dest);
  242. }
  243. // dragMove puzzle
  244. function dragMove(objNames, mode, blockId, parentDragOverBlockId) {
  245. if (!appInstance.camera) return;
  246. objNames = retrieveObjectNames(objNames);
  247. if (!objNames) return;
  248. var info = _pGlob.objDragOverInfoByBlock[parentDragOverBlockId];
  249. if (!info) return;
  250. var draggedObj = getObjectByName(info.draggedObjName);
  251. if (!draggedObj) return;
  252. if (!(blockId in _pGlob.dragMoveOrigins)) {
  253. _pGlob.dragMoveOrigins[blockId] = [];
  254. }
  255. var posOrigins = _pGlob.dragMoveOrigins[blockId];
  256. var lenDiff = objNames.length - posOrigins.length;
  257. for (var i = 0; i < lenDiff; i++) {
  258. posOrigins.push(new v3d.Vector3());
  259. }
  260. for (var i = 0; i < objNames.length; i++) {
  261. var obj = getObjectByName(objNames[i]);
  262. var posOrigin = posOrigins[i];
  263. if (!info.isMoved) {
  264. // the object position before the first move is used as an initial value
  265. posOrigin.copy(obj.position);
  266. }
  267. if (mode == "X" || mode == "Y" || mode == "Z") {
  268. var axis = mode == "X" ? _pGlob.AXIS_X : (mode == "Y" ? _pGlob.AXIS_Y : _pGlob.AXIS_Z);
  269. var coord = mode == "X" ? "x" : (mode == "Y" ? "y" : "z");
  270. var planeNor = appInstance.camera.getWorldDirection(_pGlob.vec3Tmp);
  271. planeNor.cross(axis).cross(axis);
  272. var plane = _pGlob.planeTmp.setFromNormalAndCoplanarPoint(planeNor, draggedObj.position);
  273. var p0 = intersectPlaneCSS(plane, info.downX, info.downY, _pGlob.vec3Tmp);
  274. var p1 = intersectPlaneCSS(plane, info.currX, info.currY, _pGlob.vec3Tmp2);
  275. if (p0 && p1) {
  276. obj.position[coord] = posOrigin[coord] + p1[coord] - p0[coord];
  277. }
  278. } else if (mode == "XY" || mode == "XZ" || mode == "YZ") {
  279. var normal = mode == "XY" ? _pGlob.AXIS_Z : (mode == "XZ" ? _pGlob.AXIS_Y : _pGlob.AXIS_X);
  280. var coord0 = mode == "XY" ? "x" : (mode == "XZ" ? "x" : "y");
  281. var coord1 = mode == "XY" ? "y" : (mode == "XZ" ? "z" : "z");
  282. var plane = _pGlob.planeTmp.setFromNormalAndCoplanarPoint(normal, draggedObj.position);
  283. var p0 = intersectPlaneCSS(plane, info.downX, info.downY, _pGlob.vec3Tmp);
  284. var p1 = intersectPlaneCSS(plane, info.currX, info.currY, _pGlob.vec3Tmp2);
  285. if (p0 && p1) {
  286. obj.position[coord0] = posOrigin[coord0] + p1[coord0] - p0[coord0];
  287. obj.position[coord1] = posOrigin[coord1] + p1[coord1] - p0[coord1];
  288. }
  289. } else if (mode == "XYZ") {
  290. var planeNor = appInstance.camera.getWorldDirection(_pGlob.vec3Tmp);
  291. var plane = _pGlob.planeTmp.setFromNormalAndCoplanarPoint(planeNor, draggedObj.position);
  292. var p0 = intersectPlaneCSS(plane, info.downX, info.downY, _pGlob.vec3Tmp);
  293. var p1 = intersectPlaneCSS(plane, info.currX, info.currY, _pGlob.vec3Tmp2);
  294. if (p0 && p1) {
  295. obj.position.addVectors(posOrigin, p1).sub(p0);
  296. }
  297. }
  298. obj.updateMatrixWorld(true);
  299. }
  300. }
  301. // getObjTransform puzzle
  302. function getObjTransform(objName, mode, coord) {
  303. if (!objName)
  304. return;
  305. var obj = getObjectByName(objName);
  306. if (!obj)
  307. return;
  308. if (mode == "rotation")
  309. return swizzleValueSign(coord, obj[mode][coord] * 180/Math.PI);
  310. else if (mode == 'position')
  311. return swizzleValueSign(coord, obj[mode][coord]);
  312. else
  313. return obj[mode][coord];
  314. }
  315. // distanceBetweenObjects puzzle
  316. function getDistanceBetweenObjects(objName1, objName2) {
  317. if (!objName1 || !objName2)
  318. return;
  319. var obj1 = getObjectByName(objName1);
  320. var obj2 = getObjectByName(objName2);
  321. if (!obj1 || !obj2)
  322. return;
  323. return obj1.getWorldPosition(_pGlob.vec3Tmp).distanceTo(obj2.getWorldPosition(_pGlob.vec3Tmp2));
  324. }
  325. // applyObjLocalTransform puzzle
  326. function applyObjLocalTransform(objNames, mode, x, y, z) {
  327. objNames = retrieveObjectNames(objNames);
  328. if (!objNames) return;
  329. var defValue = mode == "scale" ? 1 : 0;
  330. if (typeof x != "number") x = defValue;
  331. if (typeof y != "number") y = defValue;
  332. if (typeof z != "number") z = defValue;
  333. var inVec = swizzleVec3([x,y,z], mode == 'scale');
  334. for (var i = 0; i < objNames.length; i++) {
  335. var objName = objNames[i];
  336. if (!objName) continue;
  337. var obj = getObjectByName(objName);
  338. if (!obj) continue;
  339. // don't swizzle values for cameras, their local space happens
  340. // to be the same as for Blender/Max cameras, bcz their different
  341. // rest orientation balances difference in coordinate systems
  342. var useSwizzled = !obj.isCamera;
  343. var xVal = useSwizzled ? inVec[0] : x;
  344. var yVal = useSwizzled ? inVec[1] : y;
  345. var zVal = useSwizzled ? inVec[2] : z;
  346. switch (mode) {
  347. case "position":
  348. if (_pGlob.xrSessionAcquired && obj.isCamera) {
  349. v3d.WebVRUtils.translateVRCamera(obj, _pGlob.AXIS_X, xVal);
  350. v3d.WebVRUtils.translateVRCamera(obj, _pGlob.AXIS_Y, yVal);
  351. v3d.WebVRUtils.translateVRCamera(obj, _pGlob.AXIS_Z, zVal);
  352. } else {
  353. obj.translateX(xVal);
  354. obj.translateY(yVal);
  355. obj.translateZ(zVal);
  356. }
  357. break;
  358. case "rotation":
  359. if (_pGlob.xrSessionAcquired && obj.isCamera) {
  360. v3d.WebVRUtils.rotateVRCamera(obj, _pGlob.AXIS_X, v3d.Math.degToRad(xVal));
  361. v3d.WebVRUtils.rotateVRCamera(obj, _pGlob.AXIS_Y, v3d.Math.degToRad(yVal));
  362. v3d.WebVRUtils.rotateVRCamera(obj, _pGlob.AXIS_Z, v3d.Math.degToRad(zVal));
  363. } else {
  364. obj.rotateX(v3d.Math.degToRad(xVal));
  365. obj.rotateY(v3d.Math.degToRad(yVal));
  366. obj.rotateZ(v3d.Math.degToRad(zVal));
  367. }
  368. break;
  369. case "scale":
  370. obj.scale.x *= xVal;
  371. obj.scale.y *= yVal;
  372. obj.scale.z *= zVal;
  373. break;
  374. }
  375. obj.updateMatrixWorld(true);
  376. }
  377. }
  378. // utility function used by the whenClicked, whenHovered and whenDraggedOver puzzles
  379. function initObjectPicking(callback, eventType, mouseDownUseTouchStart) {
  380. var elem = appInstance.container;
  381. elem.addEventListener(eventType, pickListener);
  382. if (eventType == "mousedown") {
  383. var touchEventName = mouseDownUseTouchStart ? "touchstart" : "touchend";
  384. elem.addEventListener(touchEventName, pickListener);
  385. }
  386. var raycaster = new v3d.Raycaster();
  387. function pickListener(event) {
  388. event.preventDefault();
  389. var xNorm = 0, yNorm = 0;
  390. if (event instanceof MouseEvent) {
  391. xNorm = event.offsetX / elem.clientWidth;
  392. yNorm = event.offsetY / elem.clientHeight;
  393. } else if (event instanceof TouchEvent) {
  394. var rect = elem.getBoundingClientRect();
  395. xNorm = (event.changedTouches[0].clientX - rect.left) / rect.width;
  396. yNorm = (event.changedTouches[0].clientY - rect.top) / rect.height;
  397. }
  398. _pGlob.screenCoords.x = xNorm * 2 - 1;
  399. _pGlob.screenCoords.y = -yNorm * 2 + 1;
  400. raycaster.setFromCamera(_pGlob.screenCoords, appInstance.camera);
  401. var objList = [];
  402. appInstance.scene.traverse(function(obj){objList.push(obj);});
  403. var intersects = raycaster.intersectObjects(objList);
  404. if (intersects.length > 0) {
  405. var obj = intersects[0].object;
  406. callback(obj, event);
  407. } else {
  408. callback(null, event);
  409. }
  410. }
  411. }
  412. // utility function used by the whenDraggedOver puzzles
  413. function fireObjectPickingCallbacks(objName, source, index, cbParam) {
  414. for (var i = 0; i < source.length; i++) {
  415. var cb = source[i];
  416. if (objectsIncludeObj([cb[0]], objName)) {
  417. cb[index](cbParam);
  418. }
  419. }
  420. }
  421. function objectsIncludeObj(objNames, testedObjName) {
  422. if (!testedObjName) return false;
  423. for (var i = 0; i < objNames.length; i++) {
  424. if (testedObjName == objNames[i]) {
  425. return true;
  426. } else {
  427. // also check children which are auto-generated for multi-material objects
  428. var obj = getObjectByName(objNames[i]);
  429. if (obj && obj.type == "Group") {
  430. for (var j = 0; j < obj.children.length; j++) {
  431. if (testedObjName == obj.children[j].name) {
  432. return true;
  433. }
  434. }
  435. }
  436. }
  437. }
  438. return false;
  439. }
  440. // utility function used by the whenClicked, whenHovered and whenDraggedOver puzzles
  441. function getPickedObjectName(obj) {
  442. // auto-generated from a multi-material object, use parent name instead
  443. if (obj.isMesh && obj.isMaterialGeneratedMesh && obj.parent) {
  444. return obj.parent.name;
  445. } else {
  446. return obj.name;
  447. }
  448. }
  449. function eventGetOffsetCoords(e, touchId, dest) {
  450. if (e instanceof MouseEvent) {
  451. dest.set(e.offsetX, e.offsetY);
  452. } else if (window.TouchEvent && e instanceof TouchEvent) {
  453. var rect = e.target.getBoundingClientRect();
  454. var touches = e.touches;
  455. if (e.type == "touchstart" || e.type == "touchend" || e.type == "touchmove") {
  456. touches = e.changedTouches;
  457. }
  458. var touch = touches[0];
  459. for (var i = 0; i < touches.length; i++) {
  460. if (touches[i].identifier == touchId) {
  461. touch = touches[i];
  462. break;
  463. }
  464. }
  465. dest.set(touch.clientX - rect.left, touch.clientY - rect.top);
  466. }
  467. return dest;
  468. }
  469. function eventTouchIdGetFirst(e) {
  470. if (e instanceof MouseEvent) {
  471. return -1;
  472. } else if (window.TouchEvent && e instanceof TouchEvent) {
  473. if (e.type == "touchstart" || e.type == "touchend" || e.type == "touchmove") {
  474. return e.changedTouches[0].identifier;
  475. } else {
  476. return e.touches[0].identifier;
  477. }
  478. }
  479. return -1;
  480. }
  481. function eventTouchIdChangedFilter(e, touchId) {
  482. if (window.TouchEvent && e instanceof TouchEvent) {
  483. if (e.type == "touchstart" || e.type == "touchend" || e.type == "touchmove") {
  484. var isChanged = false;
  485. for (var i = 0; i < e.changedTouches.length; i++) {
  486. if (e.changedTouches[i].identifier == touchId) {
  487. isChanged = true;
  488. break;
  489. }
  490. }
  491. return isChanged;
  492. }
  493. }
  494. return true;
  495. }
  496. function initDragOverInfo() {
  497. return {
  498. draggedObjName: '',
  499. downX: 0, downY: 0,
  500. prevX: 0, prevY: 0,
  501. currX: 0, currY: 0,
  502. isDowned: false,
  503. isMoved: false,
  504. touchId: -1
  505. };
  506. }
  507. // whenDraggedOver puzzle
  508. initObjectPicking(function(obj, downEvent) {
  509. if (!obj) {
  510. return;
  511. }
  512. var objName = getPickedObjectName(obj);
  513. fireObjectPickingCallbacks(objName, _pGlob.objDragOverCallbacks, 1,
  514. { downEvent: downEvent, draggedObjName: objName });
  515. }, "mousedown", true);
  516. // whenDraggedOver puzzle
  517. function registerOnDrag(objNames, callback_start, callback_move, callback_drop, blockId) {
  518. objNames = retrieveObjectNames(objNames);
  519. if (!objNames)
  520. return;
  521. var cb = function(cbParam) {
  522. if (appInstance.controls) {
  523. appInstance.controls.enabled = false;
  524. }
  525. if (!(blockId in _pGlob.objDragOverInfoByBlock)) {
  526. _pGlob.objDragOverInfoByBlock[blockId] = initDragOverInfo();
  527. }
  528. var info = _pGlob.objDragOverInfoByBlock[blockId];
  529. // NOTE: don't use more than one pointing event, e.g. don't process
  530. // some events related to multitouch actions
  531. if (info.isDowned) {
  532. return;
  533. }
  534. var touchId = eventTouchIdGetFirst(cbParam.downEvent);
  535. var coords = eventGetOffsetCoords(cbParam.downEvent, touchId,
  536. _pGlob.vec2Tmp);
  537. info.downX = info.prevX = info.currX = coords.x;
  538. info.downY = info.prevY = info.currY = coords.y;
  539. info.touchId = touchId;
  540. info.isDowned = true;
  541. info.isMoved = false;
  542. info.draggedObjName = cbParam.draggedObjName;
  543. callback_start();
  544. var elem = appInstance.container;
  545. var moveCb = function(e) {
  546. if (!eventTouchIdChangedFilter(e, info.touchId)) {
  547. // don't handle events not intended for this particular touch
  548. return;
  549. }
  550. var coords = eventGetOffsetCoords(e, info.touchId, _pGlob.vec2Tmp);
  551. info.prevX = info.currX;
  552. info.prevY = info.currY;
  553. info.currX = coords.x;
  554. info.currY = coords.y;
  555. callback_move();
  556. info.isMoved = true;
  557. }
  558. var upCb = function(e) {
  559. if (!eventTouchIdChangedFilter(e, info.touchId)) {
  560. // don't handle events not intended for this particular touch
  561. return;
  562. }
  563. var coords = eventGetOffsetCoords(e, info.touchId, _pGlob.vec2Tmp);
  564. info.currX = coords.x;
  565. info.currY = coords.y;
  566. info.prevX = info.currX;
  567. info.prevY = info.currY;
  568. callback_drop();
  569. info.isDowned = false;
  570. elem.removeEventListener("mousemove", moveCb, false);
  571. elem.removeEventListener("touchmove", moveCb, false);
  572. elem.removeEventListener("mouseup", upCb, false);
  573. elem.removeEventListener("touchend", upCb, false);
  574. if (appInstance.controls) {
  575. appInstance.controls.enabled = true;
  576. }
  577. }
  578. elem.addEventListener("mousemove", moveCb, false);
  579. elem.addEventListener("touchmove", moveCb, false);
  580. elem.addEventListener("mouseup", upCb, false);
  581. elem.addEventListener("touchend", upCb, false);
  582. }
  583. for (var i = 0; i < objNames.length; i++) {
  584. var objName = objNames[i];
  585. if (!objName) continue;
  586. _pGlob.objDragOverCallbacks.push([objName, cb]);
  587. }
  588. }
  589. // ssao puzzle
  590. function ssao(radius, aoClamp, lumInfluence) {
  591. appInstance.enablePostprocessing([{
  592. type: 'ssao',
  593. radius: radius,
  594. aoClamp: aoClamp,
  595. lumInfluence: lumInfluence
  596. }]);
  597. }
  598. // getObjectMaterial puzzle
  599. function getObjectMaterial(objNames) {
  600. objNames = retrieveObjectNames(objNames);
  601. if (!objNames)
  602. return '';
  603. for (var i = 0; i < objNames.length; i++) {
  604. var objName = objNames[i]
  605. if (!objName)
  606. continue;
  607. var obj = getObjectByName(objName);
  608. if (!obj)
  609. continue;
  610. if (obj.material && typeof obj.material.name == "string")
  611. return obj.material.name;
  612. }
  613. return '';
  614. }
  615. // assignMaterial puzzle
  616. function assignMat(objNames, matName) {
  617. objNames = retrieveObjectNames(objNames);
  618. if (!objNames || !matName)
  619. return;
  620. var mat = v3d.SceneUtils.getMaterialByName(appInstance, matName);
  621. if (!mat)
  622. return;
  623. for (var i = 0; i < objNames.length; i++) {
  624. var objName = objNames[i];
  625. if (!objName)
  626. continue;
  627. var obj = getObjectByName(objName);
  628. if (obj)
  629. obj.material = mat;
  630. }
  631. }
  632. // whenClicked puzzle
  633. initObjectPicking(function(obj) {
  634. // save the object for the pickedObject block
  635. _pGlob.pickedObject = obj ? getPickedObjectName(obj) : '';
  636. _pGlob.objClickCallbacks.forEach(function(el) {
  637. var isPicked = obj && objectsIncludeObj(el.objNames, getPickedObjectName(obj));
  638. el.callbacks[isPicked ? 0 : 1]();
  639. });
  640. }, 'mousedown');
  641. // whenClicked puzzle
  642. function registerOnClick(objNames, cbDo, cbIfMissedDo) {
  643. objNames = retrieveObjectNames(objNames) || [];
  644. var objNamesFiltered = objNames.filter(function(name) {
  645. return name;
  646. });
  647. _pGlob.objClickCallbacks.push({
  648. objNames: objNamesFiltered,
  649. callbacks: [cbDo, cbIfMissedDo]
  650. });
  651. }
  652. // callJSFunction puzzle
  653. function getJSFunction(funcName) {
  654. var jsFunc = appInstance.ExternalInterface[funcName];
  655. if (typeof jsFunc == "function")
  656. return jsFunc;
  657. else
  658. return function() {};
  659. }
  660. // setInterval puzzle
  661. function registerInterval(timeout, callback) {
  662. window.setInterval(callback, 1000 * timeout);
  663. }
  664. // getEventProperty puzzle
  665. function getEventProperty(prop, event) {
  666. if (typeof event != "undefined") {
  667. if (prop == "target.id")
  668. return event.target.id;
  669. else
  670. return event[prop];
  671. }
  672. }
  673. // utility functions envoked by the HTML puzzles
  674. function getElements(ids, isParent) {
  675. var elems = [];
  676. if (Array.isArray(ids) && ids[0] != "WINDOW" && ids[0] != "DOCUMENT" && ids[0] != "BODY") {
  677. for (var i = 0; i < ids.length; i++)
  678. elems.push(getElement(ids[i], isParent));
  679. } else {
  680. elems.push(getElement(ids, isParent));
  681. }
  682. return elems;
  683. }
  684. function getElement(id, isParent) {
  685. var elem;
  686. if (Array.isArray(id) && id[0] == "WINDOW") {
  687. if (isParent)
  688. elem = parent;
  689. else
  690. elem = window;
  691. } else if (Array.isArray(id) && id[0] == "DOCUMENT") {
  692. if (isParent)
  693. elem = parent.document;
  694. else
  695. elem = document;
  696. } else if (Array.isArray(id) && id[0] == "BODY") {
  697. if (isParent)
  698. elem = parent.document.body;
  699. else
  700. elem = document.body;
  701. } else {
  702. if (isParent)
  703. elem = parent.document.getElementById(id);
  704. else
  705. elem = document.getElementById(id);
  706. }
  707. return elem;
  708. }
  709. // eventHTMLElem puzzle
  710. function eventHTMLElem(eventType, ids, isParent, callback) {
  711. var elems = getElements(ids, isParent);
  712. for (var i = 0; i < elems.length; i++) {
  713. var elem = elems[i];
  714. if (!elem)
  715. continue;
  716. elem.addEventListener(eventType, callback, false);
  717. }
  718. }
  719. function matGetColors(matName) {
  720. var mat = v3d.SceneUtils.getMaterialByName(appInstance, matName);
  721. if (!mat) return [];
  722. if (mat.isMeshNodeMaterial)
  723. return Object.keys(mat.nodeRGBMap);
  724. else if (mat.isMeshStandardMaterial)
  725. return ['color', 'emissive'];
  726. else
  727. return []
  728. }
  729. // setMaterialColor puzzle
  730. function setMaterialColor(matName, colName, r, g, b) {
  731. var colors = matGetColors(matName);
  732. if (colors.indexOf(colName) < 0) return;
  733. var mats = v3d.SceneUtils.getMaterialsByName(appInstance, matName);
  734. for (var i = 0; i < mats.length; i++) {
  735. var mat = mats[i];
  736. if (mat.isMeshNodeMaterial) {
  737. var rgbIdx = mat.nodeRGBMap[colName];
  738. mat.nodeRGB[rgbIdx].x = r;
  739. mat.nodeRGB[rgbIdx].y = g;
  740. mat.nodeRGB[rgbIdx].z = b;
  741. } else {
  742. mat[colName].r = r;
  743. mat[colName].g = g;
  744. mat[colName].b = b;
  745. }
  746. mat.needsUpdate = true;
  747. if (mat === appInstance.worldMaterial)
  748. appInstance.updateEnvironment(mat);
  749. }
  750. }
  751. function setRGB(R, G, B) {
  752. setMaterialColor("transparent", "Principled BSDF Color", R, G, B);
  753. r_ = R;
  754. g_ = G;
  755. b_ = B;
  756. printStates();
  757. }
  758. appInstance.ExternalInterface["setRGB"] = setRGB;
  759. // toFixedPoint puzzle
  760. function toNumber(num, prec) {
  761. prec = Math.pow(10, prec);
  762. return Math.round(num * prec)/prec;
  763. }
  764. /**
  765. * Describe this function...
  766. */
  767. function printStates() {
  768. console.log(['Bit [',bitstate,'] Qubit: [',toNumber(r_, 3),'] [',toNumber(g_, 3),'] [',toNumber(b_, 3),']'].join(''));
  769. }
  770. /**
  771. * Describe this function...
  772. */
  773. function setHSV() {
  774. hue = Math.atan(Math.min(Math.max(distX / (distY + 1), Math.PI * -2), Math.PI * 2) + Math.PI * 2) / Math.PI * 180;
  775. hue = hue / (Math.PI * 4);
  776. sat = Math.sqrt(distX * distX + distY * distY) / maxDist;
  777. value = ((distZ - maxDist) / (2 * maxDist)) * -1;
  778. getJSFunction('HSVtoRGB')(hue, sat, value);
  779. }
  780. registerOnDrag(["GROUP", "qubit_grp"], function() {
  781. dragging = true;
  782. },
  783. function() {
  784. dragMove("qubit_controller", "XY", "5{hamS]l^diNZ_?={UNM", "x7;j`9Tr6$fIW]tXfLwm");
  785. inboundStepper = 0;
  786. distZ = getObjTransform("qubit", "position", "y") - getObjTransform("qubit_controller", "position", "y");
  787. distX = getObjTransform("qubit", "position", "x") - getObjTransform("qubit_controller", "position", "x");
  788. while (getDistanceBetweenObjects("qubit_controller", "qubit") > maxDist) {
  789. inboundStepper = (typeof inboundStepper == 'number' ? inboundStepper : 0) + 1;
  790. applyObjLocalTransform("qubit_controller", "position", distX / 200, 0, distZ / 100);
  791. }
  792. distZ = getObjTransform("qubit", "position", "y") - getObjTransform("qubit_controller", "position", "y");
  793. distX = getObjTransform("qubit", "position", "x") - getObjTransform("qubit_controller", "position", "x");
  794. setHSV();
  795. },
  796. function() {
  797. dragging = false;
  798. }, "x7;j`9Tr6$fIW]tXfLwm");
  799. distZ = getObjTransform("qubit", "position", "y") - getObjTransform("qubit_controller", "position", "y");
  800. distY = getObjTransform("qubit", "position", "z") - getObjTransform("qubit_controller", "position", "z");
  801. distX = getObjTransform("qubit", "position", "x") - getObjTransform("qubit_controller", "position", "x");
  802. maxDist = 2.3;
  803. stepY = 0.1;
  804. bitstate = 0;
  805. r_ = 0.5;
  806. g_ = 0.5;
  807. b_ = 0.5;
  808. ssao(1, 0.01, 0.3);
  809. distX / distY;
  810. registerOnClick("recordqubit", function() {
  811. if (getObjectMaterial("recordqubit") == "on") {
  812. assignMat("recordqubit", "black");
  813. recordqubitstate = 0;
  814. } else {
  815. assignMat("recordqubit", "on");
  816. recordqubitstate = 1;
  817. }
  818. }, function() {});
  819. 2 / 10;
  820. registerInterval(1, function() {
  821. if (recordbitstate == 1) {
  822. getJSFunction('addBit')(bitstate);
  823. }
  824. if (recordqubitstate == 1) {
  825. getJSFunction('addQubit')(r_, g_, b_);
  826. }
  827. });
  828. Math.atan(45) / Math.PI * 180;
  829. console.log(distX);
  830. console.log(distY);
  831. registerOnClick("bit", function() {
  832. if (getObjectMaterial("bit") == "white") {
  833. assignMat("bit", "black");
  834. bitstate = 0;
  835. } else {
  836. assignMat("bit", "white");
  837. bitstate = 1;
  838. }
  839. printStates();
  840. }, function() {});
  841. eventHTMLElem('wheel', ["DOCUMENT"], false, function(event) {
  842. if (getEventProperty('deltaY', event) < 0) {
  843. applyObjLocalTransform("qubit_controller", "position", 0, stepY, 0);
  844. if (getDistanceBetweenObjects("qubit_controller", "qubit") >= maxDist) {
  845. applyObjLocalTransform("qubit_controller", "position", 0, stepY * -1, 0);
  846. }
  847. } else if (getEventProperty('deltaY', event) > 0) {
  848. applyObjLocalTransform("qubit_controller", "position", 0, stepY * -1, 0);
  849. if (getDistanceBetweenObjects("qubit_controller", "qubit") >= maxDist) {
  850. applyObjLocalTransform("qubit_controller", "position", 0, stepY, 0);
  851. }
  852. }
  853. distY = getObjTransform("qubit", "position", "z") - getObjTransform("qubit_controller", "position", "z");
  854. setHSV();
  855. });
  856. Math.abs(4);
  857. 8;
  858. registerOnClick("recordbit", function() {
  859. if (getObjectMaterial("recordbit") == "on") {
  860. assignMat("recordbit", "black");
  861. recordbitstate = 0;
  862. } else {
  863. assignMat("recordbit", "on");
  864. recordbitstate = 1;
  865. }
  866. }, function() {});
  867. Math.sqrt(4);
  868. hue = Math.acos(distX / Math.sqrt(distX * distX + distY * distY + distZ * distZ)) / Math.PI * 180;
  869. hue = (Math.atan(Math.abs(distX / distY)) / Math.PI * 180) / 45 - 1;
  870. } // end of PL.init function
  871. if (window.v3dApp) {
  872. // backwards compatibility for old player projects
  873. PL.legacyMode = true;
  874. PL.init(window.v3dApp);
  875. }
  876. })(); // end of closure
  877. /* ================================ end of code ============================= */