|
|
@@ -8,6 +8,7 @@
|
|
|
#include "Sphere.h"
|
|
|
#include "PointLight.h"
|
|
|
#include "SpotLight.h"
|
|
|
+#include "JobManager.h"
|
|
|
|
|
|
|
|
|
//======================================================================================================================
|
|
|
@@ -83,14 +84,14 @@ void VisibilityTester::test(Camera& cam)
|
|
|
//
|
|
|
// Get the renderables for the main cam
|
|
|
//
|
|
|
- getRenderableNodes(false, cam);
|
|
|
+ getRenderableNodes(false, cam, cam);
|
|
|
|
|
|
//
|
|
|
// For every spot light camera collect the renderable nodes
|
|
|
//
|
|
|
BOOST_FOREACH(SpotLight* spot, cam.getVisibleSpotLights())
|
|
|
{
|
|
|
- getRenderableNodes(true, spot->getCamera());
|
|
|
+ getRenderableNodes(true, spot->getCamera(), *spot);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -108,18 +109,29 @@ bool VisibilityTester::test(const Type& tested, const Camera& cam)
|
|
|
//======================================================================================================================
|
|
|
// getRenderableNodes =
|
|
|
//======================================================================================================================
|
|
|
-void VisibilityTester::getRenderableNodes(bool skipShadowless, Camera& cam)
|
|
|
+void VisibilityTester::getRenderableNodes(bool skipShadowless_, const Camera& cam_, VisibilityInfo& storage)
|
|
|
{
|
|
|
- cam.getVisibleMsRenderableNodes().clear();
|
|
|
- cam.getVisibleBsRenderableNodes().clear();
|
|
|
+ cam = &cam_;
|
|
|
+ skipShadowless = skipShadowless_;
|
|
|
+ visibilityInfo = &storage;
|
|
|
|
|
|
+ storage.getVisibleMsRenderableNodes().clear();
|
|
|
+ storage.getVisibleBsRenderableNodes().clear();
|
|
|
+
|
|
|
+ for(uint i = 0; i < JobManagerSingleton::getInstance().getThreadsNum(); i++)
|
|
|
+ {
|
|
|
+ JobManagerSingleton::getInstance().assignNewJob(i, getRenderableNodesJobCallback, this);
|
|
|
+ }
|
|
|
+ JobManagerSingleton::getInstance().waitForAllJobsToFinish();
|
|
|
+
|
|
|
+ /*
|
|
|
//
|
|
|
// ModelNodes
|
|
|
//
|
|
|
BOOST_FOREACH(ModelNode* node, scene.getModelNodes())
|
|
|
{
|
|
|
// Skip if the ModeNode is not visible
|
|
|
- if(!test(*node, cam))
|
|
|
+ if(!test(*node, *cam))
|
|
|
{
|
|
|
continue;
|
|
|
}
|
|
|
@@ -136,15 +148,15 @@ void VisibilityTester::getRenderableNodes(bool skipShadowless, Camera& cam)
|
|
|
}
|
|
|
|
|
|
// Test if visible by main camera
|
|
|
- if(test(*modelPatchNode, cam))
|
|
|
+ if(test(*modelPatchNode, *cam))
|
|
|
{
|
|
|
if(modelPatchNode->getCpMtl().renderInBlendingStage())
|
|
|
{
|
|
|
- cam.getVisibleBsRenderableNodes().push_back(modelPatchNode);
|
|
|
+ storage.getVisibleBsRenderableNodes().push_back(modelPatchNode);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
- cam.getVisibleMsRenderableNodes().push_back(modelPatchNode);
|
|
|
+ storage.getVisibleMsRenderableNodes().push_back(modelPatchNode);
|
|
|
}
|
|
|
modelPatchNode->setVisible(true);
|
|
|
}
|
|
|
@@ -157,7 +169,7 @@ void VisibilityTester::getRenderableNodes(bool skipShadowless, Camera& cam)
|
|
|
BOOST_FOREACH(SkinNode* node, scene.getSkinNodes())
|
|
|
{
|
|
|
// Skip if the SkinNode is not visible
|
|
|
- if(!test(*node, cam))
|
|
|
+ if(!test(*node, *cam))
|
|
|
{
|
|
|
continue;
|
|
|
}
|
|
|
@@ -175,22 +187,144 @@ void VisibilityTester::getRenderableNodes(bool skipShadowless, Camera& cam)
|
|
|
|
|
|
if(patchNode->getCpMtl().renderInBlendingStage())
|
|
|
{
|
|
|
- cam.getVisibleBsRenderableNodes().push_back(patchNode);
|
|
|
+ storage.getVisibleBsRenderableNodes().push_back(patchNode);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
- cam.getVisibleMsRenderableNodes().push_back(patchNode);
|
|
|
+ storage.getVisibleMsRenderableNodes().push_back(patchNode);
|
|
|
}
|
|
|
patchNode->setVisible(true);
|
|
|
}
|
|
|
- }
|
|
|
+ }*/
|
|
|
|
|
|
//
|
|
|
// Sort the renderables from closest to the camera to the farthest
|
|
|
//
|
|
|
- std::sort(cam.getVisibleMsRenderableNodes().begin(), cam.getVisibleMsRenderableNodes().end(),
|
|
|
- CmpDistanceFromOrigin(cam.getWorldTransform().getOrigin()));
|
|
|
- std::sort(cam.getVisibleBsRenderableNodes().begin(), cam.getVisibleBsRenderableNodes().end(),
|
|
|
- CmpDistanceFromOrigin(cam.getWorldTransform().getOrigin()));
|
|
|
+ std::sort(storage.getVisibleMsRenderableNodes().begin(), storage.getVisibleMsRenderableNodes().end(),
|
|
|
+ CmpDistanceFromOrigin(cam->getWorldTransform().getOrigin()));
|
|
|
+ std::sort(storage.getVisibleBsRenderableNodes().begin(), storage.getVisibleBsRenderableNodes().end(),
|
|
|
+ CmpDistanceFromOrigin(cam->getWorldTransform().getOrigin()));
|
|
|
}
|
|
|
|
|
|
+
|
|
|
+//======================================================================================================================
|
|
|
+// getRenderableNodesJobCallback =
|
|
|
+//======================================================================================================================
|
|
|
+void VisibilityTester::getRenderableNodesJobCallback(void* args, const WorkerThread& workerThread)
|
|
|
+{
|
|
|
+ uint id = workerThread.getId();
|
|
|
+ uint threadsNum = workerThread.getJobManager().getThreadsNum();
|
|
|
+ VisibilityTester* visTester = reinterpret_cast<VisibilityTester*>(args);
|
|
|
+ Scene& scene = visTester->scene;
|
|
|
+
|
|
|
+ uint count, from, to;
|
|
|
+ size_t nodesSize;
|
|
|
+
|
|
|
+ //
|
|
|
+ // ModelNodes
|
|
|
+ //
|
|
|
+ nodesSize = scene.getModelNodes().size();
|
|
|
+ count = nodesSize / threadsNum;
|
|
|
+ from = count * id;
|
|
|
+ to = count * (id + 1);
|
|
|
+
|
|
|
+ if(id == threadsNum - 1) // The last job will get the rest
|
|
|
+ {
|
|
|
+ to = nodesSize;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ Scene::Types<ModelNode>::Iterator it = scene.getModelNodes().begin() + from;
|
|
|
+ while(it != scene.getModelNodes().begin() + to)
|
|
|
+ {
|
|
|
+ ASSERT(it != scene.getModelNodes().end());
|
|
|
+ ModelNode* node = *it;
|
|
|
+
|
|
|
+ // Skip if the ModeNode is not visible
|
|
|
+ if(!test(*node, *visTester->cam))
|
|
|
+ {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ node->setVisible(true);
|
|
|
+
|
|
|
+ // If visible test every patch individually
|
|
|
+ BOOST_FOREACH(ModelPatchNode* modelPatchNode, node->getModelPatchNodes())
|
|
|
+ {
|
|
|
+ // Skip shadowless
|
|
|
+ if(visTester->skipShadowless && !modelPatchNode->getCpMtl().castsShadow())
|
|
|
+ {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ // Test if visible by main camera
|
|
|
+ if(test(*modelPatchNode, *visTester->cam))
|
|
|
+ {
|
|
|
+ if(modelPatchNode->getCpMtl().renderInBlendingStage())
|
|
|
+ {
|
|
|
+ boost::mutex::scoped_lock lock(visTester->bsRenderableNodesMtx);
|
|
|
+ visTester->visibilityInfo->getVisibleBsRenderableNodes().push_back(modelPatchNode);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ boost::mutex::scoped_lock lock(visTester->msRenderableNodesMtx);
|
|
|
+ visTester->visibilityInfo->getVisibleMsRenderableNodes().push_back(modelPatchNode);
|
|
|
+ }
|
|
|
+ modelPatchNode->setVisible(true);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ //
|
|
|
+ // SkinNodes
|
|
|
+ //
|
|
|
+ {
|
|
|
+ nodesSize = scene.getSkinNodes().size();
|
|
|
+ count = nodesSize / threadsNum;
|
|
|
+ from = count * id;
|
|
|
+ to = count * (id + 1);
|
|
|
+
|
|
|
+ if(id == threadsNum - 1) // The last job will get the rest
|
|
|
+ {
|
|
|
+ to = nodesSize;
|
|
|
+ }
|
|
|
+
|
|
|
+ Scene::Types<SkinNode>::Iterator it = scene.getSkinNodes().begin() + from;
|
|
|
+ while(it != scene.getSkinNodes().begin() + to)
|
|
|
+ {
|
|
|
+ ASSERT(it != scene.getSkinNodes().end());
|
|
|
+ SkinNode* node = *it;
|
|
|
+
|
|
|
+ // Skip if the SkinNode is not visible
|
|
|
+ if(!test(*node, *visTester->cam))
|
|
|
+ {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ node->setVisible(true);
|
|
|
+
|
|
|
+ // Put all the patches into the visible container
|
|
|
+ BOOST_FOREACH(SkinPatchNode* patchNode, node->getPatcheNodes())
|
|
|
+ {
|
|
|
+ // Skip shadowless
|
|
|
+ if(visTester->skipShadowless && !patchNode->getCpMtl().castsShadow())
|
|
|
+ {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ if(patchNode->getCpMtl().renderInBlendingStage())
|
|
|
+ {
|
|
|
+ boost::mutex::scoped_lock lock(visTester->bsRenderableNodesMtx);
|
|
|
+ visTester->visibilityInfo->getVisibleBsRenderableNodes().push_back(patchNode);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ boost::mutex::scoped_lock lock(visTester->msRenderableNodesMtx);
|
|
|
+ visTester->visibilityInfo->getVisibleMsRenderableNodes().push_back(patchNode);
|
|
|
+ }
|
|
|
+ patchNode->setVisible(true);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|