I'm using Phaser not PIXI (or if I am using PIXI it's being managed by Phaser behind the scenes). I apparently missed a bit in their documentation about atlas loading. https://photonstorm.github.io/phaser3-docs/Phaser.Loader.LoaderPlugin.html which allows you to load multiple atlas which is great as I'm now being able to render both atlas (Note: I'm aware the image isn't the right size. That will be fixed later.).
That said now I just want to know if you can change out an atlas's image. If there is a way to do that then I'm gold at this point! I'm looking into it now but if someone happens to know how please share. 🙂
Got it working! Thanks Nate for replying.
Here is code reference for anyone trying to solve the same problem!
const DURATION = 700;
const EASE = 'Sine.easeInOut';
const WHITE = 0xffffff;
const TEST_COLOR = 0x125689;
const HIGHLIGHT_COLOR = 0x00ff00;
export class SpineUtilities {
constructor({ scene, x, y, spineName, size, assets, configuration, pubSub }) {
[this.scene, this.x, this.y, this.spineName, this.size, this.assets, this.configuration, this.pubSub] = [scene, x, y, spineName, size, assets, configuration, pubSub];
this.targets = [];
if (spineName) {
this.spineObject = this.createSpineObject({ spineName, x, y, size, assets });
}
Activity.Utils.Timer.delayedCall(3500, () => {
this.setImage();
});
}
setImage() {
let spineObject = this.spineObject;
let skin = spineObject.findSkin('default');
this.skin = skin;
// spineObject.setSkinByName('default');
let slotName = 'target';
let slot = spineObject.findSlot(slotName);
this.slot = slot;
let slotIndex = spineObject.findSlotIndex(slotName);
this.slotIndex = slotIndex;
let bone = spineObject.skeleton.bones[1];
this.bone = bone;
let texture = window.document.createElement('IMG');
texture.src = 'http://localhost:8080/modules/GroupedChoice/1.0.0/dist/debug/media/test/grapes.png';
texture.onload = () => {
texture
let customAtlas = new this.scene.spine.plugin.TextureAtlas(
`grapes.png
size: 512,512
format: RGBA8888
filter: Linear,Linear
repeat: none
target
rotate: false
xy: 0, 0
size: 512, 512
orig: 512, 512
offset: 1, 1
index: -1`,
(path) => {
console.log(path);
let context = this.scene.spine.sceneRenderer.context.gl;//this.scene.game.context;
// let texture = this.loadTexture(context, '{{MEDIA}}/test/spineInjectionTestRegionImage.jpg');
let glTexture = new this.scene.spine.plugin.webgl.GLTexture(context, texture, false);
console.log("ATLAS READY");
return glTexture;
});
// let atlasAttachmentLoader = new this.scene.spine.plugin.AtlasAttachmentLoader(customAtlas);
// let loadedRegionAttachment = atlasAttachmentLoader.newRegionAttachment(skin, 'targetRegion', 'target');
let region = customAtlas.findRegion('target');
let attachment = spineObject.getAttachment(slotIndex, 'target');
region.renderObject = region;
attachment.setRegion(region);
}
}
createSpineObject({ spineName, x, y, size, assets }) {
let spineObject = this.scene.add.spine(x, y, spineName);
this.spineObject = spineObject;
spineObject.setSize(size, size);
spineObject.setAnimation(0, 'idle', true);
this.targets.push(spineObject);
spineObject.setSkinByName('default');
// return spineObject;
//
// MANUAL IMAGE ADDING APPROACH
// this.image = this.scene.add.image(x,y,'regionImage');
// this.image.displayWidth = 150;
// this.image.displayHeight = 150;
this.scene.events.on('update', this.update, this);
this.cursors = this.scene.input.keyboard.createCursorKeys();
// this.scene.tweens.add({
// targets: this.image,
// skewX: 1.1,
// skewY: 0.4,
// duration: 3000,
// ease: 'Sine.easeInOut',
// loop: -1,
// yoyo: true
// });
this.skeleton = spineObject.skeleton;
return spineObject;
}
update(now) {
// console.log('update');
// let bone = this.spineObject.skeleton.bones[1];
// console.log(bone.rotation);
// this.image.x = bone.worldX;
// this.image.y = bone.worldY;
// this.image.angle = -bone.rotation - 90;
}
setPosition({ x, y }) {
this.targets.forEach((target) => {
target.setPosition(x, y);
});
}
setTarget({ }) {
if (this.spineObject) {
console.log(this.attachment, this.slot);
}
}
moveObject({ position, duration, ease }) {
let promise = new Promise((resolve, reject) => {
let [x, y] = [position.x, position.y];
this.scene.tweens.add({
targets: this.targets,
duration,
ease,
x,
y,
onComplete: () => {
this.position = position;
resolve();
}
});
});
return promise;
}
loadTexture(gl, url) {
const texture = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, texture);
// Because images have to be downloaded over the internet
// they might take a moment until they are ready.
// Until then put a single pixel in the texture so we can
// use it immediately. When the image has finished downloading
// we'll update the texture with the contents of the image.
const level = 0;
const internalFormat = gl.RGBA;
const width = 1;
const height = 1;
const border = 0;
const srcFormat = gl.RGBA;
const srcType = gl.UNSIGNED_BYTE;
const pixel = new Uint8Array([0, 0, 255, 255]); // opaque blue
gl.texImage2D(gl.TEXTURE_2D, level, internalFormat,
width, height, border, srcFormat, srcType,
pixel);
const image = new Image();
image.onload = function () {
gl.bindTexture(gl.TEXTURE_2D, texture);
gl.texImage2D(gl.TEXTURE_2D, level, internalFormat,
srcFormat, srcType, image);
// WebGL1 has different requirements for power of 2 images
// vs non power of 2 images so check if the image is a
// power of 2 in both dimensions.
if (this.isPowerOf2(image.width) && this.isPowerOf2(image.height)) {
// Yes, it's a power of 2. Generate mips.
gl.generateMipmap(gl.TEXTURE_2D);
} else {
// No, it's not a power of 2. Turn off mips and set
// wrapping to clamp to edge
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
}
};
image.src = url;
return texture;
}
isPowerOf2(value) {
return (value & (value - 1)) == 0;
}
}