Commit for 2022.01.06 21-37-05.7z

This commit is contained in:
mrq 2022-01-06 21:37:00 -06:00
parent 112a061dc8
commit f45db51561
8 changed files with 145 additions and 93 deletions

View File

@ -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" }

View File

@ -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& );

View File

@ -245,7 +245,6 @@ namespace {
mesh.updateDescriptor();
return mesh;
// return mesh.interleave();
}
pod::Node decodeNode( ext::json::Value& json, pod::Graph& graph ) {

View File

@ -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

View File

@ -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;

View File

@ -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,

View File

@ -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;

View File

@ -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<ext::RENDERER::AttributeDescriptor>& descriptors ) const {