Fix pyramid canvas: enable full rotation and add pixel grid
All checks were successful
Build and Push / build-all (push) Successful in 2m3s
All checks were successful
Build and Push / build-all (push) Successful in 2m3s
- Remove maxPolarAngle limit to allow viewing base from below - Add visible grid lines between pixels (4x4 texture per pixel) - Update texture functions for new grid format Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
aa96b78f48
commit
5ab1da2a1f
1 changed files with 85 additions and 43 deletions
|
|
@ -96,31 +96,49 @@
|
|||
|
||||
function createDataTexture(faceData) {
|
||||
const size = FACE_SIZE;
|
||||
const data = new Uint8Array(size * size * 4);
|
||||
// Use larger texture for grid lines (each pixel is 4x4 with 1px grid)
|
||||
const texSize = size * 4;
|
||||
const data = new Uint8Array(texSize * texSize * 4);
|
||||
|
||||
// Fill with default color (dark gray)
|
||||
for (let i = 0; i < size * size; i++) {
|
||||
data[i * 4] = 34; // R
|
||||
data[i * 4 + 1] = 34; // G
|
||||
data[i * 4 + 2] = 34; // B
|
||||
data[i * 4 + 3] = 255; // A
|
||||
}
|
||||
// Fill with grid pattern
|
||||
for (let py = 0; py < size; py++) {
|
||||
for (let px = 0; px < size; px++) {
|
||||
// Get pixel color (default dark gray or from faceData)
|
||||
let r = 40, g = 40, b = 40;
|
||||
|
||||
// Apply pixel data from the face map
|
||||
if (faceData) {
|
||||
faceData.forEach((color, key) => {
|
||||
const [x, y] = key.split(',').map(Number);
|
||||
const idx = (y * size + x) * 4;
|
||||
const key = `${px},${py}`;
|
||||
const color = faceData.get(key);
|
||||
if (color) {
|
||||
const rgb = hexToRgb(color);
|
||||
if (rgb) {
|
||||
data[idx] = rgb.r;
|
||||
data[idx + 1] = rgb.g;
|
||||
data[idx + 2] = rgb.b;
|
||||
if (rgb) { r = rgb.r; g = rgb.g; b = rgb.b; }
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const texture = new THREE.DataTexture(data, size, size, THREE.RGBAFormat);
|
||||
// Draw 4x4 pixel block with 1px grid border
|
||||
for (let dy = 0; dy < 4; dy++) {
|
||||
for (let dx = 0; dx < 4; dx++) {
|
||||
const tx = px * 4 + dx;
|
||||
const ty = py * 4 + dy;
|
||||
const idx = (ty * texSize + tx) * 4;
|
||||
|
||||
// Grid lines on edges (darker)
|
||||
if (dx === 0 || dy === 0) {
|
||||
data[idx] = 20;
|
||||
data[idx + 1] = 20;
|
||||
data[idx + 2] = 20;
|
||||
} else {
|
||||
data[idx] = r;
|
||||
data[idx + 1] = g;
|
||||
data[idx + 2] = b;
|
||||
}
|
||||
data[idx + 3] = 255;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const texture = new THREE.DataTexture(data, texSize, texSize, THREE.RGBAFormat);
|
||||
texture.needsUpdate = true;
|
||||
texture.magFilter = THREE.NearestFilter;
|
||||
texture.minFilter = THREE.NearestFilter;
|
||||
|
|
@ -225,7 +243,8 @@
|
|||
controls.screenSpacePanning = false;
|
||||
controls.minDistance = 100;
|
||||
controls.maxDistance = 500;
|
||||
controls.maxPolarAngle = Math.PI / 2 - 0.1;
|
||||
// Allow full rotation to view base from below
|
||||
controls.maxPolarAngle = Math.PI;
|
||||
controls.target.set(0, 50, 0);
|
||||
controls.update();
|
||||
}
|
||||
|
|
@ -291,26 +310,41 @@
|
|||
|
||||
const texture = faceTextures[faceId];
|
||||
const size = FACE_SIZE;
|
||||
const texSize = size * 4;
|
||||
|
||||
// Reset to default color
|
||||
for (let i = 0; i < size * size; i++) {
|
||||
texture.image.data[i * 4] = 34;
|
||||
texture.image.data[i * 4 + 1] = 34;
|
||||
texture.image.data[i * 4 + 2] = 34;
|
||||
}
|
||||
|
||||
// Apply pixel data
|
||||
// Reset with grid pattern
|
||||
for (let py = 0; py < size; py++) {
|
||||
for (let px = 0; px < size; px++) {
|
||||
// Get pixel color
|
||||
let r = 40, g = 40, b = 40;
|
||||
if (faceData) {
|
||||
faceData.forEach((color, key) => {
|
||||
const [x, y] = key.split(',').map(Number);
|
||||
const idx = (y * size + x) * 4;
|
||||
const key = `${px},${py}`;
|
||||
const color = faceData.get(key);
|
||||
if (color) {
|
||||
const rgb = hexToRgb(color);
|
||||
if (rgb) {
|
||||
texture.image.data[idx] = rgb.r;
|
||||
texture.image.data[idx + 1] = rgb.g;
|
||||
texture.image.data[idx + 2] = rgb.b;
|
||||
if (rgb) { r = rgb.r; g = rgb.g; b = rgb.b; }
|
||||
}
|
||||
}
|
||||
|
||||
// Draw 4x4 block with grid
|
||||
for (let dy = 0; dy < 4; dy++) {
|
||||
for (let dx = 0; dx < 4; dx++) {
|
||||
const tx = px * 4 + dx;
|
||||
const ty = py * 4 + dy;
|
||||
const idx = (ty * texSize + tx) * 4;
|
||||
|
||||
if (dx === 0 || dy === 0) {
|
||||
texture.image.data[idx] = 20;
|
||||
texture.image.data[idx + 1] = 20;
|
||||
texture.image.data[idx + 2] = 20;
|
||||
} else {
|
||||
texture.image.data[idx] = r;
|
||||
texture.image.data[idx + 1] = g;
|
||||
texture.image.data[idx + 2] = b;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
texture.needsUpdate = true;
|
||||
|
|
@ -321,13 +355,21 @@
|
|||
if (!faceTextures[faceId]) return;
|
||||
|
||||
const texture = faceTextures[faceId];
|
||||
const idx = (y * FACE_SIZE + x) * 4;
|
||||
const texSize = FACE_SIZE * 4;
|
||||
const rgb = hexToRgb(color);
|
||||
|
||||
if (rgb) {
|
||||
// Update 4x4 block (skip grid lines at dx=0, dy=0)
|
||||
for (let dy = 1; dy < 4; dy++) {
|
||||
for (let dx = 1; dx < 4; dx++) {
|
||||
const tx = x * 4 + dx;
|
||||
const ty = y * 4 + dy;
|
||||
const idx = (ty * texSize + tx) * 4;
|
||||
texture.image.data[idx] = rgb.r;
|
||||
texture.image.data[idx + 1] = rgb.g;
|
||||
texture.image.data[idx + 2] = rgb.b;
|
||||
}
|
||||
}
|
||||
texture.needsUpdate = true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue