|
@@ -44,10 +44,14 @@ THREE.VRMLLoader.prototype = {
|
|
|
|
|
|
this.crossOrigin = value;
|
|
|
|
|
|
+ THREE.ImageUtils.crossOrigin = value;
|
|
|
+
|
|
|
},
|
|
|
|
|
|
parse: function ( data ) {
|
|
|
|
|
|
+ var texturePath = this.texturePath || '';
|
|
|
+
|
|
|
var parseV1 = function ( lines, scene ) {
|
|
|
|
|
|
console.warn( 'VRML V1.0 not supported yet' );
|
|
@@ -58,6 +62,7 @@ THREE.VRMLLoader.prototype = {
|
|
|
|
|
|
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;
|
|
|
|
|
|
/**
|
|
@@ -239,10 +244,10 @@ THREE.VRMLLoader.prototype = {
|
|
|
this.points = [];
|
|
|
break;
|
|
|
case 'coordIndex':
|
|
|
+ case 'texCoordIndex':
|
|
|
this.recordingFieldname = fieldName;
|
|
|
this.isRecordingFaces = true;
|
|
|
this.indexes = [];
|
|
|
- break;
|
|
|
}
|
|
|
|
|
|
if ( this.isRecordingFaces ) {
|
|
@@ -287,12 +292,14 @@ THREE.VRMLLoader.prototype = {
|
|
|
if ( /]/.exec( line ) ) {
|
|
|
|
|
|
this.isRecordingFaces = false;
|
|
|
- node.coordIndex = this.indexes;
|
|
|
+ node[this.recordingFieldname] = this.indexes;
|
|
|
|
|
|
}
|
|
|
|
|
|
} else if ( this.isRecordingPoints ) {
|
|
|
|
|
|
+ if ( node.nodeType == 'Coordinate' )
|
|
|
+
|
|
|
while ( null !== ( parts = float3_pattern.exec( line ) ) ) {
|
|
|
|
|
|
point = {
|
|
@@ -305,6 +312,19 @@ THREE.VRMLLoader.prototype = {
|
|
|
|
|
|
}
|
|
|
|
|
|
+ if ( node.nodeType == 'TextureCoordinate' )
|
|
|
+
|
|
|
+ while ( null !== ( parts = float2_pattern.exec( line ) ) ) {
|
|
|
+
|
|
|
+ point = {
|
|
|
+ x: parseFloat( parts[ 1 ] ),
|
|
|
+ y: parseFloat( parts[ 2 ] )
|
|
|
+ };
|
|
|
+
|
|
|
+ this.points.push( point );
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
// end
|
|
|
if ( /]/.exec( line ) ) {
|
|
|
|
|
@@ -505,7 +525,7 @@ THREE.VRMLLoader.prototype = {
|
|
|
|
|
|
}
|
|
|
|
|
|
- if ( matches = /([^\s]*){1}\s?{/.exec( line ) ) {
|
|
|
+ if ( matches = /([^\s]*){1}(?:\s+)?{/.exec( line ) ) {
|
|
|
|
|
|
// first subpattern should match the Node name
|
|
|
|
|
@@ -637,7 +657,7 @@ THREE.VRMLLoader.prototype = {
|
|
|
|
|
|
if ( /DEF/.exec( data.string ) ) {
|
|
|
|
|
|
- object.name = /DEF (\w+)/.exec( data.string )[ 1 ];
|
|
|
+ object.name = /DEF\s+(\w+)/.exec( data.string )[ 1 ];
|
|
|
|
|
|
defines[ object.name ] = object;
|
|
|
|
|
@@ -710,7 +730,7 @@ THREE.VRMLLoader.prototype = {
|
|
|
|
|
|
var geometry = new THREE.Geometry();
|
|
|
|
|
|
- var indexes;
|
|
|
+ var indexes, uvIndexes, uvs;
|
|
|
|
|
|
for ( var i = 0, j = data.children.length; i < j; i ++ ) {
|
|
|
|
|
@@ -718,8 +738,17 @@ THREE.VRMLLoader.prototype = {
|
|
|
|
|
|
var vec;
|
|
|
|
|
|
+ if ( 'TextureCoordinate' === child.nodeType ) {
|
|
|
+
|
|
|
+ uvs = child.points;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
if ( 'Coordinate' === child.nodeType ) {
|
|
|
|
|
|
+ if ( child.points )
|
|
|
+
|
|
|
for ( var k = 0, l = child.points.length; k < l; k ++ ) {
|
|
|
|
|
|
var point = child.points[ k ];
|
|
@@ -730,7 +759,20 @@ THREE.VRMLLoader.prototype = {
|
|
|
|
|
|
}
|
|
|
|
|
|
- break;
|
|
|
+ if ( child.string.indexOf ( 'DEF' ) > -1 ) {
|
|
|
+
|
|
|
+ var name = /DEF\s+(\w+)/.exec( child.string )[ 1 ];
|
|
|
+
|
|
|
+ defines[ name ] = geometry.vertices;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ if ( child.string.indexOf ( 'USE' ) > -1 ) {
|
|
|
+
|
|
|
+ var defineKey = /USE\s+(\w+)/.exec( child.string )[ 1 ];
|
|
|
+
|
|
|
+ geometry.vertices = defines[ defineKey ];
|
|
|
+ }
|
|
|
|
|
|
}
|
|
|
|
|
@@ -738,27 +780,45 @@ 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 ++ ) {
|
|
|
|
|
|
- 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
|
|
|
skip = 0;
|
|
|
|
|
|
- // todo: this is the time to check if the faces are ordered ccw or not (cw)
|
|
|
-
|
|
|
// 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 + 1 ],
|
|
|
- indexes[ skip + 2 ],
|
|
|
+ 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
|
|
|
+ )
|
|
|
+ ] );
|
|
|
+ }
|
|
|
+
|
|
|
skip ++;
|
|
|
|
|
|
geometry.faces.push( face );
|
|
@@ -850,8 +910,19 @@ THREE.VRMLLoader.prototype = {
|
|
|
|
|
|
parent.material = material;
|
|
|
|
|
|
- // material found, stop looping
|
|
|
- break;
|
|
|
+ }
|
|
|
+
|
|
|
+ if ( 'ImageTexture' === child.nodeType ) {
|
|
|
+
|
|
|
+ var textureName = /"([^"]+)"/.exec(child.children[ 0 ]);
|
|
|
+
|
|
|
+ if (textureName) {
|
|
|
+
|
|
|
+ parent.material.name = textureName[ 1 ];
|
|
|
+
|
|
|
+ parent.material.map = THREE.ImageUtils.loadTexture (texturePath + textureName[ 1 ]);
|
|
|
+
|
|
|
+ }
|
|
|
|
|
|
}
|
|
|
|
|
@@ -879,6 +950,40 @@ THREE.VRMLLoader.prototype = {
|
|
|
|
|
|
var lines = data.split( '\n' );
|
|
|
|
|
|
+ // some lines do not have breaks
|
|
|
+ for (var i = lines.length -1; i > -1; i--) {
|
|
|
+
|
|
|
+ // split lines with {..{ or {..[ - some have both
|
|
|
+ if (/{.*[{\[]/.test (lines[i])) {
|
|
|
+ var parts = lines[i].split ('{').join ('{\n').split ('\n');
|
|
|
+ parts.unshift(1);
|
|
|
+ parts.unshift(i);
|
|
|
+ lines.splice.apply(lines, parts);
|
|
|
+ } else
|
|
|
+
|
|
|
+ // split lines with ]..}
|
|
|
+ if (/\].*}/.test (lines[i])) {
|
|
|
+ var parts = lines[i].split (']').join (']\n').split ('\n');
|
|
|
+ parts.unshift(1);
|
|
|
+ parts.unshift(i);
|
|
|
+ lines.splice.apply(lines, parts);
|
|
|
+ }
|
|
|
+
|
|
|
+ // split lines with }..}
|
|
|
+ if (/}.*}/.test (lines[i])) {
|
|
|
+ var parts = lines[i].split ('}').join ('}\n').split ('\n');
|
|
|
+ parts.unshift(1);
|
|
|
+ parts.unshift(i);
|
|
|
+ lines.splice.apply(lines, parts);
|
|
|
+ }
|
|
|
+
|
|
|
+ // force the parser to create Coordinate node for empty coords
|
|
|
+ // coord USE something -> coord USE something Coordinate {}
|
|
|
+ if((lines[i].indexOf ('coord') > -1) && (lines[i].indexOf ('[') < 0) && (lines[i].indexOf ('{') < 0)) {
|
|
|
+ lines[i] += ' Coordinate {}';
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
var header = lines.shift();
|
|
|
|
|
|
if ( /V1.0/.exec( header ) ) {
|