Advertisement
Guest User

Untitled

a guest
Oct 17th, 2019
95
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.02 KB | None | 0 0
  1. #ifndef CAMERAH
  2. #define CAMERAH
  3.  
  4. #include "vec3.h"
  5. #include "vec2.h"
  6. #include "matrix44.h"
  7. #include "object.h"
  8.  
  9. #ifdef _WIN32 || WIN32
  10. #include <SDL.h>
  11. #elif defined(__unix__)
  12. #include <SDL2/SDL.h>
  13. #endif
  14.  
  15. const int WIDTH = 600;
  16. const int HEIGHT = 400;
  17.  
  18. class camera
  19. {
  20. public:
  21. int imgWidth, imgHeight;
  22. float fov, _near, _far;
  23. float bottom, left, top, right, aspectRatio;
  24. matrix44 camToWorld;
  25. matrix44 worldToCamera;
  26.  
  27. vec3 _from, _at, _up;
  28. vec3 axisX, axisY, axisZ;
  29.  
  30. public:
  31. camera();
  32. camera(const vec3& from, const vec3& at, const vec3& up,
  33. const float& f, const float& n,
  34. const int& windowWidth, const int& windowHeight, const float& far) :
  35. fov(f), _near(n), imgWidth(windowWidth), imgHeight(windowHeight),
  36. _from(from), _at(at), _up(up), _far(far)
  37. {
  38. float radfov = fov * (3.141592f / 180.f);
  39. top = tan(radfov / 2.f);
  40. bottom = -top;
  41. aspectRatio = (float)(windowWidth / windowHeight);
  42. right = tan(radfov / 2.f) * aspectRatio;
  43. left = -right;
  44.  
  45. look_at(from, at, up);
  46. }
  47.  
  48.  
  49. void look_at(const vec3& from, const vec3& at, const vec3& up)
  50. {
  51. axisZ = from - at;
  52. axisZ.make_unit_vector();
  53. axisY = up - (dot(up, axisZ) / dot(axisZ, axisZ)) * axisZ;
  54. axisY.make_unit_vector();
  55. axisX = cross(axisY, axisZ);
  56. axisX.make_unit_vector();
  57.  
  58. camToWorld = matrix44(
  59. axisX.x(), axisX.y(), axisX.z(), 0.0,
  60. axisY.x(), axisY.y(), axisY.z(), 0.0,
  61. axisZ.x(), axisZ.y(), axisZ.z(), 0.0,
  62. from.x(), from.y(), from.z(), 1.0
  63. );
  64. worldToCamera = camToWorld.inverse();
  65. }
  66.  
  67. bool compute_pixel_coordinates(const vec3& pWorld, vec2& praster)
  68. {
  69. vec3 algo, algo2;
  70.  
  71. matrix44 multi = matrix44(
  72. 2 * _near / (right - left), 0.0, 0.0, 0.0,
  73. 0.0, 2 * _near / (bottom - top), 0.0, 0.0,
  74. -(right + left) / (right - left), -(bottom + top) / (bottom - top), (_far + _near) / (_far - _near), 1.0,
  75. 0.0, 0.0, -(2 * _near) / (_far - _near), 0.0
  76. );
  77.  
  78. worldToCamera.mult_point_matrix(pWorld, algo);
  79.  
  80. vec3 mProjecao = vec3(
  81. algo.x() * (_near / algo.z()),
  82. algo.y() * (_near / algo.z()),
  83. _near
  84. );
  85.  
  86.  
  87. multi.mult_point_matrix(mProjecao, algo2);
  88.  
  89. praster = vec2((1 + algo2.x()) / 2 * imgWidth, (1 - algo2.y()) / 2 * imgHeight);
  90.  
  91. vec3 estouNaFrente = pWorld - _from;
  92.  
  93. estouNaFrente.make_unit_vector();
  94.  
  95. float produtoEscalarMenorZero = dot(estouNaFrente, axisZ);
  96.  
  97. // Estamos vendo se a camera está dentro do macaco, fazendo produto escalar com o eixo para ver
  98.  
  99. if ((bottom <= algo.y() && algo.y() <= top) && (left <= algo.x() && algo.x() <= right) && produtoEscalarMenorZero <= 0)
  100. {
  101. return true;
  102. } else {
  103.  
  104. return false;
  105. //calcula a cos(de algo), se der positivo, da false
  106. }
  107.  
  108. }
  109.  
  110. void desenharLinha(SDL_Renderer *vemDoMain, vec2 &ponto1, vec2 &ponto2){
  111. vec2 diretor = ponto1 - ponto2;
  112. int fInt = (int) diretor.length();
  113. diretor.make_unit_vector();
  114.  
  115. vec2 aux = ponto2;
  116. for(int iter = 0; iter < fInt; iter++){
  117. SDL_RenderDrawPoint(vemDoMain, aux.x(), aux.y());
  118. aux += diretor;
  119. }
  120.  
  121.  
  122. }
  123.  
  124. int getOutcode(vec2 p, int xMin, int xMax, int yMin, int yMax){
  125. int inside = 0;
  126. int left = 1;
  127. int right = 2;
  128. int bottom = 4;
  129. int top = 8;
  130.  
  131. if(p.y() > yMax){
  132. inside = top |= inside;
  133. }
  134. if(p.y() < yMin){
  135. inside = bottom |= inside;
  136. }
  137. if(p.x() > xMax){
  138. inside = right |= inside;
  139. }
  140. if(p.x() < xMin){
  141. inside = left |= inside;
  142. }
  143. return inside;
  144. }
  145.  
  146. bool ClipLine(vec2 &p0, vec2 &p1, int xMin, int xMax, int yMin, int yMax){
  147. int outcode0 = getOutcode(p0, xMin, xMax, yMin, yMax);
  148. int outcode1 = getOutcode(p1, xMin, xMax, yMin, yMax);
  149.  
  150. float slope = (p1.y() - p0.y())/(p1.x() - p0.x());
  151. float novoX, novoY = 0;
  152.  
  153. bool accept = false;
  154.  
  155. while(true){
  156. if(outcode0 == 0 && outcode1 == 0){
  157. accept = true;
  158. break;
  159. } else if (outcode0 & outcode1){
  160. break;
  161. } else {
  162. int outcodeOutside = outcode1 != 0? outcode1 : outcode0;
  163. if (outcodeOutside & 8){
  164. novoX = p0.x() + (1.0/slope)*((float)yMax - p0.y());
  165. novoY = (float)yMax;
  166. } else if (outcodeOutside & 4){
  167. novoX = p0.x() + (1.0/slope)*((float)yMin - p0.y());
  168. novoY = yMin;
  169. } else if (outcodeOutside & 2){
  170. novoX = (float)xMax;
  171. novoY = p0.y() + slope*((float)xMax - p0.x());
  172. } else if (outcodeOutside & 1){
  173. novoX = (float)xMin;
  174. novoY = p0.y() + slope*(xMin - p0.x());
  175. }
  176. if (outcodeOutside == outcode0){
  177. p0 = vec2(novoX, novoY);
  178. outcode0 = getOutcode(p0, xMin, xMax, yMin, yMax);
  179. } else {
  180. p1 = vec2(novoX, novoY);
  181. outcode1 = getOutcode(p1, xMin, xMax, yMin, yMax);
  182. }
  183. }
  184. }
  185. return accept;
  186. }
  187.  
  188.  
  189. void render_scene(std::vector<Obj> objs, SDL_Renderer* renderer) {
  190.  
  191. vec3 light(0.0f, 0.0f, -1.0f);
  192. light.make_unit_vector();
  193.  
  194. for (auto obj : objs)
  195. {
  196. for (int i = 0; i < obj.mesh.tris.size(); i++)
  197. {
  198. vec2 praster1;
  199. vec2 praster2;
  200. vec2 praster3;
  201. vec3 col(255, 255, 255);
  202. SDL_SetRenderDrawColor(renderer, 255, 255, 255, SDL_ALPHA_OPAQUE);
  203.  
  204. bool v1, v2, v3;
  205. v1 = compute_pixel_coordinates(obj.mesh.tris[i].vertex[0].pos, praster1);
  206. v2 = compute_pixel_coordinates(obj.mesh.tris[i].vertex[1].pos, praster2);
  207. v3 = compute_pixel_coordinates(obj.mesh.tris[i].vertex[2].pos, praster3);
  208.  
  209.  
  210.  
  211.  
  212. if (v1 && v2){
  213. vec2 aux_praster1 = praster1;
  214. vec2 aux_praster2 = praster2;
  215.  
  216. if(ClipLine(aux_praster1, aux_praster2, 0, WIDTH, 0, HEIGHT)){
  217. desenharLinha(renderer, aux_praster1, aux_praster2);
  218. }
  219. }
  220. if (v1 && v3){
  221. vec2 aux_praster1 = praster1;
  222. vec2 aux_praster3 = praster3;
  223.  
  224. if(ClipLine(aux_praster1, aux_praster3, 0, WIDTH, 0, HEIGHT)){
  225. desenharLinha(renderer, aux_praster1, aux_praster3);
  226. }
  227. }
  228. if (v2 && v3){
  229. vec2 aux_praster2 = praster2;
  230. vec2 aux_praster3 = praster3;
  231.  
  232. if(ClipLine(aux_praster2, aux_praster3, 0, WIDTH, 0, HEIGHT)){
  233. desenharLinha(renderer, aux_praster2, aux_praster3);
  234. }
  235. }
  236. }
  237. }
  238. }
  239. };
  240.  
  241.  
  242. #endif
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement