mirror of
https://github.com/overte-org/overte.git
synced 2025-07-23 16:44:09 +02:00
53 lines
2.4 KiB
C++
53 lines
2.4 KiB
C++
//
|
|
// EntityPriorityQueue.cpp
|
|
// assignment-client/src/entities
|
|
//
|
|
// Created by Andrew Meadows 2017.08.08
|
|
// Copyright 2017 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 "EntityPriorityQueue.h"
|
|
|
|
const float PrioritizedEntity::DO_NOT_SEND = -1.0e-6f;
|
|
const float PrioritizedEntity::FORCE_REMOVE = -1.0e-5f;
|
|
const float PrioritizedEntity::WHEN_IN_DOUBT_PRIORITY = 1.0f;
|
|
|
|
void ConicalView::set(const ViewFrustum& viewFrustum) {
|
|
// The ConicalView has two parts: a central sphere (same as ViewFrustum) and a circular cone that bounds the frustum part.
|
|
// Why? Because approximate intersection tests are much faster to compute for a cone than for a frustum.
|
|
_position = viewFrustum.getPosition();
|
|
_direction = viewFrustum.getDirection();
|
|
|
|
// We cache the sin and cos of the half angle of the cone that bounds the frustum.
|
|
// (the math here is left as an exercise for the reader)
|
|
float A = viewFrustum.getAspectRatio();
|
|
float t = tanf(0.5f * viewFrustum.getFieldOfView());
|
|
_cosAngle = 1.0f / sqrtf(1.0f + (A * A + 1.0f) * (t * t));
|
|
_sinAngle = sqrtf(1.0f - _cosAngle * _cosAngle);
|
|
|
|
_radius = viewFrustum.getCenterRadius();
|
|
}
|
|
|
|
float ConicalView::computePriority(const AACube& cube) const {
|
|
glm::vec3 p = cube.calcCenter() - _position; // position of bounding sphere in view-frame
|
|
float d = glm::length(p); // distance to center of bounding sphere
|
|
float r = 0.5f * cube.getScale(); // radius of bounding sphere
|
|
if (d < _radius + r) {
|
|
return r;
|
|
}
|
|
// We check the angle between the center of the cube and the _direction of the view.
|
|
// If it is less than the sum of the half-angle from center of cone to outer edge plus
|
|
// the half apparent angle of the bounding sphere then it is in view.
|
|
//
|
|
// The math here is left as an exercise for the reader with the following hints:
|
|
// (1) We actually check the dot product of the cube's local position rather than the angle and
|
|
// (2) we take advantage of this trig identity: cos(A+B) = cos(A)*cos(B) - sin(A)*sin(B)
|
|
if (glm::dot(p, _direction) > sqrtf(d * d - r * r) * _cosAngle - r * _sinAngle) {
|
|
const float AVOID_DIVIDE_BY_ZERO = 0.001f;
|
|
return r / (d + AVOID_DIVIDE_BY_ZERO);
|
|
}
|
|
return PrioritizedEntity::DO_NOT_SEND;
|
|
}
|