mirror of
https://github.com/galacean/engine.git
synced 2026-06-09 09:12:48 +08:00
Merge branch 'main' into dev/1.5
This commit is contained in:
@@ -8,9 +8,9 @@ import {
|
||||
resourceLoader,
|
||||
ResourceManager
|
||||
} from "@galacean/engine-core";
|
||||
import { getMeshoptDecoder, ready } from "./gltf/extensions/MeshoptDecoder";
|
||||
import { GLTFResource } from "./gltf/GLTFResource";
|
||||
import { GLTFParserContext } from "./gltf/parser";
|
||||
import { getMeshoptDecoder, ready } from "./gltf/extensions/MeshoptDecoder";
|
||||
|
||||
@resourceLoader(AssetType.GLTF, ["gltf", "glb"])
|
||||
export class GLTFLoader extends Loader<GLTFResource> {
|
||||
@@ -44,10 +44,22 @@ export class GLTFLoader extends Loader<GLTFResource> {
|
||||
...params
|
||||
});
|
||||
|
||||
return new AssetPromise((resolve, reject, setTaskCompleteProgress, setTaskDetailProgress) => {
|
||||
return new AssetPromise((resolve, reject, setTaskCompleteProgress, setTaskDetailProgress, onTaskCancel) => {
|
||||
context._setTaskCompleteProgress = setTaskCompleteProgress;
|
||||
context._setTaskDetailProgress = setTaskDetailProgress;
|
||||
context.parse().then(resolve).catch(reject);
|
||||
onTaskCancel(() => {
|
||||
const getPromises = context._getPromises;
|
||||
for (let i = 0, n = getPromises.length; i < n; i++) {
|
||||
getPromises[i].cancel();
|
||||
}
|
||||
});
|
||||
context
|
||||
.parse()
|
||||
.then(resolve)
|
||||
.catch((e) => {
|
||||
glTFResource.destroy();
|
||||
reject(e);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,7 +71,8 @@ export class GLTFResource extends ReferResource {
|
||||
materials && this._disassociationSuperResource(materials);
|
||||
if (meshes) {
|
||||
for (let i = 0, n = meshes.length; i < n; i++) {
|
||||
this._disassociationSuperResource(meshes[i]);
|
||||
const meshArr = meshes[i];
|
||||
meshArr && this._disassociationSuperResource(meshArr);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -79,7 +80,7 @@ export class GLTFResource extends ReferResource {
|
||||
private _disassociationSuperResource(resources: ReferResource[]): void {
|
||||
for (let i = 0, n = resources.length; i < n; i++) {
|
||||
// @ts-ignore
|
||||
resources[i]._disassociationSuperResource(this);
|
||||
resources[i]?._disassociationSuperResource(this);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import {
|
||||
AssetPromise,
|
||||
IndexFormat,
|
||||
Logger,
|
||||
Texture2D,
|
||||
TextureFilterMode,
|
||||
TypedArray,
|
||||
@@ -132,7 +134,7 @@ export class GLTFUtils {
|
||||
context: GLTFParserContext,
|
||||
bufferViews: IBufferView[],
|
||||
accessor: IAccessor
|
||||
): Promise<BufferInfo> {
|
||||
): AssetPromise<BufferInfo> {
|
||||
const componentType = accessor.componentType;
|
||||
const TypedArray = GLTFUtils.getComponentType(componentType);
|
||||
const dataElementSize = GLTFUtils.getAccessorTypeSize(accessor.type);
|
||||
@@ -140,47 +142,51 @@ export class GLTFUtils {
|
||||
const elementStride = dataElementSize * dataElementBytes;
|
||||
const accessorCount = accessor.count;
|
||||
|
||||
let promise: Promise<BufferInfo>;
|
||||
let promise: AssetPromise<BufferInfo>;
|
||||
|
||||
if (accessor.bufferView !== undefined) {
|
||||
const bufferViewIndex = accessor.bufferView;
|
||||
const bufferView = bufferViews[bufferViewIndex];
|
||||
promise = context
|
||||
.get<Uint8Array>(GLTFParserType.BufferView, accessor.bufferView)
|
||||
.then((bufferViewData) => {
|
||||
const bufferIndex = bufferView.buffer;
|
||||
const bufferByteOffset = bufferViewData.byteOffset ?? 0;
|
||||
const byteOffset = accessor.byteOffset ?? 0;
|
||||
|
||||
promise = context.get<Uint8Array>(GLTFParserType.BufferView, accessor.bufferView).then((bufferViewData) => {
|
||||
const bufferIndex = bufferView.buffer;
|
||||
const bufferByteOffset = bufferViewData.byteOffset ?? 0;
|
||||
const byteOffset = accessor.byteOffset ?? 0;
|
||||
const bufferStride = bufferView.byteStride;
|
||||
|
||||
const bufferStride = bufferView.byteStride;
|
||||
|
||||
let bufferInfo: BufferInfo;
|
||||
// According to the glTF official documentation only byteStride not undefined is allowed
|
||||
if (bufferStride !== undefined && bufferStride !== elementStride) {
|
||||
const bufferSlice = Math.floor(byteOffset / bufferStride);
|
||||
const bufferCacheKey = bufferViewIndex + ":" + componentType + ":" + bufferSlice + ":" + accessorCount;
|
||||
const accessorBufferCache = context.accessorBufferCache;
|
||||
bufferInfo = accessorBufferCache[bufferCacheKey];
|
||||
if (!bufferInfo) {
|
||||
const offset = bufferByteOffset + bufferSlice * bufferStride;
|
||||
const count = accessorCount * (bufferStride / dataElementBytes);
|
||||
let bufferInfo: BufferInfo;
|
||||
// According to the glTF official documentation only byteStride not undefined is allowed
|
||||
if (bufferStride !== undefined && bufferStride !== elementStride) {
|
||||
const bufferSlice = Math.floor(byteOffset / bufferStride);
|
||||
const bufferCacheKey = bufferViewIndex + ":" + componentType + ":" + bufferSlice + ":" + accessorCount;
|
||||
const accessorBufferCache = context.accessorBufferCache;
|
||||
bufferInfo = accessorBufferCache[bufferCacheKey];
|
||||
if (!bufferInfo) {
|
||||
const offset = bufferByteOffset + bufferSlice * bufferStride;
|
||||
const count = accessorCount * (bufferStride / dataElementBytes);
|
||||
const data = new TypedArray(bufferViewData.buffer, offset, count);
|
||||
accessorBufferCache[bufferCacheKey] = bufferInfo = new BufferInfo(data, true, bufferStride);
|
||||
bufferInfo.restoreInfo = new BufferDataRestoreInfo(
|
||||
new RestoreDataAccessor(bufferIndex, TypedArray, offset, count)
|
||||
);
|
||||
}
|
||||
} else {
|
||||
const offset = bufferByteOffset + byteOffset;
|
||||
const count = accessorCount * dataElementSize;
|
||||
const data = new TypedArray(bufferViewData.buffer, offset, count);
|
||||
accessorBufferCache[bufferCacheKey] = bufferInfo = new BufferInfo(data, true, bufferStride);
|
||||
bufferInfo = new BufferInfo(data, false, elementStride);
|
||||
bufferInfo.restoreInfo = new BufferDataRestoreInfo(
|
||||
new RestoreDataAccessor(bufferIndex, TypedArray, offset, count)
|
||||
);
|
||||
}
|
||||
} else {
|
||||
const offset = bufferByteOffset + byteOffset;
|
||||
const count = accessorCount * dataElementSize;
|
||||
const data = new TypedArray(bufferViewData.buffer, offset, count);
|
||||
bufferInfo = new BufferInfo(data, false, elementStride);
|
||||
bufferInfo.restoreInfo = new BufferDataRestoreInfo(
|
||||
new RestoreDataAccessor(bufferIndex, TypedArray, offset, count)
|
||||
);
|
||||
}
|
||||
|
||||
return bufferInfo;
|
||||
});
|
||||
return bufferInfo;
|
||||
})
|
||||
.catch((e) => {
|
||||
Logger.error("GLTFUtil getAccessorBuffer error", e);
|
||||
});
|
||||
} else {
|
||||
const count = accessorCount * dataElementSize;
|
||||
const data = new TypedArray(count);
|
||||
@@ -189,7 +195,7 @@ export class GLTFUtils {
|
||||
new RestoreDataAccessor(undefined, TypedArray, undefined, count)
|
||||
);
|
||||
|
||||
promise = Promise.resolve(bufferInfo);
|
||||
promise = AssetPromise.resolve(bufferInfo);
|
||||
}
|
||||
|
||||
return accessor.sparse
|
||||
@@ -240,47 +246,50 @@ export class GLTFUtils {
|
||||
const indicesBufferView = bufferViews[indices.bufferView];
|
||||
const valuesBufferView = bufferViews[values.bufferView];
|
||||
|
||||
return Promise.all([
|
||||
return AssetPromise.all([
|
||||
context.get<Uint8Array>(GLTFParserType.BufferView, indices.bufferView),
|
||||
context.get<Uint8Array>(GLTFParserType.BufferView, values.bufferView)
|
||||
]).then(([indicesUint8Array, valuesUin8Array]) => {
|
||||
const indicesByteOffset = (indices.byteOffset ?? 0) + (indicesUint8Array.byteOffset ?? 0);
|
||||
const indicesByteLength = indicesUint8Array.byteLength;
|
||||
const valuesByteOffset = (values.byteOffset ?? 0) + (valuesUin8Array.byteOffset ?? 0);
|
||||
const valuesByteLength = valuesUin8Array.byteLength;
|
||||
])
|
||||
.then(([indicesUint8Array, valuesUin8Array]) => {
|
||||
const indicesByteOffset = (indices.byteOffset ?? 0) + (indicesUint8Array.byteOffset ?? 0);
|
||||
const indicesByteLength = indicesUint8Array.byteLength;
|
||||
const valuesByteOffset = (values.byteOffset ?? 0) + (valuesUin8Array.byteOffset ?? 0);
|
||||
const valuesByteLength = valuesUin8Array.byteLength;
|
||||
|
||||
restoreInfo.typeSize = accessorTypeSize;
|
||||
restoreInfo.sparseCount = count;
|
||||
restoreInfo.typeSize = accessorTypeSize;
|
||||
restoreInfo.sparseCount = count;
|
||||
|
||||
const IndexTypeArray = GLTFUtils.getComponentType(indices.componentType);
|
||||
const IndexTypeArray = GLTFUtils.getComponentType(indices.componentType);
|
||||
const indexLength = indicesByteLength / IndexTypeArray.BYTES_PER_ELEMENT;
|
||||
const indicesArray = new IndexTypeArray(indicesUint8Array.buffer, indicesByteOffset, indexLength);
|
||||
restoreInfo.sparseIndices = new RestoreDataAccessor(
|
||||
indicesBufferView.buffer,
|
||||
IndexTypeArray,
|
||||
indicesByteOffset,
|
||||
indexLength
|
||||
);
|
||||
|
||||
const indexLength = indicesByteLength / IndexTypeArray.BYTES_PER_ELEMENT;
|
||||
const indicesArray = new IndexTypeArray(indicesUint8Array.buffer, indicesByteOffset, indexLength);
|
||||
restoreInfo.sparseIndices = new RestoreDataAccessor(
|
||||
indicesBufferView.buffer,
|
||||
IndexTypeArray,
|
||||
indicesByteOffset,
|
||||
indexLength
|
||||
);
|
||||
const valueLength = valuesByteLength / TypedArray.BYTES_PER_ELEMENT;
|
||||
const valuesArray = new TypedArray(valuesUin8Array.buffer, valuesByteOffset, valueLength);
|
||||
restoreInfo.sparseValues = new RestoreDataAccessor(
|
||||
valuesBufferView.buffer,
|
||||
TypedArray,
|
||||
valuesByteOffset,
|
||||
valueLength
|
||||
);
|
||||
|
||||
const valueLength = valuesByteLength / TypedArray.BYTES_PER_ELEMENT;
|
||||
const valuesArray = new TypedArray(valuesUin8Array.buffer, valuesByteOffset, valueLength);
|
||||
restoreInfo.sparseValues = new RestoreDataAccessor(
|
||||
valuesBufferView.buffer,
|
||||
TypedArray,
|
||||
valuesByteOffset,
|
||||
valueLength
|
||||
);
|
||||
|
||||
for (let i = 0; i < count; i++) {
|
||||
const replaceIndex = indicesArray[i];
|
||||
for (let j = 0; j < accessorTypeSize; j++) {
|
||||
data[replaceIndex * accessorTypeSize + j] = valuesArray[i * accessorTypeSize + j];
|
||||
for (let i = 0; i < count; i++) {
|
||||
const replaceIndex = indicesArray[i];
|
||||
for (let j = 0; j < accessorTypeSize; j++) {
|
||||
data[replaceIndex * accessorTypeSize + j] = valuesArray[i * accessorTypeSize + j];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bufferInfo.data = data;
|
||||
});
|
||||
bufferInfo.data = data;
|
||||
})
|
||||
.catch((e) => {
|
||||
Logger.error("GLTFUtil processingSparseData error", e);
|
||||
});
|
||||
}
|
||||
|
||||
static getIndexFormat(type: AccessorComponentType): IndexFormat {
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { AssetPromise, Logger } from "@galacean/engine-core";
|
||||
import { registerGLTFExtension } from "../parser/GLTFParser";
|
||||
import { GLTFParserContext, GLTFParserType } from "../parser/GLTFParserContext";
|
||||
import { GLTFExtensionMode, GLTFExtensionParser } from "./GLTFExtensionParser";
|
||||
@@ -6,18 +7,23 @@ import { getMeshoptDecoder } from "./MeshoptDecoder";
|
||||
|
||||
@registerGLTFExtension("EXT_meshopt_compression", GLTFExtensionMode.CreateAndParse)
|
||||
class EXT_meshopt_compression extends GLTFExtensionParser {
|
||||
override createAndParse(context: GLTFParserContext, schema: IEXTMeshoptCompressionSchema): Promise<Uint8Array> {
|
||||
return context.get<ArrayBuffer>(GLTFParserType.Buffer, schema.buffer).then((arrayBuffer) => {
|
||||
return getMeshoptDecoder().then((decoder) =>
|
||||
decoder.decodeGltfBuffer(
|
||||
schema.count,
|
||||
schema.byteStride,
|
||||
new Uint8Array(arrayBuffer, schema.byteOffset, schema.byteLength),
|
||||
schema.mode,
|
||||
schema.filter
|
||||
)
|
||||
);
|
||||
});
|
||||
override createAndParse(context: GLTFParserContext, schema: IEXTMeshoptCompressionSchema): AssetPromise<Uint8Array> {
|
||||
return context
|
||||
.get<ArrayBuffer>(GLTFParserType.Buffer, schema.buffer)
|
||||
.then((arrayBuffer) => {
|
||||
return getMeshoptDecoder().then((decoder) =>
|
||||
decoder.decodeGltfBuffer(
|
||||
schema.count,
|
||||
schema.byteStride,
|
||||
new Uint8Array(arrayBuffer, schema.byteOffset, schema.byteLength),
|
||||
schema.mode,
|
||||
schema.filter
|
||||
)
|
||||
);
|
||||
})
|
||||
.catch((e) => {
|
||||
Logger.error("EXT_meshopt_compression: buffer error", e);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { SystemInfo, Texture2D } from "@galacean/engine-core";
|
||||
import { AssetPromise, SystemInfo, Texture2D } from "@galacean/engine-core";
|
||||
import type { ITexture } from "../GLTFSchema";
|
||||
import { registerGLTFExtension } from "../parser/GLTFParser";
|
||||
import { GLTFParserContext } from "../parser/GLTFParserContext";
|
||||
@@ -26,13 +26,13 @@ class EXT_texture_webp extends GLTFExtensionParser {
|
||||
}
|
||||
}
|
||||
|
||||
override async createAndParse(
|
||||
override createAndParse(
|
||||
context: GLTFParserContext,
|
||||
schema: EXTWebPSchema,
|
||||
textureInfo: ITexture,
|
||||
textureIndex: number,
|
||||
isSRGBColorSpace: boolean
|
||||
): Promise<Texture2D> {
|
||||
): AssetPromise<Texture2D> {
|
||||
const webPIndex = schema.source;
|
||||
const { sampler, source: fallbackIndex = 0, name: textureName } = textureInfo;
|
||||
const texture = GLTFTextureParser._parseTexture(
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Material } from "@galacean/engine-core";
|
||||
import { AssetPromise, Material } from "@galacean/engine-core";
|
||||
import { registerGLTFExtension } from "../parser/GLTFParser";
|
||||
import { GLTFParserContext } from "../parser/GLTFParserContext";
|
||||
import { GLTFExtensionMode, GLTFExtensionParser } from "./GLTFExtensionParser";
|
||||
@@ -6,7 +6,7 @@ import { IGalaceanMaterialRemap } from "./GLTFExtensionSchema";
|
||||
|
||||
@registerGLTFExtension("GALACEAN_materials_remap", GLTFExtensionMode.CreateAndParse)
|
||||
class GALACEAN_materials_remap extends GLTFExtensionParser {
|
||||
override createAndParse(context: GLTFParserContext, schema: IGalaceanMaterialRemap): Promise<Material> {
|
||||
override createAndParse(context: GLTFParserContext, schema: IGalaceanMaterialRemap): AssetPromise<Material> {
|
||||
const { engine } = context.glTFResource;
|
||||
// @ts-ignore
|
||||
const promise = engine.resourceManager.getResourceByRef<Material>(schema);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { EngineObject } from "@galacean/engine-core";
|
||||
import { AssetPromise, EngineObject } from "@galacean/engine-core";
|
||||
import { GLTFExtensionOwnerSchema } from "../GLTFSchema";
|
||||
import { GLTFParserContext } from "../parser/GLTFParserContext";
|
||||
import { GLTFExtensionSchema } from "./GLTFExtensionSchema";
|
||||
@@ -26,7 +26,7 @@ export abstract class GLTFExtensionParser {
|
||||
extensionSchema: GLTFExtensionSchema,
|
||||
extensionOwnerSchema: GLTFExtensionOwnerSchema,
|
||||
...extra
|
||||
): EngineObject | Promise<EngineObject | Uint8Array> {
|
||||
): EngineObject | AssetPromise<EngineObject | Uint8Array> {
|
||||
throw "Not implemented.";
|
||||
}
|
||||
|
||||
@@ -44,7 +44,7 @@ export abstract class GLTFExtensionParser {
|
||||
extensionSchema: GLTFExtensionSchema,
|
||||
extensionOwnerSchema: GLTFExtensionOwnerSchema,
|
||||
...extra
|
||||
): void | Promise<void> {
|
||||
): void | AssetPromise<void> {
|
||||
throw "Not implemented.";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { PBRMaterial, Texture2D } from "@galacean/engine-core";
|
||||
import { Logger, PBRMaterial, Texture2D } from "@galacean/engine-core";
|
||||
import { GLTFMaterialParser } from "../parser/GLTFMaterialParser";
|
||||
import { registerGLTFExtension } from "../parser/GLTFParser";
|
||||
import { GLTFParserContext, GLTFParserType } from "../parser/GLTFParserContext";
|
||||
@@ -16,9 +16,14 @@ class KHR_materials_anisotropy extends GLTFExtensionParser {
|
||||
if (anisotropyTexture) {
|
||||
GLTFMaterialParser._checkOtherTextureTransform(anisotropyTexture, "Anisotropy texture");
|
||||
|
||||
context.get<Texture2D>(GLTFParserType.Texture, anisotropyTexture.index).then((texture) => {
|
||||
material.anisotropyTexture = texture;
|
||||
});
|
||||
context
|
||||
.get<Texture2D>(GLTFParserType.Texture, anisotropyTexture.index)
|
||||
.then((texture) => {
|
||||
material.anisotropyTexture = texture;
|
||||
})
|
||||
.catch((e) => {
|
||||
Logger.error("KHR_materials_anisotropy: anisotropy texture error", e);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { PBRMaterial, Texture2D } from "@galacean/engine-core";
|
||||
import { Logger, PBRMaterial, Texture2D } from "@galacean/engine-core";
|
||||
import { GLTFMaterialParser } from "../parser/GLTFMaterialParser";
|
||||
import { registerGLTFExtension } from "../parser/GLTFParser";
|
||||
import { GLTFParserContext, GLTFParserType } from "../parser/GLTFParserContext";
|
||||
@@ -22,23 +22,38 @@ class KHR_materials_clearcoat extends GLTFExtensionParser {
|
||||
if (clearcoatTexture) {
|
||||
GLTFMaterialParser._checkOtherTextureTransform(clearcoatTexture, "Clear coat");
|
||||
|
||||
context.get<Texture2D>(GLTFParserType.Texture, clearcoatTexture.index).then((texture) => {
|
||||
material.clearCoatTexture = texture;
|
||||
});
|
||||
context
|
||||
.get<Texture2D>(GLTFParserType.Texture, clearcoatTexture.index)
|
||||
.then((texture) => {
|
||||
material.clearCoatTexture = texture;
|
||||
})
|
||||
.catch((e) => {
|
||||
Logger.error("KHR_materials_clearcoat: clearcoat texture error", e);
|
||||
});
|
||||
}
|
||||
if (clearcoatRoughnessTexture) {
|
||||
GLTFMaterialParser._checkOtherTextureTransform(clearcoatRoughnessTexture, "Clear coat roughness");
|
||||
|
||||
context.get<Texture2D>(GLTFParserType.Texture, clearcoatRoughnessTexture.index).then((texture) => {
|
||||
material.clearCoatRoughnessTexture = texture;
|
||||
});
|
||||
context
|
||||
.get<Texture2D>(GLTFParserType.Texture, clearcoatRoughnessTexture.index)
|
||||
.then((texture) => {
|
||||
material.clearCoatRoughnessTexture = texture;
|
||||
})
|
||||
.catch((e) => {
|
||||
Logger.error("KHR_materials_clearcoat: clearcoat roughness texture error", e);
|
||||
});
|
||||
}
|
||||
if (clearcoatNormalTexture) {
|
||||
GLTFMaterialParser._checkOtherTextureTransform(clearcoatNormalTexture, "Clear coat normal");
|
||||
|
||||
context.get<Texture2D>(GLTFParserType.Texture, clearcoatNormalTexture.index).then((texture) => {
|
||||
material.clearCoatNormalTexture = texture;
|
||||
});
|
||||
context
|
||||
.get<Texture2D>(GLTFParserType.Texture, clearcoatNormalTexture.index)
|
||||
.then((texture) => {
|
||||
material.clearCoatNormalTexture = texture;
|
||||
})
|
||||
.catch((e) => {
|
||||
Logger.error("KHR_materials_clearcoat: clearcoat normal texture error", e);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { PBRMaterial, Texture2D } from "@galacean/engine-core";
|
||||
import { Logger, PBRMaterial, Texture2D } from "@galacean/engine-core";
|
||||
import { GLTFMaterialParser } from "../parser/GLTFMaterialParser";
|
||||
import { registerGLTFExtension } from "../parser/GLTFParser";
|
||||
import { GLTFParserContext, GLTFParserType } from "../parser/GLTFParserContext";
|
||||
@@ -24,16 +24,26 @@ class KHR_materials_iridescence extends GLTFExtensionParser {
|
||||
if (iridescenceTexture) {
|
||||
GLTFMaterialParser._checkOtherTextureTransform(iridescenceTexture, "Iridescence texture");
|
||||
|
||||
context.get<Texture2D>(GLTFParserType.Texture, iridescenceTexture.index).then((texture) => {
|
||||
material.iridescenceTexture = texture;
|
||||
});
|
||||
context
|
||||
.get<Texture2D>(GLTFParserType.Texture, iridescenceTexture.index)
|
||||
.then((texture) => {
|
||||
material.iridescenceTexture = texture;
|
||||
})
|
||||
.catch((e) => {
|
||||
Logger.error("KHR_materials_iridescence: iridescence texture error", e);
|
||||
});
|
||||
}
|
||||
if (iridescenceThicknessTexture) {
|
||||
GLTFMaterialParser._checkOtherTextureTransform(iridescenceThicknessTexture, "IridescenceThickness texture");
|
||||
|
||||
context.get<Texture2D>(GLTFParserType.Texture, iridescenceThicknessTexture.index).then((texture) => {
|
||||
material.iridescenceThicknessTexture = texture;
|
||||
});
|
||||
context
|
||||
.get<Texture2D>(GLTFParserType.Texture, iridescenceThicknessTexture.index)
|
||||
.then((texture) => {
|
||||
material.iridescenceThicknessTexture = texture;
|
||||
})
|
||||
.catch((e) => {
|
||||
Logger.error("KHR_materials_iridescence: iridescence thickness error", e);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { PBRSpecularMaterial, Texture2D } from "@galacean/engine-core";
|
||||
import { Logger, PBRSpecularMaterial, Texture2D } from "@galacean/engine-core";
|
||||
import { Color } from "@galacean/engine-math";
|
||||
import type { IMaterial } from "../GLTFSchema";
|
||||
import { GLTFMaterialParser } from "../parser/GLTFMaterialParser";
|
||||
@@ -28,10 +28,15 @@ class KHR_materials_pbrSpecularGlossiness extends GLTFExtensionParser {
|
||||
}
|
||||
|
||||
if (diffuseTexture) {
|
||||
context.get<Texture2D>(GLTFParserType.Texture, diffuseTexture.index).then((texture) => {
|
||||
material.baseTexture = texture;
|
||||
GLTFParser.executeExtensionsAdditiveAndParse(diffuseTexture.extensions, context, material, diffuseTexture);
|
||||
});
|
||||
context
|
||||
.get<Texture2D>(GLTFParserType.Texture, diffuseTexture.index)
|
||||
.then((texture) => {
|
||||
material.baseTexture = texture;
|
||||
GLTFParser.executeExtensionsAdditiveAndParse(diffuseTexture.extensions, context, material, diffuseTexture);
|
||||
})
|
||||
.catch((e) => {
|
||||
Logger.error("KHR_materials_pbrSpecularGlossiness: diffuse texture error", e);
|
||||
});
|
||||
}
|
||||
|
||||
if (specularFactor) {
|
||||
@@ -49,9 +54,14 @@ class KHR_materials_pbrSpecularGlossiness extends GLTFExtensionParser {
|
||||
if (specularGlossinessTexture) {
|
||||
GLTFMaterialParser._checkOtherTextureTransform(specularGlossinessTexture, "Specular glossiness");
|
||||
|
||||
context.get<Texture2D>(GLTFParserType.Texture, specularGlossinessTexture.index).then((texture) => {
|
||||
material.specularGlossinessTexture = texture;
|
||||
});
|
||||
context
|
||||
.get<Texture2D>(GLTFParserType.Texture, specularGlossinessTexture.index)
|
||||
.then((texture) => {
|
||||
material.specularGlossinessTexture = texture;
|
||||
})
|
||||
.catch((e) => {
|
||||
Logger.error("KHR_materials_pbrSpecularGlossiness: specular glossiness texture error", e);
|
||||
});
|
||||
}
|
||||
|
||||
material.name = ownerSchema.name;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { PBRMaterial, Texture2D } from "@galacean/engine-core";
|
||||
import { Logger, PBRMaterial, Texture2D } from "@galacean/engine-core";
|
||||
import { Color } from "@galacean/engine-math";
|
||||
import { GLTFMaterialParser } from "../parser/GLTFMaterialParser";
|
||||
import { registerGLTFExtension } from "../parser/GLTFParser";
|
||||
@@ -25,17 +25,27 @@ class KHR_materials_sheen extends GLTFExtensionParser {
|
||||
if (sheenColorTexture) {
|
||||
GLTFMaterialParser._checkOtherTextureTransform(sheenColorTexture, "Sheen texture");
|
||||
|
||||
context.get<Texture2D>(GLTFParserType.Texture, sheenColorTexture.index).then((texture) => {
|
||||
material.sheenColorTexture = texture;
|
||||
});
|
||||
context
|
||||
.get<Texture2D>(GLTFParserType.Texture, sheenColorTexture.index)
|
||||
.then((texture) => {
|
||||
material.sheenColorTexture = texture;
|
||||
})
|
||||
.catch((e) => {
|
||||
Logger.error("KHR_materials_sheen: sheenColorTexture error", e);
|
||||
});
|
||||
}
|
||||
|
||||
if (sheenRoughnessTexture) {
|
||||
GLTFMaterialParser._checkOtherTextureTransform(sheenRoughnessTexture, "SheenRoughness texture");
|
||||
|
||||
context.get<Texture2D>(GLTFParserType.Texture, sheenRoughnessTexture.index).then((texture) => {
|
||||
material.sheenRoughnessTexture = texture;
|
||||
});
|
||||
context
|
||||
.get<Texture2D>(GLTFParserType.Texture, sheenRoughnessTexture.index)
|
||||
.then((texture) => {
|
||||
material.sheenRoughnessTexture = texture;
|
||||
})
|
||||
.catch((e) => {
|
||||
Logger.error("KHR_materials_sheen: sheenRoughnessTexture error", e);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { PBRMaterial, Texture2D } from "@galacean/engine-core";
|
||||
import { Logger, PBRMaterial, Texture2D } from "@galacean/engine-core";
|
||||
import { GLTFMaterialParser } from "../parser/GLTFMaterialParser";
|
||||
import { registerGLTFExtension } from "../parser/GLTFParser";
|
||||
import { GLTFParserContext, GLTFParserType } from "../parser/GLTFParserContext";
|
||||
@@ -13,9 +13,14 @@ class KHR_materials_transmission extends GLTFExtensionParser {
|
||||
if (transmissionTexture) {
|
||||
GLTFMaterialParser._checkOtherTextureTransform(transmissionTexture, "Transmission texture");
|
||||
|
||||
context.get<Texture2D>(GLTFParserType.Texture, transmissionTexture.index).then((texture) => {
|
||||
material.transmissionTexture = texture;
|
||||
});
|
||||
context
|
||||
.get<Texture2D>(GLTFParserType.Texture, transmissionTexture.index)
|
||||
.then((texture) => {
|
||||
material.transmissionTexture = texture;
|
||||
})
|
||||
.catch((e) => {
|
||||
Logger.error("KHR_materials_transmission: transmission texture error", e);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Material, Renderer } from "@galacean/engine-core";
|
||||
import { Logger, Material, Renderer } from "@galacean/engine-core";
|
||||
import { registerGLTFExtension } from "../parser/GLTFParser";
|
||||
import { GLTFParserContext, GLTFParserType } from "../parser/GLTFParserContext";
|
||||
import { GLTFExtensionMode, GLTFExtensionParser } from "./GLTFExtensionParser";
|
||||
@@ -29,13 +29,18 @@ class KHR_materials_variants extends GLTFExtensionParser {
|
||||
|
||||
for (let i = 0; i < mappings.length; i++) {
|
||||
const { material: materialIndex, variants } = mappings[i];
|
||||
context.get<Material>(GLTFParserType.Material, materialIndex).then((material) => {
|
||||
extensionData.push({
|
||||
renderer,
|
||||
material,
|
||||
variants: variants.map((index) => variantNames[index].name)
|
||||
context
|
||||
.get<Material>(GLTFParserType.Material, materialIndex)
|
||||
.then((material) => {
|
||||
extensionData.push({
|
||||
renderer,
|
||||
material,
|
||||
variants: variants.map((index) => variantNames[index].name)
|
||||
});
|
||||
})
|
||||
.catch((e) => {
|
||||
Logger.error("KHR_materials_variants: material error", e);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { PBRMaterial, Texture2D } from "@galacean/engine-core";
|
||||
import { Logger, PBRMaterial, Texture2D } from "@galacean/engine-core";
|
||||
import { Color } from "@galacean/engine-math";
|
||||
import { GLTFMaterialParser } from "../parser/GLTFMaterialParser";
|
||||
import { registerGLTFExtension } from "../parser/GLTFParser";
|
||||
@@ -25,9 +25,14 @@ class KHR_materials_volume extends GLTFExtensionParser {
|
||||
if (thicknessTexture) {
|
||||
GLTFMaterialParser._checkOtherTextureTransform(thicknessTexture, "Thickness texture");
|
||||
|
||||
context.get<Texture2D>(GLTFParserType.Texture, thicknessTexture.index).then((texture) => {
|
||||
material.thicknessTexture = texture;
|
||||
});
|
||||
context
|
||||
.get<Texture2D>(GLTFParserType.Texture, thicknessTexture.index)
|
||||
.then((texture) => {
|
||||
material.thicknessTexture = texture;
|
||||
})
|
||||
.catch((e) => {
|
||||
Logger.error("KHR_materials_volume: thickness texture error", e);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import { AssetType, Texture2D, Utils } from "@galacean/engine-core";
|
||||
import { AssetPromise, AssetType, Logger, Texture2D, Utils } from "@galacean/engine-core";
|
||||
import { BufferTextureRestoreInfo } from "../../GLTFContentRestorer";
|
||||
import { KTX2Loader } from "../../ktx2/KTX2Loader";
|
||||
import type { ITexture } from "../GLTFSchema";
|
||||
import { GLTFUtils } from "../GLTFUtils";
|
||||
import { registerGLTFExtension } from "../parser/GLTFParser";
|
||||
import { GLTFParserContext, GLTFParserType } from "../parser/GLTFParserContext";
|
||||
import { GLTFExtensionMode, GLTFExtensionParser } from "./GLTFExtensionParser";
|
||||
import { GLTFUtils } from "../GLTFUtils";
|
||||
import { BufferTextureRestoreInfo } from "../../GLTFContentRestorer";
|
||||
import { KTX2Loader } from "../../ktx2/KTX2Loader";
|
||||
|
||||
interface KHRBasisSchema {
|
||||
source: number;
|
||||
@@ -13,11 +13,11 @@ interface KHRBasisSchema {
|
||||
|
||||
@registerGLTFExtension("KHR_texture_basisu", GLTFExtensionMode.CreateAndParse)
|
||||
class KHR_texture_basisu extends GLTFExtensionParser {
|
||||
override async createAndParse(
|
||||
override createAndParse(
|
||||
context: GLTFParserContext,
|
||||
schema: KHRBasisSchema,
|
||||
textureInfo: ITexture
|
||||
): Promise<Texture2D> {
|
||||
): AssetPromise<Texture2D> {
|
||||
const { glTF, glTFResource } = context;
|
||||
const { engine, url } = glTFResource;
|
||||
|
||||
@@ -48,23 +48,28 @@ class KHR_texture_basisu extends GLTFExtensionParser {
|
||||
} else {
|
||||
const bufferView = glTF.bufferViews[bufferViewIndex];
|
||||
|
||||
return context.get<ArrayBuffer>(GLTFParserType.Buffer, bufferView.buffer).then((buffer) => {
|
||||
const imageBuffer = new Uint8Array(buffer, bufferView.byteOffset, bufferView.byteLength);
|
||||
return context
|
||||
.get<ArrayBuffer>(GLTFParserType.Buffer, bufferView.buffer)
|
||||
.then((buffer) => {
|
||||
const imageBuffer = new Uint8Array(buffer, bufferView.byteOffset, bufferView.byteLength);
|
||||
|
||||
return KTX2Loader._parseBuffer(imageBuffer, engine)
|
||||
.then(({ ktx2Container, engine, result, targetFormat, params }) =>
|
||||
KTX2Loader._createTextureByBuffer(engine, ktx2Container.isSRGB, result, targetFormat, params)
|
||||
)
|
||||
.then((texture: Texture2D) => {
|
||||
texture.name = textureName || imageName || `texture_${bufferViewIndex}`;
|
||||
if (sampler !== undefined) {
|
||||
GLTFUtils.parseSampler(texture, samplerInfo);
|
||||
}
|
||||
const bufferTextureRestoreInfo = new BufferTextureRestoreInfo(texture, bufferView, mimeType);
|
||||
context.contentRestorer.bufferTextures.push(bufferTextureRestoreInfo);
|
||||
return texture;
|
||||
});
|
||||
});
|
||||
return KTX2Loader._parseBuffer(imageBuffer, engine)
|
||||
.then(({ ktx2Container, engine, result, targetFormat, params }) =>
|
||||
KTX2Loader._createTextureByBuffer(engine, ktx2Container.isSRGB, result, targetFormat, params)
|
||||
)
|
||||
.then((texture: Texture2D) => {
|
||||
texture.name = textureName || imageName || `texture_${bufferViewIndex}`;
|
||||
if (sampler !== undefined) {
|
||||
GLTFUtils.parseSampler(texture, samplerInfo);
|
||||
}
|
||||
const bufferTextureRestoreInfo = new BufferTextureRestoreInfo(texture, bufferView, mimeType);
|
||||
context.contentRestorer.bufferTextures.push(bufferTextureRestoreInfo);
|
||||
return texture;
|
||||
});
|
||||
})
|
||||
.catch((e) => {
|
||||
Logger.error("KHR_texture_basisu: buffer error", e);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ import {
|
||||
AnimationFloatArrayCurve,
|
||||
AnimationQuaternionCurve,
|
||||
AnimationVector3Curve,
|
||||
AssetPromise,
|
||||
Component,
|
||||
Entity,
|
||||
InterpolationType,
|
||||
@@ -32,7 +33,7 @@ export class GLTFAnimationParser extends GLTFParser {
|
||||
context: GLTFParserContext,
|
||||
animationClip: AnimationClip,
|
||||
animationInfo: IAnimation
|
||||
): Promise<AnimationClip> {
|
||||
): AssetPromise<AnimationClip> {
|
||||
const { glTF } = context;
|
||||
const { accessors, bufferViews } = glTF;
|
||||
const { channels, samplers } = animationInfo;
|
||||
@@ -41,7 +42,7 @@ export class GLTFAnimationParser extends GLTFParser {
|
||||
const entities = context.get<Entity>(GLTFParserType.Entity);
|
||||
|
||||
let duration = -1;
|
||||
let promises = new Array<Promise<void | Entity[]>>();
|
||||
let promises = new Array<AssetPromise<void | Entity[]>>();
|
||||
|
||||
// parse samplers
|
||||
for (let j = 0, m = len; j < m; j++) {
|
||||
@@ -49,7 +50,7 @@ export class GLTFAnimationParser extends GLTFParser {
|
||||
const inputAccessor = accessors[glTFSampler.input];
|
||||
const outputAccessor = accessors[glTFSampler.output];
|
||||
|
||||
const promise = Promise.all([
|
||||
const promise = AssetPromise.all([
|
||||
GLTFUtils.getAccessorBuffer(context, bufferViews, inputAccessor),
|
||||
GLTFUtils.getAccessorBuffer(context, bufferViews, outputAccessor)
|
||||
]).then((bufferInfos) => {
|
||||
@@ -98,7 +99,7 @@ export class GLTFAnimationParser extends GLTFParser {
|
||||
|
||||
promises.push(context.get<Entity>(GLTFParserType.Scene));
|
||||
|
||||
return Promise.all(promises).then(() => {
|
||||
return AssetPromise.all(promises).then(() => {
|
||||
for (let j = 0, m = channels.length; j < m; j++) {
|
||||
const glTFChannel = channels[j];
|
||||
const { target } = glTFChannel;
|
||||
@@ -227,16 +228,16 @@ export class GLTFAnimationParser extends GLTFParser {
|
||||
}
|
||||
}
|
||||
|
||||
parse(context: GLTFParserContext, index: number): Promise<AnimationClip> {
|
||||
parse(context: GLTFParserContext, index: number): AssetPromise<AnimationClip> {
|
||||
const animationInfo = context.glTF.animations[index];
|
||||
const { name = `AnimationClip${index}` } = animationInfo;
|
||||
|
||||
const animationClipPromise =
|
||||
<Promise<AnimationClip> | AnimationClip>(
|
||||
<AssetPromise<AnimationClip> | AnimationClip>(
|
||||
GLTFParser.executeExtensionsCreateAndParse(animationInfo.extensions, context, animationInfo)
|
||||
) || GLTFAnimationParser._parseStandardProperty(context, new AnimationClip(name), animationInfo);
|
||||
|
||||
return Promise.resolve(animationClipPromise).then((animationClip) => {
|
||||
return AssetPromise.resolve(animationClipPromise).then((animationClip) => {
|
||||
GLTFParser.executeExtensionsAdditiveAndParse(animationInfo.extensions, context, animationClip, animationInfo);
|
||||
return animationClip;
|
||||
});
|
||||
|
||||
@@ -2,22 +2,29 @@ import {
|
||||
AnimationClip,
|
||||
AnimatorController,
|
||||
AnimatorControllerLayer,
|
||||
AnimatorStateMachine
|
||||
AnimatorStateMachine,
|
||||
AssetPromise,
|
||||
Logger
|
||||
} from "@galacean/engine-core";
|
||||
import { GLTFParser } from "./GLTFParser";
|
||||
import { GLTFParserContext, GLTFParserType, registerGLTFParser } from "./GLTFParserContext";
|
||||
|
||||
@registerGLTFParser(GLTFParserType.AnimatorController)
|
||||
export class GLTFAnimatorControllerParser extends GLTFParser {
|
||||
parse(context: GLTFParserContext): Promise<AnimatorController> {
|
||||
parse(context: GLTFParserContext): AssetPromise<AnimatorController> {
|
||||
if (!context.needAnimatorController) {
|
||||
return Promise.resolve(null);
|
||||
return AssetPromise.resolve(null);
|
||||
}
|
||||
|
||||
return context.get<AnimationClip>(GLTFParserType.Animation).then((animations) => {
|
||||
const animatorController = this._createAnimatorController(context, animations);
|
||||
return Promise.resolve(animatorController);
|
||||
});
|
||||
return context
|
||||
.get<AnimationClip>(GLTFParserType.Animation)
|
||||
.then((animations) => {
|
||||
const animatorController = this._createAnimatorController(context, animations);
|
||||
return AssetPromise.resolve(animatorController);
|
||||
})
|
||||
.catch((e) => {
|
||||
Logger.error("GLTFAnimatorControllerParser: animator controller error", e);
|
||||
});
|
||||
}
|
||||
|
||||
private _createAnimatorController(context: GLTFParserContext, animations: AnimationClip[]): AnimatorController {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { RequestConfig, Utils } from "@galacean/engine-core";
|
||||
import { AssetPromise, RequestConfig, Utils } from "@galacean/engine-core";
|
||||
import { BufferRequestInfo } from "../../GLTFContentRestorer";
|
||||
import type { IBuffer } from "../GLTFSchema";
|
||||
import { GLTFParser } from "./GLTFParser";
|
||||
@@ -6,13 +6,15 @@ import { GLTFParserContext, GLTFParserType, registerGLTFParser } from "./GLTFPar
|
||||
|
||||
@registerGLTFParser(GLTFParserType.Buffer)
|
||||
export class GLTFBufferParser extends GLTFParser {
|
||||
parse(context: GLTFParserContext, index: number): Promise<ArrayBuffer> {
|
||||
parse(context: GLTFParserContext, index: number): AssetPromise<ArrayBuffer> {
|
||||
const buffers = context.glTF.buffers;
|
||||
|
||||
return context.buffers ? Promise.resolve(context.buffers[index]) : this._parseSingleBuffer(context, buffers[index]);
|
||||
return context.buffers
|
||||
? AssetPromise.resolve(context.buffers[index])
|
||||
: this._parseSingleBuffer(context, buffers[index]);
|
||||
}
|
||||
|
||||
private _parseSingleBuffer(context: GLTFParserContext, bufferInfo: IBuffer): Promise<ArrayBuffer> {
|
||||
private _parseSingleBuffer(context: GLTFParserContext, bufferInfo: IBuffer): AssetPromise<ArrayBuffer> {
|
||||
const { glTFResource, contentRestorer, resourceManager } = context;
|
||||
const url = glTFResource.url;
|
||||
// @ts-ignore
|
||||
|
||||
@@ -1,15 +1,19 @@
|
||||
import { registerGLTFParser, GLTFParserType, GLTFParserContext } from "./GLTFParserContext";
|
||||
import { AssetPromise, Logger } from "@galacean/engine-core";
|
||||
import { GLTFParser } from "./GLTFParser";
|
||||
import { GLTFParserContext, GLTFParserType, registerGLTFParser } from "./GLTFParserContext";
|
||||
|
||||
@registerGLTFParser(GLTFParserType.BufferView)
|
||||
export class GLTFBufferViewParser extends GLTFParser {
|
||||
parse(context: GLTFParserContext, index: number): Promise<Uint8Array> {
|
||||
parse(context: GLTFParserContext, index: number): AssetPromise<Uint8Array> {
|
||||
const bufferView = context.glTF.bufferViews[index];
|
||||
const { extensions, byteOffset = 0, byteLength, buffer: bufferIndex } = bufferView;
|
||||
return extensions
|
||||
? <Promise<Uint8Array>>GLTFParser.executeExtensionsCreateAndParse(extensions, context, bufferView)
|
||||
? <AssetPromise<Uint8Array>>GLTFParser.executeExtensionsCreateAndParse(extensions, context, bufferView)
|
||||
: context
|
||||
.get<ArrayBuffer>(GLTFParserType.Buffer, bufferIndex)
|
||||
.then((buffer) => new Uint8Array(buffer, byteOffset, byteLength));
|
||||
.then((buffer) => new Uint8Array(buffer, byteOffset, byteLength))
|
||||
.catch((e) => {
|
||||
Logger.error("GLTFBufferViewParser: buffer error", e);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import {
|
||||
BlinnPhongMaterial,
|
||||
Engine,
|
||||
AssetPromise,
|
||||
Logger,
|
||||
Material,
|
||||
PBRMaterial,
|
||||
@@ -17,12 +16,6 @@ import { GLTFParserContext, GLTFParserType, registerGLTFParser } from "./GLTFPar
|
||||
|
||||
@registerGLTFParser(GLTFParserType.Material)
|
||||
export class GLTFMaterialParser extends GLTFParser {
|
||||
/** @internal */
|
||||
static _getDefaultMaterial(engine: Engine): BlinnPhongMaterial {
|
||||
return (GLTFMaterialParser._defaultMaterial ||= new BlinnPhongMaterial(engine));
|
||||
}
|
||||
private static _defaultMaterial: BlinnPhongMaterial;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
@@ -64,15 +57,20 @@ export class GLTFMaterialParser extends GLTFParser {
|
||||
);
|
||||
}
|
||||
if (baseColorTexture) {
|
||||
context.get<Texture2D>(GLTFParserType.Texture, baseColorTexture.index).then((texture) => {
|
||||
material.baseTexture = texture;
|
||||
GLTFParser.executeExtensionsAdditiveAndParse(
|
||||
baseColorTexture.extensions,
|
||||
context,
|
||||
material,
|
||||
baseColorTexture
|
||||
);
|
||||
});
|
||||
context
|
||||
.get<Texture2D>(GLTFParserType.Texture, baseColorTexture.index)
|
||||
.then((texture) => {
|
||||
material.baseTexture = texture;
|
||||
GLTFParser.executeExtensionsAdditiveAndParse(
|
||||
baseColorTexture.extensions,
|
||||
context,
|
||||
material,
|
||||
baseColorTexture
|
||||
);
|
||||
})
|
||||
.catch((e) => {
|
||||
Logger.error("GLTFMaterialParser: baseColorTexture error", e);
|
||||
});
|
||||
}
|
||||
|
||||
if (material.constructor === PBRMaterial) {
|
||||
@@ -80,10 +78,14 @@ export class GLTFMaterialParser extends GLTFParser {
|
||||
material.roughness = roughnessFactor ?? 1;
|
||||
if (metallicRoughnessTexture) {
|
||||
GLTFMaterialParser._checkOtherTextureTransform(metallicRoughnessTexture, "Roughness metallic");
|
||||
|
||||
context.get<Texture2D>(GLTFParserType.Texture, metallicRoughnessTexture.index).then((texture) => {
|
||||
material.roughnessMetallicTexture = texture;
|
||||
});
|
||||
context
|
||||
.get<Texture2D>(GLTFParserType.Texture, metallicRoughnessTexture.index)
|
||||
.then((texture) => {
|
||||
material.roughnessMetallicTexture = texture;
|
||||
})
|
||||
.catch((e) => {
|
||||
Logger.error("GLTFMaterialParser: metallicRoughnessTexture error", e);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -91,10 +93,14 @@ export class GLTFMaterialParser extends GLTFParser {
|
||||
if (material.constructor === PBRMaterial || material.constructor === PBRSpecularMaterial) {
|
||||
if (emissiveTexture) {
|
||||
GLTFMaterialParser._checkOtherTextureTransform(emissiveTexture, "Emissive");
|
||||
|
||||
context.get<Texture2D>(GLTFParserType.Texture, emissiveTexture.index).then((texture) => {
|
||||
material.emissiveTexture = texture;
|
||||
});
|
||||
context
|
||||
.get<Texture2D>(GLTFParserType.Texture, emissiveTexture.index)
|
||||
.then((texture) => {
|
||||
material.emissiveTexture = texture;
|
||||
})
|
||||
.catch((e) => {
|
||||
Logger.error("GLTFMaterialParser: emissiveTexture error", e);
|
||||
});
|
||||
}
|
||||
|
||||
if (emissiveFactor) {
|
||||
@@ -109,9 +115,14 @@ export class GLTFMaterialParser extends GLTFParser {
|
||||
const { index, scale } = normalTexture;
|
||||
GLTFMaterialParser._checkOtherTextureTransform(normalTexture, "Normal");
|
||||
|
||||
context.get<Texture2D>(GLTFParserType.Texture, index).then((texture) => {
|
||||
material.normalTexture = texture;
|
||||
});
|
||||
context
|
||||
.get<Texture2D>(GLTFParserType.Texture, index)
|
||||
.then((texture) => {
|
||||
material.normalTexture = texture;
|
||||
})
|
||||
.catch((e) => {
|
||||
Logger.error("GLTFMaterialParser: emissiveTexture error", e);
|
||||
});
|
||||
|
||||
if (scale !== undefined) {
|
||||
material.normalTextureIntensity = scale;
|
||||
@@ -122,9 +133,14 @@ export class GLTFMaterialParser extends GLTFParser {
|
||||
const { index, strength, texCoord } = occlusionTexture;
|
||||
GLTFMaterialParser._checkOtherTextureTransform(occlusionTexture, "Occlusion");
|
||||
|
||||
context.get<Texture2D>(GLTFParserType.Texture, index).then((texture) => {
|
||||
material.occlusionTexture = texture;
|
||||
});
|
||||
context
|
||||
.get<Texture2D>(GLTFParserType.Texture, index)
|
||||
.then((texture) => {
|
||||
material.occlusionTexture = texture;
|
||||
})
|
||||
.catch((e) => {
|
||||
Logger.error("GLTFMaterialParser: occlusionTexture error", e);
|
||||
});
|
||||
|
||||
if (strength !== undefined) {
|
||||
material.occlusionTextureIntensity = strength;
|
||||
@@ -156,7 +172,7 @@ export class GLTFMaterialParser extends GLTFParser {
|
||||
}
|
||||
}
|
||||
|
||||
parse(context: GLTFParserContext, index: number): Promise<Material> {
|
||||
parse(context: GLTFParserContext, index: number): AssetPromise<Material> {
|
||||
const materialInfo = context.glTF.materials[index];
|
||||
const glTFResource = context.glTFResource;
|
||||
const engine = glTFResource.engine;
|
||||
@@ -171,8 +187,9 @@ export class GLTFMaterialParser extends GLTFParser {
|
||||
GLTFMaterialParser._parseStandardProperty(context, material as PBRMaterial, materialInfo);
|
||||
}
|
||||
|
||||
return Promise.resolve(material).then((material) => {
|
||||
material ||= GLTFMaterialParser._getDefaultMaterial(engine);
|
||||
return AssetPromise.resolve(material).then((material) => {
|
||||
// @ts-ignore
|
||||
material ||= engine._basicResources._getBlinnPhongMaterial();
|
||||
GLTFParser.executeExtensionsAdditiveAndParse(materialInfo.extensions, context, material, materialInfo);
|
||||
// @ts-ignore
|
||||
material._associationSuperResource(glTFResource);
|
||||
|
||||
@@ -1,4 +1,12 @@
|
||||
import { BlendShape, Buffer, BufferBindFlag, BufferUsage, ModelMesh, VertexElement } from "@galacean/engine-core";
|
||||
import {
|
||||
AssetPromise,
|
||||
BlendShape,
|
||||
Buffer,
|
||||
BufferBindFlag,
|
||||
BufferUsage,
|
||||
ModelMesh,
|
||||
VertexElement
|
||||
} from "@galacean/engine-core";
|
||||
import { Vector3 } from "@galacean/engine-math";
|
||||
import {
|
||||
BlendShapeDataRestoreInfo,
|
||||
@@ -26,7 +34,7 @@ export class GLTFMeshParser extends GLTFParser {
|
||||
gltfPrimitive: IMeshPrimitive,
|
||||
gltf: IGLTF,
|
||||
keepMeshData: boolean
|
||||
): Promise<ModelMesh> {
|
||||
): AssetPromise<ModelMesh> {
|
||||
const { accessors } = gltf;
|
||||
const { attributes, targets, indices, mode } = gltfPrimitive;
|
||||
const engine = mesh.engine;
|
||||
@@ -35,7 +43,7 @@ export class GLTFMeshParser extends GLTFParser {
|
||||
let vertexCount: number;
|
||||
let bufferBindIndex = 0;
|
||||
|
||||
const promises = new Array<Promise<void>>();
|
||||
const promises = new Array<AssetPromise<void>>();
|
||||
for (const attribute in attributes) {
|
||||
const accessor = accessors[attributes[attribute]];
|
||||
const promise = GLTFUtils.getAccessorBuffer(context, gltf.bufferViews, accessor).then((accessorBuffer) => {
|
||||
@@ -121,7 +129,7 @@ export class GLTFMeshParser extends GLTFParser {
|
||||
promises.push(promise);
|
||||
}
|
||||
|
||||
return Promise.all(promises).then(() => {
|
||||
return AssetPromise.all(promises).then(() => {
|
||||
mesh.setVertexElements(vertexElements);
|
||||
|
||||
// Indices
|
||||
@@ -155,7 +163,7 @@ export class GLTFMeshParser extends GLTFParser {
|
||||
context: GLTFParserContext,
|
||||
glTF: IGLTF,
|
||||
accessor: IAccessor
|
||||
): Promise<{ vertices: Vector3[]; restoreInfo: BlendShapeDataRestoreInfo }> {
|
||||
): AssetPromise<{ vertices: Vector3[]; restoreInfo: BlendShapeDataRestoreInfo }> {
|
||||
return GLTFUtils.getAccessorBuffer(context, glTF.bufferViews, accessor).then((bufferInfo) => {
|
||||
const buffer = bufferInfo.data;
|
||||
const byteOffset = bufferInfo.interleaved ? (accessor.byteOffset ?? 0) % bufferInfo.stride : 0;
|
||||
@@ -186,11 +194,11 @@ export class GLTFMeshParser extends GLTFParser {
|
||||
glTFTargets: {
|
||||
[name: string]: number;
|
||||
}[]
|
||||
): Promise<void> {
|
||||
): AssetPromise<void> {
|
||||
const glTF = context.glTF;
|
||||
const accessors = glTF.accessors;
|
||||
const blendShapeNames = glTFMesh.extras ? glTFMesh.extras.targetNames : null;
|
||||
let promises = new Array<Promise<void>>();
|
||||
let promises = new Array<AssetPromise<void>>();
|
||||
|
||||
const blendShapeCount = glTFTargets.length;
|
||||
const blendShapeCollection = new Array<BlendShapeData>(blendShapeCount);
|
||||
@@ -206,13 +214,12 @@ export class GLTFMeshParser extends GLTFParser {
|
||||
const hasNormal = normalTarget !== undefined;
|
||||
const hasTangent = tangentTarget !== undefined;
|
||||
|
||||
const promise = Promise.all([
|
||||
const promise = AssetPromise.all([
|
||||
this._getBlendShapeData(context, glTF, accessors[targets["POSITION"]]),
|
||||
hasNormal ? this._getBlendShapeData(context, glTF, accessors[normalTarget]) : null,
|
||||
hasTangent ? this._getBlendShapeData(context, glTF, accessors[tangentTarget]) : null
|
||||
]).then((vertices) => {
|
||||
const [positionData, normalData, tangentData] = vertices;
|
||||
|
||||
const blendShape = new BlendShape(name);
|
||||
blendShape.addFrame(
|
||||
1.0,
|
||||
@@ -232,7 +239,7 @@ export class GLTFMeshParser extends GLTFParser {
|
||||
promises.push(promise);
|
||||
}
|
||||
|
||||
return Promise.all(promises).then(() => {
|
||||
return AssetPromise.all(promises).then(() => {
|
||||
for (const blendShape of blendShapeCollection) {
|
||||
mesh.addBlendShape(blendShape.blendShape);
|
||||
meshRestoreInfo.blendShapes.push(blendShape.restoreInfo);
|
||||
@@ -240,18 +247,17 @@ export class GLTFMeshParser extends GLTFParser {
|
||||
});
|
||||
}
|
||||
|
||||
parse(context: GLTFParserContext, index: number): Promise<ModelMesh[]> {
|
||||
parse(context: GLTFParserContext, index: number): AssetPromise<ModelMesh[]> {
|
||||
const meshInfo = context.glTF.meshes[index];
|
||||
|
||||
const { glTF, glTFResource } = context;
|
||||
const engine = glTFResource.engine;
|
||||
const primitivePromises = new Array<Promise<ModelMesh>>();
|
||||
const primitivePromises = new Array<AssetPromise<ModelMesh>>();
|
||||
|
||||
for (let i = 0, length = meshInfo.primitives.length; i < length; i++) {
|
||||
const gltfPrimitive = meshInfo.primitives[i];
|
||||
|
||||
primitivePromises[i] = new Promise((resolve) => {
|
||||
const mesh = <ModelMesh | Promise<ModelMesh>>(
|
||||
primitivePromises[i] = new AssetPromise((resolve, reject) => {
|
||||
const mesh = <ModelMesh | AssetPromise<ModelMesh>>(
|
||||
GLTFParser.executeExtensionsCreateAndParse(gltfPrimitive.extensions, context, gltfPrimitive, meshInfo)
|
||||
);
|
||||
|
||||
@@ -284,12 +290,12 @@ export class GLTFMeshParser extends GLTFParser {
|
||||
gltfPrimitive,
|
||||
glTF,
|
||||
context.params.keepMeshData
|
||||
).then(resolve);
|
||||
).then(resolve, reject);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return Promise.all(primitivePromises);
|
||||
return AssetPromise.all(primitivePromises);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { AnimationClip, EngineObject, Material, Mesh } from "@galacean/engine-core";
|
||||
import { AssetPromise, EngineObject } from "@galacean/engine-core";
|
||||
import type { GLTFExtensionOwnerSchema } from "../GLTFSchema";
|
||||
import { GLTFExtensionMode, GLTFExtensionParser } from "../extensions/GLTFExtensionParser";
|
||||
import { GLTFExtensionSchema } from "../extensions/GLTFExtensionSchema";
|
||||
@@ -23,15 +23,15 @@ export abstract class GLTFParser {
|
||||
context: GLTFParserContext,
|
||||
ownerSchema: GLTFExtensionOwnerSchema,
|
||||
...extra
|
||||
): EngineObject | void | Promise<EngineObject | Uint8Array | void> {
|
||||
let resource: EngineObject | Promise<EngineObject> = null;
|
||||
): EngineObject | void | AssetPromise<EngineObject | Uint8Array | void> {
|
||||
let resource: EngineObject | AssetPromise<EngineObject> = null;
|
||||
|
||||
const extensionArray = Object.keys(extensions);
|
||||
for (let i = extensionArray.length - 1; i >= 0; --i) {
|
||||
const extensionName = extensionArray[i];
|
||||
const extensionSchema = extensions[extensionName];
|
||||
|
||||
resource = <EngineObject | Promise<EngineObject>>(
|
||||
resource = <EngineObject | AssetPromise<EngineObject>>(
|
||||
GLTFParser._createAndParse(extensionName, context, extensionSchema, ownerSchema, ...extra)
|
||||
);
|
||||
if (resource) {
|
||||
@@ -107,7 +107,7 @@ export abstract class GLTFParser {
|
||||
extensionSchema: GLTFExtensionSchema,
|
||||
ownerSchema: GLTFExtensionOwnerSchema,
|
||||
...extra
|
||||
): EngineObject | Uint8Array | Promise<EngineObject | Uint8Array> {
|
||||
): EngineObject | Uint8Array | AssetPromise<EngineObject | Uint8Array> {
|
||||
const parser = GLTFParser.getExtensionParser(extensionName, GLTFExtensionMode.CreateAndParse);
|
||||
|
||||
if (parser) {
|
||||
@@ -124,10 +124,7 @@ export abstract class GLTFParser {
|
||||
...extra
|
||||
): void {
|
||||
const parser = GLTFParser.getExtensionParser(extensionName, GLTFExtensionMode.AdditiveParse);
|
||||
|
||||
if (parser) {
|
||||
parser.additiveParse(context, parseResource, extensionSchema, ownerSchema, ...extra);
|
||||
}
|
||||
parser?.additiveParse(context, parseResource, extensionSchema, ownerSchema, ...extra);
|
||||
}
|
||||
|
||||
abstract parse(context: GLTFParserContext, index?: number);
|
||||
|
||||
@@ -2,8 +2,10 @@ import {
|
||||
AnimationClip,
|
||||
Animator,
|
||||
AnimatorController,
|
||||
AssetPromise,
|
||||
Buffer,
|
||||
Entity,
|
||||
Logger,
|
||||
Material,
|
||||
ModelMesh,
|
||||
ResourceManager,
|
||||
@@ -33,6 +35,9 @@ export class GLTFParserContext {
|
||||
buffers?: ArrayBuffer[];
|
||||
needAnimatorController = false;
|
||||
|
||||
/** @internal */
|
||||
_getPromises: AssetPromise<unknown>[] = [];
|
||||
|
||||
private _resourceCache = new Map<string, any>();
|
||||
private _progress = {
|
||||
taskDetail: {},
|
||||
@@ -54,21 +59,21 @@ export class GLTFParserContext {
|
||||
|
||||
get<T>(type: GLTFParserType.Entity, index: number): Entity;
|
||||
get<T>(type: GLTFParserType.Entity): Entity[];
|
||||
get<T>(type: GLTFParserType.Schema): Promise<T>;
|
||||
get<T>(type: GLTFParserType.Validator): Promise<T>;
|
||||
get<T>(type: GLTFParserType.AnimatorController): Promise<T>;
|
||||
get<T>(type: GLTFParserType, index: number): Promise<T>;
|
||||
get<T>(type: GLTFParserType): Promise<T[]>;
|
||||
get<T>(type: GLTFParserType, index?: number): Entity | Entity[] | Promise<T> | Promise<T[]> {
|
||||
get<T>(type: GLTFParserType.Schema): AssetPromise<T>;
|
||||
get<T>(type: GLTFParserType.Validator): AssetPromise<T>;
|
||||
get<T>(type: GLTFParserType.AnimatorController): AssetPromise<T>;
|
||||
get<T>(type: GLTFParserType, index: number): AssetPromise<T>;
|
||||
get<T>(type: GLTFParserType): AssetPromise<T[]>;
|
||||
get<T>(type: GLTFParserType, index?: number): Entity | Entity[] | AssetPromise<T> | AssetPromise<T[]> {
|
||||
const parser = GLTFParserContext._parsers[type];
|
||||
|
||||
if (!parser) {
|
||||
return Promise.resolve(null);
|
||||
return AssetPromise.resolve(null);
|
||||
}
|
||||
|
||||
const cache = this._resourceCache;
|
||||
const cacheKey = index === undefined ? `${type}` : `${type}:${index}`;
|
||||
let resource: Entity | Entity[] | Promise<T> | Promise<T[]> = cache.get(cacheKey);
|
||||
let resource: Entity | Entity[] | AssetPromise<T> | AssetPromise<T[]> = cache.get(cacheKey);
|
||||
|
||||
if (resource) {
|
||||
return resource;
|
||||
@@ -84,29 +89,32 @@ export class GLTFParserContext {
|
||||
resource =
|
||||
type === GLTFParserType.Entity
|
||||
? <Entity[]>glTFItems.map((_, index) => this.get<Entity>(type, index))
|
||||
: Promise.all<T>(glTFItems.map((_, index) => this.get<T>(type, index)));
|
||||
: AssetPromise.all<T>(glTFItems.map((_, index) => this.get<T>(type, index)));
|
||||
} else {
|
||||
resource = parser.parse(this, index);
|
||||
isSubAsset && this._handleSubAsset(resource, type, index);
|
||||
}
|
||||
} else {
|
||||
resource = Promise.resolve<T>(null);
|
||||
resource = AssetPromise.resolve<T>(null);
|
||||
}
|
||||
} else {
|
||||
resource = parser.parse(this, index);
|
||||
isSubAsset && this._handleSubAsset(resource, type, index);
|
||||
}
|
||||
|
||||
if (resource instanceof AssetPromise) {
|
||||
this._getPromises.push(resource);
|
||||
}
|
||||
cache.set(cacheKey, resource);
|
||||
return resource;
|
||||
}
|
||||
|
||||
parse(): Promise<GLTFResource> {
|
||||
parse(): AssetPromise<GLTFResource> {
|
||||
const promise = this.get<IGLTF>(GLTFParserType.Schema).then((json) => {
|
||||
this.glTF = json;
|
||||
this.needAnimatorController = !!(json.skins || json.animations);
|
||||
|
||||
return Promise.all([
|
||||
return AssetPromise.all([
|
||||
this.get<void>(GLTFParserType.Validator),
|
||||
this.get<Texture2D>(GLTFParserType.Texture),
|
||||
this.get<Material>(GLTFParserType.Material),
|
||||
@@ -147,7 +155,7 @@ export class GLTFParserContext {
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
_addTaskCompletePromise(taskPromise: Promise<any>): void {
|
||||
_addTaskCompletePromise(taskPromise: PromiseLike<any>): void {
|
||||
const task = this._progress.taskComplete;
|
||||
task.total += 1;
|
||||
taskPromise.then(
|
||||
@@ -159,7 +167,7 @@ export class GLTFParserContext {
|
||||
}
|
||||
|
||||
private _handleSubAsset<T>(
|
||||
resource: Entity | Entity[] | Promise<T> | Promise<T[]>,
|
||||
resource: Entity | Entity[] | AssetPromise<T> | AssetPromise<T[]>,
|
||||
type: GLTFParserType,
|
||||
index?: number
|
||||
): void {
|
||||
@@ -170,33 +178,37 @@ export class GLTFParserContext {
|
||||
} else {
|
||||
const url = this.glTFResource.url;
|
||||
|
||||
(<Promise<T>>resource).then((item: T) => {
|
||||
if (index == undefined) {
|
||||
this.glTFResource[glTFResourceKey] = item;
|
||||
} else {
|
||||
(this.glTFResource[glTFResourceKey] ||= [])[index] = item;
|
||||
}
|
||||
|
||||
if (type === GLTFParserType.Mesh) {
|
||||
for (let i = 0, length = (<ModelMesh[]>item).length; i < length; i++) {
|
||||
const mesh = item[i] as ModelMesh;
|
||||
// @ts-ignore
|
||||
this.resourceManager._onSubAssetSuccess<ModelMesh>(url, `${glTFResourceKey}[${index}][${i}]`, mesh);
|
||||
(<AssetPromise<T>>resource)
|
||||
.then((item: T) => {
|
||||
if (index == undefined) {
|
||||
this.glTFResource[glTFResourceKey] = item;
|
||||
} else {
|
||||
(this.glTFResource[glTFResourceKey] ||= [])[index] = item;
|
||||
}
|
||||
} else {
|
||||
// @ts-ignore
|
||||
this.resourceManager._onSubAssetSuccess<T>(
|
||||
url,
|
||||
`${glTFResourceKey}${index === undefined ? "" : `[${index}]`}`,
|
||||
item
|
||||
);
|
||||
|
||||
if (type === GLTFParserType.Scene && (this.glTF.scene ?? 0) === index) {
|
||||
if (type === GLTFParserType.Mesh) {
|
||||
for (let i = 0, length = (<ModelMesh[]>item).length; i < length; i++) {
|
||||
const mesh = item[i] as ModelMesh;
|
||||
// @ts-ignore
|
||||
this.resourceManager._onSubAssetSuccess<ModelMesh>(url, `${glTFResourceKey}[${index}][${i}]`, mesh);
|
||||
}
|
||||
} else {
|
||||
// @ts-ignore
|
||||
this.resourceManager._onSubAssetSuccess<Entity>(url, `defaultSceneRoot`, item as Entity);
|
||||
this.resourceManager._onSubAssetSuccess<T>(
|
||||
url,
|
||||
`${glTFResourceKey}${index === undefined ? "" : `[${index}]`}`,
|
||||
item
|
||||
);
|
||||
|
||||
if (type === GLTFParserType.Scene && (this.glTF.scene ?? 0) === index) {
|
||||
// @ts-ignore
|
||||
this.resourceManager._onSubAssetSuccess<Entity>(url, `defaultSceneRoot`, item as Entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
})
|
||||
.catch((e) => {
|
||||
Logger.error("GLTFParserContext", `Failed to load ${glTFResourceKey} ${index}: ${e}`);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import {
|
||||
AssetPromise,
|
||||
Camera,
|
||||
Entity,
|
||||
Logger,
|
||||
Material,
|
||||
Mesh,
|
||||
MeshRenderer,
|
||||
@@ -11,13 +13,12 @@ import {
|
||||
import { BoundingBox, Matrix } from "@galacean/engine-math";
|
||||
import { GLTFResource } from "../GLTFResource";
|
||||
import { CameraType, ICamera, INode } from "../GLTFSchema";
|
||||
import { GLTFMaterialParser } from "./GLTFMaterialParser";
|
||||
import { GLTFParser } from "./GLTFParser";
|
||||
import { GLTFParserContext, GLTFParserType, registerGLTFParser } from "./GLTFParserContext";
|
||||
|
||||
@registerGLTFParser(GLTFParserType.Scene)
|
||||
export class GLTFSceneParser extends GLTFParser {
|
||||
parse(context: GLTFParserContext, index: number): Promise<Entity> {
|
||||
parse(context: GLTFParserContext, index: number): AssetPromise<Entity> {
|
||||
const {
|
||||
glTF: { scenes, scene = 0 },
|
||||
glTFResource
|
||||
@@ -46,24 +47,24 @@ export class GLTFSceneParser extends GLTFParser {
|
||||
glTFResource._defaultSceneRoot = sceneRoot;
|
||||
}
|
||||
|
||||
const promises = new Array<Promise<void[]>>();
|
||||
const promises = new Array<AssetPromise<void[]>>();
|
||||
|
||||
for (let i = 0; i < sceneNodes.length; i++) {
|
||||
promises.push(this._parseEntityComponent(context, sceneNodes[i]));
|
||||
}
|
||||
|
||||
return Promise.all(promises).then(() => {
|
||||
return AssetPromise.all(promises).then(() => {
|
||||
GLTFParser.executeExtensionsAdditiveAndParse(sceneExtensions, context, sceneRoot, sceneInfo);
|
||||
return sceneRoot;
|
||||
});
|
||||
}
|
||||
|
||||
private _parseEntityComponent(context: GLTFParserContext, index: number): Promise<void[]> {
|
||||
private _parseEntityComponent(context: GLTFParserContext, index: number): AssetPromise<void[]> {
|
||||
const { glTF, glTFResource } = context;
|
||||
const entityInfo = glTF.nodes[index];
|
||||
const { camera: cameraID, mesh: meshID } = entityInfo;
|
||||
const entity = context.get<Entity>(GLTFParserType.Entity, index);
|
||||
let promise: Promise<void>;
|
||||
let promise: AssetPromise<void>;
|
||||
|
||||
if (cameraID !== undefined) {
|
||||
this._createCamera(glTFResource, glTF.cameras[cameraID], entity);
|
||||
@@ -73,7 +74,7 @@ export class GLTFSceneParser extends GLTFParser {
|
||||
promise = this._createRenderer(context, entityInfo, entity);
|
||||
}
|
||||
|
||||
return Promise.resolve(promise).then(() => {
|
||||
return AssetPromise.resolve(promise).then(() => {
|
||||
const promises = [];
|
||||
const children = entityInfo.children;
|
||||
|
||||
@@ -83,7 +84,7 @@ export class GLTFSceneParser extends GLTFParser {
|
||||
}
|
||||
}
|
||||
|
||||
return Promise.all(promises);
|
||||
return AssetPromise.all(promises);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -127,59 +128,65 @@ export class GLTFSceneParser extends GLTFParser {
|
||||
camera.enabled = false;
|
||||
}
|
||||
|
||||
private _createRenderer(context: GLTFParserContext, entityInfo: INode, entity: Entity): Promise<void> {
|
||||
private _createRenderer(context: GLTFParserContext, entityInfo: INode, entity: Entity): AssetPromise<void> {
|
||||
const { mesh: meshID, skin: skinID } = entityInfo;
|
||||
const glTFMesh = context.glTF.meshes[meshID];
|
||||
|
||||
const glTFMeshPrimitives = glTFMesh.primitives;
|
||||
const rendererCount = glTFMeshPrimitives.length;
|
||||
const blendShapeWeights = entityInfo.weights || glTFMesh.weights;
|
||||
const materialPromises = new Array<Promise<Material>>(rendererCount);
|
||||
const materialPromises = new Array<AssetPromise<Material>>(rendererCount);
|
||||
|
||||
for (let i = 0; i < rendererCount; i++) {
|
||||
materialPromises[i] = context.get<Material>(GLTFParserType.Material, glTFMeshPrimitives[i].material ?? -1);
|
||||
}
|
||||
|
||||
return Promise.all([
|
||||
return AssetPromise.all([
|
||||
context.get<ModelMesh[]>(GLTFParserType.Mesh, meshID),
|
||||
skinID !== undefined && context.get<Skin>(GLTFParserType.Skin, skinID),
|
||||
Promise.all(materialPromises)
|
||||
]).then(([meshes, skin, materials]) => {
|
||||
for (let i = 0; i < rendererCount; i++) {
|
||||
const material = materials[i] || GLTFMaterialParser._getDefaultMaterial(context.glTFResource.engine);
|
||||
const glTFPrimitive = glTFMeshPrimitives[i];
|
||||
const mesh = meshes[i];
|
||||
AssetPromise.all(materialPromises)
|
||||
])
|
||||
.then(([meshes, skin, materials]) => {
|
||||
// @ts-ignore
|
||||
const basicResources = context.glTFResource.engine._basicResources;
|
||||
for (let i = 0; i < rendererCount; i++) {
|
||||
const material = materials[i] || basicResources._getBlinnPhongMaterial();
|
||||
const glTFPrimitive = glTFMeshPrimitives[i];
|
||||
const mesh = meshes[i];
|
||||
|
||||
let renderer: MeshRenderer | SkinnedMeshRenderer;
|
||||
let renderer: MeshRenderer | SkinnedMeshRenderer;
|
||||
|
||||
if (skin || blendShapeWeights) {
|
||||
const skinRenderer = entity.addComponent(SkinnedMeshRenderer);
|
||||
skinRenderer.mesh = mesh;
|
||||
if (skin) {
|
||||
this._computeLocalBounds(skinRenderer, mesh, skin.bones, skin.rootBone, skin.inverseBindMatrices);
|
||||
skinRenderer.skin = skin;
|
||||
if (skin || blendShapeWeights) {
|
||||
const skinRenderer = entity.addComponent(SkinnedMeshRenderer);
|
||||
skinRenderer.mesh = mesh;
|
||||
if (skin) {
|
||||
this._computeLocalBounds(skinRenderer, mesh, skin.bones, skin.rootBone, skin.inverseBindMatrices);
|
||||
skinRenderer.skin = skin;
|
||||
}
|
||||
if (blendShapeWeights) {
|
||||
skinRenderer.blendShapeWeights = new Float32Array(blendShapeWeights);
|
||||
}
|
||||
renderer = skinRenderer;
|
||||
} else {
|
||||
renderer = entity.addComponent(MeshRenderer);
|
||||
renderer.mesh = mesh;
|
||||
}
|
||||
if (blendShapeWeights) {
|
||||
skinRenderer.blendShapeWeights = new Float32Array(blendShapeWeights);
|
||||
}
|
||||
renderer = skinRenderer;
|
||||
} else {
|
||||
renderer = entity.addComponent(MeshRenderer);
|
||||
renderer.mesh = mesh;
|
||||
|
||||
renderer.setMaterial(material);
|
||||
|
||||
// Enable vertex color if mesh has COLOR_0 vertex element
|
||||
mesh.vertexElements.forEach((element) => {
|
||||
if (element.semantic === "COLOR_0") {
|
||||
renderer.enableVertexColor = true;
|
||||
}
|
||||
});
|
||||
|
||||
GLTFParser.executeExtensionsAdditiveAndParse(glTFPrimitive.extensions, context, renderer, glTFPrimitive);
|
||||
}
|
||||
|
||||
renderer.setMaterial(material);
|
||||
|
||||
// Enable vertex color if mesh has COLOR_0 vertex element
|
||||
mesh.vertexElements.forEach((element) => {
|
||||
if (element.semantic === "COLOR_0") {
|
||||
renderer.enableVertexColor = true;
|
||||
}
|
||||
});
|
||||
|
||||
GLTFParser.executeExtensionsAdditiveAndParse(glTFPrimitive.extensions, context, renderer, glTFPrimitive);
|
||||
}
|
||||
});
|
||||
})
|
||||
.catch((e) => {
|
||||
Logger.error("GLTFSceneParser: create renderer error", e);
|
||||
});
|
||||
}
|
||||
|
||||
private _computeLocalBounds(
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Entity, Skin } from "@galacean/engine-core";
|
||||
import { AssetPromise, Entity, Skin } from "@galacean/engine-core";
|
||||
import { Matrix } from "@galacean/engine-math";
|
||||
import { GLTFUtils } from "../GLTFUtils";
|
||||
import { GLTFParser } from "./GLTFParser";
|
||||
@@ -6,7 +6,7 @@ import { GLTFParserContext, GLTFParserType, registerGLTFParser } from "./GLTFPar
|
||||
|
||||
@registerGLTFParser(GLTFParserType.Skin)
|
||||
export class GLTFSkinParser extends GLTFParser {
|
||||
parse(context: GLTFParserContext, index: number): Promise<Skin> {
|
||||
parse(context: GLTFParserContext, index: number): AssetPromise<Skin> {
|
||||
const glTF = context.glTF;
|
||||
const skinInfo = glTF.skins[index];
|
||||
const { inverseBindMatrices, skeleton, joints, name = `SKIN_${index}` } = skinInfo;
|
||||
@@ -50,7 +50,7 @@ export class GLTFSkinParser extends GLTFParser {
|
||||
return skin;
|
||||
});
|
||||
|
||||
return Promise.resolve(skinPromise);
|
||||
return AssetPromise.resolve(skinPromise);
|
||||
}
|
||||
|
||||
private _findSkeletonRootBone(joints: number[], entities: Entity[]): Entity {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { AssetType, Texture, Texture2D, TextureWrapMode, Utils } from "@galacean/engine-core";
|
||||
import { AssetPromise, AssetType, Logger, Texture, Texture2D, TextureWrapMode, Utils } from "@galacean/engine-core";
|
||||
import { BufferTextureRestoreInfo } from "../../GLTFContentRestorer";
|
||||
import { TextureWrapMode as GLTFTextureWrapMode, IMaterial } from "../GLTFSchema";
|
||||
import { GLTFUtils } from "../GLTFUtils";
|
||||
@@ -22,14 +22,14 @@ export class GLTFTextureParser extends GLTFParser {
|
||||
sampler?: number,
|
||||
textureName?: string,
|
||||
isSRGBColorSpace?: boolean
|
||||
): Promise<Texture2D> {
|
||||
): AssetPromise<Texture2D> {
|
||||
const { glTFResource, glTF } = context;
|
||||
const { engine, url } = glTFResource;
|
||||
const { uri, bufferView: bufferViewIndex, mimeType, name: imageName } = glTF.images[imageIndex];
|
||||
|
||||
const useSampler = sampler !== undefined;
|
||||
const samplerInfo = useSampler && GLTFUtils.getSamplerInfo(glTF.samplers[sampler]);
|
||||
let texture: Promise<Texture2D>;
|
||||
let texture: AssetPromise<Texture2D>;
|
||||
|
||||
if (uri) {
|
||||
const extIndex = uri.lastIndexOf(".");
|
||||
@@ -54,44 +54,47 @@ export class GLTFTextureParser extends GLTFParser {
|
||||
context._addTaskCompletePromise(texture);
|
||||
} else {
|
||||
const bufferView = glTF.bufferViews[bufferViewIndex];
|
||||
texture = context
|
||||
.get<ArrayBuffer>(GLTFParserType.Buffer)
|
||||
.then((buffers) => {
|
||||
const buffer = buffers[bufferView.buffer];
|
||||
const imageBuffer = new Uint8Array(buffer, bufferView.byteOffset, bufferView.byteLength);
|
||||
return GLTFUtils.loadImageBuffer(imageBuffer, mimeType).then((image) => {
|
||||
const texture = new Texture2D(
|
||||
engine,
|
||||
image.width,
|
||||
image.height,
|
||||
undefined,
|
||||
samplerInfo?.mipmap,
|
||||
isSRGBColorSpace
|
||||
);
|
||||
texture.setImageSource(image);
|
||||
texture.generateMipmaps();
|
||||
|
||||
texture = context.get<ArrayBuffer>(GLTFParserType.Buffer).then((buffers) => {
|
||||
const buffer = buffers[bufferView.buffer];
|
||||
const imageBuffer = new Uint8Array(buffer, bufferView.byteOffset, bufferView.byteLength);
|
||||
texture.name = textureName || imageName || `texture_${textureIndex}`;
|
||||
useSampler && GLTFUtils.parseSampler(texture, samplerInfo);
|
||||
|
||||
return GLTFUtils.loadImageBuffer(imageBuffer, mimeType).then((image) => {
|
||||
const texture = new Texture2D(
|
||||
engine,
|
||||
image.width,
|
||||
image.height,
|
||||
undefined,
|
||||
samplerInfo?.mipmap,
|
||||
isSRGBColorSpace
|
||||
);
|
||||
texture.setImageSource(image);
|
||||
texture.generateMipmaps();
|
||||
const bufferTextureRestoreInfo = new BufferTextureRestoreInfo(texture, bufferView, mimeType);
|
||||
context.contentRestorer.bufferTextures.push(bufferTextureRestoreInfo);
|
||||
|
||||
texture.name = textureName || imageName || `texture_${textureIndex}`;
|
||||
useSampler && GLTFUtils.parseSampler(texture, samplerInfo);
|
||||
|
||||
const bufferTextureRestoreInfo = new BufferTextureRestoreInfo(texture, bufferView, mimeType);
|
||||
context.contentRestorer.bufferTextures.push(bufferTextureRestoreInfo);
|
||||
|
||||
return texture;
|
||||
return texture;
|
||||
});
|
||||
})
|
||||
.catch((e) => {
|
||||
Logger.error("GLTFTextureParser: image buffer error", e);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
return texture;
|
||||
}
|
||||
|
||||
parse(context: GLTFParserContext, textureIndex: number): Promise<Texture> {
|
||||
parse(context: GLTFParserContext, textureIndex: number): AssetPromise<Texture> {
|
||||
const textureInfo = context.glTF.textures[textureIndex];
|
||||
const glTFResource = context.glTFResource;
|
||||
const { sampler, source: imageIndex = 0, name: textureName, extensions } = textureInfo;
|
||||
const isSRGBColorSpace = this._isSRGBColorSpace(textureIndex, context.glTF.materials);
|
||||
|
||||
let texture = <Texture | Promise<Texture>>(
|
||||
let texture = <Texture | AssetPromise<Texture>>(
|
||||
GLTFParser.executeExtensionsCreateAndParse(extensions, context, textureInfo, textureIndex, isSRGBColorSpace)
|
||||
);
|
||||
|
||||
@@ -106,7 +109,7 @@ export class GLTFTextureParser extends GLTFParser {
|
||||
);
|
||||
}
|
||||
|
||||
return Promise.resolve(texture).then((texture) => {
|
||||
return AssetPromise.resolve(texture).then((texture) => {
|
||||
GLTFParser.executeExtensionsAdditiveAndParse(extensions, context, texture, textureInfo);
|
||||
// @ts-ignore
|
||||
texture._associationSuperResource(glTFResource);
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { Logger } from "@galacean/engine-core";
|
||||
import { AssetPromise, Logger } from "@galacean/engine-core";
|
||||
import { GLTFParser } from "./GLTFParser";
|
||||
import { GLTFParserContext, GLTFParserType, registerGLTFParser } from "./GLTFParserContext";
|
||||
|
||||
@registerGLTFParser(GLTFParserType.Validator)
|
||||
export class GLTFValidator extends GLTFParser {
|
||||
parse(context: GLTFParserContext): Promise<void> {
|
||||
parse(context: GLTFParserContext): AssetPromise<void> {
|
||||
const {
|
||||
asset: { version },
|
||||
extensionsUsed,
|
||||
@@ -37,6 +37,6 @@ export class GLTFValidator extends GLTFParser {
|
||||
}
|
||||
}
|
||||
|
||||
return Promise.resolve(null);
|
||||
return AssetPromise.resolve(null);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Engine } from "@galacean/engine-core";
|
||||
import { AssetPromise, Engine } from "@galacean/engine-core";
|
||||
import { BufferReader } from "./utils/BufferReader";
|
||||
import { decoderMap } from "./utils/Decorator";
|
||||
import { FileHeader } from "./utils/FileHeader";
|
||||
@@ -15,7 +15,7 @@ export type { IModelMesh } from "./resources/mesh/IModelMesh";
|
||||
* @param engine - engine
|
||||
* @returns
|
||||
*/
|
||||
export function decode<T>(arrayBuffer: ArrayBuffer, engine: Engine): Promise<T> {
|
||||
export function decode<T>(arrayBuffer: ArrayBuffer, engine: Engine): AssetPromise<T> {
|
||||
const header = FileHeader.decode(arrayBuffer);
|
||||
const bufferReader = new BufferReader(new Uint8Array(arrayBuffer), header.headerLength, header.dataLength);
|
||||
return decoderMap[header.type].decode(engine, bufferReader).then((object) => {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import {
|
||||
AnimationArrayCurve,
|
||||
AnimationBoolCurve,
|
||||
AnimationClip,
|
||||
AnimationColorCurve,
|
||||
AnimationCurve,
|
||||
@@ -7,17 +8,17 @@ import {
|
||||
AnimationFloatArrayCurve,
|
||||
AnimationFloatCurve,
|
||||
AnimationQuaternionCurve,
|
||||
AnimationRefCurve,
|
||||
AnimationStringCurve,
|
||||
AnimationVector2Curve,
|
||||
AnimationVector3Curve,
|
||||
AnimationVector4Curve,
|
||||
AnimationRefCurve,
|
||||
AssetPromise,
|
||||
Engine,
|
||||
Keyframe,
|
||||
KeyframeValueType,
|
||||
ReferResource,
|
||||
AnimationStringCurve,
|
||||
AnimationBoolCurve,
|
||||
Loader
|
||||
Loader,
|
||||
ReferResource
|
||||
} from "@galacean/engine-core";
|
||||
import { Color, Quaternion, Vector2, Vector3, Vector4 } from "@galacean/engine-math";
|
||||
import type { BufferReader } from "../../utils/BufferReader";
|
||||
@@ -39,8 +40,8 @@ export enum InterpolableValueType {
|
||||
|
||||
@decoder("AnimationClip")
|
||||
export class AnimationClipDecoder {
|
||||
public static decode(engine: Engine, bufferReader: BufferReader): Promise<AnimationClip> {
|
||||
return new Promise((resolve) => {
|
||||
public static decode(engine: Engine, bufferReader: BufferReader): AssetPromise<AnimationClip> {
|
||||
return new AssetPromise((resolve) => {
|
||||
const name = bufferReader.nextStr();
|
||||
const clip = new AnimationClip(name);
|
||||
const eventsLen = bufferReader.nextUint16();
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { Engine } from "@galacean/engine-core";
|
||||
import { AssetPromise, Engine } from "@galacean/engine-core";
|
||||
import { BlendShape, ModelMesh } from "@galacean/engine-core";
|
||||
import { Color, Vector2, Vector3, Vector4 } from "@galacean/engine-math";
|
||||
import type { BufferReader } from "../../utils/BufferReader";
|
||||
@@ -10,8 +10,8 @@ import type { IEncodedModelMesh } from "./IModelMesh";
|
||||
*/
|
||||
@decoder("Mesh")
|
||||
export class MeshDecoder {
|
||||
public static decode(engine: Engine, bufferReader: BufferReader): Promise<ModelMesh> {
|
||||
return new Promise((resolve) => {
|
||||
public static decode(engine: Engine, bufferReader: BufferReader): AssetPromise<ModelMesh> {
|
||||
return new AssetPromise((resolve) => {
|
||||
const modelMesh = new ModelMesh(engine);
|
||||
const jsonDataString = bufferReader.nextStr();
|
||||
const encodedMeshData: IEncodedModelMesh = JSON.parse(jsonDataString);
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import { Engine, Texture2D } from "@galacean/engine-core";
|
||||
import { AssetPromise, Engine, Texture2D } from "@galacean/engine-core";
|
||||
import { BufferReader } from "../../utils/BufferReader";
|
||||
import { decoder } from "../../utils/Decorator";
|
||||
|
||||
@decoder("Texture2D")
|
||||
export class Texture2DDecoder {
|
||||
static decode(engine: Engine, bufferReader: BufferReader): Promise<Texture2D> {
|
||||
return new Promise((resolve, reject) => {
|
||||
static decode(engine: Engine, bufferReader: BufferReader): AssetPromise<Texture2D> {
|
||||
return new AssetPromise((resolve, reject) => {
|
||||
const objectId = bufferReader.nextStr();
|
||||
const mipmap = !!bufferReader.nextUint8();
|
||||
const filterMode = bufferReader.nextUint8();
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { Engine } from "@galacean/engine-core";
|
||||
import { AssetPromise, Engine } from "@galacean/engine-core";
|
||||
import type { BufferReader } from "./BufferReader";
|
||||
|
||||
export const decoderMap: Record<
|
||||
string,
|
||||
{
|
||||
decode: (engine: Engine, bufferReader: BufferReader) => Promise<any>;
|
||||
decode: (engine: Engine, bufferReader: BufferReader) => AssetPromise<any>;
|
||||
}
|
||||
> = {};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user