From faa9207d010f77287c5b49b4e4180c9adbef7b1b Mon Sep 17 00:00:00 2001 From: HarrievG Date: Fri, 10 Jun 2022 10:27:17 +0200 Subject: [PATCH] - Fixed GLTF Mesh -> Polygon Mesh creaton --- neo/idlib/MapFile.cpp | 16 +- neo/idlib/MapFile.h | 2 +- neo/renderer/Model_gltf.cpp | 418 ++++++++++++++++++------------------ 3 files changed, 211 insertions(+), 225 deletions(-) diff --git a/neo/idlib/MapFile.cpp b/neo/idlib/MapFile.cpp index 5a119944..5baa75fb 100644 --- a/neo/idlib/MapFile.cpp +++ b/neo/idlib/MapFile.cpp @@ -1448,12 +1448,11 @@ idMapEntity::GetGeometryCRC */ unsigned int idMapEntity::GetGeometryCRC() const { - int i; unsigned int crc; idMapPrimitive* mapPrim; crc = 0; - for( i = 0; i < GetNumPrimitives(); i++ ) + for(int i = 0; i < GetNumPrimitives(); i++ ) { mapPrim = GetPrimitive( i ); @@ -2773,22 +2772,17 @@ void MapPolygonMesh::SetContents() unsigned int MapPolygonMesh::GetGeometryCRC() const { - int i; - unsigned int crc; - - crc = 0; + unsigned int i; + unsigned int crc = 0; for( i = 0; i < verts.Num(); i++ ) { - crc ^= FloatCRC( verts[i].xyz.x ); - crc ^= FloatCRC( verts[i].xyz.y ); - crc ^= FloatCRC( verts[i].xyz.z ); + crc ^= StringCRC((verts[i].xyz * (i+1)).ToString()); } for( i = 0; i < polygons.Num(); i++ ) { const MapPolygon& poly = polygons[i]; - - crc ^= StringCRC( poly.GetMaterial() ); + crc ^= StringCRC( poly.GetMaterial() + idStr(i) ); } return crc; diff --git a/neo/idlib/MapFile.h b/neo/idlib/MapFile.h index e20f5427..b1798551 100644 --- a/neo/idlib/MapFile.h +++ b/neo/idlib/MapFile.h @@ -349,7 +349,7 @@ public: void ConvertFromBrush( const idMapBrush* brush, int entityNum, int primitiveNum ); void ConvertFromPatch( const idMapPatch* patch, int entityNum, int primitiveNum ); - void ConvertFromMeshGltf( const gltfMesh* mesh , gltfData* data ); + static MapPolygonMesh* ConvertFromMeshGltf( const gltfMesh_Primitive * prim, gltfData* _data ); static MapPolygonMesh* Parse( idLexer& src, const idVec3& origin, float version = CURRENT_MAP_VERSION ); bool Write( idFile* fp, int primitiveNum, const idVec3& origin ) const; diff --git a/neo/renderer/Model_gltf.cpp b/neo/renderer/Model_gltf.cpp index 65269beb..2377cdb1 100644 --- a/neo/renderer/Model_gltf.cpp +++ b/neo/renderer/Model_gltf.cpp @@ -10,221 +10,213 @@ bool idRenderModelStatic::ConvertGltfMeshToModelsurfaces( const gltfMesh* mesh ) { - - //for ( auto mesh : currentAsset->MeshList( ) ) { - // for ( auto prim : mesh->primitives ) { - return false; } -void MapPolygonMesh::ConvertFromMeshGltf( const gltfMesh* _mesh, gltfData* data ) +MapPolygonMesh* MapPolygonMesh::ConvertFromMeshGltf( const gltfMesh_Primitive * prim, gltfData* _data ) { - //for( auto* gltfMesh : data->MeshList( ) ) + MapPolygonMesh* mesh = new MapPolygonMesh(); + gltfAccessor* accessor = _data->AccessorList( )[prim->indices]; + gltfBufferView* bv = _data->BufferViewList( )[accessor->bufferView]; + gltfData* data = bv->parent; + + gltfBuffer* buff = data->BufferList( )[bv->buffer]; + uint idxDataSize = sizeof( uint ) * accessor->count; + uint* indices = ( uint* ) Mem_ClearedAlloc( idxDataSize , TAG_IDLIB_GLTF ); + + idFile_Memory idxBin = idFile_Memory( "gltfChunkIndices", + ( const char* )( ( data->GetData( bv->buffer ) + bv->byteOffset + accessor->byteOffset ) ), bv->byteLength ); + + for( int i = 0; i < accessor->count; i++ ) { - for( auto prim : _mesh->primitives ) + idxBin.Read( ( void* )( &indices[i] ), accessor->typeSize ); + if( bv->byteStride ) { - common->Printf( "primitive for %s\n", _mesh->name.c_str() ); - - gltfAccessor* accessor = data->AccessorList( )[prim->indices]; - gltfBufferView* bv = data->BufferViewList( )[accessor->bufferView]; - gltfData* data = bv->parent; - - gltfBuffer* buff = data->BufferList( )[bv->buffer]; - uint idxDataSize = sizeof( uint ) * accessor->count; - uint* indices = ( uint* ) Mem_ClearedAlloc( idxDataSize , TAG_IDLIB_GLTF ); - - idFile_Memory idxBin = idFile_Memory( "gltfChunkIndices", - ( const char* )( ( data->GetData( bv->buffer ) + bv->byteOffset + accessor->byteOffset ) ), bv->byteLength ); - - for( int i = 0; i < accessor->count; i++ ) - { - idxBin.Read( ( void* )( &indices[i] ), accessor->typeSize ); - if( bv->byteStride ) - { - idxBin.Seek( bv->byteStride - accessor->typeSize, FS_SEEK_CUR ); - } - } - - for( int i = 0; i < accessor->count; i += 3 ) - { - MapPolygon& polygon = polygons.Alloc(); - polygon.SetMaterial( "textures/enpro/enwall16" ); - polygon.AddIndex( indices[i + 2] ); - polygon.AddIndex( indices[i + 1] ); - polygon.AddIndex( indices[i + 0] ); - } - - Mem_Free( indices ); - bool sizeSet = false; - - for( auto& attrib : prim->attributes ) - { - gltfAccessor* attrAcc = data->AccessorList( )[attrib->accessorIndex]; - gltfBufferView* attrBv = data->BufferViewList( )[attrAcc->bufferView]; - gltfData* attrData = attrBv->parent; - gltfBuffer* attrbuff = attrData->BufferList( )[attrBv->buffer]; - - idFile_Memory bin = idFile_Memory( "gltfChunkVertices", - ( const char* )( ( attrData->GetData( attrBv->buffer ) + attrBv->byteOffset + attrAcc->byteOffset ) ), attrBv->byteLength ); - - if( !sizeSet ) - { - verts.AssureSize( attrAcc->count ); - sizeSet = true; - } - - switch( attrib->type ) - { - case gltfMesh_Primitive_Attribute::Type::Position: - { - for( int i = 0; i < attrAcc->count; i++ ) - { - idVec3 pos; - - bin.Read( ( void* )( &pos.x ), attrAcc->typeSize ); - bin.Read( ( void* )( &pos.y ), attrAcc->typeSize ); - bin.Read( ( void* )( &pos.z ), attrAcc->typeSize ); - -#if GLTF_YUP - // RB: proper glTF2 convention, requires Y-up export option ticked on in Blender - verts[i].xyz.x = pos.z; - verts[i].xyz.y = pos.x; - verts[i].xyz.z = pos.y; -#else - verts[i].xyz.x = pos.x; - verts[i].xyz.y = pos.y; - verts[i].xyz.z = pos.z; -#endif - - if( attrBv->byteStride ) - { - bin.Seek( attrBv->byteStride - ( 3 * attrAcc->typeSize ), FS_SEEK_CUR ); - } - - idRandom rnd( i ); - int r = rnd.RandomInt( 255 ), g = rnd.RandomInt( 255 ), b = rnd.RandomInt( 255 ); - - //vtxData[i].abgr = 0xff000000 + ( b << 16 ) + ( g << 8 ) + r; - } - - break; - } - case gltfMesh_Primitive_Attribute::Type::Normal: - { - idVec3 vec; - for( int i = 0; i < attrAcc->count; i++ ) - { - idVec3 vec; - bin.Read( ( void* )( &vec.x ), attrAcc->typeSize ); - bin.Read( ( void* )( &vec.y ), attrAcc->typeSize ); - bin.Read( ( void* )( &vec.z ), attrAcc->typeSize ); - if( attrBv->byteStride ) - { - bin.Seek( attrBv->byteStride - ( attrib->elementSize * attrAcc->typeSize ), FS_SEEK_CUR ); - } - - idVec3 normal; -#if GLTF_YUP - // RB: proper glTF2 convention, requires Y-up export option ticked on in Blender - normal.x = vec.z; - normal.y = vec.x; - normal.z = vec.y; -#else - normal.x = vec.x; - normal.y = vec.y; - normal.z = vec.z; -#endif - - verts[i].SetNormal( normal ); - } - - break; - } - case gltfMesh_Primitive_Attribute::Type::TexCoord0: - { - idVec2 vec; - for( int i = 0; i < attrAcc->count; i++ ) - { - bin.Read( ( void* )( &vec.x ), attrAcc->typeSize ); - bin.Read( ( void* )( &vec.y ), attrAcc->typeSize ); - if( attrBv->byteStride ) - { - bin.Seek( attrBv->byteStride - ( attrib->elementSize * attrAcc->typeSize ), FS_SEEK_CUR ); - } - - //vec.y = 1.0f - vec.y; - verts[i].SetTexCoord( vec ); - } - - break; - } - case gltfMesh_Primitive_Attribute::Type::Tangent: - { - idVec4 vec; - for( int i = 0; i < attrAcc->count; i++ ) - { - bin.Read( ( void* )( &vec.x ), attrAcc->typeSize ); - bin.Read( ( void* )( &vec.y ), attrAcc->typeSize ); - bin.Read( ( void* )( &vec.z ), attrAcc->typeSize ); - bin.Read( ( void* )( &vec.w ), attrAcc->typeSize ); - if( attrBv->byteStride ) - { - bin.Seek( attrBv->byteStride - ( attrib->elementSize * attrAcc->typeSize ), FS_SEEK_CUR ); - } - - idVec3 tangent; -#if GLTF_YUP - // RB: proper glTF2 convention, requires Y-up export option ticked on in Blender - tangent.x = vec.z; - tangent.y = vec.x; - tangent.z = vec.y; -#else - tangent.x = vec.x; - tangent.y = vec.y; - tangent.z = vec.z; -#endif - - verts[i].SetTangent( tangent ); - verts[i].SetBiTangentSign( vec.w ); - } - break; - } - //case gltfMesh_Primitive_Attribute::Type::Weight: - //{ - // for ( int i = 0; i < attrAcc->count; i++ ) { - // bin.Read( ( void * ) ( &vtxData[i].weight.x ), attrAcc->typeSize ); - // bin.Read( ( void * ) ( &vtxData[i].weight.y ), attrAcc->typeSize ); - // bin.Read( ( void * ) ( &vtxData[i].weight.z ), attrAcc->typeSize ); - // bin.Read( ( void * ) ( &vtxData[i].weight.w ), attrAcc->typeSize ); - // if ( attrBv->byteStride ) - // bin.Seek( attrBv->byteStride - ( attrib->elementSize * attrAcc->typeSize ), FS_SEEK_CUR ); - // } - // break; - //} - //case gltfMesh_Primitive_Attribute::Type::Indices: - //{ - // for ( int i = 0; i < attrAcc->count; i++ ) { - // bin.Read( ( void * ) ( &vtxData[i].boneIndex.x ), attrAcc->typeSize ); - // bin.Read( ( void * ) ( &vtxData[i].boneIndex.y ), attrAcc->typeSize ); - // bin.Read( ( void * ) ( &vtxData[i].boneIndex.z ), attrAcc->typeSize ); - // bin.Read( ( void * ) ( &vtxData[i].boneIndex.w ), attrAcc->typeSize ); - // if ( attrBv->byteStride ) - // bin.Seek( attrBv->byteStride - ( attrib->elementSize * attrAcc->typeSize ), FS_SEEK_CUR ); - // } - // break; - //} - } - - } + idxBin.Seek( bv->byteStride - accessor->typeSize, FS_SEEK_CUR ); } } - SetContents(); + + for( int i = 0; i < accessor->count; i += 3 ) + { + MapPolygon& polygon = mesh->polygons.Alloc(); + polygon.SetMaterial( "textures/enpro/enwall16" ); + polygon.AddIndex( indices[i + 2] ); + polygon.AddIndex( indices[i + 1] ); + polygon.AddIndex( indices[i + 0] ); + } + + Mem_Free( indices ); + bool sizeSet = false; + + for( auto& attrib : prim->attributes ) + { + gltfAccessor* attrAcc = data->AccessorList( )[attrib->accessorIndex]; + gltfBufferView* attrBv = data->BufferViewList( )[attrAcc->bufferView]; + gltfData* attrData = attrBv->parent; + gltfBuffer* attrbuff = attrData->BufferList( )[attrBv->buffer]; + + idFile_Memory bin = idFile_Memory( "gltfChunkVertices", + ( const char* )( ( attrData->GetData( attrBv->buffer ) + attrBv->byteOffset + attrAcc->byteOffset ) ), attrBv->byteLength ); + + if( !sizeSet ) + { + mesh->verts.AssureSize( attrAcc->count ); + sizeSet = true; + } + + switch( attrib->type ) + { + case gltfMesh_Primitive_Attribute::Type::Position: + { + for( int i = 0; i < attrAcc->count; i++ ) + { + idVec3 pos; + + bin.Read( ( void* )( &pos.x ), attrAcc->typeSize ); + bin.Read( ( void* )( &pos.y ), attrAcc->typeSize ); + bin.Read( ( void* )( &pos.z ), attrAcc->typeSize ); + +#if GLTF_YUP + // RB: proper glTF2 convention, requires Y-up export option ticked on in Blender + mesh->verts[i].xyz.x = pos.z; + mesh->verts[i].xyz.y = pos.x; + mesh->verts[i].xyz.z = pos.y; +#else + mesh->verts[i].xyz.x = pos.x; + mesh->verts[i].xyz.y = pos.y; + mesh->verts[i].xyz.z = pos.z; +#endif + + if( attrBv->byteStride ) + { + bin.Seek( attrBv->byteStride - ( 3 * attrAcc->typeSize ), FS_SEEK_CUR ); + } + + idRandom rnd( i ); + int r = rnd.RandomInt( 255 ), g = rnd.RandomInt( 255 ), b = rnd.RandomInt( 255 ); + + //vtxData[i].abgr = 0xff000000 + ( b << 16 ) + ( g << 8 ) + r; + } + + break; + } + case gltfMesh_Primitive_Attribute::Type::Normal: + { + idVec3 vec; + for( int i = 0; i < attrAcc->count; i++ ) + { + idVec3 vec; + bin.Read( ( void* )( &vec.x ), attrAcc->typeSize ); + bin.Read( ( void* )( &vec.y ), attrAcc->typeSize ); + bin.Read( ( void* )( &vec.z ), attrAcc->typeSize ); + if( attrBv->byteStride ) + { + bin.Seek( attrBv->byteStride - ( attrib->elementSize * attrAcc->typeSize ), FS_SEEK_CUR ); + } + + idVec3 normal; +#if GLTF_YUP + // RB: proper glTF2 convention, requires Y-up export option ticked on in Blender + normal.x = vec.z; + normal.y = vec.x; + normal.z = vec.y; +#else + normal.x = vec.x; + normal.y = vec.y; + normal.z = vec.z; +#endif + + mesh->verts[i].SetNormal( normal ); + } + + break; + } + case gltfMesh_Primitive_Attribute::Type::TexCoord0: + { + idVec2 vec; + for( int i = 0; i < attrAcc->count; i++ ) + { + bin.Read( ( void* )( &vec.x ), attrAcc->typeSize ); + bin.Read( ( void* )( &vec.y ), attrAcc->typeSize ); + if( attrBv->byteStride ) + { + bin.Seek( attrBv->byteStride - ( attrib->elementSize * attrAcc->typeSize ), FS_SEEK_CUR ); + } + + //vec.y = 1.0f - vec.y; + mesh->verts[i].SetTexCoord( vec ); + } + + break; + } + case gltfMesh_Primitive_Attribute::Type::Tangent: + { + idVec4 vec; + for( int i = 0; i < attrAcc->count; i++ ) + { + bin.Read( ( void* )( &vec.x ), attrAcc->typeSize ); + bin.Read( ( void* )( &vec.y ), attrAcc->typeSize ); + bin.Read( ( void* )( &vec.z ), attrAcc->typeSize ); + bin.Read( ( void* )( &vec.w ), attrAcc->typeSize ); + if( attrBv->byteStride ) + { + bin.Seek( attrBv->byteStride - ( attrib->elementSize * attrAcc->typeSize ), FS_SEEK_CUR ); + } + + idVec3 tangent; +#if GLTF_YUP + // RB: proper glTF2 convention, requires Y-up export option ticked on in Blender + tangent.x = vec.z; + tangent.y = vec.x; + tangent.z = vec.y; +#else + tangent.x = vec.x; + tangent.y = vec.y; + tangent.z = vec.z; +#endif + + mesh->verts[i].SetTangent( tangent ); + mesh->verts[i].SetBiTangentSign( vec.w ); + } + break; + } + //case gltfMesh_Primitive_Attribute::Type::Weight: + //{ + // for ( int i = 0; i < attrAcc->count; i++ ) { + // bin.Read( ( void * ) ( &vtxData[i].weight.x ), attrAcc->typeSize ); + // bin.Read( ( void * ) ( &vtxData[i].weight.y ), attrAcc->typeSize ); + // bin.Read( ( void * ) ( &vtxData[i].weight.z ), attrAcc->typeSize ); + // bin.Read( ( void * ) ( &vtxData[i].weight.w ), attrAcc->typeSize ); + // if ( attrBv->byteStride ) + // bin.Seek( attrBv->byteStride - ( attrib->elementSize * attrAcc->typeSize ), FS_SEEK_CUR ); + // } + // break; + //} + //case gltfMesh_Primitive_Attribute::Type::Indices: + //{ + // for ( int i = 0; i < attrAcc->count; i++ ) { + // bin.Read( ( void * ) ( &vtxData[i].boneIndex.x ), attrAcc->typeSize ); + // bin.Read( ( void * ) ( &vtxData[i].boneIndex.y ), attrAcc->typeSize ); + // bin.Read( ( void * ) ( &vtxData[i].boneIndex.z ), attrAcc->typeSize ); + // bin.Read( ( void * ) ( &vtxData[i].boneIndex.w ), attrAcc->typeSize ); + // if ( attrBv->byteStride ) + // bin.Seek( attrBv->byteStride - ( attrib->elementSize * attrAcc->typeSize ), FS_SEEK_CUR ); + // } + // break; + //} + } + + } + mesh->SetContents(); + return mesh; } int idMapEntity::GetEntities( gltfData* data, EntityListRef entities, int sceneID ) { - idMapEntity* worldspawn = new idMapEntity(); - entities.Append( worldspawn ); + entities.AssureSizeAlloc( entities.Num( ) + 1, idListNewElement ); + + idMapEntity* worldspawn = entities[0]; + bool wpSet = false; int entityCount = 0; for( auto& nodeID : data->SceneList()[sceneID]->nodes ) @@ -236,23 +228,24 @@ int idMapEntity::GetEntities( gltfData* data, EntityListRef entities, int sceneI bool isWorldSpawn = idStr::Icmp( node->extras.strPairs.GetString( "classname" ), "worldspawn" ) == 0; if( isWorldSpawn ) { - worldspawn->primitives.Resize( 1024, 256 ); + assert( !wpSet ); worldspawn->epairs.Copy( node->extras.strPairs ); + wpSet = true; } else { // account all meshes starting with worldspawn. or BSP in the name if( idStr::Icmpn( node->name, "BSP", 3 ) == 0 || idStr::Icmpn( node->name, "worldspawn.", 11 ) == 0 ) { - MapPolygonMesh* meshPrim = new MapPolygonMesh(); - //meshPrim->epairs.Copy( newEntity->epairs ); - - meshPrim->ConvertFromMeshGltf( data->MeshList()[node->mesh], data ); - worldspawn->AddPrimitive( meshPrim ); + for ( auto prim : data->MeshList()[node->mesh]->primitives ) { + worldspawn->AddPrimitive( MapPolygonMesh::ConvertFromMeshGltf( prim, data )); + } } else { - newEntity = new idMapEntity(); + + entities.AssureSizeAlloc(entities.Num()+1,idListNewElement); + newEntity = entities[entities.Num()-1]; // set name and retrieve epairs from node extras if( node->name.Length() ) @@ -270,7 +263,7 @@ int idMapEntity::GetEntities( gltfData* data, EntityListRef entities, int sceneI } #endif - data->ResolveNodeMatrix( node ); + //data->ResolveNodeMatrix( node ); idVec3 origin; @@ -287,8 +280,7 @@ int idMapEntity::GetEntities( gltfData* data, EntityListRef entities, int sceneI newEntity->epairs.Set( "origin", origin.ToString() ); - common->Printf( " %s \n ", node->name.c_str( ) ); - entities.Append( newEntity ); + //common->Printf( " %s \n ", node->name.c_str( ) ); entityCount++; }