var SkeletalPieceCollectionStatics = {};
SkeletalPieceCollectionStatics.UniquePieceID = 0;
SkeletalPieceCollectionStatics.SkeletalPieceCollectionCache = {};
Engine.SkeletalPieceCollection = class
{
constructor()
{
this.piecesByName = {};
this.replacements = {};
}
setReplacement(source, replacement)
{
this.replacements[source] = replacement;
}
clearReplacement(source, replacement)
{
if (this.replacements[source] !== undefined) delete this.replacements[source];
}
clearReplacements()
{
this.replacements = {};
}
/* Adds all the unqiue pieces from a graphic def (that is type skeletal) to the collection. */
addPiecesFromGraphicDef(graphicDef)
{
for (var pieces of graphicDef.sequences)
{
for (var i = 0; i < pieces.length; i++)
{
var piece = this.addPiece(pieces[i], graphicDef);
}
}
}
/* Adds a new piece to the piece set by name, only one unqiue piece allowed per name */
addPiece(pieceData, graphicDef)
{
if (pieceData.key === undefined) pieceData.key = pieceData.x+"_"+pieceData.y+"_"+pieceData.texture_index;
if (pieceData.n === undefined) pieceData.n = pieceData.key;
var name = pieceData.n;
var key = pieceData.key;
if (this.piecesByName[name] !== undefined) return;
var piece = null;
var textureIndex = pieceData.texture_index;
let texture = new PIXI.Texture(graphicDef.baseTextures[pieceData.texture_index]);
piece = new PIXI.Sprite(texture);
piece.texture.frame = graphicDef.frames[key].frame;
piece.anchor.x = graphicDef.frames[key].pivot.x;
piece.anchor.y = graphicDef.frames[key].pivot.y;
piece.visible = true;
piece.piece_in_use = false;
piece.piece_name = name;
piece.piece_source_frame = graphicDef.frames[key];
if (this.piecesByName[name] === undefined) this.piecesByName[name] = [];
this.piecesByName[name].push(piece);
//console.log(name);
return piece;
}
/* Clones a piece for the cases where the same piece appears more than once on a given frame but with a different transform */
clonePiece(sourcePiece)
{
var piece = new PIXI.Sprite(sourcePiece.texture);
piece.texture.frame = sourcePiece.piece_source_frame.frame;
piece.anchor.x = sourcePiece.piece_source_frame.pivot.x;
piece.anchor.y = sourcePiece.piece_source_frame.pivot.y;
piece.visible = true;
piece.piece_in_use = false;
piece.piece_name = sourcePiece.piece_name;
if (this.piecesByName[sourcePiece.piece_name] === undefined) this.piecesByName[sourcePiece.piece_name] = [];
this.piecesByName[sourcePiece.piece_name].push(piece);
return piece;
}
getPieceByName(name)
{
if (this.replacements[name] !== undefined && this.replacements[name] != "") name = this.replacements[name];
var pieceVisible = true;
if (this.replacements[name] !== undefined && this.replacements[name] == "") pieceVisible = false;
var availableCopiesOfPiece = this.piecesByName[name];
if (availableCopiesOfPiece == null)
{
Debug.Log("Error no copies of piece, was the graphic loaded?!");
return null;
}
var piece = null;
for (var i = 0; i < availableCopiesOfPiece.length; i++)
{
if (!availableCopiesOfPiece[i].piece_in_use)
{
piece = availableCopiesOfPiece[i];
break;
}
}
if (piece == null)
{
piece = this.clonePiece(availableCopiesOfPiece[0]);
}
piece.visible = pieceVisible;
piece.piece_in_use = true;
return piece;
}
clearUsedPieces()
{
for (var pieces of Object.values(this.piecesByName))
{
for (var piece of pieces)
{
piece.visible = false;
piece.piece_in_use = false;
}
}
}
clearAndRemove()
{
for (var pieces of Object.values(this.piecesByName))
{
for (var piece of pieces)
{
piece.visible = false;
piece.piece_in_use = false;
if (piece.parent != null) piece.parent.removeChild(piece);
}
}
}
}
Engine.SkeletalAnimationControllerReplaceable = class
{
static replaceControllerOnDrawable(drawable)
{
if (drawable.skeletalController == null)
{
Debug.ErrorLog("Drawable did not contain a skeletal controller to replace.");
return;
}
drawable.skeletalController.destroy();
drawable.skeletalController = new Engine.SkeletalAnimationControllerReplaceable(drawable.graphicData);
drawable.addChild(drawable.skeletalController.group);
}
constructor(graphicDef)
{
this.graphicDef = graphicDef;
if (SkeletalPieceCollectionStatics.SkeletalPieceCollectionCache[this.graphicDef.name] === undefined)
{
SkeletalPieceCollectionStatics.SkeletalPieceCollectionCache[this.graphicDef.name] = new Engine.ObjectPool(Engine.SkeletalPieceCollection);
}
var piecePool = SkeletalPieceCollectionStatics.SkeletalPieceCollectionCache[this.graphicDef.name];
this.pieceCollection = piecePool.getNextObject();// new Engine.SkeletalPieceCollection();
this.pieceCollection.addPiecesFromGraphicDef(graphicDef);
this.group = new PIXI.Container();
}
setFrame(sequence, frame)
{
//this.clearDebug();
this.clearUsedPieces();
this.pieces = this.graphicDef.sequences[sequence];
if (this.pieces === undefined){
Debug.LogError("Attempt to set non existant sequence "+sequence+" on "+this.graphicDef.name);
return;
}
for (var i = 0; i < this.pieces.length; i++)
{
var frameInfo = this.pieces[i].sequence[frame];
if (frameInfo === undefined){
Debug.LogError("Attempt to set non existant frame "+frame+" on "+this.graphicDef.name);
return;
}
if (frameInfo.used)
{
var piece = piece = this.pieceCollection.getPieceByName(this.pieces[i].n);
if (piece == null) continue;
var rot = frameInfo.rot;
var xScaleNeg = frameInfo.sx < 0;
var yScaleNeg = frameInfo.sy < 0;
if (xScaleNeg != yScaleNeg) rot *= -1;
piece.rotation = rot;
piece.x = frameInfo.tx;
piece.y = frameInfo.ty;
piece.z = frameInfo.z;
piece.zOrder = piece.z;
piece.scale.x = frameInfo.sx;
piece.scale.y = frameInfo.sy;
if (piece.parent != this.group) this.group.addChild(piece);
//this.addDebug(piece, frameInfo, this.pieces[i]);
}
}
this.group.children.sort((a, b) => {
if(a.zOrder === b.zOrder) return 0;
else return (a.zOrder < b.zOrder ? -1 : 1);
});
}
clearDebug()
{
if (this.activeDebug !== undefined){
for(var i = 0; i < this.activeDebug.length; i++){
this.activeDebug[i].parent.removeChild(this.activeDebug[i]);
}
this.activeDebug.length = 0;
}
}
addDebug(piece, frameInfo, pieceInfo)
{
if (pieceInfo.n.indexOf("Unknown") == -1) {
//piece.visible = false;
return;
}
if (this.debugClips === undefined) {
this.debugClips = new Engine.ObjectPool(Engine.DrawableText);
this.activeDebug = [];
}
var clip = this.debugClips.getNextObject();
this.activeDebug.push(clip);
//clip.setText(pieceInfo.n +" "+frameInfo.tx+" "+frameInfo.ty, "Verdana", 24);
clip.setText(pieceInfo.n, "Verdana", 24);
clip.scale.x = 1/5;
clip.scale.y = 1/5;
piece.addChild(clip);
}
clearUsedPieces()
{
this.pieceCollection.clearUsedPieces();
}
destroy()
{
this.pieceCollection.clearAndRemove();
SkeletalPieceCollectionStatics.SkeletalPieceCollectionCache[this.graphicDef.name].returnObject(this.pieceCollection);
this.graphicDef = null;
if (this.group.parent != null) this.group.parent.removeChild(this.group);
this.group = null;
}
}