+ material.BackfaceCulling = (material_flags & MATERIAL_FLAG_BACKFACE_CULLING) != 0;
+ if (!(material_flags & MATERIAL_FLAG_TILEABLE_HORIZONTAL)) {
+ material.TextureLayer[0].TextureWrapU = video::ETC_CLAMP_TO_EDGE;
+ material.TextureLayer[1].TextureWrapU = video::ETC_CLAMP_TO_EDGE;
+ }
+ if (!(material_flags & MATERIAL_FLAG_TILEABLE_VERTICAL)) {
+ material.TextureLayer[0].TextureWrapV = video::ETC_CLAMP_TO_EDGE;
+ material.TextureLayer[1].TextureWrapV = video::ETC_CLAMP_TO_EDGE;
+ }
+ }
+
+ bool isTileable() const
+ {
+ return (material_flags & MATERIAL_FLAG_TILEABLE_HORIZONTAL)
+ && (material_flags & MATERIAL_FLAG_TILEABLE_VERTICAL);
+ }
+
+ // Ordered for size, please do not reorder
+
+ video::ITexture *texture = nullptr;
+ video::ITexture *normal_texture = nullptr;
+ video::ITexture *flags_texture = nullptr;
+
+ u32 shader_id = 0;
+
+ u32 texture_id = 0;
+
+ u16 animation_frame_length_ms = 0;
+ u16 animation_frame_count = 1;
+
+ u8 material_type = TILE_MATERIAL_BASIC;
+ u8 material_flags =
+ //0 // <- DEBUG, Use the one below
+ MATERIAL_FLAG_BACKFACE_CULLING |
+ MATERIAL_FLAG_TILEABLE_HORIZONTAL|
+ MATERIAL_FLAG_TILEABLE_VERTICAL;
+
+ //! If true, the tile has its own color.
+ bool has_color = false;
+
+ std::vector<FrameSpec> *frames = nullptr;
+
+ /*!
+ * The color of the tile, or if the tile does not own
+ * a color then the color of the node owning this tile.
+ */
+ video::SColor color;
+
+ u8 scale;
+};
+
+/*!
+ * Defines a face of a node. May have up to two layers.
+ */
+struct TileSpec
+{
+ TileSpec() = default;
+
+ /*!
+ * Returns true if this tile can be merged with the other tile.
+ */
+ bool isTileable(const TileSpec &other) const {
+ for (int layer = 0; layer < MAX_TILE_LAYERS; layer++) {
+ if (layers[layer] != other.layers[layer])
+ return false;
+ if (!layers[layer].isTileable())
+ return false;
+ }
+ return rotation == 0
+ && rotation == other.rotation
+ && emissive_light == other.emissive_light;