Skip to content

Instantly share code, notes, and snippets.

@PabloAlexandre
Last active April 29, 2023 02:53
Show Gist options
  • Save PabloAlexandre/a6106ac98c0d4d65498e76d67e2a1f3c to your computer and use it in GitHub Desktop.
Save PabloAlexandre/a6106ac98c0d4d65498e76d67e2a1f3c to your computer and use it in GitHub Desktop.
Function to get UV points from 3D coordinate in cubemap images
export interface Vector3 {
x: number;
y: number;
z: number;
}
export function get3DPointFromSphere(phi: number, theta: number) {
const coordinates = {x: 0, y: 0, z: 0};
coordinates.x = Math.sin(theta) * Math.cos(phi);
coordinates.y = Math.sin(theta) * Math.sin(phi);
coordinates.z = Math.cos(theta);
return coordinates;
}
export function getParallelVector(coordinates: Vector3) {
const maximumSegment = Math.max(Math.abs(coordinates.x), Math.abs(coordinates.y), Math.abs(coordinates.z));
return {
x: coordinates.x / maximumSegment,
y: coordinates.y / maximumSegment,
z: coordinates.z / maximumSegment
}
}
interface Pixels {
x: number;
y: number;
}
const directionsMapper = {
RIGHT: ({ x }: Vector3) => x === 1,
LEFT: ({ x }: Vector3) => x === -1,
TOP: ({ y }: Vector3) => y === 1,
DOWN: ({ y }: Vector3) => y === -1,
FRONT: ({ z }: Vector3) => z === 1,
BACK: ({ z }: Vector3) => z === -1,
}
const uvMapper = {
RIGHT: ({ y, z }: Vector3, cubemapSize: number, tileSize: number ) => ({
xPixel: Math.ceil( ( ( z + 1 ) / 2 )-1 ) * cubemapSize,
yPixel: Math.ceil( ( y + 1 ) / 2 ) * cubemapSize,
xOffset: 2 * tileSize,
yOffset: tileSize,
}),
LEFT: ({ y, z }: Vector3, cubemapSize: number, tileSize: number ) => ({
xPixel: Math.ceil( ( z + 1 ) / 2 ) * cubemapSize,
yPixel: Math.ceil( ( y + 1 ) / 2 ) * cubemapSize,
xOffset: 0,
yOffset: tileSize,
}),
TOP: ({ x, z }: Vector3, cubemapSize: number, tileSize: number ) => ({
xPixel: Math.ceil( ( x + 1 ) / 2 ) * cubemapSize,
yPixel: Math.ceil( ( ( z + 1 ) / 2 )-1 ) * cubemapSize,
xOffset: tileSize,
yOffset: 2 * tileSize,
}),
DOWN: ({ x, z }: Vector3, cubemapSize: number, tileSize: number ) => ({
xPixel: Math.ceil( ( x + 1 ) / 2 ) * cubemapSize,
yPixel: Math.ceil( ( z + 1 ) / 2 ) * cubemapSize,
xOffset: tileSize,
yOffset: 0,
}),
FRONT: ({ x, y }: Vector3, cubemapSize: number, tileSize: number ) => ({
xPixel: Math.ceil( ( x + 1 ) / 2 ) * cubemapSize,
yPixel: Math.ceil( ( y + 1 ) / 2 ) * cubemapSize,
xOffset: 3 * tileSize,
yOffset: tileSize,
}),
BACK: ({ x, y }: Vector3, cubemapSize: number, tileSize: number ) => ({
xPixel: Math.ceil( ( ( x + 1 ) / 2 )-1 ) * cubemapSize,
yPixel: Math.ceil( ( y + 1 ) / 2 ) * cubemapSize,
xOffset: 3 * tileSize,
yOffset: tileSize,
}),
}
export function getPixelsFromCoordinates(
coordinate: Vector3,
cubemapSize: number,
cubemapTileSize: number
): Pixels {
const [ direction ] = Object
.entries(directionsMapper)
.find(([, validator ]) => {
return validator(coordinate);
})!;
const points = uvMapper[direction as keyof typeof uvMapper](coordinate, cubemapSize, cubemapTileSize);
const pixels = {
x: Math.abs(points.xPixel) + points.xOffset,
y: Math.abs(points.yPixel) + points.yOffset,
};
return pixels;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment