      newModel((model) => {
        model._update = () => {
          return identity.translate(0, 0, Math.sqrt(abs(Math.sin(gameTime)) * 16));
        };
        meshAdd(cylinder(GQuad), identity.translate(0, 16, 20).scale(12, 1, 3), material(0.3, 0.3, 0.3, 0.4));
        meshAdd(cylinder(GQuad), identity.translate(0, 16, 20).scale(11.5, 1.2, 2.5), material(0.5, 0.3, 0.3, 0.4));
      }, ++_modelIdCounter);


      meshAdd(
        csg_polygons(
          csg_subtract(
            polygons_transform(
              cylinder(GQuad),
              identity.translate(0, 16, 17).scale(12, 1, 6),
              material(0.5, 0.3, 0.3, 0.4),
            ),
            polygons_transform(
              cylinder(5),
              identity.translate(0, 16, 9).scale(4.5, 5, 4.5),
              material(0.5, 0.3, 0.3, 0.4),
            ),
          ),
        ),
      );


  newModel((model) => {
    model.$collisions = 0;
    model._update = () => {
      const soulPos = model.$finalMatrix.transformPoint();
      if (!soul.$value && vec3_distance(soulPos, player_position_final) < SOUL_SENSITIVITY_RADIUS) {
        soul.$value = 1;
        onSoulCollected();
      }
      model.$visible = (1 - soul.$value) as 0 | 1;

      // const ax = targetX - (soulX + mX) / 2;
      // const az = targetZ - (soulZ + mZ) / 2;

      // let centerX = 0;
      // let centerZ = 0;
      // let bestDist = Infinity;
      // let bestCircle = lastCircle;
      // for (const circle of circles) {
      //   const aax = mX - circle[0]!;
      //   const aaz = mZ - circle[1]!;
      //   const adistance = Math.hypot(aax, aaz);
      //   if (adistance < bestDist) {
      //     bestDist = adistance + Math.sin(gameTime);
      //     centerX = circle[0]!;
      //     centerZ = circle[1]!;
      //     maxDistanceDelta = circle[2]!;
      //     bestCircle = circle;
      //   }
      // }

      // console.log(bestCircle);

      const ax = targetX - soulX;
      const az = targetZ - soulZ;

      const mag = Math.hypot(ax, az);

      const XXX = 0;

      if (mag > maxDistanceDelta && mag) {
        // soulX = lerpDamp(soulX, soulX + (ax / mag) * maxDistanceDelta, 2);
        // soulZ = lerpDamp(soulZ, soulZ + (az / mag) * maxDistanceDelta, 2);

        soulX += (ax / mag) * maxDistanceDelta * gameTimeDelta * (1.5 + XXX);
        soulZ += (az / mag) * maxDistanceDelta * gameTimeDelta * (1.5 + XXX);
      } else {
        angle = Math.atan2(-az, ax);
        const rand = 1 - Math.random() / 2;
        angle += rand;
        // angle += Math.sin(gameTime) / 2;
        targetX = centerX - Math.cos(angle) * maxDistanceDelta * 2;
        targetZ = centerZ + Math.sin(angle) * maxDistanceDelta * 2;
        soulX = lerpDamp(soulX, targetX, 1);
        soulZ = lerpDamp(soulZ, targetZ, 1);
      }

      mX = lerpDamp(mX, soulX, 2 + XXX);
      mZ = lerpDamp(mZ, soulZ, 2 + XXX);

      const dx = mX - prevX;
      const dz = mZ - prevZ;
      if (dx || dz) {
        look_angle = angle_lerp_degrees(look_angle, Math.atan2(dx, dz) / DEG_TO_RAD - 180, gameTimeDelta * 7);
      }

      prevX = mX;
      prevZ = mZ;
      // const vx = mag / gameTimeDelta;

      // console.log(vx);

      // mX = lerpDamp(mX, soulX, 1 + mag);
      // mZ = lerpDamp(mZ, soulZ, 1 + mag);

      return identity.translate(mX, 0, mZ).rotateSelf(0, look_angle);
    };
    return soulMesh;
  });
};






  const centerX = 0;
  const centerZ = 0;

  let targetX = 1;
  let targetZ = 0;
  let oldt = 0;

  const containerWidth = 5;
  const containerHeight = 5;

      oldt += gameTimeDelta;
      const timeReset = oldt > 2 ? (oldt = 0) : 1;

      const dx = soulX - centerX;
      const dz = soulZ - centerZ;
      const nl = Math.sqrt(dx * dx + dz * dz);

      if (abs(dx) >= containerWidth / 3 || abs(dz) >= containerHeight / 3 || !timeReset) {
        // targetX = -dx / nl;
        // targetZ = -dz / nl;

        const alpha = Math.atan2(targetX, targetZ);

        const theta = Math.PI * 2 - alpha + Math.random() * 2 - 1;

        const tx = Math.cos(theta);
        targetZ = Math.sin(theta);
        targetX = tx;

        console.log(targetX.toFixed(3), targetZ.toFixed(3));
      }

      soulX = lerpDamp(soulX, targetX * containerWidth, 2);
      soulZ = lerpDamp(soulX, targetZ * containerHeight, 2);


