50 lines
1.7 KiB
C++
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;
|
|
}
|