- //<script>
- ;
-
-
-
- if( typeof(startupScripts) == 'undefined'){
-
- var startupScripts = {
- "0":function(){},
- "1":function(){},
- "2":function(){},
- "3":function(){},
- "4":function(){},
- "5":function(){},
- "6":function(){},
- "7":function(){}
- };
-
- }
-
-
-
- /**
- *
- * Class containing all the methods used in the 3d visual assembly
- * @class renderGlobal
- * @static
- */
-
-
-
-
- // Put recieved data about assembly into here. The code handles the rest.
- // theXMLFile should be a string, and theSTLFiles as a binary ArrayBuffer
- // Any text-based STL files should be in an 8-bit encoding
- /**
- *
- * The function which handles the actual rendering of the solution file animation
- * and loading in the models
- *
- * @method rdr_recieveData
- * @for renderGlobal
- * @param {String} theXMLFile
- * @param {Object} theSTLFiles
- * @return {Void}
- *
- */
- function rdr_receiveData(theXMLFile, theSTLFiles){
-
- theXML=theXMLFile;
-
- parts.length=0;
- var pos=0;
- var lim=theSTLFiles.length;
- var partGeom;
- var partMesh;
-
- while(pos<lim){
- partGeom=null;
- partGeom=theSTLFiles[pos];
- if(partGeom===null){
- partGeom=parseStlBinary(fileReaders[pos].Reader.result);
- }
-
- //console.log(partGeom);
-
- partMesh=new THREE.Mesh(
- partGeom,
- new THREE.MeshNormalMaterial( )
- );
- parts.push({
- Mesh: partMesh,
- Name: fileReaders[pos].Name
- })
- scene.add(partMesh);
-
- pos++;
- }
-
- rdr_renderParts();
-
- }
-
-
-
-
-
-
-
-
-
- // Dialates time with the scrolling of the mouse
- function rdr_zoomIt(e){
-
- //zoom=zoom*Math.pow(1.001,e.wheelDelta);
- var theDelta = e.deltaY == 0 ? 0 : ( e.deltaY > 0 ? 1 : -1 );
- zoom+=theDelta*(-1);
-
- }
-
-
- /**
- *
- * Attempts to lock the mouse for camera manupulation
- *
- * @method rdr_tryMouseLock
- * @for renderGlobal
- * @return {Void}
- *
- */
- function rdr_tryMouseLock(){
-
- var element= document.getElementById("theDisplay");
-
- element.requestPointerLock = element.requestPointerLock ||
- element.mozRequestPointerLock ||
- element.webkitRequestPointerLock;
- // Ask the browser to lock the pointer
- element.requestPointerLock();
-
- }
-
-
-
- /**
- *
- * Adds or Removes event listeners for input meant for camera manipulation.
- * Is triggered by a change in the state of the mouse locking or unlocking.
- * The mouse locking results in input listeners being added to the webpage,
- * whereas the unlocking of the mouse results in the removal of appropriate
- * listeners.
- *
- * @method rdr_lockChange
- * @for renderGlobal
- *
- *
- * @param {Event} e The event that is to be applied to the function by event listeners upon
- * a change in the state of mouselock
- * @return {Void}
- *
- *
- */
- function rdr_lockChange(e){
-
- var theTarget=document.getElementById("theDisplay");
- if (document.pointerLockElement === theTarget ||
- document.mozPointerLockElement === theTarget ||
- document.webkitPointerLockElement === theTarget) {
- // Pointer was just locked
- // Enable the mousemove listener
- document.addEventListener("mousemove", rdr_mouseMoved, false);
- pointerIsLocked=true;
- }
- else {
- // Pointer was just unlocked
- // Disable the mousemove listener
- document.removeEventListener("mousemove", rdr_mouseMoved, false);
- pointerIsLocked=false;
- }
-
- }
-
-
-
- /**
- *
- * Changes the orientation of the camera based off of the mouse movement
- * contained in the supplied mouse movement event. X-axis movement
- * corresponds to change in the yaw of the camera whereas Y-axis movement
- * corresponds to a change in the pitch of the camera.
- *
- * @method rdr_mouseMoved
- * @for renderGlobal
- *
- * @param {Event} e The mouse movement event to be supplied to the function by a mouse
- * movement event listener on the web page
- * @return {Void}
- *
- */
- function rdr_mouseMoved(e){
-
- var movementX = e.movementX ||
- e.mozMovementX ||
- e.webkitMovementX ||
- 0;
- var movementY = e.movementY ||
- e.mozMovementY ||
- e.webkitMovementY ||
- 0;
-
- camPitch-=movementY/400;
- if(camPitch> Math.PI/2){
- camPitch= Math.PI/2;
- }
- else if(camPitch< Math.PI/(-2)){
- camPitch= Math.PI/(-2)
- }
-
- camYaw-=movementX/400;
- if(camPitch> Math.PI){
- camPitch= Math.PI;
- }
- else if(camPitch< Math.PI*(-1)){
- camPitch= Math.PI*(-1);
- }
-
- }
-
-
-
- // Changes key press states based off of key presses
- /**
- *
- * Accepts a key press event and, if the key press corresponds to one
- * of the keys used for manipulating the view, sets the proper components
- * of "inputState" to true.
- *
- * @method rdr_registerDown
- * @for renderGlobal
- *
- *
- * @param {Event} e The key down event to be supplied to the function by a key down event
- * listener on the web page
- * @return {Void}
- *
- */
- function rdr_registerDown(e){
-
-
-
- var theKey;
- if (e.which == null) {
- theKey= String.fromCharCode(e.keyCode) // IE
- } else if (e.which!=0 /*&& e.charCode!=0*/) {
- theKey= String.fromCharCode(e.which) // the rest
- } else {
- return;// special key
- }
- theKey=theKey.toUpperCase();
-
-
-
- if(theKey=='A'){
- inputState.A=true;
- }
- if(theKey=='S'){
- inputState.S=true;
- }
- if(theKey=='D'){
- inputState.D=true;
- }
- if(theKey=='W'){
- inputState.W=true;
- }
- if(theKey==' '){
- inputState.Space=false;
- }
- if(theKey=='Q'){
- inputState.Q=true;
- }
- if(theKey=='E'){
- inputState.E=true;
- }
- if(theKey=='R'){
- inputState.R=true;
- }
- if(theKey=='F'){
- inputState.F=true;
- }
- return;
-
- }
-
-
-
-
- /**
- *
- * Accepts a key press release and, if the key release corresponds to one
- * of the keys used for manipulating the view, sets the proper components
- * of "inputState" to false
- *
- * @method rdr_registerUp
- * @for renderGlobal
- *
- *
- * @param {Event} e The key up event to be supplied to the function by a key up event
- * listener on the web page
- * @return {Void}
- *
- */
- function rdr_registerUp(e){
-
-
- var theKey;
- if (e.which == null) {
- theKey= String.fromCharCode(e.keyCode) // IE
- } else if (e.which!=0 /*&& e.charCode!=0*/) {
- theKey= String.fromCharCode(e.which) // the rest
- } else {
- return;// special key
- }
- theKey=theKey.toUpperCase();
-
-
-
- if(theKey=='A'){
- inputState.A=false;
- }
- if(theKey=='S'){
- inputState.S=false;
- }
- if(theKey=='D'){
- inputState.D=false;
- }
- if(theKey=='W'){
- inputState.W=false;
- }
- if(theKey==' '){
- inputState.Space=false;
- }
- if(theKey=='Q'){
- inputState.Q=false;
- }
- if(theKey=='E'){
- inputState.E=false;
- }
- if(theKey=='R'){
- inputState.R=false;
- }
- if(theKey=='F'){
- inputState.F=false;
- }
- return;
-
- }
-
-
- // Affects the state of the camera/animation based off of the state of the inputs
- /**
- *
- * Once called, interprets the current state of registered inputs and manipulates
- * the visualization accordingly, including the accelleration of the camera, as
- * affected by the W,S,A, and D keys, and the rotation of the camera if the F key
- * is depressed and there currently is a highlighted object of interest
- *
- * @method rdr_manageControls
- * @for renderGlobal
- * @return {Void}
- *
- */
- function rdr_manageControls(){
-
- // Set up rotation and relative position deltas
- var theRot= new THREE.Quaternion(0,0,0,0);
- theRot.setFromEuler(camera.rotation);
- var theDir= new THREE.Vector3(0,0,0);
-
-
- //
- if(inputState.A==true){
- theDir.x-=1;
- }
- if(inputState.S==true){
- theDir.z+=1;
- }
- if(inputState.D==true){
- theDir.x+=1;
- }
- if(inputState.W==true){
- theDir.z-=1;
- }
- if(inputState.Space==true && inputState.switchPrimed==true){
- inputState.switchPrimed = false;
- treequenceActive = !treequenceActive;
- }
- if(inputState.Space==false){
- inputState.switchPrimed = true;
- }
- if(inputState.Q==true){
- momentum.y-=1;
- }
- if(inputState.E==true){
- momentum.y+=1;
- }
- if(inputState.R==true){
- theTime=0;
- }
-
- if(theDir.length()>0.1){
-
- if(theBoost<boostLim){
-
- theBoost+=boostInc;
-
- }
- else{
-
- theBoost=boostLim;
-
- }
-
- }
- else{
-
- theBoost=1;
-
- }
-
- theDir.applyQuaternion(theRot);
- theDir.multiplyScalar(theSpeed*theBoost);
-
- momentum.x+=theDir.x;
- momentum.y+=theDir.y;
- momentum.z+=theDir.z;
-
- camera.position.x+=momentum.x;
- camera.position.y+=momentum.y;
- camera.position.z+=momentum.z;
-
-
-
-
- if(inputState.F==true){
- if(focusPoint==null && objectOfInterest!=null){
- focusPoint=objectOfInterest;
- }
- if(focusPoint!=null){
-
- camera.lookAt(getPartCenter(focusPoint));
- camPitch=camera.rotation.x;
- camYaw=camera.rotation.y;
- }
- }
- else{
- if(focusPoint!=null){
- focusPoint.Mesh.material= getStdMaterial();
- focusPoint=null;
- }
- }
-
- if(focusPoint==null){
- camera.rotation.x=camPitch;
- camera.rotation.y=camYaw;
- }
-
-
- }
-
-
-
-
-
-
-
- /**
- *
- * Accepts a string and outputs the string of all characters following the final '.' symbol
- * in the string. This is used internally to extract file extensions from file names.
- *
- * @method rdr_grabExtension
- * @for renderGlobal
- * @param {String} theName The file name to be processed
- * @return {String} the extension in the given file name. If no extension is found, the
- * 'undefined' value is returned.
- *
- */
- function rdr_grabExtension(theName){
- return (/[.]/.exec(theName)) ? /[^.]+$/.exec(theName) : undefined;
- }
-
- // Returns from the given list of file readers those that have not completed loading
- function rdr_whoIsLeft(theReaders){
-
- var pos=0;
- var lim=fileReaders.length;
- var theList=[];
- while(pos<lim){
- if(theReaders[pos].Reader.readyState!=2){
- theList.push(theReaders[pos].Name);
- }
- pos++;
- }
- console.log(theList);
-
- }
-
-
-
-
- /**
- *
- * Called internally by "loadParts". Parses the text stored in "theXML" into a tree
- * structure composed of nested javascript objects and converts that structure into a
- * series of keyframe arrays, each of which are stored alongside their respective
- * parts in "partFrames". Additionally, generates the path lines for each subassembly
- * and inserts those lines into "scene".
- *
- * @method rdr_renderParts
- * @for renderGlobal
- * @return {Void}
- *
- */
- function rdr_renderParts(){
-
-
- theXML = inText;
- // Cuts of the common first characters from all the part names
- cutoffPartNames(parts);
-
- // Parses in the xml of the treequence
- //console.log(theXML);
- var treeQ = $.parseXML(theXML);
- console.log(treeQ);
- treeQ=grab(treeQ,"AssemblyCandidate");
- //console.log(treeQ);
- treeQ=grab(treeQ,"Sequence");
- //console.log(treeQ);
- treeQ=grab(treeQ,"Subassemblies");
- //console.log(treeQ);
- treeQ=grab(treeQ,"SubAssembly");
-
- // Turns the treequence into a tree storing the movement data of each subassembly
- console.log(treeQ);
- var moveTree=getMovement(treeQ,0,0,0,new THREE.Vector3(0,0,0),0);
- console.log(moveTree);
-
- // Cuts off the common first characters of all the part names in the tree
- cutOffNames(moveTree,similarityCutoff(getNameList(moveTree)));
- //console.log(moveTree);
- //printAllNames(parts,moveTree);
-
- // Makes a series of keyframes for each part for evaluation in the animation
- var theFrameLists=makeKeyFrames(moveTree,[],[]);
- timeAdjustment = addCurveKeyFrames( theFrameLists, new THREE.Vector3 ( 1000,1000,1000 ) );
- //bumpTreeTimes(moveTree,10*timeAdjustment);
- //console.log(theFrameLists);
- //console.log(parts);
-
- // Links each key frame list object to the appropriate part object
- partFrames= bindPartsToKeyFrames(theFrameLists,parts);
- //console.log(partFrames.length.toString());
- //console.log(partFrames.length.toString());
- //console.log(partFrames);
- //showFrames(theFrameLists);
-
- // Zeroes the time, for obvious reasons
- theTime=0;
-
- // Adds the movement trace lines to the scene
- addLines(moveTree,null,scene,false);
-
- // Stores the movement tree for later use
- movementTree=moveTree;
-
- // Mirrors the time measurements at each keyfram to turn the dissassembly into
- // an assembly animation
- flipTreeTime(movementTree,getLongestTime(movementTree));
- //console.log(partFrames.length.toString());
- addDisplacement(movementTree, partFrames, 0);
-
- // Populates the treequence graphic
- document.getElementById("treequenceDiv").classList.add("refBranch");
- insertTreequenceHTML(movementTree,document.getElementById("treequenceDiv"));
- rdr_showHideTreequence();
-
- // Fixes a minor thing in the treequence graphic
- getChildrenByTag(document.getElementById("treequenceDiv"),"BUTTON")[0].innerHTML="+";
- getChildrenByTag(document.getElementById("treequenceDiv"),"DIV")[0].classList.add("rootNode");
- // Begins to display the parts
- initAxisLines();
-
- alignAssemblyCenter();
-
- addGrid(50000,500, -1000, 0x888888);
- addGrid(50000,500, 8000, 0x888888);
-
- var pos = 0;
- while(pos<100){
- addCylender(200, -1000, 8000, (pos%10)/10*50000-25000, pos/10/10*50000-25000, 8, 12, 0x888888);
- pos++;
- }
-
- rdr_render();
-
- }
-
-
-
-
- // Toggles the display of the treequence graphic
- /**
- *
- * Toggles the display of the HTML div element containing the treequence representation of
- * the assembly.
- *
- * @method rdr_showHideTreequence
- * @for renderGlobal
- * @return {Void}
- *
- */
- function rdr_showHideTreequence(){
-
- TDiv=document.getElementById("treequenceDiv");
- if(TDiv.state=="shown"){
- TDiv.state="notShown";
- TDiv.classList.remove("shown");
- TDiv.classList.add("hidden");
- }
- else{
- TDiv.state="shown";
- TDiv.classList.remove("hidden");
- TDiv.classList.add("shown");
- }
-
- }
-
-
-
- startupScripts["7"] = function(){
- //
- // Pretty Important: Keep this as true unless/until you've incorperated some other
- // method of getting file input/output
- //
- manualFileInput=false;
-
-
- if(manualFileInput==true){
-
- document.getElementById("HUD").innerHTML="<input type='file' id='fileinput' multiple />"+document.getElementById("HUD").innerHTML;
-
- }
- // Holder for animation frames for parts
- partFrames=null;
-
- // Sets the time to 0, for the sake of starting the animation at the right time
- theTime=0;
-
-
- // Holder for parsed-in javascript objects from the XML document
- theTreequence=null;
-
- treequenceActive = false;
-
-
- timeAdjustment = 0;
-
- standard = false;
-
-
- // Holds the state of button press inputs to smooth out control response
-
-
-
- /**
- *
- * Contains a representation of the last keyboard events reported by the
- * web page for each given key that acts as input for manipulating the
- * visulization: 'W','A','S','D','R','F', and the 'Space' key
- *
- * @element inputState
- * @for renderGlobal
- * @return {Void}
- *
- */
- inputState={
-
- W: false,
- A: false,
- S: false,
- D: false,
- R: false,
- F: false,
- Q: false,
- E: false,
- Space: false,
- switchPrimed: false
-
- }
-
-
- // The color of the background of the scene
- skyColor= 0xFFFFFF;
-
- if(standard){
- skyColor = 0x000000;
- }
-
- // The tree structure holding animation data
- movementTree=null;
- theCenter= new THREE.Vector3(0,0,0);
-
- // The part directly in front of the camera, if any such part exists
- objectOfInterest=null;
-
- // The part being locked onto by using the 'F' key
- focusPoint=null;
-
- // Name of the part being looked at, if there is any such part
- mouseOverText="";
-
- // Time dialation coefficeint
- zoom=0.2;
-
- // Base Accelleration
- theSpeed=0.2;
-
- // Accelleration bonus variables
- theBoost=1; // Initial accelleration bonus
- boostLim=25; // Limit to accelleration bonus
- boostInc=0.1; // Rate of accelleration bonus increase
-
- // Coefficient of drag camera experiences
- theDrag=0.96;
-
- // Angles of camera
- camYaw=0;
- camPitch=Math.PI/2;
-
- // The momentum of the camera
- momentum= new THREE.Vector3(0,0,0);
-
-
-
- /**update
- *
- * The main portion of the visualization's rendering cycle, managing frame rate,
- * input, camera decelleration, keyframe manipulation, model animation, object highlighting,
- * and informational display.
- *
- * @method render
- * @for renderGlobal
- * @return {Void}
- *
- */
- rdr_render = function () {
-
- // The function that will manage frame requests
- requestAnimationFrame( rdr_render );
-
-
-
- // Recieve input and set the appropriate state
- rdr_manageControls();
-
- // Apply air friction to camera
- momentum.multiplyScalar(theDrag);
-
-
- // Moves the parts along the appropriate motions of the animation
- if(zoom>=0){
- theTime=animate(partFrames,theTime,Math.pow(zoom,1.008),treequenceActive);
- }
- else{
- theTime=animate(partFrames,theTime,0-Math.pow(0-zoom,1.008),treequenceActive);
- }
-
-
- // Reset the appearence of the last object of interest
- if(objectOfInterest!=null){
- objectOfInterest.Mesh.material=getStdMaterial();
- }
-
- // Get the first part being directly looked at and sets it as object of interest
- objectOfInterest=getFirstIntersect(scene,camera,partFrames);
-
-
- // Change appearance of the object of interest and display the appropriate information
- if(objectOfInterest!==null && standard !== true){
-
- mouseOverText=" "+objectOfInterest.Name.substring(0,objectOfInterest.Name.length-4);
- objectOfInterest.Mesh.material=new THREE.MeshStandardMaterial({
- color:0xbbbbbb,
- roughness: 1.0,
- metalness: 1.0,
- shading: THREE.SmoothShading
- } );
-
- }
- else{
-
- mouseOverText="";
-
- }
-
-
- // Change appearance of the focus point mesh
- if(focusPoint!=null && standard !== true){
-
- focusPoint.Mesh.material=new THREE.MeshStandardMaterial({
- color:0xff6666,
- roughness: 1.0,
- metalness: 1.0,
- shading: THREE.SmoothShading
- } );
-
- }
-
-
- // Display information about the object of interest
- document.getElementById("mouseoverName").innerHTML="PART: "+mouseOverText;
- document.getElementById("theTime").innerHTML=("TIME: "+ theTime.toFixed(10)).toString();
-
- // Update the installation trace lines
- updateLines(movementTree,null,theTime-timeAdjustment,false,treequenceActive);
-
- updateAxisLines();
-
-
- // Call for the render
- renderer.render(scene, camera);
-
- };
-
- camera.position.x=0;
- camera.position.z=0;
- camera.position.y=0;
-
- // The variable holding the state of whether or not the pointer is locked
- pointerIsLocked=false;
-
- clearScene("theDisplay");
-
- // Setting camera to Yaw-Pitch-Roll configuration
- camera.rotation.reorder('YXZ');
-
-
- theXAxis=null;
- theYAxis=null;
- theZAxis=null;
- xRet=null;
- yRet=null;
-
-
-
-
- // Adding a whole bunch of event listeners for input
- document.getElementById("theDisplay").addEventListener("wheel", rdr_zoomIt);
- document.addEventListener('pointerlockchange', rdr_lockChange, false);
- document.addEventListener('mozpointerlockchange', rdr_lockChange, false);
- document.addEventListener('webkitpointerlockchange', rdr_lockChange, false);
- document.addEventListener('keydown', rdr_registerDown , false);
- document.addEventListener('keyup', rdr_registerUp , false);
-
- rdr_renderParts();
-
- }
-
- //</script>
-
-