scale down, add hash, allow vampires, add mobile fixes
This commit is contained in:
parent
e0e8c94593
commit
c47d712624
5 changed files with 87 additions and 26 deletions
|
@ -18,13 +18,29 @@
|
||||||
|
|
||||||
.wizard {
|
.wizard {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
padding: 25px;
|
width: calc(100% - 50px);
|
||||||
width: 100%;
|
left: 25px;
|
||||||
bottom: 0;
|
bottom: 25px;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
background: rgba(255, 255, 255, 0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width:600px) {
|
||||||
|
body {
|
||||||
|
font-size: 1.3em;
|
||||||
|
}
|
||||||
|
|
||||||
|
input, select {
|
||||||
|
font-size: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
width: 5em;
|
||||||
|
height: 3em;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
|
|
|
@ -17,8 +17,8 @@ export class HeadRenderer {
|
||||||
this.renderer.setSize(W, H);
|
this.renderer.setSize(W, H);
|
||||||
document.body.appendChild(this.renderer.domElement);
|
document.body.appendChild(this.renderer.domElement);
|
||||||
|
|
||||||
this.camera = new THREE.PerspectiveCamera(70, W / H, 1, 2000);
|
this.camera = new THREE.PerspectiveCamera(70, W / H, 1, 200);
|
||||||
this.camera.position.z = 600;
|
this.camera.position.z = 60;
|
||||||
|
|
||||||
this.scene = new THREE.Scene();
|
this.scene = new THREE.Scene();
|
||||||
this.scene.background = new Color(0xffffff);
|
this.scene.background = new Color(0xffffff);
|
||||||
|
|
|
@ -48,7 +48,7 @@ export class Shape {
|
||||||
const params = {
|
const params = {
|
||||||
color: 0xffffff,
|
color: 0xffffff,
|
||||||
transparent: true,
|
transparent: true,
|
||||||
alphaTest: 0.5,
|
alphaTest: 0.2,
|
||||||
};
|
};
|
||||||
if (this.textureInfo) {
|
if (this.textureInfo) {
|
||||||
let Loader;
|
let Loader;
|
||||||
|
@ -129,7 +129,7 @@ export class Shape {
|
||||||
geometry.translate(this.translation[0], this.translation[1], this.translation[2]);
|
geometry.translate(this.translation[0], this.translation[1], this.translation[2]);
|
||||||
|
|
||||||
// Scale up a bit
|
// Scale up a bit
|
||||||
geometry.scale(20, 20, 20);
|
geometry.scale(2, 2, 2);
|
||||||
|
|
||||||
// Rotate the face so it faces us \o/
|
// Rotate the face so it faces us \o/
|
||||||
geometry.rotateX(290 * (Math.PI / 180));
|
geometry.rotateX(290 * (Math.PI / 180));
|
||||||
|
|
|
@ -23,4 +23,6 @@ export class ShapeCollection {
|
||||||
|
|
||||||
return this.group
|
return this.group
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
window.ShapeCollection = ShapeCollection;
|
79
src/index.js
79
src/index.js
|
@ -25,7 +25,8 @@ window.addEventListener("load", async () => {
|
||||||
|
|
||||||
part1.innerHTML = "";
|
part1.innerHTML = "";
|
||||||
part2.innerHTML = "";
|
part2.innerHTML = "";
|
||||||
const indexed = {};
|
const indexed = window.indexed = {};
|
||||||
|
const byName = window.byName = {};
|
||||||
const tree = {};
|
const tree = {};
|
||||||
const shapeCache = {};
|
const shapeCache = {};
|
||||||
|
|
||||||
|
@ -33,30 +34,22 @@ window.addEventListener("load", async () => {
|
||||||
headRenderer.expose();
|
headRenderer.expose();
|
||||||
|
|
||||||
for (let mesh of allMeshes) {
|
for (let mesh of allMeshes) {
|
||||||
let [_, x, race, gender, part, nr = undefined] = mesh.name.split('_');
|
let [_, __, race, gender, part, nr = undefined] = mesh.name.split('_');
|
||||||
race = race.replace(new RegExp("\\s+"), ' ');
|
race = race.replace(new RegExp("\\s+"), ' ');
|
||||||
if (race.toLowerCase() === "khajiit") {
|
|
||||||
console.log(part, mesh.name, nr);
|
if (race === 'DarkElf') {
|
||||||
|
race = 'Dark Elf'
|
||||||
}
|
}
|
||||||
|
|
||||||
if (x !== 'N') {
|
if (nr === undefined && !['head', 'hair'].includes(part.toLowerCase())) {
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nr === undefined) {
|
|
||||||
[_, part, nr] = part.match(/(head|hair)(\d+)?/i) || [];
|
[_, part, nr] = part.match(/(head|hair)(\d+)?/i) || [];
|
||||||
console.log(part);
|
|
||||||
|
|
||||||
if (!nr) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let option = document.createElement("option");
|
let option = document.createElement("option");
|
||||||
option.textContent = mesh.name;
|
option.textContent = mesh.name;
|
||||||
option.value = mesh.id = uuidv4();
|
option.value = mesh.id = uuidv4();
|
||||||
indexed[mesh.id] = mesh;
|
indexed[mesh.id] = mesh;
|
||||||
|
byName[mesh.name] = mesh.id;
|
||||||
|
|
||||||
if (mesh.name.toLowerCase().indexOf("hair") !== -1) {
|
if (mesh.name.toLowerCase().indexOf("hair") !== -1) {
|
||||||
part1.appendChild(option);
|
part1.appendChild(option);
|
||||||
|
@ -89,7 +82,7 @@ window.addEventListener("load", async () => {
|
||||||
setRace(race.value);
|
setRace(race.value);
|
||||||
});
|
});
|
||||||
|
|
||||||
function setRace(name) {
|
function setRace(name, propagate = true) {
|
||||||
race.value = name;
|
race.value = name;
|
||||||
gender.innerHTML = "";
|
gender.innerHTML = "";
|
||||||
for (let genderX in tree[name]) {
|
for (let genderX in tree[name]) {
|
||||||
|
@ -99,7 +92,9 @@ window.addEventListener("load", async () => {
|
||||||
gender.appendChild(option);
|
gender.appendChild(option);
|
||||||
}
|
}
|
||||||
|
|
||||||
setGender(gender.value)
|
if (propagate) {
|
||||||
|
setGender(gender.value)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gender.addEventListener("change", () => {
|
gender.addEventListener("change", () => {
|
||||||
|
@ -112,19 +107,66 @@ window.addEventListener("load", async () => {
|
||||||
setHead(tree[race.value][name]['head'][0]);
|
setHead(tree[race.value][name]['head'][0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
setRace("Dark Elf");
|
// Collect hash query before setting defaults
|
||||||
|
let q = collectHashQuery();
|
||||||
|
|
||||||
|
// Dark Elf / M is what Morrowind starts you with
|
||||||
|
setRace("Dark Elf", false);
|
||||||
setGender("M");
|
setGender("M");
|
||||||
|
|
||||||
|
updateFromHash(q);
|
||||||
|
|
||||||
|
function collectHashQuery() {
|
||||||
|
return location.hash.substr(1).split('&').reduce((c, x) => {
|
||||||
|
let [name, value = ""] = x.split('=', 2).map(y => decodeURIComponent(y));
|
||||||
|
c[name] = value;
|
||||||
|
return c;
|
||||||
|
}, {});
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateFromHash(q) {
|
||||||
|
if (!q) {
|
||||||
|
q = collectHashQuery();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (byName[q['head']] && q['head'].toLowerCase().includes('head')) {
|
||||||
|
setHead(byName[q['head']]);
|
||||||
|
} else {
|
||||||
|
if (q['head']) {
|
||||||
|
console.log("No head found with name: ", q['head']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (byName[q['hair']] && q['hair'].toLowerCase().includes('hair')) {
|
||||||
|
setHair(byName[q['hair']]);
|
||||||
|
} else {
|
||||||
|
if (q['hair']) {
|
||||||
|
console.log("No hair found with name: ", q['hair']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
updateFromHash();
|
||||||
|
|
||||||
|
window.addEventListener('hashchange', () => {
|
||||||
|
updateFromHash();
|
||||||
|
});
|
||||||
|
|
||||||
function getShape(name) {
|
function getShape(name) {
|
||||||
return new ShapeCollection(indexed[name], "blob/textures/");
|
return new ShapeCollection(indexed[name], "blob/textures/");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function updateHash() {
|
||||||
|
location.hash = `head=${encodeURIComponent(indexed[part2.value].name)}&hair=${encodeURIComponent(indexed[part1.value].name)}`;
|
||||||
|
}
|
||||||
|
|
||||||
function setHair(id) {
|
function setHair(id) {
|
||||||
part1.value = id;
|
part1.value = id;
|
||||||
if (shape1 !== null) {
|
if (shape1 !== null) {
|
||||||
headRenderer.remove(shape1);
|
headRenderer.remove(shape1);
|
||||||
}
|
}
|
||||||
headRenderer.add(shape1 = getShape(id));
|
headRenderer.add(shape1 = getShape(id));
|
||||||
|
updateHash();
|
||||||
}
|
}
|
||||||
|
|
||||||
part1.addEventListener("change", () => {
|
part1.addEventListener("change", () => {
|
||||||
|
@ -147,6 +189,7 @@ window.addEventListener("load", async () => {
|
||||||
headRenderer.remove(shape2);
|
headRenderer.remove(shape2);
|
||||||
}
|
}
|
||||||
headRenderer.add(shape2 = getShape(id));
|
headRenderer.add(shape2 = getShape(id));
|
||||||
|
updateHash();
|
||||||
}
|
}
|
||||||
|
|
||||||
part2.addEventListener("change", () => {
|
part2.addEventListener("change", () => {
|
||||||
|
|
Loading…
Reference in a new issue