can you edit my code to include normals and hiding triangles that are behind the mesh:  // Helper functions
        function newVec3(xval, yval, zval) {
            return {x: xval, y: yval, z: zval};
        }

        function newTri(vec1, vec2, vec3) {
            return {v1: vec1, v2: vec2, v3: vec3};
        }

        var mesh = [
            // Front face
            newTri(newVec3(0, 0, 1), newVec3(1, 0, 1), newVec3(1, 1, 1)),
            newTri(newVec3(0, 0, 1), newVec3(1, 1, 1), newVec3(0, 1, 1)),

            // Back face
            newTri(newVec3(0, 0, 0), newVec3(1, 1, 0), newVec3(1, 0, 0)),
            newTri(newVec3(0, 0, 0), newVec3(0, 1, 0), newVec3(1, 1, 0)),

            // Top face
            newTri(newVec3(0, 1, 0), newVec3(0, 1, 1), newVec3(1, 1, 1)),
            newTri(newVec3(0, 1, 0), newVec3(1, 1, 1), newVec3(1, 1, 0)),

            // Bottom face
            newTri(newVec3(0, 0, 0), newVec3(1, 0, 0), newVec3(1, 0, 1)),
            newTri(newVec3(0, 0, 0), newVec3(1, 0, 1), newVec3(0, 0, 1)),

            // Right face
            newTri(newVec3(1, 0, 0), newVec3(1, 1, 0), newVec3(1, 1, 1)),
            newTri(newVec3(1, 0, 0), newVec3(1, 1, 1), newVec3(1, 0, 1)),

            // Left face
            newTri(newVec3(0, 0, 0), newVec3(0, 0, 1), newVec3(0, 1, 1)),
            newTri(newVec3(0, 0, 0), newVec3(0, 1, 1), newVec3(0, 1, 0))
        ];

        // Canvas setup
        createCanvas("canvas1",320,450);

        // Projection matrix setup
        var width = 320;
        var height = 450;
        var fov = 60;
        var aspectRatio = width / height;
        var near = 0.5;
        var far = 1000;
        var projectionMatrix = createProjectionMatrix(fov, aspectRatio, near, far);

        // Create projection matrix
        function createProjectionMatrix(fov, aspectRatio, near, far) {
            var fovRad = 1.0 / Math.tan(fov * 0.5 / 180.0 * Math.PI);
            return [
                aspectRatio * fovRad, 0, 0, 0,
                0, fovRad, 0, 0,
                0, 0, far / (far - near), 1,
                0, 0, (-far * near) / (far - near), 0
            ];
        }

        // Matrix multiplication
        function multiplyMatrixVector(m, v) {
            var x = v.x * m[0] + v.y * m[4] + v.z * m[8] + m[12];
            var y = v.x * m[1] + v.y * m[5] + v.z * m[9] + m[13];
            var z = v.x * m[2] + v.y * m[6] + v.z * m[10] + m[14];
            var w = v.x * m[3] + v.y * m[7] + v.z * m[11] + m[15];

            if (w != 0.0) {
                x /= w; y /= w; z /= w;
            }

            return newVec3(x, y, z);
        }

        // Create rotation matrix for the Z-axis
        function createRotationZMatrix(angle) {
            var cos = Math.cos(angle);
            var sin = Math.sin(angle);
            return [
                cos, -sin, 0, 0,
                sin, cos, 0, 0,
                0, 0, 1, 0,
                0, 0, 0, 1
            ];
        }

        function createRotationXMatrix(angle) {
            var cos = Math.cos(angle);
            var sin = Math.sin(angle);
            return [
                1, 0, 0, 0,
                0, cos, -sin, 0,
                0, sin, cos, 0,
                0, 0, 0, 1
            ];
        }

        // Create rotation matrix for the Y-axis
        function createRotationYMatrix(angle) {
            var cos = Math.cos(angle);
            var sin = Math.sin(angle);
            return [
                cos, 0, sin, 0,
                0, 1, 0, 0,
                -sin, 0, cos, 0,
                0, 0, 0, 1
            ];
        }

        // Function to rotate triangles around the origin
        function rotateTri(tri) {
            var rotationXMatrix = createRotationXMatrix(rotationAngle);
            var rotationYMatrix = createRotationYMatrix(rotationAngle * 0.5);
            var rotationZMatrix = createRotationZMatrix(rotationAngle);

            // Apply rotation matrices to vertices centered at (0,0,0)
            var v1 = multiplyMatrixVector(rotationXMatrix, tri.v1);
            v1 = multiplyMatrixVector(rotationYMatrix, v1);
            v1 = multiplyMatrixVector(rotationZMatrix, v1);

            var v2 = multiplyMatrixVector(rotationXMatrix, tri.v2);
            v2 = multiplyMatrixVector(rotationYMatrix, v2);
            v2 = multiplyMatrixVector(rotationZMatrix, v2);

            var v3 = multiplyMatrixVector(rotationXMatrix, tri.v3);
            v3 = multiplyMatrixVector(rotationYMatrix, v3);
            v3 = multiplyMatrixVector(rotationZMatrix, v3);

            return {
                v1: v1,
                v2: v2,
                v3: v3
            };
        }

        var rotationAngle = 0;

        // Draw a triangle
        function drawTriangle(x1, y1, x2, y2, x3, y3) {
            line(x1,y1,x2,y2);
            line(x2,y2,x3,y3);
            line(x3,y3,x1,y1);
        }

        // Main rendering loop
        function render() {
           clearCanvas();

            rotationAngle += 0.01; // Increment rotation angle

            for (var i = 0; i < mesh.length; i++) {
                var tri = mesh[i];
                var triRotated = rotateTri(tri); // Rotate the triangle
                triRotated.v1.z += 3;
                triRotated.v2.z += 3;
                triRotated.v3.z += 3;

                // Project the vertices
                var triProjected = {
                    v1: multiplyMatrixVector(projectionMatrix, triRotated.v1),
                    v2: multiplyMatrixVector(projectionMatrix, triRotated.v2),
                    v3: multiplyMatrixVector(projectionMatrix, triRotated.v3)
                };

                // Scale into view
                triProjected.v1.x += 1.0; triProjected.v1.y += 1.0;
                triProjected.v2.x += 1.0; triProjected.v2.y += 1.0;
                triProjected.v3.x += 1.0; triProjected.v3.y += 1.0;
                triProjected.v1.x *= 0.5 * width; triProjected.v1.y *= 0.5 * height;
                triProjected.v2.x *= 0.5 * width; triProjected.v2.y *= 0.5 * height;
                triProjected.v3.x *= 0.5 * width; triProjected.v3.y *= 0.5 * height;

                drawTriangle(
                    triProjected.v1.x, triProjected.v1.y,
                    triProjected.v2.x, triProjected.v2.y,
                    triProjected.v3.x, triProjected.v3.y
                );
            }
             

        }
timedLoop(1, function() {
  render();
  
});


        // Start rendering