summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndy Nichols <andy.nichols@theqtcompany.com>2015-07-15 23:39:58 +0200
committerAndy Nichols <andy.nichols@theqtcompany.com>2015-08-08 12:55:31 +0000
commit473bd13ed373c4cc24bdd3211ee90a070a466ce2 (patch)
tree4dbfd0bc5ea908a3feb20fed8ad5242c6cef56bb
parenta1a7e3661bce196a633ef3edd7d905c215bf9031 (diff)
Add support for loading scenes from glTF 0.8 files
This patch includes a new scene parser plugin which enables the loading of glTF files (using the 0.8 spec) into Qt3D scenes. The gltf example has been updated to work with the current APIs and the asset files it used have been updated to match the glTF 0.8 spec requrements. Previously an unused copy of the GLTF scene parser was located in render/io. It was being built, but not used as only plugin based sceneloaders were loaded by the renderer. Now it should be usable and always available. Change-Id: Ic2e31e2b63a871559aad9bad90ec2820988a1571 Reviewed-by: Laszlo Agocs <laszlo.agocs@theqtcompany.com>
-rw-r--r--[-rwxr-xr-x]examples/qt3d/exampleresources/assets/gltf/wine/wine.binbin329004 -> 329088 bytes
-rw-r--r--[-rwxr-xr-x]examples/qt3d/exampleresources/assets/gltf/wine/wine.gltf (renamed from examples/qt3d/exampleresources/assets/gltf/wine/wine.json)1217
-rw-r--r--examples/qt3d/exampleresources/assets/gltf/wine/wine0FS.glsl30
-rw-r--r--examples/qt3d/exampleresources/assets/gltf/wine/wine0VS.glsl23
-rw-r--r--examples/qt3d/exampleresources/assets/gltf/wine/wine1FS.glsl17
-rw-r--r--examples/qt3d/exampleresources/assets/gltf/wine/wine1VS.glsl12
-rw-r--r--examples/qt3d/exampleresources/assets/gltf/wine/wine2FS.glsl25
-rw-r--r--examples/qt3d/exampleresources/assets/gltf/wine/wine2VS.glsl15
-rw-r--r--examples/qt3d/exampleresources/assets/gltf/wine/wine3FS.glsl16
-rw-r--r--examples/qt3d/exampleresources/assets/gltf/wine/wine3VS.glsl12
-rw-r--r--examples/qt3d/exampleresources/assets/gltf/wine/wine4FS.glsl20
-rw-r--r--examples/qt3d/exampleresources/assets/gltf/wine/wine4VS.glsl17
-rw-r--r--examples/qt3d/exampleresources/gltf.qrc8
-rw-r--r--examples/qt3d/gltf/Wine.qml77
-rw-r--r--examples/qt3d/gltf/basic.frag12
-rw-r--r--examples/qt3d/gltf/basic.vert18
-rw-r--r--examples/qt3d/gltf/gltf.pro4
-rw-r--r--examples/qt3d/gltf/gltf_example.qrc3
-rw-r--r--examples/qt3d/gltf/main.qml164
-rw-r--r--src/plugins/sceneparsers/gltf/gltf.pro12
-rw-r--r--src/plugins/sceneparsers/gltf/gltfparser.cpp1345
-rw-r--r--src/plugins/sceneparsers/gltf/gltfparser_p.h (renamed from src/render/io/gltfparser_p.h)141
-rw-r--r--src/plugins/sceneparsers/sceneparsers.pro2
-rw-r--r--src/render/frontend/qabstractsceneloader.cpp1
-rw-r--r--src/render/io/gltfparser.cpp1110
-rw-r--r--src/render/io/render-io.pri2
26 files changed, 2413 insertions, 1890 deletions
diff --git a/examples/qt3d/exampleresources/assets/gltf/wine/wine.bin b/examples/qt3d/exampleresources/assets/gltf/wine/wine.bin
index 7c8093c5a..c43dfb43a 100755..100644
--- a/examples/qt3d/exampleresources/assets/gltf/wine/wine.bin
+++ b/examples/qt3d/exampleresources/assets/gltf/wine/wine.bin
Binary files differ
diff --git a/examples/qt3d/exampleresources/assets/gltf/wine/wine.json b/examples/qt3d/exampleresources/assets/gltf/wine/wine.gltf
index bdff245d5..39e139779 100755..100644
--- a/examples/qt3d/exampleresources/assets/gltf/wine/wine.json
+++ b/examples/qt3d/exampleresources/assets/gltf/wine/wine.gltf
@@ -1,9 +1,140 @@
{
"accessors": {
- "attribute_120": {
- "bufferView": "bufferView_408",
- "byteOffset": 38592,
+ "accessor_10": {
+ "bufferView": "bufferView_428",
+ "byteOffset": 9272,
+ "byteStride": 0,
+ "componentType": 5123,
+ "count": 2,
+ "type": "SCALAR"
+ },
+ "accessor_101": {
+ "bufferView": "bufferView_429",
+ "byteOffset": 20400,
"byteStride": 12,
+ "componentType": 5126,
+ "count": 720,
+ "max": [
+ 16.8,
+ 19.5,
+ 0.75
+ ],
+ "min": [
+ 1.4,
+ -0,
+ 0
+ ],
+ "type": "VEC3"
+ },
+ "accessor_103": {
+ "bufferView": "bufferView_429",
+ "byteOffset": 29040,
+ "byteStride": 12,
+ "componentType": 5126,
+ "count": 720,
+ "max": [
+ 1,
+ 1,
+ 1
+ ],
+ "min": [
+ -1,
+ -1,
+ -1
+ ],
+ "type": "VEC3"
+ },
+ "accessor_12": {
+ "bufferView": "bufferView_429",
+ "byteOffset": 47344,
+ "byteStride": 12,
+ "componentType": 5126,
+ "count": 2,
+ "max": [
+ 24.7369,
+ 1.5,
+ 3.5
+ ],
+ "min": [
+ 24.7369,
+ 1,
+ 3.5
+ ],
+ "type": "VEC3"
+ },
+ "accessor_124": {
+ "bufferView": "bufferView_428",
+ "byteOffset": 8120,
+ "byteStride": 0,
+ "componentType": 5123,
+ "count": 48,
+ "type": "SCALAR"
+ },
+ "accessor_126": {
+ "bufferView": "bufferView_429",
+ "byteOffset": 37680,
+ "byteStride": 12,
+ "componentType": 5126,
+ "count": 30,
+ "max": [
+ 0.5,
+ 21,
+ 46.6166
+ ],
+ "min": [
+ -0.5,
+ 0,
+ 2.5
+ ],
+ "type": "VEC3"
+ },
+ "accessor_128": {
+ "bufferView": "bufferView_429",
+ "byteOffset": 38040,
+ "byteStride": 12,
+ "componentType": 5126,
+ "count": 30,
+ "max": [
+ 1,
+ 1,
+ 1
+ ],
+ "min": [
+ -1,
+ -1,
+ -1
+ ],
+ "type": "VEC3"
+ },
+ "accessor_130": {
+ "bufferView": "bufferView_429",
+ "byteOffset": 38400,
+ "byteStride": 8,
+ "componentType": 5126,
+ "count": 30,
+ "max": [
+ 0.291667,
+ 1
+ ],
+ "min": [
+ -0.291667,
+ 0.352547
+ ],
+ "type": "VEC2"
+ },
+ "accessor_151": {
+ "bufferView": "bufferView_428",
+ "byteOffset": 8216,
+ "byteStride": 0,
+ "componentType": 5123,
+ "count": 360,
+ "type": "SCALAR"
+ },
+ "accessor_153": {
+ "bufferView": "bufferView_429",
+ "byteOffset": 38640,
+ "byteStride": 12,
+ "componentType": 5126,
"count": 176,
"max": [
54,
@@ -15,12 +146,13 @@
0,
0
],
- "type": 35665
+ "type": "VEC3"
},
- "attribute_122": {
- "bufferView": "bufferView_408",
- "byteOffset": 40704,
+ "accessor_155": {
+ "bufferView": "bufferView_429",
+ "byteOffset": 40752,
"byteStride": 12,
+ "componentType": 5126,
"count": 176,
"max": [
1,
@@ -32,12 +164,13 @@
-1,
-1
],
- "type": 35665
+ "type": "VEC3"
},
- "attribute_124": {
- "bufferView": "bufferView_408",
- "byteOffset": 42816,
+ "accessor_157": {
+ "bufferView": "bufferView_429",
+ "byteOffset": 42864,
"byteStride": 8,
+ "componentType": 5126,
"count": 176,
"max": [
8.17898,
@@ -47,12 +180,21 @@
2.31603,
-0.06428
],
- "type": 35664
+ "type": "VEC2"
+ },
+ "accessor_178": {
+ "bufferView": "bufferView_428",
+ "byteOffset": 8936,
+ "byteStride": 0,
+ "componentType": 5123,
+ "count": 168,
+ "type": "SCALAR"
},
- "attribute_147": {
- "bufferView": "bufferView_408",
- "byteOffset": 44224,
+ "accessor_180": {
+ "bufferView": "bufferView_429",
+ "byteOffset": 44272,
"byteStride": 12,
+ "componentType": 5126,
"count": 96,
"max": [
2,
@@ -64,12 +206,13 @@
0,
5.5
],
- "type": 35665
+ "type": "VEC3"
},
- "attribute_149": {
- "bufferView": "bufferView_408",
- "byteOffset": 45376,
+ "accessor_182": {
+ "bufferView": "bufferView_429",
+ "byteOffset": 45424,
"byteStride": 12,
+ "componentType": 5126,
"count": 96,
"max": [
1,
@@ -81,12 +224,13 @@
-1,
-1
],
- "type": 35665
+ "type": "VEC3"
},
- "attribute_151": {
- "bufferView": "bufferView_408",
- "byteOffset": 46528,
+ "accessor_184": {
+ "bufferView": "bufferView_429",
+ "byteOffset": 46576,
"byteStride": 8,
+ "componentType": 5126,
"count": 96,
"max": [
4.15963,
@@ -96,12 +240,21 @@
-1.14777,
-0.08885
],
- "type": 35664
+ "type": "VEC2"
+ },
+ "accessor_205": {
+ "bufferView": "bufferView_428",
+ "byteOffset": 9276,
+ "byteStride": 0,
+ "componentType": 5123,
+ "count": 4740,
+ "type": "SCALAR"
},
- "attribute_174": {
- "bufferView": "bufferView_408",
- "byteOffset": 47296,
+ "accessor_207": {
+ "bufferView": "bufferView_429",
+ "byteOffset": 47368,
"byteStride": 12,
+ "componentType": 5126,
"count": 1968,
"max": [
117.98,
@@ -113,12 +266,13 @@
0,
0
],
- "type": 35665
+ "type": "VEC3"
},
- "attribute_176": {
- "bufferView": "bufferView_408",
- "byteOffset": 70912,
+ "accessor_209": {
+ "bufferView": "bufferView_429",
+ "byteOffset": 70984,
"byteStride": 12,
+ "componentType": 5126,
"count": 1968,
"max": [
0.995313,
@@ -130,12 +284,13 @@
-0.995313,
-0.962469
],
- "type": 35665
+ "type": "VEC3"
},
- "attribute_178": {
- "bufferView": "bufferView_408",
- "byteOffset": 94528,
+ "accessor_211": {
+ "bufferView": "bufferView_429",
+ "byteOffset": 94600,
"byteStride": 8,
+ "componentType": 5126,
"count": 1968,
"max": [
0.855532,
@@ -145,12 +300,55 @@
-0.555297,
0.021103
],
- "type": 35664
+ "type": "VEC2"
},
- "attribute_221": {
- "bufferView": "bufferView_408",
- "byteOffset": 110272,
+ "accessor_22": {
+ "bufferView": "bufferView_428",
+ "byteOffset": 0,
+ "byteStride": 0,
+ "componentType": 5123,
+ "count": 2,
+ "type": "SCALAR"
+ },
+ "accessor_24": {
+ "bufferView": "bufferView_429",
+ "byteOffset": 0,
"byteStride": 12,
+ "componentType": 5126,
+ "count": 2,
+ "max": [
+ 19.7369,
+ 1.5,
+ 3.5
+ ],
+ "min": [
+ 19.7369,
+ 1,
+ 3.5
+ ],
+ "type": "VEC3"
+ },
+ "accessor_249": {
+ "bufferView": "bufferView_428",
+ "byteOffset": 18756,
+ "byteStride": 0,
+ "componentType": 5123,
+ "count": 66,
+ "type": "SCALAR"
+ },
+ "accessor_252": {
+ "bufferView": "bufferView_428",
+ "byteOffset": 18888,
+ "byteStride": 0,
+ "componentType": 5123,
+ "count": 66,
+ "type": "SCALAR"
+ },
+ "accessor_254": {
+ "bufferView": "bufferView_429",
+ "byteOffset": 110344,
+ "byteStride": 12,
+ "componentType": 5126,
"count": 48,
"max": [
82.9854,
@@ -162,12 +360,13 @@
34.9944,
0
],
- "type": 35665
+ "type": "VEC3"
},
- "attribute_223": {
- "bufferView": "bufferView_408",
- "byteOffset": 110848,
+ "accessor_256": {
+ "bufferView": "bufferView_429",
+ "byteOffset": 110920,
"byteStride": 12,
+ "componentType": 5126,
"count": 48,
"max": [
-0,
@@ -179,12 +378,13 @@
0,
-1
],
- "type": 35665
+ "type": "VEC3"
},
- "attribute_225": {
- "bufferView": "bufferView_408",
- "byteOffset": 111424,
+ "accessor_258": {
+ "bufferView": "bufferView_429",
+ "byteOffset": 111496,
"byteStride": 8,
+ "componentType": 5126,
"count": 48,
"max": [
0.642232,
@@ -194,12 +394,21 @@
0.349715,
0.987863
],
- "type": 35664
+ "type": "VEC2"
+ },
+ "accessor_279": {
+ "bufferView": "bufferView_428",
+ "byteOffset": 19020,
+ "byteStride": 0,
+ "componentType": 5123,
+ "count": 360,
+ "type": "SCALAR"
},
- "attribute_248": {
- "bufferView": "bufferView_408",
- "byteOffset": 111808,
+ "accessor_281": {
+ "bufferView": "bufferView_429",
+ "byteOffset": 111880,
"byteStride": 12,
+ "componentType": 5126,
"count": 176,
"max": [
54,
@@ -211,12 +420,13 @@
0,
0
],
- "type": 35665
+ "type": "VEC3"
},
- "attribute_250": {
- "bufferView": "bufferView_408",
- "byteOffset": 113920,
+ "accessor_283": {
+ "bufferView": "bufferView_429",
+ "byteOffset": 113992,
"byteStride": 12,
+ "componentType": 5126,
"count": 176,
"max": [
1,
@@ -228,12 +438,13 @@
-1,
-1
],
- "type": 35665
+ "type": "VEC3"
},
- "attribute_252": {
- "bufferView": "bufferView_408",
- "byteOffset": 116032,
+ "accessor_285": {
+ "bufferView": "bufferView_429",
+ "byteOffset": 116104,
"byteStride": 8,
+ "componentType": 5126,
"count": 176,
"max": [
8.17898,
@@ -243,29 +454,21 @@
2.31603,
-0.06428
],
- "type": 35664
+ "type": "VEC2"
},
- "attribute_26": {
- "bufferView": "bufferView_408",
- "byteOffset": 0,
- "byteStride": 12,
- "count": 96,
- "max": [
- 2,
- 21,
- 38
- ],
- "min": [
- 0,
- 0,
- 5.5
- ],
- "type": 35665
+ "accessor_301": {
+ "bufferView": "bufferView_428",
+ "byteOffset": 19740,
+ "byteStride": 0,
+ "componentType": 5123,
+ "count": 600,
+ "type": "SCALAR"
},
- "attribute_270": {
- "bufferView": "bufferView_408",
- "byteOffset": 117440,
+ "accessor_303": {
+ "bufferView": "bufferView_429",
+ "byteOffset": 117512,
"byteStride": 12,
+ "componentType": 5126,
"count": 224,
"max": [
5,
@@ -277,12 +480,13 @@
0,
0
],
- "type": 35665
+ "type": "VEC3"
},
- "attribute_272": {
- "bufferView": "bufferView_408",
- "byteOffset": 120128,
+ "accessor_305": {
+ "bufferView": "bufferView_429",
+ "byteOffset": 120200,
"byteStride": 12,
+ "componentType": 5126,
"count": 224,
"max": [
1,
@@ -294,29 +498,21 @@
-0.97185,
-0.97185
],
- "type": 35665
+ "type": "VEC3"
},
- "attribute_28": {
- "bufferView": "bufferView_408",
- "byteOffset": 1152,
- "byteStride": 12,
- "count": 96,
- "max": [
- 1,
- 1,
- 1
- ],
- "min": [
- -1,
- -1,
- -1
- ],
- "type": 35665
+ "accessor_326": {
+ "bufferView": "bufferView_428",
+ "byteOffset": 20940,
+ "byteStride": 0,
+ "componentType": 5123,
+ "count": 6918,
+ "type": "SCALAR"
},
- "attribute_295": {
- "bufferView": "bufferView_408",
- "byteOffset": 122816,
+ "accessor_328": {
+ "bufferView": "bufferView_429",
+ "byteOffset": 122888,
"byteStride": 12,
+ "componentType": 5126,
"count": 2933,
"max": [
25.9025,
@@ -328,12 +524,13 @@
0,
0
],
- "type": 35665
+ "type": "VEC3"
},
- "attribute_297": {
- "bufferView": "bufferView_408",
- "byteOffset": 158012,
+ "accessor_330": {
+ "bufferView": "bufferView_429",
+ "byteOffset": 158084,
"byteStride": 12,
+ "componentType": 5126,
"count": 2933,
"max": [
0.999806,
@@ -345,12 +542,13 @@
-0.999806,
-1
],
- "type": 35665
+ "type": "VEC3"
},
- "attribute_299": {
- "bufferView": "bufferView_408",
- "byteOffset": 193208,
+ "accessor_332": {
+ "bufferView": "bufferView_429",
+ "byteOffset": 193280,
"byteStride": 8,
+ "componentType": 5126,
"count": 2933,
"max": [
0.888318,
@@ -360,27 +558,29 @@
-0.595152,
0.013247
],
- "type": 35664
- },
- "attribute_30": {
- "bufferView": "bufferView_408",
- "byteOffset": 2304,
- "byteStride": 8,
- "count": 96,
- "max": [
- 4.15963,
- 1.11374
- ],
- "min": [
- -1.14777,
- -0.08885
- ],
- "type": 35664
+ "type": "VEC2"
+ },
+ "accessor_34": {
+ "bufferView": "bufferView_428",
+ "byteOffset": 4,
+ "byteStride": 0,
+ "componentType": 5123,
+ "count": 2,
+ "type": "SCALAR"
+ },
+ "accessor_348": {
+ "bufferView": "bufferView_428",
+ "byteOffset": 34776,
+ "byteStride": 0,
+ "componentType": 5123,
+ "count": 216,
+ "type": "SCALAR"
},
- "attribute_317": {
- "bufferView": "bufferView_408",
- "byteOffset": 216672,
+ "accessor_350": {
+ "bufferView": "bufferView_429",
+ "byteOffset": 216744,
"byteStride": 12,
+ "componentType": 5126,
"count": 120,
"max": [
0,
@@ -392,12 +592,13 @@
-0,
0
],
- "type": 35665
+ "type": "VEC3"
},
- "attribute_319": {
- "bufferView": "bufferView_408",
- "byteOffset": 218112,
+ "accessor_352": {
+ "bufferView": "bufferView_429",
+ "byteOffset": 218184,
"byteStride": 12,
+ "componentType": 5126,
"count": 120,
"max": [
1,
@@ -409,12 +610,39 @@
-1,
-1
],
- "type": 35665
+ "type": "VEC3"
+ },
+ "accessor_36": {
+ "bufferView": "bufferView_429",
+ "byteOffset": 24,
+ "byteStride": 12,
+ "componentType": 5126,
+ "count": 2,
+ "max": [
+ 119,
+ -0,
+ 34.625
+ ],
+ "min": [
+ 118,
+ -0,
+ 34.625
+ ],
+ "type": "VEC3"
+ },
+ "accessor_373": {
+ "bufferView": "bufferView_428",
+ "byteOffset": 35208,
+ "byteStride": 0,
+ "componentType": 5123,
+ "count": 4740,
+ "type": "SCALAR"
},
- "attribute_342": {
- "bufferView": "bufferView_408",
- "byteOffset": 219552,
+ "accessor_375": {
+ "bufferView": "bufferView_429",
+ "byteOffset": 219624,
"byteStride": 12,
+ "componentType": 5126,
"count": 1968,
"max": [
117.98,
@@ -426,12 +654,13 @@
0,
0
],
- "type": 35665
+ "type": "VEC3"
},
- "attribute_344": {
- "bufferView": "bufferView_408",
- "byteOffset": 243168,
+ "accessor_377": {
+ "bufferView": "bufferView_429",
+ "byteOffset": 243240,
"byteStride": 12,
+ "componentType": 5126,
"count": 1968,
"max": [
0.995313,
@@ -443,12 +672,13 @@
-0.995313,
-0.962469
],
- "type": 35665
+ "type": "VEC3"
},
- "attribute_346": {
- "bufferView": "bufferView_408",
- "byteOffset": 266784,
+ "accessor_379": {
+ "bufferView": "bufferView_429",
+ "byteOffset": 266856,
"byteStride": 8,
+ "componentType": 5126,
"count": 1968,
"max": [
0.855532,
@@ -458,12 +688,29 @@
-0.555297,
0.021103
],
- "type": 35664
+ "type": "VEC2"
},
- "attribute_389": {
- "bufferView": "bufferView_408",
- "byteOffset": 282528,
+ "accessor_417": {
+ "bufferView": "bufferView_428",
+ "byteOffset": 44688,
+ "byteStride": 0,
+ "componentType": 5123,
+ "count": 66,
+ "type": "SCALAR"
+ },
+ "accessor_420": {
+ "bufferView": "bufferView_428",
+ "byteOffset": 44820,
+ "byteStride": 0,
+ "componentType": 5123,
+ "count": 66,
+ "type": "SCALAR"
+ },
+ "accessor_422": {
+ "bufferView": "bufferView_429",
+ "byteOffset": 282600,
"byteStride": 12,
+ "componentType": 5126,
"count": 48,
"max": [
82.9854,
@@ -475,12 +722,13 @@
34.9944,
0
],
- "type": 35665
+ "type": "VEC3"
},
- "attribute_391": {
- "bufferView": "bufferView_408",
- "byteOffset": 283104,
+ "accessor_424": {
+ "bufferView": "bufferView_429",
+ "byteOffset": 283176,
"byteStride": 12,
+ "componentType": 5126,
"count": 48,
"max": [
-0,
@@ -492,12 +740,13 @@
0,
-1
],
- "type": 35665
+ "type": "VEC3"
},
- "attribute_393": {
- "bufferView": "bufferView_408",
- "byteOffset": 283680,
+ "accessor_426": {
+ "bufferView": "bufferView_429",
+ "byteOffset": 283752,
"byteStride": 8,
+ "componentType": 5126,
"count": 48,
"max": [
0.642232,
@@ -507,30 +756,40 @@
0.349715,
0.987863
],
- "type": 35664
+ "type": "VEC2"
+ },
+ "accessor_57": {
+ "bufferView": "bufferView_428",
+ "byteOffset": 8,
+ "byteStride": 0,
+ "componentType": 5123,
+ "count": 168,
+ "type": "SCALAR"
},
- "attribute_48": {
- "bufferView": "bufferView_408",
- "byteOffset": 3072,
+ "accessor_59": {
+ "bufferView": "bufferView_429",
+ "byteOffset": 48,
"byteStride": 12,
- "count": 720,
+ "componentType": 5126,
+ "count": 96,
"max": [
- 16.8,
- 19.5,
- 0.75
+ 2,
+ 21,
+ 38
],
"min": [
- 1.4,
- -0,
- 0
+ 0,
+ 0,
+ 5.5
],
- "type": 35665
+ "type": "VEC3"
},
- "attribute_50": {
- "bufferView": "bufferView_408",
- "byteOffset": 11712,
+ "accessor_61": {
+ "bufferView": "bufferView_429",
+ "byteOffset": 1200,
"byteStride": 12,
- "count": 720,
+ "componentType": 5126,
+ "count": 96,
"max": [
1,
1,
@@ -541,12 +800,37 @@
-1,
-1
],
- "type": 35665
+ "type": "VEC3"
},
- "attribute_68": {
- "bufferView": "bufferView_408",
- "byteOffset": 20352,
+ "accessor_63": {
+ "bufferView": "bufferView_429",
+ "byteOffset": 2352,
+ "byteStride": 8,
+ "componentType": 5126,
+ "count": 96,
+ "max": [
+ 4.15963,
+ 1.11374
+ ],
+ "min": [
+ -1.14777,
+ -0.08885
+ ],
+ "type": "VEC2"
+ },
+ "accessor_79": {
+ "bufferView": "bufferView_428",
+ "byteOffset": 344,
+ "byteStride": 0,
+ "componentType": 5123,
+ "count": 1944,
+ "type": "SCALAR"
+ },
+ "accessor_81": {
+ "bufferView": "bufferView_429",
+ "byteOffset": 3120,
"byteStride": 12,
+ "componentType": 5126,
"count": 720,
"max": [
16.8,
@@ -558,12 +842,13 @@
-0,
0
],
- "type": 35665
+ "type": "VEC3"
},
- "attribute_70": {
- "bufferView": "bufferView_408",
- "byteOffset": 28992,
+ "accessor_83": {
+ "bufferView": "bufferView_429",
+ "byteOffset": 11760,
"byteStride": 12,
+ "componentType": 5126,
"count": 720,
"max": [
1,
@@ -575,182 +860,43 @@
-1,
-1
],
- "type": 35665
- },
- "attribute_93": {
- "bufferView": "bufferView_408",
- "byteOffset": 37632,
- "byteStride": 12,
- "count": 30,
- "max": [
- 0.5,
- 21,
- 46.6166
- ],
- "min": [
- -0.5,
- 0,
- 2.5
- ],
- "type": 35665
- },
- "attribute_95": {
- "bufferView": "bufferView_408",
- "byteOffset": 37992,
- "byteStride": 12,
- "count": 30,
- "max": [
- 1,
- 1,
- 1
- ],
- "min": [
- -1,
- -1,
- -1
- ],
- "type": 35665
- },
- "attribute_97": {
- "bufferView": "bufferView_408",
- "byteOffset": 38352,
- "byteStride": 8,
- "count": 30,
- "max": [
- 0.291667,
- 1
- ],
- "min": [
- -0.291667,
- 0.352547
- ],
- "type": 35664
- },
- "indices_118": {
- "bufferView": "bufferView_409",
- "byteOffset": 8208,
- "count": 360,
- "type": 5123
- },
- "indices_145": {
- "bufferView": "bufferView_409",
- "byteOffset": 8928,
- "count": 168,
- "type": 5123
- },
- "indices_172": {
- "bufferView": "bufferView_409",
- "byteOffset": 9264,
- "count": 4740,
- "type": 5123
- },
- "indices_216": {
- "bufferView": "bufferView_409",
- "byteOffset": 18744,
- "count": 66,
- "type": 5123
- },
- "indices_219": {
- "bufferView": "bufferView_409",
- "byteOffset": 18876,
- "count": 66,
- "type": 5123
- },
- "indices_24": {
- "bufferView": "bufferView_409",
- "byteOffset": 0,
- "count": 168,
- "type": 5123
- },
- "indices_246": {
- "bufferView": "bufferView_409",
- "byteOffset": 19008,
- "count": 360,
- "type": 5123
+ "type": "VEC3"
},
- "indices_268": {
- "bufferView": "bufferView_409",
- "byteOffset": 19728,
- "count": 600,
- "type": 5123
- },
- "indices_293": {
- "bufferView": "bufferView_409",
- "byteOffset": 20928,
- "count": 6918,
- "type": 5123
- },
- "indices_315": {
- "bufferView": "bufferView_409",
- "byteOffset": 34764,
- "count": 216,
- "type": 5123
- },
- "indices_340": {
- "bufferView": "bufferView_409",
- "byteOffset": 35196,
- "count": 4740,
- "type": 5123
- },
- "indices_384": {
- "bufferView": "bufferView_409",
- "byteOffset": 44676,
- "count": 66,
- "type": 5123
- },
- "indices_387": {
- "bufferView": "bufferView_409",
- "byteOffset": 44808,
- "count": 66,
- "type": 5123
- },
- "indices_46": {
- "bufferView": "bufferView_409",
- "byteOffset": 336,
+ "accessor_99": {
+ "bufferView": "bufferView_428",
+ "byteOffset": 4232,
+ "byteStride": 0,
+ "componentType": 5123,
"count": 1944,
- "type": 5123
- },
- "indices_66": {
- "bufferView": "bufferView_409",
- "byteOffset": 4224,
- "count": 1944,
- "type": 5123
- },
- "indices_91": {
- "bufferView": "bufferView_409",
- "byteOffset": 8112,
- "count": 48,
- "type": 5123
+ "type": "SCALAR"
}
},
"animations": {},
"asset": {
- "generator": "collada2gltf@75061f683116dc0ffdad48f33c226e933132e98c"
+ "generator": "collada2gltf@f356b99aef8868f74877c7ca545f2cd206b9d3b7",
+ "premultipliedAlpha": true,
+ "profile": "WebGL 1.0.2",
+ "version": 0.8
},
"bufferViews": {
- "bufferView_408": {
+ "bufferView_428": {
"buffer": "wine",
- "byteLength": 284064,
+ "byteLength": 44952,
"byteOffset": 0,
- "target": 34962
- },
- "bufferView_409": {
- "buffer": "wine",
- "byteLength": 44940,
- "byteOffset": 284064,
"target": 34963
},
- "bufferView_410": {
+ "bufferView_429": {
"buffer": "wine",
- "byteLength": 0,
- "byteOffset": 329004
+ "byteLength": 284136,
+ "byteOffset": 44952,
+ "target": 34962
}
},
"buffers": {
"wine": {
- "byteLength": 329004,
- "path": "wine.bin",
- "type": "arraybuffer"
+ "byteLength": 329088,
+ "type": "arraybuffer",
+ "uri": "wine.bin"
}
},
"cameras": {
@@ -764,14 +910,14 @@
}
},
"images": {
- "image_0": {
- "path": "artezin_bottle.jpg"
+ "ID140": {
+ "uri": "artezin_bottle.jpg"
},
- "image_1": {
- "path": "Wood_Cherry_Original_.jpg"
+ "ID7": {
+ "uri": "Wood_Cherry_Original_.jpg"
},
- "image_2": {
- "path": "_2004_old_vine_zinfandel_btl_xlg.jpg"
+ "ID78": {
+ "uri": "_2004_old_vine_zinfandel_btl_xlg.jpg"
}
},
"materials": {
@@ -785,7 +931,7 @@
0.2,
1
],
- "diffuse": "texture_image_0"
+ "diffuse": "texture_ID140"
}
},
"name": "artezin_bottle"
@@ -811,6 +957,20 @@
},
"name": "material_5"
},
+ "ID217": {
+ "instanceTechnique": {
+ "technique": "technique3",
+ "values": {}
+ },
+ "name": "edge_color683818255"
+ },
+ "ID227": {
+ "instanceTechnique": {
+ "technique": "technique3",
+ "values": {}
+ },
+ "name": "edge_color353535255"
+ },
"ID6": {
"instanceTechnique": {
"technique": "technique1",
@@ -821,7 +981,7 @@
0.2,
1
],
- "diffuse": "texture_image_1"
+ "diffuse": "texture_ID7"
}
},
"name": "Wood_Cherry_Original_"
@@ -836,14 +996,14 @@
0.2,
1
],
- "diffuse": "texture_image_2"
+ "diffuse": "texture_ID78"
}
},
"name": "_2004_old_vine_zinfandel_btl_xlg"
},
"ID89": {
"instanceTechnique": {
- "technique": "technique3",
+ "technique": "technique4",
"values": {
"ambient": [
0.2,
@@ -863,16 +1023,42 @@
}
},
"meshes": {
+ "geometry10": {
+ "name": "geometry10",
+ "primitives": [
+ {
+ "attributes": {
+ "POSITION": "accessor_24"
+ },
+ "indices": "accessor_22",
+ "material": "ID217",
+ "primitive": 1
+ }
+ ]
+ },
+ "geometry13": {
+ "name": "geometry13",
+ "primitives": [
+ {
+ "attributes": {
+ "POSITION": "accessor_36"
+ },
+ "indices": "accessor_34",
+ "material": "ID227",
+ "primitive": 1
+ }
+ ]
+ },
"geometry16": {
"name": "geometry16",
"primitives": [
{
"attributes": {
- "NORMAL": "attribute_28",
- "POSITION": "attribute_26",
- "TEXCOORD_0": "attribute_30"
+ "NORMAL": "accessor_61",
+ "POSITION": "accessor_59",
+ "TEXCOORD_0": "accessor_63"
},
- "indices": "indices_24",
+ "indices": "accessor_57",
"material": "ID6",
"primitive": 4
}
@@ -883,10 +1069,10 @@
"primitives": [
{
"attributes": {
- "NORMAL": "attribute_50",
- "POSITION": "attribute_48"
+ "NORMAL": "accessor_83",
+ "POSITION": "accessor_81"
},
- "indices": "indices_46",
+ "indices": "accessor_79",
"material": "ID21",
"primitive": 4
}
@@ -897,10 +1083,10 @@
"primitives": [
{
"attributes": {
- "NORMAL": "attribute_70",
- "POSITION": "attribute_68"
+ "NORMAL": "accessor_103",
+ "POSITION": "accessor_101"
},
- "indices": "indices_66",
+ "indices": "accessor_99",
"material": "ID21",
"primitive": 4
}
@@ -911,11 +1097,11 @@
"primitives": [
{
"attributes": {
- "NORMAL": "attribute_95",
- "POSITION": "attribute_93",
- "TEXCOORD_0": "attribute_97"
+ "NORMAL": "accessor_128",
+ "POSITION": "accessor_126",
+ "TEXCOORD_0": "accessor_130"
},
- "indices": "indices_91",
+ "indices": "accessor_124",
"material": "ID6",
"primitive": 4
}
@@ -926,11 +1112,11 @@
"primitives": [
{
"attributes": {
- "NORMAL": "attribute_122",
- "POSITION": "attribute_120",
- "TEXCOORD_0": "attribute_124"
+ "NORMAL": "accessor_155",
+ "POSITION": "accessor_153",
+ "TEXCOORD_0": "accessor_157"
},
- "indices": "indices_118",
+ "indices": "accessor_151",
"material": "ID6",
"primitive": 4
}
@@ -941,26 +1127,39 @@
"primitives": [
{
"attributes": {
- "NORMAL": "attribute_149",
- "POSITION": "attribute_147",
- "TEXCOORD_0": "attribute_151"
+ "NORMAL": "accessor_182",
+ "POSITION": "accessor_180",
+ "TEXCOORD_0": "accessor_184"
},
- "indices": "indices_145",
+ "indices": "accessor_178",
"material": "ID6",
"primitive": 4
}
]
},
+ "geometry5": {
+ "name": "geometry5",
+ "primitives": [
+ {
+ "attributes": {
+ "POSITION": "accessor_12"
+ },
+ "indices": "accessor_10",
+ "material": "ID217",
+ "primitive": 1
+ }
+ ]
+ },
"geometry51": {
"name": "geometry51",
"primitives": [
{
"attributes": {
- "NORMAL": "attribute_176",
- "POSITION": "attribute_174",
- "TEXCOORD_0": "attribute_178"
+ "NORMAL": "accessor_209",
+ "POSITION": "accessor_207",
+ "TEXCOORD_0": "accessor_211"
},
- "indices": "indices_172",
+ "indices": "accessor_205",
"material": "ID77",
"primitive": 4
}
@@ -971,21 +1170,21 @@
"primitives": [
{
"attributes": {
- "NORMAL": "attribute_223",
- "POSITION": "attribute_221",
- "TEXCOORD_0": "attribute_225"
+ "NORMAL": "accessor_256",
+ "POSITION": "accessor_254",
+ "TEXCOORD_0": "accessor_258"
},
- "indices": "indices_216",
+ "indices": "accessor_249",
"material": "ID89",
"primitive": 4
},
{
"attributes": {
- "NORMAL": "attribute_223",
- "POSITION": "attribute_221",
- "TEXCOORD_0": "attribute_225"
+ "NORMAL": "accessor_256",
+ "POSITION": "accessor_254",
+ "TEXCOORD_0": "accessor_258"
},
- "indices": "indices_219",
+ "indices": "accessor_252",
"material": "ID77",
"primitive": 4
}
@@ -996,11 +1195,11 @@
"primitives": [
{
"attributes": {
- "NORMAL": "attribute_250",
- "POSITION": "attribute_248",
- "TEXCOORD_0": "attribute_252"
+ "NORMAL": "accessor_283",
+ "POSITION": "accessor_281",
+ "TEXCOORD_0": "accessor_285"
},
- "indices": "indices_246",
+ "indices": "accessor_279",
"material": "ID6",
"primitive": 4
}
@@ -1011,10 +1210,10 @@
"primitives": [
{
"attributes": {
- "NORMAL": "attribute_272",
- "POSITION": "attribute_270"
+ "NORMAL": "accessor_305",
+ "POSITION": "accessor_303"
},
- "indices": "indices_268",
+ "indices": "accessor_301",
"material": "ID21",
"primitive": 4
}
@@ -1025,11 +1224,11 @@
"primitives": [
{
"attributes": {
- "NORMAL": "attribute_297",
- "POSITION": "attribute_295",
- "TEXCOORD_0": "attribute_299"
+ "NORMAL": "accessor_330",
+ "POSITION": "accessor_328",
+ "TEXCOORD_0": "accessor_332"
},
- "indices": "indices_293",
+ "indices": "accessor_326",
"material": "ID139",
"primitive": 4
}
@@ -1040,10 +1239,10 @@
"primitives": [
{
"attributes": {
- "NORMAL": "attribute_319",
- "POSITION": "attribute_317"
+ "NORMAL": "accessor_352",
+ "POSITION": "accessor_350"
},
- "indices": "indices_315",
+ "indices": "accessor_348",
"material": "ID21",
"primitive": 4
}
@@ -1054,11 +1253,11 @@
"primitives": [
{
"attributes": {
- "NORMAL": "attribute_344",
- "POSITION": "attribute_342",
- "TEXCOORD_0": "attribute_346"
+ "NORMAL": "accessor_377",
+ "POSITION": "accessor_375",
+ "TEXCOORD_0": "accessor_379"
},
- "indices": "indices_340",
+ "indices": "accessor_373",
"material": "ID77",
"primitive": 4
}
@@ -1069,21 +1268,21 @@
"primitives": [
{
"attributes": {
- "NORMAL": "attribute_391",
- "POSITION": "attribute_389",
- "TEXCOORD_0": "attribute_393"
+ "NORMAL": "accessor_424",
+ "POSITION": "accessor_422",
+ "TEXCOORD_0": "accessor_426"
},
- "indices": "indices_384",
+ "indices": "accessor_417",
"material": "ID89",
"primitive": 4
},
{
"attributes": {
- "NORMAL": "attribute_391",
- "POSITION": "attribute_389",
- "TEXCOORD_0": "attribute_393"
+ "NORMAL": "accessor_424",
+ "POSITION": "accessor_422",
+ "TEXCOORD_0": "accessor_426"
},
- "indices": "indices_387",
+ "indices": "accessor_420",
"material": "ID77",
"primitive": 4
}
@@ -2993,6 +3192,9 @@
0,
1
],
+ "meshes": [
+ "geometry5"
+ ],
"name": "ID215"
},
"ID221": {
@@ -3015,6 +3217,9 @@
0,
1
],
+ "meshes": [
+ "geometry10"
+ ],
"name": "ID221"
},
"ID225": {
@@ -3037,6 +3242,9 @@
0,
1
],
+ "meshes": [
+ "geometry13"
+ ],
"name": "ID225"
},
"ID28": {
@@ -11577,9 +11785,33 @@
"geometry58"
],
"name": "ID88"
+ },
+ "node_424": {
+ "children": [
+ "SketchUp",
+ "default_camera"
+ ],
+ "matrix": [
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1,
+ 0,
+ 0,
+ -1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1
+ ],
+ "name": "Y_UP_Transform"
}
},
- "profile": "WebGL 1.0.2",
"programs": {
"program_0": {
"attributes": [
@@ -11595,16 +11827,23 @@
"a_normal",
"a_position"
],
+ "fragmentShader": "wine1FS",
+ "vertexShader": "wine1VS"
+ },
+ "program_2": {
+ "attributes": [
+ "a_position"
+ ],
"fragmentShader": "wine2FS",
"vertexShader": "wine2VS"
},
- "program_2": {
+ "program_3": {
"attributes": [
"a_normal",
"a_position"
],
- "fragmentShader": "wine4FS",
- "vertexShader": "wine4VS"
+ "fragmentShader": "wine3FS",
+ "vertexShader": "wine3VS"
}
},
"samplers": {
@@ -11619,29 +11858,42 @@
"scenes": {
"defaultScene": {
"nodes": [
- "SketchUp",
- "default_camera"
+ "node_424"
]
}
},
"shaders": {
"wine0FS": {
- "path": "wine0FS.glsl"
+ "type": 35632,
+ "uri": "wine0FS.glsl"
},
"wine0VS": {
- "path": "wine0VS.glsl"
+ "type": 35633,
+ "uri": "wine0VS.glsl"
+ },
+ "wine1FS": {
+ "type": 35632,
+ "uri": "wine1FS.glsl"
+ },
+ "wine1VS": {
+ "type": 35633,
+ "uri": "wine1VS.glsl"
},
"wine2FS": {
- "path": "wine2FS.glsl"
+ "type": 35632,
+ "uri": "wine2FS.glsl"
},
"wine2VS": {
- "path": "wine2VS.glsl"
+ "type": 35633,
+ "uri": "wine2VS.glsl"
},
- "wine4FS": {
- "path": "wine4FS.glsl"
+ "wine3FS": {
+ "type": 35632,
+ "uri": "wine3FS.glsl"
},
- "wine4VS": {
- "path": "wine4VS.glsl"
+ "wine3VS": {
+ "type": 35633,
+ "uri": "wine3VS.glsl"
}
},
"skins": {},
@@ -11717,10 +11969,10 @@
}
},
"states": {
- "blendEnable": 0,
- "cullFaceEnable": 1,
- "depthMask": 1,
- "depthTestEnable": 1
+ "enable": [
+ 2884,
+ 2929
+ ]
}
}
}
@@ -11793,21 +12045,79 @@
}
},
"states": {
- "blendEnable": 1,
- "blendEquation": 32774,
- "blendFunc": {
- "dfactor": 771,
- "sfactor": 770
- },
- "cullFaceEnable": 1,
- "depthMask": 0,
- "depthTestEnable": 1
+ "enable": [
+ 2884,
+ 2929,
+ 3042
+ ],
+ "functions": {
+ "blendEquationSeparate": [
+ 32774,
+ 32774
+ ],
+ "blendFuncSeparate": [
+ 1,
+ 771,
+ 1,
+ 771
+ ]
+ }
}
}
}
},
"technique3": {
"parameters": {
+ "modelViewMatrix": {
+ "semantic": "MODELVIEW",
+ "type": 35676
+ },
+ "position": {
+ "semantic": "POSITION",
+ "type": 35665
+ },
+ "projectionMatrix": {
+ "semantic": "PROJECTION",
+ "type": 35676
+ }
+ },
+ "pass": "defaultPass",
+ "passes": {
+ "defaultPass": {
+ "details": {
+ "commonProfile": {
+ "extras": {
+ "doubleSided": false
+ },
+ "lightingModel": "Constant",
+ "parameters": [
+ "modelViewMatrix",
+ "projectionMatrix"
+ ]
+ },
+ "type": "COLLADA-1.4.1/commonProfile"
+ },
+ "instanceProgram": {
+ "attributes": {
+ "a_position": "position"
+ },
+ "program": "program_2",
+ "uniforms": {
+ "u_modelViewMatrix": "modelViewMatrix",
+ "u_projectionMatrix": "projectionMatrix"
+ }
+ },
+ "states": {
+ "enable": [
+ 2884,
+ 2929
+ ]
+ }
+ }
+ }
+ },
+ "technique4": {
+ "parameters": {
"ambient": {
"type": 35666
},
@@ -11859,7 +12169,7 @@
"a_normal": "normal",
"a_position": "position"
},
- "program": "program_2",
+ "program": "program_3",
"uniforms": {
"u_ambient": "ambient",
"u_diffuse": "diffuse",
@@ -11869,36 +12179,39 @@
}
},
"states": {
- "blendEnable": 0,
- "cullFaceEnable": 1,
- "depthMask": 1,
- "depthTestEnable": 1
+ "enable": [
+ 2884,
+ 2929
+ ]
}
}
}
}
},
"textures": {
- "texture_image_0": {
+ "texture_ID140": {
"format": 6408,
"internalFormat": 6408,
"sampler": "sampler_0",
- "source": "image_0",
- "target": 3553
+ "source": "ID140",
+ "target": 3553,
+ "type": 5121
},
- "texture_image_1": {
+ "texture_ID7": {
"format": 6408,
"internalFormat": 6408,
"sampler": "sampler_0",
- "source": "image_1",
- "target": 3553
+ "source": "ID7",
+ "target": 3553,
+ "type": 5121
},
- "texture_image_2": {
+ "texture_ID78": {
"format": 6408,
"internalFormat": 6408,
"sampler": "sampler_0",
- "source": "image_2",
- "target": 3553
+ "source": "ID78",
+ "target": 3553,
+ "type": 5121
}
}
} \ No newline at end of file
diff --git a/examples/qt3d/exampleresources/assets/gltf/wine/wine0FS.glsl b/examples/qt3d/exampleresources/assets/gltf/wine/wine0FS.glsl
index b01fbb1a1..6e4b7e6d1 100644
--- a/examples/qt3d/exampleresources/assets/gltf/wine/wine0FS.glsl
+++ b/examples/qt3d/exampleresources/assets/gltf/wine/wine0FS.glsl
@@ -1,21 +1,17 @@
-#version 150
-//precision highp float;
-
-in vec3 v_normal;
+precision highp float;
+varying vec3 v_normal;
uniform vec4 u_ambient;
-in vec2 v_texcoord0;
+varying vec2 v_texcoord0;
uniform sampler2D u_diffuse;
-out vec4 fragColor;
-
void main(void) {
- vec3 normal = normalize(v_normal);
- vec4 color = vec4(0., 0., 0., 0.);
- vec4 diffuse = vec4(0., 0., 0., 1.);
- vec4 ambient;
- ambient = u_ambient;
- diffuse = texture(u_diffuse, v_texcoord0);
- diffuse.xyz *= max(dot(normal,vec3(0.,0.,1.)), 0.);
- color.xyz += diffuse.xyz;
- color = vec4(color.rgb * diffuse.a, diffuse.a);
- fragColor = color;
+vec3 normal = normalize(v_normal);
+vec4 color = vec4(0., 0., 0., 0.);
+vec4 diffuse = vec4(0., 0., 0., 1.);
+vec4 ambient;
+ambient = u_ambient;
+diffuse = texture2D(u_diffuse, v_texcoord0);
+diffuse.xyz *= max(dot(normal,vec3(0.,0.,1.)), 0.);
+color.xyz += diffuse.xyz;
+color = vec4(color.rgb * diffuse.a, diffuse.a);
+gl_FragColor = color;
}
diff --git a/examples/qt3d/exampleresources/assets/gltf/wine/wine0VS.glsl b/examples/qt3d/exampleresources/assets/gltf/wine/wine0VS.glsl
index f03b74739..cacc9ed99 100644
--- a/examples/qt3d/exampleresources/assets/gltf/wine/wine0VS.glsl
+++ b/examples/qt3d/exampleresources/assets/gltf/wine/wine0VS.glsl
@@ -1,18 +1,15 @@
-#version 150
-//precision highp float;
-
-in vec3 a_position;
-in vec3 a_normal;
-out vec3 v_normal;
+precision highp float;
+attribute vec3 a_position;
+attribute vec3 a_normal;
+varying vec3 v_normal;
uniform mat3 u_normalMatrix;
uniform mat4 u_modelViewMatrix;
uniform mat4 u_projectionMatrix;
-in vec2 a_texcoord0;
-out vec2 v_texcoord0;
-
+attribute vec2 a_texcoord0;
+varying vec2 v_texcoord0;
void main(void) {
- vec4 pos = u_modelViewMatrix * vec4(a_position,1.0);
- v_normal = normalize(u_normalMatrix * a_normal);
- v_texcoord0 = a_texcoord0;
- gl_Position = u_projectionMatrix * pos;
+vec4 pos = u_modelViewMatrix * vec4(a_position,1.0);
+v_normal = u_normalMatrix * a_normal;
+v_texcoord0 = a_texcoord0;
+gl_Position = u_projectionMatrix * pos;
}
diff --git a/examples/qt3d/exampleresources/assets/gltf/wine/wine1FS.glsl b/examples/qt3d/exampleresources/assets/gltf/wine/wine1FS.glsl
new file mode 100644
index 000000000..d490b4ee7
--- /dev/null
+++ b/examples/qt3d/exampleresources/assets/gltf/wine/wine1FS.glsl
@@ -0,0 +1,17 @@
+precision highp float;
+varying vec3 v_normal;
+uniform vec4 u_ambient;
+uniform vec4 u_diffuse;
+uniform float u_transparency;
+void main(void) {
+vec3 normal = normalize(v_normal);
+vec4 color = vec4(0., 0., 0., 0.);
+vec4 diffuse = vec4(0., 0., 0., 1.);
+vec4 ambient;
+ambient = u_ambient;
+diffuse = u_diffuse;
+diffuse.xyz *= max(dot(normal,vec3(0.,0.,1.)), 0.);
+color.xyz += diffuse.xyz;
+color = vec4(color.rgb * diffuse.a, diffuse.a * u_transparency);
+gl_FragColor = color;
+}
diff --git a/examples/qt3d/exampleresources/assets/gltf/wine/wine1VS.glsl b/examples/qt3d/exampleresources/assets/gltf/wine/wine1VS.glsl
new file mode 100644
index 000000000..9e3592280
--- /dev/null
+++ b/examples/qt3d/exampleresources/assets/gltf/wine/wine1VS.glsl
@@ -0,0 +1,12 @@
+precision highp float;
+attribute vec3 a_position;
+attribute vec3 a_normal;
+varying vec3 v_normal;
+uniform mat3 u_normalMatrix;
+uniform mat4 u_modelViewMatrix;
+uniform mat4 u_projectionMatrix;
+void main(void) {
+vec4 pos = u_modelViewMatrix * vec4(a_position,1.0);
+v_normal = u_normalMatrix * a_normal;
+gl_Position = u_projectionMatrix * pos;
+}
diff --git a/examples/qt3d/exampleresources/assets/gltf/wine/wine2FS.glsl b/examples/qt3d/exampleresources/assets/gltf/wine/wine2FS.glsl
index 72192fee4..b41a6d5fc 100644
--- a/examples/qt3d/exampleresources/assets/gltf/wine/wine2FS.glsl
+++ b/examples/qt3d/exampleresources/assets/gltf/wine/wine2FS.glsl
@@ -1,21 +1,8 @@
-#version 150
-//precision highp float;
-
-in vec3 v_normal;
-uniform vec4 u_ambient;
-uniform vec4 u_diffuse;
-uniform float u_transparency;
-out vec4 fragColor;
-
+precision highp float;
void main(void) {
- vec3 normal = normalize(v_normal);
- vec4 color = vec4(0., 0., 0., 0.);
- vec4 diffuse = vec4(0., 0., 0., 1.);
- vec4 ambient;
- ambient = u_ambient;
- diffuse = u_diffuse;
- diffuse.xyz *= max(dot(normal,vec3(0.,0.,1.)), 0.);
- color.xyz += diffuse.xyz;
- color = vec4(color.rgb * diffuse.a, diffuse.a * u_transparency);
- fragColor = color;
+vec4 color = vec4(0., 0., 0., 0.);
+vec4 diffuse = vec4(0., 0., 0., 1.);
+color.xyz += diffuse.xyz;
+color = vec4(color.rgb * diffuse.a, diffuse.a);
+gl_FragColor = color;
}
diff --git a/examples/qt3d/exampleresources/assets/gltf/wine/wine2VS.glsl b/examples/qt3d/exampleresources/assets/gltf/wine/wine2VS.glsl
index 1b5eabce9..17237bfea 100644
--- a/examples/qt3d/exampleresources/assets/gltf/wine/wine2VS.glsl
+++ b/examples/qt3d/exampleresources/assets/gltf/wine/wine2VS.glsl
@@ -1,15 +1,8 @@
-#version 150
-//precision highp float;
-
-in vec3 a_position;
-in vec3 a_normal;
-out vec3 v_normal;
-uniform mat3 u_normalMatrix;
+precision highp float;
+attribute vec3 a_position;
uniform mat4 u_modelViewMatrix;
uniform mat4 u_projectionMatrix;
-
void main(void) {
- vec4 pos = u_modelViewMatrix * vec4(a_position,1.0);
- v_normal = normalize(u_normalMatrix * a_normal);
- gl_Position = u_projectionMatrix * pos;
+vec4 pos = u_modelViewMatrix * vec4(a_position,1.0);
+gl_Position = u_projectionMatrix * pos;
}
diff --git a/examples/qt3d/exampleresources/assets/gltf/wine/wine3FS.glsl b/examples/qt3d/exampleresources/assets/gltf/wine/wine3FS.glsl
new file mode 100644
index 000000000..79082198c
--- /dev/null
+++ b/examples/qt3d/exampleresources/assets/gltf/wine/wine3FS.glsl
@@ -0,0 +1,16 @@
+precision highp float;
+varying vec3 v_normal;
+uniform vec4 u_ambient;
+uniform vec4 u_diffuse;
+void main(void) {
+vec3 normal = normalize(v_normal);
+vec4 color = vec4(0., 0., 0., 0.);
+vec4 diffuse = vec4(0., 0., 0., 1.);
+vec4 ambient;
+ambient = u_ambient;
+diffuse = u_diffuse;
+diffuse.xyz *= max(dot(normal,vec3(0.,0.,1.)), 0.);
+color.xyz += diffuse.xyz;
+color = vec4(color.rgb * diffuse.a, diffuse.a);
+gl_FragColor = color;
+}
diff --git a/examples/qt3d/exampleresources/assets/gltf/wine/wine3VS.glsl b/examples/qt3d/exampleresources/assets/gltf/wine/wine3VS.glsl
new file mode 100644
index 000000000..9e3592280
--- /dev/null
+++ b/examples/qt3d/exampleresources/assets/gltf/wine/wine3VS.glsl
@@ -0,0 +1,12 @@
+precision highp float;
+attribute vec3 a_position;
+attribute vec3 a_normal;
+varying vec3 v_normal;
+uniform mat3 u_normalMatrix;
+uniform mat4 u_modelViewMatrix;
+uniform mat4 u_projectionMatrix;
+void main(void) {
+vec4 pos = u_modelViewMatrix * vec4(a_position,1.0);
+v_normal = u_normalMatrix * a_normal;
+gl_Position = u_projectionMatrix * pos;
+}
diff --git a/examples/qt3d/exampleresources/assets/gltf/wine/wine4FS.glsl b/examples/qt3d/exampleresources/assets/gltf/wine/wine4FS.glsl
deleted file mode 100644
index 99acdb37c..000000000
--- a/examples/qt3d/exampleresources/assets/gltf/wine/wine4FS.glsl
+++ /dev/null
@@ -1,20 +0,0 @@
-#version 150
-//precision highp float;
-
-in vec3 v_normal;
-uniform vec4 u_ambient;
-uniform vec4 u_diffuse;
-out vec4 fragColor;
-
-void main(void) {
- vec3 normal = normalize(v_normal);
- vec4 color = vec4(0., 0., 0., 0.);
- vec4 diffuse = vec4(0., 0., 0., 1.);
- vec4 ambient;
- ambient = u_ambient;
- diffuse = u_diffuse;
- diffuse.xyz *= max(dot(normal,vec3(0.,0.,1.)), 0.);
- color.xyz += diffuse.xyz;
- color = vec4(color.rgb * diffuse.a, diffuse.a);
- fragColor = color;
-}
diff --git a/examples/qt3d/exampleresources/assets/gltf/wine/wine4VS.glsl b/examples/qt3d/exampleresources/assets/gltf/wine/wine4VS.glsl
deleted file mode 100644
index 0e66d42c1..000000000
--- a/examples/qt3d/exampleresources/assets/gltf/wine/wine4VS.glsl
+++ /dev/null
@@ -1,17 +0,0 @@
-#version 150
-//precision highp float;
-
-in vec3 a_position;
-in vec3 a_normal;
-out vec3 v_normal;
-
-uniform mat3 u_normalMatrix;
-uniform mat4 u_modelViewMatrix;
-uniform mat4 u_projectionMatrix;
-
-void main(void) {
- vec4 pos = u_modelViewMatrix * vec4(a_position,1.0);
- v_normal = normalize(u_normalMatrix * a_normal);
- gl_Position = u_projectionMatrix * pos;
-}
-
diff --git a/examples/qt3d/exampleresources/gltf.qrc b/examples/qt3d/exampleresources/gltf.qrc
index ecc727504..869fb16dc 100644
--- a/examples/qt3d/exampleresources/gltf.qrc
+++ b/examples/qt3d/exampleresources/gltf.qrc
@@ -4,13 +4,15 @@
<file>assets/gltf/wine/artezin_bottle.jpg</file>
<file>assets/gltf/wine/wine.bin</file>
<file>assets/gltf/wine/wine.dae</file>
- <file>assets/gltf/wine/wine.json</file>
<file>assets/gltf/wine/wine0FS.glsl</file>
<file>assets/gltf/wine/wine0VS.glsl</file>
<file>assets/gltf/wine/wine2FS.glsl</file>
<file>assets/gltf/wine/wine2VS.glsl</file>
- <file>assets/gltf/wine/wine4FS.glsl</file>
- <file>assets/gltf/wine/wine4VS.glsl</file>
<file>assets/gltf/wine/Wood_Cherry_Original_.jpg</file>
+ <file>assets/gltf/wine/wine.gltf</file>
+ <file>assets/gltf/wine/wine1FS.glsl</file>
+ <file>assets/gltf/wine/wine1VS.glsl</file>
+ <file>assets/gltf/wine/wine3FS.glsl</file>
+ <file>assets/gltf/wine/wine3VS.glsl</file>
</qresource>
</RCC>
diff --git a/examples/qt3d/gltf/Wine.qml b/examples/qt3d/gltf/Wine.qml
new file mode 100644
index 000000000..4a61c6584
--- /dev/null
+++ b/examples/qt3d/gltf/Wine.qml
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import Qt3D 2.0
+import Qt3D.Renderer 2.0
+
+Entity {
+ id: root
+
+ property alias x: wineTranslate.dx
+ property alias y: wineTranslate.dy
+ property alias z: wineTranslate.dz
+ property alias angleX: rotateX.angle
+ property alias angleY: rotateY.angle
+ property alias angleZ: rotateZ.angle
+ property alias scale: wineScale.scale
+
+ components: [
+ Transform {
+ Rotate {
+ id: rotateX
+ axis: Qt.vector3d(1, 0, 0)
+ }
+ Rotate {
+ id: rotateY
+ axis: Qt.vector3d(0, 1, 0)
+ }
+ Rotate {
+ id: rotateZ
+ axis: Qt.vector3d(0, 0, 1)
+ }
+ Translate {
+ id: wineTranslate
+ }
+ Scale {
+ id: wineScale
+ }
+ },
+ SceneLoader
+ {
+ source: "qrc:/assets/gltf/wine/wine.gltf"
+ }
+ ]
+}
diff --git a/examples/qt3d/gltf/basic.frag b/examples/qt3d/gltf/basic.frag
deleted file mode 100644
index 6f83f6b90..000000000
--- a/examples/qt3d/gltf/basic.frag
+++ /dev/null
@@ -1,12 +0,0 @@
-#version 330
-
-in vec3 color;
-
-out vec4 fragColor;
-
-void main()
-{
- // The color variable is interpolated to this fragment's position
- // for us by OpenGL.
- fragColor = vec4( color, 1.0 );
-}
diff --git a/examples/qt3d/gltf/basic.vert b/examples/qt3d/gltf/basic.vert
deleted file mode 100644
index 0e35affd5..000000000
--- a/examples/qt3d/gltf/basic.vert
+++ /dev/null
@@ -1,18 +0,0 @@
-#version 330
-
-in vec3 vertexPosition;
-in vec3 vertexColor;
-
-uniform mat4 u_projection;
-uniform mat4 u_model;
-
-out vec3 color;
-
-void main()
-{
- // Pass through the color to the fragment shader
- color = vertexColor;
-
- // Calculate the vertex position
- gl_Position = u_projection * u_model * vec4( vertexPosition, 1.0 );
-}
diff --git a/examples/qt3d/gltf/gltf.pro b/examples/qt3d/gltf/gltf.pro
index 5b75283ae..7f65358d5 100644
--- a/examples/qt3d/gltf/gltf.pro
+++ b/examples/qt3d/gltf/gltf.pro
@@ -10,9 +10,9 @@ SOURCES += \
main.cpp
OTHER_FILES += \
- main.qml
+ main.qml \
+ Wine.qml
RESOURCES += \
gltf_example.qrc \
../exampleresources/gltf.qrc \
- ../exampleresources/obj.qrc
diff --git a/examples/qt3d/gltf/gltf_example.qrc b/examples/qt3d/gltf/gltf_example.qrc
index c24519313..0da7ea21f 100644
--- a/examples/qt3d/gltf/gltf_example.qrc
+++ b/examples/qt3d/gltf/gltf_example.qrc
@@ -1,7 +1,6 @@
<RCC>
<qresource prefix="/">
<file>main.qml</file>
- <file>basic.frag</file>
- <file>basic.vert</file>
+ <file>Wine.qml</file>
</qresource>
</RCC>
diff --git a/examples/qt3d/gltf/main.qml b/examples/qt3d/gltf/main.qml
index acce5d7ac..c58aaf5d4 100644
--- a/examples/qt3d/gltf/main.qml
+++ b/examples/qt3d/gltf/main.qml
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Copyright (C) 2015 The Qt Company Ltd and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Qt3D module of the Qt Toolkit.
@@ -36,150 +37,43 @@
import Qt3D 2.0
import Qt3D.Renderer 2.0
-import QtQuick 2.1 as QQ2
Entity {
- id: root
- objectName: "root"
-
- Scene {
- id: wineScene
- source: ":/assets/gltf/wine/wine.json"
-
- Entity {
- transforms: [
- Translate {
- dx: 100
- dy: 0
- dz: -100
- }
-
- ]
-
- property Mesh myMesh: ballmesh
- }
-
- Entity {
- property Mesh myMesh: ballmesh
-
- transforms: [
- Translate {
- dx: 0
- dy: 100
- }
-
- ]
-
- property Material mat: greenMaterial
- }
-
- Entity {
- property Shape myShape: sphere1
-
- transforms: [
- Translate {
- dx: 50
- dy: 50
- }
-
- ]
-
- property Material mat: greenMaterial
-
- Shape {
- id: sphere1
- radius: 25
- rings: 32
- slices: 32
- }
- }
-
- Entity {
- property Shape myShape: torus1
-
- transforms: [
- Translate {
- dx: 50
- dy: 120
- }
-
- ]
-
- property Material mat: blueMaterial
-
- Shape {
- id: torus1
- radius: 40
- minorRadius: 15
- type: Shape.ShapeTorus
- }
- }
-
-
- Entity {
- property Mesh myMesh: ballmesh
-
- transforms: [
- Rotate {
- angle: 45
- axis: Qt.vector3d(0, 1, 0)
- },
-
- Translate {
- dx: 40
- dy: 100
- }
- ]
-
- property Material mat: blueMaterial
- }
+ id: sceneRoot
+
+ Camera {
+ id: camera
+ projectionType: CameraLens.PerspectiveProjection
+ fieldOfView: 45
+ aspectRatio: 16/9
+ nearPlane : 0.1
+ farPlane : 1000.0
+ position: Qt.vector3d( 0.0, 20.0, -120.0 )
+ upVector: Qt.vector3d( 0.0, 1.0, 0.0 )
+ viewCenter: Qt.vector3d( 0.0, 0.0, 0.0 )
}
- Mesh {
- id: ballmesh
- source: ":/assets/obj/ball.obj"
+ Configuration {
+ controlledCamera: camera
}
- Material {
- id: greenMaterial
-
- parameters: [
- /*
- Tag {
- name: "kd"
- value: Qt.green
- }
- */
-
- Tag {
- name: "kd"
- value: Qt.vector3d( 0.2, 1.0, 0.1 )
-
- QQ2.Vector3dAnimation on value {
- from: Qt.vector3d(0.0, 1.0, 0.1)
- to: Qt.vector3d(1.0, 1.0, 0.1)
- duration: 1000
- loops: QQ2.Animation.Infinite
- }
- },
-
- Tag {
- name: "diffuse"
- value: brick
- }
- ]
+ FrameGraph {
+ id : external_forward_renderer
+ activeFrameGraph : ForwardRenderer {
+ camera: camera
+ clearColor: "black"
+ }
}
- Material {
- id: blueMaterial
+ components: [external_forward_renderer]
- parameters: [
- Tag { name: "kd"; value: Qt.vector3d(0.2, 0.2, 1.0) }
- ]
+ Wine {
+ id: wineRack
+ scale: 1
+ x: -60.0
+ y: -20.0
+ z: 0.0
+ angleX: 180
}
- Texture {
- id: brick
- source: "/Users/jmt/KDAB/Qt3D/qt3d-ng/assets/textures/brick1.jpg"
- }
}
diff --git a/src/plugins/sceneparsers/gltf/gltf.pro b/src/plugins/sceneparsers/gltf/gltf.pro
new file mode 100644
index 000000000..bf289372d
--- /dev/null
+++ b/src/plugins/sceneparsers/gltf/gltf.pro
@@ -0,0 +1,12 @@
+TARGET = gltfsceneparser
+QT += core-private 3dcore 3dcore-private 3drenderer 3drenderer-private
+
+PLUGIN_TYPE = sceneparsers
+PLUGIN_CLASS_NAME = GLTFParser
+load(qt_plugin)
+
+HEADERS += \
+ gltfparser_p.h
+
+SOURCES += \
+ gltfparser.cpp
diff --git a/src/plugins/sceneparsers/gltf/gltfparser.cpp b/src/plugins/sceneparsers/gltf/gltfparser.cpp
new file mode 100644
index 000000000..a4a0602c2
--- /dev/null
+++ b/src/plugins/sceneparsers/gltf/gltfparser.cpp
@@ -0,0 +1,1345 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Copyright (C) 2015 The Qt Company Ltd and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "gltfparser_p.h"
+
+#include <QtCore/QDir>
+#include <QtCore/QFileInfo>
+#include <QtCore/QJsonArray>
+#include <QtCore/QJsonObject>
+
+#include <QtGui/QVector2D>
+
+#include <Qt3DCore/QCameraLens>
+#include <Qt3DCore/QEntity>
+#include <Qt3DCore/QMatrixTransform>
+#include <Qt3DCore/QTransform>
+
+#include <Qt3DCore/private/qurlhelper_p.h>
+
+#include <Qt3DRenderer/QAlphaCoverage>
+#include <Qt3DRenderer/QBlendEquation>
+#include <Qt3DRenderer/QBlendStateSeparate>
+#include <Qt3DRenderer/QColorMask>
+#include <Qt3DRenderer/QCullFace>
+#include <Qt3DRenderer/QDepthMask>
+#include <Qt3DRenderer/QDepthTest>
+#include <Qt3DRenderer/QEffect>
+#include <Qt3DRenderer/QFrontFace>
+#include <Qt3DRenderer/QGeometry>
+#include <Qt3DRenderer/QGeometryRenderer>
+#include <Qt3DRenderer/QMaterial>
+#include <Qt3DRenderer/QParameter>
+#include <Qt3DRenderer/QParameterMapping>
+#include <Qt3DRenderer/QPolygonOffset>
+#include <Qt3DRenderer/QRenderState>
+#include <Qt3DRenderer/QScissorTest>
+#include <Qt3DRenderer/QShaderProgram>
+#include <Qt3DRenderer/QTechnique>
+#include <Qt3DRenderer/QTexture>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3D {
+
+Q_LOGGING_CATEGORY(GLTFParserLog, "Qt3D.GLTFParser")
+
+namespace {
+
+const QString KEY_CAMERA = QStringLiteral("camera");
+const QString KEY_CAMERAS = QStringLiteral("cameras");
+const QString KEY_SCENES = QStringLiteral("scenes");
+const QString KEY_NODES = QStringLiteral("nodes");
+const QString KEY_MESHES = QStringLiteral("meshes");
+const QString KEY_CHILDREN = QStringLiteral("children");
+const QString KEY_MATRIX = QStringLiteral("matrix");
+const QString KEY_TYPE = QStringLiteral("type");
+const QString KEY_PERSPECTIVE =QStringLiteral("perspective");
+const QString KEY_NAME = QStringLiteral("name");
+const QString KEY_COUNT = QStringLiteral("count");
+const QString KEY_YFOV = QStringLiteral("yfov");
+const QString KEY_ZNEAR = QStringLiteral("znear");
+const QString KEY_ZFAR = QStringLiteral("zfar");
+const QString KEY_MATERIALS = QStringLiteral("materials");
+const QString KEY_TECHNIQUE = QStringLiteral("technique");
+const QString KEY_VALUES = QStringLiteral("values");
+const QString KEY_BUFFERS = QStringLiteral("buffers");
+const QString KEY_SHADERS = QStringLiteral("shaders");
+const QString KEY_PROGRAMS = QStringLiteral("programs");
+const QString KEY_PROGRAM = QStringLiteral("program");
+const QString KEY_TECHNIQUES = QStringLiteral("techniques");
+const QString KEY_ACCESSORS = QStringLiteral("accessors");
+const QString KEY_IMAGES = QStringLiteral("images");
+const QString KEY_TEXTURES = QStringLiteral("textures");
+const QString KEY_SCENE = QStringLiteral("scene");
+const QString KEY_BUFFER = QStringLiteral("buffer");
+const QString KEY_TARGET = QStringLiteral("target");
+const QString KEY_BYTE_OFFSET = QStringLiteral("byteOffset");
+const QString KEY_BYTE_LENGTH = QStringLiteral("byteLength");
+const QString KEY_BYTE_STRIDE = QStringLiteral("byteStride");
+const QString KEY_PRIMITIVES = QStringLiteral("primitives");
+const QString KEY_PRIMITIVE = QStringLiteral("primitive");
+const QString KEY_MATERIAL = QStringLiteral("material");
+const QString KEY_ATTRIBUTES = QStringLiteral("attributes");
+const QString KEY_INDICES = QStringLiteral("indices");
+const QString KEY_URI = QStringLiteral("uri");
+const QString KEY_FORMAT = QStringLiteral("format");
+const QString KEY_PASSES = QStringLiteral("passes");
+const QString KEY_SOURCE = QStringLiteral("source");
+const QString KEY_SAMPLER = QStringLiteral("sampler");
+const QString KEY_SAMPLERS = QStringLiteral("samplers");
+const QString KEY_SEMANTIC = QStringLiteral("semantic");
+const QString KEY_STATES = QStringLiteral("states");
+const QString KEY_UNIFORMS = QStringLiteral("uniforms");
+const QString KEY_PARAMETERS = QStringLiteral("parameters");
+const QString KEY_WRAP_S = QStringLiteral("wrapS");
+const QString KEY_MIN_FILTER = QStringLiteral("minFilter");
+const QString KEY_MAG_FILTER = QStringLiteral("magFilter");
+
+const QString KEY_INSTANCE_TECHNIQUE = QStringLiteral("instanceTechnique");
+const QString KEY_INSTANCE_PROGRAM = QStringLiteral("instanceProgram");
+const QString KEY_BUFFER_VIEWS = QStringLiteral("bufferViews");
+const QString KEY_BUFFER_VIEW = QStringLiteral("bufferView");
+const QString KEY_VERTEX_SHADER = QStringLiteral("vertexShader");
+const QString KEY_FRAGMENT_SHADER = QStringLiteral("fragmentShader");
+const QString KEY_INTERNAL_FORMAT = QStringLiteral("internalFormat");
+const QString KEY_COMPONENT_TYPE = QStringLiteral("componentType");
+const QString KEY_ASPECT_RATIO = QStringLiteral("aspect_ratio");
+const QString KEY_VALUE = QStringLiteral("value");
+const QString KEY_ENABLE = QStringLiteral("enable");
+const QString KEY_FUNCTIONS = QStringLiteral("functions");
+
+} // of anonymous namespace
+
+GLTFParser::GLTFParser() : AbstractSceneParser(),
+ m_parseDone(false)
+{
+}
+
+GLTFParser::~GLTFParser()
+{
+
+}
+
+void GLTFParser::setBasePath(const QString& path)
+{
+ m_basePath = path;
+}
+
+bool GLTFParser::setJSON(const QJsonDocument &json )
+{
+ if ( !json.isObject() ) {
+ return false;
+ }
+
+ m_json = json;
+ m_parseDone = false;
+
+ cleanup();
+
+ return true;
+}
+
+/*!
+ * Sets the \a path used by the parser to load the scene file.
+ * If the file is valid, parsing is automatically triggered.
+ */
+void GLTFParser::setSource(const QUrl &source)
+{
+ const QString path = QUrlHelper::urlToLocalFileOrQrc(source);
+ QFileInfo finfo(path);
+ if (!finfo.exists()) {
+ qCWarning(GLTFParserLog) << "missing file:" << path;
+ return;
+ }
+ QFile f(path);
+ f.open(QIODevice::ReadOnly);
+
+ if (!setJSON(QJsonDocument::fromJson(f.readAll()))) {
+ qCWarning(GLTFParserLog) << "not a JSON document";
+ return;
+ }
+
+ setBasePath(finfo.dir().absolutePath());
+}
+
+/*!
+ * Returns true if the extension of \a path is supported by the
+ * GLTF parser.
+ */
+bool GLTFParser::isExtensionSupported(const QUrl &source) const
+{
+ const QString path = QUrlHelper::urlToLocalFileOrQrc(source);
+ return GLTFParser::isGLTFPath(path);
+}
+
+QEntity* GLTFParser::node(const QString &id)
+{
+ QJsonObject nodes = m_json.object().value(KEY_NODES).toObject();
+ if (!nodes.contains(id)) {
+ qCWarning(GLTFParserLog) << "unknown node" << id << "in GLTF file" << m_basePath;
+ return NULL;
+ }
+
+ QJsonObject jsonObj = nodes.value(id).toObject();
+ QEntity* result = Q_NULLPTR;
+
+ // Qt3D has a limitation that a QEntity can only have 1 mesh and 1 material component
+ // So if the node has only 1 mesh, we only create 1 QEntity
+ // Otherwise if there are n meshes, there is 1 QEntity, with n children for each mesh/material combo
+ if (jsonObj.contains(KEY_MESHES)) {
+ QVector<QEntity *> entities;
+
+ Q_FOREACH (QJsonValue mesh, jsonObj.value(KEY_MESHES).toArray()) {
+ if (!m_meshDict.contains(mesh.toString())) {
+ qCWarning(GLTFParserLog) << "node" << id << "references unknown mesh" << mesh.toString();
+ continue;
+ }
+
+ Q_FOREACH (QGeometryRenderer *geometryRenderer, m_meshDict.values(mesh.toString())) {
+ QEntity *entity = new QEntity;
+ entity->addComponent(geometryRenderer);
+ entity->addComponent(material(m_meshMaterialDict[geometryRenderer]));
+ entities.append(entity);
+ }
+
+ }
+
+ if (entities.count() == 1) {
+ result = entities.first();
+ } else {
+ result = new QEntity;
+ Q_FOREACH (QEntity *entity, entities) {
+ entity->setParent(result);
+ }
+ }
+ }
+
+ //If the entity contains no meshes, results will still be null here
+ if (result == Q_NULLPTR)
+ result = new QEntity;
+
+ if ( jsonObj.contains(KEY_CHILDREN) ) {
+ Q_FOREACH (QJsonValue c, jsonObj.value(KEY_CHILDREN).toArray()) {
+ QEntity* child = node(c.toString());
+ if (!child)
+ continue;
+ child->setParent(result);
+ }
+ }
+
+ renameFromJson(jsonObj, result);
+
+ if ( jsonObj.contains(KEY_MATRIX) ) {
+ QMatrix4x4 m(Qt::Uninitialized);
+
+ QJsonArray matrixValues = jsonObj.value(KEY_MATRIX).toArray();
+ for (int i=0; i<16; ++i) {
+ double v = matrixValues.at( i ).toDouble();
+ m(i % 4, i >> 2) = v;
+ }
+
+ // ADD MATRIX TRANSFORM COMPONENT TO ENTITY
+ QTransform *trans = new QTransform();
+ trans->addTransform(new QMatrixTransform(m));
+ result->addComponent(trans);
+ }
+
+ if ( jsonObj.contains(KEY_CAMERA) ) {
+ QCameraLens* cam = camera( jsonObj.value(KEY_CAMERA).toString() );
+ if (!cam) {
+ qCWarning(GLTFParserLog) << "failed to build camera:" << jsonObj.value(KEY_CAMERA)
+ << "on node" << id;
+ } else {
+ result->addComponent(cam);
+ }
+ } // of have camera attribute
+
+ return result;
+}
+
+QEntity* GLTFParser::scene(const QString &id)
+{
+ parse();
+
+ QJsonObject scenes = m_json.object().value(KEY_SCENES).toObject();
+ if (!scenes.contains(id)) {
+ if (!id.isNull())
+ qCWarning(GLTFParserLog) << "GLTF: no such scene" << id << "in file" << m_basePath;
+ return defaultScene();
+ }
+
+ QJsonObject sceneObj = scenes.value(id).toObject();
+ QEntity* sceneEntity = new QEntity;
+ Q_FOREACH (QJsonValue nnv, sceneObj.value(KEY_NODES).toArray()) {
+ QString nodeName = nnv.toString();
+ QEntity* child = node(nodeName);
+ if (!child)
+ continue;
+ child->setParent(sceneEntity);
+ }
+
+ return sceneEntity;
+}
+
+GLTFParser::BufferData::BufferData()
+ : length(0)
+ , data(Q_NULLPTR)
+{
+}
+
+GLTFParser::BufferData::BufferData(QJsonObject json)
+{
+ path = json.value(KEY_URI).toString();
+ length = json.value(KEY_BYTE_LENGTH).toInt();
+ data = Q_NULLPTR;
+}
+
+GLTFParser::ParameterData::ParameterData() :
+ type(0)
+{
+
+}
+
+GLTFParser::ParameterData::ParameterData(QJsonObject json)
+{
+ type = json.value(KEY_TYPE).toInt();
+ semantic = json.value(KEY_SEMANTIC).toString();
+}
+
+GLTFParser::AccessorData::AccessorData()
+ : type(QAttribute::Float)
+ , dataSize(0)
+ , count(0)
+ , offset(0)
+ , stride(0)
+{
+
+}
+
+GLTFParser::AccessorData::AccessorData(const QJsonObject &json)
+{
+ bufferViewName = json.value(KEY_BUFFER_VIEW).toString();
+ offset = 0;
+ stride = 0;
+ int componentType = json.value(KEY_COMPONENT_TYPE).toInt();
+ type = accessorTypeFromJSON(componentType);
+ count = json.value(KEY_COUNT).toInt();
+ dataSize = accessorDataSizeFromJson(json.value(KEY_TYPE).toString());
+
+ if ( json.contains(KEY_BYTE_OFFSET))
+ offset = json.value(KEY_BYTE_OFFSET).toInt();
+ if ( json.contains(KEY_BYTE_STRIDE))
+ stride = json.value(KEY_BYTE_STRIDE).toInt();
+}
+
+bool GLTFParser::isGLTFPath(const QString& path)
+{
+ QFileInfo finfo(path);
+ if (!finfo.exists())
+ return false;
+
+ // might need to detect other things in the future, but would
+ // prefer to avoid doing a full parse.
+ QString suffix = finfo.suffix().toLower();
+ return (suffix == QStringLiteral("json") || suffix == QStringLiteral("gltf"));
+}
+
+void GLTFParser::renameFromJson(const QJsonObject &json, QObject * const object)
+{
+ if ( json.contains(KEY_NAME) )
+ object->setObjectName( json.value(KEY_NAME).toString() );
+}
+
+QString GLTFParser::standardUniformNamefromSemantic(const QString &semantic)
+{
+ //Standard Uniforms
+ //if (semantic == QStringLiteral("LOCAL"));
+ if (semantic == QStringLiteral("MODEL"))
+ return QStringLiteral("modelMatrix");
+ if (semantic == QStringLiteral("VIEW"))
+ return QStringLiteral("viewMatrix");
+ if (semantic == QStringLiteral("PROJECTION"))
+ return QStringLiteral("projectionMatrix");
+ if (semantic == QStringLiteral("MODELVIEW"))
+ return QStringLiteral("modelView");
+ if (semantic == QStringLiteral("MODELVIEWPROJECTION"))
+ return QStringLiteral("modelViewProjection");
+ if (semantic == QStringLiteral("MODELINVERSE"))
+ return QStringLiteral("inverseModelMatrix");
+ if (semantic == QStringLiteral("VIEWINVERSE"))
+ return QStringLiteral("inverViewMatrix");
+ if (semantic == QStringLiteral("PROJECTIONINVERSE"))
+ return QStringLiteral("inverseProjectionMatrix");
+ if (semantic == QStringLiteral("MODELVIEWPROJECTIONINVERSE"))
+ return QStringLiteral("inverseModelViewProjection");
+ if (semantic == QStringLiteral("MODELINVERSETRANSPOSE"))
+ return QStringLiteral("modelNormalMatrix");
+ if (semantic == QStringLiteral("MODELVIEWINVERSETRANSPOSE"))
+ return QStringLiteral("modelViewNormal");
+ if (semantic == QStringLiteral("VIEWPORT"))
+ return QStringLiteral("viewportMatrix");
+
+ return QString();
+}
+
+QString GLTFParser::standardAttributeNameFromSemantic(const QString &semantic)
+{
+ //Standard Attributes
+ if (semantic.startsWith(QStringLiteral("POSITION")))
+ return QAttribute::defaultPositionAttributeName();
+ if (semantic.startsWith(QStringLiteral("NORMAL")))
+ return QAttribute::defaultNormalAttributeName();
+ if (semantic.startsWith(QStringLiteral("TEXCOORD")))
+ return QAttribute::defaultTextureCoordinateAttributeName();
+ if (semantic.startsWith(QStringLiteral("COLOR")))
+ return QAttribute::defaultColorAttributeName();
+ if (semantic.startsWith(QStringLiteral("TANGENT")))
+ return QAttribute::defaultTangentAttributeName();
+
+// if (semantic.startsWith(QStringLiteral("JOINT")));
+// if (semantic.startsWith(QStringLiteral("JOINTMATRIX")));
+// if (semantic.startsWith(QStringLiteral("WEIGHT")));
+
+ return QString();
+}
+
+QEntity* GLTFParser::defaultScene()
+{
+ if (m_defaultScene.isEmpty()) {
+ qCWarning(GLTFParserLog) << Q_FUNC_INFO << "no default scene";
+ return NULL;
+ }
+
+ return scene(m_defaultScene);
+}
+
+QMaterial* GLTFParser::material(const QString &id)
+{
+ if (m_materialCache.contains(id))
+ return m_materialCache.value(id);
+
+ QJsonObject mats = m_json.object().value(KEY_MATERIALS).toObject();
+ if (!mats.contains(id)) {
+ qCWarning(GLTFParserLog) << "unknown material" << id << "in GLTF file" << m_basePath;
+ return NULL;
+ }
+
+ QJsonObject jsonObj = mats.value(id).toObject();
+
+ QJsonObject tech = jsonObj.value(KEY_INSTANCE_TECHNIQUE).toObject();
+ QString tname = tech.value(KEY_TECHNIQUE).toString();
+ if (!m_techniques.contains(tname)) {
+ qCWarning(GLTFParserLog) << "unknown technique" << tname
+ << "for material" << id << "in GLTF file" << m_basePath;
+ return NULL;
+ }
+
+ QTechnique *technique = m_techniques.value(tname);
+ // glTF doesn't deal in effects, but we need a trivial one to wrap
+ // up our techniques
+ // However we need to create a unique effect for each material instead
+ // of caching because QMaterial does not keep up with effects
+ // its not the parent of.
+ QEffect* effect = new QEffect;
+ effect->setObjectName(tname);
+ effect->addTechnique(technique);
+
+ QMaterial* mat = new QMaterial;
+ mat->setEffect(effect);
+
+ renameFromJson(jsonObj, mat);
+
+ QJsonObject values = tech.value(KEY_VALUES).toObject();
+ Q_FOREACH (QString vName, values.keys()) {
+ QParameter *param = Q_NULLPTR;
+ Q_FOREACH (QParameter *parameter, technique->parameters()) {
+ if (parameter->name() == vName) {
+ param = parameter;
+ break;
+ }
+ }
+ if (param == Q_NULLPTR) {
+ qCWarning(GLTFParserLog) << "unknown parameter:" << vName << "in technique" << tname
+ << "processing material" << id;
+ continue;
+ }
+
+ ParameterData paramData = m_parameterDataDict.value(param);
+ QVariant var = parameterValueFromJSON(paramData.type, values.value(vName));
+
+ mat->addParameter(new QParameter(param->name(), var));
+ } // of material technique-instance values iteration
+
+ m_materialCache[id] = mat;
+ return mat;
+}
+
+QCameraLens* GLTFParser::camera(const QString &id) const
+{
+ QJsonObject cams = m_json.object().value(KEY_CAMERAS).toObject();
+ if (!cams.contains(id)) {
+ qCWarning(GLTFParserLog) << "unknown camera" << id << "in GLTF file" << m_basePath;
+ return Q_NULLPTR;
+ }
+
+ QJsonObject jsonObj = cams.value(id).toObject();
+ QString camTy = jsonObj.value(KEY_TYPE).toString();
+
+ if (camTy == QStringLiteral("perspective")) {
+ if (!jsonObj.contains(KEY_PERSPECTIVE)) {
+ qCWarning(GLTFParserLog) << "camera:" << id << "missing 'perspective' object";
+ return Q_NULLPTR;
+ }
+
+ QJsonObject pObj = jsonObj.value(KEY_PERSPECTIVE).toObject();
+ double aspectRatio = pObj.value(KEY_ASPECT_RATIO).toDouble();
+ double yfov = pObj.value(KEY_YFOV).toDouble();
+ double frustumNear = pObj.value(KEY_ZNEAR).toDouble();
+ double frustumFar = pObj.value(KEY_ZFAR).toDouble();
+
+ QCameraLens* result = new QCameraLens;
+ result->setPerspectiveProjection(yfov, aspectRatio, frustumNear, frustumFar);
+ return result;
+ } else if (camTy == QStringLiteral("orthographic")) {
+ qCWarning(GLTFParserLog) << Q_FUNC_INFO << "implement me";
+
+ return Q_NULLPTR;
+ } else {
+ qCWarning(GLTFParserLog) << "camera:" << id << "has unsupported type:" << camTy;
+ return Q_NULLPTR;
+ }
+}
+
+
+void GLTFParser::parse()
+{
+ if (m_parseDone)
+ return;
+
+ QJsonObject buffers = m_json.object().value(KEY_BUFFERS).toObject();
+ Q_FOREACH (QString nm, buffers.keys()) {
+ processJSONBuffer( nm, buffers.value(nm).toObject() );
+ }
+
+ QJsonObject views = m_json.object().value(KEY_BUFFER_VIEWS).toObject();
+ loadBufferData();
+ Q_FOREACH (QString nm, views.keys()) {
+ processJSONBufferView( nm, views.value(nm).toObject() );
+ }
+ unloadBufferData();
+
+ QJsonObject shaders = m_json.object().value(KEY_SHADERS).toObject();
+ Q_FOREACH (QString nm, shaders.keys()) {
+ processJSONShader( nm, shaders.value(nm).toObject() );
+ }
+
+ QJsonObject programs = m_json.object().value(KEY_PROGRAMS).toObject();
+ Q_FOREACH (QString nm, programs.keys()) {
+ processJSONProgram( nm, programs.value(nm).toObject() );
+ }
+
+ QJsonObject techniques = m_json.object().value(KEY_TECHNIQUES).toObject();
+ Q_FOREACH (QString nm, techniques.keys()) {
+ processJSONTechnique( nm, techniques.value(nm).toObject() );
+ }
+
+ QJsonObject attrs = m_json.object().value(KEY_ACCESSORS).toObject();
+ Q_FOREACH (QString nm, attrs.keys()) {
+ processJSONAccessor( nm, attrs.value(nm).toObject() );
+ }
+
+ QJsonObject meshes = m_json.object().value(KEY_MESHES).toObject();
+ Q_FOREACH (QString nm, meshes.keys()) {
+ processJSONMesh( nm, meshes.value(nm).toObject() );
+ }
+
+ QJsonObject images = m_json.object().value(KEY_IMAGES).toObject();
+ Q_FOREACH (QString nm, images.keys()) {
+ processJSONImage( nm, images.value(nm).toObject() );
+ }
+
+ QJsonObject textures = m_json.object().value(KEY_TEXTURES).toObject();
+ Q_FOREACH (QString nm, textures.keys()) {
+ processJSONTexture(nm, textures.value(nm).toObject() );
+ }
+
+ m_defaultScene = m_json.object().value(KEY_SCENE).toString();
+ m_parseDone = true;
+}
+
+void GLTFParser::cleanup()
+{
+ m_meshDict.clear();
+ m_meshMaterialDict.clear();
+ m_accessorDict.clear();
+ //Check for Materials with no parent
+ Q_FOREACH (QMaterial *material, m_materialCache.values()) {
+ if (material->parent() == Q_NULLPTR)
+ delete material;
+ }
+ m_materialCache.clear();
+ m_bufferDatas.clear();
+ m_buffers.clear();
+ m_shaderPaths.clear();
+ //Check for ShaderPrograms with no parent
+ Q_FOREACH (QShaderProgram *program, m_programs.values()) {
+ if (program->parent() == Q_NULLPTR)
+ delete program;
+ }
+ m_programs.clear();
+ //Check for Techniques with no parent
+ Q_FOREACH (QTechnique *technique, m_techniques.values()) {
+ if (technique->parent() == Q_NULLPTR)
+ delete technique;
+ }
+ m_techniques.clear();
+ //Check for Textures with no parent
+ Q_FOREACH (QAbstractTextureProvider *texture, m_textures.values()) {
+ if (texture->parent() == Q_NULLPTR)
+ delete texture;
+ }
+ m_textures.clear();
+ m_imagePaths.clear();
+ m_defaultScene.clear();
+ m_parameterDataDict.clear();
+}
+
+void GLTFParser::processJSONBuffer(const QString &id, const QJsonObject& json)
+{
+ // simply cache buffers for lookup by buffer-views
+ m_bufferDatas[id] = BufferData(json);
+}
+
+void GLTFParser::processJSONBufferView(const QString &id, const QJsonObject& json)
+{
+ QString bufName = json.value(KEY_BUFFER).toString();
+ if (!m_bufferDatas.contains(bufName)) {
+ qCWarning(GLTFParserLog) << "unknown buffer:" << bufName << "processing view:" << id;
+ return;
+ }
+
+ int target = json.value(KEY_TARGET).toInt();
+ QBuffer::BufferType ty(QBuffer::VertexBuffer);
+
+ switch (target) {
+ case GL_ARRAY_BUFFER: ty = QBuffer::VertexBuffer; break;
+ case GL_ELEMENT_ARRAY_BUFFER: ty = QBuffer::IndexBuffer; break;
+ default:
+ qCWarning(GLTFParserLog) << Q_FUNC_INFO << "buffer" << id << "unsupported target:" << target;
+ return;
+ }
+
+ quint64 offset = 0;
+ if (json.contains(KEY_BYTE_OFFSET)) {
+ offset = json.value(KEY_BYTE_OFFSET).toInt();
+ qCDebug(GLTFParserLog) << "bv:" << id << "has offset:" << offset;
+ }
+
+ quint64 len = json.value(KEY_BYTE_LENGTH).toInt();
+
+ QByteArray bytes(m_bufferDatas[bufName].data->mid(offset, len));
+ if (bytes.count() != (int) len) {
+ qCWarning(GLTFParserLog) << "failed to read sufficient bytes from:" << m_bufferDatas[bufName].path
+ << "for view" << id;
+ }
+
+ QBuffer *b(new QBuffer(ty));
+ b->setData(bytes);
+ m_buffers[id] = b;
+}
+
+void GLTFParser::processJSONShader(const QString &id, const QJsonObject &jsonObject)
+{
+ // shaders are trivial for the moment, defer the real work
+ // to the program section
+ QString path = jsonObject.value(KEY_URI).toString();
+
+ QFileInfo info(m_basePath, path);
+ if (!info.exists()) {
+ qCWarning(GLTFParserLog) << "can't find shader" << id << "from path" << path;
+ return;
+ }
+
+ m_shaderPaths[id] = info.absoluteFilePath();
+}
+
+void GLTFParser::processJSONProgram(const QString &id, const QJsonObject &jsonObject)
+{
+ QShaderProgram* prog = new QShaderProgram;
+ prog->setObjectName(id);
+
+ QString fragName = jsonObject.value(KEY_FRAGMENT_SHADER).toString(),
+ vertName = jsonObject.value(KEY_VERTEX_SHADER).toString();
+ if (!m_shaderPaths.contains(fragName) || !m_shaderPaths.contains(vertName)) {
+ qCWarning(GLTFParserLog) << Q_FUNC_INFO << "program:" << id << "missing shader:"
+ << fragName << vertName;
+ return;
+ }
+
+ prog->setFragmentShaderCode(Qt3D::QShaderProgram::loadSource(QUrl::fromLocalFile(m_shaderPaths[fragName])));
+ prog->setVertexShaderCode(Qt3D::QShaderProgram::loadSource(QUrl::fromLocalFile(m_shaderPaths[vertName])));
+ m_programs[id] = prog;
+}
+
+void GLTFParser::processJSONTechnique(const QString &id, const QJsonObject &jsonObject )
+{
+ QTechnique *t = new QTechnique;
+ t->setObjectName(id);
+
+ QHash<QString, QParameter*> paramDict;
+ QJsonObject params = jsonObject.value(KEY_PARAMETERS).toObject();
+ Q_FOREACH (QString pname, params.keys()) {
+ QJsonObject po = params.value(pname).toObject();
+
+ //QString semantic = po.value(KEY_SEMANTIC).toString();
+ QParameter *p = new QParameter(t);
+ p->setName(pname);
+ m_parameterDataDict.insert(p, ParameterData(po));
+
+ //If the parameter has default value, set it
+ QJsonValue value = po.value(KEY_VALUE);
+ if (!value.isUndefined()) {
+ int dataType = po.value(KEY_TYPE).toInt();
+ p->setValue(parameterValueFromJSON(dataType, value));
+ }
+
+ t->addParameter(p);
+
+ paramDict[pname] = p;
+ } // of parameters iteration
+
+ QJsonObject passes = jsonObject.value(KEY_PASSES).toObject();
+ Q_FOREACH (QString pname, passes.keys()) {
+ QJsonObject po = passes.value(pname).toObject();
+ QJsonObject ip = po.value(KEY_INSTANCE_PROGRAM).toObject();
+
+ QString programName = ip.value(KEY_PROGRAM).toString();
+ if (!m_programs.contains(programName)) {
+ qCWarning(GLTFParserLog) << Q_FUNC_INFO << "technique" << id << "pass" << pname
+ << ": missing program" << programName;
+ continue;
+ }
+
+ QRenderPass* pass = new QRenderPass;
+ pass->setShaderProgram(m_programs[programName]);
+
+ QJsonObject attrs = ip.value(KEY_ATTRIBUTES).toObject();
+ Q_FOREACH ( QString shaderAttributeName, attrs.keys() ) {
+ QString pname = attrs.value(shaderAttributeName).toString();
+ QParameter *parameter = paramDict.value(pname, Q_NULLPTR);
+ QString attributeName = pname;
+ if (parameter == Q_NULLPTR) {
+ qCWarning(GLTFParserLog) << Q_FUNC_INFO << "attribute " << pname
+ << "defined in instanceProgram but not as parameter";
+ continue;
+ }
+ //Check if the parameter has a standard attribute semantic
+ QString standardAttributeName = standardAttributeNameFromSemantic(m_parameterDataDict[parameter].semantic);
+ if (!standardAttributeName.isNull()) {
+ attributeName = standardAttributeName;
+ t->removeParameter(parameter);
+ m_parameterDataDict.remove(parameter);
+ delete parameter;
+ }
+
+ pass->addBinding(new QParameterMapping(attributeName, shaderAttributeName, QParameterMapping::Attribute));
+ } // of program-instance attributes
+
+ QJsonObject uniforms = ip.value(KEY_UNIFORMS).toObject();
+ Q_FOREACH (QString shaderUniformName, uniforms.keys()) {
+ QString pname = uniforms.value(shaderUniformName).toString();
+ QParameter *parameter = paramDict.value(pname, Q_NULLPTR);
+ if (parameter == Q_NULLPTR) {
+ qCWarning(GLTFParserLog) << Q_FUNC_INFO << "uniform " << pname
+ << "defined in instanceProgram but not as parameter";
+ continue;
+ }
+ //Check if the parameter has a standard uniform semantic
+ QString standardUniformName = standardUniformNamefromSemantic(m_parameterDataDict[parameter].semantic);
+ if (standardUniformName.isNull()) {
+ pass->addBinding(new QParameterMapping(pname, shaderUniformName, QParameterMapping::Uniform));
+ } else {
+ pass->addBinding(new QParameterMapping(standardUniformName, shaderUniformName, QParameterMapping::StandardUniform));
+ t->removeParameter(parameter);
+ m_parameterDataDict.remove(parameter);
+ delete parameter;
+ }
+ } // of program-instance uniforms
+
+ QJsonObject states = po.value(KEY_STATES).toObject();
+
+ //Process states to enable
+ QJsonArray enableStatesArray = states.value(KEY_ENABLE).toArray();
+ QVector<int> enableStates;
+ Q_FOREACH (QJsonValue enableValue, enableStatesArray) {
+ enableStates.append(enableValue.toInt());
+ }
+
+ //Process the list of state functions
+ QJsonObject functions = states.value(KEY_FUNCTIONS).toObject();
+ Q_FOREACH (QString functionName, functions.keys()) {
+ int enableStateType = 0;
+ QRenderState *renderState = buildState(functionName, functions.value(functionName), enableStateType);
+ if (renderState != Q_NULLPTR) {
+ //Remove the need to set a default state values for enableStateType
+ enableStates.removeOne(enableStateType);
+ pass->addRenderState(renderState);
+ }
+ }
+
+ //Create render states with default values for any remaining enable states
+ Q_FOREACH (int enableState, enableStates) {
+ QRenderState *renderState = buildStateEnable(enableState);
+ if (renderState != Q_NULLPTR)
+ pass->addRenderState(renderState);
+ }
+
+
+ t->addPass(pass);
+ } // of passes iteration
+
+ m_techniques[id] = t;
+}
+
+void GLTFParser::processJSONAccessor( const QString &id, const QJsonObject& json )
+{
+ m_accessorDict[id] = AccessorData(json);
+}
+
+void GLTFParser::processJSONMesh(const QString &id, const QJsonObject &json)
+{
+ QJsonArray primitivesArray = json.value(KEY_PRIMITIVES).toArray();
+ Q_FOREACH (QJsonValue primitiveValue, primitivesArray) {
+ QJsonObject primitiveObject = primitiveValue.toObject();
+ int type = primitiveObject.value(KEY_PRIMITIVE).toInt();
+ QString material = primitiveObject.value(KEY_MATERIAL).toString();
+
+ if ( material.isEmpty()) {
+ qCWarning(GLTFParserLog) << "malformed primitive on " << id << ", missing material value"
+ << material;
+ continue;
+ }
+
+ QGeometryRenderer *geometryRenderer = new QGeometryRenderer;
+ QGeometry *meshGeometry = new QGeometry(geometryRenderer);
+
+ //Set Primitive Type
+ geometryRenderer->setPrimitiveType(static_cast<QGeometryRenderer::PrimitiveType>(type));
+
+ //Save Material for mesh
+ m_meshMaterialDict[geometryRenderer] = material;
+
+ QJsonObject attrs = primitiveObject.value(KEY_ATTRIBUTES).toObject();
+ Q_FOREACH (QString attrName, attrs.keys()) {
+ QString k = attrs.value(attrName).toString();
+ if (!m_accessorDict.contains(k)) {
+ qCWarning(GLTFParserLog) << "unknown attribute accessor:" << k << "on mesh" << id;
+ continue;
+ }
+
+ QString attributeName = standardAttributeNameFromSemantic(attrName);
+ if (attributeName.isEmpty())
+ attributeName = attrName;
+
+ //Get buffer handle for accessor
+ QBuffer *buffer = m_buffers.value(m_accessorDict[k].bufferViewName, Q_NULLPTR);
+ if (buffer == Q_NULLPTR) {
+ qCWarning(GLTFParserLog) << "unknown buffer-view:" << m_accessorDict[k].bufferViewName << "processing accessor:" << id;
+ continue;
+ }
+
+ QAttribute *attribute = new QAttribute(buffer,
+ attributeName,
+ m_accessorDict[k].type,
+ m_accessorDict[k].dataSize,
+ m_accessorDict[k].count,
+ m_accessorDict[k].offset,
+ m_accessorDict[k].stride);
+ attribute->setAttributeType(QAttribute::VertexAttribute);
+ meshGeometry->addAttribute(attribute);
+ }
+
+ if ( primitiveObject.contains(KEY_INDICES)) {
+ QString k = primitiveObject.value(KEY_INDICES).toString();
+ if (!m_accessorDict.contains(k)) {
+ qCWarning(GLTFParserLog) << "unknown index accessor:" << k << "on mesh" << id;
+ } else {
+ //Get buffer handle for accessor
+ QBuffer *buffer = m_buffers.value(m_accessorDict[k].bufferViewName, Q_NULLPTR);
+ if (buffer == Q_NULLPTR) {
+ qCWarning(GLTFParserLog) << "unknown buffer-view:" << m_accessorDict[k].bufferViewName << "processing accessor:" << id;
+ continue;
+ }
+
+ QAttribute *attribute = new QAttribute(buffer,
+ m_accessorDict[k].type,
+ m_accessorDict[k].dataSize,
+ m_accessorDict[k].count,
+ m_accessorDict[k].offset,
+ m_accessorDict[k].stride);
+ attribute->setAttributeType(QAttribute::IndexAttribute);
+ meshGeometry->addAttribute(attribute);
+ }
+ } // of has indices
+
+ geometryRenderer->setGeometry(meshGeometry);
+
+ m_meshDict.insert( id, geometryRenderer);
+ } // of primitives iteration
+}
+
+void GLTFParser::processJSONImage(const QString &id, const QJsonObject &jsonObject)
+{
+ QString path = jsonObject.value(KEY_URI).toString();
+ QFileInfo info(m_basePath, path);
+ if (!info.exists()) {
+ qCWarning(GLTFParserLog) << "can't find image" << id << "from path" << path;
+ return;
+ }
+
+ m_imagePaths[id] = info.absoluteFilePath();
+}
+
+void GLTFParser::processJSONTexture(const QString &id, const QJsonObject &jsonObject)
+{
+ int target = jsonObject.value(KEY_TARGET).toInt(GL_TEXTURE_2D);
+ //TODO: support other targets that GL_TEXTURE_2D (though the spec doesn't support anything else)
+ if (target != GL_TEXTURE_2D) {
+ qCWarning(GLTFParserLog) << "unsupported texture target: " << target;
+ return;
+ }
+
+ QTexture2D* tex = new QTexture2D;
+
+ // TODO: Choose suitable internal format - may vary on OpenGL context type
+ //int pixelFormat = jsonObj.value(KEY_FORMAT).toInt(GL_RGBA);
+ int internalFormat = jsonObject.value(KEY_INTERNAL_FORMAT).toInt(GL_RGBA);
+
+ tex->setFormat(static_cast<QAbstractTextureProvider::TextureFormat>(internalFormat));
+
+ QString samplerId = jsonObject.value(KEY_SAMPLER).toString();
+ QString source = jsonObject.value(KEY_SOURCE).toString();
+ if (!m_imagePaths.contains(source)) {
+ qCWarning(GLTFParserLog) << "texture" << id << "references missing image" << source;
+ return;
+ }
+
+ QTextureImage *texImage = new QTextureImage(tex);
+ texImage->setSource(QUrl::fromLocalFile(m_imagePaths[source]));
+ tex->addTextureImage(texImage);
+
+ QJsonObject samplersDict(m_json.object().value(KEY_SAMPLERS).toObject());
+ if (!samplersDict.contains(samplerId)) {
+ qCWarning(GLTFParserLog) << "texture" << id << "references unknown sampler" << samplerId;
+ return;
+ }
+
+ QJsonObject sampler = samplersDict.value(samplerId).toObject();
+
+ tex->setWrapMode(QTextureWrapMode(static_cast<QTextureWrapMode::WrapMode>(sampler.value(KEY_WRAP_S).toInt())));
+ tex->setMinificationFilter(static_cast<QAbstractTextureProvider::Filter>(sampler.value(KEY_MIN_FILTER).toInt()));
+ if (tex->minificationFilter() == QAbstractTextureProvider::NearestMipMapLinear ||
+ tex->minificationFilter() == QAbstractTextureProvider::LinearMipMapNearest ||
+ tex->minificationFilter() == QAbstractTextureProvider::NearestMipMapNearest ||
+ tex->minificationFilter() == QAbstractTextureProvider::LinearMipMapLinear) {
+
+ tex->setGenerateMipMaps(true);
+ }
+ tex->setMagnificationFilter(static_cast<QAbstractTextureProvider::Filter>(sampler.value(KEY_MAG_FILTER).toInt()));
+
+ m_textures[id] = tex;
+}
+
+void GLTFParser::loadBufferData()
+{
+ Q_FOREACH (QString bufferName, m_bufferDatas.keys()) {
+ if (m_bufferDatas[bufferName].data == Q_NULLPTR) {
+ QFile* bufferFile = resolveLocalData(m_bufferDatas[bufferName].path);
+ QByteArray *data = new QByteArray(bufferFile->readAll());
+ m_bufferDatas[bufferName].data = data;
+ delete bufferFile;
+ }
+ }
+}
+
+void GLTFParser::unloadBufferData()
+{
+ Q_FOREACH (QString bufferName, m_bufferDatas.keys()) {
+ QByteArray *data = m_bufferDatas[bufferName].data;
+ delete data;
+ }
+}
+
+QFile *GLTFParser::resolveLocalData(QString path) const
+{
+ QDir d(m_basePath);
+ Q_ASSERT(d.exists());
+
+ QString absPath = d.absoluteFilePath(path);
+ QFile* f = new QFile(absPath);
+ f->open(QIODevice::ReadOnly);
+ return f;
+}
+
+QVariant GLTFParser::parameterValueFromJSON(int type, const QJsonValue &value) const
+{
+ if (value.isBool()) {
+ if (type == GL_BOOL)
+ return QVariant(static_cast<GLboolean>(value.toBool()));
+ } else if (value.isString()) {
+ if (type == GL_SAMPLER_2D) {
+ //Textures are special because we need to do a lookup to return the
+ //QAbstractTextureProvider
+ QString textureId = value.toString();
+ if (!m_textures.contains(textureId)) {
+ qCWarning(GLTFParserLog) << "unknown texture" << textureId;
+ return QVariant();
+ } else {
+ return QVariant::fromValue(m_textures.value(textureId));
+ }
+ }
+ } else if (value.isDouble()) {
+ switch (type) {
+ case GL_BYTE:
+ return QVariant(static_cast<GLbyte>(value.toInt()));
+ case GL_UNSIGNED_BYTE:
+ return QVariant(static_cast<GLubyte>(value.toInt()));
+ case GL_SHORT:
+ return QVariant(static_cast<GLshort>(value.toInt()));
+ case GL_UNSIGNED_SHORT:
+ return QVariant(static_cast<GLushort>(value.toInt()));
+ case GL_INT:
+ return QVariant(static_cast<GLint>(value.toInt()));
+ case GL_UNSIGNED_INT:
+ return QVariant(static_cast<GLuint>(value.toInt()));
+ case GL_FLOAT:
+ return QVariant(static_cast<GLfloat>(value.toDouble()));
+ }
+ } else if (value.isArray()) {
+
+ QJsonArray valueArray = value.toArray();
+
+ QVector2D vector2D;
+ QVector3D vector3D;
+ QVector4D vector4D;
+ QVector<float> dataMat2(4, 0.0f);
+ QVector<float> dataMat3(9, 0.0f);
+
+ switch (type) {
+ case GL_BYTE:
+ return QVariant(static_cast<GLbyte>(valueArray.first().toInt()));
+ case GL_UNSIGNED_BYTE:
+ return QVariant(static_cast<GLubyte>(valueArray.first().toInt()));
+ case GL_SHORT:
+ return QVariant(static_cast<GLshort>(valueArray.first().toInt()));
+ case GL_UNSIGNED_SHORT:
+ return QVariant(static_cast<GLushort>(valueArray.first().toInt()));
+ case GL_INT:
+ return QVariant(static_cast<GLint>(valueArray.first().toInt()));
+ case GL_UNSIGNED_INT:
+ return QVariant(static_cast<GLuint>(valueArray.first().toInt()));
+ case GL_FLOAT:
+ return QVariant(static_cast<GLfloat>(valueArray.first().toDouble()));
+ case GL_FLOAT_VEC2:
+ vector2D.setX(static_cast<GLfloat>(valueArray.at(0).toDouble()));
+ vector2D.setY(static_cast<GLfloat>(valueArray.at(1).toDouble()));
+ return QVariant(vector2D);
+ case GL_FLOAT_VEC3:
+ vector3D.setX(static_cast<GLfloat>(valueArray.at(0).toDouble()));
+ vector3D.setY(static_cast<GLfloat>(valueArray.at(1).toDouble()));
+ vector3D.setZ(static_cast<GLfloat>(valueArray.at(2).toDouble()));
+ return QVariant(vector3D);
+ case GL_FLOAT_VEC4:
+ vector4D.setX(static_cast<GLfloat>(valueArray.at(0).toDouble()));
+ vector4D.setY(static_cast<GLfloat>(valueArray.at(1).toDouble()));
+ vector4D.setZ(static_cast<GLfloat>(valueArray.at(2).toDouble()));
+ vector4D.setW(static_cast<GLfloat>(valueArray.at(3).toDouble()));
+ return QVariant(vector4D);
+ case GL_INT_VEC2:
+ vector2D.setX(static_cast<GLint>(valueArray.at(0).toInt()));
+ vector2D.setY(static_cast<GLint>(valueArray.at(1).toInt()));
+ return QVariant(vector2D);
+ case GL_INT_VEC3:
+ vector3D.setX(static_cast<GLint>(valueArray.at(0).toInt()));
+ vector3D.setY(static_cast<GLint>(valueArray.at(1).toInt()));
+ vector3D.setZ(static_cast<GLint>(valueArray.at(2).toInt()));
+ return QVariant(vector3D);
+ case GL_INT_VEC4:
+ vector4D.setX(static_cast<GLint>(valueArray.at(0).toInt()));
+ vector4D.setY(static_cast<GLint>(valueArray.at(1).toInt()));
+ vector4D.setZ(static_cast<GLint>(valueArray.at(2).toInt()));
+ vector4D.setW(static_cast<GLint>(valueArray.at(3).toInt()));
+ return QVariant(vector4D);
+ case GL_BOOL:
+ return QVariant(static_cast<GLboolean>(valueArray.first().toBool()));
+ case GL_BOOL_VEC2:
+ vector2D.setX(static_cast<GLboolean>(valueArray.at(0).toBool()));
+ vector2D.setY(static_cast<GLboolean>(valueArray.at(1).toBool()));
+ return QVariant(vector2D);
+ case GL_BOOL_VEC3:
+ vector3D.setX(static_cast<GLboolean>(valueArray.at(0).toBool()));
+ vector3D.setY(static_cast<GLboolean>(valueArray.at(1).toBool()));
+ vector3D.setZ(static_cast<GLboolean>(valueArray.at(2).toBool()));
+ return QVariant(vector3D);
+ case GL_BOOL_VEC4:
+ vector4D.setX(static_cast<GLboolean>(valueArray.at(0).toBool()));
+ vector4D.setY(static_cast<GLboolean>(valueArray.at(1).toBool()));
+ vector4D.setZ(static_cast<GLboolean>(valueArray.at(2).toBool()));
+ vector4D.setW(static_cast<GLboolean>(valueArray.at(3).toBool()));
+ return QVariant(vector4D);
+ case GL_FLOAT_MAT2:
+ //Matrix2x2 is in Row Major ordering (so we need to convert)
+ dataMat2[0] = static_cast<GLfloat>(valueArray.at(0).toDouble());
+ dataMat2[1] = static_cast<GLfloat>(valueArray.at(2).toDouble());
+ dataMat2[2] = static_cast<GLfloat>(valueArray.at(1).toDouble());
+ dataMat2[3] = static_cast<GLfloat>(valueArray.at(3).toDouble());
+ return QVariant::fromValue(QMatrix2x2(dataMat2.constData()));
+ case GL_FLOAT_MAT3:
+ //Matrix3x3 is in Row Major ordering (so we need to convert)
+ dataMat3[0] = static_cast<GLfloat>(valueArray.at(0).toDouble());
+ dataMat3[1] = static_cast<GLfloat>(valueArray.at(3).toDouble());
+ dataMat3[2] = static_cast<GLfloat>(valueArray.at(6).toDouble());
+ dataMat3[3] = static_cast<GLfloat>(valueArray.at(1).toDouble());
+ dataMat3[4] = static_cast<GLfloat>(valueArray.at(4).toDouble());
+ dataMat3[5] = static_cast<GLfloat>(valueArray.at(7).toDouble());
+ dataMat3[6] = static_cast<GLfloat>(valueArray.at(2).toDouble());
+ dataMat3[7] = static_cast<GLfloat>(valueArray.at(5).toDouble());
+ dataMat3[8] = static_cast<GLfloat>(valueArray.at(8).toDouble());
+ return QVariant::fromValue(QMatrix3x3(dataMat3.constData()));
+ case GL_FLOAT_MAT4:
+ //Matrix4x4 is Column Major ordering
+ return QVariant(QMatrix4x4(static_cast<GLfloat>(valueArray.at(0).toDouble()),
+ static_cast<GLfloat>(valueArray.at(1).toDouble()),
+ static_cast<GLfloat>(valueArray.at(2).toDouble()),
+ static_cast<GLfloat>(valueArray.at(3).toDouble()),
+ static_cast<GLfloat>(valueArray.at(4).toDouble()),
+ static_cast<GLfloat>(valueArray.at(5).toDouble()),
+ static_cast<GLfloat>(valueArray.at(6).toDouble()),
+ static_cast<GLfloat>(valueArray.at(7).toDouble()),
+ static_cast<GLfloat>(valueArray.at(8).toDouble()),
+ static_cast<GLfloat>(valueArray.at(9).toDouble()),
+ static_cast<GLfloat>(valueArray.at(10).toDouble()),
+ static_cast<GLfloat>(valueArray.at(11).toDouble()),
+ static_cast<GLfloat>(valueArray.at(12).toDouble()),
+ static_cast<GLfloat>(valueArray.at(13).toDouble()),
+ static_cast<GLfloat>(valueArray.at(14).toDouble()),
+ static_cast<GLfloat>(valueArray.at(15).toDouble())));
+ case GL_SAMPLER_2D:
+ return QVariant(valueArray.at(0).toString());
+ }
+ }
+ return QVariant();
+}
+
+QAttribute::DataType GLTFParser::accessorTypeFromJSON(int componentType)
+{
+ if (componentType == GL_BYTE) {
+ return QAttribute::Byte;
+ } else if (componentType == GL_UNSIGNED_BYTE) {
+ return QAttribute::UnsignedByte;
+ } else if (componentType == GL_SHORT) {
+ return QAttribute::Short;
+ } else if (componentType == GL_UNSIGNED_SHORT) {
+ return QAttribute::UnsignedShort;
+ } else if (componentType == GL_FLOAT) {
+ return QAttribute::Float;
+ }
+
+ //There shouldn't be an invalid case here
+ qCWarning(GLTFParserLog) << "unsupported accessor type" << componentType;
+ return QAttribute::Float;
+}
+
+uint GLTFParser::accessorDataSizeFromJson(const QString &type)
+{
+ QString typeName = type.toUpper();
+ if (typeName == "SCALAR")
+ return 1;
+ if (typeName == "VEC2")
+ return 2;
+ if (typeName == "VEC3")
+ return 3;
+ if (typeName == "VEC4")
+ return 4;
+ if (typeName == "MAT2")
+ return 4;
+ if (typeName == "MAT3")
+ return 9;
+ if (typeName == "MAT4")
+ return 16;
+
+ return 0;
+}
+
+QRenderState *GLTFParser::buildStateEnable(int state)
+{
+ int type = 0;
+ //By calling buildState with QJsonValue(), a Render State with
+ //default values is created.
+
+ if (state == GL_BLEND) {
+ //It doesn't make sense to handle this state alone
+ return Q_NULLPTR;
+ }
+
+ if (state == GL_CULL_FACE) {
+ return buildState(QStringLiteral("cullFace"), QJsonValue(), type);
+ }
+
+ if (state == GL_DEPTH_TEST) {
+ return buildState(QStringLiteral("depthFunc"), QJsonValue(), type);
+ }
+
+ if (state == GL_POLYGON_OFFSET_FILL) {
+ return buildState(QStringLiteral("polygonOffset"), QJsonValue(), type);
+ }
+
+ if (state == GL_SAMPLE_ALPHA_TO_COVERAGE) {
+ return new QAlphaCoverage();
+ }
+
+ if (state == GL_SCISSOR_TEST) {
+ return buildState(QStringLiteral("scissor"), QJsonValue(), type);
+ }
+
+ qCWarning(GLTFParserLog) << Q_FUNC_INFO << "unsupported render state:" << state;
+
+ return Q_NULLPTR;
+}
+
+QRenderState* GLTFParser::buildState(const QString& functionName, const QJsonValue &value, int &type)
+{
+ type = -1;
+ QJsonArray values = value.toArray();
+
+ if (functionName == QStringLiteral("blendColor")) {
+ type = GL_BLEND;
+ //TODO: support render state blendColor
+ qCWarning(GLTFParserLog) << Q_FUNC_INFO << "unsupported render state:" << functionName;
+ return Q_NULLPTR;
+ }
+
+ if (functionName == QStringLiteral("blendEquationSeparate")) {
+ type = GL_BLEND;
+ //TODO: support settings blendEquation alpha
+ QBlendEquation *blendEquation = new QBlendEquation;
+ blendEquation->setMode((QBlendEquation::BlendMode)values.at(0).toInt(GL_FUNC_ADD));
+ return blendEquation;
+ }
+
+ if (functionName == QStringLiteral("blendFuncSeparate")) {
+ type = GL_BLEND;
+ QBlendStateSeparate *blendState = new QBlendStateSeparate;
+ blendState->setSrcRGB((QBlendState::Blending)values.at(0).toInt(GL_ONE));
+ blendState->setSrcAlpha((QBlendState::Blending)values.at(1).toInt(GL_ONE));
+ blendState->setDstRGB((QBlendState::Blending)values.at(2).toInt(GL_ZERO));
+ blendState->setDstAlpha((QBlendState::Blending)values.at(3).toInt(GL_ZERO));
+ return blendState;
+ }
+
+ if (functionName == QStringLiteral("colorMask")) {
+ QColorMask *colorMask = new QColorMask;
+ colorMask->setRed(values.at(0).toBool(true));
+ colorMask->setGreen(values.at(1).toBool(true));
+ colorMask->setBlue(values.at(2).toBool(true));
+ colorMask->setAlpha(values.at(3).toBool(true));
+ return colorMask;
+ }
+
+ if (functionName == QStringLiteral("cullFace")) {
+ type = GL_CULL_FACE;
+ QCullFace *cullFace = new QCullFace;
+ cullFace->setMode((QCullFace::CullingMode)values.at(0).toInt(GL_BACK));
+ return cullFace;
+ }
+
+ if (functionName == QStringLiteral("depthFunc")) {
+ type = GL_DEPTH_TEST;
+ QDepthTest *depthTest = new QDepthTest;
+ depthTest->setFunc((QDepthTest::DepthFunc)values.at(0).toInt(GL_LESS));
+ return depthTest;
+ }
+
+ if (functionName == QStringLiteral("depthMask")) {
+ QDepthMask *depthMask = new QDepthMask;
+ depthMask->setMask(values.at(0).toBool(true));
+ }
+
+ if (functionName == QStringLiteral("depthRange")) {
+ //TODO: support render state depthRange
+ qCWarning(GLTFParserLog) << Q_FUNC_INFO << "unsupported render state:" << functionName;
+ return Q_NULLPTR;
+ }
+
+ if (functionName == QStringLiteral("frontFace")) {
+ QFrontFace *frontFace = new QFrontFace;
+ frontFace->setDirection((QFrontFace::FaceDir)values.at(0).toInt(GL_CCW));
+ return frontFace;
+ }
+
+ if (functionName == QStringLiteral("lineWidth")) {
+ //TODO: support render state lineWidth
+ qCWarning(GLTFParserLog) << Q_FUNC_INFO << "unsupported render state:" << functionName;
+ return Q_NULLPTR;
+ }
+
+ if (functionName == QStringLiteral("polygonOffset")) {
+ type = GL_POLYGON_OFFSET_FILL;
+ QPolygonOffset *polygonOffset = new QPolygonOffset;
+ polygonOffset->setFactor((float)values.at(0).toDouble(0.0f));
+ polygonOffset->setUnits((float)values.at(1).toDouble(0.0f));
+ return polygonOffset;
+ }
+
+ if (functionName == QStringLiteral("scissor")) {
+ type = GL_SCISSOR_TEST;
+ QScissorTest *scissorTest = new QScissorTest;
+ scissorTest->setLeft(values.at(0).toDouble(0.0f));
+ scissorTest->setBottom(values.at(1).toDouble(0.0f));
+ scissorTest->setWidth(values.at(2).toDouble(0.0f));
+ scissorTest->setHeight(values.at(3).toDouble(0.0f));
+ return scissorTest;
+ }
+
+ qCWarning(GLTFParserLog) << Q_FUNC_INFO << "unsupported render state:" << functionName;
+ return Q_NULLPTR;
+}
+
+} // namespace Qt3D
+
+QT_END_NAMESPACE
diff --git a/src/render/io/gltfparser_p.h b/src/plugins/sceneparsers/gltf/gltfparser_p.h
index 0ca5edc28..5aed37f53 100644
--- a/src/render/io/gltfparser_p.h
+++ b/src/plugins/sceneparsers/gltf/gltfparser_p.h
@@ -38,15 +38,12 @@
#ifndef GLTFPARSER_H
#define GLTFPARSER_H
-#include <Qt3DRenderer/qmeshdata.h>
+#include <QtCore/QJsonDocument>
+#include <QtCore/QMultiHash>
+
#include <Qt3DRenderer/qattribute.h>
-#include <Qt3DCore/qentity.h>
-#include <Qt3DRenderer/qtechnique.h>
#include <Qt3DRenderer/qbuffer.h>
-#include <QJsonDocument>
-#include <QMultiHash>
-#include <Qt3DRenderer/qabstractmesh.h>
-#include <QImage>
+#include <Qt3DRenderer/qmeshdata.h>
#include <Qt3DRenderer/private/abstractsceneparser_p.h>
@@ -62,44 +59,103 @@ class QEffect;
class QCamera;
class QCameraLens;
class QAbstractTextureProvider;
+class QRenderState;
+class QTechnique;
+class QParameter;
+class QEntity;
+class QGeometryRenderer;
+
+Q_DECLARE_LOGGING_CATEGORY(GLTFParserLog)
class GLTFParser : public AbstractSceneParser
{
Q_OBJECT
+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt3DRenderer.GLTFParser")
public:
GLTFParser();
+ ~GLTFParser();
void setBasePath(const QString& path);
- bool setJSON( QJsonDocument json );
+ bool setJSON( const QJsonDocument &json );
// SceneParserInterface interface
- void setSource(const QUrl &source) Q_DECL_OVERRIDE;
- bool isExtensionSupported(const QUrl &source) const Q_DECL_OVERRIDE;
-
- /**
- * @brief instantiate Create Nodes based on glTf JSON document
- * @return A new scene-graph fragment based on the provided glTf
- */
- QEntity *node(const QString &id) Q_DECL_OVERRIDE;
- QEntity *scene(const QString &id = QString()) Q_DECL_OVERRIDE;
+ void setSource(const QUrl &source) Q_DECL_FINAL;
+ bool isExtensionSupported(const QUrl &source) const Q_DECL_FINAL;
+ QEntity *node(const QString &id) Q_DECL_FINAL;
+ QEntity *scene(const QString &id = QString()) Q_DECL_FINAL;
private:
+ class BufferData
+ {
+ public:
+ BufferData();
+
+ BufferData(QJsonObject json);
+
+ quint64 length;
+ QString path;
+ QByteArray *data;
+ // type if ever useful
+ };
+
+ class ParameterData
+ {
+ public:
+ ParameterData();
+ ParameterData(QJsonObject json);
+
+ QString semantic;
+ int type;
+ };
+
+ class AccessorData
+ {
+ public:
+ AccessorData();
+ AccessorData(const QJsonObject& json);
+
+ QString bufferViewName;
+ QAttribute::DataType type;
+ uint dataSize;
+ int count;
+ int offset;
+ int stride;
+ };
+
static bool isGLTFPath(const QString &path);
+ static void renameFromJson(const QJsonObject& json, QObject * const object );
+ static QString standardUniformNamefromSemantic(const QString &semantic);
+ static QString standardAttributeNameFromSemantic(const QString &semantic);
QEntity *defaultScene();
- QMeshDataPtr mesh(const QString &id);
QMaterial *material(const QString &id);
- QCameraLens *camera(const QString &id);
+ QCameraLens *camera(const QString &id) const;
void parse();
+ void cleanup();
+
+ void processJSONBuffer(const QString &id, const QJsonObject &json);
+ void processJSONBufferView(const QString &id, const QJsonObject &json);
+ void processJSONShader(const QString &id, const QJsonObject &jsonObject);
+ void processJSONProgram(const QString &id, const QJsonObject &jsonObject);
+ void processJSONTechnique(const QString &id, const QJsonObject &jsonObject);
+ void processJSONAccessor(const QString &id, const QJsonObject &json);
+ void processJSONMesh(const QString &id, const QJsonObject &json);
+ void processJSONImage(const QString &id, const QJsonObject &jsonObject);
+ void processJSONTexture(const QString &id, const QJsonObject &jsonObject);
+
+ void loadBufferData();
+ void unloadBufferData();
+
+ QFile* resolveLocalData(QString path) const;
- void processJSONMesh( QString id, QJsonObject jsonObj );
- void processJSONAccessor(QString id, const QJsonObject &json);
- void processJSONBuffer(QString id, const QJsonObject &json);
- void processJSONBufferView(QString id, const QJsonObject &json);
+ QVariant parameterValueFromJSON(int type, const QJsonValue &value) const;
+ static QAbstractAttribute::DataType accessorTypeFromJSON(int componentType);
+ static uint accessorDataSizeFromJson(const QString &type);
- void processName( const QJsonObject& json, QObject* ins );
+ static QRenderState *buildStateEnable(int state);
+ static QRenderState *buildState(const QString& functionName, const QJsonValue &value, int &type);
QJsonDocument m_json;
QString m_basePath;
@@ -108,25 +164,13 @@ private:
// multi-hash because our QMeshData corresponds to a single primitive
// in glTf.
- QMultiHash<QString, QMeshDataPtr> m_meshDict;
+ QMultiHash<QString, QGeometryRenderer*> m_meshDict;
// GLTF assigns materials at the mesh level, but we do them as siblings,
// so record the association here for when we instantiate meshes
- QMap<QMeshData*, QString> m_meshMaterialDict;
+ QMap<QGeometryRenderer*, QString> m_meshMaterialDict;
- QMap<QString, QAttribute *> m_attributeDict;
-
- class BufferData
- {
- public:
- BufferData();
-
- BufferData(QJsonObject json);
-
- quint64 length;
- QString path;
- // type if ever useful
- };
+ QMap<QString, AccessorData> m_accessorDict;
QMap<QString, QMaterial*> m_materialCache;
@@ -137,25 +181,10 @@ private:
QMap<QString, QShaderProgram*> m_programs;
QMap<QString, QTechnique *> m_techniques;
- // glTF doesn't deal in effects, but we need a trivial one to wrap
- // up our techniques
- QMap<QString, QEffect*> m_effectProxies;
+ QMap<QParameter*, ParameterData> m_parameterDataDict;
QMap<QString, QAbstractTextureProvider*> m_textures;
- QMap<QString, QImage> m_images;
-
- QFile* resolveLocalData(QString path);
-
- void processJSONShader(QString id, QJsonObject jsonObj);
- void processJSONProgram(QString id, QJsonObject jsonObj);
- void processJSONTechnique(QString id, QJsonObject jsonObj);
-
- void processJSONImage(QString id, QJsonObject jsonObj);
- void processJSONTexture(QString id, QJsonObject jsonObj);
-
- QVariant parameterValueFromJSON(QParameter *p, QJsonValue val);
-
- //Render::RenderState *buildState(const QByteArray& nm, QJsonValue obj);
+ QMap<QString, QString> m_imagePaths;
};
} // namespace Qt3D
diff --git a/src/plugins/sceneparsers/sceneparsers.pro b/src/plugins/sceneparsers/sceneparsers.pro
index 53899e493..f7a922991 100644
--- a/src/plugins/sceneparsers/sceneparsers.pro
+++ b/src/plugins/sceneparsers/sceneparsers.pro
@@ -1,2 +1,4 @@
TEMPLATE = subdirs
config_assimp|win32:!wince*|osx: SUBDIRS += assimp
+SUBDIRS += gltf
+
diff --git a/src/render/frontend/qabstractsceneloader.cpp b/src/render/frontend/qabstractsceneloader.cpp
index 4108b81e5..539fdcf5e 100644
--- a/src/render/frontend/qabstractsceneloader.cpp
+++ b/src/render/frontend/qabstractsceneloader.cpp
@@ -38,7 +38,6 @@
#include "qabstractsceneloader_p.h"
#include <Qt3DRenderer/private/renderlogging_p.h>
#include <Qt3DRenderer/private/abstractsceneparser_p.h>
-#include <Qt3DRenderer/private/gltfparser_p.h>
#include <Qt3DCore/qscenepropertychange.h>
QT_BEGIN_NAMESPACE
diff --git a/src/render/io/gltfparser.cpp b/src/render/io/gltfparser.cpp
deleted file mode 100644
index 65c800fb0..000000000
--- a/src/render/io/gltfparser.cpp
+++ /dev/null
@@ -1,1110 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
-** Copyright (C) 2015 The Qt Company Ltd and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the Qt3D module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL3$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPLv3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or later as published by the Free
-** Software Foundation and appearing in the file LICENSE.GPL included in
-** the packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 2.0 requirements will be
-** met: http://www.gnu.org/licenses/gpl-2.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "gltfparser_p.h"
-
-#include "texturedata.h"
-#include <Qt3DRenderer/private/renderlogging_p.h>
-
-#include <Qt3DCore/qentity.h>
-#include <qabstractmesh.h>
-#include <qmaterial.h>
-#include <qtechnique.h>
-#include <qshaderprogram.h>
-#include <qeffect.h>
-#include <Qt3DCore/qcamera.h>
-#include <Qt3DCore/qtransform.h>
-#include <Qt3DCore/qmatrixtransform.h>
-#include <Qt3DCore/qcameralens.h>
-#include <Qt3DCore/private/qurlhelper_p.h>
-#include <qtexture.h>
-#include <qparameter.h>
-
-#include <QJsonDocument>
-#include <QJsonObject>
-#include <QJsonArray>
-#include <QFile>
-#include <QDir>
-#include <QFileInfo>
-#include <QQuaternion>
-#include <QMatrix4x4>
-#include <QColor>
-#include <QVector2D>
-#include <QVector3D>
-#include <QUrl>
-
-// need to move these to somewhere common?
-#include <Qt3DRenderer/private/renderstate_p.h>
-#include <Qt3DRenderer/private/blendstate_p.h>
-#include <private/qabstractmesh_p.h>
-
-QT_BEGIN_NAMESPACE
-
-namespace Qt3D {
-namespace {
-
-const QString KEY_CAMERA = QStringLiteral("camera");
-const QString KEY_CAMERAS = QStringLiteral("cameras");
-const QString KEY_SCENES = QStringLiteral("scenes");
-const QString KEY_NODES = QStringLiteral("nodes");
-const QString KEY_MESHES = QStringLiteral("meshes");
-const QString KEY_CHILDREN = QStringLiteral("children");
-const QString KEY_MATRIX = QStringLiteral("matrix");
-const QString KEY_TYPE = QStringLiteral("type");
-const QString KEY_PERSPECTIVE =QStringLiteral("perspective");
-const QString KEY_NAME = QStringLiteral("name");
-const QString KEY_COUNT = QStringLiteral("count");
-const QString KEY_YFOV = QStringLiteral("yfov");
-const QString KEY_ZNEAR = QStringLiteral("znear");
-const QString KEY_ZFAR = QStringLiteral("zfar");
-const QString KEY_MATERIALS = QStringLiteral("materials");
-const QString KEY_TECHNIQUE = QStringLiteral("technique");
-const QString KEY_VALUES = QStringLiteral("values");
-const QString KEY_BUFFERS = QStringLiteral("buffers");
-const QString KEY_SHADERS = QStringLiteral("shaders");
-const QString KEY_PROGRAMS = QStringLiteral("programs");
-const QString KEY_PROGRAM = QStringLiteral("program");
-const QString KEY_TECHNIQUES = QStringLiteral("techniques");
-const QString KEY_ACCESSORS = QStringLiteral("accessors");
-const QString KEY_IMAGES = QStringLiteral("images");
-const QString KEY_TEXTURES = QStringLiteral("textures");
-const QString KEY_SCENE = QStringLiteral("scene");
-const QString KEY_BUFFER = QStringLiteral("buffer");
-const QString KEY_TARGET = QStringLiteral("target");
-const QString KEY_BYTE_OFFSET = QStringLiteral("byteOffset");
-const QString KEY_BYTE_LENGTH = QStringLiteral("byteLength");
-const QString KEY_BYTE_STRIDE = QStringLiteral("byteStride");
-const QString KEY_PRIMITIVES = QStringLiteral("primitives");
-const QString KEY_PRIMITIVE = QStringLiteral("primitive");
-const QString KEY_MATERIAL = QStringLiteral("material");
-const QString KEY_ATTRIBUTES = QStringLiteral("attributes");
-const QString KEY_INDICES = QStringLiteral("indices");
-const QString KEY_PATH = QStringLiteral("path");
-const QString KEY_FORMAT = QStringLiteral("format");
-const QString KEY_PASSES = QStringLiteral("passes");
-const QString KEY_SOURCE = QStringLiteral("source");
-const QString KEY_SAMPLER = QStringLiteral("sampler");
-const QString KEY_SAMPLERS = QStringLiteral("samplers");
-const QString KEY_LENGTH = QStringLiteral("length");
-const QString KEY_SEMANTIC = QStringLiteral("semantic");
-const QString KEY_STATES = QStringLiteral("states");
-const QString KEY_UNIFORMS = QStringLiteral("uniforms");
-const QString KEY_PARAMETERS = QStringLiteral("parameters");
-const QString KEY_WRAP_S = QStringLiteral("wrapS");
-const QString KEY_MIN_FILTER = QStringLiteral("minFilter");
-const QString KEY_MAG_FILTER = QStringLiteral("magFilter");
-
-const QString KEY_INSTANCE_TECHNIQUE = QStringLiteral("instanceTechnique");
-const QString KEY_INSTANCE_PROGRAM = QStringLiteral("instanceProgram");
-const QString KEY_BUFFER_VIEWS = QStringLiteral("bufferViews");
-const QString KEY_BUFFER_VIEW = QStringLiteral("bufferView");
-const QString KEY_VERTEX_SHADER = QStringLiteral("vertexShader");
-const QString KEY_FRAGMENT_SHADER = QStringLiteral("fragmentShader");
-const QString KEY_INTERNAL_FORMAT = QStringLiteral("internalFormat");
-
-//Parameter::StandardUniform parseSemanticName(const QByteArray& s)
-//{
-// if (s == "MODEL") return Parameter::ModelMatrix;
-// if (s == "VIEW") return Parameter::ViewMatrix;
-// if (s == "PROJECTION") return Parameter::ProjectionMatrix;
-// if (s == "MODELVIEW") return Parameter::ModelView;
-// if (s == "MODELVIEWPROJECTION")
-// return Parameter::ModelViewProjection;
-
-// if (s == "MODELINVERSE") return Parameter::ModelInverse;
-// if (s == "VIEWINVERSE") return Parameter::ViewInverse;
-// if (s == "PROJECTIONINVERSE")
-// return Parameter::ProjectionInverse;
-// if (s == "MODELVIEWINVERSE")
-// return Parameter::ModelViewInverse;
-// if (s == "MODELVIEWPROJECTIONINVERSE")
-// return Parameter::ModelViewProjectionInverse;
-
-// if (s == "MODELINVERSETRANSPOSE")
-// return Parameter::ModelNormal;
-// if (s == "MODELVIEWINVERSETRANSPOSE")
-// return Parameter::ModelViewNormal;
-
-// return Parameter::None;
-//}
-
-//QParameter::OpenGLTypes parseType(const QByteArray &s)
-//{
-// if (s == "BYTE") return QParameter::Undefined;
-// if (s == "BYTE_VEC2") return QParameter::Undefined;
-// if (s == "BYTE_VEC3") return QParameter::Undefined;
-// if (s == "BYTE_VEC4") return QParameter::Undefined;
-// if (s == "UNSIGNED_BYTE") return QParameter::Undefined;
-// if (s == "UNSIGNED_BYTE_VEC2") return QParameter::Undefined;
-// if (s == "UNSIGNED_BYTE_VEC3") return QParameter::Undefined;
-// if (s == "UNSIGNED_BYTE_VEC4") return QParameter::Undefined;
-// if (s == "SHORT") return QParameter::Undefined;
-// if (s == "SHORT_VEC2") return QParameter::Undefined;
-// if (s == "SHORT_VEC3") return QParameter::Undefined;
-// if (s == "SHORT_VEC4") return QParameter::Undefined;
-// if (s == "UNSIGNED_SHORT") return QParameter::Undefined;
-// if (s == "UNSIGNED_SHORT_VEC2") return QParameter::Undefined;
-// if (s == "UNSIGNED_SHORT_VEC3") return QParameter::Undefined;
-// if (s == "UNSIGNED_SHORT_VEC4") return QParameter::Undefined;
-// if (s == "FLOAT") return QParameter::Float;
-// if (s == "FLOAT_VEC2") return QParameter::FloatVec2;
-// if (s == "FLOAT_VEC3") return QParameter::FloatVec3;
-// if (s == "FLOAT_VEC4") return QParameter::FloatVec4;
-// if (s == "FLOAT_MAT2") return QParameter::FloatMat2;
-// if (s == "FLOAT_MAT2") return QParameter::FloatMat3;
-// if (s == "FLOAT_MAT2") return QParameter::FloatMat4;
-// if (s == "INT") return QParameter::Int;
-// if (s == "INT_VEC2") return QParameter::IntVec2;
-// if (s == "INT_VEC3") return QParameter::IntVec3;
-// if (s == "INT_VEC4") return QParameter::IntVec4;
-// if (s == "BOOL") return QParameter::Bool;
-// if (s == "BOOL_VEC2") return QParameter::BoolVec2;
-// if (s == "BOOL_VEC3") return QParameter::BoolVec3;
-// if (s == "BOOL_VEC4") return QParameter::BoolVec4;
-
-// return QParameter::Undefined;
-//}
-
-QAbstractAttribute::DataType typeFromGLType(GLint dataType, uint &dataCount)
-{
- switch (dataType) {
-
- case GL_UNSIGNED_SHORT:
- dataCount = 1;
- return QAbstractAttribute::UnsignedShort;
-
- case GL_UNSIGNED_BYTE:
- dataCount = 1;
- return QAbstractAttribute::UnsignedByte;
-
- case GL_UNSIGNED_INT:
- dataCount = 1;
- return QAbstractAttribute::UnsignedInt;
-
- case GL_SHORT:
- dataCount = 1;
- return QAbstractAttribute::Short;
-
- case GL_BYTE:
- dataCount = 1;
- return QAbstractAttribute::Byte;
-
- case GL_INT:
- dataCount = 1;
- return QAbstractAttribute::Int;
-
- case GL_FLOAT:
- dataCount = 1;
- break;
-
- case GL_FLOAT_VEC2:
- dataCount = 2;
- break;
-
- case GL_FLOAT_VEC3:
- dataCount = 3;
- break;
-
- case GL_FLOAT_VEC4:
- dataCount = 4;
- break;
-
-// TO DO: Handle doubles
-
- default:
- Q_UNREACHABLE();
- }
-
- return QAbstractAttribute::Float;
-}
-
-} // of anonymous namespace
-
-class GLTFParserMeshPrivate;
-
-class GLTFParserMeshFunctor : public QAbstractMeshFunctor
-{
-public:
- explicit GLTFParserMeshFunctor(QMeshDataPtr meshData = QMeshDataPtr());
- QMeshDataPtr operator ()() Q_DECL_OVERRIDE;
- bool operator ==(const QAbstractMeshFunctor &other) const Q_DECL_OVERRIDE;
- QT3D_FUNCTOR(GLTFParserMeshFunctor)
-private:
- QMeshDataPtr m_meshData;
-};
-
-class GLTFParserMesh : public QAbstractMesh
-{
- Q_OBJECT
-public:
- explicit GLTFParserMesh(QNode *parent = 0);
-
- void setData(QMeshDataPtr data);
- QAbstractMeshFunctorPtr meshFunctor() const Q_DECL_FINAL;
-
-protected:
- void copy(const QNode *ref) Q_DECL_FINAL;
-
-private:
- QT3D_CLONEABLE(GLTFParserMesh)
- Q_DECLARE_PRIVATE(GLTFParserMesh)
-};
-
-class GLTFParserMeshPrivate : public QAbstractMeshPrivate
-{
-public:
- GLTFParserMeshPrivate()
- : QAbstractMeshPrivate()
- {}
-
- Q_DECLARE_PUBLIC(GLTFParserMesh)
- QMeshDataPtr m_meshData;
-};
-
-GLTFParser::GLTFParser() : AbstractSceneParser(),
- m_parseDone(false)
-{
-}
-
-bool GLTFParser::isGLTFPath(const QString& path)
-{
- QFileInfo finfo(path);
- if (!finfo.exists())
- return false;
-
- // might need to detect other things in the future, but would
- // prefer to avoid doing a full parse.
- return (finfo.suffix().toLower() == QStringLiteral("json"));
-}
-
-void GLTFParser::setBasePath(const QString& path)
-{
- m_basePath = path;
-}
-
-bool GLTFParser::setJSON( QJsonDocument json )
-{
- if ( !json.isObject() ) {
- return false;
- }
-
- m_json = json;
- m_parseDone = false;
-
- m_meshDict.clear();
- m_attributeDict.clear();
- m_defaultScene.clear();
-
- return true;
-}
-
-/*!
- * Sets the \a path used by the parser to load the scene file.
- * If the file is valid, parsing is automatically triggered.
- */
-void GLTFParser::setSource(const QUrl &source)
-{
- const QString path = QUrlHelper::urlToLocalFileOrQrc(source);
- QFileInfo finfo(path);
- if (!finfo.exists()) {
- qWarning() << "missing file:" << path;
- return;
- }
- QFile f(path);
- f.open(QIODevice::ReadOnly);
-
- if (!setJSON(QJsonDocument::fromJson(f.readAll()))) {
- qWarning() << "not a JSON document";
- return;
- }
-
- setBasePath(finfo.dir().absolutePath());
-}
-
-/*!
- * Returns true if the extension of \a path is supported by the
- * GLTF parser.
- */
-bool GLTFParser::isExtensionSupported(const QUrl &source) const
-{
- const QString path = QUrlHelper::urlToLocalFileOrQrc(source);
- return GLTFParser::isGLTFPath(path);
-}
-
-QMeshDataPtr GLTFParser::mesh(const QString &id)
-{
- parse();
- if (m_meshDict.contains(id))
- return m_meshDict.value(id);
-
- qWarning() << "Unknown mesh" << id << "in GLTF file" << m_basePath;
- return QMeshDataPtr();
-}
-
-QEntity* GLTFParser::defaultScene()
-{
- parse();
- if (m_defaultScene.isEmpty()) {
- qWarning() << Q_FUNC_INFO << "no default scene";
- return NULL;
- }
-
- return scene(m_defaultScene);
-}
-
-QEntity* GLTFParser::scene(const QString &id)
-{
- parse();
-
- QJsonObject scenes = m_json.object().value(KEY_SCENES).toObject();
- if (!scenes.contains(id)) {
- qWarning() << "GLTF: no such scene" << id << "in file" << m_basePath;
- return defaultScene();
- }
-
- QJsonObject sceneObj = scenes.value(id).toObject();
- QEntity* sceneEntity = new QEntity;
- foreach (QJsonValue nnv, sceneObj.value(KEY_NODES).toArray()) {
- QString nodeName = nnv.toString();
- QEntity* child = node(nodeName);
- if (!child)
- continue;
- child->setParent(sceneEntity);
- }
-
- return sceneEntity;
-}
-
-QEntity* GLTFParser::node(const QString &id)
-{
- QJsonObject nodes = m_json.object().value(KEY_NODES).toObject();
- if (!nodes.contains(id)) {
- qWarning() << "unknown node" << id << "in GLTF file" << m_basePath;
- return NULL;
- }
-
- QJsonObject jsonObj = nodes.value(id).toObject();
- QEntity* result( new QEntity );
- parse();
-
- if ( jsonObj.contains(KEY_CHILDREN) )
- {
- foreach (QJsonValue c, jsonObj.value(KEY_CHILDREN).toArray()) {
- QEntity* child = node(c.toString());
- if (!child)
- continue;
- child->setParent(result);
- }
- }
-
- if ( jsonObj.contains(KEY_MESHES) )
- {
- typedef QList<GLTFParserMesh *> MeshList;
- QMap<QString, MeshList> materialDict;
-
- foreach (QJsonValue m, jsonObj.value(KEY_MESHES).toArray())
- {
- if (!m_meshDict.contains(m.toString())) {
- qWarning() << "node" << id << "references unknown mesh" << m.toString();
- continue;
- }
-
- foreach (QMeshDataPtr md, m_meshDict.values(m.toString())) {
- QString matId = m_meshMaterialDict[md.data()];
- GLTFParserMesh* meshComp = new GLTFParserMesh;
- meshComp->setData(md);
- materialDict[matId].append(meshComp);
- }
- }
-
- if (materialDict.size() == 1) {
- // common case
- result->addComponent(material(materialDict.firstKey()));
- foreach (GLTFParserMesh* m, materialDict.first())
- result->addComponent(m);
- } else {
- // need to make a child entity per material
- foreach (QString matId, materialDict.keys()) {
- QEntity* subEntity(new QEntity);
- subEntity->setParent(result);
-
- subEntity->addComponent(material(matId));
- foreach (GLTFParserMesh* m, materialDict.value(matId))
- subEntity->addComponent(m);
- } // of distinct material iteration
- } // of multiple materials case
- }
-
- processName(jsonObj, result);
-
- if ( jsonObj.contains(KEY_MATRIX) )
- {
- QMatrix4x4 m(Qt::Uninitialized);
-
- QJsonArray matrixValues = jsonObj.value(KEY_MATRIX).toArray();
- for (int i=0; i<16; ++i) {
- double v = matrixValues.at( i ).toDouble();
- m(i % 4, i >> 2) = v;
- }
-
- // ADD MATRIX TRANSFORM COMPONENT TO ENTITY
- QTransform *trans = new QTransform();
- trans->addTransform(new QMatrixTransform(m));
- result->addComponent(trans);
- }
-
- if ( jsonObj.contains(KEY_CAMERA) )
- {
- QCameraLens* cam = camera( jsonObj.value(KEY_CAMERA).toString() );
- if (!cam) {
- qWarning() << "failed to build camera:" << jsonObj.value(KEY_CAMERA)
- << "on node" << id;
- } else {
- result->addComponent(cam);
- }
- } // of have camera attribute
-
- return result;
-}
-
-// Get rid of miniwindef.h clobbering legal variable names
-#if defined(near)
-#undef near
-#endif
-
-#if defined(far)
-#undef far
-#endif
-
-QCameraLens* GLTFParser::camera(const QString &id)
-{
- parse();
- QJsonObject cams = m_json.object().value(KEY_CAMERAS).toObject();
- if (!cams.contains(id)) {
- qWarning() << "unknown camera" << id << "in GLTF file" << m_basePath;
- return Q_NULLPTR;
- }
-
- QJsonObject jsonObj = cams.value(id).toObject();
- QByteArray camTy = jsonObj.value(KEY_TYPE).toString().toUtf8();
-
- if (camTy == "perspective") {
- if (!jsonObj.contains(KEY_PERSPECTIVE)) {
- qWarning() << "camera:" << id << "missing 'perspective' object";
- return Q_NULLPTR;
- }
-
- QJsonObject pObj = jsonObj.value(KEY_PERSPECTIVE).toObject();
- double yfov = pObj.value(KEY_YFOV).toDouble();
- double near = pObj.value(KEY_ZNEAR).toDouble();
- double far = pObj.value(KEY_ZFAR).toDouble();
-
- QCameraLens* result = new QCameraLens;
- result->setPerspectiveProjection(yfov, 1.0, near, far);
- return result;
- } else if (camTy == "orthographic") {
- qWarning() << Q_FUNC_INFO << "implement me";
-
- return Q_NULLPTR;
- } else {
- qWarning() << "camera:" << id << "has unsupported type:" << camTy;
- return Q_NULLPTR;
- }
-}
-
-QMaterial* GLTFParser::material(const QString &id)
-{
- parse();
-
- if (m_materialCache.contains(id))
- return m_materialCache.value(id);
-
- QJsonObject mats = m_json.object().value(KEY_MATERIALS).toObject();
- if (!mats.contains(id)) {
- qWarning() << "unknown material" << id << "in GLTF file" << m_basePath;
- return NULL;
- }
-
- QJsonObject jsonObj = mats.value(id).toObject();
-
- QJsonObject tech = jsonObj.value(KEY_INSTANCE_TECHNIQUE).toObject();
- QString tname = tech.value(KEY_TECHNIQUE).toString();
- if (!m_techniques.contains(tname)) {
- qWarning() << "unknown technique" << tname <<
- "for material" << id << "in GLTF file" << m_basePath;
- return NULL;
- }
-
- QTechnique *technique = m_techniques.value(tname);
- if (!m_effectProxies.contains(tname)) {
- QEffect* eff = new QEffect;
- eff->setObjectName(tname);
- eff->addTechnique(technique);
- m_effectProxies[tname] = eff;
- }
-
- QMaterial* mat = new QMaterial;
- mat->setEffect(m_effectProxies[tname]);
-
- processName(jsonObj, mat);
-
-// QJsonObject values = tech.value(KEY_VALUES).toObject();
-// foreach (QString vName, values.keys()) {
-// QParameter* param = technique->parameterForName(vName);
-// if (!param) {
-// qWarning() << "unknown parameter:" << vName << "in technique" << tname
-// << "processing material" << id;
-// continue;
-// }
-
-// if (param->isTextureType()) {
-// QString textureId = values.value(vName).toString();
-// if (!m_textures.contains(textureId)) {
-// qWarning() << "unknown texture" << textureId << "for parameter" << vName
-// << "of material" << id;
-// } else {
-// mat->setTextureParameter(vName, m_textures.value(textureId));
-// }
-// } else {
-// // QVariant var = parameterValueFromJSON(param, values.value(vName));
-// mat->addParameter(param);
-// }
-// } // of material technique-instance values iteration
-
- m_materialCache[id] = mat;
- return mat;
-}
-
-void GLTFParser::parse()
-{
- if (m_parseDone)
- return;
-
- QJsonObject buffers = m_json.object().value(KEY_BUFFERS).toObject();
- foreach (QString nm, buffers.keys()) {
- processJSONBuffer( nm, buffers.value(nm).toObject() );
- }
-
- QJsonObject views = m_json.object().value(KEY_BUFFER_VIEWS).toObject();
- foreach (QString nm, views.keys()) {
- processJSONBufferView( nm, views.value(nm).toObject() );
- }
-
- QJsonObject shaders = m_json.object().value(KEY_SHADERS).toObject();
- foreach (QString nm, shaders.keys()) {
- processJSONShader( nm, shaders.value(nm).toObject() );
- }
-
- QJsonObject programs = m_json.object().value(KEY_PROGRAMS).toObject();
- foreach (QString nm, programs.keys()) {
- processJSONProgram( nm, programs.value(nm).toObject() );
- }
-
- QJsonObject techniques = m_json.object().value(KEY_TECHNIQUES).toObject();
- foreach (QString nm, techniques.keys()) {
- processJSONTechnique( nm, techniques.value(nm).toObject() );
- }
-
- QJsonObject attrs = m_json.object().value(KEY_ACCESSORS).toObject();
- foreach (QString nm, attrs.keys()) {
- processJSONAccessor( nm, attrs.value(nm).toObject() );
- }
-
- QJsonObject meshes = m_json.object().value(KEY_MESHES).toObject();
- foreach (QString nm, meshes.keys()) {
- processJSONMesh( nm, meshes.value(nm).toObject() );
- }
-
- QJsonObject images = m_json.object().value(KEY_IMAGES).toObject();
- foreach (QString nm, images.keys()) {
- processJSONImage( nm, images.value(nm).toObject() );
- }
-
- QJsonObject textures = m_json.object().value(KEY_TEXTURES).toObject();
- foreach (QString nm, textures.keys()) {
- processJSONTexture(nm, textures.value(nm).toObject() );
- }
-
- m_defaultScene = m_json.object().value(KEY_SCENE).toString();
- m_parseDone = true;
-}
-
-void GLTFParser::processJSONBuffer( QString id, const QJsonObject& json )
-{
- // simply cache buffers for lookup by buffer-views
- m_bufferDatas[id] = BufferData(json);
-}
-
-void GLTFParser::processJSONBufferView( QString id, const QJsonObject& json )
-{
- QString bufName = json.value(KEY_BUFFER).toString();
- if (!m_bufferDatas.contains(bufName)) {
- qWarning() << "unknown buffer:" << bufName << "processing view:" << id;
- return;
- }
-
- int target = json.value(KEY_TARGET).toInt();
- QBuffer::BufferType ty(QBuffer::VertexBuffer);
-
- switch (target) {
- case GL_ARRAY_BUFFER: ty = QBuffer::VertexBuffer; break;
- case GL_ELEMENT_ARRAY_BUFFER: ty = QBuffer::IndexBuffer; break;
- default:
- qWarning() << Q_FUNC_INFO << "buffer" << id << "unsupported target:" << target;
- return;
- }
-
- quint64 offset = 0;
- if (json.contains(KEY_BYTE_OFFSET)) {
- offset = json.value(KEY_BYTE_OFFSET).toInt();
- qCDebug(Render::Io) << "bv:" << id << "has offset:" << offset;
- }
-
- quint64 len = json.value(KEY_BYTE_LENGTH).toInt();
- QFile* f = resolveLocalData(m_bufferDatas[bufName].path);
- if (!f->seek(offset)) {
- qWarning() << "failed to seek to offset in file for bufferView:" << id << offset;
- }
-
- QByteArray bytes = f->read(len);
- if (bytes.count() != (int) len) {
- qWarning() << "failed to read sufficient bytes from:" << m_bufferDatas[bufName].path
- << "for view" << id;
- }
- delete f;
-
- QBuffer *b(new QBuffer(ty));
- b->setData(bytes);
- m_buffers[id] = b;
-}
-
-void GLTFParser::processJSONAccessor( QString id, const QJsonObject& json )
-{
- QString bvName = json.value(KEY_BUFFER_VIEW).toString();
- if (!m_buffers.contains(bvName)) {
- qWarning() << "unknown buffer-view:" << bvName << "processing accessor:" << id;
- return;
- }
-
- QBuffer *buf = m_buffers.value(bvName);
- int offset = 0, stride = 0;
- int type = json.value(KEY_TYPE).toInt();
- int count = json.value(KEY_COUNT).toInt();
-
- if ( json.contains(KEY_BYTE_OFFSET))
- offset = json.value(KEY_BYTE_OFFSET).toInt();
- if ( json.contains(KEY_BYTE_STRIDE))
- stride = json.value(KEY_BYTE_STRIDE).toInt();
-
- uint dataSize = 0;
- QAttribute::DataType dataType = typeFromGLType(type, dataSize);
-
- QAttribute *attr( new QAttribute( buf, dataType, dataSize, count, offset, stride ) );
- m_attributeDict[id] = attr;
-}
-
-void GLTFParser::processJSONMesh( QString id, QJsonObject jsonObj )
-{
- QJsonArray primsArray = jsonObj.value(KEY_PRIMITIVES).toArray();
- Q_FOREACH (QJsonValue primVal, primsArray) {
- QJsonObject primObj = primVal.toObject();
- int type = primObj.value(KEY_PRIMITIVE).toInt();
- QString material = primObj.value(KEY_MATERIAL).toString();
-
- if ( material.isEmpty()) {
- qCWarning(Render::Io) << "malformed primitive on " << id << ", missing material value"
- << material;
- continue;
- }
-
- QMeshDataPtr md(new QMeshData(static_cast<QMeshData::PrimitiveType>(type)));
- m_meshMaterialDict[md.data()] = material;
-
- QJsonObject attrs = primObj.value(KEY_ATTRIBUTES).toObject();
- Q_FOREACH (QString attrName, attrs.keys()) {
- QString k = attrs.value(attrName).toString();
- if (!m_attributeDict.contains(k)) {
- qCWarning(Render::Io) << "unknown attribute accessor:" << k << "on mesh" << id;
- continue;
- }
-
- md->addAttribute(attrName, m_attributeDict[k]);
-
- // qCDebug(Render::rIo) << "DUMP of:" << attrName;
- // m_attributeDict[k]->dump(20);
- }
-
- if ( primObj.contains(KEY_INDICES)) {
- QString k = primObj.value(KEY_INDICES).toString();
- if (!m_attributeDict.contains(k)) {
- qCWarning(Render::Io) << "unknown index accessor:" << k << "on mesh" << id;
- } else {
- md->setIndexAttribute(m_attributeDict[k]);
- // m_attributeDict[k]->dump(100);
- }
- } // of has indices
-
- m_meshDict.insert( id, md );
- } // of primitives iteration
-}
-
-void GLTFParser::processName(const QJsonObject &json, QObject *ins)
-{
- if ( json.contains(KEY_NAME) )
- {
- ins->setObjectName( json.value(KEY_NAME).toString() );
- }
-}
-
-void GLTFParser::processJSONProgram( QString id, QJsonObject jsonObj)
-{
- QShaderProgram* prog = new QShaderProgram;
- prog->setObjectName(id);
-
- QString fragName = jsonObj.value(KEY_FRAGMENT_SHADER).toString(),
- vertName = jsonObj.value(KEY_VERTEX_SHADER).toString();
- if (!m_shaderPaths.contains(fragName) || !m_shaderPaths.contains(vertName)) {
- qCWarning(Render::Io) << Q_FUNC_INFO << "program:" << id << "missing shader:" <<
- fragName << vertName;
- return;
- }
-
- prog->setFragmentShaderCode(Qt3D::QShaderProgram::loadSource(QUrl(m_shaderPaths[fragName])));
- prog->setVertexShaderCode(Qt3D::QShaderProgram::loadSource(QUrl(m_shaderPaths[vertName])));
- m_programs[id] = prog;
-}
-
-void GLTFParser::processJSONShader( QString id, QJsonObject jsonObj)
-{
- // shaders are trivial for the moment, defer the real work
- // to the program section
- QString path = jsonObj.value(KEY_PATH).toString();
-
- QFileInfo info(m_basePath, path);
- if (!info.exists()) {
- qCWarning(Render::Io) << "can't find shader" << id << "from path" << path;
- return;
- }
-
- m_shaderPaths[id] = info.absoluteFilePath();
-}
-
-void GLTFParser::processJSONImage( QString id, QJsonObject jsonObj)
-{
- QString path = jsonObj.value(KEY_PATH).toString();
- QFileInfo info(m_basePath, path);
- if (!info.exists()) {
- qCWarning(Render::Io)<< "can't find image" << id << "from path" << path;
- return;
- }
-
- QImage img(info.absoluteFilePath());
- if (img.isNull()) {
- qCWarning(Render::Io) << "failed to load image:" << info.absoluteFilePath();
- return;
- }
-
- m_images[id] = img;
-}
-
-void GLTFParser::processJSONTexture( QString id, QJsonObject jsonObj)
-{
- Q_UNUSED(id);
- Q_UNUSED(jsonObj);
-// int target = jsonObj.value(KEY_TARGET).toInt();
-// QAbstractTextureProvider* tex = new QAbstractTextureProvider(static_cast<QAbstractTextureProvider::Target>(target));
-
-
-// // TODO: Choose suitable internal format - may vary on OpenGL context type
-// //int pixelFormat = jsonObj.value(KEY_FORMAT).toInt();
-// //int internalFormat = jsonObj.value(KEY_INTERNAL_FORMAT).toInt();
-
-// tex->setFormat(QAbstractTextureProvider::RGBA8_UNorm /* static_cast<QOpenGLTexture::TextureFormat>(internalFormat)*/);
-
-// QString samplerId = jsonObj.value(KEY_SAMPLER).toString();
-// QString source = jsonObj.value(KEY_SOURCE).toString();
-// if (!m_images.contains(source)) {
-// qCWarning(Render::Io) << "texture" << id << "references missing image" << source;
-// return;
-// }
-
-// tex->setFromQImage(m_images[source]);
-
-// QJsonObject samplersDict(m_json.object().value(KEY_SAMPLERS).toObject());
-// if (!samplersDict.contains(samplerId)) {
-// qCWarning(Render::Io) << "texture" << id << "references unknown sampler" << samplerId;
-// return;
-// }
-
-// QJsonObject sampler = samplersDict.value(samplerId).toObject();
-
-// tex->setWrapMode(QTextureWrapMode(static_cast<QTextureWrapMode::WrapMode>(sampler.value(KEY_WRAP_S).toInt())));
-// tex->setMinificationFilter(static_cast<QAbstractTextureProvider::Filter>(sampler.value(KEY_MIN_FILTER).toInt()));
-// tex->setMagnificationFilter(static_cast<QAbstractTextureProvider::Filter>(sampler.value(KEY_MAG_FILTER).toInt()));
-
-// m_textures[id] = tex;
-}
-
-void GLTFParser::processJSONTechnique( QString id, QJsonObject jsonObj )
-{
- QTechnique *t = new QTechnique;
- t->setObjectName(id);
-
- QHash<QString, QParameter*> paramDict;
- QJsonObject params = jsonObj.value(KEY_PARAMETERS).toObject();
- Q_FOREACH (QString pname, params.keys()) {
- QJsonObject po = params.value(pname).toObject();
-
- // int dataType = po.value(KEY_TYPE).toInt();
- QString semantic = po.value(KEY_SEMANTIC).toString();
- // The Standard has changed, it doesn't return the raw int value for a type
- // But a string
-// QParameter* p = new QParameter(pname, parseType(po.value(KEY_TYPE).toString().toUtf8()), t);
-// Parameter::StandardUniform su = parseSemanticName(semantic.toUtf8());
-// if (su != Parameter::None) {
-// p->setStandardUniform(su);
-// } else {
-// // should really verify it's an attribute parameter?
-// // but what would be the way to do that?
-// // check the accessor dict?
-// p->setMeshAttributeName(semantic);
-// }
-
-// t->addParameter(p);
-
-// paramDict[pname] = p;
- } // of parameters iteration
-
- QJsonObject passes = jsonObj.value(KEY_PASSES).toObject();
- Q_FOREACH (QString pname, passes.keys()) {
- QJsonObject po = passes.value(pname).toObject();
- QJsonObject ip = po.value(KEY_INSTANCE_PROGRAM).toObject();
-
- QString programName = ip.value(KEY_PROGRAM).toString();
- if (!m_programs.contains(programName)) {
- qWarning() << Q_FUNC_INFO << "technique" << id << "pass" << pname
- << ": missing program" << programName;
- continue;
- }
-
- QRenderPass* pass = new QRenderPass;
- pass->setShaderProgram(m_programs[programName]);
-
- QJsonObject attrs = ip.value(KEY_ATTRIBUTES).toObject();
- Q_FOREACH ( QString attrName, attrs.keys() ) {
- QString pname = attrs.value(attrName).toString();
- // TO DO : Correct that
- // pass->addAttributeBinding(paramDict[pname], attrName);
- } // of program-instance attributes
-
- QJsonObject uniforms = ip.value(KEY_UNIFORMS).toObject();
- Q_FOREACH (QString uniformName, uniforms.keys()) {
- QString pname = uniforms.value(uniformName).toString();
- // TO DO : Correct that
- // pass->addUniformBinding(paramDict[pname], uniformName);
- } // of program-instance attributes
-
- // TODO: Use public state api only here
-// QJsonObject states = po.value(KEY_STATES).toObject();
-// Render::RenderStateSet* ss = new Render::RenderStateSet;
-
-// Q_FOREACH (QString stateName, states.keys()) {
-// Render::RenderState* s= buildState(stateName.toUtf8(), states.value(stateName));
-// if (!s)
-// continue;
-
-// ss->addState(s);
-// } // of program-instance attributes
-
-// pass->setStateSet(ss);
- t->addPass(pass);
- } // of passes iteration
-
- m_techniques[id] = t;
-}
-
-//Render::RenderState* GLTFParser::buildState(const QByteArray& nm, QJsonValue v)
-//{
-// if (nm == "blendEnable") {
-// return NULL; // will see a blendEquation spec too
-// }
-
-// if (nm == "blendFunc") {
-// QJsonObject obj = v.toObject();
-// GLenum srcF = static_cast<GLenum>(obj.value(QStringLiteral("sfactor")).toInt());
-// GLenum dstF = static_cast<GLenum>(obj.value(QStringLiteral("dfactor")).toInt());
-// return Render::BlendState::getOrCreate(srcF, dstF);
-// }
-
-// if (nm == "blendEquation") {
-// return Render::BlendEquation::getOrCreate(static_cast<GLenum>(v.toInt()));
-// }
-
-// if (nm == "cullFaceEnable" && v.toInt()) {
-// return Render::CullFace::getOrCreate(GL_BACK);
-// }
-
-// if (nm == "depthTestEnable" && v.toInt()) {
-// return Render::DepthTest::getOrCreate(GL_LESS);
-// }
-
-// if (nm == "depthMask") {
-// return Render::DepthMask::getOrCreate(v.toInt() ? GL_TRUE : GL_FALSE);
-// }
-
-// qCWarning(Render::Io) << Q_FUNC_INFO << "unsupported gltf state:" << nm;
-// return NULL;
-//}
-
-QFile *GLTFParser::resolveLocalData(QString path)
-{
- QDir d(m_basePath);
- Q_ASSERT(d.exists());
-
- QString absPath = d.absoluteFilePath(path);
- QFile* f = new QFile(absPath);
- f->open(QIODevice::ReadOnly);
- return f;
-}
-
-GLTFParser::BufferData::BufferData() :
- length(0)
-{
-}
-
-GLTFParser::BufferData::BufferData(QJsonObject json)
-{
- path = json.value(KEY_PATH).toString();
- length = json.value(KEY_LENGTH).toInt();
- // url
-}
-
-QVariant GLTFParser::parameterValueFromJSON(QParameter* p, QJsonValue val)
-{
- Q_UNUSED(p);
- Q_UNUSED(val);
-// switch (p->datatype()) {
-// case QParameter::Bool:
-// return val.toBool();
-
-// case QParameter::Float:
-// return val.toDouble();
-
-// case QParameter::FloatVec2: {
-// QJsonArray a = val.toArray();
-// return QVector2D(a[0].toDouble(), a[1].toDouble());
-// }
-
-// case QParameter::FloatVec3: {
-// QJsonArray a = val.toArray();
-// return QVector3D(a[0].toDouble(), a[1].toDouble(), a[3].toDouble());
-// }
-
-// case QParameter::FloatVec4: {
-// QJsonArray a = val.toArray();
-// return QVector4D(a[0].toDouble(),
-// a[1].toDouble(),
-// a[2].toDouble(),
-// a[3].toDouble());
-// }
-
-// case QParameter::FloatMat4: {
-// QJsonArray a = val.toArray();
-
-// QMatrix4x4 m(Qt::Uninitialized);
-// for (int i=0; i<16; ++i) {
-// m(i % 4, i / 4) = a[i].toDouble();
-// }
-// return m;
-// }
-
-// default:
-// qCWarning(Render::Io) << Q_FUNC_INFO << "unhandled type:" << QString::number(p->datatype(), 16);
-// }
-
- return QVariant();
-}
-
-void GLTFParserMesh::copy(const QNode *ref)
-{
- QAbstractMesh::copy(ref);
- const GLTFParserMesh *gltfMesh = static_cast<const GLTFParserMesh*>(ref);
- d_func()->m_meshData = gltfMesh->d_func()->m_meshData;
-}
-
-GLTFParserMesh::GLTFParserMesh(QNode *parent)
- : QAbstractMesh(*new GLTFParserMeshPrivate, parent)
-{
-}
-
-
-void GLTFParserMesh::setData(QMeshDataPtr data)
-{
- Q_D(GLTFParserMesh);
- d->m_meshData = data;
- QAbstractMesh::update();
-}
-
-QAbstractMeshFunctorPtr GLTFParserMesh::meshFunctor() const
-{
- Q_D(const GLTFParserMesh);
- return QAbstractMeshFunctorPtr(new GLTFParserMeshFunctor(d->m_meshData));
-}
-
-GLTFParserMeshFunctor::GLTFParserMeshFunctor(QMeshDataPtr meshData)
- : QAbstractMeshFunctor()
- , m_meshData(meshData)
-{
-}
-
-QMeshDataPtr GLTFParserMeshFunctor::operator ()()
-{
- return m_meshData;
-}
-
-bool GLTFParserMeshFunctor::operator ==(const QAbstractMeshFunctor &) const
-{
- return false;
-}
-
-} // namespace Qt3D
-
-QT_END_NAMESPACE
-
-Q_DECLARE_METATYPE(Qt3D::GLTFParserMeshFunctor)
-
-#include "gltfparser.moc"
diff --git a/src/render/io/render-io.pri b/src/render/io/render-io.pri
index c96e4617e..6ac63d9c5 100644
--- a/src/render/io/render-io.pri
+++ b/src/render/io/render-io.pri
@@ -1,7 +1,6 @@
INCLUDEPATH += $$PWD
HEADERS += \
- $$PWD/gltfparser_p.h \
$$PWD/objloader_p.h \
$$PWD/texturedata.h \
$$PWD/abstractsceneparser_p.h \
@@ -16,7 +15,6 @@ HEADERS += \
$$PWD/qgeometryfunctor.h
SOURCES += \
- $$PWD/gltfparser.cpp \
$$PWD/objloader.cpp \
$$PWD/texturedata.cpp \
$$PWD/abstractsceneparser.cpp \