do mojego kodu dodaj aby faktycznie dało się już poruszyć pionkiem z animacją lewitacji po krzywej w powietrzu do danego miejsca, nie skracaj kodu i pokaż go w całości:

import * as THREE from 'three';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader'; 
import { RGBELoader } from 'three/examples/jsm/Addons.js';

let chessArray = [
    [-4, -2, -3, -5, -6, -3, -2, -4],
    [-1, -1, -1, -1, -1, -1, -1, -1],
    [0, 0, 0, 0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0, 0, 0, 0],
    [1, 1, 1, 1, 1, 1, 1, 1],
    [4, 2, 3, 5, 6, 3, 2, 4],
];

class ChessSquare {
    constructor(id, x, z, material) {
        this.id = id; 
        this.position = { x, z }; 
        this.center = { x: x - 3.5, z: z - 3.5 }; 
        this.invalid = false;
 
        const geometry = new THREE.PlaneGeometry(1, 1);
        this.squareMesh = new THREE.Mesh(geometry, material);
        this.squareMesh.rotation.x = Math.PI / -2; 
        this.squareMesh.position.set(this.center.x, 0, this.center.z); 

        this.squareMesh.userData.id = id

        scene.add(this.squareMesh); 
    }
}

const scene = new THREE.Scene();
const loader = new RGBELoader()

loader.load('./assets/sky/sky.hdr', function(texture) {
    texture.mapping = THREE.EquirectangularReflectionMapping;
    scene.environment = texture
    scene.background = texture
})

const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);

const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

const controls = new OrbitControls(camera, renderer.domElement);
controls.enableDamping = true;
controls.dampingFactor = 0.25;
controls.screenSpacePanning = false;
controls.maxPolarAngle = Math.PI / 2;

const blackMaterial = new THREE.MeshBasicMaterial({ color: "#e3c16f" });
const whiteMaterial = new THREE.MeshBasicMaterial({ color: "#b88b4a" });

const chessBoard = [];
const fileLabels = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'];

const directionalLight = new THREE.DirectionalLight(0xffffff, 4);
directionalLight.position.set(5, 10, 7); 
directionalLight.castShadow = true; 
scene.add(directionalLight);

class Pawn {
    constructor(model_url, position_id, color) {
        this.model_url = model_url;
        this.position_id = position_id;
        this.color = color;
        this.isFirstMove = true;
        this.pawnMesh = null;
    }

    loadModel(callback) {
        const loader = new GLTFLoader();
        loader.load(this.model_url, (gltf) => {
            this.pawnMesh = gltf.scene;
            const color = this.color === 'white' ? 0xd2b48c : 0x8b4513; 
            this.pawnMesh.traverse((child) => {
                if (child.isMesh) {
                    child.material = new THREE.MeshToonMaterial({ color: color });
                    child.userData.parentMesh = this
					child.scale.set(0.2, 0.2, 0.2)
                }
            });       
            callback(this.pawnMesh); 
        });
    }

    valid_moves() {
        let letters = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'];
        let moves = [];

        if (this.color == "white") {
            if (this.isFirstMove) {
                moves.push(`${this.position_id[0]}${parseInt(this.position_id[1]) - 2}`);
                moves.push(`${this.position_id[0]}${parseInt(this.position_id[1]) - 1}`);
            } else {
                if (parseInt(this.position_id[1]) >= 1) {
                    moves.push(`${this.position_id[0]}${parseInt(this.position_id[1]) - 1}`);
                } else {
                    console.error("Error: Ten ruch jest niemożliwy");
                }
            }
        } else if (this.color == "black") {
            if (this.isFirstMove) {
                moves.push(`${this.position_id[0]}${parseInt(this.position_id[1]) + 2}`);
                moves.push(`${this.position_id[0]}${parseInt(this.position_id[1]) + 1}`);
            } else {
                if (parseInt(this.position_id[1]) <= 8) {
                    moves.push(`${this.position_id[0]}${parseInt(this.position_id[1]) + 1}`);
                } else {
                    console.error("Error: Ten ruch jest niemożlowy");
                }
            }
        }

        return moves;
    }

    setPosition(x, z) {
        if (this.pawnMesh) {
            this.pawnMesh.position.set(x - 3.5, -3, z - 3.5); 
        }
    }

    onMouseClick() {
        const validMoves = this.valid_moves();
        console.log('Kliknięto pionka:', this.position_id);
        console.log('Możliwe ruchy pionka:', validMoves);
        
        this.highlightValidMoves(validMoves);
        
        return validMoves;
    }

