- Fixed GLTF Mesh -> Polygon Mesh creaton

This commit is contained in:
HarrievG 2022-06-10 10:27:17 +02:00
parent c0a5f1233d
commit faa9207d01
3 changed files with 211 additions and 225 deletions

View file

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

View file

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

View file

@ -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> );
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<idMapEntity>);
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++;
}