texturemap.h 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. /*
  2. * DoRayMe - a quick and dirty Raytracer
  3. * Texture Map header
  4. *
  5. * Created by Manoël Trapier
  6. * Copyright (c) 2020 986-Studio.
  7. *
  8. */
  9. #ifndef DORAYME_TEXTUREMAP_H
  10. #define DORAYME_TEXTUREMAP_H
  11. #include <math.h>
  12. #include <tuple.h>
  13. #include <uv_pattern.h>
  14. #include <colour.h>
  15. enum TextureMapType
  16. {
  17. SPHERICAL_MAP,
  18. PLANAR_MAP,
  19. CYLINDRICAL_MAP,
  20. };
  21. class TextureMap : public Pattern
  22. {
  23. private:
  24. TextureMapType type;
  25. UVPattern *pattern;
  26. public:
  27. TextureMap(TextureMapType type, UVPattern *pattern) : Pattern(Colour(0, 0, 0), Colour(0, 0, 0)),
  28. type(type), pattern(pattern) { };
  29. static void sphericalMap(Tuple point, double &u, double &v) {
  30. /* First compute the azimuthal angle
  31. * -π < theta <= π
  32. * angle increases clockwise as viewed from above,
  33. * which is opposite of what we want, but we'll fix it later.
  34. */
  35. double theta = atan2(point.x, point.z);
  36. /* vec is the vector pointing from the sphere's origin (the world origin)
  37. * to the point, which will also happen to be exactly equal to the sphere's
  38. * radius.
  39. */
  40. Tuple vec = Vector(point.x, point.y, point.z);
  41. double radius = vec.magnitude();
  42. /* Let's compute the polar angle
  43. * 0 <= phi <= π
  44. */
  45. double phi = acos(point.y / radius);
  46. /* -0.5 < raw_u <= 0.5 */
  47. double raw_u = theta / (2 * M_PI);
  48. /* 0 <= u < 1
  49. * here's also where we fix the direction of u. Subtract it from 1,
  50. * so that it increases counterclockwise as viewed from above.
  51. */
  52. u = 1 - (raw_u + 0.5);
  53. /* We want v to be 0 at the south pole of the sphere,
  54. * and 1 at the north pole, so we have to "flip it over"
  55. * by subtracting it from 1.
  56. */
  57. v = 1 - phi / M_PI;
  58. }
  59. static void planarMap(Tuple point, double &u, double &v) {
  60. u = fmod(point.x, 1);
  61. v = fmod(point.z, 1);
  62. }
  63. Colour patternAt(Tuple point)
  64. {
  65. double u,v;
  66. switch(this->type)
  67. {
  68. default:
  69. case SPHERICAL_MAP:
  70. this->sphericalMap(point, u, v);
  71. break;
  72. case PLANAR_MAP:
  73. this->planarMap(point, u, v);
  74. break;
  75. }
  76. return this->pattern->uvPatternAt(u, v);
  77. }
  78. void dumpMe(FILE *fp) {
  79. fprintf(fp, "\"Type\": \"TextureMap\",\n");
  80. Pattern::dumpMe(fp);
  81. }
  82. };
  83. #endif /* DORAYME_TEXTUREMAP_H */