Skip to content

Commit

Permalink
feat (skin): Add script interface custom skin outfit (set entire skin)
Browse files Browse the repository at this point in the history
Custom script interface for BT set outfit
Add Apply Slot Color script interface
  • Loading branch information
MikalDev committed Aug 2, 2021
1 parent 971612d commit 421fda0
Show file tree
Hide file tree
Showing 6 changed files with 136 additions and 54 deletions.
Binary file added dist/Spine-v1.48.0.c3addon
Binary file not shown.
2 changes: 1 addition & 1 deletion src/addon.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"type": "plugin",
"name": "Spine",
"id": "Gritsenko_Spine",
"version": "1.47.5",
"version": "1.48.0",
"author": "Mikal and Igor Gritsenko",
"website": "https://gritsenko.github.io/c3_spine_plugin",
"documentation": "https://gritsenko.github.io/c3_spine_plugin",
Expand Down
61 changes: 10 additions & 51 deletions src/c3runtime/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -123,8 +123,14 @@
}

const skeleton = this.skeletonInfo.skeleton;

this.customSkins[skinName] = new spine.Skin(skinName);
// If already exists, just clear
if (this.customSkins[skinName])
{
this.customSkins[skinName].clear();
} else
{
this.customSkins[skinName] = new spine.Skin(skinName);
}
},

AddCustomSkin(skinName,addSkinName)
Expand All @@ -142,7 +148,7 @@
let addSkin = skeleton.data.findSkin(addSkinName);
if (addSkin)
{
this.customSkins[skinName].addSkin(skeleton.data.findSkin(addSkinName));
this.customSkins[skinName].addSkin(addSkin);
} else
{
if (this.debug) console.warn('[Spine] AddCustomSkin, add skin does not exist',skinName,addSkinName, this.uid, this.runtime.GetTickCount());
Expand All @@ -164,7 +170,6 @@

this.skinName = skinName
const skeleton = this.skeletonInfo.skeleton;
this.customSkins[this.skinName]
skeleton.setSkin(this.customSkins[this.skinName]);
skeleton.setSlotsToSetupPose();

Expand Down Expand Up @@ -214,53 +219,7 @@

ApplySlotColors()
{
if (!this.skeletonInfo || !this.skeletonInfo.skeleton)
{
if (this.debug) console.warn('[Spine] ApplySlotColors, no skeleton.', this.uid, this.runtime.GetTickCount());
return;
}

const skeleton = this.skeletonInfo.skeleton;
// Set regular colors to slots
let slotName;
for(slotName in this.slotColors)
{
let slot = skeleton.findSlot(slotName);
if (slot === null)
{
console.warn("[Spine] ApplySlotColors, slot not found: ",slotName,this.uid,this.runtime.GetTickCount());
continue;
}
let color = this.slotColors[slotName];
slot.color.set(
spineBatcher.getRValue(color),
spineBatcher.getGValue(color),
spineBatcher.getBValue(color),
spineBatcher.getAValue(color));
}

// Set dark colors to slots
for(slotName in this.slotDarkColors)
{
let slot = skeleton.findSlot(slotName);
if (slot === null)
{
console.warn("[Spine] ApplySlotColors dark color, slot not found: ",slotName,this.uid,this.runtime.GetTickCount());
continue;
}
// Set only if dark Color is available, (Tint Black must be applied to the slot in the project.)
if (slot.darkColor)
{
let color = this.slotDarkColors[slotName];
slot.darkColor.set(
spineBatcher.getRValue(color),
spineBatcher.getGValue(color),
spineBatcher.getBValue(color),
spineBatcher.getAValue(color));
}
}

this.SetRenderOnce(1.0, true, this.uid);
this._applySlotColors()
},

ResetSlotColors()
Expand Down
123 changes: 123 additions & 0 deletions src/c3runtime/instance.js
Original file line number Diff line number Diff line change
Expand Up @@ -983,6 +983,119 @@
this.SetRenderOnce(1.0, true, this.uid);
}

