create material for texture baking
textures can now be created manually and are no longer tracked by SceneManager (and therefore require manual tracking/disposal)
This commit is contained in:
@@ -96,7 +96,7 @@
|
||||
#include "StreamBufferAdapter.hpp"
|
||||
#include "material/image.h"
|
||||
#include "TimeIt.hpp"
|
||||
#include "UnprojectTexture.hpp"
|
||||
#include "TextureProjection.hpp"
|
||||
|
||||
namespace thermion
|
||||
{
|
||||
@@ -1058,20 +1058,5 @@ namespace thermion
|
||||
return _engine->getCameraComponent(Entity::import(entity));
|
||||
}
|
||||
|
||||
void FilamentViewer::unprojectTexture(EntityId entityId, uint8_t *input, uint32_t inputWidth, uint32_t inputHeight, uint8_t *out, uint32_t outWidth, uint32_t outHeight)
|
||||
{
|
||||
// const auto *geometry = _sceneManager->getGeometry(entityId);
|
||||
// if (!geometry->uvs)
|
||||
// {
|
||||
// Log("No UVS");
|
||||
// return;
|
||||
// }
|
||||
|
||||
// UnprojectTexture unproject(geometry, _view->getCamera(), _engine);
|
||||
|
||||
// TODO - check that input dimensions match viewport?
|
||||
|
||||
// unproject.unproject(utils::Entity::import(entityId), input, out, inputWidth, inputHeight, outWidth, outHeight);
|
||||
}
|
||||
|
||||
} // namespace thermion
|
||||
|
||||
209
thermion_dart/native/src/TextureProjection.cpp
Normal file
209
thermion_dart/native/src/TextureProjection.cpp
Normal file
@@ -0,0 +1,209 @@
|
||||
// #include <filament/Engine.h>
|
||||
// #include <filament/Camera.h>
|
||||
// #include <filament/Texture.h>
|
||||
// #include <filament/VertexBuffer.h>
|
||||
// #include <filament/IndexBuffer.h>
|
||||
// #include <filament/RenderableManager.h>
|
||||
// #include <filament/TransformManager.h>
|
||||
// #include <math/mat4.h>
|
||||
// #include <math/vec2.h>
|
||||
// #include <math/vec3.h>
|
||||
// #include <math/vec4.h>
|
||||
// #include <utils/EntityManager.h>
|
||||
// #include <backend/PixelBufferDescriptor.h>
|
||||
// #include "Log.hpp"
|
||||
// #include <vector>
|
||||
// #include <algorithm>
|
||||
// #include <iostream>
|
||||
// #include "scene/CustomGeometry.hpp"
|
||||
// #include "TextureProjection.hpp"
|
||||
|
||||
// namespace thermion
|
||||
// {
|
||||
|
||||
// bool TextureProjection::isInsideTriangle(const math::float2 &p, const math::float2 &a, const math::float2 &b, const math::float2 &c)
|
||||
// {
|
||||
// float d1 = (p.x - b.x) * (a.y - b.y) - (a.x - b.x) * (p.y - b.y);
|
||||
// float d2 = (p.x - c.x) * (b.y - c.y) - (b.x - c.x) * (p.y - c.y);
|
||||
// float d3 = (p.x - a.x) * (c.y - a.y) - (c.x - a.x) * (p.y - a.y);
|
||||
// return (d1 >= 0 && d2 >= 0 && d3 >= 0) || (d1 <= 0 && d2 <= 0 && d3 <= 0);
|
||||
// }
|
||||
|
||||
// math::float3 TextureProjection::barycentric(const math::float2 &p, const math::float2 &a, const math::float2 &b, const math::float2 &c)
|
||||
// {
|
||||
// math::float2 v0 = b - a;
|
||||
// math::float2 v1 = c - a;
|
||||
// math::float2 v2 = p - a;
|
||||
|
||||
// float d00 = dot(v0, v0);
|
||||
// float d01 = dot(v0, v1);
|
||||
// float d11 = dot(v1, v1);
|
||||
// float d20 = dot(v2, v0);
|
||||
// float d21 = dot(v2, v1);
|
||||
|
||||
// float denom = d00 * d11 - d01 * d01;
|
||||
|
||||
// float v = (d11 * d20 - d01 * d21) / denom;
|
||||
// float w = (d00 * d21 - d01 * d20) / denom;
|
||||
// float u = 1.0f - v - w;
|
||||
|
||||
// return math::float3(u, v, w);
|
||||
// }
|
||||
|
||||
// void TextureProjection::project(utils::Entity entity, const uint8_t *inputTexture, uint8_t *outputTexture,
|
||||
// uint32_t inputWidth, uint32_t inputHeight,
|
||||
// uint32_t outputWidth, uint32_t outputHeight)
|
||||
// {
|
||||
|
||||
// // auto &rm = _engine->getRenderableManager();
|
||||
|
||||
// // auto &tm = _engine->getTransformManager();
|
||||
|
||||
// // math::mat4 invViewProj = Camera::inverseProjection(_camera.getProjectionMatrix()) * _camera.getModelMatrix();
|
||||
|
||||
// // auto ti = tm.getInstance(entity);
|
||||
// // math::mat4f worldTransform = tm.getWorldTransform(ti);
|
||||
// // auto inverseWorldTransform = inverse(worldTransform);
|
||||
|
||||
// // const float *vertices = _geometry->vertices;
|
||||
// // const float *uvs = _geometry->uvs;
|
||||
// // const uint16_t *indices = _geometry->indices;
|
||||
// // uint32_t numIndices = _geometry->numIndices;
|
||||
|
||||
// // // Create a depth buffer
|
||||
// // std::vector<float> depthBuffer(inputWidth * inputHeight, std::numeric_limits<float>::infinity());
|
||||
|
||||
// // // Create a buffer to store the triangle index for each pixel
|
||||
// // std::vector<int> triangleIndexBuffer(inputWidth * inputHeight, -1);
|
||||
|
||||
// // auto max = 0.0f;
|
||||
// // auto min = 99.0f;
|
||||
|
||||
// // // Depth pre-pass
|
||||
// // for (size_t i = 0; i < numIndices; i += 3)
|
||||
// // {
|
||||
// // math::float3 v0(vertices[indices[i] * 3], vertices[indices[i] * 3 + 1], vertices[indices[i] * 3 + 2]);
|
||||
// // math::float3 v1(vertices[indices[i + 1] * 3], vertices[indices[i + 1] * 3 + 1], vertices[indices[i + 1] * 3 + 2]);
|
||||
// // math::float3 v2(vertices[indices[i + 2] * 3], vertices[indices[i + 2] * 3 + 1], vertices[indices[i + 2] * 3 + 2]);
|
||||
|
||||
// // math::float2 uv0(uvs[(indices[i] * 2)], uvs[(indices[i] * 2) + 1]);
|
||||
// // math::float2 uv1(uvs[(indices[i + 1] * 2)], uvs[(indices[i + 1] * 2) + 1]);
|
||||
// // math::float2 uv2(uvs[(indices[i + 2] * 2)], uvs[(indices[i + 2] * 2) + 1]);
|
||||
|
||||
// // // Transform vertices to world space
|
||||
// // v0 = (worldTransform * math::float4(v0, 1.0f)).xyz;
|
||||
// // v1 = (worldTransform * math::float4(v1, 1.0f)).xyz;
|
||||
// // v2 = (worldTransform * math::float4(v2, 1.0f)).xyz;
|
||||
|
||||
// // // Project vertices to screen space
|
||||
// // math::float4 clipPos0 = _camera.getProjectionMatrix() * _camera.getViewMatrix() * math::float4(v0, 1.0f);
|
||||
// // math::float4 clipPos1 = _camera.getProjectionMatrix() * _camera.getViewMatrix() * math::float4(v1, 1.0f);
|
||||
// // math::float4 clipPos2 = _camera.getProjectionMatrix() * _camera.getViewMatrix() * math::float4(v2, 1.0f);
|
||||
|
||||
// // math::float3 ndcPos0 = clipPos0.xyz / clipPos0.w;
|
||||
// // math::float3 ndcPos1 = clipPos1.xyz / clipPos1.w;
|
||||
// // math::float3 ndcPos2 = clipPos2.xyz / clipPos2.w;
|
||||
|
||||
// // // Convert NDC to screen coordinates
|
||||
// // math::float2 screenPos0((ndcPos0.x * 0.5f + 0.5f) * inputWidth, (1.0f - (ndcPos0.y * 0.5f + 0.5f)) * inputHeight);
|
||||
// // math::float2 screenPos1((ndcPos1.x * 0.5f + 0.5f) * inputWidth, (1.0f - (ndcPos1.y * 0.5f + 0.5f)) * inputHeight);
|
||||
// // math::float2 screenPos2((ndcPos2.x * 0.5f + 0.5f) * inputWidth, (1.0f - (ndcPos2.y * 0.5f + 0.5f)) * inputHeight);
|
||||
|
||||
// // // Compute bounding box of the triangle
|
||||
// // int minX = std::max(0, static_cast<int>(std::min({screenPos0.x, screenPos1.x, screenPos2.x})));
|
||||
// // int maxX = std::min(static_cast<int>(inputWidth) - 1, static_cast<int>(std::max({screenPos0.x, screenPos1.x, screenPos2.x})));
|
||||
// // int minY = std::max(0, static_cast<int>(std::min({screenPos0.y, screenPos1.y, screenPos2.y})));
|
||||
// // int maxY = std::min(static_cast<int>(inputHeight) - 1, static_cast<int>(std::max({screenPos0.y, screenPos1.y, screenPos2.y})));
|
||||
|
||||
// // // Iterate over the bounding box
|
||||
// // for (int y = minY; y <= maxY; ++y)
|
||||
// // {
|
||||
// // for (int x = minX; x <= maxX; ++x)
|
||||
// // {
|
||||
// // math::float2 pixelPos(x + 0.5f, y + 0.5f);
|
||||
|
||||
// // if (isInsideTriangle(pixelPos, screenPos0, screenPos1, screenPos2))
|
||||
// // {
|
||||
// // math::float3 bary = barycentric(pixelPos, screenPos0, screenPos1, screenPos2);
|
||||
|
||||
// // // Interpolate depth
|
||||
// // float depth = bary.x * ndcPos0.z + bary.y * ndcPos1.z + bary.z * ndcPos2.z;
|
||||
|
||||
// // // Depth test
|
||||
// // if (depth < depthBuffer[y * inputWidth + x])
|
||||
// // {
|
||||
|
||||
// // if (depth > max)
|
||||
// // {
|
||||
// // max = depth;
|
||||
// // }
|
||||
// // if (depth < min)
|
||||
// // {
|
||||
// // min = depth;
|
||||
// // }
|
||||
// // depthBuffer[y * inputWidth + x] = depth;
|
||||
// // triangleIndexBuffer[y * inputWidth + x] = i / 3; // Store triangle index
|
||||
// // }
|
||||
// // }
|
||||
// // }
|
||||
// // }
|
||||
// // }
|
||||
|
||||
// // for (uint32_t y = 0; y < outputHeight; ++y)
|
||||
// // {
|
||||
// // for (uint32_t x = 0; x < outputWidth; ++x)
|
||||
// // {
|
||||
|
||||
// // math::float2 uv(static_cast<float>(x) / outputWidth, static_cast<float>(y) / outputHeight);
|
||||
|
||||
// // // Use the UV coordinates to get the corresponding 3D position on the renderable
|
||||
// // math::float3 objectPos;
|
||||
// // math::float2 interpolatedUV;
|
||||
// // bool found = false;
|
||||
|
||||
// // // Iterate over triangles to find which one contains this UV coordinate
|
||||
// // for (size_t i = 0; i < numIndices; i += 3)
|
||||
// // {
|
||||
// // math::float2 uv0 = *(math::float2 *)&uvs[indices[i] * 2];
|
||||
// // math::float2 uv1 = *(math::float2 *)&uvs[indices[i + 1] * 2];
|
||||
// // math::float2 uv2 = *(math::float2 *)&uvs[indices[i + 2] * 2];
|
||||
|
||||
// // if (isInsideTriangle(uv, uv0, uv1, uv2))
|
||||
// // {
|
||||
// // // Compute barycentric coordinates in UV space
|
||||
// // math::float3 bary = barycentric(uv, uv0, uv1, uv2);
|
||||
|
||||
// // // Interpolate 3D position
|
||||
// // math::float3 v0(vertices[indices[i] * 3], vertices[indices[i] * 3 + 1], vertices[indices[i] * 3 + 2]);
|
||||
// // math::float3 v1(vertices[indices[i + 1] * 3], vertices[indices[i + 1] * 3 + 1], vertices[indices[i + 1] * 3 + 2]);
|
||||
// // math::float3 v2(vertices[indices[i + 2] * 3], vertices[indices[i + 2] * 3 + 1], vertices[indices[i + 2] * 3 + 2]);
|
||||
|
||||
// // objectPos = v0 * bary.x + v1 * bary.y + v2 * bary.z;
|
||||
// // interpolatedUV = uv;
|
||||
|
||||
// // // Find the screen coordinates on the input texture
|
||||
// // math::float3 worldPos = (worldTransform * math::float4(objectPos, 1.0f)).xyz;
|
||||
// // // Project the world position to screen space
|
||||
// // math::float4 clipPos = _camera.getProjectionMatrix() * _camera.getViewMatrix() * math::float4(worldPos, 1.0f);
|
||||
// // math::float3 ndcPos = clipPos.xyz / clipPos.w;
|
||||
// // // Convert NDC to screen coordinates
|
||||
// // uint32_t screenX = (ndcPos.x * 0.5f + 0.5f) * inputWidth;
|
||||
// // uint32_t screenY = (1.0f - (ndcPos.y * 0.5f + 0.5f)) * inputHeight;
|
||||
|
||||
// // if (triangleIndexBuffer[(screenY * inputWidth) + screenX] == i / 3)
|
||||
// // {
|
||||
// // if (screenX >= 0 && screenX < inputWidth && screenY >= 0 && screenY < inputHeight)
|
||||
// // {
|
||||
// // int inputIndex = (screenY * inputWidth + screenX) * 4;
|
||||
// // int outputIndex = (y * outputWidth + x) * 4;
|
||||
// // std::copy_n(&inputTexture[inputIndex], 4, &outputTexture[outputIndex]);
|
||||
// // }
|
||||
// // }
|
||||
// // }
|
||||
// // }
|
||||
// // }
|
||||
// // }
|
||||
// }
|
||||
|
||||
// } // namespace thermion
|
||||
|
||||
@@ -1,211 +0,0 @@
|
||||
#include <filament/Engine.h>
|
||||
#include <filament/Camera.h>
|
||||
#include <filament/Texture.h>
|
||||
#include <filament/VertexBuffer.h>
|
||||
#include <filament/IndexBuffer.h>
|
||||
#include <filament/RenderableManager.h>
|
||||
#include <filament/TransformManager.h>
|
||||
#include <math/mat4.h>
|
||||
#include <math/vec2.h>
|
||||
#include <math/vec3.h>
|
||||
#include <math/vec4.h>
|
||||
#include <utils/EntityManager.h>
|
||||
#include <backend/PixelBufferDescriptor.h>
|
||||
#include "Log.hpp"
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include "scene/CustomGeometry.hpp"
|
||||
#include "UnprojectTexture.hpp"
|
||||
|
||||
namespace thermion
|
||||
{
|
||||
|
||||
bool UnprojectTexture::isInsideTriangle(const math::float2 &p, const math::float2 &a, const math::float2 &b, const math::float2 &c)
|
||||
{
|
||||
float d1 = (p.x - b.x) * (a.y - b.y) - (a.x - b.x) * (p.y - b.y);
|
||||
float d2 = (p.x - c.x) * (b.y - c.y) - (b.x - c.x) * (p.y - c.y);
|
||||
float d3 = (p.x - a.x) * (c.y - a.y) - (c.x - a.x) * (p.y - a.y);
|
||||
return (d1 >= 0 && d2 >= 0 && d3 >= 0) || (d1 <= 0 && d2 <= 0 && d3 <= 0);
|
||||
}
|
||||
|
||||
math::float3 UnprojectTexture::barycentric(const math::float2 &p, const math::float2 &a, const math::float2 &b, const math::float2 &c)
|
||||
{
|
||||
math::float2 v0 = b - a;
|
||||
math::float2 v1 = c - a;
|
||||
math::float2 v2 = p - a;
|
||||
|
||||
float d00 = dot(v0, v0);
|
||||
float d01 = dot(v0, v1);
|
||||
float d11 = dot(v1, v1);
|
||||
float d20 = dot(v2, v0);
|
||||
float d21 = dot(v2, v1);
|
||||
|
||||
float denom = d00 * d11 - d01 * d01;
|
||||
|
||||
float v = (d11 * d20 - d01 * d21) / denom;
|
||||
float w = (d00 * d21 - d01 * d20) / denom;
|
||||
float u = 1.0f - v - w;
|
||||
|
||||
return math::float3(u, v, w);
|
||||
}
|
||||
|
||||
void UnprojectTexture::unproject(utils::Entity entity, const uint8_t *inputTexture, uint8_t *outputTexture,
|
||||
uint32_t inputWidth, uint32_t inputHeight,
|
||||
uint32_t outputWidth, uint32_t outputHeight)
|
||||
{
|
||||
|
||||
// auto &rm = _engine->getRenderableManager();
|
||||
|
||||
// auto &tm = _engine->getTransformManager();
|
||||
|
||||
// math::mat4 invViewProj = Camera::inverseProjection(_camera.getProjectionMatrix()) * _camera.getModelMatrix();
|
||||
|
||||
// auto ti = tm.getInstance(entity);
|
||||
// math::mat4f worldTransform = tm.getWorldTransform(ti);
|
||||
// auto inverseWorldTransform = inverse(worldTransform);
|
||||
|
||||
// const float *vertices = _geometry->vertices;
|
||||
// const float *uvs = _geometry->uvs;
|
||||
// const uint16_t *indices = _geometry->indices;
|
||||
// uint32_t numIndices = _geometry->numIndices;
|
||||
|
||||
// // Create a depth buffer
|
||||
// std::vector<float> depthBuffer(inputWidth * inputHeight, std::numeric_limits<float>::infinity());
|
||||
|
||||
// // Create a buffer to store the triangle index for each pixel
|
||||
// std::vector<int> triangleIndexBuffer(inputWidth * inputHeight, -1);
|
||||
|
||||
// auto max = 0.0f;
|
||||
// auto min = 99.0f;
|
||||
|
||||
// // Depth pre-pass
|
||||
// for (size_t i = 0; i < numIndices; i += 3)
|
||||
// {
|
||||
// math::float3 v0(vertices[indices[i] * 3], vertices[indices[i] * 3 + 1], vertices[indices[i] * 3 + 2]);
|
||||
// math::float3 v1(vertices[indices[i + 1] * 3], vertices[indices[i + 1] * 3 + 1], vertices[indices[i + 1] * 3 + 2]);
|
||||
// math::float3 v2(vertices[indices[i + 2] * 3], vertices[indices[i + 2] * 3 + 1], vertices[indices[i + 2] * 3 + 2]);
|
||||
|
||||
// math::float2 uv0(uvs[(indices[i] * 2)], uvs[(indices[i] * 2) + 1]);
|
||||
// math::float2 uv1(uvs[(indices[i + 1] * 2)], uvs[(indices[i + 1] * 2) + 1]);
|
||||
// math::float2 uv2(uvs[(indices[i + 2] * 2)], uvs[(indices[i + 2] * 2) + 1]);
|
||||
|
||||
// // Transform vertices to world space
|
||||
// v0 = (worldTransform * math::float4(v0, 1.0f)).xyz;
|
||||
// v1 = (worldTransform * math::float4(v1, 1.0f)).xyz;
|
||||
// v2 = (worldTransform * math::float4(v2, 1.0f)).xyz;
|
||||
|
||||
// // Project vertices to screen space
|
||||
// math::float4 clipPos0 = _camera.getProjectionMatrix() * _camera.getViewMatrix() * math::float4(v0, 1.0f);
|
||||
// math::float4 clipPos1 = _camera.getProjectionMatrix() * _camera.getViewMatrix() * math::float4(v1, 1.0f);
|
||||
// math::float4 clipPos2 = _camera.getProjectionMatrix() * _camera.getViewMatrix() * math::float4(v2, 1.0f);
|
||||
|
||||
// math::float3 ndcPos0 = clipPos0.xyz / clipPos0.w;
|
||||
// math::float3 ndcPos1 = clipPos1.xyz / clipPos1.w;
|
||||
// math::float3 ndcPos2 = clipPos2.xyz / clipPos2.w;
|
||||
|
||||
// // Convert NDC to screen coordinates
|
||||
// math::float2 screenPos0((ndcPos0.x * 0.5f + 0.5f) * inputWidth, (1.0f - (ndcPos0.y * 0.5f + 0.5f)) * inputHeight);
|
||||
// math::float2 screenPos1((ndcPos1.x * 0.5f + 0.5f) * inputWidth, (1.0f - (ndcPos1.y * 0.5f + 0.5f)) * inputHeight);
|
||||
// math::float2 screenPos2((ndcPos2.x * 0.5f + 0.5f) * inputWidth, (1.0f - (ndcPos2.y * 0.5f + 0.5f)) * inputHeight);
|
||||
|
||||
// // Compute bounding box of the triangle
|
||||
// int minX = std::max(0, static_cast<int>(std::min({screenPos0.x, screenPos1.x, screenPos2.x})));
|
||||
// int maxX = std::min(static_cast<int>(inputWidth) - 1, static_cast<int>(std::max({screenPos0.x, screenPos1.x, screenPos2.x})));
|
||||
// int minY = std::max(0, static_cast<int>(std::min({screenPos0.y, screenPos1.y, screenPos2.y})));
|
||||
// int maxY = std::min(static_cast<int>(inputHeight) - 1, static_cast<int>(std::max({screenPos0.y, screenPos1.y, screenPos2.y})));
|
||||
|
||||
// // Iterate over the bounding box
|
||||
// for (int y = minY; y <= maxY; ++y)
|
||||
// {
|
||||
// for (int x = minX; x <= maxX; ++x)
|
||||
// {
|
||||
// math::float2 pixelPos(x + 0.5f, y + 0.5f);
|
||||
|
||||
// if (isInsideTriangle(pixelPos, screenPos0, screenPos1, screenPos2))
|
||||
// {
|
||||
// math::float3 bary = barycentric(pixelPos, screenPos0, screenPos1, screenPos2);
|
||||
|
||||
// // Interpolate depth
|
||||
// float depth = bary.x * ndcPos0.z + bary.y * ndcPos1.z + bary.z * ndcPos2.z;
|
||||
|
||||
// // Depth test
|
||||
// if (depth < depthBuffer[y * inputWidth + x])
|
||||
// {
|
||||
|
||||
// if (depth > max)
|
||||
// {
|
||||
// max = depth;
|
||||
// }
|
||||
// if (depth < min)
|
||||
// {
|
||||
// min = depth;
|
||||
// }
|
||||
// depthBuffer[y * inputWidth + x] = depth;
|
||||
// triangleIndexBuffer[y * inputWidth + x] = i / 3; // Store triangle index
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// for (uint32_t y = 0; y < outputHeight; ++y)
|
||||
// {
|
||||
// for (uint32_t x = 0; x < outputWidth; ++x)
|
||||
// {
|
||||
|
||||
// math::float2 uv(static_cast<float>(x) / outputWidth, static_cast<float>(y) / outputHeight);
|
||||
|
||||
// // Use the UV coordinates to get the corresponding 3D position on the renderable
|
||||
// math::float3 objectPos;
|
||||
// math::float2 interpolatedUV;
|
||||
// bool found = false;
|
||||
|
||||
// // Iterate over triangles to find which one contains this UV coordinate
|
||||
// for (size_t i = 0; i < numIndices; i += 3)
|
||||
// {
|
||||
// math::float2 uv0 = *(math::float2 *)&uvs[indices[i] * 2];
|
||||
// math::float2 uv1 = *(math::float2 *)&uvs[indices[i + 1] * 2];
|
||||
// math::float2 uv2 = *(math::float2 *)&uvs[indices[i + 2] * 2];
|
||||
|
||||
// if (isInsideTriangle(uv, uv0, uv1, uv2))
|
||||
// {
|
||||
// // Compute barycentric coordinates in UV space
|
||||
// math::float3 bary = barycentric(uv, uv0, uv1, uv2);
|
||||
|
||||
// // Interpolate 3D position
|
||||
// math::float3 v0(vertices[indices[i] * 3], vertices[indices[i] * 3 + 1], vertices[indices[i] * 3 + 2]);
|
||||
// math::float3 v1(vertices[indices[i + 1] * 3], vertices[indices[i + 1] * 3 + 1], vertices[indices[i + 1] * 3 + 2]);
|
||||
// math::float3 v2(vertices[indices[i + 2] * 3], vertices[indices[i + 2] * 3 + 1], vertices[indices[i + 2] * 3 + 2]);
|
||||
|
||||
// objectPos = v0 * bary.x + v1 * bary.y + v2 * bary.z;
|
||||
// interpolatedUV = uv;
|
||||
|
||||
// // Find the screen coordinates on the input texture
|
||||
// math::float3 worldPos = (worldTransform * math::float4(objectPos, 1.0f)).xyz;
|
||||
// // Project the world position to screen space
|
||||
// math::float4 clipPos = _camera.getProjectionMatrix() * _camera.getViewMatrix() * math::float4(worldPos, 1.0f);
|
||||
// math::float3 ndcPos = clipPos.xyz / clipPos.w;
|
||||
// // Convert NDC to screen coordinates
|
||||
// uint32_t screenX = (ndcPos.x * 0.5f + 0.5f) * inputWidth;
|
||||
// uint32_t screenY = (1.0f - (ndcPos.y * 0.5f + 0.5f)) * inputHeight;
|
||||
|
||||
// if (triangleIndexBuffer[(screenY * inputWidth) + screenX] == i / 3)
|
||||
// {
|
||||
// if (screenX >= 0 && screenX < inputWidth && screenY >= 0 && screenY < inputHeight)
|
||||
// {
|
||||
// int inputIndex = (screenY * inputWidth + screenX) * 4;
|
||||
// int outputIndex = (y * outputWidth + x) * 4;
|
||||
// std::copy_n(&inputTexture[inputIndex], 4, &outputTexture[outputIndex]);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
} // namespace thermion
|
||||
|
||||
@@ -244,6 +244,12 @@ namespace thermion
|
||||
return reinterpret_cast<TTexture *>(texture);
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void Engine_destroyTexture(TEngine *tEngine, TTexture *tTexture) {
|
||||
auto *engine = reinterpret_cast<Engine *>(tEngine);
|
||||
auto *texture = reinterpret_cast<Texture *>(tTexture);
|
||||
engine->destroy(texture);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include <filament/Engine.h>
|
||||
#include <filament/Material.h>
|
||||
#include <filament/RenderTarget.h>
|
||||
#include <filament/Scene.h>
|
||||
#include <filament/Texture.h>
|
||||
#include <filament/TextureSampler.h>
|
||||
@@ -36,6 +37,12 @@ namespace thermion
|
||||
return reinterpret_cast<TLinearImage *>(linearImage);
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE float *Image_getBytes(TLinearImage *tLinearImage)
|
||||
{
|
||||
auto *linearImage = reinterpret_cast<::image::LinearImage *>(tLinearImage);
|
||||
return linearImage->getPixelRef();
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE uint32_t Image_getWidth(TLinearImage *tLinearImage)
|
||||
{
|
||||
auto *linearImage = reinterpret_cast<::image::LinearImage *>(tLinearImage);
|
||||
@@ -98,6 +105,13 @@ namespace thermion
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE TLinearImage *Image_createEmpty(uint32_t width,uint32_t height,uint32_t channel) {
|
||||
auto *image = new ::image::LinearImage(width, height, channel);
|
||||
return reinterpret_cast<TLinearImage*>(image);
|
||||
}
|
||||
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE TTextureSampler *TextureSampler_create()
|
||||
{
|
||||
auto *sampler = new filament::TextureSampler();
|
||||
@@ -217,6 +231,12 @@ namespace thermion
|
||||
delete textureSampler;
|
||||
}
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE TTexture *RenderTarget_getColorTexture(TRenderTarget *tRenderTarget) {
|
||||
auto renderTarget = reinterpret_cast<filament::RenderTarget*>(tRenderTarget);
|
||||
auto texture = renderTarget->getTexture(filament::RenderTarget::AttachmentPoint::COLOR0);
|
||||
return reinterpret_cast<TTexture*>(texture);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -413,20 +413,5 @@ extern "C"
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void unproject_texture(TViewer *viewer, EntityId entity, uint8_t *input, uint32_t inputWidth, uint32_t inputHeight, uint8_t *out, uint32_t outWidth, uint32_t outHeight)
|
||||
{
|
||||
// ((FilamentViewer *)viewer)->unprojectTexture(entity, input, inputWidth, inputHeight, out, outWidth, outHeight);
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void apply_texture_to_material(TSceneManager *sceneManager, EntityId entity, void *const texture, const char *parameterName, int materialIndex)
|
||||
{
|
||||
((SceneManager *)sceneManager)->applyTexture(entity, reinterpret_cast<Texture *>(texture), parameterName, materialIndex);
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void destroy_texture(TSceneManager *sceneManager, void *const texture)
|
||||
{
|
||||
((SceneManager *)sceneManager)->destroyTexture(reinterpret_cast<Texture *>(texture));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -722,17 +722,6 @@ std::packaged_task<void()> lambda(
|
||||
auto fut = _rl->add_task(lambda);
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void unproject_texture_render_thread(TViewer *viewer, EntityId entity, uint8_t *input, uint32_t inputWidth, uint32_t inputHeight, uint8_t *out, uint32_t outWidth, uint32_t outHeight, void (*callback)())
|
||||
{
|
||||
std::packaged_task<void()> lambda(
|
||||
[=]
|
||||
{
|
||||
unproject_texture(viewer, entity, input, inputWidth, inputHeight, out, outWidth, outHeight);
|
||||
callback();
|
||||
});
|
||||
auto fut = _rl->add_task(lambda);
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void AnimationManager_updateBoneMatricesRenderThread(
|
||||
TAnimationManager *tAnimationManager,
|
||||
TSceneAsset *sceneAsset,
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
#include "scene/Gizmo.hpp"
|
||||
#include "scene/SceneAsset.hpp"
|
||||
#include "scene/GeometrySceneAssetBuilder.hpp"
|
||||
#include "UnprojectTexture.hpp"
|
||||
#include "TextureProjection.hpp"
|
||||
|
||||
#include "resources/translation_gizmo_glb.h"
|
||||
#include "resources/rotation_gizmo_glb.h"
|
||||
@@ -470,17 +470,10 @@ namespace thermion
|
||||
destroyAssets();
|
||||
std::lock_guard lock(_mutex);
|
||||
|
||||
for (auto *texture : _textures)
|
||||
{
|
||||
_engine->destroy(texture);
|
||||
}
|
||||
|
||||
for (auto *materialInstance : _materialInstances)
|
||||
{
|
||||
_engine->destroy(materialInstance);
|
||||
}
|
||||
|
||||
_textures.clear();
|
||||
_materialInstances.clear();
|
||||
}
|
||||
|
||||
@@ -592,102 +585,6 @@ namespace thermion
|
||||
_sceneAssets.clear();
|
||||
}
|
||||
|
||||
Texture *SceneManager::createTexture(const uint8_t *data, size_t length, const char *name)
|
||||
{
|
||||
|
||||
// Create an input stream from the data
|
||||
std::istringstream stream(std::string(reinterpret_cast<const char *>(data), length));
|
||||
|
||||
// Decode the image
|
||||
image::LinearImage linearImage = image::ImageDecoder::decode(stream, name, image::ImageDecoder::ColorSpace::SRGB);
|
||||
|
||||
if (!linearImage.isValid())
|
||||
{
|
||||
Log("Failed to decode image.");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
uint32_t w = linearImage.getWidth();
|
||||
uint32_t h = linearImage.getHeight();
|
||||
uint32_t channels = linearImage.getChannels();
|
||||
|
||||
Texture::InternalFormat textureFormat = channels == 3 ? Texture::InternalFormat::RGB16F
|
||||
: Texture::InternalFormat::RGBA16F;
|
||||
Texture::Format bufferFormat = channels == 3 ? Texture::Format::RGB
|
||||
: Texture::Format::RGBA;
|
||||
|
||||
Texture *texture = Texture::Builder()
|
||||
.width(w)
|
||||
.height(h)
|
||||
.levels(1)
|
||||
.format(textureFormat)
|
||||
.sampler(Texture::Sampler::SAMPLER_2D)
|
||||
.build(*_engine);
|
||||
|
||||
if (!texture)
|
||||
{
|
||||
Log("Failed to create texture: ");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Texture::PixelBufferDescriptor buffer(
|
||||
linearImage.getPixelRef(),
|
||||
size_t(w * h * channels * sizeof(float)),
|
||||
bufferFormat,
|
||||
Texture::Type::FLOAT);
|
||||
|
||||
texture->setImage(*_engine, 0, std::move(buffer));
|
||||
|
||||
Log("Created texture: %s (%d x %d, %d channels)", name, w, h, channels);
|
||||
|
||||
_textures.insert(texture);
|
||||
|
||||
return texture;
|
||||
}
|
||||
|
||||
bool SceneManager::applyTexture(EntityId entityId, Texture *texture, const char *parameterName, int materialIndex)
|
||||
{
|
||||
auto entity = Entity::import(entityId);
|
||||
|
||||
if (entity.isNull())
|
||||
{
|
||||
Log("Entity %d is null?", entityId);
|
||||
return false;
|
||||
}
|
||||
|
||||
RenderableManager &rm = _engine->getRenderableManager();
|
||||
|
||||
auto renderable = rm.getInstance(entity);
|
||||
|
||||
if (!renderable.isValid())
|
||||
{
|
||||
Log("Renderable not valid, was the entity id correct (%d)?", entityId);
|
||||
return false;
|
||||
}
|
||||
|
||||
MaterialInstance *mi = rm.getMaterialInstanceAt(renderable, materialIndex);
|
||||
|
||||
if (!mi)
|
||||
{
|
||||
Log("ERROR: material index must be less than number of material instances");
|
||||
return false;
|
||||
}
|
||||
|
||||
auto sampler = TextureSampler();
|
||||
mi->setParameter(parameterName, texture, sampler);
|
||||
Log("Applied texture to entity %d", entityId);
|
||||
return true;
|
||||
}
|
||||
|
||||
void SceneManager::destroyTexture(Texture *texture)
|
||||
{
|
||||
if (_textures.find(texture) == _textures.end())
|
||||
{
|
||||
Log("Warning: couldn't find texture");
|
||||
}
|
||||
_textures.erase(texture);
|
||||
_engine->destroy(texture);
|
||||
}
|
||||
|
||||
void SceneManager::addCollisionComponent(EntityId entityId, void (*onCollisionCallback)(const EntityId entityId1, const EntityId entityId2), bool affectsTransform)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user