t3d-3dtiles 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. package/LICENSE +28 -0
  2. package/README.md +41 -0
  3. package/build/t3d.3dtiles.js +5418 -0
  4. package/build/t3d.3dtiles.min.js +2 -0
  5. package/build/t3d.3dtiles.module.js +6183 -0
  6. package/examples/jsm/CesiumIon.js +30 -0
  7. package/examples/jsm/Tiles3DDebugger.js +219 -0
  8. package/examples/jsm/Tiles3DUtils.js +32 -0
  9. package/examples/jsm/helpers/LineSegmentHelper.js +74 -0
  10. package/examples/jsm/helpers/OBBHelper.js +48 -0
  11. package/examples/jsm/helpers/Tiles3DHelper.js +135 -0
  12. package/examples/jsm/math/Intersects.js +100 -0
  13. package/examples/jsm/math/LineSegment.js +234 -0
  14. package/package.json +57 -0
  15. package/src/Tiles3D.js +402 -0
  16. package/src/libs/ImageBitmapLoader.js +56 -0
  17. package/src/libs/glTF/Constants.js +85 -0
  18. package/src/libs/glTF/GLTFLoader.js +169 -0
  19. package/src/libs/glTF/GLTFResource.js +28 -0
  20. package/src/libs/glTF/GLTFUtils.js +131 -0
  21. package/src/libs/glTF/extensions/EXT_meshopt_compression.js +35 -0
  22. package/src/libs/glTF/extensions/KHR_draco_mesh_compression.js +54 -0
  23. package/src/libs/glTF/extensions/KHR_lights_punctual.js +53 -0
  24. package/src/libs/glTF/extensions/KHR_materials_clearcoat.js +42 -0
  25. package/src/libs/glTF/extensions/KHR_materials_pbrSpecularGlossiness.js +53 -0
  26. package/src/libs/glTF/extensions/KHR_materials_unlit.js +13 -0
  27. package/src/libs/glTF/extensions/KHR_texture_basisu.js +14 -0
  28. package/src/libs/glTF/extensions/KHR_texture_transform.js +31 -0
  29. package/src/libs/glTF/parsers/AccessorParser.js +99 -0
  30. package/src/libs/glTF/parsers/AnimationParser.js +118 -0
  31. package/src/libs/glTF/parsers/BufferParser.js +35 -0
  32. package/src/libs/glTF/parsers/BufferViewParser.js +27 -0
  33. package/src/libs/glTF/parsers/ImageParser.js +97 -0
  34. package/src/libs/glTF/parsers/IndexParser.js +22 -0
  35. package/src/libs/glTF/parsers/MaterialParser.js +146 -0
  36. package/src/libs/glTF/parsers/NodeParser.js +145 -0
  37. package/src/libs/glTF/parsers/PrimitiveParser.js +289 -0
  38. package/src/libs/glTF/parsers/ReferenceParser.js +67 -0
  39. package/src/libs/glTF/parsers/SceneParser.js +41 -0
  40. package/src/libs/glTF/parsers/SkinParser.js +53 -0
  41. package/src/libs/glTF/parsers/TextureParser.js +71 -0
  42. package/src/libs/glTF/parsers/Validator.js +16 -0
  43. package/src/loaders/B3DMLoader.js +49 -0
  44. package/src/loaders/CMPTLoader.js +48 -0
  45. package/src/loaders/I3DMLoader.js +49 -0
  46. package/src/loaders/PNTSLoader.js +20 -0
  47. package/src/loaders/TileGLTFLoader.js +17 -0
  48. package/src/loaders/parsers/HeaderParser.js +104 -0
  49. package/src/loaders/parsers/LoadParser.js +22 -0
  50. package/src/loaders/parsers/TableParser.js +66 -0
  51. package/src/loaders/parsers/b3dm/B3DMParser.js +18 -0
  52. package/src/loaders/parsers/b3dm/B3DMRootParser.js +22 -0
  53. package/src/loaders/parsers/b3dm/MaterialParser.js +156 -0
  54. package/src/loaders/parsers/cmpt/CMPTParser.js +37 -0
  55. package/src/loaders/parsers/cmpt/CMPTRootParser.js +44 -0
  56. package/src/loaders/parsers/gltf/IndexParser.js +24 -0
  57. package/src/loaders/parsers/i3dm/I3DMParser.js +28 -0
  58. package/src/loaders/parsers/i3dm/I3DMRootParser.js +123 -0
  59. package/src/loaders/parsers/i3dm/MaterialParser.js +152 -0
  60. package/src/loaders/parsers/i3dm/PrimitiveParser.js +291 -0
  61. package/src/loaders/parsers/pnts/PNTSRootParser.js +69 -0
  62. package/src/main.js +14 -0
  63. package/src/materials/InstancedBasicMaterial.js +32 -0
  64. package/src/materials/InstancedPBRMaterial.js +32 -0
  65. package/src/materials/InstancedShaderChunks.js +23 -0
  66. package/src/math/Ellipsoid.js +41 -0
  67. package/src/math/EllipsoidRegion.js +160 -0
  68. package/src/math/FastFrustum.js +49 -0
  69. package/src/math/GeoUtils.js +31 -0
  70. package/src/math/OBB.js +395 -0
  71. package/src/math/TileBoundingVolume.js +172 -0
  72. package/src/math/TileOBB.js +103 -0
  73. package/src/utils/BatchTable.js +14 -0
  74. package/src/utils/CameraList.js +131 -0
  75. package/src/utils/FeatureTable.js +107 -0
  76. package/src/utils/IntersectionUtils.js +136 -0
  77. package/src/utils/LRUCache.js +159 -0
  78. package/src/utils/ModelLoader.js +150 -0
  79. package/src/utils/PriorityQueue.js +102 -0
  80. package/src/utils/RequestState.js +17 -0
  81. package/src/utils/TilesLoader.js +386 -0
  82. package/src/utils/TilesScheduler.js +375 -0
  83. package/src/utils/Utils.js +43 -0
