ObJS.js 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320
  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(200, 0, 0, 1)";
  8. var faceColor = "rgba(180, 180, 255, .3)";
  9. var textColor = "rgba(0, 0, 0, 1)";
  10. var vertSize = 6; //Make it even: at small scales will look better
  11. var rotationSpeed = 100; //Smaller = faster
  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. * Arrays containing the vertices, edges and faces. *
  32. ********************************************************************/
  33. var obj; //Unused
  34. var vert;
  35. var face;
  36. /********************************************************************
  37. * Booleans to determine wich elements are to draw. *
  38. ********************************************************************/
  39. var dVerts = true;
  40. var dEdges = true;
  41. var dFaces = true;
  42. /********************************************************************
  43. * Global variables that will contain the position of the mouse in *
  44. * the previous frame to calculate rotation. *
  45. ********************************************************************/
  46. var pX = null;
  47. var pY = null;
  48. /********************************************************************
  49. * Function switching the elements to draw (dVerts, dEdges, dFaces) *
  50. * @parameters: *
  51. * name (string): key to the element to draw. *
  52. * value (boolean): indicating if the element is to be drawn. *
  53. * @return: nothing *
  54. ********************************************************************/
  55. function drawElement(name, value){
  56. switch (name){
  57. case "verts":
  58. dVerts = value;
  59. break;
  60. case "edges":
  61. dEdges = value;
  62. break;
  63. case "faces":
  64. dFaces = value;
  65. break;
  66. }
  67. draw();
  68. }
  69. /********************************************************************
  70. * Main function, called every time a file is to be loaded. *
  71. * @parameters: *
  72. * val (string): name of the file, without path or extension. *
  73. * @return: nothing *
  74. ********************************************************************/
  75. function loadModel(val){
  76. //Get file
  77. xmlhttp = new XMLHttpRequest();
  78. xmlhttp.open("GET","/obj/" + val.value + ".obj", false);
  79. xmlhttp.send();
  80. var fileContent = xmlhttp.responseText;
  81. initArrays();
  82. readVerts(fileContent);
  83. readFaces(fileContent);
  84. draw();
  85. }
  86. /********************************************************************
  87. * Function initializing the arrays obj, vert and face as empty *
  88. * arrays. *
  89. * @parameters: none *
  90. * @return: nothing *
  91. ********************************************************************/
  92. function initArrays(){
  93. obj = null;
  94. vert = null;
  95. face = null;
  96. obj = new Array();
  97. vert = new Array();
  98. face = new Array();
  99. }
  100. /********************************************************************
  101. * Function tat populates the vert[] array with and array of three *
  102. * elements, containig the coordinates, with the scale applied. *
  103. * @parameters: *
  104. * text (string): the content of the obj file. *
  105. * @return: nothing *
  106. ********************************************************************/
  107. function readVerts(text){
  108. var line;
  109. var i = 0;
  110. while (text.indexOf("v ") != -1){
  111. line = text.substring(text.indexOf("v "), text.indexOf("\n", text.indexOf("v ")));
  112. vert[i] = new Array(3);
  113. line = line.substring(2);
  114. vert[i][0] = Math.round(scale * Math.round(line.substring(0, line.indexOf(" "))));
  115. line = line.substring(line.indexOf(" ") + 1);
  116. vert[i][1] = Math.round(scale * Math.round(line.substring(0, line.indexOf(" "))));
  117. line = line.substring(line.indexOf(" ") + 1);
  118. vert[i][2] = Math.round(scale * Math.round(line));
  119. i = i + 1;
  120. text = text.substring(text.indexOf("v ") + 1)
  121. }
  122. }
  123. /********************************************************************
  124. * Function that populates the face[] array with and array of an *
  125. * undetermined number of elements, containing the verices that *
  126. * form a face. *
  127. * @parameters: *
  128. * text (string): the content of the obj file. *
  129. * @return: nothing *
  130. ********************************************************************/
  131. function readFaces(text){
  132. var finish = false;
  133. var line;
  134. var i = 0;
  135. var j;
  136. while (text.indexOf("f ") != -1){
  137. line = text.substring(text.indexOf("f "), text.indexOf("\n", text.indexOf("f ")));
  138. line = line.substring(2);
  139. face[i] = new Array();
  140. j = 0;
  141. while(line.indexOf(" ") != -1){
  142. face[i][j] = line.substring(0, line.indexOf(" ")) - 1;
  143. line = line.substring(line.indexOf(" ") + 1);
  144. j = j + 1;
  145. }
  146. face[i][j] = line - 1;
  147. i = i + 1;
  148. text = text.substring(text.indexOf("f ") + 1)
  149. }
  150. }
  151. /********************************************************************
  152. * Function that draws the vertizes in the canvas. *
  153. * @parameters: none *
  154. * @return: nothing *
  155. ********************************************************************/
  156. function drawVerts(){
  157. ctx.fillStyle = vertColor;
  158. var x;
  159. var y;
  160. var w;
  161. var h;
  162. for (var i = 0; i < vert.length; i++) {
  163. x = vert[i][0] - (vertSize / 2);
  164. w = vertSize;
  165. y = vert[i][1] - (vertSize / 2);
  166. h = vertSize;
  167. ctx.fillRect(x, y, w, h);
  168. }
  169. }
  170. /********************************************************************
  171. * Function that draws the edges and the faces in the canvas, if *
  172. * they are to be drawn according to dEdges and dFaces. *
  173. * @parameters: none *
  174. * @return: nothing *
  175. ********************************************************************/
  176. function drawFaces(){
  177. for (var i = 0; i < face.length; i++){
  178. ctx.fillStyle = edgeColor;
  179. ctx.beginPath();
  180. ctx.moveTo(vert[face[i][0]][0], vert[face[i][0]][1]);
  181. for (var j = 1; j < face[i].length; j++) {
  182. ctx.lineTo(vert[face[i][j]][0], vert[face[i][j]][1]);
  183. if(dEdges)
  184. ctx.stroke();
  185. }
  186. ctx.closePath();
  187. ctx.fillStyle = faceColor;
  188. if(dFaces)
  189. ctx.fill();
  190. }
  191. }
  192. /********************************************************************
  193. * Function that writes text in the corner of the canvas. Must be *
  194. * called when everithing has been drawn. *
  195. * @parameters: none *
  196. * @return: nothing *
  197. ********************************************************************/
  198. function writeCredits(){
  199. ctx.fillStyle = textColor;
  200. ctx.font = "12px Arial";
  201. var h = canvas.height / 2 - 14;
  202. var w = canvas.width / 2 - 45;
  203. ctx.fillText("ObJS", w, h);
  204. }
  205. /********************************************************************
  206. * Function that calls every neccesary function to draw the canvas. *
  207. * @parameters: none *
  208. * @return: nothing *
  209. ********************************************************************/
  210. function draw(){
  211. initCanvas();
  212. if (dFaces || dEdges)
  213. drawFaces();
  214. if (dVerts)
  215. drawVerts();
  216. writeCredits();
  217. }
  218. /********************************************************************
  219. * Function that rotates elements in the canvas along the Y axis, *
  220. * calculating the new position for each vertex in the vert array. *
  221. * @parameters: *
  222. * des (int): mouse displacement from the last frame. *
  223. * @return: nothing *
  224. ********************************************************************/
  225. function rotateY(des) {
  226. for (var i = 0; i < vert.length; i ++) {
  227. var x = vert[i][0];
  228. var z = vert[i][2];
  229. vert[i][0] = x * Math.cos(des / rotationSpeed) - z * Math.sin(des / rotationSpeed);
  230. vert[i][2] = z * Math.cos(des / rotationSpeed) + x * Math.sin(des / rotationSpeed);
  231. }
  232. };
  233. /********************************************************************
  234. * Function that rotates elements in the canvas along the X axis, *
  235. * calculating the new position for each vertex in the vert array. *
  236. * @parameters: *
  237. * des (int): mouse displacement from the last frame. *
  238. * @return: nothing *
  239. ********************************************************************/
  240. function rotateX(des) {
  241. for (var i = 0; i < vert.length; i ++) {
  242. var y = vert[i][1];
  243. var z = vert[i][2];
  244. vert[i][1] = y * Math.cos(des / rotationSpeed) - z * Math.sin(des / rotationSpeed);
  245. vert[i][2] = z * Math.cos(des / rotationSpeed) + y * Math.sin(des / rotationSpeed);
  246. }
  247. };
  248. /********************************************************************
  249. * Function that gets the canvas ready to be drawn. It initializes *
  250. * the canvas and ctx variables if they arent already, seting mouse *
  251. * events for them, clears the canvas and sets the background. *
  252. * @parameters: none *
  253. * @return: nothing *
  254. ********************************************************************/
  255. function initCanvas(){
  256. if (canvas == null){
  257. canvas = document.getElementById("ObJSCanvas");
  258. ctx = canvas.getContext("2d");
  259. ctx.translate(canvas.width / 2, canvas.height / 2);
  260. canvas.onmousedown = function(e){
  261. pX = e.offsetX==undefined?e.layerX:e.offsetX;
  262. pY = e.offsetY==undefined?e.layerY:e.offsetY;
  263. mDown = true;
  264. }
  265. canvas.onmouseup = function(e){
  266. if(mDown)
  267. mouseClick(e);
  268. pX = null;
  269. pY = null;
  270. mDown = false;
  271. }
  272. canvas.onmousemove = function(e){
  273. if(!mDown)
  274. return;
  275. var x = e.offsetX==undefined?e.layerX:e.offsetX;
  276. var y = e.offsetY==undefined?e.layerY:e.offsetY;
  277. rotateY(x - pX);
  278. rotateX(y - pY);
  279. pX = x;
  280. pY = y;
  281. draw();
  282. return false;
  283. }
  284. }
  285. ctx.clearRect(0, 0, canvas.width, canvas.height);
  286. ctx.fillStyle = backColor;
  287. ctx.fillRect(-canvas.width / 2, -canvas.height / 2, canvas.width, canvas.height);
  288. }
  289. /********************************************************************
  290. * TODO: Function used when something in the canvas is clicked. *
  291. * @parameters: none *
  292. * @return: nothing *
  293. ********************************************************************/
  294. function mouseClick(){
  295. }