|
@@ -54,44 +54,19 @@ THREE.VRMLLoader.prototype = {
|
|
|
var textureLoader = new THREE.TextureLoader( this.manager );
|
|
|
textureLoader.setCrossOrigin( this.crossOrigin );
|
|
|
|
|
|
- var parseV1 = function ( lines, scene ) {
|
|
|
+ function parseV1( lines, scene ) {
|
|
|
|
|
|
- console.warn( 'VRML V1.0 not supported yet' );
|
|
|
+ console.warn( 'THREE.VRMLLoader: V1.0 not supported yet.' );
|
|
|
|
|
|
};
|
|
|
|
|
|
- var parseV2 = function ( lines, scene ) {
|
|
|
+ function parseV2( lines, scene ) {
|
|
|
|
|
|
var defines = {};
|
|
|
var float_pattern = /(\b|\-|\+)([\d\.e]+)/;
|
|
|
var float2_pattern = /([\d\.\+\-e]+)\s+([\d\.\+\-e]+)/g;
|
|
|
var float3_pattern = /([\d\.\+\-e]+)\s+([\d\.\+\-e]+)\s+([\d\.\+\-e]+)/g;
|
|
|
|
|
|
- /**
|
|
|
- * Interpolates colors a and b following their relative distance
|
|
|
- * expressed by t.
|
|
|
- *
|
|
|
- * @param float a
|
|
|
- * @param float b
|
|
|
- * @param float t
|
|
|
- * @returns {Color}
|
|
|
- */
|
|
|
- var interpolateColors = function( a, b, t ) {
|
|
|
-
|
|
|
- var deltaR = a.r - b.r;
|
|
|
- var deltaG = a.g - b.g;
|
|
|
- var deltaB = a.b - b.b;
|
|
|
-
|
|
|
- var c = new THREE.Color();
|
|
|
-
|
|
|
- c.r = a.r - t * deltaR;
|
|
|
- c.g = a.g - t * deltaG;
|
|
|
- c.b = a.b - t * deltaB;
|
|
|
-
|
|
|
- return c;
|
|
|
-
|
|
|
- };
|
|
|
-
|
|
|
/**
|
|
|
* Vertically paints the faces interpolating between the
|
|
|
* specified colors at the specified angels. This is used for the Background
|
|
@@ -112,13 +87,11 @@ THREE.VRMLLoader.prototype = {
|
|
|
* @param radius
|
|
|
* @param angles
|
|
|
* @param colors
|
|
|
- * @param boolean directionIsDown Whether to work bottom up or top down.
|
|
|
+ * @param boolean topDown Whether to work top down or bottom up.
|
|
|
*/
|
|
|
- var paintFaces = function ( geometry, radius, angles, colors, directionIsDown ) {
|
|
|
+ function paintFaces( geometry, radius, angles, colors, topDown ) {
|
|
|
|
|
|
- var direction = directionIsDown ? 1 : - 1;
|
|
|
-
|
|
|
- var faceIndices = [ 'a', 'b', 'c', 'd' ];
|
|
|
+ var direction = ( topDown === true ) ? 1 : - 1;
|
|
|
|
|
|
var coord = [], A = {}, B = {}, applyColor = false;
|
|
|
|
|
@@ -135,62 +108,66 @@ THREE.VRMLLoader.prototype = {
|
|
|
|
|
|
}
|
|
|
|
|
|
- // painting the colors on the faces
|
|
|
- for ( var i = 0; i < geometry.faces.length ; i ++ ) {
|
|
|
+ var index = geometry.index;
|
|
|
+ var positionAttribute = geometry.attributes.position;
|
|
|
+ var colorAttribute = new THREE.BufferAttribute( new Float32Array( geometry.attributes.position.count * 3 ), 3 );
|
|
|
|
|
|
- var f = geometry.faces[ i ];
|
|
|
+ var position = new THREE.Vector3();
|
|
|
+ var color = new THREE.Color();
|
|
|
|
|
|
- var n = ( f instanceof THREE.Face3 ) ? 3 : 4;
|
|
|
+ for ( var i = 0; i < index.count; i ++ ) {
|
|
|
|
|
|
- for ( var j = 0; j < n; j ++ ) {
|
|
|
+ var vertexIndex = index.getX( i );
|
|
|
|
|
|
- var vertexIndex = f[ faceIndices[ j ] ];
|
|
|
+ position.fromBufferAttribute( positionAttribute, vertexIndex );
|
|
|
|
|
|
- var p = geometry.vertices[ vertexIndex ];
|
|
|
+ for ( var j = 0; j < colors.length; j ++ ) {
|
|
|
|
|
|
- for ( var index = 0; index < colors.length; index ++ ) {
|
|
|
+ // linear interpolation between aColor and bColor, calculate proportion
|
|
|
+ // A is previous point (angle)
|
|
|
|
|
|
- // linear interpolation between aColor and bColor, calculate proportion
|
|
|
- // A is previous point (angle)
|
|
|
- if ( index === 0 ) {
|
|
|
+ if ( j === 0 ) {
|
|
|
|
|
|
- A.x = 0;
|
|
|
- A.y = directionIsDown ? radius : - 1 * radius;
|
|
|
+ A.x = 0;
|
|
|
+ A.y = ( topDown === true ) ? radius : - 1 * radius;
|
|
|
|
|
|
- } else {
|
|
|
+ } else {
|
|
|
|
|
|
- A.x = coord[ index - 1 ].x;
|
|
|
- A.y = coord[ index - 1 ].y;
|
|
|
+ A.x = coord[ j - 1 ].x;
|
|
|
+ A.y = coord[ j - 1 ].y;
|
|
|
|
|
|
- }
|
|
|
+ }
|
|
|
|
|
|
- // B is current point (angle)
|
|
|
- B = coord[ index ];
|
|
|
+ // B is current point (angle)
|
|
|
|
|
|
- if ( undefined !== B ) {
|
|
|
+ B = coord[ j ];
|
|
|
|
|
|
- // p has to be between the points A and B which we interpolate
|
|
|
- applyColor = directionIsDown ? p.y <= A.y && p.y > B.y : p.y >= A.y && p.y < B.y;
|
|
|
+ if ( B !== undefined ) {
|
|
|
|
|
|
- if ( applyColor ) {
|
|
|
+ // p has to be between the points A and B which we interpolate
|
|
|
|
|
|
- var aColor = colors[ index ];
|
|
|
- var bColor = colors[ index + 1 ];
|
|
|
+ applyColor = ( topDown === true ) ? ( position.y <= A.y && position.y > B.y ) : ( position.y >= A.y && position.y < B.y );
|
|
|
|
|
|
- // below is simple linear interpolation
|
|
|
- var t = Math.abs( p.y - A.y ) / ( A.y - B.y );
|
|
|
+ if ( applyColor === true ) {
|
|
|
|
|
|
- // to make it faster, you can only calculate this if the y coord changes, the color is the same for points with the same y
|
|
|
- var color = interpolateColors( aColor, bColor, t );
|
|
|
+ var aColor = colors[ j ];
|
|
|
+ var bColor = colors[ j + 1 ];
|
|
|
|
|
|
- f.vertexColors[ j ] = color;
|
|
|
+ // below is simple linear interpolation
|
|
|
|
|
|
- }
|
|
|
+ var t = Math.abs( position.y - A.y ) / ( A.y - B.y );
|
|
|
+
|
|
|
+ // to make it faster, you can only calculate this if the y coord changes, the color is the same for points with the same y
|
|
|
|
|
|
- } else if ( undefined === f.vertexColors[ j ] ) {
|
|
|
+ color.copy( aColor ).lerp( bColor, t );
|
|
|
|
|
|
- var colorIndex = directionIsDown ? colors.length - 1 : 0;
|
|
|
- f.vertexColors[ j ] = colors[ colorIndex ];
|
|
|
+ colorAttribute.setXYZ( vertexIndex, color.r, color.g, color.b );
|
|
|
+
|
|
|
+ } else {
|
|
|
+
|
|
|
+ var colorIndex = ( topDown === true ) ? colors.length - 1 : 0;
|
|
|
+ var c = colors[ colorIndex ];
|
|
|
+ colorAttribute.setXYZ( vertexIndex, c.r, c.g, c.b );
|
|
|
|
|
|
}
|
|
|
|
|
@@ -200,11 +177,13 @@ THREE.VRMLLoader.prototype = {
|
|
|
|
|
|
}
|
|
|
|
|
|
+ geometry.addAttribute( 'color', colorAttribute );
|
|
|
+
|
|
|
};
|
|
|
|
|
|
var index = [];
|
|
|
|
|
|
- var parseProperty = function ( node, line ) {
|
|
|
+ function parseProperty( node, line ) {
|
|
|
|
|
|
var parts = [], part, property = {}, fieldName;
|
|
|
|
|
@@ -216,7 +195,7 @@ THREE.VRMLLoader.prototype = {
|
|
|
|
|
|
var point, angles, colors;
|
|
|
|
|
|
- while ( null != ( part = regex.exec( line ) ) ) {
|
|
|
+ while ( null !== ( part = regex.exec( line ) ) ) {
|
|
|
|
|
|
parts.push( part[ 0 ] );
|
|
|
|
|
@@ -233,22 +212,26 @@ THREE.VRMLLoader.prototype = {
|
|
|
this.isRecordingAngles = true;
|
|
|
this.angles = [];
|
|
|
break;
|
|
|
+
|
|
|
case 'skyColor':
|
|
|
case 'groundColor':
|
|
|
this.recordingFieldname = fieldName;
|
|
|
this.isRecordingColors = true;
|
|
|
this.colors = [];
|
|
|
break;
|
|
|
+
|
|
|
case 'point':
|
|
|
this.recordingFieldname = fieldName;
|
|
|
this.isRecordingPoints = true;
|
|
|
this.points = [];
|
|
|
break;
|
|
|
+
|
|
|
case 'coordIndex':
|
|
|
case 'texCoordIndex':
|
|
|
this.recordingFieldname = fieldName;
|
|
|
this.isRecordingFaces = true;
|
|
|
this.indexes = [];
|
|
|
+ break;
|
|
|
}
|
|
|
|
|
|
if ( this.isRecordingFaces ) {
|
|
@@ -266,7 +249,7 @@ THREE.VRMLLoader.prototype = {
|
|
|
}
|
|
|
|
|
|
// end of current face
|
|
|
- if ( parts[ ind ] === "-1" ) {
|
|
|
+ if ( parts[ ind ] === '-1' ) {
|
|
|
|
|
|
if ( index.length > 0 ) {
|
|
|
|
|
@@ -400,9 +383,9 @@ THREE.VRMLLoader.prototype = {
|
|
|
case 'specularColor':
|
|
|
case 'color':
|
|
|
|
|
|
- if ( parts.length != 4 ) {
|
|
|
+ if ( parts.length !== 4 ) {
|
|
|
|
|
|
- console.warn( 'Invalid color format detected for ' + fieldName );
|
|
|
+ console.warn( 'THREE.VRMLLoader: Invalid color format detected for %s.', fieldName );
|
|
|
break;
|
|
|
|
|
|
}
|
|
@@ -420,9 +403,9 @@ THREE.VRMLLoader.prototype = {
|
|
|
case 'translation':
|
|
|
case 'scale':
|
|
|
case 'size':
|
|
|
- if ( parts.length != 4 ) {
|
|
|
+ if ( parts.length !== 4 ) {
|
|
|
|
|
|
- console.warn( 'Invalid vector format detected for ' + fieldName );
|
|
|
+ console.warn( 'THREE.VRMLLoader: Invalid vector format detected for %s.', fieldName );
|
|
|
break;
|
|
|
|
|
|
}
|
|
@@ -444,9 +427,9 @@ THREE.VRMLLoader.prototype = {
|
|
|
case 'transparency':
|
|
|
case 'shininess':
|
|
|
case 'ambientIntensity':
|
|
|
- if ( parts.length != 2 ) {
|
|
|
+ if ( parts.length !== 2 ) {
|
|
|
|
|
|
- console.warn( 'Invalid single float value specification detected for ' + fieldName );
|
|
|
+ console.warn( 'THREE.VRMLLoader: Invalid single float value specification detected for %s.', fieldName );
|
|
|
break;
|
|
|
|
|
|
}
|
|
@@ -456,9 +439,9 @@ THREE.VRMLLoader.prototype = {
|
|
|
break;
|
|
|
|
|
|
case 'rotation':
|
|
|
- if ( parts.length != 5 ) {
|
|
|
+ if ( parts.length !== 5 ) {
|
|
|
|
|
|
- console.warn( 'Invalid quaternion format detected for ' + fieldName );
|
|
|
+ console.warn( 'THREE.VRMLLoader: Invalid quaternion format detected for %s.', fieldName );
|
|
|
break;
|
|
|
|
|
|
}
|
|
@@ -477,9 +460,9 @@ THREE.VRMLLoader.prototype = {
|
|
|
case 'solid':
|
|
|
case 'colorPerVertex':
|
|
|
case 'convex':
|
|
|
- if ( parts.length != 2 ) {
|
|
|
+ if ( parts.length !== 2 ) {
|
|
|
|
|
|
- console.warn( 'Invalid format detected for ' + fieldName );
|
|
|
+ console.warn( 'THREE.VRMLLoader: Invalid format detected for %s.', fieldName );
|
|
|
break;
|
|
|
|
|
|
}
|
|
@@ -497,7 +480,7 @@ THREE.VRMLLoader.prototype = {
|
|
|
|
|
|
};
|
|
|
|
|
|
- var getTree = function ( lines ) {
|
|
|
+ function getTree( lines ) {
|
|
|
|
|
|
var tree = { 'string': 'Scene', children: [] };
|
|
|
var current = tree;
|
|
@@ -578,9 +561,9 @@ THREE.VRMLLoader.prototype = {
|
|
|
|
|
|
};
|
|
|
|
|
|
- var parseNode = function ( data, parent ) {
|
|
|
+ function parseNode( data, parent ) {
|
|
|
|
|
|
- // console.log( data );
|
|
|
+ var object;
|
|
|
|
|
|
if ( typeof data === 'string' ) {
|
|
|
|
|
@@ -590,7 +573,7 @@ THREE.VRMLLoader.prototype = {
|
|
|
|
|
|
if ( undefined == defines[ defineKey ] ) {
|
|
|
|
|
|
- console.warn( defineKey + ' is not defined.' );
|
|
|
+ console.warn( 'THREE.VRMLLoader: %s is not defined.', defineKey );
|
|
|
|
|
|
} else {
|
|
|
|
|
@@ -612,7 +595,7 @@ THREE.VRMLLoader.prototype = {
|
|
|
|
|
|
} else if ( defineKey ) {
|
|
|
|
|
|
- var object = defines[ defineKey ].clone();
|
|
|
+ object = defines[ defineKey ].clone();
|
|
|
parent.add( object );
|
|
|
|
|
|
}
|
|
@@ -625,77 +608,72 @@ THREE.VRMLLoader.prototype = {
|
|
|
|
|
|
}
|
|
|
|
|
|
- var object = parent;
|
|
|
+ object = parent;
|
|
|
+
|
|
|
+ if ( data.string.indexOf( 'AmbientLight') > - 1 && data.nodeType === 'PointLight' ) {
|
|
|
+
|
|
|
+ data.nodeType = 'AmbientLight';
|
|
|
|
|
|
- if(data.string.indexOf("AmbientLight")>-1 && data.nodeType=='PointLight'){
|
|
|
- //wenn im Namen "AmbientLight" vorkommt und es ein PointLight ist,
|
|
|
- //diesen Typ in 'AmbientLight' ändern
|
|
|
- data.nodeType='AmbientLight';
|
|
|
}
|
|
|
|
|
|
var l_visible = data.on !== undefined ? data.on : true;
|
|
|
var l_intensity = data.intensity !== undefined ? data.intensity : 1;
|
|
|
var l_color = new THREE.Color();
|
|
|
- if ( data.color ) l_color.copy( data.color );
|
|
|
|
|
|
- if('AmbientLight' === data.nodeType){
|
|
|
- object=new THREE.AmbientLight(
|
|
|
- l_color.getHex(),
|
|
|
- l_intensity
|
|
|
- );
|
|
|
- object.visible=l_visible;
|
|
|
+ if ( data.color ) {
|
|
|
|
|
|
- parent.add( object );
|
|
|
+ l_color.copy( data.color );
|
|
|
|
|
|
}
|
|
|
- else
|
|
|
- if('PointLight' === data.nodeType){
|
|
|
- var l_distance =0; //0="unendlich" ...1000
|
|
|
|
|
|
- if(data.radius!=undefined && data.radius<1000){
|
|
|
- //l_radius=data.radius;
|
|
|
- l_distance=data.radius;
|
|
|
+ if ( 'AmbientLight' === data.nodeType){
|
|
|
+
|
|
|
+ object = new THREE.AmbientLight( l_color, l_intensity );
|
|
|
+ object.visible = l_visible;
|
|
|
+
|
|
|
+ parent.add( object );
|
|
|
+
|
|
|
+ } else if ( 'PointLight' === data.nodeType ) {
|
|
|
+
|
|
|
+ var l_distance = 0;
|
|
|
+
|
|
|
+ if ( data.radius !== undefined && data.radius < 1000 ){
|
|
|
+
|
|
|
+ l_distance = data.radius;
|
|
|
+
|
|
|
}
|
|
|
- object=new THREE.PointLight(
|
|
|
- l_color.getHex(),
|
|
|
- l_intensity,
|
|
|
- l_distance);
|
|
|
- object.visible=l_visible;
|
|
|
+
|
|
|
+ object=new THREE.PointLight( l_color, l_intensity, l_distance );
|
|
|
+ object.visible = l_visible;
|
|
|
|
|
|
parent.add( object );
|
|
|
- }
|
|
|
- else
|
|
|
- if('SpotLight' === data.nodeType){
|
|
|
- var l_intensity=1;
|
|
|
- var l_distance =0;//0="unendlich"=1000
|
|
|
- var l_angle=Math.PI/3;
|
|
|
- var l_penumbra=0.0;//0..1
|
|
|
- var l_visible=true;
|
|
|
-
|
|
|
- if(data.radius!=undefined && data.radius<1000){
|
|
|
- //l_radius=data.radius;
|
|
|
- l_distance=data.radius;
|
|
|
+
|
|
|
+ } else if ( 'SpotLight' === data.nodeType ) {
|
|
|
+
|
|
|
+ var l_intensity = 1;
|
|
|
+ var l_distance = 0;
|
|
|
+ var l_angle = Math.PI/3;
|
|
|
+ var l_penumbra = 0;
|
|
|
+ var l_visible = true;
|
|
|
+
|
|
|
+ if ( data.radius !== undefined && data.radius < 1000 ) {
|
|
|
+
|
|
|
+ l_distance = data.radius;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ if ( data.cutOffAngle !== undefined ) {
|
|
|
+
|
|
|
+ l_angle = data.cutOffAngle;
|
|
|
+
|
|
|
}
|
|
|
- if(data.cutOffAngle!=undefined)l_angle=data.cutOffAngle;
|
|
|
-
|
|
|
- object = new THREE.SpotLight(
|
|
|
- l_color.getHex(),
|
|
|
- l_intensity,
|
|
|
- l_distance,
|
|
|
- l_angle,
|
|
|
- l_penumbra
|
|
|
- );
|
|
|
- object.visible=l_visible;
|
|
|
+
|
|
|
+ object = new THREE.SpotLight( l_color, l_intensity, l_distance, l_angle, l_penumbra );
|
|
|
+ object.visible = l_visible;
|
|
|
+
|
|
|
parent.add( object );
|
|
|
- /*
|
|
|
- var lightHelper = new THREE.SpotLightHelper( object );
|
|
|
- parent.parent.add( lightHelper );
|
|
|
- lightHelper.update();
|
|
|
- */
|
|
|
- }
|
|
|
- else
|
|
|
|
|
|
- if ( 'Transform' === data.nodeType || 'Group' === data.nodeType ) {
|
|
|
+ } else if ( 'Transform' === data.nodeType || 'Group' === data.nodeType ) {
|
|
|
|
|
|
object = new THREE.Object3D();
|
|
|
|
|
@@ -754,7 +732,7 @@ THREE.VRMLLoader.prototype = {
|
|
|
|
|
|
var radius = 2e4;
|
|
|
|
|
|
- var skyGeometry = new THREE.SphereGeometry( radius, segments, segments );
|
|
|
+ var skyGeometry = new THREE.SphereBufferGeometry( radius, segments, segments );
|
|
|
var skyMaterial = new THREE.MeshBasicMaterial( { fog: false, side: THREE.BackSide } );
|
|
|
|
|
|
if ( data.skyColor.length > 1 ) {
|
|
@@ -778,7 +756,7 @@ THREE.VRMLLoader.prototype = {
|
|
|
|
|
|
radius = 1.2e4;
|
|
|
|
|
|
- var groundGeometry = new THREE.SphereGeometry( radius, segments, segments, 0, 2 * Math.PI, 0.5 * Math.PI, 1.5 * Math.PI );
|
|
|
+ var groundGeometry = new THREE.SphereBufferGeometry( radius, segments, segments, 0, 2 * Math.PI, 0.5 * Math.PI, 1.5 * Math.PI );
|
|
|
var groundMaterial = new THREE.MeshBasicMaterial( { fog: false, side: THREE.BackSide, vertexColors: THREE.VertexColors } );
|
|
|
|
|
|
paintFaces( groundGeometry, radius, data.groundAngle, data.groundColor, false );
|
|
@@ -793,68 +771,82 @@ THREE.VRMLLoader.prototype = {
|
|
|
|
|
|
var s = data.size;
|
|
|
|
|
|
- parent.geometry = new THREE.BoxGeometry( s.x, s.y, s.z );
|
|
|
+ parent.geometry = new THREE.BoxBufferGeometry( s.x, s.y, s.z );
|
|
|
|
|
|
} else if ( 'Cylinder' === data.nodeType ) {
|
|
|
|
|
|
- parent.geometry = new THREE.CylinderGeometry( data.radius, data.radius, data.height );
|
|
|
+ parent.geometry = new THREE.CylinderBufferGeometry( data.radius, data.radius, data.height );
|
|
|
|
|
|
} else if ( 'Cone' === data.nodeType ) {
|
|
|
|
|
|
- parent.geometry = new THREE.CylinderGeometry( data.topRadius, data.bottomRadius, data.height );
|
|
|
+ parent.geometry = new THREE.CylinderBufferGeometry( data.topRadius, data.bottomRadius, data.height );
|
|
|
|
|
|
} else if ( 'Sphere' === data.nodeType ) {
|
|
|
|
|
|
- parent.geometry = new THREE.SphereGeometry( data.radius );
|
|
|
+ parent.geometry = new THREE.SphereBufferGeometry( data.radius );
|
|
|
|
|
|
} else if ( 'IndexedFaceSet' === data.nodeType ) {
|
|
|
|
|
|
- var geometry = new THREE.Geometry();
|
|
|
+ var geometry = new THREE.BufferGeometry();
|
|
|
+
|
|
|
+ var index = [];
|
|
|
+ var positions = [];
|
|
|
+ var uvs = [];
|
|
|
|
|
|
- var indexes, uvIndexes, uvs;
|
|
|
+ var position, uv;
|
|
|
|
|
|
- for ( var i = 0, j = data.children.length; i < j; i ++ ) {
|
|
|
+ var i, il, j, jl;
|
|
|
+
|
|
|
+ for ( i = 0, il = data.children.length; i < il; i ++ ) {
|
|
|
|
|
|
var child = data.children[ i ];
|
|
|
|
|
|
- var vec;
|
|
|
+ // uvs
|
|
|
|
|
|
if ( 'TextureCoordinate' === child.nodeType ) {
|
|
|
|
|
|
- uvs = child.points;
|
|
|
+ if ( child.points ) {
|
|
|
+
|
|
|
+ for ( j = 0, jl = child.points.length; j < jl; j ++ ) {
|
|
|
+
|
|
|
+ uv = child.points[ j ];
|
|
|
+ uvs.push( uv.x, uv.y );
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
|
|
|
}
|
|
|
|
|
|
+ // positions
|
|
|
|
|
|
if ( 'Coordinate' === child.nodeType ) {
|
|
|
|
|
|
if ( child.points ) {
|
|
|
|
|
|
- for ( var k = 0, l = child.points.length; k < l; k ++ ) {
|
|
|
-
|
|
|
- var point = child.points[ k ];
|
|
|
-
|
|
|
- vec = new THREE.Vector3( point.x, point.y, point.z );
|
|
|
+ for ( j = 0, jl = child.points.length; j < jl; j ++ ) {
|
|
|
|
|
|
- geometry.vertices.push( vec );
|
|
|
+ position = child.points[ j ];
|
|
|
+ positions.push( position.x, position.y, position.z );
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
- if ( child.string.indexOf ( 'DEF' ) > -1 ) {
|
|
|
+ if ( child.string.indexOf ( 'DEF' ) > - 1 ) {
|
|
|
|
|
|
var name = /DEF\s+([^\s]+)/.exec( child.string )[ 1 ];
|
|
|
|
|
|
- defines[ name ] = geometry.vertices;
|
|
|
+ defines[ name ] = positions.slice( 0 );
|
|
|
|
|
|
}
|
|
|
|
|
|
- if ( child.string.indexOf ( 'USE' ) > -1 ) {
|
|
|
+ if ( child.string.indexOf ( 'USE' ) > - 1 ) {
|
|
|
|
|
|
var defineKey = /USE\s+([^\s]+)/.exec( child.string )[ 1 ];
|
|
|
|
|
|
- geometry.vertices = defines[ defineKey ];
|
|
|
+ positions = defines[ defineKey ];
|
|
|
+
|
|
|
}
|
|
|
|
|
|
}
|
|
@@ -864,56 +856,59 @@ THREE.VRMLLoader.prototype = {
|
|
|
var skip = 0;
|
|
|
|
|
|
// some shapes only have vertices for use in other shapes
|
|
|
+
|
|
|
if ( data.coordIndex ) {
|
|
|
|
|
|
- // read this: http://math.hws.edu/eck/cs424/notes2013/16_Threejs_Advanced.html
|
|
|
- for ( var i = 0, j = data.coordIndex.length; i < j; i ++ ) {
|
|
|
+ var newPositions = [];
|
|
|
+ var newUvs = [];
|
|
|
+
|
|
|
+ position = new THREE.Vector3();
|
|
|
+ uv = new THREE.Vector2();
|
|
|
+
|
|
|
+ for ( i = 0, il = data.coordIndex.length; i < il; i ++ ) {
|
|
|
+
|
|
|
+ var indexes = data.coordIndex[ i ];
|
|
|
|
|
|
- indexes = data.coordIndex[ i ]; if ( data.texCoordIndex ) uvIndexes = data.texCoordIndex[ i ];
|
|
|
+ // VRML support multipoint indexed face sets (more then 3 vertices). You must calculate the composing triangles here
|
|
|
|
|
|
- // vrml support multipoint indexed face sets (more then 3 vertices). You must calculate the composing triangles here
|
|
|
skip = 0;
|
|
|
|
|
|
- // Face3 only works with triangles, but IndexedFaceSet allows shapes with more then three vertices, build them of triangles
|
|
|
while ( indexes.length >= 3 && skip < ( indexes.length - 2 ) ) {
|
|
|
|
|
|
- var face = new THREE.Face3(
|
|
|
- indexes[ 0 ],
|
|
|
- indexes[ skip + (data.ccw ? 1 : 2) ],
|
|
|
- indexes[ skip + (data.ccw ? 2 : 1) ],
|
|
|
- null // normal, will be added later
|
|
|
- // todo: pass in the color, if a color index is present
|
|
|
- );
|
|
|
-
|
|
|
- if ( uvs && uvIndexes ) {
|
|
|
- geometry.faceVertexUvs [0].push( [
|
|
|
- new THREE.Vector2 (
|
|
|
- uvs[ uvIndexes[ 0 ] ].x ,
|
|
|
- uvs[ uvIndexes[ 0 ] ].y
|
|
|
- ) ,
|
|
|
- new THREE.Vector2 (
|
|
|
- uvs[ uvIndexes[ skip + (data.ccw ? 1 : 2) ] ].x ,
|
|
|
- uvs[ uvIndexes[ skip + (data.ccw ? 1 : 2) ] ].y
|
|
|
- ) ,
|
|
|
- new THREE.Vector2 (
|
|
|
- uvs[ uvIndexes[ skip + (data.ccw ? 2 : 1) ] ].x ,
|
|
|
- uvs[ uvIndexes[ skip + (data.ccw ? 2 : 1) ] ].y
|
|
|
- )
|
|
|
- ] );
|
|
|
- }
|
|
|
+ var i1 = indexes[ 0 ];
|
|
|
+ var i2 = indexes[ skip + ( data.ccw ? 1 : 2 ) ];
|
|
|
+ var i3 = indexes[ skip + ( data.ccw ? 2 : 1 ) ];
|
|
|
|
|
|
- skip ++;
|
|
|
+ // create non indexed geometry, necessary for face normal generation
|
|
|
|
|
|
- geometry.faces.push( face );
|
|
|
+ position.fromArray( positions, i1 * 3 );
|
|
|
+ uv.fromArray( uvs, i1 * 2 );
|
|
|
+ newPositions.push( position.x, position.y, position.z );
|
|
|
+ newUvs.push( uv.x, uv.y );
|
|
|
|
|
|
- }
|
|
|
+ position.fromArray( positions, i2 * 3 );
|
|
|
+ uv.fromArray( uvs, i2 * 2 );
|
|
|
+ newPositions.push( position.x, position.y, position.z );
|
|
|
+ newUvs.push( uv.x, uv.y );
|
|
|
|
|
|
+ position.fromArray( positions, i3 * 3 );
|
|
|
+ uv.fromArray( uvs, i3 * 2 );
|
|
|
+ newPositions.push( position.x, position.y, position.z );
|
|
|
+ newUvs.push( uv.x, uv.y );
|
|
|
+
|
|
|
+ skip ++;
|
|
|
+
|
|
|
+ }
|
|
|
|
|
|
}
|
|
|
|
|
|
+ positions = newPositions;
|
|
|
+ uvs = newUvs;
|
|
|
+
|
|
|
} else {
|
|
|
|
|
|
// do not add dummy mesh to the scene
|
|
|
+
|
|
|
parent.parent.remove( parent );
|
|
|
|
|
|
}
|
|
@@ -927,8 +922,15 @@ THREE.VRMLLoader.prototype = {
|
|
|
// we need to store it on the geometry for use with defines
|
|
|
geometry.solid = data.solid;
|
|
|
|
|
|
- geometry.computeFaceNormals();
|
|
|
- //geometry.computeVertexNormals(); // does not show
|
|
|
+ geometry.addAttribute( 'position', new THREE.Float32BufferAttribute( positions, 3 ) );
|
|
|
+
|
|
|
+ if ( uvs.length > 0 ) {
|
|
|
+
|
|
|
+ geometry.addAttribute( 'uv', new THREE.Float32BufferAttribute( uvs, 2 ) );
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ geometry.computeVertexNormals();
|
|
|
geometry.computeBoundingSphere();
|
|
|
|
|
|
// see if it's a define
|