[ts][threejs] Fixed THREE.JS integration, including z-offset against z-fighting. Tinting, blending modes and premultiplied alpha still to do.

This commit is contained in:
badlogic 2016-08-18 12:33:29 +02:00
parent 144500d7e8
commit 5b4af038b8
10 changed files with 5947 additions and 43 deletions

View File

@ -899,6 +899,50 @@ declare module spine {
updateWorldVertices(slot: Slot, premultipliedAlpha: boolean): ArrayLike<number>;
}
}
declare module spine.threejs {
class AssetManager extends spine.AssetManager {
constructor();
}
}
declare module spine.threejs {
class MeshBatcher {
mesh: THREE.Mesh;
private static VERTEX_SIZE;
private _vertexBuffer;
private _vertices;
private _verticesLength;
private _indices;
private _indicesLength;
constructor(mesh: THREE.Mesh, maxVertices?: number);
begin(): void;
batch(vertices: ArrayLike<number>, indices: ArrayLike<number>, z?: number): void;
end(): void;
}
}
declare module spine.threejs {
class SkeletonMesh extends THREE.Mesh {
skeleton: Skeleton;
state: AnimationState;
zOffset: number;
private _batcher;
static QUAD_TRIANGLES: number[];
constructor(skeletonData: SkeletonData);
update(deltaTime: number): void;
private updateGeometry();
static createMesh(map: THREE.Texture): THREE.Mesh;
}
}
declare module spine.threejs {
class ThreeJsTexture extends Texture {
texture: THREE.Texture;
constructor(image: HTMLImageElement);
setFilters(minFilter: TextureFilter, magFilter: TextureFilter): void;
setWraps(uWrap: TextureWrap, vWrap: TextureWrap): void;
dispose(): void;
static toThreeJsTextureFilter(filter: TextureFilter): THREE.TextureFilter;
static toThreeJsTextureWrap(wrap: TextureWrap): THREE.Wrapping;
}
}
declare module spine.webgl {
class AssetManager extends spine.AssetManager {
constructor(gl: WebGLRenderingContext);

View File

@ -4530,6 +4530,251 @@ var spine;
spine.RegionAttachment = RegionAttachment;
})(spine || (spine = {}));
var spine;
(function (spine) {
var threejs;
(function (threejs) {
var AssetManager = (function (_super) {
__extends(AssetManager, _super);
function AssetManager() {
_super.call(this, function (image) {
return new threejs.ThreeJsTexture(image);
});
}
return AssetManager;
}(spine.AssetManager));
threejs.AssetManager = AssetManager;
})(threejs = spine.threejs || (spine.threejs = {}));
})(spine || (spine = {}));
var spine;
(function (spine) {
var threejs;
(function (threejs) {
var MeshBatcher = (function () {
function MeshBatcher(mesh, maxVertices) {
if (maxVertices === void 0) { maxVertices = 10920; }
this._verticesLength = 0;
this._indicesLength = 0;
if (maxVertices > 10920)
throw new Error("Can't have more than 10920 triangles per batch: " + maxVertices);
var vertices = this._vertices = new Float32Array(maxVertices * MeshBatcher.VERTEX_SIZE);
var indices = this._indices = new Uint16Array(maxVertices * 3);
this.mesh = mesh;
var geo = new THREE.BufferGeometry();
var vertexBuffer = this._vertexBuffer = new THREE.InterleavedBuffer(vertices, MeshBatcher.VERTEX_SIZE);
vertexBuffer.dynamic = true;
geo.addAttribute("position", new THREE.InterleavedBufferAttribute(vertexBuffer, 3, 0, false));
geo.addAttribute("color", new THREE.InterleavedBufferAttribute(vertexBuffer, 4, 3, false));
geo.addAttribute("uv", new THREE.InterleavedBufferAttribute(vertexBuffer, 2, 7, false));
geo.setIndex(new THREE.BufferAttribute(indices, 1));
geo.getIndex().dynamic = true;
geo.drawRange.start = 0;
geo.drawRange.count = 0;
mesh.geometry = geo;
}
MeshBatcher.prototype.begin = function () {
this._verticesLength = 0;
this._indicesLength = 0;
};
MeshBatcher.prototype.batch = function (vertices, indices, z) {
if (z === void 0) { z = 0; }
var indexStart = this._verticesLength / MeshBatcher.VERTEX_SIZE;
var vertexBuffer = this._vertices;
var i = this._verticesLength;
var j = 0;
for (; j < vertices.length;) {
vertexBuffer[i++] = vertices[j++];
vertexBuffer[i++] = vertices[j++];
vertexBuffer[i++] = z;
vertexBuffer[i++] = vertices[j++];
vertexBuffer[i++] = vertices[j++];
vertexBuffer[i++] = vertices[j++];
vertexBuffer[i++] = vertices[j++];
vertexBuffer[i++] = vertices[j++];
vertexBuffer[i++] = vertices[j++];
}
this._verticesLength = i;
var indicesArray = this._indices;
for (i = this._indicesLength, j = 0; j < indices.length; i++, j++)
indicesArray[i] = indices[j] + indexStart;
this._indicesLength += indices.length;
};
MeshBatcher.prototype.end = function () {
this._vertexBuffer.needsUpdate = true;
this._vertexBuffer.updateRange.offset = 0;
this._vertexBuffer.updateRange.count = this._verticesLength;
var geo = this.mesh.geometry;
geo.getIndex().needsUpdate = true;
geo.getIndex().updateRange.offset = 0;
geo.getIndex().updateRange.count = this._indicesLength;
geo.drawRange.start = 0;
geo.drawRange.count = this._indicesLength;
};
MeshBatcher.VERTEX_SIZE = 9;
return MeshBatcher;
}());
threejs.MeshBatcher = MeshBatcher;
})(threejs = spine.threejs || (spine.threejs = {}));
})(spine || (spine = {}));
var spine;
(function (spine) {
var threejs;
(function (threejs) {
var SkeletonMesh = (function (_super) {
__extends(SkeletonMesh, _super);
function SkeletonMesh(skeletonData) {
_super.call(this);
this.zOffset = 0.1;
this.skeleton = new spine.Skeleton(skeletonData);
var animData = new spine.AnimationStateData(skeletonData);
this.state = new spine.AnimationState(animData);
var material = this.material = new THREE.MeshBasicMaterial();
material.side = THREE.DoubleSide;
material.transparent = true;
material.alphaTest = 0.5;
this._batcher = new threejs.MeshBatcher(this);
}
SkeletonMesh.prototype.update = function (deltaTime) {
var state = this.state;
var skeleton = this.skeleton;
state.update(deltaTime);
state.apply(skeleton);
skeleton.updateWorldTransform();
this.updateGeometry();
};
SkeletonMesh.prototype.updateGeometry = function () {
var geometry = this.geometry;
var numVertices = 0;
var verticesLength = 0;
var indicesLength = 0;
var blendMode = null;
var vertices = null;
var triangles = null;
var drawOrder = this.skeleton.drawOrder;
var batcher = this._batcher;
batcher.begin();
var z = 0;
var zOffset = this.zOffset;
for (var i = 0, n = drawOrder.length; i < n; i++) {
var slot = drawOrder[i];
var attachment = slot.getAttachment();
var texture = null;
if (attachment instanceof spine.RegionAttachment) {
var region = attachment;
vertices = region.updateWorldVertices(slot, false);
triangles = SkeletonMesh.QUAD_TRIANGLES;
texture = region.region.renderObject.texture;
}
else if (attachment instanceof spine.MeshAttachment) {
var mesh = attachment;
vertices = mesh.updateWorldVertices(slot, false);
triangles = mesh.triangles;
texture = mesh.region.renderObject.texture;
}
else
continue;
if (texture != null) {
if (!this.material.map) {
var mat = this.material;
mat.map = texture.texture;
mat.needsUpdate = true;
}
this._batcher.batch(vertices, triangles, z);
z += zOffset;
}
}
batcher.end();
};
SkeletonMesh.createMesh = function (map) {
var geo = new THREE.BufferGeometry();
var vertices = new Float32Array(1024);
vertices.set([
-200, -200, 1, 0, 0, 1, 0, 0,
200, -200, 0, 1, 0, 1, 1, 0,
200, 200, 0, 0, 1, 1, 1, 1,
-200, 200, 1, 1, 0, 0.1, 0, 1
], 0);
var vb = new THREE.InterleavedBuffer(vertices, 8);
var positions = new THREE.InterleavedBufferAttribute(vb, 2, 0, false);
geo.addAttribute("position", positions);
var colors = new THREE.InterleavedBufferAttribute(vb, 4, 2, false);
geo.addAttribute("color", colors);
var uvs = new THREE.InterleavedBufferAttribute(vb, 2, 6, false);
geo.addAttribute("uv", colors);
var indices = new Uint16Array(1024);
indices.set([0, 1, 2, 2, 3, 0], 0);
geo.setIndex(new THREE.BufferAttribute(indices, 1));
geo.drawRange.start = 0;
geo.drawRange.count = 6;
var mat = new THREE.MeshBasicMaterial();
mat.vertexColors = THREE.VertexColors;
mat.transparent = true;
mat.map = map;
var mesh = new THREE.Mesh(geo, mat);
return mesh;
};
SkeletonMesh.QUAD_TRIANGLES = [0, 1, 2, 2, 3, 0];
return SkeletonMesh;
}(THREE.Mesh));
threejs.SkeletonMesh = SkeletonMesh;
})(threejs = spine.threejs || (spine.threejs = {}));
})(spine || (spine = {}));
var spine;
(function (spine) {
var threejs;
(function (threejs) {
var ThreeJsTexture = (function (_super) {
__extends(ThreeJsTexture, _super);
function ThreeJsTexture(image) {
_super.call(this, image);
this.texture = new THREE.Texture(image);
this.texture.flipY = false;
this.texture.needsUpdate = true;
}
ThreeJsTexture.prototype.setFilters = function (minFilter, magFilter) {
this.texture.minFilter = ThreeJsTexture.toThreeJsTextureFilter(minFilter);
this.texture.magFilter = ThreeJsTexture.toThreeJsTextureFilter(magFilter);
};
ThreeJsTexture.prototype.setWraps = function (uWrap, vWrap) {
this.texture.wrapS = ThreeJsTexture.toThreeJsTextureWrap(uWrap);
this.texture.wrapT = ThreeJsTexture.toThreeJsTextureWrap(vWrap);
};
ThreeJsTexture.prototype.dispose = function () {
this.texture.dispose();
};
ThreeJsTexture.toThreeJsTextureFilter = function (filter) {
if (filter === spine.TextureFilter.Linear)
return THREE.LinearFilter;
else if (filter === spine.TextureFilter.MipMap)
return THREE.LinearMipMapLinearFilter;
else if (filter === spine.TextureFilter.MipMapLinearLinear)
return THREE.LinearMipMapLinearFilter;
else if (filter === spine.TextureFilter.MipMapLinearNearest)
return THREE.LinearMipMapNearestFilter;
else if (filter === spine.TextureFilter.MipMapNearestLinear)
return THREE.NearestMipMapLinearFilter;
else if (filter === spine.TextureFilter.MipMapNearestNearest)
return THREE.NearestMipMapNearestFilter;
else if (filter === spine.TextureFilter.Nearest)
return THREE.NearestFilter;
else
throw new Error("Unknown texture filter: " + filter);
};
ThreeJsTexture.toThreeJsTextureWrap = function (wrap) {
if (wrap === spine.TextureWrap.ClampToEdge)
return THREE.ClampToEdgeWrapping;
else if (wrap === spine.TextureWrap.MirroredRepeat)
return THREE.MirroredRepeatWrapping;
else if (wrap === spine.TextureWrap.Repeat)
return THREE.RepeatWrapping;
else
throw new Error("Unknown texture wrap: " + wrap);
};
return ThreeJsTexture;
}(spine.Texture));
threejs.ThreeJsTexture = ThreeJsTexture;
})(threejs = spine.threejs || (spine.threejs = {}));
})(spine || (spine = {}));
var spine;
(function (spine) {
var webgl;
(function (webgl) {

File diff suppressed because one or more lines are too long

919
spine-ts/build/spine-threejs.d.ts vendored Normal file
View File

@ -0,0 +1,919 @@
declare module spine {
class Animation {
name: string;
timelines: Array<Timeline>;
duration: number;
constructor(name: string, timelines: Array<Timeline>, duration: number);
apply(skeleton: Skeleton, lastTime: number, time: number, loop: boolean, events: Array<Event>): void;
mix(skeleton: Skeleton, lastTime: number, time: number, loop: boolean, events: Array<Event>, alpha: number): void;
static binarySearch(values: ArrayLike<number>, target: number, step?: number): number;
static linearSearch(values: ArrayLike<number>, target: number, step: number): number;
}
interface Timeline {
apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number): void;
}
abstract class CurveTimeline implements Timeline {
static LINEAR: number;
static STEPPED: number;
static BEZIER: number;
static BEZIER_SIZE: number;
private curves;
constructor(frameCount: number);
getFrameCount(): number;
setLinear(frameIndex: number): void;
setStepped(frameIndex: number): void;
getCurveType(frameIndex: number): number;
setCurve(frameIndex: number, cx1: number, cy1: number, cx2: number, cy2: number): void;
getCurvePercent(frameIndex: number, percent: number): number;
abstract apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number): void;
}
class RotateTimeline extends CurveTimeline {
static ENTRIES: number;
static PREV_TIME: number;
static PREV_ROTATION: number;
static ROTATION: number;
boneIndex: number;
frames: ArrayLike<number>;
constructor(frameCount: number);
setFrame(frameIndex: number, time: number, degrees: number): void;
apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number): void;
}
class TranslateTimeline extends CurveTimeline {
static ENTRIES: number;
static PREV_TIME: number;
static PREV_X: number;
static PREV_Y: number;
static X: number;
static Y: number;
boneIndex: number;
frames: ArrayLike<number>;
constructor(frameCount: number);
setFrame(frameIndex: number, time: number, x: number, y: number): void;
apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number): void;
}
class ScaleTimeline extends TranslateTimeline {
constructor(frameCount: number);
apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number): void;
}
class ShearTimeline extends TranslateTimeline {
constructor(frameCount: number);
apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number): void;
}
class ColorTimeline extends CurveTimeline {
static ENTRIES: number;
static PREV_TIME: number;
static PREV_R: number;
static PREV_G: number;
static PREV_B: number;
static PREV_A: number;
static R: number;
static G: number;
static B: number;
static A: number;
slotIndex: number;
frames: ArrayLike<number>;
constructor(frameCount: number);
setFrame(frameIndex: number, time: number, r: number, g: number, b: number, a: number): void;
apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number): void;
}
class AttachmentTimeline implements Timeline {
slotIndex: number;
frames: ArrayLike<number>;
attachmentNames: Array<string>;
constructor(frameCount: number);
getFrameCount(): number;
setFrame(frameIndex: number, time: number, attachmentName: string): void;
apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number): void;
}
class EventTimeline implements Timeline {
frames: ArrayLike<number>;
events: Array<Event>;
constructor(frameCount: number);
getFrameCount(): number;
setFrame(frameIndex: number, event: Event): void;
apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number): void;
}
class DrawOrderTimeline implements Timeline {
frames: ArrayLike<number>;
drawOrders: Array<Array<number>>;
constructor(frameCount: number);
getFrameCount(): number;
setFrame(frameIndex: number, time: number, drawOrder: Array<number>): void;
apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number): void;
}
class DeformTimeline extends CurveTimeline {
frames: ArrayLike<number>;
frameVertices: Array<ArrayLike<number>>;
slotIndex: number;
attachment: VertexAttachment;
constructor(frameCount: number);
setFrame(frameIndex: number, time: number, vertices: ArrayLike<number>): void;
apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number): void;
}
class IkConstraintTimeline extends CurveTimeline {
static ENTRIES: number;
static PREV_TIME: number;
static PREV_MIX: number;
static PREV_BEND_DIRECTION: number;
static MIX: number;
static BEND_DIRECTION: number;
ikConstraintIndex: number;
frames: ArrayLike<number>;
constructor(frameCount: number);
setFrame(frameIndex: number, time: number, mix: number, bendDirection: number): void;
apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number): void;
}
class TransformConstraintTimeline extends CurveTimeline {
static ENTRIES: number;
static PREV_TIME: number;
static PREV_ROTATE: number;
static PREV_TRANSLATE: number;
static PREV_SCALE: number;
static PREV_SHEAR: number;
static ROTATE: number;
static TRANSLATE: number;
static SCALE: number;
static SHEAR: number;
transformConstraintIndex: number;
frames: ArrayLike<number>;
constructor(frameCount: number);
setFrame(frameIndex: number, time: number, rotateMix: number, translateMix: number, scaleMix: number, shearMix: number): void;
apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number): void;
}
class PathConstraintPositionTimeline extends CurveTimeline {
static ENTRIES: number;
static PREV_TIME: number;
static PREV_VALUE: number;
static VALUE: number;
pathConstraintIndex: number;
frames: ArrayLike<number>;
constructor(frameCount: number);
setFrame(frameIndex: number, time: number, value: number): void;
apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number): void;
}
class PathConstraintSpacingTimeline extends PathConstraintPositionTimeline {
constructor(frameCount: number);
apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number): void;
}
class PathConstraintMixTimeline extends CurveTimeline {
static ENTRIES: number;
static PREV_TIME: number;
static PREV_ROTATE: number;
static PREV_TRANSLATE: number;
static ROTATE: number;
static TRANSLATE: number;
pathConstraintIndex: number;
frames: ArrayLike<number>;
constructor(frameCount: number);
setFrame(frameIndex: number, time: number, rotateMix: number, translateMix: number): void;
apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number): void;
}
}
declare module spine {
class AnimationState {
data: AnimationStateData;
tracks: TrackEntry[];
events: Event[];
listeners: AnimationStateListener[];
timeScale: number;
constructor(data?: AnimationStateData);
update(delta: number): void;
apply(skeleton: Skeleton): void;
clearTracks(): void;
clearTrack(trackIndex: number): void;
freeAll(entry: TrackEntry): void;
expandToIndex(index: number): TrackEntry;
setCurrent(index: number, entry: TrackEntry): void;
setAnimation(trackIndex: number, animationName: string, loop: boolean): TrackEntry;
setAnimationWith(trackIndex: number, animation: Animation, loop: boolean): TrackEntry;
addAnimation(trackIndex: number, animationName: string, loop: boolean, delay: number): TrackEntry;
addAnimationWith(trackIndex: number, animation: Animation, loop: boolean, delay: number): TrackEntry;
getCurrent(trackIndex: number): TrackEntry;
addListener(listener: AnimationStateListener): void;
removeListener(listener: AnimationStateListener): void;
clearListeners(): void;
}
class TrackEntry {
next: TrackEntry;
previous: TrackEntry;
animation: Animation;
loop: boolean;
delay: number;
time: number;
lastTime: number;
endTime: number;
timeScale: number;
mixTime: number;
mixDuration: number;
listener: AnimationStateListener;
mix: number;
reset(): void;
isComplete(): boolean;
}
abstract class AnimationStateAdapter implements AnimationStateListener {
event(trackIndex: number, event: Event): void;
complete(trackIndex: number, loopCount: number): void;
start(trackIndex: number): void;
end(trackIndex: number): void;
}
interface AnimationStateListener {
event(trackIndex: number, event: Event): void;
complete(trackIndex: number, loopCount: number): void;
start(trackIndex: number): void;
end(trackIndex: number): void;
}
}
declare module spine {
class AnimationStateData {
skeletonData: SkeletonData;
animationToMixTime: Map<number>;
defaultMix: number;
constructor(skeletonData: SkeletonData);
setMix(fromName: string, toName: string, duration: number): void;
setMixWith(from: Animation, to: Animation, duration: number): void;
getMix(from: Animation, to: Animation): number;
}
}
declare module spine {
class AssetManager implements Disposable {
private _textureLoader;
private _assets;
private _errors;
private _toLoad;
private _loaded;
constructor(textureLoader: (image: HTMLImageElement) => any);
loadText(path: string, success?: (path: string, text: string) => void, error?: (path: string, error: string) => void): void;
loadTexture(path: string, success?: (path: string, image: HTMLImageElement) => void, error?: (path: string, error: string) => void): void;
get(path: string): any;
remove(path: string): void;
removeAll(): void;
isLoadingComplete(): boolean;
toLoad(): number;
loaded(): number;
dispose(): void;
hasErrors(): boolean;
errors(): Map<string>;
}
}
declare module spine {
enum BlendMode {
Normal = 0,
Additive = 1,
Multiply = 2,
Screen = 3,
}
}
declare module spine {
class Bone implements Updatable {
data: BoneData;
skeleton: Skeleton;
parent: Bone;
children: Bone[];
x: number;
y: number;
rotation: number;
scaleX: number;
scaleY: number;
shearX: number;
shearY: number;
appliedRotation: number;
a: number;
b: number;
worldX: number;
c: number;
d: number;
worldY: number;
worldSignX: number;
worldSignY: number;
sorted: boolean;
constructor(data: BoneData, skeleton: Skeleton, parent: Bone);
update(): void;
updateWorldTransform(): void;
updateWorldTransformWith(x: number, y: number, rotation: number, scaleX: number, scaleY: number, shearX: number, shearY: number): void;
setToSetupPose(): void;
getWorldRotationX(): number;
getWorldRotationY(): number;
getWorldScaleX(): number;
getWorldScaleY(): number;
worldToLocalRotationX(): number;
worldToLocalRotationY(): number;
rotateWorld(degrees: number): void;
updateLocalTransform(): void;
worldToLocal(world: Vector2): Vector2;
localToWorld(local: Vector2): Vector2;
}
}
declare module spine {
class BoneData {
index: number;
name: string;
parent: BoneData;
length: number;
x: number;
y: number;
rotation: number;
scaleX: number;
scaleY: number;
shearX: number;
shearY: number;
inheritRotation: boolean;
inheritScale: boolean;
constructor(index: number, name: string, parent: BoneData);
}
}
declare module spine {
class Event {
data: EventData;
intValue: number;
floatValue: number;
stringValue: string;
time: number;
constructor(time: number, data: EventData);
}
}
declare module spine {
class EventData {
name: string;
intValue: number;
floatValue: number;
stringValue: string;
constructor(name: string);
}
}
declare module spine {
class IkConstraint implements Updatable {
data: IkConstraintData;
bones: Array<Bone>;
target: Bone;
mix: number;
bendDirection: number;
level: number;
constructor(data: IkConstraintData, skeleton: Skeleton);
apply(): void;
update(): void;
apply1(bone: Bone, targetX: number, targetY: number, alpha: number): void;
apply2(parent: Bone, child: Bone, targetX: number, targetY: number, bendDir: number, alpha: number): void;
}
}
declare module spine {
class IkConstraintData {
name: string;
bones: BoneData[];
target: BoneData;
bendDirection: number;
mix: number;
constructor(name: string);
}
}
declare module spine {
class PathConstraint implements Updatable {
static NONE: number;
static BEFORE: number;
static AFTER: number;
data: PathConstraintData;
bones: Array<Bone>;
target: Slot;
position: number;
spacing: number;
rotateMix: number;
translateMix: number;
spaces: number[];
positions: number[];
world: number[];
curves: number[];
lengths: number[];
segments: number[];
constructor(data: PathConstraintData, skeleton: Skeleton);
apply(): void;
update(): void;
computeWorldPositions(path: PathAttachment, spacesCount: number, tangents: boolean, percentPosition: boolean, percentSpacing: boolean): number[];
addBeforePosition(p: number, temp: Array<number>, i: number, out: Array<number>, o: number): void;
addAfterPosition(p: number, temp: Array<number>, i: number, out: Array<number>, o: number): void;
addCurvePosition(p: number, x1: number, y1: number, cx1: number, cy1: number, cx2: number, cy2: number, x2: number, y2: number, out: Array<number>, o: number, tangents: boolean): void;
}
}
declare module spine {
class PathConstraintData {
name: string;
bones: BoneData[];
target: SlotData;
positionMode: PositionMode;
spacingMode: SpacingMode;
rotateMode: RotateMode;
offsetRotation: number;
position: number;
spacing: number;
rotateMix: number;
translateMix: number;
constructor(name: string);
}
enum PositionMode {
Fixed = 0,
Percent = 1,
}
enum SpacingMode {
Length = 0,
Fixed = 1,
Percent = 2,
}
enum RotateMode {
Tangent = 0,
Chain = 1,
ChainScale = 2,
}
}
declare module spine {
class Skeleton {
data: SkeletonData;
bones: Array<Bone>;
slots: Array<Slot>;
drawOrder: Array<Slot>;
ikConstraints: Array<IkConstraint>;
ikConstraintsSorted: Array<IkConstraint>;
transformConstraints: Array<TransformConstraint>;
pathConstraints: Array<PathConstraint>;
_updateCache: Updatable[];
skin: Skin;
color: Color;
time: number;
flipX: boolean;
flipY: boolean;
x: number;
y: number;
constructor(data: SkeletonData);
updateCache(): void;
sortPathConstraintAttachment(skin: Skin, slotIndex: number, slotBone: Bone): void;
sortPathConstraintAttachmentWith(attachment: Attachment, slotBone: Bone): void;
sortBone(bone: Bone): void;
sortReset(bones: Array<Bone>): void;
updateWorldTransform(): void;
setToSetupPose(): void;
setBonesToSetupPose(): void;
setSlotsToSetupPose(): void;
getRootBone(): Bone;
findBone(boneName: string): Bone;
findBoneIndex(boneName: string): number;
findSlot(slotName: string): Slot;
findSlotIndex(slotName: string): number;
setSkinByName(skinName: string): void;
setSkin(newSkin: Skin): void;
getAttachmentByName(slotName: string, attachmentName: string): Attachment;
getAttachment(slotIndex: number, attachmentName: string): Attachment;
setAttachment(slotName: string, attachmentName: string): void;
findIkConstraint(constraintName: string): IkConstraint;
findTransformConstraint(constraintName: string): TransformConstraint;
findPathConstraint(constraintName: string): PathConstraint;
getBounds(offset: Vector2, size: Vector2): void;
update(delta: number): void;
}
}
declare module spine {
class SkeletonBounds {
minX: number;
minY: number;
maxX: number;
maxY: number;
boundingBoxes: BoundingBoxAttachment[];
polygons: ArrayLike<number>[];
private _polygonPool;
update(skeleton: Skeleton, updateAabb: boolean): void;
aabbCompute(): void;
aabbContainsPoint(x: number, y: number): boolean;
aabbIntersectsSegment(x1: number, y1: number, x2: number, y2: number): boolean;
aabbIntersectsSkeleton(bounds: SkeletonBounds): boolean;
containsPoint(x: number, y: number): BoundingBoxAttachment;
containsPointPolygon(polygon: ArrayLike<number>, x: number, y: number): boolean;
intersectsSegment(x1: number, y1: number, x2: number, y2: number): BoundingBoxAttachment;
intersectsSegmentPolygon(polygon: ArrayLike<number>, x1: number, y1: number, x2: number, y2: number): boolean;
getPolygon(boundingBox: BoundingBoxAttachment): ArrayLike<number>;
}
}
declare module spine {
class SkeletonData {
name: string;
bones: BoneData[];
slots: SlotData[];
skins: Skin[];
defaultSkin: Skin;
events: EventData[];
animations: Animation[];
ikConstraints: IkConstraintData[];
transformConstraints: TransformConstraintData[];
pathConstraints: PathConstraintData[];
width: number;
height: number;
version: string;
hash: string;
imagesPath: string;
findBone(boneName: string): BoneData;
findBoneIndex(boneName: string): number;
findSlot(slotName: string): SlotData;
findSlotIndex(slotName: string): number;
findSkin(skinName: string): Skin;
findEvent(eventDataName: string): EventData;
findAnimation(animationName: string): Animation;
findIkConstraint(constraintName: string): IkConstraintData;
findTransformConstraint(constraintName: string): TransformConstraintData;
findPathConstraint(constraintName: string): PathConstraintData;
findPathConstraintIndex(pathConstraintName: string): number;
}
}
declare module spine {
class SkeletonJson {
attachmentLoader: AttachmentLoader;
scale: number;
private linkedMeshes;
constructor(attachmentLoader: AttachmentLoader);
readSkeletonData(json: string): SkeletonData;
readAttachment(map: any, skin: Skin, slotIndex: number, name: string): Attachment;
readVertices(map: any, attachment: VertexAttachment, verticesLength: number): void;
readAnimation(map: any, name: string, skeletonData: SkeletonData): void;
readCurve(map: any, timeline: CurveTimeline, frameIndex: number): void;
getValue(map: any, prop: string, defaultValue: any): any;
static blendModeFromString(str: string): BlendMode;
static positionModeFromString(str: string): PositionMode;
static spacingModeFromString(str: string): SpacingMode;
static rotateModeFromString(str: string): RotateMode;
}
}
declare module spine {
class Skin {
name: string;
attachments: Map<Attachment>[];
constructor(name: string);
addAttachment(slotIndex: number, name: string, attachment: Attachment): void;
getAttachment(slotIndex: number, name: string): Attachment;
attachAll(skeleton: Skeleton, oldSkin: Skin): void;
}
}
declare module spine {
class Slot {
data: SlotData;
bone: Bone;
color: Color;
private attachment;
private attachmentTime;
attachmentVertices: number[];
constructor(data: SlotData, bone: Bone);
getAttachment(): Attachment;
setAttachment(attachment: Attachment): void;
setAttachmentTime(time: number): void;
getAttachmentTime(): number;
setToSetupPose(): void;
}
}
declare module spine {
class SlotData {
index: number;
name: string;
boneData: BoneData;
color: Color;
attachmentName: string;
blendMode: BlendMode;
constructor(index: number, name: string, boneData: BoneData);
}
}
declare module spine {
abstract class Texture {
protected _image: HTMLImageElement;
constructor(image: HTMLImageElement);
getImage(): HTMLImageElement;
abstract setFilters(minFilter: TextureFilter, magFilter: TextureFilter): void;
abstract setWraps(uWrap: TextureWrap, vWrap: TextureWrap): void;
abstract dispose(): void;
static filterFromString(text: string): TextureFilter;
static wrapFromString(text: string): TextureWrap;
}
enum TextureFilter {
Nearest = 9728,
Linear = 9729,
MipMap = 9987,
MipMapNearestNearest = 9984,
MipMapLinearNearest = 9985,
MipMapNearestLinear = 9986,
MipMapLinearLinear = 9987,
}
enum TextureWrap {
MirroredRepeat = 33648,
ClampToEdge = 33071,
Repeat = 10497,
}
class TextureRegion {
renderObject: any;
u: number;
v: number;
u2: number;
v2: number;
width: number;
height: number;
rotate: boolean;
offsetX: number;
offsetY: number;
originalWidth: number;
originalHeight: number;
}
}
declare module spine {
class TextureAtlas implements Disposable {
pages: TextureAtlasPage[];
regions: TextureAtlasRegion[];
constructor(atlasText: string, textureLoader: (path: string) => any);
private load(atlasText, textureLoader);
findRegion(name: string): TextureAtlasRegion;
dispose(): void;
}
class TextureAtlasPage {
name: string;
minFilter: TextureFilter;
magFilter: TextureFilter;
uWrap: TextureWrap;
vWrap: TextureWrap;
texture: Texture;
width: number;
height: number;
}
class TextureAtlasRegion extends TextureRegion {
page: TextureAtlasPage;
name: string;
x: number;
y: number;
index: number;
rotate: boolean;
texture: Texture;
}
}
declare module spine {
class TextureAtlasAttachmentLoader implements AttachmentLoader {
atlas: TextureAtlas;
constructor(atlas: TextureAtlas);
newRegionAttachment(skin: Skin, name: string, path: string): RegionAttachment;
newMeshAttachment(skin: Skin, name: string, path: string): MeshAttachment;
newBoundingBoxAttachment(skin: Skin, name: string): BoundingBoxAttachment;
newPathAttachment(skin: Skin, name: string): PathAttachment;
}
}
declare module spine {
class TransformConstraint implements Updatable {
data: TransformConstraintData;
bones: Array<Bone>;
target: Bone;
rotateMix: number;
translateMix: number;
scaleMix: number;
shearMix: number;
temp: Vector2;
constructor(data: TransformConstraintData, skeleton: Skeleton);
apply(): void;
update(): void;
}
}
declare module spine {
class TransformConstraintData {
name: string;
bones: BoneData[];
target: BoneData;
rotateMix: number;
translateMix: number;
scaleMix: number;
shearMix: number;
offsetRotation: number;
offsetX: number;
offsetY: number;
offsetScaleX: number;
offsetScaleY: number;
offsetShearY: number;
constructor(name: string);
}
}
declare module spine {
interface Updatable {
update(): void;
}
}
declare module spine {
interface Map<T> {
[key: string]: T;
}
interface Disposable {
dispose(): void;
}
class Color {
r: number;
g: number;
b: number;
a: number;
constructor(r?: number, g?: number, b?: number, a?: number);
set(r: number, g: number, b: number, a: number): void;
setFromColor(c: Color): void;
setFromString(hex: string): void;
add(r: number, g: number, b: number, a: number): void;
clamp(): this;
}
class MathUtils {
static PI: number;
static PI2: number;
static radiansToDegrees: number;
static radDeg: number;
static degreesToRadians: number;
static degRad: number;
static clamp(value: number, min: number, max: number): number;
static cosDeg(degrees: number): number;
static sinDeg(degrees: number): number;
static signum(value: number): number;
static toInt(x: number): number;
}
class Utils {
static SUPPORTS_TYPED_ARRAYS: boolean;
static arrayCopy<T>(source: ArrayLike<T>, sourceStart: number, dest: ArrayLike<T>, destStart: number, numElements: number): void;
static setArraySize<T>(array: Array<T>, size: number, value?: any): Array<T>;
static newArray<T>(size: number, defaultValue: T): Array<T>;
static newFloatArray(size: number): ArrayLike<number>;
static toFloatArray(array: Array<number>): Float32Array | number[];
}
class Pool<T> {
private _items;
private _instantiator;
constructor(instantiator: () => T);
obtain(): T;
free(item: T): void;
freeAll(items: ArrayLike<T>): void;
clear(): void;
}
class Vector2 {
x: number;
y: number;
constructor(x?: number, y?: number);
set(x: number, y: number): Vector2;
}
}
declare module spine {
abstract class Attachment {
name: string;
constructor(name: string);
}
abstract class VertexAttachment extends Attachment {
bones: Array<number>;
vertices: ArrayLike<number>;
worldVerticesLength: number;
constructor(name: string);
computeWorldVertices(slot: Slot, worldVertices: ArrayLike<number>): void;
computeWorldVerticesWith(slot: Slot, start: number, count: number, worldVertices: ArrayLike<number>, offset: number): void;
applyDeform(sourceAttachment: VertexAttachment): boolean;
}
}
declare module spine {
interface AttachmentLoader {
newRegionAttachment(skin: Skin, name: string, path: string): RegionAttachment;
newMeshAttachment(skin: Skin, name: string, path: string): MeshAttachment;
newBoundingBoxAttachment(skin: Skin, name: string): BoundingBoxAttachment;
newPathAttachment(skin: Skin, name: string): PathAttachment;
}
}
declare module spine {
enum AttachmentType {
Region = 0,
BoundingBox = 1,
Mesh = 2,
LinkedMesh = 3,
Path = 4,
}
}
declare module spine {
class BoundingBoxAttachment extends VertexAttachment {
constructor(name: string);
}
}
declare module spine {
class MeshAttachment extends VertexAttachment {
region: TextureRegion;
path: string;
regionUVs: ArrayLike<number>;
worldVertices: ArrayLike<number>;
triangles: Array<number>;
color: Color;
hullLength: number;
private _parentMesh;
inheritDeform: boolean;
tempColor: Color;
constructor(name: string);
updateUVs(): void;
updateWorldVertices(slot: Slot, premultipliedAlpha: boolean): ArrayLike<number>;
applyDeform(sourceAttachment: VertexAttachment): boolean;
getParentMesh(): MeshAttachment;
setParentMesh(parentMesh: MeshAttachment): void;
}
}
declare module spine {
class PathAttachment extends VertexAttachment {
lengths: Array<number>;
closed: boolean;
constantSpeed: boolean;
constructor(name: string);
}
}
declare module spine {
class RegionAttachment extends Attachment {
static OX1: number;
static OY1: number;
static OX2: number;
static OY2: number;
static OX3: number;
static OY3: number;
static OX4: number;
static OY4: number;
static X1: number;
static Y1: number;
static C1R: number;
static C1G: number;
static C1B: number;
static C1A: number;
static U1: number;
static V1: number;
static X2: number;
static Y2: number;
static C2R: number;
static C2G: number;
static C2B: number;
static C2A: number;
static U2: number;
static V2: number;
static X3: number;
static Y3: number;
static C3R: number;
static C3G: number;
static C3B: number;
static C3A: number;
static U3: number;
static V3: number;
static X4: number;
static Y4: number;
static C4R: number;
static C4G: number;
static C4B: number;
static C4A: number;
static U4: number;
static V4: number;
x: number;
y: number;
scaleX: number;
scaleY: number;
rotation: number;
width: number;
height: number;
color: Color;
path: string;
rendererObject: any;
region: TextureRegion;
offset: ArrayLike<number>;
vertices: ArrayLike<number>;
tempColor: Color;
constructor(name: string);
setRegion(region: TextureRegion): void;
updateOffset(): void;
updateWorldVertices(slot: Slot, premultipliedAlpha: boolean): ArrayLike<number>;
}
}
declare module spine.threejs {
class AssetManager extends spine.AssetManager {
constructor();
}
}
declare module spine.threejs {
class MeshBatcher {
mesh: THREE.Mesh;
private static VERTEX_SIZE;
private _vertexBuffer;
private _vertices;
private _verticesLength;
private _indices;
private _indicesLength;
constructor(mesh: THREE.Mesh, maxVertices?: number);
begin(): void;
batch(vertices: ArrayLike<number>, indices: ArrayLike<number>, z?: number): void;
end(): void;
}
}
declare module spine.threejs {
class SkeletonMesh extends THREE.Mesh {
skeleton: Skeleton;
state: AnimationState;
zOffset: number;
private _batcher;
static QUAD_TRIANGLES: number[];
constructor(skeletonData: SkeletonData);
update(deltaTime: number): void;
private updateGeometry();
static createMesh(map: THREE.Texture): THREE.Mesh;
}
}
declare module spine.threejs {
class ThreeJsTexture extends Texture {
texture: THREE.Texture;
constructor(image: HTMLImageElement);
setFilters(minFilter: TextureFilter, magFilter: TextureFilter): void;
setWraps(uWrap: TextureWrap, vWrap: TextureWrap): void;
dispose(): void;
static toThreeJsTextureFilter(filter: TextureFilter): THREE.TextureFilter;
static toThreeJsTextureWrap(wrap: TextureWrap): THREE.Wrapping;
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -14,20 +14,16 @@
var scene, camera, renderer;
var geometry, material, mesh, skeletonMesh;
var assetManager;
var lastFrameTime = Date.now();
var lastFrameTime = Date.now() / 1000;
var dynMesh;
var batcher;
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);
camera.position.z = 400;
renderer = new THREE.WebGLRenderer();
renderer.setSize(width, height);
@ -43,17 +39,23 @@ function init () {
}
function load (name, scale) {
if (assetManager.isLoadingComplete()) {
if (assetManager.isLoadingComplete()) {
// Add a box to the scene to which we attach the skeleton mesh
geometry = new THREE.BoxGeometry(200, 200, 200);
material = new THREE.MeshBasicMaterial({ color: 0xff0000, wireframe: true });
mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);
// 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);
}

View File

@ -0,0 +1,72 @@
module spine.threejs {
export class MeshBatcher {
mesh: THREE.Mesh;
private static VERTEX_SIZE = 9;
private _vertexBuffer: THREE.InterleavedBuffer;
private _vertices: Float32Array;
private _verticesLength = 0;
private _indices: Uint16Array;
private _indicesLength = 0;
constructor (mesh: THREE.Mesh, maxVertices: number = 10920) {
if (maxVertices > 10920) throw new Error("Can't have more than 10920 triangles per batch: " + maxVertices);
let vertices = this._vertices = new Float32Array(maxVertices * MeshBatcher.VERTEX_SIZE);
let indices = this._indices = new Uint16Array(maxVertices * 3);
this.mesh = mesh;
let geo = new THREE.BufferGeometry();
let vertexBuffer = this._vertexBuffer = new THREE.InterleavedBuffer(vertices, MeshBatcher.VERTEX_SIZE);
vertexBuffer.dynamic = true;
geo.addAttribute("position", new THREE.InterleavedBufferAttribute(vertexBuffer, 3, 0, false));
geo.addAttribute("color", new THREE.InterleavedBufferAttribute(vertexBuffer, 4, 3, false));
geo.addAttribute("uv", new THREE.InterleavedBufferAttribute(vertexBuffer, 2, 7, false));
geo.setIndex(new THREE.BufferAttribute(indices, 1));
geo.getIndex().dynamic = true;
geo.drawRange.start = 0;
geo.drawRange.count = 0;
mesh.geometry = geo;
}
begin () {
this._verticesLength = 0;
this._indicesLength = 0;
}
batch (vertices: ArrayLike<number>, indices: ArrayLike<number>, z: number = 0) {
let indexStart = this._verticesLength / MeshBatcher.VERTEX_SIZE;
let vertexBuffer = this._vertices;
let i = this._verticesLength;
let j = 0;
for (;j < vertices.length;) {
vertexBuffer[i++] = vertices[j++];
vertexBuffer[i++] = vertices[j++];
vertexBuffer[i++] = z;
vertexBuffer[i++] = vertices[j++];
vertexBuffer[i++] = vertices[j++];
vertexBuffer[i++] = vertices[j++];
vertexBuffer[i++] = vertices[j++];
vertexBuffer[i++] = vertices[j++];
vertexBuffer[i++] = vertices[j++];
}
this._verticesLength = i;
let indicesArray = this._indices;
for (i = this._indicesLength, j = 0; j < indices.length; i++, j++)
indicesArray[i] = indices[j] + indexStart;
this._indicesLength += indices.length;
}
end () {
this._vertexBuffer.needsUpdate = true;
this._vertexBuffer.updateRange.offset = 0;
this._vertexBuffer.updateRange.count = this._verticesLength;
let geo = (<THREE.BufferGeometry>this.mesh.geometry);
geo.getIndex().needsUpdate = true;
geo.getIndex().updateRange.offset = 0;
geo.getIndex().updateRange.count = this._indicesLength;
geo.drawRange.start = 0;
geo.drawRange.count = this._indicesLength;
}
}
}

View File

@ -3,8 +3,9 @@ module spine.threejs {
skeleton: Skeleton;
state: AnimationState;
zOffset: number = 0.1;
private _vertexBuffer: THREE.InterleavedBuffer;
private _batcher: MeshBatcher;
static QUAD_TRIANGLES = [0, 1, 2, 2, 3, 0];
@ -15,20 +16,11 @@ module spine.threejs {
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);
let material = this.material = new THREE.MeshBasicMaterial();
material.side = THREE.DoubleSide;
material.transparent = true;
material.alphaTest = 0.5;
this._batcher = new MeshBatcher(this);
}
update(deltaTime: number) {
@ -53,6 +45,10 @@ module spine.threejs {
let vertices: ArrayLike<number> = null;
let triangles: Array<number> = null;
let drawOrder = this.skeleton.drawOrder;
let batcher = this._batcher;
batcher.begin();
let z = 0;
let zOffset = this.zOffset;
for (let i = 0, n = drawOrder.length; i < n; i++) {
let slot = drawOrder[i];
let attachment = slot.getAttachment();
@ -71,7 +67,11 @@ module spine.threejs {
} else continue;
if (texture != null) {
(<THREE.MeshBasicMaterial>this.material).map = texture.texture;
if (!(<THREE.MeshBasicMaterial>this.material).map) {
let mat = <THREE.MeshBasicMaterial>this.material;
mat.map = texture.texture;
mat.needsUpdate = true;
}
// FIXME
//let slotBlendMode = slot.data.blendMode;
//if (slotBlendMode != blendMode) {
@ -79,25 +79,43 @@ module spine.threejs {
// batcher.setBlendMode(getSourceGLBlendMode(this._gl, blendMode, premultipliedAlpha), getDestGLBlendMode(this._gl, blendMode));
//}
let indexStart = verticesLength / 8;
(<Float32Array>this._vertexBuffer.array).set(vertices, verticesLength);
verticesLength += vertices.length;
let indicesArray = geometry.getIndex().array;
for (let i = indicesLength, j = 0; j < triangles.length; i++, j++)
indicesArray[i] = triangles[j] + indexStart;
indicesLength += triangles.length;
this._batcher.batch(vertices, triangles, z);
z += zOffset;
}
}
geometry.drawRange.start = 0;
geometry.drawRange.count = indicesLength;
this._vertexBuffer.needsUpdate = true;
this._vertexBuffer.updateRange.offset = 0;
this._vertexBuffer.updateRange.count = verticesLength;
geometry.getIndex().needsUpdate = true;
geometry.getIndex().updateRange.offset = 0;
geometry.getIndex().updateRange.count = indicesLength;
batcher.end();
}
static createMesh(map: THREE.Texture) {
let geo = new THREE.BufferGeometry();
let vertices = new Float32Array(1024);
vertices.set([
-200, -200, 1, 0, 0, 1, 0, 0,
200, -200, 0, 1, 0, 1, 1, 0,
200, 200, 0, 0, 1, 1, 1, 1,
-200, 200, 1, 1, 0, 0.1, 0, 1
], 0);
let vb = new THREE.InterleavedBuffer(vertices, 8);
var positions = new THREE.InterleavedBufferAttribute(vb, 2, 0, false);
geo.addAttribute("position", positions);
var colors = new THREE.InterleavedBufferAttribute(vb, 4, 2, false);
geo.addAttribute("color", colors);
var uvs = new THREE.InterleavedBufferAttribute(vb, 2, 6, false);
geo.addAttribute("uv", colors);
var indices = new Uint16Array(1024);
indices.set([0, 1, 2, 2, 3, 0], 0);
geo.setIndex(new THREE.BufferAttribute(indices, 1));
geo.drawRange.start = 0;
geo.drawRange.count = 6;
let mat = new THREE.MeshBasicMaterial();
mat.vertexColors = THREE.VertexColors;
mat.transparent = true;
mat.map = map;
let mesh = new THREE.Mesh(geo, mat);
return mesh;
}
}
}

View File

@ -5,6 +5,8 @@ module spine.threejs {
constructor (image: HTMLImageElement) {
super(image);
this.texture = new THREE.Texture(image);
this.texture.flipY = false;
this.texture.needsUpdate = true;
}
setFilters (minFilter: TextureFilter, magFilter: TextureFilter) {