|
@@ -329,13 +329,13 @@ THREE.VRMLLoader = ( function () {
|
|
|
|
|
|
def: function ( ctx ) {
|
|
|
|
|
|
- return ctx.Identifier[ 0 ].image;
|
|
|
+ return ( ctx.Identifier || ctx.NodeName )[ 0 ].image;
|
|
|
|
|
|
},
|
|
|
|
|
|
use: function ( ctx ) {
|
|
|
|
|
|
- return { USE: ctx.Identifier[ 0 ].image };
|
|
|
+ return { USE: ( ctx.Identifier || ctx.NodeName )[ 0 ].image };
|
|
|
|
|
|
},
|
|
|
|
|
@@ -515,6 +515,8 @@ THREE.VRMLLoader = ( function () {
|
|
|
|
|
|
if ( object instanceof THREE.Object3D ) scene.add( object );
|
|
|
|
|
|
+ if ( node.name === 'WorldInfo' ) scene.userData.worldInfo = object;
|
|
|
+
|
|
|
}
|
|
|
|
|
|
return scene;
|
|
@@ -641,6 +643,14 @@ THREE.VRMLLoader = ( function () {
|
|
|
build = buildSphereNode( node );
|
|
|
break;
|
|
|
|
|
|
+ case 'ElevationGrid':
|
|
|
+ build = buildElevationGridNode( node );
|
|
|
+ break;
|
|
|
+
|
|
|
+ case 'Extrusion':
|
|
|
+ build = buildExtrusionNode( node );
|
|
|
+ break;
|
|
|
+
|
|
|
case 'Color':
|
|
|
case 'Coordinate':
|
|
|
case 'Normal':
|
|
@@ -648,6 +658,10 @@ THREE.VRMLLoader = ( function () {
|
|
|
build = buildGeometricNode( node );
|
|
|
break;
|
|
|
|
|
|
+ case 'WorldInfo':
|
|
|
+ build = buildWorldInfoNode( node );
|
|
|
+ break;
|
|
|
+
|
|
|
case 'Anchor':
|
|
|
case 'Billboard':
|
|
|
case 'Collision':
|
|
@@ -662,7 +676,6 @@ THREE.VRMLLoader = ( function () {
|
|
|
case 'Script':
|
|
|
case 'Sound':
|
|
|
case 'SpotLight':
|
|
|
- case 'WorldInfo':
|
|
|
|
|
|
case 'CylinderSensor':
|
|
|
case 'PlaneSensor':
|
|
@@ -672,8 +685,6 @@ THREE.VRMLLoader = ( function () {
|
|
|
case 'TouchSensor':
|
|
|
case 'VisibilitySensor':
|
|
|
|
|
|
- case 'ElevationGrid':
|
|
|
- case 'Extrusion':
|
|
|
case 'Text':
|
|
|
|
|
|
case 'FontStyle':
|
|
@@ -903,6 +914,7 @@ THREE.VRMLLoader = ( function () {
|
|
|
material = getNode( fieldValues[ 0 ] );
|
|
|
|
|
|
}
|
|
|
+
|
|
|
break;
|
|
|
|
|
|
case 'geometry':
|
|
@@ -911,6 +923,7 @@ THREE.VRMLLoader = ( function () {
|
|
|
geometry = getNode( fieldValues[ 0 ] );
|
|
|
|
|
|
}
|
|
|
+
|
|
|
break;
|
|
|
|
|
|
default:
|
|
@@ -1043,6 +1056,7 @@ THREE.VRMLLoader = ( function () {
|
|
|
material = new THREE.MeshBasicMaterial( { color: 0x000000 } );
|
|
|
|
|
|
}
|
|
|
+
|
|
|
break;
|
|
|
|
|
|
case 'texture':
|
|
@@ -1060,6 +1074,7 @@ THREE.VRMLLoader = ( function () {
|
|
|
}
|
|
|
|
|
|
}
|
|
|
+
|
|
|
break;
|
|
|
|
|
|
case 'textureTransform':
|
|
@@ -1068,6 +1083,7 @@ THREE.VRMLLoader = ( function () {
|
|
|
transformData = getNode( fieldValues[ 0 ] );
|
|
|
|
|
|
}
|
|
|
+
|
|
|
break;
|
|
|
|
|
|
default:
|
|
@@ -1434,6 +1450,40 @@ THREE.VRMLLoader = ( function () {
|
|
|
|
|
|
}
|
|
|
|
|
|
+ function buildWorldInfoNode( node ) {
|
|
|
+
|
|
|
+ var worldInfo = {};
|
|
|
+
|
|
|
+ var fields = node.fields;
|
|
|
+
|
|
|
+ for ( var i = 0, l = fields.length; i < l; i ++ ) {
|
|
|
+
|
|
|
+ var field = fields[ i ];
|
|
|
+ var fieldName = field.name;
|
|
|
+ var fieldValues = field.values;
|
|
|
+
|
|
|
+ switch ( fieldName ) {
|
|
|
+
|
|
|
+ case 'title':
|
|
|
+ worldInfo.title = fieldValues[ 0 ];
|
|
|
+ break;
|
|
|
+
|
|
|
+ case 'info':
|
|
|
+ worldInfo.info = fieldValues;
|
|
|
+ break;
|
|
|
+
|
|
|
+ default:
|
|
|
+ console.warn( 'THREE.VRMLLoader: Unknown field:', fieldName );
|
|
|
+ break;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ return worldInfo;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
function buildIndexedFaceSetNode( node ) {
|
|
|
|
|
|
var color, coord, normal, texCoord;
|
|
@@ -1459,6 +1509,7 @@ THREE.VRMLLoader = ( function () {
|
|
|
color = getNode( colorNode );
|
|
|
|
|
|
}
|
|
|
+
|
|
|
break;
|
|
|
|
|
|
case 'coord':
|
|
@@ -1469,6 +1520,7 @@ THREE.VRMLLoader = ( function () {
|
|
|
coord = getNode( coordNode );
|
|
|
|
|
|
}
|
|
|
+
|
|
|
break;
|
|
|
|
|
|
case 'normal':
|
|
@@ -1479,6 +1531,7 @@ THREE.VRMLLoader = ( function () {
|
|
|
normal = getNode( normalNode );
|
|
|
|
|
|
}
|
|
|
+
|
|
|
break;
|
|
|
|
|
|
case 'texCoord':
|
|
@@ -1489,6 +1542,7 @@ THREE.VRMLLoader = ( function () {
|
|
|
texCoord = getNode( texCoordNode );
|
|
|
|
|
|
}
|
|
|
+
|
|
|
break;
|
|
|
|
|
|
case 'ccw':
|
|
@@ -1715,6 +1769,7 @@ THREE.VRMLLoader = ( function () {
|
|
|
color = getNode( colorNode );
|
|
|
|
|
|
}
|
|
|
+
|
|
|
break;
|
|
|
|
|
|
case 'coord':
|
|
@@ -1725,6 +1780,7 @@ THREE.VRMLLoader = ( function () {
|
|
|
coord = getNode( coordNode );
|
|
|
|
|
|
}
|
|
|
+
|
|
|
break;
|
|
|
|
|
|
case 'colorIndex':
|
|
@@ -1834,6 +1890,7 @@ THREE.VRMLLoader = ( function () {
|
|
|
color = getNode( colorNode );
|
|
|
|
|
|
}
|
|
|
+
|
|
|
break;
|
|
|
|
|
|
case 'coord':
|
|
@@ -1844,6 +1901,7 @@ THREE.VRMLLoader = ( function () {
|
|
|
coord = getNode( coordNode );
|
|
|
|
|
|
}
|
|
|
+
|
|
|
break;
|
|
|
|
|
|
|
|
@@ -2024,6 +2082,557 @@ THREE.VRMLLoader = ( function () {
|
|
|
|
|
|
}
|
|
|
|
|
|
+ function buildElevationGridNode( node ) {
|
|
|
+
|
|
|
+ var color;
|
|
|
+ var normal;
|
|
|
+ var texCoord;
|
|
|
+ var height;
|
|
|
+
|
|
|
+ var colorPerVertex = true;
|
|
|
+ var normalPerVertex = true;
|
|
|
+ var solid = true;
|
|
|
+ var ccw = true;
|
|
|
+ var creaseAngle = 0;
|
|
|
+ var xDimension = 2;
|
|
|
+ var zDimension = 2;
|
|
|
+ var xSpacing = 1;
|
|
|
+ var zSpacing = 1;
|
|
|
+
|
|
|
+ var fields = node.fields;
|
|
|
+
|
|
|
+ for ( var i = 0, l = fields.length; i < l; i ++ ) {
|
|
|
+
|
|
|
+ var field = fields[ i ];
|
|
|
+ var fieldName = field.name;
|
|
|
+ var fieldValues = field.values;
|
|
|
+
|
|
|
+ switch ( fieldName ) {
|
|
|
+
|
|
|
+ case 'color':
|
|
|
+ var colorNode = fieldValues[ 0 ];
|
|
|
+
|
|
|
+ if ( colorNode !== null ) {
|
|
|
+
|
|
|
+ color = getNode( colorNode );
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ break;
|
|
|
+
|
|
|
+ case 'normal':
|
|
|
+ var normalNode = fieldValues[ 0 ];
|
|
|
+
|
|
|
+ if ( normalNode !== null ) {
|
|
|
+
|
|
|
+ normal = getNode( normalNode );
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ break;
|
|
|
+
|
|
|
+ case 'texCoord':
|
|
|
+ var texCoordNode = fieldValues[ 0 ];
|
|
|
+
|
|
|
+ if ( texCoordNode !== null ) {
|
|
|
+
|
|
|
+ texCoord = getNode( texCoordNode );
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ break;
|
|
|
+
|
|
|
+ case 'height':
|
|
|
+ height = fieldValues;
|
|
|
+ break;
|
|
|
+
|
|
|
+ case 'ccw':
|
|
|
+ ccw = fieldValues[ 0 ];
|
|
|
+ break;
|
|
|
+
|
|
|
+ case 'colorPerVertex':
|
|
|
+ colorPerVertex = fieldValues[ 0 ];
|
|
|
+ break;
|
|
|
+
|
|
|
+ case 'creaseAngle':
|
|
|
+ creaseAngle = fieldValues[ 0 ];
|
|
|
+ break;
|
|
|
+
|
|
|
+ case 'normalPerVertex':
|
|
|
+ normalPerVertex = fieldValues[ 0 ];
|
|
|
+ break;
|
|
|
+
|
|
|
+ case 'solid':
|
|
|
+ solid = fieldValues[ 0 ];
|
|
|
+ break;
|
|
|
+
|
|
|
+ case 'xDimension':
|
|
|
+ xDimension = fieldValues[ 0 ];
|
|
|
+ break;
|
|
|
+
|
|
|
+ case 'xSpacing':
|
|
|
+ xSpacing = fieldValues[ 0 ];
|
|
|
+ break;
|
|
|
+
|
|
|
+ case 'zDimension':
|
|
|
+ zDimension = fieldValues[ 0 ];
|
|
|
+ break;
|
|
|
+
|
|
|
+ case 'zSpacing':
|
|
|
+ zSpacing = fieldValues[ 0 ];
|
|
|
+ break;
|
|
|
+
|
|
|
+ default:
|
|
|
+ console.warn( 'THREE.VRMLLoader: Unknown field:', fieldName );
|
|
|
+ break;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ // vertex data
|
|
|
+
|
|
|
+ var vertices = [];
|
|
|
+ var normals = [];
|
|
|
+ var colors = [];
|
|
|
+ var uvs = [];
|
|
|
+
|
|
|
+ for ( var i = 0; i < zDimension; i ++ ) {
|
|
|
+
|
|
|
+ for ( var j = 0; j < xDimension; j ++ ) {
|
|
|
+
|
|
|
+ // compute a row major index
|
|
|
+
|
|
|
+ var index = ( i * xDimension ) + j;
|
|
|
+
|
|
|
+ // vertices
|
|
|
+
|
|
|
+ var x = xSpacing * i;
|
|
|
+ var y = height[ index ];
|
|
|
+ var z = zSpacing * j;
|
|
|
+
|
|
|
+ vertices.push( x, y, z );
|
|
|
+
|
|
|
+ // colors
|
|
|
+
|
|
|
+ if ( color && colorPerVertex === true ) {
|
|
|
+
|
|
|
+ var r = color[ index * 3 + 0 ];
|
|
|
+ var g = color[ index * 3 + 1 ];
|
|
|
+ var b = color[ index * 3 + 2 ];
|
|
|
+
|
|
|
+ colors.push( r, g, b );
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ // normals
|
|
|
+
|
|
|
+ if ( normal && normalPerVertex === true ) {
|
|
|
+
|
|
|
+ var xn = normal[ index * 3 + 0 ];
|
|
|
+ var yn = normal[ index * 3 + 1 ];
|
|
|
+ var zn = normal[ index * 3 + 2 ];
|
|
|
+
|
|
|
+ normals.push( xn, yn, zn );
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ // uvs
|
|
|
+
|
|
|
+ if ( texCoord ) {
|
|
|
+
|
|
|
+ var s = texCoord[ index * 2 + 0 ];
|
|
|
+ var t = texCoord[ index * 2 + 1 ];
|
|
|
+
|
|
|
+ uvs.push( s, t );
|
|
|
+
|
|
|
+
|
|
|
+ } else {
|
|
|
+
|
|
|
+ uvs.push( i / ( xDimension - 1 ), j / ( zDimension - 1 ) );
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ // indices
|
|
|
+
|
|
|
+ var indices = [];
|
|
|
+
|
|
|
+ for ( var i = 0; i < xDimension - 1; i ++ ) {
|
|
|
+
|
|
|
+ for ( var j = 0; j < zDimension - 1; j ++ ) {
|
|
|
+
|
|
|
+ // from https://tecfa.unige.ch/guides/vrml/vrml97/spec/part1/nodesRef.html#ElevationGrid
|
|
|
+
|
|
|
+ var a = i + j * xDimension;
|
|
|
+ var b = i + ( j + 1 ) * xDimension;
|
|
|
+ var c = ( i + 1 ) + ( j + 1 ) * xDimension;
|
|
|
+ var d = ( i + 1 ) + j * xDimension;
|
|
|
+
|
|
|
+ // faces
|
|
|
+
|
|
|
+ if ( ccw === true ) {
|
|
|
+
|
|
|
+ indices.push( a, c, b );
|
|
|
+ indices.push( c, a, d );
|
|
|
+
|
|
|
+ } else {
|
|
|
+
|
|
|
+ indices.push( a, b, c );
|
|
|
+ indices.push( c, d, a );
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ //
|
|
|
+
|
|
|
+ var positionAttribute = toNonIndexedAttribute( indices, new THREE.Float32BufferAttribute( vertices, 3 ) );
|
|
|
+ var uvAttribute = toNonIndexedAttribute( indices, new THREE.Float32BufferAttribute( uvs, 2 ) );
|
|
|
+ var colorAttribute;
|
|
|
+ var normalAttribute;
|
|
|
+
|
|
|
+ // color attribute
|
|
|
+
|
|
|
+ if ( color ) {
|
|
|
+
|
|
|
+ if ( colorPerVertex === false ) {
|
|
|
+
|
|
|
+ for ( var i = 0; i < xDimension - 1; i ++ ) {
|
|
|
+
|
|
|
+ for ( var j = 0; j < zDimension - 1; j ++ ) {
|
|
|
+
|
|
|
+ var index = i + j * ( xDimension - 1 );
|
|
|
+
|
|
|
+ var r = color[ index * 3 + 0 ];
|
|
|
+ var g = color[ index * 3 + 1 ];
|
|
|
+ var b = color[ index * 3 + 2 ];
|
|
|
+
|
|
|
+ // one color per quad
|
|
|
+
|
|
|
+ colors.push( r, g, b ); colors.push( r, g, b ); colors.push( r, g, b );
|
|
|
+ colors.push( r, g, b ); colors.push( r, g, b ); colors.push( r, g, b );
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ colorAttribute = new THREE.Float32BufferAttribute( colors, 3 );
|
|
|
+
|
|
|
+ } else {
|
|
|
+
|
|
|
+ colorAttribute = toNonIndexedAttribute( indices, new THREE.Float32BufferAttribute( colors, 3 ) );
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ // normal attribute
|
|
|
+
|
|
|
+ if ( normal ) {
|
|
|
+
|
|
|
+ if ( normalPerVertex === false ) {
|
|
|
+
|
|
|
+ for ( var i = 0; i < xDimension - 1; i ++ ) {
|
|
|
+
|
|
|
+ for ( var j = 0; j < zDimension - 1; j ++ ) {
|
|
|
+
|
|
|
+ var index = i + j * ( xDimension - 1 );
|
|
|
+
|
|
|
+ var xn = normal[ index * 3 + 0 ];
|
|
|
+ var yn = normal[ index * 3 + 1 ];
|
|
|
+ var zn = normal[ index * 3 + 2 ];
|
|
|
+
|
|
|
+ // one normal per quad
|
|
|
+
|
|
|
+ normals.push( xn, yn, zn ); normals.push( xn, yn, zn ); normals.push( xn, yn, zn );
|
|
|
+ normals.push( xn, yn, zn ); normals.push( xn, yn, zn ); normals.push( xn, yn, zn );
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ normalAttribute = new THREE.Float32BufferAttribute( normals, 3 );
|
|
|
+
|
|
|
+ } else {
|
|
|
+
|
|
|
+ normalAttribute = toNonIndexedAttribute( indices, new THREE.Float32BufferAttribute( normals, 3 ) );
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ } else {
|
|
|
+
|
|
|
+ normalAttribute = computeNormalAttribute( indices, vertices, creaseAngle );
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ // build geometry
|
|
|
+
|
|
|
+ var geometry = new THREE.BufferGeometry();
|
|
|
+ geometry.setAttribute( 'position', positionAttribute );
|
|
|
+ geometry.setAttribute( 'normal', normalAttribute );
|
|
|
+ geometry.setAttribute( 'uv', uvAttribute );
|
|
|
+
|
|
|
+ if ( colorAttribute ) geometry.setAttribute( 'color', colorAttribute );
|
|
|
+
|
|
|
+ // "solid" influences the material so let's store it for later use
|
|
|
+
|
|
|
+ geometry._solid = solid;
|
|
|
+ geometry._type = 'mesh';
|
|
|
+
|
|
|
+ return geometry;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ function buildExtrusionNode( node ) {
|
|
|
+
|
|
|
+ var crossSection = [ 1, 1, 1, - 1, - 1, - 1, - 1, 1, 1, 1 ];
|
|
|
+ var spine = [ 0, 0, 0, 0, 1, 0 ];
|
|
|
+ var scale;
|
|
|
+ var orientation;
|
|
|
+
|
|
|
+ var beginCap = true;
|
|
|
+ var ccw = true;
|
|
|
+ var creaseAngle = 0;
|
|
|
+ var endCap = true;
|
|
|
+ var solid = true;
|
|
|
+
|
|
|
+ var fields = node.fields;
|
|
|
+
|
|
|
+ for ( var i = 0, l = fields.length; i < l; i ++ ) {
|
|
|
+
|
|
|
+ var field = fields[ i ];
|
|
|
+ var fieldName = field.name;
|
|
|
+ var fieldValues = field.values;
|
|
|
+
|
|
|
+ switch ( fieldName ) {
|
|
|
+
|
|
|
+ case 'beginCap':
|
|
|
+ beginCap = fieldValues[ 0 ];
|
|
|
+ break;
|
|
|
+
|
|
|
+ case 'ccw':
|
|
|
+ ccw = fieldValues[ 0 ];
|
|
|
+ break;
|
|
|
+
|
|
|
+ case 'convex':
|
|
|
+ // field not supported
|
|
|
+ break;
|
|
|
+
|
|
|
+ case 'creaseAngle':
|
|
|
+ creaseAngle = fieldValues[ 0 ];
|
|
|
+ break;
|
|
|
+
|
|
|
+ case 'crossSection':
|
|
|
+ crossSection = fieldValues;
|
|
|
+ break;
|
|
|
+
|
|
|
+ case 'endCap':
|
|
|
+ endCap = fieldValues[ 0 ];
|
|
|
+ break;
|
|
|
+
|
|
|
+ case 'orientation':
|
|
|
+ orientation = fieldValues;
|
|
|
+ break;
|
|
|
+
|
|
|
+ case 'scale':
|
|
|
+ scale = fieldValues;
|
|
|
+ break;
|
|
|
+
|
|
|
+ case 'solid':
|
|
|
+ solid = fieldValues[ 0 ];
|
|
|
+ break;
|
|
|
+
|
|
|
+ case 'spine':
|
|
|
+ spine = fieldValues; // only extrusion along the Y-axis are supported so far
|
|
|
+ break;
|
|
|
+
|
|
|
+ default:
|
|
|
+ console.warn( 'THREE.VRMLLoader: Unknown field:', fieldName );
|
|
|
+ break;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ var crossSectionClosed = ( crossSection[ 0 ] === crossSection[ crossSection.length - 2 ] && crossSection[ 1 ] === crossSection[ crossSection.length - 1 ] );
|
|
|
+
|
|
|
+ // vertices
|
|
|
+
|
|
|
+ var vertices = [];
|
|
|
+ var spineVector = new THREE.Vector3();
|
|
|
+ var scaling = new THREE.Vector3();
|
|
|
+
|
|
|
+ var axis = new THREE.Vector3();
|
|
|
+ var vertex = new THREE.Vector3();
|
|
|
+ var quaternion = new THREE.Quaternion();
|
|
|
+
|
|
|
+ for ( var i = 0, j = 0, o = 0, il = spine.length; i < il; i += 3, j += 2, o += 4 ) {
|
|
|
+
|
|
|
+ spineVector.fromArray( spine, i );
|
|
|
+
|
|
|
+ scaling.x = scale ? scale[ j + 0 ] : 1;
|
|
|
+ scaling.y = 1;
|
|
|
+ scaling.z = scale ? scale[ j + 1 ] : 1;
|
|
|
+
|
|
|
+ axis.x = orientation ? orientation[ o + 0 ] : 0;
|
|
|
+ axis.y = orientation ? orientation[ o + 1 ] : 0;
|
|
|
+ axis.z = orientation ? orientation[ o + 2 ] : 1;
|
|
|
+ var angle = orientation ? orientation[ o + 3 ] : 0;
|
|
|
+
|
|
|
+ for ( var k = 0, kl = crossSection.length; k < kl; k += 2 ) {
|
|
|
+
|
|
|
+ vertex.x = crossSection[ k + 0 ];
|
|
|
+ vertex.y = 0;
|
|
|
+ vertex.z = crossSection[ k + 1 ];
|
|
|
+
|
|
|
+ // scale
|
|
|
+
|
|
|
+ vertex.multiply( scaling );
|
|
|
+
|
|
|
+ // rotate
|
|
|
+
|
|
|
+ quaternion.setFromAxisAngle( axis, angle );
|
|
|
+ vertex.applyQuaternion( quaternion );
|
|
|
+
|
|
|
+ // translate
|
|
|
+
|
|
|
+ vertex.add( spineVector );
|
|
|
+
|
|
|
+ vertices.push( vertex.x, vertex.y, vertex.z );
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ // indices
|
|
|
+
|
|
|
+ var indices = [];
|
|
|
+
|
|
|
+ var spineCount = spine.length / 3;
|
|
|
+ var crossSectionCount = crossSection.length / 2;
|
|
|
+
|
|
|
+ for ( var i = 0; i < spineCount - 1; i ++ ) {
|
|
|
+
|
|
|
+ for ( var j = 0; j < crossSectionCount - 1; j ++ ) {
|
|
|
+
|
|
|
+ var a = j + i * crossSectionCount;
|
|
|
+ var b = ( j + 1 ) + i * crossSectionCount;
|
|
|
+ var c = j + ( i + 1 ) * crossSectionCount;
|
|
|
+ var d = ( j + 1 ) + ( i + 1 ) * crossSectionCount;
|
|
|
+
|
|
|
+ if ( ( j === crossSectionCount - 2 ) && ( crossSectionClosed === true ) ) {
|
|
|
+
|
|
|
+ b = i * crossSectionCount;
|
|
|
+ d = ( i + 1 ) * crossSectionCount;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ if ( ccw === true ) {
|
|
|
+
|
|
|
+ indices.push( a, b, c );
|
|
|
+ indices.push( c, b, d );
|
|
|
+
|
|
|
+ } else {
|
|
|
+
|
|
|
+ indices.push( a, c, b );
|
|
|
+ indices.push( c, d, b );
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ // triangulate cap
|
|
|
+
|
|
|
+ if ( beginCap === true || endCap === true ) {
|
|
|
+
|
|
|
+ var contour = [];
|
|
|
+
|
|
|
+ for ( var i = 0, l = crossSection.length; i < l; i += 2 ) {
|
|
|
+
|
|
|
+ contour.push( new THREE.Vector2( crossSection[ i ], crossSection[ i + 1 ] ) );
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ var faces = THREE.ShapeUtils.triangulateShape( contour, [] );
|
|
|
+ var capIndices = [];
|
|
|
+
|
|
|
+ for ( var i = 0, l = faces.length; i < l; i ++ ) {
|
|
|
+
|
|
|
+ var face = faces[ i ];
|
|
|
+
|
|
|
+ capIndices.push( face[ 0 ], face[ 1 ], face[ 2 ] );
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ // begin cap
|
|
|
+
|
|
|
+ if ( beginCap === true ) {
|
|
|
+
|
|
|
+ for ( var i = 0, l = capIndices.length; i < l; i += 3 ) {
|
|
|
+
|
|
|
+ if ( ccw === true ) {
|
|
|
+
|
|
|
+ indices.push( capIndices[ i + 0 ], capIndices[ i + 1 ], capIndices[ i + 2 ] );
|
|
|
+
|
|
|
+ } else {
|
|
|
+
|
|
|
+ indices.push( capIndices[ i + 0 ], capIndices[ i + 2 ], capIndices[ i + 1 ] );
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ // end cap
|
|
|
+
|
|
|
+ if ( endCap === true ) {
|
|
|
+
|
|
|
+ var indexOffset = crossSectionCount * ( spineCount - 1 ); // references to the first vertex of the last cross section
|
|
|
+
|
|
|
+ for ( var i = 0, l = capIndices.length; i < l; i += 3 ) {
|
|
|
+
|
|
|
+ if ( ccw === true ) {
|
|
|
+
|
|
|
+ indices.push( indexOffset + capIndices[ i + 0 ], indexOffset + capIndices[ i + 2 ], indexOffset + capIndices[ i + 1 ] );
|
|
|
+
|
|
|
+ } else {
|
|
|
+
|
|
|
+ indices.push( indexOffset + capIndices[ i + 0 ], indexOffset + capIndices[ i + 1 ], indexOffset + capIndices[ i + 2 ] );
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ var positionAttribute = toNonIndexedAttribute( indices, new THREE.Float32BufferAttribute( vertices, 3 ) );
|
|
|
+ var normalAttribute = computeNormalAttribute( indices, vertices, creaseAngle );
|
|
|
+
|
|
|
+ var geometry = new THREE.BufferGeometry();
|
|
|
+ geometry.setAttribute( 'position', positionAttribute );
|
|
|
+ geometry.setAttribute( 'normal', normalAttribute );
|
|
|
+ // no uvs yet
|
|
|
+
|
|
|
+ // "solid" influences the material so let's store it for later use
|
|
|
+
|
|
|
+ geometry._solid = solid;
|
|
|
+ geometry._type = 'mesh';
|
|
|
+
|
|
|
+ return geometry;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
// helper functions
|
|
|
|
|
|
function resolveUSE( identifier ) {
|
|
@@ -2658,14 +3267,36 @@ THREE.VRMLLoader = ( function () {
|
|
|
$.RULE( 'def', function () {
|
|
|
|
|
|
$.CONSUME( DEF );
|
|
|
- $.CONSUME( Identifier );
|
|
|
+ $.OR( [
|
|
|
+ { ALT: function () {
|
|
|
+
|
|
|
+ $.CONSUME( Identifier );
|
|
|
+
|
|
|
+ } },
|
|
|
+ { ALT: function () {
|
|
|
+
|
|
|
+ $.CONSUME( NodeName );
|
|
|
+
|
|
|
+ } }
|
|
|
+ ] );
|
|
|
|
|
|
} );
|
|
|
|
|
|
$.RULE( 'use', function () {
|
|
|
|
|
|
$.CONSUME( USE );
|
|
|
- $.CONSUME( Identifier );
|
|
|
+ $.OR( [
|
|
|
+ { ALT: function () {
|
|
|
+
|
|
|
+ $.CONSUME( Identifier );
|
|
|
+
|
|
|
+ } },
|
|
|
+ { ALT: function () {
|
|
|
+
|
|
|
+ $.CONSUME( NodeName );
|
|
|
+
|
|
|
+ } }
|
|
|
+ ] );
|
|
|
|
|
|
} );
|
|
|
|