/////////////
  const containerR = 3;

  let vx = 1;
  let vy = 0;

  let oldt = 0;
  let lookatRadians = 0;

  let soulX = 0;
  let soulZ = 0;

  const centerX = 0;
  const centerZ = 0;


      oldt += gameTimeDelta;
      const timeReset = oldt > 2 ? (oldt = 0) : 1;

      const dx = soulX - centerX;
      const dy = soulZ - centerZ;
      const nl = Math.sqrt(dx * dx + dy * dy);

      if (!timeReset) {
        const theta = Math.random() / 2;
        const tx = vx * Math.cos(theta) - vy * Math.sin(theta);
        vy = vx * Math.sin(theta) + vy * Math.cos(theta);
        vx = tx;
      }

      if (nl > containerR) {
        // // the normal at the point of collision is -dx, -dy normalized
        const tx = -dx / nl;
        const ty = -dy / nl;

        // rotate by a random vector

        // // calculate new velocity: v' = v - 2 * dot(d, v) * n
        const dot = vx * tx + vy * ty;

        vx -= 2 * dot * tx;
        vy -= 2 * dot * ty;

        soulX *= containerR / nl;
        soulZ *= containerR / nl;
      }

      const angle = Math.atan2(-vx, -vy);

      // lookatRadians = angle_lerp_degrees(lookatRadians, angle, gameTimeDelta * 3);
      lookatRadians = lerpDamp(lookatRadians, angle, 5);

      // console.log(Math.sqrt(vx * vx + vy * vy).toFixed(3));

      // soulX += vx * gameTimeDelta * 5;
      // soulZ += vy * gameTimeDelta * 5;

      soulX = lerpDamp(soulX, soulX + vx, 2 + (1 - vx) * 2);
      soulZ = lerpDamp(soulZ, soulZ + vy, 2 + (1 - vy) * 2);

      // console.log(vx.toFixed(3), -Math.sin(angle).toFixed(3));
      // console.log(vy.toFixed(3), -Math.cos(angle).toFixed(3));

      // const dx = soul.x - containerR;
      // const dy = soul.z - containerR;
      // if (Math.sqrt(dx * dx + dy * dy) >= containerR) {
      //   // current speed
      //   const v = Math.sqrt(vx * vx + vy * vy);
      //   // Angle from center of large circle to center of small circle,
      //   // which is the same as angle from center of large cercle
      //   // to the collision point
      //   const angleToCollisionPoint = Math.atan2(-dy, dx);
      //   // Angle of the current movement
      //   const oldAngle = Math.atan2(-vy, vx);
      //   // New angle
      //   const newAngle = 2 * angleToCollisionPoint - oldAngle;
      //   // new x/y speeds, using current speed and new angle
      //   vx = -v * Math.cos(newAngle);
      //   vy = v * Math.sin(newAngle);
      // }

      // const RADIUS = 10;

      // const dx = soulPos.x - RADIUS;
      // const dz = soulPos.z - RADIUS;
      // const nl = Math.hypot(dx, dz) - 5;
      // const collision = nl >= RADIUS;

      // if (collision) {
      //   // the normal at the point of collision is -dx, -dy normalized
      //   const nx = -dx / nl;
      //   const nz = -dz / nl;
      //   // calculate new velocity: v' = v - 2 * dot(d, v) * n
      //   const dot = pvelX * nx + pvelY * nz;
      //   pvelX -= 2 * dot * nx;
      //   pvelY -= 2 * dot * nz;
      // }

      // soul.x += pvelX;
      // soul.z += pvelY;

      /* const { x, z } = soul;
      const dist = Math.hypot(x, z) || 0;

      if (dist > 5) {
        soul.$angle = Math.atan2(z, x) + Math.random();
        console.log(x, z, Math.atan2(z, x));
        // soul.$targetAngle = Math.random() * Math.PI * 2;
      }
      // soul.$angle = lerpDamp(soul.$angle, soul.$targetAngle, 0.1);
      soul.x += Math.cos(soul.$angle) * gameTimeDelta * 10;
      soul.z += Math.sin(soul.$angle) * gameTimeDelta * 10; */

      return identity.translate(soulX, 0, soulZ).rotateSelf(0, lookatRadians / DEG_TO_RAD);


  // arms
  meshAdd(sphere(10), identity.translate(0.3, 0.48, 0).rotate(0, 0, -10).scale(0.45, 0.2, 0.2), material(1, 0.3, 0.4));

  // meshAdd(
  //   sphere(10),
  //   identity.translate(0.7, 0.3, 0).rotate(0, 0, 15).scale(0.14, 0.3, 0.14),
  //   material(1, 0.3, 0.4),
  // );

  // meshAdd(
  //   sphere(10),
  //   identity.translate(0.7, 0, 0).scale(0.3, 0.25, 0.2).rotate(0, 30, 35).skewY(35).skewX(35),
  //   material(1, 0.3, 0.4),
  // );
  
    // ========= Main menu player block ========= //
  meshAdd([
    ...polygons_transform(cylinder(5), identity.translate(0, -2).scale(1.5, 0.4, 1.5), material(0.2, 0.2, 0.2, 0.2)),
    ...polygons_transform(cylinder(5), identity.translate(0, -2).scale(1.2, 0.5, 1.2), material(0.7, 0.7, 0.7, 0.2)),
  ]);
  mainMenuPlayerBlockMesh = meshEnd();

