@google/model-viewer
Version:
Easily display interactive 3D models on the web and in AR!
117 lines (92 loc) • 4.45 kB
text/typescript
/* @license
* Copyright 2020 Google LLC. All Rights Reserved.
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an 'AS IS' BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {Group, Mesh, MeshStandardMaterial, Object3D} from 'three';
import {GLTF, GLTFReference} from 'three/examples/jsm/loaders/GLTFLoader.js';
import {SkeletonUtils} from 'three/examples/jsm/utils/SkeletonUtils.js';
import {CorrelatedSceneGraph} from '../../../three-components/gltf-instance/correlated-scene-graph.js';
import {Material, PBRMetallicRoughness, Texture, TextureInfo} from '../../../three-components/gltf-instance/gltf-2.0.js';
import {assetPath, loadThreeGLTF} from '../../helpers.js';
const expect = chai.expect;
const HORSE_GLB_PATH = assetPath('models/Horse.glb');
const ORDER_TEST_GLB_PATH = assetPath('models/order-test/order-test.glb');
const KHRONOS_TRIANGLE_GLB_PATH =
assetPath('models/glTF-Sample-Models/2.0/Triangle/glTF/Triangle.gltf');
const getObject3DByName =
<T extends Object3D>(root: Object3D, name: string): T|null => {
const objects = [root];
while (objects.length) {
const next = objects.shift()!;
if (next.name === name) {
return next as T;
}
objects.push(...next.children);
}
return null;
};
suite('correlated-scene-graph', () => {
suite('CorrelatedSceneGraph', () => {
test('maps Three.js materials to glTF elements', async () => {
const threeGLTF = await loadThreeGLTF(HORSE_GLB_PATH);
const correlatedSceneGraph = CorrelatedSceneGraph.from(threeGLTF);
const threeMaterial =
((threeGLTF.scene.children[0] as Mesh).material as
MeshStandardMaterial);
const gltfMaterial = threeGLTF.parser.json.materials[0]! as Material;
const gltfReference =
correlatedSceneGraph.threeObjectMap.get(threeMaterial);
expect(gltfReference).to.be.ok;
const {type, index} = gltfReference as GLTFReference;
const referencedGltfMaterial = threeGLTF.parser.json[type][index];
expect(referencedGltfMaterial).to.be.equal(gltfMaterial);
});
test('maps Three.js textures to glTF elements', async () => {
const threeGLTF = await loadThreeGLTF(ORDER_TEST_GLB_PATH);
const correlatedSceneGraph = CorrelatedSceneGraph.from(threeGLTF);
const threeMaterial =
getObject3DByName<Mesh>(threeGLTF.scene, 'Node0')!.material as
MeshStandardMaterial;
const threeTexture = threeMaterial.map!;
const gltfMaterial = threeGLTF.parser.json.materials[2]! as Material;
const textureIndex =
((gltfMaterial.pbrMetallicRoughness as PBRMetallicRoughness)
.baseColorTexture as TextureInfo)
.index;
const gltfTexture =
threeGLTF.parser.json.textures[textureIndex] as Texture;
const gltfReference =
correlatedSceneGraph.threeObjectMap.get(threeTexture);
expect(gltfReference).to.be.ok;
const {type, index} = gltfReference as GLTFReference;
const referencedGltfTexture = threeGLTF.parser.json[type][index];
expect(referencedGltfTexture).to.be.equal(gltfTexture);
});
suite('when correlating a cloned glTF', () => {
test('ignores the GLTFLoader "default" material', async () => {
const threeGLTF = await loadThreeGLTF(KHRONOS_TRIANGLE_GLB_PATH);
const correlatedSceneGraph = CorrelatedSceneGraph.from(threeGLTF);
const scene = SkeletonUtils.clone(threeGLTF.scene) as Group;
const scenes: Group[] = [scene];
const cloneThreeGLTF: GLTF = {...threeGLTF, scene, scenes};
const cloneCorrelatedSceneGraph =
CorrelatedSceneGraph.from(cloneThreeGLTF, correlatedSceneGraph);
cloneCorrelatedSceneGraph.threeObjectMap.forEach(
(_reference, threeObject) => {
expect((threeObject as MeshStandardMaterial).isMaterial)
.to.be.undefined;
});
});
});
});
});