threejs打造3d跑车竞赛动画效果

代码语言:html

所属分类:三维

下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">

<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
<style>
  body {
	margin: 0;
	overflow: hidden;
}
canvas {
	cursor: move;
}
</style>

</head>
<body translate="no">

<script type="text/javascript" src="http://repo.bfw.wiki/bfwrepo/js/three.js"></script>
<script src='http://repo.bfw.wiki/bfwrepo/js/OrbitControls.js'></script>
<script src='http://repo.bfw.wiki/bfwrepo/js/dat.gui.min.js'></script>
<script >
      window.addEventListener("DOMContentLoaded", app);

function app() {
  var scene,
  camera,
  renderer,
  textureLoader = new THREE.TextureLoader(),
  controls,
  GUI,
  road,
  cybertruck,
  ambientLight,
  daylight,
  fogColor;

  var adjustWindow = () => {
    camera.aspect = window.innerWidth / window.innerHeight;
    camera.updateProjectionMatrix();
    renderer.setSize(window.innerWidth, window.innerHeight);
  },
  init = () => {
    // setup
    let licensePlate = textureLoader.load("http://repo.bfw.wiki/bfwrepo/image/5df5d982ef313.png"),
    grassTile = textureLoader.load("http://repo.bfw.wiki/bfwrepo/image/5df5d982ef313.png"),
    roadTile = textureLoader.load("http://repo.bfw.wiki/bfwrepo/image/5df5d96d46d8e.png");

    scene = new THREE.Scene();
    fogColor = {
      h: 215,
      s: 80,
      l: 80 };

    scene.fog = new THREE.Fog(`hsl(${fogColor.h},${fogColor.s}%,${fogColor.l}%)`, 0.01, 272);

    camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 0.1, 1000);
    camera.position.set(20, 10, 20);
    camera.lookAt(scene.position);

    renderer = new THREE.WebGLRenderer({
      logarithmicDepthBuffer: false });

    renderer.setClearColor(scene.fog.color.getStyle());
    renderer.setSize(window.innerWidth, window.innerHeight);
    renderer.shadowMap.enabled = true;

    let camControls = new THREE.OrbitControls(camera, renderer.domElement);
    camControls.enablePan = false;

    // road
    road = new Road(grassTile, roadTile);

    // cybertruck
    cybertruck = new Cybertruck(licensePlate);
    cybertruck.mesh.name = "Cybertruck";
    cybertruck.mesh.position.y = cybertruck.height / 2;

    // ambient light
    ambientLight = new THREE.AmbientLight(0xffffff);
    ambientLight.intensity = 1;
    scene.add(ambientLight);

    // daylight
    daylight = new THREE.PointLight(0xffffff, ambientLight.intensity * 2);
    daylight.position.set(0, 64, 0);
    daylight.castShadow = true;
    scene.add(daylight);

    // config
    controls = {
      daylight: ambientLight.intensity,
      speed: cybertruck.speed,
      resetCam: () => {
        camControls.reset();
      } };

    GUI = new dat.GUI();
    GUI.add(controls, "daylight", 0.1, 1, 0.01).name("Daylight").onChange(e => {
      let newVal = controls.daylight;
      cybertruck.headlight.intensity = (1 - newVal) * 2;
      cybertruck.rearlight.intensity = (1 - newVal) * 2;
      ambientLight.intensity = newVal;
      daylight.intensity = newVal * 2;

      let h = fogColor.h,
      s = fogColor.s,
      l = newVal * 100;
      fogColor.l = l * 0.8;

      let daylightColorStr = `hsl(${h},${s}%,${l.toFixed(0)}%)`,
      fogColorStr = `hsl(${h},${s}%,${fogColor.l.toFixed(0)}%)`;

      daylight.color = new THREE.Color(daylightColorStr);
      renderer.setClearColor(fogColorStr);
      scene.fog.color.set(fogColorStr);
    });
    GUI.add(controls, "speed", 0, 60, 1).name("Speed (MPH)").onChange(e => {
      cybertruck.speed = controls.speed;
    });
    GUI.add(controls, "resetCam").name("Reset Camera");

    // first render
    document.body.appendChild(renderer.domElement);
    renderScene();
  },
  renderScene = () => {
    updateObjects();
    renderer.render(scene, camera);
    requestAnimationFrame(renderScene);
  },
  spawnObjects = () => {
    scene.add(road.mesh);
    scene.add(cybertruck.mesh);
  },
  updateObjects = () => {
    if (scene.getObjectByName(cybertruck.mesh.name)) {
      cybertruck.move();

      if (cybertruck.mesh.position.z > road.tileSize)
      cybertruck.mesh.position.z -= road.tileSize;

      let cybertruckZ = cybertruck.mesh.position.z;
      daylight.position.z = cybertruckZ;
      scene.position.z = -cybertruckZ;
    }
  };

  init();
  window.addEventListener("load", spawnObjects);
  window.addEventListener("resize", adjustWindow);
}

class Cybertruck {
  constructor(licensePlateImg) {
    this.speed = 5;
    this.wireframes = false;
    this.width = 8;
    this.height = 7.5;
    this.depth = 23;
    this.mesh = new THREE.Object3D();

    let W = this.width,
    H = this.height,
    D = this.depth,
    flipXVertices = a => [-a[0], a[1], a[2]],
    toVectors = a => new THREE.Vector3(W * a[0], H * a[1], D * a[2]),
    reverseFaceDraws = a => a.reverse(),
    toFaces = a => new THREE.Face3(a[0], a[1], a[2]);

    // I. Body
    // A. Main
    let bodyVerticesArr = [
    // back (0–3)
    [-0.45, 0.26, -0.5],
    [0.45, 0.26, -0.5],
    [-0.45, -0.1, -0.48],
    [0.45, -0.1, -0.48],
    // top (4–5)
    [-0.326, 0.5, 0.08],
    [0.326, 0.5, 0.08],
    // middle (6–19)
    [-0.45, -0.1, -0.38],
    [0.45, -0.1, -0.38],
    [-0.45, 0.06, -0.36],
    [0.45, 0.06, -0.36],
    [-0.45, 0.06, -0.24],
    [0.45, 0.06, -0.24],
    [-0.45, -0.15, -0.18],
    [0.45, -0.15, -0.18],
    [-0.45, -0.17, 0.255],
    [0.45, -0.17, 0.255],
    [-0.45, 0.06, 0.303],
    [0.45, 0.06, 0.303],
    [-0.45, 0.06, 0.42],
    [0.45, 0.06, 0.42],
    // upper front (20–23)
    [-0.45, 0.08, 0.47],
    [0.45, 0.08, 0.47],
    [-0.33, 0.045, 0.5],
    [0.33, 0.045, 0.5],
    // lower front (24–27)
    [-0.45, -0.13, 0.46],
    [0.45, -0.13, 0.46],
    [-0.343, -0.13, 0.488],
    [0.343, -0.13, 0.488],
    // bottom flaps (28–31)
    [-0.41, -0.21, -0.173],
    [0.41, -0.21, -0.173],
    [-0.41, -0.23, 0.25],
    [0.41, -0.23, 0.25],
    // windows (32–39)
    [-0.4225, 0.27, -0.14],
    [0.4225, 0.27, -0.14],
    [-0.379, 0.39, -0.13],
    [0.379, 0.39, -0.13],
    [-0.337, 0.47, 0.08],
    [0.337, 0.47, 0.08],
    [-0.425, 0.17, 0.36],
    [0.425, 0.17, 0.36]],

    bodyVertices = bodyVerticesArr.map(toVectors),
    bodyFacesArr = [
    [0, 1, 3],
    [3, 2, 0],
    [0, 4, 5],
    [5, 1, 0],
    [5, 37, 35],
    [1, 5, 35],
    [1, 35, 33],
    [33, 21, 1],
    [39, 21, 33],
    [5, 21, 37],
    [21, 39, 37],
    [4, 34, 36],
    [0, 34, 4],
    [0, 32, 34],
    [32, 0, 20],
    [38, 32, 20],
    [4, 36, 20],
    [20, 36, 38],
    [20, 18, 24],
    [20, 0, 18],
    [18, 0, 16],
    [16, 0, 10],
    [10, 0, 8],
    [8, 0, 2],
    [2, 6, 8],
    [16, 10, 14],
    [12, 14, 10],
    [14, 12, 28],
    [28, 30, 14],
    [21, 25, 19],
    [21, 19, 1],
    [19, 17, 1],
    [17, 11, 1],
    [11, 9, 1],
    [1, 9, 7],
    [7, 3, 1],
    [11, 17, 15],
    [15, 13, 11],
    [15, 31, 29],
    [29, 13, 15],
    [5, 4, 20],
    [20, 21, 5],
    [21, 20, 22],
    [22, 23, 21],
    [22, 20, 24],
    [24, 26, 22],
    [23, 22, 26],
    [26, 27, 23],
    [23, 27, 25],
    [25, 21, 23],
    [2, 3, 7],
    [7, 6, 2],
    [6, 7, 9],
    [9, 8, 6],
    [8, 9, 11],
    [11, 10, 8],
    [10, 11, 13],
    [13, 12, 10],
    [12, 13, 29],
    [29, 28, 12],
    [28, 29, 31],
    [31, 30, 28],
    [30, 31, 15],
    [15, 14, 30],
    [14, 15, 17],
    [17, 16, 14],
    [16, 17, 19],
    [19, 18, 16],
    [18, 19, 25],
    [25, 24, 18],
    [24, 25, 26],
    [25, 27, 26],
    [34, 32, 33],
    [33, 35, 34],
    [34, 35, 37],
    [37, 36, 34],
    [36, 37, 39],
    [39, 38, 36],
    [33, 32, 38],
    [38, 39, 33]],

    bodyFaces = bodyFacesArr.map(toFaces),
    bodyGeo = new THREE.Geometry(),
    bodyMat = new THREE.MeshStandardMaterial({
      color: 0xbac3c8,
      wireframe: this.wireframes });


    bodyGeo.vertices = bodyVertices;
    bodyGeo.faces = bodyFaces;
    bodyGeo.computeFaceNormals();

    let body = new THREE.Mesh(bodyGeo, bodyMat);
    this.mesh.add(body);

    // B. Door Handles
    let doorHandleGeo = new THREE.BoxGeometry(W * 0.01, W * 0.024, D * 0.0375),
    doorHandleFR = new THREE.Mesh(doorHandleGeo, bodyMat);

    // front right
    doorHandleFR.position.set(W * -0.45, H * 0.13, D * 0.0844);
    doorHandleFR.rotation.x = 4 * Math.PI / 180;
    body.add(doorHandleFR);

    // front left
    let doorHandleFL = doorHandleFR.clone();
    doorHandleFL.position.x *= -1;
    body.add(doorHandleFL);

    // back right
    let doorHandleBR = doorHandleFR.clone();
    doorHandleBR.position.y = H * 0.165;
    doorHandleBR.position.z = D * -0.1094;
    body.add(doorHandleBR);

    // back left
    let doorHandleBL = doorHandleBR.clone();
    doorHandleBL.position.x *= -1;
    body.add(doorHandleBL);

    // C. Door Outlines
    let doorOutlineMat = new THREE.LineBasicMaterial({
      color: 0x000000,
      transparent: true,
      opacity: 0.25 }),

    doorOutlineFLVerticesArr = [
    [0.451, -0.17, 0.255],
    [0.451, 0.12, 0.255],
    [0.425, 0.192, 0.255],
    [0.424, 0.192, 0.255]],

    doorOutlineFLVertices = doorOutlineFLVerticesArr.map(toVectors),
    doorOutlineFLGeo = new THREE.Geometry();

    // front left
    doorOutlineFLGeo.vertices = doorOutlineFLVertices;

    let doorOutlineFL = new THREE.Line(doorOutlineFLGeo, doorOutlineMat);
    this.mesh.add(doorOutlineFL);

    // front right
    let doorOutlineFRVerticesArr = doorOutlineFLVerticesArr.map(flipXVertices),
    doorOutlineFRVertices = doorOutlineFRVerticesArr.map(toVectors),
    doorOutlineFRGeo = new THREE.Geometry();

    doorOutlineFRGeo.vertices = doorOutlineFRVertices;

    let doorOutlineFR = new THREE.Line(doorOutlineFRGeo, doorOutlineMat);
    this.mesh.add(doorOutlineFR);

    // middle left
    let doorOutlineMLVerticesArr = [
    [0.41, -0.23, 0.0594],
    [0.4505, -0.16, 0.0594],
    [0.4505, 0.156, 0.0531],
    [0.424, 0.233, 0.05],
    [0.41, 0.233, 0.048]],

    doorOutlineMLVertices = doorOutlineMLVerticesArr.map(toVectors),
    doorOutlineMLGeo = new THREE.Geometry();

    doorOutlineMLGeo.vertices = doorOutlineMLVertices;

    let doorOutlineML = new THREE.Line(doorOutlineMLGeo, doorOutlineMat);
    this.mesh.add(doorOutlineML);

    // middle right
    let doorOutlineMRVerticesArr = doorOutlineMLVerticesArr.map(flipXVertices),
    doorOutlineMRVertices = doorOutlineMRVerticesArr.map(toVectors),
    doorOutlineMRGeo = new THREE.Geometry();

    doorOutlineMRGeo.vertices = doorOutlineMRVertices;

    let doorOutlineMR = new THREE.Line(doorOutlineMRGeo, doorOutlineMat);
    this.mesh.add(doorOutlineMR);

    // back left
    let doorOutlineBLVerticesArr = [
    [0.399, -0.23, -0.1313],
    [0.45, -0.152, -0.1359],
    [0.4505, 0.195, -0.1406],
    [0.424, 0.2705, -0.1396],
    [0.4, 0.2705, -0.1396]],

    doorOutlineBLVertices = doorOutlineBLVerticesArr.map(toVectors),
    doorOutlineBLGeo = new THREE.Geometry();

    doorOutlineBLGeo.vertices = doorOutlineBLVertices;

    let doorOutlineBL = new THREE.Line(doorOutlineBLGeo, doorOutlineMat);
    this.mesh.add(doorOutlineBL);

    // back right
    let doorOutlineBRVerticesArr = doorOutlineBLVerticesArr.map(flipXVertices),
    doorOutlineBRVertices = doorOutlineBRVerticesArr.map(toVectors),
    doorOutlineBRGeo = new THREE.Geometry();

    doorOutlineBRGeo.vertices = doorOutlineBRVertices;

    let doorOutlineBR = new THREE.Line(doorOutlineBRGeo, doorOutlineMat);
    this.mesh.add(doorOutlineBR);

    // D. Fuel Cap
    let fuelCapVerticesArr = [
    [0.4502, -0.014, -0.378],
    [0.4502, -0.014, -0.4],
    [0.4502, 0.06, -0.4],
    [0.4502, 0.06, -0.36]],

    fuelCapVertices = fuelCapVerticesArr.map(toVectors),
    fuelCapGeo = new THREE.Geometry();

    fuelCapGeo.vertices = fuelCapVertices;

    let fuelCap = new THREE.Line(fuelCapGeo, doorOutlineMat);
    this.mesh.add(fuelCap);

    // II. Top Parts
    // A. Window
    let windowMat = new THREE.MeshStandardMaterial({
      color: 0x101010,
      wireframe: this.wireframes }),

    lightMat = new THREE.MeshBasicMaterial({
      color: 0xffffff,
      wireframe: this.wireframes }),

    topWindowVerticesArr = [
    [-0.371, 0.415, -0.13],
    [0.371, 0.415, -0.13],
    [-0.326, 0.5, 0.08],
    [0.326, 0.5, 0.08],
    [-0.4145, 0.2, 0.36],
    [0.4145, 0.2, 0.36]],

    topWindowVertices = topWindowVerticesArr.map(toVectors),
    topWindowFacesArr = [
    [1, 0, 2],
    [2, 3, 1],
    [3, 2, 4],
    [4, 5, 3]],

    topWindowFaces = topWindowFacesArr.map(toFaces),
    topWindowGeo = new THREE.Geometry();

    topWindowGeo.vertices = topWindowVertices;
    topWindowGeo.faces = topWindowFaces;
    topWindowGeo.computeVertexNormals();
    topWindowGeo.computeFaceNormals();

    let topWindow = new THREE.Mesh(topWindowGeo, windowMat);
    this.mesh.add(topWindow);

    // B. Light
    let topLightVerticesArr = [
    [-0.26, 0.49, 0.09],
    [0.26, 0.49, 0.09],
    [-0.26, 0.48, 0.1],
    [0.26, 0.48, 0.1]],

    topLightVertices = topLightVerticesArr.map(toVectors),
    topLightFacesArr = [
    [1, 0, 2],
    [2, 3, 1]],

    topLightFaces = topLightFacesArr.map(toFaces),
    topLightGeo = new THREE.Geometry();

    topLightGeo.vertices = topLightVertices;
    topLightGeo.faces = topLightFaces;
    topLightGeo.computeFaceNormals();

    let topLight = new THREE.Mesh(topLightGeo, lightMat);
    this.mesh.add(topLight);

    // C. Sliding Door
    let slidingDoorMat = new THREE.MeshStandardMaterial({
      color: 0x767c7f,
      wireframe: this.wireframes }),

    slidingDoorVerticesArr = [
    [-0.35, 0.274, -0.472],
    [0.35, 0.274, -0.472],
    [-0.35, 0.407, -0.145],
    [0.35, 0.407, -0.145]],

    slidingDoorVertices = slidingDoorVerticesArr.map(toVectors),
    slidingDoorFacesArr = [
    [1, 0, 2],
    [2, 3, 1]],

    slidingDoorFaces = slidingDoorFacesArr.map(toFaces),
    slidingDoorGeo = new THREE.Geometry();

    slidingDoorGeo.vertices = slidingDoorVertices;
    slidingDoorGeo.faces = slidingDoorFaces;
    slidingDoorGeo.computeFaceNormals();

    let slidingDoor = new THREE.Mesh(slidingDoorGeo, slidingDoorMat);
    this.mesh.add(slidingDoor);

    // III. Side Windows
    let sideWindowsVerticesArr = [
    [-0.4, 0.27, -0.14],
    [0.4, 0.27, -0.14],
    [-0.351, 0.39, -0.13],
    [0.351, 0.39, -0.13],
    [-0.315, 0.47, 0.08],
    [0.315, 0.47, 0.08],
    [-0.43, 0.17, 0.36],
    [0.43, 0.17, 0.36]],

    sideWindowsVertices = sideWindowsVerticesArr.map(toVectors),
    sideWindowsFacesArr = [
    [2, 3, 1],
    [1, 0, 2],
    [2, 4, 5],
    [5, 3, 2],
    [4, 6, 7],
    [7, 5, 4],
    [4, 2, 0],
    [0, 6, 4],
    [5, 7, 1],
    [1, 3, 5],
    [0, 1, 7],
    [7, 6, 0]],

    sideWindowsFaces = sideWindowsFacesArr.map(toFaces),
    sideWindowsGeo = new THREE.Geometry();

    sideWindowsGeo.vertices = sideWindowsVertices;
    sideWindowsGeo.faces = sideWindowsFaces;
    sideWindowsGeo.computeVertexNormals();
    sideWindowsGeo.computeFaceNormals();

    let sideWindows = new THREE.Mesh(sideWindowsGeo, windowMat);
    this.mesh.add(sideWindows);

    // IV. Front Lights
    // A. Upper
    let frontLightVerticesArr = [
    [-0.45, 0.075, 0.4701],
    [-0.33, 0.04, 0.4999],
    [0.33, 0.04, 0.4999],
    [0.45, 0.075, 0.4701],

    [-0.45, 0.043, 0.4685],
    [-0.3315, 0.02, 0.4985],
    [0.3315, 0.02, 0.4985],
    [0.45, 0.043, 0.4685]],

    frontLightVertices = frontLightVerticesArr.map(toVectors),
    frontLightFacesArr = [
    [1, 0, 4],
    [4, 5, 1],
    [2, 1, 5],
    [5, 6, 2],
    [3, 2, 6],
    [6, 7, 3]],

    frontLightFaces = frontLightFacesArr.map(toFaces),
    frontLightGeo = new THREE.Geometry();

    frontLightGeo.vertices = frontLightVertices;
    frontLightGeo.faces = frontLightFaces;
    frontLightGeo.computeFaceNormals();

    let frontLight = new THREE.Mesh(frontLightGeo, lightMat);
    this.mesh.add(frontLight);

    // B. Lower
    let lowerLightMat = new THREE.MeshBasicMaterial({
      color: 0xff9e59,
      wireframe: this.wireframes }),

    lowerLFrontLightVerticesArr = [
    [0.343, -0.13, 0.4881],
    [0.45, -0.13, 0.4601],
    [0.343, -0.12, 0.4885],
    [0.45, -0.12, 0.4605]],

    lowerLFrontLightVertices = lowerLFrontLightVerticesArr.map(toVectors),
    lowerLFrontLightFacesArr = [
    [0, 1, 3],
    [3, 2, 0]],

    lowerLFrontLightFaces = lowerLFrontLightFacesArr.map(toFaces),
    lowerLFrontLightGeo = new THREE.Geometry();

    // left
    lowerLFrontLightGeo.vertices = lowerLFrontLightVertices;
    lowerLFrontLightGeo.faces = lowerLFrontLightFaces;
    lowerLFrontLightGeo.computeFaceNormals();

    let lowerLFrontLight = new THREE.Mesh(lowerLFrontLightGeo, lowerLightMat);
    this.mesh.add(lowerLFrontLight);

    // right
    let lowerRFrontLightVerticesArr = lowerLFrontLightVerticesArr.map(flipXVertices),
    lowerRFrontLightVertices = lowerRFrontLightVerticesArr.map(toVectors),
    lowerRFrontLightFacesArr = lowerLFrontLightFacesArr.map(reverseFaceDraws),
    lowerRFrontLightFaces = lowerRFrontLightFacesArr.map(toFaces),
    lowerRFrontLightGeo = new THREE.Geometry();

    lowerRFrontLightGeo.vertices = lowerRFrontLightVertices;
    lowerRFrontLightGeo.faces = lowerRFrontLightFaces;
    lowerRFrontLightGeo.computeFaceNormals();

    let lowerRFrontLight = new THREE.Mesh(lowerRFrontLightGeo, lowerLightMat);
    this.mesh.add(lowerRFrontLight);

    // V. Back Light
    let backLightGeo = new THREE.PlaneGeometry(W * 0.9, H * 0.06),
    backLightMat = new THREE.MeshStandardMaterial({
      color: 0x101010,
      wireframe: this.wireframes }),

    backLight = new THREE.Mesh(backLightGeo, backLightMat);

    backLightGeo.translate(0, H * 0.03, 0);
    backLight.position.set(0, H * 0.26, D * -0.5);
    backLight.rotation.set(171 * Math.PI / 180, 0, 0);

    // red part
    let backLightInnerGeo = new THREE.PlaneGeometry(W * 0.9 - H * 0.04, H * 0.02),
    backLightInnerMat = new THREE.MeshBasicMaterial({
      color: 0xd65a65,
      wireframe: this.wireframes }),

    backLightInner = new THREE.Mesh(backLightInnerGeo, backLightInnerMat);

    backLightInnerGeo.translate(0, H * 0.03, 0);
    backLightInner.position.set(0, 0, 0.01);
    backLight.add(backLightInner);

    let backLightAreaGeo = new THREE.PlaneGeometry(W * 0.18, H * 0.02),
    backLightAreaMat = new THREE.MeshBasicMaterial({
      color: 0xfdffb8,
      wireframe: this.wireframes }),

    backLightArea2 = new THREE.Mesh(backLightAreaGeo, backLightAreaMat);

    // middle light
    backLightAreaGeo.translate(0, H * 0.03, 0);
    backLightArea2.position.set(0, 0, 0.01);
    backLightInner.add(backLightArea2);

    // left light
    let backLightArea1 = backLightArea2.clone();
    backLightArea1.position.set(W * -0.33, 0, 0.01);
    backLightInner.add(backLightArea1);

    // right light
    let backLightArea3 = backLightArea2.clone();
    backLightArea3.position.set(W * 0.33, 0, 0.01);
    backLightInner.add(backLightArea3);

    this.mesh.add(backLight);

    // VI. Left Side Part Above Wheels
    let sideMat = new THREE.MeshStandardMaterial({
      color: 0x2b2b2b,
      wireframe: this.wireframes }),

    leftSideVerticesArr = [
    // top (0–19)
    [0.45, -0.1, -0.4],
    [0.5, -0.1, -0.3825],
    [0.45, 0.06, -0.36],
    [0.5, 0.03, -0.35],
    [0.45, 0.06, -0.236],
    [0.5, 0.03, -0.24],
    [0.45, -0.15, -0.18],
    [0.5, -0.15, -0.192],
    [0.41, -0.21, -0.173],
    [0.48, -0.21, -0.19],
    [0.41, -0.23, 0.2498],
    [0.48, -0.23, 0.261],
    [0.45, -0.17, 0.255],
    [0.5, -0.17, 0.263],
    [0.45, 0.06, 0.3015],
    [0.5, 0.03, 0.3035],
    [0.45, 0.06, 0.42],
    [0.5, 0.03, 0.4165],
    [0.45, -0.13, 0.46],
    [0.5, -0.13, 0.45],
    // bottom (20–41)
    [0.45, -0.074, -0.379],
    [0.5, -0.1, -0.3775],
    [0.45, 0.04, -0.35],
    [0.5, 0.015, -0.348],
    [0.45, 0.04, -0.2505],
    [0.5, 0.015, -0.2435],
    [0.45, -0.15, -0.197],
    [0.5, -0.15, -0.197],
    [0.355, -0.29, -0.19],
    [0.4, -0.29, -0.19],
    [0.355, -0.31, 0.2582],
    [0.4, -0.31, 0.26],
    [0.45, -0.17, 0.265],
    [0.5, -0.17, 0.267],
    [0.45, 0.04, 0.3099],
    [0.5, 0.015, 0.3065],
    [0.45, 0.04, 0.418],
    [0.5, 0.015, 0.4135],
    [0.45, -0.13, 0.455],
    [0.5, -0.13, 0.445],
    [0.48, -0.21, -0.194],
    [0.48, -0.23, 0.265]],

    leftSideVertices = leftSideVerticesArr.map(toVectors),
    leftSideFacesArr = [
    [0, 2, 3],
    [3, 1, 0],
    [2, 4, 5],
    [5, 3, 2],
    [4, 6, 7],
    [7, 5, 4],
    [6, 8, 9],
    [9, 7, 6],
    [8, 10, 11],
    [11, 9, 8],
    [10, 12, 13],
    [13, 11, 10],
    [12, 14, 15],
    [15, 13, 12],
    [14, 16, 17],
    [17, 15, 14],
    [16, 18, 19],
    [19, 17, 16],
    [23, 22, 20],
    [20, 21, 23],
    [25, 24, 22],
    [22, 23, 25],
    [27, 26, 24],
    [24, 25, 27],
    [31, 30, 28],
    [28, 29, 31],
    [35, 34, 32],
    [32, 33, 35],
    [37, 36, 34],
    [34, 35, 37],
    [39, 38, 36],
    [36, 37, 39],
    [0, 1, 21],
    [21, 20, 0],
    [20, 22, 2],
    [2, 0, 20],
    [22, 24, 4],
    [4, 2, 22],
    [24, 26, 6],
    [6, 4, 24],
    [26, 28, 8],
    [8, 6, 26],
    [28, 30, 10],
    [10, 8, 28],
    [30, 32, 12],
    [12, 10, 30],
    [32, 34, 14],
    [14, 12, 32],
    [34, 36, 16],
    [16, 14, 34],
    [36, 38, 18],
    [18, 16, 36],
    [3, 23, 21],
    [21, 1, 3],
    [5, 25, 23],
    [23, 3, 5],
    [7, 27, 25],
    [25, 5, 7],
    [27, 7, 9],
    [9, 40, 27],
    [40, 9, 29],
    [26, 27, 40],
    [40, 29, 26],
    [26, 29, 28],
    [11, 31, 29],
    [29, 9, 11],
    [11, 41, 31],
    [13, 33, 41],
    [4.........完整代码请登录后点击上方下载按钮下载查看

网友评论0