ShadowVolume.js 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345
  1. /**
  2. * @author mikael emtinger / http://gomo.se/
  3. */
  4. THREE.ShadowVolume = function( meshOrGeometry, isStatic ) {
  5. if( meshOrGeometry instanceof THREE.Mesh ) {
  6. THREE.Mesh.call( this, meshOrGeometry.geometry, isStatic ? [ new THREE.ShadowVolumeDynamicMaterial() ] : [ new THREE.ShadowVolumeDynamicMaterial() ] );
  7. meshOrGeometry.addChild( this );
  8. } else {
  9. THREE.Mesh.call( this, meshOrGeometry, isStatic ? [ new THREE.ShadowVolumeDynamicMaterial() ] : [ new THREE.ShadowVolumeDynamicMaterial() ] );
  10. }
  11. this.calculateShadowVolumeGeometry();
  12. };
  13. THREE.ShadowVolume.prototype = new THREE.Mesh();
  14. THREE.ShadowVolume.prototype.constructor = THREE.ShadowVolume;
  15. THREE.ShadowVolume.prototype.supr = THREE.Mesh.prototype;
  16. /*
  17. * Calculate Shadow Faces
  18. */
  19. THREE.ShadowVolume.prototype.calculateShadowVolumeGeometry = function() {
  20. if ( this.geometry.edges && this.geometry.edges.length ) {
  21. var f, fl, face, faceA, faceB, faceAIndex, faceBIndex, vertexA, vertexB;
  22. var faceACombination, faceBCombination;
  23. var faceAvertexAIndex, faceAvertexBIndex, faceBvertexAIndex, faceBvertexBIndex;
  24. var e, el, edge, temp;
  25. var newGeometry = new THREE.Geometry();
  26. var vertices = newGeometry.vertices = this.geometry.vertices;
  27. var faces = newGeometry.faces = this.geometry.faces;
  28. var edges = newGeometry.egdes = this.geometry.edges;
  29. var edgeFaces = newGeometry.edgeFaces = [];
  30. var vertexOffset = 0;
  31. var vertexOffsetPerFace = [];
  32. for( f = 0, fl = faces.length; f < fl; f++ ) {
  33. face = faces[ f ];
  34. // calculate faces vertex offset
  35. vertexOffsetPerFace.push( vertexOffset );
  36. vertexOffset += face instanceof THREE.Face3 ? 3 : 4;
  37. // set vertex normals to face normal
  38. face.vertexNormals[ 0 ] = face.normal;
  39. face.vertexNormals[ 1 ] = face.normal;
  40. face.vertexNormals[ 2 ] = face.normal;
  41. if( face instanceof THREE.Face4 ) face.vertexNormals[ 3 ] = face.normal;
  42. }
  43. // setup edge faces
  44. for( e = 0, el = edges.length; e < el; e++ ) {
  45. edge = edges[ e ];
  46. faceA = edge.faces[ 0 ];
  47. faceB = edge.faces[ 1 ];
  48. faceAIndex = edge.faceIndices[ 0 ];
  49. faceBIndex = edge.faceIndices[ 1 ];
  50. vertexA = edge.vertexIndices[ 0 ];
  51. vertexB = edge.vertexIndices[ 1 ];
  52. // find combination and processed vertex index (vertices are split up by renderer)
  53. if( faceA.a === vertexA ) { faceACombination = "a"; faceAvertexAIndex = vertexOffsetPerFace[ faceAIndex ] + 0; }
  54. else if( faceA.b === vertexA ) { faceACombination = "b"; faceAvertexAIndex = vertexOffsetPerFace[ faceAIndex ] + 1; }
  55. else if( faceA.c === vertexA ) { faceACombination = "c"; faceAvertexAIndex = vertexOffsetPerFace[ faceAIndex ] + 2; }
  56. else if( faceA.d === vertexA ) { faceACombination = "d"; faceAvertexAIndex = vertexOffsetPerFace[ faceAIndex ] + 3; }
  57. if( faceA.a === vertexB ) { faceACombination += "a"; faceAvertexBIndex = vertexOffsetPerFace[ faceAIndex ] + 0; }
  58. else if( faceA.b === vertexB ) { faceACombination += "b"; faceAvertexBIndex = vertexOffsetPerFace[ faceAIndex ] + 1; }
  59. else if( faceA.c === vertexB ) { faceACombination += "c"; faceAvertexBIndex = vertexOffsetPerFace[ faceAIndex ] + 2; }
  60. else if( faceA.d === vertexB ) { faceACombination += "d"; faceAvertexBIndex = vertexOffsetPerFace[ faceAIndex ] + 3; }
  61. if( faceB.a === vertexA ) { faceBCombination = "a"; faceBvertexAIndex = vertexOffsetPerFace[ faceBIndex ] + 0; }
  62. else if( faceB.b === vertexA ) { faceBCombination = "b"; faceBvertexAIndex = vertexOffsetPerFace[ faceBIndex ] + 1; }
  63. else if( faceB.c === vertexA ) { faceBCombination = "c"; faceBvertexAIndex = vertexOffsetPerFace[ faceBIndex ] + 2; }
  64. else if( faceB.d === vertexA ) { faceBCombination = "d"; faceBvertexAIndex = vertexOffsetPerFace[ faceBIndex ] + 3; }
  65. if( faceB.a === vertexB ) { faceBCombination += "a"; faceBvertexBIndex = vertexOffsetPerFace[ faceBIndex ] + 0; }
  66. else if( faceB.b === vertexB ) { faceBCombination += "b"; faceBvertexBIndex = vertexOffsetPerFace[ faceBIndex ] + 1; }
  67. else if( faceB.c === vertexB ) { faceBCombination += "c"; faceBvertexBIndex = vertexOffsetPerFace[ faceBIndex ] + 2; }
  68. else if( faceB.d === vertexB ) { faceBCombination += "d"; faceBvertexBIndex = vertexOffsetPerFace[ faceBIndex ] + 3; }
  69. if( faceACombination === "ac" ||
  70. faceACombination === "ad" ||
  71. faceACombination === "ca" ||
  72. faceACombination === "da" ) {
  73. if( faceAvertexAIndex > faceAvertexBIndex ) {
  74. temp = faceAvertexAIndex;
  75. faceAvertexAIndex = faceAvertexBIndex;
  76. faceAvertexBIndex = temp;
  77. }
  78. } else {
  79. if( faceAvertexAIndex < faceAvertexBIndex ) {
  80. temp = faceAvertexAIndex;
  81. faceAvertexAIndex = faceAvertexBIndex;
  82. faceAvertexBIndex = temp;
  83. }
  84. }
  85. if( faceBCombination === "ac" ||
  86. faceBCombination === "ad" ||
  87. faceBCombination === "ca" ||
  88. faceBCombination === "da" ) {
  89. if( faceBvertexAIndex > faceBvertexBIndex ) {
  90. temp = faceBvertexAIndex;
  91. faceBvertexAIndex = faceBvertexBIndex;
  92. faceBvertexBIndex = temp;
  93. }
  94. } else {
  95. if( faceBvertexAIndex < faceBvertexBIndex ) {
  96. temp = faceBvertexAIndex;
  97. faceBvertexAIndex = faceBvertexBIndex;
  98. faceBvertexBIndex = temp;
  99. }
  100. }
  101. face = new THREE.Face4( faceAvertexAIndex, faceAvertexBIndex, faceBvertexAIndex, faceBvertexBIndex );
  102. face.normal.set( 1, 0, 0 );
  103. edgeFaces.push( face );
  104. }
  105. this.geometry = newGeometry;
  106. } else {
  107. this.calculateShadowVolumeGeometryWithoutEdgeInfo( this.geometry );
  108. }
  109. }
  110. THREE.ShadowVolume.prototype.calculateShadowVolumeGeometryWithoutEdgeInfo = function( originalGeometry ) {
  111. // create geometry
  112. this.geometry = new THREE.Geometry();
  113. this.geometry.boundingSphere = originalGeometry.boundingSphere;
  114. this.geometry.edgeFaces = [];
  115. // copy vertices / faces from original mesh
  116. var vertexTypes = this.geometry.vertexTypes;
  117. var vertices = this.geometry.vertices;
  118. var faces = this.geometry.faces;
  119. var edgeFaces = this.geometry.edgeFaces;
  120. var originalFaces = originalGeometry.faces;
  121. var originalVertices = originalGeometry.vertices;
  122. var fl = originalFaces.length;
  123. var originalFace, face, i, f, n, vertex, numVertices;
  124. var indices = [ "a", "b", "c", "d" ];
  125. for( f = 0; f < fl; f++ ) {
  126. numVertices = vertices.length;
  127. originalFace = originalFaces[ f ];
  128. if ( originalFace instanceof THREE.Face4 ) {
  129. n = 4;
  130. face = new THREE.Face4( numVertices, numVertices + 1, numVertices + 2, numVertices + 3 );
  131. } else {
  132. n = 3;
  133. face = new THREE.Face3( numVertices, numVertices + 1, numVertices + 2 );
  134. }
  135. face.normal.copy( originalFace.normal );
  136. faces.push( face );
  137. for( i = 0; i < n; i++ ) {
  138. vertex = originalVertices[ originalFace[ indices[ i ]]];
  139. vertices.push( new THREE.Vertex( vertex.position.clone()));
  140. }
  141. }
  142. // calculate edge faces
  143. var result, faceA, faceB, v, vl;
  144. for( var fa = 0; fa < originalFaces.length - 1; fa++ ) {
  145. faceA = faces[ fa ];
  146. for( var fb = fa + 1; fb < originalFaces.length; fb++ ) {
  147. faceB = faces[ fb ];
  148. result = this.facesShareEdge( vertices, faceA, faceB );
  149. if( result !== undefined ) {
  150. numVertices = vertices.length;
  151. face = new THREE.Face4( result.indices[ 0 ], result.indices[ 3 ], result.indices[ 2 ], result.indices[ 1 ] );
  152. face.normal.set( 1, 0, 0 );
  153. edgeFaces.push( face );
  154. }
  155. }
  156. }
  157. };
  158. THREE.ShadowVolume.prototype.facesShareEdge = function( vertices, faceA, faceB ) {
  159. var indicesA,
  160. indicesB,
  161. indexA,
  162. indexB,
  163. vertexA,
  164. vertexB,
  165. savedVertexA,
  166. savedVertexB,
  167. savedIndexA,
  168. savedIndexB,
  169. indexLetters,
  170. a, b,
  171. numMatches = 0,
  172. indices = [ "a", "b", "c", "d" ];
  173. if( faceA instanceof THREE.Face4 ) indicesA = 4;
  174. else indicesA = 3;
  175. if( faceB instanceof THREE.Face4 ) indicesB = 4;
  176. else indicesB = 3;
  177. for( a = 0; a < indicesA; a++ ) {
  178. indexA = faceA[ indices[ a ] ];
  179. vertexA = vertices[ indexA ];
  180. for( b = 0; b < indicesB; b++ ) {
  181. indexB = faceB[ indices[ b ] ];
  182. vertexB = vertices[ indexB ];
  183. if( Math.abs( vertexA.position.x - vertexB.position.x ) < 0.0001 &&
  184. Math.abs( vertexA.position.y - vertexB.position.y ) < 0.0001 &&
  185. Math.abs( vertexA.position.z - vertexB.position.z ) < 0.0001 ) {
  186. numMatches++;
  187. if( numMatches === 1 ) {
  188. savedVertexA = vertexA;
  189. savedVertexB = vertexB;
  190. savedIndexA = indexA;
  191. savedIndexB = indexB;
  192. indexLetters = indices[ a ];
  193. }
  194. if( numMatches === 2 ) {
  195. indexLetters += indices[ a ];
  196. if( indexLetters === "ad" || indexLetters === "ac" ) {
  197. return {
  198. faces : [ faceA, faceB ],
  199. vertices : [ savedVertexA, savedVertexB, vertexB, vertexA ],
  200. indices : [ savedIndexA, savedIndexB, indexB, indexA ],
  201. vertexTypes : [ 1, 2, 2, 1 ],
  202. extrudable : true
  203. };
  204. } else {
  205. return {
  206. faces : [ faceA, faceB ],
  207. vertices : [ savedVertexA, vertexA, vertexB, savedVertexB ],
  208. indices : [ savedIndexA, indexA, indexB, savedIndexB ],
  209. vertexTypes : [ 1, 1, 2, 2 ],
  210. extrudable : true
  211. };
  212. }
  213. }
  214. }
  215. }
  216. }
  217. return undefined;
  218. };
粤ICP备19079148号