欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

动态LOD

程序员文章站 2022-04-01 17:21:48
...

动态LOD

更多有趣示例 尽在小红砖社区

示例

动态LOD

HTML

<div id="container"></div>

JS

var container, stats;
var camera, controls, scene, renderer;
var mesh, material;
var boxGeometry = new THREE.BoxGeometry( 80, 80, 80, 4, 4, 4 );
var torusGeometry = new THREE.TorusGeometry( 50, 25, 8, 8, Math.PI * 2 );
var sphereGeometry = new THREE.SphereGeometry( 50, 15, 15 );

var modifer = new THREE.SimplifyModifier();
var meshes = [];
var count = 0;
var raycaster;
var intersectColor = 0x00D66B;
var intersected;
var mouse = new THREE.Vector2();
var targetObject;
var cameraStartPositionZ = 1500;

init();
animate();

function addStuff( geometry ) {
  count ++;
  var wireframe = new THREE.MeshPhongMaterial({
    color: 0x156289,
    emissive: 0x072534,
    side: THREE.DoubleSide,
    shading: THREE.FlatShading
  });
  mesh = new THREE.Mesh(geometry, wireframe);
  // mesh.updateMatrix();
  // mesh.matrixAutoUpdate = false;
  mesh.position.x = count * 150 - 300;
  mesh.position.y = count * 150 - 300;
  mesh.userData = {
    'tick': 0,
    'normalGeometry': geometry
  };
  scene.add( mesh );
  meshes.push( mesh );
}

function init() {
  container = document.createElement( 'div' );
  document.body.appendChild( container );

  camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 1570 );
  camera.position.z = cameraStartPositionZ;
  
  scene = new THREE.Scene();
  
  var light = new THREE.PointLight( 0xffffff, 1.5 );
  light.position.set( 1000, 1000, 2000 );
  scene.add( light );
  
  addStuff( boxGeometry );
  addStuff( sphereGeometry );
  addStuff( torusGeometry );
  
  raycaster = new THREE.Raycaster();
  
  renderer = new THREE.WebGLRenderer( { antialias: true } );
  renderer.setClearColor( 0xf0f0f0 );
  renderer.setPixelRatio( window.devicePixelRatio );
  renderer.setSize( window.innerWidth, window.innerHeight );
  container.appendChild( renderer.domElement );
  
  stats = new Stats();
  container.appendChild( stats.dom );
  //
  controls = new THREE.TrackballControls( camera, renderer.domElement );
  controls.rotateSpeed = 1.0;
  controls.zoomSpeed = 2.2;
  controls.panSpeed = 0.8;
  controls.noZoom = false;
  controls.noPan = false;
  controls.staticMoving = true;
  controls.dynamicDampingFactor = 0.02;
  
  
  window.addEventListener( 'resize', onWindowResize, false );
  document.addEventListener( 'mousemove', onDocumentMouseMove, false );
  
  var mc = new Hammer(renderer.domElement);
  mc.on("panleft panright press", function (ev) {
  });

  mc.on("tap", function (e) {
    if (intersected == null) return;
    
    if (targetObject == intersected) {
      targetGoto(new THREE.Vector3(0, 0, cameraStartPositionZ - 150), 1.75, function () {
        camera.updateProjectionMatrix();
        targetObject = null;
      }, null, "auto");
    }else{
      targetObject = intersected;
      targetGoto(targetObject.position, 1.75, function () {
        camera.updateProjectionMatrix();
      }, null, "auto");
    }
  });
}

function onWindowResize() {
  camera.aspect = window.innerWidth / window.innerHeight;
  camera.updateProjectionMatrix();
  renderer.setSize( window.innerWidth, window.innerHeight );
}


function animate() {
  meshes.forEach( m => {
    m.rotation.x += 0.01;
    m.rotation.y += 0.01;
    m.rotation.z += 0.01;
  })
  camera.position.z -= camera.position.z > 300 ? 1: 
    camera.position.z < 1500 ? -0.5: 0.5;
  requestAnimationFrame( animate );
  stats.begin();
  render();
  stats.end();
}

function render() {
  controls.update();

  scene.updateMatrixWorld();
  scene.traverse(function (mesh) {
    if (mesh instanceof THREE.Mesh) {
      if(mesh.userData){
        var v1 = new THREE.Vector3();
        var v2 = new THREE.Vector3();
        v1.setFromMatrixPosition( camera.matrixWorld );
        v2.setFromMatrixPosition( mesh.matrixWorld );
        var distance = v1.distanceTo( v2 );
        var percente = distance / 1000;
        
        percente = percente > 0.9 ? 0.88 : percente < 0.16 ? 0 : percente;
        if(mesh.userData['percente'] == percente || 0.16 < percente < 0.9 )
          return;
        // console.log(percente);
        mesh.userData['percente'] = percente;
        mesh.geometry = modifer.modify( mesh.userData['normalGeometry'], mesh.userData['normalGeometry'].vertices.length * percente | 0 );
        mesh.geometry.computeFaceNormals();
      }
    }
  });
  renderer.render( scene, camera );
}

function onDocumentMouseMove(event) {
  event.preventDefault();
  
  mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1;
  mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1;

  raycaster.setFromCamera(mouse, camera);
  var intersections = raycaster.intersectObjects(scene.children);

  if (intersections.length > 0) {
    if (intersected != intersections[0].object) {
      if (intersected) intersected.material.color.setHex(intersected.currentHex);
      intersected = intersections[0].object;
      intersected.currentHex = intersected.material.color.getHex();
      intersected.material.color.setHex(intersectColor);

    }
    if (intersected && intersected.userData)
      document.body.style.cursor = 'pointer';
  }else if (intersected) {
    intersected.material.color.setHex(intersected.currentHex);
    intersected = null;
    document.body.style.cursor = 'auto';
  }
}

var tweening = false;
function targetGoto(targetVector, duration, cb, _onUpdate2, ease) {
  if(tweening) return;
  tweening = true;
  var relativeCameraOffset = new THREE.Vector3(0, 0, 150);
  var cameraOffset = targetVector.clone().add(relativeCameraOffset);
  TweenLite.killTweensOf(camera.position);
  TweenLite.to(controls.target, isNaN(duration) ? 1 : duration, {
    x: targetVector.x, y: targetVector.y, z: targetVector.z,
    onComplete: function onComplete() {
    }
  });

  TweenLite.to(camera.position, isNaN(duration) ? 1 : duration, {
    x: cameraOffset.x,
    y: cameraOffset.y,
    z: cameraOffset.z,
    overwrite: true,
    ease: ease || Expo.easeOut,
    onStart: function () {
      controls.enabled = false;
    },
    onUpdate: function onUpdate() {
      if (_onUpdate2) _onUpdate2();
    },
    onComplete: function onComplete() {
      tweening = false;
      controls.enabled = true;
      if (cb) cb();
    }
  });
};


相关标签: # 几何图形