    highlightValidMoves(validMoves) {
        chessBoard.forEach(square => {
            const originalMaterial = (square.squareMesh.userData.id.charCodeAt(0) + square.squareMesh.userData.id.charCodeAt(1)) % 2 === 0 ? blackMaterial : whiteMaterial;
            square.squareMesh.material = originalMaterial;
        });

      
        validMoves.forEach(move => {
            const square = chessBoard.find(s => s.squareMesh.userData.id === move);
            if (square) {
                square.squareMesh.material = new THREE.MeshBasicMaterial({ color: 0x00ff00 }); 
            }
        });
    }

}

//WIEŻA
class Rook {
    constructor(model_url, position_id, color) {
        this.model_url = model_url;
        this.position_id = position_id;
        this.color = color;
        this.modelMesh = null;
    }

    loadModel(callback) {
        const loader = new GLTFLoader();
        loader.load(this.model_url, (gltf) => {
            this.modelMesh = gltf.scene;
            const color = this.color === 'white' ? 0xd2b48c : 0x8b4513;
            this.modelMesh.traverse((child) => {
                if (child.isMesh) {
                    child.material = new THREE.MeshToonMaterial({ color: color });
                    child.scale.set(0.2, 0.2,  0.2);
                    child.userData.parentMesh = this;  
                }
            });

            callback(this.modelMesh);
        });
    }

    valid_moves() {
        let letters = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'];
        let moves = [];
        let pos_letter = this.position_id[0];
        let pos_num = this.position_id[1];

        for (let i = 1; i <= 8; i++) {
            let valid_id = `${pos_letter}${i}`;
            moves.push(valid_id);
        }

        for (let i = 0; i < letters.length; i++) {
            let valid_id = `${letters[i]}${pos_num}`;
            moves.push(valid_id);
        }

        let filtered_array = moves.filter(item => item !== this.position_id);
        return filtered_array;
    }

    setPosition(x, z) {
        if (this.modelMesh) {
            this.modelMesh.position.set(x - 3.5, -3, z - 3.5);
        }
    }

    onMouseClick() {
        const validMoves = this.valid_moves();
        console.log('Kliknięto pionka:', this.position_id);
        console.log('Możliwe ruchy pionka:', validMoves);
        
        this.highlightValidMoves(validMoves);
        
        return validMoves;
    }

    highlightValidMoves(validMoves) {
 
        chessBoard.forEach(square => {
            const originalMaterial = (square.squareMesh.userData.id.charCodeAt(0) + square.squareMesh.userData.id.charCodeAt(1)) % 2 === 0 ? blackMaterial : whiteMaterial;
            square.squareMesh.material = originalMaterial;
        });

       
        validMoves.forEach(move => {
            const square = chessBoard.find(s => s.squareMesh.userData.id === move);
            if (square) {
                square.squareMesh.material = new THREE.MeshBasicMaterial({ color: 0x00ff00 }); 
            }
        });
    }

}




//KONIK
class Knight {
    constructor(model_url, position_id, color) {
        this.model_url = model_url
        this.position_id = position_id
        this.color = color
        this.knightMesh = null
    }

    loadModel(callback) {
        const loader = new GLTFLoader();
        loader.load(this.model_url, (gltf) => {
            this.knightMesh = gltf.scene;
            const color = this.color === 'white' ? 0xd2b48c : 0x8b4513;
            this.knightMesh.traverse((child) => {
                if (child.isMesh) {
                    child.material = new THREE.MeshToonMaterial({color: color})
                    child.scale.set(0.2, 0.2, 0.2)
                    child.userData.parentMesh = this;  
                }
                callback(this.knightMesh)
            })
        })
    }

    valid_moves() {
        let moves = [];
        let letters = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'];
    
        const knightMoves = [
            {x: 2, y: 1}, {x: 2, y: -1},
            {x: -2, y: 1}, {x: -2, y: -1},
            {x: 1, y: 2}, {x: 1, y: -2},
            {x: -1, y: 2}, {x: -1, y: -2}
        ];
    
        for (let move of knightMoves) {
            let newColumn = letters.indexOf(this.position_id[0]) + move.x;
            let newRow = parseInt(this.position_id[1]) + move.y;
    
            if (newColumn >= 0 && newColumn < letters.length && newRow > 0 && newRow <= 8) {
                moves.push(`${letters[newColumn]}${newRow}`);
            }
        }
    
        return moves;
    }

    setPosition(x, z) {
        if (this.knightMesh) {
            this.knightMesh.position.set(x - 3.5, 0, z - 3.5);
        }
    }

    onMouseClick() {
        const validMoves = this.valid_moves();
        console.log('Kliknięto pionka:', this.position_id);
        console.log('Możliwe ruchy pionka:', validMoves);
        
        this.highlightValidMoves(validMoves);
        
        return validMoves;
    }

    highlightValidMoves(validMoves) {
 
        chessBoard.forEach(square => {
            const originalMaterial = (square.squareMesh.userData.id.charCodeAt(0) + square.squareMesh.userData.id.charCodeAt(1)) % 2 === 0 ? blackMaterial : whiteMaterial;
            square.squareMesh.material = originalMaterial;
        });

       
        validMoves.forEach(move => {
            const square = chessBoard.find(s => s.squareMesh.userData.id === move);
            if (square) {
                square.squareMesh.material = new THREE.MeshBasicMaterial({ color: 0x00ff00 }); 
            }
        });
    }
}

//GONIEC
class Bishop {
    constructor(model_url, position_id, color) {
        this.model_url = model_url
        this.position_id = position_id
        this.color = color
        this.bishopMesh = null
    }
    loadModel(callback) {
        const loader = new GLTFLoader();
        loader.load(this.model_url, (gltf) => {
            this.bishopMesh = gltf.scene;
            const color = this.color === 'white' ? 0xd2b48c : 0x8b4513;
            this.bishopMesh.traverse((child) => {
                if (child.isMesh) {
                    child.material = new THREE.MeshToonMaterial({color: color})
                    child.scale.set(0.2, 0.2, 0.2)
                    child.userData.parentMesh = this; 
                }
                callback(this.bishopMesh)
            })
        })
    }

    valid_moves() {
        let moves = [];
        let letters = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'];
    
        let currentColumn = letters.indexOf(this.position_id[0]);
        let currentRow = parseInt(this.position_id[1]);
    
        const directions = [
            {col: -1, row: 1}, 
            {col: 1, row: 1},  
            {col: -1, row: -1},
            {col: 1, row: -1} 
        ];
    
        for (let direction of directions) {
            let newColumn = currentColumn;
            let newRow = currentRow;
    
            while (true) {
                newColumn += direction.col;
                newRow += direction.row;
    
           
                if (newColumn >= 0 && newColumn < letters.length && newRow > 0 && newRow <= 8) {
                    moves.push(`${letters[newColumn]}${newRow}`);
                } else {
                    break; 
                }
            }
        }
    
        return moves;
    }

    setPosition(x, z) {
        if (this.bishopMesh) {
            this.bishopMesh.position.set(x - 3.5, -5.4, z - 3.5);
        }
    }

    onMouseClick() {
        const validMoves = this.valid_moves();
        console.log('Kliknięto pionka:', this.position_id);
        console.log('Możliwe ruchy pionka:', validMoves);
        
        this.highlightValidMoves(validMoves);
        
        return validMoves;
    }

    highlightValidMoves(validMoves) {
 
        chessBoard.forEach(square => {
            const originalMaterial = (square.squareMesh.userData.id.charCodeAt(0) + square.squareMesh.userData.id.charCodeAt(1)) % 2 === 0 ? blackMaterial : whiteMaterial;
            square.squareMesh.material = originalMaterial;
        });

       
        validMoves.forEach(move => {
            const square = chessBoard.find(s => s.squareMesh.userData.id === move);
            if (square) {
                square.squareMesh.material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
            }
        });
    }

}

//KRÓLOWA
class Queen {
    constructor(model_url, position_id, color) {
        this.model_url = model_url
        this.position_id = position_id
        this.color = color
        this.queenMesh = null
    }
    loadModel(callback) {
        const loader = new GLTFLoader();
        loader.load(this.model_url, (gltf) => {
            this.queenMesh = gltf.scene;
            const color = this.color === 'white' ? 0xd2b48c : 0x8b4513;
            this.queenMesh.traverse((child) => {
                if (child.isMesh) {
                    child.material = new THREE.MeshToonMaterial({color: color})
                    child.scale.set(0.2, 0.2, 0.2)
                    child.userData.parentMesh = this; 
                }
                callback(this.queenMesh)
            })
        })
    }

    setPosition(x, z) {
        if (this.queenMesh) {
            this.queenMesh.position.set(x - 3.5, -5.25, z - 3.5);
        }
    }

