diff options
Diffstat (limited to '')
-rw-r--r-- | libraries/irrlicht-1.8.1/source/Irrlicht/CBillboardSceneNode.cpp | 294 |
1 files changed, 294 insertions, 0 deletions
diff --git a/libraries/irrlicht-1.8.1/source/Irrlicht/CBillboardSceneNode.cpp b/libraries/irrlicht-1.8.1/source/Irrlicht/CBillboardSceneNode.cpp new file mode 100644 index 0000000..22d41bd --- /dev/null +++ b/libraries/irrlicht-1.8.1/source/Irrlicht/CBillboardSceneNode.cpp | |||
@@ -0,0 +1,294 @@ | |||
1 | // Copyright (C) 2002-2012 Nikolaus Gebhardt | ||
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 "CBillboardSceneNode.h" | ||
6 | #include "IVideoDriver.h" | ||
7 | #include "ISceneManager.h" | ||
8 | #include "ICameraSceneNode.h" | ||
9 | #include "os.h" | ||
10 | |||
11 | namespace irr | ||
12 | { | ||
13 | namespace scene | ||
14 | { | ||
15 | |||
16 | //! constructor | ||
17 | CBillboardSceneNode::CBillboardSceneNode(ISceneNode* parent, ISceneManager* mgr, s32 id, | ||
18 | const core::vector3df& position, const core::dimension2d<f32>& size, | ||
19 | video::SColor colorTop, video::SColor colorBottom) | ||
20 | : IBillboardSceneNode(parent, mgr, id, position) | ||
21 | { | ||
22 | #ifdef _DEBUG | ||
23 | setDebugName("CBillboardSceneNode"); | ||
24 | #endif | ||
25 | |||
26 | setSize(size); | ||
27 | |||
28 | indices[0] = 0; | ||
29 | indices[1] = 2; | ||
30 | indices[2] = 1; | ||
31 | indices[3] = 0; | ||
32 | indices[4] = 3; | ||
33 | indices[5] = 2; | ||
34 | |||
35 | vertices[0].TCoords.set(1.0f, 1.0f); | ||
36 | vertices[0].Color = colorBottom; | ||
37 | |||
38 | vertices[1].TCoords.set(1.0f, 0.0f); | ||
39 | vertices[1].Color = colorTop; | ||
40 | |||
41 | vertices[2].TCoords.set(0.0f, 0.0f); | ||
42 | vertices[2].Color = colorTop; | ||
43 | |||
44 | vertices[3].TCoords.set(0.0f, 1.0f); | ||
45 | vertices[3].Color = colorBottom; | ||
46 | } | ||
47 | |||
48 | |||
49 | //! pre render event | ||
50 | void CBillboardSceneNode::OnRegisterSceneNode() | ||
51 | { | ||
52 | if (IsVisible) | ||
53 | SceneManager->registerNodeForRendering(this); | ||
54 | |||
55 | ISceneNode::OnRegisterSceneNode(); | ||
56 | } | ||
57 | |||
58 | |||
59 | //! render | ||
60 | void CBillboardSceneNode::render() | ||
61 | { | ||
62 | video::IVideoDriver* driver = SceneManager->getVideoDriver(); | ||
63 | ICameraSceneNode* camera = SceneManager->getActiveCamera(); | ||
64 | |||
65 | if (!camera || !driver) | ||
66 | return; | ||
67 | |||
68 | // make billboard look to camera | ||
69 | |||
70 | core::vector3df pos = getAbsolutePosition(); | ||
71 | |||
72 | core::vector3df campos = camera->getAbsolutePosition(); | ||
73 | core::vector3df target = camera->getTarget(); | ||
74 | core::vector3df up = camera->getUpVector(); | ||
75 | core::vector3df view = target - campos; | ||
76 | view.normalize(); | ||
77 | |||
78 | core::vector3df horizontal = up.crossProduct(view); | ||
79 | if ( horizontal.getLength() == 0 ) | ||
80 | { | ||
81 | horizontal.set(up.Y,up.X,up.Z); | ||
82 | } | ||
83 | horizontal.normalize(); | ||
84 | core::vector3df topHorizontal = horizontal * 0.5f * TopEdgeWidth; | ||
85 | horizontal *= 0.5f * Size.Width; | ||
86 | |||
87 | // pointing down! | ||
88 | core::vector3df vertical = horizontal.crossProduct(view); | ||
89 | vertical.normalize(); | ||
90 | vertical *= 0.5f * Size.Height; | ||
91 | |||
92 | view *= -1.0f; | ||
93 | |||
94 | for (s32 i=0; i<4; ++i) | ||
95 | vertices[i].Normal = view; | ||
96 | |||
97 | /* Vertices are: | ||
98 | 2--1 | ||
99 | |\ | | ||
100 | | \| | ||
101 | 3--0 | ||
102 | */ | ||
103 | vertices[0].Pos = pos + horizontal + vertical; | ||
104 | vertices[1].Pos = pos + topHorizontal - vertical; | ||
105 | vertices[2].Pos = pos - topHorizontal - vertical; | ||
106 | vertices[3].Pos = pos - horizontal + vertical; | ||
107 | |||
108 | // draw | ||
109 | |||
110 | if (DebugDataVisible & scene::EDS_BBOX) | ||
111 | { | ||
112 | driver->setTransform(video::ETS_WORLD, AbsoluteTransformation); | ||
113 | video::SMaterial m; | ||
114 | m.Lighting = false; | ||
115 | driver->setMaterial(m); | ||
116 | driver->draw3DBox(BBox, video::SColor(0,208,195,152)); | ||
117 | } | ||
118 | |||
119 | driver->setTransform(video::ETS_WORLD, core::IdentityMatrix); | ||
120 | |||
121 | driver->setMaterial(Material); | ||
122 | |||
123 | driver->drawIndexedTriangleList(vertices, 4, indices, 2); | ||
124 | } | ||
125 | |||
126 | |||
127 | //! returns the axis aligned bounding box of this node | ||
128 | const core::aabbox3d<f32>& CBillboardSceneNode::getBoundingBox() const | ||
129 | { | ||
130 | return BBox; | ||
131 | } | ||
132 | |||
133 | |||
134 | //! sets the size of the billboard | ||
135 | void CBillboardSceneNode::setSize(const core::dimension2d<f32>& size) | ||
136 | { | ||
137 | Size = size; | ||
138 | |||
139 | if (core::equals(Size.Width, 0.0f)) | ||
140 | Size.Width = 1.0f; | ||
141 | TopEdgeWidth = Size.Width; | ||
142 | |||
143 | if (core::equals(Size.Height, 0.0f)) | ||
144 | Size.Height = 1.0f; | ||
145 | |||
146 | const f32 avg = (Size.Width + Size.Height)/6; | ||
147 | BBox.MinEdge.set(-avg,-avg,-avg); | ||
148 | BBox.MaxEdge.set(avg,avg,avg); | ||
149 | } | ||
150 | |||
151 | |||
152 | void CBillboardSceneNode::setSize(f32 height, f32 bottomEdgeWidth, f32 topEdgeWidth) | ||
153 | { | ||
154 | Size.set(bottomEdgeWidth, height); | ||
155 | TopEdgeWidth = topEdgeWidth; | ||
156 | |||
157 | if (core::equals(Size.Height, 0.0f)) | ||
158 | Size.Height = 1.0f; | ||
159 | |||
160 | if (core::equals(Size.Width, 0.f) && core::equals(TopEdgeWidth, 0.f)) | ||
161 | { | ||
162 | Size.Width = 1.0f; | ||
163 | TopEdgeWidth = 1.0f; | ||
164 | } | ||
165 | |||
166 | const f32 avg = (core::max_(Size.Width,TopEdgeWidth) + Size.Height)/6; | ||
167 | BBox.MinEdge.set(-avg,-avg,-avg); | ||
168 | BBox.MaxEdge.set(avg,avg,avg); | ||
169 | } | ||
170 | |||
171 | |||
172 | video::SMaterial& CBillboardSceneNode::getMaterial(u32 i) | ||
173 | { | ||
174 | return Material; | ||
175 | } | ||
176 | |||
177 | |||
178 | //! returns amount of materials used by this scene node. | ||
179 | u32 CBillboardSceneNode::getMaterialCount() const | ||
180 | { | ||
181 | return 1; | ||
182 | } | ||
183 | |||
184 | |||
185 | //! gets the size of the billboard | ||
186 | const core::dimension2d<f32>& CBillboardSceneNode::getSize() const | ||
187 | { | ||
188 | return Size; | ||
189 | } | ||
190 | |||
191 | |||
192 | //! Gets the widths of the top and bottom edges of the billboard. | ||
193 | void CBillboardSceneNode::getSize(f32& height, f32& bottomEdgeWidth, | ||
194 | f32& topEdgeWidth) const | ||
195 | { | ||
196 | height = Size.Height; | ||
197 | bottomEdgeWidth = Size.Width; | ||
198 | topEdgeWidth = TopEdgeWidth; | ||
199 | } | ||
200 | |||
201 | |||
202 | //! Writes attributes of the scene node. | ||
203 | void CBillboardSceneNode::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const | ||
204 | { | ||
205 | IBillboardSceneNode::serializeAttributes(out, options); | ||
206 | |||
207 | out->addFloat("Width", Size.Width); | ||
208 | out->addFloat("TopEdgeWidth", TopEdgeWidth); | ||
209 | out->addFloat("Height", Size.Height); | ||
210 | out->addColor("Shade_Top", vertices[1].Color); | ||
211 | out->addColor("Shade_Down", vertices[0].Color); | ||
212 | } | ||
213 | |||
214 | |||
215 | //! Reads attributes of the scene node. | ||
216 | void CBillboardSceneNode::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options) | ||
217 | { | ||
218 | IBillboardSceneNode::deserializeAttributes(in, options); | ||
219 | |||
220 | Size.Width = in->getAttributeAsFloat("Width"); | ||
221 | Size.Height = in->getAttributeAsFloat("Height"); | ||
222 | |||
223 | if (in->existsAttribute("TopEdgeWidth")) | ||
224 | { | ||
225 | TopEdgeWidth = in->getAttributeAsFloat("TopEdgeWidth"); | ||
226 | if (Size.Width != TopEdgeWidth) | ||
227 | setSize(Size.Height, Size.Width, TopEdgeWidth); | ||
228 | } | ||
229 | else | ||
230 | setSize(Size); | ||
231 | vertices[1].Color = in->getAttributeAsColor("Shade_Top"); | ||
232 | vertices[0].Color = in->getAttributeAsColor("Shade_Down"); | ||
233 | vertices[2].Color = vertices[1].Color; | ||
234 | vertices[3].Color = vertices[0].Color; | ||
235 | } | ||
236 | |||
237 | |||
238 | //! Set the color of all vertices of the billboard | ||
239 | //! \param overallColor: the color to set | ||
240 | void CBillboardSceneNode::setColor(const video::SColor& overallColor) | ||
241 | { | ||
242 | for(u32 vertex = 0; vertex < 4; ++vertex) | ||
243 | vertices[vertex].Color = overallColor; | ||
244 | } | ||
245 | |||
246 | |||
247 | //! Set the color of the top and bottom vertices of the billboard | ||
248 | //! \param topColor: the color to set the top vertices | ||
249 | //! \param bottomColor: the color to set the bottom vertices | ||
250 | void CBillboardSceneNode::setColor(const video::SColor& topColor, | ||
251 | const video::SColor& bottomColor) | ||
252 | { | ||
253 | vertices[0].Color = bottomColor; | ||
254 | vertices[1].Color = topColor; | ||
255 | vertices[2].Color = topColor; | ||
256 | vertices[3].Color = bottomColor; | ||
257 | } | ||
258 | |||
259 | |||
260 | //! Gets the color of the top and bottom vertices of the billboard | ||
261 | //! \param[out] topColor: stores the color of the top vertices | ||
262 | //! \param[out] bottomColor: stores the color of the bottom vertices | ||
263 | void CBillboardSceneNode::getColor(video::SColor& topColor, | ||
264 | video::SColor& bottomColor) const | ||
265 | { | ||
266 | bottomColor = vertices[0].Color; | ||
267 | topColor = vertices[1].Color; | ||
268 | } | ||
269 | |||
270 | |||
271 | //! Creates a clone of this scene node and its children. | ||
272 | ISceneNode* CBillboardSceneNode::clone(ISceneNode* newParent, ISceneManager* newManager) | ||
273 | { | ||
274 | if (!newParent) | ||
275 | newParent = Parent; | ||
276 | if (!newManager) | ||
277 | newManager = SceneManager; | ||
278 | |||
279 | CBillboardSceneNode* nb = new CBillboardSceneNode(newParent, | ||
280 | newManager, ID, RelativeTranslation, Size); | ||
281 | |||
282 | nb->cloneMembers(this, newManager); | ||
283 | nb->Material = Material; | ||
284 | nb->TopEdgeWidth = this->TopEdgeWidth; | ||
285 | |||
286 | if ( newParent ) | ||
287 | nb->drop(); | ||
288 | return nb; | ||
289 | } | ||
290 | |||
291 | |||
292 | } // end namespace scene | ||
293 | } // end namespace irr | ||
294 | |||