|
@@ -2,12 +2,20 @@
|
|
|
* @author mikael emtinger / http://gomo.se/
|
|
|
*/
|
|
|
|
|
|
-THREE.ShadowVolume = function( mesh, isStatic ) {
|
|
|
+THREE.ShadowVolume = function( meshOrGeometry, isStatic ) {
|
|
|
|
|
|
- THREE.Mesh.call( this, mesh.geometry, isStatic ? [ new THREE.ShadowVolumeDynamicMaterial() ] : [ new THREE.ShadowVolumeDynamicMaterial() ] );
|
|
|
- mesh.addChild( this );
|
|
|
-
|
|
|
- this.calculateShadowVolumeGeometry( mesh.geometry );
|
|
|
+ if( meshOrGeometry instanceof THREE.Mesh ) {
|
|
|
+
|
|
|
+ THREE.Mesh.call( this, meshOrGeometry.geometry, isStatic ? [ new THREE.ShadowVolumeDynamicMaterial() ] : [ new THREE.ShadowVolumeDynamicMaterial() ] );
|
|
|
+ meshOrGeometry.addChild( this );
|
|
|
+
|
|
|
+ } else {
|
|
|
+
|
|
|
+ THREE.Mesh.call( this, meshOrGeometry, isStatic ? [ new THREE.ShadowVolumeDynamicMaterial() ] : [ new THREE.ShadowVolumeDynamicMaterial() ] );
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ this.calculateShadowVolumeGeometry();
|
|
|
|
|
|
};
|
|
|
|
|
@@ -17,10 +25,153 @@ THREE.ShadowVolume.prototype.supr = THREE.Mesh.prototype;
|
|
|
|
|
|
|
|
|
/*
|
|
|
- * Calculate Geometry
|
|
|
+ * Calculate Shadow Faces
|
|
|
*/
|
|
|
|
|
|
-THREE.ShadowVolume.prototype.calculateShadowVolumeGeometry = function( originalGeometry ) {
|
|
|
+THREE.ShadowVolume.prototype.calculateShadowVolumeGeometry = function() {
|
|
|
+
|
|
|
+ if( this.geometry.edges && this.geometry.edges.length ) {
|
|
|
+
|
|
|
+ var f, fl, face, faceA, faceB, faceAIndex, faceBIndex, vertexA, vertexB;
|
|
|
+ var faceACombination, faceBCombination;
|
|
|
+ var faceAvertexAIndex, faceAvertexBIndex, faceBvertexAIndex, faceBvertexBIndex;
|
|
|
+ var e, el, edge, temp;
|
|
|
+
|
|
|
+ var newGeometry = new THREE.Geometry();
|
|
|
+ var vertices = newGeometry.vertices = this.geometry.vertices;
|
|
|
+ var faces = newGeometry.faces = this.geometry.faces;
|
|
|
+ var edges = newGeometry.egdes = this.geometry.edges;
|
|
|
+ var edgeFaces = newGeometry.edgeFaces = [];
|
|
|
+
|
|
|
+ var vertexOffset = 0;
|
|
|
+ var vertexOffsetPerFace = [];
|
|
|
+
|
|
|
+ for( f = 0, fl = faces.length; f < fl; f++ ) {
|
|
|
+
|
|
|
+ face = faces[ f ];
|
|
|
+
|
|
|
+ // calculate faces vertex offset
|
|
|
+
|
|
|
+ vertexOffsetPerFace.push( vertexOffset );
|
|
|
+ vertexOffset += face instanceof THREE.Face3 ? 3 : 4;
|
|
|
+
|
|
|
+ // set vertex normals to face normal
|
|
|
+
|
|
|
+ face.vertexNormals[ 0 ] = face.normal;
|
|
|
+ face.vertexNormals[ 1 ] = face.normal;
|
|
|
+ face.vertexNormals[ 2 ] = face.normal;
|
|
|
+
|
|
|
+ if( face instanceof THREE.Face4 ) face.vertexNormals[ 3 ] = face.normal;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ // setup edge faces
|
|
|
+
|
|
|
+ for( e = 0, el = edges.length; e < el; e++ ) {
|
|
|
+
|
|
|
+ edge = edges[ e ];
|
|
|
+
|
|
|
+ faceA = edge.faces[ 0 ];
|
|
|
+ faceB = edge.faces[ 1 ];
|
|
|
+
|
|
|
+ faceAIndex = edge.faceIndices[ 0 ];
|
|
|
+ faceBIndex = edge.faceIndices[ 1 ];
|
|
|
+
|
|
|
+ vertexA = edge.vertexIndices[ 0 ];
|
|
|
+ vertexB = edge.vertexIndices[ 1 ];
|
|
|
+
|
|
|
+ // find combination and processed vertex index (vertices are split up by renderer)
|
|
|
+
|
|
|
+ if( faceA.a === vertexA ) { faceACombination = "a"; faceAvertexAIndex = vertexOffsetPerFace[ faceAIndex ] + 0; }
|
|
|
+ else if( faceA.b === vertexA ) { faceACombination = "b"; faceAvertexAIndex = vertexOffsetPerFace[ faceAIndex ] + 1; }
|
|
|
+ else if( faceA.c === vertexA ) { faceACombination = "c"; faceAvertexAIndex = vertexOffsetPerFace[ faceAIndex ] + 2; }
|
|
|
+ else if( faceA.d === vertexA ) { faceACombination = "d"; faceAvertexAIndex = vertexOffsetPerFace[ faceAIndex ] + 3; }
|
|
|
+
|
|
|
+ if( faceA.a === vertexB ) { faceACombination += "a"; faceAvertexBIndex = vertexOffsetPerFace[ faceAIndex ] + 0; }
|
|
|
+ else if( faceA.b === vertexB ) { faceACombination += "b"; faceAvertexBIndex = vertexOffsetPerFace[ faceAIndex ] + 1; }
|
|
|
+ else if( faceA.c === vertexB ) { faceACombination += "c"; faceAvertexBIndex = vertexOffsetPerFace[ faceAIndex ] + 2; }
|
|
|
+ else if( faceA.d === vertexB ) { faceACombination += "d"; faceAvertexBIndex = vertexOffsetPerFace[ faceAIndex ] + 3; }
|
|
|
+
|
|
|
+ if( faceB.a === vertexA ) { faceBCombination = "a"; faceBvertexAIndex = vertexOffsetPerFace[ faceBIndex ] + 0; }
|
|
|
+ else if( faceB.b === vertexA ) { faceBCombination = "b"; faceBvertexAIndex = vertexOffsetPerFace[ faceBIndex ] + 1; }
|
|
|
+ else if( faceB.c === vertexA ) { faceBCombination = "c"; faceBvertexAIndex = vertexOffsetPerFace[ faceBIndex ] + 2; }
|
|
|
+ else if( faceB.d === vertexA ) { faceBCombination = "d"; faceBvertexAIndex = vertexOffsetPerFace[ faceBIndex ] + 3; }
|
|
|
+
|
|
|
+ if( faceB.a === vertexB ) { faceBCombination += "a"; faceBvertexBIndex = vertexOffsetPerFace[ faceBIndex ] + 0; }
|
|
|
+ else if( faceB.b === vertexB ) { faceBCombination += "b"; faceBvertexBIndex = vertexOffsetPerFace[ faceBIndex ] + 1; }
|
|
|
+ else if( faceB.c === vertexB ) { faceBCombination += "c"; faceBvertexBIndex = vertexOffsetPerFace[ faceBIndex ] + 2; }
|
|
|
+ else if( faceB.d === vertexB ) { faceBCombination += "d"; faceBvertexBIndex = vertexOffsetPerFace[ faceBIndex ] + 3; }
|
|
|
+
|
|
|
+ if( faceACombination === "ac" ||
|
|
|
+ faceACombination === "ad" ||
|
|
|
+ faceACombination === "ca" ||
|
|
|
+ faceACombination === "da" ) {
|
|
|
+
|
|
|
+ if( faceAvertexAIndex > faceAvertexBIndex ) {
|
|
|
+
|
|
|
+ temp = faceAvertexAIndex;
|
|
|
+ faceAvertexAIndex = faceAvertexBIndex;
|
|
|
+ faceAvertexBIndex = temp;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ } else {
|
|
|
+
|
|
|
+ if( faceAvertexAIndex < faceAvertexBIndex ) {
|
|
|
+
|
|
|
+ temp = faceAvertexAIndex;
|
|
|
+ faceAvertexAIndex = faceAvertexBIndex;
|
|
|
+ faceAvertexBIndex = temp;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ if( faceBCombination === "ac" ||
|
|
|
+ faceBCombination === "ad" ||
|
|
|
+ faceBCombination === "ca" ||
|
|
|
+ faceBCombination === "da" ) {
|
|
|
+
|
|
|
+ if( faceBvertexAIndex > faceBvertexBIndex ) {
|
|
|
+
|
|
|
+ temp = faceBvertexAIndex;
|
|
|
+ faceBvertexAIndex = faceBvertexBIndex;
|
|
|
+ faceBvertexBIndex = temp;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ } else {
|
|
|
+
|
|
|
+ if( faceBvertexAIndex < faceBvertexBIndex ) {
|
|
|
+
|
|
|
+ temp = faceBvertexAIndex;
|
|
|
+ faceBvertexAIndex = faceBvertexBIndex;
|
|
|
+ faceBvertexBIndex = temp;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ face = new THREE.Face4( faceAvertexAIndex, faceAvertexBIndex, faceBvertexAIndex, faceBvertexBIndex );
|
|
|
+ face.normal.set( 1, 0, 0 );
|
|
|
+ edgeFaces.push( face );
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ this.geometry = newGeometry;
|
|
|
+
|
|
|
+ } else {
|
|
|
+
|
|
|
+ this.calculateShadowVolumeGeometryWithoutEdgeInfo( this.geometry );
|
|
|
+
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+THREE.ShadowVolume.prototype.calculateShadowVolumeGeometryWithoutEdgeInfo = function( originalGeometry ) {
|
|
|
|
|
|
// create geometry
|
|
|
|
|
@@ -103,11 +254,6 @@ THREE.ShadowVolume.prototype.calculateShadowVolumeGeometry = function( originalG
|
|
|
};
|
|
|
|
|
|
|
|
|
-
|
|
|
-/*
|
|
|
- * Faces share edge?
|
|
|
- */
|
|
|
-
|
|
|
THREE.ShadowVolume.prototype.facesShareEdge = function( vertices, faceA, faceB ) {
|
|
|
|
|
|
var indicesA,
|
|
@@ -199,4 +345,3 @@ THREE.ShadowVolume.prototype.facesShareEdge = function( vertices, faceA, faceB )
|
|
|
return undefined;
|
|
|
|
|
|
};
|
|
|
-
|