#include "exterior.hpp" #include #include #include #include #include #include #include "mwscene.hpp" #include #include "mwscene.hpp" #include using namespace MWRender; using namespace Ogre; using namespace ESMS; bool ExteriorCellRender::lightConst = false; float ExteriorCellRender::lightConstValue = 0.0f; bool ExteriorCellRender::lightLinear = true; int ExteriorCellRender::lightLinearMethod = 1; float ExteriorCellRender::lightLinearValue = 3; float ExteriorCellRender::lightLinearRadiusMult = 1; bool ExteriorCellRender::lightQuadratic = false; int ExteriorCellRender::lightQuadraticMethod = 2; float ExteriorCellRender::lightQuadraticValue = 16; float ExteriorCellRender::lightQuadraticRadiusMult = 1; bool ExteriorCellRender::lightOutQuadInLin = false; // start inserting a new reference. void ExteriorCellRender::insertBegin (ESM::CellRef &ref) { assert (!mInsert); // Create and place scene node for this object mInsert = mBase->createChildSceneNode(); const float *f = ref.pos.pos; mInsert->setPosition(f[0], f[1], f[2]); mInsert->setScale(ref.scale, ref.scale, ref.scale); // Convert MW rotation to a quaternion: f = ref.pos.rot; // Rotate around X axis Quaternion xr(Radian(-f[0]), Vector3::UNIT_X); // Rotate around Y axis Quaternion yr(Radian(-f[1]), Vector3::UNIT_Y); // Rotate around Z axis Quaternion zr(Radian(-f[2]), Vector3::UNIT_Z); // Rotates first around z, then y, then x mInsert->setOrientation(xr*yr*zr); mInsertMesh.clear(); } void ExteriorCellRender::rotateMesh(Ogre::Vector3 axis, Ogre::Radian angle, std::string sceneNodeName[], int elements) { assert(mInsert); Ogre::SceneNode *parent = mInsert; //std::cout << "ELEMENTS:" << elements; for (int i = 0; i < elements; i++){ if(sceneNodeName[i] != "" && parent->getChild(sceneNodeName[i])) parent = dynamic_cast (parent->getChild(sceneNodeName[i])); } parent->rotate(axis, angle); } /* void ExteriorCellRender::insertMesh(const std::string &mesh, Ogre::Vector3 vec, Ogre::Vector3 axis, Ogre::Radian angle, std::string sceneNodeName, std::string sceneParent[], int elements){ assert (mInsert); //mInsert-> Ogre::SceneNode *parent = mInsert; for (int i = 0; i < elements; i++){ if(sceneParent[i] != "" && parent->getChild(sceneParent[i])) parent = dynamic_cast (parent->getChild(sceneParent[i])); } mNpcPart = parent->createChildSceneNode(sceneNodeName); NIFLoader::load(mesh); MovableObject *ent = mScene.getMgr()->createEntity(mesh); mNpcPart->translate(vec); mNpcPart->rotate(axis, angle); // mNpcPart->translate(vec); //mNpcPart->rotate(axis, angle); mNpcPart->attachObject(ent); //mNpcPart-> } */ void ExteriorCellRender::insertMesh(const std::string &mesh, Ogre::Vector3 vec, Ogre::Vector3 axis, Ogre::Radian angle, std::string sceneNodeName, std::string sceneParent[], int elements) { insertMesh(mesh, vec, axis, angle, sceneNodeName, sceneParent, elements, true); } void ExteriorCellRender::insertMesh(const std::string &mesh, Ogre::Vector3 vec, Ogre::Vector3 axis, Ogre::Radian angle, std::string sceneNodeName, std::string sceneParent[], int elements, bool translateFirst){ assert (mInsert); //mInsert-> Ogre::SceneNode *parent = mInsert; for (int i = 0; i < elements; i++){ if(sceneParent[i] != "" && parent->getChild(sceneParent[i])) parent = dynamic_cast (parent->getChild(sceneParent[i])); } mNpcPart = parent->createChildSceneNode(sceneNodeName); MeshPtr good2 = NIFLoader::load(mesh); MovableObject *ent = mScene.getMgr()->createEntity(mesh); if(translateFirst){ mNpcPart->translate(vec); mNpcPart->rotate(axis, angle); } else{ mNpcPart->rotate(axis, angle); mNpcPart->translate(vec); } mNpcPart->attachObject(ent); Ogre::MeshManager *m = MeshManager::getSingletonPtr(); const std::string beast1 ="meshes\\b\\B_N_Khajiit_F_Skins.nif"; const std::string beast2 ="meshes\\b\\B_N_Khajiit_M_Skins.nif"; const std::string beast3 ="meshes\\b\\B_N_Argonian_F_Skins.nif"; const std::string beast4 ="meshes\\b\\B_N_Argonian_M_Skins.nif"; const std::string beasttail1 ="tail\\b\\B_N_Khajiit_F_Skins.nif"; const std::string beasttail2 ="tail\\b\\B_N_Khajiit_M_Skins.nif"; const std::string beasttail3 ="tail\\b\\B_N_Argonian_F_Skins.nif"; const std::string beasttail4 ="tail\\b\\B_N_Argonian_M_Skins.nif"; const std::string beastfoot1 ="foot\\b\\B_N_Khajiit_F_Skins.nif"; const std::string beastfoot2 ="foot\\b\\B_N_Khajiit_M_Skins.nif"; const std::string beastfoot3 ="foot\\b\\B_N_Argonian_F_Skins.nif"; const std::string beastfoot4 ="foot\\b\\B_N_Argonian_M_Skins.nif"; if(mesh.compare(beast1) == 0 && m->getByName(beasttail1).isNull()) { //std::cout << "CLONINGKHAJIITF\n"; good2->reload(); MeshPtr tail = good2->clone(beasttail1); good2->reload(); MeshPtr foot = good2->clone(beastfoot1); good2->reload(); } else if(mesh.compare(beast2) == 0 && m->getByName(beasttail2).isNull()) { //std::cout << "CLONINGKHAJIITM\n"; good2->reload(); MeshPtr tail = good2->clone(beasttail2); good2->reload(); MeshPtr foot = good2->clone(beastfoot2); good2->reload(); } else if(mesh.compare(beast3) == 0 && m->getByName(beasttail3).isNull()) { //std::cout << "CLONINGARGONIANF\n"; good2->reload(); MeshPtr tail = good2->clone(beasttail3); good2->reload(); MeshPtr foot = good2->clone(beastfoot3); good2->reload(); } else if(mesh.compare(beast4) == 0 && m->getByName(beasttail4).isNull()) { //std::cout << "CLONINGARGONIANM\n"; good2->reload(); MeshPtr tail = good2->clone(beasttail4); good2->reload(); MeshPtr foot = good2->clone(beastfoot4); good2->reload(); } } // insert a mesh related to the most recent insertBegin call. void ExteriorCellRender::scaleMesh(Ogre::Vector3 axis, std::string sceneNodeName[], int elements) { assert(mInsert); Ogre::SceneNode *parent = mInsert; //std::cout << "ELEMENTS:" << elements; for (int i = 0; i < elements; i++){ if(sceneNodeName[i] != "" && parent->getChild(sceneNodeName[i])) parent = dynamic_cast (parent->getChild(sceneNodeName[i])); } parent->scale(axis); } // insert a mesh related to the most recent insertBegin call. void ExteriorCellRender::insertMesh(const std::string &mesh) { assert (mInsert); NIFLoader::load(mesh); MovableObject *ent = mScene.getMgr()->createEntity(mesh); mInsert->attachObject(ent); if (mInsertMesh.empty()) mInsertMesh = mesh; } void ExteriorCellRender::insertObjectPhysics() { if (!mInsertMesh.empty()) mScene.addObject (mInsert->getName(), mInsertMesh, mInsert->getOrientation(), mInsert->getScale().x, mInsert->getPosition()); } void ExteriorCellRender::insertActorPhysics() { if (!mInsertMesh.empty()) mScene.addActor (mInsert->getName(), mInsertMesh, mInsert->getPosition()); } // insert a light related to the most recent insertBegin call. void ExteriorCellRender::insertLight(float r, float g, float b, float radius) { assert (mInsert); Ogre::Light *light = mScene.getMgr()->createLight(); light->setDiffuseColour (r, g, b); float cval=0.0f, lval=0.0f, qval=0.0f; if(lightConst) cval = lightConstValue; if(!lightOutQuadInLin) { if(lightLinear) radius *= lightLinearRadiusMult; if(lightQuadratic) radius *= lightQuadraticRadiusMult; if(lightLinear) lval = lightLinearValue / pow(radius, lightLinearMethod); if(lightQuadratic) qval = lightQuadraticValue / pow(radius, lightQuadraticMethod); } else { // FIXME: // Do quadratic or linear, depending if we're in an exterior or interior // cell, respectively. Ignore lightLinear and lightQuadratic. } light->setAttenuation(10*radius, cval, lval, qval); mInsert->attachObject(light); } // finish inserting a new reference and return a handle to it. std::string ExteriorCellRender::insertEnd (bool enable) { assert (mInsert); std::string handle = mInsert->getName(); if (!enable) mInsert->setVisible (false); mInsert = 0; return handle; } // configure lighting according to cell void ExteriorCellRender::configureAmbient() { mAmbientColor.setAsABGR (mCell.cell->ambi.ambient); setAmbientMode(); // Create a "sun" that shines light downwards. It doesn't look // completely right, but leave it for now. Ogre::Light *light = mScene.getMgr()->createLight(); Ogre::ColourValue colour; colour.setAsABGR (mCell.cell->ambi.sunlight); light->setDiffuseColour (colour); light->setType(Ogre::Light::LT_DIRECTIONAL); light->setDirection(0,-1,0); } // configure fog according to cell void ExteriorCellRender::configureFog() { Ogre::ColourValue color; color.setAsABGR (mCell.cell->ambi.fog); float high = 4500 + 9000 * (1-mCell.cell->ambi.fogDensity); float low = 200; mScene.getMgr()->setFog (FOG_LINEAR, color, 0, low, high); mScene.getCamera()->setFarClipDistance (high + 10); mScene.getViewport()->setBackgroundColour (color); } void ExteriorCellRender::setAmbientMode() { switch (mAmbientMode) { case 0: mScene.getMgr()->setAmbientLight(mAmbientColor); break; case 1: mScene.getMgr()->setAmbientLight(0.7f*mAmbientColor + 0.3f*ColourValue(1,1,1)); break; case 2: mScene.getMgr()->setAmbientLight(ColourValue(1,1,1)); break; } } void ExteriorCellRender::show() { mBase = mScene.getRoot()->createChildSceneNode(); configureAmbient(); configureFog(); insertCell(mCell, mEnvironment); } void ExteriorCellRender::hide() { if(mBase) mBase->setVisible(false); } void ExteriorCellRender::destroy() { if(mBase) { mBase->removeAndDestroyAllChildren(); mScene.getMgr()->destroySceneNode(mBase); } mBase = NULL; } // Switch through lighting modes. void ExteriorCellRender::toggleLight() { if (mAmbientMode==2) mAmbientMode = 0; else ++mAmbientMode; switch (mAmbientMode) { case 0: std::cout << "Setting lights to normal\n"; break; case 1: std::cout << "Turning the lights up\n"; break; case 2: std::cout << "Turning the lights to full\n"; break; } setAmbientMode(); } void ExteriorCellRender::enable (const std::string& handle) { if (!handle.empty()) mScene.getMgr()->getSceneNode (handle)->setVisible (true); } void ExteriorCellRender::disable (const std::string& handle) { if (!handle.empty()) mScene.getMgr()->getSceneNode (handle)->setVisible (false); } void ExteriorCellRender::deleteObject (const std::string& handle) { if (!handle.empty()) { Ogre::SceneNode *node = mScene.getMgr()->getSceneNode (handle); node->removeAndDestroyAllChildren(); mScene.getMgr()->destroySceneNode (node); } }