mirror of
https://github.com/AleziaKurdis/overte.git
synced 2025-04-14 09:06:51 +02:00
Merge pull request #7827 from AndrewMeadows/threadsafe-viewfrustum
resurrection of threadsafe ViewFrustum
This commit is contained in:
commit
d7eee98acc
51 changed files with 623 additions and 553 deletions
|
@ -141,6 +141,16 @@ void OctreeQueryNode::writeToPacket(const unsigned char* buffer, unsigned int by
|
|||
}
|
||||
}
|
||||
|
||||
void OctreeQueryNode::copyCurrentViewFrustum(ViewFrustum& viewOut) const {
|
||||
QMutexLocker viewLocker(&_viewMutex);
|
||||
viewOut = _currentViewFrustum;
|
||||
}
|
||||
|
||||
void OctreeQueryNode::copyLastKnownViewFrustum(ViewFrustum& viewOut) const {
|
||||
QMutexLocker viewLocker(&_viewMutex);
|
||||
viewOut = _lastKnownViewFrustum;
|
||||
}
|
||||
|
||||
bool OctreeQueryNode::updateCurrentViewFrustum() {
|
||||
// if shutting down, return immediately
|
||||
if (_isShuttingDown) {
|
||||
|
@ -171,11 +181,13 @@ bool OctreeQueryNode::updateCurrentViewFrustum() {
|
|||
}
|
||||
|
||||
|
||||
// if there has been a change, then recalculate
|
||||
if (!newestViewFrustum.isVerySimilar(_currentViewFrustum)) {
|
||||
_currentViewFrustum = newestViewFrustum;
|
||||
_currentViewFrustum.calculate();
|
||||
currentViewFrustumChanged = true;
|
||||
{ // if there has been a change, then recalculate
|
||||
QMutexLocker viewLocker(&_viewMutex);
|
||||
if (!newestViewFrustum.isVerySimilar(_currentViewFrustum)) {
|
||||
_currentViewFrustum = newestViewFrustum;
|
||||
_currentViewFrustum.calculate();
|
||||
currentViewFrustumChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Also check for LOD changes from the client
|
||||
|
@ -219,11 +231,14 @@ void OctreeQueryNode::updateLastKnownViewFrustum() {
|
|||
return;
|
||||
}
|
||||
|
||||
bool frustumChanges = !_lastKnownViewFrustum.isVerySimilar(_currentViewFrustum);
|
||||
{
|
||||
QMutexLocker viewLocker(&_viewMutex);
|
||||
bool frustumChanges = !_lastKnownViewFrustum.isVerySimilar(_currentViewFrustum);
|
||||
|
||||
if (frustumChanges) {
|
||||
// save our currentViewFrustum into our lastKnownViewFrustum
|
||||
_lastKnownViewFrustum = _currentViewFrustum;
|
||||
if (frustumChanges) {
|
||||
// save our currentViewFrustum into our lastKnownViewFrustum
|
||||
_lastKnownViewFrustum = _currentViewFrustum;
|
||||
}
|
||||
}
|
||||
|
||||
// save that we know the view has been sent.
|
||||
|
@ -237,15 +252,13 @@ bool OctreeQueryNode::moveShouldDump() const {
|
|||
return false;
|
||||
}
|
||||
|
||||
QMutexLocker viewLocker(&_viewMutex);
|
||||
glm::vec3 oldPosition = _lastKnownViewFrustum.getPosition();
|
||||
glm::vec3 newPosition = _currentViewFrustum.getPosition();
|
||||
|
||||
// theoretically we could make this slightly larger but relative to avatar scale.
|
||||
const float MAXIMUM_MOVE_WITHOUT_DUMP = 0.0f;
|
||||
if (glm::distance(newPosition, oldPosition) > MAXIMUM_MOVE_WITHOUT_DUMP) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return glm::distance(newPosition, oldPosition) > MAXIMUM_MOVE_WITHOUT_DUMP;
|
||||
}
|
||||
|
||||
void OctreeQueryNode::dumpOutOfView() {
|
||||
|
@ -257,8 +270,10 @@ void OctreeQueryNode::dumpOutOfView() {
|
|||
int stillInView = 0;
|
||||
int outOfView = 0;
|
||||
OctreeElementBag tempBag;
|
||||
ViewFrustum viewCopy;
|
||||
copyCurrentViewFrustum(viewCopy);
|
||||
while (OctreeElementPointer elementToCheck = elementBag.extract()) {
|
||||
if (elementToCheck->isInView(_currentViewFrustum)) {
|
||||
if (elementToCheck->isInView(viewCopy)) {
|
||||
tempBag.insert(elementToCheck);
|
||||
stillInView++;
|
||||
} else {
|
||||
|
@ -267,7 +282,7 @@ void OctreeQueryNode::dumpOutOfView() {
|
|||
}
|
||||
if (stillInView > 0) {
|
||||
while (OctreeElementPointer elementToKeepInBag = tempBag.extract()) {
|
||||
if (elementToKeepInBag->isInView(_currentViewFrustum)) {
|
||||
if (elementToKeepInBag->isInView(viewCopy)) {
|
||||
elementBag.insert(elementToKeepInBag);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,7 +44,7 @@ public:
|
|||
|
||||
bool packetIsDuplicate() const;
|
||||
bool shouldSuppressDuplicatePacket();
|
||||
|
||||
|
||||
unsigned int getAvailable() const { return _octreePacket->bytesAvailableForWrite(); }
|
||||
int getMaxSearchLevel() const { return _maxSearchLevel; }
|
||||
void resetMaxSearchLevel() { _maxSearchLevel = 1; }
|
||||
|
@ -56,8 +56,8 @@ public:
|
|||
OctreeElementBag elementBag;
|
||||
OctreeElementExtraEncodeData extraEncodeData;
|
||||
|
||||
ViewFrustum& getCurrentViewFrustum() { return _currentViewFrustum; }
|
||||
ViewFrustum& getLastKnownViewFrustum() { return _lastKnownViewFrustum; }
|
||||
void copyCurrentViewFrustum(ViewFrustum& viewOut) const;
|
||||
void copyLastKnownViewFrustum(ViewFrustum& viewOut) const;
|
||||
|
||||
// These are not classic setters because they are calculating and maintaining state
|
||||
// which is set asynchronously through the network receive
|
||||
|
@ -114,6 +114,8 @@ private:
|
|||
|
||||
int _maxSearchLevel { 1 };
|
||||
int _maxLevelReachedInLastSearch { 1 };
|
||||
|
||||
mutable QMutex _viewMutex { QMutex::Recursive };
|
||||
ViewFrustum _currentViewFrustum;
|
||||
ViewFrustum _lastKnownViewFrustum;
|
||||
quint64 _lastTimeBagEmpty { 0 };
|
||||
|
@ -139,7 +141,7 @@ private:
|
|||
QQueue<OCTREE_PACKET_SEQUENCE> _nackedSequenceNumbers;
|
||||
|
||||
quint64 _sceneSendStartTime = 0;
|
||||
|
||||
|
||||
std::array<char, udt::MAX_PACKET_SIZE> _lastOctreePayload;
|
||||
};
|
||||
|
||||
|
|
|
@ -338,8 +338,6 @@ int OctreeSendThread::packetDistributor(SharedNodePointer node, OctreeQueryNode*
|
|||
|
||||
_packetData.changeSettings(true, targetSize); // FIXME - eventually support only compressed packets
|
||||
|
||||
const ViewFrustum* lastViewFrustum = viewFrustumChanged ? &nodeData->getLastKnownViewFrustum() : NULL;
|
||||
|
||||
// If the current view frustum has changed OR we have nothing to send, then search against
|
||||
// the current view frustum for things to send.
|
||||
if (viewFrustumChanged || nodeData->elementBag.isEmpty()) {
|
||||
|
@ -417,7 +415,7 @@ int OctreeSendThread::packetDistributor(SharedNodePointer node, OctreeQueryNode*
|
|||
quint64 lockWaitEnd = usecTimestampNow();
|
||||
lockWaitElapsedUsec = (float)(lockWaitEnd - lockWaitStart);
|
||||
quint64 encodeStart = usecTimestampNow();
|
||||
|
||||
|
||||
OctreeElementPointer subTree = nodeData->elementBag.extract();
|
||||
if (!subTree) {
|
||||
return;
|
||||
|
@ -426,18 +424,22 @@ int OctreeSendThread::packetDistributor(SharedNodePointer node, OctreeQueryNode*
|
|||
float octreeSizeScale = nodeData->getOctreeSizeScale();
|
||||
int boundaryLevelAdjustClient = nodeData->getBoundaryLevelAdjust();
|
||||
|
||||
int boundaryLevelAdjust = boundaryLevelAdjustClient +
|
||||
int boundaryLevelAdjust = boundaryLevelAdjustClient +
|
||||
(viewFrustumChanged ? LOW_RES_MOVING_ADJUST : NO_BOUNDARY_ADJUST);
|
||||
|
||||
EncodeBitstreamParams params(INT_MAX, &nodeData->getCurrentViewFrustum(),
|
||||
WANT_EXISTS_BITS, DONT_CHOP, viewFrustumChanged, lastViewFrustum,
|
||||
EncodeBitstreamParams params(INT_MAX, WANT_EXISTS_BITS, DONT_CHOP,
|
||||
viewFrustumChanged,
|
||||
boundaryLevelAdjust, octreeSizeScale,
|
||||
nodeData->getLastTimeBagEmpty(),
|
||||
isFullScene, &nodeData->stats, _myServer->getJurisdiction(),
|
||||
&nodeData->extraEncodeData);
|
||||
nodeData->copyCurrentViewFrustum(params.viewFrustum);
|
||||
if (viewFrustumChanged) {
|
||||
nodeData->copyLastKnownViewFrustum(params.lastViewFrustum);
|
||||
}
|
||||
|
||||
// Our trackSend() function is implemented by the server subclass, and will be called back
|
||||
// during the encodeTreeBitstream() as new entities/data elements are sent
|
||||
// during the encodeTreeBitstream() as new entities/data elements are sent
|
||||
params.trackSend = [this, node](const QUuid& dataID, quint64 dataEdited) {
|
||||
_myServer->trackSend(dataID, dataEdited, node->getUUID());
|
||||
};
|
||||
|
|
|
@ -1481,10 +1481,17 @@ void Application::paintGL() {
|
|||
|
||||
auto lodManager = DependencyManager::get<LODManager>();
|
||||
|
||||
|
||||
RenderArgs renderArgs(_gpuContext, getEntities(), getViewFrustum(), lodManager->getOctreeSizeScale(),
|
||||
{
|
||||
QMutexLocker viewLocker(&_viewMutex);
|
||||
_viewFrustum.calculate();
|
||||
}
|
||||
RenderArgs renderArgs(_gpuContext, getEntities(), lodManager->getOctreeSizeScale(),
|
||||
lodManager->getBoundaryLevelAdjust(), RenderArgs::DEFAULT_RENDER_MODE,
|
||||
RenderArgs::MONO, RenderArgs::RENDER_DEBUG_NONE);
|
||||
{
|
||||
QMutexLocker viewLocker(&_viewMutex);
|
||||
renderArgs.setViewFrustum(_viewFrustum);
|
||||
}
|
||||
|
||||
PerformanceWarning::setSuppressShortTimings(Menu::getInstance()->isOptionChecked(MenuOption::SuppressShortTimings));
|
||||
bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
|
||||
|
@ -1651,7 +1658,7 @@ void Application::paintGL() {
|
|||
renderArgs._context->enableStereo(true);
|
||||
mat4 eyeOffsets[2];
|
||||
mat4 eyeProjections[2];
|
||||
auto baseProjection = renderArgs._viewFrustum->getProjection();
|
||||
auto baseProjection = renderArgs.getViewFrustum().getProjection();
|
||||
auto hmdInterface = DependencyManager::get<HMDScriptingInterface>();
|
||||
float IPDScale = hmdInterface->getIPDScale();
|
||||
mat4 headPose = displayPlugin->getHeadPose();
|
||||
|
@ -1781,7 +1788,10 @@ void Application::resizeGL() {
|
|||
_myCamera.setProjection(glm::perspective(glm::radians(_fieldOfView.get()), aspectRatio,
|
||||
DEFAULT_NEAR_CLIP, DEFAULT_FAR_CLIP));
|
||||
// Possible change in aspect ratio
|
||||
loadViewFrustum(_myCamera, _viewFrustum);
|
||||
{
|
||||
QMutexLocker viewLocker(&_viewMutex);
|
||||
loadViewFrustum(_myCamera, _viewFrustum);
|
||||
}
|
||||
|
||||
auto offscreenUi = DependencyManager::get<OffscreenUi>();
|
||||
auto uiSize = displayPlugin->getRecommendedUiSize();
|
||||
|
@ -2108,6 +2118,7 @@ void Application::keyPressEvent(QKeyEvent* event) {
|
|||
|
||||
case Qt::Key_J:
|
||||
if (isShifted) {
|
||||
QMutexLocker viewLocker(&_viewMutex);
|
||||
_viewFrustum.setFocalLength(_viewFrustum.getFocalLength() - 0.1f);
|
||||
} else {
|
||||
_myCamera.setEyeOffsetPosition(_myCamera.getEyeOffsetPosition() + glm::vec3(-0.001, 0, 0));
|
||||
|
@ -2117,6 +2128,7 @@ void Application::keyPressEvent(QKeyEvent* event) {
|
|||
|
||||
case Qt::Key_M:
|
||||
if (isShifted) {
|
||||
QMutexLocker viewLocker(&_viewMutex);
|
||||
_viewFrustum.setFocalLength(_viewFrustum.getFocalLength() + 0.1f);
|
||||
} else {
|
||||
_myCamera.setEyeOffsetPosition(_myCamera.getEyeOffsetPosition() + glm::vec3(0.001, 0, 0));
|
||||
|
@ -2965,7 +2977,10 @@ void Application::init() {
|
|||
DependencyManager::get<NodeList>()->sendDomainServerCheckIn();
|
||||
|
||||
getEntities()->init();
|
||||
getEntities()->setViewFrustum(getViewFrustum());
|
||||
{
|
||||
QMutexLocker viewLocker(&_viewMutex);
|
||||
getEntities()->setViewFrustum(_viewFrustum);
|
||||
}
|
||||
|
||||
ObjectMotionState::setShapeManager(&_shapeManager);
|
||||
_physicsEngine->init();
|
||||
|
@ -2985,7 +3000,10 @@ void Application::init() {
|
|||
getEntities()->connectSignalsToSlots(entityScriptingInterface.data());
|
||||
|
||||
_entityClipboardRenderer.init();
|
||||
_entityClipboardRenderer.setViewFrustum(getViewFrustum());
|
||||
{
|
||||
QMutexLocker viewLocker(&_viewMutex);
|
||||
_entityClipboardRenderer.setViewFrustum(_viewFrustum);
|
||||
}
|
||||
_entityClipboardRenderer.setTree(_entityClipboard);
|
||||
|
||||
// Make sure any new sounds are loaded as soon as know about them.
|
||||
|
@ -3199,9 +3217,12 @@ void Application::resetPhysicsReadyInformation() {
|
|||
|
||||
void Application::reloadResourceCaches() {
|
||||
resetPhysicsReadyInformation();
|
||||
{
|
||||
QMutexLocker viewLocker(&_viewMutex);
|
||||
_viewFrustum.setPosition(glm::vec3(0.0f, 0.0f, TREE_SCALE));
|
||||
_viewFrustum.setOrientation(glm::quat());
|
||||
}
|
||||
// Clear entities out of view frustum
|
||||
_viewFrustum.setPosition(glm::vec3(0.0f, 0.0f, TREE_SCALE));
|
||||
_viewFrustum.setOrientation(glm::quat());
|
||||
queryOctree(NodeType::EntityServer, PacketType::EntityQuery, _entityServerJurisdictions);
|
||||
|
||||
DependencyManager::get<AssetClient>()->clearCache();
|
||||
|
@ -3490,7 +3511,7 @@ void Application::update(float deltaTime) {
|
|||
// actually need to calculate the view frustum planes to send these details
|
||||
// to the server.
|
||||
{
|
||||
PerformanceTimer perfTimer("loadViewFrustum");
|
||||
QMutexLocker viewLocker(&_viewMutex);
|
||||
loadViewFrustum(_myCamera, _viewFrustum);
|
||||
}
|
||||
|
||||
|
@ -3499,6 +3520,7 @@ void Application::update(float deltaTime) {
|
|||
// Update my voxel servers with my current voxel query...
|
||||
{
|
||||
PROFILE_RANGE_EX("QueryOctree", 0xffff0000, (uint64_t)getActiveDisplayPlugin()->presentCount());
|
||||
QMutexLocker viewLocker(&_viewMutex);
|
||||
PerformanceTimer perfTimer("queryOctree");
|
||||
quint64 sinceLastQuery = now - _lastQueriedTime;
|
||||
const quint64 TOO_LONG_SINCE_LAST_QUERY = 3 * USECS_PER_SECOND;
|
||||
|
@ -3610,14 +3632,16 @@ void Application::queryOctree(NodeType_t serverType, PacketType packetType, Node
|
|||
//qCDebug(interfaceapp) << ">>> inside... queryOctree()... _viewFrustum.getFieldOfView()=" << _viewFrustum.getFieldOfView();
|
||||
bool wantExtraDebugging = getLogger()->extraDebugging();
|
||||
|
||||
_octreeQuery.setCameraPosition(_viewFrustum.getPosition());
|
||||
_octreeQuery.setCameraOrientation(_viewFrustum.getOrientation());
|
||||
_octreeQuery.setCameraFov(_viewFrustum.getFieldOfView());
|
||||
_octreeQuery.setCameraAspectRatio(_viewFrustum.getAspectRatio());
|
||||
_octreeQuery.setCameraNearClip(_viewFrustum.getNearClip());
|
||||
_octreeQuery.setCameraFarClip(_viewFrustum.getFarClip());
|
||||
ViewFrustum viewFrustum;
|
||||
copyViewFrustum(viewFrustum);
|
||||
_octreeQuery.setCameraPosition(viewFrustum.getPosition());
|
||||
_octreeQuery.setCameraOrientation(viewFrustum.getOrientation());
|
||||
_octreeQuery.setCameraFov(viewFrustum.getFieldOfView());
|
||||
_octreeQuery.setCameraAspectRatio(viewFrustum.getAspectRatio());
|
||||
_octreeQuery.setCameraNearClip(viewFrustum.getNearClip());
|
||||
_octreeQuery.setCameraFarClip(viewFrustum.getFarClip());
|
||||
_octreeQuery.setCameraEyeOffsetPosition(glm::vec3());
|
||||
_octreeQuery.setCameraCenterRadius(_viewFrustum.getCenterRadius());
|
||||
_octreeQuery.setCameraCenterRadius(viewFrustum.getCenterRadius());
|
||||
auto lodManager = DependencyManager::get<LODManager>();
|
||||
_octreeQuery.setOctreeSizeScale(lodManager->getOctreeSizeScale());
|
||||
_octreeQuery.setBoundaryLevelAdjust(lodManager->getBoundaryLevelAdjust());
|
||||
|
@ -3653,7 +3677,7 @@ void Application::queryOctree(NodeType_t serverType, PacketType packetType, Node
|
|||
rootDetails.y * TREE_SCALE,
|
||||
rootDetails.z * TREE_SCALE) - glm::vec3(HALF_TREE_SCALE),
|
||||
rootDetails.s * TREE_SCALE);
|
||||
if (_viewFrustum.cubeIntersectsKeyhole(serverBounds)) {
|
||||
if (viewFrustum.cubeIntersectsKeyhole(serverBounds)) {
|
||||
inViewServers++;
|
||||
}
|
||||
}
|
||||
|
@ -3719,11 +3743,9 @@ void Application::queryOctree(NodeType_t serverType, PacketType packetType, Node
|
|||
rootDetails.s * TREE_SCALE);
|
||||
|
||||
|
||||
inView = _viewFrustum.cubeIntersectsKeyhole(serverBounds);
|
||||
} else {
|
||||
if (wantExtraDebugging) {
|
||||
qCDebug(interfaceapp) << "Jurisdiction without RootCode for node " << *node << ". That's unusual!";
|
||||
}
|
||||
inView = viewFrustum.cubeIntersectsKeyhole(serverBounds);
|
||||
} else if (wantExtraDebugging) {
|
||||
qCDebug(interfaceapp) << "Jurisdiction without RootCode for node " << *node << ". That's unusual!";
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3814,6 +3836,7 @@ QRect Application::getDesirableApplicationGeometry() const {
|
|||
// or the "myCamera".
|
||||
//
|
||||
void Application::loadViewFrustum(Camera& camera, ViewFrustum& viewFrustum) {
|
||||
PerformanceTimer perfTimer("loadViewFrustum");
|
||||
PROFILE_RANGE(__FUNCTION__);
|
||||
// We will use these below, from either the camera or head vectors calculated above
|
||||
viewFrustum.setProjection(camera.getProjection());
|
||||
|
@ -3842,7 +3865,8 @@ PickRay Application::computePickRay(float x, float y) const {
|
|||
getApplicationCompositor().computeHmdPickRay(pickPoint, result.origin, result.direction);
|
||||
} else {
|
||||
pickPoint /= getCanvasSize();
|
||||
getViewFrustum()->computePickRay(pickPoint.x, pickPoint.y, result.origin, result.direction);
|
||||
QMutexLocker viewLocker(&_viewMutex);
|
||||
_viewFrustum.computePickRay(pickPoint.x, pickPoint.y, result.origin, result.direction);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -3855,44 +3879,19 @@ glm::vec3 Application::getAvatarPosition() const {
|
|||
return getMyAvatar()->getPosition();
|
||||
}
|
||||
|
||||
ViewFrustum* Application::getViewFrustum() {
|
||||
#ifdef DEBUG
|
||||
if (QThread::currentThread() == activeRenderingThread) {
|
||||
// FIXME, figure out a better way to do this
|
||||
//qWarning() << "Calling Application::getViewFrustum() from the active rendering thread, did you mean Application::getDisplayViewFrustum()?";
|
||||
}
|
||||
#endif
|
||||
return &_viewFrustum;
|
||||
void Application::copyViewFrustum(ViewFrustum& viewOut) const {
|
||||
QMutexLocker viewLocker(&_viewMutex);
|
||||
viewOut = _viewFrustum;
|
||||
}
|
||||
|
||||
const ViewFrustum* Application::getViewFrustum() const {
|
||||
#ifdef DEBUG
|
||||
if (QThread::currentThread() == activeRenderingThread) {
|
||||
// FIXME, figure out a better way to do this
|
||||
//qWarning() << "Calling Application::getViewFrustum() from the active rendering thread, did you mean Application::getDisplayViewFrustum()?";
|
||||
}
|
||||
#endif
|
||||
return &_viewFrustum;
|
||||
void Application::copyDisplayViewFrustum(ViewFrustum& viewOut) const {
|
||||
QMutexLocker viewLocker(&_viewMutex);
|
||||
viewOut = _displayViewFrustum;
|
||||
}
|
||||
|
||||
ViewFrustum* Application::getDisplayViewFrustum() {
|
||||
#ifdef DEBUG
|
||||
if (QThread::currentThread() != activeRenderingThread) {
|
||||
// FIXME, figure out a better way to do this
|
||||
// qWarning() << "Calling Application::getDisplayViewFrustum() from outside the active rendering thread or outside rendering, did you mean Application::getViewFrustum()?";
|
||||
}
|
||||
#endif
|
||||
return &_displayViewFrustum;
|
||||
}
|
||||
|
||||
const ViewFrustum* Application::getDisplayViewFrustum() const {
|
||||
#ifdef DEBUG
|
||||
if (QThread::currentThread() != activeRenderingThread) {
|
||||
// FIXME, figure out a better way to do this
|
||||
// qWarning() << "Calling Application::getDisplayViewFrustum() from outside the active rendering thread or outside rendering, did you mean Application::getViewFrustum()?";
|
||||
}
|
||||
#endif
|
||||
return &_displayViewFrustum;
|
||||
void Application::copyShadowViewFrustum(ViewFrustum& viewOut) const {
|
||||
QMutexLocker viewLocker(&_viewMutex);
|
||||
viewOut = _shadowViewFrustum;
|
||||
}
|
||||
|
||||
// WorldBox Render Data & rendering functions
|
||||
|
@ -3957,7 +3956,7 @@ namespace render {
|
|||
auto skybox = skyStage->getSkybox();
|
||||
if (skybox) {
|
||||
PerformanceTimer perfTimer("skybox");
|
||||
skybox->render(batch, *(args->_viewFrustum));
|
||||
skybox->render(batch, args->getViewFrustum());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -4001,7 +4000,10 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se
|
|||
PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "Application::displaySide()");
|
||||
|
||||
// load the view frustum
|
||||
loadViewFrustum(theCamera, _displayViewFrustum);
|
||||
{
|
||||
QMutexLocker viewLocker(&_viewMutex);
|
||||
loadViewFrustum(theCamera, _displayViewFrustum);
|
||||
}
|
||||
|
||||
// TODO fix shadows and make them use the GPU library
|
||||
|
||||
|
@ -4069,7 +4071,10 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se
|
|||
{
|
||||
PerformanceTimer perfTimer("EngineRun");
|
||||
|
||||
renderArgs->_viewFrustum = getDisplayViewFrustum();
|
||||
{
|
||||
QMutexLocker viewLocker(&_viewMutex);
|
||||
renderArgs->setViewFrustum(_displayViewFrustum);
|
||||
}
|
||||
_renderEngine->getRenderContext()->args = renderArgs;
|
||||
|
||||
// Before the deferred pass, let's try to use the render engine
|
||||
|
@ -5199,10 +5204,10 @@ void Application::updateInputModes() {
|
|||
}
|
||||
|
||||
mat4 Application::getEyeProjection(int eye) const {
|
||||
QMutexLocker viewLocker(&_viewMutex);
|
||||
if (isHMDMode()) {
|
||||
return getActiveDisplayPlugin()->getEyeProjection((Eye)eye, _viewFrustum.getProjection());
|
||||
}
|
||||
|
||||
return _viewFrustum.getProjection();
|
||||
}
|
||||
|
||||
|
|
|
@ -128,14 +128,12 @@ public:
|
|||
Camera* getCamera() { return &_myCamera; }
|
||||
const Camera* getCamera() const { return &_myCamera; }
|
||||
// Represents the current view frustum of the avatar.
|
||||
ViewFrustum* getViewFrustum();
|
||||
const ViewFrustum* getViewFrustum() const;
|
||||
void copyViewFrustum(ViewFrustum& viewOut) const;
|
||||
// Represents the view frustum of the current rendering pass,
|
||||
// which might be different from the viewFrustum, i.e. shadowmap
|
||||
// passes, mirror window passes, etc
|
||||
ViewFrustum* getDisplayViewFrustum();
|
||||
const ViewFrustum* getDisplayViewFrustum() const;
|
||||
ViewFrustum* getShadowViewFrustum() override { return &_shadowViewFrustum; }
|
||||
void copyDisplayViewFrustum(ViewFrustum& viewOut) const;
|
||||
void copyShadowViewFrustum(ViewFrustum& viewOut) const override;
|
||||
const OctreePacketProcessor& getOctreePacketProcessor() const { return _octreeProcessor; }
|
||||
EntityTreeRenderer* getEntities() const { return DependencyManager::get<EntityTreeRenderer>().data(); }
|
||||
QUndoStack* getUndoStack() { return &_undoStack; }
|
||||
|
@ -169,7 +167,7 @@ public:
|
|||
virtual controller::ScriptingInterface* getControllerScriptingInterface() { return _controllerScriptingInterface; }
|
||||
virtual void registerScriptEngineWithApplicationServices(ScriptEngine* scriptEngine) override;
|
||||
|
||||
virtual ViewFrustum* getCurrentViewFrustum() override { return getDisplayViewFrustum(); }
|
||||
virtual void copyCurrentViewFrustum(ViewFrustum& viewOut) const override { copyDisplayViewFrustum(viewOut); }
|
||||
virtual QThread* getMainThread() override { return thread(); }
|
||||
virtual PickRay computePickRay(float x, float y) const override;
|
||||
virtual glm::vec3 getAvatarPosition() const override;
|
||||
|
@ -413,6 +411,7 @@ private:
|
|||
EntityTreeRenderer _entityClipboardRenderer;
|
||||
EntityTreePointer _entityClipboard;
|
||||
|
||||
mutable QMutex _viewMutex { QMutex::Recursive };
|
||||
ViewFrustum _viewFrustum; // current state of view frustum, perspective, orientation, etc.
|
||||
ViewFrustum _lastQueriedViewFrustum; /// last view frustum used to query octree servers (voxels)
|
||||
ViewFrustum _displayViewFrustum;
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
//
|
||||
|
||||
#include <SettingHandle.h>
|
||||
#include <OctreeUtils.h>
|
||||
#include <Util.h>
|
||||
|
||||
#include "Application.h"
|
||||
|
@ -216,7 +217,7 @@ QString LODManager::getLODFeedbackText() {
|
|||
bool LODManager::shouldRender(const RenderArgs* args, const AABox& bounds) {
|
||||
// FIXME - eventually we want to use the render accuracy as an indicator for the level of detail
|
||||
// to use in rendering.
|
||||
float renderAccuracy = args->_viewFrustum->calculateRenderAccuracy(bounds, args->_sizeScale, args->_boundaryLevelAdjust);
|
||||
float renderAccuracy = calculateRenderAccuracy(args->getViewFrustum().getPosition(), bounds, args->_sizeScale, args->_boundaryLevelAdjust);
|
||||
return (renderAccuracy > 0.0f);
|
||||
};
|
||||
|
||||
|
@ -228,7 +229,6 @@ void LODManager::setBoundaryLevelAdjust(int boundaryLevelAdjust) {
|
|||
_boundaryLevelAdjust = boundaryLevelAdjust;
|
||||
}
|
||||
|
||||
|
||||
void LODManager::loadSettings() {
|
||||
setDesktopLODDecreaseFPS(desktopLODDecreaseFPS.get());
|
||||
setHMDLODDecreaseFPS(hmdLODDecreaseFPS.get());
|
||||
|
@ -239,4 +239,3 @@ void LODManager::saveSettings() {
|
|||
hmdLODDecreaseFPS.set(getHMDLODDecreaseFPS());
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -194,8 +194,8 @@ void Stars::render(RenderArgs* renderArgs, float alpha) {
|
|||
|
||||
gpu::Batch& batch = *renderArgs->_batch;
|
||||
batch.setViewTransform(Transform());
|
||||
batch.setProjectionTransform(renderArgs->_viewFrustum->getProjection());
|
||||
batch.setModelTransform(Transform().setRotation(glm::inverse(renderArgs->_viewFrustum->getOrientation()) *
|
||||
batch.setProjectionTransform(renderArgs->getViewFrustum().getProjection());
|
||||
batch.setModelTransform(Transform().setRotation(glm::inverse(renderArgs->getViewFrustum().getOrientation()) *
|
||||
quat(vec3(TILT, 0, 0))));
|
||||
batch.setResourceTexture(0, textureCache->getWhiteTexture());
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include <LODManager.h>
|
||||
#include <NodeList.h>
|
||||
#include <NumericalConstants.h>
|
||||
#include <OctreeUtils.h>
|
||||
#include <udt/PacketHeaders.h>
|
||||
#include <PerfStat.h>
|
||||
#include <SharedUtil.h>
|
||||
|
@ -171,7 +172,10 @@ void Avatar::simulate(float deltaTime) {
|
|||
// update the shouldAnimate flag to match whether or not we will render the avatar.
|
||||
const float MINIMUM_VISIBILITY_FOR_ON = 0.4f;
|
||||
const float MAXIMUM_VISIBILITY_FOR_OFF = 0.6f;
|
||||
float visibility = qApp->getViewFrustum()->calculateRenderAccuracy(getBounds(), DependencyManager::get<LODManager>()->getOctreeSizeScale());
|
||||
ViewFrustum viewFrustum;
|
||||
qApp->copyViewFrustum(viewFrustum);
|
||||
float visibility = calculateRenderAccuracy(viewFrustum.getPosition(),
|
||||
getBounds(), DependencyManager::get<LODManager>()->getOctreeSizeScale());
|
||||
if (!_shouldAnimate) {
|
||||
if (visibility > MINIMUM_VISIBILITY_FOR_ON) {
|
||||
_shouldAnimate = true;
|
||||
|
@ -184,8 +188,9 @@ void Avatar::simulate(float deltaTime) {
|
|||
|
||||
// simple frustum check
|
||||
float boundingRadius = getBoundingRadius();
|
||||
bool avatarPositionInView = qApp->getDisplayViewFrustum()->sphereIntersectsFrustum(getPosition(), boundingRadius);
|
||||
bool avatarMeshInView = qApp->getDisplayViewFrustum()->boxIntersectsFrustum(_skeletonModel->getRenderableMeshBound());
|
||||
qApp->copyDisplayViewFrustum(viewFrustum);
|
||||
bool avatarPositionInView = viewFrustum.sphereIntersectsFrustum(getPosition(), boundingRadius);
|
||||
bool avatarMeshInView = viewFrustum.boxIntersectsFrustum(_skeletonModel->getRenderableMeshBound());
|
||||
|
||||
if (_shouldAnimate && !_shouldSkipRender && (avatarPositionInView || avatarMeshInView)) {
|
||||
{
|
||||
|
@ -381,17 +386,16 @@ void Avatar::render(RenderArgs* renderArgs, const glm::vec3& cameraPosition) {
|
|||
}
|
||||
}
|
||||
|
||||
// simple frustum check
|
||||
float boundingRadius = getBoundingRadius();
|
||||
ViewFrustum* frustum = nullptr;
|
||||
if (renderArgs->_renderMode == RenderArgs::SHADOW_RENDER_MODE) {
|
||||
frustum = qApp->getShadowViewFrustum();
|
||||
} else {
|
||||
frustum = qApp->getDisplayViewFrustum();
|
||||
}
|
||||
|
||||
if (!frustum->sphereIntersectsFrustum(getPosition(), boundingRadius)) {
|
||||
return;
|
||||
{ // simple frustum check
|
||||
ViewFrustum frustum;
|
||||
if (renderArgs->_renderMode == RenderArgs::SHADOW_RENDER_MODE) {
|
||||
qApp->copyShadowViewFrustum(frustum);
|
||||
} else {
|
||||
qApp->copyDisplayViewFrustum(frustum);
|
||||
}
|
||||
if (!frustum.sphereIntersectsFrustum(getPosition(), getBoundingRadius())) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
glm::vec3 toTarget = cameraPosition - getPosition();
|
||||
|
@ -413,7 +417,7 @@ void Avatar::render(RenderArgs* renderArgs, const glm::vec3& cameraPosition) {
|
|||
: GLOW_FROM_AVERAGE_LOUDNESS;
|
||||
|
||||
// render body
|
||||
renderBody(renderArgs, frustum, glowLevel);
|
||||
renderBody(renderArgs, glowLevel);
|
||||
|
||||
if (renderArgs->_renderMode != RenderArgs::SHADOW_RENDER_MODE) {
|
||||
// add local lights
|
||||
|
@ -502,9 +506,8 @@ void Avatar::render(RenderArgs* renderArgs, const glm::vec3& cameraPosition) {
|
|||
|
||||
auto cameraMode = qApp->getCamera()->getMode();
|
||||
if (!isMyAvatar() || cameraMode != CAMERA_MODE_FIRST_PERSON) {
|
||||
auto& frustum = *renderArgs->_viewFrustum;
|
||||
auto& frustum = renderArgs->getViewFrustum();
|
||||
auto textPosition = getDisplayNamePosition();
|
||||
|
||||
if (frustum.pointIntersectsFrustum(textPosition)) {
|
||||
renderDisplayName(batch, frustum, textPosition);
|
||||
}
|
||||
|
@ -553,7 +556,7 @@ void Avatar::fixupModelsInScene() {
|
|||
scene->enqueuePendingChanges(pendingChanges);
|
||||
}
|
||||
|
||||
void Avatar::renderBody(RenderArgs* renderArgs, ViewFrustum* renderFrustum, float glowLevel) {
|
||||
void Avatar::renderBody(RenderArgs* renderArgs, float glowLevel) {
|
||||
fixupModelsInScene();
|
||||
getHead()->renderLookAts(renderArgs);
|
||||
}
|
||||
|
|
|
@ -232,7 +232,7 @@ protected:
|
|||
|
||||
Transform calculateDisplayNameTransform(const ViewFrustum& view, const glm::vec3& textPosition) const;
|
||||
void renderDisplayName(gpu::Batch& batch, const ViewFrustum& view, const glm::vec3& textPosition) const;
|
||||
virtual void renderBody(RenderArgs* renderArgs, ViewFrustum* renderFrustum, float glowLevel = 0.0f);
|
||||
virtual void renderBody(RenderArgs* renderArgs, float glowLevel = 0.0f);
|
||||
virtual bool shouldRenderHead(const RenderArgs* renderArgs) const;
|
||||
virtual void fixupModelsInScene();
|
||||
|
||||
|
|
|
@ -316,9 +316,6 @@ void Head::relaxLean(float deltaTime) {
|
|||
_deltaLeanForward *= relaxationFactor;
|
||||
}
|
||||
|
||||
void Head::render(RenderArgs* renderArgs, float alpha, ViewFrustum* renderFrustum) {
|
||||
}
|
||||
|
||||
void Head::renderLookAts(RenderArgs* renderArgs) {
|
||||
renderLookAts(renderArgs, _leftEyePosition, _rightEyePosition);
|
||||
}
|
||||
|
|
|
@ -28,11 +28,10 @@ class Avatar;
|
|||
class Head : public HeadData {
|
||||
public:
|
||||
explicit Head(Avatar* owningAvatar);
|
||||
|
||||
|
||||
void init();
|
||||
void reset();
|
||||
void simulate(float deltaTime, bool isMine, bool billboard = false);
|
||||
void render(RenderArgs* renderArgs, float alpha, ViewFrustum* renderFrustum);
|
||||
void setScale(float scale);
|
||||
void setPosition(glm::vec3 position) { _position = position; }
|
||||
void setAverageLoudness(float averageLoudness) { _averageLoudness = averageLoudness; }
|
||||
|
@ -44,7 +43,7 @@ public:
|
|||
|
||||
/// \return orientationBase+Delta
|
||||
glm::quat getFinalOrientationInLocalFrame() const;
|
||||
|
||||
|
||||
/// \return orientationBody * (orientationBase+Delta)
|
||||
glm::quat getFinalOrientationInWorldFrame() const;
|
||||
|
||||
|
|
|
@ -545,7 +545,9 @@ void MyAvatar::updateFromTrackers(float deltaTime) {
|
|||
head->setDeltaYaw(estimatedRotation.y);
|
||||
head->setDeltaRoll(estimatedRotation.z);
|
||||
} else {
|
||||
float magnifyFieldOfView = qApp->getViewFrustum()->getFieldOfView() / _realWorldFieldOfView.get();
|
||||
ViewFrustum viewFrustum;
|
||||
qApp->copyViewFrustum(viewFrustum);
|
||||
float magnifyFieldOfView = viewFrustum.getFieldOfView() / _realWorldFieldOfView.get();
|
||||
head->setDeltaPitch(estimatedRotation.x * magnifyFieldOfView);
|
||||
head->setDeltaYaw(estimatedRotation.y * magnifyFieldOfView);
|
||||
head->setDeltaRoll(estimatedRotation.z);
|
||||
|
@ -928,15 +930,17 @@ void MyAvatar::updateLookAtTargetAvatar() {
|
|||
// (We will be adding that offset to the camera position, after making some other adjustments.)
|
||||
glm::vec3 gazeOffset = lookAtPosition - getHead()->getEyePosition();
|
||||
|
||||
ViewFrustum viewFrustum;
|
||||
qApp->copyViewFrustum(viewFrustum);
|
||||
|
||||
// scale gazeOffset by IPD, if wearing an HMD.
|
||||
if (qApp->isHMDMode()) {
|
||||
glm::mat4 leftEye = qApp->getEyeOffset(Eye::Left);
|
||||
glm::mat4 rightEye = qApp->getEyeOffset(Eye::Right);
|
||||
glm::vec3 leftEyeHeadLocal = glm::vec3(leftEye[3]);
|
||||
glm::vec3 rightEyeHeadLocal = glm::vec3(rightEye[3]);
|
||||
auto humanSystem = qApp->getViewFrustum();
|
||||
glm::vec3 humanLeftEye = humanSystem->getPosition() + (humanSystem->getOrientation() * leftEyeHeadLocal);
|
||||
glm::vec3 humanRightEye = humanSystem->getPosition() + (humanSystem->getOrientation() * rightEyeHeadLocal);
|
||||
glm::vec3 humanLeftEye = viewFrustum.getPosition() + (viewFrustum.getOrientation() * leftEyeHeadLocal);
|
||||
glm::vec3 humanRightEye = viewFrustum.getPosition() + (viewFrustum.getOrientation() * rightEyeHeadLocal);
|
||||
|
||||
auto hmdInterface = DependencyManager::get<HMDScriptingInterface>();
|
||||
float ipdScale = hmdInterface->getIPDScale();
|
||||
|
@ -950,7 +954,7 @@ void MyAvatar::updateLookAtTargetAvatar() {
|
|||
}
|
||||
|
||||
// And now we can finally add that offset to the camera.
|
||||
glm::vec3 corrected = qApp->getViewFrustum()->getPosition() + gazeOffset;
|
||||
glm::vec3 corrected = viewFrustum.getPosition() + gazeOffset;
|
||||
|
||||
avatar->getHead()->setCorrectedLookAtPosition(corrected);
|
||||
|
||||
|
@ -1266,7 +1270,7 @@ void MyAvatar::attach(const QString& modelURL, const QString& jointName,
|
|||
Avatar::attach(modelURL, jointName, translation, rotation, scale, isSoft, allowDuplicates, useSaved);
|
||||
}
|
||||
|
||||
void MyAvatar::renderBody(RenderArgs* renderArgs, ViewFrustum* renderFrustum, float glowLevel) {
|
||||
void MyAvatar::renderBody(RenderArgs* renderArgs, float glowLevel) {
|
||||
|
||||
if (!_skeletonModel->isRenderable()) {
|
||||
return; // wait until all models are loaded
|
||||
|
@ -1274,11 +1278,6 @@ void MyAvatar::renderBody(RenderArgs* renderArgs, ViewFrustum* renderFrustum, fl
|
|||
|
||||
fixupModelsInScene();
|
||||
|
||||
// Render head so long as the camera isn't inside it
|
||||
if (shouldRenderHead(renderArgs)) {
|
||||
getHead()->render(renderArgs, 1.0f, renderFrustum);
|
||||
}
|
||||
|
||||
// This is drawing the lookat vectors from our avatar to wherever we're looking.
|
||||
if (qApp->isHMDMode()) {
|
||||
glm::vec3 cameraPosition = qApp->getCamera()->getPosition();
|
||||
|
@ -1359,7 +1358,6 @@ void MyAvatar::destroyAnimGraph() {
|
|||
void MyAvatar::preRender(RenderArgs* renderArgs) {
|
||||
|
||||
render::ScenePointer scene = qApp->getMain3DScene();
|
||||
const bool shouldDrawHead = shouldRenderHead(renderArgs);
|
||||
|
||||
if (_skeletonModel->initWhenReady(scene)) {
|
||||
initHeadBones();
|
||||
|
@ -1411,6 +1409,7 @@ void MyAvatar::preRender(RenderArgs* renderArgs) {
|
|||
DebugDraw::getInstance().updateMyAvatarPos(getPosition());
|
||||
DebugDraw::getInstance().updateMyAvatarRot(getOrientation());
|
||||
|
||||
const bool shouldDrawHead = shouldRenderHead(renderArgs);
|
||||
if (shouldDrawHead != _prevShouldDrawHead) {
|
||||
_skeletonModel->setCauterizeBones(!shouldDrawHead);
|
||||
}
|
||||
|
|
|
@ -310,7 +310,7 @@ private:
|
|||
void simulate(float deltaTime);
|
||||
void updateFromTrackers(float deltaTime);
|
||||
virtual void render(RenderArgs* renderArgs, const glm::vec3& cameraPositio) override;
|
||||
virtual void renderBody(RenderArgs* renderArgs, ViewFrustum* renderFrustum, float glowLevel = 0.0f) override;
|
||||
virtual void renderBody(RenderArgs* renderArgs, float glowLevel = 0.0f) override;
|
||||
virtual bool shouldRenderHead(const RenderArgs* renderArgs) const override;
|
||||
void setShouldRenderLocally(bool shouldRender) { _shouldRender = shouldRender; setEnableMeshVisible(shouldRender); }
|
||||
bool getShouldRenderLocally() const { return _shouldRender; }
|
||||
|
|
|
@ -65,7 +65,7 @@ void Grid3DOverlay::render(RenderArgs* args) {
|
|||
// Get the camera position rounded to the nearest major grid line
|
||||
// This grid is for UI and should lie on worldlines
|
||||
auto cameraPosition =
|
||||
(float)_majorGridEvery * glm::round(args->_viewFrustum->getPosition() / (float)_majorGridEvery);
|
||||
(float)_majorGridEvery * glm::round(args->getViewFrustum().getPosition() / (float)_majorGridEvery);
|
||||
|
||||
position += glm::vec3(cameraPosition.x, 0.0f, cameraPosition.z);
|
||||
}
|
||||
|
|
|
@ -37,10 +37,10 @@ void LocalModelsOverlay::render(RenderArgs* args) {
|
|||
auto batch = args ->_batch;
|
||||
|
||||
Transform transform = Transform();
|
||||
transform.setTranslation(args->_viewFrustum->getPosition() + getPosition());
|
||||
transform.setTranslation(args->getViewFrustum().getPosition() + getPosition());
|
||||
batch->setViewTransform(transform);
|
||||
_entityTreeRenderer->render(args);
|
||||
transform.setTranslation(args->_viewFrustum->getPosition());
|
||||
transform.setTranslation(args->getViewFrustum().getPosition());
|
||||
batch->setViewTransform(transform);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -51,7 +51,7 @@ void RenderableTextEntityItem::render(RenderArgs* args) {
|
|||
}
|
||||
if (getFaceCamera()) {
|
||||
//rotate about vertical to face the camera
|
||||
glm::vec3 dPosition = args->_viewFrustum->getPosition() - getPosition();
|
||||
glm::vec3 dPosition = args->getViewFrustum().getPosition() - getPosition();
|
||||
// If x and z are 0, atan(x, z) is undefined, so default to 0 degrees
|
||||
float yawRotation = dPosition.x == 0.0f && dPosition.z == 0.0f ? 0.0f : glm::atan(dPosition.x, dPosition.z);
|
||||
glm::quat orientation = glm::quat(glm::vec3(0.0f, yawRotation, 0.0f));
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
|
||||
#include <FBXReader.h>
|
||||
#include <GeometryUtil.h>
|
||||
#include <OctreeUtils.h>
|
||||
|
||||
#include "EntitiesLogging.h"
|
||||
#include "EntityItemProperties.h"
|
||||
|
@ -295,7 +296,7 @@ OctreeElement::AppendState EntityTreeElement::appendElementData(OctreePacketData
|
|||
entityTreeElementExtraEncodeData->entities.contains(entity->getEntityItemID());
|
||||
}
|
||||
|
||||
if (includeThisEntity && params.viewFrustum) {
|
||||
if (includeThisEntity || params.recurseEverything) {
|
||||
|
||||
// we want to use the maximum possible box for this, so that we don't have to worry about the nuance of
|
||||
// simulation changing what's visible. consider the case where the entity contains an angular velocity
|
||||
|
@ -303,7 +304,7 @@ OctreeElement::AppendState EntityTreeElement::appendElementData(OctreePacketData
|
|||
// frustum culling on rendering.
|
||||
bool success;
|
||||
AACube entityCube = entity->getQueryAACube(success);
|
||||
if (!success || !params.viewFrustum->cubeIntersectsKeyhole(entityCube)) {
|
||||
if (!success || !params.viewFrustum.cubeIntersectsKeyhole(entityCube)) {
|
||||
includeThisEntity = false; // out of view, don't include it
|
||||
} else {
|
||||
// Check the size of the entity, it's possible that a "too small to see" entity is included in a
|
||||
|
@ -320,9 +321,10 @@ OctreeElement::AppendState EntityTreeElement::appendElementData(OctreePacketData
|
|||
// AABox. If this happens, fall back to the queryAACube.
|
||||
entityBounds = AABox(entityCube);
|
||||
}
|
||||
auto renderAccuracy = params.viewFrustum->calculateRenderAccuracy(entityBounds,
|
||||
params.octreeElementSizeScale,
|
||||
params.boundaryLevelAdjust);
|
||||
auto renderAccuracy = calculateRenderAccuracy(params.viewFrustum.getPosition(),
|
||||
entityBounds,
|
||||
params.octreeElementSizeScale,
|
||||
params.boundaryLevelAdjust);
|
||||
if (renderAccuracy <= 0.0f) {
|
||||
includeThisEntity = false; // too small, don't include it
|
||||
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#include <QString>
|
||||
|
||||
#include <GeometryUtil.h>
|
||||
#include <Gzip.h>
|
||||
#include <LogHandler.h>
|
||||
#include <NetworkAccessManager.h>
|
||||
#include <OctalCode.h>
|
||||
|
@ -40,12 +41,12 @@
|
|||
#include <ResourceManager.h>
|
||||
#include <SharedUtil.h>
|
||||
#include <PathUtils.h>
|
||||
#include <Gzip.h>
|
||||
#include <ViewFrustum.h>
|
||||
|
||||
#include "OctreeConstants.h"
|
||||
#include "OctreeElementBag.h"
|
||||
#include "Octree.h"
|
||||
#include "ViewFrustum.h"
|
||||
#include "OctreeUtils.h"
|
||||
#include "OctreeLogging.h"
|
||||
|
||||
|
||||
|
@ -898,7 +899,7 @@ int Octree::encodeTreeBitstream(OctreeElementPointer element,
|
|||
}
|
||||
|
||||
// If we're at a element that is out of view, then we can return, because no nodes below us will be in view!
|
||||
if (params.viewFrustum && !element->isInView(*params.viewFrustum)) {
|
||||
if (!params.recurseEverything && !element->isInView(params.viewFrustum)) {
|
||||
params.stopReason = EncodeBitstreamParams::OUT_OF_VIEW;
|
||||
return bytesWritten;
|
||||
}
|
||||
|
@ -1014,15 +1015,12 @@ int Octree::encodeTreeBitstreamRecursion(OctreeElementPointer element,
|
|||
}
|
||||
|
||||
ViewFrustum::intersection nodeLocationThisView = ViewFrustum::INSIDE; // assume we're inside
|
||||
|
||||
// caller can pass NULL as viewFrustum if they want everything
|
||||
if (params.viewFrustum) {
|
||||
float distance = element->distanceToCamera(*params.viewFrustum);
|
||||
if (!params.recurseEverything) {
|
||||
float boundaryDistance = boundaryDistanceForRenderLevel(element->getLevel() + params.boundaryLevelAdjust,
|
||||
params.octreeElementSizeScale);
|
||||
|
||||
// If we're too far away for our render level, then just return
|
||||
if (distance >= boundaryDistance) {
|
||||
if (element->distanceToCamera(params.viewFrustum) >= boundaryDistance) {
|
||||
if (params.stats) {
|
||||
params.stats->skippedDistance(element);
|
||||
}
|
||||
|
@ -1034,7 +1032,7 @@ int Octree::encodeTreeBitstreamRecursion(OctreeElementPointer element,
|
|||
// if we are INSIDE, INTERSECT, or OUTSIDE
|
||||
if (parentLocationThisView != ViewFrustum::INSIDE) {
|
||||
assert(parentLocationThisView != ViewFrustum::OUTSIDE); // we shouldn't be here if our parent was OUTSIDE!
|
||||
nodeLocationThisView = element->computeViewIntersection(*params.viewFrustum);
|
||||
nodeLocationThisView = element->computeViewIntersection(params.viewFrustum);
|
||||
}
|
||||
|
||||
// If we're at a element that is out of view, then we can return, because no nodes below us will be in view!
|
||||
|
@ -1052,8 +1050,8 @@ int Octree::encodeTreeBitstreamRecursion(OctreeElementPointer element,
|
|||
// because we don't send nodes from the previously know in view frustum.
|
||||
bool wasInView = false;
|
||||
|
||||
if (params.deltaViewFrustum && params.lastViewFrustum) {
|
||||
ViewFrustum::intersection location = element->computeViewIntersection(*params.lastViewFrustum);
|
||||
if (params.deltaView) {
|
||||
ViewFrustum::intersection location = element->computeViewIntersection(params.lastViewFrustum);
|
||||
|
||||
// If we're a leaf, then either intersect or inside is considered "formerly in view"
|
||||
if (element->isLeaf()) {
|
||||
|
@ -1067,10 +1065,9 @@ int Octree::encodeTreeBitstreamRecursion(OctreeElementPointer element,
|
|||
// to it, and so therefore it may now be visible from an LOD perspective, in which case we don't consider it
|
||||
// as "was in view"...
|
||||
if (wasInView) {
|
||||
float distance = element->distanceToCamera(*params.lastViewFrustum);
|
||||
float boundaryDistance = boundaryDistanceForRenderLevel(element->getLevel() + params.boundaryLevelAdjust,
|
||||
params.octreeElementSizeScale);
|
||||
if (distance >= boundaryDistance) {
|
||||
if (element->distanceToCamera(params.lastViewFrustum) >= boundaryDistance) {
|
||||
// This would have been invisible... but now should be visible (we wouldn't be here otherwise)...
|
||||
wasInView = false;
|
||||
}
|
||||
|
@ -1078,9 +1075,9 @@ int Octree::encodeTreeBitstreamRecursion(OctreeElementPointer element,
|
|||
}
|
||||
|
||||
// If we were previously in the view, then we normally will return out of here and stop recursing. But
|
||||
// if we're in deltaViewFrustum mode, and this element has changed since it was last sent, then we do
|
||||
// if we're in deltaView mode, and this element has changed since it was last sent, then we do
|
||||
// need to send it.
|
||||
if (wasInView && !(params.deltaViewFrustum && element->hasChangedSince(params.lastViewFrustumSent - CHANGE_FUDGE))) {
|
||||
if (wasInView && !(params.deltaView && element->hasChangedSince(params.lastViewFrustumSent - CHANGE_FUDGE))) {
|
||||
if (params.stats) {
|
||||
params.stats->skippedWasInView(element);
|
||||
}
|
||||
|
@ -1090,7 +1087,7 @@ int Octree::encodeTreeBitstreamRecursion(OctreeElementPointer element,
|
|||
|
||||
// If we're not in delta sending mode, and we weren't asked to do a force send, and the voxel hasn't changed,
|
||||
// then we can also bail early and save bits
|
||||
if (!params.forceSendScene && !params.deltaViewFrustum &&
|
||||
if (!params.forceSendScene && !params.deltaView &&
|
||||
!element->hasChangedSince(params.lastViewFrustumSent - CHANGE_FUDGE)) {
|
||||
if (params.stats) {
|
||||
params.stats->skippedNoChange(element);
|
||||
|
@ -1179,10 +1176,10 @@ int Octree::encodeTreeBitstreamRecursion(OctreeElementPointer element,
|
|||
int originalIndex = indexOfChildren[i];
|
||||
|
||||
bool childIsInView = (childElement &&
|
||||
( !params.viewFrustum || // no view frustum was given, everything is assumed in view
|
||||
(nodeLocationThisView == ViewFrustum::INSIDE) || // parent was fully in view, we can assume ALL children are
|
||||
(params.recurseEverything ||
|
||||
(nodeLocationThisView == ViewFrustum::INSIDE) || // parent was fully in view, we can assume ALL children are
|
||||
(nodeLocationThisView == ViewFrustum::INTERSECT &&
|
||||
childElement->isInView(*params.viewFrustum)) // the parent intersects and the child is in view
|
||||
childElement->isInView(params.viewFrustum)) // the parent intersects and the child is in view
|
||||
));
|
||||
|
||||
if (!childIsInView) {
|
||||
|
@ -1192,12 +1189,11 @@ int Octree::encodeTreeBitstreamRecursion(OctreeElementPointer element,
|
|||
}
|
||||
} else {
|
||||
// Before we consider this further, let's see if it's in our LOD scope...
|
||||
float distance = distancesToChildren[i];
|
||||
float boundaryDistance = !params.viewFrustum ? 1 :
|
||||
boundaryDistanceForRenderLevel(childElement->getLevel() + params.boundaryLevelAdjust,
|
||||
float boundaryDistance = params.recurseEverything ? 1 :
|
||||
boundaryDistanceForRenderLevel(childElement->getLevel() + params.boundaryLevelAdjust,
|
||||
params.octreeElementSizeScale);
|
||||
|
||||
if (!(distance < boundaryDistance)) {
|
||||
if (!(distancesToChildren[i] < boundaryDistance)) {
|
||||
// don't need to check childElement here, because we can't get here with no childElement
|
||||
if (params.stats) {
|
||||
params.stats->skippedDistance(childElement);
|
||||
|
@ -1215,10 +1211,9 @@ int Octree::encodeTreeBitstreamRecursion(OctreeElementPointer element,
|
|||
|
||||
bool childIsOccluded = false; // assume it's not occluded
|
||||
|
||||
bool shouldRender = !params.viewFrustum
|
||||
? true
|
||||
: childElement->calculateShouldRender(params.viewFrustum,
|
||||
params.octreeElementSizeScale, params.boundaryLevelAdjust);
|
||||
bool shouldRender = params.recurseEverything ||
|
||||
childElement->calculateShouldRender(params.viewFrustum,
|
||||
params.octreeElementSizeScale, params.boundaryLevelAdjust);
|
||||
|
||||
// track some stats
|
||||
if (params.stats) {
|
||||
|
@ -1236,8 +1231,8 @@ int Octree::encodeTreeBitstreamRecursion(OctreeElementPointer element,
|
|||
if (shouldRender && !childIsOccluded) {
|
||||
bool childWasInView = false;
|
||||
|
||||
if (childElement && params.deltaViewFrustum && params.lastViewFrustum) {
|
||||
ViewFrustum::intersection location = childElement->computeViewIntersection(*params.lastViewFrustum);
|
||||
if (childElement && params.deltaView) {
|
||||
ViewFrustum::intersection location = childElement->computeViewIntersection(params.lastViewFrustum);
|
||||
|
||||
// If we're a leaf, then either intersect or inside is considered "formerly in view"
|
||||
if (childElement->isLeaf()) {
|
||||
|
@ -1251,7 +1246,7 @@ int Octree::encodeTreeBitstreamRecursion(OctreeElementPointer element,
|
|||
// Or if we were previously in the view, but this element has changed since it was last sent, then we do
|
||||
// need to send it.
|
||||
if (!childWasInView ||
|
||||
(params.deltaViewFrustum &&
|
||||
(params.deltaView &&
|
||||
childElement->hasChangedSince(params.lastViewFrustumSent - CHANGE_FUDGE))){
|
||||
|
||||
childrenDataBits += (1 << (7 - originalIndex));
|
||||
|
@ -1456,7 +1451,7 @@ int Octree::encodeTreeBitstreamRecursion(OctreeElementPointer element,
|
|||
// called databits), then we wouldn't send the children. So those types of Octree's should tell us to keep
|
||||
// recursing, by returning TRUE in recurseChildrenWithData().
|
||||
|
||||
if (recurseChildrenWithData() || !params.viewFrustum || !oneAtBit(childrenDataBits, originalIndex)) {
|
||||
if (params.recurseEverything || recurseChildrenWithData() || !oneAtBit(childrenDataBits, originalIndex)) {
|
||||
|
||||
// Allow the datatype a chance to determine if it really wants to recurse this tree. Usually this
|
||||
// will be true. But if the tree has already been encoded, we will skip this.
|
||||
|
@ -1978,7 +1973,8 @@ void Octree::writeToSVOFile(const char* fileName, OctreeElementPointer element)
|
|||
bool lastPacketWritten = false;
|
||||
|
||||
while (OctreeElementPointer subTree = elementBag.extract()) {
|
||||
EncodeBitstreamParams params(INT_MAX, IGNORE_VIEW_FRUSTUM, NO_EXISTS_BITS);
|
||||
EncodeBitstreamParams params(INT_MAX, NO_EXISTS_BITS);
|
||||
params.recurseEverything = true;
|
||||
withReadLock([&] {
|
||||
params.extraEncodeData = &extraEncodeData;
|
||||
bytesWritten = encodeTreeBitstream(subTree, &packetData, elementBag, params);
|
||||
|
|
|
@ -20,9 +20,9 @@
|
|||
|
||||
#include <shared/ReadWriteLockable.h>
|
||||
#include <SimpleMovingAverage.h>
|
||||
#include <ViewFrustum.h>
|
||||
|
||||
#include "JurisdictionMap.h"
|
||||
#include "ViewFrustum.h"
|
||||
#include "OctreeElement.h"
|
||||
#include "OctreeElementBag.h"
|
||||
#include "OctreePacketData.h"
|
||||
|
@ -61,22 +61,22 @@ const int LOW_RES_MOVING_ADJUST = 1;
|
|||
const quint64 IGNORE_LAST_SENT = 0;
|
||||
|
||||
#define IGNORE_SCENE_STATS NULL
|
||||
#define IGNORE_VIEW_FRUSTUM NULL
|
||||
#define IGNORE_COVERAGE_MAP NULL
|
||||
#define IGNORE_JURISDICTION_MAP NULL
|
||||
|
||||
class EncodeBitstreamParams {
|
||||
public:
|
||||
ViewFrustum viewFrustum;
|
||||
ViewFrustum lastViewFrustum;
|
||||
quint64 lastViewFrustumSent;
|
||||
int maxEncodeLevel;
|
||||
int maxLevelReached;
|
||||
const ViewFrustum* viewFrustum;
|
||||
bool includeExistsBits;
|
||||
int chopLevels;
|
||||
bool deltaViewFrustum;
|
||||
const ViewFrustum* lastViewFrustum;
|
||||
bool deltaView;
|
||||
bool recurseEverything { false };
|
||||
int boundaryLevelAdjust;
|
||||
float octreeElementSizeScale;
|
||||
quint64 lastViewFrustumSent;
|
||||
bool forceSendScene;
|
||||
OctreeSceneStats* stats;
|
||||
JurisdictionMap* jurisdictionMap;
|
||||
|
@ -99,11 +99,9 @@ public:
|
|||
|
||||
EncodeBitstreamParams(
|
||||
int maxEncodeLevel = INT_MAX,
|
||||
const ViewFrustum* viewFrustum = IGNORE_VIEW_FRUSTUM,
|
||||
bool includeExistsBits = WANT_EXISTS_BITS,
|
||||
int chopLevels = 0,
|
||||
bool deltaViewFrustum = false,
|
||||
const ViewFrustum* lastViewFrustum = IGNORE_VIEW_FRUSTUM,
|
||||
bool useDeltaView = false,
|
||||
int boundaryLevelAdjust = NO_BOUNDARY_ADJUST,
|
||||
float octreeElementSizeScale = DEFAULT_OCTREE_SIZE_SCALE,
|
||||
quint64 lastViewFrustumSent = IGNORE_LAST_SENT,
|
||||
|
@ -111,22 +109,22 @@ public:
|
|||
OctreeSceneStats* stats = IGNORE_SCENE_STATS,
|
||||
JurisdictionMap* jurisdictionMap = IGNORE_JURISDICTION_MAP,
|
||||
OctreeElementExtraEncodeData* extraEncodeData = NULL) :
|
||||
lastViewFrustumSent(lastViewFrustumSent),
|
||||
maxEncodeLevel(maxEncodeLevel),
|
||||
maxLevelReached(0),
|
||||
viewFrustum(viewFrustum),
|
||||
includeExistsBits(includeExistsBits),
|
||||
chopLevels(chopLevels),
|
||||
deltaViewFrustum(deltaViewFrustum),
|
||||
lastViewFrustum(lastViewFrustum),
|
||||
deltaView(useDeltaView),
|
||||
boundaryLevelAdjust(boundaryLevelAdjust),
|
||||
octreeElementSizeScale(octreeElementSizeScale),
|
||||
lastViewFrustumSent(lastViewFrustumSent),
|
||||
forceSendScene(forceSendScene),
|
||||
stats(stats),
|
||||
jurisdictionMap(jurisdictionMap),
|
||||
extraEncodeData(extraEncodeData),
|
||||
stopReason(UNKNOWN)
|
||||
{}
|
||||
{
|
||||
lastViewFrustum.invalidate();
|
||||
}
|
||||
|
||||
void displayStopReason() {
|
||||
printf("StopReason: ");
|
||||
|
@ -341,7 +339,7 @@ public:
|
|||
|
||||
bool getIsClient() const { return !_isServer; } /// Is this a client based tree. Allows guards for certain operations
|
||||
void setIsClient(bool isClient) { _isServer = !isClient; }
|
||||
|
||||
|
||||
virtual void dumpTree() { }
|
||||
virtual void pruneTree() { }
|
||||
|
||||
|
@ -352,7 +350,6 @@ public:
|
|||
virtual quint64 getAverageCreateTime() const { return 0; }
|
||||
virtual quint64 getAverageLoggingTime() const { return 0; }
|
||||
|
||||
|
||||
signals:
|
||||
void importSize(float x, float y, float z);
|
||||
void importProgress(int progress);
|
||||
|
|
|
@ -22,10 +22,11 @@
|
|||
|
||||
#include "AACube.h"
|
||||
#include "OctalCode.h"
|
||||
#include "Octree.h"
|
||||
#include "OctreeConstants.h"
|
||||
#include "OctreeElement.h"
|
||||
#include "Octree.h"
|
||||
#include "OctreeLogging.h"
|
||||
#include "OctreeUtils.h"
|
||||
#include "SharedUtil.h"
|
||||
|
||||
AtomicUIntStat OctreeElement::_octreeMemoryUsage { 0 };
|
||||
|
@ -471,11 +472,11 @@ ViewFrustum::intersection OctreeElement::computeViewIntersection(const ViewFrust
|
|||
// Since, if we know the camera position and orientation, we can know which of the corners is the "furthest"
|
||||
// corner. We can use we can use this corner as our "voxel position" to do our distance calculations off of.
|
||||
// By doing this, we don't need to test each child voxel's position vs the LOD boundary
|
||||
bool OctreeElement::calculateShouldRender(const ViewFrustum* viewFrustum, float voxelScaleSize, int boundaryLevelAdjust) const {
|
||||
bool OctreeElement::calculateShouldRender(const ViewFrustum& viewFrustum, float voxelScaleSize, int boundaryLevelAdjust) const {
|
||||
bool shouldRender = false;
|
||||
|
||||
if (hasContent()) {
|
||||
float furthestDistance = furthestDistanceToCamera(*viewFrustum);
|
||||
float furthestDistance = furthestDistanceToCamera(viewFrustum);
|
||||
float childBoundary = boundaryDistanceForRenderLevel(getLevel() + 1 + boundaryLevelAdjust, voxelScaleSize);
|
||||
bool inChildBoundary = (furthestDistance <= childBoundary);
|
||||
if (hasDetailedContent() && inChildBoundary) {
|
||||
|
|
|
@ -21,9 +21,9 @@
|
|||
|
||||
#include <OctalCode.h>
|
||||
#include <SharedUtil.h>
|
||||
#include <ViewFrustum.h>
|
||||
|
||||
#include "AACube.h"
|
||||
#include "ViewFrustum.h"
|
||||
#include "OctreeConstants.h"
|
||||
|
||||
using AtomicUIntStat = std::atomic<uintmax_t>;
|
||||
|
@ -139,7 +139,7 @@ public:
|
|||
float distanceToCamera(const ViewFrustum& viewFrustum) const;
|
||||
float furthestDistanceToCamera(const ViewFrustum& viewFrustum) const;
|
||||
|
||||
bool calculateShouldRender(const ViewFrustum* viewFrustum,
|
||||
bool calculateShouldRender(const ViewFrustum& viewFrustum,
|
||||
float voxelSizeScale = DEFAULT_OCTREE_SIZE_SCALE, int boundaryLevelAdjust = 0) const;
|
||||
|
||||
// points are assumed to be in Voxel Coordinates (not TREE_SCALE'd)
|
||||
|
|
|
@ -14,14 +14,12 @@
|
|||
#include "OctreeLogging.h"
|
||||
#include "OctreeHeadlessViewer.h"
|
||||
|
||||
OctreeHeadlessViewer::OctreeHeadlessViewer() : OctreeRenderer()
|
||||
{
|
||||
OctreeHeadlessViewer::OctreeHeadlessViewer() : OctreeRenderer() {
|
||||
_viewFrustum.setProjection(glm::perspective(glm::radians(DEFAULT_FIELD_OF_VIEW_DEGREES), DEFAULT_ASPECT_RATIO, DEFAULT_NEAR_CLIP, DEFAULT_FAR_CLIP));
|
||||
}
|
||||
|
||||
void OctreeHeadlessViewer::init() {
|
||||
OctreeRenderer::init();
|
||||
setViewFrustum(&_viewFrustum);
|
||||
}
|
||||
|
||||
void OctreeHeadlessViewer::queryOctree() {
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
|
||||
#include <udt/PacketHeaders.h>
|
||||
#include <SharedUtil.h>
|
||||
#include <ViewFrustum.h>
|
||||
|
||||
#include "JurisdictionListener.h"
|
||||
#include "Octree.h"
|
||||
|
@ -22,7 +23,6 @@
|
|||
#include "OctreeRenderer.h"
|
||||
#include "OctreeSceneStats.h"
|
||||
#include "Octree.h"
|
||||
#include "ViewFrustum.h"
|
||||
|
||||
// Generic client side Octree renderer class.
|
||||
class OctreeHeadlessViewer : public OctreeRenderer {
|
||||
|
@ -66,7 +66,6 @@ public slots:
|
|||
unsigned getOctreeElementsCount() const { return _tree->getOctreeElementsCount(); }
|
||||
|
||||
private:
|
||||
ViewFrustum _viewFrustum;
|
||||
JurisdictionListener* _jurisdictionListener = nullptr;
|
||||
OctreeQuery _octreeQuery;
|
||||
|
||||
|
|
|
@ -120,4 +120,3 @@ glm::vec3 OctreeQuery::calculateCameraDirection() const {
|
|||
glm::vec3 direction = glm::vec3(_cameraOrientation * glm::vec4(IDENTITY_FRONT, 0.0f));
|
||||
return direction;
|
||||
}
|
||||
|
||||
|
|
|
@ -22,8 +22,7 @@
|
|||
|
||||
OctreeRenderer::OctreeRenderer() :
|
||||
_tree(NULL),
|
||||
_managedTree(false),
|
||||
_viewFrustum(NULL)
|
||||
_managedTree(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -201,9 +200,9 @@ void OctreeRenderer::processDatagram(ReceivedMessage& message, SharedNodePointer
|
|||
|
||||
bool OctreeRenderer::renderOperation(OctreeElementPointer element, void* extraData) {
|
||||
RenderArgs* args = static_cast<RenderArgs*>(extraData);
|
||||
if (element->isInView(*args->_viewFrustum)) {
|
||||
if (element->isInView(args->getViewFrustum())) {
|
||||
if (element->hasContent()) {
|
||||
if (element->calculateShouldRender(args->_viewFrustum, args->_sizeScale, args->_boundaryLevelAdjust)) {
|
||||
if (element->calculateShouldRender(args->getViewFrustum(), args->_sizeScale, args->_boundaryLevelAdjust)) {
|
||||
args->_renderer->renderElement(element, args);
|
||||
} else {
|
||||
return false; // if we shouldn't render, then we also should stop recursing.
|
||||
|
|
|
@ -20,10 +20,10 @@
|
|||
#include <udt/PacketHeaders.h>
|
||||
#include <RenderArgs.h>
|
||||
#include <SharedUtil.h>
|
||||
#include <ViewFrustum.h>
|
||||
|
||||
#include "Octree.h"
|
||||
#include "OctreePacketData.h"
|
||||
#include "ViewFrustum.h"
|
||||
|
||||
class OctreeRenderer;
|
||||
|
||||
|
@ -51,8 +51,8 @@ public:
|
|||
/// render the content of the octree
|
||||
virtual void render(RenderArgs* renderArgs);
|
||||
|
||||
ViewFrustum* getViewFrustum() const { return _viewFrustum; }
|
||||
void setViewFrustum(ViewFrustum* viewFrustum) { _viewFrustum = viewFrustum; }
|
||||
const ViewFrustum& getViewFrustum() const { return _viewFrustum; }
|
||||
void setViewFrustum(const ViewFrustum& viewFrustum) { _viewFrustum = viewFrustum; }
|
||||
|
||||
static bool renderOperation(OctreeElementPointer element, void* extraData);
|
||||
|
||||
|
@ -75,7 +75,7 @@ protected:
|
|||
|
||||
OctreePointer _tree;
|
||||
bool _managedTree;
|
||||
ViewFrustum* _viewFrustum;
|
||||
ViewFrustum _viewFrustum;
|
||||
|
||||
SimpleMovingAverage _elementsPerPacket;
|
||||
SimpleMovingAverage _entitiesPerPacket;
|
||||
|
|
71
libraries/octree/src/OctreeUtils.cpp
Normal file
71
libraries/octree/src/OctreeUtils.cpp
Normal file
|
@ -0,0 +1,71 @@
|
|||
//
|
||||
// OctreeUtils.cpp
|
||||
// libraries/octree/src
|
||||
//
|
||||
// Created by Andrew Meadows 2016.03.04
|
||||
// Copyright 2016 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include "OctreeUtils.h"
|
||||
|
||||
#include <mutex>
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
#include <AABox.h>
|
||||
|
||||
|
||||
float calculateRenderAccuracy(const glm::vec3& position,
|
||||
const AABox& bounds,
|
||||
float octreeSizeScale,
|
||||
int boundaryLevelAdjust) {
|
||||
float largestDimension = bounds.getLargestDimension();
|
||||
|
||||
const float maxScale = (float)TREE_SCALE;
|
||||
float visibleDistanceAtMaxScale = boundaryDistanceForRenderLevel(boundaryLevelAdjust, octreeSizeScale) / OCTREE_TO_MESH_RATIO;
|
||||
|
||||
static std::once_flag once;
|
||||
static QMap<float, float> shouldRenderTable;
|
||||
std::call_once(once, [&] {
|
||||
float SMALLEST_SCALE_IN_TABLE = 0.001f; // 1mm is plenty small
|
||||
float scale = maxScale;
|
||||
float factor = 1.0f;
|
||||
|
||||
while (scale > SMALLEST_SCALE_IN_TABLE) {
|
||||
scale /= 2.0f;
|
||||
factor /= 2.0f;
|
||||
shouldRenderTable[scale] = factor;
|
||||
}
|
||||
});
|
||||
|
||||
float closestScale = maxScale;
|
||||
float visibleDistanceAtClosestScale = visibleDistanceAtMaxScale;
|
||||
QMap<float, float>::const_iterator lowerBound = shouldRenderTable.lowerBound(largestDimension);
|
||||
if (lowerBound != shouldRenderTable.constEnd()) {
|
||||
closestScale = lowerBound.key();
|
||||
visibleDistanceAtClosestScale = visibleDistanceAtMaxScale * lowerBound.value();
|
||||
}
|
||||
|
||||
if (closestScale < largestDimension) {
|
||||
visibleDistanceAtClosestScale *= 2.0f;
|
||||
}
|
||||
|
||||
// FIXME - for now, it's either visible or not visible. We want to adjust this to eventually return
|
||||
// a floating point for objects that have small angular size to indicate that they may be rendered
|
||||
// with lower preciscion
|
||||
float distanceToCamera = glm::length(bounds.calcCenter() - position);
|
||||
return (distanceToCamera <= visibleDistanceAtClosestScale) ? 1.0f : 0.0f;
|
||||
}
|
||||
|
||||
float boundaryDistanceForRenderLevel(unsigned int renderLevel, float voxelSizeScale) {
|
||||
return voxelSizeScale / powf(2.0f, renderLevel);
|
||||
}
|
||||
|
||||
float getAccuracyAngle(float octreeSizeScale, int boundaryLevelAdjust) {
|
||||
const float maxScale = (float)TREE_SCALE;
|
||||
float visibleDistanceAtMaxScale = boundaryDistanceForRenderLevel(boundaryLevelAdjust, octreeSizeScale) / OCTREE_TO_MESH_RATIO;
|
||||
return atan(maxScale / visibleDistanceAtMaxScale);
|
||||
}
|
30
libraries/octree/src/OctreeUtils.h
Normal file
30
libraries/octree/src/OctreeUtils.h
Normal file
|
@ -0,0 +1,30 @@
|
|||
//
|
||||
// OctreeUtils.h
|
||||
// libraries/octree/src
|
||||
//
|
||||
// Created by Andrew Meadows 2016.03.04
|
||||
// Copyright 2016 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#ifndef hifi_OctreeUtils_h
|
||||
#define hifi_OctreeUtils_h
|
||||
|
||||
#include "OctreeConstants.h"
|
||||
|
||||
class AABox;
|
||||
|
||||
/// renderAccuracy represents a floating point "visibility" of an object based on it's view from the camera. At a simple
|
||||
/// level it returns 0.0f for things that are so small for the current settings that they could not be visible.
|
||||
float calculateRenderAccuracy(const glm::vec3& position,
|
||||
const AABox& bounds,
|
||||
float octreeSizeScale = DEFAULT_OCTREE_SIZE_SCALE,
|
||||
int boundaryLevelAdjust = 0);
|
||||
|
||||
float boundaryDistanceForRenderLevel(unsigned int renderLevel, float voxelSizeScale);
|
||||
|
||||
float getAccuracyAngle(float octreeSizeScale, int boundaryLevelAdjust);
|
||||
|
||||
#endif // hifi_OctreeUtils_h
|
|
@ -28,14 +28,14 @@ class PickRay;
|
|||
/// Interface provided by Application to other objects that need access to the current view state details
|
||||
class AbstractViewStateInterface {
|
||||
public:
|
||||
/// gets the current view frustum for rendering the view state
|
||||
virtual ViewFrustum* getCurrentViewFrustum() = 0;
|
||||
/// copies the current view frustum for rendering the view state
|
||||
virtual void copyCurrentViewFrustum(ViewFrustum& viewOut) const = 0;
|
||||
|
||||
/// gets the shadow view frustum for rendering the view state
|
||||
virtual ViewFrustum* getShadowViewFrustum() = 0;
|
||||
/// copies the shadow view frustum for rendering the view state
|
||||
virtual void copyShadowViewFrustum(ViewFrustum& viewOut) const = 0;
|
||||
|
||||
virtual QThread* getMainThread() = 0;
|
||||
|
||||
|
||||
virtual PickRay computePickRay(float x, float y) const = 0;
|
||||
|
||||
virtual glm::vec3 getAvatarPosition() const = 0;
|
||||
|
|
|
@ -284,7 +284,7 @@ void AmbientOcclusionEffect::updateGaussianDistribution() {
|
|||
|
||||
void AmbientOcclusionEffect::run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext) {
|
||||
assert(renderContext->args);
|
||||
assert(renderContext->args->_viewFrustum);
|
||||
assert(renderContext->args->hasViewFrustum());
|
||||
|
||||
RenderArgs* args = renderContext->args;
|
||||
|
||||
|
@ -309,7 +309,7 @@ void AmbientOcclusionEffect::run(const render::SceneContextPointer& sceneContext
|
|||
auto resolutionLevel = getResolutionLevel();
|
||||
|
||||
// Update the depth info with near and far (same for stereo)
|
||||
setDepthInfo(args->_viewFrustum->getNearClip(), args->_viewFrustum->getFarClip());
|
||||
setDepthInfo(args->getViewFrustum().getNearClip(), args->getViewFrustum().getFarClip());
|
||||
|
||||
_frameTransformBuffer.edit<FrameTransform>().pixelInfo = args->_viewport;
|
||||
//_parametersBuffer.edit<Parameters>()._ditheringInfo.y += 0.25f;
|
||||
|
@ -319,7 +319,7 @@ void AmbientOcclusionEffect::run(const render::SceneContextPointer& sceneContext
|
|||
if (!isStereo) {
|
||||
// Eval the mono projection
|
||||
mat4 monoProjMat;
|
||||
args->_viewFrustum->evalProjectionMatrix(monoProjMat);
|
||||
args->getViewFrustum().evalProjectionMatrix(monoProjMat);
|
||||
_frameTransformBuffer.edit<FrameTransform>().projection[0] = monoProjMat;
|
||||
_frameTransformBuffer.edit<FrameTransform>().stereoInfo = glm::vec4(0.0f, (float)args->_viewport.z, 0.0f, 0.0f);
|
||||
|
||||
|
@ -365,7 +365,7 @@ void AmbientOcclusionEffect::run(const render::SceneContextPointer& sceneContext
|
|||
|
||||
// Pyramid pass
|
||||
batch.setFramebuffer(pyramidFBO);
|
||||
batch.clearColorFramebuffer(gpu::Framebuffer::BUFFER_COLOR0, glm::vec4(args->_viewFrustum->getFarClip(), 0.0f, 0.0f, 0.0f));
|
||||
batch.clearColorFramebuffer(gpu::Framebuffer::BUFFER_COLOR0, glm::vec4(args->getViewFrustum().getFarClip(), 0.0f, 0.0f, 0.0f));
|
||||
batch.setPipeline(pyramidPipeline);
|
||||
batch.setResourceTexture(AmbientOcclusionEffect_DepthMapSlot, depthBuffer);
|
||||
batch.draw(gpu::TRIANGLE_STRIP, 4);
|
||||
|
|
|
@ -94,7 +94,7 @@ const gpu::PipelinePointer& Antialiasing::getBlendPipeline() {
|
|||
|
||||
void Antialiasing::run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext) {
|
||||
assert(renderContext->args);
|
||||
assert(renderContext->args->_viewFrustum);
|
||||
assert(renderContext->args->hasViewFrustum());
|
||||
|
||||
RenderArgs* args = renderContext->args;
|
||||
|
||||
|
@ -118,8 +118,8 @@ void Antialiasing::run(const render::SceneContextPointer& sceneContext, const re
|
|||
|
||||
glm::mat4 projMat;
|
||||
Transform viewMat;
|
||||
args->_viewFrustum->evalProjectionMatrix(projMat);
|
||||
args->_viewFrustum->evalViewTransform(viewMat);
|
||||
args->getViewFrustum().evalProjectionMatrix(projMat);
|
||||
args->getViewFrustum().evalViewTransform(viewMat);
|
||||
batch.setProjectionTransform(projMat);
|
||||
batch.setViewTransform(viewMat);
|
||||
batch.setModelTransform(Transform());
|
||||
|
@ -134,7 +134,7 @@ void Antialiasing::run(const render::SceneContextPointer& sceneContext, const re
|
|||
float left, right, bottom, top, nearVal, farVal;
|
||||
glm::vec4 nearClipPlane, farClipPlane;
|
||||
|
||||
args->_viewFrustum->computeOffAxisFrustum(left, right, bottom, top, nearVal, farVal, nearClipPlane, farClipPlane);
|
||||
args->getViewFrustum().computeOffAxisFrustum(left, right, bottom, top, nearVal, farVal, nearClipPlane, farClipPlane);
|
||||
|
||||
// float depthScale = (farVal - nearVal) / farVal;
|
||||
// float nearScale = -1.0f / nearVal;
|
||||
|
|
|
@ -275,7 +275,7 @@ void DebugDeferredBuffer::configure(const Config& config) {
|
|||
|
||||
void DebugDeferredBuffer::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) {
|
||||
assert(renderContext->args);
|
||||
assert(renderContext->args->_viewFrustum);
|
||||
assert(renderContext->args->hasViewFrustum());
|
||||
RenderArgs* args = renderContext->args;
|
||||
|
||||
gpu::doInBatch(args->_context, [&](gpu::Batch& batch) {
|
||||
|
@ -283,20 +283,20 @@ void DebugDeferredBuffer::run(const SceneContextPointer& sceneContext, const Ren
|
|||
const auto framebufferCache = DependencyManager::get<FramebufferCache>();
|
||||
const auto textureCache = DependencyManager::get<TextureCache>();
|
||||
const auto& lightStage = DependencyManager::get<DeferredLightingEffect>()->getLightStage();
|
||||
|
||||
|
||||
glm::mat4 projMat;
|
||||
Transform viewMat;
|
||||
args->_viewFrustum->evalProjectionMatrix(projMat);
|
||||
args->_viewFrustum->evalViewTransform(viewMat);
|
||||
args->getViewFrustum().evalProjectionMatrix(projMat);
|
||||
args->getViewFrustum().evalViewTransform(viewMat);
|
||||
batch.setProjectionTransform(projMat);
|
||||
batch.setViewTransform(viewMat);
|
||||
batch.setModelTransform(Transform());
|
||||
|
||||
// TODO REMOVE: Temporary until UI
|
||||
auto first = _customPipelines.begin()->first;
|
||||
|
||||
|
||||
batch.setPipeline(getPipeline(_mode, first));
|
||||
|
||||
|
||||
batch.setResourceTexture(Albedo, framebufferCache->getDeferredColorTexture());
|
||||
batch.setResourceTexture(Normal, framebufferCache->getDeferredNormalTexture());
|
||||
batch.setResourceTexture(Specular, framebufferCache->getDeferredSpecularTexture());
|
||||
|
|
|
@ -218,15 +218,15 @@ void DeferredLightingEffect::render(const render::RenderContextPointer& renderCo
|
|||
float tHeight = args->_viewport.w / (float)framebufferSize.height();
|
||||
|
||||
// The view frustum is the mono frustum base
|
||||
auto viewFrustum = args->_viewFrustum;
|
||||
auto viewFrustum = args->getViewFrustum();
|
||||
|
||||
// Eval the mono projection
|
||||
mat4 monoProjMat;
|
||||
viewFrustum->evalProjectionMatrix(monoProjMat);
|
||||
viewFrustum.evalProjectionMatrix(monoProjMat);
|
||||
|
||||
// The mono view transform
|
||||
Transform monoViewTransform;
|
||||
viewFrustum->evalViewTransform(monoViewTransform);
|
||||
viewFrustum.evalViewTransform(monoViewTransform);
|
||||
|
||||
// THe mono view matrix coming from the mono view transform
|
||||
glm::mat4 monoViewMat;
|
||||
|
@ -296,8 +296,8 @@ void DeferredLightingEffect::render(const render::RenderContextPointer& renderCo
|
|||
fetchTexcoordRects[0] = glm::vec4(sMin, tMin, sWidth, tHeight);
|
||||
}
|
||||
|
||||
auto eyePoint = viewFrustum->getPosition();
|
||||
float nearRadius = glm::distance(eyePoint, viewFrustum->getNearTopLeft());
|
||||
auto eyePoint = viewFrustum.getPosition();
|
||||
float nearRadius = glm::distance(eyePoint, viewFrustum.getNearTopLeft());
|
||||
|
||||
|
||||
for (int side = 0; side < numPasses; side++) {
|
||||
|
|
|
@ -62,19 +62,19 @@ const gpu::PipelinePointer& HitEffect::getHitEffectPipeline() {
|
|||
|
||||
void HitEffect::run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext) {
|
||||
assert(renderContext->args);
|
||||
assert(renderContext->args->_viewFrustum);
|
||||
assert(renderContext->args->hasViewFrustum());
|
||||
RenderArgs* args = renderContext->args;
|
||||
|
||||
gpu::doInBatch(args->_context, [&](gpu::Batch& batch) {
|
||||
|
||||
|
||||
glm::mat4 projMat;
|
||||
Transform viewMat;
|
||||
args->_viewFrustum->evalProjectionMatrix(projMat);
|
||||
args->_viewFrustum->evalViewTransform(viewMat);
|
||||
args->getViewFrustum().evalProjectionMatrix(projMat);
|
||||
args->getViewFrustum().evalViewTransform(viewMat);
|
||||
batch.setProjectionTransform(projMat);
|
||||
batch.setViewTransform(viewMat);
|
||||
batch.setModelTransform(Transform());
|
||||
|
||||
|
||||
batch.setPipeline(getHitEffectPipeline());
|
||||
|
||||
glm::vec4 color(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
|
|
|
@ -20,7 +20,7 @@ LightStage::Shadow::Shadow(model::LightPointer light) : _light{ light}, _frustum
|
|||
_schemaBuffer = std::make_shared<gpu::Buffer>(sizeof(Schema), (const gpu::Byte*) &schema);
|
||||
}
|
||||
|
||||
void LightStage::Shadow::setKeylightFrustum(ViewFrustum* viewFrustum, float nearDepth, float farDepth) {
|
||||
void LightStage::Shadow::setKeylightFrustum(const ViewFrustum& viewFrustum, float nearDepth, float farDepth) {
|
||||
assert(nearDepth < farDepth);
|
||||
|
||||
// Orient the keylight frustum
|
||||
|
@ -38,14 +38,13 @@ void LightStage::Shadow::setKeylightFrustum(ViewFrustum* viewFrustum, float near
|
|||
_frustum->setOrientation(orientation);
|
||||
|
||||
// Position the keylight frustum
|
||||
_frustum->setPosition(viewFrustum->getPosition() - (nearDepth + farDepth)*direction);
|
||||
_frustum->setPosition(viewFrustum.getPosition() - (nearDepth + farDepth)*direction);
|
||||
|
||||
const Transform view{ _frustum->getView()};
|
||||
const Transform viewInverse{ view.getInverseMatrix() };
|
||||
|
||||
viewFrustum->calculate();
|
||||
auto nearCorners = viewFrustum->getCorners(nearDepth);
|
||||
auto farCorners = viewFrustum->getCorners(farDepth);
|
||||
auto nearCorners = viewFrustum.getCorners(nearDepth);
|
||||
auto farCorners = viewFrustum.getCorners(farDepth);
|
||||
|
||||
vec3 min{ viewInverse.transform(nearCorners.bottomLeft) };
|
||||
vec3 max{ min };
|
||||
|
|
|
@ -28,7 +28,7 @@ public:
|
|||
|
||||
Shadow(model::LightPointer light);
|
||||
|
||||
void setKeylightFrustum(ViewFrustum* viewFrustum, float nearDepth, float farDepth);
|
||||
void setKeylightFrustum(const ViewFrustum& viewFrustum, float nearDepth, float farDepth);
|
||||
|
||||
const std::shared_ptr<ViewFrustum> getFrustum() const { return _frustum; }
|
||||
|
||||
|
|
|
@ -163,7 +163,7 @@ void RenderDeferredTask::run(const SceneContextPointer& sceneContext, const Rend
|
|||
|
||||
|
||||
// Is it possible that we render without a viewFrustum ?
|
||||
if (!(renderContext->args && renderContext->args->_viewFrustum)) {
|
||||
if (!(renderContext->args && renderContext->args->hasViewFrustum())) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -174,7 +174,7 @@ void RenderDeferredTask::run(const SceneContextPointer& sceneContext, const Rend
|
|||
|
||||
void DrawDeferred::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemBounds& inItems) {
|
||||
assert(renderContext->args);
|
||||
assert(renderContext->args->_viewFrustum);
|
||||
assert(renderContext->args->hasViewFrustum());
|
||||
|
||||
auto config = std::static_pointer_cast<Config>(renderContext->jobConfig);
|
||||
|
||||
|
@ -187,8 +187,8 @@ void DrawDeferred::run(const SceneContextPointer& sceneContext, const RenderCont
|
|||
|
||||
glm::mat4 projMat;
|
||||
Transform viewMat;
|
||||
args->_viewFrustum->evalProjectionMatrix(projMat);
|
||||
args->_viewFrustum->evalViewTransform(viewMat);
|
||||
args->getViewFrustum().evalProjectionMatrix(projMat);
|
||||
args->getViewFrustum().evalViewTransform(viewMat);
|
||||
|
||||
batch.setProjectionTransform(projMat);
|
||||
batch.setViewTransform(viewMat);
|
||||
|
@ -202,7 +202,7 @@ void DrawDeferred::run(const SceneContextPointer& sceneContext, const RenderCont
|
|||
|
||||
void DrawStateSortDeferred::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemBounds& inItems) {
|
||||
assert(renderContext->args);
|
||||
assert(renderContext->args->_viewFrustum);
|
||||
assert(renderContext->args->hasViewFrustum());
|
||||
|
||||
auto config = std::static_pointer_cast<Config>(renderContext->jobConfig);
|
||||
|
||||
|
@ -215,8 +215,8 @@ void DrawStateSortDeferred::run(const SceneContextPointer& sceneContext, const R
|
|||
|
||||
glm::mat4 projMat;
|
||||
Transform viewMat;
|
||||
args->_viewFrustum->evalProjectionMatrix(projMat);
|
||||
args->_viewFrustum->evalViewTransform(viewMat);
|
||||
args->getViewFrustum().evalProjectionMatrix(projMat);
|
||||
args->getViewFrustum().evalViewTransform(viewMat);
|
||||
|
||||
batch.setProjectionTransform(projMat);
|
||||
batch.setViewTransform(viewMat);
|
||||
|
@ -240,7 +240,7 @@ DrawOverlay3D::DrawOverlay3D(bool opaque) :
|
|||
|
||||
void DrawOverlay3D::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const render::ItemBounds& inItems) {
|
||||
assert(renderContext->args);
|
||||
assert(renderContext->args->_viewFrustum);
|
||||
assert(renderContext->args->hasViewFrustum());
|
||||
|
||||
auto config = std::static_pointer_cast<Config>(renderContext->jobConfig);
|
||||
|
||||
|
@ -268,8 +268,8 @@ void DrawOverlay3D::run(const SceneContextPointer& sceneContext, const RenderCon
|
|||
|
||||
glm::mat4 projMat;
|
||||
Transform viewMat;
|
||||
args->_viewFrustum->evalProjectionMatrix(projMat);
|
||||
args->_viewFrustum->evalViewTransform(viewMat);
|
||||
args->getViewFrustum().evalProjectionMatrix(projMat);
|
||||
args->getViewFrustum().evalViewTransform(viewMat);
|
||||
|
||||
batch.setProjectionTransform(projMat);
|
||||
batch.setViewTransform(viewMat);
|
||||
|
@ -290,7 +290,7 @@ const gpu::PipelinePointer& DrawStencilDeferred::getOpaquePipeline() {
|
|||
|
||||
void DrawStencilDeferred::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) {
|
||||
assert(renderContext->args);
|
||||
assert(renderContext->args->_viewFrustum);
|
||||
assert(renderContext->args->hasViewFrustum());
|
||||
|
||||
// from the touched pixel generate the stencil buffer
|
||||
RenderArgs* args = renderContext->args;
|
||||
|
@ -316,7 +316,7 @@ void DrawStencilDeferred::run(const SceneContextPointer& sceneContext, const Ren
|
|||
|
||||
void DrawBackgroundDeferred::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemBounds& inItems) {
|
||||
assert(renderContext->args);
|
||||
assert(renderContext->args->_viewFrustum);
|
||||
assert(renderContext->args->hasViewFrustum());
|
||||
|
||||
RenderArgs* args = renderContext->args;
|
||||
doInBatch(args->_context, [&](gpu::Batch& batch) {
|
||||
|
@ -334,8 +334,8 @@ void DrawBackgroundDeferred::run(const SceneContextPointer& sceneContext, const
|
|||
|
||||
glm::mat4 projMat;
|
||||
Transform viewMat;
|
||||
args->_viewFrustum->evalProjectionMatrix(projMat);
|
||||
args->_viewFrustum->evalViewTransform(viewMat);
|
||||
args->getViewFrustum().evalProjectionMatrix(projMat);
|
||||
args->getViewFrustum().evalViewTransform(viewMat);
|
||||
|
||||
batch.setProjectionTransform(projMat);
|
||||
batch.setViewTransform(viewMat);
|
||||
|
|
|
@ -34,7 +34,7 @@ using namespace render;
|
|||
void RenderShadowMap::run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext,
|
||||
const render::ShapeBounds& inShapes) {
|
||||
assert(renderContext->args);
|
||||
assert(renderContext->args->_viewFrustum);
|
||||
assert(renderContext->args->hasViewFrustum());
|
||||
|
||||
const auto& lightStage = DependencyManager::get<DeferredLightingEffect>()->getLightStage();
|
||||
const auto globalLight = lightStage.lights[0];
|
||||
|
@ -146,16 +146,15 @@ void RenderShadowTask::run(const SceneContextPointer& sceneContext, const render
|
|||
}
|
||||
|
||||
// Cache old render args
|
||||
ViewFrustum* viewFrustum = args->_viewFrustum;
|
||||
RenderArgs::RenderMode mode = args->_renderMode;
|
||||
|
||||
auto nearClip = viewFrustum->getNearClip();
|
||||
auto nearClip = args->getViewFrustum().getNearClip();
|
||||
float nearDepth = -args->_boomOffset.z;
|
||||
const int SHADOW_FAR_DEPTH = 20;
|
||||
globalLight->shadow.setKeylightFrustum(viewFrustum, nearDepth, nearClip + SHADOW_FAR_DEPTH);
|
||||
globalLight->shadow.setKeylightFrustum(args->getViewFrustum(), nearDepth, nearClip + SHADOW_FAR_DEPTH);
|
||||
|
||||
// Set the keylight render args
|
||||
args->_viewFrustum = globalLight->shadow.getFrustum().get();
|
||||
args->pushViewFrustum(*(globalLight->shadow.getFrustum()));
|
||||
args->_renderMode = RenderArgs::SHADOW_RENDER_MODE;
|
||||
|
||||
// TODO: Allow runtime manipulation of culling ShouldRenderFunctor
|
||||
|
@ -165,6 +164,6 @@ void RenderShadowTask::run(const SceneContextPointer& sceneContext, const render
|
|||
}
|
||||
|
||||
// Reset the render args
|
||||
args->_viewFrustum = viewFrustum;
|
||||
args->popViewFrustum();
|
||||
args->_renderMode = mode;
|
||||
};
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include <algorithm>
|
||||
#include <assert.h>
|
||||
|
||||
#include <OctreeUtils.h>
|
||||
#include <PerfStat.h>
|
||||
#include <ViewFrustum.h>
|
||||
#include <gpu/Context.h>
|
||||
|
@ -23,10 +24,10 @@ using namespace render;
|
|||
void render::cullItems(const RenderContextPointer& renderContext, const CullFunctor& cullFunctor, RenderDetails::Item& details,
|
||||
const ItemBounds& inItems, ItemBounds& outItems) {
|
||||
assert(renderContext->args);
|
||||
assert(renderContext->args->_viewFrustum);
|
||||
assert(renderContext->args->hasViewFrustum());
|
||||
|
||||
RenderArgs* args = renderContext->args;
|
||||
ViewFrustum* frustum = args->_viewFrustum;
|
||||
const ViewFrustum& frustum = args->getViewFrustum();
|
||||
|
||||
details._considered += (int)inItems.size();
|
||||
|
||||
|
@ -42,7 +43,7 @@ void render::cullItems(const RenderContextPointer& renderContext, const CullFunc
|
|||
bool inView;
|
||||
{
|
||||
PerformanceTimer perfTimer("boxIntersectsFrustum");
|
||||
inView = frustum->boxIntersectsFrustum(item.bound);
|
||||
inView = frustum.boxIntersectsFrustum(item.bound);
|
||||
}
|
||||
if (inView) {
|
||||
bool bigEnoughToRender;
|
||||
|
@ -64,7 +65,7 @@ void render::cullItems(const RenderContextPointer& renderContext, const CullFunc
|
|||
|
||||
void FetchNonspatialItems::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, ItemBounds& outItems) {
|
||||
assert(renderContext->args);
|
||||
assert(renderContext->args->_viewFrustum);
|
||||
assert(renderContext->args->hasViewFrustum());
|
||||
auto& scene = sceneContext->_scene;
|
||||
|
||||
outItems.clear();
|
||||
|
@ -85,7 +86,7 @@ void FetchSpatialTree::configure(const Config& config) {
|
|||
|
||||
void FetchSpatialTree::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, ItemSpatialTree::ItemSelection& outSelection) {
|
||||
assert(renderContext->args);
|
||||
assert(renderContext->args->_viewFrustum);
|
||||
assert(renderContext->args->hasViewFrustum());
|
||||
RenderArgs* args = renderContext->args;
|
||||
auto& scene = sceneContext->_scene;
|
||||
|
||||
|
@ -93,22 +94,18 @@ void FetchSpatialTree::run(const SceneContextPointer& sceneContext, const Render
|
|||
outSelection.clear();
|
||||
|
||||
// Eventually use a frozen frustum
|
||||
auto queryFrustum = *args->_viewFrustum;
|
||||
auto queryFrustum = args->getViewFrustum();
|
||||
if (_freezeFrustum) {
|
||||
if (_justFrozeFrustum) {
|
||||
_justFrozeFrustum = false;
|
||||
_frozenFrutstum = *args->_viewFrustum;
|
||||
_frozenFrutstum = args->getViewFrustum();
|
||||
}
|
||||
queryFrustum = _frozenFrutstum;
|
||||
}
|
||||
|
||||
// Octree selection!
|
||||
|
||||
float angle = glm::degrees(queryFrustum.getAccuracyAngle(args->_sizeScale, args->_boundaryLevelAdjust));
|
||||
|
||||
|
||||
float angle = glm::degrees(getAccuracyAngle(args->_sizeScale, args->_boundaryLevelAdjust));
|
||||
scene->getSpatialTree().selectCellItems(outSelection, _filter, queryFrustum, angle);
|
||||
|
||||
}
|
||||
|
||||
void CullSpatialSelection::configure(const Config& config) {
|
||||
|
@ -120,7 +117,7 @@ void CullSpatialSelection::configure(const Config& config) {
|
|||
void CullSpatialSelection::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext,
|
||||
const ItemSpatialTree::ItemSelection& inSelection, ItemBounds& outItems) {
|
||||
assert(renderContext->args);
|
||||
assert(renderContext->args->_viewFrustum);
|
||||
assert(renderContext->args->hasViewFrustum());
|
||||
RenderArgs* args = renderContext->args;
|
||||
auto& scene = sceneContext->_scene;
|
||||
|
||||
|
@ -128,13 +125,12 @@ void CullSpatialSelection::run(const SceneContextPointer& sceneContext, const Re
|
|||
details._considered += (int)inSelection.numItems();
|
||||
|
||||
// Eventually use a frozen frustum
|
||||
auto argFrustum = args->_viewFrustum;
|
||||
if (_freezeFrustum) {
|
||||
if (_justFrozeFrustum) {
|
||||
_justFrozeFrustum = false;
|
||||
_frozenFrutstum = *args->_viewFrustum;
|
||||
_frozenFrutstum = args->getViewFrustum();
|
||||
}
|
||||
args->_viewFrustum = &_frozenFrutstum; // replace the true view frustum by the frozen one
|
||||
args->pushViewFrustum(_frozenFrutstum); // replace the true view frustum by the frozen one
|
||||
}
|
||||
|
||||
// Culling Frustum / solidAngle test helper class
|
||||
|
@ -151,8 +147,8 @@ void CullSpatialSelection::run(const SceneContextPointer& sceneContext, const Re
|
|||
_renderDetails(renderDetails)
|
||||
{
|
||||
// FIXME: Keep this code here even though we don't use it yet
|
||||
/*_eyePos = _args->_viewFrustum->getPosition();
|
||||
float a = glm::degrees(_args->_viewFrustum->getAccuracyAngle(_args->_sizeScale, _args->_boundaryLevelAdjust));
|
||||
/*_eyePos = _args->getViewFrustum().getPosition();
|
||||
float a = glm::degrees(Octree::getAccuracyAngle(_args->_sizeScale, _args->_boundaryLevelAdjust));
|
||||
auto angle = std::min(glm::radians(45.0f), a); // no worse than 45 degrees
|
||||
angle = std::max(glm::radians(1.0f / 60.0f), a); // no better than 1 minute of degree
|
||||
auto tanAlpha = tan(angle);
|
||||
|
@ -161,7 +157,7 @@ void CullSpatialSelection::run(const SceneContextPointer& sceneContext, const Re
|
|||
}
|
||||
|
||||
bool frustumTest(const AABox& bound) {
|
||||
if (!_args->_viewFrustum->boxIntersectsFrustum(bound)) {
|
||||
if (!_args->getViewFrustum().boxIntersectsFrustum(bound)) {
|
||||
_renderDetails._outOfView++;
|
||||
return false;
|
||||
}
|
||||
|
@ -305,7 +301,7 @@ void CullSpatialSelection::run(const SceneContextPointer& sceneContext, const Re
|
|||
|
||||
// Restore frustum if using the frozen one:
|
||||
if (_freezeFrustum) {
|
||||
args->_viewFrustum = argFrustum;
|
||||
args->popViewFrustum();
|
||||
}
|
||||
|
||||
std::static_pointer_cast<Config>(renderContext->jobConfig)->numItems = (int)outItems.size();
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include <algorithm>
|
||||
#include <assert.h>
|
||||
|
||||
#include <OctreeUtils.h>
|
||||
#include <PerfStat.h>
|
||||
#include <RenderArgs.h>
|
||||
|
||||
|
@ -86,7 +87,7 @@ void DrawSceneOctree::configure(const Config& config) {
|
|||
void DrawSceneOctree::run(const SceneContextPointer& sceneContext,
|
||||
const RenderContextPointer& renderContext, const ItemSpatialTree::ItemSelection& inSelection) {
|
||||
assert(renderContext->args);
|
||||
assert(renderContext->args->_viewFrustum);
|
||||
assert(renderContext->args->hasViewFrustum());
|
||||
RenderArgs* args = renderContext->args;
|
||||
auto& scene = sceneContext->_scene;
|
||||
|
||||
|
@ -97,8 +98,8 @@ void DrawSceneOctree::run(const SceneContextPointer& sceneContext,
|
|||
gpu::doInBatch(args->_context, [&](gpu::Batch& batch) {
|
||||
glm::mat4 projMat;
|
||||
Transform viewMat;
|
||||
args->_viewFrustum->evalProjectionMatrix(projMat);
|
||||
args->_viewFrustum->evalViewTransform(viewMat);
|
||||
args->getViewFrustum().evalProjectionMatrix(projMat);
|
||||
args->getViewFrustum().evalViewTransform(viewMat);
|
||||
batch.setViewportTransform(args->_viewport);
|
||||
|
||||
batch.setProjectionTransform(projMat);
|
||||
|
@ -148,7 +149,7 @@ void DrawSceneOctree::run(const SceneContextPointer& sceneContext,
|
|||
}
|
||||
// Draw the LOD Reticle
|
||||
{
|
||||
float angle = glm::degrees(args->_viewFrustum->getAccuracyAngle(args->_sizeScale, args->_boundaryLevelAdjust));
|
||||
float angle = glm::degrees(getAccuracyAngle(args->_sizeScale, args->_boundaryLevelAdjust));
|
||||
Transform crosshairModel;
|
||||
crosshairModel.setTranslation(glm::vec3(0.0, 0.0, -1000.0));
|
||||
crosshairModel.setScale(1000.0 * tan(glm::radians(angle))); // Scaling at the actual tan of the lod angle => Multiplied by TWO
|
||||
|
@ -198,15 +199,15 @@ void DrawItemSelection::configure(const Config& config) {
|
|||
void DrawItemSelection::run(const SceneContextPointer& sceneContext,
|
||||
const RenderContextPointer& renderContext, const ItemSpatialTree::ItemSelection& inSelection) {
|
||||
assert(renderContext->args);
|
||||
assert(renderContext->args->_viewFrustum);
|
||||
assert(renderContext->args->hasViewFrustum());
|
||||
RenderArgs* args = renderContext->args;
|
||||
auto& scene = sceneContext->_scene;
|
||||
|
||||
gpu::doInBatch(args->_context, [&](gpu::Batch& batch) {
|
||||
glm::mat4 projMat;
|
||||
Transform viewMat;
|
||||
args->_viewFrustum->evalProjectionMatrix(projMat);
|
||||
args->_viewFrustum->evalViewTransform(viewMat);
|
||||
args->getViewFrustum().evalProjectionMatrix(projMat);
|
||||
args->getViewFrustum().evalViewTransform(viewMat);
|
||||
batch.setViewportTransform(args->_viewport);
|
||||
|
||||
batch.setProjectionTransform(projMat);
|
||||
|
|
|
@ -107,7 +107,7 @@ void DrawStatus::run(const SceneContextPointer& sceneContext,
|
|||
const RenderContextPointer& renderContext,
|
||||
const ItemBounds& inItems) {
|
||||
assert(renderContext->args);
|
||||
assert(renderContext->args->_viewFrustum);
|
||||
assert(renderContext->args->hasViewFrustum());
|
||||
RenderArgs* args = renderContext->args;
|
||||
auto& scene = sceneContext->_scene;
|
||||
const int NUM_STATUS_VEC4_PER_ITEM = 2;
|
||||
|
@ -183,8 +183,8 @@ void DrawStatus::run(const SceneContextPointer& sceneContext,
|
|||
gpu::doInBatch(args->_context, [&](gpu::Batch& batch) {
|
||||
glm::mat4 projMat;
|
||||
Transform viewMat;
|
||||
args->_viewFrustum->evalProjectionMatrix(projMat);
|
||||
args->_viewFrustum->evalViewTransform(viewMat);
|
||||
args->getViewFrustum().evalProjectionMatrix(projMat);
|
||||
args->getViewFrustum().evalViewTransform(viewMat);
|
||||
batch.setViewportTransform(args->_viewport);
|
||||
|
||||
batch.setProjectionTransform(projMat);
|
||||
|
|
|
@ -120,7 +120,7 @@ void render::renderStateSortShapes(const SceneContextPointer& sceneContext, cons
|
|||
|
||||
void DrawLight::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemBounds& inLights) {
|
||||
assert(renderContext->args);
|
||||
assert(renderContext->args->_viewFrustum);
|
||||
assert(renderContext->args->hasViewFrustum());
|
||||
RenderArgs* args = renderContext->args;
|
||||
|
||||
// render lights
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
//
|
||||
// CullTask.cpp
|
||||
// SortTask.cpp
|
||||
// render/src/render
|
||||
//
|
||||
// Created by Sam Gateau on 2/2/16.
|
||||
|
@ -42,7 +42,7 @@ struct BackToFrontSort {
|
|||
|
||||
void render::depthSortItems(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, bool frontToBack, const ItemBounds& inItems, ItemBounds& outItems) {
|
||||
assert(renderContext->args);
|
||||
assert(renderContext->args->_viewFrustum);
|
||||
assert(renderContext->args->hasViewFrustum());
|
||||
|
||||
auto& scene = sceneContext->_scene;
|
||||
RenderArgs* args = renderContext->args;
|
||||
|
@ -60,7 +60,7 @@ void render::depthSortItems(const SceneContextPointer& sceneContext, const Rende
|
|||
for (auto itemDetails : inItems) {
|
||||
auto item = scene->getItem(itemDetails.id);
|
||||
auto bound = itemDetails.bound; // item.getBound();
|
||||
float distance = args->_viewFrustum->distanceToCamera(bound.calcCenter());
|
||||
float distance = args->getViewFrustum().distanceToCamera(bound.calcCenter());
|
||||
|
||||
itemBoundSorts.emplace_back(ItemBoundSort(distance, distance, distance, itemDetails.id, bound));
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
//
|
||||
// OctreeProjectedPolygon.cpp
|
||||
// libraries/octree/src
|
||||
// CubeProjectedPolygon.cpp
|
||||
// libraries/shared/src
|
||||
//
|
||||
// Created by Brad Hefta-Gaub on 06/11/13.
|
||||
// Copyright 2013 High Fidelity, Inc.
|
||||
|
@ -15,50 +15,50 @@
|
|||
|
||||
#include "GeometryUtil.h"
|
||||
#include "SharedUtil.h"
|
||||
#include "OctreeLogging.h"
|
||||
#include "OctreeProjectedPolygon.h"
|
||||
#include "SharedLogging.h"
|
||||
#include "CubeProjectedPolygon.h"
|
||||
|
||||
|
||||
glm::vec2 BoundingBox::getVertex(int vertexNumber) const {
|
||||
glm::vec2 BoundingRectangle::getVertex(int vertexNumber) const {
|
||||
switch (vertexNumber) {
|
||||
case BoundingBox::BOTTOM_LEFT:
|
||||
case BoundingRectangle::BOTTOM_LEFT:
|
||||
return corner;
|
||||
case BoundingBox::TOP_LEFT:
|
||||
case BoundingRectangle::TOP_LEFT:
|
||||
return glm::vec2(corner.x, corner.y + size.y);
|
||||
case BoundingBox::BOTTOM_RIGHT:
|
||||
case BoundingRectangle::BOTTOM_RIGHT:
|
||||
return glm::vec2(corner.x + size.x, corner.y);
|
||||
case BoundingBox::TOP_RIGHT:
|
||||
case BoundingRectangle::TOP_RIGHT:
|
||||
return corner + size;
|
||||
}
|
||||
assert(false); // not allowed
|
||||
return glm::vec2(0,0);
|
||||
}
|
||||
|
||||
BoundingBox BoundingBox::topHalf() const {
|
||||
BoundingRectangle BoundingRectangle::topHalf() const {
|
||||
float halfY = size.y/2.0f;
|
||||
BoundingBox result(glm::vec2(corner.x,corner.y + halfY), glm::vec2(size.x, halfY));
|
||||
BoundingRectangle result(glm::vec2(corner.x,corner.y + halfY), glm::vec2(size.x, halfY));
|
||||
return result;
|
||||
}
|
||||
|
||||
BoundingBox BoundingBox::bottomHalf() const {
|
||||
BoundingRectangle BoundingRectangle::bottomHalf() const {
|
||||
float halfY = size.y/2.0f;
|
||||
BoundingBox result(corner, glm::vec2(size.x, halfY));
|
||||
BoundingRectangle result(corner, glm::vec2(size.x, halfY));
|
||||
return result;
|
||||
}
|
||||
|
||||
BoundingBox BoundingBox::leftHalf() const {
|
||||
BoundingRectangle BoundingRectangle::leftHalf() const {
|
||||
float halfX = size.x/2.0f;
|
||||
BoundingBox result(corner, glm::vec2(halfX, size.y));
|
||||
BoundingRectangle result(corner, glm::vec2(halfX, size.y));
|
||||
return result;
|
||||
}
|
||||
|
||||
BoundingBox BoundingBox::rightHalf() const {
|
||||
BoundingRectangle BoundingRectangle::rightHalf() const {
|
||||
float halfX = size.x/2.0f;
|
||||
BoundingBox result(glm::vec2(corner.x + halfX , corner.y), glm::vec2(halfX, size.y));
|
||||
BoundingRectangle result(glm::vec2(corner.x + halfX , corner.y), glm::vec2(halfX, size.y));
|
||||
return result;
|
||||
}
|
||||
|
||||
bool BoundingBox::contains(const BoundingBox& box) const {
|
||||
bool BoundingRectangle::contains(const BoundingRectangle& box) const {
|
||||
return ( _set &&
|
||||
(box.corner.x >= corner.x) &&
|
||||
(box.corner.y >= corner.y) &&
|
||||
|
@ -67,7 +67,7 @@ bool BoundingBox::contains(const BoundingBox& box) const {
|
|||
);
|
||||
}
|
||||
|
||||
bool BoundingBox::contains(const glm::vec2& point) const {
|
||||
bool BoundingRectangle::contains(const glm::vec2& point) const {
|
||||
return ( _set &&
|
||||
(point.x > corner.x) &&
|
||||
(point.y > corner.y) &&
|
||||
|
@ -76,7 +76,7 @@ bool BoundingBox::contains(const glm::vec2& point) const {
|
|||
);
|
||||
}
|
||||
|
||||
void BoundingBox::explandToInclude(const BoundingBox& box) {
|
||||
void BoundingRectangle::explandToInclude(const BoundingRectangle& box) {
|
||||
if (!_set) {
|
||||
corner = box.corner;
|
||||
size = box.size;
|
||||
|
@ -94,20 +94,20 @@ void BoundingBox::explandToInclude(const BoundingBox& box) {
|
|||
}
|
||||
|
||||
|
||||
void BoundingBox::printDebugDetails(const char* label) const {
|
||||
qCDebug(octree, "%s _set=%s\n corner=%f,%f size=%f,%f\n bounds=[(%f,%f) to (%f,%f)]",
|
||||
(label ? label : "BoundingBox"),
|
||||
void BoundingRectangle::printDebugDetails(const char* label) const {
|
||||
qCDebug(shared, "%s _set=%s\n corner=%f,%f size=%f,%f\n bounds=[(%f,%f) to (%f,%f)]",
|
||||
(label ? label : "BoundingRectangle"),
|
||||
debug::valueOf(_set), (double)corner.x, (double)corner.y, (double)size.x, (double)size.y,
|
||||
(double)corner.x, (double)corner.y, (double)(corner.x+size.x), (double)(corner.y+size.y));
|
||||
}
|
||||
|
||||
|
||||
long OctreeProjectedPolygon::pointInside_calls = 0;
|
||||
long OctreeProjectedPolygon::occludes_calls = 0;
|
||||
long OctreeProjectedPolygon::intersects_calls = 0;
|
||||
long CubeProjectedPolygon::pointInside_calls = 0;
|
||||
long CubeProjectedPolygon::occludes_calls = 0;
|
||||
long CubeProjectedPolygon::intersects_calls = 0;
|
||||
|
||||
|
||||
OctreeProjectedPolygon::OctreeProjectedPolygon(const BoundingBox& box) :
|
||||
CubeProjectedPolygon::CubeProjectedPolygon(const BoundingRectangle& box) :
|
||||
_vertexCount(4),
|
||||
_maxX(-FLT_MAX), _maxY(-FLT_MAX), _minX(FLT_MAX), _minY(FLT_MAX),
|
||||
_distance(0)
|
||||
|
@ -118,7 +118,7 @@ OctreeProjectedPolygon::OctreeProjectedPolygon(const BoundingBox& box) :
|
|||
}
|
||||
|
||||
|
||||
void OctreeProjectedPolygon::setVertex(int vertex, const glm::vec2& point) {
|
||||
void CubeProjectedPolygon::setVertex(int vertex, const glm::vec2& point) {
|
||||
_vertices[vertex] = point;
|
||||
|
||||
// keep track of our bounding box
|
||||
|
@ -138,9 +138,9 @@ void OctreeProjectedPolygon::setVertex(int vertex, const glm::vec2& point) {
|
|||
}
|
||||
|
||||
// can be optimized with new pointInside()
|
||||
bool OctreeProjectedPolygon::occludes(const OctreeProjectedPolygon& occludee, bool checkAllInView) const {
|
||||
bool CubeProjectedPolygon::occludes(const CubeProjectedPolygon& occludee, bool checkAllInView) const {
|
||||
|
||||
OctreeProjectedPolygon::occludes_calls++;
|
||||
CubeProjectedPolygon::occludes_calls++;
|
||||
|
||||
// if we are completely out of view, then we definitely don't occlude!
|
||||
// if the occludee is completely out of view, then we also don't occlude it
|
||||
|
@ -197,12 +197,12 @@ bool OctreeProjectedPolygon::occludes(const OctreeProjectedPolygon& occludee, bo
|
|||
return false; // if we got this far, then we're not occluded
|
||||
}
|
||||
|
||||
bool OctreeProjectedPolygon::occludes(const BoundingBox& boxOccludee) const {
|
||||
OctreeProjectedPolygon testee(boxOccludee);
|
||||
bool CubeProjectedPolygon::occludes(const BoundingRectangle& boxOccludee) const {
|
||||
CubeProjectedPolygon testee(boxOccludee);
|
||||
return occludes(testee);
|
||||
}
|
||||
|
||||
bool OctreeProjectedPolygon::matches(const OctreeProjectedPolygon& testee) const {
|
||||
bool CubeProjectedPolygon::matches(const CubeProjectedPolygon& testee) const {
|
||||
if (testee.getVertexCount() != getVertexCount()) {
|
||||
return false;
|
||||
}
|
||||
|
@ -231,14 +231,14 @@ bool OctreeProjectedPolygon::matches(const OctreeProjectedPolygon& testee) const
|
|||
return true; // all of our vertices match, therefore we're the same
|
||||
}
|
||||
|
||||
bool OctreeProjectedPolygon::matches(const BoundingBox& box) const {
|
||||
OctreeProjectedPolygon testee(box);
|
||||
bool CubeProjectedPolygon::matches(const BoundingRectangle& box) const {
|
||||
CubeProjectedPolygon testee(box);
|
||||
return matches(testee);
|
||||
}
|
||||
|
||||
bool OctreeProjectedPolygon::pointInside(const glm::vec2& point, bool* matchesVertex) const {
|
||||
bool CubeProjectedPolygon::pointInside(const glm::vec2& point, bool* matchesVertex) const {
|
||||
|
||||
OctreeProjectedPolygon::pointInside_calls++;
|
||||
CubeProjectedPolygon::pointInside_calls++;
|
||||
|
||||
// first check the bounding boxes, the point must be fully within the boounding box of this polygon
|
||||
if ((point.x > getMaxX()) ||
|
||||
|
@ -264,23 +264,23 @@ bool OctreeProjectedPolygon::pointInside(const glm::vec2& point, bool* matchesVe
|
|||
return true;
|
||||
}
|
||||
|
||||
void OctreeProjectedPolygon::printDebugDetails() const {
|
||||
qCDebug(octree, "OctreeProjectedPolygon..."
|
||||
void CubeProjectedPolygon::printDebugDetails() const {
|
||||
qCDebug(shared, "CubeProjectedPolygon..."
|
||||
" minX=%f maxX=%f minY=%f maxY=%f", (double)getMinX(), (double)getMaxX(), (double)getMinY(), (double)getMaxY());
|
||||
qCDebug(octree, " vertex count=%d distance=%f", getVertexCount(), (double)getDistance());
|
||||
qCDebug(shared, " vertex count=%d distance=%f", getVertexCount(), (double)getDistance());
|
||||
for (int i = 0; i < getVertexCount(); i++) {
|
||||
glm::vec2 point = getVertex(i);
|
||||
qCDebug(octree, " vertex[%d] = %f, %f ", i, (double)point.x, (double)point.y);
|
||||
qCDebug(shared, " vertex[%d] = %f, %f ", i, (double)point.x, (double)point.y);
|
||||
}
|
||||
}
|
||||
|
||||
bool OctreeProjectedPolygon::intersects(const BoundingBox& box) const {
|
||||
OctreeProjectedPolygon testee(box);
|
||||
bool CubeProjectedPolygon::intersects(const BoundingRectangle& box) const {
|
||||
CubeProjectedPolygon testee(box);
|
||||
return intersects(testee);
|
||||
}
|
||||
|
||||
bool OctreeProjectedPolygon::intersects(const OctreeProjectedPolygon& testee) const {
|
||||
OctreeProjectedPolygon::intersects_calls++;
|
||||
bool CubeProjectedPolygon::intersects(const CubeProjectedPolygon& testee) const {
|
||||
CubeProjectedPolygon::intersects_calls++;
|
||||
return intersectsOnAxes(testee) && testee.intersectsOnAxes(*this);
|
||||
}
|
||||
|
||||
|
@ -294,7 +294,7 @@ bool OctreeProjectedPolygon::intersects(const OctreeProjectedPolygon& testee) co
|
|||
// Note: this only works on convex polygons
|
||||
//
|
||||
//
|
||||
bool OctreeProjectedPolygon::intersectsOnAxes(const OctreeProjectedPolygon& testee) const {
|
||||
bool CubeProjectedPolygon::intersectsOnAxes(const CubeProjectedPolygon& testee) const {
|
||||
|
||||
// consider each edge of this polygon as a potential separating axis
|
||||
for (int i = 0; i < getVertexCount(); i++) {
|
||||
|
@ -324,7 +324,7 @@ bool OctreeProjectedPolygon::intersectsOnAxes(const OctreeProjectedPolygon& test
|
|||
return true;
|
||||
}
|
||||
|
||||
bool OctreeProjectedPolygon::canMerge(const OctreeProjectedPolygon& that) const {
|
||||
bool CubeProjectedPolygon::canMerge(const CubeProjectedPolygon& that) const {
|
||||
|
||||
// RIGHT/NEAR
|
||||
// LEFT/NEAR
|
||||
|
@ -642,7 +642,7 @@ bool OctreeProjectedPolygon::canMerge(const OctreeProjectedPolygon& that) const
|
|||
}
|
||||
|
||||
|
||||
void OctreeProjectedPolygon::merge(const OctreeProjectedPolygon& that) {
|
||||
void CubeProjectedPolygon::merge(const CubeProjectedPolygon& that) {
|
||||
|
||||
// RIGHT/NEAR
|
||||
// LEFT/NEAR
|
|
@ -1,55 +1,55 @@
|
|||
//
|
||||
// OctreeProjectedPolygon.h
|
||||
// libraries/octree/src
|
||||
// CubeProjectedPolygon.h
|
||||
// libraries/shared/src
|
||||
//
|
||||
// Created by Brad Hefta-Gaub on 06/11/13.
|
||||
// Copyright 2013 High Fidelity, Inc.
|
||||
//
|
||||
// The projected shadow (on the 2D view plane) for a voxel
|
||||
// The projected shadow (on the 2D view plane) for a cube
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#ifndef hifi_OctreeProjectedPolygon_h
|
||||
#define hifi_OctreeProjectedPolygon_h
|
||||
#ifndef hifi_CubeProjectedPolygon_h
|
||||
#define hifi_CubeProjectedPolygon_h
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
// there's a max of 6 vertices of a project polygon, and a max of twice that when clipped to the screen
|
||||
const int MAX_PROJECTED_POLYGON_VERTEX_COUNT = 6;
|
||||
const int MAX_CLIPPED_PROJECTED_POLYGON_VERTEX_COUNT = MAX_PROJECTED_POLYGON_VERTEX_COUNT * 2;
|
||||
const int MAX_PROJECTED_POLYGON_VERTEX_COUNT = 6;
|
||||
const int MAX_CLIPPED_PROJECTED_POLYGON_VERTEX_COUNT = MAX_PROJECTED_POLYGON_VERTEX_COUNT * 2;
|
||||
typedef glm::vec2 ProjectedVertices[MAX_CLIPPED_PROJECTED_POLYGON_VERTEX_COUNT];
|
||||
|
||||
class BoundingBox {
|
||||
class BoundingRectangle {
|
||||
public:
|
||||
enum { BOTTOM_LEFT, BOTTOM_RIGHT, TOP_RIGHT, TOP_LEFT, VERTEX_COUNT };
|
||||
|
||||
BoundingBox(const glm::vec2 corner, const glm::vec2 size) : corner(corner), size(size), _set(true) {}
|
||||
BoundingBox() : _set(false) {}
|
||||
BoundingRectangle(const glm::vec2 corner, const glm::vec2 size) : corner(corner), size(size), _set(true) {}
|
||||
BoundingRectangle() : _set(false) {}
|
||||
glm::vec2 corner;
|
||||
glm::vec2 size;
|
||||
bool contains(const BoundingBox& box) const;
|
||||
bool contains(const BoundingRectangle& box) const;
|
||||
bool contains(const glm::vec2& point) const;
|
||||
bool pointInside(const glm::vec2& point) const { return contains(point); }
|
||||
|
||||
void explandToInclude(const BoundingBox& box);
|
||||
void explandToInclude(const BoundingRectangle& box);
|
||||
|
||||
float area() const { return size.x * size.y; }
|
||||
|
||||
int getVertexCount() const { return VERTEX_COUNT; }
|
||||
glm::vec2 getVertex(int vertexNumber) const;
|
||||
|
||||
BoundingBox topHalf() const;
|
||||
BoundingBox bottomHalf() const;
|
||||
BoundingBox leftHalf() const;
|
||||
BoundingBox rightHalf() const;
|
||||
BoundingRectangle topHalf() const;
|
||||
BoundingRectangle bottomHalf() const;
|
||||
BoundingRectangle leftHalf() const;
|
||||
BoundingRectangle rightHalf() const;
|
||||
|
||||
float getMaxX() const { return corner.x + size.x; }
|
||||
float getMaxY() const { return corner.y + size.y; }
|
||||
float getMinX() const { return corner.x; }
|
||||
float getMinY() const { return corner.y; }
|
||||
|
||||
|
||||
void printDebugDetails(const char* label=NULL) const;
|
||||
private:
|
||||
bool _set;
|
||||
|
@ -63,18 +63,18 @@ const int PROJECTION_NEAR = 16;
|
|||
const int PROJECTION_FAR = 32;
|
||||
const int PROJECTION_CLIPPED = 64;
|
||||
|
||||
class OctreeProjectedPolygon {
|
||||
class CubeProjectedPolygon {
|
||||
|
||||
public:
|
||||
OctreeProjectedPolygon(const BoundingBox& box);
|
||||
CubeProjectedPolygon(const BoundingRectangle& box);
|
||||
|
||||
OctreeProjectedPolygon(int vertexCount = 0) :
|
||||
_vertexCount(vertexCount),
|
||||
CubeProjectedPolygon(int vertexCount = 0) :
|
||||
_vertexCount(vertexCount),
|
||||
_maxX(-FLT_MAX), _maxY(-FLT_MAX), _minX(FLT_MAX), _minY(FLT_MAX),
|
||||
_distance(0)
|
||||
{ }
|
||||
|
||||
~OctreeProjectedPolygon() { }
|
||||
|
||||
~CubeProjectedPolygon() { }
|
||||
const ProjectedVertices& getVertices() const { return _vertices; }
|
||||
const glm::vec2& getVertex(int i) const { return _vertices[i]; }
|
||||
void setVertex(int vertex, const glm::vec2& point);
|
||||
|
@ -92,28 +92,28 @@ public:
|
|||
|
||||
|
||||
bool pointInside(const glm::vec2& point, bool* matchesVertex = NULL) const;
|
||||
bool occludes(const OctreeProjectedPolygon& occludee, bool checkAllInView = false) const;
|
||||
bool occludes(const BoundingBox& occludee) const;
|
||||
bool intersects(const OctreeProjectedPolygon& testee) const;
|
||||
bool intersects(const BoundingBox& box) const;
|
||||
bool matches(const OctreeProjectedPolygon& testee) const;
|
||||
bool matches(const BoundingBox& testee) const;
|
||||
bool intersectsOnAxes(const OctreeProjectedPolygon& testee) const;
|
||||
bool occludes(const CubeProjectedPolygon& occludee, bool checkAllInView = false) const;
|
||||
bool occludes(const BoundingRectangle& occludee) const;
|
||||
bool intersects(const CubeProjectedPolygon& testee) const;
|
||||
bool intersects(const BoundingRectangle& box) const;
|
||||
bool matches(const CubeProjectedPolygon& testee) const;
|
||||
bool matches(const BoundingRectangle& testee) const;
|
||||
bool intersectsOnAxes(const CubeProjectedPolygon& testee) const;
|
||||
|
||||
bool canMerge(const CubeProjectedPolygon& that) const;
|
||||
void merge(const CubeProjectedPolygon& that); // replaces vertices of this with new merged version
|
||||
|
||||
bool canMerge(const OctreeProjectedPolygon& that) const;
|
||||
void merge(const OctreeProjectedPolygon& that); // replaces vertices of this with new merged version
|
||||
|
||||
float getMaxX() const { return _maxX; }
|
||||
float getMaxY() const { return _maxY; }
|
||||
float getMinX() const { return _minX; }
|
||||
float getMinY() const { return _minY; }
|
||||
|
||||
BoundingBox getBoundingBox() const {
|
||||
return BoundingBox(glm::vec2(_minX,_minY), glm::vec2(_maxX - _minX, _maxY - _minY));
|
||||
|
||||
BoundingRectangle getBoundingBox() const {
|
||||
return BoundingRectangle(glm::vec2(_minX,_minY), glm::vec2(_maxX - _minX, _maxY - _minY));
|
||||
}
|
||||
|
||||
void printDebugDetails() const;
|
||||
|
||||
|
||||
static long pointInside_calls;
|
||||
static long occludes_calls;
|
||||
static long intersects_calls;
|
||||
|
@ -132,4 +132,4 @@ private:
|
|||
};
|
||||
|
||||
|
||||
#endif // hifi_OctreeProjectedPolygon_h
|
||||
#endif // hifi_CubeProjectedPolygon_h
|
|
@ -35,7 +35,7 @@ float PIDController::update(float measuredValue, float dt, bool resetAccumulator
|
|||
updateHistory(measuredValue, dt, error, accumulatedError, changeInError, p, i, d, computedValue);
|
||||
}
|
||||
Q_ASSERT(!glm::isnan(computedValue));
|
||||
|
||||
|
||||
// update state for next time
|
||||
_lastError = error;
|
||||
_lastAccumulation = accumulatedError;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
//
|
||||
// Plane.cpp
|
||||
// libraries/octree/src/
|
||||
// libraries/shared/src/
|
||||
//
|
||||
// Created by Brad Hefta-Gaub on 04/11/13.
|
||||
// Copyright 2013 High Fidelity, Inc.
|
||||
|
@ -13,12 +13,12 @@
|
|||
//
|
||||
|
||||
#include "Plane.h"
|
||||
#include "OctreeLogging.h"
|
||||
|
||||
|
||||
#include <QtCore/QDebug>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <QtCore/QDebug>
|
||||
|
||||
#include "SharedLogging.h"
|
||||
|
||||
|
||||
void Plane::set3Points(const glm::vec3 &v1, const glm::vec3 &v2, const glm::vec3 &v3) {
|
||||
glm::vec3 linev1v2, linev1v3;
|
||||
|
@ -65,7 +65,7 @@ float Plane::distance(const glm::vec3 &point) const {
|
|||
}
|
||||
|
||||
void Plane::print() const {
|
||||
qCDebug(octree, "Plane - point (x=%f y=%f z=%f) normal (x=%f y=%f z=%f) d=%f",
|
||||
qCDebug(shared, "Plane - point (x=%f y=%f z=%f) normal (x=%f y=%f z=%f) d=%f",
|
||||
(double)_point.x, (double)_point.y, (double)_point.z,
|
||||
(double)_normal.x, (double)_normal.y, (double)_normal.z, (double)_dCoefficient);
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
//
|
||||
// Plane.h
|
||||
// libraries/octree/src/
|
||||
// libraries/shared/src/
|
||||
//
|
||||
// Created by Brad Hefta-Gaub on 04/11/13.
|
||||
// Copyright 2013 High Fidelity, Inc.
|
||||
|
@ -20,7 +20,7 @@
|
|||
class Plane {
|
||||
public:
|
||||
Plane(const glm::vec3 &v1, const glm::vec3 &v2, const glm::vec3 &v3) { set3Points(v1,v2,v3); }
|
||||
Plane() : _normal(0,0,0), _point(0,0,0), _dCoefficient(0) {};
|
||||
Plane() : _normal(0.0f), _point(0.0f), _dCoefficient(0.0f) {};
|
||||
~Plane() {} ;
|
||||
|
||||
// methods for defining the plane
|
||||
|
@ -28,12 +28,13 @@ public:
|
|||
void setNormalAndPoint(const glm::vec3 &normal, const glm::vec3 &point);
|
||||
void setCoefficients(float a, float b, float c, float d);
|
||||
|
||||
// getters
|
||||
// getters
|
||||
const glm::vec3& getNormal() const { return _normal; };
|
||||
const glm::vec3& getPoint() const { return _point; };
|
||||
float getDCoefficient() const { return _dCoefficient; };
|
||||
|
||||
// utilities
|
||||
void invalidate() { _normal = glm::vec3(0.0f), _dCoefficient = 1.0e6f; } // distance() never less than 10^6
|
||||
float distance(const glm::vec3 &point) const;
|
||||
void print() const;
|
||||
|
||||
|
@ -44,4 +45,4 @@ private:
|
|||
};
|
||||
|
||||
|
||||
#endif // hifi_Plane_h
|
||||
#endif // hifi_Plane_h
|
|
@ -14,12 +14,15 @@
|
|||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include "GLMHelpers.h"
|
||||
#include <stack>
|
||||
|
||||
#include <GLMHelpers.h>
|
||||
#include <ViewFrustum.h>
|
||||
|
||||
|
||||
|
||||
class AABox;
|
||||
class OctreeRenderer;
|
||||
class ViewFrustum;
|
||||
|
||||
namespace gpu {
|
||||
class Batch;
|
||||
|
@ -39,21 +42,21 @@ public:
|
|||
SHADOW,
|
||||
OTHER
|
||||
};
|
||||
|
||||
|
||||
struct Item {
|
||||
int _considered = 0;
|
||||
int _outOfView = 0;
|
||||
int _tooSmall = 0;
|
||||
int _rendered = 0;
|
||||
};
|
||||
|
||||
|
||||
int _materialSwitches = 0;
|
||||
int _trianglesRendered = 0;
|
||||
|
||||
|
||||
Item _item;
|
||||
Item _shadow;
|
||||
Item _other;
|
||||
|
||||
|
||||
Item& edit(Type type) {
|
||||
switch (type) {
|
||||
case SHADOW:
|
||||
|
@ -77,7 +80,6 @@ public:
|
|||
|
||||
RenderArgs(std::shared_ptr<gpu::Context> context = nullptr,
|
||||
OctreeRenderer* renderer = nullptr,
|
||||
ViewFrustum* viewFrustum = nullptr,
|
||||
float sizeScale = 1.0f,
|
||||
int boundaryLevelAdjust = 0,
|
||||
RenderMode renderMode = DEFAULT_RENDER_MODE,
|
||||
|
@ -86,7 +88,6 @@ public:
|
|||
gpu::Batch* batch = nullptr) :
|
||||
_context(context),
|
||||
_renderer(renderer),
|
||||
_viewFrustum(viewFrustum),
|
||||
_sizeScale(sizeScale),
|
||||
_boundaryLevelAdjust(boundaryLevelAdjust),
|
||||
_renderMode(renderMode),
|
||||
|
@ -95,11 +96,22 @@ public:
|
|||
_batch(batch) {
|
||||
}
|
||||
|
||||
bool hasViewFrustum() const { return _viewFrustums.size() > 0; }
|
||||
void setViewFrustum(const ViewFrustum& viewFrustum) {
|
||||
while (_viewFrustums.size() > 0) {
|
||||
_viewFrustums.pop();
|
||||
}
|
||||
_viewFrustums.push(viewFrustum);
|
||||
}
|
||||
const ViewFrustum& getViewFrustum() const { assert(_viewFrustums.size() > 0); return _viewFrustums.top(); }
|
||||
void pushViewFrustum(const ViewFrustum& viewFrustum) { _viewFrustums.push(viewFrustum); }
|
||||
void popViewFrustum() { _viewFrustums.pop(); }
|
||||
|
||||
std::shared_ptr<gpu::Context> _context = nullptr;
|
||||
std::shared_ptr<gpu::Framebuffer> _blitFramebuffer = nullptr;
|
||||
std::shared_ptr<render::ShapePipeline> _pipeline = nullptr;
|
||||
OctreeRenderer* _renderer = nullptr;
|
||||
ViewFrustum* _viewFrustum = nullptr;
|
||||
std::stack<ViewFrustum> _viewFrustums;
|
||||
glm::ivec4 _viewport{ 0.0f, 0.0f, 1.0f, 1.0f };
|
||||
glm::vec3 _boomOffset{ 0.0f, 0.0f, 1.0f };
|
||||
float _sizeScale = 1.0f;
|
||||
|
@ -108,7 +120,7 @@ public:
|
|||
RenderSide _renderSide = MONO;
|
||||
DebugFlags _debugFlags = RENDER_DEBUG_NONE;
|
||||
gpu::Batch* _batch = nullptr;
|
||||
|
||||
|
||||
std::shared_ptr<gpu::Texture> _whiteTexture;
|
||||
|
||||
RenderDetails _details;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
//
|
||||
// ViewFrustum.cpp
|
||||
// libraries/octree/src
|
||||
// libraries/shared/src
|
||||
//
|
||||
// Created by Brad Hefta-Gaub on 04/11/13.
|
||||
// Copyright 2013 High Fidelity, Inc.
|
||||
|
@ -17,13 +17,13 @@
|
|||
#include <glm/gtx/vector_angle.hpp>
|
||||
#include <QtCore/QDebug>
|
||||
|
||||
#include <NumericalConstants.h>
|
||||
|
||||
#include "GeometryUtil.h"
|
||||
#include "GLMHelpers.h"
|
||||
#include "NumericalConstants.h"
|
||||
#include "SharedLogging.h"
|
||||
//#include "OctreeConstants.h"
|
||||
#include "ViewFrustum.h"
|
||||
#include "OctreeLogging.h"
|
||||
#include "OctreeConstants.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
@ -41,24 +41,24 @@ void ViewFrustum::setPosition(const glm::vec3& position) {
|
|||
}
|
||||
|
||||
// Order cooresponds to the order defined in the BoxVertex enum.
|
||||
static const glm::vec4 NDC_VALUES[8] = {
|
||||
glm::vec4(-1, -1, -1, 1),
|
||||
glm::vec4(1, -1, -1, 1),
|
||||
glm::vec4(1, 1, -1, 1),
|
||||
glm::vec4(-1, 1, -1, 1),
|
||||
glm::vec4(-1, -1, 1, 1),
|
||||
glm::vec4(1, -1, 1, 1),
|
||||
glm::vec4(1, 1, 1, 1),
|
||||
glm::vec4(-1, 1, 1, 1),
|
||||
static const glm::vec4 NDC_VALUES[NUM_FRUSTUM_CORNERS] = {
|
||||
glm::vec4(-1.0f, -1.0f, -1.0f, 1.0f),
|
||||
glm::vec4(1.0f, -1.0f, -1.0f, 1.0f),
|
||||
glm::vec4(1.0f, 1.0f, -1.0f, 1.0f),
|
||||
glm::vec4(-1.0f, 1.0f, -1.0f, 1.0f),
|
||||
glm::vec4(-1.0f, -1.0f, 1.0f, 1.0f),
|
||||
glm::vec4(1.0f, -1.0f, 1.0f, 1.0f),
|
||||
glm::vec4(1.0f, 1.0f, 1.0f, 1.0f),
|
||||
glm::vec4(-1.0f, 1.0f, 1.0f, 1.0f),
|
||||
};
|
||||
|
||||
void ViewFrustum::setProjection(const glm::mat4& projection) {
|
||||
_projection = projection;
|
||||
_inverseProjection = glm::inverse(projection);
|
||||
glm::mat4 inverseProjection = glm::inverse(projection);
|
||||
|
||||
// compute our dimensions the usual way
|
||||
for (int i = 0; i < 8; ++i) {
|
||||
_corners[i] = _inverseProjection * NDC_VALUES[i];
|
||||
for (int i = 0; i < NUM_FRUSTUM_CORNERS; ++i) {
|
||||
_corners[i] = inverseProjection * NDC_VALUES[i];
|
||||
_corners[i] /= _corners[i].w;
|
||||
}
|
||||
_nearClip = -_corners[BOTTOM_LEFT_NEAR].z;
|
||||
|
@ -66,12 +66,12 @@ void ViewFrustum::setProjection(const glm::mat4& projection) {
|
|||
_aspectRatio = (_corners[TOP_RIGHT_NEAR].x - _corners[BOTTOM_LEFT_NEAR].x) /
|
||||
(_corners[TOP_RIGHT_NEAR].y - _corners[BOTTOM_LEFT_NEAR].y);
|
||||
|
||||
glm::vec4 top = _inverseProjection * vec4(0, 1, -1, 1);
|
||||
glm::vec4 top = inverseProjection * vec4(0.0f, 1.0f, -1.0f, 1.0f);
|
||||
top /= top.w;
|
||||
_fieldOfView = abs(glm::degrees(2.0f * abs(glm::angle(vec3(0, 0, -1), glm::normalize(vec3(top))))));
|
||||
_fieldOfView = abs(glm::degrees(2.0f * abs(glm::angle(vec3(0.0f, 0.0f, -1.0f), glm::normalize(vec3(top))))));
|
||||
}
|
||||
|
||||
// ViewFrustum::calculateViewFrustum()
|
||||
// ViewFrustum::calculate()
|
||||
//
|
||||
// Description: this will calculate the view frustum bounds for a given position and direction
|
||||
//
|
||||
|
@ -84,7 +84,7 @@ void ViewFrustum::calculate() {
|
|||
// then transform them to world space
|
||||
glm::mat4 worldMatrix = glm::translate(_position) * glm::mat4(glm::mat3(_right, _up, -_direction));
|
||||
glm::vec4 v;
|
||||
for (int i = 0; i < 8; ++i) {
|
||||
for (int i = 0; i < NUM_FRUSTUM_CORNERS; ++i) {
|
||||
v = worldMatrix * _corners[i];
|
||||
v /= v.w;
|
||||
_cornersWorld[i] = glm::vec3(v);
|
||||
|
@ -133,7 +133,7 @@ const char* ViewFrustum::debugPlaneName (int plane) const {
|
|||
ViewFrustum::intersection ViewFrustum::calculateCubeFrustumIntersection(const AACube& cube) const {
|
||||
// only check against frustum
|
||||
ViewFrustum::intersection result = INSIDE;
|
||||
for(int i=0; i < 6; i++) {
|
||||
for(int i = 0; i < NUM_FRUSTUM_PLANES; i++) {
|
||||
const glm::vec3& normal = _planes[i].getNormal();
|
||||
// check distance to farthest cube point
|
||||
if ( _planes[i].distance(cube.getFarthestVertex(normal)) < 0.0f) {
|
||||
|
@ -178,7 +178,7 @@ ViewFrustum::intersection ViewFrustum::calculateCubeKeyholeIntersection(const AA
|
|||
|
||||
bool ViewFrustum::pointIntersectsFrustum(const glm::vec3& point) const {
|
||||
// only check against frustum
|
||||
for(int i = 0; i < 6; ++i) {
|
||||
for(int i = 0; i < NUM_FRUSTUM_PLANES; ++i) {
|
||||
float distance = _planes[i].distance(point);
|
||||
if (distance < 0.0f) {
|
||||
return false;
|
||||
|
@ -189,7 +189,7 @@ bool ViewFrustum::pointIntersectsFrustum(const glm::vec3& point) const {
|
|||
|
||||
bool ViewFrustum::sphereIntersectsFrustum(const glm::vec3& center, float radius) const {
|
||||
// only check against frustum
|
||||
for(int i=0; i < 6; i++) {
|
||||
for(int i = 0; i < NUM_FRUSTUM_PLANES; i++) {
|
||||
float distance = _planes[i].distance(center);
|
||||
if (distance < -radius) {
|
||||
// This is outside the regular frustum, so just return the value from checking the keyhole
|
||||
|
@ -201,7 +201,7 @@ bool ViewFrustum::sphereIntersectsFrustum(const glm::vec3& center, float radius)
|
|||
|
||||
bool ViewFrustum::boxIntersectsFrustum(const AABox& box) const {
|
||||
// only check against frustum
|
||||
for(int i=0; i < 6; i++) {
|
||||
for(int i = 0; i < NUM_FRUSTUM_PLANES; i++) {
|
||||
const glm::vec3& normal = _planes[i].getNormal();
|
||||
// check distance to farthest box point
|
||||
if ( _planes[i].distance(box.getFarthestVertex(normal)) < 0.0f) {
|
||||
|
@ -217,7 +217,7 @@ bool ViewFrustum::sphereIntersectsKeyhole(const glm::vec3& center, float radius)
|
|||
return true;
|
||||
}
|
||||
// check negative touches against frustum planes
|
||||
for(int i=0; i < 6; i++) {
|
||||
for(int i = 0; i < NUM_FRUSTUM_PLANES; i++) {
|
||||
if ( _planes[i].distance(center) < -radius) {
|
||||
return false;
|
||||
}
|
||||
|
@ -231,7 +231,7 @@ bool ViewFrustum::cubeIntersectsKeyhole(const AACube& cube) const {
|
|||
return true;
|
||||
}
|
||||
// check negative touches against frustum planes
|
||||
for(int i=0; i < 6; i++) {
|
||||
for(int i = 0; i < NUM_FRUSTUM_PLANES; i++) {
|
||||
const glm::vec3& normal = _planes[i].getNormal();
|
||||
if ( _planes[i].distance(cube.getFarthestVertex(normal)) < 0.0f) {
|
||||
return false;
|
||||
|
@ -246,7 +246,7 @@ bool ViewFrustum::boxIntersectsKeyhole(const AABox& box) const {
|
|||
return true;
|
||||
}
|
||||
// check negative touches against frustum planes
|
||||
for(int i=0; i < 6; i++) {
|
||||
for(int i = 0; i < NUM_FRUSTUM_PLANES; i++) {
|
||||
const glm::vec3& normal = _planes[i].getNormal();
|
||||
if ( _planes[i].distance(box.getFarthestVertex(normal)) < 0.0f) {
|
||||
return false;
|
||||
|
@ -281,36 +281,36 @@ bool ViewFrustum::matches(const ViewFrustum& compareTo, bool debug) const {
|
|||
testMatches(compareTo._focalLength, _focalLength);
|
||||
|
||||
if (!result && debug) {
|
||||
qCDebug(octree, "ViewFrustum::matches()... result=%s", debug::valueOf(result));
|
||||
qCDebug(octree, "%s -- compareTo._position=%f,%f,%f _position=%f,%f,%f",
|
||||
qCDebug(shared, "ViewFrustum::matches()... result=%s", debug::valueOf(result));
|
||||
qCDebug(shared, "%s -- compareTo._position=%f,%f,%f _position=%f,%f,%f",
|
||||
(testMatches(compareTo._position,_position) ? "MATCHES " : "NO MATCH"),
|
||||
(double)compareTo._position.x, (double)compareTo._position.y, (double)compareTo._position.z,
|
||||
(double)_position.x, (double)_position.y, (double)_position.z);
|
||||
qCDebug(octree, "%s -- compareTo._direction=%f,%f,%f _direction=%f,%f,%f",
|
||||
qCDebug(shared, "%s -- compareTo._direction=%f,%f,%f _direction=%f,%f,%f",
|
||||
(testMatches(compareTo._direction, _direction) ? "MATCHES " : "NO MATCH"),
|
||||
(double)compareTo._direction.x, (double)compareTo._direction.y, (double)compareTo._direction.z,
|
||||
(double)_direction.x, (double)_direction.y, (double)_direction.z );
|
||||
qCDebug(octree, "%s -- compareTo._up=%f,%f,%f _up=%f,%f,%f",
|
||||
qCDebug(shared, "%s -- compareTo._up=%f,%f,%f _up=%f,%f,%f",
|
||||
(testMatches(compareTo._up, _up) ? "MATCHES " : "NO MATCH"),
|
||||
(double)compareTo._up.x, (double)compareTo._up.y, (double)compareTo._up.z,
|
||||
(double)_up.x, (double)_up.y, (double)_up.z );
|
||||
qCDebug(octree, "%s -- compareTo._right=%f,%f,%f _right=%f,%f,%f",
|
||||
qCDebug(shared, "%s -- compareTo._right=%f,%f,%f _right=%f,%f,%f",
|
||||
(testMatches(compareTo._right, _right) ? "MATCHES " : "NO MATCH"),
|
||||
(double)compareTo._right.x, (double)compareTo._right.y, (double)compareTo._right.z,
|
||||
(double)_right.x, (double)_right.y, (double)_right.z );
|
||||
qCDebug(octree, "%s -- compareTo._fieldOfView=%f _fieldOfView=%f",
|
||||
qCDebug(shared, "%s -- compareTo._fieldOfView=%f _fieldOfView=%f",
|
||||
(testMatches(compareTo._fieldOfView, _fieldOfView) ? "MATCHES " : "NO MATCH"),
|
||||
(double)compareTo._fieldOfView, (double)_fieldOfView);
|
||||
qCDebug(octree, "%s -- compareTo._aspectRatio=%f _aspectRatio=%f",
|
||||
qCDebug(shared, "%s -- compareTo._aspectRatio=%f _aspectRatio=%f",
|
||||
(testMatches(compareTo._aspectRatio, _aspectRatio) ? "MATCHES " : "NO MATCH"),
|
||||
(double)compareTo._aspectRatio, (double)_aspectRatio);
|
||||
qCDebug(octree, "%s -- compareTo._nearClip=%f _nearClip=%f",
|
||||
qCDebug(shared, "%s -- compareTo._nearClip=%f _nearClip=%f",
|
||||
(testMatches(compareTo._nearClip, _nearClip) ? "MATCHES " : "NO MATCH"),
|
||||
(double)compareTo._nearClip, (double)_nearClip);
|
||||
qCDebug(octree, "%s -- compareTo._farClip=%f _farClip=%f",
|
||||
qCDebug(shared, "%s -- compareTo._farClip=%f _farClip=%f",
|
||||
(testMatches(compareTo._farClip, _farClip) ? "MATCHES " : "NO MATCH"),
|
||||
(double)compareTo._farClip, (double)_farClip);
|
||||
qCDebug(octree, "%s -- compareTo._focalLength=%f _focalLength=%f",
|
||||
qCDebug(shared, "%s -- compareTo._focalLength=%f _focalLength=%f",
|
||||
(testMatches(compareTo._focalLength, _focalLength) ? "MATCHES " : "NO MATCH"),
|
||||
(double)compareTo._focalLength, (double)_focalLength);
|
||||
}
|
||||
|
@ -342,34 +342,34 @@ bool ViewFrustum::isVerySimilar(const ViewFrustum& compareTo, bool debug) const
|
|||
|
||||
|
||||
if (!result && debug) {
|
||||
qCDebug(octree, "ViewFrustum::isVerySimilar()... result=%s\n", debug::valueOf(result));
|
||||
qCDebug(octree, "%s -- compareTo._position=%f,%f,%f _position=%f,%f,%f",
|
||||
qCDebug(shared, "ViewFrustum::isVerySimilar()... result=%s\n", debug::valueOf(result));
|
||||
qCDebug(shared, "%s -- compareTo._position=%f,%f,%f _position=%f,%f,%f",
|
||||
(testMatches(compareTo._position,_position, POSITION_SIMILAR_ENOUGH) ?
|
||||
"IS SIMILAR ENOUGH " : "IS NOT SIMILAR ENOUGH"),
|
||||
(double)compareTo._position.x, (double)compareTo._position.y, (double)compareTo._position.z,
|
||||
(double)_position.x, (double)_position.y, (double)_position.z );
|
||||
|
||||
qCDebug(octree, "%s -- positionDistance=%f",
|
||||
qCDebug(shared, "%s -- positionDistance=%f",
|
||||
(testMatches(0,positionDistance, POSITION_SIMILAR_ENOUGH) ? "IS SIMILAR ENOUGH " : "IS NOT SIMILAR ENOUGH"),
|
||||
(double)positionDistance);
|
||||
|
||||
qCDebug(octree, "%s -- angleOrientation=%f",
|
||||
qCDebug(shared, "%s -- angleOrientation=%f",
|
||||
(testMatches(0, angleOrientation, ORIENTATION_SIMILAR_ENOUGH) ? "IS SIMILAR ENOUGH " : "IS NOT SIMILAR ENOUGH"),
|
||||
(double)angleOrientation);
|
||||
|
||||
qCDebug(octree, "%s -- compareTo._fieldOfView=%f _fieldOfView=%f",
|
||||
qCDebug(shared, "%s -- compareTo._fieldOfView=%f _fieldOfView=%f",
|
||||
(testMatches(compareTo._fieldOfView, _fieldOfView) ? "MATCHES " : "NO MATCH"),
|
||||
(double)compareTo._fieldOfView, (double)_fieldOfView);
|
||||
qCDebug(octree, "%s -- compareTo._aspectRatio=%f _aspectRatio=%f",
|
||||
qCDebug(shared, "%s -- compareTo._aspectRatio=%f _aspectRatio=%f",
|
||||
(testMatches(compareTo._aspectRatio, _aspectRatio) ? "MATCHES " : "NO MATCH"),
|
||||
(double)compareTo._aspectRatio, (double)_aspectRatio);
|
||||
qCDebug(octree, "%s -- compareTo._nearClip=%f _nearClip=%f",
|
||||
qCDebug(shared, "%s -- compareTo._nearClip=%f _nearClip=%f",
|
||||
(testMatches(compareTo._nearClip, _nearClip) ? "MATCHES " : "NO MATCH"),
|
||||
(double)compareTo._nearClip, (double)_nearClip);
|
||||
qCDebug(octree, "%s -- compareTo._farClip=%f _farClip=%f",
|
||||
qCDebug(shared, "%s -- compareTo._farClip=%f _farClip=%f",
|
||||
(testMatches(compareTo._farClip, _farClip) ? "MATCHES " : "NO MATCH"),
|
||||
(double)compareTo._farClip, (double)_farClip);
|
||||
qCDebug(octree, "%s -- compareTo._focalLength=%f _focalLength=%f",
|
||||
qCDebug(shared, "%s -- compareTo._focalLength=%f _focalLength=%f",
|
||||
(testMatches(compareTo._focalLength, _focalLength) ? "MATCHES " : "NO MATCH"),
|
||||
(double)compareTo._focalLength, (double)_focalLength);
|
||||
}
|
||||
|
@ -394,7 +394,7 @@ void ViewFrustum::computeOffAxisFrustum(float& left, float& right, float& bottom
|
|||
// find the minimum and maximum z values, which will be our near and far clip distances
|
||||
nearValue = FLT_MAX;
|
||||
farValue = -FLT_MAX;
|
||||
for (int i = 0; i < 8; i++) {
|
||||
for (int i = 0; i < NUM_FRUSTUM_CORNERS; i++) {
|
||||
nearValue = min(nearValue, -_corners[i].z);
|
||||
farValue = max(farValue, -_corners[i].z);
|
||||
}
|
||||
|
@ -427,17 +427,17 @@ void ViewFrustum::computeOffAxisFrustum(float& left, float& right, float& bottom
|
|||
}
|
||||
|
||||
void ViewFrustum::printDebugDetails() const {
|
||||
qCDebug(octree, "ViewFrustum::printDebugDetails()...");
|
||||
qCDebug(octree, "_position=%f,%f,%f", (double)_position.x, (double)_position.y, (double)_position.z );
|
||||
qCDebug(octree, "_direction=%f,%f,%f", (double)_direction.x, (double)_direction.y, (double)_direction.z );
|
||||
qCDebug(octree, "_up=%f,%f,%f", (double)_up.x, (double)_up.y, (double)_up.z );
|
||||
qCDebug(octree, "_right=%f,%f,%f", (double)_right.x, (double)_right.y, (double)_right.z );
|
||||
qCDebug(octree, "_fieldOfView=%f", (double)_fieldOfView);
|
||||
qCDebug(octree, "_aspectRatio=%f", (double)_aspectRatio);
|
||||
qCDebug(octree, "_centerSphereRadius=%f", (double)_centerSphereRadius);
|
||||
qCDebug(octree, "_nearClip=%f", (double)_nearClip);
|
||||
qCDebug(octree, "_farClip=%f", (double)_farClip);
|
||||
qCDebug(octree, "_focalLength=%f", (double)_focalLength);
|
||||
qCDebug(shared, "ViewFrustum::printDebugDetails()...");
|
||||
qCDebug(shared, "_position=%f,%f,%f", (double)_position.x, (double)_position.y, (double)_position.z );
|
||||
qCDebug(shared, "_direction=%f,%f,%f", (double)_direction.x, (double)_direction.y, (double)_direction.z );
|
||||
qCDebug(shared, "_up=%f,%f,%f", (double)_up.x, (double)_up.y, (double)_up.z );
|
||||
qCDebug(shared, "_right=%f,%f,%f", (double)_right.x, (double)_right.y, (double)_right.z );
|
||||
qCDebug(shared, "_fieldOfView=%f", (double)_fieldOfView);
|
||||
qCDebug(shared, "_aspectRatio=%f", (double)_aspectRatio);
|
||||
qCDebug(shared, "_centerSphereRadius=%f", (double)_centerSphereRadius);
|
||||
qCDebug(shared, "_nearClip=%f", (double)_nearClip);
|
||||
qCDebug(shared, "_farClip=%f", (double)_farClip);
|
||||
qCDebug(shared, "_focalLength=%f", (double)_focalLength);
|
||||
}
|
||||
|
||||
glm::vec2 ViewFrustum::projectPoint(glm::vec3 point, bool& pointInView) const {
|
||||
|
@ -536,7 +536,7 @@ const int hullVertexLookup[MAX_POSSIBLE_COMBINATIONS][MAX_PROJECTED_POLYGON_VERT
|
|||
{6, TOP_RIGHT_NEAR, TOP_RIGHT_FAR, BOTTOM_RIGHT_FAR, BOTTOM_LEFT_FAR, BOTTOM_LEFT_NEAR, TOP_LEFT_NEAR}, // back, top, left
|
||||
};
|
||||
|
||||
OctreeProjectedPolygon ViewFrustum::getProjectedPolygon(const AACube& box) const {
|
||||
CubeProjectedPolygon ViewFrustum::getProjectedPolygon(const AACube& box) const {
|
||||
const glm::vec3& bottomNearRight = box.getCorner();
|
||||
glm::vec3 topFarLeft = box.calcTopFarLeft();
|
||||
|
||||
|
@ -549,7 +549,7 @@ OctreeProjectedPolygon ViewFrustum::getProjectedPolygon(const AACube& box) const
|
|||
|
||||
int vertexCount = hullVertexLookup[lookUp][0]; //look up number of vertices
|
||||
|
||||
OctreeProjectedPolygon projectedPolygon(vertexCount);
|
||||
CubeProjectedPolygon projectedPolygon(vertexCount);
|
||||
|
||||
bool pointInView = true;
|
||||
bool allPointsInView = false; // assume the best, but wait till we know we have a vertex
|
||||
|
@ -630,7 +630,7 @@ void ViewFrustum::getFurthestPointFromCamera(const AACube& box, glm::vec3& furth
|
|||
}
|
||||
}
|
||||
|
||||
const ViewFrustum::Corners ViewFrustum::getCorners(const float& depth) {
|
||||
const ViewFrustum::Corners ViewFrustum::getCorners(const float& depth) const {
|
||||
glm::vec3 normal = glm::normalize(_direction);
|
||||
|
||||
auto getCorner = [&](enum::BoxVertex nearCorner, enum::BoxVertex farCorner) {
|
||||
|
@ -662,51 +662,10 @@ void ViewFrustum::evalViewTransform(Transform& view) const {
|
|||
view.setRotation(getOrientation());
|
||||
}
|
||||
|
||||
float ViewFrustum::calculateRenderAccuracy(const AABox& bounds, float octreeSizeScale, int boundaryLevelAdjust) const {
|
||||
float distanceToCamera = glm::length(bounds.calcCenter() - getPosition());
|
||||
float largestDimension = bounds.getLargestDimension();
|
||||
|
||||
const float maxScale = (float)TREE_SCALE;
|
||||
float visibleDistanceAtMaxScale = boundaryDistanceForRenderLevel(boundaryLevelAdjust, octreeSizeScale) / OCTREE_TO_MESH_RATIO;
|
||||
|
||||
static std::once_flag once;
|
||||
static QMap<float, float> shouldRenderTable;
|
||||
std::call_once(once, [&] {
|
||||
float SMALLEST_SCALE_IN_TABLE = 0.001f; // 1mm is plenty small
|
||||
float scale = maxScale;
|
||||
float factor = 1.0f;
|
||||
|
||||
while (scale > SMALLEST_SCALE_IN_TABLE) {
|
||||
scale /= 2.0f;
|
||||
factor /= 2.0f;
|
||||
shouldRenderTable[scale] = factor;
|
||||
}
|
||||
});
|
||||
|
||||
float closestScale = maxScale;
|
||||
float visibleDistanceAtClosestScale = visibleDistanceAtMaxScale;
|
||||
QMap<float, float>::const_iterator lowerBound = shouldRenderTable.lowerBound(largestDimension);
|
||||
if (lowerBound != shouldRenderTable.constEnd()) {
|
||||
closestScale = lowerBound.key();
|
||||
visibleDistanceAtClosestScale = visibleDistanceAtMaxScale * lowerBound.value();
|
||||
void ViewFrustum::invalidate() {
|
||||
// these setting should make nearly all intersection tests fail
|
||||
for (int i = 0; i < NUM_FRUSTUM_PLANES; ++i) {
|
||||
_planes[i].invalidate();
|
||||
}
|
||||
|
||||
if (closestScale < largestDimension) {
|
||||
visibleDistanceAtClosestScale *= 2.0f;
|
||||
}
|
||||
|
||||
// FIXME - for now, it's either visible or not visible. We want to adjust this to eventually return
|
||||
// a floating point for objects that have small angular size to indicate that they may be rendered
|
||||
// with lower preciscion
|
||||
return (distanceToCamera <= visibleDistanceAtClosestScale) ? 1.0f : 0.0f;
|
||||
}
|
||||
|
||||
float boundaryDistanceForRenderLevel(unsigned int renderLevel, float voxelSizeScale) {
|
||||
return voxelSizeScale / powf(2, renderLevel);
|
||||
}
|
||||
|
||||
float ViewFrustum::getAccuracyAngle(float octreeSizeScale, int boundaryLevelAdjust) const {
|
||||
const float maxScale = (float)TREE_SCALE;
|
||||
float visibleDistanceAtMaxScale = boundaryDistanceForRenderLevel(boundaryLevelAdjust, octreeSizeScale) / OCTREE_TO_MESH_RATIO;
|
||||
return atan(maxScale / visibleDistanceAtMaxScale);
|
||||
_centerSphereRadius = -1.0e6f; // -10^6 should be negative enough
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
//
|
||||
// ViewFrustum.h
|
||||
// libraries/octree/src
|
||||
// libraries/shared/src
|
||||
//
|
||||
// Created by Brad Hefta-Gaub on 04/11/13.
|
||||
// Copyright 2013 High Fidelity, Inc.
|
||||
|
@ -17,21 +17,21 @@
|
|||
#include <glm/glm.hpp>
|
||||
#include <glm/gtc/quaternion.hpp>
|
||||
|
||||
#include <GLMHelpers.h>
|
||||
#include <RegisteredMetaTypes.h>
|
||||
|
||||
#include "Transform.h"
|
||||
#include "AABox.h"
|
||||
#include "AACube.h"
|
||||
#include "CubeProjectedPolygon.h"
|
||||
#include "Plane.h"
|
||||
#include "OctreeConstants.h"
|
||||
#include "OctreeProjectedPolygon.h"
|
||||
#include "RegisteredMetaTypes.h"
|
||||
#include "Transform.h"
|
||||
|
||||
const int NUM_FRUSTUM_CORNERS = 8;
|
||||
const int NUM_FRUSTUM_PLANES = 6;
|
||||
|
||||
const float DEFAULT_CENTER_SPHERE_RADIUS = 3.0f;
|
||||
const float DEFAULT_FIELD_OF_VIEW_DEGREES = 45.0f;
|
||||
const float DEFAULT_ASPECT_RATIO = 16.0f/9.0f;
|
||||
const float DEFAULT_NEAR_CLIP = 0.08f;
|
||||
const float DEFAULT_FAR_CLIP = (float)HALF_TREE_SCALE;
|
||||
const float DEFAULT_FAR_CLIP = 16384.0f;
|
||||
|
||||
// the "ViewFrustum" has a "keyhole" shape: a regular frustum for stuff that is "visible" with
|
||||
// a central sphere for stuff that is nearby (for physics simulation).
|
||||
|
@ -74,7 +74,7 @@ public:
|
|||
glm::vec3 bottomRight;
|
||||
// Get the corners depth units from frustum position, along frustum orientation
|
||||
};
|
||||
const Corners getCorners(const float& depth);
|
||||
const Corners getCorners(const float& depth) const;
|
||||
|
||||
// getters for corners
|
||||
const glm::vec3& getFarTopLeft() const { return _cornersWorld[TOP_LEFT_FAR]; }
|
||||
|
@ -123,7 +123,7 @@ public:
|
|||
void printDebugDetails() const;
|
||||
|
||||
glm::vec2 projectPoint(glm::vec3 point, bool& pointInView) const;
|
||||
OctreeProjectedPolygon getProjectedPolygon(const AACube& box) const;
|
||||
CubeProjectedPolygon getProjectedPolygon(const AACube& box) const;
|
||||
void getFurthestPointFromCamera(const AACube& box, glm::vec3& furthestPoint) const;
|
||||
|
||||
float distanceToCamera(const glm::vec3& point) const;
|
||||
|
@ -131,44 +131,37 @@ public:
|
|||
void evalProjectionMatrix(glm::mat4& proj) const;
|
||||
void evalViewTransform(Transform& view) const;
|
||||
|
||||
/// renderAccuracy represents a floating point "visibility" of an object based on it's view from the camera. At a simple
|
||||
/// level it returns 0.0f for things that are so small for the current settings that they could not be visible.
|
||||
float calculateRenderAccuracy(const AABox& bounds, float octreeSizeScale = DEFAULT_OCTREE_SIZE_SCALE,
|
||||
int boundaryLevelAdjust = 0) const;
|
||||
|
||||
float getAccuracyAngle(float octreeSizeScale = DEFAULT_OCTREE_SIZE_SCALE, int boundaryLevelAdjust = 0) const;
|
||||
|
||||
enum PlaneIndex { TOP_PLANE = 0, BOTTOM_PLANE, LEFT_PLANE, RIGHT_PLANE, NEAR_PLANE, FAR_PLANE, NUM_PLANES };
|
||||
|
||||
const ::Plane* getPlanes() const { return _planes; }
|
||||
private:
|
||||
// camera location/orientation attributes
|
||||
glm::vec3 _position; // the position in world-frame
|
||||
glm::quat _orientation;
|
||||
glm::mat4 _view;
|
||||
|
||||
// Lens attributes
|
||||
void invalidate(); // causes all reasonable intersection tests to fail
|
||||
private:
|
||||
glm::mat4 _view;
|
||||
glm::mat4 _projection;
|
||||
|
||||
// calculated for orientation
|
||||
::Plane _planes[NUM_FRUSTUM_PLANES]; // plane normals point inside frustum
|
||||
|
||||
glm::vec3 _position; // position in world-frame
|
||||
glm::quat _orientation; // orientation in world-frame
|
||||
|
||||
// calculated from orientation
|
||||
glm::vec3 _direction = IDENTITY_FRONT;
|
||||
glm::vec3 _up = IDENTITY_UP;
|
||||
glm::vec3 _right = IDENTITY_RIGHT;
|
||||
|
||||
// calculated from projection
|
||||
glm::vec4 _corners[NUM_FRUSTUM_CORNERS];
|
||||
glm::vec3 _cornersWorld[NUM_FRUSTUM_CORNERS];
|
||||
float _centerSphereRadius = DEFAULT_CENTER_SPHERE_RADIUS;
|
||||
float _width { 1.0f };
|
||||
float _height { 1.0f };
|
||||
float _aspectRatio { 1.0f };
|
||||
float _focalLength { 0.25f };
|
||||
float _fieldOfView { DEFAULT_FIELD_OF_VIEW_DEGREES };
|
||||
|
||||
// Calculated values
|
||||
glm::mat4 _inverseProjection;
|
||||
float _width = 1.0f;
|
||||
float _height = 1.0f;
|
||||
float _aspectRatio = 1.0f;
|
||||
float _nearClip = DEFAULT_NEAR_CLIP;
|
||||
float _farClip = DEFAULT_FAR_CLIP;
|
||||
float _focalLength = 0.25f;
|
||||
float _fieldOfView = DEFAULT_FIELD_OF_VIEW_DEGREES;
|
||||
glm::vec4 _corners[8];
|
||||
glm::vec3 _cornersWorld[8];
|
||||
::Plane _planes[6]; // plane normals point inside frustum
|
||||
float _nearClip { DEFAULT_NEAR_CLIP };
|
||||
float _farClip { DEFAULT_FAR_CLIP };
|
||||
|
||||
const char* debugPlaneName (int plane) const;
|
||||
|
||||
|
@ -177,6 +170,4 @@ private:
|
|||
};
|
||||
using ViewFrustumPointer = std::shared_ptr<ViewFrustum>;
|
||||
|
||||
float boundaryDistanceForRenderLevel(unsigned int renderLevel, float voxelSizeScale);
|
||||
|
||||
#endif // hifi_ViewFrustum_h
|
Loading…
Reference in a new issue