@@ -0,0 +1,28 @@
1
+ import { GLTFUtils } from '../../../libs/glTF/GLTFUtils.js';
2
+
3
+ export class I3DMParser {
4
+
5
+ static parse(context, loader) {
6
+ const bodyBytes = new Uint8Array(
7
+ context.options.buffer,
8
+ context.batchTableEnd,
9
+ context.header.byteLength - context.batchTableEnd
10
+ );
11
+
12
+ let promise = null;
13
+ if (context.header.gltfFormat === 1) {
14
+ promise = Promise.resolve(bodyBytes);
15
+ } else {
16
+ const externalUri = GLTFUtils.resolveURL(GLTFUtils.decodeText(bodyBytes), context.path);
17
+ promise = loader.loadFile(externalUri, 'arraybuffer').then(buffer => new Uint8Array(buffer));
18
+ }
19
+
20
+ return promise.then(glbBytes => {
21
+ const glbData = GLTFUtils.parseGLB(glbBytes.slice().buffer);
22
+
23
+ context.gltf = glbData.gltf;
24
+ context.buffers = glbData.buffers;
25
+ });
26
+ }
27
+
28
+ }
@@ -0,0 +1,123 @@
1
+ import { Vector3, Matrix4, Quaternion, Attribute, Buffer } from 't3d';
2
+
3
+ export class I3DMRootParser {
4
+
5
+ static parse(context, loader) {
6
+ const { featureTable, root, options } = context;
7
+
8
+ const INSTANCES_LENGTH = featureTable.getData('INSTANCES_LENGTH');
9
+ const POSITION = featureTable.getData('POSITION', INSTANCES_LENGTH, 'FLOAT', 'VEC3');
10
+ const NORMAL_UP = featureTable.getData('NORMAL_UP', INSTANCES_LENGTH, 'FLOAT', 'VEC3');
11
+ const NORMAL_RIGHT = featureTable.getData('NORMAL_RIGHT', INSTANCES_LENGTH, 'FLOAT', 'VEC3');
12
+ const SCALE = featureTable.getData('SCALE', INSTANCES_LENGTH, 'FLOAT', 'SCALAR');
13
+ const SCALE_NON_UNIFORM = featureTable.getData('SCALE_NON_UNIFORM', INSTANCES_LENGTH, 'FLOAT', 'VEC3');
14
+
15
+ // check unsupported features
16
+
17
+ [
18
+ // Global Properties
19
+ 'QUANTIZED_VOLUME_OFFSET',
20
+ 'QUANTIZED_VOLUME_SCALE',
21
+ 'EAST_NORTH_UP',
22
+
23
+ // Per-instance Properties
24
+ 'POSITION_QUANTIZED',
25
+ 'NORMAL_UP_OCT32P',
26
+ 'NORMAL_RIGHT_OCT32P'
27
+ ].forEach(feature => {
28
+ if (feature in featureTable.header) {
29
+ console.warn(`I3DMLoader: Unsupported FeatureTable feature "${feature}" detected.`);
30
+ }
31
+ });
32
+
33
+ // set instance matrix for all geometries
34
+
35
+ const averageVector = new Vector3();
36
+ for (let i = 0; i < INSTANCES_LENGTH; i++) {
37
+ averageVector.x += POSITION[i * 3 + 0] / INSTANCES_LENGTH;
38
+ averageVector.y += POSITION[i * 3 + 1] / INSTANCES_LENGTH;
39
+ averageVector.z += POSITION[i * 3 + 2] / INSTANCES_LENGTH;
40
+ }
41
+
42
+ const instances = [];
43
+
44
+ root.traverse(child => {
45
+ if (child.isMesh) {
46
+ const { geometry } = child;
47
+ geometry.instanceCount = INSTANCES_LENGTH;
48
+
49
+ const instanceMatrix = new Attribute(new Buffer(new Float32Array(INSTANCES_LENGTH * 16), 16), 16);
50
+ instanceMatrix.divisor = 1;
51
+ geometry.addAttribute('instanceMatrix', instanceMatrix);
52
+
53
+ // Center the instance around an average point to avoid jitter at large scales.
54
+ // Transform the average vector by matrix world so we can account for any existing
55
+ // transforms of the instanced mesh.
56
+ child.updateMatrix(true);
57
+ child.position.copy(averageVector).applyMatrix4(child.worldMatrix);
58
+
59
+ instances.push(child);
60
+ }
61
+ });
62
+
63
+ for (let i = 0; i < INSTANCES_LENGTH; i++) {
64
+ // position
65
+ tempPos.fromArray(POSITION, i * 3).sub(averageVector);
66
+
67
+ // rotation
68
+ if (NORMAL_UP) {
69
+ tempUp.fromArray(NORMAL_UP, i * 3);
70
+ tempRight.fromArray(NORMAL_RIGHT, i * 3);
71
+ tempFwd.crossVectors(tempRight, tempUp).normalize();
72
+
73
+ tempMat.set(
74
+ tempRight.x, tempUp.x, tempFwd.x, 0,
75
+ tempRight.y, tempUp.y, tempFwd.y, 0,
76
+ tempRight.z, tempUp.z, tempFwd.z, 0,
77
+ 0, 0, 0, 1
78
+ );
79
+
80
+ tempQuat.setFromRotationMatrix(tempMat);
81
+ } else {
82
+ tempQuat.set(0, 0, 0, 1);
83
+ }
84
+
85
+ // scale
86
+ if (SCALE) {
87
+ tempSca.set(SCALE[i], SCALE[i], SCALE[i]);
88
+ } else if (SCALE_NON_UNIFORM) {
89
+ tempSca.fromArray(SCALE_NON_UNIFORM, i * 3);
90
+ } else {
91
+ tempSca.set(1, 1, 1);
92
+ }
93
+
94
+ // TODO instance matrix should be applied to model root
95
+ tempMat.transform(tempPos, tempSca, tempQuat).multiply(options.adjustmentTransform);
96
+
97
+ for (let j = 0, l = instances.length; j < l; j++) {
98
+ const { geometry } = instances[j];
99
+ const instanceArray = geometry.getAttribute('instanceMatrix').buffer.array;
100
+ tempMat.toArray(instanceArray, i * 16);
101
+ geometry.version++;
102
+ }
103
+ }
104
+
105
+ // fix rtc center
106
+
107
+ const rtcCenter = featureTable.getData('RTC_CENTER');
108
+ if (rtcCenter) {
109
+ root.position.x += rtcCenter[0];
110
+ root.position.y += rtcCenter[1];
111
+ root.position.z += rtcCenter[2];
112
+ }
113
+ }
114
+
115
+ }
116
+
117
+ const tempFwd = new Vector3();
118
+ const tempUp = new Vector3();
119
+ const tempRight = new Vector3();
120
+ const tempPos = new Vector3();
121
+ const tempQuat = new Quaternion();
122
+ const tempSca = new Vector3();
123
+ const tempMat = new Matrix4();
@@ -0,0 +1,152 @@
1
+ import {
2
+ Color3,
3
+ // PBRMaterial,
4
+ DRAW_SIDE,
5
+ TEXEL_ENCODING_TYPE
6
+ } from 't3d';
7
+ // import { KHR_materials_unlit as _KHR_materials_unlit } from '../../../libs/glTF/extensions/KHR_materials_unlit.js';
8
+ import { KHR_materials_pbrSpecularGlossiness as _KHR_materials_pbrSpecularGlossiness } from '../../../libs/glTF/extensions/KHR_materials_pbrSpecularGlossiness.js';
9
+ import { KHR_materials_clearcoat as _KHR_materials_clearcoat } from '../../../libs/glTF/extensions/KHR_materials_clearcoat.js';
10
+ import { KHR_texture_transform } from '../../../libs/glTF/extensions/KHR_texture_transform.js';
11
+ import { ALPHA_MODES } from '../../../libs/glTF/Constants.js';
12
+
13
+ import { InstancedPBRMaterial } from '../../../materials/InstancedPBRMaterial.js'; // @parser-modification - instanced materials
14
+ import { InstancedBasicMaterial } from '../../../materials/InstancedBasicMaterial.js'; // @parser-modification - instanced materials
15
+
16
+ export class MaterialParser {
17
+
18
+ static parse(context) {
19
+ const { gltf, textures } = context;
20
+
21
+ if (!gltf.materials) return;
22
+
23
+ const materials = [];
24
+ for (let i = 0; i < gltf.materials.length; i++) {
25
+ const {
26
+ extensions = {},
27
+ pbrMetallicRoughness,
28
+ normalTexture,
29
+ occlusionTexture,
30
+ emissiveTexture,
31
+ emissiveFactor,
32
+ alphaMode,
33
+ alphaCutoff,
34
+ doubleSided,
35
+ name = ''
36
+ } = gltf.materials[i];
37
+
38
+ const { KHR_materials_unlit, KHR_materials_pbrSpecularGlossiness, KHR_materials_clearcoat } = extensions;
39
+
40
+ let material = null;
41
+ if (KHR_materials_unlit) {
42
+ material = new InstancedBasicMaterial(); // @parser-modification - instanced materials
43
+ } else if (KHR_materials_pbrSpecularGlossiness) {
44
+ // TODO - InstancedPBR2Material
45
+ material = new InstancedPBRMaterial(); // @parser-modification - instanced materials
46
+ material.specular = new Color3(0x111111);
47
+ _KHR_materials_pbrSpecularGlossiness.parseParams(material, KHR_materials_pbrSpecularGlossiness, textures);
48
+ } else if (KHR_materials_clearcoat) {
49
+ material = new InstancedPBRMaterial(); // @parser-modification - instanced materials
50
+ _KHR_materials_clearcoat.parseParams(material, KHR_materials_clearcoat, textures);
51
+ } else {
52
+ material = new InstancedPBRMaterial(); // @parser-modification - instanced materials
53
+ }
54
+
55
+ material.name = name;
56
+
57
+ if (pbrMetallicRoughness) {
58
+ const { baseColorFactor, baseColorTexture, metallicFactor, roughnessFactor, metallicRoughnessTexture } = pbrMetallicRoughness;
59
+
60
+ if (Array.isArray(baseColorFactor)) {
61
+ material.diffuse.fromArray(baseColorFactor);
62
+ material.opacity = (baseColorFactor[3] !== undefined) ? baseColorFactor[3] : 1;
63
+ }
64
+
65
+ if (baseColorTexture) {
66
+ material.diffuseMap = textures[baseColorTexture.index];
67
+ material.diffuseMapCoord = baseColorTexture.texCoord || 0;
68
+ if (material.diffuseMap) {
69
+ material.diffuseMap.encoding = TEXEL_ENCODING_TYPE.SRGB;
70
+ parseTextureTransform(material, 'diffuseMap', baseColorTexture.extensions);
71
+ }
72
+ }
73
+
74
+ if (!KHR_materials_unlit && !KHR_materials_pbrSpecularGlossiness) {
75
+ material.metalness = metallicFactor !== undefined ? metallicFactor : 1;
76
+ material.roughness = roughnessFactor !== undefined ? roughnessFactor : 1;
77
+ if (metallicRoughnessTexture) {
78
+ material.metalnessMap = textures[metallicRoughnessTexture.index];
79
+ material.roughnessMap = textures[metallicRoughnessTexture.index];
80
+ // parseTextureTransform(material, 'metalnessMap', metallicRoughnessTexture.extensions);
81
+ // parseTextureTransform(material, 'roughnessMap', metallicRoughnessTexture.extensions);
82
+ }
83
+ }
84
+ }
85
+
86
+ if (emissiveFactor) {
87
+ material.emissive.fromArray(emissiveFactor);
88
+ }
89
+
90
+ if (emissiveTexture) {
91
+ material.emissiveMap = textures[emissiveTexture.index];
92
+ material.emissiveMapCoord = emissiveTexture.texCoord || 0;
93
+ if (material.emissiveMap) {
94
+ material.emissiveMap.encoding = TEXEL_ENCODING_TYPE.SRGB;
95
+ parseTextureTransform(material, 'emissiveMap', emissiveTexture.extensions);
96
+ }
97
+ }
98
+
99
+ if (occlusionTexture) {
100
+ material.aoMap = textures[occlusionTexture.index];
101
+ material.aoMapCoord = occlusionTexture.texCoord || 0;
102
+ if (occlusionTexture.strength !== undefined) {
103
+ material.aoMapIntensity = occlusionTexture.strength;
104
+ }
105
+ if (material.aoMap) {
106
+ parseTextureTransform(material, 'aoMap', occlusionTexture.extensions);
107
+ }
108
+ }
109
+
110
+ if (!KHR_materials_unlit) {
111
+ if (normalTexture) {
112
+ material.normalMap = textures[normalTexture.index];
113
+
114
+ material.normalScale.set(1, -1);
115
+ if (normalTexture.scale !== undefined) {
116
+ // fix flip y for normal map
117
+ // https://github.com/mrdoob/three.js/issues/11438#issuecomment-507003995
118
+ material.normalScale.set(normalTexture.scale, -normalTexture.scale);
119
+ }
120
+
121
+ if (material.normalMap) {
122
+ // parseTextureTransform(material, 'normalMap', normalTexture.extensions);
123
+ }
124
+ }
125
+ }
126
+
127
+ material.side = doubleSided === true ? DRAW_SIDE.DOUBLE : DRAW_SIDE.FRONT;
128
+
129
+ if (alphaMode === ALPHA_MODES.BLEND) {
130
+ material.transparent = true;
131
+ } else {
132
+ material.transparent = false;
133
+
134
+ if (alphaMode === ALPHA_MODES.MASK) {
135
+ material.alphaTest = alphaCutoff !== undefined ? alphaCutoff : 0.5;
136
+ }
137
+ }
138
+
139
+ materials[i] = material;
140
+ }
141
+
142
+ context.materials = materials;
143
+ }
144
+
145
+ }
146
+
147
+ function parseTextureTransform(material, key, extensions = {}) {
148
+ const extension = extensions.KHR_texture_transform;
149
+ if (extension) {
150
+ KHR_texture_transform.transform(material[key + 'Transform'], extension);
151
+ }
152
+ }
@@ -0,0 +1,291 @@
1
+ import { Geometry, /* PBRMaterial, */ VERTEX_COLOR, SHADING_TYPE, PointsMaterial, Material, BasicMaterial } from 't3d';
2
+ import { GLTFUtils } from '../../../libs/glTF/GLTFUtils.js';
3
+ import { ATTRIBUTES, ACCESSOR_COMPONENT_TYPES, WEBGL_DRAW_MODES } from '../../../libs/glTF/Constants.js';
4
+ import { KHR_draco_mesh_compression as _KHR_draco_mesh_compression } from '../../../libs/glTF/extensions/KHR_draco_mesh_compression.js';
5
+
6
+ import { InstancedPBRMaterial } from '../../../materials/InstancedPBRMaterial.js'; // @parser-modification - instanced materials
7
+
8
+ export class PrimitiveParser {
9
+
10
+ static parse(context, loader) {
11
+ const { gltf, accessors, materials, bufferViews } = context;
12
+
13
+ if (!gltf.meshes) return;
14
+
15
+ const materialCache = new Map();
16
+ const geometryPromiseCache = new Map();
17
+
18
+ const meshPromises = [];
19
+ for (let i = 0; i < gltf.meshes.length; i++) {
20
+ const gltfMesh = gltf.meshes[i];
21
+
22
+ const primitivePromises = [];
23
+ for (let j = 0; j < gltfMesh.primitives.length; j++) {
24
+ const gltfPrimitive = gltfMesh.primitives[j];
25
+ const {
26
+ extensions = {},
27
+ mode,
28
+ material
29
+ } = gltfPrimitive;
30
+ const { KHR_draco_mesh_compression } = extensions;
31
+
32
+ let geometryPromise;
33
+
34
+ const geometryKey = createGeometryKey(gltfPrimitive);
35
+ if (geometryPromiseCache.has(geometryKey)) {
36
+ geometryPromise = geometryPromiseCache.get(geometryKey);
37
+ } else {
38
+ if (KHR_draco_mesh_compression) {
39
+ geometryPromise = _KHR_draco_mesh_compression.getGeometry(KHR_draco_mesh_compression, bufferViews, gltfPrimitive.attributes, gltf.accessors, loader.getDRACOLoader());
40
+ } else {
41
+ geometryPromise = Promise.resolve(new Geometry());
42
+ }
43
+
44
+ geometryPromise = geometryPromise.then(geometry => {
45
+ parseGeometryFromGLTFPrimitive(geometry, gltfPrimitive, gltf, accessors);
46
+ return geometry;
47
+ });
48
+
49
+ geometryPromiseCache.set(geometryKey, geometryPromise);
50
+ }
51
+
52
+ const primitivePromise = geometryPromise.then(geometry => {
53
+ const primitive = {
54
+ mode,
55
+ geometry,
56
+ material: material === undefined ? new InstancedPBRMaterial() : materials[material], // @parser-modification - instanced materials
57
+ weights: (Object.keys(geometry.morphAttributes).length > 0 && gltfMesh.weights) ? gltfMesh.weights.slice(0) : undefined,
58
+ skinned: gltfMesh.isSkinned
59
+ };
60
+ assignFinalMaterial(primitive, materialCache);
61
+ return primitive;
62
+ });
63
+
64
+ primitivePromises.push(primitivePromise);
65
+ }
66
+ meshPromises.push(Promise.all(primitivePromises));
67
+ }
68
+
69
+ materialCache.clear();
70
+ geometryPromiseCache.clear();
71
+
72
+ return Promise.all(meshPromises).then(primitives => {
73
+ context.primitives = primitives;
74
+ });
75
+ }
76
+
77
+ }
78
+
79
+ function parseGeometryFromGLTFPrimitive(geometry, gltfPrimitive, gltf, accessors) {
80
+ const { attributes, indices, targets } = gltfPrimitive;
81
+
82
+ // set attributes
83
+
84
+ for (const attributeSemantic in attributes) {
85
+ const accessorIdx = attributes[attributeSemantic];
86
+
87
+ const attributeName = ATTRIBUTES[attributeSemantic] === undefined ? attributeSemantic : ATTRIBUTES[attributeSemantic];
88
+ // Skip attributes already provided by e.g. Draco extension.
89
+ if (attributeName in geometry.attributes) continue;
90
+
91
+ geometry.addAttribute(attributeName, accessors[accessorIdx]);
92
+ }
93
+
94
+ // set index
95
+
96
+ if (indices !== undefined && !geometry.index) {
97
+ geometry.setIndex(accessors[indices]);
98
+ }
99
+
100
+ // compute bounds
101
+
102
+ const { boundingBox, boundingSphere } = geometry;
103
+ if (attributes.POSITION !== undefined) {
104
+ const accessorIdx = attributes.POSITION;
105
+ const accessor = gltf.accessors[accessorIdx];
106
+
107
+ if (accessor.min && accessor.max) {
108
+ boundingBox.min.fromArray(accessor.min);
109
+ boundingBox.max.fromArray(accessor.max);
110
+
111
+ if (accessor.normalized) {
112
+ const boxScale = GLTFUtils.getNormalizedComponentScale(ACCESSOR_COMPONENT_TYPES[accessor.componentType]);
113
+ boundingBox.min.multiplyScalar(boxScale);
114
+ boundingBox.max.multiplyScalar(boxScale);
115
+ }
116
+ } else {
117
+ geometry.computeBoundingBox();
118
+ }
119
+ } else {
120
+ geometry.computeBoundingBox();
121
+ }
122
+ boundingBox.getCenter(boundingSphere.center);
123
+ boundingSphere.radius = boundingBox.min.distanceTo(boundingBox.max) / 2;
124
+
125
+ // set morph targets
126
+
127
+ if (targets) {
128
+ let hasMorphPosition = false;
129
+ let hasMorphNormal = false;
130
+
131
+ for (let i = 0, il = targets.length; i < il; i++) {
132
+ const target = targets[i];
133
+
134
+ if (target.POSITION !== undefined) hasMorphPosition = true;
135
+ if (target.NORMAL !== undefined) hasMorphNormal = true;
136
+
137
+ if (hasMorphPosition && hasMorphNormal) break;
138
+ }
139
+
140
+ if (hasMorphPosition || hasMorphNormal) {
141
+ const morphPositions = [];
142
+ const morphNormals = [];
143
+
144
+ for (let i = 0, il = targets.length; i < il; i++) {
145
+ const target = targets[i];
146
+
147
+ if (hasMorphPosition) {
148
+ morphPositions.push(target.POSITION !== undefined ? accessors[target.POSITION] : geometry.attributes[ATTRIBUTES.POSITION]);
149
+ }
150
+ if (hasMorphNormal) {
151
+ morphNormals.push(target.NORMAL !== undefined ? accessors[target.NORMAL] : geometry.attributes[ATTRIBUTES.NORMAL]);
152
+ }
153
+ }
154
+
155
+ if (hasMorphPosition) {
156
+ geometry.morphAttributes.position = morphPositions;
157
+ }
158
+ if (hasMorphNormal) {
159
+ geometry.morphAttributes.normal = morphNormals;
160
+ }
161
+ }
162
+ }
163
+
164
+ return geometry;
165
+ }
166
+
167
+ function assignFinalMaterial(primitive, materialCache) {
168
+ let { geometry, material, skinned, mode } = primitive;
169
+
170
+ // If the material will be modified later on, clone it now.
171
+ const useVertexTangents = geometry.attributes[ATTRIBUTES.TANGENT] !== undefined;
172
+ const useVertexColors = geometry.attributes[ATTRIBUTES.COLOR_0] !== undefined;
173
+ const useFlatShading = geometry.attributes[ATTRIBUTES.NORMAL] === undefined;
174
+ const useSkinning = skinned;
175
+
176
+ if (mode === WEBGL_DRAW_MODES.POINTS) {
177
+ const cacheKey = 'PointsMaterial:' + material.id;
178
+ let pointsMaterial = materialCache.get(cacheKey);
179
+ if (!pointsMaterial) {
180
+ pointsMaterial = new PointsMaterial();
181
+ Material.prototype.copy.call(pointsMaterial, material);
182
+ pointsMaterial.diffuse.copy(material.diffuse);
183
+ pointsMaterial.diffuseMap = material.map;
184
+ pointsMaterial.drawMode = mode;
185
+ pointsMaterial.acceptLight = false; // PointsMaterial doesn't support lights yet
186
+ materialCache.set(cacheKey, pointsMaterial);
187
+ }
188
+ material = pointsMaterial;
189
+ } else if (mode === WEBGL_DRAW_MODES.LINES || mode === WEBGL_DRAW_MODES.LINE_STRIP || mode === WEBGL_DRAW_MODES.LINE_LOOP) {
190
+ const cacheKey = 'BasicMaterial:' + material.id;
191
+ let basicMaterial = materialCache.get(cacheKey);
192
+ if (!basicMaterial) {
193
+ basicMaterial = new BasicMaterial();
194
+ basicMaterial.envMap = undefined; // force close env map
195
+ basicMaterial.diffuse.copy(material.diffuse);
196
+ basicMaterial.diffuseMap = material.diffuseMap;
197
+ basicMaterial.drawMode = mode;
198
+ materialCache.set(cacheKey, basicMaterial);
199
+ }
200
+ material = basicMaterial;
201
+ } else if (mode === WEBGL_DRAW_MODES.TRIANGLE_STRIP) {
202
+ // TODO
203
+ console.warn('TRIANGLE_STRIP will be removed later.');
204
+ material.drawMode = WEBGL_DRAW_MODES.TRIANGLE_STRIP;
205
+ } else if (mode === WEBGL_DRAW_MODES.TRIANGLE_FAN) {
206
+ // TODO
207
+ console.warn('TRIANGLE_FAN will be removed later.');
208
+ material.drawMode = WEBGL_DRAW_MODES.TRIANGLE_FAN;
209
+ }
210
+
211
+ if (useVertexTangents || useVertexColors || useFlatShading || useSkinning) {
212
+ let cacheKey = 'ClonedMaterial:' + material.id + ':';
213
+
214
+ if (useVertexTangents) cacheKey += 'vertex-tangents:';
215
+ if (useVertexColors) {
216
+ if (geometry.attributes[ATTRIBUTES.COLOR_0].size === 3) {
217
+ cacheKey += 'vertex-colors-rgb:';
218
+ } else if (geometry.attributes[ATTRIBUTES.COLOR_0].size === 4) {
219
+ cacheKey += 'vertex-colors-rgba:';
220
+ }
221
+ }
222
+ if (useFlatShading) cacheKey += 'flat-shading:';
223
+
224
+ let cachedMaterial = materialCache.get(cacheKey);
225
+
226
+ if (!cachedMaterial) {
227
+ cachedMaterial = material.clone();
228
+
229
+ if (useVertexTangents) {
230
+ cachedMaterial.vertexTangents = true;
231
+
232
+ // revert flip y fix for tangents
233
+ // https://github.com/mrdoob/three.js/issues/11438#issuecomment-507003995
234
+ if (cachedMaterial.normalMap) {
235
+ cachedMaterial.normalScale.y *= -1;
236
+ }
237
+ }
238
+
239
+ if (useVertexColors) {
240
+ if (geometry.attributes[ATTRIBUTES.COLOR_0].size === 3) {
241
+ cachedMaterial.vertexColors = VERTEX_COLOR.RGB;
242
+ } else if (geometry.attributes[ATTRIBUTES.COLOR_0].size === 4) {
243
+ cachedMaterial.vertexColors = VERTEX_COLOR.RGBA;
244
+ } else {
245
+ console.warn('Illegal vertex color size: ' + geometry.attributes[ATTRIBUTES.COLOR_0].size);
246
+ }
247
+ }
248
+
249
+ if (useFlatShading) {
250
+ cachedMaterial.shading = SHADING_TYPE.FLAT_SHADING;
251
+ }
252
+ }
253
+
254
+ material = cachedMaterial;
255
+ }
256
+
257
+ primitive.material = material;
258
+ }
259
+
260
+ function createGeometryKey(primitive) {
261
+ const dracoExtension = primitive.extensions && primitive.extensions.KHR_draco_mesh_compression;
262
+ let geometryKey;
263
+
264
+ if (dracoExtension) {
265
+ geometryKey = 'draco:' + dracoExtension.bufferView
266
+ + ':' + dracoExtension.indices
267
+ + ':' + createAttributesKey(dracoExtension.attributes);
268
+ } else {
269
+ geometryKey = primitive.indices + ':' + createAttributesKey(primitive.attributes) + ':' + primitive.mode;
270
+ }
271
+
272
+ if (primitive.targets) {
273
+ for (let i = 0, il = primitive.targets.length; i < il; i++) {
274
+ geometryKey += ':' + createAttributesKey(primitive.targets[i]);
275
+ }
276
+ }
277
+
278
+ return geometryKey;
279
+ }
280
+
281
+ function createAttributesKey(attributes) {
282
+ let attributesKey = '';
283
+
284
+ const keys = Object.keys(attributes).sort();
285
+
286
+ for (let i = 0, il = keys.length; i < il; i++) {
287
+ attributesKey += keys[i] + ':' + attributes[keys[i]] + ';';
288
+ }
289
+
290
+ return attributesKey;
291
+ }
@@ -0,0 +1,69 @@
1
+ import { Mesh, Geometry, PointsMaterial, Attribute, Buffer, VERTEX_COLOR } from 't3d';
2
+
3
+ export class PNTSRootParser {
4
+
5
+ static parse(context, loader) {
6
+ const { featureTable } = context;
7
+
8
+ const POINTS_LENGTH = featureTable.getData('POINTS_LENGTH');
9
+ const POSITION = featureTable.getData('POSITION', POINTS_LENGTH, 'FLOAT', 'VEC3');
10
+ const RGB = featureTable.getData('RGB', POINTS_LENGTH, 'UNSIGNED_BYTE', 'VEC3');
11
+ const RGBA = featureTable.getData('RGBA', POINTS_LENGTH, 'UNSIGNED_BYTE', 'VEC4');
12
+
13
+ // check unsupported features
14
+
15
+ [
16
+ // Global Properties
17
+ 'QUANTIZED_VOLUME_OFFSET',
18
+ 'QUANTIZED_VOLUME_SCALE',
19
+ 'CONSTANT_RGBA',
20
+ 'BATCH_LENGTH',
21
+
22
+ // Per-point Properties
23
+ 'POSITION_QUANTIZED',
24
+ 'RGB565',
25
+ 'NORMAL',
26
+ 'NORMAL_OCT16P',
27
+ 'BATCH_ID'
28
+ ].forEach(feature => {
29
+ if (feature in featureTable.header) {
30
+ console.warn(`PNTSLoader: Unsupported FeatureTable feature "${feature}" detected.`);
31
+ }
32
+ });
33
+
34
+ // generate root
35
+
36
+ const geometry = new Geometry();
37
+ geometry.addAttribute('a_Position', new Attribute(new Buffer(POSITION, 3), 3, 0, true));
38
+ geometry.computeBoundingBox();
39
+ geometry.computeBoundingSphere();
40
+
41
+ const material = new PointsMaterial();
42
+ material.size = 2;
43
+ material.sizeAttenuation = false;
44
+
45
+ if (RGB !== null) {
46
+ geometry.addAttribute('a_Color', new Attribute(new Buffer(RGB, 3), 3, 0, true));
47
+ material.vertexColors = VERTEX_COLOR.RGB;
48
+ } else if (RGBA !== null) {
49
+ geometry.addAttribute('a_Color', new Attribute(new Buffer(RGBA, 4), 4, 0, true));
50
+ material.vertexColors = VERTEX_COLOR.RGBA;
51
+ }
52
+
53
+ const root = new Mesh(geometry, material);
54
+
55
+ // output mesh to root
56
+
57
+ context.root = root;
58
+
59
+ // fix rtc center
60
+
61
+ const rtcCenter = featureTable.getData('RTC_CENTER');
62
+ if (rtcCenter) {
63
+ root.position.x += rtcCenter[0];
64
+ root.position.y += rtcCenter[1];
65
+ root.position.z += rtcCenter[2];
66
+ }
67
+ }
68
+
69
+ }
package/src/main.js ADDED
@@ -0,0 +1,14 @@
1
+ export * from './Tiles3D.js';
2
+
3
+ export * from './math/OBB.js';
4
+
5
+ export * from './materials/InstancedBasicMaterial.js';
6
+ export * from './materials/InstancedPBRMaterial.js';
7
+
8
+ export * from './loaders/B3DMLoader.js';
9
+ export * from './loaders/CMPTLoader.js';
10
+ export * from './loaders/TileGLTFLoader.js';
11
+ export * from './loaders/I3DMLoader.js';
12
+ export * from './loaders/PNTSLoader.js';
13
+
14
+ export { LoadParser as DebugLoadParser } from './loaders/parsers/LoadParser.js';