// // VROPortalFrame.h // ViroKit // // Created by Raj Advani on 8/5/17. // Copyright © 2017 Viro Media. All rights reserved. // #ifndef VROPortalFrame_h #define VROPortalFrame_h #include "VRONode.h" class VROShaderModifier; class VROLineSegment; enum class VROFace; /* Portal frames are nodes that contain the geometry representing the entrance (or exit) from the portal. We need these for two reasons: 1. They enable us to manipulate the scale and other transformations of the portal's entrance without changing the transform of the entire VROPortal. 2. VROPortals need their frames dynamically assigned each frame if the active portal changes, in order to render entrances where necessary and exits where necessary. */ class VROPortalFrame : public VRONode { public: /* Return the shader modifier that is used to render a portal frame to the stencil buffer. This modifier discards the non-transparent sections of the portal frame, so that only the 'window' gets rendered to the stencil buffer. */ static std::shared_ptr getAlphaDiscardModifier(); VROPortalFrame(); virtual ~VROPortalFrame(); /* If this portal frame is two-sided then this returns the stencil face that we should render to the stencil buffer. The other face (the inactive) face, will not render to the stencil buffer. Example: A --- P --- B Suppose A and B are two portals separated by portal frame P. Suppose P is the 'entrance' to B. Our goal is to have the front face of P display B, and the back face display A. Therefore, if we're "in" portal B, we should render the stencil to the back faces of B, and if we're "in" portal A, we should render the stencil to the front faces of B. This works because when we don't write to the stencil, we simply render the world we're in; so in the former case the front of P will render B, and the latter case the back of P will render A. */ VROFace getActiveFace(bool isExit) const; VROFace getInactiveFace(bool isExit) const; /* Return true if this portal frame is two-sided. See _twoSided below for discussion. */ bool isTwoSided() const { return _twoSided; } void setTwoSided(bool twoSided) { _twoSided = twoSided; } /* Returns true if this frame intersects the given line segment. */ bool intersectsLineSegment(VROLineSegment segment) const; private: /* Normally, both sides of a portal frame are windows into the same scene. So if you are in an AR world and you're looking through a portal into a VR world, you can walk around the portal and see the VR world from both sides of the portal. However, it's also useful to sometimes have 2-sided portals: that is, a portal which on one side shows the VR world and on the other side the AR world. This is particularly useful when we're about to pass through a portal. In such cases, we want the portal to show different worlds on each side in order to prevent flickering. Two-sided portals are enabled under the hood by using the front/back stencil buffer operations. */ bool _twoSided; }; #endif /* VROPortalFrame_h */