mirror of
https://github.com/overte-org/overte.git
synced 2025-04-21 19:04:32 +02:00
Merge pull request #4966 from ZappoMan/team-teaching-scene-api
TEAM TEACHING - primitive (non-model) entities rendering using new engine.
This commit is contained in:
commit
be7b4f97e6
9 changed files with 186 additions and 33 deletions
|
@ -348,6 +348,9 @@ public:
|
|||
|
||||
void setMaxOctreePacketsPerSecond(int maxOctreePPS);
|
||||
int getMaxOctreePacketsPerSecond();
|
||||
|
||||
render::ScenePointer getMain3DScene() { return _main3DScene; }
|
||||
render::EnginePointer getRenderEngine() { return _renderEngine; }
|
||||
|
||||
signals:
|
||||
|
||||
|
|
|
@ -12,4 +12,4 @@ find_package(Bullet REQUIRED)
|
|||
target_include_directories(${TARGET_NAME} SYSTEM PRIVATE ${BULLET_INCLUDE_DIRS})
|
||||
target_link_libraries(${TARGET_NAME} ${BULLET_LIBRARIES})
|
||||
|
||||
link_hifi_libraries(shared gpu script-engine render-utils)
|
||||
link_hifi_libraries(shared gpu script-engine render render-utils)
|
||||
|
|
|
@ -29,8 +29,11 @@
|
|||
#include <TextureCache.h>
|
||||
#include <SoundCache.h>
|
||||
|
||||
|
||||
#include "EntityTreeRenderer.h"
|
||||
|
||||
#include "RenderableEntityItem.h"
|
||||
|
||||
#include "RenderableBoxEntityItem.h"
|
||||
#include "RenderableLightEntityItem.h"
|
||||
#include "RenderableModelEntityItem.h"
|
||||
|
@ -92,6 +95,10 @@ void EntityTreeRenderer::clear() {
|
|||
}
|
||||
OctreeRenderer::clear();
|
||||
_entityScripts.clear();
|
||||
|
||||
// TODO/FIXME - this needs to be fixed... we need to clear all items out of the scene in this case.
|
||||
qDebug() << "EntityTreeRenderer::clear() need to clear the scene... ";
|
||||
|
||||
}
|
||||
|
||||
void EntityTreeRenderer::init() {
|
||||
|
@ -474,6 +481,7 @@ void EntityTreeRenderer::applyZonePropertiesToScene(std::shared_ptr<ZoneEntityIt
|
|||
}
|
||||
|
||||
void EntityTreeRenderer::render(RenderArgs* renderArgs) {
|
||||
|
||||
if (_tree && !_shuttingDown) {
|
||||
Model::startScene(renderArgs->_renderSide);
|
||||
|
||||
|
@ -509,7 +517,9 @@ void EntityTreeRenderer::render(RenderArgs* renderArgs) {
|
|||
glPushMatrix();
|
||||
renderArgs->_context->enqueueBatch(batch);
|
||||
glPopMatrix();
|
||||
|
||||
|
||||
renderArgs->_batch = nullptr;
|
||||
|
||||
// stats...
|
||||
_meshesConsidered = renderArgs->_meshesConsidered;
|
||||
_meshesRendered = renderArgs->_meshesRendered;
|
||||
|
@ -693,35 +703,38 @@ void EntityTreeRenderer::renderElement(OctreeElement* element, RenderArgs* args)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// hack for models. :(
|
||||
if (entityItem->getType() == EntityTypes::Model) {
|
||||
// render entityItem
|
||||
AABox entityBox = entityItem->getAABox();
|
||||
|
||||
// render entityItem
|
||||
AABox entityBox = entityItem->getAABox();
|
||||
// TODO: some entity types (like lights) might want to be rendered even
|
||||
// when they are outside of the view frustum...
|
||||
float distance = args->_viewFrustum->distanceToCamera(entityBox.calcCenter());
|
||||
|
||||
// TODO: some entity types (like lights) might want to be rendered even
|
||||
// when they are outside of the view frustum...
|
||||
float distance = args->_viewFrustum->distanceToCamera(entityBox.calcCenter());
|
||||
|
||||
bool outOfView = args->_viewFrustum->boxInFrustum(entityBox) == ViewFrustum::OUTSIDE;
|
||||
if (!outOfView) {
|
||||
bool bigEnoughToRender = _viewState->shouldRenderMesh(entityBox.getLargestDimension(), distance);
|
||||
bool outOfView = args->_viewFrustum->boxInFrustum(entityBox) == ViewFrustum::OUTSIDE;
|
||||
if (!outOfView) {
|
||||
bool bigEnoughToRender = _viewState->shouldRenderMesh(entityBox.getLargestDimension(), distance);
|
||||
|
||||
if (bigEnoughToRender) {
|
||||
renderProxies(entityItem, args);
|
||||
if (bigEnoughToRender) {
|
||||
renderProxies(entityItem, args);
|
||||
|
||||
Glower* glower = NULL;
|
||||
if (entityItem->getGlowLevel() > 0.0f) {
|
||||
glower = new Glower(args, entityItem->getGlowLevel());
|
||||
}
|
||||
entityItem->render(args);
|
||||
args->_itemsRendered++;
|
||||
if (glower) {
|
||||
delete glower;
|
||||
Glower* glower = NULL;
|
||||
if (entityItem->getGlowLevel() > 0.0f) {
|
||||
glower = new Glower(args, entityItem->getGlowLevel());
|
||||
}
|
||||
entityItem->render(args);
|
||||
args->_itemsRendered++;
|
||||
if (glower) {
|
||||
delete glower;
|
||||
}
|
||||
} else {
|
||||
args->_itemsTooSmall++;
|
||||
}
|
||||
} else {
|
||||
args->_itemsTooSmall++;
|
||||
args->_itemsOutOfView++;
|
||||
}
|
||||
} else {
|
||||
args->_itemsOutOfView++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1048,10 +1061,34 @@ void EntityTreeRenderer::deletingEntity(const EntityItemID& entityID) {
|
|||
checkAndCallUnload(entityID);
|
||||
}
|
||||
_entityScripts.remove(entityID);
|
||||
|
||||
// here's where we remove the entity payload from the scene
|
||||
|
||||
render::Scene::PendingChanges pendingChanges;
|
||||
if (_entityToSceneItems.contains(entityID)) {
|
||||
render::ItemID renderItem = _entityToSceneItems[entityID];
|
||||
pendingChanges.removeItem(renderItem);
|
||||
_viewState->getMain3DScene()->enqueuePendingChanges(pendingChanges);
|
||||
}
|
||||
}
|
||||
|
||||
void EntityTreeRenderer::addingEntity(const EntityItemID& entityID) {
|
||||
checkAndCallPreload(entityID);
|
||||
|
||||
// here's where we add the entity payload to the scene
|
||||
|
||||
render::Scene::PendingChanges pendingChanges;
|
||||
render::ItemID renderItem = _viewState->getMain3DScene()->allocateID();
|
||||
_entityToSceneItems[entityID] = renderItem;
|
||||
EntityItemPointer entity = static_cast<EntityTree*>(_tree)->findEntityByID(entityID);
|
||||
|
||||
auto renderData = RenderableEntityItem::Pointer(new RenderableEntityItem(entity));
|
||||
auto renderPayload = render::PayloadPointer(new RenderableEntityItem::Payload(renderData));
|
||||
|
||||
pendingChanges.resetItem(renderItem, renderPayload);
|
||||
|
||||
_viewState->getMain3DScene()->enqueuePendingChanges(pendingChanges);
|
||||
_viewState->getMain3DScene()->processPendingChangesQueue();
|
||||
}
|
||||
|
||||
void EntityTreeRenderer::entitySciptChanging(const EntityItemID& entityID) {
|
||||
|
@ -1181,4 +1218,3 @@ void EntityTreeRenderer::entityCollisionWithEntity(const EntityItemID& idA, cons
|
|||
entityScriptB.property("collisionWithEntity").call(entityScriptA, args);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include <EntityScriptingInterface.h> // for RayToEntityIntersectionResult
|
||||
#include <MouseEvent.h>
|
||||
#include <OctreeRenderer.h>
|
||||
#include <render/Scene.h>
|
||||
#include <ScriptCache.h>
|
||||
#include <AbstractAudioInterface.h>
|
||||
|
||||
|
@ -186,6 +187,8 @@ private:
|
|||
float _previousStageHour;
|
||||
int _previousStageDay;
|
||||
|
||||
QHash<EntityItemID, render::ItemID> _entityToSceneItems;
|
||||
};
|
||||
|
||||
|
||||
#endif // hifi_EntityTreeRenderer_h
|
||||
|
|
38
libraries/entities-renderer/src/RenderableEntityItem.cpp
Normal file
38
libraries/entities-renderer/src/RenderableEntityItem.cpp
Normal file
|
@ -0,0 +1,38 @@
|
|||
//
|
||||
// RenderableEntityItem.cpp
|
||||
// interface/src
|
||||
//
|
||||
// Created by Brad Hefta-Gaub on 12/6/13.
|
||||
// Copyright 2013 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
|
||||
//
|
||||
|
||||
|
||||
#include "RenderableEntityItem.h"
|
||||
|
||||
namespace render {
|
||||
template <> const ItemKey payloadGetKey(const RenderableEntityItem::Pointer& payload) {
|
||||
return ItemKey::Builder::opaqueShape();
|
||||
}
|
||||
|
||||
template <> const Item::Bound payloadGetBound(const RenderableEntityItem::Pointer& payload) {
|
||||
if (payload && payload->entity) {
|
||||
return payload->entity->getAABox();
|
||||
}
|
||||
return render::Item::Bound();
|
||||
}
|
||||
template <> void payloadRender(const RenderableEntityItem::Pointer& payload, RenderArgs* args) {
|
||||
if (args) {
|
||||
args->_elementsTouched++;
|
||||
if (payload && payload->entity) {
|
||||
if (payload->entity->getType() != EntityTypes::Model) {
|
||||
payload->entity->render(args);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
33
libraries/entities-renderer/src/RenderableEntityItem.h
Normal file
33
libraries/entities-renderer/src/RenderableEntityItem.h
Normal file
|
@ -0,0 +1,33 @@
|
|||
//
|
||||
// RenderableEntityItem.h
|
||||
// interface/src
|
||||
//
|
||||
// Created by Brad Hefta-Gaub on 12/6/13.
|
||||
// Copyright 2013 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
|
||||
//
|
||||
|
||||
#ifndef hifi_RenderableEntityItem_h
|
||||
#define hifi_RenderableEntityItem_h
|
||||
|
||||
#include <render/Scene.h>
|
||||
#include <EntityItem.h>
|
||||
|
||||
class RenderableEntityItem {
|
||||
public:
|
||||
RenderableEntityItem(EntityItemPointer entity) : entity(entity) { }
|
||||
typedef render::Payload<RenderableEntityItem> Payload;
|
||||
typedef Payload::DataPointer Pointer;
|
||||
|
||||
EntityItemPointer entity;
|
||||
};
|
||||
|
||||
namespace render {
|
||||
template <> const ItemKey payloadGetKey(const RenderableEntityItem::Pointer& payload);
|
||||
template <> const Item::Bound payloadGetBound(const RenderableEntityItem::Pointer& payload);
|
||||
template <> void payloadRender(const RenderableEntityItem::Pointer& payload, RenderArgs* args);
|
||||
}
|
||||
|
||||
#endif // hifi_RenderableEntityItem_h
|
|
@ -15,6 +15,9 @@
|
|||
#include <glm/glm.hpp>
|
||||
#include <functional>
|
||||
|
||||
#include <render/Scene.h>
|
||||
#include <render/Engine.h>
|
||||
|
||||
#include <QtGlobal>
|
||||
|
||||
class Transform;
|
||||
|
@ -60,6 +63,10 @@ public:
|
|||
virtual void postLambdaEvent(std::function<void()> f) = 0;
|
||||
virtual qreal getDevicePixelRatio() = 0;
|
||||
|
||||
virtual render::ScenePointer getMain3DScene() = 0;
|
||||
virtual render::EnginePointer getRenderEngine() = 0;
|
||||
|
||||
// FIXME - we shouldn't assume that there's a single instance of an AbstractViewStateInterface
|
||||
static AbstractViewStateInterface* instance();
|
||||
static void setInstance(AbstractViewStateInterface* instance);
|
||||
};
|
||||
|
|
|
@ -11,6 +11,12 @@
|
|||
|
||||
#include "DrawTask.h"
|
||||
|
||||
#include <PerfStat.h>
|
||||
|
||||
#include "gpu/Batch.h"
|
||||
#include "gpu/Context.h"
|
||||
|
||||
|
||||
using namespace render;
|
||||
|
||||
|
||||
|
@ -28,13 +34,20 @@ void DrawSceneTask::run(const SceneContextPointer& sceneContext, const RenderCon
|
|||
auto& itemBucketMap = scene->getMasterBucket();
|
||||
|
||||
RenderArgs* args = renderContext->args;
|
||||
gpu::Batch theBatch;
|
||||
|
||||
args->_batch = &theBatch;
|
||||
|
||||
// render opaques
|
||||
auto filter = ItemFilter::Builder::opaqueShape();
|
||||
auto& opaqueShapeItems = itemBucketMap.at(filter);
|
||||
|
||||
|
||||
for (auto id : opaqueShapeItems) {
|
||||
auto item = scene->getItem(id);
|
||||
item.render(args);
|
||||
}
|
||||
|
||||
args->_context->enqueueBatch((*args->_batch));
|
||||
args->_batch = nullptr;
|
||||
};
|
||||
|
||||
|
|
|
@ -12,16 +12,17 @@
|
|||
#ifndef hifi_render_Scene_h
|
||||
#define hifi_render_Scene_h
|
||||
|
||||
#include <bitset>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <set>
|
||||
#include <map>
|
||||
#include <RenderArgs.h>
|
||||
#include <AABox.h>
|
||||
#include <atomic>
|
||||
#include <bitset>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <queue>
|
||||
#include <set>
|
||||
#include <vector>
|
||||
|
||||
#include <AABox.h>
|
||||
#include <RenderArgs.h>
|
||||
|
||||
namespace render {
|
||||
|
||||
|
@ -93,6 +94,13 @@ public:
|
|||
bool isPickable() const { return _flags[PICKABLE]; }
|
||||
};
|
||||
|
||||
inline QDebug operator<<(QDebug debug, const ItemKey& itemKey) {
|
||||
debug << "[ItemKey: isOpaque:" << itemKey.isOpaque()
|
||||
<< ", isStatic:" << itemKey.isStatic()
|
||||
<< ", isWorldSpace:" << itemKey.isWorldSpace()
|
||||
<< "]";
|
||||
return debug;
|
||||
}
|
||||
|
||||
class ItemFilter {
|
||||
public:
|
||||
|
@ -153,6 +161,12 @@ public:
|
|||
};
|
||||
};
|
||||
|
||||
inline QDebug operator<<(QDebug debug, const ItemFilter& me) {
|
||||
debug << "[ItemFilter: opaqueShape:" << me.test(ItemKey::Builder::opaqueShape())
|
||||
<< "]";
|
||||
return debug;
|
||||
}
|
||||
|
||||
class Item {
|
||||
public:
|
||||
typedef std::vector<Item> Vector;
|
||||
|
@ -202,6 +216,12 @@ protected:
|
|||
friend class Scene;
|
||||
};
|
||||
|
||||
inline QDebug operator<<(QDebug debug, const Item& item) {
|
||||
debug << "[Item: _key:" << item.getKey() << ", bounds:" << item.getBound() << "]";
|
||||
return debug;
|
||||
}
|
||||
|
||||
|
||||
// THe Payload class is the real Payload to be used
|
||||
// THis allow anything to be turned into a Payload as long as the required interface functions are available
|
||||
// When creating a new kind of payload from a new "stuff" class then you need to create specialized version for "stuff"
|
||||
|
|
Loading…
Reference in a new issue