Skip to content

Commit

Permalink
Add Animator compoment for skinned glTF modle, even no amimation cl…
Browse files Browse the repository at this point in the history
…ips (#1107)

* feat: add Animator compoment for skin mode
  • Loading branch information
GuoLei1990 authored Oct 17, 2022
1 parent b1f0bd3 commit e3e5b71
Show file tree
Hide file tree
Showing 14 changed files with 106 additions and 78 deletions.
10 changes: 6 additions & 4 deletions packages/loader/src/GLTFLoader.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
import { AssetPromise, AssetType, Loader, LoadItem, resourceLoader, ResourceManager } from "@oasis-engine/core";
import { GLTFParser } from "./gltf/GLTFParser";
import { GLTFResource } from "./gltf/GLTFResource";
import { ParserContext } from "./gltf/parser/ParserContext";

@resourceLoader(AssetType.Prefab, ["gltf", "glb"])
export class GLTFLoader extends Loader<GLTFResource> {
load(item: LoadItem, resourceManager: ResourceManager): AssetPromise<GLTFResource> {
const url = item.url;
return new AssetPromise((resolve, reject) => {
const resource = new GLTFResource(resourceManager.engine);
resource.url = url;
resource._keepMeshData = item.params?.keepMeshData ?? false;
const context = new ParserContext();
context.glTFResource = new GLTFResource(resourceManager.engine);
context.glTFResource.url = url;
context.keepMeshData = item.params?.keepMeshData ?? false;

GLTFParser.instance
.parse(resource)
.parse(context)
.then(resolve)
.catch((e) => {
console.error(e);
Expand Down
8 changes: 5 additions & 3 deletions packages/loader/src/gltf/GLTFParser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { EntityParser } from "./parser/EntityParser";
import { MaterialParser } from "./parser/MaterialParser";
import { MeshParser } from "./parser/MeshParser";
import { Parser } from "./parser/Parser";
import { ParserContext } from "./parser/ParserContext";
import { SceneParser } from "./parser/SceneParser";
import { SkinParser } from "./parser/SkinParser";
import { TextureParser } from "./parser/TextureParser";
Expand All @@ -31,7 +32,8 @@ export class GLTFParser {
});
}

parse(context: GLTFResource): Promise<GLTFResource> {
parse(context: ParserContext): Promise<GLTFResource> {
const glTFResource = context.glTFResource;
let lastPipe: void | Promise<void>;

return new Promise((resolve, reject) => {
Expand All @@ -48,11 +50,11 @@ export class GLTFParser {
if (lastPipe) {
lastPipe
.then(() => {
resolve(context);
resolve(glTFResource);
})
.catch(reject);
} else {
resolve(context);
resolve(glTFResource);
}
});
}
Expand Down
3 changes: 1 addition & 2 deletions packages/loader/src/gltf/GLTFResource.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,5 @@ export class GLTFResource extends EngineObject {
defaultSceneRoot: Entity;
/** Renderer can replace material by `renderer.setMaterial` if gltf use plugin-in KHR_materials_variants. */
variants?: { renderer: Renderer; material: Material; variants: string[] }[];
/** @internal */
_keepMeshData?: boolean;

}
11 changes: 5 additions & 6 deletions packages/loader/src/gltf/parser/AnimationParser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,15 @@ import {
TypedArray
} from "@oasis-engine/core";
import { Quaternion, Vector3, Vector4 } from "@oasis-engine/math";
import { GLTFResource } from "../GLTFResource";
import { GLTFUtil } from "../GLTFUtil";
import { AccessorType, AnimationChannelTargetPath, AnimationSamplerInterpolation, IAnimationChannel } from "../Schema";
import { Parser } from "./Parser";
import { ParserContext } from "./ParserContext";

export class AnimationParser extends Parser {
parse(context: GLTFResource): void {
const { gltf, buffers, entities } = context;
parse(context: ParserContext): void {
const glTFResource = context.glTFResource;
const { gltf, buffers, entities } = glTFResource;
const { animations, accessors } = gltf;
if (!animations) {
return;
Expand Down Expand Up @@ -120,9 +121,7 @@ export class AnimationParser extends Parser {
index: i
};
}
context.animations = animationClips;
// @ts-ignore for editor
context._animationsIndices = animationsIndices;
glTFResource.animations = animationClips;
}

private _addCurve(
Expand Down
17 changes: 9 additions & 8 deletions packages/loader/src/gltf/parser/BufferParser.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import { AssetType } from "@oasis-engine/core";
import { GLTFResource } from "../GLTFResource";
import { IBuffer, IGLTF } from "../Schema";
import { GLTFUtil } from "../GLTFUtil";
import { IBuffer, IGLTF } from "../Schema";
import { Parser } from "./Parser";
import { ParserContext } from "./ParserContext";

export class BufferParser extends Parser {
parse(context: GLTFResource): Promise<void> {
const { url, engine } = context;
parse(context: ParserContext): Promise<void> {
const glTFResource = context.glTFResource;
const { url, engine } = glTFResource;

if (this._isGLB(url)) {
return engine.resourceManager
Expand All @@ -16,8 +17,8 @@ export class BufferParser extends Parser {
})
.then(GLTFUtil.parseGLB)
.then(({ gltf, buffers }) => {
context.gltf = gltf;
context.buffers = buffers;
glTFResource.gltf = gltf;
glTFResource.buffers = buffers;
});
} else {
return engine.resourceManager
Expand All @@ -26,7 +27,7 @@ export class BufferParser extends Parser {
type: AssetType.JSON
})
.then((gltf: IGLTF) => {
context.gltf = gltf;
glTFResource.gltf = gltf;
return Promise.all(
gltf.buffers.map((buffer: IBuffer) => {
return engine.resourceManager.load<ArrayBuffer>({
Expand All @@ -35,7 +36,7 @@ export class BufferParser extends Parser {
});
})
).then((buffers: ArrayBuffer[]) => {
context.buffers = buffers;
glTFResource.buffers = buffers;
});
});
}
Expand Down
14 changes: 9 additions & 5 deletions packages/loader/src/gltf/parser/EntityParser.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
import { Entity } from "@oasis-engine/core";
import { GLTFResource } from "../GLTFResource";
import { Parser } from "./Parser";
import { ParserContext } from "./ParserContext";

export class EntityParser extends Parser {
/** @internal */
static _defaultName: String = "_GLTF_ENTITY_";

parse(context: GLTFResource): void {
parse(context: ParserContext): void {
const glTFResource = context.glTFResource;

const {
engine,
gltf: { nodes }
} = context;
} = glTFResource;

if (!nodes) return;

const entities: Entity[] = [];
Expand Down Expand Up @@ -40,9 +44,9 @@ export class EntityParser extends Parser {
entities[i] = entity;
}

context.entities = entities;
this._buildEntityTree(context);
this._createSceneRoots(context);
glTFResource.entities = entities;
this._buildEntityTree(glTFResource);
this._createSceneRoots(glTFResource);
}

private _buildEntityTree(context: GLTFResource): void {
Expand Down
25 changes: 14 additions & 11 deletions packages/loader/src/gltf/parser/MaterialParser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { Color } from "@oasis-engine/math";
import { GLTFResource } from "../GLTFResource";
import { MaterialAlphaMode } from "../Schema";
import { Parser } from "./Parser";
import { ParserContext } from "./ParserContext";

export class MaterialParser extends Parser {
/** @internal */
Expand All @@ -21,8 +22,10 @@ export class MaterialParser extends Parser {
}
}

parse(context: GLTFResource): void {
const { gltf, engine, textures } = context;
parse(context: ParserContext): void {
const glTFResource = context.glTFResource;

const { gltf, engine, textures } = glTFResource;
if (!gltf.materials) return;

const materials: Material[] = [];
Expand All @@ -46,13 +49,13 @@ export class MaterialParser extends Parser {
let material: UnlitMaterial | PBRMaterial | PBRSpecularMaterial = null;

if (KHR_materials_unlit) {
material = <UnlitMaterial>Parser.createEngineResource("KHR_materials_unlit", KHR_materials_unlit, context);
material = <UnlitMaterial>Parser.createEngineResource("KHR_materials_unlit", KHR_materials_unlit, glTFResource);
} else if (KHR_materials_pbrSpecularGlossiness) {
material = <PBRSpecularMaterial>(
Parser.createEngineResource(
"KHR_materials_pbrSpecularGlossiness",
KHR_materials_pbrSpecularGlossiness,
context
glTFResource
)
);
} else {
Expand All @@ -62,7 +65,7 @@ export class MaterialParser extends Parser {
material.name = name;

if (KHR_materials_clearcoat) {
Parser.parseEngineResource("KHR_materials_clearcoat", KHR_materials_clearcoat, material, context);
Parser.parseEngineResource("KHR_materials_clearcoat", KHR_materials_clearcoat, material, glTFResource);
}

if (pbrMetallicRoughness) {
Expand All @@ -79,7 +82,7 @@ export class MaterialParser extends Parser {
}
if (baseColorTexture) {
material.baseTexture = textures[baseColorTexture.index];
MaterialParser._parseTextureTransform(material, baseColorTexture.extensions, context);
MaterialParser._parseTextureTransform(material, baseColorTexture.extensions, glTFResource);
}

if (!KHR_materials_unlit && !KHR_materials_pbrSpecularGlossiness) {
Expand All @@ -88,7 +91,7 @@ export class MaterialParser extends Parser {
m.roughness = roughnessFactor ?? 1;
if (metallicRoughnessTexture) {
m.roughnessMetallicTexture = textures[metallicRoughnessTexture.index];
MaterialParser._parseTextureTransform(material, metallicRoughnessTexture.extensions, context);
MaterialParser._parseTextureTransform(material, metallicRoughnessTexture.extensions, glTFResource);
}
}
}
Expand All @@ -98,7 +101,7 @@ export class MaterialParser extends Parser {

if (emissiveTexture) {
m.emissiveTexture = textures[emissiveTexture.index];
MaterialParser._parseTextureTransform(material, emissiveTexture.extensions, context);
MaterialParser._parseTextureTransform(material, emissiveTexture.extensions, glTFResource);
}

if (emissiveFactor) {
Expand All @@ -112,7 +115,7 @@ export class MaterialParser extends Parser {
if (normalTexture) {
const { index, scale } = normalTexture;
m.normalTexture = textures[index];
MaterialParser._parseTextureTransform(material, normalTexture.extensions, context);
MaterialParser._parseTextureTransform(material, normalTexture.extensions, glTFResource);
if (scale !== undefined) {
m.normalTextureIntensity = scale;
}
Expand All @@ -121,7 +124,7 @@ export class MaterialParser extends Parser {
if (occlusionTexture) {
const { index, strength, texCoord } = occlusionTexture;
m.occlusionTexture = textures[index];
MaterialParser._parseTextureTransform(material, occlusionTexture.extensions, context);
MaterialParser._parseTextureTransform(material, occlusionTexture.extensions, glTFResource);
if (strength !== undefined) {
m.occlusionTextureIntensity = strength;
}
Expand Down Expand Up @@ -154,6 +157,6 @@ export class MaterialParser extends Parser {
materials[i] = material;
}

context.materials = materials;
glTFResource.materials = materials;
}
}
25 changes: 11 additions & 14 deletions packages/loader/src/gltf/parser/MeshParser.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,18 @@
import { BlendShape, Engine, EngineObject, ModelMesh, TypedArray } from "@oasis-engine/core";
import { BlendShape, EngineObject, ModelMesh, TypedArray } from "@oasis-engine/core";
import { Vector3 } from "@oasis-engine/math";
import { GLTFResource } from "../GLTFResource";
import { GLTFUtil } from "../GLTFUtil";
import { AccessorType, IGLTF, IMesh, IMeshPrimitive } from "../Schema";
import { Parser } from "./Parser";
import { ParserContext } from "./ParserContext";

export class MeshParser extends Parser {
private static _tempVector3 = new Vector3();

private _keepMeshData: boolean = false;

parse(context: GLTFResource): Promise<void> {
const { engine, gltf, buffers, _keepMeshData } = context;
parse(context: ParserContext): Promise<void> {
const glTFResource = context.glTFResource;
const { engine, gltf, buffers } = glTFResource;
if (!gltf.meshes) return;

this._keepMeshData = _keepMeshData;

const meshPromises: Promise<ModelMesh[]>[] = [];

for (let i = 0; i < gltf.meshes.length; i++) {
Expand All @@ -36,7 +33,7 @@ export class MeshParser extends Parser {
Parser.createEngineResource(
"KHR_draco_mesh_compression",
KHR_draco_mesh_compression,
context,
glTFResource,
gltfPrimitive
)
))
Expand All @@ -60,7 +57,7 @@ export class MeshParser extends Parser {
() => {
return decodedGeometry.index.array;
},
engine
context.keepMeshData
);
})
.then(resolve);
Expand Down Expand Up @@ -89,7 +86,7 @@ export class MeshParser extends Parser {
const indexAccessor = gltf.accessors[gltfPrimitive.indices];
return GLTFUtil.getAccessorData(gltf, indexAccessor, buffers);
},
engine
context.keepMeshData
).then(resolve);
}
})
Expand All @@ -100,7 +97,7 @@ export class MeshParser extends Parser {
}

return Promise.all(meshPromises).then((meshes: ModelMesh[][]) => {
context.meshes = meshes;
glTFResource.meshes = meshes;
});
}

Expand All @@ -112,7 +109,7 @@ export class MeshParser extends Parser {
getVertexBufferData: (semantic: string) => TypedArray,
getBlendShapeData: (semantic: string, shapeIndex: number) => TypedArray,
getIndexBufferData: () => TypedArray,
engine: Engine
keepMeshData: boolean
): Promise<ModelMesh> {
const { attributes, targets, indices, mode } = gltfPrimitive;
let vertexCount: number;
Expand Down Expand Up @@ -225,7 +222,7 @@ export class MeshParser extends Parser {
// BlendShapes
targets && this._createBlendShape(mesh, gltfMesh, targets, getBlendShapeData);

mesh.uploadData(!this._keepMeshData);
mesh.uploadData(!keepMeshData);
return Promise.resolve(mesh);
}

Expand Down
3 changes: 2 additions & 1 deletion packages/loader/src/gltf/parser/Parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { EngineObject } from "@oasis-engine/core";
import { ExtensionParser } from "../extensions/ExtensionParser";
import { ExtensionSchema } from "../extensions/Schema";
import { GLTFResource } from "../GLTFResource";
import { ParserContext } from "./ParserContext";

export abstract class Parser {
private static _extensionParsers: Record<string, ExtensionParser[]> = {};
Expand Down Expand Up @@ -60,7 +61,7 @@ export abstract class Parser {
Parser._extensionParsers[extensionName].push(extensionParser);
}

abstract parse(context: GLTFResource): void | Promise<void>;
abstract parse(context: ParserContext): void | Promise<void>;
}

/**
Expand Down
10 changes: 10 additions & 0 deletions packages/loader/src/gltf/parser/ParserContext.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { GLTFResource } from "../GLTFResource";

/**
* @internal
*/
export class ParserContext {
glTFResource: GLTFResource;
keepMeshData: boolean;
createAnimator: boolean;
}
Loading

0 comments on commit e3e5b71

Please sign in to comment.