From 7fc9dd9495621cd73062b54301e2cbe87ffa1403 Mon Sep 17 00:00:00 2001 From: Vadim Lopatin Date: Thu, 31 Mar 2016 15:47:05 +0300 Subject: [PATCH] obj model loader for #183 --- dlangui-monod-linux.dproj | 3 + dlangui-monod-osx.dproj | 3 + dlangui-msvc.visualdproj | 3 + examples/d3d/d3d-msvc.visualdproj | 8 +- examples/d3d/dub.json | 2 +- examples/d3d/src/d3d.d | 5 + examples/d3d/views/res/models/suzanne.obj | 1013 +++++++++++++++++++++ examples/d3d/views/resources.list | 1 + src/dlangui/core/parseutils.d | 42 + src/dlangui/core/settings.d | 41 +- src/dlangui/dml/parser.d | 466 +--------- src/dlangui/dml/tokenizer.d | 501 ++++++++++ src/dlangui/graphics/scene/objimport.d | 194 ++++ 13 files changed, 1774 insertions(+), 508 deletions(-) create mode 100644 examples/d3d/views/res/models/suzanne.obj create mode 100644 src/dlangui/core/parseutils.d create mode 100644 src/dlangui/dml/tokenizer.d create mode 100644 src/dlangui/graphics/scene/objimport.d diff --git a/dlangui-monod-linux.dproj b/dlangui-monod-linux.dproj index 1376d1e7..a7a4b57a 100644 --- a/dlangui-monod-linux.dproj +++ b/dlangui-monod-linux.dproj @@ -256,6 +256,7 @@ + @@ -270,6 +271,7 @@ + @@ -286,6 +288,7 @@ + diff --git a/dlangui-monod-osx.dproj b/dlangui-monod-osx.dproj index 665ca7b0..dfd82c8a 100644 --- a/dlangui-monod-osx.dproj +++ b/dlangui-monod-osx.dproj @@ -115,6 +115,7 @@ + @@ -129,6 +130,7 @@ + @@ -145,6 +147,7 @@ + diff --git a/dlangui-msvc.visualdproj b/dlangui-msvc.visualdproj index cec418cb..fef32695 100644 --- a/dlangui-msvc.visualdproj +++ b/dlangui-msvc.visualdproj @@ -748,6 +748,7 @@ + @@ -767,6 +768,7 @@ + @@ -777,6 +779,7 @@ + diff --git a/examples/d3d/d3d-msvc.visualdproj b/examples/d3d/d3d-msvc.visualdproj index 369a7246..20d53180 100644 --- a/examples/d3d/d3d-msvc.visualdproj +++ b/examples/d3d/d3d-msvc.visualdproj @@ -54,7 +54,7 @@ 1 $(DMDInstallDir)windows\bin\dmd.exe $(SolutionDir)/../dlangui/src $(SolutionDir)/../dlangui/3rdparty $(SolutionDir)/../dlangui/deps/DerelictGL3/source $(SolutionDir)/../dlangui/deps/DerelictUtil/source $(SolutionDir)/../dlangui/deps/DerelictFT/source $(SolutionDir)/../dlangui/deps/DerelictSDL2/source - views views/res views/res/i18n views/res/mdpi views/res/hdpi views/res/shaders + views views/res views/res/i18n views/res/mdpi views/res/hdpi views/res/shaders views/res/models $(ConfigurationName) $(OutDir) @@ -146,7 +146,7 @@ 0 0 0 - 2.043 + 2 0 0 0 @@ -156,7 +156,7 @@ 1 $(DMDInstallDir)windows\bin\dmd.exe $(SolutionDir)/../dlangui/src $(SolutionDir)/../dlangui/3rdparty $(SolutionDir)/../dlangui/deps/DerelictGL3/source $(SolutionDir)/../dlangui/deps/DerelictUtil/source $(SolutionDir)/../dlangui/deps/DerelictFT/source $(SolutionDir)/../dlangui/deps/DerelictSDL2/source - views views/res views/res/i18n views/res/mdpi views/res/hdpi views/res/shaders + views views/res views/res/i18n views/res/mdpi views/res/hdpi views/res/shaders views/res/models $(ConfigurationName) $(OutDir) @@ -258,7 +258,7 @@ 1 $(DMDInstallDir)windows\bin\dmd.exe $(SolutionDir)/../dlangui/src $(SolutionDir)/../dlangui/3rdparty $(SolutionDir)/../dlangui/deps/DerelictGL3/source $(SolutionDir)/../dlangui/deps/DerelictUtil/source $(SolutionDir)/../dlangui/deps/DerelictFT/source $(SolutionDir)/../dlangui/deps/DerelictSDL2/source - views views/res views/res/i18n views/res/mdpi views/res/hdpi views/res/shaders + views views/res views/res/i18n views/res/mdpi views/res/hdpi views/res/shaders views/res/models $(ConfigurationName) $(OutDir) diff --git a/examples/d3d/dub.json b/examples/d3d/dub.json index b41e6cca..94b57412 100644 --- a/examples/d3d/dub.json +++ b/examples/d3d/dub.json @@ -5,7 +5,7 @@ "license": "Boost", "authors": ["Vadim Lopatin"], - "stringImportPaths": ["views", "views/res", "views/res/i18n", "views/res/mdpi", "views/res/shaders"], + "stringImportPaths": ["views", "views/res", "views/res/i18n", "views/res/mdpi", "views/res/shaders", "views/res/models"], "targetPath": "bin", "targetName": "d3d", diff --git a/examples/d3d/src/d3d.d b/examples/d3d/src/d3d.d index 3f7d392f..eaa31298 100644 --- a/examples/d3d/src/d3d.d +++ b/examples/d3d/src/d3d.d @@ -8,6 +8,7 @@ import dlangui.graphics.scene.material; import dlangui.graphics.scene.effect; import dlangui.graphics.scene.model; import dlangui.graphics.scene.node; +import dlangui.graphics.scene.objimport; import dlangui.graphics.glsupport; import dlangui.graphics.gldrawbuf; import derelict.opengl3.gl3; @@ -133,6 +134,10 @@ class UiWidget : VerticalLayout, CellVisitor { Node3d cubeNode = new Node3d("cubes", cubeDrawable); _scene.addChild(cubeNode); + ObjModelImport importer; + string src = loadTextResource("suzanne.obj"); + importer.parse(src); + _minerMesh = new Mesh(VertexFormat(VertexElementType.POSITION, VertexElementType.NORMAL, VertexElementType.COLOR, VertexElementType.TEXCOORD0)); _world = new World(); diff --git a/examples/d3d/views/res/models/suzanne.obj b/examples/d3d/views/res/models/suzanne.obj new file mode 100644 index 00000000..5d51b99a --- /dev/null +++ b/examples/d3d/views/res/models/suzanne.obj @@ -0,0 +1,1013 @@ +# Blender v2.62 (sub 0) OBJ File: '' +# www.blender.org +mtllib suzanne.mtl +o Monkey +v 1.557551 1.541131 0.480829 +v 0.331108 1.541131 1.596098 +v 1.536168 1.436254 0.329004 +v 0.181992 1.436254 1.560428 +v 1.478211 1.373008 0.181574 +v 0.040715 1.373008 1.488764 +v 1.299164 1.255507 0.438430 +v 0.313379 1.255507 1.334856 +v 1.391609 1.338692 0.539742 +v 0.405477 1.338692 1.436484 +v 1.463655 1.481125 0.616616 +v 0.475179 1.481125 1.515489 +v 1.364483 1.546302 0.736294 +v 0.603715 1.546302 1.428101 +v 1.229196 1.444066 0.728841 +v 0.609112 1.444066 1.292716 +v 1.099516 1.382490 0.672423 +v 0.565234 1.382490 1.158274 +v 0.999523 1.680306 0.748103 +v 0.650045 1.680306 1.065901 +v 1.143843 1.689665 0.787413 +v 0.675507 1.689665 1.213296 +v 1.311700 1.699877 0.771950 +v 0.644211 1.699876 1.378933 +v 1.346024 1.859916 0.715994 +v 0.585255 1.859916 1.407802 +v 1.200208 1.936552 0.696964 +v 0.580124 1.936552 1.260838 +v 1.064277 1.981164 0.633672 +v 0.529995 1.981164 1.119523 +v 1.249393 2.101073 0.383699 +v 0.263608 2.101073 1.280125 +v 1.350597 2.035456 0.494642 +v 0.364465 2.035455 1.391384 +v 1.437718 1.921785 0.588093 +v 0.449242 1.921785 1.486966 +v 1.539091 1.854744 0.460530 +v 0.312649 1.854744 1.575799 +v 1.507180 1.928740 0.297126 +v 0.153003 1.928740 1.528550 +v 1.442972 1.971683 0.142823 +v 0.005477 1.971683 1.450013 +v 1.536074 1.667319 0.059548 +v -0.086243 1.667319 1.534807 +v 1.582090 1.679180 0.226901 +v 0.075998 1.679179 1.596471 +v 1.585635 1.693070 0.417696 +v 0.265598 1.693070 1.618075 +v 1.591538 1.698184 0.488689 +v 0.335712 1.698184 1.630677 +v 1.555366 1.831457 0.522179 +v 0.372478 1.831457 1.597841 +v 1.475218 1.888964 0.629304 +v 0.486715 1.888964 1.528202 +v 1.400874 1.836088 0.734210 +v 0.598192 1.836088 1.464130 +v 1.371363 1.704175 0.781462 +v 0.648027 1.704175 1.439229 +v 1.416026 1.578656 0.750873 +v 0.613345 1.578656 1.480793 +v 1.500561 1.704465 0.657092 +v 0.511977 1.704464 1.556063 +v 1.496745 1.523239 0.652977 +v 0.508242 1.523239 1.551874 +v 1.570519 1.574025 0.538842 +v 0.387631 1.574025 1.614504 +v 0.884647 2.056404 0.972832 +v 0.978271 1.910794 1.075789 +v 1.007056 -0.010544 1.107443 +v 1.023780 0.665525 1.125833 +v 1.023886 0.911022 1.125950 +v 0.991120 -0.217316 1.089918 +v 0.731860 2.063051 0.804815 +v 0.608941 2.262743 0.669642 +v -0.702664 2.617960 -0.772708 +v -1.013210 1.943970 -1.114210 +v -0.970250 1.169563 -1.066968 +v -0.339555 0.413568 -0.373404 +v 1.080089 0.879063 0.535973 +v 0.431237 0.879063 1.126008 +v 1.162680 0.361279 0.480163 +v 0.367854 0.361279 1.202940 +v 1.224984 -0.044071 0.455140 +v 0.337042 -0.044072 1.262593 +v 1.233364 -0.380861 0.426531 +v 0.307767 -0.380861 1.268224 +v 1.187077 -0.550258 0.474563 +v 0.359969 -0.550258 1.226697 +v 1.037141 -0.603638 0.668392 +v 0.567130 -0.603638 1.095798 +v 0.822848 -0.627828 0.904871 +v 1.301277 0.986458 0.231784 +v 0.107462 0.986458 1.317383 +v 1.536013 1.183073 -0.063415 +v -0.208648 1.183072 1.523096 +v 1.691008 1.511699 -0.338022 +v -0.496704 1.511699 1.651379 +v 1.809938 1.935251 -0.277375 +v -0.447597 1.935251 1.775520 +v 1.699542 2.114131 -0.067254 +v -0.227962 2.114130 1.685526 +v 1.482161 2.332810 0.255507 +v 0.113942 2.332810 1.499701 +v 1.296200 2.551259 0.513268 +v 0.388161 2.551259 1.338996 +v 1.123635 2.491603 0.732056 +v 0.622313 2.491603 1.187935 +v 0.999250 2.181512 0.870335 +v 0.771754 2.181512 1.077210 +v 1.181442 2.004993 0.825873 +v 0.710232 2.004993 1.254370 +v 1.118734 1.826579 0.888449 +v 0.778467 1.826579 1.197872 +v 1.243571 1.359620 0.762021 +v 0.640781 1.359620 1.310170 +v 1.413467 1.283638 0.507156 +v 0.370966 1.283638 1.455156 +v 1.554596 1.368817 0.284158 +v 0.135601 1.368817 1.574524 +v 1.667730 1.575157 0.099474 +v -0.058970 1.575156 1.669653 +v 1.694565 1.785974 0.068322 +v -0.092524 1.785974 1.693416 +v 1.647587 1.933794 0.157522 +v 0.000725 1.933794 1.655100 +v 1.496208 2.068395 0.405105 +v 0.261536 2.068394 1.527857 +v 1.272432 2.132214 0.705662 +v 0.581941 2.132214 1.333562 +v 1.010509 -0.174395 1.111239 +v 1.157375 -0.174807 0.954419 +v 0.840480 -0.174807 1.242588 +v 1.151300 -0.350989 0.924204 +v 0.810977 -0.350989 1.233679 +v 1.069282 -0.440411 0.973784 +v 0.868104 -0.440411 1.156726 +v 0.964561 -0.463026 1.060711 +v 0.985469 0.904933 1.083704 +v 0.968272 0.991639 1.064793 +v 1.109568 0.953310 0.948632 +v 0.839248 0.953310 1.194449 +v 1.147907 0.806256 0.918546 +v 0.805665 0.806256 1.229764 +v 1.105752 0.656782 0.959886 +v 0.850813 0.656782 1.191716 +v 1.401087 1.141674 0.436000 +v 0.301304 1.141673 1.436091 +v 1.606451 1.311528 0.112870 +v -0.039829 1.311528 1.609918 +v 1.731937 1.580541 -0.089250 +v -0.252928 1.580541 1.715692 +v 1.802342 1.882002 -0.068724 +v -0.239164 1.882001 1.787725 +v 1.759268 2.034402 0.098814 +v -0.068300 2.034402 1.760717 +v 1.555273 2.243515 0.417633 +v 0.268411 2.243514 1.587844 +v 1.399993 2.399956 0.639232 +v 0.503725 2.399956 1.454256 +v 1.265033 2.351730 0.810953 +v 0.687459 2.351729 1.336171 +v 1.136191 2.091978 0.950311 +v 0.838396 2.091978 1.221111 +v 1.180835 1.062361 0.862932 +v 0.747182 1.062361 1.257276 +v 1.218603 0.353955 0.759067 +v 0.640205 0.353955 1.285033 +v 1.267841 -0.057563 0.720826 +v 0.597472 -0.057563 1.330428 +v 1.268471 -0.308299 0.693952 +v 0.570659 -0.308300 1.328509 +v 1.212580 -0.476107 0.708830 +v 0.590765 -0.476107 1.274279 +v 1.099028 -0.534266 0.815843 +v 0.708054 -0.534266 1.171375 +v 0.910663 -0.555989 1.001440 +v 0.943180 1.300730 1.037200 +v 0.950303 1.628774 1.045033 +v 1.369922 2.150492 0.573698 +v 0.441335 2.150492 1.418112 +v 1.145915 1.481920 0.847275 +v 0.734903 1.481920 1.221030 +v 1.115217 1.641806 0.882467 +v 0.772845 1.641806 1.193804 +v 1.157501 -0.015738 0.952884 +v 0.838939 -0.015738 1.242568 +v 1.119044 0.367634 0.972940 +v 0.862548 0.367634 1.206184 +v 0.998981 0.362086 1.098563 +v 0.987565 0.602611 1.086009 +v 1.137300 0.724992 1.018816 +v 0.906488 0.724992 1.228704 +v 1.192659 0.823835 0.980435 +v 0.863035 0.823835 1.280179 +v 1.148682 0.955153 0.985944 +v 0.872686 0.955153 1.236922 +v 1.062688 0.975967 1.060763 +v 0.955315 0.975967 1.158402 +v 1.062707 0.863441 1.168641 +v 1.107904 0.946747 1.091309 +v 0.981441 0.946747 1.206309 +v 1.169164 0.932992 1.036933 +v 0.921505 0.932992 1.262142 +v 1.188745 0.834247 1.053575 +v 0.936218 0.834247 1.283211 +v 1.147209 0.762518 1.064424 +v 0.950953 0.762518 1.242890 +v 1.051170 0.731220 1.155954 +v 1.087167 0.602707 0.504372 +v 0.399108 0.602707 1.130060 +v 1.152946 0.790166 0.800188 +v 0.687361 0.790166 1.223568 +v 1.166985 0.621767 0.778931 +v 0.664870 0.621767 1.235530 +v 1.061312 0.743784 0.535731 +v 0.432775 0.743784 1.107293 +v 0.960657 -0.422809 1.056419 +v 1.033371 -0.401393 0.996301 +v 0.893921 -0.401393 1.123110 +v 1.105542 -0.317474 0.962951 +v 0.853884 -0.317474 1.191797 +v 1.106624 -0.201489 0.985600 +v 0.876329 -0.201489 1.195020 +v 0.930534 -0.260704 1.023293 +v 1.035395 -0.242586 0.930010 +v 0.827737 -0.242586 1.118844 +v 1.041032 -0.311107 0.908482 +v 0.805772 -0.311107 1.122417 +v 0.986559 -0.361714 0.940082 +v 0.842390 -0.361714 1.071183 +v 0.913247 -0.382032 1.004283 +v 1.198416 1.655756 0.833149 +v 0.715867 1.655756 1.271957 +v 1.223934 1.534917 0.811856 +v 0.692252 1.534917 1.295342 +v 1.390455 2.043658 0.574672 +v 0.440359 2.043658 1.438644 +v 1.311339 2.029925 0.677864 +v 0.550582 2.029925 1.369661 +v 1.511618 1.990023 0.452471 +v 0.307229 1.990023 1.547685 +v 1.614724 1.887367 0.235843 +v 0.081807 1.887367 1.629805 +v 1.650974 1.760813 0.173539 +v 0.016349 1.760813 1.659989 +v 1.636168 1.592645 0.203798 +v 0.047875 1.592644 1.648116 +v 1.555524 1.430897 0.368259 +v 0.219236 1.430897 1.583416 +v 1.443544 1.368865 0.548299 +v 0.409075 1.368865 1.488996 +v 1.299790 1.440982 0.749171 +v 0.622662 1.440982 1.364918 +v 1.201537 1.801527 0.820673 +v 0.703152 1.801526 1.273881 +v 1.241358 1.942831 0.768528 +v 0.647468 1.942831 1.308583 +v 1.254534 1.911219 0.726075 +v 0.603958 1.911219 1.317679 +v 1.212705 1.793844 0.773491 +v 0.655124 1.793844 1.280529 +v 1.304707 1.469300 0.711148 +v 0.584345 1.469300 1.366212 +v 1.431898 1.411445 0.539336 +v 0.401256 1.411445 1.476554 +v 1.528865 1.464708 0.379283 +v 0.232736 1.464707 1.557921 +v 1.593959 1.608745 0.238406 +v 0.086326 1.608744 1.609376 +v 1.604108 1.748941 0.207146 +v 0.054245 1.748941 1.616518 +v 1.571505 1.862729 0.265004 +v 0.114931 1.862729 1.589543 +v 1.490815 1.960163 0.449563 +v 0.306305 1.960163 1.526700 +v 1.319638 1.985078 0.659029 +v 0.531045 1.985078 1.376137 +v 1.389737 1.999994 0.567665 +v 0.433452 1.999993 1.437266 +v 1.230905 1.557108 0.770216 +v 0.650139 1.557108 1.298337 +v 1.206948 1.665424 0.783007 +v 0.665142 1.665424 1.275699 +v 0.905195 2.160242 0.631140 +v 0.542545 2.160242 0.960917 +v 1.021863 2.422813 0.556044 +v 0.456734 2.422813 1.069946 +v 1.175368 2.467711 0.357759 +v 0.244798 2.467711 1.203975 +v 1.273369 2.246875 0.145016 +v 0.023728 2.246875 1.281380 +v 1.494610 2.068221 -0.220211 +v -0.360817 2.068221 1.467026 +v 1.611447 1.906675 -0.407303 +v -0.558136 1.906675 1.565613 +v 1.513929 1.511406 -0.490959 +v -0.632176 1.511405 1.460608 +v 1.353052 1.174716 -0.252732 +v -0.379781 1.174715 1.323023 +v 1.141863 0.959670 0.109124 +v 0.000456 0.959670 1.147065 +v 0.230544 2.745087 0.253526 +v -0.217983 2.860323 -0.239712 +v -0.751438 0.698307 -0.826344 +v 0.204333 0.323680 0.224702 +v 0.683270 -0.590867 0.751380 +v 0.548793 -0.305803 0.603498 +v 0.480488 0.066628 0.528384 +v 0.391822 0.258160 0.430880 +v 1.255002 1.550009 -0.888187 +v -1.003088 1.550008 1.165212 +v 1.057206 1.653400 -1.160972 +v -1.255907 1.653399 0.942463 +v 0.510876 1.589572 -1.572621 +v -1.613947 1.589572 0.359592 +v -0.319041 1.832516 -1.472797 +v -1.435948 1.832516 -0.457135 +v 1.057196 1.072262 -0.761879 +v -0.858609 1.072262 0.980262 +v 0.676626 0.896405 -1.027135 +v -1.086617 0.896404 0.576274 +v 0.413484 1.064152 -1.385578 +v -1.418518 1.064151 0.280358 +v -0.381602 1.153586 -1.326173 +v -1.284056 1.153586 -0.505524 +v 0.893291 0.448559 0.317635 +v 0.231579 0.448559 0.919365 +v 0.628560 0.346935 0.237874 +v 0.177256 0.346935 0.648269 +v 0.985057 -0.214397 0.308618 +v 0.213908 -0.214397 1.009864 +v 0.930297 0.154679 0.324968 +v 0.235372 0.154679 0.956900 +v 1.045723 -0.495595 0.338245 +v 0.237655 -0.495596 1.073064 +v 0.761846 -0.249747 0.436806 +v 0.362666 -0.249747 0.799801 +v 0.692574 0.120917 0.386553 +v 0.319201 0.120917 0.726080 +v 0.889282 -0.550767 0.527306 +v 0.440686 -0.550767 0.935237 +v 0.866849 0.633415 0.265023 +v 0.181708 0.633415 0.888058 +v 0.971819 0.785468 0.376266 +v 0.282507 0.785467 1.003094 +v 1.002157 0.871088 0.401905 +v 0.305155 0.871088 1.035725 +v 0.537224 0.462841 -0.013933 +v -0.064765 0.462841 0.533488 +v 0.096352 0.528093 -0.649756 +v -0.655961 0.528093 0.034363 +v -0.229716 0.791713 -1.115710 +v -1.088929 0.791713 -0.334382 +v -0.025686 2.533815 -1.187650 +v -1.179875 2.533815 -0.138085 +v 0.363411 2.760881 -0.761910 +v -0.792912 2.760881 0.289595 +v 0.745792 2.653251 -0.343772 +v -0.412881 2.653250 0.709870 +v 1.053638 2.248427 -0.022378 +v -0.122096 2.248426 1.046779 +v 1.355605 1.928091 -0.602985 +v -0.728700 1.928090 1.292382 +v 1.209707 2.088272 -0.435627 +v -0.548272 2.088271 1.162996 +v 0.915656 2.395282 -0.769655 +v -0.852941 2.395281 0.838623 +v 1.132045 2.123478 -0.930592 +v -1.033654 2.123477 1.038792 +v 0.846456 2.175955 -1.253081 +v -1.327637 2.175955 0.723935 +v 0.592378 2.463061 -1.127310 +v -1.178360 2.463060 0.482915 +v 0.289811 2.256173 -1.447439 +v -1.468385 2.256172 0.151381 +v 0.574317 2.044939 -1.512020 +v -1.559628 2.044938 0.428489 +v 0.102084 1.661294 -1.567933 +v -1.570552 1.661294 -0.046917 +v 0.017868 1.062824 -1.321718 +v -1.317466 1.062823 -0.107429 +v 0.851869 1.741247 -1.384874 +v -1.459349 1.741246 0.716838 +v 0.794671 0.787800 -0.263381 +v -0.337481 0.787799 0.766145 +v 0.372789 0.759805 -0.823582 +v -0.855194 0.759805 0.293088 +v 0.887300 1.805215 -1.560567 +v -1.637609 1.805214 0.735465 +v 0.891097 0.867476 -1.269492 +v -1.348203 0.867476 0.766821 +v 1.032408 0.929593 -1.777943 +v -1.867754 0.929592 0.859326 +v 1.199819 1.188194 -2.192019 +v -2.295827 1.188193 0.986756 +v 1.256881 1.604292 -2.309551 +v -2.418238 1.604291 1.032427 +v 1.119334 1.898593 -2.190074 +v -2.286267 1.898592 0.906818 +v 0.971133 1.901480 -1.843758 +v -1.927468 1.901479 0.792092 +v 1.005618 1.824832 -1.792481 +v -1.879689 1.824831 0.831280 +v 1.109664 1.817010 -2.096161 +v -2.191860 1.817009 0.906088 +v 1.199953 1.565677 -2.203251 +v -2.307022 1.565676 0.985826 +v 1.159299 1.216397 -2.096514 +v -2.196913 1.216396 0.955467 +v 1.054898 1.008124 -1.740850 +v -1.832959 1.008124 0.885229 +v 0.965013 0.965728 -1.313626 +v -1.399141 0.965728 0.836223 +v 0.949716 1.740221 -1.560909 +v -1.643862 1.740220 0.797568 +v 0.919668 1.640003 -1.657580 +v -1.737251 1.640002 0.758497 +v 0.944636 1.027873 -1.465680 +v -1.548580 1.027872 0.801533 +v 1.002205 1.064740 -1.819136 +v -1.905900 1.064740 0.825357 +v 1.088955 1.230499 -2.114828 +v -2.208481 1.230498 0.883704 +v 1.124225 1.502054 -2.206796 +v -2.303376 1.502054 0.910102 +v 1.049719 1.696317 -2.119388 +v -2.209303 1.696317 0.844212 +v 0.957388 1.704767 -1.862547 +v -1.944871 1.704766 0.776629 +v 0.883818 1.617079 -1.427106 +v -1.504418 1.617079 0.744643 +v 0.802852 1.395699 -1.455047 +v -1.524563 1.395699 0.661393 +v 0.735013 1.248339 -1.374532 +v -1.437983 1.248339 0.601487 +v 0.777492 1.204265 -1.438980 +v -1.506165 1.204265 0.637670 +v 0.810284 1.112657 -1.425561 +v -1.495913 1.112656 0.671585 +v 0.815743 1.043388 -1.397158 +v -1.468155 1.043387 0.679711 +v 0.934364 1.169691 -1.057214 +v -1.140979 1.169691 0.830003 +v 0.813120 1.035102 -1.169837 +v -1.241608 1.035102 0.698636 +v 0.796321 1.175481 -1.228149 +v -1.298067 1.175480 0.676388 +v 0.859151 1.461221 -1.325128 +v -1.400562 1.461220 0.729748 +v 0.870465 1.529796 -1.536327 +v -1.611883 1.529796 0.721002 +v 0.833001 1.482436 -1.625002 +v -1.696610 1.482436 0.675306 +v 0.785163 1.045334 -1.485415 +v -1.553119 1.045333 0.640907 +v 0.793887 1.109109 -1.528569 +v -1.596905 1.109108 0.645503 +v 0.757396 1.205590 -1.509305 +v -1.574270 1.205590 0.611002 +v 0.702964 1.255423 -1.454944 +v -1.514998 1.255422 0.561965 +v 0.769856 1.364408 -1.538364 +v -1.604379 1.364408 0.620653 +v 0.926996 1.644125 -1.941652 +v -2.020740 1.644124 0.738880 +v 1.011446 1.637343 -2.152561 +v -2.238701 1.637342 0.802969 +v 1.083534 1.471622 -2.230516 +v -2.323135 1.471621 0.867347 +v 1.048134 1.243852 -2.138737 +v -2.228415 1.243851 0.840801 +v 0.951427 1.098139 -1.877573 +v -1.959264 1.098138 0.769271 +v 0.892197 1.057657 -1.561390 +v -1.638892 1.057657 0.740262 +v 0.882213 1.582588 -1.748385 +v -1.824100 1.582587 0.712608 +v 0.818061 1.272776 -1.608669 +v -1.678935 1.272776 0.661980 +v 0.867717 1.172179 -1.643435 +v -1.718249 1.172179 0.708120 +v 0.919564 1.267513 -1.802554 +v -1.881564 1.267512 0.744659 +v 0.876376 1.378890 -1.727318 +v -1.802575 1.378889 0.708793 +v 0.925619 1.485198 -1.843698 +v -1.923097 1.485197 0.746789 +v 0.978380 1.378467 -1.933059 +v -2.017054 1.378466 0.790847 +v 1.027766 1.461404 -2.023433 +v -2.111700 1.461404 0.831448 +v 0.981870 1.562784 -1.981166 +v -2.065275 1.562783 0.789764 +v 0.833511 1.722392 -1.996331 +v -2.066317 1.722392 0.640635 +v 1.041956 1.758106 -2.334999 +v -2.423209 1.758106 0.816058 +v 1.197357 1.568206 -2.417396 +v -2.519958 1.568205 0.962954 +v 1.119228 1.261748 -2.334125 +v -2.429660 1.261747 0.893065 +v 0.884160 1.041271 -1.954334 +v -2.029307 1.041270 0.695035 +v 0.708126 0.986850 -1.510021 +v -1.570315 0.986849 0.561885 +v 0.702928 1.636983 -1.667190 +v -1.726285 1.636982 0.541821 +usemtl Material +s 1 +f 47 1 3 45 +f 4 2 48 46 +f 45 3 5 43 +f 6 4 46 44 +f 3 9 7 5 +f 8 10 4 6 +f 1 11 9 3 +f 10 12 2 4 +f 11 13 15 9 +f 16 14 12 10 +f 9 15 17 7 +f 18 16 10 8 +f 15 21 19 17 +f 20 22 16 18 +f 13 23 21 15 +f 22 24 14 16 +f 23 25 27 21 +f 28 26 24 22 +f 21 27 29 19 +f 30 28 22 20 +f 27 33 31 29 +f 32 34 28 30 +f 25 35 33 27 +f 34 36 26 28 +f 35 37 39 33 +f 40 38 36 34 +f 33 39 41 31 +f 42 40 34 32 +f 39 45 43 41 +f 44 46 40 42 +f 37 47 45 39 +f 46 48 38 40 +f 47 37 51 49 +f 52 38 48 50 +f 37 35 53 51 +f 54 36 38 52 +f 35 25 55 53 +f 56 26 36 54 +f 25 23 57 55 +f 58 24 26 56 +f 23 13 59 57 +f 60 14 24 58 +f 13 11 63 59 +f 64 12 14 60 +f 11 1 65 63 +f 66 2 12 64 +f 1 47 49 65 +f 50 48 2 66 +f 61 65 49 +f 50 66 62 +f 63 65 61 +f 62 66 64 +f 61 59 63 +f 64 60 62 +f 61 57 59 +f 60 58 62 +f 61 55 57 +f 58 56 62 +f 61 53 55 +f 56 54 62 +f 61 51 53 +f 54 52 62 +f 61 49 51 +f 52 50 62 +f 89 174 176 91 +f 176 175 90 91 +f 87 172 174 89 +f 175 173 88 90 +f 85 170 172 87 +f 173 171 86 88 +f 83 168 170 85 +f 171 169 84 86 +f 81 166 168 83 +f 169 167 82 84 +f 79 92 146 164 +f 147 93 80 165 +f 92 94 148 146 +f 149 95 93 147 +f 94 96 150 148 +f 151 97 95 149 +f 96 98 152 150 +f 153 99 97 151 +f 98 100 154 152 +f 155 101 99 153 +f 100 102 156 154 +f 157 103 101 155 +f 102 104 158 156 +f 159 105 103 157 +f 104 106 160 158 +f 161 107 105 159 +f 106 108 162 160 +f 163 109 107 161 +f 108 67 68 162 +f 68 67 109 163 +f 110 128 160 162 +f 161 129 111 163 +f 128 179 158 160 +f 159 180 129 161 +f 126 156 158 179 +f 159 157 127 180 +f 124 154 156 126 +f 157 155 125 127 +f 122 152 154 124 +f 155 153 123 125 +f 120 150 152 122 +f 153 151 121 123 +f 118 148 150 120 +f 151 149 119 121 +f 116 146 148 118 +f 149 147 117 119 +f 114 164 146 116 +f 147 165 115 117 +f 114 181 177 164 +f 177 182 115 165 +f 110 162 68 112 +f 68 163 111 113 +f 112 68 178 183 +f 178 68 113 184 +f 177 181 183 178 +f 184 182 177 178 +f 135 137 176 174 +f 176 137 136 175 +f 133 135 174 172 +f 175 136 134 173 +f 131 133 172 170 +f 173 134 132 171 +f 166 187 185 168 +f 186 188 167 169 +f 131 170 168 185 +f 169 171 132 186 +f 144 190 189 187 +f 189 190 145 188 +f 185 187 189 69 +f 189 188 186 69 +f 130 131 185 69 +f 186 132 130 69 +f 142 193 191 144 +f 192 194 143 145 +f 140 195 193 142 +f 194 196 141 143 +f 139 197 195 140 +f 196 198 139 141 +f 138 71 197 139 +f 198 71 138 139 +f 190 144 191 70 +f 192 145 190 70 +f 70 191 206 208 +f 207 192 70 208 +f 71 199 200 197 +f 201 199 71 198 +f 197 200 202 195 +f 203 201 198 196 +f 195 202 204 193 +f 205 203 196 194 +f 193 204 206 191 +f 207 205 194 192 +f 199 204 202 200 +f 203 205 199 201 +f 199 208 206 204 +f 207 208 199 205 +f 139 140 164 177 +f 165 141 139 177 +f 140 142 211 164 +f 212 143 141 165 +f 142 144 213 211 +f 214 145 143 212 +f 144 187 166 213 +f 167 188 145 214 +f 81 209 213 166 +f 214 210 82 167 +f 209 215 211 213 +f 212 216 210 214 +f 79 164 211 215 +f 212 165 80 216 +f 131 130 72 222 +f 72 130 132 223 +f 133 131 222 220 +f 223 132 134 221 +f 135 133 220 218 +f 221 134 136 219 +f 137 135 218 217 +f 219 136 137 217 +f 217 218 229 231 +f 230 219 217 231 +f 218 220 227 229 +f 228 221 219 230 +f 220 222 225 227 +f 226 223 221 228 +f 222 72 224 225 +f 224 72 223 226 +f 224 231 229 225 +f 230 231 224 226 +f 225 229 227 +f 228 230 226 +f 183 181 234 232 +f 235 182 184 233 +f 112 183 232 254 +f 233 184 113 255 +f 110 112 254 256 +f 255 113 111 257 +f 181 114 252 234 +f 253 115 182 235 +f 114 116 250 252 +f 251 117 115 253 +f 116 118 248 250 +f 249 119 117 251 +f 118 120 246 248 +f 247 121 119 249 +f 120 122 244 246 +f 245 123 121 247 +f 122 124 242 244 +f 243 125 123 245 +f 124 126 240 242 +f 241 127 125 243 +f 126 179 236 240 +f 237 180 127 241 +f 179 128 238 236 +f 239 129 180 237 +f 128 110 256 238 +f 257 111 129 239 +f 238 256 258 276 +f 259 257 239 277 +f 236 238 276 278 +f 277 239 237 279 +f 240 236 278 274 +f 279 237 241 275 +f 242 240 274 272 +f 275 241 243 273 +f 244 242 272 270 +f 273 243 245 271 +f 246 244 270 268 +f 271 245 247 269 +f 248 246 268 266 +f 269 247 249 267 +f 250 248 266 264 +f 267 249 251 265 +f 252 250 264 262 +f 265 251 253 263 +f 234 252 262 280 +f 263 253 235 281 +f 256 254 260 258 +f 261 255 257 259 +f 254 232 282 260 +f 283 233 255 261 +f 232 234 280 282 +f 281 235 233 283 +f 67 108 284 73 +f 285 109 67 73 +f 108 106 286 284 +f 287 107 109 285 +f 106 104 288 286 +f 289 105 107 287 +f 104 102 290 288 +f 291 103 105 289 +f 102 100 292 290 +f 293 101 103 291 +f 100 98 294 292 +f 295 99 101 293 +f 98 96 296 294 +f 297 97 99 295 +f 96 94 298 296 +f 299 95 97 297 +f 94 92 300 298 +f 301 93 95 299 +f 308 309 328 338 +f 329 309 308 339 +f 307 308 338 336 +f 339 308 307 337 +f 306 307 336 340 +f 337 307 306 341 +f 89 91 306 340 +f 306 91 90 341 +f 87 89 340 334 +f 341 90 88 335 +f 85 87 334 330 +f 335 88 86 331 +f 83 85 330 332 +f 331 86 84 333 +f 330 336 338 332 +f 339 337 331 333 +f 330 334 340 336 +f 341 335 331 337 +f 326 332 338 328 +f 339 333 327 329 +f 81 83 332 326 +f 333 84 82 327 +f 209 342 344 215 +f 345 343 210 216 +f 81 326 342 209 +f 343 327 82 210 +f 79 215 344 346 +f 345 216 80 347 +f 79 346 300 92 +f 301 347 80 93 +f 77 324 352 304 +f 353 325 77 304 +f 304 352 350 78 +f 351 353 304 78 +f 78 350 348 305 +f 349 351 78 305 +f 305 348 328 309 +f 329 349 305 309 +f 326 328 348 342 +f 349 329 327 343 +f 296 298 318 310 +f 319 299 297 311 +f 76 316 324 77 +f 325 317 76 77 +f 302 358 356 303 +f 357 359 302 303 +f 303 356 354 75 +f 355 357 303 75 +f 75 354 316 76 +f 317 355 75 76 +f 292 294 362 364 +f 363 295 293 365 +f 364 362 368 366 +f 369 363 365 367 +f 366 368 370 372 +f 371 369 367 373 +f 372 370 376 374 +f 377 371 373 375 +f 314 378 374 376 +f 375 379 315 377 +f 316 354 374 378 +f 375 355 317 379 +f 354 356 372 374 +f 373 357 355 375 +f 356 358 366 372 +f 367 359 357 373 +f 358 360 364 366 +f 365 361 359 367 +f 290 292 364 360 +f 365 293 291 361 +f 74 360 358 302 +f 359 361 74 302 +f 284 286 288 290 +f 289 287 285 291 +f 284 290 360 74 +f 361 291 285 74 +f 73 284 74 +f 74 285 73 +f 294 296 310 362 +f 311 297 295 363 +f 310 312 368 362 +f 369 313 311 363 +f 312 382 370 368 +f 371 383 313 369 +f 314 376 370 382 +f 371 377 315 383 +f 348 350 386 384 +f 387 351 349 385 +f 318 384 386 320 +f 387 385 319 321 +f 298 300 384 318 +f 385 301 299 319 +f 300 344 342 384 +f 343 345 301 385 +f 342 348 384 +f 385 349 343 +f 300 346 344 +f 345 347 301 +f 314 322 380 378 +f 381 323 315 379 +f 316 378 380 324 +f 381 379 317 325 +f 320 386 380 322 +f 381 387 321 323 +f 350 352 380 386 +f 381 353 351 387 +f 324 380 352 +f 353 381 325 +f 400 388 414 402 +f 415 389 401 403 +f 400 402 404 398 +f 405 403 401 399 +f 398 404 406 396 +f 407 405 399 397 +f 396 406 408 394 +f 409 407 397 395 +f 394 408 410 392 +f 411 409 395 393 +f 392 410 412 390 +f 413 411 393 391 +f 410 420 418 412 +f 419 421 411 413 +f 408 422 420 410 +f 421 423 409 411 +f 406 424 422 408 +f 423 425 407 409 +f 404 426 424 406 +f 425 427 405 407 +f 402 428 426 404 +f 427 429 403 405 +f 402 414 416 428 +f 417 415 403 429 +f 318 320 444 442 +f 445 321 319 443 +f 320 390 412 444 +f 413 391 321 445 +f 310 318 442 312 +f 443 319 311 313 +f 382 430 414 388 +f 415 431 383 389 +f 412 418 440 444 +f 441 419 413 445 +f 438 446 444 440 +f 445 447 439 441 +f 434 446 438 436 +f 439 447 435 437 +f 432 448 446 434 +f 447 449 433 435 +f 430 448 432 450 +f 433 449 431 451 +f 414 430 450 416 +f 451 431 415 417 +f 312 448 430 382 +f 431 449 313 383 +f 312 442 446 448 +f 447 443 313 449 +f 442 444 446 +f 447 445 443 +f 416 450 452 476 +f 453 451 417 477 +f 450 432 462 452 +f 463 433 451 453 +f 432 434 460 462 +f 461 435 433 463 +f 434 436 458 460 +f 459 437 435 461 +f 436 438 456 458 +f 457 439 437 459 +f 438 440 454 456 +f 455 441 439 457 +f 440 418 474 454 +f 475 419 441 455 +f 428 416 476 464 +f 477 417 429 465 +f 426 428 464 466 +f 465 429 427 467 +f 424 426 466 468 +f 467 427 425 469 +f 422 424 468 470 +f 469 425 423 471 +f 420 422 470 472 +f 471 423 421 473 +f 418 420 472 474 +f 473 421 419 475 +f 458 456 480 478 +f 481 457 459 479 +f 478 480 482 484 +f 483 481 479 485 +f 484 482 488 486 +f 489 483 485 487 +f 486 488 490 492 +f 491 489 487 493 +f 464 476 486 492 +f 487 477 465 493 +f 452 484 486 476 +f 487 485 453 477 +f 452 462 478 484 +f 479 463 453 485 +f 458 478 462 460 +f 463 479 459 461 +f 454 474 480 456 +f 481 475 455 457 +f 472 482 480 474 +f 481 483 473 475 +f 470 488 482 472 +f 483 489 471 473 +f 468 490 488 470 +f 489 491 469 471 +f 466 492 490 468 +f 491 493 467 469 +f 464 492 466 +f 467 493 465 +f 392 390 504 502 +f 505 391 393 503 +f 394 392 502 500 +f 503 393 395 501 +f 396 394 500 498 +f 501 395 397 499 +f 398 396 498 496 +f 499 397 399 497 +f 400 398 496 494 +f 497 399 401 495 +f 388 400 494 506 +f 495 401 389 507 +f 494 502 504 506 +f 505 503 495 507 +f 494 496 500 502 +f 501 497 495 503 +f 496 498 500 +f 501 499 497 +f 314 382 388 506 +f 389 383 315 507 +f 314 506 504 322 +f 505 507 315 323 +f 320 322 504 390 +f 505 323 321 391 diff --git a/examples/d3d/views/resources.list b/examples/d3d/views/resources.list index 28d55c35..61d7ce47 100644 --- a/examples/d3d/views/resources.list +++ b/examples/d3d/views/resources.list @@ -6,3 +6,4 @@ res/mdpi/crate.png res/mdpi/blocks.png res/shaders/textured.vert res/shaders/textured.frag +res/models/suzanne.obj diff --git a/src/dlangui/core/parseutils.d b/src/dlangui/core/parseutils.d new file mode 100644 index 00000000..b5f6bc7c --- /dev/null +++ b/src/dlangui/core/parseutils.d @@ -0,0 +1,42 @@ +module dlangui.core.parseutils; + +long parseLong(inout string v, long defValue = 0) { + int len = cast(int)v.length; + if (len == 0) + return defValue; + int sign = 1; + long value = 0; + int digits = 0; + foreach(i; 0 .. len) { + char ch = v[i]; + if (ch == '-') { + if (i != 0) + return defValue; + sign = -1; + } else if (ch >= '0' && ch <= '9') { + digits++; + value = value * 10 + (ch - '0'); + } else { + return defValue; + } + } + return digits > 0 ? (sign > 0 ? value : -value) : defValue; +} + +ulong parseULong(inout string v, ulong defValue = 0) { + int len = cast(int)v.length; + if (len == 0) + return defValue; + ulong value = 0; + int digits = 0; + foreach(i; 0 .. len) { + char ch = v[i]; + if (ch >= '0' && ch <= '9') { + digits++; + value = value * 10 + (ch - '0'); + } else { + return defValue; + } + } + return digits > 0 ? value : defValue; +} diff --git a/src/dlangui/core/settings.d b/src/dlangui/core/settings.d index 59f4c0be..6f64318f 100644 --- a/src/dlangui/core/settings.d +++ b/src/dlangui/core/settings.d @@ -28,6 +28,7 @@ module dlangui.core.settings; import dlangui.core.logger; import dlangui.core.types : parseHexDigit; +public import dlangui.core.parseutils; import std.range; //import std.algorithm : clamp, equal; import std.algorithm : equal; @@ -1906,44 +1907,4 @@ final class Setting { } } -long parseLong(inout string v, long defValue = 0) { - int len = cast(int)v.length; - if (len == 0) - return defValue; - int sign = 1; - long value = 0; - int digits = 0; - foreach(i; 0 .. len) { - char ch = v[i]; - if (ch == '-') { - if (i != 0) - return defValue; - sign = -1; - } else if (ch >= '0' && ch <= '9') { - digits++; - value = value * 10 + (ch - '0'); - } else { - return defValue; - } - } - return digits > 0 ? (sign > 0 ? value : -value) : defValue; -} - -ulong parseULong(inout string v, ulong defValue = 0) { - int len = cast(int)v.length; - if (len == 0) - return defValue; - ulong value = 0; - int digits = 0; - foreach(i; 0 .. len) { - char ch = v[i]; - if (ch >= '0' && ch <= '9') { - digits++; - value = value * 10 + (ch - '0'); - } else { - return defValue; - } - } - return digits > 0 ? value : defValue; -} diff --git a/src/dlangui/dml/parser.d b/src/dlangui/dml/parser.d index eb34b6fe..37d6097f 100644 --- a/src/dlangui/dml/parser.d +++ b/src/dlangui/dml/parser.d @@ -34,26 +34,7 @@ import std.algorithm : equal, min, max; import std.utf : toUTF32, toUTF8; import std.array : join; public import dlangui.dml.annotations; - -class ParserException : Exception { - protected string _msg; - protected string _file; - protected int _line; - protected int _pos; - - @property string file() { return _file; } - @property string msg() { return _msg; } - @property int line() { return _line; } - @property int pos() { return _pos; } - - this(string msg, string file, int line, int pos) { - super(msg ~ " at " ~ file ~ " line " ~ to!string(line) ~ " column " ~ to!string(pos)); - _msg = msg; - _file = file; - _line = line; - _pos = pos; - } -} +public import dlangui.dml.tokenizer; /// parser exception - unknown (unregistered) widget name class UnknownWidgetException : ParserException { @@ -78,447 +59,6 @@ class UnknownPropertyException : UnknownWidgetException { } } -enum TokenType : ushort { - /// end of file - eof, - /// end of line - eol, - /// whitespace - whitespace, - /// string literal - str, - /// integer literal - integer, - /// floating point literal - floating, - /// comment - comment, - /// ident - ident, - /// error - error, - // operators - /// : operator - colon, - /// . operator - dot, - /// ; operator - semicolon, - /// , operator - comma, - /// - operator - minus, - /// + operator - plus, - /// [ - curlyOpen, - /// ] - curlyClose, - /// ( - open, - /// ) - close, - /// [ - squareOpen, - /// ] - squareClose, -} - -struct Token { - TokenType type; - ushort line; - ushort pos; - bool multiline; - string text; - union { - int intvalue; - double floatvalue; - } - public @property string toString() const { - if (type == TokenType.integer) - return "" ~ to!string(line) ~ ":" ~ to!string(pos) ~ " " ~ to!string(type) ~ " " ~ to!string(intvalue); - else if (type == TokenType.floating) - return "" ~ to!string(line) ~ ":" ~ to!string(pos) ~ " " ~ to!string(type) ~ " " ~ to!string(floatvalue); - else - return "" ~ to!string(line) ~ ":" ~ to!string(pos) ~ " " ~ to!string(type) ~ " \"" ~ text ~ "\""; - } - @property bool isMultilineComment() { - return type == TokenType.comment && multiline; - } -} - -/// simple tokenizer for DlangUI ML -class Tokenizer { - protected LineStream _lines; - - dchar[] _lineText; - ushort _line; - ushort _pos; - int _len; - dchar _prevChar; - string _filename; - - Token _token; - - enum : int { - EOF_CHAR = 0x001A, - EOL_CHAR = 0x000A - } - - this(string source, string filename = "") { - _filename = filename; - _lines = LineStream.create(source, filename); - _lineText = _lines.readLine(); - _len = cast(int)_lineText.length; - _line = 0; - _pos = 0; - _prevChar = 0; - } - - ~this() { - destroy(_lines); - _lines = null; - } - - protected dchar peekChar() { - if (_pos < _len) - return _lineText[_pos]; - else if (_lineText is null) - return EOF_CHAR; - return EOL_CHAR; - } - - protected dchar peekNextChar() { - if (_pos < _len - 1) - return _lineText[_pos + 1]; - else if (_lineText is null) - return EOF_CHAR; - return EOL_CHAR; - } - - protected dchar nextChar() { - if (_pos < _len) - _prevChar = _lineText[_pos++]; - else if (_lineText is null) - _prevChar = EOF_CHAR; - else { - _lineText = _lines.readLine(); - _len = cast(int)_lineText.length; - _line++; - _pos = 0; - _prevChar = EOL_CHAR; - } - return _prevChar; - } - - protected dchar skipChar() { - nextChar(); - return peekChar(); - } - - protected void setTokenStart() { - _token.pos = _pos; - _token.line = _line; - _token.text = null; - _token.intvalue = 0; - } - - protected ref const(Token) parseEof() { - _token.type = TokenType.eof; - return _token; - } - - protected ref const(Token) parseEol() { - _token.type = TokenType.eol; - nextChar(); - return _token; - } - - protected ref const(Token) parseWhiteSpace() { - _token.type = TokenType.whitespace; - for(;;) { - dchar ch = skipChar(); - if (ch != ' ' && ch != '\t') - break; - } - return _token; - } - - static bool isAlpha(dchar ch) { - return (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || ch == '_'; - } - - static bool isNum(dchar ch) { - return (ch >= '0' && ch <= '9'); - } - - static bool isAlphaNum(dchar ch) { - return isNum(ch) || isAlpha(ch); - } - - private char[] _stringbuf; - protected ref const(Token) parseString() { - _token.type = TokenType.str; - //skipChar(); // skip " - bool lastBackslash = false; - _stringbuf.length = 0; - for(;;) { - dchar ch = skipChar(); - if (ch == '\"') { - if (lastBackslash) { - _stringbuf ~= ch; - lastBackslash = false; - } else { - skipChar(); - break; - } - } else if (ch == '\\') { - if (lastBackslash) { - _stringbuf ~= ch; - lastBackslash = false; - } else { - lastBackslash = true; - } - } else if (ch == EOL_CHAR) { - skipChar(); - break; - } else if (lastBackslash) { - if (ch == 'n') - ch = '\n'; - else if (ch == 't') - ch = '\t'; - _stringbuf ~= ch; - lastBackslash = false; - } else { - _stringbuf ~= ch; - lastBackslash = false; - } - } - _token.text = _stringbuf.dup; - return _token; - } - - protected ref const(Token) parseIdent() { - _token.type = TokenType.ident; - _stringbuf.length = 0; - _stringbuf ~= peekChar(); - for(;;) { - dchar ch = skipChar(); - if (!isAlphaNum(ch)) - break; - _stringbuf ~= ch; - } - _token.text = _stringbuf.dup; - return _token; - } - - protected ref const(Token) parseFloating(int n) { - _token.type = TokenType.floating; - dchar ch = peekChar(); - // floating point - int div = 1; - int n2 = 0; - for (;;) { - ch = skipChar(); - if (!isNum(ch)) - break; - n2 = n2 * 10 + (ch - '0'); - div *= 10; - } - _token.floatvalue = cast(double)n + (div > 0 ? cast(double)n2 / div : 0.0); - string suffix; - if (ch == '%') { - suffix ~= ch; - ch = skipChar(); - } else { - while (ch >= 'a' && ch <= 'z') { - suffix ~= ch; - ch = skipChar(); - } - } - if (isAlphaNum(ch) || ch == '.') - return parseError(); - _token.text = suffix; - return _token; - } - - protected ref const(Token) parseHex(int prefixLen) { - dchar ch = 0; - foreach(i; 0 .. prefixLen) - ch = skipChar(); - - uint n = parseHexDigit(ch); - if (n == uint.max) - return parseError(); - - for(;;) { - ch = skipChar(); - uint digit = parseHexDigit(ch); - if (digit == uint.max) - break; - n = (n << 4) + digit; - } - string suffix; - if (ch == '%') { - suffix ~= ch; - ch = skipChar(); - } else { - while (ch >= 'a' && ch <= 'z') { - suffix ~= ch; - ch = skipChar(); - } - } - if (isAlphaNum(ch) || ch == '.') - return parseError(); - _token.type = TokenType.integer; - _token.intvalue = n; - _token.text = suffix; - return _token; - } - - protected ref const(Token) parseNumber() { - dchar ch = peekChar(); - uint n = ch - '0'; - for(;;) { - ch = skipChar(); - if (!isNum(ch)) - break; - n = n * 10 + (ch - '0'); - } - if (ch == '.') - return parseFloating(n); - string suffix; - if (ch == '%') { - suffix ~= ch; - ch = skipChar(); - } else { - while (ch >= 'a' && ch <= 'z') { - suffix ~= ch; - ch = skipChar(); - } - } - if (isAlphaNum(ch) || ch == '.') - return parseError(); - _token.type = TokenType.integer; - _token.intvalue = n; - _token.text = suffix; - return _token; - } - - protected ref const(Token) parseSingleLineComment() { - for(;;) { - dchar ch = skipChar(); - if (ch == EOL_CHAR || ch == EOF_CHAR) - break; - } - _token.type = TokenType.comment; - _token.multiline = false; - return _token; - } - - protected ref const(Token) parseMultiLineComment() { - skipChar(); - for(;;) { - dchar ch = skipChar(); - if (ch == '*' && peekNextChar() == '/') { - skipChar(); - skipChar(); - break; - } - if (ch == EOF_CHAR) - break; - } - _token.type = TokenType.comment; - _token.multiline = true; - return _token; - } - - protected ref const(Token) parseError() { - _token.type = TokenType.error; - for(;;) { - dchar ch = skipChar(); - if (ch == ' ' || ch == '\t' || ch == EOL_CHAR || ch == EOF_CHAR) - break; - } - return _token; - } - - protected ref const(Token) parseOp(TokenType op) { - _token.type = op; - skipChar(); - return _token; - } - - /// get next token - ref const(Token) nextToken() { - setTokenStart(); - dchar ch = peekChar(); - if (ch == EOF_CHAR) - return parseEof(); - if (ch == EOL_CHAR) - return parseEol(); - if (ch == ' ' || ch == '\t') - return parseWhiteSpace(); - if (ch == '\"') - return parseString(); - if (isAlpha(ch)) - return parseIdent(); - if (ch == '0' && peekNextChar == 'x') - return parseHex(2); - if (ch == '#') - return parseHex(1); - if (isNum(ch)) - return parseNumber(); - if (ch == '.' && isNum(peekNextChar())) - return parseFloating(0); - if (ch == '/' && peekNextChar() == '/') - return parseSingleLineComment(); - if (ch == '/' && peekNextChar() == '*') - return parseMultiLineComment(); - switch (ch) { - case '.': return parseOp(TokenType.dot); - case ':': return parseOp(TokenType.colon); - case ';': return parseOp(TokenType.semicolon); - case ',': return parseOp(TokenType.comma); - case '-': return parseOp(TokenType.minus); - case '+': return parseOp(TokenType.plus); - case '{': return parseOp(TokenType.curlyOpen); - case '}': return parseOp(TokenType.curlyClose); - case '(': return parseOp(TokenType.open); - case ')': return parseOp(TokenType.close); - case '[': return parseOp(TokenType.squareOpen); - case ']': return parseOp(TokenType.squareClose); - default: - return parseError(); - } - } - - string getContextSource() { - string s = toUTF8(_lineText); - if (_pos == 0) - return " near `^^^" ~ s[0..min($,30)] ~ "`"; - if (_pos >= _len) - return " near `" ~ s[max(_len - 30, 0) .. $] ~ "^^^`"; - return " near `" ~ s[max(_pos - 15, 0) .. _pos] ~ "^^^" ~ s[_pos .. min(_pos + 15, $)] ~ "`"; - } - - void emitError(string msg) { - throw new ParserException(msg ~ getContextSource(), _filename, _token.line, _token.pos); - } - - void emitUnknownPropertyError(string objectName, string propName) { - throw new UnknownPropertyException("Unknown property " ~ objectName ~ "." ~ propName ~ getContextSource(), objectName, propName, _filename, _token.line, _token.pos); - } - - void emitUnknownObjectError(string objectName) { - throw new UnknownWidgetException("Unknown widget type " ~ objectName ~ getContextSource(), objectName, _filename, _token.line, _token.pos); - } - - void emitError(string msg, ref const Token token) { - throw new ParserException(msg, _filename, token.line, token.pos); - } -} - class MLParser { protected string _code; protected string _filename; @@ -590,11 +130,11 @@ class MLParser { } protected void unknownObjectError(string objectName) { - _tokenizer.emitUnknownObjectError(objectName); + throw new UnknownWidgetException("Unknown widget type " ~ objectName ~ _tokenizer.getContextSource(), objectName, _tokenizer.filename, _tokenizer.line, _tokenizer.pos); } protected void unknownPropertyError(string objectName, string propName) { - _tokenizer.emitUnknownPropertyError(objectName, propName); + throw new UnknownPropertyException("Unknown property " ~ objectName ~ "." ~ propName ~ _tokenizer.getContextSource(), objectName, propName, _tokenizer.filename, _tokenizer.line, _tokenizer.pos); } Widget createWidget(string name) { diff --git a/src/dlangui/dml/tokenizer.d b/src/dlangui/dml/tokenizer.d new file mode 100644 index 00000000..2b6e04f2 --- /dev/null +++ b/src/dlangui/dml/tokenizer.d @@ -0,0 +1,501 @@ +module dlangui.dml.tokenizer; + +import dlangui.core.types; +import dlangui.core.linestream; + +import std.conv : to; +import std.utf : toUTF32, toUTF8; +import std.algorithm : equal, min, max; + +enum TokenType : ushort { + /// end of file + eof, + /// end of line + eol, + /// whitespace + whitespace, + /// string literal + str, + /// integer literal + integer, + /// floating point literal + floating, + /// comment + comment, + /// ident + ident, + /// error + error, + // operators + /// : operator + colon, + /// . operator + dot, + /// ; operator + semicolon, + /// / operator + divide, + /// , operator + comma, + /// - operator + minus, + /// + operator + plus, + /// [ + curlyOpen, + /// ] + curlyClose, + /// ( + open, + /// ) + close, + /// [ + squareOpen, + /// ] + squareClose, +} + +struct Token { + TokenType type; + ushort line; + ushort pos; + bool multiline; + string text; + union { + int intvalue; + double floatvalue; + } + public @property string toString() const { + if (type == TokenType.integer) + return "" ~ to!string(line) ~ ":" ~ to!string(pos) ~ " " ~ to!string(type) ~ " " ~ to!string(intvalue); + else if (type == TokenType.floating) + return "" ~ to!string(line) ~ ":" ~ to!string(pos) ~ " " ~ to!string(type) ~ " " ~ to!string(floatvalue); + else + return "" ~ to!string(line) ~ ":" ~ to!string(pos) ~ " " ~ to!string(type) ~ " \"" ~ text ~ "\""; + } + @property bool isMultilineComment() { + return type == TokenType.comment && multiline; + } +} + +class ParserException : Exception { + protected string _msg; + protected string _file; + protected int _line; + protected int _pos; + + @property string file() { return _file; } + @property string msg() { return _msg; } + @property int line() { return _line; } + @property int pos() { return _pos; } + + this(string msg, string file, int line, int pos) { + super(msg ~ " at " ~ file ~ " line " ~ to!string(line) ~ " column " ~ to!string(pos)); + _msg = msg; + _file = file; + _line = line; + _pos = pos; + } +} + +/// simple tokenizer for DlangUI ML +class Tokenizer { + + protected string[] _singleLineCommentPrefixes = ["//"]; + protected LineStream _lines; + protected dchar[] _lineText; + protected ushort _line; + protected ushort _pos; + protected int _len; + protected dchar _prevChar; + protected string _filename; + protected Token _token; + + enum : int { + EOF_CHAR = 0x001A, + EOL_CHAR = 0x000A + } + + this(string source, string filename = "", string[] singleLineCommentPrefixes = ["//"]) { + _singleLineCommentPrefixes = singleLineCommentPrefixes; + _filename = filename; + _lines = LineStream.create(source, filename); + _lineText = _lines.readLine(); + _len = cast(int)_lineText.length; + _line = 0; + _pos = 0; + _prevChar = 0; + } + + ~this() { + destroy(_lines); + _lines = null; + } + + protected dchar peekChar() { + if (_pos < _len) + return _lineText[_pos]; + else if (_lineText is null) + return EOF_CHAR; + return EOL_CHAR; + } + + protected dchar peekNextChar() { + if (_pos < _len - 1) + return _lineText[_pos + 1]; + else if (_lineText is null) + return EOF_CHAR; + return EOL_CHAR; + } + + protected dchar nextChar() { + if (_pos < _len) + _prevChar = _lineText[_pos++]; + else if (_lineText is null) + _prevChar = EOF_CHAR; + else { + _lineText = _lines.readLine(); + _len = cast(int)_lineText.length; + _line++; + _pos = 0; + _prevChar = EOL_CHAR; + } + return _prevChar; + } + + protected dchar skipChar() { + nextChar(); + return peekChar(); + } + + protected void setTokenStart() { + _token.pos = _pos; + _token.line = _line; + _token.text = null; + _token.intvalue = 0; + } + + protected ref const(Token) parseEof() { + _token.type = TokenType.eof; + return _token; + } + + protected ref const(Token) parseEol() { + _token.type = TokenType.eol; + nextChar(); + return _token; + } + + protected ref const(Token) parseWhiteSpace() { + _token.type = TokenType.whitespace; + for(;;) { + dchar ch = skipChar(); + if (ch != ' ' && ch != '\t') + break; + } + return _token; + } + + static bool isAlpha(dchar ch) { + return (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || ch == '_'; + } + + static bool isNum(dchar ch) { + return (ch >= '0' && ch <= '9'); + } + + static bool isAlphaNum(dchar ch) { + return isNum(ch) || isAlpha(ch); + } + + private char[] _stringbuf; + protected ref const(Token) parseString() { + _token.type = TokenType.str; + //skipChar(); // skip " + bool lastBackslash = false; + _stringbuf.length = 0; + for(;;) { + dchar ch = skipChar(); + if (ch == '\"') { + if (lastBackslash) { + _stringbuf ~= ch; + lastBackslash = false; + } else { + skipChar(); + break; + } + } else if (ch == '\\') { + if (lastBackslash) { + _stringbuf ~= ch; + lastBackslash = false; + } else { + lastBackslash = true; + } + } else if (ch == EOL_CHAR) { + skipChar(); + break; + } else if (lastBackslash) { + if (ch == 'n') + ch = '\n'; + else if (ch == 't') + ch = '\t'; + _stringbuf ~= ch; + lastBackslash = false; + } else { + _stringbuf ~= ch; + lastBackslash = false; + } + } + _token.text = _stringbuf.dup; + return _token; + } + + protected ref const(Token) parseIdent() { + _token.type = TokenType.ident; + _stringbuf.length = 0; + _stringbuf ~= peekChar(); + for(;;) { + dchar ch = skipChar(); + if (!isAlphaNum(ch)) + break; + _stringbuf ~= ch; + } + _token.text = _stringbuf.dup; + return _token; + } + + protected ref const(Token) parseFloating(int n) { + _token.type = TokenType.floating; + dchar ch = peekChar(); + // floating point + int div = 1; + int n2 = 0; + for (;;) { + ch = skipChar(); + if (!isNum(ch)) + break; + n2 = n2 * 10 + (ch - '0'); + div *= 10; + } + _token.floatvalue = cast(double)n + (div > 0 ? cast(double)n2 / div : 0.0); + string suffix; + if (ch == '%') { + suffix ~= ch; + ch = skipChar(); + } else { + while (ch >= 'a' && ch <= 'z') { + suffix ~= ch; + ch = skipChar(); + } + } + if (isAlphaNum(ch) || ch == '.') + return parseError(); + _token.text = suffix; + return _token; + } + + protected ref const(Token) parseHex(int prefixLen) { + dchar ch = 0; + foreach(i; 0 .. prefixLen) + ch = skipChar(); + + uint n = parseHexDigit(ch); + if (n == uint.max) + return parseError(); + + for(;;) { + ch = skipChar(); + uint digit = parseHexDigit(ch); + if (digit == uint.max) + break; + n = (n << 4) + digit; + } + string suffix; + if (ch == '%') { + suffix ~= ch; + ch = skipChar(); + } else { + while (ch >= 'a' && ch <= 'z') { + suffix ~= ch; + ch = skipChar(); + } + } + if (isAlphaNum(ch) || ch == '.') + return parseError(); + _token.type = TokenType.integer; + _token.intvalue = n; + _token.text = suffix; + return _token; + } + + protected ref const(Token) parseNumber() { + dchar ch = peekChar(); + uint n = ch - '0'; + for(;;) { + ch = skipChar(); + if (!isNum(ch)) + break; + n = n * 10 + (ch - '0'); + } + if (ch == '.') + return parseFloating(n); + string suffix; + if (ch == '%') { + suffix ~= ch; + ch = skipChar(); + } else { + while (ch >= 'a' && ch <= 'z') { + suffix ~= ch; + ch = skipChar(); + } + } + if (isAlphaNum(ch) || ch == '.') + return parseError(); + _token.type = TokenType.integer; + _token.intvalue = n; + _token.text = suffix; + return _token; + } + + protected ref const(Token) parseSingleLineComment() { + for(;;) { + dchar ch = skipChar(); + if (ch == EOL_CHAR || ch == EOF_CHAR) + break; + } + _token.type = TokenType.comment; + _token.multiline = false; + return _token; + } + + protected ref const(Token) parseMultiLineComment() { + skipChar(); + for(;;) { + dchar ch = skipChar(); + if (ch == '*' && peekNextChar() == '/') { + skipChar(); + skipChar(); + break; + } + if (ch == EOF_CHAR) + break; + } + _token.type = TokenType.comment; + _token.multiline = true; + return _token; + } + + protected ref const(Token) parseError() { + _token.type = TokenType.error; + for(;;) { + dchar ch = skipChar(); + if (ch == ' ' || ch == '\t' || ch == EOL_CHAR || ch == EOF_CHAR) + break; + } + return _token; + } + + protected ref const(Token) parseOp(TokenType op) { + _token.type = op; + skipChar(); + return _token; + } + + /// get next token + ref const(Token) nextToken() { + setTokenStart(); + dchar ch = peekChar(); + if (ch == EOF_CHAR) + return parseEof(); + if (ch == EOL_CHAR) + return parseEol(); + if (ch == ' ' || ch == '\t') + return parseWhiteSpace(); + if (ch == '\"') + return parseString(); + if (isAlpha(ch)) + return parseIdent(); + if (ch == '0' && peekNextChar == 'x') + return parseHex(2); + if (ch == '#') + return parseHex(1); + if (isNum(ch)) + return parseNumber(); + if (ch == '.' && isNum(peekNextChar())) + return parseFloating(0); + foreach(prefix; _singleLineCommentPrefixes) { + if (ch == prefix[0] && (prefix.length == 1 || peekNextChar() == prefix[1])) + return parseSingleLineComment(); + } + if (ch == '/' && peekNextChar() == '*') + return parseMultiLineComment(); + switch (ch) { + case '.': return parseOp(TokenType.dot); + case ':': return parseOp(TokenType.colon); + case ';': return parseOp(TokenType.semicolon); + case ',': return parseOp(TokenType.comma); + case '-': return parseOp(TokenType.minus); + case '+': return parseOp(TokenType.plus); + case '{': return parseOp(TokenType.curlyOpen); + case '}': return parseOp(TokenType.curlyClose); + case '(': return parseOp(TokenType.open); + case ')': return parseOp(TokenType.close); + case '[': return parseOp(TokenType.squareOpen); + case ']': return parseOp(TokenType.squareClose); + case '/': return parseOp(TokenType.divide); + default: + return parseError(); + } + } + + string getContextSource() { + string s = toUTF8(_lineText); + if (_pos == 0) + return " near `^^^" ~ s[0..min($,30)] ~ "`"; + if (_pos >= _len) + return " near `" ~ s[max(_len - 30, 0) .. $] ~ "^^^`"; + return " near `" ~ s[max(_pos - 15, 0) .. _pos] ~ "^^^" ~ s[_pos .. min(_pos + 15, $)] ~ "`"; + } + + @property string filename() { + return filename; + } + @property int line() { + return _token.line; + } + @property int pos() { + return _token.pos; + } + + void emitError(string msg) { + throw new ParserException(msg ~ getContextSource(), _filename, _token.line, _token.pos); + } + + void emitError(string msg, ref const Token token) { + throw new ParserException(msg, _filename, token.line, token.pos); + } +} + +/// tokenize source into array of tokens (excluding EOF) +public Token[] tokenize(string code, string[] _singleLineCommentPrefixes = ["//"]) { + Token[] res; + auto tokenizer = new Tokenizer(code, ""); + for (;;) { + auto token = tokenizer.nextToken(); + if (token.type == TokenType.eof) + break; + res ~= token; + } + return res; +} + +/// exclude whitespace tokens at beginning and end of token sequence +Token[] trimSpaceTokens(Token[] tokens, bool trimBeginning = true, bool trimEnd = true) { + if (trimBeginning) + while(tokens.length > 0 && tokens[0].type == TokenType.whitespace) + tokens = tokens[1 .. $]; + if (trimEnd) + while(tokens.length > 0 && tokens[$ - 1].type == TokenType.whitespace) + tokens = tokens[0 .. $ - 1]; + return tokens; +} diff --git a/src/dlangui/graphics/scene/objimport.d b/src/dlangui/graphics/scene/objimport.d new file mode 100644 index 00000000..b2ccf256 --- /dev/null +++ b/src/dlangui/graphics/scene/objimport.d @@ -0,0 +1,194 @@ +module dlangui.graphics.scene.objimport; + +import dlangui.core.logger; +import dlangui.dml.tokenizer; + +struct ObjModelImport { + alias FaceIndex = int[3]; + + private float[] _vertexData; + private float[] _normalData; + private float[] _txData; + private int _vertexCount; + private int _normalCount; + private int _triangleCount; + private int _txCount; + private float[8] _buf; + protected float[] parseFloatList(Token[] tokens, int maxItems = 3, float padding = 0) { + int i = 0; + foreach(t; tokens) { + if (i >= maxItems) + break; + if (t.type == TokenType.floating) + _buf[i++] = cast(float)t.floatvalue; + else if (t.type == TokenType.integer) + _buf[i++] = cast(float)t.intvalue; + } + while(i < maxItems) + _buf[i++] = padding; + if (i > 0) + return _buf[0 .. i]; + return null; + } + //# List of geometric vertices, with (x,y,z[,w]) coordinates, w is optional and defaults to 1.0. + //v 0.123 0.234 0.345 1.0 + protected bool parseVertexLine(Token[] tokens) { + float[] data = parseFloatList(tokens, 3, 0); + if (data.length == 3) { + _vertexData ~= data; + _vertexCount++; + return true; + } + return false; + } + //# List of texture coordinates, in (u, v [,w]) coordinates, these will vary between 0 and 1, w is optional and defaults to 0. + //vt 0.500 1 [0] + protected bool parseVertexTextureLine(Token[] tokens) { + float[] data = parseFloatList(tokens, 2, 0); + if (data.length == 2) { + _txData ~= data; + _txCount++; + return true; + } + return false; + } + //# List of vertex normals in (x,y,z) form; normals might not be unit vectors. + //vn 0.707 0.000 0.707 + protected bool parseVertexNormalsLine(Token[] tokens) { + float[] data = parseFloatList(tokens, 3, 0); + if (data.length == 3) { + _normalData ~= data; + _normalCount++; + return true; + } + return false; + } + + static protected bool skipToken(ref Token[] tokens) { + tokens = tokens.length > 1 ? tokens[1 .. $] : null; + return tokens.length > 0; + } + static protected bool parseIndex(ref Token[] tokens, ref int data) { + int sign = 1; + if (tokens[0].type == TokenType.minus) { + sign = -1; + skipToken(tokens); + } + if (tokens[0].type == TokenType.integer) { + data = tokens[0].intvalue * sign; + skipToken(tokens); + return true; + } + return false; + } + static protected bool skip(ref Token[] tokens, TokenType type) { + if (tokens.length > 0 && tokens[0].type == type) { + skipToken(tokens); + return true; + } + return false; + } + static protected bool parseFaceIndex(ref Token[] tokens, ref FaceIndex data) { + int i = 0; + if (tokens.length == 0) + return false; + if (!parseIndex(tokens, data[0])) + return false; + if (skip(tokens, TokenType.divide)) { + parseIndex(tokens, data[1]); + if (skip(tokens, TokenType.divide)) { + if (!parseIndex(tokens, data[2])) + return false; + } + } + return tokens.length == 0 || skip(tokens, TokenType.whitespace); + } + //# Parameter space vertices in ( u [,v] [,w] ) form; free form geometry statement ( see below ) + //vp 0.310000 3.210000 2.100000 + protected bool parseParameterSpaceLine(Token[] tokens) { + // not supported + + return true; + } + + //f 1 2 3 + //f 3/1 4/2 5/3 + //f 6/4/1 3/5/3 7/6/5 + protected bool parseFaceLine(Token[] tokens) { + FaceIndex[10] indexes; + int i = 0; + while(parseFaceIndex(tokens, indexes[i])) { + if (++i >= 10) + break; + } + for (int j = 1; j + 1 < i; j++) + addTriangle(indexes[0], indexes[j], indexes[j + 1]); + return true; + } + + protected bool addTriangle(FaceIndex v1, FaceIndex v2, FaceIndex v3) { + _triangleCount++; + return true; + } + + protected bool parseLine(Token[] tokens) { + tokens = trimSpaceTokens(tokens); + if (tokens.length) { + if (tokens[0].type == TokenType.comment) + return true; // ignore comment + if (tokens[0].type == TokenType.ident) { + string ident = tokens[0].text; + tokens = trimSpaceTokens(tokens[1 .. $], true, false); + if (ident == "v") // vertex + return parseVertexLine(tokens); + if (ident == "vt") // texture coords + return parseVertexTextureLine(tokens); + if (ident == "vn") // normals + return parseVertexNormalsLine(tokens); + if (ident == "vp") // parameter space + return parseParameterSpaceLine(tokens); + if (ident == "f") // face + return parseFaceLine(tokens); + } + } + return true; + } + bool parse(string source) { + import dlangui.dml.tokenizer; + try { + Token[] tokens = tokenize(source, ["#"]); + int start = 0; + int i = 0; + for ( ; i <= tokens.length; i++) { + if (i == tokens.length || tokens[i].type == TokenType.eol) { + if (i > start && !parseLine(tokens[start .. i])) + return false; + start = i + 1; + } + } + } catch (ParserException e) { + Log.d("failed to tokenize OBJ source", e); + return false; + } + return true; + } + +} + +// load text resource +string loadTextResource(string resourceId) { + import dlangui.graphics.resources; + import std.string : endsWith; + string filename; + filename = drawableCache.findResource(resourceId); + if (!filename) { + Log.e("Object resource file not found for resourceId ", resourceId); + assert(false); + } + string s = cast(string)loadResourceBytes(filename); + if (!s) { + Log.e("Cannot read shader source resource ", resourceId, " from file ", filename); + assert(false); + } + return s; +}