// BlockyFroggy
// Copyright © 2017 John Ryland.
// All rights reserved.
#pragma once
#ifndef VOXEL_MODEL_H
#define VOXEL_MODEL_H
#include <vector>
#include <map>
#include <string>
#include <cstdint>
class VoxelTriangle
{
public:
struct { float m_x, m_y, m_z; } m_verts[3];
struct { float m_u, m_v; } m_uvs[3];
uint32_t m_axis;
};
class VoxelBox // (basically like a AABB - Axis aligned bounding box)
{
public:
float m_x, m_y, m_z, m_t; // position
float m_w, m_d, m_h; // size (able to scale non-uniformly, assuming z is up)
uint32_t m_color; // color
};
typedef std::vector<VoxelBox> VoxelBoxList;
typedef std::vector<VoxelTriangle> VoxelTriangleList;
struct CachedVoxelModel
{
bool m_dirty;
VoxelBoxList m_model;
VoxelTriangleList m_modelTriangles;
};
class VoxelModels
{
public:
VoxelModels();
~VoxelModels();
void reloadDataFromFile(const char* a_fileName, bool a_onlineAsset);
VoxelBoxList& getModel(const char* name, int xOff, int yOff, int w, int h, int d, bool direction, uint32_t* x_axis, uint32_t* z_axis);
VoxelTriangleList& getModelTriangles(const char* name, int xOff, int yOff, int w, int h, int d, bool direction, uint32_t* x_axis, uint32_t* z_axis);
void invalidateCache() { m_voxelModelCache.clear(); }
uint32_t getPixel(int x, int y) { if (size_t(y*256+x) < m_decodedData.size()) return ((uint32_t*)m_decodedData.data())[y*256+x]; return 0; }
void editPixel(int x, int y, uint32_t col) { if (size_t(y*256+x) < m_decodedData.size())
if ( ((uint32_t*)m_decodedData.data())[y*256+x] != col ) {
((uint32_t*)m_decodedData.data())[y*256+x] = col; m_dataChanged = true; } }
bool dataUpdated() { return m_dataChanged; }
void ackDataUpdated() { m_dataChanged = false; }
void* y_axis() { return (void*)m_decodedData.data(); }
private:
bool m_dataChanged = true;
void decodeData(const unsigned char* a_pngData, size_t a_dataLen);
std::vector<unsigned char> m_decodedData;
size_t m_decodedDataWidth, m_decodedDataHeight;
std::map<std::string,CachedVoxelModel> m_voxelModelCache;
};
#endif // VOXEL_MODEL_H