Skip to content

Commit

Permalink
[Script/LuaVector] Added bindings for byte vectors
Browse files Browse the repository at this point in the history
- Added a lerpf() binding to simulate Vector::lerp<float>()
  • Loading branch information
Razakhel committed Sep 26, 2023
1 parent bb8ccad commit a651927
Show file tree
Hide file tree
Showing 3 changed files with 175 additions and 1 deletion.
4 changes: 4 additions & 0 deletions include/RaZ/Data/Image.inl
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ template <typename T, std::size_t N>
Vector<T, N> Image::recoverPixel(std::size_t widthIndex, std::size_t heightIndex) const {
static_assert(std::is_same_v<T, uint8_t> || std::is_same_v<T, float>, "Error: The given pixel's type to be recovered is unsupported.");
assert("Error: Recovering multiple values for a pixel requires an image having the same channel count." && m_channelCount == N);
assert("Error: Recovering a byte pixel requires the image to be of a byte type." && (!std::is_same_v<T, uint8_t> || m_dataType == ImageDataType::BYTE));
assert("Error: Recovering a float pixel requires the image to be of a float type." && (!std::is_same_v<T, float> || m_dataType == ImageDataType::FLOAT));

const T* imgData = static_cast<T*>(m_data->getDataPtr()) + computeIndex(widthIndex, heightIndex);

Expand Down Expand Up @@ -43,6 +45,8 @@ template <typename T, std::size_t N>
void Image::setPixel(std::size_t widthIndex, std::size_t heightIndex, const Vector<T, N>& values) {
static_assert(std::is_same_v<T, uint8_t> || std::is_same_v<T, float>, "Error: The given pixel's type to be set is unsupported.");
assert("Error: Setting multiple values for a pixel requires an image having the same channel count." && m_channelCount == N);
assert("Error: Setting a byte pixel requires the image to be of a byte type." && (!std::is_same_v<T, uint8_t> || m_dataType == ImageDataType::BYTE));
assert("Error: Setting a float pixel requires the image to be of a float type." && (!std::is_same_v<T, float> || m_dataType == ImageDataType::FLOAT));

T* imgData = static_cast<T*>(m_data->getDataPtr()) + computeIndex(widthIndex, heightIndex);

Expand Down
96 changes: 96 additions & 0 deletions src/RaZ/Script/LuaVector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,102 @@ void LuaWrapper::registerVectorTypes() {
// Unsigned 64-bit integers seem to be supported in Lua 5.3 and above, so there may (will) be a better solution
// Manually hashing a vector should not be useful on Lua's side anyway

{
sol::usertype<Vec2b> vec2b = state.new_usertype<Vec2b>("Vec2b",
sol::constructors<Vec2b(),
Vec2b(uint8_t),
Vec2b(uint8_t, uint8_t),
Vec2b(const Vec3b&)>());
vec2b["x"] = PickConstOverload<>(&Vec2b::x);
vec2b["y"] = PickConstOverload<>(&Vec2b::y);
vec2b["dot"] = &Vec2b::dot<>;
vec2b["computeSquaredLength"] = &Vec2b::computeSquaredLength<>;
vec2b["computeLength"] = &Vec2b::computeLength<>;
vec2b["normalize"] = &Vec2b::normalize<>;
vec2b["lerp"] = &Vec2b::lerp<>;
vec2b["lerpf"] = &Vec2b::lerp<float>;
vec2b["nlerp"] = &Vec2b::nlerp<>;
vec2b["strictlyEquals"] = &Vec2b::strictlyEquals;
vec2b.set_function(sol::meta_function::unary_minus, PickOverload<>(&Vec2b::operator-));
vec2b.set_function(sol::meta_function::addition, sol::overload(PickOverload<const Vec2b&>(&Vec2b::operator+),
PickOverload<uint8_t>(&Vec2b::operator+)));
vec2b.set_function(sol::meta_function::subtraction, sol::overload(PickOverload<const Vec2b&>(&Vec2b::operator-),
PickOverload<uint8_t>(&Vec2b::operator-)));
vec2b.set_function(sol::meta_function::multiplication, sol::overload(PickOverload<const Vec2b&>(&Vec2b::operator*),
PickOverload<uint8_t>(&Vec2b::operator*),
PickOverload<const Vec2b&, const Mat2b&>(&::Raz::operator*<uint8_t, 2, 2>)));
vec2b.set_function(sol::meta_function::division, sol::overload(PickOverload<const Vec2b&>(&Vec2b::operator/),
PickOverload<uint8_t>(&Vec2b::operator/)));
vec2b.set_function(sol::meta_function::index, PickConstOverload<std::size_t>(&Vec2b::operator[]));
}

{
sol::usertype<Vec3b> vec3b = state.new_usertype<Vec3b>("Vec3b",
sol::constructors<Vec3b(),
Vec3b(uint8_t),
Vec3b(uint8_t, uint8_t, uint8_t),
Vec3b(const Vec2b&, uint8_t),
Vec3b(const Vec4b&)>());
vec3b["x"] = PickConstOverload<>(&Vec3b::x);
vec3b["y"] = PickConstOverload<>(&Vec3b::y);
vec3b["z"] = PickConstOverload<>(&Vec3b::z);
vec3b["dot"] = &Vec3b::dot<>;
vec3b["computeSquaredLength"] = &Vec3b::computeSquaredLength<>;
vec3b["computeLength"] = &Vec3b::computeLength<>;
vec3b["normalize"] = &Vec3b::normalize<>;
vec3b["lerp"] = &Vec3b::lerp<>;
vec3b["lerpf"] = &Vec3b::lerp<float>;
vec3b["nlerp"] = &Vec3b::nlerp<>;
vec3b["strictlyEquals"] = &Vec3b::strictlyEquals;
vec3b.set_function(sol::meta_function::unary_minus, PickOverload<>(&Vec3b::operator-));
vec3b.set_function(sol::meta_function::addition, sol::overload(PickOverload<const Vec3b&>(&Vec3b::operator+),
PickOverload<uint8_t>(&Vec3b::operator+)));
vec3b.set_function(sol::meta_function::subtraction, sol::overload(PickOverload<const Vec3b&>(&Vec3b::operator-),
PickOverload<uint8_t>(&Vec3b::operator-)));
vec3b.set_function(sol::meta_function::multiplication, sol::overload(PickOverload<const Vec3b&>(&Vec3b::operator*),
PickOverload<uint8_t>(&Vec3b::operator*),
PickOverload<const Vec3b&, const Mat3b&>(&::Raz::operator*<uint8_t, 3, 3>)));
vec3b.set_function(sol::meta_function::division, sol::overload(PickOverload<const Vec3b&>(&Vec3b::operator/),
PickOverload<uint8_t>(&Vec3b::operator/)));
vec3b.set_function(sol::meta_function::index, PickConstOverload<std::size_t>(&Vec3b::operator[]));

sol::table axis = state["Axis"].get_or_create<sol::table>();
axis["X"] = Axis::X;
axis["Y"] = Axis::Y;
axis["Z"] = Axis::Z;
}

{
sol::usertype<Vec4b> vec4b = state.new_usertype<Vec4b>("Vec4b",
sol::constructors<Vec4b(),
Vec4b(uint8_t),
Vec4b(uint8_t, uint8_t, uint8_t, uint8_t),
Vec4b(const Vec3b&, uint8_t)>());
vec4b["x"] = PickConstOverload<>(&Vec4b::x);
vec4b["y"] = PickConstOverload<>(&Vec4b::y);
vec4b["z"] = PickConstOverload<>(&Vec4b::z);
vec4b["w"] = PickConstOverload<>(&Vec4b::w);
vec4b["dot"] = &Vec4b::dot<>;
vec4b["computeSquaredLength"] = &Vec4b::computeSquaredLength<>;
vec4b["computeLength"] = &Vec4b::computeLength<>;
vec4b["normalize"] = &Vec4b::normalize<>;
vec4b["lerp"] = &Vec4b::lerp<>;
vec4b["lerpf"] = &Vec4b::lerp<float>;
vec4b["nlerp"] = &Vec4b::nlerp<>;
vec4b["strictlyEquals"] = &Vec4b::strictlyEquals;
vec4b.set_function(sol::meta_function::unary_minus, PickOverload<>(&Vec4b::operator-));
vec4b.set_function(sol::meta_function::addition, sol::overload(PickOverload<const Vec4b&>(&Vec4b::operator+),
PickOverload<uint8_t>(&Vec4b::operator+)));
vec4b.set_function(sol::meta_function::subtraction, sol::overload(PickOverload<const Vec4b&>(&Vec4b::operator-),
PickOverload<uint8_t>(&Vec4b::operator-)));
vec4b.set_function(sol::meta_function::multiplication, sol::overload(PickOverload<const Vec4b&>(&Vec4b::operator*),
PickOverload<uint8_t>(&Vec4b::operator*),
PickOverload<const Vec4b&, const Mat4b&>(&::Raz::operator*<uint8_t, 4, 4>)));
vec4b.set_function(sol::meta_function::division, sol::overload(PickOverload<const Vec4b&>(&Vec4b::operator/),
PickOverload<uint8_t>(&Vec4b::operator/)));
vec4b.set_function(sol::meta_function::index, PickConstOverload<std::size_t>(&Vec4b::operator[]));
}

{
sol::usertype<Vec2f> vec2f = state.new_usertype<Vec2f>("Vec2f",
sol::constructors<Vec2f(),
Expand Down
76 changes: 75 additions & 1 deletion tests/src/RaZ/Script/LuaMath.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,81 @@ TEST_CASE("LuaMath Transform") {
)"));
}

TEST_CASE("LuaMath Vector") {
TEST_CASE("LuaMath Vector byte") {
CHECK(Raz::LuaWrapper::execute(R"(
local vec2 = Vec2b.new()
vec2 = Vec2b.new(1)
vec2 = Vec2b.new(1, 2)
vec2 = Vec2b.new(Vec3b.new(1, 2, 3))
assert(vec2:x() == vec2[0])
assert(vec2:y() == vec2[1])
assert(vec2:computeSquaredLength() == vec2:dot(vec2))
assert(FloatUtils.areNearlyEqual(vec2:computeLength(), 2.236068))
assert(FloatUtils.areNearlyEqual(vec2:normalize():computeSquaredLength(), 1))
assert(Vec2b.new(0, 1):lerp(Vec2b.new(1, 0), 0.5) == Vec2b.new(0)) -- Truncated from 0.5 to 0
assert(Vec2b.new(0, 1):lerpf(Vec2b.new(1, 0), 0.5) == Vec2f.new(0.5)) -- lerpf() is available to avoid truncating
assert(Vec2b.new(0, 1):nlerp(Vec2b.new(1, 0), 0.5) == Vec2f.new(0.7071067))
assert(-vec2 == Vec2b.new(255, 254)) -- This is technically doable, but probably never makes sense and may be removed in the future
assert(vec2 + Vec2b.new(1) == vec2 + 1)
assert(vec2 - Vec2b.new(1) == vec2 - 1)
assert(vec2 * Vec2b.new(2) == vec2 * 2)
assert(vec2 / Vec2b.new(2) == vec2 / 2)
local vec3 = Vec3b.new()
vec3 = Vec3b.new(1)
vec3 = Vec3b.new(1, 2, 3)
vec3 = Vec3b.new(vec2, 3)
vec3 = Vec3b.new(Vec4b.new(1, 2, 3, 4))
assert(vec3:x() == vec3[0])
assert(vec3:y() == vec3[1])
assert(vec3:z() == vec3[2])
assert(vec3:computeSquaredLength() == vec3:dot(vec3))
assert(FloatUtils.areNearlyEqual(vec3:computeLength(), 3.7416574))
assert(FloatUtils.areNearlyEqual(vec3:normalize():computeSquaredLength(), 1))
assert(Vec3b.new(0, 1, 0):lerp(Vec3b.new(1, 0, 1), 0.5) == Vec3b.new(0)) -- Truncated from 0.5 to 0
assert(Vec3b.new(0, 1, 0):lerpf(Vec3b.new(1, 0, 1), 0.5) == Vec3f.new(0.5))
assert(Vec3b.new(0, 1, 0):nlerp(Vec3b.new(1, 0, 1), 0.5) == Vec3f.new(0.5773502))
assert(-vec3 == Vec3b.new(255, 254, 253))
assert(vec3 + Vec3b.new(1) == vec3 + 1)
assert(vec3 - Vec3b.new(1) == vec3 - 1)
assert(vec3 * Vec3b.new(2) == vec3 * 2)
assert(vec3 / Vec3b.new(2) == vec3 / 2)
local vec4 = Vec4b.new()
vec4 = Vec4b.new(1)
vec4 = Vec4b.new(1, 2, 3, 4)
vec4 = Vec4b.new(vec3, 4)
assert(vec4:x() == vec4[0])
assert(vec4:y() == vec4[1])
assert(vec4:z() == vec4[2])
assert(vec4:w() == vec4[3])
assert(vec4:computeSquaredLength() == vec4:dot(vec4))
assert(FloatUtils.areNearlyEqual(vec4:computeLength(), 5.4772257))
assert(FloatUtils.areNearlyEqual(vec4:normalize():computeSquaredLength(), 1))
assert(Vec4b.new(0, 1, 0, 1):lerp(Vec4b.new(1, 0, 1, 1), 0.5) == Vec4b.new(0, 0, 0, 1)) -- Truncated from 0.5 to 0
assert(Vec4b.new(0, 1, 0, 1):lerpf(Vec4b.new(1, 0, 1, 1), 0.5) == Vec4f.new(0.5, 0.5, 0.5, 1))
assert(Vec4b.new(0, 1, 0, 1):nlerp(Vec4b.new(1, 0, 1, 1), 0.5) == Vec4f.new(0.3779644, 0.3779644, 0.3779644, 0.7559289))
assert(-vec4 == Vec4b.new(255, 254, 253, 252))
assert(vec4 + Vec4b.new(1) == vec4 + 1)
assert(vec4 - Vec4b.new(1) == vec4 - 1)
assert(vec4 * Vec4b.new(2) == vec4 * 2)
assert(vec4 / Vec4b.new(2) == vec4 / 2)
)"));
}

TEST_CASE("LuaMath Vector float") {
CHECK(Raz::LuaWrapper::execute(R"(
local vec2 = Vec2f.new()
vec2 = Vec2f.new(1)
Expand Down

0 comments on commit a651927

Please sign in to comment.