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) {
|
function createDataTexture(faceData) {
|
||||||
const size = FACE_SIZE;
|
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)
|
// Fill with grid pattern
|
||||||
for (let i = 0; i < size * size; i++) {
|
for (let py = 0; py < size; py++) {
|
||||||
data[i * 4] = 34; // R
|
for (let px = 0; px < size; px++) {
|
||||||
data[i * 4 + 1] = 34; // G
|
// Get pixel color (default dark gray or from faceData)
|
||||||
data[i * 4 + 2] = 34; // B
|
let r = 40, g = 40, b = 40;
|
||||||
data[i * 4 + 3] = 255; // A
|
|
||||||
}
|
|
||||||
|
|
||||||
// Apply pixel data from the face map
|
if (faceData) {
|
||||||
if (faceData) {
|
const key = `${px},${py}`;
|
||||||
faceData.forEach((color, key) => {
|
const color = faceData.get(key);
|
||||||
const [x, y] = key.split(',').map(Number);
|
if (color) {
|
||||||
const idx = (y * size + x) * 4;
|
const rgb = hexToRgb(color);
|
||||||
const rgb = hexToRgb(color);
|
if (rgb) { r = rgb.r; g = rgb.g; b = rgb.b; }
|
||||||
if (rgb) {
|
}
|
||||||
data[idx] = rgb.r;
|
|
||||||
data[idx + 1] = rgb.g;
|
|
||||||
data[idx + 2] = rgb.b;
|
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
// 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, size, size, THREE.RGBAFormat);
|
const texture = new THREE.DataTexture(data, texSize, texSize, THREE.RGBAFormat);
|
||||||
texture.needsUpdate = true;
|
texture.needsUpdate = true;
|
||||||
texture.magFilter = THREE.NearestFilter;
|
texture.magFilter = THREE.NearestFilter;
|
||||||
texture.minFilter = THREE.NearestFilter;
|
texture.minFilter = THREE.NearestFilter;
|
||||||
|
|
@ -225,7 +243,8 @@
|
||||||
controls.screenSpacePanning = false;
|
controls.screenSpacePanning = false;
|
||||||
controls.minDistance = 100;
|
controls.minDistance = 100;
|
||||||
controls.maxDistance = 500;
|
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.target.set(0, 50, 0);
|
||||||
controls.update();
|
controls.update();
|
||||||
}
|
}
|
||||||
|
|
@ -291,26 +310,41 @@
|
||||||
|
|
||||||
const texture = faceTextures[faceId];
|
const texture = faceTextures[faceId];
|
||||||
const size = FACE_SIZE;
|
const size = FACE_SIZE;
|
||||||
|
const texSize = size * 4;
|
||||||
|
|
||||||
// Reset to default color
|
// Reset with grid pattern
|
||||||
for (let i = 0; i < size * size; i++) {
|
for (let py = 0; py < size; py++) {
|
||||||
texture.image.data[i * 4] = 34;
|
for (let px = 0; px < size; px++) {
|
||||||
texture.image.data[i * 4 + 1] = 34;
|
// Get pixel color
|
||||||
texture.image.data[i * 4 + 2] = 34;
|
let r = 40, g = 40, b = 40;
|
||||||
}
|
if (faceData) {
|
||||||
|
const key = `${px},${py}`;
|
||||||
// Apply pixel data
|
const color = faceData.get(key);
|
||||||
if (faceData) {
|
if (color) {
|
||||||
faceData.forEach((color, key) => {
|
const rgb = hexToRgb(color);
|
||||||
const [x, y] = key.split(',').map(Number);
|
if (rgb) { r = rgb.r; g = rgb.g; b = rgb.b; }
|
||||||
const idx = (y * size + x) * 4;
|
}
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
// 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;
|
texture.needsUpdate = true;
|
||||||
|
|
@ -321,13 +355,21 @@
|
||||||
if (!faceTextures[faceId]) return;
|
if (!faceTextures[faceId]) return;
|
||||||
|
|
||||||
const texture = faceTextures[faceId];
|
const texture = faceTextures[faceId];
|
||||||
const idx = (y * FACE_SIZE + x) * 4;
|
const texSize = FACE_SIZE * 4;
|
||||||
const rgb = hexToRgb(color);
|
const rgb = hexToRgb(color);
|
||||||
|
|
||||||
if (rgb) {
|
if (rgb) {
|
||||||
texture.image.data[idx] = rgb.r;
|
// Update 4x4 block (skip grid lines at dx=0, dy=0)
|
||||||
texture.image.data[idx + 1] = rgb.g;
|
for (let dy = 1; dy < 4; dy++) {
|
||||||
texture.image.data[idx + 2] = rgb.b;
|
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;
|
texture.needsUpdate = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue