THREE.JS:不应显示为可见的对象显示为可见

时间:2017-03-17 18:47:41

标签: javascript three.js

我正在修补一个太阳系模拟器,除了一个部分外,它一切顺利:当月亮或行星落在其母体后面时,你仍然可以看到它!

场景中没有透明对象,我没有对渲染对象的顺序进行任何修改,所以我不知道为什么对象出现在另一个对象后面时会出现。

我正在使用three.js r71(问题仍然出现在r84中)。

要查看它出错的地方:查看http:mrhuffman.net/projects/gp并选择火星系统;你会看到Phobos或Deimos如何在火星背后仍然可见。

这是场景的代码。它不像我刚刚开始工作那样整洁,所以如果你需要澄清或有疑问,请拍!

import THREE from '../vendor/three';
import OrbitControls from '../vendor/OrbitControlsES6';
import ColladaLoader from '../vendor/ColladaLoaderES6';
import nBodyProblem from '../algorithms/nBodyProblem';

const scene = ( function () {

  //Full screen action

  let w = window.innerWidth;
  let h = window.innerHeight;

  let requestAnimationFrameId = null;
  let scene = null;
  let camera = null;
  let controls = null;
  let renderer = null;
  let system = null;
  let dae = null;

  let cameraControlsWrapper = null;
  let orbitButton = null;
  let view3DButton = null;

  let pathCanvas = document.createElement( 'canvas' );
  pathCanvas.style.display = 'none';
  pathCanvas.style.backgroundImage = 'url(misc/starfield.jpg)';
  let ctxPath = pathCanvas.getContext( '2d' );

  let massCanvas = document.createElement( 'canvas' );
  massCanvas.style.display = 'none';
  massCanvas.style.position = 'absolute';
  massCanvas.style.zIndex = 2;
  massCanvas.style.top = 0;
  massCanvas.style.bottom = 0;
  let ctxMass = massCanvas.getContext( '2d' );

  pathCanvas.width = w;
  pathCanvas.height = h;

  massCanvas.width = w;
  massCanvas.height = h;

  ctxPath.translate( w / 2, h / 2 );
  ctxMass.translate( w / 2, h / 2 );

  function showOrbits() {
    orbitButton.style.display = 'none';
    cameraControlsWrapper.style.display = 'none';
    pathCanvas.style.display = 'block';
    massCanvas.style.display = 'block';
    view3DButton.style.display = 'block';
  }

  function hideOrbits() {
    view3DButton.style.display = 'none';
    pathCanvas.style.display = 'none';
    massCanvas.style.display = 'none';
    orbitButton.style.display = 'block';
    cameraControlsWrapper.style.display = 'block';
  }

  function createBody( radius, name, type ) {
    let segments = type !== 'asteroid' ? 32 : 6;
    let geometry = new THREE.SphereGeometry( radius, segments, segments );
    let map;
    let bumpMap;

    switch( type ) {
      case 'asteroid':    
        map = THREE.ImageUtils.loadTexture('textures/Phobos.jpg');
        bumpMap = THREE.ImageUtils.loadTexture('textures/PhobosBump.jpg');
        break;

      case 'custom':    
        map = THREE.ImageUtils.loadTexture('textures/Acid.jpg');
        break;

      case 'star':    
        map = THREE.ImageUtils.loadTexture('textures/Sun.jpg');
        break;

      case 'spacecraft':    
        scene.add( dae );
        return dae;

      default:    
        map = THREE.ImageUtils.loadTexture('textures/' + name + '.jpg');
        bumpMap = THREE.ImageUtils.loadTexture('textures/Phobos.jpg');
    }

    let material = new THREE.MeshPhongMaterial( { map: map, bumpMap: bumpMap, bumpScale: 0.02 } );
    let mesh = new THREE.Mesh( geometry, material );
    mesh.rotation.x = 1.5;
    scene.add( mesh );    
    return mesh;    
}

  function sceneSetup( callback, scenario, container, camPos, camFocus, viewOrbits, view3D, cameraControls ) {
    if ( scenario.model === undefined ) {
      callback( scenario, container, camPos, camFocus, viewOrbits, view3D, cameraControls );     
      return;    
    }

    let loader = new ColladaLoader();
    loader.options.convertUpAxis = true;
    loader.load( './models/' + scenario.model + '/' + scenario.model + '.dae', ( collada ) => {    
      dae = collada.scene;
      dae.scale.setScalar( 1 / 800 );

      callback( scenario, container, camPos, camFocus, viewOrbits, view3D, cameraControls );
    });
  }

  function initSimulation( scenario, container, camPos, camFocus, viewOrbits, view3D, cameraControls ) {

    cameraControlsWrapper = cameraControls;
    orbitButton = viewOrbits;
    orbitButton.addEventListener( 'click', showOrbits, false );
    view3DButton = view3D;
    view3DButton.addEventListener( 'click', hideOrbits, false );
    hideOrbits();
    scene = new THREE.Scene();
    camera = new THREE.PerspectiveCamera( 45, w / h, 0.000001, 1500 );
    //Prevent rolling of the camera when you view a body from another    
    camera.up.set( 0, 0, 1 );    
    camera.position.set( 0, 90, 150 );    
    var light = new THREE.AmbientLight(0x404040);
    scene.add(light);    
    renderer = new THREE.WebGLRenderer({
        antialias: true,
        alpha: true
    });
    renderer.setSize(w, h);
    renderer.setClearColor(0x000000);

    container.appendChild( pathCanvas );
    container.appendChild( massCanvas );
    container.appendChild( renderer.domElement );

    controls = new OrbitControls( camera, renderer.domElement );

    //Create a new n-body problem from the selected scenario    
    system = new nBodyProblem( {
      g: scenario.g,
      law: scenario.law,
      dt: scenario.dt,
      masses: scenario.masses
    });

    //Create visual manifestations of the planets, asteroids and star(s)
    for (let i = 0; i < system.masses.length; i++) {
      let mass = system.masses[ i ];
      mass.manifestation = createBody( mass.radius, mass.name, mass.type );
    }

    const render = function () {    
      requestAnimationFrameId = requestAnimationFrame( render );    
      //Update state vectors          system.updatePositionVectors().updateVelocityVectors().updateBarycenter().calculateElapsedTime();

      //Check if a rocket should be fired and if so check if it should be fired in this iteration; should that be the case, fire!    
      if ( scenario.rocketBurn === true ) {    
        if ( system.elapsedTime === scenario.rocketBurnTime ) {    
          for ( let i = 0; i < system.masses.length; i++ ) {    
            if ( system.masses[ i ].type === 'spacecraft' ) {    
                system.masses[ i ].vx = scenario.afterRocketBurnVelocity.vx;
                system.masses[ i ].vy = scenario.afterRocketBurnVelocity.vy;
                system.masses[ i ].vz = scenario.afterRocketBurnVelocity.vz;
            }   
          }    
        }    
      }

      ctxMass.clearRect( -0.5 * w, -0.5 * h, w, h );

      //Put all the masses in their new positions and set camera position and focus    
      for (let i = 0; i < system.masses.length; i++) {    
        let mass = system.masses[ i ];    
        let x = mass.x * scenario.scale;
        let y = mass.y * scenario.scale;
        let z = mass.z * scenario.scale;

        mass.manifestation.position.set( x, y, z );    
        let camR = camPos.value;
        let name = mass.name;

        if ( camR === name ) {    
          camera.position.set( x, y, z + ( mass.radius * 1.2 ) );
          controls.enabled = false;    
        } else if ( camR === 'free' ) {    
          controls.enabled = true;    
        }

        if ( camFocus.value === name ) {    
          camera.lookAt( new THREE.Vector3( x, y, z ) );    
          //If the camera mode is free, the user can pan, orbit and have fun
          if ( camPos === 'free' ) controls.target = new THREE.Vector3( x, y, z );    
        }

        ctxPath.fillStyle = mass.color;
        ctxPath.fillRect( x, y, 1, 1 );

        ctxMass.beginPath();
        ctxMass.fillStyle = mass.color;
        ctxMass.arc( x, y, 6, 0, 2 * Math.PI );
        ctxMass.fill();

        ctxMass.font = "14px Arial";
        ctxMass.fillText( mass.name, x + 8, y );    
      }

      //Put the barycenter of the system in its new position

      let barycenterX = system.x * scenario.scale;
      let barycenterY = system.y * scenario.scale;

      ctxMass.strokeStyle = 'limegreen';
      ctxMass.lineWidth = 2;
      ctxMass.beginPath();
      ctxMass.moveTo( barycenterX - 20, barycenterY );
      ctxMass.lineTo( barycenterX + 20, barycenterY );
      ctxMass.moveTo( barycenterX, barycenterY - 20 );
      ctxMass.lineTo( barycenterX, barycenterY + 20 );
      ctxMass.stroke();

      ctxMass.fillStyle = 'limegreen';
      ctxMass.font = "14px Arial";
      ctxMass.fillText( 'Barycenter', barycenterX, barycenterY - 25 );

      renderer.render( scene, camera );

    };

    //Makes the scene responsive
    //Note that traces are cleared when the size of the viewport changes

    window.addEventListener( 'resize', onWindowResize, false );

    function onWindowResize() {    
      w = window.innerWidth;
      h = window.innerHeight;

      camera.aspect = w / h;
      camera.updateProjectionMatrix();    
      renderer.setSize( w, h );    

      pathCanvas.width = w;
      pathCanvas.height = h;

      massCanvas.width = w;
      massCanvas.height = h;

      ctxPath.clearRect( -0.5 * w, -0.5 * h, w, h );
      ctxMass.clearRect( -0.5 * w, -0.5 * h, w, h );

      ctxPath.translate( w / 2, h / 2 );
      ctxMass.translate( w / 2, h / 2 );    
    }    
    render();
  }

  //Tidy up    
  function resetSimulation() {    
    orbitButton.removeEventListener( 'click', showOrbits );
    view3DButton.removeEventListener( 'click', hideOrbits );

    cancelAnimationFrame( requestAnimationFrameId );    
    ctxPath.clearRect( -0.5 * w, -0.5 * h, w, h );

    renderer.domElement.parentNode.removeChild( renderer.domElement );
    pathCanvas.parentNode.removeChild( pathCanvas );
    massCanvas.parentNode.removeChild( massCanvas );    
  }

  //API    
  return {
    startSimulation: (  scenario, container, camPos, camFocus, viewOrbits, view3D, cameraControls  ) => {    
        sceneSetup( initSimulation, scenario, container, camPos, camFocus, viewOrbits, view3D, cameraControls );        
    },
    resetSimulation: resetSimulation
  };    
}());

export default scene;

0 个答案:

没有答案