    valid_moves() {
        let moves = [];
        let letters = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'];

        let currentColumn = letters.indexOf(this.position_id[0]);
        let currentRow = parseInt(this.position_id[1]);

        const directions = [
            { col: -1, row: 0 }, 
            { col: 1, row: 0 },  
            { col: 0, row: 1 },  
            { col: 0, row: -1 },  
            { col: -1, row: 1 }, 
            { col: 1, row: 1 },   
            { col: -1, row: -1 },  
            { col: 1, row: -1 }   
        ];

        for (let direction of directions) {
            let newColumn = currentColumn;
            let newRow = currentRow;

            while (true) {
                newColumn += direction.col;
                newRow += direction.row;

                if (newColumn >= 0 && newColumn < letters.length && newRow > 0 && newRow <= 8) {
                    moves.push(`${letters[newColumn]}${newRow}`);
                } else {
                    break; 
                }
            }
        }

        return moves;
    }

    onMouseClick() {
        const validMoves = this.valid_moves();
        console.log('Kliknięto pionka:', this.position_id);
        console.log('Możliwe ruchy pionka:', validMoves);
        
        this.highlightValidMoves(validMoves);
        
        return validMoves;
    }

    highlightValidMoves(validMoves) {
 
        chessBoard.forEach(square => {
            const originalMaterial = (square.squareMesh.userData.id.charCodeAt(0) + square.squareMesh.userData.id.charCodeAt(1)) % 2 === 0 ? blackMaterial : whiteMaterial;
            square.squareMesh.material = originalMaterial;
        });

       
        validMoves.forEach(move => {
            const square = chessBoard.find(s => s.squareMesh.userData.id === move);
            if (square) {
                square.squareMesh.material = new THREE.MeshBasicMaterial({ color: 0x00ff00 }); 
            }
        });
    }
}

//KRÓL
class King {
    constructor(model_url, position_id, color) {
        this.model_url = model_url
        this.position_id = position_id
        this.color = color
        this.kingMesh = null
    }
    loadModel(callback) {
        const loader = new GLTFLoader();
        loader.load(this.model_url, (gltf) => {
            this.kingMesh = gltf.scene;
            const color = this.color === 'white' ? 0xd2b48c : 0x8b4513;
            this.kingMesh.traverse((child) => {
                if (child.isMesh) {
                    child.material = new THREE.MeshToonMaterial({color: color})
                    child.scale.set(0.2, 0.2, 0.2)
                    child.userData.parentMesh = this; 
                }
                callback(this.kingMesh)
            })
        })
    }

    setPosition(x, z) {
        if (this.kingMesh) {
            this.kingMesh.position.set(x - 3.5, -7.75, z - 3.5);
        }
    }

    valid_moves() {
        let moves = [];
        let letters = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'];
        
        let currentColumn = letters.indexOf(this.position_id[0]);
        let currentRow = parseInt(this.position_id[1]);

        const directions = [
            { col: -1, row: 1 },   
            { col: 0, row: 1 },   
            { col: 1, row: 1 },   
            { col: 1, row: 0 },    
            { col: 1, row: -1 },   
            { col: 0, row: -1 },   
            { col: -1, row: -1 },  
            { col: -1, row: 0 }    
        ];

        for (let direction of directions) {
            let newColumn = currentColumn + direction.col;
            let newRow = currentRow + direction.row;

            if (newColumn >= 0 && newColumn < letters.length && newRow > 0 && newRow <= 8) {
                moves.push(`${letters[newColumn]}${newRow}`);
            }
        }

        return moves;
    }
    
    onMouseClick() {
        const validMoves = this.valid_moves();
        console.log('Kliknięto pionka:', this.position_id);
        console.log('Możliwe ruchy pionka:', validMoves);
        
        this.highlightValidMoves(validMoves);
        
        return validMoves;
    }

    highlightValidMoves(validMoves) {
 
        chessBoard.forEach(square => {
            const originalMaterial = (square.squareMesh.userData.id.charCodeAt(0) + square.squareMesh.userData.id.charCodeAt(1)) % 2 === 0 ? blackMaterial : whiteMaterial;
            square.squareMesh.material = originalMaterial;
        });

       
        validMoves.forEach(move => {
            const square = chessBoard.find(s => s.squareMesh.userData.id === move);
            if (square) {
                square.squareMesh.material = new THREE.MeshBasicMaterial({ color: 0x00ff00 }); 
            }
        });
    }

}

let pawn = new Pawn("", "e5", "white");
console.log(pawn.valid_moves());

let blackPawn = new Pawn("", "h4", "black");
console.log(blackPawn.valid_moves());

let rook = new Rook('model', 'd5', 'white');
console.log(rook.valid_moves())


for (let x = 0; x < 8; x++) {
    for (let z = 0; z < 8; z++) {
        const id = `${fileLabels[x]}${z + 1}`; 
        const isBlack = (x + z) % 2 === 0; 
        const material = isBlack ? blackMaterial : whiteMaterial;

        const square = new ChessSquare(id, x, z, material);
        chessBoard.push(square); 
    }
}


