1 // Copyright (C) 2007-2012 Dean Wadsworth
2 // This file is part of the "Irrlicht Engine".
3 // For conditions of distribution and use, see copyright notice in irrlicht.h
4 
5 #include "CVolumeLightSceneNode.h"
6 #include "IVideoDriver.h"
7 #include "ISceneManager.h"
8 #include "S3DVertex.h"
9 #include "os.h"
10 
11 namespace irr
12 {
13 namespace scene
14 {
15 
16 //! constructor
CVolumeLightSceneNode(ISceneNode * parent,ISceneManager * mgr,s32 id,const u32 subdivU,const u32 subdivV,const video::SColor foot,const video::SColor tail,const core::vector3df & position,const core::vector3df & rotation,const core::vector3df & scale)17 CVolumeLightSceneNode::CVolumeLightSceneNode(ISceneNode* parent, ISceneManager* mgr,
18 		s32 id, const u32 subdivU, const u32 subdivV,
19 		const video::SColor foot,
20 		const video::SColor tail,
21 		const core::vector3df& position,
22 		const core::vector3df& rotation, const core::vector3df& scale)
23 	: IVolumeLightSceneNode(parent, mgr, id, position, rotation, scale),
24 		Mesh(0), LPDistance(8.0f),
25 		SubdivideU(subdivU), SubdivideV(subdivV),
26 		FootColor(foot), TailColor(tail),
27 		LightDimensions(core::vector3df(1.0f, 1.2f, 1.0f))
28 {
29 	#ifdef _DEBUG
30 	setDebugName("CVolumeLightSceneNode");
31 	#endif
32 
33 	constructLight();
34 }
35 
36 
~CVolumeLightSceneNode()37 CVolumeLightSceneNode::~CVolumeLightSceneNode()
38 {
39 	if (Mesh)
40 		Mesh->drop();
41 }
42 
43 
constructLight()44 void CVolumeLightSceneNode::constructLight()
45 {
46 	if (Mesh)
47 		Mesh->drop();
48 	Mesh = SceneManager->getGeometryCreator()->createVolumeLightMesh(SubdivideU, SubdivideV, FootColor, TailColor, LPDistance, LightDimensions);
49 }
50 
51 
52 //! renders the node.
render()53 void CVolumeLightSceneNode::render()
54 {
55 	if (!Mesh)
56 		return;
57 
58 	video::IVideoDriver* driver = SceneManager->getVideoDriver();
59 	driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
60 
61 	driver->setMaterial(Mesh->getMeshBuffer(0)->getMaterial());
62 	driver->drawMeshBuffer(Mesh->getMeshBuffer(0));
63 }
64 
65 
66 //! returns the axis aligned bounding box of this node
getBoundingBox() const67 const core::aabbox3d<f32>& CVolumeLightSceneNode::getBoundingBox() const
68 {
69 	return Mesh->getBoundingBox();
70 }
71 
72 
OnRegisterSceneNode()73 void CVolumeLightSceneNode::OnRegisterSceneNode()
74 {
75 	if (IsVisible)
76 	{
77 		SceneManager->registerNodeForRendering(this, ESNRP_TRANSPARENT);
78 	}
79 	ISceneNode::OnRegisterSceneNode();
80 }
81 
82 
83 //! returns the material based on the zero based index i. To get the amount
84 //! of materials used by this scene node, use getMaterialCount().
85 //! This function is needed for inserting the node into the scene hirachy on a
86 //! optimal position for minimizing renderstate changes, but can also be used
87 //! to directly modify the material of a scene node.
getMaterial(u32 i)88 video::SMaterial& CVolumeLightSceneNode::getMaterial(u32 i)
89 {
90 	return Mesh->getMeshBuffer(i)->getMaterial();
91 }
92 
93 
94 //! returns amount of materials used by this scene node.
getMaterialCount() const95 u32 CVolumeLightSceneNode::getMaterialCount() const
96 {
97 	return 1;
98 }
99 
100 
setSubDivideU(const u32 inU)101 void CVolumeLightSceneNode::setSubDivideU (const u32 inU)
102 {
103 	if (inU != SubdivideU)
104 	{
105 		SubdivideU = inU;
106 		constructLight();
107 	}
108 }
109 
110 
setSubDivideV(const u32 inV)111 void CVolumeLightSceneNode::setSubDivideV (const u32 inV)
112 {
113 	if (inV != SubdivideV)
114 	{
115 		SubdivideV = inV;
116 		constructLight();
117 	}
118 }
119 
120 
setFootColor(const video::SColor inColor)121 void CVolumeLightSceneNode::setFootColor(const video::SColor inColor)
122 {
123 	if (inColor != FootColor)
124 	{
125 		FootColor = inColor;
126 		constructLight();
127 	}
128 }
129 
130 
setTailColor(const video::SColor inColor)131 void CVolumeLightSceneNode::setTailColor(const video::SColor inColor)
132 {
133 	if (inColor != TailColor)
134 	{
135 		TailColor = inColor;
136 		constructLight();
137 	}
138 }
139 
140 
141 //! Writes attributes of the scene node.
serializeAttributes(io::IAttributes * out,io::SAttributeReadWriteOptions * options) const142 void CVolumeLightSceneNode::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const
143 {
144 	ISceneNode::serializeAttributes(out, options);
145 
146 	out->addFloat("lpDistance", LPDistance);
147 	out->addInt("subDivideU", SubdivideU);
148 	out->addInt("subDivideV", SubdivideV);
149 
150 	out->addColor("footColor", FootColor);
151 	out->addColor("tailColor", TailColor);
152 
153 	out->addVector3d("lightDimension", LightDimensions);
154 }
155 
156 
157 //! Reads attributes of the scene node.
deserializeAttributes(io::IAttributes * in,io::SAttributeReadWriteOptions * options)158 void CVolumeLightSceneNode::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options)
159 {
160 	LPDistance = in->getAttributeAsFloat("lpDistance");
161 	LPDistance = core::max_(LPDistance, 8.0f);
162 
163 	SubdivideU = in->getAttributeAsInt("subDivideU");
164 	SubdivideU = core::max_(SubdivideU, 1u);
165 
166 	SubdivideV = in->getAttributeAsInt("subDivideV");
167 	SubdivideV = core::max_(SubdivideV, 1u);
168 
169 	FootColor = in->getAttributeAsColor("footColor");
170 	TailColor = in->getAttributeAsColor("tailColor");
171 
172 	LightDimensions = in->getAttributeAsVector3d("lightDimension");
173 
174 	constructLight();
175 
176 	ISceneNode::deserializeAttributes(in, options);
177 }
178 
179 
180 //! Creates a clone of this scene node and its children.
clone(ISceneNode * newParent,ISceneManager * newManager)181 ISceneNode* CVolumeLightSceneNode::clone(ISceneNode* newParent, ISceneManager* newManager)
182 {
183 	if (!newParent)
184 		newParent = Parent;
185 	if (!newManager)
186 		newManager = SceneManager;
187 
188 	CVolumeLightSceneNode* nb = new CVolumeLightSceneNode(newParent,
189 		newManager, ID, SubdivideU, SubdivideV, FootColor, TailColor, RelativeTranslation);
190 
191 	nb->cloneMembers(this, newManager);
192 	nb->getMaterial(0) = Mesh->getMeshBuffer(0)->getMaterial();
193 
194 	if ( newParent )
195 		nb->drop();
196 	return nb;
197 }
198 
199 
200 } // end namespace scene
201 } // end namespace irr
202 
203