| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370 |
- /********************************************************************
- * Parameters used all along the script. Only for *
- * customization. *
- ********************************************************************/
- var backColor = "rgba(200, 200, 200, 1)";
- var vertColor = "rgba(10, 10, 10, 1)";
- var edgeColor = "rgba(100, 70, 70, 1)";
- var faceColor = "rgba(180, 180, 255, .6)";
- var textColor = "rgba(0, 0, 0, 1)";
- var vertSize = 4; //Make it even: at small scales will look better
- var rotationSpeed = 100; //Smaller = faster. 100 is a good speed
- /********************************************************************
- * Parameters used to scale the measures in the .obj file. Can be *
- * integer or float, greater than 0 *
- * TODO: Must be automatically calculated according to the canvas *
- * dimensions, so the bigest dimension from the object can fit in *
- * the smallest dimension of the canvas. *
- ********************************************************************/
- var scale;// = 50;
- /********************************************************************
- * Global variable to determine if the mouse button is being holded *
- * down. *
- ********************************************************************/
- var mDown = false;
- /********************************************************************
- * Global variables containing the canvas and its context. *
- ********************************************************************/
- var canvas;
- var ctx;
- /********************************************************************
- * Global variables containing the number of elements. *
- ********************************************************************/
- var totalVert;
- var totalEdge;//TODO: I dont know how to calculate
- var totalFace
- /********************************************************************
- * Arrays containing the vertices, edges and faces. *
- ********************************************************************/
- var obj; //Unused
- var vert;
- var face;
- /********************************************************************
- * Array containing the order the veres and faces. *
- ********************************************************************/
- var order;
- /********************************************************************
- * Booleans to determine wich elements are to draw. *
- ********************************************************************/
- var dVerts = true;
- var dEdges = true;
- var dFaces = true;
- /********************************************************************
- * Global variables that will contain the position of the mouse in *
- * the previous frame to calculate rotation. *
- ********************************************************************/
- var pX = null;
- var pY = null;
- /********************************************************************
- * Function switching the elements to draw (dVerts, dEdges, dFaces) *
- * #parameters: *
- * name (string): key to the element to draw. *
- * value (boolean): indicating if the element is to be drawn. *
- * #return: nothing *
- ********************************************************************/
- function drawElement(name, value){
- switch (name){
- case "verts":
- dVerts = value;
- break;
- case "edges":
- dEdges = value;
- break;
- case "faces":
- dFaces = value;
- break;
- }
- draw();
- }
- /********************************************************************
- * Main function, called every time a file is to be loaded. *
- * #parameters: *
- * val (string): name of the file, without path or extension. *
- * #return: nothing *
- ********************************************************************/
- function loadModel(val){
- //Get file
- xmlhttp = new XMLHttpRequest();
- xmlhttp.open("GET","/obj/" + val.value + ".obj", false);
- xmlhttp.send();
- var fileContent = xmlhttp.responseText;
- initArrays();
- if (canvas == null)
- initCanvas();
- readVerts(fileContent);
- readFaces(fileContent);
- draw();
- }
- /********************************************************************
- * Function initializing the arrays obj, vert and face as empty *
- * arrays. *
- * #parameters: none *
- * #return: nothing *
- ********************************************************************/
- function initArrays(){
- obj = null;
- vert = null;
- face = null;
- obj = new Array();
- vert = new Array();
- face = new Array();
- }
- /********************************************************************
- * Function tat populates the vert[] array with and array of three *
- * elements, containig the coordinates, with the scale applied. *
- * #parameters: *
- * text (string): the content of the obj file. *
- * #return: nothing *
- ********************************************************************/
- function readVerts(text){
- var line;
- var i = 0;
- var max = 0;
- var dist;
- while (text.indexOf("v ") != -1){
- line = text.substring(text.indexOf("v "), text.indexOf("\n", text.indexOf("v ")));
- vert[i] = new Array(3);
- line = line.substring(2);
- vert[i][0] = line.substring(0, line.indexOf(" "));
- line = line.substring(line.indexOf(" ") + 1);
- vert[i][1] = line.substring(0, line.indexOf(" "));
- line = line.substring(line.indexOf(" ") + 1);
- vert[i][2] = line;
- text = text.substring(text.indexOf("v ") + 1)
- dist = Math.sqrt(vert[i][0] * vert[i][0] + vert[i][1] * vert[i][1] + vert[i][2] * vert[i][2]);
- if (dist > max)
- max = dist;
- i = i + 1;
- }
- scale = calculateScale(max);
- totalVert = vert.length;
- }
- /********************************************************************
- * Function that automatically calculates the best scale for the *
- * modelermined number of elements, containing the verices that *
- * form a face, so the bigest dimension from the object can fit in *
- * the smallest dimension of the canvas. *
- * #parameters: *
- * text (int): the farthest vertex, from the center. *
- * #return: (int) The scale to be aplied. *
- ********************************************************************/
- function calculateScale(max){
- var dim;
- if (canvas.width < canvas.height)
- dim = canvas.width;
- else
- dim = canvas.height;
- var sc = Math.round((0.95 * dim) / (2 * max));
- return sc;
- }
- /********************************************************************
- * Function that populates the face[] array with and array of an *
- * undetermined number of elements, containing the verices that *
- * form a face. *
- * #parameters: *
- * text (string): the content of the obj file. *
- * #return: nothing *
- ********************************************************************/
- function readFaces(text){
- var finish = false;
- var line;
- var i = 0;
- var j;
- while (text.indexOf("f ") != -1){
- line = text.substring(text.indexOf("f "), text.indexOf("\n", text.indexOf("f ")));
- line = line.substring(2);
- face[i] = new Array();
- j = 0;
- while(line.indexOf(" ") != -1){
- face[i][j] = line.substring(0, line.indexOf(" ")) - 1;
- line = line.substring(line.indexOf(" ") + 1);
- j = j + 1;
- }
- face[i][j] = line - 1;
- i = i + 1;
- text = text.substring(text.indexOf("f ") + 1)
- }
- totalFace = face.length;
- }
- /********************************************************************
- * Function that compares the average Z coordinate of two faces. *
- * Must be used when sorting the face array. *
- * #parameters: *
- * a (Array): One face. *
- * b (Array): The other face. *
- * #return: (int) -1, 1 or 0. *
- ********************************************************************/
- function faceComparator(a,b){
- var aZ;
- var bZ;
- var i = 0;
- var sum = 0.0;
- while (i < a.length){
- sum = sum + parseFloat(vert[a[i]][2]);
- i = i + 1;
- }
- aZ = sum / parseFloat(i);
- i = 0;
- sum = 0;
- while (i < b.length){
- sum = sum + parseFloat(1 * vert[b[i]][2]);
- i = i + 1;
- }
- bZ = sum / parseFloat(i);
- if (aZ < bZ) return -1;
- if (aZ > bZ) return 1;
- return 0;
- }
- /********************************************************************
- * Function that writes text in the corner of the canvas. Must be *
- * called when everithing has been drawn. *
- * #parameters: none *
- * #return: nothing *
- ********************************************************************/
- function writeCredits(){
- ctx.fillStyle = textColor;
- ctx.font = "12px Arial";
- var h = canvas.height / 2 - 14;
- var w = 10 - (canvas.height / 2);
- ctx.fillText("ObJS " + totalVert + " vertizes " + totalFace + " faces", w, h);
- }
- /********************************************************************
- * Function that draws th vertizes, faces and edges in the canvas. *
- * #parameters: none *
- * #return: nothing *
- ********************************************************************/
- function draw(){
- face = face.sort(faceComparator).reverse();
- clearCanvas();
- for (var i = 0; i < face.length; i++){
- ctx.strokeStyle = edgeColor;
- ctx.fillStyle = vertColor;
- ctx.beginPath();
- ctx.moveTo(scale * vert[face[i][0]][0], scale * vert[face[i][0]][1]);
- for (var j = 1; j < face[i].length; j++) {
- ctx.lineTo(scale * vert[face[i][j]][0], scale * vert[face[i][j]][1]);
- if(dEdges)
- ctx.stroke();
- if(dVerts){
- var x = scale * vert[face[i][j]][0] - (vertSize / 2);
- var w = vertSize;
- var y = scale * vert[face[i][j]][1] - (vertSize / 2);
- var h = vertSize;
- ctx.fillRect(x, y, w, h);
- }
- }
- ctx.closePath();
- ctx.fillStyle = faceColor;
- if(dFaces)
- ctx.fill();
- }
- writeCredits();
- }
- /********************************************************************
- * Function that rotates elements in the canvas along the Y axis, *
- * calculating the new position for each vertex in the vert array. *
- * #parameters: *
- * des (int): mouse displacement from the last frame. *
- * #return: nothing *
- ********************************************************************/
- function rotateY(des) {
- for (var i = 0; i < vert.length; i ++) {
- var x = vert[i][0];
- var z = vert[i][2];
- vert[i][0] = x * Math.cos(des / rotationSpeed) - z * Math.sin(des / rotationSpeed);
- vert[i][2] = z * Math.cos(des / rotationSpeed) + x * Math.sin(des / rotationSpeed);
- }
- };
- /********************************************************************
- * Function that rotates elements in the canvas along the X axis, *
- * calculating the new position for each vertex in the vert array. *
- * #parameters: *
- * des (int): mouse displacement from the last frame. *
- * #return: nothing *
- ********************************************************************/
- function rotateX(des) {
- for (var i = 0; i < vert.length; i ++) {
- var y = vert[i][1];
- var z = vert[i][2];
- vert[i][1] = y * Math.cos(des / rotationSpeed) - z * Math.sin(des / rotationSpeed);
- vert[i][2] = z * Math.cos(des / rotationSpeed) + y * Math.sin(des / rotationSpeed);
- }
- };
- /********************************************************************
- * Function that initializes the canvas, assignin it to the HTML *
- * element, and set the required mouse events. *
- * #parameters: none *
- * #return: nothing *
- ********************************************************************/
- function initCanvas(){
- canvas = document.getElementById("ObJSCanvas");
- ctx = canvas.getContext("2d");
- ctx.translate(canvas.width / 2, canvas.height / 2);
-
- canvas.onmousedown = function(e){
- pX = e.offsetX==undefined?e.layerX:e.offsetX;
- pY = e.offsetY==undefined?e.layerY:e.offsetY;
- mDown = true;
- }
-
- canvas.onmouseup = function(e){
- if(mDown)
- mouseClick(e);
- pX = null;
- pY = null;
- mDown = false;
- }
-
- canvas.onmousemove = function(e){
- if(!mDown)
- return;
- var x = e.offsetX==undefined?e.layerX:e.offsetX;
- var y = e.offsetY==undefined?e.layerY:e.offsetY;
- rotateY(x - pX);
- rotateX(y - pY);
- pX = x;
- pY = y;
- draw();
- return false;
- }
- }
- /********************************************************************
- * Function that clears the canvas and gets it ready to draw on it. *
- * #parameters: none *
- * #return: nothing *
- ********************************************************************/
- function clearCanvas(){
- ctx.clearRect(0, 0, canvas.width, canvas.height);
-
- ctx.fillStyle = backColor;
- ctx.fillRect(-canvas.width / 2, -canvas.height / 2, canvas.width, canvas.height);
- }
- /********************************************************************
- * TODO: Function used when something in the canvas is clicked. *
- * #parameters: none *
- * #return: nothing *
- ********************************************************************/
- function mouseClick(){
- }
|