spriteAPI.h 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. 
  2. #ifndef DFPSR_SPRITE_ENGINE
  3. #define DFPSR_SPRITE_ENGINE
  4. #include "../../DFPSR/includeFramework.h"
  5. #include "orthoAPI.h"
  6. #include "lightAPI.h"
  7. #include <assert.h>
  8. #include <limits>
  9. namespace dsr {
  10. // TODO: Make into a constructor for each vector type
  11. inline FVector3D parseFVector3D(const ReadableString& content) {
  12. List<String> args = string_split(content, U',');
  13. if (args.length() != 3) {
  14. printText("Expected a vector of three decimal values.\n");
  15. return FVector3D();
  16. } else {
  17. return FVector3D(string_toDouble(args[0]), string_toDouble(args[1]), string_toDouble(args[2]));
  18. }
  19. }
  20. // A 2D image with depth and normal images for deferred light.
  21. // To be rendered into images in advance for maximum detail level.
  22. struct SpriteInstance {
  23. public:
  24. int32_t typeIndex;
  25. Direction direction;
  26. IVector3D location; // Mini-tile coordinates.
  27. bool shadowCasting;
  28. uint64_t userData; // Can be used to store additional information needed for specific games.
  29. public:
  30. SpriteInstance(int typeIndex, Direction direction, const IVector3D& location, bool shadowCasting, uint64_t userData = 0)
  31. : typeIndex(typeIndex), direction(direction), location(location), shadowCasting(shadowCasting), userData(userData) {}
  32. };
  33. struct DenseModelImpl;
  34. using DenseModel = std::shared_ptr<struct DenseModelImpl>;
  35. DenseModel DenseModel_create(const Model& original);
  36. // A 3D model that can be rotated freely.
  37. // To be rendered during game-play to allow free rotation.
  38. struct ModelInstance {
  39. public:
  40. int typeIndex;
  41. Transform3D location; // 3D tile coordinates with translation and 3-axis rotation allowed.
  42. uint64_t userData; // Can be used to store additional information needed for specific games.
  43. public:
  44. ModelInstance(int typeIndex, const Transform3D& location, uint64_t userData = 0)
  45. : typeIndex(typeIndex), location(location), userData(userData) {}
  46. };
  47. class SpriteWorldImpl;
  48. using SpriteWorld = std::shared_ptr<SpriteWorldImpl>;
  49. // Sprite types
  50. int spriteWorld_loadSpriteTypeFromFile(const String& folderPath, const String& spriteName);
  51. int spriteWorld_getSpriteTypeCount();
  52. String spriteWorld_getSpriteTypeName(int index);
  53. // Model types
  54. int spriteWorld_loadModelTypeFromFile(const String& folderPath, const String& visibleModelName, const String& shadowModelName);
  55. int spriteWorld_getModelTypeCount();
  56. String spriteWorld_getModelTypeName(int index);
  57. SpriteWorld spriteWorld_create(OrthoSystem ortho, int shadowResolution);
  58. void spriteWorld_addBackgroundSprite(SpriteWorld& world, const SpriteInstance& sprite);
  59. void spriteWorld_addBackgroundModel(SpriteWorld& world, const ModelInstance& instance);
  60. void spriteWorld_addTemporarySprite(SpriteWorld& world, const SpriteInstance& sprite);
  61. void spriteWorld_addTemporaryModel(SpriteWorld& world, const ModelInstance& instance);
  62. // SpriteInstance& sprite, const IVector3D origin, const IVector3D minBound, const IVector3D maxBound -> bool selected
  63. using SpriteSelection = std::function<bool(SpriteInstance&, const IVector3D, const IVector3D, const IVector3D)>;
  64. // Remove sprites using an axis aligned serach box in mini-tile coordinates and a lambda filter.
  65. // Use userData in the lambda's first argument to get ownership information.
  66. // Return true for each sprite to remove from the background.
  67. void spriteWorld_removeBackgroundSprites(SpriteWorld& world, const IVector3D& searchMinBound, const IVector3D& searchMaxBound, const SpriteSelection& filter);
  68. // Erasing every sprite within the bound.
  69. void spriteWorld_removeBackgroundSprites(SpriteWorld& world, const IVector3D& searchMinBound, const IVector3D& searchMaxBound);
  70. // ModelInstance& model, const IVector3D origin, const IVector3D minBound, const IVector3D maxBound -> bool selected.
  71. using ModelSelection = std::function<bool(ModelInstance&, const IVector3D, const IVector3D, const IVector3D)>;
  72. // Remove models using an axis aligned serach box in mini-tile coordinates and a lambda filter.
  73. // Use userData in the lambda's first argument to get ownership information.
  74. // Return true for each model to remove from the background.
  75. void spriteWorld_removeBackgroundModels(SpriteWorld& world, const IVector3D& searchMinBound, const IVector3D& searchMaxBound, const ModelSelection& filter);
  76. // Erasing every model within the bound.
  77. void spriteWorld_removeBackgroundModels(SpriteWorld& world, const IVector3D& searchMinBound, const IVector3D& searchMaxBound);
  78. // Create a point light that only exists until the next call to spriteWorld_clearTemporary.
  79. // position is in tile unit world-space.
  80. void spriteWorld_createTemporary_pointLight(SpriteWorld& world, const FVector3D position, float radius, float intensity, ColorRgbI32 color, bool shadowCasting);
  81. void spriteWorld_createTemporary_directedLight(SpriteWorld& world, const FVector3D direction, float intensity, ColorRgbI32 color);
  82. void spriteWorld_clearTemporary(SpriteWorld& world);
  83. // Draw the world using the current camera at the center of colorTarget.
  84. void spriteWorld_draw(SpriteWorld& world, AlignedImageRgbaU8& colorTarget);
  85. // Draw debug information.
  86. void spriteWorld_debug_octrees(SpriteWorld& world, AlignedImageRgbaU8& colorTarget);
  87. // The result is an approximation in mini-tile units.
  88. // The 3D system does not align with screen pixels for less than whole tile units.
  89. IVector3D spriteWorld_findGroundAtPixel(SpriteWorld& world, const AlignedImageRgbaU8& colorBuffer, const IVector2D& pixelLocation);
  90. // Approximates a mini-tile offset along the ground from the given pixel offset and moves the camera accordingly.
  91. // If the offset is too small, the camera might not move at all.
  92. void spriteWorld_moveCameraInPixels(SpriteWorld& world, const IVector2D& pixelOffset);
  93. // Get internal buffers after rendering.
  94. // Reading before having drawn the world for the first time will return null because the world does not yet know the target resolution.
  95. // By not being a part of rendering itself, it cannot go back in time and speed up rendering, so only use for debugging.
  96. // TODO: Make another feature for actually disabling dynamic light on low-end machines.
  97. AlignedImageRgbaU8 spriteWorld_getDiffuseBuffer(SpriteWorld& world);
  98. OrderedImageRgbaU8 spriteWorld_getNormalBuffer(SpriteWorld& world);
  99. OrderedImageRgbaU8 spriteWorld_getLightBuffer(SpriteWorld& world);
  100. AlignedImageF32 spriteWorld_getHeightBuffer(SpriteWorld& world);
  101. // Camera's location as a 3D coordinate in world mini-tile coordinates.
  102. IVector3D spriteWorld_getCameraLocation(const SpriteWorld& world);
  103. void spriteWorld_setCameraLocation(SpriteWorld& world, const IVector3D miniTileLocation);
  104. // Access the index of the camera's fixed direction.
  105. // This is not an index selecting the camera itself, only selecting the viewing angle.
  106. // TODO: Implement bound checks or a system that's easier to understand.
  107. int spriteWorld_getCameraDirectionIndex(const SpriteWorld& world);
  108. void spriteWorld_setCameraDirectionIndex(SpriteWorld& world, int index);
  109. // Get the current direction's orthogonal axis system.
  110. // This can be used to convert between world and screen coordinates using the camera location.
  111. OrthoView& spriteWorld_getCurrentOrthoView(SpriteWorld& world);
  112. // Get the whole game's orthogonal system for all camera angles.
  113. OrthoSystem& spriteWorld_getOrthoSystem(SpriteWorld& world);
  114. // Pre-conditions:
  115. // The model should be pre-transformed so that it can be rendered at the world origin.
  116. // Textures must be converted into vertex colors or else they will simply be ignored.
  117. // Enabling debug will save another file using a *Debug.png prefix with additional information.
  118. // Use it to find flaws in generated shadow shapes that are hard to see in raw data.
  119. // TODO: Hide OrthoSystem or expose it safely.
  120. void sprite_generateFromModel(const Model& visibleModel, const Model& shadowModel, const OrthoSystem& ortho, const String& targetPath, int cameraAngles, bool debug = false);
  121. // A simpler version writing the result to an image and a string instead of saving to files.
  122. void sprite_generateFromModel(ImageRgbaU8& targetAtlas, String& targetConfigText, const Model& visibleModel, const Model& shadowModel, const OrthoSystem& ortho, const String& targetPath, int cameraAngles);
  123. }
  124. #endif