mirror of
https://github.com/overte-org/overte.git
synced 2025-04-09 13:02:24 +02:00
Merge pull request #12407 from NissimHadar/shadowControlsOffZvork
Shadow control for zones, models and shapes
This commit is contained in:
commit
3201d2ba21
37 changed files with 284 additions and 147 deletions
|
@ -1,19 +0,0 @@
|
|||
import QtQuick 2.5
|
||||
import Qt.labs.settings 1.0
|
||||
|
||||
import "../../dialogs"
|
||||
|
||||
PreferencesDialog {
|
||||
id: root
|
||||
objectName: "GraphicsPreferencesDialog"
|
||||
title: "Graphics Settings"
|
||||
showCategories: ["Graphics"]
|
||||
property var settings: Settings {
|
||||
category: root.objectName
|
||||
property alias x: root.x
|
||||
property alias y: root.y
|
||||
property alias width: root.width
|
||||
property alias height: root.height
|
||||
}
|
||||
}
|
||||
|
|
@ -1,37 +0,0 @@
|
|||
//
|
||||
// TabletGraphicsPreferences.qml
|
||||
//
|
||||
// Created by Vlad Stelmahovsky on 12 Mar 2017.
|
||||
// Copyright 2017 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
import QtQuick 2.5
|
||||
import QtQuick.Controls 1.4
|
||||
import "tabletWindows"
|
||||
import "../../dialogs"
|
||||
|
||||
StackView {
|
||||
id: profileRoot
|
||||
initialItem: root
|
||||
objectName: "stack"
|
||||
property string title: "Graphics Settings"
|
||||
|
||||
signal sendToScript(var message);
|
||||
|
||||
function pushSource(path) {
|
||||
profileRoot.push(Qt.resolvedUrl(path));
|
||||
}
|
||||
|
||||
function popSource() {
|
||||
profileRoot.pop();
|
||||
}
|
||||
|
||||
TabletPreferencesDialog {
|
||||
id: root
|
||||
objectName: "TabletGraphicsPreferences"
|
||||
showCategories: ["Graphics"]
|
||||
}
|
||||
}
|
|
@ -43,6 +43,7 @@
|
|||
#include "ui/StandAloneJSConsole.h"
|
||||
#include "InterfaceLogging.h"
|
||||
#include "LocationBookmarks.h"
|
||||
#include "DeferredLightingEffect.h"
|
||||
|
||||
#if defined(Q_OS_MAC) || defined(Q_OS_WIN)
|
||||
#include "SpeechRecognizer.h"
|
||||
|
@ -361,10 +362,15 @@ Menu::Menu() {
|
|||
MenuWrapper* developerMenu = addMenu("Developer", "Developer");
|
||||
|
||||
// Developer > Graphics...
|
||||
action = addActionToQMenuAndActionHash(developerMenu, "Graphics...");
|
||||
connect(action, &QAction::triggered, [] {
|
||||
qApp->showDialog(QString("hifi/dialogs/GraphicsPreferencesDialog.qml"),
|
||||
QString("hifi/tablet/TabletGraphicsPreferences.qml"), "GraphicsPreferencesDialog");
|
||||
MenuWrapper* graphicsOptionsMenu = developerMenu->addMenu("Render");
|
||||
action = addCheckableActionToQMenuAndActionHash(graphicsOptionsMenu, MenuOption::Shadows, 0, true);
|
||||
connect(action, &QAction::triggered, [action] {
|
||||
DependencyManager::get<DeferredLightingEffect>()->setShadowMapEnabled(action->isChecked());
|
||||
});
|
||||
|
||||
action = addCheckableActionToQMenuAndActionHash(graphicsOptionsMenu, MenuOption::AmbientOcclusion, 0, false);
|
||||
connect(action, &QAction::triggered, [action] {
|
||||
DependencyManager::get<DeferredLightingEffect>()->setAmbientOcclusionEnabled(action->isChecked());
|
||||
});
|
||||
|
||||
// Developer > UI >>>
|
||||
|
|
|
@ -204,6 +204,8 @@ namespace MenuOption {
|
|||
const QString WorldAxes = "World Axes";
|
||||
const QString DesktopTabletToToolbar = "Desktop Tablet Becomes Toolbar";
|
||||
const QString HMDTabletToToolbar = "HMD Tablet Becomes Toolbar";
|
||||
const QString Shadows = "Shadows";
|
||||
const QString AmbientOcclusion = "AmbientOcclusion";
|
||||
}
|
||||
|
||||
#endif // hifi_Menu_h
|
||||
|
|
|
@ -1112,6 +1112,7 @@ void MyAvatar::setEnableDebugDrawIKChains(bool isEnabled) {
|
|||
|
||||
void MyAvatar::setEnableMeshVisible(bool isEnabled) {
|
||||
_skeletonModel->setVisibleInScene(isEnabled, qApp->getMain3DScene(), render::ItemKey::TAG_BITS_NONE, true);
|
||||
_skeletonModel->setCanCastShadow(isEnabled, qApp->getMain3DScene(), render::ItemKey::TAG_BITS_NONE, true);
|
||||
}
|
||||
|
||||
void MyAvatar::setEnableInverseKinematics(bool isEnabled) {
|
||||
|
@ -1464,6 +1465,7 @@ void MyAvatar::setSkeletonModelURL(const QUrl& skeletonModelURL) {
|
|||
int skeletonModelChangeCount = _skeletonModelChangeCount;
|
||||
Avatar::setSkeletonModelURL(skeletonModelURL);
|
||||
_skeletonModel->setVisibleInScene(true, qApp->getMain3DScene(), render::ItemKey::TAG_BITS_NONE, true);
|
||||
_skeletonModel->setCanCastShadow(true, qApp->getMain3DScene(), render::ItemKey::TAG_BITS_NONE, true);
|
||||
_headBoneSet.clear();
|
||||
_cauterizationNeedsUpdate = true;
|
||||
|
||||
|
@ -1819,12 +1821,6 @@ void MyAvatar::attach(const QString& modelURL, const QString& jointName,
|
|||
Avatar::attach(modelURL, jointName, translation, rotation, scale, isSoft, allowDuplicates, useSaved);
|
||||
}
|
||||
|
||||
void MyAvatar::setVisibleInSceneIfReady(Model* model, const render::ScenePointer& scene, bool visible) {
|
||||
if (model->isActive() && model->isRenderable()) {
|
||||
model->setVisibleInScene(visible, scene, render::ItemKey::TAG_BITS_NONE, true);
|
||||
}
|
||||
}
|
||||
|
||||
void MyAvatar::initHeadBones() {
|
||||
int neckJointIndex = -1;
|
||||
if (_skeletonModel->isLoaded()) {
|
||||
|
@ -2014,8 +2010,11 @@ void MyAvatar::preDisplaySide(RenderArgs* renderArgs) {
|
|||
_attachmentData[i].jointName.compare("RightEye", Qt::CaseInsensitive) == 0 ||
|
||||
_attachmentData[i].jointName.compare("HeadTop_End", Qt::CaseInsensitive) == 0 ||
|
||||
_attachmentData[i].jointName.compare("Face", Qt::CaseInsensitive) == 0) {
|
||||
|
||||
_attachmentModels[i]->setVisibleInScene(shouldDrawHead, qApp->getMain3DScene(),
|
||||
render::ItemKey::TAG_BITS_NONE, true);
|
||||
|
||||
_attachmentModels[i]->setCanCastShadow(shouldDrawHead, qApp->getMain3DScene(), render::ItemKey::TAG_BITS_NONE, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -677,8 +677,6 @@ private:
|
|||
// These are made private for MyAvatar so that you will use the "use" methods instead
|
||||
virtual void setSkeletonModelURL(const QUrl& skeletonModelURL) override;
|
||||
|
||||
void setVisibleInSceneIfReady(Model* model, const render::ScenePointer& scene, bool visiblity);
|
||||
|
||||
virtual void updatePalms() override {}
|
||||
void lateUpdatePalms();
|
||||
|
||||
|
|
|
@ -164,7 +164,12 @@ ItemKey EntityRenderer::getKey() {
|
|||
return ItemKey::Builder::transparentShape().withTypeMeta().withTagBits(render::ItemKey::TAG_BITS_0 | render::ItemKey::TAG_BITS_1);
|
||||
}
|
||||
|
||||
return ItemKey::Builder::opaqueShape().withTypeMeta().withTagBits(render::ItemKey::TAG_BITS_0 | render::ItemKey::TAG_BITS_1);
|
||||
// This allows shapes to cast shadows
|
||||
if (_canCastShadow) {
|
||||
return ItemKey::Builder::opaqueShape().withTypeMeta().withTagBits(render::ItemKey::TAG_BITS_0 | render::ItemKey::TAG_BITS_1).withShadowCaster();
|
||||
} else {
|
||||
return ItemKey::Builder::opaqueShape().withTypeMeta().withTagBits(render::ItemKey::TAG_BITS_0 | render::ItemKey::TAG_BITS_1);
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t EntityRenderer::metaFetchMetaSubItems(ItemIDs& subItems) {
|
||||
|
@ -377,6 +382,7 @@ void EntityRenderer::doRenderUpdateSynchronous(const ScenePointer& scene, Transa
|
|||
|
||||
_moving = entity->isMovingRelativeToParent();
|
||||
_visible = entity->getVisible();
|
||||
_canCastShadow = entity->getCanCastShadow();
|
||||
_cauterized = entity->getCauterized();
|
||||
_needsRenderUpdate = false;
|
||||
});
|
||||
|
|
|
@ -126,6 +126,7 @@ protected:
|
|||
bool _isFading{ _entitiesShouldFadeFunction() };
|
||||
bool _prevIsTransparent { false };
|
||||
bool _visible { false };
|
||||
bool _canCastShadow { false };
|
||||
bool _cauterized { false };
|
||||
bool _moving { false };
|
||||
bool _needsRenderUpdate { false };
|
||||
|
|
|
@ -1356,6 +1356,10 @@ void ModelEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& sce
|
|||
}
|
||||
// TODO? early exit here when not visible?
|
||||
|
||||
if (model->canCastShadow() != _canCastShadow) {
|
||||
model->setCanCastShadow(_canCastShadow, scene, viewTaskBits, false);
|
||||
}
|
||||
|
||||
if (_needsCollisionGeometryUpdate) {
|
||||
setCollisionMeshKey(entity->getCollisionMeshKey());
|
||||
_needsCollisionGeometryUpdate = false;
|
||||
|
|
|
@ -330,6 +330,7 @@ void ZoneEntityRenderer::updateKeySunFromEntity(const TypedEntityPointer& entity
|
|||
sunLight->setColor(ColorUtils::toVec3(_keyLightProperties.getColor()));
|
||||
sunLight->setIntensity(_keyLightProperties.getIntensity());
|
||||
sunLight->setDirection(entity->getTransform().getRotation() * _keyLightProperties.getDirection());
|
||||
sunLight->setCastShadows(_keyLightProperties.getCastShadows());
|
||||
}
|
||||
|
||||
void ZoneEntityRenderer::updateAmbientLightFromEntity(const TypedEntityPointer& entity) {
|
||||
|
|
|
@ -91,6 +91,7 @@ EntityPropertyFlags EntityItem::getEntityProperties(EncodeBitstreamParams& param
|
|||
requestedProperties += PROP_REGISTRATION_POINT;
|
||||
requestedProperties += PROP_ANGULAR_DAMPING;
|
||||
requestedProperties += PROP_VISIBLE;
|
||||
requestedProperties += PROP_CAN_CAST_SHADOW;
|
||||
requestedProperties += PROP_COLLISIONLESS;
|
||||
requestedProperties += PROP_COLLISION_MASK;
|
||||
requestedProperties += PROP_DYNAMIC;
|
||||
|
@ -249,6 +250,7 @@ OctreeElement::AppendState EntityItem::appendEntityData(OctreePacketData* packet
|
|||
APPEND_ENTITY_PROPERTY(PROP_REGISTRATION_POINT, getRegistrationPoint());
|
||||
APPEND_ENTITY_PROPERTY(PROP_ANGULAR_DAMPING, getAngularDamping());
|
||||
APPEND_ENTITY_PROPERTY(PROP_VISIBLE, getVisible());
|
||||
APPEND_ENTITY_PROPERTY(PROP_CAN_CAST_SHADOW, getCanCastShadow());
|
||||
APPEND_ENTITY_PROPERTY(PROP_COLLISIONLESS, getCollisionless());
|
||||
APPEND_ENTITY_PROPERTY(PROP_COLLISION_MASK, getCollisionMask());
|
||||
APPEND_ENTITY_PROPERTY(PROP_DYNAMIC, getDynamic());
|
||||
|
@ -799,6 +801,7 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef
|
|||
|
||||
READ_ENTITY_PROPERTY(PROP_ANGULAR_DAMPING, float, setAngularDamping);
|
||||
READ_ENTITY_PROPERTY(PROP_VISIBLE, bool, setVisible);
|
||||
READ_ENTITY_PROPERTY(PROP_CAN_CAST_SHADOW, bool, setCanCastShadow);
|
||||
READ_ENTITY_PROPERTY(PROP_COLLISIONLESS, bool, setCollisionless);
|
||||
READ_ENTITY_PROPERTY(PROP_COLLISION_MASK, uint8_t, setCollisionMask);
|
||||
READ_ENTITY_PROPERTY(PROP_DYNAMIC, bool, setDynamic);
|
||||
|
@ -1234,6 +1237,7 @@ EntityItemProperties EntityItem::getProperties(EntityPropertyFlags desiredProper
|
|||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(angularDamping, getAngularDamping);
|
||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(localRenderAlpha, getLocalRenderAlpha);
|
||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(visible, getVisible);
|
||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(canCastShadow, getCanCastShadow);
|
||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(collisionless, getCollisionless);
|
||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(collisionMask, getCollisionMask);
|
||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(dynamic, getDynamic);
|
||||
|
@ -1346,6 +1350,7 @@ bool EntityItem::setProperties(const EntityItemProperties& properties) {
|
|||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(collisionSoundURL, setCollisionSoundURL);
|
||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(localRenderAlpha, setLocalRenderAlpha);
|
||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(visible, setVisible);
|
||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(canCastShadow, setCanCastShadow);
|
||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(userData, setUserData);
|
||||
|
||||
// Certifiable Properties
|
||||
|
@ -2723,6 +2728,28 @@ void EntityItem::setVisible(bool value) {
|
|||
}
|
||||
}
|
||||
|
||||
bool EntityItem::getCanCastShadow() const {
|
||||
bool result;
|
||||
withReadLock([&] {
|
||||
result = _canCastShadow;
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
void EntityItem::setCanCastShadow(bool value) {
|
||||
bool changed = false;
|
||||
withWriteLock([&] {
|
||||
if (_canCastShadow != value) {
|
||||
changed = true;
|
||||
_canCastShadow = value;
|
||||
}
|
||||
});
|
||||
|
||||
if (changed) {
|
||||
emit requestRenderUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
bool EntityItem::isChildOfMyAvatar() const {
|
||||
QUuid ancestorID = findAncestorOfType(NestableType::Avatar);
|
||||
return !ancestorID.isNull() && (ancestorID == Physics::getSessionUUID() || ancestorID == AVATAR_SELF_ID);
|
||||
|
|
|
@ -274,6 +274,10 @@ public:
|
|||
|
||||
bool getVisible() const;
|
||||
void setVisible(bool value);
|
||||
|
||||
bool getCanCastShadow() const;
|
||||
void setCanCastShadow(bool value);
|
||||
|
||||
inline bool isVisible() const { return getVisible(); }
|
||||
inline bool isInvisible() const { return !getVisible(); }
|
||||
|
||||
|
@ -551,6 +555,7 @@ protected:
|
|||
glm::vec3 _registrationPoint { ENTITY_ITEM_DEFAULT_REGISTRATION_POINT };
|
||||
float _angularDamping { ENTITY_ITEM_DEFAULT_ANGULAR_DAMPING };
|
||||
bool _visible { ENTITY_ITEM_DEFAULT_VISIBLE };
|
||||
bool _canCastShadow{ ENTITY_ITEM_DEFAULT_CAN_CAST_SHADOW };
|
||||
bool _collisionless { ENTITY_ITEM_DEFAULT_COLLISIONLESS };
|
||||
uint8_t _collisionMask { ENTITY_COLLISION_MASK_DEFAULT };
|
||||
bool _dynamic { ENTITY_ITEM_DEFAULT_DYNAMIC };
|
||||
|
|
|
@ -316,6 +316,7 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const {
|
|||
CHECK_PROPERTY_CHANGE(PROP_MODEL_URL, modelURL);
|
||||
CHECK_PROPERTY_CHANGE(PROP_COMPOUND_SHAPE_URL, compoundShapeURL);
|
||||
CHECK_PROPERTY_CHANGE(PROP_VISIBLE, visible);
|
||||
CHECK_PROPERTY_CHANGE(PROP_CAN_CAST_SHADOW, canCastShadow);
|
||||
CHECK_PROPERTY_CHANGE(PROP_REGISTRATION_POINT, registrationPoint);
|
||||
CHECK_PROPERTY_CHANGE(PROP_ANGULAR_VELOCITY, angularVelocity);
|
||||
CHECK_PROPERTY_CHANGE(PROP_ANGULAR_DAMPING, angularDamping);
|
||||
|
@ -490,6 +491,7 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine, bool
|
|||
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_ANGULAR_VELOCITY, angularVelocity);
|
||||
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_ANGULAR_DAMPING, angularDamping);
|
||||
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_VISIBLE, visible);
|
||||
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_CAN_CAST_SHADOW, canCastShadow);
|
||||
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_COLLISIONLESS, collisionless);
|
||||
COPY_PROXY_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_COLLISIONLESS, collisionless, ignoreForCollisions, getCollisionless()); // legacy support
|
||||
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_COLLISION_MASK, collisionMask);
|
||||
|
@ -751,6 +753,7 @@ void EntityItemProperties::copyFromScriptValue(const QScriptValue& object, bool
|
|||
COPY_PROPERTY_FROM_QSCRIPTVALUE(angularVelocity, glmVec3, setAngularVelocity);
|
||||
COPY_PROPERTY_FROM_QSCRIPTVALUE(angularDamping, float, setAngularDamping);
|
||||
COPY_PROPERTY_FROM_QSCRIPTVALUE(visible, bool, setVisible);
|
||||
COPY_PROPERTY_FROM_QSCRIPTVALUE(canCastShadow, bool, setCanCastShadow);
|
||||
COPY_PROPERTY_FROM_QSCRIPTVALUE(color, xColor, setColor);
|
||||
COPY_PROPERTY_FROM_QSCRIPTVALUE(colorSpread, xColor, setColorSpread);
|
||||
COPY_PROPERTY_FROM_QSCRIPTVALUE(colorStart, xColor, setColorStart);
|
||||
|
@ -922,6 +925,7 @@ void EntityItemProperties::merge(const EntityItemProperties& other) {
|
|||
COPY_PROPERTY_IF_CHANGED(angularVelocity);
|
||||
COPY_PROPERTY_IF_CHANGED(angularDamping);
|
||||
COPY_PROPERTY_IF_CHANGED(visible);
|
||||
COPY_PROPERTY_IF_CHANGED(canCastShadow);
|
||||
COPY_PROPERTY_IF_CHANGED(color);
|
||||
COPY_PROPERTY_IF_CHANGED(colorSpread);
|
||||
COPY_PROPERTY_IF_CHANGED(colorStart);
|
||||
|
@ -1094,6 +1098,7 @@ void EntityItemProperties::entityPropertyFlagsFromScriptValue(const QScriptValue
|
|||
|
||||
std::call_once(initMap, [](){
|
||||
ADD_PROPERTY_TO_MAP(PROP_VISIBLE, Visible, visible, bool);
|
||||
ADD_PROPERTY_TO_MAP(PROP_CAN_CAST_SHADOW, CanCastShadow, canCastShadow, bool);
|
||||
ADD_PROPERTY_TO_MAP(PROP_POSITION, Position, position, glm::vec3);
|
||||
ADD_PROPERTY_TO_MAP(PROP_DIMENSIONS, Dimensions, dimensions, glm::vec3);
|
||||
ADD_PROPERTY_TO_MAP(PROP_ROTATION, Rotation, rotation, glm::quat);
|
||||
|
@ -1187,6 +1192,8 @@ void EntityItemProperties::entityPropertyFlagsFromScriptValue(const QScriptValue
|
|||
ADD_PROPERTY_TO_MAP(PROP_KEYLIGHT_COLOR, KeyLightColor, keyLightColor, xColor);
|
||||
ADD_PROPERTY_TO_MAP(PROP_KEYLIGHT_INTENSITY, KeyLightIntensity, keyLightIntensity, float);
|
||||
ADD_PROPERTY_TO_MAP(PROP_KEYLIGHT_DIRECTION, KeyLightDirection, keyLightDirection, glm::vec3);
|
||||
ADD_PROPERTY_TO_MAP(PROP_KEYLIGHT_CAST_SHADOW, KeyLightCastShadows, keyLightCastShadows, bool);
|
||||
|
||||
ADD_PROPERTY_TO_MAP(PROP_VOXEL_VOLUME_SIZE, VoxelVolumeSize, voxelVolumeSize, glm::vec3);
|
||||
ADD_PROPERTY_TO_MAP(PROP_VOXEL_DATA, VoxelData, voxelData, QByteArray);
|
||||
ADD_PROPERTY_TO_MAP(PROP_VOXEL_SURFACE_STYLE, VoxelSurfaceStyle, voxelSurfaceStyle, uint16_t);
|
||||
|
@ -1412,6 +1419,7 @@ OctreeElement::AppendState EntityItemProperties::encodeEntityEditPacket(PacketTy
|
|||
APPEND_ENTITY_PROPERTY(PROP_ANGULAR_VELOCITY, properties.getAngularVelocity());
|
||||
APPEND_ENTITY_PROPERTY(PROP_ANGULAR_DAMPING, properties.getAngularDamping());
|
||||
APPEND_ENTITY_PROPERTY(PROP_VISIBLE, properties.getVisible());
|
||||
APPEND_ENTITY_PROPERTY(PROP_CAN_CAST_SHADOW, properties.getCanCastShadow());
|
||||
APPEND_ENTITY_PROPERTY(PROP_COLLISIONLESS, properties.getCollisionless());
|
||||
APPEND_ENTITY_PROPERTY(PROP_COLLISION_MASK, properties.getCollisionMask());
|
||||
APPEND_ENTITY_PROPERTY(PROP_DYNAMIC, properties.getDynamic());
|
||||
|
@ -1784,6 +1792,7 @@ bool EntityItemProperties::decodeEntityEditPacket(const unsigned char* data, int
|
|||
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_ANGULAR_VELOCITY, glm::vec3, setAngularVelocity);
|
||||
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_ANGULAR_DAMPING, float, setAngularDamping);
|
||||
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_VISIBLE, bool, setVisible);
|
||||
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_CAN_CAST_SHADOW, bool, setCanCastShadow);
|
||||
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_COLLISIONLESS, bool, setCollisionless);
|
||||
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_COLLISION_MASK, uint8_t, setCollisionMask);
|
||||
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_DYNAMIC, bool, setDynamic);
|
||||
|
@ -2053,6 +2062,7 @@ void EntityItemProperties::markAllChanged() {
|
|||
_angularDampingChanged = true;
|
||||
_nameChanged = true;
|
||||
_visibleChanged = true;
|
||||
_canCastShadowChanged = true;
|
||||
_colorChanged = true;
|
||||
_alphaChanged = true;
|
||||
_modelURLChanged = true;
|
||||
|
@ -2250,6 +2260,9 @@ QList<QString> EntityItemProperties::listChangedProperties() {
|
|||
if (visibleChanged()) {
|
||||
out += "visible";
|
||||
}
|
||||
if (canCastShadowChanged()) {
|
||||
out += "canCastShadow";
|
||||
}
|
||||
if (rotationChanged()) {
|
||||
out += "rotation";
|
||||
}
|
||||
|
|
|
@ -117,6 +117,7 @@ public:
|
|||
// bool _fooChanged { false };
|
||||
|
||||
DEFINE_PROPERTY(PROP_VISIBLE, Visible, visible, bool, ENTITY_ITEM_DEFAULT_VISIBLE);
|
||||
DEFINE_PROPERTY(PROP_CAN_CAST_SHADOW, CanCastShadow, canCastShadow, bool, ENTITY_ITEM_DEFAULT_CAN_CAST_SHADOW);
|
||||
DEFINE_PROPERTY_REF_WITH_SETTER(PROP_POSITION, Position, position, glm::vec3, ENTITY_ITEM_ZERO_VEC3);
|
||||
DEFINE_PROPERTY_REF(PROP_DIMENSIONS, Dimensions, dimensions, glm::vec3, ENTITY_ITEM_DEFAULT_DIMENSIONS);
|
||||
DEFINE_PROPERTY_REF(PROP_ROTATION, Rotation, rotation, glm::quat, ENTITY_ITEM_DEFAULT_ROTATION);
|
||||
|
@ -426,6 +427,7 @@ inline QDebug operator<<(QDebug debug, const EntityItemProperties& properties) {
|
|||
DEBUG_PROPERTY_IF_CHANGED(debug, properties, Velocity, velocity, "in meters");
|
||||
DEBUG_PROPERTY_IF_CHANGED(debug, properties, Name, name, "");
|
||||
DEBUG_PROPERTY_IF_CHANGED(debug, properties, Visible, visible, "");
|
||||
DEBUG_PROPERTY_IF_CHANGED(debug, properties, CanCastShadow, canCastShadow, "");
|
||||
DEBUG_PROPERTY_IF_CHANGED(debug, properties, Rotation, rotation, "");
|
||||
DEBUG_PROPERTY_IF_CHANGED(debug, properties, Density, density, "");
|
||||
DEBUG_PROPERTY_IF_CHANGED(debug, properties, Gravity, gravity, "");
|
||||
|
|
|
@ -46,6 +46,7 @@ const quint32 ENTITY_ITEM_DEFAULT_STATIC_CERTIFICATE_VERSION = 0;
|
|||
const float ENTITY_ITEM_DEFAULT_ALPHA = 1.0f;
|
||||
const float ENTITY_ITEM_DEFAULT_LOCAL_RENDER_ALPHA = 1.0f;
|
||||
const bool ENTITY_ITEM_DEFAULT_VISIBLE = true;
|
||||
const bool ENTITY_ITEM_DEFAULT_CAN_CAST_SHADOW { true };
|
||||
|
||||
const QString ENTITY_ITEM_DEFAULT_SCRIPT = QString("");
|
||||
const quint64 ENTITY_ITEM_DEFAULT_SCRIPT_TIMESTAMP = 0;
|
||||
|
|
|
@ -20,6 +20,7 @@ enum EntityPropertyList {
|
|||
|
||||
// these properties are supported by the EntityItem base class
|
||||
PROP_VISIBLE,
|
||||
PROP_CAN_CAST_SHADOW,
|
||||
PROP_POSITION,
|
||||
PROP_DIMENSIONS,
|
||||
PROP_ROTATION,
|
||||
|
@ -205,6 +206,11 @@ enum EntityPropertyList {
|
|||
|
||||
PROP_HAZE_MODE,
|
||||
|
||||
PROP_KEYLIGHT_COLOR,
|
||||
PROP_KEYLIGHT_INTENSITY,
|
||||
PROP_KEYLIGHT_DIRECTION,
|
||||
PROP_KEYLIGHT_CAST_SHADOW,
|
||||
|
||||
PROP_HAZE_RANGE,
|
||||
PROP_HAZE_COLOR,
|
||||
PROP_HAZE_GLARE_COLOR,
|
||||
|
@ -254,10 +260,6 @@ enum EntityPropertyList {
|
|||
// Aliases/Piggyback properties for Zones. These properties intentionally reuse the enum values for
|
||||
// other properties which will never overlap with each other. We do this so that we don't have to expand
|
||||
// the size of the properties bitflags mask
|
||||
PROP_KEYLIGHT_COLOR = PROP_COLOR,
|
||||
PROP_KEYLIGHT_INTENSITY = PROP_INTENSITY,
|
||||
PROP_KEYLIGHT_DIRECTION = PROP_EXPONENT,
|
||||
|
||||
PROP_SKYBOX_COLOR = PROP_ANIMATION_URL,
|
||||
PROP_SKYBOX_URL = PROP_ANIMATION_FPS,
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@ const xColor KeyLightPropertyGroup::DEFAULT_KEYLIGHT_COLOR = { 255, 255, 255 };
|
|||
const float KeyLightPropertyGroup::DEFAULT_KEYLIGHT_INTENSITY = 1.0f;
|
||||
const float KeyLightPropertyGroup::DEFAULT_KEYLIGHT_AMBIENT_INTENSITY = 0.5f;
|
||||
const glm::vec3 KeyLightPropertyGroup::DEFAULT_KEYLIGHT_DIRECTION = { 0.0f, -1.0f, 0.0f };
|
||||
const bool KeyLightPropertyGroup::DEFAULT_KEYLIGHT_CAST_SHADOWS { false };
|
||||
|
||||
void KeyLightPropertyGroup::copyToScriptValue(const EntityPropertyFlags& desiredProperties, QScriptValue& properties,
|
||||
QScriptEngine* engine, bool skipDefaults, EntityItemProperties& defaultEntityProperties) const {
|
||||
|
@ -28,23 +29,27 @@ void KeyLightPropertyGroup::copyToScriptValue(const EntityPropertyFlags& desired
|
|||
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_KEYLIGHT_COLOR, KeyLight, keyLight, Color, color);
|
||||
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_KEYLIGHT_INTENSITY, KeyLight, keyLight, Intensity, intensity);
|
||||
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_KEYLIGHT_DIRECTION, KeyLight, keyLight, Direction, direction);
|
||||
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_KEYLIGHT_CAST_SHADOW, KeyLight, keyLight, CastShadows, castShadows);
|
||||
}
|
||||
|
||||
void KeyLightPropertyGroup::copyFromScriptValue(const QScriptValue& object, bool& _defaultSettings) {
|
||||
COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(keyLight, color, xColor, setColor);
|
||||
COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(keyLight, intensity, float, setIntensity);
|
||||
COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(keyLight, direction, glmVec3, setDirection);
|
||||
|
||||
COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(keyLight, castShadows, bool, setCastShadows);
|
||||
|
||||
// legacy property support
|
||||
COPY_PROPERTY_FROM_QSCRIPTVALUE_GETTER(keyLightColor, xColor, setColor, getColor);
|
||||
COPY_PROPERTY_FROM_QSCRIPTVALUE_GETTER(keyLightIntensity, float, setIntensity, getIntensity);
|
||||
COPY_PROPERTY_FROM_QSCRIPTVALUE_GETTER(keyLightDirection, glmVec3, setDirection, getDirection);
|
||||
COPY_PROPERTY_FROM_QSCRIPTVALUE_GETTER(keyLightCastShadows, bool, setCastShadows, getCastShadows);
|
||||
}
|
||||
|
||||
void KeyLightPropertyGroup::merge(const KeyLightPropertyGroup& other) {
|
||||
COPY_PROPERTY_IF_CHANGED(color);
|
||||
COPY_PROPERTY_IF_CHANGED(intensity);
|
||||
COPY_PROPERTY_IF_CHANGED(direction);
|
||||
COPY_PROPERTY_IF_CHANGED(castShadows);
|
||||
}
|
||||
|
||||
void KeyLightPropertyGroup::debugDump() const {
|
||||
|
@ -52,6 +57,7 @@ void KeyLightPropertyGroup::debugDump() const {
|
|||
qCDebug(entities) << " color:" << getColor(); // << "," << getColor()[1] << "," << getColor()[2];
|
||||
qCDebug(entities) << " intensity:" << getIntensity();
|
||||
qCDebug(entities) << " direction:" << getDirection();
|
||||
qCDebug(entities) << " castShadows:" << getCastShadows();
|
||||
}
|
||||
|
||||
void KeyLightPropertyGroup::listChangedProperties(QList<QString>& out) {
|
||||
|
@ -64,6 +70,9 @@ void KeyLightPropertyGroup::listChangedProperties(QList<QString>& out) {
|
|||
if (directionChanged()) {
|
||||
out << "keyLight-direction";
|
||||
}
|
||||
if (castShadowsChanged()) {
|
||||
out << "keyLight-castShadows";
|
||||
}
|
||||
}
|
||||
|
||||
bool KeyLightPropertyGroup::appendToEditPacket(OctreePacketData* packetData,
|
||||
|
@ -71,19 +80,21 @@ bool KeyLightPropertyGroup::appendToEditPacket(OctreePacketData* packetData,
|
|||
EntityPropertyFlags& propertyFlags,
|
||||
EntityPropertyFlags& propertiesDidntFit,
|
||||
int& propertyCount,
|
||||
OctreeElement::AppendState& appendState) const {
|
||||
OctreeElement::AppendState& appendState) const
|
||||
{
|
||||
|
||||
bool successPropertyFits = true;
|
||||
|
||||
APPEND_ENTITY_PROPERTY(PROP_KEYLIGHT_COLOR, getColor());
|
||||
APPEND_ENTITY_PROPERTY(PROP_KEYLIGHT_INTENSITY, getIntensity());
|
||||
APPEND_ENTITY_PROPERTY(PROP_KEYLIGHT_DIRECTION, getDirection());
|
||||
|
||||
APPEND_ENTITY_PROPERTY(PROP_KEYLIGHT_CAST_SHADOW, getCastShadows());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool KeyLightPropertyGroup::decodeFromEditPacket(EntityPropertyFlags& propertyFlags, const unsigned char*& dataAt,
|
||||
int& processedBytes) {
|
||||
int& processedBytes) {
|
||||
|
||||
int bytesRead = 0;
|
||||
bool overwriteLocalData = true;
|
||||
|
@ -92,11 +103,13 @@ bool KeyLightPropertyGroup::decodeFromEditPacket(EntityPropertyFlags& propertyFl
|
|||
READ_ENTITY_PROPERTY(PROP_KEYLIGHT_COLOR, xColor, setColor);
|
||||
READ_ENTITY_PROPERTY(PROP_KEYLIGHT_INTENSITY, float, setIntensity);
|
||||
READ_ENTITY_PROPERTY(PROP_KEYLIGHT_DIRECTION, glm::vec3, setDirection);
|
||||
|
||||
READ_ENTITY_PROPERTY(PROP_KEYLIGHT_CAST_SHADOW, bool, setCastShadows);
|
||||
|
||||
DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_KEYLIGHT_COLOR, Color);
|
||||
DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_KEYLIGHT_INTENSITY, Intensity);
|
||||
DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_KEYLIGHT_DIRECTION, Direction);
|
||||
|
||||
DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_KEYLIGHT_CAST_SHADOW, CastShadows);
|
||||
|
||||
processedBytes += bytesRead;
|
||||
|
||||
Q_UNUSED(somethingChanged);
|
||||
|
@ -108,6 +121,7 @@ void KeyLightPropertyGroup::markAllChanged() {
|
|||
_colorChanged = true;
|
||||
_intensityChanged = true;
|
||||
_directionChanged = true;
|
||||
_castShadowsChanged = true;
|
||||
}
|
||||
|
||||
EntityPropertyFlags KeyLightPropertyGroup::getChangedProperties() const {
|
||||
|
@ -116,7 +130,8 @@ EntityPropertyFlags KeyLightPropertyGroup::getChangedProperties() const {
|
|||
CHECK_PROPERTY_CHANGE(PROP_KEYLIGHT_COLOR, color);
|
||||
CHECK_PROPERTY_CHANGE(PROP_KEYLIGHT_INTENSITY, intensity);
|
||||
CHECK_PROPERTY_CHANGE(PROP_KEYLIGHT_DIRECTION, direction);
|
||||
|
||||
CHECK_PROPERTY_CHANGE(PROP_KEYLIGHT_CAST_SHADOW, castShadows);
|
||||
|
||||
return changedProperties;
|
||||
}
|
||||
|
||||
|
@ -124,6 +139,7 @@ void KeyLightPropertyGroup::getProperties(EntityItemProperties& properties) cons
|
|||
COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(KeyLight, Color, getColor);
|
||||
COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(KeyLight, Intensity, getIntensity);
|
||||
COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(KeyLight, Direction, getDirection);
|
||||
COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(KeyLight, CastShadows, getCastShadows);
|
||||
}
|
||||
|
||||
bool KeyLightPropertyGroup::setProperties(const EntityItemProperties& properties) {
|
||||
|
@ -132,6 +148,7 @@ bool KeyLightPropertyGroup::setProperties(const EntityItemProperties& properties
|
|||
SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(KeyLight, Color, color, setColor);
|
||||
SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(KeyLight, Intensity, intensity, setIntensity);
|
||||
SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(KeyLight, Direction, direction, setDirection);
|
||||
SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(KeyLight, CastShadows, castShadows, setCastShadows);
|
||||
|
||||
return somethingChanged;
|
||||
}
|
||||
|
@ -142,6 +159,7 @@ EntityPropertyFlags KeyLightPropertyGroup::getEntityProperties(EncodeBitstreamPa
|
|||
requestedProperties += PROP_KEYLIGHT_COLOR;
|
||||
requestedProperties += PROP_KEYLIGHT_INTENSITY;
|
||||
requestedProperties += PROP_KEYLIGHT_DIRECTION;
|
||||
requestedProperties += PROP_KEYLIGHT_CAST_SHADOW;
|
||||
|
||||
return requestedProperties;
|
||||
}
|
||||
|
@ -159,6 +177,7 @@ void KeyLightPropertyGroup::appendSubclassData(OctreePacketData* packetData, Enc
|
|||
APPEND_ENTITY_PROPERTY(PROP_KEYLIGHT_COLOR, getColor());
|
||||
APPEND_ENTITY_PROPERTY(PROP_KEYLIGHT_INTENSITY, getIntensity());
|
||||
APPEND_ENTITY_PROPERTY(PROP_KEYLIGHT_DIRECTION, getDirection());
|
||||
APPEND_ENTITY_PROPERTY(PROP_KEYLIGHT_CAST_SHADOW, getCastShadows());
|
||||
}
|
||||
|
||||
int KeyLightPropertyGroup::readEntitySubclassDataFromBuffer(const unsigned char* data, int bytesLeftToRead,
|
||||
|
@ -172,6 +191,7 @@ int KeyLightPropertyGroup::readEntitySubclassDataFromBuffer(const unsigned char*
|
|||
READ_ENTITY_PROPERTY(PROP_KEYLIGHT_COLOR, xColor, setColor);
|
||||
READ_ENTITY_PROPERTY(PROP_KEYLIGHT_INTENSITY, float, setIntensity);
|
||||
READ_ENTITY_PROPERTY(PROP_KEYLIGHT_DIRECTION, glm::vec3, setDirection);
|
||||
READ_ENTITY_PROPERTY(PROP_KEYLIGHT_CAST_SHADOW, bool, setCastShadows);
|
||||
|
||||
return bytesRead;
|
||||
}
|
||||
|
|
|
@ -78,10 +78,12 @@ public:
|
|||
static const float DEFAULT_KEYLIGHT_INTENSITY;
|
||||
static const float DEFAULT_KEYLIGHT_AMBIENT_INTENSITY;
|
||||
static const glm::vec3 DEFAULT_KEYLIGHT_DIRECTION;
|
||||
static const bool DEFAULT_KEYLIGHT_CAST_SHADOWS;
|
||||
|
||||
DEFINE_PROPERTY_REF(PROP_KEYLIGHT_COLOR, Color, color, xColor, DEFAULT_KEYLIGHT_COLOR);
|
||||
DEFINE_PROPERTY(PROP_KEYLIGHT_INTENSITY, Intensity, intensity, float, DEFAULT_KEYLIGHT_INTENSITY);
|
||||
DEFINE_PROPERTY_REF(PROP_KEYLIGHT_DIRECTION, Direction, direction, glm::vec3, DEFAULT_KEYLIGHT_DIRECTION);
|
||||
DEFINE_PROPERTY(PROP_KEYLIGHT_CAST_SHADOW, CastShadows, castShadows, bool, DEFAULT_KEYLIGHT_CAST_SHADOWS);
|
||||
};
|
||||
|
||||
#endif // hifi_KeyLightPropertyGroup_h
|
||||
|
|
|
@ -53,6 +53,7 @@ void ModelEntityItem::setTextures(const QString& textures) {
|
|||
|
||||
EntityItemProperties ModelEntityItem::getProperties(EntityPropertyFlags desiredProperties) const {
|
||||
EntityItemProperties properties = EntityItem::getProperties(desiredProperties); // get the properties from our base class
|
||||
|
||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(color, getXColor);
|
||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(modelURL, getModelURL);
|
||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(compoundShapeURL, getCompoundShapeURL);
|
||||
|
@ -64,6 +65,7 @@ EntityItemProperties ModelEntityItem::getProperties(EntityPropertyFlags desiredP
|
|||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(jointTranslations, getJointTranslations);
|
||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(relayParentJoints, getRelayParentJoints);
|
||||
_animationProperties.getProperties(properties);
|
||||
|
||||
return properties;
|
||||
}
|
||||
|
||||
|
@ -191,8 +193,6 @@ void ModelEntityItem::appendSubclassData(OctreePacketData* packetData, EncodeBit
|
|||
APPEND_ENTITY_PROPERTY(PROP_JOINT_TRANSLATIONS, getJointTranslations());
|
||||
}
|
||||
|
||||
|
||||
|
||||
// added update function back for property fix
|
||||
void ModelEntityItem::update(const quint64& now) {
|
||||
|
||||
|
@ -571,15 +571,16 @@ QVector<bool> ModelEntityItem::getJointTranslationsSet() const {
|
|||
return result;
|
||||
}
|
||||
|
||||
|
||||
xColor ModelEntityItem::getXColor() const {
|
||||
xColor color = { _color[RED_INDEX], _color[GREEN_INDEX], _color[BLUE_INDEX] }; return color;
|
||||
}
|
||||
|
||||
bool ModelEntityItem::hasModel() const {
|
||||
return resultWithReadLock<bool>([&] {
|
||||
return !_modelURL.isEmpty();
|
||||
});
|
||||
}
|
||||
|
||||
bool ModelEntityItem::hasCompoundShapeURL() const {
|
||||
return !_compoundShapeURL.get().isEmpty();
|
||||
}
|
||||
|
@ -659,7 +660,6 @@ bool ModelEntityItem::getAnimationLoop() const {
|
|||
});
|
||||
}
|
||||
|
||||
|
||||
void ModelEntityItem::setAnimationHold(bool hold) {
|
||||
withWriteLock([&] {
|
||||
_animationProperties.setHold(hold);
|
||||
|
|
|
@ -92,6 +92,7 @@ EntityItemProperties ShapeEntityItem::getProperties(EntityPropertyFlags desiredP
|
|||
EntityItemProperties properties = EntityItem::getProperties(desiredProperties); // get the properties from our base class
|
||||
properties.setColor(getXColor());
|
||||
properties.setShape(entity::stringFromShape(getShape()));
|
||||
|
||||
return properties;
|
||||
}
|
||||
|
||||
|
@ -166,6 +167,7 @@ EntityPropertyFlags ShapeEntityItem::getEntityProperties(EncodeBitstreamParams&
|
|||
requestedProperties += PROP_SHAPE;
|
||||
requestedProperties += PROP_COLOR;
|
||||
requestedProperties += PROP_ALPHA;
|
||||
|
||||
return requestedProperties;
|
||||
}
|
||||
|
||||
|
@ -368,4 +370,3 @@ void ShapeEntityItem::computeShapeInfo(ShapeInfo& info) {
|
|||
ShapeType ShapeEntityItem::getShapeType() const {
|
||||
return _collisionShapeType;
|
||||
}
|
||||
|
||||
|
|
|
@ -114,6 +114,8 @@ protected:
|
|||
//! ellipsoids.
|
||||
ShapeType _collisionShapeType{ ShapeType::SHAPE_TYPE_ELLIPSOID };
|
||||
|
||||
bool _canCastShadow { ENTITY_ITEM_DEFAULT_CAN_CAST_SHADOW };
|
||||
|
||||
std::shared_ptr<graphics::Material> _material;
|
||||
};
|
||||
|
||||
|
|
|
@ -65,6 +65,14 @@ const Vec3& Light::getDirection() const {
|
|||
return _lightSchemaBuffer->volume.direction;
|
||||
}
|
||||
|
||||
void Light::setCastShadows(const bool castShadows) {
|
||||
_castShadows = castShadows;
|
||||
}
|
||||
|
||||
bool Light::getCastShadows() const {
|
||||
return _castShadows;
|
||||
}
|
||||
|
||||
void Light::setColor(const Color& color) {
|
||||
_lightSchemaBuffer.edit().irradiance.color = color;
|
||||
updateLightRadius();
|
||||
|
@ -132,7 +140,6 @@ void Light::setSpotExponent(float exponent) {
|
|||
_lightSchemaBuffer.edit().irradiance.falloffSpot = exponent;
|
||||
}
|
||||
|
||||
|
||||
void Light::setAmbientIntensity(float intensity) {
|
||||
_ambientSchemaBuffer.edit().intensity = intensity;
|
||||
}
|
||||
|
|
|
@ -103,6 +103,9 @@ public:
|
|||
void setDirection(const Vec3& direction);
|
||||
const Vec3& getDirection() const;
|
||||
|
||||
void setCastShadows(const bool castShadows);
|
||||
bool getCastShadows() const;
|
||||
|
||||
void setOrientation(const Quat& orientation);
|
||||
const glm::quat& getOrientation() const { return _transform.getRotation(); }
|
||||
|
||||
|
@ -191,6 +194,8 @@ protected:
|
|||
|
||||
void updateLightRadius();
|
||||
|
||||
bool _castShadows{ false };
|
||||
|
||||
};
|
||||
typedef std::shared_ptr< Light > LightPointer;
|
||||
|
||||
|
|
|
@ -30,7 +30,7 @@ PacketVersion versionForPacketType(PacketType packetType) {
|
|||
case PacketType::EntityEdit:
|
||||
case PacketType::EntityData:
|
||||
case PacketType::EntityPhysics:
|
||||
return static_cast<PacketVersion>(EntityVersion::MaterialEntities);
|
||||
return static_cast<PacketVersion>(EntityVersion::ShadowControl);
|
||||
case PacketType::EntityQuery:
|
||||
return static_cast<PacketVersion>(EntityQueryPacketVersion::RemovedJurisdictions);
|
||||
case PacketType::AvatarIdentity:
|
||||
|
|
|
@ -218,7 +218,8 @@ enum class EntityVersion : PacketVersion {
|
|||
ZoneLightInheritModes = 82,
|
||||
ZoneStageRemoved,
|
||||
SoftEntities,
|
||||
MaterialEntities
|
||||
MaterialEntities,
|
||||
ShadowControl
|
||||
};
|
||||
|
||||
enum class EntityScriptCallMethodVersion : PacketVersion {
|
||||
|
|
|
@ -204,6 +204,7 @@ void CauterizedModel::updateRenderItems() {
|
|||
|
||||
bool isWireframe = self->isWireframe();
|
||||
bool isVisible = self->isVisible();
|
||||
bool canCastShadow = self->canCastShadow();
|
||||
bool isLayeredInFront = self->isLayeredInFront();
|
||||
bool isLayeredInHUD = self->isLayeredInHUD();
|
||||
bool enableCauterization = self->getEnableCauterization();
|
||||
|
@ -219,7 +220,7 @@ void CauterizedModel::updateRenderItems() {
|
|||
bool invalidatePayloadShapeKey = self->shouldInvalidatePayloadShapeKey(meshIndex);
|
||||
|
||||
transaction.updateItem<CauterizedMeshPartPayload>(itemID, [modelTransform, clusterTransforms, clusterTransformsCauterized, invalidatePayloadShapeKey,
|
||||
isWireframe, isVisible, isLayeredInFront, isLayeredInHUD, enableCauterization](CauterizedMeshPartPayload& data) {
|
||||
isWireframe, isVisible, isLayeredInFront, isLayeredInHUD, canCastShadow, enableCauterization](CauterizedMeshPartPayload& data) {
|
||||
data.updateClusterBuffer(clusterTransforms, clusterTransformsCauterized);
|
||||
|
||||
Transform renderTransform = modelTransform;
|
||||
|
@ -249,7 +250,7 @@ void CauterizedModel::updateRenderItems() {
|
|||
data.updateTransformForCauterizedMesh(renderTransform);
|
||||
|
||||
data.setEnableCauterization(enableCauterization);
|
||||
data.updateKey(isVisible, isLayeredInFront || isLayeredInHUD, render::ItemKey::TAG_BITS_ALL);
|
||||
data.updateKey(isVisible, isLayeredInFront || isLayeredInHUD, canCastShadow, render::ItemKey::TAG_BITS_ALL);
|
||||
data.setLayer(isLayeredInFront, isLayeredInHUD);
|
||||
data.setShapeKey(invalidatePayloadShapeKey, isWireframe);
|
||||
});
|
||||
|
|
|
@ -492,7 +492,7 @@ void RenderDeferredSetup::run(const render::RenderContextPointer& renderContext,
|
|||
batch.setResourceTexture(DEFERRED_BUFFER_DEPTH_UNIT, deferredFramebuffer->getPrimaryDepthTexture());
|
||||
|
||||
// FIXME: Different render modes should have different tasks
|
||||
if (args->_renderMode == RenderArgs::DEFAULT_RENDER_MODE && deferredLightingEffect->isAmbientOcclusionEnabled()) {
|
||||
if (args->_renderMode == RenderArgs::DEFAULT_RENDER_MODE && deferredLightingEffect->isAmbientOcclusionEnabled() && ambientOcclusionFramebuffer) {
|
||||
batch.setResourceTexture(DEFERRED_BUFFER_OBSCURANCE_UNIT, ambientOcclusionFramebuffer->getOcclusionTexture());
|
||||
} else {
|
||||
// need to assign the white texture if ao is off
|
||||
|
@ -537,15 +537,25 @@ void RenderDeferredSetup::run(const render::RenderContextPointer& renderContext,
|
|||
|
||||
auto keyLight = lightAndShadow.first;
|
||||
|
||||
graphics::LightPointer keyAmbientLight;
|
||||
graphics::LightPointer ambientLight;
|
||||
if (lightStage && lightStage->_currentFrame._ambientLights.size()) {
|
||||
keyAmbientLight = lightStage->getLight(lightStage->_currentFrame._ambientLights.front());
|
||||
ambientLight = lightStage->getLight(lightStage->_currentFrame._ambientLights.front());
|
||||
}
|
||||
bool hasAmbientMap = (keyAmbientLight != nullptr);
|
||||
bool hasAmbientMap = (ambientLight != nullptr);
|
||||
|
||||
// Setup the global directional pass pipeline
|
||||
{
|
||||
if (deferredLightingEffect->_shadowMapEnabled) {
|
||||
// Check if keylight casts shadows
|
||||
bool keyLightCastShadows { false };
|
||||
|
||||
if (lightStage && lightStage->_currentFrame._sunLights.size()) {
|
||||
graphics::LightPointer keyLight = lightStage->getLight(lightStage->_currentFrame._sunLights.front());
|
||||
if (keyLight) {
|
||||
keyLightCastShadows = keyLight->getCastShadows();
|
||||
}
|
||||
}
|
||||
|
||||
if (deferredLightingEffect->_shadowMapEnabled && keyLightCastShadows) {
|
||||
|
||||
// If the keylight has an ambient Map then use the Skybox version of the pass
|
||||
// otherwise use the ambient sphere version
|
||||
|
|
|
@ -61,7 +61,7 @@ public:
|
|||
private:
|
||||
DeferredLightingEffect() = default;
|
||||
|
||||
bool _shadowMapEnabled{ false };
|
||||
bool _shadowMapEnabled{ true }; // note that this value is overwritten in the ::configure method
|
||||
bool _ambientOcclusionEnabled{ false };
|
||||
|
||||
graphics::MeshPointer _pointLightMesh;
|
||||
|
|
|
@ -77,7 +77,7 @@ void MeshPartPayload::removeMaterial(graphics::MaterialPointer material) {
|
|||
_drawMaterials.remove(material);
|
||||
}
|
||||
|
||||
void MeshPartPayload::updateKey(bool isVisible, bool isLayered, uint8_t tagBits, bool isGroupCulled) {
|
||||
void MeshPartPayload::updateKey(bool isVisible, bool isLayered, bool canCastShadow, uint8_t tagBits, bool isGroupCulled) {
|
||||
ItemKey::Builder builder;
|
||||
builder.withTypeShape();
|
||||
|
||||
|
@ -91,6 +91,10 @@ void MeshPartPayload::updateKey(bool isVisible, bool isLayered, uint8_t tagBits,
|
|||
builder.withLayered();
|
||||
}
|
||||
|
||||
if (canCastShadow) {
|
||||
builder.withShadowCaster();
|
||||
}
|
||||
|
||||
if (isGroupCulled) {
|
||||
builder.withSubMetaCulled();
|
||||
}
|
||||
|
@ -290,7 +294,8 @@ void ModelMeshPartPayload::updateTransformForSkinnedMesh(const Transform& render
|
|||
_worldBound.transform(boundTransform);
|
||||
}
|
||||
|
||||
void ModelMeshPartPayload::updateKey(bool isVisible, bool isLayered, uint8_t tagBits, bool isGroupCulled) {
|
||||
// Note that this method is called for models but not for shapes
|
||||
void ModelMeshPartPayload::updateKey(bool isVisible, bool isLayered, bool canCastShadow, uint8_t tagBits, bool isGroupCulled) {
|
||||
ItemKey::Builder builder;
|
||||
builder.withTypeShape();
|
||||
|
||||
|
@ -304,6 +309,10 @@ void ModelMeshPartPayload::updateKey(bool isVisible, bool isLayered, uint8_t tag
|
|||
builder.withLayered();
|
||||
}
|
||||
|
||||
if (canCastShadow) {
|
||||
builder.withShadowCaster();
|
||||
}
|
||||
|
||||
if (isGroupCulled) {
|
||||
builder.withSubMetaCulled();
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@ public:
|
|||
typedef render::Payload<MeshPartPayload> Payload;
|
||||
typedef Payload::DataPointer Pointer;
|
||||
|
||||
virtual void updateKey(bool isVisible, bool isLayered, uint8_t tagBits, bool isGroupCulled = false);
|
||||
virtual void updateKey(bool isVisible, bool isLayered, bool canCastShadow, uint8_t tagBits, bool isGroupCulled = false);
|
||||
|
||||
virtual void updateMeshPart(const std::shared_ptr<const graphics::Mesh>& drawMesh, int partIndex);
|
||||
|
||||
|
@ -98,7 +98,7 @@ public:
|
|||
using TransformType = glm::mat4;
|
||||
#endif
|
||||
|
||||
void updateKey(bool isVisible, bool isLayered, uint8_t tagBits, bool isGroupCulled = false) override;
|
||||
void updateKey(bool isVisible, bool isLayered, bool canCastShadow, uint8_t tagBits, bool isGroupCulled = false) override;
|
||||
void updateClusterBuffer(const std::vector<TransformType>& clusterTransforms);
|
||||
void updateTransformForSkinnedMesh(const Transform& renderTransform, const Transform& boundTransform);
|
||||
|
||||
|
|
|
@ -102,6 +102,7 @@ Model::Model(QObject* parent, SpatiallyNestable* spatiallyNestableOverride) :
|
|||
_snappedToRegistrationPoint(false),
|
||||
_url(HTTP_INVALID_COM),
|
||||
_isVisible(true),
|
||||
_canCastShadow(false),
|
||||
_blendNumber(0),
|
||||
_appliedBlendNumber(0),
|
||||
_isWireframe(false)
|
||||
|
@ -268,6 +269,7 @@ void Model::updateRenderItems() {
|
|||
|
||||
bool isWireframe = self->isWireframe();
|
||||
bool isVisible = self->isVisible();
|
||||
bool canCastShadow = self->canCastShadow();
|
||||
uint8_t viewTagBits = self->getViewTagBits();
|
||||
bool isLayeredInFront = self->isLayeredInFront();
|
||||
bool isLayeredInHUD = self->isLayeredInHUD();
|
||||
|
@ -284,7 +286,7 @@ void Model::updateRenderItems() {
|
|||
|
||||
transaction.updateItem<ModelMeshPartPayload>(itemID, [modelTransform, clusterTransforms,
|
||||
invalidatePayloadShapeKey, isWireframe, isVisible,
|
||||
viewTagBits, isLayeredInFront,
|
||||
canCastShadow, viewTagBits, isLayeredInFront,
|
||||
isLayeredInHUD, isGroupCulled](ModelMeshPartPayload& data) {
|
||||
data.updateClusterBuffer(clusterTransforms);
|
||||
|
||||
|
@ -301,7 +303,7 @@ void Model::updateRenderItems() {
|
|||
}
|
||||
data.updateTransformForSkinnedMesh(renderTransform, modelTransform);
|
||||
|
||||
data.updateKey(isVisible, isLayeredInFront || isLayeredInHUD, viewTagBits, isGroupCulled);
|
||||
data.updateKey(isVisible, isLayeredInFront || isLayeredInHUD, canCastShadow, viewTagBits, isGroupCulled);
|
||||
data.setLayer(isLayeredInFront, isLayeredInHUD);
|
||||
data.setShapeKey(invalidatePayloadShapeKey, isWireframe);
|
||||
});
|
||||
|
@ -693,46 +695,66 @@ void Model::setVisibleInScene(bool isVisible, const render::ScenePointer& scene,
|
|||
|
||||
bool isLayeredInFront = _isLayeredInFront;
|
||||
bool isLayeredInHUD = _isLayeredInHUD;
|
||||
|
||||
bool canCastShadow = _canCastShadow;
|
||||
render::Transaction transaction;
|
||||
foreach (auto item, _modelMeshRenderItemsMap.keys()) {
|
||||
transaction.updateItem<ModelMeshPartPayload>(item, [isVisible, viewTagBits, isLayeredInFront,
|
||||
transaction.updateItem<ModelMeshPartPayload>(item, [isVisible, viewTagBits, isLayeredInFront, canCastShadow,
|
||||
isLayeredInHUD, isGroupCulled](ModelMeshPartPayload& data) {
|
||||
data.updateKey(isVisible, isLayeredInFront || isLayeredInHUD, viewTagBits, isGroupCulled);
|
||||
data.updateKey(isVisible, isLayeredInFront || isLayeredInHUD, canCastShadow, viewTagBits, isGroupCulled);
|
||||
});
|
||||
}
|
||||
foreach(auto item, _collisionRenderItemsMap.keys()) {
|
||||
transaction.updateItem<ModelMeshPartPayload>(item, [isVisible, viewTagBits, isLayeredInFront,
|
||||
transaction.updateItem<ModelMeshPartPayload>(item, [isVisible, viewTagBits, isLayeredInFront, canCastShadow,
|
||||
isLayeredInHUD, isGroupCulled](ModelMeshPartPayload& data) {
|
||||
data.updateKey(isVisible, isLayeredInFront || isLayeredInHUD, viewTagBits, isGroupCulled);
|
||||
data.updateKey(isVisible, isLayeredInFront || isLayeredInHUD, canCastShadow, viewTagBits, isGroupCulled);
|
||||
});
|
||||
}
|
||||
scene->enqueueTransaction(transaction);
|
||||
}
|
||||
}
|
||||
|
||||
void Model::setCanCastShadow(bool canCastShadow, const render::ScenePointer& scene, uint8_t viewTagBits, bool isGroupCulled) {
|
||||
if (_canCastShadow != canCastShadow) {
|
||||
_canCastShadow = canCastShadow;
|
||||
|
||||
bool isVisible = _isVisible;
|
||||
bool isLayeredInFront = _isLayeredInFront;
|
||||
bool isLayeredInHUD = _isLayeredInHUD;
|
||||
|
||||
render::Transaction transaction;
|
||||
foreach (auto item, _modelMeshRenderItemsMap.keys()) {
|
||||
transaction.updateItem<ModelMeshPartPayload>(item,
|
||||
[isVisible, viewTagBits, canCastShadow, isLayeredInFront, isLayeredInHUD, isGroupCulled](ModelMeshPartPayload& data) {
|
||||
data.updateKey(isVisible, viewTagBits, canCastShadow, isLayeredInFront || isLayeredInHUD, isGroupCulled);
|
||||
});
|
||||
}
|
||||
|
||||
scene->enqueueTransaction(transaction);
|
||||
}
|
||||
}
|
||||
|
||||
void Model::setLayeredInFront(bool isLayeredInFront, const render::ScenePointer& scene) {
|
||||
if (_isLayeredInFront != isLayeredInFront) {
|
||||
_isLayeredInFront = isLayeredInFront;
|
||||
|
||||
bool isVisible = _isVisible;
|
||||
bool canCastShadow = _canCastShadow;
|
||||
uint8_t viewTagBits = _viewTagBits;
|
||||
bool isLayeredInHUD = _isLayeredInHUD;
|
||||
bool isGroupCulled = _isGroupCulled;
|
||||
|
||||
render::Transaction transaction;
|
||||
foreach(auto item, _modelMeshRenderItemsMap.keys()) {
|
||||
transaction.updateItem<ModelMeshPartPayload>(item, [isVisible, viewTagBits, isLayeredInFront,
|
||||
transaction.updateItem<ModelMeshPartPayload>(item, [isVisible, viewTagBits, isLayeredInFront, canCastShadow,
|
||||
isLayeredInHUD, isGroupCulled](ModelMeshPartPayload& data) {
|
||||
data.updateKey(isVisible, isLayeredInFront || isLayeredInHUD, viewTagBits, isGroupCulled);
|
||||
data.updateKey(isVisible, isLayeredInFront || isLayeredInHUD, canCastShadow, viewTagBits, isGroupCulled);
|
||||
data.setLayer(isLayeredInFront, isLayeredInHUD);
|
||||
});
|
||||
}
|
||||
foreach(auto item, _collisionRenderItemsMap.keys()) {
|
||||
transaction.updateItem<ModelMeshPartPayload>(item, [isVisible, viewTagBits, isLayeredInFront,
|
||||
transaction.updateItem<ModelMeshPartPayload>(item, [isVisible, viewTagBits, isLayeredInFront, canCastShadow,
|
||||
isLayeredInHUD, isGroupCulled](ModelMeshPartPayload& data) {
|
||||
data.updateKey(isVisible, isLayeredInFront || isLayeredInHUD, viewTagBits, isGroupCulled);
|
||||
data.updateKey(isVisible, isLayeredInFront || isLayeredInHUD, canCastShadow, viewTagBits, isGroupCulled);
|
||||
data.setLayer(isLayeredInFront, isLayeredInHUD);
|
||||
});
|
||||
}
|
||||
|
@ -745,22 +767,23 @@ void Model::setLayeredInHUD(bool isLayeredInHUD, const render::ScenePointer& sce
|
|||
_isLayeredInHUD = isLayeredInHUD;
|
||||
|
||||
bool isVisible = _isVisible;
|
||||
bool canCastShadow = _canCastShadow;
|
||||
uint8_t viewTagBits = _viewTagBits;
|
||||
bool isLayeredInFront = _isLayeredInFront;
|
||||
bool isGroupCulled = _isGroupCulled;
|
||||
|
||||
render::Transaction transaction;
|
||||
foreach(auto item, _modelMeshRenderItemsMap.keys()) {
|
||||
transaction.updateItem<ModelMeshPartPayload>(item, [isVisible, viewTagBits, isLayeredInFront,
|
||||
transaction.updateItem<ModelMeshPartPayload>(item, [isVisible, viewTagBits, isLayeredInFront, canCastShadow,
|
||||
isLayeredInHUD, isGroupCulled](ModelMeshPartPayload& data) {
|
||||
data.updateKey(isVisible, isLayeredInFront || isLayeredInHUD, viewTagBits, isGroupCulled);
|
||||
data.updateKey(isVisible, isLayeredInFront || isLayeredInHUD, canCastShadow, viewTagBits, isGroupCulled);
|
||||
data.setLayer(isLayeredInFront, isLayeredInHUD);
|
||||
});
|
||||
}
|
||||
foreach(auto item, _collisionRenderItemsMap.keys()) {
|
||||
transaction.updateItem<ModelMeshPartPayload>(item, [isVisible, viewTagBits, isLayeredInFront,
|
||||
transaction.updateItem<ModelMeshPartPayload>(item, [isVisible, viewTagBits, isLayeredInFront, canCastShadow,
|
||||
isLayeredInHUD, isGroupCulled](ModelMeshPartPayload& data) {
|
||||
data.updateKey(isVisible, isLayeredInFront || isLayeredInHUD, viewTagBits, isGroupCulled);
|
||||
data.updateKey(isVisible, isLayeredInFront || isLayeredInHUD, canCastShadow, viewTagBits, isGroupCulled);
|
||||
data.setLayer(isLayeredInFront, isLayeredInHUD);
|
||||
});
|
||||
}
|
||||
|
@ -1562,14 +1585,15 @@ void Model::addMaterial(graphics::MaterialLayer material, const std::string& par
|
|||
uint8_t viewTagBits = getViewTagBits();
|
||||
bool layeredInFront = isLayeredInFront();
|
||||
bool layeredInHUD = isLayeredInHUD();
|
||||
bool canCastShadow = _canCastShadow;
|
||||
bool wireframe = isWireframe();
|
||||
auto meshIndex = _modelMeshRenderItemShapes[shapeID].meshIndex;
|
||||
bool invalidatePayloadShapeKey = shouldInvalidatePayloadShapeKey(meshIndex);
|
||||
transaction.updateItem<ModelMeshPartPayload>(itemID, [material, visible, layeredInFront, layeredInHUD, viewTagBits,
|
||||
transaction.updateItem<ModelMeshPartPayload>(itemID, [material, visible, layeredInFront, layeredInHUD, viewTagBits, canCastShadow,
|
||||
invalidatePayloadShapeKey, wireframe](ModelMeshPartPayload& data) {
|
||||
data.addMaterial(material);
|
||||
// if the material changed, we might need to update our item key or shape key
|
||||
data.updateKey(visible, layeredInFront || layeredInHUD, viewTagBits);
|
||||
data.updateKey(visible, layeredInFront || layeredInHUD, canCastShadow, viewTagBits);
|
||||
data.setShapeKey(invalidatePayloadShapeKey, wireframe);
|
||||
});
|
||||
}
|
||||
|
@ -1587,14 +1611,15 @@ void Model::removeMaterial(graphics::MaterialPointer material, const std::string
|
|||
uint8_t viewTagBits = getViewTagBits();
|
||||
bool layeredInFront = isLayeredInFront();
|
||||
bool layeredInHUD = isLayeredInHUD();
|
||||
bool canCastShadow = _canCastShadow;
|
||||
bool wireframe = isWireframe();
|
||||
auto meshIndex = _modelMeshRenderItemShapes[shapeID].meshIndex;
|
||||
bool invalidatePayloadShapeKey = shouldInvalidatePayloadShapeKey(meshIndex);
|
||||
transaction.updateItem<ModelMeshPartPayload>(itemID, [material, visible, layeredInFront, layeredInHUD, viewTagBits,
|
||||
transaction.updateItem<ModelMeshPartPayload>(itemID, [material, visible, layeredInFront, layeredInHUD, viewTagBits, canCastShadow,
|
||||
invalidatePayloadShapeKey, wireframe](ModelMeshPartPayload& data) {
|
||||
data.removeMaterial(material);
|
||||
// if the material changed, we might need to update our item key or shape key
|
||||
data.updateKey(visible, layeredInFront || layeredInHUD, viewTagBits);
|
||||
data.updateKey(visible, layeredInFront || layeredInHUD, canCastShadow, viewTagBits);
|
||||
data.setShapeKey(invalidatePayloadShapeKey, wireframe);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -87,6 +87,10 @@ public:
|
|||
|
||||
// new Scene/Engine rendering support
|
||||
void setVisibleInScene(bool isVisible, const render::ScenePointer& scene, uint8_t viewTagBits, bool isGroupCulled);
|
||||
|
||||
bool canCastShadow() const { return _canCastShadow; }
|
||||
void setCanCastShadow(bool canCastShadow, const render::ScenePointer& scene, uint8_t viewTagBits, bool isGroupCulled);
|
||||
|
||||
void setLayeredInFront(bool isLayeredInFront, const render::ScenePointer& scene);
|
||||
void setLayeredInHUD(bool isLayeredInHUD, const render::ScenePointer& scene);
|
||||
bool needsFixupInScene() const;
|
||||
|
@ -404,6 +408,8 @@ protected:
|
|||
bool _isVisible;
|
||||
uint8_t _viewTagBits{ render::ItemKey::TAG_BITS_ALL };
|
||||
|
||||
bool _canCastShadow;
|
||||
|
||||
gpu::Buffers _blendedVertexBuffers;
|
||||
|
||||
QVector<QVector<QSharedPointer<Texture> > > _dilatedTextures;
|
||||
|
|
|
@ -218,7 +218,10 @@ void RenderShadowTask::build(JobModel& task, const render::Varying& input, rende
|
|||
const auto setupOutput = task.addJob<RenderShadowSetup>("ShadowSetup");
|
||||
const auto queryResolution = setupOutput.getN<RenderShadowSetup::Outputs>(2);
|
||||
// Fetch and cull the items from the scene
|
||||
static const auto shadowCasterFilter = ItemFilter::Builder::visibleWorldItems().withTypeShape().withOpaque().withoutLayered().withTagBits(tagBits, tagMask);
|
||||
|
||||
// Enable models to not cast shadows (otherwise, models will always cast shadows)
|
||||
static const auto shadowCasterFilter = ItemFilter::Builder::visibleWorldItems().withTypeShape().withOpaque().withoutLayered().withTagBits(tagBits, tagMask).withShadowCaster();
|
||||
|
||||
const auto fetchInput = FetchSpatialTree::Inputs(shadowCasterFilter, queryResolution).asVarying();
|
||||
const auto shadowSelection = task.addJob<FetchSpatialTree>("FetchShadowTree", fetchInput);
|
||||
const auto selectionInputs = FetchSpatialSelection::Inputs(shadowSelection, shadowCasterFilter).asVarying();
|
||||
|
@ -297,8 +300,14 @@ void RenderShadowSetup::setSlopeBias(int cascadeIndex, float value) {
|
|||
}
|
||||
|
||||
void RenderShadowSetup::run(const render::RenderContextPointer& renderContext, Outputs& output) {
|
||||
// Abort all jobs if not casting shadows
|
||||
auto lightStage = renderContext->_scene->getStage<LightStage>();
|
||||
assert(lightStage);
|
||||
if (!lightStage->getCurrentKeyLight() || !lightStage->getCurrentKeyLight()->getCastShadows()) {
|
||||
renderContext->taskFlow.abortTask();
|
||||
return;
|
||||
}
|
||||
|
||||
// Cache old render args
|
||||
RenderArgs* args = renderContext->args;
|
||||
|
||||
|
@ -378,12 +387,13 @@ void RenderShadowSetup::run(const render::RenderContextPointer& renderContext, O
|
|||
void RenderShadowCascadeSetup::run(const render::RenderContextPointer& renderContext, Outputs& output) {
|
||||
auto lightStage = renderContext->_scene->getStage<LightStage>();
|
||||
assert(lightStage);
|
||||
|
||||
// Cache old render args
|
||||
RenderArgs* args = renderContext->args;
|
||||
|
||||
const auto globalShadow = lightStage->getCurrentKeyShadow();
|
||||
if (globalShadow && _cascadeIndex<globalShadow->getCascadeCount()) {
|
||||
output.edit0() = ItemFilter::Builder::visibleWorldItems().withTypeShape().withOpaque().withoutLayered().withTagBits(_tagBits, _tagMask);
|
||||
output.edit0() = ItemFilter::Builder::visibleWorldItems().withTypeShape().withOpaque().withoutLayered().withTagBits(_tagBits, _tagMask).withShadowCaster();
|
||||
|
||||
// Set the keylight render args
|
||||
auto& cascade = globalShadow->getCascade(_cascadeIndex);
|
||||
|
|
|
@ -38,7 +38,7 @@ class RenderShadowTaskConfig : public render::Task::Config::Persistent {
|
|||
Q_OBJECT
|
||||
Q_PROPERTY(bool enabled MEMBER enabled NOTIFY dirty)
|
||||
public:
|
||||
RenderShadowTaskConfig() : render::Task::Config::Persistent(QStringList() << "Render" << "Engine" << "Shadows", false) {}
|
||||
RenderShadowTaskConfig() : render::Task::Config::Persistent(QStringList() << "Render" << "Engine" << "Shadows", true) {}
|
||||
|
||||
signals:
|
||||
void dirty();
|
||||
|
|
|
@ -226,7 +226,6 @@ public:
|
|||
Builder& withVisible() { _value.reset(ItemKey::INVISIBLE); _mask.set(ItemKey::INVISIBLE); return (*this); }
|
||||
Builder& withInvisible() { _value.set(ItemKey::INVISIBLE); _mask.set(ItemKey::INVISIBLE); return (*this); }
|
||||
|
||||
Builder& withNoShadowCaster() { _value.reset(ItemKey::SHADOW_CASTER); _mask.set(ItemKey::SHADOW_CASTER); return (*this); }
|
||||
Builder& withShadowCaster() { _value.set(ItemKey::SHADOW_CASTER); _mask.set(ItemKey::SHADOW_CASTER); return (*this); }
|
||||
|
||||
Builder& withoutLayered() { _value.reset(ItemKey::LAYERED); _mask.set(ItemKey::LAYERED); return (*this); }
|
||||
|
|
|
@ -42,25 +42,28 @@
|
|||
</div>
|
||||
</fieldset>
|
||||
|
||||
|
||||
<fieldset id="general" class="major">
|
||||
<div class="shape-group shape-section property dropdown" id="shape-list">
|
||||
<label for="property-shape">Shape</label>
|
||||
<select name="SelectShape" id="property-shape">
|
||||
<option value="Cube">Box</option>
|
||||
<option value="Sphere">Sphere</option>
|
||||
<option value="Tetrahedron">Tetrahedron</option>
|
||||
<option value="Octahedron">Octahedron</option>
|
||||
<option value="Icosahedron">Icosahedron</option>
|
||||
<option value="Dodecahedron">Dodecahedron</option>
|
||||
<option value="Hexagon">Hexagon</option>
|
||||
<option value="Triangle">Triangle</option>
|
||||
<option value="Octagon">Octagon</option>
|
||||
<option value="Cylinder">Cylinder</option>
|
||||
<option value="Cone">Cone</option>
|
||||
<option value="Circle">Circle</option>
|
||||
<option value="Quad">Quad</option>
|
||||
</select>
|
||||
<option value="Cube">Box</option>
|
||||
<option value="Sphere">Sphere</option>
|
||||
<option value="Tetrahedron">Tetrahedron</option>
|
||||
<option value="Octahedron">Octahedron</option>
|
||||
<option value="Icosahedron">Icosahedron</option>
|
||||
<option value="Dodecahedron">Dodecahedron</option>
|
||||
<option value="Hexagon">Hexagon</option>
|
||||
<option value="Triangle">Triangle</option>
|
||||
<option value="Octagon">Octagon</option>
|
||||
<option value="Cylinder">Cylinder</option>
|
||||
<option value="Cone">Cone</option>
|
||||
<option value="Circle">Circle</option>
|
||||
<option value="Quad">Quad</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="can-cast-shadow-section property checkbox">
|
||||
<input type="checkbox" id="property-can-cast-shadow">
|
||||
<label for="property-can-cast-shadow">Can cast shadow</label>
|
||||
</div>
|
||||
<div class="property text">
|
||||
<label for="property-name">Name</label>
|
||||
|
@ -293,7 +296,6 @@
|
|||
</div>
|
||||
</fieldset>
|
||||
|
||||
|
||||
<fieldset id="behavior" class="major">
|
||||
<legend class="section-header behavior-group">
|
||||
Behavior<span class=".collapse-icon">M</span>
|
||||
|
@ -365,8 +367,6 @@
|
|||
</div>
|
||||
</fieldset>
|
||||
|
||||
|
||||
|
||||
<fieldset id="light" class="major">
|
||||
<legend class="section-header light-group light-section">
|
||||
Light<span class=".collapse-icon">M</span>
|
||||
|
@ -400,7 +400,6 @@
|
|||
</fieldset>
|
||||
</fieldset>
|
||||
|
||||
|
||||
<fieldset id="model" class="major">
|
||||
<legend class="section-header model-group model-section zone-section">
|
||||
Model<span class=".collapse-icon">M</span>
|
||||
|
@ -484,7 +483,6 @@
|
|||
</fieldset>
|
||||
</fieldset>
|
||||
|
||||
|
||||
<fieldset id="zone" class="major">
|
||||
<legend class="section-header zone-group zone-section">
|
||||
Zone<span class=".collapse-icon">M</span>
|
||||
|
@ -532,6 +530,10 @@
|
|||
<div></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="zone-group zone-section keylight-section property checkbox">
|
||||
<input type="checkbox" id="property-zone-key-light-cast-shadows">
|
||||
<label for="property-zone-key-light-cast-shadows">Cast Shadows</label>
|
||||
</div>
|
||||
<fieldset class="minor">
|
||||
<legend class="sub-section-header zone-group zone-section background-section">
|
||||
Skybox
|
||||
|
@ -676,7 +678,7 @@
|
|||
min="-1000" max="50000" step="10"></div>
|
||||
</div>
|
||||
</fieldset-->
|
||||
</fieldset>
|
||||
</fieldset>
|
||||
</fieldset>
|
||||
<fieldset id="text" class="major">
|
||||
<legend class="section-header text-group text-section">
|
||||
|
|
|
@ -616,6 +616,8 @@ function loaded() {
|
|||
|
||||
var elShape = document.getElementById("property-shape");
|
||||
|
||||
var elCanCastShadow = document.getElementById("property-can-cast-shadow");
|
||||
|
||||
var elLightSpotLight = document.getElementById("property-light-spot-light");
|
||||
var elLightColor = document.getElementById("property-light-color");
|
||||
var elLightColorRed = document.getElementById("property-light-color-red");
|
||||
|
@ -687,6 +689,8 @@ function loaded() {
|
|||
var elZoneKeyLightDirectionX = document.getElementById("property-zone-key-light-direction-x");
|
||||
var elZoneKeyLightDirectionY = document.getElementById("property-zone-key-light-direction-y");
|
||||
|
||||
var elZoneKeyLightCastShadows = document.getElementById("property-zone-key-light-cast-shadows");
|
||||
|
||||
// Skybox
|
||||
var elZoneSkyboxModeInherit = document.getElementById("property-zone-skybox-mode-inherit");
|
||||
var elZoneSkyboxModeDisabled = document.getElementById("property-zone-skybox-mode-disabled");
|
||||
|
@ -844,7 +848,6 @@ function loaded() {
|
|||
|
||||
elLocked.checked = properties.locked;
|
||||
|
||||
|
||||
elName.value = properties.name;
|
||||
|
||||
elVisible.checked = properties.visible;
|
||||
|
@ -1011,6 +1014,12 @@ function loaded() {
|
|||
properties.color.green + "," + properties.color.blue + ")";
|
||||
}
|
||||
|
||||
if (properties.type === "Model" ||
|
||||
properties.type === "Shape" || properties.type === "Box" || properties.type === "Sphere") {
|
||||
|
||||
elCanCastShadow.checked = properties.canCastShadow;
|
||||
}
|
||||
|
||||
if (properties.type === "Model") {
|
||||
elModelURL.value = properties.modelURL;
|
||||
elShapeType.value = properties.shapeType;
|
||||
|
@ -1060,7 +1069,6 @@ function loaded() {
|
|||
elLightFalloffRadius.value = properties.falloffRadius.toFixed(1);
|
||||
elLightExponent.value = properties.exponent.toFixed(2);
|
||||
elLightCutoff.value = properties.cutoff.toFixed(2);
|
||||
|
||||
} else if (properties.type === "Zone") {
|
||||
// Key light
|
||||
elZoneKeyLightModeInherit.checked = (properties.keyLightMode === 'inherit');
|
||||
|
@ -1076,6 +1084,8 @@ function loaded() {
|
|||
elZoneKeyLightDirectionX.value = properties.keyLight.direction.x.toFixed(2);
|
||||
elZoneKeyLightDirectionY.value = properties.keyLight.direction.y.toFixed(2);
|
||||
|
||||
elZoneKeyLightCastShadows.checked = properties.keyLight.castShadows;
|
||||
|
||||
// Skybox
|
||||
elZoneSkyboxModeInherit.checked = (properties.skyboxMode === 'inherit');
|
||||
elZoneSkyboxModeDisabled.checked = (properties.skyboxMode === 'disabled');
|
||||
|
@ -1139,13 +1149,15 @@ function loaded() {
|
|||
// Show/hide sections as required
|
||||
showElements(document.getElementsByClassName('skybox-section'),
|
||||
elZoneSkyboxModeEnabled.checked);
|
||||
|
||||
showElements(document.getElementsByClassName('keylight-section'),
|
||||
elZoneKeyLightModeEnabled.checked);
|
||||
|
||||
showElements(document.getElementsByClassName('ambient-section'),
|
||||
elZoneAmbientLightModeEnabled.checked);
|
||||
|
||||
showElements(document.getElementsByClassName('haze-section'),
|
||||
elZoneHazeModeEnabled.checked);
|
||||
|
||||
} else if (properties.type === "PolyVox") {
|
||||
elVoxelVolumeSizeX.value = properties.voxelVolumeSize.x.toFixed(2);
|
||||
elVoxelVolumeSizeY.value = properties.voxelVolumeSize.y.toFixed(2);
|
||||
|
@ -1176,6 +1188,15 @@ function loaded() {
|
|||
elMaterialMappingRot.value = properties.materialMappingRot.toFixed(2);
|
||||
}
|
||||
|
||||
// Only these types can cast a shadow
|
||||
if (properties.type === "Model" ||
|
||||
properties.type === "Shape" || properties.type === "Box" || properties.type === "Sphere") {
|
||||
|
||||
showElements(document.getElementsByClassName('can-cast-shadow-section'), true);
|
||||
} else {
|
||||
showElements(document.getElementsByClassName('can-cast-shadow-section'), false);
|
||||
}
|
||||
|
||||
if (properties.locked) {
|
||||
disableProperties();
|
||||
elLocked.removeAttribute('disabled');
|
||||
|
@ -1432,6 +1453,8 @@ function loaded() {
|
|||
|
||||
elShape.addEventListener('change', createEmitTextPropertyUpdateFunction('shape'));
|
||||
|
||||
elCanCastShadow.addEventListener('change', createEmitCheckedPropertyUpdateFunction('canCastShadow'));
|
||||
|
||||
elImageURL.addEventListener('change', createImageURLUpdateFunction('textures'));
|
||||
|
||||
elWebSourceURL.addEventListener('change', createEmitTextPropertyUpdateFunction('sourceUrl'));
|
||||
|
@ -1590,6 +1613,9 @@ function loaded() {
|
|||
elZoneKeyLightDirectionX.addEventListener('change', zoneKeyLightDirectionChangeFunction);
|
||||
elZoneKeyLightDirectionY.addEventListener('change', zoneKeyLightDirectionChangeFunction);
|
||||
|
||||
elZoneKeyLightCastShadows.addEventListener('change',
|
||||
createEmitGroupCheckedPropertyUpdateFunction('keyLight', 'castShadows'));
|
||||
|
||||
// Skybox
|
||||
var skyboxModeChanged = createZoneComponentModeChangedFunction('skyboxMode',
|
||||
elZoneSkyboxModeInherit, elZoneSkyboxModeDisabled, elZoneSkyboxModeEnabled);
|
||||
|
|
Loading…
Reference in a new issue