shape.cpp 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. /*
  2. * DoRayMe - a quick and dirty Raytracer
  3. * Object implementation
  4. *
  5. * Created by Manoël Trapier
  6. * Copyright (c) 2020 986-Studio.
  7. *
  8. */
  9. #include <ray.h>
  10. #include <shape.h>
  11. #include <matrix.h>
  12. #include <tuple.h>
  13. #include <intersect.h>
  14. Shape::Shape(ShapeType type)
  15. {
  16. this->parent = nullptr;
  17. this->dropShadow = true;
  18. this->type = type;
  19. this->localTransformMatrix = Matrix4().identity();
  20. this->updateTransform();
  21. }
  22. Intersect Shape::intersect(Ray r)
  23. {
  24. return this->localIntersect(this->invTransform(r));
  25. };
  26. Tuple Shape::normalToWorld(Tuple normalVector)
  27. {
  28. Tuple world_normal = this->transposedInverseTransform * normalVector;
  29. /* W may get wrong, so hack it. This is perfectly normal as we are using a 4x4 matrix instead of a 3x3 */
  30. world_normal.w = 0;
  31. return world_normal.normalise();
  32. };
  33. Tuple Shape::normalAt(Tuple point)
  34. {
  35. Tuple local_point = this->worldToObject(point);
  36. Tuple local_normal = this->localNormalAt(local_point);
  37. Tuple world_normal = this->normalToWorld(local_normal);
  38. return world_normal;
  39. }
  40. void Shape::updateTransform()
  41. {
  42. this->transformMatrix = this->localTransformMatrix;
  43. if (this->parent != nullptr)
  44. {
  45. this->transformMatrix = this->parent->transformMatrix * this->transformMatrix;
  46. }
  47. this->inverseTransform = this->transformMatrix.inverse();
  48. this->transposedInverseTransform = this->inverseTransform.transpose();
  49. }
  50. void Shape::setTransform(Matrix transform)
  51. {
  52. this->localTransformMatrix = transform;
  53. this->updateTransform();
  54. }
  55. BoundingBox Shape::getBounds()
  56. {
  57. BoundingBox ret;
  58. ret.min = this->objectToWorld(Point(-1, -1, -1));
  59. ret.max = this->objectToWorld(Point(1, 1, 1));
  60. return ret;
  61. }
  62. void Shape::dumpMe(FILE *fp)
  63. {
  64. fprintf(fp, "\"Material\": {\n");
  65. this->material.dumpMe(fp);
  66. fprintf(fp, "},\n");
  67. fprintf(fp, "\"DropShadow\": %d,\n", this->dropShadow);
  68. }