Merge pull request #6981 from howard-stearns/animate-iff-visible-with-step2-billboard-removal

Animate iff visible with step2 billboard removal
This commit is contained in:
Brad Hefta-Gaub 2016-02-01 13:54:25 -08:00
commit 711787a997
12 changed files with 46 additions and 210 deletions

View file

@ -181,7 +181,6 @@ using namespace std;
static QTimer locationUpdateTimer;
static QTimer balanceUpdateTimer;
static QTimer identityPacketTimer;
static QTimer billboardPacketTimer;
static QTimer pingTimer;
static const QString SNAPSHOT_EXTENSION = ".jpg";
@ -632,10 +631,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) :
connect(&identityPacketTimer, &QTimer::timeout, getMyAvatar(), &MyAvatar::sendIdentityPacket);
identityPacketTimer.start(AVATAR_IDENTITY_PACKET_SEND_INTERVAL_MSECS);
// send the billboard packet for our avatar every few seconds
connect(&billboardPacketTimer, &QTimer::timeout, getMyAvatar(), &MyAvatar::sendBillboardPacket);
billboardPacketTimer.start(AVATAR_BILLBOARD_PACKET_SEND_INTERVAL_MSECS);
QString cachePath = QStandardPaths::writableLocation(QStandardPaths::DataLocation);
QNetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance();
QNetworkDiskCache* cache = new QNetworkDiskCache();
@ -1032,7 +1027,6 @@ void Application::cleanupBeforeQuit() {
locationUpdateTimer.stop();
balanceUpdateTimer.stop();
identityPacketTimer.stop();
billboardPacketTimer.stop();
pingTimer.stop();
QMetaObject::invokeMethod(&_settingsTimer, "stop", Qt::BlockingQueuedConnection);
@ -3538,23 +3532,6 @@ glm::vec3 Application::getAvatarPosition() const {
return getMyAvatar()->getPosition();
}
QImage Application::renderAvatarBillboard(RenderArgs* renderArgs) {
const int BILLBOARD_SIZE = 64;
// Need to make sure the gl context is current here
_offscreenContext->makeCurrent();
renderArgs->_renderMode = RenderArgs::DEFAULT_RENDER_MODE;
renderRearViewMirror(renderArgs, QRect(0, 0, BILLBOARD_SIZE, BILLBOARD_SIZE), true);
auto primaryFbo = DependencyManager::get<FramebufferCache>()->getPrimaryFramebuffer();
QImage image(BILLBOARD_SIZE, BILLBOARD_SIZE, QImage::Format_ARGB32);
renderArgs->_context->downloadFramebuffer(primaryFbo, glm::ivec4(0, 0, BILLBOARD_SIZE, BILLBOARD_SIZE), image);
return image;
}
ViewFrustum* Application::getViewFrustum() {
#ifdef DEBUG
if (QThread::currentThread() == activeRenderingThread) {
@ -3684,7 +3661,7 @@ namespace render {
}
void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool selfAvatarOnly, bool billboard) {
void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool selfAvatarOnly) {
// FIXME: This preRender call is temporary until we create a separate render::scene for the mirror rendering.
// Then we can move this logic into the Avatar::simulate call.
@ -3750,18 +3727,6 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se
});
}
if (!billboard) {
DependencyManager::get<DeferredLightingEffect>()->setAmbientLightMode(getRenderAmbientLight());
auto skyStage = DependencyManager::get<SceneScriptingInterface>()->getSkyStage();
DependencyManager::get<DeferredLightingEffect>()->setGlobalLight(skyStage->getSunLight()->getDirection(), skyStage->getSunLight()->getColor(), skyStage->getSunLight()->getIntensity(), skyStage->getSunLight()->getAmbientIntensity());
auto skybox = model::SkyboxPointer();
if (skyStage->getBackgroundMode() == model::SunSkyStage::SKY_BOX) {
skybox = skyStage->getSkybox();
}
DependencyManager::get<DeferredLightingEffect>()->setGlobalSkybox(skybox);
}
{
PerformanceTimer perfTimer("SceneProcessPendingChanges");
_main3DScene->enqueuePendingChanges(pendingChanges);
@ -3785,7 +3750,7 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se
activeRenderingThread = nullptr;
}
void Application::renderRearViewMirror(RenderArgs* renderArgs, const QRect& region, bool billboard) {
void Application::renderRearViewMirror(RenderArgs* renderArgs, const QRect& region) {
auto originalViewport = renderArgs->_viewport;
// Grab current viewport to reset it at the end
@ -3795,12 +3760,7 @@ void Application::renderRearViewMirror(RenderArgs* renderArgs, const QRect& regi
auto myAvatar = getMyAvatar();
// bool eyeRelativeCamera = false;
if (billboard) {
fov = BILLBOARD_FIELD_OF_VIEW; // degees
_mirrorCamera.setPosition(myAvatar->getPosition() +
myAvatar->getOrientation() * glm::vec3(0.0f, 0.0f, -1.0f) * BILLBOARD_DISTANCE * myAvatar->getScale());
} else if (!AvatarInputs::getInstance()->mirrorZoomed()) {
if (!AvatarInputs::getInstance()->mirrorZoomed()) {
_mirrorCamera.setPosition(myAvatar->getChestPosition() +
myAvatar->getOrientation() * glm::vec3(0.0f, 0.0f, -1.0f) * MIRROR_REARVIEW_BODY_DISTANCE * myAvatar->getScale());
@ -3829,20 +3789,15 @@ void Application::renderRearViewMirror(RenderArgs* renderArgs, const QRect& regi
// set the bounds of rear mirror view
gpu::Vec4i viewport;
if (billboard) {
viewport = gpu::Vec4i(0, 0, region.width(), region.height());
} else {
// if not rendering the billboard, the region is in device independent coordinates; must convert to device
float ratio = (float)QApplication::desktop()->windowHandle()->devicePixelRatio() * getRenderResolutionScale();
int width = region.width() * ratio;
int height = region.height() * ratio;
viewport = gpu::Vec4i(0, 0, width, height);
}
// the region is in device independent coordinates; must convert to device
float ratio = (float)QApplication::desktop()->windowHandle()->devicePixelRatio() * getRenderResolutionScale();
int width = region.width() * ratio;
int height = region.height() * ratio;
gpu::Vec4i viewport = gpu::Vec4i(0, 0, width, height);
renderArgs->_viewport = viewport;
// render rear mirror view
displaySide(renderArgs, _mirrorCamera, true, billboard);
displaySide(renderArgs, _mirrorCamera, true);
renderArgs->_viewport = originalViewport;
}

View file

@ -168,8 +168,6 @@ public:
virtual controller::ScriptingInterface* getControllerScriptingInterface() { return _controllerScriptingInterface; }
virtual void registerScriptEngineWithApplicationServices(ScriptEngine* scriptEngine) override;
QImage renderAvatarBillboard(RenderArgs* renderArgs);
virtual ViewFrustum* getCurrentViewFrustum() { return getDisplayViewFrustum(); }
virtual QThread* getMainThread() { return thread(); }
virtual PickRay computePickRay(float x, float y) const;
@ -344,7 +342,7 @@ private:
glm::vec3 getSunDirection();
void renderRearViewMirror(RenderArgs* renderArgs, const QRect& region, bool billboard = false);
void renderRearViewMirror(RenderArgs* renderArgs, const QRect& region);
int sendNackPackets();
@ -357,7 +355,7 @@ private:
void initializeAcceptedFiles();
int getRenderAmbientLight() const;
void displaySide(RenderArgs* renderArgs, Camera& whichCamera, bool selfAvatarOnly = false, bool billboard = false);
void displaySide(RenderArgs* renderArgs, Camera& whichCamera, bool selfAvatarOnly = false);
bool importSVOFromURL(const QString& urlString);

View file

@ -9,7 +9,6 @@
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#include <avatar/AvatarManager.h>
#include <SettingHandle.h>
#include <Util.h>
@ -34,7 +33,6 @@ void LODManager::setRenderDistanceInverseHighLimit(float newValue) {
}
LODManager::LODManager() {
calculateAvatarLODDistanceMultiplier();
setRenderDistanceInverseHighLimit(renderDistanceInverseHighLimit.get());
setRenderDistanceInverseLowLimit(1.0f / (float)TREE_SCALE);
@ -182,7 +180,6 @@ void LODManager::autoAdjustLOD(float currentFPS) {
}
if (changed) {
calculateAvatarLODDistanceMultiplier();
auto lodToolsDialog = DependencyManager::get<DialogsManager>()->getLodToolsDialog();
if (lodToolsDialog) {
lodToolsDialog->reloadSliders();
@ -292,11 +289,6 @@ bool LODManager::shouldRender(const RenderArgs* args, const AABox& bounds) {
void LODManager::setOctreeSizeScale(float sizeScale) {
_octreeSizeScale = sizeScale;
calculateAvatarLODDistanceMultiplier();
}
void LODManager::calculateAvatarLODDistanceMultiplier() {
_avatarLODDistanceMultiplier = AVATAR_TO_ENTITY_RATIO / (_octreeSizeScale / DEFAULT_OCTREE_SIZE_SCALE);
}
void LODManager::setBoundaryLevelAdjust(int boundaryLevelAdjust) {

View file

@ -46,10 +46,6 @@ const float ADJUST_LOD_UP_BY = 1.1f;
const float ADJUST_LOD_MIN_SIZE_SCALE = 1.0f;
const float ADJUST_LOD_MAX_SIZE_SCALE = DEFAULT_OCTREE_SIZE_SCALE;
// The ratio of "visibility" of avatars to other content. A value larger than 1 will mean Avatars "cull" later than entities
// do. But both are still culled using the same angular size logic.
const float AVATAR_TO_ENTITY_RATIO = 2.0f;
class RenderArgs;
class AABox;
@ -68,8 +64,6 @@ public:
Q_INVOKABLE void setHMDLODDecreaseFPS(float value) { _hmdLODDecreaseFPS = value; }
Q_INVOKABLE float getHMDLODDecreaseFPS() const { return _hmdLODDecreaseFPS; }
Q_INVOKABLE float getHMDLODIncreaseFPS() const { return glm::min(_hmdLODDecreaseFPS + INCREASE_LOD_GAP, MAX_LIKELY_HMD_FPS); }
Q_INVOKABLE float getAvatarLODDistanceMultiplier() const { return _avatarLODDistanceMultiplier; }
// User Tweakable LOD Items
Q_INVOKABLE QString getLODFeedbackText();
@ -116,13 +110,11 @@ signals:
private:
LODManager();
void calculateAvatarLODDistanceMultiplier();
bool _automaticLODAdjust = true;
float _desktopLODDecreaseFPS = DEFAULT_DESKTOP_LOD_DOWN_FPS;
float _hmdLODDecreaseFPS = DEFAULT_HMD_LOD_DOWN_FPS;
float _avatarLODDistanceMultiplier;
float _octreeSizeScale = DEFAULT_OCTREE_SIZE_SCALE;
int _boundaryLevelAdjust = 0;

View file

@ -94,7 +94,6 @@ Avatar::Avatar(RigPointer rig) :
_worldUpDirection(DEFAULT_UP_DIRECTION),
_moving(false),
_initialized(false),
_shouldRenderBillboard(true),
_voiceSphereID(GeometryCache::UNKNOWN_ID)
{
// we may have been created in the network thread, but we live in the main thread
@ -115,13 +114,10 @@ Avatar::~Avatar() {
}
}
const float BILLBOARD_LOD_DISTANCE = 40.0f;
void Avatar::init() {
getHead()->init();
_skeletonModel.init();
_initialized = true;
_shouldRenderBillboard = (getLODDistance() >= BILLBOARD_LOD_DISTANCE);
}
glm::vec3 Avatar::getChestPosition() const {
@ -141,12 +137,14 @@ glm::quat Avatar::getWorldAlignedOrientation () const {
}
AABox Avatar::getBounds() const {
return AABox();
}
float Avatar::getLODDistance() const {
return DependencyManager::get<LODManager>()->getAvatarLODDistanceMultiplier() *
glm::distance(qApp->getCamera()->getPosition(), getPosition()) / getUniformScale();
// Our skeleton models are rigged, and this method call safely produces the static bounds of the model.
// Except, that getPartBounds produces an infinite, uncentered bounding box when the model is not yet parsed,
// and we want a centered one. NOTE: There is code that may never try to render, and thus never load and get the
// real model bounds, if this is unrealistically small.
if (!_skeletonModel.isRenderable()) {
return AABox(getPosition(), getUniformScale()); // approximately 2m tall, scaled to user request.
}
return _skeletonModel.getPartBounds(0, 0, getPosition(), getOrientation());
}
void Avatar::animateScaleChanges(float deltaTime) {
@ -176,20 +174,22 @@ void Avatar::simulate(float deltaTime) {
}
animateScaleChanges(deltaTime);
// update the billboard render flag
const float BILLBOARD_HYSTERESIS_PROPORTION = 0.1f;
if (_shouldRenderBillboard) {
if (getLODDistance() < BILLBOARD_LOD_DISTANCE * (1.0f - BILLBOARD_HYSTERESIS_PROPORTION)) {
_shouldRenderBillboard = false;
qCDebug(interfaceapp) << "Unbillboarding" << (isMyAvatar() ? "myself" : getSessionUUID()) << "for LOD" << getLODDistance();
// 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());
if (!_shouldAnimate) {
if (visibility > MINIMUM_VISIBILITY_FOR_ON) {
_shouldAnimate = true;
qCDebug(interfaceapp) << "Restoring" << (isMyAvatar() ? "myself" : getSessionUUID()) << "for visibility" << visibility;
}
} else if (getLODDistance() > BILLBOARD_LOD_DISTANCE * (1.0f + BILLBOARD_HYSTERESIS_PROPORTION)) {
_shouldRenderBillboard = true;
qCDebug(interfaceapp) << "Billboarding" << (isMyAvatar() ? "myself" : getSessionUUID()) << "for LOD" << getLODDistance();
} else if (visibility < MAXIMUM_VISIBILITY_FOR_OFF) {
_shouldAnimate = false;
qCDebug(interfaceapp) << "Optimizing" << (isMyAvatar() ? "myself" : getSessionUUID()) << "for visibility" << visibility;
}
// simple frustum check
float boundingRadius = getBillboardSize();
float boundingRadius = getBoundingRadius();
bool inViewFrustum = qApp->getViewFrustum()->sphereInFrustum(getPosition(), boundingRadius) !=
ViewFrustum::OUTSIDE;
@ -198,7 +198,7 @@ void Avatar::simulate(float deltaTime) {
getHand()->simulate(deltaTime, false);
}
if (!_shouldRenderBillboard && !_shouldSkipRender && inViewFrustum) {
if (_shouldAnimate && !_shouldSkipRender && inViewFrustum) {
{
PerformanceTimer perfTimer("skeleton");
_skeletonModel.getRig()->copyJointsFromJointData(_jointData);
@ -214,7 +214,7 @@ void Avatar::simulate(float deltaTime) {
Head* head = getHead();
head->setPosition(headPosition);
head->setScale(getUniformScale());
head->simulate(deltaTime, false, _shouldRenderBillboard);
head->simulate(deltaTime, false, _shouldAnimate);
}
}
@ -389,7 +389,7 @@ void Avatar::render(RenderArgs* renderArgs, const glm::vec3& cameraPosition) {
}
// simple frustum check
float boundingRadius = getBillboardSize();
float boundingRadius = getBoundingRadius();
ViewFrustum* frustum = nullptr;
if (renderArgs->_renderMode == RenderArgs::SHADOW_RENDER_MODE) {
frustum = qApp->getShadowViewFrustum();
@ -567,10 +567,7 @@ void Avatar::renderBody(RenderArgs* renderArgs, ViewFrustum* renderFrustum, floa
fixupModelsInScene();
{
if (_shouldRenderBillboard || !(_skeletonModel.isRenderable() && getHead()->getFaceModel().isRenderable())) {
// render the billboard until both models are loaded
renderBillboard(renderArgs);
} else {
if (_skeletonModel.isRenderable() && getHead()->getFaceModel().isRenderable()) {
getHead()->render(renderArgs, 1.0f, renderFrustum);
}
@ -617,50 +614,8 @@ void Avatar::updateJointMappings() {
// no-op; joint mappings come from skeleton model
}
void Avatar::renderBillboard(RenderArgs* renderArgs) {
// FIXME disabling the billboard because it doesn't appear to work reliably
// the billboard is ending up with a random texture and position.
return;
if (_billboard.isEmpty()) {
return;
}
if (!_billboardTexture) {
// Using a unique URL ensures we don't get another avatar's texture from TextureCache
QUrl uniqueUrl = QUrl(QUuid::createUuid().toString());
_billboardTexture = DependencyManager::get<TextureCache>()->getTexture(
uniqueUrl, DEFAULT_TEXTURE, _billboard);
}
if (!_billboardTexture || !_billboardTexture->isLoaded()) {
return;
}
// rotate about vertical to face the camera
glm::quat rotation = getOrientation();
glm::vec3 cameraVector = glm::inverse(rotation) * (qApp->getCamera()->getPosition() - getPosition());
rotation = rotation * glm::angleAxis(atan2f(-cameraVector.x, -cameraVector.z), glm::vec3(0.0f, 1.0f, 0.0f));
// compute the size from the billboard camera parameters and scale
float size = getBillboardSize();
Transform transform;
transform.setTranslation(getPosition());
transform.setRotation(rotation);
transform.setScale(size);
glm::vec2 topLeft(-1.0f, -1.0f);
glm::vec2 bottomRight(1.0f, 1.0f);
glm::vec2 texCoordTopLeft(0.0f, 0.0f);
glm::vec2 texCoordBottomRight(1.0f, 1.0f);
gpu::Batch& batch = *renderArgs->_batch;
PROFILE_RANGE_BATCH(batch, __FUNCTION__);
batch.setResourceTexture(0, _billboardTexture->getGPUTexture());
DependencyManager::get<GeometryCache>()->bindSimpleProgram(batch, true);
DependencyManager::get<GeometryCache>()->renderQuad(batch, topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight,
glm::vec4(1.0f, 1.0f, 1.0f, 1.0f));
}
float Avatar::getBillboardSize() const {
return getUniformScale() * BILLBOARD_DISTANCE * glm::tan(glm::radians(BILLBOARD_FIELD_OF_VIEW / 2.0f));
float Avatar::getBoundingRadius() const {
return getBounds().getLargestDimension() / 2.0f;
}
#ifdef DEBUG
@ -672,7 +627,7 @@ void debugValue(const QString& str, const glm::vec3& value) {
void debugValue(const QString& str, const float& value) {
if (glm::isnan(value) || glm::isinf(value)) {
qCWarning(interfaceapp) << "debugValue() " << str << value;
}
}
};
#define DEBUG_VALUE(str, value) debugValue(str, value)
#else
@ -693,11 +648,11 @@ glm::vec3 Avatar::getDisplayNamePosition() const {
namePosition += bodyUpDirection * headHeight * SLIGHTLY_ABOVE;
} else {
const float HEAD_PROPORTION = 0.75f;
float billboardSize = getBillboardSize();
float size = getBoundingRadius();
DEBUG_VALUE("_position =", getPosition());
DEBUG_VALUE("billboardSize =", billboardSize);
namePosition = getPosition() + bodyUpDirection * (billboardSize * HEAD_PROPORTION);
DEBUG_VALUE("size =", size);
namePosition = getPosition() + bodyUpDirection * (size * HEAD_PROPORTION);
}
if (glm::any(glm::isnan(namePosition)) || glm::any(glm::isinf(namePosition))) {
@ -1001,12 +956,6 @@ void Avatar::setAttachmentData(const QVector<AttachmentData>& attachmentData) {
*/
}
void Avatar::setBillboard(const QByteArray& billboard) {
AvatarData::setBillboard(billboard);
// clear out any existing billboard texture
_billboardTexture.reset();
}
int Avatar::parseDataFromBuffer(const QByteArray& buffer) {
startUpdate();

View file

@ -38,9 +38,6 @@ namespace render {
static const float SCALING_RATIO = .05f;
static const float SMOOTHING_RATIO = .05f; // 0 < ratio < 1
static const float BILLBOARD_FIELD_OF_VIEW = 30.0f; // degrees
static const float BILLBOARD_DISTANCE = 5.56f; // meters
extern const float CHAT_MESSAGE_SCALE;
extern const float CHAT_MESSAGE_HEIGHT;
@ -119,7 +116,6 @@ public:
virtual void setFaceModelURL(const QUrl& faceModelURL) override;
virtual void setSkeletonModelURL(const QUrl& skeletonModelURL) override;
virtual void setAttachmentData(const QVector<AttachmentData>& attachmentData) override;
virtual void setBillboard(const QByteArray& billboard) override;
void setShowDisplayName(bool showDisplayName);
@ -254,14 +250,11 @@ protected:
private:
bool _initialized;
NetworkTexturePointer _billboardTexture;
bool _shouldRenderBillboard;
bool _shouldAnimate { true };
bool _shouldSkipRender { false };
bool _isLookAtTarget;
void renderBillboard(RenderArgs* renderArgs);
float getBillboardSize() const;
float getBoundingRadius() const;
static int _jointConesID;

View file

@ -33,10 +33,6 @@ void AvatarUpdate::synchronousProcess() {
auto frameCount = qApp->getFrameCount();
_headPose = qApp->getActiveDisplayPlugin()->getHeadPose(frameCount);
if (_updateBillboard) {
DependencyManager::get<AvatarManager>()->getMyAvatar()->doUpdateBillboard();
}
if (!isThreaded()) {
process();
}

View file

@ -22,13 +22,11 @@ class AvatarUpdate : public GenericThread {
public:
AvatarUpdate();
void synchronousProcess();
void setRequestBillboardUpdate(bool needsUpdate) { _updateBillboard = needsUpdate; }
private:
virtual bool process(); // No reason for other classes to invoke this.
quint64 _lastAvatarUpdate; // microsoeconds
quint64 _targetInterval; // microseconds
bool _updateBillboard;
// Goes away if Application::getActiveDisplayPlugin() and friends are made thread safe:
public:

View file

@ -97,7 +97,6 @@ MyAvatar::MyAvatar(RigPointer rig) :
_characterController(this),
_lookAtTargetAvatar(),
_shouldRender(true),
_billboardValid(false),
_eyeContactTarget(LEFT_EYE),
_realWorldFieldOfView("realWorldFieldOfView",
DEFAULT_REAL_WORLD_FIELD_OF_VIEW_DEGREES),
@ -229,7 +228,7 @@ void MyAvatar::reset(bool andReload) {
}
// Reset dynamic state.
_wasPushing = _isPushing = _isBraking = _billboardValid = false;
_wasPushing = _isPushing = _isBraking = false;
_follow.deactivate();
_skeletonModel.reset();
getHead()->reset();
@ -364,9 +363,6 @@ void MyAvatar::simulate(float deltaTime) {
recorder->recordFrame(FRAME_TYPE, toFrame(*this));
}
// consider updating our billboard
maybeUpdateBillboard();
locationChanged();
// if a entity-child of this avatar has moved outside of its queryAACube, update the cube and tell the entity server.
EntityTreeRenderer* entityTreeRenderer = qApp->getEntities();
@ -983,14 +979,12 @@ void MyAvatar::setFaceModelURL(const QUrl& faceModelURL) {
Avatar::setFaceModelURL(faceModelURL);
render::ScenePointer scene = qApp->getMain3DScene();
getHead()->getFaceModel().setVisibleInScene(_prevShouldDrawHead, scene);
_billboardValid = false;
}
void MyAvatar::setSkeletonModelURL(const QUrl& skeletonModelURL) {
Avatar::setSkeletonModelURL(skeletonModelURL);
render::ScenePointer scene = qApp->getMain3DScene();
_billboardValid = false;
_skeletonModel.setVisibleInScene(true, scene);
_headBoneSet.clear();
}
@ -1043,7 +1037,6 @@ void MyAvatar::setAttachmentData(const QVector<AttachmentData>& attachmentData)
return;
}
Avatar::setAttachmentData(attachmentData);
_billboardValid = false;
}
glm::vec3 MyAvatar::getSkeletonPosition() const {
@ -1583,33 +1576,6 @@ bool findAvatarAvatarPenetration(const glm::vec3 positionA, float radiusA, float
return false;
}
void MyAvatar::maybeUpdateBillboard() {
qApp->getAvatarUpdater()->setRequestBillboardUpdate(false);
if (_billboardValid || !(_skeletonModel.isLoadedWithTextures() && getHead()->getFaceModel().isLoadedWithTextures())) {
return;
}
for (auto& model : _attachmentModels) {
if (!model->isLoadedWithTextures()) {
return;
}
}
qApp->getAvatarUpdater()->setRequestBillboardUpdate(true);
}
void MyAvatar::doUpdateBillboard() {
RenderArgs renderArgs(qApp->getGPUContext());
QImage image = qApp->renderAvatarBillboard(&renderArgs);
_billboard.clear();
QBuffer buffer(&_billboard);
buffer.open(QIODevice::WriteOnly);
image.save(&buffer, "PNG");
#ifdef DEBUG
image.save("billboard.png", "PNG");
#endif
_billboardValid = true;
sendBillboardPacket();
}
bool MyAvatar::isHovering() const {
return _characterController.isHovering();
}

View file

@ -223,7 +223,6 @@ public:
static const float ZOOM_MAX;
static const float ZOOM_DEFAULT;
void doUpdateBillboard();
void destroyAnimGraph();
AudioListenerMode getAudioListenerMode() { return _audioListenerMode; }
@ -340,7 +339,6 @@ private:
AvatarWeakPointer _lookAtTargetAvatar;
glm::vec3 _targetAvatarPosition;
bool _shouldRender;
bool _billboardValid;
float _oculusYawOffset;
eyeContactTarget _eyeContactTarget;
@ -355,7 +353,6 @@ private:
glm::vec3 applyScriptedMotor(float deltaTime, const glm::vec3& velocity);
void updatePosition(float deltaTime);
void updateCollisionSound(const glm::vec3& penetration, float deltaTime, float frequency);
void maybeUpdateBillboard();
void initHeadBones();
void initAnimGraph();

View file

@ -1113,7 +1113,7 @@ void Model::deleteGeometry() {
_blendedBlendshapeCoefficients.clear();
}
AABox Model::getPartBounds(int meshIndex, int partIndex, glm::vec3 modelPosition, glm::quat modelOrientation) {
AABox Model::getPartBounds(int meshIndex, int partIndex, glm::vec3 modelPosition, glm::quat modelOrientation) const {
if (!_geometry || !_geometry->isLoaded()) {
return AABox();

View file

@ -89,7 +89,7 @@ public:
bool isVisible() const { return _isVisible; }
void updateRenderItems();
AABox getPartBounds(int meshIndex, int partIndex, glm::vec3 modelPosition, glm::quat modelOrientation);
AABox getPartBounds(int meshIndex, int partIndex, glm::vec3 modelPosition, glm::quat modelOrientation) const;
bool maybeStartBlender();