//----------------------------------------------------------------------- const Ogre::Quaternion& BasicRenderable::getWorldOrientation(void) const { Ogre::Node* n = mParent->getParentNode(); assert(n); return n->_getDerivedOrientation(); }
void ObjectAnimation::fillBatch(Ogre::StaticGeometry *sg) { std::vector<Ogre::Entity*>::reverse_iterator iter = mObjectRoot->mEntities.rbegin(); for(;iter != mObjectRoot->mEntities.rend();++iter) { Ogre::Node *node = (*iter)->getParentNode(); if ((*iter)->isVisible()) sg->addEntity(*iter, node->_getDerivedPosition(), node->_getDerivedOrientation(), node->_getDerivedScale()); } }
/** See Ogre::ParticleEmitter. */ void _initParticle(Ogre::Particle *particle) { Ogre::Vector3 xOff, yOff, zOff; // Call superclass ParticleEmitter::_initParticle(particle); xOff = Ogre::Math::SymmetricRandom() * mXRange; yOff = Ogre::Math::SymmetricRandom() * mYRange; zOff = Ogre::Math::SymmetricRandom() * mZRange; #if OGRE_VERSION >= (1 << 16 | 10 << 8 | 0) Ogre::Vector3& position = particle->mPosition; Ogre::Vector3& direction = particle->mDirection; Ogre::ColourValue& colour = particle->mColour; Ogre::Real& totalTimeToLive = particle->mTotalTimeToLive; Ogre::Real& timeToLive = particle->mTimeToLive; #else Ogre::Vector3& position = particle->position; Ogre::Vector3& direction = particle->direction; Ogre::ColourValue& colour = particle->colour; Ogre::Real& totalTimeToLive = particle->totalTimeToLive; Ogre::Real& timeToLive = particle->timeToLive; #endif Ogre::Node* emitterBone = mEmitterBones.at(OEngine::Misc::Rng::rollDice(mEmitterBones.size())); position = xOff + yOff + zOff + mParticleBone->_getDerivedOrientation().Inverse() * (emitterBone->_getDerivedPosition() - mParticleBone->_getDerivedPosition()); // Generate complex data by reference genEmissionColour(colour); // NOTE: We do not use mDirection/mAngle for the initial direction. Ogre::Radian hdir = mHorizontalDir + mHorizontalAngle*Ogre::Math::SymmetricRandom(); Ogre::Radian vdir = mVerticalDir + mVerticalAngle*Ogre::Math::SymmetricRandom(); direction = (mParticleBone->_getDerivedOrientation().Inverse() * emitterBone->_getDerivedOrientation() * Ogre::Quaternion(hdir, Ogre::Vector3::UNIT_Z) * Ogre::Quaternion(vdir, Ogre::Vector3::UNIT_X)) * Ogre::Vector3::UNIT_Z; genEmissionVelocity(direction); // Generate simpler data timeToLive = totalTimeToLive = genEmissionTTL(); }
void EmberEntityLoader::loadPage(::Forests::PageInfo & page) { static Ogre::ColourValue colour(1, 1, 1, 1); #if EMBERENTITYLOADER_USEBATCH const int batchX = static_cast<int>(Ogre::Math::Floor(page.bounds.left/ mBatchSize)); const int batchY = static_cast<int>(Ogre::Math::Floor(page.bounds.top / mBatchSize)); EntityMap& entities(mEntities[batchX][batchY]); #else EntityMap& entities(mEntities); #endif for (EntityMap::iterator I = entities.begin(); I != entities.end(); ++I) { ModelRepresentationInstance& instance(I->second); Model::ModelRepresentation* modelRepresentation(instance.modelRepresentation); EmberEntity& emberEntity = modelRepresentation->getEntity(); if (emberEntity.isVisible()) { WFMath::Point<3> viewPos = emberEntity.getViewPosition(); if (viewPos.isValid()) { Ogre::Vector3 pos(Convert::toOgre(viewPos)); Model::Model& model(modelRepresentation->getModel()); Ogre::Node* node = model.getParentNode(); if (node) { const Ogre::Vector3& pos = node->_getDerivedPosition(); if (pos.x > page.bounds.left && pos.x < page.bounds.right && pos.z > page.bounds.top && pos.z < page.bounds.bottom) { for (Model::Model::SubModelSet::const_iterator J = model.getSubmodels().begin(); J != model.getSubmodels().end(); ++J) { // if (!(*J)->getEntity()->getParentSceneNode()) { // model->getParentSceneNode()->attachObject((*J)->getEntity()); // } // if ((*J)->getEntity()->isVisible()) { addEntity((*J)->getEntity(), pos, node->_getDerivedOrientation(), modelRepresentation->getScale(), colour); // (*J)->getEntity()->setVisible(false); // } } } } } } } }
void Objects::insertMesh (const MWWorld::Ptr& ptr, const std::string& mesh, bool light) { Ogre::SceneNode* insert = ptr.getRefData().getBaseNode(); assert(insert); Ogre::AxisAlignedBox bounds = Ogre::AxisAlignedBox::BOX_NULL; NifOgre::ObjectList objects = NifOgre::Loader::createObjects(insert, mesh); for(size_t i = 0;i < objects.mEntities.size();i++) bounds.merge(objects.mEntities[i]->getWorldBoundingBox(true)); Ogre::Vector3 extents = bounds.getSize(); extents *= insert->getScale(); float size = std::max(std::max(extents.x, extents.y), extents.z); bool small = (size < Settings::Manager::getInt("small object size", "Viewing distance")) && Settings::Manager::getBool("limit small object distance", "Viewing distance"); // do not fade out doors. that will cause holes and look stupid if (ptr.getTypeName().find("Door") != std::string::npos) small = false; if (mBounds.find(ptr.getCell()) == mBounds.end()) mBounds[ptr.getCell()] = Ogre::AxisAlignedBox::BOX_NULL; mBounds[ptr.getCell()].merge(bounds); bool anyTransparency = false; for(size_t i = 0;!anyTransparency && i < objects.mEntities.size();i++) { Ogre::Entity *ent = objects.mEntities[i]; for(unsigned int i=0;!anyTransparency && i < ent->getNumSubEntities(); ++i) { anyTransparency = ent->getSubEntity(i)->getMaterial()->isTransparent(); } } if(!mIsStatic || !Settings::Manager::getBool("use static geometry", "Objects") || anyTransparency || objects.mParticles.size() > 0) { for(size_t i = 0;i < objects.mEntities.size();i++) { Ogre::Entity *ent = objects.mEntities[i]; for(unsigned int i=0; i < ent->getNumSubEntities(); ++i) { Ogre::SubEntity* subEnt = ent->getSubEntity(i); subEnt->setRenderQueueGroup(subEnt->getMaterial()->isTransparent() ? RQG_Alpha : RQG_Main); } ent->setRenderingDistance(small ? Settings::Manager::getInt("small object distance", "Viewing distance") : 0); ent->setVisibilityFlags(mIsStatic ? (small ? RV_StaticsSmall : RV_Statics) : RV_Misc); } for(size_t i = 0;i < objects.mParticles.size();i++) { Ogre::ParticleSystem *part = objects.mParticles[i]; // TODO: Check the particle system's material for actual transparency part->setRenderQueueGroup(RQG_Alpha); part->setRenderingDistance(small ? Settings::Manager::getInt("small object distance", "Viewing distance") : 0); part->setVisibilityFlags(mIsStatic ? (small ? RV_StaticsSmall : RV_Statics) : RV_Misc); } } else { Ogre::StaticGeometry* sg = 0; if (small) { if( mStaticGeometrySmall.find(ptr.getCell()) == mStaticGeometrySmall.end()) { uniqueID = uniqueID +1; sg = mRenderer.getScene()->createStaticGeometry( "sg" + Ogre::StringConverter::toString(uniqueID)); mStaticGeometrySmall[ptr.getCell()] = sg; sg->setRenderingDistance(Settings::Manager::getInt("small object distance", "Viewing distance")); } else sg = mStaticGeometrySmall[ptr.getCell()]; } else { if( mStaticGeometry.find(ptr.getCell()) == mStaticGeometry.end()) { uniqueID = uniqueID +1; sg = mRenderer.getScene()->createStaticGeometry( "sg" + Ogre::StringConverter::toString(uniqueID)); mStaticGeometry[ptr.getCell()] = sg; } else sg = mStaticGeometry[ptr.getCell()]; } // This specifies the size of a single batch region. // If it is set too high: // - there will be problems choosing the correct lights // - the culling will be more inefficient // If it is set too low: // - there will be too many batches. sg->setRegionDimensions(Ogre::Vector3(2500,2500,2500)); sg->setVisibilityFlags(small ? RV_StaticsSmall : RV_Statics); sg->setCastShadows(true); sg->setRenderQueueGroup(RQG_Main); std::vector<Ogre::Entity*>::reverse_iterator iter = objects.mEntities.rbegin(); while(iter != objects.mEntities.rend()) { Ogre::Node *node = (*iter)->getParentNode(); sg->addEntity(*iter, node->_getDerivedPosition(), node->_getDerivedOrientation(), node->_getDerivedScale()); (*iter)->detachFromParent(); mRenderer.getScene()->destroyEntity(*iter); iter++; } } if (light) { insertLight(ptr, objects.mSkelBase, bounds.getCenter() - insert->_getDerivedPosition()); } }