Merge branch 'master' into cursor_manager

This commit is contained in:
Brad Davis 2015-06-10 10:20:57 -07:00
commit 863402aea2
28 changed files with 510 additions and 191 deletions

View file

@ -14,10 +14,10 @@ var connectSound = SoundCache.getSound("file://" + Paths.resources + "sounds/sho
// setup the options needed for that sound
var connectSoundOptions = {
localOnly: true
localOnly: true
}
// play the sound locally once we get the first audio packet from a mixer
Audio.receivedFirstPacket.connect(function(){
Audio.playSound(connectSound, connectSoundOptions);
Audio.playSound(connectSound, connectSoundOptions);
});

View file

@ -12,7 +12,7 @@
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
Script.include('lineRider.js')
var MAX_POINTS_PER_LINE = 30;
var MAX_POINTS_PER_LINE = 80;
var colorPalette = [{

View file

@ -336,7 +336,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) :
_enableProcessOctreeThread(true),
_octreeProcessor(),
_nodeBoundsDisplay(this),
_applicationOverlay(),
_runningScriptsWidget(NULL),
_runningScriptsWidgetWasVisible(false),
_trayIcon(new QSystemTrayIcon(_window)),
@ -347,7 +346,8 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) :
_notifiedPacketVersionMismatchThisDomain(false),
_domainConnectionRefusals(QList<QString>()),
_maxOctreePPS(maxOctreePacketsPerSecond.get()),
_lastFaceTrackerUpdate(0)
_lastFaceTrackerUpdate(0),
_applicationOverlay()
{
setInstance(this);
#ifdef Q_OS_WIN

View file

@ -304,6 +304,7 @@ bool Avatar::addToScene(AvatarSharedPointer self, std::shared_ptr<render::Scene>
void Avatar::removeFromScene(AvatarSharedPointer self, std::shared_ptr<render::Scene> scene, render::PendingChanges& pendingChanges) {
pendingChanges.removeItem(_renderItemID);
_skeletonModel.removeFromScene(scene, pendingChanges);
getHead()->getFaceModel().removeFromScene(scene, pendingChanges);
}
void Avatar::render(RenderArgs* renderArgs, const glm::vec3& cameraPosition, bool postLighting) {

View file

@ -55,7 +55,7 @@ AvatarManager::AvatarManager(QObject* parent) :
_avatarFades() {
// register a meta type for the weak pointer we'll use for the owning avatar mixer for each avatar
qRegisterMetaType<QWeakPointer<Node> >("NodeWeakPointer");
_myAvatar = std::shared_ptr<MyAvatar>(new MyAvatar());
_myAvatar = std::make_shared<MyAvatar>();
}
void AvatarManager::init() {
@ -97,9 +97,9 @@ void AvatarManager::updateOtherAvatars(float deltaTime) {
// simulate avatars
AvatarHash::iterator avatarIterator = _avatarHash.begin();
while (avatarIterator != _avatarHash.end()) {
Avatar* avatar = reinterpret_cast<Avatar*>(avatarIterator.value().get());
auto avatar = std::dynamic_pointer_cast<Avatar>(avatarIterator.value());
if (avatar == _myAvatar.get() || !avatar->isInitialized()) {
if (avatar == _myAvatar || !avatar->isInitialized()) {
// DO NOT update _myAvatar! Its update has already been done earlier in the main loop.
// DO NOT update or fade out uninitialized Avatars
++avatarIterator;
@ -121,26 +121,30 @@ void AvatarManager::simulateAvatarFades(float deltaTime) {
const float SHRINK_RATE = 0.9f;
const float MIN_FADE_SCALE = 0.001f;
render::ScenePointer scene = Application::getInstance()->getMain3DScene();
render::PendingChanges pendingChanges;
while (fadingIterator != _avatarFades.end()) {
Avatar* avatar = static_cast<Avatar*>(fadingIterator->get());
auto avatar = std::static_pointer_cast<Avatar>(*fadingIterator);
avatar->setTargetScale(avatar->getScale() * SHRINK_RATE, true);
if (avatar->getTargetScale() < MIN_FADE_SCALE) {
avatar->removeFromScene(*fadingIterator, scene, pendingChanges);
fadingIterator = _avatarFades.erase(fadingIterator);
} else {
avatar->simulate(deltaTime);
++fadingIterator;
}
}
scene->enqueuePendingChanges(pendingChanges);
}
AvatarSharedPointer AvatarManager::newSharedAvatar() {
return AvatarSharedPointer(new Avatar());
return AvatarSharedPointer(std::make_shared<Avatar>());
}
// virtual
AvatarSharedPointer AvatarManager::addAvatar(const QUuid& sessionUUID, const QWeakPointer<Node>& mixerWeakPointer) {
std::shared_ptr<Avatar> avatar = std::dynamic_pointer_cast<Avatar>(AvatarHashMap::addAvatar(sessionUUID, mixerWeakPointer));
auto avatar = std::dynamic_pointer_cast<Avatar>(AvatarHashMap::addAvatar(sessionUUID, mixerWeakPointer));
render::ScenePointer scene = Application::getInstance()->getMain3DScene();
render::PendingChanges pendingChanges;
avatar->addToScene(avatar, scene, pendingChanges);
@ -171,10 +175,6 @@ void AvatarManager::removeAvatar(const QUuid& sessionUUID) {
_avatarFades.push_back(avatarIterator.value());
_avatarHash.erase(avatarIterator);
}
render::ScenePointer scene = Application::getInstance()->getMain3DScene();
render::PendingChanges pendingChanges;
avatar->removeFromScene(avatar, scene, pendingChanges);
scene->enqueuePendingChanges(pendingChanges);
}
}
@ -182,12 +182,12 @@ void AvatarManager::clearOtherAvatars() {
// clear any avatars that came from an avatar-mixer
AvatarHash::iterator avatarIterator = _avatarHash.begin();
while (avatarIterator != _avatarHash.end()) {
Avatar* avatar = reinterpret_cast<Avatar*>(avatarIterator.value().get());
if (avatar == _myAvatar.get() || !avatar->isInitialized()) {
auto avatar = std::static_pointer_cast<Avatar>(avatarIterator.value());
if (avatar == _myAvatar || !avatar->isInitialized()) {
// don't remove myAvatar or uninitialized avatars from the list
++avatarIterator;
} else {
removeAvatarMotionState(avatar);
removeAvatarMotionState(avatar.get());
_avatarFades.push_back(avatarIterator.value());
avatarIterator = _avatarHash.erase(avatarIterator);
}
@ -250,7 +250,7 @@ void AvatarManager::handleCollisionEvents(CollisionEvents& collisionEvents) {
void AvatarManager::updateAvatarPhysicsShape(const QUuid& id) {
AvatarHash::iterator avatarItr = _avatarHash.find(id);
if (avatarItr != _avatarHash.end()) {
Avatar* avatar = static_cast<Avatar*>(avatarItr.value().get());
auto avatar = std::static_pointer_cast<Avatar>(avatarItr.value());
AvatarMotionState* motionState = avatar->_motionState;
if (motionState) {
motionState->addDirtyFlags(EntityItem::DIRTY_SHAPE);
@ -259,7 +259,7 @@ void AvatarManager::updateAvatarPhysicsShape(const QUuid& id) {
avatar->computeShapeInfo(shapeInfo);
btCollisionShape* shape = ObjectMotionState::getShapeManager()->getShape(shapeInfo);
if (shape) {
AvatarMotionState* motionState = new AvatarMotionState(avatar, shape);
AvatarMotionState* motionState = new AvatarMotionState(avatar.get(), shape);
avatar->_motionState = motionState;
_motionStatesToAdd.insert(motionState);
_avatarMotionStates.insert(motionState);

View file

@ -14,7 +14,18 @@
#include "DeviceTracker.h"
#ifdef __GNUC__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wsign-compare"
#endif
#include <glm/glm.hpp>
#ifdef __GNUC__
#pragma GCC diagnostic pop
#endif
#include <glm/gtc/quaternion.hpp>
#include <glm/gtc/matrix_transform.hpp>

View file

@ -267,9 +267,8 @@ void ApplicationOverlay::displayOverlayTexture() {
glLoadIdentity();
glDisable(GL_DEPTH_TEST);
glDisable(GL_LIGHTING);
if (_alpha < 1.0) {
glEnable(GL_BLEND);
}
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glViewport(0, 0, qApp->getDeviceSize().width(), qApp->getDeviceSize().height());
static const glm::vec2 topLeft(-1, 1);
@ -300,12 +299,14 @@ void ApplicationOverlay::displayOverlayTexture() {
mousePosition.y *= -1.0f;
glEnable(GL_TEXTURE_2D);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glBindTexture(GL_TEXTURE_2D, gpu::GLBackend::getTextureID(_crosshairTexture));
glm::vec4 reticleColor = { RETICLE_COLOR[0], RETICLE_COLOR[1], RETICLE_COLOR[2], 1.0f };
DependencyManager::get<GeometryCache>()->renderQuad(
mouseTopLeft + mousePosition, mouseBottomRight + mousePosition,
texCoordTopLeft, texCoordBottomRight,
reticleColor);
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_CONSTANT_ALPHA, GL_ONE);
glDisable(GL_TEXTURE_2D);
} glPopMatrix();
}
@ -455,6 +456,9 @@ void ApplicationOverlay::displayOverlayTextureStereo(Camera& whichCamera, float
}
//draw the mouse pointer
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, gpu::GLBackend::getTextureID(_crosshairTexture));
glm::vec2 canvasSize = qApp->getCanvasSize();
const float reticleSize = 40.0f / canvasSize.x * quadWidth;
@ -584,7 +588,9 @@ void ApplicationOverlay::renderPointers() {
_crosshairTexture = TextureCache::getImageTexture(PathUtils::resourcesPath() + "images/sixense-reticle.png");
}
glEnable(GL_TEXTURE_2D);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, gpu::GLBackend::getTextureID(_crosshairTexture));
@ -746,8 +752,14 @@ void ApplicationOverlay::renderControllerPointers() {
}
void ApplicationOverlay::renderPointersOculus() {
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, gpu::GLBackend::getTextureID(_crosshairTexture));
glDisable(GL_DEPTH_TEST);
glMatrixMode(GL_MODELVIEW);
//Controller Pointers
@ -772,6 +784,8 @@ void ApplicationOverlay::renderPointersOculus() {
}
glEnable(GL_DEPTH_TEST);
glDisable(GL_TEXTURE_2D);
glDisable(GL_BLEND);
}
//Renders a small magnification of the currently bound texture at the coordinates

View file

@ -232,7 +232,7 @@ void RenderableModelEntityItem::render(RenderArgs* args) {
remapTextures();
{
float alpha = getLocalRenderAlpha();
// float alpha = getLocalRenderAlpha();
if (!_model || _needsModelReload) {
// TODO: this getModel() appears to be about 3% of model render time. We should optimize

View file

@ -213,7 +213,7 @@ uint8_t RenderablePolyVoxEntityItem::getVoxel(int x, int y, int z) {
// if _voxelSurfaceStyle is SURFACE_EDGED_CUBIC, we maintain an extra layer of
// voxels all around the requested voxel space. Having the empty voxels around
// the edges changes how the surface extractor behaves.
if (_voxelSurfaceStyle == SURFACE_EDGED_CUBIC) {
return _volData->getVoxelAt(x + 1, y + 1, z + 1);
}
@ -239,7 +239,7 @@ void RenderablePolyVoxEntityItem::updateOnCount(int x, int y, int z, uint8_t toV
if (!inUserBounds(_volData, _voxelSurfaceStyle, x, y, z)) {
return;
}
uint8_t uVoxelValue = getVoxel(x, y, z);
if (toValue != 0) {
if (uVoxelValue == 0) {
@ -347,8 +347,8 @@ void RenderablePolyVoxEntityItem::getModel() {
sizeof(PolyVox::PositionMaterialNormal),
gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::RAW)));
// auto normalAttrib = mesh->getAttributeBuffer(gpu::Stream::NORMAL);
// for (auto normal = normalAttrib.begin<glm::vec3>(); normal != normalAttrib.end<glm::vec3>(); normal++) {
// (*normal) = -(*normal);
@ -363,7 +363,7 @@ void RenderablePolyVoxEntityItem::getModel() {
// gpu::Element(gpu::VEC2, gpu::FLOAT, gpu::RAW)));
#ifdef WANT_DEBUG
qDebug() << "---- vecIndices.size() =" << vecIndices.size();
qDebug() << "---- vecVertices.size() =" << vecVertices.size();
@ -379,7 +379,7 @@ void RenderablePolyVoxEntityItem::render(RenderArgs* args) {
if (_needsModelReload) {
getModel();
}
Transform transform;
transform.setTranslation(getPosition() - getRegistrationPoint() * getDimensions());
transform.setRotation(getRotation());
@ -398,7 +398,7 @@ void RenderablePolyVoxEntityItem::render(RenderArgs* args) {
mesh->getVertexBuffer()._stride);
batch.setIndexBuffer(gpu::UINT32, mesh->getIndexBuffer()._buffer, 0);
batch.drawIndexed(gpu::TRIANGLES, mesh->getNumIndices(), 0);
RenderableDebugableEntityItem::render(this, args);
}
@ -448,14 +448,13 @@ bool RenderablePolyVoxEntityItem::findDetailedRayIntersection(const glm::vec3& o
glm::vec3 normDirection = glm::normalize(direction);
// the PolyVox ray intersection code requires a near and far point.
glm::vec3 scale = getDimensions() / _voxelVolumeSize; // meters / voxel-units
// set ray cast length to long enough to cover all of the voxel space
// set ray cast length to long enough to cover all of the voxel space
float distanceToEntity = glm::distance(origin, getPosition());
float largestDimension = glm::max(getDimensions().x, getDimensions().y, getDimensions().z) * 2.0f;
glm::vec3 farPoint = origin + normDirection * (distanceToEntity + largestDimension);
glm::vec4 originInVoxel = wtvMatrix * glm::vec4(origin, 1.0f);
glm::vec4 farInVoxel = wtvMatrix * glm::vec4(farPoint, 1.0f);
PolyVox::Vector3DFloat startPoint(originInVoxel.x, originInVoxel.y, originInVoxel.z);
PolyVox::Vector3DFloat endPoint(farInVoxel.x, farInVoxel.y, farInVoxel.z);
@ -479,7 +478,7 @@ bool RenderablePolyVoxEntityItem::findDetailedRayIntersection(const glm::vec3& o
}
result -= glm::vec4(0.5f, 0.5f, 0.5f, 0.0f);
glm::vec4 intersectedWorldPosition = voxelToWorldMatrix() * result;
distance = glm::distance(glm::vec3(intersectedWorldPosition), origin);
@ -556,9 +555,9 @@ void RenderablePolyVoxEntityItem::decompressVolumeData() {
<< voxelXSize << voxelYSize << voxelZSize;
return;
}
int rawSize = voxelXSize * voxelYSize * voxelZSize;
QByteArray compressedData;
reader >> compressedData;
QByteArray uncompressedData = qUncompress(compressedData);
@ -635,9 +634,6 @@ void RenderablePolyVoxEntityItem::computeShapeInfo(ShapeInfo& info) {
float offL = -0.5f;
float offH = 0.5f;
// float offL = 0.0f;
// float offH = 1.0f;
glm::vec3 p000 = glm::vec3(wToM * glm::vec4(x + offL, y + offL, z + offL, 1.0f));
glm::vec3 p001 = glm::vec3(wToM * glm::vec4(x + offL, y + offL, z + offH, 1.0f));
glm::vec3 p010 = glm::vec3(wToM * glm::vec4(x + offL, y + offH, z + offL, 1.0f));

View file

@ -191,8 +191,8 @@ void RenderableWebEntityItem::render(RenderArgs* args) {
}
void RenderableWebEntityItem::setSourceUrl(const QString& value) {
qDebug() << "Setting web entity source URL to " << value;
if (_sourceUrl != value) {
qDebug() << "Setting web entity source URL to " << value;
_sourceUrl = value;
if (_webSurface) {
AbstractViewStateInterface::instance()->postLambdaEvent([this] {

View file

@ -86,6 +86,7 @@ bool LineEntityItem::setProperties(const EntityItemProperties& properties) {
void LineEntityItem::setLinePoints(const QVector<glm::vec3>& points) {
QVector<glm::vec3> sanitizedPoints;
int invalidPoints = 0;
for (int i = 0; i < points.size(); i++) {
glm::vec3 point = points.at(i);
// Make sure all of our points are valid numbers.
@ -93,9 +94,12 @@ void LineEntityItem::setLinePoints(const QVector<glm::vec3>& points) {
if (point.x > 0 && point.y > 0 && point.z > 0){
sanitizedPoints << point;
} else {
qDebug() << "INVALID POINT";
++invalidPoints;
}
}
if (invalidPoints > 0) {
qDebug() << "Line with" << invalidPoints << "INVALID POINTS";
}
_points = sanitizedPoints;
_pointsChanged = true;
}

View file

@ -1902,8 +1902,8 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping,
} else {
material._material->setDiffuse(material.diffuse);
}
material._material->setSpecular(material.specular);
material._material->setShininess(material.shininess);
material._material->setMetallic(glm::length(material.specular));
material._material->setGloss(material.shininess);
if (material.opacity <= 0.0f) {
material._material->setOpacity(1.0f);

View file

@ -134,8 +134,8 @@ void setMeshPartDefaults(FBXMeshPart& meshPart, QString materialID) {
meshPart._material = model::MaterialPointer(new model::Material());
meshPart._material->setDiffuse(glm::vec3(1.0, 1.0, 1.0));
meshPart._material->setOpacity(1.0);
meshPart._material->setSpecular(glm::vec3(1.0, 1.0, 1.0));
meshPart._material->setShininess(96.0);
meshPart._material->setMetallic(0.0);
meshPart._material->setGloss(96.0);
meshPart._material->setEmissive(glm::vec3(0.0, 0.0, 0.0));
}
@ -481,8 +481,8 @@ FBXGeometry OBJReader::readOBJ(QIODevice* device, const QVariantHash& mapping, Q
meshPart.specularTexture.filename = material->specularTextureFilename;
// ... and some things are set in the underlying material.
meshPart._material->setDiffuse(material->diffuseColor);
meshPart._material->setSpecular(material->specularColor);
meshPart._material->setShininess(material->shininess);
meshPart._material->setMetallic(glm::length(material->specularColor));
meshPart._material->setGloss(material->shininess);
meshPart._material->setOpacity(material->opacity);
}
// qCDebug(modelformat) << "OBJ Reader part:" << meshPartCount << "name:" << leadFace.groupName << "material:" << groupMaterialName << "diffuse:" << meshPart._material->getDiffuse() << "faces:" << faceGroup.count() << "triangle indices will start with:" << mesh.vertices.count();
@ -567,10 +567,10 @@ void fbxDebugDump(const FBXGeometry& fbxgeo) {
qCDebug(modelformat) << " quadIndices.count() =" << meshPart.quadIndices.count();
qCDebug(modelformat) << " triangleIndices.count() =" << meshPart.triangleIndices.count();
qCDebug(modelformat) << " diffuseColor =" << meshPart.diffuseColor << "mat =" << meshPart._material->getDiffuse();
qCDebug(modelformat) << " specularColor =" << meshPart.specularColor << "mat =" << meshPart._material->getSpecular();
qCDebug(modelformat) << " specularColor =" << meshPart.specularColor << "mat =" << meshPart._material->getMetallic();
qCDebug(modelformat) << " emissiveColor =" << meshPart.emissiveColor << "mat =" << meshPart._material->getEmissive();
qCDebug(modelformat) << " emissiveParams =" << meshPart.emissiveParams;
qCDebug(modelformat) << " shininess =" << meshPart.shininess << "mat =" << meshPart._material->getShininess();
qCDebug(modelformat) << " gloss =" << meshPart.shininess << "mat =" << meshPart._material->getGloss();
qCDebug(modelformat) << " opacity =" << meshPart.opacity << "mat =" << meshPart._material->getOpacity();
qCDebug(modelformat) << " materialID =" << meshPart.materialID;
qCDebug(modelformat) << " diffuse texture =" << meshPart.diffuseTexture.filename;

View file

@ -437,6 +437,8 @@ public:
explicit operator bool() const { return bool(_texture); }
bool operator !() const { return (!_texture); }
bool isValid() const { return bool(_texture); }
};
typedef std::vector<TextureView> TextureViews;

View file

@ -14,7 +14,7 @@ using namespace model;
using namespace gpu;
Material::Material() :
_flags(0),
_key(0),
_schemaBuffer(),
_textureMap() {
@ -26,13 +26,13 @@ Material::Material() :
}
Material::Material(const Material& material) :
_flags(material._flags),
_key(material._key),
_schemaBuffer(material._schemaBuffer),
_textureMap(material._textureMap) {
}
Material& Material::operator= (const Material& material) {
_flags = (material._flags);
_key = (material._key);
_schemaBuffer = (material._schemaBuffer);
_textureMap = (material._textureMap);
@ -43,52 +43,32 @@ Material::~Material() {
}
void Material::setDiffuse(const Color& diffuse) {
if (glm::any(glm::greaterThan(diffuse, Color(0.0f)))) {
_flags.set(DIFFUSE_BIT);
} else {
_flags.reset(DIFFUSE_BIT);
}
_key.setDiffuse(glm::any(glm::greaterThan(diffuse, Color(0.0f))));
_schemaBuffer.edit<Schema>()._diffuse = diffuse;
}
void Material::setSpecular(const Color& specular) {
if (glm::any(glm::greaterThan(specular, Color(0.0f)))) {
_flags.set(SPECULAR_BIT);
} else {
_flags.reset(SPECULAR_BIT);
}
_schemaBuffer.edit<Schema>()._specular = specular;
void Material::setMetallic(float metallic) {
_key.setMetallic(metallic > 0.0f);
_schemaBuffer.edit<Schema>()._metallic = glm::vec3(metallic);
}
void Material::setEmissive(const Color& emissive) {
if (glm::any(glm::greaterThan(emissive, Color(0.0f)))) {
_flags.set(EMISSIVE_BIT);
} else {
_flags.reset(EMISSIVE_BIT);
}
_key.setEmissive(glm::any(glm::greaterThan(emissive, Color(0.0f))));
_schemaBuffer.edit<Schema>()._emissive = emissive;
}
void Material::setShininess(float shininess) {
if (shininess > 0.0f) {
_flags.set(SHININESS_BIT);
} else {
_flags.reset(SHININESS_BIT);
}
_schemaBuffer.edit<Schema>()._shininess = shininess;
void Material::setGloss(float gloss) {
_key.setGloss((gloss > 0.0f));
_schemaBuffer.edit<Schema>()._gloss = gloss;
}
void Material::setOpacity(float opacity) {
if (opacity >= 1.0f) {
_flags.reset(TRANSPARENT_BIT);
} else {
_flags.set(TRANSPARENT_BIT);
}
_key.setTransparent((opacity < 1.0f));
_schemaBuffer.edit<Schema>()._opacity = opacity;
}
void Material::setTextureView(MapChannel channel, const gpu::TextureView& view) {
_flags.set(DIFFUSE_MAP_BIT + channel);
_key.setMapChannel(channel, (view.isValid()));
_textureMap[channel] = view;
}

View file

@ -23,6 +23,177 @@
namespace model {
// Material Key is a coarse trait description of a material used to classify the materials
class MaterialKey {
public:
enum FlagBit {
EMISSIVE_VAL_BIT = 0,
DIFFUSE_VAL_BIT,
METALLIC_VAL_BIT,
GLOSS_VAL_BIT,
TRANSPARENT_VAL_BIT,
EMISSIVE_MAP_BIT,
DIFFUSE_MAP_BIT,
METALLIC_MAP_BIT,
GLOSS_MAP_BIT,
TRANSPARENT_MAP_BIT,
NORMAL_MAP_BIT,
NUM_FLAGS,
};
typedef std::bitset<NUM_FLAGS> Flags;
enum MapChannel {
EMISSIVE_MAP = 0,
DIFFUSE_MAP,
METALLIC_MAP,
GLOSS_MAP,
TRANSPARENT_MAP,
NORMAL_MAP,
NUM_MAP_CHANNELS,
};
// The signature is the Flags
Flags _flags;
MaterialKey() : _flags(0) {}
MaterialKey(const Flags& flags) : _flags(flags) {}
class Builder {
Flags _flags{ 0 };
public:
Builder() {}
MaterialKey build() const { return MaterialKey(_flags); }
Builder& withEmissive() { _flags.set(EMISSIVE_VAL_BIT); return (*this); }
Builder& withDiffuse() { _flags.set(DIFFUSE_VAL_BIT); return (*this); }
Builder& withMetallic() { _flags.set(METALLIC_VAL_BIT); return (*this); }
Builder& withGloss() { _flags.set(GLOSS_VAL_BIT); return (*this); }
Builder& withTransparent() { _flags.set(TRANSPARENT_VAL_BIT); return (*this); }
Builder& withEmissiveMap() { _flags.set(EMISSIVE_MAP_BIT); return (*this); }
Builder& withDiffuseMap() { _flags.set(DIFFUSE_MAP_BIT); return (*this); }
Builder& withMetallicMap() { _flags.set(METALLIC_MAP_BIT); return (*this); }
Builder& withGlossMap() { _flags.set(GLOSS_MAP_BIT); return (*this); }
Builder& withTransparentMap() { _flags.set(TRANSPARENT_MAP_BIT); return (*this); }
Builder& withNormalMap() { _flags.set(NORMAL_MAP_BIT); return (*this); }
// Convenient standard keys that we will keep on using all over the place
static MaterialKey opaqueDiffuse() { return Builder().withDiffuse().build(); }
};
void setEmissive(bool value) { _flags.set(EMISSIVE_VAL_BIT, value); }
bool isEmissive() const { return _flags[EMISSIVE_VAL_BIT]; }
void setEmissiveMap(bool value) { _flags.set(EMISSIVE_MAP_BIT, value); }
bool isEmissiveMap() const { return _flags[EMISSIVE_MAP_BIT]; }
void setDiffuse(bool value) { _flags.set(DIFFUSE_VAL_BIT, value); }
bool isDiffuse() const { return _flags[DIFFUSE_VAL_BIT]; }
void setDiffuseMap(bool value) { _flags.set(DIFFUSE_MAP_BIT, value); }
bool isDiffuseMap() const { return _flags[DIFFUSE_MAP_BIT]; }
void setMetallic(bool value) { _flags.set(METALLIC_VAL_BIT, value); }
bool isMetallic() const { return _flags[METALLIC_VAL_BIT]; }
void setMetallicMap(bool value) { _flags.set(METALLIC_MAP_BIT, value); }
bool isMetallicMap() const { return _flags[METALLIC_MAP_BIT]; }
void setGloss(bool value) { _flags.set(GLOSS_VAL_BIT, value); }
bool isGloss() const { return _flags[GLOSS_VAL_BIT]; }
void setGlossMap(bool value) { _flags.set(GLOSS_MAP_BIT, value); }
bool isGlossMap() const { return _flags[GLOSS_MAP_BIT]; }
void setTransparent(bool value) { _flags.set(TRANSPARENT_VAL_BIT, value); }
bool isTransparent() const { return _flags[TRANSPARENT_VAL_BIT]; }
bool isOpaque() const { return !_flags[TRANSPARENT_VAL_BIT]; }
void setTransparentMap(bool value) { _flags.set(TRANSPARENT_MAP_BIT, value); }
bool isTransparentMap() const { return _flags[TRANSPARENT_MAP_BIT]; }
void setNormalMap(bool value) { _flags.set(NORMAL_MAP_BIT, value); }
bool isNormalMap() const { return _flags[NORMAL_MAP_BIT]; }
void setMapChannel(MapChannel channel, bool value) { _flags.set(EMISSIVE_MAP_BIT + channel, value); }
bool isMapChannel(MapChannel channel) const { return _flags[EMISSIVE_MAP_BIT + channel]; }
};
class MaterialFilter {
public:
MaterialKey::Flags _value{ 0 };
MaterialKey::Flags _mask{ 0 };
MaterialFilter(const MaterialKey::Flags& value = MaterialKey::Flags(0), const MaterialKey::Flags& mask = MaterialKey::Flags(0)) : _value(value), _mask(mask) {}
class Builder {
MaterialKey::Flags _value{ 0 };
MaterialKey::Flags _mask{ 0 };
public:
Builder() {}
MaterialFilter build() const { return MaterialFilter(_value, _mask); }
Builder& withoutEmissive() { _value.reset(MaterialKey::EMISSIVE_VAL_BIT); _mask.set(MaterialKey::EMISSIVE_VAL_BIT); return (*this); }
Builder& withEmissive() { _value.set(MaterialKey::EMISSIVE_VAL_BIT); _mask.set(MaterialKey::EMISSIVE_VAL_BIT); return (*this); }
Builder& withoutEmissiveMap() { _value.reset(MaterialKey::EMISSIVE_MAP_BIT); _mask.set(MaterialKey::EMISSIVE_MAP_BIT); return (*this); }
Builder& withEmissiveMap() { _value.set(MaterialKey::EMISSIVE_MAP_BIT); _mask.set(MaterialKey::EMISSIVE_MAP_BIT); return (*this); }
Builder& withoutDiffuse() { _value.reset(MaterialKey::DIFFUSE_VAL_BIT); _mask.set(MaterialKey::DIFFUSE_VAL_BIT); return (*this); }
Builder& withDiffuse() { _value.set(MaterialKey::DIFFUSE_VAL_BIT); _mask.set(MaterialKey::DIFFUSE_VAL_BIT); return (*this); }
Builder& withoutDiffuseMap() { _value.reset(MaterialKey::DIFFUSE_MAP_BIT); _mask.set(MaterialKey::DIFFUSE_MAP_BIT); return (*this); }
Builder& withDiffuseMap() { _value.set(MaterialKey::DIFFUSE_MAP_BIT); _mask.set(MaterialKey::DIFFUSE_MAP_BIT); return (*this); }
Builder& withoutMetallic() { _value.reset(MaterialKey::METALLIC_VAL_BIT); _mask.set(MaterialKey::METALLIC_VAL_BIT); return (*this); }
Builder& withMetallic() { _value.set(MaterialKey::METALLIC_VAL_BIT); _mask.set(MaterialKey::METALLIC_VAL_BIT); return (*this); }
Builder& withoutMetallicMap() { _value.reset(MaterialKey::METALLIC_MAP_BIT); _mask.set(MaterialKey::METALLIC_MAP_BIT); return (*this); }
Builder& withMetallicMap() { _value.set(MaterialKey::METALLIC_MAP_BIT); _mask.set(MaterialKey::METALLIC_MAP_BIT); return (*this); }
Builder& withoutGloss() { _value.reset(MaterialKey::GLOSS_VAL_BIT); _mask.set(MaterialKey::GLOSS_VAL_BIT); return (*this); }
Builder& withGloss() { _value.set(MaterialKey::GLOSS_VAL_BIT); _mask.set(MaterialKey::GLOSS_VAL_BIT); return (*this); }
Builder& withoutGlossMap() { _value.reset(MaterialKey::GLOSS_MAP_BIT); _mask.set(MaterialKey::GLOSS_MAP_BIT); return (*this); }
Builder& withGlossMap() { _value.set(MaterialKey::GLOSS_MAP_BIT); _mask.set(MaterialKey::GLOSS_MAP_BIT); return (*this); }
Builder& withoutTransparent() { _value.reset(MaterialKey::TRANSPARENT_VAL_BIT); _mask.set(MaterialKey::TRANSPARENT_VAL_BIT); return (*this); }
Builder& withTransparent() { _value.set(MaterialKey::TRANSPARENT_VAL_BIT); _mask.set(MaterialKey::TRANSPARENT_VAL_BIT); return (*this); }
Builder& withoutTransparentMap() { _value.reset(MaterialKey::TRANSPARENT_MAP_BIT); _mask.set(MaterialKey::TRANSPARENT_MAP_BIT); return (*this); }
Builder& withTransparentMap() { _value.set(MaterialKey::TRANSPARENT_MAP_BIT); _mask.set(MaterialKey::TRANSPARENT_MAP_BIT); return (*this); }
Builder& withoutNormalMap() { _value.reset(MaterialKey::NORMAL_MAP_BIT); _mask.set(MaterialKey::NORMAL_MAP_BIT); return (*this); }
Builder& withNormalMap() { _value.set(MaterialKey::NORMAL_MAP_BIT); _mask.set(MaterialKey::NORMAL_MAP_BIT); return (*this); }
// Convenient standard keys that we will keep on using all over the place
static MaterialFilter opaqueDiffuse() { return Builder().withDiffuse().withoutTransparent().build(); }
};
// Item Filter operator testing if a key pass the filter
bool test(const MaterialKey& key) const { return (key._flags & _mask) == (_value & _mask); }
class Less {
public:
bool operator() (const MaterialFilter& left, const MaterialFilter& right) const {
if (left._value.to_ulong() == right._value.to_ulong()) {
return left._mask.to_ulong() < right._mask.to_ulong();
} else {
return left._value.to_ulong() < right._value.to_ulong();
}
}
};
};
class Material {
public:
typedef gpu::BufferView UniformBufferView;
@ -30,52 +201,27 @@ public:
typedef glm::vec3 Color;
enum MapChannel {
DIFFUSE_MAP = 0,
SPECULAR_MAP,
SHININESS_MAP,
EMISSIVE_MAP,
OPACITY_MAP,
NORMAL_MAP,
NUM_MAPS,
};
typedef MaterialKey::MapChannel MapChannel;
typedef std::map<MapChannel, TextureView> TextureMap;
typedef std::bitset<NUM_MAPS> MapFlags;
enum FlagBit {
DIFFUSE_BIT = 0,
SPECULAR_BIT,
SHININESS_BIT,
EMISSIVE_BIT,
TRANSPARENT_BIT,
DIFFUSE_MAP_BIT,
SPECULAR_MAP_BIT,
SHININESS_MAP_BIT,
EMISSIVE_MAP_BIT,
OPACITY_MAP_BIT,
NORMAL_MAP_BIT,
NUM_FLAGS,
};
typedef std::bitset<NUM_FLAGS> Flags;
typedef std::bitset<MaterialKey::NUM_MAP_CHANNELS> MapFlags;
Material();
Material(const Material& material);
Material& operator= (const Material& material);
virtual ~Material();
const MaterialKey& getKey() const { return _key; }
const Color& getEmissive() const { return _schemaBuffer.get<Schema>()._emissive; }
const Color& getDiffuse() const { return _schemaBuffer.get<Schema>()._diffuse; }
const Color& getSpecular() const { return _schemaBuffer.get<Schema>()._specular; }
float getShininess() const { return _schemaBuffer.get<Schema>()._shininess; }
float getMetallic() const { return _schemaBuffer.get<Schema>()._metallic.x; }
float getGloss() const { return _schemaBuffer.get<Schema>()._gloss; }
float getOpacity() const { return _schemaBuffer.get<Schema>()._opacity; }
void setDiffuse(const Color& diffuse);
void setSpecular(const Color& specular);
void setEmissive(const Color& emissive);
void setShininess(float shininess);
void setDiffuse(const Color& diffuse);
void setMetallic(float metallic);
void setGloss(float gloss);
void setOpacity(float opacity);
// Schema to access the attribute values of the material
@ -84,8 +230,8 @@ public:
Color _diffuse{0.5f};
float _opacity{1.f};
Color _specular{0.03f};
float _shininess{0.1f};
Color _metallic{0.03f};
float _gloss{0.1f};
Color _emissive{0.0f};
float _spare0{0.0f};
glm::vec4 _spareVec4{0.0f}; // for alignment beauty, Material size == Mat4x4
@ -100,7 +246,7 @@ public:
protected:
Flags _flags;
MaterialKey _key;
UniformBufferView _schemaBuffer;
TextureMap _textureMap;

View file

@ -44,70 +44,73 @@ void Skybox::setCubemap(const gpu::TexturePointer& cubemap) {
void Skybox::render(gpu::Batch& batch, const ViewFrustum& viewFrustum, const Skybox& skybox) {
if (skybox.getCubemap() && skybox.getCubemap()->isDefined()) {
if (skybox.getCubemap()) {
if (skybox.getCubemap()->isDefined()) {
static gpu::PipelinePointer thePipeline;
static gpu::BufferPointer theBuffer;
static gpu::Stream::FormatPointer theFormat;
static gpu::BufferPointer theConstants;
int SKYBOX_CONSTANTS_SLOT = 0; // need to be defined by the compilation of the shader
if (!thePipeline) {
auto skyVS = gpu::ShaderPointer(gpu::Shader::createVertex(std::string(Skybox_vert)));
auto skyFS = gpu::ShaderPointer(gpu::Shader::createPixel(std::string(Skybox_frag)));
auto skyShader = gpu::ShaderPointer(gpu::Shader::createProgram(skyVS, skyFS));
static gpu::PipelinePointer thePipeline;
static gpu::BufferPointer theBuffer;
static gpu::Stream::FormatPointer theFormat;
static gpu::BufferPointer theConstants;
int SKYBOX_CONSTANTS_SLOT = 0; // need to be defined by the compilation of the shader
if (!thePipeline) {
auto skyVS = gpu::ShaderPointer(gpu::Shader::createVertex(std::string(Skybox_vert)));
auto skyFS = gpu::ShaderPointer(gpu::Shader::createPixel(std::string(Skybox_frag)));
auto skyShader = gpu::ShaderPointer(gpu::Shader::createProgram(skyVS, skyFS));
gpu::Shader::BindingSet bindings;
bindings.insert(gpu::Shader::Binding(std::string("cubeMap"), 0));
if (!gpu::Shader::makeProgram(*skyShader, bindings)) {
gpu::Shader::BindingSet bindings;
bindings.insert(gpu::Shader::Binding(std::string("cubeMap"), 0));
if (!gpu::Shader::makeProgram(*skyShader, bindings)) {
}
}
SKYBOX_CONSTANTS_SLOT = skyShader->getBuffers().findLocation("skyboxBuffer");
if (SKYBOX_CONSTANTS_SLOT == gpu::Shader::INVALID_LOCATION) {
SKYBOX_CONSTANTS_SLOT = skyShader->getUniforms().findLocation("skyboxBuffer");
}
SKYBOX_CONSTANTS_SLOT = skyShader->getBuffers().findLocation("skyboxBuffer");
if (SKYBOX_CONSTANTS_SLOT == gpu::Shader::INVALID_LOCATION) {
SKYBOX_CONSTANTS_SLOT = skyShader->getUniforms().findLocation("skyboxBuffer");
}
auto skyState = gpu::StatePointer(new gpu::State());
auto skyState = gpu::StatePointer(new gpu::State());
thePipeline = gpu::PipelinePointer(gpu::Pipeline::create(skyShader, skyState));
thePipeline = gpu::PipelinePointer(gpu::Pipeline::create(skyShader, skyState));
const float CLIP = 1.0;
const glm::vec2 vertices[4] = { {-CLIP, -CLIP}, {CLIP, -CLIP}, {-CLIP, CLIP}, {CLIP, CLIP}};
theBuffer.reset(new gpu::Buffer(sizeof(vertices), (const gpu::Byte*) vertices));
const float CLIP = 1.0;
const glm::vec2 vertices[4] = { {-CLIP, -CLIP}, {CLIP, -CLIP}, {-CLIP, CLIP}, {CLIP, CLIP}};
theBuffer.reset(new gpu::Buffer(sizeof(vertices), (const gpu::Byte*) vertices));
theFormat.reset(new gpu::Stream::Format());
theFormat->setAttribute(gpu::Stream::POSITION, gpu::Stream::POSITION, gpu::Element(gpu::VEC2, gpu::FLOAT, gpu::XYZ));
theFormat.reset(new gpu::Stream::Format());
theFormat->setAttribute(gpu::Stream::POSITION, gpu::Stream::POSITION, gpu::Element(gpu::VEC2, gpu::FLOAT, gpu::XYZ));
auto color = glm::vec4(1.0f);
theConstants.reset(new gpu::Buffer(sizeof(color), (const gpu::Byte*) &color));
auto color = glm::vec4(1.0f);
theConstants.reset(new gpu::Buffer(sizeof(color), (const gpu::Byte*) &color));
}
glm::mat4 projMat;
viewFrustum.evalProjectionMatrix(projMat);
Transform viewTransform;
viewFrustum.evalViewTransform(viewTransform);
if (glm::all(glm::equal(skybox.getColor(), glm::vec3(0.0f)))) {
auto color = glm::vec4(1.0f);
theConstants->setSubData(0, sizeof(color), (const gpu::Byte*) &color);
} else {
theConstants->setSubData(0, sizeof(Color), (const gpu::Byte*) &skybox.getColor());
}
batch.setProjectionTransform(projMat);
batch.setViewTransform(viewTransform);
batch.setModelTransform(Transform()); // only for Mac
batch.setPipeline(thePipeline);
batch.setInputBuffer(gpu::Stream::POSITION, theBuffer, 0, 8);
batch.setUniformBuffer(SKYBOX_CONSTANTS_SLOT, theConstants, 0, theConstants->getSize());
batch.setInputFormat(theFormat);
batch.setUniformTexture(0, skybox.getCubemap());
batch.draw(gpu::TRIANGLE_STRIP, 4);
}
glm::mat4 projMat;
viewFrustum.evalProjectionMatrix(projMat);
Transform viewTransform;
viewFrustum.evalViewTransform(viewTransform);
if (glm::all(glm::equal(skybox.getColor(), glm::vec3(0.0f)))) {
auto color = glm::vec4(1.0f);
theConstants->setSubData(0, sizeof(color), (const gpu::Byte*) &color);
} else {
theConstants->setSubData(0, sizeof(Color), (const gpu::Byte*) &skybox.getColor());
}
batch.setProjectionTransform(projMat);
batch.setViewTransform(viewTransform);
batch.setModelTransform(Transform()); // only for Mac
batch.setPipeline(thePipeline);
batch.setInputBuffer(gpu::Stream::POSITION, theBuffer, 0, 8);
batch.setUniformBuffer(SKYBOX_CONSTANTS_SLOT, theConstants, 0, theConstants->getSize());
batch.setInputFormat(theFormat);
batch.setUniformTexture(0, skybox.getCubemap());
batch.draw(gpu::TRIANGLE_STRIP, 4);
} else {
// skybox has no cubemap, just clear the color buffer
auto color = skybox.getColor();
batch.clearFramebuffer(gpu::Framebuffer::BUFFER_COLOR0, glm::vec4(color, 1.0f), 0.f, 0);
batch.clearFramebuffer(gpu::Framebuffer::BUFFER_COLOR0, glm::vec4(color, 0.0f), 0.f, 0);
}
}

View file

@ -24,7 +24,7 @@ typedef glm::vec3 Color;
class TextureUsage {
public:
gpu::Texture::Type _type{ gpu::Texture::TEX_2D };
Material::MapFlags _materialUsage{ Material::DIFFUSE_MAP };
Material::MapFlags _materialUsage{ MaterialKey::DIFFUSE_MAP };
int _environmentUsage = 0;
};

View file

@ -35,6 +35,7 @@ AddressManager::AddressManager() :
_positionGetter(NULL),
_orientationGetter(NULL)
{
}
bool AddressManager::isConnected() {
@ -217,7 +218,7 @@ void AddressManager::goToAddressFromObject(const QVariantMap& dataObject, const
const QString DOMAIN_NETWORK_PORT_KEY = "network_port";
const QString DOMAIN_ICE_SERVER_ADDRESS_KEY = "ice_server_address";
DependencyManager::get<NodeList>()->flagTimeForConnectionStep(LimitedNodeList::ConnectionStep::HandleAddress);
DependencyManager::get<NodeList>()->flagTimeForConnectionStep(LimitedNodeList::ConnectionStep::HandleAddress);
const QString DOMAIN_ID_KEY = "id";
QString domainIDString = domainObject[DOMAIN_ID_KEY].toString();
@ -415,6 +416,9 @@ bool AddressManager::handleViewpoint(const QString& viewpointString, bool should
positionRegex.cap(2).toFloat(),
positionRegex.cap(3).toFloat());
// we're about to jump positions - store the current address in our history
addCurrentAddressToHistory();
if (!isNaN(newPosition.x) && !isNaN(newPosition.y) && !isNaN(newPosition.z)) {
glm::quat newOrientation;
@ -467,6 +471,10 @@ bool AddressManager::handleUsername(const QString& lookupString) {
void AddressManager::setHost(const QString& host) {
if (host != _host) {
// if the host is being changed we should store current address in the history
addCurrentAddressToHistory();
_host = host;
emit hostChanged(_host);
}
@ -474,7 +482,8 @@ void AddressManager::setHost(const QString& host) {
void AddressManager::setDomainInfo(const QString& hostname, quint16 port) {
_host = hostname;
setHost(hostname);
_rootPlaceID = QUuid();
qCDebug(networking) << "Possible domain change required to connect to domain at" << hostname << "on" << port;
@ -500,3 +509,22 @@ void AddressManager::copyAddress() {
void AddressManager::copyPath() {
QApplication::clipboard()->setText(currentPath());
}
void AddressManager::addCurrentAddressToHistory() {
if (_lastHistoryAppend == 0) {
// we don't store the first address on application load
// just update the last append time so the next is stored
_lastHistoryAppend = usecTimestampNow();
} else {
const quint64 DOUBLE_STORE_THRESHOLD_USECS = 500000;
// avoid double storing when the host changes and the viewpoint changes immediately after
if (usecTimestampNow() - _lastHistoryAppend > DOUBLE_STORE_THRESHOLD_USECS) {
// add the current address to the history
_history.append(currentAddress());
// change our last history append to now
_lastHistoryAppend = usecTimestampNow();
}
}
}

View file

@ -98,10 +98,15 @@ private:
bool handleUsername(const QString& lookupString);
bool handleDomainID(const QString& host);
void addCurrentAddressToHistory();
QString _host;
QUuid _rootPlaceID;
PositionGetter _positionGetter;
OrientationGetter _orientationGetter;
QList<QUrl> _history;
quint64 _lastHistoryAppend = 0;
};
#endif // hifi_AddressManager_h

View file

@ -605,9 +605,6 @@ const int NUM_BYTES_STUN_HEADER = 20;
void LimitedNodeList::sendSTUNRequest() {
static quint64 lastTimeStamp = usecTimestampNow();
lastTimeStamp = usecTimestampNow();
const int NUM_INITIAL_STUN_REQUESTS_BEFORE_FAIL = 10;
if (!_hasCompletedInitialSTUN) {

View file

@ -78,8 +78,8 @@ Model::Model(QObject* parent) :
_showTrueJointTransforms(true),
_lodDistance(0.0f),
_pupilDilation(0.0f),
_isVisible(true),
_url("http://invalid.com"),
_isVisible(true),
_blendNumber(0),
_appliedBlendNumber(0),
_calculatedMeshPartBoxesValid(false),
@ -891,6 +891,9 @@ namespace render {
return payload->model->renderPart(args, payload->meshIndex, payload->partIndex, false);
}
}
/* template <> const model::MaterialKey& shapeGetMaterialKey(const OpaqueMeshPart::Pointer& payload) {
return payload->model->getPartMaterial(payload->meshIndex, payload->partIndex);
}*/
}
void Model::setVisibleInScene(bool newValue, std::shared_ptr<render::Scene> scene) {
@ -913,8 +916,6 @@ bool Model::addToScene(std::shared_ptr<render::Scene> scene, render::PendingChan
bool somethingAdded = false;
qDebug() << "Model::addToScene : " << this->getURL().toString();
// allow the attachments to add to scene
foreach (Model* attachment, _attachments) {
bool attachementSomethingAdded = attachment->addToScene(scene, pendingChanges);
@ -954,7 +955,6 @@ void Model::removeFromScene(std::shared_ptr<render::Scene> scene, render::Pendin
}
_renderItems.clear();
_readyWhenAdded = false;
qDebug() << "Model::removeFromScene : " << this->getURL().toString();
}
bool Model::render(RenderArgs* renderArgs, float alpha) {
@ -2118,8 +2118,8 @@ void Model::renderPart(RenderArgs* args, int meshIndex, int partIndex, bool tran
}
Locations* locations = nullptr;
pickPrograms(batch, mode, translucent, alphaThreshold, hasLightmap, hasTangents, hasSpecular, isSkinned, wireframe,
args, locations);
pickPrograms(batch, mode, translucentMesh, alphaThreshold, hasLightmap, hasTangents, hasSpecular, isSkinned, wireframe,
args, locations);
updateVisibleJointStates();

View file

@ -312,8 +312,7 @@ protected:
float getLimbLength(int jointIndex) const;
/// Allow sub classes to force invalidating the bboxes
void invalidCalculatedMeshBoxes() {
qDebug() << "invalidCalculatedMeshBoxes()";
void invalidCalculatedMeshBoxes() {
_calculatedMeshBoxesValid = false;
_calculatedMeshPartBoxesValid = false;
_calculatedMeshTrianglesValid = false;

View file

@ -44,7 +44,7 @@ template <> void render::jobRun(const ResolveDeferred& job, const SceneContextPo
RenderDeferredTask::RenderDeferredTask() : Task() {
_jobs.push_back(Job(PrepareDeferred()));
_jobs.push_back(Job(DrawBackground()));
_jobs.push_back(Job(DrawOpaque()));
_jobs.push_back(Job(DrawOpaqueDeferred()));
_jobs.push_back(Job(DrawLight()));
_jobs.push_back(Job(ResetGLState()));
_jobs.push_back(Job(RenderDeferred()));
@ -78,6 +78,84 @@ void RenderDeferredTask::run(const SceneContextPointer& sceneContext, const Rend
template <> void render::jobRun(const DrawOpaqueDeferred& job, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) {
PerformanceTimer perfTimer("DrawOpaqueDeferred");
assert(renderContext->args);
assert(renderContext->args->_viewFrustum);
// render opaques
auto& scene = sceneContext->_scene;
auto& items = scene->getMasterBucket().at(ItemFilter::Builder::opaqueShape());
auto& renderDetails = renderContext->args->_details;
ItemIDsBounds inItems;
inItems.reserve(items.size());
for (auto id : items) {
inItems.emplace_back(ItemIDAndBounds(id));
}
ItemIDsBounds& renderedItems = inItems;
renderContext->_numFeedOpaqueItems = renderedItems.size();
ItemIDsBounds culledItems;
culledItems.reserve(inItems.size());
if (renderContext->_cullOpaque) {
renderDetails.pointTo(RenderDetails::OPAQUE_ITEM);
cullItems(sceneContext, renderContext, renderedItems, culledItems);
renderDetails.pointTo(RenderDetails::OTHER_ITEM);
renderedItems = culledItems;
}
renderContext->_numDrawnOpaqueItems = renderedItems.size();
ItemIDsBounds sortedItems;
sortedItems.reserve(culledItems.size());
if (renderContext->_sortOpaque) {
depthSortItems(sceneContext, renderContext, true, renderedItems, sortedItems); // Sort Front to back opaque items!
renderedItems = sortedItems;
}
// ItemIDsBounds sortedItems;
/* ItemMaterialBucketMap stateSortedItems;
stateSortedItems.allocateStandardMaterialBuckets();
if (true) {
for (auto& itemIDAndBound : renderedItems) {
stateSortedItems.insert(itemIDAndBound.id, scene->getItem(itemIDAndBound.id).getMaterialKey());
}
}
*/
if (renderContext->_renderOpaque) {
RenderArgs* args = renderContext->args;
gpu::Batch batch;
args->_batch = &batch;
glm::mat4 projMat;
Transform viewMat;
args->_viewFrustum->evalProjectionMatrix(projMat);
args->_viewFrustum->evalViewTransform(viewMat);
batch.setProjectionTransform(projMat);
batch.setViewTransform(viewMat);
renderContext->args->_renderMode = RenderArgs::NORMAL_RENDER_MODE;
{
GLenum buffers[3];
int bufferCount = 0;
buffers[bufferCount++] = GL_COLOR_ATTACHMENT0;
buffers[bufferCount++] = GL_COLOR_ATTACHMENT1;
buffers[bufferCount++] = GL_COLOR_ATTACHMENT2;
batch._glDrawBuffers(bufferCount, buffers);
}
renderItems(sceneContext, renderContext, renderedItems, renderContext->_maxDrawnOpaqueItems);
args->_context->render((*args->_batch));
args->_batch = nullptr;
}
}
template <> void render::jobRun(const DrawTransparentDeferred& job, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) {
PerformanceTimer perfTimer("DrawTransparentDeferred");
assert(renderContext->args);

View file

@ -35,6 +35,14 @@ namespace render {
template <> void jobRun(const ResolveDeferred& job, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext);
}
class DrawOpaqueDeferred {
public:
};
namespace render {
template <> void jobRun(const DrawOpaqueDeferred& job, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext);
}
class DrawTransparentDeferred {
public:
};

View file

@ -174,7 +174,7 @@ void render::renderItems(const SceneContextPointer& sceneContext, const RenderCo
auto& scene = sceneContext->_scene;
RenderArgs* args = renderContext->args;
// render
if ((maxDrawnItems < 0) || (maxDrawnItems > inItems.size())) {
if ((maxDrawnItems < 0) || (maxDrawnItems > (int) inItems.size())) {
for (auto itemDetails : inItems) {
auto item = scene->getItem(itemDetails.id);
item.render(args);
@ -445,3 +445,18 @@ template <> void render::jobRun(const DrawBackground& job, const SceneContextPoi
// Force the context sync
args->_context->syncCache();
}
void ItemMaterialBucketMap::insert(const ItemID& id, const model::MaterialKey& key) {
// Insert the itemID in every bucket where it filters true
for (auto& bucket : (*this)) {
if (bucket.first.test(key)) {
bucket.second.push_back(id);
}
}
}
void ItemMaterialBucketMap::allocateStandardMaterialBuckets() {
(*this)[model::MaterialFilter::Builder::opaqueDiffuse()];
}

View file

@ -62,6 +62,10 @@ void depthSortItems(const SceneContextPointer& sceneContext, const RenderContext
void renderItems(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemIDsBounds& inItems, int maxDrawnItems = -1);
void materialSortItems(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemIDsBounds& inItems, ItemIDsBounds& outItems);
class DrawOpaque {
public:
};
@ -101,6 +105,20 @@ public:
};
// A map of ItemIDs allowing to create bucket lists of SHAPE type items which are filtered by their
// Material
class ItemMaterialBucketMap : public std::map<model::MaterialFilter, ItemIDs, model::MaterialFilter::Less> {
public:
ItemMaterialBucketMap() {}
void insert(const ItemID& id, const model::MaterialKey& key);
// standard builders allocating the main buckets
void allocateStandardMaterialBuckets();
};
}
#endif // hifi_render_Task_h

View file

@ -24,6 +24,8 @@
#include <AABox.h>
#include <RenderArgs.h>
#include "model/Material.h"
namespace render {
class Context;
@ -216,6 +218,8 @@ public:
virtual void update(const UpdateFunctorPointer& functor) = 0;
virtual const model::MaterialKey getMaterialKey() const = 0;
~PayloadInterface() {}
protected:
};
@ -240,6 +244,9 @@ public:
void render(RenderArgs* args) { _payload->render(args); }
void update(const UpdateFunctorPointer& updateFunctor) { _payload->update(updateFunctor); }
// Shape Type Interface
const model::MaterialKey& getMaterialKey() const { return _payload->getMaterialKey(); }
protected:
PayloadPointer _payload;
ItemKey _key;
@ -275,16 +282,23 @@ template <class T> const ItemKey payloadGetKey(const std::shared_ptr<T>& payload
template <class T> const Item::Bound payloadGetBound(const std::shared_ptr<T>& payloadData) { return Item::Bound(); }
template <class T> void payloadRender(const std::shared_ptr<T>& payloadData, RenderArgs* args) { }
// Shape type interface
template <class T> const model::MaterialKey shapeGetMaterialKey(const std::shared_ptr<T>& payloadData) { return model::MaterialKey(); }
template <class T> class Payload : public Item::PayloadInterface {
public:
typedef std::shared_ptr<T> DataPointer;
typedef UpdateFunctor<T> Updater;
virtual void update(const UpdateFunctorPointer& functor) { static_cast<Updater*>(functor.get())->_func((*_data)); }
// Payload general interface
virtual const ItemKey getKey() const { return payloadGetKey<T>(_data); }
virtual const Item::Bound getBound() const { return payloadGetBound<T>(_data); }
virtual void render(RenderArgs* args) { payloadRender<T>(_data, args); }
virtual void update(const UpdateFunctorPointer& functor) { static_cast<Updater*>(functor.get())->_func((*_data)); }
virtual void render(RenderArgs* args) { payloadRender<T>(_data, args); }
// Shape Type interface
virtual const model::MaterialKey getMaterialKey() const { return shapeGetMaterialKey<T>(_data); }
Payload(const DataPointer& data) : _data(data) {}
protected: