Merge branch 'master' of github.com:highfidelity/hifi into black

This commit is contained in:
Sam Gateau 2018-09-05 11:35:59 -07:00
commit 2ced6d9681
20 changed files with 205 additions and 138 deletions

View file

@ -46,6 +46,7 @@ This can either be entered directly into your shell session before you build or
The path it needs to be set to will depend on where and how Qt5 was installed. e.g.
export QT_CMAKE_PREFIX_PATH=/usr/local/Qt5.10.1/5.10.1/gcc_64/lib/cmake
export QT_CMAKE_PREFIX_PATH=/usr/local/qt/5.10.1/clang_64/lib/cmake/
export QT_CMAKE_PREFIX_PATH=/usr/local/Cellar/qt5/5.10.1/lib/cmake
export QT_CMAKE_PREFIX_PATH=/usr/local/opt/qt5/lib/cmake

View file

@ -6,13 +6,20 @@ Please read the [general build guide](BUILD.md) for information on dependencies
Should you choose not to install Qt5 via a package manager that handles dependencies for you, you may be missing some Qt5 dependencies. On Ubuntu, for example, the following additional packages are required:
libasound2 libxmu-dev libxi-dev freeglut3-dev libasound2-dev libjack0 libjack-dev libxrandr-dev libudev-dev libssl-dev
libasound2 libxmu-dev libxi-dev freeglut3-dev libasound2-dev libjack0 libjack-dev libxrandr-dev libudev-dev libssl-dev zlib1g-dev
## Ubuntu 16.04 specific build guide
## Ubuntu 16.04/18.04 specific build guide
### Ubuntu 18.04 only
Add the universe repository:
_(This is not enabled by default on the server edition)_
```bash
sudo add-apt-repository universe
sudo apt-get update
```
### Prepare environment
hifiqt5.10.1
Install qt:
Install Qt 5.10.1:
```bash
wget http://debian.highfidelity.com/pool/h/hi/hifiqt5.10.1_5.10.1_amd64.deb
sudo dpkg -i hifiqt5.10.1_5.10.1_amd64.deb
@ -20,19 +27,20 @@ sudo dpkg -i hifiqt5.10.1_5.10.1_amd64.deb
Install build dependencies:
```bash
sudo apt-get install libasound2 libxmu-dev libxi-dev freeglut3-dev libasound2-dev libjack0 libjack-dev libxrandr-dev libudev-dev libssl-dev
sudo apt-get install libasound2 libxmu-dev libxi-dev freeglut3-dev libasound2-dev libjack0 libjack-dev libxrandr-dev libudev-dev libssl-dev zlib1g-dev
```
To compile interface in a server you must install:
```bash
sudo apt -y install libpulse0 libnss3 libnspr4 libfontconfig1 libxcursor1 libxcomposite1 libxtst6 libxslt1.1
sudo apt-get -y install libpulse0 libnss3 libnspr4 libfontconfig1 libxcursor1 libxcomposite1 libxtst6 libxslt1.1
```
Install build tools:
```bash
sudo apt install cmake
sudo apt-get install cmake
```
### Get code and checkout the tag you need
Clone this repository:
@ -48,12 +56,7 @@ git tags
Then checkout last tag with:
```bash
git checkout tags/RELEASE-6819
```
Or go to the highfidelity download page (https://highfidelity.com/download) to get the release version. For example, if there is a BETA 6731 type:
```bash
git checkout tags/RELEASE-6731
git checkout tags/v0.71.0
```
### Compiling
@ -66,15 +69,20 @@ cd hifi/build
Prepare makefiles:
```bash
cmake -DQT_CMAKE_PREFIX_PATH=/usr/local/Qt5.10.1/5.10/gcc_64/lib/cmake ..
cmake -DQT_CMAKE_PREFIX_PATH=/usr/local/Qt5.10.1/5.10.1/gcc_64/lib/cmake ..
```
Start compilation and get a cup of coffee:
Start compilation of the server and get a cup of coffee:
```bash
make domain-server assignment-client interface
make domain-server assignment-client
```
In a server does not make sense to compile interface
To compile interface:
```bash
make interface
```
In a server, it does not make sense to compile interface
### Running the software
@ -93,4 +101,4 @@ Running interface:
./interface/interface
```
Go to localhost in running interface.
Go to localhost in the running interface.

