API Docs for:
Show:

File: workspace\templates\renderScript.js

  1. //<script>
  2. ;
  3.  
  4.  
  5.  
  6. if( typeof(startupScripts) == 'undefined'){
  7.  
  8. var startupScripts = {
  9. "0":function(){},
  10. "1":function(){},
  11. "2":function(){},
  12. "3":function(){},
  13. "4":function(){},
  14. "5":function(){},
  15. "6":function(){},
  16. "7":function(){}
  17. };
  18.  
  19. }
  20.  
  21.  
  22.  
  23. /**
  24. *
  25. * Class containing all the methods used in the 3d visual assembly
  26. * @class renderGlobal
  27. * @static
  28. */
  29.  
  30.  
  31.  
  32.  
  33. // Put recieved data about assembly into here. The code handles the rest.
  34. // theXMLFile should be a string, and theSTLFiles as a binary ArrayBuffer
  35. // Any text-based STL files should be in an 8-bit encoding
  36. /**
  37. *
  38. * The function which handles the actual rendering of the solution file animation
  39. * and loading in the models
  40. *
  41. * @method rdr_recieveData
  42. * @for renderGlobal
  43. * @param {String} theXMLFile
  44. * @param {Object} theSTLFiles
  45. * @return {Void}
  46. *
  47. */
  48. function rdr_receiveData(theXMLFile, theSTLFiles){
  49.  
  50. theXML=theXMLFile;
  51.  
  52. parts.length=0;
  53. var pos=0;
  54. var lim=theSTLFiles.length;
  55. var partGeom;
  56. var partMesh;
  57.  
  58. while(pos<lim){
  59. partGeom=null;
  60. partGeom=theSTLFiles[pos];
  61. if(partGeom===null){
  62. partGeom=parseStlBinary(fileReaders[pos].Reader.result);
  63. }
  64.  
  65. //console.log(partGeom);
  66.  
  67. partMesh=new THREE.Mesh(
  68. partGeom,
  69. new THREE.MeshNormalMaterial( )
  70. );
  71. parts.push({
  72. Mesh: partMesh,
  73. Name: fileReaders[pos].Name
  74. })
  75. scene.add(partMesh);
  76.  
  77. pos++;
  78. }
  79.  
  80. rdr_renderParts();
  81.  
  82. }
  83.  
  84.  
  85.  
  86.  
  87.  
  88.  
  89.  
  90.  
  91.  
  92. // Dialates time with the scrolling of the mouse
  93. function rdr_zoomIt(e){
  94.  
  95. //zoom=zoom*Math.pow(1.001,e.wheelDelta);
  96. var theDelta = e.deltaY == 0 ? 0 : ( e.deltaY > 0 ? 1 : -1 );
  97. zoom+=theDelta*(-1);
  98.  
  99. }
  100.  
  101.  
  102. /**
  103. *
  104. * Attempts to lock the mouse for camera manupulation
  105. *
  106. * @method rdr_tryMouseLock
  107. * @for renderGlobal
  108. * @return {Void}
  109. *
  110. */
  111. function rdr_tryMouseLock(){
  112.  
  113. var element= document.getElementById("theDisplay");
  114.  
  115. element.requestPointerLock = element.requestPointerLock ||
  116. element.mozRequestPointerLock ||
  117. element.webkitRequestPointerLock;
  118. // Ask the browser to lock the pointer
  119. element.requestPointerLock();
  120.  
  121. }
  122.  
  123.  
  124.  
  125. /**
  126. *
  127. * Adds or Removes event listeners for input meant for camera manipulation.
  128. * Is triggered by a change in the state of the mouse locking or unlocking.
  129. * The mouse locking results in input listeners being added to the webpage,
  130. * whereas the unlocking of the mouse results in the removal of appropriate
  131. * listeners.
  132. *
  133. * @method rdr_lockChange
  134. * @for renderGlobal
  135. *
  136. *
  137. * @param {Event} e The event that is to be applied to the function by event listeners upon
  138. * a change in the state of mouselock
  139. * @return {Void}
  140. *
  141. *
  142. */
  143. function rdr_lockChange(e){
  144.  
  145. var theTarget=document.getElementById("theDisplay");
  146. if (document.pointerLockElement === theTarget ||
  147. document.mozPointerLockElement === theTarget ||
  148. document.webkitPointerLockElement === theTarget) {
  149. // Pointer was just locked
  150. // Enable the mousemove listener
  151. document.addEventListener("mousemove", rdr_mouseMoved, false);
  152. pointerIsLocked=true;
  153. }
  154. else {
  155. // Pointer was just unlocked
  156. // Disable the mousemove listener
  157. document.removeEventListener("mousemove", rdr_mouseMoved, false);
  158. pointerIsLocked=false;
  159. }
  160.  
  161. }
  162.  
  163.  
  164.  
  165. /**
  166. *
  167. * Changes the orientation of the camera based off of the mouse movement
  168. * contained in the supplied mouse movement event. X-axis movement
  169. * corresponds to change in the yaw of the camera whereas Y-axis movement
  170. * corresponds to a change in the pitch of the camera.
  171. *
  172. * @method rdr_mouseMoved
  173. * @for renderGlobal
  174. *
  175. * @param {Event} e The mouse movement event to be supplied to the function by a mouse
  176. * movement event listener on the web page
  177. * @return {Void}
  178. *
  179. */
  180. function rdr_mouseMoved(e){
  181.  
  182. var movementX = e.movementX ||
  183. e.mozMovementX ||
  184. e.webkitMovementX ||
  185. 0;
  186. var movementY = e.movementY ||
  187. e.mozMovementY ||
  188. e.webkitMovementY ||
  189. 0;
  190.  
  191. camPitch-=movementY/400;
  192. if(camPitch> Math.PI/2){
  193. camPitch= Math.PI/2;
  194. }
  195. else if(camPitch< Math.PI/(-2)){
  196. camPitch= Math.PI/(-2)
  197. }
  198.  
  199. camYaw-=movementX/400;
  200. if(camPitch> Math.PI){
  201. camPitch= Math.PI;
  202. }
  203. else if(camPitch< Math.PI*(-1)){
  204. camPitch= Math.PI*(-1);
  205. }
  206.  
  207. }
  208.  
  209.  
  210.  
  211. // Changes key press states based off of key presses
  212. /**
  213. *
  214. * Accepts a key press event and, if the key press corresponds to one
  215. * of the keys used for manipulating the view, sets the proper components
  216. * of "inputState" to true.
  217. *
  218. * @method rdr_registerDown
  219. * @for renderGlobal
  220. *
  221. *
  222. * @param {Event} e The key down event to be supplied to the function by a key down event
  223. * listener on the web page
  224. * @return {Void}
  225. *
  226. */
  227. function rdr_registerDown(e){
  228.  
  229.  
  230.  
  231. var theKey;
  232. if (e.which == null) {
  233. theKey= String.fromCharCode(e.keyCode) // IE
  234. } else if (e.which!=0 /*&& e.charCode!=0*/) {
  235. theKey= String.fromCharCode(e.which) // the rest
  236. } else {
  237. return;// special key
  238. }
  239. theKey=theKey.toUpperCase();
  240.  
  241.  
  242.  
  243. if(theKey=='A'){
  244. inputState.A=true;
  245. }
  246. if(theKey=='S'){
  247. inputState.S=true;
  248. }
  249. if(theKey=='D'){
  250. inputState.D=true;
  251. }
  252. if(theKey=='W'){
  253. inputState.W=true;
  254. }
  255. if(theKey==' '){
  256. inputState.Space=false;
  257. }
  258. if(theKey=='Q'){
  259. inputState.Q=true;
  260. }
  261. if(theKey=='E'){
  262. inputState.E=true;
  263. }
  264. if(theKey=='R'){
  265. inputState.R=true;
  266. }
  267. if(theKey=='F'){
  268. inputState.F=true;
  269. }
  270. return;
  271.  
  272. }
  273.  
  274.  
  275.  
  276.  
  277. /**
  278. *
  279. * Accepts a key press release and, if the key release corresponds to one
  280. * of the keys used for manipulating the view, sets the proper components
  281. * of "inputState" to false
  282. *
  283. * @method rdr_registerUp
  284. * @for renderGlobal
  285. *
  286. *
  287. * @param {Event} e The key up event to be supplied to the function by a key up event
  288. * listener on the web page
  289. * @return {Void}
  290. *
  291. */
  292. function rdr_registerUp(e){
  293.  
  294.  
  295. var theKey;
  296. if (e.which == null) {
  297. theKey= String.fromCharCode(e.keyCode) // IE
  298. } else if (e.which!=0 /*&& e.charCode!=0*/) {
  299. theKey= String.fromCharCode(e.which) // the rest
  300. } else {
  301. return;// special key
  302. }
  303. theKey=theKey.toUpperCase();
  304.  
  305.  
  306.  
  307. if(theKey=='A'){
  308. inputState.A=false;
  309. }
  310. if(theKey=='S'){
  311. inputState.S=false;
  312. }
  313. if(theKey=='D'){
  314. inputState.D=false;
  315. }
  316. if(theKey=='W'){
  317. inputState.W=false;
  318. }
  319. if(theKey==' '){
  320. inputState.Space=false;
  321. }
  322. if(theKey=='Q'){
  323. inputState.Q=false;
  324. }
  325. if(theKey=='E'){
  326. inputState.E=false;
  327. }
  328. if(theKey=='R'){
  329. inputState.R=false;
  330. }
  331. if(theKey=='F'){
  332. inputState.F=false;
  333. }
  334. return;
  335.  
  336. }
  337.  
  338.  
  339. // Affects the state of the camera/animation based off of the state of the inputs
  340. /**
  341. *
  342. * Once called, interprets the current state of registered inputs and manipulates
  343. * the visualization accordingly, including the accelleration of the camera, as
  344. * affected by the W,S,A, and D keys, and the rotation of the camera if the F key
  345. * is depressed and there currently is a highlighted object of interest
  346. *
  347. * @method rdr_manageControls
  348. * @for renderGlobal
  349. * @return {Void}
  350. *
  351. */
  352. function rdr_manageControls(){
  353.  
  354. // Set up rotation and relative position deltas
  355. var theRot= new THREE.Quaternion(0,0,0,0);
  356. theRot.setFromEuler(camera.rotation);
  357. var theDir= new THREE.Vector3(0,0,0);
  358.  
  359.  
  360. //
  361. if(inputState.A==true){
  362. theDir.x-=1;
  363. }
  364. if(inputState.S==true){
  365. theDir.z+=1;
  366. }
  367. if(inputState.D==true){
  368. theDir.x+=1;
  369. }
  370. if(inputState.W==true){
  371. theDir.z-=1;
  372. }
  373. if(inputState.Space==true && inputState.switchPrimed==true){
  374. inputState.switchPrimed = false;
  375. treequenceActive = !treequenceActive;
  376. }
  377. if(inputState.Space==false){
  378. inputState.switchPrimed = true;
  379. }
  380. if(inputState.Q==true){
  381. momentum.y-=1;
  382. }
  383. if(inputState.E==true){
  384. momentum.y+=1;
  385. }
  386. if(inputState.R==true){
  387. theTime=0;
  388. }
  389.  
  390. if(theDir.length()>0.1){
  391.  
  392. if(theBoost<boostLim){
  393.  
  394. theBoost+=boostInc;
  395.  
  396. }
  397. else{
  398.  
  399. theBoost=boostLim;
  400.  
  401. }
  402.  
  403. }
  404. else{
  405.  
  406. theBoost=1;
  407.  
  408. }
  409.  
  410. theDir.applyQuaternion(theRot);
  411. theDir.multiplyScalar(theSpeed*theBoost);
  412.  
  413. momentum.x+=theDir.x;
  414. momentum.y+=theDir.y;
  415. momentum.z+=theDir.z;
  416.  
  417. camera.position.x+=momentum.x;
  418. camera.position.y+=momentum.y;
  419. camera.position.z+=momentum.z;
  420.  
  421.  
  422.  
  423.  
  424. if(inputState.F==true){
  425. if(focusPoint==null && objectOfInterest!=null){
  426. focusPoint=objectOfInterest;
  427. }
  428. if(focusPoint!=null){
  429.  
  430. camera.lookAt(getPartCenter(focusPoint));
  431. camPitch=camera.rotation.x;
  432. camYaw=camera.rotation.y;
  433. }
  434. }
  435. else{
  436. if(focusPoint!=null){
  437. focusPoint.Mesh.material= getStdMaterial();
  438. focusPoint=null;
  439. }
  440. }
  441.  
  442. if(focusPoint==null){
  443. camera.rotation.x=camPitch;
  444. camera.rotation.y=camYaw;
  445. }
  446.  
  447.  
  448. }
  449.  
  450.  
  451.  
  452.  
  453.  
  454.  
  455.  
  456. /**
  457. *
  458. * Accepts a string and outputs the string of all characters following the final '.' symbol
  459. * in the string. This is used internally to extract file extensions from file names.
  460. *
  461. * @method rdr_grabExtension
  462. * @for renderGlobal
  463. * @param {String} theName The file name to be processed
  464. * @return {String} the extension in the given file name. If no extension is found, the
  465. * 'undefined' value is returned.
  466. *
  467. */
  468. function rdr_grabExtension(theName){
  469. return (/[.]/.exec(theName)) ? /[^.]+$/.exec(theName) : undefined;
  470. }
  471.  
  472. // Returns from the given list of file readers those that have not completed loading
  473. function rdr_whoIsLeft(theReaders){
  474.  
  475. var pos=0;
  476. var lim=fileReaders.length;
  477. var theList=[];
  478. while(pos<lim){
  479. if(theReaders[pos].Reader.readyState!=2){
  480. theList.push(theReaders[pos].Name);
  481. }
  482. pos++;
  483. }
  484. console.log(theList);
  485.  
  486. }
  487.  
  488.  
  489.  
  490.  
  491. /**
  492. *
  493. * Called internally by "loadParts". Parses the text stored in "theXML" into a tree
  494. * structure composed of nested javascript objects and converts that structure into a
  495. * series of keyframe arrays, each of which are stored alongside their respective
  496. * parts in "partFrames". Additionally, generates the path lines for each subassembly
  497. * and inserts those lines into "scene".
  498. *
  499. * @method rdr_renderParts
  500. * @for renderGlobal
  501. * @return {Void}
  502. *
  503. */
  504. function rdr_renderParts(){
  505.  
  506.  
  507. theXML = inText;
  508. // Cuts of the common first characters from all the part names
  509. cutoffPartNames(parts);
  510.  
  511. // Parses in the xml of the treequence
  512. //console.log(theXML);
  513. var treeQ = $.parseXML(theXML);
  514. console.log(treeQ);
  515. treeQ=grab(treeQ,"AssemblyCandidate");
  516. //console.log(treeQ);
  517. treeQ=grab(treeQ,"Sequence");
  518. //console.log(treeQ);
  519. treeQ=grab(treeQ,"Subassemblies");
  520. //console.log(treeQ);
  521. treeQ=grab(treeQ,"SubAssembly");
  522.  
  523. // Turns the treequence into a tree storing the movement data of each subassembly
  524. console.log(treeQ);
  525. var moveTree=getMovement(treeQ,0,0,0,new THREE.Vector3(0,0,0),0);
  526. console.log(moveTree);
  527.  
  528. // Cuts off the common first characters of all the part names in the tree
  529. cutOffNames(moveTree,similarityCutoff(getNameList(moveTree)));
  530. //console.log(moveTree);
  531. //printAllNames(parts,moveTree);
  532.  
  533. // Makes a series of keyframes for each part for evaluation in the animation
  534. var theFrameLists=makeKeyFrames(moveTree,[],[]);
  535. timeAdjustment = addCurveKeyFrames( theFrameLists, new THREE.Vector3 ( 1000,1000,1000 ) );
  536. //bumpTreeTimes(moveTree,10*timeAdjustment);
  537. //console.log(theFrameLists);
  538. //console.log(parts);
  539.  
  540. // Links each key frame list object to the appropriate part object
  541. partFrames= bindPartsToKeyFrames(theFrameLists,parts);
  542. //console.log(partFrames.length.toString());
  543. //console.log(partFrames.length.toString());
  544. //console.log(partFrames);
  545. //showFrames(theFrameLists);
  546.  
  547. // Zeroes the time, for obvious reasons
  548. theTime=0;
  549.  
  550. // Adds the movement trace lines to the scene
  551. addLines(moveTree,null,scene,false);
  552.  
  553. // Stores the movement tree for later use
  554. movementTree=moveTree;
  555.  
  556. // Mirrors the time measurements at each keyfram to turn the dissassembly into
  557. // an assembly animation
  558. flipTreeTime(movementTree,getLongestTime(movementTree));
  559. //console.log(partFrames.length.toString());
  560. addDisplacement(movementTree, partFrames, 0);
  561.  
  562. // Populates the treequence graphic
  563. document.getElementById("treequenceDiv").classList.add("refBranch");
  564. insertTreequenceHTML(movementTree,document.getElementById("treequenceDiv"));
  565. rdr_showHideTreequence();
  566.  
  567. // Fixes a minor thing in the treequence graphic
  568. getChildrenByTag(document.getElementById("treequenceDiv"),"BUTTON")[0].innerHTML="+";
  569. getChildrenByTag(document.getElementById("treequenceDiv"),"DIV")[0].classList.add("rootNode");
  570. // Begins to display the parts
  571. initAxisLines();
  572.  
  573. alignAssemblyCenter();
  574.  
  575. addGrid(50000,500, -1000, 0x888888);
  576. addGrid(50000,500, 8000, 0x888888);
  577.  
  578. var pos = 0;
  579. while(pos<100){
  580. addCylender(200, -1000, 8000, (pos%10)/10*50000-25000, pos/10/10*50000-25000, 8, 12, 0x888888);
  581. pos++;
  582. }
  583.  
  584. rdr_render();
  585.  
  586. }
  587.  
  588.  
  589.  
  590.  
  591. // Toggles the display of the treequence graphic
  592. /**
  593. *
  594. * Toggles the display of the HTML div element containing the treequence representation of
  595. * the assembly.
  596. *
  597. * @method rdr_showHideTreequence
  598. * @for renderGlobal
  599. * @return {Void}
  600. *
  601. */
  602. function rdr_showHideTreequence(){
  603.  
  604. TDiv=document.getElementById("treequenceDiv");
  605. if(TDiv.state=="shown"){
  606. TDiv.state="notShown";
  607. TDiv.classList.remove("shown");
  608. TDiv.classList.add("hidden");
  609. }
  610. else{
  611. TDiv.state="shown";
  612. TDiv.classList.remove("hidden");
  613. TDiv.classList.add("shown");
  614. }
  615.  
  616. }
  617.  
  618.  
  619.  
  620. startupScripts["7"] = function(){
  621. //
  622. // Pretty Important: Keep this as true unless/until you've incorperated some other
  623. // method of getting file input/output
  624. //
  625. manualFileInput=false;
  626.  
  627.  
  628. if(manualFileInput==true){
  629.  
  630. document.getElementById("HUD").innerHTML="<input type='file' id='fileinput' multiple />"+document.getElementById("HUD").innerHTML;
  631.  
  632. }
  633. // Holder for animation frames for parts
  634. partFrames=null;
  635.  
  636. // Sets the time to 0, for the sake of starting the animation at the right time
  637. theTime=0;
  638.  
  639.  
  640. // Holder for parsed-in javascript objects from the XML document
  641. theTreequence=null;
  642.  
  643. treequenceActive = false;
  644.  
  645.  
  646. timeAdjustment = 0;
  647.  
  648. standard = false;
  649.  
  650.  
  651. // Holds the state of button press inputs to smooth out control response
  652.  
  653.  
  654.  
  655. /**
  656. *
  657. * Contains a representation of the last keyboard events reported by the
  658. * web page for each given key that acts as input for manipulating the
  659. * visulization: 'W','A','S','D','R','F', and the 'Space' key
  660. *
  661. * @element inputState
  662. * @for renderGlobal
  663. * @return {Void}
  664. *
  665. */
  666. inputState={
  667.  
  668. W: false,
  669. A: false,
  670. S: false,
  671. D: false,
  672. R: false,
  673. F: false,
  674. Q: false,
  675. E: false,
  676. Space: false,
  677. switchPrimed: false
  678.  
  679. }
  680.  
  681.  
  682. // The color of the background of the scene
  683. skyColor= 0xFFFFFF;
  684.  
  685. if(standard){
  686. skyColor = 0x000000;
  687. }
  688.  
  689. // The tree structure holding animation data
  690. movementTree=null;
  691. theCenter= new THREE.Vector3(0,0,0);
  692.  
  693. // The part directly in front of the camera, if any such part exists
  694. objectOfInterest=null;
  695.  
  696. // The part being locked onto by using the 'F' key
  697. focusPoint=null;
  698.  
  699. // Name of the part being looked at, if there is any such part
  700. mouseOverText="";
  701.  
  702. // Time dialation coefficeint
  703. zoom=0.2;
  704.  
  705. // Base Accelleration
  706. theSpeed=0.2;
  707.  
  708. // Accelleration bonus variables
  709. theBoost=1; // Initial accelleration bonus
  710. boostLim=25; // Limit to accelleration bonus
  711. boostInc=0.1; // Rate of accelleration bonus increase
  712.  
  713. // Coefficient of drag camera experiences
  714. theDrag=0.96;
  715.  
  716. // Angles of camera
  717. camYaw=0;
  718. camPitch=Math.PI/2;
  719.  
  720. // The momentum of the camera
  721. momentum= new THREE.Vector3(0,0,0);
  722.  
  723.  
  724.  
  725. /**update
  726. *
  727. * The main portion of the visualization's rendering cycle, managing frame rate,
  728. * input, camera decelleration, keyframe manipulation, model animation, object highlighting,
  729. * and informational display.
  730. *
  731. * @method render
  732. * @for renderGlobal
  733. * @return {Void}
  734. *
  735. */
  736. rdr_render = function () {
  737.  
  738. // The function that will manage frame requests
  739. requestAnimationFrame( rdr_render );
  740.  
  741.  
  742.  
  743. // Recieve input and set the appropriate state
  744. rdr_manageControls();
  745.  
  746. // Apply air friction to camera
  747. momentum.multiplyScalar(theDrag);
  748.  
  749.  
  750. // Moves the parts along the appropriate motions of the animation
  751. if(zoom>=0){
  752. theTime=animate(partFrames,theTime,Math.pow(zoom,1.008),treequenceActive);
  753. }
  754. else{
  755. theTime=animate(partFrames,theTime,0-Math.pow(0-zoom,1.008),treequenceActive);
  756. }
  757.  
  758.  
  759. // Reset the appearence of the last object of interest
  760. if(objectOfInterest!=null){
  761. objectOfInterest.Mesh.material=getStdMaterial();
  762. }
  763.  
  764. // Get the first part being directly looked at and sets it as object of interest
  765. objectOfInterest=getFirstIntersect(scene,camera,partFrames);
  766.  
  767.  
  768. // Change appearance of the object of interest and display the appropriate information
  769. if(objectOfInterest!==null && standard !== true){
  770.  
  771. mouseOverText=" "+objectOfInterest.Name.substring(0,objectOfInterest.Name.length-4);
  772. objectOfInterest.Mesh.material=new THREE.MeshStandardMaterial({
  773. color:0xbbbbbb,
  774. roughness: 1.0,
  775. metalness: 1.0,
  776. shading: THREE.SmoothShading
  777. } );
  778.  
  779. }
  780. else{
  781.  
  782. mouseOverText="";
  783.  
  784. }
  785.  
  786.  
  787. // Change appearance of the focus point mesh
  788. if(focusPoint!=null && standard !== true){
  789.  
  790. focusPoint.Mesh.material=new THREE.MeshStandardMaterial({
  791. color:0xff6666,
  792. roughness: 1.0,
  793. metalness: 1.0,
  794. shading: THREE.SmoothShading
  795. } );
  796.  
  797. }
  798.  
  799.  
  800. // Display information about the object of interest
  801. document.getElementById("mouseoverName").innerHTML="PART: "+mouseOverText;
  802. document.getElementById("theTime").innerHTML=("TIME: "+ theTime.toFixed(10)).toString();
  803.  
  804. // Update the installation trace lines
  805. updateLines(movementTree,null,theTime-timeAdjustment,false,treequenceActive);
  806.  
  807. updateAxisLines();
  808.  
  809.  
  810. // Call for the render
  811. renderer.render(scene, camera);
  812.  
  813. };
  814.  
  815. camera.position.x=0;
  816. camera.position.z=0;
  817. camera.position.y=0;
  818.  
  819. // The variable holding the state of whether or not the pointer is locked
  820. pointerIsLocked=false;
  821.  
  822. clearScene("theDisplay");
  823.  
  824. // Setting camera to Yaw-Pitch-Roll configuration
  825. camera.rotation.reorder('YXZ');
  826.  
  827.  
  828. theXAxis=null;
  829. theYAxis=null;
  830. theZAxis=null;
  831. xRet=null;
  832. yRet=null;
  833.  
  834.  
  835.  
  836.  
  837. // Adding a whole bunch of event listeners for input
  838. document.getElementById("theDisplay").addEventListener("wheel", rdr_zoomIt);
  839. document.addEventListener('pointerlockchange', rdr_lockChange, false);
  840. document.addEventListener('mozpointerlockchange', rdr_lockChange, false);
  841. document.addEventListener('webkitpointerlockchange', rdr_lockChange, false);
  842. document.addEventListener('keydown', rdr_registerDown , false);
  843. document.addEventListener('keyup', rdr_registerUp , false);
  844.  
  845. rdr_renderParts();
  846.  
  847. }
  848.  
  849. //</script>
  850.