aboutsummaryrefslogtreecommitdiff
path: root/source/Irrlicht/COctreeSceneNode.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/Irrlicht/COctreeSceneNode.cpp')
-rw-r--r--source/Irrlicht/COctreeSceneNode.cpp677
1 files changed, 0 insertions, 677 deletions
diff --git a/source/Irrlicht/COctreeSceneNode.cpp b/source/Irrlicht/COctreeSceneNode.cpp
deleted file mode 100644
index 16df119..0000000
--- a/source/Irrlicht/COctreeSceneNode.cpp
+++ /dev/null
@@ -1,677 +0,0 @@
-// Copyright (C) 2002-2012 Nikolaus Gebhardt
-// This file is part of the "Irrlicht Engine".
-// For conditions of distribution and use, see copyright notice in irrlicht.h
-
-#include "IrrCompileConfig.h"
-#ifdef _IRR_COMPILE_WITH_OCTREE_SCENENODE_
-
-#include "COctreeSceneNode.h"
-#include "Octree.h"
-#include "ISceneManager.h"
-#include "IVideoDriver.h"
-#include "ICameraSceneNode.h"
-#include "IMeshCache.h"
-#include "IAnimatedMesh.h"
-#include "IMaterialRenderer.h"
-#include "os.h"
-#ifdef _IRR_COMPILE_WITH_SHADOW_VOLUME_SCENENODE_
-#include "CShadowVolumeSceneNode.h"
-#else
-#include "IShadowVolumeSceneNode.h"
-#endif // _IRR_COMPILE_WITH_SHADOW_VOLUME_SCENENODE_
-#include "EProfileIDs.h"
-#include "IProfiler.h"
-
-namespace irr
-{
-namespace scene
-{
-
-
-//! constructor
-COctreeSceneNode::COctreeSceneNode(ISceneNode* parent, ISceneManager* mgr,
- s32 id, s32 minimalPolysPerNode)
- : IOctreeSceneNode(parent, mgr, id), StdOctree(0), LightMapOctree(0),
- TangentsOctree(0), VertexType((video::E_VERTEX_TYPE)-1),
- MinimalPolysPerNode(minimalPolysPerNode), Mesh(0), Shadow(0),
- UseVBOs(EOV_NO_VBO), PolygonChecks(EOPC_BOX)
-{
-#ifdef _DEBUG
- setDebugName("COctreeSceneNode");
-#endif
-
- IRR_PROFILE(
- static bool initProfile = false;
- if (!initProfile )
- {
- initProfile = true;
- getProfiler().add(EPID_OC_RENDER, L"render octnode", L"Irrlicht scene");
- getProfiler().add(EPID_OC_CALCPOLYS, L"calc octnode", L"Irrlicht scene");
- }
- )
-}
-
-
-//! destructor
-COctreeSceneNode::~COctreeSceneNode()
-{
- if (Shadow)
- Shadow->drop();
- deleteTree();
-}
-
-
-void COctreeSceneNode::OnRegisterSceneNode()
-{
- if (IsVisible)
- {
- // because this node supports rendering of mixed mode meshes consisting of
- // transparent and solid material at the same time, we need to go through all
- // materials, check of what type they are and register this node for the right
- // render pass according to that.
-
- video::IVideoDriver* driver = SceneManager->getVideoDriver();
-
- PassCount = 0;
- u32 transparentCount = 0;
- u32 solidCount = 0;
-
- // count transparent and solid materials in this scene node
- for (u32 i=0; i<Materials.size(); ++i)
- {
- if (driver->needsTransparentRenderPass(Materials[i]))
- ++transparentCount;
- else
- ++solidCount;
-
- if (solidCount && transparentCount)
- break;
- }
-
- // register according to material types counted
-
- if (solidCount)
- SceneManager->registerNodeForRendering(this, scene::ESNRP_SOLID);
-
- if (transparentCount)
- SceneManager->registerNodeForRendering(this, scene::ESNRP_TRANSPARENT);
-
- ISceneNode::OnRegisterSceneNode();
- }
-}
-
-template <class VT>
-void renderMeshBuffer(video::IVideoDriver* driver, EOCTREENODE_VBO useVBO, typename Octree<VT>::SMeshChunk& meshChunk, const typename Octree<VT>::SIndexData& indexData)
-{
- switch ( useVBO )
- {
- case EOV_NO_VBO:
- driver->drawIndexedTriangleList(
- &meshChunk.Vertices[0],
- meshChunk.Vertices.size(),
- indexData.Indices, indexData.CurrentSize / 3);
- break;
- case EOV_USE_VBO:
- driver->drawMeshBuffer ( &meshChunk );
- break;
- case EOV_USE_VBO_WITH_VISIBITLY:
- {
- u16* oldPointer = meshChunk.Indices.pointer();
- const u32 oldSize = meshChunk.Indices.size();
- meshChunk.Indices.set_free_when_destroyed(false);
- meshChunk.Indices.set_pointer(indexData.Indices, indexData.CurrentSize, false, false);
- meshChunk.setDirty(scene::EBT_INDEX);
- driver->drawMeshBuffer ( &meshChunk );
- meshChunk.Indices.set_pointer(oldPointer, oldSize);
- meshChunk.setDirty(scene::EBT_INDEX);
- break;
- }
- }
-}
-
-//! renders the node.
-void COctreeSceneNode::render()
-{
- IRR_PROFILE(CProfileScope psRender(EPID_OC_RENDER);)
- video::IVideoDriver* driver = SceneManager->getVideoDriver();
-
- if (!driver)
- return;
-
- ICameraSceneNode* camera = SceneManager->getActiveCamera();
- if (!camera)
- return;
-
- const bool isTransparentPass =
- SceneManager->getSceneNodeRenderPass() == scene::ESNRP_TRANSPARENT;
- ++PassCount;
-
- driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
-
- if (Shadow)
- Shadow->updateShadowVolumes();
-
- SViewFrustum frust = *camera->getViewFrustum();
-
- //transform the frustum to the current absolute transformation
- if ( !AbsoluteTransformation.isIdentity() )
- {
- core::matrix4 invTrans(AbsoluteTransformation, core::matrix4::EM4CONST_INVERSE);
- frust.transform(invTrans);
- }
-
- const core::aabbox3d<float> &box = frust.getBoundingBox();
-
- switch (VertexType)
- {
- case video::EVT_STANDARD:
- {
- IRR_PROFILE(getProfiler().start(EPID_OC_CALCPOLYS));
- switch ( PolygonChecks )
- {
- case EOPC_BOX:
- StdOctree->calculatePolys(box);
- break;
- case EOPC_FRUSTUM:
- StdOctree->calculatePolys(frust);
- break;
- }
- IRR_PROFILE(getProfiler().stop(EPID_OC_CALCPOLYS));
-
- const Octree<video::S3DVertex>::SIndexData* d = StdOctree->getIndexData();
-
- for (u32 i=0; i<Materials.size(); ++i)
- {
- if ( 0 == d[i].CurrentSize )
- continue;
-
- const bool transparent = driver->needsTransparentRenderPass(Materials[i]);
-
- // only render transparent buffer if this is the transparent render pass
- // and solid only in solid pass
- if (transparent == isTransparentPass)
- {
- driver->setMaterial(Materials[i]);
- renderMeshBuffer<video::S3DVertex>(driver, UseVBOs, StdMeshes[i], d[i]);
- }
- }
- }
- break;
- case video::EVT_2TCOORDS:
- {
- IRR_PROFILE(getProfiler().start(EPID_OC_CALCPOLYS));
- switch ( PolygonChecks )
- {
- case EOPC_BOX:
- LightMapOctree->calculatePolys(box);
- break;
- case EOPC_FRUSTUM:
- LightMapOctree->calculatePolys(frust);
- break;
- }
- IRR_PROFILE(getProfiler().stop(EPID_OC_CALCPOLYS));
-
- const Octree<video::S3DVertex2TCoords>::SIndexData* d = LightMapOctree->getIndexData();
-
- for (u32 i=0; i<Materials.size(); ++i)
- {
- if ( 0 == d[i].CurrentSize )
- continue;
-
- const video::IMaterialRenderer* const rnd = driver->getMaterialRenderer(Materials[i].MaterialType);
- const bool transparent = (rnd && rnd->isTransparent());
-
- // only render transparent buffer if this is the transparent render pass
- // and solid only in solid pass
- if (transparent == isTransparentPass)
- {
- driver->setMaterial(Materials[i]);
-
- renderMeshBuffer<video::S3DVertex2TCoords>(driver, UseVBOs, LightMapMeshes[i], d[i]);
- }
- }
- }
- break;
- case video::EVT_TANGENTS:
- {
- IRR_PROFILE(getProfiler().start(EPID_OC_CALCPOLYS));
- switch ( PolygonChecks )
- {
- case EOPC_BOX:
- TangentsOctree->calculatePolys(box);
- break;
- case EOPC_FRUSTUM:
- TangentsOctree->calculatePolys(frust);
- break;
- }
- IRR_PROFILE(getProfiler().stop(EPID_OC_CALCPOLYS));
-
- const Octree<video::S3DVertexTangents>::SIndexData* d = TangentsOctree->getIndexData();
-
- for (u32 i=0; i<Materials.size(); ++i)
- {
- if ( 0 == d[i].CurrentSize )
- continue;
-
- const video::IMaterialRenderer* const rnd = driver->getMaterialRenderer(Materials[i].MaterialType);
- const bool transparent = (rnd && rnd->isTransparent());
-
- // only render transparent buffer if this is the transparent render pass
- // and solid only in solid pass
- if (transparent == isTransparentPass)
- {
- driver->setMaterial(Materials[i]);
- renderMeshBuffer<video::S3DVertexTangents>(driver, UseVBOs, TangentsMeshes[i], d[i]);
- }
- }
- }
- break;
- }
-
- // for debug purposes only
- if (DebugDataVisible && !Materials.empty() && PassCount==1)
- {
- core::array< const core::aabbox3d<f32>* > boxes;
- video::SMaterial m;
- m.Lighting = false;
- driver->setMaterial(m);
- if ( DebugDataVisible & scene::EDS_BBOX_BUFFERS )
- {
- switch (VertexType)
- {
- case video::EVT_STANDARD:
- StdOctree->getBoundingBoxes(box, boxes);
- break;
- case video::EVT_2TCOORDS:
- LightMapOctree->getBoundingBoxes(box, boxes);
- break;
- case video::EVT_TANGENTS:
- TangentsOctree->getBoundingBoxes(box, boxes);
- break;
- }
-
- for (u32 b=0; b!=boxes.size(); ++b)
- driver->draw3DBox(*boxes[b]);
- }
-
- if ( DebugDataVisible & scene::EDS_BBOX )
- driver->draw3DBox(Box,video::SColor(0,255,0,0));
- }
-
-}
-
-
-//! Removes a child from this scene node.
-//! Implemented here, to be able to remove the shadow properly, if there is one,
-//! or to remove attached childs.
-bool COctreeSceneNode::removeChild(ISceneNode* child)
-{
- if (child && Shadow == child)
- {
- Shadow->drop();
- Shadow = 0;
- }
-
- return ISceneNode::removeChild(child);
-}
-
-void COctreeSceneNode::setUseVBO(EOCTREENODE_VBO useVBO)
-{
- UseVBOs = useVBO;
- if ( Mesh )
- createTree(Mesh);
-}
-
-EOCTREENODE_VBO COctreeSceneNode::getUseVBO() const
-{
- return UseVBOs;
-}
-
-void COctreeSceneNode::setPolygonChecks(EOCTREE_POLYGON_CHECKS checks)
-{
- PolygonChecks = checks;
-}
-
-EOCTREE_POLYGON_CHECKS COctreeSceneNode::getPolygonChecks() const
-{
- return PolygonChecks;
-}
-
-//! Creates shadow volume scene node as child of this node
-//! and returns a pointer to it.
-IShadowVolumeSceneNode* COctreeSceneNode::addShadowVolumeSceneNode(
- const IMesh* shadowMesh, s32 id, bool zfailmethod, f32 infinity)
-{
-#ifdef _IRR_COMPILE_WITH_SHADOW_VOLUME_SCENENODE_
- if (!SceneManager->getVideoDriver()->queryFeature(video::EVDF_STENCIL_BUFFER))
- return 0;
-
- if (!shadowMesh)
- shadowMesh = Mesh; // if null is given, use the mesh of node
-
- if (Shadow)
- Shadow->drop();
-
- Shadow = new CShadowVolumeSceneNode(shadowMesh, this, SceneManager, id, zfailmethod, infinity);
- return Shadow;
-#else
- return 0;
-#endif
-}
-
-
-//! returns the axis aligned bounding box of this node
-const core::aabbox3d<f32>& COctreeSceneNode::getBoundingBox() const
-{
- return Box;
-}
-
-
-//! creates the tree
-/* This method has a lot of duplication and overhead. Moreover, the tangents mesh conversion does not really work. I think we need a a proper mesh implementation for octrees, which handle all vertex types internally. Converting all structures to just one vertex type is always problematic.
-Thanks to Auria for fixing major parts of this method. */
-bool COctreeSceneNode::createTree(IMesh* mesh)
-{
- if (!mesh)
- return false;
-
- MeshName = SceneManager->getMeshCache()->getMeshName(mesh);
-
- mesh->grab();
- deleteTree();
-
- Mesh = mesh;
-
- const u32 beginTime = os::Timer::getRealTime();
-
- u32 nodeCount = 0;
- u32 polyCount = 0;
- u32 i;
-
- Box = mesh->getBoundingBox();
-
- if (mesh->getMeshBufferCount())
- {
- // check for "largest" buffer types
- // Also dropping buffers/materials for empty buffer
- // (which looks like a horrible idea. If a user wanted that material without mesh he should still get it...
- // but not going to change that now. Only documenting it after figuring out what happens here.
- // It works at least as Materials are reset in deleteTree).
- VertexType = video::EVT_STANDARD;
- u32 meshReserve = 0;
- for (i=0; i<mesh->getMeshBufferCount(); ++i)
- {
- const IMeshBuffer* b = mesh->getMeshBuffer(i);
- if (b->getVertexCount() && b->getIndexCount())
- {
- ++meshReserve;
- if (b->getVertexType() == video::EVT_2TCOORDS)
- VertexType = video::EVT_2TCOORDS;
- else if (b->getVertexType() == video::EVT_TANGENTS)
- VertexType = video::EVT_TANGENTS;
- }
- }
- Materials.reallocate(Materials.size()+meshReserve);
-
- switch(VertexType)
- {
- case video::EVT_STANDARD:
- {
- StdMeshes.reallocate(StdMeshes.size() + meshReserve);
- for (i=0; i<mesh->getMeshBufferCount(); ++i)
- {
- IMeshBuffer* b = mesh->getMeshBuffer(i);
-
- if (b->getVertexCount() && b->getIndexCount())
- {
- Materials.push_back(b->getMaterial());
-
- StdMeshes.push_back(Octree<video::S3DVertex>::SMeshChunk());
- Octree<video::S3DVertex>::SMeshChunk &nchunk = StdMeshes.getLast();
- nchunk.MaterialId = Materials.size() - 1;
-
- u32 v;
- nchunk.Vertices.reallocate(b->getVertexCount());
- switch (b->getVertexType())
- {
- case video::EVT_STANDARD:
- for (v=0; v<b->getVertexCount(); ++v)
- nchunk.Vertices.push_back(((video::S3DVertex*)b->getVertices())[v]);
- break;
- case video::EVT_2TCOORDS:
- for (v=0; v<b->getVertexCount(); ++v)
- nchunk.Vertices.push_back(((video::S3DVertex2TCoords*)b->getVertices())[v]);
- break;
- case video::EVT_TANGENTS:
- for (v=0; v<b->getVertexCount(); ++v)
- nchunk.Vertices.push_back(((video::S3DVertexTangents*)b->getVertices())[v]);
- break;
- }
-
- polyCount += b->getIndexCount();
-
- nchunk.Indices.reallocate(b->getIndexCount());
- for (v=0; v<b->getIndexCount(); ++v)
- nchunk.Indices.push_back(b->getIndices()[v]);
- }
- }
-
- StdOctree = new Octree<video::S3DVertex>(StdMeshes, MinimalPolysPerNode);
- nodeCount = StdOctree->getNodeCount();
- }
- break;
- case video::EVT_2TCOORDS:
- {
- LightMapMeshes.reallocate(LightMapMeshes.size() + meshReserve);
-
- for ( i=0; i < mesh->getMeshBufferCount(); ++i)
- {
- IMeshBuffer* b = mesh->getMeshBuffer(i);
-
- if (b->getVertexCount() && b->getIndexCount())
- {
- Materials.push_back(b->getMaterial());
- LightMapMeshes.push_back(Octree<video::S3DVertex2TCoords>::SMeshChunk());
- Octree<video::S3DVertex2TCoords>::SMeshChunk& nchunk = LightMapMeshes.getLast();
- nchunk.MaterialId = Materials.size() - 1;
-
- if (UseVBOs == EOV_USE_VBO_WITH_VISIBITLY)
- {
- nchunk.setHardwareMappingHint(scene::EHM_STATIC, scene::EBT_VERTEX);
- nchunk.setHardwareMappingHint(scene::EHM_DYNAMIC, scene::EBT_INDEX);
- }
- else
- nchunk.setHardwareMappingHint(scene::EHM_STATIC);
-
- u32 v;
- nchunk.Vertices.reallocate(b->getVertexCount());
- switch (b->getVertexType())
- {
- case video::EVT_STANDARD:
- for (v=0; v<b->getVertexCount(); ++v)
- nchunk.Vertices.push_back(((video::S3DVertex*)b->getVertices())[v]);
- break;
- case video::EVT_2TCOORDS:
- for (v=0; v<b->getVertexCount(); ++v)
- nchunk.Vertices.push_back(((video::S3DVertex2TCoords*)b->getVertices())[v]);
- break;
- case video::EVT_TANGENTS:
- for (v=0; v<b->getVertexCount(); ++v)
- nchunk.Vertices.push_back(((video::S3DVertexTangents*)b->getVertices())[v]);
- break;
- }
-
- polyCount += b->getIndexCount();
- nchunk.Indices.reallocate(b->getIndexCount());
- for (v=0; v<b->getIndexCount(); ++v)
- nchunk.Indices.push_back(b->getIndices()[v]);
- }
- }
-
- LightMapOctree = new Octree<video::S3DVertex2TCoords>(LightMapMeshes, MinimalPolysPerNode);
- nodeCount = LightMapOctree->getNodeCount();
- }
- break;
- case video::EVT_TANGENTS:
- {
- TangentsMeshes.reallocate(TangentsMeshes.size() + meshReserve);
-
- for (u32 i=0; i<mesh->getMeshBufferCount(); ++i)
- {
- IMeshBuffer* b = mesh->getMeshBuffer(i);
-
- if (b->getVertexCount() && b->getIndexCount())
- {
- Materials.push_back(b->getMaterial());
- TangentsMeshes.push_back(Octree<video::S3DVertexTangents>::SMeshChunk());
- Octree<video::S3DVertexTangents>::SMeshChunk& nchunk = TangentsMeshes.getLast();
- nchunk.MaterialId = Materials.size() - 1;
-
- u32 v;
- nchunk.Vertices.reallocate(b->getVertexCount());
- switch (b->getVertexType())
- {
- case video::EVT_STANDARD:
- for (v=0; v<b->getVertexCount(); ++v)
- {
- const video::S3DVertex& tmpV = ((video::S3DVertex*)b->getVertices())[v];
- nchunk.Vertices.push_back(video::S3DVertexTangents(tmpV.Pos, tmpV.Color, tmpV.TCoords));
- }
- break;
- case video::EVT_2TCOORDS:
- for (v=0; v<b->getVertexCount(); ++v)
- {
- const video::S3DVertex2TCoords& tmpV = ((video::S3DVertex2TCoords*)b->getVertices())[v];
- nchunk.Vertices.push_back(video::S3DVertexTangents(tmpV.Pos, tmpV.Color, tmpV.TCoords));
- }
- break;
- case video::EVT_TANGENTS:
- for (v=0; v<b->getVertexCount(); ++v)
- nchunk.Vertices.push_back(((video::S3DVertexTangents*)b->getVertices())[v]);
- break;
- }
-
- polyCount += b->getIndexCount();
- nchunk.Indices.reallocate(b->getIndexCount());
- for (v=0; v<b->getIndexCount(); ++v)
- nchunk.Indices.push_back(b->getIndices()[v]);
- }
- }
-
- TangentsOctree = new Octree<video::S3DVertexTangents>(TangentsMeshes, MinimalPolysPerNode);
- nodeCount = TangentsOctree->getNodeCount();
- }
- break;
- }
- }
-
- const u32 endTime = os::Timer::getRealTime();
- c8 tmp[255];
- sprintf(tmp, "Needed %ums to create Octree SceneNode.(%u nodes, %u polys)",
- endTime - beginTime, nodeCount, polyCount/3);
- os::Printer::log(tmp, ELL_INFORMATION);
-
- return true;
-}
-
-
-//! returns the material based on the zero based index i.
-video::SMaterial& COctreeSceneNode::getMaterial(u32 i)
-{
- if ( i >= Materials.size() )
- return ISceneNode::getMaterial(i);
-
- return Materials[i];
-}
-
-
-//! returns amount of materials used by this scene node.
-u32 COctreeSceneNode::getMaterialCount() const
-{
- return Materials.size();
-}
-
-
-//! Writes attributes of the scene node.
-void COctreeSceneNode::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const
-{
- ISceneNode::serializeAttributes(out, options);
-
- out->addInt("MinimalPolysPerNode", MinimalPolysPerNode);
- out->addString("Mesh", MeshName.c_str());
-}
-
-
-//! Reads attributes of the scene node.
-void COctreeSceneNode::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options)
-{
- const s32 oldMinimal = MinimalPolysPerNode;
-
- MinimalPolysPerNode = in->getAttributeAsInt("MinimalPolysPerNode");
- io::path newMeshStr = in->getAttributeAsString("Mesh");
-
- IMesh* newMesh = 0;
-
- if (newMeshStr == "")
- newMeshStr = MeshName;
-
- IAnimatedMesh* newAnimatedMesh = SceneManager->getMesh(newMeshStr.c_str());
-
- if (newAnimatedMesh)
- newMesh = newAnimatedMesh->getMesh(0);
-
- if (newMesh && ((MeshName != newMeshStr) || (MinimalPolysPerNode != oldMinimal)))
- {
- // recalculate tree
- createTree(newMesh);
- }
-
- ISceneNode::deserializeAttributes(in, options);
-}
-
-
-void COctreeSceneNode::deleteTree()
-{
- delete StdOctree;
- StdOctree = 0;
- StdMeshes.clear();
-
- delete LightMapOctree;
- LightMapOctree = 0;
- LightMapMeshes.clear();
-
- delete TangentsOctree;
- TangentsOctree = 0;
- TangentsMeshes.clear();
-
- Materials.clear();
-
- if(Mesh)
- Mesh->drop();
-}
-
-void COctreeSceneNode::setMesh(IMesh* mesh)
-{
- createTree(mesh);
-}
-
-IMesh* COctreeSceneNode::getMesh(void)
-{
- return Mesh;
-}
-
-void COctreeSceneNode::setReadOnlyMaterials(bool readonly)
-{
- // Do nothing
-}
-
-bool COctreeSceneNode::isReadOnlyMaterials() const
-{
- return false;
-}
-
-
-} // end namespace scene
-} // end namespace irr
-
-#endif // _IRR_COMPILE_WITH_OCTREE_SCENENODE_