MinusculeRender/src/phone_material.cc

50 lines
1.7 KiB
C++

// Copyright 2024 SquareBlock Inc. All Rights Reserved.
// Author: tianlei.richard@qq.com (tianlei.richard)
#include "phone_material.h"
#include "spdlog/spdlog.h"
#include "util/interpolation.h"
#include <opencv2/highgui/highgui.hpp>
PhoneMaterial::PhoneMaterial(
const std::vector<std::filesystem::path> &texture_path) {
for (const auto &path : texture_path) {
if (!std::filesystem::exists(path)) {
spdlog::warn("Texture {} is not existed!", path.c_str());
continue;
}
const auto &img(cv::imread(path));
spdlog::debug("Texture at {}, shape: ({},{})", path.c_str(), img.cols,
img.rows);
textures_.push_back(img);
}
}
cv::Vec3b PhoneMaterial::sample_texture(const TextureId texture_id,
const Point2d &texture_coordinate) {
cv::Vec3b res{0, 0, 0};
if (texture_id >= 0 && texture_id < textures_.size()) {
const auto &texture = textures_[texture_id];
const double x = texture_coordinate.x() * texture.cols - 0.5;
const double y = texture_coordinate.y() * texture.rows - 0.5;
const int x_f = x;
const int x_c = x + 1.;
const float t_x = x - x_f;
const int y_f = y;
const int y_c = y + 1.;
const float t_y = y - y_f;
const cv::Vec3b &a = texture.at<cv::Vec3b>(x_f, y_f);
const cv::Vec3b &b = texture.at<cv::Vec3b>(x_f, y_c);
const cv::Vec3b &c = texture.at<cv::Vec3b>(x_c, y_f);
const cv::Vec3b &d = texture.at<cv::Vec3b>(x_c, y_c);
res = bilerp(t_x, t_y, a, b, c, d);
} else {
spdlog::warn("Sample texture {} at ({}, {}) failed!", texture_id,
texture_coordinate.x(), texture_coordinate.y());
}
return res;
}