|
@@ -912,91 +912,144 @@ THREE.VRMLLoader.prototype = {
|
|
|
|
|
|
}
|
|
|
|
|
|
- var skip = 0;
|
|
|
-
|
|
|
// some shapes only have vertices for use in other shapes
|
|
|
|
|
|
if ( data.coordIndex ) {
|
|
|
|
|
|
+ function triangulateIndexArray( indexArray ) {
|
|
|
+
|
|
|
+ var triangulatedIndexArray = [];
|
|
|
+ var ccw = data.ccw === undefined ? true : data.ccw; // ccw is true by default
|
|
|
+ var skip = 0;
|
|
|
+
|
|
|
+ for ( i = 0, il = indexArray.length; i < il; i ++ ) {
|
|
|
+
|
|
|
+ var indexedFace = data.coordIndex[ i ];
|
|
|
+
|
|
|
+ // VRML support multipoint indexed face sets (more then 3 vertices). You must calculate the composing triangles here
|
|
|
+
|
|
|
+ skip = 0;
|
|
|
+
|
|
|
+ while ( indexedFace.length >= 3 && skip < ( indexedFace.length - 2 ) ) {
|
|
|
+
|
|
|
+ var i1 = indexedFace[ 0 ];
|
|
|
+ var i2 = indexedFace[ skip + ( ccw ? 1 : 2 ) ];
|
|
|
+ var i3 = indexedFace[ skip + ( ccw ? 2 : 1 ) ];
|
|
|
+
|
|
|
+ triangulatedIndexArray.push( i1, i2, i3 );
|
|
|
+
|
|
|
+ skip ++;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ return triangulatedIndexArray;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ var positionIndexes = data.coordIndex ? triangulateIndexArray( data.coordIndex ) : [];
|
|
|
+ var normalIndexes = data.normalIndex ? triangulateIndexArray( data.normalIndex ) : positionIndexes;
|
|
|
+ var colorIndexes = data.colorIndex ? triangulateIndexArray( data.colorIndex ) : positionIndexes;
|
|
|
+ var uvIndexes = data.texCoordIndex ? triangulateIndexArray( data.texCoordIndex ) : positionIndexes;
|
|
|
+
|
|
|
+ var newIndexes = [];
|
|
|
var newPositions = [];
|
|
|
- var newColors = [];
|
|
|
var newNormals = [];
|
|
|
+ var newColors = [];
|
|
|
var newUvs = [];
|
|
|
|
|
|
- position = new THREE.Vector3();
|
|
|
- color = new THREE.Color();
|
|
|
- normal = new THREE.Vector3();
|
|
|
- uv = new THREE.Vector2();
|
|
|
+ // if any other index array does not match the coordinate indexes, split any points that differ
|
|
|
|
|
|
- for ( i = 0, il = data.coordIndex.length; i < il; i ++ ) {
|
|
|
+ var pointMap = Object.create( null );
|
|
|
|
|
|
- var indexes = data.coordIndex[ i ];
|
|
|
+ for ( i = 0; i < positionIndexes.length; i ++ ) {
|
|
|
|
|
|
- // VRML support multipoint indexed face sets (more then 3 vertices). You must calculate the composing triangles here
|
|
|
+ var pointAttributes = [];
|
|
|
|
|
|
- skip = 0;
|
|
|
+ var positionIndex = positionIndexes[ i ];
|
|
|
+ var normalIndex = normalIndexes[ i ];
|
|
|
+ var colorIndex = colorIndexes[ i ];
|
|
|
+ var uvIndex = uvIndexes[ i ];
|
|
|
|
|
|
- while ( indexes.length >= 3 && skip < ( indexes.length - 2 ) ) {
|
|
|
+ var base = 10; // which base to use to represent each value
|
|
|
|
|
|
- if ( data.ccw === undefined ) data.ccw = true; // ccw is true by default
|
|
|
+ pointAttributes.push( positionIndex.toString( base ) );
|
|
|
|
|
|
- var i1 = indexes[ 0 ];
|
|
|
- var i2 = indexes[ skip + ( data.ccw ? 1 : 2 ) ];
|
|
|
- var i3 = indexes[ skip + ( data.ccw ? 2 : 1 ) ];
|
|
|
+ if ( normalIndex !== undefined ) {
|
|
|
|
|
|
- // create non indexed geometry, necessary for face normal generation
|
|
|
+ pointAttributes.push( normalIndex.toString( base ) );
|
|
|
|
|
|
- position.fromArray( positions, i1 * 3 );
|
|
|
- newPositions.push( position.x, position.y, position.z );
|
|
|
- position.fromArray( positions, i2 * 3 );
|
|
|
- newPositions.push( position.x, position.y, position.z );
|
|
|
- position.fromArray( positions, i3 * 3 );
|
|
|
- newPositions.push( position.x, position.y, position.z );
|
|
|
+ }
|
|
|
|
|
|
- if ( colors.length > 0 ) {
|
|
|
+ if ( colorIndex !== undefined ) {
|
|
|
|
|
|
- color.fromArray( colors, i1 * 3 );
|
|
|
- newColors.push( color.r, color.g, color.b );
|
|
|
- color.fromArray( colors, i2 * 3 );
|
|
|
- newColors.push( color.r, color.g, color.b );
|
|
|
- color.fromArray( colors, i3 * 3 );
|
|
|
- newColors.push( color.r, color.g, color.b );
|
|
|
+ pointAttributes.push( colorIndex.toString( base ) );
|
|
|
|
|
|
- }
|
|
|
+ }
|
|
|
|
|
|
- if ( uvs.length > 0 ) {
|
|
|
+ if ( uvIndex !== undefined ) {
|
|
|
|
|
|
- uv.fromArray( uvs, i1 * 2 );
|
|
|
- newUvs.push( uv.x, uv.y );
|
|
|
- uv.fromArray( uvs, i2 * 2 );
|
|
|
- newUvs.push( uv.x, uv.y );
|
|
|
- uv.fromArray( uvs, i3 * 2 );
|
|
|
- newUvs.push( uv.x, uv.y );
|
|
|
+ pointAttributes.push( uvIndex.toString( base ) );
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ var pointId = pointAttributes.join( ',' );
|
|
|
+ var newIndex = pointMap[ pointId ];
|
|
|
+
|
|
|
+ if ( newIndex === undefined ) {
|
|
|
+
|
|
|
+ newIndex = newPositions.length / 3;
|
|
|
+ pointMap[ pointId ] = newIndex;
|
|
|
+
|
|
|
+ newPositions.push(
|
|
|
+ positions[ positionIndex * 3 ],
|
|
|
+ positions[ positionIndex * 3 + 1 ],
|
|
|
+ positions[ positionIndex * 3 + 2 ]
|
|
|
+ );
|
|
|
+
|
|
|
+ if ( normalIndex !== undefined && normals.length > 0 ) {
|
|
|
+
|
|
|
+ newNormals.push(
|
|
|
+ normals[ normalIndex * 3 ],
|
|
|
+ normals[ normalIndex * 3 + 1 ],
|
|
|
+ normals[ normalIndex * 3 + 2 ]
|
|
|
+ );
|
|
|
|
|
|
}
|
|
|
|
|
|
- if ( normals.length > 0 ) {
|
|
|
+ if ( colorIndex !== undefined && colors.length > 0 ) {
|
|
|
|
|
|
- normal.fromArray( normals, i1 * 3 );
|
|
|
- newNormals.push( normal.x, normal.y, normal.z );
|
|
|
- normal.fromArray( normals, i2 * 3 );
|
|
|
- newNormals.push( normal.x, normal.y, normal.z );
|
|
|
- normal.fromArray( normals, i3 * 3 );
|
|
|
- newNormals.push( normal.x, normal.y, normal.z );
|
|
|
+ newColors.push(
|
|
|
+ colors[ colorIndex * 3 ],
|
|
|
+ colors[ colorIndex * 3 + 1 ],
|
|
|
+ colors[ colorIndex * 3 + 2 ]
|
|
|
+ );
|
|
|
|
|
|
}
|
|
|
|
|
|
- skip ++;
|
|
|
+ if ( uvIndex !== undefined && uvs.length > 0 ) {
|
|
|
+
|
|
|
+ newUvs.push(
|
|
|
+ uvs[ uvIndex * 2 ],
|
|
|
+ uvs[ uvIndex * 2 + 1 ]
|
|
|
+ );
|
|
|
+
|
|
|
+ }
|
|
|
|
|
|
}
|
|
|
|
|
|
+ newIndexes.push( newIndex );
|
|
|
+
|
|
|
}
|
|
|
|
|
|
positions = newPositions;
|
|
|
- colors = newColors;
|
|
|
normals = newNormals;
|
|
|
+ color = newColors;
|
|
|
uvs = newUvs;
|
|
|
|
|
|
+ geometry.setIndex( newIndexes );
|
|
|
+
|
|
|
} else {
|
|
|
|
|
|
// do not add dummy mesh to the scene
|
|
@@ -1034,6 +1087,8 @@ THREE.VRMLLoader.prototype = {
|
|
|
|
|
|
} else {
|
|
|
|
|
|
+ // convert geometry to non-indexed to get sharp normals
|
|
|
+ geometry = geometry.toNonIndexed();
|
|
|
geometry.computeVertexNormals();
|
|
|
|
|
|
}
|