From 7028cbe09c688437910a25623098762bf0fa592d Mon Sep 17 00:00:00 2001 From: David Walter Seikel Date: Mon, 28 Mar 2016 22:28:34 +1000 Subject: Move Irrlicht to src/others. --- .../source/Irrlicht/CSkyBoxSceneNode.cpp | 263 +++++++++++++++++++++ 1 file changed, 263 insertions(+) create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CSkyBoxSceneNode.cpp (limited to 'src/others/irrlicht-1.8.1/source/Irrlicht/CSkyBoxSceneNode.cpp') diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CSkyBoxSceneNode.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CSkyBoxSceneNode.cpp new file mode 100644 index 0000000..756fab9 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CSkyBoxSceneNode.cpp @@ -0,0 +1,263 @@ +// 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 "CSkyBoxSceneNode.h" +#include "IVideoDriver.h" +#include "ISceneManager.h" +#include "ICameraSceneNode.h" +#include "S3DVertex.h" +#include "os.h" + +namespace irr +{ +namespace scene +{ + +//! constructor +CSkyBoxSceneNode::CSkyBoxSceneNode(video::ITexture* top, video::ITexture* bottom, video::ITexture* left, + video::ITexture* right, video::ITexture* front, video::ITexture* back, ISceneNode* parent, ISceneManager* mgr, s32 id) +: ISceneNode(parent, mgr, id) +{ + #ifdef _DEBUG + setDebugName("CSkyBoxSceneNode"); + #endif + + setAutomaticCulling(scene::EAC_OFF); + Box.MaxEdge.set(0,0,0); + Box.MinEdge.set(0,0,0); + + // create indices + + Indices[0] = 0; + Indices[1] = 1; + Indices[2] = 2; + Indices[3] = 3; + + // create material + + video::SMaterial mat; + mat.Lighting = false; + mat.ZBuffer = video::ECFN_NEVER; + mat.ZWriteEnable = false; + mat.AntiAliasing=0; + mat.TextureLayer[0].TextureWrapU = video::ETC_CLAMP_TO_EDGE; + mat.TextureLayer[0].TextureWrapV = video::ETC_CLAMP_TO_EDGE; + + /* Hey, I am no artist, but look at that + cool ASCII art I made! ;) + + -111 111 + /6--------/5 y + / | / | ^ z + / | 11-1 | | / + -11-1 3---------2 | |/ + | 7- - -| -4 1-11 *---->x + | -1-11 | / 3-------|2 + |/ | / | //| + 0---------1/ | // | + -1-1-1 1-1-1 |// | + 0--------1 + */ + + video::ITexture* tex = front; + if (!tex) tex = left; + if (!tex) tex = back; + if (!tex) tex = right; + if (!tex) tex = top; + if (!tex) tex = bottom; + + const f32 onepixel = tex?(1.0f / (tex->getSize().Width * 1.5f)) : 0.0f; + const f32 t = 1.0f - onepixel; + const f32 o = 0.0f + onepixel; + + // create front side + + Material[0] = mat; + Material[0].setTexture(0, front); + Vertices[0] = video::S3DVertex(-1,-1,-1, 0,0,1, video::SColor(255,255,255,255), t, t); + Vertices[1] = video::S3DVertex( 1,-1,-1, 0,0,1, video::SColor(255,255,255,255), o, t); + Vertices[2] = video::S3DVertex( 1, 1,-1, 0,0,1, video::SColor(255,255,255,255), o, o); + Vertices[3] = video::S3DVertex(-1, 1,-1, 0,0,1, video::SColor(255,255,255,255), t, o); + + // create left side + + Material[1] = mat; + Material[1].setTexture(0, left); + Vertices[4] = video::S3DVertex( 1,-1,-1, -1,0,0, video::SColor(255,255,255,255), t, t); + Vertices[5] = video::S3DVertex( 1,-1, 1, -1,0,0, video::SColor(255,255,255,255), o, t); + Vertices[6] = video::S3DVertex( 1, 1, 1, -1,0,0, video::SColor(255,255,255,255), o, o); + Vertices[7] = video::S3DVertex( 1, 1,-1, -1,0,0, video::SColor(255,255,255,255), t, o); + + // create back side + + Material[2] = mat; + Material[2].setTexture(0, back); + Vertices[8] = video::S3DVertex( 1,-1, 1, 0,0,-1, video::SColor(255,255,255,255), t, t); + Vertices[9] = video::S3DVertex(-1,-1, 1, 0,0,-1, video::SColor(255,255,255,255), o, t); + Vertices[10] = video::S3DVertex(-1, 1, 1, 0,0,-1, video::SColor(255,255,255,255), o, o); + Vertices[11] = video::S3DVertex( 1, 1, 1, 0,0,-1, video::SColor(255,255,255,255), t, o); + + // create right side + + Material[3] = mat; + Material[3].setTexture(0, right); + Vertices[12] = video::S3DVertex(-1,-1, 1, 1,0,0, video::SColor(255,255,255,255), t, t); + Vertices[13] = video::S3DVertex(-1,-1,-1, 1,0,0, video::SColor(255,255,255,255), o, t); + Vertices[14] = video::S3DVertex(-1, 1,-1, 1,0,0, video::SColor(255,255,255,255), o, o); + Vertices[15] = video::S3DVertex(-1, 1, 1, 1,0,0, video::SColor(255,255,255,255), t, o); + + // create top side + + Material[4] = mat; + Material[4].setTexture(0, top); + Vertices[16] = video::S3DVertex( 1, 1,-1, 0,-1,0, video::SColor(255,255,255,255), t, t); + Vertices[17] = video::S3DVertex( 1, 1, 1, 0,-1,0, video::SColor(255,255,255,255), o, t); + Vertices[18] = video::S3DVertex(-1, 1, 1, 0,-1,0, video::SColor(255,255,255,255), o, o); + Vertices[19] = video::S3DVertex(-1, 1,-1, 0,-1,0, video::SColor(255,255,255,255), t, o); + + // create bottom side + + Material[5] = mat; + Material[5].setTexture(0, bottom); + Vertices[20] = video::S3DVertex( 1,-1, 1, 0,1,0, video::SColor(255,255,255,255), o, o); + Vertices[21] = video::S3DVertex( 1,-1,-1, 0,1,0, video::SColor(255,255,255,255), t, o); + Vertices[22] = video::S3DVertex(-1,-1,-1, 0,1,0, video::SColor(255,255,255,255), t, t); + Vertices[23] = video::S3DVertex(-1,-1, 1, 0,1,0, video::SColor(255,255,255,255), o, t); +} + + +//! renders the node. +void CSkyBoxSceneNode::render() +{ + video::IVideoDriver* driver = SceneManager->getVideoDriver(); + scene::ICameraSceneNode* camera = SceneManager->getActiveCamera(); + + if (!camera || !driver) + return; + + if ( !camera->isOrthogonal() ) + { + // draw perspective skybox + + core::matrix4 translate(AbsoluteTransformation); + translate.setTranslation(camera->getAbsolutePosition()); + + // Draw the sky box between the near and far clip plane + const f32 viewDistance = (camera->getNearValue() + camera->getFarValue()) * 0.5f; + core::matrix4 scale; + scale.setScale(core::vector3df(viewDistance, viewDistance, viewDistance)); + + driver->setTransform(video::ETS_WORLD, translate * scale); + + for (s32 i=0; i<6; ++i) + { + driver->setMaterial(Material[i]); + driver->drawIndexedTriangleFan(&Vertices[i*4], 4, Indices, 2); + } + } + else + { + // draw orthogonal skybox, + // simply choose one texture and draw it as 2d picture. + // there could be better ways to do this, but currently I think this is ok. + + core::vector3df lookVect = camera->getTarget() - camera->getAbsolutePosition(); + lookVect.normalize(); + core::vector3df absVect( core::abs_(lookVect.X), + core::abs_(lookVect.Y), + core::abs_(lookVect.Z)); + + int idx = 0; + + if ( absVect.X >= absVect.Y && absVect.X >= absVect.Z ) + { + // x direction + idx = lookVect.X > 0 ? 0 : 2; + } + else + if ( absVect.Y >= absVect.X && absVect.Y >= absVect.Z ) + { + // y direction + idx = lookVect.Y > 0 ? 4 : 5; + } + else + if ( absVect.Z >= absVect.X && absVect.Z >= absVect.Y ) + { + // z direction + idx = lookVect.Z > 0 ? 1 : 3; + } + + video::ITexture* tex = Material[idx].getTexture(0); + + if ( tex ) + { + core::rect rctDest(core::position2d(-1,0), + core::dimension2di(driver->getCurrentRenderTargetSize())); + core::rect rctSrc(core::position2d(0,0), + core::dimension2di(tex->getSize())); + + driver->draw2DImage(tex, rctDest, rctSrc); + } + } +} + + + +//! returns the axis aligned bounding box of this node +const core::aabbox3d& CSkyBoxSceneNode::getBoundingBox() const +{ + return Box; +} + + +void CSkyBoxSceneNode::OnRegisterSceneNode() +{ + if (IsVisible) + SceneManager->registerNodeForRendering(this, ESNRP_SKY_BOX); + + ISceneNode::OnRegisterSceneNode(); +} + + +//! returns the material based on the zero based index i. To get the amount +//! of materials used by this scene node, use getMaterialCount(). +//! This function is needed for inserting the node into the scene hirachy on a +//! optimal position for minimizing renderstate changes, but can also be used +//! to directly modify the material of a scene node. +video::SMaterial& CSkyBoxSceneNode::getMaterial(u32 i) +{ + return Material[i]; +} + + +//! returns amount of materials used by this scene node. +u32 CSkyBoxSceneNode::getMaterialCount() const +{ + return 6; +} + + +//! Creates a clone of this scene node and its children. +ISceneNode* CSkyBoxSceneNode::clone(ISceneNode* newParent, ISceneManager* newManager) +{ + if (!newParent) newParent = Parent; + if (!newManager) newManager = SceneManager; + + CSkyBoxSceneNode* nb = new CSkyBoxSceneNode(0,0,0,0,0,0, newParent, + newManager, ID); + + nb->cloneMembers(this, newManager); + + for (u32 i=0; i<6; ++i) + nb->Material[i] = Material[i]; + + if ( newParent ) + nb->drop(); + return nb; +} + + +} // end namespace scene +} // end namespace irr + -- cgit v1.1