aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/src/others/irrlicht-1.8.1/source/Irrlicht/CSkyDomeSceneNode.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/others/irrlicht-1.8.1/source/Irrlicht/CSkyDomeSceneNode.cpp')
-rw-r--r--src/others/irrlicht-1.8.1/source/Irrlicht/CSkyDomeSceneNode.cpp264
1 files changed, 264 insertions, 0 deletions
diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CSkyDomeSceneNode.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CSkyDomeSceneNode.cpp
new file mode 100644
index 0000000..0554661
--- /dev/null
+++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CSkyDomeSceneNode.cpp
@@ -0,0 +1,264 @@
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// Code for this scene node has been contributed by Anders la Cour-Harbo (alc)
5
6#include "CSkyDomeSceneNode.h"
7#include "IVideoDriver.h"
8#include "ISceneManager.h"
9#include "ICameraSceneNode.h"
10#include "IAnimatedMesh.h"
11#include "os.h"
12
13namespace irr
14{
15namespace scene
16{
17
18/* horiRes and vertRes:
19 Controls the number of faces along the horizontal axis (30 is a good value)
20 and the number of faces along the vertical axis (8 is a good value).
21
22 texturePercentage:
23 Only the top texturePercentage of the image is used, e.g. 0.8 uses the top 80% of the image,
24 1.0 uses the entire image. This is useful as some landscape images have a small banner
25 at the bottom that you don't want.
26
27 spherePercentage:
28 This controls how far around the sphere the sky dome goes. For value 1.0 you get exactly the upper
29 hemisphere, for 1.1 you get slightly more, and for 2.0 you get a full sphere. It is sometimes useful
30 to use a value slightly bigger than 1 to avoid a gap between some ground place and the sky. This
31 parameters stretches the image to fit the chosen "sphere-size". */
32
33CSkyDomeSceneNode::CSkyDomeSceneNode(video::ITexture* sky, u32 horiRes, u32 vertRes,
34 f32 texturePercentage, f32 spherePercentage, f32 radius,
35 ISceneNode* parent, ISceneManager* mgr, s32 id)
36 : ISceneNode(parent, mgr, id), Buffer(0),
37 HorizontalResolution(horiRes), VerticalResolution(vertRes),
38 TexturePercentage(texturePercentage),
39 SpherePercentage(spherePercentage), Radius(radius)
40{
41 #ifdef _DEBUG
42 setDebugName("CSkyDomeSceneNode");
43 #endif
44
45 setAutomaticCulling(scene::EAC_OFF);
46
47 Buffer = new SMeshBuffer();
48 Buffer->Material.Lighting = false;
49 Buffer->Material.ZBuffer = video::ECFN_NEVER;
50 Buffer->Material.ZWriteEnable = false;
51 Buffer->Material.AntiAliasing = video::EAAM_OFF;
52 Buffer->Material.setTexture(0, sky);
53 Buffer->BoundingBox.MaxEdge.set(0,0,0);
54 Buffer->BoundingBox.MinEdge.set(0,0,0);
55
56 // regenerate the mesh
57 generateMesh();
58}
59
60
61CSkyDomeSceneNode::~CSkyDomeSceneNode()
62{
63 if (Buffer)
64 Buffer->drop();
65}
66
67
68void CSkyDomeSceneNode::generateMesh()
69{
70 f32 azimuth;
71 u32 k;
72
73 Buffer->Vertices.clear();
74 Buffer->Indices.clear();
75
76 const f32 azimuth_step = (core::PI * 2.f) / HorizontalResolution;
77 if (SpherePercentage < 0.f)
78 SpherePercentage = -SpherePercentage;
79 if (SpherePercentage > 2.f)
80 SpherePercentage = 2.f;
81 const f32 elevation_step = SpherePercentage * core::HALF_PI / (f32)VerticalResolution;
82
83 Buffer->Vertices.reallocate( (HorizontalResolution + 1) * (VerticalResolution + 1) );
84 Buffer->Indices.reallocate(3 * (2*VerticalResolution - 1) * HorizontalResolution);
85
86 video::S3DVertex vtx;
87 vtx.Color.set(255,255,255,255);
88 vtx.Normal.set(0.0f,-1.f,0.0f);
89
90 const f32 tcV = TexturePercentage / VerticalResolution;
91 for (k = 0, azimuth = 0; k <= HorizontalResolution; ++k)
92 {
93 f32 elevation = core::HALF_PI;
94 const f32 tcU = (f32)k / (f32)HorizontalResolution;
95 const f32 sinA = sinf(azimuth);
96 const f32 cosA = cosf(azimuth);
97 for (u32 j = 0; j <= VerticalResolution; ++j)
98 {
99 const f32 cosEr = Radius * cosf(elevation);
100 vtx.Pos.set(cosEr*sinA, Radius*sinf(elevation), cosEr*cosA);
101 vtx.TCoords.set(tcU, j*tcV);
102
103 vtx.Normal = -vtx.Pos;
104 vtx.Normal.normalize();
105
106 Buffer->Vertices.push_back(vtx);
107 elevation -= elevation_step;
108 }
109 azimuth += azimuth_step;
110 }
111
112 for (k = 0; k < HorizontalResolution; ++k)
113 {
114 Buffer->Indices.push_back(VerticalResolution + 2 + (VerticalResolution + 1)*k);
115 Buffer->Indices.push_back(1 + (VerticalResolution + 1)*k);
116 Buffer->Indices.push_back(0 + (VerticalResolution + 1)*k);
117
118 for (u32 j = 1; j < VerticalResolution; ++j)
119 {
120 Buffer->Indices.push_back(VerticalResolution + 2 + (VerticalResolution + 1)*k + j);
121 Buffer->Indices.push_back(1 + (VerticalResolution + 1)*k + j);
122 Buffer->Indices.push_back(0 + (VerticalResolution + 1)*k + j);
123
124 Buffer->Indices.push_back(VerticalResolution + 1 + (VerticalResolution + 1)*k + j);
125 Buffer->Indices.push_back(VerticalResolution + 2 + (VerticalResolution + 1)*k + j);
126 Buffer->Indices.push_back(0 + (VerticalResolution + 1)*k + j);
127 }
128 }
129 Buffer->setHardwareMappingHint(scene::EHM_STATIC);
130}
131
132
133//! renders the node.
134void CSkyDomeSceneNode::render()
135{
136 video::IVideoDriver* driver = SceneManager->getVideoDriver();
137 scene::ICameraSceneNode* camera = SceneManager->getActiveCamera();
138
139 if (!camera || !driver)
140 return;
141
142 if ( !camera->isOrthogonal() )
143 {
144 core::matrix4 mat(AbsoluteTransformation);
145 mat.setTranslation(camera->getAbsolutePosition());
146
147 driver->setTransform(video::ETS_WORLD, mat);
148
149 driver->setMaterial(Buffer->Material);
150 driver->drawMeshBuffer(Buffer);
151 }
152
153 // for debug purposes only:
154 if ( DebugDataVisible )
155 {
156 video::SMaterial m;
157 m.Lighting = false;
158 driver->setMaterial(m);
159
160 if ( DebugDataVisible & scene::EDS_NORMALS )
161 {
162 // draw normals
163 const f32 debugNormalLength = SceneManager->getParameters()->getAttributeAsFloat(DEBUG_NORMAL_LENGTH);
164 const video::SColor debugNormalColor = SceneManager->getParameters()->getAttributeAsColor(DEBUG_NORMAL_COLOR);
165 driver->drawMeshBufferNormals(Buffer, debugNormalLength, debugNormalColor);
166 }
167
168 // show mesh
169 if ( DebugDataVisible & scene::EDS_MESH_WIRE_OVERLAY )
170 {
171 m.Wireframe = true;
172 driver->setMaterial(m);
173
174 driver->drawMeshBuffer(Buffer);
175 }
176 }
177}
178
179
180//! returns the axis aligned bounding box of this node
181const core::aabbox3d<f32>& CSkyDomeSceneNode::getBoundingBox() const
182{
183 return Buffer->BoundingBox;
184}
185
186
187void CSkyDomeSceneNode::OnRegisterSceneNode()
188{
189 if (IsVisible)
190 {
191 SceneManager->registerNodeForRendering(this, ESNRP_SKY_BOX );
192 }
193
194 ISceneNode::OnRegisterSceneNode();
195}
196
197
198//! returns the material based on the zero based index i. To get the amount
199//! of materials used by this scene node, use getMaterialCount().
200//! This function is needed for inserting the node into the scene hirachy on a
201//! optimal position for minimizing renderstate changes, but can also be used
202//! to directly modify the material of a scene node.
203video::SMaterial& CSkyDomeSceneNode::getMaterial(u32 i)
204{
205 return Buffer->Material;
206}
207
208
209//! returns amount of materials used by this scene node.
210u32 CSkyDomeSceneNode::getMaterialCount() const
211{
212 return 1;
213}
214
215
216//! Writes attributes of the scene node.
217void CSkyDomeSceneNode::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const
218{
219 ISceneNode::serializeAttributes(out, options);
220
221 out->addInt ("HorizontalResolution", HorizontalResolution);
222 out->addInt ("VerticalResolution", VerticalResolution);
223 out->addFloat("TexturePercentage", TexturePercentage);
224 out->addFloat("SpherePercentage", SpherePercentage);
225 out->addFloat("Radius", Radius);
226}
227
228
229//! Reads attributes of the scene node.
230void CSkyDomeSceneNode::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options)
231{
232 HorizontalResolution = in->getAttributeAsInt ("HorizontalResolution");
233 VerticalResolution = in->getAttributeAsInt ("VerticalResolution");
234 TexturePercentage = in->getAttributeAsFloat("TexturePercentage");
235 SpherePercentage = in->getAttributeAsFloat("SpherePercentage");
236 Radius = in->getAttributeAsFloat("Radius");
237
238 ISceneNode::deserializeAttributes(in, options);
239
240 // regenerate the mesh
241 generateMesh();
242}
243
244//! Creates a clone of this scene node and its children.
245ISceneNode* CSkyDomeSceneNode::clone(ISceneNode* newParent, ISceneManager* newManager)
246{
247 if (!newParent)
248 newParent = Parent;
249 if (!newManager)
250 newManager = SceneManager;
251
252 CSkyDomeSceneNode* nb = new CSkyDomeSceneNode(Buffer->Material.TextureLayer[0].Texture, HorizontalResolution, VerticalResolution, TexturePercentage,
253 SpherePercentage, Radius, newParent, newManager, ID);
254
255 nb->cloneMembers(this, newManager);
256
257 if ( newParent )
258 nb->drop();
259 return nb;
260}
261
262
263} // namespace scene
264} // namespace irr