Files
deighton-ar/mobile/ios/ViroKit.framework/Headers/VROPortal.h
2018-03-27 17:46:15 -07:00

294 lines
9.1 KiB
C++

//
// VROPortal.h
// ViroKit
//
// Created by Raj Advani on 7/31/17.
// Copyright © 2017 Viro Media. All rights reserved.
//
#ifndef VROPortal_h
#define VROPortal_h
#include "VRONode.h"
#include "VROTree.h"
#include "VROLineSegment.h"
#include "VROPortalDelegate.h"
class VROPortalFrame;
/*
Portals are nodes that partition subgraphs of the overall scene
graph. They are used to simulate "teleportation" between two
different scenes, and can also be used for more efficient visibility
determination.
*/
class VROPortal : public VRONode {
public:
VROPortal();
virtual ~VROPortal();
/*
Delete any rendering resources. Invoked prior to destruction, on the
rendering thread.
Recurses down the tree.
*/
void deleteGL();
/*
Render this portal's background.
*/
void renderBackground(const VRORenderContext &context, std::shared_ptr<VRODriver> &driver);
/*
Render this portal's geometry.
*/
void renderPortal(const VRORenderContext &context, std::shared_ptr<VRODriver> &driver);
/*
Render this portal's silhouette. The geometry is rendered using the provided material. This
method is typically used to render into the stencil or depth buffers only.
*/
void renderPortalSilhouette(std::shared_ptr<VROMaterial> &material,
VROSilhouetteMode mode, std::function<bool(const VRONode &)> filter,
const VRORenderContext &context, std::shared_ptr<VRODriver> &driver);
/*
Render the visible nodes in this portal's graph, in an order determined by the
latest computed sort keys.
*/
void renderContents(const VRORenderContext &context, std::shared_ptr<VRODriver> &driver);
/*
Iterate up and down the scene graph, starting at the active portal.
Fill in the recursion level of each portal (defined as steps to
reach from the active portal), and return a graph of all portals reached.
This is the recursive helper for VROScene::sortPortalsByDistance().
The frame number if used as a 'visited' flag, as this function searches
both up and down the graph and is expected to only be invoked once
per frame as part of the render-cycle.
The activeFrame node is used to assign an entrance frame geometry to this
portal. See the discussion under _activePortalFrame for more detail.
*/
void traversePortals(int frame, int recursionLevel,
std::shared_ptr<VROPortalFrame> activeFrame,
tree<std::shared_ptr<VROPortal>> *outPortals);
/*
Sort the visible nodes in this portal's sub-graph by their sort-keys, and fill
the internal _keys vector with the results.
*/
void sortNodesBySortKeys();
/*
Represents how how many levels deep this portal is: for example, the active portal
is 0, a portal within the active portal is 1, a portal within a portal within a portal
is 2, and so on.
Note this is *always* relative to the active portal.
*/
int getRecursionLevel() const {
return _recursionLevel;
}
/*
Set the node (with geometry) to render for the entrance to this portal. This
geometry will double as the 'exit' back to this portal from children.
*/
void setPortalEntrance(std::shared_ptr<VROPortalFrame> entrance);
const std::shared_ptr<VROPortalFrame> getPortalEntrance() {
return _portalEntrance;
}
/*
Return the portal frame being rendered for this portal; either an exit or an
entrance.
*/
const std::shared_ptr<VROPortalFrame> getActivePortalFrame() const {
return _activePortalFrame;
}
/*
Return portalDelegate if it exists.
*/
std::shared_ptr<VROPortalDelegate> getPortalDelegate() {
if (_portalDelegate.expired()){
return nullptr;
}
return _portalDelegate.lock();
}
void setPortalDelegate(std::shared_ptr<VROPortalDelegate> delegate) {
_portalDelegate = delegate;
}
/*
Return true if the portal frame rendered by this portal is an exit into
a parent portal, as opposed to this portal's own 'entrance' portal.
*/
bool isRenderingExitFrame() const {
return _activePortalFrame != _portalEntrance;
}
/*
If a portal is passable then it reprsents an entry-point into another navigable world,
meaning it can be set as the active portal. Non-passable portals can be AR elements overlaid
on the real world like picture frames, that are meant to be viewed from outside only.
*/
void setPassable(bool passable) {
_passable = passable;
}
bool isPassable() const {
return _passable;
}
/*
Return true if the given line segment intersects the portal geometry.
*/
bool intersectsLineSegment(VROLineSegment segment) const;
#pragma mark - Environment Lighting
/*
Set the lighting environment map for this portal.
*/
void setLightingEnvironment(std::shared_ptr<VROTexture> texture);
/*
Get the lighting environment map for this portal.
*/
std::shared_ptr<VROTexture> getLightingEnvironment() const;
#pragma mark - Backgrounds
/*
Note: the scene renders all backgrounds in its tree before rendering
any content.
*/
/*
Set the background to a cube-map defined by the given cube texture or
color.
*/
void setBackgroundCube(std::shared_ptr<VROTexture> textureCube);
void setBackgroundCube(VROVector4f color);
/*
Set the background to a textured sphere.
*/
void setBackgroundSphere(std::shared_ptr<VROTexture> textureSphere);
/*
Set the background to an arbitrary geometry. All this guarantees is that
the given object will be rendered first. No properties will be set on
this geometry, but typically background geometries are screen-space, and
do not read or write to the depth buffer.
*/
void setBackground(std::shared_ptr<VROGeometry> geometry);
/*
Set an arbitrary transform to apply to the background. The transform
may also be set as a quaternion (rotation).
*/
void setBackgroundTransform(VROMatrix4f transform);
void setBackgroundRotation(VROQuaternion rotation);
std::shared_ptr<VROGeometry> getBackground() const {
return _background;
}
void removeBackground();
private:
/*
The number of steps to reach this portal from the active portal.
*/
int _recursionLevel;
/*
The nodes in this portal's scene-graph, ordered for rendering by their
sort keys.
*/
std::vector<VROSortKey> _keys;
/*
True if this portal can be entered; e.g, if it can be made into an
active portal.
*/
bool _passable;
/*
Portals have an entrance node that strictly defines the *geometry*
(the frame, or window) that delineates the entrance into, or exit from,
the portal.
*/
std::shared_ptr<VROPortalFrame> _portalEntrance;
/*
The _activePortalFrame is the frame this portal should render as its
entrance.
When moving down the portal tree, this is set to the portal's own
entrance: _portalEntrance. However, when moving up the tree, this is
set to the active child portal's entrance.
For example, if we have the following portal tree:
A
B E
C D
If A is the active portal, then B would render its own entrance (as an
entrance from A into B), C would render its own entrance (as an entrance
from B into C) and so on for every portal in the tree.
However, if D is the active portal, then B will render D's entrance (as
an exit from D into B), B will render A's entrance (as an exit from B into
A), and the remaining portals (C and E) would simply render their own
entrances.
These portals frames are assigned during traversePortals.
*/
std::shared_ptr<VROPortalFrame> _activePortalFrame;
/*
The background visual to display. All backgrounds in the scene are rendered before
node content.
*/
std::shared_ptr<VROGeometry> _background;
/*
The lighting environment for this portal. Determines the effect of image-based
lighting (IBL) for objects using the physically based lighting model.
*/
std::shared_ptr<VROTexture> _lightingEnvironment;
/*
Portal delegate that is invoked when a portal is entered and exited.
*/
std::weak_ptr<VROPortalDelegate> _portalDelegate;
/*
Transform to apply to the background geometry.
*/
VROMatrix4f _backgroundTransform;
/*
Installs required shader modifiers on the background.
*/
void installBackgroundShaderModifier();
/*
Deactivates culling on every geometry in the given node, recursively down the
tree. Needed to ensure culling is off on portal frames.
*/
void deactivateCulling(std::shared_ptr<VRONode> node);
};
#endif /* VROPortal_h */