Skip to content

fileType parameter ignored when using url without file extension in SplatMesh #233

@marvinluo1

Description

@marvinluo1

Description

The documentation states that the fileType parameter can
be used with URLs that have no file extension:

"If the URL contains a path with no obvious file
extension, you can set the field fileType when
constructing a SplatMesh or PackedSplats."

// File type can't be auto-detected, so we set it explicitly
scene.add(new SplatMesh({
  url: "splatBin/0123456789abcdef",
  fileType: SplatFileType.SPLAT,
}));

scene.add(new SplatMesh({
  url: "ksplatBin/fedcba9876543210",
  fileType: SplatFileType.KSPLAT,
}));

However, this feature does not work in practice. The
fileType parameter is ignored when using the url
parameter.

Expected Behavior

// This should work according to the documentation
const splatMesh = new SplatMesh({
  url: "https://example.com/point_cloud_data",  // No file
extension
  fileType: SplatFileType.SPLAT,
});
await splatMesh.initialized;

The mesh should load successfully by using the provided
fileType to determine how to parse the file.

Actual Behavior

The above code fails to load. The fileType parameter is
ignored, and the loader attempts to detect the file type
from the URL extension, which doesn't exist.

Root Cause

Looking at the source code, when url is provided, the
code path goes through SplatLoader.loadAsync(url) which
calls getFileExtension(url) directly and doesn't use the
fileType parameter:

// Current implementation
if (url) {
  const loader = new SplatLoader();
  await loader.loadAsync(url);  // fileType is never passed
 or used
}

The fileType parameter is only respected when using the
fileBytes approach:

if (fileBytes) {
  const unpacked = await unpackSplats({
    pathOrUrl: options.fileName ?? url,
    fileType: options.fileType,  // Only used here
  });
}

Workaround

Currently, the only way to load files from extension-less
URLs is to manually fetch and use fileBytes:

import { FileLoader } from 'three';

const loader = new FileLoader();
loader.setResponseType('arraybuffer');
const arrayBuffer = await loader.loadAsync(src);

const splatMesh = new SplatMesh({
  fileBytes: arrayBuffer as ArrayBuffer,
  fileType: SplatFileType.SPLAT,
  fileName: 'file.splat',
});
await splatMesh.initialized;

Suggested Fix

The SplatMesh constructor should pass the fileType
parameter to SplatLoader when it's provided, or check if
fileType is set before attempting extension-based
detection.

Environment

  • @sparkjsdev/spark version: 0.1.10
  • Three.js version: (latest)
  • Browser: All browsers affected

Additional Context

This issue affects use cases where:

  • Assets are served from CDNs with content-addressed URLs
    (no extensions)
  • Blob URLs are used for local file handling
  • API endpoints serve binary data without file extensions
    in the URL path

This issue description:

  1. ✅ Clearly states the problem with a concise title
  2. ✅ Quotes the documentation that claims the feature
    works
  3. ✅ Provides expected vs actual behavior with code
    examples
  4. ✅ Explains the root cause with source code references
  5. ✅ Offers a working workaround
  6. ✅ Suggests how to fix it
  7. ✅ Includes version information and context

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions