React-360 源码阅读【5】

栏目: 服务器 · 发布时间: 6年前

内容简介:今天我们看下大概这里我们可以看到

今天我们看下 compositor 。顾名思义,compositor 应该是你第一个接触到的 访问属性,我们不妨回顾下官方代码 Client 里面的内容:

function init(bundle, parent, options = {}) {  
  const r360 = new ReactInstance(bundle, parent, {
    // Add custom options here
    fullScreen: true,
    ...options,
  });

  // Render your app content to the default cylinder surface
  r360.renderToSurface(
    r360.createRoot('hello_360', { /* initial props */ }),
    r360.getDefaultSurface()
  );

  // Load the initial environment
  r360.compositor.setBackground(r360.getAssetURL('360_world.jpg'));
}

window.React360 = {init};

大概这里我们可以看到 r360.compositor 这么一个东西,大概我们所处理 React-360 背景的音乐,图片都是在这里完成初始化和操作的。

React-360 源码阅读【5】

这其中最核心的是 Compositor.js ,里面对外暴露了我们经常需要调用的方法;

import * as THREE from 'three';  
import {type Quaternion, type Ray, type Vec3} from '../Controls/Types';  
import createRemoteImageManager from '../Utils/createRemoteImageManager';  
import type ResourceManager from '../Utils/ResourceManager';  
import Cursor from './Cursor';  
import Environment, {type PanoOptions} from './Environment/Environment';  
import Surface from './Surface';  
import type {VideoPlayer} from './Video/Types';  
import VideoPlayerManager from './Video/VideoPlayerManager';

const LEFT = 'left';  
const RIGHT = 'right';

// 用于 VR 设备中的左右眼模式
const leftCamera = new THREE.PerspectiveCamera();  
leftCamera.matrixAutoUpdate = false;  
const rightCamera = new THREE.PerspectiveCamera();  
rightCamera.matrixAutoUpdate = false;

export default class Compositor {  
  _camera: THREE.Camera;
  _canvas: HTMLCanvasElement;
  _cursor: Cursor;
  _cursorVisibility: string;
  _defaultSurface: ?Surface;
  _environment: Environment;
  _frame: HTMLElement;
  _isMouseCursorActive: boolean;
  _renderer: THREE.WebGLRenderer;
  _scene: THREE.Scene;
  _surfaceRoot: THREE.Object3D;
  _surfaces: {[name: string]: Surface};
  _resourceManager: ResourceManager<Image>;
  _videoPlayers: VideoPlayerManager;

  constructor(frame: HTMLElement, scene: THREE.Scene) {
    this._frame = frame;
    this._cursorVisibility = 'auto';
    this._isMouseCursorActive = false;
    this._defaultSurface = null;
    this._surfaces = {};
    this._resourceManager = createRemoteImageManager();
    // 用于对视频播放器进行控制
    this._videoPlayers = new VideoPlayerManager();
    // 设置 three.js 的相机配置
    this._camera = new THREE.PerspectiveCamera(
      60,
      frame.clientWidth / frame.clientHeight,
      0.1,
      2000,
    );
    // 设置 render 这些都是最基础 three.js 创建的对象
    this._renderer = new THREE.WebGLRenderer({
      antialias: true,
    });
    this._canvas = this._renderer.domElement;
    // 设置设备的像素比
    this._renderer.setPixelRatio(window.devicePixelRatio);
    this._renderer.setSize(frame.clientWidth, frame.clientHeight);
    // 将 canvas 添加到容器中
    frame.appendChild(this._renderer.domElement);
    // 在之前 ReactInstance.js 中创建的 scene
    this._scene = scene;
    // 获取环境状态
    this._environment = new Environment(
      this._resourceManager,
      this._videoPlayers,
    );
    // 将用于背景的全景Node添加到场景中进行渲染
    scene.add(this._environment.getPanoNode());

    this._surfaceRoot = new THREE.Object3D();
    scene.add(this._surfaceRoot);

    this._cursor = new Cursor();
    // 将用于鼠标显示的图像添加进来
    scene.add(this._cursor.getMesh());
  }

  setCursorVisibility(vis: string) {
    this._cursorVisibility = vis;
  }

  // 设置背景的全景图
  setBackground(src: string, options: PanoOptions = {}): Promise<void> {
    return this._environment.setSource(src, options);
  }

  // 设置背景的视频
  setBackgroundVideo(handle: string, options: PanoOptions = {}): Promise<void> {
    return this._environment.setVideoSource(handle, options);
  }
  // 创建 视频播放器
  createVideoPlayer(handle: string): VideoPlayer {
    return this._videoPlayers.createPlayer(handle);
  }

  getVideoPlayerManager(): VideoPlayerManager {
    return this._videoPlayers;
  }

  // 访问环境状态
  getEnvironment(): Environment {
    return this._environment;
  }

  getCursorVisibility(): string {
    return this._cursorVisibility;
  }

  // 设置鼠标与当前场景的交互
  setMouseCursorActive(active: boolean) {
    if (this._isMouseCursorActive !== active) {
      this._isMouseCursorActive = active;
      this._frame.style.cursor = active ? 'pointer' : 'inherit';
    }
  }

  // 添加表面纹理
  addSurface(name: string, surface: Surface) {
    if (this._surfaces[name]) {
      throw new Error(
        `Cannot add Surface with tag '${name}', a Surface with that name already exists.`,
      );
    }
    this._surfaces[name] = surface;
  }

