[ts] THREE.JS backend, revised batching using interleaved buffers, WIP

This commit is contained in:
badlogic 2016-08-17 16:04:27 +02:00
parent 8536f210ce
commit b9afff01fd
8 changed files with 3105 additions and 1 deletions

View File

@ -11,7 +11,7 @@ module spine {
}
abstract setFilters (minFilter: TextureFilter, magFilter: TextureFilter): void;
abstract setWraps (uWrap: TextureWrap, vWrap: TextureWrap): void;
abstract setWraps (uWrap: TextureWrap, vWrap: TextureWrap): void;
abstract dispose (): void;

View File

@ -0,0 +1,279 @@
raptor.png
size: 1024,1024
format: RGBA8888
filter: Linear,Linear
repeat: none
back_arm
rotate: true
xy: 140, 191
size: 46, 29
orig: 46, 29
offset: 0, 0
index: -1
back_bracer
rotate: true
xy: 167, 317
size: 39, 28
orig: 39, 28
offset: 0, 0
index: -1
back_hand
rotate: false
xy: 167, 358
size: 36, 34
orig: 36, 34
offset: 0, 0
index: -1
back_knee
rotate: false
xy: 299, 478
size: 49, 67
orig: 49, 67
offset: 0, 0
index: -1
back_thigh
rotate: true
xy: 167, 437
size: 39, 24
orig: 39, 24
offset: 0, 0
index: -1
eyes_closed
rotate: true
xy: 2, 2
size: 47, 45
orig: 47, 45
offset: 0, 0
index: -1
eyes_open
rotate: true
xy: 49, 2
size: 47, 45
orig: 47, 45
offset: 0, 0
index: -1
eyes_surprised
rotate: true
xy: 96, 2
size: 47, 45
orig: 47, 45
offset: 0, 0
index: -1
front_arm
rotate: false
xy: 419, 544
size: 48, 30
orig: 48, 30
offset: 0, 0
index: -1
front_bracer
rotate: false
xy: 880, 695
size: 41, 29
orig: 41, 29
offset: 0, 0
index: -1
front_hand
rotate: true
xy: 167, 394
size: 41, 38
orig: 41, 38
offset: 0, 0
index: -1
front_open_hand
rotate: false
xy: 880, 726
size: 43, 44
orig: 43, 44
offset: 0, 0
index: -1
front_thigh
rotate: false
xy: 360, 545
size: 57, 29
orig: 57, 29
offset: 0, 0
index: -1
gun
rotate: false
xy: 785, 774
size: 107, 103
orig: 107, 103
offset: 0, 0
index: -1
gun_nohand
rotate: false
xy: 614, 703
size: 105, 102
orig: 105, 102
offset: 0, 0
index: -1
head
rotate: false
xy: 2, 137
size: 136, 149
orig: 136, 149
offset: 0, 0
index: -1
lower_leg
rotate: true
xy: 780, 699
size: 73, 98
orig: 73, 98
offset: 0, 0
index: -1
mouth_grind
rotate: false
xy: 469, 544
size: 47, 30
orig: 47, 30
offset: 0, 0
index: -1
mouth_oooo
rotate: true
xy: 894, 772
size: 105, 30
orig: 105, 30
offset: 0, 0
index: -1
mouth_smile
rotate: true
xy: 140, 239
size: 47, 30
orig: 47, 30
offset: 0, 0
index: -1
neck
rotate: true
xy: 538, 577
size: 18, 21
orig: 18, 21
offset: 0, 0
index: -1
raptor_arm_back
rotate: false
xy: 940, 936
size: 82, 86
orig: 82, 86
offset: 0, 0
index: -1
raptor_body
rotate: false
xy: 2, 737
size: 610, 285
orig: 610, 285
offset: 0, 0
index: -1
raptor_front_arm
rotate: true
xy: 195, 464
size: 81, 102
orig: 81, 102
offset: 0, 0
index: -1
raptor_front_leg
rotate: false
xy: 2, 478
size: 191, 257
orig: 191, 257
offset: 0, 0
index: -1
raptor_hindleg_back
rotate: false
xy: 614, 807
size: 169, 215
orig: 169, 215
offset: 0, 0
index: -1
raptor_horn
rotate: false
xy: 360, 655
size: 182, 80
orig: 182, 80
offset: 0, 0
index: -1
raptor_horn_back
rotate: false
xy: 360, 576
size: 176, 77
orig: 176, 77
offset: 0, 0
index: -1
raptor_jaw
rotate: false
xy: 785, 879
size: 153, 143
orig: 153, 143
offset: 0, 0
index: -1
raptor_saddle_noshadow
rotate: false
xy: 2, 288
size: 163, 188
orig: 163, 188
offset: 0, 0
index: -1
raptor_saddle_strap_front
rotate: false
xy: 721, 710
size: 57, 95
orig: 57, 95
offset: 0, 0
index: -1
raptor_saddle_strap_rear
rotate: true
xy: 940, 880
size: 54, 74
orig: 54, 74
offset: 0, 0
index: -1
raptor_saddle_w_shadow
rotate: false
xy: 195, 547
size: 163, 188
orig: 163, 188
offset: 0, 0
index: -1
raptor_tongue
rotate: true
xy: 544, 649
size: 86, 64
orig: 86, 64
offset: 0, 0
index: -1
stirrup_back
rotate: true
xy: 140, 145
size: 44, 35
orig: 44, 35
offset: 0, 0
index: -1
stirrup_front
rotate: false
xy: 538, 597
size: 45, 50
orig: 45, 50
offset: 0, 0
index: -1
stirrup_strap
rotate: false
xy: 350, 497
size: 49, 46
orig: 49, 46
offset: 0, 0
index: -1
torso
rotate: true
xy: 610, 647
size: 54, 91
orig: 54, 91
offset: 0, 0
index: -1
visor
rotate: false
xy: 2, 51
size: 131, 84
orig: 131, 84
offset: 0, 0
index: -1

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 495 KiB

