1
0
mirror of https://github.com/misskey-dev/misskey.git synced 2026-05-14 04:05:34 +02:00
This commit is contained in:
syuilo
2026-04-18 15:08:36 +09:00
parent d1555d5423
commit 47cd092380
3 changed files with 122 additions and 25 deletions

View File

@@ -236,7 +236,7 @@ export class WorldEngine extends EventEmitter<WorldEngineEvents> {
messageRing.rotation = messageRing.rotationQuaternion.toEulerAngles();
messageRing.rotationQuaternion = null;
const text = new RecyvlingTextGrid(messageRing, 256, {
dir: 'left',
meshFlipped: true,
material: this.textMaterial,
});
@@ -247,7 +247,7 @@ export class WorldEngine extends EventEmitter<WorldEngineEvents> {
const anim = new BABYLON.Animation('', 'rotation.y', 60, BABYLON.Animation.ANIMATIONTYPE_FLOAT, BABYLON.Animation.ANIMATIONLOOPMODE_CYCLE);
anim.setKeys([
{ frame: 0, value: 0 },
{ frame: 10000, value: Math.PI * 2 },
{ frame: 10000, value: -(Math.PI * 2) },
]);
messageRing.animations = [anim];
this.scene.beginAnimation(messageRing, 0, 10000, true);
@@ -271,6 +271,66 @@ export class WorldEngine extends EventEmitter<WorldEngineEvents> {
}, 10000);
}
{
const messageRingRoot = new BABYLON.TransformNode('', this.scene);
const messageRing = envObj.meshes.find(m => m.name.includes('__MESSAGE_RING_INNER_1__'));
messageRing.parent = messageRingRoot;
messageRing.rotation = messageRing.rotationQuaternion.toEulerAngles();
messageRing.rotationQuaternion = null;
const text = new RecyvlingTextGrid(messageRing, 64, {
material: this.textMaterial,
repeatSeparator: ' ',
});
//messageRingRoot.rotation.x = Math.PI / 4;
const anim = new BABYLON.Animation('', 'rotation.y', 60, BABYLON.Animation.ANIMATIONTYPE_FLOAT, BABYLON.Animation.ANIMATIONLOOPMODE_CYCLE);
anim.setKeys([
{ frame: 0, value: 0 },
{ frame: 10000, value: (Math.PI * 2) },
]);
messageRing.animations = [anim];
this.scene.beginAnimation(messageRing, 0, 10000, true);
setInterval(() => {
const now = new Date();
const hours = now.getHours().toString().padStart(2, '0');
const minutes = now.getMinutes().toString().padStart(2, '0');
const seconds = now.getSeconds().toString().padStart(2, '0');
text.write(`${hours}:${minutes}:${seconds}`);
}, 1000);
}
{
const messageRingRoot = new BABYLON.TransformNode('', this.scene);
const messageRing = envObj.meshes.find(m => m.name.includes('__MESSAGE_RING_INNER_2__'));
messageRing.parent = messageRingRoot;
messageRing.rotation = messageRing.rotationQuaternion.toEulerAngles();
messageRing.rotationQuaternion = null;
const text = new RecyvlingTextGrid(messageRing, 64, {
material: this.textMaterial,
repeatSeparator: ' ',
});
//messageRingRoot.rotation.x = Math.PI / 4;
const anim = new BABYLON.Animation('', 'rotation.y', 60, BABYLON.Animation.ANIMATIONTYPE_FLOAT, BABYLON.Animation.ANIMATIONLOOPMODE_CYCLE);
anim.setKeys([
{ frame: 0, value: 0 },
{ frame: 10000, value: -(Math.PI * 2) },
]);
messageRing.animations = [anim];
this.scene.beginAnimation(messageRing, 0, 10000, true);
setInterval(() => {
const now = new Date();
const years = now.getFullYear().toString();
const months = (now.getMonth() + 1).toString().padStart(2, '0');
const days = now.getDate().toString().padStart(2, '0');
text.write(`${years}/${months}/${days}`);
}, 1000);
}
for (let i = 0; i < 16; i++) {
const sphereRoot = new BABYLON.TransformNode('', this.scene);
sphereRoot.position = new BABYLON.Vector3(cm(0), cm(1000 + (100 * i)), cm(0));

View File

@@ -502,9 +502,13 @@ export class RecyvlingTextGrid {
public mesh: BABYLON.Mesh;
private originalUvs: BABYLON.FloatArray;
private currentText = '';
private meshFlipped: boolean;
private repeatSeparator: string;
constructor(mesh: BABYLON.Mesh, facesCount: number, options: {
meshFlipped: boolean;
material: BABYLON.StandardMaterial;
repeatSeparator?: string;
}) {
this.mesh = mesh;
this.mesh.material = options.material;
@@ -513,6 +517,8 @@ export class RecyvlingTextGrid {
this.facesCount = facesCount;
this.originalUvs = mesh.getVerticesData(BABYLON.VertexBuffer.UVKind)!.slice();
this.meshFlipped = options.meshFlipped;
this.repeatSeparator = options.repeatSeparator ?? ' ■ ';
//this.write('');
}
@@ -522,17 +528,16 @@ export class RecyvlingTextGrid {
const charIndexes: number[] = [];
const repeatSeparator = ' ■ ';
let maxRepeat = Math.ceil(this.facesCount / text.length);
if (maxRepeat > 1) {
text += repeatSeparator;
text += this.repeatSeparator;
maxRepeat = Math.ceil(this.facesCount / text.length);
}
for (let i = 0; i < this.facesCount; i++) {
if (i + text.length >= (maxRepeat * text.length)) {
if (i >= this.facesCount - repeatSeparator.length) {
charIndexes.push(TEXT_TEXTURE_CHAR_MAP[repeatSeparator[(i - (this.facesCount - repeatSeparator.length)) % repeatSeparator.length]]);
if (i >= this.facesCount - this.repeatSeparator.length) {
charIndexes.push(TEXT_TEXTURE_CHAR_MAP[this.repeatSeparator[(i - (this.facesCount - this.repeatSeparator.length)) % this.repeatSeparator.length]]);
} else {
charIndexes.push(TEXT_TEXTURE_CHAR_MAP[' ']);
}
@@ -554,13 +559,18 @@ export class RecyvlingTextGrid {
const verticesCountPerFace = 6; // ひとつの四角はふたつの三角に分割されるので 3*2=6
for (let i = 0; i < this.facesCount; i++) {
const charIndex = charIndexes[i];
const charIndex = charIndexes[this.meshFlipped ? i : (this.facesCount - i - 1)];
const charX = charIndex % TEXT_TEXTURE_CHAR_COLS;
const charY = Math.floor(charIndex / TEXT_TEXTURE_CHAR_COLS);
const uvIndex = i * (verticesCountPerFace * 2); // uvは(x,y)の2要素なので*2
/*
/* (non-flipped)
a d--e
| \ \ |
b--c f
*/
/* (flipped)
a--b d
| / / |
c e--f
@@ -577,30 +587,57 @@ export class RecyvlingTextGrid {
const y = uvs[uvIndex + j + 1];
// 多少ずれがあってもいいように(例えばblenderではUV展開時にデフォルトでわずかなマージンを追加する)、中心より大きいか/小さいかで判定する
if (this.meshFlipped) {
// ひとつの四角はふたつの三角に分割される。右下に来る三角(d-e-f)の方が先にくるっぽい
if (j >= 6) {
if (x < 0.5 && y < 0.5) {
aIndex = j;
} else if (x > 0.5 && y < 0.5) {
bIndex = j;
} else if (x < 0.5 && y > 0.5) {
cIndex = j;
if (j >= 6) {
if (x < 0.5 && y < 0.5) {
aIndex = j;
} else if (x > 0.5 && y < 0.5) {
bIndex = j;
} else if (x < 0.5 && y > 0.5) {
cIndex = j;
}
} else {
if (x > 0.5 && y < 0.5) {
dIndex = j;
} else if (x < 0.5 && y > 0.5) {
eIndex = j;
} else if (x > 0.5 && y > 0.5) {
fIndex = j;
}
}
} else {
if (x > 0.5 && y < 0.5) {
dIndex = j;
} else if (x < 0.5 && y > 0.5) {
eIndex = j;
} else if (x > 0.5 && y > 0.5) {
fIndex = j;
if (j >= 6) {
if (x < 0.5 && y < 0.5) {
aIndex = j;
} else if (x < 0.5 && y > 0.5) {
bIndex = j;
} else if (x > 0.5 && y > 0.5) {
cIndex = j;
}
} else {
if (x < 0.5 && y < 0.5) {
dIndex = j;
} else if (x > 0.5 && y < 0.5) {
eIndex = j;
} else if (x > 0.5 && y > 0.5) {
fIndex = j;
}
}
}
}
uvs[uvIndex + aIndex + 0] = uvs[uvIndex + cIndex + 0] = uvs[uvIndex + eIndex + 0] = charX / TEXT_TEXTURE_CHAR_COLS;
uvs[uvIndex + aIndex + 1] = uvs[uvIndex + bIndex + 1] = uvs[uvIndex + dIndex + 1] = charY / TEXT_TEXTURE_CHAR_ROWS;
uvs[uvIndex + bIndex + 0] = uvs[uvIndex + dIndex + 0] = uvs[uvIndex + fIndex + 0] = (charX + 1) / TEXT_TEXTURE_CHAR_COLS;
uvs[uvIndex + cIndex + 1] = uvs[uvIndex + eIndex + 1] = uvs[uvIndex + fIndex + 1] = (charY + 1) / TEXT_TEXTURE_CHAR_ROWS;
if (this.meshFlipped) {
uvs[uvIndex + aIndex + 0] = uvs[uvIndex + cIndex + 0] = uvs[uvIndex + eIndex + 0] = charX / TEXT_TEXTURE_CHAR_COLS;
uvs[uvIndex + aIndex + 1] = uvs[uvIndex + bIndex + 1] = uvs[uvIndex + dIndex + 1] = charY / TEXT_TEXTURE_CHAR_ROWS;
uvs[uvIndex + bIndex + 0] = uvs[uvIndex + dIndex + 0] = uvs[uvIndex + fIndex + 0] = (charX + 1) / TEXT_TEXTURE_CHAR_COLS;
uvs[uvIndex + cIndex + 1] = uvs[uvIndex + eIndex + 1] = uvs[uvIndex + fIndex + 1] = (charY + 1) / TEXT_TEXTURE_CHAR_ROWS;
} else {
uvs[uvIndex + aIndex + 0] = uvs[uvIndex + dIndex + 0] = uvs[uvIndex + bIndex + 0] = charX / TEXT_TEXTURE_CHAR_COLS;
uvs[uvIndex + aIndex + 1] = uvs[uvIndex + dIndex + 1] = uvs[uvIndex + eIndex + 1] = charY / TEXT_TEXTURE_CHAR_ROWS;
uvs[uvIndex + eIndex + 0] = uvs[uvIndex + fIndex + 0] = uvs[uvIndex + cIndex + 0] = (charX + 1) / TEXT_TEXTURE_CHAR_COLS;
uvs[uvIndex + bIndex + 1] = uvs[uvIndex + cIndex + 1] = uvs[uvIndex + fIndex + 1] = (charY + 1) / TEXT_TEXTURE_CHAR_ROWS;
}
}
this.mesh.updateVerticesData(BABYLON.VertexBuffer.UVKind, uvs);