ObJS.js 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749
  1. /********************************************************************
  2. * The ObJS objectnitializes the canvas, assignin it to the HTML *
  3. * element, and set the required mouse events. *
  4. * #parameters: none *
  5. * #return: nothing *
  6. ********************************************************************/
  7. function ObJS(){
  8. /********************************************************************
  9. * Parameters for costumization. *
  10. ********************************************************************/
  11. var backColor = "rgba(200, 200, 200, 1)";
  12. var vertColor = "rgba(10, 10, 10, 1)";
  13. var edgeColor = "rgba(100, 70, 70, 1)";
  14. var faceColor = "rgba(180, 180, 255, .6)";
  15. var faceAlpha = .6;
  16. var textColor = "rgba(0, 0, 0, 1)";
  17. var vertSize = 4; //Make it even: at small scales will look better
  18. var rotationSpeed = 90; //Smaller = faster. 100 is a good speed
  19. var zoomSpeed = 0.161; //0-1. 0.2 or 0.3 are good speeds
  20. var moveSpeed = .5;
  21. /********************************************************************
  22. * Variable containing this object, to be refered from nested *
  23. * functions. *
  24. ********************************************************************/
  25. var thisObJS;
  26. /********************************************************************
  27. * Parameter used to scale the measures in the .obj file. Can be *
  28. * integer or float, greater than 0. 50 is a good default. *
  29. ********************************************************************/
  30. var scale;
  31. /********************************************************************
  32. * Variable to determine if the canvas has been initialized. *
  33. ********************************************************************/
  34. var canvasInitialized = false;
  35. /********************************************************************
  36. * Variable to determine if the mouse button is being holded down. *
  37. ********************************************************************/
  38. var mDown = false;
  39. var pinch = false;
  40. var pinchScale = 0;
  41. /********************************************************************
  42. * Variables containing the canvas and its context. *
  43. ********************************************************************/
  44. var canvas;
  45. var ctx;
  46. /********************************************************************
  47. * Variables containing the number of elements. *
  48. ********************************************************************/
  49. var totalVert;
  50. var totalMaterial = 0;
  51. var totalFace
  52. /********************************************************************
  53. * Arrays containing the vertices, faces and materials. *
  54. ********************************************************************/
  55. var material;
  56. var vert;
  57. var face;
  58. /********************************************************************
  59. * Booleans to determine wich elements are to draw. *
  60. ********************************************************************/
  61. var dVerts = true;
  62. var dEdges = true;
  63. var dFaces = true;
  64. var dBackg = true;
  65. /********************************************************************
  66. * Booleans to indicate if mtl file should be used. *
  67. ********************************************************************/
  68. var useMtl = true;
  69. /********************************************************************
  70. * Global variables that will contain the position of the mouse in *
  71. * the previous frame to calculate rotation. *
  72. ********************************************************************/
  73. var pX = null;
  74. var pY = null;
  75. /********************************************************************
  76. * Function that initializes the canvas, assignin it to the HTML *
  77. * element, and set the required mouse events. *
  78. * #parameters: *
  79. * canv (canvas): canvas to use. If omited, the one named *
  80. * named "ObJSCanvas" will be used. *
  81. * #return: nothing *
  82. * #scope: public *
  83. ********************************************************************/
  84. this.initCanvas = function(canv){
  85. if (!canvasInitialized){
  86. if (canv!= null)
  87. canvas = canv;
  88. else
  89. canvas = document.getElementById("ObJSCanvas");
  90. ctx = canvas.getContext("2d");
  91. ctx.translate(canvas.width / 2, canvas.height / 2);
  92. canvas.onmousedown = function(e){
  93. pX = e.offsetX==undefined?e.layerX:e.offsetX;
  94. pY = e.offsetY==undefined?e.layerY:e.offsetY;
  95. mDown = true;
  96. };
  97. canvas.onmouseup = function(e){
  98. if(mDown)
  99. mouseClick(e);
  100. pX = null;
  101. pY = null;
  102. mDown = false;
  103. };
  104. canvas.onmousemove = function(e){
  105. if(!mDown)
  106. return;
  107. var x = e.offsetX==undefined?e.layerX:e.offsetX;
  108. var y = e.offsetY==undefined?e.layerY:e.offsetY;
  109. if (e.shiftKey){
  110. thisObJS.moveHorizontal(x - pX);
  111. thisObJS.moveVertical(y - pY);
  112. }
  113. else{
  114. thisObJS.rotateY(x - pX);
  115. thisObJS.rotateX(y - pY);
  116. }
  117. pX = x;
  118. pY = y;
  119. return false;
  120. };
  121. canvas.onmouseout = function(e){
  122. if(mDown)
  123. mDown = false;
  124. }
  125. canvas.addEventListener('mousewheel',function(e){
  126. e.preventDefault();
  127. if (event.wheelDelta > 0)
  128. thisObJS.zoom(1);
  129. else
  130. thisObJS.zoom(-1);
  131. return false;
  132. }, false);
  133. canvas.addEventListener('touchstart',function(e){
  134. if(e.touches.length == 2) {
  135. pinch = true;
  136. pinchScale = Math.sqrt((e.touches[0].clientX-e.touches[1].clientX) * (e.touches[0].clientX-e.touches[1].clientX) + (e.touches[0].clientY-e.touches[1].clientY) * (e.touches[0].clientY-e.touches[1].clientY));
  137. }
  138. return false;
  139. }, false);
  140. canvas.addEventListener('touchend',function(e){
  141. if(pinch)
  142. pinch = false;
  143. return false;
  144. }, false);
  145. canvas.addEventListener('touchcancel',function(e){
  146. if(pinch)
  147. pinch = false;
  148. return false;
  149. }, false);
  150. canvas.addEventListener('touchleave',function(e){
  151. if(pinch)
  152. pinch = false;
  153. return false;
  154. }, false);
  155. canvas.addEventListener('touchmove',function(e){
  156. e.preventDefault();
  157. if(pinch){
  158. var dist = Math.sqrt((e.touches[0].clientX-e.touches[1].clientX) * (e.touches[0].clientX-e.touches[1].clientX) + (e.touches[0].clientY-e.touches[1].clientY) * (e.touches[0].clientY-e.touches[1].clientY));
  159. if (dist > pinchScale)
  160. thisObJS.zoom(1);
  161. else if (dist < pinchScale)
  162. thisObJS.zoom(-1);
  163. pinchScale = dist;
  164. }
  165. else{
  166. var x = e.touches[0].clientX
  167. var y = e.touches[0].clientY;
  168. thisObJS.rotateY(x - pX);
  169. thisObJS.rotateX(y - pY);
  170. pX = x;
  171. pY = y;
  172. }
  173. return false;
  174. }, false);
  175. canvasInitialized = true;
  176. }
  177. };
  178. /********************************************************************
  179. * Main function, called every time a file is to be loaded. *
  180. * #parameters: *
  181. * file (string): name of the file, without path or extension. *
  182. * #return: nothing *
  183. * #scope: public *
  184. ********************************************************************/
  185. this.load = function(file){
  186. if(!canvasInitialized)
  187. initCanvas();
  188. //Get obj file
  189. var xmlhttp = new XMLHttpRequest();
  190. xmlhttp.open("GET", file, false);
  191. xmlhttp.send();
  192. var fileContent = xmlhttp.responseText;
  193. //Get mtl file
  194. xmlhttp = new XMLHttpRequest();
  195. xmlhttp.open("GET",file.substring(0, file.lastIndexOf(".")) + ".mtl", false);
  196. xmlhttp.send();
  197. var mtlContent = xmlhttp.responseText;
  198. initArrays();
  199. readFile(fileContent);
  200. readMtlFile(mtlContent);
  201. draw();
  202. };
  203. /********************************************************************
  204. * Functions switching the elements drawn (dVerts, dEdges, dFaces). *
  205. * #parameters: *
  206. * on (boolean): indicating if the element is to be drawn. *
  207. * #return: nothing *
  208. * #scope: public *
  209. ********************************************************************/
  210. this.drawVertizes = function(on){
  211. if (on == true || on == false){
  212. dVerts = on;
  213. draw();
  214. }
  215. };
  216. this.drawEdges = function(on){
  217. if (on == true || on == false){
  218. dEdges = on;
  219. draw();
  220. }
  221. };
  222. this.drawFaces = function(on){
  223. if (on == true || on == false){
  224. dFaces = on;
  225. draw();
  226. }
  227. };
  228. this.drawBackground = function(on){
  229. if (on == true || on == false){
  230. dBackg = on;
  231. draw();
  232. }
  233. };
  234. /********************************************************************
  235. * Functions switching the color of the elements. *
  236. * #parameters: *
  237. * code (string): hex color value, in #fff or #ffffff form. If *
  238. * wrong, a message will be printed to console, *
  239. * and nothing will be changed. *
  240. * #return: nothing *
  241. * #scope: public *
  242. ********************************************************************/
  243. this.setVertizesColor = function(code){
  244. if (isColor(code)){
  245. var color = hexToRgb(code);
  246. vertColor = "rgba(" + color.r + ", " + color.g + ", " + color.b + ", 1)";
  247. draw();
  248. }
  249. else
  250. console.log("setVertizesColor(" + code + ") ERROR: " + code + " not a valid hex color");
  251. };
  252. this.setEdgesColor = function(code){
  253. if (isColor(code)){
  254. var color = hexToRgb(code);
  255. edgeColor = "rgba(" + color.r + ", " + color.g + ", " + color.b + ", 1)";
  256. draw();
  257. }
  258. else
  259. console.log("setEdgesColor(" + code + ") ERROR: " + code + " not a valid hex color");
  260. };
  261. this.setFacesColor = function(code){
  262. if (isColor(code)){
  263. var color = hexToRgb(code);
  264. faceColor = "rgba(" + color.r + ", " + color.g + ", " + color.b + ", 1)";
  265. draw();
  266. }
  267. else
  268. console.log("setFacesColor(" + code + ") ERROR: " + code + " not a valid hex color");
  269. };
  270. this.setBackgroundColor = function(code){
  271. if (isColor(code)){
  272. var color = hexToRgb(code);
  273. backColor = "rgba(" + color.r + ", " + color.g + ", " + color.b + ", 1)";
  274. draw();
  275. }
  276. else
  277. console.log("setBackgroundColor(" + code + ") ERROR: " + code + " not a valid hex color");
  278. };
  279. /********************************************************************
  280. * Function switching the use of mtl file for color. *
  281. * #parameters: *
  282. * value (boolean): indicating if the element is to be drawn. *
  283. * #return: nothing *
  284. * #scope: public *
  285. ********************************************************************/
  286. this.linkMaterial = function(value){
  287. useMtl = value;
  288. draw();
  289. }
  290. /********************************************************************
  291. * Function switching the alpha value of the faces. *
  292. * #parameters: *
  293. * percent (int): Value (0-100) of alpha. Must be processed (0-1) *
  294. * #return: nothing *
  295. * #scope: public *
  296. ********************************************************************/
  297. this.setAlpha = function(percent){
  298. if (percent >= 0 && percent <= 100){
  299. faceAlpha = percent / 100;
  300. faceColor = faceColor.substring(0, faceColor.lastIndexOf(",") + 2) + faceAlpha + ")";
  301. draw();
  302. }
  303. else
  304. console.log("setAlpha(" + percent + "); ERROR: Only values between 0 and 100 are allowed");
  305. };
  306. /********************************************************************
  307. * Function switching the rotation speed. *
  308. * #parameters: *
  309. * percent (int): Value (0-10) of speed. *
  310. * #return: nothing *
  311. * #scope: public *
  312. ********************************************************************/
  313. this.setRotationSpeed = function(percent){
  314. if (percent >= 0 && percent <= 10){
  315. rotationSpeed = Math.round((10 - percent) * 30);
  316. if (rotationSpeed == 0)
  317. rotationSpeed = 1;
  318. }
  319. else
  320. console.log("setRotationSpeed(" + percent + "); ERROR: Only values between 0 and 10 are allowed");
  321. }
  322. /********************************************************************
  323. * Functions that rotate elements in the canvas along the *
  324. * correspondent axys, calculating the new position for each vertex *
  325. * in the vert array. *
  326. * #parameters: *
  327. * des (int): distance to rotate. *
  328. * #return: nothing *
  329. * #scope: public *
  330. ********************************************************************/
  331. this.rotateY = function(des){
  332. for (var i = 0; i < vert.length; i ++) {
  333. var x = vert[i][0];
  334. var z = vert[i][2];
  335. vert[i][0] = x * Math.cos(des / rotationSpeed) - z * Math.sin(des / rotationSpeed);
  336. vert[i][2] = z * Math.cos(des / rotationSpeed) + x * Math.sin(des / rotationSpeed);
  337. }
  338. draw();
  339. };
  340. this.rotateX = function(des){
  341. for (var i = 0; i < vert.length; i ++) {
  342. var y = vert[i][1];
  343. var z = vert[i][2];
  344. vert[i][1] = y * Math.cos(des / rotationSpeed) - z * Math.sin(des / rotationSpeed);
  345. vert[i][2] = z * Math.cos(des / rotationSpeed) + y * Math.sin(des / rotationSpeed);
  346. }
  347. draw();
  348. };
  349. /********************************************************************
  350. * Function switching the movement speed of the model. *
  351. * #parameters: *
  352. * percent (int): Value (0-10) of speed. *
  353. * #return: nothing *
  354. * #scope: public *
  355. ********************************************************************/
  356. this.setMovementSpeed = function(percent){
  357. if (percent >= 0 && percent <= 10)
  358. moveSpeed = ((percent * 0.8) / 10) + 0.01;
  359. else
  360. console.log("setMoveSpeed(" + percent + "); ERROR: Only values between 0 and 10 are allowed");
  361. }
  362. /********************************************************************
  363. * Functions that move elements in the canvas along the selected *
  364. * direction, calculating the new position for each vertex in the *
  365. * vert array. *
  366. * #parameters: *
  367. * des (int): distance to move. *
  368. * #return: nothing *
  369. * #scope: public *
  370. ********************************************************************/
  371. this.moveVertical = function(des){
  372. for (var i = 0; i < vert.length; i ++)
  373. vert[i][1] = (vert[i][1] * 1) + des * (moveSpeed / 50);
  374. draw();
  375. };
  376. this.moveHorizontal = function(des){
  377. for (var i = 0; i < vert.length; i ++)
  378. vert[i][0] = (vert[i][0] * 1) + des * (moveSpeed / 50);
  379. draw();
  380. };
  381. /********************************************************************
  382. * Function switching the zoom speede of the faces. *
  383. * #parameters: *
  384. * percent (int): Value (0-100) of speed. *
  385. * #return: nothing *
  386. * #scope: public *
  387. ********************************************************************/
  388. this.setZoomSpeed = function(percent){
  389. if (percent >= 0 && percent <= 10)
  390. zoomSpeed = ((percent * 0.8) / 10) + 0.01;
  391. else
  392. console.log("setZoomSpeed(" + percent + "); ERROR: Only values between 0 and 10 are allowed");
  393. }
  394. /********************************************************************
  395. * Function that changes the scale variable, witch results in a *
  396. * zoom in or zoom out effect. *
  397. * #parameters: none *
  398. * #return: nothing *
  399. * #scope: public *
  400. ********************************************************************/
  401. this.zoom = function(val){
  402. scale = scale + val * scale * zoomSpeed;
  403. draw();
  404. };
  405. /********************************************************************
  406. * Function that clears the arrays and the canvas. Use to unload a *
  407. * model. *
  408. * #parameters: none *
  409. * #return: nothing *
  410. * #scope: public *
  411. ********************************************************************/
  412. this.clear = function(){
  413. initArrays();
  414. clearCanvas();
  415. };
  416. /********************************************************************
  417. * Function that turns a hex color code in RGB. *
  418. * stackoverflow.com/questions/5623838/rgb-to-hex-and-hex-to-rgb *
  419. * #parameters: *
  420. * hex (string): color code, for example "#33ff99" *
  421. * #return: (Array) r, g, b, with their correspondent color. *
  422. * #scope: private *
  423. ********************************************************************/
  424. var hexToRgb = function(hex) {
  425. var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
  426. return result ? {
  427. r: parseInt(result[1], 16),
  428. g: parseInt(result[2], 16),
  429. b: parseInt(result[3], 16)
  430. } : null;
  431. };
  432. /********************************************************************
  433. * Function that checks if a string is a valid hexadecimal color *
  434. * code, in the format '#ffffff' or '#fff' *
  435. * #parameters: *
  436. * code (string): Code to check. *
  437. * #return: (Boolean) True if valid color code, false otherwise. *
  438. * #scope: private *
  439. ********************************************************************/
  440. var isColor = function(code){
  441. if (code[0] != '#')
  442. return false;
  443. if (code.length != 4 && code.length != 7)
  444. return false
  445. for (var i = 1; i < code.length; i ++)
  446. if (code[i] < '0' || (code[i] > 9 && code[i] < 'A') || (code[i] > 'Z' && code[i] < 'a') || code[i] > 'z')
  447. return false;
  448. return true;
  449. };
  450. /********************************************************************
  451. * Function that clears the canvas and gets it ready to draw on it. *
  452. * #parameters: none *
  453. * #return: nothing *
  454. * #scope: private *
  455. ********************************************************************/
  456. var clearCanvas = function(){
  457. ctx.clearRect(0, 0, canvas.width, canvas.height);
  458. if (dBackg)
  459. ctx.fillStyle = backColor;
  460. else
  461. ctx.fillStyle = "#ffffff";
  462. ctx.fillRect(-canvas.width / 2, -canvas.height / 2, canvas.width, canvas.height);
  463. };
  464. /********************************************************************
  465. * Function initializing the arrays obj, vert and face as empty *
  466. * arrays. *
  467. * #parameters: none *
  468. * #return: nothing *
  469. * #scope: private *
  470. ********************************************************************/
  471. var initArrays = function(){
  472. material = null;
  473. vert = null;
  474. face = null;
  475. material = new Array();
  476. vert = new Array();
  477. face = new Array();
  478. };
  479. /********************************************************************
  480. * Function tat populates the vert[] array with and array of three *
  481. * elements, containig the coordinates, and the face[] array with *
  482. * the vertizes forming the face, plus one element indicating the *
  483. * codename of the material. *
  484. * #parameters: *
  485. * text (string): the content of the obj file. *
  486. * #return: nothing *
  487. * #scope: private *
  488. ********************************************************************/
  489. var readFile = function(text){
  490. var line;
  491. var v = 0;
  492. var f = 0;
  493. var m = 0;
  494. var max = 0;
  495. var j;
  496. var dist;
  497. var mat = "null";
  498. text = text + "\n";
  499. while (text.indexOf("\n") != -1){
  500. line = text.substring(0, text.indexOf("\n"));
  501. if (line.substring(0, 2) == "v "){
  502. vert[v] = new Array(3);
  503. line = line.substring(2);
  504. vert[v][0] = line.substring(0, line.indexOf(" "));
  505. line = line.substring(line.indexOf(" ") + 1);
  506. vert[v][1] = line.substring(0, line.indexOf(" "));
  507. line = line.substring(line.indexOf(" ") + 1);
  508. vert[v][2] = line;
  509. dist = Math.sqrt(vert[v][0] * vert[v][0] + vert[v][1] * vert[v][1] + vert[v][2] * vert[v][2]);
  510. if (dist > max)
  511. max = dist;
  512. v = v + 1;
  513. }
  514. else if (line.substring(0,2) == "f "){
  515. line = line.substring(2);
  516. face[f] = new Array();
  517. j = 0;
  518. while(line.indexOf(" ") != -1){
  519. face[f][j] = line.substring(0, line.indexOf(" ")) - 1;
  520. line = line.substring(line.indexOf(" ") + 1);
  521. j = j + 1;
  522. }
  523. face[f][j] = line - 1;
  524. face[f][j + 1] = mat;
  525. f = f + 1;
  526. }
  527. else if (line.substring(0, 6) == "usemtl"){
  528. mat = line.substring(7);
  529. }
  530. text = text.substring(text.indexOf("\n") + 1);
  531. }
  532. scale = calculateScale(max);
  533. totalVert = vert.length;
  534. totalFace = face.length;
  535. };
  536. /********************************************************************
  537. * Function tat populates the material[] array with an array *
  538. * containig, four values: the material name, and the three RGB *
  539. * values. *
  540. * #parameters: *
  541. * text (string): the content of the mtl file. *
  542. * #return: nothing *
  543. * #scope: private *
  544. ********************************************************************/
  545. var readMtlFile = function(text){
  546. text = text + "\n";
  547. i = -1;
  548. while (text.indexOf("\n") != -1){
  549. line = text.substring(0, text.indexOf("\n"));
  550. if (line.substring(0, 6) == "newmtl"){
  551. i = i + 1;
  552. material[i] = new Array(4);
  553. material[i][0] = line.substring(line.indexOf(" ") + 1);
  554. }
  555. //Kd, ddifuse color, usefull
  556. //Ka, ambient color, not now
  557. //Ks, specular color, not now
  558. //d or TR, transparency, not now
  559. else if (line.substring(0, 3) == "Kd "){
  560. line = line.substring(3);
  561. material[i][1] = line.substring(0, line.indexOf(" "));
  562. line = line.substring(line.indexOf(" ") + 1);
  563. material[i][2] = line.substring(0, line.indexOf(" "));
  564. line = line.substring(line.indexOf(" ") + 1);
  565. material[i][3] = line;
  566. }
  567. text = text.substring(text.indexOf("\n") + 1);
  568. }
  569. totalMaterial = material.length;
  570. };
  571. /********************************************************************
  572. * Function that automatically calculates the best scale for the *
  573. * modelermined number of elements, containing the verices that *
  574. * form a face, so the bigest dimension from the object can fit in *
  575. * the smallest dimension of the canvas. *
  576. * #parameters: *
  577. * text (int): the farthest vertex, from the center. *
  578. * #return: (int) The scale to be aplied. *
  579. * #scope: private *
  580. ********************************************************************/
  581. var calculateScale = function(max){
  582. var dim;
  583. if (canvas.width < canvas.height)
  584. dim = canvas.width;
  585. else
  586. dim = canvas.height;
  587. var sc = Math.round((0.95 * dim) / (2 * max));
  588. return sc;
  589. };
  590. /********************************************************************
  591. * Function that compares the average Z coordinate of two faces. *
  592. * Must be used when sorting the face array. *
  593. * #parameters: *
  594. * a (Array): One face. *
  595. * b (Array): The other face. *
  596. * #return: (int) -1, 1 or 0. *
  597. * #scope: private *
  598. ********************************************************************/
  599. var faceComparator = function(a,b){
  600. var aZ;
  601. var bZ;
  602. var i = 0;
  603. var sum = 0.0;
  604. while (i < a.length - 1){
  605. sum = sum + parseFloat(vert[a[i]][2]);
  606. i = i + 1;
  607. }
  608. aZ = sum / parseFloat(i);
  609. i = 0;
  610. sum = 0;
  611. while (i < b.length - 1){
  612. sum = sum + parseFloat(1 * vert[b[i]][2]);
  613. i = i + 1;
  614. }
  615. bZ = sum / parseFloat(i);
  616. if (aZ < bZ) return -1;
  617. if (aZ > bZ) return 1;
  618. return 0;
  619. };
  620. /********************************************************************
  621. * Function that writes text in the corner of the canvas. Must be *
  622. * called when everithing has been drawn. *
  623. * #parameters: none *
  624. * #return: nothing *
  625. * #scope: private *
  626. ********************************************************************/
  627. var writeCredits = function(){
  628. ctx.fillStyle = textColor;
  629. ctx.font = "12px Arial";
  630. var h = canvas.height / 2 - 14;
  631. var w = 10 - (canvas.width / 2);
  632. ctx.fillText("ObJS: " + totalVert + " vertizes " + totalFace + " faces " + totalMaterial + " materials", w, h);
  633. };
  634. /********************************************************************
  635. * Function that draws th vertizes, faces and edges in the canvas. *
  636. * #parameters: none *
  637. * #return: nothing *
  638. * #scope: private *
  639. ********************************************************************/
  640. var draw = function(){
  641. face = face.sort(faceComparator).reverse();
  642. clearCanvas();
  643. for (var i = 0; i < face.length; i++){
  644. ctx.strokeStyle = edgeColor;
  645. ctx.fillStyle = vertColor;
  646. ctx.beginPath();
  647. ctx.moveTo(scale * vert[face[i][0]][0], scale * vert[face[i][0]][1]);
  648. for (var j = 1; j < face[i].length - 1; j++) {
  649. ctx.lineTo(scale * vert[face[i][j]][0], scale * vert[face[i][j]][1]);
  650. if(dEdges)
  651. ctx.stroke();
  652. if(dVerts){
  653. var x = scale * vert[face[i][j]][0] - (vertSize / 2);
  654. var w = vertSize;
  655. var y = scale * vert[face[i][j]][1] - (vertSize / 2);
  656. var h = vertSize;
  657. ctx.fillRect(x, y, w, h);
  658. }
  659. }
  660. ctx.closePath();
  661. if (useMtl){
  662. //Get material with the same name as the one in the last element of the face
  663. j = 0;
  664. while (material[j][0] != face[i][face[i].length - 1] && j < material.length)
  665. j = j + 1;
  666. if (material[j][0] == face[i][face[i].length - 1])
  667. ctx.fillStyle = "rgba(" + Math.round(255 * material[j][1]) + ", " + Math.round(255 * material[j][2]) + ", " + Math.round(255 * material[j][3]) + ", " + faceAlpha + ")";
  668. else
  669. ctx.fillStyle = faceColor;
  670. }
  671. else
  672. ctx.fillStyle = faceColor;
  673. if(dFaces)
  674. ctx.fill();
  675. }
  676. writeCredits();
  677. };
  678. /********************************************************************
  679. * TODO: Function used when something in the canvas is clicked. *
  680. * #parameters: none *
  681. * #return: nothing *
  682. * #scope: private *
  683. ********************************************************************/
  684. var mouseClick = function(){
  685. };
  686. thisObJS = this;
  687. return this;
  688. }