Commit for 2022.04.02 22-23-38.7z
This commit is contained in:
parent
b904c7f280
commit
947423860d
4
Makefile
4
Makefile
@ -31,8 +31,8 @@ EXT_LIB_NAME += ext
|
||||
#VULKAN_SDK_PATH += /c/VulkanSDK/1.2.162.0/
|
||||
#VULKAN_SDK_PATH += /c/VulkanSDK/1.2.176.1/
|
||||
#VULKAN_SDK_PATH += /c/VulkanSDK/1.2.182.0/
|
||||
VULKAN_SDK_PATH += /c/VulkanSDK/1.2.198.1/
|
||||
#VULKAN_SDK_PATH += /c/VulkanSDK/1.3.204.1/
|
||||
#VULKAN_SDK_PATH += /c/VulkanSDK/1.2.198.1/
|
||||
VULKAN_SDK_PATH += /c/VulkanSDK/1.3.204.1/
|
||||
|
||||
#GLSLC += $(VULKAN_SDK_PATH)/Bin/glslangValidator
|
||||
GLSLC += $(VULKAN_SDK_PATH)/Bin/glslc
|
||||
|
@ -46,7 +46,7 @@
|
||||
"ext": {
|
||||
"vulkan": {
|
||||
"validation": {
|
||||
"enabled": true,
|
||||
"enabled": false,
|
||||
"filters": [
|
||||
"MessageID = 0x124ffb34", // VUID-VkImageMemoryBarrier-oldLayout-01197
|
||||
"MessageID = 0x8ab1932c", // VUID-VkImageViewCreateInfo-imageViewType-04973
|
||||
@ -62,6 +62,7 @@
|
||||
"size": 1,
|
||||
// "size": [ 640, 480, "NEAREST" ],
|
||||
// "size": [ 1280, 720 ],
|
||||
"size": [ 960, 540 ],
|
||||
"msaa": 16
|
||||
},
|
||||
"experimental": {
|
||||
@ -109,7 +110,9 @@
|
||||
"VK_KHR_get_physical_device_properties2",
|
||||
"VK_KHR_get_surface_capabilities2"
|
||||
],
|
||||
"device": []
|
||||
"device": [
|
||||
"VK_KHR_swapchain"
|
||||
]
|
||||
}
|
||||
},
|
||||
"opengl": {
|
||||
|
@ -5,10 +5,10 @@
|
||||
|
||||
// { "filename": "./models/mcdonalds.glb", "delay": 0, "single threaded": false }
|
||||
// { "filename": "./models/mcdonalds/graph.json", "delay": 0, "single threaded": false, "category": "models" }
|
||||
// { "filename": "./models/mcdonalds/graph.json.gz", "delay": 0, "single threaded": false, "category": "models" }
|
||||
{ "filename": "./models/mcdonalds/graph.json.gz", "delay": 0, "single threaded": false, "category": "models" }
|
||||
|
||||
// { "filename": "./models/mini_mcd.glb", "delay": 0, "single threaded": false }
|
||||
{ "filename": "./models/mini_mcd/graph.json.gz", "delay": 0, "single threaded": false, "category": "models" }
|
||||
// { "filename": "./models/mini_mcd/graph.json.gz", "delay": 0, "single threaded": false, "category": "models" }
|
||||
],
|
||||
"metadata": {
|
||||
"model": {
|
||||
|
@ -1,7 +1,7 @@
|
||||
{
|
||||
"import": "/model.json",
|
||||
"assets": [
|
||||
{ "filename": "./models/tiny_msci.glb", "delay": 0, "single threaded": false, "category": "models" }
|
||||
// { "filename": "./models/tiny_msci.glb", "delay": 0, "single threaded": false, "category": "models" }
|
||||
// { "filename": "./models/tiny_msci/graph.json", "delay": 0, "single threaded": false, "category": "models" }
|
||||
// { "filename": "./models/tiny_msci/graph.json.gz", "delay": 0, "single threaded": false, "category": "models" }
|
||||
|
||||
@ -14,7 +14,7 @@
|
||||
// { "filename": "./models/msci/graph.json", "delay": 0, "single threaded": false, "category": "models" }
|
||||
// { "filename": "./models/msci/graph.json.gz", "delay": 0, "single threaded": false, "category": "models" }
|
||||
|
||||
// { "filename": "./models/medsci.glb", "delay": 0, "single threaded": false }
|
||||
{ "filename": "./models/medsci.glb", "delay": 0, "single threaded": false }
|
||||
// { "filename": "./models/medsci/graph.json", "delay": 0, "single threaded": false, "category": "models" }
|
||||
// { "filename": "./models/medsci/graph.json.gz", "delay": 0, "single threaded": false, "category": "models" }
|
||||
],
|
||||
|
@ -45,6 +45,8 @@ namespace ext {
|
||||
void destroy();
|
||||
};
|
||||
struct UF_API Texture {
|
||||
enums::Format::type_t DefaultFormat = enums::Format::R8G8B8A8_UNORM;
|
||||
|
||||
Device* device = nullptr;
|
||||
|
||||
GLuint image = GL_NULL_HANDLE;
|
||||
@ -52,6 +54,7 @@ namespace ext {
|
||||
enums::Image::viewType_t viewType = enums::Image::VIEW_TYPE_2D;
|
||||
enums::Format::type_t format = enums::Format::R8G8B8A8_UNORM;
|
||||
size_t internalFormat = 0;
|
||||
bool srgb = false;
|
||||
|
||||
struct Descriptor {
|
||||
GLuint image = GL_NULL_HANDLE;
|
||||
|
@ -44,6 +44,8 @@ namespace ext {
|
||||
};
|
||||
|
||||
struct UF_API Texture {
|
||||
static VkFormat DefaultFormat;
|
||||
|
||||
Device* device = nullptr;
|
||||
|
||||
VkImage image = VK_NULL_HANDLE;
|
||||
@ -54,6 +56,7 @@ namespace ext {
|
||||
VkDeviceMemory deviceMemory = VK_NULL_HANDLE;
|
||||
VkDescriptorImageInfo descriptor = {};
|
||||
VkFormat format = enums::Format::R8G8B8A8_UNORM;
|
||||
bool srgb = false;
|
||||
|
||||
Sampler sampler = {};
|
||||
|
||||
@ -88,32 +91,32 @@ namespace ext {
|
||||
);
|
||||
void loadFromFile(
|
||||
const uf::stl::string& filename,
|
||||
VkFormat format = VK_FORMAT_R8G8B8A8_UNORM,
|
||||
VkFormat format = DefaultFormat,
|
||||
VkImageUsageFlags imageUsageFlags = VK_IMAGE_USAGE_SAMPLED_BIT,
|
||||
VkImageLayout imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
|
||||
);
|
||||
void loadFromFile(
|
||||
const uf::stl::string& filename,
|
||||
Device& device,
|
||||
VkFormat format = VK_FORMAT_R8G8B8A8_UNORM,
|
||||
VkFormat format = DefaultFormat,
|
||||
VkImageUsageFlags imageUsageFlags = VK_IMAGE_USAGE_SAMPLED_BIT,
|
||||
VkImageLayout imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
|
||||
);
|
||||
void loadFromImage(
|
||||
const uf::Image& image,
|
||||
Device& device,
|
||||
VkFormat format = VK_FORMAT_R8G8B8A8_UNORM,
|
||||
VkFormat format = DefaultFormat,
|
||||
VkImageUsageFlags imageUsageFlags = VK_IMAGE_USAGE_SAMPLED_BIT,
|
||||
VkImageLayout imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
|
||||
);
|
||||
void loadFromImage(
|
||||
const uf::Image& image,
|
||||
VkFormat format = VK_FORMAT_R8G8B8A8_UNORM,
|
||||
VkFormat format = DefaultFormat,
|
||||
VkImageUsageFlags imageUsageFlags = VK_IMAGE_USAGE_SAMPLED_BIT,
|
||||
VkImageLayout imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
|
||||
);
|
||||
void fromBuffers( void* buffer, VkDeviceSize bufferSize, VkFormat format, uint32_t texWidth, uint32_t texHeight, uint32_t texDepth, uint32_t layers, Device& device, VkImageUsageFlags imageUsageFlags = VK_IMAGE_USAGE_SAMPLED_BIT, VkImageLayout imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL );
|
||||
void asRenderTarget( Device& device, uint32_t texWidth, uint32_t texHeight, VkFormat format = VK_FORMAT_R8G8B8A8_UNORM );
|
||||
void asRenderTarget( Device& device, uint32_t texWidth, uint32_t texHeight, VkFormat format = DefaultFormat );
|
||||
void aliasTexture( const Texture& );
|
||||
void aliasAttachment( const RenderTarget::Attachment& attachment, bool = true );
|
||||
void aliasAttachment( const RenderTarget::Attachment& attachment, size_t, bool = true );
|
||||
|
@ -14,10 +14,41 @@ namespace uf {
|
||||
} extents;
|
||||
|
||||
pod::Vector3ui id = {};
|
||||
uf::stl::vector<uf::stl::vector<uint32_t>> indices;
|
||||
uf::stl::vector<uint32_t> indices;
|
||||
};
|
||||
struct Grid {
|
||||
int divisions = 1;
|
||||
|
||||
struct {
|
||||
pod::Vector3f min = { std::numeric_limits<float>::max(), std::numeric_limits<float>::max(), std::numeric_limits<float>::max() };
|
||||
pod::Vector3f max = { -std::numeric_limits<float>::max(), -std::numeric_limits<float>::max(), -std::numeric_limits<float>::max() };
|
||||
|
||||
pod::Vector3f center = {};
|
||||
pod::Vector3f corner = {};
|
||||
|
||||
pod::Vector3f size = {};
|
||||
pod::Vector3f piece = {};
|
||||
} extents;
|
||||
|
||||
uf::stl::vector<Node> nodes;
|
||||
};
|
||||
|
||||
uf::stl::vector<Node> UF_API partition( uf::Mesh&, int );
|
||||
void UF_API print( const Grid&, size_t indices );
|
||||
Grid UF_API generate( int divisions, void* pPointer, size_t pStride, size_t pFirst, size_t pCount, void* iPointer, size_t iStride, size_t iFirst, size_t iCount );
|
||||
Grid UF_API partition( uf::Mesh&, int );
|
||||
|
||||
template<typename T, typename U = uint32_t>
|
||||
Grid UF_API partition( uf::stl::vector<T>& vertices, uf::stl::vector<U>& indices, int divisions ) {
|
||||
auto vertexDescriptor = T::descriptor.front();
|
||||
|
||||
for ( auto& descriptor : T::descriptor ) if ( descriptor.name == "position" ) { vertexDescriptor = descriptor; break; }
|
||||
UF_ASSERT( vertexDescriptor.name == "position" );
|
||||
|
||||
return generate( divisions,
|
||||
vertices.data(), sizeof(T), 0, vertices.size(),
|
||||
indices.data(), sizeof(U), 0, indices.size()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -12,7 +12,7 @@
|
||||
#if UF_ENV_DREAMCAST
|
||||
#define UF_GRAPH_LOAD_MULTITHREAD 0
|
||||
#else
|
||||
#define UF_GRAPH_LOAD_MULTITHREAD 1
|
||||
#define UF_GRAPH_LOAD_MULTITHREAD 0
|
||||
#endif
|
||||
|
||||
namespace {
|
||||
|
@ -12,7 +12,7 @@
|
||||
#if UF_ENV_DREAMCAST
|
||||
#define UF_GRAPH_LOAD_MULTITHREAD 0
|
||||
#else
|
||||
#define UF_GRAPH_LOAD_MULTITHREAD 1
|
||||
#define UF_GRAPH_LOAD_MULTITHREAD 0
|
||||
#endif
|
||||
|
||||
namespace {
|
||||
|
@ -391,8 +391,22 @@ void uf::graph::process( pod::Graph& graph ) {
|
||||
}
|
||||
// add atlas
|
||||
|
||||
|
||||
// setup textures
|
||||
uf::graph::storage.texture2Ds.reserve( uf::graph::storage.images.map.size() );
|
||||
|
||||
// figure out what texture is what exactly
|
||||
for ( auto& keyName : graph.materials ) {
|
||||
auto& material = uf::graph::storage.materials[keyName];
|
||||
auto ID = material.indexAlbedo;
|
||||
|
||||
if ( !(0 <= ID && ID < graph.textures.size()) ) continue;
|
||||
|
||||
auto texName = graph.textures[ID];
|
||||
auto& texture = uf::graph::storage.texture2Ds[texName];
|
||||
texture.srgb = true;
|
||||
}
|
||||
|
||||
for ( auto& keyName : graph.images ) {
|
||||
auto& image = uf::graph::storage.images[keyName];
|
||||
auto& texture = uf::graph::storage.texture2Ds[keyName];
|
||||
@ -401,6 +415,7 @@ void uf::graph::process( pod::Graph& graph ) {
|
||||
auto filter = graph.metadata["filter"].as<uf::stl::string>() == "NEAREST" && !isLightmap ? uf::renderer::enums::Filter::NEAREST : uf::renderer::enums::Filter::LINEAR;
|
||||
texture.sampler.descriptor.filter.min = filter;
|
||||
texture.sampler.descriptor.filter.mag = filter;
|
||||
|
||||
texture.loadFromImage( image );
|
||||
#if UF_ENV_DREAMCAST
|
||||
image.clear();
|
||||
@ -468,6 +483,7 @@ void uf::graph::process( pod::Graph& graph ) {
|
||||
instance.lightmapID = it - keys.begin();
|
||||
}
|
||||
}
|
||||
|
||||
uf::graph::reload();
|
||||
|
||||
// setup combined mesh if requested
|
||||
@ -513,7 +529,8 @@ void uf::graph::process( pod::Graph& graph ) {
|
||||
|
||||
// slice mesh
|
||||
{
|
||||
auto slices = uf::meshgrid::partition( mesh, 3 );
|
||||
// auto slices = uf::meshgrid::partition( mesh, 1 );
|
||||
// uf::meshgrid::print( slices, mesh.index.count );
|
||||
}
|
||||
|
||||
{
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include <uf/utils/serialize/serializer.h>
|
||||
#include <uf/utils/image/atlas.h>
|
||||
#include <uf/utils/string/hash.h>
|
||||
#include <uf/utils/mesh/grid.h>
|
||||
|
||||
#include <gltf/tiny_gltf.h>
|
||||
#include <uf/ext/gltf/gltf.h>
|
||||
@ -40,9 +41,7 @@ namespace {
|
||||
default: return uf::renderer::enums::Filter::LINEAR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace {
|
||||
int32_t loadNode( const tinygltf::Model& model, pod::Graph& graph, int32_t nodeIndex, int32_t parentIndex );
|
||||
|
||||
int32_t loadNodes( const tinygltf::Model& model, pod::Graph& graph, const std::vector<int>& nodes, int32_t nodeIndex ) {
|
||||
@ -109,6 +108,14 @@ namespace {
|
||||
}
|
||||
return nodeIndex;
|
||||
}
|
||||
|
||||
template<typename T = uf::graph::mesh::Skinned, typename U = uint32_t>
|
||||
struct Primitive {
|
||||
uf::stl::vector<T> vertices;
|
||||
uf::stl::vector<U> indices;
|
||||
|
||||
pod::Primitive primitive;
|
||||
};
|
||||
}
|
||||
|
||||
pod::Graph ext::gltf::load( const uf::stl::string& filename, const uf::Serializer& metadata ) {
|
||||
@ -226,19 +233,87 @@ pod::Graph ext::gltf::load( const uf::stl::string& filename, const uf::Serialize
|
||||
for ( auto& m : model.meshes ) {
|
||||
auto meshID = graph.meshes.size();
|
||||
auto keyName = graph.meshes.emplace_back(filename + "/" + m.name);
|
||||
|
||||
graph.primitives.emplace_back(keyName);
|
||||
graph.drawCommands.emplace_back(keyName);
|
||||
|
||||
auto& drawCommands = /*graph.storage*/uf::graph::storage.drawCommands[keyName];
|
||||
auto& primitives = /*graph.storage*/uf::graph::storage.primitives[keyName];
|
||||
auto& mesh = /*graph.storage*/uf::graph::storage.meshes[keyName];
|
||||
|
||||
mesh.bindIndirect<pod::DrawCommand>();
|
||||
#if 0 || UF_USE_VULKAN
|
||||
bool full = true;
|
||||
#else
|
||||
bool full = graph.metadata["flags"]["SKINNED"].as<bool>();
|
||||
#endif
|
||||
if ( full ) {
|
||||
|
||||
size_t divisions = m.name == "worldspawn_20" ? 2 : 1;
|
||||
if ( graph.metadata["flags"]["SKINNED"].as<bool>() ) {
|
||||
#define UF_GRAPH_MESH_FORMAT uf::graph::mesh::Skinned, uint32_t
|
||||
#define UF_GRAPH_PROCESS_PRIMITIVES_FULL 1
|
||||
#define UF_GRAPH_GRID 1
|
||||
#include "processPrimitives2.inl"
|
||||
#undef UF_GRAPH_PROCESS_PRIMITIVES_FULL
|
||||
#undef UF_GRAPH_MESH_FORMAT
|
||||
} else {
|
||||
#define UF_GRAPH_MESH_FORMAT uf::graph::mesh::Base, uint32_t
|
||||
#define UF_GRAPH_PROCESS_PRIMITIVES_FULL 0
|
||||
#include "processPrimitives2.inl"
|
||||
#undef UF_GRAPH_PROCESS_PRIMITIVES_FULL
|
||||
#undef UF_GRAPH_MESH_FORMAT
|
||||
}
|
||||
|
||||
mesh.insertIndirects(drawCommands);
|
||||
mesh.updateDescriptor();
|
||||
|
||||
#if 0
|
||||
if ( m.name == "worldspawn_20" ) {
|
||||
uf::stl::vector<::Primitive<>> objs;
|
||||
|
||||
#include "processPrimitives2.inl"
|
||||
|
||||
graph.primitives.emplace_back(keyName);
|
||||
graph.drawCommands.emplace_back(keyName);
|
||||
|
||||
auto& drawCommands = /*graph.storage*/uf::graph::storage.drawCommands[keyName];
|
||||
auto& primitives = /*graph.storage*/uf::graph::storage.primitives[keyName];
|
||||
auto& mesh = /*graph.storage*/uf::graph::storage.meshes[keyName];
|
||||
|
||||
mesh.bindIndirect<pod::DrawCommand>();
|
||||
mesh.bind<uf::graph::mesh::Skinned, uint32_t>();
|
||||
|
||||
size_t indexID = 0;
|
||||
size_t vertexID = 0;
|
||||
for ( auto& obj : objs ) {
|
||||
drawCommands.emplace_back(pod::DrawCommand{
|
||||
.indices = obj.indices.size(),
|
||||
.instances = 1,
|
||||
.indexID = indexID,
|
||||
.vertexID = vertexID,
|
||||
.instanceID = 0,
|
||||
|
||||
|
||||
.vertices = obj.vertices.size(),
|
||||
});
|
||||
|
||||
primitives.emplace_back( obj.primitive );
|
||||
|
||||
indexID += obj.indices.size();
|
||||
vertexID += obj.vertices.size();
|
||||
|
||||
mesh.insertVertices(obj.vertices);
|
||||
mesh.insertIndices(obj.indices);
|
||||
}
|
||||
|
||||
mesh.insertIndirects(drawCommands);
|
||||
mesh.updateDescriptor();
|
||||
} else {
|
||||
graph.primitives.emplace_back(keyName);
|
||||
graph.drawCommands.emplace_back(keyName);
|
||||
|
||||
auto& drawCommands = /*graph.storage*/uf::graph::storage.drawCommands[keyName];
|
||||
auto& primitives = /*graph.storage*/uf::graph::storage.primitives[keyName];
|
||||
auto& mesh = /*graph.storage*/uf::graph::storage.meshes[keyName];
|
||||
|
||||
mesh.bindIndirect<pod::DrawCommand>();
|
||||
|
||||
if ( graph.metadata["flags"]["SKINNED"].as<bool>() ) {
|
||||
mesh.bind<uf::graph::mesh::Skinned, uint32_t>();
|
||||
uf::stl::vector<uf::graph::mesh::Skinned> vertices;
|
||||
uf::stl::vector<uint32_t> indices;
|
||||
@ -254,6 +329,8 @@ pod::Graph ext::gltf::load( const uf::stl::string& filename, const uf::Serialize
|
||||
mesh.insertIndirects(drawCommands);
|
||||
mesh.updateDescriptor();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
// load skins
|
||||
{
|
||||
|
229
engine/src/ext/gltf/processPrimitives2.inl
Normal file
229
engine/src/ext/gltf/processPrimitives2.inl
Normal file
@ -0,0 +1,229 @@
|
||||
uf::stl::vector<::Primitive<UF_GRAPH_MESH_FORMAT>> objs;
|
||||
uf::stl::vector<::Primitive<UF_GRAPH_MESH_FORMAT>> slices;
|
||||
|
||||
mesh.bind<UF_GRAPH_MESH_FORMAT>();
|
||||
|
||||
for ( auto& p : m.primitives ) {
|
||||
auto& obj = objs.emplace_back();
|
||||
|
||||
struct Attribute {
|
||||
uf::stl::string name = "";
|
||||
size_t components = 0;
|
||||
size_t length = 0;
|
||||
size_t stride = 0;
|
||||
uint8_t* buffer = NULL;
|
||||
|
||||
uf::stl::vector<float> floats;
|
||||
uf::stl::vector<uint8_t> int8s;
|
||||
uf::stl::vector<uint16_t> int16s;
|
||||
uf::stl::vector<uint32_t> int32s;
|
||||
};
|
||||
|
||||
uf::stl::unordered_map<uf::stl::string, Attribute> attributes = {
|
||||
{"POSITION", {}},
|
||||
{"TEXCOORD_0", {}},
|
||||
{"COLOR_0", {}},
|
||||
{"NORMAL", {}},
|
||||
#if UF_GRAPH_PROCESS_PRIMITIVES_FULL
|
||||
{"TANGENT", {}},
|
||||
{"JOINTS_0", {}},
|
||||
{"WEIGHTS_0", {}},
|
||||
#endif
|
||||
};
|
||||
|
||||
for ( auto& kv : attributes ) {
|
||||
auto& attribute = kv.second;
|
||||
attribute.name = kv.first;
|
||||
auto it = p.attributes.find(attribute.name);
|
||||
if ( it == p.attributes.end() ) continue;
|
||||
|
||||
auto& accessor = model.accessors[it->second];
|
||||
auto& view = model.bufferViews[accessor.bufferView];
|
||||
|
||||
if ( attribute.name == "POSITION" ) {
|
||||
obj.vertices.resize(accessor.count);
|
||||
obj.primitive.instance.bounds.min = pod::Vector3f{ accessor.minValues[0], accessor.minValues[1], accessor.minValues[2] };
|
||||
obj.primitive.instance.bounds.max = pod::Vector3f{ accessor.maxValues[0], accessor.maxValues[1], accessor.maxValues[2] };
|
||||
|
||||
if ( !(graph.metadata["flags"]["INVERT"].as<bool>()) ){
|
||||
obj.primitive.instance.bounds.min.x = -obj.primitive.instance.bounds.min.x;
|
||||
obj.primitive.instance.bounds.max.x = -obj.primitive.instance.bounds.max.x;
|
||||
}
|
||||
}
|
||||
|
||||
switch ( accessor.componentType ) {
|
||||
case TINYGLTF_COMPONENT_TYPE_BYTE:
|
||||
case TINYGLTF_COMPONENT_TYPE_UNSIGNED_BYTE: {
|
||||
auto* buffer = reinterpret_cast<const uint8_t*>(&(model.buffers[view.buffer].data[accessor.byteOffset + view.byteOffset]));
|
||||
attribute.components = accessor.ByteStride(view) / sizeof(uint8_t);
|
||||
attribute.length = accessor.count * attribute.components;
|
||||
attribute.int8s.assign( &buffer[0], &buffer[attribute.length] );
|
||||
} break;
|
||||
case TINYGLTF_COMPONENT_TYPE_SHORT:
|
||||
case TINYGLTF_COMPONENT_TYPE_UNSIGNED_SHORT: {
|
||||
auto* buffer = reinterpret_cast<const uint16_t*>(&(model.buffers[view.buffer].data[accessor.byteOffset + view.byteOffset]));
|
||||
attribute.components = accessor.ByteStride(view) / sizeof(uint16_t);
|
||||
attribute.length = accessor.count * attribute.components;
|
||||
attribute.int16s.assign( &buffer[0], &buffer[attribute.length] );
|
||||
} break;
|
||||
case TINYGLTF_COMPONENT_TYPE_INT:
|
||||
case TINYGLTF_COMPONENT_TYPE_UNSIGNED_INT: {
|
||||
auto* buffer = reinterpret_cast<const uint32_t*>(&(model.buffers[view.buffer].data[accessor.byteOffset + view.byteOffset]));
|
||||
attribute.components = accessor.ByteStride(view) / sizeof(uint32_t);
|
||||
attribute.length = accessor.count * attribute.components;
|
||||
attribute.int32s.assign( &buffer[0], &buffer[attribute.length] );
|
||||
} break;
|
||||
case TINYGLTF_COMPONENT_TYPE_FLOAT: {
|
||||
auto* buffer = reinterpret_cast<const float*>(&(model.buffers[view.buffer].data[accessor.byteOffset + view.byteOffset]));
|
||||
attribute.components = accessor.ByteStride(view) / sizeof(float);
|
||||
attribute.length = accessor.count * attribute.components;
|
||||
attribute.floats.assign( &buffer[0], &buffer[attribute.length] );
|
||||
} break;
|
||||
default: UF_MSG_ERROR("Unsupported component type");
|
||||
}
|
||||
}
|
||||
|
||||
for ( size_t i = 0; i < obj.vertices.size(); ++i ) {
|
||||
#if 0
|
||||
#define ITERATE_ATTRIBUTE( name, member )\
|
||||
memcpy( &vertex.member[0], &attributes[name].buffer[i * attributes[name].components], attributes[name].stride );
|
||||
#else
|
||||
#define ITERATE_ATTRIBUTE( name, member, floatScale )\
|
||||
if ( !attributes[name].int8s.empty() ) { \
|
||||
for ( size_t j = 0; j < attributes[name].components; ++j )\
|
||||
vertex.member[j] = attributes[name].int8s[i * attributes[name].components + j];\
|
||||
} else if ( !attributes[name].int16s.empty() ) { \
|
||||
for ( size_t j = 0; j < attributes[name].components; ++j )\
|
||||
vertex.member[j] = attributes[name].int16s[i * attributes[name].components + j];\
|
||||
} else if ( !attributes[name].int32s.empty() ) { \
|
||||
for ( size_t j = 0; j < attributes[name].components; ++j )\
|
||||
vertex.member[j] = attributes[name].int32s[i * attributes[name].components + j];\
|
||||
} else if ( !attributes[name].floats.empty() ) { \
|
||||
for ( size_t j = 0; j < attributes[name].components; ++j )\
|
||||
vertex.member[j] = attributes[name].floats[i * attributes[name].components + j] * floatScale;\
|
||||
}
|
||||
#endif
|
||||
|
||||
auto& vertex = obj.vertices[i];
|
||||
ITERATE_ATTRIBUTE("POSITION", position, 1);
|
||||
ITERATE_ATTRIBUTE("TEXCOORD_0", uv, 1);
|
||||
ITERATE_ATTRIBUTE("COLOR_0", color, 255.0f);
|
||||
ITERATE_ATTRIBUTE("NORMAL", normal, 1);
|
||||
#if UF_GRAPH_PROCESS_PRIMITIVES_FULL
|
||||
ITERATE_ATTRIBUTE("TANGENT", tangent, 1);
|
||||
ITERATE_ATTRIBUTE("JOINTS_0", joints, 1);
|
||||
ITERATE_ATTRIBUTE("WEIGHTS_0", weights, 1);
|
||||
#endif
|
||||
|
||||
#undef ITERATE_ATTRIBUTE
|
||||
|
||||
// required due to reverse-Z projection matrix flipping the X axis as well
|
||||
// default is to proceed with this
|
||||
if ( !(graph.metadata["flags"]["INVERT"].as<bool>()) ){
|
||||
vertex.position.x = -vertex.position.x;
|
||||
vertex.normal.x = -vertex.normal.x;
|
||||
#if UF_GRAPH_PROCESS_PRIMITIVES_FULL
|
||||
vertex.tangent.x = -vertex.tangent.x;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if ( p.indices > -1 ) {
|
||||
auto& accessor = model.accessors[p.indices];
|
||||
auto& view = model.bufferViews[accessor.bufferView];
|
||||
auto& buffer = model.buffers[view.buffer];
|
||||
|
||||
obj.indices.reserve( static_cast<uint32_t>(accessor.count) );
|
||||
|
||||
#define COPY_INDICES() for (size_t index = 0; index < accessor.count; index++) obj.indices.emplace_back(buf[index]);
|
||||
|
||||
const void* pointer = &(buffer.data[accessor.byteOffset + view.byteOffset]);
|
||||
switch (accessor.componentType) {
|
||||
case TINYGLTF_PARAMETER_TYPE_UNSIGNED_INT: {
|
||||
auto* buf = static_cast<const uint32_t*>( pointer );
|
||||
COPY_INDICES()
|
||||
break;
|
||||
}
|
||||
case TINYGLTF_PARAMETER_TYPE_UNSIGNED_SHORT: {
|
||||
auto* buf = static_cast<const uint16_t*>( pointer );
|
||||
COPY_INDICES()
|
||||
break;
|
||||
}
|
||||
case TINYGLTF_PARAMETER_TYPE_UNSIGNED_BYTE: {
|
||||
auto* buf = static_cast<const uint8_t*>( pointer );
|
||||
COPY_INDICES()
|
||||
break;
|
||||
}
|
||||
}
|
||||
#undef COPY_INDICES
|
||||
}
|
||||
|
||||
obj.primitive.instance.materialID = p.material;
|
||||
obj.primitive.instance.primitiveID = objs.size() - 1;
|
||||
obj.primitive.instance.meshID = meshID;
|
||||
obj.primitive.instance.objectID = 0;
|
||||
|
||||
obj.primitive.drawCommand.indices = obj.indices.size();
|
||||
obj.primitive.drawCommand.instances = 1;
|
||||
obj.primitive.drawCommand.indexID = 0;
|
||||
obj.primitive.drawCommand.vertexID = 0;
|
||||
obj.primitive.drawCommand.instanceID = 0;
|
||||
obj.primitive.drawCommand.vertices = obj.vertices.size();
|
||||
}
|
||||
|
||||
if ( divisions > 1 ) {
|
||||
for ( auto& obj : objs ) {
|
||||
auto grid = uf::meshgrid::partition( obj.vertices, obj.indices, divisions );
|
||||
// uf::meshgrid::print( grid, obj.indices.size() );
|
||||
|
||||
for ( auto& node : grid.nodes ) {
|
||||
auto& slice = slices.emplace_back();
|
||||
slice.vertices.reserve( node.indices.size() );
|
||||
slice.indices.reserve( node.indices.size() );
|
||||
for ( auto& index : node.indices ) {
|
||||
slice.vertices.emplace_back( obj.vertices[index] );
|
||||
slice.indices.emplace_back( slice.indices.size() );
|
||||
}
|
||||
|
||||
slice.primitive.instance.materialID = obj.primitive.instance.materialID;
|
||||
slice.primitive.instance.primitiveID = slices.size() - 1;
|
||||
slice.primitive.instance.meshID = meshID;
|
||||
slice.primitive.instance.objectID = 0;
|
||||
|
||||
slice.primitive.drawCommand.indices = slice.indices.size();
|
||||
slice.primitive.drawCommand.instances = 1;
|
||||
slice.primitive.drawCommand.indexID = 0;
|
||||
slice.primitive.drawCommand.vertexID = 0;
|
||||
slice.primitive.drawCommand.instanceID = 0;
|
||||
slice.primitive.drawCommand.vertices = slice.vertices.size();
|
||||
}
|
||||
}
|
||||
|
||||
UF_MSG_DEBUG( "Draw commands: " << m.name << ": " << objs.size() << " -> " << slices.size() );
|
||||
} else {
|
||||
slices = std::move( objs );
|
||||
}
|
||||
|
||||
|
||||
size_t indexID = 0;
|
||||
size_t vertexID = 0;
|
||||
for ( auto& obj : slices ) {
|
||||
drawCommands.emplace_back(pod::DrawCommand{
|
||||
.indices = obj.indices.size(),
|
||||
.instances = 1,
|
||||
.indexID = indexID,
|
||||
.vertexID = vertexID,
|
||||
.instanceID = 0,
|
||||
|
||||
|
||||
.vertices = obj.vertices.size(),
|
||||
});
|
||||
|
||||
primitives.emplace_back( obj.primitive );
|
||||
|
||||
indexID += obj.indices.size();
|
||||
vertexID += obj.vertices.size();
|
||||
|
||||
mesh.insertVertices(obj.vertices);
|
||||
mesh.insertIndices(obj.indices);
|
||||
}
|
@ -104,6 +104,15 @@ void ext::opengl::Texture::loadFromImage(
|
||||
Device& device,
|
||||
enums::Format::type_t format
|
||||
) {
|
||||
switch ( format ) {
|
||||
case enums::Format::R8_SRGB:
|
||||
case enums::Format::R8G8_SRGB:
|
||||
case enums::Format::R8G8B8_SRGB:
|
||||
case enums::Format::R8G8B8A8_SRGB:
|
||||
srgb = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if ( image.getFormat() != 0 ) {
|
||||
internalFormat = image.getFormat();
|
||||
} else {
|
||||
@ -112,7 +121,7 @@ void ext::opengl::Texture::loadFromImage(
|
||||
case 1:
|
||||
switch ( image.getBpp() ) {
|
||||
case 8:
|
||||
format = enums::Format::R8_UNORM;
|
||||
format = srgb ? enums::Format::R8_SRGB : enums::Format::R8_UNORM;
|
||||
break;
|
||||
default:
|
||||
UF_EXCEPTION("OpenGL error: unsupported BPP of " << image.getBpp() );
|
||||
@ -123,7 +132,7 @@ void ext::opengl::Texture::loadFromImage(
|
||||
case 2:
|
||||
switch ( image.getBpp() ) {
|
||||
case 16:
|
||||
format = enums::Format::R8G8_UNORM;
|
||||
format = srgb ? enums::Format::R8G8_SRGB : enums::Format::R8G8_UNORM;
|
||||
break;
|
||||
default:
|
||||
UF_EXCEPTION("OpenGL error: unsupported BPP of " << image.getBpp() );
|
||||
@ -134,7 +143,7 @@ void ext::opengl::Texture::loadFromImage(
|
||||
case 3:
|
||||
switch ( image.getBpp() ) {
|
||||
case 24:
|
||||
format = enums::Format::R8G8B8_UNORM;
|
||||
format = srgb ? enums::Format::R8G8B8_SRGB : enums::Format::R8G8B8_UNORM;
|
||||
break;
|
||||
default:
|
||||
UF_EXCEPTION("OpenGL error: unsupported BPP of " << image.getBpp() );
|
||||
@ -148,7 +157,7 @@ void ext::opengl::Texture::loadFromImage(
|
||||
format = enums::Format::R4G4B4A4_UNORM_PACK16;
|
||||
break;
|
||||
case 32:
|
||||
format = enums::Format::R8G8B8A8_UNORM;
|
||||
format = srgb ? enums::Format::R8G8B8A8_SRGB : enums::Format::R8G8B8A8_UNORM;
|
||||
break;
|
||||
default:
|
||||
UF_EXCEPTION("OpenGL error: unsupported BPP of " << image.getBpp() );
|
||||
@ -267,19 +276,24 @@ void ext::opengl::Texture::update( void* data, size_t bufferSize, uint32_t layer
|
||||
GLenum type = GL_UNSIGNED_BYTE;
|
||||
switch ( this->format ) {
|
||||
case enums::Format::R8_UNORM:
|
||||
case enums::Format::R8_SRGB:
|
||||
format = GL_LUMINANCE;
|
||||
break;
|
||||
case enums::Format::R8G8_UNORM:
|
||||
case enums::Format::R8G8_SRGB:
|
||||
format = GL_LUMINANCE_ALPHA;
|
||||
break;
|
||||
case enums::Format::R8G8B8_UNORM:
|
||||
case enums::Format::R8G8B8_SRGB:
|
||||
format = GL_RGB;
|
||||
break;
|
||||
case enums::Format::R4G4B4A4_UNORM_PACK16:
|
||||
case enums::Format::R4G4B4A4_UNORM_PSRGB:
|
||||
format = GL_RGBA;
|
||||
type = GL_UNSIGNED_SHORT_4_4_4_4;
|
||||
break;
|
||||
case enums::Format::R8G8B8A8_UNORM:
|
||||
case enums::Format::R8G8B8A8_SRGB:
|
||||
format = GL_RGBA;
|
||||
break;
|
||||
}
|
||||
|
@ -12,7 +12,7 @@
|
||||
|
||||
#include <uf/utils/serialize/serializer.h>
|
||||
|
||||
#define UF_MSG_VALIDATION(X) if ( ext::vulkan::settings::validation ) UF_MSG("VULKAN", X);
|
||||
#define UF_MSG_VALIDATION(X) if ( ext::vulkan::settings::validation ) UF_MSG(X, " VULKAN ");
|
||||
|
||||
namespace {
|
||||
#if UF_USE_OPENVR
|
||||
@ -846,14 +846,23 @@ void ext::vulkan::Device::initialize() {
|
||||
uint32_t formatCount; vkGetPhysicalDeviceSurfaceFormatsKHR( this->physicalDevice, device.surface, &formatCount, nullptr);
|
||||
formats.resize( formatCount );
|
||||
vkGetPhysicalDeviceSurfaceFormatsKHR( this->physicalDevice, device.surface, &formatCount, formats.data() );
|
||||
|
||||
bool SRGB = true;
|
||||
auto TARGET_FORMAT = SRGB ? VK_FORMAT_B8G8R8A8_SRGB : VK_FORMAT_B8G8R8A8_UNORM;
|
||||
auto TARGET_COLORSPACE = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR;
|
||||
if ( ext::vulkan::settings::experimental::hdr ) {
|
||||
TARGET_FORMAT = VK_FORMAT_R32G32B32A32_SFLOAT;
|
||||
TARGET_COLORSPACE = VK_COLOR_SPACE_HDR10_ST2084_EXT;
|
||||
}
|
||||
|
||||
// If the surface format list only includes one entry with VK_FORMAT_UNDEFINED,
|
||||
// there is no preferered format, so we assume VK_FORMAT_B8G8R8A8_UNORM
|
||||
if ( (formatCount == 1) && (formats[0].format == VK_FORMAT_UNDEFINED) ) {
|
||||
ext::vulkan::settings::formats::color = VK_FORMAT_B8G8R8A8_UNORM;
|
||||
// there is no preferered format, so we assume VK_FORMAT_B8G8R8A8_SRGB
|
||||
if ( formatCount == 1 && formats[0].format == VK_FORMAT_UNDEFINED ) {
|
||||
ext::vulkan::settings::formats::color = TARGET_FORMAT;
|
||||
ext::vulkan::settings::formats::colorSpace = formats[0].colorSpace;
|
||||
} else {
|
||||
// iterate over the list of available surface format and
|
||||
// check for the presence of VK_FORMAT_B8G8R8A8_UNORM
|
||||
// check for the presence of VK_FORMAT_B8G8R8A8_SRGB
|
||||
bool found = false;
|
||||
for ( auto&& surfaceFormat : formats ) {
|
||||
if ( surfaceFormat.format == ext::vulkan::settings::formats::color ) {
|
||||
@ -865,14 +874,14 @@ void ext::vulkan::Device::initialize() {
|
||||
}
|
||||
if ( !found ) {
|
||||
for ( auto&& surfaceFormat : formats ) {
|
||||
if ( surfaceFormat.format == VK_FORMAT_B8G8R8A8_UNORM ) {
|
||||
if ( surfaceFormat.format == TARGET_FORMAT ) {
|
||||
ext::vulkan::settings::formats::color = surfaceFormat.format;
|
||||
ext::vulkan::settings::formats::colorSpace = surfaceFormat.colorSpace;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// in case VK_FORMAT_B8G8R8A8_UNORM is not available
|
||||
// in case VK_FORMAT_B8G8R8A8_SRGB is not available
|
||||
// select the first available color format
|
||||
if ( !found ) {
|
||||
ext::vulkan::settings::formats::color = formats[0].format;
|
||||
|
@ -9,6 +9,8 @@ ext::vulkan::Texture2D ext::vulkan::Texture2D::empty;
|
||||
ext::vulkan::Texture3D ext::vulkan::Texture3D::empty;
|
||||
ext::vulkan::TextureCube ext::vulkan::TextureCube::empty;
|
||||
|
||||
VkFormat ext::vulkan::Texture::DefaultFormat = VK_FORMAT_R8G8B8A8_UNORM;
|
||||
|
||||
uf::stl::vector<ext::vulkan::Sampler> ext::vulkan::Sampler::samplers;
|
||||
|
||||
ext::vulkan::Sampler ext::vulkan::Sampler::retrieve( const ext::vulkan::Sampler::Descriptor& info ) {
|
||||
@ -316,12 +318,34 @@ void ext::vulkan::Texture::loadFromImage(
|
||||
VkImageUsageFlags imageUsageFlags,
|
||||
VkImageLayout imageLayout
|
||||
) {
|
||||
/*
|
||||
switch ( format ) {
|
||||
case enums::Format::R8_SRGB:
|
||||
case enums::Format::R8G8_SRGB:
|
||||
case enums::Format::R8G8B8_SRGB:
|
||||
case enums::Format::R8G8B8A8_SRGB:
|
||||
srgb = true;
|
||||
break;
|
||||
}
|
||||
*/
|
||||
|
||||
switch ( image.getChannels() ) {
|
||||
// R
|
||||
case 1:
|
||||
switch ( image.getBpp() ) {
|
||||
case 8:
|
||||
format = VK_FORMAT_R8_UNORM;
|
||||
format = srgb ? VK_FORMAT_R8_SRGB : VK_FORMAT_R8_UNORM;
|
||||
break;
|
||||
default:
|
||||
UF_EXCEPTION("Vulkan error: unsupported BPP of " << image.getBpp() );
|
||||
break;
|
||||
}
|
||||
break;
|
||||
// RG
|
||||
case 2:
|
||||
switch ( image.getBpp() ) {
|
||||
case 16:
|
||||
format = srgb ? VK_FORMAT_R8G8_SRGB : VK_FORMAT_R8G8_UNORM;
|
||||
break;
|
||||
default:
|
||||
UF_EXCEPTION("Vulkan error: unsupported BPP of " << image.getBpp() );
|
||||
@ -332,7 +356,7 @@ void ext::vulkan::Texture::loadFromImage(
|
||||
case 3:
|
||||
switch ( image.getBpp() ) {
|
||||
case 24:
|
||||
format = VK_FORMAT_R8G8B8_UNORM;
|
||||
format = srgb ? VK_FORMAT_R8G8B8_SRGB : VK_FORMAT_R8G8B8_UNORM;
|
||||
break;
|
||||
default:
|
||||
UF_EXCEPTION("Vulkan error: unsupported BPP of " << image.getBpp() );
|
||||
@ -343,7 +367,7 @@ void ext::vulkan::Texture::loadFromImage(
|
||||
case 4:
|
||||
switch ( image.getBpp() ) {
|
||||
case 32:
|
||||
format = VK_FORMAT_R8G8B8A8_UNORM;
|
||||
format = srgb ? VK_FORMAT_R8G8B8A8_SRGB : VK_FORMAT_R8G8B8A8_UNORM;
|
||||
break;
|
||||
default:
|
||||
UF_EXCEPTION("Vulkan error: unsupported BPP of " << image.getBpp() );
|
||||
|
@ -111,10 +111,10 @@ pod::Vector2ui UF_API ext::xatlas::unwrap( pod::Graph& graph ) {
|
||||
}
|
||||
|
||||
::xatlas::ChartOptions chartOptions{};
|
||||
chartOptions.useInputMeshUvs = true;
|
||||
// chartOptions.useInputMeshUvs = true;
|
||||
|
||||
::xatlas::PackOptions packOptions{};
|
||||
packOptions.bruteForce = false;
|
||||
packOptions.bruteForce = true;
|
||||
// packOptions.resolution = resolution;
|
||||
// packOptions.texelsPerUnit = 64.0f;
|
||||
packOptions.blockAlign = true;
|
||||
|
@ -5,20 +5,116 @@ namespace {
|
||||
// return ( min.x <= p.x && p.x <= max.x && min.y <= p.y && p.y <= max.y && min.z <= p.z && p.z <= max.z );
|
||||
return (p.x <= max.x && p.x >= min.x) && (p.y <= max.y && p.y >= min.y) && (p.z <= max.z && p.z >= min.z);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
uf::stl::vector<uf::meshgrid::Node> UF_API uf::meshgrid::partition( uf::Mesh& mesh, int divisions ) {
|
||||
struct {
|
||||
pod::Vector3f min = { std::numeric_limits<float>::max(), std::numeric_limits<float>::max(), std::numeric_limits<float>::max() };
|
||||
pod::Vector3f max = { -std::numeric_limits<float>::max(), -std::numeric_limits<float>::max(), -std::numeric_limits<float>::max() };
|
||||
void UF_API uf::meshgrid::print( const uf::meshgrid::Grid& grid, size_t indices ) {
|
||||
UF_MSG_DEBUG( "== == == ==");
|
||||
float total = 0.0f;
|
||||
for ( auto& node : grid.nodes ) {
|
||||
float percentage = 100.0f * node.indices.size() / indices;
|
||||
total += percentage;
|
||||
UF_MSG_DEBUG(
|
||||
"[" << node.id.x << "," << node.id.y << "," << node.id.z << "] "
|
||||
"[" << percentage << "%|" << total << "%] "
|
||||
"Min: " << uf::vector::toString( node.extents.min ) << " | "
|
||||
"Max: " << uf::vector::toString( node.extents.max )
|
||||
);
|
||||
}
|
||||
|
||||
pod::Vector3f center = {};
|
||||
pod::Vector3f corner = {};
|
||||
UF_MSG_DEBUG( "== == == ==");
|
||||
UF_MSG_DEBUG( "Min: " << uf::vector::toString( grid.extents.min ) );
|
||||
UF_MSG_DEBUG( "Max: " << uf::vector::toString( grid.extents.max ) );
|
||||
UF_MSG_DEBUG( "Center: " << uf::vector::toString( grid.extents.center ) );
|
||||
UF_MSG_DEBUG( "Corner: " << uf::vector::toString( grid.extents.corner ) );
|
||||
UF_MSG_DEBUG( "Size: " << uf::vector::toString( grid.extents.size ) );
|
||||
UF_MSG_DEBUG( "Piece: " << uf::vector::toString( grid.extents.piece ) );
|
||||
UF_MSG_DEBUG( "== == == ==");
|
||||
}
|
||||
|
||||
pod::Vector3f size = {};
|
||||
pod::Vector3f piece = {};
|
||||
} extents;
|
||||
uf::meshgrid::Grid uf::meshgrid::generate( int divisions,
|
||||
void* pPointer, size_t pStride, size_t pFirst, size_t pCount,
|
||||
void* iPointer, size_t iStride, size_t iFirst, size_t iCount
|
||||
) {
|
||||
uf::meshgrid::Grid grid;
|
||||
grid.divisions = divisions;
|
||||
|
||||
// calculate extents
|
||||
for ( size_t i = 0; i < pCount; ++i ) {
|
||||
pod::Vector3f& position = *(pod::Vector3f*) (pPointer + pStride * (pFirst + i));
|
||||
grid.extents.min = uf::vector::min( position, grid.extents.min );
|
||||
grid.extents.max = uf::vector::max( position, grid.extents.max );
|
||||
}
|
||||
constexpr float epsilon = std::numeric_limits<float>::epsilon();
|
||||
grid.extents.min -= pod::Vector3f{ epsilon, epsilon, epsilon }; // dilate
|
||||
grid.extents.max += pod::Vector3f{ epsilon, epsilon, epsilon }; // dilate
|
||||
grid.extents.size = uf::vector::abs(grid.extents.max - grid.extents.min);
|
||||
grid.extents.piece = grid.extents.size / divisions;
|
||||
|
||||
grid.extents.center = (grid.extents.max + grid.extents.min) * 0.5f;
|
||||
grid.extents.corner = grid.extents.size * 0.5f;
|
||||
|
||||
// initialize
|
||||
grid.nodes.reserve( divisions * divisions * divisions );
|
||||
for ( int z = 0; z < divisions; ++z ) {
|
||||
for ( int y = 0; y < divisions; ++y ) {
|
||||
for ( int x = 0; x < divisions; ++x ) {
|
||||
grid.nodes.emplace_back(uf::meshgrid::Node{
|
||||
.extents = {
|
||||
.min = grid.extents.min + grid.extents.piece * pod::Vector3f{ x, y, z },
|
||||
.max = grid.extents.min + grid.extents.piece * pod::Vector3f{ x+1, y+1, z+1 },
|
||||
},
|
||||
.id = pod::Vector3ui{ x, y, z },
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// iterate
|
||||
for ( size_t i = 0; i < iCount; i+=3 ) {
|
||||
size_t indexA = 0;
|
||||
size_t indexB = 0;
|
||||
size_t indexC = 0;
|
||||
|
||||
uint8_t* indexPointerA = (uint8_t*) (iPointer + iStride * (iFirst + i + 0));
|
||||
uint8_t* indexPointerB = (uint8_t*) (iPointer + iStride * (iFirst + i + 1));
|
||||
uint8_t* indexPointerC = (uint8_t*) (iPointer + iStride * (iFirst + i + 2));
|
||||
|
||||
switch ( iStride ) {
|
||||
case sizeof(uint8_t): {
|
||||
indexA = *( uint8_t*) indexPointerA;
|
||||
indexB = *( uint8_t*) indexPointerB;
|
||||
indexC = *( uint8_t*) indexPointerC;
|
||||
} break;
|
||||
case sizeof(uint16_t): {
|
||||
indexA = *(uint16_t*) indexPointerA;
|
||||
indexB = *(uint16_t*) indexPointerB;
|
||||
indexC = *(uint16_t*) indexPointerC;
|
||||
} break;
|
||||
case sizeof(uint32_t): {
|
||||
indexA = *(uint32_t*) indexPointerA;
|
||||
indexB = *(uint32_t*) indexPointerB;
|
||||
indexC = *(uint32_t*) indexPointerC;
|
||||
} break;
|
||||
}
|
||||
|
||||
pod::Vector3f& positionA = *(pod::Vector3f*) (pPointer + pStride * (pFirst + indexA));
|
||||
pod::Vector3f& positionB = *(pod::Vector3f*) (pPointer + pStride * (pFirst + indexB));
|
||||
pod::Vector3f& positionC = *(pod::Vector3f*) (pPointer + pStride * (pFirst + indexC));
|
||||
|
||||
for ( auto& node : grid.nodes ) {
|
||||
// if ( isInside( positionA, node.extents.min, node.extents.max ) || isInside( positionB, node.extents.min, node.extents.max ) || isInside( positionC, node.extents.min, node.extents.max ) ) {
|
||||
if ( isInside( (positionA + positionB + positionC) / 3.0f, node.extents.min, node.extents.max ) ) {
|
||||
node.indices.emplace_back( indexA );
|
||||
node.indices.emplace_back( indexB );
|
||||
node.indices.emplace_back( indexC );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return grid;
|
||||
}
|
||||
uf::meshgrid::Grid UF_API uf::meshgrid::partition( uf::Mesh& mesh, int divisions ) {
|
||||
uf::Mesh::Input vertexInput = mesh.vertex;
|
||||
uf::Mesh::Input indexInput = mesh.index;
|
||||
|
||||
@ -28,30 +124,34 @@ uf::stl::vector<uf::meshgrid::Node> UF_API uf::meshgrid::partition( uf::Mesh& me
|
||||
for ( auto& attribute : mesh.vertex.attributes ) if ( attribute.descriptor.name == "position" ) { vertexAttribute = attribute; break; }
|
||||
UF_ASSERT( vertexAttribute.descriptor.name == "position" );
|
||||
|
||||
return generate( divisions,
|
||||
vertexAttribute.pointer + vertexAttribute.offset, vertexAttribute.stride, vertexInput.first, mesh.vertex.count,
|
||||
indexAttribute.pointer + indexAttribute.offset, indexAttribute.stride, indexInput.first, mesh.index.count
|
||||
);
|
||||
/*
|
||||
for ( size_t i = 0; i < mesh.vertex.count; ++i ) {
|
||||
pod::Vector3f& position = *(pod::Vector3f*) (vertexAttribute.pointer + vertexAttribute.stride * (vertexInput.first + i));
|
||||
extents.min = uf::vector::min( position, extents.min );
|
||||
extents.max = uf::vector::max( position, extents.max );
|
||||
grid.extents.min = uf::vector::min( position, grid.extents.min );
|
||||
grid.extents.max = uf::vector::max( position, grid.extents.max );
|
||||
}
|
||||
constexpr float epsilon = std::numeric_limits<float>::epsilon();
|
||||
extents.min -= pod::Vector3f{ epsilon, epsilon, epsilon }; // dilate
|
||||
extents.max += pod::Vector3f{ epsilon, epsilon, epsilon }; // dilate
|
||||
extents.size = uf::vector::abs(extents.max - extents.min);
|
||||
extents.piece = extents.size / divisions;
|
||||
grid.extents.min -= pod::Vector3f{ epsilon, epsilon, epsilon }; // dilate
|
||||
grid.extents.max += pod::Vector3f{ epsilon, epsilon, epsilon }; // dilate
|
||||
grid.extents.size = uf::vector::abs(grid.extents.max - grid.extents.min);
|
||||
grid.extents.piece = grid.extents.size / divisions;
|
||||
|
||||
extents.center = (extents.max + extents.min) * 0.5f;
|
||||
extents.corner = extents.size * 0.5f;
|
||||
grid.extents.center = (grid.extents.max + grid.extents.min) * 0.5f;
|
||||
grid.extents.corner = grid.extents.size * 0.5f;
|
||||
|
||||
uf::stl::vector<uf::meshgrid::Node> nodes;
|
||||
nodes.reserve( divisions * divisions * divisions );
|
||||
grid.nodes.reserve( divisions * divisions * divisions );
|
||||
|
||||
for ( int z = 0; z < divisions; ++z ) {
|
||||
for ( int y = 0; y < divisions; ++y ) {
|
||||
for ( int x = 0; x < divisions; ++x ) {
|
||||
nodes.emplace_back(uf::meshgrid::Node{
|
||||
grid.nodes.emplace_back(uf::meshgrid::Node{
|
||||
.extents = {
|
||||
.min = extents.min + extents.piece * pod::Vector3f{ x, y, z },
|
||||
.max = extents.min + extents.piece * pod::Vector3f{ x+1, y+1, z+1 },
|
||||
.min = grid.extents.min + grid.extents.piece * pod::Vector3f{ x, y, z },
|
||||
.max = grid.extents.min + grid.extents.piece * pod::Vector3f{ x+1, y+1, z+1 },
|
||||
},
|
||||
.id = pod::Vector3ui{ x, y, z },
|
||||
});
|
||||
@ -90,7 +190,7 @@ uf::stl::vector<uf::meshgrid::Node> UF_API uf::meshgrid::partition( uf::Mesh& me
|
||||
pod::Vector3f& positionB = *(pod::Vector3f*) (vertexAttribute.pointer + vertexAttribute.stride * (vertexInput.first + indexB));
|
||||
pod::Vector3f& positionC = *(pod::Vector3f*) (vertexAttribute.pointer + vertexAttribute.stride * (vertexInput.first + indexC));
|
||||
|
||||
for ( auto& node : nodes ) {
|
||||
for ( auto& node : grid.nodes ) {
|
||||
// if ( isInside( positionA, node.extents.min, node.extents.max ) || isInside( positionB, node.extents.min, node.extents.max ) || isInside( positionC, node.extents.min, node.extents.max ) ) {
|
||||
if ( isInside( (positionA + positionB + positionC) / 3.0f, node.extents.min, node.extents.max ) ) {
|
||||
node.indices.emplace_back( indexA );
|
||||
@ -99,29 +199,8 @@ uf::stl::vector<uf::meshgrid::Node> UF_API uf::meshgrid::partition( uf::Mesh& me
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
UF_MSG_DEBUG( "== == == ==");
|
||||
float total = 0.0f;
|
||||
for ( auto& node : nodes ) {
|
||||
float percentage = 100.8f * node.indices.size() / indexInput.count;
|
||||
total += percentage;
|
||||
UF_MSG_DEBUG(
|
||||
"[" << node.id.x << "," << node.id.y << "," << node.id.z << "] "
|
||||
"[" << percentage << "%|" << total << "%] "
|
||||
"Min: " << uf::vector::toString( node.extents.min ) << " | "
|
||||
"Max: " << uf::vector::toString( node.extents.max )
|
||||
);
|
||||
}
|
||||
UF_MSG_DEBUG( "== == == ==");
|
||||
UF_MSG_DEBUG( "Min: " << uf::vector::toString( extents.min ) );
|
||||
UF_MSG_DEBUG( "Max: " << uf::vector::toString( extents.max ) );
|
||||
UF_MSG_DEBUG( "Center: " << uf::vector::toString( extents.center ) );
|
||||
UF_MSG_DEBUG( "Corner: " << uf::vector::toString( extents.corner ) );
|
||||
UF_MSG_DEBUG( "Size: " << uf::vector::toString( extents.size ) );
|
||||
UF_MSG_DEBUG( "Piece: " << uf::vector::toString( extents.piece ) );
|
||||
UF_MSG_DEBUG( "== == == ==");
|
||||
|
||||
return nodes;
|
||||
return grid;
|
||||
*/
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
Loading…
Reference in New Issue
Block a user