FileVRMLParser.pas 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923
  1. //
  2. // The unit is part of the GLScene Engine, http://glscene.org
  3. //
  4. unit FileVRMLParser;
  5. (* VRML file format parser. *)
  6. interface
  7. {$I GLScene.inc}
  8. uses
  9. System.Classes,
  10. System.SysUtils,
  11. GLVectorGeometry,
  12. GLVectorTypes,
  13. GLVectorLists,
  14. GLS.Utils;
  15. type
  16. TVRMLNode = class
  17. private
  18. FNodes: TList;
  19. FParent: TVRMLNode;
  20. FName, FDefName: String;
  21. function GetNode(index: Integer): TVRMLNode;
  22. public
  23. constructor Create; virtual;
  24. constructor CreateOwned(AParent: TVRMLNode);
  25. destructor Destroy; override;
  26. function Count: Integer;
  27. procedure Clear;
  28. procedure Add(node: TVRMLNode);
  29. procedure Remove(node: TVRMLNode);
  30. procedure Delete(index: Integer);
  31. property Nodes[index: Integer]: TVRMLNode read GetNode; default;
  32. property Parent: TVRMLNode read FParent;
  33. property Name: String read FName write FName;
  34. property DefName: String read FDefName write FDefName;
  35. end;
  36. TVRMLSingleArray = class(TVRMLNode)
  37. private
  38. FValues: TSingleList;
  39. public
  40. constructor Create; override;
  41. destructor Destroy; override;
  42. property Values: TSingleList read FValues;
  43. end;
  44. TVRMLIntegerArray = class(TVRMLNode)
  45. private
  46. FValues: TIntegerList;
  47. public
  48. constructor Create; override;
  49. destructor Destroy; override;
  50. property Values: TIntegerList read FValues;
  51. end;
  52. TVRMLMaterial = class(TVRMLNode)
  53. private
  54. FDiffuseColor, FAmbientColor, FSpecularColor, FEmissiveColor: TVector3f;
  55. FTransparency, FShininess: Single;
  56. FHasDiffuse, FHasAmbient, FHasSpecular, FHasEmissive, FHasTransparency,
  57. FHasShininess: Boolean;
  58. public
  59. constructor Create; override;
  60. property DiffuseColor: TVector3f read FDiffuseColor write FDiffuseColor;
  61. property AmbientColor: TVector3f read FAmbientColor write FAmbientColor;
  62. property SpecularColor: TVector3f read FSpecularColor write FSpecularColor;
  63. property EmissiveColor: TVector3f read FEmissiveColor write FEmissiveColor;
  64. property Transparency: Single read FTransparency write FTransparency;
  65. property Shininess: Single read FShininess write FShininess;
  66. property HasDiffuse: Boolean read FHasDiffuse write FHasDiffuse;
  67. property HasAmbient: Boolean read FHasAmbient write FHasAmbient;
  68. property HasSpecular: Boolean read FHasSpecular write FHasSpecular;
  69. property HasEmissive: Boolean read FHasEmissive write FHasEmissive;
  70. property HasTransparency: Boolean read FHasTransparency
  71. write FHasTransparency;
  72. property HasShininess: Boolean read FHasShininess write FHasShininess;
  73. end;
  74. TVRMLUse = class(TVRMLNode)
  75. private
  76. FValue: String;
  77. public
  78. property Value: String read FValue write FValue;
  79. end;
  80. TVRMLShapeHints = class(TVRMLNode)
  81. private
  82. FCreaseAngle: Single;
  83. public
  84. property CreaseAngle: Single read FCreaseAngle write FCreaseAngle;
  85. end;
  86. TVRMLTransform = class(TVRMLNode)
  87. private
  88. FCenter: TVector3f;
  89. FRotation: TVector4f;
  90. FScaleFactor: TVector3f;
  91. public
  92. constructor Create; override;
  93. property Center: TVector3f read FCenter write FCenter;
  94. property Rotation: TVector4f read FRotation write FRotation;
  95. property ScaleFactor: TVector3f read FScaleFactor write FScaleFactor;
  96. end;
  97. TVRMLParser = class
  98. private
  99. FCursor: Integer;
  100. FTokens: TStringList;
  101. FRootNode: TVRMLNode;
  102. FCurrentNode: TVRMLNode;
  103. FAllowUnknownNodes: Boolean;
  104. FDefines: TList;
  105. protected
  106. function ReadToken: String;
  107. function ReadSingle: Single;
  108. function ReadVector3f: TVector3f;
  109. function ReadVector4f: TVector4f;
  110. procedure ReadUnknownArray(DefName: String = '');
  111. procedure ReadUnknownHeirachy(DefName: String = '');
  112. procedure ReadUnknown(unknown_token: String; DefName: String = '');
  113. procedure ReadPointArray(DefName: String = '');
  114. procedure ReadCoordIndexArray(DefName: String = '');
  115. procedure ReadNormalIndexArray(DefName: String = '');
  116. procedure ReadTextureCoordIndexArray(DefName: String = '');
  117. procedure ReadCoordinate3(DefName: String = '');
  118. procedure ReadNormal(DefName: String = '');
  119. procedure ReadTextureCoordinate2(DefName: String = '');
  120. procedure ReadMaterial(DefName: String = '');
  121. procedure ReadIndexedFaceSet(DefName: String = '');
  122. procedure ReadTransform(DefName: String = '');
  123. procedure ReadShapeHints(DefName: String = '');
  124. procedure ReadSeparator(DefName: String = '');
  125. procedure ReadGroup(DefName: String = '');
  126. procedure ReadDef;
  127. procedure ReadUse;
  128. public
  129. constructor Create;
  130. destructor Destroy; override;
  131. procedure Parse(Text: String);
  132. property RootNode: TVRMLNode read FRootNode;
  133. property AllowUnknownNodes: Boolean read FAllowUnknownNodes
  134. write FAllowUnknownNodes;
  135. end;
  136. // ---------------------------------------------------------------------------
  137. implementation
  138. // ---------------------------------------------------------------------------
  139. function CreateVRMLTokenList(Text: String): TStringList;
  140. const
  141. cSymbols: array [0 .. 3] of char = ('{', '}', '[', ']');
  142. var
  143. i, j, p: Integer;
  144. str, token: String;
  145. begin
  146. Result := TStringList.Create;
  147. Result.Text := Text;
  148. for i := 0 to Result.Count - 1 do
  149. begin
  150. p := Pos('#', Result[i]);
  151. if p > 0 then
  152. Result[i] := Copy(Result[i], 1, p - 1);
  153. end;
  154. Result.CommaText := Result.Text;
  155. for j := 0 to Length(cSymbols) - 1 do
  156. begin
  157. i := 0;
  158. repeat
  159. token := Result[i];
  160. p := Pos(cSymbols[j], token);
  161. if (p > 0) and (token <> cSymbols[j]) then
  162. begin
  163. str := Copy(token, p + 1, Length(token) - p);
  164. if (p = 1) then
  165. begin
  166. Result.Delete(i);
  167. Result.Insert(i, trim(str));
  168. Result.Insert(i, cSymbols[j]);
  169. end
  170. else
  171. begin
  172. Result.Delete(i);
  173. if Length(str) > 0 then
  174. Result.Insert(i, trim(str));
  175. Result.Insert(i, cSymbols[j]);
  176. Result.Insert(i, trim(Copy(token, 1, p - 1)));
  177. end;
  178. end;
  179. Inc(i);
  180. until i >= Result.Count - 1;
  181. end;
  182. end;
  183. // ---------------
  184. // --------------- TVRMLNode ---------------
  185. // ---------------
  186. constructor TVRMLNode.Create;
  187. begin
  188. FNodes := TList.Create;
  189. end;
  190. constructor TVRMLNode.CreateOwned(AParent: TVRMLNode);
  191. begin
  192. Create;
  193. if Assigned(AParent) then
  194. AParent.Add(Self);
  195. end;
  196. destructor TVRMLNode.Destroy;
  197. begin
  198. Clear;
  199. FNodes.Free;
  200. inherited;
  201. end;
  202. function TVRMLNode.GetNode(index: Integer): TVRMLNode;
  203. begin
  204. Result := TVRMLNode(FNodes[index]);
  205. end;
  206. function TVRMLNode.Count: Integer;
  207. begin
  208. Result := FNodes.Count;
  209. end;
  210. procedure TVRMLNode.Clear;
  211. begin
  212. while FNodes.Count > 0 do
  213. Delete(0);
  214. end;
  215. procedure TVRMLNode.Add(node: TVRMLNode);
  216. begin
  217. if not Assigned(node) then
  218. exit;
  219. if Assigned(node.Parent) then
  220. node.Parent.FNodes.Remove(node);
  221. FNodes.Add(node);
  222. node.FParent := Self;
  223. end;
  224. procedure TVRMLNode.Remove(node: TVRMLNode);
  225. begin
  226. if not Assigned(node) then
  227. exit;
  228. FNodes.Remove(node);
  229. node.Free;
  230. end;
  231. procedure TVRMLNode.Delete(index: Integer);
  232. begin
  233. if (index < 0) or (index >= Count) then
  234. exit;
  235. Nodes[index].Free;
  236. FNodes.Delete(index);
  237. end;
  238. // ---------------
  239. // --------------- TVRMLSingleArray ---------------
  240. // ---------------
  241. constructor TVRMLSingleArray.Create;
  242. begin
  243. inherited;
  244. FValues := TSingleList.Create;
  245. end;
  246. destructor TVRMLSingleArray.Destroy;
  247. begin
  248. FValues.Free;
  249. inherited;
  250. end;
  251. // ---------------
  252. // --------------- TVRMLIntegerArray ---------------
  253. // ---------------
  254. constructor TVRMLIntegerArray.Create;
  255. begin
  256. inherited;
  257. FValues := TIntegerList.Create;
  258. end;
  259. destructor TVRMLIntegerArray.Destroy;
  260. begin
  261. FValues.Free;
  262. inherited;
  263. end;
  264. // ---------------
  265. // --------------- TVRMLMaterial ---------------
  266. // ---------------
  267. constructor TVRMLMaterial.Create;
  268. begin
  269. inherited;
  270. // Default shininess value
  271. FHasDiffuse := False;
  272. FHasAmbient := False;
  273. FHasSpecular := False;
  274. FHasEmissive := False;
  275. FHasTransparency := False;
  276. FHasShininess := False;
  277. end;
  278. // ---------------
  279. // --------------- TVRMLTransform ---------------
  280. // ---------------
  281. constructor TVRMLTransform.Create;
  282. begin
  283. inherited;
  284. FScaleFactor.X := 1;
  285. FScaleFactor.Y := 1;
  286. FScaleFactor.Z := 1;
  287. end;
  288. // ---------------
  289. // --------------- TVRMLParser ---------------
  290. // ---------------
  291. constructor TVRMLParser.Create;
  292. begin
  293. FDefines := TList.Create;
  294. FRootNode := TVRMLNode.Create;
  295. FRootNode.Name := 'Root';
  296. FAllowUnknownNodes := False;
  297. end;
  298. destructor TVRMLParser.Destroy;
  299. begin
  300. FDefines.Free;
  301. FRootNode.Free;
  302. inherited;
  303. end;
  304. function TVRMLParser.ReadToken: String;
  305. begin
  306. if FCursor < FTokens.Count then
  307. begin
  308. Result := LowerCase(FTokens[FCursor]);
  309. Inc(FCursor);
  310. end
  311. else
  312. Result := '';
  313. end;
  314. procedure TVRMLParser.ReadUnknownArray(DefName: String);
  315. var
  316. token: String;
  317. begin
  318. if AllowUnknownNodes then
  319. begin
  320. FCurrentNode := TVRMLNode.CreateOwned(FCurrentNode);
  321. FCurrentNode.Name := 'Unknown array';
  322. end;
  323. repeat
  324. token := ReadToken;
  325. if token = '' then
  326. exit;
  327. until token = ']';
  328. if AllowUnknownNodes then
  329. FCurrentNode := FCurrentNode.Parent;
  330. end;
  331. procedure TVRMLParser.ReadUnknownHeirachy(DefName: String);
  332. var
  333. token: String;
  334. begin
  335. if AllowUnknownNodes then
  336. begin
  337. FCurrentNode := TVRMLNode.CreateOwned(FCurrentNode);
  338. FCurrentNode.Name := 'Unknown hierarchy';
  339. end;
  340. repeat
  341. token := ReadToken;
  342. if token = '' then
  343. exit
  344. else
  345. ReadUnknown(token);
  346. until token = '}';
  347. if AllowUnknownNodes then
  348. FCurrentNode := FCurrentNode.Parent;
  349. end;
  350. procedure TVRMLParser.ReadUnknown(unknown_token: String; DefName: String);
  351. begin
  352. if unknown_token = '{' then
  353. ReadUnknownHeirachy
  354. else if unknown_token = '[' then
  355. ReadUnknownArray
  356. else if (unknown_token <> '}') and (unknown_token <> ']') and AllowUnknownNodes
  357. then
  358. begin
  359. TVRMLNode.CreateOwned(FCurrentNode).Name := 'UNKNOWN[' +
  360. unknown_token + ']';
  361. end;
  362. end;
  363. function TVRMLParser.ReadSingle: Single;
  364. begin
  365. Result := GLS.Utils.StrToFloatDef(ReadToken, 0);
  366. end;
  367. function TVRMLParser.ReadVector3f: TVector3f;
  368. begin
  369. Result.X := ReadSingle;
  370. Result.Y := ReadSingle;
  371. Result.Z := ReadSingle;
  372. end;
  373. function TVRMLParser.ReadVector4f: TVector4f;
  374. begin
  375. Result.X := ReadSingle;
  376. Result.Y := ReadSingle;
  377. Result.Z := ReadSingle;
  378. Result.W := ReadSingle;
  379. end;
  380. procedure TVRMLParser.ReadPointArray(DefName: String);
  381. var
  382. token: String;
  383. begin
  384. FCurrentNode := TVRMLSingleArray.CreateOwned(FCurrentNode);
  385. FCurrentNode.Name := 'PointArray';
  386. repeat
  387. token := ReadToken;
  388. if token = '' then
  389. exit;
  390. until token = '[';
  391. repeat
  392. token := ReadToken;
  393. if token = '' then
  394. exit
  395. else if token <> ']' then
  396. TVRMLSingleArray(FCurrentNode)
  397. .Values.Add(GLS.Utils.StrToFloatDef(token, 0));
  398. until token = ']';
  399. FCurrentNode := FCurrentNode.Parent;
  400. end;
  401. procedure TVRMLParser.ReadCoordIndexArray(DefName: String = '');
  402. var
  403. token: String;
  404. begin
  405. FCurrentNode := TVRMLIntegerArray.CreateOwned(FCurrentNode);
  406. FCurrentNode.Name := 'CoordIndexArray';
  407. FCurrentNode.DefName := DefName;
  408. repeat
  409. token := ReadToken;
  410. if token = '' then
  411. exit;
  412. until token = '[';
  413. repeat
  414. token := ReadToken;
  415. if token = '' then
  416. exit
  417. else if token <> ']' then
  418. TVRMLIntegerArray(FCurrentNode).Values.Add(StrToInt(token));
  419. until token = ']';
  420. FCurrentNode := FCurrentNode.Parent;
  421. end;
  422. procedure TVRMLParser.ReadNormalIndexArray(DefName: String = '');
  423. var
  424. token: String;
  425. begin
  426. FCurrentNode := TVRMLIntegerArray.CreateOwned(FCurrentNode);
  427. FCurrentNode.Name := 'NormalIndexArray';
  428. FCurrentNode.DefName := DefName;
  429. repeat
  430. token := ReadToken;
  431. if token = '' then
  432. exit;
  433. until token = '[';
  434. repeat
  435. token := ReadToken;
  436. if token = '' then
  437. exit
  438. else if token <> ']' then
  439. TVRMLIntegerArray(FCurrentNode).Values.Add(StrToInt(token));
  440. until token = ']';
  441. FCurrentNode := FCurrentNode.Parent;
  442. end;
  443. procedure TVRMLParser.ReadTextureCoordIndexArray(DefName: String = '');
  444. var
  445. token: String;
  446. begin
  447. FCurrentNode := TVRMLIntegerArray.CreateOwned(FCurrentNode);
  448. FCurrentNode.Name := 'TextureCoordIndexArray';
  449. FCurrentNode.DefName := DefName;
  450. repeat
  451. token := ReadToken;
  452. if token = '' then
  453. exit;
  454. until token = '[';
  455. repeat
  456. token := ReadToken;
  457. if token = '' then
  458. exit
  459. else if token <> ']' then
  460. TVRMLIntegerArray(FCurrentNode).Values.Add(StrToInt(token));
  461. until token = ']';
  462. FCurrentNode := FCurrentNode.Parent;
  463. end;
  464. procedure TVRMLParser.ReadMaterial(DefName: String);
  465. var
  466. token: String;
  467. begin
  468. FCurrentNode := TVRMLMaterial.CreateOwned(FCurrentNode);
  469. FCurrentNode.Name := 'Material';
  470. FCurrentNode.DefName := DefName;
  471. repeat
  472. token := ReadToken;
  473. if token = '' then
  474. exit;
  475. until token = '{';
  476. with TVRMLMaterial(FCurrentNode) do
  477. begin
  478. repeat
  479. token := ReadToken;
  480. if token = '' then
  481. exit
  482. else if token = 'diffusecolor' then
  483. begin
  484. DiffuseColor := ReadVector3f;
  485. HasDiffuse := True;
  486. end
  487. else if token = 'ambientcolor' then
  488. begin
  489. AmbientColor := ReadVector3f;
  490. HasAmbient := True;
  491. end
  492. else if token = 'specularcolor' then
  493. begin
  494. SpecularColor := ReadVector3f;
  495. HasSpecular := True;
  496. end
  497. else if token = 'emissivecolor' then
  498. begin
  499. EmissiveColor := ReadVector3f;
  500. HasEmissive := True;
  501. end
  502. else if token = 'transparency' then
  503. begin
  504. Transparency := ReadSingle;
  505. HasTransparency := True;
  506. end
  507. else if token = 'shininess' then
  508. begin
  509. Shininess := ReadSingle;
  510. HasShininess := True;
  511. end
  512. else if token <> '}' then
  513. ReadUnknown(token);
  514. until token = '}';
  515. end;
  516. FCurrentNode := FCurrentNode.Parent;
  517. end;
  518. procedure TVRMLParser.ReadCoordinate3(DefName: String = '');
  519. var
  520. token: String;
  521. begin
  522. FCurrentNode := TVRMLNode.CreateOwned(FCurrentNode);
  523. FCurrentNode.Name := 'Coordinate3';
  524. FCurrentNode.DefName := DefName;
  525. repeat
  526. token := ReadToken;
  527. if token = '' then
  528. exit;
  529. until token = '{';
  530. repeat
  531. token := ReadToken;
  532. if token = '' then
  533. exit
  534. else if token = 'point' then
  535. ReadPointArray
  536. else if token <> '}' then
  537. ReadUnknown(token);
  538. until token = '}';
  539. FCurrentNode := FCurrentNode.Parent;
  540. end;
  541. procedure TVRMLParser.ReadNormal(DefName: String = '');
  542. var
  543. token: String;
  544. begin
  545. FCurrentNode := TVRMLNode.CreateOwned(FCurrentNode);
  546. FCurrentNode.Name := 'Normal';
  547. FCurrentNode.DefName := DefName;
  548. repeat
  549. token := ReadToken;
  550. if token = '' then
  551. exit;
  552. until token = '{';
  553. repeat
  554. token := ReadToken;
  555. if token = '' then
  556. exit
  557. else if token = 'vector' then
  558. ReadPointArray
  559. else if token <> '}' then
  560. ReadUnknown(token);
  561. until token = '}';
  562. FCurrentNode := FCurrentNode.Parent;
  563. end;
  564. procedure TVRMLParser.ReadTextureCoordinate2(DefName: String = '');
  565. var
  566. token: String;
  567. begin
  568. FCurrentNode := TVRMLNode.CreateOwned(FCurrentNode);
  569. FCurrentNode.Name := 'TextureCoordinate2';
  570. FCurrentNode.DefName := DefName;
  571. repeat
  572. token := ReadToken;
  573. if token = '' then
  574. exit;
  575. until token = '{';
  576. repeat
  577. token := ReadToken;
  578. if token = '' then
  579. exit
  580. else if token = 'point' then
  581. ReadPointArray
  582. else if token <> '}' then
  583. ReadUnknown(token);
  584. until token = '}';
  585. FCurrentNode := FCurrentNode.Parent;
  586. end;
  587. procedure TVRMLParser.ReadIndexedFaceSet(DefName: String = '');
  588. var
  589. token: String;
  590. begin
  591. FCurrentNode := TVRMLNode.CreateOwned(FCurrentNode);
  592. FCurrentNode.Name := 'IndexedFaceSet';
  593. FCurrentNode.DefName := DefName;
  594. repeat
  595. token := ReadToken;
  596. if token = '' then
  597. exit;
  598. until token = '{';
  599. repeat
  600. token := ReadToken;
  601. if token = '' then
  602. exit
  603. else if token = 'coordindex' then
  604. ReadCoordIndexArray
  605. else if token = 'normalindex' then
  606. ReadNormalIndexArray
  607. else if token = 'texturecoordindex' then
  608. ReadTextureCoordIndexArray
  609. else if token <> '}' then
  610. ReadUnknown(token);
  611. until token = '}';
  612. FCurrentNode := FCurrentNode.Parent;
  613. end;
  614. procedure TVRMLParser.ReadTransform(DefName: String);
  615. var
  616. token: String;
  617. begin
  618. FCurrentNode := TVRMLTransform.CreateOwned(FCurrentNode);
  619. FCurrentNode.Name := 'Transform';
  620. FCurrentNode.DefName := DefName;
  621. repeat
  622. token := ReadToken;
  623. if token = '' then
  624. exit;
  625. until token = '{';
  626. with TVRMLTransform(FCurrentNode) do
  627. begin
  628. repeat
  629. token := ReadToken;
  630. if token = '' then
  631. exit
  632. else if token = 'rotation' then
  633. Rotation := ReadVector4f
  634. else if token = 'center' then
  635. Center := ReadVector3f
  636. else if token = 'scalefactor' then
  637. ScaleFactor := ReadVector3f
  638. else if token <> '}' then
  639. ReadUnknown(token);
  640. until token = '}';
  641. end;
  642. FCurrentNode := FCurrentNode.Parent;
  643. end;
  644. procedure TVRMLParser.ReadShapeHints(DefName: String = '');
  645. var
  646. token: String;
  647. begin
  648. FCurrentNode := TVRMLShapeHints.CreateOwned(FCurrentNode);
  649. FCurrentNode.Name := 'ShapeHints';
  650. FCurrentNode.DefName := DefName;
  651. repeat
  652. token := ReadToken;
  653. if token = '' then
  654. exit;
  655. until token = '{';
  656. repeat
  657. token := ReadToken;
  658. if token = '' then
  659. exit
  660. else if token = 'creaseangle' then
  661. TVRMLShapeHints(FCurrentNode).CreaseAngle := ReadSingle
  662. else if token <> '}' then
  663. ReadUnknown(token);
  664. until token = '}';
  665. FCurrentNode := FCurrentNode.Parent;
  666. end;
  667. procedure TVRMLParser.ReadSeparator(DefName: String = '');
  668. var
  669. token: String;
  670. begin
  671. FCurrentNode := TVRMLNode.CreateOwned(FCurrentNode);
  672. FCurrentNode.Name := 'Separator';
  673. FCurrentNode.DefName := DefName;
  674. repeat
  675. token := ReadToken;
  676. if token = '' then
  677. exit;
  678. until token = '{';
  679. repeat
  680. token := ReadToken;
  681. if token = '' then
  682. exit
  683. else if token = 'def' then
  684. ReadDef
  685. else if (token = 'group') or (token = 'switch') then
  686. ReadGroup
  687. else if token = 'separator' then
  688. ReadSeparator
  689. else if token = 'use' then
  690. ReadUse
  691. else if token = 'shapehints' then
  692. ReadShapeHints
  693. else if token = 'transform' then
  694. ReadTransform
  695. else if token = 'material' then
  696. ReadMaterial
  697. else if token = 'coordinate3' then
  698. ReadCoordinate3
  699. else if token = 'normal' then
  700. ReadNormal
  701. else if token = 'texturecoordinate2' then
  702. ReadTextureCoordinate2
  703. else if token = 'indexedfaceset' then
  704. ReadIndexedFaceSet
  705. else if token <> '}' then
  706. ReadUnknown(token);
  707. until token = '}';
  708. FCurrentNode := FCurrentNode.Parent;
  709. end;
  710. procedure TVRMLParser.ReadGroup(DefName: String = '');
  711. var
  712. token: String;
  713. begin
  714. FCurrentNode := TVRMLNode.CreateOwned(FCurrentNode);
  715. FCurrentNode.Name := 'Group';
  716. FCurrentNode.DefName := DefName;
  717. repeat
  718. token := ReadToken;
  719. if token = '' then
  720. exit;
  721. until token = '{';
  722. repeat
  723. token := ReadToken;
  724. if token = '' then
  725. exit
  726. else if token = 'def' then
  727. ReadDef
  728. else if (token = 'group') or (token = 'switch') then
  729. ReadGroup
  730. else if token = 'separator' then
  731. ReadSeparator
  732. else if token = 'use' then
  733. ReadUse
  734. else if token = 'shapehints' then
  735. ReadShapeHints
  736. else if token = 'transform' then
  737. ReadTransform
  738. else if token = 'material' then
  739. ReadMaterial
  740. else if token = 'coordinate3' then
  741. ReadCoordinate3
  742. else if token = 'indexedfaceset' then
  743. ReadIndexedFaceSet
  744. else if token <> '}' then
  745. ReadUnknown(token);
  746. until token = '}';
  747. FCurrentNode := FCurrentNode.Parent;
  748. end;
  749. procedure TVRMLParser.ReadDef;
  750. var
  751. DefName, token: String;
  752. begin
  753. DefName := ReadToken;
  754. token := ReadToken;
  755. if (token = 'group') or (token = 'switch') then
  756. ReadGroup(DefName)
  757. else if token = 'separator' then
  758. ReadSeparator(DefName)
  759. else if token = 'transform' then
  760. ReadTransform(DefName)
  761. else if token = 'material' then
  762. ReadMaterial(DefName)
  763. else if token = 'coordinate3' then
  764. ReadCoordinate3(DefName)
  765. else if token = 'indexedfaceset' then
  766. ReadIndexedFaceSet(DefName)
  767. else
  768. ReadUnknown(token);
  769. end;
  770. procedure TVRMLParser.ReadUse;
  771. begin
  772. with TVRMLUse.CreateOwned(FCurrentNode) do
  773. begin
  774. name := 'Use';
  775. Value := ReadToken;
  776. end;
  777. end;
  778. procedure TVRMLParser.Parse(Text: String);
  779. var
  780. token: String;
  781. begin
  782. FTokens := CreateVRMLTokenList(Text);
  783. FCursor := 0;
  784. FCurrentNode := FRootNode;
  785. try
  786. repeat
  787. token := ReadToken;
  788. if token = 'def' then
  789. ReadDef
  790. else if (token = 'group') or (token = 'switch') then
  791. ReadGroup
  792. else if token = 'separator' then
  793. ReadSeparator
  794. else if token = 'use' then
  795. ReadUse
  796. else if token = 'shapehints' then
  797. ReadShapeHints
  798. else if token = 'transform' then
  799. ReadTransform
  800. else if token = 'material' then
  801. ReadMaterial
  802. else if token = 'coordinate3' then
  803. ReadCoordinate3
  804. else if token = 'indexedfaceset' then
  805. ReadIndexedFaceSet
  806. else
  807. ReadUnknown(token);
  808. until FCursor >= FTokens.Count;
  809. finally
  810. FTokens.Free;
  811. end;
  812. end;
  813. end.