Facepunch / sbox-sdf

Library providing marching cubes / squares mesh generation

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

`Sdf2DMeshWriter` generate extra indices for the same vertex

PolSpock opened this issue · comments

Describe the bug

Hello,

I've updated my SDF library for getting the 2D rework, however my "shard system" has started to bug. (cause i'm navigating on Indices)

After investigation, i've found that WriteCollisionMesh() is creating too many indices instead of reusing them for the same Vertex

The old system (before the rework in lately July) was working well

To Reproduce

  1. Go to your Sdf2DMeshWriter.cs file and private void WriteCollisionMesh( Sdf2DLayer layer ) function
  2. Add this piece of debug :
		if ( Game.IsServer )
		{

			Log.Info( "finish" );
			Log.Info( _collisionMeshWriter.Vertices.Count );
			Log.Info( _collisionMeshWriter.Indices.Count );

			foreach ( var indices1 in _collisionMeshWriter.Indices.GetRange(0, 100 ) )
			{
				foreach ( var indices2 in _collisionMeshWriter.Indices.GetRange( 0, 100 ) )
				{
					if ( indices1 == indices2 )
					{
						continue;
					}

					if ( _collisionMeshWriter.Vertices[indices1].AlmostEqual( _collisionMeshWriter.Vertices[indices2] ) )
					{
						Log.Info( indices1 + ", " + indices2 + " are equals : " + _collisionMeshWriter.Vertices[indices1] + " vs " + _collisionMeshWriter.Vertices[indices2] );
					}
				}
			}
		}
  1. Now create a Sdf2DWorld. Personally, i have edited the BlobTool
  2. Spawn a 2D surface SdfWorld.AddAsync( new RectSdf( new Vector2( -58, -58 ), new Vector2( 58, 58 ) ), Default2DVolume )
  3. Start a game and spawn the Sdf2DWorld : you will have many duplicate indices referring to the same Vertex

Whereas if you using a old version of the SDF Library (like this one https://github.com/Facepunch/sbox-sdf/tree/1b833630142e34110e9e46bdc4ba3cbe50da3a6c), you have to add the same debug in public void Write( Sdf2DArrayData data, Sdf2DLayer layer, bool renderMesh, bool collisionMesh ) function of Sdf2DMeshWriter.cs

if ( collisionMesh )
{
	foreach ( var triangle in FrontBackTriangles ) Collision.AddFrontBackTriangle( data, unitSize, triangle );

	foreach ( var block in SolidBlocks )
	{
		var (tri0, tri1) = block.Triangles;

		Collision.AddFrontBackTriangle( data, unitSize, tri0 );
		Collision.AddFrontBackTriangle( data, unitSize, tri1 );
	}

	foreach ( var cutFace in CutFaces ) Collision.AddCutFace( data, unitSize, cutFace );

	if ( Game.IsServer )
	{

		Log.Info( "finish" );
		Log.Info( Collision.Vertices.Count );
		Log.Info( Collision.Indices.Count );

		foreach ( var indices1 in Collision.Indices )
		{
			foreach ( var indices2 in Collision.Indices )
			{
				if ( indices1 == indices2 )
				{
					continue;
				}

				if ( Collision.Vertices[indices1].AlmostEqual( Collision.Vertices[indices2] ) )
				{
					Log.Info( indices1 + ", " + indices2 + " are equals : " + Collision.Vertices[indices1] + " vs " + Collision.Vertices[indices2] );
				}
			}
		}
	}
}

And you will have no duplicate extra indices for the same Vertex

Expected behavior

Only one indice must refer to a vertex.

I have tried to fix it myself but have not been able yet.

Regards

In the rewrite I'm not stitching together vertices from the cut faces and the front / back faces. Doing it in a nice way will be tricky, but I'll have a try soon.

Sorry for the long wait, this should be sufficient for what you're doing now. There might still be some vertices that are almost identical, but the collision mesh should be properly connected now.

Feel free to comment / reopen if it's still an issue for you.