How to use @gltf-transform/core - 10 common examples

To help you get started, we’ve selected a few @gltf-transform/core examples, based on popular ways it is used in public projects.

Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.

github donmccurdy / glTF-Transform / packages / split / src / split.ts View on Github external
const split = function (container: GLTFContainer, meshes: Array): GLTFContainer {

  const json = container.json;
  const logger = GLTFUtil.createLogger('@gltf-transform/split', LoggerVerbosity.INFO);

  const bufferViewMap = {};
  const removedBufferViews = [];

  // Group bufferviews by mesh.
  json.meshes.forEach((mesh) => {
    if (meshes.indexOf(mesh.name) === -1) return;
    mesh.primitives.forEach((prim) => {
      if (prim.indices) markAccessor(json.accessors[prim.indices]);
      Object.keys(prim.attributes).forEach((attrName) => {
        markAccessor(json.accessors[prim.attributes[attrName]]);
      });

      function markAccessor(accessor) {
        if (bufferViewMap[accessor.bufferView] === undefined) {
          bufferViewMap[accessor.bufferView] = mesh.name;
github donmccurdy / glTF-Transform / packages / prune / src / prune.ts View on Github external
const prune = function (container: GLTFContainer): GLTFContainer {
  const json = container.json;
  const logger = GLTFUtil.createLogger('@gltf-transform/prune', LoggerVerbosity.INFO);

  // Find all accessors used for mesh data.
  let meshAccessorIndices = [];
  json.meshes.forEach((mesh) => {
    mesh.primitives.forEach((primitive) => {
      for (const semantic in primitive.attributes) {
        meshAccessorIndices.push(primitive.attributes[semantic]);
      }
      if (primitive.indices) {
        meshAccessorIndices.push(primitive.indices);
      }
    })
  });

  meshAccessorIndices = Array.from(new Set(meshAccessorIndices)); // dedupe
  meshAccessorIndices.sort((a, b) => a > b ? 1 : -1); // sort ascending
github donmccurdy / glTF-Transform / packages / atlas / src / atlas.ts View on Github external
return Promise.all(pending).then(() => {
    const buffer = (canvas as any).toBuffer() as Buffer;
    const arrayBuffer = GLTFUtil.trimBuffer(buffer);

    GLTFUtil.addImage(container, 'atlas', arrayBuffer, atlasIsPNG ? 'image/png': 'image/jpeg');
    const atlasImageIndex = container.json.images.length - 1;

    // Reassign textures to atlas.
    const imageMap = new Map();
    images.forEach((i) => imageMap.set(i.index, i));
    container.json.materials.forEach((material) => {
      if (!material.pbrMetallicRoughness) return;
      if (!material.pbrMetallicRoughness.baseColorTexture) return;
      const baseColorTexture = material.pbrMetallicRoughness.baseColorTexture;
      const textureIndex = baseColorTexture.index;
      const textureDef = container.json.textures[textureIndex];
      if (!imageMap.has(textureDef.source)) return;
      const image = imageMap.get(textureDef.source);
      baseColorTexture['extensions'] = baseColorTexture['extensions'] || {};
      baseColorTexture['extensions'][KHR_TEXTURE_TRANSFORM] = {
        offset: [image.x / atlasWidth, image.y / atlasHeight],
github donmccurdy / glTF-Transform / packages / ao / src / ao.ts View on Github external
const primitives = [];
    const meshes = container.json.meshes || [];
    meshes.forEach((mesh) => {
        mesh.primitives.forEach((primitive) => {
            const position = container.getAccessorArray(primitive.attributes['POSITION']);
            const cells = primitive.indices !== undefined ? container.getAccessorArray(primitive.indices) : undefined;
            primitives.push({position, cells, def: primitive});
        })
    });

    if (primitives.length === 0) {
        logger.warn('No primitives found.');
        return;
    }

    GLTFUtil.addImage(container, 'occlusion', TEXTURE_DATA, TEXTURE_MIME_TYPE);
    container.json.textures.push({source: container.json.images.length - 1});
    const occlusionTextureIndex = container.json.textures.length - 1;

    let regl;
    if (options.gl) {
        const gl = options.gl(resolution, resolution);
        gl.getExtension('OES_texture_float');
        gl.getExtension('OES_element_index_uint');
        regl = REGL({gl, extensions: ['OES_texture_float', 'OES_element_index_uint']});
    }

    // TODO: Implement baking such that primitives affect other primitives, and respect
    // world transforms.
    primitives.forEach((primitive, index) => {
        logger.info(`Baking primitive ${index} / ${primitives.length}.`);
github donmccurdy / glTF-Transform / packages / prune / src / prune.ts View on Github external
}
      }
      if (primitive.indices && duplicateAccessors.has(primitive.indices)) {
        primitive.indices = duplicateAccessors.get(primitive.indices);
      }
    });
  });

  // Clean up.
  const removedAccessors = Array.from(duplicateAccessors).map(([dup, _]) => dup);
  removedAccessors.sort((a, b) => a > b ? -1 : 1); // sort descending
  removedAccessors.forEach((index) => GLTFUtil.removeAccessor(container, index));
  for (let i = container.json.bufferViews.length - 1; i >= 0; i--) {
    const bufferView = container.json.bufferViews[i];
    if (bufferView.byteLength === 0) {
      GLTFUtil.removeBufferView(container, i);
    }
  }

  return container;
}
github donmccurdy / glTF-Transform / packages / ao / src / ao.ts View on Github external
const aoSampler = geoao(position, {cells, resolution, regl});
        for (let i = 0; i < samples; i++) aoSampler.sample();
        const ao = aoSampler.report();
        aoSampler.dispose();

        // Write UV set and add AO map.
        const numVertices = ao.length;
        const uv2Data = new Float32Array(numVertices * 2);
        for (let i = 0; i < numVertices; i++) {
            uv2Data[i * 2] = uv2Data[i * 2 + 1] = 1 - ao[i];
        }
        GLTFUtil.addAccessor(
            container,
            uv2Data,
            'VEC2' as GLTF.AccessorType.VEC2,
            AccessorComponentType.FLOAT,
            numVertices,
            BufferViewTarget.ARRAY_BUFFER
        );
        const accessorIndex = container.json.accessors.length - 1;
        primitiveDef.attributes['TEXCOORD_1'] = accessorIndex;
        if (primitiveDef.attributes['TEXCOORD_0'] === undefined) {
            primitiveDef.attributes['TEXCOORD_0'] = accessorIndex;
        }
        container.json.materials[primitiveDef.material].occlusionTexture = {index: occlusionTextureIndex};
    });
github donmccurdy / glTF-Transform / packages / ao / src / ao.ts View on Github external
const ao = aoSampler.report();
        aoSampler.dispose();

        // Write UV set and add AO map.
        const numVertices = ao.length;
        const uv2Data = new Float32Array(numVertices * 2);
        for (let i = 0; i < numVertices; i++) {
            uv2Data[i * 2] = uv2Data[i * 2 + 1] = 1 - ao[i];
        }
        GLTFUtil.addAccessor(
            container,
            uv2Data,
            'VEC2' as GLTF.AccessorType.VEC2,
            AccessorComponentType.FLOAT,
            numVertices,
            BufferViewTarget.ARRAY_BUFFER
        );
        const accessorIndex = container.json.accessors.length - 1;
        primitiveDef.attributes['TEXCOORD_1'] = accessorIndex;
        if (primitiveDef.attributes['TEXCOORD_0'] === undefined) {
            primitiveDef.attributes['TEXCOORD_0'] = accessorIndex;
        }
        container.json.materials[primitiveDef.material].occlusionTexture = {index: occlusionTextureIndex};
    });
github donmccurdy / glTF-Transform / packages / ao / src / ao.ts View on Github external
}

        // Bake vertex AO.
        const {position, cells} = primitive;
        const aoSampler = geoao(position, {cells, resolution, regl});
        for (let i = 0; i < samples; i++) aoSampler.sample();
        const ao = aoSampler.report();
        aoSampler.dispose();

        // Write UV set and add AO map.
        const numVertices = ao.length;
        const uv2Data = new Float32Array(numVertices * 2);
        for (let i = 0; i < numVertices; i++) {
            uv2Data[i * 2] = uv2Data[i * 2 + 1] = 1 - ao[i];
        }
        GLTFUtil.addAccessor(
            container,
            uv2Data,
            'VEC2' as GLTF.AccessorType.VEC2,
            AccessorComponentType.FLOAT,
            numVertices,
            BufferViewTarget.ARRAY_BUFFER
        );
        const accessorIndex = container.json.accessors.length - 1;
        primitiveDef.attributes['TEXCOORD_1'] = accessorIndex;
        if (primitiveDef.attributes['TEXCOORD_0'] === undefined) {
            primitiveDef.attributes['TEXCOORD_0'] = accessorIndex;
        }
        container.json.materials[primitiveDef.material].occlusionTexture = {index: occlusionTextureIndex};
    });
github donmccurdy / glTF-Transform / packages / prune / src / prune.ts View on Github external
// Find duplicate mesh accessors.
  const duplicateAccessors = new Map();
  for (let i = 0; i < meshAccessorIndices.length; i++) {
    if (duplicateAccessors.has(i)) continue;
    const iAccessor = container.json.accessors[i];
    const iAccessorData = container.getAccessorArray(i).slice().buffer;
    for (let j = i + 1; j < meshAccessorIndices.length; j++) {
      if (duplicateAccessors.has(j)) continue;
      const jAccessor = container.json.accessors[j];
      const jAccessorData = container.getAccessorArray(j).slice().buffer;
      if (iAccessor.type !== jAccessor.type) continue;
      if (iAccessor.componentType !== jAccessor.componentType) continue;
      if (iAccessor.count !== jAccessor.count) continue;
      if (iAccessor.normalized !== jAccessor.normalized) continue;
      if (GLTFUtil.arrayBufferEquals(iAccessorData, jAccessorData)) {
        duplicateAccessors.set(j, i);
      }
    }
  }
  logger.info(`Duplicates: ${Array.from(duplicateAccessors).length} of ${json.accessors.length}.`);

  // Replace accessor references.
  json.meshes.forEach((mesh) => {
    mesh.primitives.forEach((primitive) => {
      for (const semantic in primitive.attributes) {
        const index = primitive.attributes[semantic];
        if (duplicateAccessors.has(index)) {
          primitive.attributes[semantic] = duplicateAccessors.get(index);
        }
      }
      if (primitive.indices && duplicateAccessors.has(primitive.indices)) {
github donmccurdy / glTF-Transform / packages / split / src / split.ts View on Github external
}
      })

      removedBufferViews.push(bufferViewIndex);
    });

  });

  // Removed emptied bufferviews.
  removedBufferViews.sort((a, b) => a > b ? -1 : 1);
  removedBufferViews.forEach((index) => GLTFUtil.removeBufferView(container, index));

  // Remove initial buffer, if empty.
  const buffer = json.buffers[0];
  if (buffer.byteLength === 0) {
    GLTFUtil.removeBuffer(container, 0);
  }

  return container;
}