shuffled code around for when I figure out how I want to stream a partitioned mesh (even though this defeats the purpose of re-implementing the chunk/region system because I do not want to go about splitting each region into its own model-entity-graph-whatever)
This commit is contained in:
parent
cf9a4c9a9d
commit
a9b5a03f94
2
Makefile
2
Makefile
@ -55,7 +55,7 @@ FLAGS += -DUF_DEV_ENV
|
|||||||
ifneq (,$(findstring win64,$(ARCH)))
|
ifneq (,$(findstring win64,$(ARCH)))
|
||||||
ifneq (,$(findstring -DUF_DEV_ENV,$(FLAGS)))
|
ifneq (,$(findstring -DUF_DEV_ENV,$(FLAGS)))
|
||||||
REQ_DEPS += meshoptimizer toml xatlas curl ffx:fsr cpptrace vall_e # ncurses openvr draco discord bullet ultralight-ux
|
REQ_DEPS += meshoptimizer toml xatlas curl ffx:fsr cpptrace vall_e # ncurses openvr draco discord bullet ultralight-ux
|
||||||
FLAGS += -march=native -flto # -g
|
FLAGS += -march=native # -flto # -g
|
||||||
endif
|
endif
|
||||||
REQ_DEPS += $(RENDERER) json:nlohmann zlib luajit reactphysics simd ctti gltf imgui fmt freetype openal ogg wav
|
REQ_DEPS += $(RENDERER) json:nlohmann zlib luajit reactphysics simd ctti gltf imgui fmt freetype openal ogg wav
|
||||||
FLAGS += -DUF_ENV_WINDOWS -DUF_ENV_WIN64 -DWIN32_LEAN_AND_MEAN
|
FLAGS += -DUF_ENV_WINDOWS -DUF_ENV_WIN64 -DWIN32_LEAN_AND_MEAN
|
||||||
|
@ -3,8 +3,10 @@
|
|||||||
"assets": [
|
"assets": [
|
||||||
// { "filename": "./models/ss2_medsci1.glb" }
|
// { "filename": "./models/ss2_medsci1.glb" }
|
||||||
// { "filename": "./models/ss2_medsci1/graph.json" }
|
// { "filename": "./models/ss2_medsci1/graph.json" }
|
||||||
// { "filename": "./models/ss2_medsci1_smallish/graph.json" }
|
// { "filename": "./models/ss2_medsci1_small.glb" }
|
||||||
{ "filename": "./models/ss2_medsci1_small/graph.json" }
|
{ "filename": "./models/ss2_medsci1_small/graph.json" }
|
||||||
|
// { "filename": "./models/ss2_medsci1_smallish.glb" }
|
||||||
|
// { "filename": "./models/ss2_medsci1_smallish/graph.json" }
|
||||||
],
|
],
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"graph": {
|
"graph": {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"engine": {
|
"engine": {
|
||||||
"scenes": {
|
"scenes": {
|
||||||
"start": "SourceEngine",
|
"start": "StartMenu",
|
||||||
"matrix": { "reverseInfinite": true },
|
"matrix": { "reverseInfinite": true },
|
||||||
"meshes": { "interleaved": false },
|
"meshes": { "interleaved": false },
|
||||||
"lights": { "enabled": true,
|
"lights": { "enabled": true,
|
||||||
|
@ -152,6 +152,8 @@ namespace uf {
|
|||||||
|
|
||||||
uf::stl::string UF_API print( const pod::Graph& graph );
|
uf::stl::string UF_API print( const pod::Graph& graph );
|
||||||
uf::Serializer UF_API stats( const pod::Graph& graph );
|
uf::Serializer UF_API stats( const pod::Graph& graph );
|
||||||
|
void UF_API reload( pod::Graph& graph );
|
||||||
|
void UF_API reload( pod::Graph& graph, pod::Node& node );
|
||||||
void UF_API reload();
|
void UF_API reload();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -83,55 +83,6 @@ namespace uf {
|
|||||||
|
|
||||||
uf::meshgrid::calculate( grid, eps );
|
uf::meshgrid::calculate( grid, eps );
|
||||||
|
|
||||||
// it's better to naively clip the mesh multiple times rather than calculate the triangles needed to clip
|
|
||||||
/*
|
|
||||||
if ( clip ) {
|
|
||||||
for ( auto& pair : grid.nodes ) {
|
|
||||||
++atlasID;
|
|
||||||
for ( auto& meshlet : meshlets ) {
|
|
||||||
auto& node = pair.second;
|
|
||||||
|
|
||||||
uf::stl::vector<T> vertices = meshlet.vertices;
|
|
||||||
uf::stl::vector<U> indices = meshlet.indices;
|
|
||||||
|
|
||||||
uf::shapes::clip<T,U>( vertices, indices, node.extents.min, node.extents.max );
|
|
||||||
|
|
||||||
if ( vertices.empty() || indices.empty() ) continue;
|
|
||||||
|
|
||||||
size_t primitiveID = partitioned.size();
|
|
||||||
auto& slice = partitioned.emplace_back();
|
|
||||||
|
|
||||||
slice.vertices = std::move( vertices );
|
|
||||||
slice.indices = std::move( indices );
|
|
||||||
|
|
||||||
for ( auto& vertex : slice.vertices ) {
|
|
||||||
vertex.id.x = primitiveID;
|
|
||||||
vertex.id.y = meshlet.primitive.instance.meshID;
|
|
||||||
}
|
|
||||||
|
|
||||||
slice.primitive.instance = meshlet.primitive.instance;
|
|
||||||
slice.primitive.instance.materialID = meshlet.primitive.instance.materialID;
|
|
||||||
slice.primitive.instance.primitiveID = primitiveID;
|
|
||||||
slice.primitive.instance.meshID = meshlet.primitive.instance.meshID;
|
|
||||||
slice.primitive.instance.objectID = 0;
|
|
||||||
slice.primitive.instance.auxID = atlasID;
|
|
||||||
slice.primitive.instance.bounds.min = node.extents.min;
|
|
||||||
slice.primitive.instance.bounds.max = node.extents.max;
|
|
||||||
|
|
||||||
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.auxID = atlasID; // meshlet.primitive.instance.meshID;
|
|
||||||
slice.primitive.drawCommand.vertices = slice.vertices.size();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return partitioned;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
for ( auto& meshlet : meshlets ) uf::meshgrid::partition<T,U>( grid, meshlet.vertices, meshlet.indices, meshlet.primitive );
|
for ( auto& meshlet : meshlets ) uf::meshgrid::partition<T,U>( grid, meshlet.vertices, meshlet.indices, meshlet.primitive );
|
||||||
if ( cleanup ) uf::meshgrid::cleanup( grid );
|
if ( cleanup ) uf::meshgrid::cleanup( grid );
|
||||||
|
|
||||||
@ -155,14 +106,6 @@ namespace uf {
|
|||||||
vertex.id.y = meshlet.primitive.instance.meshID;
|
vertex.id.y = meshlet.primitive.instance.meshID;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
if ( clip ) {
|
|
||||||
node.effectiveExtents.min = node.extents.min;
|
|
||||||
node.effectiveExtents.max = node.extents.max;
|
|
||||||
uf::shapes::clip<T,U>( slice.vertices, slice.indices, node.extents.min, node.extents.max );
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
slice.primitive.instance = meshlet.primitive.instance;
|
slice.primitive.instance = meshlet.primitive.instance;
|
||||||
slice.primitive.instance.materialID = meshlet.primitive.instance.materialID;
|
slice.primitive.instance.materialID = meshlet.primitive.instance.materialID;
|
||||||
slice.primitive.instance.primitiveID = primitiveID;
|
slice.primitive.instance.primitiveID = primitiveID;
|
||||||
|
@ -65,6 +65,11 @@ namespace {
|
|||||||
sampler.descriptor.addressMode.u = (uf::renderer::enums::AddressMode::type_t) json["u"].as<size_t>();
|
sampler.descriptor.addressMode.u = (uf::renderer::enums::AddressMode::type_t) json["u"].as<size_t>();
|
||||||
sampler.descriptor.addressMode.v = (uf::renderer::enums::AddressMode::type_t) json["v"].as<size_t>();
|
sampler.descriptor.addressMode.v = (uf::renderer::enums::AddressMode::type_t) json["v"].as<size_t>();
|
||||||
sampler.descriptor.addressMode.w = sampler.descriptor.addressMode.v;
|
sampler.descriptor.addressMode.w = sampler.descriptor.addressMode.v;
|
||||||
|
|
||||||
|
#if UF_ENV_DREAMCAST
|
||||||
|
sampler.descriptor.filter.min = uf::renderer::enums::Filter::NEAREST;
|
||||||
|
sampler.descriptor.filter.mag = uf::renderer::enums::Filter::NEAREST;
|
||||||
|
#endif
|
||||||
|
|
||||||
return sampler;
|
return sampler;
|
||||||
}
|
}
|
||||||
|
@ -226,6 +226,7 @@ void uf::graph::initializeGraphics( pod::Graph& graph, uf::Object& entity, uf::M
|
|||||||
auto& sceneMetadataJson = scene.getComponent<uf::Serializer>();
|
auto& sceneMetadataJson = scene.getComponent<uf::Serializer>();
|
||||||
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>();
|
||||||
|
|
||||||
|
|
||||||
auto& graphic = entity.getComponent<uf::renderer::Graphic>();
|
auto& graphic = entity.getComponent<uf::renderer::Graphic>();
|
||||||
graphic.initialize();
|
graphic.initialize();
|
||||||
graphic.initializeMesh( mesh );
|
graphic.initializeMesh( mesh );
|
||||||
@ -1217,132 +1218,9 @@ void uf::graph::process( pod::Graph& graph ) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
UF_DEBUG_TIMER_MULTITRACE("Updating master graph");
|
UF_DEBUG_TIMER_MULTITRACE("Updating master graph");
|
||||||
|
uf::graph::reload( graph );
|
||||||
uf::graph::reload();
|
uf::graph::reload();
|
||||||
|
|
||||||
// setup combined mesh if requested
|
|
||||||
if ( !(graph.metadata["renderer"]["separate"].as<bool>()) ) {
|
|
||||||
UF_DEBUG_TIMER_MULTITRACE("Processing root graphic");
|
|
||||||
|
|
||||||
graph.root.mesh = graph.meshes.size();
|
|
||||||
auto keyName = graph.name + "/" + graph.root.name;
|
|
||||||
auto& mesh = storage.meshes[graph.meshes.emplace_back(keyName)];
|
|
||||||
|
|
||||||
mesh.bindIndirect<pod::DrawCommand>();
|
|
||||||
#if UF_ENV_DREAMCAST
|
|
||||||
mesh.bind<uf::graph::mesh::Base, uint32_t>();
|
|
||||||
#else
|
|
||||||
mesh.bind<uf::graph::mesh::Skinned, uint32_t>();
|
|
||||||
#endif
|
|
||||||
/*
|
|
||||||
{
|
|
||||||
#if UF_ENV_DREAMCAST
|
|
||||||
mesh.bind<uf::graph::mesh::Base_u16q, uint32_t>();
|
|
||||||
// mesh.convert<float, uint16_t>();
|
|
||||||
#else
|
|
||||||
auto conversion = graph.metadata["decode"]["conversion"].as<uf::stl::string>();
|
|
||||||
if ( conversion != "" ) {
|
|
||||||
if ( conversion == "uint16_t" ) mesh.bind<uf::graph::mesh::Skinned_16f, uint32_t>();
|
|
||||||
#if UF_USE_FLOAT16
|
|
||||||
else if ( conversion == "float16" ) mesh.bind<uf::graph::mesh::Skinned_16f, uint32_t>();
|
|
||||||
#endif
|
|
||||||
#if UF_USE_BFLOAT16
|
|
||||||
else if ( conversion == "bfloat16" ) mesh.bind<uf::graph::mesh::Skinned_16f, uint32_t>();
|
|
||||||
#endif
|
|
||||||
else mesh.bind<uf::graph::mesh::Skinned, uint32_t>();
|
|
||||||
} else mesh.bind<uf::graph::mesh::Skinned, uint32_t>();
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
uf::stl::vector<pod::DrawCommand> drawCommands;
|
|
||||||
|
|
||||||
size_t counts = 0;
|
|
||||||
for ( auto& name : graph.meshes ) {
|
|
||||||
if ( name == keyName ) continue;
|
|
||||||
auto tag = ext::json::find( name, graph.metadata["tags"] );
|
|
||||||
if ( ext::json::isObject( tag ) ) {
|
|
||||||
if ( tag["ignore"].as<bool>() ) continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto& m = storage.meshes.map[name];
|
|
||||||
m.updateDescriptor();
|
|
||||||
|
|
||||||
mesh.insertVertices( m );
|
|
||||||
mesh.insertIndices( m );
|
|
||||||
mesh.insertInstances( m );
|
|
||||||
|
|
||||||
// mesh.insertIndirects( m );
|
|
||||||
pod::DrawCommand* drawCommand = (pod::DrawCommand*) m.getBuffer( m.indirect ).data();
|
|
||||||
for ( size_t i = 0; i < m.indirect.count; ++i ) drawCommands.emplace_back( drawCommand[i] );
|
|
||||||
}
|
|
||||||
|
|
||||||
// fix up draw command for combined mesh
|
|
||||||
{
|
|
||||||
size_t totalIndices = 0;
|
|
||||||
size_t totalVertices = 0;
|
|
||||||
for ( auto& drawCommand : drawCommands ) {
|
|
||||||
drawCommand.indexID = totalIndices;
|
|
||||||
drawCommand.vertexID = totalVertices;
|
|
||||||
|
|
||||||
totalIndices += drawCommand.indices;
|
|
||||||
totalVertices += drawCommand.vertices;
|
|
||||||
}
|
|
||||||
|
|
||||||
mesh.insertIndirects( drawCommands );
|
|
||||||
}
|
|
||||||
|
|
||||||
#if UF_ENV_DREAMCAST
|
|
||||||
{
|
|
||||||
uf::stl::vector<uf::stl::string> attributesKept = ext::json::vector<uf::stl::string>(graph.metadata["decode"]["attributes"]);
|
|
||||||
if ( !mesh.isInterleaved() ) {
|
|
||||||
uf::stl::vector<size_t> remove; remove.reserve(mesh.vertex.attributes.size());
|
|
||||||
|
|
||||||
for ( size_t i = 0; i < mesh.vertex.attributes.size(); ++i ) {
|
|
||||||
auto& attribute = mesh.vertex.attributes[i];
|
|
||||||
if ( std::find( attributesKept.begin(), attributesKept.end(), attribute.descriptor.name ) != attributesKept.end() ) continue;
|
|
||||||
remove.insert(remove.begin(), i);
|
|
||||||
UF_MSG_DEBUG("Removing mesh attribute: {}", attribute.descriptor.name);
|
|
||||||
}
|
|
||||||
for ( auto& i : remove ) {
|
|
||||||
mesh.buffers[mesh.vertex.attributes[i].buffer].clear();
|
|
||||||
mesh.buffers[mesh.vertex.attributes[i].buffer].shrink_to_fit();
|
|
||||||
mesh.vertex.attributes.erase(mesh.vertex.attributes.begin() + i);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
UF_MSG_DEBUG("Attribute removal requested yet mesh is interleaved, ignoring...");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
{
|
|
||||||
#if UF_ENV_DREAMCAST && GL_QUANTIZED_SHORT
|
|
||||||
mesh.convert<float, uint16_t>();
|
|
||||||
UF_MSG_DEBUG("Quantizing mesh to GL_QUANTIZED_SHORT");
|
|
||||||
#else
|
|
||||||
auto conversion = graph.metadata["decode"]["conversion"].as<uf::stl::string>();
|
|
||||||
if ( conversion != "" ) {
|
|
||||||
#if UF_USE_FLOAT16
|
|
||||||
if ( conversion == "float16" ) mesh.convert<float, float16>();
|
|
||||||
else if ( conversion == "float" ) mesh.convert<float16, float>();
|
|
||||||
#endif
|
|
||||||
#if UF_USE_BFLOAT16
|
|
||||||
if ( conversion == "bfloat16" ) mesh.convert<float, bfloat16>();
|
|
||||||
else if ( conversion == "float" ) mesh.convert<bfloat16, float>();
|
|
||||||
#endif
|
|
||||||
if ( conversion == "uint16_t" ) mesh.convert<float, uint16_t>();
|
|
||||||
else if ( conversion == "float" ) mesh.convert<uint16_t, float>();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
mesh.updateDescriptor();
|
|
||||||
|
|
||||||
{
|
|
||||||
auto& graphic = graph.root.entity->getComponent<uf::renderer::Graphic>();
|
|
||||||
uf::graph::initializeGraphics( graph, *graph.root.entity, mesh );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
storage.instanceAddresses.keys = storage.instances.keys;
|
storage.instanceAddresses.keys = storage.instances.keys;
|
||||||
UF_DEBUG_TIMER_MULTITRACE_END("Processed graph.");
|
UF_DEBUG_TIMER_MULTITRACE_END("Processed graph.");
|
||||||
}
|
}
|
||||||
@ -1520,7 +1398,8 @@ void uf::graph::process( pod::Graph& graph, int32_t index, uf::Object& parent )
|
|||||||
size_t objectID = storage.entities.keys.size();
|
size_t objectID = storage.entities.keys.size();
|
||||||
auto objectKeyName = std::to_string(objectID);
|
auto objectKeyName = std::to_string(objectID);
|
||||||
storage.entities[objectKeyName] = &entity;
|
storage.entities[objectKeyName] = &entity;
|
||||||
|
|
||||||
|
//
|
||||||
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]];
|
||||||
@ -1553,9 +1432,6 @@ void uf::graph::process( pod::Graph& graph, int32_t index, uf::Object& parent )
|
|||||||
drawCommand.instanceID = instanceID;
|
drawCommand.instanceID = instanceID;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ( (graph.metadata["renderer"]["separate"].as<bool>()) && graph.metadata["renderer"]["render"].as<bool>() ) {
|
|
||||||
uf::graph::initializeGraphics( graph, entity, mesh );
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
{
|
||||||
auto phyziks = tag["physics"];
|
auto phyziks = tag["physics"];
|
||||||
@ -1565,16 +1441,7 @@ void uf::graph::process( pod::Graph& graph, int32_t index, uf::Object& parent )
|
|||||||
if ( ext::json::isObject( phyziks ) ) {
|
if ( ext::json::isObject( phyziks ) ) {
|
||||||
uf::stl::string type = phyziks["type"].as<uf::stl::string>();
|
uf::stl::string type = phyziks["type"].as<uf::stl::string>();
|
||||||
|
|
||||||
if ( type == "mesh" ) {
|
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 min = uf::matrix::multiply<float>( model, bounds.min, 1.0f );
|
||||||
auto max = uf::matrix::multiply<float>( model, bounds.max, 1.0f );
|
auto max = uf::matrix::multiply<float>( model, bounds.max, 1.0f );
|
||||||
|
|
||||||
@ -1587,6 +1454,7 @@ void uf::graph::process( pod::Graph& graph, int32_t index, uf::Object& parent )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for ( auto index : node.children ) uf::graph::process( graph, index, entity );
|
for ( auto index : node.children ) uf::graph::process( graph, index, entity );
|
||||||
}
|
}
|
||||||
void uf::graph::cleanup( pod::Graph& graph ) {
|
void uf::graph::cleanup( pod::Graph& graph ) {
|
||||||
@ -1988,6 +1856,174 @@ void uf::graph::destroy( pod::Graph::Storage& storage, bool soft ) {
|
|||||||
|
|
||||||
uf::renderer::states::rebuild = true;
|
uf::renderer::states::rebuild = true;
|
||||||
}
|
}
|
||||||
|
void uf::graph::reload( pod::Graph& graph, pod::Node& node ) {
|
||||||
|
if ( !(0 <= node.mesh && node.mesh < graph.meshes.size()) ) return;
|
||||||
|
|
||||||
|
auto& scene = uf::scene::getCurrentScene();
|
||||||
|
auto& storage = uf::graph::globalStorage ? uf::graph::storage : scene.getComponent<pod::Graph::Storage>();
|
||||||
|
|
||||||
|
auto& entity = node.entity->as<uf::Object>();
|
||||||
|
|
||||||
|
auto& metadata = entity.getComponent<uf::ObjectBehavior::Metadata>();
|
||||||
|
auto& metadataJson = entity.getComponent<uf::Serializer>();
|
||||||
|
auto& transform = entity.getComponent<pod::Transform<>>();
|
||||||
|
|
||||||
|
ext::json::Value tag = ext::json::find( node.name, graph.metadata["tags"] );
|
||||||
|
|
||||||
|
if ( 0 <= node.mesh && node.mesh < graph.meshes.size() ) {
|
||||||
|
auto model = uf::transform::model( transform );
|
||||||
|
auto& mesh = storage.meshes.map[graph.meshes[node.mesh]];
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
if ( (graph.metadata["renderer"]["separate"].as<bool>()) && graph.metadata["renderer"]["render"].as<bool>() ) {
|
||||||
|
#endif
|
||||||
|
if ( graph.metadata["renderer"]["render"].as<bool>() ) {
|
||||||
|
bool exists = entity.hasComponent<uf::renderer::Graphic>();
|
||||||
|
if ( exists ) {
|
||||||
|
auto& graphic = entity.getComponent<uf::renderer::Graphic>();
|
||||||
|
graphic.updateMesh( mesh );
|
||||||
|
} else {
|
||||||
|
uf::graph::initializeGraphics( graph, entity, mesh );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
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" ) {
|
||||||
|
bool exists = entity.hasComponent<pod::PhysicsState>();
|
||||||
|
if ( exists ) {
|
||||||
|
uf::physics::terminate( entity );
|
||||||
|
// entity.deleteComponent<pod::PhysicsState>();
|
||||||
|
}
|
||||||
|
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, mesh, !phyziks["static"].as<bool>(true) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void uf::graph::reload( pod::Graph& graph ) {
|
||||||
|
// update graphics
|
||||||
|
for ( auto& node : graph.nodes ) uf::graph::reload( graph, node );
|
||||||
|
|
||||||
|
// setup combined mesh if requested
|
||||||
|
// disabled for now
|
||||||
|
#if 0
|
||||||
|
if ( !(graph.metadata["renderer"]["separate"].as<bool>()) ) {
|
||||||
|
UF_DEBUG_TIMER_MULTITRACE("Processing root graphic");
|
||||||
|
|
||||||
|
graph.root.mesh = graph.meshes.size();
|
||||||
|
auto keyName = graph.name + "/" + graph.root.name;
|
||||||
|
auto& mesh = storage.meshes[graph.meshes.emplace_back(keyName)];
|
||||||
|
|
||||||
|
mesh.bindIndirect<pod::DrawCommand>();
|
||||||
|
#if UF_ENV_DREAMCAST
|
||||||
|
mesh.bind<uf::graph::mesh::Base, uint32_t>();
|
||||||
|
#else
|
||||||
|
mesh.bind<uf::graph::mesh::Skinned, uint32_t>();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
uf::stl::vector<pod::DrawCommand> drawCommands;
|
||||||
|
|
||||||
|
size_t counts = 0;
|
||||||
|
for ( auto& name : graph.meshes ) {
|
||||||
|
if ( name == keyName ) continue;
|
||||||
|
auto tag = ext::json::find( name, graph.metadata["tags"] );
|
||||||
|
if ( ext::json::isObject( tag ) ) {
|
||||||
|
if ( tag["ignore"].as<bool>() ) continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto& m = storage.meshes.map[name];
|
||||||
|
m.updateDescriptor();
|
||||||
|
|
||||||
|
mesh.insertVertices( m );
|
||||||
|
mesh.insertIndices( m );
|
||||||
|
mesh.insertInstances( m );
|
||||||
|
|
||||||
|
// mesh.insertIndirects( m );
|
||||||
|
pod::DrawCommand* drawCommand = (pod::DrawCommand*) m.getBuffer( m.indirect ).data();
|
||||||
|
for ( size_t i = 0; i < m.indirect.count; ++i ) drawCommands.emplace_back( drawCommand[i] );
|
||||||
|
}
|
||||||
|
|
||||||
|
// fix up draw command for combined mesh
|
||||||
|
{
|
||||||
|
size_t totalIndices = 0;
|
||||||
|
size_t totalVertices = 0;
|
||||||
|
for ( auto& drawCommand : drawCommands ) {
|
||||||
|
drawCommand.indexID = totalIndices;
|
||||||
|
drawCommand.vertexID = totalVertices;
|
||||||
|
|
||||||
|
totalIndices += drawCommand.indices;
|
||||||
|
totalVertices += drawCommand.vertices;
|
||||||
|
}
|
||||||
|
|
||||||
|
mesh.insertIndirects( drawCommands );
|
||||||
|
}
|
||||||
|
|
||||||
|
#if UF_ENV_DREAMCAST
|
||||||
|
{
|
||||||
|
uf::stl::vector<uf::stl::string> attributesKept = ext::json::vector<uf::stl::string>(graph.metadata["decode"]["attributes"]);
|
||||||
|
if ( !mesh.isInterleaved() ) {
|
||||||
|
uf::stl::vector<size_t> remove; remove.reserve(mesh.vertex.attributes.size());
|
||||||
|
|
||||||
|
for ( size_t i = 0; i < mesh.vertex.attributes.size(); ++i ) {
|
||||||
|
auto& attribute = mesh.vertex.attributes[i];
|
||||||
|
if ( std::find( attributesKept.begin(), attributesKept.end(), attribute.descriptor.name ) != attributesKept.end() ) continue;
|
||||||
|
remove.insert(remove.begin(), i);
|
||||||
|
UF_MSG_DEBUG("Removing mesh attribute: {}", attribute.descriptor.name);
|
||||||
|
}
|
||||||
|
for ( auto& i : remove ) {
|
||||||
|
mesh.buffers[mesh.vertex.attributes[i].buffer].clear();
|
||||||
|
mesh.buffers[mesh.vertex.attributes[i].buffer].shrink_to_fit();
|
||||||
|
mesh.vertex.attributes.erase(mesh.vertex.attributes.begin() + i);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
UF_MSG_DEBUG("Attribute removal requested yet mesh is interleaved, ignoring...");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
{
|
||||||
|
#if UF_ENV_DREAMCAST && GL_QUANTIZED_SHORT
|
||||||
|
mesh.convert<float, uint16_t>();
|
||||||
|
UF_MSG_DEBUG("Quantizing mesh to GL_QUANTIZED_SHORT");
|
||||||
|
#else
|
||||||
|
auto conversion = graph.metadata["decode"]["conversion"].as<uf::stl::string>();
|
||||||
|
if ( conversion != "" ) {
|
||||||
|
#if UF_USE_FLOAT16
|
||||||
|
if ( conversion == "float16" ) mesh.convert<float, float16>();
|
||||||
|
else if ( conversion == "float" ) mesh.convert<float16, float>();
|
||||||
|
#endif
|
||||||
|
#if UF_USE_BFLOAT16
|
||||||
|
if ( conversion == "bfloat16" ) mesh.convert<float, bfloat16>();
|
||||||
|
else if ( conversion == "float" ) mesh.convert<bfloat16, float>();
|
||||||
|
#endif
|
||||||
|
if ( conversion == "uint16_t" ) mesh.convert<float, uint16_t>();
|
||||||
|
else if ( conversion == "float" ) mesh.convert<uint16_t, float>();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
mesh.updateDescriptor();
|
||||||
|
|
||||||
|
{
|
||||||
|
auto& graphic = graph.root.entity->getComponent<uf::renderer::Graphic>();
|
||||||
|
uf::graph::initializeGraphics( graph, *graph.root.entity, mesh );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
void uf::graph::reload() {
|
void uf::graph::reload() {
|
||||||
::newGraphAdded = true;
|
::newGraphAdded = true;
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user