_addCustomSkinOutfit(skinName, addOutfit, slots, dependentSlots)
{
const spine = globalThis.spine;
if (!this.skeletonInfo || !this.skeletonInfo.skeleton)
{
if (this.debug) console.warn('[Spine] AddCustomSkin, skeleton is not available',skinName,addOutfit, this.uid, this.runtime.GetTickCount());
return;
}

const skeleton = this.skeletonInfo.skeleton;

if (!this.customSkins[skinName])
{
this.customSkins[skinName] = new spine.Skin(skinName);
} else
{
this.customSkins[skinName].clear();
}

slots.forEach( slotName =>
{
let addSkinName = slotName+'/'+addOutfit[slotName].skinName;
let addSkin = skeleton.data.findSkin(addSkinName);
if (addSkin)
{
// Skin
this.customSkins[skinName].addSkin(addSkin);
if (dependentSlots[slotName])
{
let addSkinName = dependentSlots[slotName]+'/'+addOutfit[slotName].skinName;
let addSkin = skeleton.data.findSkin(addSkinName);
this.customSkins[skinName].addSkin(addSkin);
}
// Color
this.slotColors[slotName] = this._swap32(addOutfit[slotName].tintColor);
this.slotDarkColors[slotName] = this._swap32(addOutfit[slotName].tintDarkColor);
const slotRef = skeleton.findSlot(slotName)
spine.Color.rgba8888ToColor(slotRef.color, addOutfit[slotName].tintColor);
spine.Color.rgba8888ToColor(slotRef.darkColor, addOutfit[slotName].tintDarkColor);
// Dependent slots color
if (dependentSlots[slotName])
{
const slotRef = skeleton.findSlot(dependentSlots[slotName])
spine.Color.rgba8888ToColor(slotRef.color, addOutfit[slotName].tintColor);
spine.Color.rgba8888ToColor(slotRef.darkColor, addOutfit[slotName].tintDarkColor);
}
} else
{
if (this.debug) console.warn('[Spine] AddCustomSkin, add skin does not exist',skinName,addSkinName, this.uid, this.runtime.GetTickCount());
}
})
this.SetRenderOnce(1.0, true, this.uid);
}

// Unsigned swap for C3 RGBA representation
_swap32(val) {
return (((val & 0xFF) << 24)
| ((val & 0xFF00) << 8)
| ((val >>> 8) & 0xFF00)
| ((val >>> 24) & 0xFF)) >>> 0;
}

_applySlotColors()
{
if (!this.skeletonInfo || !this.skeletonInfo.skeleton)
{
if (this.debug) console.warn('[Spine] ApplySlotColors, no skeleton.', this.uid, this.runtime.GetTickCount());
return;
}

const skeleton = this.skeletonInfo.skeleton;
// Set regular colors to slots
let slotName;
for(slotName in this.slotColors)
{
let slot = skeleton.findSlot(slotName);
if (slot === null)
{
console.warn("[Spine] ApplySlotColors, slot not found: ",slotName,this.uid,this.runtime.GetTickCount());
continue;
}
let color = this.slotColors[slotName];
slot.color.set(
spineBatcher.getRValue(color),
spineBatcher.getGValue(color),
spineBatcher.getBValue(color),
spineBatcher.getAValue(color));
}

// Set dark colors to slots
for(slotName in this.slotDarkColors)
{
let slot = skeleton.findSlot(slotName);
if (slot === null)
{
console.warn("[Spine] ApplySlotColors dark color, slot not found: ",slotName,this.uid,this.runtime.GetTickCount());
continue;
}
// Set only if dark Color is available, (Tint Black must be applied to the slot in the project.)
if (slot.darkColor)
{
let color = this.slotDarkColors[slotName];
slot.darkColor.set(
spineBatcher.getRValue(color),
spineBatcher.getGValue(color),
spineBatcher.getBValue(color),
spineBatcher.getAValue(color));
console.log('darkColor, slotName', slotName, Number(this.slotDarkColors[slotName]).toString(16), spineBatcher.getRValue(color), spineBatcher.getAValue(color))
}
}

this.SetRenderOnce(1.0, true, this.uid);
}
};

// Script interface. Use a WeakMap to safely hide the internal implementation details from the
Expand Down Expand Up @@ -1034,5 +1147,15 @@
map.get(this)._deleteAnimation(trackIndex, mixDuration);
}

addCustomSkinOutfit(skinName, addOutfit, slots, dependentSlots)
{
map.get(this)._addCustomSkinOutfit(skinName, addOutfit, slots, dependentSlots);
}

applySlotColors()
{
map.get(this)._applySlotColors();
}

};
}
2 changes: 1 addition & 1 deletion src/c3runtime/spine-draw.js
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,6 @@ class SpineBatch {

if (!globalThis.spineBatcher)
{
console.log('[Spine] SpineBatcher init, 1.47.5');
console.log('[Spine] SpineBatcher init, 1.48.0');
globalThis.spineBatcher = new SpineBatch();
}
2 changes: 1 addition & 1 deletion src/plugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
const C3 = self.C3;

const PLUGIN_ID = "Gritsenko_Spine";
const PLUGIN_VERSION = "1.47.5";
const PLUGIN_VERSION = "1.48.0";
const PLUGIN_CATEGORY = "general";

const PLUGIN_CLASS = SDK.Plugins.Gritsenko_Spine = class SpinePlugin extends SDK.IPluginBase {
Expand Down

0 comments on commit 421fda0

Please sign in to comment.