// background
        integers_map(4, (i) =>
          meshAdd(
            polygons_transform(
              bigArc,
              identity.translate(i * 24 - 18, 10, 40).scale(2, 2),
              material(0.6, 0.6, 0.6, 0.3),
            ),
          ),
        );
        
          meshAdd(
      csg_polygons(
        csg_subtract(
          polygons_transform(cylinder(8), identity.translate(0, -2, 0).scale(5, 7, 5), material(0.3, 0.3, 0.3, 0.3)),
          csg_union([
            polygons_transform(
              cylinder(6),
              identity
                .translate(0, 1.1, 0)
                .rotate(180 - 45, 0, 90)
                .scale(3, 17, 3),
              material(0.5, 0.5, 0.5, 0.2),
            ),
            polygons_transform(
              cylinder(6),
              identity.translate(0, 1.1, 0).rotate(45, 0, 90).scale(3, 17, 3),
              material(0.5, 0.5, 0.5, 0.2),
            ),
            polygons_transform(cylinder(6), identity.translate(0, 5).scale(3, 5, 3), material(0.3, 0.3, 0.3, 0.3)),
          ]),
        ),
      ),
    );
    
    
        // entrance horns
    [-1, 1].map((i) =>
      meshAdd(
        polygons_transform(
          horn
          identity
            .translate(i * 4, 0.5, -20.8)
            .rotate(0, i * 90 - 90, i * 23)
            .scale(1.3, 9, 1.3),
          material(1, 1, 0.8, 0.2),
        ),
      ),
    );

    // double creepy horns

          [-1, 1].map((i) =>
        meshAdd(
          polygons_transform(
            horn,
            identity
              .translate(-42, -3, -21.5)
              .rotate(0, i * 90, i * 90) //
              .scale(1.3, 9, 1.3),
            material(1, 1, 0.8, 0.2),
          ),
        ),
      );


              // arrows
              polygons_transform(
                cylinder(3),
                identity.translate(-100, -0.6, -0.5).scale3d(1.1),
                material(0.7, 0.7, 0.7, 0.3),
              ),
              polygons_transform(
                cylinder(3),
                identity.translate(-105, -0.6, -0.5).rotate(0, -45).scale3d(1.1),
                material(0.7, 0.7, 0.7, 0.3),
              ),
              polygons_transform(
                GBox,
                identity.translate(-100, -0.6, -1.7).scale(0.2, 1.1, 1.5),
                material(0.7, 0.7, 0.7, 0.3),
              ),
              polygons_transform(
                GBox,
                identity.translate(-105, -0.6, -0.5).rotate(0, -45).translate(0, 0, -1.5).scale(0.2, 1.1, 1.5),
                material(0.7, 0.7, 0.7, 0.3),
              ),

    // "crystals"

    // integers_map(10, (i) => {
    //   meshAdd(
    //     polygons_transform(
    //       cylinder(((i * 23) % 5) + 5, 0, 0.6),
    //       identity
    //         .translate(-102 + abs(Math.sin(i)) * 5 + i, -2.3 - i, -30 - i * 2.5)
    //         .scaleSelf(5 + i / 2, 1, 5 + i / 3),
    //       material(1, 1, 1, 0.4),
    //     ),
    //   );
    // });
  // meshAdd(polygons_transform(GBox, identity.translate(-80, -11, 18).scale(5, 1, 3), material(0.5, 0.5, 0.5, 1)));
  
    const pentacleTriangles = polygons_transform(
    csg_polygons(
      csg_union(
        polygon_transform(polygon_regular(5), identity.rotate(0, 180)).map(({ x, z }, i) => {
          const m = identity.translate(x * 1.8, 0, z * 1.8).rotate(0, 180 + (i / 5) * 360);
          return csg_subtract(
            polygons_transform(cylinder(3), m.scale(0.8, 0.8, 1.4)),
            polygons_transform(cylinder(3), m.scale(0.5, 2, 1)),
          );
        }),
      ),
    ),
    identity.translate(0, 0.5).scale(4.5, 1, 4.5),
    material(0.5, 0.3, 0.4),
  );


/*


  // meshAdd(polygons_transform(cylinder(6, 0, 0, 0.3), identity.translate(15, -2, -5).scale(10, 1, 15)));

  // meshAdd(
  //   csg_polygons(
  //     csg_subtract(
  //       polygons_transform(GBox, identity.translate(12, -2, -5).scale(7, 1, 15), material(1, 1, 1)),
  //       polygons_transform(GBox, identity.translate(15, -2, -21).rotate(0, 60).scale(5, 8, 8), material(1, 1, 1)),
  //     ),
  //   ),
  // );

  // meshAdd(
  //   polygons_transform(GBox, identity.translate(12, -2, -5).scale(7, 1, 12).rotate(0, 71.6), material(0.94, 0.4, 0.4)),
  // );

  // meshAdd(
  //   polygons_transform(cylinder(6, 0, 0, 0.4), identity.translate(20, -5, 0).scale(8, 1, 10), material(0.5, 0.5, 0.5)),
  // );

  // meshAdd(polygons_transform(GBox, identity.translate(3, -0, -21).rotate(0, 60).scale(3, 1, 3), material(1, 0, 0)));
  // meshAdd(
  //   polygons_transform(
  //     GBox,
  //     identity.translate(16, -3, -13).rotate(0, 60).rotate(15, 0).scale(3, 1, 13),
  //     material(1, 1, 1),
  //   ),
  // );

  // meshAdd(polygons_transform(cylinder(6, 0, 0, 0.3), identity.scale(20, 10, 20), material(1, 1, 1)));

  /* meshAdd(
    csg_polygons(
      csg_subtract(
        polygons_transform(cylinder(6), identity.translate(0, -5, 0).scale(23, 1, 23), material(0.6, 0.1, 0.1)),
        baseHole,
      ),
    ),
  );

  // polygon_transform(polygon_regular(5), identity.scale(20 * 0.2, 1, 44 * 0.2)).map(({ x, z }) => {
  //   meshAdd(polygons_transform(cylinder(5), identity.translate(x, 3, z).scale(0.3, 3, 0.3), material(0.8, 0, 0.8)));
  // });
  // meshAdd(weirdObject());
  // meshAdd(pavement());

  const base1 = polygons_transform(cylinder(6), identity.scale(10, 1, 24).rotate(0, 45, 0), material(1, 1, 1));
  const base2 = polygons_transform(
    cylinder(5),
    identity.translate(18, -4, 0).rotate(0, 20, 0).scale(18, 1, 14),
    material(1, 0, 1),
  );

  meshAdd(base1);
  meshAdd(base2);

const base = polygons_transform(cylinder(5), identity.scale(15, 2, 15), material(1, 1, 1));

  meshAdd(dw
    csg_polygons(
      csg_subtract(
        csg_union([
          base,
          polygons_transform(
            GBox,
            identity.translate(-20, -1, -5).rotate(0, -18, 0).scale(10, 1, 10),
            material(0, 1, 0),
          ),
        ]),
        csg_union([
          polygons_transform(base, identity.translate(0, 1).scale(0.9, 1, 0.9), material(0.8, 0.8, 0.8)),
          polygons_transform(cylinder(5), identity.scale(3, 3, 3), material(1, 1, 1)),
        ]),
      ),
    ),
  );
  const base = polygons_transform(cylinder(6), identity.scale(10, 1, 24), material(1, 1, 1));

  meshAdd(
    csg_polygons(
      csg_subtract(
        base,
        csg_union([
          polygons_transform(base, identity.translate(0, 0.5).scale(0.9, 0.5, 0.9), material(0.8, 0.8, 0.8)),
          polygons_transform(base, identity.scale(0.2, 3, 0.2), material(1, 1, 1)),
        ]),
      ),
    ),
  );

  polygon_transform(polygon_regular(6), identity.scale(20 * 0.2, 1, 44 * 0.2)).map(({ x, z }) => {
    meshAdd(polygons_transform(cylinder(8), identity.translate(x, 3, z).scale(0.3, 3, 0.3), material(0.8, 0, 0.8)));
  }); */

// const arcHole = (transform: DOMMatrixReadOnly, color: number) =>
// csg_union_op(
//   polygons_transform(cylinder(12), transform.scale(3, 3, 20).rotate(90, 0, 0), color),
//   polygons_transform(GBox, transform.translate(0, -3).scale(3, 3, 20).rotate(90, 0, 0), color),
// );

// const huge = csg_polygons(
//   csg_subtract(
//     polygons_transform(cylinder(8), identity.translate(0, 10).scale(15, 15, 15), material(0.8, 0.2, 1)),
//     csg_union([
//       arcHole(identity.translate(0, 2, 0).rotate(0, 20, 0), material(1, 1, 1)),
//       arcHole(identity.translate(0, 2 + 10, 0).rotate(0, 45 + 20, 0), material(1, 1, 1)),
//     ]),
//   ),
// );
// meshAdd(huge);

//  return [...polygons_transform(corridor(), identity.translate(0, 10, 0)), ...pavement(), ...weirdObject()];

// const c = corridor().map((t) => solid_transform(t, identity.translate(0, 10, 0)));

// const merged: Polygon[][] = [];
// for (let z = -8; z < 8; ++z) {
//   for (let x = -8; x < 8; ++x) {
//     for (let y = -2; y < 2; ++y) {
//       for (const solid of c) {
//         merged.push(solid_transform(solid, identity.translate(x * 20, y * 20, z * 20).scale(1, 1, 0.3)));
//       }
//     }
//   }
// }

