2020-01-18 15:54:54 +01:00
|
|
|
import { BoxGeometry, DoubleSide, FrontSide, Group, Mesh, MeshBasicMaterial, Object3D, Texture, Vector2 } from "three";
|
2017-10-01 14:00:45 +02:00
|
|
|
|
2018-07-21 05:07:52 +02:00
|
|
|
function toFaceVertices(x1: number, y1: number, x2: number, y2: number, w: number, h: number) {
|
2017-10-01 14:00:45 +02:00
|
|
|
return [
|
2020-01-01 10:18:06 +01:00
|
|
|
new Vector2(x1 / w, 1.0 - y2 / h),
|
|
|
|
new Vector2(x2 / w, 1.0 - y2 / h),
|
|
|
|
new Vector2(x2 / w, 1.0 - y1 / h),
|
|
|
|
new Vector2(x1 / w, 1.0 - y1 / h)
|
2017-10-01 14:00:45 +02:00
|
|
|
];
|
|
|
|
}
|
|
|
|
|
2018-07-21 05:07:52 +02:00
|
|
|
function toSkinVertices(x1: number, y1: number, x2: number, y2: number) {
|
2017-10-01 14:00:45 +02:00
|
|
|
return toFaceVertices(x1, y1, x2, y2, 64.0, 64.0);
|
|
|
|
}
|
|
|
|
|
2018-07-21 05:07:52 +02:00
|
|
|
function toCapeVertices(x1: number, y1: number, x2: number, y2: number) {
|
2017-10-01 14:00:45 +02:00
|
|
|
return toFaceVertices(x1, y1, x2, y2, 64.0, 32.0);
|
|
|
|
}
|
|
|
|
|
2020-01-01 10:18:06 +01:00
|
|
|
function setVertices(box: BoxGeometry, top: Array<Vector2>, bottom: Array<Vector2>, left: Array<Vector2>, front: Array<Vector2>, right: Array<Vector2>, back: Array<Vector2>) {
|
2018-07-21 05:07:52 +02:00
|
|
|
|
2017-10-01 14:00:45 +02:00
|
|
|
box.faceVertexUvs[0] = [];
|
|
|
|
box.faceVertexUvs[0][0] = [right[3], right[0], right[2]];
|
|
|
|
box.faceVertexUvs[0][1] = [right[0], right[1], right[2]];
|
|
|
|
box.faceVertexUvs[0][2] = [left[3], left[0], left[2]];
|
|
|
|
box.faceVertexUvs[0][3] = [left[0], left[1], left[2]];
|
|
|
|
box.faceVertexUvs[0][4] = [top[3], top[0], top[2]];
|
|
|
|
box.faceVertexUvs[0][5] = [top[0], top[1], top[2]];
|
|
|
|
box.faceVertexUvs[0][6] = [bottom[0], bottom[3], bottom[1]];
|
|
|
|
box.faceVertexUvs[0][7] = [bottom[3], bottom[2], bottom[1]];
|
|
|
|
box.faceVertexUvs[0][8] = [front[3], front[0], front[2]];
|
|
|
|
box.faceVertexUvs[0][9] = [front[0], front[1], front[2]];
|
|
|
|
box.faceVertexUvs[0][10] = [back[3], back[0], back[2]];
|
|
|
|
box.faceVertexUvs[0][11] = [back[0], back[1], back[2]];
|
|
|
|
}
|
|
|
|
|
2018-10-20 09:32:56 +02:00
|
|
|
/**
|
|
|
|
* Notice that innerLayer and outerLayer may NOT be the direct children of the Group.
|
|
|
|
*/
|
2020-01-01 10:18:06 +01:00
|
|
|
export class BodyPart extends Group {
|
2018-10-20 16:28:58 +02:00
|
|
|
constructor(
|
2020-01-01 10:18:06 +01:00
|
|
|
readonly innerLayer: Object3D,
|
|
|
|
readonly outerLayer: Object3D
|
2018-10-20 16:28:58 +02:00
|
|
|
) {
|
2018-10-20 09:32:56 +02:00
|
|
|
super();
|
2019-04-20 16:08:49 +02:00
|
|
|
innerLayer.name = "inner";
|
|
|
|
outerLayer.name = "outer";
|
2018-10-20 09:32:56 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-01-01 10:18:06 +01:00
|
|
|
export class SkinObject extends Group {
|
2018-07-17 20:49:00 +02:00
|
|
|
|
2018-07-21 05:07:52 +02:00
|
|
|
// body parts
|
2018-10-20 09:32:56 +02:00
|
|
|
readonly head: BodyPart;
|
|
|
|
readonly body: BodyPart;
|
|
|
|
readonly rightArm: BodyPart;
|
|
|
|
readonly leftArm: BodyPart;
|
|
|
|
readonly rightLeg: BodyPart;
|
|
|
|
readonly leftLeg: BodyPart;
|
2018-07-17 20:49:00 +02:00
|
|
|
|
2018-08-16 13:23:49 +02:00
|
|
|
private modelListeners: Array<() => void> = []; // called when model(slim property) is changed
|
2018-07-21 05:07:52 +02:00
|
|
|
private _slim = false;
|
2018-07-17 20:49:00 +02:00
|
|
|
|
2020-01-18 15:54:54 +01:00
|
|
|
constructor(texture: Texture) {
|
2017-10-01 14:00:45 +02:00
|
|
|
super();
|
|
|
|
|
2020-01-30 15:44:25 +01:00
|
|
|
const layer1 = {
|
|
|
|
map: texture,
|
|
|
|
side: FrontSide
|
|
|
|
};
|
|
|
|
const layer2 = {
|
|
|
|
map: texture,
|
|
|
|
side: DoubleSide,
|
|
|
|
transparent: true,
|
|
|
|
opacity: 1,
|
|
|
|
alphaTest: 0.5
|
|
|
|
}
|
|
|
|
|
|
|
|
const layer1Material = new MeshBasicMaterial(layer1);
|
|
|
|
const layer2Material = new MeshBasicMaterial(layer2);
|
2020-01-18 15:54:54 +01:00
|
|
|
|
2017-10-01 14:00:45 +02:00
|
|
|
// Head
|
2020-01-01 10:18:06 +01:00
|
|
|
const headBox = new BoxGeometry(8, 8, 8, 0, 0, 0);
|
2018-07-02 08:54:49 +02:00
|
|
|
setVertices(headBox,
|
2017-10-01 14:00:45 +02:00
|
|
|
toSkinVertices(8, 0, 16, 8),
|
|
|
|
toSkinVertices(16, 0, 24, 8),
|
|
|
|
toSkinVertices(0, 8, 8, 16),
|
|
|
|
toSkinVertices(8, 8, 16, 16),
|
|
|
|
toSkinVertices(16, 8, 24, 16),
|
|
|
|
toSkinVertices(24, 8, 32, 16)
|
|
|
|
);
|
2020-01-01 10:18:06 +01:00
|
|
|
const headMesh = new Mesh(headBox, layer1Material);
|
2017-10-01 14:00:45 +02:00
|
|
|
|
2020-01-01 10:18:06 +01:00
|
|
|
const head2Box = new BoxGeometry(9, 9, 9, 0, 0, 0);
|
2018-07-02 08:54:49 +02:00
|
|
|
setVertices(head2Box,
|
2017-10-01 14:00:45 +02:00
|
|
|
toSkinVertices(40, 0, 48, 8),
|
|
|
|
toSkinVertices(48, 0, 56, 8),
|
|
|
|
toSkinVertices(32, 8, 40, 16),
|
|
|
|
toSkinVertices(40, 8, 48, 16),
|
|
|
|
toSkinVertices(48, 8, 56, 16),
|
|
|
|
toSkinVertices(56, 8, 64, 16)
|
|
|
|
);
|
2020-01-01 10:18:06 +01:00
|
|
|
const head2Mesh = new Mesh(head2Box, layer2Material);
|
2017-10-01 14:00:45 +02:00
|
|
|
head2Mesh.renderOrder = -1;
|
|
|
|
|
2018-10-20 09:32:56 +02:00
|
|
|
this.head = new BodyPart(headMesh, head2Mesh);
|
2019-04-20 16:08:49 +02:00
|
|
|
this.head.name = "head";
|
2018-10-20 09:32:56 +02:00
|
|
|
this.head.add(headMesh, head2Mesh);
|
2017-10-01 14:00:45 +02:00
|
|
|
this.add(this.head);
|
|
|
|
|
|
|
|
// Body
|
2020-01-01 10:18:06 +01:00
|
|
|
const bodyBox = new BoxGeometry(8, 12, 4, 0, 0, 0);
|
2018-07-02 08:54:49 +02:00
|
|
|
setVertices(bodyBox,
|
2017-10-01 14:00:45 +02:00
|
|
|
toSkinVertices(20, 16, 28, 20),
|
|
|
|
toSkinVertices(28, 16, 36, 20),
|
|
|
|
toSkinVertices(16, 20, 20, 32),
|
|
|
|
toSkinVertices(20, 20, 28, 32),
|
|
|
|
toSkinVertices(28, 20, 32, 32),
|
|
|
|
toSkinVertices(32, 20, 40, 32)
|
|
|
|
);
|
2020-01-30 15:44:25 +01:00
|
|
|
const bodyMesh = new Mesh(bodyBox, new MeshBasicMaterial({
|
|
|
|
...layer1,
|
|
|
|
// this pulls bodyMesh towards the camera
|
|
|
|
// so body is given priority over others in z-fighting
|
|
|
|
polygonOffset: true,
|
|
|
|
polygonOffsetUnits: -1
|
|
|
|
}));
|
2017-10-01 14:00:45 +02:00
|
|
|
|
2020-01-01 10:18:06 +01:00
|
|
|
const body2Box = new BoxGeometry(9, 13.5, 4.5, 0, 0, 0);
|
2018-07-02 08:54:49 +02:00
|
|
|
setVertices(body2Box,
|
2017-10-01 14:00:45 +02:00
|
|
|
toSkinVertices(20, 32, 28, 36),
|
|
|
|
toSkinVertices(28, 32, 36, 36),
|
|
|
|
toSkinVertices(16, 36, 20, 48),
|
|
|
|
toSkinVertices(20, 36, 28, 48),
|
|
|
|
toSkinVertices(28, 36, 32, 48),
|
|
|
|
toSkinVertices(32, 36, 40, 48)
|
|
|
|
);
|
2020-01-30 15:44:25 +01:00
|
|
|
const body2Mesh = new Mesh(body2Box, new MeshBasicMaterial({
|
|
|
|
...layer2,
|
|
|
|
// same as above
|
|
|
|
polygonOffset: true,
|
|
|
|
polygonOffsetUnits: -1
|
|
|
|
}));
|
2017-10-01 14:00:45 +02:00
|
|
|
|
2018-10-20 09:32:56 +02:00
|
|
|
this.body = new BodyPart(bodyMesh, body2Mesh);
|
2019-04-20 16:08:49 +02:00
|
|
|
this.body.name = "body";
|
2018-10-20 09:32:56 +02:00
|
|
|
this.body.add(bodyMesh, body2Mesh);
|
2017-10-01 14:00:45 +02:00
|
|
|
this.body.position.y = -10;
|
|
|
|
this.add(this.body);
|
|
|
|
|
|
|
|
// Right Arm
|
2020-01-01 10:18:06 +01:00
|
|
|
const rightArmBox = new BoxGeometry(1, 1, 1, 0, 0, 0); // w/d/h is model-related
|
|
|
|
const rightArmMesh = new Mesh(rightArmBox, layer1Material);
|
2018-07-02 09:46:48 +02:00
|
|
|
this.modelListeners.push(() => {
|
2020-01-30 15:44:25 +01:00
|
|
|
rightArmMesh.scale.x = this.slim ? 3 : 4;
|
|
|
|
rightArmMesh.scale.y = 12;
|
|
|
|
rightArmMesh.scale.z = 4;
|
2018-07-02 09:46:48 +02:00
|
|
|
if (this.slim) {
|
|
|
|
setVertices(rightArmBox,
|
|
|
|
toSkinVertices(44, 16, 47, 20),
|
|
|
|
toSkinVertices(47, 16, 50, 20),
|
|
|
|
toSkinVertices(40, 20, 44, 32),
|
|
|
|
toSkinVertices(44, 20, 47, 32),
|
|
|
|
toSkinVertices(47, 20, 51, 32),
|
|
|
|
toSkinVertices(51, 20, 54, 32)
|
|
|
|
);
|
|
|
|
} else {
|
|
|
|
setVertices(rightArmBox,
|
|
|
|
toSkinVertices(44, 16, 48, 20),
|
|
|
|
toSkinVertices(48, 16, 52, 20),
|
|
|
|
toSkinVertices(40, 20, 44, 32),
|
|
|
|
toSkinVertices(44, 20, 48, 32),
|
|
|
|
toSkinVertices(48, 20, 52, 32),
|
|
|
|
toSkinVertices(52, 20, 56, 32)
|
|
|
|
);
|
|
|
|
}
|
|
|
|
rightArmBox.uvsNeedUpdate = true;
|
|
|
|
rightArmBox.elementsNeedUpdate = true;
|
|
|
|
});
|
|
|
|
|
2020-01-01 10:18:06 +01:00
|
|
|
const rightArm2Box = new BoxGeometry(1, 1, 1, 0, 0, 0); // w/d/h is model-related
|
|
|
|
const rightArm2Mesh = new Mesh(rightArm2Box, layer2Material);
|
2017-10-01 14:00:45 +02:00
|
|
|
rightArm2Mesh.renderOrder = 1;
|
2018-07-02 09:46:48 +02:00
|
|
|
this.modelListeners.push(() => {
|
2020-01-30 15:44:25 +01:00
|
|
|
rightArm2Mesh.scale.x = this.slim ? 3.375 : 4.5;
|
|
|
|
rightArm2Mesh.scale.y = 13.5;
|
|
|
|
rightArm2Mesh.scale.z = 4.5;
|
2018-07-02 09:46:48 +02:00
|
|
|
if (this.slim) {
|
|
|
|
setVertices(rightArm2Box,
|
|
|
|
toSkinVertices(44, 32, 47, 36),
|
|
|
|
toSkinVertices(47, 32, 50, 36),
|
|
|
|
toSkinVertices(40, 36, 44, 48),
|
|
|
|
toSkinVertices(44, 36, 47, 48),
|
|
|
|
toSkinVertices(47, 36, 51, 48),
|
|
|
|
toSkinVertices(51, 36, 54, 48)
|
|
|
|
);
|
|
|
|
} else {
|
|
|
|
setVertices(rightArm2Box,
|
|
|
|
toSkinVertices(44, 32, 48, 36),
|
|
|
|
toSkinVertices(48, 32, 52, 36),
|
|
|
|
toSkinVertices(40, 36, 44, 48),
|
|
|
|
toSkinVertices(44, 36, 48, 48),
|
|
|
|
toSkinVertices(48, 36, 52, 48),
|
|
|
|
toSkinVertices(52, 36, 56, 48)
|
|
|
|
);
|
|
|
|
}
|
|
|
|
rightArm2Box.uvsNeedUpdate = true;
|
|
|
|
rightArm2Box.elementsNeedUpdate = true;
|
|
|
|
});
|
2017-10-01 14:00:45 +02:00
|
|
|
|
2020-01-01 10:18:06 +01:00
|
|
|
const rightArmPivot = new Group();
|
2018-10-20 09:32:56 +02:00
|
|
|
rightArmPivot.add(rightArmMesh, rightArm2Mesh);
|
2017-10-01 14:00:45 +02:00
|
|
|
rightArmPivot.position.y = -6;
|
2018-10-20 09:32:56 +02:00
|
|
|
|
|
|
|
this.rightArm = new BodyPart(rightArmMesh, rightArm2Mesh);
|
2019-04-20 16:08:49 +02:00
|
|
|
this.rightArm.name = "rightArm";
|
2017-10-01 14:00:45 +02:00
|
|
|
this.rightArm.add(rightArmPivot);
|
|
|
|
this.rightArm.position.y = -4;
|
2018-07-02 09:46:48 +02:00
|
|
|
this.modelListeners.push(() => {
|
|
|
|
this.rightArm.position.x = this.slim ? -5.5 : -6;
|
|
|
|
});
|
2017-10-01 14:00:45 +02:00
|
|
|
this.add(this.rightArm);
|
|
|
|
|
|
|
|
// Left Arm
|
2020-01-01 10:18:06 +01:00
|
|
|
const leftArmBox = new BoxGeometry(1, 1, 1, 0, 0, 0); // w/d/h is model-related
|
|
|
|
const leftArmMesh = new Mesh(leftArmBox, layer1Material);
|
2018-07-02 09:46:48 +02:00
|
|
|
this.modelListeners.push(() => {
|
2020-01-30 15:44:25 +01:00
|
|
|
leftArmMesh.scale.x = this.slim ? 3 : 4;
|
|
|
|
leftArmMesh.scale.y = 12;
|
|
|
|
leftArmMesh.scale.z = 4;
|
2018-07-02 09:46:48 +02:00
|
|
|
if (this.slim) {
|
|
|
|
setVertices(leftArmBox,
|
|
|
|
toSkinVertices(36, 48, 39, 52),
|
|
|
|
toSkinVertices(39, 48, 42, 52),
|
|
|
|
toSkinVertices(32, 52, 36, 64),
|
|
|
|
toSkinVertices(36, 52, 39, 64),
|
|
|
|
toSkinVertices(39, 52, 43, 64),
|
|
|
|
toSkinVertices(43, 52, 46, 64)
|
|
|
|
);
|
|
|
|
} else {
|
|
|
|
setVertices(leftArmBox,
|
|
|
|
toSkinVertices(36, 48, 40, 52),
|
|
|
|
toSkinVertices(40, 48, 44, 52),
|
|
|
|
toSkinVertices(32, 52, 36, 64),
|
|
|
|
toSkinVertices(36, 52, 40, 64),
|
|
|
|
toSkinVertices(40, 52, 44, 64),
|
|
|
|
toSkinVertices(44, 52, 48, 64)
|
|
|
|
);
|
|
|
|
}
|
|
|
|
leftArmBox.uvsNeedUpdate = true;
|
2018-07-17 20:49:00 +02:00
|
|
|
leftArmBox.elementsNeedUpdate = true;
|
2018-07-02 09:46:48 +02:00
|
|
|
});
|
|
|
|
|
2020-01-01 10:18:06 +01:00
|
|
|
const leftArm2Box = new BoxGeometry(1, 1, 1, 0, 0, 0); // w/d/h is model-related
|
|
|
|
const leftArm2Mesh = new Mesh(leftArm2Box, layer2Material);
|
2017-10-01 14:00:45 +02:00
|
|
|
leftArm2Mesh.renderOrder = 1;
|
2018-07-02 09:46:48 +02:00
|
|
|
this.modelListeners.push(() => {
|
2020-01-30 15:44:25 +01:00
|
|
|
leftArm2Mesh.scale.x = this.slim ? 3.375 : 4.5;
|
|
|
|
leftArm2Mesh.scale.y = 13.5;
|
|
|
|
leftArm2Mesh.scale.z = 4.5;
|
2018-07-02 09:46:48 +02:00
|
|
|
if (this.slim) {
|
|
|
|
setVertices(leftArm2Box,
|
|
|
|
toSkinVertices(52, 48, 55, 52),
|
|
|
|
toSkinVertices(55, 48, 58, 52),
|
|
|
|
toSkinVertices(48, 52, 52, 64),
|
|
|
|
toSkinVertices(52, 52, 55, 64),
|
|
|
|
toSkinVertices(55, 52, 59, 64),
|
|
|
|
toSkinVertices(59, 52, 62, 64)
|
|
|
|
);
|
|
|
|
} else {
|
|
|
|
setVertices(leftArm2Box,
|
|
|
|
toSkinVertices(52, 48, 56, 52),
|
|
|
|
toSkinVertices(56, 48, 60, 52),
|
|
|
|
toSkinVertices(48, 52, 52, 64),
|
|
|
|
toSkinVertices(52, 52, 56, 64),
|
|
|
|
toSkinVertices(56, 52, 60, 64),
|
|
|
|
toSkinVertices(60, 52, 64, 64)
|
|
|
|
);
|
|
|
|
}
|
|
|
|
leftArm2Box.uvsNeedUpdate = true;
|
|
|
|
leftArm2Box.elementsNeedUpdate = true;
|
|
|
|
});
|
2017-10-01 14:00:45 +02:00
|
|
|
|
2020-01-01 10:18:06 +01:00
|
|
|
const leftArmPivot = new Group();
|
2018-10-20 09:32:56 +02:00
|
|
|
leftArmPivot.add(leftArmMesh, leftArm2Mesh);
|
2017-10-01 14:00:45 +02:00
|
|
|
leftArmPivot.position.y = -6;
|
2018-10-20 09:32:56 +02:00
|
|
|
|
|
|
|
this.leftArm = new BodyPart(leftArmMesh, leftArm2Mesh);
|
2019-04-20 16:08:49 +02:00
|
|
|
this.leftArm.name = "leftArm";
|
2017-10-01 14:00:45 +02:00
|
|
|
this.leftArm.add(leftArmPivot);
|
|
|
|
this.leftArm.position.y = -4;
|
2018-07-02 09:46:48 +02:00
|
|
|
this.modelListeners.push(() => {
|
|
|
|
this.leftArm.position.x = this.slim ? 5.5 : 6;
|
|
|
|
});
|
2017-10-01 14:00:45 +02:00
|
|
|
this.add(this.leftArm);
|
|
|
|
|
|
|
|
// Right Leg
|
2020-01-30 15:44:25 +01:00
|
|
|
const rightLegBox = new BoxGeometry(4, 12, 4, 0, 0, 0);
|
2018-07-02 08:54:49 +02:00
|
|
|
setVertices(rightLegBox,
|
2017-10-01 14:00:45 +02:00
|
|
|
toSkinVertices(4, 16, 8, 20),
|
|
|
|
toSkinVertices(8, 16, 12, 20),
|
|
|
|
toSkinVertices(0, 20, 4, 32),
|
|
|
|
toSkinVertices(4, 20, 8, 32),
|
|
|
|
toSkinVertices(8, 20, 12, 32),
|
|
|
|
toSkinVertices(12, 20, 16, 32)
|
|
|
|
);
|
2020-01-01 10:18:06 +01:00
|
|
|
const rightLegMesh = new Mesh(rightLegBox, layer1Material);
|
2017-10-01 14:00:45 +02:00
|
|
|
|
2020-01-30 15:44:25 +01:00
|
|
|
const rightLeg2Box = new BoxGeometry(4.5, 13.5, 4.5, 0, 0, 0);
|
2018-07-02 08:54:49 +02:00
|
|
|
setVertices(rightLeg2Box,
|
2017-10-01 14:00:45 +02:00
|
|
|
toSkinVertices(4, 32, 8, 36),
|
|
|
|
toSkinVertices(8, 32, 12, 36),
|
|
|
|
toSkinVertices(0, 36, 4, 48),
|
|
|
|
toSkinVertices(4, 36, 8, 48),
|
|
|
|
toSkinVertices(8, 36, 12, 48),
|
|
|
|
toSkinVertices(12, 36, 16, 48)
|
|
|
|
);
|
2020-01-01 10:18:06 +01:00
|
|
|
const rightLeg2Mesh = new Mesh(rightLeg2Box, layer2Material);
|
2017-10-01 14:00:45 +02:00
|
|
|
rightLeg2Mesh.renderOrder = 1;
|
|
|
|
|
2020-01-01 10:18:06 +01:00
|
|
|
const rightLegPivot = new Group();
|
2018-10-20 09:32:56 +02:00
|
|
|
rightLegPivot.add(rightLegMesh, rightLeg2Mesh);
|
2017-10-01 14:00:45 +02:00
|
|
|
rightLegPivot.position.y = -6;
|
2018-10-20 09:32:56 +02:00
|
|
|
|
|
|
|
this.rightLeg = new BodyPart(rightLegMesh, rightLeg2Mesh);
|
2019-05-02 10:33:13 +02:00
|
|
|
this.rightLeg.name = "rightLeg";
|
2017-10-01 14:00:45 +02:00
|
|
|
this.rightLeg.add(rightLegPivot);
|
|
|
|
this.rightLeg.position.y = -16;
|
|
|
|
this.rightLeg.position.x = -2;
|
|
|
|
this.add(this.rightLeg);
|
|
|
|
|
|
|
|
// Left Leg
|
2020-01-30 15:44:25 +01:00
|
|
|
const leftLegBox = new BoxGeometry(4, 12, 4, 0, 0, 0);
|
2018-07-02 08:54:49 +02:00
|
|
|
setVertices(leftLegBox,
|
2017-10-01 14:00:45 +02:00
|
|
|
toSkinVertices(20, 48, 24, 52),
|
|
|
|
toSkinVertices(24, 48, 28, 52),
|
|
|
|
toSkinVertices(16, 52, 20, 64),
|
|
|
|
toSkinVertices(20, 52, 24, 64),
|
|
|
|
toSkinVertices(24, 52, 28, 64),
|
|
|
|
toSkinVertices(28, 52, 32, 64)
|
|
|
|
);
|
2020-01-01 10:18:06 +01:00
|
|
|
const leftLegMesh = new Mesh(leftLegBox, layer1Material);
|
2017-10-01 14:00:45 +02:00
|
|
|
|
2020-01-30 15:44:25 +01:00
|
|
|
const leftLeg2Box = new BoxGeometry(4.5, 13.5, 4.5, 0, 0, 0);
|
2018-07-02 08:54:49 +02:00
|
|
|
setVertices(leftLeg2Box,
|
2017-10-01 14:00:45 +02:00
|
|
|
toSkinVertices(4, 48, 8, 52),
|
|
|
|
toSkinVertices(8, 48, 12, 52),
|
|
|
|
toSkinVertices(0, 52, 4, 64),
|
|
|
|
toSkinVertices(4, 52, 8, 64),
|
|
|
|
toSkinVertices(8, 52, 12, 64),
|
|
|
|
toSkinVertices(12, 52, 16, 64)
|
|
|
|
);
|
2020-01-01 10:18:06 +01:00
|
|
|
const leftLeg2Mesh = new Mesh(leftLeg2Box, layer2Material);
|
2017-10-01 14:00:45 +02:00
|
|
|
leftLeg2Mesh.renderOrder = 1;
|
|
|
|
|
2020-01-01 10:18:06 +01:00
|
|
|
const leftLegPivot = new Group();
|
2018-10-20 09:32:56 +02:00
|
|
|
leftLegPivot.add(leftLegMesh, leftLeg2Mesh);
|
2017-10-01 14:00:45 +02:00
|
|
|
leftLegPivot.position.y = -6;
|
2018-10-20 09:32:56 +02:00
|
|
|
|
|
|
|
this.leftLeg = new BodyPart(leftLegMesh, leftLeg2Mesh);
|
2019-04-20 16:08:49 +02:00
|
|
|
this.leftLeg.name = "leftLeg";
|
2017-10-01 14:00:45 +02:00
|
|
|
this.leftLeg.add(leftLegPivot);
|
|
|
|
this.leftLeg.position.y = -16;
|
|
|
|
this.leftLeg.position.x = 2;
|
|
|
|
this.add(this.leftLeg);
|
2018-07-02 09:46:48 +02:00
|
|
|
|
2018-07-21 16:38:02 +02:00
|
|
|
this.slim = false;
|
2018-07-02 09:46:48 +02:00
|
|
|
}
|
|
|
|
|
2018-07-21 05:07:52 +02:00
|
|
|
get slim() {
|
|
|
|
return this._slim;
|
|
|
|
}
|
2018-07-02 09:46:48 +02:00
|
|
|
|
2018-07-21 05:07:52 +02:00
|
|
|
set slim(value) {
|
2018-07-21 05:41:12 +02:00
|
|
|
this._slim = value;
|
|
|
|
this.modelListeners.forEach(listener => listener());
|
2018-07-21 05:07:52 +02:00
|
|
|
}
|
2018-10-20 09:32:56 +02:00
|
|
|
|
|
|
|
private getBodyParts() {
|
2018-10-20 09:40:52 +02:00
|
|
|
return this.children.filter(it => it instanceof BodyPart) as Array<BodyPart>;
|
2018-10-20 09:32:56 +02:00
|
|
|
}
|
|
|
|
|
2018-10-20 16:11:43 +02:00
|
|
|
setInnerLayerVisible(value: boolean) {
|
2018-10-20 09:32:56 +02:00
|
|
|
this.getBodyParts().forEach(part => part.innerLayer.visible = value);
|
|
|
|
}
|
|
|
|
|
2018-10-20 16:11:43 +02:00
|
|
|
setOuterLayerVisible(value: boolean) {
|
2018-10-20 09:32:56 +02:00
|
|
|
this.getBodyParts().forEach(part => part.outerLayer.visible = value);
|
|
|
|
}
|
2017-10-02 15:29:41 +02:00
|
|
|
}
|
2017-10-01 14:00:45 +02:00
|
|
|
|
2020-01-01 10:18:06 +01:00
|
|
|
export class CapeObject extends Group {
|
2018-07-17 20:49:00 +02:00
|
|
|
|
2020-01-01 10:18:06 +01:00
|
|
|
readonly cape: Mesh;
|
2018-07-17 20:49:00 +02:00
|
|
|
|
2020-01-18 15:54:54 +01:00
|
|
|
constructor(texture: Texture) {
|
2017-10-01 14:00:45 +02:00
|
|
|
super();
|
|
|
|
|
2020-01-18 15:54:54 +01:00
|
|
|
const capeMaterial = new MeshBasicMaterial({ map: texture, transparent: true, opacity: 1, side: DoubleSide, alphaTest: 0.5 });
|
|
|
|
|
2017-10-01 14:00:45 +02:00
|
|
|
// back = outside
|
|
|
|
// front = inside
|
2020-01-01 10:18:06 +01:00
|
|
|
const capeBox = new BoxGeometry(10, 16, 1, 0, 0, 0);
|
2018-07-02 08:54:49 +02:00
|
|
|
setVertices(capeBox,
|
2017-10-01 14:00:45 +02:00
|
|
|
toCapeVertices(1, 0, 11, 1),
|
|
|
|
toCapeVertices(11, 0, 21, 1),
|
|
|
|
toCapeVertices(11, 1, 12, 17),
|
|
|
|
toCapeVertices(12, 1, 22, 17),
|
|
|
|
toCapeVertices(0, 1, 1, 17),
|
|
|
|
toCapeVertices(1, 1, 11, 17)
|
|
|
|
);
|
2020-01-01 10:18:06 +01:00
|
|
|
this.cape = new Mesh(capeBox, capeMaterial);
|
2017-10-01 14:00:45 +02:00
|
|
|
this.cape.position.y = -8;
|
|
|
|
this.cape.position.z = -0.5;
|
|
|
|
this.add(this.cape);
|
|
|
|
}
|
2017-10-02 15:29:41 +02:00
|
|
|
}
|
2017-10-01 14:00:45 +02:00
|
|
|
|
2020-01-01 10:18:06 +01:00
|
|
|
export class PlayerObject extends Group {
|
2018-07-17 20:49:00 +02:00
|
|
|
|
2018-08-17 06:56:13 +02:00
|
|
|
readonly skin: SkinObject;
|
|
|
|
readonly cape: CapeObject;
|
2018-07-17 20:49:00 +02:00
|
|
|
|
2020-01-18 15:54:54 +01:00
|
|
|
constructor(skinTexture: Texture, capeTexture: Texture) {
|
2017-10-01 14:00:45 +02:00
|
|
|
super();
|
|
|
|
|
2020-01-18 15:54:54 +01:00
|
|
|
this.skin = new SkinObject(skinTexture);
|
2019-04-20 16:08:49 +02:00
|
|
|
this.skin.name = "skin";
|
2017-10-01 14:00:45 +02:00
|
|
|
this.add(this.skin);
|
|
|
|
|
2020-01-18 15:54:54 +01:00
|
|
|
this.cape = new CapeObject(capeTexture);
|
2019-04-20 16:08:49 +02:00
|
|
|
this.cape.name = "cape";
|
2017-10-01 14:00:45 +02:00
|
|
|
this.cape.position.z = -2;
|
|
|
|
this.cape.position.y = -4;
|
|
|
|
this.cape.rotation.x = 25 * Math.PI / 180;
|
|
|
|
this.add(this.cape);
|
|
|
|
}
|
2017-10-02 15:29:41 +02:00
|
|
|
}
|