View File

@ -0,0 +1,102 @@
<html>
<head>
<meta charset="UTF-8">
<title>spine-threejs</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r79/three.js"></script>
<script src="../../build/spine-threejs.js"></script>
<style>body, input { font-family: tahoma; font-size: 11pt }</style>
</head>
<body>
<script>
var scene, camera, renderer;
var geometry, material, mesh, skeletonMesh;
var assetManager;
var lastFrameTime = Date.now();
function init () {
scene = new THREE.Scene();
var width = 640, height = 480;
camera = new THREE.PerspectiveCamera(75, width / height, 1, 3000);
camera.position.z = 400;
geometry = new THREE.BoxGeometry(200, 200, 200);
material = new THREE.MeshBasicMaterial({ color: 0xff0000, wireframe: true });
mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);
renderer = new THREE.WebGLRenderer();
renderer.setSize(width, height);
document.body.appendChild(renderer.domElement);
assetManager = new spine.threejs.AssetManager();
assetManager.loadText("assets/raptor.json");
assetManager.loadText("assets/raptor.atlas");
assetManager.loadTexture("assets/raptor.png");
requestAnimationFrame(load);
}
function load (name, scale) {
if (assetManager.isLoadingComplete()) {
// Load the texture atlas using name.atlas and name.png from the AssetManager.
// The function passed to TextureAtlas is used to resolve relative paths.
atlas = new spine.TextureAtlas(assetManager.get("assets/raptor.atlas"), function(path) {
return assetManager.get("assets/" + path);
});
var skeletonData = loadSkeleton("raptor", 0.4);
skeletonMesh = new spine.threejs.SkeletonMesh(skeletonData);
skeletonMesh.state.setAnimation(0, "walk", true);
mesh.add(skeletonMesh);
requestAnimationFrame(render);
} else requestAnimationFrame(load);
}
function loadSkeleton (name, scale) {
// Load the texture atlas using name.atlas and name.png from the AssetManager.
// The function passed to TextureAtlas is used to resolve relative paths.
atlas = new spine.TextureAtlas(assetManager.get("assets/" + name + ".atlas"), function(path) {
return assetManager.get("assets/" + path);
});
// Create a TextureAtlasAttachmentLoader that resolves region, mesh, boundingbox and path attachments
atlasLoader = new spine.TextureAtlasAttachmentLoader(atlas);
// Create a SkeletonJson instance for parsing the .json file.
var skeletonJson = new spine.SkeletonJson(atlasLoader);
// Set the scale to apply during parsing, parse the file, and create a new skeleton.
skeletonJson.scale = scale;
var skeletonData = skeletonJson.readSkeletonData(assetManager.get("assets/" + name + ".json"));
return skeletonData;
}
var lastTime = Date.now();
function render() {
var now = Date.now() / 1000;
var delta = now - lastFrameTime;
lastFrameTime = now;
var a = Math.sin(now);
var b = Math.cos(now);
mesh.rotation.x = a * Math.PI * 0.2;
mesh.rotation.y = b * Math.PI * 0.4;
skeletonMesh.update(delta);
renderer.render(scene, camera);
requestAnimationFrame(render);
}
(function() {
init();
}());
</script>
</body>
</html>