// return [...merged, pavement(), weirdObject()];

// const materialWhite = material(1, 1, 1);
// const material0 = material(1, 0.3, 0);
// const material1 = material(0, 0.5, 0.7);
// const material2 = material(0, 0.2, 0.9);
// const material3 = material(0.2, 0, 0.9);
// const material4 = material(0.4, 0.9, 0);
// const material5 = material(0.4, 0, 0.9);

// const corridor = (): Polygon[] => {
//   // const p = csg_union([
//   //   csg_union([
//   //     solid_transform(solid_box(material4), identity.rotate(20).scale(1.5, 6.9, 4)),
//   //     solid_transform(solid_box(material5), identity.rotate(20).scale(1.5, 5.9, 10)),
//   //   ]),
//   //   csg_subtract(
//   //     solid_transform(solid_box(material0), identity.scale(3.5, 3.5, 20)),
//   //     csg_union([
//   //       solid_transform(solid_box(material1), identity.scale(3, 3, 22)),
//   //       ...integers_map(6, (i) =>
//   //         solid_transform(
//   //           solid_cylinder(material1, 6),
//   //           identity
//   //             .translate(0, 0.6, i * 6 - 14)
//   //             .rotate(0, 0, 90)
//   //             .scale(2.5, 4, 1.5),
//   //         ),
//   //       ),
//   //     ]),
//   //   ),
//   // ]);

//   // const p = csg_subtract(
//   //   solid_transform(solid_cylinder(material0, 8, 1.1), identity.scale(3.5, 3.5, 20).rotate(90, 0, 20)),
//   //   csg_union([
//   //     solid_transform(solid_cylinder(material1, 8, 1.1), identity.scale(3, 3, 22).rotate(90, 0, 20)),
//   //     ...integers_map(6, (i) =>
//   //       solid_transform(
//   //         solid_cylinder(material1, 6, 0.5),
//   //         identity
//   //           .translate(0, 0, i * 6 - 14)
//   //           .rotate(0, 0, 90)
//   //           .scale(1, 4, 1),
//   //       ),
//   //     ),
//   //   ]),
//   // );

//   const p = csg_subtract(
//     polygons_transform(GBox, identity.scale(3.5, 3.5, 20), material0),
//     csg_union([
//       polygons_transform(GBox, identity.scale(3, 3, 22), material1),
//       ...integers_map(6, (i) =>
//         polygons_transform(
//           cylinder(6),
//           identity
//             .translate(0, 0.6, i * 6 - 14)
//             .rotate(0, 0, 90)
//             .scale(2.5, 4, 1.5),
//           material1,
//         ),
//       ),
//     ]),
//   );

//   return csg_polygons(p);
// };