const pawnModels = [];

function addPawnsToBoard() {
    const pawn_model_url = './assets/pawns/pawn/scene.gltf'; 
    const rook_model_url = './assets/pawns/rook/scene.gltf';
    const knight_model_url = './assets/pawns/knight/scene.gltf'
    const queen_model_url = './assets/pawns/queen/scene.gltf';
    const bishop_model_url = './assets/pawns/bishop/scene.gltf'
    const king_model_url = './assets/pawns/king/scene.gltf'

    for (let x = 0; x < 8; x++) {
        for (let z = 0; z < 8; z++) {
            const piece = chessArray[z][x];

            if (piece == 1 || piece == -1) {
                const color = piece > 0 ? 'white' : 'black';
                const pawn = new Pawn(pawn_model_url, `${fileLabels[x]}${z + 1}`, color);
                pawn.loadModel((mesh) => {
                    pawn.setPosition(x, z);
                    scene.add(mesh);
                    mesh.userData.parentMesh = pawn;
                    pawnModels.push(mesh); 
                });
            }

            if (piece == 2 || piece == -2) {
                const color = piece > 0 ? 'white' : 'black';
                const knight = new Knight(knight_model_url, `${fileLabels[x]}${z + 1}`, color);
                knight.loadModel((mesh) => {
                    knight.setPosition(x, z);
                    scene.add(mesh);
                    mesh.userData.parentMesh = knight;
                    pawnModels.push(mesh); 
                });
            } 

            if (piece == 4 || piece == -4) {
                const color = piece > 0 ? 'white' : 'black';
                const rook = new Rook(rook_model_url, `${fileLabels[x]}${z + 1}`, color);
                rook.loadModel((mesh) => {
                    rook.setPosition(x, z);
                    scene.add(mesh);
                    mesh.userData.parentMesh = rook;
                    pawnModels.push(mesh); 
                });
            }

            if (piece == 5 || piece == -5) {
                const color = piece > 0 ? 'white' : 'black';
                const queen = new Queen(queen_model_url, `${fileLabels[x]}${z + 1}`, color);
                queen.loadModel((mesh) => {
                    queen.setPosition(x, z);
                    scene.add(mesh);
                    mesh.userData.parentMesh = queen;
                    pawnModels.push(mesh); 
                });
            }

            if (piece == 3 || piece == -3) {
                const color = piece > 0 ? 'white' : 'black';
                const bishop = new Bishop(bishop_model_url, `${fileLabels[x]}${z + 1}`, color);
                bishop.loadModel((mesh) => {
                    bishop.setPosition(x, z);
                    scene.add(mesh);
                    mesh.userData.parentMesh = bishop;
                    pawnModels.push(mesh); 
                });
            }

            if (piece == 6 || piece == -6) {
                const color = piece > 0 ? 'white' : 'black';
                const king = new King(king_model_url, `${fileLabels[x]}${z + 1}`, color);
                king.loadModel((mesh) => {
                    king.setPosition(x, z);
                    scene.add(mesh);
                    mesh.userData.parentMesh = king;
                    pawnModels.push(mesh); 
                });
            }
        }
    }
}

const raycaster = new THREE.Raycaster()
const mouse = new THREE.Vector2()

let selectedPawn = null; 
let previousColor = null; 

window.addEventListener('click', (event) => {
    mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
    mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;

    raycaster.setFromCamera(mouse, camera);

    const intersects = raycaster.intersectObjects(pawnModels);

    if (intersects.length > 0) {
        const clickedObject = intersects[0].object;
        const selectedPiece = clickedObject.userData.parentMesh;

        console.log('Kliknięto obiekt:', clickedObject);
        console.log('selectedPiece:', selectedPiece);

        if (selectedPiece && typeof selectedPiece.onMouseClick === 'function') {
            const possibleMoves = selectedPiece.onMouseClick(); 

        } else {
            console.error("Error: Kliknięty obiekt nie jest figurą lub nie ma metody onMouseClick");
        }

        if (selectedPawn) {
            selectedPawn.material.color.set(previousColor);
        }

        previousColor = clickedObject.material.color.getHex(); 
        clickedObject.material.color.set(0xFFD700); 
        selectedPawn = clickedObject;
    }
});

addPawnsToBoard();

camera.position.set(5, 5, 5);
controls.update();

function animate() {
    controls.update(); 
    renderer.render(scene, camera);
    requestAnimationFrame(animate);
}
animate();