Remove shadow volume code
We use shadowmap
This commit is contained in:
parent
d3708ba798
commit
c1d85e8674
@ -148,7 +148,6 @@ source/Irrlicht/CGUISpinBox.cpp
|
||||
source/Irrlicht/CReadFile.cpp
|
||||
source/Irrlicht/CParticleRingEmitter.cpp
|
||||
source/Irrlicht/CMetaTriangleSelector.cpp
|
||||
source/Irrlicht/CShadowVolumeSceneNode.cpp
|
||||
source/Irrlicht/CDefaultSceneNodeFactory.cpp
|
||||
source/Irrlicht/CGUIImage.cpp
|
||||
source/Irrlicht/CGUIEnvironment.cpp
|
||||
@ -233,7 +232,6 @@ source/Irrlicht/CSphereSceneNode.h
|
||||
source/Irrlicht/CIrrDeviceStub.h
|
||||
source/Irrlicht/CDummyTransformationSceneNode.h
|
||||
source/Irrlicht/CParticleBoxEmitter.h
|
||||
source/Irrlicht/CShadowVolumeSceneNode.h
|
||||
source/Irrlicht/COctreeSceneNode.h
|
||||
source/Irrlicht/CReadFile.h
|
||||
source/Irrlicht/COSOperator.h
|
||||
|
@ -94,27 +94,6 @@ namespace scene
|
||||
/** \return The importance of the animation: 1.f keeps the original animation, 0.f is no animation. */
|
||||
virtual f32 getAnimationStrength() const =0;
|
||||
|
||||
//! Creates shadow volume scene node as child of this node.
|
||||
/** The shadow can be rendered using the ZPass or the zfail
|
||||
method. ZPass is a little bit faster because the shadow volume
|
||||
creation is easier, but with this method there occur ugly
|
||||
looking artifacs when the camera is inside the shadow volume.
|
||||
These error do not occur with the ZFail method.
|
||||
\param shadowMesh: Optional custom mesh for shadow volume.
|
||||
\param id: Id of the shadow scene node. This id can be used to
|
||||
identify the node later.
|
||||
\param zfailmethod: If set to true, the shadow will use the
|
||||
zfail method, if not, zpass is used.
|
||||
\param infinity: Value used by the shadow volume algorithm to
|
||||
scale the shadow volume (for zfail shadow volume we support only
|
||||
finite shadows, so camera zfar must be larger than shadow back cap,
|
||||
which is depend on infinity parameter).
|
||||
\return Pointer to the created shadow scene node. This pointer
|
||||
should not be dropped. See IReferenceCounted::drop() for more
|
||||
information. */
|
||||
virtual IShadowVolumeSceneNode* addShadowVolumeSceneNode(const IMesh* shadowMesh=0,
|
||||
s32 id=-1, bool zfailmethod=true, f32 infinity=1000.0f) = 0;
|
||||
|
||||
|
||||
//! Get a pointer to a joint in the mesh (if the mesh is a bone based mesh).
|
||||
/** With this method it is possible to attach scene nodes to
|
||||
|
@ -38,27 +38,6 @@ public:
|
||||
/** \return Pointer to mesh which is displayed by this node. */
|
||||
virtual IMesh* getMesh(void) = 0;
|
||||
|
||||
//! Creates shadow volume scene node as child of this node.
|
||||
/** The shadow can be rendered using the ZPass or the zfail
|
||||
method. ZPass is a little bit faster because the shadow volume
|
||||
creation is easier, but with this method there occur ugly
|
||||
looking artifacs when the camera is inside the shadow volume.
|
||||
These error do not occur with the ZFail method.
|
||||
\param shadowMesh: Optional custom mesh for shadow volume.
|
||||
\param id: Id of the shadow scene node. This id can be used to
|
||||
identify the node later.
|
||||
\param zfailmethod: If set to true, the shadow will use the
|
||||
zfail method, if not, zpass is used.
|
||||
\param infinity: Value used by the shadow volume algorithm to
|
||||
scale the shadow volume (for zfail shadow volume we support only
|
||||
finite shadows, so camera zfar must be larger than shadow back cap,
|
||||
which is depend on infinity parameter).
|
||||
\return Pointer to the created shadow scene node. This pointer
|
||||
should not be dropped. See IReferenceCounted::drop() for more
|
||||
information. */
|
||||
virtual IShadowVolumeSceneNode* addShadowVolumeSceneNode(const IMesh* shadowMesh=0,
|
||||
s32 id=-1, bool zfailmethod=true, f32 infinity=1000.0f) = 0;
|
||||
|
||||
//! Sets if the scene node should not copy the materials of the mesh but use them in a read only style.
|
||||
/** In this way it is possible to change the materials of a mesh
|
||||
causing all mesh scene nodes referencing this mesh to change, too.
|
||||
|
@ -7,7 +7,6 @@
|
||||
#include "ISceneManager.h"
|
||||
#include "S3DVertex.h"
|
||||
#include "os.h"
|
||||
#include "CShadowVolumeSceneNode.h"
|
||||
#include "CSkinnedMesh.h"
|
||||
#include "IDummyTransformationSceneNode.h"
|
||||
#include "IBoneSceneNode.h"
|
||||
@ -37,7 +36,7 @@ CAnimatedMeshSceneNode::CAnimatedMeshSceneNode(IAnimatedMesh* mesh,
|
||||
TransitionTime(0), Transiting(0.f), TransitingBlend(0.f),
|
||||
JointMode(EJUOR_NONE), JointsUsed(false),
|
||||
Looping(true), ReadOnlyMaterials(false), RenderFromIdentity(false),
|
||||
LoopCallBack(0), PassCount(0), Shadow(0)
|
||||
LoopCallBack(0), PassCount(0)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
setDebugName("CAnimatedMeshSceneNode");
|
||||
@ -53,9 +52,6 @@ CAnimatedMeshSceneNode::~CAnimatedMeshSceneNode()
|
||||
if (Mesh)
|
||||
Mesh->drop();
|
||||
|
||||
if (Shadow)
|
||||
Shadow->drop();
|
||||
|
||||
if (LoopCallBack)
|
||||
LoopCallBack->drop();
|
||||
}
|
||||
@ -287,9 +283,6 @@ void CAnimatedMeshSceneNode::render()
|
||||
|
||||
driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
|
||||
|
||||
if (Shadow && PassCount==1)
|
||||
Shadow->updateShadowVolumes();
|
||||
|
||||
// for debug purposes only:
|
||||
|
||||
bool renderMeshes = true;
|
||||
@ -523,23 +516,6 @@ u32 CAnimatedMeshSceneNode::getMaterialCount() const
|
||||
}
|
||||
|
||||
|
||||
//! Creates shadow volume scene node as child of this node
|
||||
//! and returns a pointer to it.
|
||||
IShadowVolumeSceneNode* CAnimatedMeshSceneNode::addShadowVolumeSceneNode(
|
||||
const IMesh* shadowMesh, s32 id, bool zfailmethod, f32 infinity)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
//! Returns a pointer to a child node, which has the same transformation as
|
||||
//! the corresponding joint, if the mesh in this scene node is a skinned mesh.
|
||||
@ -644,12 +620,6 @@ ISceneNode* CAnimatedMeshSceneNode::getXJointNode(const c8* jointName)
|
||||
//! or to remove attached childs.
|
||||
bool CAnimatedMeshSceneNode::removeChild(ISceneNode* child)
|
||||
{
|
||||
if (child && Shadow == child)
|
||||
{
|
||||
Shadow->drop();
|
||||
Shadow = 0;
|
||||
}
|
||||
|
||||
if (ISceneNode::removeChild(child))
|
||||
{
|
||||
if (JointsUsed) //stop weird bugs caused while changing parents as the joints are being created
|
||||
@ -1015,8 +985,6 @@ ISceneNode* CAnimatedMeshSceneNode::clone(ISceneNode* newParent, ISceneManager*
|
||||
newNode->ReadOnlyMaterials = ReadOnlyMaterials;
|
||||
newNode->LoopCallBack = LoopCallBack;
|
||||
newNode->PassCount = PassCount;
|
||||
newNode->Shadow = Shadow;
|
||||
newNode->Shadow->grab();
|
||||
newNode->JointChildSceneNodes = JointChildSceneNodes;
|
||||
newNode->PretransitingSave = PretransitingSave;
|
||||
newNode->RenderFromIdentity = RenderFromIdentity;
|
||||
|
@ -84,11 +84,6 @@ namespace scene
|
||||
//! returns amount of materials used by this scene node.
|
||||
virtual u32 getMaterialCount() const;
|
||||
|
||||
//! Creates shadow volume scene node as child of this node
|
||||
//! and returns a pointer to it.
|
||||
virtual IShadowVolumeSceneNode* addShadowVolumeSceneNode(const IMesh* shadowMesh,
|
||||
s32 id, bool zfailmethod=true, f32 infinity=1000.0f);
|
||||
|
||||
//! Returns a pointer to a child node, which has the same transformation as
|
||||
//! the corrsesponding joint, if the mesh in this scene node is a skinned mesh.
|
||||
virtual IBoneSceneNode* getJointNode(const c8* jointName);
|
||||
@ -199,8 +194,6 @@ namespace scene
|
||||
IAnimationEndCallBack* LoopCallBack;
|
||||
s32 PassCount;
|
||||
|
||||
IShadowVolumeSceneNode* Shadow;
|
||||
|
||||
core::array<IBoneSceneNode* > JointChildSceneNodes;
|
||||
core::array<core::matrix4> PretransitingSave;
|
||||
};
|
||||
|
@ -8,7 +8,6 @@
|
||||
#include "S3DVertex.h"
|
||||
#include "SMeshBuffer.h"
|
||||
#include "os.h"
|
||||
#include "CShadowVolumeSceneNode.h"
|
||||
|
||||
namespace irr
|
||||
{
|
||||
@ -33,7 +32,7 @@ CCubeSceneNode::CCubeSceneNode(f32 size, ISceneNode* parent, ISceneManager* mgr,
|
||||
s32 id, const core::vector3df& position,
|
||||
const core::vector3df& rotation, const core::vector3df& scale)
|
||||
: IMeshSceneNode(parent, mgr, id, position, rotation, scale),
|
||||
Mesh(0), Shadow(0), Size(size)
|
||||
Mesh(0), Size(size)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
setDebugName("CCubeSceneNode");
|
||||
@ -45,8 +44,6 @@ CCubeSceneNode::CCubeSceneNode(f32 size, ISceneNode* parent, ISceneManager* mgr,
|
||||
|
||||
CCubeSceneNode::~CCubeSceneNode()
|
||||
{
|
||||
if (Shadow)
|
||||
Shadow->drop();
|
||||
if (Mesh)
|
||||
Mesh->drop();
|
||||
}
|
||||
@ -66,9 +63,6 @@ void CCubeSceneNode::render()
|
||||
video::IVideoDriver* driver = SceneManager->getVideoDriver();
|
||||
driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
|
||||
|
||||
if (Shadow)
|
||||
Shadow->updateShadowVolumes();
|
||||
|
||||
// for debug purposes only:
|
||||
video::SMaterial mat = Mesh->getMeshBuffer(0)->getMaterial();
|
||||
|
||||
@ -132,35 +126,10 @@ const core::aabbox3d<f32>& CCubeSceneNode::getBoundingBox() const
|
||||
//! or to remove attached childs.
|
||||
bool CCubeSceneNode::removeChild(ISceneNode* child)
|
||||
{
|
||||
if (child && Shadow == child)
|
||||
{
|
||||
Shadow->drop();
|
||||
Shadow = 0;
|
||||
}
|
||||
|
||||
return ISceneNode::removeChild(child);
|
||||
}
|
||||
|
||||
|
||||
//! Creates shadow volume scene node as child of this node
|
||||
//! and returns a pointer to it.
|
||||
IShadowVolumeSceneNode* CCubeSceneNode::addShadowVolumeSceneNode(
|
||||
const IMesh* shadowMesh, s32 id, bool zfailmethod, f32 infinity)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
void CCubeSceneNode::OnRegisterSceneNode()
|
||||
{
|
||||
if (IsVisible)
|
||||
@ -220,8 +189,6 @@ ISceneNode* CCubeSceneNode::clone(ISceneNode* newParent, ISceneManager* newManag
|
||||
|
||||
nb->cloneMembers(this, newManager);
|
||||
nb->getMaterial(0) = getMaterial(0);
|
||||
nb->Shadow = Shadow;
|
||||
nb->Shadow->grab();
|
||||
|
||||
if ( newParent )
|
||||
nb->drop();
|
||||
|
@ -45,11 +45,6 @@ namespace scene
|
||||
//! Returns type of the scene node
|
||||
virtual ESCENE_NODE_TYPE getType() const { return ESNT_CUBE; }
|
||||
|
||||
//! Creates shadow volume scene node as child of this node
|
||||
//! and returns a pointer to it.
|
||||
virtual IShadowVolumeSceneNode* addShadowVolumeSceneNode(const IMesh* shadowMesh,
|
||||
s32 id, bool zfailmethod=true, f32 infinity=10000.0f);
|
||||
|
||||
//! Writes attributes of the scene node.
|
||||
virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options=0) const;
|
||||
|
||||
@ -82,7 +77,6 @@ namespace scene
|
||||
void setSize();
|
||||
|
||||
IMesh* Mesh;
|
||||
IShadowVolumeSceneNode* Shadow;
|
||||
f32 Size;
|
||||
};
|
||||
|
||||
|
@ -11,7 +11,6 @@
|
||||
#include "IAnimatedMesh.h"
|
||||
#include "IMaterialRenderer.h"
|
||||
#include "IFileSystem.h"
|
||||
#include "CShadowVolumeSceneNode.h"
|
||||
|
||||
namespace irr
|
||||
{
|
||||
@ -24,7 +23,7 @@ namespace scene
|
||||
CMeshSceneNode::CMeshSceneNode(IMesh* mesh, ISceneNode* parent, ISceneManager* mgr, s32 id,
|
||||
const core::vector3df& position, const core::vector3df& rotation,
|
||||
const core::vector3df& scale)
|
||||
: IMeshSceneNode(parent, mgr, id, position, rotation, scale), Mesh(0), Shadow(0),
|
||||
: IMeshSceneNode(parent, mgr, id, position, rotation, scale), Mesh(0),
|
||||
PassCount(0), ReadOnlyMaterials(false)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
@ -38,8 +37,6 @@ CMeshSceneNode::CMeshSceneNode(IMesh* mesh, ISceneNode* parent, ISceneManager* m
|
||||
//! destructor
|
||||
CMeshSceneNode::~CMeshSceneNode()
|
||||
{
|
||||
if (Shadow)
|
||||
Shadow->drop();
|
||||
if (Mesh)
|
||||
Mesh->drop();
|
||||
}
|
||||
@ -128,9 +125,6 @@ void CMeshSceneNode::render()
|
||||
driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
|
||||
Box = Mesh->getBoundingBox();
|
||||
|
||||
if (Shadow && PassCount==1)
|
||||
Shadow->updateShadowVolumes();
|
||||
|
||||
// for debug purposes only:
|
||||
|
||||
bool renderMeshes = true;
|
||||
@ -232,12 +226,6 @@ void CMeshSceneNode::render()
|
||||
//! or to remove attached childs.
|
||||
bool CMeshSceneNode::removeChild(ISceneNode* child)
|
||||
{
|
||||
if (child && Shadow == child)
|
||||
{
|
||||
Shadow->drop();
|
||||
Shadow = 0;
|
||||
}
|
||||
|
||||
return ISceneNode::removeChild(child);
|
||||
}
|
||||
|
||||
@ -294,25 +282,6 @@ void CMeshSceneNode::setMesh(IMesh* mesh)
|
||||
}
|
||||
|
||||
|
||||
//! Creates shadow volume scene node as child of this node
|
||||
//! and returns a pointer to it.
|
||||
IShadowVolumeSceneNode* CMeshSceneNode::addShadowVolumeSceneNode(
|
||||
const IMesh* shadowMesh, s32 id, bool zfailmethod, f32 infinity)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
void CMeshSceneNode::copyMaterials()
|
||||
{
|
||||
Materials.clear();
|
||||
@ -432,8 +401,6 @@ ISceneNode* CMeshSceneNode::clone(ISceneNode* newParent, ISceneManager* newManag
|
||||
nb->cloneMembers(this, newManager);
|
||||
nb->ReadOnlyMaterials = ReadOnlyMaterials;
|
||||
nb->Materials = Materials;
|
||||
nb->Shadow = Shadow;
|
||||
nb->Shadow->grab();
|
||||
|
||||
if (newParent)
|
||||
nb->drop();
|
||||
|
@ -60,11 +60,6 @@ namespace scene
|
||||
//! Returns the current mesh
|
||||
virtual IMesh* getMesh(void) { return Mesh; }
|
||||
|
||||
//! Creates shadow volume scene node as child of this node
|
||||
//! and returns a pointer to it.
|
||||
virtual IShadowVolumeSceneNode* addShadowVolumeSceneNode(const IMesh* shadowMesh,
|
||||
s32 id, bool zfailmethod=true, f32 infinity=10000.0f);
|
||||
|
||||
//! Sets if the scene node should not copy the materials of the mesh but use them in a read only style.
|
||||
/* In this way it is possible to change the materials a mesh causing all mesh scene nodes
|
||||
referencing this mesh to change too. */
|
||||
@ -90,7 +85,6 @@ namespace scene
|
||||
video::SMaterial ReadOnlyMaterial;
|
||||
|
||||
IMesh* Mesh;
|
||||
IShadowVolumeSceneNode* Shadow;
|
||||
|
||||
s32 PassCount;
|
||||
bool ReadOnlyMaterials;
|
||||
|
@ -11,7 +11,6 @@
|
||||
#include "IAnimatedMesh.h"
|
||||
#include "IMaterialRenderer.h"
|
||||
#include "os.h"
|
||||
#include "CShadowVolumeSceneNode.h"
|
||||
|
||||
namespace irr
|
||||
{
|
||||
@ -24,7 +23,7 @@ COctreeSceneNode::COctreeSceneNode(ISceneNode* parent, ISceneManager* mgr,
|
||||
s32 id, s32 minimalPolysPerNode)
|
||||
: IMeshSceneNode(parent, mgr, id), StdOctree(0), LightMapOctree(0),
|
||||
TangentsOctree(0), VertexType((video::E_VERTEX_TYPE)-1),
|
||||
MinimalPolysPerNode(minimalPolysPerNode), Mesh(0), Shadow(0),
|
||||
MinimalPolysPerNode(minimalPolysPerNode), Mesh(0),
|
||||
UseVBOs(OCTREE_USE_HARDWARE), UseVisibilityAndVBOs(OCTREE_USE_VISIBILITY),
|
||||
BoxBased(OCTREE_BOX_BASED)
|
||||
{
|
||||
@ -37,8 +36,6 @@ COctreeSceneNode::COctreeSceneNode(ISceneNode* parent, ISceneManager* mgr,
|
||||
//! destructor
|
||||
COctreeSceneNode::~COctreeSceneNode()
|
||||
{
|
||||
if (Shadow)
|
||||
Shadow->drop();
|
||||
deleteTree();
|
||||
}
|
||||
|
||||
@ -104,9 +101,6 @@ void COctreeSceneNode::render()
|
||||
|
||||
driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
|
||||
|
||||
if (Shadow)
|
||||
Shadow->updateShadowVolumes();
|
||||
|
||||
SViewFrustum frust = *camera->getViewFrustum();
|
||||
|
||||
//transform the frustum to the current absolute transformation
|
||||
@ -291,35 +285,10 @@ void COctreeSceneNode::render()
|
||||
//! or to remove attached childs.
|
||||
bool COctreeSceneNode::removeChild(ISceneNode* child)
|
||||
{
|
||||
if (child && Shadow == child)
|
||||
{
|
||||
Shadow->drop();
|
||||
Shadow = 0;
|
||||
}
|
||||
|
||||
return ISceneNode::removeChild(child);
|
||||
}
|
||||
|
||||
|
||||
//! 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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
//! returns the axis aligned bounding box of this node
|
||||
const core::aabbox3d<f32>& COctreeSceneNode::getBoundingBox() const
|
||||
{
|
||||
|
@ -66,11 +66,6 @@ namespace scene
|
||||
//! Check if the scene node should not copy the materials of the mesh but use them in a read only style
|
||||
virtual bool isReadOnlyMaterials() const;
|
||||
|
||||
//! Creates shadow volume scene node as child of this node
|
||||
//! and returns a pointer to it.
|
||||
virtual IShadowVolumeSceneNode* addShadowVolumeSceneNode(const IMesh* shadowMesh,
|
||||
s32 id, bool zfailmethod=true, f32 infinity=10000.0f);
|
||||
|
||||
//! 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.
|
||||
@ -99,7 +94,6 @@ namespace scene
|
||||
s32 PassCount;
|
||||
|
||||
IMesh * Mesh;
|
||||
IShadowVolumeSceneNode* Shadow;
|
||||
//! use VBOs for rendering where possible
|
||||
bool UseVBOs;
|
||||
//! use visibility information together with VBOs
|
||||
|
@ -1,419 +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 "CShadowVolumeSceneNode.h"
|
||||
#include "ISceneManager.h"
|
||||
#include "IMesh.h"
|
||||
#include "IVideoDriver.h"
|
||||
#include "ICameraSceneNode.h"
|
||||
#include "SViewFrustum.h"
|
||||
#include "SLight.h"
|
||||
#include "os.h"
|
||||
|
||||
namespace irr
|
||||
{
|
||||
namespace scene
|
||||
{
|
||||
|
||||
|
||||
//! constructor
|
||||
CShadowVolumeSceneNode::CShadowVolumeSceneNode(const IMesh* shadowMesh, ISceneNode* parent,
|
||||
ISceneManager* mgr, s32 id, bool zfailmethod, f32 infinity)
|
||||
: IShadowVolumeSceneNode(parent, mgr, id),
|
||||
ShadowMesh(0), IndexCount(0), VertexCount(0), ShadowVolumesUsed(0),
|
||||
Infinity(infinity), UseZFailMethod(zfailmethod)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
setDebugName("CShadowVolumeSceneNode");
|
||||
#endif
|
||||
setShadowMesh(shadowMesh);
|
||||
setAutomaticCulling(scene::EAC_OFF);
|
||||
}
|
||||
|
||||
|
||||
//! destructor
|
||||
CShadowVolumeSceneNode::~CShadowVolumeSceneNode()
|
||||
{
|
||||
if (ShadowMesh)
|
||||
ShadowMesh->drop();
|
||||
}
|
||||
|
||||
|
||||
void CShadowVolumeSceneNode::createShadowVolume(const core::vector3df& light, bool isDirectional)
|
||||
{
|
||||
SShadowVolume* svp = 0;
|
||||
core::aabbox3d<f32>* bb = 0;
|
||||
|
||||
// builds the shadow volume and adds it to the shadow volume list.
|
||||
|
||||
if (ShadowVolumes.size() > ShadowVolumesUsed)
|
||||
{
|
||||
// get the next unused buffer
|
||||
|
||||
svp = &ShadowVolumes[ShadowVolumesUsed];
|
||||
svp->set_used(0);
|
||||
|
||||
bb = &ShadowBBox[ShadowVolumesUsed];
|
||||
}
|
||||
else
|
||||
{
|
||||
ShadowVolumes.push_back(SShadowVolume());
|
||||
svp = &ShadowVolumes.getLast();
|
||||
|
||||
ShadowBBox.push_back(core::aabbox3d<f32>());
|
||||
bb = &ShadowBBox.getLast();
|
||||
}
|
||||
svp->reallocate(IndexCount*5);
|
||||
++ShadowVolumesUsed;
|
||||
|
||||
// We use triangle lists
|
||||
Edges.set_used(IndexCount*2);
|
||||
u32 numEdges = 0;
|
||||
|
||||
numEdges=createEdgesAndCaps(light, svp, bb);
|
||||
|
||||
// for all edges add the near->far quads
|
||||
for (u32 i=0; i<numEdges; ++i)
|
||||
{
|
||||
const core::vector3df &v1 = Vertices[Edges[2*i+0]];
|
||||
const core::vector3df &v2 = Vertices[Edges[2*i+1]];
|
||||
const core::vector3df v3(v1+(v1 - light).normalize()*Infinity);
|
||||
const core::vector3df v4(v2+(v2 - light).normalize()*Infinity);
|
||||
|
||||
// Add a quad (two triangles) to the vertex list
|
||||
#ifdef _DEBUG
|
||||
if (svp->size() >= svp->allocated_size()-5)
|
||||
os::Printer::log("Allocation too small.", ELL_DEBUG);
|
||||
#endif
|
||||
svp->push_back(v1);
|
||||
svp->push_back(v2);
|
||||
svp->push_back(v3);
|
||||
|
||||
svp->push_back(v2);
|
||||
svp->push_back(v4);
|
||||
svp->push_back(v3);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#define IRR_USE_ADJACENCY
|
||||
#define IRR_USE_REVERSE_EXTRUDED
|
||||
|
||||
u32 CShadowVolumeSceneNode::createEdgesAndCaps(const core::vector3df& light,
|
||||
SShadowVolume* svp, core::aabbox3d<f32>* bb)
|
||||
{
|
||||
u32 numEdges=0;
|
||||
const u32 faceCount = IndexCount / 3;
|
||||
|
||||
if(faceCount >= 1)
|
||||
bb->reset(Vertices[Indices[0]]);
|
||||
else
|
||||
bb->reset(0,0,0);
|
||||
|
||||
// Check every face if it is front or back facing the light.
|
||||
for (u32 i=0; i<faceCount; ++i)
|
||||
{
|
||||
const core::vector3df v0 = Vertices[Indices[3*i+0]];
|
||||
const core::vector3df v1 = Vertices[Indices[3*i+1]];
|
||||
const core::vector3df v2 = Vertices[Indices[3*i+2]];
|
||||
|
||||
#ifdef IRR_USE_REVERSE_EXTRUDED
|
||||
FaceData[i]=core::triangle3df(v0,v1,v2).isFrontFacing(light);
|
||||
#else
|
||||
FaceData[i]=core::triangle3df(v2,v1,v0).isFrontFacing(light);
|
||||
#endif
|
||||
|
||||
if (UseZFailMethod && FaceData[i])
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
if (svp->size() >= svp->allocated_size()-5)
|
||||
os::Printer::log("Allocation too small.", ELL_DEBUG);
|
||||
#endif
|
||||
// add front cap from light-facing faces
|
||||
svp->push_back(v2);
|
||||
svp->push_back(v1);
|
||||
svp->push_back(v0);
|
||||
|
||||
// add back cap
|
||||
const core::vector3df i0 = v0+(v0-light).normalize()*Infinity;
|
||||
const core::vector3df i1 = v1+(v1-light).normalize()*Infinity;
|
||||
const core::vector3df i2 = v2+(v2-light).normalize()*Infinity;
|
||||
|
||||
svp->push_back(i0);
|
||||
svp->push_back(i1);
|
||||
svp->push_back(i2);
|
||||
|
||||
bb->addInternalPoint(i0);
|
||||
bb->addInternalPoint(i1);
|
||||
bb->addInternalPoint(i2);
|
||||
}
|
||||
}
|
||||
|
||||
// Create edges
|
||||
for (u32 i=0; i<faceCount; ++i)
|
||||
{
|
||||
// check all front facing faces
|
||||
if (FaceData[i] == true)
|
||||
{
|
||||
const u16 wFace0 = Indices[3*i+0];
|
||||
const u16 wFace1 = Indices[3*i+1];
|
||||
const u16 wFace2 = Indices[3*i+2];
|
||||
|
||||
const u16 adj0 = Adjacency[3*i+0];
|
||||
const u16 adj1 = Adjacency[3*i+1];
|
||||
const u16 adj2 = Adjacency[3*i+2];
|
||||
|
||||
// add edges if face is adjacent to back-facing face
|
||||
// or if no adjacent face was found
|
||||
#ifdef IRR_USE_ADJACENCY
|
||||
if (adj0 == i || FaceData[adj0] == false)
|
||||
#endif
|
||||
{
|
||||
// add edge v0-v1
|
||||
Edges[2*numEdges+0] = wFace0;
|
||||
Edges[2*numEdges+1] = wFace1;
|
||||
++numEdges;
|
||||
}
|
||||
|
||||
#ifdef IRR_USE_ADJACENCY
|
||||
if (adj1 == i || FaceData[adj1] == false)
|
||||
#endif
|
||||
{
|
||||
// add edge v1-v2
|
||||
Edges[2*numEdges+0] = wFace1;
|
||||
Edges[2*numEdges+1] = wFace2;
|
||||
++numEdges;
|
||||
}
|
||||
|
||||
#ifdef IRR_USE_ADJACENCY
|
||||
if (adj2 == i || FaceData[adj2] == false)
|
||||
#endif
|
||||
{
|
||||
// add edge v2-v0
|
||||
Edges[2*numEdges+0] = wFace2;
|
||||
Edges[2*numEdges+1] = wFace0;
|
||||
++numEdges;
|
||||
}
|
||||
}
|
||||
}
|
||||
return numEdges;
|
||||
}
|
||||
|
||||
|
||||
void CShadowVolumeSceneNode::setShadowMesh(const IMesh* mesh)
|
||||
{
|
||||
if (ShadowMesh == mesh)
|
||||
return;
|
||||
if (ShadowMesh)
|
||||
ShadowMesh->drop();
|
||||
ShadowMesh = mesh;
|
||||
if (ShadowMesh)
|
||||
{
|
||||
ShadowMesh->grab();
|
||||
Box = ShadowMesh->getBoundingBox();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CShadowVolumeSceneNode::updateShadowVolumes()
|
||||
{
|
||||
const u32 oldIndexCount = IndexCount;
|
||||
const u32 oldVertexCount = VertexCount;
|
||||
|
||||
const IMesh* const mesh = ShadowMesh;
|
||||
if (!mesh)
|
||||
return;
|
||||
|
||||
// create as much shadow volumes as there are lights but
|
||||
// do not ignore the max light settings.
|
||||
const u32 lightCount = SceneManager->getVideoDriver()->getDynamicLightCount();
|
||||
if (!lightCount)
|
||||
return;
|
||||
|
||||
// calculate total amount of vertices and indices
|
||||
|
||||
VertexCount = 0;
|
||||
IndexCount = 0;
|
||||
ShadowVolumesUsed = 0;
|
||||
|
||||
u32 i;
|
||||
u32 totalVertices = 0;
|
||||
u32 totalIndices = 0;
|
||||
const u32 bufcnt = mesh->getMeshBufferCount();
|
||||
|
||||
for (i=0; i<bufcnt; ++i)
|
||||
{
|
||||
const IMeshBuffer* buf = mesh->getMeshBuffer(i);
|
||||
totalIndices += buf->getIndexCount();
|
||||
totalVertices += buf->getVertexCount();
|
||||
}
|
||||
|
||||
// allocate memory if necessary
|
||||
|
||||
Vertices.set_used(totalVertices);
|
||||
Indices.set_used(totalIndices);
|
||||
FaceData.set_used(totalIndices / 3);
|
||||
|
||||
// copy mesh
|
||||
for (i=0; i<bufcnt; ++i)
|
||||
{
|
||||
const IMeshBuffer* buf = mesh->getMeshBuffer(i);
|
||||
|
||||
const u16* idxp = buf->getIndices();
|
||||
const u16* idxpend = idxp + buf->getIndexCount();
|
||||
for (; idxp!=idxpend; ++idxp)
|
||||
Indices[IndexCount++] = *idxp + VertexCount;
|
||||
|
||||
const u32 vtxcnt = buf->getVertexCount();
|
||||
for (u32 j=0; j<vtxcnt; ++j)
|
||||
Vertices[VertexCount++] = buf->getPosition(j);
|
||||
}
|
||||
|
||||
// recalculate adjacency if necessary
|
||||
if (oldVertexCount != VertexCount || oldIndexCount != IndexCount)
|
||||
calculateAdjacency();
|
||||
|
||||
core::matrix4 mat = Parent->getAbsoluteTransformation();
|
||||
mat.makeInverse();
|
||||
const core::vector3df parentpos = Parent->getAbsolutePosition();
|
||||
|
||||
// TODO: Only correct for point lights.
|
||||
for (i=0; i<lightCount; ++i)
|
||||
{
|
||||
const video::SLight& dl = SceneManager->getVideoDriver()->getDynamicLight(i);
|
||||
core::vector3df lpos = dl.Position;
|
||||
if (dl.CastShadows &&
|
||||
fabs((lpos - parentpos).getLengthSQ()) <= (dl.Radius*dl.Radius*4.0f))
|
||||
{
|
||||
mat.transformVect(lpos);
|
||||
createShadowVolume(lpos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//! pre render method
|
||||
void CShadowVolumeSceneNode::OnRegisterSceneNode()
|
||||
{
|
||||
if (IsVisible)
|
||||
{
|
||||
SceneManager->registerNodeForRendering(this, scene::ESNRP_SHADOW);
|
||||
ISceneNode::OnRegisterSceneNode();
|
||||
}
|
||||
}
|
||||
|
||||
//! renders the node.
|
||||
void CShadowVolumeSceneNode::render()
|
||||
{
|
||||
video::IVideoDriver* driver = SceneManager->getVideoDriver();
|
||||
|
||||
if (!ShadowVolumesUsed || !driver)
|
||||
return;
|
||||
|
||||
driver->setTransform(video::ETS_WORLD, Parent->getAbsoluteTransformation());
|
||||
|
||||
for (u32 i=0; i<ShadowVolumesUsed; ++i)
|
||||
{
|
||||
bool drawShadow = true;
|
||||
|
||||
if (UseZFailMethod && SceneManager->getActiveCamera())
|
||||
{
|
||||
// Disable shadows drawing, when back cap is behind of ZFar plane.
|
||||
|
||||
SViewFrustum frust = *SceneManager->getActiveCamera()->getViewFrustum();
|
||||
|
||||
core::matrix4 invTrans(Parent->getAbsoluteTransformation(), core::matrix4::EM4CONST_INVERSE);
|
||||
frust.transform(invTrans);
|
||||
|
||||
core::vector3df edges[8];
|
||||
ShadowBBox[i].getEdges(edges);
|
||||
|
||||
core::vector3df largestEdge = edges[0];
|
||||
f32 maxDistance = core::vector3df(SceneManager->getActiveCamera()->getPosition() - edges[0]).getLength();
|
||||
f32 curDistance = 0.f;
|
||||
|
||||
for(int j = 1; j < 8; ++j)
|
||||
{
|
||||
curDistance = core::vector3df(SceneManager->getActiveCamera()->getPosition() - edges[j]).getLength();
|
||||
|
||||
if(curDistance > maxDistance)
|
||||
{
|
||||
maxDistance = curDistance;
|
||||
largestEdge = edges[j];
|
||||
}
|
||||
}
|
||||
|
||||
if (!(frust.planes[scene::SViewFrustum::VF_FAR_PLANE].classifyPointRelation(largestEdge) != core::ISREL3D_FRONT))
|
||||
drawShadow = false;
|
||||
}
|
||||
|
||||
if(drawShadow)
|
||||
driver->drawStencilShadowVolume(ShadowVolumes[i], UseZFailMethod, DebugDataVisible);
|
||||
else
|
||||
{
|
||||
core::array<core::vector3df> triangles;
|
||||
driver->drawStencilShadowVolume(triangles, UseZFailMethod, DebugDataVisible);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//! returns the axis aligned bounding box of this node
|
||||
const core::aabbox3d<f32>& CShadowVolumeSceneNode::getBoundingBox() const
|
||||
{
|
||||
return Box;
|
||||
}
|
||||
|
||||
|
||||
//! Generates adjacency information based on mesh indices.
|
||||
void CShadowVolumeSceneNode::calculateAdjacency()
|
||||
{
|
||||
Adjacency.set_used(IndexCount);
|
||||
|
||||
// go through all faces and fetch their three neighbours
|
||||
for (u32 f=0; f<IndexCount; f+=3)
|
||||
{
|
||||
for (u32 edge = 0; edge<3; ++edge)
|
||||
{
|
||||
const core::vector3df& v1 = Vertices[Indices[f+edge]];
|
||||
const core::vector3df& v2 = Vertices[Indices[f+((edge+1)%3)]];
|
||||
|
||||
// now we search an_O_ther _F_ace with these two
|
||||
// vertices, which is not the current face.
|
||||
u32 of;
|
||||
|
||||
for (of=0; of<IndexCount; of+=3)
|
||||
{
|
||||
// only other faces
|
||||
if (of != f)
|
||||
{
|
||||
bool cnt1 = false;
|
||||
bool cnt2 = false;
|
||||
|
||||
for (s32 e=0; e<3; ++e)
|
||||
{
|
||||
if (v1.equals(Vertices[Indices[of+e]]))
|
||||
cnt1=true;
|
||||
|
||||
if (v2.equals(Vertices[Indices[of+e]]))
|
||||
cnt2=true;
|
||||
}
|
||||
// one match for each vertex, i.e. edge is the same
|
||||
if (cnt1 && cnt2)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// no adjacent edges -> store face number, else store adjacent face
|
||||
if (of >= IndexCount)
|
||||
Adjacency[f + edge] = f/3;
|
||||
else
|
||||
Adjacency[f + edge] = of/3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} // end namespace scene
|
||||
} // end namespace irr
|
@ -1,87 +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
|
||||
|
||||
#ifndef __C_SHADOW_VOLUME_SCENE_NODE_H_INCLUDED__
|
||||
#define __C_SHADOW_VOLUME_SCENE_NODE_H_INCLUDED__
|
||||
|
||||
#include "IShadowVolumeSceneNode.h"
|
||||
|
||||
namespace irr
|
||||
{
|
||||
namespace scene
|
||||
{
|
||||
|
||||
//! Scene node for rendering a shadow volume into a stencil buffer.
|
||||
class CShadowVolumeSceneNode : public IShadowVolumeSceneNode
|
||||
{
|
||||
public:
|
||||
|
||||
//! constructor
|
||||
CShadowVolumeSceneNode(const IMesh* shadowMesh, ISceneNode* parent, ISceneManager* mgr,
|
||||
s32 id, bool zfailmethod=true, f32 infinity=10000.0f);
|
||||
|
||||
//! destructor
|
||||
virtual ~CShadowVolumeSceneNode();
|
||||
|
||||
//! Sets the mesh from which the shadow volume should be generated.
|
||||
/** To optimize shadow rendering, use a simpler mesh for shadows.
|
||||
*/
|
||||
virtual void setShadowMesh(const IMesh* mesh);
|
||||
|
||||
//! Updates the shadow volumes for current light positions.
|
||||
/** Called each render cycle from Animated Mesh SceneNode render method. */
|
||||
virtual void updateShadowVolumes();
|
||||
|
||||
//! pre render method
|
||||
virtual void OnRegisterSceneNode();
|
||||
|
||||
//! renders the node.
|
||||
virtual void render();
|
||||
|
||||
//! returns the axis aligned bounding box of this node
|
||||
virtual const core::aabbox3d<f32>& getBoundingBox() const;
|
||||
|
||||
//! Returns type of the scene node
|
||||
virtual ESCENE_NODE_TYPE getType() const { return ESNT_SHADOW_VOLUME; }
|
||||
|
||||
private:
|
||||
|
||||
typedef core::array<core::vector3df> SShadowVolume;
|
||||
|
||||
void createShadowVolume(const core::vector3df& pos, bool isDirectional=false);
|
||||
u32 createEdgesAndCaps(const core::vector3df& light, SShadowVolume* svp, core::aabbox3d<f32>* bb);
|
||||
|
||||
//! Generates adjacency information based on mesh indices.
|
||||
void calculateAdjacency();
|
||||
|
||||
core::aabbox3d<f32> Box;
|
||||
|
||||
// a shadow volume for every light
|
||||
core::array<SShadowVolume> ShadowVolumes;
|
||||
|
||||
// a back cap bounding box for every light
|
||||
core::array<core::aabbox3d<f32> > ShadowBBox;
|
||||
|
||||
core::array<core::vector3df> Vertices;
|
||||
core::array<u16> Indices;
|
||||
core::array<u16> Adjacency;
|
||||
core::array<u16> Edges;
|
||||
// tells if face is front facing
|
||||
core::array<bool> FaceData;
|
||||
|
||||
const scene::IMesh* ShadowMesh;
|
||||
|
||||
u32 IndexCount;
|
||||
u32 VertexCount;
|
||||
u32 ShadowVolumesUsed;
|
||||
|
||||
f32 Infinity;
|
||||
|
||||
bool UseZFailMethod;
|
||||
};
|
||||
|
||||
} // end namespace scene
|
||||
} // end namespace irr
|
||||
|
||||
#endif
|
@ -7,7 +7,6 @@
|
||||
#include "ISceneManager.h"
|
||||
#include "S3DVertex.h"
|
||||
#include "os.h"
|
||||
#include "CShadowVolumeSceneNode.h"
|
||||
|
||||
namespace irr
|
||||
{
|
||||
@ -17,7 +16,7 @@ namespace scene
|
||||
//! constructor
|
||||
CSphereSceneNode::CSphereSceneNode(f32 radius, u32 polyCountX, u32 polyCountY, ISceneNode* parent, ISceneManager* mgr, s32 id,
|
||||
const core::vector3df& position, const core::vector3df& rotation, const core::vector3df& scale)
|
||||
: IMeshSceneNode(parent, mgr, id, position, rotation, scale), Mesh(0), Shadow(0),
|
||||
: IMeshSceneNode(parent, mgr, id, position, rotation, scale), Mesh(0),
|
||||
Radius(radius), PolyCountX(polyCountX), PolyCountY(polyCountY)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
@ -32,8 +31,6 @@ CSphereSceneNode::CSphereSceneNode(f32 radius, u32 polyCountX, u32 polyCountY, I
|
||||
//! destructor
|
||||
CSphereSceneNode::~CSphereSceneNode()
|
||||
{
|
||||
if (Shadow)
|
||||
Shadow->drop();
|
||||
if (Mesh)
|
||||
Mesh->drop();
|
||||
}
|
||||
@ -48,8 +45,6 @@ void CSphereSceneNode::render()
|
||||
{
|
||||
driver->setMaterial(Mesh->getMeshBuffer(0)->getMaterial());
|
||||
driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
|
||||
if (Shadow)
|
||||
Shadow->updateShadowVolumes();
|
||||
|
||||
driver->drawMeshBuffer(Mesh->getMeshBuffer(0));
|
||||
if ( DebugDataVisible & scene::EDS_BBOX )
|
||||
@ -68,35 +63,10 @@ void CSphereSceneNode::render()
|
||||
//! or to remove attached childs.
|
||||
bool CSphereSceneNode::removeChild(ISceneNode* child)
|
||||
{
|
||||
if (child && Shadow == child)
|
||||
{
|
||||
Shadow->drop();
|
||||
Shadow = 0;
|
||||
}
|
||||
|
||||
return ISceneNode::removeChild(child);
|
||||
}
|
||||
|
||||
|
||||
//! Creates shadow volume scene node as child of this node
|
||||
//! and returns a pointer to it.
|
||||
IShadowVolumeSceneNode* CSphereSceneNode::addShadowVolumeSceneNode(
|
||||
const IMesh* shadowMesh, s32 id, bool zfailmethod, f32 infinity)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
//! returns the axis aligned bounding box of this node
|
||||
const core::aabbox3d<f32>& CSphereSceneNode::getBoundingBox() const
|
||||
{
|
||||
@ -185,8 +155,6 @@ ISceneNode* CSphereSceneNode::clone(ISceneNode* newParent, ISceneManager* newMan
|
||||
|
||||
nb->cloneMembers(this, newManager);
|
||||
nb->getMaterial(0) = Mesh->getMeshBuffer(0)->getMaterial();
|
||||
nb->Shadow = Shadow;
|
||||
nb->Shadow->grab();
|
||||
|
||||
if ( newParent )
|
||||
nb->drop();
|
||||
|
@ -69,11 +69,6 @@ namespace scene
|
||||
//! Returns if the scene node should not copy the materials of the mesh but use them in a read only style
|
||||
virtual bool isReadOnlyMaterials() const { return false; }
|
||||
|
||||
//! Creates shadow volume scene node as child of this node
|
||||
//! and returns a pointer to it.
|
||||
virtual IShadowVolumeSceneNode* addShadowVolumeSceneNode(const IMesh* shadowMesh,
|
||||
s32 id, bool zfailmethod=true, f32 infinity=10000.0f);
|
||||
|
||||
//! 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.
|
||||
@ -82,7 +77,6 @@ namespace scene
|
||||
private:
|
||||
|
||||
IMesh* Mesh;
|
||||
IShadowVolumeSceneNode* Shadow;
|
||||
core::aabbox3d<f32> Box;
|
||||
f32 Radius;
|
||||
u32 PolyCountX;
|
||||
|
@ -55,8 +55,6 @@ public:
|
||||
virtual scene::IMesh *getMesh() OVERRIDE { return m_mesh; }
|
||||
virtual void setReadOnlyMaterials(bool) OVERRIDE {}
|
||||
virtual bool isReadOnlyMaterials() const OVERRIDE { return false; }
|
||||
virtual scene::IShadowVolumeSceneNode* addShadowVolumeSceneNode
|
||||
(const scene::IMesh*, int, bool, f32) OVERRIDE { return NULL; }
|
||||
|
||||
protected:
|
||||
video::SMaterial m_mat;
|
||||
|
Loading…
x
Reference in New Issue
Block a user