View File

@ -0,0 +1,9 @@
module spine.threejs {
export class AssetManager extends spine.AssetManager {
constructor () {
super((image: HTMLImageElement) => {
return new ThreeJsTexture(image);
});
}
}
}

View File

@ -0,0 +1,51 @@
module spine.threejs {
export class SkeletonMesh extends THREE.Mesh {
skeleton: Skeleton;
state: AnimationState;
private _vertexBuffer: THREE.InterleavedBuffer;
constructor (skeletonData: SkeletonData) {
super();
this.skeleton = new Skeleton(skeletonData);
let animData = new AnimationStateData(skeletonData);
this.state = new AnimationState(animData);
this.material = new THREE.MeshBasicMaterial();
this.material.vertexColors = THREE.VertexColors;
let geometry: THREE.BufferGeometry = this.geometry = new THREE.BufferGeometry();
let vertexBuffer = this._vertexBuffer = new THREE.InterleavedBuffer(new Float32Array(8 * 3 * 10920), 8);
vertexBuffer.setDynamic(true);
geometry.addAttribute("position", new THREE.InterleavedBufferAttribute(vertexBuffer, 2, 0, false));
geometry.addAttribute("color", new THREE.InterleavedBufferAttribute(vertexBuffer, 4, 2, false));
geometry.addAttribute("uv", new THREE.InterleavedBufferAttribute(vertexBuffer, 2, 6, false));
let indexBuffer = new Uint16Array(3 * 10920);
geometry.setIndex(new THREE.BufferAttribute(indexBuffer, 1));
geometry.getIndex().dynamic = true;
this.update(0);
}
update(deltaTime: number) {
let state = this.state;
let skeleton = this.skeleton;
state.update(deltaTime);
state.apply(skeleton);
skeleton.updateWorldTransform();
this.updateGeometry();
}
private updateGeometry() {
let geometry = <THREE.BufferGeometry>this.geometry;
geometry.drawRange.start = 0;
geometry.drawRange.count = 0;
this._vertexBuffer.needsUpdate = true;
geometry.getIndex().needsUpdate = true;
}
}
}

View File

@ -0,0 +1,42 @@
module spine.threejs {
export class ThreeJsTexture extends Texture {
texture: THREE.Texture;
constructor (image: HTMLImageElement) {
super(image);
this.texture = new THREE.Texture(image);
}
setFilters (minFilter: TextureFilter, magFilter: TextureFilter) {
this.texture.minFilter = ThreeJsTexture.toThreeJsTextureFilter(minFilter);
this.texture.magFilter = ThreeJsTexture.toThreeJsTextureFilter(magFilter);
}
setWraps (uWrap: TextureWrap, vWrap: TextureWrap) {
this.texture.wrapS = ThreeJsTexture.toThreeJsTextureWrap(uWrap);
this.texture.wrapT = ThreeJsTexture.toThreeJsTextureWrap(vWrap);
}
dispose () {
this.texture.dispose();
}
static toThreeJsTextureFilter(filter: TextureFilter) {
if (filter === TextureFilter.Linear) return THREE.LinearFilter;
else if (filter === TextureFilter.MipMap) return THREE.LinearMipMapLinearFilter;
else if (filter === TextureFilter.MipMapLinearLinear) return THREE.LinearMipMapLinearFilter;
else if (filter === TextureFilter.MipMapLinearNearest) return THREE.LinearMipMapNearestFilter;
else if (filter === TextureFilter.MipMapNearestLinear) return THREE.NearestMipMapLinearFilter;
else if (filter === TextureFilter.MipMapNearestNearest) return THREE.NearestMipMapNearestFilter;
else if (filter === TextureFilter.Nearest) return THREE.NearestFilter;
else throw new Error("Unknown texture filter: " + filter);
}
static toThreeJsTextureWrap(wrap: TextureWrap) {
if (wrap === TextureWrap.ClampToEdge) return THREE.ClampToEdgeWrapping;
else if (wrap === TextureWrap.MirroredRepeat) return THREE.MirroredRepeatWrapping;
else if (wrap === TextureWrap.Repeat) return THREE.RepeatWrapping;
else throw new Error("Unknown texture wrap: " + wrap);
}
}
}