Fix inverted normals for some edges of transvoxel
	
		
			
	
		
	
	
		
	
		
			Some checks failed
		
		
	
	
		
			
				
	
				studiorailgun/Renderer/pipeline/head There was a failure building this commit
				
			
		
		
	
	
				
					
				
			
		
			Some checks failed
		
		
	
	studiorailgun/Renderer/pipeline/head There was a failure building this commit
				
			This commit is contained in:
		
							parent
							
								
									c02959efee
								
							
						
					
					
						commit
						4f639cc6be
					
				| @ -938,6 +938,9 @@ Fix draw cell LOD joining bug | ||||
| Fix draw cell bounding sphere calculation | ||||
| Hill Gen tweaks | ||||
| 
 | ||||
| (11/05/2024) | ||||
| More normals fixes for terrain | ||||
| 
 | ||||
| 
 | ||||
| # TODO | ||||
| 
 | ||||
|  | ||||
| @ -168,6 +168,7 @@ public class TransvoxelModelGeneration { | ||||
|      * @param verts | ||||
|      * @param normals | ||||
|      * @param trianglesSharingVert | ||||
|      * @param invertNormals Flag to invert normals | ||||
|      * @return | ||||
|      */ | ||||
|     protected static int polygonize( | ||||
| @ -178,7 +179,8 @@ public class TransvoxelModelGeneration { | ||||
|             Map<String,Integer> vertMap, | ||||
|             List<Vector3f> verts, | ||||
|             List<Vector3f> normals, | ||||
|             List<Integer> trianglesSharingVert | ||||
|             List<Integer> trianglesSharingVert, | ||||
|             boolean invertNormals | ||||
|         ){ | ||||
|         int i; | ||||
|         int ntriang; | ||||
| @ -311,6 +313,9 @@ public class TransvoxelModelGeneration { | ||||
|             Vector3f u = verts.get(index1).sub(verts.get(index0), new Vector3f()); | ||||
|             Vector3f v = verts.get(index2).sub(verts.get(index1), new Vector3f()); | ||||
|             Vector3f n = new Vector3f(u.y * v.z - u.z * v.y, u.z * v.x - u.x * v.z, u.x * v.y - u.y * v.x).normalize(); | ||||
|             if(invertNormals){ | ||||
|                 n = n.mul(-1); | ||||
|             } | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| @ -376,6 +381,7 @@ public class TransvoxelModelGeneration { | ||||
|      * @param verts The list of verts | ||||
|      * @param normals The normal map | ||||
|      * @param trianglesSharingVert The indices of triangles sharing verts -- Used for making sure normals are pointing correctly | ||||
|      * @param invertNormals Override to invert normals | ||||
|      * @return The number of triangles created | ||||
|      */ | ||||
|     protected static int polygonizeTransition( | ||||
| @ -386,7 +392,8 @@ public class TransvoxelModelGeneration { | ||||
|             Map<String,Integer> vertMap, | ||||
|             List<Vector3f> verts, | ||||
|             List<Vector3f> normals, | ||||
|             List<Integer> trianglesSharingVert | ||||
|             List<Integer> trianglesSharingVert, | ||||
|             boolean invertNormals | ||||
|         ){ | ||||
| 
 | ||||
| 
 | ||||
| @ -749,6 +756,9 @@ public class TransvoxelModelGeneration { | ||||
|             Vector3f u = verts.get(index1).sub(verts.get(index0), new Vector3f()); | ||||
|             Vector3f v = verts.get(index2).sub(verts.get(index1), new Vector3f()); | ||||
|             Vector3f n = new Vector3f(u.y * v.z - u.z * v.y, u.z * v.x - u.x * v.z, u.x * v.y - u.y * v.x).normalize(); | ||||
|             if(invertNormals){ | ||||
|                 n = n.mul(-1); | ||||
|             } | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| @ -1055,7 +1065,7 @@ public class TransvoxelModelGeneration { | ||||
|                         chunkData.textureGrid[x+0][y+1][z+0], chunkData.textureGrid[x+0][y+1][z+1], chunkData.textureGrid[x+1][y+1][z+1], chunkData.textureGrid[x+1][y+1][z+0] | ||||
|                     ); | ||||
|                     //polygonize the current gridcell | ||||
|                     polygonize(currentCell, TerrainChunkModelGeneration.MIN_ISO_VALUE, triangles, samplerTriangles, vertMap, verts, normals, trianglesSharingVert); | ||||
|                     polygonize(currentCell, TerrainChunkModelGeneration.MIN_ISO_VALUE, triangles, samplerTriangles, vertMap, verts, normals, trianglesSharingVert, false); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
| @ -1105,7 +1115,7 @@ public class TransvoxelModelGeneration { | ||||
|                         chunkData.xPositiveEdgeAtlas[(y+0)*2+0][(z+0)*2+0], chunkData.xPositiveEdgeAtlas[(y+1)*2+0][(z+0)*2+0], | ||||
|                         chunkData.xPositiveEdgeAtlas[(y+0)*2+0][(z+1)*2+0], chunkData.xPositiveEdgeAtlas[(y+1)*2+0][(z+1)*2+0] | ||||
|                     ); | ||||
|                     polygonizeTransition(currentTransitionCell, TerrainChunkModelGeneration.MIN_ISO_VALUE, triangles, samplerTriangles, vertMap, verts, normals, trianglesSharingVert); | ||||
|                     polygonizeTransition(currentTransitionCell, TerrainChunkModelGeneration.MIN_ISO_VALUE, triangles, samplerTriangles, vertMap, verts, normals, trianglesSharingVert, true); | ||||
| 
 | ||||
|                     // | ||||
|                     //Generate the normal cell with half width | ||||
| @ -1119,7 +1129,7 @@ public class TransvoxelModelGeneration { | ||||
|                         chunkData.textureGrid[x+0][y+1][z+0], chunkData.textureGrid[x+0][y+1][z+1], chunkData.xPositiveEdgeAtlas[(y+1)*2+0][(z+1)*2+0], chunkData.xPositiveEdgeAtlas[(y+1)*2+0][(z+0)*2+0] | ||||
|                     ); | ||||
|                     //polygonize the current gridcell | ||||
|                     polygonize(currentCell, TerrainChunkModelGeneration.MIN_ISO_VALUE, triangles, samplerTriangles, vertMap, verts, normals, trianglesSharingVert); | ||||
|                     polygonize(currentCell, TerrainChunkModelGeneration.MIN_ISO_VALUE, triangles, samplerTriangles, vertMap, verts, normals, trianglesSharingVert, false); | ||||
|                 } | ||||
|             } | ||||
|         } else { | ||||
| @ -1136,7 +1146,7 @@ public class TransvoxelModelGeneration { | ||||
|                         chunkData.textureGrid[x+0][y+1][z+0], chunkData.textureGrid[x+0][y+1][z+1], chunkData.textureGrid[x+1][y+1][z+1], chunkData.textureGrid[x+1][y+1][z+0] | ||||
|                     ); | ||||
|                     //polygonize the current gridcell | ||||
|                     polygonize(currentCell, TerrainChunkModelGeneration.MIN_ISO_VALUE, triangles, samplerTriangles, vertMap, verts, normals, trianglesSharingVert); | ||||
|                     polygonize(currentCell, TerrainChunkModelGeneration.MIN_ISO_VALUE, triangles, samplerTriangles, vertMap, verts, normals, trianglesSharingVert, false); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
| @ -1179,7 +1189,7 @@ public class TransvoxelModelGeneration { | ||||
|                         chunkData.xNegativeEdgeAtlas[(y+0)*2+0][(z+0)*2+0], chunkData.xNegativeEdgeAtlas[(y+1)*2+0][(z+0)*2+0], | ||||
|                         chunkData.xNegativeEdgeAtlas[(y+0)*2+0][(z+1)*2+0], chunkData.xNegativeEdgeAtlas[(y+1)*2+0][(z+1)*2+0] | ||||
|                     ); | ||||
|                     polygonizeTransition(currentTransitionCell, TerrainChunkModelGeneration.MIN_ISO_VALUE, triangles, samplerTriangles, vertMap, verts, normals, trianglesSharingVert); | ||||
|                     polygonizeTransition(currentTransitionCell, TerrainChunkModelGeneration.MIN_ISO_VALUE, triangles, samplerTriangles, vertMap, verts, normals, trianglesSharingVert, false); | ||||
| 
 | ||||
|                     // | ||||
|                     //Generate the normal cell with half width | ||||
| @ -1193,7 +1203,7 @@ public class TransvoxelModelGeneration { | ||||
|                         chunkData.xNegativeEdgeAtlas[(y+1)*2+0][(z+0)*2+0], chunkData.xNegativeEdgeAtlas[(y+1)*2+0][(z+1)*2+0], chunkData.textureGrid[x+1][y+1][z+1], chunkData.textureGrid[x+1][y+1][z+0] | ||||
|                     ); | ||||
|                     //polygonize the current gridcell | ||||
|                     polygonize(currentCell, TerrainChunkModelGeneration.MIN_ISO_VALUE, triangles, samplerTriangles, vertMap, verts, normals, trianglesSharingVert); | ||||
|                     polygonize(currentCell, TerrainChunkModelGeneration.MIN_ISO_VALUE, triangles, samplerTriangles, vertMap, verts, normals, trianglesSharingVert, false); | ||||
|                 } | ||||
|             } | ||||
|         } else { | ||||
| @ -1210,7 +1220,7 @@ public class TransvoxelModelGeneration { | ||||
|                         chunkData.textureGrid[x+0][y+1][z+0], chunkData.textureGrid[x+0][y+1][z+1], chunkData.textureGrid[x+1][y+1][z+1], chunkData.textureGrid[x+1][y+1][z+0] | ||||
|                     ); | ||||
|                     //polygonize the current gridcell | ||||
|                     polygonize(currentCell, TerrainChunkModelGeneration.MIN_ISO_VALUE, triangles, samplerTriangles, vertMap, verts, normals, trianglesSharingVert); | ||||
|                     polygonize(currentCell, TerrainChunkModelGeneration.MIN_ISO_VALUE, triangles, samplerTriangles, vertMap, verts, normals, trianglesSharingVert, false); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
| @ -1252,7 +1262,7 @@ public class TransvoxelModelGeneration { | ||||
|                         chunkData.yPositiveEdgeAtlas[(x+0)*2+0][(z+0)*2+0], chunkData.yPositiveEdgeAtlas[(x+1)*2+0][(z+0)*2+0], | ||||
|                         chunkData.yPositiveEdgeAtlas[(x+0)*2+0][(z+1)*2+0], chunkData.yPositiveEdgeAtlas[(x+1)*2+0][(z+1)*2+0] | ||||
|                     ); | ||||
|                     polygonizeTransition(currentTransitionCell, TerrainChunkModelGeneration.MIN_ISO_VALUE, triangles, samplerTriangles, vertMap, verts, normals, trianglesSharingVert); | ||||
|                     polygonizeTransition(currentTransitionCell, TerrainChunkModelGeneration.MIN_ISO_VALUE, triangles, samplerTriangles, vertMap, verts, normals, trianglesSharingVert, false); | ||||
| 
 | ||||
|                     // | ||||
|                     //Generate the normal cell with half width | ||||
| @ -1266,7 +1276,7 @@ public class TransvoxelModelGeneration { | ||||
|                         chunkData.yPositiveEdgeAtlas[(x+0)*2+0][(z+0)*2+0],     chunkData.yPositiveEdgeAtlas[(x+0)*2+0][(z+1)*2+0],     chunkData.yPositiveEdgeAtlas[(x+1)*2+0][(z+1)*2+0],     chunkData.yPositiveEdgeAtlas[(x+1)*2+0][(z+0)*2+0] | ||||
|                     ); | ||||
|                     //polygonize the current gridcell | ||||
|                     polygonize(currentCell, TerrainChunkModelGeneration.MIN_ISO_VALUE, triangles, samplerTriangles, vertMap, verts, normals, trianglesSharingVert); | ||||
|                     polygonize(currentCell, TerrainChunkModelGeneration.MIN_ISO_VALUE, triangles, samplerTriangles, vertMap, verts, normals, trianglesSharingVert, false); | ||||
|                 } | ||||
|             } | ||||
|         } else { | ||||
| @ -1283,7 +1293,7 @@ public class TransvoxelModelGeneration { | ||||
|                         chunkData.textureGrid[x+0][y+1][z+0], chunkData.textureGrid[x+0][y+1][z+1], chunkData.textureGrid[x+1][y+1][z+1], chunkData.textureGrid[x+1][y+1][z+0] | ||||
|                     ); | ||||
|                     //polygonize the current gridcell | ||||
|                     polygonize(currentCell, TerrainChunkModelGeneration.MIN_ISO_VALUE, triangles, samplerTriangles, vertMap, verts, normals, trianglesSharingVert); | ||||
|                     polygonize(currentCell, TerrainChunkModelGeneration.MIN_ISO_VALUE, triangles, samplerTriangles, vertMap, verts, normals, trianglesSharingVert, false); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
| @ -1325,7 +1335,7 @@ public class TransvoxelModelGeneration { | ||||
|                         chunkData.yNegativeEdgeAtlas[(x+0)*2+0][(z+0)*2+0], chunkData.yNegativeEdgeAtlas[(x+1)*2+0][(z+0)*2+0], | ||||
|                         chunkData.yNegativeEdgeAtlas[(x+0)*2+0][(z+1)*2+0], chunkData.yNegativeEdgeAtlas[(x+1)*2+0][(z+1)*2+0] | ||||
|                     ); | ||||
|                     polygonizeTransition(currentTransitionCell, TerrainChunkModelGeneration.MIN_ISO_VALUE, triangles, samplerTriangles, vertMap, verts, normals, trianglesSharingVert); | ||||
|                     polygonizeTransition(currentTransitionCell, TerrainChunkModelGeneration.MIN_ISO_VALUE, triangles, samplerTriangles, vertMap, verts, normals, trianglesSharingVert, false); | ||||
| 
 | ||||
|                     // | ||||
|                     //Generate the normal cell with half width | ||||
| @ -1339,7 +1349,7 @@ public class TransvoxelModelGeneration { | ||||
|                         chunkData.yNegativeEdgeAtlas[(x+0)*2+0][(z+0)*2+0],     chunkData.yNegativeEdgeAtlas[(x+0)*2+0][(z+1)*2+0],     chunkData.yNegativeEdgeAtlas[(x+1)*2+0][(z+1)*2+0],     chunkData.yNegativeEdgeAtlas[(x+1)*2+0][(z+0)*2+0] | ||||
|                     ); | ||||
|                     //polygonize the current gridcell | ||||
|                     polygonize(currentCell, TerrainChunkModelGeneration.MIN_ISO_VALUE, triangles, samplerTriangles, vertMap, verts, normals, trianglesSharingVert); | ||||
|                     polygonize(currentCell, TerrainChunkModelGeneration.MIN_ISO_VALUE, triangles, samplerTriangles, vertMap, verts, normals, trianglesSharingVert, false); | ||||
|                 } | ||||
|             } | ||||
|         } else { | ||||
| @ -1356,7 +1366,7 @@ public class TransvoxelModelGeneration { | ||||
|                         chunkData.textureGrid[x+0][y+1][z+0], chunkData.textureGrid[x+0][y+1][z+1], chunkData.textureGrid[x+1][y+1][z+1], chunkData.textureGrid[x+1][y+1][z+0] | ||||
|                     ); | ||||
|                     //polygonize the current gridcell | ||||
|                     polygonize(currentCell, TerrainChunkModelGeneration.MIN_ISO_VALUE, triangles, samplerTriangles, vertMap, verts, normals, trianglesSharingVert); | ||||
|                     polygonize(currentCell, TerrainChunkModelGeneration.MIN_ISO_VALUE, triangles, samplerTriangles, vertMap, verts, normals, trianglesSharingVert, false); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
| @ -1399,7 +1409,7 @@ public class TransvoxelModelGeneration { | ||||
|                         chunkData.zPositiveEdgeAtlas[(x+0)*2+0][(y+0)*2+0], chunkData.zPositiveEdgeAtlas[(x+0)*2+0][(y+1)*2+0], | ||||
|                         chunkData.zPositiveEdgeAtlas[(x+1)*2+0][(y+0)*2+0], chunkData.zPositiveEdgeAtlas[(x+1)*2+0][(y+1)*2+0] | ||||
|                     ); | ||||
|                     polygonizeTransition(currentTransitionCell, TerrainChunkModelGeneration.MIN_ISO_VALUE, triangles, samplerTriangles, vertMap, verts, normals, trianglesSharingVert); | ||||
|                     polygonizeTransition(currentTransitionCell, TerrainChunkModelGeneration.MIN_ISO_VALUE, triangles, samplerTriangles, vertMap, verts, normals, trianglesSharingVert, false); | ||||
| 
 | ||||
|                     // | ||||
|                     //Generate the normal cell with half width | ||||
| @ -1413,7 +1423,7 @@ public class TransvoxelModelGeneration { | ||||
|                         chunkData.textureGrid[x+0][y+1][z+0], chunkData.zPositiveEdgeAtlas[(x+0)*2+0][(y+1)*2+0], chunkData.zPositiveEdgeAtlas[(x+1)*2+0][(y+1)*2+0], chunkData.textureGrid[x+1][y+1][z+0] | ||||
|                     ); | ||||
|                     //polygonize the current gridcell | ||||
|                     polygonize(currentCell, TerrainChunkModelGeneration.MIN_ISO_VALUE, triangles, samplerTriangles, vertMap, verts, normals, trianglesSharingVert); | ||||
|                     polygonize(currentCell, TerrainChunkModelGeneration.MIN_ISO_VALUE, triangles, samplerTriangles, vertMap, verts, normals, trianglesSharingVert, false); | ||||
|                 } | ||||
|             } | ||||
|         } else { | ||||
| @ -1430,7 +1440,7 @@ public class TransvoxelModelGeneration { | ||||
|                         chunkData.textureGrid[x+0][y+1][z+0], chunkData.textureGrid[x+0][y+1][z+1], chunkData.textureGrid[x+1][y+1][z+1], chunkData.textureGrid[x+1][y+1][z+0] | ||||
|                     ); | ||||
|                     //polygonize the current gridcell | ||||
|                     polygonize(currentCell, TerrainChunkModelGeneration.MIN_ISO_VALUE, triangles, samplerTriangles, vertMap, verts, normals, trianglesSharingVert); | ||||
|                     polygonize(currentCell, TerrainChunkModelGeneration.MIN_ISO_VALUE, triangles, samplerTriangles, vertMap, verts, normals, trianglesSharingVert, false); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
| @ -1473,7 +1483,7 @@ public class TransvoxelModelGeneration { | ||||
|                         chunkData.zNegativeEdgeAtlas[(x+0)*2+0][(y+0)*2+0], chunkData.zNegativeEdgeAtlas[(x+0)*2+0][(y+1)*2+0], | ||||
|                         chunkData.zNegativeEdgeAtlas[(x+1)*2+0][(y+0)*2+0], chunkData.zNegativeEdgeAtlas[(x+1)*2+0][(y+1)*2+0] | ||||
|                     ); | ||||
|                     polygonizeTransition(currentTransitionCell, TerrainChunkModelGeneration.MIN_ISO_VALUE, triangles, samplerTriangles, vertMap, verts, normals, trianglesSharingVert); | ||||
|                     polygonizeTransition(currentTransitionCell, TerrainChunkModelGeneration.MIN_ISO_VALUE, triangles, samplerTriangles, vertMap, verts, normals, trianglesSharingVert, true); | ||||
| 
 | ||||
|                     // | ||||
|                     //Generate the normal cell with half width | ||||
| @ -1487,7 +1497,7 @@ public class TransvoxelModelGeneration { | ||||
|                         chunkData.textureGrid[x+0][y+1][z+1], chunkData.zNegativeEdgeAtlas[(x+0)*2+0][(y+1)*2+0], chunkData.zNegativeEdgeAtlas[(x+1)*2+0][(y+1)*2+0], chunkData.textureGrid[x+1][y+1][z+1] | ||||
|                     ); | ||||
|                     //polygonize the current gridcell | ||||
|                     polygonize(currentCell, TerrainChunkModelGeneration.MIN_ISO_VALUE, triangles, samplerTriangles, vertMap, verts, normals, trianglesSharingVert); | ||||
|                     polygonize(currentCell, TerrainChunkModelGeneration.MIN_ISO_VALUE, triangles, samplerTriangles, vertMap, verts, normals, trianglesSharingVert, true); | ||||
|                 } | ||||
|             } | ||||
|         } else { | ||||
| @ -1504,7 +1514,7 @@ public class TransvoxelModelGeneration { | ||||
|                         chunkData.textureGrid[x+0][y+1][z+0], chunkData.textureGrid[x+0][y+1][z+1], chunkData.textureGrid[x+1][y+1][z+1], chunkData.textureGrid[x+1][y+1][z+0] | ||||
|                     ); | ||||
|                     //polygonize the current gridcell | ||||
|                     polygonize(currentCell, TerrainChunkModelGeneration.MIN_ISO_VALUE, triangles, samplerTriangles, vertMap, verts, normals, trianglesSharingVert); | ||||
|                     polygonize(currentCell, TerrainChunkModelGeneration.MIN_ISO_VALUE, triangles, samplerTriangles, vertMap, verts, normals, trianglesSharingVert, false); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
| @ -1544,7 +1554,7 @@ public class TransvoxelModelGeneration { | ||||
|                     chunkData.xNegativeEdgeAtlas[(y+0)*2+0][(z+0)*2+0], chunkData.xNegativeEdgeAtlas[(y+1)*2+0][(z+0)*2+0], | ||||
|                     chunkData.xNegativeEdgeAtlas[(y+0)*2+0][(z+1)*2+0], chunkData.xNegativeEdgeAtlas[(y+1)*2+0][(z+1)*2+0] | ||||
|                 ); | ||||
|                 polygonizeTransition(currentTransitionCell, TerrainChunkModelGeneration.MIN_ISO_VALUE, triangles, samplerTriangles, vertMap, verts, normals, trianglesSharingVert); | ||||
|                 polygonizeTransition(currentTransitionCell, TerrainChunkModelGeneration.MIN_ISO_VALUE, triangles, samplerTriangles, vertMap, verts, normals, trianglesSharingVert, false); | ||||
| 
 | ||||
|                 // | ||||
|                 //Generate the z-side transition cell | ||||
| @ -1572,7 +1582,7 @@ public class TransvoxelModelGeneration { | ||||
|                     chunkData.zNegativeEdgeAtlas[(x+0)*2+0][(y+0)*2+0], chunkData.zNegativeEdgeAtlas[(x+0)*2+0][(y+1)*2+0], | ||||
|                     chunkData.zNegativeEdgeAtlas[(x+1)*2+0][(y+0)*2+0], chunkData.zNegativeEdgeAtlas[(x+1)*2+0][(y+1)*2+0] | ||||
|                 ); | ||||
|                 polygonizeTransition(currentTransitionCell, TerrainChunkModelGeneration.MIN_ISO_VALUE, triangles, samplerTriangles, vertMap, verts, normals, trianglesSharingVert); | ||||
|                 polygonizeTransition(currentTransitionCell, TerrainChunkModelGeneration.MIN_ISO_VALUE, triangles, samplerTriangles, vertMap, verts, normals, trianglesSharingVert, true); | ||||
| 
 | ||||
|                 // | ||||
|                 //Generate the normal cell with half width | ||||
| @ -1586,7 +1596,7 @@ public class TransvoxelModelGeneration { | ||||
|                     chunkData.xNegativeEdgeAtlas[(y+1)*2+0][(z+0)*2+0], chunkData.xNegativeEdgeAtlas[(y+1)*2+0][(z+1)*2+0], chunkData.textureGrid[x+1][y+1][z+1], chunkData.textureGrid[x+1][y+1][z+0] | ||||
|                 ); | ||||
|                 //polygonize the current gridcell | ||||
|                 polygonize(currentCell, TerrainChunkModelGeneration.MIN_ISO_VALUE, triangles, samplerTriangles, vertMap, verts, normals, trianglesSharingVert); | ||||
|                 polygonize(currentCell, TerrainChunkModelGeneration.MIN_ISO_VALUE, triangles, samplerTriangles, vertMap, verts, normals, trianglesSharingVert, true); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user