|
@@ -35,46 +35,38 @@ OTHER DEALINGS IN THE SOFTWARE.
|
|
|
#include "StringUtils.h"
|
|
#include "StringUtils.h"
|
|
|
#include "Array.h"
|
|
#include "Array.h"
|
|
|
#include "Config.h"
|
|
#include "Config.h"
|
|
|
|
|
+#include "ReaderWriter.h"
|
|
|
|
|
+#include <cfloat>
|
|
|
|
|
|
|
|
namespace crown
|
|
namespace crown
|
|
|
{
|
|
{
|
|
|
namespace sprite_resource
|
|
namespace sprite_resource
|
|
|
{
|
|
{
|
|
|
|
|
|
|
|
-//-----------------------------------------------------------------------------
|
|
|
|
|
-struct FrameData
|
|
|
|
|
|
|
+struct SpriteFrame
|
|
|
{
|
|
{
|
|
|
- float x0, y0;
|
|
|
|
|
- float x1, y1;
|
|
|
|
|
-
|
|
|
|
|
- float scale_x, scale_y;
|
|
|
|
|
- float offset_x, offset_y;
|
|
|
|
|
|
|
+ StringId32 name;
|
|
|
|
|
+ Vector4 region; // [x0, y0, x1, y1]
|
|
|
|
|
+ Vector2 scale; // [Sx, Sy]
|
|
|
|
|
+ Vector2 offset; // [Ox, Oy]
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//-----------------------------------------------------------------------------
|
|
|
-void parse_frame(JSONElement frame, Array<StringId32>& names, Array<FrameData>& regions)
|
|
|
|
|
|
|
+void parse_frame(JSONElement e, SpriteFrame& frame)
|
|
|
{
|
|
{
|
|
|
- JSONElement name = frame.key("name");
|
|
|
|
|
- JSONElement region = frame.key("region");
|
|
|
|
|
- JSONElement offset = frame.key("offset");
|
|
|
|
|
- JSONElement scale = frame.key("scale");
|
|
|
|
|
-
|
|
|
|
|
- DynamicString frame_name;
|
|
|
|
|
- name.to_string(frame_name);
|
|
|
|
|
-
|
|
|
|
|
- StringId32 name_hash = string::murmur2_32(frame_name.c_str(), frame_name.length(), 0);
|
|
|
|
|
- FrameData fd;
|
|
|
|
|
- fd.x0 = region[0].to_float();
|
|
|
|
|
- fd.y0 = region[1].to_float();
|
|
|
|
|
- fd.x1 = region[2].to_float();
|
|
|
|
|
- fd.y1 = region[3].to_float();
|
|
|
|
|
- fd.offset_x = offset[0].to_float();
|
|
|
|
|
- fd.offset_y = offset[1].to_float();
|
|
|
|
|
- fd.scale_x = scale[0].to_float();
|
|
|
|
|
- fd.scale_y = scale[1].to_float();
|
|
|
|
|
-
|
|
|
|
|
- array::push_back(names, name_hash);
|
|
|
|
|
- array::push_back(regions, fd);
|
|
|
|
|
|
|
+ frame.name = e.key("name" ).to_string_id();
|
|
|
|
|
+ frame.region = e.key("region").to_vector4();
|
|
|
|
|
+ frame.offset = e.key("offset").to_vector2();
|
|
|
|
|
+ frame.scale = e.key("scale" ).to_vector2();
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+//-----------------------------------------------------------------------------
|
|
|
|
|
+void parse_animation(JSONElement e, SpriteAnimation& anim)
|
|
|
|
|
+{
|
|
|
|
|
+ anim.name = e.key("name").to_string_id();
|
|
|
|
|
+ anim.time = e.key("time").to_float();
|
|
|
|
|
+ anim.num_frames = 0;
|
|
|
|
|
+ anim.start_frame = 0;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//-----------------------------------------------------------------------------
|
|
@@ -86,77 +78,108 @@ void compile(Filesystem& fs, const char* resource_path, File* out_file)
|
|
|
|
|
|
|
|
JSONElement root = json.root();
|
|
JSONElement root = json.root();
|
|
|
|
|
|
|
|
- float width;
|
|
|
|
|
- float height;
|
|
|
|
|
- Array<StringId32> m_names(default_allocator());
|
|
|
|
|
- Array<FrameData> m_regions(default_allocator());
|
|
|
|
|
- Array<float> m_vertices(default_allocator());
|
|
|
|
|
- Array<uint16_t> m_indices(default_allocator());
|
|
|
|
|
-
|
|
|
|
|
// Read width/height
|
|
// Read width/height
|
|
|
- width = root.key("width").to_float();
|
|
|
|
|
- height = root.key("height").to_float();
|
|
|
|
|
|
|
+ const float width = root.key("width" ).to_float();
|
|
|
|
|
+ const float height = root.key("height").to_float();
|
|
|
|
|
+ const uint32_t num_frames = root.key("frames").size();
|
|
|
|
|
+ const uint32_t num_animations = root.key("animations").size();
|
|
|
|
|
|
|
|
- // Read frames
|
|
|
|
|
- JSONElement frames = root.key("frames");
|
|
|
|
|
- uint32_t num_frames = frames.size();
|
|
|
|
|
- for (uint32_t i = 0; i < num_frames; i++)
|
|
|
|
|
- {
|
|
|
|
|
- parse_frame(frames[i], m_names, m_regions);
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ BinaryWriter bw(*out_file);
|
|
|
|
|
|
|
|
|
|
+ Array<float> vertices(default_allocator());
|
|
|
|
|
+ Array<uint16_t> indices(default_allocator());
|
|
|
uint32_t num_idx = 0;
|
|
uint32_t num_idx = 0;
|
|
|
for (uint32_t i = 0; i < num_frames; i++)
|
|
for (uint32_t i = 0; i < num_frames; i++)
|
|
|
{
|
|
{
|
|
|
- const FrameData& fd = m_regions[i];
|
|
|
|
|
|
|
+ JSONElement e(root.key("frames")[i]);
|
|
|
|
|
+
|
|
|
|
|
+ SpriteFrame frame;
|
|
|
|
|
+ parse_frame(e, frame);
|
|
|
|
|
+
|
|
|
|
|
+ const SpriteFrame& fd = frame;
|
|
|
|
|
|
|
|
// Compute uv coords
|
|
// Compute uv coords
|
|
|
- const float u0 = fd.x0 / width;
|
|
|
|
|
- const float v0 = fd.y0 / height;
|
|
|
|
|
- const float u1 = (fd.x0 + fd.x1) / width;
|
|
|
|
|
- const float v1 = (fd.y0 + fd.y1) / height;
|
|
|
|
|
|
|
+ const float u0 = fd.region.x / width;
|
|
|
|
|
+ const float v0 = fd.region.y / height;
|
|
|
|
|
+ const float u1 = (fd.region.x + fd.region.z) / width;
|
|
|
|
|
+ const float v1 = (fd.region.y + fd.region.w) / height;
|
|
|
|
|
|
|
|
// Compute positions
|
|
// Compute positions
|
|
|
- const float w = fd.x1 / CE_PIXELS_PER_METER;
|
|
|
|
|
- const float h = fd.y1 / CE_PIXELS_PER_METER;
|
|
|
|
|
|
|
+ const float w = fd.region.z / CE_PIXELS_PER_METER;
|
|
|
|
|
+ const float h = fd.region.w / CE_PIXELS_PER_METER;
|
|
|
|
|
+
|
|
|
|
|
+ const float x0 = fd.scale.x * (-w * 0.5) + fd.offset.x;
|
|
|
|
|
+ const float y0 = fd.scale.y * (-h * 0.5) + fd.offset.y;
|
|
|
|
|
+ const float x1 = fd.scale.x * ( w * 0.5) + fd.offset.x;
|
|
|
|
|
+ const float y1 = fd.scale.y * ( h * 0.5) + fd.offset.y;
|
|
|
|
|
|
|
|
- const float x0 = fd.scale_x * (-w * 0.5) + fd.offset_x;
|
|
|
|
|
- const float y0 = fd.scale_y * (-h * 0.5) + fd.offset_y;
|
|
|
|
|
- const float x1 = fd.scale_x * ( w * 0.5) + fd.offset_x;
|
|
|
|
|
- const float y1 = fd.scale_y * ( h * 0.5) + fd.offset_y;
|
|
|
|
|
|
|
+ CE_LOGD("%f %f %f %f", x0, y0, x1, y1);
|
|
|
|
|
|
|
|
- array::push_back(m_vertices, x0); array::push_back(m_vertices, y0); // position
|
|
|
|
|
- array::push_back(m_vertices, u0); array::push_back(m_vertices, v0); // uv
|
|
|
|
|
|
|
+ array::push_back(vertices, x0); array::push_back(vertices, y0); // position
|
|
|
|
|
+ array::push_back(vertices, u0); array::push_back(vertices, v0); // uv
|
|
|
|
|
|
|
|
- array::push_back(m_vertices, x1); array::push_back(m_vertices, y0); // position
|
|
|
|
|
- array::push_back(m_vertices, u1); array::push_back(m_vertices, v0); // uv
|
|
|
|
|
|
|
+ array::push_back(vertices, x1); array::push_back(vertices, y0); // position
|
|
|
|
|
+ array::push_back(vertices, u1); array::push_back(vertices, v0); // uv
|
|
|
|
|
|
|
|
- array::push_back(m_vertices, x1); array::push_back(m_vertices, y1); // position
|
|
|
|
|
- array::push_back(m_vertices, u1); array::push_back(m_vertices, v1); // uv
|
|
|
|
|
|
|
+ array::push_back(vertices, x1); array::push_back(vertices, y1); // position
|
|
|
|
|
+ array::push_back(vertices, u1); array::push_back(vertices, v1); // uv
|
|
|
|
|
|
|
|
- array::push_back(m_vertices, x0); array::push_back(m_vertices, y1); // position
|
|
|
|
|
- array::push_back(m_vertices, u0); array::push_back(m_vertices, v1); // uv
|
|
|
|
|
|
|
+ array::push_back(vertices, x0); array::push_back(vertices, y1); // position
|
|
|
|
|
+ array::push_back(vertices, u0); array::push_back(vertices, v1); // uv
|
|
|
|
|
|
|
|
- array::push_back(m_indices, uint16_t(num_idx)); array::push_back(m_indices, uint16_t(num_idx + 1)); array::push_back(m_indices, uint16_t(num_idx + 2));
|
|
|
|
|
- array::push_back(m_indices, uint16_t(num_idx)); array::push_back(m_indices, uint16_t(num_idx + 2)); array::push_back(m_indices, uint16_t(num_idx + 3));
|
|
|
|
|
|
|
+ array::push_back(indices, uint16_t(num_idx)); array::push_back(indices, uint16_t(num_idx + 1)); array::push_back(indices, uint16_t(num_idx + 2));
|
|
|
|
|
+ array::push_back(indices, uint16_t(num_idx)); array::push_back(indices, uint16_t(num_idx + 2)); array::push_back(indices, uint16_t(num_idx + 3));
|
|
|
num_idx += 4;
|
|
num_idx += 4;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- SpriteHeader h;
|
|
|
|
|
- h.num_frames = array::size(m_names);
|
|
|
|
|
- h.num_vertices = array::size(m_vertices) / 4; // 4 components per vertex
|
|
|
|
|
- h.num_indices = array::size(m_indices);
|
|
|
|
|
|
|
+ const uint32_t num_vertices = array::size(vertices) / 4; // 4 components per vertex
|
|
|
|
|
+ const uint32_t num_indices = array::size(indices);
|
|
|
|
|
+
|
|
|
|
|
+ // Write animations
|
|
|
|
|
+ Array<SpriteAnimation> animations(default_allocator());
|
|
|
|
|
+ Array<uint32_t> frames(default_allocator());
|
|
|
|
|
+
|
|
|
|
|
+ for (uint32_t i = 0; i < num_animations; i++)
|
|
|
|
|
+ {
|
|
|
|
|
+ JSONElement e(root.key("animations")[i]);
|
|
|
|
|
+
|
|
|
|
|
+ SpriteAnimation anim;
|
|
|
|
|
+ parse_animation(e, anim);
|
|
|
|
|
+
|
|
|
|
|
+ // Read frames
|
|
|
|
|
+ const uint32_t num_frames = e.key("frames").size();
|
|
|
|
|
+
|
|
|
|
|
+ anim.num_frames = num_frames;
|
|
|
|
|
+ anim.start_frame = array::size(frames); // Relative offset
|
|
|
|
|
+
|
|
|
|
|
+ for (uint32_t ff = 0; ff < num_frames; ff++)
|
|
|
|
|
+ array::push_back(frames, (uint32_t) e.key("frames")[ff].to_int());
|
|
|
|
|
+
|
|
|
|
|
+ array::push_back(animations, anim);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // Write header
|
|
|
|
|
+ bw.write(uint32_t(0)); // vb
|
|
|
|
|
+ bw.write(uint32_t(0)); // ib
|
|
|
|
|
+ bw.write(num_animations); uint32_t offt = sizeof(SpriteHeader);
|
|
|
|
|
+ bw.write(offt);
|
|
|
|
|
+ bw.write(num_vertices); offt += sizeof(SpriteAnimation) * array::size(animations) + sizeof(uint32_t) * array::size(frames);
|
|
|
|
|
+ bw.write(offt);
|
|
|
|
|
+ bw.write(num_indices); offt += sizeof(float) * array::size(vertices);
|
|
|
|
|
+ bw.write(offt);
|
|
|
|
|
+
|
|
|
|
|
+ if (array::size(animations))
|
|
|
|
|
+ bw.write(array::begin(animations), sizeof(SpriteAnimation) * array::size(animations));
|
|
|
|
|
+
|
|
|
|
|
+ if (array::size(frames))
|
|
|
|
|
+ bw.write(array::begin(frames), sizeof(uint32_t) * array::size(frames));
|
|
|
|
|
|
|
|
- uint32_t offt = sizeof(SpriteHeader);
|
|
|
|
|
- /*h.frame_names_offset = offt*/; offt += sizeof(StringId32) * h.num_frames;
|
|
|
|
|
- h.vertices_offset = offt; offt += sizeof(float) * array::size(m_vertices);
|
|
|
|
|
- h.indices_offset = offt; offt += sizeof(uint16_t) * array::size(m_indices);
|
|
|
|
|
|
|
+ if (array::size(vertices))
|
|
|
|
|
+ bw.write(array::begin(vertices), sizeof(float) * array::size(vertices));
|
|
|
|
|
|
|
|
- out_file->write((char*) &h, sizeof(SpriteHeader));
|
|
|
|
|
- out_file->write((char*) array::begin(m_names), sizeof(StringId32) * array::size(m_names));
|
|
|
|
|
- out_file->write((char*) array::begin(m_vertices), sizeof(float) * array::size(m_vertices));
|
|
|
|
|
- out_file->write((char*) array::begin(m_indices), sizeof(uint16_t) * array::size(m_indices));
|
|
|
|
|
|
|
+ if (array::size(indices))
|
|
|
|
|
+ bw.write(array::begin(indices), sizeof(uint16_t) * array::size(indices));
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
} // namespace sprite_resource
|
|
} // namespace sprite_resource
|
|
|
-} // namespace crown
|
|
|
|
|
|
|
+} // namespace crown
|