Adding a light item per zone

This commit is contained in:
samcake 2017-05-04 16:47:03 -07:00
parent 32a7631bb9
commit 64317f5fd0
7 changed files with 198 additions and 4 deletions

View file

@ -21,6 +21,9 @@
#include "EntityTreeRenderer.h"
#include "RenderableEntityItem.h"
#include <LightPayload.h>
// Sphere entities should fit inside a cube entity of the same size, so a sphere that has dimensions 1x1x1
// is a half unit sphere. However, the geometry cache renders a UNIT sphere, so we need to scale down.
static const float SPHERE_ENTITY_SCALE = 0.5f;
@ -168,6 +171,37 @@ void RenderableZoneEntityItem::render(RenderArgs* args) {
_model->removeFromScene(scene, transaction);
scene->enqueueTransaction(transaction);
}
/*
{
// Set the keylight
sceneKeyLight->setColor(ColorUtils::toVec3(this->getKeyLightProperties().getColor()));
sceneKeyLight->setIntensity(this->getKeyLightProperties().getIntensity());
sceneKeyLight->setAmbientIntensity(this->getKeyLightProperties().getAmbientIntensity());
sceneKeyLight->setDirection(this->getKeyLightProperties().getDirection());
// Set the stage
bool isSunModelEnabled = this->getStageProperties().getSunModelEnabled();
sceneStage->setSunModelEnable(isSunModelEnabled);
if (isSunModelEnabled) {
sceneStage->setLocation(this->getStageProperties().getLongitude(),
this->getStageProperties().getLatitude(),
this->getStageProperties().getAltitude());
auto sceneTime = sceneStage->getTime();
sceneTime->setHour(this->getStageProperties().calculateHour());
sceneTime->setDay(this->getStageProperties().calculateDay());
}
// Set the ambient texture
_ambientTextureURL = this->getKeyLightProperties().getAmbientURL();
if (_ambientTextureURL.isEmpty()) {
_pendingAmbientTexture = false;
_ambientTexture.clear();
} else {
_pendingAmbientTexture = true;
}
}*/
}
bool RenderableZoneEntityItem::contains(const glm::vec3& point) const {
@ -229,11 +263,25 @@ bool RenderableZoneEntityItem::addToScene(EntityItemPointer self, const render::
renderPayload->addStatusGetters(statusGetters);
transaction.resetItem(_myMetaItem, renderPayload);
_myKeyLightItem = scene->allocateID();
auto keyLightPayload = std::make_shared<KeyLightPayload>();
updateKeyLightItemFromEntity((*keyLightPayload));
auto keyLightItem = std::make_shared<KeyLightPayload::Payload>(keyLightPayload);
transaction.resetItem(_myKeyLightItem, keyLightItem);
return true;
}
void RenderableZoneEntityItem::removeFromScene(EntityItemPointer self, const render::ScenePointer& scene,
render::Transaction& transaction) {
transaction.removeItem(_myKeyLightItem);
render::Item::clearID(_myKeyLightItem);
transaction.removeItem(_myMetaItem);
render::Item::clearID(_myMetaItem);
if (_model) {
@ -249,11 +297,43 @@ void RenderableZoneEntityItem::notifyBoundChanged() {
render::Transaction transaction;
render::ScenePointer scene = AbstractViewStateInterface::instance()->getMain3DScene();
if (scene) {
transaction.updateItem<RenderableZoneEntityItemMeta>(_myMetaItem, [](RenderableZoneEntityItemMeta& data) {
});
transaction.updateItem<RenderableZoneEntityItemMeta>(_myMetaItem, [](RenderableZoneEntityItemMeta& data) {});
transaction.updateItem<KeyLightPayload>(_myKeyLightItem, [](KeyLightPayload& data) {});
scene->enqueueTransaction(transaction);
} else {
qCWarning(entitiesrenderer) << "RenderableZoneEntityItem::notifyBoundChanged(), Unexpected null scene, possibly during application shutdown";
}
}
void RenderableZoneEntityItem::updateKeyLightItemFromEntity(KeyLightPayload& keylightPayload) {
auto entity = this;
keylightPayload.setVisible(entity->getVisible());
auto light = keylightPayload.editLight();
light->setPosition(entity->getPosition());
light->setOrientation(entity->getRotation());
bool success;
keylightPayload.editBound() = entity->getAABox(success);
if (!success) {
keylightPayload.editBound() = render::Item::Bound();
}
// Set the keylight
light->setColor(ColorUtils::toVec3(this->getKeyLightProperties().getColor()));
light->setIntensity(this->getKeyLightProperties().getIntensity());
light->setAmbientIntensity(this->getKeyLightProperties().getAmbientIntensity());
light->setDirection(this->getKeyLightProperties().getDirection());
// light->setColor(toGlm(entity->getXColor()));
// float intensity = entity->getIntensity();//* entity->getFadingRatio();
// light->setIntensity(intensity);
light->setType(model::Light::SUN);
}

View file

@ -16,6 +16,7 @@
#include <ZoneEntityItem.h>
class NetworkGeometry;
class KeyLightPayload;
class RenderableZoneEntityItem : public ZoneEntityItem {
public:
@ -42,7 +43,7 @@ public:
virtual void removeFromScene(EntityItemPointer self, const render::ScenePointer& scene, render::Transaction& transaction) override;
render::ItemID getRenderItemID() const { return _myMetaItem; }
private:
virtual void locationChanged(bool tellPhysics = true) override { EntityItem::locationChanged(tellPhysics); notifyBoundChanged(); }
virtual void dimensionsChanged() override { EntityItem::dimensionsChanged(); notifyBoundChanged(); }
@ -54,11 +55,17 @@ private:
template<typename Lambda>
void changeProperties(Lambda functor);
void updateKeyLightItemFromEntity(KeyLightPayload& keylightPayload);
Model* _model;
bool _needsInitialSimulation;
render::ItemID _myMetaItem{ render::Item::INVALID_ITEM_ID };
render::ItemID _myKeyLightItem { render::Item::INVALID_ITEM_ID };
};
#endif // hifi_RenderableZoneEntityItem_h

View file

@ -81,3 +81,71 @@ void LightPayload::render(RenderArgs* args) {
}
}
namespace render {
template <> const ItemKey payloadGetKey(const KeyLightPayload::Pointer& payload) {
ItemKey::Builder builder;
builder.withTypeLight();
if (!payload || !payload->isVisible()) {
builder.withInvisible();
}
return builder.build();
}
template <> const Item::Bound payloadGetBound(const KeyLightPayload::Pointer& payload) {
if (payload) {
return payload->editBound();
}
return render::Item::Bound();
}
template <> void payloadRender(const KeyLightPayload::Pointer& payload, RenderArgs* args) {
if (args) {
if (payload) {
payload->render(args);
}
}
}
}
KeyLightPayload::KeyLightPayload() :
_light(std::make_shared<model::Light>())
{
}
KeyLightPayload::~KeyLightPayload() {
if (!LightStage::isIndexInvalid(_index)) {
if (_stage) {
_stage->removeLight(_index);
}
}
}
void KeyLightPayload::render(RenderArgs* args) {
if (!_stage) {
_stage = DependencyManager::get<DeferredLightingEffect>()->getLightStage();
}
// Do we need to allocate the light in the stage ?
if (LightStage::isIndexInvalid(_index)) {
_index = _stage->addLight(_light);
_needUpdate = false;
}
// Need an update ?
if (_needUpdate) {
_stage->updateLightArrayBuffer(_index);
_needUpdate = false;
}
if (isVisible()) {
// FInally, push the light visible in the frame
_stage->_currentFrame.pushLight(_index, _light->getType());
#ifdef WANT_DEBUG
Q_ASSERT(args->_batch);
gpu::Batch& batch = *args->_batch;
batch.setModelTransform(getTransformToCenter());
DependencyManager::get<GeometryCache>()->renderWireSphere(batch, 0.5f, 15, 15, glm::vec4(color, 1.0f));
#endif
}
}

View file

@ -46,4 +46,34 @@ namespace render {
template <> void payloadRender(const LightPayload::Pointer& payload, RenderArgs* args);
}
class KeyLightPayload {
public:
using Payload = render::Payload<KeyLightPayload>;
using Pointer = Payload::DataPointer;
KeyLightPayload();
~KeyLightPayload();
void render(RenderArgs* args);
model::LightPointer editLight() { _needUpdate = true; return _light; }
render::Item::Bound& editBound() { _needUpdate = true; return _bound; }
void setVisible(bool visible) { _isVisible = visible; }
bool isVisible() const { return _isVisible; }
protected:
model::LightPointer _light;
render::Item::Bound _bound;
LightStagePointer _stage;
LightStage::Index _index { LightStage::INVALID_INDEX };
bool _needUpdate { true };
bool _isVisible { true };
};
namespace render {
template <> const ItemKey payloadGetKey(const KeyLightPayload::Pointer& payload);
template <> const Item::Bound payloadGetBound(const KeyLightPayload::Pointer& payload);
template <> void payloadRender(const KeyLightPayload::Pointer& payload, RenderArgs* args);
}
#endif

View file

@ -123,14 +123,17 @@ public:
switch (type) {
case model::Light::POINT: { pushPointLight(index); break; }
case model::Light::SPOT: { pushSpotLight(index); break; }
case model::Light::SUN: { pushSunLight(index); break; }
default: { break; }
}
}
void pushPointLight(LightStage::Index index) { _pointLights.emplace_back(index); }
void pushSpotLight(LightStage::Index index) { _spotLights.emplace_back(index); }
void pushSunLight(LightStage::Index index) { _sunLights.emplace_back(index); }
LightStage::LightIndices _pointLights;
LightStage::LightIndices _spotLights;
LightStage::LightIndices _sunLights;
};
Frame _currentFrame;

View file

@ -162,6 +162,7 @@ void RenderDeferredTask::build(JobModel& task, const render::Varying& input, ren
task.addJob<DrawBounds>("DrawOpaqueBounds", opaques);
task.addJob<DrawBounds>("DrawTransparentBounds", transparents);
task.addJob<DrawBounds>("DrawLightBounds", lights);
task.addJob<ZoneRendererTask>("ZoneRenderer", opaques);
}

View file

@ -189,6 +189,11 @@ Column {
checked: Render.getConfig("DrawOverlayTransparentBounds")["enabled"]
onCheckedChanged: { Render.getConfig("DrawOverlayTransparentBounds")["enabled"] = checked }
}
CheckBox {
text: "Lights"
checked: Render.getConfig("DrawLightBounds")["enabled"]
onCheckedChanged: { Render.getConfig("DrawLightBounds")["enabled"] = checked; }
}
CheckBox {
text: "Zones"
checked: Render.getConfig("DrawZones")["enabled"]