Преглед изворни кода

Merge pull request #6663 from RaananW/videoDome-180

Video dome 180
David Catuhe пре 6 година
родитељ
комит
86a5e63f98
2 измењених фајлова са 42 додато и 4 уклоњено
  1. 1 0
      dist/preview release/what's new.md
  2. 41 4
      src/Helpers/videoDome.ts

+ 1 - 0
dist/preview release/what's new.md

@@ -31,6 +31,7 @@
 - Added url parameters to web request modifiers ([PierreLeBlond](https://github.com/PierreLeBlond))
 - Added `VRExperienceHelper.exitVROnDoubleTap` ([Deltakosh](https://github.com/deltakosh/))
 - Added `Scene.getTextureByUniqueID` ([aWeirdo](https://github.com/aWeirdo/))
+- Added support for 180 VR videos in `VideoDome` ([RaananW](https://github.com/RaananW/))
 - Added optional parameter to use Euler angles in planeRotationGizmo ([CedricGuillemet](https://github.com/CedricGuillemet))
 
 ### Engine

+ 41 - 4
src/Helpers/videoDome.ts

@@ -10,11 +10,13 @@ import "../Meshes/Builders/sphereBuilder";
 import { Nullable } from "../types";
 import { Observer } from "../Misc/observable";
 import { Vector3 } from '../Maths/math.vector';
+import { Axis } from '../Maths/math';
+import { SphereBuilder } from '../Meshes/Builders/sphereBuilder';
 
 declare type Camera = import("../Cameras/camera").Camera;
 
 /**
- * Display a 360 degree video on an approximately spherical surface, useful for VR applications or skyboxes.
+ * Display a 360/180 degree video on an approximately spherical surface, useful for VR applications or skyboxes.
  * As a subclass of TransformNode, this allow parenting to the camera or multiple videos with different locations in the scene.
  * This class achieves its effect with a VideoTexture and a correctly configured BackgroundMaterial on an inverted sphere.
  * Potential additions to this helper include zoom and and non-infinite distance rendering effects.
@@ -33,6 +35,8 @@ export class VideoDome extends TransformNode {
      */
     public static readonly MODE_SIDEBYSIDE = 2;
 
+    private _halfDome: boolean = false;
+
     private _useDirectMapping = false;
 
     /**
@@ -58,6 +62,11 @@ export class VideoDome extends TransformNode {
     protected _mesh: Mesh;
 
     /**
+     * A mesh that will be used to mask the back of the video dome in case it is a 180 degree movie.
+     */
+    private _halfDomeMask: Mesh;
+
+    /**
      * The current fov(field of view) multiplier, 0.0 - 2.0. Defaults to 1.0. Lower values "zoom in" and higher values "zoom out".
      * Also see the options.resolution property.
      */
@@ -87,6 +96,22 @@ export class VideoDome extends TransformNode {
     }
 
     /**
+     * Is the video a 180 degrees video (half dome) or 360 video (full dome)
+     *
+     */
+    public get halfDome(): boolean {
+        return this._halfDome;
+    }
+
+    /**
+     * Set the halfDome mode. If set, only the front (180 degrees) will be displayed and the back will be blacked out.
+     */
+    public set halfDome(enabled: boolean) {
+        this._halfDome = enabled;
+        this._halfDomeMask.setEnabled(enabled);
+    }
+
+    /**
      * Oberserver used in Stereoscopic VR Mode.
      */
     private _onBeforeCameraRenderObserver: Nullable<Observer<Camera>> = null;
@@ -105,7 +130,8 @@ export class VideoDome extends TransformNode {
         size?: number,
         poster?: string,
         faceForward?: boolean,
-        useDirectMapping?: boolean
+        useDirectMapping?: boolean,
+        halfDomeMode?: boolean
     }, scene: Scene) {
         super(name, scene);
 
@@ -160,6 +186,15 @@ export class VideoDome extends TransformNode {
         this._mesh.material = material;
         this._mesh.parent = this;
 
+        // create a (disabled until needed) mask to cover unneeded segments of 180 videos.
+        this._halfDomeMask = SphereBuilder.CreateSphere("", { slice: 0.5, diameter: options.size * 0.99, segments: options.resolution, sideOrientation: Mesh.BACKSIDE }, scene);
+        this._halfDomeMask.rotate(Axis.X, -Math.PI / 2);
+        // set the parent, so it will always be positioned correctly AND will be disposed when the main sphere is disposed
+        this._halfDomeMask.parent = this._mesh;
+        this._halfDome = !!options.halfDomeMode;
+        // enable or disable according to the settings
+        this._halfDomeMask.setEnabled(this._halfDome);
+
         // optional configuration
         if (options.clickToPlay) {
             scene.onPointerUp = () => {
@@ -191,13 +226,15 @@ export class VideoDome extends TransformNode {
 
         switch (value) {
             case VideoDome.MODE_SIDEBYSIDE:
-                this._videoTexture.uScale = 0.5;
+                // in half-dome mode the uScale should be double of 360 videos
+                this._videoTexture.uScale = this._halfDome ? 1 : 0.5;
                 this._onBeforeCameraRenderObserver = this._scene.onBeforeCameraRenderObservable.add((camera) => {
                     this._videoTexture.uOffset = camera.isRightCamera ? 0.5 : 0.0;
                 });
                 break;
             case VideoDome.MODE_TOPBOTTOM:
-                this._videoTexture.vScale = 0.5;
+                // in half-dome mode the vScale should be double of 360 videos
+                this._videoTexture.vScale = this._halfDome ? 1 : 0.5;
                 this._onBeforeCameraRenderObserver = this._scene.onBeforeCameraRenderObservable.add((camera) => {
                     this._videoTexture.vOffset = camera.isRightCamera ? 0.5 : 0.0;
                 });