From 600e43de246bdf9388d5a4f82cb2f28618be621a Mon Sep 17 00:00:00 2001 From: Mario Zechner Date: Mon, 4 Sep 2023 10:56:28 +0200 Subject: [PATCH] Formatting --- spine-ts/spine-phaser/src/SpineGameObject.ts | 595 +++++++++---------- spine-ts/spine-phaser/src/SpinePlugin.ts | 2 +- spine-ts/spine-threejs/src/SkeletonMesh.ts | 484 +++++++-------- spine-ts/spine-webgl/src/SkeletonRenderer.ts | 2 +- 4 files changed, 541 insertions(+), 542 deletions(-) diff --git a/spine-ts/spine-phaser/src/SpineGameObject.ts b/spine-ts/spine-phaser/src/SpineGameObject.ts index cadfdbaff..96f70ab80 100644 --- a/spine-ts/spine-phaser/src/SpineGameObject.ts +++ b/spine-ts/spine-phaser/src/SpineGameObject.ts @@ -30,137 +30,136 @@ import { SPINE_GAME_OBJECT_TYPE } from "./keys"; import { SpinePlugin } from "./SpinePlugin"; import { - ComputedSizeMixin, - DepthMixin, - FlipMixin, - ScrollFactorMixin, - TransformMixin, - VisibleMixin, - AlphaMixin, - OriginMixin, + ComputedSizeMixin, + DepthMixin, + FlipMixin, + ScrollFactorMixin, + TransformMixin, + VisibleMixin, + AlphaMixin, + OriginMixin, } from "./mixins"; import { - AnimationState, - AnimationStateData, - Bone, - MathUtils, - Skeleton, - Skin, - Vector2, + AnimationState, + AnimationStateData, + Bone, + MathUtils, + Skeleton, + Skin, + Vector2, } from "@esotericsoftware/spine-core"; class BaseSpineGameObject extends Phaser.GameObjects.GameObject { - constructor(scene: Phaser.Scene, type: string) { - super(scene, type); - } + constructor (scene: Phaser.Scene, type: string) { + super(scene, type); + } } /** A bounds provider calculates the bounding box for a skeleton, which is then assigned as the size of the SpineGameObject. */ export interface SpineGameObjectBoundsProvider { - // Returns the bounding box for the skeleton, in skeleton space. - calculateBounds(gameObject: SpineGameObject): { - x: number; - y: number; - width: number; - height: number; - }; + // Returns the bounding box for the skeleton, in skeleton space. + calculateBounds (gameObject: SpineGameObject): { + x: number; + y: number; + width: number; + height: number; + }; } /** A bounds provider that calculates the bounding box from the setup pose. */ export class SetupPoseBoundsProvider implements SpineGameObjectBoundsProvider { - calculateBounds(gameObject: SpineGameObject) { - if (!gameObject.skeleton) return { x: 0, y: 0, width: 0, height: 0 }; - // Make a copy of animation state and skeleton as this might be called while - // the skeleton in the GameObject has already been heavily modified. We can not - // reconstruct that state. - const skeleton = new Skeleton(gameObject.skeleton.data); - skeleton.setToSetupPose(); - skeleton.updateWorldTransform(); - const bounds = skeleton.getBoundsRect(); - return bounds.width == Number.NEGATIVE_INFINITY - ? { x: 0, y: 0, width: 0, height: 0 } - : bounds; - } + calculateBounds (gameObject: SpineGameObject) { + if (!gameObject.skeleton) return { x: 0, y: 0, width: 0, height: 0 }; + // Make a copy of animation state and skeleton as this might be called while + // the skeleton in the GameObject has already been heavily modified. We can not + // reconstruct that state. + const skeleton = new Skeleton(gameObject.skeleton.data); + skeleton.setToSetupPose(); + skeleton.updateWorldTransform(); + const bounds = skeleton.getBoundsRect(); + return bounds.width == Number.NEGATIVE_INFINITY + ? { x: 0, y: 0, width: 0, height: 0 } + : bounds; + } } /** A bounds provider that calculates the bounding box by taking the maximumg bounding box for a combination of skins and specific animation. */ export class SkinsAndAnimationBoundsProvider - implements SpineGameObjectBoundsProvider -{ - /** - * @param animation The animation to use for calculating the bounds. If null, the setup pose is used. - * @param skins The skins to use for calculating the bounds. If empty, the default skin is used. - * @param timeStep The time step to use for calculating the bounds. A smaller time step means more precision, but slower calculation. - */ - constructor( - private animation: string | null, - private skins: string[] = [], - private timeStep: number = 0.05 - ) {} + implements SpineGameObjectBoundsProvider { + /** + * @param animation The animation to use for calculating the bounds. If null, the setup pose is used. + * @param skins The skins to use for calculating the bounds. If empty, the default skin is used. + * @param timeStep The time step to use for calculating the bounds. A smaller time step means more precision, but slower calculation. + */ + constructor ( + private animation: string | null, + private skins: string[] = [], + private timeStep: number = 0.05 + ) { } - calculateBounds(gameObject: SpineGameObject): { - x: number; - y: number; - width: number; - height: number; - } { - if (!gameObject.skeleton || !gameObject.animationState) - return { x: 0, y: 0, width: 0, height: 0 }; - // Make a copy of animation state and skeleton as this might be called while - // the skeleton in the GameObject has already been heavily modified. We can not - // reconstruct that state. - const animationState = new AnimationState(gameObject.animationState.data); - const skeleton = new Skeleton(gameObject.skeleton.data); - const data = skeleton.data; - if (this.skins.length > 0) { - let customSkin = new Skin("custom-skin"); - for (const skinName of this.skins) { - const skin = data.findSkin(skinName); - if (skin == null) continue; - customSkin.addSkin(skin); - } - skeleton.setSkin(customSkin); - } - skeleton.setToSetupPose(); + calculateBounds (gameObject: SpineGameObject): { + x: number; + y: number; + width: number; + height: number; + } { + if (!gameObject.skeleton || !gameObject.animationState) + return { x: 0, y: 0, width: 0, height: 0 }; + // Make a copy of animation state and skeleton as this might be called while + // the skeleton in the GameObject has already been heavily modified. We can not + // reconstruct that state. + const animationState = new AnimationState(gameObject.animationState.data); + const skeleton = new Skeleton(gameObject.skeleton.data); + const data = skeleton.data; + if (this.skins.length > 0) { + let customSkin = new Skin("custom-skin"); + for (const skinName of this.skins) { + const skin = data.findSkin(skinName); + if (skin == null) continue; + customSkin.addSkin(skin); + } + skeleton.setSkin(customSkin); + } + skeleton.setToSetupPose(); - const animation = - this.animation != null ? data.findAnimation(this.animation!) : null; - if (animation == null) { - skeleton.updateWorldTransform(); - const bounds = skeleton.getBoundsRect(); - return bounds.width == Number.NEGATIVE_INFINITY - ? { x: 0, y: 0, width: 0, height: 0 } - : bounds; - } else { - let minX = Number.POSITIVE_INFINITY, - minY = Number.POSITIVE_INFINITY, - maxX = Number.NEGATIVE_INFINITY, - maxY = Number.NEGATIVE_INFINITY; - animationState.clearTracks(); - animationState.setAnimationWith(0, animation, false); - const steps = Math.max(animation.duration / this.timeStep, 1.0); - for (let i = 0; i < steps; i++) { - animationState.update(i > 0 ? this.timeStep : 0); - animationState.apply(skeleton); - skeleton.updateWorldTransform(); + const animation = + this.animation != null ? data.findAnimation(this.animation!) : null; + if (animation == null) { + skeleton.updateWorldTransform(); + const bounds = skeleton.getBoundsRect(); + return bounds.width == Number.NEGATIVE_INFINITY + ? { x: 0, y: 0, width: 0, height: 0 } + : bounds; + } else { + let minX = Number.POSITIVE_INFINITY, + minY = Number.POSITIVE_INFINITY, + maxX = Number.NEGATIVE_INFINITY, + maxY = Number.NEGATIVE_INFINITY; + animationState.clearTracks(); + animationState.setAnimationWith(0, animation, false); + const steps = Math.max(animation.duration / this.timeStep, 1.0); + for (let i = 0; i < steps; i++) { + animationState.update(i > 0 ? this.timeStep : 0); + animationState.apply(skeleton); + skeleton.updateWorldTransform(); - const bounds = skeleton.getBoundsRect(); - minX = Math.min(minX, bounds.x); - minY = Math.min(minY, bounds.y); - maxX = Math.max(maxX, minX + bounds.width); - maxY = Math.max(maxY, minY + bounds.height); - } - const bounds = { - x: minX, - y: minY, - width: maxX - minX, - height: maxY - minY, - }; - return bounds.width == Number.NEGATIVE_INFINITY - ? { x: 0, y: 0, width: 0, height: 0 } - : bounds; - } - } + const bounds = skeleton.getBoundsRect(); + minX = Math.min(minX, bounds.x); + minY = Math.min(minY, bounds.y); + maxX = Math.max(maxX, minX + bounds.width); + maxY = Math.max(maxY, minY + bounds.height); + } + const bounds = { + x: minX, + y: minY, + width: maxX - minX, + height: maxY - minY, + }; + return bounds.width == Number.NEGATIVE_INFINITY + ? { x: 0, y: 0, width: 0, height: 0 } + : bounds; + } + } } /** @@ -185,214 +184,214 @@ export class SkinsAndAnimationBoundsProvider * See {@link skeletonToPhaserWorldCoordinates}, {@link phaserWorldCoordinatesToSkeleton}, and {@link phaserWorldCoordinatesToBoneLocal.} */ export class SpineGameObject extends DepthMixin( - OriginMixin( - ComputedSizeMixin( - FlipMixin( - ScrollFactorMixin( - TransformMixin(VisibleMixin(AlphaMixin(BaseSpineGameObject))) - ) - ) - ) - ) + OriginMixin( + ComputedSizeMixin( + FlipMixin( + ScrollFactorMixin( + TransformMixin(VisibleMixin(AlphaMixin(BaseSpineGameObject))) + ) + ) + ) + ) ) { - blendMode = -1; - skeleton: Skeleton; - animationStateData: AnimationStateData; - animationState: AnimationState; - beforeUpdateWorldTransforms: (object: SpineGameObject) => void = () => {}; - afterUpdateWorldTransforms: (object: SpineGameObject) => void = () => {}; - private premultipliedAlpha = false; + blendMode = -1; + skeleton: Skeleton; + animationStateData: AnimationStateData; + animationState: AnimationState; + beforeUpdateWorldTransforms: (object: SpineGameObject) => void = () => { }; + afterUpdateWorldTransforms: (object: SpineGameObject) => void = () => { }; + private premultipliedAlpha = false; - constructor( - scene: Phaser.Scene, - private plugin: SpinePlugin, - x: number, - y: number, - dataKey: string, - atlasKey: string, - public boundsProvider: SpineGameObjectBoundsProvider = new SetupPoseBoundsProvider() - ) { - super(scene, (window as any).SPINE_GAME_OBJECT_TYPE ? (window as any).SPINE_GAME_OBJECT_TYPE : SPINE_GAME_OBJECT_TYPE); - this.setPosition(x, y); + constructor ( + scene: Phaser.Scene, + private plugin: SpinePlugin, + x: number, + y: number, + dataKey: string, + atlasKey: string, + public boundsProvider: SpineGameObjectBoundsProvider = new SetupPoseBoundsProvider() + ) { + super(scene, (window as any).SPINE_GAME_OBJECT_TYPE ? (window as any).SPINE_GAME_OBJECT_TYPE : SPINE_GAME_OBJECT_TYPE); + this.setPosition(x, y); - this.premultipliedAlpha = this.plugin.isAtlasPremultiplied(atlasKey); - this.skeleton = this.plugin.createSkeleton(dataKey, atlasKey); - this.animationStateData = new AnimationStateData(this.skeleton.data); - this.animationState = new AnimationState(this.animationStateData); - this.skeleton.updateWorldTransform(); - this.updateSize(); - } + this.premultipliedAlpha = this.plugin.isAtlasPremultiplied(atlasKey); + this.skeleton = this.plugin.createSkeleton(dataKey, atlasKey); + this.animationStateData = new AnimationStateData(this.skeleton.data); + this.animationState = new AnimationState(this.animationStateData); + this.skeleton.updateWorldTransform(); + this.updateSize(); + } - updateSize() { - if (!this.skeleton) return; - let bounds = this.boundsProvider.calculateBounds(this); - // For some reason the TS compiler and the ComputedSize mixin don't work well together and we have - // to cast to any. - let self = this as any; - self.width = bounds.width; - self.height = bounds.height; - this.displayOriginX = -bounds.x; - this.displayOriginY = -bounds.y; - } + updateSize () { + if (!this.skeleton) return; + let bounds = this.boundsProvider.calculateBounds(this); + // For some reason the TS compiler and the ComputedSize mixin don't work well together and we have + // to cast to any. + let self = this as any; + self.width = bounds.width; + self.height = bounds.height; + this.displayOriginX = -bounds.x; + this.displayOriginY = -bounds.y; + } - /** Converts a point from the skeleton coordinate system to the Phaser world coordinate system. */ - skeletonToPhaserWorldCoordinates(point: { x: number; y: number }) { - let transform = this.getWorldTransformMatrix(); - let a = transform.a, - b = transform.b, - c = transform.c, - d = transform.d, - tx = transform.tx, - ty = transform.ty; - let x = point.x; - let y = point.y; - point.x = x * a + y * c + tx; - point.y = x * b + y * d + ty; - } + /** Converts a point from the skeleton coordinate system to the Phaser world coordinate system. */ + skeletonToPhaserWorldCoordinates (point: { x: number; y: number }) { + let transform = this.getWorldTransformMatrix(); + let a = transform.a, + b = transform.b, + c = transform.c, + d = transform.d, + tx = transform.tx, + ty = transform.ty; + let x = point.x; + let y = point.y; + point.x = x * a + y * c + tx; + point.y = x * b + y * d + ty; + } - /** Converts a point from the Phaser world coordinate system to the skeleton coordinate system. */ - phaserWorldCoordinatesToSkeleton(point: { x: number; y: number }) { - let transform = this.getWorldTransformMatrix(); - transform = transform.invert(); - let a = transform.a, - b = transform.b, - c = transform.c, - d = transform.d, - tx = transform.tx, - ty = transform.ty; - let x = point.x; - let y = point.y; - point.x = x * a + y * c + tx; - point.y = x * b + y * d + ty; - } + /** Converts a point from the Phaser world coordinate system to the skeleton coordinate system. */ + phaserWorldCoordinatesToSkeleton (point: { x: number; y: number }) { + let transform = this.getWorldTransformMatrix(); + transform = transform.invert(); + let a = transform.a, + b = transform.b, + c = transform.c, + d = transform.d, + tx = transform.tx, + ty = transform.ty; + let x = point.x; + let y = point.y; + point.x = x * a + y * c + tx; + point.y = x * b + y * d + ty; + } - /** Converts a point from the Phaser world coordinate system to the bone's local coordinate system. */ - phaserWorldCoordinatesToBone(point: { x: number; y: number }, bone: Bone) { - this.phaserWorldCoordinatesToSkeleton(point); - if (bone.parent) { - bone.parent.worldToLocal(point as Vector2); - } else { - bone.worldToLocal(point as Vector2); - } - } + /** Converts a point from the Phaser world coordinate system to the bone's local coordinate system. */ + phaserWorldCoordinatesToBone (point: { x: number; y: number }, bone: Bone) { + this.phaserWorldCoordinatesToSkeleton(point); + if (bone.parent) { + bone.parent.worldToLocal(point as Vector2); + } else { + bone.worldToLocal(point as Vector2); + } + } - /** - * Updates the {@link AnimationState}, applies it to the {@link Skeleton}, then updates the world transforms of all bones. - * @param delta The time delta in milliseconds - */ - updatePose(delta: number) { - this.animationState.update(delta / 1000); - this.animationState.apply(this.skeleton); - this.beforeUpdateWorldTransforms(this); - this.skeleton.updateWorldTransform(); - this.afterUpdateWorldTransforms(this); - } + /** + * Updates the {@link AnimationState}, applies it to the {@link Skeleton}, then updates the world transforms of all bones. + * @param delta The time delta in milliseconds + */ + updatePose (delta: number) { + this.animationState.update(delta / 1000); + this.animationState.apply(this.skeleton); + this.beforeUpdateWorldTransforms(this); + this.skeleton.updateWorldTransform(); + this.afterUpdateWorldTransforms(this); + } - preUpdate(time: number, delta: number) { - if (!this.skeleton || !this.animationState) return; - this.updatePose(delta); - } + preUpdate (time: number, delta: number) { + if (!this.skeleton || !this.animationState) return; + this.updatePose(delta); + } - preDestroy() { - // FIXME tear down any event emitters - } + preDestroy () { + // FIXME tear down any event emitters + } - willRender(camera: Phaser.Cameras.Scene2D.Camera) { - if (!this.visible) return false; + willRender (camera: Phaser.Cameras.Scene2D.Camera) { + if (!this.visible) return false; - var GameObjectRenderMask = 0xf; - var result = !this.skeleton || !(GameObjectRenderMask !== this.renderFlags || (this.cameraFilter !== 0 && this.cameraFilter & camera.id)); + var GameObjectRenderMask = 0xf; + var result = !this.skeleton || !(GameObjectRenderMask !== this.renderFlags || (this.cameraFilter !== 0 && this.cameraFilter & camera.id)); - if (!result && this.parentContainer && this.plugin.webGLRenderer) { - var sceneRenderer = this.plugin.webGLRenderer; + if (!result && this.parentContainer && this.plugin.webGLRenderer) { + var sceneRenderer = this.plugin.webGLRenderer; - if (this.plugin.gl && this.plugin.phaserRenderer instanceof Phaser.Renderer.WebGL.WebGLRenderer && sceneRenderer.batcher.isDrawing) { - sceneRenderer.end(); - this.plugin.phaserRenderer.pipelines.rebind(); - } - } + if (this.plugin.gl && this.plugin.phaserRenderer instanceof Phaser.Renderer.WebGL.WebGLRenderer && sceneRenderer.batcher.isDrawing) { + sceneRenderer.end(); + this.plugin.phaserRenderer.pipelines.rebind(); + } + } - return result; - } + return result; + } - renderWebGL( - renderer: Phaser.Renderer.WebGL.WebGLRenderer, - src: SpineGameObject, - camera: Phaser.Cameras.Scene2D.Camera, - parentMatrix: Phaser.GameObjects.Components.TransformMatrix - ) { - if (!this.skeleton || !this.animationState || !this.plugin.webGLRenderer) - return; + renderWebGL ( + renderer: Phaser.Renderer.WebGL.WebGLRenderer, + src: SpineGameObject, + camera: Phaser.Cameras.Scene2D.Camera, + parentMatrix: Phaser.GameObjects.Components.TransformMatrix + ) { + if (!this.skeleton || !this.animationState || !this.plugin.webGLRenderer) + return; - let sceneRenderer = this.plugin.webGLRenderer; - if (renderer.newType) { - renderer.pipelines.clear(); - sceneRenderer.begin(); - } + let sceneRenderer = this.plugin.webGLRenderer; + if (renderer.newType) { + renderer.pipelines.clear(); + sceneRenderer.begin(); + } - camera.addToRenderList(src); - let transform = Phaser.GameObjects.GetCalcMatrix( - src, - camera, - parentMatrix - ).calc; - let a = transform.a, - b = transform.b, - c = transform.c, - d = transform.d, - tx = transform.tx, - ty = transform.ty; - sceneRenderer.drawSkeleton( - this.skeleton, - this.premultipliedAlpha, - -1, - -1, - (vertices, numVertices, stride) => { - for (let i = 0; i < numVertices; i += stride) { - let vx = vertices[i]; - let vy = vertices[i + 1]; - vertices[i] = vx * a + vy * c + tx; - vertices[i + 1] = vx * b + vy * d + ty; - } - } - ); + camera.addToRenderList(src); + let transform = Phaser.GameObjects.GetCalcMatrix( + src, + camera, + parentMatrix + ).calc; + let a = transform.a, + b = transform.b, + c = transform.c, + d = transform.d, + tx = transform.tx, + ty = transform.ty; + sceneRenderer.drawSkeleton( + this.skeleton, + this.premultipliedAlpha, + -1, + -1, + (vertices, numVertices, stride) => { + for (let i = 0; i < numVertices; i += stride) { + let vx = vertices[i]; + let vy = vertices[i + 1]; + vertices[i] = vx * a + vy * c + tx; + vertices[i + 1] = vx * b + vy * d + ty; + } + } + ); - if (!renderer.nextTypeMatch) { - sceneRenderer.end(); - renderer.pipelines.rebind(); - } - } + if (!renderer.nextTypeMatch) { + sceneRenderer.end(); + renderer.pipelines.rebind(); + } + } - renderCanvas( - renderer: Phaser.Renderer.Canvas.CanvasRenderer, - src: SpineGameObject, - camera: Phaser.Cameras.Scene2D.Camera, - parentMatrix: Phaser.GameObjects.Components.TransformMatrix - ) { - if (!this.skeleton || !this.animationState || !this.plugin.canvasRenderer) - return; + renderCanvas ( + renderer: Phaser.Renderer.Canvas.CanvasRenderer, + src: SpineGameObject, + camera: Phaser.Cameras.Scene2D.Camera, + parentMatrix: Phaser.GameObjects.Components.TransformMatrix + ) { + if (!this.skeleton || !this.animationState || !this.plugin.canvasRenderer) + return; - let context = renderer.currentContext; - let skeletonRenderer = this.plugin.canvasRenderer; - (skeletonRenderer as any).ctx = context; + let context = renderer.currentContext; + let skeletonRenderer = this.plugin.canvasRenderer; + (skeletonRenderer as any).ctx = context; - camera.addToRenderList(src); - let transform = Phaser.GameObjects.GetCalcMatrix( - src, - camera, - parentMatrix - ).calc; - let skeleton = this.skeleton; - skeleton.x = transform.tx; - skeleton.y = transform.ty; - skeleton.scaleX = transform.scaleX; - skeleton.scaleY = transform.scaleY; - let root = skeleton.getRootBone()!; - root.rotation = -MathUtils.radiansToDegrees * transform.rotationNormalized; - this.skeleton.updateWorldTransform(); + camera.addToRenderList(src); + let transform = Phaser.GameObjects.GetCalcMatrix( + src, + camera, + parentMatrix + ).calc; + let skeleton = this.skeleton; + skeleton.x = transform.tx; + skeleton.y = transform.ty; + skeleton.scaleX = transform.scaleX; + skeleton.scaleY = transform.scaleY; + let root = skeleton.getRootBone()!; + root.rotation = -MathUtils.radiansToDegrees * transform.rotationNormalized; + this.skeleton.updateWorldTransform(); - context.save(); - skeletonRenderer.draw(skeleton); - context.restore(); - } + context.save(); + skeletonRenderer.draw(skeleton); + context.restore(); + } } diff --git a/spine-ts/spine-phaser/src/SpinePlugin.ts b/spine-ts/spine-phaser/src/SpinePlugin.ts index d28a1334c..01abaf0f4 100644 --- a/spine-ts/spine-phaser/src/SpinePlugin.ts +++ b/spine-ts/spine-phaser/src/SpinePlugin.ts @@ -271,7 +271,7 @@ class SpineSkeletonDataFile extends Phaser.Loader.MultiFile { url = config.url; fileType = config.type === "spineJson" ? SpineSkeletonDataFileType.json : SpineSkeletonDataFileType.binary; xhrSettings = config.xhrSettings; - } + } let file = null; let isJson = fileType == SpineSkeletonDataFileType.json; if (isJson) { diff --git a/spine-ts/spine-threejs/src/SkeletonMesh.ts b/spine-ts/spine-threejs/src/SkeletonMesh.ts index 5769dc47f..433c75689 100644 --- a/spine-ts/spine-threejs/src/SkeletonMesh.ts +++ b/spine-ts/spine-threejs/src/SkeletonMesh.ts @@ -28,32 +28,32 @@ *****************************************************************************/ import { - AnimationState, - AnimationStateData, - BlendMode, - ClippingAttachment, - Color, - MeshAttachment, - NumberArrayLike, - RegionAttachment, - Skeleton, - SkeletonClipping, - SkeletonData, - TextureAtlasRegion, - Utils, - Vector2, + AnimationState, + AnimationStateData, + BlendMode, + ClippingAttachment, + Color, + MeshAttachment, + NumberArrayLike, + RegionAttachment, + Skeleton, + SkeletonClipping, + SkeletonData, + TextureAtlasRegion, + Utils, + Vector2, } from "@esotericsoftware/spine-core"; import { MeshBatcher } from "./MeshBatcher"; import * as THREE from "three"; import { ThreeJsTexture } from "./ThreeJsTexture"; export type SkeletonMeshMaterialParametersCustomizer = ( - materialParameters: THREE.ShaderMaterialParameters + materialParameters: THREE.ShaderMaterialParameters ) => void; export class SkeletonMeshMaterial extends THREE.ShaderMaterial { - constructor(customizer: SkeletonMeshMaterialParametersCustomizer) { - let vertexShader = ` + constructor (customizer: SkeletonMeshMaterialParametersCustomizer) { + let vertexShader = ` attribute vec4 color; varying vec2 vUv; varying vec4 vColor; @@ -63,7 +63,7 @@ export class SkeletonMeshMaterial extends THREE.ShaderMaterial { gl_Position = projectionMatrix*modelViewMatrix*vec4(position,1.0); } `; - let fragmentShader = ` + let fragmentShader = ` uniform sampler2D map; #ifdef USE_SPINE_ALPHATEST uniform float alphaTest; @@ -78,253 +78,253 @@ export class SkeletonMeshMaterial extends THREE.ShaderMaterial { } `; - let parameters: THREE.ShaderMaterialParameters = { - uniforms: { - map: { value: null }, - }, - vertexShader: vertexShader, - fragmentShader: fragmentShader, - side: THREE.DoubleSide, - transparent: true, - depthWrite: true, - alphaTest: 0.0, - }; - customizer(parameters); - if (parameters.alphaTest && parameters.alphaTest > 0) { - parameters.defines = { USE_SPINE_ALPHATEST: 1 }; - if (!parameters.uniforms) parameters.uniforms = {}; - parameters.uniforms["alphaTest"] = { value: parameters.alphaTest }; - } - super(parameters); - } + let parameters: THREE.ShaderMaterialParameters = { + uniforms: { + map: { value: null }, + }, + vertexShader: vertexShader, + fragmentShader: fragmentShader, + side: THREE.DoubleSide, + transparent: true, + depthWrite: true, + alphaTest: 0.0, + }; + customizer(parameters); + if (parameters.alphaTest && parameters.alphaTest > 0) { + parameters.defines = { USE_SPINE_ALPHATEST: 1 }; + if (!parameters.uniforms) parameters.uniforms = {}; + parameters.uniforms["alphaTest"] = { value: parameters.alphaTest }; + } + super(parameters); + } } export class SkeletonMesh extends THREE.Object3D { - tempPos: Vector2 = new Vector2(); - tempUv: Vector2 = new Vector2(); - tempLight = new Color(); - tempDark = new Color(); - skeleton: Skeleton; - state: AnimationState; - zOffset: number = 0.1; + tempPos: Vector2 = new Vector2(); + tempUv: Vector2 = new Vector2(); + tempLight = new Color(); + tempDark = new Color(); + skeleton: Skeleton; + state: AnimationState; + zOffset: number = 0.1; - private batches = new Array(); - private nextBatchIndex = 0; - private clipper: SkeletonClipping = new SkeletonClipping(); + private batches = new Array(); + private nextBatchIndex = 0; + private clipper: SkeletonClipping = new SkeletonClipping(); - static QUAD_TRIANGLES = [0, 1, 2, 2, 3, 0]; - static VERTEX_SIZE = 2 + 2 + 4; + static QUAD_TRIANGLES = [0, 1, 2, 2, 3, 0]; + static VERTEX_SIZE = 2 + 2 + 4; - private vertices = Utils.newFloatArray(1024); - private tempColor = new Color(); + private vertices = Utils.newFloatArray(1024); + private tempColor = new Color(); - constructor( - skeletonData: SkeletonData, - private materialCustomerizer: SkeletonMeshMaterialParametersCustomizer = ( - material - ) => {} - ) { - super(); + constructor ( + skeletonData: SkeletonData, + private materialCustomerizer: SkeletonMeshMaterialParametersCustomizer = ( + material + ) => { } + ) { + super(); - this.skeleton = new Skeleton(skeletonData); - let animData = new AnimationStateData(skeletonData); - this.state = new AnimationState(animData); - } + this.skeleton = new Skeleton(skeletonData); + let animData = new AnimationStateData(skeletonData); + this.state = new AnimationState(animData); + } - update(deltaTime: number) { - let state = this.state; - let skeleton = this.skeleton; + update (deltaTime: number) { + let state = this.state; + let skeleton = this.skeleton; - state.update(deltaTime); - state.apply(skeleton); - skeleton.updateWorldTransform(); + state.update(deltaTime); + state.apply(skeleton); + skeleton.updateWorldTransform(); - this.updateGeometry(); - } + this.updateGeometry(); + } - dispose() { - for (var i = 0; i < this.batches.length; i++) { - this.batches[i].dispose(); - } - } + dispose () { + for (var i = 0; i < this.batches.length; i++) { + this.batches[i].dispose(); + } + } - private clearBatches() { - for (var i = 0; i < this.batches.length; i++) { - this.batches[i].clear(); - this.batches[i].visible = false; - } - this.nextBatchIndex = 0; - } + private clearBatches () { + for (var i = 0; i < this.batches.length; i++) { + this.batches[i].clear(); + this.batches[i].visible = false; + } + this.nextBatchIndex = 0; + } - private nextBatch() { - if (this.batches.length == this.nextBatchIndex) { - let batch = new MeshBatcher(10920, this.materialCustomerizer); - this.add(batch); - this.batches.push(batch); - } - let batch = this.batches[this.nextBatchIndex++]; - batch.visible = true; - return batch; - } + private nextBatch () { + if (this.batches.length == this.nextBatchIndex) { + let batch = new MeshBatcher(10920, this.materialCustomerizer); + this.add(batch); + this.batches.push(batch); + } + let batch = this.batches[this.nextBatchIndex++]; + batch.visible = true; + return batch; + } - private updateGeometry() { - this.clearBatches(); + private updateGeometry () { + this.clearBatches(); - let tempPos = this.tempPos; - let tempUv = this.tempUv; - let tempLight = this.tempLight; - let tempDark = this.tempDark; - let clipper = this.clipper; + let tempPos = this.tempPos; + let tempUv = this.tempUv; + let tempLight = this.tempLight; + let tempDark = this.tempDark; + let clipper = this.clipper; - let vertices: NumberArrayLike = this.vertices; - let triangles: Array | null = null; - let uvs: NumberArrayLike | null = null; - let drawOrder = this.skeleton.drawOrder; - let batch = this.nextBatch(); - batch.begin(); - let z = 0; - let zOffset = this.zOffset; - for (let i = 0, n = drawOrder.length; i < n; i++) { - let vertexSize = clipper.isClipping() ? 2 : SkeletonMesh.VERTEX_SIZE; - let slot = drawOrder[i]; - if (!slot.bone.active) { - clipper.clipEndWithSlot(slot); - continue; - } - let attachment = slot.getAttachment(); - let attachmentColor: Color | null; - let texture: ThreeJsTexture | null; - let numFloats = 0; - if (attachment instanceof RegionAttachment) { - let region = attachment; - attachmentColor = region.color; - vertices = this.vertices; - numFloats = vertexSize * 4; - region.computeWorldVertices(slot, vertices, 0, vertexSize); - triangles = SkeletonMesh.QUAD_TRIANGLES; - uvs = region.uvs; - texture = region.region!.texture; - } else if (attachment instanceof MeshAttachment) { - let mesh = attachment; - attachmentColor = mesh.color; - vertices = this.vertices; - numFloats = (mesh.worldVerticesLength >> 1) * vertexSize; - if (numFloats > vertices.length) { - vertices = this.vertices = Utils.newFloatArray(numFloats); - } - mesh.computeWorldVertices( - slot, - 0, - mesh.worldVerticesLength, - vertices, - 0, - vertexSize - ); - triangles = mesh.triangles; - uvs = mesh.uvs; - texture = mesh.region!.texture; - } else if (attachment instanceof ClippingAttachment) { - let clip = attachment; - clipper.clipStart(slot, clip); - continue; - } else { - clipper.clipEndWithSlot(slot); - continue; - } + let vertices: NumberArrayLike = this.vertices; + let triangles: Array | null = null; + let uvs: NumberArrayLike | null = null; + let drawOrder = this.skeleton.drawOrder; + let batch = this.nextBatch(); + batch.begin(); + let z = 0; + let zOffset = this.zOffset; + for (let i = 0, n = drawOrder.length; i < n; i++) { + let vertexSize = clipper.isClipping() ? 2 : SkeletonMesh.VERTEX_SIZE; + let slot = drawOrder[i]; + if (!slot.bone.active) { + clipper.clipEndWithSlot(slot); + continue; + } + let attachment = slot.getAttachment(); + let attachmentColor: Color | null; + let texture: ThreeJsTexture | null; + let numFloats = 0; + if (attachment instanceof RegionAttachment) { + let region = attachment; + attachmentColor = region.color; + vertices = this.vertices; + numFloats = vertexSize * 4; + region.computeWorldVertices(slot, vertices, 0, vertexSize); + triangles = SkeletonMesh.QUAD_TRIANGLES; + uvs = region.uvs; + texture = region.region!.texture; + } else if (attachment instanceof MeshAttachment) { + let mesh = attachment; + attachmentColor = mesh.color; + vertices = this.vertices; + numFloats = (mesh.worldVerticesLength >> 1) * vertexSize; + if (numFloats > vertices.length) { + vertices = this.vertices = Utils.newFloatArray(numFloats); + } + mesh.computeWorldVertices( + slot, + 0, + mesh.worldVerticesLength, + vertices, + 0, + vertexSize + ); + triangles = mesh.triangles; + uvs = mesh.uvs; + texture = mesh.region!.texture; + } else if (attachment instanceof ClippingAttachment) { + let clip = attachment; + clipper.clipStart(slot, clip); + continue; + } else { + clipper.clipEndWithSlot(slot); + continue; + } - if (texture != null) { - let skeleton = slot.bone.skeleton; - let skeletonColor = skeleton.color; - let slotColor = slot.color; - let alpha = skeletonColor.a * slotColor.a * attachmentColor.a; - let color = this.tempColor; - color.set( - skeletonColor.r * slotColor.r * attachmentColor.r, - skeletonColor.g * slotColor.g * attachmentColor.g, - skeletonColor.b * slotColor.b * attachmentColor.b, - alpha - ); + if (texture != null) { + let skeleton = slot.bone.skeleton; + let skeletonColor = skeleton.color; + let slotColor = slot.color; + let alpha = skeletonColor.a * slotColor.a * attachmentColor.a; + let color = this.tempColor; + color.set( + skeletonColor.r * slotColor.r * attachmentColor.r, + skeletonColor.g * slotColor.g * attachmentColor.g, + skeletonColor.b * slotColor.b * attachmentColor.b, + alpha + ); - let finalVertices: NumberArrayLike; - let finalVerticesLength: number; - let finalIndices: NumberArrayLike; - let finalIndicesLength: number; + let finalVertices: NumberArrayLike; + let finalVerticesLength: number; + let finalIndices: NumberArrayLike; + let finalIndicesLength: number; - if (clipper.isClipping()) { - clipper.clipTriangles( - vertices, - numFloats, - triangles, - triangles.length, - uvs, - color, - tempLight, - false - ); - let clippedVertices = clipper.clippedVertices; - let clippedTriangles = clipper.clippedTriangles; - finalVertices = clippedVertices; - finalVerticesLength = clippedVertices.length; - finalIndices = clippedTriangles; - finalIndicesLength = clippedTriangles.length; - } else { - let verts = vertices; - for ( - let v = 2, u = 0, n = numFloats; - v < n; - v += vertexSize, u += 2 - ) { - verts[v] = color.r; - verts[v + 1] = color.g; - verts[v + 2] = color.b; - verts[v + 3] = color.a; - verts[v + 4] = uvs[u]; - verts[v + 5] = uvs[u + 1]; - } - finalVertices = vertices; - finalVerticesLength = numFloats; - finalIndices = triangles; - finalIndicesLength = triangles.length; - } + if (clipper.isClipping()) { + clipper.clipTriangles( + vertices, + numFloats, + triangles, + triangles.length, + uvs, + color, + tempLight, + false + ); + let clippedVertices = clipper.clippedVertices; + let clippedTriangles = clipper.clippedTriangles; + finalVertices = clippedVertices; + finalVerticesLength = clippedVertices.length; + finalIndices = clippedTriangles; + finalIndicesLength = clippedTriangles.length; + } else { + let verts = vertices; + for ( + let v = 2, u = 0, n = numFloats; + v < n; + v += vertexSize, u += 2 + ) { + verts[v] = color.r; + verts[v + 1] = color.g; + verts[v + 2] = color.b; + verts[v + 3] = color.a; + verts[v + 4] = uvs[u]; + verts[v + 5] = uvs[u + 1]; + } + finalVertices = vertices; + finalVerticesLength = numFloats; + finalIndices = triangles; + finalIndicesLength = triangles.length; + } - if (finalVerticesLength == 0 || finalIndicesLength == 0) { - clipper.clipEndWithSlot(slot); - continue; - } + if (finalVerticesLength == 0 || finalIndicesLength == 0) { + clipper.clipEndWithSlot(slot); + continue; + } - // Start new batch if this one can't hold vertices/indices - if ( - !batch.canBatch( - finalVerticesLength / SkeletonMesh.VERTEX_SIZE, - finalIndicesLength - ) - ) { - batch.end(); - batch = this.nextBatch(); - batch.begin(); - } + // Start new batch if this one can't hold vertices/indices + if ( + !batch.canBatch( + finalVerticesLength / SkeletonMesh.VERTEX_SIZE, + finalIndicesLength + ) + ) { + batch.end(); + batch = this.nextBatch(); + batch.begin(); + } - const slotBlendMode = slot.data.blendMode; - const slotTexture = texture.texture; - const materialGroup = batch.findMaterialGroup( - slotTexture, - slotBlendMode - ); + const slotBlendMode = slot.data.blendMode; + const slotTexture = texture.texture; + const materialGroup = batch.findMaterialGroup( + slotTexture, + slotBlendMode + ); - batch.addMaterialGroup(finalIndicesLength, materialGroup); - batch.batch( - finalVertices, - finalVerticesLength, - finalIndices, - finalIndicesLength, - z - ); - z += zOffset; - } + batch.addMaterialGroup(finalIndicesLength, materialGroup); + batch.batch( + finalVertices, + finalVerticesLength, + finalIndices, + finalIndicesLength, + z + ); + z += zOffset; + } - clipper.clipEndWithSlot(slot); - } - clipper.clipEnd(); - batch.end(); - } + clipper.clipEndWithSlot(slot); + } + clipper.clipEnd(); + batch.end(); + } } diff --git a/spine-ts/spine-webgl/src/SkeletonRenderer.ts b/spine-ts/spine-webgl/src/SkeletonRenderer.ts index bded0dd82..9c77897be 100644 --- a/spine-ts/spine-webgl/src/SkeletonRenderer.ts +++ b/spine-ts/spine-webgl/src/SkeletonRenderer.ts @@ -170,7 +170,7 @@ export class SkeletonRenderer { WebGLBlendModeConverter.getSourceColorGLBlendMode(blendMode, premultipliedAlpha), WebGLBlendModeConverter.getSourceAlphaGLBlendMode(blendMode, premultipliedAlpha), WebGLBlendModeConverter.getDestColorGLBlendMode(blendMode), - WebGLBlendModeConverter.getDestAlphaGLBlendMode(blendMode, premultipliedAlpha) ); + WebGLBlendModeConverter.getDestAlphaGLBlendMode(blendMode, premultipliedAlpha)); } if (clipper.isClipping()) {