hkpTriangleCompressor.inl
上传用户:yisoukefu
上传日期:2020-08-09
资源大小:39506k
文件大小:9k
源码类别:

其他游戏

开发平台:

Visual C++

  1. /* 
  2.  * 
  3.  * Confidential Information of Telekinesys Research Limited (t/a Havok). Not for disclosure or distribution without Havok's
  4.  * prior written consent. This software contains code, techniques and know-how which is confidential and proprietary to Havok.
  5.  * Level 2 and Level 3 source code contains trade secrets of Havok. Havok Software (C) Copyright 1999-2009 Telekinesys Research Limited t/a Havok. All Rights Reserved. Use of this software is subject to the terms of an end user license agreement.
  6.  * 
  7.  */
  8. //#define ONE_BYTE_PER_VERT
  9. #ifdef ONE_BYTE_PER_VERT
  10. typedef hkUint8 hkByteVert;
  11. #else
  12. typedef hkUint16 hkByteVert;
  13. #endif
  14. struct CompressedMesh
  15. {
  16. float m_x;
  17. float m_y;
  18. float m_z;
  19. hkUint8 m_numVerts;
  20. hkUint8 m_numTriangles;
  21. hkUint8 m_numMaterialIndices;
  22. hkUint8 pad1;
  23. float m_xInc;
  24. float m_yInc;
  25. float m_zInc;
  26. hkUint32 pad2;
  27. };
  28. struct ByteVec
  29. {
  30. hkByteVert m_verts[3];
  31. };
  32. struct TriIndices
  33. {
  34. hkUint8 m_vert[3];
  35. };
  36. typedef hkUint16 WeldingInfo;
  37. namespace hkTriCompressor
  38. {
  39. // This endian swaps the data
  40. // Big endian data (e.g PS3/ Xbox360) is unchanged. Little endian data is swapped back and forth
  41. template<typename T>
  42. HK_FORCE_INLINE T HK_CALL ConvertEndian( T tIn )
  43. {
  44. #if (HK_ENDIAN_BIG==1)
  45. return tIn;
  46. #else
  47. switch ( sizeof(T) )
  48. {
  49. case 1:
  50. {
  51. return tIn;
  52. }
  53. case 2:
  54. {
  55. union {
  56. hkUint8 bytes[2];
  57. T data;
  58. } t;
  59. t.data = tIn;
  60. hkAlgorithm::swap( t.bytes[0], t.bytes[1] );
  61. return t.data;
  62. }
  63. case 4:
  64. {
  65. union {
  66. hkUint8 bytes[4];
  67. T data;
  68. } t;
  69. t.data = tIn;
  70. hkAlgorithm::swap( t.bytes[1], t.bytes[2] );
  71. hkAlgorithm::swap( t.bytes[0], t.bytes[3] );
  72. return t.data;
  73. }
  74. default:
  75. {
  76. HK_BREAKPOINT(0x0);
  77. return tIn; // silence compiler warning
  78. }
  79. }
  80. #endif
  81. }
  82. }
  83. hkUint8 hkpTriangleCompressor::getMaterialIndex(int triangleIndex, const void* data )
  84. {
  85. HK_ASSERT2( 0x765e4534, (hkUlong(data) & 0x3) == 0, "Data must be at least 4 byte aligned");
  86. const CompressedMesh* compressedMesh = reinterpret_cast<const CompressedMesh*>( data );
  87. int baseOffset =  HK_HINT_SIZE16(sizeof(CompressedMesh)) + 
  88.   HK_HINT_SIZE16(sizeof(ByteVec)) * compressedMesh->m_numVerts + 
  89.  (HK_HINT_SIZE16(sizeof(TriIndices)) + HK_HINT_SIZE16(sizeof(WeldingInfo))) * compressedMesh->m_numTriangles;
  90. HK_ASSERT2( 0x65e43e45, triangleIndex < compressedMesh->m_numMaterialIndices, "Material index out of range" );
  91. return *((hkUint8*)data + baseOffset + triangleIndex);
  92. }
  93. void hkpTriangleCompressor::setWeldingInfo(int triangleIndex, void* data, hkUint16 weldingInfo)
  94. {
  95. HK_ASSERT2( 0x765e4534, (hkUlong(data) & 0x3) == 0, "Data must be at least 4 byte aligned");
  96. const CompressedMesh* compressedMesh = reinterpret_cast<const CompressedMesh*>( data );
  97. HK_ASSERT2( 0x65e43e45, triangleIndex < compressedMesh->m_numTriangles, "Triangle index out of range" );
  98. int baseOffset =  HK_HINT_SIZE16(sizeof(CompressedMesh)) + 
  99.   HK_HINT_SIZE16(sizeof(ByteVec)) * compressedMesh->m_numVerts + 
  100.   HK_HINT_SIZE16(sizeof(TriIndices)) * compressedMesh->m_numTriangles;
  101. hkUint16* weldingBase = reinterpret_cast<hkUint16*>( (hkUint8*)data + baseOffset );
  102. weldingBase[ triangleIndex ] = hkTriCompressor::ConvertEndian<hkUint16>(weldingInfo);
  103. }
  104. #ifdef HK_PLATFORM_PS3_SPU
  105. static vec_uchar16 unalignedLoad3FloatShuffle = (vec_uchar16)
  106. {
  107. 0x00, 0x01, 0x02, 0x03,
  108. 0x04, 0x05, 0x06, 0x07,
  109. 0x08, 0x09, 0x0A, 0x0B,
  110. 0x80, 0x80, 0x80, 0x80
  111. };
  112. #ifdef ONE_BYTE_PER_VERT
  113. static vec_uchar16 unalignedLoad3VertShuffle = (vec_uchar16)
  114. {
  115. 0x80, 0x80, 0x80, 0x00,
  116. 0x80, 0x80, 0x80, 0x01,
  117. 0x80, 0x80, 0x80, 0x02,
  118. 0x80, 0x80, 0x80, 0x80
  119. };
  120. #else
  121. static vec_uchar16 unalignedLoad3VertShuffle = (vec_uchar16)
  122. {
  123. 0x80, 0x80, 0x00, 0x01,
  124. 0x80, 0x80, 0x02, 0x03,
  125. 0x80, 0x80, 0x04, 0x05,
  126. 0x80, 0x80, 0x80, 0x80
  127. };
  128. #endif
  129. void hkpTriangleCompressor::getTriangleShape( hkpTriangleShape& triangleShape, int index, const void* data )
  130. {
  131. CompressedMesh& compressedMesh = *(CompressedMesh*)data;
  132. HK_ASSERT2( 0x765e4534, (hkUlong(data) & 0x3) == 0, "Data must be at least 4 byte aligned");
  133. unsigned int alignment = (unsigned int )data & 0xF;
  134. vec_uchar16 shuffle = (vec_uchar16)spu_add((vec_uint4)unalignedLoad3FloatShuffle, (vec_uint4)spu_splats(((unsigned char)(alignment))));
  135. vec_uint4 * __restrict__ inputBuffer = (vec_uint4 *) data; // rounds down data on spu
  136. vec_uint4 offset, incr;
  137. offset  = spu_shuffle(inputBuffer[0], inputBuffer[1], shuffle);
  138. incr = spu_shuffle(inputBuffer[1], inputBuffer[2], shuffle);
  139. ByteVec* verts = (ByteVec*)((hkUlong)data + sizeof( CompressedMesh ));
  140. TriIndices* triIndicesArray = (TriIndices*)( verts + compressedMesh.m_numVerts );
  141. TriIndices* triIndices = triIndicesArray + index;
  142. ByteVec* __restrict__ byteV0 = verts + triIndices->m_vert[0];
  143. unsigned int alignmentV0 = (unsigned int) byteV0 & 0xF;
  144. vec_uchar16 shuffleV0 = (vec_uchar16)spu_add((vec_uint4)unalignedLoad3VertShuffle, (vec_uint4)spu_splats(((unsigned char)(alignmentV0))));
  145. vector unsigned int * __restrict__ byteV0data = (vector unsigned int *)byteV0;
  146. vector float byteV0vector = spu_convtf(spu_shuffle(byteV0data[0],byteV0data[1],shuffleV0),0);
  147. ByteVec* __restrict__ byteV1 = verts + triIndices->m_vert[1];
  148. unsigned int alignmentV1 = (unsigned int) byteV1 & 0xF;
  149. vec_uchar16 shuffleV1 = (vec_uchar16)spu_add((vec_uint4)unalignedLoad3VertShuffle, (vec_uint4)spu_splats(((unsigned char)(alignmentV1))));
  150. vector unsigned int * __restrict__ byteV1data = (vector unsigned int *)byteV1;
  151. vector float byteV1vector = spu_convtf(spu_shuffle(byteV1data[0],byteV1data[1],shuffleV1),0);
  152. ByteVec* __restrict__ byteV2 = verts + triIndices->m_vert[2];
  153. unsigned int alignmentV2 = (unsigned int) byteV2 & 0xF;
  154. vec_uchar16 shuffleV2 = (vec_uchar16)spu_add((vec_uint4)unalignedLoad3VertShuffle, (vec_uint4)spu_splats(((unsigned char)(alignmentV2))));
  155. vector unsigned int * __restrict__ byteV2data = (vector unsigned int *)byteV2;
  156. vector float byteV2vector = spu_convtf(spu_shuffle(byteV2data[0],byteV2data[1],shuffleV2),0);
  157. hkVector4 v0,v1,v2; 
  158. v0 = (hkQuadReal) spu_madd((hkQuadReal)incr, byteV0vector, (hkQuadReal)offset);
  159. v1 = (hkQuadReal) spu_madd((hkQuadReal)incr, byteV1vector, (hkQuadReal)offset);
  160. v2 = (hkQuadReal) spu_madd((hkQuadReal)incr, byteV2vector, (hkQuadReal)offset);
  161. triangleShape.setVertex(0, v0);
  162. triangleShape.setVertex(1, v1);
  163. triangleShape.setVertex(2, v2);
  164. WeldingInfo* weldingInfoBase = (WeldingInfo*)( triIndicesArray + compressedMesh.m_numTriangles );
  165. triangleShape.setWeldingInfo( weldingInfoBase[index] );
  166. }
  167. #else
  168. void hkpTriangleCompressor::getTriangleShape( hkpTriangleShape& triangleShape, int index, const void* data )
  169. {
  170. HK_ASSERT2( 0x765e4534, (hkUlong(data) & 0x3) == 0, "Data must be at least 4 byte aligned");
  171. CompressedMesh& compressedMesh = *(CompressedMesh*)data;
  172. hkVector4 offset; offset.set( hkTriCompressor::ConvertEndian<hkReal>(compressedMesh.m_x),
  173.   hkTriCompressor::ConvertEndian<hkReal>(compressedMesh.m_y),
  174.   hkTriCompressor::ConvertEndian<hkReal>(compressedMesh.m_z));
  175. hkVector4 incr; incr.set( hkTriCompressor::ConvertEndian<hkReal>(compressedMesh.m_xInc),
  176.   hkTriCompressor::ConvertEndian<hkReal>(compressedMesh.m_yInc),
  177.   hkTriCompressor::ConvertEndian<hkReal>(compressedMesh.m_zInc));
  178. ByteVec* verts = (ByteVec*)((hkUlong)data + sizeof( CompressedMesh ));
  179. TriIndices* triIndicesArray = (TriIndices*)( verts + compressedMesh.m_numVerts);
  180. TriIndices& triIndices = triIndicesArray[ index ];
  181. for (int i = 0; i < 3; ++i)
  182. {
  183. ByteVec& byteV = verts[triIndices.m_vert[i]];
  184. hkVector4 quantizedVert; 
  185. quantizedVert.set( (hkReal) hkTriCompressor::ConvertEndian<hkByteVert>(byteV.m_verts[0]), 
  186.    (hkReal) hkTriCompressor::ConvertEndian<hkByteVert>(byteV.m_verts[1]), 
  187.    (hkReal) hkTriCompressor::ConvertEndian<hkByteVert>(byteV.m_verts[2])); 
  188. hkVector4 vert;
  189. vert.setAddMul4( offset, incr, quantizedVert );
  190. triangleShape.setVertex(i, vert);
  191. }
  192. WeldingInfo* weldingInfoBase = (WeldingInfo*)( triIndicesArray + compressedMesh.m_numTriangles );
  193. triangleShape.setWeldingInfo( hkTriCompressor::ConvertEndian<WeldingInfo>(weldingInfoBase[index]) );
  194. }
  195. #endif
  196. /*
  197. * Havok SDK - NO SOURCE PC DOWNLOAD, BUILD(#20090216)
  198. * Confidential Information of Havok.  (C) Copyright 1999-2009
  199. * Telekinesys Research Limited t/a Havok. All Rights Reserved. The Havok
  200. * Logo, and the Havok buzzsaw logo are trademarks of Havok.  Title, ownership
  201. * rights, and intellectual property rights in the Havok software remain in
  202. * Havok and/or its suppliers.
  203. * Use of this software for evaluation purposes is subject to and indicates
  204. * acceptance of the End User licence Agreement for this product. A copy of
  205. * the license is included with this software and is also available at www.havok.com/tryhavok.
  206. */