Merge branch 'master' into plugins

This commit is contained in:
Bradley Austin Davis 2015-07-27 10:09:02 -04:00
commit 3c6416d6b8
11 changed files with 200 additions and 144 deletions

View file

@ -443,36 +443,57 @@ void Avatar::render(RenderArgs* renderArgs, const glm::vec3& cameraPosition) {
_skeletonModel.renderBoundingCollisionShapes(*renderArgs->_batch, 0.7f);
}
// Stack indicator spheres
float indicatorOffset = 0.0f;
if (!_displayName.isEmpty() && _displayNameAlpha != 0.0f) {
const float DISPLAY_NAME_INDICATOR_OFFSET = 0.22f;
indicatorOffset = DISPLAY_NAME_INDICATOR_OFFSET;
}
const float INDICATOR_RADIUS = 0.03f;
const float INDICATOR_INDICATOR_OFFSET = 3.0f * INDICATOR_RADIUS;
// If this is the avatar being looked at, render a little ball above their head
if (_isLookAtTarget && Menu::getInstance()->isOptionChecked(MenuOption::RenderFocusIndicator)) {
const float INDICATOR_OFFSET = 0.22f;
const float INDICATOR_RADIUS = 0.03f;
const glm::vec4 LOOK_AT_INDICATOR_COLOR = { 0.8f, 0.0f, 0.0f, 0.75f };
glm::vec3 position = glm::vec3(_position.x, getDisplayNamePosition().y + indicatorOffset, _position.z);
glm::vec3 position = glm::vec3(_position.x, getDisplayNamePosition().y + INDICATOR_OFFSET, _position.z);
Transform transform;
transform.setTranslation(position);
batch.setModelTransform(transform);
DependencyManager::get<DeferredLightingEffect>()->renderSolidSphere(batch, INDICATOR_RADIUS,
15, 15, LOOK_AT_INDICATOR_COLOR);
indicatorOffset += INDICATOR_INDICATOR_OFFSET;
}
// If the avatar is looking at me, render an indication that they area
if (getHead()->getIsLookingAtMe() && Menu::getInstance()->isOptionChecked(MenuOption::ShowWhosLookingAtMe)) {
const glm::vec4 LOOKING_AT_ME_COLOR = { 0.8f, 0.65f, 0.0f, 0.1f };
glm::vec3 position = glm::vec3(_position.x, getDisplayNamePosition().y + indicatorOffset, _position.z);
Transform transform;
transform.setTranslation(position);
batch.setModelTransform(transform);
DependencyManager::get<DeferredLightingEffect>()->renderSolidSphere(batch, INDICATOR_RADIUS,
15, 15, LOOKING_AT_ME_COLOR);
// If the avatar is looking at me, indicate that they are
if (getHead()->isLookingAtMe() && Menu::getInstance()->isOptionChecked(MenuOption::ShowWhosLookingAtMe)) {
const glm::vec3 LOOKING_AT_ME_COLOR = { 1.0f, 1.0f, 1.0f };
const float LOOKING_AT_ME_ALPHA_START = 0.8f;
const float LOOKING_AT_ME_DURATION = 0.5f; // seconds
quint64 now = usecTimestampNow();
float alpha = LOOKING_AT_ME_ALPHA_START
* (1.0f - ((float)(usecTimestampNow() - getHead()->getLookingAtMeStarted()))
/ (LOOKING_AT_ME_DURATION * (float)USECS_PER_SECOND));
if (alpha > 0.0f) {
QSharedPointer<NetworkGeometry> geometry = getHead()->getFaceModel().getGeometry();
if (geometry) {
const float DEFAULT_EYE_DIAMETER = 0.048f; // Typical human eye
const float RADIUS_INCREMENT = 0.005f;
Transform transform;
glm::vec3 position = getHead()->getLeftEyePosition();
transform.setTranslation(position);
batch.setModelTransform(transform);
float eyeDiameter = geometry->getFBXGeometry().leftEyeSize;
if (eyeDiameter == 0.0f) {
eyeDiameter = DEFAULT_EYE_DIAMETER;
}
DependencyManager::get<DeferredLightingEffect>()->renderSolidSphere(batch,
eyeDiameter * _scale / 2.0f + RADIUS_INCREMENT, 15, 15, glm::vec4(LOOKING_AT_ME_COLOR, alpha));
position = getHead()->getRightEyePosition();
transform.setTranslation(position);
batch.setModelTransform(transform);
eyeDiameter = geometry->getFBXGeometry().rightEyeSize;
if (eyeDiameter == 0.0f) {
eyeDiameter = DEFAULT_EYE_DIAMETER;
}
DependencyManager::get<DeferredLightingEffect>()->renderSolidSphere(batch,
eyeDiameter * _scale / 2.0f + RADIUS_INCREMENT, 15, 15, glm::vec4(LOOKING_AT_ME_COLOR, alpha));
}
}
}
// quick check before falling into the code below:

View file

@ -56,6 +56,8 @@ Head::Head(Avatar* owningAvatar) :
_deltaLeanForward(0.0f),
_isCameraMoving(false),
_isLookingAtMe(false),
_lookingAtMeStarted(0),
_wasLastLookingAtMe(0),
_faceModel(this),
_leftEyeLookAtID(DependencyManager::get<GeometryCache>()->allocateID()),
_rightEyeLookAtID(DependencyManager::get<GeometryCache>()->allocateID())
@ -320,7 +322,7 @@ glm::quat Head::getFinalOrientationInLocalFrame() const {
}
glm::vec3 Head::getCorrectedLookAtPosition() {
if (_isLookingAtMe) {
if (isLookingAtMe()) {
return _correctedLookAtPosition;
} else {
return getLookAtPosition();
@ -328,10 +330,21 @@ glm::vec3 Head::getCorrectedLookAtPosition() {
}
void Head::setCorrectedLookAtPosition(glm::vec3 correctedLookAtPosition) {
if (!isLookingAtMe()) {
_lookingAtMeStarted = usecTimestampNow();
}
_isLookingAtMe = true;
_wasLastLookingAtMe = usecTimestampNow();
_correctedLookAtPosition = correctedLookAtPosition;
}
bool Head::isLookingAtMe() {
// Allow for outages such as may be encountered during avatar movement
quint64 now = usecTimestampNow();
const quint64 LOOKING_AT_ME_GAP_ALLOWED = 1000000; // microseconds
return _isLookingAtMe || (now - _wasLastLookingAtMe) < LOOKING_AT_ME_GAP_ALLOWED;
}
glm::quat Head::getCameraOrientation() const {
// NOTE: Head::getCameraOrientation() is not used for orienting the camera "view" while in Oculus mode, so
// you may wonder why this code is here. This method will be called while in Oculus mode to determine how

View file

@ -52,8 +52,9 @@ public:
void setCorrectedLookAtPosition(glm::vec3 correctedLookAtPosition);
glm::vec3 getCorrectedLookAtPosition();
void clearCorrectedLookAtPosition() { _isLookingAtMe = false; }
bool getIsLookingAtMe() { return _isLookingAtMe; }
bool isLookingAtMe();
quint64 getLookingAtMeStarted() { return _lookingAtMeStarted; }
float getScale() const { return _scale; }
glm::vec3 getPosition() const { return _position; }
const glm::vec3& getEyePosition() const { return _eyePosition; }
@ -139,6 +140,8 @@ private:
bool _isCameraMoving;
bool _isLookingAtMe;
quint64 _lookingAtMeStarted;
quint64 _wasLastLookingAtMe;
FaceModel _faceModel;
glm::vec3 _correctedLookAtPosition;

View file

@ -57,7 +57,7 @@ WebWindowClass::WebWindowClass(const QString& title, const QString& url, int wid
} else {
auto dialogWidget = new QDialog(Application::getInstance()->getWindow(), Qt::Window);
dialogWidget->setWindowTitle(title);
dialogWidget->setMinimumSize(width, height);
dialogWidget->resize(width, height);
connect(dialogWidget, &QDialog::finished, this, &WebWindowClass::hasClosed);
auto layout = new QVBoxLayout(dialogWidget);

View file

@ -2616,10 +2616,17 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping,
buildModelMesh(extracted);
# endif
if (extracted.mesh.isEye) {
if (maxJointIndex == geometry.leftEyeJointIndex) {
geometry.leftEyeSize = extracted.mesh.meshExtents.largestDimension() * offsetScale;
} else {
geometry.rightEyeSize = extracted.mesh.meshExtents.largestDimension() * offsetScale;
}
}
geometry.meshes.append(extracted.mesh);
int meshIndex = geometry.meshes.size() - 1;
meshIDsToMeshIndices.insert(it.key(), meshIndex);
}
// now that all joints have been scanned, compute a collision shape for each joint

View file

@ -232,7 +232,10 @@ public:
int rightHandJointIndex = -1;
int leftToeJointIndex = -1;
int rightToeJointIndex = -1;
float leftEyeSize = 0.0f; // Maximum mesh extents dimension
float rightEyeSize = 0.0f;
QVector<int> humanIKJointIndices;
glm::vec3 palmDirection;

View file

@ -106,36 +106,6 @@ void Batch::drawIndexedInstanced(uint32 nbInstances, Primitive primitiveType, ui
_params.push_back(nbInstances);
}
void Batch::clearFramebuffer(Framebuffer::Masks targets, const Vec4& color, float depth, int stencil, bool enableScissor) {
ADD_COMMAND(clearFramebuffer);
_params.push_back(enableScissor);
_params.push_back(stencil);
_params.push_back(depth);
_params.push_back(color.w);
_params.push_back(color.z);
_params.push_back(color.y);
_params.push_back(color.x);
_params.push_back(targets);
}
void Batch::clearColorFramebuffer(Framebuffer::Masks targets, const Vec4& color, bool enableScissor) {
clearFramebuffer(targets & Framebuffer::BUFFER_COLORS, color, 1.0f, 0, enableScissor);
}
void Batch::clearDepthFramebuffer(float depth, bool enableScissor) {
clearFramebuffer(Framebuffer::BUFFER_DEPTH, Vec4(0.0f), depth, 0, enableScissor);
}
void Batch::clearStencilFramebuffer(int stencil, bool enableScissor) {
clearFramebuffer(Framebuffer::BUFFER_STENCIL, Vec4(0.0f), 1.0f, stencil, enableScissor);
}
void Batch::clearDepthStencilFramebuffer(float depth, int stencil, bool enableScissor) {
clearFramebuffer(Framebuffer::BUFFER_DEPTHSTENCIL, Vec4(0.0f), depth, stencil, enableScissor);
}
void Batch::setInputFormat(const Stream::FormatPointer& format) {
ADD_COMMAND(setInputFormat);
@ -255,6 +225,35 @@ void Batch::setFramebuffer(const FramebufferPointer& framebuffer) {
}
void Batch::clearFramebuffer(Framebuffer::Masks targets, const Vec4& color, float depth, int stencil, bool enableScissor) {
ADD_COMMAND(clearFramebuffer);
_params.push_back(enableScissor);
_params.push_back(stencil);
_params.push_back(depth);
_params.push_back(color.w);
_params.push_back(color.z);
_params.push_back(color.y);
_params.push_back(color.x);
_params.push_back(targets);
}
void Batch::clearColorFramebuffer(Framebuffer::Masks targets, const Vec4& color, bool enableScissor) {
clearFramebuffer(targets & Framebuffer::BUFFER_COLORS, color, 1.0f, 0, enableScissor);
}
void Batch::clearDepthFramebuffer(float depth, bool enableScissor) {
clearFramebuffer(Framebuffer::BUFFER_DEPTH, Vec4(0.0f), depth, 0, enableScissor);
}
void Batch::clearStencilFramebuffer(int stencil, bool enableScissor) {
clearFramebuffer(Framebuffer::BUFFER_STENCIL, Vec4(0.0f), 1.0f, stencil, enableScissor);
}
void Batch::clearDepthStencilFramebuffer(float depth, int stencil, bool enableScissor) {
clearFramebuffer(Framebuffer::BUFFER_DEPTHSTENCIL, Vec4(0.0f), depth, stencil, enableScissor);
}
void Batch::blit(const FramebufferPointer& src, const Vec4i& srcViewport,
const FramebufferPointer& dst, const Vec4i& dstViewport) {
ADD_COMMAND(blit);

View file

@ -54,15 +54,6 @@ public:
void drawInstanced(uint32 nbInstances, Primitive primitiveType, uint32 nbVertices, uint32 startVertex = 0, uint32 startInstance = 0);
void drawIndexedInstanced(uint32 nbInstances, Primitive primitiveType, uint32 nbIndices, uint32 startIndex = 0, uint32 startInstance = 0);
// Clear framebuffer layers
// Targets can be any of the render buffers contained in the Framebuffer
// Optionally the scissor test can be enabled locally for this command and to restrict the clearing command to the pixels contained in the scissor rectangle
void clearFramebuffer(Framebuffer::Masks targets, const Vec4& color, float depth, int stencil, bool enableScissor = false);
void clearColorFramebuffer(Framebuffer::Masks targets, const Vec4& color, bool enableScissor = false); // not a command, just a shortcut for clearFramebuffer, mask out targets to make sure it touches only color targets
void clearDepthFramebuffer(float depth, bool enableScissor = false); // not a command, just a shortcut for clearFramebuffer, it touches only depth target
void clearStencilFramebuffer(int stencil, bool enableScissor = false); // not a command, just a shortcut for clearFramebuffer, it touches only stencil target
void clearDepthStencilFramebuffer(float depth, int stencil, bool enableScissor = false); // not a command, just a shortcut for clearFramebuffer, it touches depth and stencil target
// Input Stage
// InputFormat
// InputBuffers
@ -105,8 +96,17 @@ public:
// Framebuffer Stage
void setFramebuffer(const FramebufferPointer& framebuffer);
void blit(const FramebufferPointer& src, const Vec4i& srcViewport,
const FramebufferPointer& dst, const Vec4i& dstViewport);
// Clear framebuffer layers
// Targets can be any of the render buffers contained in the currnetly bound Framebuffer
// Optionally the scissor test can be enabled locally for this command and to restrict the clearing command to the pixels contained in the scissor rectangle
void clearFramebuffer(Framebuffer::Masks targets, const Vec4& color, float depth, int stencil, bool enableScissor = false);
void clearColorFramebuffer(Framebuffer::Masks targets, const Vec4& color, bool enableScissor = false); // not a command, just a shortcut for clearFramebuffer, mask out targets to make sure it touches only color targets
void clearDepthFramebuffer(float depth, bool enableScissor = false); // not a command, just a shortcut for clearFramebuffer, it touches only depth target
void clearStencilFramebuffer(int stencil, bool enableScissor = false); // not a command, just a shortcut for clearFramebuffer, it touches only stencil target
void clearDepthStencilFramebuffer(float depth, int stencil, bool enableScissor = false); // not a command, just a shortcut for clearFramebuffer, it touches depth and stencil target
void blit(const FramebufferPointer& src, const Vec4i& srcViewport, const FramebufferPointer& dst, const Vec4i& dstViewport);
// Query Section
void beginQuery(const QueryPointer& query);
@ -162,8 +162,6 @@ public:
COMMAND_drawInstanced,
COMMAND_drawIndexedInstanced,
COMMAND_clearFramebuffer,
COMMAND_setInputFormat,
COMMAND_setInputBuffer,
COMMAND_setIndexBuffer,
@ -181,6 +179,7 @@ public:
COMMAND_setResourceTexture,
COMMAND_setFramebuffer,
COMMAND_clearFramebuffer,
COMMAND_blit,
COMMAND_beginQuery,

View file

@ -21,7 +21,6 @@ GLBackend::CommandCall GLBackend::_commandCalls[Batch::NUM_COMMANDS] =
(&::gpu::GLBackend::do_drawIndexed),
(&::gpu::GLBackend::do_drawInstanced),
(&::gpu::GLBackend::do_drawIndexedInstanced),
(&::gpu::GLBackend::do_clearFramebuffer),
(&::gpu::GLBackend::do_setInputFormat),
(&::gpu::GLBackend::do_setInputBuffer),
@ -40,6 +39,7 @@ GLBackend::CommandCall GLBackend::_commandCalls[Batch::NUM_COMMANDS] =
(&::gpu::GLBackend::do_setResourceTexture),
(&::gpu::GLBackend::do_setFramebuffer),
(&::gpu::GLBackend::do_clearFramebuffer),
(&::gpu::GLBackend::do_blit),
(&::gpu::GLBackend::do_beginQuery),
@ -246,71 +246,6 @@ void GLBackend::do_drawIndexedInstanced(Batch& batch, uint32 paramOffset) {
(void) CHECK_GL_ERROR();
}
void GLBackend::do_clearFramebuffer(Batch& batch, uint32 paramOffset) {
uint32 masks = batch._params[paramOffset + 7]._uint;
Vec4 color;
color.x = batch._params[paramOffset + 6]._float;
color.y = batch._params[paramOffset + 5]._float;
color.z = batch._params[paramOffset + 4]._float;
color.w = batch._params[paramOffset + 3]._float;
float depth = batch._params[paramOffset + 2]._float;
int stencil = batch._params[paramOffset + 1]._int;
int useScissor = batch._params[paramOffset + 0]._int;
GLuint glmask = 0;
if (masks & Framebuffer::BUFFER_STENCIL) {
glClearStencil(stencil);
glmask |= GL_STENCIL_BUFFER_BIT;
}
if (masks & Framebuffer::BUFFER_DEPTH) {
glClearDepth(depth);
glmask |= GL_DEPTH_BUFFER_BIT;
}
std::vector<GLenum> drawBuffers;
if (masks & Framebuffer::BUFFER_COLORS) {
for (unsigned int i = 0; i < Framebuffer::MAX_NUM_RENDER_BUFFERS; i++) {
if (masks & (1 << i)) {
drawBuffers.push_back(GL_COLOR_ATTACHMENT0 + i);
}
}
if (!drawBuffers.empty()) {
glDrawBuffers(drawBuffers.size(), drawBuffers.data());
glClearColor(color.x, color.y, color.z, color.w);
glmask |= GL_COLOR_BUFFER_BIT;
}
// Force the color mask cache to WRITE_ALL if not the case
do_setStateColorWriteMask(State::ColorMask::WRITE_ALL);
}
// Apply scissor if needed and if not already on
bool doEnableScissor = (useScissor && (!_pipeline._stateCache.scissorEnable));
if (doEnableScissor) {
glEnable(GL_SCISSOR_TEST);
}
glClear(glmask);
// Restore scissor if needed
if (doEnableScissor) {
glDisable(GL_SCISSOR_TEST);
}
// Restore the color draw buffers only if a frmaebuffer is bound
if (_output._framebuffer && !drawBuffers.empty()) {
auto glFramebuffer = syncGPUObject(*_output._framebuffer);
if (glFramebuffer) {
glDrawBuffers(glFramebuffer->_colorBuffers.size(), glFramebuffer->_colorBuffers.data());
}
}
(void) CHECK_GL_ERROR();
}
// TODO: As long as we have gl calls explicitely issued from interface
// code, we need to be able to record and batch these calls. THe long
// term strategy is to get rid of any GL calls in favor of the HIFI GPU API

View file

@ -241,8 +241,6 @@ protected:
void do_drawInstanced(Batch& batch, uint32 paramOffset);
void do_drawIndexedInstanced(Batch& batch, uint32 paramOffset);
void do_clearFramebuffer(Batch& batch, uint32 paramOffset);
// Input Stage
void do_setInputFormat(Batch& batch, uint32 paramOffset);
void do_setInputBuffer(Batch& batch, uint32 paramOffset);
@ -385,6 +383,7 @@ protected:
// Output stage
void do_setFramebuffer(Batch& batch, uint32 paramOffset);
void do_clearFramebuffer(Batch& batch, uint32 paramOffset);
void do_blit(Batch& batch, uint32 paramOffset);
// Synchronize the state cache of this Backend with the actual real state of the GL Context

View file

@ -180,7 +180,6 @@ void GLBackend::syncOutputStateCache() {
void GLBackend::do_setFramebuffer(Batch& batch, uint32 paramOffset) {
auto framebuffer = batch._framebuffers.get(batch._params[paramOffset]._uint);
if (_output._framebuffer != framebuffer) {
auto newFBO = getFramebufferID(framebuffer);
if (_output._drawFBO != newFBO) {
@ -191,6 +190,72 @@ void GLBackend::do_setFramebuffer(Batch& batch, uint32 paramOffset) {
}
}
void GLBackend::do_clearFramebuffer(Batch& batch, uint32 paramOffset) {
uint32 masks = batch._params[paramOffset + 7]._uint;
Vec4 color;
color.x = batch._params[paramOffset + 6]._float;
color.y = batch._params[paramOffset + 5]._float;
color.z = batch._params[paramOffset + 4]._float;
color.w = batch._params[paramOffset + 3]._float;
float depth = batch._params[paramOffset + 2]._float;
int stencil = batch._params[paramOffset + 1]._int;
int useScissor = batch._params[paramOffset + 0]._int;
GLuint glmask = 0;
if (masks & Framebuffer::BUFFER_STENCIL) {
glClearStencil(stencil);
glmask |= GL_STENCIL_BUFFER_BIT;
}
if (masks & Framebuffer::BUFFER_DEPTH) {
glClearDepth(depth);
glmask |= GL_DEPTH_BUFFER_BIT;
}
std::vector<GLenum> drawBuffers;
if (masks & Framebuffer::BUFFER_COLORS) {
for (unsigned int i = 0; i < Framebuffer::MAX_NUM_RENDER_BUFFERS; i++) {
if (masks & (1 << i)) {
drawBuffers.push_back(GL_COLOR_ATTACHMENT0 + i);
}
}
if (!drawBuffers.empty()) {
glDrawBuffers(drawBuffers.size(), drawBuffers.data());
glClearColor(color.x, color.y, color.z, color.w);
glmask |= GL_COLOR_BUFFER_BIT;
}
// Force the color mask cache to WRITE_ALL if not the case
do_setStateColorWriteMask(State::ColorMask::WRITE_ALL);
}
// Apply scissor if needed and if not already on
bool doEnableScissor = (useScissor && (!_pipeline._stateCache.scissorEnable));
if (doEnableScissor) {
glEnable(GL_SCISSOR_TEST);
}
// Clear!
glClear(glmask);
// Restore scissor if needed
if (doEnableScissor) {
glDisable(GL_SCISSOR_TEST);
}
// Restore the color draw buffers only if a frmaebuffer is bound
if (_output._framebuffer && !drawBuffers.empty()) {
auto glFramebuffer = syncGPUObject(*_output._framebuffer);
if (glFramebuffer) {
glDrawBuffers(glFramebuffer->_colorBuffers.size(), glFramebuffer->_colorBuffers.data());
}
}
(void) CHECK_GL_ERROR();
}
void GLBackend::do_blit(Batch& batch, uint32 paramOffset) {
auto srcframebuffer = batch._framebuffers.get(batch._params[paramOffset]._uint);
Vec4i srcvp;
@ -203,19 +268,31 @@ void GLBackend::do_blit(Batch& batch, uint32 paramOffset) {
for (size_t i = 0; i < 4; ++i) {
dstvp[i] = batch._params[paramOffset + 6 + i]._int;
}
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, getFramebufferID(dstframebuffer));
// Assign dest framebuffer if not bound already
auto newDrawFBO = getFramebufferID(dstframebuffer);
if (_output._drawFBO != newDrawFBO) {
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, newDrawFBO);
}
// always bind the read fbo
glBindFramebuffer(GL_READ_FRAMEBUFFER, getFramebufferID(srcframebuffer));
// Blit!
glBlitFramebuffer(srcvp.x, srcvp.y, srcvp.z, srcvp.w,
dstvp.x, dstvp.y, dstvp.z, dstvp.w,
GL_COLOR_BUFFER_BIT, GL_LINEAR);
(void) CHECK_GL_ERROR();
if (_output._framebuffer) {
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, getFramebufferID(_output._framebuffer));
// Always clean the read fbo to 0
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
// Restore draw fbo if changed
if (_output._drawFBO != newDrawFBO) {
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, _output._drawFBO);
}
}
(void) CHECK_GL_ERROR();
}
void GLBackend::downloadFramebuffer(const FramebufferPointer& srcFramebuffer, const Vec4i& region, QImage& destImage) {
auto readFBO = gpu::GLBackend::getFramebufferID(srcFramebuffer);