Переглянути джерело

[cpp][ts] Improved test beds.

Mario Zechner 1 рік тому
батько
коміт
8a80baa0ac

+ 5 - 3
spine-sfml/cpp/example/testbed.cpp

@@ -70,11 +70,12 @@ class NullAttachmentLoader : public AttachmentLoader {
 };
 
 int main(void) {
-	String atlasFile("");
-	String skeletonFile("/Users/badlogic/workspaces/spine-runtimes/spine-haxe/example/assets/vine-pro.json");
+	String atlasFile("/Users/badlogic/Desktop/basemodel-male/basemodel-male.atlas");
+	String skeletonFile("/Users/badlogic/Desktop/basemodel-male/basemodel-male.skel");
 	String animation = "";
+    String skin = "BasicBody";
 
-	float scale = 1.0f;
+	float scale = 0.1f;
 	SFMLTextureLoader textureLoader;
 	NullAttachmentLoader nullLoader;
 	Atlas *atlas = atlasFile.length() == 0 ? nullptr : new Atlas(atlasFile, &textureLoader);
@@ -106,6 +107,7 @@ int main(void) {
     drawable.skeleton->updateWorldTransform();
 	drawable.skeleton->setPosition(320, 590);
 	if (animation.length() > 0) drawable.state->setAnimation(0, animation, true);
+    if (skin.length() > 0) drawable.skeleton->setSkin(skin);
 
 	sf::RenderWindow window(sf::VideoMode(640, 640), "Spine SFML - testbed");
 	window.setFramerateLimit(60);

+ 21 - 15
spine-ts/spine-webgl/example/drag-and-drop.html

@@ -1,21 +1,27 @@
 <html>
-<script src="../dist/iife/spine-webgl.js"></script>
-<style>
+  <script src="../dist/iife/spine-webgl.js"></script>
+  <style>
     * {
-        margin: 0;
-        padding: 0;
+      margin: 0;
+      padding: 0;
     }
-</style>
+  </style>
 
-<body>
-    <canvas id="canvas" style="position: absolute; width: 100%; height: 100%;"></canvas>
-    <div style="position: absolute; top: 1em; left: 1em; z-index: 1; color: #ccc;">
-        <label style="margin-right: 0.5em;">Animations</label>
-        <select id="animations"></select>
-        <label>PMA</label>
-        <input type="checkbox" id="pma" checked>
+  <body>
+    <canvas
+      id="canvas"
+      style="position: absolute; width: 100%; height: 100%"
+    ></canvas>
+    <div
+      style="position: absolute; top: 1em; left: 1em; z-index: 1; color: #ccc"
+    >
+      <label style="margin-right: 0.5em"> Animations</label>
+      <select id="animations"></select>
+      <label style="margin-right: 0.5em">Skins</label>
+      <select id="skins"></select>
+      <label>PMA</label>
+      <input type="checkbox" id="pma" checked />
     </div>
     <script src="drag-and-drop.js"></script>
-</body>
-
-</html>
+  </body>
+</html>

+ 261 - 197
spine-ts/spine-webgl/example/drag-and-drop.js

@@ -1,230 +1,294 @@
 class App {
-    constructor() {
-        this.skeleton = null;
-        this.animationState = null;
-        this.canvas = null;
-        this.pma = true;
-    }
+  constructor() {
+    this.skeleton = null;
+    this.animationState = null;
+    this.canvas = null;
+    this.pma = true;
+  }
 
-    loadAssets(canvas) {
-        this.canvas = canvas;
+  loadAssets(canvas) {
+    this.canvas = canvas;
 
-        // Load assets of Spineboy.
-        canvas.assetManager.loadBinary("assets/spineboy-pro.skel");
-        canvas.assetManager.loadTextureAtlas("assets/spineboy-pma.atlas");
-    }
+    // Load assets of Spineboy.
+    canvas.assetManager.loadBinary("assets/spineboy-pro.skel");
+    canvas.assetManager.loadTextureAtlas("assets/spineboy-pma.atlas");
+  }
 
-    initialize(canvas) {
-        // Load the Spineboy skeleton
-        this.loadSkeleton("assets/spineboy-pro.skel", "assets/spineboy-pma.atlas", "run");
+  initialize(canvas) {
+    // Load the Spineboy skeleton
+    this.loadSkeleton(
+      "assets/spineboy-pro.skel",
+      "assets/spineboy-pma.atlas",
+      "run"
+    );
 
-        // Setup listener for animation selection box
-        let animationSelectBox = document.body.querySelector("#animations");
-        animationSelectBox.onchange = () => {
-            this.animationState.setAnimation(0, animationSelectBox.value, true);
-        }
+    // Setup listener for animation selection box
+    let animationSelectBox = document.body.querySelector("#animations");
+    animationSelectBox.onchange = () => {
+      this.animationState.setAnimation(0, animationSelectBox.value, true);
+    };
 
-        // Setup listener for the PMA checkbox
-        let pmaCheckbox = document.body.querySelector("#pma");
-        pmaCheckbox.onchange = () => {
-            this.pma = pmaCheckbox.checked;
-        }
+    // Setup listener for skin selection box
+    let skinSelectBox = document.body.querySelector("#skins");
+    skinSelectBox.onchange = () => {
+      this.skeleton.setSkinByName(skinSelectBox.value);
+    };
 
-        // Setup the drag and drop listener
-        new FileDragAndDrop(canvas.htmlCanvas, (files) => this.onDrop(files))
+    // Setup listener for the PMA checkbox
+    let pmaCheckbox = document.body.querySelector("#pma");
+    pmaCheckbox.onchange = () => {
+      this.pma = pmaCheckbox.checked;
+    };
 
-        // Setup a camera controller for paning and zooming
-        new spine.CameraController(canvas.htmlCanvas, canvas.renderer.camera);
-    }
+    // Setup the drag and drop listener
+    new FileDragAndDrop(canvas.htmlCanvas, (files) => this.onDrop(files));
+
+    // Setup a camera controller for paning and zooming
+    new spine.CameraController(canvas.htmlCanvas, canvas.renderer.camera);
+  }
+
+  onDrop(files) {
+    let atlasFile;
+    let skeletonFile;
+    let pngs = [];
+    let assetManager = this.canvas.assetManager;
+
+    // We use data URIs to load the dropped files. Some file types
+    // are binary, so we have to encode them to base64 for loading
+    // through AssetManager.
+    let bufferToBase64 = (buffer) => {
+      var binary = "";
+      var bytes = new Uint8Array(buffer);
+      var len = bytes.byteLength;
+      for (var i = 0; i < len; i++) {
+        binary += String.fromCharCode(bytes[i]);
+      }
+      return window.btoa(binary);
+    };
 
-    onDrop(files) {
-        let atlasFile;
-        let skeletonFile;
-        let pngs = [];
-        let assetManager = this.canvas.assetManager;
-
-        // We use data URIs to load the dropped files. Some file types
-        // are binary, so we have to encode them to base64 for loading
-        // through AssetManager.
-        let bufferToBase64 = (buffer) => {
-            var binary = '';
-            var bytes = new Uint8Array(buffer);
-            var len = bytes.byteLength;
-            for (var i = 0; i < len; i++) {
-                binary += String.fromCharCode(bytes[i]);
-            }
-            return window.btoa(binary);
-        }
-
-        for (var file of files) {
-            if (file.name.endsWith(".atlas") || file.name.endsWith(".atlas.txt")) {
-                atlasFile = file;
-                assetManager.setRawDataURI(file.name, "data:text/plain;," + file.contentText);
-            } else if (file.name.endsWith(".skel")) {
-                skeletonFile = file;
-                assetManager.setRawDataURI(file.name, "data:application/octet-stream;base64," + bufferToBase64(file.contentBinary));
-                assetManager.loadBinary(file.name);
-            } else if (file.name.endsWith(".json")) {
-                skeletonFile = file;
-                assetManager.setRawDataURI(file.name, "data:text/plain;," + file.contentText);
-                assetManager.loadJson(file.name);
-            } else if (file.name.endsWith(".png")) {
-                pngs.push(file);
-                assetManager.setRawDataURI(file.name, "data:image/png;base64," + bufferToBase64(file.contentBinary));
-            }
-        }
-
-        if (!atlasFile) {
-            alert("Please provide a .atlas or .atlas.txt atlas file.");
-            return;
-        }
-        if (pngs.length == 0) {
-            alert("Please provide the atlas page .png file(s).");
-        }
-        if (!skeletonFile) {
-            alert("Please provide a .skel or .json skeleton file.");
-            return;
-        }
-
-        assetManager.loadTextureAtlas(atlasFile.name);
-
-        let waitForLoad = () => {
-            if (this.canvas.assetManager.isLoadingComplete()) {
-                this.loadSkeleton(skeletonFile.name, atlasFile.name);
-            } else {
-                requestAnimationFrame(waitForLoad);
-            }
-        }
-        waitForLoad();
+    for (var file of files) {
+      if (file.name.endsWith(".atlas") || file.name.endsWith(".atlas.txt")) {
+        atlasFile = file;
+        assetManager.setRawDataURI(
+          file.name,
+          "data:text/plain;," + file.contentText
+        );
+      } else if (file.name.endsWith(".skel")) {
+        skeletonFile = file;
+        assetManager.setRawDataURI(
+          file.name,
+          "data:application/octet-stream;base64," +
+            bufferToBase64(file.contentBinary)
+        );
+        assetManager.loadBinary(file.name);
+      } else if (file.name.endsWith(".json")) {
+        skeletonFile = file;
+        assetManager.setRawDataURI(
+          file.name,
+          "data:text/plain;," + file.contentText
+        );
+        assetManager.loadJson(file.name);
+      } else if (file.name.endsWith(".png")) {
+        pngs.push(file);
+        assetManager.setRawDataURI(
+          file.name,
+          "data:image/png;base64," + bufferToBase64(file.contentBinary)
+        );
+      }
     }
 
-    loadSkeleton(skeletonFile, atlasFile, animationName) {
-        // Load the skeleton and setup the animation state
-        let assetManager = this.canvas.assetManager;
-        var atlas = assetManager.require(atlasFile);
-        var atlasLoader = new spine.AtlasAttachmentLoader(atlas);
-        var skeletonData;
-        var skeletonBinaryOrJson = skeletonFile.endsWith(".skel") ?
-            new spine.SkeletonBinary(atlasLoader) :
-            new spine.SkeletonJson(atlasLoader);
-        skeletonBinaryOrJson.scale = 1;
-        skeletonData = skeletonBinaryOrJson.readSkeletonData(assetManager.require(skeletonFile));
-        this.skeleton = new spine.Skeleton(skeletonData);
-        var animationStateData = new spine.AnimationStateData(skeletonData);
-        this.animationState = new spine.AnimationState(animationStateData);
-
-        // Fill the animation selection box.
-        let animationSelectBox = document.body.querySelector("#animations");
-        animationSelectBox.innerHTML = "";
-        for (var animation of this.skeleton.data.animations) {
-            if (!animationName) animationName = animation.name;
-            let option = document.createElement("option");
-            option.value = option.innerText = animation.name;
-            option.selected = animation.name == animationName;
-            animationSelectBox.appendChild(option);
-        }
-        this.animationState.setAnimation(0, animationName, true);
-
-        // Center the skeleton in the viewport
-        this.centerSkeleton();
+    if (!atlasFile) {
+      alert("Please provide a .atlas or .atlas.txt atlas file.");
+      return;
     }
+    if (pngs.length == 0) {
+      alert("Please provide the atlas page .png file(s).");
+    }
+    if (!skeletonFile) {
+      alert("Please provide a .skel or .json skeleton file.");
+      return;
+    }
+
+    assetManager.loadTextureAtlas(atlasFile.name);
 
-    centerSkeleton() {
-        // Calculate the bounds of the skeleton
-        this.animationState.update(0);
-        this.animationState.apply(this.skeleton);
-        this.skeleton.updateWorldTransform();
-        let offset = new spine.Vector2(), size = new spine.Vector2();
-        this.skeleton.getBounds(offset, size);
-
-        // Make sure the canvas is sized properly and position and zoom
-        // the camera so the skeleton is centered in the viewport.
-        let renderer = this.canvas.renderer;
-        renderer.resize(spine.ResizeMode.Expand);
-        let camera = this.canvas.renderer.camera;
-        camera.position.x = offset.x + size.x / 2;
-        camera.position.y = offset.y + size.y / 2;
-        camera.zoom = size.x > size.y ? size.x / this.canvas.htmlCanvas.width * 3 : size.y / this.canvas.htmlCanvas.height * 3;
-        camera.update();
+    let waitForLoad = () => {
+      if (this.canvas.assetManager.isLoadingComplete()) {
+        this.loadSkeleton(skeletonFile.name, atlasFile.name);
+      } else {
+        requestAnimationFrame(waitForLoad);
+      }
+    };
+    waitForLoad();
+  }
+
+  loadSkeleton(skeletonFile, atlasFile, animationName) {
+    // Load the skeleton and setup the animation state
+    let assetManager = this.canvas.assetManager;
+    var atlas = assetManager.require(atlasFile);
+    var atlasLoader = new spine.AtlasAttachmentLoader(atlas);
+    var skeletonData;
+    var skeletonBinaryOrJson = skeletonFile.endsWith(".skel")
+      ? new spine.SkeletonBinary(atlasLoader)
+      : new spine.SkeletonJson(atlasLoader);
+    skeletonBinaryOrJson.scale = 1;
+    skeletonData = skeletonBinaryOrJson.readSkeletonData(
+      assetManager.require(skeletonFile)
+    );
+    this.skeleton = new spine.Skeleton(skeletonData);
+    var animationStateData = new spine.AnimationStateData(skeletonData);
+    this.animationState = new spine.AnimationState(animationStateData);
+
+    // Fill the animation selection box.
+    let animationSelectBox = document.body.querySelector("#animations");
+    animationSelectBox.innerHTML = "";
+    for (var animation of this.skeleton.data.animations) {
+      if (!animationName) animationName = animation.name;
+      let option = document.createElement("option");
+      option.value = option.innerText = animation.name;
+      option.selected = animation.name == animationName;
+      animationSelectBox.appendChild(option);
     }
+    this.animationState.setAnimation(0, animationName, true);
 
-    update(canvas, delta) {
-        this.animationState.update(delta);
-        this.animationState.apply(this.skeleton);
-        this.skeleton.updateWorldTransform();
+    // Fill the skin selection box.
+    let skinSelectBox = document.body.querySelector("#skins");
+    skinSelectBox.innerHTML = "";
+    for (var skin of this.skeleton.data.skins) {
+      let option = document.createElement("option");
+      option.value = option.innerText = skin.name;
+      skinSelectBox.appendChild(option);
+    }
+    if (
+      !this.skeleton.data.defaultSkin ||
+      (this.skeleton.data.defaultSkin.attachments.length == 0 &&
+        this.skeleton.data.skins.length > 1)
+    ) {
+      this.skeleton.setSkin(this.skeleton.data.skins[0]);
     }
 
-    render(canvas) {
-        let renderer = canvas.renderer;
-        renderer.resize(spine.ResizeMode.Expand);
+    // Center the skeleton in the viewport
+    this.centerSkeleton();
+  }
 
-        canvas.clear(0.2, 0.2, 0.2, 1);
+  centerSkeleton() {
+    // Calculate the bounds of the skeleton
+    this.animationState.update(0);
+    this.animationState.apply(this.skeleton);
+    this.skeleton.updateWorldTransform();
+    let offset = new spine.Vector2(),
+      size = new spine.Vector2();
+    this.skeleton.getBounds(offset, size);
 
-        renderer.begin();
-        renderer.line(-10000, 0, 10000, 0, spine.Color.RED);
-        renderer.line(0, -10000, 0, 10000, spine.Color.GREEN);
-        renderer.drawSkeleton(this.skeleton, this.pma);
-        renderer.end();
+    let camera = this.canvas.renderer.camera;
+    let renderer = this.canvas.renderer;
+    renderer.resize(spine.ResizeMode.Expand);
+    if (
+      !Number.isFinite(size.x) ||
+      !Number.isFinite(size.y) ||
+      !Number.isFinite(offset.x) ||
+      !Number.isFinite(offset.y)
+    ) {
+      camera.position.x = 0;
+      camera.position.y = 0;
+      camera.zoom = 1;
+      camera.update();
+      return;
     }
+
+    // Make sure the canvas is sized properly and position and zoom
+    // the camera so the skeleton is centered in the viewport.
+    camera.position.x = offset.x + size.x / 2;
+    camera.position.y = offset.y + size.y / 2;
+    camera.zoom =
+      size.x > size.y
+        ? (size.x / this.canvas.htmlCanvas.width) * 3
+        : (size.y / this.canvas.htmlCanvas.height) * 3;
+    camera.update();
+  }
+
+  update(canvas, delta) {
+    this.animationState.update(delta);
+    this.animationState.apply(this.skeleton);
+    this.skeleton.updateWorldTransform();
+  }
+
+  render(canvas) {
+    let renderer = canvas.renderer;
+    renderer.resize(spine.ResizeMode.Expand);
+
+    canvas.clear(0.2, 0.2, 0.2, 1);
+
+    renderer.begin();
+    renderer.line(-10000, 0, 10000, 0, spine.Color.RED);
+    renderer.line(0, -10000, 0, 10000, spine.Color.GREEN);
+    renderer.drawSkeleton(this.skeleton, this.pma);
+    renderer.end();
+  }
 }
 
 new spine.SpineCanvas(document.getElementById("canvas"), {
-    app: new App(),
-    webglConfig: {
-        alpha: false
-    }
+  app: new App(),
+  webglConfig: {
+    alpha: false,
+  },
 });
 
 class FileDragAndDrop {
-    constructor(element, callback) {
-        this.callback = callback;
-        element.ondrop = (ev) => this.onDrop(ev);
-        element.ondragover = (ev) => ev.preventDefault();
-    }
+  constructor(element, callback) {
+    this.callback = callback;
+    element.ondrop = (ev) => this.onDrop(ev);
+    element.ondragover = (ev) => ev.preventDefault();
+  }
 
-    async onDrop(event) {
-        event.preventDefault();
-        event.stopPropagation();
-
-        const items = Object.keys(event.dataTransfer.items);
-        let files = [];
-        await Promise.all(items.map(async (key) => {
-            var file = event.dataTransfer.items[key].getAsFile();
-            if (file.kind == "string") return;
-            let contentBinary = await file.arrayBuffer();
-            let contentText = await file.text();
-            files.push({ name: file.name, contentBinary: contentBinary, contentText: contentText });
-        }));
-        this.callback(files);
-    }
+  async onDrop(event) {
+    event.preventDefault();
+    event.stopPropagation();
+
+    const items = Object.keys(event.dataTransfer.items);
+    let files = [];
+    await Promise.all(
+      items.map(async (key) => {
+        var file = event.dataTransfer.items[key].getAsFile();
+        if (file.kind == "string") return;
+        let contentBinary = await file.arrayBuffer();
+        let contentText = await file.text();
+        files.push({
+          name: file.name,
+          contentBinary: contentBinary,
+          contentText: contentText,
+        });
+      })
+    );
+    this.callback(files);
+  }
 }
 
 // Shim for older browsers for File/Blob.arrayBuffer() and .text()
 (function () {
-    function arrayBuffer() {
-        return new Promise(function () {
-            let fr = new FileReader();
-            fr.onload = () => {
-                resolve(fr.result);
-            };
-            fr.readAsArrayBuffer();
-        })
-    }
+  function arrayBuffer() {
+    return new Promise(function () {
+      let fr = new FileReader();
+      fr.onload = () => {
+        resolve(fr.result);
+      };
+      fr.readAsArrayBuffer();
+    });
+  }
 
-    function text() {
-        return new Promise(function () {
-            let fr = new FileReader();
-            fr.onload = () => {
-                resolve(fr.result);
-            };
-            fr.readAsText(this);
-        })
-    }
+  function text() {
+    return new Promise(function () {
+      let fr = new FileReader();
+      fr.onload = () => {
+        resolve(fr.result);
+      };
+      fr.readAsText(this);
+    });
+  }
 
-    if ('File' in self) {
-        File.prototype.arrayBuffer = File.prototype.arrayBuffer || arrayBuffer;
-        File.prototype.text = File.prototype.text || text;
-    }
-    Blob.prototype.arrayBuffer = Blob.prototype.arrayBuffer || arrayBuffer;
-    Blob.prototype.text = Blob.prototype.text || text;
-})();
+  if ("File" in self) {
+    File.prototype.arrayBuffer = File.prototype.arrayBuffer || arrayBuffer;
+    File.prototype.text = File.prototype.text || text;
+  }
+  Blob.prototype.arrayBuffer = Blob.prototype.arrayBuffer || arrayBuffer;
+  Blob.prototype.text = Blob.prototype.text || text;
+})();