소스 검색

Added vertex welding support.

bkaradzic 12 년 전
부모
커밋
35a39f6c00
2개의 변경된 파일64개의 추가작업 그리고 0개의 파일을 삭제
  1. 12 0
      include/bgfx.h
  2. 52 0
      src/vertexdecl.cpp

+ 12 - 0
include/bgfx.h

@@ -562,6 +562,18 @@ namespace bgfx
 	///
 	void vertexConvert(const VertexDecl& _destDecl, void* _destData, const VertexDecl& _srcDecl, const void* _srcData, uint32_t _num = 1);
 
+	/// Weld vertices.
+	///
+	/// @param _output Welded vertices remapping table. The size of buffer
+	///   must be the same as number of vertices.
+	/// @param _decl Vertex stream declaration.
+	/// @param _data Vertex stream.
+	/// @param _num Number of vertices in vertex stream.
+	/// @param _epsilon Error tolerance for vertex position comparison.
+	/// @returns Number of unique vertices after vertex welding.
+	///
+	uint16_t weldVertices(uint16_t* _output, const VertexDecl& _decl, const void* _data, uint16_t _num, float _epsilon = 0.001f);
+
 	/// Swizzle RGBA8 image to BGRA8.
 	///
 	/// @param _width Width of input image (pixels).

+ 52 - 0
src/vertexdecl.cpp

@@ -483,4 +483,56 @@ namespace bgfx
 		}
 	}
 
+	inline float sqLength(const float _a[3], const float _b[3])
+	{
+		const float xx = _a[0] - _b[0];
+		const float yy = _a[1] - _b[1];
+		const float zz = _a[2] - _b[2];
+		return xx*xx + yy*yy + zz*zz;
+	}
+
+	uint16_t weldVertices(uint16_t* _output, const VertexDecl& _decl, const void* _data, uint16_t _num, float _epsilon)
+	{
+		const uint32_t hashSize = bx::uint32_nextpow2(_num);
+		const uint32_t hashMask = hashSize-1;
+		const float epsilonSq = _epsilon*_epsilon;
+
+		uint32_t numVertices = 0;
+
+		const uint32_t size = sizeof(uint16_t)*(hashSize + _num);
+		uint16_t* hashTable = (uint16_t*)alloca(size);
+		memset(hashTable, 0xff, size);
+
+		uint16_t* next = hashTable + hashSize;
+
+		for (uint32_t ii = 0; ii < _num; ++ii)
+		{
+			float pos[4];
+			vertexUnpack(pos, bgfx::Attrib::Position, _decl, _data, ii);
+			uint32_t hashValue = bx::hashMurmur2A(pos, 3*sizeof(float) ) & hashMask;
+
+			uint16_t offset = hashTable[hashValue];
+			for (; UINT16_MAX != offset; offset = next[offset])
+			{
+				float test[4];
+				vertexUnpack(test, bgfx::Attrib::Position, _decl, _data, _output[offset]);
+				if (sqLength(test, pos) < epsilonSq)
+				{
+					_output[ii] = _output[offset];
+					break;
+				}
+			}
+
+			if (UINT16_MAX == offset)
+			{
+				_output[ii] = ii;
+				next[numVertices] = hashTable[hashValue];
+				hashTable[hashValue] = ii;
+				numVertices++;
+			}
+		}
+
+		return numVertices;
+	}
+
 } // namespace bgfx