ObJS.js 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362
  1. /********************************************************************
  2. * Parameters used all along the script. Only for *
  3. * customization. *
  4. ********************************************************************/
  5. var backColor = "rgba(200, 200, 200, 1)";
  6. var vertColor = "rgba(10, 10, 10, 1)";
  7. var edgeColor = "rgba(100, 70, 70, 1)";
  8. var faceColor = "rgba(180, 180, 255, .3)";
  9. var textColor = "rgba(0, 0, 0, 1)";
  10. var vertSize = 2; //Make it even: at small scales will look better
  11. var rotationSpeed = 100; //Smaller = faster. 100 is a good speed
  12. /********************************************************************
  13. * Parameters used to scale the measures in the .obj file. Can be *
  14. * integer or float, greater than 0 *
  15. * TODO: Must be automatically calculated according to the canvas *
  16. * dimensions, so the bigest dimension from the object can fit in *
  17. * the smallest dimension of the canvas. *
  18. ********************************************************************/
  19. var scale;// = 50;
  20. /********************************************************************
  21. * Global variable to determine if the mouse button is being holded *
  22. * down. *
  23. ********************************************************************/
  24. var mDown = false;
  25. /********************************************************************
  26. * Global variables containing the canvas and its context. *
  27. ********************************************************************/
  28. var canvas;
  29. var ctx;
  30. /********************************************************************
  31. * Global variables containing the number of elements. *
  32. ********************************************************************/
  33. var totalVert;
  34. var totalEdge;//TODO: I dont know how to calculate
  35. var totalFace
  36. /********************************************************************
  37. * Arrays containing the vertices, edges and faces. *
  38. ********************************************************************/
  39. var obj; //Unused
  40. var vert;
  41. var face;
  42. /********************************************************************
  43. * Booleans to determine wich elements are to draw. *
  44. ********************************************************************/
  45. var dVerts = true;
  46. var dEdges = true;
  47. var dFaces = true;
  48. /********************************************************************
  49. * Global variables that will contain the position of the mouse in *
  50. * the previous frame to calculate rotation. *
  51. ********************************************************************/
  52. var pX = null;
  53. var pY = null;
  54. /********************************************************************
  55. * Function switching the elements to draw (dVerts, dEdges, dFaces) *
  56. * @parameters: *
  57. * name (string): key to the element to draw. *
  58. * value (boolean): indicating if the element is to be drawn. *
  59. * @return: nothing *
  60. ********************************************************************/
  61. function drawElement(name, value){
  62. switch (name){
  63. case "verts":
  64. dVerts = value;
  65. break;
  66. case "edges":
  67. dEdges = value;
  68. break;
  69. case "faces":
  70. dFaces = value;
  71. break;
  72. }
  73. draw();
  74. }
  75. /********************************************************************
  76. * Main function, called every time a file is to be loaded. *
  77. * @parameters: *
  78. * val (string): name of the file, without path or extension. *
  79. * @return: nothing *
  80. ********************************************************************/
  81. function loadModel(val){
  82. //Get file
  83. xmlhttp = new XMLHttpRequest();
  84. xmlhttp.open("GET","/obj/" + val.value + ".obj", false);
  85. xmlhttp.send();
  86. var fileContent = xmlhttp.responseText;
  87. initArrays();
  88. if (canvas == null)
  89. initCanvas();
  90. readVerts(fileContent);
  91. readFaces(fileContent);
  92. draw();
  93. }
  94. /********************************************************************
  95. * Function initializing the arrays obj, vert and face as empty *
  96. * arrays. *
  97. * @parameters: none *
  98. * @return: nothing *
  99. ********************************************************************/
  100. function initArrays(){
  101. obj = null;
  102. vert = null;
  103. face = null;
  104. obj = new Array();
  105. vert = new Array();
  106. face = new Array();
  107. }
  108. /********************************************************************
  109. * Function tat populates the vert[] array with and array of three *
  110. * elements, containig the coordinates, with the scale applied. *
  111. * @parameters: *
  112. * text (string): the content of the obj file. *
  113. * @return: nothing *
  114. ********************************************************************/
  115. function readVerts(text){
  116. var line;
  117. var i = 0;
  118. var max = 0;
  119. var dist;
  120. while (text.indexOf("v ") != -1){
  121. line = text.substring(text.indexOf("v "), text.indexOf("\n", text.indexOf("v ")));
  122. vert[i] = new Array(3);
  123. line = line.substring(2);
  124. vert[i][0] = line.substring(0, line.indexOf(" "));
  125. line = line.substring(line.indexOf(" ") + 1);
  126. vert[i][1] = line.substring(0, line.indexOf(" "));
  127. line = line.substring(line.indexOf(" ") + 1);
  128. vert[i][2] = line;
  129. text = text.substring(text.indexOf("v ") + 1)
  130. dist = Math.sqrt(vert[i][0] * vert[i][0] + vert[i][1] * vert[i][1] + vert[i][2] * vert[i][2]);
  131. if (dist > max)
  132. max = dist;
  133. i = i + 1;
  134. }
  135. scale = calculateScale(max);
  136. totalVert = vert.length;
  137. }
  138. /********************************************************************
  139. * Function that automatically calculates the best scale for the *
  140. * modelermined number of elements, containing the verices that *
  141. * form a face, so the bigest dimension from the object can fit in *
  142. * the smallest dimension of the canvas. *
  143. * @parameters: *
  144. * text (int): the farthest vertex, from the center. *
  145. * @return: (int) The scale to be aplied. *
  146. ********************************************************************/
  147. function calculateScale(max){
  148. var dim;
  149. if (canvas.width < canvas.height)
  150. dim = canvas.width;
  151. else
  152. dim = canvas.height;
  153. var sc = Math.round((0.95 * dim) / (2 * max));
  154. return sc;
  155. }
  156. /********************************************************************
  157. * Function that populates the face[] array with and array of an *
  158. * undetermined number of elements, containing the verices that *
  159. * form a face. *
  160. * @parameters: *
  161. * text (string): the content of the obj file. *
  162. * @return: nothing *
  163. ********************************************************************/
  164. function readFaces(text){
  165. var finish = false;
  166. var line;
  167. var i = 0;
  168. var j;
  169. while (text.indexOf("f ") != -1){
  170. line = text.substring(text.indexOf("f "), text.indexOf("\n", text.indexOf("f ")));
  171. line = line.substring(2);
  172. face[i] = new Array();
  173. j = 0;
  174. while(line.indexOf(" ") != -1){
  175. face[i][j] = line.substring(0, line.indexOf(" ")) - 1;
  176. line = line.substring(line.indexOf(" ") + 1);
  177. j = j + 1;
  178. }
  179. face[i][j] = line - 1;
  180. i = i + 1;
  181. text = text.substring(text.indexOf("f ") + 1)
  182. }
  183. totalFace = face.length;
  184. }
  185. /********************************************************************
  186. * Function that draws the vertizes in the canvas. *
  187. * @parameters: none *
  188. * @return: nothing *
  189. ********************************************************************/
  190. function drawVerts(){
  191. ctx.fillStyle = vertColor;
  192. var x;
  193. var y;
  194. var w;
  195. var h;
  196. //console.log("Drawing " + vert.length + " vertices")
  197. for (var i = 0; i < vert.length; i++) {
  198. x = scale * vert[i][0] - (vertSize / 2);
  199. w = vertSize;
  200. y = scale * vert[i][1] - (vertSize / 2);
  201. h = vertSize;
  202. ctx.fillRect(x, y, w, h);
  203. }
  204. }
  205. /********************************************************************
  206. * Function that draws the edges and the faces in the canvas, if *
  207. * they are to be drawn according to dEdges and dFaces. *
  208. * @parameters: none *
  209. * @return: nothing *
  210. ********************************************************************/
  211. function drawFaces(){
  212. //console.log("Drawing " + face.length + " faces")
  213. for (var i = 0; i < face.length; i++){
  214. ctx.strokeStyle = edgeColor;
  215. ctx.beginPath();
  216. ctx.moveTo(scale * vert[face[i][0]][0], scale * vert[face[i][0]][1]);
  217. for (var j = 1; j < face[i].length; j++) {
  218. ctx.lineTo(scale * vert[face[i][j]][0], scale * vert[face[i][j]][1]);
  219. if(dEdges)
  220. ctx.stroke();
  221. }
  222. ctx.closePath();
  223. ctx.fillStyle = faceColor;
  224. if(dFaces)
  225. ctx.fill();
  226. }
  227. }
  228. /********************************************************************
  229. * Function that writes text in the corner of the canvas. Must be *
  230. * called when everithing has been drawn. *
  231. * @parameters: none *
  232. * @return: nothing *
  233. ********************************************************************/
  234. function writeCredits(){
  235. ctx.fillStyle = textColor;
  236. ctx.font = "12px Arial";
  237. var h = canvas.height / 2 - 14;
  238. var w = 10 - (canvas.height / 2);
  239. ctx.fillText("ObJS " + totalVert + " vertizes " + totalFace + " faces", w, h);
  240. }
  241. /********************************************************************
  242. * Function that calls every neccesary function to draw the canvas. *
  243. * @parameters: none *
  244. * @return: nothing *
  245. ********************************************************************/
  246. function draw(){
  247. clearCanvas();
  248. if (dFaces || dEdges)
  249. drawFaces();
  250. if (dVerts)
  251. drawVerts();
  252. writeCredits();
  253. }
  254. /********************************************************************
  255. * Function that rotates elements in the canvas along the Y axis, *
  256. * calculating the new position for each vertex in the vert array. *
  257. * @parameters: *
  258. * des (int): mouse displacement from the last frame. *
  259. * @return: nothing *
  260. ********************************************************************/
  261. function rotateY(des) {
  262. for (var i = 0; i < vert.length; i ++) {
  263. var x = vert[i][0];
  264. var z = vert[i][2];
  265. vert[i][0] = x * Math.cos(des / rotationSpeed) - z * Math.sin(des / rotationSpeed);
  266. vert[i][2] = z * Math.cos(des / rotationSpeed) + x * Math.sin(des / rotationSpeed);
  267. }
  268. };
  269. /********************************************************************
  270. * Function that rotates elements in the canvas along the X axis, *
  271. * calculating the new position for each vertex in the vert array. *
  272. * @parameters: *
  273. * des (int): mouse displacement from the last frame. *
  274. * @return: nothing *
  275. ********************************************************************/
  276. function rotateX(des) {
  277. for (var i = 0; i < vert.length; i ++) {
  278. var y = vert[i][1];
  279. var z = vert[i][2];
  280. vert[i][1] = y * Math.cos(des / rotationSpeed) - z * Math.sin(des / rotationSpeed);
  281. vert[i][2] = z * Math.cos(des / rotationSpeed) + y * Math.sin(des / rotationSpeed);
  282. }
  283. };
  284. /********************************************************************
  285. * Function that initializes the canvas, assignin it to the HTML *
  286. * element, and set the required mouse events. *
  287. * @parameters: none *
  288. * @return: nothing *
  289. ********************************************************************/
  290. function initCanvas(){
  291. canvas = document.getElementById("ObJSCanvas");
  292. ctx = canvas.getContext("2d");
  293. ctx.translate(canvas.width / 2, canvas.height / 2);
  294. canvas.onmousedown = function(e){
  295. pX = e.offsetX==undefined?e.layerX:e.offsetX;
  296. pY = e.offsetY==undefined?e.layerY:e.offsetY;
  297. mDown = true;
  298. }
  299. canvas.onmouseup = function(e){
  300. if(mDown)
  301. mouseClick(e);
  302. pX = null;
  303. pY = null;
  304. mDown = false;
  305. }
  306. canvas.onmousemove = function(e){
  307. if(!mDown)
  308. return;
  309. var x = e.offsetX==undefined?e.layerX:e.offsetX;
  310. var y = e.offsetY==undefined?e.layerY:e.offsetY;
  311. rotateY(x - pX);
  312. rotateX(y - pY);
  313. pX = x;
  314. pY = y;
  315. draw();
  316. return false;
  317. }
  318. }
  319. /********************************************************************
  320. * Function that clears the canvas and gets it ready to draw on it. *
  321. * @parameters: none *
  322. * @return: nothing *
  323. ********************************************************************/
  324. function clearCanvas(){
  325. ctx.clearRect(0, 0, canvas.width, canvas.height);
  326. ctx.fillStyle = backColor;
  327. ctx.fillRect(-canvas.width / 2, -canvas.height / 2, canvas.width, canvas.height);
  328. }
  329. /********************************************************************
  330. * TODO: Function used when something in the canvas is clicked. *
  331. * @parameters: none *
  332. * @return: nothing *
  333. ********************************************************************/
  334. function mouseClick(){
  335. }