Bring changes over from work done for n64 game jam

This commit is contained in:
James Lambert 2023-08-05 13:07:08 -06:00
parent a1542b34fe
commit 1ab857e008
11 changed files with 499 additions and 42 deletions

View file

@ -75,6 +75,39 @@ end
exports.is_raw = is_raw
--- @table CommentType
local CommentType = {}
local function comment(value)
return setmetatable({ value = value}, CommentType)
end
CommentType.__index = CommentType;
function CommentType.__tostring(comment)
return 'comment(' .. comment.value .. ')'
end
--- renders a string as a comment
---@function comment
---@tparam string value
---@treturn CommentType result
exports.comment = comment
--- returns true if value is a CommentType
---@function is_comment
---@tparam any value
---@treturn boolean result
local function is_comment(value)
return getmetatable(value) == CommentType
end
exports.is_comment = is_comment
--- alias for raw("'\n")
--- @table newline
exports.newline = raw('\n')
--- alias for raw("NULL")
--- @table null_value
local null_value = raw("NULL")

View file

@ -4,6 +4,7 @@ local Vector3 = {}
local Box3 = {}
local Quaternion = {}
local Color4 = {}
local Plane3 = {}
--- creates a new 3d vector
--- @function vector3
@ -69,6 +70,32 @@ local function isQuaternion(obj)
return type(obj) == 'table' and type(obj.x) == 'number' and type(obj.y) == 'number' and type(obj.z) == 'number' and type(obj.w) == 'number'
end
--- creates a new Plane3
--- @function plane3
--- @tparam Vector3 normal the normal of the plane
--- @tparam number d the distance to the origin
--- @treturn Plane3
local function plane3(normal, d)
return setmetatable({ normal = normal, d = d }, Plane3)
end
--- creates a new Plane3 using a point and a normal
--- @function plane3
--- @tparam Vector3 normal the normal of the plane
--- @tparam Vector3 point a point on the plane
--- @treturn Plane3
local function plane3_with_point(normal, point)
if not isVector3(normal) then
error('plane3_with_point expected vector as first operand got ' .. type(b), 2)
end
if not isVector3(point) then
error('plane3_with_point expected vector as second operand got ' .. type(b), 2)
end
return setmetatable({ normal = normal, d = -normal:dot(point) }, Plane3)
end
--- @type Vector3
--- @tfield number x
--- @tfield number y
@ -136,6 +163,15 @@ function Vector3.__sub(a, b)
return vector3(a.x - b.x, a.y - b.y, a.z - b.z)
end
--- @function __unm
--- @tparam number|Vector3 b
--- @treturn Vector3
function Vector3.__unm(a)
return vector3(-a.x, -a.y, -a.z)
end
--- @function __mul
--- @tparam number|Vector3 b
--- @treturn Vector3
@ -228,6 +264,9 @@ end
--- @tparam Vector3 b
--- @treturn number
function Vector3.dot(a, b)
if not isVector3(b) then
error('Vector3.dot expected another vector as second operand', 2)
end
return a.x * b.x + a.y * b.y + a.z * b.z
end
@ -248,6 +287,12 @@ end
--- @tparam Vector3 b
--- @treturn Vector3
function Vector3.lerp(a, b, lerp)
if not isVector3(b) then
error('Vector3.lerp expected another vector as second operand', 2)
end
if type(lerp) ~= 'number' then
error('Vector3.lerp expected number as third operand', 2)
end
return a * (1 - lerp) + b * lerp
end
@ -543,6 +588,15 @@ function Color4.lerp(a, b, lerp)
return a * (1 - lerp) + b * lerp
end
--- @type Plane3
--- @tfield Vector3 normal
--- @tfield number d
Plane3.__index = Plane3;
function Plane3.distance_to_point(plane, point)
return plane.normal:dot(point) + plane.d
end
return {
vector3 = vector3,
Vector3 = Vector3,
@ -555,4 +609,7 @@ return {
isQuaternion = isQuaternion,
color4 = color4,
isColor4 = isColor4,
plane3 = plane3,
plane3_with_point = plane3_with_point,
Plane3 = Plane3,
}

View file

@ -72,7 +72,7 @@ int StructureEntryDataChunk::CalculateEstimatedLength() {
return mName.length() + 4 + mEntry->GetEstimatedLength();
}
StructureDataChunk::StructureDataChunk(): DataChunk() {}
StructureDataChunk::StructureDataChunk(): DataChunk(), mHasNewlineHints(false) {}
StructureDataChunk::StructureDataChunk(const aiVector3D& vector) : StructureDataChunk() {
AddPrimitive(vector.x);
@ -96,6 +96,10 @@ StructureDataChunk::StructureDataChunk(const aiAABB& bb) : StructureDataChunk()
void StructureDataChunk::Add(std::unique_ptr<DataChunk> entry) {
if (dynamic_cast<NewlineHintChunk*>(entry.get()) != nullptr) {
mHasNewlineHints = true;
}
mChildren.push_back(std::move(entry));
}
@ -106,13 +110,18 @@ void StructureDataChunk::Add(const std::string& name, std::unique_ptr<DataChunk>
)));
}
void StructureDataChunk::AddNewlineHint() {
mHasNewlineHints = true;
mChildren.push_back(std::unique_ptr<DataChunk>(new NewlineHintChunk()));
}
#define MAX_CHARS_PER_LINE 80
#define SPACES_PER_INDENT 4
bool StructureDataChunk::Output(std::ostream& output, int indentLevel, int linePrefix) {
output << '{';
OutputChildren(mChildren, output, indentLevel, linePrefix + GetEstimatedLength(), true);
OutputChildren(mChildren, output, indentLevel, linePrefix + GetEstimatedLength(), true, !mHasNewlineHints);
output << '}';
return true;
@ -138,7 +147,7 @@ void StructureDataChunk::OutputIndent(std::ostream& output, int indentLevel) {
}
}
void StructureDataChunk::OutputChildren(std::vector<std::unique_ptr<DataChunk>>& children, std::ostream& output, int indentLevel, int totalLength, bool trailingComma) {
void StructureDataChunk::OutputChildren(std::vector<std::unique_ptr<DataChunk>>& children, std::ostream& output, int indentLevel, int totalLength, bool trailingComma, bool includeNewlines) {
bool needsComma = false;
if (totalLength < MAX_CHARS_PER_LINE) {
@ -147,17 +156,33 @@ void StructureDataChunk::OutputChildren(std::vector<std::unique_ptr<DataChunk>>&
output << ", ";
}
if (dynamic_cast<NewlineHintChunk*>(children[i].get()) != nullptr) {
needsComma = false;
continue;
}
needsComma = children[i]->Output(output, indentLevel, 0);
}
} else {
output << '\n';
bool needsIndent = true;
++indentLevel;
for (size_t i = 0; i < children.size(); ++i) {
if (needsIndent) {
OutputIndent(output, indentLevel);
if (children[i]->Output(output, indentLevel, indentLevel * SPACES_PER_INDENT) && (i < children.size() - 1 || trailingComma)) {
output << ",\n";
needsIndent = false;
} else {
output << ' ';
}
if (children[i]->Output(output, indentLevel, indentLevel * SPACES_PER_INDENT) && (i < children.size() - 1 || trailingComma)) {
output << ",";
}
if (includeNewlines) {
output << "\n";
needsIndent = true;
} else if (dynamic_cast<NewlineHintChunk*>(children[i].get()) != nullptr) {
needsIndent = true;
}
}
--indentLevel;
@ -176,7 +201,7 @@ void MacroDataChunk::Add(std::unique_ptr<DataChunk> entry) {
bool MacroDataChunk::Output(std::ostream& output, int indentLevel, int linePrefix) {
output << mMacroName << '(';
StructureDataChunk::OutputChildren(mParameters, output, indentLevel, mSingleLine ? 0 : linePrefix + GetEstimatedLength(), false);
StructureDataChunk::OutputChildren(mParameters, output, indentLevel, mSingleLine ? 0 : linePrefix + GetEstimatedLength(), false, true);
output << ')';
return true;
@ -207,3 +232,14 @@ bool CommentDataChunk::Output(std::ostream& output, int indentLevel, int linePre
int CommentDataChunk::CalculateEstimatedLength() {
return 6 + mComment.length();
}
NewlineHintChunk::NewlineHintChunk() : DataChunk() {}
bool NewlineHintChunk::Output(std::ostream& output, int indentLevel, int linePrefix) {
output << "\n";
return false;
}
int NewlineHintChunk::CalculateEstimatedLength() {
return 0;
}

View file

@ -96,14 +96,17 @@ public:
)));
}
void AddNewlineHint();
virtual bool Output(std::ostream& output, int indentLevel, int linePrefix);
static void OutputIndent(std::ostream& output, int indentLevel);
static void OutputChildren(std::vector<std::unique_ptr<DataChunk>>& children, std::ostream& output, int indentLevel, int totalLength, bool trailingComma);
static void OutputChildren(std::vector<std::unique_ptr<DataChunk>>& children, std::ostream& output, int indentLevel, int totalLength, bool trailingComma, bool includeNewlines);
protected:
virtual int CalculateEstimatedLength();
private:
std::vector<std::unique_ptr<DataChunk>> mChildren;
bool mHasNewlineHints;
};
class MacroDataChunk : public DataChunk {
@ -139,4 +142,12 @@ private:
std::string mComment;
};
class NewlineHintChunk : public DataChunk {
public:
NewlineHintChunk();
virtual bool Output(std::ostream& output, int indentLevel, int linePrefix);
protected:
virtual int CalculateEstimatedLength();
};
#endif

View file

@ -88,6 +88,7 @@ std::unique_ptr<DataChunk> buildDataChunk(lua_State* L) {
}
if (type == LUA_TTABLE) {
// check if this is a raw value
lua_getglobal(L, "require");
lua_pushstring(L, "sk_definition_writer");
lua_call(L, 1, 1);
@ -103,12 +104,22 @@ std::unique_ptr<DataChunk> buildDataChunk(lua_State* L) {
// pop the bool
lua_pop(L, 1);
lua_getfield(L, -1, "value");
std::unique_ptr<DataChunk> result(new PrimitiveDataChunk<std::string>(lua_tostring(L, -1)));
const char* buffer = lua_tostring(L, -1);
if (strcmp(buffer, "\n") == 0) {
std::unique_ptr<DataChunk> result(new NewlineHintChunk());
lua_pop(L, 1);
return result;
}
std::unique_ptr<DataChunk> result(new PrimitiveDataChunk<std::string>(buffer));
lua_pop(L, 1);
return result;
}
lua_pop(L, 1);
// check if ths is a macro value
lua_getglobal(L, "require");
lua_pushstring(L, "sk_definition_writer");
lua_call(L, 1, 1);
@ -127,6 +138,28 @@ std::unique_ptr<DataChunk> buildDataChunk(lua_State* L) {
}
lua_pop(L, 1);
// check if this is a comment
lua_getglobal(L, "require");
lua_pushstring(L, "sk_definition_writer");
lua_call(L, 1, 1);
lua_getfield(L, -1, "is_comment");
// remove sk_definition_writer module
lua_remove(L, -2);
lua_pushnil(L);
lua_copy(L, -3, -1);
lua_call(L, 1, 1);
if (lua_toboolean(L, -1)) {
// pop the bool
lua_pop(L, 1);
lua_getfield(L, -1, "value");
std::unique_ptr<DataChunk> result(new CommentDataChunk(lua_tostring(L, -1)));
lua_pop(L, 1);
return result;
}
lua_pop(L, 1);
return buildStructureChunk(L);
}

View file

@ -2,6 +2,8 @@
#include "LuaMesh.h"
#include <iomanip>
#include "../definition_generator/MeshDefinitionGenerator.h"
#include "../definition_generator/MaterialGenerator.h"
#include "./LuaBasicTypes.h"
@ -119,10 +121,135 @@ void toLuaLazyArray(lua_State* L, T* vertices, unsigned count) {
lua_setmetatable(L, -2);
}
void textureFromLua(lua_State* L, std::shared_ptr<TextureDefinition>& texture) {
lua_getfield(L, -1, "ptr");
fromLua(L, texture);
lua_pop(L, 1);
}
void textureToLua(lua_State* L, std::shared_ptr<TextureDefinition> texture);
int luaTextureCrop(lua_State* L) {
int x = luaL_checkinteger(L, 2);
int y = luaL_checkinteger(L, 3);
int w = luaL_checkinteger(L, 4);
int h = luaL_checkinteger(L, 5);
lua_settop(L, 1);
std::shared_ptr<TextureDefinition> texture;
textureFromLua(L, texture);
std::shared_ptr<TextureDefinition> result = texture->Crop(x, y, w, h);
textureToLua(L, result);
return 1;
}
int luaTextureResize(lua_State* L) {
int w = luaL_checkinteger(L, 2);
int h = luaL_checkinteger(L, 3);
lua_settop(L, 1);
std::shared_ptr<TextureDefinition> texture;
textureFromLua(L, texture);
std::shared_ptr<TextureDefinition> result = texture->Resize(w, h);
textureToLua(L, result);
return 1;
}
int luaTextureData(lua_State* L) {
lua_settop(L, 1);
if (lua_isnil(L, 1)) {
lua_pushstring(L, "call to get_data had nil as the first paramter");
lua_error(L);
return 0;
}
std::shared_ptr<TextureDefinition> texture;
textureFromLua(L, texture);
if (!texture) {
return 0;
}
const std::vector<unsigned long long>& data = texture->GetData();
lua_createtable(L, data.size(), 0);
for (unsigned i = 0; i < data.size(); ++i) {
std::ostringstream stream;
stream << "0x" << std::hex << std::setw(16) << std::setfill('0') << data[i];
luaLoadModuleFunction(L, "sk_definition_writer", "raw");
lua_pushstring(L, stream.str().c_str());
lua_call(L, 1, 1);
lua_seti(L, -2, i + 1);
}
return 1;
}
/**
@table Texture
@tfield number width
@tfield number height
@tfield string name
@tfield function get_data
@tfield function crop
*/
void textureToLua(lua_State* L, std::shared_ptr<TextureDefinition> texture) {
if (!texture) {
lua_pushnil(L);
return;
}
lua_createtable(L, 0, 0);
luaLoadModuleFunction(L, "sk_mesh", "Texture");
lua_setmetatable(L, -2);
toLua(L, texture);
lua_setfield(L, -2, "ptr");
lua_pushinteger(L, texture->Width());
lua_setfield(L, -2, "width");
lua_pushinteger(L, texture->Height());
lua_setfield(L, -2, "height");
lua_pushstring(L, texture->Name().c_str());
lua_setfield(L, -2, "name");
}
/**
@table TileState
@tfield string format
@tfield string size
@tfield Texture texture
*/
void toLua(lua_State* L, TileState& tileState) {
lua_createtable(L, 0, 0);
lua_pushstring(L, nameForImageFormat(tileState.format));
lua_setfield(L, -2, "format");
lua_pushstring(L, nameForImageSize(tileState.size));
lua_setfield(L, -2, "size");
textureToLua(L, tileState.texture);
lua_setfield(L, -2, "texture");
}
/***
@table Material
@tfield string name
@tfield string macro_name
@tfield {...TileState} tiles
*/
void toLua(lua_State* L, Material* material) {
if (!material) {
@ -130,7 +257,7 @@ void toLua(lua_State* L, Material* material) {
return;
}
lua_createtable(L, 1, 0);
lua_createtable(L, 0, 0);
luaLoadModuleFunction(L, "sk_mesh", "Material");
lua_setmetatable(L, -2);
@ -148,6 +275,13 @@ void toLua(lua_State* L, Material* material) {
}
lua_setfield(L, -2, "properties");
lua_createtable(L, MAX_TILE_COUNT, 0);
for (int i = 0; i < MAX_TILE_COUNT; ++i) {
toLua(L, material->mState.tiles[i]);
lua_seti(L, -2, i + 1);
}
lua_setfield(L, -2, "tiles");
lua_pushlightuserdata(L, material);
lua_setfield(L, -2, "ptr");
}
@ -195,6 +329,7 @@ int luaTransformMesh(lua_State* L) {
@tfield sk_transform.Transform transform
@tfield {sk_math.Vector3,...} vertices
@tfield {sk_math.Vector3,...} normals
@tfield {sk_math.Vector3,...} uv
@tfield {{number,number,number},...} faces
@tfield Material material
*/
@ -223,6 +358,13 @@ void meshToLua(lua_State* L, std::shared_ptr<ExtendedMesh> mesh) {
toLuaLazyArray<aiVector3D>(L, mesh->mMesh->mNormals, mesh->mMesh->mNumVertices);
lua_setfield(L, -2, "normals");
if (mesh->mMesh->mTextureCoords[0]) {
toLuaLazyArray<aiVector3D>(L, mesh->mMesh->mTextureCoords[0], mesh->mMesh->mNumVertices);
} else {
lua_pushnil(L);
}
lua_setfield(L, -2, "uv");
toLua(L, mesh->mMesh->mFaces, mesh->mMesh->mNumFaces);
lua_setfield(L, -2, "faces");
@ -449,6 +591,23 @@ int buildMeshModule(lua_State* L) {
lua_newtable(L);
lua_setfield(L, -2, "Mesh");
lua_newtable(L);
lua_pushcfunction(L, luaTextureCrop);
lua_setfield(L, -2, "crop");
lua_pushcfunction(L, luaTextureResize);
lua_setfield(L, -2, "resize");
lua_pushcfunction(L, luaTextureData);
lua_setfield(L, -2, "get_data");
lua_pushnil(L);
lua_copy(L, -2, -1);
lua_setfield(L, -2, "__index");
lua_setfield(L, -2, "Texture");
lua_pushlightuserdata(L, scene);
lua_pushlightuserdata(L, fileDefinition);
lua_pushlightuserdata(L, settings);

View file

@ -43,6 +43,39 @@ int luaTransformFromPosRotationScale(lua_State* L) {
return 1;
}
/***
@function from_pos_rot_scale
@tparam {...number} data
@treturn Transform
*/
int luaTransformFromArray(lua_State* L) {
lua_type(L, 1);
if (lua_isnil(L, 1)) {
return 0;
}
double value[16];
for (int i = 0; i < 16; ++i) {
if (lua_geti(L, 1, i + 1) == LUA_TNUMBER) {
value[i] = lua_tonumber(L, -1);
} else {
value[i] = 0.0;
}
lua_pop(L, 1);
}
aiMatrix4x4 fullTransform(
value[0], value[1], value[2], value[3],
value[4], value[5], value[6], value[7],
value[8], value[9], value[10], value[11],
value[12], value[13], value[14], value[15]
);
toLua(L, fullTransform);
return 1;
}
/***
A 4x4 matrix transform
@type Transform
@ -126,7 +159,7 @@ int luaTransformIndex(lua_State* L) {
int row = lua_tointeger(L, -2);
int col = lua_tointeger(L, -1);
lua_pushnumber(L, (*mtx)[row][col]);
lua_pushnumber(L, (*mtx)[row - 1][col - 1]);
return 1;
}
}
@ -189,23 +222,23 @@ int luaTransformToString(lua_State* L) {
std::ostringstream result;
result << "| " << std::setprecision(5) << std::fixed << std::setw(5) << a->a1 << " ";
result << std::setprecision(5) << std::fixed << std::setw(5) << a->b1 << " ";
result << std::setprecision(5) << std::fixed << std::setw(5) << a->c1 << " ";
result << std::setprecision(5) << std::fixed << std::setw(5) << a->d1 << " |" << std::endl;
result << std::setprecision(5) << std::fixed << std::setw(5) << a->a2 << " ";
result << std::setprecision(5) << std::fixed << std::setw(5) << a->a3 << " ";
result << std::setprecision(5) << std::fixed << std::setw(5) << a->a4 << " |" << std::endl;
result << "| " << std::setprecision(5) << std::fixed << std::setw(5) << a->a2 << " ";
result << "| " << std::setprecision(5) << std::fixed << std::setw(5) << a->b1 << " ";
result << std::setprecision(5) << std::fixed << std::setw(5) << a->b2 << " ";
result << std::setprecision(5) << std::fixed << std::setw(5) << a->c2 << " ";
result << std::setprecision(5) << std::fixed << std::setw(5) << a->d2 << " |" << std::endl;
result << "| " << std::setprecision(5) << std::fixed << std::setw(5) << a->a3 << " ";
result << std::setprecision(5) << std::fixed << std::setw(5) << a->b3 << " ";
result << std::setprecision(5) << std::fixed << std::setw(5) << a->c3 << " ";
result << std::setprecision(5) << std::fixed << std::setw(5) << a->d3 << " |" << std::endl;
result << std::setprecision(5) << std::fixed << std::setw(5) << a->b4 << " |" << std::endl;
result << "| " << std::setprecision(5) << std::fixed << std::setw(5) << a->a4 << " ";
result << std::setprecision(5) << std::fixed << std::setw(5) << a->b4 << " ";
result << std::setprecision(5) << std::fixed << std::setw(5) << a->c4 << " ";
result << "| " << std::setprecision(5) << std::fixed << std::setw(5) << a->c1 << " ";
result << std::setprecision(5) << std::fixed << std::setw(5) << a->c2 << " ";
result << std::setprecision(5) << std::fixed << std::setw(5) << a->c3 << " ";
result << std::setprecision(5) << std::fixed << std::setw(5) << a->c4 << " |" << std::endl;
result << "| " << std::setprecision(5) << std::fixed << std::setw(5) << a->d1 << " ";
result << std::setprecision(5) << std::fixed << std::setw(5) << a->d2 << " ";
result << std::setprecision(5) << std::fixed << std::setw(5) << a->d3 << " ";
result << std::setprecision(5) << std::fixed << std::setw(5) << a->d4 << " |" << std::endl;
toLua(L, result.str());
@ -218,6 +251,9 @@ int buildTransformModule(lua_State* L) {
lua_pushcfunction(L, luaTransformFromPosRotationScale);
lua_setfield(L, -2, "from_pos_rot_scale");
lua_pushcfunction(L, luaTransformFromArray);
lua_setfield(L, -2, "from_array");
return 1;
}

View file

@ -0,0 +1,10 @@
#include "CImgu8.h"
CImgu8::CImgu8(const std::string& filename) : mImg(filename.c_str()) {
}
CImgu8::CImgu8(const cimg_library_suffixed::CImg<unsigned char>& img) : mImg(img) {
}

View file

@ -0,0 +1,23 @@
#ifndef __CIMG_U8_H__
#define __CIMG_U8_H__
#define cimg_display 0
#define cimg_use_png
#define cimg_use_tiff
// This is a massive header file and I don't
// want it to drive my compile times up by being
// included in every file. That is whey I created
// The CImgu8 class. You should not include this header
// file from other header files
#include "../../cimg/CImg.h"
#include <string>
class CImgu8 {
public:
CImgu8(const std::string& filename);
CImgu8(const cimg_library_suffixed::CImg<unsigned char>& img);
cimg_library_suffixed::CImg<unsigned char> mImg;
};
#endif

View file

@ -1,7 +1,3 @@
#define cimg_display 0
#define cimg_use_png
#define cimg_use_tiff
#include "../../cimg/CImg.h"
#include "TextureDefinition.h"
#include "../FileUtils.h"
@ -13,6 +9,8 @@
#include <assimp/vector3.h>
#include <assimp/vector3.inl>
#include "CImgu8.h"
DataChunkStream::DataChunkStream() :
mCurrentBufferPos(0),
mCurrentBuffer(0) {}
@ -474,40 +472,56 @@ unsigned PalleteDefinition::ColorCount() const {
}
TextureDefinition::TextureDefinition(const std::string& filename, G_IM_FMT fmt, G_IM_SIZ siz, TextureDefinitionEffect effects, std::shared_ptr<PalleteDefinition> pallete) :
mName(getBaseName(replaceExtension(filename, "")) + "_" + gFormatShortName[(int)fmt] + "_" + gSizeName[(int)siz]),
mFmt(fmt),
mSiz(siz),
mPallete(pallete),
mEffects(effects) {
TextureDefinition(
new CImgu8(filename),
getBaseName(replaceExtension(filename, "")) + "_" + gFormatShortName[(int)fmt] + "_" + gSizeName[(int)siz],
fmt,
siz,
pallete,
effects
) {
}
cimg_library_suffixed::CImg<unsigned char> imageData(filename.c_str());
TextureDefinition::~TextureDefinition() {
delete mImg;
mImg = NULL;
}
TextureDefinition::TextureDefinition(
CImgu8* img,
const std::string& name,
G_IM_FMT fmt,
G_IM_SIZ siz,
std::shared_ptr<PalleteDefinition> pallete,
TextureDefinitionEffect effects
): mImg(std::move(img)), mName(name), mFmt(fmt), mSiz(siz), mWidth(img->mImg.width()), mHeight(img->mImg.height()),
mPallete(pallete), mEffects(effects) {
if (HasEffect(TextureDefinitionEffect::TwoToneGrayscale)) {
applyTwoToneEffect(imageData, mTwoToneMax, mTwoToneMin);
applyTwoToneEffect(mImg->mImg, mTwoToneMax, mTwoToneMin);
}
if (HasEffect(TextureDefinitionEffect::NormalMap)) {
calculateNormalMap(imageData);
calculateNormalMap(mImg->mImg);
}
if (HasEffect(TextureDefinitionEffect::Invert)) {
invertImage(imageData);
invertImage(mImg->mImg);
}
if (HasEffect(TextureDefinitionEffect::SelectR) ||
HasEffect(TextureDefinitionEffect::SelectG) ||
HasEffect(TextureDefinitionEffect::SelectB)) {
selectChannel(imageData, mEffects);
selectChannel(mImg->mImg, mEffects);
}
mWidth = imageData.width();
mHeight = imageData.height();
mWidth = mImg->mImg.width();
mHeight = mImg->mImg.height();
DataChunkStream dataStream;
for (int y = 0; y < mHeight; ++y) {
for (int x = 0; x < mWidth; ++x) {
convertPixel(imageData, x, y, dataStream, fmt, siz, pallete);
convertPixel(mImg->mImg, x, y, dataStream, fmt, siz, pallete);
}
}
@ -520,8 +534,8 @@ TextureDefinition::TextureDefinition(const std::string& filename, G_IM_FMT fmt,
mFmt = G_IM_FMT::G_IM_FMT_CI;
mSiz = pallete->ColorCount() <= 16 ? G_IM_SIZ::G_IM_SIZ_4b : G_IM_SIZ::G_IM_SIZ_8b;
}
}
}
bool isGrayscale(cimg_library_suffixed::CImg<unsigned char>& input, int x, int y) {
switch (input.spectrum()) {
case 1:
@ -668,6 +682,10 @@ bool TextureDefinition::GetLineForTile(int& line) const {
return bitLine % 64 == 0;
}
const std::vector<unsigned long long>& TextureDefinition::GetData() const {
return mData;
}
const std::string& TextureDefinition::Name() const {
return mName;
}
@ -687,3 +705,25 @@ PixelRGBAu8 TextureDefinition::GetTwoToneMax() const {
std::shared_ptr<PalleteDefinition> TextureDefinition::GetPallete() const {
return mPallete;
}
std::shared_ptr<TextureDefinition> TextureDefinition::Crop(int x, int y, int w, int h) const {
return std::shared_ptr<TextureDefinition>(new TextureDefinition(
new CImgu8(mImg->mImg.get_crop(x, y, x + w - 1, y + h - 1)),
mName,
mFmt,
mSiz,
mPallete,
mEffects
));
}
std::shared_ptr<TextureDefinition> TextureDefinition::Resize(int w, int h) const {
return std::shared_ptr<TextureDefinition>(new TextureDefinition(
new CImgu8(mImg->mImg.get_resize(w, h, -100, -100, 5)),
mName,
mFmt,
mSiz,
mPallete,
mEffects
));
}

View file

@ -3,12 +3,15 @@
#include <vector>
#include <inttypes.h>
#include <memory>
#include "TextureFormats.h"
#include "../definitions/DataChunk.h"
#include "../definitions/FileDefinition.h"
class CImgu8;
class DataChunkStream {
public:
DataChunkStream();
@ -85,6 +88,7 @@ private:
class TextureDefinition {
public:
TextureDefinition(const std::string& filename, G_IM_FMT fmt, G_IM_SIZ siz, TextureDefinitionEffect effects, std::shared_ptr<PalleteDefinition> pallete);
~TextureDefinition();
static void DetermineIdealFormat(const std::string& filename, G_IM_FMT& fmt, G_IM_SIZ& siz);
@ -102,6 +106,8 @@ public:
int DTX() const;
int NBytes() const;
const std::vector<unsigned long long>& GetData() const;
const std::string& Name() const;
bool HasEffect(TextureDefinitionEffect effect) const;
@ -110,7 +116,20 @@ public:
PixelRGBAu8 GetTwoToneMax() const;
std::shared_ptr<PalleteDefinition> GetPallete() const;
std::shared_ptr<TextureDefinition> Crop(int x, int y, int w, int h) const;
std::shared_ptr<TextureDefinition> Resize(int w, int h) const;
private:
TextureDefinition(
CImgu8* mImg,
const std::string& name,
G_IM_FMT fmt,
G_IM_SIZ siz,
std::shared_ptr<PalleteDefinition> pallete,
TextureDefinitionEffect effects
);
CImgu8* mImg;
std::string mName;
G_IM_FMT mFmt;
G_IM_SIZ mSiz;