View file

@ -329,6 +329,7 @@ void AvatarMixerSlave::broadcastAvatarDataToAgent(const SharedNodePointer& node)
AvatarData::_avatarSortCoefficientSize,
AvatarData::_avatarSortCoefficientCenter,
AvatarData::_avatarSortCoefficientAge);
sortedAvatars.reserve(avatarsToSort.size());
// ignore or sort
const AvatarSharedPointer& thisAvatar = nodeData->getAvatarSharedPointer();
@ -429,9 +430,9 @@ void AvatarMixerSlave::broadcastAvatarDataToAgent(const SharedNodePointer& node)
int remainingAvatars = (int)sortedAvatars.size();
auto traitsPacketList = NLPacketList::create(PacketType::BulkAvatarTraits, QByteArray(), true, true);
while (!sortedAvatars.empty()) {
const auto avatarData = sortedAvatars.top().getAvatar();
sortedAvatars.pop();
const auto& sortedAvatarVector = sortedAvatars.getSortedVector();
for (const auto& sortedAvatar : sortedAvatarVector) {
const auto& avatarData = sortedAvatar.getAvatar();
remainingAvatars--;
auto otherNode = avatarDataToNodes[avatarData];

View file

@ -187,16 +187,17 @@ void AvatarManager::updateOtherAvatars(float deltaTime) {
AvatarSharedPointer _avatar;
};
auto avatarMap = getHashCopy();
AvatarHash::iterator itr = avatarMap.begin();
const auto& views = qApp->getConicalViews();
PrioritySortUtil::PriorityQueue<SortableAvatar> sortedAvatars(views,
AvatarData::_avatarSortCoefficientSize,
AvatarData::_avatarSortCoefficientCenter,
AvatarData::_avatarSortCoefficientAge);
sortedAvatars.reserve(avatarMap.size() - 1); // don't include MyAvatar
// sort
auto avatarMap = getHashCopy();
AvatarHash::iterator itr = avatarMap.begin();
while (itr != avatarMap.end()) {
const auto& avatar = std::static_pointer_cast<Avatar>(*itr);
// DO NOT update _myAvatar! Its update has already been done earlier in the main loop.
@ -206,6 +207,7 @@ void AvatarManager::updateOtherAvatars(float deltaTime) {
}
++itr;
}
const auto& sortedAvatarVector = sortedAvatars.getSortedVector();
// process in sorted order
uint64_t startTime = usecTimestampNow();
@ -216,8 +218,8 @@ void AvatarManager::updateOtherAvatars(float deltaTime) {
render::Transaction renderTransaction;
workload::Transaction workloadTransaction;
while (!sortedAvatars.empty()) {
const SortableAvatar& sortData = sortedAvatars.top();
for (auto it = sortedAvatarVector.begin(); it != sortedAvatarVector.end(); ++it) {
const SortableAvatar& sortData = *it;
const auto avatar = std::static_pointer_cast<OtherAvatar>(sortData.getAvatar());
// TODO: to help us scale to more avatars it would be nice to not have to poll orb state here
@ -231,7 +233,6 @@ void AvatarManager::updateOtherAvatars(float deltaTime) {
bool ignoring = DependencyManager::get<NodeList>()->isPersonalMutingNode(avatar->getID());
if (ignoring) {
sortedAvatars.pop();
continue;
}
@ -260,26 +261,19 @@ void AvatarManager::updateOtherAvatars(float deltaTime) {
// --> some avatar velocity measurements may be a little off
// no time to simulate, but we take the time to count how many were tragically missed
bool inView = sortData.getPriority() > OUT_OF_VIEW_THRESHOLD;
if (!inView) {
break;
}
if (inView && avatar->hasNewJointData()) {
numAVatarsNotUpdated++;
}
sortedAvatars.pop();
while (inView && !sortedAvatars.empty()) {
const SortableAvatar& newSortData = sortedAvatars.top();
while (it != sortedAvatarVector.end()) {
const SortableAvatar& newSortData = *it;
const auto newAvatar = std::static_pointer_cast<Avatar>(newSortData.getAvatar());
inView = newSortData.getPriority() > OUT_OF_VIEW_THRESHOLD;
if (inView && newAvatar->hasNewJointData()) {
numAVatarsNotUpdated++;
bool inView = newSortData.getPriority() > OUT_OF_VIEW_THRESHOLD;
// Once we reach an avatar that's not in view, all avatars after it will also be out of view
if (!inView) {
break;
}
sortedAvatars.pop();
numAVatarsNotUpdated += (int)(newAvatar->hasNewJointData());
++it;
}
break;
}
sortedAvatars.pop();
}
if (_shouldRender) {

View file

@ -4313,7 +4313,8 @@ glm::mat4 MyAvatar::getCenterEyeCalibrationMat() const {
auto centerEyeRot = Quaternions::Y_180;
return createMatFromQuatAndPos(centerEyeRot, centerEyePos / getSensorToWorldScale());
} else {
return createMatFromQuatAndPos(DEFAULT_AVATAR_MIDDLE_EYE_ROT, DEFAULT_AVATAR_MIDDLE_EYE_POS / getSensorToWorldScale());
glm::mat4 headMat = getHeadCalibrationMat();
return createMatFromQuatAndPos(DEFAULT_AVATAR_MIDDLE_EYE_ROT, extractTranslation(headMat) + DEFAULT_AVATAR_HEAD_TO_MIDDLE_EYE_OFFSET);
}
}
@ -4323,9 +4324,10 @@ glm::mat4 MyAvatar::getHeadCalibrationMat() const {
if (headIndex >= 0) {
auto headPos = getAbsoluteDefaultJointTranslationInObjectFrame(headIndex);
auto headRot = getAbsoluteDefaultJointRotationInObjectFrame(headIndex);
return createMatFromQuatAndPos(headRot, headPos / getSensorToWorldScale());
} else {
return createMatFromQuatAndPos(DEFAULT_AVATAR_HEAD_ROT, DEFAULT_AVATAR_HEAD_POS / getSensorToWorldScale());
return createMatFromQuatAndPos(DEFAULT_AVATAR_HEAD_ROT, DEFAULT_AVATAR_HEAD_POS);
}
}
@ -4337,7 +4339,7 @@ glm::mat4 MyAvatar::getSpine2CalibrationMat() const {
auto spine2Rot = getAbsoluteDefaultJointRotationInObjectFrame(spine2Index);
return createMatFromQuatAndPos(spine2Rot, spine2Pos / getSensorToWorldScale());
} else {
return createMatFromQuatAndPos(DEFAULT_AVATAR_SPINE2_ROT, DEFAULT_AVATAR_SPINE2_POS / getSensorToWorldScale());
return createMatFromQuatAndPos(DEFAULT_AVATAR_SPINE2_ROT, DEFAULT_AVATAR_SPINE2_POS);
}
}
@ -4349,7 +4351,7 @@ glm::mat4 MyAvatar::getHipsCalibrationMat() const {
auto hipsRot = getAbsoluteDefaultJointRotationInObjectFrame(hipsIndex);
return createMatFromQuatAndPos(hipsRot, hipsPos / getSensorToWorldScale());
} else {
return createMatFromQuatAndPos(DEFAULT_AVATAR_HIPS_ROT, DEFAULT_AVATAR_HIPS_POS / getSensorToWorldScale());
return createMatFromQuatAndPos(DEFAULT_AVATAR_HIPS_ROT, DEFAULT_AVATAR_HIPS_POS);
}
}
@ -4361,7 +4363,7 @@ glm::mat4 MyAvatar::getLeftFootCalibrationMat() const {
auto leftFootRot = getAbsoluteDefaultJointRotationInObjectFrame(leftFootIndex);
return createMatFromQuatAndPos(leftFootRot, leftFootPos / getSensorToWorldScale());
} else {
return createMatFromQuatAndPos(DEFAULT_AVATAR_LEFTFOOT_ROT, DEFAULT_AVATAR_LEFTFOOT_POS / getSensorToWorldScale());
return createMatFromQuatAndPos(DEFAULT_AVATAR_LEFTFOOT_ROT, DEFAULT_AVATAR_LEFTFOOT_POS);
}
}
@ -4373,11 +4375,10 @@ glm::mat4 MyAvatar::getRightFootCalibrationMat() const {
auto rightFootRot = getAbsoluteDefaultJointRotationInObjectFrame(rightFootIndex);
return createMatFromQuatAndPos(rightFootRot, rightFootPos / getSensorToWorldScale());
} else {
return createMatFromQuatAndPos(DEFAULT_AVATAR_RIGHTFOOT_ROT, DEFAULT_AVATAR_RIGHTFOOT_POS / getSensorToWorldScale());
return createMatFromQuatAndPos(DEFAULT_AVATAR_RIGHTFOOT_ROT, DEFAULT_AVATAR_RIGHTFOOT_POS);
}
}
glm::mat4 MyAvatar::getRightArmCalibrationMat() const {
int rightArmIndex = _skeletonModel->getRig().indexOfJoint("RightArm");
if (rightArmIndex >= 0) {
@ -4385,7 +4386,7 @@ glm::mat4 MyAvatar::getRightArmCalibrationMat() const {
auto rightArmRot = getAbsoluteDefaultJointRotationInObjectFrame(rightArmIndex);
return createMatFromQuatAndPos(rightArmRot, rightArmPos / getSensorToWorldScale());
} else {
return createMatFromQuatAndPos(DEFAULT_AVATAR_RIGHTARM_ROT, DEFAULT_AVATAR_RIGHTARM_POS / getSensorToWorldScale());
return createMatFromQuatAndPos(DEFAULT_AVATAR_RIGHTARM_ROT, DEFAULT_AVATAR_RIGHTARM_POS);
}
}
@ -4396,7 +4397,7 @@ glm::mat4 MyAvatar::getLeftArmCalibrationMat() const {
auto leftArmRot = getAbsoluteDefaultJointRotationInObjectFrame(leftArmIndex);
return createMatFromQuatAndPos(leftArmRot, leftArmPos / getSensorToWorldScale());
} else {
return createMatFromQuatAndPos(DEFAULT_AVATAR_LEFTARM_ROT, DEFAULT_AVATAR_LEFTARM_POS / getSensorToWorldScale());
return createMatFromQuatAndPos(DEFAULT_AVATAR_LEFTARM_ROT, DEFAULT_AVATAR_LEFTARM_POS);
}
}
@ -4407,7 +4408,7 @@ glm::mat4 MyAvatar::getRightHandCalibrationMat() const {
auto rightHandRot = getAbsoluteDefaultJointRotationInObjectFrame(rightHandIndex);
return createMatFromQuatAndPos(rightHandRot, rightHandPos / getSensorToWorldScale());
} else {
return createMatFromQuatAndPos(DEFAULT_AVATAR_RIGHTHAND_ROT, DEFAULT_AVATAR_RIGHTHAND_POS / getSensorToWorldScale());
return createMatFromQuatAndPos(DEFAULT_AVATAR_RIGHTHAND_ROT, DEFAULT_AVATAR_RIGHTHAND_POS);
}
}
@ -4418,7 +4419,7 @@ glm::mat4 MyAvatar::getLeftHandCalibrationMat() const {
auto leftHandRot = getAbsoluteDefaultJointRotationInObjectFrame(leftHandIndex);
return createMatFromQuatAndPos(leftHandRot, leftHandPos / getSensorToWorldScale());
} else {
return createMatFromQuatAndPos(DEFAULT_AVATAR_LEFTHAND_ROT, DEFAULT_AVATAR_LEFTHAND_POS / getSensorToWorldScale());
return createMatFromQuatAndPos(DEFAULT_AVATAR_LEFTHAND_ROT, DEFAULT_AVATAR_LEFTHAND_POS);
}
}

View file

@ -1034,7 +1034,7 @@ public:
virtual glm::quat getAbsoluteJointRotationInObjectFrame(int index) const override;
virtual glm::vec3 getAbsoluteJointTranslationInObjectFrame(int index) const override;
// all calibration matrices are in absolute avatar space.
// all calibration matrices are in absolute sensor space.
glm::mat4 getCenterEyeCalibrationMat() const;
glm::mat4 getHeadCalibrationMat() const;
glm::mat4 getSpine2CalibrationMat() const;

View file

@ -29,20 +29,23 @@ OtherAvatar::~OtherAvatar() {
}
void OtherAvatar::removeOrb() {
if (qApp->getOverlays().isAddedOverlay(_otherAvatarOrbMeshPlaceholderID)) {
if (!_otherAvatarOrbMeshPlaceholderID.isNull()) {
qApp->getOverlays().deleteOverlay(_otherAvatarOrbMeshPlaceholderID);
_otherAvatarOrbMeshPlaceholderID = UNKNOWN_OVERLAY_ID;
}
}
void OtherAvatar::updateOrbPosition() {
if (_otherAvatarOrbMeshPlaceholder != nullptr) {
_otherAvatarOrbMeshPlaceholder->setWorldPosition(getHead()->getPosition());
if (_otherAvatarOrbMeshPlaceholderID.isNull()) {
_otherAvatarOrbMeshPlaceholderID = qApp->getOverlays().addOverlay(_otherAvatarOrbMeshPlaceholder);
}
}
}
void OtherAvatar::createOrb() {
if (_otherAvatarOrbMeshPlaceholderID == UNKNOWN_OVERLAY_ID ||
!qApp->getOverlays().isAddedOverlay(_otherAvatarOrbMeshPlaceholderID)) {
if (_otherAvatarOrbMeshPlaceholderID.isNull()) {
_otherAvatarOrbMeshPlaceholder = std::make_shared<Sphere3DOverlay>();
_otherAvatarOrbMeshPlaceholder->setAlpha(1.0f);
_otherAvatarOrbMeshPlaceholder->setColor({ 0xFF, 0x00, 0xFF });

View file

@ -926,7 +926,7 @@ void Rig::computeMotionAnimationState(float deltaTime, const glm::vec3& worldPos
// compute blend based on velocity
const float JUMP_SPEED = 3.5f;
float alpha = glm::clamp(-_lastVelocity.y / JUMP_SPEED, -1.0f, 1.0f) + 1.0f;
float alpha = glm::clamp(-workingVelocity.y / JUMP_SPEED, -1.0f, 1.0f) + 1.0f;
_animVars.set("inAirAlpha", alpha);
}

View file

@ -19,16 +19,16 @@ struct InputCalibrationData {
glm::mat4 sensorToWorldMat; // sensor to world
glm::mat4 avatarMat; // avatar to world
glm::mat4 hmdSensorMat; // hmd pos and orientation in sensor space
glm::mat4 defaultCenterEyeMat; // default pose for the center of the eyes in avatar space.
glm::mat4 defaultHeadMat; // default pose for head joint in avatar space
glm::mat4 defaultSpine2; // default pose for spine2 joint in avatar space
glm::mat4 defaultHips; // default pose for hips joint in avatar space
glm::mat4 defaultLeftFoot; // default pose for leftFoot joint in avatar space
glm::mat4 defaultRightFoot; // default pose for rightFoot joint in avatar space
glm::mat4 defaultRightArm; // default pose for rightArm joint in avatar space
glm::mat4 defaultLeftArm; // default pose for leftArm joint in avatar space
glm::mat4 defaultRightHand; // default pose for rightHand joint in avatar space
glm::mat4 defaultLeftHand; // default pose for leftHand joint in avatar space
glm::mat4 defaultCenterEyeMat; // default pose for the center of the eyes in sensor space.
glm::mat4 defaultHeadMat; // default pose for head joint in sensor space
glm::mat4 defaultSpine2; // default pose for spine2 joint in sensor space
glm::mat4 defaultHips; // default pose for hips joint in sensor space
glm::mat4 defaultLeftFoot; // default pose for leftFoot joint in sensor space
glm::mat4 defaultRightFoot; // default pose for rightFoot joint in sensor space
glm::mat4 defaultRightArm; // default pose for rightArm joint in sensor space
glm::mat4 defaultLeftArm; // default pose for leftArm joint in sensor space
glm::mat4 defaultRightHand; // default pose for rightHand joint in sensor space
glm::mat4 defaultLeftHand; // default pose for leftHand joint in sensor space
};
enum class ChannelType {

View file

@ -527,8 +527,8 @@ bool UserInputMapper::applyRoute(const Route::Pointer& route, bool force) {
}
// If the source hasn't been written yet, defer processing of this route
auto source = route->source;
auto sourceInput = source->getInput();
auto& source = route->source;
auto& sourceInput = source->getInput();
if (sourceInput.device == STANDARD_DEVICE && !force && source->writeable()) {
if (debugRoutes && route->debug) {
qCDebug(controllers) << "Source not yet written, deferring";
@ -559,7 +559,7 @@ bool UserInputMapper::applyRoute(const Route::Pointer& route, bool force) {
return true;
}
auto destination = route->destination;
auto& destination = route->destination;
// THis could happen if the route destination failed to create
// FIXME: Maybe do not create the route if the destination failed and avoid this case ?
if (!destination) {

View file

@ -382,6 +382,7 @@ void EntityTreeRenderer::updateChangedEntities(const render::ScenePointer& scene
const auto& views = _viewState->getConicalViews();
PrioritySortUtil::PriorityQueue<SortableRenderer> sortedRenderables(views);
sortedRenderables.reserve(_renderablesToUpdate.size());
{
PROFILE_RANGE_EX(simulation_physics, "SortRenderables", 0xffff00ff, (uint64_t)_renderablesToUpdate.size());
std::unordered_map<EntityItemID, EntityRendererPointer>::iterator itr = _renderablesToUpdate.begin();
@ -405,11 +406,14 @@ void EntityTreeRenderer::updateChangedEntities(const render::ScenePointer& scene
// process the sorted renderables
size_t numSorted = sortedRenderables.size();
while (!sortedRenderables.empty() && usecTimestampNow() < expiry) {
const auto renderable = sortedRenderables.top().getRenderer();
const auto& sortedRenderablesVector = sortedRenderables.getSortedVector();
for (const auto& sortedRenderable : sortedRenderablesVector) {
if (usecTimestampNow() > expiry) {
break;
}
const auto& renderable = sortedRenderable.getRenderer();
renderable->updateInScene(scene, transaction);
_renderablesToUpdate.erase(renderable->getEntity()->getID());
sortedRenderables.pop();
}
// compute average per-renderable update cost

View file

@ -13,6 +13,7 @@
#include <glm/detail/type_vec.hpp>
#include "GpuHelpers.h"
#include "GLMHelpers.h"
namespace graphics {
class Mesh;
@ -55,18 +56,16 @@ namespace buffer_helpers {
tangent = glm::clamp(tangent, -1.0f, 1.0f);
normal *= 511.0f;
tangent *= 511.0f;
normal = glm::round(normal);
tangent = glm::round(tangent);
glm::detail::i10i10i10i2 normalStruct;
glm::detail::i10i10i10i2 tangentStruct;
normalStruct.data.x = int(normal.x);
normalStruct.data.y = int(normal.y);
normalStruct.data.z = int(normal.z);
normalStruct.data.x = fastLrintf(normal.x);
normalStruct.data.y = fastLrintf(normal.y);
normalStruct.data.z = fastLrintf(normal.z);
normalStruct.data.w = 0;
tangentStruct.data.x = int(tangent.x);
tangentStruct.data.y = int(tangent.y);
tangentStruct.data.z = int(tangent.z);
tangentStruct.data.x = fastLrintf(tangent.x);
tangentStruct.data.y = fastLrintf(tangent.y);
tangentStruct.data.z = fastLrintf(tangent.z);
tangentStruct.data.w = 0;
packedNormal = normalStruct.pack;
packedTangent = tangentStruct.pack;

View file

@ -79,33 +79,43 @@ void AABox::setBox(const glm::vec3& corner, const glm::vec3& scale) {
glm::vec3 AABox::getFarthestVertex(const glm::vec3& normal) const {
glm::vec3 result = _corner;
if (normal.x > 0.0f) {
result.x += _scale.x;
}
if (normal.y > 0.0f) {
result.y += _scale.y;
}
if (normal.z > 0.0f) {
result.z += _scale.z;
}
// This is a branchless version of:
//if (normal.x > 0.0f) {
// result.x += _scale.x;
//}
//if (normal.y > 0.0f) {
// result.y += _scale.y;
//}
//if (normal.z > 0.0f) {
// result.z += _scale.z;
//}
float blend = (float)(normal.x > 0.0f);
result.x += blend * _scale.x + (1.0f - blend) * 0.0f;
blend = (float)(normal.y > 0.0f);
result.y += blend * _scale.y + (1.0f - blend) * 0.0f;
blend = (float)(normal.z > 0.0f);
result.z += blend * _scale.z + (1.0f - blend) * 0.0f;
return result;
}
glm::vec3 AABox::getNearestVertex(const glm::vec3& normal) const {
glm::vec3 result = _corner;
if (normal.x < 0.0f) {
result.x += _scale.x;
}
if (normal.y < 0.0f) {
result.y += _scale.y;
}
if (normal.z < 0.0f) {
result.z += _scale.z;
}
// This is a branchless version of:
//if (normal.x < 0.0f) {
// result.x += _scale.x;
//}
//if (normal.y < 0.0f) {
// result.y += _scale.y;
//}
//if (normal.z < 0.0f) {
// result.z += _scale.z;
//}
float blend = (float)(normal.x < 0.0f);
result.x += blend * _scale.x + (1.0f - blend) * 0.0f;
blend = (float)(normal.y < 0.0f);
result.y += blend * _scale.y + (1.0f - blend) * 0.0f;
blend = (float)(normal.z < 0.0f);
result.z += blend * _scale.z + (1.0f - blend) * 0.0f;
return result;
}
@ -459,28 +469,6 @@ AABox AABox::clamp(float min, float max) const {
return AABox(clampedCorner, clampedScale);
}
AABox& AABox::operator += (const glm::vec3& point) {
if (isInvalid()) {
_corner = glm::min(_corner, point);
} else {
glm::vec3 maximum(_corner + _scale);
_corner = glm::min(_corner, point);
maximum = glm::max(maximum, point);
_scale = maximum - _corner;
}
return (*this);
}
AABox& AABox::operator += (const AABox& box) {
if (!box.isInvalid()) {
(*this) += box._corner;
(*this) += box.calcTopFarLeft();
}
return (*this);
}
void AABox::embiggen(float scale) {
_corner += scale * (-0.5f * _scale);
_scale *= scale;

View file

@ -85,8 +85,23 @@ public:
AABox clamp(const glm::vec3& min, const glm::vec3& max) const;
AABox clamp(float min, float max) const;
AABox& operator += (const glm::vec3& point);
AABox& operator += (const AABox& box);
inline AABox& operator+=(const glm::vec3& point) {
bool valid = !isInvalid();
glm::vec3 maximum = glm::max(_corner + _scale, point);
_corner = glm::min(_corner, point);
if (valid) {
_scale = maximum - _corner;
}
return (*this);
}
inline AABox& operator+=(const AABox& box) {
if (!box.isInvalid()) {
(*this) += box._corner;
(*this) += box.calcTopFarLeft();
}
return (*this);
}
// Translate the AABox just moving the corner
void translate(const glm::vec3& translation) { _corner += translation; }
@ -114,7 +129,7 @@ public:
static const glm::vec3 INFINITY_VECTOR;
bool isInvalid() const { return _corner == INFINITY_VECTOR; }
bool isInvalid() const { return _corner.x == std::numeric_limits<float>::infinity(); }
void clear() { _corner = INFINITY_VECTOR; _scale = glm::vec3(0.0f); }

View file

@ -44,7 +44,7 @@ const float DEFAULT_AVATAR_RIGHTHAND_MASS = 2.0f;
// Used when avatar is missing joints... (avatar space)
const glm::quat DEFAULT_AVATAR_MIDDLE_EYE_ROT { Quaternions::Y_180 };
const glm::vec3 DEFAULT_AVATAR_MIDDLE_EYE_POS { 0.0f, 0.6f, 0.0f };
const glm::vec3 DEFAULT_AVATAR_HEAD_TO_MIDDLE_EYE_OFFSET = { 0.0f, 0.06f, -0.09f };
const glm::vec3 DEFAULT_AVATAR_HEAD_POS { 0.0f, 0.53f, 0.0f };
const glm::quat DEFAULT_AVATAR_HEAD_ROT { Quaternions::Y_180 };
const glm::vec3 DEFAULT_AVATAR_RIGHTARM_POS { -0.134824f, 0.396348f, -0.0515777f };

View file

@ -316,4 +316,17 @@ inline void glm_mat4u_mul(const glm::mat4& m1, const glm::mat4& m2, glm::mat4& r
#endif
}
// convert float to int, using round-to-nearest-even (undefined on overflow)
inline int fastLrintf(float x) {
#if GLM_ARCH & GLM_ARCH_SSE2_BIT
return _mm_cvt_ss2si(_mm_set_ss(x));
#else
// return lrintf(x);
static_assert(std::numeric_limits<double>::is_iec559, "Requires IEEE-754 double precision format");
union { double d; int64_t i; } bits = { (double)x };
bits.d += (3ULL << 51);
return (int)bits.i;
#endif
}
#endif // hifi_GLMHelpers_h

View file

@ -12,7 +12,6 @@
#define hifi_PrioritySortUtil_h
#include <glm/glm.hpp>
#include <queue>
#include "NumericalConstants.h"
#include "shared/ConicalViewFrustum.h"
@ -75,7 +74,6 @@ namespace PrioritySortUtil {
void setPriority(float priority) { _priority = priority; }
float getPriority() const { return _priority; }
bool operator<(const Sortable& other) const { return _priority < other._priority; }
private:
float _priority { 0.0f };
};
@ -97,14 +95,18 @@ namespace PrioritySortUtil {
_ageWeight = ageWeight;
}
size_t size() const { return _queue.size(); }
size_t size() const { return _vector.size(); }
void push(T thing) {
thing.setPriority(computePriority(thing));
_queue.push(thing);
_vector.push_back(thing);
}
void reserve(size_t num) {
_vector.reserve(num);
}
const std::vector<T>& getSortedVector() {
std::sort(_vector.begin(), _vector.end(), [](const T& left, const T& right) { return left.getPriority() > right.getPriority(); });
return _vector;
}
const T& top() const { return _queue.top(); }
void pop() { return _queue.pop(); }
bool empty() const { return _queue.empty(); }
private:
@ -153,7 +155,7 @@ namespace PrioritySortUtil {
}
ConicalViewFrustums _views;
std::priority_queue<T> _queue;
std::vector<T> _vector;
float _angularWeight { DEFAULT_ANGULAR_COEF };
float _centerWeight { DEFAULT_CENTER_COEF };
float _ageWeight { DEFAULT_AGE_COEF };

View file

@ -168,12 +168,13 @@ void AACubeTests::rayVsParabolaPerformance() {
glm::vec3 origin(0.0f);
glm::vec3 direction = glm::normalize(glm::vec3(1.0f));
glm::vec3 invDirection = 1.0f / direction;
float distance;
BoxFace face;
glm::vec3 normal;
auto start = std::chrono::high_resolution_clock::now();
for (auto& cube : cubes) {
if (cube.findRayIntersection(origin, direction, distance, face, normal)) {
if (cube.findRayIntersection(origin, direction, invDirection, distance, face, normal)) {
numRayHits++;
}
}

View file

@ -214,3 +214,39 @@ void GLMHelpersTests::testGenerateBasisVectors() {
QCOMPARE_WITH_ABS_ERROR(w, z, EPSILON);
}
}
void GLMHelpersTests::roundPerf() {
const int NUM_VECS = 1000000;
const float MAX_VEC = 500.0f;
std::vector<glm::vec3> vecs;
vecs.reserve(NUM_VECS);
for (int i = 0; i < NUM_VECS; i++) {
vecs.emplace_back(randFloatInRange(-MAX_VEC, MAX_VEC), randFloatInRange(-MAX_VEC, MAX_VEC), randFloatInRange(-MAX_VEC, MAX_VEC));
}
std::vector<glm::vec3> vecs2 = vecs;
std::vector<glm::vec3> originalVecs = vecs;
auto start = std::chrono::high_resolution_clock::now();
for (auto& vec : vecs) {
vec = glm::round(vec);
}
auto glmTime = std::chrono::high_resolution_clock::now() - start;
start = std::chrono::high_resolution_clock::now();
for (auto& vec : vecs2) {
vec = glm::vec3(fastLrintf(vec.x), fastLrintf(vec.y), fastLrintf(vec.z));
}
auto manualTime = std::chrono::high_resolution_clock::now() - start;
bool identical = true;
for (int i = 0; i < vecs.size(); i++) {
identical &= vecs[i] == vecs2[i];
if (vecs[i] != vecs2[i]) {
qDebug() << "glm: " << vecs[i].x << vecs[i].y << vecs[i].z << ", manual: " << vecs2[i].x << vecs2[i].y << vecs2[i].z;
qDebug() << "original: " << originalVecs[i].x << originalVecs[i].y << originalVecs[i].z;
break;
}
}
qDebug() << "ratio: " << (float)glmTime.count() / (float)manualTime.count() << ", identical: " << identical;
}

View file

@ -22,6 +22,7 @@ private slots:
void testSixByteOrientationCompression();
void testSimd();
void testGenerateBasisVectors();
void roundPerf();
};
float getErrorDifference(const float& a, const float& b);