2
0

VRMLLoader.js 73 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456
  1. console.warn( "THREE.VRMLLoader: As part of the transition to ES6 Modules, the files in 'examples/js' were deprecated in May 2020 (r117) and will be deleted in December 2020 (r124). You can find more information about developing using ES6 Modules in https://threejs.org/docs/#manual/en/introduction/Installation." );
  2. THREE.VRMLLoader = ( function () {
  3. // dependency check
  4. if ( typeof chevrotain === 'undefined' ) { // eslint-disable-line no-undef
  5. throw Error( 'THREE.VRMLLoader: External library chevrotain.min.js required.' );
  6. }
  7. // class definitions
  8. function VRMLLoader( manager ) {
  9. THREE.Loader.call( this, manager );
  10. }
  11. VRMLLoader.prototype = Object.assign( Object.create( THREE.Loader.prototype ), {
  12. constructor: VRMLLoader,
  13. load: function ( url, onLoad, onProgress, onError ) {
  14. var scope = this;
  15. var path = ( scope.path === '' ) ? THREE.LoaderUtils.extractUrlBase( url ) : scope.path;
  16. var loader = new THREE.FileLoader( scope.manager );
  17. loader.setPath( scope.path );
  18. loader.setRequestHeader( scope.requestHeader );
  19. loader.setWithCredentials( scope.withCredentials );
  20. loader.load( url, function ( text ) {
  21. try {
  22. onLoad( scope.parse( text, path ) );
  23. } catch ( e ) {
  24. if ( onError ) {
  25. onError( e );
  26. } else {
  27. console.error( e );
  28. }
  29. scope.manager.itemError( url );
  30. }
  31. }, onProgress, onError );
  32. },
  33. parse: function ( data, path ) {
  34. var nodeMap = {};
  35. function generateVRMLTree( data ) {
  36. // create lexer, parser and visitor
  37. var tokenData = createTokens();
  38. var lexer = new VRMLLexer( tokenData.tokens );
  39. var parser = new VRMLParser( tokenData.tokenVocabulary );
  40. var visitor = createVisitor( parser.getBaseCstVisitorConstructor() );
  41. // lexing
  42. var lexingResult = lexer.lex( data );
  43. parser.input = lexingResult.tokens;
  44. // parsing
  45. var cstOutput = parser.vrml();
  46. if ( parser.errors.length > 0 ) {
  47. console.error( parser.errors );
  48. throw Error( 'THREE.VRMLLoader: Parsing errors detected.' );
  49. }
  50. // actions
  51. var ast = visitor.visit( cstOutput );
  52. return ast;
  53. }
  54. function createTokens() {
  55. var createToken = chevrotain.createToken; // eslint-disable-line no-undef
  56. // from http://gun.teipir.gr/VRML-amgem/spec/part1/concepts.html#SyntaxBasics
  57. var RouteIdentifier = createToken( { name: 'RouteIdentifier', pattern: /[^\x30-\x39\0-\x20\x22\x27\x23\x2b\x2c\x2d\x2e\x5b\x5d\x5c\x7b\x7d][^\0-\x20\x22\x27\x23\x2b\x2c\x2d\x2e\x5b\x5d\x5c\x7b\x7d]*[\.][^\x30-\x39\0-\x20\x22\x27\x23\x2b\x2c\x2d\x2e\x5b\x5d\x5c\x7b\x7d][^\0-\x20\x22\x27\x23\x2b\x2c\x2d\x2e\x5b\x5d\x5c\x7b\x7d]*/ } );
  58. var Identifier = createToken( { name: 'Identifier', pattern: /[^\x30-\x39\0-\x20\x22\x27\x23\x2b\x2c\x2d\x2e\x5b\x5d\x5c\x7b\x7d][^\0-\x20\x22\x27\x23\x2b\x2c\x2d\x2e\x5b\x5d\x5c\x7b\x7d]*/, longer_alt: RouteIdentifier } );
  59. // from http://gun.teipir.gr/VRML-amgem/spec/part1/nodesRef.html
  60. var nodeTypes = [
  61. 'Anchor', 'Billboard', 'Collision', 'Group', 'Transform', // grouping nodes
  62. 'Inline', 'LOD', 'Switch', // special groups
  63. 'AudioClip', 'DirectionalLight', 'PointLight', 'Script', 'Shape', 'Sound', 'SpotLight', 'WorldInfo', // common nodes
  64. 'CylinderSensor', 'PlaneSensor', 'ProximitySensor', 'SphereSensor', 'TimeSensor', 'TouchSensor', 'VisibilitySensor', // sensors
  65. 'Box', 'Cone', 'Cylinder', 'ElevationGrid', 'Extrusion', 'IndexedFaceSet', 'IndexedLineSet', 'PointSet', 'Sphere', // geometries
  66. 'Color', 'Coordinate', 'Normal', 'TextureCoordinate', // geometric properties
  67. 'Appearance', 'FontStyle', 'ImageTexture', 'Material', 'MovieTexture', 'PixelTexture', 'TextureTransform', // appearance
  68. 'ColorInterpolator', 'CoordinateInterpolator', 'NormalInterpolator', 'OrientationInterpolator', 'PositionInterpolator', 'ScalarInterpolator', // interpolators
  69. 'Background', 'Fog', 'NavigationInfo', 'Viewpoint', // bindable nodes
  70. 'Text' // Text must be placed at the end of the regex so there are no matches for TextureTransform and TextureCoordinate
  71. ];
  72. //
  73. var Version = createToken( {
  74. name: 'Version',
  75. pattern: /#VRML.*/,
  76. longer_alt: Identifier
  77. } );
  78. var NodeName = createToken( {
  79. name: 'NodeName',
  80. pattern: new RegExp( nodeTypes.join( '|' ) ),
  81. longer_alt: Identifier
  82. } );
  83. var DEF = createToken( {
  84. name: 'DEF',
  85. pattern: /DEF/,
  86. longer_alt: Identifier
  87. } );
  88. var USE = createToken( {
  89. name: 'USE',
  90. pattern: /USE/,
  91. longer_alt: Identifier
  92. } );
  93. var ROUTE = createToken( {
  94. name: 'ROUTE',
  95. pattern: /ROUTE/,
  96. longer_alt: Identifier
  97. } );
  98. var TO = createToken( {
  99. name: 'TO',
  100. pattern: /TO/,
  101. longer_alt: Identifier
  102. } );
  103. //
  104. var StringLiteral = createToken( { name: "StringLiteral", pattern: /"(:?[^\\"\n\r]+|\\(:?[bfnrtv"\\/]|u[0-9a-fA-F]{4}))*"/ } );
  105. var HexLiteral = createToken( { name: 'HexLiteral', pattern: /0[xX][0-9a-fA-F]+/ } );
  106. var NumberLiteral = createToken( { name: 'NumberLiteral', pattern: /[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?/ } );
  107. var TrueLiteral = createToken( { name: 'TrueLiteral', pattern: /TRUE/ } );
  108. var FalseLiteral = createToken( { name: 'FalseLiteral', pattern: /FALSE/ } );
  109. var NullLiteral = createToken( { name: 'NullLiteral', pattern: /NULL/ } );
  110. var LSquare = createToken( { name: 'LSquare', pattern: /\[/ } );
  111. var RSquare = createToken( { name: 'RSquare', pattern: /]/ } );
  112. var LCurly = createToken( { name: 'LCurly', pattern: /{/ } );
  113. var RCurly = createToken( { name: 'RCurly', pattern: /}/ } );
  114. var Comment = createToken( {
  115. name: 'Comment',
  116. pattern: /#.*/,
  117. group: chevrotain.Lexer.SKIPPED // eslint-disable-line no-undef
  118. } );
  119. // commas, blanks, tabs, newlines and carriage returns are whitespace characters wherever they appear outside of string fields
  120. var WhiteSpace = createToken( {
  121. name: 'WhiteSpace',
  122. pattern: /[ ,\s]/,
  123. group: chevrotain.Lexer.SKIPPED // eslint-disable-line no-undef
  124. } );
  125. var tokens = [
  126. WhiteSpace,
  127. // keywords appear before the Identifier
  128. NodeName,
  129. DEF,
  130. USE,
  131. ROUTE,
  132. TO,
  133. TrueLiteral,
  134. FalseLiteral,
  135. NullLiteral,
  136. // the Identifier must appear after the keywords because all keywords are valid identifiers
  137. Version,
  138. Identifier,
  139. RouteIdentifier,
  140. StringLiteral,
  141. HexLiteral,
  142. NumberLiteral,
  143. LSquare,
  144. RSquare,
  145. LCurly,
  146. RCurly,
  147. Comment
  148. ];
  149. var tokenVocabulary = {};
  150. for ( var i = 0, l = tokens.length; i < l; i ++ ) {
  151. var token = tokens[ i ];
  152. tokenVocabulary[ token.name ] = token;
  153. }
  154. return { tokens: tokens, tokenVocabulary: tokenVocabulary };
  155. }
  156. function createVisitor( BaseVRMLVisitor ) {
  157. // the visitor is created dynmaically based on the given base class
  158. function VRMLToASTVisitor() {
  159. BaseVRMLVisitor.call( this );
  160. this.validateVisitor();
  161. }
  162. VRMLToASTVisitor.prototype = Object.assign( Object.create( BaseVRMLVisitor.prototype ), {
  163. constructor: VRMLToASTVisitor,
  164. vrml: function ( ctx ) {
  165. var data = {
  166. version: this.visit( ctx.version ),
  167. nodes: [],
  168. routes: []
  169. };
  170. for ( var i = 0, l = ctx.node.length; i < l; i ++ ) {
  171. var node = ctx.node[ i ];
  172. data.nodes.push( this.visit( node ) );
  173. }
  174. if ( ctx.route ) {
  175. for ( var i = 0, l = ctx.route.length; i < l; i ++ ) {
  176. var route = ctx.route[ i ];
  177. data.routes.push( this.visit( route ) );
  178. }
  179. }
  180. return data;
  181. },
  182. version: function ( ctx ) {
  183. return ctx.Version[ 0 ].image;
  184. },
  185. node: function ( ctx ) {
  186. var data = {
  187. name: ctx.NodeName[ 0 ].image,
  188. fields: []
  189. };
  190. if ( ctx.field ) {
  191. for ( var i = 0, l = ctx.field.length; i < l; i ++ ) {
  192. var field = ctx.field[ i ];
  193. data.fields.push( this.visit( field ) );
  194. }
  195. }
  196. // DEF
  197. if ( ctx.def ) {
  198. data.DEF = this.visit( ctx.def[ 0 ] );
  199. }
  200. return data;
  201. },
  202. field: function ( ctx ) {
  203. var data = {
  204. name: ctx.Identifier[ 0 ].image,
  205. type: null,
  206. values: null
  207. };
  208. var result;
  209. // SFValue
  210. if ( ctx.singleFieldValue ) {
  211. result = this.visit( ctx.singleFieldValue[ 0 ] );
  212. }
  213. // MFValue
  214. if ( ctx.multiFieldValue ) {
  215. result = this.visit( ctx.multiFieldValue[ 0 ] );
  216. }
  217. data.type = result.type;
  218. data.values = result.values;
  219. return data;
  220. },
  221. def: function ( ctx ) {
  222. return ( ctx.Identifier || ctx.NodeName )[ 0 ].image;
  223. },
  224. use: function ( ctx ) {
  225. return { USE: ( ctx.Identifier || ctx.NodeName )[ 0 ].image };
  226. },
  227. singleFieldValue: function ( ctx ) {
  228. return processField( this, ctx );
  229. },
  230. multiFieldValue: function ( ctx ) {
  231. return processField( this, ctx );
  232. },
  233. route: function ( ctx ) {
  234. var data = {
  235. FROM: ctx.RouteIdentifier[ 0 ].image,
  236. TO: ctx.RouteIdentifier[ 1 ].image
  237. };
  238. return data;
  239. }
  240. } );
  241. function processField( scope, ctx ) {
  242. var field = {
  243. type: null,
  244. values: []
  245. };
  246. if ( ctx.node ) {
  247. field.type = 'node';
  248. for ( var i = 0, l = ctx.node.length; i < l; i ++ ) {
  249. var node = ctx.node[ i ];
  250. field.values.push( scope.visit( node ) );
  251. }
  252. }
  253. if ( ctx.use ) {
  254. field.type = 'use';
  255. for ( var i = 0, l = ctx.use.length; i < l; i ++ ) {
  256. var use = ctx.use[ i ];
  257. field.values.push( scope.visit( use ) );
  258. }
  259. }
  260. if ( ctx.StringLiteral ) {
  261. field.type = 'string';
  262. for ( var i = 0, l = ctx.StringLiteral.length; i < l; i ++ ) {
  263. var stringLiteral = ctx.StringLiteral[ i ];
  264. field.values.push( stringLiteral.image.replace( /'|"/g, '' ) );
  265. }
  266. }
  267. if ( ctx.NumberLiteral ) {
  268. field.type = 'number';
  269. for ( var i = 0, l = ctx.NumberLiteral.length; i < l; i ++ ) {
  270. var numberLiteral = ctx.NumberLiteral[ i ];
  271. field.values.push( parseFloat( numberLiteral.image ) );
  272. }
  273. }
  274. if ( ctx.HexLiteral ) {
  275. field.type = 'hex';
  276. for ( var i = 0, l = ctx.HexLiteral.length; i < l; i ++ ) {
  277. var hexLiteral = ctx.HexLiteral[ i ];
  278. field.values.push( hexLiteral.image );
  279. }
  280. }
  281. if ( ctx.TrueLiteral ) {
  282. field.type = 'boolean';
  283. for ( var i = 0, l = ctx.TrueLiteral.length; i < l; i ++ ) {
  284. var trueLiteral = ctx.TrueLiteral[ i ];
  285. if ( trueLiteral.image === 'TRUE' ) field.values.push( true );
  286. }
  287. }
  288. if ( ctx.FalseLiteral ) {
  289. field.type = 'boolean';
  290. for ( var i = 0, l = ctx.FalseLiteral.length; i < l; i ++ ) {
  291. var falseLiteral = ctx.FalseLiteral[ i ];
  292. if ( falseLiteral.image === 'FALSE' ) field.values.push( false );
  293. }
  294. }
  295. if ( ctx.NullLiteral ) {
  296. field.type = 'null';
  297. ctx.NullLiteral.forEach( function () {
  298. field.values.push( null );
  299. } );
  300. }
  301. return field;
  302. }
  303. return new VRMLToASTVisitor();
  304. }
  305. function parseTree( tree ) {
  306. // console.log( JSON.stringify( tree, null, 2 ) );
  307. var nodes = tree.nodes;
  308. var scene = new THREE.Scene();
  309. // first iteration: build nodemap based on DEF statements
  310. for ( var i = 0, l = nodes.length; i < l; i ++ ) {
  311. var node = nodes[ i ];
  312. buildNodeMap( node );
  313. }
  314. // second iteration: build nodes
  315. for ( var i = 0, l = nodes.length; i < l; i ++ ) {
  316. var node = nodes[ i ];
  317. var object = getNode( node );
  318. if ( object instanceof THREE.Object3D ) scene.add( object );
  319. if ( node.name === 'WorldInfo' ) scene.userData.worldInfo = object;
  320. }
  321. return scene;
  322. }
  323. function buildNodeMap( node ) {
  324. if ( node.DEF ) {
  325. nodeMap[ node.DEF ] = node;
  326. }
  327. var fields = node.fields;
  328. for ( var i = 0, l = fields.length; i < l; i ++ ) {
  329. var field = fields[ i ];
  330. if ( field.type === 'node' ) {
  331. var fieldValues = field.values;
  332. for ( var j = 0, jl = fieldValues.length; j < jl; j ++ ) {
  333. buildNodeMap( fieldValues[ j ] );
  334. }
  335. }
  336. }
  337. }
  338. function getNode( node ) {
  339. // handle case where a node refers to a different one
  340. if ( node.USE ) {
  341. return resolveUSE( node.USE );
  342. }
  343. if ( node.build !== undefined ) return node.build;
  344. node.build = buildNode( node );
  345. return node.build;
  346. }
  347. // node builder
  348. function buildNode( node ) {
  349. var nodeName = node.name;
  350. var build;
  351. switch ( nodeName ) {
  352. case 'Group':
  353. case 'Transform':
  354. case 'Collision':
  355. build = buildGroupingNode( node );
  356. break;
  357. case 'Background':
  358. build = buildBackgroundNode( node );
  359. break;
  360. case 'Shape':
  361. build = buildShapeNode( node );
  362. break;
  363. case 'Appearance':
  364. build = buildAppearanceNode( node );
  365. break;
  366. case 'Material':
  367. build = buildMaterialNode( node );
  368. break;
  369. case 'ImageTexture':
  370. build = buildImageTextureNode( node );
  371. break;
  372. case 'PixelTexture':
  373. build = buildPixelTextureNode( node );
  374. break;
  375. case 'TextureTransform':
  376. build = buildTextureTransformNode( node );
  377. break;
  378. case 'IndexedFaceSet':
  379. build = buildIndexedFaceSetNode( node );
  380. break;
  381. case 'IndexedLineSet':
  382. build = buildIndexedLineSetNode( node );
  383. break;
  384. case 'PointSet':
  385. build = buildPointSetNode( node );
  386. break;
  387. case 'Box':
  388. build = buildBoxNode( node );
  389. break;
  390. case 'Cone':
  391. build = buildConeNode( node );
  392. break;
  393. case 'Cylinder':
  394. build = buildCylinderNode( node );
  395. break;
  396. case 'Sphere':
  397. build = buildSphereNode( node );
  398. break;
  399. case 'ElevationGrid':
  400. build = buildElevationGridNode( node );
  401. break;
  402. case 'Extrusion':
  403. build = buildExtrusionNode( node );
  404. break;
  405. case 'Color':
  406. case 'Coordinate':
  407. case 'Normal':
  408. case 'TextureCoordinate':
  409. build = buildGeometricNode( node );
  410. break;
  411. case 'WorldInfo':
  412. build = buildWorldInfoNode( node );
  413. break;
  414. case 'Anchor':
  415. case 'Billboard':
  416. case 'Inline':
  417. case 'LOD':
  418. case 'Switch':
  419. case 'AudioClip':
  420. case 'DirectionalLight':
  421. case 'PointLight':
  422. case 'Script':
  423. case 'Sound':
  424. case 'SpotLight':
  425. case 'CylinderSensor':
  426. case 'PlaneSensor':
  427. case 'ProximitySensor':
  428. case 'SphereSensor':
  429. case 'TimeSensor':
  430. case 'TouchSensor':
  431. case 'VisibilitySensor':
  432. case 'Text':
  433. case 'FontStyle':
  434. case 'MovieTexture':
  435. case 'ColorInterpolator':
  436. case 'CoordinateInterpolator':
  437. case 'NormalInterpolator':
  438. case 'OrientationInterpolator':
  439. case 'PositionInterpolator':
  440. case 'ScalarInterpolator':
  441. case 'Fog':
  442. case 'NavigationInfo':
  443. case 'Viewpoint':
  444. // node not supported yet
  445. break;
  446. default:
  447. console.warn( 'THREE.VRMLLoader: Unknown node:', nodeName );
  448. break;
  449. }
  450. return build;
  451. }
  452. function buildGroupingNode( node ) {
  453. var object = new THREE.Group();
  454. //
  455. var fields = node.fields;
  456. for ( var i = 0, l = fields.length; i < l; i ++ ) {
  457. var field = fields[ i ];
  458. var fieldName = field.name;
  459. var fieldValues = field.values;
  460. switch ( fieldName ) {
  461. case 'bboxCenter':
  462. // field not supported
  463. break;
  464. case 'bboxSize':
  465. // field not supported
  466. break;
  467. case 'center':
  468. // field not supported
  469. break;
  470. case 'children':
  471. parseFieldChildren( fieldValues, object );
  472. break;
  473. case 'collide':
  474. // field not supported
  475. break;
  476. case 'rotation':
  477. var axis = new THREE.Vector3( fieldValues[ 0 ], fieldValues[ 1 ], fieldValues[ 2 ] );
  478. var angle = fieldValues[ 3 ];
  479. object.quaternion.setFromAxisAngle( axis, angle );
  480. break;
  481. case 'scale':
  482. object.scale.set( fieldValues[ 0 ], fieldValues[ 1 ], fieldValues[ 2 ] );
  483. break;
  484. case 'scaleOrientation':
  485. // field not supported
  486. break;
  487. case 'translation':
  488. object.position.set( fieldValues[ 0 ], fieldValues[ 1 ], fieldValues[ 2 ] );
  489. break;
  490. case 'proxy':
  491. // field not supported
  492. break;
  493. default:
  494. console.warn( 'THREE.VRMLLoader: Unknown field:', fieldName );
  495. break;
  496. }
  497. }
  498. return object;
  499. }
  500. function buildBackgroundNode( node ) {
  501. var group = new THREE.Group();
  502. var groundAngle, groundColor;
  503. var skyAngle, skyColor;
  504. var fields = node.fields;
  505. for ( var i = 0, l = fields.length; i < l; i ++ ) {
  506. var field = fields[ i ];
  507. var fieldName = field.name;
  508. var fieldValues = field.values;
  509. switch ( fieldName ) {
  510. case 'groundAngle':
  511. groundAngle = fieldValues;
  512. break;
  513. case 'groundColor':
  514. groundColor = fieldValues;
  515. break;
  516. case 'backUrl':
  517. // field not supported
  518. break;
  519. case 'bottomUrl':
  520. // field not supported
  521. break;
  522. case 'frontUrl':
  523. // field not supported
  524. break;
  525. case 'leftUrl':
  526. // field not supported
  527. break;
  528. case 'rightUrl':
  529. // field not supported
  530. break;
  531. case 'topUrl':
  532. // field not supported
  533. break;
  534. case 'skyAngle':
  535. skyAngle = fieldValues;
  536. break;
  537. case 'skyColor':
  538. skyColor = fieldValues;
  539. break;
  540. default:
  541. console.warn( 'THREE.VRMLLoader: Unknown field:', fieldName );
  542. break;
  543. }
  544. }
  545. var radius = 10000;
  546. // sky
  547. if ( skyColor ) {
  548. var skyGeometry = new THREE.SphereBufferGeometry( radius, 32, 16 );
  549. var skyMaterial = new THREE.MeshBasicMaterial( { fog: false, side: THREE.BackSide, depthWrite: false, depthTest: false } );
  550. if ( skyColor.length > 3 ) {
  551. paintFaces( skyGeometry, radius, skyAngle, toColorArray( skyColor ), true );
  552. skyMaterial.vertexColors = true;
  553. } else {
  554. skyMaterial.color.setRGB( skyColor[ 0 ], skyColor[ 1 ], skyColor[ 2 ] );
  555. }
  556. var sky = new THREE.Mesh( skyGeometry, skyMaterial );
  557. group.add( sky );
  558. }
  559. // ground
  560. if ( groundColor ) {
  561. if ( groundColor.length > 0 ) {
  562. var groundGeometry = new THREE.SphereBufferGeometry( radius, 32, 16, 0, 2 * Math.PI, 0.5 * Math.PI, 1.5 * Math.PI );
  563. var groundMaterial = new THREE.MeshBasicMaterial( { fog: false, side: THREE.BackSide, vertexColors: true, depthWrite: false, depthTest: false } );
  564. paintFaces( groundGeometry, radius, groundAngle, toColorArray( groundColor ), false );
  565. var ground = new THREE.Mesh( groundGeometry, groundMaterial );
  566. group.add( ground );
  567. }
  568. }
  569. // render background group first
  570. group.renderOrder = - Infinity;
  571. return group;
  572. }
  573. function buildShapeNode( node ) {
  574. var fields = node.fields;
  575. // if the appearance field is NULL or unspecified, lighting is off and the unlit object color is (0, 0, 0)
  576. var material = new THREE.MeshBasicMaterial( { color: 0x000000 } );
  577. var geometry;
  578. for ( var i = 0, l = fields.length; i < l; i ++ ) {
  579. var field = fields[ i ];
  580. var fieldName = field.name;
  581. var fieldValues = field.values;
  582. switch ( fieldName ) {
  583. case 'appearance':
  584. if ( fieldValues[ 0 ] !== null ) {
  585. material = getNode( fieldValues[ 0 ] );
  586. }
  587. break;
  588. case 'geometry':
  589. if ( fieldValues[ 0 ] !== null ) {
  590. geometry = getNode( fieldValues[ 0 ] );
  591. }
  592. break;
  593. default:
  594. console.warn( 'THREE.VRMLLoader: Unknown field:', fieldName );
  595. break;
  596. }
  597. }
  598. // build 3D object
  599. var object;
  600. if ( geometry && geometry.attributes.position ) {
  601. var type = geometry._type;
  602. if ( type === 'points' ) { // points
  603. var pointsMaterial = new THREE.PointsMaterial( { color: 0xffffff } );
  604. if ( geometry.attributes.color !== undefined ) {
  605. pointsMaterial.vertexColors = true;
  606. } else {
  607. // if the color field is NULL and there is a material defined for the appearance affecting this PointSet, then use the emissiveColor of the material to draw the points
  608. if ( material.isMeshPhongMaterial ) {
  609. pointsMaterial.color.copy( material.emissive );
  610. }
  611. }
  612. object = new THREE.Points( geometry, pointsMaterial );
  613. } else if ( type === 'line' ) { // lines
  614. var lineMaterial = new THREE.LineBasicMaterial( { color: 0xffffff } );
  615. if ( geometry.attributes.color !== undefined ) {
  616. lineMaterial.vertexColors = true;
  617. } else {
  618. // if the color field is NULL and there is a material defined for the appearance affecting this IndexedLineSet, then use the emissiveColor of the material to draw the lines
  619. if ( material.isMeshPhongMaterial ) {
  620. lineMaterial.color.copy( material.emissive );
  621. }
  622. }
  623. object = new THREE.LineSegments( geometry, lineMaterial );
  624. } else { // consider meshes
  625. // check "solid" hint (it's placed in the geometry but affects the material)
  626. if ( geometry._solid !== undefined ) {
  627. material.side = ( geometry._solid ) ? THREE.FrontSide : THREE.DoubleSide;
  628. }
  629. // check for vertex colors
  630. if ( geometry.attributes.color !== undefined ) {
  631. material.vertexColors = true;
  632. }
  633. object = new THREE.Mesh( geometry, material );
  634. }
  635. } else {
  636. object = new THREE.Object3D();
  637. // if the geometry field is NULL or no vertices are defined the object is not drawn
  638. object.visible = false;
  639. }
  640. return object;
  641. }
  642. function buildAppearanceNode( node ) {
  643. var material = new THREE.MeshPhongMaterial();
  644. var transformData;
  645. var fields = node.fields;
  646. for ( var i = 0, l = fields.length; i < l; i ++ ) {
  647. var field = fields[ i ];
  648. var fieldName = field.name;
  649. var fieldValues = field.values;
  650. switch ( fieldName ) {
  651. case 'material':
  652. if ( fieldValues[ 0 ] !== null ) {
  653. var materialData = getNode( fieldValues[ 0 ] );
  654. if ( materialData.diffuseColor ) material.color.copy( materialData.diffuseColor );
  655. if ( materialData.emissiveColor ) material.emissive.copy( materialData.emissiveColor );
  656. if ( materialData.shininess ) material.shininess = materialData.shininess;
  657. if ( materialData.specularColor ) material.specular.copy( materialData.specularColor );
  658. if ( materialData.transparency ) material.opacity = 1 - materialData.transparency;
  659. if ( materialData.transparency > 0 ) material.transparent = true;
  660. } else {
  661. // if the material field is NULL or unspecified, lighting is off and the unlit object color is (0, 0, 0)
  662. material = new THREE.MeshBasicMaterial( { color: 0x000000 } );
  663. }
  664. break;
  665. case 'texture':
  666. var textureNode = fieldValues[ 0 ];
  667. if ( textureNode !== null ) {
  668. if ( textureNode.name === 'ImageTexture' || textureNode.name === 'PixelTexture' ) {
  669. material.map = getNode( textureNode );
  670. } else {
  671. // MovieTexture not supported yet
  672. }
  673. }
  674. break;
  675. case 'textureTransform':
  676. if ( fieldValues[ 0 ] !== null ) {
  677. transformData = getNode( fieldValues[ 0 ] );
  678. }
  679. break;
  680. default:
  681. console.warn( 'THREE.VRMLLoader: Unknown field:', fieldName );
  682. break;
  683. }
  684. }
  685. // only apply texture transform data if a texture was defined
  686. if ( material.map ) {
  687. // respect VRML lighting model
  688. if ( material.map.__type ) {
  689. switch ( material.map.__type ) {
  690. case TEXTURE_TYPE.INTENSITY_ALPHA:
  691. material.opacity = 1; // ignore transparency
  692. break;
  693. case TEXTURE_TYPE.RGB:
  694. material.color.set( 0xffffff ); // ignore material color
  695. break;
  696. case TEXTURE_TYPE.RGBA:
  697. material.color.set( 0xffffff ); // ignore material color
  698. material.opacity = 1; // ignore transparency
  699. break;
  700. default:
  701. }
  702. delete material.map.__type;
  703. }
  704. // apply texture transform
  705. if ( transformData ) {
  706. material.map.center.copy( transformData.center );
  707. material.map.rotation = transformData.rotation;
  708. material.map.repeat.copy( transformData.scale );
  709. material.map.offset.copy( transformData.translation );
  710. }
  711. }
  712. return material;
  713. }
  714. function buildMaterialNode( node ) {
  715. var materialData = {};
  716. var fields = node.fields;
  717. for ( var i = 0, l = fields.length; i < l; i ++ ) {
  718. var field = fields[ i ];
  719. var fieldName = field.name;
  720. var fieldValues = field.values;
  721. switch ( fieldName ) {
  722. case 'ambientIntensity':
  723. // field not supported
  724. break;
  725. case 'diffuseColor':
  726. materialData.diffuseColor = new THREE.Color( fieldValues[ 0 ], fieldValues[ 1 ], fieldValues[ 2 ] );
  727. break;
  728. case 'emissiveColor':
  729. materialData.emissiveColor = new THREE.Color( fieldValues[ 0 ], fieldValues[ 1 ], fieldValues[ 2 ] );
  730. break;
  731. case 'shininess':
  732. materialData.shininess = fieldValues[ 0 ];
  733. break;
  734. case 'specularColor':
  735. materialData.emissiveColor = new THREE.Color( fieldValues[ 0 ], fieldValues[ 1 ], fieldValues[ 2 ] );
  736. break;
  737. case 'transparency':
  738. materialData.transparency = fieldValues[ 0 ];
  739. break;
  740. default:
  741. console.warn( 'THREE.VRMLLoader: Unknown field:', fieldName );
  742. break;
  743. }
  744. }
  745. return materialData;
  746. }
  747. function parseHexColor( hex, textureType, color ) {
  748. switch ( textureType ) {
  749. case TEXTURE_TYPE.INTENSITY:
  750. // Intensity texture: A one-component image specifies one-byte hexadecimal or integer values representing the intensity of the image
  751. var value = parseInt( hex );
  752. color.r = value;
  753. color.g = value;
  754. color.b = value;
  755. break;
  756. case TEXTURE_TYPE.INTENSITY_ALPHA:
  757. // Intensity+Alpha texture: A two-component image specifies the intensity in the first (high) byte and the alpha opacity in the second (low) byte.
  758. var value = parseInt( "0x" + hex.substring( 2, 4 ) );
  759. color.r = value;
  760. color.g = value;
  761. color.b = value;
  762. color.a = parseInt( "0x" + hex.substring( 4, 6 ) );
  763. break;
  764. case TEXTURE_TYPE.RGB:
  765. // RGB texture: Pixels in a three-component image specify the red component in the first (high) byte, followed by the green and blue components
  766. color.r = parseInt( "0x" + hex.substring( 2, 4 ) );
  767. color.g = parseInt( "0x" + hex.substring( 4, 6 ) );
  768. color.b = parseInt( "0x" + hex.substring( 6, 8 ) );
  769. break;
  770. case TEXTURE_TYPE.RGBA:
  771. // RGBA texture: Four-component images specify the alpha opacity byte after red/green/blue
  772. color.r = parseInt( "0x" + hex.substring( 2, 4 ) );
  773. color.g = parseInt( "0x" + hex.substring( 4, 6 ) );
  774. color.b = parseInt( "0x" + hex.substring( 6, 8 ) );
  775. color.a = parseInt( "0x" + hex.substring( 8, 10 ) );
  776. break;
  777. default:
  778. }
  779. }
  780. function getTextureType( num_components ) {
  781. var type;
  782. switch ( num_components ) {
  783. case 1:
  784. type = TEXTURE_TYPE.INTENSITY;
  785. break;
  786. case 2:
  787. type = TEXTURE_TYPE.INTENSITY_ALPHA;
  788. break;
  789. case 3:
  790. type = TEXTURE_TYPE.RGB;
  791. break;
  792. case 4:
  793. type = TEXTURE_TYPE.RGBA;
  794. break;
  795. default:
  796. }
  797. return type;
  798. }
  799. function buildPixelTextureNode( node ) {
  800. var texture;
  801. var wrapS = THREE.RepeatWrapping;
  802. var wrapT = THREE.RepeatWrapping;
  803. var fields = node.fields;
  804. for ( var i = 0, l = fields.length; i < l; i ++ ) {
  805. var field = fields[ i ];
  806. var fieldName = field.name;
  807. var fieldValues = field.values;
  808. switch ( fieldName ) {
  809. case 'image':
  810. var width = fieldValues[ 0 ];
  811. var height = fieldValues[ 1 ];
  812. var num_components = fieldValues[ 2 ];
  813. var useAlpha = ( num_components === 2 || num_components === 4 );
  814. var textureType = getTextureType( num_components );
  815. var size = ( ( useAlpha === true ) ? 4 : 3 ) * ( width * height );
  816. var data = new Uint8Array( size );
  817. var color = { r: 0, g: 0, b: 0, a: 0 };
  818. for ( var j = 3, k = 0, jl = fieldValues.length; j < jl; j ++, k ++ ) {
  819. parseHexColor( fieldValues[ j ], textureType, color );
  820. if ( useAlpha === true ) {
  821. var stride = k * 4;
  822. data[ stride + 0 ] = color.r;
  823. data[ stride + 1 ] = color.g;
  824. data[ stride + 2 ] = color.b;
  825. data[ stride + 3 ] = color.a;
  826. } else {
  827. var stride = k * 3;
  828. data[ stride + 0 ] = color.r;
  829. data[ stride + 1 ] = color.g;
  830. data[ stride + 2 ] = color.b;
  831. }
  832. }
  833. texture = new THREE.DataTexture( data, width, height, ( useAlpha === true ) ? THREE.RGBAFormat : THREE.RGBFormat );
  834. texture.__type = textureType; // needed for material modifications
  835. break;
  836. case 'repeatS':
  837. if ( fieldValues[ 0 ] === false ) wrapS = THREE.ClampToEdgeWrapping;
  838. break;
  839. case 'repeatT':
  840. if ( fieldValues[ 0 ] === false ) wrapT = THREE.ClampToEdgeWrapping;
  841. break;
  842. default:
  843. console.warn( 'THREE.VRMLLoader: Unknown field:', fieldName );
  844. break;
  845. }
  846. }
  847. if ( texture ) {
  848. texture.wrapS = wrapS;
  849. texture.wrapT = wrapT;
  850. }
  851. return texture;
  852. }
  853. function buildImageTextureNode( node ) {
  854. var texture;
  855. var wrapS = THREE.RepeatWrapping;
  856. var wrapT = THREE.RepeatWrapping;
  857. var fields = node.fields;
  858. for ( var i = 0, l = fields.length; i < l; i ++ ) {
  859. var field = fields[ i ];
  860. var fieldName = field.name;
  861. var fieldValues = field.values;
  862. switch ( fieldName ) {
  863. case 'url':
  864. var url = fieldValues[ 0 ];
  865. if ( url ) texture = textureLoader.load( url );
  866. break;
  867. case 'repeatS':
  868. if ( fieldValues[ 0 ] === false ) wrapS = THREE.ClampToEdgeWrapping;
  869. break;
  870. case 'repeatT':
  871. if ( fieldValues[ 0 ] === false ) wrapT = THREE.ClampToEdgeWrapping;
  872. break;
  873. default:
  874. console.warn( 'THREE.VRMLLoader: Unknown field:', fieldName );
  875. break;
  876. }
  877. }
  878. if ( texture ) {
  879. texture.wrapS = wrapS;
  880. texture.wrapT = wrapT;
  881. }
  882. return texture;
  883. }
  884. function buildTextureTransformNode( node ) {
  885. var transformData = {
  886. center: new THREE.Vector2(),
  887. rotation: new THREE.Vector2(),
  888. scale: new THREE.Vector2(),
  889. translation: new THREE.Vector2()
  890. };
  891. var fields = node.fields;
  892. for ( var i = 0, l = fields.length; i < l; i ++ ) {
  893. var field = fields[ i ];
  894. var fieldName = field.name;
  895. var fieldValues = field.values;
  896. switch ( fieldName ) {
  897. case 'center':
  898. transformData.center.set( fieldValues[ 0 ], fieldValues[ 1 ] );
  899. break;
  900. case 'rotation':
  901. transformData.rotation = fieldValues[ 0 ];
  902. break;
  903. case 'scale':
  904. transformData.scale.set( fieldValues[ 0 ], fieldValues[ 1 ] );
  905. break;
  906. case 'translation':
  907. transformData.translation.set( fieldValues[ 0 ], fieldValues[ 1 ] );
  908. break;
  909. default:
  910. console.warn( 'THREE.VRMLLoader: Unknown field:', fieldName );
  911. break;
  912. }
  913. }
  914. return transformData;
  915. }
  916. function buildGeometricNode( node ) {
  917. return node.fields[ 0 ].values;
  918. }
  919. function buildWorldInfoNode( node ) {
  920. var worldInfo = {};
  921. var fields = node.fields;
  922. for ( var i = 0, l = fields.length; i < l; i ++ ) {
  923. var field = fields[ i ];
  924. var fieldName = field.name;
  925. var fieldValues = field.values;
  926. switch ( fieldName ) {
  927. case 'title':
  928. worldInfo.title = fieldValues[ 0 ];
  929. break;
  930. case 'info':
  931. worldInfo.info = fieldValues;
  932. break;
  933. default:
  934. console.warn( 'THREE.VRMLLoader: Unknown field:', fieldName );
  935. break;
  936. }
  937. }
  938. return worldInfo;
  939. }
  940. function buildIndexedFaceSetNode( node ) {
  941. var color, coord, normal, texCoord;
  942. var ccw = true, solid = true, creaseAngle = 0;
  943. var colorIndex, coordIndex, normalIndex, texCoordIndex;
  944. var colorPerVertex = true, normalPerVertex = true;
  945. var fields = node.fields;
  946. for ( var i = 0, l = fields.length; i < l; i ++ ) {
  947. var field = fields[ i ];
  948. var fieldName = field.name;
  949. var fieldValues = field.values;
  950. switch ( fieldName ) {
  951. case 'color':
  952. var colorNode = fieldValues[ 0 ];
  953. if ( colorNode !== null ) {
  954. color = getNode( colorNode );
  955. }
  956. break;
  957. case 'coord':
  958. var coordNode = fieldValues[ 0 ];
  959. if ( coordNode !== null ) {
  960. coord = getNode( coordNode );
  961. }
  962. break;
  963. case 'normal':
  964. var normalNode = fieldValues[ 0 ];
  965. if ( normalNode !== null ) {
  966. normal = getNode( normalNode );
  967. }
  968. break;
  969. case 'texCoord':
  970. var texCoordNode = fieldValues[ 0 ];
  971. if ( texCoordNode !== null ) {
  972. texCoord = getNode( texCoordNode );
  973. }
  974. break;
  975. case 'ccw':
  976. ccw = fieldValues[ 0 ];
  977. break;
  978. case 'colorIndex':
  979. colorIndex = fieldValues;
  980. break;
  981. case 'colorPerVertex':
  982. colorPerVertex = fieldValues[ 0 ];
  983. break;
  984. case 'convex':
  985. // field not supported
  986. break;
  987. case 'coordIndex':
  988. coordIndex = fieldValues;
  989. break;
  990. case 'creaseAngle':
  991. creaseAngle = fieldValues[ 0 ];
  992. break;
  993. case 'normalIndex':
  994. normalIndex = fieldValues;
  995. break;
  996. case 'normalPerVertex':
  997. normalPerVertex = fieldValues[ 0 ];
  998. break;
  999. case 'solid':
  1000. solid = fieldValues[ 0 ];
  1001. break;
  1002. case 'texCoordIndex':
  1003. texCoordIndex = fieldValues;
  1004. break;
  1005. default:
  1006. console.warn( 'THREE.VRMLLoader: Unknown field:', fieldName );
  1007. break;
  1008. }
  1009. }
  1010. if ( coordIndex === undefined ) {
  1011. console.warn( 'THREE.VRMLLoader: Missing coordIndex.' );
  1012. return new THREE.BufferGeometry(); // handle VRML files with incomplete geometry definition
  1013. }
  1014. var triangulatedCoordIndex = triangulateFaceIndex( coordIndex, ccw );
  1015. var positionAttribute;
  1016. var colorAttribute;
  1017. var normalAttribute;
  1018. var uvAttribute;
  1019. if ( color ) {
  1020. if ( colorPerVertex === true ) {
  1021. if ( colorIndex && colorIndex.length > 0 ) {
  1022. // if the colorIndex field is not empty, then it is used to choose colors for each vertex of the IndexedFaceSet.
  1023. var triangulatedColorIndex = triangulateFaceIndex( colorIndex, ccw );
  1024. colorAttribute = computeAttributeFromIndexedData( triangulatedCoordIndex, triangulatedColorIndex, color, 3 );
  1025. } else {
  1026. // if the colorIndex field is empty, then the coordIndex field is used to choose colors from the Color node
  1027. colorAttribute = toNonIndexedAttribute( triangulatedCoordIndex, new THREE.Float32BufferAttribute( color, 3 ) );
  1028. }
  1029. } else {
  1030. if ( colorIndex && colorIndex.length > 0 ) {
  1031. // if the colorIndex field is not empty, then they are used to choose one color for each face of the IndexedFaceSet
  1032. var flattenFaceColors = flattenData( color, colorIndex );
  1033. var triangulatedFaceColors = triangulateFaceData( flattenFaceColors, coordIndex );
  1034. colorAttribute = computeAttributeFromFaceData( triangulatedCoordIndex, triangulatedFaceColors );
  1035. } else {
  1036. // if the colorIndex field is empty, then the color are applied to each face of the IndexedFaceSet in order
  1037. var triangulatedFaceColors = triangulateFaceData( color, coordIndex );
  1038. colorAttribute = computeAttributeFromFaceData( triangulatedCoordIndex, triangulatedFaceColors );
  1039. }
  1040. }
  1041. }
  1042. if ( normal ) {
  1043. if ( normalPerVertex === true ) {
  1044. // consider vertex normals
  1045. if ( normalIndex && normalIndex.length > 0 ) {
  1046. // if the normalIndex field is not empty, then it is used to choose normals for each vertex of the IndexedFaceSet.
  1047. var triangulatedNormalIndex = triangulateFaceIndex( normalIndex, ccw );
  1048. normalAttribute = computeAttributeFromIndexedData( triangulatedCoordIndex, triangulatedNormalIndex, normal, 3 );
  1049. } else {
  1050. // if the normalIndex field is empty, then the coordIndex field is used to choose normals from the Normal node
  1051. normalAttribute = toNonIndexedAttribute( triangulatedCoordIndex, new THREE.Float32BufferAttribute( normal, 3 ) );
  1052. }
  1053. } else {
  1054. // consider face normals
  1055. if ( normalIndex && normalIndex.length > 0 ) {
  1056. // if the normalIndex field is not empty, then they are used to choose one normal for each face of the IndexedFaceSet
  1057. var flattenFaceNormals = flattenData( normal, normalIndex );
  1058. var triangulatedFaceNormals = triangulateFaceData( flattenFaceNormals, coordIndex );
  1059. normalAttribute = computeAttributeFromFaceData( triangulatedCoordIndex, triangulatedFaceNormals );
  1060. } else {
  1061. // if the normalIndex field is empty, then the normals are applied to each face of the IndexedFaceSet in order
  1062. var triangulatedFaceNormals = triangulateFaceData( normal, coordIndex );
  1063. normalAttribute = computeAttributeFromFaceData( triangulatedCoordIndex, triangulatedFaceNormals );
  1064. }
  1065. }
  1066. } else {
  1067. // if the normal field is NULL, then the loader should automatically generate normals, using creaseAngle to determine if and how normals are smoothed across shared vertices
  1068. normalAttribute = computeNormalAttribute( triangulatedCoordIndex, coord, creaseAngle );
  1069. }
  1070. if ( texCoord ) {
  1071. // texture coordinates are always defined on vertex level
  1072. if ( texCoordIndex && texCoordIndex.length > 0 ) {
  1073. // if the texCoordIndex field is not empty, then it is used to choose texture coordinates for each vertex of the IndexedFaceSet.
  1074. var triangulatedTexCoordIndex = triangulateFaceIndex( texCoordIndex, ccw );
  1075. uvAttribute = computeAttributeFromIndexedData( triangulatedCoordIndex, triangulatedTexCoordIndex, texCoord, 2 );
  1076. } else {
  1077. // if the texCoordIndex field is empty, then the coordIndex array is used to choose texture coordinates from the TextureCoordinate node
  1078. uvAttribute = toNonIndexedAttribute( triangulatedCoordIndex, new THREE.Float32BufferAttribute( texCoord, 2 ) );
  1079. }
  1080. }
  1081. var geometry = new THREE.BufferGeometry();
  1082. positionAttribute = toNonIndexedAttribute( triangulatedCoordIndex, new THREE.Float32BufferAttribute( coord, 3 ) );
  1083. geometry.setAttribute( 'position', positionAttribute );
  1084. geometry.setAttribute( 'normal', normalAttribute );
  1085. // optional attributes
  1086. if ( colorAttribute ) geometry.setAttribute( 'color', colorAttribute );
  1087. if ( uvAttribute ) geometry.setAttribute( 'uv', uvAttribute );
  1088. // "solid" influences the material so let's store it for later use
  1089. geometry._solid = solid;
  1090. geometry._type = 'mesh';
  1091. return geometry;
  1092. }
  1093. function buildIndexedLineSetNode( node ) {
  1094. var color, coord;
  1095. var colorIndex, coordIndex;
  1096. var colorPerVertex = true;
  1097. var fields = node.fields;
  1098. for ( var i = 0, l = fields.length; i < l; i ++ ) {
  1099. var field = fields[ i ];
  1100. var fieldName = field.name;
  1101. var fieldValues = field.values;
  1102. switch ( fieldName ) {
  1103. case 'color':
  1104. var colorNode = fieldValues[ 0 ];
  1105. if ( colorNode !== null ) {
  1106. color = getNode( colorNode );
  1107. }
  1108. break;
  1109. case 'coord':
  1110. var coordNode = fieldValues[ 0 ];
  1111. if ( coordNode !== null ) {
  1112. coord = getNode( coordNode );
  1113. }
  1114. break;
  1115. case 'colorIndex':
  1116. colorIndex = fieldValues;
  1117. break;
  1118. case 'colorPerVertex':
  1119. colorPerVertex = fieldValues[ 0 ];
  1120. break;
  1121. case 'coordIndex':
  1122. coordIndex = fieldValues;
  1123. break;
  1124. default:
  1125. console.warn( 'THREE.VRMLLoader: Unknown field:', fieldName );
  1126. break;
  1127. }
  1128. }
  1129. // build lines
  1130. var colorAttribute;
  1131. var expandedLineIndex = expandLineIndex( coordIndex ); // create an index for three.js's linesegment primitive
  1132. if ( color ) {
  1133. if ( colorPerVertex === true ) {
  1134. if ( colorIndex.length > 0 ) {
  1135. // if the colorIndex field is not empty, then one color is used for each polyline of the IndexedLineSet.
  1136. var expandedColorIndex = expandLineIndex( colorIndex ); // compute colors for each line segment (rendering primitve)
  1137. colorAttribute = computeAttributeFromIndexedData( expandedLineIndex, expandedColorIndex, color, 3 ); // compute data on vertex level
  1138. } else {
  1139. // if the colorIndex field is empty, then the colors are applied to each polyline of the IndexedLineSet in order.
  1140. colorAttribute = toNonIndexedAttribute( expandedLineIndex, new THREE.Float32BufferAttribute( color, 3 ) );
  1141. }
  1142. } else {
  1143. if ( colorIndex.length > 0 ) {
  1144. // if the colorIndex field is not empty, then colors are applied to each vertex of the IndexedLineSet
  1145. var flattenLineColors = flattenData( color, colorIndex ); // compute colors for each VRML primitve
  1146. var expandedLineColors = expandLineData( flattenLineColors, coordIndex ); // compute colors for each line segment (rendering primitve)
  1147. colorAttribute = computeAttributeFromLineData( expandedLineIndex, expandedLineColors ); // compute data on vertex level
  1148. } else {
  1149. // if the colorIndex field is empty, then the coordIndex field is used to choose colors from the Color node
  1150. var expandedLineColors = expandLineData( color, coordIndex ); // compute colors for each line segment (rendering primitve)
  1151. colorAttribute = computeAttributeFromLineData( expandedLineIndex, expandedLineColors ); // compute data on vertex level
  1152. }
  1153. }
  1154. }
  1155. //
  1156. var geometry = new THREE.BufferGeometry();
  1157. var positionAttribute = toNonIndexedAttribute( expandedLineIndex, new THREE.Float32BufferAttribute( coord, 3 ) );
  1158. geometry.setAttribute( 'position', positionAttribute );
  1159. if ( colorAttribute ) geometry.setAttribute( 'color', colorAttribute );
  1160. geometry._type = 'line';
  1161. return geometry;
  1162. }
  1163. function buildPointSetNode( node ) {
  1164. var geometry;
  1165. var color, coord;
  1166. var fields = node.fields;
  1167. for ( var i = 0, l = fields.length; i < l; i ++ ) {
  1168. var field = fields[ i ];
  1169. var fieldName = field.name;
  1170. var fieldValues = field.values;
  1171. switch ( fieldName ) {
  1172. case 'color':
  1173. var colorNode = fieldValues[ 0 ];
  1174. if ( colorNode !== null ) {
  1175. color = getNode( colorNode );
  1176. }
  1177. break;
  1178. case 'coord':
  1179. var coordNode = fieldValues[ 0 ];
  1180. if ( coordNode !== null ) {
  1181. coord = getNode( coordNode );
  1182. }
  1183. break;
  1184. default:
  1185. console.warn( 'THREE.VRMLLoader: Unknown field:', fieldName );
  1186. break;
  1187. }
  1188. }
  1189. var geometry = new THREE.BufferGeometry();
  1190. geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( coord, 3 ) );
  1191. if ( color ) geometry.setAttribute( 'color', new THREE.Float32BufferAttribute( color, 3 ) );
  1192. geometry._type = 'points';
  1193. return geometry;
  1194. }
  1195. function buildBoxNode( node ) {
  1196. var size = new THREE.Vector3( 2, 2, 2 );
  1197. var fields = node.fields;
  1198. for ( var i = 0, l = fields.length; i < l; i ++ ) {
  1199. var field = fields[ i ];
  1200. var fieldName = field.name;
  1201. var fieldValues = field.values;
  1202. switch ( fieldName ) {
  1203. case 'size':
  1204. size.x = fieldValues[ 0 ];
  1205. size.y = fieldValues[ 1 ];
  1206. size.z = fieldValues[ 2 ];
  1207. break;
  1208. default:
  1209. console.warn( 'THREE.VRMLLoader: Unknown field:', fieldName );
  1210. break;
  1211. }
  1212. }
  1213. var geometry = new THREE.BoxBufferGeometry( size.x, size.y, size.z );
  1214. return geometry;
  1215. }
  1216. function buildConeNode( node ) {
  1217. var radius = 1, height = 2, openEnded = false;
  1218. var fields = node.fields;
  1219. for ( var i = 0, l = fields.length; i < l; i ++ ) {
  1220. var field = fields[ i ];
  1221. var fieldName = field.name;
  1222. var fieldValues = field.values;
  1223. switch ( fieldName ) {
  1224. case 'bottom':
  1225. openEnded = ! fieldValues[ 0 ];
  1226. break;
  1227. case 'bottomRadius':
  1228. radius = fieldValues[ 0 ];
  1229. break;
  1230. case 'height':
  1231. height = fieldValues[ 0 ];
  1232. break;
  1233. case 'side':
  1234. // field not supported
  1235. break;
  1236. default:
  1237. console.warn( 'THREE.VRMLLoader: Unknown field:', fieldName );
  1238. break;
  1239. }
  1240. }
  1241. var geometry = new THREE.ConeBufferGeometry( radius, height, 16, 1, openEnded );
  1242. return geometry;
  1243. }
  1244. function buildCylinderNode( node ) {
  1245. var radius = 1, height = 2;
  1246. var fields = node.fields;
  1247. for ( var i = 0, l = fields.length; i < l; i ++ ) {
  1248. var field = fields[ i ];
  1249. var fieldName = field.name;
  1250. var fieldValues = field.values;
  1251. switch ( fieldName ) {
  1252. case 'bottom':
  1253. // field not supported
  1254. break;
  1255. case 'radius':
  1256. radius = fieldValues[ 0 ];
  1257. break;
  1258. case 'height':
  1259. height = fieldValues[ 0 ];
  1260. break;
  1261. case 'side':
  1262. // field not supported
  1263. break;
  1264. case 'top':
  1265. // field not supported
  1266. break;
  1267. default:
  1268. console.warn( 'THREE.VRMLLoader: Unknown field:', fieldName );
  1269. break;
  1270. }
  1271. }
  1272. var geometry = new THREE.CylinderBufferGeometry( radius, radius, height, 16, 1 );
  1273. return geometry;
  1274. }
  1275. function buildSphereNode( node ) {
  1276. var radius = 1;
  1277. var fields = node.fields;
  1278. for ( var i = 0, l = fields.length; i < l; i ++ ) {
  1279. var field = fields[ i ];
  1280. var fieldName = field.name;
  1281. var fieldValues = field.values;
  1282. switch ( fieldName ) {
  1283. case 'radius':
  1284. radius = fieldValues[ 0 ];
  1285. break;
  1286. default:
  1287. console.warn( 'THREE.VRMLLoader: Unknown field:', fieldName );
  1288. break;
  1289. }
  1290. }
  1291. var geometry = new THREE.SphereBufferGeometry( radius, 16, 16 );
  1292. return geometry;
  1293. }
  1294. function buildElevationGridNode( node ) {
  1295. var color;
  1296. var normal;
  1297. var texCoord;
  1298. var height;
  1299. var colorPerVertex = true;
  1300. var normalPerVertex = true;
  1301. var solid = true;
  1302. var ccw = true;
  1303. var creaseAngle = 0;
  1304. var xDimension = 2;
  1305. var zDimension = 2;
  1306. var xSpacing = 1;
  1307. var zSpacing = 1;
  1308. var fields = node.fields;
  1309. for ( var i = 0, l = fields.length; i < l; i ++ ) {
  1310. var field = fields[ i ];
  1311. var fieldName = field.name;
  1312. var fieldValues = field.values;
  1313. switch ( fieldName ) {
  1314. case 'color':
  1315. var colorNode = fieldValues[ 0 ];
  1316. if ( colorNode !== null ) {
  1317. color = getNode( colorNode );
  1318. }
  1319. break;
  1320. case 'normal':
  1321. var normalNode = fieldValues[ 0 ];
  1322. if ( normalNode !== null ) {
  1323. normal = getNode( normalNode );
  1324. }
  1325. break;
  1326. case 'texCoord':
  1327. var texCoordNode = fieldValues[ 0 ];
  1328. if ( texCoordNode !== null ) {
  1329. texCoord = getNode( texCoordNode );
  1330. }
  1331. break;
  1332. case 'height':
  1333. height = fieldValues;
  1334. break;
  1335. case 'ccw':
  1336. ccw = fieldValues[ 0 ];
  1337. break;
  1338. case 'colorPerVertex':
  1339. colorPerVertex = fieldValues[ 0 ];
  1340. break;
  1341. case 'creaseAngle':
  1342. creaseAngle = fieldValues[ 0 ];
  1343. break;
  1344. case 'normalPerVertex':
  1345. normalPerVertex = fieldValues[ 0 ];
  1346. break;
  1347. case 'solid':
  1348. solid = fieldValues[ 0 ];
  1349. break;
  1350. case 'xDimension':
  1351. xDimension = fieldValues[ 0 ];
  1352. break;
  1353. case 'xSpacing':
  1354. xSpacing = fieldValues[ 0 ];
  1355. break;
  1356. case 'zDimension':
  1357. zDimension = fieldValues[ 0 ];
  1358. break;
  1359. case 'zSpacing':
  1360. zSpacing = fieldValues[ 0 ];
  1361. break;
  1362. default:
  1363. console.warn( 'THREE.VRMLLoader: Unknown field:', fieldName );
  1364. break;
  1365. }
  1366. }
  1367. // vertex data
  1368. var vertices = [];
  1369. var normals = [];
  1370. var colors = [];
  1371. var uvs = [];
  1372. for ( var i = 0; i < zDimension; i ++ ) {
  1373. for ( var j = 0; j < xDimension; j ++ ) {
  1374. // compute a row major index
  1375. var index = ( i * xDimension ) + j;
  1376. // vertices
  1377. var x = xSpacing * i;
  1378. var y = height[ index ];
  1379. var z = zSpacing * j;
  1380. vertices.push( x, y, z );
  1381. // colors
  1382. if ( color && colorPerVertex === true ) {
  1383. var r = color[ index * 3 + 0 ];
  1384. var g = color[ index * 3 + 1 ];
  1385. var b = color[ index * 3 + 2 ];
  1386. colors.push( r, g, b );
  1387. }
  1388. // normals
  1389. if ( normal && normalPerVertex === true ) {
  1390. var xn = normal[ index * 3 + 0 ];
  1391. var yn = normal[ index * 3 + 1 ];
  1392. var zn = normal[ index * 3 + 2 ];
  1393. normals.push( xn, yn, zn );
  1394. }
  1395. // uvs
  1396. if ( texCoord ) {
  1397. var s = texCoord[ index * 2 + 0 ];
  1398. var t = texCoord[ index * 2 + 1 ];
  1399. uvs.push( s, t );
  1400. } else {
  1401. uvs.push( i / ( xDimension - 1 ), j / ( zDimension - 1 ) );
  1402. }
  1403. }
  1404. }
  1405. // indices
  1406. var indices = [];
  1407. for ( var i = 0; i < xDimension - 1; i ++ ) {
  1408. for ( var j = 0; j < zDimension - 1; j ++ ) {
  1409. // from https://tecfa.unige.ch/guides/vrml/vrml97/spec/part1/nodesRef.html#ElevationGrid
  1410. var a = i + j * xDimension;
  1411. var b = i + ( j + 1 ) * xDimension;
  1412. var c = ( i + 1 ) + ( j + 1 ) * xDimension;
  1413. var d = ( i + 1 ) + j * xDimension;
  1414. // faces
  1415. if ( ccw === true ) {
  1416. indices.push( a, c, b );
  1417. indices.push( c, a, d );
  1418. } else {
  1419. indices.push( a, b, c );
  1420. indices.push( c, d, a );
  1421. }
  1422. }
  1423. }
  1424. //
  1425. var positionAttribute = toNonIndexedAttribute( indices, new THREE.Float32BufferAttribute( vertices, 3 ) );
  1426. var uvAttribute = toNonIndexedAttribute( indices, new THREE.Float32BufferAttribute( uvs, 2 ) );
  1427. var colorAttribute;
  1428. var normalAttribute;
  1429. // color attribute
  1430. if ( color ) {
  1431. if ( colorPerVertex === false ) {
  1432. for ( var i = 0; i < xDimension - 1; i ++ ) {
  1433. for ( var j = 0; j < zDimension - 1; j ++ ) {
  1434. var index = i + j * ( xDimension - 1 );
  1435. var r = color[ index * 3 + 0 ];
  1436. var g = color[ index * 3 + 1 ];
  1437. var b = color[ index * 3 + 2 ];
  1438. // one color per quad
  1439. colors.push( r, g, b ); colors.push( r, g, b ); colors.push( r, g, b );
  1440. colors.push( r, g, b ); colors.push( r, g, b ); colors.push( r, g, b );
  1441. }
  1442. }
  1443. colorAttribute = new THREE.Float32BufferAttribute( colors, 3 );
  1444. } else {
  1445. colorAttribute = toNonIndexedAttribute( indices, new THREE.Float32BufferAttribute( colors, 3 ) );
  1446. }
  1447. }
  1448. // normal attribute
  1449. if ( normal ) {
  1450. if ( normalPerVertex === false ) {
  1451. for ( var i = 0; i < xDimension - 1; i ++ ) {
  1452. for ( var j = 0; j < zDimension - 1; j ++ ) {
  1453. var index = i + j * ( xDimension - 1 );
  1454. var xn = normal[ index * 3 + 0 ];
  1455. var yn = normal[ index * 3 + 1 ];
  1456. var zn = normal[ index * 3 + 2 ];
  1457. // one normal per quad
  1458. normals.push( xn, yn, zn ); normals.push( xn, yn, zn ); normals.push( xn, yn, zn );
  1459. normals.push( xn, yn, zn ); normals.push( xn, yn, zn ); normals.push( xn, yn, zn );
  1460. }
  1461. }
  1462. normalAttribute = new THREE.Float32BufferAttribute( normals, 3 );
  1463. } else {
  1464. normalAttribute = toNonIndexedAttribute( indices, new THREE.Float32BufferAttribute( normals, 3 ) );
  1465. }
  1466. } else {
  1467. normalAttribute = computeNormalAttribute( indices, vertices, creaseAngle );
  1468. }
  1469. // build geometry
  1470. var geometry = new THREE.BufferGeometry();
  1471. geometry.setAttribute( 'position', positionAttribute );
  1472. geometry.setAttribute( 'normal', normalAttribute );
  1473. geometry.setAttribute( 'uv', uvAttribute );
  1474. if ( colorAttribute ) geometry.setAttribute( 'color', colorAttribute );
  1475. // "solid" influences the material so let's store it for later use
  1476. geometry._solid = solid;
  1477. geometry._type = 'mesh';
  1478. return geometry;
  1479. }
  1480. function buildExtrusionNode( node ) {
  1481. var crossSection = [ 1, 1, 1, - 1, - 1, - 1, - 1, 1, 1, 1 ];
  1482. var spine = [ 0, 0, 0, 0, 1, 0 ];
  1483. var scale;
  1484. var orientation;
  1485. var beginCap = true;
  1486. var ccw = true;
  1487. var creaseAngle = 0;
  1488. var endCap = true;
  1489. var solid = true;
  1490. var fields = node.fields;
  1491. for ( var i = 0, l = fields.length; i < l; i ++ ) {
  1492. var field = fields[ i ];
  1493. var fieldName = field.name;
  1494. var fieldValues = field.values;
  1495. switch ( fieldName ) {
  1496. case 'beginCap':
  1497. beginCap = fieldValues[ 0 ];
  1498. break;
  1499. case 'ccw':
  1500. ccw = fieldValues[ 0 ];
  1501. break;
  1502. case 'convex':
  1503. // field not supported
  1504. break;
  1505. case 'creaseAngle':
  1506. creaseAngle = fieldValues[ 0 ];
  1507. break;
  1508. case 'crossSection':
  1509. crossSection = fieldValues;
  1510. break;
  1511. case 'endCap':
  1512. endCap = fieldValues[ 0 ];
  1513. break;
  1514. case 'orientation':
  1515. orientation = fieldValues;
  1516. break;
  1517. case 'scale':
  1518. scale = fieldValues;
  1519. break;
  1520. case 'solid':
  1521. solid = fieldValues[ 0 ];
  1522. break;
  1523. case 'spine':
  1524. spine = fieldValues; // only extrusion along the Y-axis are supported so far
  1525. break;
  1526. default:
  1527. console.warn( 'THREE.VRMLLoader: Unknown field:', fieldName );
  1528. break;
  1529. }
  1530. }
  1531. var crossSectionClosed = ( crossSection[ 0 ] === crossSection[ crossSection.length - 2 ] && crossSection[ 1 ] === crossSection[ crossSection.length - 1 ] );
  1532. // vertices
  1533. var vertices = [];
  1534. var spineVector = new THREE.Vector3();
  1535. var scaling = new THREE.Vector3();
  1536. var axis = new THREE.Vector3();
  1537. var vertex = new THREE.Vector3();
  1538. var quaternion = new THREE.Quaternion();
  1539. for ( var i = 0, j = 0, o = 0, il = spine.length; i < il; i += 3, j += 2, o += 4 ) {
  1540. spineVector.fromArray( spine, i );
  1541. scaling.x = scale ? scale[ j + 0 ] : 1;
  1542. scaling.y = 1;
  1543. scaling.z = scale ? scale[ j + 1 ] : 1;
  1544. axis.x = orientation ? orientation[ o + 0 ] : 0;
  1545. axis.y = orientation ? orientation[ o + 1 ] : 0;
  1546. axis.z = orientation ? orientation[ o + 2 ] : 1;
  1547. var angle = orientation ? orientation[ o + 3 ] : 0;
  1548. for ( var k = 0, kl = crossSection.length; k < kl; k += 2 ) {
  1549. vertex.x = crossSection[ k + 0 ];
  1550. vertex.y = 0;
  1551. vertex.z = crossSection[ k + 1 ];
  1552. // scale
  1553. vertex.multiply( scaling );
  1554. // rotate
  1555. quaternion.setFromAxisAngle( axis, angle );
  1556. vertex.applyQuaternion( quaternion );
  1557. // translate
  1558. vertex.add( spineVector );
  1559. vertices.push( vertex.x, vertex.y, vertex.z );
  1560. }
  1561. }
  1562. // indices
  1563. var indices = [];
  1564. var spineCount = spine.length / 3;
  1565. var crossSectionCount = crossSection.length / 2;
  1566. for ( var i = 0; i < spineCount - 1; i ++ ) {
  1567. for ( var j = 0; j < crossSectionCount - 1; j ++ ) {
  1568. var a = j + i * crossSectionCount;
  1569. var b = ( j + 1 ) + i * crossSectionCount;
  1570. var c = j + ( i + 1 ) * crossSectionCount;
  1571. var d = ( j + 1 ) + ( i + 1 ) * crossSectionCount;
  1572. if ( ( j === crossSectionCount - 2 ) && ( crossSectionClosed === true ) ) {
  1573. b = i * crossSectionCount;
  1574. d = ( i + 1 ) * crossSectionCount;
  1575. }
  1576. if ( ccw === true ) {
  1577. indices.push( a, b, c );
  1578. indices.push( c, b, d );
  1579. } else {
  1580. indices.push( a, c, b );
  1581. indices.push( c, d, b );
  1582. }
  1583. }
  1584. }
  1585. // triangulate cap
  1586. if ( beginCap === true || endCap === true ) {
  1587. var contour = [];
  1588. for ( var i = 0, l = crossSection.length; i < l; i += 2 ) {
  1589. contour.push( new THREE.Vector2( crossSection[ i ], crossSection[ i + 1 ] ) );
  1590. }
  1591. var faces = THREE.ShapeUtils.triangulateShape( contour, [] );
  1592. var capIndices = [];
  1593. for ( var i = 0, l = faces.length; i < l; i ++ ) {
  1594. var face = faces[ i ];
  1595. capIndices.push( face[ 0 ], face[ 1 ], face[ 2 ] );
  1596. }
  1597. // begin cap
  1598. if ( beginCap === true ) {
  1599. for ( var i = 0, l = capIndices.length; i < l; i += 3 ) {
  1600. if ( ccw === true ) {
  1601. indices.push( capIndices[ i + 0 ], capIndices[ i + 1 ], capIndices[ i + 2 ] );
  1602. } else {
  1603. indices.push( capIndices[ i + 0 ], capIndices[ i + 2 ], capIndices[ i + 1 ] );
  1604. }
  1605. }
  1606. }
  1607. // end cap
  1608. if ( endCap === true ) {
  1609. var indexOffset = crossSectionCount * ( spineCount - 1 ); // references to the first vertex of the last cross section
  1610. for ( var i = 0, l = capIndices.length; i < l; i += 3 ) {
  1611. if ( ccw === true ) {
  1612. indices.push( indexOffset + capIndices[ i + 0 ], indexOffset + capIndices[ i + 2 ], indexOffset + capIndices[ i + 1 ] );
  1613. } else {
  1614. indices.push( indexOffset + capIndices[ i + 0 ], indexOffset + capIndices[ i + 1 ], indexOffset + capIndices[ i + 2 ] );
  1615. }
  1616. }
  1617. }
  1618. }
  1619. var positionAttribute = toNonIndexedAttribute( indices, new THREE.Float32BufferAttribute( vertices, 3 ) );
  1620. var normalAttribute = computeNormalAttribute( indices, vertices, creaseAngle );
  1621. var geometry = new THREE.BufferGeometry();
  1622. geometry.setAttribute( 'position', positionAttribute );
  1623. geometry.setAttribute( 'normal', normalAttribute );
  1624. // no uvs yet
  1625. // "solid" influences the material so let's store it for later use
  1626. geometry._solid = solid;
  1627. geometry._type = 'mesh';
  1628. return geometry;
  1629. }
  1630. // helper functions
  1631. function resolveUSE( identifier ) {
  1632. var node = nodeMap[ identifier ];
  1633. var build = getNode( node );
  1634. // because the same 3D objects can have different transformations, it's necessary to clone them.
  1635. // materials can be influenced by the geometry (e.g. vertex normals). cloning is necessary to avoid
  1636. // any side effects
  1637. return ( build.isObject3D || build.isMaterial ) ? build.clone() : build;
  1638. }
  1639. function parseFieldChildren( children, owner ) {
  1640. for ( var i = 0, l = children.length; i < l; i ++ ) {
  1641. var object = getNode( children[ i ] );
  1642. if ( object instanceof THREE.Object3D ) owner.add( object );
  1643. }
  1644. }
  1645. function triangulateFaceIndex( index, ccw ) {
  1646. var indices = [];
  1647. // since face defintions can have more than three vertices, it's necessary to
  1648. // perform a simple triangulation
  1649. var start = 0;
  1650. for ( var i = 0, l = index.length; i < l; i ++ ) {
  1651. var i1 = index[ start ];
  1652. var i2 = index[ i + ( ccw ? 1 : 2 ) ];
  1653. var i3 = index[ i + ( ccw ? 2 : 1 ) ];
  1654. indices.push( i1, i2, i3 );
  1655. // an index of -1 indicates that the current face has ended and the next one begins
  1656. if ( index[ i + 3 ] === - 1 || i + 3 >= l ) {
  1657. i += 3;
  1658. start = i + 1;
  1659. }
  1660. }
  1661. return indices;
  1662. }
  1663. function triangulateFaceData( data, index ) {
  1664. var triangulatedData = [];
  1665. var start = 0;
  1666. for ( var i = 0, l = index.length; i < l; i ++ ) {
  1667. var stride = start * 3;
  1668. var x = data[ stride ];
  1669. var y = data[ stride + 1 ];
  1670. var z = data[ stride + 2 ];
  1671. triangulatedData.push( x, y, z );
  1672. // an index of -1 indicates that the current face has ended and the next one begins
  1673. if ( index[ i + 3 ] === - 1 || i + 3 >= l ) {
  1674. i += 3;
  1675. start ++;
  1676. }
  1677. }
  1678. return triangulatedData;
  1679. }
  1680. function flattenData( data, index ) {
  1681. var flattenData = [];
  1682. for ( var i = 0, l = index.length; i < l; i ++ ) {
  1683. var i1 = index[ i ];
  1684. var stride = i1 * 3;
  1685. var x = data[ stride ];
  1686. var y = data[ stride + 1 ];
  1687. var z = data[ stride + 2 ];
  1688. flattenData.push( x, y, z );
  1689. }
  1690. return flattenData;
  1691. }
  1692. function expandLineIndex( index ) {
  1693. var indices = [];
  1694. for ( var i = 0, l = index.length; i < l; i ++ ) {
  1695. var i1 = index[ i ];
  1696. var i2 = index[ i + 1 ];
  1697. indices.push( i1, i2 );
  1698. // an index of -1 indicates that the current line has ended and the next one begins
  1699. if ( index[ i + 2 ] === - 1 || i + 2 >= l ) {
  1700. i += 2;
  1701. }
  1702. }
  1703. return indices;
  1704. }
  1705. function expandLineData( data, index ) {
  1706. var triangulatedData = [];
  1707. var start = 0;
  1708. for ( var i = 0, l = index.length; i < l; i ++ ) {
  1709. var stride = start * 3;
  1710. var x = data[ stride ];
  1711. var y = data[ stride + 1 ];
  1712. var z = data[ stride + 2 ];
  1713. triangulatedData.push( x, y, z );
  1714. // an index of -1 indicates that the current line has ended and the next one begins
  1715. if ( index[ i + 2 ] === - 1 || i + 2 >= l ) {
  1716. i += 2;
  1717. start ++;
  1718. }
  1719. }
  1720. return triangulatedData;
  1721. }
  1722. var vA = new THREE.Vector3();
  1723. var vB = new THREE.Vector3();
  1724. var vC = new THREE.Vector3();
  1725. var uvA = new THREE.Vector2();
  1726. var uvB = new THREE.Vector2();
  1727. var uvC = new THREE.Vector2();
  1728. function computeAttributeFromIndexedData( coordIndex, index, data, itemSize ) {
  1729. var array = [];
  1730. // we use the coordIndex.length as delimiter since normalIndex must contain at least as many indices
  1731. for ( var i = 0, l = coordIndex.length; i < l; i += 3 ) {
  1732. var a = index[ i ];
  1733. var b = index[ i + 1 ];
  1734. var c = index[ i + 2 ];
  1735. if ( itemSize === 2 ) {
  1736. uvA.fromArray( data, a * itemSize );
  1737. uvB.fromArray( data, b * itemSize );
  1738. uvC.fromArray( data, c * itemSize );
  1739. array.push( uvA.x, uvA.y );
  1740. array.push( uvB.x, uvB.y );
  1741. array.push( uvC.x, uvC.y );
  1742. } else {
  1743. vA.fromArray( data, a * itemSize );
  1744. vB.fromArray( data, b * itemSize );
  1745. vC.fromArray( data, c * itemSize );
  1746. array.push( vA.x, vA.y, vA.z );
  1747. array.push( vB.x, vB.y, vB.z );
  1748. array.push( vC.x, vC.y, vC.z );
  1749. }
  1750. }
  1751. return new THREE.Float32BufferAttribute( array, itemSize );
  1752. }
  1753. function computeAttributeFromFaceData( index, faceData ) {
  1754. var array = [];
  1755. for ( var i = 0, j = 0, l = index.length; i < l; i += 3, j ++ ) {
  1756. vA.fromArray( faceData, j * 3 );
  1757. array.push( vA.x, vA.y, vA.z );
  1758. array.push( vA.x, vA.y, vA.z );
  1759. array.push( vA.x, vA.y, vA.z );
  1760. }
  1761. return new THREE.Float32BufferAttribute( array, 3 );
  1762. }
  1763. function computeAttributeFromLineData( index, lineData ) {
  1764. var array = [];
  1765. for ( var i = 0, j = 0, l = index.length; i < l; i += 2, j ++ ) {
  1766. vA.fromArray( lineData, j * 3 );
  1767. array.push( vA.x, vA.y, vA.z );
  1768. array.push( vA.x, vA.y, vA.z );
  1769. }
  1770. return new THREE.Float32BufferAttribute( array, 3 );
  1771. }
  1772. function toNonIndexedAttribute( indices, attribute ) {
  1773. var array = attribute.array;
  1774. var itemSize = attribute.itemSize;
  1775. var array2 = new array.constructor( indices.length * itemSize );
  1776. var index = 0, index2 = 0;
  1777. for ( var i = 0, l = indices.length; i < l; i ++ ) {
  1778. index = indices[ i ] * itemSize;
  1779. for ( var j = 0; j < itemSize; j ++ ) {
  1780. array2[ index2 ++ ] = array[ index ++ ];
  1781. }
  1782. }
  1783. return new THREE.Float32BufferAttribute( array2, itemSize );
  1784. }
  1785. var ab = new THREE.Vector3();
  1786. var cb = new THREE.Vector3();
  1787. function computeNormalAttribute( index, coord, creaseAngle ) {
  1788. var faces = [];
  1789. var vertexNormals = {};
  1790. // prepare face and raw vertex normals
  1791. for ( var i = 0, l = index.length; i < l; i += 3 ) {
  1792. var a = index[ i ];
  1793. var b = index[ i + 1 ];
  1794. var c = index[ i + 2 ];
  1795. var face = new Face( a, b, c );
  1796. vA.fromArray( coord, a * 3 );
  1797. vB.fromArray( coord, b * 3 );
  1798. vC.fromArray( coord, c * 3 );
  1799. cb.subVectors( vC, vB );
  1800. ab.subVectors( vA, vB );
  1801. cb.cross( ab );
  1802. cb.normalize();
  1803. face.normal.copy( cb );
  1804. if ( vertexNormals[ a ] === undefined ) vertexNormals[ a ] = [];
  1805. if ( vertexNormals[ b ] === undefined ) vertexNormals[ b ] = [];
  1806. if ( vertexNormals[ c ] === undefined ) vertexNormals[ c ] = [];
  1807. vertexNormals[ a ].push( face.normal );
  1808. vertexNormals[ b ].push( face.normal );
  1809. vertexNormals[ c ].push( face.normal );
  1810. faces.push( face );
  1811. }
  1812. // compute vertex normals and build final geometry
  1813. var normals = [];
  1814. for ( var i = 0, l = faces.length; i < l; i ++ ) {
  1815. var face = faces[ i ];
  1816. var nA = weightedNormal( vertexNormals[ face.a ], face.normal, creaseAngle );
  1817. var nB = weightedNormal( vertexNormals[ face.b ], face.normal, creaseAngle );
  1818. var nC = weightedNormal( vertexNormals[ face.c ], face.normal, creaseAngle );
  1819. vA.fromArray( coord, face.a * 3 );
  1820. vB.fromArray( coord, face.b * 3 );
  1821. vC.fromArray( coord, face.c * 3 );
  1822. normals.push( nA.x, nA.y, nA.z );
  1823. normals.push( nB.x, nB.y, nB.z );
  1824. normals.push( nC.x, nC.y, nC.z );
  1825. }
  1826. return new THREE.Float32BufferAttribute( normals, 3 );
  1827. }
  1828. function weightedNormal( normals, vector, creaseAngle ) {
  1829. var normal = new THREE.Vector3();
  1830. if ( creaseAngle === 0 ) {
  1831. normal.copy( vector );
  1832. } else {
  1833. for ( var i = 0, l = normals.length; i < l; i ++ ) {
  1834. if ( normals[ i ].angleTo( vector ) < creaseAngle ) {
  1835. normal.add( normals[ i ] );
  1836. }
  1837. }
  1838. }
  1839. return normal.normalize();
  1840. }
  1841. function toColorArray( colors ) {
  1842. var array = [];
  1843. for ( var i = 0, l = colors.length; i < l; i += 3 ) {
  1844. array.push( new THREE.Color( colors[ i ], colors[ i + 1 ], colors[ i + 2 ] ) );
  1845. }
  1846. return array;
  1847. }
  1848. /**
  1849. * Vertically paints the faces interpolating between the
  1850. * specified colors at the specified angels. This is used for the Background
  1851. * node, but could be applied to other nodes with multiple faces as well.
  1852. *
  1853. * When used with the Background node, default is directionIsDown is true if
  1854. * interpolating the skyColor down from the Zenith. When interpolationg up from
  1855. * the Nadir i.e. interpolating the groundColor, the directionIsDown is false.
  1856. *
  1857. * The first angle is never specified, it is the Zenith (0 rad). Angles are specified
  1858. * in radians. The geometry is thought a sphere, but could be anything. The color interpolation
  1859. * is linear along the Y axis in any case.
  1860. *
  1861. * You must specify one more color than you have angles at the beginning of the colors array.
  1862. * This is the color of the Zenith (the top of the shape).
  1863. *
  1864. * @param {BufferGeometry} geometry
  1865. * @param {number} radius
  1866. * @param {array} angles
  1867. * @param {array} colors
  1868. * @param {boolean} topDown - Whether to work top down or bottom up.
  1869. */
  1870. function paintFaces( geometry, radius, angles, colors, topDown ) {
  1871. // compute threshold values
  1872. var thresholds = [];
  1873. var startAngle = ( topDown === true ) ? 0 : Math.PI;
  1874. for ( var i = 0, l = colors.length; i < l; i ++ ) {
  1875. var angle = ( i === 0 ) ? 0 : angles[ i - 1 ];
  1876. angle = ( topDown === true ) ? angle : ( startAngle - angle );
  1877. var point = new THREE.Vector3();
  1878. point.setFromSphericalCoords( radius, angle, 0 );
  1879. thresholds.push( point );
  1880. }
  1881. // generate vertex colors
  1882. var indices = geometry.index;
  1883. var positionAttribute = geometry.attributes.position;
  1884. var colorAttribute = new THREE.BufferAttribute( new Float32Array( geometry.attributes.position.count * 3 ), 3 );
  1885. var position = new THREE.Vector3();
  1886. var color = new THREE.Color();
  1887. for ( var i = 0; i < indices.count; i ++ ) {
  1888. var index = indices.getX( i );
  1889. position.fromBufferAttribute( positionAttribute, index );
  1890. var thresholdIndexA, thresholdIndexB;
  1891. var t = 1;
  1892. for ( var j = 1; j < thresholds.length; j ++ ) {
  1893. thresholdIndexA = j - 1;
  1894. thresholdIndexB = j;
  1895. var thresholdA = thresholds[ thresholdIndexA ];
  1896. var thresholdB = thresholds[ thresholdIndexB ];
  1897. if ( topDown === true ) {
  1898. // interpolation for sky color
  1899. if ( position.y <= thresholdA.y && position.y > thresholdB.y ) {
  1900. t = Math.abs( thresholdA.y - position.y ) / Math.abs( thresholdA.y - thresholdB.y );
  1901. break;
  1902. }
  1903. } else {
  1904. // interpolation for ground color
  1905. if ( position.y >= thresholdA.y && position.y < thresholdB.y ) {
  1906. t = Math.abs( thresholdA.y - position.y ) / Math.abs( thresholdA.y - thresholdB.y );
  1907. break;
  1908. }
  1909. }
  1910. }
  1911. var colorA = colors[ thresholdIndexA ];
  1912. var colorB = colors[ thresholdIndexB ];
  1913. color.copy( colorA ).lerp( colorB, t );
  1914. colorAttribute.setXYZ( index, color.r, color.g, color.b );
  1915. }
  1916. geometry.setAttribute( 'color', colorAttribute );
  1917. }
  1918. //
  1919. var textureLoader = new THREE.TextureLoader( this.manager );
  1920. textureLoader.setPath( this.resourcePath || path ).setCrossOrigin( this.crossOrigin );
  1921. // check version (only 2.0 is supported)
  1922. if ( data.indexOf( '#VRML V2.0' ) === - 1 ) {
  1923. throw Error( 'THREE.VRMLLexer: Version of VRML asset not supported.' );
  1924. }
  1925. // create JSON representing the tree structure of the VRML asset
  1926. var tree = generateVRMLTree( data );
  1927. // parse the tree structure to a three.js scene
  1928. var scene = parseTree( tree );
  1929. return scene;
  1930. }
  1931. } );
  1932. function VRMLLexer( tokens ) {
  1933. this.lexer = new chevrotain.Lexer( tokens ); // eslint-disable-line no-undef
  1934. }
  1935. VRMLLexer.prototype = {
  1936. constructor: VRMLLexer,
  1937. lex: function ( inputText ) {
  1938. var lexingResult = this.lexer.tokenize( inputText );
  1939. if ( lexingResult.errors.length > 0 ) {
  1940. console.error( lexingResult.errors );
  1941. throw Error( 'THREE.VRMLLexer: Lexing errors detected.' );
  1942. }
  1943. return lexingResult;
  1944. }
  1945. };
  1946. function VRMLParser( tokenVocabulary ) {
  1947. chevrotain.Parser.call( this, tokenVocabulary ); // eslint-disable-line no-undef
  1948. var $ = this;
  1949. var Version = tokenVocabulary[ 'Version' ];
  1950. var LCurly = tokenVocabulary[ 'LCurly' ];
  1951. var RCurly = tokenVocabulary[ 'RCurly' ];
  1952. var LSquare = tokenVocabulary[ 'LSquare' ];
  1953. var RSquare = tokenVocabulary[ 'RSquare' ];
  1954. var Identifier = tokenVocabulary[ 'Identifier' ];
  1955. var RouteIdentifier = tokenVocabulary[ 'RouteIdentifier' ];
  1956. var StringLiteral = tokenVocabulary[ 'StringLiteral' ];
  1957. var HexLiteral = tokenVocabulary[ 'HexLiteral' ];
  1958. var NumberLiteral = tokenVocabulary[ 'NumberLiteral' ];
  1959. var TrueLiteral = tokenVocabulary[ 'TrueLiteral' ];
  1960. var FalseLiteral = tokenVocabulary[ 'FalseLiteral' ];
  1961. var NullLiteral = tokenVocabulary[ 'NullLiteral' ];
  1962. var DEF = tokenVocabulary[ 'DEF' ];
  1963. var USE = tokenVocabulary[ 'USE' ];
  1964. var ROUTE = tokenVocabulary[ 'ROUTE' ];
  1965. var TO = tokenVocabulary[ 'TO' ];
  1966. var NodeName = tokenVocabulary[ 'NodeName' ];
  1967. $.RULE( 'vrml', function () {
  1968. $.SUBRULE( $.version );
  1969. $.AT_LEAST_ONE( function () {
  1970. $.SUBRULE( $.node );
  1971. } );
  1972. $.MANY( function () {
  1973. $.SUBRULE( $.route );
  1974. } );
  1975. } );
  1976. $.RULE( 'version', function () {
  1977. $.CONSUME( Version );
  1978. } );
  1979. $.RULE( 'node', function () {
  1980. $.OPTION( function () {
  1981. $.SUBRULE( $.def );
  1982. } );
  1983. $.CONSUME( NodeName );
  1984. $.CONSUME( LCurly );
  1985. $.MANY( function () {
  1986. $.SUBRULE( $.field );
  1987. } );
  1988. $.CONSUME( RCurly );
  1989. } );
  1990. $.RULE( 'field', function () {
  1991. $.CONSUME( Identifier );
  1992. $.OR2( [
  1993. { ALT: function () {
  1994. $.SUBRULE( $.singleFieldValue );
  1995. } },
  1996. { ALT: function () {
  1997. $.SUBRULE( $.multiFieldValue );
  1998. } }
  1999. ] );
  2000. } );
  2001. $.RULE( 'def', function () {
  2002. $.CONSUME( DEF );
  2003. $.OR( [
  2004. { ALT: function () {
  2005. $.CONSUME( Identifier );
  2006. } },
  2007. { ALT: function () {
  2008. $.CONSUME( NodeName );
  2009. } }
  2010. ] );
  2011. } );
  2012. $.RULE( 'use', function () {
  2013. $.CONSUME( USE );
  2014. $.OR( [
  2015. { ALT: function () {
  2016. $.CONSUME( Identifier );
  2017. } },
  2018. { ALT: function () {
  2019. $.CONSUME( NodeName );
  2020. } }
  2021. ] );
  2022. } );
  2023. $.RULE( 'singleFieldValue', function () {
  2024. $.AT_LEAST_ONE( function () {
  2025. $.OR( [
  2026. { ALT: function () {
  2027. $.SUBRULE( $.node );
  2028. } },
  2029. { ALT: function () {
  2030. $.SUBRULE( $.use );
  2031. } },
  2032. { ALT: function () {
  2033. $.CONSUME( StringLiteral );
  2034. } },
  2035. { ALT: function () {
  2036. $.CONSUME( HexLiteral );
  2037. } },
  2038. { ALT: function () {
  2039. $.CONSUME( NumberLiteral );
  2040. } },
  2041. { ALT: function () {
  2042. $.CONSUME( TrueLiteral );
  2043. } },
  2044. { ALT: function () {
  2045. $.CONSUME( FalseLiteral );
  2046. } },
  2047. { ALT: function () {
  2048. $.CONSUME( NullLiteral );
  2049. } }
  2050. ] );
  2051. } );
  2052. } );
  2053. $.RULE( 'multiFieldValue', function () {
  2054. $.CONSUME( LSquare );
  2055. $.MANY( function () {
  2056. $.OR( [
  2057. { ALT: function () {
  2058. $.SUBRULE( $.node );
  2059. } },
  2060. { ALT: function () {
  2061. $.SUBRULE( $.use );
  2062. } },
  2063. { ALT: function () {
  2064. $.CONSUME( StringLiteral );
  2065. } },
  2066. { ALT: function () {
  2067. $.CONSUME( HexLiteral );
  2068. } },
  2069. { ALT: function () {
  2070. $.CONSUME( NumberLiteral );
  2071. } },
  2072. { ALT: function () {
  2073. $.CONSUME( NullLiteral );
  2074. } }
  2075. ] );
  2076. } );
  2077. $.CONSUME( RSquare );
  2078. } );
  2079. $.RULE( 'route', function () {
  2080. $.CONSUME( ROUTE );
  2081. $.CONSUME( RouteIdentifier );
  2082. $.CONSUME( TO );
  2083. $.CONSUME2( RouteIdentifier );
  2084. } );
  2085. this.performSelfAnalysis();
  2086. }
  2087. VRMLParser.prototype = Object.create( chevrotain.Parser.prototype ); // eslint-disable-line no-undef
  2088. VRMLParser.prototype.constructor = VRMLParser;
  2089. function Face( a, b, c ) {
  2090. this.a = a;
  2091. this.b = b;
  2092. this.c = c;
  2093. this.normal = new THREE.Vector3();
  2094. }
  2095. var TEXTURE_TYPE = {
  2096. INTENSITY: 1,
  2097. INTENSITY_ALPHA: 2,
  2098. RGB: 3,
  2099. RGBA: 4
  2100. };
  2101. return VRMLLoader;
  2102. } )();