mirror of
https://github.com/overte-org/overte.git
synced 2025-08-08 16:38:27 +02:00
merge
This commit is contained in:
commit
2f32d358c3
28 changed files with 577 additions and 178 deletions
|
@ -14,10 +14,10 @@ var connectSound = SoundCache.getSound("file://" + Paths.resources + "sounds/sho
|
||||||
|
|
||||||
// setup the options needed for that sound
|
// setup the options needed for that sound
|
||||||
var connectSoundOptions = {
|
var connectSoundOptions = {
|
||||||
localOnly: true
|
localOnly: true
|
||||||
}
|
}
|
||||||
|
|
||||||
// play the sound locally once we get the first audio packet from a mixer
|
// play the sound locally once we get the first audio packet from a mixer
|
||||||
Audio.receivedFirstPacket.connect(function(){
|
Audio.receivedFirstPacket.connect(function(){
|
||||||
Audio.playSound(connectSound, connectSoundOptions);
|
Audio.playSound(connectSound, connectSoundOptions);
|
||||||
});
|
});
|
||||||
|
|
|
@ -360,6 +360,10 @@
|
||||||
var elVoxelVolumeSizeZ = document.getElementById("property-voxel-volume-size-z");
|
var elVoxelVolumeSizeZ = document.getElementById("property-voxel-volume-size-z");
|
||||||
var elVoxelSurfaceStyle = document.getElementById("property-voxel-surface-style");
|
var elVoxelSurfaceStyle = document.getElementById("property-voxel-surface-style");
|
||||||
|
|
||||||
|
var elHyperlinkHref = document.getElementById("property-hyperlink-href");
|
||||||
|
var elHyperlinkDescription = document.getElementById("property-hyperlink-description");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (window.EventBridge !== undefined) {
|
if (window.EventBridge !== undefined) {
|
||||||
EventBridge.scriptEventReceived.connect(function(data) {
|
EventBridge.scriptEventReceived.connect(function(data) {
|
||||||
|
@ -467,6 +471,9 @@
|
||||||
elScriptURL.value = properties.script;
|
elScriptURL.value = properties.script;
|
||||||
elUserData.value = properties.userData;
|
elUserData.value = properties.userData;
|
||||||
|
|
||||||
|
elHyperlinkHref.value = properties.href;
|
||||||
|
elHyperlinkDescription.value = properties.description;
|
||||||
|
|
||||||
for (var i = 0; i < allSections.length; i++) {
|
for (var i = 0; i < allSections.length; i++) {
|
||||||
for (var j = 0; j < allSections[i].length; j++) {
|
for (var j = 0; j < allSections[i].length; j++) {
|
||||||
allSections[i][j].style.display = 'none';
|
allSections[i][j].style.display = 'none';
|
||||||
|
@ -612,6 +619,8 @@
|
||||||
|
|
||||||
elLocked.addEventListener('change', createEmitCheckedPropertyUpdateFunction('locked'));
|
elLocked.addEventListener('change', createEmitCheckedPropertyUpdateFunction('locked'));
|
||||||
elName.addEventListener('change', createEmitTextPropertyUpdateFunction('name'));
|
elName.addEventListener('change', createEmitTextPropertyUpdateFunction('name'));
|
||||||
|
elHyperlinkHref.addEventListener('change', createEmitTextPropertyUpdateFunction('href'));
|
||||||
|
elHyperlinkDescription.addEventListener('change', createEmitTextPropertyUpdateFunction('description'));
|
||||||
elVisible.addEventListener('change', createEmitCheckedPropertyUpdateFunction('visible'));
|
elVisible.addEventListener('change', createEmitCheckedPropertyUpdateFunction('visible'));
|
||||||
|
|
||||||
var positionChangeFunction = createEmitVec3PropertyUpdateFunction(
|
var positionChangeFunction = createEmitVec3PropertyUpdateFunction(
|
||||||
|
@ -850,6 +859,9 @@
|
||||||
elVoxelVolumeSizeZ.addEventListener('change', voxelVolumeSizeChangeFunction);
|
elVoxelVolumeSizeZ.addEventListener('change', voxelVolumeSizeChangeFunction);
|
||||||
elVoxelSurfaceStyle.addEventListener('change', createEmitTextPropertyUpdateFunction('voxelSurfaceStyle'));
|
elVoxelSurfaceStyle.addEventListener('change', createEmitTextPropertyUpdateFunction('voxelSurfaceStyle'));
|
||||||
|
|
||||||
|
var hyperlinkChangeFunction = createEmitGroupTextPropertyUpdateFunction('hyperlink','href');
|
||||||
|
var hyperlinkChangeFunction = createEmitGroupTextPropertyUpdateFunction('hyperlink','description');
|
||||||
|
|
||||||
|
|
||||||
elMoveSelectionToGrid.addEventListener("click", function() {
|
elMoveSelectionToGrid.addEventListener("click", function() {
|
||||||
EventBridge.emitWebEvent(JSON.stringify({
|
EventBridge.emitWebEvent(JSON.stringify({
|
||||||
|
@ -937,6 +949,18 @@
|
||||||
<input type="text" id="property-name"></input>
|
<input type="text" id="property-name"></input>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="property">
|
||||||
|
<div class="label">Hyperlink</div>
|
||||||
|
<div class="input-area">Href<br></div>
|
||||||
|
<div class="value">
|
||||||
|
<input id="property-hyperlink-href" class="url"></input>
|
||||||
|
</div>
|
||||||
|
<div class="input-area">Description<br></div> <div class="value">
|
||||||
|
<input id="property-hyperlink-description" class="url"></input>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="property">
|
<div class="property">
|
||||||
<span class="label">Locked</span>
|
<span class="label">Locked</span>
|
||||||
<span class="value">
|
<span class="value">
|
||||||
|
|
|
@ -524,6 +524,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) :
|
||||||
_window->setVisible(true);
|
_window->setVisible(true);
|
||||||
_glWidget->setFocusPolicy(Qt::StrongFocus);
|
_glWidget->setFocusPolicy(Qt::StrongFocus);
|
||||||
_glWidget->setFocus();
|
_glWidget->setFocus();
|
||||||
|
_glWidget->setCursor(Qt::BlankCursor);
|
||||||
|
|
||||||
// enable mouse tracking; otherwise, we only get drag events
|
// enable mouse tracking; otherwise, we only get drag events
|
||||||
_glWidget->setMouseTracking(true);
|
_glWidget->setMouseTracking(true);
|
||||||
|
@ -1891,8 +1892,6 @@ void Application::setEnableVRMode(bool enableVRMode) {
|
||||||
}
|
}
|
||||||
|
|
||||||
resizeGL();
|
resizeGL();
|
||||||
|
|
||||||
updateCursorVisibility();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::setLowVelocityFilter(bool lowVelocityFilter) {
|
void Application::setLowVelocityFilter(bool lowVelocityFilter) {
|
||||||
|
@ -2401,19 +2400,8 @@ void Application::updateCursor(float deltaTime) {
|
||||||
lastMousePos = QCursor::pos();
|
lastMousePos = QCursor::pos();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::updateCursorVisibility() {
|
|
||||||
if (!_cursorVisible ||
|
|
||||||
Menu::getInstance()->isOptionChecked(MenuOption::EnableVRMode) ||
|
|
||||||
Menu::getInstance()->isOptionChecked(MenuOption::Enable3DTVMode)) {
|
|
||||||
_window->setCursor(Qt::BlankCursor);
|
|
||||||
} else {
|
|
||||||
_window->unsetCursor();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Application::setCursorVisible(bool visible) {
|
void Application::setCursorVisible(bool visible) {
|
||||||
_cursorVisible = visible;
|
_cursorVisible = visible;
|
||||||
updateCursorVisibility();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::update(float deltaTime) {
|
void Application::update(float deltaTime) {
|
||||||
|
|
|
@ -475,8 +475,6 @@ private:
|
||||||
void updateProjectionMatrix();
|
void updateProjectionMatrix();
|
||||||
void updateProjectionMatrix(Camera& camera, bool updateViewFrustum = true);
|
void updateProjectionMatrix(Camera& camera, bool updateViewFrustum = true);
|
||||||
|
|
||||||
void updateCursorVisibility();
|
|
||||||
|
|
||||||
void sendPingPackets();
|
void sendPingPackets();
|
||||||
|
|
||||||
void initDisplay();
|
void initDisplay();
|
||||||
|
|
|
@ -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) {
|
void Avatar::removeFromScene(AvatarSharedPointer self, std::shared_ptr<render::Scene> scene, render::PendingChanges& pendingChanges) {
|
||||||
pendingChanges.removeItem(_renderItemID);
|
pendingChanges.removeItem(_renderItemID);
|
||||||
_skeletonModel.removeFromScene(scene, pendingChanges);
|
_skeletonModel.removeFromScene(scene, pendingChanges);
|
||||||
|
getHead()->getFaceModel().removeFromScene(scene, pendingChanges);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Avatar::render(RenderArgs* renderArgs, const glm::vec3& cameraPosition, bool postLighting) {
|
void Avatar::render(RenderArgs* renderArgs, const glm::vec3& cameraPosition, bool postLighting) {
|
||||||
|
|
|
@ -55,7 +55,7 @@ AvatarManager::AvatarManager(QObject* parent) :
|
||||||
_avatarFades() {
|
_avatarFades() {
|
||||||
// register a meta type for the weak pointer we'll use for the owning avatar mixer for each avatar
|
// register a meta type for the weak pointer we'll use for the owning avatar mixer for each avatar
|
||||||
qRegisterMetaType<QWeakPointer<Node> >("NodeWeakPointer");
|
qRegisterMetaType<QWeakPointer<Node> >("NodeWeakPointer");
|
||||||
_myAvatar = std::shared_ptr<MyAvatar>(new MyAvatar());
|
_myAvatar = std::make_shared<MyAvatar>();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AvatarManager::init() {
|
void AvatarManager::init() {
|
||||||
|
@ -97,9 +97,9 @@ void AvatarManager::updateOtherAvatars(float deltaTime) {
|
||||||
// simulate avatars
|
// simulate avatars
|
||||||
AvatarHash::iterator avatarIterator = _avatarHash.begin();
|
AvatarHash::iterator avatarIterator = _avatarHash.begin();
|
||||||
while (avatarIterator != _avatarHash.end()) {
|
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 _myAvatar! Its update has already been done earlier in the main loop.
|
||||||
// DO NOT update or fade out uninitialized Avatars
|
// DO NOT update or fade out uninitialized Avatars
|
||||||
++avatarIterator;
|
++avatarIterator;
|
||||||
|
@ -121,26 +121,30 @@ void AvatarManager::simulateAvatarFades(float deltaTime) {
|
||||||
|
|
||||||
const float SHRINK_RATE = 0.9f;
|
const float SHRINK_RATE = 0.9f;
|
||||||
const float MIN_FADE_SCALE = 0.001f;
|
const float MIN_FADE_SCALE = 0.001f;
|
||||||
|
|
||||||
|
render::ScenePointer scene = Application::getInstance()->getMain3DScene();
|
||||||
|
render::PendingChanges pendingChanges;
|
||||||
while (fadingIterator != _avatarFades.end()) {
|
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);
|
avatar->setTargetScale(avatar->getScale() * SHRINK_RATE, true);
|
||||||
if (avatar->getTargetScale() < MIN_FADE_SCALE) {
|
if (avatar->getTargetScale() < MIN_FADE_SCALE) {
|
||||||
|
avatar->removeFromScene(*fadingIterator, scene, pendingChanges);
|
||||||
fadingIterator = _avatarFades.erase(fadingIterator);
|
fadingIterator = _avatarFades.erase(fadingIterator);
|
||||||
} else {
|
} else {
|
||||||
avatar->simulate(deltaTime);
|
avatar->simulate(deltaTime);
|
||||||
++fadingIterator;
|
++fadingIterator;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
scene->enqueuePendingChanges(pendingChanges);
|
||||||
}
|
}
|
||||||
|
|
||||||
AvatarSharedPointer AvatarManager::newSharedAvatar() {
|
AvatarSharedPointer AvatarManager::newSharedAvatar() {
|
||||||
return AvatarSharedPointer(new Avatar());
|
return AvatarSharedPointer(std::make_shared<Avatar>());
|
||||||
}
|
}
|
||||||
|
|
||||||
// virtual
|
// virtual
|
||||||
AvatarSharedPointer AvatarManager::addAvatar(const QUuid& sessionUUID, const QWeakPointer<Node>& mixerWeakPointer) {
|
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::ScenePointer scene = Application::getInstance()->getMain3DScene();
|
||||||
render::PendingChanges pendingChanges;
|
render::PendingChanges pendingChanges;
|
||||||
avatar->addToScene(avatar, scene, pendingChanges);
|
avatar->addToScene(avatar, scene, pendingChanges);
|
||||||
|
@ -171,10 +175,6 @@ void AvatarManager::removeAvatar(const QUuid& sessionUUID) {
|
||||||
_avatarFades.push_back(avatarIterator.value());
|
_avatarFades.push_back(avatarIterator.value());
|
||||||
_avatarHash.erase(avatarIterator);
|
_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
|
// clear any avatars that came from an avatar-mixer
|
||||||
AvatarHash::iterator avatarIterator = _avatarHash.begin();
|
AvatarHash::iterator avatarIterator = _avatarHash.begin();
|
||||||
while (avatarIterator != _avatarHash.end()) {
|
while (avatarIterator != _avatarHash.end()) {
|
||||||
Avatar* avatar = reinterpret_cast<Avatar*>(avatarIterator.value().get());
|
auto avatar = std::static_pointer_cast<Avatar>(avatarIterator.value());
|
||||||
if (avatar == _myAvatar.get() || !avatar->isInitialized()) {
|
if (avatar == _myAvatar || !avatar->isInitialized()) {
|
||||||
// don't remove myAvatar or uninitialized avatars from the list
|
// don't remove myAvatar or uninitialized avatars from the list
|
||||||
++avatarIterator;
|
++avatarIterator;
|
||||||
} else {
|
} else {
|
||||||
removeAvatarMotionState(avatar);
|
removeAvatarMotionState(avatar.get());
|
||||||
_avatarFades.push_back(avatarIterator.value());
|
_avatarFades.push_back(avatarIterator.value());
|
||||||
avatarIterator = _avatarHash.erase(avatarIterator);
|
avatarIterator = _avatarHash.erase(avatarIterator);
|
||||||
}
|
}
|
||||||
|
@ -250,7 +250,7 @@ void AvatarManager::handleCollisionEvents(CollisionEvents& collisionEvents) {
|
||||||
void AvatarManager::updateAvatarPhysicsShape(const QUuid& id) {
|
void AvatarManager::updateAvatarPhysicsShape(const QUuid& id) {
|
||||||
AvatarHash::iterator avatarItr = _avatarHash.find(id);
|
AvatarHash::iterator avatarItr = _avatarHash.find(id);
|
||||||
if (avatarItr != _avatarHash.end()) {
|
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;
|
AvatarMotionState* motionState = avatar->_motionState;
|
||||||
if (motionState) {
|
if (motionState) {
|
||||||
motionState->addDirtyFlags(EntityItem::DIRTY_SHAPE);
|
motionState->addDirtyFlags(EntityItem::DIRTY_SHAPE);
|
||||||
|
@ -259,7 +259,7 @@ void AvatarManager::updateAvatarPhysicsShape(const QUuid& id) {
|
||||||
avatar->computeShapeInfo(shapeInfo);
|
avatar->computeShapeInfo(shapeInfo);
|
||||||
btCollisionShape* shape = ObjectMotionState::getShapeManager()->getShape(shapeInfo);
|
btCollisionShape* shape = ObjectMotionState::getShapeManager()->getShape(shapeInfo);
|
||||||
if (shape) {
|
if (shape) {
|
||||||
AvatarMotionState* motionState = new AvatarMotionState(avatar, shape);
|
AvatarMotionState* motionState = new AvatarMotionState(avatar.get(), shape);
|
||||||
avatar->_motionState = motionState;
|
avatar->_motionState = motionState;
|
||||||
_motionStatesToAdd.insert(motionState);
|
_motionStatesToAdd.insert(motionState);
|
||||||
_avatarMotionStates.insert(motionState);
|
_avatarMotionStates.insert(motionState);
|
||||||
|
|
|
@ -267,9 +267,8 @@ void ApplicationOverlay::displayOverlayTexture() {
|
||||||
glLoadIdentity();
|
glLoadIdentity();
|
||||||
glDisable(GL_DEPTH_TEST);
|
glDisable(GL_DEPTH_TEST);
|
||||||
glDisable(GL_LIGHTING);
|
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());
|
glViewport(0, 0, qApp->getDeviceSize().width(), qApp->getDeviceSize().height());
|
||||||
|
|
||||||
static const glm::vec2 topLeft(-1, 1);
|
static const glm::vec2 topLeft(-1, 1);
|
||||||
|
@ -277,9 +276,38 @@ void ApplicationOverlay::displayOverlayTexture() {
|
||||||
static const glm::vec2 texCoordTopLeft(0.0f, 1.0f);
|
static const glm::vec2 texCoordTopLeft(0.0f, 1.0f);
|
||||||
static const glm::vec2 texCoordBottomRight(1.0f, 0.0f);
|
static const glm::vec2 texCoordBottomRight(1.0f, 0.0f);
|
||||||
with_each_texture(_overlays.getTexture(), _newUiTexture, [&] {
|
with_each_texture(_overlays.getTexture(), _newUiTexture, [&] {
|
||||||
DependencyManager::get<GeometryCache>()->renderQuad(topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight,
|
DependencyManager::get<GeometryCache>()->renderQuad(
|
||||||
|
topLeft, bottomRight,
|
||||||
|
texCoordTopLeft, texCoordBottomRight,
|
||||||
glm::vec4(1.0f, 1.0f, 1.0f, _alpha));
|
glm::vec4(1.0f, 1.0f, 1.0f, _alpha));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (!_crosshairTexture) {
|
||||||
|
_crosshairTexture = DependencyManager::get<TextureCache>()->
|
||||||
|
getImageTexture(PathUtils::resourcesPath() + "images/sixense-reticle.png");
|
||||||
|
}
|
||||||
|
|
||||||
|
//draw the mouse pointer
|
||||||
|
glm::vec2 canvasSize = qApp->getCanvasSize();
|
||||||
|
glm::vec2 mouseSize = 32.0f / canvasSize;
|
||||||
|
auto mouseTopLeft = topLeft * mouseSize;
|
||||||
|
auto mouseBottomRight = bottomRight * mouseSize;
|
||||||
|
vec2 mousePosition = vec2(qApp->getMouseX(), qApp->getMouseY());
|
||||||
|
mousePosition /= canvasSize;
|
||||||
|
mousePosition *= 2.0f;
|
||||||
|
mousePosition -= 1.0f;
|
||||||
|
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();
|
} glPopMatrix();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -428,6 +456,9 @@ void ApplicationOverlay::displayOverlayTextureStereo(Camera& whichCamera, float
|
||||||
}
|
}
|
||||||
|
|
||||||
//draw the mouse pointer
|
//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));
|
glBindTexture(GL_TEXTURE_2D, gpu::GLBackend::getTextureID(_crosshairTexture));
|
||||||
glm::vec2 canvasSize = qApp->getCanvasSize();
|
glm::vec2 canvasSize = qApp->getCanvasSize();
|
||||||
const float reticleSize = 40.0f / canvasSize.x * quadWidth;
|
const float reticleSize = 40.0f / canvasSize.x * quadWidth;
|
||||||
|
@ -557,7 +588,9 @@ void ApplicationOverlay::renderPointers() {
|
||||||
_crosshairTexture = TextureCache::getImageTexture(PathUtils::resourcesPath() + "images/sixense-reticle.png");
|
_crosshairTexture = TextureCache::getImageTexture(PathUtils::resourcesPath() + "images/sixense-reticle.png");
|
||||||
}
|
}
|
||||||
glEnable(GL_TEXTURE_2D);
|
glEnable(GL_TEXTURE_2D);
|
||||||
|
glEnable(GL_BLEND);
|
||||||
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
|
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
glBindTexture(GL_TEXTURE_2D, gpu::GLBackend::getTextureID(_crosshairTexture));
|
glBindTexture(GL_TEXTURE_2D, gpu::GLBackend::getTextureID(_crosshairTexture));
|
||||||
|
|
||||||
|
@ -719,8 +752,14 @@ void ApplicationOverlay::renderControllerPointers() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ApplicationOverlay::renderPointersOculus() {
|
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));
|
glBindTexture(GL_TEXTURE_2D, gpu::GLBackend::getTextureID(_crosshairTexture));
|
||||||
glDisable(GL_DEPTH_TEST);
|
glDisable(GL_DEPTH_TEST);
|
||||||
|
|
||||||
glMatrixMode(GL_MODELVIEW);
|
glMatrixMode(GL_MODELVIEW);
|
||||||
|
|
||||||
//Controller Pointers
|
//Controller Pointers
|
||||||
|
@ -745,6 +784,8 @@ void ApplicationOverlay::renderPointersOculus() {
|
||||||
}
|
}
|
||||||
|
|
||||||
glEnable(GL_DEPTH_TEST);
|
glEnable(GL_DEPTH_TEST);
|
||||||
|
glDisable(GL_TEXTURE_2D);
|
||||||
|
glDisable(GL_BLEND);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Renders a small magnification of the currently bound texture at the coordinates
|
//Renders a small magnification of the currently bound texture at the coordinates
|
||||||
|
|
|
@ -70,7 +70,9 @@ EntityItem::EntityItem(const EntityItemID& entityItemID) :
|
||||||
_dirtyFlags(0),
|
_dirtyFlags(0),
|
||||||
_element(nullptr),
|
_element(nullptr),
|
||||||
_physicsInfo(nullptr),
|
_physicsInfo(nullptr),
|
||||||
_simulated(false)
|
_simulated(false),
|
||||||
|
_href(""),
|
||||||
|
_description("")
|
||||||
{
|
{
|
||||||
quint64 now = usecTimestampNow();
|
quint64 now = usecTimestampNow();
|
||||||
_lastSimulated = now;
|
_lastSimulated = now;
|
||||||
|
@ -117,6 +119,8 @@ EntityPropertyFlags EntityItem::getEntityProperties(EncodeBitstreamParams& param
|
||||||
requestedProperties += PROP_MARKETPLACE_ID;
|
requestedProperties += PROP_MARKETPLACE_ID;
|
||||||
requestedProperties += PROP_NAME;
|
requestedProperties += PROP_NAME;
|
||||||
requestedProperties += PROP_SIMULATOR_ID;
|
requestedProperties += PROP_SIMULATOR_ID;
|
||||||
|
requestedProperties += PROP_HREF;
|
||||||
|
requestedProperties += PROP_DESCRIPTION;
|
||||||
|
|
||||||
return requestedProperties;
|
return requestedProperties;
|
||||||
}
|
}
|
||||||
|
@ -246,6 +250,9 @@ OctreeElement::AppendState EntityItem::appendEntityData(OctreePacketData* packet
|
||||||
APPEND_ENTITY_PROPERTY(PROP_MARKETPLACE_ID, getMarketplaceID());
|
APPEND_ENTITY_PROPERTY(PROP_MARKETPLACE_ID, getMarketplaceID());
|
||||||
APPEND_ENTITY_PROPERTY(PROP_NAME, getName());
|
APPEND_ENTITY_PROPERTY(PROP_NAME, getName());
|
||||||
APPEND_ENTITY_PROPERTY(PROP_COLLISION_SOUND_URL, getCollisionSoundURL());
|
APPEND_ENTITY_PROPERTY(PROP_COLLISION_SOUND_URL, getCollisionSoundURL());
|
||||||
|
APPEND_ENTITY_PROPERTY(PROP_HREF, getHref());
|
||||||
|
APPEND_ENTITY_PROPERTY(PROP_DESCRIPTION, getDescription());
|
||||||
|
|
||||||
|
|
||||||
appendSubclassData(packetData, params, entityTreeElementExtraEncodeData,
|
appendSubclassData(packetData, params, entityTreeElementExtraEncodeData,
|
||||||
requestedProperties,
|
requestedProperties,
|
||||||
|
@ -573,6 +580,9 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef
|
||||||
|
|
||||||
READ_ENTITY_PROPERTY(PROP_NAME, QString, setName);
|
READ_ENTITY_PROPERTY(PROP_NAME, QString, setName);
|
||||||
READ_ENTITY_PROPERTY(PROP_COLLISION_SOUND_URL, QString, setCollisionSoundURL);
|
READ_ENTITY_PROPERTY(PROP_COLLISION_SOUND_URL, QString, setCollisionSoundURL);
|
||||||
|
READ_ENTITY_PROPERTY(PROP_HREF, QString, setHref);
|
||||||
|
READ_ENTITY_PROPERTY(PROP_DESCRIPTION, QString, setDescription);
|
||||||
|
|
||||||
bytesRead += readEntitySubclassDataFromBuffer(dataAt, (bytesLeftToRead - bytesRead), args, propertyFlags, overwriteLocalData);
|
bytesRead += readEntitySubclassDataFromBuffer(dataAt, (bytesLeftToRead - bytesRead), args, propertyFlags, overwriteLocalData);
|
||||||
|
|
||||||
////////////////////////////////////
|
////////////////////////////////////
|
||||||
|
@ -905,6 +915,8 @@ EntityItemProperties EntityItem::getProperties() const {
|
||||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(simulatorID, getSimulatorID);
|
COPY_ENTITY_PROPERTY_TO_PROPERTIES(simulatorID, getSimulatorID);
|
||||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(marketplaceID, getMarketplaceID);
|
COPY_ENTITY_PROPERTY_TO_PROPERTIES(marketplaceID, getMarketplaceID);
|
||||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(name, getName);
|
COPY_ENTITY_PROPERTY_TO_PROPERTIES(name, getName);
|
||||||
|
COPY_ENTITY_PROPERTY_TO_PROPERTIES(href, getHref);
|
||||||
|
COPY_ENTITY_PROPERTY_TO_PROPERTIES(description, getDescription);
|
||||||
|
|
||||||
properties._defaultSettings = false;
|
properties._defaultSettings = false;
|
||||||
|
|
||||||
|
@ -963,6 +975,8 @@ bool EntityItem::setProperties(const EntityItemProperties& properties) {
|
||||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(userData, setUserData);
|
SET_ENTITY_PROPERTY_FROM_PROPERTIES(userData, setUserData);
|
||||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(marketplaceID, setMarketplaceID);
|
SET_ENTITY_PROPERTY_FROM_PROPERTIES(marketplaceID, setMarketplaceID);
|
||||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(name, setName);
|
SET_ENTITY_PROPERTY_FROM_PROPERTIES(name, setName);
|
||||||
|
SET_ENTITY_PROPERTY_FROM_PROPERTIES(href, setHref);
|
||||||
|
SET_ENTITY_PROPERTY_FROM_PROPERTIES(description, setDescription);
|
||||||
|
|
||||||
if (somethingChanged) {
|
if (somethingChanged) {
|
||||||
uint64_t now = usecTimestampNow();
|
uint64_t now = usecTimestampNow();
|
||||||
|
|
|
@ -203,7 +203,14 @@ public:
|
||||||
|
|
||||||
inline const glm::quat& getRotation() const { return _transform.getRotation(); }
|
inline const glm::quat& getRotation() const { return _transform.getRotation(); }
|
||||||
inline void setRotation(const glm::quat& rotation) { _transform.setRotation(rotation); }
|
inline void setRotation(const glm::quat& rotation) { _transform.setRotation(rotation); }
|
||||||
|
|
||||||
|
// Hyperlink related getters and setters
|
||||||
|
QString getHref() const { return _href; }
|
||||||
|
void setHref(QString value) { _href = value; }
|
||||||
|
|
||||||
|
QString getDescription() const { return _description; }
|
||||||
|
void setDescription(QString value) { _description = value; }
|
||||||
|
|
||||||
/// Dimensions in meters (0.0 - TREE_SCALE)
|
/// Dimensions in meters (0.0 - TREE_SCALE)
|
||||||
inline const glm::vec3& getDimensions() const { return _transform.getScale(); }
|
inline const glm::vec3& getDimensions() const { return _transform.getScale(); }
|
||||||
virtual void setDimensions(const glm::vec3& value);
|
virtual void setDimensions(const glm::vec3& value);
|
||||||
|
@ -415,6 +422,8 @@ protected:
|
||||||
quint64 _simulatorIDChangedTime; // when was _simulatorID last updated?
|
quint64 _simulatorIDChangedTime; // when was _simulatorID last updated?
|
||||||
QString _marketplaceID;
|
QString _marketplaceID;
|
||||||
QString _name;
|
QString _name;
|
||||||
|
QString _href; //Hyperlink href
|
||||||
|
QString _description; //Hyperlink description
|
||||||
|
|
||||||
// NOTE: Damping is applied like this: v *= pow(1 - damping, dt)
|
// NOTE: Damping is applied like this: v *= pow(1 - damping, dt)
|
||||||
//
|
//
|
||||||
|
|
|
@ -347,6 +347,9 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const {
|
||||||
CHECK_PROPERTY_CHANGE(PROP_VOXEL_SURFACE_STYLE, voxelSurfaceStyle);
|
CHECK_PROPERTY_CHANGE(PROP_VOXEL_SURFACE_STYLE, voxelSurfaceStyle);
|
||||||
CHECK_PROPERTY_CHANGE(PROP_LINE_WIDTH, lineWidth);
|
CHECK_PROPERTY_CHANGE(PROP_LINE_WIDTH, lineWidth);
|
||||||
CHECK_PROPERTY_CHANGE(PROP_LINE_POINTS, linePoints);
|
CHECK_PROPERTY_CHANGE(PROP_LINE_POINTS, linePoints);
|
||||||
|
CHECK_PROPERTY_CHANGE(PROP_HREF, href);
|
||||||
|
CHECK_PROPERTY_CHANGE(PROP_DESCRIPTION, description);
|
||||||
|
|
||||||
changedProperties += _stage.getChangedProperties();
|
changedProperties += _stage.getChangedProperties();
|
||||||
changedProperties += _atmosphere.getChangedProperties();
|
changedProperties += _atmosphere.getChangedProperties();
|
||||||
changedProperties += _skybox.getChangedProperties();
|
changedProperties += _skybox.getChangedProperties();
|
||||||
|
@ -439,7 +442,9 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine, bool
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(voxelSurfaceStyle);
|
COPY_PROPERTY_TO_QSCRIPTVALUE(voxelSurfaceStyle);
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(lineWidth);
|
COPY_PROPERTY_TO_QSCRIPTVALUE(lineWidth);
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(linePoints);
|
COPY_PROPERTY_TO_QSCRIPTVALUE(linePoints);
|
||||||
|
COPY_PROPERTY_TO_QSCRIPTVALUE(href);
|
||||||
|
COPY_PROPERTY_TO_QSCRIPTVALUE(description);
|
||||||
|
|
||||||
// Sitting properties support
|
// Sitting properties support
|
||||||
if (!skipDefaults) {
|
if (!skipDefaults) {
|
||||||
QScriptValue sittingPoints = engine->newObject();
|
QScriptValue sittingPoints = engine->newObject();
|
||||||
|
@ -548,6 +553,9 @@ void EntityItemProperties::copyFromScriptValue(const QScriptValue& object, bool
|
||||||
COPY_PROPERTY_FROM_QSCRIPTVALUE(voxelSurfaceStyle, uint16_t, setVoxelSurfaceStyle);
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(voxelSurfaceStyle, uint16_t, setVoxelSurfaceStyle);
|
||||||
COPY_PROPERTY_FROM_QSCRIPTVALUE(lineWidth, float, setLineWidth);
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(lineWidth, float, setLineWidth);
|
||||||
COPY_PROPERTY_FROM_QSCRIPTVALUE(linePoints, qVectorVec3, setLinePoints);
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(linePoints, qVectorVec3, setLinePoints);
|
||||||
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(href, QString, setHref);
|
||||||
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(description, QString, setDescription);
|
||||||
|
|
||||||
|
|
||||||
if (!honorReadOnly) {
|
if (!honorReadOnly) {
|
||||||
// this is used by the json reader to set things that we don't want javascript to able to affect.
|
// this is used by the json reader to set things that we don't want javascript to able to affect.
|
||||||
|
@ -712,6 +720,8 @@ bool EntityItemProperties::encodeEntityEditPacket(PacketType command, EntityItem
|
||||||
APPEND_ENTITY_PROPERTY(PROP_LOCKED, properties.getLocked());
|
APPEND_ENTITY_PROPERTY(PROP_LOCKED, properties.getLocked());
|
||||||
APPEND_ENTITY_PROPERTY(PROP_USER_DATA, properties.getUserData());
|
APPEND_ENTITY_PROPERTY(PROP_USER_DATA, properties.getUserData());
|
||||||
APPEND_ENTITY_PROPERTY(PROP_SIMULATOR_ID, properties.getSimulatorID());
|
APPEND_ENTITY_PROPERTY(PROP_SIMULATOR_ID, properties.getSimulatorID());
|
||||||
|
APPEND_ENTITY_PROPERTY(PROP_HREF, properties.getHref());
|
||||||
|
APPEND_ENTITY_PROPERTY(PROP_DESCRIPTION, properties.getDescription());
|
||||||
|
|
||||||
if (properties.getType() == EntityTypes::Web) {
|
if (properties.getType() == EntityTypes::Web) {
|
||||||
APPEND_ENTITY_PROPERTY(PROP_SOURCE_URL, properties.getSourceUrl());
|
APPEND_ENTITY_PROPERTY(PROP_SOURCE_URL, properties.getSourceUrl());
|
||||||
|
@ -962,6 +972,8 @@ bool EntityItemProperties::decodeEntityEditPacket(const unsigned char* data, int
|
||||||
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_LOCKED, bool, setLocked);
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_LOCKED, bool, setLocked);
|
||||||
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_USER_DATA, QString, setUserData);
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_USER_DATA, QString, setUserData);
|
||||||
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_SIMULATOR_ID, QUuid, setSimulatorID);
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_SIMULATOR_ID, QUuid, setSimulatorID);
|
||||||
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_HREF, QString, setHref);
|
||||||
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_DESCRIPTION, QString, setDescription);
|
||||||
|
|
||||||
if (properties.getType() == EntityTypes::Web) {
|
if (properties.getType() == EntityTypes::Web) {
|
||||||
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_SOURCE_URL, QString, setSourceUrl);
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_SOURCE_URL, QString, setSourceUrl);
|
||||||
|
@ -1147,6 +1159,9 @@ void EntityItemProperties::markAllChanged() {
|
||||||
_lineWidthChanged = true;
|
_lineWidthChanged = true;
|
||||||
_linePointsChanged = true;
|
_linePointsChanged = true;
|
||||||
|
|
||||||
|
_hrefChanged = true;
|
||||||
|
_descriptionChanged = true;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The maximum bounding cube for the entity, independent of it's rotation.
|
/// The maximum bounding cube for the entity, independent of it's rotation.
|
||||||
|
|
|
@ -148,6 +148,8 @@ public:
|
||||||
DEFINE_PROPERTY_REF(PROP_SOURCE_URL, SourceUrl, sourceUrl, QString);
|
DEFINE_PROPERTY_REF(PROP_SOURCE_URL, SourceUrl, sourceUrl, QString);
|
||||||
DEFINE_PROPERTY(PROP_LINE_WIDTH, LineWidth, lineWidth, float);
|
DEFINE_PROPERTY(PROP_LINE_WIDTH, LineWidth, lineWidth, float);
|
||||||
DEFINE_PROPERTY_REF(LINE_POINTS, LinePoints, linePoints, QVector<glm::vec3>);
|
DEFINE_PROPERTY_REF(LINE_POINTS, LinePoints, linePoints, QVector<glm::vec3>);
|
||||||
|
DEFINE_PROPERTY_REF(PROP_HREF, Href, href, QString);
|
||||||
|
DEFINE_PROPERTY_REF(PROP_DESCRIPTION, Description, description, QString);
|
||||||
|
|
||||||
static QString getBackgroundModeString(BackgroundMode mode);
|
static QString getBackgroundModeString(BackgroundMode mode);
|
||||||
|
|
||||||
|
@ -295,6 +297,8 @@ inline QDebug operator<<(QDebug debug, const EntityItemProperties& properties) {
|
||||||
DEBUG_PROPERTY_IF_CHANGED(debug, properties, VoxelVolumeSize, voxelVolumeSize, "");
|
DEBUG_PROPERTY_IF_CHANGED(debug, properties, VoxelVolumeSize, voxelVolumeSize, "");
|
||||||
DEBUG_PROPERTY_IF_CHANGED(debug, properties, VoxelData, voxelData, "");
|
DEBUG_PROPERTY_IF_CHANGED(debug, properties, VoxelData, voxelData, "");
|
||||||
DEBUG_PROPERTY_IF_CHANGED(debug, properties, VoxelSurfaceStyle, voxelSurfaceStyle, "");
|
DEBUG_PROPERTY_IF_CHANGED(debug, properties, VoxelSurfaceStyle, voxelSurfaceStyle, "");
|
||||||
|
DEBUG_PROPERTY_IF_CHANGED(debug, properties, Href, href, "");
|
||||||
|
DEBUG_PROPERTY_IF_CHANGED(debug, properties, Description, description, "");
|
||||||
|
|
||||||
properties.getStage().debugDump();
|
properties.getStage().debugDump();
|
||||||
properties.getAtmosphere().debugDump();
|
properties.getAtmosphere().debugDump();
|
||||||
|
|
|
@ -117,6 +117,10 @@ enum EntityPropertyList {
|
||||||
//for lines
|
//for lines
|
||||||
PROP_LINE_WIDTH,
|
PROP_LINE_WIDTH,
|
||||||
PROP_LINE_POINTS,
|
PROP_LINE_POINTS,
|
||||||
|
|
||||||
|
// used by hyperlinks
|
||||||
|
PROP_HREF,
|
||||||
|
PROP_DESCRIPTION,
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// ATTENTION: add new properties ABOVE this line
|
// ATTENTION: add new properties ABOVE this line
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#include "EntityTree.h"
|
#include "EntityTree.h"
|
||||||
#include "EntitiesLogging.h"
|
#include "EntitiesLogging.h"
|
||||||
#include "EntityTreeElement.h"
|
#include "EntityTreeElement.h"
|
||||||
|
#include "OctreeConstants.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -90,8 +91,8 @@ void LineEntityItem::setLinePoints(const QVector<glm::vec3>& points) {
|
||||||
for (int i = 0; i < points.size(); i++) {
|
for (int i = 0; i < points.size(); i++) {
|
||||||
glm::vec3 point = points.at(i);
|
glm::vec3 point = points.at(i);
|
||||||
// Make sure all of our points are valid numbers.
|
// Make sure all of our points are valid numbers.
|
||||||
// Must be greater than 0 because vector component is set to 0 if it is invalid data
|
// Must be greater than 0 because vector component is set to 0 if it is invalid data. Also should never be greater than TREE_SCALE
|
||||||
if (point.x > 0 && point.y > 0 && point.z > 0){
|
if ( (point.x > 0 && point.x < TREE_SCALE) && (point.y > 0 && point.y < TREE_SCALE) && (point.z > 0 && point.z < TREE_SCALE) ) {
|
||||||
sanitizedPoints << point;
|
sanitizedPoints << point;
|
||||||
} else {
|
} else {
|
||||||
++invalidPoints;
|
++invalidPoints;
|
||||||
|
|
|
@ -1902,8 +1902,8 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping,
|
||||||
} else {
|
} else {
|
||||||
material._material->setDiffuse(material.diffuse);
|
material._material->setDiffuse(material.diffuse);
|
||||||
}
|
}
|
||||||
material._material->setSpecular(material.specular);
|
material._material->setMetallic(glm::length(material.specular));
|
||||||
material._material->setShininess(material.shininess);
|
material._material->setGloss(material.shininess);
|
||||||
|
|
||||||
if (material.opacity <= 0.0f) {
|
if (material.opacity <= 0.0f) {
|
||||||
material._material->setOpacity(1.0f);
|
material._material->setOpacity(1.0f);
|
||||||
|
|
|
@ -134,8 +134,8 @@ void setMeshPartDefaults(FBXMeshPart& meshPart, QString materialID) {
|
||||||
meshPart._material = model::MaterialPointer(new model::Material());
|
meshPart._material = model::MaterialPointer(new model::Material());
|
||||||
meshPart._material->setDiffuse(glm::vec3(1.0, 1.0, 1.0));
|
meshPart._material->setDiffuse(glm::vec3(1.0, 1.0, 1.0));
|
||||||
meshPart._material->setOpacity(1.0);
|
meshPart._material->setOpacity(1.0);
|
||||||
meshPart._material->setSpecular(glm::vec3(1.0, 1.0, 1.0));
|
meshPart._material->setMetallic(0.0);
|
||||||
meshPart._material->setShininess(96.0);
|
meshPart._material->setGloss(96.0);
|
||||||
meshPart._material->setEmissive(glm::vec3(0.0, 0.0, 0.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;
|
meshPart.specularTexture.filename = material->specularTextureFilename;
|
||||||
// ... and some things are set in the underlying material.
|
// ... and some things are set in the underlying material.
|
||||||
meshPart._material->setDiffuse(material->diffuseColor);
|
meshPart._material->setDiffuse(material->diffuseColor);
|
||||||
meshPart._material->setSpecular(material->specularColor);
|
meshPart._material->setMetallic(glm::length(material->specularColor));
|
||||||
meshPart._material->setShininess(material->shininess);
|
meshPart._material->setGloss(material->shininess);
|
||||||
meshPart._material->setOpacity(material->opacity);
|
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();
|
// 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) << " quadIndices.count() =" << meshPart.quadIndices.count();
|
||||||
qCDebug(modelformat) << " triangleIndices.count() =" << meshPart.triangleIndices.count();
|
qCDebug(modelformat) << " triangleIndices.count() =" << meshPart.triangleIndices.count();
|
||||||
qCDebug(modelformat) << " diffuseColor =" << meshPart.diffuseColor << "mat =" << meshPart._material->getDiffuse();
|
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) << " emissiveColor =" << meshPart.emissiveColor << "mat =" << meshPart._material->getEmissive();
|
||||||
qCDebug(modelformat) << " emissiveParams =" << meshPart.emissiveParams;
|
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) << " opacity =" << meshPart.opacity << "mat =" << meshPart._material->getOpacity();
|
||||||
qCDebug(modelformat) << " materialID =" << meshPart.materialID;
|
qCDebug(modelformat) << " materialID =" << meshPart.materialID;
|
||||||
qCDebug(modelformat) << " diffuse texture =" << meshPart.diffuseTexture.filename;
|
qCDebug(modelformat) << " diffuse texture =" << meshPart.diffuseTexture.filename;
|
||||||
|
|
|
@ -437,6 +437,8 @@ public:
|
||||||
|
|
||||||
explicit operator bool() const { return bool(_texture); }
|
explicit operator bool() const { return bool(_texture); }
|
||||||
bool operator !() const { return (!_texture); }
|
bool operator !() const { return (!_texture); }
|
||||||
|
|
||||||
|
bool isValid() const { return bool(_texture); }
|
||||||
};
|
};
|
||||||
typedef std::vector<TextureView> TextureViews;
|
typedef std::vector<TextureView> TextureViews;
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@ using namespace model;
|
||||||
using namespace gpu;
|
using namespace gpu;
|
||||||
|
|
||||||
Material::Material() :
|
Material::Material() :
|
||||||
_flags(0),
|
_key(0),
|
||||||
_schemaBuffer(),
|
_schemaBuffer(),
|
||||||
_textureMap() {
|
_textureMap() {
|
||||||
|
|
||||||
|
@ -26,13 +26,13 @@ Material::Material() :
|
||||||
}
|
}
|
||||||
|
|
||||||
Material::Material(const Material& material) :
|
Material::Material(const Material& material) :
|
||||||
_flags(material._flags),
|
_key(material._key),
|
||||||
_schemaBuffer(material._schemaBuffer),
|
_schemaBuffer(material._schemaBuffer),
|
||||||
_textureMap(material._textureMap) {
|
_textureMap(material._textureMap) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Material& Material::operator= (const Material& material) {
|
Material& Material::operator= (const Material& material) {
|
||||||
_flags = (material._flags);
|
_key = (material._key);
|
||||||
_schemaBuffer = (material._schemaBuffer);
|
_schemaBuffer = (material._schemaBuffer);
|
||||||
_textureMap = (material._textureMap);
|
_textureMap = (material._textureMap);
|
||||||
|
|
||||||
|
@ -43,52 +43,32 @@ Material::~Material() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Material::setDiffuse(const Color& diffuse) {
|
void Material::setDiffuse(const Color& diffuse) {
|
||||||
if (glm::any(glm::greaterThan(diffuse, Color(0.0f)))) {
|
_key.setDiffuse(glm::any(glm::greaterThan(diffuse, Color(0.0f))));
|
||||||
_flags.set(DIFFUSE_BIT);
|
|
||||||
} else {
|
|
||||||
_flags.reset(DIFFUSE_BIT);
|
|
||||||
}
|
|
||||||
_schemaBuffer.edit<Schema>()._diffuse = diffuse;
|
_schemaBuffer.edit<Schema>()._diffuse = diffuse;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Material::setSpecular(const Color& specular) {
|
void Material::setMetallic(float metallic) {
|
||||||
if (glm::any(glm::greaterThan(specular, Color(0.0f)))) {
|
_key.setMetallic(metallic > 0.0f);
|
||||||
_flags.set(SPECULAR_BIT);
|
_schemaBuffer.edit<Schema>()._metallic = glm::vec3(metallic);
|
||||||
} else {
|
|
||||||
_flags.reset(SPECULAR_BIT);
|
|
||||||
}
|
|
||||||
_schemaBuffer.edit<Schema>()._specular = specular;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Material::setEmissive(const Color& emissive) {
|
void Material::setEmissive(const Color& emissive) {
|
||||||
if (glm::any(glm::greaterThan(emissive, Color(0.0f)))) {
|
_key.setEmissive(glm::any(glm::greaterThan(emissive, Color(0.0f))));
|
||||||
_flags.set(EMISSIVE_BIT);
|
|
||||||
} else {
|
|
||||||
_flags.reset(EMISSIVE_BIT);
|
|
||||||
}
|
|
||||||
_schemaBuffer.edit<Schema>()._emissive = emissive;
|
_schemaBuffer.edit<Schema>()._emissive = emissive;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Material::setShininess(float shininess) {
|
void Material::setGloss(float gloss) {
|
||||||
if (shininess > 0.0f) {
|
_key.setGloss((gloss > 0.0f));
|
||||||
_flags.set(SHININESS_BIT);
|
_schemaBuffer.edit<Schema>()._gloss = gloss;
|
||||||
} else {
|
|
||||||
_flags.reset(SHININESS_BIT);
|
|
||||||
}
|
|
||||||
_schemaBuffer.edit<Schema>()._shininess = shininess;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Material::setOpacity(float opacity) {
|
void Material::setOpacity(float opacity) {
|
||||||
if (opacity >= 1.0f) {
|
_key.setTransparent((opacity < 1.0f));
|
||||||
_flags.reset(TRANSPARENT_BIT);
|
|
||||||
} else {
|
|
||||||
_flags.set(TRANSPARENT_BIT);
|
|
||||||
}
|
|
||||||
_schemaBuffer.edit<Schema>()._opacity = opacity;
|
_schemaBuffer.edit<Schema>()._opacity = opacity;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Material::setTextureView(MapChannel channel, const gpu::TextureView& view) {
|
void Material::setTextureView(MapChannel channel, const gpu::TextureView& view) {
|
||||||
_flags.set(DIFFUSE_MAP_BIT + channel);
|
_key.setMapChannel(channel, (view.isValid()));
|
||||||
_textureMap[channel] = view;
|
_textureMap[channel] = view;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,177 @@
|
||||||
|
|
||||||
namespace model {
|
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 {
|
class Material {
|
||||||
public:
|
public:
|
||||||
typedef gpu::BufferView UniformBufferView;
|
typedef gpu::BufferView UniformBufferView;
|
||||||
|
@ -30,52 +201,27 @@ public:
|
||||||
|
|
||||||
typedef glm::vec3 Color;
|
typedef glm::vec3 Color;
|
||||||
|
|
||||||
enum MapChannel {
|
typedef MaterialKey::MapChannel MapChannel;
|
||||||
DIFFUSE_MAP = 0,
|
|
||||||
SPECULAR_MAP,
|
|
||||||
SHININESS_MAP,
|
|
||||||
EMISSIVE_MAP,
|
|
||||||
OPACITY_MAP,
|
|
||||||
NORMAL_MAP,
|
|
||||||
|
|
||||||
NUM_MAPS,
|
|
||||||
};
|
|
||||||
typedef std::map<MapChannel, TextureView> TextureMap;
|
typedef std::map<MapChannel, TextureView> TextureMap;
|
||||||
typedef std::bitset<NUM_MAPS> MapFlags;
|
typedef std::bitset<MaterialKey::NUM_MAP_CHANNELS> 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;
|
|
||||||
|
|
||||||
Material();
|
Material();
|
||||||
Material(const Material& material);
|
Material(const Material& material);
|
||||||
Material& operator= (const Material& material);
|
Material& operator= (const Material& material);
|
||||||
virtual ~Material();
|
virtual ~Material();
|
||||||
|
|
||||||
|
const MaterialKey& getKey() const { return _key; }
|
||||||
|
|
||||||
const Color& getEmissive() const { return _schemaBuffer.get<Schema>()._emissive; }
|
const Color& getEmissive() const { return _schemaBuffer.get<Schema>()._emissive; }
|
||||||
const Color& getDiffuse() const { return _schemaBuffer.get<Schema>()._diffuse; }
|
const Color& getDiffuse() const { return _schemaBuffer.get<Schema>()._diffuse; }
|
||||||
const Color& getSpecular() const { return _schemaBuffer.get<Schema>()._specular; }
|
float getMetallic() const { return _schemaBuffer.get<Schema>()._metallic.x; }
|
||||||
float getShininess() const { return _schemaBuffer.get<Schema>()._shininess; }
|
float getGloss() const { return _schemaBuffer.get<Schema>()._gloss; }
|
||||||
float getOpacity() const { return _schemaBuffer.get<Schema>()._opacity; }
|
float getOpacity() const { return _schemaBuffer.get<Schema>()._opacity; }
|
||||||
|
|
||||||
void setDiffuse(const Color& diffuse);
|
|
||||||
void setSpecular(const Color& specular);
|
|
||||||
void setEmissive(const Color& emissive);
|
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);
|
void setOpacity(float opacity);
|
||||||
|
|
||||||
// Schema to access the attribute values of the material
|
// Schema to access the attribute values of the material
|
||||||
|
@ -84,8 +230,8 @@ public:
|
||||||
|
|
||||||
Color _diffuse{0.5f};
|
Color _diffuse{0.5f};
|
||||||
float _opacity{1.f};
|
float _opacity{1.f};
|
||||||
Color _specular{0.03f};
|
Color _metallic{0.03f};
|
||||||
float _shininess{0.1f};
|
float _gloss{0.1f};
|
||||||
Color _emissive{0.0f};
|
Color _emissive{0.0f};
|
||||||
float _spare0{0.0f};
|
float _spare0{0.0f};
|
||||||
glm::vec4 _spareVec4{0.0f}; // for alignment beauty, Material size == Mat4x4
|
glm::vec4 _spareVec4{0.0f}; // for alignment beauty, Material size == Mat4x4
|
||||||
|
@ -100,7 +246,7 @@ public:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
Flags _flags;
|
MaterialKey _key;
|
||||||
UniformBufferView _schemaBuffer;
|
UniformBufferView _schemaBuffer;
|
||||||
TextureMap _textureMap;
|
TextureMap _textureMap;
|
||||||
|
|
||||||
|
|
|
@ -44,70 +44,73 @@ void Skybox::setCubemap(const gpu::TexturePointer& cubemap) {
|
||||||
|
|
||||||
void Skybox::render(gpu::Batch& batch, const ViewFrustum& viewFrustum, const Skybox& skybox) {
|
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::PipelinePointer thePipeline;
|
||||||
static gpu::BufferPointer theBuffer;
|
static gpu::BufferPointer theBuffer;
|
||||||
static gpu::Stream::FormatPointer theFormat;
|
static gpu::Stream::FormatPointer theFormat;
|
||||||
static gpu::BufferPointer theConstants;
|
static gpu::BufferPointer theConstants;
|
||||||
int SKYBOX_CONSTANTS_SLOT = 0; // need to be defined by the compilation of the shader
|
int SKYBOX_CONSTANTS_SLOT = 0; // need to be defined by the compilation of the shader
|
||||||
if (!thePipeline) {
|
if (!thePipeline) {
|
||||||
auto skyVS = gpu::ShaderPointer(gpu::Shader::createVertex(std::string(Skybox_vert)));
|
auto skyVS = gpu::ShaderPointer(gpu::Shader::createVertex(std::string(Skybox_vert)));
|
||||||
auto skyFS = gpu::ShaderPointer(gpu::Shader::createPixel(std::string(Skybox_frag)));
|
auto skyFS = gpu::ShaderPointer(gpu::Shader::createPixel(std::string(Skybox_frag)));
|
||||||
auto skyShader = gpu::ShaderPointer(gpu::Shader::createProgram(skyVS, skyFS));
|
auto skyShader = gpu::ShaderPointer(gpu::Shader::createProgram(skyVS, skyFS));
|
||||||
|
|
||||||
gpu::Shader::BindingSet bindings;
|
gpu::Shader::BindingSet bindings;
|
||||||
bindings.insert(gpu::Shader::Binding(std::string("cubeMap"), 0));
|
bindings.insert(gpu::Shader::Binding(std::string("cubeMap"), 0));
|
||||||
if (!gpu::Shader::makeProgram(*skyShader, bindings)) {
|
if (!gpu::Shader::makeProgram(*skyShader, bindings)) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SKYBOX_CONSTANTS_SLOT = skyShader->getBuffers().findLocation("skyboxBuffer");
|
SKYBOX_CONSTANTS_SLOT = skyShader->getBuffers().findLocation("skyboxBuffer");
|
||||||
if (SKYBOX_CONSTANTS_SLOT == gpu::Shader::INVALID_LOCATION) {
|
if (SKYBOX_CONSTANTS_SLOT == gpu::Shader::INVALID_LOCATION) {
|
||||||
SKYBOX_CONSTANTS_SLOT = skyShader->getUniforms().findLocation("skyboxBuffer");
|
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 float CLIP = 1.0;
|
||||||
const glm::vec2 vertices[4] = { {-CLIP, -CLIP}, {CLIP, -CLIP}, {-CLIP, CLIP}, {CLIP, CLIP}};
|
const glm::vec2 vertices[4] = { {-CLIP, -CLIP}, {CLIP, -CLIP}, {-CLIP, CLIP}, {CLIP, CLIP}};
|
||||||
theBuffer.reset(new gpu::Buffer(sizeof(vertices), (const gpu::Byte*) vertices));
|
theBuffer.reset(new gpu::Buffer(sizeof(vertices), (const gpu::Byte*) vertices));
|
||||||
|
|
||||||
theFormat.reset(new gpu::Stream::Format());
|
theFormat.reset(new gpu::Stream::Format());
|
||||||
theFormat->setAttribute(gpu::Stream::POSITION, gpu::Stream::POSITION, gpu::Element(gpu::VEC2, gpu::FLOAT, gpu::XYZ));
|
theFormat->setAttribute(gpu::Stream::POSITION, gpu::Stream::POSITION, gpu::Element(gpu::VEC2, gpu::FLOAT, gpu::XYZ));
|
||||||
|
|
||||||
auto color = glm::vec4(1.0f);
|
auto color = glm::vec4(1.0f);
|
||||||
theConstants.reset(new gpu::Buffer(sizeof(color), (const gpu::Byte*) &color));
|
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 {
|
} else {
|
||||||
// skybox has no cubemap, just clear the color buffer
|
// skybox has no cubemap, just clear the color buffer
|
||||||
auto color = skybox.getColor();
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,7 @@ typedef glm::vec3 Color;
|
||||||
class TextureUsage {
|
class TextureUsage {
|
||||||
public:
|
public:
|
||||||
gpu::Texture::Type _type{ gpu::Texture::TEX_2D };
|
gpu::Texture::Type _type{ gpu::Texture::TEX_2D };
|
||||||
Material::MapFlags _materialUsage{ Material::DIFFUSE_MAP };
|
Material::MapFlags _materialUsage{ MaterialKey::DIFFUSE_MAP };
|
||||||
|
|
||||||
int _environmentUsage = 0;
|
int _environmentUsage = 0;
|
||||||
};
|
};
|
||||||
|
|
|
@ -35,6 +35,7 @@ AddressManager::AddressManager() :
|
||||||
_positionGetter(NULL),
|
_positionGetter(NULL),
|
||||||
_orientationGetter(NULL)
|
_orientationGetter(NULL)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AddressManager::isConnected() {
|
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_NETWORK_PORT_KEY = "network_port";
|
||||||
const QString DOMAIN_ICE_SERVER_ADDRESS_KEY = "ice_server_address";
|
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";
|
const QString DOMAIN_ID_KEY = "id";
|
||||||
QString domainIDString = domainObject[DOMAIN_ID_KEY].toString();
|
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(2).toFloat(),
|
||||||
positionRegex.cap(3).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)) {
|
if (!isNaN(newPosition.x) && !isNaN(newPosition.y) && !isNaN(newPosition.z)) {
|
||||||
glm::quat newOrientation;
|
glm::quat newOrientation;
|
||||||
|
|
||||||
|
@ -467,6 +471,10 @@ bool AddressManager::handleUsername(const QString& lookupString) {
|
||||||
|
|
||||||
void AddressManager::setHost(const QString& host) {
|
void AddressManager::setHost(const QString& host) {
|
||||||
if (host != _host) {
|
if (host != _host) {
|
||||||
|
|
||||||
|
// if the host is being changed we should store current address in the history
|
||||||
|
addCurrentAddressToHistory();
|
||||||
|
|
||||||
_host = host;
|
_host = host;
|
||||||
emit hostChanged(_host);
|
emit hostChanged(_host);
|
||||||
}
|
}
|
||||||
|
@ -474,7 +482,8 @@ void AddressManager::setHost(const QString& host) {
|
||||||
|
|
||||||
|
|
||||||
void AddressManager::setDomainInfo(const QString& hostname, quint16 port) {
|
void AddressManager::setDomainInfo(const QString& hostname, quint16 port) {
|
||||||
_host = hostname;
|
setHost(hostname);
|
||||||
|
|
||||||
_rootPlaceID = QUuid();
|
_rootPlaceID = QUuid();
|
||||||
|
|
||||||
qCDebug(networking) << "Possible domain change required to connect to domain at" << hostname << "on" << port;
|
qCDebug(networking) << "Possible domain change required to connect to domain at" << hostname << "on" << port;
|
||||||
|
@ -500,3 +509,22 @@ void AddressManager::copyAddress() {
|
||||||
void AddressManager::copyPath() {
|
void AddressManager::copyPath() {
|
||||||
QApplication::clipboard()->setText(currentPath());
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -98,10 +98,15 @@ private:
|
||||||
bool handleUsername(const QString& lookupString);
|
bool handleUsername(const QString& lookupString);
|
||||||
bool handleDomainID(const QString& host);
|
bool handleDomainID(const QString& host);
|
||||||
|
|
||||||
|
void addCurrentAddressToHistory();
|
||||||
|
|
||||||
QString _host;
|
QString _host;
|
||||||
QUuid _rootPlaceID;
|
QUuid _rootPlaceID;
|
||||||
PositionGetter _positionGetter;
|
PositionGetter _positionGetter;
|
||||||
OrientationGetter _orientationGetter;
|
OrientationGetter _orientationGetter;
|
||||||
|
|
||||||
|
QList<QUrl> _history;
|
||||||
|
quint64 _lastHistoryAppend = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // hifi_AddressManager_h
|
#endif // hifi_AddressManager_h
|
||||||
|
|
|
@ -891,6 +891,9 @@ namespace render {
|
||||||
return payload->model->renderPart(args, payload->meshIndex, payload->partIndex, false);
|
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) {
|
void Model::setVisibleInScene(bool newValue, std::shared_ptr<render::Scene> scene) {
|
||||||
|
|
|
@ -44,7 +44,7 @@ template <> void render::jobRun(const ResolveDeferred& job, const SceneContextPo
|
||||||
RenderDeferredTask::RenderDeferredTask() : Task() {
|
RenderDeferredTask::RenderDeferredTask() : Task() {
|
||||||
_jobs.push_back(Job(PrepareDeferred()));
|
_jobs.push_back(Job(PrepareDeferred()));
|
||||||
_jobs.push_back(Job(DrawBackground()));
|
_jobs.push_back(Job(DrawBackground()));
|
||||||
_jobs.push_back(Job(DrawOpaque()));
|
_jobs.push_back(Job(DrawOpaqueDeferred()));
|
||||||
_jobs.push_back(Job(DrawLight()));
|
_jobs.push_back(Job(DrawLight()));
|
||||||
_jobs.push_back(Job(ResetGLState()));
|
_jobs.push_back(Job(ResetGLState()));
|
||||||
_jobs.push_back(Job(RenderDeferred()));
|
_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) {
|
template <> void render::jobRun(const DrawTransparentDeferred& job, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) {
|
||||||
PerformanceTimer perfTimer("DrawTransparentDeferred");
|
PerformanceTimer perfTimer("DrawTransparentDeferred");
|
||||||
assert(renderContext->args);
|
assert(renderContext->args);
|
||||||
|
|
|
@ -35,6 +35,14 @@ namespace render {
|
||||||
template <> void jobRun(const ResolveDeferred& job, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext);
|
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 {
|
class DrawTransparentDeferred {
|
||||||
public:
|
public:
|
||||||
};
|
};
|
||||||
|
|
|
@ -445,3 +445,18 @@ template <> void render::jobRun(const DrawBackground& job, const SceneContextPoi
|
||||||
// Force the context sync
|
// Force the context sync
|
||||||
args->_context->syncCache();
|
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()];
|
||||||
|
}
|
||||||
|
|
|
@ -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 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 {
|
class DrawOpaque {
|
||||||
public:
|
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
|
#endif // hifi_render_Task_h
|
||||||
|
|
|
@ -24,6 +24,8 @@
|
||||||
#include <AABox.h>
|
#include <AABox.h>
|
||||||
#include <RenderArgs.h>
|
#include <RenderArgs.h>
|
||||||
|
|
||||||
|
#include "model/Material.h"
|
||||||
|
|
||||||
namespace render {
|
namespace render {
|
||||||
|
|
||||||
class Context;
|
class Context;
|
||||||
|
@ -216,6 +218,8 @@ public:
|
||||||
|
|
||||||
virtual void update(const UpdateFunctorPointer& functor) = 0;
|
virtual void update(const UpdateFunctorPointer& functor) = 0;
|
||||||
|
|
||||||
|
virtual const model::MaterialKey getMaterialKey() const = 0;
|
||||||
|
|
||||||
~PayloadInterface() {}
|
~PayloadInterface() {}
|
||||||
protected:
|
protected:
|
||||||
};
|
};
|
||||||
|
@ -240,6 +244,9 @@ public:
|
||||||
void render(RenderArgs* args) { _payload->render(args); }
|
void render(RenderArgs* args) { _payload->render(args); }
|
||||||
void update(const UpdateFunctorPointer& updateFunctor) { _payload->update(updateFunctor); }
|
void update(const UpdateFunctorPointer& updateFunctor) { _payload->update(updateFunctor); }
|
||||||
|
|
||||||
|
// Shape Type Interface
|
||||||
|
const model::MaterialKey& getMaterialKey() const { return _payload->getMaterialKey(); }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
PayloadPointer _payload;
|
PayloadPointer _payload;
|
||||||
ItemKey _key;
|
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> 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) { }
|
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 {
|
template <class T> class Payload : public Item::PayloadInterface {
|
||||||
public:
|
public:
|
||||||
typedef std::shared_ptr<T> DataPointer;
|
typedef std::shared_ptr<T> DataPointer;
|
||||||
typedef UpdateFunctor<T> Updater;
|
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 ItemKey getKey() const { return payloadGetKey<T>(_data); }
|
||||||
virtual const Item::Bound getBound() const { return payloadGetBound<T>(_data); }
|
virtual const Item::Bound getBound() const { return payloadGetBound<T>(_data); }
|
||||||
virtual void render(RenderArgs* args) { payloadRender<T>(_data, args); }
|
virtual void render(RenderArgs* args) { payloadRender<T>(_data, args); }
|
||||||
|
|
||||||
virtual void update(const UpdateFunctorPointer& functor) { static_cast<Updater*>(functor.get())->_func((*_data)); }
|
// Shape Type interface
|
||||||
|
virtual const model::MaterialKey getMaterialKey() const { return shapeGetMaterialKey<T>(_data); }
|
||||||
|
|
||||||
Payload(const DataPointer& data) : _data(data) {}
|
Payload(const DataPointer& data) : _data(data) {}
|
||||||
protected:
|
protected:
|
||||||
|
|
Loading…
Reference in a new issue