remove the weird redundancy of having drawcommands + instances + primitives (which store draw commands and instances) (although i should probably do the opposite to not tie instances to draw commands)
This commit is contained in:
parent
9f2f51c644
commit
a099c562a2
@ -126,7 +126,7 @@ void main() {
|
|||||||
const Instance instance = instances[instanceID];
|
const Instance instance = instances[instanceID];
|
||||||
const Material material = materials[instance.materialID];
|
const Material material = materials[instance.materialID];
|
||||||
|
|
||||||
const uint mapID = instance.auxID;
|
const uint mapID = instance.lightmapID; // was auxID
|
||||||
|
|
||||||
vec4 A = material.colorBase;
|
vec4 A = material.colorBase;
|
||||||
surface.material.metallic = material.factorMetallic;
|
surface.material.metallic = material.factorMetallic;
|
||||||
|
|||||||
@ -1 +1 @@
|
|||||||
vulkan
|
opengl
|
||||||
@ -28,9 +28,7 @@ namespace pod {
|
|||||||
uf::stl::vector<pod::Node> nodes; //
|
uf::stl::vector<pod::Node> nodes; //
|
||||||
|
|
||||||
// Render information
|
// Render information
|
||||||
uf::stl::vector<uf::stl::string> instances; //
|
|
||||||
uf::stl::vector<uf::stl::string> primitives; //
|
uf::stl::vector<uf::stl::string> primitives; //
|
||||||
uf::stl::vector<uf::stl::string> drawCommands; //
|
|
||||||
uf::stl::vector<uf::stl::string> meshes; //
|
uf::stl::vector<uf::stl::string> meshes; //
|
||||||
|
|
||||||
uf::stl::vector<uf::stl::string> images; //
|
uf::stl::vector<uf::stl::string> images; //
|
||||||
@ -49,9 +47,6 @@ namespace pod {
|
|||||||
// Animation queue
|
// Animation queue
|
||||||
uf::stl::queue<uf::stl::string> sequence;
|
uf::stl::queue<uf::stl::string> sequence;
|
||||||
|
|
||||||
// Streaming stuff
|
|
||||||
uf::stl::unordered_map<uf::stl::string, uf::stl::string> buffer_paths; // probably will go unused since cramming it all in here is pain
|
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
struct {
|
struct {
|
||||||
bool loop = true;
|
bool loop = true;
|
||||||
@ -84,10 +79,8 @@ namespace pod {
|
|||||||
|
|
||||||
// Local storage, used for save/load
|
// Local storage, used for save/load
|
||||||
struct Storage {
|
struct Storage {
|
||||||
uf::stl::KeyMap<pod::Instance> instances;
|
|
||||||
uf::stl::KeyMap<pod::Instance::Addresses> instanceAddresses;
|
uf::stl::KeyMap<pod::Instance::Addresses> instanceAddresses;
|
||||||
uf::stl::KeyMap<uf::stl::vector<pod::Primitive>> primitives;
|
uf::stl::KeyMap<uf::stl::vector<pod::Primitive>> primitives;
|
||||||
uf::stl::KeyMap<uf::stl::vector<pod::DrawCommand>> drawCommands;
|
|
||||||
uf::stl::KeyMap<uf::Mesh> meshes;
|
uf::stl::KeyMap<uf::Mesh> meshes;
|
||||||
|
|
||||||
uf::stl::KeyMap<uf::Image> images;
|
uf::stl::KeyMap<uf::Image> images;
|
||||||
@ -141,13 +134,12 @@ namespace uf {
|
|||||||
void UF_API initializeGraphics( pod::Graph& graph, uf::Object& entity, uf::Mesh& mesh );
|
void UF_API initializeGraphics( pod::Graph& graph, uf::Object& entity, uf::Mesh& mesh );
|
||||||
void UF_API process( pod::Graph& graph );
|
void UF_API process( pod::Graph& graph );
|
||||||
void UF_API process( pod::Graph& graph, int32_t, uf::Object& parent );
|
void UF_API process( pod::Graph& graph, int32_t, uf::Object& parent );
|
||||||
void UF_API cleanup( pod::Graph& graph );
|
|
||||||
void UF_API reload( pod::Graph& );
|
void UF_API reload( pod::Graph& );
|
||||||
void UF_API initialize( pod::Graph& graph );
|
void UF_API initialize( pod::Graph& graph );
|
||||||
|
|
||||||
void UF_API update( pod::Graph& );
|
void UF_API update( pod::Graph& );
|
||||||
void UF_API update( pod::Graph&, float );
|
void UF_API update( pod::Graph&, float );
|
||||||
|
|
||||||
void UF_API updateAnimation( pod::Graph&, float );
|
void UF_API updateAnimation( pod::Graph&, float );
|
||||||
void UF_API updateAnimation( pod::Graph&, pod::Node& );
|
void UF_API updateAnimation( pod::Graph&, pod::Node& );
|
||||||
void UF_API override( pod::Graph& );
|
void UF_API override( pod::Graph& );
|
||||||
|
|||||||
@ -59,35 +59,42 @@ namespace ext {
|
|||||||
}
|
}
|
||||||
|
|
||||||
namespace pod {
|
namespace pod {
|
||||||
|
// stores information for a draw call
|
||||||
|
// used for GPU-driven indirection
|
||||||
|
// to-do: probably repurpose auxID and materialIDs
|
||||||
struct UF_API DrawCommand {
|
struct UF_API DrawCommand {
|
||||||
alignas(4) uint32_t indices = 0; // triangle count
|
alignas(4) uint32_t indices = 0; // triangle count
|
||||||
alignas(4) uint32_t instances = 0; // instance count
|
alignas(4) uint32_t instances = 0; // instance count
|
||||||
alignas(4) uint32_t indexID = 0; // starting triangle position
|
alignas(4) uint32_t indexID = 0; // starting triangle position
|
||||||
alignas(4) int32_t vertexID = 0; // starting vertex position
|
alignas(4) int32_t vertexID = 0; // starting vertex position
|
||||||
alignas(4) uint32_t instanceID = 0; // starting instance position
|
alignas(4) uint32_t instanceID = 0; // starting instance position
|
||||||
// extra data
|
// extra data for padding
|
||||||
alignas(4) uint32_t auxID = 0; //
|
alignas(4) uint32_t auxID = 0; // used for storing which grid this belongs to when slicing, otherwise unused
|
||||||
alignas(4) uint32_t materialID = 0; //
|
alignas(4) uint32_t materialID = 0; // unused
|
||||||
alignas(4) uint32_t vertices = 0; //
|
alignas(4) uint32_t vertices = 0; // stores vertex count, should be unused
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// stores information about how to transform a draw call
|
||||||
|
// to-do: clean up this mess
|
||||||
|
struct UF_API Instance {
|
||||||
|
// these could easily be tied to objectID
|
||||||
|
pod::Matrix4f model; // current model matrix
|
||||||
|
pod::Matrix4f previous; // previous model matrix, used for the "motion" output
|
||||||
|
|
||||||
struct UF_API Instance {
|
pod::Vector4f color = {1,1,1,1}; // additional color information
|
||||||
pod::Matrix4f model;
|
|
||||||
pod::Matrix4f previous;
|
|
||||||
|
|
||||||
pod::Vector4f color = {1,1,1,1};
|
alignas(4) uint32_t materialID = 0; // index for material information
|
||||||
|
alignas(4) uint32_t primitiveID = 0; // index to reference the primitive(?)
|
||||||
|
alignas(4) uint32_t meshID = 0; // unused
|
||||||
|
alignas(4) uint32_t objectID = 0; // unused
|
||||||
|
|
||||||
alignas(4) uint32_t materialID = 0;
|
alignas(4) int32_t jointID = -1; // offset for skins(?)
|
||||||
alignas(4) uint32_t primitiveID = 0;
|
alignas(4) int32_t lightmapID = -1; // index for lightmap to use
|
||||||
alignas(4) uint32_t meshID = 0;
|
alignas(4) uint32_t imageID = 0; // unused?
|
||||||
alignas(4) uint32_t objectID = 0;
|
alignas(4) uint32_t auxID = 0; // also the lightmap ID?
|
||||||
|
|
||||||
alignas(4) int32_t jointID = -1;
|
|
||||||
alignas(4) int32_t lightmapID = -1;
|
|
||||||
alignas(4) uint32_t imageID = 0;
|
|
||||||
alignas(4) uint32_t auxID = 0;
|
|
||||||
|
|
||||||
|
// AABB for this primitive
|
||||||
|
// should be for the specific draw call itself, rather than the mesh(let) entirely
|
||||||
struct Bounds {
|
struct Bounds {
|
||||||
pod::Vector3f min = { std::numeric_limits<float>::max(), std::numeric_limits<float>::max(), std::numeric_limits<float>::max() };
|
pod::Vector3f min = { std::numeric_limits<float>::max(), std::numeric_limits<float>::max(), std::numeric_limits<float>::max() };
|
||||||
alignas(4) float padding1 = 0;
|
alignas(4) float padding1 = 0;
|
||||||
@ -95,6 +102,7 @@ namespace pod {
|
|||||||
alignas(4) float padding2 = 0;
|
alignas(4) float padding2 = 0;
|
||||||
} bounds;
|
} bounds;
|
||||||
|
|
||||||
|
// stores "pointers" on the GPU side for buffer locations, used for RT / recalculating barycentrics
|
||||||
struct UF_API Addresses {
|
struct UF_API Addresses {
|
||||||
alignas(8) uint64_t vertex{};
|
alignas(8) uint64_t vertex{};
|
||||||
alignas(8) uint64_t index{};
|
alignas(8) uint64_t index{};
|
||||||
|
|||||||
@ -263,7 +263,7 @@ uf::stl::string uf::asset::load( uf::asset::Payload& payload ) {
|
|||||||
if ( asset.metadata["debug"]["print"]["stats"].as<bool>() ) UF_MSG_INFO("{}", uf::graph::stats( asset ));
|
if ( asset.metadata["debug"]["print"]["stats"].as<bool>() ) UF_MSG_INFO("{}", uf::graph::stats( asset ));
|
||||||
if ( asset.metadata["debug"]["print"]["tree"].as<bool>() ) UF_MSG_INFO("{}", uf::graph::print( asset ));
|
if ( asset.metadata["debug"]["print"]["tree"].as<bool>() ) UF_MSG_INFO("{}", uf::graph::print( asset ));
|
||||||
#endif
|
#endif
|
||||||
if ( !asset.metadata["debug"]["no cleanup"].as<bool>() ) uf::graph::cleanup( asset );
|
//if ( !asset.metadata["debug"]["no cleanup"].as<bool>() ) uf::graph::cleanup( asset );
|
||||||
} break;
|
} break;
|
||||||
default: {
|
default: {
|
||||||
UF_MSG_ERROR("Failed to parse {}: unimplemented extension: {}", filename, extension );
|
UF_MSG_ERROR("Failed to parse {}: unimplemented extension: {}", filename, extension );
|
||||||
|
|||||||
@ -90,7 +90,7 @@ void ext::BakingBehavior::initialize( uf::Object& self ) {
|
|||||||
for ( auto& texture : storage.shadow2Ds ) textures2D.emplace_back().aliasTexture(texture);
|
for ( auto& texture : storage.shadow2Ds ) textures2D.emplace_back().aliasTexture(texture);
|
||||||
for ( auto& texture : storage.shadowCubes ) texturesCube.emplace_back().aliasTexture(texture);
|
for ( auto& texture : storage.shadowCubes ) texturesCube.emplace_back().aliasTexture(texture);
|
||||||
|
|
||||||
::totalIDs = storage.instances.keys.size();
|
::totalIDs = storage.primitives.keys.size();
|
||||||
|
|
||||||
metadata.buffers.baked.fromBuffers( NULL, 0, uf::renderer::enums::Format::R8G8B8A8_UNORM, metadata.size.x, metadata.size.y, metadata.max.layers, 1, VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT, VK_IMAGE_LAYOUT_GENERAL );
|
metadata.buffers.baked.fromBuffers( NULL, 0, uf::renderer::enums::Format::R8G8B8A8_UNORM, metadata.size.x, metadata.size.y, metadata.max.layers, 1, VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT, VK_IMAGE_LAYOUT_GENERAL );
|
||||||
|
|
||||||
|
|||||||
@ -95,7 +95,12 @@ void ext::RayTraceSceneBehavior::tick( uf::Object& self ) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static uf::stl::vector<pod::Instance> previousInstances;
|
static uf::stl::vector<pod::Instance> previousInstances;
|
||||||
uf::stl::vector<pod::Instance> instances = storage.instances.flatten();
|
uf::stl::vector<pod::Instance> instances; instances.reserve(storage.primitives.map.size());
|
||||||
|
for ( auto& key : storage.primitives.keys ) {
|
||||||
|
for ( auto& primitive : storage.primitives.map[key] ) {
|
||||||
|
instances.emplace_back( primitive.instance );
|
||||||
|
}
|
||||||
|
}
|
||||||
if ( instances.empty() ) return;
|
if ( instances.empty() ) return;
|
||||||
|
|
||||||
static uf::stl::vector<uf::Graphic*> previousGraphics;
|
static uf::stl::vector<uf::Graphic*> previousGraphics;
|
||||||
|
|||||||
@ -17,9 +17,6 @@ namespace {
|
|||||||
|
|
||||||
// grab relevant IDs
|
// grab relevant IDs
|
||||||
size_t nodeID = graph.nodes.size();
|
size_t nodeID = graph.nodes.size();
|
||||||
size_t instanceID = storage.instances.keys.size(); // graph.instances.size();
|
|
||||||
size_t primitiveID = graph.primitives.size();
|
|
||||||
size_t drawCommandID = graph.drawCommands.size();
|
|
||||||
size_t meshID = graph.meshes.size();
|
size_t meshID = graph.meshes.size();
|
||||||
size_t objectID = storage.entities.keys.size();
|
size_t objectID = storage.entities.keys.size();
|
||||||
|
|
||||||
@ -55,50 +52,62 @@ namespace {
|
|||||||
}
|
}
|
||||||
// graphic.material.textures.clear();
|
// graphic.material.textures.clear();
|
||||||
|
|
||||||
|
// to-do: import all draw commands from indirect buffer
|
||||||
|
#if 0
|
||||||
if ( object.hasComponent<uf::Mesh>() ) {
|
if ( object.hasComponent<uf::Mesh>() ) {
|
||||||
node.mesh = meshID;
|
node.mesh = meshID;
|
||||||
// import
|
|
||||||
auto& instance = storage.instances[graph.instances.emplace_back(keyName)];
|
|
||||||
auto& drawCommands = storage.drawCommands[graph.drawCommands.emplace_back(keyName)];
|
|
||||||
auto& drawCommand = drawCommands.emplace_back();
|
|
||||||
auto& primitives = storage.primitives[graph.primitives.emplace_back(keyName)];
|
auto& primitives = storage.primitives[graph.primitives.emplace_back(keyName)];
|
||||||
auto& primitive = primitives.emplace_back();
|
|
||||||
auto& mesh = (storage.meshes[graph.meshes.emplace_back(keyName)] = object.getComponent<uf::Mesh>());
|
auto& mesh = (storage.meshes[graph.meshes.emplace_back(keyName)] = object.getComponent<uf::Mesh>());
|
||||||
|
|
||||||
pod::Vector3f boundsMin = { std::numeric_limits<float>::max(), std::numeric_limits<float>::max(), std::numeric_limits<float>::max() };
|
auto& attribute = mesh.indirect.attributes.front();
|
||||||
pod::Vector3f boundsMax = { -std::numeric_limits<float>::max(), -std::numeric_limits<float>::max(), -std::numeric_limits<float>::max() };
|
auto& buffer = mesh.buffers[mesh.isInterleaved(mesh.indirect.interleaved) ? mesh.indirect.interleaved : attribute.buffer];
|
||||||
|
pod::DrawCommand* drawCommands = (pod::DrawCommand*) buffer.data();
|
||||||
|
|
||||||
for ( auto& attribute : mesh.vertex.attributes ) {
|
// import
|
||||||
if ( attribute.descriptor.name != "position" ) continue;
|
for ( auto drawCommandID = 0; drawCommandID < mesh.indirect.count; ++drawCommandID ) {
|
||||||
for ( size_t i = 0; i < mesh.vertex.count; ++i ) {
|
size_t primitiveID = primitives.size();
|
||||||
auto& position = *(const pod::Vector3f*) ( attribute.pointer + attribute.stride * (mesh.vertex.first + i));
|
size_t instanceID = primitiveID;
|
||||||
boundsMin = uf::vector::min( boundsMin, position );
|
|
||||||
boundsMax = uf::vector::max( boundsMax, position );
|
auto& primitive = primitives.emplace_back();
|
||||||
|
auto& drawCommand = primitive.drawCommand;
|
||||||
|
auto& instance = primitive.instance;
|
||||||
|
|
||||||
|
pod::Vector3f boundsMin = { std::numeric_limits<float>::max(), std::numeric_limits<float>::max(), std::numeric_limits<float>::max() };
|
||||||
|
pod::Vector3f boundsMax = { -std::numeric_limits<float>::max(), -std::numeric_limits<float>::max(), -std::numeric_limits<float>::max() };
|
||||||
|
|
||||||
|
for ( auto& attribute : mesh.vertex.attributes ) {
|
||||||
|
if ( attribute.descriptor.name != "position" ) continue;
|
||||||
|
for ( size_t i = 0; i < mesh.vertex.count; ++i ) {
|
||||||
|
auto& position = *(const pod::Vector3f*) ( attribute.pointer + attribute.stride * (mesh.vertex.first + i));
|
||||||
|
boundsMin = uf::vector::min( boundsMin, position );
|
||||||
|
boundsMax = uf::vector::max( boundsMax, position );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
instance.materialID = materialID;
|
||||||
|
instance.primitiveID = primitiveID;
|
||||||
|
instance.meshID = meshID;
|
||||||
|
instance.objectID = objectID;
|
||||||
|
instance.bounds.min = boundsMin;
|
||||||
|
instance.bounds.max = boundsMax;
|
||||||
|
|
||||||
|
drawCommand.indices = mesh.index.count;
|
||||||
|
drawCommand.instances = 1;
|
||||||
|
drawCommand.indexID = 0;
|
||||||
|
drawCommand.vertexID = 0;
|
||||||
|
drawCommand.instanceID = instanceID;
|
||||||
|
drawCommand.vertices = mesh.vertex.count;
|
||||||
|
|
||||||
|
primitive.instance = instance;
|
||||||
|
primitive.drawCommand = drawCommand;
|
||||||
}
|
}
|
||||||
|
|
||||||
instance.materialID = materialID;
|
//mesh.insertIndirects(drawCommands); // to-do
|
||||||
instance.primitiveID = primitiveID;
|
|
||||||
instance.meshID = meshID;
|
|
||||||
instance.objectID = objectID;
|
|
||||||
instance.bounds.min = boundsMin;
|
|
||||||
instance.bounds.max = boundsMax;
|
|
||||||
|
|
||||||
drawCommand.indices = mesh.index.count;
|
|
||||||
drawCommand.instances = 1;
|
|
||||||
drawCommand.indexID = 0;
|
|
||||||
drawCommand.vertexID = 0;
|
|
||||||
drawCommand.instanceID = instanceID;
|
|
||||||
drawCommand.vertices = mesh.vertex.count;
|
|
||||||
|
|
||||||
primitive.instance = instance;
|
|
||||||
primitive.drawCommand = drawCommand;
|
|
||||||
|
|
||||||
mesh.insertIndirects(drawCommands);
|
|
||||||
mesh.updateDescriptor();
|
mesh.updateDescriptor();
|
||||||
|
|
||||||
uf::graph::initializeGraphics( graph, object, mesh );
|
uf::graph::initializeGraphics( graph, object, mesh );
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -137,19 +146,7 @@ pod::Graph& uf::graph::convert( uf::Object& object, bool process ) {
|
|||||||
if ( !(0 <= texture.index && texture.index < graph.images.size()) ) continue;
|
if ( !(0 <= texture.index && texture.index < graph.images.size()) ) continue;
|
||||||
|
|
||||||
auto& needle = graph.images[texture.index];
|
auto& needle = graph.images[texture.index];
|
||||||
#if 1
|
|
||||||
texture.index = indices[needle];
|
texture.index = indices[needle];
|
||||||
#elif 1
|
|
||||||
for ( size_t i = 0; i < keys.size(); ++i ) {
|
|
||||||
if ( keys[i] != needle ) continue;
|
|
||||||
texture.index = i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
auto it = std::find( keys.begin(), keys.end(), needle );
|
|
||||||
UF_ASSERT( it != keys.end() );
|
|
||||||
texture.index = it - keys.begin();
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
// remap materials->texture IDs
|
// remap materials->texture IDs
|
||||||
for ( auto& name : graph.materials ) {
|
for ( auto& name : graph.materials ) {
|
||||||
@ -161,86 +158,52 @@ pod::Graph& uf::graph::convert( uf::Object& object, bool process ) {
|
|||||||
auto& ID = *pointer;
|
auto& ID = *pointer;
|
||||||
if ( !(0 <= ID && ID < graph.textures.size()) ) continue;
|
if ( !(0 <= ID && ID < graph.textures.size()) ) continue;
|
||||||
auto& needle = graph.textures[ID];
|
auto& needle = graph.textures[ID];
|
||||||
#if 1
|
|
||||||
ID = indices[needle];
|
ID = indices[needle];
|
||||||
#elif 1
|
|
||||||
for ( size_t i = 0; i < keys.size(); ++i ) {
|
|
||||||
if ( keys[i] != needle ) continue;
|
|
||||||
ID = i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
if ( !(0 <= ID && ID < graph.textures.size()) ) continue;
|
|
||||||
auto it = std::find( keys.begin(), keys.end(), needle );
|
|
||||||
UF_ASSERT( it != keys.end() );
|
|
||||||
ID = it - keys.begin();
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// remap instance variables
|
// remap instance variables
|
||||||
for ( auto& name : graph.instances ) {
|
for ( auto& name : graph.primitives ) {
|
||||||
auto& instance = storage.instances[name];
|
auto& primitives = storage.primitives[name];
|
||||||
|
for ( auto& primitive : primitives ) {
|
||||||
if ( 0 <= instance.materialID && instance.materialID < graph.materials.size() ) {
|
auto& instance = primitive.instance;
|
||||||
auto& keys = /*graph.storage*/storage.materials.keys;
|
|
||||||
auto& indices = /*graph.storage*/storage.materials.indices;
|
|
||||||
|
|
||||||
if ( !(0 <= instance.materialID && instance.materialID < graph.materials.size()) ) continue;
|
if ( 0 <= instance.materialID && instance.materialID < graph.materials.size() ) {
|
||||||
|
auto& keys = storage.materials.keys;
|
||||||
|
auto& indices = storage.materials.indices;
|
||||||
|
|
||||||
|
if ( !(0 <= instance.materialID && instance.materialID < graph.materials.size()) ) continue;
|
||||||
|
|
||||||
auto& needle = graph.materials[instance.materialID];
|
auto& needle = graph.materials[instance.materialID];
|
||||||
#if 1
|
instance.materialID = indices[needle];
|
||||||
instance.materialID = indices[needle];
|
|
||||||
#elif 1
|
|
||||||
for ( size_t i = 0; i < keys.size(); ++i ) {
|
|
||||||
if ( keys[i] != needle ) continue;
|
|
||||||
instance.materialID = i;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
#else
|
if ( 0 <= instance.lightmapID && instance.lightmapID < graph.textures.size() ) {
|
||||||
auto it = std::find( keys.begin(), keys.end(), needle );
|
auto& keys = storage.textures.keys;
|
||||||
UF_ASSERT( it != keys.end() );
|
auto& indices = storage.textures.indices;
|
||||||
instance.materialID = it - keys.begin();
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
if ( 0 <= instance.lightmapID && instance.lightmapID < graph.textures.size() ) {
|
|
||||||
auto& keys = /*graph.storage*/storage.textures.keys;
|
|
||||||
auto& indices = /*graph.storage*/storage.textures.indices;
|
|
||||||
|
|
||||||
if ( !(0 <= instance.lightmapID && instance.lightmapID < graph.textures.size()) ) continue;
|
if ( !(0 <= instance.lightmapID && instance.lightmapID < graph.textures.size()) ) continue;
|
||||||
|
|
||||||
auto& needle = graph.textures[instance.lightmapID];
|
auto& needle = graph.textures[instance.lightmapID];
|
||||||
#if 1
|
instance.lightmapID = indices[needle];
|
||||||
instance.lightmapID = indices[needle];
|
|
||||||
#elif 1
|
|
||||||
for ( size_t i = 0; i < keys.size(); ++i ) {
|
|
||||||
if ( keys[i] != needle ) continue;
|
|
||||||
instance.lightmapID = i;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
#else
|
#if 0
|
||||||
auto it = std::find( keys.begin(), keys.end(), needle );
|
// i genuinely dont remember what this is used for
|
||||||
UF_ASSERT( it != keys.end() );
|
|
||||||
instance.lightmapID = it - keys.begin();
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
#if 0
|
|
||||||
// i genuinely dont remember what this is used for
|
|
||||||
|
|
||||||
if ( 0 <= instance.imageID && instance.imageID < graph.images.size() ) {
|
if ( 0 <= instance.imageID && instance.imageID < graph.images.size() ) {
|
||||||
auto& keys = /*graph.storage*/storage.images.keys;
|
auto& keys = storage.images.keys;
|
||||||
auto it = std::find( keys.begin(), keys.end(), graph.images[instance.imageID] );
|
auto it = std::find( keys.begin(), keys.end(), graph.images[instance.imageID] );
|
||||||
UF_ASSERT( it != keys.end() );
|
UF_ASSERT( it != keys.end() );
|
||||||
instance.imageID = it - keys.begin();
|
instance.imageID = it - keys.begin();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
// remap a skinID as an actual jointID
|
// remap a skinID as an actual jointID
|
||||||
if ( 0 <= instance.jointID && instance.jointID < graph.skins.size() ) {
|
if ( 0 <= instance.jointID && instance.jointID < graph.skins.size() ) {
|
||||||
auto& name = graph.skins[instance.jointID];
|
auto& name = graph.skins[instance.jointID];
|
||||||
instance.jointID = 0;
|
instance.jointID = 0;
|
||||||
for ( auto key : storage.joints.keys ) {
|
for ( auto key : storage.joints.keys ) {
|
||||||
if ( key == name ) break;
|
if ( key == name ) break;
|
||||||
auto& joints = storage.joints[key];
|
auto& joints = storage.joints[key];
|
||||||
instance.jointID += joints.size();
|
instance.jointID += joints.size();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -420,21 +420,6 @@ void uf::graph::load( pod::Graph& graph, const uf::stl::string& filename, const
|
|||||||
key += ":";
|
key += ":";
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks.queue([&]{
|
|
||||||
// load images
|
|
||||||
UF_DEBUG_TIMER_MULTITRACE("Reading instances...");
|
|
||||||
graph.instances.reserve( serializer["instances"].size() );
|
|
||||||
ext::json::forEach( serializer["instances"], [&]( ext::json::Value& value ){
|
|
||||||
auto name = key + value["name"].as<uf::stl::string>();
|
|
||||||
// UF_MSG_DEBUG("{}", name);
|
|
||||||
/*graph.storage*/storage.instances[name] = decodeInstance( value, graph );
|
|
||||||
graph.instances.emplace_back(name);
|
|
||||||
});
|
|
||||||
UF_DEBUG_TIMER_MULTITRACE("Read instances");
|
|
||||||
#if UF_ENV_DREAMCAST
|
|
||||||
DC_STATS();
|
|
||||||
#endif
|
|
||||||
});
|
|
||||||
tasks.queue([&]{
|
tasks.queue([&]{
|
||||||
// load images
|
// load images
|
||||||
UF_DEBUG_TIMER_MULTITRACE("Reading primitives...");
|
UF_DEBUG_TIMER_MULTITRACE("Reading primitives...");
|
||||||
@ -450,21 +435,6 @@ void uf::graph::load( pod::Graph& graph, const uf::stl::string& filename, const
|
|||||||
DC_STATS();
|
DC_STATS();
|
||||||
#endif
|
#endif
|
||||||
});
|
});
|
||||||
tasks.queue([&]{
|
|
||||||
// load images
|
|
||||||
UF_DEBUG_TIMER_MULTITRACE("Reading drawCommands...");
|
|
||||||
graph.drawCommands.reserve( serializer["drawCommands"].size() );
|
|
||||||
ext::json::forEach( serializer["drawCommands"], [&]( ext::json::Value& value ){
|
|
||||||
auto name = key + value["name"].as<uf::stl::string>();
|
|
||||||
// UF_MSG_DEBUG("{}", name);
|
|
||||||
/*graph.storage*/storage.drawCommands[name] = decodeDrawCommands( value, graph );
|
|
||||||
graph.drawCommands.emplace_back(name);
|
|
||||||
});
|
|
||||||
UF_DEBUG_TIMER_MULTITRACE("Read drawCommands");
|
|
||||||
#if UF_ENV_DREAMCAST
|
|
||||||
DC_STATS();
|
|
||||||
#endif
|
|
||||||
});
|
|
||||||
tasks.queue([&]{
|
tasks.queue([&]{
|
||||||
// load mesh information
|
// load mesh information
|
||||||
UF_DEBUG_TIMER_MULTITRACE("Reading meshes...");
|
UF_DEBUG_TIMER_MULTITRACE("Reading meshes...");
|
||||||
|
|||||||
@ -290,16 +290,6 @@ uf::stl::string uf::graph::save( const pod::Graph& graph, const uf::stl::string&
|
|||||||
auto& scene = uf::scene::getCurrentScene();
|
auto& scene = uf::scene::getCurrentScene();
|
||||||
auto& storage = uf::graph::globalStorage ? uf::graph::storage : scene.getComponent<pod::Graph::Storage>();
|
auto& storage = uf::graph::globalStorage ? uf::graph::storage : scene.getComponent<pod::Graph::Storage>();
|
||||||
|
|
||||||
tasks.queue([&]{
|
|
||||||
ext::json::reserve( serializer["instances"], graph.instances.size() );
|
|
||||||
for ( size_t i = 0; i < graph.instances.size(); ++i ) {
|
|
||||||
auto& name = graph.instances[i];
|
|
||||||
auto& instance = /*graph.storage*/storage.instances.map.at(name);
|
|
||||||
uf::Serializer json = encode( instance, settings, graph );
|
|
||||||
json["name"] = name;
|
|
||||||
serializer["instances"].emplace_back( json );
|
|
||||||
}
|
|
||||||
});
|
|
||||||
tasks.queue([&]{
|
tasks.queue([&]{
|
||||||
ext::json::reserve( serializer["primitives"], graph.primitives.size() );
|
ext::json::reserve( serializer["primitives"], graph.primitives.size() );
|
||||||
for ( size_t i = 0; i < graph.primitives.size(); ++i ) {
|
for ( size_t i = 0; i < graph.primitives.size(); ++i ) {
|
||||||
@ -313,19 +303,6 @@ uf::stl::string uf::graph::save( const pod::Graph& graph, const uf::stl::string&
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
tasks.queue([&]{
|
|
||||||
ext::json::reserve( serializer["drawCommands"], graph.drawCommands.size() );
|
|
||||||
for ( size_t i = 0; i < graph.drawCommands.size(); ++i ) {
|
|
||||||
auto& name = graph.drawCommands[i];
|
|
||||||
auto& drawCommands = /*graph.storage*/storage.drawCommands.map.at(name);
|
|
||||||
auto& json = serializer["drawCommands"].emplace_back();
|
|
||||||
json["name"] = name;
|
|
||||||
// ext::json::reserve( json["drawCommands"], drawCommands.size() );
|
|
||||||
for ( auto& drawCommand : drawCommands ) {
|
|
||||||
json["drawCommands"].emplace_back( encode( drawCommand, settings, graph ) );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
tasks.queue([&]{
|
tasks.queue([&]{
|
||||||
// store mesh information
|
// store mesh information
|
||||||
ext::json::reserve( serializer["meshes"], graph.meshes.size() );
|
ext::json::reserve( serializer["meshes"], graph.meshes.size() );
|
||||||
|
|||||||
@ -26,7 +26,7 @@
|
|||||||
#if UF_USE_OPENGL
|
#if UF_USE_OPENGL
|
||||||
#define UF_GRAPH_SPARSE_READ_MESH 1
|
#define UF_GRAPH_SPARSE_READ_MESH 1
|
||||||
#else
|
#else
|
||||||
#define UF_GRAPH_SPARSE_READ_MESH 1
|
#define UF_GRAPH_SPARSE_READ_MESH 0
|
||||||
#endif
|
#endif
|
||||||
#define UF_GRAPH_EXTENDED 1
|
#define UF_GRAPH_EXTENDED 1
|
||||||
|
|
||||||
@ -520,13 +520,9 @@ namespace {
|
|||||||
for ( size_t drawID = 0; drawID < mesh.indirect.count; ++drawID ) {
|
for ( size_t drawID = 0; drawID < mesh.indirect.count; ++drawID ) {
|
||||||
auto& drawCommand = drawCommands[drawID];
|
auto& drawCommand = drawCommands[drawID];
|
||||||
auto instanceID = drawCommand.instanceID;
|
auto instanceID = drawCommand.instanceID;
|
||||||
auto instanceKeyName = std::to_string(instanceID);
|
auto instanceKeyName = std::to_string(instanceID); // it *should* be fine as the instance IDs are already objective to the scene graph
|
||||||
|
|
||||||
if ( storage.instanceAddresses.map.count(instanceKeyName) > 0 ) {
|
auto& instanceAddresses = storage.instanceAddresses[instanceKeyName];
|
||||||
// UF_MSG_ERROR("DUPLICATE INSTANCE ID: {}", instanceKeyName);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto& instanceAddresses = storage.instanceAddresses.map[instanceKeyName];
|
|
||||||
if ( mesh.vertex.count ) {
|
if ( mesh.vertex.count ) {
|
||||||
if ( mesh.isInterleaved( mesh.vertex ) ) {
|
if ( mesh.isInterleaved( mesh.vertex ) ) {
|
||||||
instanceAddresses.vertex = graphic.buffers.at(graphic.descriptor.inputs.vertex.interleaved).getAddress();
|
instanceAddresses.vertex = graphic.buffers.at(graphic.descriptor.inputs.vertex.interleaved).getAddress();
|
||||||
@ -556,6 +552,7 @@ namespace {
|
|||||||
|
|
||||||
instanceAddresses.drawID = drawID;
|
instanceAddresses.drawID = drawID;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -780,12 +777,6 @@ void uf::graph::process( pod::Graph& graph ) {
|
|||||||
uf::stl::unordered_map<size_t, size_t> lightmapIDs;
|
uf::stl::unordered_map<size_t, size_t> lightmapIDs;
|
||||||
uint32_t lightmapCount = 0;
|
uint32_t lightmapCount = 0;
|
||||||
|
|
||||||
for ( auto& name : graph.instances ) {
|
|
||||||
auto& instance = storage.instances[name];
|
|
||||||
filenames[instance.auxID] = uf::string::replace(UF_GRAPH_DEFAULT_LIGHTMAP, "%i", std::to_string(instance.auxID));
|
|
||||||
|
|
||||||
lightmapCount = std::max( lightmapCount, instance.auxID + 1 );
|
|
||||||
}
|
|
||||||
for ( auto& name : graph.primitives ) {
|
for ( auto& name : graph.primitives ) {
|
||||||
auto& primitives = storage.primitives[name];
|
auto& primitives = storage.primitives[name];
|
||||||
for ( auto& primitive : primitives ) {
|
for ( auto& primitive : primitives ) {
|
||||||
@ -859,11 +850,6 @@ void uf::graph::process( pod::Graph& graph ) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for ( auto& name : graph.instances ) {
|
|
||||||
auto& instance = storage.instances[name];
|
|
||||||
if ( lightmapIDs.count( instance.auxID ) == 0 ) continue;
|
|
||||||
instance.lightmapID = lightmapIDs[instance.auxID];
|
|
||||||
}
|
|
||||||
for ( auto& name : graph.primitives ) {
|
for ( auto& name : graph.primitives ) {
|
||||||
auto& primitives = storage.primitives[name];
|
auto& primitives = storage.primitives[name];
|
||||||
for ( auto& primitive : primitives ) {
|
for ( auto& primitive : primitives ) {
|
||||||
@ -1038,80 +1024,60 @@ void uf::graph::process( pod::Graph& graph ) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// remap instance variables
|
// remap instance variables
|
||||||
UF_DEBUG_TIMER_MULTITRACE("Remapping instances");
|
UF_DEBUG_TIMER_MULTITRACE("Remapping primitive");
|
||||||
for ( auto& name : graph.instances ) {
|
for ( auto& name : graph.primitives ) {
|
||||||
auto& instance = storage.instances[name];
|
auto& primitives = storage.primitives[name];
|
||||||
|
for ( auto& primitive : primitives ) {
|
||||||
if ( 0 <= instance.materialID && instance.materialID < graph.materials.size() ) {
|
auto& drawCommand = primitive.drawCommand;
|
||||||
auto& keys = storage.materials.keys;
|
auto& instance = primitive.instance;
|
||||||
auto& indices = storage.materials.indices;
|
|
||||||
|
|
||||||
if ( !(0 <= instance.materialID && instance.materialID < graph.materials.size()) ) continue;
|
|
||||||
|
|
||||||
auto& needle = graph.materials[instance.materialID];
|
// remap instance ID
|
||||||
instance.materialID = indices[needle];
|
if ( 0 <= drawCommand.instanceID && drawCommand.instanceID < graph.primitives.size() ) {
|
||||||
}
|
for ( auto key : storage.primitives.keys ) {
|
||||||
if ( 0 <= instance.lightmapID && instance.lightmapID < graph.textures.size() ) {
|
if ( key == name ) break;
|
||||||
auto& keys = storage.textures.keys;
|
drawCommand.instanceID += storage.primitives[key].size();
|
||||||
auto& indices = storage.textures.indices;
|
|
||||||
|
|
||||||
if ( !(0 <= instance.lightmapID && instance.lightmapID < graph.textures.size()) ) continue;
|
|
||||||
|
|
||||||
auto& needle = graph.textures[instance.lightmapID];
|
|
||||||
instance.lightmapID = indices[needle];
|
|
||||||
}
|
|
||||||
#if 0
|
|
||||||
// i genuinely dont remember what this is used for
|
|
||||||
|
|
||||||
if ( 0 <= instance.imageID && instance.imageID < graph.images.size() ) {
|
|
||||||
auto& keys = storage.images.keys;
|
|
||||||
auto it = std::find( keys.begin(), keys.end(), graph.images[instance.imageID] );
|
|
||||||
UF_ASSERT( it != keys.end() );
|
|
||||||
instance.imageID = it - keys.begin();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
// remap a skinID as an actual jointID
|
|
||||||
if ( 0 <= instance.jointID && instance.jointID < graph.skins.size() ) {
|
|
||||||
auto& name = graph.skins[instance.jointID];
|
|
||||||
instance.jointID = 0;
|
|
||||||
for ( auto key : storage.joints.keys ) {
|
|
||||||
if ( key == name ) break;
|
|
||||||
auto& joints = storage.joints[key];
|
|
||||||
instance.jointID += joints.size();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// remap draw commands
|
|
||||||
#if 0
|
|
||||||
UF_DEBUG_TIMER_MULTITRACE("Remapping drawCommands");
|
|
||||||
for ( auto& name : graph.drawCommands ) {
|
|
||||||
auto& drawCommands = storage.drawCommands[name];
|
|
||||||
for ( auto& drawCommand : drawCommands ) {
|
|
||||||
if ( 0 <= drawCommand.instanceID && drawCommand.instanceID < graph.instances.size() ) {
|
|
||||||
auto& keys = storage.instances.keys;
|
|
||||||
auto& indices = storage.instances.indices;
|
|
||||||
|
|
||||||
if ( !(0 <= drawCommand.instanceID && drawCommand.instanceID < graph.instances.size()) ) continue;
|
|
||||||
|
|
||||||
auto& needle = graph.instances[drawCommand.instanceID];
|
|
||||||
#if 1
|
|
||||||
drawCommand.instanceID = indices[needle];
|
|
||||||
#elif 1
|
|
||||||
for ( size_t i = 0; i < keys.size(); ++i ) {
|
|
||||||
if ( keys[i] != needle ) continue;
|
|
||||||
drawCommand.instanceID = i;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
#else
|
}
|
||||||
auto it = std::find( keys.begin(), keys.end(), needle );
|
|
||||||
|
if ( 0 <= instance.materialID && instance.materialID < graph.materials.size() ) {
|
||||||
|
auto& keys = storage.materials.keys;
|
||||||
|
auto& indices = storage.materials.indices;
|
||||||
|
|
||||||
|
if ( !(0 <= instance.materialID && instance.materialID < graph.materials.size()) ) continue;
|
||||||
|
|
||||||
|
auto& needle = graph.materials[instance.materialID];
|
||||||
|
instance.materialID = indices[needle];
|
||||||
|
}
|
||||||
|
if ( 0 <= instance.lightmapID && instance.lightmapID < graph.textures.size() ) {
|
||||||
|
auto& keys = storage.textures.keys;
|
||||||
|
auto& indices = storage.textures.indices;
|
||||||
|
|
||||||
|
if ( !(0 <= instance.lightmapID && instance.lightmapID < graph.textures.size()) ) continue;
|
||||||
|
|
||||||
|
auto& needle = graph.textures[instance.lightmapID];
|
||||||
|
instance.lightmapID = indices[needle];
|
||||||
|
}
|
||||||
|
#if 0
|
||||||
|
// i genuinely dont remember what this is used for
|
||||||
|
|
||||||
|
if ( 0 <= instance.imageID && instance.imageID < graph.images.size() ) {
|
||||||
|
auto& keys = storage.images.keys;
|
||||||
|
auto it = std::find( keys.begin(), keys.end(), graph.images[instance.imageID] );
|
||||||
UF_ASSERT( it != keys.end() );
|
UF_ASSERT( it != keys.end() );
|
||||||
drawCommand.instanceID = it - keys.begin();
|
instance.imageID = it - keys.begin();
|
||||||
#endif
|
}
|
||||||
|
#endif
|
||||||
|
// remap a skinID as an actual jointID
|
||||||
|
if ( 0 <= instance.jointID && instance.jointID < graph.skins.size() ) {
|
||||||
|
auto& name = graph.skins[instance.jointID];
|
||||||
|
instance.jointID = 0;
|
||||||
|
for ( auto key : storage.joints.keys ) {
|
||||||
|
if ( key == name ) break;
|
||||||
|
instance.jointID += storage.joints[key].size();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
if ( graphMetadataJson["debug"]["print"]["lights"].as<bool>() ) {
|
if ( graphMetadataJson["debug"]["print"]["lights"].as<bool>() ) {
|
||||||
UF_MSG_DEBUG("Lights: {}", graph.lights.size());
|
UF_MSG_DEBUG("Lights: {}", graph.lights.size());
|
||||||
@ -1126,16 +1092,21 @@ void uf::graph::process( pod::Graph& graph ) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( graphMetadataJson["debug"]["print"]["instances"].as<bool>() ) {
|
#if 0
|
||||||
UF_MSG_DEBUG("Instances: {}", graph.instances.size());
|
if ( graphMetadataJson["debug"]["print"]["primitives"].as<bool>() ) {
|
||||||
for ( auto& name : graph.instances ) {
|
UF_MSG_DEBUG("Instances: {}", graph.primitives.size());
|
||||||
auto& instance = storage.instances[name];
|
for ( auto& name : graph.primitives ) {
|
||||||
UF_MSG_DEBUG("\tInstance: {} | {} | {}", name,
|
auto& primitive = storage.primitives[name];
|
||||||
instance.materialID,
|
for ( auto& primitive : primitives ) {
|
||||||
instance.lightmapID
|
auto& instance = primitive.instance;
|
||||||
);
|
UF_MSG_DEBUG("\tInstance: {} | {} | {}", name,
|
||||||
|
instance.materialID,
|
||||||
|
instance.lightmapID
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
if ( graphMetadataJson["debug"]["print"]["materials"].as<bool>() ) {
|
if ( graphMetadataJson["debug"]["print"]["materials"].as<bool>() ) {
|
||||||
UF_MSG_DEBUG("Materials: {}", graph.materials.size());
|
UF_MSG_DEBUG("Materials: {}", graph.materials.size());
|
||||||
for ( auto& name : graph.materials ) {
|
for ( auto& name : graph.materials ) {
|
||||||
@ -1163,7 +1134,6 @@ void uf::graph::process( pod::Graph& graph ) {
|
|||||||
#endif
|
#endif
|
||||||
uf::graph::reload();
|
uf::graph::reload();
|
||||||
|
|
||||||
storage.instanceAddresses.keys = storage.instances.keys;
|
|
||||||
UF_DEBUG_TIMER_MULTITRACE_END("Processed graph.");
|
UF_DEBUG_TIMER_MULTITRACE_END("Processed graph.");
|
||||||
}
|
}
|
||||||
void uf::graph::process( pod::Graph& graph, int32_t index, uf::Object& parent ) {
|
void uf::graph::process( pod::Graph& graph, int32_t index, uf::Object& parent ) {
|
||||||
@ -1313,22 +1283,25 @@ void uf::graph::process( pod::Graph& graph, int32_t index, uf::Object& parent )
|
|||||||
storage.entities[objectKeyName] = &entity;
|
storage.entities[objectKeyName] = &entity;
|
||||||
|
|
||||||
//
|
//
|
||||||
#if !UF_GRAPH_EXTENDED
|
|
||||||
if ( 0 <= node.mesh && node.mesh < graph.meshes.size() ) {
|
if ( 0 <= node.mesh && node.mesh < graph.meshes.size() ) {
|
||||||
auto model = uf::transform::model( transform );
|
auto model = uf::transform::model( transform );
|
||||||
auto& mesh = storage.meshes.map[graph.meshes[node.mesh]];
|
auto& mesh = storage.meshes.map[graph.meshes[node.mesh]];
|
||||||
auto& primitives = storage.primitives.map[graph.primitives[node.mesh]];
|
auto& primitives = storage.primitives.map[graph.primitives[node.mesh]];
|
||||||
|
|
||||||
pod::Instance::Bounds bounds;
|
pod::Instance::Bounds bounds;
|
||||||
|
pod::DrawCommand* drawCommands = NULL;
|
||||||
|
if ( mesh.indirect.count && mesh.indirect.count <= primitives.size() ) {
|
||||||
|
auto& attribute = mesh.indirect.attributes.front();
|
||||||
|
auto& buffer = mesh.buffers[mesh.isInterleaved(mesh.indirect.interleaved) ? mesh.indirect.interleaved : attribute.buffer];
|
||||||
|
drawCommands = (pod::DrawCommand*) buffer.data();
|
||||||
|
}
|
||||||
// setup instances
|
// setup instances
|
||||||
for ( auto i = 0; i < primitives.size(); ++i ) {
|
for ( auto i = 0; i < primitives.size(); ++i ) {
|
||||||
auto& primitive = primitives[i];
|
auto& primitive = primitives[i];
|
||||||
|
auto& instance = primitive.instance;
|
||||||
|
auto& drawCommand = primitive.drawCommand;
|
||||||
|
|
||||||
size_t instanceID = storage.instances.keys.size();
|
auto instanceID = i;
|
||||||
auto instanceKeyName = graph.instances.emplace_back(std::to_string(instanceID));
|
|
||||||
|
|
||||||
auto& instance = storage.instances[instanceKeyName];
|
|
||||||
instance = primitive.instance;
|
|
||||||
|
|
||||||
instance.model = model;
|
instance.model = model;
|
||||||
instance.previous = model;
|
instance.previous = model;
|
||||||
@ -1338,82 +1311,14 @@ void uf::graph::process( pod::Graph& graph, int32_t index, uf::Object& parent )
|
|||||||
bounds.min = uf::vector::min( bounds.min, instance.bounds.min );
|
bounds.min = uf::vector::min( bounds.min, instance.bounds.min );
|
||||||
bounds.max = uf::vector::max( bounds.max, instance.bounds.max );
|
bounds.max = uf::vector::max( bounds.max, instance.bounds.max );
|
||||||
|
|
||||||
if ( mesh.indirect.count && mesh.indirect.count <= primitives.size() ) {
|
drawCommand.instanceID = instanceID;
|
||||||
auto& attribute = mesh.indirect.attributes.front();
|
if ( drawCommands ) drawCommands[i].instanceID = instanceID;
|
||||||
auto& buffer = mesh.buffers[mesh.isInterleaved(mesh.indirect.interleaved) ? mesh.indirect.interleaved : attribute.buffer];
|
|
||||||
pod::DrawCommand* drawCommands = (pod::DrawCommand*) buffer.data();
|
|
||||||
auto& drawCommand = drawCommands[i];
|
|
||||||
drawCommand.instanceID = instanceID;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
#if !UF_GRAPH_EXTENDED
|
||||||
if ( graphMetadataJson["renderer"]["render"].as<bool>() ) {
|
if ( graphMetadataJson["renderer"]["render"].as<bool>() ) {
|
||||||
uf::graph::initializeGraphics( graph, entity, mesh );
|
uf::graph::initializeGraphics( graph, entity, mesh );
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
{
|
|
||||||
auto phyziks = tag["physics"];
|
|
||||||
if ( !ext::json::isObject( phyziks ) ) phyziks = metadataJson["physics"];
|
|
||||||
else metadataJson["physics"] = phyziks;
|
|
||||||
|
|
||||||
if ( ext::json::isObject( phyziks ) ) {
|
|
||||||
uf::stl::string type = phyziks["type"].as<uf::stl::string>();
|
|
||||||
|
|
||||||
if ( type == "mesh" ) {
|
|
||||||
auto& collider = entity.getComponent<pod::PhysicsState>();
|
|
||||||
collider.stats.mass = phyziks["mass"].as(collider.stats.mass);
|
|
||||||
collider.stats.friction = phyziks["friction"].as(collider.stats.friction);
|
|
||||||
collider.stats.restitution = phyziks["restitution"].as(collider.stats.restitution);
|
|
||||||
collider.stats.inertia = uf::vector::decode( phyziks["inertia"], collider.stats.inertia );
|
|
||||||
collider.stats.gravity = uf::vector::decode( phyziks["gravity"], collider.stats.gravity );
|
|
||||||
|
|
||||||
uf::physics::impl::create( entity.as<uf::Object>(), mesh, !phyziks["static"].as<bool>(true) );
|
|
||||||
} else {
|
|
||||||
auto min = uf::matrix::multiply<float>( model, bounds.min, 1.0f );
|
|
||||||
auto max = uf::matrix::multiply<float>( model, bounds.max, 1.0f );
|
|
||||||
|
|
||||||
pod::Vector3f center = (max + min) * 0.5f;
|
|
||||||
pod::Vector3f corner = uf::vector::abs(max - min) * 0.5f;
|
|
||||||
|
|
||||||
metadataJson["physics"]["center"] = uf::vector::encode( center );
|
|
||||||
metadataJson["physics"]["corner"] = uf::vector::encode( corner );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
if ( 0 <= node.mesh && node.mesh < graph.meshes.size() ) {
|
|
||||||
auto model = uf::transform::model( transform );
|
|
||||||
auto& mesh = storage.meshes.map[graph.meshes[node.mesh]];
|
|
||||||
auto& primitives = storage.primitives.map[graph.primitives[node.mesh]];
|
|
||||||
|
|
||||||
pod::Instance::Bounds bounds;
|
|
||||||
// setup instances
|
|
||||||
for ( auto i = 0; i < primitives.size(); ++i ) {
|
|
||||||
auto& primitive = primitives[i];
|
|
||||||
|
|
||||||
size_t instanceID = storage.instances.keys.size();
|
|
||||||
auto instanceKeyName = graph.instances.emplace_back(std::to_string(instanceID));
|
|
||||||
|
|
||||||
auto& instance = storage.instances[instanceKeyName];
|
|
||||||
instance = primitive.instance;
|
|
||||||
|
|
||||||
instance.model = model;
|
|
||||||
instance.previous = model;
|
|
||||||
instance.objectID = objectID;
|
|
||||||
instance.jointID = graphMetadataJson["renderer"]["skinned"].as<bool>() ? 0 : -1;
|
|
||||||
|
|
||||||
bounds.min = uf::vector::min( bounds.min, instance.bounds.min );
|
|
||||||
bounds.max = uf::vector::max( bounds.max, instance.bounds.max );
|
|
||||||
|
|
||||||
primitive.drawCommand.instanceID = instanceID;
|
|
||||||
if ( mesh.indirect.count && mesh.indirect.count <= primitives.size() ) {
|
|
||||||
auto& attribute = mesh.indirect.attributes.front();
|
|
||||||
auto& buffer = mesh.buffers[mesh.isInterleaved(mesh.indirect.interleaved) ? mesh.indirect.interleaved : attribute.buffer];
|
|
||||||
pod::DrawCommand* drawCommands = (pod::DrawCommand*) buffer.data();
|
|
||||||
auto& drawCommand = drawCommands[i];
|
|
||||||
drawCommand.instanceID = instanceID;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
{
|
||||||
auto phyziks = tag["physics"];
|
auto phyziks = tag["physics"];
|
||||||
@ -1433,10 +1338,21 @@ void uf::graph::process( pod::Graph& graph, int32_t index, uf::Object& parent )
|
|||||||
metadataJson["physics"]["center"] = uf::vector::encode( center );
|
metadataJson["physics"]["center"] = uf::vector::encode( center );
|
||||||
metadataJson["physics"]["corner"] = uf::vector::encode( corner );
|
metadataJson["physics"]["corner"] = uf::vector::encode( corner );
|
||||||
}
|
}
|
||||||
|
#if UF_GRAPH_EXTENDED
|
||||||
|
if ( type == "mesh" ) {
|
||||||
|
auto& collider = entity.getComponent<pod::PhysicsState>();
|
||||||
|
collider.stats.mass = phyziks["mass"].as(collider.stats.mass);
|
||||||
|
collider.stats.friction = phyziks["friction"].as(collider.stats.friction);
|
||||||
|
collider.stats.restitution = phyziks["restitution"].as(collider.stats.restitution);
|
||||||
|
collider.stats.inertia = uf::vector::decode( phyziks["inertia"], collider.stats.inertia );
|
||||||
|
collider.stats.gravity = uf::vector::decode( phyziks["gravity"], collider.stats.gravity );
|
||||||
|
|
||||||
|
uf::physics::impl::create( entity.as<uf::Object>(), mesh, !phyziks["static"].as<bool>(true) );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
for ( auto index : node.children ) uf::graph::process( graph, index, entity );
|
for ( auto index : node.children ) uf::graph::process( graph, index, entity );
|
||||||
}
|
}
|
||||||
@ -1488,17 +1404,22 @@ void uf::graph::tick( uf::Object& object ) {
|
|||||||
}
|
}
|
||||||
bool uf::graph::tick( pod::Graph::Storage& storage ) {
|
bool uf::graph::tick( pod::Graph::Storage& storage ) {
|
||||||
bool rebuild = false;
|
bool rebuild = false;
|
||||||
uf::stl::vector<pod::Instance> instances = storage.instances.flatten();
|
uf::stl::vector<pod::Instance> instances; instances.reserve(storage.primitives.map.size());
|
||||||
uf::stl::vector<pod::Instance::Addresses> instanceAddresses = storage.instanceAddresses.flatten();
|
uf::stl::vector<pod::Instance::Addresses> instanceAddresses = storage.instanceAddresses.flatten();
|
||||||
uf::stl::vector<pod::Matrix4f> joints; joints.reserve(storage.joints.map.size());
|
uf::stl::vector<pod::Matrix4f> joints; joints.reserve(storage.joints.map.size());
|
||||||
|
|
||||||
|
for ( auto& key : storage.primitives.keys ) {
|
||||||
|
for ( auto& primitive : storage.primitives.map[key] ) {
|
||||||
|
instances.emplace_back( primitive.instance );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for ( auto& key : storage.joints.keys ) {
|
for ( auto& key : storage.joints.keys ) {
|
||||||
auto& matrices = storage.joints.map[key];
|
auto& matrices = storage.joints.map[key];
|
||||||
joints.reserve( joints.size() + matrices.size() );
|
joints.reserve( joints.size() + matrices.size() );
|
||||||
for ( auto& mat : matrices ) joints.emplace_back( mat );
|
for ( auto& mat : matrices ) joints.emplace_back( mat );
|
||||||
}
|
}
|
||||||
|
|
||||||
rebuild = storage.buffers.instance.update( (const void*) instances.data(), instances.size() * sizeof(pod::Instance) ) || rebuild;
|
rebuild = storage.buffers.instance.update( (const void*) instances.data(), instances.size() * sizeof(pod::Instance) ) || rebuild;
|
||||||
rebuild = storage.buffers.instanceAddresses.update( (const void*) instanceAddresses.data(), instanceAddresses.size() * sizeof(pod::Instance::Addresses) ) || rebuild;
|
rebuild = storage.buffers.instanceAddresses.update( (const void*) instanceAddresses.data(), instanceAddresses.size() * sizeof(pod::Instance::Addresses) ) || rebuild;
|
||||||
rebuild = storage.buffers.joint.update( (const void*) joints.data(), joints.size() * sizeof(pod::Matrix4f) ) || rebuild;
|
rebuild = storage.buffers.joint.update( (const void*) joints.data(), joints.size() * sizeof(pod::Matrix4f) ) || rebuild;
|
||||||
@ -1506,9 +1427,13 @@ bool uf::graph::tick( pod::Graph::Storage& storage ) {
|
|||||||
if ( ::newGraphAdded ) {
|
if ( ::newGraphAdded ) {
|
||||||
uf::stl::vector<pod::Material> materials = storage.materials.flatten();
|
uf::stl::vector<pod::Material> materials = storage.materials.flatten();
|
||||||
uf::stl::vector<pod::Texture> textures = storage.textures.flatten();
|
uf::stl::vector<pod::Texture> textures = storage.textures.flatten();
|
||||||
uf::stl::vector<pod::DrawCommand> drawCommands; drawCommands.reserve(storage.drawCommands.map.size());
|
uf::stl::vector<pod::DrawCommand> drawCommands; drawCommands.reserve(storage.primitives.map.size());
|
||||||
|
|
||||||
for ( auto& key : storage.drawCommands.keys ) drawCommands.insert( drawCommands.end(), storage.drawCommands.map[key].begin(), storage.drawCommands.map[key].end() );
|
for ( auto& key : storage.primitives.keys ) {
|
||||||
|
for ( auto& primitive : storage.primitives.map[key] ) {
|
||||||
|
drawCommands.emplace_back( primitive.drawCommand );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
rebuild = storage.buffers.drawCommands.update( (const void*) drawCommands.data(), drawCommands.size() * sizeof(pod::DrawCommand) ) || rebuild;
|
rebuild = storage.buffers.drawCommands.update( (const void*) drawCommands.data(), drawCommands.size() * sizeof(pod::DrawCommand) ) || rebuild;
|
||||||
rebuild = storage.buffers.material.update( (const void*) materials.data(), materials.size() * sizeof(pod::Material) ) || rebuild;
|
rebuild = storage.buffers.material.update( (const void*) materials.data(), materials.size() * sizeof(pod::Material) ) || rebuild;
|
||||||
@ -1600,10 +1525,8 @@ void uf::graph::destroy( pod::Graph::Storage& storage, bool soft ) {
|
|||||||
for ( auto pair : storage.meshes.map ) pair.second.destroy();
|
for ( auto pair : storage.meshes.map ) pair.second.destroy();
|
||||||
|
|
||||||
// cleanup storage cache
|
// cleanup storage cache
|
||||||
storage.instances.clear();
|
|
||||||
storage.instanceAddresses.clear();
|
storage.instanceAddresses.clear();
|
||||||
storage.primitives.clear();
|
storage.primitives.clear();
|
||||||
storage.drawCommands.clear();
|
|
||||||
storage.meshes.clear();
|
storage.meshes.clear();
|
||||||
storage.images.clear();
|
storage.images.clear();
|
||||||
storage.materials.clear();
|
storage.materials.clear();
|
||||||
@ -2044,27 +1967,29 @@ void uf::graph::update( pod::Graph& graph, float delta ) {
|
|||||||
|
|
||||||
#if !UF_ENV_DREAMCAST
|
#if !UF_ENV_DREAMCAST
|
||||||
// update instance model
|
// update instance model
|
||||||
|
|
||||||
uf::stl::unordered_map<size_t, pod::Matrix4f> instanceCache;
|
uf::stl::unordered_map<size_t, pod::Matrix4f> instanceCache;
|
||||||
for ( auto& name : storage.instances.keys ) {
|
for ( auto& name : graph.primitives ) {
|
||||||
auto& instance = storage.instances[name];
|
auto& primitives = storage.primitives[name];
|
||||||
instance.previous = instance.model;
|
for ( auto& primitive : primitives ) {
|
||||||
|
// auto& drawCommand = primitive.drawCommand;
|
||||||
|
auto& instance = primitive.instance;
|
||||||
|
instance.previous = instance.model;
|
||||||
|
if ( instanceCache.count( instance.objectID ) > 0 ) {
|
||||||
|
instance.model = instanceCache[instance.objectID];
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if ( instanceCache.count( instance.objectID ) > 0 ) {
|
auto& entity = *storage.entities[std::to_string(instance.objectID)];
|
||||||
instance.model = instanceCache[instance.objectID];
|
if ( !entity.isValid() ) continue;
|
||||||
continue;
|
auto& metadata = entity.getComponent<uf::ObjectBehavior::Metadata>();
|
||||||
|
if ( metadata.system.ignoreGraph ) continue;
|
||||||
|
|
||||||
|
auto& transform = entity.getComponent<pod::Transform<>>();
|
||||||
|
instance.model = (instanceCache[instance.objectID] = uf::transform::model( transform ));
|
||||||
}
|
}
|
||||||
|
|
||||||
auto& entity = *storage.entities[std::to_string(instance.objectID)];
|
|
||||||
if ( !entity.isValid() ) continue;
|
|
||||||
auto& metadata = entity.getComponent<uf::ObjectBehavior::Metadata>();
|
|
||||||
if ( metadata.system.ignoreGraph ) continue;
|
|
||||||
|
|
||||||
auto& transform = entity.getComponent<pod::Transform<>>();
|
|
||||||
instance.model = (instanceCache[instance.objectID] = uf::transform::model( transform ));
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
uf::graph::updateAnimation( graph, delta );
|
uf::graph::updateAnimation( graph, delta );
|
||||||
}
|
|
||||||
void uf::graph::cleanup( pod::Graph& graph ) {
|
|
||||||
}
|
}
|
||||||
@ -156,12 +156,12 @@ void ext::gltf::load( pod::Graph& graph, const uf::stl::string& filename, const
|
|||||||
// load images
|
// load images
|
||||||
{
|
{
|
||||||
graph.images.reserve(model.images.size());
|
graph.images.reserve(model.images.size());
|
||||||
/*graph.storage*/storage.images.reserve(model.images.size());
|
storage.images.reserve(model.images.size());
|
||||||
|
|
||||||
for ( auto& i : model.images ) {
|
for ( auto& i : model.images ) {
|
||||||
auto imageID = graph.images.size();
|
auto imageID = graph.images.size();
|
||||||
auto keyName = graph.images.emplace_back(key + i.name);
|
auto keyName = graph.images.emplace_back(key + i.name);
|
||||||
auto& image = /*graph.storage*/storage.images[keyName];
|
auto& image = storage.images[keyName];
|
||||||
if ( graph.metadata["debug"]["print"]["images"].as<bool>() ) {
|
if ( graph.metadata["debug"]["print"]["images"].as<bool>() ) {
|
||||||
UF_MSG_DEBUG("Image: {}", i.name );
|
UF_MSG_DEBUG("Image: {}", i.name );
|
||||||
}
|
}
|
||||||
@ -171,11 +171,11 @@ void ext::gltf::load( pod::Graph& graph, const uf::stl::string& filename, const
|
|||||||
}
|
}
|
||||||
// load samplers
|
// load samplers
|
||||||
{
|
{
|
||||||
/*graph.storage*/storage.samplers.reserve(model.samplers.size());
|
storage.samplers.reserve(model.samplers.size());
|
||||||
for ( auto& s : model.samplers ) {
|
for ( auto& s : model.samplers ) {
|
||||||
auto samplerID = graph.samplers.size();
|
auto samplerID = graph.samplers.size();
|
||||||
auto keyName = graph.samplers.emplace_back(key + s.name);
|
auto keyName = graph.samplers.emplace_back(key + s.name);
|
||||||
auto& sampler = /*graph.storage*/storage.samplers[keyName];
|
auto& sampler = storage.samplers[keyName];
|
||||||
if ( graph.metadata["debug"]["print"]["samplers"].as<bool>() ) {
|
if ( graph.metadata["debug"]["print"]["samplers"].as<bool>() ) {
|
||||||
UF_MSG_DEBUG("Sampler: {}", s.name );
|
UF_MSG_DEBUG("Sampler: {}", s.name );
|
||||||
}
|
}
|
||||||
@ -190,12 +190,12 @@ void ext::gltf::load( pod::Graph& graph, const uf::stl::string& filename, const
|
|||||||
// load textures
|
// load textures
|
||||||
{
|
{
|
||||||
graph.textures.reserve(model.textures.size());
|
graph.textures.reserve(model.textures.size());
|
||||||
/*graph.storage*/storage.textures.reserve(model.textures.size());
|
storage.textures.reserve(model.textures.size());
|
||||||
|
|
||||||
for ( auto& t : model.textures ) {
|
for ( auto& t : model.textures ) {
|
||||||
auto textureID = graph.textures.size();
|
auto textureID = graph.textures.size();
|
||||||
auto keyName = graph.textures.emplace_back((t.name == "" ? graph.images[t.source] : (key + t.name)));
|
auto keyName = graph.textures.emplace_back((t.name == "" ? graph.images[t.source] : (key + t.name)));
|
||||||
auto& texture = /*graph.storage*/storage.textures[keyName];
|
auto& texture = storage.textures[keyName];
|
||||||
if ( graph.metadata["debug"]["print"]["textures"].as<bool>() ) {
|
if ( graph.metadata["debug"]["print"]["textures"].as<bool>() ) {
|
||||||
UF_MSG_DEBUG("Texture: {}", t.name );
|
UF_MSG_DEBUG("Texture: {}", t.name );
|
||||||
}
|
}
|
||||||
@ -207,12 +207,12 @@ void ext::gltf::load( pod::Graph& graph, const uf::stl::string& filename, const
|
|||||||
// load materials
|
// load materials
|
||||||
{
|
{
|
||||||
graph.materials.reserve(model.materials.size());
|
graph.materials.reserve(model.materials.size());
|
||||||
/*graph.storage*/storage.materials.reserve(model.materials.size());
|
storage.materials.reserve(model.materials.size());
|
||||||
|
|
||||||
for ( auto& m : model.materials ) {
|
for ( auto& m : model.materials ) {
|
||||||
auto materialID = graph.materials.size();
|
auto materialID = graph.materials.size();
|
||||||
auto keyName = graph.materials.emplace_back(key + m.name);
|
auto keyName = graph.materials.emplace_back(key + m.name);
|
||||||
auto& material = /*graph.storage*/storage.materials[keyName];
|
auto& material = storage.materials[keyName];
|
||||||
if ( graph.metadata["debug"]["print"]["materials"].as<bool>() ) {
|
if ( graph.metadata["debug"]["print"]["materials"].as<bool>() ) {
|
||||||
UF_MSG_DEBUG("Material: {}", m.name );
|
UF_MSG_DEBUG("Material: {}", m.name );
|
||||||
}
|
}
|
||||||
@ -255,7 +255,7 @@ void ext::gltf::load( pod::Graph& graph, const uf::stl::string& filename, const
|
|||||||
{
|
{
|
||||||
size_t masterAuxID = 0;
|
size_t masterAuxID = 0;
|
||||||
graph.meshes.reserve(model.meshes.size());
|
graph.meshes.reserve(model.meshes.size());
|
||||||
/*graph.storage*/storage.meshes.reserve(model.meshes.size());
|
storage.meshes.reserve(model.meshes.size());
|
||||||
|
|
||||||
for ( auto& m : model.meshes ) {
|
for ( auto& m : model.meshes ) {
|
||||||
auto meshID = graph.meshes.size();
|
auto meshID = graph.meshes.size();
|
||||||
@ -265,11 +265,9 @@ void ext::gltf::load( pod::Graph& graph, const uf::stl::string& filename, const
|
|||||||
}
|
}
|
||||||
|
|
||||||
graph.primitives.emplace_back(keyName);
|
graph.primitives.emplace_back(keyName);
|
||||||
graph.drawCommands.emplace_back(keyName);
|
|
||||||
|
|
||||||
auto& drawCommands = /*graph.storage*/storage.drawCommands[keyName];
|
auto& primitives = storage.primitives[keyName];
|
||||||
auto& primitives = /*graph.storage*/storage.primitives[keyName];
|
auto& mesh = storage.meshes[keyName];
|
||||||
auto& mesh = /*graph.storage*/storage.meshes[keyName];
|
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
uf::meshgrid::Grid grid;
|
uf::meshgrid::Grid grid;
|
||||||
@ -349,12 +347,12 @@ void ext::gltf::load( pod::Graph& graph, const uf::stl::string& filename, const
|
|||||||
// load skins
|
// load skins
|
||||||
{
|
{
|
||||||
graph.skins.reserve( model.skins.size() );
|
graph.skins.reserve( model.skins.size() );
|
||||||
/*graph.storage*/storage.skins.reserve( model.skins.size() );
|
storage.skins.reserve( model.skins.size() );
|
||||||
|
|
||||||
for ( auto& s : model.skins ) {
|
for ( auto& s : model.skins ) {
|
||||||
auto skinID = graph.skins.size();
|
auto skinID = graph.skins.size();
|
||||||
auto keyName = graph.skins.emplace_back(key + s.name);
|
auto keyName = graph.skins.emplace_back(key + s.name);
|
||||||
auto& skin = /*graph.storage*/storage.skins[keyName];
|
auto& skin = storage.skins[keyName];
|
||||||
if ( graph.metadata["debug"]["print"]["skins"].as<bool>() ) {
|
if ( graph.metadata["debug"]["print"]["skins"].as<bool>() ) {
|
||||||
UF_MSG_DEBUG("Skin: {}", s.name );
|
UF_MSG_DEBUG("Skin: {}", s.name );
|
||||||
}
|
}
|
||||||
@ -386,12 +384,12 @@ void ext::gltf::load( pod::Graph& graph, const uf::stl::string& filename, const
|
|||||||
// load animations
|
// load animations
|
||||||
{
|
{
|
||||||
graph.animations.reserve( model.animations.size() );
|
graph.animations.reserve( model.animations.size() );
|
||||||
/*graph.storage*/storage.animations.reserve( model.animations.size() );
|
storage.animations.reserve( model.animations.size() );
|
||||||
|
|
||||||
for ( auto& a : model.animations ) {
|
for ( auto& a : model.animations ) {
|
||||||
auto animationID = graph.animations.size();
|
auto animationID = graph.animations.size();
|
||||||
auto keyName = graph.animations.emplace_back(key + a.name);
|
auto keyName = graph.animations.emplace_back(key + a.name);
|
||||||
auto& animation = /*graph.storage*/storage.animations[keyName];
|
auto& animation = storage.animations[keyName];
|
||||||
if ( graph.metadata["debug"]["print"]["animations"].as<bool>() ) {
|
if ( graph.metadata["debug"]["print"]["animations"].as<bool>() ) {
|
||||||
UF_MSG_DEBUG("Animation: {}", a.name );
|
UF_MSG_DEBUG("Animation: {}", a.name );
|
||||||
}
|
}
|
||||||
@ -477,17 +475,17 @@ void ext::gltf::load( pod::Graph& graph, const uf::stl::string& filename, const
|
|||||||
// generate atlas
|
// generate atlas
|
||||||
if ( graph.metadata["renderer"]["atlas"].as<bool>() ) {
|
if ( graph.metadata["renderer"]["atlas"].as<bool>() ) {
|
||||||
auto atlasName = filename + "/" + "atlas";
|
auto atlasName = filename + "/" + "atlas";
|
||||||
auto& atlas = /*graph.storage*/storage.atlases[atlasName];
|
auto& atlas = storage.atlases[atlasName];
|
||||||
auto atlasImageIndex = graph.images.size();
|
auto atlasImageIndex = graph.images.size();
|
||||||
auto atlasTextureIndex = graph.textures.size();
|
auto atlasTextureIndex = graph.textures.size();
|
||||||
|
|
||||||
for ( auto& keyName : graph.images ) atlas.addImage( /*graph.storage*/storage.images[keyName] );
|
for ( auto& keyName : graph.images ) atlas.addImage( storage.images[keyName] );
|
||||||
atlas.generate();
|
atlas.generate();
|
||||||
|
|
||||||
for ( auto& keyName : graph.images ) {
|
for ( auto& keyName : graph.images ) {
|
||||||
auto& texture = /*graph.storage*/storage.textures[keyName];
|
auto& texture = storage.textures[keyName];
|
||||||
if ( texture.index < 0 ) continue;
|
if ( texture.index < 0 ) continue;
|
||||||
auto& image = /*graph.storage*/storage.images[keyName];
|
auto& image = storage.images[keyName];
|
||||||
|
|
||||||
const auto& hash = image.getHash();
|
const auto& hash = image.getHash();
|
||||||
auto min = atlas.mapUv( {0, 0}, hash );
|
auto min = atlas.mapUv( {0, 0}, hash );
|
||||||
@ -499,11 +497,11 @@ void ext::gltf::load( pod::Graph& graph, const uf::stl::string& filename, const
|
|||||||
|
|
||||||
{
|
{
|
||||||
graph.images.emplace_back(atlasName);
|
graph.images.emplace_back(atlasName);
|
||||||
auto& image = /*graph.storage*/storage.images[atlasName];
|
auto& image = storage.images[atlasName];
|
||||||
image = atlas.getAtlas();
|
image = atlas.getAtlas();
|
||||||
|
|
||||||
graph.textures.emplace_back(atlasName);
|
graph.textures.emplace_back(atlasName);
|
||||||
auto& texture = /*graph.storage*/storage.textures[atlasName];
|
auto& texture = storage.textures[atlasName];
|
||||||
texture.index = atlasImageIndex;
|
texture.index = atlasImageIndex;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -543,7 +541,7 @@ void ext::gltf::load( pod::Graph& graph, const uf::stl::string& filename, const
|
|||||||
if ( !should ) continue;
|
if ( !should ) continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto& mesh = /*graph.storage*/storage.meshes[keyName];
|
auto& mesh = storage.meshes[keyName];
|
||||||
UF_MSG_DEBUG("Optimizing mesh at level {}: {}", level, keyName);
|
UF_MSG_DEBUG("Optimizing mesh at level {}: {}", level, keyName);
|
||||||
if ( !ext::meshopt::optimize( mesh, simplify, level, print ) ) {
|
if ( !ext::meshopt::optimize( mesh, simplify, level, print ) ) {
|
||||||
UF_MSG_ERROR("Mesh optimization failed: {}", keyName );
|
UF_MSG_ERROR("Mesh optimization failed: {}", keyName );
|
||||||
|
|||||||
@ -378,13 +378,18 @@ if ( meshopt.should ) {
|
|||||||
mesh.bindIndirect<pod::DrawCommand>();
|
mesh.bindIndirect<pod::DrawCommand>();
|
||||||
mesh.bind<UF_GRAPH_MESH_FORMAT>(false); // default to de-interleaved regardless of requirement (makes things easier)
|
mesh.bind<UF_GRAPH_MESH_FORMAT>(false); // default to de-interleaved regardless of requirement (makes things easier)
|
||||||
|
|
||||||
|
uf::stl::vector<pod::DrawCommand> drawCommands;
|
||||||
|
drawCommands.reserve( meshlets.size() );
|
||||||
|
primitives.reserve( meshlets.size() );
|
||||||
|
|
||||||
for ( auto& meshlet : meshlets ) {
|
for ( auto& meshlet : meshlets ) {
|
||||||
|
// to-do: check against the meshlet's actual primitive information
|
||||||
auto& drawCommand = drawCommands.emplace_back(pod::DrawCommand{
|
auto& drawCommand = drawCommands.emplace_back(pod::DrawCommand{
|
||||||
.indices = meshlet.indices.size(),
|
.indices = meshlet.indices.size(),
|
||||||
.instances = 1,
|
.instances = 1,
|
||||||
.indexID = indexID,
|
.indexID = indexID,
|
||||||
.vertexID = vertexID,
|
.vertexID = vertexID,
|
||||||
.instanceID = 0,
|
.instanceID = meshlet.primitive.drawCommand.instanceID,
|
||||||
.auxID = meshlet.primitive.drawCommand.auxID,
|
.auxID = meshlet.primitive.drawCommand.auxID,
|
||||||
.materialID = meshlet.primitive.drawCommand.materialID,
|
.materialID = meshlet.primitive.drawCommand.materialID,
|
||||||
.vertices = meshlet.vertices.size(),
|
.vertices = meshlet.vertices.size(),
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user