  showSurface(surface: Surface) {
    this._surfaceRoot.add(surface.getNode());
  }

  getSurface(name: string): ?Surface {
    return this._surfaces[name];
  }

  getDefaultSurface(): Surface {
    if (!this._defaultSurface) {
      this._defaultSurface = new Surface(1000, 600);
    }
    return this._defaultSurface;
  }
 // 获取 Canvas 元素
  getCanvas(): HTMLCanvasElement {
    return this._canvas;
  }
  // 获取 Camera 对象
  getCamera(): THREE.Camera {
    return this._camera;
  }

  // 获取 three.js 渲染对象
  getRenderer(): THREE.WebGLRenderer {
    return this._renderer;
  }
  // 重新设置当前画布的大小
  resize(width: number, height: number, pixelRatio: number = 1) {
    this._renderer.setPixelRatio(pixelRatio);
    this._renderer.setSize(width, height, false);
  }

  resizeCanvas(width: number, height: number) {
    this._camera.aspect = width / height;
    this._camera.updateProjectionMatrix();
    this._renderer.setSize(width, height, true);
  }

  prepareForRender(eye: ?string) {
    this._environment.prepareForRender(eye);
  }
  // 每一帧的回调函数
  frame(delta: number) {
    this._environment.frame(delta);
    this._videoPlayers.frame();
  }
  // 更新鼠标轨迹
  updateCursor(rays: ?Array<Ray>, depth: number) {
    if (!rays || rays.length < 1) {
      this._cursor.hide();
      return;
    }
    // TODO: extend to multiple rays
    if (!rays[0].drawsCursor) {
      this._cursor.hide();
      return;
    }
    this._cursor.show();
    const origin = rays[0].origin;
    const direction = rays[0].direction;
    const cameraToCursorX = origin[0] + direction[0] * depth;
    const cameraToCursorY = origin[1] + direction[1] * depth;
    const cameraToCursorZ = origin[2] + direction[2] * depth;
    this._cursor.setPosition(cameraToCursorX, cameraToCursorY, cameraToCursorZ);
  }

  // 开始只想渲染
  render(position: Vec3, quat: Quaternion) {
    this.prepareForRender(null);
    this._camera.position.set(position[0], position[1], position[2]);
    this._camera.quaternion.set(quat[0], quat[1], quat[2], quat[3]);

    this._renderer.render(this._scene, this._camera);
  }

  renderSurface(surface: Surface) {
    this._renderer.render(surface.getScene(), surface.getCamera());
  }
 // 渲染 VR 模式
  renderVR(display: VRDisplay, frameData: VRFrameData) {
    const preserveAutoUpdate = this._scene.autoUpdate;
    if (preserveAutoUpdate) {
      this._scene.updateMatrixWorld();
      this._scene.autoUpdate = false;
    }

    const size = this._renderer.getSize();
    this._renderer.setScissorTest(true);
    this._camera.updateMatrixWorld();

    leftCamera.matrixWorldInverse.fromArray(frameData.leftViewMatrix);
    rightCamera.matrixWorldInverse.fromArray(frameData.rightViewMatrix);
    leftCamera.matrixWorld.getInverse(leftCamera.matrixWorldInverse);
    rightCamera.matrixWorld.getInverse(rightCamera.matrixWorldInverse);
    leftCamera.projectionMatrix.fromArray(frameData.leftProjectionMatrix);
    rightCamera.projectionMatrix.fromArray(frameData.rightProjectionMatrix);

    let x = 0;
    const y = 0;
    const w = 0.5 * size.width;
    const h = size.height;

    this.prepareForRender(LEFT);
    this._renderer.setViewport(x, y, w, h);
    this._renderer.setScissor(x, y, w, h);
    this._renderer.render(this._scene, leftCamera);

    x = w;

    this.prepareForRender(RIGHT);
    this._renderer.setViewport(x, y, w, h);
    this._renderer.setScissor(x, y, w, h);
    this._renderer.render(this._scene, rightCamera);

    this._renderer.setViewport(0, 0, size.width, size.height);
    this._renderer.setScissorTest(false);

    if (preserveAutoUpdate) {
      this._scene.autoUpdate = true;
    }
    display.submitFrame();
  }
}

大概通过这些方法你可以非常方便的进行全景图的设置和视频的设置。同时你也可以获取 three.js 的一些基本对象比如 Camera, Renderer 等。


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

深入浅出WebAssembly

深入浅出WebAssembly

于航 / 电子工业出版社 / 2018-11 / 128.00元

WebAssembly是一种新的二进制格式,它可以方便地将C/C++等静态语言的代码快速地“运行”在浏览器中,这一特性为前端密集计算场景提供了无限可能。不仅如此,通过WebAssembly技术,我们还可以将基于Unity等游戏引擎开发的大型游戏快速地移植到Web端。WebAssembly技术现在已经被计划设计成W3C的标准,众多浏览器厂商已经提供了对其MVP版本标准的支持。在Google I/O ......一起来看看 《深入浅出WebAssembly》 这本书的介绍吧!

HTML 压缩/解压工具
HTML 压缩/解压工具

在线压缩/解压 HTML 代码

MD5 加密
MD5 加密

MD5 加密工具

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具