diff --git a/bin/data/scenes/ss2/medsci.json b/bin/data/scenes/ss2/medsci.json index 89daa7a7..14d4950e 100644 --- a/bin/data/scenes/ss2/medsci.json +++ b/bin/data/scenes/ss2/medsci.json @@ -1,9 +1,9 @@ { "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" } + // { "filename": "./models/tiny_msci/graph.json.gz", "delay": 0, "single threaded": false, "category": "models" } // { "filename": "./models/micro_sci.glb", "delay": 0, "single threaded": false, "category": "models" } // { "filename": "./models/micro_sci/graph.json", "delay": 0, "single threaded": false, "category": "models" } diff --git a/engine/inc/uf/utils/mesh/mesh.h b/engine/inc/uf/utils/mesh/mesh.h index 0769b36d..1101d028 100644 --- a/engine/inc/uf/utils/mesh/mesh.h +++ b/engine/inc/uf/utils/mesh/mesh.h @@ -109,7 +109,7 @@ namespace uf { void initialize(); void destroy(); - uf::Mesh interleave() const; + uf::Mesh convert( bool ) const; void updateDescriptor(); void bind( const uf::Mesh& ); diff --git a/engine/src/engine/graph/decode.cpp b/engine/src/engine/graph/decode.cpp index 1e093043..afd3c52a 100644 --- a/engine/src/engine/graph/decode.cpp +++ b/engine/src/engine/graph/decode.cpp @@ -245,7 +245,6 @@ namespace { mesh.updateDescriptor(); return mesh; - // return mesh.interleave(); } pod::Node decodeNode( ext::json::Value& json, pod::Graph& graph ) { diff --git a/engine/src/ext/opengl/commands.cpp b/engine/src/ext/opengl/commands.cpp index d1801402..a3ab216b 100644 --- a/engine/src/ext/opengl/commands.cpp +++ b/engine/src/ext/opengl/commands.cpp @@ -321,7 +321,7 @@ void ext::opengl::CommandBuffer::drawIndexed( const ext::opengl::CommandBuffer:: if ( drawInfo.attributes.normal.pointer ) GL_ERROR_CHECK(glNormalPointer(GL_FLOAT, drawInfo.attributes.normal.stride, drawInfo.attributes.normal.pointer)); if ( drawInfo.attributes.color.pointer ) GL_ERROR_CHECK(glColorPointer(4, GL_UNSIGNED_BYTE, drawInfo.attributes.color.stride, drawInfo.attributes.color.pointer)); GL_ERROR_CHECK(glVertexPointer(3, GL_FLOAT, drawInfo.attributes.position.stride, drawInfo.attributes.position.pointer)); - GL_ERROR_CHECK(glDrawElements(GL_TRIANGLES, drawInfo.attributes.index.length, indicesType, drawInfo.attributes.index.pointer)); + GL_ERROR_CHECK(glDrawElements(GL_TRIANGLES, drawInfo.attributes.index.length / drawInfo.attributes.index.stride, indicesType, drawInfo.attributes.index.pointer)); if ( drawInfo.textures.secondary.image ) { #if UF_ENV_DREAMCAST diff --git a/engine/src/ext/opengl/graphic.cpp b/engine/src/ext/opengl/graphic.cpp index 953ddcfb..fdc17990 100644 --- a/engine/src/ext/opengl/graphic.cpp +++ b/engine/src/ext/opengl/graphic.cpp @@ -395,11 +395,12 @@ void ext::opengl::Graphic::record( CommandBuffer& commandBuffer, const GraphicDe drawCommandInfo.attributes.index = descriptor.inputs.index.attributes.front(); drawCommandInfo.attributes.index.pointer = (void*) ((uint8_t*) drawCommandInfo.attributes.index.pointer + drawCommand.indexID * drawCommandInfo.attributes.index.stride); - drawCommandInfo.attributes.index.length = drawCommand.indices; + drawCommandInfo.attributes.index.length = drawCommand.indices * drawCommandInfo.attributes.index.stride; for ( uf::Mesh::Attribute attribute : descriptor.inputs.vertex.attributes ) { - attribute.pointer = (void*) ((uint8_t*) attribute.pointer + drawCommand.vertexID * attribute.stride); - attribute.length = drawCommand.vertices; + attribute.pointer += drawCommand.vertexID * attribute.stride; + attribute.length = drawCommand.vertices * attribute.stride; + // UF_MSG_DEBUG( attribute.descriptor.name << ": " << attribute.descriptor.offset << " " << attribute.pointer << " " << attribute.pointer - attribute.descriptor.offset ); if ( attribute.descriptor.name == "position" ) drawCommandInfo.attributes.position = attribute; else if ( attribute.descriptor.name == "uv" ) drawCommandInfo.attributes.uv = attribute; @@ -407,11 +408,10 @@ void ext::opengl::Graphic::record( CommandBuffer& commandBuffer, const GraphicDe else if ( attribute.descriptor.name == "normal" ) drawCommandInfo.attributes.normal = attribute; else if ( attribute.descriptor.name == "color" ) drawCommandInfo.attributes.color = attribute; } - /* for ( size_t i = 0; i < drawCommand.vertices; ++i ) { - float* p = (float*) (drawCommandInfo.attributes.position.pointer + i * drawCommandInfo.attributes.position.stride + drawCommandInfo.attributes.position.descriptor.offset); - float* uv = (float*) (drawCommandInfo.attributes.uv.pointer + i * drawCommandInfo.attributes.uv.stride + drawCommandInfo.attributes.uv.descriptor.offset); + float* p = (float*) (drawCommandInfo.attributes.position.pointer + i * drawCommandInfo.attributes.position.stride); + float* uv = (float*) (drawCommandInfo.attributes.uv.pointer + i * drawCommandInfo.attributes.uv.stride); std::cout << "(" << p[0] << ", " << p[1] << ", " << p[2] << "|" << uv[0] << ", " << uv[1] << ") "; } std::cout << std::endl; diff --git a/engine/src/ext/reactphysics/reactphysics.cpp b/engine/src/ext/reactphysics/reactphysics.cpp index ed484db0..9bef1f77 100644 --- a/engine/src/ext/reactphysics/reactphysics.cpp +++ b/engine/src/ext/reactphysics/reactphysics.cpp @@ -199,11 +199,11 @@ pod::PhysicsState& ext::reactphysics::create( uf::Object& object, const uf::Mesh remappedIndexAttribute = mesh.remapIndexAttribute( indexAttribute, i ); vArray = new rp3d::TriangleVertexArray( - remappedVertexAttribute.length, + remappedVertexAttribute.length / remappedVertexAttribute.stride, (const uint8_t*) remappedVertexAttribute.pointer, remappedVertexAttribute.stride, - remappedIndexAttribute.length / 3, + remappedIndexAttribute.length / remappedIndexAttribute.stride / 3, (const uint8_t*) remappedIndexAttribute.pointer, remappedIndexAttribute.stride * 3, @@ -215,11 +215,11 @@ pod::PhysicsState& ext::reactphysics::create( uf::Object& object, const uf::Mesh } } else { vArray = new rp3d::TriangleVertexArray( - vertexAttribute.length, + mesh.vertex.count, (const uint8_t*) vertexAttribute.pointer, vertexAttribute.stride, - indexAttribute.length / 3, + mesh.index.count / 3, (const uint8_t*) indexAttribute.pointer, indexAttribute.stride * 3, diff --git a/engine/src/ext/xatlas/xatlas.cpp b/engine/src/ext/xatlas/xatlas.cpp index b16ab273..21f348c2 100644 --- a/engine/src/ext/xatlas/xatlas.cpp +++ b/engine/src/ext/xatlas/xatlas.cpp @@ -96,13 +96,13 @@ pod::Vector2ui UF_API ext::xatlas::unwrap( pod::Graph& graph ) { entry.command = i; auto& decl = entry.decl; - decl.vertexCount = remappedUvAttribute.length; + decl.vertexCount = remappedPositionAttribute.length / remappedPositionAttribute.stride; decl.vertexPositionData = remappedPositionAttribute.pointer; decl.vertexPositionStride = remappedPositionAttribute.stride; decl.vertexUvData = remappedUvAttribute.pointer; decl.vertexUvStride = remappedUvAttribute.stride; - decl.indexCount = remappedIndexAttribute.length; + decl.indexCount = remappedIndexAttribute.length / remappedIndexAttribute.stride; decl.indexData = remappedIndexAttribute.pointer; decl.indexFormat = indexType; } @@ -111,13 +111,13 @@ pod::Vector2ui UF_API ext::xatlas::unwrap( pod::Graph& graph ) { entry.index = index; auto& decl = entry.decl; - decl.vertexCount = uvAttribute.length; + decl.vertexCount = mesh.vertex.count; decl.vertexPositionData = positionAttribute.pointer; decl.vertexPositionStride = positionAttribute.stride; decl.vertexUvData = uvAttribute.pointer; decl.vertexUvStride = uvAttribute.stride; - decl.indexCount = indexAttribute.length; + decl.indexCount = mesh.index.count; decl.indexData = indexAttribute.pointer; decl.indexFormat = indexType; decl.indexFormat = indexType; diff --git a/engine/src/utils/mesh/mesh.cpp b/engine/src/utils/mesh/mesh.cpp index 30f3df54..3fd2fb94 100644 --- a/engine/src/utils/mesh/mesh.cpp +++ b/engine/src/utils/mesh/mesh.cpp @@ -58,44 +58,42 @@ void uf::Mesh::destroy() { buffers.clear(); } -uf::Mesh uf::Mesh::interleave() const { - uf::Mesh interleaved; - interleaved.vertex.interleaved = true; - interleaved.index.interleaved = false; - interleaved.instance.interleaved = true; - interleaved.indirect.interleaved = false; - interleaved.bind(*this); +uf::Mesh uf::Mesh::convert( bool interleave ) const { + uf::Mesh res; - #define PARSE_INPUT_INTERLEAVED(N){\ - uf::Mesh::Input input = N;\ - interleaved.N = input;\ - auto& buffer = interleaved.buffers.at(interleaved.N.interleaved);\ - while ( input.count-- ) {\ - for ( auto& attribute : input.attributes ) {\ - buffer.insert( buffer.end(), (uint8_t*) attribute.pointer, (uint8_t*) attribute.pointer + attribute.descriptor.size );\ - attribute.pointer += input.stride;\ - }\ - }\ - } + // overkill but I don't want to rewrite a bind<>(); + res.vertex.attributes = vertex.attributes; + res.vertex.count = 0; + res.vertex.stride = vertex.stride; + res.vertex.offset = vertex.offset; - PARSE_INPUT_INTERLEAVED(vertex); - interleaved.insertIndices(*this); - PARSE_INPUT_INTERLEAVED(instance); - interleaved.insertIndirects(*this); -/* - auto& buffer = interleaved.buffers.emplace_back(); -#define PARSE_INPUT_INTERLEAVED(name) {\ - interleaved.name = name;\ - interleaved.name.offset = buffer.size();\ - if ( isInterleaved( name.interleaved ) ) buffer.insert( buffer.end(), buffers[name.interleaved].begin(), buffers[name.interleaved].end() );\ - else for ( auto& attribute : name.attributes ) buffer.insert( buffer.end(), buffers[attribute.buffer].begin(), buffers[attribute.buffer].end() );\ -} - PARSE_INPUT_INTERLEAVED(vertex); - PARSE_INPUT_INTERLEAVED(index); - PARSE_INPUT_INTERLEAVED(instance); - PARSE_INPUT_INTERLEAVED(indirect); -*/ - return interleaved; + res.index.attributes = index.attributes; + res.index.count = 0; + res.index.interleaved = -1; + res.index.stride = index.stride; + res.index.offset = index.offset; + + res.instance.attributes = instance.attributes; + res.instance.count = 0; + res.index.interleaved = -1; + res.instance.stride = instance.stride; + res.instance.offset = instance.offset; + res.indirect.attributes = indirect.attributes; + + res.indirect.count = 0; + res.indirect.interleaved = -1; + res.indirect.stride = indirect.stride; + res.indirect.offset = indirect.offset; + res._bind( interleave ); + + res.insertVertices(*this); + res.insertIndices(*this); + res.insertInstances(*this); + res.insertIndirects(*this); + + res.updateDescriptor(); + + return res; } void uf::Mesh::updateDescriptor() { _updateDescriptor(vertex); @@ -179,12 +177,12 @@ void uf::Mesh::print() const { str << "[" << i << "][" << attribute.descriptor.name << "]: ( "; switch ( attribute.descriptor.type ) { case uf::renderer::enums::Type::FLOAT: for ( auto j = 0; j < attribute.descriptor.components; ++j ) str << ((float*) (e + attribute.descriptor.offset))[j] << " "; break; - case uf::renderer::enums::Type::UINT: for ( auto j = 0; j < attribute.descriptor.components; ++j ) str << ((uint32_t*) (e + attribute.descriptor.offset))[j] << " "; break; - case uf::renderer::enums::Type::INT: for ( auto j = 0; j < attribute.descriptor.components; ++j ) str << ((int32_t*) (e + attribute.descriptor.offset))[j] << " "; break; - case uf::renderer::enums::Type::USHORT: for ( auto j = 0; j < attribute.descriptor.components; ++j ) str << ((uint16_t*) (e + attribute.descriptor.offset))[j] << " "; break; - case uf::renderer::enums::Type::SHORT: for ( auto j = 0; j < attribute.descriptor.components; ++j ) str << ((int16_t*) (e + attribute.descriptor.offset))[j] << " "; break; - case uf::renderer::enums::Type::UBYTE: for ( auto j = 0; j < attribute.descriptor.components; ++j ) str << ((uint8_t*) (e + attribute.descriptor.offset))[j] << " "; break; - case uf::renderer::enums::Type::BYTE: for ( auto j = 0; j < attribute.descriptor.components; ++j ) str << ((int8_t*) (e + attribute.descriptor.offset))[j] << " "; break; + case uf::renderer::enums::Type::UINT: for ( auto j = 0; j < attribute.descriptor.components; ++j ) str << (int) ((uint32_t*) (e + attribute.descriptor.offset))[j] << " "; break; + case uf::renderer::enums::Type::INT: for ( auto j = 0; j < attribute.descriptor.components; ++j ) str << (int) ((int32_t*) (e + attribute.descriptor.offset))[j] << " "; break; + case uf::renderer::enums::Type::USHORT: for ( auto j = 0; j < attribute.descriptor.components; ++j ) str << (int) ((uint16_t*) (e + attribute.descriptor.offset))[j] << " "; break; + case uf::renderer::enums::Type::SHORT: for ( auto j = 0; j < attribute.descriptor.components; ++j ) str << (int) ((int16_t*) (e + attribute.descriptor.offset))[j] << " "; break; + case uf::renderer::enums::Type::UBYTE: for ( auto j = 0; j < attribute.descriptor.components; ++j ) str << (int) ((uint8_t*) (e + attribute.descriptor.offset))[j] << " "; break; + case uf::renderer::enums::Type::BYTE: for ( auto j = 0; j < attribute.descriptor.components; ++j ) str << (int) ((int8_t*) (e + attribute.descriptor.offset))[j] << " "; break; } str << ")\n"; } @@ -193,16 +191,17 @@ void uf::Mesh::print() const { str << "[" << i << "][" << attribute.descriptor.name << "]: ( "; switch ( attribute.descriptor.type ) { case uf::renderer::enums::Type::FLOAT: for ( auto j = 0; j < attribute.descriptor.components; ++j ) str << ((float*) &buffer[i * attribute.descriptor.size])[j] << " "; break; - case uf::renderer::enums::Type::UINT: for ( auto j = 0; j < attribute.descriptor.components; ++j ) str << ((uint32_t*) &buffer[i * attribute.descriptor.size])[j] << " "; break; - case uf::renderer::enums::Type::INT: for ( auto j = 0; j < attribute.descriptor.components; ++j ) str << ((int32_t*) &buffer[i * attribute.descriptor.size])[j] << " "; break; - case uf::renderer::enums::Type::USHORT: for ( auto j = 0; j < attribute.descriptor.components; ++j ) str << ((uint16_t*) &buffer[i * attribute.descriptor.size])[j] << " "; break; - case uf::renderer::enums::Type::SHORT: for ( auto j = 0; j < attribute.descriptor.components; ++j ) str << ((int16_t*) &buffer[i * attribute.descriptor.size])[j] << " "; break; - case uf::renderer::enums::Type::UBYTE: for ( auto j = 0; j < attribute.descriptor.components; ++j ) str << ((uint8_t*) &buffer[i * attribute.descriptor.size])[j] << " "; break; - case uf::renderer::enums::Type::BYTE: for ( auto j = 0; j < attribute.descriptor.components; ++j ) str << ((int8_t*) &buffer[i * attribute.descriptor.size])[j] << " "; break; + case uf::renderer::enums::Type::UINT: for ( auto j = 0; j < attribute.descriptor.components; ++j ) str << (int) ((uint32_t*) &buffer[i * attribute.descriptor.size])[j] << " "; break; + case uf::renderer::enums::Type::INT: for ( auto j = 0; j < attribute.descriptor.components; ++j ) str << (int) ((int32_t*) &buffer[i * attribute.descriptor.size])[j] << " "; break; + case uf::renderer::enums::Type::USHORT: for ( auto j = 0; j < attribute.descriptor.components; ++j ) str << (int) ((uint16_t*) &buffer[i * attribute.descriptor.size])[j] << " "; break; + case uf::renderer::enums::Type::SHORT: for ( auto j = 0; j < attribute.descriptor.components; ++j ) str << (int) ((int16_t*) &buffer[i * attribute.descriptor.size])[j] << " "; break; + case uf::renderer::enums::Type::UBYTE: for ( auto j = 0; j < attribute.descriptor.components; ++j ) str << (int) ((uint8_t*) &buffer[i * attribute.descriptor.size])[j] << " "; break; + case uf::renderer::enums::Type::BYTE: for ( auto j = 0; j < attribute.descriptor.components; ++j ) str << (int) ((int8_t*) &buffer[i * attribute.descriptor.size])[j] << " "; break; } str << ")\n"; } } + str << "Indices: " << index.count << " | " << (isInterleaved(index.interleaved) ? "interleaved" : "deinterleaved") << "\n"; for ( auto i = 0; i < index.count; ++i ) { if ( isInterleaved(index.interleaved) ) { @@ -276,7 +275,8 @@ void uf::Mesh::_bind( bool interleave ) { PARSE_INPUT(vertex, interleave) PARSE_INPUT(index, false) - PARSE_INPUT(instance, interleave) +// PARSE_INPUT(instance, interleave) + PARSE_INPUT(instance, false) PARSE_INPUT(indirect, false) buffers.resize( buffer ); @@ -293,6 +293,7 @@ void uf::Mesh::_updateDescriptor( uf::Mesh::Input& input ) { attribute.length = buffer.size(); attribute.pointer = (void*) (buffer.data() + attribute.offset); if ( !interleaved ) attribute.stride = attribute.descriptor.size; + else attribute.pointer += attribute.descriptor.offset; input.stride += attribute.descriptor.size; } for ( auto& attribute : input.attributes ) { @@ -305,36 +306,36 @@ uf::Mesh::Attribute uf::Mesh::_remapAttribute( const uf::Mesh::Input& input, con if ( i < indirect.count ) { auto& drawCommand = ((const pod::DrawCommand*) buffers[isInterleaved(indirect.interleaved) ? indirect.interleaved : indirect.attributes.front().buffer].data())[i]; if ( &input == &vertex ) { - res.pointer = (void*) ((uint8_t*) res.pointer + drawCommand.vertexID * res.stride); - res.length = drawCommand.vertices; + res.pointer += drawCommand.vertexID * res.stride; + res.length = drawCommand.vertices * res.stride; } else if ( &input == &index ) { - res.pointer = (void*) ((uint8_t*) res.pointer + drawCommand.indexID * res.stride); - res.length = drawCommand.indices; + res.pointer += drawCommand.indexID * res.stride; + res.length = drawCommand.indices * res.stride; } } return res; } -void uf::Mesh::_insertVs( uf::Mesh::Input& input, const uf::Mesh& mesh, const uf::Mesh::Input& srcInput ) { - _reserveVs( input, input.count += srcInput.count ); +void uf::Mesh::_insertVs( uf::Mesh::Input& dstInput, const uf::Mesh& mesh, const uf::Mesh::Input& srcInput ) { + _reserveVs( dstInput, dstInput.count += srcInput.count ); // both meshes are interleaved, just copy directly - if ( isInterleaved(input.interleaved) && isInterleaved(srcInput.interleaved) ) { - if ( !_hasV( input, srcInput ) ) return; + if ( isInterleaved(dstInput.interleaved) && isInterleaved(srcInput.interleaved) ) { + if ( !_hasV( dstInput, srcInput ) ) return; auto& src = mesh.buffers[srcInput.interleaved]; - auto& dst = buffers[input.interleaved]; + auto& dst = buffers[dstInput.interleaved]; dst.insert( dst.end(), src.begin(), src.end() ); // both meshes are de-interleaved, just copy directly - } else if ( !isInterleaved(input.interleaved) && !isInterleaved(srcInput.interleaved) ) { - if ( _hasV( input, srcInput ) ) { - for ( auto i = 0; i < input.attributes.size(); ++i ) { + } else if ( !isInterleaved(dstInput.interleaved) && !isInterleaved(srcInput.interleaved) ) { + if ( _hasV( dstInput, srcInput ) ) { + for ( auto i = 0; i < dstInput.attributes.size(); ++i ) { auto& srcAttribute = srcInput.attributes[i]; - auto& dstAttribute = input.attributes[i]; + auto& dstAttribute = dstInput.attributes[i]; auto& src = mesh.buffers[srcAttribute.buffer]; auto& dst = buffers[dstAttribute.buffer]; dst.insert( dst.end(), src.begin(), src.end() ); } } else { - for ( auto& dstAttribute : input.attributes ) { + for ( auto& dstAttribute : dstInput.attributes ) { for ( auto& srcAttribute : srcInput.attributes ) { if ( srcAttribute.descriptor != dstAttribute.descriptor ) continue; @@ -347,34 +348,86 @@ void uf::Mesh::_insertVs( uf::Mesh::Input& input, const uf::Mesh& mesh, const uf } } // not easy to convert, will implement later + } else if ( isInterleaved(dstInput.interleaved) && !isInterleaved(srcInput.interleaved) ) { + // UF_EXCEPTION("to be implemented: deinterleaved -> interleaved"); + uf::Mesh::Input _srcInput = srcInput; + auto& dst = buffers.at(dstInput.interleaved); + size_t _ = 0; + while ( _++ < _srcInput.count ) { + for ( auto& srcAttribute : _srcInput.attributes ) { + dst.insert( dst.end(), (uint8_t*) srcAttribute.pointer, (uint8_t*) srcAttribute.pointer + srcAttribute.descriptor.size ); + srcAttribute.pointer += srcAttribute.descriptor.size; + } + } + } else if ( !isInterleaved(dstInput.interleaved) && isInterleaved(srcInput.interleaved) ) { + // UF_EXCEPTION("to be implemented: interleaved -> deinterleaved"); + uf::Mesh::Input _srcInput = _srcInput; + const uint8_t* src = (const uint8_t*) mesh.buffers.at(srcInput.interleaved).data(); + size_t _ = 0; + while ( _++ < _srcInput.count ) { + for ( size_t i = 0; i < dstInput.attributes.size(); ++i ) { + auto& srcAttribute = _srcInput.attributes.at(i); + auto& dstAttribute = dstInput.attributes.at(i); + + auto& dst = buffers.at(dstAttribute.buffer); + dst.insert( dst.end(), src, src + srcAttribute.descriptor.size ); + src += srcAttribute.descriptor.size; + } + } } else { - UF_EXCEPTION("to be implemented"); + UF_EXCEPTION("to be implemented: ??"); } - _updateDescriptor( input ); + _updateDescriptor( dstInput ); } -void uf::Mesh::_insertIs( uf::Mesh::Input& input, const uf::Mesh& mesh, const uf::Mesh::Input& srcInput ) { +void uf::Mesh::_insertIs( uf::Mesh::Input& dstInput, const uf::Mesh& mesh, const uf::Mesh::Input& srcInput ) { // if ( !_hasI( source ) ) return; - _reserveIs( input, input.count += srcInput.count ); + _reserveIs( dstInput, dstInput.count += srcInput.count ); // both meshes are interleaved, just copy directly - if ( isInterleaved(input.interleaved) && isInterleaved(srcInput.interleaved) ) { + if ( isInterleaved(dstInput.interleaved) && isInterleaved(srcInput.interleaved) ) { auto& src = mesh.buffers[srcInput.interleaved]; - auto& dst = buffers[input.interleaved]; + auto& dst = buffers[dstInput.interleaved]; dst.insert( dst.end(), src.begin(), src.end() ); // both meshes are de-interleaved, just copy directly - } else if ( !isInterleaved(input.interleaved) && !isInterleaved(srcInput.interleaved) ) { - for ( auto i = 0; i < input.attributes.size(); ++i ) { + } else if ( !isInterleaved(dstInput.interleaved) && !isInterleaved(srcInput.interleaved) ) { + for ( auto i = 0; i < dstInput.attributes.size(); ++i ) { auto& srcAttribute = srcInput.attributes[i]; - auto& dstAttribute = input.attributes[i]; + auto& dstAttribute = dstInput.attributes[i]; auto& src = mesh.buffers[srcAttribute.buffer]; auto& dst = buffers[dstAttribute.buffer]; dst.insert( dst.end(), src.begin(), src.end() ); } // not easy to convert, will implement later + } else if ( isInterleaved(dstInput.interleaved) && !isInterleaved(srcInput.interleaved) ) { + // UF_EXCEPTION("to be implemented: deinterleaved -> interleaved"); + uf::Mesh::Input _srcInput = srcInput; + auto& dst = buffers.at(dstInput.interleaved); + size_t _ = 0; + while ( _++ < _srcInput.count ) { + for ( auto& srcAttribute : _srcInput.attributes ) { + dst.insert( dst.end(), (uint8_t*) srcAttribute.pointer, (uint8_t*) srcAttribute.pointer + srcAttribute.descriptor.size ); + srcAttribute.pointer += srcAttribute.descriptor.size; + } + } + } else if ( !isInterleaved(dstInput.interleaved) && isInterleaved(srcInput.interleaved) ) { + // UF_EXCEPTION("to be implemented: interleaved -> deinterleaved"); + uf::Mesh::Input _srcInput = _srcInput; + const uint8_t* src = (const uint8_t*) mesh.buffers.at(srcInput.interleaved).data(); + size_t _ = 0; + while ( _++ < _srcInput.count ) { + for ( size_t i = 0; i < dstInput.attributes.size(); ++i ) { + auto& srcAttribute = _srcInput.attributes.at(i); + auto& dstAttribute = dstInput.attributes.at(i); + + auto& dst = buffers.at(dstAttribute.buffer); + dst.insert( dst.end(), src, src + srcAttribute.descriptor.size ); + src += srcAttribute.descriptor.size; + } + } } else { - UF_EXCEPTION("to be implemented"); + UF_EXCEPTION("to be implemented: ??"); } - _updateDescriptor( input ); + _updateDescriptor( dstInput ); } // Vertices bool uf::Mesh::_hasV( const uf::Mesh::Input& input, const uf::stl::vector& descriptors ) const {