const weirdObject = () => {
  const material0 = material(1, 0.3, 0);
  const material1 = material(0, 0.5, 0.7);
  const material2 = material(0, 0.2, 0.9);
  const material3 = material(0.2, 0, 0.9);
  const material4 = material(0.4, 0.9, 0);
  const material5 = material(0.4, 0, 0.9);

  const figure0 = polygons_transform(cylinder(6), identity, material0);

  const figure01 = polygons_transform(cylinder(6), identity.scale(1, 0.6, 1).translate(0, 1, 0), material5);
  // const figure02 = solid_transform(solid_cylinder(material0, 6);

  const figure1 = polygons_transform(
    cylinder(118),
    identity.translate(-0.2).rotate(90, 10, 10).scale(0.5, 2, 0.5),
    material1,
  );

  const figure2 = polygons_transform(
    cylinder(118),
    identity.translate(-0.2).rotate(90, 10, 10).scale(0.22, 1.5, 0.22).skewY(10),
    material2,
  );

  const figure3 = polygons_transform(
    cylinder(18),
    identity.translate(-0.2).rotate(0, 10, 10).scale(0.3, 1.4, 0.3),
    material3,
  );

  const figure4 = polygons_transform(
    cylinder(8),
    identity.translate(-0.2).rotate(0, 0, 90).scale(0.15, 2, 0.15),
    material4,
  );

  const figure5 = polygons_transform(
    cylinder(5),
    identity.translate(-0.2).rotate(0, 10, 10).scale(0.15, 1.7, 0.15),
    material5,
  );

  if (DEBUG) {
    console.time("weird");
  }

  const csg0 = csg_subtract(csg_union([figure01, figure0]), figure1);
  const csg1 = csg_union([csg0, figure2]);
  const csg2 = csg_union([csg1, figure3]);
  const csg3 = csg_subtract(csg2, figure4);
  const csg4 = csg_subtract(csg3, figure5);

  const result = csg_polygons(csg4);

  if (DEBUG) {
    console.timeEnd("weird");
  }

  return result;
};


/*** player first camera

export const camera_firstPersonRotate = (x: number, y: number) => {
  camera_rotation.y = angle_wrap_degrees(camera_rotation.y + x);
  camera_rotation.x = Math.max(Math.min(camera_rotation.x + y, 87), -87);
};

export const camera_firstPersonMove = (x: number, z: number) => {
  const yradians = camera_rotation.y * DEG_TO_RAD;
  const c = Math.cos(yradians);
  const s = Math.sin(yradians);
  camera_position.x += x * c - z * s;
  camera_position.z += x * s + z * c;
};

import {
  keyboard_downKeys,
  KEY_DEBUG_FLY_DOWN,
  KEY_DEBUG_FLY_UP,
  KEY_DOWN,
  KEY_LEFT,
  KEY_RIGHT,
  KEY_RUN,
  KEY_UP,
  mouse_movementReset,
  mouse_movementX,
  mouse_movementY,
} from "./input";

import { camera_firstPersonMove, camera_firstPersonRotate, camera_position } from "./camera";

export const PLAYER_SPEED_WALKING = 2.1;

export const PLAYER_SPEED_RUNNING = DEBUG ? 20 : 5.5;

export const camera_update = (deltaTime: number) => {
  const movStrafe = (keyboard_downKeys[KEY_LEFT] ? -1 : 0) + (keyboard_downKeys[KEY_RIGHT] ? 1 : 0);
  const movForward = (keyboard_downKeys[KEY_UP] ? -1 : 0) + (keyboard_downKeys[KEY_DOWN] ? 1 : 0);

  const movSpeed = (keyboard_downKeys[KEY_RUN] ? PLAYER_SPEED_RUNNING : PLAYER_SPEED_WALKING) * deltaTime;

  // normalize the forward and strafe movements if both strafe and forward are set
  const playerSpeed = movStrafe && movForward ? movSpeed / Math.SQRT2 : movSpeed;

  camera_firstPersonMove(movStrafe * playerSpeed, movForward * playerSpeed);

  camera_position.y -=
    ((keyboard_downKeys[KEY_DEBUG_FLY_UP] ? -1 : 0) + (keyboard_downKeys[KEY_DEBUG_FLY_DOWN] ? 1 : 0)) * movSpeed;

  camera_firstPersonRotate(mouse_movementX * 0.1, mouse_movementY * 0.1);

  mouse_movementReset();
};


*/
