2017-10-29 05:16:22 +01:00
|
|
|
#include "TextureMapper.h"
|
|
|
|
|
|
|
|
#include <glm/mat3x3.hpp>
|
|
|
|
|
|
|
|
#include "stb_image_write.h"
|
|
|
|
|
|
|
|
#include <iostream>
|
|
|
|
|
|
|
|
TextureMapper::TextureMapper(Density &density, size_t textureSize) :
|
|
|
|
density(density), textureSize(textureSize), albedo(
|
|
|
|
textureSize * textureSize), normal(textureSize * textureSize), roughness(
|
2017-11-02 03:44:44 +01:00
|
|
|
textureSize * textureSize), darkestColor(0.3, 0.25, 0.2, 1.0), brightestColor(
|
|
|
|
0.9, 0.85, 0.8, 1.0) {
|
2017-10-29 05:16:22 +01:00
|
|
|
|
|
|
|
}
|
|
|
|
void TextureMapper::setTextureSize(size_t size) {
|
|
|
|
textureSize = size;
|
|
|
|
albedo.resize(textureSize * textureSize);
|
|
|
|
normal.resize(textureSize * textureSize);
|
|
|
|
roughness.resize(textureSize * textureSize);
|
|
|
|
}
|
|
|
|
|
|
|
|
size_t TextureMapper::getTextureSize() {
|
|
|
|
return textureSize;
|
|
|
|
}
|
|
|
|
|
|
|
|
void TextureMapper::map(const vec3v_t &inVertices, const vec3v_t &inNormals,
|
|
|
|
const uvec3v_t &inIndices) {
|
|
|
|
float texf = 1. / textureSize;
|
|
|
|
|
|
|
|
vertices.clear();
|
|
|
|
vertices.reserve(inIndices.size() * 3);
|
|
|
|
normals.clear();
|
|
|
|
normals.reserve(inIndices.size() * 3);
|
|
|
|
texcoords.clear();
|
|
|
|
texcoords.reserve(inIndices.size() * 3);
|
|
|
|
|
2017-11-02 03:44:44 +01:00
|
|
|
// 2 px margin
|
|
|
|
size_t marginPixels = 2;
|
|
|
|
float margin = marginPixels * texf;
|
|
|
|
|
|
|
|
std::fill(albedo.begin(), albedo.end(), 255.f * brightestColor);
|
|
|
|
std::fill(normal.begin(), normal.end(), ucvec4_t(255, 255, 255, 255));
|
|
|
|
std::fill(roughness.begin(), roughness.end(), 255);
|
|
|
|
|
2017-10-29 05:16:22 +01:00
|
|
|
int rects = ceil(sqrt(inIndices.size())), rx = 0, ry = 0;
|
2017-11-02 03:44:44 +01:00
|
|
|
float rectSizePixel = floor(((float)textureSize - (rects + 1) * marginPixels) / rects);
|
|
|
|
float rectSize = rectSizePixel / textureSize;
|
|
|
|
printf("Rects: %d, Size: %f", rects, rectSize);
|
|
|
|
for (size_t i = 0; i < inIndices.size(); i++) {
|
2017-10-29 05:16:22 +01:00
|
|
|
glm::vec3 p[3], n[3];
|
|
|
|
glm::uvec3 idx = inIndices[i];
|
|
|
|
indices.push_back(
|
|
|
|
glm::uvec3(vertices.size(), vertices.size() + 1,
|
|
|
|
vertices.size() + 2));
|
|
|
|
for (size_t j = 0; j < 3; j++) {
|
|
|
|
p[j] = inVertices[idx[j]];
|
|
|
|
vertices.push_back(p[j]);
|
|
|
|
n[j] = inNormals[idx[j]];
|
|
|
|
normals.push_back(n[j]);
|
|
|
|
}
|
|
|
|
|
|
|
|
glm::vec3 ex = glm::normalize(p[1] - p[0]);
|
|
|
|
glm::vec3 ey = glm::normalize(glm::cross(ex, p[2] - p[0]));
|
|
|
|
glm::vec3 ez = glm::normalize(glm::cross(ex, ey));
|
|
|
|
glm::mat3 base = glm::mat3(ex, ey, ez);
|
|
|
|
glm::vec3 t[3] = { p[0] * base, p[1] * base, p[2] * base };
|
|
|
|
glm::vec3 lower = min(min(t[0], t[1]), t[2]);
|
|
|
|
glm::vec3 upper = max(max(t[0], t[1]), t[2]);
|
|
|
|
t[0] -= lower;
|
|
|
|
t[1] -= lower;
|
|
|
|
t[2] -= lower;
|
|
|
|
glm::vec3 extent = upper - lower;
|
|
|
|
float s = std::max(std::max(extent.x, extent.y), extent.z);
|
2017-11-02 03:44:44 +01:00
|
|
|
t[0] *= 0.9 * rectSize / s;
|
|
|
|
t[1] *= rectSize / s;
|
|
|
|
t[2] *= rectSize / s;
|
|
|
|
glm::vec3 off(margin + rx * (rectSize + margin), 0, margin + ry * (rectSize + margin));
|
2017-10-29 05:16:22 +01:00
|
|
|
t[0] += off;
|
|
|
|
t[1] += off;
|
|
|
|
t[2] += off;
|
|
|
|
texcoords.push_back(glm::vec2(t[0].x, t[0].z));
|
|
|
|
texcoords.push_back(glm::vec2(t[1].x, t[1].z));
|
|
|
|
texcoords.push_back(glm::vec2(t[2].x, t[2].z));
|
2017-11-02 03:44:44 +01:00
|
|
|
#if 0
|
2017-10-29 05:16:22 +01:00
|
|
|
//if (rx == 0 && ry == 0) {
|
|
|
|
t[0].y = 0;
|
|
|
|
t[1].y = 0;
|
|
|
|
t[2].y = 0;
|
|
|
|
// cout << "ftex " << texf << endl;
|
|
|
|
// cout << "t[0] " << t[0].x << " " << t[0].z << endl;
|
|
|
|
// cout << "t[1] " << t[1].x << " " << t[1].z << endl;
|
|
|
|
// cout << "t[2] " << t[2].x << " " << t[2].z << endl;
|
|
|
|
// cout << "t[0]p " << t[0].x * ntex << " " << (1 - t[0].z) * ntex << endl;
|
|
|
|
// cout << "t[1]p " << t[1].x * ntex << " " << (1 - t[1].z) * ntex << endl;
|
|
|
|
// cout << "t[2]p " << t[2].x * ntex << " " << (1 - t[2].z) * ntex << endl;
|
|
|
|
// fill texture
|
|
|
|
// fill whole rect for now
|
|
|
|
int rpix = floor(rectSize * textureSize);
|
|
|
|
|
|
|
|
glm::vec3 eb = t[1] - t[0];
|
|
|
|
float leb = glm::length(eb);
|
|
|
|
glm::vec3 ec = t[2] - t[0];
|
|
|
|
float lec = glm::length(ec);
|
|
|
|
// mat2 textureBase = mat2(vec2(eb.x, eb.z), vec2(ec.x, ec.z));
|
|
|
|
// mat2 itextureBase = inverse(textureBase);
|
|
|
|
glm::mat3 textureBase = glm::mat3(eb, glm::cross(eb, ec), ec);
|
|
|
|
glm::mat3 itextureBase = glm::inverse(textureBase);
|
|
|
|
|
|
|
|
// eb = normalize(eb);
|
|
|
|
// ec = normalize(ec);
|
|
|
|
|
|
|
|
glm::vec3 db = p[1] - p[0];
|
|
|
|
glm::vec3 dc = p[2] - p[0];
|
|
|
|
|
|
|
|
glm::vec3 mb = glm::normalize(p[1] - p[0]);
|
|
|
|
glm::vec3 mc = glm::normalize(p[2] - p[0]);
|
|
|
|
// mat2 faceBase = mat2(vec2(mb.x, mb.z), vec2(mc.x, mc.z));
|
|
|
|
// mat2 ifaceBase = inverse(faceBase);
|
|
|
|
|
|
|
|
glm::mat3 faceBase = glm::mat3(db, glm::cross(db, dc), dc);
|
|
|
|
glm::mat3 ifaceBase = glm::inverse(faceBase);
|
|
|
|
|
2017-11-02 03:44:44 +01:00
|
|
|
glm::vec3 tmin = min(min(t[0], t[1]), t[2]);
|
|
|
|
tmin = tmin * glm::vec3((float) textureSize);
|
|
|
|
tmin = floor(tmin) - glm::vec3(2.0f);
|
|
|
|
//tmin = tmin - glm::vec3(1.0f);
|
|
|
|
tmin = max(tmin, glm::vec3(0.1));
|
|
|
|
|
|
|
|
// glm::vec3 tmax = min(
|
|
|
|
// ceil(
|
|
|
|
// max(max(t[0], t[1]), t[2])
|
|
|
|
// * glm::vec3((float) textureSize))
|
|
|
|
// + glm::vec3(1.0f), glm::vec3(textureSize - 1));
|
|
|
|
|
|
|
|
glm::vec3 tmax = max(max(t[0], t[1]), t[2]);
|
|
|
|
tmax = tmax * glm::vec3((float) textureSize);
|
|
|
|
tmax = ceil(tmax) + glm::vec3(2.0f);
|
|
|
|
tmax = min(tmax, glm::vec3(textureSize));
|
2017-10-29 05:16:22 +01:00
|
|
|
|
|
|
|
// TODO: borders!
|
|
|
|
for (int ix = tmin.x; ix < tmax.x; ix++) {
|
|
|
|
for (int iy = (textureSize - tmax.z); iy < (textureSize - tmin.z);
|
|
|
|
iy++) {
|
|
|
|
|
|
|
|
// https://stackoverflow.com/questions/2049582/how-to-determine-if-a-point-is-in-a-2d-triangle#2049593
|
|
|
|
|
|
|
|
// for (int iy = tmin.z; iy < tmax.z; iy++) {
|
|
|
|
|
|
|
|
// cout << "pix " << ix << " " << iy << endl;
|
|
|
|
// cout << "uv " << float(ix) * texf << " " << 1.f - float(iy) * texf << endl;
|
|
|
|
|
|
|
|
// pixel to uv space
|
|
|
|
glm::vec3 res = glm::vec3(float(ix) * texf, 0.f,
|
|
|
|
1.f - float(iy) * texf) - t[0];
|
|
|
|
// cout << "r = " << r.x << " " << r.y << endl;
|
|
|
|
glm::vec3 local = faceBase * itextureBase * res;
|
|
|
|
|
|
|
|
// cout << "res = " << res.x << " " << res.y << endl;
|
|
|
|
// vec2 res = ifaceBase * textureBase * r * faceBase;
|
|
|
|
//
|
|
|
|
// cout << "pix " << ix << " " << res.x << " " << res.y << " " << res.z << endl;
|
|
|
|
// float fb = dot(r, eb) / leb;
|
|
|
|
// float fc = dot(r, ec) / lec;
|
|
|
|
glm::vec3 sp = p[0] + local; //res.x * mb + res.y * mc;
|
|
|
|
float v = (float) density(sp, false);
|
|
|
|
//
|
|
|
|
//v = pow(v, 3);
|
|
|
|
// default color
|
|
|
|
// float r = 0.8 + v * 0.2, g = 0.75 + 0.2 * v, b = 0.7
|
|
|
|
// + 0.2 * v;
|
|
|
|
|
|
|
|
glm::vec3 rgb = glm::vec3(255)
|
|
|
|
* glm::mix(darkestColor, brightestColor, v);
|
|
|
|
albedo[ix + (textureSize - iy) * textureSize][0] = rgb.x;
|
|
|
|
albedo[ix + (textureSize - iy) * textureSize][1] = rgb.y;
|
|
|
|
albedo[ix + (textureSize - iy) * textureSize][2] = rgb.z;
|
|
|
|
|
|
|
|
// diff[ix + iy * ntex] = v * 255;
|
|
|
|
// diff[ix + iy * ntex][0] = (32 * rx) % 255;
|
|
|
|
// diff[ix + iy * ntex][1] = (32 * ry) % 255;
|
|
|
|
// diff[ix + iy * ntex][2] = 0; //(0.5 + sp.z) * 255;
|
|
|
|
|
|
|
|
// float rd = 1.f; //0.7 + 0.3 * length(r) * rects;
|
2017-11-02 03:44:44 +01:00
|
|
|
// albedo[ix + (textureSize - iy) * textureSize][0] = rd * (sp.x) * 255;
|
|
|
|
// albedo[ix + (textureSize - iy) * textureSize][1] = rd * (sp.y) * 255;
|
|
|
|
// albedo[ix + (textureSize - iy) * textureSize][2] = rd * (sp.z) * 255;
|
2017-10-29 05:16:22 +01:00
|
|
|
|
|
|
|
// albedo[ix + iy * textureSize][0] = length(res) * rects * 255;
|
|
|
|
// albedo[ix + iy * textureSize][1] = length(res) * rects * 255;
|
|
|
|
// albedo[ix + iy * textureSize][2] = length(res) * rects * 255;
|
|
|
|
|
|
|
|
// diff[ix + iy * ntex][0] = r.x * rects * 200;
|
|
|
|
// diff[ix + iy * ntex][1] = -r.z * rects * 200;
|
|
|
|
// diff[ix + iy * ntex][2] = 0;
|
|
|
|
|
|
|
|
// diff[ix + iy * ntex][0] = 128 + (res.x - 0.5) * 200;
|
|
|
|
// diff[ix + iy * ntex][1] = 128 + (res.y - 0.5) * 200;
|
|
|
|
// diff[ix + iy * ntex][2] = 0; //res.z * 255;
|
|
|
|
|
|
|
|
}
|
|
|
|
//}
|
|
|
|
}
|
|
|
|
rx++;
|
|
|
|
if (rx >= rects) {
|
|
|
|
rx = 0;
|
|
|
|
ry++;
|
|
|
|
}
|
2017-11-02 03:44:44 +01:00
|
|
|
#endif
|
2017-10-29 05:16:22 +01:00
|
|
|
}
|
|
|
|
//
|
|
|
|
// for (int ix = 0; ix < ntex; ix++) {
|
|
|
|
// for (int iy = 0; iy < ntex; iy++) {
|
|
|
|
//
|
|
|
|
// float v = (float) noise.octaveNoise0_1(ix * texf * frequency,
|
|
|
|
// iy * texf * frequency, 0.5 * frequency, 4);
|
|
|
|
// diff[ix + (ntex - iy) * ntex] = 5 + v * 250;
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
stbi_write_png("albedo.png", textureSize, textureSize, 3, albedo.data(), 0);
|
|
|
|
}
|