Skip to content

Commit 70cc5f7

Browse files
authored
Merge pull request #14862 from Glinkis/patch-3
Update VRMLLoader to use or create an indexed geometry.
2 parents 9ff1e25 + 3c37371 commit 70cc5f7

File tree

1 file changed

+102
-47
lines changed

1 file changed

+102
-47
lines changed

examples/js/loaders/VRMLLoader.js

Lines changed: 102 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)