@@ -912,91 +912,144 @@ THREE.VRMLLoader.prototype = {
912912
913913 }
914914
915- var skip = 0 ;
916-
917915 // some shapes only have vertices for use in other shapes
918916
919917 if ( data . coordIndex ) {
920918
919+ function triangulateIndexArray ( indexArray ) {
920+
921+ var triangulatedIndexArray = [ ] ;
922+ var ccw = data . ccw === undefined ? true : data . ccw ; // ccw is true by default
923+ var skip = 0 ;
924+
925+ for ( i = 0 , il = indexArray . length ; i < il ; i ++ ) {
926+
927+ var indexedFace = data . coordIndex [ i ] ;
928+
929+ // VRML support multipoint indexed face sets (more then 3 vertices). You must calculate the composing triangles here
930+
931+ skip = 0 ;
932+
933+ while ( indexedFace . length >= 3 && skip < ( indexedFace . length - 2 ) ) {
934+
935+ var i1 = indexedFace [ 0 ] ;
936+ var i2 = indexedFace [ skip + ( ccw ? 1 : 2 ) ] ;
937+ var i3 = indexedFace [ skip + ( ccw ? 2 : 1 ) ] ;
938+
939+ triangulatedIndexArray . push ( i1 , i2 , i3 ) ;
940+
941+ skip ++ ;
942+
943+ }
944+
945+ }
946+
947+ return triangulatedIndexArray ;
948+
949+ }
950+
951+ var positionIndexes = data . coordIndex ? triangulateIndexArray ( data . coordIndex ) : [ ] ;
952+ var normalIndexes = data . normalIndex ? triangulateIndexArray ( data . normalIndex ) : positionIndexes ;
953+ var colorIndexes = data . colorIndex ? triangulateIndexArray ( data . colorIndex ) : positionIndexes ;
954+ var uvIndexes = data . texCoordIndex ? triangulateIndexArray ( data . texCoordIndex ) : positionIndexes ;
955+
956+ var newIndexes = [ ] ;
921957 var newPositions = [ ] ;
922- var newColors = [ ] ;
923958 var newNormals = [ ] ;
959+ var newColors = [ ] ;
924960 var newUvs = [ ] ;
925961
926- position = new THREE . Vector3 ( ) ;
927- color = new THREE . Color ( ) ;
928- normal = new THREE . Vector3 ( ) ;
929- uv = new THREE . Vector2 ( ) ;
962+ // if any other index array does not match the coordinate indexes, split any points that differ
930963
931- for ( i = 0 , il = data . coordIndex . length ; i < il ; i ++ ) {
964+ var pointMap = Object . create ( null ) ;
932965
933- var indexes = data . coordIndex [ i ] ;
966+ for ( i = 0 ; i < positionIndexes . length ; i ++ ) {
934967
935- // VRML support multipoint indexed face sets (more then 3 vertices). You must calculate the composing triangles here
968+ var pointAttributes = [ ] ;
936969
937- skip = 0 ;
970+ var positionIndex = positionIndexes [ i ] ;
971+ var normalIndex = normalIndexes [ i ] ;
972+ var colorIndex = colorIndexes [ i ] ;
973+ var uvIndex = uvIndexes [ i ] ;
938974
939- while ( indexes . length >= 3 && skip < ( indexes . length - 2 ) ) {
975+ var base = 10 ; // which base to use to represent each value
940976
941- if ( data . ccw === undefined ) data . ccw = true ; // ccw is true by default
977+ pointAttributes . push ( positionIndex . toString ( base ) ) ;
942978
943- var i1 = indexes [ 0 ] ;
944- var i2 = indexes [ skip + ( data . ccw ? 1 : 2 ) ] ;
945- var i3 = indexes [ skip + ( data . ccw ? 2 : 1 ) ] ;
979+ if ( normalIndex !== undefined ) {
946980
947- // create non indexed geometry, necessary for face normal generation
981+ pointAttributes . push ( normalIndex . toString ( base ) ) ;
948982
949- position . fromArray ( positions , i1 * 3 ) ;
950- newPositions . push ( position . x , position . y , position . z ) ;
951- position . fromArray ( positions , i2 * 3 ) ;
952- newPositions . push ( position . x , position . y , position . z ) ;
953- position . fromArray ( positions , i3 * 3 ) ;
954- newPositions . push ( position . x , position . y , position . z ) ;
983+ }
955984
956- if ( colors . length > 0 ) {
985+ if ( colorIndex !== undefined ) {
957986
958- color . fromArray ( colors , i1 * 3 ) ;
959- newColors . push ( color . r , color . g , color . b ) ;
960- color . fromArray ( colors , i2 * 3 ) ;
961- newColors . push ( color . r , color . g , color . b ) ;
962- color . fromArray ( colors , i3 * 3 ) ;
963- newColors . push ( color . r , color . g , color . b ) ;
987+ pointAttributes . push ( colorIndex . toString ( base ) ) ;
964988
965- }
989+ }
966990
967- if ( uvs . length > 0 ) {
991+ if ( uvIndex !== undefined ) {
968992
969- uv . fromArray ( uvs , i1 * 2 ) ;
970- newUvs . push ( uv . x , uv . y ) ;
971- uv . fromArray ( uvs , i2 * 2 ) ;
972- newUvs . push ( uv . x , uv . y ) ;
973- uv . fromArray ( uvs , i3 * 2 ) ;
974- newUvs . push ( uv . x , uv . y ) ;
993+ pointAttributes . push ( uvIndex . toString ( base ) ) ;
994+
995+ }
996+
997+ var pointId = pointAttributes . join ( ',' ) ;
998+ var newIndex = pointMap [ pointId ] ;
999+
1000+ if ( newIndex === undefined ) {
1001+
1002+ newIndex = newPositions . length / 3 ;
1003+ pointMap [ pointId ] = newIndex ;
1004+
1005+ newPositions . push (
1006+ positions [ positionIndex * 3 ] ,
1007+ positions [ positionIndex * 3 + 1 ] ,
1008+ positions [ positionIndex * 3 + 2 ]
1009+ ) ;
1010+
1011+ if ( normalIndex !== undefined && normals . length > 0 ) {
1012+
1013+ newNormals . push (
1014+ normals [ normalIndex * 3 ] ,
1015+ normals [ normalIndex * 3 + 1 ] ,
1016+ normals [ normalIndex * 3 + 2 ]
1017+ ) ;
9751018
9761019 }
9771020
978- if ( normals . length > 0 ) {
1021+ if ( colorIndex !== undefined && colors . length > 0 ) {
9791022
980- normal . fromArray ( normals , i1 * 3 ) ;
981- newNormals . push ( normal . x , normal . y , normal . z ) ;
982- normal . fromArray ( normals , i2 * 3 ) ;
983- newNormals . push ( normal . x , normal . y , normal . z ) ;
984- normal . fromArray ( normals , i3 * 3 ) ;
985- newNormals . push ( normal . x , normal . y , normal . z ) ;
1023+ newColors . push (
1024+ colors [ colorIndex * 3 ] ,
1025+ colors [ colorIndex * 3 + 1 ] ,
1026+ colors [ colorIndex * 3 + 2 ]
1027+ ) ;
9861028
9871029 }
9881030
989- skip ++ ;
1031+ if ( uvIndex !== undefined && uvs . length > 0 ) {
1032+
1033+ newUvs . push (
1034+ uvs [ uvIndex * 2 ] ,
1035+ uvs [ uvIndex * 2 + 1 ]
1036+ ) ;
1037+
1038+ }
9901039
9911040 }
9921041
1042+ newIndexes . push ( newIndex ) ;
1043+
9931044 }
9941045
9951046 positions = newPositions ;
996- colors = newColors ;
9971047 normals = newNormals ;
1048+ color = newColors ;
9981049 uvs = newUvs ;
9991050
1051+ geometry . setIndex ( newIndexes ) ;
1052+
10001053 } else {
10011054
10021055 // do not add dummy mesh to the scene
@@ -1034,6 +1087,8 @@ THREE.VRMLLoader.prototype = {
10341087
10351088 } else {
10361089
1090+ // convert geometry to non-indexed to get sharp normals
1091+ geometry = geometry . toNonIndexed ( ) ;
10371092 geometry . computeVertexNormals ( ) ;
10381093
10391094 }
0 commit comments